hscdio (empty) → 0.1.0.0
raw patch · 143 files changed
+22222/−0 lines, 143 filesdep +HUnitdep +basedep +base-compatsetup-changedbinary-added
Dependencies added: HUnit, base, base-compat, bitwise, bytestring, containers, directory, hedgehog, hedgehog-classes, hscdio, mtl, optparse-applicative, text, vector
Files
- CHANGELOG.md +34/−0
- FEATURES +111/−0
- LICENSE +674/−0
- README.md +129/−0
- ROADMAP.md +58/−0
- Setup.hs +2/−0
- bin/Sound/Libcdio/PackCdText.hs +73/−0
- hscdio.cabal +277/−0
- include/cdio/compat/cd_types.h +29/−0
- include/cdio/compat/cdtext.h +36/−0
- include/cdio/compat/cycle_break.h +14/−0
- include/cdio/compat/device.h +42/−0
- include/cdio/compat/disc.h +25/−0
- include/cdio/compat/logging.h +33/−0
- include/cdio/compat/mmc.h +9/−0
- include/cdio/compat/read.h +39/−0
- include/cdio/compat/sector.h +60/−0
- include/cdio/compat/track.h +21/−0
- include/cdio/compat/types.h +13/−0
- include/cdio/compat/version.h +25/−0
- src/Data/Text/Encoding/MsJIS.hs +1566/−0
- src/Foreign/Libcdio.hs +74/−0
- src/Foreign/Libcdio/CdText.hs +310/−0
- src/Foreign/Libcdio/CdText/Binary.hs +409/−0
- src/Foreign/Libcdio/CdTypes.hs +193/−0
- src/Foreign/Libcdio/Device.hs +1380/−0
- src/Foreign/Libcdio/Disc.hs +256/−0
- src/Foreign/Libcdio/Logging.hs +166/−0
- src/Foreign/Libcdio/Marshal.hs +295/−0
- src/Foreign/Libcdio/Read.hs +253/−0
- src/Foreign/Libcdio/Sector.hs +674/−0
- src/Foreign/Libcdio/Track.hs +315/−0
- src/Foreign/Libcdio/Types.hs +115/−0
- src/Foreign/Libcdio/Types/Enums.chs +453/−0
- src/Foreign/Libcdio/Types/Internal.hs +409/−0
- src/Foreign/Libcdio/Types/Offsets.chs +127/−0
- src/Foreign/Libcdio/Util.hs +289/−0
- src/Foreign/Libcdio/Version.hs +90/−0
- src/Sound/Libcdio.hs +48/−0
- src/Sound/Libcdio/Common.hs +20/−0
- src/Sound/Libcdio/Device.hs +143/−0
- src/Sound/Libcdio/Logging.hs +92/−0
- src/Sound/Libcdio/Read/CdText.hs +415/−0
- src/Sound/Libcdio/Read/Data.hs +173/−0
- src/Sound/Libcdio/Read/Filesystem.hs +40/−0
- src/Sound/Libcdio/Track.hs +128/−0
- src/Sound/Libcdio/Types.hs +61/−0
- src/Sound/Libcdio/Types/Cdio.hs +243/−0
- src/c/cdio/compat/cdtext.c +100/−0
- src/c/cdio/compat/device.c +110/−0
- src/c/cdio/compat/disc.c +32/−0
- src/c/cdio/compat/logging.c +91/−0
- src/c/cdio/compat/read.c +89/−0
- src/c/cdio/compat/sector.c +152/−0
- src/c/cdio/compat/track.c +31/−0
- src/c/cdio/compat/types.c +10/−0
- src/c/cdio/compat/version.c +16/−0
- test/Data/Text/Encoding/MsJIS/Test/Classes.hs +65/−0
- test/Data/Text/Encoding/MsJIS/Test/Unit.hs +107/−0
- test/Foreign/Libcdio/CdText/Test/Classes.hs +60/−0
- test/Foreign/Libcdio/CdTypes/Test/Classes.hs +84/−0
- test/Foreign/Libcdio/Device/Test/Classes.hs +127/−0
- test/Foreign/Libcdio/Disc/Test/Classes.hs +39/−0
- test/Foreign/Libcdio/Logging/Test/Classes.hs +57/−0
- test/Foreign/Libcdio/Logging/Test/Property.hs +82/−0
- test/Foreign/Libcdio/Read/Test/Classes.hs +50/−0
- test/Foreign/Libcdio/Sector/Test/Classes.hs +91/−0
- test/Foreign/Libcdio/Track/Test/Classes.hs +63/−0
- test/Foreign/Libcdio/Util/Test/Classes.hs +41/−0
- test/Sound/Libcdio/CdText/Test/Classes.hs +78/−0
- test/Sound/Libcdio/Cdio/Test/Classes.hs +55/−0
- test/Test/Libcdio/Property.hs +79/−0
- test/Test/Libcdio/Property/Common.hs +61/−0
- test/Test/Libcdio/Unit.hs +41/−0
- test/Test/Libcdio/Unit/Common.hs +22/−0
- test/Test/Libcdio/Unit/Foreign/CarolusRex.hs +102/−0
- test/Test/Libcdio/Unit/Foreign/DeeperDance.hs +85/−0
- test/Test/Libcdio/Unit/Foreign/RevolutionDays.hs +77/−0
- test/Test/Libcdio/Unit/Sound/CarolusRex.hs +92/−0
- test/Test/Libcdio/Unit/Sound/Common.hs +38/−0
- test/Test/Libcdio/Unit/Sound/DeeperDance.hs +66/−0
- test/Test/Libcdio/Unit/Sound/RevolutionDays.hs +63/−0
- test/Test/Libcdio/Upstream.hs +54/−0
- test/Test/Libcdio/Upstream/Foreign/BinCue.hs +86/−0
- test/Test/Libcdio/Upstream/Foreign/CdrDao.hs +85/−0
- test/Test/Libcdio/Upstream/Foreign/Common.hs +84/−0
- test/Test/Libcdio/Upstream/Foreign/FreeBsd.hs +38/−0
- test/Test/Libcdio/Upstream/Foreign/Linux.hs +47/−0
- test/Test/Libcdio/Upstream/Foreign/Nrg.hs +50/−0
- test/Test/Libcdio/Upstream/Foreign/OsX.hs +39/−0
- test/Test/Libcdio/Upstream/Foreign/Pregap.hs +54/−0
- test/Test/Libcdio/Upstream/Foreign/SizeOf.hs +26/−0
- test/Test/Libcdio/Upstream/Foreign/Solaris.hs +32/−0
- test/Test/Libcdio/Upstream/Foreign/Track.hs +44/−0
- test/Test/Libcdio/Upstream/Foreign/Win32.hs +36/−0
- test/Test/Libcdio/Upstream/Sound/Common.hs +88/−0
- test/Test/Libcdio/Upstream/Sound/Image.hs +134/−0
- test/Test/Libcdio/Upstream/Sound/System.hs +104/−0
- test/Test/Libcdio/Upstream/Sound/Track.hs +51/−0
- test/datafiles/unit/CP932.txt +7998/−0
- test/datafiles/unit/carolus-rex.cdtext binary
- test/datafiles/unit/deeper-dance.cdtext binary
- test/datafiles/unit/pearl-jam.cdtext binary
- test/datafiles/unit/revolution-days.cdtext binary
- test/datafiles/upstream/bad-cat1.cue +9/−0
- test/datafiles/upstream/bad-cat1.toc +8/−0
- test/datafiles/upstream/bad-cat2.cue +9/−0
- test/datafiles/upstream/bad-cat2.toc +8/−0
- test/datafiles/upstream/bad-cat3.cue +9/−0
- test/datafiles/upstream/bad-cat3.toc +8/−0
- test/datafiles/upstream/bad-file.toc +13/−0
- test/datafiles/upstream/bad-mode1.cue +7/−0
- test/datafiles/upstream/bad-mode1.toc +5/−0
- test/datafiles/upstream/bad-msf-1.cue +7/−0
- test/datafiles/upstream/bad-msf-1.toc +6/−0
- test/datafiles/upstream/bad-msf-2.cue +7/−0
- test/datafiles/upstream/bad-msf-2.toc +6/−0
- test/datafiles/upstream/bad-msf-3.cue +7/−0
- test/datafiles/upstream/bad-msf-3.toc +6/−0
- test/datafiles/upstream/cdda.bin binary
- test/datafiles/upstream/cdda.cue +9/−0
- test/datafiles/upstream/cdtext.toc +48/−0
- test/datafiles/upstream/data1.toc +8/−0
- test/datafiles/upstream/data2.toc +13/−0
- test/datafiles/upstream/data5.toc +13/−0
- test/datafiles/upstream/data6.toc +8/−0
- test/datafiles/upstream/data7.toc +13/−0
- test/datafiles/upstream/isofs-m1.bin binary
- test/datafiles/upstream/isofs-m1.cue +4/−0
- test/datafiles/upstream/p1.bin binary
- test/datafiles/upstream/p1.cue +12/−0
- test/datafiles/upstream/p1.nrg binary
- test/datafiles/upstream/t1.toc +5/−0
- test/datafiles/upstream/t10.toc +8/−0
- test/datafiles/upstream/t2.toc +6/−0
- test/datafiles/upstream/t3.toc +11/−0
- test/datafiles/upstream/t4.toc +8/−0
- test/datafiles/upstream/t5.toc +8/−0
- test/datafiles/upstream/t6.toc +7/−0
- test/datafiles/upstream/t7.toc +12/−0
- test/datafiles/upstream/t8.toc +14/−0
- test/datafiles/upstream/t9.toc +31/−0
- test/datafiles/upstream/vcd2.toc +22/−0
+ CHANGELOG.md view
@@ -0,0 +1,34 @@+The Haskell bindings for libcdio follow the Haskell-standard [Package+Versioning Policy](https://pvp.haskell.org), where the first three numbers+indicate version (types/presence of exported symbols), the fourth number+indicates patch (underlying behaviour and/or backend code), and the fifth+indicates revision (docs, packaging, etc.) This is in contrast to the C+libcdio itself, which (recently) uses Semantic Versioning; the only real+difference is that the first *two* numbers of the bindings signal a breaking+change, while the base library signals that with only *one*.+++## v/0.1.0.0. Unreleased++Initial release with nearly all of 'cdio/cdio.h' translated, but not necessarily+tested, documented, or stabilized.+++### Added++* f/1.1.1. Translate all core symbols brought in by simply using `#include "cdio/cdio.h`.+ For the full list of headers this includes, see `FEATURES`.+ Also note that several symbols were left untranslated; see the documentation of `Foreign.Libcdio` for the list.+ * f/1.1.3.1. Translate `cdio/cd_types.h` as it's used in some bitmasks above.+ * f/1.1.3.2. Integrate log messages with the monad rather than (impurely) printing output.+ * f/1.1.4.2. Translate `cdio/util.h` as it provides the conversion functions for `Bcd` values.+* f/1.3.1. f/1.3.3.1. f/1.3.3.2. f/1.3.4.2. Rewrite the documentation of the above to be more clear, more comprehensive, and (occasionally) more correct.+* (some of) f/1.4.1. Just enough of the upstream tests to be sure the bindings are not going *completely* off the rails.+* f/3.1. f/3.3. i/008. Provide a smoother means of accessing the library to Haskell users.+* i/002. Close the low-hanging memory leaks from being returned allocated strings, without obfuscating the type system.+* i/003. i/009. Enforce a bit more type safety by binding integral/string types with typesafe wrappers.++### Known issues++* i/011. On some systems, opening a Cdio session stops the drive from recognizing a manual (push-button) request to open the drive. This also occurs with other libraries, so it's not purely a libcdio problem, Haskell bindings or otherwise, but I come across it much more frequently with the bindings than anywhere else.+* i/021. A `readLog` call will occasionally return unexpected entries.
+ FEATURES view
@@ -0,0 +1,111 @@+The numeric code may be used to search the version control log by prefixing it+with `f/`; for example, to find all of the documentation edits, `f/1.3.`++Lines prefixed with an asterisk (*) are considered complete -- though edits for+refactoring or bugfixes are always still possibilities -- while ones with an+exclamation point (!) are in progress.++ 0. Infrastructure and metadata for code structure, rather than program behaviour+ 0.1. Maintain a README with a high-level overview of the library+ 0.2. Explicit tracking of what has been and what will be done+ 0.2.1. FEATURES+ 0.2.2. CHANGELOG+ 0.2.3. ROADMAP+ 0.3. Track bug reports and feature requests++ 1. Provide a direct Haskell interface to libcdio and libcdio-paranoia+ 1.1. Export all symbols the libcdio public C headers do+* 1.1.1. Translate the "primary" headers #included directly by `cdio/cdio.h`+* 1.1.1.1. `cdio/version.h`+* 1.1.1.2. `cdio/types.h`+* 1.1.1.3. `cdio/sector.h`+* 1.1.1.4. `cdio/device.h`+* 1.1.1.5. `cdio/cdtext.h`+* 1.1.1.6. `cdio/disc.h`+* 1.1.1.7. `cdio/read.h`+* 1.1.1.8. `cdio/track.h`+* 1.1.1.9. `cdio/memory.h`+ 1.1.2. Translate the headers #included by `cdio/mmc_cmds.h`+ 1.1.2.1. `cdio/mmc.h`+ 1.1.2.1.1. `cdio/audio.h+ 1.1.2.1.2. `cdio/dvd.h`+ 1.1.2.1.3. `cdio/mmc_util.h`+ 1.1.2.2. `cdio/mmc_ll_cmds.h`+ 1.1.2.3. `cdio/mmc_hl_cmds.h`+ 1.1.3. Translate the remainder of those public headers+* 1.1.3.1. `cdio/cd_types.h`+* 1.1.3.2. `cdio/logging.h`+ 1.1.3.3. `cdio/utf8.h`+ 1.1.3.4. `cdio/posix.h`+ 1.1.4. Translate the deprecated headers for "backwards compatibility"+ 1.1.4.1. `cdio/ds.h`+* 1.1.4.2. `cdio/util.h`+ 1.1.5. Translate the libcdio-paranoia headers+ 1.1.5.1. `cdio/paranoia/cdda.h`+ 1.1.5.2. `cdio/paranoia/paranoia.h`+ 1.1.6. Translate headers for handling non-audio data+ 1.1.6.1. `cdio/iso9660.h`+ 1.1.6.1.1. `cdio/rock.h`+ 1.1.6.1.1. `cdio/xa.h`+ 1.1.6.2. `cdio/udf.h`+ 1.1.6.2.1. `cdio/udf_file.h`+ 1.1.6.2.2. `cdio/udf_time.h`+ 1.1.6.2.3. `cdio/ecma_167.h`+ 1.3. Improve the documentation from that copied from the headers+* 1.3.1. "Primary" headers #included directly by `cdio/cdio.h`+* 1.3.1.1. `cdio/version.h`+* 1.3.1.2. `cdio/types.h`+* 1.3.1.3. `cdio/sector.h`+* 1.3.1.4. `cdio/device.h`+* 1.3.1.5. `cdio/cdtext.h`+* 1.3.1.6. `cdio/disc.h`+* 1.3.1.7. `cdio/read.h`+* 1.3.1.8. `cdio/track.h`+* 1.3.1.9. `cdio/memory.h`+ 1.3.2. Headers #included by `cdio/mmc_cmds.h`+ 1.3.2.1. `cdio/mmc.h`+ 1.3.2.1.1. `cdio/audio.h+ 1.3.2.1.2. `cdio/dvd.h`+ 1.3.2.1.3. `cdio/mmc_util.h`+ 1.3.2.2. `cdio/mmc_ll_cmds.h`+ 1.3.2.3. `cdio/mmc_hl_cmds.h`+ 1.3.3. Other public headers+* 1.3.3.1. `cdio/cd_types.h`+* 1.3.3.2. `cdio/logging.h`+ 1.3.3.3. `cdio/utf8.h`+ 1.3.3.4. `cdio/posix.h`+ 1.3.4. Deprecated headers for "backwards compatibility"+ 1.3.4.1. `cdio/ds.h`+* 1.3.4.2. `cdio/util.h`+ 1.3.5. libcdio-paranoia headers+ 1.3.5.1. `cdio/paranoia/cdda.h`+ 1.3.5.2. `cdio/paranoia/paranoia.h`+ 1.3.6. Non-audio data+ 1.3.6.1. `cdio/iso9660.h`+ 1.3.6.1.1. `cdio/rock.h`+ 1.3.6.1.1. `cdio/xa.h`+ 1.3.6.2. `cdio/udf.h`+ 1.3.6.2.1. `cdio/udf_file.h`+ 1.3.6.2.2. `cdio/udf_time.h`+ 1.3.6.2.3. `cdio/ecma_167.h`+ 1.4. Copy and translate library tests+! 1.4.1. libcdio tests+ 1.4.2. libcdio-paranoia tests++ 2. Provide Haskell reimplementations of the packaged binaries+ 2.1. `cd-drive`+ 2.2. `cd-info`+ 2.3. `cd-read`+ 2.4. `cdda-player`+ 2.5. `iso-info`+ 2.6. `iso-read`+ 2.7. `mmc-tool`+ 2.8. `libcdio-paranoia`++! 3. Provide alternate idomatic (custom-Monad-based) interface for libcdio functions+* 3.1. "Primary" headers #included directly by `cdio/cdio.h`+ 3.2. Headers #included by `cdio/mmc_cmds.h`+! 3.3. Other public headers+ 3.4. Deprecated headers for "backwards compatibility"+ 3.5. libcdio-paranoia headers+ 3.6. Non-audio data file access
+ LICENSE view
@@ -0,0 +1,674 @@+ GNU GENERAL PUBLIC LICENSE+ Version 3, 29 June 2007++ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>+ Everyone is permitted to copy and distribute verbatim copies+ of this license document, but changing it is not allowed.++ Preamble++ The GNU General Public License is a free, copyleft license for+software and other kinds of works.++ The licenses for most software and other practical works are designed+to take away your freedom to share and change the works. By contrast,+the GNU General Public License is intended to guarantee your freedom to+share and change all versions of a program--to make sure it remains free+software for all its users. We, the Free Software Foundation, use the+GNU General Public License for most of our software; it applies also to+any other work released this way by its authors. You can apply it to+your programs, too.++ When we speak of free software, we are referring to freedom, not+price. Our General Public Licenses are designed to make sure that you+have the freedom to distribute copies of free software (and charge for+them if you wish), that you receive source code or can get it if you+want it, that you can change the software or use pieces of it in new+free programs, and that you know you can do these things.++ To protect your rights, we need to prevent others from denying you+these rights or asking you to surrender the rights. Therefore, you have+certain responsibilities if you distribute copies of the software, or if+you modify it: responsibilities to respect the freedom of others.++ For example, if you distribute copies of such a program, whether+gratis or for a fee, you must pass on to the recipients the same+freedoms that you received. You must make sure that they, too, receive+or can get the source code. And you must show them these terms so they+know their rights.++ Developers that use the GNU GPL protect your rights with two steps:+(1) assert copyright on the software, and (2) offer you this License+giving you legal permission to copy, distribute and/or modify it.++ For the developers' and authors' protection, the GPL clearly explains+that there is no warranty for this free software. For both users' and+authors' sake, the GPL requires that modified versions be marked as+changed, so that their problems will not be attributed erroneously to+authors of previous versions.++ Some devices are designed to deny users access to install or run+modified versions of the software inside them, although the manufacturer+can do so. This is fundamentally incompatible with the aim of+protecting users' freedom to change the software. The systematic+pattern of such abuse occurs in the area of products for individuals to+use, which is precisely where it is most unacceptable. Therefore, we+have designed this version of the GPL to prohibit the practice for those+products. If such problems arise substantially in other domains, we+stand ready to extend this provision to those domains in future versions+of the GPL, as needed to protect the freedom of users.++ Finally, every program is threatened constantly by software patents.+States should not allow patents to restrict development and use of+software on general-purpose computers, but in those that do, we wish to+avoid the special danger that patents applied to a free program could+make it effectively proprietary. To prevent this, the GPL assures that+patents cannot be used to render the program non-free.++ The precise terms and conditions for copying, distribution and+modification follow.++ TERMS AND CONDITIONS++ 0. Definitions.++ "This License" refers to version 3 of the GNU General Public License.++ "Copyright" also means copyright-like laws that apply to other kinds of+works, such as semiconductor masks.++ "The Program" refers to any copyrightable work licensed under this+License. Each licensee is addressed as "you". "Licensees" and+"recipients" may be individuals or organizations.++ To "modify" a work means to copy from or adapt all or part of the work+in a fashion requiring copyright permission, other than the making of an+exact copy. The resulting work is called a "modified version" of the+earlier work or a work "based on" the earlier work.++ A "covered work" means either the unmodified Program or a work based+on the Program.++ To "propagate" a work means to do anything with it that, without+permission, would make you directly or secondarily liable for+infringement under applicable copyright law, except executing it on a+computer or modifying a private copy. Propagation includes copying,+distribution (with or without modification), making available to the+public, and in some countries other activities as well.++ To "convey" a work means any kind of propagation that enables other+parties to make or receive copies. Mere interaction with a user through+a computer network, with no transfer of a copy, is not conveying.++ An interactive user interface displays "Appropriate Legal Notices"+to the extent that it includes a convenient and prominently visible+feature that (1) displays an appropriate copyright notice, and (2)+tells the user that there is no warranty for the work (except to the+extent that warranties are provided), that licensees may convey the+work under this License, and how to view a copy of this License. If+the interface presents a list of user commands or options, such as a+menu, a prominent item in the list meets this criterion.++ 1. Source Code.++ The "source code" for a work means the preferred form of the work+for making modifications to it. "Object code" means any non-source+form of a work.++ A "Standard Interface" means an interface that either is an official+standard defined by a recognized standards body, or, in the case of+interfaces specified for a particular programming language, one that+is widely used among developers working in that language.++ The "System Libraries" of an executable work include anything, other+than the work as a whole, that (a) is included in the normal form of+packaging a Major Component, but which is not part of that Major+Component, and (b) serves only to enable use of the work with that+Major Component, or to implement a Standard Interface for which an+implementation is available to the public in source code form. A+"Major Component", in this context, means a major essential component+(kernel, window system, and so on) of the specific operating system+(if any) on which the executable work runs, or a compiler used to+produce the work, or an object code interpreter used to run it.++ The "Corresponding Source" for a work in object code form means all+the source code needed to generate, install, and (for an executable+work) run the object code and to modify the work, including scripts to+control those activities. However, it does not include the work's+System Libraries, or general-purpose tools or generally available free+programs which are used unmodified in performing those activities but+which are not part of the work. For example, Corresponding Source+includes interface definition files associated with source files for+the work, and the source code for shared libraries and dynamically+linked subprograms that the work is specifically designed to require,+such as by intimate data communication or control flow between those+subprograms and other parts of the work.++ The Corresponding Source need not include anything that users+can regenerate automatically from other parts of the Corresponding+Source.++ The Corresponding Source for a work in source code form is that+same work.++ 2. Basic Permissions.++ All rights granted under this License are granted for the term of+copyright on the Program, and are irrevocable provided the stated+conditions are met. This License explicitly affirms your unlimited+permission to run the unmodified Program. The output from running a+covered work is covered by this License only if the output, given its+content, constitutes a covered work. This License acknowledges your+rights of fair use or other equivalent, as provided by copyright law.++ You may make, run and propagate covered works that you do not+convey, without conditions so long as your license otherwise remains+in force. You may convey covered works to others for the sole purpose+of having them make modifications exclusively for you, or provide you+with facilities for running those works, provided that you comply with+the terms of this License in conveying all material for which you do+not control copyright. Those thus making or running the covered works+for you must do so exclusively on your behalf, under your direction+and control, on terms that prohibit them from making any copies of+your copyrighted material outside their relationship with you.++ Conveying under any other circumstances is permitted solely under+the conditions stated below. Sublicensing is not allowed; section 10+makes it unnecessary.++ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.++ No covered work shall be deemed part of an effective technological+measure under any applicable law fulfilling obligations under article+11 of the WIPO copyright treaty adopted on 20 December 1996, or+similar laws prohibiting or restricting circumvention of such+measures.++ When you convey a covered work, you waive any legal power to forbid+circumvention of technological measures to the extent such circumvention+is effected by exercising rights under this License with respect to+the covered work, and you disclaim any intention to limit operation or+modification of the work as a means of enforcing, against the work's+users, your or third parties' legal rights to forbid circumvention of+technological measures.++ 4. Conveying Verbatim Copies.++ You may convey verbatim copies of the Program's source code as you+receive it, in any medium, provided that you conspicuously and+appropriately publish on each copy an appropriate copyright notice;+keep intact all notices stating that this License and any+non-permissive terms added in accord with section 7 apply to the code;+keep intact all notices of the absence of any warranty; and give all+recipients a copy of this License along with the Program.++ You may charge any price or no price for each copy that you convey,+and you may offer support or warranty protection for a fee.++ 5. Conveying Modified Source Versions.++ You may convey a work based on the Program, or the modifications to+produce it from the Program, in the form of source code under the+terms of section 4, provided that you also meet all of these conditions:++ a) The work must carry prominent notices stating that you modified+ it, and giving a relevant date.++ b) The work must carry prominent notices stating that it is+ released under this License and any conditions added under section+ 7. This requirement modifies the requirement in section 4 to+ "keep intact all notices".++ c) You must license the entire work, as a whole, under this+ License to anyone who comes into possession of a copy. This+ License will therefore apply, along with any applicable section 7+ additional terms, to the whole of the work, and all its parts,+ regardless of how they are packaged. This License gives no+ permission to license the work in any other way, but it does not+ invalidate such permission if you have separately received it.++ d) If the work has interactive user interfaces, each must display+ Appropriate Legal Notices; however, if the Program has interactive+ interfaces that do not display Appropriate Legal Notices, your+ work need not make them do so.++ A compilation of a covered work with other separate and independent+works, which are not by their nature extensions of the covered work,+and which are not combined with it such as to form a larger program,+in or on a volume of a storage or distribution medium, is called an+"aggregate" if the compilation and its resulting copyright are not+used to limit the access or legal rights of the compilation's users+beyond what the individual works permit. Inclusion of a covered work+in an aggregate does not cause this License to apply to the other+parts of the aggregate.++ 6. Conveying Non-Source Forms.++ You may convey a covered work in object code form under the terms+of sections 4 and 5, provided that you also convey the+machine-readable Corresponding Source under the terms of this License,+in one of these ways:++ a) Convey the object code in, or embodied in, a physical product+ (including a physical distribution medium), accompanied by the+ Corresponding Source fixed on a durable physical medium+ customarily used for software interchange.++ b) Convey the object code in, or embodied in, a physical product+ (including a physical distribution medium), accompanied by a+ written offer, valid for at least three years and valid for as+ long as you offer spare parts or customer support for that product+ model, to give anyone who possesses the object code either (1) a+ copy of the Corresponding Source for all the software in the+ product that is covered by this License, on a durable physical+ medium customarily used for software interchange, for a price no+ more than your reasonable cost of physically performing this+ conveying of source, or (2) access to copy the+ Corresponding Source from a network server at no charge.++ c) Convey individual copies of the object code with a copy of the+ written offer to provide the Corresponding Source. This+ alternative is allowed only occasionally and noncommercially, and+ only if you received the object code with such an offer, in accord+ with subsection 6b.++ d) Convey the object code by offering access from a designated+ place (gratis or for a charge), and offer equivalent access to the+ Corresponding Source in the same way through the same place at no+ further charge. You need not require recipients to copy the+ Corresponding Source along with the object code. If the place to+ copy the object code is a network server, the Corresponding Source+ may be on a different server (operated by you or a third party)+ that supports equivalent copying facilities, provided you maintain+ clear directions next to the object code saying where to find the+ Corresponding Source. Regardless of what server hosts the+ Corresponding Source, you remain obligated to ensure that it is+ available for as long as needed to satisfy these requirements.++ e) Convey the object code using peer-to-peer transmission, provided+ you inform other peers where the object code and Corresponding+ Source of the work are being offered to the general public at no+ charge under subsection 6d.++ A separable portion of the object code, whose source code is excluded+from the Corresponding Source as a System Library, need not be+included in conveying the object code work.++ A "User Product" is either (1) a "consumer product", which means any+tangible personal property which is normally used for personal, family,+or household purposes, or (2) anything designed or sold for incorporation+into a dwelling. In determining whether a product is a consumer product,+doubtful cases shall be resolved in favor of coverage. For a particular+product received by a particular user, "normally used" refers to a+typical or common use of that class of product, regardless of the status+of the particular user or of the way in which the particular user+actually uses, or expects or is expected to use, the product. A product+is a consumer product regardless of whether the product has substantial+commercial, industrial or non-consumer uses, unless such uses represent+the only significant mode of use of the product.++ "Installation Information" for a User Product means any methods,+procedures, authorization keys, or other information required to install+and execute modified versions of a covered work in that User Product from+a modified version of its Corresponding Source. The information must+suffice to ensure that the continued functioning of the modified object+code is in no case prevented or interfered with solely because+modification has been made.++ If you convey an object code work under this section in, or with, or+specifically for use in, a User Product, and the conveying occurs as+part of a transaction in which the right of possession and use of the+User Product is transferred to the recipient in perpetuity or for a+fixed term (regardless of how the transaction is characterized), the+Corresponding Source conveyed under this section must be accompanied+by the Installation Information. But this requirement does not apply+if neither you nor any third party retains the ability to install+modified object code on the User Product (for example, the work has+been installed in ROM).++ The requirement to provide Installation Information does not include a+requirement to continue to provide support service, warranty, or updates+for a work that has been modified or installed by the recipient, or for+the User Product in which it has been modified or installed. Access to a+network may be denied when the modification itself materially and+adversely affects the operation of the network or violates the rules and+protocols for communication across the network.++ Corresponding Source conveyed, and Installation Information provided,+in accord with this section must be in a format that is publicly+documented (and with an implementation available to the public in+source code form), and must require no special password or key for+unpacking, reading or copying.++ 7. Additional Terms.++ "Additional permissions" are terms that supplement the terms of this+License by making exceptions from one or more of its conditions.+Additional permissions that are applicable to the entire Program shall+be treated as though they were included in this License, to the extent+that they are valid under applicable law. If additional permissions+apply only to part of the Program, that part may be used separately+under those permissions, but the entire Program remains governed by+this License without regard to the additional permissions.++ When you convey a copy of a covered work, you may at your option+remove any additional permissions from that copy, or from any part of+it. (Additional permissions may be written to require their own+removal in certain cases when you modify the work.) You may place+additional permissions on material, added by you to a covered work,+for which you have or can give appropriate copyright permission.++ Notwithstanding any other provision of this License, for material you+add to a covered work, you may (if authorized by the copyright holders of+that material) supplement the terms of this License with terms:++ a) Disclaiming warranty or limiting liability differently from the+ terms of sections 15 and 16 of this License; or++ b) Requiring preservation of specified reasonable legal notices or+ author attributions in that material or in the Appropriate Legal+ Notices displayed by works containing it; or++ c) Prohibiting misrepresentation of the origin of that material, or+ requiring that modified versions of such material be marked in+ reasonable ways as different from the original version; or++ d) Limiting the use for publicity purposes of names of licensors or+ authors of the material; or++ e) Declining to grant rights under trademark law for use of some+ trade names, trademarks, or service marks; or++ f) Requiring indemnification of licensors and authors of that+ material by anyone who conveys the material (or modified versions of+ it) with contractual assumptions of liability to the recipient, for+ any liability that these contractual assumptions directly impose on+ those licensors and authors.++ All other non-permissive additional terms are considered "further+restrictions" within the meaning of section 10. If the Program as you+received it, or any part of it, contains a notice stating that it is+governed by this License along with a term that is a further+restriction, you may remove that term. If a license document contains+a further restriction but permits relicensing or conveying under this+License, you may add to a covered work material governed by the terms+of that license document, provided that the further restriction does+not survive such relicensing or conveying.++ If you add terms to a covered work in accord with this section, you+must place, in the relevant source files, a statement of the+additional terms that apply to those files, or a notice indicating+where to find the applicable terms.++ Additional terms, permissive or non-permissive, may be stated in the+form of a separately written license, or stated as exceptions;+the above requirements apply either way.++ 8. Termination.++ You may not propagate or modify a covered work except as expressly+provided under this License. Any attempt otherwise to propagate or+modify it is void, and will automatically terminate your rights under+this License (including any patent licenses granted under the third+paragraph of section 11).++ However, if you cease all violation of this License, then your+license from a particular copyright holder is reinstated (a)+provisionally, unless and until the copyright holder explicitly and+finally terminates your license, and (b) permanently, if the copyright+holder fails to notify you of the violation by some reasonable means+prior to 60 days after the cessation.++ Moreover, your license from a particular copyright holder is+reinstated permanently if the copyright holder notifies you of the+violation by some reasonable means, this is the first time you have+received notice of violation of this License (for any work) from that+copyright holder, and you cure the violation prior to 30 days after+your receipt of the notice.++ Termination of your rights under this section does not terminate the+licenses of parties who have received copies or rights from you under+this License. If your rights have been terminated and not permanently+reinstated, you do not qualify to receive new licenses for the same+material under section 10.++ 9. Acceptance Not Required for Having Copies.++ You are not required to accept this License in order to receive or+run a copy of the Program. Ancillary propagation of a covered work+occurring solely as a consequence of using peer-to-peer transmission+to receive a copy likewise does not require acceptance. However,+nothing other than this License grants you permission to propagate or+modify any covered work. These actions infringe copyright if you do+not accept this License. Therefore, by modifying or propagating a+covered work, you indicate your acceptance of this License to do so.++ 10. Automatic Licensing of Downstream Recipients.++ Each time you convey a covered work, the recipient automatically+receives a license from the original licensors, to run, modify and+propagate that work, subject to this License. You are not responsible+for enforcing compliance by third parties with this License.++ An "entity transaction" is a transaction transferring control of an+organization, or substantially all assets of one, or subdividing an+organization, or merging organizations. If propagation of a covered+work results from an entity transaction, each party to that+transaction who receives a copy of the work also receives whatever+licenses to the work the party's predecessor in interest had or could+give under the previous paragraph, plus a right to possession of the+Corresponding Source of the work from the predecessor in interest, if+the predecessor has it or can get it with reasonable efforts.++ You may not impose any further restrictions on the exercise of the+rights granted or affirmed under this License. For example, you may+not impose a license fee, royalty, or other charge for exercise of+rights granted under this License, and you may not initiate litigation+(including a cross-claim or counterclaim in a lawsuit) alleging that+any patent claim is infringed by making, using, selling, offering for+sale, or importing the Program or any portion of it.++ 11. Patents.++ A "contributor" is a copyright holder who authorizes use under this+License of the Program or a work on which the Program is based. The+work thus licensed is called the contributor's "contributor version".++ A contributor's "essential patent claims" are all patent claims+owned or controlled by the contributor, whether already acquired or+hereafter acquired, that would be infringed by some manner, permitted+by this License, of making, using, or selling its contributor version,+but do not include claims that would be infringed only as a+consequence of further modification of the contributor version. For+purposes of this definition, "control" includes the right to grant+patent sublicenses in a manner consistent with the requirements of+this License.++ Each contributor grants you a non-exclusive, worldwide, royalty-free+patent license under the contributor's essential patent claims, to+make, use, sell, offer for sale, import and otherwise run, modify and+propagate the contents of its contributor version.++ In the following three paragraphs, a "patent license" is any express+agreement or commitment, however denominated, not to enforce a patent+(such as an express permission to practice a patent or covenant not to+sue for patent infringement). To "grant" such a patent license to a+party means to make such an agreement or commitment not to enforce a+patent against the party.++ If you convey a covered work, knowingly relying on a patent license,+and the Corresponding Source of the work is not available for anyone+to copy, free of charge and under the terms of this License, through a+publicly available network server or other readily accessible means,+then you must either (1) cause the Corresponding Source to be so+available, or (2) arrange to deprive yourself of the benefit of the+patent license for this particular work, or (3) arrange, in a manner+consistent with the requirements of this License, to extend the patent+license to downstream recipients. "Knowingly relying" means you have+actual knowledge that, but for the patent license, your conveying the+covered work in a country, or your recipient's use of the covered work+in a country, would infringe one or more identifiable patents in that+country that you have reason to believe are valid.++ If, pursuant to or in connection with a single transaction or+arrangement, you convey, or propagate by procuring conveyance of, a+covered work, and grant a patent license to some of the parties+receiving the covered work authorizing them to use, propagate, modify+or convey a specific copy of the covered work, then the patent license+you grant is automatically extended to all recipients of the covered+work and works based on it.++ A patent license is "discriminatory" if it does not include within+the scope of its coverage, prohibits the exercise of, or is+conditioned on the non-exercise of one or more of the rights that are+specifically granted under this License. You may not convey a covered+work if you are a party to an arrangement with a third party that is+in the business of distributing software, under which you make payment+to the third party based on the extent of your activity of conveying+the work, and under which the third party grants, to any of the+parties who would receive the covered work from you, a discriminatory+patent license (a) in connection with copies of the covered work+conveyed by you (or copies made from those copies), or (b) primarily+for and in connection with specific products or compilations that+contain the covered work, unless you entered into that arrangement,+or that patent license was granted, prior to 28 March 2007.++ Nothing in this License shall be construed as excluding or limiting+any implied license or other defenses to infringement that may+otherwise be available to you under applicable patent law.++ 12. No Surrender of Others' Freedom.++ If conditions are imposed on you (whether by court order, agreement or+otherwise) that contradict the conditions of this License, they do not+excuse you from the conditions of this License. If you cannot convey a+covered work so as to satisfy simultaneously your obligations under this+License and any other pertinent obligations, then as a consequence you may+not convey it at all. For example, if you agree to terms that obligate you+to collect a royalty for further conveying from those to whom you convey+the Program, the only way you could satisfy both those terms and this+License would be to refrain entirely from conveying the Program.++ 13. Use with the GNU Affero General Public License.++ Notwithstanding any other provision of this License, you have+permission to link or combine any covered work with a work licensed+under version 3 of the GNU Affero General Public License into a single+combined work, and to convey the resulting work. The terms of this+License will continue to apply to the part which is the covered work,+but the special requirements of the GNU Affero General Public License,+section 13, concerning interaction through a network will apply to the+combination as such.++ 14. Revised Versions of this License.++ The Free Software Foundation may publish revised and/or new versions of+the GNU General Public License from time to time. Such new versions will+be similar in spirit to the present version, but may differ in detail to+address new problems or concerns.++ Each version is given a distinguishing version number. If the+Program specifies that a certain numbered version of the GNU General+Public License "or any later version" applies to it, you have the+option of following the terms and conditions either of that numbered+version or of any later version published by the Free Software+Foundation. If the Program does not specify a version number of the+GNU General Public License, you may choose any version ever published+by the Free Software Foundation.++ If the Program specifies that a proxy can decide which future+versions of the GNU General Public License can be used, that proxy's+public statement of acceptance of a version permanently authorizes you+to choose that version for the Program.++ Later license versions may give you additional or different+permissions. However, no additional obligations are imposed on any+author or copyright holder as a result of your choosing to follow a+later version.++ 15. Disclaimer of Warranty.++ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.++ 16. Limitation of Liability.++ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF+SUCH DAMAGES.++ 17. Interpretation of Sections 15 and 16.++ If the disclaimer of warranty and limitation of liability provided+above cannot be given local legal effect according to their terms,+reviewing courts shall apply local law that most closely approximates+an absolute waiver of all civil liability in connection with the+Program, unless a warranty or assumption of liability accompanies a+copy of the Program in return for a fee.++ END OF TERMS AND CONDITIONS++ How to Apply These Terms to Your New Programs++ If you develop a new program, and you want it to be of the greatest+possible use to the public, the best way to achieve this is to make it+free software which everyone can redistribute and change under these terms.++ To do so, attach the following notices to the program. It is safest+to attach them to the start of each source file to most effectively+state the exclusion of warranty; and each file should have at least+the "copyright" line and a pointer to where the full notice is found.++ <one line to give the program's name and a brief idea of what it does.>+ Copyright (C) <year> <name of author>++ This program is free software: you can redistribute it and/or modify+ it under the terms of the GNU General Public License as published by+ the Free Software Foundation, either version 3 of the License, or+ (at your option) any later version.++ This program is distributed in the hope that it will be useful,+ but WITHOUT ANY WARRANTY; without even the implied warranty of+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+ GNU General Public License for more details.++ You should have received a copy of the GNU General Public License+ along with this program. If not, see <http://www.gnu.org/licenses/>.++Also add information on how to contact you by electronic and paper mail.++ If the program does terminal interaction, make it output a short+notice like this when it starts in an interactive mode:++ <program> Copyright (C) <year> <name of author>+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.+ This is free software, and you are welcome to redistribute it+ under certain conditions; type `show c' for details.++The hypothetical commands `show w' and `show c' should show the appropriate+parts of the General Public License. Of course, your program's commands+might be different; for a GUI interface, you would use an "about box".++ You should also get your employer (if you work as a programmer) or school,+if any, to sign a "copyright disclaimer" for the program, if necessary.+For more information on this, and how to apply and follow the GNU GPL, see+<http://www.gnu.org/licenses/>.++ The GNU General Public License does not permit incorporating your program+into proprietary programs. If your program is a subroutine library, you+may consider it more useful to permit linking proprietary applications with+the library. If this is what you want to do, use the GNU Lesser General+Public License instead of this License. But first, please read+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
+ README.md view
@@ -0,0 +1,129 @@+# About+In C, [libcdio](https://www.gnu.org/software/libcdio/) provides a widely-ported +and highly-usable library for retrieving data from CDs (and disc images). This +is an area which Haskell has thus far been lacking a solution for; while modern +technology has admittedly been moving away from discs in favour of downloading +files over the internet, there is still some utility in the medium for any +programmers whose projects might involve external storage (note, however, that +`libcdio` only allows /reading/ discs, and leaves /authoring/ to other +libraries).++While the majority of the core library has been translated, many supplemental +headers (MMC commands, CD-Paranoia, etc.) are not yet available; for the +current progress see the [FEATURES](./FEATURES) file and the +[ROADMAP](./ROADMAP.md) for the rough order in which those are planned to be +developed, and please do report any bugs you find (or even fix them yourself!)+++# License++The original `libcdio` is licensed under the GPL, and these bindings, of +course, follow suit. If you do use this in your own project, therefore, you +are subject to the ambiguity of whether linking to a GPL library then requires +your own code to also be released under the GPL. Look elsewhere for a full +discussion on what arguments are given in that debate, but in short, the GPL +says that "a work based on the Program" must *also* be released under the GPL.++To err on the side of caution, if you use this library, release your code under +the GPL. To do otherwise is to take a firm stance against the linking argument +at best, violate the copyright at worst, and make GPL proponents angry at you +either way.+++# Installation++## Requirements++As with nearly every Haskell project, the `.cabal` file maintains the list of +dependencies, and that should be taken as authoritative over anywhere else +except Hackage revisions, and I'll try to keep the code up to date with those.++Notably, the actual core of this package is the C `libcdio` library. All +bindings should fail gracefully for any version within the supported range, and +so should be safe to call blindly, but this is accomplished via preprocessor +commands, and so *this package must be recompiled whenever the base libcdio +version changes*. Minor version bumps to the underlying library (and certainly +patch releases) should still run safely after being recompiled, but there may +be some unexpected behaviour: version 2.1 added a few meta-values to the +`Language` enum, for example, at values greater than 255, while the previous +maximum value was below that. It is possible for a C compiler to have used a +byte representation for <2.1 and a larger one for >=2.1; something like that +could *possibly* result in things being set at/referenced from the wrong memory +offset.++ * libcdio: >= 0.93 && < 2.2+ * c2hs: >= 0.26+ * ghc: >= 8.0++## c2hs + ghc++Some parts of the bindings have been written for the `c2hs` preprocessor, and +while manual compilation is technically possible, it's much more involved than +necessary. Instead, just use `cabal-install` or `stack` as usual. If you +really do have to invoke `gcc` manually, however, run that preprocessor first:++ c2hs --cppopts=-E --cppopts=-Iinclude/ --include=.../ src/Foreign/Libcdio/Types/Enums.chs+ c2hs --cppopts=-E --cppopts=-Iinclude/ --include=.../ src/Foreign/Libcdio/Types/Offsets.chs+++# Usage++The original implementation revolves around a classically-C architecture of +threading a mutable (though opaque) pointer through through many function +calls. For those used to that or who are following pre-existing guides, a +set of low-level bindings mirroring that architecture may be found under +the "Foreign.Libcdio" tree; for anyone used to Haskell, the monadic +bindings under "Sound.Libcdio" are recommended instead. A lookup table for +translating existing code and/or knowledge into each progressively higher-level +interface is provided in the documentation of the `Foreign.Libcdio.*` modules.++As a general rule, any project should /only/ import modules from a single set +of bindings, not both, as while the datatypes can frequently be passed between +them, several function names have been reused and so may collide.+++# Contributing++I welcome any patches, whether for bug fixes, new features, or anything else. +If you just want to point out a bug or ask for some yet-unmentioned feature, I +maintain that list in [ISSUES](./ISSUES/); see the [README](./ISSUES/README.md) +in that directory for the format if you want to submit something in a more +complete form or contribute to any ongoing discussion, but otherwise feel free +to simply [email me](mailto:ag@eitilt.life) and I'll wrangle it into the +right form.++If you decide to contribute yourself, please enable the `dev` build flag. +For the moment, it just enables all warnings I want to enforce in the code, but +it might provide other aids in the future as well. I've avoided enabling them +during everyday building as while an end user seeing a warning *might* feel +inclined to fix the program, chances are it's just going to be ignored as the +list of built files scrolls by.++ cabal configure -fdev++Depending on the size of your hack, I welcome either a diff file, or you can +bundle your complete darcs patches with `darcs send`. Either way, attach the +changes to an email addressed to ag@eitilt.life and I'll see about adding it to +the codebase.++## Patch format++If you do send the latter, every patch should have a comment with a (at least +mildly) descriptive name prefixed with a tag indicating the general category +addressed by the patch: for fixing issues, that is an "i/" followed by the +issue number (padded with leading zeros to three digits); for general +development, "f/" followed by the best topic in the `FEATURES` key; for +completeness, version tags are "v/" followed by the package reference followed +by the version. All are terminated with a final period.++Please do not squash patches. Each patch should represent a minimal but +complete change: certainly enough context to successfully compile, hopefully +enough context to not break any previously-passing tests, and potentially +combining closely-related changes at your discretion, but if you wind up trying +to decide between multiple tags or you're adding all of your work over the +entire day, you should probably look closely at whether you can break the patch +apart any farther.++Additionally, make good use of the `--ask-deps` flag. Until I get a CI +integration together, it's easy to miss a dependency, but do your best to +select anything which your patch may require to build successfully.
+ ROADMAP.md view
@@ -0,0 +1,58 @@+# Version roadmap++While the `FEATURES` file provides a checklist and rough progress indication,+it does not give any indication of priority. This document, then, is a means+of sorting those features into a rough order of implementation. Future version+numbers here are only a rough indication of expectations; intermediate breaking+changes and partial releases may require they be incremented.+++## Core library++* f/1.1.1.+* f/1.1.3.1.+* f/1.3.1.+* f/1.3.3.1.+* f/1.1.3.2.+* f/1.4.1. *(those which may be implemented at this point)*+* f/3.1.+++## Re-implement binaries for testing++* f/2.1.+* f/2.2.+* f/2.3.+* f/2.5.+* f/2.6.+++## libcdio-paranoia++* f/1.1.5.+* f/1.3.5.+* f/1.4.2.+* f/2.8.+* f/3.5.+++## MMC commands++* f/1.1.2.+* f/1.3.2.+* f/1.4.1. *(those which may be implemented at this point)*+* f/2.7.+* f/3.2.+++## Non-audio data++* f/1.1.3.3.+* f/1.1.3.4.+* f/1.1.4.1.+* f/1.1.6.+* f/1.3.3.3.+* f/1.3.3.4.+* f/1.3.4.1.+* f/1.3.6.+* f/3.6.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ bin/Sound/Libcdio/PackCdText.hs view
@@ -0,0 +1,73 @@+{-# LANGUAGE CPP #-}++module Main where+++import qualified Options.Applicative as O++import qualified Data.ByteString as BS++import qualified System.IO as IO++import Sound.Libcdio+import Sound.Libcdio.Read.CdText++#if MIN_VERSION_base(4,11,0)+#else+import Data.Monoid ( (<>) )+#endif++import Options.Applicative ( (<|>), (<**>) )+++data Options = Options+ { source :: FilePath+ , sink :: Maybe FilePath+ , help :: Bool+ }+ deriving ( Eq, Ord, Show, Read )+++options :: O.Parser Options+options = Options+ <$> O.strArgument (O.metavar "FILE")+ <*> output+ <*> O.switch+ ( O.long "help"+ <> O.short 'h'+ <> O.help "Print this help message"+ )++output :: O.Parser (Maybe FilePath)+output = O.flag' Nothing+ ( O.long "stdout"+ <> O.short 'O'+ <> O.help "Echo the resulting binary blob to stdout"+ )+ <|> Just <$> O.strOption+ ( O.long "output"+ <> O.short 'o'+ <> O.metavar "FILE"+ <> O.value "cdtext.dat"+ <> O.help "Where to save the resulting CDTEXT blob"+ )++description :: O.InfoMod a+description = O.fullDesc+ <> O.progDesc "Generate a binary CDTEXT file from readable data"+++main :: IO ()+main = do+ os <- O.execParser $ O.info (options <**> O.helper) description+ if help os+ then putStrLn "TODO: Print the help"+ else do+ let write p = case sink os of+ Just f -> IO.withBinaryFile f IO.WriteMode $ flip BS.hPut p+ Nothing -> BS.putStr p+ bs <- open (Just $ source os) False cdTextRaw+ case bs of+ Right (Just bs') -> write bs'+ Right Nothing -> IO.hPutStrLn IO.stderr "No CDTEXT on disc"+ _ -> IO.hPutStrLn IO.stderr "Unable to open device"
+ hscdio.cabal view
@@ -0,0 +1,277 @@+cabal-version: 2.4++name: hscdio+author: Sam May+category: Sound+synopsis: Haskell bindings to the libcdio disc-reading library.++version: 0.1.0.0+stability: provisional+maintainer: sam@eitilt.life++copyright: (c) 2018-2021 Sam May+license: GPL-3.0-or-later+license-file: LICENSE+extra-source-files: CHANGELOG.md+ , FEATURES+ , README.md+ , ROADMAP.md+ , include/cdio/compat/*.h+ -- The test suites will run relative to the source directory+ , test/datafiles/**/*.bin+ , test/datafiles/**/*.cdtext+ , test/datafiles/**/*.cue+ , test/datafiles/**/*.nrg+ , test/datafiles/**/*.toc+ , test/datafiles/**/*.txt++homepage: https://ag.eitilt.life/hscdio+bug-reports: mailto:ag@eitilt.life++description:+ The C library "libcdio" provides unified functions for reading data from+ CDs and disc images across an impressive range of operating sysems. This+ package provides Haskell bindings for those functions, in both a format+ familiar to anyone who has used the original library, and a format more+ native to the Haskell ecosystem.++build-type: Simple+tested-with: GHC ==8.0.2, GHC ==8.2.2, GHC ==8.4.4, GHC ==8.6.5, GHC ==8.8.4, GHC ==8.10.4+++source-repository head+ type: darcs+ location: https://darcs.eitilt.life/hscdio++source-repository this+ type: darcs+ location: https://darcs.eitilt.life/hscdio+ tag: v/0.1.0.0.+++source-repository head+ type: darcs+ location: https://hub.darcs.net/ag.eitilt/hscdio++source-repository this+ type: darcs+ location: https://hub.darcs.net/ag.eitilt/hscdio+ tag: v/0.1.0.0.+++flag dev+ description: Trigger stricter behaviour for development+ default: False+ manual: True++flag tools+ description: Build developers' aids+ default: False+ manual: True+++common flags-ghc+ if flag(dev)+ ghc-options: -Weverything+ -Wno-unrecognised-pragmas+ -Wno-implicit-prelude -Wno-missing-import-lists+ -Wno-missing-exported-signatures -Wno-missing-local-signatures+ -Wno-missed-specialisations -Wno-all-missed-specialisations+ -Wno-safe -Wno-unsafe+ -Wno-monomorphism-restriction+ if impl(ghc >= 8.4.1)+ ghc-options: -Wno-missing-export-lists+ if impl(ghc >= 8.8.1)+ ghc-options: -Wno-missing-deriving-strategies+ if impl(ghc >= 8.10.1)+ ghc-options: -Wno-missing-safe-haskell-mode+ -Wno-prepositive-qualified-module+ else+ ghc-options: -Wno-unrecognised-pragmas+++library+ import: flags-ghc+ hs-source-dirs: src+ exposed-modules: Data.Text.Encoding.MsJIS+ , Foreign.Libcdio.CdText+ , Foreign.Libcdio.CdTypes+ , Foreign.Libcdio.Device+ , Foreign.Libcdio.Disc+ , Foreign.Libcdio.Logging+ , Foreign.Libcdio.Read+ , Foreign.Libcdio.Sector+ , Foreign.Libcdio.Track+ , Foreign.Libcdio.Types+ , Foreign.Libcdio.Util+ , Foreign.Libcdio.Version+ , Foreign.Libcdio+ , Sound.Libcdio+ , Sound.Libcdio.Device+ , Sound.Libcdio.Logging+ , Sound.Libcdio.Read.CdText+ , Sound.Libcdio.Read.Data+ , Sound.Libcdio.Read.Filesystem+ , Sound.Libcdio.Track+ , Sound.Libcdio.Types+ other-modules: Foreign.Libcdio.Marshal+ , Foreign.Libcdio.CdText.Binary+ , Foreign.Libcdio.Types.Enums+ , Foreign.Libcdio.Types.Internal+ , Foreign.Libcdio.Types.Offsets+ , Sound.Libcdio.Common+ , Sound.Libcdio.Types.Cdio+ -- Be sure to keep pkg/gentoo/dev-haskell/*.ebuild up to date+ build-depends: base >=4.9 && <4.15+ , bitwise >=0.1 && <1.1+ , bytestring >=0.9 && <0.12+ , containers <0.7+ , mtl <2.3+ , text >=0.3 && <1.3+ , vector <0.13+ build-tool-depends: c2hs:c2hs >=0.26 && <0.29+ include-dirs: include+ includes: cdio/cdtext.h+ , cdio/cdio.h+ , cdio/cd_types.h+ , cdio/device.h+ , cdio/disc.h+ , cdio/memory.h+ , cdio/mmc.h+ , cdio/track.h+ , cdio/types.h+ , cdio/sector.h+ , cdio/util.h+ , cdio/compat/cdtext.h+ , cdio/compat/cd_types.h+ , cdio/compat/cycle_break.h+ , cdio/compat/device.h+ , cdio/compat/disc.h+ , cdio/compat/logging.h+ , cdio/compat/mmc.h+ , cdio/compat/read.h+ , cdio/compat/sector.h+ , cdio/compat/track.h+ , cdio/compat/types.h+ , cdio/compat/version.h+ , stdint.h+ , stdlib.h+ , string.h+ , unistd.h+ c-sources: src/c/cdio/compat/cdtext.c+ , src/c/cdio/compat/device.c+ , src/c/cdio/compat/disc.c+ , src/c/cdio/compat/logging.c+ , src/c/cdio/compat/read.c+ , src/c/cdio/compat/sector.c+ , src/c/cdio/compat/track.c+ , src/c/cdio/compat/types.c+ , src/c/cdio/compat/version.c+ extra-libraries: cdio+ default-language: Haskell2010+ other-extensions: CPP+ , ForeignFunctionInterface+ , MultiParamTypeClasses+ , OverloadedStrings+ , Trustworthy++test-suite property+ import: flags-ghc+ type: exitcode-stdio-1.0+ hs-source-dirs: test+ if impl(ghc < 8.6.1)+ -- hedgehog-classes requires base>=4.12.0.0+ buildable: False+ main-is: Test/Libcdio/Property.hs+ other-modules: Data.Text.Encoding.MsJIS.Test.Classes+ , Foreign.Libcdio.CdText.Test.Classes+ , Foreign.Libcdio.CdTypes.Test.Classes+ , Foreign.Libcdio.Device.Test.Classes+ , Foreign.Libcdio.Disc.Test.Classes+ , Foreign.Libcdio.Logging.Test.Classes+ , Foreign.Libcdio.Logging.Test.Property+ , Foreign.Libcdio.Read.Test.Classes+ , Foreign.Libcdio.Sector.Test.Classes+ , Foreign.Libcdio.Track.Test.Classes+ , Foreign.Libcdio.Util.Test.Classes+ , Sound.Libcdio.Cdio.Test.Classes+ , Sound.Libcdio.CdText.Test.Classes+ , Test.Libcdio.Property.Common+ build-depends: base+ , hscdio+ , hedgehog <1.1+ , hedgehog-classes >=0.1.1.0 && <0.3+ , text+ default-language: Haskell2010+ other-extensions: CPP+ , OverloadedStrings++test-suite unit+ import: flags-ghc+ type: exitcode-stdio-1.0+ hs-source-dirs: test+ main-is: Test/Libcdio/Unit.hs+ other-modules: Paths_hscdio+ , Data.Text.Encoding.MsJIS.Test.Unit+ , Test.Libcdio.Unit.Common+ , Test.Libcdio.Unit.Foreign.CarolusRex+ , Test.Libcdio.Unit.Foreign.DeeperDance+ , Test.Libcdio.Unit.Foreign.RevolutionDays+ , Test.Libcdio.Unit.Sound.Common+ , Test.Libcdio.Unit.Sound.CarolusRex+ , Test.Libcdio.Unit.Sound.DeeperDance+ , Test.Libcdio.Unit.Sound.RevolutionDays+ autogen-modules: Paths_hscdio+ build-depends: base+ , hscdio+ , HUnit >=1.1 && <1.7+ , base-compat >= 0.9.3 && <0.12+ , bytestring+ , text+ default-language: Haskell2010++test-suite upstream+ import: flags-ghc+ type: exitcode-stdio-1.0+ hs-source-dirs: test+ main-is: Test/Libcdio/Upstream.hs+ other-modules: Paths_hscdio+ , Test.Libcdio.Upstream.Foreign.Common+ , Test.Libcdio.Upstream.Foreign.BinCue+ , Test.Libcdio.Upstream.Foreign.CdrDao+ , Test.Libcdio.Upstream.Foreign.FreeBsd+ , Test.Libcdio.Upstream.Foreign.Linux+ , Test.Libcdio.Upstream.Foreign.Nrg+ , Test.Libcdio.Upstream.Foreign.OsX+ , Test.Libcdio.Upstream.Foreign.Pregap+ , Test.Libcdio.Upstream.Foreign.Solaris+ , Test.Libcdio.Upstream.Foreign.SizeOf+ , Test.Libcdio.Upstream.Foreign.Track+ , Test.Libcdio.Upstream.Foreign.Win32+ , Test.Libcdio.Upstream.Sound.Common+ , Test.Libcdio.Upstream.Sound.Image+ , Test.Libcdio.Upstream.Sound.System+ , Test.Libcdio.Upstream.Sound.Track+ autogen-modules: Paths_hscdio+ build-depends: base+ , hscdio+ , HUnit >=1.1 && <1.7+ , base-compat >= 0.9.3 && <0.12+ , directory >=1.2.3 && <1.4+ , text+ default-language: Haskell2010+ other-extensions: CPP+ , OverloadedStrings++executable pack-cdtext+ import: flags-ghc+ hs-source-dirs: bin+ if !flag(tools)+ buildable: False+ main-is: Sound/Libcdio/PackCdText.hs+ build-depends: base+ , hscdio+ , bytestring+ , optparse-applicative+ default-language: Haskell2010+ other-extensions: CPP
+ include/cdio/compat/cd_types.h view
@@ -0,0 +1,29 @@+#ifndef __CDIO_COMPAT_CD_TYPES__+#define __CDIO_COMPAT_CD_TYPES__+++#include "cdio/compat/types.h"+#include "cdio/cd_types.h"++#include "stdint.h"+++// c2hs can't handle the `~` in CDIO_FS_MATCH_ALL+typedef enum {+ FS_ANAL_XA = CDIO_FS_ANAL_XA,+ FS_ANAL_MULTISESSION = CDIO_FS_ANAL_MULTISESSION,+ FS_ANAL_PHOTO_CD = CDIO_FS_ANAL_PHOTO_CD,+ FS_ANAL_HIDDEN_TRACK = CDIO_FS_ANAL_HIDDEN_TRACK,+ FS_ANAL_CDTV = CDIO_FS_ANAL_CDTV,+ FS_ANAL_BOOTABLE = CDIO_FS_ANAL_BOOTABLE,+ FS_ANAL_VIDEOCD = CDIO_FS_ANAL_VIDEOCD,+ FS_ANAL_ROCKRIDGE = CDIO_FS_ANAL_ROCKRIDGE,+ FS_ANAL_JOLIET = CDIO_FS_ANAL_JOLIET,+ FS_ANAL_SVCD = CDIO_FS_ANAL_SVCD,+ FS_ANAL_CVD = CDIO_FS_ANAL_CVD,+ FS_ANAL_XISO = CDIO_FS_ANAL_XISO,+ FS_ANAL_ISO9660_ANY = CDIO_FS_ANAL_ISO9660_ANY+} fs_cap_t;+++#endif
+ include/cdio/compat/cdtext.h view
@@ -0,0 +1,36 @@+#ifndef __CDIO_COMPAT_CDTEXT__+#define __CDIO_COMPAT_CDTEXT__+++#include "cdio/cdtext.h"++#include "stdint.h"++// Required for 'DriverReturnCode' for some reason+#include "cdio/cdio.h"+++// Defined in a private header+#define CDTEXT_NUM_BLOCKS_MAX 8+++// FFI-compatible wrappers++cdtext_genre_t genre_unused();++cdtext_lang_t language_unknown();+cdtext_lang_t language_invalid();+cdtext_lang_t language_unused();+++// Symbol compatibility definitions++cdtext_lang_t cdtext_str2lang_safe(const char*);++int cdtext_data_init_safe(cdtext_t*, uint8_t*, size_t);++cdtext_lang_t* cdtext_list_languages_v2_safe(cdtext_t*);+bool cdtext_set_language_index_safe(cdtext_t*, int);+++#endif
+ include/cdio/compat/cycle_break.h view
@@ -0,0 +1,14 @@+#ifndef __CDIO_COMPAT_CYCLE_BREAK__+#define __CDIO_COMPAT_CYCLE_BREAK__+++// Several cdio headers don't support direct inclusion (they invoke cdio.h,+// which in turn brings in read.h before the device definitions that one needs)+// so short-circuit that loop by pretending cdio.h has already been processed.+#define __CDIO_H__++// That then requires the one symbol defined in cdio.h be created manually:+typedef struct _CdIo CdIo_t;+++#endif
+ include/cdio/compat/device.h view
@@ -0,0 +1,42 @@+#ifndef __CDIO_COMPAT_DEVICE__+#define __CDIO_COMPAT_DEVICE__+++#include "cdio/compat/cycle_break.h"+#include "cdio/device.h"+++// FFI-compatible wrappers++const unsigned int vendor_len();+const unsigned int model_len();+const unsigned int revision_len();++bitfield_t drive_cap_error();+bitfield_t drive_cap_unknown();++const driver_id_t* get_drivers();+const driver_id_t* get_device_drivers();+const driver_id_t get_os_driver();+++// Symbol compatibility definitions++#if LIBCDIO_SINCE_VERSION_1_0+// Keep the old enum values around, for broader compatibility.+#define DRIVER_BSDI (DRIVER_DEVICE+1)+#define DRIVER_OS2 (DRIVER_DEVICE+2)+#endif++CdIo_t* cdio_open_bsdi_safe(const char*);+CdIo_t* cdio_open_am_bsdi_safe(const char*, const char*);+char* cdio_get_default_device_bsdi_safe();+char** cdio_get_devices_bsdi_safe();++CdIo_t* cdio_open_os2_safe(const char*);+CdIo_t* cdio_open_am_os2_safe(const char*, const char*);+char* cdio_get_default_device_os2_safe();+char** cdio_get_devices_os2_safe();+++#endif
+ include/cdio/compat/disc.h view
@@ -0,0 +1,25 @@+#ifndef __CDIO_COMPAT_DISC__+#define __CDIO_COMPAT_DISC__+++#include "cdio/compat/cycle_break.h"+#include "cdio/compat/cdtext.h"+#include "cdio/disc.h"++#include "cdio/compat/track.h"+#include "cdio/compat/types.h"+++// FFI-compatible wrappers++const char* discmode_string(discmode_t);++discmode_t discmode_error();+++// Marshalling aids++void get_cdtext_raw_len(CdIo_t*, uint8_t**, unsigned int*);+++#endif
+ include/cdio/compat/logging.h view
@@ -0,0 +1,33 @@+#ifndef __CDIO_COMPAT_LOGGING__+#define __CDIO_COMPAT_LOGGING__++// Custom in-memory log management+++#include "cdio/compat/cycle_break.h"+#include "cdio/logging.h"+++// Combination log entry and linked list+typedef struct cdio_log_entry_s {+ cdio_log_level_t level;+ const char* message;+ struct cdio_log_entry_s* prev;+} cdio_log_entry_t;++// Root of the afore-mentioned linked list+cdio_log_entry_t* haskell_log;++// Register the custom handler with libcdio+void setup_cdio_logger();++// Control message filtering+cdio_log_level_t get_cdio_log_level();+void set_cdio_log_level(cdio_log_level_t);++// Access/clear the accumulated list+cdio_log_entry_t** read_cdio_log();+void free_cdio_log();+++#endif
+ include/cdio/compat/mmc.h view
@@ -0,0 +1,9 @@+#ifndef __CDIO_COMPAT_MMC__+#define __CDIO_COMPAT_MMC__+++#include "cdio/compat/device.h"+#include "cdio/mmc.h"+++#endif
+ include/cdio/compat/read.h view
@@ -0,0 +1,39 @@+#ifndef __CDIO_COMPAT_READ__+#define __CDIO_COMPAT_READ__+++#include "cdio/compat/device.h"+#include "cdio/read.h"++#include "unistd.h"+++// FFI-compatible wrappings++typedef enum {+ WHENCE_SEEK_START = SEEK_SET,+ WHENCE_SEEK_CURRENT = SEEK_CUR,+ WHENCE_SEEK_END = SEEK_END+} whence_t;+++// Marshalling aids++void read_bytes(const CdIo_t*, void**, ssize_t*, size_t);++driver_return_code_t read_sector(const CdIo_t*, void**, uint32_t*, lsn_t, cdio_read_mode_t);+driver_return_code_t read_sectors(const CdIo_t*, void**, uint32_t*, lsn_t, cdio_read_mode_t, uint32_t);++driver_return_code_t read_data_sectors(const CdIo_t*, void**, uint32_t*, lsn_t, uint16_t, uint32_t);++driver_return_code_t read_audio_sector(const CdIo_t*, void**, uint32_t*, lsn_t);+driver_return_code_t read_audio_sectors(const CdIo_t*, void**, uint32_t*, lsn_t, uint32_t);++driver_return_code_t read_mode1_sector(const CdIo_t*, void**, uint32_t*, lsn_t, bool);+driver_return_code_t read_mode1_sectors(const CdIo_t*, void**, uint32_t*, lsn_t, bool, uint32_t);++driver_return_code_t read_mode2_sector(const CdIo_t*, void**, uint32_t*, lsn_t, bool);+driver_return_code_t read_mode2_sectors(const CdIo_t*, void**, uint32_t*, lsn_t, bool, uint32_t);+++#endif
+ include/cdio/compat/sector.h view
@@ -0,0 +1,60 @@+#ifndef __CDIO_COMPAT_SECTOR__+#define __CDIO_COMPAT_SECTOR__+++#include "cdio/sector.h"++#include "stdint.h"+++// FFI-compatible wrappings++lsn_t min_lsn();+lsn_t max_lsn();++lba_t invalid_lba();+lsn_t invalid_lsn();++size_t sizeof_msf();++unsigned int pregap_sectors();+unsigned int postgap_sectors();++unsigned int cd_mins();+unsigned int secs_per_min();+unsigned int frames_per_min();+unsigned int frames_per_sec();+unsigned int chunks_per_frame();++unsigned int min_session();+unsigned int max_session();++unsigned int sync_size();+unsigned int chunk_size();+unsigned int framesize_sub();++unsigned int header_size();+unsigned int subheader_size();+unsigned int edc_size();+unsigned int mode1_pad_size();+unsigned int ecc_size();++unsigned int framesize();+unsigned int framesize_raw();+unsigned int framesize_rawer();+unsigned int framesize_raw0();+unsigned int framesize_raw1();++unsigned int header_size_xa();+unsigned int tail_size_xa();+unsigned int sync_size_xa();+unsigned int data_size_xa();+unsigned int tagged_size_xa();+++const uint8_t* sector_sync_header();++cdio_cd_minutes_sectors max_sectors();+++#endif
+ include/cdio/compat/track.h view
@@ -0,0 +1,21 @@+#ifndef __CDIO_COMPAT_TRACK__+#define __CDIO_COMPAT_TRACK__+++#include "cdio/compat/types.h"+#include "cdio/track.h"+++// FFI-compatible wrappings++const char* track_format_string(track_format_t);++track_t invalid_track();+track_t leadout_track();+track_t min_tracks();+track_t max_tracks();++track_format_t track_format_error();+++#endif
+ include/cdio/compat/types.h view
@@ -0,0 +1,13 @@+#ifndef __CDIO_COMPAT_TYPES__+#define __CDIO_COMPAT_TYPES__+++#include "cdio/compat/cycle_break.h"+#include "cdio/types.h"+++unsigned char mcn_length();+unsigned char isrc_length();+++#endif
+ include/cdio/compat/version.h view
@@ -0,0 +1,25 @@+#ifndef __CDIO_COMPAT_VERSION__+#define __CDIO_COMPAT_VERSION__+++#include "cdio/cdio.h"+#include "cdio/version.h"+++// FFI-compatible wrappings++const char* get_cdio_version_string();+const unsigned int get_cdio_version_num();+const unsigned int get_cdio_version_api();+++// Base library compatibility testing++#define LIBCDIO_SINCE_VERSION_0_94 (LIBCDIO_VERSION_NUM >= 94 || LIBCDIO_VERSION_NUM == 1)+#define LIBCDIO_SINCE_VERSION_1_0 (LIBCDIO_VERSION_NUM >= 10000 || LIBCDIO_VERSION_NUM == 1)+#define LIBCDIO_SINCE_VERSION_1_1 (LIBCDIO_VERSION_NUM >= 10100)+#define LIBCDIO_SINCE_VERSION_2_0 (LIBCDIO_VERSION_NUM >= 20000)+#define LIBCDIO_SINCE_VERSION_2_1 (LIBCDIO_VERSION_NUM >= 20100)+++#endif
+ src/Data/Text/Encoding/MsJIS.hs view
@@ -0,0 +1,1566 @@+{-# LANGUAGE Trustworthy #-}++{-|+Description: Basic support for the Microsoft extension of Shift JIS.++Copyright: (c) 2020-2021 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: stable+Portability: portable++The CdText standard technically allows for data encoded as Shift JIS; I am+unaware of any discs produced with such data as no member of the libcdio-dev+mailing list (or any of the very few other resources) have Japanese imports,+but for completion the ability to read that encoding is required. This module+provides a light-weight implementation modeled on the "Data.Text.Encoding"+UTF-8 interface.+-}+module Data.Text.Encoding.MsJIS+ ( -- * Types+ JISChar ( .. )+ , JISDecodeError ( .. )+ , JISEncodeError ( .. )+ -- * Transformations+ -- ** Decode+ , decodeMsJIS'+ , decodeMsJISWith+ -- ** Encode+ , encodeMsJIS'+ , encodeMsJISWith+ ) where+++import qualified Data.ByteString as BS+import qualified Data.IntMap as M+import qualified Data.Maybe as Y+import qualified Data.Text as T+import qualified Data.Text.Encoding.Error as T+import qualified Data.Vector as V+import qualified Data.Word as W++import Data.Vector ( (!) )+++-- | A shorthand categorization scheme for representing the effect of a single+-- byte in the absence of existing context.+data First+ = None+ -- ^ The byte is invalid, perhaps unless preceded by a lead byte.+ | Lone Char+ -- ^ It represents the given character when not preceded by a lead+ -- byte.+ | Lead+ -- ^ The representation is dependant on the next byte in the stream.+ deriving ( Eq, Ord, Show, Read )++-- | The characters which may be represented under the Shift JIS encoding.+-- Note that this type is only exposed as part of error reporting or recovery+-- functions, and is not intended as a replacement of 'Char'.+data JISChar+ = Single W.Word8+ | Double W.Word8 W.Word8+ deriving ( Eq, Ord, Show, Read )+instance Bounded JISChar where+ minBound = Single minBound+ maxBound = Double 0xFC 0xFC+-- | Ignores the three invalid single-byte characters @"\xFD\xFE\xFF"@, and any+-- double-byte characters outside the primary range+-- @([0x81..0x9F]++[0xE0..0xFC], [0x40..0xFC])@. 'fromEnum' any such "invalid"+-- characters will overlap with the canonical characters, and the result should+-- not be relied upon to remain consistent between versions.+-- +-- >>> succ $ Single 0xFC+-- Double 0x81 0x40+-- +-- >>> succ $ Double 0x9F 0xFC+-- Double 0xE0 0x40+instance Enum JISChar where+ toEnum i+ | i <= 0xFC = Single $ fromIntegral i+ | otherwise = Double l t+ where (d, m) = divMod (i - 0xFD) 0xBC+ l = fromIntegral d + if d >= 0x1F+ -- First index of second table group (0xE0) minus first value of d here (0x1F)+ then 0xC1+ -- First index of first table group+ else 0x81+ -- First byte in trail tables+ t = fromIntegral m + 0x40+ fromEnum (Single c) = fromIntegral c+ -- Underlying: @s + (l' * x) + (t - y) + 1@+ -- + -- s = Last single char (0xFC)+ -- l' = Table index (in [0x81..0x9F]++[0xE0..0xFC]): @l - w@+ -- l = Lead byte+ -- w = First byte of either first group (0x81) or second (0xE0)+ -- x = Length of tables (0xBC)+ -- t = Trail byte+ -- y = First byte in trail tables (0x40)+ -- + -- s - y + 1 = 0xBD+ fromEnum (Double l t) = (l' * 0xBC) + fromIntegral t + 0xBD+ where l' = fromIntegral l - if l > 0x9F then 0xE0 else 0x81+++-- | The given one- or two- byte sequence was unable to be decoded; the error+-- may be described by the unstructured text.+data JISDecodeError = JISDecodeError String (Maybe JISChar)+ deriving ( Eq, Show, Read )++-- | The given character was unable to be serialized in binary form; this is+-- almost certainly due to it not being included in Shift JIS, but the error is+-- described by the unstructured text anyway.+data JISEncodeError = JISEncodeError String (Maybe Char)+ deriving ( Eq, Show, Read )+++-- | Lookup table for the broad category a byte falls into when not preceded+-- by a lead byte.+type FirstByteTable = V.Vector First++-- | The characters a two-byte sequence may decode to under the context of a+-- given lead byte.+type SecondByteTable = V.Vector (Maybe Char)+++-- | Transform a 'BS.ByteString' into unambiguous 'Char's according to+-- Microsoft's extension of the Shift JIS encoding scheme.+--+-- If the input contains any invalid sequences under that scheme, the first+-- byte(s) which triggered an error will be returned instead.+decodeMsJIS' :: BS.ByteString -> Either JISDecodeError T.Text+decodeMsJIS' = fmap T.pack . decodeMsJIS'' . BS.unpack++-- | Iterate through the byte stream, consuming one or two bytes each cycle as+-- required to decode a Shift JIS character.+--+-- If the input contains any invalid sequences under that scheme, the first+-- byte(s) which triggered an error will be returned instead.+decodeMsJIS'' :: [W.Word8] -> Either JISDecodeError String+decodeMsJIS'' [] = Right ""+decodeMsJIS'' (b1:bs) = case lookupJIS b1 $ Y.listToMaybe bs of+ (Left err, _) -> Left err+ (Right c, w) -> fmap (c :) . decodeMsJIS'' $ if w then drop 1 bs else bs+++-- | Transform a 'BS.ByteString' into unambiguous 'Char's according to+-- Microsoft's extension of the Shift JIS encoding scheme.+decodeMsJISWith :: T.OnError JISChar Char -> BS.ByteString -> T.Text+decodeMsJISWith e = T.pack . decodeMsJISWith' e . BS.unpack++-- | Iterate through the byte stream, consuming one or two bytes each cycle as+-- required to decode a Shift JIS character.+decodeMsJISWith' :: T.OnError JISChar Char -> [W.Word8] -> String+decodeMsJISWith' _ [] = ""+decodeMsJISWith' e (b1:bs) = case lookupJIS b1 $ Y.listToMaybe bs of+ (Left (JISDecodeError msg err), w) -> maybe (loop w) (: loop w) $ e msg err+ (Right c, w) -> c : loop w+ where loop _ | null bs = ""+ loop w = decodeMsJISWith' e $ if w then drop 1 bs else bs+++-- | Transform an unambiguous string into a binary stream according to+-- Microsoft's extension of the Shift JIS encoding scheme.+--+-- If the input contains any characters without an associated binary sequence+-- under that scheme, the first such character which triggers the error will be+-- returned instead.+encodeMsJIS' :: T.Text -> Either JISEncodeError BS.ByteString+encodeMsJIS' = T.foldl' (\bs -> throwEncode bs . flatten . lookupUnicode) (Right BS.empty)+ where throwEncode e@(Left _) _ = e+ throwEncode _ (Left c) = Left $ JISEncodeError (encodeErrorString "encodeMsJIS'") c+ throwEncode (Right bs) (Right bs') = Right $ mappend bs bs'++-- | Transform an unambiguous string into a binary stream according to+-- Microsoft's extension of the Shift JIS encoding scheme.+encodeMsJISWith :: T.OnError Char BS.ByteString -> T.Text -> BS.ByteString+encodeMsJISWith e = T.foldl' (\bs -> throwEncode bs . flatten . lookupUnicode) BS.empty+ where throwEncode bs (Left c) = Y.fromMaybe bs $ e (encodeErrorString "encodeMsJISWith") c+ throwEncode bs (Right bs') = mappend bs bs'++-- | There is only a single reason why encoding to Shift JIS may fail.+encodeErrorString :: String -> String+encodeErrorString func = func ++ ": Character not in MS JIS"++-- | Rewrap the result of a character-to-binary lookup into a form suitable for+-- 'JISEncodeError'.+flatten :: Either Char [BS.ByteString] -> Either (Maybe Char) BS.ByteString+flatten (Right []) = Left Nothing+flatten (Right (bs:_)) = Right bs+flatten (Left e) = Left $ Just e+++-- | The broad categories defining the behaviour of a byte in the Shift JIS+-- encoding scheme, in the absence of any existing context. May be safely+-- indexed using any integer fitting into eight bits:+--+-- >>> length firstBytes+-- 255+firstBytes :: FirstByteTable+firstBytes = V.fromList $+ {-0x00..0x7F-} map Lone ['\NUL'..'\DEL'] +++ {-0x80..0x9F-} None : replicate 0x1F Lead +++ {-0xA0..0xDF-} None : map Lone ['\xFF61'..'\xFF9F'] +++ {-0xE0..0xFC-} replicate 0x1D Lead +++ {-0xFD..0xFF-} replicate 3 None++-- | The lookup tables describing the representation of any valid two-byte+-- sequence in the Shift JIS encoding scheme. As not every byte is a valid+-- lead byte (and thus may not have an indexed table), @lookupTrailTable@ is+-- recommended rather than direct indexing. The presence or absence of a valid+-- character does not affect whether the subtable may be safely indexed:+--+-- >>> V.all ((==) 0xBC . length) secondBytes+-- True+secondBytes :: V.Vector SecondByteTable+secondBytes = V.fromList $+ [ second81, second82, second83, second84, second85, second86, second87 ] +++ [ second88, second89, second8A, second8B, second8C, second8D, second8E, second8F ] +++ [ second90, second91, second92, second93, second94, second95, second96, second97 ] +++ [ second98, second99, second9A, second9B, second9C, second9D, second9E, second9F ] +++ [ secondE0, secondE1, secondE2, secondE3, secondE4, secondE5, secondE6, secondE7 ] +++ [ secondE8, secondE9, secondEA, secondEB, secondEC, secondED, secondEE, secondEF ] +++ [ secondF0, secondF1, secondF2, secondF3, secondF4, secondF5, secondF6, secondF7 ] +++ [ secondF8, secondF9, secondFA, secondFB, secondFC ]++-- | Try to decode a one- or two-byte sequence to an unambiguous character+-- according to the Shift JIS encoding scheme. Returns a 'Bool' indicating+-- whether the second byte was used in decoding the 'Char' (i.e., 'False'+-- indicates that the next character starts /on/ the second byte given rather+-- than /after/ it).+lookupJIS :: W.Word8 -> Maybe W.Word8 -> (Either JISDecodeError Char, Bool)+lookupJIS l t' = case (lookupLead l, t') of+ (SingleByte c, _) -> (Right c, False)+ (MultiByte _, Nothing) -> (err "Input ended without trail byte" $ Single l, False)+ (MultiByte ts, Just t) ->+ let found = ts ! (fromIntegral t - 0x40)+ in (maybe (err "Unassigned trail byte" $ Double l t) Right found, True)+ (NoChar e, _) -> (Left e, False)+ where err msg char = Left . JISDecodeError ("lookupJIS: " ++ msg) $ Just char++-- | Given the first byte in a (potentially multibyte) Shift JIS binary+-- representation, try to retrieve the associated character.+lookupLead :: W.Word8 -> LeadResult+lookupLead w = case firstBytes ! fromIntegral w of+ Lone c -> SingleByte c+ Lead -> maybe (err "Invalid lead byte") MultiByte $ lookupTrailTable w+ None -> err "Unassigned lead byte"+ where err msg = NoChar . JISDecodeError ("lookupJIS: " ++ msg) . Just $ Single w++-- | The potential values which may result from looking up a single byte in the+-- Shift JIS scheme without any preceding context.+data LeadResult+ = SingleByte Char+ -- ^ The byte represents a complete character.+ | MultiByte SecondByteTable+ -- ^ The byte indicates one of a set of characters which may only be+ -- disambiguated by the next byte in the stream.+ | NoChar JISDecodeError+ -- ^ The byte itself is invalid.++-- | Given the first byte in a multibyte Shift JIS binary representation, look+-- up what characters may be represented depending on the following byte in the+-- stream. If the input is not a valid lead byte, 'Nothing' is returned+-- instead. The presence or absence of a valid character does not affect+-- whether the subtable may be safely indexed (but note that position @0@ is+-- associated with byte @0x40@):+--+-- >>> maybe True ((==) 0xBC . length) $ lookupTrailTable b+-- True+lookupTrailTable :: W.Word8 -> Maybe SecondByteTable+lookupTrailTable l+ | l < 0x81 ||+ (l > 0x9F && l < 0xE0) ||+ l > 0xFC = Nothing+ | l <= 0x9F = Just $ secondBytes ! (fromIntegral l - 0x81)+ | otherwise = Just $ secondBytes ! (fromIntegral l - 0xC1)++++-- | The lookup table from Unicode character reference number to Shift JIS+-- binary representation.+unicodeMap :: M.IntMap [JISChar]+unicodeMap = M.fromListWith (++) . V.toList $+ V.imapMaybe keyFirsts firstBytes V.++ V.concat (V.toList $ V.imap keySeconds secondBytes)++-- | Transformation function to obtain a lookup-tuple from a single-byte Shift+-- JIS representation.+keyFirsts+ :: Int+ -- ^ The index (i.e., the byte itself) in the list of single- and+ -- lead-byte categories.+ -> First+ -- ^ The category associated with that byte; everything /except/ @Lone@+ -- bytes will be ignored.+ -> Maybe (M.Key, [JISChar])+keyFirsts l (Lone j) = Just (fromEnum j, [Single $ fromIntegral l])+keyFirsts _ _ = Nothing++-- | Transformation function to obtain all lookup-tuples of double-byte Shift+-- JIS representations beginning with the given byte.+keySeconds+ :: Int+ -- ^ The index (i.e., the byte itself) in the list of single- and+ -- lead-byte categories.+ -> SecondByteTable+ -- ^ The trailing-byte lookup table associated with that lead byte.+ -> V.Vector (M.Key, [JISChar])+keySeconds l = V.imapMaybe (\t j -> m (Double l' $ fromIntegral t + 0x40) <$> j)+ where l' = fromIntegral $ l + if l < 0x1F then 0x81 else 0xC1+ m t' j' = (fromEnum j', [t'])+++-- | Given a particular character, retrieve all its potential binary+-- representations in the Shift JIS encoding scheme.+lookupUnicode :: Char -> Either Char [BS.ByteString]+lookupUnicode c = case M.lookup (fromEnum c) unicodeMap of+ Just js -> Right $ map pack js+ Nothing -> Left c+ where pack (Single w) = BS.singleton w+ pack (Double l t) = BS.pack [l, t]+++-- * Multi-byte lookup tables++-- | A continuous sequence of valid multibyte characters.+chars :: String -> [Maybe Char]+chars = map Just++-- | A continuous sequence of unassigned multibyte characters.+nothings :: Int -> [Maybe Char]+nothings = flip replicate Nothing++-- | Generate an entire table of "valid" multibyte characters, without any+-- actual assigned characters.+nothingSecond :: SecondByteTable+nothingSecond = V.replicate 0xC0 Nothing++-- | Generate an entire table of multibyte characters which map to a portion of+-- the Private Use Area (i.e., are reserved for program- or company-internal+-- use).+privateUseSecond :: W.Word16 -> SecondByteTable+privateUseSecond b = V.fromList $+ {-0x40..0x7F-} map (Just . toEnum . fromIntegral) [b..b + 0x3E] ++ Nothing :+ {-0x80..0xFC-} map (Just . toEnum . fromIntegral) [b + 0x3F..b + 0xBB]+++-- | The multibyte characters with a lead byte of @0x81@.+second81 :: SecondByteTable+second81 = V.fromList $+ {-0x40-} chars "\x3000\x3001\x3002\xFF0C\xFF0E\x30FB\xFF1A\xFF1B" +++ {-0x48-} chars "\xFF1F\xFF01\x309B\x309C\x00B4\xFF40\x00A8\xFF3E" +++ {-0x50-} chars "\xFFE3\xFF3F\x30FD\x30FE\x309D\x309E\x3003\x4EDD" +++ {-0x58-} chars "\x3005\x3006\x3007\x30FC\x2015\x2010\xFF0F\xFF3C" +++ {-0x60-} chars "\xFF5E\x2225\xFF5C\x2026\x2025\x2018\x2019\x201C" +++ {-0x68-} chars "\x201D\xFF08\xFF09\x3014\x3015\xFF3B\xFF3D\xFF5B" +++ {-0x70-} chars "\xFF5D\x3008\x3009\x300A\x300B\x300C\x300D\x300E" +++ {-0x78-} chars "\x300F\x3010\x3011\xFF0B\xFF0D\x00B1\x00D7" ++ Nothing :+ {-0x80-} chars "\x00F7\xFF1D\x2260\xFF1C\xFF1E\x2266\x2267\x221E" +++ {-0x88-} chars "\x2234\x2642\x2640\x00B0\x2032\x2033\x2103\xFFE5" +++ {-0x90-} chars "\xFF04\xFFE0\xFFE1\xFF05\xFF03\xFF06\xFF0A\xFF20" +++ {-0x98-} chars "\x00A7\x2606\x2605\x25CB\x25CF\x25CE\x25C7\x25C6" +++ {-0xA0-} chars "\x25A1\x25A0\x25B3\x25B2\x25BD\x25BC\x203B\x3012" +++ {-0xA8-} chars "\x2192\x2190\x2191\x2193\x3013" ++ nothings 3 +++ {-0xB0-} nothings 8 +++ {-0xB8-} chars "\x2208\x220B\x2286\x2287\x2282\x2283\x222A\x2229" +++ {-0xC0-} nothings 8 +++ {-0xC8-} chars "\x2227\x2228\xFFE2\x21D2\x21D4\x2200\x2203" ++ Nothing :+ {-0xD0-} nothings 8 +++ {-0xD8-} nothings 2 ++ chars "\x2220\x22A5\x2312\x2202\x2207\x2261" +++ {-0xE0-} chars "\x2252\x226A\x226B\x221A\x223D\x221D\x2235\x222B" +++ {-0xE8-} Just '\x222C' : nothings 7 +++ {-0xF0-} chars "\x212B\x2030\x266F\x266D\x266A\x2020\x2021\x00B6" +++ {-0xF8-} nothings 4 ++ [Just '\x25EF']++-- | The multibyte characters with a lead byte of @0x82@.+second82 :: SecondByteTable+second82 = V.fromList $+ {-0x40..0x4E-} nothings 15 +++ {-0x4F..0x58-} chars ['\xFF10'..'\xFF19'] +++ {-0x59..0x5F-} nothings 7 +++ {-0x60..0x79-} chars ['\xFF21'..'\xFF3A'] +++ {-0x7A..0x80-} nothings 7 +++ {-0x81..0x9A-} chars ['\xFF41'..'\xFF5A'] +++ {-0x9B..0x9E-} nothings 4 +++ {-0x9F..0xF1-} chars ['\x3041'..'\x3093'] +++ {-0xF2..0xFC-} nothings 11++-- | The multibyte characters with a lead byte of @0x83@.+second83 :: SecondByteTable+second83 = V.fromList $+ {-0x40..0x7F-} chars ['\x30A1'..'\x30DF'] ++ Nothing :+ {-0x80..0x96-} chars ['\x30E0'..'\x30F6'] +++ {-0x97..0x9E-} nothings 8 +++ {-0x9F..0xAF-} chars ['\x0391'..'\x03A1'] +++ {-0xB0..0xB6-} chars ['\x03A3'..'\x03A9'] +++ {-0xB7..0xBE-} nothings 8 +++ {-0xBF..0xCF-} chars ['\x03B1'..'\x03C1'] +++ {-0xD0..0xD6-} chars ['\x03C3'..'\x03C9'] +++ {-0xD7..0xFC-} nothings 0x26++-- | The multibyte characters with a lead byte of @0x84@.+second84 :: SecondByteTable+second84 = V.fromList $+ {-0x40..0x46-} chars ['\x0410'..'\x0415'] ++ Just '\x0401' :+ {-0x47..0x60-} chars ['\x0416'..'\x042F'] +++ {-0x61..0x6F-} nothings 15 +++ {-0x60..0x66-} chars ['\x0430'..'\x0435'] ++ Just '\x0451' :+ {-0x67..0x7F-} chars ['\x0436'..'\x043D'] ++ Nothing :+ {-0x80..0x91-} chars ['\x043E'..'\x044F'] +++ {-0x92..0x9F-} nothings 13 ++ Just '\x2500' :+ {-0xA0-} chars "\x2502\x250C\x2510\x2518\x2514\x251C\x252C\x2524" +++ {-0xA8-} chars "\x2534\x253C\x2501\x2503\x250F\x2513\x251B\x2517" +++ {-0xB0-} chars "\x2523\x2533\x252B\x253B\x254B\x2520\x252F\x2528" +++ {-0xB8-} chars "\x2537\x253F\x251D\x2530\x2525\x2538\x2542" +++ {-0xBF..0xFC-} nothings 0x3E++-- | The multibyte characters with a lead byte of @0x85@.+second85 :: SecondByteTable+second85 = nothingSecond++-- | The multibyte characters with a lead byte of @0x86@.+second86 :: SecondByteTable+second86 = nothingSecond++-- | The multibyte characters with a lead byte of @0x87@.+second87 :: SecondByteTable+second87 = V.fromList $+ {-0x40..0x53-} chars ['\x2460'..'\x2473'] +++ {-0x54..0x5F-} chars ['\x2160'..'\x2169'] ++ Nothing : Just '\x3349' :+ {-0x60-} chars "\x3314\x3322\x334D\x3318\x3327\x3303\x3336\x3351" +++ {-0x68-} chars "\x3357\x330D\x3326\x3323\x332B\x334A\x333B\x339C" +++ {-0x70-} chars "\x339D\x339E\x338E\x338F\x33C4\x33A1" +++ {-0x76..0x7F-} nothings 8 ++ Just '\x337B' : Nothing :+ {-0x80-} chars "\x301D\x301F\x2116\x33CD\x2121\x32A4\x32A5\x32A6" +++ {-0x88-} chars "\x32A7\x32A8\x3231\x3232\x3239\x337E\x337D\x337C" +++ {-0x90-} chars "\x2252\x2261\x222B\x222E\x2211\x221A\x22A5\x2220" +++ {-0x98-} chars "\x221F\x22BF\x2235\x2229\x222A" +++ {-0x9D..0xFC-} nothings 0x60++-- | The multibyte characters with a lead byte of @0x88@.+second88 :: SecondByteTable+second88 = V.fromList $+ {-0x40..0x9F-} nothings 0x5F ++ Just '\x4E9C' :+ {-0xA0-} chars "\x5516\x5A03\x963F\x54C0\x611B\x6328\x59F6\x9022" +++ {-0xA8-} chars "\x8475\x831C\x7A50\x60AA\x63E1\x6E25\x65ED\x8466" +++ {-0xB0-} chars "\x82A6\x9BF5\x6893\x5727\x65A1\x6271\x5B9B\x59D0" +++ {-0xB8-} chars "\x867B\x98F4\x7D62\x7DBE\x9B8E\x6216\x7C9F\x88B7" +++ {-0xC0-} chars "\x5B89\x5EB5\x6309\x6697\x6848\x95C7\x978D\x674F" +++ {-0xC8-} chars "\x4EE5\x4F0A\x4F4D\x4F9D\x5049\x56F2\x5937\x59D4" +++ {-0xD0-} chars "\x5A01\x5C09\x60DF\x610F\x6170\x6613\x6905\x70BA" +++ {-0xD8-} chars "\x754F\x7570\x79FB\x7DAD\x7DEF\x80C3\x840E\x8863" +++ {-0xE0-} chars "\x8B02\x9055\x907A\x533B\x4E95\x4EA5\x57DF\x80B2" +++ {-0xE8-} chars "\x90C1\x78EF\x4E00\x58F1\x6EA2\x9038\x7A32\x8328" +++ {-0xF0-} chars "\x828B\x9C2F\x5141\x5370\x54BD\x54E1\x56E0\x59FB" +++ {-0xF8-} chars "\x5F15\x98F2\x6DEB\x80E4\x852D"++-- | The multibyte characters with a lead byte of @0x89@.+second89 :: SecondByteTable+second89 = V.fromList $+ {-0x40-} chars "\x9662\x9670\x96A0\x97FB\x540B\x53F3\x5B87\x70CF" +++ {-0x48-} chars "\x7FBD\x8FC2\x96E8\x536F\x9D5C\x7ABA\x4E11\x7893" +++ {-0x50-} chars "\x81FC\x6E26\x5618\x5504\x6B1D\x851A\x9C3B\x59E5" +++ {-0x58-} chars "\x53A9\x6D66\x74DC\x958F\x5642\x4E91\x904B\x96F2" +++ {-0x60-} chars "\x834F\x990C\x53E1\x55B6\x5B30\x5F71\x6620\x66F3" +++ {-0x68-} chars "\x6804\x6C38\x6CF3\x6D29\x745B\x76C8\x7A4E\x9834" +++ {-0x70-} chars "\x82F1\x885B\x8A60\x92ED\x6DB2\x75AB\x76CA\x99C5" +++ {-0x78-} chars "\x60A6\x8B01\x8D8A\x95B2\x698E\x53AD\x5186" ++ Nothing :+ {-0x80-} chars "\x5712\x5830\x5944\x5BB4\x5EF6\x6028\x63A9\x63F4" +++ {-0x88-} chars "\x6CBF\x6F14\x708E\x7114\x7159\x71D5\x733F\x7E01" +++ {-0x90-} chars "\x8276\x82D1\x8597\x9060\x925B\x9D1B\x5869\x65BC" +++ {-0x98-} chars "\x6C5A\x7525\x51F9\x592E\x5965\x5F80\x5FDC\x62BC" +++ {-0xA0-} chars "\x65FA\x6A2A\x6B27\x6BB4\x738B\x7FC1\x8956\x9D2C" +++ {-0xA8-} chars "\x9D0E\x9EC4\x5CA1\x6C96\x837B\x5104\x5C4B\x61B6" +++ {-0xB0-} chars "\x81C6\x6876\x7261\x4E59\x4FFA\x5378\x6069\x6E29" +++ {-0xB8-} chars "\x7A4F\x97F3\x4E0B\x5316\x4EEE\x4F55\x4F3D\x4FA1" +++ {-0xC0-} chars "\x4F73\x52A0\x53EF\x5609\x590F\x5AC1\x5BB6\x5BE1" +++ {-0xC8-} chars "\x79D1\x6687\x679C\x67B6\x6B4C\x6CB3\x706B\x73C2" +++ {-0xD0-} chars "\x798D\x79BE\x7A3C\x7B87\x82B1\x82DB\x8304\x8377" +++ {-0xD8-} chars "\x83EF\x83D3\x8766\x8AB2\x5629\x8CA8\x8FE6\x904E" +++ {-0xE0-} chars "\x971E\x868A\x4FC4\x5CE8\x6211\x7259\x753B\x81E5" +++ {-0xE8-} chars "\x82BD\x86FE\x8CC0\x96C5\x9913\x99D5\x4ECB\x4F1A" +++ {-0xF0-} chars "\x89E3\x56DE\x584A\x58CA\x5EFB\x5FEB\x602A\x6094" +++ {-0xF8-} chars "\x6062\x61D0\x6212\x62D0\x6539"++-- | The multibyte characters with a lead byte of @0x8A@.+second8A :: SecondByteTable+second8A = V.fromList $+ {-0x40-} chars "\x9B41\x6666\x68B0\x6D77\x7070\x754C\x7686\x7D75" +++ {-0x48-} chars "\x82A5\x87F9\x958B\x968E\x8C9D\x51F1\x52BE\x5916" +++ {-0x50-} chars "\x54B3\x5BB3\x5D16\x6168\x6982\x6DAF\x788D\x84CB" +++ {-0x58-} chars "\x8857\x8A72\x93A7\x9AB8\x6D6C\x99A8\x86D9\x57A3" +++ {-0x60-} chars "\x67FF\x86CE\x920E\x5283\x5687\x5404\x5ED3\x62E1" +++ {-0x68-} chars "\x64B9\x683C\x6838\x6BBB\x7372\x78BA\x7A6B\x899A" +++ {-0x70-} chars "\x89D2\x8D6B\x8F03\x90ED\x95A3\x9694\x9769\x5B66" +++ {-0x78-} chars "\x5CB3\x697D\x984D\x984E\x639B\x7B20\x6A2B" ++ Nothing :+ {-0x80-} chars "\x6A7F\x68B6\x9C0D\x6F5F\x5272\x559D\x6070\x62EC" +++ {-0x88-} chars "\x6D3B\x6E07\x6ED1\x845B\x8910\x8F44\x4E14\x9C39" +++ {-0x90-} chars "\x53F6\x691B\x6A3A\x9784\x682A\x515C\x7AC3\x84B2" +++ {-0x98-} chars "\x91DC\x938C\x565B\x9D28\x6822\x8305\x8431\x7CA5" +++ {-0xA0-} chars "\x5208\x82C5\x74E6\x4E7E\x4F83\x51A0\x5BD2\x520A" +++ {-0xA8-} chars "\x52D8\x52E7\x5DFB\x559A\x582A\x59E6\x5B8C\x5B98" +++ {-0xB0-} chars "\x5BDB\x5E72\x5E79\x60A3\x611F\x6163\x61BE\x63DB" +++ {-0xB8-} chars "\x6562\x67D1\x6853\x68FA\x6B3E\x6B53\x6C57\x6F22" +++ {-0xC0-} chars "\x6F97\x6F45\x74B0\x7518\x76E3\x770B\x7AFF\x7BA1" +++ {-0xC8-} chars "\x7C21\x7DE9\x7F36\x7FF0\x809D\x8266\x839E\x89B3" +++ {-0xD0-} chars "\x8ACC\x8CAB\x9084\x9451\x9593\x9591\x95A2\x9665" +++ {-0xD8-} chars "\x97D3\x9928\x8218\x4E38\x542B\x5CB8\x5DCC\x73A9" +++ {-0xE0-} chars "\x764C\x773C\x5CA9\x7FEB\x8D0B\x96C1\x9811\x9854" +++ {-0xE8-} chars "\x9858\x4F01\x4F0E\x5371\x559C\x5668\x57FA\x5947" +++ {-0xF0-} chars "\x5B09\x5BC4\x5C90\x5E0C\x5E7E\x5FCC\x63EE\x673A" +++ {-0xF8-} chars "\x65D7\x65E2\x671F\x68CB\x68C4"++-- | The multibyte characters with a lead byte of @0x8B@.+second8B :: SecondByteTable+second8B = V.fromList $+ {-0x40-} chars "\x6A5F\x5E30\x6BC5\x6C17\x6C7D\x757F\x7948\x5B63" +++ {-0x48-} chars "\x7A00\x7D00\x5FBD\x898F\x8A18\x8CB4\x8D77\x8ECC" +++ {-0x50-} chars "\x8F1D\x98E2\x9A0E\x9B3C\x4E80\x507D\x5100\x5993" +++ {-0x58-} chars "\x5B9C\x622F\x6280\x64EC\x6B3A\x72A0\x7591\x7947" +++ {-0x60-} chars "\x7FA9\x87FB\x8ABC\x8B70\x63AC\x83CA\x97A0\x5409" +++ {-0x68-} chars "\x5403\x55AB\x6854\x6A58\x8A70\x7827\x6775\x9ECD" +++ {-0x70-} chars "\x5374\x5BA2\x811A\x8650\x9006\x4E18\x4E45\x4EC7" +++ {-0x78-} chars "\x4F11\x53CA\x5438\x5BAE\x5F13\x6025\x6551" ++ Nothing :+ {-0x80-} chars "\x673D\x6C42\x6C72\x6CE3\x7078\x7403\x7A76\x7AAE" +++ {-0x88-} chars "\x7B08\x7D1A\x7CFE\x7D66\x65E7\x725B\x53BB\x5C45" +++ {-0x90-} chars "\x5DE8\x62D2\x62E0\x6319\x6E20\x865A\x8A31\x8DDD" +++ {-0x98-} chars "\x92F8\x6F01\x79A6\x9B5A\x4EA8\x4EAB\x4EAC\x4F9B" +++ {-0xA0-} chars "\x4FA0\x50D1\x5147\x7AF6\x5171\x51F6\x5354\x5321" +++ {-0xA8-} chars "\x537F\x53EB\x55AC\x5883\x5CE1\x5F37\x5F4A\x602F" +++ {-0xB0-} chars "\x6050\x606D\x631F\x6559\x6A4B\x6CC1\x72C2\x72ED" +++ {-0xB8-} chars "\x77EF\x80F8\x8105\x8208\x854E\x90F7\x93E1\x97FF" +++ {-0xC0-} chars "\x9957\x9A5A\x4EF0\x51DD\x5C2D\x6681\x696D\x5C40" +++ {-0xC8-} chars "\x66F2\x6975\x7389\x6850\x7C81\x50C5\x52E4\x5747" +++ {-0xD0-} chars "\x5DFE\x9326\x65A4\x6B23\x6B3D\x7434\x7981\x79BD" +++ {-0xD8-} chars "\x7B4B\x7DCA\x82B9\x83CC\x887F\x895F\x8B39\x8FD1" +++ {-0xE0-} chars "\x91D1\x541F\x9280\x4E5D\x5036\x53E5\x533A\x72D7" +++ {-0xE8-} chars "\x7396\x77E9\x82E6\x8EAF\x99C6\x99C8\x99D2\x5177" +++ {-0xF0-} chars "\x611A\x865E\x55B0\x7A7A\x5076\x5BD3\x9047\x9685" +++ {-0xF8-} chars "\x4E32\x6ADB\x91E7\x5C51\x5C48"++-- | The multibyte characters with a lead byte of @0x8C@.+second8C :: SecondByteTable+second8C = V.fromList $+ {-0x40-} chars "\x6398\x7A9F\x6C93\x9774\x8F61\x7AAA\x718A\x9688" +++ {-0x48-} chars "\x7C82\x6817\x7E70\x6851\x936C\x52F2\x541B\x85AB" +++ {-0x50-} chars "\x8A13\x7FA4\x8ECD\x90E1\x5366\x8888\x7941\x4FC2" +++ {-0x58-} chars "\x50BE\x5211\x5144\x5553\x572D\x73EA\x578B\x5951" +++ {-0x60-} chars "\x5F62\x5F84\x6075\x6176\x6167\x61A9\x63B2\x643A" +++ {-0x68-} chars "\x656C\x666F\x6842\x6E13\x7566\x7A3D\x7CFB\x7D4C" +++ {-0x70-} chars "\x7D99\x7E4B\x7F6B\x830E\x834A\x86CD\x8A08\x8A63" +++ {-0x78-} chars "\x8B66\x8EFD\x981A\x9D8F\x82B8\x8FCE\x9BE8" ++ Nothing :+ {-0x80-} chars "\x5287\x621F\x6483\x6FC0\x9699\x6841\x5091\x6B20" +++ {-0x88-} chars "\x6C7A\x6F54\x7A74\x7D50\x8840\x8A23\x6708\x4EF6" +++ {-0x90-} chars "\x5039\x5026\x5065\x517C\x5238\x5263\x55A7\x570F" +++ {-0x98-} chars "\x5805\x5ACC\x5EFA\x61B2\x61F8\x62F3\x6372\x691C" +++ {-0xA0-} chars "\x6A29\x727D\x72AC\x732E\x7814\x786F\x7D79\x770C" +++ {-0xA8-} chars "\x80A9\x898B\x8B19\x8CE2\x8ED2\x9063\x9375\x967A" +++ {-0xB0-} chars "\x9855\x9A13\x9E78\x5143\x539F\x53B3\x5E7B\x5F26" +++ {-0xB8-} chars "\x6E1B\x6E90\x7384\x73FE\x7D43\x8237\x8A00\x8AFA" +++ {-0xC0-} chars "\x9650\x4E4E\x500B\x53E4\x547C\x56FA\x59D1\x5B64" +++ {-0xC8-} chars "\x5DF1\x5EAB\x5F27\x6238\x6545\x67AF\x6E56\x72D0" +++ {-0xD0-} chars "\x7CCA\x88B4\x80A1\x80E1\x83F0\x864E\x8A87\x8DE8" +++ {-0xD8-} chars "\x9237\x96C7\x9867\x9F13\x4E94\x4E92\x4F0D\x5348" +++ {-0xE0-} chars "\x5449\x543E\x5A2F\x5F8C\x5FA1\x609F\x68A7\x6A8E" +++ {-0xE8-} chars "\x745A\x7881\x8A9E\x8AA4\x8B77\x9190\x4E5E\x9BC9" +++ {-0xF0-} chars "\x4EA4\x4F7C\x4FAF\x5019\x5016\x5149\x516C\x529F" +++ {-0xF8-} chars "\x52B9\x52FE\x539A\x53E3\x5411"++-- | The multibyte characters with a lead byte of @0x8D@.+second8D :: SecondByteTable+second8D = V.fromList $+ {-0x40-} chars "\x540E\x5589\x5751\x57A2\x597D\x5B54\x5B5D\x5B8F" +++ {-0x48-} chars "\x5DE5\x5DE7\x5DF7\x5E78\x5E83\x5E9A\x5EB7\x5F18" +++ {-0x50-} chars "\x6052\x614C\x6297\x62D8\x63A7\x653B\x6602\x6643" +++ {-0x58-} chars "\x66F4\x676D\x6821\x6897\x69CB\x6C5F\x6D2A\x6D69" +++ {-0x60-} chars "\x6E2F\x6E9D\x7532\x7687\x786C\x7A3F\x7CE0\x7D05" +++ {-0x68-} chars "\x7D18\x7D5E\x7DB1\x8015\x8003\x80AF\x80B1\x8154" +++ {-0x70-} chars "\x818F\x822A\x8352\x884C\x8861\x8B1B\x8CA2\x8CFC" +++ {-0x78-} chars "\x90CA\x9175\x9271\x783F\x92FC\x95A4\x964D" ++ Nothing :+ {-0x80-} chars "\x9805\x9999\x9AD8\x9D3B\x525B\x52AB\x53F7\x5408" +++ {-0x88-} chars "\x58D5\x62F7\x6FE0\x8C6A\x8F5F\x9EB9\x514B\x523B" +++ {-0x90-} chars "\x544A\x56FD\x7A40\x9177\x9D60\x9ED2\x7344\x6F09" +++ {-0x98-} chars "\x8170\x7511\x5FFD\x60DA\x9AA8\x72DB\x8FBC\x6B64" +++ {-0xA0-} chars "\x9803\x4ECA\x56F0\x5764\x58BE\x5A5A\x6068\x61C7" +++ {-0xA8-} chars "\x660F\x6606\x6839\x68B1\x6DF7\x75D5\x7D3A\x826E" +++ {-0xB0-} chars "\x9B42\x4E9B\x4F50\x53C9\x5506\x5D6F\x5DE6\x5DEE" +++ {-0xB8-} chars "\x67FB\x6C99\x7473\x7802\x8A50\x9396\x88DF\x5750" +++ {-0xC0-} chars "\x5EA7\x632B\x50B5\x50AC\x518D\x6700\x54C9\x585E" +++ {-0xC8-} chars "\x59BB\x5BB0\x5F69\x624D\x63A1\x683D\x6B73\x6E08" +++ {-0xD0-} chars "\x707D\x91C7\x7280\x7815\x7826\x796D\x658E\x7D30" +++ {-0xD8-} chars "\x83DC\x88C1\x8F09\x969B\x5264\x5728\x6750\x7F6A" +++ {-0xE0-} chars "\x8CA1\x51B4\x5742\x962A\x583A\x698A\x80B4\x54B2" +++ {-0xE8-} chars "\x5D0E\x57FC\x7895\x9DFA\x4F5C\x524A\x548B\x643E" +++ {-0xF0-} chars "\x6628\x6714\x67F5\x7A84\x7B56\x7D22\x932F\x685C" +++ {-0xF8-} chars "\x9BAD\x7B39\x5319\x518A\x5237"++-- | The multibyte characters with a lead byte of @0x8E@.+second8E :: SecondByteTable+second8E = V.fromList $+ {-0x40-} chars "\x5BDF\x62F6\x64AE\x64E6\x672D\x6BBA\x85A9\x96D1" +++ {-0x48-} chars "\x7690\x9BD6\x634C\x9306\x9BAB\x76BF\x6652\x4E09" +++ {-0x50-} chars "\x5098\x53C2\x5C71\x60E8\x6492\x6563\x685F\x71E6" +++ {-0x58-} chars "\x73CA\x7523\x7B97\x7E82\x8695\x8B83\x8CDB\x9178" +++ {-0x60-} chars "\x9910\x65AC\x66AB\x6B8B\x4ED5\x4ED4\x4F3A\x4F7F" +++ {-0x68-} chars "\x523A\x53F8\x53F2\x55E3\x56DB\x58EB\x59CB\x59C9" +++ {-0x70-} chars "\x59FF\x5B50\x5C4D\x5E02\x5E2B\x5FD7\x601D\x6307" +++ {-0x78-} chars "\x652F\x5B5C\x65AF\x65BD\x65E8\x679D\x6B62" ++ Nothing :+ {-0x80-} chars "\x6B7B\x6C0F\x7345\x7949\x79C1\x7CF8\x7D19\x7D2B" +++ {-0x88-} chars "\x80A2\x8102\x81F3\x8996\x8A5E\x8A69\x8A66\x8A8C" +++ {-0x90-} chars "\x8AEE\x8CC7\x8CDC\x96CC\x98FC\x6B6F\x4E8B\x4F3C" +++ {-0x98-} chars "\x4F8D\x5150\x5B57\x5BFA\x6148\x6301\x6642\x6B21" +++ {-0xA0-} chars "\x6ECB\x6CBB\x723E\x74BD\x75D4\x78C1\x793A\x800C" +++ {-0xA8-} chars "\x8033\x81EA\x8494\x8F9E\x6C50\x9E7F\x5F0F\x8B58" +++ {-0xB0-} chars "\x9D2B\x7AFA\x8EF8\x5B8D\x96EB\x4E03\x53F1\x57F7" +++ {-0xB8-} chars "\x5931\x5AC9\x5BA4\x6089\x6E7F\x6F06\x75BE\x8CEA" +++ {-0xC0-} chars "\x5B9F\x8500\x7BE0\x5072\x67F4\x829D\x5C61\x854A" +++ {-0xC8-} chars "\x7E1E\x820E\x5199\x5C04\x6368\x8D66\x659C\x716E" +++ {-0xD0-} chars "\x793E\x7D17\x8005\x8B1D\x8ECA\x906E\x86C7\x90AA" +++ {-0xD8-} chars "\x501F\x52FA\x5C3A\x6753\x707C\x7235\x914C\x91C8" +++ {-0xE0-} chars "\x932B\x82E5\x5BC2\x5F31\x60F9\x4E3B\x53D6\x5B88" +++ {-0xE8-} chars "\x624B\x6731\x6B8A\x72E9\x73E0\x7A2E\x816B\x8DA3" +++ {-0xF0-} chars "\x9152\x9996\x5112\x53D7\x546A\x5BFF\x6388\x6A39" +++ {-0xF8-} chars "\x7DAC\x9700\x56DA\x53CE\x5468"++-- | The multibyte characters with a lead byte of @0x8F@.+second8F :: SecondByteTable+second8F = V.fromList $+ {-0x40-} chars "\x5B97\x5C31\x5DDE\x4FEE\x6101\x62FE\x6D32\x79C0" +++ {-0x48-} chars "\x79CB\x7D42\x7E4D\x7FD2\x81ED\x821F\x8490\x8846" +++ {-0x50-} chars "\x8972\x8B90\x8E74\x8F2F\x9031\x914B\x916C\x96C6" +++ {-0x58-} chars "\x919C\x4EC0\x4F4F\x5145\x5341\x5F93\x620E\x67D4" +++ {-0x60-} chars "\x6C41\x6E0B\x7363\x7E26\x91CD\x9283\x53D4\x5919" +++ {-0x68-} chars "\x5BBF\x6DD1\x795D\x7E2E\x7C9B\x587E\x719F\x51FA" +++ {-0x70-} chars "\x8853\x8FF0\x4FCA\x5CFB\x6625\x77AC\x7AE3\x821C" +++ {-0x78-} chars "\x99FF\x51C6\x5FAA\x65EC\x696F\x6B89\x6DF3" ++ Nothing :+ {-0x80-} chars "\x6E96\x6F64\x76FE\x7D14\x5DE1\x9075\x9187\x9806" +++ {-0x88-} chars "\x51E6\x521D\x6240\x6691\x66D9\x6E1A\x5EB6\x7DD2" +++ {-0x90-} chars "\x7F72\x66F8\x85AF\x85F7\x8AF8\x52A9\x53D9\x5973" +++ {-0x98-} chars "\x5E8F\x5F90\x6055\x92E4\x9664\x50B7\x511F\x52DD" +++ {-0xA0-} chars "\x5320\x5347\x53EC\x54E8\x5546\x5531\x5617\x5968" +++ {-0xA8-} chars "\x59BE\x5A3C\x5BB5\x5C06\x5C0F\x5C11\x5C1A\x5E84" +++ {-0xB0-} chars "\x5E8A\x5EE0\x5F70\x627F\x6284\x62DB\x638C\x6377" +++ {-0xB8-} chars "\x6607\x660C\x662D\x6676\x677E\x68A2\x6A1F\x6A35" +++ {-0xC0-} chars "\x6CBC\x6D88\x6E09\x6E58\x713C\x7126\x7167\x75C7" +++ {-0xC8-} chars "\x7701\x785D\x7901\x7965\x79F0\x7AE0\x7B11\x7CA7" +++ {-0xD0-} chars "\x7D39\x8096\x83D6\x848B\x8549\x885D\x88F3\x8A1F" +++ {-0xD8-} chars "\x8A3C\x8A54\x8A73\x8C61\x8CDE\x91A4\x9266\x937E" +++ {-0xE0-} chars "\x9418\x969C\x9798\x4E0A\x4E08\x4E1E\x4E57\x5197" +++ {-0xE8-} chars "\x5270\x57CE\x5834\x58CC\x5B22\x5E38\x60C5\x64FE" +++ {-0xF0-} chars "\x6761\x6756\x6D44\x72B6\x7573\x7A63\x84B8\x8B72" +++ {-0xF8-} chars "\x91B8\x9320\x5631\x57F4\x98FE"++-- | The multibyte characters with a lead byte of @0x90@.+second90 :: SecondByteTable+second90 = V.fromList $+ {-0x40-} chars "\x62ED\x690D\x6B96\x71ED\x7E54\x8077\x8272\x89E6" +++ {-0x48-} chars "\x98DF\x8755\x8FB1\x5C3B\x4F38\x4FE1\x4FB5\x5507" +++ {-0x50-} chars "\x5A20\x5BDD\x5BE9\x5FC3\x614E\x632F\x65B0\x664B" +++ {-0x58-} chars "\x68EE\x699B\x6D78\x6DF1\x7533\x75B9\x771F\x795E" +++ {-0x60-} chars "\x79E6\x7D33\x81E3\x82AF\x85AA\x89AA\x8A3A\x8EAB" +++ {-0x68-} chars "\x8F9B\x9032\x91DD\x9707\x4EBA\x4EC1\x5203\x5875" +++ {-0x70-} chars "\x58EC\x5C0B\x751A\x5C3D\x814E\x8A0A\x8FC5\x9663" +++ {-0x78-} chars "\x976D\x7B25\x8ACF\x9808\x9162\x56F3\x53A8" ++ Nothing :+ {-0x80-} chars "\x9017\x5439\x5782\x5E25\x63A8\x6C34\x708A\x7761" +++ {-0x88-} chars "\x7C8B\x7FE0\x8870\x9042\x9154\x9310\x9318\x968F" +++ {-0x90-} chars "\x745E\x9AC4\x5D07\x5D69\x6570\x67A2\x8DA8\x96DB" +++ {-0x98-} chars "\x636E\x6749\x6919\x83C5\x9817\x96C0\x88FE\x6F84" +++ {-0xA0-} chars "\x647A\x5BF8\x4E16\x702C\x755D\x662F\x51C4\x5236" +++ {-0xA8-} chars "\x52E2\x59D3\x5F81\x6027\x6210\x653F\x6574\x661F" +++ {-0xB0-} chars "\x6674\x68F2\x6816\x6B63\x6E05\x7272\x751F\x76DB" +++ {-0xB8-} chars "\x7CBE\x8056\x58F0\x88FD\x897F\x8AA0\x8A93\x8ACB" +++ {-0xC0-} chars "\x901D\x9192\x9752\x9759\x6589\x7A0E\x8106\x96BB" +++ {-0xC8-} chars "\x5E2D\x60DC\x621A\x65A5\x6614\x6790\x77F3\x7A4D" +++ {-0xD0-} chars "\x7C4D\x7E3E\x810A\x8CAC\x8D64\x8DE1\x8E5F\x78A9" +++ {-0xD8-} chars "\x5207\x62D9\x63A5\x6442\x6298\x8A2D\x7A83\x7BC0" +++ {-0xE0-} chars "\x8AAC\x96EA\x7D76\x820C\x8749\x4ED9\x5148\x5343" +++ {-0xE8-} chars "\x5360\x5BA3\x5C02\x5C16\x5DDD\x6226\x6247\x64B0" +++ {-0xF0-} chars "\x6813\x6834\x6CC9\x6D45\x6D17\x67D3\x6F5C\x714E" +++ {-0xF8-} chars "\x717D\x65CB\x7A7F\x7BAD\x7DDA"++-- | The multibyte characters with a lead byte of @0x91@.+second91 :: SecondByteTable+second91 = V.fromList $+ {-0x40-} chars "\x7E4A\x7FA8\x817A\x821B\x8239\x85A6\x8A6E\x8CCE" +++ {-0x48-} chars "\x8DF5\x9078\x9077\x92AD\x9291\x9583\x9BAE\x524D" +++ {-0x50-} chars "\x5584\x6F38\x7136\x5168\x7985\x7E55\x81B3\x7CCE" +++ {-0x58-} chars "\x564C\x5851\x5CA8\x63AA\x66FE\x66FD\x695A\x72D9" +++ {-0x60-} chars "\x758F\x758E\x790E\x7956\x79DF\x7C97\x7D20\x7D44" +++ {-0x68-} chars "\x8607\x8A34\x963B\x9061\x9F20\x50E7\x5275\x53CC" +++ {-0x70-} chars "\x53E2\x5009\x55AA\x58EE\x594F\x723D\x5B8B\x5C64" +++ {-0x78-} chars "\x531D\x60E3\x60F3\x635C\x6383\x633F\x63BB" ++ Nothing :+ {-0x80-} chars "\x64CD\x65E9\x66F9\x5DE3\x69CD\x69FD\x6F15\x71E5" +++ {-0x88-} chars "\x4E89\x75E9\x76F8\x7A93\x7CDF\x7DCF\x7D9C\x8061" +++ {-0x90-} chars "\x8349\x8358\x846C\x84BC\x85FB\x88C5\x8D70\x9001" +++ {-0x98-} chars "\x906D\x9397\x971C\x9A12\x50CF\x5897\x618E\x81D3" +++ {-0xA0-} chars "\x8535\x8D08\x9020\x4FC3\x5074\x5247\x5373\x606F" +++ {-0xA8-} chars "\x6349\x675F\x6E2C\x8DB3\x901F\x4FD7\x5C5E\x8CCA" +++ {-0xB0-} chars "\x65CF\x7D9A\x5352\x8896\x5176\x63C3\x5B58\x5B6B" +++ {-0xB8-} chars "\x5C0A\x640D\x6751\x905C\x4ED6\x591A\x592A\x6C70" +++ {-0xC0-} chars "\x8A51\x553E\x5815\x59A5\x60F0\x6253\x67C1\x8235" +++ {-0xC8-} chars "\x6955\x9640\x99C4\x9A28\x4F53\x5806\x5BFE\x8010" +++ {-0xD0-} chars "\x5CB1\x5E2F\x5F85\x6020\x614B\x6234\x66FF\x6CF0" +++ {-0xD8-} chars "\x6EDE\x80CE\x817F\x82D4\x888B\x8CB8\x9000\x902E" +++ {-0xE0-} chars "\x968A\x9EDB\x9BDB\x4EE3\x53F0\x5927\x7B2C\x918D" +++ {-0xE8-} chars "\x984C\x9DF9\x6EDD\x7027\x5353\x5544\x5B85\x6258" +++ {-0xF0-} chars "\x629E\x62D3\x6CA2\x6FEF\x7422\x8A17\x9438\x6FC1" +++ {-0xF8-} chars "\x8AFE\x8338\x51E7\x86F8\x53EA"++-- | The multibyte characters with a lead byte of @0x92@.+second92 :: SecondByteTable+second92 = V.fromList $+ {-0x40-} chars "\x53E9\x4F46\x9054\x8FB0\x596A\x8131\x5DFD\x7AEA" +++ {-0x48-} chars "\x8FBF\x68DA\x8C37\x72F8\x9C48\x6A3D\x8AB0\x4E39" +++ {-0x50-} chars "\x5358\x5606\x5766\x62C5\x63A2\x65E6\x6B4E\x6DE1" +++ {-0x58-} chars "\x6E5B\x70AD\x77ED\x7AEF\x7BAA\x7DBB\x803D\x80C6" +++ {-0x60-} chars "\x86CB\x8A95\x935B\x56E3\x58C7\x5F3E\x65AD\x6696" +++ {-0x68-} chars "\x6A80\x6BB5\x7537\x8AC7\x5024\x77E5\x5730\x5F1B" +++ {-0x70-} chars "\x6065\x667A\x6C60\x75F4\x7A1A\x7F6E\x81F4\x8718" +++ {-0x78-} chars "\x9045\x99B3\x7BC9\x755C\x7AF9\x7B51\x84C4" ++ Nothing :+ {-0x80-} chars "\x9010\x79E9\x7A92\x8336\x5AE1\x7740\x4E2D\x4EF2" +++ {-0x88-} chars "\x5B99\x5FE0\x62BD\x663C\x67F1\x6CE8\x866B\x8877" +++ {-0x90-} chars "\x8A3B\x914E\x92F3\x99D0\x6A17\x7026\x732A\x82E7" +++ {-0x98-} chars "\x8457\x8CAF\x4E01\x5146\x51CB\x558B\x5BF5\x5E16" +++ {-0xA0-} chars "\x5E33\x5E81\x5F14\x5F35\x5F6B\x5FB4\x61F2\x6311" +++ {-0xA8-} chars "\x66A2\x671D\x6F6E\x7252\x753A\x773A\x8074\x8139" +++ {-0xB0-} chars "\x8178\x8776\x8ABF\x8ADC\x8D85\x8DF3\x929A\x9577" +++ {-0xB8-} chars "\x9802\x9CE5\x52C5\x6357\x76F4\x6715\x6C88\x73CD" +++ {-0xC0-} chars "\x8CC3\x93AE\x9673\x6D25\x589C\x690E\x69CC\x8FFD" +++ {-0xC8-} chars "\x939A\x75DB\x901A\x585A\x6802\x63B4\x69FB\x4F43" +++ {-0xD0-} chars "\x6F2C\x67D8\x8FBB\x8526\x7DB4\x9354\x693F\x6F70" +++ {-0xD8-} chars "\x576A\x58F7\x5B2C\x7D2C\x722A\x540A\x91E3\x9DB4" +++ {-0xE0-} chars "\x4EAD\x4F4E\x505C\x5075\x5243\x8C9E\x5448\x5824" +++ {-0xE8-} chars "\x5B9A\x5E1D\x5E95\x5EAD\x5EF7\x5F1F\x608C\x62B5" +++ {-0xF0-} chars "\x633A\x63D0\x68AF\x6C40\x7887\x798E\x7A0B\x7DE0" +++ {-0xF8-} chars "\x8247\x8A02\x8AE6\x8E44\x9013"++-- | The multibyte characters with a lead byte of @0x93@.+second93 :: SecondByteTable+second93 = V.fromList $+ {-0x40-} chars "\x90B8\x912D\x91D8\x9F0E\x6CE5\x6458\x64E2\x6575" +++ {-0x48-} chars "\x6EF4\x7684\x7B1B\x9069\x93D1\x6EBA\x54F2\x5FB9" +++ {-0x50-} chars "\x64A4\x8F4D\x8FED\x9244\x5178\x586B\x5929\x5C55" +++ {-0x58-} chars "\x5E97\x6DFB\x7E8F\x751C\x8CBC\x8EE2\x985B\x70B9" +++ {-0x60-} chars "\x4F1D\x6BBF\x6FB1\x7530\x96FB\x514E\x5410\x5835" +++ {-0x68-} chars "\x5857\x59AC\x5C60\x5F92\x6597\x675C\x6E21\x767B" +++ {-0x70-} chars "\x83DF\x8CED\x9014\x90FD\x934D\x7825\x783A\x52AA" +++ {-0x78-} chars "\x5EA6\x571F\x5974\x6012\x5012\x515A\x51AC" ++ Nothing :+ {-0x80-} chars "\x51CD\x5200\x5510\x5854\x5858\x5957\x5B95\x5CF6" +++ {-0x88-} chars "\x5D8B\x60BC\x6295\x642D\x6771\x6843\x68BC\x68DF" +++ {-0x90-} chars "\x76D7\x6DD8\x6E6F\x6D9B\x706F\x71C8\x5F53\x75D8" +++ {-0x98-} chars "\x7977\x7B49\x7B54\x7B52\x7CD6\x7D71\x5230\x8463" +++ {-0xA0-} chars "\x8569\x85E4\x8A0E\x8B04\x8C46\x8E0F\x9003\x900F" +++ {-0xA8-} chars "\x9419\x9676\x982D\x9A30\x95D8\x50CD\x52D5\x540C" +++ {-0xB0-} chars "\x5802\x5C0E\x61A7\x649E\x6D1E\x77B3\x7AE5\x80F4" +++ {-0xB8-} chars "\x8404\x9053\x9285\x5CE0\x9D07\x533F\x5F97\x5FB3" +++ {-0xC0-} chars "\x6D9C\x7279\x7763\x79BF\x7BE4\x6BD2\x72EC\x8AAD" +++ {-0xC8-} chars "\x6803\x6A61\x51F8\x7A81\x6934\x5C4A\x9CF6\x82EB" +++ {-0xD0-} chars "\x5BC5\x9149\x701E\x5678\x5C6F\x60C7\x6566\x6C8C" +++ {-0xD8-} chars "\x8C5A\x9041\x9813\x5451\x66C7\x920D\x5948\x90A3" +++ {-0xE0-} chars "\x5185\x4E4D\x51EA\x8599\x8B0E\x7058\x637A\x934B" +++ {-0xE8-} chars "\x6962\x99B4\x7E04\x7577\x5357\x6960\x8EDF\x96E3" +++ {-0xF0-} chars "\x6C5D\x4E8C\x5C3C\x5F10\x8FE9\x5302\x8CD1\x8089" +++ {-0xF8-} chars "\x8679\x5EFF\x65E5\x4E73\x5165"++-- | The multibyte characters with a lead byte of @0x94@.+second94 :: SecondByteTable+second94 = V.fromList $+ {-0x40-} chars "\x5982\x5C3F\x97EE\x4EFB\x598A\x5FCD\x8A8D\x6FE1" +++ {-0x48-} chars "\x79B0\x7962\x5BE7\x8471\x732B\x71B1\x5E74\x5FF5" +++ {-0x50-} chars "\x637B\x649A\x71C3\x7C98\x4E43\x5EFC\x4E4B\x57DC" +++ {-0x58-} chars "\x56A2\x60A9\x6FC3\x7D0D\x80FD\x8133\x81BF\x8FB2" +++ {-0x60-} chars "\x8997\x86A4\x5DF4\x628A\x64AD\x8987\x6777\x6CE2" +++ {-0x68-} chars "\x6D3E\x7436\x7834\x5A46\x7F75\x82AD\x99AC\x4FF3" +++ {-0x70-} chars "\x5EC3\x62DD\x6392\x6557\x676F\x76C3\x724C\x80CC" +++ {-0x78-} chars "\x80BA\x8F29\x914D\x500D\x57F9\x5A92\x6885" ++ Nothing :+ {-0x80-} chars "\x6973\x7164\x72FD\x8CB7\x58F2\x8CE0\x966A\x9019" +++ {-0x88-} chars "\x877F\x79E4\x77E7\x8429\x4F2F\x5265\x535A\x62CD" +++ {-0x90-} chars "\x67CF\x6CCA\x767D\x7B94\x7C95\x8236\x8584\x8FEB" +++ {-0x98-} chars "\x66DD\x6F20\x7206\x7E1B\x83AB\x99C1\x9EA6\x51FD" +++ {-0xA0-} chars "\x7BB1\x7872\x7BB8\x8087\x7B48\x6AE8\x5E61\x808C" +++ {-0xA8-} chars "\x7551\x7560\x516B\x9262\x6E8C\x767A\x9197\x9AEA" +++ {-0xB0-} chars "\x4F10\x7F70\x629C\x7B4F\x95A5\x9CE9\x567A\x5859" +++ {-0xB8-} chars "\x86E4\x96BC\x4F34\x5224\x534A\x53CD\x53DB\x5E06" +++ {-0xC0-} chars "\x642C\x6591\x677F\x6C3E\x6C4E\x7248\x72AF\x73ED" +++ {-0xC8-} chars "\x7554\x7E41\x822C\x85E9\x8CA9\x7BC4\x91C6\x7169" +++ {-0xD0-} chars "\x9812\x98EF\x633D\x6669\x756A\x76E4\x78D0\x8543" +++ {-0xD8-} chars "\x86EE\x532A\x5351\x5426\x5983\x5E87\x5F7C\x60B2" +++ {-0xE0-} chars "\x6249\x6279\x62AB\x6590\x6BD4\x6CCC\x75B2\x76AE" +++ {-0xE8-} chars "\x7891\x79D8\x7DCB\x7F77\x80A5\x88AB\x8AB9\x8CBB" +++ {-0xF0-} chars "\x907F\x975E\x98DB\x6A0B\x7C38\x5099\x5C3E\x5FAE" +++ {-0xF8-} chars "\x6787\x6BD8\x7435\x7709\x7F8E"++-- | The multibyte characters with a lead byte of @0x95@.+second95 :: SecondByteTable+second95 = V.fromList $+ {-0x40-} chars "\x9F3B\x67CA\x7A17\x5339\x758B\x9AED\x5F66\x819D" +++ {-0x48-} chars "\x83F1\x8098\x5F3C\x5FC5\x7562\x7B46\x903C\x6867" +++ {-0x50-} chars "\x59EB\x5A9B\x7D10\x767E\x8B2C\x4FF5\x5F6A\x6A19" +++ {-0x58-} chars "\x6C37\x6F02\x74E2\x7968\x8868\x8A55\x8C79\x5EDF" +++ {-0x60-} chars "\x63CF\x75C5\x79D2\x82D7\x9328\x92F2\x849C\x86ED" +++ {-0x68-} chars "\x9C2D\x54C1\x5F6C\x658C\x6D5C\x7015\x8CA7\x8CD3" +++ {-0x70-} chars "\x983B\x654F\x74F6\x4E0D\x4ED8\x57E0\x592B\x5A66" +++ {-0x78-} chars "\x5BCC\x51A8\x5E03\x5E9C\x6016\x6276\x6577" ++ Nothing :+ {-0x80-} chars "\x65A7\x666E\x6D6E\x7236\x7B26\x8150\x819A\x8299" +++ {-0x88-} chars "\x8B5C\x8CA0\x8CE6\x8D74\x961C\x9644\x4FAE\x64AB" +++ {-0x90-} chars "\x6B66\x821E\x8461\x856A\x90E8\x5C01\x6953\x98A8" +++ {-0x98-} chars "\x847A\x8557\x4F0F\x526F\x5FA9\x5E45\x670D\x798F" +++ {-0xA0-} chars "\x8179\x8907\x8986\x6DF5\x5F17\x6255\x6CB8\x4ECF" +++ {-0xA8-} chars "\x7269\x9B92\x5206\x543B\x5674\x58B3\x61A4\x626E" +++ {-0xB0-} chars "\x711A\x596E\x7C89\x7CDE\x7D1B\x96F0\x6587\x805E" +++ {-0xB8-} chars "\x4E19\x4F75\x5175\x5840\x5E63\x5E73\x5F0A\x67C4" +++ {-0xC0-} chars "\x4E26\x853D\x9589\x965B\x7C73\x9801\x50FB\x58C1" +++ {-0xC8-} chars "\x7656\x78A7\x5225\x77A5\x8511\x7B86\x504F\x5909" +++ {-0xD0-} chars "\x7247\x7BC7\x7DE8\x8FBA\x8FD4\x904D\x4FBF\x52C9" +++ {-0xD8-} chars "\x5A29\x5F01\x97AD\x4FDD\x8217\x92EA\x5703\x6355" +++ {-0xE0-} chars "\x6B69\x752B\x88DC\x8F14\x7A42\x52DF\x5893\x6155" +++ {-0xE8-} chars "\x620A\x66AE\x6BCD\x7C3F\x83E9\x5023\x4FF8\x5305" +++ {-0xF0-} chars "\x5446\x5831\x5949\x5B9D\x5CF0\x5CEF\x5D29\x5E96" +++ {-0xF8-} chars "\x62B1\x6367\x653E\x65B9\x670B"++-- | The multibyte characters with a lead byte of @0x96@.+second96 :: SecondByteTable+second96 = V.fromList $+ {-0x40-} chars "\x6CD5\x6CE1\x70F9\x7832\x7E2B\x80DE\x82B3\x840C" +++ {-0x48-} chars "\x84EC\x8702\x8912\x8A2A\x8C4A\x90A6\x92D2\x98FD" +++ {-0x50-} chars "\x9CF3\x9D6C\x4E4F\x4EA1\x508D\x5256\x574A\x59A8" +++ {-0x58-} chars "\x5E3D\x5FD8\x5FD9\x623F\x66B4\x671B\x67D0\x68D2" +++ {-0x60-} chars "\x5192\x7D21\x80AA\x81A8\x8B00\x8C8C\x8CBF\x927E" +++ {-0x68-} chars "\x9632\x5420\x982C\x5317\x50D5\x535C\x58A8\x64B2" +++ {-0x70-} chars "\x6734\x7267\x7766\x7A46\x91E6\x52C3\x6CA1\x6B86" +++ {-0x78-} chars "\x5800\x5E4C\x5954\x672C\x7FFB\x51E1\x76C6" ++ Nothing :+ {-0x80-} chars "\x6469\x78E8\x9B54\x9EBB\x57CB\x59B9\x6627\x679A" +++ {-0x88-} chars "\x6BCE\x54E9\x69D9\x5E55\x819C\x6795\x9BAA\x67FE" +++ {-0x90-} chars "\x9C52\x685D\x4EA6\x4FE3\x53C8\x62B9\x672B\x6CAB" +++ {-0x98-} chars "\x8FC4\x4FAD\x7E6D\x9EBF\x4E07\x6162\x6E80\x6F2B" +++ {-0xA0-} chars "\x8513\x5473\x672A\x9B45\x5DF3\x7B95\x5CAC\x5BC6" +++ {-0xA8-} chars "\x871C\x6E4A\x84D1\x7A14\x8108\x5999\x7C8D\x6C11" +++ {-0xB0-} chars "\x7720\x52D9\x5922\x7121\x725F\x77DB\x9727\x9D61" +++ {-0xB8-} chars "\x690B\x5A7F\x5A18\x51A5\x540D\x547D\x660E\x76DF" +++ {-0xC0-} chars "\x8FF7\x9298\x9CF4\x59EA\x725D\x6EC5\x514D\x68C9" +++ {-0xC8-} chars "\x7DBF\x7DEC\x9762\x9EBA\x6478\x6A21\x8302\x5984" +++ {-0xD0-} chars "\x5B5F\x6BDB\x731B\x76F2\x7DB2\x8017\x8499\x5132" +++ {-0xD8-} chars "\x6728\x9ED9\x76EE\x6762\x52FF\x9905\x5C24\x623B" +++ {-0xE0-} chars "\x7C7E\x8CB0\x554F\x60B6\x7D0B\x9580\x5301\x4E5F" +++ {-0xE8-} chars "\x51B6\x591C\x723A\x8036\x91CE\x5F25\x77E2\x5384" +++ {-0xF0-} chars "\x5F79\x7D04\x85AC\x8A33\x8E8D\x9756\x67F3\x85AE" +++ {-0xF8-} chars "\x9453\x6109\x6108\x6CB9\x7652"++-- | The multibyte characters with a lead byte of @0x97@.+second97 :: SecondByteTable+second97 = V.fromList $+ {-0x40-} chars "\x8AED\x8F38\x552F\x4F51\x512A\x52C7\x53CB\x5BA5" +++ {-0x48-} chars "\x5E7D\x60A0\x6182\x63D6\x6709\x67DA\x6E67\x6D8C" +++ {-0x50-} chars "\x7336\x7337\x7531\x7950\x88D5\x8A98\x904A\x9091" +++ {-0x58-} chars "\x90F5\x96C4\x878D\x5915\x4E88\x4F59\x4E0E\x8A89" +++ {-0x60-} chars "\x8F3F\x9810\x50AD\x5E7C\x5996\x5BB9\x5EB8\x63DA" +++ {-0x68-} chars "\x63FA\x64C1\x66DC\x694A\x69D8\x6D0B\x6EB6\x7194" +++ {-0x70-} chars "\x7528\x7AAF\x7F8A\x8000\x8449\x84C9\x8981\x8B21" +++ {-0x78-} chars "\x8E0A\x9065\x967D\x990A\x617E\x6291\x6B32" ++ Nothing :+ {-0x80-} chars "\x6C83\x6D74\x7FCC\x7FFC\x6DC0\x7F85\x87BA\x88F8" +++ {-0x88-} chars "\x6765\x83B1\x983C\x96F7\x6D1B\x7D61\x843D\x916A" +++ {-0x90-} chars "\x4E71\x5375\x5D50\x6B04\x6FEB\x85CD\x862D\x89A7" +++ {-0x98-} chars "\x5229\x540F\x5C65\x674E\x68A8\x7406\x7483\x75E2" +++ {-0xA0-} chars "\x88CF\x88E1\x91CC\x96E2\x9678\x5F8B\x7387\x7ACB" +++ {-0xA8-} chars "\x844E\x63A0\x7565\x5289\x6D41\x6E9C\x7409\x7559" +++ {-0xB0-} chars "\x786B\x7C92\x9686\x7ADC\x9F8D\x4FB6\x616E\x65C5" +++ {-0xB8-} chars "\x865C\x4E86\x4EAE\x50DA\x4E21\x51CC\x5BEE\x6599" +++ {-0xC0-} chars "\x6881\x6DBC\x731F\x7642\x77AD\x7A1C\x7CE7\x826F" +++ {-0xC8-} chars "\x8AD2\x907C\x91CF\x9675\x9818\x529B\x7DD1\x502B" +++ {-0xD0-} chars "\x5398\x6797\x6DCB\x71D0\x7433\x81E8\x8F2A\x96A3" +++ {-0xD8-} chars "\x9C57\x9E9F\x7460\x5841\x6D99\x7D2F\x985E\x4EE4" +++ {-0xE0-} chars "\x4F36\x4F8B\x51B7\x52B1\x5DBA\x601C\x73B2\x793C" +++ {-0xE8-} chars "\x82D3\x9234\x96B7\x96F6\x970A\x9E97\x9F62\x66A6" +++ {-0xF0-} chars "\x6B74\x5217\x52A3\x70C8\x88C2\x5EC9\x604B\x6190" +++ {-0xF8-} chars "\x6F23\x7149\x7C3E\x7DF4\x806F"++-- | The multibyte characters with a lead byte of @0x98@.+second98 :: SecondByteTable+second98 = V.fromList $+ {-0x40-} chars "\x84EE\x9023\x932C\x5442\x9B6F\x6AD3\x7089\x8CC2" +++ {-0x48-} chars "\x8DEF\x9732\x52B4\x5A41\x5ECA\x5F04\x6717\x697C" +++ {-0x50-} chars "\x6994\x6D6A\x6F0F\x7262\x72FC\x7BED\x8001\x807E" +++ {-0x58-} chars "\x874B\x90CE\x516D\x9E93\x7984\x808B\x9332\x8AD6" +++ {-0x60-} chars "\x502D\x548C\x8A71\x6B6A\x8CC4\x8107\x60D1\x67A0" +++ {-0x68-} chars "\x9DF2\x4E99\x4E98\x9C10\x8A6B\x85C1\x8568\x6900" +++ {-0x70-} chars "\x6E7E\x7897\x8155" +++ {-0x73..0x9F-} nothings 0x2C ++ Just '\x5F0C' :+ {-0xA0-} chars "\x4E10\x4E15\x4E2A\x4E31\x4E36\x4E3C\x4E3F\x4E42" +++ {-0xA8-} chars "\x4E56\x4E58\x4E82\x4E85\x8C6B\x4E8A\x8212\x5F0D" +++ {-0xB0-} chars "\x4E8E\x4E9E\x4E9F\x4EA0\x4EA2\x4EB0\x4EB3\x4EB6" +++ {-0xB8-} chars "\x4ECE\x4ECD\x4EC4\x4EC6\x4EC2\x4ED7\x4EDE\x4EED" +++ {-0xC0-} chars "\x4EDF\x4EF7\x4F09\x4F5A\x4F30\x4F5B\x4F5D\x4F57" +++ {-0xC8-} chars "\x4F47\x4F76\x4F88\x4F8F\x4F98\x4F7B\x4F69\x4F70" +++ {-0xD0-} chars "\x4F91\x4F6F\x4F86\x4F96\x5118\x4FD4\x4FDF\x4FCE" +++ {-0xD8-} chars "\x4FD8\x4FDB\x4FD1\x4FDA\x4FD0\x4FE4\x4FE5\x501A" +++ {-0xE0-} chars "\x5028\x5014\x502A\x5025\x5005\x4F1C\x4FF6\x5021" +++ {-0xE8-} chars "\x5029\x502C\x4FFE\x4FEF\x5011\x5006\x5043\x5047" +++ {-0xF0-} chars "\x6703\x5055\x5050\x5048\x505A\x5056\x506C\x5078" +++ {-0xF8-} chars "\x5080\x509A\x5085\x50B4\x50B2"++-- | The multibyte characters with a lead byte of @0x99@.+second99 :: SecondByteTable+second99 = V.fromList $+ {-0x40-} chars "\x50C9\x50CA\x50B3\x50C2\x50D6\x50DE\x50E5\x50ED" +++ {-0x48-} chars "\x50E3\x50EE\x50F9\x50F5\x5109\x5101\x5102\x5116" +++ {-0x50-} chars "\x5115\x5114\x511A\x5121\x513A\x5137\x513C\x513B" +++ {-0x58-} chars "\x513F\x5140\x5152\x514C\x5154\x5162\x7AF8\x5169" +++ {-0x60-} chars "\x516A\x516E\x5180\x5182\x56D8\x518C\x5189\x518F" +++ {-0x68-} chars "\x5191\x5193\x5195\x5196\x51A4\x51A6\x51A2\x51A9" +++ {-0x70-} chars "\x51AA\x51AB\x51B3\x51B1\x51B2\x51B0\x51B5\x51BD" +++ {-0x78-} chars "\x51C5\x51C9\x51DB\x51E0\x8655\x51E9\x51ED" ++ Nothing :+ {-0x80-} chars "\x51F0\x51F5\x51FE\x5204\x520B\x5214\x520E\x5227" +++ {-0x88-} chars "\x522A\x522E\x5233\x5239\x524F\x5244\x524B\x524C" +++ {-0x90-} chars "\x525E\x5254\x526A\x5274\x5269\x5273\x527F\x527D" +++ {-0x98-} chars "\x528D\x5294\x5292\x5271\x5288\x5291\x8FA8\x8FA7" +++ {-0xA0-} chars "\x52AC\x52AD\x52BC\x52B5\x52C1\x52CD\x52D7\x52DE" +++ {-0xA8-} chars "\x52E3\x52E6\x98ED\x52E0\x52F3\x52F5\x52F8\x52F9" +++ {-0xB0-} chars "\x5306\x5308\x7538\x530D\x5310\x530F\x5315\x531A" +++ {-0xB8-} chars "\x5323\x532F\x5331\x5333\x5338\x5340\x5346\x5345" +++ {-0xC0-} chars "\x4E17\x5349\x534D\x51D6\x535E\x5369\x536E\x5918" +++ {-0xC8-} chars "\x537B\x5377\x5382\x5396\x53A0\x53A6\x53A5\x53AE" +++ {-0xD0-} chars "\x53B0\x53B6\x53C3\x7C12\x96D9\x53DF\x66FC\x71EE" +++ {-0xD8-} chars "\x53EE\x53E8\x53ED\x53FA\x5401\x543D\x5440\x542C" +++ {-0xE0-} chars "\x542D\x543C\x542E\x5436\x5429\x541D\x544E\x548F" +++ {-0xE8-} chars "\x5475\x548E\x545F\x5471\x5477\x5470\x5492\x547B" +++ {-0xF0-} chars "\x5480\x5476\x5484\x5490\x5486\x54C7\x54A2\x54B8" +++ {-0xF8-} chars "\x54A5\x54AC\x54C4\x54C8\x54A8"++-- | The multibyte characters with a lead byte of @0x9A@.+second9A :: SecondByteTable+second9A = V.fromList $+ {-0x40-} chars "\x54AB\x54C2\x54A4\x54BE\x54BC\x54D8\x54E5\x54E6" +++ {-0x48-} chars "\x550F\x5514\x54FD\x54EE\x54ED\x54FA\x54E2\x5539" +++ {-0x50-} chars "\x5540\x5563\x554C\x552E\x555C\x5545\x5556\x5557" +++ {-0x58-} chars "\x5538\x5533\x555D\x5599\x5580\x54AF\x558A\x559F" +++ {-0x60-} chars "\x557B\x557E\x5598\x559E\x55AE\x557C\x5583\x55A9" +++ {-0x68-} chars "\x5587\x55A8\x55DA\x55C5\x55DF\x55C4\x55DC\x55E4" +++ {-0x70-} chars "\x55D4\x5614\x55F7\x5616\x55FE\x55FD\x561B\x55F9" +++ {-0x78-} chars "\x564E\x5650\x71DF\x5634\x5636\x5632\x5638" ++ Nothing :+ {-0x80-} chars "\x566B\x5664\x562F\x566C\x566A\x5686\x5680\x568A" +++ {-0x88-} chars "\x56A0\x5694\x568F\x56A5\x56AE\x56B6\x56B4\x56C2" +++ {-0x90-} chars "\x56BC\x56C1\x56C3\x56C0\x56C8\x56CE\x56D1\x56D3" +++ {-0x98-} chars "\x56D7\x56EE\x56F9\x5700\x56FF\x5704\x5709\x5708" +++ {-0xA0-} chars "\x570B\x570D\x5713\x5718\x5716\x55C7\x571C\x5726" +++ {-0xA8-} chars "\x5737\x5738\x574E\x573B\x5740\x574F\x5769\x57C0" +++ {-0xB0-} chars "\x5788\x5761\x577F\x5789\x5793\x57A0\x57B3\x57A4" +++ {-0xB8-} chars "\x57AA\x57B0\x57C3\x57C6\x57D4\x57D2\x57D3\x580A" +++ {-0xC0-} chars "\x57D6\x57E3\x580B\x5819\x581D\x5872\x5821\x5862" +++ {-0xC8-} chars "\x584B\x5870\x6BC0\x5852\x583D\x5879\x5885\x58B9" +++ {-0xD0-} chars "\x589F\x58AB\x58BA\x58DE\x58BB\x58B8\x58AE\x58C5" +++ {-0xD8-} chars "\x58D3\x58D1\x58D7\x58D9\x58D8\x58E5\x58DC\x58E4" +++ {-0xE0-} chars "\x58DF\x58EF\x58FA\x58F9\x58FB\x58FC\x58FD\x5902" +++ {-0xE8-} chars "\x590A\x5910\x591B\x68A6\x5925\x592C\x592D\x5932" +++ {-0xF0-} chars "\x5938\x593E\x7AD2\x5955\x5950\x594E\x595A\x5958" +++ {-0xF8-} chars "\x5962\x5960\x5967\x596C\x5969"++-- | The multibyte characters with a lead byte of @0x9B@.+second9B :: SecondByteTable+second9B = V.fromList $+ {-0x40-} chars "\x5978\x5981\x599D\x4F5E\x4FAB\x59A3\x59B2\x59C6" +++ {-0x48-} chars "\x59E8\x59DC\x598D\x59D9\x59DA\x5A25\x5A1F\x5A11" +++ {-0x50-} chars "\x5A1C\x5A09\x5A1A\x5A40\x5A6C\x5A49\x5A35\x5A36" +++ {-0x58-} chars "\x5A62\x5A6A\x5A9A\x5ABC\x5ABE\x5ACB\x5AC2\x5ABD" +++ {-0x60-} chars "\x5AE3\x5AD7\x5AE6\x5AE9\x5AD6\x5AFA\x5AFB\x5B0C" +++ {-0x68-} chars "\x5B0B\x5B16\x5B32\x5AD0\x5B2A\x5B36\x5B3E\x5B43" +++ {-0x70-} chars "\x5B45\x5B40\x5B51\x5B55\x5B5A\x5B5B\x5B65\x5B69" +++ {-0x78-} chars "\x5B70\x5B73\x5B75\x5B78\x6588\x5B7A\x5B80" ++ Nothing :+ {-0x80-} chars "\x5B83\x5BA6\x5BB8\x5BC3\x5BC7\x5BC9\x5BD4\x5BD0" +++ {-0x88-} chars "\x5BE4\x5BE6\x5BE2\x5BDE\x5BE5\x5BEB\x5BF0\x5BF6" +++ {-0x90-} chars "\x5BF3\x5C05\x5C07\x5C08\x5C0D\x5C13\x5C20\x5C22" +++ {-0x98-} chars "\x5C28\x5C38\x5C39\x5C41\x5C46\x5C4E\x5C53\x5C50" +++ {-0xA0-} chars "\x5C4F\x5B71\x5C6C\x5C6E\x4E62\x5C76\x5C79\x5C8C" +++ {-0xA8-} chars "\x5C91\x5C94\x599B\x5CAB\x5CBB\x5CB6\x5CBC\x5CB7" +++ {-0xB0-} chars "\x5CC5\x5CBE\x5CC7\x5CD9\x5CE9\x5CFD\x5CFA\x5CED" +++ {-0xB8-} chars "\x5D8C\x5CEA\x5D0B\x5D15\x5D17\x5D5C\x5D1F\x5D1B" +++ {-0xC0-} chars "\x5D11\x5D14\x5D22\x5D1A\x5D19\x5D18\x5D4C\x5D52" +++ {-0xC8-} chars "\x5D4E\x5D4B\x5D6C\x5D73\x5D76\x5D87\x5D84\x5D82" +++ {-0xD0-} chars "\x5DA2\x5D9D\x5DAC\x5DAE\x5DBD\x5D90\x5DB7\x5DBC" +++ {-0xD8-} chars "\x5DC9\x5DCD\x5DD3\x5DD2\x5DD6\x5DDB\x5DEB\x5DF2" +++ {-0xE0-} chars "\x5DF5\x5E0B\x5E1A\x5E19\x5E11\x5E1B\x5E36\x5E37" +++ {-0xE8-} chars "\x5E44\x5E43\x5E40\x5E4E\x5E57\x5E54\x5E5F\x5E62" +++ {-0xF0-} chars "\x5E64\x5E47\x5E75\x5E76\x5E7A\x9EBC\x5E7F\x5EA0" +++ {-0xF8-} chars "\x5EC1\x5EC2\x5EC8\x5ED0\x5ECF"++-- | The multibyte characters with a lead byte of @0x9C@.+second9C :: SecondByteTable+second9C = V.fromList $+ {-0x40-} chars "\x5ED6\x5EE3\x5EDD\x5EDA\x5EDB\x5EE2\x5EE1\x5EE8" +++ {-0x48-} chars "\x5EE9\x5EEC\x5EF1\x5EF3\x5EF0\x5EF4\x5EF8\x5EFE" +++ {-0x50-} chars "\x5F03\x5F09\x5F5D\x5F5C\x5F0B\x5F11\x5F16\x5F29" +++ {-0x58-} chars "\x5F2D\x5F38\x5F41\x5F48\x5F4C\x5F4E\x5F2F\x5F51" +++ {-0x60-} chars "\x5F56\x5F57\x5F59\x5F61\x5F6D\x5F73\x5F77\x5F83" +++ {-0x68-} chars "\x5F82\x5F7F\x5F8A\x5F88\x5F91\x5F87\x5F9E\x5F99" +++ {-0x70-} chars "\x5F98\x5FA0\x5FA8\x5FAD\x5FBC\x5FD6\x5FFB\x5FE4" +++ {-0x78-} chars "\x5FF8\x5FF1\x5FDD\x60B3\x5FFF\x6021\x6060" ++ Nothing :+ {-0x80-} chars "\x6019\x6010\x6029\x600E\x6031\x601B\x6015\x602B" +++ {-0x88-} chars "\x6026\x600F\x603A\x605A\x6041\x606A\x6077\x605F" +++ {-0x90-} chars "\x604A\x6046\x604D\x6063\x6043\x6064\x6042\x606C" +++ {-0x98-} chars "\x606B\x6059\x6081\x608D\x60E7\x6083\x609A\x6084" +++ {-0xA0-} chars "\x609B\x6096\x6097\x6092\x60A7\x608B\x60E1\x60B8" +++ {-0xA8-} chars "\x60E0\x60D3\x60B4\x5FF0\x60BD\x60C6\x60B5\x60D8" +++ {-0xB0-} chars "\x614D\x6115\x6106\x60F6\x60F7\x6100\x60F4\x60FA" +++ {-0xB8-} chars "\x6103\x6121\x60FB\x60F1\x610D\x610E\x6147\x613E" +++ {-0xC0-} chars "\x6128\x6127\x614A\x613F\x613C\x612C\x6134\x613D" +++ {-0xC8-} chars "\x6142\x6144\x6173\x6177\x6158\x6159\x615A\x616B" +++ {-0xD0-} chars "\x6174\x616F\x6165\x6171\x615F\x615D\x6153\x6175" +++ {-0xD8-} chars "\x6199\x6196\x6187\x61AC\x6194\x619A\x618A\x6191" +++ {-0xE0-} chars "\x61AB\x61AE\x61CC\x61CA\x61C9\x61F7\x61C8\x61C3" +++ {-0xE8-} chars "\x61C6\x61BA\x61CB\x7F79\x61CD\x61E6\x61E3\x61F6" +++ {-0xF0-} chars "\x61FA\x61F4\x61FF\x61FD\x61FC\x61FE\x6200\x6208" +++ {-0xF8-} chars "\x6209\x620D\x620C\x6214\x621B"++-- | The multibyte characters with a lead byte of @0x9D@.+second9D :: SecondByteTable+second9D = V.fromList $+ {-0x40-} chars "\x621E\x6221\x622A\x622E\x6230\x6232\x6233\x6241" +++ {-0x48-} chars "\x624E\x625E\x6263\x625B\x6260\x6268\x627C\x6282" +++ {-0x50-} chars "\x6289\x627E\x6292\x6293\x6296\x62D4\x6283\x6294" +++ {-0x58-} chars "\x62D7\x62D1\x62BB\x62CF\x62FF\x62C6\x64D4\x62C8" +++ {-0x60-} chars "\x62DC\x62CC\x62CA\x62C2\x62C7\x629B\x62C9\x630C" +++ {-0x68-} chars "\x62EE\x62F1\x6327\x6302\x6308\x62EF\x62F5\x6350" +++ {-0x70-} chars "\x633E\x634D\x641C\x634F\x6396\x638E\x6380\x63AB" +++ {-0x78-} chars "\x6376\x63A3\x638F\x6389\x639F\x63B5\x636B" ++ Nothing :+ {-0x80-} chars "\x6369\x63BE\x63E9\x63C0\x63C6\x63E3\x63C9\x63D2" +++ {-0x88-} chars "\x63F6\x63C4\x6416\x6434\x6406\x6413\x6426\x6436" +++ {-0x90-} chars "\x651D\x6417\x6428\x640F\x6467\x646F\x6476\x644E" +++ {-0x98-} chars "\x652A\x6495\x6493\x64A5\x64A9\x6488\x64BC\x64DA" +++ {-0xA0-} chars "\x64D2\x64C5\x64C7\x64BB\x64D8\x64C2\x64F1\x64E7" +++ {-0xA8-} chars "\x8209\x64E0\x64E1\x62AC\x64E3\x64EF\x652C\x64F6" +++ {-0xB0-} chars "\x64F4\x64F2\x64FA\x6500\x64FD\x6518\x651C\x6505" +++ {-0xB8-} chars "\x6524\x6523\x652B\x6534\x6535\x6537\x6536\x6538" +++ {-0xC0-} chars "\x754B\x6548\x6556\x6555\x654D\x6558\x655E\x655D" +++ {-0xC8-} chars "\x6572\x6578\x6582\x6583\x8B8A\x659B\x659F\x65AB" +++ {-0xD0-} chars "\x65B7\x65C3\x65C6\x65C1\x65C4\x65CC\x65D2\x65DB" +++ {-0xD8-} chars "\x65D9\x65E0\x65E1\x65F1\x6772\x660A\x6603\x65FB" +++ {-0xE0-} chars "\x6773\x6635\x6636\x6634\x661C\x664F\x6644\x6649" +++ {-0xE8-} chars "\x6641\x665E\x665D\x6664\x6667\x6668\x665F\x6662" +++ {-0xF0-} chars "\x6670\x6683\x6688\x668E\x6689\x6684\x6698\x669D" +++ {-0xF8-} chars "\x66C1\x66B9\x66C9\x66BE\x66BC"++-- | The multibyte characters with a lead byte of @0x9E@.+second9E :: SecondByteTable+second9E = V.fromList $+ {-0x40-} chars "\x66C4\x66B8\x66D6\x66DA\x66E0\x663F\x66E6\x66E9" +++ {-0x48-} chars "\x66F0\x66F5\x66F7\x670F\x6716\x671E\x6726\x6727" +++ {-0x50-} chars "\x9738\x672E\x673F\x6736\x6741\x6738\x6737\x6746" +++ {-0x58-} chars "\x675E\x6760\x6759\x6763\x6764\x6789\x6770\x67A9" +++ {-0x60-} chars "\x677C\x676A\x678C\x678B\x67A6\x67A1\x6785\x67B7" +++ {-0x68-} chars "\x67EF\x67B4\x67EC\x67B3\x67E9\x67B8\x67E4\x67DE" +++ {-0x70-} chars "\x67DD\x67E2\x67EE\x67B9\x67CE\x67C6\x67E7\x6A9C" +++ {-0x78-} chars "\x681E\x6846\x6829\x6840\x684D\x6832\x684E" ++ Nothing :+ {-0x80-} chars "\x68B3\x682B\x6859\x6863\x6877\x687F\x689F\x688F" +++ {-0x88-} chars "\x68AD\x6894\x689D\x689B\x6883\x6AAE\x68B9\x6874" +++ {-0x90-} chars "\x68B5\x68A0\x68BA\x690F\x688D\x687E\x6901\x68CA" +++ {-0x98-} chars "\x6908\x68D8\x6922\x6926\x68E1\x690C\x68CD\x68D4" +++ {-0xA0-} chars "\x68E7\x68D5\x6936\x6912\x6904\x68D7\x68E3\x6925" +++ {-0xA8-} chars "\x68F9\x68E0\x68EF\x6928\x692A\x691A\x6923\x6921" +++ {-0xB0-} chars "\x68C6\x6979\x6977\x695C\x6978\x696B\x6954\x697E" +++ {-0xB8-} chars "\x696E\x6939\x6974\x693D\x6959\x6930\x6961\x695E" +++ {-0xC0-} chars "\x695D\x6981\x696A\x69B2\x69AE\x69D0\x69BF\x69C1" +++ {-0xC8-} chars "\x69D3\x69BE\x69CE\x5BE8\x69CA\x69DD\x69BB\x69C3" +++ {-0xD0-} chars "\x69A7\x6A2E\x6991\x69A0\x699C\x6995\x69B4\x69DE" +++ {-0xD8-} chars "\x69E8\x6A02\x6A1B\x69FF\x6B0A\x69F9\x69F2\x69E7" +++ {-0xE0-} chars "\x6A05\x69B1\x6A1E\x69ED\x6A14\x69EB\x6A0A\x6A12" +++ {-0xE8-} chars "\x6AC1\x6A23\x6A13\x6A44\x6A0C\x6A72\x6A36\x6A78" +++ {-0xF0-} chars "\x6A47\x6A62\x6A59\x6A66\x6A48\x6A38\x6A22\x6A90" +++ {-0xF8-} chars "\x6A8D\x6AA0\x6A84\x6AA2\x6AA3"++-- | The multibyte characters with a lead byte of @0x9F@.+second9F :: SecondByteTable+second9F = V.fromList $+ {-0x40-} chars "\x6A97\x8617\x6ABB\x6AC3\x6AC2\x6AB8\x6AB3\x6AAC" +++ {-0x48-} chars "\x6ADE\x6AD1\x6ADF\x6AAA\x6ADA\x6AEA\x6AFB\x6B05" +++ {-0x50-} chars "\x8616\x6AFA\x6B12\x6B16\x9B31\x6B1F\x6B38\x6B37" +++ {-0x58-} chars "\x76DC\x6B39\x98EE\x6B47\x6B43\x6B49\x6B50\x6B59" +++ {-0x60-} chars "\x6B54\x6B5B\x6B5F\x6B61\x6B78\x6B79\x6B7F\x6B80" +++ {-0x68-} chars "\x6B84\x6B83\x6B8D\x6B98\x6B95\x6B9E\x6BA4\x6BAA" +++ {-0x70-} chars "\x6BAB\x6BAF\x6BB2\x6BB1\x6BB3\x6BB7\x6BBC\x6BC6" +++ {-0x78-} chars "\x6BCB\x6BD3\x6BDF\x6BEC\x6BEB\x6BF3\x6BEF" ++ Nothing :+ {-0x80-} chars "\x9EBE\x6C08\x6C13\x6C14\x6C1B\x6C24\x6C23\x6C5E" +++ {-0x88-} chars "\x6C55\x6C62\x6C6A\x6C82\x6C8D\x6C9A\x6C81\x6C9B" +++ {-0x90-} chars "\x6C7E\x6C68\x6C73\x6C92\x6C90\x6CC4\x6CF1\x6CD3" +++ {-0x98-} chars "\x6CBD\x6CD7\x6CC5\x6CDD\x6CAE\x6CB1\x6CBE\x6CBA" +++ {-0xA0-} chars "\x6CDB\x6CEF\x6CD9\x6CEA\x6D1F\x884D\x6D36\x6D2B" +++ {-0xA8-} chars "\x6D3D\x6D38\x6D19\x6D35\x6D33\x6D12\x6D0C\x6D63" +++ {-0xB0-} chars "\x6D93\x6D64\x6D5A\x6D79\x6D59\x6D8E\x6D95\x6FE4" +++ {-0xB8-} chars "\x6D85\x6DF9\x6E15\x6E0A\x6DB5\x6DC7\x6DE6\x6DB8" +++ {-0xC0-} chars "\x6DC6\x6DEC\x6DDE\x6DCC\x6DE8\x6DD2\x6DC5\x6DFA" +++ {-0xC8-} chars "\x6DD9\x6DE4\x6DD5\x6DEA\x6DEE\x6E2D\x6E6E\x6E2E" +++ {-0xD0-} chars "\x6E19\x6E72\x6E5F\x6E3E\x6E23\x6E6B\x6E2B\x6E76" +++ {-0xD8-} chars "\x6E4D\x6E1F\x6E43\x6E3A\x6E4E\x6E24\x6EFF\x6E1D" +++ {-0xE0-} chars "\x6E38\x6E82\x6EAA\x6E98\x6EC9\x6EB7\x6ED3\x6EBD" +++ {-0xE8-} chars "\x6EAF\x6EC4\x6EB2\x6ED4\x6ED5\x6E8F\x6EA5\x6EC2" +++ {-0xF0-} chars "\x6E9F\x6F41\x6F11\x704C\x6EEC\x6EF8\x6EFE\x6F3F" +++ {-0xF8-} chars "\x6EF2\x6F31\x6EEF\x6F32\x6ECC"++-- | The multibyte characters with a lead byte of @0xE0@.+secondE0 :: SecondByteTable+secondE0 = V.fromList $+ {-0x40-} chars "\x6F3E\x6F13\x6EF7\x6F86\x6F7A\x6F78\x6F81\x6F80" +++ {-0x48-} chars "\x6F6F\x6F5B\x6FF3\x6F6D\x6F82\x6F7C\x6F58\x6F8E" +++ {-0x50-} chars "\x6F91\x6FC2\x6F66\x6FB3\x6FA3\x6FA1\x6FA4\x6FB9" +++ {-0x58-} chars "\x6FC6\x6FAA\x6FDF\x6FD5\x6FEC\x6FD4\x6FD8\x6FF1" +++ {-0x60-} chars "\x6FEE\x6FDB\x7009\x700B\x6FFA\x7011\x7001\x700F" +++ {-0x68-} chars "\x6FFE\x701B\x701A\x6F74\x701D\x7018\x701F\x7030" +++ {-0x70-} chars "\x703E\x7032\x7051\x7063\x7099\x7092\x70AF\x70F1" +++ {-0x78-} chars "\x70AC\x70B8\x70B3\x70AE\x70DF\x70CB\x70DD" ++ Nothing :+ {-0x80-} chars "\x70D9\x7109\x70FD\x711C\x7119\x7165\x7155\x7188" +++ {-0x88-} chars "\x7166\x7162\x714C\x7156\x716C\x718F\x71FB\x7184" +++ {-0x90-} chars "\x7195\x71A8\x71AC\x71D7\x71B9\x71BE\x71D2\x71C9" +++ {-0x98-} chars "\x71D4\x71CE\x71E0\x71EC\x71E7\x71F5\x71FC\x71F9" +++ {-0xA0-} chars "\x71FF\x720D\x7210\x721B\x7228\x722D\x722C\x7230" +++ {-0xA8-} chars "\x7232\x723B\x723C\x723F\x7240\x7246\x724B\x7258" +++ {-0xB0-} chars "\x7274\x727E\x7282\x7281\x7287\x7292\x7296\x72A2" +++ {-0xB8-} chars "\x72A7\x72B9\x72B2\x72C3\x72C6\x72C4\x72CE\x72D2" +++ {-0xC0-} chars "\x72E2\x72E0\x72E1\x72F9\x72F7\x500F\x7317\x730A" +++ {-0xC8-} chars "\x731C\x7316\x731D\x7334\x732F\x7329\x7325\x733E" +++ {-0xD0-} chars "\x734E\x734F\x9ED8\x7357\x736A\x7368\x7370\x7378" +++ {-0xD8-} chars "\x7375\x737B\x737A\x73C8\x73B3\x73CE\x73BB\x73C0" +++ {-0xE0-} chars "\x73E5\x73EE\x73DE\x74A2\x7405\x746F\x7425\x73F8" +++ {-0xE8-} chars "\x7432\x743A\x7455\x743F\x745F\x7459\x7441\x745C" +++ {-0xF0-} chars "\x7469\x7470\x7463\x746A\x7476\x747E\x748B\x749E" +++ {-0xF8-} chars "\x74A7\x74CA\x74CF\x74D4\x73F1"++-- | The multibyte characters with a lead byte of @0xE1@.+secondE1 :: SecondByteTable+secondE1 = V.fromList $+ {-0x40-} chars "\x74E0\x74E3\x74E7\x74E9\x74EE\x74F2\x74F0\x74F1" +++ {-0x48-} chars "\x74F8\x74F7\x7504\x7503\x7505\x750C\x750E\x750D" +++ {-0x50-} chars "\x7515\x7513\x751E\x7526\x752C\x753C\x7544\x754D" +++ {-0x58-} chars "\x754A\x7549\x755B\x7546\x755A\x7569\x7564\x7567" +++ {-0x60-} chars "\x756B\x756D\x7578\x7576\x7586\x7587\x7574\x758A" +++ {-0x68-} chars "\x7589\x7582\x7594\x759A\x759D\x75A5\x75A3\x75C2" +++ {-0x70-} chars "\x75B3\x75C3\x75B5\x75BD\x75B8\x75BC\x75B1\x75CD" +++ {-0x78-} chars "\x75CA\x75D2\x75D9\x75E3\x75DE\x75FE\x75FF" ++ Nothing :+ {-0x80-} chars "\x75FC\x7601\x75F0\x75FA\x75F2\x75F3\x760B\x760D" +++ {-0x88-} chars "\x7609\x761F\x7627\x7620\x7621\x7622\x7624\x7634" +++ {-0x90-} chars "\x7630\x763B\x7647\x7648\x7646\x765C\x7658\x7661" +++ {-0x98-} chars "\x7662\x7668\x7669\x766A\x7667\x766C\x7670\x7672" +++ {-0xA0-} chars "\x7676\x7678\x767C\x7680\x7683\x7688\x768B\x768E" +++ {-0xA8-} chars "\x7696\x7693\x7699\x769A\x76B0\x76B4\x76B8\x76B9" +++ {-0xB0-} chars "\x76BA\x76C2\x76CD\x76D6\x76D2\x76DE\x76E1\x76E5" +++ {-0xB8-} chars "\x76E7\x76EA\x862F\x76FB\x7708\x7707\x7704\x7729" +++ {-0xC0-} chars "\x7724\x771E\x7725\x7726\x771B\x7737\x7738\x7747" +++ {-0xC8-} chars "\x775A\x7768\x776B\x775B\x7765\x777F\x777E\x7779" +++ {-0xD0-} chars "\x778E\x778B\x7791\x77A0\x779E\x77B0\x77B6\x77B9" +++ {-0xD8-} chars "\x77BF\x77BC\x77BD\x77BB\x77C7\x77CD\x77D7\x77DA" +++ {-0xE0-} chars "\x77DC\x77E3\x77EE\x77FC\x780C\x7812\x7926\x7820" +++ {-0xE8-} chars "\x792A\x7845\x788E\x7874\x7886\x787C\x789A\x788C" +++ {-0xF0-} chars "\x78A3\x78B5\x78AA\x78AF\x78D1\x78C6\x78CB\x78D4" +++ {-0xF8-} chars "\x78BE\x78BC\x78C5\x78CA\x78EC"++-- | The multibyte characters with a lead byte of @0xE2@.+secondE2 :: SecondByteTable+secondE2 = V.fromList $+ {-0x40-} chars "\x78E7\x78DA\x78FD\x78F4\x7907\x7912\x7911\x7919" +++ {-0x48-} chars "\x792C\x792B\x7940\x7960\x7957\x795F\x795A\x7955" +++ {-0x50-} chars "\x7953\x797A\x797F\x798A\x799D\x79A7\x9F4B\x79AA" +++ {-0x58-} chars "\x79AE\x79B3\x79B9\x79BA\x79C9\x79D5\x79E7\x79EC" +++ {-0x60-} chars "\x79E1\x79E3\x7A08\x7A0D\x7A18\x7A19\x7A20\x7A1F" +++ {-0x68-} chars "\x7980\x7A31\x7A3B\x7A3E\x7A37\x7A43\x7A57\x7A49" +++ {-0x70-} chars "\x7A61\x7A62\x7A69\x9F9D\x7A70\x7A79\x7A7D\x7A88" +++ {-0x78-} chars "\x7A97\x7A95\x7A98\x7A96\x7AA9\x7AC8\x7AB0" ++ Nothing :+ {-0x80-} chars "\x7AB6\x7AC5\x7AC4\x7ABF\x9083\x7AC7\x7ACA\x7ACD" +++ {-0x88-} chars "\x7ACF\x7AD5\x7AD3\x7AD9\x7ADA\x7ADD\x7AE1\x7AE2" +++ {-0x90-} chars "\x7AE6\x7AED\x7AF0\x7B02\x7B0F\x7B0A\x7B06\x7B33" +++ {-0x98-} chars "\x7B18\x7B19\x7B1E\x7B35\x7B28\x7B36\x7B50\x7B7A" +++ {-0xA0-} chars "\x7B04\x7B4D\x7B0B\x7B4C\x7B45\x7B75\x7B65\x7B74" +++ {-0xA8-} chars "\x7B67\x7B70\x7B71\x7B6C\x7B6E\x7B9D\x7B98\x7B9F" +++ {-0xB0-} chars "\x7B8D\x7B9C\x7B9A\x7B8B\x7B92\x7B8F\x7B5D\x7B99" +++ {-0xB8-} chars "\x7BCB\x7BC1\x7BCC\x7BCF\x7BB4\x7BC6\x7BDD\x7BE9" +++ {-0xC0-} chars "\x7C11\x7C14\x7BE6\x7BE5\x7C60\x7C00\x7C07\x7C13" +++ {-0xC8-} chars "\x7BF3\x7BF7\x7C17\x7C0D\x7BF6\x7C23\x7C27\x7C2A" +++ {-0xD0-} chars "\x7C1F\x7C37\x7C2B\x7C3D\x7C4C\x7C43\x7C54\x7C4F" +++ {-0xD8-} chars "\x7C40\x7C50\x7C58\x7C5F\x7C64\x7C56\x7C65\x7C6C" +++ {-0xE0-} chars "\x7C75\x7C83\x7C90\x7CA4\x7CAD\x7CA2\x7CAB\x7CA1" +++ {-0xE8-} chars "\x7CA8\x7CB3\x7CB2\x7CB1\x7CAE\x7CB9\x7CBD\x7CC0" +++ {-0xF0-} chars "\x7CC5\x7CC2\x7CD8\x7CD2\x7CDC\x7CE2\x9B3B\x7CEF" +++ {-0xF8-} chars "\x7CF2\x7CF4\x7CF6\x7CFA\x7D06"++-- | The multibyte characters with a lead byte of @0xE3@.+secondE3 :: SecondByteTable+secondE3 = V.fromList $+ {-0x40-} chars "\x7D02\x7D1C\x7D15\x7D0A\x7D45\x7D4B\x7D2E\x7D32" +++ {-0x48-} chars "\x7D3F\x7D35\x7D46\x7D73\x7D56\x7D4E\x7D72\x7D68" +++ {-0x50-} chars "\x7D6E\x7D4F\x7D63\x7D93\x7D89\x7D5B\x7D8F\x7D7D" +++ {-0x58-} chars "\x7D9B\x7DBA\x7DAE\x7DA3\x7DB5\x7DC7\x7DBD\x7DAB" +++ {-0x60-} chars "\x7E3D\x7DA2\x7DAF\x7DDC\x7DB8\x7D9F\x7DB0\x7DD8" +++ {-0x68-} chars "\x7DDD\x7DE4\x7DDE\x7DFB\x7DF2\x7DE1\x7E05\x7E0A" +++ {-0x70-} chars "\x7E23\x7E21\x7E12\x7E31\x7E1F\x7E09\x7E0B\x7E22" +++ {-0x78-} chars "\x7E46\x7E66\x7E3B\x7E35\x7E39\x7E43\x7E37" ++ Nothing :+ {-0x80-} chars "\x7E32\x7E3A\x7E67\x7E5D\x7E56\x7E5E\x7E59\x7E5A" +++ {-0x88-} chars "\x7E79\x7E6A\x7E69\x7E7C\x7E7B\x7E83\x7DD5\x7E7D" +++ {-0x90-} chars "\x8FAE\x7E7F\x7E88\x7E89\x7E8C\x7E92\x7E90\x7E93" +++ {-0x98-} chars "\x7E94\x7E96\x7E8E\x7E9B\x7E9C\x7F38\x7F3A\x7F45" +++ {-0xA0-} chars "\x7F4C\x7F4D\x7F4E\x7F50\x7F51\x7F55\x7F54\x7F58" +++ {-0xA8-} chars "\x7F5F\x7F60\x7F68\x7F69\x7F67\x7F78\x7F82\x7F86" +++ {-0xB0-} chars "\x7F83\x7F88\x7F87\x7F8C\x7F94\x7F9E\x7F9D\x7F9A" +++ {-0xB8-} chars "\x7FA3\x7FAF\x7FB2\x7FB9\x7FAE\x7FB6\x7FB8\x8B71" +++ {-0xC0-} chars "\x7FC5\x7FC6\x7FCA\x7FD5\x7FD4\x7FE1\x7FE6\x7FE9" +++ {-0xC8-} chars "\x7FF3\x7FF9\x98DC\x8006\x8004\x800B\x8012\x8018" +++ {-0xD0-} chars "\x8019\x801C\x8021\x8028\x803F\x803B\x804A\x8046" +++ {-0xD8-} chars "\x8052\x8058\x805A\x805F\x8062\x8068\x8073\x8072" +++ {-0xE0-} chars "\x8070\x8076\x8079\x807D\x807F\x8084\x8086\x8085" +++ {-0xE8-} chars "\x809B\x8093\x809A\x80AD\x5190\x80AC\x80DB\x80E5" +++ {-0xF0-} chars "\x80D9\x80DD\x80C4\x80DA\x80D6\x8109\x80EF\x80F1" +++ {-0xF8-} chars "\x811B\x8129\x8123\x812F\x814B"++-- | The multibyte characters with a lead byte of @0xE4@.+secondE4 :: SecondByteTable+secondE4 = V.fromList $+ {-0x40-} chars "\x968B\x8146\x813E\x8153\x8151\x80FC\x8171\x816E" +++ {-0x48-} chars "\x8165\x8166\x8174\x8183\x8188\x818A\x8180\x8182" +++ {-0x50-} chars "\x81A0\x8195\x81A4\x81A3\x815F\x8193\x81A9\x81B0" +++ {-0x58-} chars "\x81B5\x81BE\x81B8\x81BD\x81C0\x81C2\x81BA\x81C9" +++ {-0x60-} chars "\x81CD\x81D1\x81D9\x81D8\x81C8\x81DA\x81DF\x81E0" +++ {-0x68-} chars "\x81E7\x81FA\x81FB\x81FE\x8201\x8202\x8205\x8207" +++ {-0x70-} chars "\x820A\x820D\x8210\x8216\x8229\x822B\x8238\x8233" +++ {-0x78-} chars "\x8240\x8259\x8258\x825D\x825A\x825F\x8264" ++ Nothing :+ {-0x80-} chars "\x8262\x8268\x826A\x826B\x822E\x8271\x8277\x8278" +++ {-0x88-} chars "\x827E\x828D\x8292\x82AB\x829F\x82BB\x82AC\x82E1" +++ {-0x90-} chars "\x82E3\x82DF\x82D2\x82F4\x82F3\x82FA\x8393\x8303" +++ {-0x98-} chars "\x82FB\x82F9\x82DE\x8306\x82DC\x8309\x82D9\x8335" +++ {-0xA0-} chars "\x8334\x8316\x8332\x8331\x8340\x8339\x8350\x8345" +++ {-0xA8-} chars "\x832F\x832B\x8317\x8318\x8385\x839A\x83AA\x839F" +++ {-0xB0-} chars "\x83A2\x8396\x8323\x838E\x8387\x838A\x837C\x83B5" +++ {-0xB8-} chars "\x8373\x8375\x83A0\x8389\x83A8\x83F4\x8413\x83EB" +++ {-0xC0-} chars "\x83CE\x83FD\x8403\x83D8\x840B\x83C1\x83F7\x8407" +++ {-0xC8-} chars "\x83E0\x83F2\x840D\x8422\x8420\x83BD\x8438\x8506" +++ {-0xD0-} chars "\x83FB\x846D\x842A\x843C\x855A\x8484\x8477\x846B" +++ {-0xD8-} chars "\x84AD\x846E\x8482\x8469\x8446\x842C\x846F\x8479" +++ {-0xE0-} chars "\x8435\x84CA\x8462\x84B9\x84BF\x849F\x84D9\x84CD" +++ {-0xE8-} chars "\x84BB\x84DA\x84D0\x84C1\x84C6\x84D6\x84A1\x8521" +++ {-0xF0-} chars "\x84FF\x84F4\x8517\x8518\x852C\x851F\x8515\x8514" +++ {-0xF8-} chars "\x84FC\x8540\x8563\x8558\x8548"++-- | The multibyte characters with a lead byte of @0xE5@.+secondE5 :: SecondByteTable+secondE5 = V.fromList $+ {-0x40-} chars "\x8541\x8602\x854B\x8555\x8580\x85A4\x8588\x8591" +++ {-0x48-} chars "\x858A\x85A8\x856D\x8594\x859B\x85EA\x8587\x859C" +++ {-0x50-} chars "\x8577\x857E\x8590\x85C9\x85BA\x85CF\x85B9\x85D0" +++ {-0x58-} chars "\x85D5\x85DD\x85E5\x85DC\x85F9\x860A\x8613\x860B" +++ {-0x60-} chars "\x85FE\x85FA\x8606\x8622\x861A\x8630\x863F\x864D" +++ {-0x68-} chars "\x4E55\x8654\x865F\x8667\x8671\x8693\x86A3\x86A9" +++ {-0x70-} chars "\x86AA\x868B\x868C\x86B6\x86AF\x86C4\x86C6\x86B0" +++ {-0x78-} chars "\x86C9\x8823\x86AB\x86D4\x86DE\x86E9\x86EC" ++ Nothing :+ {-0x80-} chars "\x86DF\x86DB\x86EF\x8712\x8706\x8708\x8700\x8703" +++ {-0x88-} chars "\x86FB\x8711\x8709\x870D\x86F9\x870A\x8734\x873F" +++ {-0x90-} chars "\x8737\x873B\x8725\x8729\x871A\x8760\x875F\x8778" +++ {-0x98-} chars "\x874C\x874E\x8774\x8757\x8768\x876E\x8759\x8753" +++ {-0xA0-} chars "\x8763\x876A\x8805\x87A2\x879F\x8782\x87AF\x87CB" +++ {-0xA8-} chars "\x87BD\x87C0\x87D0\x96D6\x87AB\x87C4\x87B3\x87C7" +++ {-0xB0-} chars "\x87C6\x87BB\x87EF\x87F2\x87E0\x880F\x880D\x87FE" +++ {-0xB8-} chars "\x87F6\x87F7\x880E\x87D2\x8811\x8816\x8815\x8822" +++ {-0xC0-} chars "\x8821\x8831\x8836\x8839\x8827\x883B\x8844\x8842" +++ {-0xC8-} chars "\x8852\x8859\x885E\x8862\x886B\x8881\x887E\x889E" +++ {-0xD0-} chars "\x8875\x887D\x88B5\x8872\x8882\x8897\x8892\x88AE" +++ {-0xD8-} chars "\x8899\x88A2\x888D\x88A4\x88B0\x88BF\x88B1\x88C3" +++ {-0xE0-} chars "\x88C4\x88D4\x88D8\x88D9\x88DD\x88F9\x8902\x88FC" +++ {-0xE8-} chars "\x88F4\x88E8\x88F2\x8904\x890C\x890A\x8913\x8943" +++ {-0xF0-} chars "\x891E\x8925\x892A\x892B\x8941\x8944\x893B\x8936" +++ {-0xF8-} chars "\x8938\x894C\x891D\x8960\x895E"++-- | The multibyte characters with a lead byte of @0xE6@.+secondE6 :: SecondByteTable+secondE6 = V.fromList $+ {-0x40-} chars "\x8966\x8964\x896D\x896A\x896F\x8974\x8977\x897E" +++ {-0x48-} chars "\x8983\x8988\x898A\x8993\x8998\x89A1\x89A9\x89A6" +++ {-0x50-} chars "\x89AC\x89AF\x89B2\x89BA\x89BD\x89BF\x89C0\x89DA" +++ {-0x58-} chars "\x89DC\x89DD\x89E7\x89F4\x89F8\x8A03\x8A16\x8A10" +++ {-0x60-} chars "\x8A0C\x8A1B\x8A1D\x8A25\x8A36\x8A41\x8A5B\x8A52" +++ {-0x68-} chars "\x8A46\x8A48\x8A7C\x8A6D\x8A6C\x8A62\x8A85\x8A82" +++ {-0x70-} chars "\x8A84\x8AA8\x8AA1\x8A91\x8AA5\x8AA6\x8A9A\x8AA3" +++ {-0x78-} chars "\x8AC4\x8ACD\x8AC2\x8ADA\x8AEB\x8AF3\x8AE7" ++ Nothing :+ {-0x80-} chars "\x8AE4\x8AF1\x8B14\x8AE0\x8AE2\x8AF7\x8ADE\x8ADB" +++ {-0x88-} chars "\x8B0C\x8B07\x8B1A\x8AE1\x8B16\x8B10\x8B17\x8B20" +++ {-0x90-} chars "\x8B33\x97AB\x8B26\x8B2B\x8B3E\x8B28\x8B41\x8B4C" +++ {-0x98-} chars "\x8B4F\x8B4E\x8B49\x8B56\x8B5B\x8B5A\x8B6B\x8B5F" +++ {-0xA0-} chars "\x8B6C\x8B6F\x8B74\x8B7D\x8B80\x8B8C\x8B8E\x8B92" +++ {-0xA8-} chars "\x8B93\x8B96\x8B99\x8B9A\x8C3A\x8C41\x8C3F\x8C48" +++ {-0xB0-} chars "\x8C4C\x8C4E\x8C50\x8C55\x8C62\x8C6C\x8C78\x8C7A" +++ {-0xB8-} chars "\x8C82\x8C89\x8C85\x8C8A\x8C8D\x8C8E\x8C94\x8C7C" +++ {-0xC0-} chars "\x8C98\x621D\x8CAD\x8CAA\x8CBD\x8CB2\x8CB3\x8CAE" +++ {-0xC8-} chars "\x8CB6\x8CC8\x8CC1\x8CE4\x8CE3\x8CDA\x8CFD\x8CFA" +++ {-0xD0-} chars "\x8CFB\x8D04\x8D05\x8D0A\x8D07\x8D0F\x8D0D\x8D10" +++ {-0xD8-} chars "\x9F4E\x8D13\x8CCD\x8D14\x8D16\x8D67\x8D6D\x8D71" +++ {-0xE0-} chars "\x8D73\x8D81\x8D99\x8DC2\x8DBE\x8DBA\x8DCF\x8DDA" +++ {-0xE8-} chars "\x8DD6\x8DCC\x8DDB\x8DCB\x8DEA\x8DEB\x8DDF\x8DE3" +++ {-0xF0-} chars "\x8DFC\x8E08\x8E09\x8DFF\x8E1D\x8E1E\x8E10\x8E1F" +++ {-0xF8-} chars "\x8E42\x8E35\x8E30\x8E34\x8E4A"++-- | The multibyte characters with a lead byte of @0xE7@.+secondE7 :: SecondByteTable+secondE7 = V.fromList $+ {-0x40-} chars "\x8E47\x8E49\x8E4C\x8E50\x8E48\x8E59\x8E64\x8E60" +++ {-0x48-} chars "\x8E2A\x8E63\x8E55\x8E76\x8E72\x8E7C\x8E81\x8E87" +++ {-0x50-} chars "\x8E85\x8E84\x8E8B\x8E8A\x8E93\x8E91\x8E94\x8E99" +++ {-0x58-} chars "\x8EAA\x8EA1\x8EAC\x8EB0\x8EC6\x8EB1\x8EBE\x8EC5" +++ {-0x60-} chars "\x8EC8\x8ECB\x8EDB\x8EE3\x8EFC\x8EFB\x8EEB\x8EFE" +++ {-0x68-} chars "\x8F0A\x8F05\x8F15\x8F12\x8F19\x8F13\x8F1C\x8F1F" +++ {-0x70-} chars "\x8F1B\x8F0C\x8F26\x8F33\x8F3B\x8F39\x8F45\x8F42" +++ {-0x78-} chars "\x8F3E\x8F4C\x8F49\x8F46\x8F4E\x8F57\x8F5C" ++ Nothing :+ {-0x80-} chars "\x8F62\x8F63\x8F64\x8F9C\x8F9F\x8FA3\x8FAD\x8FAF" +++ {-0x88-} chars "\x8FB7\x8FDA\x8FE5\x8FE2\x8FEA\x8FEF\x9087\x8FF4" +++ {-0x90-} chars "\x9005\x8FF9\x8FFA\x9011\x9015\x9021\x900D\x901E" +++ {-0x98-} chars "\x9016\x900B\x9027\x9036\x9035\x9039\x8FF8\x904F" +++ {-0xA0-} chars "\x9050\x9051\x9052\x900E\x9049\x903E\x9056\x9058" +++ {-0xA8-} chars "\x905E\x9068\x906F\x9076\x96A8\x9072\x9082\x907D" +++ {-0xB0-} chars "\x9081\x9080\x908A\x9089\x908F\x90A8\x90AF\x90B1" +++ {-0xB8-} chars "\x90B5\x90E2\x90E4\x6248\x90DB\x9102\x9112\x9119" +++ {-0xC0-} chars "\x9132\x9130\x914A\x9156\x9158\x9163\x9165\x9169" +++ {-0xC8-} chars "\x9173\x9172\x918B\x9189\x9182\x91A2\x91AB\x91AF" +++ {-0xD0-} chars "\x91AA\x91B5\x91B4\x91BA\x91C0\x91C1\x91C9\x91CB" +++ {-0xD8-} chars "\x91D0\x91D6\x91DF\x91E1\x91DB\x91FC\x91F5\x91F6" +++ {-0xE0-} chars "\x921E\x91FF\x9214\x922C\x9215\x9211\x925E\x9257" +++ {-0xE8-} chars "\x9245\x9249\x9264\x9248\x9295\x923F\x924B\x9250" +++ {-0xF0-} chars "\x929C\x9296\x9293\x929B\x925A\x92CF\x92B9\x92B7" +++ {-0xF8-} chars "\x92E9\x930F\x92FA\x9344\x932E"++-- | The multibyte characters with a lead byte of @0xE8@.+secondE8 :: SecondByteTable+secondE8 = V.fromList $+ {-0x40-} chars "\x9319\x9322\x931A\x9323\x933A\x9335\x933B\x935C" +++ {-0x48-} chars "\x9360\x937C\x936E\x9356\x93B0\x93AC\x93AD\x9394" +++ {-0x50-} chars "\x93B9\x93D6\x93D7\x93E8\x93E5\x93D8\x93C3\x93DD" +++ {-0x58-} chars "\x93D0\x93C8\x93E4\x941A\x9414\x9413\x9403\x9407" +++ {-0x60-} chars "\x9410\x9436\x942B\x9435\x9421\x943A\x9441\x9452" +++ {-0x68-} chars "\x9444\x945B\x9460\x9462\x945E\x946A\x9229\x9470" +++ {-0x70-} chars "\x9475\x9477\x947D\x945A\x947C\x947E\x9481\x947F" +++ {-0x78-} chars "\x9582\x9587\x958A\x9594\x9596\x9598\x9599" ++ Nothing :+ {-0x80-} chars "\x95A0\x95A8\x95A7\x95AD\x95BC\x95BB\x95B9\x95BE" +++ {-0x88-} chars "\x95CA\x6FF6\x95C3\x95CD\x95CC\x95D5\x95D4\x95D6" +++ {-0x90-} chars "\x95DC\x95E1\x95E5\x95E2\x9621\x9628\x962E\x962F" +++ {-0x98-} chars "\x9642\x964C\x964F\x964B\x9677\x965C\x965E\x965D" +++ {-0xA0-} chars "\x965F\x9666\x9672\x966C\x968D\x9698\x9695\x9697" +++ {-0xA8-} chars "\x96AA\x96A7\x96B1\x96B2\x96B0\x96B4\x96B6\x96B8" +++ {-0xB0-} chars "\x96B9\x96CE\x96CB\x96C9\x96CD\x894D\x96DC\x970D" +++ {-0xB8-} chars "\x96D5\x96F9\x9704\x9706\x9708\x9713\x970E\x9711" +++ {-0xC0-} chars "\x970F\x9716\x9719\x9724\x972A\x9730\x9739\x973D" +++ {-0xC8-} chars "\x973E\x9744\x9746\x9748\x9742\x9749\x975C\x9760" +++ {-0xD0-} chars "\x9764\x9766\x9768\x52D2\x976B\x9771\x9779\x9785" +++ {-0xD8-} chars "\x977C\x9781\x977A\x9786\x978B\x978F\x9790\x979C" +++ {-0xE0-} chars "\x97A8\x97A6\x97A3\x97B3\x97B4\x97C3\x97C6\x97C8" +++ {-0xE8-} chars "\x97CB\x97DC\x97ED\x9F4F\x97F2\x7ADF\x97F6\x97F5" +++ {-0xF0-} chars "\x980F\x980C\x9838\x9824\x9821\x9837\x983D\x9846" +++ {-0xF8-} chars "\x984F\x984B\x986B\x986F\x9870"++-- | The multibyte characters with a lead byte of @0xE9@.+secondE9 :: SecondByteTable+secondE9 = V.fromList $+ {-0x40-} chars "\x9871\x9874\x9873\x98AA\x98AF\x98B1\x98B6\x98C4" +++ {-0x48-} chars "\x98C3\x98C6\x98E9\x98EB\x9903\x9909\x9912\x9914" +++ {-0x50-} chars "\x9918\x9921\x991D\x991E\x9924\x9920\x992C\x992E" +++ {-0x58-} chars "\x993D\x993E\x9942\x9949\x9945\x9950\x994B\x9951" +++ {-0x60-} chars "\x9952\x994C\x9955\x9997\x9998\x99A5\x99AD\x99AE" +++ {-0x68-} chars "\x99BC\x99DF\x99DB\x99DD\x99D8\x99D1\x99ED\x99EE" +++ {-0x70-} chars "\x99F1\x99F2\x99FB\x99F8\x9A01\x9A0F\x9A05\x99E2" +++ {-0x78-} chars "\x9A19\x9A2B\x9A37\x9A45\x9A42\x9A40\x9A43" ++ Nothing :+ {-0x80-} chars "\x9A3E\x9A55\x9A4D\x9A5B\x9A57\x9A5F\x9A62\x9A65" +++ {-0x88-} chars "\x9A64\x9A69\x9A6B\x9A6A\x9AAD\x9AB0\x9ABC\x9AC0" +++ {-0x90-} chars "\x9ACF\x9AD1\x9AD3\x9AD4\x9ADE\x9ADF\x9AE2\x9AE3" +++ {-0x98-} chars "\x9AE6\x9AEF\x9AEB\x9AEE\x9AF4\x9AF1\x9AF7\x9AFB" +++ {-0xA0-} chars "\x9B06\x9B18\x9B1A\x9B1F\x9B22\x9B23\x9B25\x9B27" +++ {-0xA8-} chars "\x9B28\x9B29\x9B2A\x9B2E\x9B2F\x9B32\x9B44\x9B43" +++ {-0xB0-} chars "\x9B4F\x9B4D\x9B4E\x9B51\x9B58\x9B74\x9B93\x9B83" +++ {-0xB8-} chars "\x9B91\x9B96\x9B97\x9B9F\x9BA0\x9BA8\x9BB4\x9BC0" +++ {-0xC0-} chars "\x9BCA\x9BB9\x9BC6\x9BCF\x9BD1\x9BD2\x9BE3\x9BE2" +++ {-0xC8-} chars "\x9BE4\x9BD4\x9BE1\x9C3A\x9BF2\x9BF1\x9BF0\x9C15" +++ {-0xD0-} chars "\x9C14\x9C09\x9C13\x9C0C\x9C06\x9C08\x9C12\x9C0A" +++ {-0xD8-} chars "\x9C04\x9C2E\x9C1B\x9C25\x9C24\x9C21\x9C30\x9C47" +++ {-0xE0-} chars "\x9C32\x9C46\x9C3E\x9C5A\x9C60\x9C67\x9C76\x9C78" +++ {-0xE8-} chars "\x9CE7\x9CEC\x9CF0\x9D09\x9D08\x9CEB\x9D03\x9D06" +++ {-0xF0-} chars "\x9D2A\x9D26\x9DAF\x9D23\x9D1F\x9D44\x9D15\x9D12" +++ {-0xF8-} chars "\x9D41\x9D3F\x9D3E\x9D46\x9D48"++-- | The multibyte characters with a lead byte of @0xEA@.+secondEA :: SecondByteTable+secondEA = V.fromList $+ {-0x40-} chars "\x9D5D\x9D5E\x9D64\x9D51\x9D50\x9D59\x9D72\x9D89" +++ {-0x48-} chars "\x9D87\x9DAB\x9D6F\x9D7A\x9D9A\x9DA4\x9DA9\x9DB2" +++ {-0x50-} chars "\x9DC4\x9DC1\x9DBB\x9DB8\x9DBA\x9DC6\x9DCF\x9DC2" +++ {-0x58-} chars "\x9DD9\x9DD3\x9DF8\x9DE6\x9DED\x9DEF\x9DFD\x9E1A" +++ {-0x60-} chars "\x9E1B\x9E1E\x9E75\x9E79\x9E7D\x9E81\x9E88\x9E8B" +++ {-0x68-} chars "\x9E8C\x9E92\x9E95\x9E91\x9E9D\x9EA5\x9EA9\x9EB8" +++ {-0x70-} chars "\x9EAA\x9EAD\x9761\x9ECC\x9ECE\x9ECF\x9ED0\x9ED4" +++ {-0x78-} chars "\x9EDC\x9EDE\x9EDD\x9EE0\x9EE5\x9EE8\x9EEF" ++ Nothing :+ {-0x80-} chars "\x9EF4\x9EF6\x9EF7\x9EF9\x9EFB\x9EFC\x9EFD\x9F07" +++ {-0x88-} chars "\x9F08\x76B7\x9F15\x9F21\x9F2C\x9F3E\x9F4A\x9F52" +++ {-0x90-} chars "\x9F54\x9F63\x9F5F\x9F60\x9F61\x9F66\x9F67\x9F6C" +++ {-0x98-} chars "\x9F6A\x9F77\x9F72\x9F76\x9F95\x9F9C\x9FA0\x582F" +++ {-0xA0-} chars "\x69C7\x9059\x7464\x51DC\x7199" +++ {-0xA5..0xFC-} nothings 0x58++-- | The multibyte characters with a lead byte of @0xEB@.+secondEB :: SecondByteTable+secondEB = nothingSecond++-- | The multibyte characters with a lead byte of @0xEC@.+secondEC :: SecondByteTable+secondEC = nothingSecond++-- | The multibyte characters with a lead byte of @0xED@.+secondED :: SecondByteTable+secondED = V.fromList $+ {-0x40-} chars "\x7E8A\x891C\x9348\x9288\x84DC\x4FC9\x70BB\x6631" +++ {-0x48-} chars "\x68C8\x92F9\x66FB\x5F45\x4E28\x4EE1\x4EFC\x4F00" +++ {-0x50-} chars "\x4F03\x4F39\x4F56\x4F92\x4F8A\x4F9A\x4F94\x4FCD" +++ {-0x58-} chars "\x5040\x5022\x4FFF\x501E\x5046\x5070\x5042\x5094" +++ {-0x60-} chars "\x50F4\x50D8\x514A\x5164\x519D\x51BE\x51EC\x5215" +++ {-0x68-} chars "\x529C\x52A6\x52C0\x52DB\x5300\x5307\x5324\x5372" +++ {-0x70-} chars "\x5393\x53B2\x53DD\xFA0E\x549C\x548A\x54A9\x54FF" +++ {-0x78-} chars "\x5586\x5759\x5765\x57AC\x57C8\x57C7\xFA0F" ++ Nothing :+ {-0x80-} chars "\xFA10\x589E\x58B2\x590B\x5953\x595B\x595D\x5963" +++ {-0x88-} chars "\x59A4\x59BA\x5B56\x5BC0\x752F\x5BD8\x5BEC\x5C1E" +++ {-0x90-} chars "\x5CA6\x5CBA\x5CF5\x5D27\x5D53\xFA11\x5D42\x5D6D" +++ {-0x98-} chars "\x5DB8\x5DB9\x5DD0\x5F21\x5F34\x5F67\x5FB7\x5FDE" +++ {-0xA0-} chars "\x605D\x6085\x608A\x60DE\x60D5\x6120\x60F2\x6111" +++ {-0xA8-} chars "\x6137\x6130\x6198\x6213\x62A6\x63F5\x6460\x649D" +++ {-0xB0-} chars "\x64CE\x654E\x6600\x6615\x663B\x6609\x662E\x661E" +++ {-0xB8-} chars "\x6624\x6665\x6657\x6659\xFA12\x6673\x6699\x66A0" +++ {-0xC0-} chars "\x66B2\x66BF\x66FA\x670E\xF929\x6766\x67BB\x6852" +++ {-0xC8-} chars "\x67C0\x6801\x6844\x68CF\xFA13\x6968\xFA14\x6998" +++ {-0xD0-} chars "\x69E2\x6A30\x6A6B\x6A46\x6A73\x6A7E\x6AE2\x6AE4" +++ {-0xD8-} chars "\x6BD6\x6C3F\x6C5C\x6C86\x6C6F\x6CDA\x6D04\x6D87" +++ {-0xE0-} chars "\x6D6F\x6D96\x6DAC\x6DCF\x6DF8\x6DF2\x6DFC\x6E39" +++ {-0xE8-} chars "\x6E5C\x6E27\x6E3C\x6EBF\x6F88\x6FB5\x6FF5\x7005" +++ {-0xF0-} chars "\x7007\x7028\x7085\x70AB\x710F\x7104\x715C\x7146" +++ {-0xF8-} chars "\x7147\xFA15\x71C1\x71FE\x72B1"++-- | The multibyte characters with a lead byte of @0xEE@.+secondEE :: SecondByteTable+secondEE = V.fromList $+ {-0x40-} chars "\x72BE\x7324\xFA16\x7377\x73BD\x73C9\x73D6\x73E3" +++ {-0x48-} chars "\x73D2\x7407\x73F5\x7426\x742A\x7429\x742E\x7462" +++ {-0x50-} chars "\x7489\x749F\x7501\x756F\x7682\x769C\x769E\x769B" +++ {-0x58-} chars "\x76A6\xFA17\x7746\x52AF\x7821\x784E\x7864\x787A" +++ {-0x40-} chars "\x7930\xFA18\xFA19\xFA1A\x7994\xFA1B\x799B\x7AD1" +++ {-0x68-} chars "\x7AE7\xFA1C\x7AEB\x7B9E\xFA1D\x7D48\x7D5C\x7DB7" +++ {-0x70-} chars "\x7DA0\x7DD6\x7E52\x7F47\x7FA1\xFA1E\x8301\x8362" +++ {-0x78-} chars "\x837F\x83C7\x83F6\x8448\x84B4\x8553\x8559" ++ Nothing :+ {-0x80-} chars "\x856B\xFA1F\x85B0\xFA20\xFA21\x8807\x88F5\x8A12" +++ {-0x88-} chars "\x8A37\x8A79\x8AA7\x8ABE\x8ADF\xFA22\x8AF6\x8B53" +++ {-0x90-} chars "\x8B7F\x8CF0\x8CF4\x8D12\x8D76\xFA23\x8ECF\xFA24" +++ {-0x98-} chars "\xFA25\x9067\x90DE\xFA26\x9115\x9127\x91DA\x91D7" +++ {-0xA0-} chars "\x91DE\x91ED\x91EE\x91E4\x91E5\x9206\x9210\x920A" +++ {-0xA8-} chars "\x923A\x9240\x923C\x924E\x9259\x9251\x9239\x9267" +++ {-0xB0-} chars "\x92A7\x9277\x9278\x92E7\x92D7\x92D9\x92D0\xFA27" +++ {-0xB8-} chars "\x92D5\x92E0\x92D3\x9325\x9321\x92FB\xFA28\x931E" +++ {-0xC0-} chars "\x92FF\x931D\x9302\x9370\x9357\x93A4\x93C6\x93DE" +++ {-0xC8-} chars "\x93F8\x9431\x9445\x9448\x9592\xF9DC\xFA29\x969D" +++ {-0xD0-} chars "\x96AF\x9733\x973B\x9743\x974D\x974F\x9751\x9755" +++ {-0xD8-} chars "\x9857\x9865\xFA2A\xFA2B\x9927\xFA2C\x999E\x9A4E" +++ {-0xE0-} chars "\x9AD9\x9ADC\x9B75\x9B72\x9B8F\x9BB1\x9BBB\x9C00" +++ {-0xE8-} chars "\x9D70\x9D6B\xFA2D\x9E19\x9ED1" ++ nothings 2 +++ {-0xEF..0xF8-} chars ['\x2170'..'\x2179'] +++ {-0xF9-} chars "\xFFE2\xFFE4\xFF07\xFF02"++-- | The multibyte characters with a lead byte of @0xEF@.+secondEF :: SecondByteTable+secondEF = nothingSecond++-- | The multibyte characters with a lead byte of @0xF0@.+secondF0 :: SecondByteTable+secondF0 = privateUseSecond 0xE000++-- | The multibyte characters with a lead byte of @0xF1@.+secondF1 :: SecondByteTable+secondF1 = privateUseSecond 0xE0BC++-- | The multibyte characters with a lead byte of @0xF2@.+secondF2 :: SecondByteTable+secondF2 = privateUseSecond 0xE178++-- | The multibyte characters with a lead byte of @0xF3@.+secondF3 :: SecondByteTable+secondF3 = privateUseSecond 0xE234++-- | The multibyte characters with a lead byte of @0xF4@.+secondF4 :: SecondByteTable+secondF4 = privateUseSecond 0xE2F0++-- | The multibyte characters with a lead byte of @0xF5@.+secondF5 :: SecondByteTable+secondF5 = privateUseSecond 0xE3AC++-- | The multibyte characters with a lead byte of @0xF6@.+secondF6 :: SecondByteTable+secondF6 = privateUseSecond 0xE468++-- | The multibyte characters with a lead byte of @0xF7@.+secondF7 :: SecondByteTable+secondF7 = privateUseSecond 0xE524++-- | The multibyte characters with a lead byte of @0xF8@.+secondF8 :: SecondByteTable+secondF8 = privateUseSecond 0xE5E0++-- | The multibyte characters with a lead byte of @0xF9@.+secondF9 :: SecondByteTable+secondF9 = privateUseSecond 0xE69C++-- | The multibyte characters with a lead byte of @0xFA@.+secondFA :: SecondByteTable+secondFA = V.fromList $+ {-0x40..0x49-} chars ['\x2170'..'\x2179'] +++ {-0x4A..0x53-} chars ['\x2160'..'\x2169'] +++ {-0x54-} chars "\xFFE2\xFFE4\xFF07\xFF02" +++ {-0x58-} chars "\x3231\x2116\x2121\x2235\x7E8A\x891C\x9348\x9288" +++ {-0x60-} chars "\x84DC\x4FC9\x70BB\x6631\x68C8\x92F9\x66FB\x5F45" +++ {-0x68-} chars "\x4E28\x4EE1\x4EFC\x4F00\x4F03\x4F39\x4F56\x4F92" +++ {-0x70-} chars "\x4F8A\x4F9A\x4F94\x4FCD\x5040\x5022\x4FFF\x501E" +++ {-0x78-} chars "\x5046\x5070\x5042\x5094\x50F4\x50D8\x514A" ++ Nothing :+ {-0x80-} chars "\x5164\x519D\x51BE\x51EC\x5215\x529C\x52A6\x52C0" +++ {-0x88-} chars "\x52DB\x5300\x5307\x5324\x5372\x5393\x53B2\x53DD" +++ {-0x90-} chars "\xFA0E\x549C\x548A\x54A9\x54FF\x5586\x5759\x5765" +++ {-0x98-} chars "\x57AC\x57C8\x57C7\xFA0F\xFA10\x589E\x58B2\x590B" +++ {-0xA0-} chars "\x5953\x595B\x595D\x5963\x59A4\x59BA\x5B56\x5BC0" +++ {-0xA8-} chars "\x752F\x5BD8\x5BEC\x5C1E\x5CA6\x5CBA\x5CF5\x5D27" +++ {-0xB0-} chars "\x5D53\xFA11\x5D42\x5D6D\x5DB8\x5DB9\x5DD0\x5F21" +++ {-0xB8-} chars "\x5F34\x5F67\x5FB7\x5FDE\x605D\x6085\x608A\x60DE" +++ {-0xC0-} chars "\x60D5\x6120\x60F2\x6111\x6137\x6130\x6198\x6213" +++ {-0xC8-} chars "\x62A6\x63F5\x6460\x649D\x64CE\x654E\x6600\x6615" +++ {-0xD0-} chars "\x663B\x6609\x662E\x661E\x6624\x6665\x6657\x6659" +++ {-0xD8-} chars "\xFA12\x6673\x6699\x66A0\x66B2\x66BF\x66FA\x670E" +++ {-0xE0-} chars "\xF929\x6766\x67BB\x6852\x67C0\x6801\x6844\x68CF" +++ {-0xE8-} chars "\xFA13\x6968\xFA14\x6998\x69E2\x6A30\x6A6B\x6A46" +++ {-0xF0-} chars "\x6A73\x6A7E\x6AE2\x6AE4\x6BD6\x6C3F\x6C5C\x6C86" +++ {-0xF8-} chars "\x6C6F\x6CDA\x6D04\x6D87\x6D6F"++-- | The multibyte characters with a lead byte of @0xFB@.+secondFB :: SecondByteTable+secondFB = V.fromList $+ {-0x40-} chars "\x6D96\x6DAC\x6DCF\x6DF8\x6DF2\x6DFC\x6E39\x6E5C" +++ {-0x48-} chars "\x6E27\x6E3C\x6EBF\x6F88\x6FB5\x6FF5\x7005\x7007" +++ {-0x50-} chars "\x7028\x7085\x70AB\x710F\x7104\x715C\x7146\x7147" +++ {-0x58-} chars "\xFA15\x71C1\x71FE\x72B1\x72BE\x7324\xFA16\x7377" +++ {-0x60-} chars "\x73BD\x73C9\x73D6\x73E3\x73D2\x7407\x73F5\x7426" +++ {-0x68-} chars "\x742A\x7429\x742E\x7462\x7489\x749F\x7501\x756F" +++ {-0x70-} chars "\x7682\x769C\x769E\x769B\x76A6\xFA17\x7746\x52AF" +++ {-0x78-} chars "\x7821\x784E\x7864\x787A\x7930\xFA18\xFA19" ++ Nothing :+ {-0x80-} chars "\xFA1A\x7994\xFA1B\x799B\x7AD1\x7AE7\xFA1C\x7AEB" +++ {-0x88-} chars "\x7B9E\xFA1D\x7D48\x7D5C\x7DB7\x7DA0\x7DD6\x7E52" +++ {-0x90-} chars "\x7F47\x7FA1\xFA1E\x8301\x8362\x837F\x83C7\x83F6" +++ {-0x98-} chars "\x8448\x84B4\x8553\x8559\x856B\xFA1F\x85B0\xFA20" +++ {-0xA0-} chars "\xFA21\x8807\x88F5\x8A12\x8A37\x8A79\x8AA7\x8ABE" +++ {-0xA8-} chars "\x8ADF\xFA22\x8AF6\x8B53\x8B7F\x8CF0\x8CF4\x8D12" +++ {-0xB0-} chars "\x8D76\xFA23\x8ECF\xFA24\xFA25\x9067\x90DE\xFA26" +++ {-0xB8-} chars "\x9115\x9127\x91DA\x91D7\x91DE\x91ED\x91EE\x91E4" +++ {-0xC0-} chars "\x91E5\x9206\x9210\x920A\x923A\x9240\x923C\x924E" +++ {-0xC8-} chars "\x9259\x9251\x9239\x9267\x92A7\x9277\x9278\x92E7" +++ {-0xD0-} chars "\x92D7\x92D9\x92D0\xFA27\x92D5\x92E0\x92D3\x9325" +++ {-0xD8-} chars "\x9321\x92FB\xFA28\x931E\x92FF\x931D\x9302\x9370" +++ {-0xE0-} chars "\x9357\x93A4\x93C6\x93DE\x93F8\x9431\x9445\x9448" +++ {-0xE8-} chars "\x9592\xF9DC\xFA29\x969D\x96AF\x9733\x973B\x9743" +++ {-0xF0-} chars "\x974D\x974F\x9751\x9755\x9857\x9865\xFA2A\xFA2B" +++ {-0xF8-} chars "\x9927\xFA2C\x999E\x9A4E\x9AD9"++-- | The multibyte characters with a lead byte of @0xFC@.+secondFC :: SecondByteTable+secondFC = V.fromList $+ {-0x40-} chars "\x9ADC\x9B75\x9B72\x9B8F\x9BB1\x9BBB\x9C00\x9D70" +++ {-0x48-} chars "\x9D6B\xFA2D\x9E19\x9ED1" +++ {-0x4C..0xFC-} nothings 0xB1
+ src/Foreign/Libcdio.hs view
@@ -0,0 +1,74 @@+{-|+Description: Bindings directly mirroring the C interface of libcdio.++Copyright: (c) 2018-2021 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: stable+Portability: non-portable (requires libcdio)++Modules in this tree are designed so users familiar with working with the+original libcdio should be able to write essentially the same code they're+used to, in the 'IO' monad. There have, however, been some changes made (beyond+mapping the types to ones more native to Haskell), mostly to take advantage of+the type safety. These have then been adapted further into the modules under+"Sound.Libcdio", which aim to provide much of the same functionality but in a+form the library might have taken if it had been originally written for+Haskell.++As /this/ interface does mirror the structure of the C library, each header+file is translated into a separate module, as follows. Any changes from those+original headers which might not be easily guessed are noted in the+documentation for each module, along with similar equivalencies to the+higher-level interface.++* @cdio.h@ -> "Foreign.Libcdio"+* @cd_types.h@ -> "Foreign.Libcdio.CdTypes" (not reexported by @cdio.h@, or this module)+* @cdtext.h@ -> "Foreign.Libcdio.CdText"+* @device.h@ -> "Foreign.Libcdio.Device"+* @disc.h@ -> "Foreign.Libcdio.Disc"+* @logging.h@ -> "Foreign.Libcdio.Logging" (not reexported by @cdio.h@, or this module)+* @memory.h@ (removed; the only exported symbol @cdio_free@ is encapsulated+ into the Haskell garbage collection)+* @read.h@ -> "Foreign.Libcdio.Read"+* @sector.h@ -> "Foreign.Libcdio.Sector"+* @track.h@ -> "Foreign.Libcdio.Track"+* @types.h@ -> "Foreign.Libcdio.Types"++ * The original header was an interesting collection of some (but not all)+ types used by the library. The module is both more universal by+ exporting all types in the interface, and less required as each relevant+ type is exported by the various modules themselves.++* @util.h@ -> "Foreign.Libcdio.Util" (not reexported by @cdio.h@, or this module)+* @version.h@ -> "Foreign.Libcdio.Version"+++= @cdio.h@++== Defines+* @CDIO_API_VERSION@ -> 'apiVersion' (primarily exported from "Foreign.Libcdio.Version")++== Types+* @CdIo_t@ -> 'Cdio' (primarily exported from "Foreign.Libcdio.Device")+-}+module Foreign.Libcdio+ ( module Foreign.Libcdio.CdText+ , module Foreign.Libcdio.Device+ , module Foreign.Libcdio.Disc+ , module Foreign.Libcdio.Read+ , module Foreign.Libcdio.Sector+ , module Foreign.Libcdio.Track+ , module Foreign.Libcdio.Version+ ) where+++import Foreign.Libcdio.Version+import Foreign.Libcdio.Sector++import Foreign.Libcdio.Device+import Foreign.Libcdio.CdText+import Foreign.Libcdio.Disc+import Foreign.Libcdio.Read+import Foreign.Libcdio.Track
+ src/Foreign/Libcdio/CdText.hs view
@@ -0,0 +1,310 @@+{-# LANGUAGE ForeignFunctionInterface #-}++{-|+Description: Functions and types providing metadata about the disc contents.++Copyright: (c) 2018-2021 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: stable+Portability: non-portable (requires libcdio)++Metadata is stored in a binary format both library-internally and on the disc.+Most audio archivists will recognize it as "those information fields in a CUE+file" (though there are [other+formats](https://www.gnu.org/software/libcdio/cd-text-format.html#Sony-Text-File-Format-_0028Input-Sheet-Version-0_002e7T_0029)+as well), and casual listeners will recognize it as the scrolling text that+you're always happy to see, on the rare times your music player shows it.+Little-used and even-less-known, however, is that a single disc can+theoretically contain metadata in up to eight different languages; because of+the complexity that introduces, no unifying datatype is provided in favour of a+function-based interface.+++= @cdtext.h@++== Defines+* @MIN_CDTEXT_FIELD@ (removed; identical to @'minBound' :: 'Field'@)+* @MAX_CDTEXT_FIELD@ (removed; identical to @'maxBound' :: 'Field'@)++== Types+* @cdtext_field_t@ -> 'Field'++ - @CDTEXT_FIELD_INVALID@ (removed; handled via 'Nothing')++* @cdtext_genre_t@ -> 'Genre'++ - @CDTEXT_GENRE_UNUSED@ (removed; handled via 'Nothing')++* @cdtext_lang_t@ -> 'Language'++ - @CDTEXT_LANGUAGE_UNKNOWN@ -> 'UnknownLanguage'++ - /Before libcdio 2.1.0: (often effectively removed; handled via 'Nothing')/++ - @CDTEXT_LANGUAGE_INVALID@ (removed; handled via 'Nothing')+ - @CDTEXT_LANGUAGE_BLOCK_UNUSED@ (removed; handled via 'Nothing')++* @cdtext_t@ (removed; merged into 'Cdio' objects)++== Symbols+* @cdtext_data_init@ -> 'cdTextDataInit'+* @cdtext_destroy@ (removed; handled via the garbage collector)+* @cdtext_field2str@ -> 'fieldString'+* @cdtext_genre2str@ -> 'genreString'+* @cdtext_get@ (removed; type conversion makes it identical to @cdtext_get_const@)+* @cdtext_get_const@ -> 'cdTextGet'+* @cdtext_get_first_track@ -> 'firstTrack'+* @cdtext_get_genre@ -> 'genre'+* @cdtext_get_language@ -> 'language'+* @cdtext_get_last_track@ -> 'lastTrack'+* @cdtext_init@ (removed; internal function without much external occasion)+* @cdtext_lang2str@ -> 'languageString'+* @cdtext_list_languages@ -> 'listLanguages'+* @cdtext_list_languages_v2@ -> 'listAllLanguages'+* @cdtext_select_language@ -> 'selectLanguage'+* @cdtext_set@ (removed; primarily intended for internal use, and is more limited than would be expected)+* @cdtext_set_language_index@ -> 'selectLanguageIndex'+* @cdtext_str2lang@ -> 'parseLanguage'+++= "Sound.Libcdio.Read.CdText"+While similar functionality is provided, the+@"Sound.Libcdio.Read".'Sound.Libcdio.Read.CdText'@ is written as a separate+monadic interface rather than in the 'Cdio'-bound style used here.++* 'cdTextDataInit' -> 'Sound.Libcdio.Read.CdText.parseCdText'+* 'cdTextGet' -> 'Sound.Libcdio.Read.CdText.discId', @'snd' 'Sound.Libcdio.Read.CdText.genre'@, and 'Sound.Libcdio.Read.CdText.info'+* 'genre' -> @'fst' 'Sound.Libcdio.Read.CdText.genre'@+* 'listAllLanguages' -> 'Sound.Libcdio.Read.CdText.languages'+* 'listLanguages' (removed; obsolete and imprecise)+* 'selectLanguage' -> 'Sound.Libcdio.Read.CdText.withLanguage'+* 'selectLanguageIndex' -> 'Sound.Libcdio.Read.CdText.withIndex'+-}+module Foreign.Libcdio.CdText+ ( -- * Types+ Cdio+ , Field ( .. )+ , Genre ( .. )+ , Language ( .. )+ -- * Description+ , fieldString+ , languageString+ , parseLanguage+ , genreString+ -- * Management+ , cdTextDataInit+ , listLanguages+ , listAllLanguages+ , selectLanguage+ , selectLanguageIndex+ -- * Access+ , cdTextGet+ , genre+ , language+ , firstTrack+ , lastTrack+ ) where+++import qualified Data.List as L+import qualified Data.Maybe as Y++import qualified Foreign.C.String as C+import qualified Foreign.C.Types as C+import qualified Foreign.Ptr as C++import qualified Foreign.Marshal.Array as M+import qualified Foreign.Marshal.Utils as M++import qualified System.IO.Unsafe as IO.Unsafe++import Foreign.Libcdio.Device+import Foreign.Libcdio.Marshal+import Foreign.Libcdio.Track+import Foreign.Libcdio.Types.Enums+import Foreign.Libcdio.Types.Internal+import Foreign.Libcdio.Version++import Sound.Libcdio.Common+++-- | Return a canonical English name of the given genre, as opposed to the+-- machine representation returned by the 'Show' instance.+genreString :: Genre -> String+genreString = IO.Unsafe.unsafePerformIO .+ C.peekCString . genreString' . fromIntegral . fromEnum++foreign import ccall safe "cdio/compat/cdtext.h cdtext_genre2str"+ genreString' :: CGenre -> C.CString++-- | Return a canonical English name of the given language, as opposed to the+-- machine representation returned by the 'Show' instance.+languageString :: Language -> String+languageString = IO.Unsafe.unsafePerformIO .+ C.peekCString . languageString' . fromIntegral . fromEnum++foreign import ccall safe "cdio/compat/cdtext.h cdtext_lang2str"+ languageString' :: CLanguage -> C.CString++-- | Transform a string returned by 'languageString' back into its+-- 'Language' representation.+-- +-- /Before libcdio 2.1.0: Always returns 'Nothing'/+parseLanguage :: String -> Maybe Language+parseLanguage s+ | libcdioVersionNum >= makeVersion [2,1] = IO.Unsafe.unsafePerformIO $ do+ i <- C.withCString s parseLanguage'+ return . fmap (toEnum . fromIntegral) $ maybeError [languageInvalid, languageUnused] i+ | otherwise = Nothing++foreign import ccall safe "cdio/compat/cdtext.h cdtext_str2lang_safe"+ parseLanguage' :: C.CString -> IO CLanguage++foreign import ccall safe "cdio/compat/cdtext.h language_unknown"+ languageUnknown :: CLanguage++foreign import ccall safe "cdio/compat/cdtext.h language_invalid"+ languageInvalid :: CLanguage++foreign import ccall safe "cdio/compat/cdtext.h language_unused"+ languageUnused :: CLanguage++-- | Describe the type of data in a human-readable manner, as opposed to the+-- machine representation returned by the 'Show' instance.+fieldString :: Field -> String+fieldString = IO.Unsafe.unsafePerformIO .+ C.peekCString . fieldString' . fromIntegral . fromEnum++foreign import ccall safe "cdio/compat/cdtext.h cdtext_field2str"+ fieldString' :: CField -> C.CString+++-- | Attempt to retrieve the value of a given field from the disc (if+-- 'Nothing') or track (if 'Just') metadata, in the currently-active language.+-- Note that 'GenreName' and 'DiscId' will /always/ refer to the disc-level+-- data.+cdTextGet :: Cdio -> Field -> Maybe Track -> IO (Maybe String)+cdTextGet _ _ (Just DiscPregap) = return Nothing+cdTextGet _ _ (Just DiscLeadout) = return Nothing+cdTextGet c GenreName _ = cdTextGet_ c GenreName 0+cdTextGet c DiscId _ = cdTextGet_ c DiscId 0+cdTextGet c f Nothing = cdTextGet_ c f 0+cdTextGet c f (Just t) = cdTextGet_ c f t++cdTextGet_ :: Cdio -> Field -> Track -> IO (Maybe String)+cdTextGet_ c f t = withCdText' Nothing c $ \x ->+ cdTextGet' x (fromIntegral $ fromEnum f) (fromIntegral $ fromEnum t) >>= M.maybePeek C.peekCString++foreign import ccall safe "cdio/compat/cdtext.h cdtext_get_const"+ cdTextGet' :: C.Ptr CdText -> CField -> CTrack -> IO C.CString+++-- | The machine-readable genre describing the music on this disc. For any+-- associated human-readable name or subgenre, use @'cdTextGet' c 'GenreName'+-- 'Nothing'@.+genre :: Cdio -> IO (Maybe Genre)+genre c = do+ g <- withCdText c genre'+ return $ if g == Just 0 then Nothing else toEnum . fromIntegral <$> g++foreign import ccall safe "cdio/compat/cdtext.h cdtext_get_genre"+ genre' :: C.Ptr CdText -> IO CGenre++-- | Indicate which language results will (currently) be returned in. See+-- 'selectLanguage' to change this.+language :: Cdio -> IO (Maybe Language)+language c = fmap (toEnum . fromIntegral) <$> withCdText c language'++foreign import ccall safe "cdio/compat/cdtext.h cdtext_get_language"+ language' :: C.Ptr CdText -> IO CLanguage+++-- | The earliest track with any associated metadata in the current language.+-- Note that this may differ from 'minTrack'.+firstTrack :: Cdio -> IO (Maybe Track)+firstTrack c = fmap (toEnum . fromIntegral) . maybeError [0] <$> withCdText' 0 c firstTrack'++foreign import ccall safe "cdio/compat/cdtext.h cdtext_get_first_track"+ firstTrack' :: C.Ptr CdText -> IO CTrack++-- | The final track with any associated metadata in the current language.+-- Note that this may differ from 'maxTrack'.+lastTrack :: Cdio -> IO (Maybe Track)+lastTrack c = fmap (toEnum . fromIntegral) . maybeError [0] <$> withCdText' 0 c lastTrack'++foreign import ccall safe "cdio/compat/cdtext.h cdtext_get_last_track"+ lastTrack' :: C.Ptr CdText -> IO CTrack+++-- | Try to set the data associated with the given language as active for+-- future calls to 'cdTextGet' and similar. If passed 'UnknownLanguage' or the+-- CDTEXT does not provide the one requested, selects the first (default) data+-- set instead, and returns 'False'.+selectLanguage :: Cdio -> Language -> IO Bool+selectLanguage c l = fmap M.toBool . withCdText' 0 c $ \x ->+ selectLanguage' x . fromIntegral $ fromEnum l++foreign import ccall safe "cdio/compat/cdtext.h cdtext_select_language"+ selectLanguage' :: C.Ptr CdText -> CLanguage -> IO CBool++-- | Retrieve the languages included in the disc metadata. Note that this does+-- not save the index position or any duplicate language blocks (if that is+-- desired, see 'listAllLanguages' instead).+listLanguages :: Cdio -> IO [Language]+listLanguages c = withCdText' [] c $ \x -> do+ l' <- listLanguages' x+ ls <- peekLanguages l' [languageUnknown, languageInvalid, languageUnused]+ return . L.nub $ Y.catMaybes ls++foreign import ccall safe "cdio/compat/cdtext.h cdtext_list_languages"+ listLanguages' :: C.Ptr CdText -> IO (C.Ptr CLanguage)++-- | Retrieve the languages included in the disc metadata, in the order they+-- occur, and respecting any empty language blocks if there's a valid language+-- after them (empty blocks at the end are cleaned away).+-- +-- /Before libcdio 2.1.0: Acts as 'listLanguages'/+listAllLanguages :: Cdio -> IO [Maybe Language]+listAllLanguages c = withCdText' [] c $ \x -> do+ l' <- listAllLanguages' x+ ls <- peekLanguages l' [languageInvalid, languageUnused]+ return $ case L.dropWhileEnd Y.isNothing ls of+ [] -> [Just UnknownLanguage]+ ls' -> ls'++foreign import ccall safe "cdio/compat/cdtext.h cdtext_list_languages_v2_safe"+ listAllLanguages' :: C.Ptr CdText -> IO (C.Ptr CLanguage)++peekLanguages :: C.Ptr CLanguage -> [CLanguage] -> IO [Maybe Language]+peekLanguages p es+ | p == C.nullPtr = return []+ | otherwise = map (fmap (toEnum . fromIntegral) . maybeError es) <$> M.peekArray 8 p++-- | Select the language at the given index of 'listAllLanguages' for future+-- data retrieval. If the index is out of bounds or corresponds to a 'Nothing'+-- in 'listAllLanguages', the first (default) data set is selected instead and+-- 'False is returned.+selectLanguageIndex :: Cdio -> Word -> IO Bool+selectLanguageIndex c i = M.toBool <$> withCdText' 0 c (flip selectLanguageIndex' $ fromIntegral i)++foreign import ccall safe "cdio/compat/cdtext.h cdtext_set_language_index_safe"+ selectLanguageIndex' :: C.Ptr CdText -> C.CInt -> IO CBool+++{- Primarily intended as an internal function+-- | Set the given field at the given track to the given value.+cdTextSet :: Cdio -> Field -> Maybe String -> Maybe Track -> IO ()+cdTextSet _ _ _ (Just DiscPregap) = mempty+cdTextSet _ _ _ (Just DiscLeadout) = mempty+cdTextSet c f v Nothing = cdTextSet_ c f v 0+cdTextSet c f v (Just t) = cdTextSet_ c f v t++cdTextSet_ :: Cdio -> Field -> Maybe String -> Track -> IO ()+cdTextSet_ c f v t = withCdText_ c $ \x -> M.maybeWith C.withCString v $ \s ->+ cdTextSet' x (toCEnum f) s (withTrack t) C.nullPtr++foreign import ccall safe "cdio/compat/cdtext.h cdtext_set"+ cdTextSet' :: C.Ptr CdText -> CField -> C.CString -> CTrack -> C.CString -> IO ()+-}
+ src/Foreign/Libcdio/CdText/Binary.hs view
@@ -0,0 +1,409 @@+{-# LANGUAGE OverloadedStrings #-}+{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}+{-# OPTIONS_GHC -Wno-unused-imports #-}++{-|+Description: ++Copyright: (c) 2020-2021 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: stable+Portability: non-portable (requires libcdio)+-}+module Foreign.Libcdio.CdText.Binary+ ( Info ( .. )+ , emptyCdTextRaw+ , packCdTextBlock+ , joinBlockInfo+ , checksum+ ) where+++import qualified Data.Bits as B+import qualified Data.Bifunctor as F.B+import qualified Data.ByteString as BS+import qualified Data.ByteString.Char8 as BS.C+import qualified Data.Char as C+import qualified Data.List as L+import qualified Data.Maybe as Y+import qualified Data.Word as W++import qualified Data.Text as T+import qualified Data.Text.Encoding.Error as T+import qualified Data.Text.Encoding.MsJIS as T++import Data.Bits ( (.&.), (.|.) )++import Foreign.Libcdio.Track+import Foreign.Libcdio.Types.Enums++import Sound.Libcdio.Common+++type TrackId = W.Word8+type PackType = W.Word8+type BlockId = Word+type BlockSize = W.Word8+++-- | Textual data used for describing tracks on a disc (as well as the disc+-- itself).+data Info = Info+ { title :: Maybe String+ , performer :: Maybe String+ , songwriter :: Maybe String+ , composer :: Maybe String+ , arranger :: Maybe String+ , message :: Maybe String+ , code :: Maybe String+ }+ deriving ( Eq, Show, Read )+++emptyCdTextRaw :: [Maybe Language] -> BS.ByteString+emptyCdTextRaw [] = emptyCdTextRaw [Nothing]+emptyCdTextRaw ls =+ BS.concat . concat . flip map (zip [0..] ls) $ \(i, _) -> map checksum .+ joinBlockInfo ls [3 | _ <- ls] .+ generateBlockInfo i Iso8859_1 0 0 $+ replicate 15 0 ++ [3]+++data Encoding+ = Iso8859_1+ | ASCII+ | MS_JIS+ deriving ( Eq, Ord, Bounded, Show, Read )+instance Enum Encoding where+ toEnum 0x00 = Iso8859_1+ toEnum 0x01 = ASCII+ toEnum 0x80 = MS_JIS+ toEnum _ = ASCII+ fromEnum Iso8859_1 = 0x00+ fromEnum ASCII = 0x01+ fromEnum MS_JIS = 0x80++data Pack+ = TitlePack+ | PerformerPack+ | SongwriterPack+ | ComposerPack+ | ArrangerPack+ | MessagePack+ | DiscIdPack+ | GenrePack+ | TocPack+ | Toc2Pack+ | ClosedPack+ | CodePack+ | InfoPack+ deriving ( Eq, Ord, Bounded, Enum, Show, Read )+++-- | Generate the binary data representing a CDTEXT language block.+packCdTextBlock+ :: BlockId+ -> Maybe String+ -> Track+ -> Maybe Genre+ -> Maybe String+ -> Info+ -> [Info]+ -> [BS.ByteString]+packCdTextBlock blockIndex catalogue startTrack@(Track _) genreCode genreName disc tracks =+ allPacks <> generateBlockInfo blockIndex encoding startTrackId endTrackId allLengths+ where (titles, tt) = text title TitlePack (0 :: Int)+ (performers, tp) = text performer PerformerPack ip+ (songwriters, ts) = text songwriter SongwriterPack is+ (composers, tc) = text composer ComposerPack ic+ (arrangers, ta) = text arranger ArrangerPack ia+ (messages, tm) = text message MessagePack im+ (catalogueB, _) = pack' DiscIdPack False il (prepareSingleText ASCII catalogue, 0 :: Int)+ (genreB, _) = pack' GenrePack False ig (prepareGenre genreCode genreName, 0 :: Int)+ -- (tocB, _) = pack' TocPack False it _+ -- (toc2B, ) = pack' Toc2Pack False i2 _+ -- (closedB, ) = pack' ClosedPack False ix $ prepareSingleText Iso8859_1 _+ (codes, to) = pack' CodePack False io $ prepareText' ASCII code+ lt = length titles+ (ip, lp) = ( lt, length performers)+ (is, ls) = (ip + lp, length songwriters)+ (ic, lc) = (is + ls, length composers)+ (ia, la) = (ic + lc, length arrangers)+ (im, lm) = (ia + la, length messages)+ (il, ll) = (im + lm, length catalogueB)+ (ig, lg) = (il + ll, length genreB)+ (io, lo) = (ig + lg, length codes)+ allLengths = reverse . (3 :) . snd $ L.foldl'+ (\(acc, as) a -> if acc + a > 0xFC then (0xFC, (0xFC - acc) : as) else (acc + a, a : as))+ (0, [])+ [lt, lp, ls, lc, la, lm, ll, lg, 0, 0, 0, 0, 0, 0, lo]+ allPacks = take 0xFC+ $ titles+ <> performers+ <> songwriters+ <> composers+ <> arrangers+ <> messages+ <> catalogueB+ <> genreB+ <> codes+ encoding = guessEncoding . Y.catMaybes . concat $ infoList disc : map infoList tracks+ wideChars = encoding == MS_JIS+ infoList i = [f i | f <- [title, performer, songwriter, composer, arranger, message, code]]+ startTrackId = fromIntegral $ fromEnum startTrack+ endTrackId = foldr max 0 [tt, tp, ts, tc, ta, tm, to]+ text f p i = F.B.first (pack p wideChars blockIndex $ fromIntegral i) $+ prepareText' encoding f+ prepareSingleText _ Nothing = []+ prepareSingleText e (Just t) = (\t' -> [(0, t')]) $ encodeText e t+ prepareText' e f = (t', foldr (max . fst) 0 t')+ where t' = prepareText e startTrackId (f disc) (map f tracks)+ pack' p w i = F.B.first . pack p w blockIndex $ fromIntegral i+packCdTextBlock blockIndex catalogue DiscPregap genreCode genreName _ tracks =+ packCdTextBlock blockIndex catalogue 1 genreCode genreName disc tracks'+ where (disc, tracks') = case tracks of+ [] -> (Info Nothing Nothing Nothing Nothing Nothing Nothing Nothing, [])+ (t:ts) -> (t, ts)+packCdTextBlock blockIndex catalogue DiscLeadout genreCode genreName disc _ =+ packCdTextBlock blockIndex catalogue 1 genreCode genreName disc []++-- | Generate the local block info. Note that this does /not/ result in full+-- payloads for the last two packs; @packInfo@ adds them automatically.+generateBlockInfo :: BlockId -> Encoding -> TrackId -> TrackId -> [Int] -> [BS.ByteString]+generateBlockInfo blockIndex encoding startTrack endTrack lengths =+ pack InfoPack False blockIndex (fromIntegral $ sum lengths - 3) . packTuple $+ [fromIntegral $ fromEnum encoding, startTrack, endTrack, 0x00] +++ take 16 (map fromIntegral lengths ++ repeat 0)+ where packTuple bs = [(0, BS.pack bs)]+++-- | Use the minimal encoding based on the characters used by the strings. If+-- any character outside ISO 8859-1 ("Latin-1") is found, 'MS_JIS' is used as a+-- fallback; this isn't strictly comprehensive, but it is a lot harder to test+-- for (i.e. I'd have to write a function for it).+guessEncoding :: [String] -> Encoding+guessEncoding [] = Iso8859_1+guessEncoding ts+ | all (all C.isAscii) ts = ASCII+ | all (all C.isLatin1) ts = Iso8859_1+ | otherwise = MS_JIS+++-- | Collapse the track texts to their minimal size if allowed (if present for+-- disc-level info, all tracks must be represented).+prepareText :: Encoding -> TrackId -> Maybe String -> [Maybe String] -> [(TrackId, BS.ByteString)]+prepareText e _ (Just d) [] = [(0, encodeText e d)]+prepareText e i d'@(Just d) ta@(t:_)+ | d' == t = case prepareTrackTexts e i' $ d' : trim ta of+ [] -> []+ ((_, bs):bss) -> (0, bs) : bss+ | otherwise = (0, encodeText e d) : uncurry (prepareTrackTexts e) (trimTexts i ta)+ where trim = L.dropWhileEnd Y.isNothing . dropWhile Y.isNothing+ i' = i - 1 + fromIntegral (length $ takeWhile Y.isNothing ta)+{- This block forces track info if it's present for the disc, as required by+ - the libcdio docs. It doesn't look like that's actually required in these+ - references, but I don't trust them enough to take it out entirely.+prepareText e i d'@(Just d) ta@(t:_)+ | d' == t = case prepareTrackTexts e (i - 1) $ d' : ta of+ [] -> []+ ((_, bs):bss) -> (0, bs) : bss+ | otherwise = (0, encodeText e d) : prepareTrackTexts e i ta+-}+prepareText e i Nothing ts = uncurry (prepareTrackTexts e) $ trimTexts i ts++trimTexts :: TrackId -> [Maybe String] -> (TrackId, [Maybe String])+trimTexts i' [] = (i', [])+trimTexts i' (Nothing:ts') = trimTexts (i' + 1) ts'+trimTexts i' ts' = (i', L.dropWhileEnd Y.isNothing ts')++-- | Collapse the texts further by making use of the tab-replacement shortcut+-- for repeated values.+prepareTrackTexts :: Encoding -> TrackId -> [Maybe String] -> [(TrackId, BS.ByteString)]+prepareTrackTexts _ _ [] = []+prepareTrackTexts e i ts = encodeTrackTexts e i . reverse $ L.foldl' deduplicate [] ts+ where deduplicate [] (Just s) = [s]+ deduplicate ts' Nothing = "" : ts'+ deduplicate ts' (Just s) =+ let ss = takeWhile (== s) ts'+ in s : map (const "\t") ss ++ deduplicate' (drop (length ss) ts')+ deduplicate' [] = []+ deduplicate' (t':ts') = deduplicate ts' $ Just t'++-- | Combine the genre code and description into a single bytestring.+prepareGenre :: Maybe Genre -> Maybe String -> [(TrackId, BS.ByteString)]+prepareGenre Nothing Nothing = []+prepareGenre gc gt = [(0, encodeGenre gc <> encodeText ASCII (Y.fromMaybe "" gt))]+++-- | Conduct text to the proper encoder and append the proper terminator.+encodeText :: Encoding -> String -> BS.ByteString+encodeText MS_JIS "\t" = BS.pack [0x09,0x09,0x00,0x00]+encodeText ASCII t = BS.map (.&. 0x7F) $ encodeText Iso8859_1 t+encodeText Iso8859_1 t = BS.C.pack $ t ++ ['\NUL']+encodeText MS_JIS t = T.encodeMsJISWith T.ignore (T.pack t) <> BS.C.pack ['\NUL', '\NUL']++-- | Encode all members of a given textual category, pairing them with their+-- track index or 0 if one applies to the disc as a whole.+encodeTrackTexts :: Encoding -> TrackId -> [String] -> [(TrackId, BS.ByteString)]+encodeTrackTexts e i ts = zip [i ..] $ map (encodeText e) ts++-- | Store the genre code in a two-byte string.+encodeGenre :: Maybe Genre -> BS.ByteString+encodeGenre g = BS.pack [gh, gc]+ where gc = maybe 0x00 (fromIntegral . fromEnum) g+ -- Futureproofing decades-old technology+ gh = if gc <= 0xFF then 0x00 else B.shiftR gc 8+++-- | Prevent index overflow for any single pack type.+pack :: Pack -> Bool -> BlockId -> BlockSize -> [(TrackId, BS.ByteString)] -> [BS.ByteString]+pack p w b i bss = take 0xFF $ pack_ p w b i bss++-- | Conduct binary data and starting track to the proper packers.+pack_ :: Pack -> Bool -> BlockId -> BlockSize -> [(TrackId, BS.ByteString)] -> [BS.ByteString]+pack_ TitlePack = packText 0x80+pack_ PerformerPack = packText 0x81+pack_ SongwriterPack = packText 0x82+pack_ ComposerPack = packText 0x83+pack_ ArrangerPack = packText 0x84+pack_ MessagePack = packText 0x85+pack_ DiscIdPack = packText 0x86+pack_ GenrePack = packGenre+pack_ ClosedPack = packText 0x8D+pack_ TocPack = const4 []+pack_ Toc2Pack = const4 []+pack_ CodePack = packText 0x8E+pack_ InfoPack = packBlockInfo++const4 :: a -> b -> c -> d -> e -> a+const4 a _ _ _ _ = a++packText+ :: PackType+ -> Bool+ -> BlockId+ -> BlockSize+ -> [(TrackId, BS.ByteString)] -> [BS.ByteString]+packText p w b i bss = zipWith (curry $ addHeader p w b) [i ..] .+ reverse $ L.foldl' splitText [] bss++packGenre :: Bool -> BlockId -> BlockSize -> [(TrackId, BS.ByteString)] -> [BS.ByteString]+packGenre _ _ _ [] = []+packGenre w b i ((_, bs):_) = zipWith (curry $ addHeader 0x87 w b) [i ..] $ splitGenre bs++-- | Create the skeleton block info packs, leaving out counts and languages.+packBlockInfo :: Bool -> BlockId -> BlockSize -> [(TrackId, BS.ByteString)] -> [BS.ByteString]+packBlockInfo w b i [] =+ [ addHeader 0x8F w b (i + p, (p, 0, BS.empty))+ | p <- [0 .. 2]+ ]+packBlockInfo w b i ((_, bs):_) =+ [ addHeader 0x8F w b (i, (0, 0, p1))+ , addHeader 0x8F w b (i + 1, (1, 0, p2))+ , addHeader 0x8F w b (i + 2, (2, 0, BS.empty))+ ]+ where (p1, p2) = BS.splitAt 12 bs++-- | Generate the four-byte identifying and metadata-carrying header.+-- +-- NOTE: While the libcdio documentation on the CDTEXT format says that byte 3+-- (@l'@) is 15 if the text starts at any point before the previous pack,+-- that's not the case in any of my (admittedly limited and unverified)+-- reference blobs: it's capped at 15, yes, but if one pack has two characters,+-- the next has the full twelve, and the text still continues into a third,+-- that third will have a third byte of 14.+addHeader+ :: PackType+ -- ^ Pack type+ -> Bool+ -- ^ Two-byte characters?+ -> BlockId+ -- ^ Language index+ -> (BlockSize, (TrackId, Word, BS.ByteString))+ -- ^ Starting pack index, track number, characters in previous block, and payload+ -> BS.ByteString+addHeader p w b (i, (t, l, bs)) = BS.pack [p, t, i, f] <> bs+ where l' = if l > 15 then 0x0F else 0x0F .&. fromIntegral l+ b' = 0x70 .&. B.shiftL (fromIntegral b) 4+ w' = if w then 0x80 else 0x00+ f = w' .|. b' .|. l'++-- | Takes tuples of (track index, track data) and adds them (initial track,+-- initial length in previous packs, packed data), where the packed data is+-- /no more than/ 12 bytes long. Note that the final list will have to be+-- 'reverse'd.+splitText :: [(TrackId, Word, BS.ByteString)] -> (TrackId, BS.ByteString) -> [(TrackId, Word, BS.ByteString)]+splitText [] bst@(t, _) = splitText [(t, 0, BS.empty)] bst+splitText csa@((u, l, cs):css) (t, bs)+ | cl == 12 =+ [ (t, l', bs')+ | (l', bs') <- reverse . zip [0, 12 ..] $ splitAtEvery 12 bs+ ] ++ csa+ -- Will have incorrect t, l' if @BS.length cs > 12@, but as that shouldn't+ -- happen anyway, it's not an issue.+ | otherwise =+ let (cs':bss) = splitAtEvery 12 $ cs <> bs+ in [ (t, l', bs')+ | (l', bs') <- reverse $ zip [(12 - cl), (24 - cl) ..] bss+ ] ++ (u, l, cs') : css+ where cl = fromIntegral $ BS.length cs++-- | Takes the genre string prefixed by a single, two-byte genre code+-- identifier, splits the string, and prepends the code to every pack.+splitGenre :: BS.ByteString -> [(TrackId, Word, BS.ByteString)]+splitGenre bs =+ [ (0, l', gc <> bs')+ | (l', bs') <- zip [0, 10 ..] . splitAtEvery 10 $ BS.drop 2 bs+ ]+ where gc = BS.take 2 bs++-- | Extend the builtin 'BS.splitAt' to return an entire list of substrings.+splitAtEvery :: Int -> BS.ByteString -> [BS.ByteString]+splitAtEvery i bs+ | i <= 0 = []+ | i >= BS.length bs = [bs]+ | otherwise = recurse $ BS.splitAt i bs+ where recurse (h, t) = h : splitAtEvery i t+++-- | Now that we have the languages and sizes of all blocks, update the info+-- packs to include them. Note that this requires that the info packs are+-- located at the end of the block.+joinBlockInfo :: [Maybe Language] -> [BlockSize] -> [BS.ByteString] -> [BS.ByteString]+joinBlockInfo _ _ [] = []+joinBlockInfo _ _ [b] = [b]+joinBlockInfo ls ss bss = h ++ [p2, p3]+ where (h, t) = splitAt (length bss - 2) bss+ ls' = take 8 $ map (maybe 0 $ fromIntegral . fromEnum) ls ++ repeat 0+ ss' = take 8 $ ss ++ repeat 0+ p2 = head t <> BS.pack (take 4 ss')+ p3 = head (tail t) <> BS.pack (drop 4 ss' ++ ls')+++-- | Generate a checksum over the first 16 (including header) bytes of a data+-- pack, zero-padding /or truncating/ as necessary.+checksum :: BS.ByteString -> BS.ByteString+checksum bs = checksum' $ case compare 16 $ BS.length bs of+ GT -> BS.take 16 $ bs <> BS.replicate 16 0+ EQ -> bs+ LT -> BS.take 16 bs++-- | Actually run the checksum function on all the bytes of the input. Note+-- that this doesn't verify that the length is actually the proper 16.+checksum' :: BS.ByteString -> BS.ByteString+checksum' bs = bs <> (BS.pack . split . finalize . BS.foldl' checksumBytes h' $ t <> BS.singleton 0)+ where split i = map fromIntegral [B.shiftR i 8, i]+ finalize i = B.xor i 0xFFFF+ (h, t) = Y.fromMaybe (0, BS.empty) $ BS.uncons bs+ h' = B.shiftL (fromIntegral h) 8++checksumBytes :: W.Word16 -> W.Word8 -> W.Word16+checksumBytes acc a = checksumBits 8 . B.xor acc $ fromIntegral a++checksumBits :: Word -> W.Word16 -> W.Word16+checksumBits 0 i = i+checksumBits c i = checksumBits (c - 1) i'+ where i' | B.testBit i 15 = B.xor 0x1021 $ B.shiftL i 1+ | otherwise = B.shiftL i 1
+ src/Foreign/Libcdio/CdTypes.hs view
@@ -0,0 +1,193 @@+{-# LANGUAGE ForeignFunctionInterface #-}++{-|+Description: Objects used to describe the CD and filesystem format.++Copyright: (c) 2019-2021 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: stable+Portability: non-portable (requires libcdio)++Like any drive, discs may store their data according to many different+filesystem structures. These are abstracted to a degree in libcdio, but as+each track may store its data differently, and at the very least 'Audio' is+handled differently than any of the file-oriented layouts, it is still helpful+to know the underlying structure.+++= @cd_types.h@++== Defines+* CDIO_FSTYPE (removed; cdio_fs_anal_t represented differently in Haskell)+* CDIO_FS_UNKNOWN (removed; handled via 'Nothing')++== Types+* @cdio_fs_t@ -> 'Foreign.Libcdio.CdTypes.Filesystem'++ - @CDIO_FS_INTERACTIVE@ -> 'Foreign.Libcdio.CdTypes.CdI'+ - @CDIO_FS_ISO_HFS@ -> 'Foreign.Libcdio.CdTypes.Hfs' with a 'Just' 'Foreign.Libcdio.CdTypes.IsoAnalysis'+ - @CDIO_FS_ISO_9660_INTERACTIVE@ -> 'Foreign.Libcdio.CdTypes.CdI' with a 'Just' 'Foreign.Libcdio.CdTypes.IsoAnalysis'+ - @CDIO_FS_ISO_UDF@ -> 'Foreign.Libcdio.CdTypes.Udf' with a 'Just' 'Foreign.Libcdio.CdTypes.IsoAnalysis'+ - @CDIO_FS_ISO_XISO@ -> 'Foreign.Libcdio.CdTypes.XboxIso'+ - @CDIO_FS_ISO_UDFX@ -> 'Foreign.Libcdio.CdTypes.XboxUdf'++* @cdio_fs_cap_t@ -> 'Foreign.Libcdio.CdTypes.FilesystemClass'++ Note that some values are not included in the Haskell type, as the indexing+ implementation is stricter than the equivalent bit operations in C.++ - @CDIO_FS_MASK@ (removed; cdio_fs_anal_t represented differently in Haskell)+ - @CDIO_FS_ANAL_VCD_ANY@ -> 'Foreign.Libcdio.CdTypes.fsAnyVcd'+ - @CDIO_FS_MATCH_ALL@ -> 'Foreign.Libcdio.CdTypes.fsAny'+ - @CDIO_FS_ANAL_CDTV@ -> 'Foreign.Libcdio.CdTypes.CommodoreCdtv'+ - @CDIO_FS_ANAL_SVCD@ -> 'Foreign.Libcdio.CdTypes.SuperVideoCd'+ - @CDIO_FS_ANAL_CVD@ -> 'Foreign.Libcdio.CdTypes.ChoijiVideoCd'+ - @CDIO_FS_ANAL_XISO@ -> 'Foreign.Libcdio.CdTypes.XboxIsoClass'++* @cdio_iso_analysis_t@ -> 'Foreign.Libcdio.CdTypes.IsoAnalysis'++ - @joliet_level@ -> 'Foreign.Libcdio.CdTypes.jolietLevel'+ - @iso_label@ -> 'Foreign.Libcdio.CdTypes.label'+ - @isofs_size@ -> 'Foreign.Libcdio.CdTypes.fsSize'+ - @UDFVerMajor@ -> 'fst' 'Foreign.Libcdio.CdTypes.udfVersion'+ - @UDFVerMinor@ -> 'snd' 'Foreign.Libcdio.CdTypes.udfVersion'++== Symbols+* @cdio_guess_cd_type@ -> 'Foreign.Libcdio.CdTypes.trackType'+++= "Sound.Libcdio.Read.Filesystem"++* 'trackType' -> 'Sound.Libcdio.Read.Filesystem.filesystemType'+-}+module Foreign.Libcdio.CdTypes+ ( -- * Types+ Filesystem ( .. )+ , FilesystemClass ( .. )+ , FilesystemClasses+ , fsAny, fsAnyVcd+ , IsoAnalysis ( .. )+ -- * Access+ , trackType+ ) where+++import qualified Data.Maybe as Y+import qualified Data.Word as W++import qualified Data.Array.BitArray as A++import qualified Foreign.C.String as C+import qualified Foreign.C.Types as C+import qualified Foreign.Ptr as C++import qualified Foreign.Marshal.Alloc as M+import qualified Foreign.Storable as S++import Foreign.Libcdio.Marshal+import Foreign.Libcdio.Track+import Foreign.Libcdio.Types.Enums+import Foreign.Libcdio.Types.Offsets+import Foreign.Libcdio.Types.Internal+++-- | Types of filesystem which may be read from a disc.+data Filesystem+ = Audio+ | HighSierra+ | Iso9660+ | CdI+ | Cd3do+ | Ext2+ | Hfs+ | Ufs+ | Udf+ | XboxIso+ | XboxUdf+ deriving ( Eq, Show, Read, Ord, Enum, Bounded )+++-- | A collection of disc/filesystem descriptions.+type FilesystemClasses = A.BitArray FilesystemClass++-- | Any sort of Video CD.+fsAnyVcd :: FilesystemClasses+fsAnyVcd = genBitArray+ [ VideoCd+ , SuperVideoCd+ , ChoijiVideoCd+ ]++-- | The set of every 'FilesystemClass'.+fsAny :: FilesystemClasses+fsAny = genBitArray [minBound .. maxBound]+++-- | A collection of data describing a disc using the ISO 9660 standard.+data IsoAnalysis = IsoAnalysis+ { jolietLevel :: Maybe Word+ , label :: String+ , fsSize :: Word+ , udfVersion :: Maybe (W.Word8, W.Word8)+ }+ deriving ( Eq, Show, Read )+instance S.Storable IsoAnalysis where+ sizeOf _ = iaSizeOf+ alignment _ = iaAlign+ peek c = do+ j <- S.peekByteOff c iaJolietLevel :: IO C.CUInt+ l <- C.peekCString $ C.plusPtr c iaLabel+ s <- S.peekByteOff c iaIsoSize :: IO C.CUInt+ a <- S.peekByteOff c iaUDFMajor+ i <- S.peekByteOff c iaUDFMinor+ return $ IsoAnalysis+ { jolietLevel = if j == 0 then Nothing else Just $ fromIntegral j+ , label = l+ , fsSize = fromIntegral s+ , udfVersion = if a == 0 then Nothing else Just (a, i)+ }+ poke c hs = do+ let (a, i) = Y.fromMaybe (0, 0) $ udfVersion hs+ S.pokeByteOff c iaJolietLevel . maybe (0 :: C.CUInt) fromIntegral $ jolietLevel hs+ pokeCString (label hs) 33 $ C.plusPtr c iaLabel+ S.pokeByteOff c iaIsoSize (fromIntegral $ fsSize hs :: C.CUInt)+ S.pokeByteOff c iaUDFMajor a+ S.pokeByteOff c iaUDFMinor i+++-- | Determine what type of file system is stored in the given track of a disc.+trackType :: Cdio -> Track -> IO (Maybe Filesystem, FilesystemClasses, Maybe IsoAnalysis)+trackType c t = do+ l' <- trackLsn c t+ (fs, iso') <- case l' of+ Just l -> withCdio' defaultCdType $ \c' -> M.alloca $ \i' -> do+ e' <- cdType_ c' l (withTrack t) i'+ iso <- S.peek i'+ return (modEnumFlags e', iso)+ Nothing -> return defaultCdType+ let fc = snd fs+ iso = Just iso' { udfVersion = Nothing }+ isoUdf = Just iso'+ return $ case fst fs of+ Nothing -> (Nothing, fc, isoUdf)+ Just Fs3do -> (Just Cd3do, fc, iso)+ Just FsAudio -> (Just Audio, fc, Nothing)+ Just FsExt2 -> (Just Ext2, fc, iso)+ Just FsHfs -> (Just Hfs, fc, Nothing)+ Just FsIsoHfs -> (Just Hfs, fc, iso)+ Just FsHighSierra -> (Just HighSierra, fc, iso)+ Just FsInteractive -> (Just CdI, fc, Nothing)+ Just FsIso9660Interactive -> (Just CdI, fc, iso)+ Just FsIso9660 -> (Just Iso9660, fc, iso)+ Just FsUdf -> (Just Udf, fc, Nothing)+ Just FsIsoUdf -> (Just Udf, fc, isoUdf)+ Just FsUdfx -> (Just Udf, fc, isoUdf)+ Just FsUfs -> (Just Ufs, fc, iso)+ Just FsXiso -> (Just XboxIso, fc, iso)+ where defaultCdType = ((Nothing, genBitArray []), IsoAnalysis Nothing "" 0 Nothing)+ withCdio' b = fmap (Y.fromMaybe b) . withCdio c++foreign import ccall safe "cdio/compat/cd_types.h cdio_guess_cd_type"+ cdType_ :: C.Ptr Cdio -> Lsn -> CTrack -> C.Ptr IsoAnalysis -> IO C.CInt
+ src/Foreign/Libcdio/Device.hs view
@@ -0,0 +1,1380 @@+{-# LANGUAGE ForeignFunctionInterface #-}++{-|+Description: Various device-management functions, including session initialization.++Copyright: (c) 2018-2021 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: stable+Portability: non-portable (requires libcdio)++The entire library architecture revolves around the concept of a device—not the+disc, but the drive containing it. A function to read a segment of data is not+just a lookup from memory, but an instruction to the device to move the read+arm into position and begin interpreting the pits and ridges. With that+understanding, it makes sense that this module provides not just the means to+determine what any particular drive is capable of, but also the only means to+obtain the 'Cdio' object the everything else revolves around.+++= @device.h@++== Types+* @cdio_drive_cap_misc_t@ -> 'DriveCapabilityMisc'++ - @CDIO_DRIVE_CAP_ERROR@ (removed; handled via 'Nothing')+ - @CDIO_DRIVE_CAP_UNKNOWN@ (removed; handled via 'Nothing')++* @cdio_drive_cap_read_t@ -> 'DriveCapabilityRead'++ - @CDIO_DRIVE_CAP_READ_AUDIO@ -> 'ReadAnalogAudio'+ - @CDIO_DRIVE_CAP_READ_CD_DA@ -> 'ReadDigitalAudio'+ - @CDIO_DRIVE_CAP_READ_CD_R@ -> 'ReadCdRecordable'+ - @CDIO_DRIVE_CAP_READ_CD_RW@ -> 'ReadCdReWritable'+ - @CDIO_DRIVE_CAP_READ_DVD_R@ -> 'ReadDvdRecordable'+ - @CDIO_DRIVE_CAP_READ_DVD_PR@ -> 'ReadDvdPlusRecordable'+ - @CDIO_DRIVE_CAP_READ_DVD_RW@ -> 'ReadDvdReWritable'+ - @CDIO_DRIVE_CAP_READ_DVD_PRW@ -> 'ReadDvdPlusReWritable'+ - @CDIO_DRIVE_CAP_READ_C2_ERRS@ -> 'ReadC2ErrorCorrection'++* @cdio_drive_cap_write_t@ -> 'DriveCapabilityWrite'++ Note that some values are not included in the Haskell type, as the indexing+ implementation is stricter than the equivalent bit operations in C.++ - @CDIO_DRIVE_CAP_WRITE_CD_R@ -> 'WriteCdRecordable'+ - @CDIO_DRIVE_CAP_WRITE_CD_RW@ -> 'WriteCdReWritable'+ - @CDIO_DRIVE_CAP_WRITE_DVD_R@ -> 'WriteDvdRecordable'+ - @CDIO_DRIVE_CAP_WRITE_DVD_PR@ -> 'WriteDvdPlusRecordable'+ - @CDIO_DRIVE_CAP_WRITE_DVD_RW@ -> 'WriteDvdReWritable'+ - @CDIO_DRIVE_CAP_WRITE_DVD_PRW@ -> 'WriteDvdPlusReWritable'+ - @CDIO_DRIVE_CAP_WRITE_CD@ -> 'capsWriteCd'+ - @CDIO_DRIVE_CAP_WRITE_DVD@ -> 'capsWriteDvd'+ - @CDIO_DRIVE_CAP_WRITE@ -> 'capsWrite'++* @cdio_drive_misc_cap_t@ -> 'DriveMiscCaps'+* @cdio_drive_read_cap_t@ -> 'DriveReadCaps'+* @cdio_drive_write_cap_t@ -> 'DriveWriteCaps'+* @cdio_hwinfo_t@ -> 'HardwareInfo'++ - @psz_vendor@ -> 'vendor'+ - @psz_model@ -> 'model'+ - @psz_revision@ -> 'revision'++* @cdio_mmc_hw_len_t@ (type removed; values are structural constants rather than an actual enum)++ - @CDIO_MMC_HW_VENDOR_LEN@ -> 'vendorLength'+ - @CDIO_MMC_HW_MODEL_LEN@ -> 'modelLength'+ - @CDIO_MMC_HW_REVISION_LEN@ -> 'revisionLength'++* @cdio_src_category_mask_t@ (removed; never used in the public interface)+* @driver_id_t@ -> 'DriverId'+* @driver_return_code_t@ -> 'DriverReturnCode'++== Symbols+* @cdio_close_tray@ -> 'closeTray'+* @cdio_destroy@ (removed; handled via garbage collector)+* @cdio_device_drivers@ -> 'deviceDrivers'+* @cdio_driver_describe@ -> 'driverDescribe'+* @cdio_driver_errmsg@ -> 'driverErrmsg'+* @cdio_drivers@ -> 'drivers'+* @cdio_eject_media@ -> 'ejectMedia'+* @cdio_eject_media_drive@ -> 'ejectDrive'+* @cdio_free_device_list@ (removed; handled via garbage collector)+* @cdio_get_arg@ -> 'getArg' and 'getAccessMode'+* @cdio_get_default_device@ -> 'defaultDevice' (@CdIo_t*@ argument dropped as no non-redundant path to get one exists)+* @cdio_get_default_device_*@ -> @defaultDevice*@ (eg. 'defaultDeviceLinux')+* @cdio_get_devices@ -> 'devices'+* @cdio_get_devices_*@ -> @devices*@ (eg. 'devicesLinux')+* @cdio_get_devices_with_cap@ -> 'devicesWithFilesystem'+* @cdio_get_devices_with_cap_ret@ -> 'devicesWithFilesystemRet'+* @cdio_get_drive_cap@ -> 'driveCap'+* @cdio_get_drive_cap_dev@ -> 'driveCapDevice'+* @cdio_get_driver_id@ -> 'driverId'+* @cdio_get_driver_name@ -> 'driverName'+* @cdio_get_hwinfo@ -> 'hwinfo'+* @cdio_get_last_session@ -> 'lastSession'+* @cdio_get_media_changed@ -> 'isMediaChanged'+* @cdio_have_atapi@ -> 'haveAtapi'+* @cdio_have_driver@ -> 'haveDriver'+* @cdio_init@ (removed; internal function without much external occasion for use)+* @cdio_is_binfile@ -> 'cueFromBin'+* @cdio_is_cuefile@ -> 'binFromCue'+* @cdio_is_device@ -> 'isDevice'+* @cdio_is_nrg@ -> 'isNrg'+* @cdio_is_tocfile@ -> 'isToc'+* @cdio_open@ -> 'cdioOpen'+* @cdio_open_*@ -> @cdioOpen*@ (eg. 'cdioOpenLinux')+* @cdio_open_am@ -> 'cdioOpenAm'+* @cdio_open_am_*@ -> @cdioOpenAm*@ (eg. 'cdioOpenAmLinux')+* @cdio_os_driver@ -> 'osDriver'+* @cdio_set_arg@ (removed; primarily intended for internal use, and is more limited than would be expected)+* @cdio_set_blocksize@ -> 'setBlocksize'+* @cdio_set_speed@ -> 'setSpeed'+++= "Sound.Libcdio.Device"++* 'Cdio' -> @"Sound.Libcdio".'Sound.Libcdio.Cdio'@ (note, however, that the latter is a more abstracted 'Monad')++* 'binFromCue' -> 'Sound.Libcdio.Device.isCue'+* 'cdioOpen' -> @"Sound.Libcdio".'Sound.Libcdio.open'@ and 'Sound.Libcdio.openDefault'+* 'cdioOpenAm' -> @"Sound.Libcdio".'Sound.Libcdio.openMode'@ and 'Sound.Libcdio.openModeDefault'+* @cdioOpen*@ (removed; @"Sound.Libcdio".'Sound.Libcdio.open'@ handles the auto-detection)+* 'closeTray' -> 'Sound.Libcdio.Device.closeDeviceTray' and 'Sound.Libcdio.Device.closeDeviceTray''+* 'cueFromBin' (removed; this and 'Foreign.binFromCue' just replace the file extension after validation, they don't go searching)+* @defaultDevice*@ (removed; driver type isn't a public part of device opening)+* 'deviceDrivers' -> @'not' 'Sound.Libcdio.Device.isImageDriver'@+* 'devicesRet' (removed; @"Sound.Libcdio".'Sound.Libcdio.open'@ doesn't require a specific 'Foreign.DriverId' to be passed)+* 'devicesWithFilesystem' (removed; can't think of a use case for searching for discs of a specific data layout)+* 'devicesWithFilesystemRet' (removed; can't think of a use case for searching for discs of a specific data layout)+* @devices*@ (removed; 'Sound.Libcdio.Device.devices' delegates via the 'Foreign.DriverId' parameter)+* 'driveCap' -> 'Sound.Libcdio.Device.capabilities'+* 'driveCapDevice' -> 'Sound.Libcdio.Device.deviceCapabilities'+* 'driverId' -> 'Sound.Libcdio.Device.driver'+* 'ejectDrive' -> 'Sound.Libcdio.Device.ejectDevice'+* 'ejectMedia' (removed; argument to e.g. @"Sound.Libcdio".'Sound.Libcdio.open'@)+* 'getArg' -> @"Sound.Libcdio".'Sound.Libcdio.getArg'@+* 'getAccessMode' -> @"Sound.Libcdio".'Sound.Libcdio.getAccessMode'@+* 'haveDriver' (removed; use @`'elem'` 'Sound.Libcdio.Device.drivers'@)+* 'hwinfo' -> 'Sound.Libcdio.Device.hardware'+* 'lastSession' -> @"Sound.Libcdio.Read.Data".'Sound.Libcdio.Read.Data.lastSessionOffset'@+* 'modelLength' (removed; unnecessary low-level detail)+* 'revisionLength' (removed; unnecessary low-level detail)+* 'vendorLength' (removed; unnecessary low-level detail)+-}+module Foreign.Libcdio.Device+ ( -- * Types+ Cdio+ , HardwareInfo ( .. )+ , vendorLength+ , modelLength+ , revisionLength+ , emptyHardwareInfo+ , DriverId ( .. )+ , DriverReturnCode ( .. )+ , SessionArg ( .. )+ , AccessMode ( .. )+ -- ** Capabilities+ , DriveCapabilityRead ( .. )+ , DriveReadCaps+ , DriveCapabilityWrite ( .. )+ , DriveWriteCaps+ , capsWriteCd+ , capsWriteDvd+ , capsWrite+ , DriveCapabilityMisc ( .. )+ , DriveMiscCaps+ , DriveCaps+ -- * Drivers+ , drivers+ , deviceDrivers+ , osDriver+ , driverName+ , driverId+ , driverDescribe+ , driverErrmsg+ , haveDriver+ -- * Devices+ , devices+ , devicesRet+ , devicesWithFilesystem+ , devicesWithFilesystemRet+ , defaultDevice+ , defaultDeviceDriver+ , hwinfo+ , driveCap+ , driveCapDevice+ , haveAtapi+ , ejectMedia+ , ejectDrive+ , closeTray+ -- * Session+ , getArg+ , getAccessMode+ , isMediaChanged+ , setBlocksize+ , setSpeed+ , lastSession+ -- * Device paths+ , cdioOpen+ , cdioOpenAm+ -- ** Hardware+ , isDevice+ , cdioOpenCd+ , cdioOpenAmCd+ -- ** Images+ , cueFromBin+ , binFromCue+ , isNrg+ , isToc+ {-+ -- *** BIN/CUE+ , cdioOpenBinCue+ , cdioOpenCue+ , cdioOpenAmBinCue+ , defaultDeviceBinCue+ , devicesBinCue+ -- *** cdrdao+ , cdioOpenCdrDao+ , cdioOpenAmCdrDao+ , defaultDeviceCdrDao+ , devicesCdrDao+ -- *** Nero+ , cdioOpenNero+ , cdioOpenAmNero+ , defaultDeviceNero+ , devicesNero+ -- ** Hardware+ -- *** BSDI+ , cdioOpenBsdi+ , cdioOpenAmBsdi+ , defaultDeviceBsdi+ , devicesBsdi+ -- *** FreeBSD+ , cdioOpenFreeBsd+ , cdioOpenAmFreeBsd+ , defaultDeviceFreeBsd+ , devicesFreeBsd+ -- *** Linux+ , cdioOpenLinux+ , cdioOpenAmLinux+ , defaultDeviceLinux+ , devicesLinux+ -- *** OS/2+ , cdioOpenOs2+ , cdioOpenAmOs2+ , defaultDeviceOs2+ , devicesOs2+ -- *** Solaris+ , cdioOpenSolaris+ , cdioOpenAmSolaris+ , defaultDeviceSolaris+ , devicesSolaris+ -- *** Windows+ , cdioOpenWin32+ , cdioOpenAmWin32+ , defaultDeviceWin32+ , devicesWin32+ -}+ ) where+++import qualified Control.Monad as N++import qualified Data.Array.BitArray as A+import qualified Data.Maybe as Y++import qualified Foreign.C.String as C+import qualified Foreign.C.Types as C+import qualified Foreign.Ptr as C++import qualified Foreign.Marshal.Alloc as M+import qualified Foreign.Marshal.Array as M+import qualified Foreign.Marshal.Utils as M+import qualified Foreign.Storable as S++import qualified System.IO.Unsafe as IO.Unsafe++import Data.Ix ( Ix )+import Data.Bits ( (.&.) )++import Foreign.Libcdio.CdTypes+import Foreign.Libcdio.Marshal+import Foreign.Libcdio.Types.Enums+import Foreign.Libcdio.Types.Internal+import Foreign.Libcdio.Types.Offsets++import Sound.Libcdio.Common+++toDriverReturnCode :: Maybe CDriverReturnCode -> DriverReturnCode+toDriverReturnCode = maybe Uninitialized $ toEnum . fromIntegral+++-- | The collection of features for reading discs a device provides.+type DriveReadCaps = A.BitArray DriveCapabilityRead+-- | The collection of features for writing discs a device provides.+type DriveWriteCaps = A.BitArray DriveCapabilityWrite+-- | The collection of hardware features a device was built with.+type DriveMiscCaps = A.BitArray DriveCapabilityMisc++-- | The three types are usually passed around together, so we can simplify the+-- type signatures using them.+type DriveCaps = (DriveReadCaps, DriveWriteCaps, DriveMiscCaps)+++-- | Capabilites indicating a device has some sort of CD-writing ability.+capsWriteCd :: DriveWriteCaps+capsWriteCd = genBitArray+ [ WriteCdRecordable+ , WriteCdReWritable+ ]++-- | Capabilites indicating a device has some sort of DVD-writing ability.+capsWriteDvd :: DriveWriteCaps+capsWriteDvd = genBitArray+ [ WriteDvdRecordable+ , WriteDvdPlusRecordable+ , WriteDvdRam+ , WriteDvdReWritable+ , WriteDvdPlusReWritable+ ]++-- | Capabilites indicating a device has some sort of disc-writing ability.+capsWrite :: DriveWriteCaps+capsWrite = A.zipWith (||) capsWriteCd capsWriteDvd+++-- | Length of the drive vendor name in returned in a 'HardwareInfo' query.+vendorLength :: Word+vendorLength = fromIntegral vendorLength'++foreign import ccall safe "cdio/compat/device.h vendor_len"+ vendorLength' :: C.CUInt+++-- | Length of the drive model name in returned in a 'HardwareInfo' query.+modelLength :: Word+modelLength = fromIntegral modelLength'++foreign import ccall safe "cdio/compat/device.h model_len"+ modelLength' :: C.CUInt++-- | Length of the drive revision number in returned in a 'HardwareInfo' query.+revisionLength :: Word+revisionLength = fromIntegral revisionLength'++foreign import ccall safe "cdio/compat/device.h revision_len"+ revisionLength' :: C.CUInt+++-- | Information defining the make and model of a (typically physical) device.+data HardwareInfo = HardwareInfo+ { vendor :: String+ -- ^ The company who designed and/or built the drive.+ , model :: String+ -- ^ The name of the specific drive design.+ , revision :: String+ -- ^ The version number for hardware/firmware following a series.+ }+ deriving ( Eq, Show, Read )+instance S.Storable HardwareInfo where+ sizeOf _ = hiSizeOf+ alignment _ = hiAlign+ peek c = do+ v <- decode vendorLength hiVendor+ m <- decode modelLength hiModel+ r <- decode revisionLength hiRevision+ return $ HardwareInfo v m r+ where decode l o = C.peekCStringLen (C.plusPtr c o, fromIntegral l)+ poke c hs = do+ pokeCString (vendor hs) (fromIntegral vendorLength + 1) (C.plusPtr c hiVendor)+ pokeCString (model hs) (fromIntegral modelLength + 1) (C.plusPtr c hiModel)+ pokeCString (revision hs) (fromIntegral revisionLength + 1) (C.plusPtr c hiRevision)++-- | A 'HardwareInfo' object with values suitable as defaults.+emptyHardwareInfo :: HardwareInfo+emptyHardwareInfo = HardwareInfo+ { vendor = replicate (fromIntegral vendorLength) '\NUL'+ , model = replicate (fromIntegral modelLength) '\NUL'+ , revision = replicate (fromIntegral revisionLength) '\NUL'+ }+++{- Barely even used internally.+-- | Which type(s) of device describe a particular drive.+type SrcCategories = A.BitArray SrcCategoryMask+-}+++-- | Unmarshall a C-style list of drivers.+peekDriverIdArray :: (Integral a, S.Storable a) => C.Ptr a -> IO [DriverId]+peekDriverIdArray is' = do+ is <- M.peekArray0 (fromIntegral $ fromEnum DriverUnknown) is'+ return $ map (toEnum . fromIntegral) is+++-- | All supported drivers, listed in order of preference.+drivers :: [DriverId]+drivers = filter haveDriver <$> IO.Unsafe.unsafePerformIO $ peekDriverIdArray drivers'++foreign import ccall safe "cdio/compat/device.h get_drivers"+ drivers' :: C.Ptr CDriverId++-- | All supported drivers for physical devices, listed in order of preference.+deviceDrivers :: [DriverId]+deviceDrivers = IO.Unsafe.unsafePerformIO $ peekDriverIdArray deviceDrivers'++foreign import ccall safe "cdio/compat/device.h get_device_drivers"+ deviceDrivers' :: C.Ptr CDriverId++-- | The particular driver for the current operating system, or 'DriverUnknown'+-- if no device driver exists.+osDriver :: DriverId+osDriver = toEnum $ fromIntegral osDriver'++foreign import ccall safe "cdio/compat/device.h get_os_driver"+ osDriver' :: CDriverId+++-- | Close a CD drive, if the device supports doing so.+closeTray+ :: Maybe FilePath+ -- ^ The name of the drive to use, or 'Nothing' to use 'defaultDeviceDriver'.+ -> DriverId+ -> IO (DriverReturnCode, DriverId)+ -- ^ Any errors, along with the actual driver used if passed+ -- 'DriverUnknown' or 'DriverDevice'.+closeTray f d = M.maybeWith C.withCString f $ \f' -> M.with (fromIntegral $ fromEnum d) $ \d' -> do+ r <- closeTray' f' d'+ d'' <- S.peek d'+ return (toEnum $ fromIntegral r, toEnum $ fromIntegral d'')++foreign import ccall safe "cdio/compat/device.h cdio_close_tray"+ closeTray' :: C.CString -> C.Ptr CDriverId -> IO CDriverReturnCode+++-- | Describe the driver-level error in a human-readable manner, as opposed to+-- the machine representation returned by the 'Show' instance.+driverErrmsg :: DriverReturnCode -> String+driverErrmsg = IO.Unsafe.unsafePerformIO .+ C.peekCString . driverErrmsg' . fromIntegral . fromEnum++foreign import ccall safe "cdio/compat/device.h cdio_driver_errmsg"+ driverErrmsg' :: CDriverReturnCode -> C.CString+++-- | Eject the media represented by the session identifier, if the device+-- supports doing so.+-- +-- __Warning:__ Assuming this succeeds, the 'Cdio' object is destroyed and any+-- further operations on it will fail!+ejectMedia :: Cdio -> IO DriverReturnCode+ejectMedia = fmap toDriverReturnCode . flip withCdioPtr ejectMedia'++foreign import ccall safe "cdio/compat/device.h cdio_eject_media"+ ejectMedia' :: C.Ptr (C.Ptr Cdio) -> IO CDriverReturnCode++-- | Eject media in a CD drive, if the device supports doing so. If a 'Cdio'+-- session has already been opened on the drive, 'ejectMedia' is strongly+-- recommended instead.+ejectDrive+ :: Maybe FilePath+ -- ^ The name of the device to eject, or 'Nothing' to use the default+ -- drive for the machine.+ -> IO DriverReturnCode+ejectDrive = fmap (toEnum . fromIntegral) . flip (M.maybeWith C.withCString) ejectDrive'++foreign import ccall safe "cdio/compat/device.h cdio_eject_media_drive"+ ejectDrive' :: C.CString -> IO CDriverReturnCode+++-- | Find the default disc device for the system, if one exists.+-- +-- The C library allows getting the default device from a 'Cdio' object, but+-- since that seems to only be initialized from either the default device+-- itself or with an explicit path, doing so seems rather redundant.+defaultDevice :: IO (Maybe FilePath)+defaultDevice = defaultDevice' C.nullPtr >>= M.maybePeek C.peekCString++foreign import ccall safe "cdio/compat/device.h cdio_get_default_device"+ defaultDevice' :: C.Ptr Cdio -> IO C.CString++-- | Find the default disc device for a given driver, if one exists.+defaultDeviceDriver+ :: DriverId+ -> IO (Maybe FilePath, DriverId)+ -- ^ The name of the device, along with the associated driver if+ -- passed 'DriverUnknown' or 'DriverDevice'.+defaultDeviceDriver d = M.with (fromIntegral $ fromEnum d) $ \d' -> do+ f <- defaultDeviceDriver' d' >>= M.maybePeek C.peekCString+ d'' <- S.peek d'+ return (f, toEnum $ fromIntegral d'')++foreign import ccall safe "cdio/compat/device.h cdio_get_default_device_driver"+ defaultDeviceDriver' :: C.Ptr CDriverId -> IO C.CString+++-- | List (static) available devices on the system which can be accessed with a+-- particular driver; some file devices (e.g. with 'DriverBinCue') might be+-- returned, but an exhaustive list should not be expected in that case.+-- +-- If passed 'DriverDevice', the returned value will list any type of hardware+-- device, but no image files. Likewise, if passed 'DriverUnknown', all+-- hardware devices will be returned along with any already-known images.+devices :: DriverId -> IO [FilePath]+devices d = devices' (fromIntegral $ fromEnum d) >>= peekFStringArray++foreign import ccall safe "cdio/compat/device.h cdio_get_devices"+ devices' :: CDriverId -> IO (C.Ptr C.CString)++-- | Like 'devices', but if 'DriverDevice' or 'DriverUnknown' is passed, the+-- second return value reflects the driver the library would use by default.+-- If any other 'DriverId' is passed, that value is returned unchanged.+devicesRet :: DriverId -> IO ([FilePath], DriverId)+devicesRet d = M.with (fromIntegral $ fromEnum d) $ \d' -> do+ fs <- devicesRet' d' >>= peekFStringArray+ d'' <- S.peek d'+ return (fs, toEnum $ fromIntegral d'')++foreign import ccall safe "cdio/compat/device.h cdio_get_devices_ret"+ devicesRet' :: C.Ptr CDriverId -> IO (C.Ptr C.CString)++-- | Determine which of the devices may read discs fitting the given+-- description.+devicesWithFilesystem+ :: [FilePath]+ -- ^ If empty, then search all possible drives.+ -> Maybe Filesystem+ -> FilesystemClasses+ -> Bool+ -- ^ If 'True', then a device matching any of the capabilities+ -- succeeds; if 'False' then it must match every capability given+ -- (empty capabilities always match).+ -> IO [FilePath]+devicesWithFilesystem ps fs fc b = allocaStringArray ps $ \ps' ->+ devicesWithFilesystem' ps' (joinEnumFlags fs' fc) (M.fromBool b) >>= peekFStringArray+ where fs' = maybe 0 fromEnum fs++foreign import ccall safe "cdio/compat/device.h cdio_get_devices_with_cap"+ devicesWithFilesystem' :: C.Ptr C.CString -> C.CInt -> CBool -> IO (C.Ptr C.CString)++-- | Like 'devicesWithFilesystem', but returning the type of driver found as with+-- 'devicesRet'. This is only helpful if the device list is empty; otherwise+-- it simply returns 'DriverDevice'.+devicesWithFilesystemRet+ :: [FilePath]+ -- ^ If empty, then search all possible drives.+ -> Maybe Filesystem+ -> FilesystemClasses+ -> Bool+ -- ^ If 'True', then a device matching any of the capabilities+ -- succeeds; if 'False' then it must match every capability given+ -- (empty capabilities always match).+ -> IO ([FilePath], DriverId)+devicesWithFilesystemRet ps fs fc b = M.alloca $ \d -> allocaStringArray ps $ \ps' -> do+ ds <- devicesWithFilesystemRet' ps' (joinEnumFlags fs' fc) (M.fromBool b) d+ ds' <- peekFStringArray ds+ d' <- S.peek d+ return (ds', toEnum $ fromIntegral d')+ where fs' = maybe 0 fromEnum fs++foreign import ccall safe "cdio/compat/device.h cdio_get_devices_with_cap_ret"+ devicesWithFilesystemRet' :: C.Ptr C.CString -> C.CInt -> CBool -> C.Ptr CDriverId -> IO (C.Ptr C.CString)+++-- | Get the drive capabilities for the default device.+driveCap :: Cdio -> IO DriveCaps+driveCap c = M.alloca $ \x -> M.alloca $ \y -> M.alloca $ \z -> do+ withCdio_ c $ \c' -> driveCap' c' x y z+ peekDriveCaps x y z++foreign import ccall safe "cdio/compat/device.h cdio_get_drive_cap"+ driveCap' :: C.Ptr Cdio -> C.Ptr CBitfield -> C.Ptr CBitfield -> C.Ptr CBitfield -> IO ()++-- | Get the drive capabilities for a specified device.+driveCapDevice :: FilePath -> IO DriveCaps+driveCapDevice f = C.withCString f $ \f' -> M.alloca $ \x -> M.alloca $ \y -> M.alloca $ \z -> do+ driveCapDevice' f' x y z+ peekDriveCaps x y z++foreign import ccall safe "cdio/compat/device.h cdio_get_drive_cap_dev"+ driveCapDevice' :: C.CString -> C.Ptr CBitfield -> C.Ptr CBitfield -> C.Ptr CBitfield -> IO ()++-- | The value indicating an error occurring during the retrieval of drive+-- capabilities.+foreign import ccall safe "cdio/compat/device.h drive_cap_error"+ capError :: CBitfield++-- | The value used for initializing drive capabilities.+foreign import ccall safe "cdio/compat/device.h drive_cap_unknown"+ capUnknown :: CBitfield++peekDriveCaps :: C.Ptr CBitfield -> C.Ptr CBitfield -> C.Ptr CBitfield -> IO DriveCaps+peekDriveCaps x y z = do+ x' <- S.peek x+ y' <- S.peek y+ z' <- S.peek z+ return $ extractCapError x' y' z'++-- | Process each capability collection, and if all are+-- @CDIO_DRIVE_CAP_UNKNOWN@ (uninitialized) or @CDIO_DRIVE_CAP_ERROR@, then+-- collapse them.+extractCapError :: CBitfield -> CBitfield -> CBitfield -> DriveCaps+extractCapError rs ws ms = case (packMay rs, packMay ws, packMay ms) of+ (Nothing, Nothing, Nothing) -> (pack empty, pack empty, pack empty)+ (rs', ws', ms') -> (orEmpty rs', orEmpty ws', orEmpty ms')+ where testEnumBit :: (Integral c, Enum i) => c -> i -> (i, Bool)+ testEnumBit c i = (i, (fromIntegral c .&. fromEnum i) /= 0)+ pack bs = A.array (minBound, maxBound) $ map (testEnumBit bs) [minBound .. maxBound]+ packMay bs+ | bs .&. capError == 0 = Nothing+ | bs .&. capUnknown == 0 = Nothing+ | otherwise = Just $ pack bs+ orEmpty :: (Bounded a, Enum a, Ix a) => Maybe (A.BitArray a) -> A.BitArray a+ orEmpty = Y.fromMaybe $ pack empty+ empty = 0x0 :: CBitfield+++-- | Describe the driver used by the session in a human-readable (English)+-- manner. See also 'driverId'.+driverName :: Cdio -> IO (Maybe String)+driverName c = withCdio c driverName' >>= maybe (return Nothing) (M.maybePeek C.peekCString)++foreign import ccall safe "cdio/compat/device.h cdio_get_driver_name"+ driverName' :: C.Ptr Cdio -> IO C.CString++{- Not exported+-- | Describe the IO driver in a human-readable manner, as opposed to the+-- machine representation returned by the 'Show' instance.+driverNameFromId :: DriverId -> String+driverNameFromId d = IO.Unsafe.unsafePerformIO $ driverNameFromId d >>= C.peekCString++foreign import ccall safe "cdio/compat/device.h cdio_get_driver_name_from_id"+ driverNameFromId' :: DriverId -> C.CString+-}++-- | The machine-readable identifier of the driver used by the session. This+-- should be preferred to 'driverName' wherever possible.+-- +-- Returns 'Nothing' if the 'Cdio' object has already been closed.+driverId :: Cdio -> IO (Maybe DriverId)+driverId c = fmap (toEnum . fromIntegral) <$> withCdio c driverId'++foreign import ccall safe "cdio/compat/device.h cdio_get_driver_id"+ driverId' :: C.Ptr Cdio -> IO CDriverId++-- | Get a description of the hardware associated with a particular session.+-- +-- Returns 'Nothing' if the 'Cdio' object has already been closed, or if an+-- error occurred in retrieval.+hwinfo :: Cdio -> IO (Maybe HardwareInfo)+hwinfo c = M.alloca $ \h -> do+ b <- withCdio c $ flip hwinfo' h+ case M.toBool <$> b of+ Just True -> M.maybePeek S.peek h+ _ -> return Nothing++foreign import ccall safe "cdio/compat/device.h cdio_get_hwinfo"+ hwinfo' :: C.Ptr Cdio -> C.Ptr HardwareInfo -> IO CBool+++-- | Get the starting address of the last write session of a disc.+lastSession :: Cdio -> IO (Either DriverReturnCode Lsn)+lastSession c = M.alloca $ \l -> do+ r <- withCdio c $ flip lastSession' l+ l' <- S.peek l+ return $ case toEnum . fromIntegral <$> r of+ Just Success -> Right l'+ Just e -> Left e+ Nothing -> Left Uninitialized++foreign import ccall safe "cdio/compat/device.h cdio_get_last_session"+ lastSession' :: C.Ptr Cdio -> C.Ptr Lsn -> IO CDriverReturnCode+++-- | Find out if the media has changed since the last call.+isMediaChanged :: Cdio -> IO (Either DriverReturnCode Bool)+isMediaChanged c = maybe (Left Uninitialized) errorOrBool <$> withCdio c isMediaChanged'++foreign import ccall safe "cdio/compat/device.h cdio_get_media_changed"+ isMediaChanged' :: C.Ptr Cdio -> IO CDriverReturnCode+++-- | Determine if the device understands ATAPI commands.+-- +-- Returns 'Nothing' if the 'Cdio' object has already been closed, or if the+-- capability can't be determined.+haveAtapi :: Cdio -> IO (Maybe Bool)+haveAtapi c = fmap N.join . withCdio c $ fmap bool3 . haveAtapi'++foreign import ccall safe "cdio/compat/device.h cdio_have_atapi"+ haveAtapi' :: C.Ptr Cdio -> IO C.CInt+++-- | Determine whether the system provides a particular driver.+haveDriver :: DriverId -> Bool+haveDriver = M.toBool . haveDriver' . fromIntegral . fromEnum++foreign import ccall safe "cdio/compat/device.h cdio_have_driver"+ haveDriver' :: CDriverId -> CBool+++{- Encapsulated into the 'ForeignPtr Cdio'.+-- | Free any resources associated with a reading session.+cdioDestroy :: Cdio -> IO ()+cdioDestroy = flip withCdio cdioDestroy'++foreign import ccall safe "cdio/compat/device.h cdio_destroy"+ cdioDestroy' :: C.Ptr Cdio -> IO ()+-}+++-- | Describe the IO driver in a human-readable manner, as opposed to the+-- machine representation returned by the 'Show' instance.+driverDescribe :: DriverId -> String+driverDescribe = IO.Unsafe.unsafePerformIO .+ C.peekCString . driverDescribe' . fromIntegral . fromEnum++foreign import ccall safe "cdio/compat/device.h cdio_driver_describe"+ driverDescribe' :: CDriverId -> C.CString+++-- | Open a session referencing the given location, or the default device if+-- passed 'Nothing'.+cdioOpen :: Maybe FilePath -> DriverId -> IO (Maybe Cdio)+cdioOpen f d = M.maybeWith C.withCString f $ \f' -> do+ setupLogger+ c' <- cdioOpen' f' (fromIntegral $ fromEnum d)+ M.maybePeek peekCdio c'++foreign import ccall safe "cdio/compat/device.h cdio_open"+ cdioOpen' :: C.CString -> CDriverId -> IO (C.Ptr Cdio)++-- | Open a session referencing the given location, or the default device if+-- passed 'Nothing', with the desired access mode.+cdioOpenAm :: Maybe FilePath -> DriverId -> AccessMode -> IO (Maybe Cdio)+cdioOpenAm f d m = M.maybeWith C.withCString f $ \f' -> C.withCString (serializeAccessMode m) $ \m' -> do+ setupLogger+ c' <- cdioOpenAm' f' (fromIntegral $ fromEnum d) m'+ M.maybePeek peekCdio c'++foreign import ccall safe "cdio/compat/device.h cdio_open_am"+ cdioOpenAm' :: C.CString -> CDriverId -> C.CString -> IO (C.Ptr Cdio)+++open'+ :: (C.CString -> IO (C.Ptr Cdio))+ -> Maybe FilePath+ -> IO (Maybe Cdio)+open' f p = withCStringNull p $ \p' -> do+ setupLogger+ f p' >>= M.maybePeek peekCdio++openAm'+ :: (C.CString -> C.CString -> IO (C.Ptr Cdio))+ -> Maybe FilePath+ -> AccessMode+ -> IO (Maybe Cdio)+openAm' f p m = withCStringNull p $ \p' -> C.withCString (serializeAccessMode m) $ \m' -> do+ setupLogger+ f p' m' >>= M.maybePeek peekCdio++withCStringNull :: Maybe String -> (C.CString -> IO a) -> IO a+withCStringNull Nothing f = f C.nullPtr+withCStringNull (Just str) f = C.withCString str f+++-- | Set up the specified CD-ROM device for reading.+cdioOpenCd :: Maybe FilePath -> IO (Maybe Cdio)+cdioOpenCd = open' cdioOpenCd'++foreign import ccall safe "cdio/compat/device.h cdio_open_cd"+ cdioOpenCd' :: C.CString -> IO (C.Ptr Cdio)++-- | Set up the specified CD-ROM device for reading, with the desired access+-- mode.+cdioOpenAmCd :: Maybe FilePath -> AccessMode -> IO (Maybe Cdio)+cdioOpenAmCd = openAm' cdioOpenAmCd'++foreign import ccall safe "cdio/compat/device.h cdio_open_am_cd"+ cdioOpenAmCd' :: C.CString -> C.CString -> IO (C.Ptr Cdio)+++{- All the official bindings hide these, which makes me think they're not as reliable.+defaultPath' :: IO C.CString -> IO (Maybe FilePath)+defaultPath' p = p >>= M.maybePeek C.peekCString++deviceList' :: IO (C.Ptr C.CString) -> IO [FilePath]+deviceList' ps = ps >>= peekFStringArray+++-- | Set up a BIN/CUE disc image for reading.+cdioOpenBinCue+ :: Maybe FilePath+ -- ^ The path to either the @*.bin@ or the @*.cue@ file.+ -> IO (Maybe Cdio)+cdioOpenBinCue = open' cdioOpenBinCue'++foreign import ccall safe "cdio/compat/device.h cdio_open_bincue"+ cdioOpenBinCue' :: C.CString -> IO (C.Ptr Cdio)++-- | Set up a BIN/CUE disc image for reading, with the desired access mode.+cdioOpenAmBinCue+ :: Maybe FilePath+ -- ^ The path to either the @*.bin@ or the @*.cue@ file.+ -> AccessMode+ -> IO (Maybe Cdio)+cdioOpenAmBinCue = openAm' cdioOpenAmBinCue'++foreign import ccall safe "cdio/compat/device.h cdio_open_am_bincue"+ cdioOpenAmBinCue' :: C.CString -> C.CString -> IO (C.Ptr Cdio)++-- | The default CUE file that would be used if none is specified.+defaultDeviceBinCue :: IO (Maybe FilePath)+defaultDeviceBinCue = defaultPath' defaultDeviceBinCue'++foreign import ccall safe "cdio/compat/device.h cdio_get_default_device_bincue"+ defaultDeviceBinCue' :: IO C.CString++-- | The CUE files contained in the current directory.+devicesBinCue :: IO [FilePath]+devicesBinCue = deviceList' devicesBinCue'++foreign import ccall safe "cdio/compat/device.h cdio_get_devices_bincue"+ devicesBinCue' :: IO (C.Ptr C.CString)+++-- | Set up a cdrdao disc image for reading.+cdioOpenCdrDao+ :: Maybe FilePath+ -- ^ The path to the @*.toc@ file.+ -> IO (Maybe Cdio)+cdioOpenCdrDao = open' cdioOpenCdrDao'++foreign import ccall safe "cdio/compat/device.h cdio_open_cdrdao"+ cdioOpenCdrDao' :: C.CString -> IO (C.Ptr Cdio)++-- | Set up a cdrdao disc image for reading, with the desired access mode.+cdioOpenAmCdrDao+ :: Maybe FilePath+ -- ^ The path to the @*.toc@ file.+ -> AccessMode+ -> IO (Maybe Cdio)+cdioOpenAmCdrDao = openAm' cdioOpenAmCdrDao'++foreign import ccall safe "cdio/compat/device.h cdio_open_am_cdrdao"+ cdioOpenAmCdrDao' :: C.CString -> C.CString -> IO (C.Ptr Cdio)++-- | The default TOC file that would be used if none is specified.+defaultDeviceCdrDao :: IO (Maybe FilePath)+defaultDeviceCdrDao = defaultPath' defaultDeviceCdrDao'++foreign import ccall safe "cdio/compat/device.h cdio_get_default_device_cdrdao"+ defaultDeviceCdrDao' :: IO C.CString++-- | Paths to potential TOC disc images.+devicesCdrDao :: IO [FilePath]+devicesCdrDao = deviceList' devicesCdrDao'++foreign import ccall safe "cdio/compat/device.h cdio_get_devices_cdrdao"+ devicesCdrDao' :: IO (C.Ptr C.CString)+++-- | Set up a BIN/CUE disc image for reading. Unlike 'cdioOpenBinCue' which+-- may reference either, this path /must/ point to the @*.cue@ file.+cdioOpenCue :: Maybe FilePath -> IO (Maybe Cdio)+cdioOpenCue = open' cdioOpenCue'++foreign import ccall safe "cdio/compat/device.h cdio_open_cue"+ cdioOpenCue' :: C.CString -> IO (C.Ptr Cdio)+++-- | Set up a device for reading using the AIX driver.+cdioOpenAix :: Maybe FilePath -> IO (Maybe Cdio)+cdioOpenAix = open' cdioOpenAix'++foreign import ccall safe "cdio/compat/device.h cdio_open_aix"+ cdioOpenAix' :: C.CString -> IO (C.Ptr Cdio)++-- | Set up a device for reading using the AIX driver, with the desired access+-- mode.+cdioOpenAmAix :: Maybe FilePath -> AccessMode -> IO (Maybe Cdio)+cdioOpenAmAix = openAm' cdioOpenAmAix'++foreign import ccall safe "cdio/compat/device.h cdio_open_am_aix"+ cdioOpenAmAix' :: C.CString -> C.CString -> IO (C.Ptr Cdio)++-- | The default device name that the AIX driver would use if none is+-- specified.+defaultDeviceAix :: IO (Maybe FilePath)+defaultDeviceAix = defaultPath' defaultDeviceAix'++foreign import ccall safe "cdio/compat/device.h cdio_get_default_device_aix"+ defaultDeviceAix' :: IO C.CString++-- | All of the devices that the AIX driver can find. This may require a disc+-- to be inserted in order for the system to recognize the drive.+devicesAix :: IO [FilePath]+devicesAix = deviceList' devicesAix'++foreign import ccall safe "cdio/compat/device.h cdio_get_devices_aix"+ devicesAix' :: IO (C.Ptr C.CString)+++-- | Set up a device for reading using the FreeBSD driver.+cdioOpenFreeBsd :: Maybe FilePath -> IO (Maybe Cdio)+cdioOpenFreeBsd = open' cdioOpenFreeBsd'++foreign import ccall safe "cdio/compat/device.h cdio_open_freebsd"+ cdioOpenFreeBsd' :: C.CString -> IO (C.Ptr Cdio)++-- | Set up a device for reading using the FreeBSD driver, with the desired+-- access mode.+cdioOpenAmFreeBsd :: Maybe FilePath -> AccessMode -> IO (Maybe Cdio)+cdioOpenAmFreeBsd = openAm' cdioOpenAmFreeBsd'++foreign import ccall safe "cdio/compat/device.h cdio_open_am_freebsd"+ cdioOpenAmFreeBsd' :: C.CString -> C.CString -> IO (C.Ptr Cdio)++-- | The default device name that the FreeBSD driver would use if none is+-- specified.+defaultDeviceFreeBsd :: IO (Maybe FilePath)+defaultDeviceFreeBsd = defaultPath' defaultDeviceFreeBsd'++foreign import ccall safe "cdio/compat/device.h cdio_get_default_device_freebsd"+ defaultDeviceFreeBsd' :: IO C.CString++-- | All of the devices that the FreeBSD driver can find. This may require a+-- disc to be inserted in order for the system to recognize the drive.+devicesFreeBsd :: IO [FilePath]+devicesFreeBsd = deviceList' devicesFreeBsd'++foreign import ccall safe "cdio/compat/device.h cdio_get_devices_freebsd"+ devicesFreeBsd' :: IO (C.Ptr C.CString)+++-- | Set up a device for reading using the BSDI driver.+-- +-- /Since libcdio 1.0: Always returns 'Nothing'/+cdioOpenBsdi :: Maybe FilePath -> IO (Maybe Cdio)+cdioOpenBsdi = open' cdioOpenBsdi'++foreign import ccall safe "cdio/compat/device.h cdio_open_bsdi_safe"+ cdioOpenBsdi' :: C.CString -> IO (C.Ptr Cdio)++-- | Set up a device for reading using the BSDI driver, with the desired access+-- mode.+-- +-- /Since libcdio 1.0: Always returns 'Nothing'/+cdioOpenAmBsdi :: Maybe FilePath -> AccessMode -> IO (Maybe Cdio)+cdioOpenAmBsdi = openAm' cdioOpenAmBsdi'++foreign import ccall safe "cdio/compat/device.h cdio_open_am_bsdi_safe"+ cdioOpenAmBsdi' :: C.CString -> C.CString -> IO (C.Ptr Cdio)++-- | The default device name that the BSDI driver would use if none is+-- specified.+-- +-- /Since libcdio 1.0: Always returns 'Nothing'/+defaultDeviceBsdi :: IO (Maybe FilePath)+defaultDeviceBsdi = defaultPath' defaultDeviceBsdi'++foreign import ccall safe "cdio/compat/device.h cdio_get_default_device_bsdi_safe"+ defaultDeviceBsdi' :: IO C.CString++-- | All of the devices that the BSDI driver can find. This may require a disc+-- to be inserted in order for the system to recognize the drive.+-- +-- /Since libcdio 1.0: Always returns @[]@/+devicesBsdi :: IO [FilePath]+devicesBsdi = deviceList' devicesBsdi'++foreign import ccall safe "cdio/compat/device.h cdio_get_devices_bsdi_safe"+ devicesBsdi' :: IO (C.Ptr C.CString)+++-- | Set up a device for reading using the GNU/Linux driver. This may require+-- a disc to be inserted in order for the system to recognize the drive.+cdioOpenLinux :: Maybe FilePath -> IO (Maybe Cdio)+cdioOpenLinux = open' cdioOpenLinux'++foreign import ccall safe "cdio/compat/device.h cdio_open_linux"+ cdioOpenLinux' :: C.CString -> IO (C.Ptr Cdio)++-- | Set up a device for reading using the GNU/Linux driver, with the desired+-- access mode.+cdioOpenAmLinux :: Maybe FilePath -> AccessMode -> IO (Maybe Cdio)+cdioOpenAmLinux = openAm' cdioOpenAmLinux'++foreign import ccall safe "cdio/compat/device.h cdio_open_am_linux"+ cdioOpenAmLinux' :: C.CString -> C.CString -> IO (C.Ptr Cdio)++-- | The default device name that the GNU/Linux driver would use if none is+-- specified. This may require a disc to be inserted in order for the system to+-- recognize the drive.+defaultDeviceLinux :: IO (Maybe FilePath)+defaultDeviceLinux = defaultPath' defaultDeviceLinux'++foreign import ccall safe "cdio/compat/device.h cdio_get_default_device_linux"+ defaultDeviceLinux' :: IO C.CString++-- | All of the devices that the GNU/Linux driver can find.+devicesLinux :: IO [FilePath]+devicesLinux = deviceList' devicesLinux'++foreign import ccall safe "cdio/compat/device.h cdio_get_devices_linux"+ devicesLinux' :: IO (C.Ptr C.CString)+++-- | Set up a device for reading using the Sun Solaris driver. This may+-- require a disc to be inserted in order for the system to recognize the+-- drive.+cdioOpenSolaris :: Maybe FilePath -> IO (Maybe Cdio)+cdioOpenSolaris = open' cdioOpenSolaris'++foreign import ccall safe "cdio/compat/device.h cdio_open_solaris"+ cdioOpenSolaris' :: C.CString -> IO (C.Ptr Cdio)++-- | Set up a device for reading using the Sun Solaris driver, with the desired+-- access mode.+cdioOpenAmSolaris :: Maybe FilePath -> AccessMode -> IO (Maybe Cdio)+cdioOpenAmSolaris = openAm' cdioOpenAmSolaris'++foreign import ccall safe "cdio/compat/device.h cdio_open_am_solaris"+ cdioOpenAmSolaris' :: C.CString -> C.CString -> IO (C.Ptr Cdio)++-- | The default device name that the Solaris driver would use if none is+-- specified. This may require a disc to be inserted in order for the system+-- to recognize the drive.+defaultDeviceSolaris :: IO (Maybe FilePath)+defaultDeviceSolaris = defaultPath' defaultDeviceSolaris'++foreign import ccall safe "cdio/compat/device.h cdio_get_default_device_solaris"+ defaultDeviceSolaris' :: IO C.CString++-- | All of the devices that the Solaris driver can find.+devicesSolaris :: IO [FilePath]+devicesSolaris = deviceList' devicesSolaris'++foreign import ccall safe "cdio/compat/device.h cdio_get_devices_solaris"+ devicesSolaris' :: IO (C.Ptr C.CString)+++-- | Set up a device for reading using the Apple OSX driver. This may require+-- a disc to be inserted in order for the system to recognize the drive.+cdioOpenOsX :: Maybe FilePath -> IO (Maybe Cdio)+cdioOpenOsX = open' cdioOpenOsX'++foreign import ccall safe "cdio/compat/device.h cdio_open_osx"+ cdioOpenOsX' :: C.CString -> IO (C.Ptr Cdio)++-- | Set up a device for reading using the Apple OSX driver, with the desired+-- access mode.+cdioOpenAmOsX :: Maybe FilePath -> AccessMode -> IO (Maybe Cdio)+cdioOpenAmOsX = openAm' cdioOpenAmOsX'++foreign import ccall safe "cdio/compat/device.h cdio_open_am_osx"+ cdioOpenAmOsX' :: C.CString -> C.CString -> IO (C.Ptr Cdio)++-- | The default device name that the OSX driver would use if none is+-- specified. This may require a disc to be inserted in order for the system+-- to recognize the drive.+defaultDeviceOsX :: IO (Maybe FilePath)+defaultDeviceOsX = defaultPath' defaultDeviceOsX'++foreign import ccall safe "cdio/compat/device.h cdio_get_default_device_osx"+ defaultDeviceOsX' :: IO C.CString++-- | All of the devices that the OSX driver can find.+devicesOsX :: IO [FilePath]+devicesOsX = deviceList' devicesOsX'++foreign import ccall safe "cdio/compat/device.h cdio_get_devices_osx"+ devicesOsX' :: IO (C.Ptr C.CString)+++-- | Set up a device for reading using the Microsoft Windows driver. This may+-- require a disc to be inserted in order for the system to recognize the+-- drive.+cdioOpenWin32 :: Maybe FilePath -> IO (Maybe Cdio)+cdioOpenWin32 = open' cdioOpenWin32'++foreign import ccall safe "cdio/compat/device.h cdio_open_win32"+ cdioOpenWin32' :: C.CString -> IO (C.Ptr Cdio)++-- | Set up a device for reading using the Microsoft Windows driver, with the+-- desired access mode.+cdioOpenAmWin32 :: Maybe FilePath -> AccessMode -> IO (Maybe Cdio)+cdioOpenAmWin32 = openAm' cdioOpenAmWin32'++foreign import ccall safe "cdio/compat/device.h cdio_open_am_win32"+ cdioOpenAmWin32' :: C.CString -> C.CString -> IO (C.Ptr Cdio)++-- | The default device name that the Microsoft Windows driver would use if+-- none is specified. This may require a disc to be inserted in order for the+-- system to recognize the drive.+defaultDeviceWin32 :: IO (Maybe FilePath)+defaultDeviceWin32 = defaultPath' defaultDeviceWin32'++foreign import ccall safe "cdio/compat/device.h cdio_get_default_device_win32"+ defaultDeviceWin32' :: IO C.CString++-- | All of the devices that the Microsoft Windows driver can find.+devicesWin32 :: IO [FilePath]+devicesWin32 = deviceList' devicesWin32'++foreign import ccall safe "cdio/compat/device.h cdio_get_devices_win32"+ devicesWin32' :: IO (C.Ptr C.CString)+++-- | Set up a device for reading using the IBM OS/2 driver. This may require a+-- disc to be inserted in order for the system to recognize the drive.+-- +-- /Since libcdio 1.0: Always returns 'Nothing'/+cdioOpenOs2 :: Maybe FilePath -> IO (Maybe Cdio)+cdioOpenOs2 = open' cdioOpenOs2'++foreign import ccall safe "cdio/compat/device.h cdio_open_os2_safe"+ cdioOpenOs2' :: C.CString -> IO (C.Ptr Cdio)++-- | Set up a device for reading using the IBM OS/2 driver, with the desired+-- access mode.+-- +-- /Since libcdio 1.0: Always returns 'Nothing'/+cdioOpenAmOs2 :: Maybe FilePath -> AccessMode -> IO (Maybe Cdio)+cdioOpenAmOs2 = openAm' cdioOpenAmOs2'++foreign import ccall safe "cdio/compat/device.h cdio_open_am_os2_safe"+ cdioOpenAmOs2' :: C.CString -> C.CString -> IO (C.Ptr Cdio)++-- | The default device name that the OS/2 driver would use if none is+-- specified. This may require a disc to be inserted in order for the system+-- to recognize the drive.+-- +-- /Since libcdio 1.0: Always returns 'Nothing'/+defaultDeviceOs2 :: IO (Maybe FilePath)+defaultDeviceOs2 = defaultPath' defaultDeviceOs2'++foreign import ccall safe "cdio/compat/device.h cdio_get_default_device_os2_safe"+ defaultDeviceOs2' :: IO C.CString++-- | All of the devices that the OS/2 driver can find.+-- +-- /Since libcdio 1.0: Always returns @[]@/+devicesOs2 :: IO [FilePath]+devicesOs2 = deviceList' devicesOs2'++foreign import ccall safe "cdio/compat/device.h cdio_get_devices_os2_safe"+ devicesOs2' :: IO (C.Ptr C.CString)+++-- | Set up a Nero disc image for reading.+cdioOpenNero :: Maybe FilePath -> IO (Maybe Cdio)+cdioOpenNero = open' cdioOpenNero'++foreign import ccall safe "cdio/compat/device.h cdio_open_nrg"+ cdioOpenNero' :: C.CString -> IO (C.Ptr Cdio)++-- | Set up a Nero disc image for reading, with the desired access mode.+cdioOpenAmNero :: Maybe FilePath -> AccessMode -> IO (Maybe Cdio)+cdioOpenAmNero = openAm' cdioOpenAmNero'++foreign import ccall safe "cdio/compat/device.h cdio_open_am_nrg"+ cdioOpenAmNero' :: C.CString -> C.CString -> IO (C.Ptr Cdio)++-- | The default image file that the Nero driver would use if none is+-- specified.+defaultDeviceNero :: IO (Maybe FilePath)+defaultDeviceNero = defaultPath' defaultDeviceNero'++foreign import ccall safe "cdio/compat/device.h cdio_get_default_device_nrg"+ defaultDeviceNero' :: IO C.CString++-- | Paths to potential Nero disc images.+devicesNero :: IO [FilePath]+devicesNero = deviceList' devicesNero'++foreign import ccall safe "cdio/compat/device.h cdio_get_devices_nrg"+ devicesNero' :: IO (C.Ptr C.CString)+-}+++-- | If the given file is a BIN disc image (determined by file extension),+-- return the corresponding CUE file. Note that this simply replaces the+-- extension to obtain the new file name.+cueFromBin :: FilePath -> IO (Maybe FilePath)+cueFromBin f = C.withCString f cueFromBin' >>= M.maybePeek C.peekCString++foreign import ccall safe "cdio/compat/device.h cdio_is_binfile"+ cueFromBin' :: C.CString -> IO C.CString++-- | If the given file is a valid CUE disc description, return the+-- corresponding BIN file. Note that this simply replaces the file extension+-- to obtain the new file name.+binFromCue :: FilePath -> IO (Maybe FilePath)+binFromCue f = C.withCString f binFromCue' >>= M.maybePeek C.peekCString++foreign import ccall safe "cdio/compat/device.h cdio_is_cuefile"+ binFromCue' :: C.CString -> IO C.CString++-- | Check that a Nero disc image file is valid.+isNrg :: FilePath -> IO Bool+isNrg = fmap M.toBool . flip C.withCString isNrg'++foreign import ccall safe "cdio/compat/device.h cdio_is_nrg"+ isNrg' :: C.CString -> IO CBool++-- | Check that a cdrdao-style TOC description file is valid.+isToc :: FilePath -> IO Bool+isToc = fmap M.toBool . flip C.withCString isToc'++foreign import ccall safe "cdio/compat/device.h cdio_is_tocfile"+ isToc' :: C.CString -> IO CBool++-- | Determine whether the given path refers to a hardware device, according to+-- the given driver. 'DriverUnknown' or 'DriverDevice' may be passed if the+-- system is unknown.+isDevice :: FilePath -> DriverId -> IO Bool+isDevice f d = M.toBool <$> C.withCString f (flip isDevice' . fromIntegral $ fromEnum d)++foreign import ccall safe "cdio/compat/device.h cdio_is_device"+ isDevice' :: C.CString -> CDriverId -> IO CBool+++-- | Set the blocksize for subsequent reads.+setBlocksize+ :: Cdio+ -- ^ The CdText object is mutated as a result of the function.+ -> Int+ -> IO DriverReturnCode+setBlocksize c s = toDriverReturnCode <$> withCdio c (flip setBlocksize' $ fromIntegral s)++foreign import ccall safe "cdio/compat/device.h cdio_set_blocksize"+ setBlocksize' :: C.Ptr Cdio -> C.CInt -> IO CDriverReturnCode++-- | Set the drive speed. With many devices, if a value above their maximum+-- speed is given, it will be silently capped.+--+-- Note that, unlike 'MMC.setSpeed', this uses a unit unique to disc drives,+-- which depends on the type of disc; to convert to or from Kb/s, use the+-- formula @dt * cds = kbs@ where @dt@ is either @176@ for raw data or @150@+-- for filesystem data, and @cds@ is the 'Int' passed to this function.+setSpeed+ :: Cdio+ -- ^ The CdText object is mutated as a result of the function.+ -> Int+ -> IO DriverReturnCode+setSpeed c v = toDriverReturnCode <$> withCdio c (flip setSpeed' $ fromIntegral v)++foreign import ccall safe "cdio/compat/device.h cdio_set_speed"+ setSpeed' :: C.Ptr Cdio -> C.CInt -> IO CDriverReturnCode+++-- | Retrieve the session value associated with the given key. The particular+-- case of @"access-mode"@ is instead handled by 'getAccessMode'.+getArg :: Cdio -> SessionArg -> IO (Maybe String)+getArg c k = C.withCString (serializeSessionArg k) $ \k' ->+ withCdio c (`getArg'` k') >>= maybe (return Nothing) (M.maybePeek C.peekCString)++-- | Check what instruction set is in use for reading the disc. Other session+-- values are handled by 'getArg'.+getAccessMode :: Cdio -> IO (Maybe AccessMode)+getAccessMode c = C.withCString "access-mode" $ \k' -> do+ str <- withCdio c (`getArg'` k') >>= maybe (return Nothing) (M.maybePeek C.peekCString)+ return $ fmap unserializeAccessMode str++foreign import ccall safe "cdio/compat/device.h cdio_get_arg"+ getArg' :: C.Ptr Cdio -> C.CString -> IO C.CString++{- This is very likely intended for internal use only+-- | Change the session value associated with the given key.+setArg+ :: Cdio+ -- ^ The CdText object is mutated as a result of the function.+ -> SessionArg+ -> String+ -- ^ The new property value.+ -> IO DriverReturnCode+setArg c k v = C.withCString (serializeSessionArg k) $ \k' -> C.withCString v $ \v' ->+ toDriverReturnCode <$> withCdio c (\c' -> setArg' c' k' v')++foreign import ccall safe "cdio/compat/device.h cdio_set_arg"+ setArg' :: C.Ptr Cdio -> C.CString -> C.CString -> IO CDriverReturnCode+-}++-- | Metadata about the session in the form of (often freeform) text, providing+-- a type-safe index to 'getArg'. Note that not every driver type supports+-- every item.+--+-- The key @"access-mode"@ is handled separately by 'getAccessMode', to better+-- reflect its restricted outputs.+data SessionArg+ = Source+ | Cue+ | ScsiTuple+ | MmcSupported+ deriving ( Eq, Ord, Bounded, Enum, Show, Read )+instance S.Storable SessionArg where+ sizeOf _ = S.sizeOf (undefined :: C.CString)+ alignment _ = S.alignment (undefined :: C.CString)+ peek p = do+ p' <- S.peek $ C.castPtr p+ if p' == C.nullPtr+ then error "Storable(SessionArg).peek: NULL reference"+ else do+ str <- C.peekCString p'+ return $ case str of+ "source" -> Source+ "cue" -> Cue+ "scsi-tuple" -> ScsiTuple+ "mmc-supported?" -> MmcSupported+ _ -> error $ "Storable(SessionArg).peek: unknown key '" ++ str ++ "'"+ poke p hs = C.newCString (serializeSessionArg hs) >>= S.poke (C.castPtr p)++serializeSessionArg :: SessionArg -> String+serializeSessionArg Source = "source"+serializeSessionArg Cue = "cue"+serializeSessionArg ScsiTuple = "scsi-tuple"+serializeSessionArg MmcSupported = "mmc-supported?"+++-- | Which instruction set should be used to communicate with the driver,+-- providing a type-safe input for session initialization. Note that not every+-- driver type supports every item.+data AccessMode+ = Image+ | Ioctl+ -- ^ The 'DriverLinux' and 'DriverBsdi' drivers use a different+ -- internal representation for 'Ioctl_'.+ | Ioctl_+ -- ^ The 'DriverFreeBsd' and 'DriverWin32' drivers use a different+ -- internal representation for 'Ioctl'.+ | Aspi+ | Atapi+ | Cam+ | Scsi+ | ReadCd+ | Read10+ | MmcReadWrite+ | MmcReadWriteExclusive+ deriving ( Eq, Ord, Bounded, Enum, Show, Read )+instance S.Storable AccessMode where+ sizeOf _ = S.sizeOf (undefined :: C.CString)+ alignment _ = S.alignment (undefined :: C.CString)+ peek p = do+ p' <- S.peek $ C.castPtr p+ if p' == C.nullPtr+ then error "Storable(AccessMode).peek: NULL reference"+ else unserializeAccessMode <$> C.peekCString p'+ poke p hs = C.newCString (serializeAccessMode hs) >>= S.poke (C.castPtr p)++serializeAccessMode :: AccessMode -> String+serializeAccessMode Image = "image"+serializeAccessMode Ioctl = "IOCTL"+serializeAccessMode Ioctl_ = "ioctl"+serializeAccessMode Aspi = "ASPI"+serializeAccessMode Atapi = "ATAPI"+serializeAccessMode Cam = "CAM"+serializeAccessMode Scsi = "SCSI"+serializeAccessMode ReadCd = "READ_CD"+serializeAccessMode Read10 = "READ_10"+serializeAccessMode MmcReadWrite = "MMC_RDWR"+serializeAccessMode MmcReadWriteExclusive = "MMC_RDWR_EXCL"++unserializeAccessMode :: String -> AccessMode+unserializeAccessMode "image" = Image+unserializeAccessMode "IOCTL" = Ioctl+unserializeAccessMode "ioctl" = Ioctl_+unserializeAccessMode "ASPI" = Aspi+unserializeAccessMode "ATAPI" = Atapi+unserializeAccessMode "CAM" = Cam+unserializeAccessMode "SCSI" = Scsi+unserializeAccessMode "READ_CD" = ReadCd+unserializeAccessMode "READ_10" = Read10+unserializeAccessMode "MMC_RDRW" = MmcReadWrite+unserializeAccessMode "MMC_RDRW_EXCL" = MmcReadWriteExclusive+unserializeAccessMode str = error $ "Storable(AccessMode).peek: unknown key '" ++ str ++ "'"
+ src/Foreign/Libcdio/Disc.hs view
@@ -0,0 +1,256 @@+{-# LANGUAGE ForeignFunctionInterface #-}++{-|+Description: The top-level header for disc-related libcdio calls.++Copyright: (c) 2018-2021 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: stable+Portability: non-portable (requires libcdio)++This module provides informational and metadata functions primarily related to+the layout of data on a physical disc. While both "Foreign.Libcdio.Read" and+"Foreign.Libcdio.CdText" provide more exciting access to the actual data, this+still provides a critical intermediate step between those and the physical+hardware of "Foreign.Libcdio.Device".+++= @disc.h@++== Types+* @discmode_t@ -> 'DiscMode'++ - @CDIO_DISC_MODE_CD_DA@ -> 'AudioCdMode'+ - @CDIO_DISC_MODE_CD_DATA@ -> 'DataCdMode'+ - @CDIO_DISC_MODE_CD_XA@ -> 'XaCdMode'+ - @CDIO_DISC_MODE_CD_MIXED@ -> 'MixedCdMode'+ - @CDIO_DISC_MODE_DVD_ROM@ -> 'DvdRomMode'+ - @CDIO_DISC_MODE_DVD_RAM@ -> 'DvdRamMode'+ - @CDIO_DISC_MODE_DVD_R@ -> 'DvdRecordableMode'+ - @CDIO_DISC_MODE_DVD_RW@ -> 'DvdReWritableMode'+ - @CDIO_DISC_MODE_HD_DVD_ROM@ -> 'HighDefinitionDvdRomMode'+ - @CDIO_DISC_MODE_HD_DVD_RAM@ -> 'HighDefinitionDvdRamMode'+ - @CDIO_DISC_MODE_HD_DVD_R@ -> 'HighDefinitionDvdRecordableMode'+ - @CDIO_DISC_MODE_DVD_PR@ -> 'DvdPlusRecordableMode'+ - @CDIO_DISC_MODE_DVD_PRW@ -> 'DvdPlusReWritableMode'+ - @CDIO_DISC_MODE_DVD_PR_DL@ -> 'DoubleLayerDvdPlusRecordableMode'+ - @CDIO_DISC_MODE_DVD_PRW_DL@ -> 'DoubleLayerDvdPlusReWritableMode'+ - @CDIO_DISC_MODE_DVD_OTHER@ -> 'OtherDvdMode'+ - @CDIO_DISC_MODE_NO_INFO@ -> 'NoModeInfo'+ - @CDIO_DISC_MODE_CD_I@ -> 'CdIMode'+ - @CDIO_DISC_MODE_ERROR@ (removed; handled via 'Nothing')++== Symbols+* @cdio_get_cdtext@ (removed; merged into 'Cdio' objects due to pointer lifespan issues)+* @cdio_get_cdtext_raw@ -> 'cdTextRaw'+* @cdio_get_disc_last_lsn@ -> 'lastLsn'+* @cdio_get_discmode@ -> 'discMode'+* @cdio_get_joliet_level@ -> 'discJolietLevel'+* @cdio_get_mcn@ -> 'cdMcn'+* @cdio_get_num_tracks@ -> 'numTracks'+* @cdio_is_discmode_cdrom@ -> 'isCdRom'+* @cdio_is_discmode_dvd@ -> 'isDvd'+* @discmode2str@ -> 'discModeString'+++= "Sound.Libcdio.Read.Data"++* @cdio_get_cdtext@ -> @"Sound.Libcdio.Read.CdText".'Sound.Libcdio.Read.Data.cdText'@+* 'cdMcn' -> 'Sound.Libcdio.Read.Data.catalogue'+* 'cdTextRaw' -> @"Sound.Libcdio.Read.CdText".'Sound.Libcdio.Read.Data.cdTextRaw'@+* 'lastLsn' -> 'Sound.Libcdio.Read.Data.lastAddress'+* 'mcnLength' (removed; unnecessary low-level detail)+* 'numTracks' -> @"Sound.Libcdio.Track".'Sound.Libcdio.Track.tracks'@+-}+module Foreign.Libcdio.Disc+ ( -- * Types+ DiscMode ( .. )+ , discModeString+ , isCdRom, isDvd+ -- * Data+ , discMode+ , numTracks+ , lastLsn+ , discJolietLevel+ , hasCdText+ , cdTextRaw+ , cdMcn+ , mcnLength+ ) where+++import qualified Control.Monad as N++import qualified Data.ByteString as BS+import qualified Data.Maybe as Y+import qualified Data.Word as W++import qualified Foreign.C.String as C+import qualified Foreign.C.Types as C+import qualified Foreign.Ptr as C++import qualified Foreign.Marshal.Alloc as M+import qualified Foreign.Marshal.Utils as M+import qualified Foreign.Storable as S++import qualified System.IO.Unsafe as IO.Unsafe++import Foreign.Libcdio.CdText+import Foreign.Libcdio.CdText.Binary+import Foreign.Libcdio.Marshal+import Foreign.Libcdio.Track+import Foreign.Libcdio.Types.Enums+import Foreign.Libcdio.Types.Internal+++-- | Filter out @CDIO_DISC_MODE_ERROR@ values to fit the 'Enum'.+invalidDiscMode :: CDiscMode -> Maybe DiscMode+invalidDiscMode = fmap (toEnum . fromIntegral) . maybeError [invalidDiscMode']++foreign import ccall safe "cdio/compat/disc.h discmode_error"+ invalidDiscMode' :: CDiscMode+++-- | Describe a type a disc according to its official name, as opposed to the+-- machine representation returned by the 'Show' instance.+discModeString :: DiscMode -> String+discModeString = IO.Unsafe.unsafePerformIO .+ C.peekCString . discModeString' . fromIntegral . fromEnum++foreign import ccall safe "cdio/compat/disc.h discmode_string"+ discModeString' :: CDiscMode -> C.CString+++-- | Get the raw CD-Text binary data contained on a disc.+cdTextRaw :: Cdio -> IO (Maybe BS.ByteString)+cdTextRaw c = withCdTextBlob c cdTextRaw' >>= maybe (serialize c) (return . Just)++foreign import ccall safe "cdio/compat/disc.h get_cdtext_raw_len"+ cdTextRaw' :: C.Ptr Cdio -> C.Ptr (C.Ptr C.CChar) -> C.Ptr C.CInt -> IO ()++-- | Allocate a dummy pointer to have somewhere to store the return value.+withCdTextBlob :: Cdio -> (C.Ptr Cdio -> C.Ptr (C.Ptr C.CChar) -> C.Ptr C.CInt -> IO ()) -> IO (Maybe BS.ByteString)+withCdTextBlob c f = M.alloca $ \p' -> M.alloca $ \i' -> do+ y <- withCdio c $ \c' -> f c' p' i'+ if Y.isNothing y+ then return Nothing+ else do+ p <- S.peek p'+ i <- S.peek i'+ if p == C.nullPtr+ then return Nothing+ else do+ bs <- BS.packCStringLen (C.plusPtr p 4, fromIntegral i)+ M.free p+ return $ Just bs++-- | If the @cdio_get_cdtext_raw@ call fails to provide a valid+-- 'BS.ByteString', but we can access the stringified CDTEXT, generate one+-- ourselves. This is necessary as, if the CDTEXT wasn't binary to begin with+-- (i.e. in an image file), libcdio is a bit lazy and doesn't return anything.+serialize :: Cdio -> IO (Maybe BS.ByteString)+serialize x = do+ ls <- listAllLanguages x+ ps <- N.forM [0 .. fromIntegral (length ls) - 1] $ \i -> do+ b <- selectLanguageIndex x i+ if b then serializeLanguage x i else return (0, [])+ let (ss, bss) = unzip ps+ return $ case map checksum $ concatMap (joinBlockInfo ls ss) bss of+ [] -> Nothing+ bs -> Just $ BS.concat bs++-- | Retrieve all data from the current CDTEXT block and render it to the pack+-- format used by the binary representation. For convenience, the highest+-- sequence number used by this block is also returned.+serializeLanguage :: Cdio -> Word -> IO (W.Word8, [BS.ByteString])+serializeLanguage x i = do+ t1 <- Y.fromMaybe 1 <$> firstTrack x+ tl <- Y.fromMaybe 0 <$> lastTrack x+ di <- serializeInfo x Nothing+ tis <- mapM (serializeInfo x . Just) [t1..tl]+ c <- cdTextGet x DiscId Nothing+ g <- genre x+ gs <- cdTextGet x GenreName Nothing+ let ps = packCdTextBlock i c t1 g gs di tis+ return (fromIntegral . max 0 $ length ps - 1, ps)++-- | Retrieve all text packs defined in the current block for the given track,+-- and pack them into an easy-to-pass-around datatype.+serializeInfo :: Cdio -> Maybe Track -> IO Info+serializeInfo x t = do+ n <- cdTextGet x Title t+ p <- cdTextGet x Performer t+ s <- cdTextGet x Songwriter t+ c <- cdTextGet x Composer t+ a <- cdTextGet x Arranger t+ m <- cdTextGet x Message t+ o <- cdTextGet x (if Y.isNothing t then UpcEan else Isrc) t+ return $ Info n p s c a m o+++-- | Determine which type of disc is being accessed. Note that while this+-- provides a general direction, it shouldn't be relied upon for actual reading+-- of data; use 'Foreign.Libcdio.Track.trackFormat' for more granular info.+discMode :: Cdio -> IO (Maybe DiscMode)+discMode c = (>>= invalidDiscMode) <$> withCdio c discMode'++foreign import ccall safe "cdio/compat/disc.h cdio_get_discmode"+ discMode' :: C.Ptr Cdio -> IO CDiscMode+++-- | Get the size of a disc in blocks, or equivalently the address of the end+-- of the readable data.+lastLsn :: Cdio -> IO (Maybe Lsn)+lastLsn c = (>>= invalidZeroLsn) <$> withCdio c lastLsn'++foreign import ccall safe "cdio/compat/disc.h cdio_get_disc_last_lsn"+ lastLsn' :: C.Ptr Cdio -> IO C.CInt+++-- | The original ISO 9660 (data) filesystem specification was rather+-- restrictive in what files could be named; the Joliet extensions allow such+-- exciting features as lowercase letters, not to mention full Unicode support.+discJolietLevel :: Cdio -> IO (Maybe Word)+discJolietLevel c = (>>= maybeError [0] . fromIntegral) <$> withCdio c discJolietLevel'++foreign import ccall safe "cdio/compat/disc.h cdio_get_joliet_level"+ discJolietLevel' :: C.Ptr Cdio -> IO C.CUChar+++-- | Get the media catalog number from a disc. This may also be retrieved+-- by @'Foreign.Libcdio.CdText.getField' 'Foreign.Libcdio.CdText.UpcEan'+-- 'Nothing'@, though that references a different source and thus may not have+-- the same return value.+cdMcn :: Cdio -> IO (Maybe String)+cdMcn c = withCdio c cdMcn' >>= maybe (return Nothing) (M.maybePeek peekFString)++foreign import ccall safe "cdio/compat/disc.h cdio_get_mcn"+ cdMcn' :: C.Ptr Cdio -> IO C.CString+++-- | Get the number of tracks on a CD.+-- +-- Returns 'Nothing' if the 'Cdio' object has already been closed, or if the+-- disc table of contents can't be read.+numTracks :: Cdio -> IO (Maybe Track)+numTracks c = (>>= invalidTrack) <$> withCdio c numTracks'++foreign import ccall safe "cdio/compat/disc.h cdio_get_num_tracks"+ numTracks' :: C.Ptr Cdio -> IO C.CUChar+++-- | Return true if a 'DiscMode' refers to some sort of CD.+isCdRom :: DiscMode -> Bool+isCdRom = M.toBool . isCdRom' . fromIntegral . fromEnum++foreign import ccall safe "cdio/compat/disc.h cdio_is_discmode_cdrom"+ isCdRom' :: CDiscMode -> C.CUChar++-- | Return true if a 'DiscMode' refers to some sort of DVD.+isDvd :: DiscMode -> Bool+isDvd = M.toBool . isDvd' . fromIntegral . fromEnum++foreign import ccall safe "cdio/compat/disc.h cdio_is_discmode_dvd"+ isDvd' :: CDiscMode -> C.CUChar
+ src/Foreign/Libcdio/Logging.hs view
@@ -0,0 +1,166 @@+{-# LANGUAGE ForeignFunctionInterface #-}++{-|+Description: Control over and access to library log output.++Copyright: (c) 2020-2021 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: stable+Portability: non-portable (requires libcdio)++The underlying library is rather loud in its error and warning messages,+potentially emitting a lot of impure terminal clutter even on some+otherwise-pure functions. Very helpfully, it also provides a mechanism for+integrating the logs with whatever framework is in place for the larger+project; that mechanism can be leveraged to cache the logs in memory until+specifically asked for, at which point they can be packaged into Haskell types.+Some of the immediacy—and therefore user ability to match note to source—is+unfortunately lost, but the apparent purity is worth it.+++= @logging.h@++== Types+* @cdio_log_level_t@ -> 'Foreign.Libcdio.Logging.LogLevel'++== Symbols+* @cdio_default_log_handler@ (removed; always handled through 'Foreign.Libcdio.Logging.readLog')+* @cdio_assert@ -> @'Foreign.Libcdio.Logging.putLog' 'Forign.Libcdio.Logging.LogAssert'@+* @cdio_debug@ -> @'Foreign.Libcdio.Logging.putLog' 'Forign.Libcdio.Logging.LogDebug'@+* @cdio_error@ -> @'Foreign.Libcdio.Logging.putLog' 'Forign.Libcdio.Logging.LogError'@+* @cdio_info@ -> @'Foreign.Libcdio.Logging.putLog' 'Forign.Libcdio.Logging.LogInfo'@+* @cdio_log@ -> 'Foreign.Libcdio.Logging.putLog'+* @cdio_log_set_handler@ (removed; always handled through 'Foreign.Libcdio.Logging.readLog')+* @cdio_loglevel_default@ -> 'Foreign.Libcdio.Logging.logCutoff' and 'Foreign.Libcdio.Logging.setLogCutoff'+* @cdio_warn@ -> @'Foreign.Libcdio.Logging.putLog' 'Forign.Libcdio.Logging.LogWarn'@+++= "Sound.Libcdio.Logging"+Most functions have been re-contextulized as being provided through a+'Sound.Libcdio.Logging.LibcdioLogger' instance, but the interface is otherwise+unchanged.+-}+module Foreign.Libcdio.Logging+ ( -- * Types+ LogEntry ( .. )+ , LogLevel ( .. )+ -- * Message interaction+ , putLog+ , readLog+ , clearLog+ -- * Management+ , logCutoff+ , setLogCutoff+ , setupLogger+ ) where+++import qualified Control.Monad as N++import qualified Data.Maybe as Y++import qualified Foreign.C.String as C+import qualified Foreign.C.Types as C+import qualified Foreign.Ptr as C++import qualified Foreign.Marshal.Array as M+import qualified Foreign.Marshal.Utils as M+import qualified Foreign.Storable as S++import Foreign.Libcdio.Marshal+import Foreign.Libcdio.Types.Enums+import Foreign.Libcdio.Types.Offsets+++-- | Check the current minimum severity which will be recorded in the logs.+--+-- See 'setLogCutoff'.+logCutoff :: IO LogLevel+logCutoff = toEnum . fromIntegral <$> logCutoff'++foreign import ccall safe "cdio/compat/logging.h get_cdio_log_level"+ logCutoff' :: IO CLogLevel+++-- | Set the minimum severity required for a message to be recorded in the+-- logs.+--+-- See 'logCutoff'.+setLogCutoff :: LogLevel -> IO ()+setLogCutoff = setLogCutoff' . fromIntegral . fromEnum++foreign import ccall safe "cdio/compat/logging.h set_cdio_log_level"+ setLogCutoff' :: CLogLevel -> IO ()+++-- | An unstructured message emitted from the library to let the user know+-- what's going on behind the scenes.+data LogEntry = LogEntry+ { logLevel :: LogLevel+ -- ^ How critical it is that the user receive this particular message.+ , logMessage :: String+ -- ^ The text of the message itself.+ }+ deriving ( Eq, Show, Read )+instance S.Storable LogEntry where+ sizeOf _ = leSizeOf+ alignment _ = leAlign+ peek c = do+ l <- S.peekByteOff c leLevel :: IO CLogLevel+ m' <- S.peekByteOff c leMessage+ m <- if m' == C.nullPtr+ then return ""+ else C.peekCString m'+ return $ LogEntry+ { logLevel = toEnum $ fromIntegral l+ , logMessage = m+ }+ poke c hs = do+ S.pokeByteOff c leLevel (fromIntegral . fromEnum $ logLevel hs :: CLogLevel)+ m <- C.newCString $ logMessage hs+ S.pokeByteOff c leMessage m+ S.pokeByteOff c lePrevious C.nullPtr+++-- | Retrieve all messages currently in the log for further processing. Note+-- that this retains the contents of the log for future calls; to remove them,+-- a separate call to 'clearLog' must be made.+--+-- >>> setupLogger+-- >>> putLog $ LogEntry LogWarn "Testing log reading"+-- >>> readLog+-- [LogEntry LogWarn "Testing log reading"]+-- >>> readLog+-- [LogEntry LogWarn "Testing log reading"]+-- >>> clearLog+-- >>> readLog+-- []+readLog :: IO [LogEntry]+readLog = do+ es' <- readLog'+ es <- Y.fromMaybe [] <$> M.maybePeek (M.peekArray0 C.nullPtr) es'+ N.forM es S.peek++foreign import ccall safe "cdio/compat/logging.h read_cdio_log"+ readLog' :: IO (C.Ptr (C.Ptr LogEntry))+++-- | Empty all messages currently in the log. There is no way to selectively+-- remove only some messages; if that is desired, call 'readLog' first:+--+-- >>> setupLogger+-- >>> msgs <- readLog+-- >>> clearLog+-- >>> mapM_ putLog $ filter p msgs+foreign import ccall safe "cdio/compat/logging.h free_cdio_log"+ clearLog :: IO ()+++-- | Append a message to the logs.+putLog :: LogEntry -> IO ()+putLog e = C.withCString (logMessage e) $ putLog' (fromIntegral . fromEnum $ logLevel e)++foreign import ccall safe "cdio/compat/logging.h cdio_log"+ putLog' :: CLogLevel -> C.CString -> IO ()
+ src/Foreign/Libcdio/Marshal.hs view
@@ -0,0 +1,295 @@+{-# LANGUAGE ForeignFunctionInterface #-}++{-|+Description: Utility functions for the libcdio FFI.++Copyright: (c) 2018-2021 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: provisional+Portability: portable+-}+module Foreign.Libcdio.Marshal+ ( -- * Types+ -- ** Cdio+ Cdio+ , withCdio+ , withCdio_+ , withCdioPtr+ , peekCdio+ -- ** CdText+ , CdText+ , withCdText+ , withCdText'+ , withCdText_+ , hasCdText+ , cdTextDataInit+ -- * Management+ , setupLogger+ , genBitArray+ -- * Marshalling+ -- ** Bool+ , errorOrBool+ , bool3+ -- ** Int+ , errorOrInt+ , maybeError+ -- ** Enum a+ , joinEnumFlags+ , modEnumFlags+ -- ** ByteString+ , peekByteStringLen+ -- ** String+ , allocaStringArray+ -- ** FString+ , peekFString+ , peekFStringArray+ ) where+++import qualified Data.Array.BitArray as A+import qualified Data.Bits as B+import qualified Data.ByteString as BS+import qualified Data.Ix as I+import qualified Data.Maybe as Y++import qualified Foreign.C.String as C+import qualified Foreign.C.Types as C+import qualified Foreign.ForeignPtr as C+import qualified Foreign.Ptr as C++import qualified Foreign.Marshal.Alloc as M+import qualified Foreign.Marshal.Array as M+import qualified Foreign.Marshal.Utils as M++import qualified Foreign.Storable as S+++-- | Helper to convert device capabilities to a bitfield.+genBitArray :: (Bounded a, I.Ix a) => [a] -> A.BitArray a+genBitArray [] = A.false (minBound, maxBound)+genBitArray cs = A.array (minBound, maxBound) $ map (\i -> (i, True)) cs+++-- | A particular disc reading/writing device, along with the data contained+-- on the loaded disc. Note well that this is always a mutable object, and is+-- not thread-safe; moreover, any function this is passed to may wind up+-- silently modifying the data.+data Cdio = Cdio (Maybe (C.ForeignPtr Cdio)) (Maybe (C.ForeignPtr CdText))++-- | Free all memory used by a reference to a device.+foreign import ccall "cdio/compat/device.h &cdio_destroy"+ cdioDestroy :: C.FinalizerPtr Cdio++-- | Convert the (foreign) reference to a device to something the FFI can use.+withCdio :: Cdio -> (C.Ptr Cdio -> IO b) -> IO (Maybe b)+withCdio (Cdio Nothing _) = const $ return Nothing+withCdio (Cdio (Just c) _) = fmap Just . C.withForeignPtr c++withCdio_ :: Cdio -> (C.Ptr Cdio -> IO ()) -> IO ()+withCdio_ c f = withCdio c f >> mempty++-- | Marshall a device reference with an extra layer of indirection.+withCdioPtr :: Cdio -> (C.Ptr (C.Ptr Cdio) -> IO b) -> IO (Maybe b)+withCdioPtr (Cdio Nothing _) _ = return Nothing+withCdioPtr (Cdio (Just c) _) f = M.alloca $ \p ->+ C.withForeignPtr c $ \c' -> do+ S.poke p c'+ Just <$> f p++-- | Un-marshall a newly-allocated pointer to a drive.+peekCdio :: C.Ptr Cdio -> IO Cdio+peekCdio c = do+ -- All public methods of opening 'Cdio' objects already have this earlier to+ -- catch any logs from opening the disc, but add it again just to be safe.+ setupLogger+ x <- M.maybePeek getCdText' c+ x' <- case x of+ Just x' -> Just <$> C.newForeignPtr_ x'+ Nothing -> return Nothing+ p' <- C.newForeignPtr cdioDestroy c+ return $ Cdio (Just p') x'++foreign import ccall "cdio/compat/disc.h cdio_get_cdtext"+ getCdText' :: C.Ptr Cdio -> IO (C.Ptr CdText)+++-- | Initialize the log-management backend to use the mechanisms provided by+-- this library instead of just printing to standard output. While this will+-- usually be taken care of automatically, it may still be necessary to call+-- this explicitly if messages are being recorded before any disc session is+-- opened.+foreign import ccall "cdio/compat/logging.h setup_cdio_logger"+ setupLogger :: IO ()+++-- | The metadata describing the contents of a disc.+-- +-- This type is not exported, and is mainly here to catch copy-paste errors on+-- my end.+data CdText++-- | Free all memory used by a reference to a device.+foreign import ccall "cdio/compat/cdtext.h &cdtext_destroy"+ cdTextDestroy :: C.FinalizerPtr CdText++-- | Convert the (foreign) reference to a device to something the FFI can use.+withCdText :: Cdio -> (C.Ptr CdText -> IO b) -> IO (Maybe b)+withCdText (Cdio _ Nothing) = const $ return Nothing+withCdText (Cdio _ (Just x)) = fmap Just <$> C.withForeignPtr x++withCdText' :: b -> Cdio -> (C.Ptr CdText -> IO b) -> IO b+withCdText' b c = fmap (Y.fromMaybe b) . withCdText c++withCdText_ :: Cdio -> (C.Ptr CdText -> IO ()) -> IO ()+withCdText_ c f = withCdText c f >> mempty++-- | Whether the various functions in "Foreign.Libcdio.CdText" will have any+-- effect, or simply return 'mempty'.+hasCdText :: Cdio -> Bool+hasCdText (Cdio _ x) = Y.isJust x+++-- | Read binary CD-TEXT data into a structured datatype.+--+-- Note that binary CdText dumps will frequently include four bytes at the+-- beginning indicating the size of the file; this implementation expects that+-- those bytes /are not/ included. If your dump does include them, @'BS.drop'+-- 4@ before passing the 'BS.ByteString' to this function.+-- +-- /Before libcdio 0.94: Always returns 'Nothing'/+cdTextDataInit :: BS.ByteString -> IO (Maybe Cdio)+cdTextDataInit bs = do+ setupLogger+ x <- cdTextInit' >>= C.newForeignPtr cdTextDestroy+ b <- BS.useAsCStringLen bs $ \(bs', l) -> withCdText (Cdio Nothing $ Just x) $ \x' ->+ cdTextDataInit' x' bs' $ fromIntegral l+ return $ if b == Just 0+ then Just . Cdio Nothing $ Just x+ else Nothing++-- | Create a new empty CDTEXT object.+foreign import ccall "cdio/compat/cdtext.h cdtext_init"+ cdTextInit' :: IO (C.Ptr CdText)++foreign import ccall safe "cdio/compat/cdtext.h cdtext_data_init_safe"+ cdTextDataInit' :: C.Ptr CdText -> C.Ptr C.CChar -> C.CSize -> IO C.CInt+++-- | Free the memory indicated by a C-style pointer, avoiding a segfault if+-- passed a @NULL@ pointer.+cdioFree :: C.Ptr a -> IO ()+cdioFree = mkFree cdioFree'++foreign import ccall "cdio/memory.h &cdio_free"+ cdioFree' :: C.FunPtr (C.Ptr a -> IO ())++-- | Retrieve the actual function with a @free@-style signature.+foreign import ccall "dynamic"+ mkFree :: C.FunPtr (C.Ptr a -> IO ()) -> C.Ptr a -> IO ()+++-- | Convert a return code indicating an error or success/failure into a+-- type-safe representation.+errorOrBool :: (Integral a, Enum b) => a -> Either b Bool+errorOrBool = fmap M.toBool . errorOrInt+++-- | Convert the custom indeterminate boolean to more ideomatic Haskell.+bool3 :: C.CInt -> Maybe Bool+bool3 0 = Just False+bool3 1 = Just True+bool3 _ = Nothing+++-- | Convert a return code indicating an error or a numeric value into a+-- type-safe representation.+errorOrInt :: (Integral a, Enum b) => a -> Either b a+errorOrInt i+ | i < 0 = Left . toEnum $ fromIntegral i+ | otherwise = Right i++-- | Filter out an error value expressed as part of a C-style enum.+maybeError :: Eq a => [a] -> a -> Maybe a+maybeError es i+ | elem i es = Nothing+ | otherwise = Just i+++-- | Unmarshall a block of binary data from a C-style array with an explicit+-- length. Returns 'Nothing' if the returned size is negative.+peekByteStringLen+ :: (Integral b, S.Storable b)+ => C.Ptr (C.Ptr a)+ -> C.Ptr b+ -> IO (Maybe BS.ByteString)+peekByteStringLen p l = do+ p' <- S.peek p+ l' <- S.peek l+ if l' < 0 || p' == C.nullPtr+ then return Nothing+ else Just <$> BS.packCStringLen (C.castPtr p', fromIntegral l')+++-- | Combine an ordered value and an array of bit flags into a single value.+joinEnumFlags+ :: (Enum a, Enum b, Bounded b, I.Ix b, Integral c, B.Bits c)+ => a+ -> A.BitArray b+ -> c+joinEnumFlags a bs = fromIntegral (fromEnum a) + bs'+ where bs' = foldr set 0x0 . zip [fst bnds .. snd bnds] $ drop fstBit [0..]+ bnds = (minBound, maxBound)+ set (e, i) b = case bs A.!? e of+ Just True -> B.setBit b i+ _ -> b+ fstBit = B.countTrailingZeros . fromEnum $ fst bnds++-- | Split a number into an ordered value (below the 'minBound') and an array+-- of bit flags.+modEnumFlags+ :: (Integral a, B.Bits a, Enum b, Bounded b, Enum c, Bounded c, I.Ix c)+ => a+ -> (Maybe b, A.BitArray c)+modEnumFlags i = (toEnumMaybe $ fromIntegral fs, bs)+ where fs = mod i . fromIntegral . fromEnum $ fst bnds+ bs = A.listArray bnds . map (B.testBit i) . drop fstBit $ take lstBit [0..]+ bnds = (minBound, maxBound)+ fstBit = B.countTrailingZeros . fromEnum $ fst bnds+ lstBit = B.countTrailingZeros . fromEnum $ snd bnds+++-- | Will not work if the 'Enum' instance has been redefined to not be+-- sequential.+-- +-- From <https://stackoverflow.com/a/2744712/7634517>+toEnumMaybe :: (Enum a, Bounded a) => Int -> Maybe a+toEnumMaybe i = if i < fromEnum n || i > fromEnum x+ then Nothing+ else Just e+ where e = toEnum i+ n = asTypeOf minBound e+ x = asTypeOf maxBound e+++-- | Temporarily copy a list of 'String's to pass them to a C function as a+-- @NULL@-terminated array, cleaning up the allocated memory afterward.+allocaStringArray :: [String] -> (C.Ptr C.CString -> IO a) -> IO a+allocaStringArray [] f = f C.nullPtr+allocaStringArray ss f = M.withMany C.withCString ss $ \ss' -> M.withArray0 C.nullPtr ss' f+++-- | Retrieve the value of a C-style string which needs to be manually freed.+peekFString :: C.CString -> IO String+peekFString c = do+ s <- C.peekCString c+ cdioFree c+ return s++-- | Retrieve the values of an array of C-style strings which all need to be+-- manually freed.+peekFStringArray :: C.Ptr C.CString -> IO [String]+peekFStringArray p = do+ ss <- M.maybePeek (M.peekArray0 C.nullPtr) p+ maybe (return []) (mapM peekFString) ss
+ src/Foreign/Libcdio/Read.hs view
@@ -0,0 +1,253 @@+{-# LANGUAGE ForeignFunctionInterface #-}++{-|+Description: Functions providing a means to retrieve the data stored on a disc.++Copyright: (c) 2018-2021 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: stable+Portability: non-portable (requires libcdio)++After obtaining landmarks through "Foreign.Libcdio.Disc" (and likely+"Foreign.Libcdio.Track"), this module provides the functions required to+actually retrive the primary data from the disc. Some knowledge of its+physical layout is required, which may be determined through+'Foreign.Libcdio.Track.trackFormat'.+++= @read.h@++== Types+* @cdio_read_mode_t@ -> 'ReadMode'++ - @CDIO_READ_MODE_M1F1@ -> 'Mode1Form1'+ - @CDIO_READ_MODE_M1F2@ -> 'Mode1Form2'+ - @CDIO_READ_MODE_M2F1@ -> 'Mode2Form1'+ - @CDIO_READ_MODE_M2F2@ -> 'Mode2Form2'++== Symbols+* @cdio_lseek@ -> 'seek'+* @cdio_read@ -> 'readBytes'+* @cdio_read_audio_sector@ -> 'readAudioSector'+* @cdio_read_audio_sectors@ -> 'readAudioSectors'+* @cdio_read_data_sectors@ -> 'readDataSectors'+* @cdio_read_mode1_sector@ -> 'readDataModeSector'+* @cdio_read_mode1_sectors@ -> 'readDataModeSectors'+* @cdio_read_mode2_sector@ -> 'readXaModeSector'+* @cdio_read_mode2_sectors@ -> 'readXaModeSectors'+* @cdio_read_sector@ -> 'readSector'+* @cdio_read_sectors@ -> 'readSectors'+++= "Sound.Libcdio.Read.Data"+Each of the single-sector @read*@ aliases have been removed for consistency.++* 'ReadMode' (removed; unnecessary low-level detail)++* 'readAudioSectors' -> 'Sound.Libcdio.Read.Data.readAudio'+* 'readBytes' -> 'Sound.Libcdio.Read.Data.readRaw' (note that the count is now the number of /sectors/ rather than bytes)+* 'readDataModeSectors' -> 'Sound.Libcdio.Read.Data.readData'+* 'readDataSectors' (removed; unnecessary low-level detail)+* 'readXaModeSectors' -> 'Sound.Libcdio.Read.Data.readXa'+-}+module Foreign.Libcdio.Read+ ( -- * Types+ ReadMode ( .. )+ , Whence ( .. )+ -- * Functions+ -- ** Raw+ , seek+ , readBytes+ -- ** Sector+ , readSector, readSectors+ , readAudioSector, readAudioSectors+ , readDataSectors+ , readDataModeSector, readDataModeSectors+ , readXaModeSector, readXaModeSectors+ ) where+++import qualified Control.Monad as N++import qualified Data.ByteString as BS+import qualified Data.Maybe as Y++import qualified Foreign.C.Types as C+import qualified Foreign.Ptr as C+import qualified Foreign.Storable as S++import qualified Foreign.Marshal.Alloc as M+import qualified Foreign.Marshal.Utils as M++import Foreign.Libcdio.Device+import Foreign.Libcdio.Marshal+import Foreign.Libcdio.Types.Enums+import Foreign.Libcdio.Types.Internal+++-- | Reposition the read pointer in the 'Cdio' session for a future call to+-- 'readBytes'.+seek :: Cdio -> Int -> Whence -> IO (Either DriverReturnCode Word)+seek c o w = do+ o' <- withCdio c $ \c' -> seek' c' (fromIntegral o) (fromIntegral $ fromEnum w)+ return . fmap fromIntegral $ maybe (Left Uninitialized) errorOrInt o'++foreign import ccall safe "cdio/compat/read.h cdio_lseek"+ seek' :: C.Ptr Cdio -> C.CLong -> C.CInt -> IO C.CLong+++collapseReturnCode :: Maybe DriverReturnCode -> a -> Either DriverReturnCode a+collapseReturnCode (Just Success) a = Right a+collapseReturnCode (Just e) _ = Left e+collapseReturnCode Nothing _ = Left Uninitialized+++withCdioByteString+ :: Cdio+ -> (C.Ptr Cdio -> C.Ptr (C.Ptr ()) -> C.Ptr C.CUInt -> IO a)+ -- ^ A foreign function which will read a given number of bytes into a+ -- referenced buffer, potentially returning a numeric error code. Note+ -- that this marshalling /will/ try to free the inner pointer of the+ -- second argument, so the function should @malloc@ a temporary value+ -- accordingly.+ -> IO (Maybe a, Maybe BS.ByteString)+withCdioByteString c g = M.alloca $ \bs' -> M.alloca $ \s' -> do+ a <- withCdio c $ \c' -> g c' bs' s'+ bs <- peekByteStringLen bs' s'+ p <- S.peek bs'+ N.unless (p == C.nullPtr) $ M.free p+ return (a, bs)++-- | Marshalling function for handling read instructions operating on a given+-- number of whole-sector blocks.+readCdioSectors+ :: Cdio+ -> (C.Ptr Cdio -> C.Ptr (C.Ptr ()) -> C.Ptr C.CUInt -> IO C.CInt)+ -> IO (Either DriverReturnCode BS.ByteString)+readCdioSectors c f = do+ (r, bs) <- withCdioByteString c f+ return $ collapseReturnCode (toEnum . fromIntegral <$> r) (Y.fromMaybe BS.empty bs)+++-- | Read a given number of bytes from the disc. With data of a known+-- structure, use 'readSectors' or similar instead, which /don't/ include the+-- headers and footers described in "Foreign.Libcdio.Sector".+readBytes :: Cdio -> Word -> IO (Maybe BS.ByteString)+readBytes c l = fmap snd <$> withCdioByteString c $ \c' bs' s' ->+ readBytes' c' bs' s' $ fromIntegral l++foreign import ccall safe "cdio/compat/read.h read_bytes"+ readBytes' :: C.Ptr Cdio -> C.Ptr (C.Ptr ()) -> C.Ptr C.CUInt -> C.CULong -> IO ()+++-- | Read the data contained in a specific sector from the disc.+readSector :: Cdio -> Lsn -> ReadMode -> IO (Either DriverReturnCode BS.ByteString)+readSector c o m = readCdioSectors c $ \c' bs' s' ->+ readSector' c' bs' s' o (fromIntegral $ fromEnum m)++foreign import ccall safe "cdio/compat/read.h read_sector"+ readSector' :: C.Ptr Cdio -> C.Ptr (C.Ptr ()) -> C.Ptr C.CUInt -> Lsn -> C.CInt -> IO C.CInt++-- | Read the data contained in the given number of sectors from the disc,+-- beginning with the specified sector.+readSectors :: Cdio -> Lsn -> ReadMode -> Word -> IO (Either DriverReturnCode BS.ByteString)+readSectors c o m l = readCdioSectors c $ \c' bs' s' ->+ readSectors' c' bs' s' o (fromIntegral $ fromEnum m) (fromIntegral l)++foreign import ccall safe "cdio/compat/read.h read_sectors"+ readSectors' :: C.Ptr Cdio -> C.Ptr (C.Ptr ()) -> C.Ptr C.CUInt -> Lsn -> C.CInt -> C.CUInt -> IO C.CInt+++-- | Similar to calling 'readSector' with 'AudioMode', depending on the driver+-- implementation.+readAudioSector :: Cdio -> Lsn -> IO (Either DriverReturnCode BS.ByteString)+readAudioSector c o = readCdioSectors c $ \c' bs' s' ->+ readAudioSector' c' bs' s' o++foreign import ccall safe "cdio/compat/read.h read_audio_sector"+ readAudioSector' :: C.Ptr Cdio -> C.Ptr (C.Ptr ()) -> C.Ptr C.CUInt -> Lsn -> IO C.CInt++-- | Similar to calling 'readSectors' with 'AudioMode', depending on the driver+-- implementation.+readAudioSectors :: Cdio -> Lsn -> Word -> IO (Either DriverReturnCode BS.ByteString)+readAudioSectors c o l = readCdioSectors c $ \c' bs' s' ->+ readAudioSectors' c' bs' s' o $ fromIntegral l++foreign import ccall safe "cdio/compat/read.h read_audio_sectors"+ readAudioSectors' :: C.Ptr Cdio -> C.Ptr (C.Ptr ()) -> C.Ptr C.CUInt -> Lsn -> C.CUInt -> IO C.CInt+++-- | Read the raw data from a given number of sectors on the disc, beginning+-- with the specified sector.+readDataSectors+ :: Cdio+ -> Lsn+ -> Word+ -- ^ Sector size (e.g. 'Foreign.Libcdio.Sector.dataSize' or+ -- 'Foreign.Libcdio.Sector.dataSizeRawXa').+ -> Word+ -- ^ Number of sectors to read.+ -> IO (Either DriverReturnCode BS.ByteString)+readDataSectors c o z l = readCdioSectors c $ \c' bs' s' ->+ readDataSectors' c' bs' s' o (fromIntegral z) (fromIntegral l)++foreign import ccall safe "cdio/compat/read.h read_data_sectors"+ readDataSectors' :: C.Ptr Cdio -> C.Ptr (C.Ptr ()) -> C.Ptr C.CUInt -> Lsn -> C.CUShort -> C.CUInt -> IO C.CInt+++-- | Similar to calling 'readSector', depending on the driver implementation.+readDataModeSector+ :: Cdio+ -> Lsn+ -> Bool+ -- ^ If 'True' Form 2, otherwise Form 1 (see "Foreign.Libcdio.Sector").+ -> IO (Either DriverReturnCode BS.ByteString)+readDataModeSector c o m = readCdioSectors c $ \c' bs' s' ->+ readDataModeSector' c' bs' s' o $ M.fromBool m++foreign import ccall safe "cdio/compat/read.h read_mode1_sector"+ readDataModeSector' :: C.Ptr Cdio -> C.Ptr (C.Ptr ()) -> C.Ptr C.CUInt -> Lsn -> C.CUChar -> IO C.CInt++-- | Similar to calling 'readSectors', depending on the driver implementation.+readDataModeSectors+ :: Cdio+ -> Lsn+ -> Bool+ -- ^ If 'True' Form 2, otherwise Form 1 (see "Foreign.Libcdio.Sector").+ -> Word+ -> IO (Either DriverReturnCode BS.ByteString)+readDataModeSectors c o m l = readCdioSectors c $ \c' bs' s' ->+ readDataModeSectors' c' bs' s' o (M.fromBool m) (fromIntegral l)++foreign import ccall safe "cdio/compat/read.h read_mode1_sectors"+ readDataModeSectors' :: C.Ptr Cdio -> C.Ptr (C.Ptr ()) -> C.Ptr C.CUInt -> Lsn -> C.CUChar -> C.CUInt -> IO C.CInt+++-- | Similar to calling 'readSector', depending on the driver implementation.+readXaModeSector+ :: Cdio+ -> Lsn+ -> Bool+ -- ^ If 'True' Form 2, otherwise Form 1 (see "Foreign.Libcdio.Sector").+ -> IO (Either DriverReturnCode BS.ByteString)+readXaModeSector c o m = readCdioSectors c $ \c' bs' s' ->+ readXaModeSector' c' bs' s' o $ M.fromBool m++foreign import ccall safe "cdio/compat/read.h read_mode2_sector"+ readXaModeSector' :: C.Ptr Cdio -> C.Ptr (C.Ptr ()) -> C.Ptr C.CUInt -> Lsn -> C.CUChar -> IO C.CInt++-- | Similar to calling 'readSectors', depending on the driver implementation.+readXaModeSectors+ :: Cdio+ -> Lsn+ -> Bool+ -- ^ If 'True' Form 2, otherwise Form 1 (see "Foreign.Libcdio.Sector").+ -> Word+ -> IO (Either DriverReturnCode BS.ByteString)+readXaModeSectors c o m l = readCdioSectors c $ \c' bs' s' ->+ readXaModeSectors' c' bs' s' o (M.fromBool m) (fromIntegral l)++foreign import ccall safe "cdio/compat/read.h read_mode2_sectors"+ readXaModeSectors' :: C.Ptr Cdio -> C.Ptr (C.Ptr ()) -> C.Ptr C.CUInt -> Lsn -> C.CUChar -> C.CUInt -> IO C.CInt
+ src/Foreign/Libcdio/Sector.hs view
@@ -0,0 +1,674 @@+{-# LANGUAGE ForeignFunctionInterface #-}++{-|+Description: Values related to on-disc data layout: track boundaries, sector sizes, address formats, etc.++Copyright: (c) 2018-2021 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: stable+Portability: non-portable (requires libcdio)++The bulk of this module deals with the sizes of various parts of disc sectors,+and so a brief description of each is likely helpful; for more information, see+the libcdio user guide, or any of the other various documentation that people+have written. Depending on the accuracy required, multiple methods of encoding+data onto discs were developed enabling different degrees of error detection+and recovery. For ease of implementation, these check regions are spaced+evenly throughout the data, effectively dividing it into blocks of 'sectorSize'+bytes. The inner structure of each block is thus:++= Sector layout++== Audio++As audio CDs are intended to be listened to by human ears, often in noisy+environments, byte-perfect fidelity was deemed unnecessary; data fills the+entire sector without leaving room for checksums or synchronization points.+This structure is more technically described as "CD-DA" (Digital Audio).++@+|- 'sectorSize' -|+@++== Data (Mode 1)++The original structure described in the /Yellow Book/ standard. Mode 1, Form 1+is notably the layout used for CD-ROMs. It would be most correct to describe+these as "Mode 1" and "Mode 2" with no reference to form, but the libcdio+documentation has adopted the practice below as a parallel to the XA names.++=== Mode 1, Form 1++@+|------------------------------------ 'sectorSize' -------------------------------------|+ 'syncSize' + 'headerSize' + __'dataSize'__ + 'errorDetectionSize' + 'padSize' + 'errorCorrectionSize'+ |------------------------------- 'syncedSize' -------------------------------|+ |-------------------- 'tailSize' --------------------|+@++=== Mode 1, Form 2++@+|------------ 'sectorSize' -----------|+ 'syncSize' + 'headerSize' + __'dataSizeRaw'__+ |------ 'syncedSize' ------|+@+++== XA (Mode 2)++Developed as a later extension to the Mode 1, Form 2 (technically just "Mode+2") standard above to allow different data to be interleaved.++=== Mode 2, Form 1++@+|--------------------------------------- 'sectorSize' ----------------------------------------|+ 'syncSize' + 'headerSize' + 'subheaderSize' + __'dataSize'__ + 'errorDetectionSize' + 'errorCorrectionSize'+|---------- 'syncHeaderSizeXa' ---------| |-------------- 'tailSizeXa' --------------|+ |------ 'headerSizeXa' ------|+ |---------------------------------- 'syncedSize' ----------------------------------|+ |--------------------------- 'dataSizeRaw' ---------------------------|+@++=== Mode 2, Form 2++@+|--------------------------- 'sectorSize' --------------------------|+ 'syncSize' + 'headerSize' + 'subheaderSize' + __'dataSizeRawXa'__ + 'padSizeXa'+|---------- 'syncHeaderSizeXa' ---------|+ |------ 'headerSizeXa' ------|+ |--------------------- 'syncedSize' ---------------------|+ |-------------- 'dataSizeRaw' --------------|+ |----- 'taggedDataSizeRaw' -----|+@+++= @sector.h@++== Defines+* @CDIO_CD_CHUNK_SIZE@ -> 'chunkSize'+* @CDIO_CD_ECC_SIZE@ -> 'errorCorrectionSize'+* @CDIO_CD_EDC_SIZE@ -> 'errorDetectionSize'+* @CDIO_CD_FRAMESIZE@ -> 'dataSize'+* @CDIO_CD_FRAMESIZE_RAW@ -> 'sectorSize'+* @CDIO_CD_FRAMESIZE_RAW0@ -> 'dataSizeRaw'+* @CDIO_CD_FRAMESIZE_RAW1@ -> 'syncedSize'+* @CDIO_CD_FRAMESIZE_RAWER@ -> 'sectorSizeMax'+* @CDIO_CD_FRAMESIZE_SUB@ -> 'framesizeSub'+* @CDIO_CD_FRAMES_PER_MIN@ -> 'framesPerMin'+* @CDIO_CD_FRAMES_PER_SEC@ -> 'framesPerSec'+* @CDIO_CD_HEADER_SIZE@ -> 'headerSize'+* @CDIO_CD_M1F1_ZERO_SIZE@ -> 'padSize'+* @CDIO_CD_MAX_LSN@ (removed; identical to @'maxBound' :: 'Lsn'@)+* @CDIO_CD_MAX_SESSIONS@ -> 'maxSessions'+* @CDIO_CD_MINS@ -> 'cdMins'+* @CDIO_CD_MIN_LSN@ (removed; identical to @'minBound' :: 'Lsn'@)+* @CDIO_CD_MIN_SESSION_NO@ -> 'minSessionNo'+* @CDIO_CD_NUM_OF_CHUNKS@ -> 'chunksPerSector'+* @CDIO_CD_SECS_PER_MIN@ -> 'secsPerMin'+* @CDIO_CD_SUBHEADER_SIZE@ -> 'subheaderSize'+* @CDIO_CD_SYNC_SIZE@ -> 'syncSize'+* @CDIO_CD_XA_HEADER@ -> 'headerSizeXa'+* @CDIO_CD_XA_SYNC_HEADER@ -> 'syncHeaderSizeXa'+* @CDIO_CD_XA_TAIL@ -> 'tailSizeXa'+* @CDIO_POSTGAP_SECTORS@ -> 'postgapSectors'+* @CDIO_PREGAP_SECTORS@ -> 'pregapSectors'+* @M2F2_SECTOR_SIZE@ -> 'dataSizeRawXa'+* @M2RAW_SECTOR_SIZE@ (removed; identical to 'dataSizeRaw')+* @M2SUB_SECTOR_SIZE@ -> 'taggedDataSizeRaw'+* @msf_t_SIZEOF@ (removed; structural constant not required for Haskell)++== Types+* @cdio_cd_minutes_sectors@ (removed; most values were simple calculations on @CDIO_CD_FRAMES_PER_MIN@, which can be done manually)++ - @CDIO_CD_MAX_SECTORS@ -> 'maxSectors'++* @cdio_subchannel@ -> 'SubchannelData'++ - @CDIO_SUBCHANNEL_SUBQ_DATA@ -> 'QChannelData'++* @flag_t@ -> 'Flags' and 'Flag'++ - @SCMS@ -> 'SerialCopyManagement'++== Symbols+* @CDIO_SECTOR_SYNC_HEADER@ -> 'sectorSyncHeader'+* @cdio_lba_to_lsn@ -> 'lbaToLsn'+* @cdio_lba_to_msf@ -> 'lbaToMsf'+* @cdio_lba_to_msf_str@ -> 'lbaToMsfStr'+* @cdio_lsn_to_lba@ -> 'lsnToLba'+* @cdio_lsn_to_msf@ -> 'lsnToMsf'+* @cdio_msf_to_lba@ -> 'msfToLba'+* @cdio_msf_to_lsn@ -> 'msfToLsn'+* @cdio_msf_to_str@ -> 'msfToStr'+++= "Sound.Libcdio.Read.Data"++* 'Flag' (currently removed; unused in the translated portion of the interface)+* 'Flags' (currently removed; unused in the translated portion of the interface)+* 'Lba' (removed; only one address format is needed, and 'Lsn' is more widespread)+* 'Msf' (removed; only one address format is needed, and timestamps can be confusing for non-audio data)+* 'SubchannelData' (currently removed; unused in the translated portion of the interface)++* 'cdMins' -> 'Sound.Libcdio.Read.Data.maxCdMinutes'+* 'chunkSize' (removed; unnecessary low-level detail)+* 'chunksPerSector' (removed; unnecessary low-level detail)+* 'framesizeSub' (removed; unnecessary low-level detail)+* 'lbaToLsn' (removed; only 'Lsn' is used in @Sound@)+* 'lbaToMsf' (removed; only 'Lsn' is used in @Sound@)+* 'lbaToMsfStr' -> 'Sound.Libcdio.Read.Data.audioTimestamp'+* 'lsnToLba' (removed; only 'Lsn' is used in @Sound@)+* 'lsnToMsf' (removed; only 'Lsn' is used in @Sound@)+* 'maxSectors' -> 'Sound.Libcdio.Read.Data.maxSectors'+* 'maxSessions' (removed; explicit session handling not yet implemented by libcdio)+* 'minSessionNo' (removed; explicit session handling not yet implemented by libcdio)+* 'msfToLba' (removed; only 'Lsn' is used in @Sound@)+* 'msfToLsn' (removed; only 'Lsn' is used in @Sound@)+* 'msfToStr' (removed; only 'Lsn' is used in @Sound@)+* 'postgapSectors' -> 'Sound.Libcdio.Read.Data.defaultPostgapSectors'+* 'pregapSectors' -> 'Sound.Libcdio.Read.Data.defaultPregapSectors'+* 'secsPerMin' (removed; real-world constant)+* 'sectorSyncHeader' (removed; unnecessary low-level detail)+* 'framesPerMin' (removed; simple arithmatic of 'framesPerSec'++All size constants (e.g. 'sectorSize') likewise removed as unnecessary.+-}+module Foreign.Libcdio.Sector+ ( -- * Types+ SubchannelData ( .. )+ , Flags+ , Flag ( .. )+ , Lba+ , Lsn+ , Msf ( .. )+ -- * Conversions+ , lbaToLsn+ , lsnToLba+ , lbaToMsf+ , msfToLba+ , lsnToMsf+ , msfToLsn+ , lbaToMsfStr+ , msfToStr+ -- * Basic counts+ , chunkSize+ , minSessionNo, maxSessions+ , pregapSectors, postgapSectors+ , maxSectors+ , framesizeSub+ -- ** Units of time+ , chunksPerSector+ , framesPerSec+ , secsPerMin+ , framesPerMin+ , cdMins+ -- * Sector blocks+ , sectorSize+ , syncedSize+ , sectorSizeMax+ -- ** Headers+ , sectorSyncHeader+ , syncSize+ , headerSize+ , subheaderSize+ , headerSizeXa+ , syncHeaderSizeXa+ -- ** Data+ , dataSize+ , dataSizeRaw+ , dataSizeRawXa+ , taggedDataSizeRaw+ -- ** Error correction+ , errorDetectionSize+ , errorCorrectionSize+ , padSize+ , padSizeXa+ , tailSize+ , tailSizeXa+ ) where+++import qualified Data.Array.BitArray as A+import qualified Data.ByteString as BS++import qualified Foreign.C.String as C+import qualified Foreign.C.Types as C+import qualified Foreign.Ptr as C++import qualified Foreign.Marshal.Alloc as M+import qualified Foreign.Marshal.Utils as M+import qualified Foreign.Storable as S++import qualified System.IO.Unsafe as IO.Unsafe+++import Foreign.Libcdio.Marshal+import Foreign.Libcdio.Types.Enums+import Foreign.Libcdio.Types.Internal+import Foreign.Libcdio.Types.Offsets+import Foreign.Libcdio.Util+++-- | The collection of metadata describing a particular track.+type Flags = A.BitArray Flag+++-- | The number of sectors spanned by a track pre-gap by default.+pregapSectors :: Word+pregapSectors = fromIntegral pregapSectors'++foreign import ccall safe "cdio/compat/sector.h pregap_sectors"+ pregapSectors' :: C.CUInt++-- | The number of sectors spanned by a track post-gap by default.+postgapSectors :: Word+postgapSectors = fromIntegral postgapSectors'++foreign import ccall safe "cdio/compat/sector.h postgap_sectors"+ postgapSectors' :: C.CUInt+++-- | The typical maximum length of a disc, though it's not a strict limit.+cdMins :: Word+cdMins = fromIntegral cdMins'++foreign import ccall safe "cdio/compat/sector.h cd_mins"+ cdMins' :: C.CUInt++-- | The number of seconds in a minute.+secsPerMin :: Word+secsPerMin = fromIntegral secsPerMin'++foreign import ccall safe "cdio/compat/sector.h secs_per_min"+ secsPerMin' :: C.CUInt++-- | The number of disc sectors comprising a second of audio data.+framesPerSec :: Word+framesPerSec = fromIntegral framesPerSec'++foreign import ccall safe "cdio/compat/sector.h frames_per_sec"+ framesPerSec' :: C.CUInt++-- | The number of bytes in a disc sector's sync header.+syncSize :: Word+syncSize = fromIntegral syncSize'++foreign import ccall safe "cdio/compat/sector.h sync_size"+ syncSize' :: C.CUInt++-- | The size of the smallest meaningful segment of data, in bytes.+chunkSize :: Word+chunkSize = fromIntegral chunkSize'++foreign import ccall safe "cdio/compat/sector.h chunk_size"+ chunkSize' :: C.CUInt++-- | The number of data chunks comprising a disc sector.+chunksPerSector :: Word+chunksPerSector = fromIntegral chunksPerSector'++foreign import ccall safe "cdio/compat/sector.h chunks_per_frame"+ chunksPerSector' :: C.CUInt++-- | The size of a segment of data in the subchannel, in bytes.+framesizeSub :: Word+framesizeSub = fromIntegral framesizeSub'++foreign import ccall safe "cdio/compat/sector.h framesize_sub"+ framesizeSub' :: C.CUInt+++-- | The size of the address of a data sector, in bytes.+headerSize :: Word+headerSize = fromIntegral headerSize'++foreign import ccall safe "cdio/compat/sector.h header_size"+ headerSize' :: C.CUInt++-- | The size of the subheader of an XA sector, in bytes.+subheaderSize :: Word+subheaderSize = fromIntegral subheaderSize'++foreign import ccall safe "cdio/compat/sector.h subheader_size"+ subheaderSize' :: C.CUInt++-- | The size of the EDC error correction segment, in bytes.+errorDetectionSize :: Word+errorDetectionSize = fromIntegral errorDetectionSize'++foreign import ccall safe "cdio/compat/sector.h edc_size"+ errorDetectionSize' :: C.CUInt++-- | The amount of padding between the EDC and ECC segments in a Mode 1 sector,+-- in bytes.+padSize :: Word+padSize = fromIntegral padSize'++foreign import ccall safe "cdio/compat/sector.h mode1_pad_size"+ padSize' :: C.CUInt++-- | The size of the ECC error correction segment, in bytes.+errorCorrectionSize :: Word+errorCorrectionSize = fromIntegral errorCorrectionSize'++foreign import ccall safe "cdio/compat/sector.h ecc_size"+ errorCorrectionSize' :: C.CUInt+++-- | The amount of data which may be contained in a disc sector /with/ error+-- correction, in bytes.+dataSize :: Word+dataSize = fromIntegral dataSize'++foreign import ccall safe "cdio/compat/sector.h framesize"+ dataSize' :: C.CUInt++-- | The size of an entire disc sector, in bytes.+sectorSize :: Word+sectorSize = fromIntegral sectorSize'++foreign import ccall safe "cdio/compat/sector.h framesize_raw"+ sectorSize' :: C.CUInt++-- | The maximum number of bytes that may be returned from a single call.+sectorSizeMax :: Word+sectorSizeMax = fromIntegral sectorSizeMax'++foreign import ccall safe "cdio/compat/sector.h framesize_rawer"+ sectorSizeMax' :: C.CUInt++-- | The size of a disc sector in bytes, ignoring the sync header.+syncedSize :: Word+syncedSize = fromIntegral syncedSize'++foreign import ccall safe "cdio/compat/sector.h framesize_raw1"+ syncedSize' :: C.CUInt++-- | The amount of data which may be contained in a disc sector /without/ error+-- correction, in bytes.+dataSizeRaw :: Word+dataSizeRaw = fromIntegral dataSizeRaw'++foreign import ccall safe "cdio/compat/sector.h framesize_raw0"+ dataSizeRaw' :: C.CUInt+++-- | The total size of the meaningful XA sector headers, in bytes.+headerSizeXa :: Word+headerSizeXa = fromIntegral headerSizeXa'++foreign import ccall safe "cdio/compat/sector.h header_size_xa"+ headerSizeXa' :: C.CUInt++-- | The total size of all data sector error correction segments, in bytes.+tailSize :: Word+tailSize = errorDetectionSize + padSize + errorCorrectionSize++-- | The total size of all XA sector error correction segments, in bytes.+tailSizeXa :: Word+tailSizeXa = fromIntegral tailSizeXa'++foreign import ccall safe "cdio/compat/sector.h tail_size_xa"+ tailSizeXa' :: C.CUInt++-- | The total size of all headers in an XA sector, including the sync marker.+syncHeaderSizeXa :: Word+syncHeaderSizeXa = fromIntegral syncHeaderSizeXa'++foreign import ccall safe "cdio/compat/sector.h sync_size_xa"+ syncHeaderSizeXa' :: C.CUInt++-- | The amount of padding at the end of an XA sector without error correction,+-- in bytes.+padSizeXa :: Word+padSizeXa = dataSizeRaw - taggedDataSizeRaw+++-- | The byte sequence used to mark the start of a disc sector, to allow+-- correcting drift while reading.+sectorSyncHeader :: BS.ByteString+sectorSyncHeader = IO.Unsafe.unsafePerformIO $+ BS.packCStringLen (sectorSyncHeader', fromIntegral syncSize)++foreign import ccall safe "cdio/compat/sector.h sector_sync_header"+ sectorSyncHeader' :: C.Ptr C.CChar+++-- | The amount of data contained in an XA sector without error correction, in+-- bytes.+dataSizeRawXa :: Word+dataSizeRawXa = fromIntegral dataSizeRawXa'++foreign import ccall safe "cdio/compat/sector.h data_size_xa"+ dataSizeRawXa' :: C.CUInt++-- | The size of tagged data (counting the subheader) contained in an XA sector+-- without error correction, in bytes.+taggedDataSizeRaw :: Word+taggedDataSizeRaw = fromIntegral taggedDataSizeRaw'++foreign import ccall safe "cdio/compat/sector.h tagged_size_xa"+ taggedDataSizeRaw' :: C.CUInt+++-- | How many sessions are allowed on a disc.+maxSessions :: Word+maxSessions = fromIntegral maxSessions'++foreign import ccall safe "cdio/compat/sector.h max_session"+ maxSessions' :: C.CUInt++-- | The smallest session number on a disc.+minSessionNo :: Word+minSessionNo = fromIntegral minSessionNo'++foreign import ccall safe "cdio/compat/sector.h min_session"+ minSessionNo' :: C.CUInt+++-- | A shortcut for calculating @'framesPerSec' * 'secsPerMin'@+framesPerMin :: Word+framesPerMin = fromIntegral framesPerMin'++foreign import ccall safe "cdio/compat/sector.h frames_per_min"+ framesPerMin' :: C.CUInt+++-- | The maximum number of sectors allowed to be stored on a disc.+maxSectors :: Word+maxSectors = fromIntegral maxSectors'++foreign import ccall safe "cdio/compat/sector.h max_sectors"+ maxSectors' :: C.CUInt+++-- | Minute\/second\/frame structure for addresses. Generally only makes sense+-- for audio discs.+data Msf = Msf+ { minute :: Word+ , second :: Word+ -- ^ 'secsPerMin'+ , frame :: Word+ -- ^ 'framesPerSec'+ }+ deriving ( Show, Read )+instance Eq Msf where+ l == r = compare l r == EQ+instance Ord Msf where+ compare l r = case minute l' `compare` minute r' of+ EQ -> case second l' `compare` second r' of+ EQ -> frame l' `compare` frame r'+ x -> x+ x -> x+ where l' = normalize l+ r' = normalize r+ normalize msf@(Msf m s f)+ | f >= framesPerSec = normalize $ Msf m (s + div f framesPerSec) (mod f framesPerSec)+ | s >= secsPerMin = Msf (m + div s secsPerMin) (mod s secsPerMin) f+ | otherwise = msf+instance Bounded Msf where+ minBound = Msf 0 0 0+ maxBound = Msf maxBound (secsPerMin - 1) (framesPerSec - 1)+instance S.Storable Msf where+ sizeOf _ = msfSizeOf+ alignment _ = msfAlign+ peek c = do+ m <- S.peekByteOff c msfM+ s <- S.peekByteOff c msfS+ f <- S.peekByteOff c msfF+ return $ Msf (fromBcd8 m) (fromBcd8 s) (fromBcd8 f)+ poke c hs = do+ S.pokeByteOff c msfM . toBcd8 $ minute hs+ S.pokeByteOff c msfS . toBcd8 $ second hs+ S.pokeByteOff c msfF . toBcd8 $ frame hs+instance Enum Msf where+ fromEnum msf = fromInteger+ $ toInteger (frame msf)+ + toInteger (second msf) * fromIntegral framesPerSec+ + toInteger (minute msf) * fromIntegral framesPerMin+ toEnum i = Msf+ { minute = div i' framesPerMin+ , second = flip mod secsPerMin $ div i' framesPerSec+ , frame = mod i' framesPerSec+ }+ where i' = fromIntegral i+ pred (Msf 0 0 0) = error "Enum.pred(Msf): tried to take `pred' of minBound"+ pred (Msf m s f)+ | f >= framesPerSec = pred $ Msf m (s + div f framesPerSec) (mod f framesPerSec)+ | s >= secsPerMin = pred $ Msf (m + div s secsPerMin) (mod s secsPerMin) f+ | f == 0 && s == 0 = Msf (m - 1) (secsPerMin - 1) (framesPerSec - 1)+ | f == 0 = Msf m (s - 1) (framesPerSec - 1)+ | otherwise = Msf m s (f - 1)+ succ msf@(Msf m s f)+ | msf >= maxBound = error "Enum.succ(Msf): tried to take `succ' of maxBound"+ | otherwise = let (fd, fm) = overflow f 1 framesPerSec+ (sd, sm) = overflow s fd secsPerMin+ in Msf (m + sd) sm fm+ where -- Relies on unsigned type, and @y + b < maxBound@+ overflow x y b+ | x > maxBound - y = (div (x - b + y) b + 1, mod (x - b + y) b)+ | otherwise = (div (x + y) b, mod (x + y) b)++{- Use @sizeOf Msf@+msfSizeof :: Word+msfSizeof = fromIntegral msfSizeof'++foreign import ccall safe "cdio/compat/sector.h sizeof_msf_const"+ msfSizeof' :: C.CSize+-}+++{- Never used after definition.+-- | Address in one of the two primary address formats.+data CdromAddr+ = MsfAddr Msf+ | LbaAddr Lba+ deriving ( Eq, Show, Read, Ord )+-- | Note that, while the 'peek' implementation attempts to detect which form+-- the address takes, it may get it wrong and read a 'Msf' address as an 'Lba'+-- or vice versa. If the type is otherwise known, it may be better to read+-- the pointer as that type directly, and wrap into the union manually.+instance S.Storable CdromAddr where+ sizeOf _ = adrSizeOf+ alignment _ = adrAlign+ peek c = do+ msf <- S.peek $ C.castPtr c+ lba <- S.peek $ C.castPtr c+ -- Barring uncleared bits, an LBA has an extra byte.+ if mod 0x100 lba /= 0+ || second msf >= secsPerMin+ || frame msf >= framesPerSec+ then return $ LbaAddr lba+ else return $ MsfAddr msf+ poke c (MsfAddr hs) = S.poke (C.castPtr c) hs+ poke c (LbaAddr hs) = S.poke (C.castPtr c) hs+-}+++-- | Print a logical address as the corresponding timestamp, assuming audio+-- data.+lbaToMsfStr :: Lba -> String+lbaToMsfStr l = IO.Unsafe.unsafePerformIO $+ lbaToMsfStr' (fromIntegral l) >>= peekFString++foreign import ccall safe "cdio/compat/sector.h cdio_lba_to_msf_str"+ lbaToMsfStr' :: CLba -> IO C.CString++-- | Print a disc timestamp in the standard "MM:SS:FF" format.+msfToStr :: Msf -> String+msfToStr msf = IO.Unsafe.unsafePerformIO $+ M.with msf msfToStr' >>= C.peekCString++foreign import ccall safe "cdio/compat/sector.h cdio_msf_to_str"+ msfToStr' :: C.Ptr Msf -> IO C.CString++-- | Convert an LBA address into the corresponding LSN.+lbaToLsn :: Lba -> Lsn+lbaToLsn = fromIntegral . lbaToLsn' . fromIntegral++-- C erroneously returns @lba_t@.+foreign import ccall safe "cdio/compat/sector.h cdio_lba_to_lsn"+ lbaToLsn' :: CLba -> CLba++-- | Convert an LBA address into the corresponding timestamp, assuming audio+-- data.+lbaToMsf :: Lba -> Msf+lbaToMsf l = IO.Unsafe.unsafePerformIO . M.alloca $ \m' ->+ lbaToMsf' (fromIntegral l) m' >> S.peek m'++foreign import ccall safe "cdio/compat/sector.h cdio_lba_to_msf"+ lbaToMsf' :: CLba -> C.Ptr Msf -> IO ()++-- | Convert an LSN address into the corresponding LBA.+lsnToLba :: Lsn -> Lba+lsnToLba = fromIntegral . lsnToLba' . fromIntegral++foreign import ccall safe "cdio/compat/sector.h cdio_lsn_to_lba"+ lsnToLba' :: CLsn -> CLba++-- | Convert an LSN address into the corresponding timestamp, assuming audio+-- data.+lsnToMsf :: Lsn -> Msf+lsnToMsf l = IO.Unsafe.unsafePerformIO . M.alloca $ \m' ->+ lsnToMsf' (fromIntegral l) m' >> S.peek m'++foreign import ccall safe "cdio/compat/sector.h cdio_lsn_to_msf"+ lsnToMsf' :: CLsn -> C.Ptr Msf -> IO ()++-- | Convert a timestamp into the corresponding LBA address, assuming audio+-- data.+msfToLba :: Msf -> Lba+msfToLba = fromIntegral . IO.Unsafe.unsafePerformIO . flip M.with msfToLba'++foreign import ccall safe "cdio/compat/sector.h cdio_msf_to_lba"+ msfToLba' :: C.Ptr Msf -> IO CLsn++-- | Convert a timestamp into the corresponding LSN address, assuming audio+-- data.+msfToLsn :: Msf -> Lsn+msfToLsn = fromIntegral . IO.Unsafe.unsafePerformIO . flip M.with msfToLsn'++foreign import ccall safe "cdio/compat/sector.h cdio_msf_to_lsn"+ msfToLsn' :: C.Ptr Msf -> IO CLsn++{- Not exported+-- | Convert a split timestamp into the corresponding LBA address, assuming+-- audio data.+msf3ToLba :: Word -> Word -> Word -> Lba+msf3ToLba m s f = fromIntegral $ msf3ToLba' (fromIntegral m) (fromIntegral s) (fromIntegral f)++foreign import ccall safe "cdio/compat/sector.h cdio_msf3_to_lba"+ msf3ToLba' :: C.CUInt -> C.CUInt -> C.CUInt -> CLba++-- | Read a timestamp in the form MM:SS:FF into the corresponding LBA address,+-- assuming audio data.+mmssffToLba :: String -> Maybe Lba+mmssffToLba s = invalidLba . IO.Unsafe.unsafePerformIO $ C.withCString s mmssffToLba++foreign import ccall safe "cdio/compat/sector.h cdio_mmssff_to_lba"+ mmssffToLba' :: C.CString -> IO CLba+-}
+ src/Foreign/Libcdio/Track.hs view
@@ -0,0 +1,315 @@+{-# LANGUAGE ForeignFunctionInterface #-}++{-|+Description: Information-gathering on the location and form of disc tracks.++Copyright: (c) 2018-2021 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: stable+Portability: non-portable (requires libcdio)++What many people would think of as the most important division on a CD isn't+quite as an integral a part of the physical data layout: they are described in+a table of contents before the first track of any recording session, and may+have lower-resolution "echoes" in the subchannels alongside the data, but it+would be hard to otherwise recover the track boundaries from the data itself.+This module, then, provides the functions to retrieve that metadata from the+table of contents and from the subchannels.+++= @track.h@++== Defines+* @CDIO_CDROM_CDI_TRACK@ (removed; only has utility in library code)+* @CDIO_CDROM_DATA_TRACK@ (removed; only has utility in library code)+* @CDIO_INVALID_TRACK@ (removed; handled via 'Nothing')+* @CDIO_CDROM_LBA@ (removed; only has utility in library code)+* @CDIO_CDROM_LEADOUT_TRACK@ -> 'DiscLeadout'+* @CDIO_CDROM_MSF@ (removed; only has utility in library code)+* @CDIO_CDROM_XA_TRACK@ (removed; only has utility in library code)+* @CDIO_CD_MAX_TRACKS@ -> 'maxTrack'+* @CDIO_CD_MIN_TRACK_NO@ -> 'minTrack'++== Types+* @track_flag_t@ -> 'Maybe' 'Bool' (CDIO_TRACK_FLAG_ERROR is never used in library code)+* @track_flags_t@ (removed; never used in the public interface)+* @track_format_t@ -> 'TrackFormat'++ -@TRACK_FORMAT_PSX@ -> 'FormatPlaystation'+ -@TRACK_FORMAT_ERROR@ (removed; handled via 'Nothing')++* @trackmode_t@ (removed; never used in the public API)++== Symbols+* @cdio_get_first_track_num@ -> 'firstTrackNum'+* @cdio_get_last_track_num@ -> 'lastTrackNum'+* @cdio_get_track@ -> 'trackAt'+* @cdio_get_track_channels@ -> 'numChannels'+* @cdio_get_track_copy_permit@ -> 'copyPermit'+* @cdio_get_track_format@ -> 'trackFormat'+* @cdio_get_track_green@ -> 'isGreen'+* @cdio_get_track_isrc@ -> 'trackIsrc'+* @cdio_get_track_last_lsn@ -> 'trackLastLsn'+* @cdio_get_track_lba@ -> 'trackLba'+* @cdio_get_track_lsn@ -> 'trackLsn'+* @cdio_get_track_msf@ -> 'trackMsf'+* @cdio_get_track_preemphasis@ -> 'hasPreemphasis'+* @cdio_get_track_pregap_lba@ -> 'pregapLba'+* @cdio_get_track_pregap_lsn@ -> 'pregapLsn'+* @cdio_get_track_sec_count@ -> 'sectorCount'+* @track_format2str@ -> 'trackFormatString'+++= "Sound.Libcdio.Track"++* 'firstTrackNum' -> 'Sound.Libcdio.Track.firstDiscTrack'+* 'isrcLength' (removed; unnecessary low-level detail)+* 'lastTrackNum' -> 'Sound.Libcdio.Track.lastDiscTrack'+* 'numChannels' -> 'Sound.Libcdio.Track.quadAudio'+* 'pregapLba' (removed; only 'Lsn' is used in @Sound@)+* 'pregapLsn' -> 'Sound.Libcdio.Track.pregap'+* 'sectorCount' -> 'Sound.Libcdio.Track.totalLength'+* 'trackFormat' -> 'Sound.Libcdio.Track.format'+* 'trackIsrc' -> @"Sound.Libcdio.Read.Data".'Sound.Libcdio.Read.Data.isrc'@+* 'trackLastLsn' -> 'Sound.Libcdio.Track.offsetEnd'+* 'trackLba' (removed; only 'Lsn' is used in @Sound@)+* 'trackLsn' -> 'Sound.Libcdio.Track.offset'+* 'trackMsf' (removed; only 'Lsn' is used in @Sound@)+-}+module Foreign.Libcdio.Track+ ( -- * Types+ Track ( .. )+ , TrackNum+ , minTrack+ , maxTrack+ , TrackFormat ( .. )+ , trackFormatString+ -- * Location+ , firstTrackNum+ , lastTrackNum+ , trackAt+ , trackLba, trackLsn+ , trackMsf+ , trackLastLsn+ , pregapLba, pregapLsn+ , sectorCount+ -- * Data+ , trackFormat, isGreen+ , hasPreemphasis+ , copyPermit+ , numChannels+ , trackIsrc+ , isrcLength+ ) where+++import qualified Foreign.C.String as C+import qualified Foreign.C.Types as C+import qualified Foreign.Ptr as C++import qualified Foreign.Marshal.Alloc as M+import qualified Foreign.Marshal.Utils as M+import qualified Foreign.Storable as S++import qualified System.IO.Unsafe as IO.Unsafe++import Foreign.Libcdio.Marshal+import Foreign.Libcdio.Sector+import Foreign.Libcdio.Types.Enums+import Foreign.Libcdio.Types.Internal++import Sound.Libcdio.Common+++withCdioTrack :: (C.Ptr Cdio -> CTrack -> IO a) -> (a -> Maybe b) -> Cdio -> Track -> IO (Maybe b)+withCdioTrack f g c = fmap (>>= g) . withCdio c . flip f . withTrack+++-- | Filter out @TRACK_FORMAT_ERROR@ values to fit the 'Enum'.+invalidFormat :: CTrackFormat -> Maybe TrackFormat+invalidFormat = fmap (toEnum . fromIntegral) . maybeError [trackFormatError]++foreign import ccall safe "cdio/compat/track.h track_format_error"+ trackFormatError :: CTrackFormat++-- | Describe the data layout of a 'Track' in a human-readable manner, as+-- opposed to the machine representation returned by the 'Show' instance.+trackFormatString :: TrackFormat -> String+trackFormatString = IO.Unsafe.unsafePerformIO .+ C.peekCString . trackFormatString' . fromIntegral . fromEnum++foreign import ccall safe "cdio/compat/track.h track_format_string"+ trackFormatString' :: CTrackFormat -> C.CString+++-- | Give up a small amount of nuance in order to use standard types.+fromTrackFlagStatus :: Integral a => a -> Maybe Bool+fromTrackFlagStatus c = case toEnum $ fromIntegral c of+ FlagTrue -> Just True+ FlagFalse -> Just False+ _ -> Nothing+++-- | The number of the first track on the disc. This will almost always be 1,+-- but that is not strictly guaranteed; the (perhaps theoretical) example is of+-- a multi-disc set, where later discs pick the numbering back up where the+-- previous one left off.+-- +-- Returns 'Nothing' if the 'Cdio' object has already been closed, or if the+-- disc table of contents can't be read.+firstTrackNum :: Cdio -> IO (Maybe Track)+firstTrackNum c = (>>= invalidTrack) <$> withCdio c firstTrackNum'++foreign import ccall safe "cdio/compat/track.h cdio_get_first_track_num"+ firstTrackNum' :: C.Ptr Cdio -> IO CTrack++-- | The number of the last track on the disc.+-- +-- Returns 'Nothing' if the 'Cdio' object has already been closed, or if the+-- disc table of contents can't be read.+lastTrackNum :: Cdio -> IO (Maybe Track)+lastTrackNum c = (>>= invalidTrack) <$> withCdio c lastTrackNum'++foreign import ccall safe "cdio/compat/track.h cdio_get_last_track_num"+ lastTrackNum' :: C.Ptr Cdio -> IO CTrack+++-- | The track which contains the given address.+-- +-- Returns 'Nothing' if the 'Cdio' object has already been closed, or if the+-- address is beyond the written data on the disc. Note that 'DiscLeadout' is+-- treated as if it were a single sector long:+-- +-- >>> Just endTrack <- lastTrackNum cdio+-- >>> Just endAddr <- trackLastLsn cdio endTrack+-- >>> trackAt cdio $ endAddr + 1+-- Just DiscLeadout+-- >>> trackAt cdio $ endAddr + 2+-- Nothing+trackAt :: Cdio -> Lsn -> IO (Maybe Track)+trackAt c = fmap (>>= invalidTrack) . withCdio c . flip trackAt' . fromIntegral++foreign import ccall safe "cdio/compat/track.h cdio_get_track"+ trackAt' :: C.Ptr Cdio -> C.CInt -> IO CTrack+++-- | The number of channels in the given track; either 2 or 4 per the standard.+numChannels :: Cdio -> Track -> IO (Maybe Word)+numChannels = withCdioTrack numChannels' numChannelsError++-- | The user doesn't care about which type of error it is here.+numChannelsError :: (Integral a, Integral b) => a -> Maybe b+numChannelsError i+ | i < 0 = Nothing+ | otherwise = Just $ fromIntegral i++foreign import ccall safe "cdio/compat/track.h cdio_get_track_channels"+ numChannels' :: C.Ptr Cdio -> CTrack -> IO C.CInt+++-- | Whether the track may be legally copied.+copyPermit :: Cdio -> Track -> IO (Maybe Bool)+copyPermit = withCdioTrack copyPermit' fromTrackFlagStatus++foreign import ccall safe "cdio/compat/track.h cdio_get_track_copy_permit"+ copyPermit' :: C.Ptr Cdio -> CTrack -> IO C.CInt+++-- | Whether preemphasis has been applied to the track for noise reduction.+hasPreemphasis :: Cdio -> Track -> IO (Maybe Bool)+hasPreemphasis = withCdioTrack hasPreemphasis' fromTrackFlagStatus++foreign import ccall safe "cdio/compat/track.h cdio_get_track_preemphasis"+ hasPreemphasis' :: C.Ptr Cdio -> CTrack -> IO C.CInt+++-- | The raw data structure of a track.+trackFormat :: Cdio -> Track -> IO (Maybe TrackFormat)+trackFormat = withCdioTrack trackFormat' invalidFormat++foreign import ccall safe "cdio/compat/track.h cdio_get_track_format"+ trackFormat' :: C.Ptr Cdio -> CTrack -> IO C.CInt+++-- | Whether the track data was stored using the Green Book (CD-i) standard.+isGreen :: Cdio -> Track -> IO (Maybe Bool)+isGreen c t = do+ f <- firstTrackNum c+ l <- lastTrackNum c+ if Just t < f || Just t > l+ then return Nothing+ else withCdioTrack isGreen' (Just . M.toBool) c t++foreign import ccall safe "cdio/compat/track.h cdio_get_track_green"+ isGreen' :: C.Ptr Cdio -> CTrack -> IO C.CUChar+++-- | The address of the end of the given track.+trackLastLsn :: Cdio -> Track -> IO (Maybe Lsn)+trackLastLsn = withCdioTrack trackLastLsn' invalidLsn++foreign import ccall safe "cdio/compat/track.h cdio_get_track_last_lsn"+ trackLastLsn' :: C.Ptr Cdio -> CTrack -> IO C.CInt++-- | The address of the start of the given track.+trackLba :: Cdio -> Track -> IO (Maybe Lba)+trackLba = withCdioTrack trackLba' invalidLba++foreign import ccall safe "cdio/compat/track.h cdio_get_track_lba"+ trackLba' :: C.Ptr Cdio -> CTrack -> IO C.CInt++-- | The address of the start of the given track.+trackLsn :: Cdio -> Track -> IO (Maybe Lsn)+trackLsn = withCdioTrack trackLsn' invalidLsn++foreign import ccall safe "cdio/compat/track.h cdio_get_track_lsn"+ trackLsn' :: C.Ptr Cdio -> CTrack -> IO C.CInt++-- | The address of the start of any pregap before the given track.+pregapLba :: Cdio -> Track -> IO (Maybe Lba)+pregapLba = withCdioTrack pregapLba' invalidLba++foreign import ccall safe "cdio/compat/track.h cdio_get_track_pregap_lba"+ pregapLba' :: C.Ptr Cdio -> CTrack -> IO C.CInt++-- | The address of the start of any pregap before the given track.+pregapLsn :: Cdio -> Track -> IO (Maybe Lsn)+pregapLsn = withCdioTrack pregapLsn' invalidLsn++foreign import ccall safe "cdio/compat/track.h cdio_get_track_pregap_lsn"+ pregapLsn' :: C.Ptr Cdio -> CTrack -> IO C.CInt+++-- | The International Standard Recording Code the given track. This may also+-- be retrieved by @'Foreign.Libcdio.CdText.getField'+-- 'Foreign.Libcdio.CdText.Isrc' $ 'Just' t@, though that references a+-- different source and thus may not have the same return value.+trackIsrc :: Cdio -> Track -> IO (Maybe String)+trackIsrc c t = withCdio c (flip trackIsrc' $ withTrack t) >>=+ maybe (return Nothing) (M.maybePeek peekFString)++foreign import ccall safe "cdio/compat/track.h cdio_get_track_isrc"+ trackIsrc' :: C.Ptr Cdio -> CTrack -> IO C.CString+++-- | The timestamp at which the given track begins.+trackMsf :: Cdio -> Track -> IO (Maybe Msf)+trackMsf c t = M.alloca $ \m' -> do+ b <- withCdio c $ \c' -> trackMsf' c' (withTrack t) m'+ case M.toBool <$> b of+ Just True -> M.maybePeek S.peek m'+ _ -> return Nothing++foreign import ccall safe "cdio/compat/track.h cdio_get_track_msf"+ trackMsf' :: C.Ptr Cdio -> CTrack -> C.Ptr Msf -> IO CBool+++-- | The number of sectors "assigned" to the specified track, including any in+-- the pregap between it and the following one.+sectorCount :: Cdio -> Track -> IO (Maybe Word)+sectorCount = withCdioTrack sectorCount' $ maybeError [0] . fromIntegral++foreign import ccall safe "cdio/compat/track.h cdio_get_track_sec_count"+ sectorCount' :: C.Ptr Cdio -> CTrack -> IO C.CUInt
+ src/Foreign/Libcdio/Types.hs view
@@ -0,0 +1,115 @@+{-# OPTIONS_HADDOCK not-home #-}++{-|+Description: Common types used in the module-mirroring interface.++Copyright: (c) 2020-2021 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: stable+Portability: non-portable (requires libcdio)++The original header defined a rather heterogeneous collection of typedefs,+enums, and preprocessor macros, none of which provide much utility when+separated from their associated functions. Instead of following that design+decision (which only makes sense under the C @#include@ model), this module+instead exports every type used by the interface /without/ any constructors or+associated functions, for any type signatures which may expose an object only+in passing it along.+++= @types.h@++== Defines+* @CDIO_INVALID_LBA@ (removed; handled via 'Nothing')+* @CDIO_INVALID_LSN@ (removed; handled via 'Nothing')+* @CDIO_INVALID_SESSION@ (removed; handled via 'Nothing')+* @CDIO_ISRC_SIZE@ -> @"Foreign.Libcdio.Track".'isrcLength'@+* @CDIO_MCN_SIZE@ -> @"Foreign.Libcdio.Disc".'mcnLength'@+* @__cd_offsetof@ (removed; structural calculation encapsulated behind the scenes)++== Types+* @CdioDataFree_t@ (removed; pointer handling is encapsulated behind the scenes)+* @bitfield_t@ (removed; accomplished with greater safety through "Data.Array.BitArray")+* @bool_3way_t@ -> 'Maybe' 'Bool'++ - @nope@ -> 'Just' 'False'+ - @yep@ -> 'Just' 'True'+ - @dunno@ -> 'Nothing'++* @cdio_cdrom_addr@ (removed; never used in library code)+* @cdio_fs_anal_t@ -> @"Foreign.Libcdio.CdTypes".'Filesystem'@, 'FilesystemClasses', and 'IsoAnalysis'+* @cdio_isrc_t@ (removed; never used in library code)+* @cdio_mcn_t@ (removed; never used in library code)+* @cdio_track_flag@ (removed; identical in all but name to 'Flag')+* @cdio_utf8_t@ (removed; 'Char' already serves this purpose)+* @lba_t@ -> @"Foreign.Libcdio.Sector".'Lba'@+* @lsn_t@ -> @"Foreign.Libcdio.Sector".'Lsn'@+* @msf_t@ -> @"Foreign.Libcdio.Sector".'Msf'@++ - @m@ -> 'minute'+ - @s@ -> 'second'+ - @f@ -> 'frame'++* @session_t@ (removed: only used internally)+* @track_t@ -> @"Foreign.Libcdio.Track".'Track'@+++= "Sound.Libcdio.Types"+The exact collection of exported types has been changed to reflect those used+by the higher-level interface, but the modules are otherwise very similar; many+types are shared between the two.+-}+module Foreign.Libcdio.Types+ ( -- * Disc+ Cdio+ , Whence+ , Lba+ , Lsn+ , Msf+ , Bcd+ , Track+ , TrackNum+ , TrackFormat+ , ReadMode+ , SessionArg+ -- * CdText+ , SubchannelData+ , Field+ , Genre+ , Language+ , Flag+ , Flags+ -- * Hardware+ , DriverId+ , DriverReturnCode+ , HardwareInfo+ , DriveCapabilityRead+ , DriveReadCaps+ , DriveCapabilityWrite+ , DriveWriteCaps+ , DriveCapabilityMisc+ , DriveMiscCaps+ , DriveCaps+ , DiscMode+ -- * Data+ , Filesystem+ , FilesystemClass+ , FilesystemClasses+ , IsoAnalysis+ -- * Logging+ , LogEntry+ , LogLevel+ ) where+++import Foreign.Libcdio.CdText+import Foreign.Libcdio.CdTypes+import Foreign.Libcdio.Device+import Foreign.Libcdio.Disc+import Foreign.Libcdio.Logging+import Foreign.Libcdio.Read+import Foreign.Libcdio.Sector+import Foreign.Libcdio.Track+import Foreign.Libcdio.Util
+ src/Foreign/Libcdio/Types/Enums.chs view
@@ -0,0 +1,453 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE ForeignFunctionInterface #-}+{-# OPTIONS_HADDOCK not-home #-}++#include "cdio/compat/version.h"++{-|+Description: c2hs-generated types for re-export by more relevant modules.++Copyright: (c) 2018-2021 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: stable+Portability: non-portable (requires libcdio)++Many of the enums in the C library are large things with explicit numeric+representation, and maintaining them in pure Haskell would be a nightmare. On+the other hand, keeping them in their natural modules means those can never be+analyzed for coverage. Splitting the former out here allows the best of both+worlds — losing typeclass coverage reports on the enums is a small price. Just+note that since this isn't exposed, it /can not/ be used directly by any other+c2hs-generated modules.+-}+module Foreign.Libcdio.Types.Enums+ ( -- * "Foreign.Libcdio.CdText"+ CField+ , Field ( .. )+ , CGenre+ , Genre ( .. )+ , CLanguage+ , Language ( .. )+ -- * "Foreign.Libcdio.CdTypes"+ , Filesystem_ ( .. )+ , FilesystemClass ( .. )+ -- * "Foreign.Libcdio.Device"+ , DriveCapabilityMisc ( .. )+ , DriveCapabilityRead ( .. )+ , DriveCapabilityWrite ( .. )+ , CDriverId+ , DriverId ( .. )+ , CDriverReturnCode+ , DriverReturnCode ( .. )+ -- * "Foreign.Libcdio.Disc"+ , CDiscMode+ , DiscMode ( .. )+ -- * "Foreign.Libcdio.Logging"+ , CLogLevel+ , LogLevel ( .. )+ -- * "Foreign.Libcdio.Read"+ , ReadMode ( .. )+ , Whence ( .. )+ -- * "Foreign.Libcdio.Sector"+ , SubchannelData ( .. )+ , Flag ( .. )+ -- * "Foreign.Libcdio.Track"+ , CTrackFormat+ , TrackFormat ( .. )+ , TrackFlagStatus ( .. )+ ) where+++import Data.Ix ( Ix )+++#include "cdio/compat/cdtext.h"+++-- | The underlying type of the C @cdtext_field_t@, i.e. 'Field'.+type CField = {#type cdtext_field_t#}++-- | Descriptions of the content contained in an associated CD Text field.+{#enum cdtext_field_t as Field+ { underscoreToCase+ , CDTEXT_FIELD_DISCID as DiscId+ , CDTEXT_FIELD_GENRE as GenreName+ } omit ( CDTEXT_FIELD_INVALID )+ with prefix = "cdtext_field"+ deriving ( Eq, Show, Read, Ord, Bounded )+#}+++-- | The underlying type of the C @cdtext_genre_t@, i.e. 'Genre'.+type CGenre = {#type cdtext_genre_t#}++-- | Genres recognized in the CD Text standard.+{#enum cdtext_genre_t as Genre+ { underscoreToCase+ , CDTEXT_GENRE_ADULT_CONTEMP as AdultContemporary+ , CDTEXT_GENRE_CHRIST_CONTEMP as ChristianContemporary+ , CDTEXT_GENRE_HIPHOP as HipHop+ , CDTEXT_GENRE_LATIN as LatinMusic+ , CDTEXT_GENRE_NEWAGE as NewAge+ , CDTEXT_GENRE_RYTHMANDBLUES as RhythmAndBlues+ , CDTEXT_GENRE_SOUNDEFFECTS as SoundEffects+ } omit ( CDTEXT_GENRE_UNUSED )+ with prefix = "cdtext_genre"+ deriving ( Eq, Show, Read, Ord, Bounded )+#}+++-- | The underlying type of the C @cdtext_lang_t@, i.e. 'Language'.+type CLanguage = {#type cdtext_lang_t#}++-- | Written languages recognized in the CD Text standard.+#if LIBCDIO_SINCE_VERSION_2_1+{#enum cdtext_lang_t as Language+ { underscoreToCase+ , CDTEXT_LANGUAGE_UNKNOWN as UnknownLanguage+ , CDTEXT_LANGUAGE_SERBO_CROAT as SerboCroatian+ , CDTEXT_LANGUAGE_SRANANTONGO as SrananTongo+ } omit+ ( CDTEXT_LANGUAGE_INVALID+ , CDTEXT_LANGUAGE_BLOCK_UNUSED+ )+ with prefix = "cdtext_language"+ deriving ( Eq, Show, Read, Ord, Bounded )+#}+#else+{#enum cdtext_lang_t as Language+ { underscoreToCase+ , CDTEXT_LANGUAGE_UNKNOWN as UnknownLanguage+ , CDTEXT_LANGUAGE_SERBO_CROAT as SerboCroatian+ , CDTEXT_LANGUAGE_SRANANTONGO as SrananTongo+ }+ with prefix = "cdtext_language"+ deriving ( Eq, Show, Read, Ord, Bounded )+#}+#endif++++#include "cdio/compat/cd_types.h"+++-- | Internal filesystem type, including ones that conflate+-- 'Foreign.Libcdio.CdTypes.Filesystem' with+-- 'Foreign.Libcdio.CdTypes.IsoAnalysis'; these are separated in+-- 'Foreign.Libcdio.CdTypes.cdType'.+{#enum cdio_fs_t as Filesystem_+ {underscoreToCase}+ with prefix = "cdio"+ deriving ( Eq, Show, Read, Ord, Bounded )+#}+++-- | Higher-level descriptions of discs/filesystems.+{#enum fs_cap_t as FilesystemClass+ { underscoreToCase+ , FS_ANAL_CDTV as CommodoreCdtv+ , FS_ANAL_VIDEOCD as VideoCd+ , FS_ANAL_ROCKRIDGE as RockRidge+ , FS_ANAL_SVCD as SuperVideoCd+ , FS_ANAL_CVD as ChoijiVideoCd+ , FS_ANAL_XISO as XboxIsoClass+ , FS_ANAL_ISO9660_ANY as Iso9660Class+ }+ with prefix = "fs_anal"+ deriving ( Eq, Show, Read, Ord, Bounded, Ix )+#}++++#include "cdio/compat/device.h"+++-- | Miscellaneous properties a device can have, typically describing hardware+-- features, which are collected in 'Foreign.Libcdio.Device.DriveMiscCaps'.+{#enum cdio_drive_cap_misc_t as DriveCapabilityMisc+ { underscoreToCase+ } omit+ ( CDIO_DRIVE_CAP_ERROR+ , CDIO_DRIVE_CAP_UNKNOWN+ )+ with prefix = "cdio_drive_cap"+ deriving ( Eq, Show, Read, Ord, Bounded, Ix )+#}++-- | Read-related properties a device can have, mostly describing what formats+-- it understands, which are collected in 'Foreign.Libcdio.Device.DriveReadCaps'.+-- +-- The difference between 'ReadAnalogAudio' and 'ReadDigitalAudio' is poorly+-- documented in libcdio; they have been named here according to their assumed+-- meanings (see <https://www.cdrfaq.org/faq02.html#S2-4-3>), but that pattern+-- may not be completely accurate.+{#enum cdio_drive_cap_read_t as DriveCapabilityRead+ { underscoreToCase+ , CDIO_DRIVE_CAP_READ_AUDIO as ReadAnalogAudio+ , CDIO_DRIVE_CAP_READ_CD_DA as ReadDigitalAudio+ , CDIO_DRIVE_CAP_READ_CD_G as ReadCdGraphics+ , CDIO_DRIVE_CAP_READ_CD_R as ReadCdRecordable+ , CDIO_DRIVE_CAP_READ_CD_RW as ReadCdReWritable+ , CDIO_DRIVE_CAP_READ_DVD_R as ReadDvdRecordable+ , CDIO_DRIVE_CAP_READ_DVD_PR as ReadDvdPlusRecordable+ , CDIO_DRIVE_CAP_READ_DVD_RW as ReadDvdReWritable+ , CDIO_DRIVE_CAP_READ_DVD_RPW as ReadDvdPlusReWritable+ , CDIO_DRIVE_CAP_READ_C2_ERRS as ReadC2ErrorCorrection+ }+ with prefix = "cdio_drive_cap"+ deriving ( Eq, Show, Read, Ord, Bounded, Ix )+#}++-- | Write-related properties a device can have, mostly describing what formats+-- it can burn, which are collected in 'Foreign.Libcdio.Device.DriveWriteCaps'.+{#enum cdio_drive_cap_write_t as DriveCapabilityWrite+ { underscoreToCase+ , CDIO_DRIVE_CAP_WRITE_CD_R as WriteCdRecordable+ , CDIO_DRIVE_CAP_WRITE_CD_RW as WriteCdReWritable+ , CDIO_DRIVE_CAP_WRITE_DVD_R as WriteDvdRecordable+ , CDIO_DRIVE_CAP_WRITE_DVD_PR as WriteDvdPlusRecordable+ , CDIO_DRIVE_CAP_WRITE_DVD_RW as WriteDvdReWritable+ , CDIO_DRIVE_CAP_WRITE_DVD_RPW as WriteDvdPlusReWritable+ } omit+ ( CDIO_DRIVE_CAP_WRITE_CD+ , CDIO_DRIVE_CAP_WRITE_DVD+ , CDIO_DRIVE_CAP_WRITE+ )+ with prefix = "cdio_drive_cap"+ deriving ( Eq, Show, Read, Ord, Bounded, Ix )+#}+++{- Barely even used internally.+-- | Different types of device that can be read, which are collected in+-- 'Foreign.Libcdio.Device.SrcCategories'.+{#enum cdio_src_category_mask_t as SrcCategoryMask+ {underscoreToCase}+ with prefix = "cdio"+ deriving ( Eq, Show, Read, Ord, Bounded, Ix )+#}+-}+++-- | The underlying type of the C @driver_id_t@, i.e. 'DriverId'.+type CDriverId = {#type driver_id_t#}++-- | Devices or file types supported by the library.+{#enum define DriverId+ { DRIVER_UNKNOWN as DriverUnknown+ , DRIVER_AIX as DriverAix+ , DRIVER_BSDI as DriverBsdi+ , DRIVER_FREEBSD as DriverFreeBsd+ , DRIVER_NETBSD as DriverNetBsd+ , DRIVER_LINUX as DriverLinux+ , DRIVER_SOLARIS as DriverSolaris+ , DRIVER_OS2 as DriverOs2+ , DRIVER_OSX as DriverOsX+ , DRIVER_WIN32 as DriverWin32+ , DRIVER_CDRDAO as DriverCdrDao+ , DRIVER_BINCUE as DriverBinCue+ , DRIVER_NRG as DriverNrg+ , DRIVER_DEVICE as DriverDevice+ }+ deriving ( Eq, Show, Read, Ord, Bounded )+#}+++-- | The underlying type of the C @driver_return_code_t@, i.e.+-- 'DriverReturnCode'.+type CDriverReturnCode = {#type driver_return_code_t#}++-- | Descriptions of various error states which may be returned by driver+-- functions.+{#enum driver_return_code_t as DriverReturnCode+ { underscoreToCase+ , DRIVER_OP_ERROR as DriverError+ , DRIVER_OP_UNINIT as Uninitialized+ } with prefix = "driver_op"+ deriving ( Eq, Show, Read, Ord, Bounded )+#}++++#include "cdio/compat/disc.h"+++-- | The underlying type of the C @discmode_t@, i.e. 'DiscMode'.+type CDiscMode = {#type discmode_t#}++-- | Different types of disc. Modes are combined from several sources, along+-- with some libcdio-specific additions:+--+-- * MMC-5 6.33.3.13 (Send CUESHEET)+-- * MMC-5 Table 400 "DVD Book"+-- * GNU/Linux @\/usr\/include\/linux\/cdrom.h@+--+-- As C2HS and Haddock don't yet interact well enough to document Enum fields,+-- some of the less obvious mappings include:+--+-- * 'DataCdMode': CD-ROM form 1+-- * 'MixedCdMode': some combination of 'AudioCdMode', 'DataCdMode', and 'XaCdMode'+-- * 'DvdPlusRecordableMode': DVD+R+-- * 'DvdPlusReWritableMode': DVD+RW+{#enum discmode_t as DiscMode+ { underscoreToCase+ , CDIO_DISC_MODE_CD_DA as AudioCdMode+ , CDIO_DISC_MODE_CD_DATA as DataCdMode+ , CDIO_DISC_MODE_CD_XA as XaCdMode+ , CDIO_DISC_MODE_CD_MIXED as MixedCdMode+ , CDIO_DISC_MODE_DVD_ROM as DvdRomMode+ , CDIO_DISC_MODE_DVD_RAM as DvdRamMode+ , CDIO_DISC_MODE_DVD_R as DvdRecordableMode+ , CDIO_DISC_MODE_DVD_RW as DvdReWritableMode+ , CDIO_DISC_MODE_HD_DVD_ROM as HighDefinitionDvdRomMode+ , CDIO_DISC_MODE_HD_DVD_RAM as HighDefinitionDvdRamMode+ , CDIO_DISC_MODE_HD_DVD_R as HighDefinitionDvdRecordableMode+ , CDIO_DISC_MODE_DVD_PR as DvdPlusRecordableMode+ , CDIO_DISC_MODE_DVD_PRW as DvdPlusReWritableMode+ , CDIO_DISC_MODE_DVD_PR_DL as DoubleLayerDvdPlusRecordableMode+ , CDIO_DISC_MODE_DVD_PRW_DL as DoubleLayerDvdPlusReWritableMode+ , CDIO_DISC_MODE_DVD_OTHER as OtherDvdMode+ , CDIO_DISC_MODE_NO_INFO as NoModeInfo+ , CDIO_DISC_MODE_CD_I as CdIMode+ } omit ( CDIO_DISC_MODE_ERROR )+ with prefix = "cdio_disc_mode"+ deriving ( Eq, Show, Read, Ord, Bounded )+#}++++#include "cdio/compat/logging.h"+++-- | The underlying type of the C @cdio_log_level_t@, i.e. 'LogLevel'.+type CLogLevel = {#type cdio_log_level_t#}++-- | How much detail should be recorded in the logs.+{#enum cdio_log_level_t as LogLevel+ {underscoreToCase}+ with prefix = "cdio"+ deriving ( Eq, Show, Read, Ord, Bounded )+#}++++#include "cdio/compat/read.h"+++-- | How data is laid out on a disc.+{#enum cdio_read_mode_t as ReadMode+ { underscoreToCase+ , CDIO_READ_MODE_AUDIO as AudioMode+ , CDIO_READ_MODE_M1F1 as Mode1Form1+ , CDIO_READ_MODE_M1F2 as Mode1Form2+ , CDIO_READ_MODE_M2F1 as Mode2Form1+ , CDIO_READ_MODE_M2F2 as Mode2Form2+ }+ with prefix = "cdio_read_mode"+ deriving ( Eq, Show, Read, Ord, Bounded )+#}+++-- | Which location an offset passed to 'Foreign.Libcdio.Read.seek' should be+-- based on.+{#enum whence_t as Whence+ {underscoreToCase}+ with prefix = "whence"+ deriving ( Eq, Show, Read, Ord, Bounded )+#}++++#include "cdio/compat/sector.h"+++-- | Types of information stored on disc subchannels.+{#enum cdio_subchannel as SubchannelData+ { underscoreToCase+ , CDIO_SUBCHANNEL_SUBQ_DATA as QChannelData+ }+ with prefix = "cdio_subchannel"+ deriving ( Eq, Show, Read, Ord, Bounded )+#}+++-- | Metadata describing the layout or type of data on a track.+{#enum flag_t as Flag+ { underscoreToCase+ , DATA as DataTrack+ , SCMS as SerialCopyManagement+ } omit ( NONE )+ deriving ( Eq, Show, Read, Ord, Bounded, Ix )+#}+++{- Not actually an 'Enum', but rather shortcuts for basic multiplications.+-- | How many sectors are contained in various lengths of disc.+{#enum cdio_cd_minutes_sectors as CdMinutesSectors+ {underscoreToCase}+ with prefix = "cdio"+ deriving ( Eq, Show, Read, Ord, Bounded )+#}+-}++++#include "cdio/compat/track.h"+++-- | The underlying type of the C @track_format_t@, i.e. 'TrackFormat'.+type CTrackFormat = {#type track_format_t#}++-- | The structure in which data is stored on a segment of a disc. The exact+-- representation of these values is discussed in "Foreign.Libcdio.Sector".+{#enum track_format_t as TrackFormat+ { underscoreToCase+ , TRACK_FORMAT_CDI as FormatCdI+ , TRACK_FORMAT_PSX as FormatPlaystation+ } omit ( TRACK_FORMAT_ERROR )+ with prefix = "track"+ deriving ( Eq, Show, Read, Ord, Bounded )+#}+++{- Barely even used internally.+-- | The block format in which the data is saved in a track on disc.+{#enum trackmode_t as TrackMode+ {underscoreToCase}+ deriving ( Eq, Show, Read, Ord, Bounded )+#}+-}+++-- | Whether a track has a particular flag specified.+{#enum track_flag_t as TrackFlagStatus+ {underscoreToCase}+ with prefix = "cdio_track"+ deriving ( Eq, Show, Read, Ord, Bounded )+#}++++#include "cdio/util.h"+++{- Similar semantics from 'Maybe Bool'.+-- | A version of 'Bool' which also provides a third, non-definitive state.+{#enum bool_3way_t as Bool3+ {nope as No, yep as Yes, dunno as Unknown}+ deriving ( Eq, Show, Read, Ix )+#}+-- Need to explicitly instance Ord and Bounded as the below is the logical+-- order, but @dunno@ is assigned @3@ in the C code.+instance Ord Bool3 where+ No <= _ = True+ _ <= Yes = True+ Unknown <= Unknown = True+ _ <= _ = False+instance Bounded Bool3 where+ minBound = No+ maxBound = Yes+-- Needs: Bits, FiniteBits, Generic, Rep, Data, Storable for parity with Bool+-}
+ src/Foreign/Libcdio/Types/Internal.hs view
@@ -0,0 +1,409 @@+{-# LANGUAGE ForeignFunctionInterface #-}++{-|+Description: Common type definitions used pervasively in libcdio, along with+ low-level features intended for internal use.++Copyright: (c) 2018-2021 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: stable+Portability: non-portable (requires libcdio)++While most of @types.h@ is user-facing, it's undesirable to export the+@newtype@ constructors, for type safety. Hiding them breaks c2hs automatic+marshalling, which means that we have to write custom marshalling functions.+Exporting those clutters the user surface with unnecessary and+likely-never-used code, so the types in this module got split off for use+internally — at which point the constructors may as well be exported anyway.+-}+module Foreign.Libcdio.Types.Internal+ ( -- * Addresses+ Lba ( .. )+ , CLba+ , Lsn ( .. )+ , CLsn+ -- * Segments+ , Track ( .. )+ , CTrack+ , TrackNum+ , minTrack+ , maxTrack+ -- * Data+ , CBitfield+ , isrcLength+ , mcnLength+ -- * Marshalling+ , invalidLba+ , invalidLsn+ , invalidZeroLsn+ , invalidTrack+ , invalidZeroTrack+ , withLba+ , withLsn+ , withTrack+ ) where+++import qualified Data.Bits as B+import qualified Data.Ix as I+import qualified Data.List as L+import qualified Data.Maybe as Y++import qualified Foreign.C.Types as C+import qualified Foreign.Ptr as C+import qualified Foreign.Storable as S++import qualified Text.Printf as P++import Data.Bits ((.&.), (.|.))++import Foreign.Libcdio.Marshal+++{- 'Char' is already native.+type CUtf8 = C.CChar++-- | A character explicitly encoded as UTF-8.+newtype Utf8 = Utf8 CUtf8+ deriving ( Eq, Ord, Show, Read, Bounded )+-}+++-- | The representation of the various @DriveCaps*@ at the C boundary.+type CBitfield = C.CUInt++{- Accomplished with "Data.Array.BitArray".+-- | The type used for bit-fields in structs with eight or less flags.+newtype Bitfield = Bitfield CBitfield+ deriving ( Eq, Ord, Show, Read, Bounded )+-}+++-- | Marshal an address to a type which pins the required size of the C+-- representation, rather than the polymorphism of 'fromIntegral'.+withLba :: Lba -> CLba+withLba (Lba i) = i++type CLba = C.CInt++-- | The type-safe representation of a Logical Block Address, counting sectors+-- from the very beginning of the write session. See also 'Lsn'.+newtype Lba = Lba CLba+ deriving ( Eq, Ord, Show, Read )+instance Bounded Lba where+ minBound = Lba . lsnToLba $ fromIntegral (minBound :: Lsn)+ maxBound = Lba . lsnToLba $ fromIntegral (maxBound :: Lsn)+instance Enum Lba where+ toEnum = Lba . toEnum+ fromEnum (Lba i) = fromEnum i+instance I.Ix Lba where+ range (Lba a, Lba b) = map Lba [a..b]+ inRange (a, b) i = a <= i && i <= b+ index r@(a, b) i = Y.fromMaybe (error $ "Ix(Lba).index: Index (" ++ show i ++ ") out of range (" ++ show r ++ ")")+ $ L.elemIndex i [a..b]+instance Num Lba where+ Lba a + Lba b = Lba $ a + b+ Lba a - Lba b = Lba $ a - b+ Lba a * Lba b = Lba $ a * b+ abs (Lba i) = Lba $ abs i+ signum (Lba i) = Lba $ signum i+ fromInteger = Lba . fromInteger+instance Real Lba where+ toRational (Lba i) = toRational i+instance Integral Lba where+ quotRem (Lba i) (Lba d) = (Lba q, Lba r)+ where (q, r) = quotRem i d+ toInteger (Lba i) = toInteger i+instance B.Bits Lba where+ (Lba a) .&. (Lba b) = Lba $ a .&. b+ (Lba a) .|. (Lba b) = Lba $ a .|. b+ xor (Lba a) (Lba b) = Lba $ B.xor a b+ complement (Lba i) = Lba $ B.complement i+ shift (Lba i) = Lba . B.shift i+ rotate (Lba i) = Lba . B.rotate i+ bitSize (Lba i) = B.finiteBitSize i+ bitSizeMaybe (Lba i) = B.bitSizeMaybe i+ isSigned (Lba i) = B.isSigned i+ testBit (Lba i) = B.testBit i+ bit = Lba . B.bit+ popCount (Lba i) = B.popCount i+instance B.FiniteBits Lba where+ finiteBitSize (Lba i) = B.finiteBitSize i+instance P.PrintfArg Lba where+ formatArg = P.formatArg . (fromIntegral :: Lba -> Int)+instance S.Storable Lba where+ sizeOf (Lba i) = S.sizeOf i+ alignment (Lba i) = S.alignment i+ peek p = Lba <$> S.peek (C.castPtr p)+ poke p (Lba i) = S.poke (C.castPtr p) i++foreign import ccall safe "cdio/compat/sector.h cdio_lsn_to_lba"+ lsnToLba :: CLsn -> CLba++foreign import ccall safe "cdio/compat/disc.h invalid_lba"+ invalidLba' :: CLba++-- | Filter out @CDIO_INVALID_LBA@ values for type-safe errors.+invalidLba :: CLba -> Maybe Lba+invalidLba = fmap fromIntegral . maybeError [invalidLba']+++-- | Marshal an address to a type which pins the required size of the C+-- representation, rather than the polymorphism of 'fromIntegral'.+withLsn :: Lsn -> CLsn+withLsn (Lsn i) = i++type CLsn = C.CInt++-- | The type-safe representation of a Logical Sector Number, counting sectors+-- from the start of track 1; this notably excludes the blank session lead-in.+-- See also 'Lba'.+newtype Lsn = Lsn CLsn+ deriving ( Eq, Ord, Show, Read )+instance Bounded Lsn where+ minBound = Lsn minLsn+ maxBound = Lsn maxLsn+instance Enum Lsn where+ toEnum = Lsn . toEnum+ fromEnum (Lsn i) = fromEnum i+instance I.Ix Lsn where+ range (Lsn a, Lsn b) = map Lsn [a..b]+ inRange (a, b) i = a <= i && i <= b+ index r@(a, b) i = Y.fromMaybe (error $ "Ix(Lsn).index: Index (" ++ show i ++ ") out of range (" ++ show r ++ ")")+ $ L.elemIndex i [a..b]+instance Num Lsn where+ Lsn a + Lsn b = Lsn $ a + b+ Lsn a - Lsn b = Lsn $ a - b+ Lsn a * Lsn b = Lsn $ a * b+ abs (Lsn i) = Lsn $ abs i+ signum (Lsn i) = Lsn $ signum i+ fromInteger = Lsn . fromInteger+instance Real Lsn where+ toRational (Lsn i) = toRational i+instance Integral Lsn where+ quotRem (Lsn i) (Lsn d) = (Lsn q, Lsn r)+ where (q, r) = quotRem i d+ toInteger (Lsn i) = toInteger i+instance B.Bits Lsn where+ (Lsn a) .&. (Lsn b) = Lsn $ a .&. b+ (Lsn a) .|. (Lsn b) = Lsn $ a .|. b+ xor (Lsn a) (Lsn b) = Lsn $ B.xor a b+ complement (Lsn i) = Lsn $ B.complement i+ shift (Lsn i) = Lsn . B.shift i+ rotate (Lsn i) = Lsn . B.rotate i+ bitSize (Lsn i) = B.finiteBitSize i+ bitSizeMaybe (Lsn i) = B.bitSizeMaybe i+ isSigned (Lsn i) = B.isSigned i+ testBit (Lsn i) = B.testBit i+ bit = Lsn . B.bit+ popCount (Lsn i) = B.popCount i+instance B.FiniteBits Lsn where+ finiteBitSize (Lsn i) = B.finiteBitSize i+instance P.PrintfArg Lsn where+ formatArg = P.formatArg . (fromIntegral :: Lsn -> Int)+instance S.Storable Lsn where+ sizeOf (Lsn i) = S.sizeOf i+ alignment (Lsn i) = S.alignment i+ peek p = Lsn <$> S.peek (C.castPtr p)+ poke p (Lsn i) = S.poke (C.castPtr p) i++foreign import ccall safe "cdio/compat/sector.h min_lsn"+ minLsn :: CLsn++foreign import ccall safe "cdio/compat/sector.h max_lsn"+ maxLsn :: CLsn++foreign import ccall safe "cdio/compat/disc.h invalid_lsn"+ invalidLsn' :: CLsn++-- | Filter out @CDIO_INVALID_LSN@ values for type-safe errors.+invalidLsn :: CLsn -> Maybe Lsn+invalidLsn = fmap fromIntegral . maybeError [invalidLsn']++-- | Filter out both @0@ and @CDIO_INVALID_LSN@ values for type-safe errors.+invalidZeroLsn :: CLsn -> Maybe Lsn+invalidZeroLsn = fmap fromIntegral . maybeError [0, invalidLsn']+++-- | Marshal a track number to a type which pins the required size of the C+-- representation, rather than the polymorphism of 'fromIntegral'. Note that+-- @withTrack 'DiscLeadout' /= fromIntegral (fromEnum 'DiscLeadout')@+withTrack :: Track -> CTrack+withTrack DiscPregap = 0+withTrack (Track (TrackNum i)) = fromIntegral i + minTrack'+withTrack DiscLeadout = leadoutTrack'++type CTrack = C.CUChar++-- | Opaque newtype representing the numeric index of a 'Track', while+-- enforcing the invariants inherant to the specification. Of very limited+-- utility outside that context.+newtype TrackNum = TrackNum Word+ deriving ( Eq, Ord )+instance Bounded TrackNum where+ minBound = TrackNum 0+ maxBound = TrackNum $ maxTrackW - minTrackW+instance Show TrackNum where+ show (TrackNum i) = show $ i + minTrackW+instance Read TrackNum where+ readsPrec d = \str -> do+ (i, str') <- readsPrec d str+ return (TrackNum $ i - minTrackW, str')++-- | An index into the segmentation within a write session on a disc.+data Track+ = DiscPregap+ -- ^ The (usually buffer) data located before the first track on a+ -- disc.+ | Track TrackNum+ -- ^ The common understanding of a CD track: a segment of the data on+ -- the disc containing (usually) a single song.+ | DiscLeadout+ -- ^ Any (usually buffer) data located after the end of the last track+ -- on a disc.+ deriving ( Eq, Ord, Show )+instance Bounded Track where+ minBound = DiscPregap+ maxBound = DiscLeadout+-- | Note that @'fromEnum' 'DiscLeadout'@ uses a value (== 100) chosen to be+-- contiguous to the rest of the datatype rather than that used internally+-- (== 0xAA). 'toEnum' accepts both values.+instance Enum Track where+ toEnum i+ | i < fromIntegral minTrack' = DiscPregap+ | i > fromIntegral maxTrack' = DiscLeadout+ | otherwise = Track . TrackNum $ fromIntegral i - minTrackW+ fromEnum DiscPregap = fromIntegral minTrack' - 1+ fromEnum (Track (TrackNum i)) = fromIntegral $ i + minTrackW+ fromEnum DiscLeadout = fromIntegral maxTrack' + 1+ pred DiscPregap = error "Enum.pred(Track): tried to take `pred' of DiscPregap"+ pred (Track n@(TrackNum i))+ | n == minBound = DiscPregap+ | n > maxBound = DiscLeadout+ | otherwise = Track . TrackNum $ i - 1+ pred DiscLeadout = Track maxBound+ succ DiscPregap = Track minBound+ succ (Track n@(TrackNum i))+ | n >= maxBound = DiscLeadout+ | otherwise = Track . TrackNum $ i + 1+ succ DiscLeadout = error "Enum.succ(Track): tried to take `succ' of DiscLeadout"+instance Read Track where+ readsPrec d = \s ->+ [ (DiscPregap, s')+ | ("DiscPregap", s') <- lex s+ ] +++ [ (DiscLeadout, s')+ | ("DiscLeadout", s') <- lex s+ ] +++ [ (packTrack i, s')+ | (i, s') <- readParen (d > 10) readsTrack s+ ]+ where packTrack i+ | i < minTrackW = DiscPregap+ | i > maxTrackW = DiscLeadout+ | otherwise = Track . TrackNum $ i - minTrackW+ readsTrack s =+ [ (i, s'')+ | ("Track", s') <- lex s+ , (i, s'') <- readsPrec 10 s'+ ]+instance I.Ix Track where+ range (a, b) = map toEnum [fromEnum a..fromEnum b]+ inRange (a, b) i = a <= i && i <= b+ index r@(a, b) i = Y.fromMaybe (error $ "Ix(Track).index: Index (" ++ show i ++ ") out of range (" ++ show r ++ ")")+ $ L.elemIndex i [a..b]+instance Num Track where+ a + b = toEnum $ fromEnum a + fromEnum b+ a - b = toEnum $ fromEnum a - fromEnum b+ a * b = toEnum $ fromEnum a * fromEnum b+ abs t = t+ signum _ = DiscPregap+ fromInteger = toEnum . fromInteger+instance P.PrintfArg Track where+ formatArg t = P.formatInt $ withTrack t+-- | Note that 'S.poke' uses the official representation of 'DiscLeadout'+-- (@CDIO_CDROM_LEADOUT_TRACK == 0xAA@, as used by libcdio) rather than the+-- hscdio @'fromEnum' 'DiscLeadout'@ (== 100), as the latter was chosen for+-- proximity to the other constructors.+instance S.Storable Track where+ sizeOf _ = S.sizeOf leadoutTrack'+ alignment _ = S.alignment leadoutTrack'+ peek p = toEnum . fromIntegral <$> S.peek (C.castPtr p :: C.Ptr CTrack)+ poke p = S.poke (C.castPtr p) . withTrack++-- | The first data track on a disc (i.e. @'Track' 1@).+minTrack :: Track+minTrack = fromIntegral minTrack'++minTrackW :: Word+minTrackW = fromIntegral minTrack'++foreign import ccall safe "cdio/compat/track.h min_tracks"+ minTrack' :: CTrack++-- | The highest data track allowed by the specifications (i.e. @'Track' 99@).+maxTrack :: Track+maxTrack = fromIntegral maxTrack'++maxTrackW :: Word+maxTrackW = fromIntegral maxTrack'++foreign import ccall safe "cdio/compat/track.h max_tracks"+ maxTrack' :: CTrack++foreign import ccall safe "cdio/compat/track.h leadout_track"+ leadoutTrack' :: CTrack++foreign import ccall safe "cdio/compat/track.h invalid_track"+ invalidTrack' :: CTrack++-- | Filter out @CDIO_INVALID_TRACK@ values for type-safe errors.+invalidTrack :: CTrack -> Maybe Track+invalidTrack = fmap (toEnum . fromIntegral) . maybeError [invalidTrack']++-- | Filter out @CDIO_INVALID_TRACK@ and 'DiscPregap' values for type-safe+-- errors.+invalidZeroTrack :: CTrack -> Maybe Track+invalidZeroTrack = fmap (toEnum . fromIntegral) . maybeError [0, invalidTrack']+++-- | Number of ASCII bytes in a media catalog number.+mcnLength :: Word+mcnLength = fromIntegral mcnLength'++foreign import ccall safe "cdio/compat/types.h mcn_length"+ mcnLength' :: C.CUChar++{- Never used after definition.+-- | Some Media Catalog Number which identifies a disc; in practice usually a+-- UPC/EAN bar code.+newtype Mcn = Mcn String+ deriving ( Eq, Ord, Show, Read, Bounded )+instance S.Storable Mcn where+ sizeOf _ = S.sizeOf C.nullPtr+ alignment _ = S.alignment C.nullPtr+ peek p = Mcn <$> C.peekCStringLen (C.castPtr p, mcnLength)+ poke p (Mcn s) = undefined+--}+++-- | Number of ASCII characters in an International Standard Recording Code.+isrcLength :: Word+isrcLength = fromIntegral isrcLength'++foreign import ccall safe "cdio/compat/types.h isrc_length"+ isrcLength' :: C.CUChar++{- Never used after definition.+-- | The International Standard Recording Code attached to a track of a disc,+-- as assigned by a central agency.+newtype Isrc = Isrc String+ deriving ( Eq, Ord, Show, Read, Bounded )+instance S.Storable Isrc where+ sizeOf _ = S.sizeOf C.nullPtr+ alignment _ = S.alignment C.nullPtr+ peek p = Isrc <$> C.peekCStringLen (C.castPtr p, isrcLength)+ poke p (Isrc s) = undefined+-}
+ src/Foreign/Libcdio/Types/Offsets.chs view
@@ -0,0 +1,127 @@+{-|+Description: c2hs-generated byte offsets for members of C structs.++Copyright: (c) 2020 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: stable+Portability: non-portable (requires libcdio)++Since this library already handles marshalling to and from C types itself, the+only remaining benefit to using c2hs for datatypes is not having to worry about+tracking the internal byte arrangement of C structs. That can be done just as+easily externally here, with the added benefit of being able to analyze+coverage of the primary modules. Just note that since this isn't exposed, it+/can not/ be used directly by any other c2hs-generated modules.+-}+module Foreign.Libcdio.Types.Offsets where+++import qualified Foreign.C.String as C+import qualified Foreign.Ptr as C++import qualified Foreign.Marshal.Array as M+import qualified Foreign.Storable as S+++pokeCString :: String -> Int -> C.CString -> IO ()+pokeCString s l p = C.withCStringLen (s ++ "\NUL") $ \(c, cl) ->+ if l < cl+ then M.copyArray p c (l - 1) >> S.poke (C.plusPtr p $ l - 1) '\NUL'+ else M.copyArray p c cl+++#include "cdio/compat/cd_types.h"+++iaSizeOf :: Int+iaSizeOf = {#sizeof cdio_iso_analysis_t#}++iaAlign :: Int+iaAlign = {#alignof cdio_iso_analysis_t#}++iaJolietLevel :: Int+iaJolietLevel = {#offsetof cdio_iso_analysis_t->joliet_level#}++iaLabel :: Int+iaLabel = {#offsetof cdio_iso_analysis_t->iso_label#}++iaIsoSize :: Int+iaIsoSize = {#offsetof cdio_iso_analysis_t->isofs_size#}++iaUDFMajor :: Int+iaUDFMajor = {#offsetof cdio_iso_analysis_t->UDFVerMajor#}++iaUDFMinor :: Int+iaUDFMinor = {#offsetof cdio_iso_analysis_t->UDFVerMinor#}++++#include "cdio/compat/device.h"+++hiSizeOf :: Int+hiSizeOf = {#sizeof cdio_hwinfo#}++hiAlign :: Int+hiAlign = {#alignof cdio_hwinfo#}++hiVendor :: Int+hiVendor = {#offsetof cdio_hwinfo->psz_vendor#}++hiModel :: Int+hiModel = {#offsetof cdio_hwinfo->psz_model#}++hiRevision :: Int+hiRevision = {#offsetof cdio_hwinfo->psz_revision#}++++#include "cdio/compat/logging.h"+++leSizeOf :: Int+leSizeOf = {#sizeof cdio_log_entry_t#}++leAlign :: Int+leAlign = {#alignof cdio_log_entry_t#}++leLevel :: Int+leLevel = {#offsetof cdio_log_entry_t->level#}++leMessage :: Int+leMessage = {#offsetof cdio_log_entry_t->message#}++lePrevious :: Int+lePrevious = {#offsetof cdio_log_entry_t->prev#}++++#include "cdio/compat/sector.h"+++-- c2hs can't handle the packed datatype, so get the values from C itself.+msfSizeOf :: Int+msfSizeOf = fromIntegral $ {#call pure sizeof_msf#}++msfAlign :: Int+msfAlign = {#alignof msf_t#}++msfM :: Int+msfM = {#offsetof msf_t->m#}++msfS :: Int+msfS = {#offsetof msf_t->s#}++msfF :: Int+msfF = {#offsetof msf_t->f#}+++{- Never used after definition.+adrSizeOf :: Int+adrSizeOf = {#sizeof cdio_cdrom_addr#}++adrAlign :: Int+adrAlign = {#alignof cdio_cdrom_addr#}+-}
+ src/Foreign/Libcdio/Util.hs view
@@ -0,0 +1,289 @@+{-# LANGUAGE ForeignFunctionInterface #-}++{-|+Description: Miscellaneous utility functions, of limited utility.++Copyright: (c) 2018-2021 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: stable+Portability: non-portable (requires libcdio)++Most functions defined by the C header either encapsulate math to perform on+an object or the system state, or edit `String's in some (barring allocations)+pure manner, including a few with general utility rather than being specific to+libcdio. However, most are also restricted to internal use, and not provided+as symbols exported by the library itself; those internal functions are still+present in the Haskell source as well, for anyone interested. As such, this+module and the functions it provides should rarely need to be used.+++= @util.h@++== Defines+* @CDIO_FREE_IF_NOT_NULL@ (removed; Haskell handles its own memory management)+* @CLAMP@ (removed; preprocessor logic isn't required in Haskell)+* @IN@ (removed; preprocessor logic isn't required in Haskell)+* @MAX@ (removed; preprocessor logic isn't required in Haskell)+* @MAX@ (removed; preprocessor logic isn't required in Haskell)++== Symbols+* @_cdio_strfreev@ (removed; list is automatically freed)+* @_cdio_strsplit@ -> 'Foreign.Libcdio.Util.strsplit'+* @cdio_from_bcd8@ -> 'Foreign.Libcdio.Util.fromBcd8'+* @cdio_realpath@ -> 'Foreign.Libcdio.Util.realpath'+* @cdio_to_bcd8@ -> 'Foreign.Libcdio.Util.toBcd8'+-}+module Foreign.Libcdio.Util+ ( Bcd+ , toBcd8, fromBcd8+ , strsplit+ , realpath+ ) where+++{- Used only by not exported symbols+import qualified Foreign.ForeignPtr as C++import qualified Foreign.Marshal.Alloc as M+import qualified Foreign.Marshal.Array as M+import qualified Foreign.Marshal.Utils as M++import qualified System.IO.Unsafe as IO.Unsafe++import Foreign.Libcdio.Types.Internal+-}++import qualified Data.Word as W+++import qualified Data.Ix as I++import qualified Foreign.C.String as C+import qualified Foreign.C.Types as C+import qualified Foreign.Ptr as C++import qualified Foreign.Marshal.Utils as M+import qualified Foreign.Storable as S++import qualified Numeric as NM++import qualified Text.Printf as P+++import Foreign.Libcdio.Marshal+++{- Not exported+-- | Calculate how many blocks of a given size are required to contain the+-- given number of bytes.+len2blocks+ :: W.Word32+ -- ^ The number of bytes to fit.+ -> W.Word16+ -- ^ The size of each block.+ -> Lsn+len2blocks b s = fromIntegral $ len2blocks' (fromIntegral b) (fromIntegral s)++foreign import ccall safe "cdio/util.h _cdio_len2blocks"+ len2blocks' :: C.CUInt -> C.CUShort -> C.CInt++-- | Round up to the next block boundery after a given offset.+ceil2block+ :: Int+ -- ^ The base address to round.+ -> W.Word16+ -- ^ The size of each block.+ -> Int+ceil2block p s = fromIntegral $ ceil2block' (fromIntegral p) (fromIntegral s)++foreign import ccall safe "cdio/util.h _cdio_ceil2block"+ ceil2block' :: C.CInt -> C.CUShort -> C.CInt+++-- | Add a given length after a given address, potentially putting it at the+-- start of a new block if there is not enough space remaining in the one in+-- which the address is located.+ofsAdd+ :: Int+ -- ^ The base addres.+ -> Int+ -- ^ The number of bytes to add.+ -> W.Word16+ -- ^ The size of each block.+ -> Int+ofsAdd p a s = fromIntegral $ ofsAdd' (fromIntegral p) (fromIntegral a) (fromIntegral s)++foreign import ccall safe "cdio/util.h _cdio_ofs_add"+ ofsAdd' :: C.CInt -> C.CInt -> C.CUShort -> C.CInt+++-- | Print a 'True'/'False' value as "yes"/"no".+--+-- A similar, but not identical, result may be obtained with 'show'.+boolStr :: Bool -> String+boolStr = IO.Unsafe.unsafePerformIO . C.peekCString . boolStr' . M.fromBool++foreign import ccall safe "cdio/util.h _cdio_bool_str"+ boolStr' :: C.CInt -> C.CString+++-- | Copy the contents of one memory address to another, newly allocated one.+memdup :: C.Ptr a -> Word+ -> IO (Maybe (C.ForeignPtr a))+ -- ^ 'Nothing' if the source is 'nullPtr',+ -- or a pointer to the new memory.+memdup p s = do+ p' <- memdup' p (fromIntegral s)+ if p == C.nullPtr+ then return Nothing+ else Just <$> C.newForeignPtr cdioFreePtr p'++foreign import ccall safe "cdio/util.h _cdio_memdup"+ memdup' :: C.Ptr a -> C.CSize -> IO (C.Ptr a)+++-- | Create a copy of a string with all characters transformed to upper case.+--+-- This should be functionally identical to @map toUpper@.+strdupUpper :: String -> IO String+strdupUpper s = C.withCString s strdupUpper' >>= peekFString++foreign import ccall safe "cdio/util.h _cdio_strdup_upper"+ strdupUpper' :: C.CString -> IO C.CString++-- | Duplicate a path and make it platform compliant. Typically needed for+-- MinGW\/MSYS where a "\/c\/..." path must be translated to "c:\/...".+strdupFixpath :: String -> IO (Maybe String)+strdupFixpath s = C.withCString s strdupFixpath' >>= peekNullFString++foreign import ccall safe "cdio/util.h _cdio_strdup_fixpath"+ strdupFixpath' :: C.CString -> IO C.CString+++-- | Count the number of C-style string pointers in a NULL-terminated array.+--+-- As we are already know the list is fully populated, this offers no benefit+-- over 'length'; Haskell's type system will not insert anything acting like a+-- string which is actually @NULL@.+strlenv :: [String] -> IO Word+strlenv ss = M.withMany C.withCString ss $ \ss' ->+ fromIntegral <$> M.withArray0 C.nullPtr ss' strlenv'++foreign import ccall safe "cdio/util.h _cdio_strlenv"+ strlenv' :: C.Ptr C.CString -> IO C.CSize+-}+++-- | Return the substrings between a given delimiter, dropping any empty ones.+--+-- The Haskell repositories provide this via+-- [split](https://hackage.haskell.org/package/split).+--+-- > strsplit str d == Data.List.Split.wordsBy (== d) str+strsplit :: String -> Char -> IO [String]+strsplit s c = C.withCString s (flip strsplit' . fromIntegral $ fromEnum c) >>= peekFStringArray++foreign import ccall safe "cdio/util.h _cdio_strsplit"+ strsplit' :: C.CString -> C.CChar -> IO (C.Ptr C.CString)+++-- | A bitwise encoding where the lower four bits encode a number modulo 10,+-- and the upper encode the same divided by 10.+newtype Bcd = Bcd W.Word8+instance Eq Bcd where+ a == b = fromBcd8 a == fromBcd8 b+instance Ord Bcd where+ compare a b = compare (fromBcd8 a) (fromBcd8 b)+instance Show Bcd where+ showsPrec p i@(Bcd w)+ | mod w 0x10 >= 0xA = showParen (p > application) $+ showString ("Bcd 0x" ++ pad) . NM.showHex w+ | otherwise = showsPrec p $ fromBcd8 i+ where application = 10+ pad | i >= 0x10 = ""+ | otherwise = "0"+instance Read Bcd where+ readsPrec p s =+ map toBcd8Fst (readsPrec p s)+ ++ readParen (p > application)+ (\r -> [ (Bcd i, v ++ ' ' : u)+ | ("Bcd", t) <- lex r+ , ('0':'x':l, u) <- lex t+ , (i, v) <- NM.readHex l+ ]) s+ where toBcd8Fst (w, b) = (toBcd8 w, b)+ application = 10+-- | >>> map fromBcd8 [minBound, maxBound]+-- [0, 159]+instance Bounded Bcd where+ minBound = Bcd 0+ maxBound = Bcd 0xF9+instance Enum Bcd where+ toEnum i = toBcd8 $ toEnum i+ fromEnum b = fromEnum $ fromBcd8 b+ succ i+ | i >= maxBound = error "Enum.succ(Bcd): tried to take `succ' of maxBound"+ | otherwise = toBcd8 . succ $ fromBcd8 i+ pred i+ | i <= minBound = error "Enum.pred(Bcd): tried to take `pred' of minBound"+ | otherwise = toBcd8 . pred $ fromBcd8 i+instance I.Ix Bcd where+ range (a, b) = map toBcd8 $ I.range (fromBcd8 a, fromBcd8 b)+ inRange (a, b) i = I.inRange (fromBcd8 a, fromBcd8 b) $ fromBcd8 i+ index (a, b) i = I.index (fromBcd8 a, fromBcd8 b) $ fromBcd8 i+instance Num Bcd where+ a + b = toBcd8 $ fromBcd8 a + fromBcd8 b+ a - b = toBcd8 $ fromBcd8 a - fromBcd8 b+ a * b = toBcd8 $ fromBcd8 a * fromBcd8 b+ abs i = i+ signum b = toBcd8 . signum $ fromBcd8 b+ fromInteger i = toBcd8 $ fromInteger i+instance Real Bcd where+ toRational b = toRational $ fromBcd8 b+instance Integral Bcd where+ quotRem dividend divisor = (toBcd8 q, toBcd8 r)+ where (q, r) = quotRem (fromBcd8 dividend) (fromBcd8 divisor)+ toInteger b = toInteger $ fromBcd8 b+instance P.PrintfArg Bcd where+ formatArg = P.formatArg . fromBcd8+instance S.Storable Bcd where+ sizeOf (Bcd i) = S.sizeOf i+ alignment (Bcd i) = S.alignment i+ peek p = Bcd <$> S.peek (C.castPtr p)+ poke p (Bcd i) = S.poke (C.castPtr p) i++-- | Encode a number according to the libcdio BCD encoding. If the value is+-- greater than @'maxBound' :: 'Bcd'@, it wraps back around to @0@.+toBcd8 :: Word -> Bcd+toBcd8 = Bcd . fromIntegral . toBcd8' . fromIntegral++foreign import ccall safe "cdio/util.h cdio_to_bcd8"+ toBcd8' :: C.CUInt -> C.CUInt++-- | Decode a number in the libcdio BCD encoding.+fromBcd8 :: Bcd -> Word+fromBcd8 (Bcd i) = fromIntegral . fromBcd8' $ fromIntegral i++foreign import ccall safe "cdio/util.h cdio_from_bcd8"+ fromBcd8' :: C.CUInt -> C.CUInt+++-- | Same as POSIX.1-2001 realpath, if the system provides it. If not,+-- libcdio's "poor-man's simulation" of its behavior.+--+-- The Haskell repositories provide a similar alternative in+-- @System.Directory.canonicalizePath@ from+-- [directory](https://hackage.haskell.org/package/directory).+realpath :: String -> IO (Maybe String)+realpath s = C.withCString s (`realpath'` C.nullPtr) >>= M.maybePeek peekFString++foreign import ccall safe "cdio/util.h cdio_realpath"+ realpath' :: C.CString -> C.CString -> IO C.CString+++{- Pointer logic is not exposed.+-- | Some function which matches the free() prototype.+type DataFree = C.FunPtr (C.Ptr () -> IO ())+-}
+ src/Foreign/Libcdio/Version.hs view
@@ -0,0 +1,90 @@+{-# LANGUAGE ForeignFunctionInterface #-}++{-|+Description: Objects used to determine which version of the C library is used.++Copyright: (c) 2018-2021 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: stable+Portability: non-portable (requires libcdio)++The values in this module are best treated as informational; it may be helpful+to use 'cdioVersionString' in printing copyright, for example, and+'libcdioVersionNum' does serve a purpose in the tests, but all are of little+value outside of such very particular situations. Instead, an effort has been+made to have all version differences in the base library degrade gracefully,+and those fallback values are able to be handled transparently. For example,+rather than explicitly testing whether libcdio is new enough to have exposed+@cdtext_data_init@, simply call 'Foreign.Libcdio.CdText.cdTextDataInit' and+have a plan for if it returns 'Nothing' rather than a @'Just'+'Foreign.Libcdio.CdText.CdText'@.+++= @version.h@++== Defines+* @CDIO_VERSION@ (removed; identical to 'cdioVersionString')+* @LIBCDIO_VERSION_NUM@ (removed; identical to 'libcdioVersionNum')++== Symbols+* @cdio_version_string@ -> 'cdioVersionString'+* @libcdio_version_num@ -> 'libcdioVersionNum'+++= "Sound.Libcdio"+Re-exported unchanged as there is little reason for it to be a separate module,+and no changes need to be made to the types.+-}+module Foreign.Libcdio.Version+ ( V.Version+ , V.makeVersion+ , cdioVersionString+ , libcdioVersionNum+ , apiVersion+ ) where+++import qualified Data.Version as V++import qualified Foreign.C.String as C+import qualified Foreign.C.Types as C++import qualified System.IO.Unsafe as IO.Unsafe+++-- | The value of the preprocessor macro @CDIO_VERSION@, listing both the+-- SemVar-style version of libcdio and the full architecture of the system+-- which compiled it (e.g. @2.0.0 x86_64-pc-linux-gnu@).+cdioVersionString :: String+cdioVersionString = IO.Unsafe.unsafePerformIO $ C.peekCString cdioVersionString'++foreign import ccall safe "cdio/compat/version.h get_cdio_version_string"+ cdioVersionString' :: C.CString+++-- | The value of the preprocessor macro @LIBCDIO_VERSION_NUM@, containing a+-- numeric representation of the version suitable for arithmetic testing.+libcdioVersionNum :: V.Version+libcdioVersionNum+ | v <= 94 = V.makeVersion [0, v]+ | v == 1 = V.makeVersion [1]+ | otherwise = V.makeVersion [j, n, p]+ where v = fromIntegral cdioVersionNum'+ (j, v') = divMod v 10000+ (n, p) = divMod v' 100++foreign import ccall safe "cdio/compat/version.h get_cdio_version_num"+ cdioVersionNum' :: C.CUInt+++-- | The value of the preprocessor macro @CDIO_API_VERSION@, containing a+-- single, monotonically increasing constant representing changes to the public+-- interface. However, as it's somewhat unclear what changes warrant bumping+-- this number, it is typically better to use 'libcdioVersionNum' instead.+apiVersion :: Word+apiVersion = fromIntegral apiVersion'++foreign import ccall safe "cdio/compat/version.h get_cdio_version_api"+ apiVersion' :: C.CUInt
+ src/Sound/Libcdio.hs view
@@ -0,0 +1,48 @@+{-# OPTIONS_HADDOCK not-home #-}++{-|+Description: High-level bindings providing a idiomatic Haskell interface to libcdio.++Copyright: (c) 2019-2021 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: stable+Portability: non-portable (requires libcdio)++One of the goals of these bindings is to make it not only possible to interface+with the libcdio library, but to do so as comfortably and safely as possible.+In that, the "Foreign.Libcdio" interface is a bit lacking, due to its mutable+state and requirement of threading 'IO' through computations. The modules in+this namespace provide an alternative which builds on that base, with a more+native style. As a general rule, a project should /only/ import modules from+the @Sound@ or the @Foreign@ namespaces, not both, as while the types can often+be interchanged, several function names have been reused and so may collide.+-}+module Sound.Libcdio+ ( -- * Types+ -- ** Session+ Cdio+ , CdioError ( .. )+ , CdioErrorType ( .. )+ , SessionArg ( .. )+ , AccessMode ( .. )+ -- ** Version+ , Foreign.Version+ , Foreign.makeVersion+ -- * Evaluation+ , open+ , openMode+ , runCdio+ , getArg+ , getAccessMode+ -- * Library data+ , Foreign.cdioVersionString+ , Foreign.libcdioVersionNum+ , Foreign.apiVersion+ ) where+++import qualified Foreign.Libcdio.Version as Foreign++import Sound.Libcdio.Types.Cdio
+ src/Sound/Libcdio/Common.hs view
@@ -0,0 +1,20 @@+{-# LANGUAGE CPP #-}++module Sound.Libcdio.Common+ ( (<>)+ , CBool+ ) where+++#if MIN_VERSION_base(4,11,0)+#else+import Data.Monoid ( (<>) )+#endif+++#if MIN_VERSION_base(4,10,0)+import Foreign.C.Types ( CBool )+#else+import qualified Foreign.C.Types as C+type CBool = C.CUChar+#endif
+ src/Sound/Libcdio/Device.hs view
@@ -0,0 +1,143 @@+{-|+Description: Information and procedures related to a system's (usually) physical disc drives.++Copyright: (c) 2019-2021 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: stable+Portability: non-portable (requires libcdio)++Any software dealing with CDs has to deal with the fact that they are,+ultimately, a physical medium and thus reading from them requires interfacing+with system hardware. This module provides the means to do just that. Note+that, unlike the C and "Foreign.Libcdio" interfaces, however, this /doesn't/+provide any means to open a read session; that functionality is instead+exported directly from "Sound.Libcdio".+-}+module Sound.Libcdio.Device+ ( -- * Types+ Foreign.HardwareInfo ( .. )+ , Foreign.emptyHardwareInfo+ , Foreign.DriverId ( .. )+ , Foreign.DriverReturnCode ( .. )+ -- ** Capabilities+ , Foreign.DriveCaps+ , Foreign.DriveCapabilityRead ( .. )+ , Foreign.DriveReadCaps+ , Foreign.DriveCapabilityWrite ( .. )+ , Foreign.DriveWriteCaps+ , Foreign.capsWriteCd+ , Foreign.capsWriteDvd+ , Foreign.capsWrite+ , Foreign.DriveCapabilityMisc ( .. )+ , Foreign.DriveMiscCaps+ -- * Drivers+ , driver+ , Foreign.drivers+ , Foreign.osDriver+ , isImageDriver+ , isDevice+ -- * Session+ , setBlocksize+ , setSpeed+ , isMediaChanged+ -- * Devices+ , Foreign.devices+ , Foreign.defaultDevice+ , Foreign.defaultDeviceDriver+ , capabilities+ , deviceCapabilities+ -- ** Images+ , isCue+ , Foreign.isToc+ , Foreign.isNrg+ -- ** Hardware+ , hardware+ , haveAtapi+ , ejectDevice+ , closeDeviceTray+ , closeDeviceTray'+ ) where+++import qualified Data.Maybe as Y++import qualified Foreign.Libcdio.Device as Foreign++import Sound.Libcdio.Types.Cdio+++-- | Get the driver through which the disc is being read.+driver :: Cdio Foreign.DriverId+driver = liftCdio $ fmap (Y.fromMaybe Foreign.DriverUnknown) . Foreign.driverId++-- | Whether a particular driver deals with image files saved to disc, or a CD+-- drive itself.+isImageDriver :: Foreign.DriverId -> Bool+isImageDriver = not . flip elem Foreign.deviceDrivers+++-- | Get a description of the device in use.+hardware :: Cdio Foreign.HardwareInfo+hardware = liftCdio $ fmap (Y.fromMaybe Foreign.emptyHardwareInfo) . Foreign.hwinfo++-- | Which features are provided by the current device. See+-- 'deviceCapabilities' when a session has not yet been opened.+capabilities :: Cdio Foreign.DriveCaps+capabilities = liftCdio Foreign.driveCap++-- | Whether ATAPI commands are understood by the current device.+-- +-- Returns 'Nothing' if the capability can't be determined.+haveAtapi :: Cdio (Maybe Bool)+haveAtapi = liftCdio Foreign.haveAtapi+++-- | Which features are provided by a particular device. See 'capabilities'+-- for accessing these within a 'Cdio' session.+deviceCapabilities :: FilePath -> IO Foreign.DriveCaps+deviceCapabilities = Foreign.driveCapDevice+++-- | Open a particular device's tray or otherwise free any disc it holds for+-- removal, replacement, or insertion.+ejectDevice :: Maybe FilePath -> IO Foreign.DriverReturnCode+ejectDevice = Foreign.ejectDrive++-- | If a device supports discs on an extending, motorized tray (i.e. a+-- standard CD drive), close it.+closeDeviceTray :: Maybe FilePath -> IO Foreign.DriverReturnCode+closeDeviceTray = fmap fst . flip Foreign.closeTray Foreign.DriverUnknown++-- | As 'closeDeviceTray'', but specify the driver to use in case of ambiguity.+closeDeviceTray' :: Maybe FilePath -> Foreign.DriverId -> IO Foreign.DriverReturnCode+closeDeviceTray' p = fmap fst . Foreign.closeTray p+++-- | Specify how much data should be read from a disc at once. Note that this+-- only affects the transport; any reading functions operate on independant+-- byte counts or other sizes derived from such.+setBlocksize :: Int -> Cdio Foreign.DriverReturnCode+setBlocksize s = liftCdio $ flip Foreign.setBlocksize s++-- | Specify the speed at which the disc is read. Lower values result in+-- slower IO, but better accuracy.+setSpeed :: Int -> Cdio Foreign.DriverReturnCode+setSpeed s = liftCdio $ flip Foreign.setSpeed s+++-- | Check if any data in the read session has been changed since the last call+-- of this function. This is most helpful when multiple 'Cdio' computations+-- are run on a partial call of 'Sound.Libcdio.Types.Cdio.open' or similar.+isMediaChanged :: Cdio (Either Foreign.DriverReturnCode Bool)+isMediaChanged = liftCdio Foreign.isMediaChanged+++-- | Whether a file is valid according to the (loose) CUE standard.+isCue :: FilePath -> IO Bool+isCue = fmap Y.isJust . Foreign.binFromCue++-- | Whether the path represents a physical disc drive in the system.+isDevice :: FilePath -> IO Bool+isDevice = flip Foreign.isDevice Foreign.DriverDevice
+ src/Sound/Libcdio/Logging.hs view
@@ -0,0 +1,92 @@+{-|+Description: Control over and access to library log output.++Copyright: (c) 2020-2021 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: stable+Portability: non-portable (requires libcdio)++The underlying library is rather loud in its error and warning messages,+potentially emitting a lot of impure terminal clutter even on some+otherwise-pure functions. Very helpfully, it also provides a mechanism for+integrating the logs with whatever framework is in place for the larger+project; that mechanism can be leveraged to cache the logs in memory until+specifically asked for, at which point they can be packaged into Haskell types.+Some of the immediacy—and therefore user ability to match note to source—is+unfortunately lost, but the apparent purity is worth it.+-}+module Sound.Libcdio.Logging+ ( -- * Types+ LibcdioLogger ( .. )+ , Foreign.LogEntry ( .. )+ , Foreign.LogLevel ( .. )+ -- * Utility+ , isolateLogs+ , Foreign.setupLogger+ ) where+++import qualified Foreign.Libcdio.Logging as Foreign+++-- | An environment which integrates the libcdio logging interface; will almost+-- always be a 'Monad', but as an 'Applicative' might technically be able to+-- implement these, that constraint isn't enforced.+class LibcdioLogger m where+ logCutoff :: m Foreign.LogLevel+ -- ^ Check the current minimum severity which will be recorded in the+ -- logs.+ setLogCutoff :: Foreign.LogLevel -> m ()+ -- ^ Set the minimum severity required for a message to be recorded in+ -- the logs.+ readLog :: m [Foreign.LogEntry]+ -- ^ Retrieve all messages currently in the log for further processing.+ -- Note that this retains the contents of the log for future calls; to+ -- remove them, a separate call to 'clearLog' must be made.+ --+ -- >>> putLog $ LogEntry LogWarn "Testing log reading" >>= readLog+ -- [LogEntry LogWarn "Testing log reading"]+ --+ -- >>> clearLog >>= readLog+ -- []+ clearLog :: m ()+ -- ^ Empty all messages currently in the log. There is no way to+ -- selectively remove only some messages; if that is desired, call+ -- 'readLog' first:+ --+ -- >>> setupLogger+ -- >>> msgs <- readLog+ -- >>> clearLog+ -- >>> mapM_ putLog $ filter p msgs+ putLog :: Foreign.LogEntry -> m ()+ -- ^ Append a message to the logs.++-- | The required initialization function 'Foreign.setupLogger' isn't called+-- automatically; /make sure/ to do so manually before using any of these.+instance LibcdioLogger IO where+ logCutoff = Foreign.logCutoff+ setLogCutoff = Foreign.setLogCutoff+ readLog = Foreign.readLog+ clearLog = Foreign.clearLog+ putLog = Foreign.putLog+++-- | Keep the monad pure by preventing it from reading stale logs, but since+-- the outer IO might still care about them, restore the entire stack after.+--+-- Note that the logs are /not/ thread-safe; messages from other threads may be+-- interwoven with those from the passed computation even after this function+-- is called.+isolateLogs :: (Monad m, LibcdioLogger m) => m a -> m a+isolateLogs a' = do+ es <- readLog+ clearLog++ a <- a'+ es' <- readLog+ clearLog++ mapM_ putLog $ es ++ es'+ return a
+ src/Sound/Libcdio/Read/CdText.hs view
@@ -0,0 +1,415 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE MultiParamTypeClasses #-}++{-|+Description: Functions providing metadata about the contents of a disc.++Copyright: (c) 2019-2021 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: stable+Portability: non-portable (requires libcdio)++Metadata is stored in a binary format both library-internally and on the disc.+Most audio archivists will recognize it as "those information fields in a CUE+file" (though there are [other+formats](https://www.gnu.org/software/libcdio/cd-text-format.html#Sony-Text-File-Format-_0028Input-Sheet-Version-0_002e7T_0029)+as well), and casual listeners will recognize it as the scrolling text that+you're always happy to see, on the rare times your music player shows it.+Little-used and even-less-known, however, is that a single disc can+theoretically contain metadata in up to eight different languages; because of+the complexity that introduces, it makes more sense to use a second monadic+interface than to try to provide a single monolithic datatype within 'Cdio'.+-}+module Sound.Libcdio.Read.CdText+ ( -- * Types+ CdText+ , CdTextError ( .. )+ , CdTextErrorType ( .. )+ , Info ( .. )+ , emptyInfo+ , Foreign.Genre ( .. )+ , Foreign.Language ( .. )+ -- * Evaluation+ , cdText+ , parseCdText+ , withLanguage+ , withIndex+ , withAll+ , runCdText+ -- * Data+ , language+ , languages+ , firstTrack+ , lastTrack+ , info+ , discId+ , genre+ , cdTextRaw+ ) where+++import qualified Control.Applicative as A+#if MIN_VERSION_mtl(2,2,1)+import qualified Control.Monad.Except as N.E+#else+import qualified Control.Monad.Error as N.E+#endif+import qualified Control.Monad.Fail as N.F++import qualified Data.ByteString as BS+import qualified Data.Maybe as Y+import qualified Data.Text as T++import qualified Foreign.Libcdio.CdText as Foreign+import qualified Foreign.Libcdio.Disc as Foreign+import qualified Foreign.Libcdio.Logging as Foreign++import qualified Text.Show as R++import Sound.Libcdio.Logging+import Sound.Libcdio.Track+import Sound.Libcdio.Types.Cdio++import Control.Applicative ( (<|>) )+import Data.Functor ( ($>) )+++-- | A computation within the environment of metadata (in a particular+-- language) stored on a CD. The options for affecting that environment+-- from within are limited by design, as this library is intended for /reading/+-- discs rather than /authoring/ them.+newtype CdText a = CdText (Maybe InitialLanguage -> Foreign.Cdio -> IO (Either CdTextError a))+instance Functor CdText where+ fmap f (CdText a) = CdText $ \l c -> fmap f <$> a l c+instance Applicative CdText where+ pure a = CdText $ \_ _ -> return $ Right a+ CdText f <*> CdText a = CdText $ \l c -> do+ f' <- f l c+ a' <- a l c+ return $ f' <*> a'+-- | 'A.empty' fails with 'CdTextEmpty'.+instance A.Alternative CdText where+ empty = CdText $ \_ _ -> return . Left . CdTextError CdTextEmpty $ T.pack "empty"+ CdText f <|> CdText g = CdText $ \l c -> f l c <|> g l c+instance Monad CdText where+ CdText a >>= f = CdText $ \l c -> do+ a' <- a l c+ let bind' a'' = let CdText b = f a'' in b l c+ either (return . Left) bind' a'+-- | Wraps the text in a 'FreeformCdTextError', for recovery with 'N.E.catchError'.+instance N.F.MonadFail CdText where+ fail e = CdText $ \_ _ ->+ return . Left $ CdTextError (FreeformCdTextError $ T.pack e) (T.pack "fail")+instance N.E.MonadError CdTextError CdText where+ throwError err = CdText $ \_ _ -> return $ Left err+ catchError (CdText f) e = CdText $ \l c -> f l c >>= \a' -> case a' of+ Left err ->+ let CdText g = e err+ in g l c+ Right a -> return $ Right a+instance LibcdioLogger CdText where+ logCutoff = CdText $ \_ _ -> Right <$> Foreign.logCutoff+ setLogCutoff l = CdText $ \_ _ -> Right <$> Foreign.setLogCutoff l+ readLog = CdText $ \_ _ -> Right <$> Foreign.readLog+ clearLog = CdText $ \_ _ -> Right <$> Foreign.clearLog+ putLog e = CdText $ \_ _ -> Right <$> Foreign.putLog e++-- | Lift a metadata computation from the C-style "Foreign.Libcdio" interface+-- into the monadic "Sound.Libcdio".+liftCdText :: (Foreign.Cdio -> IO a) -> CdText a+liftCdText f = CdText $ \_ c -> Right <$> f c+++-- | Associates a well-typed error with human-readable context information.+data CdTextError = CdTextError CdTextErrorType T.Text+ deriving ( Eq, Show, Read )++-- | Potential situations which may cause a computation to fail.+data CdTextErrorType+ = InvalidBlock Word+ -- ^ The requested language index is outside of the bounds accessible+ -- by the library (@[0..7]@ in libcdio 2.1 and after, or the smaller+ -- range of languages returned by 'languages' before that version).+ | LanguageNotFound Foreign.Language+ -- ^ The CdText data does not contain the requested language, or+ -- 'Foreign.UnknownLanguage' was requested (prior to libcdio 2.1 there+ -- was no way to select the latter blocks; even after that version,+ -- 'withIndex' must be used instead).+ | BadBinaryRead+ -- ^ The binary data can not be parsed into a CdText object.+ | NoCdText+ -- ^ The CD contains no CdText data.+ | CdTextEmpty+ -- ^ 'A.empty' was called and no better alternative was encountered.+ | FreeformCdTextError T.Text+ -- ^ Escape hatch from structured typing to allow user-specified+ -- (and user-triggered) errors.+ deriving ( Eq, Show, Read )+++-- | The language which was active at the beginning of the 'CdText'+-- computation.+data InitialLanguage+ = Lang Foreign.Language+ -- ^ The language was chosen specifically.+ | Index Word+ -- ^ The language was chosen by index.+ | Default+ -- ^ No language was explicitly set.++-- | Restore the active language to whatever it was before a 'CdText'+-- computation was run.+resetLanguage :: Maybe InitialLanguage -> Foreign.Cdio -> IO ()+resetLanguage Nothing _ = mempty+resetLanguage (Just (Lang l)) c = Foreign.selectLanguage c l >> mempty+resetLanguage (Just (Index i)) c = Foreign.selectLanguageIndex c i >> mempty+resetLanguage (Just Default) c = Foreign.selectLanguageIndex c 0 >> mempty+++-- | Textual metadata describing a single track on a disc, or the disc itself.+data Info = Info+ { title :: Maybe T.Text+ , performer :: Maybe T.Text+ , songwriter :: Maybe T.Text+ , composer :: Maybe T.Text+ , arranger :: Maybe T.Text+ , message :: Maybe T.Text+ -- ^ An otherwise-uncategorized comment.+ , code :: Maybe T.Text+ -- ^ Either a UPC/EAN (for the disc) or an ISRC (for a track).+ }+ deriving ( Eq )+-- | Modeled after the standard record syntax, but omitting any 'Nothing'+-- fields for space reasons.+instance Show Info where+ showsPrec d ts = R.showParen (d > 10)+ $ R.showString "Info { "+ . maybeShows title "title"+ . maybeShows performer "performer"+ . maybeShows songwriter "songwriter"+ . maybeShows composer "composer"+ . maybeShows arranger "arranger"+ . maybeShows message "message"+ . maybeShows code "code"+ . R.showString "}"+ where maybeShows f n+ | Just t <- f ts =+ R.showString (n ++ " = ")+ . shows t+ . R.showString ", "+ | otherwise = id+instance Read Info where+ readsPrec p =+ readParen (p > 10) $ \r ->+ [ (Info t f w c a m o, r10)+ | ("Info", r1) <- lex r+ , ("{", r2) <- lex r1+ , (t, r3) <- maybeLex "title" r2+ , (f, r4) <- maybeLex "performer" r3+ , (w, r5) <- maybeLex "songwriter" r4+ , (c, r6) <- maybeLex "composer" r5+ , (a, r7) <- maybeLex "arranger" r6+ , (m, r8) <- maybeLex "message" r7+ , (o, r9) <- maybeLex "code" r8+ , ("}", r10) <- lex r9+ ]+ where maybeLex t s' = do+ (t', s1) <- lex s'+ if t == t'+ then do+ ("=", s2) <- lex s1+ (x, s3) <- reads s2+ (",", s4) <- lex s3+ return (Just x, s4)+ else return (Nothing, s')++-- | An 'Info' object with values suitable as defaults.+emptyInfo :: Info+emptyInfo = Info+ { title = Nothing+ , performer = Nothing+ , songwriter = Nothing+ , composer = Nothing+ , arranger = Nothing+ , message = Nothing+ , code = Nothing+ }+++-- | Use a C-style 'Foreign.Cdio' object as the base to run a Haskell-style+-- 'CdText' computation.+-- +-- Note that some invariants of the monadic interface may not work as expected+-- when used with the mutable objects, usually due to changing the active+-- language block:+-- +-- @+-- l <- 'Foreign.language' cdio+-- _ <- 'runCdText' cdio $ 'withIndex' i g+-- l' <- 'Foreign.language' cdio+-- (l == l') == undefined+-- @+runCdText :: Foreign.Cdio -> CdText a -> IO (Either CdTextError a)+runCdText c (CdText f) = isolateLogs $ f Nothing c+++-- | Run the given computation within the CdText data associated with the+-- 'Cdio' session. At this top level, a @'withIndex' 0@ specifically will+-- almost always have the same effect as running the computation directly.+-- Fails with 'NoCdText' if the disc doesn't provide any metadata.+cdText :: CdText a -> Cdio (Either CdTextError a)+cdText (CdText f) = liftCdio $ \c' -> if Foreign.hasCdText c'+ then isolateLogs $ f (Just Default) c'+ else return . Left . CdTextError NoCdText $ T.pack "cdText"++-- | Given a binary stream, attempt to parse it as a CdText block and run the+-- given computation. Returns @'Left' 'BadBinaryRead'@ if that parse fails.+-- At this top level, a @'withIndex' 0@ specifically will almost always have+-- the same effect as running the computation directly.+--+-- Note that binary CdText dumps will frequently include four bytes at the+-- beginning indicating the size of the file; this implementation expects that+-- those bytes /are not/ included. If your dump does indeed begin with them,+-- @'BS.drop' 4@ before passing the 'BS.ByteString' to this function.+--+-- /Before libcdio 0.94: Always returns @'Left' 'BadBinaryRead'@/+parseCdText :: BS.ByteString -> CdText a -> IO (Either CdTextError a)+parseCdText bs (CdText f) = isolateLogs $ do+ c <- Foreign.cdTextDataInit bs+ case c of+ Just c' -> f (Just Default) c'+ Nothing -> return . Left . CdTextError BadBinaryRead $ T.pack "parseCdText"+++-- | Try to use a specific language as the context for the given computation;+-- as this will frequently fail with 'LanguageNotFound' if given anything other+-- than 'Foreign.English', it is recommended that you provide a fallback with+-- 'A.<|>' or at least allow recovery with 'A.optional'. Note that+-- 'Foreign.UnknownLanguage' will always fail.+withLanguage :: Foreign.Language -> CdText a -> CdText a+withLanguage l (CdText f) = CdText $ \l' c -> isolateLogs $ do+ b <- Foreign.selectLanguage c l+ a <- if b+ then f (Just $ Lang l) c+ else return . Left . CdTextError (LanguageNotFound l) $ T.pack "withLanguage"+ resetLanguage l' c+ return a++-- | Run the given computation over the data in a specific block. Fails with+-- 'InvalidBlock' if the index can't be accessed.+withIndex :: Word -> CdText a -> CdText a+withIndex i x = CdText $ \l c -> do+ a <- withIndex' "withIndex" c x i+ resetLanguage l c+ return a++-- | Underlying logic for index-based block selection. Fails with+-- 'InvalidBlock' if the index can't be accessed.+withIndex'+ :: String+ -- ^ The function calling this, for error printing.+ -> Foreign.Cdio+ -- ^ The underlying disc session.+ -> CdText a+ -- ^ The computation to run.+ -> Word+ -- ^ The index to select.+ -> IO (Either CdTextError a)+withIndex' s c (CdText f) i = do+ b <- Foreign.selectLanguageIndex c i+ if b+ then f (Just $ Index i) c+ else return . Left . CdTextError (InvalidBlock i) $ T.pack s++-- | Run the given computation over /all/ of the accessible languages in the+-- CdText data. When successful, the resulting list can be associated exactly+-- with the list of 'languages':+--+-- >>> ls <- 'languages'+-- >>> Right ls' <- 'cdText' $ 'withAll' 'language'+-- >>> ls == ls'+-- True+withAll :: CdText a -> CdText [Maybe a]+withAll x = CdText $ \l c -> do+ ls <- Foreign.listAllLanguages c+ let is = zipWith ($>) ls [0..]+ as <- mapM (withBlock c) is+ resetLanguage l c+ return $ sequence as+ where withBlock c (Just i) = fmap Just <$> withIndex' "withAll" c x i+ withBlock _ Nothing = return $ Right Nothing+++-- | Get the raw binary data making up the CdText data, if any exists on the+-- disc.+cdTextRaw :: Cdio (Maybe BS.ByteString)+cdTextRaw = liftCdio Foreign.cdTextRaw+++-- | Get the language in which any info is currently being retrieved.+language :: CdText Foreign.Language+language = liftCdText $ fmap (Y.fromMaybe Foreign.UnknownLanguage) . Foreign.language++-- | List every language with associated data in the CdText data associated+-- with the session. Drops any 'Foreign.UnknownLanguage' values from the end+-- of the list. For a version which operates within the 'CdText' monad, the+-- construction @'withAll' 'language'@ will have an identical effect.+--+-- /Before libcdio 2.1.0: Silently drops any 'Nothing' or/+-- /@'Just' 'Foreign.UnknownLanguage'@ values, even in the middle of the list,/+-- /and only lists any single language a maximum of one time./+languages :: Cdio [Maybe Foreign.Language]+languages = liftCdio Foreign.listAllLanguages+++-- | The earliest track with any associated metadata in the current language.+-- Note that this may differ from 'Sound.Libcdio.Track.minTrack' which gives+-- the first track on the disk, CDTEXT or not.+firstTrack :: CdText Track+firstTrack = liftCdText $ fmap (Y.fromMaybe 1) . Foreign.firstTrack++-- | The final track with any associated metadata in the current language.+-- Note that this may differ from 'Sound.Libcdio.Track.maxTrack' which gives+-- the last track on the disc, CDTEXT or not.+lastTrack :: CdText Track+lastTrack = liftCdText $ fmap (Y.fromMaybe 1) . Foreign.lastTrack+++-- | Publisher-specific catalogue number, or some other context-specific+-- identifier. Note that this may be different than @'code' $ 'info'+-- 'Nothing'@ which is (assumed to be) the unambiguous bar code unique to this+-- disc release.+discId :: CdText (Maybe T.Text)+discId = liftCdText $ \c -> fmap T.pack <$> Foreign.cdTextGet c Foreign.DiscId Nothing++-- | The genre describing the music on this disc, and any associated+-- human-readable name or subgenre.+genre :: CdText (Maybe Foreign.Genre, Maybe T.Text)+genre = liftCdText $ \c -> do+ g <- Foreign.genre c+ s <- Foreign.cdTextGet c Foreign.GenreName Nothing+ return (g, T.pack <$> s)+++-- | Retrieve the collection of data associated with a specific track, or if+-- 'Nothing', the disc itself.+info :: Maybe Track -> CdText Info+info t = liftCdText $ \c -> do+ l <- Foreign.cdTextGet c Foreign.Title t+ p <- Foreign.cdTextGet c Foreign.Performer t+ s <- Foreign.cdTextGet c Foreign.Songwriter t+ w <- Foreign.cdTextGet c Foreign.Composer t+ a <- Foreign.cdTextGet c Foreign.Arranger t+ m <- Foreign.cdTextGet c Foreign.Message t+ o <- Foreign.cdTextGet c (if Y.isNothing t then Foreign.UpcEan else Foreign.Isrc) t+ return $ Info+ { title = T.pack <$> l+ , performer = T.pack <$> p+ , songwriter = T.pack <$> s+ , composer = T.pack <$> w+ , arranger = T.pack <$> a+ , message = T.pack <$> m+ , code = T.pack <$> o+ }
+ src/Sound/Libcdio/Read/Data.hs view
@@ -0,0 +1,173 @@+{-|+Description: Methods of retreaving the actual stored data.++Copyright: (c) 2019-2021 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: stable+Portability: non-portable (requires libcdio)++This module is likely what most usage of the library revolves around:+retrieving the data stored on a CD. For more discussion of the layout, see+"Foreign.Libcdio.Sector".+-}+module Sound.Libcdio.Read.Data+ ( -- * Types+ Foreign.Lsn+ , Foreign.Whence ( .. )+ , Foreign.DiscMode ( .. )+ , Foreign.isCdRom+ , Foreign.isDvd+ -- * Info+ , discMode+ , discJolietLevel+ , lastAddress+ , lastSessionAddress+ , audioTimestamp+ , catalogue+ , isrc+ -- * Read+ -- $read-design+ , seek+ , readRaw+ , readAudio+ , readData+ , readXa+ -- * Basic counts+ , Foreign.framesPerSec+ , maxCdSectors+ , maxCdMinutes+ , defaultPregapSectors+ , defaultPostgapSectors+ ) where+++import qualified Data.ByteString as BS+import qualified Data.Text as T++import qualified Foreign.Libcdio.Device as Foreign+import qualified Foreign.Libcdio.Disc as Foreign+import qualified Foreign.Libcdio.Read as Foreign+import qualified Foreign.Libcdio.Sector as Foreign+import qualified Foreign.Libcdio.Track as Foreign++import Sound.Libcdio.Device+import Sound.Libcdio.Types.Cdio+++-- | Determine which type of disc is being accessed.+discMode :: Cdio (Maybe Foreign.DiscMode)+discMode = liftCdio Foreign.discMode++-- | The original ISO 9660 (data) filesystem specification was rather+-- restrictive in what files could be named; the Joliet extensions allow such+-- exciting features as lowercase letters, not to mention full Unicode support.+discJolietLevel :: Cdio (Maybe Word)+discJolietLevel = liftCdio Foreign.discJolietLevel+++-- | Get the size of a disc in blocks, or equivalently the address of the end+-- of the readable data.+lastAddress :: Cdio (Maybe Foreign.Lsn)+lastAddress = liftCdio Foreign.lastLsn++-- | Get the starting address of the last write session of a disc.+lastSessionAddress :: Cdio (Either DriverReturnCode Foreign.Lsn)+lastSessionAddress = liftCdio Foreign.lastSession+++-- | The number of sectors spanned by a track pre-gap by default.+defaultPregapSectors :: Word+defaultPregapSectors = Foreign.pregapSectors++-- | The number of sectors spanned by a track post-gap by default.+defaultPostgapSectors :: Word+defaultPostgapSectors = Foreign.postgapSectors+++-- | Print a disc timestamp in the standard "MM:SS:FF" format, assuming the+-- address refers to audio data.+audioTimestamp :: Foreign.Lsn -> T.Text+audioTimestamp = T.pack . Foreign.msfToStr . Foreign.lsnToMsf++-- | The maximum number of sectors allowed to be stored on a disc.+maxCdSectors :: Word+maxCdSectors = Foreign.maxSectors++-- | The typical maximum length of a disc, though it's not a strict limit.+maxCdMinutes :: Word+maxCdMinutes = Foreign.cdMins+++-- | Get the media catalog number from a disc. This may also be retrieved+-- by @'Sound.Libcdio.Read.CdText.code' $ 'Sound.Libcdio.Read.CdText.info'+-- 'Nothing'@, though that references a different source and thus may not have+-- the same return value.+catalogue :: Cdio (Maybe T.Text)+catalogue = liftCdio $ \c -> fmap T.pack <$> Foreign.cdMcn c++-- | The International Standard Recording Code the given track. This may also+-- be retrieved by @'Sound.Libcdio.Read.CdText.code' .+-- 'Sound.Libcdio.Read.CdText.info' $ 'Just' t@, though that references a+-- different source and thus may not have the same return value.+isrc :: Foreign.Track -> Cdio (Maybe T.Text)+isrc t = liftCdio $ \c -> fmap T.pack <$> Foreign.trackIsrc c t+++-- $read-design+-- For now, the library isn't able to automatically determine which @read*@+-- function should be used; refer to 'Sound.Libcdio.Track.format', and switch+-- on its return value. For more info on the various data layouts, see the+-- intro to "Foreign.Libcdio.Sector".+--+-- Compared to the C and @Foreign@ interfaces, /all/ read functions have been+-- tweaked for better internal consistency. Where a @cdio_read@ or+-- 'Foreign.readBytes' call would ask for the number of bytes to read, here it+-- asks for the number of /sectors/. On the other hand, the formerly+-- sector-oriented commands operate from the current 'seek' position rather+-- than, effectively, hiding a 'seek' behind the scenes.+++-- | Reposition the read pointer in the 'Cdio' session for a future call to+-- one of the @read*@ functions.+seek :: Int -> Foreign.Whence -> Cdio Foreign.Lsn+seek o w = liftCdioError $ \c -> do + o' <- Foreign.seek c (o * fromIntegral Foreign.sectorSize) w+ pos <- case flip mod Foreign.sectorSize <$> o' of+ Right drift | drift /= 0 -> Foreign.seek c (fromIntegral $ negate drift) Foreign.SeekCurrent+ _ -> return o'+ return . packCdioError' "seek" $ fromIntegral . flip div Foreign.sectorSize <$> pos+++-- | Read a given number of sectors from the disc. With data of a known+-- structure, use 'readAudio', 'readData', or 'readXa', which /don't/ include+-- the headers and footers described in "Foreign.Libcdio.Sector".+readRaw :: Word -> Cdio BS.ByteString+readRaw l = liftCdioError $ \c -> do+ bs <- Foreign.readBytes c (l * Foreign.sectorSize)+ return . packCdioError' "readAudio" $ maybe (Left Foreign.DriverError) Right bs++-- | Read a given number of sectors stored as CD-DA from the disc.+readAudio :: Word -> Cdio BS.ByteString+readAudio l = seek 0 Foreign.SeekCurrent >>= liftCdioError' (\c o ->+ packCdioError' "readAudio" <$> Foreign.readAudioSectors c o l)++-- | Read a given number of sectors stored as Mode 1 data from the disc.+readData+ :: Bool+ -- ^ If 'True' Form 2, otherwise Form 1 (see "Foreign.Libcdio.Sector").+ -> Word+ -> Cdio BS.ByteString+readData m l = seek 0 Foreign.SeekCurrent >>= liftCdioError' (\c o ->+ packCdioError' "readData" <$> Foreign.readDataModeSectors c o m l)++-- | Read a given number of sectors stored according to the Mode 2 extension+-- from the disc.+readXa+ :: Bool+ -- ^ If 'True' Form 2, otherwise Form 1 (see "Foreign.Libcdio.Sector").+ -> Word+ -> Cdio BS.ByteString+readXa f l = seek 0 Foreign.SeekCurrent >>= liftCdioError' (\c o ->+ packCdioError' "readXA" <$> Foreign.readXaModeSectors c o f l)
+ src/Sound/Libcdio/Read/Filesystem.hs view
@@ -0,0 +1,40 @@+{-|+Description: Objects used to describe the CD and filesystem format.++Copyright: (c) 2020-2021 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: stable+Portability: non-portable (requires libcdio)++Like any drive, discs may store their data according to many different+filesystem structures. These are abstracted to a degree in libcdio, but as+each track may store its data differently, and at the very least+'Foreign.Audio' is handled differently than any of the file-oriented layouts,+it is still helpful to know the underlying structure. This module, then, is a+counterpart to "Sound.Libcdio.Read.Data", providing information about the+/structure/ for the latter's retrieval of /data/.+-}+module Sound.Libcdio.Read.Filesystem+ ( -- * Types+ Foreign.Filesystem ( .. )+ , Foreign.FilesystemClass ( .. )+ , Foreign.FilesystemClasses+ , Foreign.fsAny+ , Foreign.fsAnyVcd+ , Foreign.IsoAnalysis ( .. )+ -- * Query+ , trackType+ ) where+++import qualified Foreign.Libcdio.CdTypes as Foreign++import Sound.Libcdio.Track+import Sound.Libcdio.Types.Cdio+++-- | Determine what type of file system is stored in the given track of a disc.+trackType :: Track -> Cdio (Maybe Foreign.Filesystem, Foreign.FilesystemClasses, Maybe Foreign.IsoAnalysis)+trackType = liftCdio . flip Foreign.trackType
+ src/Sound/Libcdio/Track.hs view
@@ -0,0 +1,128 @@+{-|+Description: Information about the division of a single disc into tracks.++Copyright: (c) 2019-2021 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: stable+Portability: non-portable (requires libcdio)++What many people would think of as the most important division on a CD isn't+quite as an integral a part of the physical data layout: they are described in+a table of contents before the first track of any recording session, and may+have lower-resolution "echoes" in the subchannels alongside the data, but it+would be hard to otherwise recover the track boundaries from the data itself.+This module, then, provides the functions to retrieve that metadata from the+table of contents and from the subchannels.+-}+module Sound.Libcdio.Track+ ( -- * Types+ Foreign.Track ( .. )+ , Foreign.minTrack+ , Foreign.maxTrack+ , Foreign.TrackNum+ , Foreign.TrackFormat ( .. )+ -- * Location+ , firstDiscTrack+ , lastDiscTrack+ , tracks+ -- ** Address+ , trackAt+ , pregap+ , offset+ , offsetEnd+ , totalLength+ -- * Data+ , format+ , isGreen+ , hasPreemphasis+ , copyPermit+ , quadAudio+ ) where+++import qualified Foreign.Libcdio.Disc as Foreign+import qualified Foreign.Libcdio.Track as Foreign++import Sound.Libcdio.Read.Data+import Sound.Libcdio.Types.Cdio+++-- | The number of the first track on the disc. This will almost always be 1,+-- but that is not strictly guaranteed; the (perhaps theoretical) example is of+-- a multi-disc set, where later discs pick the numbering back up where the+-- previous one left off.+-- +-- Returns 'Nothing' if the disc table of contents can't be read.+firstDiscTrack :: Cdio (Maybe Foreign.Track)+firstDiscTrack = liftCdio Foreign.firstTrackNum++-- | The number of the last track on the disc.+-- +-- Returns 'Nothing' if the disc table of contents can't be read.+lastDiscTrack :: Cdio (Maybe Foreign.Track)+lastDiscTrack = liftCdio Foreign.lastTrackNum+++-- | Get the number of tracks on a CD.+-- +-- Returns 'Nothing' if the disc table of contents can't be read.+tracks :: Cdio (Maybe Foreign.Track)+tracks = liftCdio Foreign.numTracks++-- | The track which contains the given address.+-- +-- Returns 'Nothing' if the address is beyond the written data on the disc.+-- Note that 'Foreign.DiscLeadout' is treated as if it were a single sector+-- long:+-- +-- >>> Just endTrack <- lastDiscTrack+-- >>> Just endAddr <- offsetEnd endTrack+-- >>> trackAt $ endAddr + 1+-- Just DiscLeadout+-- >>> trackAt $ endAddr + 2+-- Nothing+trackAt :: Lsn -> Cdio (Maybe Foreign.Track)+trackAt = liftCdio . flip Foreign.trackAt+++-- | The address of the start of any pregap before the given track.+pregap :: Foreign.Track -> Cdio (Maybe Lsn)+pregap = liftCdio . flip Foreign.pregapLsn++-- | The address of the start of the given track.+offset :: Foreign.Track -> Cdio (Maybe Lsn)+offset = liftCdio . flip Foreign.trackLsn++-- | The address of the end of the given track.+offsetEnd :: Foreign.Track -> Cdio (Maybe Lsn)+offsetEnd = liftCdio . flip Foreign.trackLastLsn++-- | The number of sectors "assigned" to the specified track, including any in+-- the pregap between it and the following one.+totalLength :: Foreign.Track -> Cdio (Maybe Word)+totalLength = liftCdio . flip Foreign.sectorCount+++-- | The raw data structure of a track.+format :: Foreign.Track -> Cdio (Maybe Foreign.TrackFormat)+format = liftCdio . flip Foreign.trackFormat++-- | Whether the track data was stored using the Green Book (CD-i) standard.+isGreen :: Foreign.Track -> Cdio (Maybe Bool)+isGreen = liftCdio . flip Foreign.isGreen+++-- | Whether preemphasis has been applied to the track for noise reduction.+hasPreemphasis :: Foreign.Track -> Cdio (Maybe Bool)+hasPreemphasis = liftCdio . flip Foreign.hasPreemphasis++-- | Whether the track may be legally copied.+copyPermit :: Foreign.Track -> Cdio (Maybe Bool)+copyPermit = liftCdio . flip Foreign.copyPermit++-- | Whether the track was encoded with a richer 4-channel structure, or+-- whether it just includes the standard stereo (2-channel) layout.+quadAudio :: Foreign.Track -> Cdio (Maybe Bool)+quadAudio t = liftCdio $ \c -> fmap (> 2) <$> Foreign.numChannels c t
+ src/Sound/Libcdio/Types.hs view
@@ -0,0 +1,61 @@+{-# OPTIONS_HADDOCK not-home #-}++{-|+Description: Common types used in the high-level interface.++Copyright: (c) 2019-2021 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: stable+Portability: non-portable (requires libcdio)+-}+module Sound.Libcdio.Types+ ( -- * Disc+ Cdio+ , CdioError+ , CdioErrorType+ , Whence+ , Lsn+ , Track+ , TrackNum+ , TrackFormat+ , SessionArg+ -- * CdText+ , CdText+ , CdTextError+ , CdTextErrorType+ , Info+ , Genre+ , Language+ -- * Hardware+ , DriverId+ , DriverReturnCode+ , HardwareInfo+ , DriveCapabilityRead+ , DriveReadCaps+ , DriveCapabilityWrite+ , DriveWriteCaps+ , DriveCapabilityMisc+ , DriveMiscCaps+ , DriveCaps+ , DiscMode+ -- * Data+ , Filesystem+ , FilesystemClass+ , FilesystemClasses+ , IsoAnalysis+ -- * Logging+ , LibcdioLogger+ , LogEntry+ , LogLevel+ ) where+++import Sound.Libcdio.Device+import Sound.Libcdio.Logging+import Sound.Libcdio.Read.CdText+import Sound.Libcdio.Read.Data+import Sound.Libcdio.Read.Filesystem+import Sound.Libcdio.Track+import Sound.Libcdio.Types.Cdio
+ src/Sound/Libcdio/Types/Cdio.hs view
@@ -0,0 +1,243 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE MultiParamTypeClasses #-}++{-|+Description: Internal module to allow constructor access without pollution.++Copyright: (c) 2019-2021 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: stable+Portability: non-portable (requires libcdio)+-}+module Sound.Libcdio.Types.Cdio+ ( Cdio+ , CdioError ( .. )+ , CdioErrorType ( .. )+ , Foreign.SessionArg ( .. )+ , Foreign.AccessMode ( .. )+ , liftCdio+ , liftCdio'+ , liftCdioError+ , liftCdioError'+ , packCdioError+ , packCdioError'+ , open+ , openMode+ , getArg+ , getAccessMode+ , runCdio+ ) where+++import qualified Control.Applicative as A+#if MIN_VERSION_mtl(2,2,1)+import qualified Control.Monad.Except as N.E+#else+import qualified Control.Monad.Error as N.E+#endif+import qualified Control.Monad.Fail as N.F++import qualified Data.Text as T++import qualified Foreign.Libcdio.Device as Foreign+import qualified Foreign.Libcdio.Logging as Foreign++import Sound.Libcdio.Logging++import Control.Applicative ( (<|>) )+import Data.Array.BitArray ( (!) )+++-- | A computation within the environment of the data (music or file) stored on+-- a CD. The options for affecting that environment from within are limited by+-- design, as this library is intended for /reading/ discs rather than+-- /authoring/ them.+newtype Cdio a = Cdio (Foreign.Cdio -> IO (Either CdioError a))+instance Functor Cdio where+ fmap f (Cdio a) = Cdio $ \c -> fmap f <$> a c+instance Applicative Cdio where+ pure a = Cdio . const . return $ Right a+ Cdio f <*> Cdio a = Cdio $ \c -> do+ f' <- f c+ a' <- a c+ return $ f' <*> a'+-- | 'A.empty' fails with 'CdioEmpty'.+instance A.Alternative Cdio where+ empty = Cdio $ \_ -> return . Left . CdioError CdioEmpty $ T.pack "empty"+ Cdio f <|> Cdio g = Cdio $ \c -> f c <|> g c+instance Monad Cdio where+ Cdio a >>= f = Cdio $ \c -> do+ a' <- a c+ case a' of+ Left e -> return $ Left e+ Right x -> let Cdio b = f x in b c+-- | Wraps the text in a 'FreeformCdioError', for recovery with 'N.E.catchError'.+instance N.F.MonadFail Cdio where+ fail e = Cdio . const . return . flip errorText "fail" . FreeformCdioError $ T.pack e+instance N.E.MonadError CdioError Cdio where+ throwError err = Cdio . const . return $ Left err+ catchError (Cdio f) e = Cdio $ \c -> f c >>= \a' -> case a' of+ Left err ->+ let Cdio g = e err+ in g c+ Right a -> return $ Right a+instance LibcdioLogger Cdio where+ logCutoff = Cdio $ \_ -> Right <$> Foreign.logCutoff+ setLogCutoff l = Cdio $ \_ -> Right <$> Foreign.setLogCutoff l+ readLog = Cdio $ \_ -> Right <$> Foreign.readLog+ clearLog = Cdio $ \_ -> Right <$> Foreign.clearLog+ putLog e = Cdio $ \_ -> Right <$> Foreign.putLog e++-- | Lift a computation from the C-style "Foreign.Libcdio" interface into the+-- monadic "Sound.Libcdio".+liftCdio :: (Foreign.Cdio -> IO a) -> Cdio a+liftCdio f = Cdio $ fmap Right . f++-- | As 'liftCdio', but for functions which take a second argument alongside+-- the read session.+liftCdio' :: (Foreign.Cdio -> a -> IO b) -> a -> Cdio b+liftCdio' f a = Cdio $ fmap Right . flip f a++-- | As 'liftCdio', but for functions which may return an error code indicating+-- failure.+liftCdioError :: (Foreign.Cdio -> IO (Either CdioError a)) -> Cdio a+{-# INLINE liftCdioError #-}+liftCdioError = Cdio++-- | As 'liftCdio'', but for functions which may return an error code indicating+-- failure.+liftCdioError' :: (Foreign.Cdio -> a -> IO (Either CdioError b)) -> a -> Cdio b+liftCdioError' f a = Cdio $ flip f a+++-- | Associates a well-typed error with human-readable context information.+data CdioError = CdioError CdioErrorType T.Text+ deriving ( Eq, Show, Read )++-- | Potential situations which may cause a computation to fail.+data CdioErrorType+ = DriverError+ -- ^ A requested operation failed for some unknown reason, or the+ -- operating system doesn't support the 'Sound.Libcdio.Device.DriverId'+ -- in use.+ | BadParameter+ -- ^ Some value passed to a requested operation was rejected as+ -- nonsensical or otherwise breaking the value-level invariants.+ | NotPermitted+ -- ^ The ability to perform a requested operation has been restricted+ -- (e.g., the user doesn't have permission to access the disc drive).+ | SessionClosed+ -- ^ The underlying library closed the 'Cdio' session prematurely.+ | Unsupported+ -- ^ A requested operation isn't available with driver used by the+ -- 'Cdio' session. Refer to 'Sound.Libcdio.Device.capabilities' and+ -- 'Sound.Libcdio.Device.deviceCapabilities' to reduce these.+ | CdioEmpty+ -- ^ 'A.empty' was called and no better alternative was encountered.+ | FreeformCdioError T.Text+ -- ^ Escape hatch from structured typing to allow user-specified+ -- (and user-triggered) errors.+ deriving ( Eq, Show, Read )++errorText :: CdioErrorType -> String -> Either CdioError a+errorText e = Left . CdioError e . T.pack++packCdioError :: String -> Foreign.DriverReturnCode -> a -> Either CdioError a+packCdioError _ Foreign.Success = Right+packCdioError s Foreign.DriverError = const $ errorText DriverError s+packCdioError s Foreign.Unsupported = const $ errorText Unsupported s+packCdioError s Foreign.Uninitialized = const $ errorText BadParameter s+packCdioError s Foreign.NotPermitted = const $ errorText NotPermitted s+packCdioError s Foreign.BadParameter = const $ errorText BadParameter s+packCdioError s Foreign.BadPointer = const $ errorText BadParameter s+packCdioError s Foreign.NoDriver = const $ errorText DriverError s+packCdioError _ Foreign.MmcSenseData = Right++packCdioError' :: String -> Either Foreign.DriverReturnCode a -> Either CdioError a+packCdioError' _ (Right a) = Right a+packCdioError' s (Left Foreign.Success) = errorText DriverError s+packCdioError' s (Left e) = packCdioError s e undefined+++-- | Use a C-style @"Foreign.Libcdio".'Foreign.Cdio'@ object as the base to run+-- a Haskell-style @"Sound.Libcdio".'Cdio'@ computation.+-- +-- Note that some invariants of the monadic interface may not work as expected+-- when used with the mutable objects.+runCdio :: Foreign.Cdio -> Cdio a -> IO (Either CdioError a)+runCdio c (Cdio f) = isolateLogs $ f c+++-- | Open a session to read data from the disc drive/image at the given+-- location. If passed 'Nothing' instead, uses the path considered "default";+-- on operating systems with a concept of numbered devices (e.g., Window's @D:@+-- drive, FreeBSD's @\/dev\/cd0@) will usually return the first such device+-- found to be suitable.+open+ :: Maybe FilePath+ -> Bool+ -- ^ Whether the disc should be ejected after the computation.+ -> Cdio a+ -> IO (Either CdioError a)+open = open' "open" Nothing+++-- | Open a session to read data from the disc drive/image at the given+-- location, using a specific instruction set. If passed 'Nothing' instead,+-- uses the path considered "default"; on operating systems with a concept of+-- numbered devices (e.g., Window's @D:@ drive, FreeBSD's @\/dev\/cd0@) will+-- usually return the first such device found to be suitable.+openMode+ :: Foreign.AccessMode+ -> Maybe FilePath+ -> Bool+ -- ^ Whether the disc should be ejected after the computation.+ -> Cdio a+ -> IO (Either CdioError a)+openMode = open' "openMode" . Just+++open'+ :: String+ -- ^ The name of the calling function, for error reporting.+ -> Maybe Foreign.AccessMode+ -> Maybe FilePath+ -> Bool+ -- ^ Whether the disc should be ejected after the computation.+ -> Cdio a+ -> IO (Either CdioError a)+open' s m p e (Cdio f) = isolateLogs $ do+ -- Rely on the driver autodetect behaviour.+ c <- case m of+ Just m' -> Foreign.cdioOpenAm p Foreign.DriverUnknown m'+ Nothing -> Foreign.cdioOpen p Foreign.DriverUnknown+ case c of+ Just c' -> do+ a <- f c'+ -- This isn't actually necessary since the failure code is ignored,+ -- but it's a small cost to be sure nothing weird happens (e.g.+ -- printing a warning message).+ (_, _, cap) <- Foreign.driveCap c'+ let e' = if e && cap ! Foreign.MiscEject+ then Foreign.ejectMedia c'+ else return Foreign.Success+ e' >> return a+ -- There may be a chance memory allocation fails, but far and away the+ -- most common is a path which is not actually a device.+ Nothing -> do+ return $ errorText BadParameter s+++-- | Retrieve the session value associated with the given key. The particular+-- case of @"access-mode"@ is instead handled by 'getAccessMode'.+getArg :: Foreign.SessionArg -> Cdio (Maybe T.Text)+getArg k = liftCdio $ \c -> do+ v <- Foreign.getArg c k+ return $ T.pack <$> v++-- | Check what instruction set is in use for reading the disc. Other session+-- values are handled by 'getArg'.+getAccessMode :: Cdio (Maybe Foreign.AccessMode)+getAccessMode = liftCdio Foreign.getAccessMode
+ src/c/cdio/compat/cdtext.c view
@@ -0,0 +1,100 @@+#include "cdio/compat/cdtext.h"++#include "stdlib.h"+#include "string.h"++#include "cdio/compat/device.h"+#include "cdio/memory.h"+#include "cdio/compat/track.h"+#include "cdio/compat/version.h"+++// FFI-compatible wrappers++cdtext_genre_t genre_unused() {+ return CDTEXT_GENRE_UNUSED;+}++cdtext_lang_t language_unknown() {+ return CDTEXT_LANGUAGE_UNKNOWN;+}++cdtext_lang_t language_invalid() {+#if LIBCDIO_SINCE_VERSION_2_1+ return CDTEXT_LANGUAGE_INVALID;+#else+ return CDTEXT_LANGUAGE_UNKNOWN;+#endif+}++cdtext_lang_t language_unused() {+#if LIBCDIO_SINCE_VERSION_2_1+ return CDTEXT_LANGUAGE_BLOCK_UNUSED;+#else+ return CDTEXT_LANGUAGE_UNKNOWN;+#endif+}+++// Symbol compatibility definitions++cdtext_lang_t cdtext_str2lang_safe(const char* str) {+#if LIBCDIO_SINCE_VERSION_2_1+ return cdtext_str2lang(str);+#else+ return CDTEXT_LANGUAGE_UNKNOWN;+#endif+}+++int cdtext_data_init_safe(cdtext_t* cdtext, uint8_t* data, size_t len) {+#if LIBCDIO_SINCE_VERSION_0_94+ return cdtext_data_init(cdtext, data, len);+#else+ return -1;+#endif+}+++cdtext_lang_t* cdtext_list_languages_v2_safe(cdtext_t* cdtext) {+#if LIBCDIO_SINCE_VERSION_2_1+ return cdtext_list_languages_v2(cdtext);+#else+ return cdtext_list_languages(cdtext);+#endif+}++bool cdtext_set_language_index_safe(cdtext_t* cdtext, int i) {+#if LIBCDIO_SINCE_VERSION_2_1+ return cdtext_set_language_index(cdtext, i);+#else+ // If we don't have a builtin index function, fall back on the list of+ // languages we *do* have, and derive an index from that.++ cdtext_lang_t* langs = cdtext_list_languages(cdtext);+ cdtext_lang_t nub_langs[CDTEXT_NUM_BLOCKS_MAX];++ // The Haskell interface drops both blocks without a known language and+ // blocks with a language which was already used (since+ // `cdtext_select_language` is unable to select either), but the C list is+ // messier and needs to be cleaned for the index to be predictable.+ int found = 0;+ for (int j = 0; j < CDTEXT_NUM_BLOCKS_MAX; ++j) {+ if (langs[j] == CDTEXT_LANGUAGE_UNKNOWN)+ continue;+ for (int k = 0; k <= found; ++k) {+ if (k == found) {+ nub_langs[found] = langs[j];+ ++found;+ break;+ } else if (langs[k] == langs[j])+ break;+ }+ }++ if (i < 0 || i >= found)+ return cdtext_select_language(cdtext, CDTEXT_LANGUAGE_UNKNOWN);+ else+ return cdtext_select_language(cdtext, nub_langs[i]);+#endif+}
+ src/c/cdio/compat/device.c view
@@ -0,0 +1,110 @@+#include "cdio/compat/device.h"++#include "cdio/compat/version.h"++#include "stdlib.h"+++// FFI-compatible wrappers++const unsigned int vendor_len() {+ return CDIO_MMC_HW_VENDOR_LEN;+}++const unsigned int model_len() {+ return CDIO_MMC_HW_MODEL_LEN;+}++const unsigned int revision_len() {+ return CDIO_MMC_HW_REVISION_LEN;+}+++bitfield_t drive_cap_error() {+ return CDIO_DRIVE_CAP_ERROR;+}++bitfield_t drive_cap_unknown() {+ return CDIO_DRIVE_CAP_UNKNOWN;+}+++const driver_id_t* get_drivers() {+ return cdio_drivers;+}++const driver_id_t* get_device_drivers() {+ return cdio_device_drivers;+}++const driver_id_t get_os_driver() {+ return cdio_os_driver;+}+++// Symbol compatibility definitions++CdIo_t* cdio_open_bsdi_safe(const char* src) {+#if LIBCDIO_SINCE_VERSION_1_0+ return NULL;+#else+ return cdio_open_bsdi(src);+#endif+}++CdIo_t* cdio_open_am_bsdi_safe(const char* src, const char* mode) {+#if LIBCDIO_SINCE_VERSION_1_0+ return NULL;+#else+ return cdio_open_am_bsdi(src, mode);+#endif+}++char* cdio_get_default_device_bsdi_safe() {+#if LIBCDIO_SINCE_VERSION_1_0+ return NULL;+#else+ return cdio_get_default_device_bsdi();+#endif+}++char** cdio_get_devices_bsdi_safe() {+#if LIBCDIO_SINCE_VERSION_1_0+ return NULL;+#else+ return cdio_get_devices_bsdi();+#endif+}+++CdIo_t* cdio_open_os2_safe(const char* src) {+#if LIBCDIO_SINCE_VERSION_1_0+ return NULL;+#else+ return cdio_open_os2(src);+#endif+}++CdIo_t* cdio_open_am_os2_safe(const char* src, const char* mode) {+#if LIBCDIO_SINCE_VERSION_1_0+ return NULL;+#else+ return cdio_open_am_os2(src, mode);+#endif+}++char* cdio_get_default_device_os2_safe() {+#if LIBCDIO_SINCE_VERSION_1_0+ return NULL;+#else+ return cdio_get_default_device_os2();+#endif+}++char** cdio_get_devices_os2_safe() {+#if LIBCDIO_SINCE_VERSION_1_0+ return NULL;+#else+ return cdio_get_devices_os2();+#endif+}
+ src/c/cdio/compat/disc.c view
@@ -0,0 +1,32 @@+#include "cdio/compat/disc.h"++#include "cdio/compat/mmc.h"+++// FFI-compatible wrappers++const char* discmode_string(discmode_t dm) {+ if (dm > CDIO_DISC_MODE_CD_I || dm < CDIO_DISC_MODE_CD_DA)+ return discmode2str[CDIO_DISC_MODE_ERROR];+ else+ return discmode2str[dm];+}+++discmode_t discmode_error() {+ return CDIO_DISC_MODE_ERROR;+}+++// Marshalling aids++void get_cdtext_raw_len(CdIo_t* cdio, uint8_t** data, unsigned int* length) {+ *data = cdio_get_cdtext_raw(cdio);+ // Source diving to lib/driver/generic.h:read_cdtext_generic()+ if (data && *data)+ // The CDTEXT length includes the two always-null bytes before the+ // data, but *not* the two length bytes themselves.+ *length = CDIO_MMC_GET_LEN16(*data) - 2;+ else+ *length = 0;+}
+ src/c/cdio/compat/logging.c view
@@ -0,0 +1,91 @@+#include "cdio/compat/logging.h"++#include <stdlib.h>+#include <string.h>+++// Avoid unnecessary repeated calls; don't seem to mess anything up, but may as+// well keep clean.+bool replaced_cdio_logger = false;+++cdio_log_level_t get_cdio_log_level() {+ return cdio_loglevel_default;+}++void set_cdio_log_level(cdio_log_level_t l) {+ // The `_default` refers to the default handler, but it has explicitly been+ // opened up to alternate implementations as well.+ cdio_loglevel_default = l;+}+++void haskell_log_handler(cdio_log_level_t lvl, const char* msg) {+ if (lvl >= cdio_loglevel_default) {+ cdio_log_entry_t* entry = (cdio_log_entry_t*) malloc(sizeof(cdio_log_entry_t));+ if (!entry)+ return;++ // The Haskell garbage collector could easily clean anything logged+ // from the bindings before it's read.+ char* message = malloc(strlen(msg) + 1);+ if (!message) {+ free(entry);+ return;+ }+ else+ strcpy(message, msg);++ entry->level = lvl;+ entry->prev = haskell_log;+ entry->message = message;++ haskell_log = entry;+ }+}++void setup_cdio_logger() {+ if (!replaced_cdio_logger) {+ cdio_log_set_handler(*haskell_log_handler);+ haskell_log = NULL;+ replaced_cdio_logger = true;+ }+}+++cdio_log_entry_t** read_cdio_log() {+ if (!haskell_log)+ return NULL;++ // We need the total number of entries for determining allocation size.+ int count = 0;+ cdio_log_entry_t* entry = haskell_log;+ while (entry) {+ ++count;+ entry = entry->prev;+ }++ cdio_log_entry_t** out = (cdio_log_entry_t**) calloc(count + 1, sizeof(cdio_log_entry_t*));+ if (!out)+ return NULL;++ // ...and since we have the total anyway, may as well reverse the FILO into+ // chronological order now.+ entry = haskell_log;+ for (int i = count - 1; i >= 0; --i) {+ out[i] = entry;+ entry = entry->prev;+ }++ return out;+}++void free_cdio_log() {+ while (haskell_log) {+ cdio_log_entry_t* entry = haskell_log;+ haskell_log = entry->prev;+ if (entry->message)+ free((void *)entry->message);+ free(entry);+ }+}
+ src/c/cdio/compat/read.c view
@@ -0,0 +1,89 @@+#include "cdio/compat/read.h"++#include "stdlib.h"++#include "cdio/compat/sector.h"+++// Allocate the proper sizes in C, as Haskell marshalling for anything but+// simple `Storable` types is a bit awkward.++void read_bytes(const CdIo_t* cdio, void** buf, ssize_t* out, size_t bytes) {+ *buf = malloc(bytes);+ *out = cdio_read(cdio, *buf, bytes);+}+++uint16_t sector_size(cdio_read_mode_t mode) {+ switch (mode) {+ case CDIO_READ_MODE_AUDIO:+ return CDIO_CD_FRAMESIZE_RAW;+ case CDIO_READ_MODE_M1F1:+ return CDIO_CD_FRAMESIZE;+ case CDIO_READ_MODE_M1F2:+ return CDIO_CD_FRAMESIZE_RAW0;+ case CDIO_READ_MODE_M2F1:+ return CDIO_CD_FRAMESIZE;+ case CDIO_READ_MODE_M2F2:+ return M2F2_SECTOR_SIZE;+ default:+ return 0;+ }+}++void setup_read(void** buff, uint32_t* bytes, uint16_t blocksize, uint32_t blocks) {+ *bytes = blocksize * blocks;+ *buff = malloc(*bytes);+}+++// Marshalling aids++driver_return_code_t read_sector(const CdIo_t* cdio, void** buff, uint32_t* bytes, lsn_t lsn, cdio_read_mode_t mode) {+ setup_read(buff, bytes, sector_size(mode), 1);+ return cdio_read_sector(cdio, *buff, lsn, mode);+}++driver_return_code_t read_sectors(const CdIo_t* cdio, void** buff, uint32_t* bytes, lsn_t lsn, cdio_read_mode_t mode, uint32_t blocks) {+ setup_read(buff, bytes, sector_size(mode), blocks);+ return cdio_read_sectors(cdio, *buff, lsn, mode, blocks);+}+++driver_return_code_t read_data_sectors(const CdIo_t* cdio, void** buff, uint32_t* bytes, lsn_t lsn, uint16_t blocksize, uint32_t blocks) {+ setup_read(buff, bytes, blocksize, blocks);+ return cdio_read_data_sectors(cdio, *buff, lsn, blocksize, blocks);+}+++driver_return_code_t read_audio_sector(const CdIo_t* cdio, void** buff, uint32_t* bytes, lsn_t lsn) {+ setup_read(buff, bytes, sector_size(CDIO_READ_MODE_AUDIO), 1);+ return cdio_read_audio_sector(cdio, *buff, lsn);+}++driver_return_code_t read_audio_sectors(const CdIo_t* cdio, void** buff, uint32_t* bytes, lsn_t lsn, uint32_t blocks) {+ setup_read(buff, bytes, sector_size(CDIO_READ_MODE_AUDIO), blocks);+ return cdio_read_audio_sectors(cdio, *buff, lsn, blocks);+}+++driver_return_code_t read_mode1_sector(const CdIo_t* cdio, void** buff, uint32_t* bytes, lsn_t lsn, bool form2) {+ setup_read(buff, bytes, sector_size((form2 ? CDIO_READ_MODE_M1F2 : CDIO_READ_MODE_M1F1)), 1);+ return cdio_read_mode1_sector(cdio, *buff, lsn, form2);+}++driver_return_code_t read_mode1_sectors(const CdIo_t* cdio, void** buff, uint32_t* bytes, lsn_t lsn, bool form2, uint32_t blocks) {+ setup_read(buff, bytes, sector_size((form2 ? CDIO_READ_MODE_M1F2 : CDIO_READ_MODE_M1F1)), blocks);+ return cdio_read_mode1_sectors(cdio, *buff, lsn, form2, blocks);+}+++driver_return_code_t read_mode2_sector(const CdIo_t* cdio, void** buff, uint32_t* bytes, lsn_t lsn, bool form2) {+ setup_read(buff, bytes, sector_size((form2 ? CDIO_READ_MODE_M2F2 : CDIO_READ_MODE_M2F1)), 1);+ return cdio_read_mode2_sector(cdio, *buff, lsn, form2);+}++driver_return_code_t read_mode2_sectors(const CdIo_t* cdio, void** buff, uint32_t* bytes, lsn_t lsn, bool form2, uint32_t blocks) {+ setup_read(buff, bytes, sector_size((form2 ? CDIO_READ_MODE_M2F2 : CDIO_READ_MODE_M2F1)), blocks);+ return cdio_read_mode2_sectors(cdio, *buff, lsn, form2, blocks);+}
+ src/c/cdio/compat/sector.c view
@@ -0,0 +1,152 @@+#include "cdio/compat/sector.h"++#include "string.h"+++// FFI-compatible wrappings++lsn_t min_lsn() {+ return CDIO_CD_MIN_LSN;+}++lsn_t max_lsn() {+ return CDIO_CD_MAX_LSN;+}+++lba_t invalid_lba() {+ return CDIO_INVALID_LBA;+}++lsn_t invalid_lsn() {+ return CDIO_INVALID_LSN;+}+++size_t sizeof_msf() {+ return sizeof(msf_t);+}+++unsigned int pregap_sectors() {+ return CDIO_PREGAP_SECTORS;+}++unsigned int postgap_sectors() {+ return CDIO_POSTGAP_SECTORS;+}+++unsigned int cd_mins() {+ return CDIO_CD_MINS;+}++unsigned int secs_per_min() {+ return CDIO_CD_SECS_PER_MIN;+}++unsigned int frames_per_min() {+ return CDIO_CD_FRAMES_PER_MIN;+}++unsigned int frames_per_sec() {+ return CDIO_CD_FRAMES_PER_SEC;+}++unsigned int chunks_per_frame() {+ return CDIO_CD_NUM_OF_CHUNKS;+}+++unsigned int min_session() {+ return CDIO_CD_MIN_SESSION_NO;+}++unsigned int max_session() {+ return CDIO_CD_MAX_SESSIONS;+}+++unsigned int sync_size() {+ return CDIO_CD_SYNC_SIZE;+}++unsigned int chunk_size() {+ return CDIO_CD_CHUNK_SIZE;+}++unsigned int framesize_sub() {+ return CDIO_CD_FRAMESIZE_SUB;+}++unsigned int header_size() {+ return CDIO_CD_HEADER_SIZE;+}++unsigned int subheader_size() {+ return CDIO_CD_SUBHEADER_SIZE;+}++unsigned int edc_size() {+ return CDIO_CD_EDC_SIZE;+}++unsigned int mode1_pad_size() {+ return CDIO_CD_M1F1_ZERO_SIZE;+}++unsigned int ecc_size() {+ return CDIO_CD_ECC_SIZE;+}+++unsigned int framesize() {+ return CDIO_CD_FRAMESIZE;+}++unsigned int framesize_raw() {+ return CDIO_CD_FRAMESIZE_RAW;+}++unsigned int framesize_rawer() {+ return CDIO_CD_FRAMESIZE_RAWER;+}++unsigned int framesize_raw0() {+ return CDIO_CD_FRAMESIZE_RAW0;+}++unsigned int framesize_raw1() {+ return CDIO_CD_FRAMESIZE_RAW1;+}+++unsigned int header_size_xa() {+ return CDIO_CD_XA_HEADER;+}++unsigned int tail_size_xa() {+ return CDIO_CD_XA_TAIL;+}++unsigned int sync_size_xa() {+ return CDIO_CD_XA_SYNC_HEADER;+}++unsigned int data_size_xa() {+ return M2F2_SECTOR_SIZE;+}++unsigned int tagged_size_xa() {+ return M2SUB_SECTOR_SIZE;+}+++const uint8_t* sector_sync_header() {+ return CDIO_SECTOR_SYNC_HEADER;+}+++cdio_cd_minutes_sectors max_sectors() {+ return CDIO_CD_MAX_SECTORS;+}
+ src/c/cdio/compat/track.c view
@@ -0,0 +1,31 @@+#include "cdio/compat/track.h"+++// FFI-compatible wrappings++const char* track_format_string(track_format_t tf) {+ if (tf > TRACK_FORMAT_ERROR || tf < TRACK_FORMAT_AUDIO)+ return track_format2str[TRACK_FORMAT_ERROR];+ else+ return track_format2str[tf];+}++track_t invalid_track() {+ return CDIO_INVALID_TRACK;+}++track_t leadout_track() {+ return CDIO_CDROM_LEADOUT_TRACK;+}++track_format_t track_format_error() {+ return TRACK_FORMAT_ERROR;+}++track_t min_tracks() {+ return CDIO_CD_MIN_TRACK_NO;+}++track_t max_tracks() {+ return CDIO_CD_MAX_TRACKS;+}
+ src/c/cdio/compat/types.c view
@@ -0,0 +1,10 @@+#include "cdio/compat/types.h"+++unsigned char mcn_length() {+ return CDIO_MCN_SIZE;+}++unsigned char isrc_length() {+ return CDIO_ISRC_SIZE;+}
+ src/c/cdio/compat/version.c view
@@ -0,0 +1,16 @@+#include "cdio/compat/version.h"+++// FFI-compatible wrappings++const char* get_cdio_version_string() {+ return cdio_version_string;+}++const unsigned int get_cdio_version_num() {+ return libcdio_version_num;+}++const unsigned int get_cdio_version_api() {+ return CDIO_API_VERSION;+}
+ test/Data/Text/Encoding/MsJIS/Test/Classes.hs view
@@ -0,0 +1,65 @@+{-|+Description: ++Copyright: (c) 2020-2021 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: experimental+Portability: portable+-}+module Data.Text.Encoding.MsJIS.Test.Classes+ ( laws+ , genJISChar+ , genDecodeError+ , genEncodeError+ ) where+++import qualified Hedgehog as H+import qualified Hedgehog.Gen as H.G+import qualified Hedgehog.Classes as H.C++import qualified Data.Text as T++import Data.Text.Encoding.MsJIS++import Test.Libcdio.Property.Common+++laws :: [LawsGroup]+laws =+ [ ("JISChar", map (\f -> f genJISChar)+ [ H.C.eqLaws+ , ordLaws'+ , H.C.showLaws+ , H.C.showReadLaws+ , H.C.boundedEnumLaws+ ]+ ), ("JISDecodeError", map (\f -> f genDecodeError)+ [ H.C.eqLaws+ , H.C.showLaws+ , H.C.showReadLaws+ ]+ ), ("JISEncodeError", map (\f -> f genEncodeError)+ [ H.C.eqLaws+ , H.C.showLaws+ , H.C.showReadLaws+ ]+ )]+++genJISChar :: H.Gen JISChar+genJISChar = H.G.enumBounded++genDecodeError :: H.Gen JISDecodeError+genDecodeError = do+ s <- genSample+ c <- H.G.maybe genJISChar+ return $ JISDecodeError (T.unpack s) c++genEncodeError :: H.Gen JISEncodeError+genEncodeError = do+ s <- genSample+ c <- H.G.maybe H.G.unicode+ return $ JISEncodeError (T.unpack s) c
+ test/Data/Text/Encoding/MsJIS/Test/Unit.hs view
@@ -0,0 +1,107 @@+{-|+Description: ++Copyright: (c) 2020 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: experimental+Portability: portable+-}+module Data.Text.Encoding.MsJIS.Test.Unit (tests) where+++import qualified Test.HUnit as U+import Test.HUnit ( (@=?), (@?=), (~:) )++import qualified Data.ByteString as BS+import qualified Data.Maybe as Y+import qualified Data.Text as T++import qualified System.IO.Unsafe as IO.U++import Data.Text.Encoding.MsJIS++import Test.Libcdio.Unit.Common+++testFile :: FilePath+testFile = dataFile "CP932.txt"++charRef :: [(JISChar, T.Text)]+charRef = IO.U.unsafePerformIO $ do+ ls <- lines <$> readFile testFile+ return . flip Y.mapMaybe ls $ \l -> case words l of+ [] -> Nothing+ [_] -> Nothing+ (('#':_):_) -> Nothing+ (_:('#':_):_) -> Nothing+ (j:u:_) -> Just (toJIS $ read j, T.singleton . toEnum $ read u)+ where toJIS i+ | i > 0xFF = uncurry Double . mapBoth fromIntegral $ divMod i (0x100 :: Word)+ | otherwise = Single $ fromIntegral i+++tests :: U.Test+tests = "Data.Text.Encoding.MsJIS" ~: U.TestList+ [ decode+ , encode+ , duplicatesDuplicated+ ]+++decode :: U.Test+decode = "JIS characters are read correctly" ~: U.TestList+ [ show j ++ " -> " ++ T.unpack u ~: U.TestCase (decodeMsJIS' (unpack j) @?= Right u)+ | (j, u) <- charRef+ ]++encode :: U.Test+encode = "JIS characters are encoded correctly" ~: U.TestList+ [ T.unpack u ++ " -> " ++ show j ~: U.TestCase (Right (unpack j) @=? encodeMsJIS' u)+ | (j, u) <- charRef+ , notElem j duplicateChars+ ]++duplicatesDuplicated :: U.Test+duplicatesDuplicated = "Duplicate JIS characters roundtrip to something else" ~: U.TestList+ [ U.TestCase $ do+ c <- either decodeFailure return $ decodeMsJIS' bs+ bs' <- either encodeFailure return $ encodeMsJIS' c+ U.assert $ bs /= bs'+ | bs <- map unpack duplicateChars+ ]+ where decodeFailure = U.assertFailure . mappend "JIS decode failed with " . show+ encodeFailure = U.assertFailure . mappend "JIS encode failed with " . show++unpack :: JISChar -> BS.ByteString+unpack (Single w) = BS.singleton w+unpack (Double l t) = BS.pack [l, t]++duplicateChars :: [JISChar]+duplicateChars =+ [ Double 0x81 0xBE+ , Double 0x81 0xBF+ , Double 0x81 0xCA+ , Double 0x81 0xDA+ , Double 0x81 0xDB+ , Double 0x81 0xDF+ , Double 0x81 0xE0+ , Double 0x81 0xE3+ , Double 0x81 0xE6+ , Double 0x81 0xE7+ ] +++ [ Double 0x87 t+ | t <- [0x54..0x5D]+ ] +++ [ Double 0x87 0x82+ , Double 0x87 0x84+ , Double 0x87 0x8A+ , Double 0x87 0x9A+ ] +++ [ Double 0xED t+ | t <- [0x40..0x7E] ++ [0x80..0xFC]+ ] +++ [ Double 0xEE t+ | t <- [0x40..0x7E] ++ [0x80..0xEC] ++ [0xEF..0xFC]+ ]
+ test/Foreign/Libcdio/CdText/Test/Classes.hs view
@@ -0,0 +1,60 @@+{-|+Description: ++Copyright: (c) 2019 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: experimental+Portability: portable+-}+module Foreign.Libcdio.CdText.Test.Classes+ ( laws+ , genGenre+ , genLanguage+ ) where+++import qualified Hedgehog as H+import qualified Hedgehog.Gen as H.G+import qualified Hedgehog.Classes as H.C++import Test.Libcdio.Property.Common++import Foreign.Libcdio.CdText+++laws :: [LawsGroup]+laws =+ [ ("Field", map (\f -> f genField)+ [ H.C.eqLaws+ , ordLaws'+ , H.C.showLaws+ , H.C.showReadLaws+ , H.C.boundedEnumLaws+ ]+ ), ("Genre", map (\f -> f genGenre)+ [ H.C.eqLaws+ , ordLaws'+ , H.C.showLaws+ , H.C.showReadLaws+ , H.C.boundedEnumLaws+ ]+ ), ("Language", map (\f -> f genLanguage)+ [ H.C.eqLaws+ , ordLaws'+ , H.C.showLaws+ , H.C.showReadLaws+ , H.C.boundedEnumLaws+ ]+ )]+++genField :: H.Gen Field+genField = H.G.enumBounded++genGenre :: H.Gen Genre+genGenre = H.G.enumBounded++genLanguage :: H.Gen Language+genLanguage = enumSparse
+ test/Foreign/Libcdio/CdTypes/Test/Classes.hs view
@@ -0,0 +1,84 @@+{-|+Description: ++Copyright: (c) 2019 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: experimental+Portability: portable+-}+module Foreign.Libcdio.CdTypes.Test.Classes+ ( laws+ , genFilesystem+ , genFilesystemClass+ , genIsoAnalysis+ ) where+++import qualified Hedgehog as H+import qualified Hedgehog.Gen as H.G+import qualified Hedgehog.Range as H.R+import qualified Hedgehog.Classes as H.C++import qualified Data.Text as T++import qualified Foreign.C.Types as C++import Foreign.Libcdio.CdTypes++import Test.Libcdio.Property.Common+++laws :: [LawsGroup]+laws =+ [ ("Filesystem", map (\f -> f genFilesystem)+ [ H.C.eqLaws+ , ordLaws'+ , H.C.showLaws+ , H.C.showReadLaws+ , H.C.boundedEnumLaws+ ]+ ), ("FilesystemClass", map (\f -> f genFilesystemClass)+ [ H.C.eqLaws+ , ordLaws'+ , H.C.showLaws+ , H.C.showReadLaws+ , H.C.boundedEnumLaws+ ]+ ), ("IsoAnalysis", map (\f -> f genIsoAnalysis)+ [ H.C.eqLaws+ , H.C.showLaws+ , H.C.showReadLaws+ , storableLaws'+ ]+ )]+++genFilesystem :: H.Gen Filesystem+genFilesystem = H.G.enumBounded++genFilesystemClass :: H.Gen FilesystemClass+genFilesystemClass = enumSparse++genIsoAnalysis :: H.Gen IsoAnalysis+genIsoAnalysis = do+ j <- H.G.maybe . H.G.word $ H.R.constant 1 3+ l <- genSample+ s <- H.G.integral (H.R.linearBounded :: H.R.Range C.CUInt)+ v <- H.G.maybe $ H.G.element+ [ (1, 0)+ , (1, 1)+ , (1, 2)+ , (1, 50)+ , (2, 0)+ , (2, 1)+ , (2, 50)+ , (2, 60)+ ]+ return $ IsoAnalysis+ { jolietLevel = j+ , label = T.unpack l+ , fsSize = fromIntegral s+ , udfVersion = v+ }
+ test/Foreign/Libcdio/Device/Test/Classes.hs view
@@ -0,0 +1,127 @@+{-|+Description: ++Copyright: (c) 2019-2021 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: experimental+Portability: portable+-}+module Foreign.Libcdio.Device.Test.Classes+ ( laws+ , genDriveCapabilityRead+ , genDriveCapabilityWrite+ , genDriveCapabilityMisc+ , genHardwareInfo+ , genDriverId+ , genDriverReturnCode+ , genSessionArg+ , genAccessMode+ ) where+++import qualified Hedgehog as H+import qualified Hedgehog.Gen as H.G+import qualified Hedgehog.Range as H.R+import qualified Hedgehog.Classes as H.C++import Foreign.Libcdio.Device++import Test.Libcdio.Property.Common+++laws :: [LawsGroup]+laws =+ [ ("DriveCapabilityRead", map (\f -> f genDriveCapabilityRead)+ [ H.C.eqLaws+ , ordLaws'+ , H.C.showLaws+ , H.C.showReadLaws+ , H.C.boundedEnumLaws+ ]+ ), ("DriveCapabilityWrite", map (\f -> f genDriveCapabilityWrite)+ [ H.C.eqLaws+ , ordLaws'+ , H.C.showLaws+ , H.C.showReadLaws+ , H.C.boundedEnumLaws+ ]+ ), ("DriveCapabilityMisc", map (\f -> f genDriveCapabilityMisc)+ [ H.C.eqLaws+ , ordLaws'+ , H.C.showLaws+ , H.C.showReadLaws+ , H.C.boundedEnumLaws+ ]+ ), ("HardwareInfo", map (\f -> f genHardwareInfo)+ [ H.C.eqLaws+ , H.C.showLaws+ , H.C.showReadLaws+ , storableLaws'+ ]+ ), ("DriverId", map (\f -> f genDriverId)+ [ H.C.eqLaws+ , ordLaws'+ , H.C.showLaws+ , H.C.showReadLaws+ , H.C.boundedEnumLaws+ ]+ ), ("DriverReturnCode", map (\f -> f genDriverReturnCode)+ [ H.C.eqLaws+ , ordLaws'+ , H.C.showLaws+ , H.C.showReadLaws+ , H.C.boundedEnumLaws+ ]+ ), ("SessionArg", map (\f -> f genSessionArg)+ [ H.C.eqLaws+ , ordLaws'+ , H.C.showLaws+ , H.C.showReadLaws+ , H.C.boundedEnumLaws+ , storableLaws'+ ]+ ), ("AccessMode", map (\f -> f genAccessMode)+ [ H.C.eqLaws+ , ordLaws'+ , H.C.showLaws+ , H.C.showReadLaws+ , H.C.boundedEnumLaws+ , storableLaws'+ ]+ )]+++genDriveCapabilityRead :: H.Gen DriveCapabilityRead+genDriveCapabilityRead = enumSparse++genDriveCapabilityWrite :: H.Gen DriveCapabilityWrite+genDriveCapabilityWrite = enumSparse++genDriveCapabilityMisc :: H.Gen DriveCapabilityMisc+genDriveCapabilityMisc = enumSparse++genHardwareInfo :: H.Gen HardwareInfo+genHardwareInfo = do+ --TODO: Test other string lengths+ v <- H.G.string (H.R.singleton $ fromIntegral vendorLength) H.G.ascii+ m <- H.G.string (H.R.singleton $ fromIntegral modelLength) H.G.ascii+ r <- H.G.string (H.R.singleton $ fromIntegral revisionLength) H.G.ascii+ return $ HardwareInfo+ { vendor = v+ , model = m+ , revision = r+ }++genDriverId :: H.Gen DriverId+genDriverId = enumSparse++genDriverReturnCode :: H.Gen DriverReturnCode+genDriverReturnCode = enumSparse++genSessionArg :: H.Gen SessionArg+genSessionArg = H.G.enumBounded++genAccessMode :: H.Gen AccessMode+genAccessMode = H.G.enumBounded
+ test/Foreign/Libcdio/Disc/Test/Classes.hs view
@@ -0,0 +1,39 @@+{-|+Description: ++Copyright: (c) 2019 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: experimental+Portability: portable+-}+module Foreign.Libcdio.Disc.Test.Classes+ ( laws+ , genDiscMode+ ) where+++import qualified Hedgehog as H+import qualified Hedgehog.Gen as H.G+import qualified Hedgehog.Classes as H.C++import Foreign.Libcdio.Disc++import Test.Libcdio.Property.Common+++laws :: [LawsGroup]+laws =+ [ ("DiscMode", map (\f -> f genDiscMode)+ [ H.C.eqLaws+ , ordLaws'+ , H.C.showLaws+ , H.C.showReadLaws+ , H.C.boundedEnumLaws+ ]+ )]+++genDiscMode :: H.Gen DiscMode+genDiscMode = H.G.enumBounded
+ test/Foreign/Libcdio/Logging/Test/Classes.hs view
@@ -0,0 +1,57 @@+{-|+Description: ++Copyright: (c) 2021 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: experimental+Portability: portable+-}+module Foreign.Libcdio.Logging.Test.Classes+ ( laws+ , genLogEntry+ , genLogLevel+ ) where+++import qualified Hedgehog as H+import qualified Hedgehog.Gen as H.G+import qualified Hedgehog.Classes as H.C++import qualified Data.Text as T++import Foreign.Libcdio.Logging++import Test.Libcdio.Property.Common+++laws :: [LawsGroup]+laws =+ [ ("LogLevel", map (\f -> f genLogLevel)+ [ H.C.eqLaws+ , ordLaws'+ , H.C.showLaws+ , H.C.showReadLaws+ , H.C.boundedEnumLaws+ ]+ ), ("LogEntry", map (\f -> f genLogEntry)+ [ H.C.eqLaws+ , H.C.showLaws+ , H.C.showReadLaws+ , storableLaws'+ ]+ )]+++genLogLevel :: H.Gen LogLevel+genLogLevel = H.G.enumBounded++genLogEntry :: H.Gen LogEntry+genLogEntry = do+ l <- genLogLevel+ m <- genSample+ return $ LogEntry+ { logLevel = l+ , logMessage = T.unpack m+ }
+ test/Foreign/Libcdio/Logging/Test/Property.hs view
@@ -0,0 +1,82 @@+{-# LANGUAGE OverloadedStrings #-}++{-|+Description: ++Copyright: (c) 2021 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: experimental+Portability: portable+-}+module Foreign.Libcdio.Logging.Test.Property+ ( properties+ ) where+++import qualified Hedgehog as H+import qualified Hedgehog.Gen as H.G+import qualified Hedgehog.Range as H.R++import Foreign.Libcdio.Logging+import Foreign.Libcdio.Logging.Test.Classes++import Test.Libcdio.Property.Common++import Hedgehog ( (===) )+++properties :: H.Group+properties = H.Group "Foreign.Libcdio.Logging"+ [ setGetCutoff+ , filtered+ -- , retrieval+ , persistance+ , clear+ ]+++setGetCutoff :: Test+setGetCutoff = packTest "Cutoff level is successfully recovered" $ do+ H.evalIO setupLogger+ l <- H.forAll genLogLevel+ H.evalIO $ setLogCutoff l+ l' <- H.evalIO logCutoff+ l === l'+++logTest :: ([LogEntry] -> LogLevel -> H.PropertyT IO ()) -> H.PropertyT IO ()+logTest prop = do+ H.evalIO setupLogger+ H.evalIO clearLog+ minLevel <- H.forAll genLogLevel+ msgs <- H.forAll $ H.G.list (H.R.linear 0 16) genLogEntry+ H.evalIO $ setLogCutoff minLevel+ H.evalIO $ mapM_ putLog msgs+ prop msgs minLevel+ H.evalIO clearLog+++filtered :: Test+filtered = packTest "Log entries below the cutoff are hidden" . logTest $ \_ minLevel -> do+ msgs <- H.evalIO readLog+ H.annotateShow msgs+ H.assert . flip all msgs $ \msg -> logLevel msg >= minLevel++retrieval :: Test+retrieval = packTest "Log entries are read unchanged" . logTest $ \msgs minLevel -> do+ msgs' <- H.evalIO readLog+ filter (\msg -> logLevel msg >= minLevel) msgs === msgs'++persistance :: Test+persistance = packTest "'readLog' doesn't modify the logs" . logTest $ \_ _ -> do+ msgs <- H.evalIO readLog+ msgs' <- H.evalIO readLog+ msgs === msgs'++clear :: Test+clear = packTest "Clearing removes the entire log" . logTest $ \_ _ -> do+ H.evalIO clearLog+ msgs' <- H.evalIO readLog+ msgs' === []
+ test/Foreign/Libcdio/Read/Test/Classes.hs view
@@ -0,0 +1,50 @@+{-|+Description: ++Copyright: (c) 2019 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: experimental+Portability: portable+-}+module Foreign.Libcdio.Read.Test.Classes+ ( laws+ , genReadMode+ , genWhence+ ) where+++import qualified Hedgehog as H+import qualified Hedgehog.Gen as H.G+import qualified Hedgehog.Classes as H.C++import Foreign.Libcdio.Read++import Test.Libcdio.Property.Common+++laws :: [LawsGroup]+laws =+ [ ("ReadMode", map (\f -> f genReadMode)+ [ H.C.eqLaws+ , ordLaws'+ , H.C.showLaws+ , H.C.showReadLaws+ , H.C.boundedEnumLaws+ ]+ ), ("Whence", map (\f -> f genWhence)+ [ H.C.eqLaws+ , ordLaws'+ , H.C.showLaws+ , H.C.showReadLaws+ , H.C.boundedEnumLaws+ ]+ )]+++genReadMode :: H.Gen ReadMode+genReadMode = H.G.enumBounded++genWhence :: H.Gen Whence+genWhence = H.G.enumBounded
+ test/Foreign/Libcdio/Sector/Test/Classes.hs view
@@ -0,0 +1,91 @@+{-|+Description: ++Copyright: (c) 2019 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: experimental+Portability: portable+-}+module Foreign.Libcdio.Sector.Test.Classes+ ( laws+ , genSubchannelData+ , genFlag+ , genLba+ , genLsn+ , genMsf+ ) where+++import qualified Hedgehog as H+import qualified Hedgehog.Gen as H.G+import qualified Hedgehog.Classes as H.C+import qualified Hedgehog.Range as H.R++import Foreign.Libcdio.Sector++import Test.Libcdio.Property.Common+++laws :: [LawsGroup]+laws =+ [ ("SubchannelData", map (\f -> f genSubchannelData)+ [ H.C.eqLaws+ , ordLaws'+ , H.C.showLaws+ , H.C.showReadLaws+ , H.C.boundedEnumLaws+ ]+ ), ("Flag", map (\f -> f genFlag)+ [ H.C.eqLaws+ , ordLaws'+ , H.C.showLaws+ , H.C.showReadLaws+ , H.C.boundedEnumLaws+ ]+ ), ("Lba", map (\f -> f genLba)+ [ H.C.eqLaws+ , ordLaws'+ , H.C.showLaws+ , H.C.showReadLaws+ , H.C.boundedEnumLaws+ , H.C.bitsLaws+ , storableLaws'+ ]+ ), ("Integral Lba", [H.C.integralLaws $ nonZero genLba]+ ), ("Lsn", map (\f -> f genLsn)+ [ H.C.eqLaws+ , ordLaws'+ , H.C.showLaws+ , H.C.showReadLaws+ , H.C.boundedEnumLaws+ , H.C.bitsLaws+ , storableLaws'+ ]+ ), ("Integral Lsn", [H.C.integralLaws $ nonZero genLsn]+ ), ("Msf", map (\f -> f genMsf)+ [ H.C.eqLaws+ , ordLaws'+ , H.C.showLaws+ , H.C.showReadLaws+ , H.C.boundedEnumLaws+ , storableLaws'+ ]+ )]+++genSubchannelData :: H.Gen SubchannelData+genSubchannelData = H.G.enumBounded++genFlag :: H.Gen Flag+genFlag = enumSparse++genLba :: H.Gen Lba+genLba = H.G.integral (H.R.linearBounded :: H.R.Range Lba)++genLsn :: H.Gen Lsn+genLsn = H.G.integral (H.R.linearBounded :: H.R.Range Lsn)++genMsf :: H.Gen Msf+genMsf = H.G.enumBounded
+ test/Foreign/Libcdio/Track/Test/Classes.hs view
@@ -0,0 +1,63 @@+{-|+Description: ++Copyright: (c) 2019-2021 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: experimental+Portability: portable+-}+module Foreign.Libcdio.Track.Test.Classes+ ( laws+ , genTrack+ , genTrackNum+ , genTrackFormat+ ) where+++import qualified Hedgehog as H+import qualified Hedgehog.Gen as H.G+import qualified Hedgehog.Classes as H.C++import Foreign.Libcdio.Track++import Test.Libcdio.Property.Common+++laws :: [LawsGroup]+laws =+ [ ("Track", map (\f -> f genTrack)+ [ H.C.eqLaws+ , ordLaws'+ , H.C.showLaws+ , H.C.showReadLaws+ , H.C.boundedEnumLaws+ , storableLaws'+ ]+ ), ("TrackNum", map (\f -> f genTrackNum)+ [ H.C.eqLaws+ , ordLaws'+ , H.C.showLaws+ , H.C.showReadLaws+ ]+ ), ("TrackFormat", map (\f -> f genTrackFormat)+ [ H.C.eqLaws+ , ordLaws'+ , H.C.showLaws+ , H.C.showReadLaws+ , H.C.boundedEnumLaws+ ]+ )]+++genTrack :: H.Gen Track+genTrack = H.G.enumBounded++genTrackNum :: H.Gen TrackNum+genTrackNum = do+ Track t <- H.G.enum minTrack maxTrack+ return t++genTrackFormat :: H.Gen TrackFormat+genTrackFormat = H.G.enumBounded
+ test/Foreign/Libcdio/Util/Test/Classes.hs view
@@ -0,0 +1,41 @@+{-|+Description: ++Copyright: (c) 2019-2020 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: experimental+Portability: portable+-}+module Foreign.Libcdio.Util.Test.Classes+ ( laws+ , genBcd+ ) where+++import qualified Hedgehog as H+import qualified Hedgehog.Gen as H.G+import qualified Hedgehog.Classes as H.C++import Foreign.Libcdio.Types++import Test.Libcdio.Property.Common+++laws :: [LawsGroup]+laws =+ [ ("Bcd", map (\f -> f genBcd)+ [ H.C.eqLaws+ , ordLaws'+ , H.C.showLaws+ , H.C.showReadLaws+ , H.C.boundedEnumLaws+ , storableLaws'+ ]+ ), ("Integral Bcd", [H.C.integralLaws $ nonZero genBcd]+ )]+++genBcd :: H.Gen Bcd+genBcd = H.G.enumBounded
+ test/Sound/Libcdio/CdText/Test/Classes.hs view
@@ -0,0 +1,78 @@+{-|+Description: ++Copyright: (c) 2020 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: experimental+Portability: portable+-}+module Sound.Libcdio.CdText.Test.Classes+ ( laws+ , genCdTextError+ , genCdTextErrorType+ , genInfo+ ) where+++import qualified Hedgehog as H+import qualified Hedgehog.Gen as H.G+import qualified Hedgehog.Range as H.R+import qualified Hedgehog.Classes as H.C++import Sound.Libcdio.Read.CdText++import Foreign.Libcdio.CdText.Test.Classes hiding ( laws )+import Test.Libcdio.Property.Common+++laws :: [LawsGroup]+laws =+ [ ("Info", map (\f -> f genInfo)+ [ H.C.eqLaws+ , H.C.showLaws+ , H.C.showReadLaws+ ]+ ), ("CdTextErrrorType", map (\f -> f genCdTextErrorType)+ [ H.C.eqLaws+ , H.C.showLaws+ , H.C.showReadLaws+ ]+ ), ("CdTextErrror", map (\f -> f genCdTextError)+ [ H.C.eqLaws+ , H.C.showLaws+ , H.C.showReadLaws+ ]+ )]+++genCdTextErrorType :: H.Gen CdTextErrorType+genCdTextErrorType = H.G.choice+ [ InvalidBlock <$> H.G.word H.R.linearBounded+ , LanguageNotFound <$> genLanguage+ , H.G.constant BadBinaryRead+ , FreeformCdTextError <$> genSample+ ]++genCdTextError :: H.Gen CdTextError+genCdTextError = CdTextError <$> genCdTextErrorType <*> genSample++genInfo :: H.Gen Info+genInfo = do+ t <- H.G.maybe genSample+ p <- H.G.maybe genSample+ s <- H.G.maybe genSample+ c <- H.G.maybe genSample+ a <- H.G.maybe genSample+ m <- H.G.maybe genSample+ o <- H.G.maybe genSample+ return $ Info+ { title = t+ , performer = p+ , songwriter = s+ , composer = c+ , arranger = a+ , message = m+ , code = o+ }
+ test/Sound/Libcdio/Cdio/Test/Classes.hs view
@@ -0,0 +1,55 @@+{-|+Description: ++Copyright: (c) 2020-2021 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: experimental+Portability: portable+-}+module Sound.Libcdio.Cdio.Test.Classes+ ( laws+ , genCdioError+ , genCdioErrorType+ ) where+++import qualified Hedgehog as H+import qualified Hedgehog.Gen as H.G+import qualified Hedgehog.Classes as H.C++import Sound.Libcdio++import Test.Libcdio.Property.Common+++laws :: [LawsGroup]+laws =+ [ ("CdioErrrorType", map (\f -> f genCdioErrorType)+ [ H.C.eqLaws+ , H.C.showLaws+ , H.C.showReadLaws+ ]+ ), ("CdioErrror", map (\f -> f genCdioError)+ [ H.C.eqLaws+ , H.C.showLaws+ , H.C.showReadLaws+ ]+ )]+++genCdioErrorType :: H.Gen CdioErrorType+genCdioErrorType = H.G.frequency+ [ (6, H.G.element+ [ DriverError+ , BadParameter+ , NotPermitted+ , SessionClosed+ , Unsupported+ ])+ , (1, FreeformCdioError <$> genSample)+ ]++genCdioError :: H.Gen CdioError+genCdioError = CdioError <$> genCdioErrorType <*> genSample
+ test/Test/Libcdio/Property.hs view
@@ -0,0 +1,79 @@+{-|+Description: ++Copyright: (c) 2019-2021 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: experimental+Portability: non-portable (requires "GHC.IO.Encoding")+-}+module Main where+++import qualified Data.Bool as B++import qualified GHC.IO.Encoding as GIO++import qualified Hedgehog as H+import qualified Hedgehog.Classes as H.C++import qualified System.Exit as E+import qualified System.IO as IO++import qualified Data.Text.Encoding.MsJIS.Test.Classes as MsJIS++import qualified Foreign.Libcdio.CdText.Test.Classes as CdText+import qualified Foreign.Libcdio.CdTypes.Test.Classes as CdTypes+import qualified Foreign.Libcdio.Device.Test.Classes as Device+import qualified Foreign.Libcdio.Disc.Test.Classes as Disc+import qualified Foreign.Libcdio.Logging.Test.Classes as Logging+import qualified Foreign.Libcdio.Read.Test.Classes as Read+import qualified Foreign.Libcdio.Sector.Test.Classes as Sector+import qualified Foreign.Libcdio.Track.Test.Classes as Track+import qualified Foreign.Libcdio.Util.Test.Classes as Util++import qualified Sound.Libcdio.Cdio.Test.Classes as S.Cdio+import qualified Sound.Libcdio.CdText.Test.Classes as S.CdText++import qualified Foreign.Libcdio.Logging.Test.Property as Logging++import Test.Libcdio.Property.Common+++laws :: [LawsGroup]+laws = concat+ [ MsJIS.laws+ , CdText.laws+ , CdTypes.laws+ , Device.laws+ , Disc.laws+ , Logging.laws+ , Read.laws+ , Sector.laws+ , Track.laws+ , Util.laws+ , S.Cdio.laws+ , S.CdText.laws+ ]+++parallelProperties :: [H.Group]+parallelProperties =+ [+ ]++sequentialProperties :: [H.Group]+sequentialProperties =+ [ Logging.properties+ ]+++main :: IO ()+main = do+ GIO.setLocaleEncoding IO.utf8+ lawsResult <- H.C.lawsCheckMany laws+ parallelResults <- mapM H.checkParallel parallelProperties+ sequentialResults <- mapM H.checkSequential sequentialProperties+ B.bool E.exitFailure E.exitSuccess . and $+ lawsResult : parallelResults ++ sequentialResults
+ test/Test/Libcdio/Property/Common.hs view
@@ -0,0 +1,61 @@+{-# LANGUAGE CPP #-}+{-# OPTIONS_GHC -Wno-redundant-constraints #-}++{-|+Description: ++Copyright: (c) 2019-2021 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: experimental+Portability: portable+-}+module Test.Libcdio.Property.Common where+++import qualified Data.String as S+import qualified Data.Text as T++import qualified Hedgehog as H+import qualified Hedgehog.Gen as H.G+import qualified Hedgehog.Classes as H.C+import qualified Hedgehog.Range as H.R++import qualified Foreign.Storable as S+++type Test = (H.PropertyName, H.Property)+type LawsGroup = (String, [H.C.Laws])+++enumSparse :: (Enum a, Bounded a) => H.Gen a+enumSparse = H.G.element [minBound..maxBound]++nonZero :: (Eq a, Num a) => H.Gen a -> H.Gen a+nonZero = H.G.filter (/= 0)+++packTest :: String -> H.PropertyT IO () -> Test+packTest name prop = (S.fromString name, H.property prop)+++genSample :: H.Gen T.Text+genSample = H.G.text (H.R.linear 1 12) $ H.G.frequency [c7, c8]+ where c7 = (0x5F, H.G.enum ' ' '~')+ c8 = (0x60, H.G.enum '\xA0' '\xFF')+++ordLaws' :: (Ord a, Show a) => H.Gen a -> H.C.Laws+#if MIN_VERSION_hedgehog_classes(0,2,1)+ordLaws' = H.C.ordLaws+#else+ordLaws' = const $ H.C.Laws "Ord" []+#endif++storableLaws' :: (Eq a, Show a, S.Storable a) => H.Gen a -> H.C.Laws+#if MIN_VERSION_hedgehog_classes(0,2,6)+storableLaws' = H.C.storableLaws+#else+storableLaws' = const $ H.C.Laws "Storable" []+#endif
+ test/Test/Libcdio/Unit.hs view
@@ -0,0 +1,41 @@+{-|+Description: ++Copyright: (c) 2019 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: experimental+Portability: portable+-}+module Main where+++import qualified Control.Monad as M+import qualified System.Exit as E+import qualified Test.HUnit as U++import qualified Data.Text.Encoding.MsJIS.Test.Unit as MsJIS++import qualified Test.Libcdio.Unit.Foreign.CarolusRex as Rex+import qualified Test.Libcdio.Unit.Foreign.DeeperDance as Dance+import qualified Test.Libcdio.Unit.Foreign.RevolutionDays as Revolution++import qualified Test.Libcdio.Unit.Sound.CarolusRex as S.Rex+import qualified Test.Libcdio.Unit.Sound.DeeperDance as S.Dance+import qualified Test.Libcdio.Unit.Sound.RevolutionDays as S.Revolution+++main :: IO ()+main = do+ results <- U.runTestTT $ U.TestList+ [ MsJIS.tests+ , Dance.tests+ , Revolution.tests+ , Rex.tests+ , S.Dance.tests+ , S.Rex.tests+ , S.Revolution.tests+ ]+ + M.unless (U.errors results == 0 && U.failures results == 0) E.exitFailure
+ test/Test/Libcdio/Unit/Common.hs view
@@ -0,0 +1,22 @@+{-|+Description: ++Copyright: (c) 2019-2020 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: experimental+Portability: portable+-}+module Test.Libcdio.Unit.Common where+++dataDir :: FilePath+dataDir = "test/datafiles/unit/"++dataFile :: FilePath -> FilePath+dataFile = (++) dataDir+++mapBoth :: (a -> b) -> (a, a) -> (b, b)+mapBoth f (l, r) = (f l, f r)
+ test/Test/Libcdio/Unit/Foreign/CarolusRex.hs view
@@ -0,0 +1,102 @@+{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}++{-|+Description: Tests of multi-block CDTEXT in the Foreign interface.++Copyright: (c) 2019-2021 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: experimental+Portability: portable++The CDTEXT file used in this module was generated using the tool written by+Pigeon at <https://pigeonsnest.co.uk/stuff/cdtext.html> (warning for a /lot/ of+swearing). The encoding was later manually set to ASCII.+-}+module Test.Libcdio.Unit.Foreign.CarolusRex (tests) where+++import qualified Test.HUnit as U+import Test.HUnit ( (@?), (@?=), (~:) )++import qualified Data.ByteString as BS+import qualified Data.Maybe as Y++import Foreign.Libcdio.CdText++import Test.Libcdio.Unit.Common+++testFile :: FilePath+testFile = dataFile "carolus-rex.cdtext"+++tests :: U.Test+tests = "Foreign.Libcdio.Test.CarolusRex" ~: U.TestList+ [ parse+ ]++parse :: U.Test+parse = "Binary CDTEXT is read properly" ~: U.TestCase $ do+ bs <- BS.readFile testFile+ x' <- cdTextDataInit bs+ + Y.isJust x' @? "Failed to read binary CdText"+ let Just x = x'+ + checkLanguage x English+ checkLanguage x Swedish++checkLanguage :: Cdio -> Language -> U.Assertion+checkLanguage x l = do+ b <- selectLanguage x l+ b @? "Unable to change language to " ++ show l+ + l' <- language x+ l' @?= Just l+ + t1 <- firstTrack x+ t1 @?= Just 1+ + tl <- lastTrack x+ tl @?= Just (fromIntegral $ length titlesEnglish)+ + t <- cdTextGet x Title Nothing+ t @?= Just "Carolus Rex"+ + p <- cdTextGet x Performer Nothing+ p @?= Just "Sabaton"+ + ts <- mapM (cdTextGet x Title . Just . fromIntegral) [1 .. length titlesEnglish]+ ts @?= if l == English then titlesEnglish else titlesSwedish++titlesEnglish :: [Maybe String]+titlesEnglish = map Just+ [ "Dominium maris Baltici"+ , "The Lion from the North"+ , "Gott mit uns"+ , "A Lifetime of War"+ , "1648"+ , "The Carolean's Prayer"+ , "Carolus Rex"+ , "Killing Ground"+ , "Poltava"+ , "Long Live the King"+ , "Ruina Imperii"+ ]++titlesSwedish :: [Maybe String]+titlesSwedish = map Just+ [ "Dominium maris Baltici"+ , "Lejonet fraan Norden"+ , "Gott mit uns"+ , "En Livstid i krig"+ , "1648"+ , "Karolinens bo:n"+ , "Carolus Rex"+ , "Ett slag fa:rgat ro:tt"+ , "Poltava"+ , "Konungens likfa:rd"+ , "Ruina Imperii"+ ]
+ test/Test/Libcdio/Unit/Foreign/DeeperDance.hs view
@@ -0,0 +1,85 @@+{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}++{-|+Description: ++Copyright: (c) 2019-2021 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: experimental+Portability: portable++The CDTEXT file used in this module comes via James Olin Oden at+<https://bugzilla.redhat.com/show_bug.cgi?id=1321677#c3>.+-}+module Test.Libcdio.Unit.Foreign.DeeperDance (tests) where+++import qualified Test.HUnit as U+import Test.HUnit ( (@?), (@?=), (~:) )++import qualified Control.Monad as M++import qualified Data.ByteString as BS+import qualified Data.Maybe as Y++import Foreign.Libcdio.CdText++import Test.Libcdio.Unit.Common+++testFile :: FilePath+testFile = dataFile "deeper-dance.cdtext"+++tests :: U.Test+tests = "Foreign.Libcdio.Test.DeeperDance" ~: U.TestList+ [ parse+ ]++parse :: U.Test+parse = "Binary CDTEXT is read properly" ~: U.TestCase $ do+ bs <- BS.readFile testFile+ x' <- cdTextDataInit bs++ Y.isJust x' @? "Failed to read binary CdText"+ let Just x = x'++ l <- language x+ l @?= Just English++ t1 <- firstTrack x+ t1 @?= Just 1++ tl <- lastTrack x+ tl @?= Just (fromIntegral $ length titles)++ t <- cdTextGet x Title Nothing+ t @?= Just "Deeper Dance"++ p <- cdTextGet x Performer Nothing+ p @?= performer++ ts <- M.forM [1 .. length titles] $ \i -> do+ t' <- cdTextGet x Title . Just $ fromIntegral i+ p' <- cdTextGet x Performer . Just $ fromIntegral i+ return (t', p')+ ts @?= zip titles (repeat performer)++performer :: Maybe String+performer = Just "James Olin Oden"++titles :: [Maybe String]+titles = map Just+ [ "Deeper Dance"+ , "The Hunt"+ , "Harold's Dream"+ , "Jazz Fusion No. 9"+ , "Love's Tattoo"+ , "The Day I Told Her Micheal Domhnaill Died"+ , "The Fool Amongst the Keeners"+ , "Love Is Not Tame"+ , "Dear John and the Big Red Pickup Truck"+ , "Dance Right Out of My Grave"+ ]
+ test/Test/Libcdio/Unit/Foreign/RevolutionDays.hs view
@@ -0,0 +1,77 @@+{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}++{-|+Description: ++Copyright: (c) 2019-2020 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: experimental+Portability: portable++The CDTEXT file used in this module comes via Pigeon at+<https://pigeonsnest.co.uk/stuff/cdtext.html> (warning for a /lot/ of+swearing). The encoding was later manually set to ASCII.+-}+module Test.Libcdio.Unit.Foreign.RevolutionDays (tests) where+++import qualified Test.HUnit as U+import Test.HUnit ( (@?), (@?=), (~:) )++import qualified Data.ByteString as BS+import qualified Data.Maybe as Y++import Foreign.Libcdio.CdText++import Test.Libcdio.Unit.Common+++testFile :: FilePath+testFile = dataFile "revolution-days.cdtext"+++tests :: U.Test+tests = "Foreign.Libcdio.Test.RevolutionDays" ~: U.TestList+ [ parse+ ]++parse :: U.Test+parse = "Binary CDTEXT is read properly" ~: U.TestCase $ do+ bs <- BS.readFile testFile+ x' <- cdTextDataInit bs++ Y.isJust x' @? "Failed to read binary CdText"+ let Just x = x'++ t1 <- firstTrack x+ t1 @?= Just 1++ tl <- lastTrack x+ tl @?= Just (fromIntegral $ length titles)++ t <- cdTextGet x Title Nothing+ t @?= Just "REVOLUTION DAYS"++ p <- cdTextGet x Performer Nothing+ p @?= Just "BARCLAY JAMES HARVEST FEATURING LES HOLROYD"++ ts <- mapM (cdTextGet x Title . Just . fromIntegral) [1 .. length titles]+ ts @?= titles++titles :: [Maybe String]+titles = map Just+ [ "IT'S MY LIFE"+ , "MISSING YOU"+ , "THAT WAS THEN... THIS IS NOW"+ , "PRELUDE"+ , "JANUARY MORNING"+ , "LOVE ON THE LINE"+ , "QUIERO EL SOL"+ , "TOTALLY COOL"+ , "LIFE IS FOR LIVING"+ , "SLEEPY SUNDAY"+ , "REVOLUTION DAY"+ , "MARLENE (from the BERLIN SUITE)"+ ]
+ test/Test/Libcdio/Unit/Sound/CarolusRex.hs view
@@ -0,0 +1,92 @@+{-|+Description: Tests of multi-block CDTEXT in the Sound interface.++Copyright: (c) 2020-2021 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: experimental+Portability: portable++The CDTEXT file used in this module was generated using the tool written by+Pigeon at <https://pigeonsnest.co.uk/stuff/cdtext.html> (warning for a /lot/ of+swearing). The encoding was later manually set to ASCII.+-}+module Test.Libcdio.Unit.Sound.CarolusRex (tests) where+++import qualified Test.HUnit as U+import Test.HUnit ( (@?=), (~:) )++import qualified Data.ByteString as BS+import qualified Data.Maybe as Y+import qualified Data.Text as T++import Sound.Libcdio.Read.CdText++import Test.Libcdio.Unit.Sound.Common+++testFile :: FilePath+testFile = dataFile "carolus-rex.cdtext"+++tests :: U.Test+tests = "Sound.Libcdio.Test.CarolusRex" ~: U.TestList+ [ binary+ ]++binary :: U.Test+binary = "Binary CDTEXT is read properly" ~: U.TestCase $ do+ bs <- BS.readFile testFile+ x <- parseCdText bs . withAll $ do+ l <- language+ a <- checkLanguage $ zip langs [infoEnglish, infoSwedish]+ return (l, a)+ either (const $ U.assertFailure "Could not parse binary data") runAssertions x++runAssertions :: [Maybe (Language, U.Assertion)] -> IO ()+runAssertions xs = do+ let (ls, as) = unzip $ Y.catMaybes xs+ ls @?= langs+ sequence_ as+++langs :: [Language]+langs = [English, Swedish]++infoEnglish :: [Info]+infoEnglish = emptyInfo+ { title = Just $ T.pack "Carolus Rex"+ , performer = Just $ T.pack "Sabaton"+ } : map (\t -> emptyInfo { title = Just $ T.pack t })+ [ "Dominium maris Baltici"+ , "The Lion from the North"+ , "Gott mit uns"+ , "A Lifetime of War"+ , "1648"+ , "The Carolean's Prayer"+ , "Carolus Rex"+ , "Killing Ground"+ , "Poltava"+ , "Long Live the King"+ , "Ruina Imperii"+ ]++infoSwedish :: [Info]+infoSwedish = emptyInfo+ { title = Just $ T.pack "Carolus Rex"+ , performer = Just $ T.pack "Sabaton"+ } : map (\t -> emptyInfo { title = Just $ T.pack t })+ [ "Dominium maris Baltici"+ , "Lejonet fraan Norden"+ , "Gott mit uns"+ , "En Livstid i krig"+ , "1648"+ , "Karolinens bo:n"+ , "Carolus Rex"+ , "Ett slag fa:rgat ro:tt"+ , "Poltava"+ , "Konungens likfa:rd"+ , "Ruina Imperii"+ ]
+ test/Test/Libcdio/Unit/Sound/Common.hs view
@@ -0,0 +1,38 @@+{-|+Description: ++Copyright: (c) 2020-2021 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: experimental+Portability: portable+-}+module Test.Libcdio.Unit.Sound.Common+ ( module Test.Libcdio.Unit.Common+ , checkLanguage+ ) where+++import qualified Test.HUnit as U+import Test.HUnit ( (@?=) )++import Sound.Libcdio.Read.CdText++import Test.Libcdio.Unit.Common+++checkLanguage :: [(Language, [Info])] -> CdText U.Assertion+checkLanguage ls = do+ l <- language+ let is' = lookup l ls+ t1 <- firstTrack+ tl <- lastTrack+ i <- info Nothing+ is <- mapM (info . Just) [t1..tl]+ return $ case is' of+ Just is'' -> do+ t1 @?= 1+ tl @?= fromIntegral (length is)+ i : is @?= is''+ Nothing -> U.assertFailure "Unexpected language in CdText"
+ test/Test/Libcdio/Unit/Sound/DeeperDance.hs view
@@ -0,0 +1,66 @@+{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}++{-|+Description: ++Copyright: (c) 2020-2021 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: experimental+Portability: portable++The CDTEXT file used in this module comes via James Olin Oden at+<https://bugzilla.redhat.com/show_bug.cgi?id=1321677#c3>.+-}+module Test.Libcdio.Unit.Sound.DeeperDance (tests) where+++import qualified Test.HUnit as U+import Test.HUnit ( (~:) )++import qualified Data.ByteString as BS+import qualified Data.Either.Compat as E+import qualified Data.Text as T++import Sound.Libcdio.Read.CdText++import Test.Libcdio.Unit.Sound.Common+++testFile :: FilePath+testFile = dataFile "deeper-dance.cdtext"+++tests :: U.Test+tests = "Sound.Libcdio.Test.DeeperDance" ~: U.TestList+ [ binary+ ]++binary :: U.Test+binary = "Binary CDTEXT is read properly" ~: U.TestCase $ do+ bs <- BS.readFile testFile+ x <- parseCdText bs $ checkLanguage [(English, infos)]+ E.fromRight (U.assertFailure "Could not parse binary data") x+++performer' :: Maybe T.Text+performer' = Just $ T.pack "James Olin Oden"++infos :: [Info]+infos = map (\t -> emptyInfo+ { title = Just $ T.pack t+ , performer = performer'+ })+ [ "Deeper Dance"+ , "Deeper Dance"+ , "The Hunt"+ , "Harold's Dream"+ , "Jazz Fusion No. 9"+ , "Love's Tattoo"+ , "The Day I Told Her Micheal Domhnaill Died"+ , "The Fool Amongst the Keeners"+ , "Love Is Not Tame"+ , "Dear John and the Big Red Pickup Truck"+ , "Dance Right Out of My Grave"+ ]
+ test/Test/Libcdio/Unit/Sound/RevolutionDays.hs view
@@ -0,0 +1,63 @@+{-|+Description: ++Copyright: (c) 2020-2021 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: experimental+Portability: portable++The CDTEXT file used in this module comes via Pigeon at+<https://pigeonsnest.co.uk/stuff/cdtext.html> (warning for a /lot/ of+swearing). The encoding was later manually set to ASCII.+-}+module Test.Libcdio.Unit.Sound.RevolutionDays (tests) where+++import qualified Test.HUnit as U+import Test.HUnit ( (~:) )++import qualified Data.ByteString as BS+import qualified Data.Either.Compat as E+import qualified Data.Text as T++import Sound.Libcdio.Read.CdText++import Test.Libcdio.Unit.Sound.Common+++testFile :: FilePath+testFile = dataFile "revolution-days.cdtext"+++tests :: U.Test+tests = "Sound.Libcdio.Test.RevolutionDays" ~: U.TestList+ [ binary+ ]++binary :: U.Test+binary = "Binary CDTEXT is read properly" ~: U.TestCase $ do+ bs <- BS.readFile testFile+ x <- parseCdText bs . withLanguage English $ checkLanguage [(English, infos)]+ E.fromRight (U.assertFailure "Could not read binary data") x+++infos :: [Info]+infos = emptyInfo+ { title = Just $ T.pack "REVOLUTION DAYS"+ , performer = Just $ T.pack "BARCLAY JAMES HARVEST FEATURING LES HOLROYD"+ } : map (\t -> emptyInfo { title = Just $ T.pack t })+ [ "IT'S MY LIFE"+ , "MISSING YOU"+ , "THAT WAS THEN... THIS IS NOW"+ , "PRELUDE"+ , "JANUARY MORNING"+ , "LOVE ON THE LINE"+ , "QUIERO EL SOL"+ , "TOTALLY COOL"+ , "LIFE IS FOR LIVING"+ , "SLEEPY SUNDAY"+ , "REVOLUTION DAY"+ , "MARLENE (from the BERLIN SUITE)"+ ]
+ test/Test/Libcdio/Upstream.hs view
@@ -0,0 +1,54 @@+{-|+Description: ++Copyright: (c) 2019-2021 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: experimental+Portability: portable+-}+module Main where+++import qualified Control.Monad as M+import qualified System.Exit as E+import qualified Test.HUnit as U++import qualified Test.Libcdio.Upstream.Foreign.BinCue as BinCue+import qualified Test.Libcdio.Upstream.Foreign.CdrDao as CdrDao+import qualified Test.Libcdio.Upstream.Foreign.FreeBsd as FreeBsd+import qualified Test.Libcdio.Upstream.Foreign.Linux as Linux+import qualified Test.Libcdio.Upstream.Foreign.Nrg as Nrg+import qualified Test.Libcdio.Upstream.Foreign.OsX as OsX+import qualified Test.Libcdio.Upstream.Foreign.Pregap as Pregap+import qualified Test.Libcdio.Upstream.Foreign.Solaris as Solaris+import qualified Test.Libcdio.Upstream.Foreign.SizeOf as SizeOf+import qualified Test.Libcdio.Upstream.Foreign.Track as Track+import qualified Test.Libcdio.Upstream.Foreign.Win32 as Win32++import qualified Test.Libcdio.Upstream.Sound.Image as Sound.Image+import qualified Test.Libcdio.Upstream.Sound.System as Sound.System+import qualified Test.Libcdio.Upstream.Sound.Track as Sound.Track+++main :: IO ()+main = do+ results <- U.runTestTT $ U.TestList+ [ BinCue.tests+ , CdrDao.tests+ , FreeBsd.tests+ , Linux.tests+ , Nrg.tests+ , OsX.tests+ , Pregap.tests+ , Solaris.tests+ , SizeOf.tests+ , Track.tests+ , Win32.tests+ , Sound.Image.tests+ , Sound.System.tests+ , Sound.Track.tests+ ]+ + M.unless (U.errors results == 0 && U.failures results == 0) E.exitFailure
+ test/Test/Libcdio/Upstream/Foreign/BinCue.hs view
@@ -0,0 +1,86 @@+{-|+Description: ++Copyright: (c) 2019-2020 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: experimental+Portability: portable+-}+module Test.Libcdio.Upstream.Foreign.BinCue+ ( tests+ , goodCues+ , badCues+ ) where+++import qualified Test.HUnit as U+import Test.HUnit ( (@?), (@?=), (~:) )++import qualified Data.Maybe as Y++-- import qualified System.Directory as D++import Foreign.Libcdio.Device++import Test.Libcdio.Upstream.Foreign.Common+++tests :: U.Test+tests = "Foreign.Libcdio.Test.BinCue" ~: U.TestList+ [ parse+ , open+ ]+++parse :: U.Test+parse = "Distinguish valid and invalid CUE files" ~: U.TestList+ (map good goodCues ++ map bad badCues)+ where good = cueTest Y.isJust "is not recognized as a CUE file"+ bad = cueTest Y.isNothing "should not be recognized as a CUE file"+ cueTest t s f = U.TestCase $ t <$> binFromCue (dataFile f) @? "'" ++ f ++ "' " ++ s++goodCues :: [FilePath]+goodCues =+ [ "cdda.cue"+ , "isofs-m1.cue"+ ]++badCues :: [FilePath]+badCues =+ [ "bad-cat1.cue"+ , "bad-cat2.cue"+ , "bad-cat3.cue"+ , "bad-mode1.cue"+ , "bad-msf-1.cue"+ , "bad-msf-2.cue"+ , "bad-msf-3.cue"+ ]+++open :: U.Test+open = "CUE files open the associated device correctly" ~: U.TestCase $ do+ c <- cdioOpen (Just $ dataFile "cdda.cue") DriverUnknown+ cdio <- case c of+ Nothing -> U.assertFailure "Can't open the CUE file"+ Just c' -> return c'+ + b <- setBlocksize cdio 2048+ b @?= Unsupported+ + checkMmc cdio $ Just False+ checkAccessMode cdio [Image]+ + {- Seems to be either an unimplemented or a reverted equivalence+ d <- D.withCurrentDirectory dataDir . defaultDevice $ Just cdio+ device <- case d of+ Nothing -> U.assertFailure "No default device returned for the CUE file"+ Just d' -> return d'+ checkSource cdio [device]+ -}+ + s <- setSpeed cdio 5+ s @?= Unsupported+ + return ()
+ test/Test/Libcdio/Upstream/Foreign/CdrDao.hs view
@@ -0,0 +1,85 @@+{-|+Description: ++Copyright: (c) 2019-2021 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: experimental+Portability: portable+-}+module Test.Libcdio.Upstream.Foreign.CdrDao+ ( tests+ , goodToc+ , badToc+ ) where+++import qualified Test.HUnit as U+import Test.HUnit ( (@?), (~:) )++import qualified System.Directory as D++import Foreign.Libcdio.Device++import Test.Libcdio.Upstream.Foreign.Common+++tests :: U.Test+tests = "Foreign.Libcdio.Test.CdrDao" ~: U.TestList+ [ parse+ , open+ ]+++parse :: U.Test+parse = "Distinguish valid and invalid TOC files" ~: U.TestList+ (map good goodToc ++ map bad badToc)+ where good = tocTest id "is not recognized as a TOC file"+ bad = tocTest not "should not be recognized as a TOC file"+ tocTest t s f = U.TestCase . D.withCurrentDirectory dataDir $ fmap t (isToc f) @? "'" ++ f ++ "' " ++ s++goodToc :: [FilePath]+goodToc =+ [ "cdtext.toc"+ , "t1.toc"+ , "t2.toc"+ , "t3.toc"+ , "t4.toc"+ , "t5.toc"+ , "t6.toc"+ , "t7.toc"+ , "t8.toc"+ , "t9.toc"+ , "t10.toc"+ , "data1.toc"+ , "data2.toc"+ , "data5.toc"+ , "data6.toc"+ , "data7.toc"+ , "vcd2.toc"+ ]++badToc :: [FilePath]+badToc =+ [ "bad-cat1.toc"+ , "bad-cat2.toc"+ , "bad-cat3.toc"+ , "bad-file.toc"+ , "bad-mode1.toc"+ , "bad-msf-1.toc"+ , "bad-msf-2.toc"+ , "bad-msf-3.toc"+ ]+++open :: U.Test+open = "TOC files open the associated device correctly" ~: U.TestCase $ do+ c <- cdioOpen (Just $ dataFile "cdtext.toc") DriverUnknown+ cdio <- case c of+ Nothing -> U.assertFailure "Can't open the TOC file"+ Just c' -> return c'+ + checkMmc cdio $ Just False+ checkAccessMode cdio [Image]+ checkSource cdio [dataFile "cdtext.toc"]
+ test/Test/Libcdio/Upstream/Foreign/Common.hs view
@@ -0,0 +1,84 @@+{-|+Description: ++Copyright: (c) 2019-2021 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: experimental+Portability: portable++The semantics of several functions in this module were copied from+@test/driver/helper.*@ in the libcdio source, but their implementation was+rewritten for the Haskell wrapper.+-}+module Test.Libcdio.Upstream.Foreign.Common where+++import qualified Test.HUnit as U+import Test.HUnit ( (@?), (@=?), (~:) )++import qualified Control.Monad as M++import qualified Data.Char as C+import qualified Data.Maybe as Y++import Foreign.Libcdio.Device+++dataDir :: String+dataDir = "test/datafiles/upstream/"++dataFile :: String -> String+dataFile = (++) dataDir+++checkArg :: SessionArg -> Cdio -> [String] -> U.Assertion+checkArg k c ss = do+ v <- getArg c k+ value <- case v of+ Nothing -> U.assertFailure $ show k ++ "' isn't assigned"+ Just v' -> return v'+ null ss || elem value ss @? show k ++ "' has invalid value '" ++ value ++ "'"++checkAccessMode :: Cdio -> [AccessMode] -> U.Assertion+checkAccessMode c ms = do+ v <- getAccessMode c+ value <- case v of+ Nothing -> U.assertFailure "'access-mode' isn't assigned"+ Just v' -> return v'+ null ms || elem value ms @? "'access-mode' has invalid value '" ++ show value ++ "'"++checkSource :: Cdio -> [String] -> U.Assertion+checkSource = checkArg Source+++-- | Whether the session advertises MMC support. A 'Nothing' value indicates+-- that the actual state doesn't matter, just that it's advertised at all.+-- +-- The C function takes a numeric value translating to the following:+-- +-- * @1@ -> 'Just' 'False'+-- * @2@ -> 'Just' 'True'+-- * @3@ -> 'Nothing'+checkMmc :: Cdio -> Maybe Bool -> U.Assertion+checkMmc c b = do+ v <- getArg c MmcSupported+ Y.isJust v @? "Session does not describe MMC status."+ case b of+ Just _ -> map C.toLower . show <$> b @=? v+ Nothing -> return ()+++find :: DriverId -> Maybe AccessMode -> ((Cdio, String) -> U.Assertion) -> U.Test+find d m f = "The driver is able to find its devices" ~: U.TestCase $ do+ ss <- devices d+ not (null ss) @? "Can't find a device"+ let open s = case m of+ Nothing -> cdioOpen s d+ Just m' -> cdioOpenAm s d m'+ cs <- mapM (open . Just) ss+ cs' <- M.forM (zip ss cs) $ \(s, c) -> case c of+ Nothing -> U.assertFailure $ "Can't open device '" ++ s ++ "'"+ Just c' -> return c'+ mapM_ f $ zip cs' ss
+ test/Test/Libcdio/Upstream/Foreign/FreeBsd.hs view
@@ -0,0 +1,38 @@+{-|+Description: ++Copyright: (c) 2019 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: experimental+Portability: portable+-}+module Test.Libcdio.Upstream.Foreign.FreeBsd (tests) where+++import qualified Test.HUnit as U+import Test.HUnit ( (~:) )++import Foreign.Libcdio.Device++import Test.Libcdio.Upstream.Foreign.Common+++tests :: U.Test+tests = "Foreign.Libcdio.Test.FreeBsd" ~: U.TestList tests'+ where tests' | haveDriver DriverFreeBsd =+ [ open+ , find DriverFreeBsd Nothing $ \(c, s) -> checkSource c [s]+ ]+ | otherwise = []++open :: U.Test+open = "The driver opens devices correctly" ~: U.TestCase $ do+ c <- cdioOpen Nothing DriverFreeBsd+ cdio <- case c of+ Nothing -> U.assertFailure "Can't open the default device"+ Just c' -> return c'+ + checkAccessMode cdio [Ioctl_, Cam]+ checkMmc cdio $ Just False
+ test/Test/Libcdio/Upstream/Foreign/Linux.hs view
@@ -0,0 +1,47 @@+{-|+Description: ++Copyright: (c) 2019-2021 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: experimental+Portability: portable+-}+module Test.Libcdio.Upstream.Foreign.Linux (tests) where+++import qualified Test.HUnit as U+import Test.HUnit ( (~:) )++import Foreign.Libcdio.Device++import Test.Libcdio.Upstream.Foreign.Common+++tests :: U.Test+tests = "Foreign.Libcdio.Test.Linux" ~: U.TestList tests'+ where tests' | haveDriver DriverLinux =+ [ find DriverLinux (Just MmcReadWrite) check+ ]+ | otherwise = []++check :: (Cdio, String) -> U.Assertion+check (cdio, source) = do+ {- Exact behaviour dependant on whether there's a disc in the drive+ tc <- lastTrackNum cdio+ if Y.fromMaybe maxTrack tc >= maxTrack - 1+ then mempty+ else do+ l <- trackLsn cdio maxTrack+ Y.isNothing l @? "Overlarge track not detected"+ -}+ + checkSource cdio [source]+ checkMmc cdio Nothing+ + checkArg ScsiTuple cdio []+ + {- Access mode doesn't seem implemented+ checkAccessMode cdio [MmcReadWrite]+ -}
+ test/Test/Libcdio/Upstream/Foreign/Nrg.hs view
@@ -0,0 +1,50 @@+{-|+Description: ++Copyright: (c) 2019-2020 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: experimental+Portability: portable+-}+module Test.Libcdio.Upstream.Foreign.Nrg+ ( tests+ , goodNrg+ ) where+++import qualified Test.HUnit as U+import Test.HUnit ( (@=?), (~:) )++import Foreign.Libcdio.CdText+import Foreign.Libcdio.Device++import Test.Libcdio.Upstream.Foreign.Common+++tests :: U.Test+tests = "Foreign.Libcdio.Test.Nrg" ~: U.TestList $ map open goodNrg+++goodNrg :: [FilePath]+goodNrg+ | haveDriver DriverNrg = ["p1.nrg"]+ | otherwise = []+++open :: FilePath -> U.Test+open f = "Nero images open the associated device correctly" ~: U.TestCase $ do+ c <- cdioOpen (Just $ dataFile f) DriverUnknown+ cdio <- case c of+ Nothing -> U.assertFailure "Can't open the Nero file"+ Just c' -> return c'+ + p <- cdTextGet cdio Performer Nothing+ Just "Richard Stallman" @=? p+ t <- cdTextGet cdio Title Nothing+ Just "Join us now we have the software" @=? t+ + checkMmc cdio $ Just False+ checkAccessMode cdio [Image]+ checkSource cdio [dataFile f]
+ test/Test/Libcdio/Upstream/Foreign/OsX.hs view
@@ -0,0 +1,39 @@+{-|+Description: ++Copyright: (c) 2019 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: experimental+Portability: portable+-}+module Test.Libcdio.Upstream.Foreign.OsX (tests) where+++import qualified Test.HUnit as U+import Test.HUnit ( (@?), (~:) )++import qualified Data.Maybe as Y++import Foreign.Libcdio.Device+import Foreign.Libcdio.Disc++import Test.Libcdio.Upstream.Foreign.Common+++tests :: U.Test+tests = "Foreign.Libcdio.Test.OsX" ~: U.TestList tests'+ where tests' | haveDriver DriverOsX =+ [ find DriverOsX Nothing check+ ]+ | otherwise = []++check :: (Cdio, String) -> U.Assertion+check (cdio, source) = do+ checkSource cdio [source]+ -- can't supply arbitrary access modes+ --checkAccessMode cdio ["OS X"]+ + m <- discMode cdio+ Y.isJust m @? "Error getting disc mode for device '" ++ source ++ "'"
+ test/Test/Libcdio/Upstream/Foreign/Pregap.hs view
@@ -0,0 +1,54 @@+{-|+Description: ++Copyright: (c) 2019-2020 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: experimental+Portability: portable+-}+module Test.Libcdio.Upstream.Foreign.Pregap+ ( tests+ , gaps+ ) where+++import qualified Test.HUnit as U+import Test.HUnit ( (@=?), (~:) )++import qualified Control.Monad as M++import qualified System.Directory as D++import Foreign.Libcdio.Device+import Foreign.Libcdio.Track+import Foreign.Libcdio.Types++import Test.Libcdio.Upstream.Foreign.Common+++tests :: U.Test+tests = "Foreign.Libcdio.Test.Pregap" ~: map ((\f (a,b,c)->f a b c) checkGap) gaps++gaps :: [(DriverId, FilePath, [(Track, Maybe Lsn)])]+gaps =+ [ (DriverCdrDao, "t2.toc", [(1, Just 4425), (2, Nothing)])+ , (DriverBinCue, "p1.cue", [(1, Just 0), (2, Just 150), (3, Nothing)])+ ] +++ [ (DriverNrg, "p1.nrg", [(2, Just 225), (3, Nothing)])+ | haveDriver DriverNrg+ ]++checkGap :: DriverId -> FilePath -> [(Track, Maybe Lsn)] -> U.Assertion+checkGap d s gs+ | haveDriver d = do+ c <- D.withCurrentDirectory dataDir $ cdioOpen (Just s) d+ cdio <- case c of+ Nothing -> U.assertFailure $ "Can't open the disc image '" ++ s ++ "'"+ Just c' -> return c'+ + M.forM_ gs $ \(t, g) -> do+ p <- pregapLsn cdio t+ g @=? p+ | otherwise = return ()
+ test/Test/Libcdio/Upstream/Foreign/SizeOf.hs view
@@ -0,0 +1,26 @@+{-|+Description: ++Copyright: (c) 2019 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: experimental+Portability: portable+-}+module Test.Libcdio.Upstream.Foreign.SizeOf (tests) where+++import qualified Test.HUnit as U+import Test.HUnit ( (~=?), (~:) )++import qualified Foreign.Storable as S++import Foreign.Libcdio.Sector+++tests :: U.Test+tests = "Foreign.Libcdio.Test.SizeOf" ~: U.TestList+ [ 3 ~=? S.sizeOf (Msf 0 0 0)+ --TODO: More from iso9660_private.h+ ]
+ test/Test/Libcdio/Upstream/Foreign/Solaris.hs view
@@ -0,0 +1,32 @@+{-|+Description: ++Copyright: (c) 2019 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: experimental+Portability: portable+-}+module Test.Libcdio.Upstream.Foreign.Solaris (tests) where+++import qualified Test.HUnit as U+import Test.HUnit ( (~:) )++import Foreign.Libcdio.Device++import Test.Libcdio.Upstream.Foreign.Common+++tests :: U.Test+tests = "Foreign.Libcdio.Test.Solaris" ~: U.TestList tests'+ where tests' | haveDriver DriverSolaris =+ [ find DriverSolaris (Just Scsi) check+ ]+ | otherwise = []++check :: (Cdio, String) -> U.Assertion+check (cdio, source) = do+ checkSource cdio [source]+ checkAccessMode cdio [Scsi]
+ test/Test/Libcdio/Upstream/Foreign/Track.hs view
@@ -0,0 +1,44 @@+{-|+Description: ++Copyright: (c) 2019 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: experimental+Portability: portable+-}+module Test.Libcdio.Upstream.Foreign.Track (tests) where+++import qualified Test.HUnit as U+import Test.HUnit ( (@?), (@=?), (~:) )++import qualified Data.Maybe as Y++import Foreign.Libcdio.Device+import Foreign.Libcdio.Track++import Test.Libcdio.Upstream.Foreign.Common+++tests :: U.Test+tests = "Foreign.Libcdio.Test.Track" ~: U.TestList+ [ open+ ]++open :: U.Test+open = "Track accessing works correctly" ~: U.TestCase $ do+ c <- cdioOpen (Just . dataFile $ "cdda.cue") DriverUnknown+ cdio <- case c of+ Nothing -> U.assertFailure "Can't open the image file"+ Just c' -> return c'+ + t <- trackAt cdio 1000+ Y.isNothing t @? "Overlarge addresses aren't caught"+ + ts <- mapM (trackAt cdio) $ 301 : [0..9]+ mapM_ (Just 1 @=?) ts+ + l <- trackAt cdio 302+ Just DiscLeadout @=? l
+ test/Test/Libcdio/Upstream/Foreign/Win32.hs view
@@ -0,0 +1,36 @@+{-|+Description: ++Copyright: (c) 2019-2021 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: experimental+Portability: portable+-}+module Test.Libcdio.Upstream.Foreign.Win32 (tests) where+++import qualified Test.HUnit as U+import Test.HUnit ( (~:) )++import Foreign.Libcdio.Device++import Test.Libcdio.Upstream.Foreign.Common+++tests :: U.Test+tests = "Foreign.Libcdio.Test.Win32" ~: U.TestList tests'+ where tests' | haveDriver DriverWin32 =+ [ find DriverWin32 Nothing $ \(c, s) -> checkSource c [s]+ , find DriverWin32 (Just Aspi) $ flip checkAccessMode [Aspi] . fst+ , find DriverWin32 (Just Ioctl_) checkIoctl+ ]+ | otherwise = []++checkIoctl :: (Cdio, String) -> U.Assertion+checkIoctl (cdio, _) = do+ checkArg ScsiTuple cdio []+ + checkAccessMode cdio [Ioctl_]+ checkMmc cdio $ Just True
+ test/Test/Libcdio/Upstream/Sound/Common.hs view
@@ -0,0 +1,88 @@+{-# LANGUAGE CPP #-}++{-|+Description: ++Copyright: (c) 2020-2021 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: experimental+Portability: portable+-}+module Test.Libcdio.Upstream.Sound.Common+ ( Foreign.dataDir+ , checkArg+ , checkAccessMode+ , checkSource+ , checkMmc+ , testCdio+ , testCdioMode+ ) where+++import qualified Test.HUnit as U+import Test.HUnit ( (~:), (@=?) )++import qualified Data.Maybe as Y+import qualified Data.Text as T++import qualified System.Directory as D++import Sound.Libcdio++import qualified Test.Libcdio.Upstream.Foreign.Common as Foreign+++-- | Whether the session argument is one of the allowed values. An empty list+-- indicates that the actual value doesn't matter, just that it exists.+checkArg :: SessionArg -> [T.Text] -> Cdio U.Assertion+checkArg k ss = do+ v <- getArg k+ return $ case v of+ Nothing -> U.assertFailure $ show k ++ "' isn't assigned"+ Just v' -> if null ss || elem v' ss+ then return ()+ else U.assertFailure $ show k ++ "' has invalid value '" ++ T.unpack v' ++ "'"++checkAccessMode :: [AccessMode] -> Cdio U.Assertion+checkAccessMode ms = do+ v <- getAccessMode+ return $ case v of+ Nothing -> U.assertFailure "'access-mode' isn't assigned"+ Just v' -> if null ms || elem v' ms+ then return ()+ else U.assertFailure $ "'access-mode' has invalid value '" ++ show v' ++ "'"++checkSource :: [FilePath] -> Cdio U.Assertion+checkSource = checkArg Source . map T.pack+++-- | Whether the session advertises MMC support. A 'Nothing' value indicates+-- that the actual state doesn't matter, just that it's advertised at all.+-- +-- The C function takes a numeric value translating to the following:+-- +-- * @1@ -> 'Just' 'False'+-- * @2@ -> 'Just' 'True'+-- * @3@ -> 'Nothing'+checkMmc :: Maybe Bool -> Cdio U.Assertion+checkMmc b = do+ v <- getArg MmcSupported+ return $ if Y.isJust v+ then case b of+ Just _ -> (T.toLower . T.pack . show <$> b) @=? v+ Nothing -> return ()+ else U.assertFailure "Session does not describe MMC status."+++testCdio :: [FilePath] -> (FilePath -> Cdio [U.Assertion]) -> U.Test+testCdio = testCdioMode Nothing++testCdioMode :: Maybe AccessMode -> [FilePath] -> (FilePath -> Cdio [U.Assertion]) -> U.Test+testCdioMode m fs c = U.TestList . flip map fs $ \f -> f ~: U.TestCase $ do+ o <- D.withCurrentDirectory Foreign.dataDir . open' (Just f) False $ c f+ either (const $ U.assertFailure "Can't open the image or device") sequence_ o+ where open' = case m of+ Just m' -> openMode m'+ Nothing -> open
+ test/Test/Libcdio/Upstream/Sound/Image.hs view
@@ -0,0 +1,134 @@+{-# LANGUAGE OverloadedStrings #-}+{-# OPTIONS_GHC -Wno-unused-local-binds #-}++{-|+Description: ++Copyright: (c) 2020-2021 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: experimental+Portability: portable+-}+module Test.Libcdio.Upstream.Sound.Image (tests) where+++import qualified Test.HUnit as U+import Test.HUnit ( (@=?), (~:) )++import qualified Data.Either.Compat as E+import qualified Data.Maybe as Y+import qualified Data.Text as T++import qualified System.Directory as D++import Sound.Libcdio+import Sound.Libcdio.Device+import Sound.Libcdio.Read.CdText++import Test.Libcdio.Upstream.Sound.Common++import qualified Test.Libcdio.Upstream.Foreign.BinCue as Foreign+import qualified Test.Libcdio.Upstream.Foreign.CdrDao as Foreign+import qualified Test.Libcdio.Upstream.Foreign.Nrg as Foreign+++tests :: U.Test+tests = "Sound.Libcdio.Test.Image" ~: U.TestList+ [ parseTests+ , run+ ]+++parseTests :: U.Test+parseTests = "Distinguish valid and invalid image files" ~: U.TestList+ [ parseCue+ , parseToc+ ]++parseCue :: U.Test+parseCue = "CUE" ~: U.TestList+ (map good Foreign.goodCues ++ map bad Foreign.badCues)+ where good = parseTest "CUE" True+ bad = parseTest "CUE" False++parseToc :: U.Test+parseToc = "TOC" ~: U.TestList+ (map good Foreign.goodToc ++ map bad Foreign.badToc)+ where good = parseTest "TOC" True+ bad = parseTest "TOC" False++parseTest :: String -> Bool -> FilePath -> U.Test+parseTest i y f = msg ~: U.TestCase . D.withCurrentDirectory dataDir $ do+ o <- open (Just f) False $ return ()+ y @=? E.isRight o+ where msg | y = f' ++ "is not recognized as a " ++ i'+ | otherwise = f' ++ "should not be recognized as a " ++ i'+ f' = "'" ++ f ++ "' "+ i' = i ++ " file"+++goodAll :: [FilePath]+goodAll = Foreign.goodCues ++ Foreign.goodToc ++ Foreign.goodNrg++goodCdText :: [FilePath]+goodCdText = ["cdda.cue", "cdtext.toc"] ++ Foreign.goodNrg+++run :: U.Test+run = U.TestList+ [ runAll+ , testCdText+ ]++runAll :: U.Test+runAll = "Expected session behaviour" ~: testCdio goodAll $ \f -> do+ _ <- setBlocksize 2048+ + m <- checkMmc $ Just False+ a <- checkAccessMode [Image]+ + let f' = T.unpack . T.replace ".cue" ".bin" $ T.pack f+ s <- checkSource [f']+ + _ <- setSpeed 5+ + return [m, a, s]++testCdText :: U.Test+testCdText = "Properly-formed CDTEXT" ~: testCdio goodCdText . const $ do+ is <- cdText . withAll $ do+ i <- info Nothing+ i1 <- info $ Just 1+ l' <- discId+ g' <- genre+ return (i, i1, l', g')+ let is' = E.fromRight [] is+ + let checkCdText (i, i1, _, _) = map (\f -> f i) discTests ++ map (\f -> f i1) trackTests+ --checkCdText (i, i1, l', g') = map (\f -> f i) discTests ++ [l l', g g'] ++ map (\f -> f i1) trackTests+ p i = Just "Richard Stallman" @=? performer i+ t i = Just "Join us now we have the software" @=? title i+ s i = Nothing @=? songwriter i+ c i = Nothing @=? composer i+ a i = Nothing @=? arranger i+ m i = Nothing @=? message i+ o i = Nothing @=? code i+ l l' = Just "0000010271955" @=? l'+ g g' = (Nothing, Nothing) @=? g'+ --discTests = [p, t, s, c, a, m, o]+ discTests = [p, t]+ p1 i1 = Just "Richard S" @=? performer i1+ t1 i1 = Just "Soft" @=? title i1+ s1 i1 = Nothing @=? songwriter i1+ c1 i1 = Nothing @=? composer i1+ a1 i1 = Nothing @=? arranger i1+ m1 i1 = Nothing @=? message i1+ o1 i1 = Just "US-XX1-98-01234" @=? code i1+ --trackTests = [p1, t1, s1, c1, a1, m1, o1]+ trackTests = []+ return $ case length is' of+ 0 -> [U.assertFailure "Can't access the CD Text"]+ 1 -> checkCdText . head $ Y.catMaybes is'+ _ -> [U.assertFailure "Trailing CD Text languages"]
+ test/Test/Libcdio/Upstream/Sound/System.hs view
@@ -0,0 +1,104 @@+{-# LANGUAGE OverloadedStrings #-}++{-|+Description: ++Copyright: (c) 2020-2021 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: experimental+Portability: portable+-}+module Test.Libcdio.Upstream.Sound.System (tests) where+++import qualified Test.HUnit as U+import Test.HUnit ( (@?), (~:) )++import qualified Data.Maybe as Y++import Sound.Libcdio+import Sound.Libcdio.Device+import Sound.Libcdio.Read.Data++import Test.Libcdio.Upstream.Sound.Common+++tests :: U.Test+tests = "Sound.Libcdio.Test.System" ~: U.TestList+ [ haveSystemDriver d ts+ | (d, ts) <-+ [ (DriverFreeBsd, testsBsd)+ , (DriverLinux, testsLinux)+ , (DriverOsX, testsOsx)+ , (DriverSolaris, testsSolaris)+ , (DriverWin32, testsWin32)+ ]+ ]++testsBsd :: U.Test+testsBsd = find DriverFreeBsd Nothing $ \p -> do+ s <- checkSource [p]+ a <- checkAccessMode [Ioctl_, Cam]+ m <- checkMmc $ Just False+ return [s, a, m]++testsLinux :: U.Test+testsLinux = find DriverLinux (Just MmcReadWrite) $ \p -> do+ s <- checkSource [p]+ m <- checkMmc Nothing+ t <- checkArg ScsiTuple []+ return [s, m, t]++testsOsx :: U.Test+testsOsx = find DriverOsX Nothing $ \p -> do+ s <- checkSource [p]+ -- can't supply arbitrary access modes+ --a <- checkAccessMode ["OS X"]+ + d <- discMode+ let d' = Y.isJust d @? "Error getting disc mode"+ + return [s, d']++testsSolaris :: U.Test+testsSolaris = find DriverSolaris (Just Scsi) $ \p -> do+ s <- checkSource [p]+ a <- checkAccessMode [Scsi]+ return [s, a]++testsWin32 :: U.Test+testsWin32 = U.TestList $ map (uncurry $ find DriverWin32)+ [ ( Nothing, \p -> do+ s <- checkSource [p]+ return [s]+ )+ , ( Just Aspi, \p -> do+ s <- checkSource [p]+ a <- checkAccessMode [Aspi]+ return [s, a]+ )+ , ( Just Ioctl_, \p -> do+ s <- checkSource [p]+ t <- checkArg ScsiTuple []+ a <- checkAccessMode [Ioctl_]+ m <- checkMmc $ Just True+ return [s, t, a, m]+ )+ ]+++haveSystemDriver :: DriverId -> U.Test -> U.Test+haveSystemDriver d ts+ | elem d drivers = drop 6 (show d) ~: ts+ | otherwise = U.TestList []++find :: DriverId -> Maybe AccessMode -> (FilePath -> Cdio [U.Assertion]) -> U.Test+find d m c = U.TestCase $ do+ ps <- devices d+ -- Don't actually want to fail on no device, for systems without CD drives+ sequence_ . unwrap $ testCdioMode m ps c+ where unwrap (U.TestCase a) = [a]+ unwrap (U.TestList ts) = concatMap unwrap ts+ unwrap (U.TestLabel _ t) = unwrap t
+ test/Test/Libcdio/Upstream/Sound/Track.hs view
@@ -0,0 +1,51 @@+{-|+Description: ++Copyright: (c) 2020 Sam May+License: GPL-3.0-or-later+Maintainer: ag@eitilt.life++Stability: experimental+Portability: portable+-}+module Test.Libcdio.Upstream.Sound.Track (tests) where+++import qualified Test.HUnit as U+import Test.HUnit ( (@?), (@=?), (~:) )++import qualified Control.Monad as M++import qualified Data.Maybe as Y++import Sound.Libcdio.Track++import Test.Libcdio.Upstream.Sound.Common++import qualified Test.Libcdio.Upstream.Foreign.Pregap as Foreign+++tests :: U.Test+tests = "Sound.Libcdio.Test.Track" ~: U.TestList+ [ gaps+ , address+ ]++gaps :: U.Test+gaps = "Pregap lengths" ~: U.TestList $ map (\(_,b,c) -> checkGap b c) Foreign.gaps+ where checkGap f gs = testCdio [f] . const . M.forM gs $ \(t, g) -> do+ p <- pregap t+ return $ g @=? p++address :: U.Test+address = "Sector addressing" ~: testCdio ["cdda.cue"] . const $ do+ t <- trackAt 1000+ let t' = Y.isNothing t @? "Overlarge addresses aren't caught"+ + ts <- mapM trackAt $ 301 : [0..9]+ let ts' = mapM_ (Just 1 @=?) ts+ + l <- trackAt 302+ let l' = Just DiscLeadout @=? l+ + return [t', ts', l']
+ test/datafiles/unit/CP932.txt view
@@ -0,0 +1,7998 @@+#+# Name: cp932 to Unicode table+# Unicode version: 2.0+# Table version: 2.01+# Table format: Format A+# Date: 04/15/98+#+# Contact: Shawn.Steele@microsoft.com+#+# General notes: none+#+# Format: Three tab-separated columns+# Column #1 is the cp932 code (in hex)+# Column #2 is the Unicode (in hex as 0xXXXX)+# Column #3 is the Unicode name (follows a comment sign, '#')+#+# The entries are in cp932 order+#+0x00 0x0000 #NULL+0x01 0x0001 #START OF HEADING+0x02 0x0002 #START OF TEXT+0x03 0x0003 #END OF TEXT+0x04 0x0004 #END OF TRANSMISSION+0x05 0x0005 #ENQUIRY+0x06 0x0006 #ACKNOWLEDGE+0x07 0x0007 #BELL+0x08 0x0008 #BACKSPACE+0x09 0x0009 #HORIZONTAL TABULATION+0x0A 0x000A #LINE FEED+0x0B 0x000B #VERTICAL TABULATION+0x0C 0x000C #FORM FEED+0x0D 0x000D #CARRIAGE RETURN+0x0E 0x000E #SHIFT OUT+0x0F 0x000F #SHIFT IN+0x10 0x0010 #DATA LINK ESCAPE+0x11 0x0011 #DEVICE CONTROL ONE+0x12 0x0012 #DEVICE CONTROL TWO+0x13 0x0013 #DEVICE CONTROL THREE+0x14 0x0014 #DEVICE CONTROL FOUR+0x15 0x0015 #NEGATIVE ACKNOWLEDGE+0x16 0x0016 #SYNCHRONOUS IDLE+0x17 0x0017 #END OF TRANSMISSION BLOCK+0x18 0x0018 #CANCEL+0x19 0x0019 #END OF MEDIUM+0x1A 0x001A #SUBSTITUTE+0x1B 0x001B #ESCAPE+0x1C 0x001C #FILE SEPARATOR+0x1D 0x001D #GROUP SEPARATOR+0x1E 0x001E #RECORD SEPARATOR+0x1F 0x001F #UNIT SEPARATOR+0x20 0x0020 #SPACE+0x21 0x0021 #EXCLAMATION MARK+0x22 0x0022 #QUOTATION MARK+0x23 0x0023 #NUMBER SIGN+0x24 0x0024 #DOLLAR SIGN+0x25 0x0025 #PERCENT SIGN+0x26 0x0026 #AMPERSAND+0x27 0x0027 #APOSTROPHE+0x28 0x0028 #LEFT PARENTHESIS+0x29 0x0029 #RIGHT PARENTHESIS+0x2A 0x002A #ASTERISK+0x2B 0x002B #PLUS SIGN+0x2C 0x002C #COMMA+0x2D 0x002D #HYPHEN-MINUS+0x2E 0x002E #FULL STOP+0x2F 0x002F #SOLIDUS+0x30 0x0030 #DIGIT ZERO+0x31 0x0031 #DIGIT ONE+0x32 0x0032 #DIGIT TWO+0x33 0x0033 #DIGIT THREE+0x34 0x0034 #DIGIT FOUR+0x35 0x0035 #DIGIT FIVE+0x36 0x0036 #DIGIT SIX+0x37 0x0037 #DIGIT SEVEN+0x38 0x0038 #DIGIT EIGHT+0x39 0x0039 #DIGIT NINE+0x3A 0x003A #COLON+0x3B 0x003B #SEMICOLON+0x3C 0x003C #LESS-THAN SIGN+0x3D 0x003D #EQUALS SIGN+0x3E 0x003E #GREATER-THAN SIGN+0x3F 0x003F #QUESTION MARK+0x40 0x0040 #COMMERCIAL AT+0x41 0x0041 #LATIN CAPITAL LETTER A+0x42 0x0042 #LATIN CAPITAL LETTER B+0x43 0x0043 #LATIN CAPITAL LETTER C+0x44 0x0044 #LATIN CAPITAL LETTER D+0x45 0x0045 #LATIN CAPITAL LETTER E+0x46 0x0046 #LATIN CAPITAL LETTER F+0x47 0x0047 #LATIN CAPITAL LETTER G+0x48 0x0048 #LATIN CAPITAL LETTER H+0x49 0x0049 #LATIN CAPITAL LETTER I+0x4A 0x004A #LATIN CAPITAL LETTER J+0x4B 0x004B #LATIN CAPITAL LETTER K+0x4C 0x004C #LATIN CAPITAL LETTER L+0x4D 0x004D #LATIN CAPITAL LETTER M+0x4E 0x004E #LATIN CAPITAL LETTER N+0x4F 0x004F #LATIN CAPITAL LETTER O+0x50 0x0050 #LATIN CAPITAL LETTER P+0x51 0x0051 #LATIN CAPITAL LETTER Q+0x52 0x0052 #LATIN CAPITAL LETTER R+0x53 0x0053 #LATIN CAPITAL LETTER S+0x54 0x0054 #LATIN CAPITAL LETTER T+0x55 0x0055 #LATIN CAPITAL LETTER U+0x56 0x0056 #LATIN CAPITAL LETTER V+0x57 0x0057 #LATIN CAPITAL LETTER W+0x58 0x0058 #LATIN CAPITAL LETTER X+0x59 0x0059 #LATIN CAPITAL LETTER Y+0x5A 0x005A #LATIN CAPITAL LETTER Z+0x5B 0x005B #LEFT SQUARE BRACKET+0x5C 0x005C #REVERSE SOLIDUS+0x5D 0x005D #RIGHT SQUARE BRACKET+0x5E 0x005E #CIRCUMFLEX ACCENT+0x5F 0x005F #LOW LINE+0x60 0x0060 #GRAVE ACCENT+0x61 0x0061 #LATIN SMALL LETTER A+0x62 0x0062 #LATIN SMALL LETTER B+0x63 0x0063 #LATIN SMALL LETTER C+0x64 0x0064 #LATIN SMALL LETTER D+0x65 0x0065 #LATIN SMALL LETTER E+0x66 0x0066 #LATIN SMALL LETTER F+0x67 0x0067 #LATIN SMALL LETTER G+0x68 0x0068 #LATIN SMALL LETTER H+0x69 0x0069 #LATIN SMALL LETTER I+0x6A 0x006A #LATIN SMALL LETTER J+0x6B 0x006B #LATIN SMALL LETTER K+0x6C 0x006C #LATIN SMALL LETTER L+0x6D 0x006D #LATIN SMALL LETTER M+0x6E 0x006E #LATIN SMALL LETTER N+0x6F 0x006F #LATIN SMALL LETTER O+0x70 0x0070 #LATIN SMALL LETTER P+0x71 0x0071 #LATIN SMALL LETTER Q+0x72 0x0072 #LATIN SMALL LETTER R+0x73 0x0073 #LATIN SMALL LETTER S+0x74 0x0074 #LATIN SMALL LETTER T+0x75 0x0075 #LATIN SMALL LETTER U+0x76 0x0076 #LATIN SMALL LETTER V+0x77 0x0077 #LATIN SMALL LETTER W+0x78 0x0078 #LATIN SMALL LETTER X+0x79 0x0079 #LATIN SMALL LETTER Y+0x7A 0x007A #LATIN SMALL LETTER Z+0x7B 0x007B #LEFT CURLY BRACKET+0x7C 0x007C #VERTICAL LINE+0x7D 0x007D #RIGHT CURLY BRACKET+0x7E 0x007E #TILDE+0x7F 0x007F #DELETE+0x80 #UNDEFINED+0x81 #DBCS LEAD BYTE+0x82 #DBCS LEAD BYTE+0x83 #DBCS LEAD BYTE+0x84 #DBCS LEAD BYTE+0x85 #DBCS LEAD BYTE+0x86 #DBCS LEAD BYTE+0x87 #DBCS LEAD BYTE+0x88 #DBCS LEAD BYTE+0x89 #DBCS LEAD BYTE+0x8A #DBCS LEAD BYTE+0x8B #DBCS LEAD BYTE+0x8C #DBCS LEAD BYTE+0x8D #DBCS LEAD BYTE+0x8E #DBCS LEAD BYTE+0x8F #DBCS LEAD BYTE+0x90 #DBCS LEAD BYTE+0x91 #DBCS LEAD BYTE+0x92 #DBCS LEAD BYTE+0x93 #DBCS LEAD BYTE+0x94 #DBCS LEAD BYTE+0x95 #DBCS LEAD BYTE+0x96 #DBCS LEAD BYTE+0x97 #DBCS LEAD BYTE+0x98 #DBCS LEAD BYTE+0x99 #DBCS LEAD BYTE+0x9A #DBCS LEAD BYTE+0x9B #DBCS LEAD BYTE+0x9C #DBCS LEAD BYTE+0x9D #DBCS LEAD BYTE+0x9E #DBCS LEAD BYTE+0x9F #DBCS LEAD BYTE+0xA0 #UNDEFINED+0xA1 0xFF61 #HALFWIDTH IDEOGRAPHIC FULL STOP+0xA2 0xFF62 #HALFWIDTH LEFT CORNER BRACKET+0xA3 0xFF63 #HALFWIDTH RIGHT CORNER BRACKET+0xA4 0xFF64 #HALFWIDTH IDEOGRAPHIC COMMA+0xA5 0xFF65 #HALFWIDTH KATAKANA MIDDLE DOT+0xA6 0xFF66 #HALFWIDTH KATAKANA LETTER WO+0xA7 0xFF67 #HALFWIDTH KATAKANA LETTER SMALL A+0xA8 0xFF68 #HALFWIDTH KATAKANA LETTER SMALL I+0xA9 0xFF69 #HALFWIDTH KATAKANA LETTER SMALL U+0xAA 0xFF6A #HALFWIDTH KATAKANA LETTER SMALL E+0xAB 0xFF6B #HALFWIDTH KATAKANA LETTER SMALL O+0xAC 0xFF6C #HALFWIDTH KATAKANA LETTER SMALL YA+0xAD 0xFF6D #HALFWIDTH KATAKANA LETTER SMALL YU+0xAE 0xFF6E #HALFWIDTH KATAKANA LETTER SMALL YO+0xAF 0xFF6F #HALFWIDTH KATAKANA LETTER SMALL TU+0xB0 0xFF70 #HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK+0xB1 0xFF71 #HALFWIDTH KATAKANA LETTER A+0xB2 0xFF72 #HALFWIDTH KATAKANA LETTER I+0xB3 0xFF73 #HALFWIDTH KATAKANA LETTER U+0xB4 0xFF74 #HALFWIDTH KATAKANA LETTER E+0xB5 0xFF75 #HALFWIDTH KATAKANA LETTER O+0xB6 0xFF76 #HALFWIDTH KATAKANA LETTER KA+0xB7 0xFF77 #HALFWIDTH KATAKANA LETTER KI+0xB8 0xFF78 #HALFWIDTH KATAKANA LETTER KU+0xB9 0xFF79 #HALFWIDTH KATAKANA LETTER KE+0xBA 0xFF7A #HALFWIDTH KATAKANA LETTER KO+0xBB 0xFF7B #HALFWIDTH KATAKANA LETTER SA+0xBC 0xFF7C #HALFWIDTH KATAKANA LETTER SI+0xBD 0xFF7D #HALFWIDTH KATAKANA LETTER SU+0xBE 0xFF7E #HALFWIDTH KATAKANA LETTER SE+0xBF 0xFF7F #HALFWIDTH KATAKANA LETTER SO+0xC0 0xFF80 #HALFWIDTH KATAKANA LETTER TA+0xC1 0xFF81 #HALFWIDTH KATAKANA LETTER TI+0xC2 0xFF82 #HALFWIDTH KATAKANA LETTER TU+0xC3 0xFF83 #HALFWIDTH KATAKANA LETTER TE+0xC4 0xFF84 #HALFWIDTH KATAKANA LETTER TO+0xC5 0xFF85 #HALFWIDTH KATAKANA LETTER NA+0xC6 0xFF86 #HALFWIDTH KATAKANA LETTER NI+0xC7 0xFF87 #HALFWIDTH KATAKANA LETTER NU+0xC8 0xFF88 #HALFWIDTH KATAKANA LETTER NE+0xC9 0xFF89 #HALFWIDTH KATAKANA LETTER NO+0xCA 0xFF8A #HALFWIDTH KATAKANA LETTER HA+0xCB 0xFF8B #HALFWIDTH KATAKANA LETTER HI+0xCC 0xFF8C #HALFWIDTH KATAKANA LETTER HU+0xCD 0xFF8D #HALFWIDTH KATAKANA LETTER HE+0xCE 0xFF8E #HALFWIDTH KATAKANA LETTER HO+0xCF 0xFF8F #HALFWIDTH KATAKANA LETTER MA+0xD0 0xFF90 #HALFWIDTH KATAKANA LETTER MI+0xD1 0xFF91 #HALFWIDTH KATAKANA LETTER MU+0xD2 0xFF92 #HALFWIDTH KATAKANA LETTER ME+0xD3 0xFF93 #HALFWIDTH KATAKANA LETTER MO+0xD4 0xFF94 #HALFWIDTH KATAKANA LETTER YA+0xD5 0xFF95 #HALFWIDTH KATAKANA LETTER YU+0xD6 0xFF96 #HALFWIDTH KATAKANA LETTER YO+0xD7 0xFF97 #HALFWIDTH KATAKANA LETTER RA+0xD8 0xFF98 #HALFWIDTH KATAKANA LETTER RI+0xD9 0xFF99 #HALFWIDTH KATAKANA LETTER RU+0xDA 0xFF9A #HALFWIDTH KATAKANA LETTER RE+0xDB 0xFF9B #HALFWIDTH KATAKANA LETTER RO+0xDC 0xFF9C #HALFWIDTH KATAKANA LETTER WA+0xDD 0xFF9D #HALFWIDTH KATAKANA LETTER N+0xDE 0xFF9E #HALFWIDTH KATAKANA VOICED SOUND MARK+0xDF 0xFF9F #HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK+0xE0 #DBCS LEAD BYTE+0xE1 #DBCS LEAD BYTE+0xE2 #DBCS LEAD BYTE+0xE3 #DBCS LEAD BYTE+0xE4 #DBCS LEAD BYTE+0xE5 #DBCS LEAD BYTE+0xE6 #DBCS LEAD BYTE+0xE7 #DBCS LEAD BYTE+0xE8 #DBCS LEAD BYTE+0xE9 #DBCS LEAD BYTE+0xEA #DBCS LEAD BYTE+0xEB #DBCS LEAD BYTE+0xEC #DBCS LEAD BYTE+0xED #DBCS LEAD BYTE+0xEE #DBCS LEAD BYTE+0xEF #DBCS LEAD BYTE+0xF0 #DBCS LEAD BYTE+0xF1 #DBCS LEAD BYTE+0xF2 #DBCS LEAD BYTE+0xF3 #DBCS LEAD BYTE+0xF4 #DBCS LEAD BYTE+0xF5 #DBCS LEAD BYTE+0xF6 #DBCS LEAD BYTE+0xF7 #DBCS LEAD BYTE+0xF8 #DBCS LEAD BYTE+0xF9 #DBCS LEAD BYTE+0xFA #DBCS LEAD BYTE+0xFB #DBCS LEAD BYTE+0xFC #DBCS LEAD BYTE+0xFD #UNDEFINED+0xFE #UNDEFINED+0xFF #UNDEFINED+0x8140 0x3000 #IDEOGRAPHIC SPACE+0x8141 0x3001 #IDEOGRAPHIC COMMA+0x8142 0x3002 #IDEOGRAPHIC FULL STOP+0x8143 0xFF0C #FULLWIDTH COMMA+0x8144 0xFF0E #FULLWIDTH FULL STOP+0x8145 0x30FB #KATAKANA MIDDLE DOT+0x8146 0xFF1A #FULLWIDTH COLON+0x8147 0xFF1B #FULLWIDTH SEMICOLON+0x8148 0xFF1F #FULLWIDTH QUESTION MARK+0x8149 0xFF01 #FULLWIDTH EXCLAMATION MARK+0x814A 0x309B #KATAKANA-HIRAGANA VOICED SOUND MARK+0x814B 0x309C #KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK+0x814C 0x00B4 #ACUTE ACCENT+0x814D 0xFF40 #FULLWIDTH GRAVE ACCENT+0x814E 0x00A8 #DIAERESIS+0x814F 0xFF3E #FULLWIDTH CIRCUMFLEX ACCENT+0x8150 0xFFE3 #FULLWIDTH MACRON+0x8151 0xFF3F #FULLWIDTH LOW LINE+0x8152 0x30FD #KATAKANA ITERATION MARK+0x8153 0x30FE #KATAKANA VOICED ITERATION MARK+0x8154 0x309D #HIRAGANA ITERATION MARK+0x8155 0x309E #HIRAGANA VOICED ITERATION MARK+0x8156 0x3003 #DITTO MARK+0x8157 0x4EDD #CJK UNIFIED IDEOGRAPH+0x8158 0x3005 #IDEOGRAPHIC ITERATION MARK+0x8159 0x3006 #IDEOGRAPHIC CLOSING MARK+0x815A 0x3007 #IDEOGRAPHIC NUMBER ZERO+0x815B 0x30FC #KATAKANA-HIRAGANA PROLONGED SOUND MARK+0x815C 0x2015 #HORIZONTAL BAR+0x815D 0x2010 #HYPHEN+0x815E 0xFF0F #FULLWIDTH SOLIDUS+0x815F 0xFF3C #FULLWIDTH REVERSE SOLIDUS+0x8160 0xFF5E #FULLWIDTH TILDE+0x8161 0x2225 #PARALLEL TO+0x8162 0xFF5C #FULLWIDTH VERTICAL LINE+0x8163 0x2026 #HORIZONTAL ELLIPSIS+0x8164 0x2025 #TWO DOT LEADER+0x8165 0x2018 #LEFT SINGLE QUOTATION MARK+0x8166 0x2019 #RIGHT SINGLE QUOTATION MARK+0x8167 0x201C #LEFT DOUBLE QUOTATION MARK+0x8168 0x201D #RIGHT DOUBLE QUOTATION MARK+0x8169 0xFF08 #FULLWIDTH LEFT PARENTHESIS+0x816A 0xFF09 #FULLWIDTH RIGHT PARENTHESIS+0x816B 0x3014 #LEFT TORTOISE SHELL BRACKET+0x816C 0x3015 #RIGHT TORTOISE SHELL BRACKET+0x816D 0xFF3B #FULLWIDTH LEFT SQUARE BRACKET+0x816E 0xFF3D #FULLWIDTH RIGHT SQUARE BRACKET+0x816F 0xFF5B #FULLWIDTH LEFT CURLY BRACKET+0x8170 0xFF5D #FULLWIDTH RIGHT CURLY BRACKET+0x8171 0x3008 #LEFT ANGLE BRACKET+0x8172 0x3009 #RIGHT ANGLE BRACKET+0x8173 0x300A #LEFT DOUBLE ANGLE BRACKET+0x8174 0x300B #RIGHT DOUBLE ANGLE BRACKET+0x8175 0x300C #LEFT CORNER BRACKET+0x8176 0x300D #RIGHT CORNER BRACKET+0x8177 0x300E #LEFT WHITE CORNER BRACKET+0x8178 0x300F #RIGHT WHITE CORNER BRACKET+0x8179 0x3010 #LEFT BLACK LENTICULAR BRACKET+0x817A 0x3011 #RIGHT BLACK LENTICULAR BRACKET+0x817B 0xFF0B #FULLWIDTH PLUS SIGN+0x817C 0xFF0D #FULLWIDTH HYPHEN-MINUS+0x817D 0x00B1 #PLUS-MINUS SIGN+0x817E 0x00D7 #MULTIPLICATION SIGN+0x8180 0x00F7 #DIVISION SIGN+0x8181 0xFF1D #FULLWIDTH EQUALS SIGN+0x8182 0x2260 #NOT EQUAL TO+0x8183 0xFF1C #FULLWIDTH LESS-THAN SIGN+0x8184 0xFF1E #FULLWIDTH GREATER-THAN SIGN+0x8185 0x2266 #LESS-THAN OVER EQUAL TO+0x8186 0x2267 #GREATER-THAN OVER EQUAL TO+0x8187 0x221E #INFINITY+0x8188 0x2234 #THEREFORE+0x8189 0x2642 #MALE SIGN+0x818A 0x2640 #FEMALE SIGN+0x818B 0x00B0 #DEGREE SIGN+0x818C 0x2032 #PRIME+0x818D 0x2033 #DOUBLE PRIME+0x818E 0x2103 #DEGREE CELSIUS+0x818F 0xFFE5 #FULLWIDTH YEN SIGN+0x8190 0xFF04 #FULLWIDTH DOLLAR SIGN+0x8191 0xFFE0 #FULLWIDTH CENT SIGN+0x8192 0xFFE1 #FULLWIDTH POUND SIGN+0x8193 0xFF05 #FULLWIDTH PERCENT SIGN+0x8194 0xFF03 #FULLWIDTH NUMBER SIGN+0x8195 0xFF06 #FULLWIDTH AMPERSAND+0x8196 0xFF0A #FULLWIDTH ASTERISK+0x8197 0xFF20 #FULLWIDTH COMMERCIAL AT+0x8198 0x00A7 #SECTION SIGN+0x8199 0x2606 #WHITE STAR+0x819A 0x2605 #BLACK STAR+0x819B 0x25CB #WHITE CIRCLE+0x819C 0x25CF #BLACK CIRCLE+0x819D 0x25CE #BULLSEYE+0x819E 0x25C7 #WHITE DIAMOND+0x819F 0x25C6 #BLACK DIAMOND+0x81A0 0x25A1 #WHITE SQUARE+0x81A1 0x25A0 #BLACK SQUARE+0x81A2 0x25B3 #WHITE UP-POINTING TRIANGLE+0x81A3 0x25B2 #BLACK UP-POINTING TRIANGLE+0x81A4 0x25BD #WHITE DOWN-POINTING TRIANGLE+0x81A5 0x25BC #BLACK DOWN-POINTING TRIANGLE+0x81A6 0x203B #REFERENCE MARK+0x81A7 0x3012 #POSTAL MARK+0x81A8 0x2192 #RIGHTWARDS ARROW+0x81A9 0x2190 #LEFTWARDS ARROW+0x81AA 0x2191 #UPWARDS ARROW+0x81AB 0x2193 #DOWNWARDS ARROW+0x81AC 0x3013 #GETA MARK+0x81B8 0x2208 #ELEMENT OF+0x81B9 0x220B #CONTAINS AS MEMBER+0x81BA 0x2286 #SUBSET OF OR EQUAL TO+0x81BB 0x2287 #SUPERSET OF OR EQUAL TO+0x81BC 0x2282 #SUBSET OF+0x81BD 0x2283 #SUPERSET OF+0x81BE 0x222A #UNION+0x81BF 0x2229 #INTERSECTION+0x81C8 0x2227 #LOGICAL AND+0x81C9 0x2228 #LOGICAL OR+0x81CA 0xFFE2 #FULLWIDTH NOT SIGN+0x81CB 0x21D2 #RIGHTWARDS DOUBLE ARROW+0x81CC 0x21D4 #LEFT RIGHT DOUBLE ARROW+0x81CD 0x2200 #FOR ALL+0x81CE 0x2203 #THERE EXISTS+0x81DA 0x2220 #ANGLE+0x81DB 0x22A5 #UP TACK+0x81DC 0x2312 #ARC+0x81DD 0x2202 #PARTIAL DIFFERENTIAL+0x81DE 0x2207 #NABLA+0x81DF 0x2261 #IDENTICAL TO+0x81E0 0x2252 #APPROXIMATELY EQUAL TO OR THE IMAGE OF+0x81E1 0x226A #MUCH LESS-THAN+0x81E2 0x226B #MUCH GREATER-THAN+0x81E3 0x221A #SQUARE ROOT+0x81E4 0x223D #REVERSED TILDE+0x81E5 0x221D #PROPORTIONAL TO+0x81E6 0x2235 #BECAUSE+0x81E7 0x222B #INTEGRAL+0x81E8 0x222C #DOUBLE INTEGRAL+0x81F0 0x212B #ANGSTROM SIGN+0x81F1 0x2030 #PER MILLE SIGN+0x81F2 0x266F #MUSIC SHARP SIGN+0x81F3 0x266D #MUSIC FLAT SIGN+0x81F4 0x266A #EIGHTH NOTE+0x81F5 0x2020 #DAGGER+0x81F6 0x2021 #DOUBLE DAGGER+0x81F7 0x00B6 #PILCROW SIGN+0x81FC 0x25EF #LARGE CIRCLE+0x824F 0xFF10 #FULLWIDTH DIGIT ZERO+0x8250 0xFF11 #FULLWIDTH DIGIT ONE+0x8251 0xFF12 #FULLWIDTH DIGIT TWO+0x8252 0xFF13 #FULLWIDTH DIGIT THREE+0x8253 0xFF14 #FULLWIDTH DIGIT FOUR+0x8254 0xFF15 #FULLWIDTH DIGIT FIVE+0x8255 0xFF16 #FULLWIDTH DIGIT SIX+0x8256 0xFF17 #FULLWIDTH DIGIT SEVEN+0x8257 0xFF18 #FULLWIDTH DIGIT EIGHT+0x8258 0xFF19 #FULLWIDTH DIGIT NINE+0x8260 0xFF21 #FULLWIDTH LATIN CAPITAL LETTER A+0x8261 0xFF22 #FULLWIDTH LATIN CAPITAL LETTER B+0x8262 0xFF23 #FULLWIDTH LATIN CAPITAL LETTER C+0x8263 0xFF24 #FULLWIDTH LATIN CAPITAL LETTER D+0x8264 0xFF25 #FULLWIDTH LATIN CAPITAL LETTER E+0x8265 0xFF26 #FULLWIDTH LATIN CAPITAL LETTER F+0x8266 0xFF27 #FULLWIDTH LATIN CAPITAL LETTER G+0x8267 0xFF28 #FULLWIDTH LATIN CAPITAL LETTER H+0x8268 0xFF29 #FULLWIDTH LATIN CAPITAL LETTER I+0x8269 0xFF2A #FULLWIDTH LATIN CAPITAL LETTER J+0x826A 0xFF2B #FULLWIDTH LATIN CAPITAL LETTER K+0x826B 0xFF2C #FULLWIDTH LATIN CAPITAL LETTER L+0x826C 0xFF2D #FULLWIDTH LATIN CAPITAL LETTER M+0x826D 0xFF2E #FULLWIDTH LATIN CAPITAL LETTER N+0x826E 0xFF2F #FULLWIDTH LATIN CAPITAL LETTER O+0x826F 0xFF30 #FULLWIDTH LATIN CAPITAL LETTER P+0x8270 0xFF31 #FULLWIDTH LATIN CAPITAL LETTER Q+0x8271 0xFF32 #FULLWIDTH LATIN CAPITAL LETTER R+0x8272 0xFF33 #FULLWIDTH LATIN CAPITAL LETTER S+0x8273 0xFF34 #FULLWIDTH LATIN CAPITAL LETTER T+0x8274 0xFF35 #FULLWIDTH LATIN CAPITAL LETTER U+0x8275 0xFF36 #FULLWIDTH LATIN CAPITAL LETTER V+0x8276 0xFF37 #FULLWIDTH LATIN CAPITAL LETTER W+0x8277 0xFF38 #FULLWIDTH LATIN CAPITAL LETTER X+0x8278 0xFF39 #FULLWIDTH LATIN CAPITAL LETTER Y+0x8279 0xFF3A #FULLWIDTH LATIN CAPITAL LETTER Z+0x8281 0xFF41 #FULLWIDTH LATIN SMALL LETTER A+0x8282 0xFF42 #FULLWIDTH LATIN SMALL LETTER B+0x8283 0xFF43 #FULLWIDTH LATIN SMALL LETTER C+0x8284 0xFF44 #FULLWIDTH LATIN SMALL LETTER D+0x8285 0xFF45 #FULLWIDTH LATIN SMALL LETTER E+0x8286 0xFF46 #FULLWIDTH LATIN SMALL LETTER F+0x8287 0xFF47 #FULLWIDTH LATIN SMALL LETTER G+0x8288 0xFF48 #FULLWIDTH LATIN SMALL LETTER H+0x8289 0xFF49 #FULLWIDTH LATIN SMALL LETTER I+0x828A 0xFF4A #FULLWIDTH LATIN SMALL LETTER J+0x828B 0xFF4B #FULLWIDTH LATIN SMALL LETTER K+0x828C 0xFF4C #FULLWIDTH LATIN SMALL LETTER L+0x828D 0xFF4D #FULLWIDTH LATIN SMALL LETTER M+0x828E 0xFF4E #FULLWIDTH LATIN SMALL LETTER N+0x828F 0xFF4F #FULLWIDTH LATIN SMALL LETTER O+0x8290 0xFF50 #FULLWIDTH LATIN SMALL LETTER P+0x8291 0xFF51 #FULLWIDTH LATIN SMALL LETTER Q+0x8292 0xFF52 #FULLWIDTH LATIN SMALL LETTER R+0x8293 0xFF53 #FULLWIDTH LATIN SMALL LETTER S+0x8294 0xFF54 #FULLWIDTH LATIN SMALL LETTER T+0x8295 0xFF55 #FULLWIDTH LATIN SMALL LETTER U+0x8296 0xFF56 #FULLWIDTH LATIN SMALL LETTER V+0x8297 0xFF57 #FULLWIDTH LATIN SMALL LETTER W+0x8298 0xFF58 #FULLWIDTH LATIN SMALL LETTER X+0x8299 0xFF59 #FULLWIDTH LATIN SMALL LETTER Y+0x829A 0xFF5A #FULLWIDTH LATIN SMALL LETTER Z+0x829F 0x3041 #HIRAGANA LETTER SMALL A+0x82A0 0x3042 #HIRAGANA LETTER A+0x82A1 0x3043 #HIRAGANA LETTER SMALL I+0x82A2 0x3044 #HIRAGANA LETTER I+0x82A3 0x3045 #HIRAGANA LETTER SMALL U+0x82A4 0x3046 #HIRAGANA LETTER U+0x82A5 0x3047 #HIRAGANA LETTER SMALL E+0x82A6 0x3048 #HIRAGANA LETTER E+0x82A7 0x3049 #HIRAGANA LETTER SMALL O+0x82A8 0x304A #HIRAGANA LETTER O+0x82A9 0x304B #HIRAGANA LETTER KA+0x82AA 0x304C #HIRAGANA LETTER GA+0x82AB 0x304D #HIRAGANA LETTER KI+0x82AC 0x304E #HIRAGANA LETTER GI+0x82AD 0x304F #HIRAGANA LETTER KU+0x82AE 0x3050 #HIRAGANA LETTER GU+0x82AF 0x3051 #HIRAGANA LETTER KE+0x82B0 0x3052 #HIRAGANA LETTER GE+0x82B1 0x3053 #HIRAGANA LETTER KO+0x82B2 0x3054 #HIRAGANA LETTER GO+0x82B3 0x3055 #HIRAGANA LETTER SA+0x82B4 0x3056 #HIRAGANA LETTER ZA+0x82B5 0x3057 #HIRAGANA LETTER SI+0x82B6 0x3058 #HIRAGANA LETTER ZI+0x82B7 0x3059 #HIRAGANA LETTER SU+0x82B8 0x305A #HIRAGANA LETTER ZU+0x82B9 0x305B #HIRAGANA LETTER SE+0x82BA 0x305C #HIRAGANA LETTER ZE+0x82BB 0x305D #HIRAGANA LETTER SO+0x82BC 0x305E #HIRAGANA LETTER ZO+0x82BD 0x305F #HIRAGANA LETTER TA+0x82BE 0x3060 #HIRAGANA LETTER DA+0x82BF 0x3061 #HIRAGANA LETTER TI+0x82C0 0x3062 #HIRAGANA LETTER DI+0x82C1 0x3063 #HIRAGANA LETTER SMALL TU+0x82C2 0x3064 #HIRAGANA LETTER TU+0x82C3 0x3065 #HIRAGANA LETTER DU+0x82C4 0x3066 #HIRAGANA LETTER TE+0x82C5 0x3067 #HIRAGANA LETTER DE+0x82C6 0x3068 #HIRAGANA LETTER TO+0x82C7 0x3069 #HIRAGANA LETTER DO+0x82C8 0x306A #HIRAGANA LETTER NA+0x82C9 0x306B #HIRAGANA LETTER NI+0x82CA 0x306C #HIRAGANA LETTER NU+0x82CB 0x306D #HIRAGANA LETTER NE+0x82CC 0x306E #HIRAGANA LETTER NO+0x82CD 0x306F #HIRAGANA LETTER HA+0x82CE 0x3070 #HIRAGANA LETTER BA+0x82CF 0x3071 #HIRAGANA LETTER PA+0x82D0 0x3072 #HIRAGANA LETTER HI+0x82D1 0x3073 #HIRAGANA LETTER BI+0x82D2 0x3074 #HIRAGANA LETTER PI+0x82D3 0x3075 #HIRAGANA LETTER HU+0x82D4 0x3076 #HIRAGANA LETTER BU+0x82D5 0x3077 #HIRAGANA LETTER PU+0x82D6 0x3078 #HIRAGANA LETTER HE+0x82D7 0x3079 #HIRAGANA LETTER BE+0x82D8 0x307A #HIRAGANA LETTER PE+0x82D9 0x307B #HIRAGANA LETTER HO+0x82DA 0x307C #HIRAGANA LETTER BO+0x82DB 0x307D #HIRAGANA LETTER PO+0x82DC 0x307E #HIRAGANA LETTER MA+0x82DD 0x307F #HIRAGANA LETTER MI+0x82DE 0x3080 #HIRAGANA LETTER MU+0x82DF 0x3081 #HIRAGANA LETTER ME+0x82E0 0x3082 #HIRAGANA LETTER MO+0x82E1 0x3083 #HIRAGANA LETTER SMALL YA+0x82E2 0x3084 #HIRAGANA LETTER YA+0x82E3 0x3085 #HIRAGANA LETTER SMALL YU+0x82E4 0x3086 #HIRAGANA LETTER YU+0x82E5 0x3087 #HIRAGANA LETTER SMALL YO+0x82E6 0x3088 #HIRAGANA LETTER YO+0x82E7 0x3089 #HIRAGANA LETTER RA+0x82E8 0x308A #HIRAGANA LETTER RI+0x82E9 0x308B #HIRAGANA LETTER RU+0x82EA 0x308C #HIRAGANA LETTER RE+0x82EB 0x308D #HIRAGANA LETTER RO+0x82EC 0x308E #HIRAGANA LETTER SMALL WA+0x82ED 0x308F #HIRAGANA LETTER WA+0x82EE 0x3090 #HIRAGANA LETTER WI+0x82EF 0x3091 #HIRAGANA LETTER WE+0x82F0 0x3092 #HIRAGANA LETTER WO+0x82F1 0x3093 #HIRAGANA LETTER N+0x8340 0x30A1 #KATAKANA LETTER SMALL A+0x8341 0x30A2 #KATAKANA LETTER A+0x8342 0x30A3 #KATAKANA LETTER SMALL I+0x8343 0x30A4 #KATAKANA LETTER I+0x8344 0x30A5 #KATAKANA LETTER SMALL U+0x8345 0x30A6 #KATAKANA LETTER U+0x8346 0x30A7 #KATAKANA LETTER SMALL E+0x8347 0x30A8 #KATAKANA LETTER E+0x8348 0x30A9 #KATAKANA LETTER SMALL O+0x8349 0x30AA #KATAKANA LETTER O+0x834A 0x30AB #KATAKANA LETTER KA+0x834B 0x30AC #KATAKANA LETTER GA+0x834C 0x30AD #KATAKANA LETTER KI+0x834D 0x30AE #KATAKANA LETTER GI+0x834E 0x30AF #KATAKANA LETTER KU+0x834F 0x30B0 #KATAKANA LETTER GU+0x8350 0x30B1 #KATAKANA LETTER KE+0x8351 0x30B2 #KATAKANA LETTER GE+0x8352 0x30B3 #KATAKANA LETTER KO+0x8353 0x30B4 #KATAKANA LETTER GO+0x8354 0x30B5 #KATAKANA LETTER SA+0x8355 0x30B6 #KATAKANA LETTER ZA+0x8356 0x30B7 #KATAKANA LETTER SI+0x8357 0x30B8 #KATAKANA LETTER ZI+0x8358 0x30B9 #KATAKANA LETTER SU+0x8359 0x30BA #KATAKANA LETTER ZU+0x835A 0x30BB #KATAKANA LETTER SE+0x835B 0x30BC #KATAKANA LETTER ZE+0x835C 0x30BD #KATAKANA LETTER SO+0x835D 0x30BE #KATAKANA LETTER ZO+0x835E 0x30BF #KATAKANA LETTER TA+0x835F 0x30C0 #KATAKANA LETTER DA+0x8360 0x30C1 #KATAKANA LETTER TI+0x8361 0x30C2 #KATAKANA LETTER DI+0x8362 0x30C3 #KATAKANA LETTER SMALL TU+0x8363 0x30C4 #KATAKANA LETTER TU+0x8364 0x30C5 #KATAKANA LETTER DU+0x8365 0x30C6 #KATAKANA LETTER TE+0x8366 0x30C7 #KATAKANA LETTER DE+0x8367 0x30C8 #KATAKANA LETTER TO+0x8368 0x30C9 #KATAKANA LETTER DO+0x8369 0x30CA #KATAKANA LETTER NA+0x836A 0x30CB #KATAKANA LETTER NI+0x836B 0x30CC #KATAKANA LETTER NU+0x836C 0x30CD #KATAKANA LETTER NE+0x836D 0x30CE #KATAKANA LETTER NO+0x836E 0x30CF #KATAKANA LETTER HA+0x836F 0x30D0 #KATAKANA LETTER BA+0x8370 0x30D1 #KATAKANA LETTER PA+0x8371 0x30D2 #KATAKANA LETTER HI+0x8372 0x30D3 #KATAKANA LETTER BI+0x8373 0x30D4 #KATAKANA LETTER PI+0x8374 0x30D5 #KATAKANA LETTER HU+0x8375 0x30D6 #KATAKANA LETTER BU+0x8376 0x30D7 #KATAKANA LETTER PU+0x8377 0x30D8 #KATAKANA LETTER HE+0x8378 0x30D9 #KATAKANA LETTER BE+0x8379 0x30DA #KATAKANA LETTER PE+0x837A 0x30DB #KATAKANA LETTER HO+0x837B 0x30DC #KATAKANA LETTER BO+0x837C 0x30DD #KATAKANA LETTER PO+0x837D 0x30DE #KATAKANA LETTER MA+0x837E 0x30DF #KATAKANA LETTER MI+0x8380 0x30E0 #KATAKANA LETTER MU+0x8381 0x30E1 #KATAKANA LETTER ME+0x8382 0x30E2 #KATAKANA LETTER MO+0x8383 0x30E3 #KATAKANA LETTER SMALL YA+0x8384 0x30E4 #KATAKANA LETTER YA+0x8385 0x30E5 #KATAKANA LETTER SMALL YU+0x8386 0x30E6 #KATAKANA LETTER YU+0x8387 0x30E7 #KATAKANA LETTER SMALL YO+0x8388 0x30E8 #KATAKANA LETTER YO+0x8389 0x30E9 #KATAKANA LETTER RA+0x838A 0x30EA #KATAKANA LETTER RI+0x838B 0x30EB #KATAKANA LETTER RU+0x838C 0x30EC #KATAKANA LETTER RE+0x838D 0x30ED #KATAKANA LETTER RO+0x838E 0x30EE #KATAKANA LETTER SMALL WA+0x838F 0x30EF #KATAKANA LETTER WA+0x8390 0x30F0 #KATAKANA LETTER WI+0x8391 0x30F1 #KATAKANA LETTER WE+0x8392 0x30F2 #KATAKANA LETTER WO+0x8393 0x30F3 #KATAKANA LETTER N+0x8394 0x30F4 #KATAKANA LETTER VU+0x8395 0x30F5 #KATAKANA LETTER SMALL KA+0x8396 0x30F6 #KATAKANA LETTER SMALL KE+0x839F 0x0391 #GREEK CAPITAL LETTER ALPHA+0x83A0 0x0392 #GREEK CAPITAL LETTER BETA+0x83A1 0x0393 #GREEK CAPITAL LETTER GAMMA+0x83A2 0x0394 #GREEK CAPITAL LETTER DELTA+0x83A3 0x0395 #GREEK CAPITAL LETTER EPSILON+0x83A4 0x0396 #GREEK CAPITAL LETTER ZETA+0x83A5 0x0397 #GREEK CAPITAL LETTER ETA+0x83A6 0x0398 #GREEK CAPITAL LETTER THETA+0x83A7 0x0399 #GREEK CAPITAL LETTER IOTA+0x83A8 0x039A #GREEK CAPITAL LETTER KAPPA+0x83A9 0x039B #GREEK CAPITAL LETTER LAMDA+0x83AA 0x039C #GREEK CAPITAL LETTER MU+0x83AB 0x039D #GREEK CAPITAL LETTER NU+0x83AC 0x039E #GREEK CAPITAL LETTER XI+0x83AD 0x039F #GREEK CAPITAL LETTER OMICRON+0x83AE 0x03A0 #GREEK CAPITAL LETTER PI+0x83AF 0x03A1 #GREEK CAPITAL LETTER RHO+0x83B0 0x03A3 #GREEK CAPITAL LETTER SIGMA+0x83B1 0x03A4 #GREEK CAPITAL LETTER TAU+0x83B2 0x03A5 #GREEK CAPITAL LETTER UPSILON+0x83B3 0x03A6 #GREEK CAPITAL LETTER PHI+0x83B4 0x03A7 #GREEK CAPITAL LETTER CHI+0x83B5 0x03A8 #GREEK CAPITAL LETTER PSI+0x83B6 0x03A9 #GREEK CAPITAL LETTER OMEGA+0x83BF 0x03B1 #GREEK SMALL LETTER ALPHA+0x83C0 0x03B2 #GREEK SMALL LETTER BETA+0x83C1 0x03B3 #GREEK SMALL LETTER GAMMA+0x83C2 0x03B4 #GREEK SMALL LETTER DELTA+0x83C3 0x03B5 #GREEK SMALL LETTER EPSILON+0x83C4 0x03B6 #GREEK SMALL LETTER ZETA+0x83C5 0x03B7 #GREEK SMALL LETTER ETA+0x83C6 0x03B8 #GREEK SMALL LETTER THETA+0x83C7 0x03B9 #GREEK SMALL LETTER IOTA+0x83C8 0x03BA #GREEK SMALL LETTER KAPPA+0x83C9 0x03BB #GREEK SMALL LETTER LAMDA+0x83CA 0x03BC #GREEK SMALL LETTER MU+0x83CB 0x03BD #GREEK SMALL LETTER NU+0x83CC 0x03BE #GREEK SMALL LETTER XI+0x83CD 0x03BF #GREEK SMALL LETTER OMICRON+0x83CE 0x03C0 #GREEK SMALL LETTER PI+0x83CF 0x03C1 #GREEK SMALL LETTER RHO+0x83D0 0x03C3 #GREEK SMALL LETTER SIGMA+0x83D1 0x03C4 #GREEK SMALL LETTER TAU+0x83D2 0x03C5 #GREEK SMALL LETTER UPSILON+0x83D3 0x03C6 #GREEK SMALL LETTER PHI+0x83D4 0x03C7 #GREEK SMALL LETTER CHI+0x83D5 0x03C8 #GREEK SMALL LETTER PSI+0x83D6 0x03C9 #GREEK SMALL LETTER OMEGA+0x8440 0x0410 #CYRILLIC CAPITAL LETTER A+0x8441 0x0411 #CYRILLIC CAPITAL LETTER BE+0x8442 0x0412 #CYRILLIC CAPITAL LETTER VE+0x8443 0x0413 #CYRILLIC CAPITAL LETTER GHE+0x8444 0x0414 #CYRILLIC CAPITAL LETTER DE+0x8445 0x0415 #CYRILLIC CAPITAL LETTER IE+0x8446 0x0401 #CYRILLIC CAPITAL LETTER IO+0x8447 0x0416 #CYRILLIC CAPITAL LETTER ZHE+0x8448 0x0417 #CYRILLIC CAPITAL LETTER ZE+0x8449 0x0418 #CYRILLIC CAPITAL LETTER I+0x844A 0x0419 #CYRILLIC CAPITAL LETTER SHORT I+0x844B 0x041A #CYRILLIC CAPITAL LETTER KA+0x844C 0x041B #CYRILLIC CAPITAL LETTER EL+0x844D 0x041C #CYRILLIC CAPITAL LETTER EM+0x844E 0x041D #CYRILLIC CAPITAL LETTER EN+0x844F 0x041E #CYRILLIC CAPITAL LETTER O+0x8450 0x041F #CYRILLIC CAPITAL LETTER PE+0x8451 0x0420 #CYRILLIC CAPITAL LETTER ER+0x8452 0x0421 #CYRILLIC CAPITAL LETTER ES+0x8453 0x0422 #CYRILLIC CAPITAL LETTER TE+0x8454 0x0423 #CYRILLIC CAPITAL LETTER U+0x8455 0x0424 #CYRILLIC CAPITAL LETTER EF+0x8456 0x0425 #CYRILLIC CAPITAL LETTER HA+0x8457 0x0426 #CYRILLIC CAPITAL LETTER TSE+0x8458 0x0427 #CYRILLIC CAPITAL LETTER CHE+0x8459 0x0428 #CYRILLIC CAPITAL LETTER SHA+0x845A 0x0429 #CYRILLIC CAPITAL LETTER SHCHA+0x845B 0x042A #CYRILLIC CAPITAL LETTER HARD SIGN+0x845C 0x042B #CYRILLIC CAPITAL LETTER YERU+0x845D 0x042C #CYRILLIC CAPITAL LETTER SOFT SIGN+0x845E 0x042D #CYRILLIC CAPITAL LETTER E+0x845F 0x042E #CYRILLIC CAPITAL LETTER YU+0x8460 0x042F #CYRILLIC CAPITAL LETTER YA+0x8470 0x0430 #CYRILLIC SMALL LETTER A+0x8471 0x0431 #CYRILLIC SMALL LETTER BE+0x8472 0x0432 #CYRILLIC SMALL LETTER VE+0x8473 0x0433 #CYRILLIC SMALL LETTER GHE+0x8474 0x0434 #CYRILLIC SMALL LETTER DE+0x8475 0x0435 #CYRILLIC SMALL LETTER IE+0x8476 0x0451 #CYRILLIC SMALL LETTER IO+0x8477 0x0436 #CYRILLIC SMALL LETTER ZHE+0x8478 0x0437 #CYRILLIC SMALL LETTER ZE+0x8479 0x0438 #CYRILLIC SMALL LETTER I+0x847A 0x0439 #CYRILLIC SMALL LETTER SHORT I+0x847B 0x043A #CYRILLIC SMALL LETTER KA+0x847C 0x043B #CYRILLIC SMALL LETTER EL+0x847D 0x043C #CYRILLIC SMALL LETTER EM+0x847E 0x043D #CYRILLIC SMALL LETTER EN+0x8480 0x043E #CYRILLIC SMALL LETTER O+0x8481 0x043F #CYRILLIC SMALL LETTER PE+0x8482 0x0440 #CYRILLIC SMALL LETTER ER+0x8483 0x0441 #CYRILLIC SMALL LETTER ES+0x8484 0x0442 #CYRILLIC SMALL LETTER TE+0x8485 0x0443 #CYRILLIC SMALL LETTER U+0x8486 0x0444 #CYRILLIC SMALL LETTER EF+0x8487 0x0445 #CYRILLIC SMALL LETTER HA+0x8488 0x0446 #CYRILLIC SMALL LETTER TSE+0x8489 0x0447 #CYRILLIC SMALL LETTER CHE+0x848A 0x0448 #CYRILLIC SMALL LETTER SHA+0x848B 0x0449 #CYRILLIC SMALL LETTER SHCHA+0x848C 0x044A #CYRILLIC SMALL LETTER HARD SIGN+0x848D 0x044B #CYRILLIC SMALL LETTER YERU+0x848E 0x044C #CYRILLIC SMALL LETTER SOFT SIGN+0x848F 0x044D #CYRILLIC SMALL LETTER E+0x8490 0x044E #CYRILLIC SMALL LETTER YU+0x8491 0x044F #CYRILLIC SMALL LETTER YA+0x849F 0x2500 #BOX DRAWINGS LIGHT HORIZONTAL+0x84A0 0x2502 #BOX DRAWINGS LIGHT VERTICAL+0x84A1 0x250C #BOX DRAWINGS LIGHT DOWN AND RIGHT+0x84A2 0x2510 #BOX DRAWINGS LIGHT DOWN AND LEFT+0x84A3 0x2518 #BOX DRAWINGS LIGHT UP AND LEFT+0x84A4 0x2514 #BOX DRAWINGS LIGHT UP AND RIGHT+0x84A5 0x251C #BOX DRAWINGS LIGHT VERTICAL AND RIGHT+0x84A6 0x252C #BOX DRAWINGS LIGHT DOWN AND HORIZONTAL+0x84A7 0x2524 #BOX DRAWINGS LIGHT VERTICAL AND LEFT+0x84A8 0x2534 #BOX DRAWINGS LIGHT UP AND HORIZONTAL+0x84A9 0x253C #BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL+0x84AA 0x2501 #BOX DRAWINGS HEAVY HORIZONTAL+0x84AB 0x2503 #BOX DRAWINGS HEAVY VERTICAL+0x84AC 0x250F #BOX DRAWINGS HEAVY DOWN AND RIGHT+0x84AD 0x2513 #BOX DRAWINGS HEAVY DOWN AND LEFT+0x84AE 0x251B #BOX DRAWINGS HEAVY UP AND LEFT+0x84AF 0x2517 #BOX DRAWINGS HEAVY UP AND RIGHT+0x84B0 0x2523 #BOX DRAWINGS HEAVY VERTICAL AND RIGHT+0x84B1 0x2533 #BOX DRAWINGS HEAVY DOWN AND HORIZONTAL+0x84B2 0x252B #BOX DRAWINGS HEAVY VERTICAL AND LEFT+0x84B3 0x253B #BOX DRAWINGS HEAVY UP AND HORIZONTAL+0x84B4 0x254B #BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL+0x84B5 0x2520 #BOX DRAWINGS VERTICAL HEAVY AND RIGHT LIGHT+0x84B6 0x252F #BOX DRAWINGS DOWN LIGHT AND HORIZONTAL HEAVY+0x84B7 0x2528 #BOX DRAWINGS VERTICAL HEAVY AND LEFT LIGHT+0x84B8 0x2537 #BOX DRAWINGS UP LIGHT AND HORIZONTAL HEAVY+0x84B9 0x253F #BOX DRAWINGS VERTICAL LIGHT AND HORIZONTAL HEAVY+0x84BA 0x251D #BOX DRAWINGS VERTICAL LIGHT AND RIGHT HEAVY+0x84BB 0x2530 #BOX DRAWINGS DOWN HEAVY AND HORIZONTAL LIGHT+0x84BC 0x2525 #BOX DRAWINGS VERTICAL LIGHT AND LEFT HEAVY+0x84BD 0x2538 #BOX DRAWINGS UP HEAVY AND HORIZONTAL LIGHT+0x84BE 0x2542 #BOX DRAWINGS VERTICAL HEAVY AND HORIZONTAL LIGHT+0x8740 0x2460 #CIRCLED DIGIT ONE+0x8741 0x2461 #CIRCLED DIGIT TWO+0x8742 0x2462 #CIRCLED DIGIT THREE+0x8743 0x2463 #CIRCLED DIGIT FOUR+0x8744 0x2464 #CIRCLED DIGIT FIVE+0x8745 0x2465 #CIRCLED DIGIT SIX+0x8746 0x2466 #CIRCLED DIGIT SEVEN+0x8747 0x2467 #CIRCLED DIGIT EIGHT+0x8748 0x2468 #CIRCLED DIGIT NINE+0x8749 0x2469 #CIRCLED NUMBER TEN+0x874A 0x246A #CIRCLED NUMBER ELEVEN+0x874B 0x246B #CIRCLED NUMBER TWELVE+0x874C 0x246C #CIRCLED NUMBER THIRTEEN+0x874D 0x246D #CIRCLED NUMBER FOURTEEN+0x874E 0x246E #CIRCLED NUMBER FIFTEEN+0x874F 0x246F #CIRCLED NUMBER SIXTEEN+0x8750 0x2470 #CIRCLED NUMBER SEVENTEEN+0x8751 0x2471 #CIRCLED NUMBER EIGHTEEN+0x8752 0x2472 #CIRCLED NUMBER NINETEEN+0x8753 0x2473 #CIRCLED NUMBER TWENTY+0x8754 0x2160 #ROMAN NUMERAL ONE+0x8755 0x2161 #ROMAN NUMERAL TWO+0x8756 0x2162 #ROMAN NUMERAL THREE+0x8757 0x2163 #ROMAN NUMERAL FOUR+0x8758 0x2164 #ROMAN NUMERAL FIVE+0x8759 0x2165 #ROMAN NUMERAL SIX+0x875A 0x2166 #ROMAN NUMERAL SEVEN+0x875B 0x2167 #ROMAN NUMERAL EIGHT+0x875C 0x2168 #ROMAN NUMERAL NINE+0x875D 0x2169 #ROMAN NUMERAL TEN+0x875F 0x3349 #SQUARE MIRI+0x8760 0x3314 #SQUARE KIRO+0x8761 0x3322 #SQUARE SENTI+0x8762 0x334D #SQUARE MEETORU+0x8763 0x3318 #SQUARE GURAMU+0x8764 0x3327 #SQUARE TON+0x8765 0x3303 #SQUARE AARU+0x8766 0x3336 #SQUARE HEKUTAARU+0x8767 0x3351 #SQUARE RITTORU+0x8768 0x3357 #SQUARE WATTO+0x8769 0x330D #SQUARE KARORII+0x876A 0x3326 #SQUARE DORU+0x876B 0x3323 #SQUARE SENTO+0x876C 0x332B #SQUARE PAASENTO+0x876D 0x334A #SQUARE MIRIBAARU+0x876E 0x333B #SQUARE PEEZI+0x876F 0x339C #SQUARE MM+0x8770 0x339D #SQUARE CM+0x8771 0x339E #SQUARE KM+0x8772 0x338E #SQUARE MG+0x8773 0x338F #SQUARE KG+0x8774 0x33C4 #SQUARE CC+0x8775 0x33A1 #SQUARE M SQUARED+0x877E 0x337B #SQUARE ERA NAME HEISEI+0x8780 0x301D #REVERSED DOUBLE PRIME QUOTATION MARK+0x8781 0x301F #LOW DOUBLE PRIME QUOTATION MARK+0x8782 0x2116 #NUMERO SIGN+0x8783 0x33CD #SQUARE KK+0x8784 0x2121 #TELEPHONE SIGN+0x8785 0x32A4 #CIRCLED IDEOGRAPH HIGH+0x8786 0x32A5 #CIRCLED IDEOGRAPH CENTRE+0x8787 0x32A6 #CIRCLED IDEOGRAPH LOW+0x8788 0x32A7 #CIRCLED IDEOGRAPH LEFT+0x8789 0x32A8 #CIRCLED IDEOGRAPH RIGHT+0x878A 0x3231 #PARENTHESIZED IDEOGRAPH STOCK+0x878B 0x3232 #PARENTHESIZED IDEOGRAPH HAVE+0x878C 0x3239 #PARENTHESIZED IDEOGRAPH REPRESENT+0x878D 0x337E #SQUARE ERA NAME MEIZI+0x878E 0x337D #SQUARE ERA NAME TAISYOU+0x878F 0x337C #SQUARE ERA NAME SYOUWA+0x8790 0x2252 #APPROXIMATELY EQUAL TO OR THE IMAGE OF+0x8791 0x2261 #IDENTICAL TO+0x8792 0x222B #INTEGRAL+0x8793 0x222E #CONTOUR INTEGRAL+0x8794 0x2211 #N-ARY SUMMATION+0x8795 0x221A #SQUARE ROOT+0x8796 0x22A5 #UP TACK+0x8797 0x2220 #ANGLE+0x8798 0x221F #RIGHT ANGLE+0x8799 0x22BF #RIGHT TRIANGLE+0x879A 0x2235 #BECAUSE+0x879B 0x2229 #INTERSECTION+0x879C 0x222A #UNION+0x889F 0x4E9C #CJK UNIFIED IDEOGRAPH+0x88A0 0x5516 #CJK UNIFIED IDEOGRAPH+0x88A1 0x5A03 #CJK UNIFIED IDEOGRAPH+0x88A2 0x963F #CJK UNIFIED IDEOGRAPH+0x88A3 0x54C0 #CJK UNIFIED IDEOGRAPH+0x88A4 0x611B #CJK UNIFIED IDEOGRAPH+0x88A5 0x6328 #CJK UNIFIED IDEOGRAPH+0x88A6 0x59F6 #CJK UNIFIED IDEOGRAPH+0x88A7 0x9022 #CJK UNIFIED IDEOGRAPH+0x88A8 0x8475 #CJK UNIFIED IDEOGRAPH+0x88A9 0x831C #CJK UNIFIED IDEOGRAPH+0x88AA 0x7A50 #CJK UNIFIED IDEOGRAPH+0x88AB 0x60AA #CJK UNIFIED IDEOGRAPH+0x88AC 0x63E1 #CJK UNIFIED IDEOGRAPH+0x88AD 0x6E25 #CJK UNIFIED IDEOGRAPH+0x88AE 0x65ED #CJK UNIFIED IDEOGRAPH+0x88AF 0x8466 #CJK UNIFIED IDEOGRAPH+0x88B0 0x82A6 #CJK UNIFIED IDEOGRAPH+0x88B1 0x9BF5 #CJK UNIFIED IDEOGRAPH+0x88B2 0x6893 #CJK UNIFIED IDEOGRAPH+0x88B3 0x5727 #CJK UNIFIED IDEOGRAPH+0x88B4 0x65A1 #CJK UNIFIED IDEOGRAPH+0x88B5 0x6271 #CJK UNIFIED IDEOGRAPH+0x88B6 0x5B9B #CJK UNIFIED IDEOGRAPH+0x88B7 0x59D0 #CJK UNIFIED IDEOGRAPH+0x88B8 0x867B #CJK UNIFIED IDEOGRAPH+0x88B9 0x98F4 #CJK UNIFIED IDEOGRAPH+0x88BA 0x7D62 #CJK UNIFIED IDEOGRAPH+0x88BB 0x7DBE #CJK UNIFIED IDEOGRAPH+0x88BC 0x9B8E #CJK UNIFIED IDEOGRAPH+0x88BD 0x6216 #CJK UNIFIED IDEOGRAPH+0x88BE 0x7C9F #CJK UNIFIED IDEOGRAPH+0x88BF 0x88B7 #CJK UNIFIED IDEOGRAPH+0x88C0 0x5B89 #CJK UNIFIED IDEOGRAPH+0x88C1 0x5EB5 #CJK UNIFIED IDEOGRAPH+0x88C2 0x6309 #CJK UNIFIED IDEOGRAPH+0x88C3 0x6697 #CJK UNIFIED IDEOGRAPH+0x88C4 0x6848 #CJK UNIFIED IDEOGRAPH+0x88C5 0x95C7 #CJK UNIFIED IDEOGRAPH+0x88C6 0x978D #CJK UNIFIED IDEOGRAPH+0x88C7 0x674F #CJK UNIFIED IDEOGRAPH+0x88C8 0x4EE5 #CJK UNIFIED IDEOGRAPH+0x88C9 0x4F0A #CJK UNIFIED IDEOGRAPH+0x88CA 0x4F4D #CJK UNIFIED IDEOGRAPH+0x88CB 0x4F9D #CJK UNIFIED IDEOGRAPH+0x88CC 0x5049 #CJK UNIFIED IDEOGRAPH+0x88CD 0x56F2 #CJK UNIFIED IDEOGRAPH+0x88CE 0x5937 #CJK UNIFIED IDEOGRAPH+0x88CF 0x59D4 #CJK UNIFIED IDEOGRAPH+0x88D0 0x5A01 #CJK UNIFIED IDEOGRAPH+0x88D1 0x5C09 #CJK UNIFIED IDEOGRAPH+0x88D2 0x60DF #CJK UNIFIED IDEOGRAPH+0x88D3 0x610F #CJK UNIFIED IDEOGRAPH+0x88D4 0x6170 #CJK UNIFIED IDEOGRAPH+0x88D5 0x6613 #CJK UNIFIED IDEOGRAPH+0x88D6 0x6905 #CJK UNIFIED IDEOGRAPH+0x88D7 0x70BA #CJK UNIFIED IDEOGRAPH+0x88D8 0x754F #CJK UNIFIED IDEOGRAPH+0x88D9 0x7570 #CJK UNIFIED IDEOGRAPH+0x88DA 0x79FB #CJK UNIFIED IDEOGRAPH+0x88DB 0x7DAD #CJK UNIFIED IDEOGRAPH+0x88DC 0x7DEF #CJK UNIFIED IDEOGRAPH+0x88DD 0x80C3 #CJK UNIFIED IDEOGRAPH+0x88DE 0x840E #CJK UNIFIED IDEOGRAPH+0x88DF 0x8863 #CJK UNIFIED IDEOGRAPH+0x88E0 0x8B02 #CJK UNIFIED IDEOGRAPH+0x88E1 0x9055 #CJK UNIFIED IDEOGRAPH+0x88E2 0x907A #CJK UNIFIED IDEOGRAPH+0x88E3 0x533B #CJK UNIFIED IDEOGRAPH+0x88E4 0x4E95 #CJK UNIFIED IDEOGRAPH+0x88E5 0x4EA5 #CJK UNIFIED IDEOGRAPH+0x88E6 0x57DF #CJK UNIFIED IDEOGRAPH+0x88E7 0x80B2 #CJK UNIFIED IDEOGRAPH+0x88E8 0x90C1 #CJK UNIFIED IDEOGRAPH+0x88E9 0x78EF #CJK UNIFIED IDEOGRAPH+0x88EA 0x4E00 #CJK UNIFIED IDEOGRAPH+0x88EB 0x58F1 #CJK UNIFIED IDEOGRAPH+0x88EC 0x6EA2 #CJK UNIFIED IDEOGRAPH+0x88ED 0x9038 #CJK UNIFIED IDEOGRAPH+0x88EE 0x7A32 #CJK UNIFIED IDEOGRAPH+0x88EF 0x8328 #CJK UNIFIED IDEOGRAPH+0x88F0 0x828B #CJK UNIFIED IDEOGRAPH+0x88F1 0x9C2F #CJK UNIFIED IDEOGRAPH+0x88F2 0x5141 #CJK UNIFIED IDEOGRAPH+0x88F3 0x5370 #CJK UNIFIED IDEOGRAPH+0x88F4 0x54BD #CJK UNIFIED IDEOGRAPH+0x88F5 0x54E1 #CJK UNIFIED IDEOGRAPH+0x88F6 0x56E0 #CJK UNIFIED IDEOGRAPH+0x88F7 0x59FB #CJK UNIFIED IDEOGRAPH+0x88F8 0x5F15 #CJK UNIFIED IDEOGRAPH+0x88F9 0x98F2 #CJK UNIFIED IDEOGRAPH+0x88FA 0x6DEB #CJK UNIFIED IDEOGRAPH+0x88FB 0x80E4 #CJK UNIFIED IDEOGRAPH+0x88FC 0x852D #CJK UNIFIED IDEOGRAPH+0x8940 0x9662 #CJK UNIFIED IDEOGRAPH+0x8941 0x9670 #CJK UNIFIED IDEOGRAPH+0x8942 0x96A0 #CJK UNIFIED IDEOGRAPH+0x8943 0x97FB #CJK UNIFIED IDEOGRAPH+0x8944 0x540B #CJK UNIFIED IDEOGRAPH+0x8945 0x53F3 #CJK UNIFIED IDEOGRAPH+0x8946 0x5B87 #CJK UNIFIED IDEOGRAPH+0x8947 0x70CF #CJK UNIFIED IDEOGRAPH+0x8948 0x7FBD #CJK UNIFIED IDEOGRAPH+0x8949 0x8FC2 #CJK UNIFIED IDEOGRAPH+0x894A 0x96E8 #CJK UNIFIED IDEOGRAPH+0x894B 0x536F #CJK UNIFIED IDEOGRAPH+0x894C 0x9D5C #CJK UNIFIED IDEOGRAPH+0x894D 0x7ABA #CJK UNIFIED IDEOGRAPH+0x894E 0x4E11 #CJK UNIFIED IDEOGRAPH+0x894F 0x7893 #CJK UNIFIED IDEOGRAPH+0x8950 0x81FC #CJK UNIFIED IDEOGRAPH+0x8951 0x6E26 #CJK UNIFIED IDEOGRAPH+0x8952 0x5618 #CJK UNIFIED IDEOGRAPH+0x8953 0x5504 #CJK UNIFIED IDEOGRAPH+0x8954 0x6B1D #CJK UNIFIED IDEOGRAPH+0x8955 0x851A #CJK UNIFIED IDEOGRAPH+0x8956 0x9C3B #CJK UNIFIED IDEOGRAPH+0x8957 0x59E5 #CJK UNIFIED IDEOGRAPH+0x8958 0x53A9 #CJK UNIFIED IDEOGRAPH+0x8959 0x6D66 #CJK UNIFIED IDEOGRAPH+0x895A 0x74DC #CJK UNIFIED IDEOGRAPH+0x895B 0x958F #CJK UNIFIED IDEOGRAPH+0x895C 0x5642 #CJK UNIFIED IDEOGRAPH+0x895D 0x4E91 #CJK UNIFIED IDEOGRAPH+0x895E 0x904B #CJK UNIFIED IDEOGRAPH+0x895F 0x96F2 #CJK UNIFIED IDEOGRAPH+0x8960 0x834F #CJK UNIFIED IDEOGRAPH+0x8961 0x990C #CJK UNIFIED IDEOGRAPH+0x8962 0x53E1 #CJK UNIFIED IDEOGRAPH+0x8963 0x55B6 #CJK UNIFIED IDEOGRAPH+0x8964 0x5B30 #CJK UNIFIED IDEOGRAPH+0x8965 0x5F71 #CJK UNIFIED IDEOGRAPH+0x8966 0x6620 #CJK UNIFIED IDEOGRAPH+0x8967 0x66F3 #CJK UNIFIED IDEOGRAPH+0x8968 0x6804 #CJK UNIFIED IDEOGRAPH+0x8969 0x6C38 #CJK UNIFIED IDEOGRAPH+0x896A 0x6CF3 #CJK UNIFIED IDEOGRAPH+0x896B 0x6D29 #CJK UNIFIED IDEOGRAPH+0x896C 0x745B #CJK UNIFIED IDEOGRAPH+0x896D 0x76C8 #CJK UNIFIED IDEOGRAPH+0x896E 0x7A4E #CJK UNIFIED IDEOGRAPH+0x896F 0x9834 #CJK UNIFIED IDEOGRAPH+0x8970 0x82F1 #CJK UNIFIED IDEOGRAPH+0x8971 0x885B #CJK UNIFIED IDEOGRAPH+0x8972 0x8A60 #CJK UNIFIED IDEOGRAPH+0x8973 0x92ED #CJK UNIFIED IDEOGRAPH+0x8974 0x6DB2 #CJK UNIFIED IDEOGRAPH+0x8975 0x75AB #CJK UNIFIED IDEOGRAPH+0x8976 0x76CA #CJK UNIFIED IDEOGRAPH+0x8977 0x99C5 #CJK UNIFIED IDEOGRAPH+0x8978 0x60A6 #CJK UNIFIED IDEOGRAPH+0x8979 0x8B01 #CJK UNIFIED IDEOGRAPH+0x897A 0x8D8A #CJK UNIFIED IDEOGRAPH+0x897B 0x95B2 #CJK UNIFIED IDEOGRAPH+0x897C 0x698E #CJK UNIFIED IDEOGRAPH+0x897D 0x53AD #CJK UNIFIED IDEOGRAPH+0x897E 0x5186 #CJK UNIFIED IDEOGRAPH+0x8980 0x5712 #CJK UNIFIED IDEOGRAPH+0x8981 0x5830 #CJK UNIFIED IDEOGRAPH+0x8982 0x5944 #CJK UNIFIED IDEOGRAPH+0x8983 0x5BB4 #CJK UNIFIED IDEOGRAPH+0x8984 0x5EF6 #CJK UNIFIED IDEOGRAPH+0x8985 0x6028 #CJK UNIFIED IDEOGRAPH+0x8986 0x63A9 #CJK UNIFIED IDEOGRAPH+0x8987 0x63F4 #CJK UNIFIED IDEOGRAPH+0x8988 0x6CBF #CJK UNIFIED IDEOGRAPH+0x8989 0x6F14 #CJK UNIFIED IDEOGRAPH+0x898A 0x708E #CJK UNIFIED IDEOGRAPH+0x898B 0x7114 #CJK UNIFIED IDEOGRAPH+0x898C 0x7159 #CJK UNIFIED IDEOGRAPH+0x898D 0x71D5 #CJK UNIFIED IDEOGRAPH+0x898E 0x733F #CJK UNIFIED IDEOGRAPH+0x898F 0x7E01 #CJK UNIFIED IDEOGRAPH+0x8990 0x8276 #CJK UNIFIED IDEOGRAPH+0x8991 0x82D1 #CJK UNIFIED IDEOGRAPH+0x8992 0x8597 #CJK UNIFIED IDEOGRAPH+0x8993 0x9060 #CJK UNIFIED IDEOGRAPH+0x8994 0x925B #CJK UNIFIED IDEOGRAPH+0x8995 0x9D1B #CJK UNIFIED IDEOGRAPH+0x8996 0x5869 #CJK UNIFIED IDEOGRAPH+0x8997 0x65BC #CJK UNIFIED IDEOGRAPH+0x8998 0x6C5A #CJK UNIFIED IDEOGRAPH+0x8999 0x7525 #CJK UNIFIED IDEOGRAPH+0x899A 0x51F9 #CJK UNIFIED IDEOGRAPH+0x899B 0x592E #CJK UNIFIED IDEOGRAPH+0x899C 0x5965 #CJK UNIFIED IDEOGRAPH+0x899D 0x5F80 #CJK UNIFIED IDEOGRAPH+0x899E 0x5FDC #CJK UNIFIED IDEOGRAPH+0x899F 0x62BC #CJK UNIFIED IDEOGRAPH+0x89A0 0x65FA #CJK UNIFIED IDEOGRAPH+0x89A1 0x6A2A #CJK UNIFIED IDEOGRAPH+0x89A2 0x6B27 #CJK UNIFIED IDEOGRAPH+0x89A3 0x6BB4 #CJK UNIFIED IDEOGRAPH+0x89A4 0x738B #CJK UNIFIED IDEOGRAPH+0x89A5 0x7FC1 #CJK UNIFIED IDEOGRAPH+0x89A6 0x8956 #CJK UNIFIED IDEOGRAPH+0x89A7 0x9D2C #CJK UNIFIED IDEOGRAPH+0x89A8 0x9D0E #CJK UNIFIED IDEOGRAPH+0x89A9 0x9EC4 #CJK UNIFIED IDEOGRAPH+0x89AA 0x5CA1 #CJK UNIFIED IDEOGRAPH+0x89AB 0x6C96 #CJK UNIFIED IDEOGRAPH+0x89AC 0x837B #CJK UNIFIED IDEOGRAPH+0x89AD 0x5104 #CJK UNIFIED IDEOGRAPH+0x89AE 0x5C4B #CJK UNIFIED IDEOGRAPH+0x89AF 0x61B6 #CJK UNIFIED IDEOGRAPH+0x89B0 0x81C6 #CJK UNIFIED IDEOGRAPH+0x89B1 0x6876 #CJK UNIFIED IDEOGRAPH+0x89B2 0x7261 #CJK UNIFIED IDEOGRAPH+0x89B3 0x4E59 #CJK UNIFIED IDEOGRAPH+0x89B4 0x4FFA #CJK UNIFIED IDEOGRAPH+0x89B5 0x5378 #CJK UNIFIED IDEOGRAPH+0x89B6 0x6069 #CJK UNIFIED IDEOGRAPH+0x89B7 0x6E29 #CJK UNIFIED IDEOGRAPH+0x89B8 0x7A4F #CJK UNIFIED IDEOGRAPH+0x89B9 0x97F3 #CJK UNIFIED IDEOGRAPH+0x89BA 0x4E0B #CJK UNIFIED IDEOGRAPH+0x89BB 0x5316 #CJK UNIFIED IDEOGRAPH+0x89BC 0x4EEE #CJK UNIFIED IDEOGRAPH+0x89BD 0x4F55 #CJK UNIFIED IDEOGRAPH+0x89BE 0x4F3D #CJK UNIFIED IDEOGRAPH+0x89BF 0x4FA1 #CJK UNIFIED IDEOGRAPH+0x89C0 0x4F73 #CJK UNIFIED IDEOGRAPH+0x89C1 0x52A0 #CJK UNIFIED IDEOGRAPH+0x89C2 0x53EF #CJK UNIFIED IDEOGRAPH+0x89C3 0x5609 #CJK UNIFIED IDEOGRAPH+0x89C4 0x590F #CJK UNIFIED IDEOGRAPH+0x89C5 0x5AC1 #CJK UNIFIED IDEOGRAPH+0x89C6 0x5BB6 #CJK UNIFIED IDEOGRAPH+0x89C7 0x5BE1 #CJK UNIFIED IDEOGRAPH+0x89C8 0x79D1 #CJK UNIFIED IDEOGRAPH+0x89C9 0x6687 #CJK UNIFIED IDEOGRAPH+0x89CA 0x679C #CJK UNIFIED IDEOGRAPH+0x89CB 0x67B6 #CJK UNIFIED IDEOGRAPH+0x89CC 0x6B4C #CJK UNIFIED IDEOGRAPH+0x89CD 0x6CB3 #CJK UNIFIED IDEOGRAPH+0x89CE 0x706B #CJK UNIFIED IDEOGRAPH+0x89CF 0x73C2 #CJK UNIFIED IDEOGRAPH+0x89D0 0x798D #CJK UNIFIED IDEOGRAPH+0x89D1 0x79BE #CJK UNIFIED IDEOGRAPH+0x89D2 0x7A3C #CJK UNIFIED IDEOGRAPH+0x89D3 0x7B87 #CJK UNIFIED IDEOGRAPH+0x89D4 0x82B1 #CJK UNIFIED IDEOGRAPH+0x89D5 0x82DB #CJK UNIFIED IDEOGRAPH+0x89D6 0x8304 #CJK UNIFIED IDEOGRAPH+0x89D7 0x8377 #CJK UNIFIED IDEOGRAPH+0x89D8 0x83EF #CJK UNIFIED IDEOGRAPH+0x89D9 0x83D3 #CJK UNIFIED IDEOGRAPH+0x89DA 0x8766 #CJK UNIFIED IDEOGRAPH+0x89DB 0x8AB2 #CJK UNIFIED IDEOGRAPH+0x89DC 0x5629 #CJK UNIFIED IDEOGRAPH+0x89DD 0x8CA8 #CJK UNIFIED IDEOGRAPH+0x89DE 0x8FE6 #CJK UNIFIED IDEOGRAPH+0x89DF 0x904E #CJK UNIFIED IDEOGRAPH+0x89E0 0x971E #CJK UNIFIED IDEOGRAPH+0x89E1 0x868A #CJK UNIFIED IDEOGRAPH+0x89E2 0x4FC4 #CJK UNIFIED IDEOGRAPH+0x89E3 0x5CE8 #CJK UNIFIED IDEOGRAPH+0x89E4 0x6211 #CJK UNIFIED IDEOGRAPH+0x89E5 0x7259 #CJK UNIFIED IDEOGRAPH+0x89E6 0x753B #CJK UNIFIED IDEOGRAPH+0x89E7 0x81E5 #CJK UNIFIED IDEOGRAPH+0x89E8 0x82BD #CJK UNIFIED IDEOGRAPH+0x89E9 0x86FE #CJK UNIFIED IDEOGRAPH+0x89EA 0x8CC0 #CJK UNIFIED IDEOGRAPH+0x89EB 0x96C5 #CJK UNIFIED IDEOGRAPH+0x89EC 0x9913 #CJK UNIFIED IDEOGRAPH+0x89ED 0x99D5 #CJK UNIFIED IDEOGRAPH+0x89EE 0x4ECB #CJK UNIFIED IDEOGRAPH+0x89EF 0x4F1A #CJK UNIFIED IDEOGRAPH+0x89F0 0x89E3 #CJK UNIFIED IDEOGRAPH+0x89F1 0x56DE #CJK UNIFIED IDEOGRAPH+0x89F2 0x584A #CJK UNIFIED IDEOGRAPH+0x89F3 0x58CA #CJK UNIFIED IDEOGRAPH+0x89F4 0x5EFB #CJK UNIFIED IDEOGRAPH+0x89F5 0x5FEB #CJK UNIFIED IDEOGRAPH+0x89F6 0x602A #CJK UNIFIED IDEOGRAPH+0x89F7 0x6094 #CJK UNIFIED IDEOGRAPH+0x89F8 0x6062 #CJK UNIFIED IDEOGRAPH+0x89F9 0x61D0 #CJK UNIFIED IDEOGRAPH+0x89FA 0x6212 #CJK UNIFIED IDEOGRAPH+0x89FB 0x62D0 #CJK UNIFIED IDEOGRAPH+0x89FC 0x6539 #CJK UNIFIED IDEOGRAPH+0x8A40 0x9B41 #CJK UNIFIED IDEOGRAPH+0x8A41 0x6666 #CJK UNIFIED IDEOGRAPH+0x8A42 0x68B0 #CJK UNIFIED IDEOGRAPH+0x8A43 0x6D77 #CJK UNIFIED IDEOGRAPH+0x8A44 0x7070 #CJK UNIFIED IDEOGRAPH+0x8A45 0x754C #CJK UNIFIED IDEOGRAPH+0x8A46 0x7686 #CJK UNIFIED IDEOGRAPH+0x8A47 0x7D75 #CJK UNIFIED IDEOGRAPH+0x8A48 0x82A5 #CJK UNIFIED IDEOGRAPH+0x8A49 0x87F9 #CJK UNIFIED IDEOGRAPH+0x8A4A 0x958B #CJK UNIFIED IDEOGRAPH+0x8A4B 0x968E #CJK UNIFIED IDEOGRAPH+0x8A4C 0x8C9D #CJK UNIFIED IDEOGRAPH+0x8A4D 0x51F1 #CJK UNIFIED IDEOGRAPH+0x8A4E 0x52BE #CJK UNIFIED IDEOGRAPH+0x8A4F 0x5916 #CJK UNIFIED IDEOGRAPH+0x8A50 0x54B3 #CJK UNIFIED IDEOGRAPH+0x8A51 0x5BB3 #CJK UNIFIED IDEOGRAPH+0x8A52 0x5D16 #CJK UNIFIED IDEOGRAPH+0x8A53 0x6168 #CJK UNIFIED IDEOGRAPH+0x8A54 0x6982 #CJK UNIFIED IDEOGRAPH+0x8A55 0x6DAF #CJK UNIFIED IDEOGRAPH+0x8A56 0x788D #CJK UNIFIED IDEOGRAPH+0x8A57 0x84CB #CJK UNIFIED IDEOGRAPH+0x8A58 0x8857 #CJK UNIFIED IDEOGRAPH+0x8A59 0x8A72 #CJK UNIFIED IDEOGRAPH+0x8A5A 0x93A7 #CJK UNIFIED IDEOGRAPH+0x8A5B 0x9AB8 #CJK UNIFIED IDEOGRAPH+0x8A5C 0x6D6C #CJK UNIFIED IDEOGRAPH+0x8A5D 0x99A8 #CJK UNIFIED IDEOGRAPH+0x8A5E 0x86D9 #CJK UNIFIED IDEOGRAPH+0x8A5F 0x57A3 #CJK UNIFIED IDEOGRAPH+0x8A60 0x67FF #CJK UNIFIED IDEOGRAPH+0x8A61 0x86CE #CJK UNIFIED IDEOGRAPH+0x8A62 0x920E #CJK UNIFIED IDEOGRAPH+0x8A63 0x5283 #CJK UNIFIED IDEOGRAPH+0x8A64 0x5687 #CJK UNIFIED IDEOGRAPH+0x8A65 0x5404 #CJK UNIFIED IDEOGRAPH+0x8A66 0x5ED3 #CJK UNIFIED IDEOGRAPH+0x8A67 0x62E1 #CJK UNIFIED IDEOGRAPH+0x8A68 0x64B9 #CJK UNIFIED IDEOGRAPH+0x8A69 0x683C #CJK UNIFIED IDEOGRAPH+0x8A6A 0x6838 #CJK UNIFIED IDEOGRAPH+0x8A6B 0x6BBB #CJK UNIFIED IDEOGRAPH+0x8A6C 0x7372 #CJK UNIFIED IDEOGRAPH+0x8A6D 0x78BA #CJK UNIFIED IDEOGRAPH+0x8A6E 0x7A6B #CJK UNIFIED IDEOGRAPH+0x8A6F 0x899A #CJK UNIFIED IDEOGRAPH+0x8A70 0x89D2 #CJK UNIFIED IDEOGRAPH+0x8A71 0x8D6B #CJK UNIFIED IDEOGRAPH+0x8A72 0x8F03 #CJK UNIFIED IDEOGRAPH+0x8A73 0x90ED #CJK UNIFIED IDEOGRAPH+0x8A74 0x95A3 #CJK UNIFIED IDEOGRAPH+0x8A75 0x9694 #CJK UNIFIED IDEOGRAPH+0x8A76 0x9769 #CJK UNIFIED IDEOGRAPH+0x8A77 0x5B66 #CJK UNIFIED IDEOGRAPH+0x8A78 0x5CB3 #CJK UNIFIED IDEOGRAPH+0x8A79 0x697D #CJK UNIFIED IDEOGRAPH+0x8A7A 0x984D #CJK UNIFIED IDEOGRAPH+0x8A7B 0x984E #CJK UNIFIED IDEOGRAPH+0x8A7C 0x639B #CJK UNIFIED IDEOGRAPH+0x8A7D 0x7B20 #CJK UNIFIED IDEOGRAPH+0x8A7E 0x6A2B #CJK UNIFIED IDEOGRAPH+0x8A80 0x6A7F #CJK UNIFIED IDEOGRAPH+0x8A81 0x68B6 #CJK UNIFIED IDEOGRAPH+0x8A82 0x9C0D #CJK UNIFIED IDEOGRAPH+0x8A83 0x6F5F #CJK UNIFIED IDEOGRAPH+0x8A84 0x5272 #CJK UNIFIED IDEOGRAPH+0x8A85 0x559D #CJK UNIFIED IDEOGRAPH+0x8A86 0x6070 #CJK UNIFIED IDEOGRAPH+0x8A87 0x62EC #CJK UNIFIED IDEOGRAPH+0x8A88 0x6D3B #CJK UNIFIED IDEOGRAPH+0x8A89 0x6E07 #CJK UNIFIED IDEOGRAPH+0x8A8A 0x6ED1 #CJK UNIFIED IDEOGRAPH+0x8A8B 0x845B #CJK UNIFIED IDEOGRAPH+0x8A8C 0x8910 #CJK UNIFIED IDEOGRAPH+0x8A8D 0x8F44 #CJK UNIFIED IDEOGRAPH+0x8A8E 0x4E14 #CJK UNIFIED IDEOGRAPH+0x8A8F 0x9C39 #CJK UNIFIED IDEOGRAPH+0x8A90 0x53F6 #CJK UNIFIED IDEOGRAPH+0x8A91 0x691B #CJK UNIFIED IDEOGRAPH+0x8A92 0x6A3A #CJK UNIFIED IDEOGRAPH+0x8A93 0x9784 #CJK UNIFIED IDEOGRAPH+0x8A94 0x682A #CJK UNIFIED IDEOGRAPH+0x8A95 0x515C #CJK UNIFIED IDEOGRAPH+0x8A96 0x7AC3 #CJK UNIFIED IDEOGRAPH+0x8A97 0x84B2 #CJK UNIFIED IDEOGRAPH+0x8A98 0x91DC #CJK UNIFIED IDEOGRAPH+0x8A99 0x938C #CJK UNIFIED IDEOGRAPH+0x8A9A 0x565B #CJK UNIFIED IDEOGRAPH+0x8A9B 0x9D28 #CJK UNIFIED IDEOGRAPH+0x8A9C 0x6822 #CJK UNIFIED IDEOGRAPH+0x8A9D 0x8305 #CJK UNIFIED IDEOGRAPH+0x8A9E 0x8431 #CJK UNIFIED IDEOGRAPH+0x8A9F 0x7CA5 #CJK UNIFIED IDEOGRAPH+0x8AA0 0x5208 #CJK UNIFIED IDEOGRAPH+0x8AA1 0x82C5 #CJK UNIFIED IDEOGRAPH+0x8AA2 0x74E6 #CJK UNIFIED IDEOGRAPH+0x8AA3 0x4E7E #CJK UNIFIED IDEOGRAPH+0x8AA4 0x4F83 #CJK UNIFIED IDEOGRAPH+0x8AA5 0x51A0 #CJK UNIFIED IDEOGRAPH+0x8AA6 0x5BD2 #CJK UNIFIED IDEOGRAPH+0x8AA7 0x520A #CJK UNIFIED IDEOGRAPH+0x8AA8 0x52D8 #CJK UNIFIED IDEOGRAPH+0x8AA9 0x52E7 #CJK UNIFIED IDEOGRAPH+0x8AAA 0x5DFB #CJK UNIFIED IDEOGRAPH+0x8AAB 0x559A #CJK UNIFIED IDEOGRAPH+0x8AAC 0x582A #CJK UNIFIED IDEOGRAPH+0x8AAD 0x59E6 #CJK UNIFIED IDEOGRAPH+0x8AAE 0x5B8C #CJK UNIFIED IDEOGRAPH+0x8AAF 0x5B98 #CJK UNIFIED IDEOGRAPH+0x8AB0 0x5BDB #CJK UNIFIED IDEOGRAPH+0x8AB1 0x5E72 #CJK UNIFIED IDEOGRAPH+0x8AB2 0x5E79 #CJK UNIFIED IDEOGRAPH+0x8AB3 0x60A3 #CJK UNIFIED IDEOGRAPH+0x8AB4 0x611F #CJK UNIFIED IDEOGRAPH+0x8AB5 0x6163 #CJK UNIFIED IDEOGRAPH+0x8AB6 0x61BE #CJK UNIFIED IDEOGRAPH+0x8AB7 0x63DB #CJK UNIFIED IDEOGRAPH+0x8AB8 0x6562 #CJK UNIFIED IDEOGRAPH+0x8AB9 0x67D1 #CJK UNIFIED IDEOGRAPH+0x8ABA 0x6853 #CJK UNIFIED IDEOGRAPH+0x8ABB 0x68FA #CJK UNIFIED IDEOGRAPH+0x8ABC 0x6B3E #CJK UNIFIED IDEOGRAPH+0x8ABD 0x6B53 #CJK UNIFIED IDEOGRAPH+0x8ABE 0x6C57 #CJK UNIFIED IDEOGRAPH+0x8ABF 0x6F22 #CJK UNIFIED IDEOGRAPH+0x8AC0 0x6F97 #CJK UNIFIED IDEOGRAPH+0x8AC1 0x6F45 #CJK UNIFIED IDEOGRAPH+0x8AC2 0x74B0 #CJK UNIFIED IDEOGRAPH+0x8AC3 0x7518 #CJK UNIFIED IDEOGRAPH+0x8AC4 0x76E3 #CJK UNIFIED IDEOGRAPH+0x8AC5 0x770B #CJK UNIFIED IDEOGRAPH+0x8AC6 0x7AFF #CJK UNIFIED IDEOGRAPH+0x8AC7 0x7BA1 #CJK UNIFIED IDEOGRAPH+0x8AC8 0x7C21 #CJK UNIFIED IDEOGRAPH+0x8AC9 0x7DE9 #CJK UNIFIED IDEOGRAPH+0x8ACA 0x7F36 #CJK UNIFIED IDEOGRAPH+0x8ACB 0x7FF0 #CJK UNIFIED IDEOGRAPH+0x8ACC 0x809D #CJK UNIFIED IDEOGRAPH+0x8ACD 0x8266 #CJK UNIFIED IDEOGRAPH+0x8ACE 0x839E #CJK UNIFIED IDEOGRAPH+0x8ACF 0x89B3 #CJK UNIFIED IDEOGRAPH+0x8AD0 0x8ACC #CJK UNIFIED IDEOGRAPH+0x8AD1 0x8CAB #CJK UNIFIED IDEOGRAPH+0x8AD2 0x9084 #CJK UNIFIED IDEOGRAPH+0x8AD3 0x9451 #CJK UNIFIED IDEOGRAPH+0x8AD4 0x9593 #CJK UNIFIED IDEOGRAPH+0x8AD5 0x9591 #CJK UNIFIED IDEOGRAPH+0x8AD6 0x95A2 #CJK UNIFIED IDEOGRAPH+0x8AD7 0x9665 #CJK UNIFIED IDEOGRAPH+0x8AD8 0x97D3 #CJK UNIFIED IDEOGRAPH+0x8AD9 0x9928 #CJK UNIFIED IDEOGRAPH+0x8ADA 0x8218 #CJK UNIFIED IDEOGRAPH+0x8ADB 0x4E38 #CJK UNIFIED IDEOGRAPH+0x8ADC 0x542B #CJK UNIFIED IDEOGRAPH+0x8ADD 0x5CB8 #CJK UNIFIED IDEOGRAPH+0x8ADE 0x5DCC #CJK UNIFIED IDEOGRAPH+0x8ADF 0x73A9 #CJK UNIFIED IDEOGRAPH+0x8AE0 0x764C #CJK UNIFIED IDEOGRAPH+0x8AE1 0x773C #CJK UNIFIED IDEOGRAPH+0x8AE2 0x5CA9 #CJK UNIFIED IDEOGRAPH+0x8AE3 0x7FEB #CJK UNIFIED IDEOGRAPH+0x8AE4 0x8D0B #CJK UNIFIED IDEOGRAPH+0x8AE5 0x96C1 #CJK UNIFIED IDEOGRAPH+0x8AE6 0x9811 #CJK UNIFIED IDEOGRAPH+0x8AE7 0x9854 #CJK UNIFIED IDEOGRAPH+0x8AE8 0x9858 #CJK UNIFIED IDEOGRAPH+0x8AE9 0x4F01 #CJK UNIFIED IDEOGRAPH+0x8AEA 0x4F0E #CJK UNIFIED IDEOGRAPH+0x8AEB 0x5371 #CJK UNIFIED IDEOGRAPH+0x8AEC 0x559C #CJK UNIFIED IDEOGRAPH+0x8AED 0x5668 #CJK UNIFIED IDEOGRAPH+0x8AEE 0x57FA #CJK UNIFIED IDEOGRAPH+0x8AEF 0x5947 #CJK UNIFIED IDEOGRAPH+0x8AF0 0x5B09 #CJK UNIFIED IDEOGRAPH+0x8AF1 0x5BC4 #CJK UNIFIED IDEOGRAPH+0x8AF2 0x5C90 #CJK UNIFIED IDEOGRAPH+0x8AF3 0x5E0C #CJK UNIFIED IDEOGRAPH+0x8AF4 0x5E7E #CJK UNIFIED IDEOGRAPH+0x8AF5 0x5FCC #CJK UNIFIED IDEOGRAPH+0x8AF6 0x63EE #CJK UNIFIED IDEOGRAPH+0x8AF7 0x673A #CJK UNIFIED IDEOGRAPH+0x8AF8 0x65D7 #CJK UNIFIED IDEOGRAPH+0x8AF9 0x65E2 #CJK UNIFIED IDEOGRAPH+0x8AFA 0x671F #CJK UNIFIED IDEOGRAPH+0x8AFB 0x68CB #CJK UNIFIED IDEOGRAPH+0x8AFC 0x68C4 #CJK UNIFIED IDEOGRAPH+0x8B40 0x6A5F #CJK UNIFIED IDEOGRAPH+0x8B41 0x5E30 #CJK UNIFIED IDEOGRAPH+0x8B42 0x6BC5 #CJK UNIFIED IDEOGRAPH+0x8B43 0x6C17 #CJK UNIFIED IDEOGRAPH+0x8B44 0x6C7D #CJK UNIFIED IDEOGRAPH+0x8B45 0x757F #CJK UNIFIED IDEOGRAPH+0x8B46 0x7948 #CJK UNIFIED IDEOGRAPH+0x8B47 0x5B63 #CJK UNIFIED IDEOGRAPH+0x8B48 0x7A00 #CJK UNIFIED IDEOGRAPH+0x8B49 0x7D00 #CJK UNIFIED IDEOGRAPH+0x8B4A 0x5FBD #CJK UNIFIED IDEOGRAPH+0x8B4B 0x898F #CJK UNIFIED IDEOGRAPH+0x8B4C 0x8A18 #CJK UNIFIED IDEOGRAPH+0x8B4D 0x8CB4 #CJK UNIFIED IDEOGRAPH+0x8B4E 0x8D77 #CJK UNIFIED IDEOGRAPH+0x8B4F 0x8ECC #CJK UNIFIED IDEOGRAPH+0x8B50 0x8F1D #CJK UNIFIED IDEOGRAPH+0x8B51 0x98E2 #CJK UNIFIED IDEOGRAPH+0x8B52 0x9A0E #CJK UNIFIED IDEOGRAPH+0x8B53 0x9B3C #CJK UNIFIED IDEOGRAPH+0x8B54 0x4E80 #CJK UNIFIED IDEOGRAPH+0x8B55 0x507D #CJK UNIFIED IDEOGRAPH+0x8B56 0x5100 #CJK UNIFIED IDEOGRAPH+0x8B57 0x5993 #CJK UNIFIED IDEOGRAPH+0x8B58 0x5B9C #CJK UNIFIED IDEOGRAPH+0x8B59 0x622F #CJK UNIFIED IDEOGRAPH+0x8B5A 0x6280 #CJK UNIFIED IDEOGRAPH+0x8B5B 0x64EC #CJK UNIFIED IDEOGRAPH+0x8B5C 0x6B3A #CJK UNIFIED IDEOGRAPH+0x8B5D 0x72A0 #CJK UNIFIED IDEOGRAPH+0x8B5E 0x7591 #CJK UNIFIED IDEOGRAPH+0x8B5F 0x7947 #CJK UNIFIED IDEOGRAPH+0x8B60 0x7FA9 #CJK UNIFIED IDEOGRAPH+0x8B61 0x87FB #CJK UNIFIED IDEOGRAPH+0x8B62 0x8ABC #CJK UNIFIED IDEOGRAPH+0x8B63 0x8B70 #CJK UNIFIED IDEOGRAPH+0x8B64 0x63AC #CJK UNIFIED IDEOGRAPH+0x8B65 0x83CA #CJK UNIFIED IDEOGRAPH+0x8B66 0x97A0 #CJK UNIFIED IDEOGRAPH+0x8B67 0x5409 #CJK UNIFIED IDEOGRAPH+0x8B68 0x5403 #CJK UNIFIED IDEOGRAPH+0x8B69 0x55AB #CJK UNIFIED IDEOGRAPH+0x8B6A 0x6854 #CJK UNIFIED IDEOGRAPH+0x8B6B 0x6A58 #CJK UNIFIED IDEOGRAPH+0x8B6C 0x8A70 #CJK UNIFIED IDEOGRAPH+0x8B6D 0x7827 #CJK UNIFIED IDEOGRAPH+0x8B6E 0x6775 #CJK UNIFIED IDEOGRAPH+0x8B6F 0x9ECD #CJK UNIFIED IDEOGRAPH+0x8B70 0x5374 #CJK UNIFIED IDEOGRAPH+0x8B71 0x5BA2 #CJK UNIFIED IDEOGRAPH+0x8B72 0x811A #CJK UNIFIED IDEOGRAPH+0x8B73 0x8650 #CJK UNIFIED IDEOGRAPH+0x8B74 0x9006 #CJK UNIFIED IDEOGRAPH+0x8B75 0x4E18 #CJK UNIFIED IDEOGRAPH+0x8B76 0x4E45 #CJK UNIFIED IDEOGRAPH+0x8B77 0x4EC7 #CJK UNIFIED IDEOGRAPH+0x8B78 0x4F11 #CJK UNIFIED IDEOGRAPH+0x8B79 0x53CA #CJK UNIFIED IDEOGRAPH+0x8B7A 0x5438 #CJK UNIFIED IDEOGRAPH+0x8B7B 0x5BAE #CJK UNIFIED IDEOGRAPH+0x8B7C 0x5F13 #CJK UNIFIED IDEOGRAPH+0x8B7D 0x6025 #CJK UNIFIED IDEOGRAPH+0x8B7E 0x6551 #CJK UNIFIED IDEOGRAPH+0x8B80 0x673D #CJK UNIFIED IDEOGRAPH+0x8B81 0x6C42 #CJK UNIFIED IDEOGRAPH+0x8B82 0x6C72 #CJK UNIFIED IDEOGRAPH+0x8B83 0x6CE3 #CJK UNIFIED IDEOGRAPH+0x8B84 0x7078 #CJK UNIFIED IDEOGRAPH+0x8B85 0x7403 #CJK UNIFIED IDEOGRAPH+0x8B86 0x7A76 #CJK UNIFIED IDEOGRAPH+0x8B87 0x7AAE #CJK UNIFIED IDEOGRAPH+0x8B88 0x7B08 #CJK UNIFIED IDEOGRAPH+0x8B89 0x7D1A #CJK UNIFIED IDEOGRAPH+0x8B8A 0x7CFE #CJK UNIFIED IDEOGRAPH+0x8B8B 0x7D66 #CJK UNIFIED IDEOGRAPH+0x8B8C 0x65E7 #CJK UNIFIED IDEOGRAPH+0x8B8D 0x725B #CJK UNIFIED IDEOGRAPH+0x8B8E 0x53BB #CJK UNIFIED IDEOGRAPH+0x8B8F 0x5C45 #CJK UNIFIED IDEOGRAPH+0x8B90 0x5DE8 #CJK UNIFIED IDEOGRAPH+0x8B91 0x62D2 #CJK UNIFIED IDEOGRAPH+0x8B92 0x62E0 #CJK UNIFIED IDEOGRAPH+0x8B93 0x6319 #CJK UNIFIED IDEOGRAPH+0x8B94 0x6E20 #CJK UNIFIED IDEOGRAPH+0x8B95 0x865A #CJK UNIFIED IDEOGRAPH+0x8B96 0x8A31 #CJK UNIFIED IDEOGRAPH+0x8B97 0x8DDD #CJK UNIFIED IDEOGRAPH+0x8B98 0x92F8 #CJK UNIFIED IDEOGRAPH+0x8B99 0x6F01 #CJK UNIFIED IDEOGRAPH+0x8B9A 0x79A6 #CJK UNIFIED IDEOGRAPH+0x8B9B 0x9B5A #CJK UNIFIED IDEOGRAPH+0x8B9C 0x4EA8 #CJK UNIFIED IDEOGRAPH+0x8B9D 0x4EAB #CJK UNIFIED IDEOGRAPH+0x8B9E 0x4EAC #CJK UNIFIED IDEOGRAPH+0x8B9F 0x4F9B #CJK UNIFIED IDEOGRAPH+0x8BA0 0x4FA0 #CJK UNIFIED IDEOGRAPH+0x8BA1 0x50D1 #CJK UNIFIED IDEOGRAPH+0x8BA2 0x5147 #CJK UNIFIED IDEOGRAPH+0x8BA3 0x7AF6 #CJK UNIFIED IDEOGRAPH+0x8BA4 0x5171 #CJK UNIFIED IDEOGRAPH+0x8BA5 0x51F6 #CJK UNIFIED IDEOGRAPH+0x8BA6 0x5354 #CJK UNIFIED IDEOGRAPH+0x8BA7 0x5321 #CJK UNIFIED IDEOGRAPH+0x8BA8 0x537F #CJK UNIFIED IDEOGRAPH+0x8BA9 0x53EB #CJK UNIFIED IDEOGRAPH+0x8BAA 0x55AC #CJK UNIFIED IDEOGRAPH+0x8BAB 0x5883 #CJK UNIFIED IDEOGRAPH+0x8BAC 0x5CE1 #CJK UNIFIED IDEOGRAPH+0x8BAD 0x5F37 #CJK UNIFIED IDEOGRAPH+0x8BAE 0x5F4A #CJK UNIFIED IDEOGRAPH+0x8BAF 0x602F #CJK UNIFIED IDEOGRAPH+0x8BB0 0x6050 #CJK UNIFIED IDEOGRAPH+0x8BB1 0x606D #CJK UNIFIED IDEOGRAPH+0x8BB2 0x631F #CJK UNIFIED IDEOGRAPH+0x8BB3 0x6559 #CJK UNIFIED IDEOGRAPH+0x8BB4 0x6A4B #CJK UNIFIED IDEOGRAPH+0x8BB5 0x6CC1 #CJK UNIFIED IDEOGRAPH+0x8BB6 0x72C2 #CJK UNIFIED IDEOGRAPH+0x8BB7 0x72ED #CJK UNIFIED IDEOGRAPH+0x8BB8 0x77EF #CJK UNIFIED IDEOGRAPH+0x8BB9 0x80F8 #CJK UNIFIED IDEOGRAPH+0x8BBA 0x8105 #CJK UNIFIED IDEOGRAPH+0x8BBB 0x8208 #CJK UNIFIED IDEOGRAPH+0x8BBC 0x854E #CJK UNIFIED IDEOGRAPH+0x8BBD 0x90F7 #CJK UNIFIED IDEOGRAPH+0x8BBE 0x93E1 #CJK UNIFIED IDEOGRAPH+0x8BBF 0x97FF #CJK UNIFIED IDEOGRAPH+0x8BC0 0x9957 #CJK UNIFIED IDEOGRAPH+0x8BC1 0x9A5A #CJK UNIFIED IDEOGRAPH+0x8BC2 0x4EF0 #CJK UNIFIED IDEOGRAPH+0x8BC3 0x51DD #CJK UNIFIED IDEOGRAPH+0x8BC4 0x5C2D #CJK UNIFIED IDEOGRAPH+0x8BC5 0x6681 #CJK UNIFIED IDEOGRAPH+0x8BC6 0x696D #CJK UNIFIED IDEOGRAPH+0x8BC7 0x5C40 #CJK UNIFIED IDEOGRAPH+0x8BC8 0x66F2 #CJK UNIFIED IDEOGRAPH+0x8BC9 0x6975 #CJK UNIFIED IDEOGRAPH+0x8BCA 0x7389 #CJK UNIFIED IDEOGRAPH+0x8BCB 0x6850 #CJK UNIFIED IDEOGRAPH+0x8BCC 0x7C81 #CJK UNIFIED IDEOGRAPH+0x8BCD 0x50C5 #CJK UNIFIED IDEOGRAPH+0x8BCE 0x52E4 #CJK UNIFIED IDEOGRAPH+0x8BCF 0x5747 #CJK UNIFIED IDEOGRAPH+0x8BD0 0x5DFE #CJK UNIFIED IDEOGRAPH+0x8BD1 0x9326 #CJK UNIFIED IDEOGRAPH+0x8BD2 0x65A4 #CJK UNIFIED IDEOGRAPH+0x8BD3 0x6B23 #CJK UNIFIED IDEOGRAPH+0x8BD4 0x6B3D #CJK UNIFIED IDEOGRAPH+0x8BD5 0x7434 #CJK UNIFIED IDEOGRAPH+0x8BD6 0x7981 #CJK UNIFIED IDEOGRAPH+0x8BD7 0x79BD #CJK UNIFIED IDEOGRAPH+0x8BD8 0x7B4B #CJK UNIFIED IDEOGRAPH+0x8BD9 0x7DCA #CJK UNIFIED IDEOGRAPH+0x8BDA 0x82B9 #CJK UNIFIED IDEOGRAPH+0x8BDB 0x83CC #CJK UNIFIED IDEOGRAPH+0x8BDC 0x887F #CJK UNIFIED IDEOGRAPH+0x8BDD 0x895F #CJK UNIFIED IDEOGRAPH+0x8BDE 0x8B39 #CJK UNIFIED IDEOGRAPH+0x8BDF 0x8FD1 #CJK UNIFIED IDEOGRAPH+0x8BE0 0x91D1 #CJK UNIFIED IDEOGRAPH+0x8BE1 0x541F #CJK UNIFIED IDEOGRAPH+0x8BE2 0x9280 #CJK UNIFIED IDEOGRAPH+0x8BE3 0x4E5D #CJK UNIFIED IDEOGRAPH+0x8BE4 0x5036 #CJK UNIFIED IDEOGRAPH+0x8BE5 0x53E5 #CJK UNIFIED IDEOGRAPH+0x8BE6 0x533A #CJK UNIFIED IDEOGRAPH+0x8BE7 0x72D7 #CJK UNIFIED IDEOGRAPH+0x8BE8 0x7396 #CJK UNIFIED IDEOGRAPH+0x8BE9 0x77E9 #CJK UNIFIED IDEOGRAPH+0x8BEA 0x82E6 #CJK UNIFIED IDEOGRAPH+0x8BEB 0x8EAF #CJK UNIFIED IDEOGRAPH+0x8BEC 0x99C6 #CJK UNIFIED IDEOGRAPH+0x8BED 0x99C8 #CJK UNIFIED IDEOGRAPH+0x8BEE 0x99D2 #CJK UNIFIED IDEOGRAPH+0x8BEF 0x5177 #CJK UNIFIED IDEOGRAPH+0x8BF0 0x611A #CJK UNIFIED IDEOGRAPH+0x8BF1 0x865E #CJK UNIFIED IDEOGRAPH+0x8BF2 0x55B0 #CJK UNIFIED IDEOGRAPH+0x8BF3 0x7A7A #CJK UNIFIED IDEOGRAPH+0x8BF4 0x5076 #CJK UNIFIED IDEOGRAPH+0x8BF5 0x5BD3 #CJK UNIFIED IDEOGRAPH+0x8BF6 0x9047 #CJK UNIFIED IDEOGRAPH+0x8BF7 0x9685 #CJK UNIFIED IDEOGRAPH+0x8BF8 0x4E32 #CJK UNIFIED IDEOGRAPH+0x8BF9 0x6ADB #CJK UNIFIED IDEOGRAPH+0x8BFA 0x91E7 #CJK UNIFIED IDEOGRAPH+0x8BFB 0x5C51 #CJK UNIFIED IDEOGRAPH+0x8BFC 0x5C48 #CJK UNIFIED IDEOGRAPH+0x8C40 0x6398 #CJK UNIFIED IDEOGRAPH+0x8C41 0x7A9F #CJK UNIFIED IDEOGRAPH+0x8C42 0x6C93 #CJK UNIFIED IDEOGRAPH+0x8C43 0x9774 #CJK UNIFIED IDEOGRAPH+0x8C44 0x8F61 #CJK UNIFIED IDEOGRAPH+0x8C45 0x7AAA #CJK UNIFIED IDEOGRAPH+0x8C46 0x718A #CJK UNIFIED IDEOGRAPH+0x8C47 0x9688 #CJK UNIFIED IDEOGRAPH+0x8C48 0x7C82 #CJK UNIFIED IDEOGRAPH+0x8C49 0x6817 #CJK UNIFIED IDEOGRAPH+0x8C4A 0x7E70 #CJK UNIFIED IDEOGRAPH+0x8C4B 0x6851 #CJK UNIFIED IDEOGRAPH+0x8C4C 0x936C #CJK UNIFIED IDEOGRAPH+0x8C4D 0x52F2 #CJK UNIFIED IDEOGRAPH+0x8C4E 0x541B #CJK UNIFIED IDEOGRAPH+0x8C4F 0x85AB #CJK UNIFIED IDEOGRAPH+0x8C50 0x8A13 #CJK UNIFIED IDEOGRAPH+0x8C51 0x7FA4 #CJK UNIFIED IDEOGRAPH+0x8C52 0x8ECD #CJK UNIFIED IDEOGRAPH+0x8C53 0x90E1 #CJK UNIFIED IDEOGRAPH+0x8C54 0x5366 #CJK UNIFIED IDEOGRAPH+0x8C55 0x8888 #CJK UNIFIED IDEOGRAPH+0x8C56 0x7941 #CJK UNIFIED IDEOGRAPH+0x8C57 0x4FC2 #CJK UNIFIED IDEOGRAPH+0x8C58 0x50BE #CJK UNIFIED IDEOGRAPH+0x8C59 0x5211 #CJK UNIFIED IDEOGRAPH+0x8C5A 0x5144 #CJK UNIFIED IDEOGRAPH+0x8C5B 0x5553 #CJK UNIFIED IDEOGRAPH+0x8C5C 0x572D #CJK UNIFIED IDEOGRAPH+0x8C5D 0x73EA #CJK UNIFIED IDEOGRAPH+0x8C5E 0x578B #CJK UNIFIED IDEOGRAPH+0x8C5F 0x5951 #CJK UNIFIED IDEOGRAPH+0x8C60 0x5F62 #CJK UNIFIED IDEOGRAPH+0x8C61 0x5F84 #CJK UNIFIED IDEOGRAPH+0x8C62 0x6075 #CJK UNIFIED IDEOGRAPH+0x8C63 0x6176 #CJK UNIFIED IDEOGRAPH+0x8C64 0x6167 #CJK UNIFIED IDEOGRAPH+0x8C65 0x61A9 #CJK UNIFIED IDEOGRAPH+0x8C66 0x63B2 #CJK UNIFIED IDEOGRAPH+0x8C67 0x643A #CJK UNIFIED IDEOGRAPH+0x8C68 0x656C #CJK UNIFIED IDEOGRAPH+0x8C69 0x666F #CJK UNIFIED IDEOGRAPH+0x8C6A 0x6842 #CJK UNIFIED IDEOGRAPH+0x8C6B 0x6E13 #CJK UNIFIED IDEOGRAPH+0x8C6C 0x7566 #CJK UNIFIED IDEOGRAPH+0x8C6D 0x7A3D #CJK UNIFIED IDEOGRAPH+0x8C6E 0x7CFB #CJK UNIFIED IDEOGRAPH+0x8C6F 0x7D4C #CJK UNIFIED IDEOGRAPH+0x8C70 0x7D99 #CJK UNIFIED IDEOGRAPH+0x8C71 0x7E4B #CJK UNIFIED IDEOGRAPH+0x8C72 0x7F6B #CJK UNIFIED IDEOGRAPH+0x8C73 0x830E #CJK UNIFIED IDEOGRAPH+0x8C74 0x834A #CJK UNIFIED IDEOGRAPH+0x8C75 0x86CD #CJK UNIFIED IDEOGRAPH+0x8C76 0x8A08 #CJK UNIFIED IDEOGRAPH+0x8C77 0x8A63 #CJK UNIFIED IDEOGRAPH+0x8C78 0x8B66 #CJK UNIFIED IDEOGRAPH+0x8C79 0x8EFD #CJK UNIFIED IDEOGRAPH+0x8C7A 0x981A #CJK UNIFIED IDEOGRAPH+0x8C7B 0x9D8F #CJK UNIFIED IDEOGRAPH+0x8C7C 0x82B8 #CJK UNIFIED IDEOGRAPH+0x8C7D 0x8FCE #CJK UNIFIED IDEOGRAPH+0x8C7E 0x9BE8 #CJK UNIFIED IDEOGRAPH+0x8C80 0x5287 #CJK UNIFIED IDEOGRAPH+0x8C81 0x621F #CJK UNIFIED IDEOGRAPH+0x8C82 0x6483 #CJK UNIFIED IDEOGRAPH+0x8C83 0x6FC0 #CJK UNIFIED IDEOGRAPH+0x8C84 0x9699 #CJK UNIFIED IDEOGRAPH+0x8C85 0x6841 #CJK UNIFIED IDEOGRAPH+0x8C86 0x5091 #CJK UNIFIED IDEOGRAPH+0x8C87 0x6B20 #CJK UNIFIED IDEOGRAPH+0x8C88 0x6C7A #CJK UNIFIED IDEOGRAPH+0x8C89 0x6F54 #CJK UNIFIED IDEOGRAPH+0x8C8A 0x7A74 #CJK UNIFIED IDEOGRAPH+0x8C8B 0x7D50 #CJK UNIFIED IDEOGRAPH+0x8C8C 0x8840 #CJK UNIFIED IDEOGRAPH+0x8C8D 0x8A23 #CJK UNIFIED IDEOGRAPH+0x8C8E 0x6708 #CJK UNIFIED IDEOGRAPH+0x8C8F 0x4EF6 #CJK UNIFIED IDEOGRAPH+0x8C90 0x5039 #CJK UNIFIED IDEOGRAPH+0x8C91 0x5026 #CJK UNIFIED IDEOGRAPH+0x8C92 0x5065 #CJK UNIFIED IDEOGRAPH+0x8C93 0x517C #CJK UNIFIED IDEOGRAPH+0x8C94 0x5238 #CJK UNIFIED IDEOGRAPH+0x8C95 0x5263 #CJK UNIFIED IDEOGRAPH+0x8C96 0x55A7 #CJK UNIFIED IDEOGRAPH+0x8C97 0x570F #CJK UNIFIED IDEOGRAPH+0x8C98 0x5805 #CJK UNIFIED IDEOGRAPH+0x8C99 0x5ACC #CJK UNIFIED IDEOGRAPH+0x8C9A 0x5EFA #CJK UNIFIED IDEOGRAPH+0x8C9B 0x61B2 #CJK UNIFIED IDEOGRAPH+0x8C9C 0x61F8 #CJK UNIFIED IDEOGRAPH+0x8C9D 0x62F3 #CJK UNIFIED IDEOGRAPH+0x8C9E 0x6372 #CJK UNIFIED IDEOGRAPH+0x8C9F 0x691C #CJK UNIFIED IDEOGRAPH+0x8CA0 0x6A29 #CJK UNIFIED IDEOGRAPH+0x8CA1 0x727D #CJK UNIFIED IDEOGRAPH+0x8CA2 0x72AC #CJK UNIFIED IDEOGRAPH+0x8CA3 0x732E #CJK UNIFIED IDEOGRAPH+0x8CA4 0x7814 #CJK UNIFIED IDEOGRAPH+0x8CA5 0x786F #CJK UNIFIED IDEOGRAPH+0x8CA6 0x7D79 #CJK UNIFIED IDEOGRAPH+0x8CA7 0x770C #CJK UNIFIED IDEOGRAPH+0x8CA8 0x80A9 #CJK UNIFIED IDEOGRAPH+0x8CA9 0x898B #CJK UNIFIED IDEOGRAPH+0x8CAA 0x8B19 #CJK UNIFIED IDEOGRAPH+0x8CAB 0x8CE2 #CJK UNIFIED IDEOGRAPH+0x8CAC 0x8ED2 #CJK UNIFIED IDEOGRAPH+0x8CAD 0x9063 #CJK UNIFIED IDEOGRAPH+0x8CAE 0x9375 #CJK UNIFIED IDEOGRAPH+0x8CAF 0x967A #CJK UNIFIED IDEOGRAPH+0x8CB0 0x9855 #CJK UNIFIED IDEOGRAPH+0x8CB1 0x9A13 #CJK UNIFIED IDEOGRAPH+0x8CB2 0x9E78 #CJK UNIFIED IDEOGRAPH+0x8CB3 0x5143 #CJK UNIFIED IDEOGRAPH+0x8CB4 0x539F #CJK UNIFIED IDEOGRAPH+0x8CB5 0x53B3 #CJK UNIFIED IDEOGRAPH+0x8CB6 0x5E7B #CJK UNIFIED IDEOGRAPH+0x8CB7 0x5F26 #CJK UNIFIED IDEOGRAPH+0x8CB8 0x6E1B #CJK UNIFIED IDEOGRAPH+0x8CB9 0x6E90 #CJK UNIFIED IDEOGRAPH+0x8CBA 0x7384 #CJK UNIFIED IDEOGRAPH+0x8CBB 0x73FE #CJK UNIFIED IDEOGRAPH+0x8CBC 0x7D43 #CJK UNIFIED IDEOGRAPH+0x8CBD 0x8237 #CJK UNIFIED IDEOGRAPH+0x8CBE 0x8A00 #CJK UNIFIED IDEOGRAPH+0x8CBF 0x8AFA #CJK UNIFIED IDEOGRAPH+0x8CC0 0x9650 #CJK UNIFIED IDEOGRAPH+0x8CC1 0x4E4E #CJK UNIFIED IDEOGRAPH+0x8CC2 0x500B #CJK UNIFIED IDEOGRAPH+0x8CC3 0x53E4 #CJK UNIFIED IDEOGRAPH+0x8CC4 0x547C #CJK UNIFIED IDEOGRAPH+0x8CC5 0x56FA #CJK UNIFIED IDEOGRAPH+0x8CC6 0x59D1 #CJK UNIFIED IDEOGRAPH+0x8CC7 0x5B64 #CJK UNIFIED IDEOGRAPH+0x8CC8 0x5DF1 #CJK UNIFIED IDEOGRAPH+0x8CC9 0x5EAB #CJK UNIFIED IDEOGRAPH+0x8CCA 0x5F27 #CJK UNIFIED IDEOGRAPH+0x8CCB 0x6238 #CJK UNIFIED IDEOGRAPH+0x8CCC 0x6545 #CJK UNIFIED IDEOGRAPH+0x8CCD 0x67AF #CJK UNIFIED IDEOGRAPH+0x8CCE 0x6E56 #CJK UNIFIED IDEOGRAPH+0x8CCF 0x72D0 #CJK UNIFIED IDEOGRAPH+0x8CD0 0x7CCA #CJK UNIFIED IDEOGRAPH+0x8CD1 0x88B4 #CJK UNIFIED IDEOGRAPH+0x8CD2 0x80A1 #CJK UNIFIED IDEOGRAPH+0x8CD3 0x80E1 #CJK UNIFIED IDEOGRAPH+0x8CD4 0x83F0 #CJK UNIFIED IDEOGRAPH+0x8CD5 0x864E #CJK UNIFIED IDEOGRAPH+0x8CD6 0x8A87 #CJK UNIFIED IDEOGRAPH+0x8CD7 0x8DE8 #CJK UNIFIED IDEOGRAPH+0x8CD8 0x9237 #CJK UNIFIED IDEOGRAPH+0x8CD9 0x96C7 #CJK UNIFIED IDEOGRAPH+0x8CDA 0x9867 #CJK UNIFIED IDEOGRAPH+0x8CDB 0x9F13 #CJK UNIFIED IDEOGRAPH+0x8CDC 0x4E94 #CJK UNIFIED IDEOGRAPH+0x8CDD 0x4E92 #CJK UNIFIED IDEOGRAPH+0x8CDE 0x4F0D #CJK UNIFIED IDEOGRAPH+0x8CDF 0x5348 #CJK UNIFIED IDEOGRAPH+0x8CE0 0x5449 #CJK UNIFIED IDEOGRAPH+0x8CE1 0x543E #CJK UNIFIED IDEOGRAPH+0x8CE2 0x5A2F #CJK UNIFIED IDEOGRAPH+0x8CE3 0x5F8C #CJK UNIFIED IDEOGRAPH+0x8CE4 0x5FA1 #CJK UNIFIED IDEOGRAPH+0x8CE5 0x609F #CJK UNIFIED IDEOGRAPH+0x8CE6 0x68A7 #CJK UNIFIED IDEOGRAPH+0x8CE7 0x6A8E #CJK UNIFIED IDEOGRAPH+0x8CE8 0x745A #CJK UNIFIED IDEOGRAPH+0x8CE9 0x7881 #CJK UNIFIED IDEOGRAPH+0x8CEA 0x8A9E #CJK UNIFIED IDEOGRAPH+0x8CEB 0x8AA4 #CJK UNIFIED IDEOGRAPH+0x8CEC 0x8B77 #CJK UNIFIED IDEOGRAPH+0x8CED 0x9190 #CJK UNIFIED IDEOGRAPH+0x8CEE 0x4E5E #CJK UNIFIED IDEOGRAPH+0x8CEF 0x9BC9 #CJK UNIFIED IDEOGRAPH+0x8CF0 0x4EA4 #CJK UNIFIED IDEOGRAPH+0x8CF1 0x4F7C #CJK UNIFIED IDEOGRAPH+0x8CF2 0x4FAF #CJK UNIFIED IDEOGRAPH+0x8CF3 0x5019 #CJK UNIFIED IDEOGRAPH+0x8CF4 0x5016 #CJK UNIFIED IDEOGRAPH+0x8CF5 0x5149 #CJK UNIFIED IDEOGRAPH+0x8CF6 0x516C #CJK UNIFIED IDEOGRAPH+0x8CF7 0x529F #CJK UNIFIED IDEOGRAPH+0x8CF8 0x52B9 #CJK UNIFIED IDEOGRAPH+0x8CF9 0x52FE #CJK UNIFIED IDEOGRAPH+0x8CFA 0x539A #CJK UNIFIED IDEOGRAPH+0x8CFB 0x53E3 #CJK UNIFIED IDEOGRAPH+0x8CFC 0x5411 #CJK UNIFIED IDEOGRAPH+0x8D40 0x540E #CJK UNIFIED IDEOGRAPH+0x8D41 0x5589 #CJK UNIFIED IDEOGRAPH+0x8D42 0x5751 #CJK UNIFIED IDEOGRAPH+0x8D43 0x57A2 #CJK UNIFIED IDEOGRAPH+0x8D44 0x597D #CJK UNIFIED IDEOGRAPH+0x8D45 0x5B54 #CJK UNIFIED IDEOGRAPH+0x8D46 0x5B5D #CJK UNIFIED IDEOGRAPH+0x8D47 0x5B8F #CJK UNIFIED IDEOGRAPH+0x8D48 0x5DE5 #CJK UNIFIED IDEOGRAPH+0x8D49 0x5DE7 #CJK UNIFIED IDEOGRAPH+0x8D4A 0x5DF7 #CJK UNIFIED IDEOGRAPH+0x8D4B 0x5E78 #CJK UNIFIED IDEOGRAPH+0x8D4C 0x5E83 #CJK UNIFIED IDEOGRAPH+0x8D4D 0x5E9A #CJK UNIFIED IDEOGRAPH+0x8D4E 0x5EB7 #CJK UNIFIED IDEOGRAPH+0x8D4F 0x5F18 #CJK UNIFIED IDEOGRAPH+0x8D50 0x6052 #CJK UNIFIED IDEOGRAPH+0x8D51 0x614C #CJK UNIFIED IDEOGRAPH+0x8D52 0x6297 #CJK UNIFIED IDEOGRAPH+0x8D53 0x62D8 #CJK UNIFIED IDEOGRAPH+0x8D54 0x63A7 #CJK UNIFIED IDEOGRAPH+0x8D55 0x653B #CJK UNIFIED IDEOGRAPH+0x8D56 0x6602 #CJK UNIFIED IDEOGRAPH+0x8D57 0x6643 #CJK UNIFIED IDEOGRAPH+0x8D58 0x66F4 #CJK UNIFIED IDEOGRAPH+0x8D59 0x676D #CJK UNIFIED IDEOGRAPH+0x8D5A 0x6821 #CJK UNIFIED IDEOGRAPH+0x8D5B 0x6897 #CJK UNIFIED IDEOGRAPH+0x8D5C 0x69CB #CJK UNIFIED IDEOGRAPH+0x8D5D 0x6C5F #CJK UNIFIED IDEOGRAPH+0x8D5E 0x6D2A #CJK UNIFIED IDEOGRAPH+0x8D5F 0x6D69 #CJK UNIFIED IDEOGRAPH+0x8D60 0x6E2F #CJK UNIFIED IDEOGRAPH+0x8D61 0x6E9D #CJK UNIFIED IDEOGRAPH+0x8D62 0x7532 #CJK UNIFIED IDEOGRAPH+0x8D63 0x7687 #CJK UNIFIED IDEOGRAPH+0x8D64 0x786C #CJK UNIFIED IDEOGRAPH+0x8D65 0x7A3F #CJK UNIFIED IDEOGRAPH+0x8D66 0x7CE0 #CJK UNIFIED IDEOGRAPH+0x8D67 0x7D05 #CJK UNIFIED IDEOGRAPH+0x8D68 0x7D18 #CJK UNIFIED IDEOGRAPH+0x8D69 0x7D5E #CJK UNIFIED IDEOGRAPH+0x8D6A 0x7DB1 #CJK UNIFIED IDEOGRAPH+0x8D6B 0x8015 #CJK UNIFIED IDEOGRAPH+0x8D6C 0x8003 #CJK UNIFIED IDEOGRAPH+0x8D6D 0x80AF #CJK UNIFIED IDEOGRAPH+0x8D6E 0x80B1 #CJK UNIFIED IDEOGRAPH+0x8D6F 0x8154 #CJK UNIFIED IDEOGRAPH+0x8D70 0x818F #CJK UNIFIED IDEOGRAPH+0x8D71 0x822A #CJK UNIFIED IDEOGRAPH+0x8D72 0x8352 #CJK UNIFIED IDEOGRAPH+0x8D73 0x884C #CJK UNIFIED IDEOGRAPH+0x8D74 0x8861 #CJK UNIFIED IDEOGRAPH+0x8D75 0x8B1B #CJK UNIFIED IDEOGRAPH+0x8D76 0x8CA2 #CJK UNIFIED IDEOGRAPH+0x8D77 0x8CFC #CJK UNIFIED IDEOGRAPH+0x8D78 0x90CA #CJK UNIFIED IDEOGRAPH+0x8D79 0x9175 #CJK UNIFIED IDEOGRAPH+0x8D7A 0x9271 #CJK UNIFIED IDEOGRAPH+0x8D7B 0x783F #CJK UNIFIED IDEOGRAPH+0x8D7C 0x92FC #CJK UNIFIED IDEOGRAPH+0x8D7D 0x95A4 #CJK UNIFIED IDEOGRAPH+0x8D7E 0x964D #CJK UNIFIED IDEOGRAPH+0x8D80 0x9805 #CJK UNIFIED IDEOGRAPH+0x8D81 0x9999 #CJK UNIFIED IDEOGRAPH+0x8D82 0x9AD8 #CJK UNIFIED IDEOGRAPH+0x8D83 0x9D3B #CJK UNIFIED IDEOGRAPH+0x8D84 0x525B #CJK UNIFIED IDEOGRAPH+0x8D85 0x52AB #CJK UNIFIED IDEOGRAPH+0x8D86 0x53F7 #CJK UNIFIED IDEOGRAPH+0x8D87 0x5408 #CJK UNIFIED IDEOGRAPH+0x8D88 0x58D5 #CJK UNIFIED IDEOGRAPH+0x8D89 0x62F7 #CJK UNIFIED IDEOGRAPH+0x8D8A 0x6FE0 #CJK UNIFIED IDEOGRAPH+0x8D8B 0x8C6A #CJK UNIFIED IDEOGRAPH+0x8D8C 0x8F5F #CJK UNIFIED IDEOGRAPH+0x8D8D 0x9EB9 #CJK UNIFIED IDEOGRAPH+0x8D8E 0x514B #CJK UNIFIED IDEOGRAPH+0x8D8F 0x523B #CJK UNIFIED IDEOGRAPH+0x8D90 0x544A #CJK UNIFIED IDEOGRAPH+0x8D91 0x56FD #CJK UNIFIED IDEOGRAPH+0x8D92 0x7A40 #CJK UNIFIED IDEOGRAPH+0x8D93 0x9177 #CJK UNIFIED IDEOGRAPH+0x8D94 0x9D60 #CJK UNIFIED IDEOGRAPH+0x8D95 0x9ED2 #CJK UNIFIED IDEOGRAPH+0x8D96 0x7344 #CJK UNIFIED IDEOGRAPH+0x8D97 0x6F09 #CJK UNIFIED IDEOGRAPH+0x8D98 0x8170 #CJK UNIFIED IDEOGRAPH+0x8D99 0x7511 #CJK UNIFIED IDEOGRAPH+0x8D9A 0x5FFD #CJK UNIFIED IDEOGRAPH+0x8D9B 0x60DA #CJK UNIFIED IDEOGRAPH+0x8D9C 0x9AA8 #CJK UNIFIED IDEOGRAPH+0x8D9D 0x72DB #CJK UNIFIED IDEOGRAPH+0x8D9E 0x8FBC #CJK UNIFIED IDEOGRAPH+0x8D9F 0x6B64 #CJK UNIFIED IDEOGRAPH+0x8DA0 0x9803 #CJK UNIFIED IDEOGRAPH+0x8DA1 0x4ECA #CJK UNIFIED IDEOGRAPH+0x8DA2 0x56F0 #CJK UNIFIED IDEOGRAPH+0x8DA3 0x5764 #CJK UNIFIED IDEOGRAPH+0x8DA4 0x58BE #CJK UNIFIED IDEOGRAPH+0x8DA5 0x5A5A #CJK UNIFIED IDEOGRAPH+0x8DA6 0x6068 #CJK UNIFIED IDEOGRAPH+0x8DA7 0x61C7 #CJK UNIFIED IDEOGRAPH+0x8DA8 0x660F #CJK UNIFIED IDEOGRAPH+0x8DA9 0x6606 #CJK UNIFIED IDEOGRAPH+0x8DAA 0x6839 #CJK UNIFIED IDEOGRAPH+0x8DAB 0x68B1 #CJK UNIFIED IDEOGRAPH+0x8DAC 0x6DF7 #CJK UNIFIED IDEOGRAPH+0x8DAD 0x75D5 #CJK UNIFIED IDEOGRAPH+0x8DAE 0x7D3A #CJK UNIFIED IDEOGRAPH+0x8DAF 0x826E #CJK UNIFIED IDEOGRAPH+0x8DB0 0x9B42 #CJK UNIFIED IDEOGRAPH+0x8DB1 0x4E9B #CJK UNIFIED IDEOGRAPH+0x8DB2 0x4F50 #CJK UNIFIED IDEOGRAPH+0x8DB3 0x53C9 #CJK UNIFIED IDEOGRAPH+0x8DB4 0x5506 #CJK UNIFIED IDEOGRAPH+0x8DB5 0x5D6F #CJK UNIFIED IDEOGRAPH+0x8DB6 0x5DE6 #CJK UNIFIED IDEOGRAPH+0x8DB7 0x5DEE #CJK UNIFIED IDEOGRAPH+0x8DB8 0x67FB #CJK UNIFIED IDEOGRAPH+0x8DB9 0x6C99 #CJK UNIFIED IDEOGRAPH+0x8DBA 0x7473 #CJK UNIFIED IDEOGRAPH+0x8DBB 0x7802 #CJK UNIFIED IDEOGRAPH+0x8DBC 0x8A50 #CJK UNIFIED IDEOGRAPH+0x8DBD 0x9396 #CJK UNIFIED IDEOGRAPH+0x8DBE 0x88DF #CJK UNIFIED IDEOGRAPH+0x8DBF 0x5750 #CJK UNIFIED IDEOGRAPH+0x8DC0 0x5EA7 #CJK UNIFIED IDEOGRAPH+0x8DC1 0x632B #CJK UNIFIED IDEOGRAPH+0x8DC2 0x50B5 #CJK UNIFIED IDEOGRAPH+0x8DC3 0x50AC #CJK UNIFIED IDEOGRAPH+0x8DC4 0x518D #CJK UNIFIED IDEOGRAPH+0x8DC5 0x6700 #CJK UNIFIED IDEOGRAPH+0x8DC6 0x54C9 #CJK UNIFIED IDEOGRAPH+0x8DC7 0x585E #CJK UNIFIED IDEOGRAPH+0x8DC8 0x59BB #CJK UNIFIED IDEOGRAPH+0x8DC9 0x5BB0 #CJK UNIFIED IDEOGRAPH+0x8DCA 0x5F69 #CJK UNIFIED IDEOGRAPH+0x8DCB 0x624D #CJK UNIFIED IDEOGRAPH+0x8DCC 0x63A1 #CJK UNIFIED IDEOGRAPH+0x8DCD 0x683D #CJK UNIFIED IDEOGRAPH+0x8DCE 0x6B73 #CJK UNIFIED IDEOGRAPH+0x8DCF 0x6E08 #CJK UNIFIED IDEOGRAPH+0x8DD0 0x707D #CJK UNIFIED IDEOGRAPH+0x8DD1 0x91C7 #CJK UNIFIED IDEOGRAPH+0x8DD2 0x7280 #CJK UNIFIED IDEOGRAPH+0x8DD3 0x7815 #CJK UNIFIED IDEOGRAPH+0x8DD4 0x7826 #CJK UNIFIED IDEOGRAPH+0x8DD5 0x796D #CJK UNIFIED IDEOGRAPH+0x8DD6 0x658E #CJK UNIFIED IDEOGRAPH+0x8DD7 0x7D30 #CJK UNIFIED IDEOGRAPH+0x8DD8 0x83DC #CJK UNIFIED IDEOGRAPH+0x8DD9 0x88C1 #CJK UNIFIED IDEOGRAPH+0x8DDA 0x8F09 #CJK UNIFIED IDEOGRAPH+0x8DDB 0x969B #CJK UNIFIED IDEOGRAPH+0x8DDC 0x5264 #CJK UNIFIED IDEOGRAPH+0x8DDD 0x5728 #CJK UNIFIED IDEOGRAPH+0x8DDE 0x6750 #CJK UNIFIED IDEOGRAPH+0x8DDF 0x7F6A #CJK UNIFIED IDEOGRAPH+0x8DE0 0x8CA1 #CJK UNIFIED IDEOGRAPH+0x8DE1 0x51B4 #CJK UNIFIED IDEOGRAPH+0x8DE2 0x5742 #CJK UNIFIED IDEOGRAPH+0x8DE3 0x962A #CJK UNIFIED IDEOGRAPH+0x8DE4 0x583A #CJK UNIFIED IDEOGRAPH+0x8DE5 0x698A #CJK UNIFIED IDEOGRAPH+0x8DE6 0x80B4 #CJK UNIFIED IDEOGRAPH+0x8DE7 0x54B2 #CJK UNIFIED IDEOGRAPH+0x8DE8 0x5D0E #CJK UNIFIED IDEOGRAPH+0x8DE9 0x57FC #CJK UNIFIED IDEOGRAPH+0x8DEA 0x7895 #CJK UNIFIED IDEOGRAPH+0x8DEB 0x9DFA #CJK UNIFIED IDEOGRAPH+0x8DEC 0x4F5C #CJK UNIFIED IDEOGRAPH+0x8DED 0x524A #CJK UNIFIED IDEOGRAPH+0x8DEE 0x548B #CJK UNIFIED IDEOGRAPH+0x8DEF 0x643E #CJK UNIFIED IDEOGRAPH+0x8DF0 0x6628 #CJK UNIFIED IDEOGRAPH+0x8DF1 0x6714 #CJK UNIFIED IDEOGRAPH+0x8DF2 0x67F5 #CJK UNIFIED IDEOGRAPH+0x8DF3 0x7A84 #CJK UNIFIED IDEOGRAPH+0x8DF4 0x7B56 #CJK UNIFIED IDEOGRAPH+0x8DF5 0x7D22 #CJK UNIFIED IDEOGRAPH+0x8DF6 0x932F #CJK UNIFIED IDEOGRAPH+0x8DF7 0x685C #CJK UNIFIED IDEOGRAPH+0x8DF8 0x9BAD #CJK UNIFIED IDEOGRAPH+0x8DF9 0x7B39 #CJK UNIFIED IDEOGRAPH+0x8DFA 0x5319 #CJK UNIFIED IDEOGRAPH+0x8DFB 0x518A #CJK UNIFIED IDEOGRAPH+0x8DFC 0x5237 #CJK UNIFIED IDEOGRAPH+0x8E40 0x5BDF #CJK UNIFIED IDEOGRAPH+0x8E41 0x62F6 #CJK UNIFIED IDEOGRAPH+0x8E42 0x64AE #CJK UNIFIED IDEOGRAPH+0x8E43 0x64E6 #CJK UNIFIED IDEOGRAPH+0x8E44 0x672D #CJK UNIFIED IDEOGRAPH+0x8E45 0x6BBA #CJK UNIFIED IDEOGRAPH+0x8E46 0x85A9 #CJK UNIFIED IDEOGRAPH+0x8E47 0x96D1 #CJK UNIFIED IDEOGRAPH+0x8E48 0x7690 #CJK UNIFIED IDEOGRAPH+0x8E49 0x9BD6 #CJK UNIFIED IDEOGRAPH+0x8E4A 0x634C #CJK UNIFIED IDEOGRAPH+0x8E4B 0x9306 #CJK UNIFIED IDEOGRAPH+0x8E4C 0x9BAB #CJK UNIFIED IDEOGRAPH+0x8E4D 0x76BF #CJK UNIFIED IDEOGRAPH+0x8E4E 0x6652 #CJK UNIFIED IDEOGRAPH+0x8E4F 0x4E09 #CJK UNIFIED IDEOGRAPH+0x8E50 0x5098 #CJK UNIFIED IDEOGRAPH+0x8E51 0x53C2 #CJK UNIFIED IDEOGRAPH+0x8E52 0x5C71 #CJK UNIFIED IDEOGRAPH+0x8E53 0x60E8 #CJK UNIFIED IDEOGRAPH+0x8E54 0x6492 #CJK UNIFIED IDEOGRAPH+0x8E55 0x6563 #CJK UNIFIED IDEOGRAPH+0x8E56 0x685F #CJK UNIFIED IDEOGRAPH+0x8E57 0x71E6 #CJK UNIFIED IDEOGRAPH+0x8E58 0x73CA #CJK UNIFIED IDEOGRAPH+0x8E59 0x7523 #CJK UNIFIED IDEOGRAPH+0x8E5A 0x7B97 #CJK UNIFIED IDEOGRAPH+0x8E5B 0x7E82 #CJK UNIFIED IDEOGRAPH+0x8E5C 0x8695 #CJK UNIFIED IDEOGRAPH+0x8E5D 0x8B83 #CJK UNIFIED IDEOGRAPH+0x8E5E 0x8CDB #CJK UNIFIED IDEOGRAPH+0x8E5F 0x9178 #CJK UNIFIED IDEOGRAPH+0x8E60 0x9910 #CJK UNIFIED IDEOGRAPH+0x8E61 0x65AC #CJK UNIFIED IDEOGRAPH+0x8E62 0x66AB #CJK UNIFIED IDEOGRAPH+0x8E63 0x6B8B #CJK UNIFIED IDEOGRAPH+0x8E64 0x4ED5 #CJK UNIFIED IDEOGRAPH+0x8E65 0x4ED4 #CJK UNIFIED IDEOGRAPH+0x8E66 0x4F3A #CJK UNIFIED IDEOGRAPH+0x8E67 0x4F7F #CJK UNIFIED IDEOGRAPH+0x8E68 0x523A #CJK UNIFIED IDEOGRAPH+0x8E69 0x53F8 #CJK UNIFIED IDEOGRAPH+0x8E6A 0x53F2 #CJK UNIFIED IDEOGRAPH+0x8E6B 0x55E3 #CJK UNIFIED IDEOGRAPH+0x8E6C 0x56DB #CJK UNIFIED IDEOGRAPH+0x8E6D 0x58EB #CJK UNIFIED IDEOGRAPH+0x8E6E 0x59CB #CJK UNIFIED IDEOGRAPH+0x8E6F 0x59C9 #CJK UNIFIED IDEOGRAPH+0x8E70 0x59FF #CJK UNIFIED IDEOGRAPH+0x8E71 0x5B50 #CJK UNIFIED IDEOGRAPH+0x8E72 0x5C4D #CJK UNIFIED IDEOGRAPH+0x8E73 0x5E02 #CJK UNIFIED IDEOGRAPH+0x8E74 0x5E2B #CJK UNIFIED IDEOGRAPH+0x8E75 0x5FD7 #CJK UNIFIED IDEOGRAPH+0x8E76 0x601D #CJK UNIFIED IDEOGRAPH+0x8E77 0x6307 #CJK UNIFIED IDEOGRAPH+0x8E78 0x652F #CJK UNIFIED IDEOGRAPH+0x8E79 0x5B5C #CJK UNIFIED IDEOGRAPH+0x8E7A 0x65AF #CJK UNIFIED IDEOGRAPH+0x8E7B 0x65BD #CJK UNIFIED IDEOGRAPH+0x8E7C 0x65E8 #CJK UNIFIED IDEOGRAPH+0x8E7D 0x679D #CJK UNIFIED IDEOGRAPH+0x8E7E 0x6B62 #CJK UNIFIED IDEOGRAPH+0x8E80 0x6B7B #CJK UNIFIED IDEOGRAPH+0x8E81 0x6C0F #CJK UNIFIED IDEOGRAPH+0x8E82 0x7345 #CJK UNIFIED IDEOGRAPH+0x8E83 0x7949 #CJK UNIFIED IDEOGRAPH+0x8E84 0x79C1 #CJK UNIFIED IDEOGRAPH+0x8E85 0x7CF8 #CJK UNIFIED IDEOGRAPH+0x8E86 0x7D19 #CJK UNIFIED IDEOGRAPH+0x8E87 0x7D2B #CJK UNIFIED IDEOGRAPH+0x8E88 0x80A2 #CJK UNIFIED IDEOGRAPH+0x8E89 0x8102 #CJK UNIFIED IDEOGRAPH+0x8E8A 0x81F3 #CJK UNIFIED IDEOGRAPH+0x8E8B 0x8996 #CJK UNIFIED IDEOGRAPH+0x8E8C 0x8A5E #CJK UNIFIED IDEOGRAPH+0x8E8D 0x8A69 #CJK UNIFIED IDEOGRAPH+0x8E8E 0x8A66 #CJK UNIFIED IDEOGRAPH+0x8E8F 0x8A8C #CJK UNIFIED IDEOGRAPH+0x8E90 0x8AEE #CJK UNIFIED IDEOGRAPH+0x8E91 0x8CC7 #CJK UNIFIED IDEOGRAPH+0x8E92 0x8CDC #CJK UNIFIED IDEOGRAPH+0x8E93 0x96CC #CJK UNIFIED IDEOGRAPH+0x8E94 0x98FC #CJK UNIFIED IDEOGRAPH+0x8E95 0x6B6F #CJK UNIFIED IDEOGRAPH+0x8E96 0x4E8B #CJK UNIFIED IDEOGRAPH+0x8E97 0x4F3C #CJK UNIFIED IDEOGRAPH+0x8E98 0x4F8D #CJK UNIFIED IDEOGRAPH+0x8E99 0x5150 #CJK UNIFIED IDEOGRAPH+0x8E9A 0x5B57 #CJK UNIFIED IDEOGRAPH+0x8E9B 0x5BFA #CJK UNIFIED IDEOGRAPH+0x8E9C 0x6148 #CJK UNIFIED IDEOGRAPH+0x8E9D 0x6301 #CJK UNIFIED IDEOGRAPH+0x8E9E 0x6642 #CJK UNIFIED IDEOGRAPH+0x8E9F 0x6B21 #CJK UNIFIED IDEOGRAPH+0x8EA0 0x6ECB #CJK UNIFIED IDEOGRAPH+0x8EA1 0x6CBB #CJK UNIFIED IDEOGRAPH+0x8EA2 0x723E #CJK UNIFIED IDEOGRAPH+0x8EA3 0x74BD #CJK UNIFIED IDEOGRAPH+0x8EA4 0x75D4 #CJK UNIFIED IDEOGRAPH+0x8EA5 0x78C1 #CJK UNIFIED IDEOGRAPH+0x8EA6 0x793A #CJK UNIFIED IDEOGRAPH+0x8EA7 0x800C #CJK UNIFIED IDEOGRAPH+0x8EA8 0x8033 #CJK UNIFIED IDEOGRAPH+0x8EA9 0x81EA #CJK UNIFIED IDEOGRAPH+0x8EAA 0x8494 #CJK UNIFIED IDEOGRAPH+0x8EAB 0x8F9E #CJK UNIFIED IDEOGRAPH+0x8EAC 0x6C50 #CJK UNIFIED IDEOGRAPH+0x8EAD 0x9E7F #CJK UNIFIED IDEOGRAPH+0x8EAE 0x5F0F #CJK UNIFIED IDEOGRAPH+0x8EAF 0x8B58 #CJK UNIFIED IDEOGRAPH+0x8EB0 0x9D2B #CJK UNIFIED IDEOGRAPH+0x8EB1 0x7AFA #CJK UNIFIED IDEOGRAPH+0x8EB2 0x8EF8 #CJK UNIFIED IDEOGRAPH+0x8EB3 0x5B8D #CJK UNIFIED IDEOGRAPH+0x8EB4 0x96EB #CJK UNIFIED IDEOGRAPH+0x8EB5 0x4E03 #CJK UNIFIED IDEOGRAPH+0x8EB6 0x53F1 #CJK UNIFIED IDEOGRAPH+0x8EB7 0x57F7 #CJK UNIFIED IDEOGRAPH+0x8EB8 0x5931 #CJK UNIFIED IDEOGRAPH+0x8EB9 0x5AC9 #CJK UNIFIED IDEOGRAPH+0x8EBA 0x5BA4 #CJK UNIFIED IDEOGRAPH+0x8EBB 0x6089 #CJK UNIFIED IDEOGRAPH+0x8EBC 0x6E7F #CJK UNIFIED IDEOGRAPH+0x8EBD 0x6F06 #CJK UNIFIED IDEOGRAPH+0x8EBE 0x75BE #CJK UNIFIED IDEOGRAPH+0x8EBF 0x8CEA #CJK UNIFIED IDEOGRAPH+0x8EC0 0x5B9F #CJK UNIFIED IDEOGRAPH+0x8EC1 0x8500 #CJK UNIFIED IDEOGRAPH+0x8EC2 0x7BE0 #CJK UNIFIED IDEOGRAPH+0x8EC3 0x5072 #CJK UNIFIED IDEOGRAPH+0x8EC4 0x67F4 #CJK UNIFIED IDEOGRAPH+0x8EC5 0x829D #CJK UNIFIED IDEOGRAPH+0x8EC6 0x5C61 #CJK UNIFIED IDEOGRAPH+0x8EC7 0x854A #CJK UNIFIED IDEOGRAPH+0x8EC8 0x7E1E #CJK UNIFIED IDEOGRAPH+0x8EC9 0x820E #CJK UNIFIED IDEOGRAPH+0x8ECA 0x5199 #CJK UNIFIED IDEOGRAPH+0x8ECB 0x5C04 #CJK UNIFIED IDEOGRAPH+0x8ECC 0x6368 #CJK UNIFIED IDEOGRAPH+0x8ECD 0x8D66 #CJK UNIFIED IDEOGRAPH+0x8ECE 0x659C #CJK UNIFIED IDEOGRAPH+0x8ECF 0x716E #CJK UNIFIED IDEOGRAPH+0x8ED0 0x793E #CJK UNIFIED IDEOGRAPH+0x8ED1 0x7D17 #CJK UNIFIED IDEOGRAPH+0x8ED2 0x8005 #CJK UNIFIED IDEOGRAPH+0x8ED3 0x8B1D #CJK UNIFIED IDEOGRAPH+0x8ED4 0x8ECA #CJK UNIFIED IDEOGRAPH+0x8ED5 0x906E #CJK UNIFIED IDEOGRAPH+0x8ED6 0x86C7 #CJK UNIFIED IDEOGRAPH+0x8ED7 0x90AA #CJK UNIFIED IDEOGRAPH+0x8ED8 0x501F #CJK UNIFIED IDEOGRAPH+0x8ED9 0x52FA #CJK UNIFIED IDEOGRAPH+0x8EDA 0x5C3A #CJK UNIFIED IDEOGRAPH+0x8EDB 0x6753 #CJK UNIFIED IDEOGRAPH+0x8EDC 0x707C #CJK UNIFIED IDEOGRAPH+0x8EDD 0x7235 #CJK UNIFIED IDEOGRAPH+0x8EDE 0x914C #CJK UNIFIED IDEOGRAPH+0x8EDF 0x91C8 #CJK UNIFIED IDEOGRAPH+0x8EE0 0x932B #CJK UNIFIED IDEOGRAPH+0x8EE1 0x82E5 #CJK UNIFIED IDEOGRAPH+0x8EE2 0x5BC2 #CJK UNIFIED IDEOGRAPH+0x8EE3 0x5F31 #CJK UNIFIED IDEOGRAPH+0x8EE4 0x60F9 #CJK UNIFIED IDEOGRAPH+0x8EE5 0x4E3B #CJK UNIFIED IDEOGRAPH+0x8EE6 0x53D6 #CJK UNIFIED IDEOGRAPH+0x8EE7 0x5B88 #CJK UNIFIED IDEOGRAPH+0x8EE8 0x624B #CJK UNIFIED IDEOGRAPH+0x8EE9 0x6731 #CJK UNIFIED IDEOGRAPH+0x8EEA 0x6B8A #CJK UNIFIED IDEOGRAPH+0x8EEB 0x72E9 #CJK UNIFIED IDEOGRAPH+0x8EEC 0x73E0 #CJK UNIFIED IDEOGRAPH+0x8EED 0x7A2E #CJK UNIFIED IDEOGRAPH+0x8EEE 0x816B #CJK UNIFIED IDEOGRAPH+0x8EEF 0x8DA3 #CJK UNIFIED IDEOGRAPH+0x8EF0 0x9152 #CJK UNIFIED IDEOGRAPH+0x8EF1 0x9996 #CJK UNIFIED IDEOGRAPH+0x8EF2 0x5112 #CJK UNIFIED IDEOGRAPH+0x8EF3 0x53D7 #CJK UNIFIED IDEOGRAPH+0x8EF4 0x546A #CJK UNIFIED IDEOGRAPH+0x8EF5 0x5BFF #CJK UNIFIED IDEOGRAPH+0x8EF6 0x6388 #CJK UNIFIED IDEOGRAPH+0x8EF7 0x6A39 #CJK UNIFIED IDEOGRAPH+0x8EF8 0x7DAC #CJK UNIFIED IDEOGRAPH+0x8EF9 0x9700 #CJK UNIFIED IDEOGRAPH+0x8EFA 0x56DA #CJK UNIFIED IDEOGRAPH+0x8EFB 0x53CE #CJK UNIFIED IDEOGRAPH+0x8EFC 0x5468 #CJK UNIFIED IDEOGRAPH+0x8F40 0x5B97 #CJK UNIFIED IDEOGRAPH+0x8F41 0x5C31 #CJK UNIFIED IDEOGRAPH+0x8F42 0x5DDE #CJK UNIFIED IDEOGRAPH+0x8F43 0x4FEE #CJK UNIFIED IDEOGRAPH+0x8F44 0x6101 #CJK UNIFIED IDEOGRAPH+0x8F45 0x62FE #CJK UNIFIED IDEOGRAPH+0x8F46 0x6D32 #CJK UNIFIED IDEOGRAPH+0x8F47 0x79C0 #CJK UNIFIED IDEOGRAPH+0x8F48 0x79CB #CJK UNIFIED IDEOGRAPH+0x8F49 0x7D42 #CJK UNIFIED IDEOGRAPH+0x8F4A 0x7E4D #CJK UNIFIED IDEOGRAPH+0x8F4B 0x7FD2 #CJK UNIFIED IDEOGRAPH+0x8F4C 0x81ED #CJK UNIFIED IDEOGRAPH+0x8F4D 0x821F #CJK UNIFIED IDEOGRAPH+0x8F4E 0x8490 #CJK UNIFIED IDEOGRAPH+0x8F4F 0x8846 #CJK UNIFIED IDEOGRAPH+0x8F50 0x8972 #CJK UNIFIED IDEOGRAPH+0x8F51 0x8B90 #CJK UNIFIED IDEOGRAPH+0x8F52 0x8E74 #CJK UNIFIED IDEOGRAPH+0x8F53 0x8F2F #CJK UNIFIED IDEOGRAPH+0x8F54 0x9031 #CJK UNIFIED IDEOGRAPH+0x8F55 0x914B #CJK UNIFIED IDEOGRAPH+0x8F56 0x916C #CJK UNIFIED IDEOGRAPH+0x8F57 0x96C6 #CJK UNIFIED IDEOGRAPH+0x8F58 0x919C #CJK UNIFIED IDEOGRAPH+0x8F59 0x4EC0 #CJK UNIFIED IDEOGRAPH+0x8F5A 0x4F4F #CJK UNIFIED IDEOGRAPH+0x8F5B 0x5145 #CJK UNIFIED IDEOGRAPH+0x8F5C 0x5341 #CJK UNIFIED IDEOGRAPH+0x8F5D 0x5F93 #CJK UNIFIED IDEOGRAPH+0x8F5E 0x620E #CJK UNIFIED IDEOGRAPH+0x8F5F 0x67D4 #CJK UNIFIED IDEOGRAPH+0x8F60 0x6C41 #CJK UNIFIED IDEOGRAPH+0x8F61 0x6E0B #CJK UNIFIED IDEOGRAPH+0x8F62 0x7363 #CJK UNIFIED IDEOGRAPH+0x8F63 0x7E26 #CJK UNIFIED IDEOGRAPH+0x8F64 0x91CD #CJK UNIFIED IDEOGRAPH+0x8F65 0x9283 #CJK UNIFIED IDEOGRAPH+0x8F66 0x53D4 #CJK UNIFIED IDEOGRAPH+0x8F67 0x5919 #CJK UNIFIED IDEOGRAPH+0x8F68 0x5BBF #CJK UNIFIED IDEOGRAPH+0x8F69 0x6DD1 #CJK UNIFIED IDEOGRAPH+0x8F6A 0x795D #CJK UNIFIED IDEOGRAPH+0x8F6B 0x7E2E #CJK UNIFIED IDEOGRAPH+0x8F6C 0x7C9B #CJK UNIFIED IDEOGRAPH+0x8F6D 0x587E #CJK UNIFIED IDEOGRAPH+0x8F6E 0x719F #CJK UNIFIED IDEOGRAPH+0x8F6F 0x51FA #CJK UNIFIED IDEOGRAPH+0x8F70 0x8853 #CJK UNIFIED IDEOGRAPH+0x8F71 0x8FF0 #CJK UNIFIED IDEOGRAPH+0x8F72 0x4FCA #CJK UNIFIED IDEOGRAPH+0x8F73 0x5CFB #CJK UNIFIED IDEOGRAPH+0x8F74 0x6625 #CJK UNIFIED IDEOGRAPH+0x8F75 0x77AC #CJK UNIFIED IDEOGRAPH+0x8F76 0x7AE3 #CJK UNIFIED IDEOGRAPH+0x8F77 0x821C #CJK UNIFIED IDEOGRAPH+0x8F78 0x99FF #CJK UNIFIED IDEOGRAPH+0x8F79 0x51C6 #CJK UNIFIED IDEOGRAPH+0x8F7A 0x5FAA #CJK UNIFIED IDEOGRAPH+0x8F7B 0x65EC #CJK UNIFIED IDEOGRAPH+0x8F7C 0x696F #CJK UNIFIED IDEOGRAPH+0x8F7D 0x6B89 #CJK UNIFIED IDEOGRAPH+0x8F7E 0x6DF3 #CJK UNIFIED IDEOGRAPH+0x8F80 0x6E96 #CJK UNIFIED IDEOGRAPH+0x8F81 0x6F64 #CJK UNIFIED IDEOGRAPH+0x8F82 0x76FE #CJK UNIFIED IDEOGRAPH+0x8F83 0x7D14 #CJK UNIFIED IDEOGRAPH+0x8F84 0x5DE1 #CJK UNIFIED IDEOGRAPH+0x8F85 0x9075 #CJK UNIFIED IDEOGRAPH+0x8F86 0x9187 #CJK UNIFIED IDEOGRAPH+0x8F87 0x9806 #CJK UNIFIED IDEOGRAPH+0x8F88 0x51E6 #CJK UNIFIED IDEOGRAPH+0x8F89 0x521D #CJK UNIFIED IDEOGRAPH+0x8F8A 0x6240 #CJK UNIFIED IDEOGRAPH+0x8F8B 0x6691 #CJK UNIFIED IDEOGRAPH+0x8F8C 0x66D9 #CJK UNIFIED IDEOGRAPH+0x8F8D 0x6E1A #CJK UNIFIED IDEOGRAPH+0x8F8E 0x5EB6 #CJK UNIFIED IDEOGRAPH+0x8F8F 0x7DD2 #CJK UNIFIED IDEOGRAPH+0x8F90 0x7F72 #CJK UNIFIED IDEOGRAPH+0x8F91 0x66F8 #CJK UNIFIED IDEOGRAPH+0x8F92 0x85AF #CJK UNIFIED IDEOGRAPH+0x8F93 0x85F7 #CJK UNIFIED IDEOGRAPH+0x8F94 0x8AF8 #CJK UNIFIED IDEOGRAPH+0x8F95 0x52A9 #CJK UNIFIED IDEOGRAPH+0x8F96 0x53D9 #CJK UNIFIED IDEOGRAPH+0x8F97 0x5973 #CJK UNIFIED IDEOGRAPH+0x8F98 0x5E8F #CJK UNIFIED IDEOGRAPH+0x8F99 0x5F90 #CJK UNIFIED IDEOGRAPH+0x8F9A 0x6055 #CJK UNIFIED IDEOGRAPH+0x8F9B 0x92E4 #CJK UNIFIED IDEOGRAPH+0x8F9C 0x9664 #CJK UNIFIED IDEOGRAPH+0x8F9D 0x50B7 #CJK UNIFIED IDEOGRAPH+0x8F9E 0x511F #CJK UNIFIED IDEOGRAPH+0x8F9F 0x52DD #CJK UNIFIED IDEOGRAPH+0x8FA0 0x5320 #CJK UNIFIED IDEOGRAPH+0x8FA1 0x5347 #CJK UNIFIED IDEOGRAPH+0x8FA2 0x53EC #CJK UNIFIED IDEOGRAPH+0x8FA3 0x54E8 #CJK UNIFIED IDEOGRAPH+0x8FA4 0x5546 #CJK UNIFIED IDEOGRAPH+0x8FA5 0x5531 #CJK UNIFIED IDEOGRAPH+0x8FA6 0x5617 #CJK UNIFIED IDEOGRAPH+0x8FA7 0x5968 #CJK UNIFIED IDEOGRAPH+0x8FA8 0x59BE #CJK UNIFIED IDEOGRAPH+0x8FA9 0x5A3C #CJK UNIFIED IDEOGRAPH+0x8FAA 0x5BB5 #CJK UNIFIED IDEOGRAPH+0x8FAB 0x5C06 #CJK UNIFIED IDEOGRAPH+0x8FAC 0x5C0F #CJK UNIFIED IDEOGRAPH+0x8FAD 0x5C11 #CJK UNIFIED IDEOGRAPH+0x8FAE 0x5C1A #CJK UNIFIED IDEOGRAPH+0x8FAF 0x5E84 #CJK UNIFIED IDEOGRAPH+0x8FB0 0x5E8A #CJK UNIFIED IDEOGRAPH+0x8FB1 0x5EE0 #CJK UNIFIED IDEOGRAPH+0x8FB2 0x5F70 #CJK UNIFIED IDEOGRAPH+0x8FB3 0x627F #CJK UNIFIED IDEOGRAPH+0x8FB4 0x6284 #CJK UNIFIED IDEOGRAPH+0x8FB5 0x62DB #CJK UNIFIED IDEOGRAPH+0x8FB6 0x638C #CJK UNIFIED IDEOGRAPH+0x8FB7 0x6377 #CJK UNIFIED IDEOGRAPH+0x8FB8 0x6607 #CJK UNIFIED IDEOGRAPH+0x8FB9 0x660C #CJK UNIFIED IDEOGRAPH+0x8FBA 0x662D #CJK UNIFIED IDEOGRAPH+0x8FBB 0x6676 #CJK UNIFIED IDEOGRAPH+0x8FBC 0x677E #CJK UNIFIED IDEOGRAPH+0x8FBD 0x68A2 #CJK UNIFIED IDEOGRAPH+0x8FBE 0x6A1F #CJK UNIFIED IDEOGRAPH+0x8FBF 0x6A35 #CJK UNIFIED IDEOGRAPH+0x8FC0 0x6CBC #CJK UNIFIED IDEOGRAPH+0x8FC1 0x6D88 #CJK UNIFIED IDEOGRAPH+0x8FC2 0x6E09 #CJK UNIFIED IDEOGRAPH+0x8FC3 0x6E58 #CJK UNIFIED IDEOGRAPH+0x8FC4 0x713C #CJK UNIFIED IDEOGRAPH+0x8FC5 0x7126 #CJK UNIFIED IDEOGRAPH+0x8FC6 0x7167 #CJK UNIFIED IDEOGRAPH+0x8FC7 0x75C7 #CJK UNIFIED IDEOGRAPH+0x8FC8 0x7701 #CJK UNIFIED IDEOGRAPH+0x8FC9 0x785D #CJK UNIFIED IDEOGRAPH+0x8FCA 0x7901 #CJK UNIFIED IDEOGRAPH+0x8FCB 0x7965 #CJK UNIFIED IDEOGRAPH+0x8FCC 0x79F0 #CJK UNIFIED IDEOGRAPH+0x8FCD 0x7AE0 #CJK UNIFIED IDEOGRAPH+0x8FCE 0x7B11 #CJK UNIFIED IDEOGRAPH+0x8FCF 0x7CA7 #CJK UNIFIED IDEOGRAPH+0x8FD0 0x7D39 #CJK UNIFIED IDEOGRAPH+0x8FD1 0x8096 #CJK UNIFIED IDEOGRAPH+0x8FD2 0x83D6 #CJK UNIFIED IDEOGRAPH+0x8FD3 0x848B #CJK UNIFIED IDEOGRAPH+0x8FD4 0x8549 #CJK UNIFIED IDEOGRAPH+0x8FD5 0x885D #CJK UNIFIED IDEOGRAPH+0x8FD6 0x88F3 #CJK UNIFIED IDEOGRAPH+0x8FD7 0x8A1F #CJK UNIFIED IDEOGRAPH+0x8FD8 0x8A3C #CJK UNIFIED IDEOGRAPH+0x8FD9 0x8A54 #CJK UNIFIED IDEOGRAPH+0x8FDA 0x8A73 #CJK UNIFIED IDEOGRAPH+0x8FDB 0x8C61 #CJK UNIFIED IDEOGRAPH+0x8FDC 0x8CDE #CJK UNIFIED IDEOGRAPH+0x8FDD 0x91A4 #CJK UNIFIED IDEOGRAPH+0x8FDE 0x9266 #CJK UNIFIED IDEOGRAPH+0x8FDF 0x937E #CJK UNIFIED IDEOGRAPH+0x8FE0 0x9418 #CJK UNIFIED IDEOGRAPH+0x8FE1 0x969C #CJK UNIFIED IDEOGRAPH+0x8FE2 0x9798 #CJK UNIFIED IDEOGRAPH+0x8FE3 0x4E0A #CJK UNIFIED IDEOGRAPH+0x8FE4 0x4E08 #CJK UNIFIED IDEOGRAPH+0x8FE5 0x4E1E #CJK UNIFIED IDEOGRAPH+0x8FE6 0x4E57 #CJK UNIFIED IDEOGRAPH+0x8FE7 0x5197 #CJK UNIFIED IDEOGRAPH+0x8FE8 0x5270 #CJK UNIFIED IDEOGRAPH+0x8FE9 0x57CE #CJK UNIFIED IDEOGRAPH+0x8FEA 0x5834 #CJK UNIFIED IDEOGRAPH+0x8FEB 0x58CC #CJK UNIFIED IDEOGRAPH+0x8FEC 0x5B22 #CJK UNIFIED IDEOGRAPH+0x8FED 0x5E38 #CJK UNIFIED IDEOGRAPH+0x8FEE 0x60C5 #CJK UNIFIED IDEOGRAPH+0x8FEF 0x64FE #CJK UNIFIED IDEOGRAPH+0x8FF0 0x6761 #CJK UNIFIED IDEOGRAPH+0x8FF1 0x6756 #CJK UNIFIED IDEOGRAPH+0x8FF2 0x6D44 #CJK UNIFIED IDEOGRAPH+0x8FF3 0x72B6 #CJK UNIFIED IDEOGRAPH+0x8FF4 0x7573 #CJK UNIFIED IDEOGRAPH+0x8FF5 0x7A63 #CJK UNIFIED IDEOGRAPH+0x8FF6 0x84B8 #CJK UNIFIED IDEOGRAPH+0x8FF7 0x8B72 #CJK UNIFIED IDEOGRAPH+0x8FF8 0x91B8 #CJK UNIFIED IDEOGRAPH+0x8FF9 0x9320 #CJK UNIFIED IDEOGRAPH+0x8FFA 0x5631 #CJK UNIFIED IDEOGRAPH+0x8FFB 0x57F4 #CJK UNIFIED IDEOGRAPH+0x8FFC 0x98FE #CJK UNIFIED IDEOGRAPH+0x9040 0x62ED #CJK UNIFIED IDEOGRAPH+0x9041 0x690D #CJK UNIFIED IDEOGRAPH+0x9042 0x6B96 #CJK UNIFIED IDEOGRAPH+0x9043 0x71ED #CJK UNIFIED IDEOGRAPH+0x9044 0x7E54 #CJK UNIFIED IDEOGRAPH+0x9045 0x8077 #CJK UNIFIED IDEOGRAPH+0x9046 0x8272 #CJK UNIFIED IDEOGRAPH+0x9047 0x89E6 #CJK UNIFIED IDEOGRAPH+0x9048 0x98DF #CJK UNIFIED IDEOGRAPH+0x9049 0x8755 #CJK UNIFIED IDEOGRAPH+0x904A 0x8FB1 #CJK UNIFIED IDEOGRAPH+0x904B 0x5C3B #CJK UNIFIED IDEOGRAPH+0x904C 0x4F38 #CJK UNIFIED IDEOGRAPH+0x904D 0x4FE1 #CJK UNIFIED IDEOGRAPH+0x904E 0x4FB5 #CJK UNIFIED IDEOGRAPH+0x904F 0x5507 #CJK UNIFIED IDEOGRAPH+0x9050 0x5A20 #CJK UNIFIED IDEOGRAPH+0x9051 0x5BDD #CJK UNIFIED IDEOGRAPH+0x9052 0x5BE9 #CJK UNIFIED IDEOGRAPH+0x9053 0x5FC3 #CJK UNIFIED IDEOGRAPH+0x9054 0x614E #CJK UNIFIED IDEOGRAPH+0x9055 0x632F #CJK UNIFIED IDEOGRAPH+0x9056 0x65B0 #CJK UNIFIED IDEOGRAPH+0x9057 0x664B #CJK UNIFIED IDEOGRAPH+0x9058 0x68EE #CJK UNIFIED IDEOGRAPH+0x9059 0x699B #CJK UNIFIED IDEOGRAPH+0x905A 0x6D78 #CJK UNIFIED IDEOGRAPH+0x905B 0x6DF1 #CJK UNIFIED IDEOGRAPH+0x905C 0x7533 #CJK UNIFIED IDEOGRAPH+0x905D 0x75B9 #CJK UNIFIED IDEOGRAPH+0x905E 0x771F #CJK UNIFIED IDEOGRAPH+0x905F 0x795E #CJK UNIFIED IDEOGRAPH+0x9060 0x79E6 #CJK UNIFIED IDEOGRAPH+0x9061 0x7D33 #CJK UNIFIED IDEOGRAPH+0x9062 0x81E3 #CJK UNIFIED IDEOGRAPH+0x9063 0x82AF #CJK UNIFIED IDEOGRAPH+0x9064 0x85AA #CJK UNIFIED IDEOGRAPH+0x9065 0x89AA #CJK UNIFIED IDEOGRAPH+0x9066 0x8A3A #CJK UNIFIED IDEOGRAPH+0x9067 0x8EAB #CJK UNIFIED IDEOGRAPH+0x9068 0x8F9B #CJK UNIFIED IDEOGRAPH+0x9069 0x9032 #CJK UNIFIED IDEOGRAPH+0x906A 0x91DD #CJK UNIFIED IDEOGRAPH+0x906B 0x9707 #CJK UNIFIED IDEOGRAPH+0x906C 0x4EBA #CJK UNIFIED IDEOGRAPH+0x906D 0x4EC1 #CJK UNIFIED IDEOGRAPH+0x906E 0x5203 #CJK UNIFIED IDEOGRAPH+0x906F 0x5875 #CJK UNIFIED IDEOGRAPH+0x9070 0x58EC #CJK UNIFIED IDEOGRAPH+0x9071 0x5C0B #CJK UNIFIED IDEOGRAPH+0x9072 0x751A #CJK UNIFIED IDEOGRAPH+0x9073 0x5C3D #CJK UNIFIED IDEOGRAPH+0x9074 0x814E #CJK UNIFIED IDEOGRAPH+0x9075 0x8A0A #CJK UNIFIED IDEOGRAPH+0x9076 0x8FC5 #CJK UNIFIED IDEOGRAPH+0x9077 0x9663 #CJK UNIFIED IDEOGRAPH+0x9078 0x976D #CJK UNIFIED IDEOGRAPH+0x9079 0x7B25 #CJK UNIFIED IDEOGRAPH+0x907A 0x8ACF #CJK UNIFIED IDEOGRAPH+0x907B 0x9808 #CJK UNIFIED IDEOGRAPH+0x907C 0x9162 #CJK UNIFIED IDEOGRAPH+0x907D 0x56F3 #CJK UNIFIED IDEOGRAPH+0x907E 0x53A8 #CJK UNIFIED IDEOGRAPH+0x9080 0x9017 #CJK UNIFIED IDEOGRAPH+0x9081 0x5439 #CJK UNIFIED IDEOGRAPH+0x9082 0x5782 #CJK UNIFIED IDEOGRAPH+0x9083 0x5E25 #CJK UNIFIED IDEOGRAPH+0x9084 0x63A8 #CJK UNIFIED IDEOGRAPH+0x9085 0x6C34 #CJK UNIFIED IDEOGRAPH+0x9086 0x708A #CJK UNIFIED IDEOGRAPH+0x9087 0x7761 #CJK UNIFIED IDEOGRAPH+0x9088 0x7C8B #CJK UNIFIED IDEOGRAPH+0x9089 0x7FE0 #CJK UNIFIED IDEOGRAPH+0x908A 0x8870 #CJK UNIFIED IDEOGRAPH+0x908B 0x9042 #CJK UNIFIED IDEOGRAPH+0x908C 0x9154 #CJK UNIFIED IDEOGRAPH+0x908D 0x9310 #CJK UNIFIED IDEOGRAPH+0x908E 0x9318 #CJK UNIFIED IDEOGRAPH+0x908F 0x968F #CJK UNIFIED IDEOGRAPH+0x9090 0x745E #CJK UNIFIED IDEOGRAPH+0x9091 0x9AC4 #CJK UNIFIED IDEOGRAPH+0x9092 0x5D07 #CJK UNIFIED IDEOGRAPH+0x9093 0x5D69 #CJK UNIFIED IDEOGRAPH+0x9094 0x6570 #CJK UNIFIED IDEOGRAPH+0x9095 0x67A2 #CJK UNIFIED IDEOGRAPH+0x9096 0x8DA8 #CJK UNIFIED IDEOGRAPH+0x9097 0x96DB #CJK UNIFIED IDEOGRAPH+0x9098 0x636E #CJK UNIFIED IDEOGRAPH+0x9099 0x6749 #CJK UNIFIED IDEOGRAPH+0x909A 0x6919 #CJK UNIFIED IDEOGRAPH+0x909B 0x83C5 #CJK UNIFIED IDEOGRAPH+0x909C 0x9817 #CJK UNIFIED IDEOGRAPH+0x909D 0x96C0 #CJK UNIFIED IDEOGRAPH+0x909E 0x88FE #CJK UNIFIED IDEOGRAPH+0x909F 0x6F84 #CJK UNIFIED IDEOGRAPH+0x90A0 0x647A #CJK UNIFIED IDEOGRAPH+0x90A1 0x5BF8 #CJK UNIFIED IDEOGRAPH+0x90A2 0x4E16 #CJK UNIFIED IDEOGRAPH+0x90A3 0x702C #CJK UNIFIED IDEOGRAPH+0x90A4 0x755D #CJK UNIFIED IDEOGRAPH+0x90A5 0x662F #CJK UNIFIED IDEOGRAPH+0x90A6 0x51C4 #CJK UNIFIED IDEOGRAPH+0x90A7 0x5236 #CJK UNIFIED IDEOGRAPH+0x90A8 0x52E2 #CJK UNIFIED IDEOGRAPH+0x90A9 0x59D3 #CJK UNIFIED IDEOGRAPH+0x90AA 0x5F81 #CJK UNIFIED IDEOGRAPH+0x90AB 0x6027 #CJK UNIFIED IDEOGRAPH+0x90AC 0x6210 #CJK UNIFIED IDEOGRAPH+0x90AD 0x653F #CJK UNIFIED IDEOGRAPH+0x90AE 0x6574 #CJK UNIFIED IDEOGRAPH+0x90AF 0x661F #CJK UNIFIED IDEOGRAPH+0x90B0 0x6674 #CJK UNIFIED IDEOGRAPH+0x90B1 0x68F2 #CJK UNIFIED IDEOGRAPH+0x90B2 0x6816 #CJK UNIFIED IDEOGRAPH+0x90B3 0x6B63 #CJK UNIFIED IDEOGRAPH+0x90B4 0x6E05 #CJK UNIFIED IDEOGRAPH+0x90B5 0x7272 #CJK UNIFIED IDEOGRAPH+0x90B6 0x751F #CJK UNIFIED IDEOGRAPH+0x90B7 0x76DB #CJK UNIFIED IDEOGRAPH+0x90B8 0x7CBE #CJK UNIFIED IDEOGRAPH+0x90B9 0x8056 #CJK UNIFIED IDEOGRAPH+0x90BA 0x58F0 #CJK UNIFIED IDEOGRAPH+0x90BB 0x88FD #CJK UNIFIED IDEOGRAPH+0x90BC 0x897F #CJK UNIFIED IDEOGRAPH+0x90BD 0x8AA0 #CJK UNIFIED IDEOGRAPH+0x90BE 0x8A93 #CJK UNIFIED IDEOGRAPH+0x90BF 0x8ACB #CJK UNIFIED IDEOGRAPH+0x90C0 0x901D #CJK UNIFIED IDEOGRAPH+0x90C1 0x9192 #CJK UNIFIED IDEOGRAPH+0x90C2 0x9752 #CJK UNIFIED IDEOGRAPH+0x90C3 0x9759 #CJK UNIFIED IDEOGRAPH+0x90C4 0x6589 #CJK UNIFIED IDEOGRAPH+0x90C5 0x7A0E #CJK UNIFIED IDEOGRAPH+0x90C6 0x8106 #CJK UNIFIED IDEOGRAPH+0x90C7 0x96BB #CJK UNIFIED IDEOGRAPH+0x90C8 0x5E2D #CJK UNIFIED IDEOGRAPH+0x90C9 0x60DC #CJK UNIFIED IDEOGRAPH+0x90CA 0x621A #CJK UNIFIED IDEOGRAPH+0x90CB 0x65A5 #CJK UNIFIED IDEOGRAPH+0x90CC 0x6614 #CJK UNIFIED IDEOGRAPH+0x90CD 0x6790 #CJK UNIFIED IDEOGRAPH+0x90CE 0x77F3 #CJK UNIFIED IDEOGRAPH+0x90CF 0x7A4D #CJK UNIFIED IDEOGRAPH+0x90D0 0x7C4D #CJK UNIFIED IDEOGRAPH+0x90D1 0x7E3E #CJK UNIFIED IDEOGRAPH+0x90D2 0x810A #CJK UNIFIED IDEOGRAPH+0x90D3 0x8CAC #CJK UNIFIED IDEOGRAPH+0x90D4 0x8D64 #CJK UNIFIED IDEOGRAPH+0x90D5 0x8DE1 #CJK UNIFIED IDEOGRAPH+0x90D6 0x8E5F #CJK UNIFIED IDEOGRAPH+0x90D7 0x78A9 #CJK UNIFIED IDEOGRAPH+0x90D8 0x5207 #CJK UNIFIED IDEOGRAPH+0x90D9 0x62D9 #CJK UNIFIED IDEOGRAPH+0x90DA 0x63A5 #CJK UNIFIED IDEOGRAPH+0x90DB 0x6442 #CJK UNIFIED IDEOGRAPH+0x90DC 0x6298 #CJK UNIFIED IDEOGRAPH+0x90DD 0x8A2D #CJK UNIFIED IDEOGRAPH+0x90DE 0x7A83 #CJK UNIFIED IDEOGRAPH+0x90DF 0x7BC0 #CJK UNIFIED IDEOGRAPH+0x90E0 0x8AAC #CJK UNIFIED IDEOGRAPH+0x90E1 0x96EA #CJK UNIFIED IDEOGRAPH+0x90E2 0x7D76 #CJK UNIFIED IDEOGRAPH+0x90E3 0x820C #CJK UNIFIED IDEOGRAPH+0x90E4 0x8749 #CJK UNIFIED IDEOGRAPH+0x90E5 0x4ED9 #CJK UNIFIED IDEOGRAPH+0x90E6 0x5148 #CJK UNIFIED IDEOGRAPH+0x90E7 0x5343 #CJK UNIFIED IDEOGRAPH+0x90E8 0x5360 #CJK UNIFIED IDEOGRAPH+0x90E9 0x5BA3 #CJK UNIFIED IDEOGRAPH+0x90EA 0x5C02 #CJK UNIFIED IDEOGRAPH+0x90EB 0x5C16 #CJK UNIFIED IDEOGRAPH+0x90EC 0x5DDD #CJK UNIFIED IDEOGRAPH+0x90ED 0x6226 #CJK UNIFIED IDEOGRAPH+0x90EE 0x6247 #CJK UNIFIED IDEOGRAPH+0x90EF 0x64B0 #CJK UNIFIED IDEOGRAPH+0x90F0 0x6813 #CJK UNIFIED IDEOGRAPH+0x90F1 0x6834 #CJK UNIFIED IDEOGRAPH+0x90F2 0x6CC9 #CJK UNIFIED IDEOGRAPH+0x90F3 0x6D45 #CJK UNIFIED IDEOGRAPH+0x90F4 0x6D17 #CJK UNIFIED IDEOGRAPH+0x90F5 0x67D3 #CJK UNIFIED IDEOGRAPH+0x90F6 0x6F5C #CJK UNIFIED IDEOGRAPH+0x90F7 0x714E #CJK UNIFIED IDEOGRAPH+0x90F8 0x717D #CJK UNIFIED IDEOGRAPH+0x90F9 0x65CB #CJK UNIFIED IDEOGRAPH+0x90FA 0x7A7F #CJK UNIFIED IDEOGRAPH+0x90FB 0x7BAD #CJK UNIFIED IDEOGRAPH+0x90FC 0x7DDA #CJK UNIFIED IDEOGRAPH+0x9140 0x7E4A #CJK UNIFIED IDEOGRAPH+0x9141 0x7FA8 #CJK UNIFIED IDEOGRAPH+0x9142 0x817A #CJK UNIFIED IDEOGRAPH+0x9143 0x821B #CJK UNIFIED IDEOGRAPH+0x9144 0x8239 #CJK UNIFIED IDEOGRAPH+0x9145 0x85A6 #CJK UNIFIED IDEOGRAPH+0x9146 0x8A6E #CJK UNIFIED IDEOGRAPH+0x9147 0x8CCE #CJK UNIFIED IDEOGRAPH+0x9148 0x8DF5 #CJK UNIFIED IDEOGRAPH+0x9149 0x9078 #CJK UNIFIED IDEOGRAPH+0x914A 0x9077 #CJK UNIFIED IDEOGRAPH+0x914B 0x92AD #CJK UNIFIED IDEOGRAPH+0x914C 0x9291 #CJK UNIFIED IDEOGRAPH+0x914D 0x9583 #CJK UNIFIED IDEOGRAPH+0x914E 0x9BAE #CJK UNIFIED IDEOGRAPH+0x914F 0x524D #CJK UNIFIED IDEOGRAPH+0x9150 0x5584 #CJK UNIFIED IDEOGRAPH+0x9151 0x6F38 #CJK UNIFIED IDEOGRAPH+0x9152 0x7136 #CJK UNIFIED IDEOGRAPH+0x9153 0x5168 #CJK UNIFIED IDEOGRAPH+0x9154 0x7985 #CJK UNIFIED IDEOGRAPH+0x9155 0x7E55 #CJK UNIFIED IDEOGRAPH+0x9156 0x81B3 #CJK UNIFIED IDEOGRAPH+0x9157 0x7CCE #CJK UNIFIED IDEOGRAPH+0x9158 0x564C #CJK UNIFIED IDEOGRAPH+0x9159 0x5851 #CJK UNIFIED IDEOGRAPH+0x915A 0x5CA8 #CJK UNIFIED IDEOGRAPH+0x915B 0x63AA #CJK UNIFIED IDEOGRAPH+0x915C 0x66FE #CJK UNIFIED IDEOGRAPH+0x915D 0x66FD #CJK UNIFIED IDEOGRAPH+0x915E 0x695A #CJK UNIFIED IDEOGRAPH+0x915F 0x72D9 #CJK UNIFIED IDEOGRAPH+0x9160 0x758F #CJK UNIFIED IDEOGRAPH+0x9161 0x758E #CJK UNIFIED IDEOGRAPH+0x9162 0x790E #CJK UNIFIED IDEOGRAPH+0x9163 0x7956 #CJK UNIFIED IDEOGRAPH+0x9164 0x79DF #CJK UNIFIED IDEOGRAPH+0x9165 0x7C97 #CJK UNIFIED IDEOGRAPH+0x9166 0x7D20 #CJK UNIFIED IDEOGRAPH+0x9167 0x7D44 #CJK UNIFIED IDEOGRAPH+0x9168 0x8607 #CJK UNIFIED IDEOGRAPH+0x9169 0x8A34 #CJK UNIFIED IDEOGRAPH+0x916A 0x963B #CJK UNIFIED IDEOGRAPH+0x916B 0x9061 #CJK UNIFIED IDEOGRAPH+0x916C 0x9F20 #CJK UNIFIED IDEOGRAPH+0x916D 0x50E7 #CJK UNIFIED IDEOGRAPH+0x916E 0x5275 #CJK UNIFIED IDEOGRAPH+0x916F 0x53CC #CJK UNIFIED IDEOGRAPH+0x9170 0x53E2 #CJK UNIFIED IDEOGRAPH+0x9171 0x5009 #CJK UNIFIED IDEOGRAPH+0x9172 0x55AA #CJK UNIFIED IDEOGRAPH+0x9173 0x58EE #CJK UNIFIED IDEOGRAPH+0x9174 0x594F #CJK UNIFIED IDEOGRAPH+0x9175 0x723D #CJK UNIFIED IDEOGRAPH+0x9176 0x5B8B #CJK UNIFIED IDEOGRAPH+0x9177 0x5C64 #CJK UNIFIED IDEOGRAPH+0x9178 0x531D #CJK UNIFIED IDEOGRAPH+0x9179 0x60E3 #CJK UNIFIED IDEOGRAPH+0x917A 0x60F3 #CJK UNIFIED IDEOGRAPH+0x917B 0x635C #CJK UNIFIED IDEOGRAPH+0x917C 0x6383 #CJK UNIFIED IDEOGRAPH+0x917D 0x633F #CJK UNIFIED IDEOGRAPH+0x917E 0x63BB #CJK UNIFIED IDEOGRAPH+0x9180 0x64CD #CJK UNIFIED IDEOGRAPH+0x9181 0x65E9 #CJK UNIFIED IDEOGRAPH+0x9182 0x66F9 #CJK UNIFIED IDEOGRAPH+0x9183 0x5DE3 #CJK UNIFIED IDEOGRAPH+0x9184 0x69CD #CJK UNIFIED IDEOGRAPH+0x9185 0x69FD #CJK UNIFIED IDEOGRAPH+0x9186 0x6F15 #CJK UNIFIED IDEOGRAPH+0x9187 0x71E5 #CJK UNIFIED IDEOGRAPH+0x9188 0x4E89 #CJK UNIFIED IDEOGRAPH+0x9189 0x75E9 #CJK UNIFIED IDEOGRAPH+0x918A 0x76F8 #CJK UNIFIED IDEOGRAPH+0x918B 0x7A93 #CJK UNIFIED IDEOGRAPH+0x918C 0x7CDF #CJK UNIFIED IDEOGRAPH+0x918D 0x7DCF #CJK UNIFIED IDEOGRAPH+0x918E 0x7D9C #CJK UNIFIED IDEOGRAPH+0x918F 0x8061 #CJK UNIFIED IDEOGRAPH+0x9190 0x8349 #CJK UNIFIED IDEOGRAPH+0x9191 0x8358 #CJK UNIFIED IDEOGRAPH+0x9192 0x846C #CJK UNIFIED IDEOGRAPH+0x9193 0x84BC #CJK UNIFIED IDEOGRAPH+0x9194 0x85FB #CJK UNIFIED IDEOGRAPH+0x9195 0x88C5 #CJK UNIFIED IDEOGRAPH+0x9196 0x8D70 #CJK UNIFIED IDEOGRAPH+0x9197 0x9001 #CJK UNIFIED IDEOGRAPH+0x9198 0x906D #CJK UNIFIED IDEOGRAPH+0x9199 0x9397 #CJK UNIFIED IDEOGRAPH+0x919A 0x971C #CJK UNIFIED IDEOGRAPH+0x919B 0x9A12 #CJK UNIFIED IDEOGRAPH+0x919C 0x50CF #CJK UNIFIED IDEOGRAPH+0x919D 0x5897 #CJK UNIFIED IDEOGRAPH+0x919E 0x618E #CJK UNIFIED IDEOGRAPH+0x919F 0x81D3 #CJK UNIFIED IDEOGRAPH+0x91A0 0x8535 #CJK UNIFIED IDEOGRAPH+0x91A1 0x8D08 #CJK UNIFIED IDEOGRAPH+0x91A2 0x9020 #CJK UNIFIED IDEOGRAPH+0x91A3 0x4FC3 #CJK UNIFIED IDEOGRAPH+0x91A4 0x5074 #CJK UNIFIED IDEOGRAPH+0x91A5 0x5247 #CJK UNIFIED IDEOGRAPH+0x91A6 0x5373 #CJK UNIFIED IDEOGRAPH+0x91A7 0x606F #CJK UNIFIED IDEOGRAPH+0x91A8 0x6349 #CJK UNIFIED IDEOGRAPH+0x91A9 0x675F #CJK UNIFIED IDEOGRAPH+0x91AA 0x6E2C #CJK UNIFIED IDEOGRAPH+0x91AB 0x8DB3 #CJK UNIFIED IDEOGRAPH+0x91AC 0x901F #CJK UNIFIED IDEOGRAPH+0x91AD 0x4FD7 #CJK UNIFIED IDEOGRAPH+0x91AE 0x5C5E #CJK UNIFIED IDEOGRAPH+0x91AF 0x8CCA #CJK UNIFIED IDEOGRAPH+0x91B0 0x65CF #CJK UNIFIED IDEOGRAPH+0x91B1 0x7D9A #CJK UNIFIED IDEOGRAPH+0x91B2 0x5352 #CJK UNIFIED IDEOGRAPH+0x91B3 0x8896 #CJK UNIFIED IDEOGRAPH+0x91B4 0x5176 #CJK UNIFIED IDEOGRAPH+0x91B5 0x63C3 #CJK UNIFIED IDEOGRAPH+0x91B6 0x5B58 #CJK UNIFIED IDEOGRAPH+0x91B7 0x5B6B #CJK UNIFIED IDEOGRAPH+0x91B8 0x5C0A #CJK UNIFIED IDEOGRAPH+0x91B9 0x640D #CJK UNIFIED IDEOGRAPH+0x91BA 0x6751 #CJK UNIFIED IDEOGRAPH+0x91BB 0x905C #CJK UNIFIED IDEOGRAPH+0x91BC 0x4ED6 #CJK UNIFIED IDEOGRAPH+0x91BD 0x591A #CJK UNIFIED IDEOGRAPH+0x91BE 0x592A #CJK UNIFIED IDEOGRAPH+0x91BF 0x6C70 #CJK UNIFIED IDEOGRAPH+0x91C0 0x8A51 #CJK UNIFIED IDEOGRAPH+0x91C1 0x553E #CJK UNIFIED IDEOGRAPH+0x91C2 0x5815 #CJK UNIFIED IDEOGRAPH+0x91C3 0x59A5 #CJK UNIFIED IDEOGRAPH+0x91C4 0x60F0 #CJK UNIFIED IDEOGRAPH+0x91C5 0x6253 #CJK UNIFIED IDEOGRAPH+0x91C6 0x67C1 #CJK UNIFIED IDEOGRAPH+0x91C7 0x8235 #CJK UNIFIED IDEOGRAPH+0x91C8 0x6955 #CJK UNIFIED IDEOGRAPH+0x91C9 0x9640 #CJK UNIFIED IDEOGRAPH+0x91CA 0x99C4 #CJK UNIFIED IDEOGRAPH+0x91CB 0x9A28 #CJK UNIFIED IDEOGRAPH+0x91CC 0x4F53 #CJK UNIFIED IDEOGRAPH+0x91CD 0x5806 #CJK UNIFIED IDEOGRAPH+0x91CE 0x5BFE #CJK UNIFIED IDEOGRAPH+0x91CF 0x8010 #CJK UNIFIED IDEOGRAPH+0x91D0 0x5CB1 #CJK UNIFIED IDEOGRAPH+0x91D1 0x5E2F #CJK UNIFIED IDEOGRAPH+0x91D2 0x5F85 #CJK UNIFIED IDEOGRAPH+0x91D3 0x6020 #CJK UNIFIED IDEOGRAPH+0x91D4 0x614B #CJK UNIFIED IDEOGRAPH+0x91D5 0x6234 #CJK UNIFIED IDEOGRAPH+0x91D6 0x66FF #CJK UNIFIED IDEOGRAPH+0x91D7 0x6CF0 #CJK UNIFIED IDEOGRAPH+0x91D8 0x6EDE #CJK UNIFIED IDEOGRAPH+0x91D9 0x80CE #CJK UNIFIED IDEOGRAPH+0x91DA 0x817F #CJK UNIFIED IDEOGRAPH+0x91DB 0x82D4 #CJK UNIFIED IDEOGRAPH+0x91DC 0x888B #CJK UNIFIED IDEOGRAPH+0x91DD 0x8CB8 #CJK UNIFIED IDEOGRAPH+0x91DE 0x9000 #CJK UNIFIED IDEOGRAPH+0x91DF 0x902E #CJK UNIFIED IDEOGRAPH+0x91E0 0x968A #CJK UNIFIED IDEOGRAPH+0x91E1 0x9EDB #CJK UNIFIED IDEOGRAPH+0x91E2 0x9BDB #CJK UNIFIED IDEOGRAPH+0x91E3 0x4EE3 #CJK UNIFIED IDEOGRAPH+0x91E4 0x53F0 #CJK UNIFIED IDEOGRAPH+0x91E5 0x5927 #CJK UNIFIED IDEOGRAPH+0x91E6 0x7B2C #CJK UNIFIED IDEOGRAPH+0x91E7 0x918D #CJK UNIFIED IDEOGRAPH+0x91E8 0x984C #CJK UNIFIED IDEOGRAPH+0x91E9 0x9DF9 #CJK UNIFIED IDEOGRAPH+0x91EA 0x6EDD #CJK UNIFIED IDEOGRAPH+0x91EB 0x7027 #CJK UNIFIED IDEOGRAPH+0x91EC 0x5353 #CJK UNIFIED IDEOGRAPH+0x91ED 0x5544 #CJK UNIFIED IDEOGRAPH+0x91EE 0x5B85 #CJK UNIFIED IDEOGRAPH+0x91EF 0x6258 #CJK UNIFIED IDEOGRAPH+0x91F0 0x629E #CJK UNIFIED IDEOGRAPH+0x91F1 0x62D3 #CJK UNIFIED IDEOGRAPH+0x91F2 0x6CA2 #CJK UNIFIED IDEOGRAPH+0x91F3 0x6FEF #CJK UNIFIED IDEOGRAPH+0x91F4 0x7422 #CJK UNIFIED IDEOGRAPH+0x91F5 0x8A17 #CJK UNIFIED IDEOGRAPH+0x91F6 0x9438 #CJK UNIFIED IDEOGRAPH+0x91F7 0x6FC1 #CJK UNIFIED IDEOGRAPH+0x91F8 0x8AFE #CJK UNIFIED IDEOGRAPH+0x91F9 0x8338 #CJK UNIFIED IDEOGRAPH+0x91FA 0x51E7 #CJK UNIFIED IDEOGRAPH+0x91FB 0x86F8 #CJK UNIFIED IDEOGRAPH+0x91FC 0x53EA #CJK UNIFIED IDEOGRAPH+0x9240 0x53E9 #CJK UNIFIED IDEOGRAPH+0x9241 0x4F46 #CJK UNIFIED IDEOGRAPH+0x9242 0x9054 #CJK UNIFIED IDEOGRAPH+0x9243 0x8FB0 #CJK UNIFIED IDEOGRAPH+0x9244 0x596A #CJK UNIFIED IDEOGRAPH+0x9245 0x8131 #CJK UNIFIED IDEOGRAPH+0x9246 0x5DFD #CJK UNIFIED IDEOGRAPH+0x9247 0x7AEA #CJK UNIFIED IDEOGRAPH+0x9248 0x8FBF #CJK UNIFIED IDEOGRAPH+0x9249 0x68DA #CJK UNIFIED IDEOGRAPH+0x924A 0x8C37 #CJK UNIFIED IDEOGRAPH+0x924B 0x72F8 #CJK UNIFIED IDEOGRAPH+0x924C 0x9C48 #CJK UNIFIED IDEOGRAPH+0x924D 0x6A3D #CJK UNIFIED IDEOGRAPH+0x924E 0x8AB0 #CJK UNIFIED IDEOGRAPH+0x924F 0x4E39 #CJK UNIFIED IDEOGRAPH+0x9250 0x5358 #CJK UNIFIED IDEOGRAPH+0x9251 0x5606 #CJK UNIFIED IDEOGRAPH+0x9252 0x5766 #CJK UNIFIED IDEOGRAPH+0x9253 0x62C5 #CJK UNIFIED IDEOGRAPH+0x9254 0x63A2 #CJK UNIFIED IDEOGRAPH+0x9255 0x65E6 #CJK UNIFIED IDEOGRAPH+0x9256 0x6B4E #CJK UNIFIED IDEOGRAPH+0x9257 0x6DE1 #CJK UNIFIED IDEOGRAPH+0x9258 0x6E5B #CJK UNIFIED IDEOGRAPH+0x9259 0x70AD #CJK UNIFIED IDEOGRAPH+0x925A 0x77ED #CJK UNIFIED IDEOGRAPH+0x925B 0x7AEF #CJK UNIFIED IDEOGRAPH+0x925C 0x7BAA #CJK UNIFIED IDEOGRAPH+0x925D 0x7DBB #CJK UNIFIED IDEOGRAPH+0x925E 0x803D #CJK UNIFIED IDEOGRAPH+0x925F 0x80C6 #CJK UNIFIED IDEOGRAPH+0x9260 0x86CB #CJK UNIFIED IDEOGRAPH+0x9261 0x8A95 #CJK UNIFIED IDEOGRAPH+0x9262 0x935B #CJK UNIFIED IDEOGRAPH+0x9263 0x56E3 #CJK UNIFIED IDEOGRAPH+0x9264 0x58C7 #CJK UNIFIED IDEOGRAPH+0x9265 0x5F3E #CJK UNIFIED IDEOGRAPH+0x9266 0x65AD #CJK UNIFIED IDEOGRAPH+0x9267 0x6696 #CJK UNIFIED IDEOGRAPH+0x9268 0x6A80 #CJK UNIFIED IDEOGRAPH+0x9269 0x6BB5 #CJK UNIFIED IDEOGRAPH+0x926A 0x7537 #CJK UNIFIED IDEOGRAPH+0x926B 0x8AC7 #CJK UNIFIED IDEOGRAPH+0x926C 0x5024 #CJK UNIFIED IDEOGRAPH+0x926D 0x77E5 #CJK UNIFIED IDEOGRAPH+0x926E 0x5730 #CJK UNIFIED IDEOGRAPH+0x926F 0x5F1B #CJK UNIFIED IDEOGRAPH+0x9270 0x6065 #CJK UNIFIED IDEOGRAPH+0x9271 0x667A #CJK UNIFIED IDEOGRAPH+0x9272 0x6C60 #CJK UNIFIED IDEOGRAPH+0x9273 0x75F4 #CJK UNIFIED IDEOGRAPH+0x9274 0x7A1A #CJK UNIFIED IDEOGRAPH+0x9275 0x7F6E #CJK UNIFIED IDEOGRAPH+0x9276 0x81F4 #CJK UNIFIED IDEOGRAPH+0x9277 0x8718 #CJK UNIFIED IDEOGRAPH+0x9278 0x9045 #CJK UNIFIED IDEOGRAPH+0x9279 0x99B3 #CJK UNIFIED IDEOGRAPH+0x927A 0x7BC9 #CJK UNIFIED IDEOGRAPH+0x927B 0x755C #CJK UNIFIED IDEOGRAPH+0x927C 0x7AF9 #CJK UNIFIED IDEOGRAPH+0x927D 0x7B51 #CJK UNIFIED IDEOGRAPH+0x927E 0x84C4 #CJK UNIFIED IDEOGRAPH+0x9280 0x9010 #CJK UNIFIED IDEOGRAPH+0x9281 0x79E9 #CJK UNIFIED IDEOGRAPH+0x9282 0x7A92 #CJK UNIFIED IDEOGRAPH+0x9283 0x8336 #CJK UNIFIED IDEOGRAPH+0x9284 0x5AE1 #CJK UNIFIED IDEOGRAPH+0x9285 0x7740 #CJK UNIFIED IDEOGRAPH+0x9286 0x4E2D #CJK UNIFIED IDEOGRAPH+0x9287 0x4EF2 #CJK UNIFIED IDEOGRAPH+0x9288 0x5B99 #CJK UNIFIED IDEOGRAPH+0x9289 0x5FE0 #CJK UNIFIED IDEOGRAPH+0x928A 0x62BD #CJK UNIFIED IDEOGRAPH+0x928B 0x663C #CJK UNIFIED IDEOGRAPH+0x928C 0x67F1 #CJK UNIFIED IDEOGRAPH+0x928D 0x6CE8 #CJK UNIFIED IDEOGRAPH+0x928E 0x866B #CJK UNIFIED IDEOGRAPH+0x928F 0x8877 #CJK UNIFIED IDEOGRAPH+0x9290 0x8A3B #CJK UNIFIED IDEOGRAPH+0x9291 0x914E #CJK UNIFIED IDEOGRAPH+0x9292 0x92F3 #CJK UNIFIED IDEOGRAPH+0x9293 0x99D0 #CJK UNIFIED IDEOGRAPH+0x9294 0x6A17 #CJK UNIFIED IDEOGRAPH+0x9295 0x7026 #CJK UNIFIED IDEOGRAPH+0x9296 0x732A #CJK UNIFIED IDEOGRAPH+0x9297 0x82E7 #CJK UNIFIED IDEOGRAPH+0x9298 0x8457 #CJK UNIFIED IDEOGRAPH+0x9299 0x8CAF #CJK UNIFIED IDEOGRAPH+0x929A 0x4E01 #CJK UNIFIED IDEOGRAPH+0x929B 0x5146 #CJK UNIFIED IDEOGRAPH+0x929C 0x51CB #CJK UNIFIED IDEOGRAPH+0x929D 0x558B #CJK UNIFIED IDEOGRAPH+0x929E 0x5BF5 #CJK UNIFIED IDEOGRAPH+0x929F 0x5E16 #CJK UNIFIED IDEOGRAPH+0x92A0 0x5E33 #CJK UNIFIED IDEOGRAPH+0x92A1 0x5E81 #CJK UNIFIED IDEOGRAPH+0x92A2 0x5F14 #CJK UNIFIED IDEOGRAPH+0x92A3 0x5F35 #CJK UNIFIED IDEOGRAPH+0x92A4 0x5F6B #CJK UNIFIED IDEOGRAPH+0x92A5 0x5FB4 #CJK UNIFIED IDEOGRAPH+0x92A6 0x61F2 #CJK UNIFIED IDEOGRAPH+0x92A7 0x6311 #CJK UNIFIED IDEOGRAPH+0x92A8 0x66A2 #CJK UNIFIED IDEOGRAPH+0x92A9 0x671D #CJK UNIFIED IDEOGRAPH+0x92AA 0x6F6E #CJK UNIFIED IDEOGRAPH+0x92AB 0x7252 #CJK UNIFIED IDEOGRAPH+0x92AC 0x753A #CJK UNIFIED IDEOGRAPH+0x92AD 0x773A #CJK UNIFIED IDEOGRAPH+0x92AE 0x8074 #CJK UNIFIED IDEOGRAPH+0x92AF 0x8139 #CJK UNIFIED IDEOGRAPH+0x92B0 0x8178 #CJK UNIFIED IDEOGRAPH+0x92B1 0x8776 #CJK UNIFIED IDEOGRAPH+0x92B2 0x8ABF #CJK UNIFIED IDEOGRAPH+0x92B3 0x8ADC #CJK UNIFIED IDEOGRAPH+0x92B4 0x8D85 #CJK UNIFIED IDEOGRAPH+0x92B5 0x8DF3 #CJK UNIFIED IDEOGRAPH+0x92B6 0x929A #CJK UNIFIED IDEOGRAPH+0x92B7 0x9577 #CJK UNIFIED IDEOGRAPH+0x92B8 0x9802 #CJK UNIFIED IDEOGRAPH+0x92B9 0x9CE5 #CJK UNIFIED IDEOGRAPH+0x92BA 0x52C5 #CJK UNIFIED IDEOGRAPH+0x92BB 0x6357 #CJK UNIFIED IDEOGRAPH+0x92BC 0x76F4 #CJK UNIFIED IDEOGRAPH+0x92BD 0x6715 #CJK UNIFIED IDEOGRAPH+0x92BE 0x6C88 #CJK UNIFIED IDEOGRAPH+0x92BF 0x73CD #CJK UNIFIED IDEOGRAPH+0x92C0 0x8CC3 #CJK UNIFIED IDEOGRAPH+0x92C1 0x93AE #CJK UNIFIED IDEOGRAPH+0x92C2 0x9673 #CJK UNIFIED IDEOGRAPH+0x92C3 0x6D25 #CJK UNIFIED IDEOGRAPH+0x92C4 0x589C #CJK UNIFIED IDEOGRAPH+0x92C5 0x690E #CJK UNIFIED IDEOGRAPH+0x92C6 0x69CC #CJK UNIFIED IDEOGRAPH+0x92C7 0x8FFD #CJK UNIFIED IDEOGRAPH+0x92C8 0x939A #CJK UNIFIED IDEOGRAPH+0x92C9 0x75DB #CJK UNIFIED IDEOGRAPH+0x92CA 0x901A #CJK UNIFIED IDEOGRAPH+0x92CB 0x585A #CJK UNIFIED IDEOGRAPH+0x92CC 0x6802 #CJK UNIFIED IDEOGRAPH+0x92CD 0x63B4 #CJK UNIFIED IDEOGRAPH+0x92CE 0x69FB #CJK UNIFIED IDEOGRAPH+0x92CF 0x4F43 #CJK UNIFIED IDEOGRAPH+0x92D0 0x6F2C #CJK UNIFIED IDEOGRAPH+0x92D1 0x67D8 #CJK UNIFIED IDEOGRAPH+0x92D2 0x8FBB #CJK UNIFIED IDEOGRAPH+0x92D3 0x8526 #CJK UNIFIED IDEOGRAPH+0x92D4 0x7DB4 #CJK UNIFIED IDEOGRAPH+0x92D5 0x9354 #CJK UNIFIED IDEOGRAPH+0x92D6 0x693F #CJK UNIFIED IDEOGRAPH+0x92D7 0x6F70 #CJK UNIFIED IDEOGRAPH+0x92D8 0x576A #CJK UNIFIED IDEOGRAPH+0x92D9 0x58F7 #CJK UNIFIED IDEOGRAPH+0x92DA 0x5B2C #CJK UNIFIED IDEOGRAPH+0x92DB 0x7D2C #CJK UNIFIED IDEOGRAPH+0x92DC 0x722A #CJK UNIFIED IDEOGRAPH+0x92DD 0x540A #CJK UNIFIED IDEOGRAPH+0x92DE 0x91E3 #CJK UNIFIED IDEOGRAPH+0x92DF 0x9DB4 #CJK UNIFIED IDEOGRAPH+0x92E0 0x4EAD #CJK UNIFIED IDEOGRAPH+0x92E1 0x4F4E #CJK UNIFIED IDEOGRAPH+0x92E2 0x505C #CJK UNIFIED IDEOGRAPH+0x92E3 0x5075 #CJK UNIFIED IDEOGRAPH+0x92E4 0x5243 #CJK UNIFIED IDEOGRAPH+0x92E5 0x8C9E #CJK UNIFIED IDEOGRAPH+0x92E6 0x5448 #CJK UNIFIED IDEOGRAPH+0x92E7 0x5824 #CJK UNIFIED IDEOGRAPH+0x92E8 0x5B9A #CJK UNIFIED IDEOGRAPH+0x92E9 0x5E1D #CJK UNIFIED IDEOGRAPH+0x92EA 0x5E95 #CJK UNIFIED IDEOGRAPH+0x92EB 0x5EAD #CJK UNIFIED IDEOGRAPH+0x92EC 0x5EF7 #CJK UNIFIED IDEOGRAPH+0x92ED 0x5F1F #CJK UNIFIED IDEOGRAPH+0x92EE 0x608C #CJK UNIFIED IDEOGRAPH+0x92EF 0x62B5 #CJK UNIFIED IDEOGRAPH+0x92F0 0x633A #CJK UNIFIED IDEOGRAPH+0x92F1 0x63D0 #CJK UNIFIED IDEOGRAPH+0x92F2 0x68AF #CJK UNIFIED IDEOGRAPH+0x92F3 0x6C40 #CJK UNIFIED IDEOGRAPH+0x92F4 0x7887 #CJK UNIFIED IDEOGRAPH+0x92F5 0x798E #CJK UNIFIED IDEOGRAPH+0x92F6 0x7A0B #CJK UNIFIED IDEOGRAPH+0x92F7 0x7DE0 #CJK UNIFIED IDEOGRAPH+0x92F8 0x8247 #CJK UNIFIED IDEOGRAPH+0x92F9 0x8A02 #CJK UNIFIED IDEOGRAPH+0x92FA 0x8AE6 #CJK UNIFIED IDEOGRAPH+0x92FB 0x8E44 #CJK UNIFIED IDEOGRAPH+0x92FC 0x9013 #CJK UNIFIED IDEOGRAPH+0x9340 0x90B8 #CJK UNIFIED IDEOGRAPH+0x9341 0x912D #CJK UNIFIED IDEOGRAPH+0x9342 0x91D8 #CJK UNIFIED IDEOGRAPH+0x9343 0x9F0E #CJK UNIFIED IDEOGRAPH+0x9344 0x6CE5 #CJK UNIFIED IDEOGRAPH+0x9345 0x6458 #CJK UNIFIED IDEOGRAPH+0x9346 0x64E2 #CJK UNIFIED IDEOGRAPH+0x9347 0x6575 #CJK UNIFIED IDEOGRAPH+0x9348 0x6EF4 #CJK UNIFIED IDEOGRAPH+0x9349 0x7684 #CJK UNIFIED IDEOGRAPH+0x934A 0x7B1B #CJK UNIFIED IDEOGRAPH+0x934B 0x9069 #CJK UNIFIED IDEOGRAPH+0x934C 0x93D1 #CJK UNIFIED IDEOGRAPH+0x934D 0x6EBA #CJK UNIFIED IDEOGRAPH+0x934E 0x54F2 #CJK UNIFIED IDEOGRAPH+0x934F 0x5FB9 #CJK UNIFIED IDEOGRAPH+0x9350 0x64A4 #CJK UNIFIED IDEOGRAPH+0x9351 0x8F4D #CJK UNIFIED IDEOGRAPH+0x9352 0x8FED #CJK UNIFIED IDEOGRAPH+0x9353 0x9244 #CJK UNIFIED IDEOGRAPH+0x9354 0x5178 #CJK UNIFIED IDEOGRAPH+0x9355 0x586B #CJK UNIFIED IDEOGRAPH+0x9356 0x5929 #CJK UNIFIED IDEOGRAPH+0x9357 0x5C55 #CJK UNIFIED IDEOGRAPH+0x9358 0x5E97 #CJK UNIFIED IDEOGRAPH+0x9359 0x6DFB #CJK UNIFIED IDEOGRAPH+0x935A 0x7E8F #CJK UNIFIED IDEOGRAPH+0x935B 0x751C #CJK UNIFIED IDEOGRAPH+0x935C 0x8CBC #CJK UNIFIED IDEOGRAPH+0x935D 0x8EE2 #CJK UNIFIED IDEOGRAPH+0x935E 0x985B #CJK UNIFIED IDEOGRAPH+0x935F 0x70B9 #CJK UNIFIED IDEOGRAPH+0x9360 0x4F1D #CJK UNIFIED IDEOGRAPH+0x9361 0x6BBF #CJK UNIFIED IDEOGRAPH+0x9362 0x6FB1 #CJK UNIFIED IDEOGRAPH+0x9363 0x7530 #CJK UNIFIED IDEOGRAPH+0x9364 0x96FB #CJK UNIFIED IDEOGRAPH+0x9365 0x514E #CJK UNIFIED IDEOGRAPH+0x9366 0x5410 #CJK UNIFIED IDEOGRAPH+0x9367 0x5835 #CJK UNIFIED IDEOGRAPH+0x9368 0x5857 #CJK UNIFIED IDEOGRAPH+0x9369 0x59AC #CJK UNIFIED IDEOGRAPH+0x936A 0x5C60 #CJK UNIFIED IDEOGRAPH+0x936B 0x5F92 #CJK UNIFIED IDEOGRAPH+0x936C 0x6597 #CJK UNIFIED IDEOGRAPH+0x936D 0x675C #CJK UNIFIED IDEOGRAPH+0x936E 0x6E21 #CJK UNIFIED IDEOGRAPH+0x936F 0x767B #CJK UNIFIED IDEOGRAPH+0x9370 0x83DF #CJK UNIFIED IDEOGRAPH+0x9371 0x8CED #CJK UNIFIED IDEOGRAPH+0x9372 0x9014 #CJK UNIFIED IDEOGRAPH+0x9373 0x90FD #CJK UNIFIED IDEOGRAPH+0x9374 0x934D #CJK UNIFIED IDEOGRAPH+0x9375 0x7825 #CJK UNIFIED IDEOGRAPH+0x9376 0x783A #CJK UNIFIED IDEOGRAPH+0x9377 0x52AA #CJK UNIFIED IDEOGRAPH+0x9378 0x5EA6 #CJK UNIFIED IDEOGRAPH+0x9379 0x571F #CJK UNIFIED IDEOGRAPH+0x937A 0x5974 #CJK UNIFIED IDEOGRAPH+0x937B 0x6012 #CJK UNIFIED IDEOGRAPH+0x937C 0x5012 #CJK UNIFIED IDEOGRAPH+0x937D 0x515A #CJK UNIFIED IDEOGRAPH+0x937E 0x51AC #CJK UNIFIED IDEOGRAPH+0x9380 0x51CD #CJK UNIFIED IDEOGRAPH+0x9381 0x5200 #CJK UNIFIED IDEOGRAPH+0x9382 0x5510 #CJK UNIFIED IDEOGRAPH+0x9383 0x5854 #CJK UNIFIED IDEOGRAPH+0x9384 0x5858 #CJK UNIFIED IDEOGRAPH+0x9385 0x5957 #CJK UNIFIED IDEOGRAPH+0x9386 0x5B95 #CJK UNIFIED IDEOGRAPH+0x9387 0x5CF6 #CJK UNIFIED IDEOGRAPH+0x9388 0x5D8B #CJK UNIFIED IDEOGRAPH+0x9389 0x60BC #CJK UNIFIED IDEOGRAPH+0x938A 0x6295 #CJK UNIFIED IDEOGRAPH+0x938B 0x642D #CJK UNIFIED IDEOGRAPH+0x938C 0x6771 #CJK UNIFIED IDEOGRAPH+0x938D 0x6843 #CJK UNIFIED IDEOGRAPH+0x938E 0x68BC #CJK UNIFIED IDEOGRAPH+0x938F 0x68DF #CJK UNIFIED IDEOGRAPH+0x9390 0x76D7 #CJK UNIFIED IDEOGRAPH+0x9391 0x6DD8 #CJK UNIFIED IDEOGRAPH+0x9392 0x6E6F #CJK UNIFIED IDEOGRAPH+0x9393 0x6D9B #CJK UNIFIED IDEOGRAPH+0x9394 0x706F #CJK UNIFIED IDEOGRAPH+0x9395 0x71C8 #CJK UNIFIED IDEOGRAPH+0x9396 0x5F53 #CJK UNIFIED IDEOGRAPH+0x9397 0x75D8 #CJK UNIFIED IDEOGRAPH+0x9398 0x7977 #CJK UNIFIED IDEOGRAPH+0x9399 0x7B49 #CJK UNIFIED IDEOGRAPH+0x939A 0x7B54 #CJK UNIFIED IDEOGRAPH+0x939B 0x7B52 #CJK UNIFIED IDEOGRAPH+0x939C 0x7CD6 #CJK UNIFIED IDEOGRAPH+0x939D 0x7D71 #CJK UNIFIED IDEOGRAPH+0x939E 0x5230 #CJK UNIFIED IDEOGRAPH+0x939F 0x8463 #CJK UNIFIED IDEOGRAPH+0x93A0 0x8569 #CJK UNIFIED IDEOGRAPH+0x93A1 0x85E4 #CJK UNIFIED IDEOGRAPH+0x93A2 0x8A0E #CJK UNIFIED IDEOGRAPH+0x93A3 0x8B04 #CJK UNIFIED IDEOGRAPH+0x93A4 0x8C46 #CJK UNIFIED IDEOGRAPH+0x93A5 0x8E0F #CJK UNIFIED IDEOGRAPH+0x93A6 0x9003 #CJK UNIFIED IDEOGRAPH+0x93A7 0x900F #CJK UNIFIED IDEOGRAPH+0x93A8 0x9419 #CJK UNIFIED IDEOGRAPH+0x93A9 0x9676 #CJK UNIFIED IDEOGRAPH+0x93AA 0x982D #CJK UNIFIED IDEOGRAPH+0x93AB 0x9A30 #CJK UNIFIED IDEOGRAPH+0x93AC 0x95D8 #CJK UNIFIED IDEOGRAPH+0x93AD 0x50CD #CJK UNIFIED IDEOGRAPH+0x93AE 0x52D5 #CJK UNIFIED IDEOGRAPH+0x93AF 0x540C #CJK UNIFIED IDEOGRAPH+0x93B0 0x5802 #CJK UNIFIED IDEOGRAPH+0x93B1 0x5C0E #CJK UNIFIED IDEOGRAPH+0x93B2 0x61A7 #CJK UNIFIED IDEOGRAPH+0x93B3 0x649E #CJK UNIFIED IDEOGRAPH+0x93B4 0x6D1E #CJK UNIFIED IDEOGRAPH+0x93B5 0x77B3 #CJK UNIFIED IDEOGRAPH+0x93B6 0x7AE5 #CJK UNIFIED IDEOGRAPH+0x93B7 0x80F4 #CJK UNIFIED IDEOGRAPH+0x93B8 0x8404 #CJK UNIFIED IDEOGRAPH+0x93B9 0x9053 #CJK UNIFIED IDEOGRAPH+0x93BA 0x9285 #CJK UNIFIED IDEOGRAPH+0x93BB 0x5CE0 #CJK UNIFIED IDEOGRAPH+0x93BC 0x9D07 #CJK UNIFIED IDEOGRAPH+0x93BD 0x533F #CJK UNIFIED IDEOGRAPH+0x93BE 0x5F97 #CJK UNIFIED IDEOGRAPH+0x93BF 0x5FB3 #CJK UNIFIED IDEOGRAPH+0x93C0 0x6D9C #CJK UNIFIED IDEOGRAPH+0x93C1 0x7279 #CJK UNIFIED IDEOGRAPH+0x93C2 0x7763 #CJK UNIFIED IDEOGRAPH+0x93C3 0x79BF #CJK UNIFIED IDEOGRAPH+0x93C4 0x7BE4 #CJK UNIFIED IDEOGRAPH+0x93C5 0x6BD2 #CJK UNIFIED IDEOGRAPH+0x93C6 0x72EC #CJK UNIFIED IDEOGRAPH+0x93C7 0x8AAD #CJK UNIFIED IDEOGRAPH+0x93C8 0x6803 #CJK UNIFIED IDEOGRAPH+0x93C9 0x6A61 #CJK UNIFIED IDEOGRAPH+0x93CA 0x51F8 #CJK UNIFIED IDEOGRAPH+0x93CB 0x7A81 #CJK UNIFIED IDEOGRAPH+0x93CC 0x6934 #CJK UNIFIED IDEOGRAPH+0x93CD 0x5C4A #CJK UNIFIED IDEOGRAPH+0x93CE 0x9CF6 #CJK UNIFIED IDEOGRAPH+0x93CF 0x82EB #CJK UNIFIED IDEOGRAPH+0x93D0 0x5BC5 #CJK UNIFIED IDEOGRAPH+0x93D1 0x9149 #CJK UNIFIED IDEOGRAPH+0x93D2 0x701E #CJK UNIFIED IDEOGRAPH+0x93D3 0x5678 #CJK UNIFIED IDEOGRAPH+0x93D4 0x5C6F #CJK UNIFIED IDEOGRAPH+0x93D5 0x60C7 #CJK UNIFIED IDEOGRAPH+0x93D6 0x6566 #CJK UNIFIED IDEOGRAPH+0x93D7 0x6C8C #CJK UNIFIED IDEOGRAPH+0x93D8 0x8C5A #CJK UNIFIED IDEOGRAPH+0x93D9 0x9041 #CJK UNIFIED IDEOGRAPH+0x93DA 0x9813 #CJK UNIFIED IDEOGRAPH+0x93DB 0x5451 #CJK UNIFIED IDEOGRAPH+0x93DC 0x66C7 #CJK UNIFIED IDEOGRAPH+0x93DD 0x920D #CJK UNIFIED IDEOGRAPH+0x93DE 0x5948 #CJK UNIFIED IDEOGRAPH+0x93DF 0x90A3 #CJK UNIFIED IDEOGRAPH+0x93E0 0x5185 #CJK UNIFIED IDEOGRAPH+0x93E1 0x4E4D #CJK UNIFIED IDEOGRAPH+0x93E2 0x51EA #CJK UNIFIED IDEOGRAPH+0x93E3 0x8599 #CJK UNIFIED IDEOGRAPH+0x93E4 0x8B0E #CJK UNIFIED IDEOGRAPH+0x93E5 0x7058 #CJK UNIFIED IDEOGRAPH+0x93E6 0x637A #CJK UNIFIED IDEOGRAPH+0x93E7 0x934B #CJK UNIFIED IDEOGRAPH+0x93E8 0x6962 #CJK UNIFIED IDEOGRAPH+0x93E9 0x99B4 #CJK UNIFIED IDEOGRAPH+0x93EA 0x7E04 #CJK UNIFIED IDEOGRAPH+0x93EB 0x7577 #CJK UNIFIED IDEOGRAPH+0x93EC 0x5357 #CJK UNIFIED IDEOGRAPH+0x93ED 0x6960 #CJK UNIFIED IDEOGRAPH+0x93EE 0x8EDF #CJK UNIFIED IDEOGRAPH+0x93EF 0x96E3 #CJK UNIFIED IDEOGRAPH+0x93F0 0x6C5D #CJK UNIFIED IDEOGRAPH+0x93F1 0x4E8C #CJK UNIFIED IDEOGRAPH+0x93F2 0x5C3C #CJK UNIFIED IDEOGRAPH+0x93F3 0x5F10 #CJK UNIFIED IDEOGRAPH+0x93F4 0x8FE9 #CJK UNIFIED IDEOGRAPH+0x93F5 0x5302 #CJK UNIFIED IDEOGRAPH+0x93F6 0x8CD1 #CJK UNIFIED IDEOGRAPH+0x93F7 0x8089 #CJK UNIFIED IDEOGRAPH+0x93F8 0x8679 #CJK UNIFIED IDEOGRAPH+0x93F9 0x5EFF #CJK UNIFIED IDEOGRAPH+0x93FA 0x65E5 #CJK UNIFIED IDEOGRAPH+0x93FB 0x4E73 #CJK UNIFIED IDEOGRAPH+0x93FC 0x5165 #CJK UNIFIED IDEOGRAPH+0x9440 0x5982 #CJK UNIFIED IDEOGRAPH+0x9441 0x5C3F #CJK UNIFIED IDEOGRAPH+0x9442 0x97EE #CJK UNIFIED IDEOGRAPH+0x9443 0x4EFB #CJK UNIFIED IDEOGRAPH+0x9444 0x598A #CJK UNIFIED IDEOGRAPH+0x9445 0x5FCD #CJK UNIFIED IDEOGRAPH+0x9446 0x8A8D #CJK UNIFIED IDEOGRAPH+0x9447 0x6FE1 #CJK UNIFIED IDEOGRAPH+0x9448 0x79B0 #CJK UNIFIED IDEOGRAPH+0x9449 0x7962 #CJK UNIFIED IDEOGRAPH+0x944A 0x5BE7 #CJK UNIFIED IDEOGRAPH+0x944B 0x8471 #CJK UNIFIED IDEOGRAPH+0x944C 0x732B #CJK UNIFIED IDEOGRAPH+0x944D 0x71B1 #CJK UNIFIED IDEOGRAPH+0x944E 0x5E74 #CJK UNIFIED IDEOGRAPH+0x944F 0x5FF5 #CJK UNIFIED IDEOGRAPH+0x9450 0x637B #CJK UNIFIED IDEOGRAPH+0x9451 0x649A #CJK UNIFIED IDEOGRAPH+0x9452 0x71C3 #CJK UNIFIED IDEOGRAPH+0x9453 0x7C98 #CJK UNIFIED IDEOGRAPH+0x9454 0x4E43 #CJK UNIFIED IDEOGRAPH+0x9455 0x5EFC #CJK UNIFIED IDEOGRAPH+0x9456 0x4E4B #CJK UNIFIED IDEOGRAPH+0x9457 0x57DC #CJK UNIFIED IDEOGRAPH+0x9458 0x56A2 #CJK UNIFIED IDEOGRAPH+0x9459 0x60A9 #CJK UNIFIED IDEOGRAPH+0x945A 0x6FC3 #CJK UNIFIED IDEOGRAPH+0x945B 0x7D0D #CJK UNIFIED IDEOGRAPH+0x945C 0x80FD #CJK UNIFIED IDEOGRAPH+0x945D 0x8133 #CJK UNIFIED IDEOGRAPH+0x945E 0x81BF #CJK UNIFIED IDEOGRAPH+0x945F 0x8FB2 #CJK UNIFIED IDEOGRAPH+0x9460 0x8997 #CJK UNIFIED IDEOGRAPH+0x9461 0x86A4 #CJK UNIFIED IDEOGRAPH+0x9462 0x5DF4 #CJK UNIFIED IDEOGRAPH+0x9463 0x628A #CJK UNIFIED IDEOGRAPH+0x9464 0x64AD #CJK UNIFIED IDEOGRAPH+0x9465 0x8987 #CJK UNIFIED IDEOGRAPH+0x9466 0x6777 #CJK UNIFIED IDEOGRAPH+0x9467 0x6CE2 #CJK UNIFIED IDEOGRAPH+0x9468 0x6D3E #CJK UNIFIED IDEOGRAPH+0x9469 0x7436 #CJK UNIFIED IDEOGRAPH+0x946A 0x7834 #CJK UNIFIED IDEOGRAPH+0x946B 0x5A46 #CJK UNIFIED IDEOGRAPH+0x946C 0x7F75 #CJK UNIFIED IDEOGRAPH+0x946D 0x82AD #CJK UNIFIED IDEOGRAPH+0x946E 0x99AC #CJK UNIFIED IDEOGRAPH+0x946F 0x4FF3 #CJK UNIFIED IDEOGRAPH+0x9470 0x5EC3 #CJK UNIFIED IDEOGRAPH+0x9471 0x62DD #CJK UNIFIED IDEOGRAPH+0x9472 0x6392 #CJK UNIFIED IDEOGRAPH+0x9473 0x6557 #CJK UNIFIED IDEOGRAPH+0x9474 0x676F #CJK UNIFIED IDEOGRAPH+0x9475 0x76C3 #CJK UNIFIED IDEOGRAPH+0x9476 0x724C #CJK UNIFIED IDEOGRAPH+0x9477 0x80CC #CJK UNIFIED IDEOGRAPH+0x9478 0x80BA #CJK UNIFIED IDEOGRAPH+0x9479 0x8F29 #CJK UNIFIED IDEOGRAPH+0x947A 0x914D #CJK UNIFIED IDEOGRAPH+0x947B 0x500D #CJK UNIFIED IDEOGRAPH+0x947C 0x57F9 #CJK UNIFIED IDEOGRAPH+0x947D 0x5A92 #CJK UNIFIED IDEOGRAPH+0x947E 0x6885 #CJK UNIFIED IDEOGRAPH+0x9480 0x6973 #CJK UNIFIED IDEOGRAPH+0x9481 0x7164 #CJK UNIFIED IDEOGRAPH+0x9482 0x72FD #CJK UNIFIED IDEOGRAPH+0x9483 0x8CB7 #CJK UNIFIED IDEOGRAPH+0x9484 0x58F2 #CJK UNIFIED IDEOGRAPH+0x9485 0x8CE0 #CJK UNIFIED IDEOGRAPH+0x9486 0x966A #CJK UNIFIED IDEOGRAPH+0x9487 0x9019 #CJK UNIFIED IDEOGRAPH+0x9488 0x877F #CJK UNIFIED IDEOGRAPH+0x9489 0x79E4 #CJK UNIFIED IDEOGRAPH+0x948A 0x77E7 #CJK UNIFIED IDEOGRAPH+0x948B 0x8429 #CJK UNIFIED IDEOGRAPH+0x948C 0x4F2F #CJK UNIFIED IDEOGRAPH+0x948D 0x5265 #CJK UNIFIED IDEOGRAPH+0x948E 0x535A #CJK UNIFIED IDEOGRAPH+0x948F 0x62CD #CJK UNIFIED IDEOGRAPH+0x9490 0x67CF #CJK UNIFIED IDEOGRAPH+0x9491 0x6CCA #CJK UNIFIED IDEOGRAPH+0x9492 0x767D #CJK UNIFIED IDEOGRAPH+0x9493 0x7B94 #CJK UNIFIED IDEOGRAPH+0x9494 0x7C95 #CJK UNIFIED IDEOGRAPH+0x9495 0x8236 #CJK UNIFIED IDEOGRAPH+0x9496 0x8584 #CJK UNIFIED IDEOGRAPH+0x9497 0x8FEB #CJK UNIFIED IDEOGRAPH+0x9498 0x66DD #CJK UNIFIED IDEOGRAPH+0x9499 0x6F20 #CJK UNIFIED IDEOGRAPH+0x949A 0x7206 #CJK UNIFIED IDEOGRAPH+0x949B 0x7E1B #CJK UNIFIED IDEOGRAPH+0x949C 0x83AB #CJK UNIFIED IDEOGRAPH+0x949D 0x99C1 #CJK UNIFIED IDEOGRAPH+0x949E 0x9EA6 #CJK UNIFIED IDEOGRAPH+0x949F 0x51FD #CJK UNIFIED IDEOGRAPH+0x94A0 0x7BB1 #CJK UNIFIED IDEOGRAPH+0x94A1 0x7872 #CJK UNIFIED IDEOGRAPH+0x94A2 0x7BB8 #CJK UNIFIED IDEOGRAPH+0x94A3 0x8087 #CJK UNIFIED IDEOGRAPH+0x94A4 0x7B48 #CJK UNIFIED IDEOGRAPH+0x94A5 0x6AE8 #CJK UNIFIED IDEOGRAPH+0x94A6 0x5E61 #CJK UNIFIED IDEOGRAPH+0x94A7 0x808C #CJK UNIFIED IDEOGRAPH+0x94A8 0x7551 #CJK UNIFIED IDEOGRAPH+0x94A9 0x7560 #CJK UNIFIED IDEOGRAPH+0x94AA 0x516B #CJK UNIFIED IDEOGRAPH+0x94AB 0x9262 #CJK UNIFIED IDEOGRAPH+0x94AC 0x6E8C #CJK UNIFIED IDEOGRAPH+0x94AD 0x767A #CJK UNIFIED IDEOGRAPH+0x94AE 0x9197 #CJK UNIFIED IDEOGRAPH+0x94AF 0x9AEA #CJK UNIFIED IDEOGRAPH+0x94B0 0x4F10 #CJK UNIFIED IDEOGRAPH+0x94B1 0x7F70 #CJK UNIFIED IDEOGRAPH+0x94B2 0x629C #CJK UNIFIED IDEOGRAPH+0x94B3 0x7B4F #CJK UNIFIED IDEOGRAPH+0x94B4 0x95A5 #CJK UNIFIED IDEOGRAPH+0x94B5 0x9CE9 #CJK UNIFIED IDEOGRAPH+0x94B6 0x567A #CJK UNIFIED IDEOGRAPH+0x94B7 0x5859 #CJK UNIFIED IDEOGRAPH+0x94B8 0x86E4 #CJK UNIFIED IDEOGRAPH+0x94B9 0x96BC #CJK UNIFIED IDEOGRAPH+0x94BA 0x4F34 #CJK UNIFIED IDEOGRAPH+0x94BB 0x5224 #CJK UNIFIED IDEOGRAPH+0x94BC 0x534A #CJK UNIFIED IDEOGRAPH+0x94BD 0x53CD #CJK UNIFIED IDEOGRAPH+0x94BE 0x53DB #CJK UNIFIED IDEOGRAPH+0x94BF 0x5E06 #CJK UNIFIED IDEOGRAPH+0x94C0 0x642C #CJK UNIFIED IDEOGRAPH+0x94C1 0x6591 #CJK UNIFIED IDEOGRAPH+0x94C2 0x677F #CJK UNIFIED IDEOGRAPH+0x94C3 0x6C3E #CJK UNIFIED IDEOGRAPH+0x94C4 0x6C4E #CJK UNIFIED IDEOGRAPH+0x94C5 0x7248 #CJK UNIFIED IDEOGRAPH+0x94C6 0x72AF #CJK UNIFIED IDEOGRAPH+0x94C7 0x73ED #CJK UNIFIED IDEOGRAPH+0x94C8 0x7554 #CJK UNIFIED IDEOGRAPH+0x94C9 0x7E41 #CJK UNIFIED IDEOGRAPH+0x94CA 0x822C #CJK UNIFIED IDEOGRAPH+0x94CB 0x85E9 #CJK UNIFIED IDEOGRAPH+0x94CC 0x8CA9 #CJK UNIFIED IDEOGRAPH+0x94CD 0x7BC4 #CJK UNIFIED IDEOGRAPH+0x94CE 0x91C6 #CJK UNIFIED IDEOGRAPH+0x94CF 0x7169 #CJK UNIFIED IDEOGRAPH+0x94D0 0x9812 #CJK UNIFIED IDEOGRAPH+0x94D1 0x98EF #CJK UNIFIED IDEOGRAPH+0x94D2 0x633D #CJK UNIFIED IDEOGRAPH+0x94D3 0x6669 #CJK UNIFIED IDEOGRAPH+0x94D4 0x756A #CJK UNIFIED IDEOGRAPH+0x94D5 0x76E4 #CJK UNIFIED IDEOGRAPH+0x94D6 0x78D0 #CJK UNIFIED IDEOGRAPH+0x94D7 0x8543 #CJK UNIFIED IDEOGRAPH+0x94D8 0x86EE #CJK UNIFIED IDEOGRAPH+0x94D9 0x532A #CJK UNIFIED IDEOGRAPH+0x94DA 0x5351 #CJK UNIFIED IDEOGRAPH+0x94DB 0x5426 #CJK UNIFIED IDEOGRAPH+0x94DC 0x5983 #CJK UNIFIED IDEOGRAPH+0x94DD 0x5E87 #CJK UNIFIED IDEOGRAPH+0x94DE 0x5F7C #CJK UNIFIED IDEOGRAPH+0x94DF 0x60B2 #CJK UNIFIED IDEOGRAPH+0x94E0 0x6249 #CJK UNIFIED IDEOGRAPH+0x94E1 0x6279 #CJK UNIFIED IDEOGRAPH+0x94E2 0x62AB #CJK UNIFIED IDEOGRAPH+0x94E3 0x6590 #CJK UNIFIED IDEOGRAPH+0x94E4 0x6BD4 #CJK UNIFIED IDEOGRAPH+0x94E5 0x6CCC #CJK UNIFIED IDEOGRAPH+0x94E6 0x75B2 #CJK UNIFIED IDEOGRAPH+0x94E7 0x76AE #CJK UNIFIED IDEOGRAPH+0x94E8 0x7891 #CJK UNIFIED IDEOGRAPH+0x94E9 0x79D8 #CJK UNIFIED IDEOGRAPH+0x94EA 0x7DCB #CJK UNIFIED IDEOGRAPH+0x94EB 0x7F77 #CJK UNIFIED IDEOGRAPH+0x94EC 0x80A5 #CJK UNIFIED IDEOGRAPH+0x94ED 0x88AB #CJK UNIFIED IDEOGRAPH+0x94EE 0x8AB9 #CJK UNIFIED IDEOGRAPH+0x94EF 0x8CBB #CJK UNIFIED IDEOGRAPH+0x94F0 0x907F #CJK UNIFIED IDEOGRAPH+0x94F1 0x975E #CJK UNIFIED IDEOGRAPH+0x94F2 0x98DB #CJK UNIFIED IDEOGRAPH+0x94F3 0x6A0B #CJK UNIFIED IDEOGRAPH+0x94F4 0x7C38 #CJK UNIFIED IDEOGRAPH+0x94F5 0x5099 #CJK UNIFIED IDEOGRAPH+0x94F6 0x5C3E #CJK UNIFIED IDEOGRAPH+0x94F7 0x5FAE #CJK UNIFIED IDEOGRAPH+0x94F8 0x6787 #CJK UNIFIED IDEOGRAPH+0x94F9 0x6BD8 #CJK UNIFIED IDEOGRAPH+0x94FA 0x7435 #CJK UNIFIED IDEOGRAPH+0x94FB 0x7709 #CJK UNIFIED IDEOGRAPH+0x94FC 0x7F8E #CJK UNIFIED IDEOGRAPH+0x9540 0x9F3B #CJK UNIFIED IDEOGRAPH+0x9541 0x67CA #CJK UNIFIED IDEOGRAPH+0x9542 0x7A17 #CJK UNIFIED IDEOGRAPH+0x9543 0x5339 #CJK UNIFIED IDEOGRAPH+0x9544 0x758B #CJK UNIFIED IDEOGRAPH+0x9545 0x9AED #CJK UNIFIED IDEOGRAPH+0x9546 0x5F66 #CJK UNIFIED IDEOGRAPH+0x9547 0x819D #CJK UNIFIED IDEOGRAPH+0x9548 0x83F1 #CJK UNIFIED IDEOGRAPH+0x9549 0x8098 #CJK UNIFIED IDEOGRAPH+0x954A 0x5F3C #CJK UNIFIED IDEOGRAPH+0x954B 0x5FC5 #CJK UNIFIED IDEOGRAPH+0x954C 0x7562 #CJK UNIFIED IDEOGRAPH+0x954D 0x7B46 #CJK UNIFIED IDEOGRAPH+0x954E 0x903C #CJK UNIFIED IDEOGRAPH+0x954F 0x6867 #CJK UNIFIED IDEOGRAPH+0x9550 0x59EB #CJK UNIFIED IDEOGRAPH+0x9551 0x5A9B #CJK UNIFIED IDEOGRAPH+0x9552 0x7D10 #CJK UNIFIED IDEOGRAPH+0x9553 0x767E #CJK UNIFIED IDEOGRAPH+0x9554 0x8B2C #CJK UNIFIED IDEOGRAPH+0x9555 0x4FF5 #CJK UNIFIED IDEOGRAPH+0x9556 0x5F6A #CJK UNIFIED IDEOGRAPH+0x9557 0x6A19 #CJK UNIFIED IDEOGRAPH+0x9558 0x6C37 #CJK UNIFIED IDEOGRAPH+0x9559 0x6F02 #CJK UNIFIED IDEOGRAPH+0x955A 0x74E2 #CJK UNIFIED IDEOGRAPH+0x955B 0x7968 #CJK UNIFIED IDEOGRAPH+0x955C 0x8868 #CJK UNIFIED IDEOGRAPH+0x955D 0x8A55 #CJK UNIFIED IDEOGRAPH+0x955E 0x8C79 #CJK UNIFIED IDEOGRAPH+0x955F 0x5EDF #CJK UNIFIED IDEOGRAPH+0x9560 0x63CF #CJK UNIFIED IDEOGRAPH+0x9561 0x75C5 #CJK UNIFIED IDEOGRAPH+0x9562 0x79D2 #CJK UNIFIED IDEOGRAPH+0x9563 0x82D7 #CJK UNIFIED IDEOGRAPH+0x9564 0x9328 #CJK UNIFIED IDEOGRAPH+0x9565 0x92F2 #CJK UNIFIED IDEOGRAPH+0x9566 0x849C #CJK UNIFIED IDEOGRAPH+0x9567 0x86ED #CJK UNIFIED IDEOGRAPH+0x9568 0x9C2D #CJK UNIFIED IDEOGRAPH+0x9569 0x54C1 #CJK UNIFIED IDEOGRAPH+0x956A 0x5F6C #CJK UNIFIED IDEOGRAPH+0x956B 0x658C #CJK UNIFIED IDEOGRAPH+0x956C 0x6D5C #CJK UNIFIED IDEOGRAPH+0x956D 0x7015 #CJK UNIFIED IDEOGRAPH+0x956E 0x8CA7 #CJK UNIFIED IDEOGRAPH+0x956F 0x8CD3 #CJK UNIFIED IDEOGRAPH+0x9570 0x983B #CJK UNIFIED IDEOGRAPH+0x9571 0x654F #CJK UNIFIED IDEOGRAPH+0x9572 0x74F6 #CJK UNIFIED IDEOGRAPH+0x9573 0x4E0D #CJK UNIFIED IDEOGRAPH+0x9574 0x4ED8 #CJK UNIFIED IDEOGRAPH+0x9575 0x57E0 #CJK UNIFIED IDEOGRAPH+0x9576 0x592B #CJK UNIFIED IDEOGRAPH+0x9577 0x5A66 #CJK UNIFIED IDEOGRAPH+0x9578 0x5BCC #CJK UNIFIED IDEOGRAPH+0x9579 0x51A8 #CJK UNIFIED IDEOGRAPH+0x957A 0x5E03 #CJK UNIFIED IDEOGRAPH+0x957B 0x5E9C #CJK UNIFIED IDEOGRAPH+0x957C 0x6016 #CJK UNIFIED IDEOGRAPH+0x957D 0x6276 #CJK UNIFIED IDEOGRAPH+0x957E 0x6577 #CJK UNIFIED IDEOGRAPH+0x9580 0x65A7 #CJK UNIFIED IDEOGRAPH+0x9581 0x666E #CJK UNIFIED IDEOGRAPH+0x9582 0x6D6E #CJK UNIFIED IDEOGRAPH+0x9583 0x7236 #CJK UNIFIED IDEOGRAPH+0x9584 0x7B26 #CJK UNIFIED IDEOGRAPH+0x9585 0x8150 #CJK UNIFIED IDEOGRAPH+0x9586 0x819A #CJK UNIFIED IDEOGRAPH+0x9587 0x8299 #CJK UNIFIED IDEOGRAPH+0x9588 0x8B5C #CJK UNIFIED IDEOGRAPH+0x9589 0x8CA0 #CJK UNIFIED IDEOGRAPH+0x958A 0x8CE6 #CJK UNIFIED IDEOGRAPH+0x958B 0x8D74 #CJK UNIFIED IDEOGRAPH+0x958C 0x961C #CJK UNIFIED IDEOGRAPH+0x958D 0x9644 #CJK UNIFIED IDEOGRAPH+0x958E 0x4FAE #CJK UNIFIED IDEOGRAPH+0x958F 0x64AB #CJK UNIFIED IDEOGRAPH+0x9590 0x6B66 #CJK UNIFIED IDEOGRAPH+0x9591 0x821E #CJK UNIFIED IDEOGRAPH+0x9592 0x8461 #CJK UNIFIED IDEOGRAPH+0x9593 0x856A #CJK UNIFIED IDEOGRAPH+0x9594 0x90E8 #CJK UNIFIED IDEOGRAPH+0x9595 0x5C01 #CJK UNIFIED IDEOGRAPH+0x9596 0x6953 #CJK UNIFIED IDEOGRAPH+0x9597 0x98A8 #CJK UNIFIED IDEOGRAPH+0x9598 0x847A #CJK UNIFIED IDEOGRAPH+0x9599 0x8557 #CJK UNIFIED IDEOGRAPH+0x959A 0x4F0F #CJK UNIFIED IDEOGRAPH+0x959B 0x526F #CJK UNIFIED IDEOGRAPH+0x959C 0x5FA9 #CJK UNIFIED IDEOGRAPH+0x959D 0x5E45 #CJK UNIFIED IDEOGRAPH+0x959E 0x670D #CJK UNIFIED IDEOGRAPH+0x959F 0x798F #CJK UNIFIED IDEOGRAPH+0x95A0 0x8179 #CJK UNIFIED IDEOGRAPH+0x95A1 0x8907 #CJK UNIFIED IDEOGRAPH+0x95A2 0x8986 #CJK UNIFIED IDEOGRAPH+0x95A3 0x6DF5 #CJK UNIFIED IDEOGRAPH+0x95A4 0x5F17 #CJK UNIFIED IDEOGRAPH+0x95A5 0x6255 #CJK UNIFIED IDEOGRAPH+0x95A6 0x6CB8 #CJK UNIFIED IDEOGRAPH+0x95A7 0x4ECF #CJK UNIFIED IDEOGRAPH+0x95A8 0x7269 #CJK UNIFIED IDEOGRAPH+0x95A9 0x9B92 #CJK UNIFIED IDEOGRAPH+0x95AA 0x5206 #CJK UNIFIED IDEOGRAPH+0x95AB 0x543B #CJK UNIFIED IDEOGRAPH+0x95AC 0x5674 #CJK UNIFIED IDEOGRAPH+0x95AD 0x58B3 #CJK UNIFIED IDEOGRAPH+0x95AE 0x61A4 #CJK UNIFIED IDEOGRAPH+0x95AF 0x626E #CJK UNIFIED IDEOGRAPH+0x95B0 0x711A #CJK UNIFIED IDEOGRAPH+0x95B1 0x596E #CJK UNIFIED IDEOGRAPH+0x95B2 0x7C89 #CJK UNIFIED IDEOGRAPH+0x95B3 0x7CDE #CJK UNIFIED IDEOGRAPH+0x95B4 0x7D1B #CJK UNIFIED IDEOGRAPH+0x95B5 0x96F0 #CJK UNIFIED IDEOGRAPH+0x95B6 0x6587 #CJK UNIFIED IDEOGRAPH+0x95B7 0x805E #CJK UNIFIED IDEOGRAPH+0x95B8 0x4E19 #CJK UNIFIED IDEOGRAPH+0x95B9 0x4F75 #CJK UNIFIED IDEOGRAPH+0x95BA 0x5175 #CJK UNIFIED IDEOGRAPH+0x95BB 0x5840 #CJK UNIFIED IDEOGRAPH+0x95BC 0x5E63 #CJK UNIFIED IDEOGRAPH+0x95BD 0x5E73 #CJK UNIFIED IDEOGRAPH+0x95BE 0x5F0A #CJK UNIFIED IDEOGRAPH+0x95BF 0x67C4 #CJK UNIFIED IDEOGRAPH+0x95C0 0x4E26 #CJK UNIFIED IDEOGRAPH+0x95C1 0x853D #CJK UNIFIED IDEOGRAPH+0x95C2 0x9589 #CJK UNIFIED IDEOGRAPH+0x95C3 0x965B #CJK UNIFIED IDEOGRAPH+0x95C4 0x7C73 #CJK UNIFIED IDEOGRAPH+0x95C5 0x9801 #CJK UNIFIED IDEOGRAPH+0x95C6 0x50FB #CJK UNIFIED IDEOGRAPH+0x95C7 0x58C1 #CJK UNIFIED IDEOGRAPH+0x95C8 0x7656 #CJK UNIFIED IDEOGRAPH+0x95C9 0x78A7 #CJK UNIFIED IDEOGRAPH+0x95CA 0x5225 #CJK UNIFIED IDEOGRAPH+0x95CB 0x77A5 #CJK UNIFIED IDEOGRAPH+0x95CC 0x8511 #CJK UNIFIED IDEOGRAPH+0x95CD 0x7B86 #CJK UNIFIED IDEOGRAPH+0x95CE 0x504F #CJK UNIFIED IDEOGRAPH+0x95CF 0x5909 #CJK UNIFIED IDEOGRAPH+0x95D0 0x7247 #CJK UNIFIED IDEOGRAPH+0x95D1 0x7BC7 #CJK UNIFIED IDEOGRAPH+0x95D2 0x7DE8 #CJK UNIFIED IDEOGRAPH+0x95D3 0x8FBA #CJK UNIFIED IDEOGRAPH+0x95D4 0x8FD4 #CJK UNIFIED IDEOGRAPH+0x95D5 0x904D #CJK UNIFIED IDEOGRAPH+0x95D6 0x4FBF #CJK UNIFIED IDEOGRAPH+0x95D7 0x52C9 #CJK UNIFIED IDEOGRAPH+0x95D8 0x5A29 #CJK UNIFIED IDEOGRAPH+0x95D9 0x5F01 #CJK UNIFIED IDEOGRAPH+0x95DA 0x97AD #CJK UNIFIED IDEOGRAPH+0x95DB 0x4FDD #CJK UNIFIED IDEOGRAPH+0x95DC 0x8217 #CJK UNIFIED IDEOGRAPH+0x95DD 0x92EA #CJK UNIFIED IDEOGRAPH+0x95DE 0x5703 #CJK UNIFIED IDEOGRAPH+0x95DF 0x6355 #CJK UNIFIED IDEOGRAPH+0x95E0 0x6B69 #CJK UNIFIED IDEOGRAPH+0x95E1 0x752B #CJK UNIFIED IDEOGRAPH+0x95E2 0x88DC #CJK UNIFIED IDEOGRAPH+0x95E3 0x8F14 #CJK UNIFIED IDEOGRAPH+0x95E4 0x7A42 #CJK UNIFIED IDEOGRAPH+0x95E5 0x52DF #CJK UNIFIED IDEOGRAPH+0x95E6 0x5893 #CJK UNIFIED IDEOGRAPH+0x95E7 0x6155 #CJK UNIFIED IDEOGRAPH+0x95E8 0x620A #CJK UNIFIED IDEOGRAPH+0x95E9 0x66AE #CJK UNIFIED IDEOGRAPH+0x95EA 0x6BCD #CJK UNIFIED IDEOGRAPH+0x95EB 0x7C3F #CJK UNIFIED IDEOGRAPH+0x95EC 0x83E9 #CJK UNIFIED IDEOGRAPH+0x95ED 0x5023 #CJK UNIFIED IDEOGRAPH+0x95EE 0x4FF8 #CJK UNIFIED IDEOGRAPH+0x95EF 0x5305 #CJK UNIFIED IDEOGRAPH+0x95F0 0x5446 #CJK UNIFIED IDEOGRAPH+0x95F1 0x5831 #CJK UNIFIED IDEOGRAPH+0x95F2 0x5949 #CJK UNIFIED IDEOGRAPH+0x95F3 0x5B9D #CJK UNIFIED IDEOGRAPH+0x95F4 0x5CF0 #CJK UNIFIED IDEOGRAPH+0x95F5 0x5CEF #CJK UNIFIED IDEOGRAPH+0x95F6 0x5D29 #CJK UNIFIED IDEOGRAPH+0x95F7 0x5E96 #CJK UNIFIED IDEOGRAPH+0x95F8 0x62B1 #CJK UNIFIED IDEOGRAPH+0x95F9 0x6367 #CJK UNIFIED IDEOGRAPH+0x95FA 0x653E #CJK UNIFIED IDEOGRAPH+0x95FB 0x65B9 #CJK UNIFIED IDEOGRAPH+0x95FC 0x670B #CJK UNIFIED IDEOGRAPH+0x9640 0x6CD5 #CJK UNIFIED IDEOGRAPH+0x9641 0x6CE1 #CJK UNIFIED IDEOGRAPH+0x9642 0x70F9 #CJK UNIFIED IDEOGRAPH+0x9643 0x7832 #CJK UNIFIED IDEOGRAPH+0x9644 0x7E2B #CJK UNIFIED IDEOGRAPH+0x9645 0x80DE #CJK UNIFIED IDEOGRAPH+0x9646 0x82B3 #CJK UNIFIED IDEOGRAPH+0x9647 0x840C #CJK UNIFIED IDEOGRAPH+0x9648 0x84EC #CJK UNIFIED IDEOGRAPH+0x9649 0x8702 #CJK UNIFIED IDEOGRAPH+0x964A 0x8912 #CJK UNIFIED IDEOGRAPH+0x964B 0x8A2A #CJK UNIFIED IDEOGRAPH+0x964C 0x8C4A #CJK UNIFIED IDEOGRAPH+0x964D 0x90A6 #CJK UNIFIED IDEOGRAPH+0x964E 0x92D2 #CJK UNIFIED IDEOGRAPH+0x964F 0x98FD #CJK UNIFIED IDEOGRAPH+0x9650 0x9CF3 #CJK UNIFIED IDEOGRAPH+0x9651 0x9D6C #CJK UNIFIED IDEOGRAPH+0x9652 0x4E4F #CJK UNIFIED IDEOGRAPH+0x9653 0x4EA1 #CJK UNIFIED IDEOGRAPH+0x9654 0x508D #CJK UNIFIED IDEOGRAPH+0x9655 0x5256 #CJK UNIFIED IDEOGRAPH+0x9656 0x574A #CJK UNIFIED IDEOGRAPH+0x9657 0x59A8 #CJK UNIFIED IDEOGRAPH+0x9658 0x5E3D #CJK UNIFIED IDEOGRAPH+0x9659 0x5FD8 #CJK UNIFIED IDEOGRAPH+0x965A 0x5FD9 #CJK UNIFIED IDEOGRAPH+0x965B 0x623F #CJK UNIFIED IDEOGRAPH+0x965C 0x66B4 #CJK UNIFIED IDEOGRAPH+0x965D 0x671B #CJK UNIFIED IDEOGRAPH+0x965E 0x67D0 #CJK UNIFIED IDEOGRAPH+0x965F 0x68D2 #CJK UNIFIED IDEOGRAPH+0x9660 0x5192 #CJK UNIFIED IDEOGRAPH+0x9661 0x7D21 #CJK UNIFIED IDEOGRAPH+0x9662 0x80AA #CJK UNIFIED IDEOGRAPH+0x9663 0x81A8 #CJK UNIFIED IDEOGRAPH+0x9664 0x8B00 #CJK UNIFIED IDEOGRAPH+0x9665 0x8C8C #CJK UNIFIED IDEOGRAPH+0x9666 0x8CBF #CJK UNIFIED IDEOGRAPH+0x9667 0x927E #CJK UNIFIED IDEOGRAPH+0x9668 0x9632 #CJK UNIFIED IDEOGRAPH+0x9669 0x5420 #CJK UNIFIED IDEOGRAPH+0x966A 0x982C #CJK UNIFIED IDEOGRAPH+0x966B 0x5317 #CJK UNIFIED IDEOGRAPH+0x966C 0x50D5 #CJK UNIFIED IDEOGRAPH+0x966D 0x535C #CJK UNIFIED IDEOGRAPH+0x966E 0x58A8 #CJK UNIFIED IDEOGRAPH+0x966F 0x64B2 #CJK UNIFIED IDEOGRAPH+0x9670 0x6734 #CJK UNIFIED IDEOGRAPH+0x9671 0x7267 #CJK UNIFIED IDEOGRAPH+0x9672 0x7766 #CJK UNIFIED IDEOGRAPH+0x9673 0x7A46 #CJK UNIFIED IDEOGRAPH+0x9674 0x91E6 #CJK UNIFIED IDEOGRAPH+0x9675 0x52C3 #CJK UNIFIED IDEOGRAPH+0x9676 0x6CA1 #CJK UNIFIED IDEOGRAPH+0x9677 0x6B86 #CJK UNIFIED IDEOGRAPH+0x9678 0x5800 #CJK UNIFIED IDEOGRAPH+0x9679 0x5E4C #CJK UNIFIED IDEOGRAPH+0x967A 0x5954 #CJK UNIFIED IDEOGRAPH+0x967B 0x672C #CJK UNIFIED IDEOGRAPH+0x967C 0x7FFB #CJK UNIFIED IDEOGRAPH+0x967D 0x51E1 #CJK UNIFIED IDEOGRAPH+0x967E 0x76C6 #CJK UNIFIED IDEOGRAPH+0x9680 0x6469 #CJK UNIFIED IDEOGRAPH+0x9681 0x78E8 #CJK UNIFIED IDEOGRAPH+0x9682 0x9B54 #CJK UNIFIED IDEOGRAPH+0x9683 0x9EBB #CJK UNIFIED IDEOGRAPH+0x9684 0x57CB #CJK UNIFIED IDEOGRAPH+0x9685 0x59B9 #CJK UNIFIED IDEOGRAPH+0x9686 0x6627 #CJK UNIFIED IDEOGRAPH+0x9687 0x679A #CJK UNIFIED IDEOGRAPH+0x9688 0x6BCE #CJK UNIFIED IDEOGRAPH+0x9689 0x54E9 #CJK UNIFIED IDEOGRAPH+0x968A 0x69D9 #CJK UNIFIED IDEOGRAPH+0x968B 0x5E55 #CJK UNIFIED IDEOGRAPH+0x968C 0x819C #CJK UNIFIED IDEOGRAPH+0x968D 0x6795 #CJK UNIFIED IDEOGRAPH+0x968E 0x9BAA #CJK UNIFIED IDEOGRAPH+0x968F 0x67FE #CJK UNIFIED IDEOGRAPH+0x9690 0x9C52 #CJK UNIFIED IDEOGRAPH+0x9691 0x685D #CJK UNIFIED IDEOGRAPH+0x9692 0x4EA6 #CJK UNIFIED IDEOGRAPH+0x9693 0x4FE3 #CJK UNIFIED IDEOGRAPH+0x9694 0x53C8 #CJK UNIFIED IDEOGRAPH+0x9695 0x62B9 #CJK UNIFIED IDEOGRAPH+0x9696 0x672B #CJK UNIFIED IDEOGRAPH+0x9697 0x6CAB #CJK UNIFIED IDEOGRAPH+0x9698 0x8FC4 #CJK UNIFIED IDEOGRAPH+0x9699 0x4FAD #CJK UNIFIED IDEOGRAPH+0x969A 0x7E6D #CJK UNIFIED IDEOGRAPH+0x969B 0x9EBF #CJK UNIFIED IDEOGRAPH+0x969C 0x4E07 #CJK UNIFIED IDEOGRAPH+0x969D 0x6162 #CJK UNIFIED IDEOGRAPH+0x969E 0x6E80 #CJK UNIFIED IDEOGRAPH+0x969F 0x6F2B #CJK UNIFIED IDEOGRAPH+0x96A0 0x8513 #CJK UNIFIED IDEOGRAPH+0x96A1 0x5473 #CJK UNIFIED IDEOGRAPH+0x96A2 0x672A #CJK UNIFIED IDEOGRAPH+0x96A3 0x9B45 #CJK UNIFIED IDEOGRAPH+0x96A4 0x5DF3 #CJK UNIFIED IDEOGRAPH+0x96A5 0x7B95 #CJK UNIFIED IDEOGRAPH+0x96A6 0x5CAC #CJK UNIFIED IDEOGRAPH+0x96A7 0x5BC6 #CJK UNIFIED IDEOGRAPH+0x96A8 0x871C #CJK UNIFIED IDEOGRAPH+0x96A9 0x6E4A #CJK UNIFIED IDEOGRAPH+0x96AA 0x84D1 #CJK UNIFIED IDEOGRAPH+0x96AB 0x7A14 #CJK UNIFIED IDEOGRAPH+0x96AC 0x8108 #CJK UNIFIED IDEOGRAPH+0x96AD 0x5999 #CJK UNIFIED IDEOGRAPH+0x96AE 0x7C8D #CJK UNIFIED IDEOGRAPH+0x96AF 0x6C11 #CJK UNIFIED IDEOGRAPH+0x96B0 0x7720 #CJK UNIFIED IDEOGRAPH+0x96B1 0x52D9 #CJK UNIFIED IDEOGRAPH+0x96B2 0x5922 #CJK UNIFIED IDEOGRAPH+0x96B3 0x7121 #CJK UNIFIED IDEOGRAPH+0x96B4 0x725F #CJK UNIFIED IDEOGRAPH+0x96B5 0x77DB #CJK UNIFIED IDEOGRAPH+0x96B6 0x9727 #CJK UNIFIED IDEOGRAPH+0x96B7 0x9D61 #CJK UNIFIED IDEOGRAPH+0x96B8 0x690B #CJK UNIFIED IDEOGRAPH+0x96B9 0x5A7F #CJK UNIFIED IDEOGRAPH+0x96BA 0x5A18 #CJK UNIFIED IDEOGRAPH+0x96BB 0x51A5 #CJK UNIFIED IDEOGRAPH+0x96BC 0x540D #CJK UNIFIED IDEOGRAPH+0x96BD 0x547D #CJK UNIFIED IDEOGRAPH+0x96BE 0x660E #CJK UNIFIED IDEOGRAPH+0x96BF 0x76DF #CJK UNIFIED IDEOGRAPH+0x96C0 0x8FF7 #CJK UNIFIED IDEOGRAPH+0x96C1 0x9298 #CJK UNIFIED IDEOGRAPH+0x96C2 0x9CF4 #CJK UNIFIED IDEOGRAPH+0x96C3 0x59EA #CJK UNIFIED IDEOGRAPH+0x96C4 0x725D #CJK UNIFIED IDEOGRAPH+0x96C5 0x6EC5 #CJK UNIFIED IDEOGRAPH+0x96C6 0x514D #CJK UNIFIED IDEOGRAPH+0x96C7 0x68C9 #CJK UNIFIED IDEOGRAPH+0x96C8 0x7DBF #CJK UNIFIED IDEOGRAPH+0x96C9 0x7DEC #CJK UNIFIED IDEOGRAPH+0x96CA 0x9762 #CJK UNIFIED IDEOGRAPH+0x96CB 0x9EBA #CJK UNIFIED IDEOGRAPH+0x96CC 0x6478 #CJK UNIFIED IDEOGRAPH+0x96CD 0x6A21 #CJK UNIFIED IDEOGRAPH+0x96CE 0x8302 #CJK UNIFIED IDEOGRAPH+0x96CF 0x5984 #CJK UNIFIED IDEOGRAPH+0x96D0 0x5B5F #CJK UNIFIED IDEOGRAPH+0x96D1 0x6BDB #CJK UNIFIED IDEOGRAPH+0x96D2 0x731B #CJK UNIFIED IDEOGRAPH+0x96D3 0x76F2 #CJK UNIFIED IDEOGRAPH+0x96D4 0x7DB2 #CJK UNIFIED IDEOGRAPH+0x96D5 0x8017 #CJK UNIFIED IDEOGRAPH+0x96D6 0x8499 #CJK UNIFIED IDEOGRAPH+0x96D7 0x5132 #CJK UNIFIED IDEOGRAPH+0x96D8 0x6728 #CJK UNIFIED IDEOGRAPH+0x96D9 0x9ED9 #CJK UNIFIED IDEOGRAPH+0x96DA 0x76EE #CJK UNIFIED IDEOGRAPH+0x96DB 0x6762 #CJK UNIFIED IDEOGRAPH+0x96DC 0x52FF #CJK UNIFIED IDEOGRAPH+0x96DD 0x9905 #CJK UNIFIED IDEOGRAPH+0x96DE 0x5C24 #CJK UNIFIED IDEOGRAPH+0x96DF 0x623B #CJK UNIFIED IDEOGRAPH+0x96E0 0x7C7E #CJK UNIFIED IDEOGRAPH+0x96E1 0x8CB0 #CJK UNIFIED IDEOGRAPH+0x96E2 0x554F #CJK UNIFIED IDEOGRAPH+0x96E3 0x60B6 #CJK UNIFIED IDEOGRAPH+0x96E4 0x7D0B #CJK UNIFIED IDEOGRAPH+0x96E5 0x9580 #CJK UNIFIED IDEOGRAPH+0x96E6 0x5301 #CJK UNIFIED IDEOGRAPH+0x96E7 0x4E5F #CJK UNIFIED IDEOGRAPH+0x96E8 0x51B6 #CJK UNIFIED IDEOGRAPH+0x96E9 0x591C #CJK UNIFIED IDEOGRAPH+0x96EA 0x723A #CJK UNIFIED IDEOGRAPH+0x96EB 0x8036 #CJK UNIFIED IDEOGRAPH+0x96EC 0x91CE #CJK UNIFIED IDEOGRAPH+0x96ED 0x5F25 #CJK UNIFIED IDEOGRAPH+0x96EE 0x77E2 #CJK UNIFIED IDEOGRAPH+0x96EF 0x5384 #CJK UNIFIED IDEOGRAPH+0x96F0 0x5F79 #CJK UNIFIED IDEOGRAPH+0x96F1 0x7D04 #CJK UNIFIED IDEOGRAPH+0x96F2 0x85AC #CJK UNIFIED IDEOGRAPH+0x96F3 0x8A33 #CJK UNIFIED IDEOGRAPH+0x96F4 0x8E8D #CJK UNIFIED IDEOGRAPH+0x96F5 0x9756 #CJK UNIFIED IDEOGRAPH+0x96F6 0x67F3 #CJK UNIFIED IDEOGRAPH+0x96F7 0x85AE #CJK UNIFIED IDEOGRAPH+0x96F8 0x9453 #CJK UNIFIED IDEOGRAPH+0x96F9 0x6109 #CJK UNIFIED IDEOGRAPH+0x96FA 0x6108 #CJK UNIFIED IDEOGRAPH+0x96FB 0x6CB9 #CJK UNIFIED IDEOGRAPH+0x96FC 0x7652 #CJK UNIFIED IDEOGRAPH+0x9740 0x8AED #CJK UNIFIED IDEOGRAPH+0x9741 0x8F38 #CJK UNIFIED IDEOGRAPH+0x9742 0x552F #CJK UNIFIED IDEOGRAPH+0x9743 0x4F51 #CJK UNIFIED IDEOGRAPH+0x9744 0x512A #CJK UNIFIED IDEOGRAPH+0x9745 0x52C7 #CJK UNIFIED IDEOGRAPH+0x9746 0x53CB #CJK UNIFIED IDEOGRAPH+0x9747 0x5BA5 #CJK UNIFIED IDEOGRAPH+0x9748 0x5E7D #CJK UNIFIED IDEOGRAPH+0x9749 0x60A0 #CJK UNIFIED IDEOGRAPH+0x974A 0x6182 #CJK UNIFIED IDEOGRAPH+0x974B 0x63D6 #CJK UNIFIED IDEOGRAPH+0x974C 0x6709 #CJK UNIFIED IDEOGRAPH+0x974D 0x67DA #CJK UNIFIED IDEOGRAPH+0x974E 0x6E67 #CJK UNIFIED IDEOGRAPH+0x974F 0x6D8C #CJK UNIFIED IDEOGRAPH+0x9750 0x7336 #CJK UNIFIED IDEOGRAPH+0x9751 0x7337 #CJK UNIFIED IDEOGRAPH+0x9752 0x7531 #CJK UNIFIED IDEOGRAPH+0x9753 0x7950 #CJK UNIFIED IDEOGRAPH+0x9754 0x88D5 #CJK UNIFIED IDEOGRAPH+0x9755 0x8A98 #CJK UNIFIED IDEOGRAPH+0x9756 0x904A #CJK UNIFIED IDEOGRAPH+0x9757 0x9091 #CJK UNIFIED IDEOGRAPH+0x9758 0x90F5 #CJK UNIFIED IDEOGRAPH+0x9759 0x96C4 #CJK UNIFIED IDEOGRAPH+0x975A 0x878D #CJK UNIFIED IDEOGRAPH+0x975B 0x5915 #CJK UNIFIED IDEOGRAPH+0x975C 0x4E88 #CJK UNIFIED IDEOGRAPH+0x975D 0x4F59 #CJK UNIFIED IDEOGRAPH+0x975E 0x4E0E #CJK UNIFIED IDEOGRAPH+0x975F 0x8A89 #CJK UNIFIED IDEOGRAPH+0x9760 0x8F3F #CJK UNIFIED IDEOGRAPH+0x9761 0x9810 #CJK UNIFIED IDEOGRAPH+0x9762 0x50AD #CJK UNIFIED IDEOGRAPH+0x9763 0x5E7C #CJK UNIFIED IDEOGRAPH+0x9764 0x5996 #CJK UNIFIED IDEOGRAPH+0x9765 0x5BB9 #CJK UNIFIED IDEOGRAPH+0x9766 0x5EB8 #CJK UNIFIED IDEOGRAPH+0x9767 0x63DA #CJK UNIFIED IDEOGRAPH+0x9768 0x63FA #CJK UNIFIED IDEOGRAPH+0x9769 0x64C1 #CJK UNIFIED IDEOGRAPH+0x976A 0x66DC #CJK UNIFIED IDEOGRAPH+0x976B 0x694A #CJK UNIFIED IDEOGRAPH+0x976C 0x69D8 #CJK UNIFIED IDEOGRAPH+0x976D 0x6D0B #CJK UNIFIED IDEOGRAPH+0x976E 0x6EB6 #CJK UNIFIED IDEOGRAPH+0x976F 0x7194 #CJK UNIFIED IDEOGRAPH+0x9770 0x7528 #CJK UNIFIED IDEOGRAPH+0x9771 0x7AAF #CJK UNIFIED IDEOGRAPH+0x9772 0x7F8A #CJK UNIFIED IDEOGRAPH+0x9773 0x8000 #CJK UNIFIED IDEOGRAPH+0x9774 0x8449 #CJK UNIFIED IDEOGRAPH+0x9775 0x84C9 #CJK UNIFIED IDEOGRAPH+0x9776 0x8981 #CJK UNIFIED IDEOGRAPH+0x9777 0x8B21 #CJK UNIFIED IDEOGRAPH+0x9778 0x8E0A #CJK UNIFIED IDEOGRAPH+0x9779 0x9065 #CJK UNIFIED IDEOGRAPH+0x977A 0x967D #CJK UNIFIED IDEOGRAPH+0x977B 0x990A #CJK UNIFIED IDEOGRAPH+0x977C 0x617E #CJK UNIFIED IDEOGRAPH+0x977D 0x6291 #CJK UNIFIED IDEOGRAPH+0x977E 0x6B32 #CJK UNIFIED IDEOGRAPH+0x9780 0x6C83 #CJK UNIFIED IDEOGRAPH+0x9781 0x6D74 #CJK UNIFIED IDEOGRAPH+0x9782 0x7FCC #CJK UNIFIED IDEOGRAPH+0x9783 0x7FFC #CJK UNIFIED IDEOGRAPH+0x9784 0x6DC0 #CJK UNIFIED IDEOGRAPH+0x9785 0x7F85 #CJK UNIFIED IDEOGRAPH+0x9786 0x87BA #CJK UNIFIED IDEOGRAPH+0x9787 0x88F8 #CJK UNIFIED IDEOGRAPH+0x9788 0x6765 #CJK UNIFIED IDEOGRAPH+0x9789 0x83B1 #CJK UNIFIED IDEOGRAPH+0x978A 0x983C #CJK UNIFIED IDEOGRAPH+0x978B 0x96F7 #CJK UNIFIED IDEOGRAPH+0x978C 0x6D1B #CJK UNIFIED IDEOGRAPH+0x978D 0x7D61 #CJK UNIFIED IDEOGRAPH+0x978E 0x843D #CJK UNIFIED IDEOGRAPH+0x978F 0x916A #CJK UNIFIED IDEOGRAPH+0x9790 0x4E71 #CJK UNIFIED IDEOGRAPH+0x9791 0x5375 #CJK UNIFIED IDEOGRAPH+0x9792 0x5D50 #CJK UNIFIED IDEOGRAPH+0x9793 0x6B04 #CJK UNIFIED IDEOGRAPH+0x9794 0x6FEB #CJK UNIFIED IDEOGRAPH+0x9795 0x85CD #CJK UNIFIED IDEOGRAPH+0x9796 0x862D #CJK UNIFIED IDEOGRAPH+0x9797 0x89A7 #CJK UNIFIED IDEOGRAPH+0x9798 0x5229 #CJK UNIFIED IDEOGRAPH+0x9799 0x540F #CJK UNIFIED IDEOGRAPH+0x979A 0x5C65 #CJK UNIFIED IDEOGRAPH+0x979B 0x674E #CJK UNIFIED IDEOGRAPH+0x979C 0x68A8 #CJK UNIFIED IDEOGRAPH+0x979D 0x7406 #CJK UNIFIED IDEOGRAPH+0x979E 0x7483 #CJK UNIFIED IDEOGRAPH+0x979F 0x75E2 #CJK UNIFIED IDEOGRAPH+0x97A0 0x88CF #CJK UNIFIED IDEOGRAPH+0x97A1 0x88E1 #CJK UNIFIED IDEOGRAPH+0x97A2 0x91CC #CJK UNIFIED IDEOGRAPH+0x97A3 0x96E2 #CJK UNIFIED IDEOGRAPH+0x97A4 0x9678 #CJK UNIFIED IDEOGRAPH+0x97A5 0x5F8B #CJK UNIFIED IDEOGRAPH+0x97A6 0x7387 #CJK UNIFIED IDEOGRAPH+0x97A7 0x7ACB #CJK UNIFIED IDEOGRAPH+0x97A8 0x844E #CJK UNIFIED IDEOGRAPH+0x97A9 0x63A0 #CJK UNIFIED IDEOGRAPH+0x97AA 0x7565 #CJK UNIFIED IDEOGRAPH+0x97AB 0x5289 #CJK UNIFIED IDEOGRAPH+0x97AC 0x6D41 #CJK UNIFIED IDEOGRAPH+0x97AD 0x6E9C #CJK UNIFIED IDEOGRAPH+0x97AE 0x7409 #CJK UNIFIED IDEOGRAPH+0x97AF 0x7559 #CJK UNIFIED IDEOGRAPH+0x97B0 0x786B #CJK UNIFIED IDEOGRAPH+0x97B1 0x7C92 #CJK UNIFIED IDEOGRAPH+0x97B2 0x9686 #CJK UNIFIED IDEOGRAPH+0x97B3 0x7ADC #CJK UNIFIED IDEOGRAPH+0x97B4 0x9F8D #CJK UNIFIED IDEOGRAPH+0x97B5 0x4FB6 #CJK UNIFIED IDEOGRAPH+0x97B6 0x616E #CJK UNIFIED IDEOGRAPH+0x97B7 0x65C5 #CJK UNIFIED IDEOGRAPH+0x97B8 0x865C #CJK UNIFIED IDEOGRAPH+0x97B9 0x4E86 #CJK UNIFIED IDEOGRAPH+0x97BA 0x4EAE #CJK UNIFIED IDEOGRAPH+0x97BB 0x50DA #CJK UNIFIED IDEOGRAPH+0x97BC 0x4E21 #CJK UNIFIED IDEOGRAPH+0x97BD 0x51CC #CJK UNIFIED IDEOGRAPH+0x97BE 0x5BEE #CJK UNIFIED IDEOGRAPH+0x97BF 0x6599 #CJK UNIFIED IDEOGRAPH+0x97C0 0x6881 #CJK UNIFIED IDEOGRAPH+0x97C1 0x6DBC #CJK UNIFIED IDEOGRAPH+0x97C2 0x731F #CJK UNIFIED IDEOGRAPH+0x97C3 0x7642 #CJK UNIFIED IDEOGRAPH+0x97C4 0x77AD #CJK UNIFIED IDEOGRAPH+0x97C5 0x7A1C #CJK UNIFIED IDEOGRAPH+0x97C6 0x7CE7 #CJK UNIFIED IDEOGRAPH+0x97C7 0x826F #CJK UNIFIED IDEOGRAPH+0x97C8 0x8AD2 #CJK UNIFIED IDEOGRAPH+0x97C9 0x907C #CJK UNIFIED IDEOGRAPH+0x97CA 0x91CF #CJK UNIFIED IDEOGRAPH+0x97CB 0x9675 #CJK UNIFIED IDEOGRAPH+0x97CC 0x9818 #CJK UNIFIED IDEOGRAPH+0x97CD 0x529B #CJK UNIFIED IDEOGRAPH+0x97CE 0x7DD1 #CJK UNIFIED IDEOGRAPH+0x97CF 0x502B #CJK UNIFIED IDEOGRAPH+0x97D0 0x5398 #CJK UNIFIED IDEOGRAPH+0x97D1 0x6797 #CJK UNIFIED IDEOGRAPH+0x97D2 0x6DCB #CJK UNIFIED IDEOGRAPH+0x97D3 0x71D0 #CJK UNIFIED IDEOGRAPH+0x97D4 0x7433 #CJK UNIFIED IDEOGRAPH+0x97D5 0x81E8 #CJK UNIFIED IDEOGRAPH+0x97D6 0x8F2A #CJK UNIFIED IDEOGRAPH+0x97D7 0x96A3 #CJK UNIFIED IDEOGRAPH+0x97D8 0x9C57 #CJK UNIFIED IDEOGRAPH+0x97D9 0x9E9F #CJK UNIFIED IDEOGRAPH+0x97DA 0x7460 #CJK UNIFIED IDEOGRAPH+0x97DB 0x5841 #CJK UNIFIED IDEOGRAPH+0x97DC 0x6D99 #CJK UNIFIED IDEOGRAPH+0x97DD 0x7D2F #CJK UNIFIED IDEOGRAPH+0x97DE 0x985E #CJK UNIFIED IDEOGRAPH+0x97DF 0x4EE4 #CJK UNIFIED IDEOGRAPH+0x97E0 0x4F36 #CJK UNIFIED IDEOGRAPH+0x97E1 0x4F8B #CJK UNIFIED IDEOGRAPH+0x97E2 0x51B7 #CJK UNIFIED IDEOGRAPH+0x97E3 0x52B1 #CJK UNIFIED IDEOGRAPH+0x97E4 0x5DBA #CJK UNIFIED IDEOGRAPH+0x97E5 0x601C #CJK UNIFIED IDEOGRAPH+0x97E6 0x73B2 #CJK UNIFIED IDEOGRAPH+0x97E7 0x793C #CJK UNIFIED IDEOGRAPH+0x97E8 0x82D3 #CJK UNIFIED IDEOGRAPH+0x97E9 0x9234 #CJK UNIFIED IDEOGRAPH+0x97EA 0x96B7 #CJK UNIFIED IDEOGRAPH+0x97EB 0x96F6 #CJK UNIFIED IDEOGRAPH+0x97EC 0x970A #CJK UNIFIED IDEOGRAPH+0x97ED 0x9E97 #CJK UNIFIED IDEOGRAPH+0x97EE 0x9F62 #CJK UNIFIED IDEOGRAPH+0x97EF 0x66A6 #CJK UNIFIED IDEOGRAPH+0x97F0 0x6B74 #CJK UNIFIED IDEOGRAPH+0x97F1 0x5217 #CJK UNIFIED IDEOGRAPH+0x97F2 0x52A3 #CJK UNIFIED IDEOGRAPH+0x97F3 0x70C8 #CJK UNIFIED IDEOGRAPH+0x97F4 0x88C2 #CJK UNIFIED IDEOGRAPH+0x97F5 0x5EC9 #CJK UNIFIED IDEOGRAPH+0x97F6 0x604B #CJK UNIFIED IDEOGRAPH+0x97F7 0x6190 #CJK UNIFIED IDEOGRAPH+0x97F8 0x6F23 #CJK UNIFIED IDEOGRAPH+0x97F9 0x7149 #CJK UNIFIED IDEOGRAPH+0x97FA 0x7C3E #CJK UNIFIED IDEOGRAPH+0x97FB 0x7DF4 #CJK UNIFIED IDEOGRAPH+0x97FC 0x806F #CJK UNIFIED IDEOGRAPH+0x9840 0x84EE #CJK UNIFIED IDEOGRAPH+0x9841 0x9023 #CJK UNIFIED IDEOGRAPH+0x9842 0x932C #CJK UNIFIED IDEOGRAPH+0x9843 0x5442 #CJK UNIFIED IDEOGRAPH+0x9844 0x9B6F #CJK UNIFIED IDEOGRAPH+0x9845 0x6AD3 #CJK UNIFIED IDEOGRAPH+0x9846 0x7089 #CJK UNIFIED IDEOGRAPH+0x9847 0x8CC2 #CJK UNIFIED IDEOGRAPH+0x9848 0x8DEF #CJK UNIFIED IDEOGRAPH+0x9849 0x9732 #CJK UNIFIED IDEOGRAPH+0x984A 0x52B4 #CJK UNIFIED IDEOGRAPH+0x984B 0x5A41 #CJK UNIFIED IDEOGRAPH+0x984C 0x5ECA #CJK UNIFIED IDEOGRAPH+0x984D 0x5F04 #CJK UNIFIED IDEOGRAPH+0x984E 0x6717 #CJK UNIFIED IDEOGRAPH+0x984F 0x697C #CJK UNIFIED IDEOGRAPH+0x9850 0x6994 #CJK UNIFIED IDEOGRAPH+0x9851 0x6D6A #CJK UNIFIED IDEOGRAPH+0x9852 0x6F0F #CJK UNIFIED IDEOGRAPH+0x9853 0x7262 #CJK UNIFIED IDEOGRAPH+0x9854 0x72FC #CJK UNIFIED IDEOGRAPH+0x9855 0x7BED #CJK UNIFIED IDEOGRAPH+0x9856 0x8001 #CJK UNIFIED IDEOGRAPH+0x9857 0x807E #CJK UNIFIED IDEOGRAPH+0x9858 0x874B #CJK UNIFIED IDEOGRAPH+0x9859 0x90CE #CJK UNIFIED IDEOGRAPH+0x985A 0x516D #CJK UNIFIED IDEOGRAPH+0x985B 0x9E93 #CJK UNIFIED IDEOGRAPH+0x985C 0x7984 #CJK UNIFIED IDEOGRAPH+0x985D 0x808B #CJK UNIFIED IDEOGRAPH+0x985E 0x9332 #CJK UNIFIED IDEOGRAPH+0x985F 0x8AD6 #CJK UNIFIED IDEOGRAPH+0x9860 0x502D #CJK UNIFIED IDEOGRAPH+0x9861 0x548C #CJK UNIFIED IDEOGRAPH+0x9862 0x8A71 #CJK UNIFIED IDEOGRAPH+0x9863 0x6B6A #CJK UNIFIED IDEOGRAPH+0x9864 0x8CC4 #CJK UNIFIED IDEOGRAPH+0x9865 0x8107 #CJK UNIFIED IDEOGRAPH+0x9866 0x60D1 #CJK UNIFIED IDEOGRAPH+0x9867 0x67A0 #CJK UNIFIED IDEOGRAPH+0x9868 0x9DF2 #CJK UNIFIED IDEOGRAPH+0x9869 0x4E99 #CJK UNIFIED IDEOGRAPH+0x986A 0x4E98 #CJK UNIFIED IDEOGRAPH+0x986B 0x9C10 #CJK UNIFIED IDEOGRAPH+0x986C 0x8A6B #CJK UNIFIED IDEOGRAPH+0x986D 0x85C1 #CJK UNIFIED IDEOGRAPH+0x986E 0x8568 #CJK UNIFIED IDEOGRAPH+0x986F 0x6900 #CJK UNIFIED IDEOGRAPH+0x9870 0x6E7E #CJK UNIFIED IDEOGRAPH+0x9871 0x7897 #CJK UNIFIED IDEOGRAPH+0x9872 0x8155 #CJK UNIFIED IDEOGRAPH+0x989F 0x5F0C #CJK UNIFIED IDEOGRAPH+0x98A0 0x4E10 #CJK UNIFIED IDEOGRAPH+0x98A1 0x4E15 #CJK UNIFIED IDEOGRAPH+0x98A2 0x4E2A #CJK UNIFIED IDEOGRAPH+0x98A3 0x4E31 #CJK UNIFIED IDEOGRAPH+0x98A4 0x4E36 #CJK UNIFIED IDEOGRAPH+0x98A5 0x4E3C #CJK UNIFIED IDEOGRAPH+0x98A6 0x4E3F #CJK UNIFIED IDEOGRAPH+0x98A7 0x4E42 #CJK UNIFIED IDEOGRAPH+0x98A8 0x4E56 #CJK UNIFIED IDEOGRAPH+0x98A9 0x4E58 #CJK UNIFIED IDEOGRAPH+0x98AA 0x4E82 #CJK UNIFIED IDEOGRAPH+0x98AB 0x4E85 #CJK UNIFIED IDEOGRAPH+0x98AC 0x8C6B #CJK UNIFIED IDEOGRAPH+0x98AD 0x4E8A #CJK UNIFIED IDEOGRAPH+0x98AE 0x8212 #CJK UNIFIED IDEOGRAPH+0x98AF 0x5F0D #CJK UNIFIED IDEOGRAPH+0x98B0 0x4E8E #CJK UNIFIED IDEOGRAPH+0x98B1 0x4E9E #CJK UNIFIED IDEOGRAPH+0x98B2 0x4E9F #CJK UNIFIED IDEOGRAPH+0x98B3 0x4EA0 #CJK UNIFIED IDEOGRAPH+0x98B4 0x4EA2 #CJK UNIFIED IDEOGRAPH+0x98B5 0x4EB0 #CJK UNIFIED IDEOGRAPH+0x98B6 0x4EB3 #CJK UNIFIED IDEOGRAPH+0x98B7 0x4EB6 #CJK UNIFIED IDEOGRAPH+0x98B8 0x4ECE #CJK UNIFIED IDEOGRAPH+0x98B9 0x4ECD #CJK UNIFIED IDEOGRAPH+0x98BA 0x4EC4 #CJK UNIFIED IDEOGRAPH+0x98BB 0x4EC6 #CJK UNIFIED IDEOGRAPH+0x98BC 0x4EC2 #CJK UNIFIED IDEOGRAPH+0x98BD 0x4ED7 #CJK UNIFIED IDEOGRAPH+0x98BE 0x4EDE #CJK UNIFIED IDEOGRAPH+0x98BF 0x4EED #CJK UNIFIED IDEOGRAPH+0x98C0 0x4EDF #CJK UNIFIED IDEOGRAPH+0x98C1 0x4EF7 #CJK UNIFIED IDEOGRAPH+0x98C2 0x4F09 #CJK UNIFIED IDEOGRAPH+0x98C3 0x4F5A #CJK UNIFIED IDEOGRAPH+0x98C4 0x4F30 #CJK UNIFIED IDEOGRAPH+0x98C5 0x4F5B #CJK UNIFIED IDEOGRAPH+0x98C6 0x4F5D #CJK UNIFIED IDEOGRAPH+0x98C7 0x4F57 #CJK UNIFIED IDEOGRAPH+0x98C8 0x4F47 #CJK UNIFIED IDEOGRAPH+0x98C9 0x4F76 #CJK UNIFIED IDEOGRAPH+0x98CA 0x4F88 #CJK UNIFIED IDEOGRAPH+0x98CB 0x4F8F #CJK UNIFIED IDEOGRAPH+0x98CC 0x4F98 #CJK UNIFIED IDEOGRAPH+0x98CD 0x4F7B #CJK UNIFIED IDEOGRAPH+0x98CE 0x4F69 #CJK UNIFIED IDEOGRAPH+0x98CF 0x4F70 #CJK UNIFIED IDEOGRAPH+0x98D0 0x4F91 #CJK UNIFIED IDEOGRAPH+0x98D1 0x4F6F #CJK UNIFIED IDEOGRAPH+0x98D2 0x4F86 #CJK UNIFIED IDEOGRAPH+0x98D3 0x4F96 #CJK UNIFIED IDEOGRAPH+0x98D4 0x5118 #CJK UNIFIED IDEOGRAPH+0x98D5 0x4FD4 #CJK UNIFIED IDEOGRAPH+0x98D6 0x4FDF #CJK UNIFIED IDEOGRAPH+0x98D7 0x4FCE #CJK UNIFIED IDEOGRAPH+0x98D8 0x4FD8 #CJK UNIFIED IDEOGRAPH+0x98D9 0x4FDB #CJK UNIFIED IDEOGRAPH+0x98DA 0x4FD1 #CJK UNIFIED IDEOGRAPH+0x98DB 0x4FDA #CJK UNIFIED IDEOGRAPH+0x98DC 0x4FD0 #CJK UNIFIED IDEOGRAPH+0x98DD 0x4FE4 #CJK UNIFIED IDEOGRAPH+0x98DE 0x4FE5 #CJK UNIFIED IDEOGRAPH+0x98DF 0x501A #CJK UNIFIED IDEOGRAPH+0x98E0 0x5028 #CJK UNIFIED IDEOGRAPH+0x98E1 0x5014 #CJK UNIFIED IDEOGRAPH+0x98E2 0x502A #CJK UNIFIED IDEOGRAPH+0x98E3 0x5025 #CJK UNIFIED IDEOGRAPH+0x98E4 0x5005 #CJK UNIFIED IDEOGRAPH+0x98E5 0x4F1C #CJK UNIFIED IDEOGRAPH+0x98E6 0x4FF6 #CJK UNIFIED IDEOGRAPH+0x98E7 0x5021 #CJK UNIFIED IDEOGRAPH+0x98E8 0x5029 #CJK UNIFIED IDEOGRAPH+0x98E9 0x502C #CJK UNIFIED IDEOGRAPH+0x98EA 0x4FFE #CJK UNIFIED IDEOGRAPH+0x98EB 0x4FEF #CJK UNIFIED IDEOGRAPH+0x98EC 0x5011 #CJK UNIFIED IDEOGRAPH+0x98ED 0x5006 #CJK UNIFIED IDEOGRAPH+0x98EE 0x5043 #CJK UNIFIED IDEOGRAPH+0x98EF 0x5047 #CJK UNIFIED IDEOGRAPH+0x98F0 0x6703 #CJK UNIFIED IDEOGRAPH+0x98F1 0x5055 #CJK UNIFIED IDEOGRAPH+0x98F2 0x5050 #CJK UNIFIED IDEOGRAPH+0x98F3 0x5048 #CJK UNIFIED IDEOGRAPH+0x98F4 0x505A #CJK UNIFIED IDEOGRAPH+0x98F5 0x5056 #CJK UNIFIED IDEOGRAPH+0x98F6 0x506C #CJK UNIFIED IDEOGRAPH+0x98F7 0x5078 #CJK UNIFIED IDEOGRAPH+0x98F8 0x5080 #CJK UNIFIED IDEOGRAPH+0x98F9 0x509A #CJK UNIFIED IDEOGRAPH+0x98FA 0x5085 #CJK UNIFIED IDEOGRAPH+0x98FB 0x50B4 #CJK UNIFIED IDEOGRAPH+0x98FC 0x50B2 #CJK UNIFIED IDEOGRAPH+0x9940 0x50C9 #CJK UNIFIED IDEOGRAPH+0x9941 0x50CA #CJK UNIFIED IDEOGRAPH+0x9942 0x50B3 #CJK UNIFIED IDEOGRAPH+0x9943 0x50C2 #CJK UNIFIED IDEOGRAPH+0x9944 0x50D6 #CJK UNIFIED IDEOGRAPH+0x9945 0x50DE #CJK UNIFIED IDEOGRAPH+0x9946 0x50E5 #CJK UNIFIED IDEOGRAPH+0x9947 0x50ED #CJK UNIFIED IDEOGRAPH+0x9948 0x50E3 #CJK UNIFIED IDEOGRAPH+0x9949 0x50EE #CJK UNIFIED IDEOGRAPH+0x994A 0x50F9 #CJK UNIFIED IDEOGRAPH+0x994B 0x50F5 #CJK UNIFIED IDEOGRAPH+0x994C 0x5109 #CJK UNIFIED IDEOGRAPH+0x994D 0x5101 #CJK UNIFIED IDEOGRAPH+0x994E 0x5102 #CJK UNIFIED IDEOGRAPH+0x994F 0x5116 #CJK UNIFIED IDEOGRAPH+0x9950 0x5115 #CJK UNIFIED IDEOGRAPH+0x9951 0x5114 #CJK UNIFIED IDEOGRAPH+0x9952 0x511A #CJK UNIFIED IDEOGRAPH+0x9953 0x5121 #CJK UNIFIED IDEOGRAPH+0x9954 0x513A #CJK UNIFIED IDEOGRAPH+0x9955 0x5137 #CJK UNIFIED IDEOGRAPH+0x9956 0x513C #CJK UNIFIED IDEOGRAPH+0x9957 0x513B #CJK UNIFIED IDEOGRAPH+0x9958 0x513F #CJK UNIFIED IDEOGRAPH+0x9959 0x5140 #CJK UNIFIED IDEOGRAPH+0x995A 0x5152 #CJK UNIFIED IDEOGRAPH+0x995B 0x514C #CJK UNIFIED IDEOGRAPH+0x995C 0x5154 #CJK UNIFIED IDEOGRAPH+0x995D 0x5162 #CJK UNIFIED IDEOGRAPH+0x995E 0x7AF8 #CJK UNIFIED IDEOGRAPH+0x995F 0x5169 #CJK UNIFIED IDEOGRAPH+0x9960 0x516A #CJK UNIFIED IDEOGRAPH+0x9961 0x516E #CJK UNIFIED IDEOGRAPH+0x9962 0x5180 #CJK UNIFIED IDEOGRAPH+0x9963 0x5182 #CJK UNIFIED IDEOGRAPH+0x9964 0x56D8 #CJK UNIFIED IDEOGRAPH+0x9965 0x518C #CJK UNIFIED IDEOGRAPH+0x9966 0x5189 #CJK UNIFIED IDEOGRAPH+0x9967 0x518F #CJK UNIFIED IDEOGRAPH+0x9968 0x5191 #CJK UNIFIED IDEOGRAPH+0x9969 0x5193 #CJK UNIFIED IDEOGRAPH+0x996A 0x5195 #CJK UNIFIED IDEOGRAPH+0x996B 0x5196 #CJK UNIFIED IDEOGRAPH+0x996C 0x51A4 #CJK UNIFIED IDEOGRAPH+0x996D 0x51A6 #CJK UNIFIED IDEOGRAPH+0x996E 0x51A2 #CJK UNIFIED IDEOGRAPH+0x996F 0x51A9 #CJK UNIFIED IDEOGRAPH+0x9970 0x51AA #CJK UNIFIED IDEOGRAPH+0x9971 0x51AB #CJK UNIFIED IDEOGRAPH+0x9972 0x51B3 #CJK UNIFIED IDEOGRAPH+0x9973 0x51B1 #CJK UNIFIED IDEOGRAPH+0x9974 0x51B2 #CJK UNIFIED IDEOGRAPH+0x9975 0x51B0 #CJK UNIFIED IDEOGRAPH+0x9976 0x51B5 #CJK UNIFIED IDEOGRAPH+0x9977 0x51BD #CJK UNIFIED IDEOGRAPH+0x9978 0x51C5 #CJK UNIFIED IDEOGRAPH+0x9979 0x51C9 #CJK UNIFIED IDEOGRAPH+0x997A 0x51DB #CJK UNIFIED IDEOGRAPH+0x997B 0x51E0 #CJK UNIFIED IDEOGRAPH+0x997C 0x8655 #CJK UNIFIED IDEOGRAPH+0x997D 0x51E9 #CJK UNIFIED IDEOGRAPH+0x997E 0x51ED #CJK UNIFIED IDEOGRAPH+0x9980 0x51F0 #CJK UNIFIED IDEOGRAPH+0x9981 0x51F5 #CJK UNIFIED IDEOGRAPH+0x9982 0x51FE #CJK UNIFIED IDEOGRAPH+0x9983 0x5204 #CJK UNIFIED IDEOGRAPH+0x9984 0x520B #CJK UNIFIED IDEOGRAPH+0x9985 0x5214 #CJK UNIFIED IDEOGRAPH+0x9986 0x520E #CJK UNIFIED IDEOGRAPH+0x9987 0x5227 #CJK UNIFIED IDEOGRAPH+0x9988 0x522A #CJK UNIFIED IDEOGRAPH+0x9989 0x522E #CJK UNIFIED IDEOGRAPH+0x998A 0x5233 #CJK UNIFIED IDEOGRAPH+0x998B 0x5239 #CJK UNIFIED IDEOGRAPH+0x998C 0x524F #CJK UNIFIED IDEOGRAPH+0x998D 0x5244 #CJK UNIFIED IDEOGRAPH+0x998E 0x524B #CJK UNIFIED IDEOGRAPH+0x998F 0x524C #CJK UNIFIED IDEOGRAPH+0x9990 0x525E #CJK UNIFIED IDEOGRAPH+0x9991 0x5254 #CJK UNIFIED IDEOGRAPH+0x9992 0x526A #CJK UNIFIED IDEOGRAPH+0x9993 0x5274 #CJK UNIFIED IDEOGRAPH+0x9994 0x5269 #CJK UNIFIED IDEOGRAPH+0x9995 0x5273 #CJK UNIFIED IDEOGRAPH+0x9996 0x527F #CJK UNIFIED IDEOGRAPH+0x9997 0x527D #CJK UNIFIED IDEOGRAPH+0x9998 0x528D #CJK UNIFIED IDEOGRAPH+0x9999 0x5294 #CJK UNIFIED IDEOGRAPH+0x999A 0x5292 #CJK UNIFIED IDEOGRAPH+0x999B 0x5271 #CJK UNIFIED IDEOGRAPH+0x999C 0x5288 #CJK UNIFIED IDEOGRAPH+0x999D 0x5291 #CJK UNIFIED IDEOGRAPH+0x999E 0x8FA8 #CJK UNIFIED IDEOGRAPH+0x999F 0x8FA7 #CJK UNIFIED IDEOGRAPH+0x99A0 0x52AC #CJK UNIFIED IDEOGRAPH+0x99A1 0x52AD #CJK UNIFIED IDEOGRAPH+0x99A2 0x52BC #CJK UNIFIED IDEOGRAPH+0x99A3 0x52B5 #CJK UNIFIED IDEOGRAPH+0x99A4 0x52C1 #CJK UNIFIED IDEOGRAPH+0x99A5 0x52CD #CJK UNIFIED IDEOGRAPH+0x99A6 0x52D7 #CJK UNIFIED IDEOGRAPH+0x99A7 0x52DE #CJK UNIFIED IDEOGRAPH+0x99A8 0x52E3 #CJK UNIFIED IDEOGRAPH+0x99A9 0x52E6 #CJK UNIFIED IDEOGRAPH+0x99AA 0x98ED #CJK UNIFIED IDEOGRAPH+0x99AB 0x52E0 #CJK UNIFIED IDEOGRAPH+0x99AC 0x52F3 #CJK UNIFIED IDEOGRAPH+0x99AD 0x52F5 #CJK UNIFIED IDEOGRAPH+0x99AE 0x52F8 #CJK UNIFIED IDEOGRAPH+0x99AF 0x52F9 #CJK UNIFIED IDEOGRAPH+0x99B0 0x5306 #CJK UNIFIED IDEOGRAPH+0x99B1 0x5308 #CJK UNIFIED IDEOGRAPH+0x99B2 0x7538 #CJK UNIFIED IDEOGRAPH+0x99B3 0x530D #CJK UNIFIED IDEOGRAPH+0x99B4 0x5310 #CJK UNIFIED IDEOGRAPH+0x99B5 0x530F #CJK UNIFIED IDEOGRAPH+0x99B6 0x5315 #CJK UNIFIED IDEOGRAPH+0x99B7 0x531A #CJK UNIFIED IDEOGRAPH+0x99B8 0x5323 #CJK UNIFIED IDEOGRAPH+0x99B9 0x532F #CJK UNIFIED IDEOGRAPH+0x99BA 0x5331 #CJK UNIFIED IDEOGRAPH+0x99BB 0x5333 #CJK UNIFIED IDEOGRAPH+0x99BC 0x5338 #CJK UNIFIED IDEOGRAPH+0x99BD 0x5340 #CJK UNIFIED IDEOGRAPH+0x99BE 0x5346 #CJK UNIFIED IDEOGRAPH+0x99BF 0x5345 #CJK UNIFIED IDEOGRAPH+0x99C0 0x4E17 #CJK UNIFIED IDEOGRAPH+0x99C1 0x5349 #CJK UNIFIED IDEOGRAPH+0x99C2 0x534D #CJK UNIFIED IDEOGRAPH+0x99C3 0x51D6 #CJK UNIFIED IDEOGRAPH+0x99C4 0x535E #CJK UNIFIED IDEOGRAPH+0x99C5 0x5369 #CJK UNIFIED IDEOGRAPH+0x99C6 0x536E #CJK UNIFIED IDEOGRAPH+0x99C7 0x5918 #CJK UNIFIED IDEOGRAPH+0x99C8 0x537B #CJK UNIFIED IDEOGRAPH+0x99C9 0x5377 #CJK UNIFIED IDEOGRAPH+0x99CA 0x5382 #CJK UNIFIED IDEOGRAPH+0x99CB 0x5396 #CJK UNIFIED IDEOGRAPH+0x99CC 0x53A0 #CJK UNIFIED IDEOGRAPH+0x99CD 0x53A6 #CJK UNIFIED IDEOGRAPH+0x99CE 0x53A5 #CJK UNIFIED IDEOGRAPH+0x99CF 0x53AE #CJK UNIFIED IDEOGRAPH+0x99D0 0x53B0 #CJK UNIFIED IDEOGRAPH+0x99D1 0x53B6 #CJK UNIFIED IDEOGRAPH+0x99D2 0x53C3 #CJK UNIFIED IDEOGRAPH+0x99D3 0x7C12 #CJK UNIFIED IDEOGRAPH+0x99D4 0x96D9 #CJK UNIFIED IDEOGRAPH+0x99D5 0x53DF #CJK UNIFIED IDEOGRAPH+0x99D6 0x66FC #CJK UNIFIED IDEOGRAPH+0x99D7 0x71EE #CJK UNIFIED IDEOGRAPH+0x99D8 0x53EE #CJK UNIFIED IDEOGRAPH+0x99D9 0x53E8 #CJK UNIFIED IDEOGRAPH+0x99DA 0x53ED #CJK UNIFIED IDEOGRAPH+0x99DB 0x53FA #CJK UNIFIED IDEOGRAPH+0x99DC 0x5401 #CJK UNIFIED IDEOGRAPH+0x99DD 0x543D #CJK UNIFIED IDEOGRAPH+0x99DE 0x5440 #CJK UNIFIED IDEOGRAPH+0x99DF 0x542C #CJK UNIFIED IDEOGRAPH+0x99E0 0x542D #CJK UNIFIED IDEOGRAPH+0x99E1 0x543C #CJK UNIFIED IDEOGRAPH+0x99E2 0x542E #CJK UNIFIED IDEOGRAPH+0x99E3 0x5436 #CJK UNIFIED IDEOGRAPH+0x99E4 0x5429 #CJK UNIFIED IDEOGRAPH+0x99E5 0x541D #CJK UNIFIED IDEOGRAPH+0x99E6 0x544E #CJK UNIFIED IDEOGRAPH+0x99E7 0x548F #CJK UNIFIED IDEOGRAPH+0x99E8 0x5475 #CJK UNIFIED IDEOGRAPH+0x99E9 0x548E #CJK UNIFIED IDEOGRAPH+0x99EA 0x545F #CJK UNIFIED IDEOGRAPH+0x99EB 0x5471 #CJK UNIFIED IDEOGRAPH+0x99EC 0x5477 #CJK UNIFIED IDEOGRAPH+0x99ED 0x5470 #CJK UNIFIED IDEOGRAPH+0x99EE 0x5492 #CJK UNIFIED IDEOGRAPH+0x99EF 0x547B #CJK UNIFIED IDEOGRAPH+0x99F0 0x5480 #CJK UNIFIED IDEOGRAPH+0x99F1 0x5476 #CJK UNIFIED IDEOGRAPH+0x99F2 0x5484 #CJK UNIFIED IDEOGRAPH+0x99F3 0x5490 #CJK UNIFIED IDEOGRAPH+0x99F4 0x5486 #CJK UNIFIED IDEOGRAPH+0x99F5 0x54C7 #CJK UNIFIED IDEOGRAPH+0x99F6 0x54A2 #CJK UNIFIED IDEOGRAPH+0x99F7 0x54B8 #CJK UNIFIED IDEOGRAPH+0x99F8 0x54A5 #CJK UNIFIED IDEOGRAPH+0x99F9 0x54AC #CJK UNIFIED IDEOGRAPH+0x99FA 0x54C4 #CJK UNIFIED IDEOGRAPH+0x99FB 0x54C8 #CJK UNIFIED IDEOGRAPH+0x99FC 0x54A8 #CJK UNIFIED IDEOGRAPH+0x9A40 0x54AB #CJK UNIFIED IDEOGRAPH+0x9A41 0x54C2 #CJK UNIFIED IDEOGRAPH+0x9A42 0x54A4 #CJK UNIFIED IDEOGRAPH+0x9A43 0x54BE #CJK UNIFIED IDEOGRAPH+0x9A44 0x54BC #CJK UNIFIED IDEOGRAPH+0x9A45 0x54D8 #CJK UNIFIED IDEOGRAPH+0x9A46 0x54E5 #CJK UNIFIED IDEOGRAPH+0x9A47 0x54E6 #CJK UNIFIED IDEOGRAPH+0x9A48 0x550F #CJK UNIFIED IDEOGRAPH+0x9A49 0x5514 #CJK UNIFIED IDEOGRAPH+0x9A4A 0x54FD #CJK UNIFIED IDEOGRAPH+0x9A4B 0x54EE #CJK UNIFIED IDEOGRAPH+0x9A4C 0x54ED #CJK UNIFIED IDEOGRAPH+0x9A4D 0x54FA #CJK UNIFIED IDEOGRAPH+0x9A4E 0x54E2 #CJK UNIFIED IDEOGRAPH+0x9A4F 0x5539 #CJK UNIFIED IDEOGRAPH+0x9A50 0x5540 #CJK UNIFIED IDEOGRAPH+0x9A51 0x5563 #CJK UNIFIED IDEOGRAPH+0x9A52 0x554C #CJK UNIFIED IDEOGRAPH+0x9A53 0x552E #CJK UNIFIED IDEOGRAPH+0x9A54 0x555C #CJK UNIFIED IDEOGRAPH+0x9A55 0x5545 #CJK UNIFIED IDEOGRAPH+0x9A56 0x5556 #CJK UNIFIED IDEOGRAPH+0x9A57 0x5557 #CJK UNIFIED IDEOGRAPH+0x9A58 0x5538 #CJK UNIFIED IDEOGRAPH+0x9A59 0x5533 #CJK UNIFIED IDEOGRAPH+0x9A5A 0x555D #CJK UNIFIED IDEOGRAPH+0x9A5B 0x5599 #CJK UNIFIED IDEOGRAPH+0x9A5C 0x5580 #CJK UNIFIED IDEOGRAPH+0x9A5D 0x54AF #CJK UNIFIED IDEOGRAPH+0x9A5E 0x558A #CJK UNIFIED IDEOGRAPH+0x9A5F 0x559F #CJK UNIFIED IDEOGRAPH+0x9A60 0x557B #CJK UNIFIED IDEOGRAPH+0x9A61 0x557E #CJK UNIFIED IDEOGRAPH+0x9A62 0x5598 #CJK UNIFIED IDEOGRAPH+0x9A63 0x559E #CJK UNIFIED IDEOGRAPH+0x9A64 0x55AE #CJK UNIFIED IDEOGRAPH+0x9A65 0x557C #CJK UNIFIED IDEOGRAPH+0x9A66 0x5583 #CJK UNIFIED IDEOGRAPH+0x9A67 0x55A9 #CJK UNIFIED IDEOGRAPH+0x9A68 0x5587 #CJK UNIFIED IDEOGRAPH+0x9A69 0x55A8 #CJK UNIFIED IDEOGRAPH+0x9A6A 0x55DA #CJK UNIFIED IDEOGRAPH+0x9A6B 0x55C5 #CJK UNIFIED IDEOGRAPH+0x9A6C 0x55DF #CJK UNIFIED IDEOGRAPH+0x9A6D 0x55C4 #CJK UNIFIED IDEOGRAPH+0x9A6E 0x55DC #CJK UNIFIED IDEOGRAPH+0x9A6F 0x55E4 #CJK UNIFIED IDEOGRAPH+0x9A70 0x55D4 #CJK UNIFIED IDEOGRAPH+0x9A71 0x5614 #CJK UNIFIED IDEOGRAPH+0x9A72 0x55F7 #CJK UNIFIED IDEOGRAPH+0x9A73 0x5616 #CJK UNIFIED IDEOGRAPH+0x9A74 0x55FE #CJK UNIFIED IDEOGRAPH+0x9A75 0x55FD #CJK UNIFIED IDEOGRAPH+0x9A76 0x561B #CJK UNIFIED IDEOGRAPH+0x9A77 0x55F9 #CJK UNIFIED IDEOGRAPH+0x9A78 0x564E #CJK UNIFIED IDEOGRAPH+0x9A79 0x5650 #CJK UNIFIED IDEOGRAPH+0x9A7A 0x71DF #CJK UNIFIED IDEOGRAPH+0x9A7B 0x5634 #CJK UNIFIED IDEOGRAPH+0x9A7C 0x5636 #CJK UNIFIED IDEOGRAPH+0x9A7D 0x5632 #CJK UNIFIED IDEOGRAPH+0x9A7E 0x5638 #CJK UNIFIED IDEOGRAPH+0x9A80 0x566B #CJK UNIFIED IDEOGRAPH+0x9A81 0x5664 #CJK UNIFIED IDEOGRAPH+0x9A82 0x562F #CJK UNIFIED IDEOGRAPH+0x9A83 0x566C #CJK UNIFIED IDEOGRAPH+0x9A84 0x566A #CJK UNIFIED IDEOGRAPH+0x9A85 0x5686 #CJK UNIFIED IDEOGRAPH+0x9A86 0x5680 #CJK UNIFIED IDEOGRAPH+0x9A87 0x568A #CJK UNIFIED IDEOGRAPH+0x9A88 0x56A0 #CJK UNIFIED IDEOGRAPH+0x9A89 0x5694 #CJK UNIFIED IDEOGRAPH+0x9A8A 0x568F #CJK UNIFIED IDEOGRAPH+0x9A8B 0x56A5 #CJK UNIFIED IDEOGRAPH+0x9A8C 0x56AE #CJK UNIFIED IDEOGRAPH+0x9A8D 0x56B6 #CJK UNIFIED IDEOGRAPH+0x9A8E 0x56B4 #CJK UNIFIED IDEOGRAPH+0x9A8F 0x56C2 #CJK UNIFIED IDEOGRAPH+0x9A90 0x56BC #CJK UNIFIED IDEOGRAPH+0x9A91 0x56C1 #CJK UNIFIED IDEOGRAPH+0x9A92 0x56C3 #CJK UNIFIED IDEOGRAPH+0x9A93 0x56C0 #CJK UNIFIED IDEOGRAPH+0x9A94 0x56C8 #CJK UNIFIED IDEOGRAPH+0x9A95 0x56CE #CJK UNIFIED IDEOGRAPH+0x9A96 0x56D1 #CJK UNIFIED IDEOGRAPH+0x9A97 0x56D3 #CJK UNIFIED IDEOGRAPH+0x9A98 0x56D7 #CJK UNIFIED IDEOGRAPH+0x9A99 0x56EE #CJK UNIFIED IDEOGRAPH+0x9A9A 0x56F9 #CJK UNIFIED IDEOGRAPH+0x9A9B 0x5700 #CJK UNIFIED IDEOGRAPH+0x9A9C 0x56FF #CJK UNIFIED IDEOGRAPH+0x9A9D 0x5704 #CJK UNIFIED IDEOGRAPH+0x9A9E 0x5709 #CJK UNIFIED IDEOGRAPH+0x9A9F 0x5708 #CJK UNIFIED IDEOGRAPH+0x9AA0 0x570B #CJK UNIFIED IDEOGRAPH+0x9AA1 0x570D #CJK UNIFIED IDEOGRAPH+0x9AA2 0x5713 #CJK UNIFIED IDEOGRAPH+0x9AA3 0x5718 #CJK UNIFIED IDEOGRAPH+0x9AA4 0x5716 #CJK UNIFIED IDEOGRAPH+0x9AA5 0x55C7 #CJK UNIFIED IDEOGRAPH+0x9AA6 0x571C #CJK UNIFIED IDEOGRAPH+0x9AA7 0x5726 #CJK UNIFIED IDEOGRAPH+0x9AA8 0x5737 #CJK UNIFIED IDEOGRAPH+0x9AA9 0x5738 #CJK UNIFIED IDEOGRAPH+0x9AAA 0x574E #CJK UNIFIED IDEOGRAPH+0x9AAB 0x573B #CJK UNIFIED IDEOGRAPH+0x9AAC 0x5740 #CJK UNIFIED IDEOGRAPH+0x9AAD 0x574F #CJK UNIFIED IDEOGRAPH+0x9AAE 0x5769 #CJK UNIFIED IDEOGRAPH+0x9AAF 0x57C0 #CJK UNIFIED IDEOGRAPH+0x9AB0 0x5788 #CJK UNIFIED IDEOGRAPH+0x9AB1 0x5761 #CJK UNIFIED IDEOGRAPH+0x9AB2 0x577F #CJK UNIFIED IDEOGRAPH+0x9AB3 0x5789 #CJK UNIFIED IDEOGRAPH+0x9AB4 0x5793 #CJK UNIFIED IDEOGRAPH+0x9AB5 0x57A0 #CJK UNIFIED IDEOGRAPH+0x9AB6 0x57B3 #CJK UNIFIED IDEOGRAPH+0x9AB7 0x57A4 #CJK UNIFIED IDEOGRAPH+0x9AB8 0x57AA #CJK UNIFIED IDEOGRAPH+0x9AB9 0x57B0 #CJK UNIFIED IDEOGRAPH+0x9ABA 0x57C3 #CJK UNIFIED IDEOGRAPH+0x9ABB 0x57C6 #CJK UNIFIED IDEOGRAPH+0x9ABC 0x57D4 #CJK UNIFIED IDEOGRAPH+0x9ABD 0x57D2 #CJK UNIFIED IDEOGRAPH+0x9ABE 0x57D3 #CJK UNIFIED IDEOGRAPH+0x9ABF 0x580A #CJK UNIFIED IDEOGRAPH+0x9AC0 0x57D6 #CJK UNIFIED IDEOGRAPH+0x9AC1 0x57E3 #CJK UNIFIED IDEOGRAPH+0x9AC2 0x580B #CJK UNIFIED IDEOGRAPH+0x9AC3 0x5819 #CJK UNIFIED IDEOGRAPH+0x9AC4 0x581D #CJK UNIFIED IDEOGRAPH+0x9AC5 0x5872 #CJK UNIFIED IDEOGRAPH+0x9AC6 0x5821 #CJK UNIFIED IDEOGRAPH+0x9AC7 0x5862 #CJK UNIFIED IDEOGRAPH+0x9AC8 0x584B #CJK UNIFIED IDEOGRAPH+0x9AC9 0x5870 #CJK UNIFIED IDEOGRAPH+0x9ACA 0x6BC0 #CJK UNIFIED IDEOGRAPH+0x9ACB 0x5852 #CJK UNIFIED IDEOGRAPH+0x9ACC 0x583D #CJK UNIFIED IDEOGRAPH+0x9ACD 0x5879 #CJK UNIFIED IDEOGRAPH+0x9ACE 0x5885 #CJK UNIFIED IDEOGRAPH+0x9ACF 0x58B9 #CJK UNIFIED IDEOGRAPH+0x9AD0 0x589F #CJK UNIFIED IDEOGRAPH+0x9AD1 0x58AB #CJK UNIFIED IDEOGRAPH+0x9AD2 0x58BA #CJK UNIFIED IDEOGRAPH+0x9AD3 0x58DE #CJK UNIFIED IDEOGRAPH+0x9AD4 0x58BB #CJK UNIFIED IDEOGRAPH+0x9AD5 0x58B8 #CJK UNIFIED IDEOGRAPH+0x9AD6 0x58AE #CJK UNIFIED IDEOGRAPH+0x9AD7 0x58C5 #CJK UNIFIED IDEOGRAPH+0x9AD8 0x58D3 #CJK UNIFIED IDEOGRAPH+0x9AD9 0x58D1 #CJK UNIFIED IDEOGRAPH+0x9ADA 0x58D7 #CJK UNIFIED IDEOGRAPH+0x9ADB 0x58D9 #CJK UNIFIED IDEOGRAPH+0x9ADC 0x58D8 #CJK UNIFIED IDEOGRAPH+0x9ADD 0x58E5 #CJK UNIFIED IDEOGRAPH+0x9ADE 0x58DC #CJK UNIFIED IDEOGRAPH+0x9ADF 0x58E4 #CJK UNIFIED IDEOGRAPH+0x9AE0 0x58DF #CJK UNIFIED IDEOGRAPH+0x9AE1 0x58EF #CJK UNIFIED IDEOGRAPH+0x9AE2 0x58FA #CJK UNIFIED IDEOGRAPH+0x9AE3 0x58F9 #CJK UNIFIED IDEOGRAPH+0x9AE4 0x58FB #CJK UNIFIED IDEOGRAPH+0x9AE5 0x58FC #CJK UNIFIED IDEOGRAPH+0x9AE6 0x58FD #CJK UNIFIED IDEOGRAPH+0x9AE7 0x5902 #CJK UNIFIED IDEOGRAPH+0x9AE8 0x590A #CJK UNIFIED IDEOGRAPH+0x9AE9 0x5910 #CJK UNIFIED IDEOGRAPH+0x9AEA 0x591B #CJK UNIFIED IDEOGRAPH+0x9AEB 0x68A6 #CJK UNIFIED IDEOGRAPH+0x9AEC 0x5925 #CJK UNIFIED IDEOGRAPH+0x9AED 0x592C #CJK UNIFIED IDEOGRAPH+0x9AEE 0x592D #CJK UNIFIED IDEOGRAPH+0x9AEF 0x5932 #CJK UNIFIED IDEOGRAPH+0x9AF0 0x5938 #CJK UNIFIED IDEOGRAPH+0x9AF1 0x593E #CJK UNIFIED IDEOGRAPH+0x9AF2 0x7AD2 #CJK UNIFIED IDEOGRAPH+0x9AF3 0x5955 #CJK UNIFIED IDEOGRAPH+0x9AF4 0x5950 #CJK UNIFIED IDEOGRAPH+0x9AF5 0x594E #CJK UNIFIED IDEOGRAPH+0x9AF6 0x595A #CJK UNIFIED IDEOGRAPH+0x9AF7 0x5958 #CJK UNIFIED IDEOGRAPH+0x9AF8 0x5962 #CJK UNIFIED IDEOGRAPH+0x9AF9 0x5960 #CJK UNIFIED IDEOGRAPH+0x9AFA 0x5967 #CJK UNIFIED IDEOGRAPH+0x9AFB 0x596C #CJK UNIFIED IDEOGRAPH+0x9AFC 0x5969 #CJK UNIFIED IDEOGRAPH+0x9B40 0x5978 #CJK UNIFIED IDEOGRAPH+0x9B41 0x5981 #CJK UNIFIED IDEOGRAPH+0x9B42 0x599D #CJK UNIFIED IDEOGRAPH+0x9B43 0x4F5E #CJK UNIFIED IDEOGRAPH+0x9B44 0x4FAB #CJK UNIFIED IDEOGRAPH+0x9B45 0x59A3 #CJK UNIFIED IDEOGRAPH+0x9B46 0x59B2 #CJK UNIFIED IDEOGRAPH+0x9B47 0x59C6 #CJK UNIFIED IDEOGRAPH+0x9B48 0x59E8 #CJK UNIFIED IDEOGRAPH+0x9B49 0x59DC #CJK UNIFIED IDEOGRAPH+0x9B4A 0x598D #CJK UNIFIED IDEOGRAPH+0x9B4B 0x59D9 #CJK UNIFIED IDEOGRAPH+0x9B4C 0x59DA #CJK UNIFIED IDEOGRAPH+0x9B4D 0x5A25 #CJK UNIFIED IDEOGRAPH+0x9B4E 0x5A1F #CJK UNIFIED IDEOGRAPH+0x9B4F 0x5A11 #CJK UNIFIED IDEOGRAPH+0x9B50 0x5A1C #CJK UNIFIED IDEOGRAPH+0x9B51 0x5A09 #CJK UNIFIED IDEOGRAPH+0x9B52 0x5A1A #CJK UNIFIED IDEOGRAPH+0x9B53 0x5A40 #CJK UNIFIED IDEOGRAPH+0x9B54 0x5A6C #CJK UNIFIED IDEOGRAPH+0x9B55 0x5A49 #CJK UNIFIED IDEOGRAPH+0x9B56 0x5A35 #CJK UNIFIED IDEOGRAPH+0x9B57 0x5A36 #CJK UNIFIED IDEOGRAPH+0x9B58 0x5A62 #CJK UNIFIED IDEOGRAPH+0x9B59 0x5A6A #CJK UNIFIED IDEOGRAPH+0x9B5A 0x5A9A #CJK UNIFIED IDEOGRAPH+0x9B5B 0x5ABC #CJK UNIFIED IDEOGRAPH+0x9B5C 0x5ABE #CJK UNIFIED IDEOGRAPH+0x9B5D 0x5ACB #CJK UNIFIED IDEOGRAPH+0x9B5E 0x5AC2 #CJK UNIFIED IDEOGRAPH+0x9B5F 0x5ABD #CJK UNIFIED IDEOGRAPH+0x9B60 0x5AE3 #CJK UNIFIED IDEOGRAPH+0x9B61 0x5AD7 #CJK UNIFIED IDEOGRAPH+0x9B62 0x5AE6 #CJK UNIFIED IDEOGRAPH+0x9B63 0x5AE9 #CJK UNIFIED IDEOGRAPH+0x9B64 0x5AD6 #CJK UNIFIED IDEOGRAPH+0x9B65 0x5AFA #CJK UNIFIED IDEOGRAPH+0x9B66 0x5AFB #CJK UNIFIED IDEOGRAPH+0x9B67 0x5B0C #CJK UNIFIED IDEOGRAPH+0x9B68 0x5B0B #CJK UNIFIED IDEOGRAPH+0x9B69 0x5B16 #CJK UNIFIED IDEOGRAPH+0x9B6A 0x5B32 #CJK UNIFIED IDEOGRAPH+0x9B6B 0x5AD0 #CJK UNIFIED IDEOGRAPH+0x9B6C 0x5B2A #CJK UNIFIED IDEOGRAPH+0x9B6D 0x5B36 #CJK UNIFIED IDEOGRAPH+0x9B6E 0x5B3E #CJK UNIFIED IDEOGRAPH+0x9B6F 0x5B43 #CJK UNIFIED IDEOGRAPH+0x9B70 0x5B45 #CJK UNIFIED IDEOGRAPH+0x9B71 0x5B40 #CJK UNIFIED IDEOGRAPH+0x9B72 0x5B51 #CJK UNIFIED IDEOGRAPH+0x9B73 0x5B55 #CJK UNIFIED IDEOGRAPH+0x9B74 0x5B5A #CJK UNIFIED IDEOGRAPH+0x9B75 0x5B5B #CJK UNIFIED IDEOGRAPH+0x9B76 0x5B65 #CJK UNIFIED IDEOGRAPH+0x9B77 0x5B69 #CJK UNIFIED IDEOGRAPH+0x9B78 0x5B70 #CJK UNIFIED IDEOGRAPH+0x9B79 0x5B73 #CJK UNIFIED IDEOGRAPH+0x9B7A 0x5B75 #CJK UNIFIED IDEOGRAPH+0x9B7B 0x5B78 #CJK UNIFIED IDEOGRAPH+0x9B7C 0x6588 #CJK UNIFIED IDEOGRAPH+0x9B7D 0x5B7A #CJK UNIFIED IDEOGRAPH+0x9B7E 0x5B80 #CJK UNIFIED IDEOGRAPH+0x9B80 0x5B83 #CJK UNIFIED IDEOGRAPH+0x9B81 0x5BA6 #CJK UNIFIED IDEOGRAPH+0x9B82 0x5BB8 #CJK UNIFIED IDEOGRAPH+0x9B83 0x5BC3 #CJK UNIFIED IDEOGRAPH+0x9B84 0x5BC7 #CJK UNIFIED IDEOGRAPH+0x9B85 0x5BC9 #CJK UNIFIED IDEOGRAPH+0x9B86 0x5BD4 #CJK UNIFIED IDEOGRAPH+0x9B87 0x5BD0 #CJK UNIFIED IDEOGRAPH+0x9B88 0x5BE4 #CJK UNIFIED IDEOGRAPH+0x9B89 0x5BE6 #CJK UNIFIED IDEOGRAPH+0x9B8A 0x5BE2 #CJK UNIFIED IDEOGRAPH+0x9B8B 0x5BDE #CJK UNIFIED IDEOGRAPH+0x9B8C 0x5BE5 #CJK UNIFIED IDEOGRAPH+0x9B8D 0x5BEB #CJK UNIFIED IDEOGRAPH+0x9B8E 0x5BF0 #CJK UNIFIED IDEOGRAPH+0x9B8F 0x5BF6 #CJK UNIFIED IDEOGRAPH+0x9B90 0x5BF3 #CJK UNIFIED IDEOGRAPH+0x9B91 0x5C05 #CJK UNIFIED IDEOGRAPH+0x9B92 0x5C07 #CJK UNIFIED IDEOGRAPH+0x9B93 0x5C08 #CJK UNIFIED IDEOGRAPH+0x9B94 0x5C0D #CJK UNIFIED IDEOGRAPH+0x9B95 0x5C13 #CJK UNIFIED IDEOGRAPH+0x9B96 0x5C20 #CJK UNIFIED IDEOGRAPH+0x9B97 0x5C22 #CJK UNIFIED IDEOGRAPH+0x9B98 0x5C28 #CJK UNIFIED IDEOGRAPH+0x9B99 0x5C38 #CJK UNIFIED IDEOGRAPH+0x9B9A 0x5C39 #CJK UNIFIED IDEOGRAPH+0x9B9B 0x5C41 #CJK UNIFIED IDEOGRAPH+0x9B9C 0x5C46 #CJK UNIFIED IDEOGRAPH+0x9B9D 0x5C4E #CJK UNIFIED IDEOGRAPH+0x9B9E 0x5C53 #CJK UNIFIED IDEOGRAPH+0x9B9F 0x5C50 #CJK UNIFIED IDEOGRAPH+0x9BA0 0x5C4F #CJK UNIFIED IDEOGRAPH+0x9BA1 0x5B71 #CJK UNIFIED IDEOGRAPH+0x9BA2 0x5C6C #CJK UNIFIED IDEOGRAPH+0x9BA3 0x5C6E #CJK UNIFIED IDEOGRAPH+0x9BA4 0x4E62 #CJK UNIFIED IDEOGRAPH+0x9BA5 0x5C76 #CJK UNIFIED IDEOGRAPH+0x9BA6 0x5C79 #CJK UNIFIED IDEOGRAPH+0x9BA7 0x5C8C #CJK UNIFIED IDEOGRAPH+0x9BA8 0x5C91 #CJK UNIFIED IDEOGRAPH+0x9BA9 0x5C94 #CJK UNIFIED IDEOGRAPH+0x9BAA 0x599B #CJK UNIFIED IDEOGRAPH+0x9BAB 0x5CAB #CJK UNIFIED IDEOGRAPH+0x9BAC 0x5CBB #CJK UNIFIED IDEOGRAPH+0x9BAD 0x5CB6 #CJK UNIFIED IDEOGRAPH+0x9BAE 0x5CBC #CJK UNIFIED IDEOGRAPH+0x9BAF 0x5CB7 #CJK UNIFIED IDEOGRAPH+0x9BB0 0x5CC5 #CJK UNIFIED IDEOGRAPH+0x9BB1 0x5CBE #CJK UNIFIED IDEOGRAPH+0x9BB2 0x5CC7 #CJK UNIFIED IDEOGRAPH+0x9BB3 0x5CD9 #CJK UNIFIED IDEOGRAPH+0x9BB4 0x5CE9 #CJK UNIFIED IDEOGRAPH+0x9BB5 0x5CFD #CJK UNIFIED IDEOGRAPH+0x9BB6 0x5CFA #CJK UNIFIED IDEOGRAPH+0x9BB7 0x5CED #CJK UNIFIED IDEOGRAPH+0x9BB8 0x5D8C #CJK UNIFIED IDEOGRAPH+0x9BB9 0x5CEA #CJK UNIFIED IDEOGRAPH+0x9BBA 0x5D0B #CJK UNIFIED IDEOGRAPH+0x9BBB 0x5D15 #CJK UNIFIED IDEOGRAPH+0x9BBC 0x5D17 #CJK UNIFIED IDEOGRAPH+0x9BBD 0x5D5C #CJK UNIFIED IDEOGRAPH+0x9BBE 0x5D1F #CJK UNIFIED IDEOGRAPH+0x9BBF 0x5D1B #CJK UNIFIED IDEOGRAPH+0x9BC0 0x5D11 #CJK UNIFIED IDEOGRAPH+0x9BC1 0x5D14 #CJK UNIFIED IDEOGRAPH+0x9BC2 0x5D22 #CJK UNIFIED IDEOGRAPH+0x9BC3 0x5D1A #CJK UNIFIED IDEOGRAPH+0x9BC4 0x5D19 #CJK UNIFIED IDEOGRAPH+0x9BC5 0x5D18 #CJK UNIFIED IDEOGRAPH+0x9BC6 0x5D4C #CJK UNIFIED IDEOGRAPH+0x9BC7 0x5D52 #CJK UNIFIED IDEOGRAPH+0x9BC8 0x5D4E #CJK UNIFIED IDEOGRAPH+0x9BC9 0x5D4B #CJK UNIFIED IDEOGRAPH+0x9BCA 0x5D6C #CJK UNIFIED IDEOGRAPH+0x9BCB 0x5D73 #CJK UNIFIED IDEOGRAPH+0x9BCC 0x5D76 #CJK UNIFIED IDEOGRAPH+0x9BCD 0x5D87 #CJK UNIFIED IDEOGRAPH+0x9BCE 0x5D84 #CJK UNIFIED IDEOGRAPH+0x9BCF 0x5D82 #CJK UNIFIED IDEOGRAPH+0x9BD0 0x5DA2 #CJK UNIFIED IDEOGRAPH+0x9BD1 0x5D9D #CJK UNIFIED IDEOGRAPH+0x9BD2 0x5DAC #CJK UNIFIED IDEOGRAPH+0x9BD3 0x5DAE #CJK UNIFIED IDEOGRAPH+0x9BD4 0x5DBD #CJK UNIFIED IDEOGRAPH+0x9BD5 0x5D90 #CJK UNIFIED IDEOGRAPH+0x9BD6 0x5DB7 #CJK UNIFIED IDEOGRAPH+0x9BD7 0x5DBC #CJK UNIFIED IDEOGRAPH+0x9BD8 0x5DC9 #CJK UNIFIED IDEOGRAPH+0x9BD9 0x5DCD #CJK UNIFIED IDEOGRAPH+0x9BDA 0x5DD3 #CJK UNIFIED IDEOGRAPH+0x9BDB 0x5DD2 #CJK UNIFIED IDEOGRAPH+0x9BDC 0x5DD6 #CJK UNIFIED IDEOGRAPH+0x9BDD 0x5DDB #CJK UNIFIED IDEOGRAPH+0x9BDE 0x5DEB #CJK UNIFIED IDEOGRAPH+0x9BDF 0x5DF2 #CJK UNIFIED IDEOGRAPH+0x9BE0 0x5DF5 #CJK UNIFIED IDEOGRAPH+0x9BE1 0x5E0B #CJK UNIFIED IDEOGRAPH+0x9BE2 0x5E1A #CJK UNIFIED IDEOGRAPH+0x9BE3 0x5E19 #CJK UNIFIED IDEOGRAPH+0x9BE4 0x5E11 #CJK UNIFIED IDEOGRAPH+0x9BE5 0x5E1B #CJK UNIFIED IDEOGRAPH+0x9BE6 0x5E36 #CJK UNIFIED IDEOGRAPH+0x9BE7 0x5E37 #CJK UNIFIED IDEOGRAPH+0x9BE8 0x5E44 #CJK UNIFIED IDEOGRAPH+0x9BE9 0x5E43 #CJK UNIFIED IDEOGRAPH+0x9BEA 0x5E40 #CJK UNIFIED IDEOGRAPH+0x9BEB 0x5E4E #CJK UNIFIED IDEOGRAPH+0x9BEC 0x5E57 #CJK UNIFIED IDEOGRAPH+0x9BED 0x5E54 #CJK UNIFIED IDEOGRAPH+0x9BEE 0x5E5F #CJK UNIFIED IDEOGRAPH+0x9BEF 0x5E62 #CJK UNIFIED IDEOGRAPH+0x9BF0 0x5E64 #CJK UNIFIED IDEOGRAPH+0x9BF1 0x5E47 #CJK UNIFIED IDEOGRAPH+0x9BF2 0x5E75 #CJK UNIFIED IDEOGRAPH+0x9BF3 0x5E76 #CJK UNIFIED IDEOGRAPH+0x9BF4 0x5E7A #CJK UNIFIED IDEOGRAPH+0x9BF5 0x9EBC #CJK UNIFIED IDEOGRAPH+0x9BF6 0x5E7F #CJK UNIFIED IDEOGRAPH+0x9BF7 0x5EA0 #CJK UNIFIED IDEOGRAPH+0x9BF8 0x5EC1 #CJK UNIFIED IDEOGRAPH+0x9BF9 0x5EC2 #CJK UNIFIED IDEOGRAPH+0x9BFA 0x5EC8 #CJK UNIFIED IDEOGRAPH+0x9BFB 0x5ED0 #CJK UNIFIED IDEOGRAPH+0x9BFC 0x5ECF #CJK UNIFIED IDEOGRAPH+0x9C40 0x5ED6 #CJK UNIFIED IDEOGRAPH+0x9C41 0x5EE3 #CJK UNIFIED IDEOGRAPH+0x9C42 0x5EDD #CJK UNIFIED IDEOGRAPH+0x9C43 0x5EDA #CJK UNIFIED IDEOGRAPH+0x9C44 0x5EDB #CJK UNIFIED IDEOGRAPH+0x9C45 0x5EE2 #CJK UNIFIED IDEOGRAPH+0x9C46 0x5EE1 #CJK UNIFIED IDEOGRAPH+0x9C47 0x5EE8 #CJK UNIFIED IDEOGRAPH+0x9C48 0x5EE9 #CJK UNIFIED IDEOGRAPH+0x9C49 0x5EEC #CJK UNIFIED IDEOGRAPH+0x9C4A 0x5EF1 #CJK UNIFIED IDEOGRAPH+0x9C4B 0x5EF3 #CJK UNIFIED IDEOGRAPH+0x9C4C 0x5EF0 #CJK UNIFIED IDEOGRAPH+0x9C4D 0x5EF4 #CJK UNIFIED IDEOGRAPH+0x9C4E 0x5EF8 #CJK UNIFIED IDEOGRAPH+0x9C4F 0x5EFE #CJK UNIFIED IDEOGRAPH+0x9C50 0x5F03 #CJK UNIFIED IDEOGRAPH+0x9C51 0x5F09 #CJK UNIFIED IDEOGRAPH+0x9C52 0x5F5D #CJK UNIFIED IDEOGRAPH+0x9C53 0x5F5C #CJK UNIFIED IDEOGRAPH+0x9C54 0x5F0B #CJK UNIFIED IDEOGRAPH+0x9C55 0x5F11 #CJK UNIFIED IDEOGRAPH+0x9C56 0x5F16 #CJK UNIFIED IDEOGRAPH+0x9C57 0x5F29 #CJK UNIFIED IDEOGRAPH+0x9C58 0x5F2D #CJK UNIFIED IDEOGRAPH+0x9C59 0x5F38 #CJK UNIFIED IDEOGRAPH+0x9C5A 0x5F41 #CJK UNIFIED IDEOGRAPH+0x9C5B 0x5F48 #CJK UNIFIED IDEOGRAPH+0x9C5C 0x5F4C #CJK UNIFIED IDEOGRAPH+0x9C5D 0x5F4E #CJK UNIFIED IDEOGRAPH+0x9C5E 0x5F2F #CJK UNIFIED IDEOGRAPH+0x9C5F 0x5F51 #CJK UNIFIED IDEOGRAPH+0x9C60 0x5F56 #CJK UNIFIED IDEOGRAPH+0x9C61 0x5F57 #CJK UNIFIED IDEOGRAPH+0x9C62 0x5F59 #CJK UNIFIED IDEOGRAPH+0x9C63 0x5F61 #CJK UNIFIED IDEOGRAPH+0x9C64 0x5F6D #CJK UNIFIED IDEOGRAPH+0x9C65 0x5F73 #CJK UNIFIED IDEOGRAPH+0x9C66 0x5F77 #CJK UNIFIED IDEOGRAPH+0x9C67 0x5F83 #CJK UNIFIED IDEOGRAPH+0x9C68 0x5F82 #CJK UNIFIED IDEOGRAPH+0x9C69 0x5F7F #CJK UNIFIED IDEOGRAPH+0x9C6A 0x5F8A #CJK UNIFIED IDEOGRAPH+0x9C6B 0x5F88 #CJK UNIFIED IDEOGRAPH+0x9C6C 0x5F91 #CJK UNIFIED IDEOGRAPH+0x9C6D 0x5F87 #CJK UNIFIED IDEOGRAPH+0x9C6E 0x5F9E #CJK UNIFIED IDEOGRAPH+0x9C6F 0x5F99 #CJK UNIFIED IDEOGRAPH+0x9C70 0x5F98 #CJK UNIFIED IDEOGRAPH+0x9C71 0x5FA0 #CJK UNIFIED IDEOGRAPH+0x9C72 0x5FA8 #CJK UNIFIED IDEOGRAPH+0x9C73 0x5FAD #CJK UNIFIED IDEOGRAPH+0x9C74 0x5FBC #CJK UNIFIED IDEOGRAPH+0x9C75 0x5FD6 #CJK UNIFIED IDEOGRAPH+0x9C76 0x5FFB #CJK UNIFIED IDEOGRAPH+0x9C77 0x5FE4 #CJK UNIFIED IDEOGRAPH+0x9C78 0x5FF8 #CJK UNIFIED IDEOGRAPH+0x9C79 0x5FF1 #CJK UNIFIED IDEOGRAPH+0x9C7A 0x5FDD #CJK UNIFIED IDEOGRAPH+0x9C7B 0x60B3 #CJK UNIFIED IDEOGRAPH+0x9C7C 0x5FFF #CJK UNIFIED IDEOGRAPH+0x9C7D 0x6021 #CJK UNIFIED IDEOGRAPH+0x9C7E 0x6060 #CJK UNIFIED IDEOGRAPH+0x9C80 0x6019 #CJK UNIFIED IDEOGRAPH+0x9C81 0x6010 #CJK UNIFIED IDEOGRAPH+0x9C82 0x6029 #CJK UNIFIED IDEOGRAPH+0x9C83 0x600E #CJK UNIFIED IDEOGRAPH+0x9C84 0x6031 #CJK UNIFIED IDEOGRAPH+0x9C85 0x601B #CJK UNIFIED IDEOGRAPH+0x9C86 0x6015 #CJK UNIFIED IDEOGRAPH+0x9C87 0x602B #CJK UNIFIED IDEOGRAPH+0x9C88 0x6026 #CJK UNIFIED IDEOGRAPH+0x9C89 0x600F #CJK UNIFIED IDEOGRAPH+0x9C8A 0x603A #CJK UNIFIED IDEOGRAPH+0x9C8B 0x605A #CJK UNIFIED IDEOGRAPH+0x9C8C 0x6041 #CJK UNIFIED IDEOGRAPH+0x9C8D 0x606A #CJK UNIFIED IDEOGRAPH+0x9C8E 0x6077 #CJK UNIFIED IDEOGRAPH+0x9C8F 0x605F #CJK UNIFIED IDEOGRAPH+0x9C90 0x604A #CJK UNIFIED IDEOGRAPH+0x9C91 0x6046 #CJK UNIFIED IDEOGRAPH+0x9C92 0x604D #CJK UNIFIED IDEOGRAPH+0x9C93 0x6063 #CJK UNIFIED IDEOGRAPH+0x9C94 0x6043 #CJK UNIFIED IDEOGRAPH+0x9C95 0x6064 #CJK UNIFIED IDEOGRAPH+0x9C96 0x6042 #CJK UNIFIED IDEOGRAPH+0x9C97 0x606C #CJK UNIFIED IDEOGRAPH+0x9C98 0x606B #CJK UNIFIED IDEOGRAPH+0x9C99 0x6059 #CJK UNIFIED IDEOGRAPH+0x9C9A 0x6081 #CJK UNIFIED IDEOGRAPH+0x9C9B 0x608D #CJK UNIFIED IDEOGRAPH+0x9C9C 0x60E7 #CJK UNIFIED IDEOGRAPH+0x9C9D 0x6083 #CJK UNIFIED IDEOGRAPH+0x9C9E 0x609A #CJK UNIFIED IDEOGRAPH+0x9C9F 0x6084 #CJK UNIFIED IDEOGRAPH+0x9CA0 0x609B #CJK UNIFIED IDEOGRAPH+0x9CA1 0x6096 #CJK UNIFIED IDEOGRAPH+0x9CA2 0x6097 #CJK UNIFIED IDEOGRAPH+0x9CA3 0x6092 #CJK UNIFIED IDEOGRAPH+0x9CA4 0x60A7 #CJK UNIFIED IDEOGRAPH+0x9CA5 0x608B #CJK UNIFIED IDEOGRAPH+0x9CA6 0x60E1 #CJK UNIFIED IDEOGRAPH+0x9CA7 0x60B8 #CJK UNIFIED IDEOGRAPH+0x9CA8 0x60E0 #CJK UNIFIED IDEOGRAPH+0x9CA9 0x60D3 #CJK UNIFIED IDEOGRAPH+0x9CAA 0x60B4 #CJK UNIFIED IDEOGRAPH+0x9CAB 0x5FF0 #CJK UNIFIED IDEOGRAPH+0x9CAC 0x60BD #CJK UNIFIED IDEOGRAPH+0x9CAD 0x60C6 #CJK UNIFIED IDEOGRAPH+0x9CAE 0x60B5 #CJK UNIFIED IDEOGRAPH+0x9CAF 0x60D8 #CJK UNIFIED IDEOGRAPH+0x9CB0 0x614D #CJK UNIFIED IDEOGRAPH+0x9CB1 0x6115 #CJK UNIFIED IDEOGRAPH+0x9CB2 0x6106 #CJK UNIFIED IDEOGRAPH+0x9CB3 0x60F6 #CJK UNIFIED IDEOGRAPH+0x9CB4 0x60F7 #CJK UNIFIED IDEOGRAPH+0x9CB5 0x6100 #CJK UNIFIED IDEOGRAPH+0x9CB6 0x60F4 #CJK UNIFIED IDEOGRAPH+0x9CB7 0x60FA #CJK UNIFIED IDEOGRAPH+0x9CB8 0x6103 #CJK UNIFIED IDEOGRAPH+0x9CB9 0x6121 #CJK UNIFIED IDEOGRAPH+0x9CBA 0x60FB #CJK UNIFIED IDEOGRAPH+0x9CBB 0x60F1 #CJK UNIFIED IDEOGRAPH+0x9CBC 0x610D #CJK UNIFIED IDEOGRAPH+0x9CBD 0x610E #CJK UNIFIED IDEOGRAPH+0x9CBE 0x6147 #CJK UNIFIED IDEOGRAPH+0x9CBF 0x613E #CJK UNIFIED IDEOGRAPH+0x9CC0 0x6128 #CJK UNIFIED IDEOGRAPH+0x9CC1 0x6127 #CJK UNIFIED IDEOGRAPH+0x9CC2 0x614A #CJK UNIFIED IDEOGRAPH+0x9CC3 0x613F #CJK UNIFIED IDEOGRAPH+0x9CC4 0x613C #CJK UNIFIED IDEOGRAPH+0x9CC5 0x612C #CJK UNIFIED IDEOGRAPH+0x9CC6 0x6134 #CJK UNIFIED IDEOGRAPH+0x9CC7 0x613D #CJK UNIFIED IDEOGRAPH+0x9CC8 0x6142 #CJK UNIFIED IDEOGRAPH+0x9CC9 0x6144 #CJK UNIFIED IDEOGRAPH+0x9CCA 0x6173 #CJK UNIFIED IDEOGRAPH+0x9CCB 0x6177 #CJK UNIFIED IDEOGRAPH+0x9CCC 0x6158 #CJK UNIFIED IDEOGRAPH+0x9CCD 0x6159 #CJK UNIFIED IDEOGRAPH+0x9CCE 0x615A #CJK UNIFIED IDEOGRAPH+0x9CCF 0x616B #CJK UNIFIED IDEOGRAPH+0x9CD0 0x6174 #CJK UNIFIED IDEOGRAPH+0x9CD1 0x616F #CJK UNIFIED IDEOGRAPH+0x9CD2 0x6165 #CJK UNIFIED IDEOGRAPH+0x9CD3 0x6171 #CJK UNIFIED IDEOGRAPH+0x9CD4 0x615F #CJK UNIFIED IDEOGRAPH+0x9CD5 0x615D #CJK UNIFIED IDEOGRAPH+0x9CD6 0x6153 #CJK UNIFIED IDEOGRAPH+0x9CD7 0x6175 #CJK UNIFIED IDEOGRAPH+0x9CD8 0x6199 #CJK UNIFIED IDEOGRAPH+0x9CD9 0x6196 #CJK UNIFIED IDEOGRAPH+0x9CDA 0x6187 #CJK UNIFIED IDEOGRAPH+0x9CDB 0x61AC #CJK UNIFIED IDEOGRAPH+0x9CDC 0x6194 #CJK UNIFIED IDEOGRAPH+0x9CDD 0x619A #CJK UNIFIED IDEOGRAPH+0x9CDE 0x618A #CJK UNIFIED IDEOGRAPH+0x9CDF 0x6191 #CJK UNIFIED IDEOGRAPH+0x9CE0 0x61AB #CJK UNIFIED IDEOGRAPH+0x9CE1 0x61AE #CJK UNIFIED IDEOGRAPH+0x9CE2 0x61CC #CJK UNIFIED IDEOGRAPH+0x9CE3 0x61CA #CJK UNIFIED IDEOGRAPH+0x9CE4 0x61C9 #CJK UNIFIED IDEOGRAPH+0x9CE5 0x61F7 #CJK UNIFIED IDEOGRAPH+0x9CE6 0x61C8 #CJK UNIFIED IDEOGRAPH+0x9CE7 0x61C3 #CJK UNIFIED IDEOGRAPH+0x9CE8 0x61C6 #CJK UNIFIED IDEOGRAPH+0x9CE9 0x61BA #CJK UNIFIED IDEOGRAPH+0x9CEA 0x61CB #CJK UNIFIED IDEOGRAPH+0x9CEB 0x7F79 #CJK UNIFIED IDEOGRAPH+0x9CEC 0x61CD #CJK UNIFIED IDEOGRAPH+0x9CED 0x61E6 #CJK UNIFIED IDEOGRAPH+0x9CEE 0x61E3 #CJK UNIFIED IDEOGRAPH+0x9CEF 0x61F6 #CJK UNIFIED IDEOGRAPH+0x9CF0 0x61FA #CJK UNIFIED IDEOGRAPH+0x9CF1 0x61F4 #CJK UNIFIED IDEOGRAPH+0x9CF2 0x61FF #CJK UNIFIED IDEOGRAPH+0x9CF3 0x61FD #CJK UNIFIED IDEOGRAPH+0x9CF4 0x61FC #CJK UNIFIED IDEOGRAPH+0x9CF5 0x61FE #CJK UNIFIED IDEOGRAPH+0x9CF6 0x6200 #CJK UNIFIED IDEOGRAPH+0x9CF7 0x6208 #CJK UNIFIED IDEOGRAPH+0x9CF8 0x6209 #CJK UNIFIED IDEOGRAPH+0x9CF9 0x620D #CJK UNIFIED IDEOGRAPH+0x9CFA 0x620C #CJK UNIFIED IDEOGRAPH+0x9CFB 0x6214 #CJK UNIFIED IDEOGRAPH+0x9CFC 0x621B #CJK UNIFIED IDEOGRAPH+0x9D40 0x621E #CJK UNIFIED IDEOGRAPH+0x9D41 0x6221 #CJK UNIFIED IDEOGRAPH+0x9D42 0x622A #CJK UNIFIED IDEOGRAPH+0x9D43 0x622E #CJK UNIFIED IDEOGRAPH+0x9D44 0x6230 #CJK UNIFIED IDEOGRAPH+0x9D45 0x6232 #CJK UNIFIED IDEOGRAPH+0x9D46 0x6233 #CJK UNIFIED IDEOGRAPH+0x9D47 0x6241 #CJK UNIFIED IDEOGRAPH+0x9D48 0x624E #CJK UNIFIED IDEOGRAPH+0x9D49 0x625E #CJK UNIFIED IDEOGRAPH+0x9D4A 0x6263 #CJK UNIFIED IDEOGRAPH+0x9D4B 0x625B #CJK UNIFIED IDEOGRAPH+0x9D4C 0x6260 #CJK UNIFIED IDEOGRAPH+0x9D4D 0x6268 #CJK UNIFIED IDEOGRAPH+0x9D4E 0x627C #CJK UNIFIED IDEOGRAPH+0x9D4F 0x6282 #CJK UNIFIED IDEOGRAPH+0x9D50 0x6289 #CJK UNIFIED IDEOGRAPH+0x9D51 0x627E #CJK UNIFIED IDEOGRAPH+0x9D52 0x6292 #CJK UNIFIED IDEOGRAPH+0x9D53 0x6293 #CJK UNIFIED IDEOGRAPH+0x9D54 0x6296 #CJK UNIFIED IDEOGRAPH+0x9D55 0x62D4 #CJK UNIFIED IDEOGRAPH+0x9D56 0x6283 #CJK UNIFIED IDEOGRAPH+0x9D57 0x6294 #CJK UNIFIED IDEOGRAPH+0x9D58 0x62D7 #CJK UNIFIED IDEOGRAPH+0x9D59 0x62D1 #CJK UNIFIED IDEOGRAPH+0x9D5A 0x62BB #CJK UNIFIED IDEOGRAPH+0x9D5B 0x62CF #CJK UNIFIED IDEOGRAPH+0x9D5C 0x62FF #CJK UNIFIED IDEOGRAPH+0x9D5D 0x62C6 #CJK UNIFIED IDEOGRAPH+0x9D5E 0x64D4 #CJK UNIFIED IDEOGRAPH+0x9D5F 0x62C8 #CJK UNIFIED IDEOGRAPH+0x9D60 0x62DC #CJK UNIFIED IDEOGRAPH+0x9D61 0x62CC #CJK UNIFIED IDEOGRAPH+0x9D62 0x62CA #CJK UNIFIED IDEOGRAPH+0x9D63 0x62C2 #CJK UNIFIED IDEOGRAPH+0x9D64 0x62C7 #CJK UNIFIED IDEOGRAPH+0x9D65 0x629B #CJK UNIFIED IDEOGRAPH+0x9D66 0x62C9 #CJK UNIFIED IDEOGRAPH+0x9D67 0x630C #CJK UNIFIED IDEOGRAPH+0x9D68 0x62EE #CJK UNIFIED IDEOGRAPH+0x9D69 0x62F1 #CJK UNIFIED IDEOGRAPH+0x9D6A 0x6327 #CJK UNIFIED IDEOGRAPH+0x9D6B 0x6302 #CJK UNIFIED IDEOGRAPH+0x9D6C 0x6308 #CJK UNIFIED IDEOGRAPH+0x9D6D 0x62EF #CJK UNIFIED IDEOGRAPH+0x9D6E 0x62F5 #CJK UNIFIED IDEOGRAPH+0x9D6F 0x6350 #CJK UNIFIED IDEOGRAPH+0x9D70 0x633E #CJK UNIFIED IDEOGRAPH+0x9D71 0x634D #CJK UNIFIED IDEOGRAPH+0x9D72 0x641C #CJK UNIFIED IDEOGRAPH+0x9D73 0x634F #CJK UNIFIED IDEOGRAPH+0x9D74 0x6396 #CJK UNIFIED IDEOGRAPH+0x9D75 0x638E #CJK UNIFIED IDEOGRAPH+0x9D76 0x6380 #CJK UNIFIED IDEOGRAPH+0x9D77 0x63AB #CJK UNIFIED IDEOGRAPH+0x9D78 0x6376 #CJK UNIFIED IDEOGRAPH+0x9D79 0x63A3 #CJK UNIFIED IDEOGRAPH+0x9D7A 0x638F #CJK UNIFIED IDEOGRAPH+0x9D7B 0x6389 #CJK UNIFIED IDEOGRAPH+0x9D7C 0x639F #CJK UNIFIED IDEOGRAPH+0x9D7D 0x63B5 #CJK UNIFIED IDEOGRAPH+0x9D7E 0x636B #CJK UNIFIED IDEOGRAPH+0x9D80 0x6369 #CJK UNIFIED IDEOGRAPH+0x9D81 0x63BE #CJK UNIFIED IDEOGRAPH+0x9D82 0x63E9 #CJK UNIFIED IDEOGRAPH+0x9D83 0x63C0 #CJK UNIFIED IDEOGRAPH+0x9D84 0x63C6 #CJK UNIFIED IDEOGRAPH+0x9D85 0x63E3 #CJK UNIFIED IDEOGRAPH+0x9D86 0x63C9 #CJK UNIFIED IDEOGRAPH+0x9D87 0x63D2 #CJK UNIFIED IDEOGRAPH+0x9D88 0x63F6 #CJK UNIFIED IDEOGRAPH+0x9D89 0x63C4 #CJK UNIFIED IDEOGRAPH+0x9D8A 0x6416 #CJK UNIFIED IDEOGRAPH+0x9D8B 0x6434 #CJK UNIFIED IDEOGRAPH+0x9D8C 0x6406 #CJK UNIFIED IDEOGRAPH+0x9D8D 0x6413 #CJK UNIFIED IDEOGRAPH+0x9D8E 0x6426 #CJK UNIFIED IDEOGRAPH+0x9D8F 0x6436 #CJK UNIFIED IDEOGRAPH+0x9D90 0x651D #CJK UNIFIED IDEOGRAPH+0x9D91 0x6417 #CJK UNIFIED IDEOGRAPH+0x9D92 0x6428 #CJK UNIFIED IDEOGRAPH+0x9D93 0x640F #CJK UNIFIED IDEOGRAPH+0x9D94 0x6467 #CJK UNIFIED IDEOGRAPH+0x9D95 0x646F #CJK UNIFIED IDEOGRAPH+0x9D96 0x6476 #CJK UNIFIED IDEOGRAPH+0x9D97 0x644E #CJK UNIFIED IDEOGRAPH+0x9D98 0x652A #CJK UNIFIED IDEOGRAPH+0x9D99 0x6495 #CJK UNIFIED IDEOGRAPH+0x9D9A 0x6493 #CJK UNIFIED IDEOGRAPH+0x9D9B 0x64A5 #CJK UNIFIED IDEOGRAPH+0x9D9C 0x64A9 #CJK UNIFIED IDEOGRAPH+0x9D9D 0x6488 #CJK UNIFIED IDEOGRAPH+0x9D9E 0x64BC #CJK UNIFIED IDEOGRAPH+0x9D9F 0x64DA #CJK UNIFIED IDEOGRAPH+0x9DA0 0x64D2 #CJK UNIFIED IDEOGRAPH+0x9DA1 0x64C5 #CJK UNIFIED IDEOGRAPH+0x9DA2 0x64C7 #CJK UNIFIED IDEOGRAPH+0x9DA3 0x64BB #CJK UNIFIED IDEOGRAPH+0x9DA4 0x64D8 #CJK UNIFIED IDEOGRAPH+0x9DA5 0x64C2 #CJK UNIFIED IDEOGRAPH+0x9DA6 0x64F1 #CJK UNIFIED IDEOGRAPH+0x9DA7 0x64E7 #CJK UNIFIED IDEOGRAPH+0x9DA8 0x8209 #CJK UNIFIED IDEOGRAPH+0x9DA9 0x64E0 #CJK UNIFIED IDEOGRAPH+0x9DAA 0x64E1 #CJK UNIFIED IDEOGRAPH+0x9DAB 0x62AC #CJK UNIFIED IDEOGRAPH+0x9DAC 0x64E3 #CJK UNIFIED IDEOGRAPH+0x9DAD 0x64EF #CJK UNIFIED IDEOGRAPH+0x9DAE 0x652C #CJK UNIFIED IDEOGRAPH+0x9DAF 0x64F6 #CJK UNIFIED IDEOGRAPH+0x9DB0 0x64F4 #CJK UNIFIED IDEOGRAPH+0x9DB1 0x64F2 #CJK UNIFIED IDEOGRAPH+0x9DB2 0x64FA #CJK UNIFIED IDEOGRAPH+0x9DB3 0x6500 #CJK UNIFIED IDEOGRAPH+0x9DB4 0x64FD #CJK UNIFIED IDEOGRAPH+0x9DB5 0x6518 #CJK UNIFIED IDEOGRAPH+0x9DB6 0x651C #CJK UNIFIED IDEOGRAPH+0x9DB7 0x6505 #CJK UNIFIED IDEOGRAPH+0x9DB8 0x6524 #CJK UNIFIED IDEOGRAPH+0x9DB9 0x6523 #CJK UNIFIED IDEOGRAPH+0x9DBA 0x652B #CJK UNIFIED IDEOGRAPH+0x9DBB 0x6534 #CJK UNIFIED IDEOGRAPH+0x9DBC 0x6535 #CJK UNIFIED IDEOGRAPH+0x9DBD 0x6537 #CJK UNIFIED IDEOGRAPH+0x9DBE 0x6536 #CJK UNIFIED IDEOGRAPH+0x9DBF 0x6538 #CJK UNIFIED IDEOGRAPH+0x9DC0 0x754B #CJK UNIFIED IDEOGRAPH+0x9DC1 0x6548 #CJK UNIFIED IDEOGRAPH+0x9DC2 0x6556 #CJK UNIFIED IDEOGRAPH+0x9DC3 0x6555 #CJK UNIFIED IDEOGRAPH+0x9DC4 0x654D #CJK UNIFIED IDEOGRAPH+0x9DC5 0x6558 #CJK UNIFIED IDEOGRAPH+0x9DC6 0x655E #CJK UNIFIED IDEOGRAPH+0x9DC7 0x655D #CJK UNIFIED IDEOGRAPH+0x9DC8 0x6572 #CJK UNIFIED IDEOGRAPH+0x9DC9 0x6578 #CJK UNIFIED IDEOGRAPH+0x9DCA 0x6582 #CJK UNIFIED IDEOGRAPH+0x9DCB 0x6583 #CJK UNIFIED IDEOGRAPH+0x9DCC 0x8B8A #CJK UNIFIED IDEOGRAPH+0x9DCD 0x659B #CJK UNIFIED IDEOGRAPH+0x9DCE 0x659F #CJK UNIFIED IDEOGRAPH+0x9DCF 0x65AB #CJK UNIFIED IDEOGRAPH+0x9DD0 0x65B7 #CJK UNIFIED IDEOGRAPH+0x9DD1 0x65C3 #CJK UNIFIED IDEOGRAPH+0x9DD2 0x65C6 #CJK UNIFIED IDEOGRAPH+0x9DD3 0x65C1 #CJK UNIFIED IDEOGRAPH+0x9DD4 0x65C4 #CJK UNIFIED IDEOGRAPH+0x9DD5 0x65CC #CJK UNIFIED IDEOGRAPH+0x9DD6 0x65D2 #CJK UNIFIED IDEOGRAPH+0x9DD7 0x65DB #CJK UNIFIED IDEOGRAPH+0x9DD8 0x65D9 #CJK UNIFIED IDEOGRAPH+0x9DD9 0x65E0 #CJK UNIFIED IDEOGRAPH+0x9DDA 0x65E1 #CJK UNIFIED IDEOGRAPH+0x9DDB 0x65F1 #CJK UNIFIED IDEOGRAPH+0x9DDC 0x6772 #CJK UNIFIED IDEOGRAPH+0x9DDD 0x660A #CJK UNIFIED IDEOGRAPH+0x9DDE 0x6603 #CJK UNIFIED IDEOGRAPH+0x9DDF 0x65FB #CJK UNIFIED IDEOGRAPH+0x9DE0 0x6773 #CJK UNIFIED IDEOGRAPH+0x9DE1 0x6635 #CJK UNIFIED IDEOGRAPH+0x9DE2 0x6636 #CJK UNIFIED IDEOGRAPH+0x9DE3 0x6634 #CJK UNIFIED IDEOGRAPH+0x9DE4 0x661C #CJK UNIFIED IDEOGRAPH+0x9DE5 0x664F #CJK UNIFIED IDEOGRAPH+0x9DE6 0x6644 #CJK UNIFIED IDEOGRAPH+0x9DE7 0x6649 #CJK UNIFIED IDEOGRAPH+0x9DE8 0x6641 #CJK UNIFIED IDEOGRAPH+0x9DE9 0x665E #CJK UNIFIED IDEOGRAPH+0x9DEA 0x665D #CJK UNIFIED IDEOGRAPH+0x9DEB 0x6664 #CJK UNIFIED IDEOGRAPH+0x9DEC 0x6667 #CJK UNIFIED IDEOGRAPH+0x9DED 0x6668 #CJK UNIFIED IDEOGRAPH+0x9DEE 0x665F #CJK UNIFIED IDEOGRAPH+0x9DEF 0x6662 #CJK UNIFIED IDEOGRAPH+0x9DF0 0x6670 #CJK UNIFIED IDEOGRAPH+0x9DF1 0x6683 #CJK UNIFIED IDEOGRAPH+0x9DF2 0x6688 #CJK UNIFIED IDEOGRAPH+0x9DF3 0x668E #CJK UNIFIED IDEOGRAPH+0x9DF4 0x6689 #CJK UNIFIED IDEOGRAPH+0x9DF5 0x6684 #CJK UNIFIED IDEOGRAPH+0x9DF6 0x6698 #CJK UNIFIED IDEOGRAPH+0x9DF7 0x669D #CJK UNIFIED IDEOGRAPH+0x9DF8 0x66C1 #CJK UNIFIED IDEOGRAPH+0x9DF9 0x66B9 #CJK UNIFIED IDEOGRAPH+0x9DFA 0x66C9 #CJK UNIFIED IDEOGRAPH+0x9DFB 0x66BE #CJK UNIFIED IDEOGRAPH+0x9DFC 0x66BC #CJK UNIFIED IDEOGRAPH+0x9E40 0x66C4 #CJK UNIFIED IDEOGRAPH+0x9E41 0x66B8 #CJK UNIFIED IDEOGRAPH+0x9E42 0x66D6 #CJK UNIFIED IDEOGRAPH+0x9E43 0x66DA #CJK UNIFIED IDEOGRAPH+0x9E44 0x66E0 #CJK UNIFIED IDEOGRAPH+0x9E45 0x663F #CJK UNIFIED IDEOGRAPH+0x9E46 0x66E6 #CJK UNIFIED IDEOGRAPH+0x9E47 0x66E9 #CJK UNIFIED IDEOGRAPH+0x9E48 0x66F0 #CJK UNIFIED IDEOGRAPH+0x9E49 0x66F5 #CJK UNIFIED IDEOGRAPH+0x9E4A 0x66F7 #CJK UNIFIED IDEOGRAPH+0x9E4B 0x670F #CJK UNIFIED IDEOGRAPH+0x9E4C 0x6716 #CJK UNIFIED IDEOGRAPH+0x9E4D 0x671E #CJK UNIFIED IDEOGRAPH+0x9E4E 0x6726 #CJK UNIFIED IDEOGRAPH+0x9E4F 0x6727 #CJK UNIFIED IDEOGRAPH+0x9E50 0x9738 #CJK UNIFIED IDEOGRAPH+0x9E51 0x672E #CJK UNIFIED IDEOGRAPH+0x9E52 0x673F #CJK UNIFIED IDEOGRAPH+0x9E53 0x6736 #CJK UNIFIED IDEOGRAPH+0x9E54 0x6741 #CJK UNIFIED IDEOGRAPH+0x9E55 0x6738 #CJK UNIFIED IDEOGRAPH+0x9E56 0x6737 #CJK UNIFIED IDEOGRAPH+0x9E57 0x6746 #CJK UNIFIED IDEOGRAPH+0x9E58 0x675E #CJK UNIFIED IDEOGRAPH+0x9E59 0x6760 #CJK UNIFIED IDEOGRAPH+0x9E5A 0x6759 #CJK UNIFIED IDEOGRAPH+0x9E5B 0x6763 #CJK UNIFIED IDEOGRAPH+0x9E5C 0x6764 #CJK UNIFIED IDEOGRAPH+0x9E5D 0x6789 #CJK UNIFIED IDEOGRAPH+0x9E5E 0x6770 #CJK UNIFIED IDEOGRAPH+0x9E5F 0x67A9 #CJK UNIFIED IDEOGRAPH+0x9E60 0x677C #CJK UNIFIED IDEOGRAPH+0x9E61 0x676A #CJK UNIFIED IDEOGRAPH+0x9E62 0x678C #CJK UNIFIED IDEOGRAPH+0x9E63 0x678B #CJK UNIFIED IDEOGRAPH+0x9E64 0x67A6 #CJK UNIFIED IDEOGRAPH+0x9E65 0x67A1 #CJK UNIFIED IDEOGRAPH+0x9E66 0x6785 #CJK UNIFIED IDEOGRAPH+0x9E67 0x67B7 #CJK UNIFIED IDEOGRAPH+0x9E68 0x67EF #CJK UNIFIED IDEOGRAPH+0x9E69 0x67B4 #CJK UNIFIED IDEOGRAPH+0x9E6A 0x67EC #CJK UNIFIED IDEOGRAPH+0x9E6B 0x67B3 #CJK UNIFIED IDEOGRAPH+0x9E6C 0x67E9 #CJK UNIFIED IDEOGRAPH+0x9E6D 0x67B8 #CJK UNIFIED IDEOGRAPH+0x9E6E 0x67E4 #CJK UNIFIED IDEOGRAPH+0x9E6F 0x67DE #CJK UNIFIED IDEOGRAPH+0x9E70 0x67DD #CJK UNIFIED IDEOGRAPH+0x9E71 0x67E2 #CJK UNIFIED IDEOGRAPH+0x9E72 0x67EE #CJK UNIFIED IDEOGRAPH+0x9E73 0x67B9 #CJK UNIFIED IDEOGRAPH+0x9E74 0x67CE #CJK UNIFIED IDEOGRAPH+0x9E75 0x67C6 #CJK UNIFIED IDEOGRAPH+0x9E76 0x67E7 #CJK UNIFIED IDEOGRAPH+0x9E77 0x6A9C #CJK UNIFIED IDEOGRAPH+0x9E78 0x681E #CJK UNIFIED IDEOGRAPH+0x9E79 0x6846 #CJK UNIFIED IDEOGRAPH+0x9E7A 0x6829 #CJK UNIFIED IDEOGRAPH+0x9E7B 0x6840 #CJK UNIFIED IDEOGRAPH+0x9E7C 0x684D #CJK UNIFIED IDEOGRAPH+0x9E7D 0x6832 #CJK UNIFIED IDEOGRAPH+0x9E7E 0x684E #CJK UNIFIED IDEOGRAPH+0x9E80 0x68B3 #CJK UNIFIED IDEOGRAPH+0x9E81 0x682B #CJK UNIFIED IDEOGRAPH+0x9E82 0x6859 #CJK UNIFIED IDEOGRAPH+0x9E83 0x6863 #CJK UNIFIED IDEOGRAPH+0x9E84 0x6877 #CJK UNIFIED IDEOGRAPH+0x9E85 0x687F #CJK UNIFIED IDEOGRAPH+0x9E86 0x689F #CJK UNIFIED IDEOGRAPH+0x9E87 0x688F #CJK UNIFIED IDEOGRAPH+0x9E88 0x68AD #CJK UNIFIED IDEOGRAPH+0x9E89 0x6894 #CJK UNIFIED IDEOGRAPH+0x9E8A 0x689D #CJK UNIFIED IDEOGRAPH+0x9E8B 0x689B #CJK UNIFIED IDEOGRAPH+0x9E8C 0x6883 #CJK UNIFIED IDEOGRAPH+0x9E8D 0x6AAE #CJK UNIFIED IDEOGRAPH+0x9E8E 0x68B9 #CJK UNIFIED IDEOGRAPH+0x9E8F 0x6874 #CJK UNIFIED IDEOGRAPH+0x9E90 0x68B5 #CJK UNIFIED IDEOGRAPH+0x9E91 0x68A0 #CJK UNIFIED IDEOGRAPH+0x9E92 0x68BA #CJK UNIFIED IDEOGRAPH+0x9E93 0x690F #CJK UNIFIED IDEOGRAPH+0x9E94 0x688D #CJK UNIFIED IDEOGRAPH+0x9E95 0x687E #CJK UNIFIED IDEOGRAPH+0x9E96 0x6901 #CJK UNIFIED IDEOGRAPH+0x9E97 0x68CA #CJK UNIFIED IDEOGRAPH+0x9E98 0x6908 #CJK UNIFIED IDEOGRAPH+0x9E99 0x68D8 #CJK UNIFIED IDEOGRAPH+0x9E9A 0x6922 #CJK UNIFIED IDEOGRAPH+0x9E9B 0x6926 #CJK UNIFIED IDEOGRAPH+0x9E9C 0x68E1 #CJK UNIFIED IDEOGRAPH+0x9E9D 0x690C #CJK UNIFIED IDEOGRAPH+0x9E9E 0x68CD #CJK UNIFIED IDEOGRAPH+0x9E9F 0x68D4 #CJK UNIFIED IDEOGRAPH+0x9EA0 0x68E7 #CJK UNIFIED IDEOGRAPH+0x9EA1 0x68D5 #CJK UNIFIED IDEOGRAPH+0x9EA2 0x6936 #CJK UNIFIED IDEOGRAPH+0x9EA3 0x6912 #CJK UNIFIED IDEOGRAPH+0x9EA4 0x6904 #CJK UNIFIED IDEOGRAPH+0x9EA5 0x68D7 #CJK UNIFIED IDEOGRAPH+0x9EA6 0x68E3 #CJK UNIFIED IDEOGRAPH+0x9EA7 0x6925 #CJK UNIFIED IDEOGRAPH+0x9EA8 0x68F9 #CJK UNIFIED IDEOGRAPH+0x9EA9 0x68E0 #CJK UNIFIED IDEOGRAPH+0x9EAA 0x68EF #CJK UNIFIED IDEOGRAPH+0x9EAB 0x6928 #CJK UNIFIED IDEOGRAPH+0x9EAC 0x692A #CJK UNIFIED IDEOGRAPH+0x9EAD 0x691A #CJK UNIFIED IDEOGRAPH+0x9EAE 0x6923 #CJK UNIFIED IDEOGRAPH+0x9EAF 0x6921 #CJK UNIFIED IDEOGRAPH+0x9EB0 0x68C6 #CJK UNIFIED IDEOGRAPH+0x9EB1 0x6979 #CJK UNIFIED IDEOGRAPH+0x9EB2 0x6977 #CJK UNIFIED IDEOGRAPH+0x9EB3 0x695C #CJK UNIFIED IDEOGRAPH+0x9EB4 0x6978 #CJK UNIFIED IDEOGRAPH+0x9EB5 0x696B #CJK UNIFIED IDEOGRAPH+0x9EB6 0x6954 #CJK UNIFIED IDEOGRAPH+0x9EB7 0x697E #CJK UNIFIED IDEOGRAPH+0x9EB8 0x696E #CJK UNIFIED IDEOGRAPH+0x9EB9 0x6939 #CJK UNIFIED IDEOGRAPH+0x9EBA 0x6974 #CJK UNIFIED IDEOGRAPH+0x9EBB 0x693D #CJK UNIFIED IDEOGRAPH+0x9EBC 0x6959 #CJK UNIFIED IDEOGRAPH+0x9EBD 0x6930 #CJK UNIFIED IDEOGRAPH+0x9EBE 0x6961 #CJK UNIFIED IDEOGRAPH+0x9EBF 0x695E #CJK UNIFIED IDEOGRAPH+0x9EC0 0x695D #CJK UNIFIED IDEOGRAPH+0x9EC1 0x6981 #CJK UNIFIED IDEOGRAPH+0x9EC2 0x696A #CJK UNIFIED IDEOGRAPH+0x9EC3 0x69B2 #CJK UNIFIED IDEOGRAPH+0x9EC4 0x69AE #CJK UNIFIED IDEOGRAPH+0x9EC5 0x69D0 #CJK UNIFIED IDEOGRAPH+0x9EC6 0x69BF #CJK UNIFIED IDEOGRAPH+0x9EC7 0x69C1 #CJK UNIFIED IDEOGRAPH+0x9EC8 0x69D3 #CJK UNIFIED IDEOGRAPH+0x9EC9 0x69BE #CJK UNIFIED IDEOGRAPH+0x9ECA 0x69CE #CJK UNIFIED IDEOGRAPH+0x9ECB 0x5BE8 #CJK UNIFIED IDEOGRAPH+0x9ECC 0x69CA #CJK UNIFIED IDEOGRAPH+0x9ECD 0x69DD #CJK UNIFIED IDEOGRAPH+0x9ECE 0x69BB #CJK UNIFIED IDEOGRAPH+0x9ECF 0x69C3 #CJK UNIFIED IDEOGRAPH+0x9ED0 0x69A7 #CJK UNIFIED IDEOGRAPH+0x9ED1 0x6A2E #CJK UNIFIED IDEOGRAPH+0x9ED2 0x6991 #CJK UNIFIED IDEOGRAPH+0x9ED3 0x69A0 #CJK UNIFIED IDEOGRAPH+0x9ED4 0x699C #CJK UNIFIED IDEOGRAPH+0x9ED5 0x6995 #CJK UNIFIED IDEOGRAPH+0x9ED6 0x69B4 #CJK UNIFIED IDEOGRAPH+0x9ED7 0x69DE #CJK UNIFIED IDEOGRAPH+0x9ED8 0x69E8 #CJK UNIFIED IDEOGRAPH+0x9ED9 0x6A02 #CJK UNIFIED IDEOGRAPH+0x9EDA 0x6A1B #CJK UNIFIED IDEOGRAPH+0x9EDB 0x69FF #CJK UNIFIED IDEOGRAPH+0x9EDC 0x6B0A #CJK UNIFIED IDEOGRAPH+0x9EDD 0x69F9 #CJK UNIFIED IDEOGRAPH+0x9EDE 0x69F2 #CJK UNIFIED IDEOGRAPH+0x9EDF 0x69E7 #CJK UNIFIED IDEOGRAPH+0x9EE0 0x6A05 #CJK UNIFIED IDEOGRAPH+0x9EE1 0x69B1 #CJK UNIFIED IDEOGRAPH+0x9EE2 0x6A1E #CJK UNIFIED IDEOGRAPH+0x9EE3 0x69ED #CJK UNIFIED IDEOGRAPH+0x9EE4 0x6A14 #CJK UNIFIED IDEOGRAPH+0x9EE5 0x69EB #CJK UNIFIED IDEOGRAPH+0x9EE6 0x6A0A #CJK UNIFIED IDEOGRAPH+0x9EE7 0x6A12 #CJK UNIFIED IDEOGRAPH+0x9EE8 0x6AC1 #CJK UNIFIED IDEOGRAPH+0x9EE9 0x6A23 #CJK UNIFIED IDEOGRAPH+0x9EEA 0x6A13 #CJK UNIFIED IDEOGRAPH+0x9EEB 0x6A44 #CJK UNIFIED IDEOGRAPH+0x9EEC 0x6A0C #CJK UNIFIED IDEOGRAPH+0x9EED 0x6A72 #CJK UNIFIED IDEOGRAPH+0x9EEE 0x6A36 #CJK UNIFIED IDEOGRAPH+0x9EEF 0x6A78 #CJK UNIFIED IDEOGRAPH+0x9EF0 0x6A47 #CJK UNIFIED IDEOGRAPH+0x9EF1 0x6A62 #CJK UNIFIED IDEOGRAPH+0x9EF2 0x6A59 #CJK UNIFIED IDEOGRAPH+0x9EF3 0x6A66 #CJK UNIFIED IDEOGRAPH+0x9EF4 0x6A48 #CJK UNIFIED IDEOGRAPH+0x9EF5 0x6A38 #CJK UNIFIED IDEOGRAPH+0x9EF6 0x6A22 #CJK UNIFIED IDEOGRAPH+0x9EF7 0x6A90 #CJK UNIFIED IDEOGRAPH+0x9EF8 0x6A8D #CJK UNIFIED IDEOGRAPH+0x9EF9 0x6AA0 #CJK UNIFIED IDEOGRAPH+0x9EFA 0x6A84 #CJK UNIFIED IDEOGRAPH+0x9EFB 0x6AA2 #CJK UNIFIED IDEOGRAPH+0x9EFC 0x6AA3 #CJK UNIFIED IDEOGRAPH+0x9F40 0x6A97 #CJK UNIFIED IDEOGRAPH+0x9F41 0x8617 #CJK UNIFIED IDEOGRAPH+0x9F42 0x6ABB #CJK UNIFIED IDEOGRAPH+0x9F43 0x6AC3 #CJK UNIFIED IDEOGRAPH+0x9F44 0x6AC2 #CJK UNIFIED IDEOGRAPH+0x9F45 0x6AB8 #CJK UNIFIED IDEOGRAPH+0x9F46 0x6AB3 #CJK UNIFIED IDEOGRAPH+0x9F47 0x6AAC #CJK UNIFIED IDEOGRAPH+0x9F48 0x6ADE #CJK UNIFIED IDEOGRAPH+0x9F49 0x6AD1 #CJK UNIFIED IDEOGRAPH+0x9F4A 0x6ADF #CJK UNIFIED IDEOGRAPH+0x9F4B 0x6AAA #CJK UNIFIED IDEOGRAPH+0x9F4C 0x6ADA #CJK UNIFIED IDEOGRAPH+0x9F4D 0x6AEA #CJK UNIFIED IDEOGRAPH+0x9F4E 0x6AFB #CJK UNIFIED IDEOGRAPH+0x9F4F 0x6B05 #CJK UNIFIED IDEOGRAPH+0x9F50 0x8616 #CJK UNIFIED IDEOGRAPH+0x9F51 0x6AFA #CJK UNIFIED IDEOGRAPH+0x9F52 0x6B12 #CJK UNIFIED IDEOGRAPH+0x9F53 0x6B16 #CJK UNIFIED IDEOGRAPH+0x9F54 0x9B31 #CJK UNIFIED IDEOGRAPH+0x9F55 0x6B1F #CJK UNIFIED IDEOGRAPH+0x9F56 0x6B38 #CJK UNIFIED IDEOGRAPH+0x9F57 0x6B37 #CJK UNIFIED IDEOGRAPH+0x9F58 0x76DC #CJK UNIFIED IDEOGRAPH+0x9F59 0x6B39 #CJK UNIFIED IDEOGRAPH+0x9F5A 0x98EE #CJK UNIFIED IDEOGRAPH+0x9F5B 0x6B47 #CJK UNIFIED IDEOGRAPH+0x9F5C 0x6B43 #CJK UNIFIED IDEOGRAPH+0x9F5D 0x6B49 #CJK UNIFIED IDEOGRAPH+0x9F5E 0x6B50 #CJK UNIFIED IDEOGRAPH+0x9F5F 0x6B59 #CJK UNIFIED IDEOGRAPH+0x9F60 0x6B54 #CJK UNIFIED IDEOGRAPH+0x9F61 0x6B5B #CJK UNIFIED IDEOGRAPH+0x9F62 0x6B5F #CJK UNIFIED IDEOGRAPH+0x9F63 0x6B61 #CJK UNIFIED IDEOGRAPH+0x9F64 0x6B78 #CJK UNIFIED IDEOGRAPH+0x9F65 0x6B79 #CJK UNIFIED IDEOGRAPH+0x9F66 0x6B7F #CJK UNIFIED IDEOGRAPH+0x9F67 0x6B80 #CJK UNIFIED IDEOGRAPH+0x9F68 0x6B84 #CJK UNIFIED IDEOGRAPH+0x9F69 0x6B83 #CJK UNIFIED IDEOGRAPH+0x9F6A 0x6B8D #CJK UNIFIED IDEOGRAPH+0x9F6B 0x6B98 #CJK UNIFIED IDEOGRAPH+0x9F6C 0x6B95 #CJK UNIFIED IDEOGRAPH+0x9F6D 0x6B9E #CJK UNIFIED IDEOGRAPH+0x9F6E 0x6BA4 #CJK UNIFIED IDEOGRAPH+0x9F6F 0x6BAA #CJK UNIFIED IDEOGRAPH+0x9F70 0x6BAB #CJK UNIFIED IDEOGRAPH+0x9F71 0x6BAF #CJK UNIFIED IDEOGRAPH+0x9F72 0x6BB2 #CJK UNIFIED IDEOGRAPH+0x9F73 0x6BB1 #CJK UNIFIED IDEOGRAPH+0x9F74 0x6BB3 #CJK UNIFIED IDEOGRAPH+0x9F75 0x6BB7 #CJK UNIFIED IDEOGRAPH+0x9F76 0x6BBC #CJK UNIFIED IDEOGRAPH+0x9F77 0x6BC6 #CJK UNIFIED IDEOGRAPH+0x9F78 0x6BCB #CJK UNIFIED IDEOGRAPH+0x9F79 0x6BD3 #CJK UNIFIED IDEOGRAPH+0x9F7A 0x6BDF #CJK UNIFIED IDEOGRAPH+0x9F7B 0x6BEC #CJK UNIFIED IDEOGRAPH+0x9F7C 0x6BEB #CJK UNIFIED IDEOGRAPH+0x9F7D 0x6BF3 #CJK UNIFIED IDEOGRAPH+0x9F7E 0x6BEF #CJK UNIFIED IDEOGRAPH+0x9F80 0x9EBE #CJK UNIFIED IDEOGRAPH+0x9F81 0x6C08 #CJK UNIFIED IDEOGRAPH+0x9F82 0x6C13 #CJK UNIFIED IDEOGRAPH+0x9F83 0x6C14 #CJK UNIFIED IDEOGRAPH+0x9F84 0x6C1B #CJK UNIFIED IDEOGRAPH+0x9F85 0x6C24 #CJK UNIFIED IDEOGRAPH+0x9F86 0x6C23 #CJK UNIFIED IDEOGRAPH+0x9F87 0x6C5E #CJK UNIFIED IDEOGRAPH+0x9F88 0x6C55 #CJK UNIFIED IDEOGRAPH+0x9F89 0x6C62 #CJK UNIFIED IDEOGRAPH+0x9F8A 0x6C6A #CJK UNIFIED IDEOGRAPH+0x9F8B 0x6C82 #CJK UNIFIED IDEOGRAPH+0x9F8C 0x6C8D #CJK UNIFIED IDEOGRAPH+0x9F8D 0x6C9A #CJK UNIFIED IDEOGRAPH+0x9F8E 0x6C81 #CJK UNIFIED IDEOGRAPH+0x9F8F 0x6C9B #CJK UNIFIED IDEOGRAPH+0x9F90 0x6C7E #CJK UNIFIED IDEOGRAPH+0x9F91 0x6C68 #CJK UNIFIED IDEOGRAPH+0x9F92 0x6C73 #CJK UNIFIED IDEOGRAPH+0x9F93 0x6C92 #CJK UNIFIED IDEOGRAPH+0x9F94 0x6C90 #CJK UNIFIED IDEOGRAPH+0x9F95 0x6CC4 #CJK UNIFIED IDEOGRAPH+0x9F96 0x6CF1 #CJK UNIFIED IDEOGRAPH+0x9F97 0x6CD3 #CJK UNIFIED IDEOGRAPH+0x9F98 0x6CBD #CJK UNIFIED IDEOGRAPH+0x9F99 0x6CD7 #CJK UNIFIED IDEOGRAPH+0x9F9A 0x6CC5 #CJK UNIFIED IDEOGRAPH+0x9F9B 0x6CDD #CJK UNIFIED IDEOGRAPH+0x9F9C 0x6CAE #CJK UNIFIED IDEOGRAPH+0x9F9D 0x6CB1 #CJK UNIFIED IDEOGRAPH+0x9F9E 0x6CBE #CJK UNIFIED IDEOGRAPH+0x9F9F 0x6CBA #CJK UNIFIED IDEOGRAPH+0x9FA0 0x6CDB #CJK UNIFIED IDEOGRAPH+0x9FA1 0x6CEF #CJK UNIFIED IDEOGRAPH+0x9FA2 0x6CD9 #CJK UNIFIED IDEOGRAPH+0x9FA3 0x6CEA #CJK UNIFIED IDEOGRAPH+0x9FA4 0x6D1F #CJK UNIFIED IDEOGRAPH+0x9FA5 0x884D #CJK UNIFIED IDEOGRAPH+0x9FA6 0x6D36 #CJK UNIFIED IDEOGRAPH+0x9FA7 0x6D2B #CJK UNIFIED IDEOGRAPH+0x9FA8 0x6D3D #CJK UNIFIED IDEOGRAPH+0x9FA9 0x6D38 #CJK UNIFIED IDEOGRAPH+0x9FAA 0x6D19 #CJK UNIFIED IDEOGRAPH+0x9FAB 0x6D35 #CJK UNIFIED IDEOGRAPH+0x9FAC 0x6D33 #CJK UNIFIED IDEOGRAPH+0x9FAD 0x6D12 #CJK UNIFIED IDEOGRAPH+0x9FAE 0x6D0C #CJK UNIFIED IDEOGRAPH+0x9FAF 0x6D63 #CJK UNIFIED IDEOGRAPH+0x9FB0 0x6D93 #CJK UNIFIED IDEOGRAPH+0x9FB1 0x6D64 #CJK UNIFIED IDEOGRAPH+0x9FB2 0x6D5A #CJK UNIFIED IDEOGRAPH+0x9FB3 0x6D79 #CJK UNIFIED IDEOGRAPH+0x9FB4 0x6D59 #CJK UNIFIED IDEOGRAPH+0x9FB5 0x6D8E #CJK UNIFIED IDEOGRAPH+0x9FB6 0x6D95 #CJK UNIFIED IDEOGRAPH+0x9FB7 0x6FE4 #CJK UNIFIED IDEOGRAPH+0x9FB8 0x6D85 #CJK UNIFIED IDEOGRAPH+0x9FB9 0x6DF9 #CJK UNIFIED IDEOGRAPH+0x9FBA 0x6E15 #CJK UNIFIED IDEOGRAPH+0x9FBB 0x6E0A #CJK UNIFIED IDEOGRAPH+0x9FBC 0x6DB5 #CJK UNIFIED IDEOGRAPH+0x9FBD 0x6DC7 #CJK UNIFIED IDEOGRAPH+0x9FBE 0x6DE6 #CJK UNIFIED IDEOGRAPH+0x9FBF 0x6DB8 #CJK UNIFIED IDEOGRAPH+0x9FC0 0x6DC6 #CJK UNIFIED IDEOGRAPH+0x9FC1 0x6DEC #CJK UNIFIED IDEOGRAPH+0x9FC2 0x6DDE #CJK UNIFIED IDEOGRAPH+0x9FC3 0x6DCC #CJK UNIFIED IDEOGRAPH+0x9FC4 0x6DE8 #CJK UNIFIED IDEOGRAPH+0x9FC5 0x6DD2 #CJK UNIFIED IDEOGRAPH+0x9FC6 0x6DC5 #CJK UNIFIED IDEOGRAPH+0x9FC7 0x6DFA #CJK UNIFIED IDEOGRAPH+0x9FC8 0x6DD9 #CJK UNIFIED IDEOGRAPH+0x9FC9 0x6DE4 #CJK UNIFIED IDEOGRAPH+0x9FCA 0x6DD5 #CJK UNIFIED IDEOGRAPH+0x9FCB 0x6DEA #CJK UNIFIED IDEOGRAPH+0x9FCC 0x6DEE #CJK UNIFIED IDEOGRAPH+0x9FCD 0x6E2D #CJK UNIFIED IDEOGRAPH+0x9FCE 0x6E6E #CJK UNIFIED IDEOGRAPH+0x9FCF 0x6E2E #CJK UNIFIED IDEOGRAPH+0x9FD0 0x6E19 #CJK UNIFIED IDEOGRAPH+0x9FD1 0x6E72 #CJK UNIFIED IDEOGRAPH+0x9FD2 0x6E5F #CJK UNIFIED IDEOGRAPH+0x9FD3 0x6E3E #CJK UNIFIED IDEOGRAPH+0x9FD4 0x6E23 #CJK UNIFIED IDEOGRAPH+0x9FD5 0x6E6B #CJK UNIFIED IDEOGRAPH+0x9FD6 0x6E2B #CJK UNIFIED IDEOGRAPH+0x9FD7 0x6E76 #CJK UNIFIED IDEOGRAPH+0x9FD8 0x6E4D #CJK UNIFIED IDEOGRAPH+0x9FD9 0x6E1F #CJK UNIFIED IDEOGRAPH+0x9FDA 0x6E43 #CJK UNIFIED IDEOGRAPH+0x9FDB 0x6E3A #CJK UNIFIED IDEOGRAPH+0x9FDC 0x6E4E #CJK UNIFIED IDEOGRAPH+0x9FDD 0x6E24 #CJK UNIFIED IDEOGRAPH+0x9FDE 0x6EFF #CJK UNIFIED IDEOGRAPH+0x9FDF 0x6E1D #CJK UNIFIED IDEOGRAPH+0x9FE0 0x6E38 #CJK UNIFIED IDEOGRAPH+0x9FE1 0x6E82 #CJK UNIFIED IDEOGRAPH+0x9FE2 0x6EAA #CJK UNIFIED IDEOGRAPH+0x9FE3 0x6E98 #CJK UNIFIED IDEOGRAPH+0x9FE4 0x6EC9 #CJK UNIFIED IDEOGRAPH+0x9FE5 0x6EB7 #CJK UNIFIED IDEOGRAPH+0x9FE6 0x6ED3 #CJK UNIFIED IDEOGRAPH+0x9FE7 0x6EBD #CJK UNIFIED IDEOGRAPH+0x9FE8 0x6EAF #CJK UNIFIED IDEOGRAPH+0x9FE9 0x6EC4 #CJK UNIFIED IDEOGRAPH+0x9FEA 0x6EB2 #CJK UNIFIED IDEOGRAPH+0x9FEB 0x6ED4 #CJK UNIFIED IDEOGRAPH+0x9FEC 0x6ED5 #CJK UNIFIED IDEOGRAPH+0x9FED 0x6E8F #CJK UNIFIED IDEOGRAPH+0x9FEE 0x6EA5 #CJK UNIFIED IDEOGRAPH+0x9FEF 0x6EC2 #CJK UNIFIED IDEOGRAPH+0x9FF0 0x6E9F #CJK UNIFIED IDEOGRAPH+0x9FF1 0x6F41 #CJK UNIFIED IDEOGRAPH+0x9FF2 0x6F11 #CJK UNIFIED IDEOGRAPH+0x9FF3 0x704C #CJK UNIFIED IDEOGRAPH+0x9FF4 0x6EEC #CJK UNIFIED IDEOGRAPH+0x9FF5 0x6EF8 #CJK UNIFIED IDEOGRAPH+0x9FF6 0x6EFE #CJK UNIFIED IDEOGRAPH+0x9FF7 0x6F3F #CJK UNIFIED IDEOGRAPH+0x9FF8 0x6EF2 #CJK UNIFIED IDEOGRAPH+0x9FF9 0x6F31 #CJK UNIFIED IDEOGRAPH+0x9FFA 0x6EEF #CJK UNIFIED IDEOGRAPH+0x9FFB 0x6F32 #CJK UNIFIED IDEOGRAPH+0x9FFC 0x6ECC #CJK UNIFIED IDEOGRAPH+0xE040 0x6F3E #CJK UNIFIED IDEOGRAPH+0xE041 0x6F13 #CJK UNIFIED IDEOGRAPH+0xE042 0x6EF7 #CJK UNIFIED IDEOGRAPH+0xE043 0x6F86 #CJK UNIFIED IDEOGRAPH+0xE044 0x6F7A #CJK UNIFIED IDEOGRAPH+0xE045 0x6F78 #CJK UNIFIED IDEOGRAPH+0xE046 0x6F81 #CJK UNIFIED IDEOGRAPH+0xE047 0x6F80 #CJK UNIFIED IDEOGRAPH+0xE048 0x6F6F #CJK UNIFIED IDEOGRAPH+0xE049 0x6F5B #CJK UNIFIED IDEOGRAPH+0xE04A 0x6FF3 #CJK UNIFIED IDEOGRAPH+0xE04B 0x6F6D #CJK UNIFIED IDEOGRAPH+0xE04C 0x6F82 #CJK UNIFIED IDEOGRAPH+0xE04D 0x6F7C #CJK UNIFIED IDEOGRAPH+0xE04E 0x6F58 #CJK UNIFIED IDEOGRAPH+0xE04F 0x6F8E #CJK UNIFIED IDEOGRAPH+0xE050 0x6F91 #CJK UNIFIED IDEOGRAPH+0xE051 0x6FC2 #CJK UNIFIED IDEOGRAPH+0xE052 0x6F66 #CJK UNIFIED IDEOGRAPH+0xE053 0x6FB3 #CJK UNIFIED IDEOGRAPH+0xE054 0x6FA3 #CJK UNIFIED IDEOGRAPH+0xE055 0x6FA1 #CJK UNIFIED IDEOGRAPH+0xE056 0x6FA4 #CJK UNIFIED IDEOGRAPH+0xE057 0x6FB9 #CJK UNIFIED IDEOGRAPH+0xE058 0x6FC6 #CJK UNIFIED IDEOGRAPH+0xE059 0x6FAA #CJK UNIFIED IDEOGRAPH+0xE05A 0x6FDF #CJK UNIFIED IDEOGRAPH+0xE05B 0x6FD5 #CJK UNIFIED IDEOGRAPH+0xE05C 0x6FEC #CJK UNIFIED IDEOGRAPH+0xE05D 0x6FD4 #CJK UNIFIED IDEOGRAPH+0xE05E 0x6FD8 #CJK UNIFIED IDEOGRAPH+0xE05F 0x6FF1 #CJK UNIFIED IDEOGRAPH+0xE060 0x6FEE #CJK UNIFIED IDEOGRAPH+0xE061 0x6FDB #CJK UNIFIED IDEOGRAPH+0xE062 0x7009 #CJK UNIFIED IDEOGRAPH+0xE063 0x700B #CJK UNIFIED IDEOGRAPH+0xE064 0x6FFA #CJK UNIFIED IDEOGRAPH+0xE065 0x7011 #CJK UNIFIED IDEOGRAPH+0xE066 0x7001 #CJK UNIFIED IDEOGRAPH+0xE067 0x700F #CJK UNIFIED IDEOGRAPH+0xE068 0x6FFE #CJK UNIFIED IDEOGRAPH+0xE069 0x701B #CJK UNIFIED IDEOGRAPH+0xE06A 0x701A #CJK UNIFIED IDEOGRAPH+0xE06B 0x6F74 #CJK UNIFIED IDEOGRAPH+0xE06C 0x701D #CJK UNIFIED IDEOGRAPH+0xE06D 0x7018 #CJK UNIFIED IDEOGRAPH+0xE06E 0x701F #CJK UNIFIED IDEOGRAPH+0xE06F 0x7030 #CJK UNIFIED IDEOGRAPH+0xE070 0x703E #CJK UNIFIED IDEOGRAPH+0xE071 0x7032 #CJK UNIFIED IDEOGRAPH+0xE072 0x7051 #CJK UNIFIED IDEOGRAPH+0xE073 0x7063 #CJK UNIFIED IDEOGRAPH+0xE074 0x7099 #CJK UNIFIED IDEOGRAPH+0xE075 0x7092 #CJK UNIFIED IDEOGRAPH+0xE076 0x70AF #CJK UNIFIED IDEOGRAPH+0xE077 0x70F1 #CJK UNIFIED IDEOGRAPH+0xE078 0x70AC #CJK UNIFIED IDEOGRAPH+0xE079 0x70B8 #CJK UNIFIED IDEOGRAPH+0xE07A 0x70B3 #CJK UNIFIED IDEOGRAPH+0xE07B 0x70AE #CJK UNIFIED IDEOGRAPH+0xE07C 0x70DF #CJK UNIFIED IDEOGRAPH+0xE07D 0x70CB #CJK UNIFIED IDEOGRAPH+0xE07E 0x70DD #CJK UNIFIED IDEOGRAPH+0xE080 0x70D9 #CJK UNIFIED IDEOGRAPH+0xE081 0x7109 #CJK UNIFIED IDEOGRAPH+0xE082 0x70FD #CJK UNIFIED IDEOGRAPH+0xE083 0x711C #CJK UNIFIED IDEOGRAPH+0xE084 0x7119 #CJK UNIFIED IDEOGRAPH+0xE085 0x7165 #CJK UNIFIED IDEOGRAPH+0xE086 0x7155 #CJK UNIFIED IDEOGRAPH+0xE087 0x7188 #CJK UNIFIED IDEOGRAPH+0xE088 0x7166 #CJK UNIFIED IDEOGRAPH+0xE089 0x7162 #CJK UNIFIED IDEOGRAPH+0xE08A 0x714C #CJK UNIFIED IDEOGRAPH+0xE08B 0x7156 #CJK UNIFIED IDEOGRAPH+0xE08C 0x716C #CJK UNIFIED IDEOGRAPH+0xE08D 0x718F #CJK UNIFIED IDEOGRAPH+0xE08E 0x71FB #CJK UNIFIED IDEOGRAPH+0xE08F 0x7184 #CJK UNIFIED IDEOGRAPH+0xE090 0x7195 #CJK UNIFIED IDEOGRAPH+0xE091 0x71A8 #CJK UNIFIED IDEOGRAPH+0xE092 0x71AC #CJK UNIFIED IDEOGRAPH+0xE093 0x71D7 #CJK UNIFIED IDEOGRAPH+0xE094 0x71B9 #CJK UNIFIED IDEOGRAPH+0xE095 0x71BE #CJK UNIFIED IDEOGRAPH+0xE096 0x71D2 #CJK UNIFIED IDEOGRAPH+0xE097 0x71C9 #CJK UNIFIED IDEOGRAPH+0xE098 0x71D4 #CJK UNIFIED IDEOGRAPH+0xE099 0x71CE #CJK UNIFIED IDEOGRAPH+0xE09A 0x71E0 #CJK UNIFIED IDEOGRAPH+0xE09B 0x71EC #CJK UNIFIED IDEOGRAPH+0xE09C 0x71E7 #CJK UNIFIED IDEOGRAPH+0xE09D 0x71F5 #CJK UNIFIED IDEOGRAPH+0xE09E 0x71FC #CJK UNIFIED IDEOGRAPH+0xE09F 0x71F9 #CJK UNIFIED IDEOGRAPH+0xE0A0 0x71FF #CJK UNIFIED IDEOGRAPH+0xE0A1 0x720D #CJK UNIFIED IDEOGRAPH+0xE0A2 0x7210 #CJK UNIFIED IDEOGRAPH+0xE0A3 0x721B #CJK UNIFIED IDEOGRAPH+0xE0A4 0x7228 #CJK UNIFIED IDEOGRAPH+0xE0A5 0x722D #CJK UNIFIED IDEOGRAPH+0xE0A6 0x722C #CJK UNIFIED IDEOGRAPH+0xE0A7 0x7230 #CJK UNIFIED IDEOGRAPH+0xE0A8 0x7232 #CJK UNIFIED IDEOGRAPH+0xE0A9 0x723B #CJK UNIFIED IDEOGRAPH+0xE0AA 0x723C #CJK UNIFIED IDEOGRAPH+0xE0AB 0x723F #CJK UNIFIED IDEOGRAPH+0xE0AC 0x7240 #CJK UNIFIED IDEOGRAPH+0xE0AD 0x7246 #CJK UNIFIED IDEOGRAPH+0xE0AE 0x724B #CJK UNIFIED IDEOGRAPH+0xE0AF 0x7258 #CJK UNIFIED IDEOGRAPH+0xE0B0 0x7274 #CJK UNIFIED IDEOGRAPH+0xE0B1 0x727E #CJK UNIFIED IDEOGRAPH+0xE0B2 0x7282 #CJK UNIFIED IDEOGRAPH+0xE0B3 0x7281 #CJK UNIFIED IDEOGRAPH+0xE0B4 0x7287 #CJK UNIFIED IDEOGRAPH+0xE0B5 0x7292 #CJK UNIFIED IDEOGRAPH+0xE0B6 0x7296 #CJK UNIFIED IDEOGRAPH+0xE0B7 0x72A2 #CJK UNIFIED IDEOGRAPH+0xE0B8 0x72A7 #CJK UNIFIED IDEOGRAPH+0xE0B9 0x72B9 #CJK UNIFIED IDEOGRAPH+0xE0BA 0x72B2 #CJK UNIFIED IDEOGRAPH+0xE0BB 0x72C3 #CJK UNIFIED IDEOGRAPH+0xE0BC 0x72C6 #CJK UNIFIED IDEOGRAPH+0xE0BD 0x72C4 #CJK UNIFIED IDEOGRAPH+0xE0BE 0x72CE #CJK UNIFIED IDEOGRAPH+0xE0BF 0x72D2 #CJK UNIFIED IDEOGRAPH+0xE0C0 0x72E2 #CJK UNIFIED IDEOGRAPH+0xE0C1 0x72E0 #CJK UNIFIED IDEOGRAPH+0xE0C2 0x72E1 #CJK UNIFIED IDEOGRAPH+0xE0C3 0x72F9 #CJK UNIFIED IDEOGRAPH+0xE0C4 0x72F7 #CJK UNIFIED IDEOGRAPH+0xE0C5 0x500F #CJK UNIFIED IDEOGRAPH+0xE0C6 0x7317 #CJK UNIFIED IDEOGRAPH+0xE0C7 0x730A #CJK UNIFIED IDEOGRAPH+0xE0C8 0x731C #CJK UNIFIED IDEOGRAPH+0xE0C9 0x7316 #CJK UNIFIED IDEOGRAPH+0xE0CA 0x731D #CJK UNIFIED IDEOGRAPH+0xE0CB 0x7334 #CJK UNIFIED IDEOGRAPH+0xE0CC 0x732F #CJK UNIFIED IDEOGRAPH+0xE0CD 0x7329 #CJK UNIFIED IDEOGRAPH+0xE0CE 0x7325 #CJK UNIFIED IDEOGRAPH+0xE0CF 0x733E #CJK UNIFIED IDEOGRAPH+0xE0D0 0x734E #CJK UNIFIED IDEOGRAPH+0xE0D1 0x734F #CJK UNIFIED IDEOGRAPH+0xE0D2 0x9ED8 #CJK UNIFIED IDEOGRAPH+0xE0D3 0x7357 #CJK UNIFIED IDEOGRAPH+0xE0D4 0x736A #CJK UNIFIED IDEOGRAPH+0xE0D5 0x7368 #CJK UNIFIED IDEOGRAPH+0xE0D6 0x7370 #CJK UNIFIED IDEOGRAPH+0xE0D7 0x7378 #CJK UNIFIED IDEOGRAPH+0xE0D8 0x7375 #CJK UNIFIED IDEOGRAPH+0xE0D9 0x737B #CJK UNIFIED IDEOGRAPH+0xE0DA 0x737A #CJK UNIFIED IDEOGRAPH+0xE0DB 0x73C8 #CJK UNIFIED IDEOGRAPH+0xE0DC 0x73B3 #CJK UNIFIED IDEOGRAPH+0xE0DD 0x73CE #CJK UNIFIED IDEOGRAPH+0xE0DE 0x73BB #CJK UNIFIED IDEOGRAPH+0xE0DF 0x73C0 #CJK UNIFIED IDEOGRAPH+0xE0E0 0x73E5 #CJK UNIFIED IDEOGRAPH+0xE0E1 0x73EE #CJK UNIFIED IDEOGRAPH+0xE0E2 0x73DE #CJK UNIFIED IDEOGRAPH+0xE0E3 0x74A2 #CJK UNIFIED IDEOGRAPH+0xE0E4 0x7405 #CJK UNIFIED IDEOGRAPH+0xE0E5 0x746F #CJK UNIFIED IDEOGRAPH+0xE0E6 0x7425 #CJK UNIFIED IDEOGRAPH+0xE0E7 0x73F8 #CJK UNIFIED IDEOGRAPH+0xE0E8 0x7432 #CJK UNIFIED IDEOGRAPH+0xE0E9 0x743A #CJK UNIFIED IDEOGRAPH+0xE0EA 0x7455 #CJK UNIFIED IDEOGRAPH+0xE0EB 0x743F #CJK UNIFIED IDEOGRAPH+0xE0EC 0x745F #CJK UNIFIED IDEOGRAPH+0xE0ED 0x7459 #CJK UNIFIED IDEOGRAPH+0xE0EE 0x7441 #CJK UNIFIED IDEOGRAPH+0xE0EF 0x745C #CJK UNIFIED IDEOGRAPH+0xE0F0 0x7469 #CJK UNIFIED IDEOGRAPH+0xE0F1 0x7470 #CJK UNIFIED IDEOGRAPH+0xE0F2 0x7463 #CJK UNIFIED IDEOGRAPH+0xE0F3 0x746A #CJK UNIFIED IDEOGRAPH+0xE0F4 0x7476 #CJK UNIFIED IDEOGRAPH+0xE0F5 0x747E #CJK UNIFIED IDEOGRAPH+0xE0F6 0x748B #CJK UNIFIED IDEOGRAPH+0xE0F7 0x749E #CJK UNIFIED IDEOGRAPH+0xE0F8 0x74A7 #CJK UNIFIED IDEOGRAPH+0xE0F9 0x74CA #CJK UNIFIED IDEOGRAPH+0xE0FA 0x74CF #CJK UNIFIED IDEOGRAPH+0xE0FB 0x74D4 #CJK UNIFIED IDEOGRAPH+0xE0FC 0x73F1 #CJK UNIFIED IDEOGRAPH+0xE140 0x74E0 #CJK UNIFIED IDEOGRAPH+0xE141 0x74E3 #CJK UNIFIED IDEOGRAPH+0xE142 0x74E7 #CJK UNIFIED IDEOGRAPH+0xE143 0x74E9 #CJK UNIFIED IDEOGRAPH+0xE144 0x74EE #CJK UNIFIED IDEOGRAPH+0xE145 0x74F2 #CJK UNIFIED IDEOGRAPH+0xE146 0x74F0 #CJK UNIFIED IDEOGRAPH+0xE147 0x74F1 #CJK UNIFIED IDEOGRAPH+0xE148 0x74F8 #CJK UNIFIED IDEOGRAPH+0xE149 0x74F7 #CJK UNIFIED IDEOGRAPH+0xE14A 0x7504 #CJK UNIFIED IDEOGRAPH+0xE14B 0x7503 #CJK UNIFIED IDEOGRAPH+0xE14C 0x7505 #CJK UNIFIED IDEOGRAPH+0xE14D 0x750C #CJK UNIFIED IDEOGRAPH+0xE14E 0x750E #CJK UNIFIED IDEOGRAPH+0xE14F 0x750D #CJK UNIFIED IDEOGRAPH+0xE150 0x7515 #CJK UNIFIED IDEOGRAPH+0xE151 0x7513 #CJK UNIFIED IDEOGRAPH+0xE152 0x751E #CJK UNIFIED IDEOGRAPH+0xE153 0x7526 #CJK UNIFIED IDEOGRAPH+0xE154 0x752C #CJK UNIFIED IDEOGRAPH+0xE155 0x753C #CJK UNIFIED IDEOGRAPH+0xE156 0x7544 #CJK UNIFIED IDEOGRAPH+0xE157 0x754D #CJK UNIFIED IDEOGRAPH+0xE158 0x754A #CJK UNIFIED IDEOGRAPH+0xE159 0x7549 #CJK UNIFIED IDEOGRAPH+0xE15A 0x755B #CJK UNIFIED IDEOGRAPH+0xE15B 0x7546 #CJK UNIFIED IDEOGRAPH+0xE15C 0x755A #CJK UNIFIED IDEOGRAPH+0xE15D 0x7569 #CJK UNIFIED IDEOGRAPH+0xE15E 0x7564 #CJK UNIFIED IDEOGRAPH+0xE15F 0x7567 #CJK UNIFIED IDEOGRAPH+0xE160 0x756B #CJK UNIFIED IDEOGRAPH+0xE161 0x756D #CJK UNIFIED IDEOGRAPH+0xE162 0x7578 #CJK UNIFIED IDEOGRAPH+0xE163 0x7576 #CJK UNIFIED IDEOGRAPH+0xE164 0x7586 #CJK UNIFIED IDEOGRAPH+0xE165 0x7587 #CJK UNIFIED IDEOGRAPH+0xE166 0x7574 #CJK UNIFIED IDEOGRAPH+0xE167 0x758A #CJK UNIFIED IDEOGRAPH+0xE168 0x7589 #CJK UNIFIED IDEOGRAPH+0xE169 0x7582 #CJK UNIFIED IDEOGRAPH+0xE16A 0x7594 #CJK UNIFIED IDEOGRAPH+0xE16B 0x759A #CJK UNIFIED IDEOGRAPH+0xE16C 0x759D #CJK UNIFIED IDEOGRAPH+0xE16D 0x75A5 #CJK UNIFIED IDEOGRAPH+0xE16E 0x75A3 #CJK UNIFIED IDEOGRAPH+0xE16F 0x75C2 #CJK UNIFIED IDEOGRAPH+0xE170 0x75B3 #CJK UNIFIED IDEOGRAPH+0xE171 0x75C3 #CJK UNIFIED IDEOGRAPH+0xE172 0x75B5 #CJK UNIFIED IDEOGRAPH+0xE173 0x75BD #CJK UNIFIED IDEOGRAPH+0xE174 0x75B8 #CJK UNIFIED IDEOGRAPH+0xE175 0x75BC #CJK UNIFIED IDEOGRAPH+0xE176 0x75B1 #CJK UNIFIED IDEOGRAPH+0xE177 0x75CD #CJK UNIFIED IDEOGRAPH+0xE178 0x75CA #CJK UNIFIED IDEOGRAPH+0xE179 0x75D2 #CJK UNIFIED IDEOGRAPH+0xE17A 0x75D9 #CJK UNIFIED IDEOGRAPH+0xE17B 0x75E3 #CJK UNIFIED IDEOGRAPH+0xE17C 0x75DE #CJK UNIFIED IDEOGRAPH+0xE17D 0x75FE #CJK UNIFIED IDEOGRAPH+0xE17E 0x75FF #CJK UNIFIED IDEOGRAPH+0xE180 0x75FC #CJK UNIFIED IDEOGRAPH+0xE181 0x7601 #CJK UNIFIED IDEOGRAPH+0xE182 0x75F0 #CJK UNIFIED IDEOGRAPH+0xE183 0x75FA #CJK UNIFIED IDEOGRAPH+0xE184 0x75F2 #CJK UNIFIED IDEOGRAPH+0xE185 0x75F3 #CJK UNIFIED IDEOGRAPH+0xE186 0x760B #CJK UNIFIED IDEOGRAPH+0xE187 0x760D #CJK UNIFIED IDEOGRAPH+0xE188 0x7609 #CJK UNIFIED IDEOGRAPH+0xE189 0x761F #CJK UNIFIED IDEOGRAPH+0xE18A 0x7627 #CJK UNIFIED IDEOGRAPH+0xE18B 0x7620 #CJK UNIFIED IDEOGRAPH+0xE18C 0x7621 #CJK UNIFIED IDEOGRAPH+0xE18D 0x7622 #CJK UNIFIED IDEOGRAPH+0xE18E 0x7624 #CJK UNIFIED IDEOGRAPH+0xE18F 0x7634 #CJK UNIFIED IDEOGRAPH+0xE190 0x7630 #CJK UNIFIED IDEOGRAPH+0xE191 0x763B #CJK UNIFIED IDEOGRAPH+0xE192 0x7647 #CJK UNIFIED IDEOGRAPH+0xE193 0x7648 #CJK UNIFIED IDEOGRAPH+0xE194 0x7646 #CJK UNIFIED IDEOGRAPH+0xE195 0x765C #CJK UNIFIED IDEOGRAPH+0xE196 0x7658 #CJK UNIFIED IDEOGRAPH+0xE197 0x7661 #CJK UNIFIED IDEOGRAPH+0xE198 0x7662 #CJK UNIFIED IDEOGRAPH+0xE199 0x7668 #CJK UNIFIED IDEOGRAPH+0xE19A 0x7669 #CJK UNIFIED IDEOGRAPH+0xE19B 0x766A #CJK UNIFIED IDEOGRAPH+0xE19C 0x7667 #CJK UNIFIED IDEOGRAPH+0xE19D 0x766C #CJK UNIFIED IDEOGRAPH+0xE19E 0x7670 #CJK UNIFIED IDEOGRAPH+0xE19F 0x7672 #CJK UNIFIED IDEOGRAPH+0xE1A0 0x7676 #CJK UNIFIED IDEOGRAPH+0xE1A1 0x7678 #CJK UNIFIED IDEOGRAPH+0xE1A2 0x767C #CJK UNIFIED IDEOGRAPH+0xE1A3 0x7680 #CJK UNIFIED IDEOGRAPH+0xE1A4 0x7683 #CJK UNIFIED IDEOGRAPH+0xE1A5 0x7688 #CJK UNIFIED IDEOGRAPH+0xE1A6 0x768B #CJK UNIFIED IDEOGRAPH+0xE1A7 0x768E #CJK UNIFIED IDEOGRAPH+0xE1A8 0x7696 #CJK UNIFIED IDEOGRAPH+0xE1A9 0x7693 #CJK UNIFIED IDEOGRAPH+0xE1AA 0x7699 #CJK UNIFIED IDEOGRAPH+0xE1AB 0x769A #CJK UNIFIED IDEOGRAPH+0xE1AC 0x76B0 #CJK UNIFIED IDEOGRAPH+0xE1AD 0x76B4 #CJK UNIFIED IDEOGRAPH+0xE1AE 0x76B8 #CJK UNIFIED IDEOGRAPH+0xE1AF 0x76B9 #CJK UNIFIED IDEOGRAPH+0xE1B0 0x76BA #CJK UNIFIED IDEOGRAPH+0xE1B1 0x76C2 #CJK UNIFIED IDEOGRAPH+0xE1B2 0x76CD #CJK UNIFIED IDEOGRAPH+0xE1B3 0x76D6 #CJK UNIFIED IDEOGRAPH+0xE1B4 0x76D2 #CJK UNIFIED IDEOGRAPH+0xE1B5 0x76DE #CJK UNIFIED IDEOGRAPH+0xE1B6 0x76E1 #CJK UNIFIED IDEOGRAPH+0xE1B7 0x76E5 #CJK UNIFIED IDEOGRAPH+0xE1B8 0x76E7 #CJK UNIFIED IDEOGRAPH+0xE1B9 0x76EA #CJK UNIFIED IDEOGRAPH+0xE1BA 0x862F #CJK UNIFIED IDEOGRAPH+0xE1BB 0x76FB #CJK UNIFIED IDEOGRAPH+0xE1BC 0x7708 #CJK UNIFIED IDEOGRAPH+0xE1BD 0x7707 #CJK UNIFIED IDEOGRAPH+0xE1BE 0x7704 #CJK UNIFIED IDEOGRAPH+0xE1BF 0x7729 #CJK UNIFIED IDEOGRAPH+0xE1C0 0x7724 #CJK UNIFIED IDEOGRAPH+0xE1C1 0x771E #CJK UNIFIED IDEOGRAPH+0xE1C2 0x7725 #CJK UNIFIED IDEOGRAPH+0xE1C3 0x7726 #CJK UNIFIED IDEOGRAPH+0xE1C4 0x771B #CJK UNIFIED IDEOGRAPH+0xE1C5 0x7737 #CJK UNIFIED IDEOGRAPH+0xE1C6 0x7738 #CJK UNIFIED IDEOGRAPH+0xE1C7 0x7747 #CJK UNIFIED IDEOGRAPH+0xE1C8 0x775A #CJK UNIFIED IDEOGRAPH+0xE1C9 0x7768 #CJK UNIFIED IDEOGRAPH+0xE1CA 0x776B #CJK UNIFIED IDEOGRAPH+0xE1CB 0x775B #CJK UNIFIED IDEOGRAPH+0xE1CC 0x7765 #CJK UNIFIED IDEOGRAPH+0xE1CD 0x777F #CJK UNIFIED IDEOGRAPH+0xE1CE 0x777E #CJK UNIFIED IDEOGRAPH+0xE1CF 0x7779 #CJK UNIFIED IDEOGRAPH+0xE1D0 0x778E #CJK UNIFIED IDEOGRAPH+0xE1D1 0x778B #CJK UNIFIED IDEOGRAPH+0xE1D2 0x7791 #CJK UNIFIED IDEOGRAPH+0xE1D3 0x77A0 #CJK UNIFIED IDEOGRAPH+0xE1D4 0x779E #CJK UNIFIED IDEOGRAPH+0xE1D5 0x77B0 #CJK UNIFIED IDEOGRAPH+0xE1D6 0x77B6 #CJK UNIFIED IDEOGRAPH+0xE1D7 0x77B9 #CJK UNIFIED IDEOGRAPH+0xE1D8 0x77BF #CJK UNIFIED IDEOGRAPH+0xE1D9 0x77BC #CJK UNIFIED IDEOGRAPH+0xE1DA 0x77BD #CJK UNIFIED IDEOGRAPH+0xE1DB 0x77BB #CJK UNIFIED IDEOGRAPH+0xE1DC 0x77C7 #CJK UNIFIED IDEOGRAPH+0xE1DD 0x77CD #CJK UNIFIED IDEOGRAPH+0xE1DE 0x77D7 #CJK UNIFIED IDEOGRAPH+0xE1DF 0x77DA #CJK UNIFIED IDEOGRAPH+0xE1E0 0x77DC #CJK UNIFIED IDEOGRAPH+0xE1E1 0x77E3 #CJK UNIFIED IDEOGRAPH+0xE1E2 0x77EE #CJK UNIFIED IDEOGRAPH+0xE1E3 0x77FC #CJK UNIFIED IDEOGRAPH+0xE1E4 0x780C #CJK UNIFIED IDEOGRAPH+0xE1E5 0x7812 #CJK UNIFIED IDEOGRAPH+0xE1E6 0x7926 #CJK UNIFIED IDEOGRAPH+0xE1E7 0x7820 #CJK UNIFIED IDEOGRAPH+0xE1E8 0x792A #CJK UNIFIED IDEOGRAPH+0xE1E9 0x7845 #CJK UNIFIED IDEOGRAPH+0xE1EA 0x788E #CJK UNIFIED IDEOGRAPH+0xE1EB 0x7874 #CJK UNIFIED IDEOGRAPH+0xE1EC 0x7886 #CJK UNIFIED IDEOGRAPH+0xE1ED 0x787C #CJK UNIFIED IDEOGRAPH+0xE1EE 0x789A #CJK UNIFIED IDEOGRAPH+0xE1EF 0x788C #CJK UNIFIED IDEOGRAPH+0xE1F0 0x78A3 #CJK UNIFIED IDEOGRAPH+0xE1F1 0x78B5 #CJK UNIFIED IDEOGRAPH+0xE1F2 0x78AA #CJK UNIFIED IDEOGRAPH+0xE1F3 0x78AF #CJK UNIFIED IDEOGRAPH+0xE1F4 0x78D1 #CJK UNIFIED IDEOGRAPH+0xE1F5 0x78C6 #CJK UNIFIED IDEOGRAPH+0xE1F6 0x78CB #CJK UNIFIED IDEOGRAPH+0xE1F7 0x78D4 #CJK UNIFIED IDEOGRAPH+0xE1F8 0x78BE #CJK UNIFIED IDEOGRAPH+0xE1F9 0x78BC #CJK UNIFIED IDEOGRAPH+0xE1FA 0x78C5 #CJK UNIFIED IDEOGRAPH+0xE1FB 0x78CA #CJK UNIFIED IDEOGRAPH+0xE1FC 0x78EC #CJK UNIFIED IDEOGRAPH+0xE240 0x78E7 #CJK UNIFIED IDEOGRAPH+0xE241 0x78DA #CJK UNIFIED IDEOGRAPH+0xE242 0x78FD #CJK UNIFIED IDEOGRAPH+0xE243 0x78F4 #CJK UNIFIED IDEOGRAPH+0xE244 0x7907 #CJK UNIFIED IDEOGRAPH+0xE245 0x7912 #CJK UNIFIED IDEOGRAPH+0xE246 0x7911 #CJK UNIFIED IDEOGRAPH+0xE247 0x7919 #CJK UNIFIED IDEOGRAPH+0xE248 0x792C #CJK UNIFIED IDEOGRAPH+0xE249 0x792B #CJK UNIFIED IDEOGRAPH+0xE24A 0x7940 #CJK UNIFIED IDEOGRAPH+0xE24B 0x7960 #CJK UNIFIED IDEOGRAPH+0xE24C 0x7957 #CJK UNIFIED IDEOGRAPH+0xE24D 0x795F #CJK UNIFIED IDEOGRAPH+0xE24E 0x795A #CJK UNIFIED IDEOGRAPH+0xE24F 0x7955 #CJK UNIFIED IDEOGRAPH+0xE250 0x7953 #CJK UNIFIED IDEOGRAPH+0xE251 0x797A #CJK UNIFIED IDEOGRAPH+0xE252 0x797F #CJK UNIFIED IDEOGRAPH+0xE253 0x798A #CJK UNIFIED IDEOGRAPH+0xE254 0x799D #CJK UNIFIED IDEOGRAPH+0xE255 0x79A7 #CJK UNIFIED IDEOGRAPH+0xE256 0x9F4B #CJK UNIFIED IDEOGRAPH+0xE257 0x79AA #CJK UNIFIED IDEOGRAPH+0xE258 0x79AE #CJK UNIFIED IDEOGRAPH+0xE259 0x79B3 #CJK UNIFIED IDEOGRAPH+0xE25A 0x79B9 #CJK UNIFIED IDEOGRAPH+0xE25B 0x79BA #CJK UNIFIED IDEOGRAPH+0xE25C 0x79C9 #CJK UNIFIED IDEOGRAPH+0xE25D 0x79D5 #CJK UNIFIED IDEOGRAPH+0xE25E 0x79E7 #CJK UNIFIED IDEOGRAPH+0xE25F 0x79EC #CJK UNIFIED IDEOGRAPH+0xE260 0x79E1 #CJK UNIFIED IDEOGRAPH+0xE261 0x79E3 #CJK UNIFIED IDEOGRAPH+0xE262 0x7A08 #CJK UNIFIED IDEOGRAPH+0xE263 0x7A0D #CJK UNIFIED IDEOGRAPH+0xE264 0x7A18 #CJK UNIFIED IDEOGRAPH+0xE265 0x7A19 #CJK UNIFIED IDEOGRAPH+0xE266 0x7A20 #CJK UNIFIED IDEOGRAPH+0xE267 0x7A1F #CJK UNIFIED IDEOGRAPH+0xE268 0x7980 #CJK UNIFIED IDEOGRAPH+0xE269 0x7A31 #CJK UNIFIED IDEOGRAPH+0xE26A 0x7A3B #CJK UNIFIED IDEOGRAPH+0xE26B 0x7A3E #CJK UNIFIED IDEOGRAPH+0xE26C 0x7A37 #CJK UNIFIED IDEOGRAPH+0xE26D 0x7A43 #CJK UNIFIED IDEOGRAPH+0xE26E 0x7A57 #CJK UNIFIED IDEOGRAPH+0xE26F 0x7A49 #CJK UNIFIED IDEOGRAPH+0xE270 0x7A61 #CJK UNIFIED IDEOGRAPH+0xE271 0x7A62 #CJK UNIFIED IDEOGRAPH+0xE272 0x7A69 #CJK UNIFIED IDEOGRAPH+0xE273 0x9F9D #CJK UNIFIED IDEOGRAPH+0xE274 0x7A70 #CJK UNIFIED IDEOGRAPH+0xE275 0x7A79 #CJK UNIFIED IDEOGRAPH+0xE276 0x7A7D #CJK UNIFIED IDEOGRAPH+0xE277 0x7A88 #CJK UNIFIED IDEOGRAPH+0xE278 0x7A97 #CJK UNIFIED IDEOGRAPH+0xE279 0x7A95 #CJK UNIFIED IDEOGRAPH+0xE27A 0x7A98 #CJK UNIFIED IDEOGRAPH+0xE27B 0x7A96 #CJK UNIFIED IDEOGRAPH+0xE27C 0x7AA9 #CJK UNIFIED IDEOGRAPH+0xE27D 0x7AC8 #CJK UNIFIED IDEOGRAPH+0xE27E 0x7AB0 #CJK UNIFIED IDEOGRAPH+0xE280 0x7AB6 #CJK UNIFIED IDEOGRAPH+0xE281 0x7AC5 #CJK UNIFIED IDEOGRAPH+0xE282 0x7AC4 #CJK UNIFIED IDEOGRAPH+0xE283 0x7ABF #CJK UNIFIED IDEOGRAPH+0xE284 0x9083 #CJK UNIFIED IDEOGRAPH+0xE285 0x7AC7 #CJK UNIFIED IDEOGRAPH+0xE286 0x7ACA #CJK UNIFIED IDEOGRAPH+0xE287 0x7ACD #CJK UNIFIED IDEOGRAPH+0xE288 0x7ACF #CJK UNIFIED IDEOGRAPH+0xE289 0x7AD5 #CJK UNIFIED IDEOGRAPH+0xE28A 0x7AD3 #CJK UNIFIED IDEOGRAPH+0xE28B 0x7AD9 #CJK UNIFIED IDEOGRAPH+0xE28C 0x7ADA #CJK UNIFIED IDEOGRAPH+0xE28D 0x7ADD #CJK UNIFIED IDEOGRAPH+0xE28E 0x7AE1 #CJK UNIFIED IDEOGRAPH+0xE28F 0x7AE2 #CJK UNIFIED IDEOGRAPH+0xE290 0x7AE6 #CJK UNIFIED IDEOGRAPH+0xE291 0x7AED #CJK UNIFIED IDEOGRAPH+0xE292 0x7AF0 #CJK UNIFIED IDEOGRAPH+0xE293 0x7B02 #CJK UNIFIED IDEOGRAPH+0xE294 0x7B0F #CJK UNIFIED IDEOGRAPH+0xE295 0x7B0A #CJK UNIFIED IDEOGRAPH+0xE296 0x7B06 #CJK UNIFIED IDEOGRAPH+0xE297 0x7B33 #CJK UNIFIED IDEOGRAPH+0xE298 0x7B18 #CJK UNIFIED IDEOGRAPH+0xE299 0x7B19 #CJK UNIFIED IDEOGRAPH+0xE29A 0x7B1E #CJK UNIFIED IDEOGRAPH+0xE29B 0x7B35 #CJK UNIFIED IDEOGRAPH+0xE29C 0x7B28 #CJK UNIFIED IDEOGRAPH+0xE29D 0x7B36 #CJK UNIFIED IDEOGRAPH+0xE29E 0x7B50 #CJK UNIFIED IDEOGRAPH+0xE29F 0x7B7A #CJK UNIFIED IDEOGRAPH+0xE2A0 0x7B04 #CJK UNIFIED IDEOGRAPH+0xE2A1 0x7B4D #CJK UNIFIED IDEOGRAPH+0xE2A2 0x7B0B #CJK UNIFIED IDEOGRAPH+0xE2A3 0x7B4C #CJK UNIFIED IDEOGRAPH+0xE2A4 0x7B45 #CJK UNIFIED IDEOGRAPH+0xE2A5 0x7B75 #CJK UNIFIED IDEOGRAPH+0xE2A6 0x7B65 #CJK UNIFIED IDEOGRAPH+0xE2A7 0x7B74 #CJK UNIFIED IDEOGRAPH+0xE2A8 0x7B67 #CJK UNIFIED IDEOGRAPH+0xE2A9 0x7B70 #CJK UNIFIED IDEOGRAPH+0xE2AA 0x7B71 #CJK UNIFIED IDEOGRAPH+0xE2AB 0x7B6C #CJK UNIFIED IDEOGRAPH+0xE2AC 0x7B6E #CJK UNIFIED IDEOGRAPH+0xE2AD 0x7B9D #CJK UNIFIED IDEOGRAPH+0xE2AE 0x7B98 #CJK UNIFIED IDEOGRAPH+0xE2AF 0x7B9F #CJK UNIFIED IDEOGRAPH+0xE2B0 0x7B8D #CJK UNIFIED IDEOGRAPH+0xE2B1 0x7B9C #CJK UNIFIED IDEOGRAPH+0xE2B2 0x7B9A #CJK UNIFIED IDEOGRAPH+0xE2B3 0x7B8B #CJK UNIFIED IDEOGRAPH+0xE2B4 0x7B92 #CJK UNIFIED IDEOGRAPH+0xE2B5 0x7B8F #CJK UNIFIED IDEOGRAPH+0xE2B6 0x7B5D #CJK UNIFIED IDEOGRAPH+0xE2B7 0x7B99 #CJK UNIFIED IDEOGRAPH+0xE2B8 0x7BCB #CJK UNIFIED IDEOGRAPH+0xE2B9 0x7BC1 #CJK UNIFIED IDEOGRAPH+0xE2BA 0x7BCC #CJK UNIFIED IDEOGRAPH+0xE2BB 0x7BCF #CJK UNIFIED IDEOGRAPH+0xE2BC 0x7BB4 #CJK UNIFIED IDEOGRAPH+0xE2BD 0x7BC6 #CJK UNIFIED IDEOGRAPH+0xE2BE 0x7BDD #CJK UNIFIED IDEOGRAPH+0xE2BF 0x7BE9 #CJK UNIFIED IDEOGRAPH+0xE2C0 0x7C11 #CJK UNIFIED IDEOGRAPH+0xE2C1 0x7C14 #CJK UNIFIED IDEOGRAPH+0xE2C2 0x7BE6 #CJK UNIFIED IDEOGRAPH+0xE2C3 0x7BE5 #CJK UNIFIED IDEOGRAPH+0xE2C4 0x7C60 #CJK UNIFIED IDEOGRAPH+0xE2C5 0x7C00 #CJK UNIFIED IDEOGRAPH+0xE2C6 0x7C07 #CJK UNIFIED IDEOGRAPH+0xE2C7 0x7C13 #CJK UNIFIED IDEOGRAPH+0xE2C8 0x7BF3 #CJK UNIFIED IDEOGRAPH+0xE2C9 0x7BF7 #CJK UNIFIED IDEOGRAPH+0xE2CA 0x7C17 #CJK UNIFIED IDEOGRAPH+0xE2CB 0x7C0D #CJK UNIFIED IDEOGRAPH+0xE2CC 0x7BF6 #CJK UNIFIED IDEOGRAPH+0xE2CD 0x7C23 #CJK UNIFIED IDEOGRAPH+0xE2CE 0x7C27 #CJK UNIFIED IDEOGRAPH+0xE2CF 0x7C2A #CJK UNIFIED IDEOGRAPH+0xE2D0 0x7C1F #CJK UNIFIED IDEOGRAPH+0xE2D1 0x7C37 #CJK UNIFIED IDEOGRAPH+0xE2D2 0x7C2B #CJK UNIFIED IDEOGRAPH+0xE2D3 0x7C3D #CJK UNIFIED IDEOGRAPH+0xE2D4 0x7C4C #CJK UNIFIED IDEOGRAPH+0xE2D5 0x7C43 #CJK UNIFIED IDEOGRAPH+0xE2D6 0x7C54 #CJK UNIFIED IDEOGRAPH+0xE2D7 0x7C4F #CJK UNIFIED IDEOGRAPH+0xE2D8 0x7C40 #CJK UNIFIED IDEOGRAPH+0xE2D9 0x7C50 #CJK UNIFIED IDEOGRAPH+0xE2DA 0x7C58 #CJK UNIFIED IDEOGRAPH+0xE2DB 0x7C5F #CJK UNIFIED IDEOGRAPH+0xE2DC 0x7C64 #CJK UNIFIED IDEOGRAPH+0xE2DD 0x7C56 #CJK UNIFIED IDEOGRAPH+0xE2DE 0x7C65 #CJK UNIFIED IDEOGRAPH+0xE2DF 0x7C6C #CJK UNIFIED IDEOGRAPH+0xE2E0 0x7C75 #CJK UNIFIED IDEOGRAPH+0xE2E1 0x7C83 #CJK UNIFIED IDEOGRAPH+0xE2E2 0x7C90 #CJK UNIFIED IDEOGRAPH+0xE2E3 0x7CA4 #CJK UNIFIED IDEOGRAPH+0xE2E4 0x7CAD #CJK UNIFIED IDEOGRAPH+0xE2E5 0x7CA2 #CJK UNIFIED IDEOGRAPH+0xE2E6 0x7CAB #CJK UNIFIED IDEOGRAPH+0xE2E7 0x7CA1 #CJK UNIFIED IDEOGRAPH+0xE2E8 0x7CA8 #CJK UNIFIED IDEOGRAPH+0xE2E9 0x7CB3 #CJK UNIFIED IDEOGRAPH+0xE2EA 0x7CB2 #CJK UNIFIED IDEOGRAPH+0xE2EB 0x7CB1 #CJK UNIFIED IDEOGRAPH+0xE2EC 0x7CAE #CJK UNIFIED IDEOGRAPH+0xE2ED 0x7CB9 #CJK UNIFIED IDEOGRAPH+0xE2EE 0x7CBD #CJK UNIFIED IDEOGRAPH+0xE2EF 0x7CC0 #CJK UNIFIED IDEOGRAPH+0xE2F0 0x7CC5 #CJK UNIFIED IDEOGRAPH+0xE2F1 0x7CC2 #CJK UNIFIED IDEOGRAPH+0xE2F2 0x7CD8 #CJK UNIFIED IDEOGRAPH+0xE2F3 0x7CD2 #CJK UNIFIED IDEOGRAPH+0xE2F4 0x7CDC #CJK UNIFIED IDEOGRAPH+0xE2F5 0x7CE2 #CJK UNIFIED IDEOGRAPH+0xE2F6 0x9B3B #CJK UNIFIED IDEOGRAPH+0xE2F7 0x7CEF #CJK UNIFIED IDEOGRAPH+0xE2F8 0x7CF2 #CJK UNIFIED IDEOGRAPH+0xE2F9 0x7CF4 #CJK UNIFIED IDEOGRAPH+0xE2FA 0x7CF6 #CJK UNIFIED IDEOGRAPH+0xE2FB 0x7CFA #CJK UNIFIED IDEOGRAPH+0xE2FC 0x7D06 #CJK UNIFIED IDEOGRAPH+0xE340 0x7D02 #CJK UNIFIED IDEOGRAPH+0xE341 0x7D1C #CJK UNIFIED IDEOGRAPH+0xE342 0x7D15 #CJK UNIFIED IDEOGRAPH+0xE343 0x7D0A #CJK UNIFIED IDEOGRAPH+0xE344 0x7D45 #CJK UNIFIED IDEOGRAPH+0xE345 0x7D4B #CJK UNIFIED IDEOGRAPH+0xE346 0x7D2E #CJK UNIFIED IDEOGRAPH+0xE347 0x7D32 #CJK UNIFIED IDEOGRAPH+0xE348 0x7D3F #CJK UNIFIED IDEOGRAPH+0xE349 0x7D35 #CJK UNIFIED IDEOGRAPH+0xE34A 0x7D46 #CJK UNIFIED IDEOGRAPH+0xE34B 0x7D73 #CJK UNIFIED IDEOGRAPH+0xE34C 0x7D56 #CJK UNIFIED IDEOGRAPH+0xE34D 0x7D4E #CJK UNIFIED IDEOGRAPH+0xE34E 0x7D72 #CJK UNIFIED IDEOGRAPH+0xE34F 0x7D68 #CJK UNIFIED IDEOGRAPH+0xE350 0x7D6E #CJK UNIFIED IDEOGRAPH+0xE351 0x7D4F #CJK UNIFIED IDEOGRAPH+0xE352 0x7D63 #CJK UNIFIED IDEOGRAPH+0xE353 0x7D93 #CJK UNIFIED IDEOGRAPH+0xE354 0x7D89 #CJK UNIFIED IDEOGRAPH+0xE355 0x7D5B #CJK UNIFIED IDEOGRAPH+0xE356 0x7D8F #CJK UNIFIED IDEOGRAPH+0xE357 0x7D7D #CJK UNIFIED IDEOGRAPH+0xE358 0x7D9B #CJK UNIFIED IDEOGRAPH+0xE359 0x7DBA #CJK UNIFIED IDEOGRAPH+0xE35A 0x7DAE #CJK UNIFIED IDEOGRAPH+0xE35B 0x7DA3 #CJK UNIFIED IDEOGRAPH+0xE35C 0x7DB5 #CJK UNIFIED IDEOGRAPH+0xE35D 0x7DC7 #CJK UNIFIED IDEOGRAPH+0xE35E 0x7DBD #CJK UNIFIED IDEOGRAPH+0xE35F 0x7DAB #CJK UNIFIED IDEOGRAPH+0xE360 0x7E3D #CJK UNIFIED IDEOGRAPH+0xE361 0x7DA2 #CJK UNIFIED IDEOGRAPH+0xE362 0x7DAF #CJK UNIFIED IDEOGRAPH+0xE363 0x7DDC #CJK UNIFIED IDEOGRAPH+0xE364 0x7DB8 #CJK UNIFIED IDEOGRAPH+0xE365 0x7D9F #CJK UNIFIED IDEOGRAPH+0xE366 0x7DB0 #CJK UNIFIED IDEOGRAPH+0xE367 0x7DD8 #CJK UNIFIED IDEOGRAPH+0xE368 0x7DDD #CJK UNIFIED IDEOGRAPH+0xE369 0x7DE4 #CJK UNIFIED IDEOGRAPH+0xE36A 0x7DDE #CJK UNIFIED IDEOGRAPH+0xE36B 0x7DFB #CJK UNIFIED IDEOGRAPH+0xE36C 0x7DF2 #CJK UNIFIED IDEOGRAPH+0xE36D 0x7DE1 #CJK UNIFIED IDEOGRAPH+0xE36E 0x7E05 #CJK UNIFIED IDEOGRAPH+0xE36F 0x7E0A #CJK UNIFIED IDEOGRAPH+0xE370 0x7E23 #CJK UNIFIED IDEOGRAPH+0xE371 0x7E21 #CJK UNIFIED IDEOGRAPH+0xE372 0x7E12 #CJK UNIFIED IDEOGRAPH+0xE373 0x7E31 #CJK UNIFIED IDEOGRAPH+0xE374 0x7E1F #CJK UNIFIED IDEOGRAPH+0xE375 0x7E09 #CJK UNIFIED IDEOGRAPH+0xE376 0x7E0B #CJK UNIFIED IDEOGRAPH+0xE377 0x7E22 #CJK UNIFIED IDEOGRAPH+0xE378 0x7E46 #CJK UNIFIED IDEOGRAPH+0xE379 0x7E66 #CJK UNIFIED IDEOGRAPH+0xE37A 0x7E3B #CJK UNIFIED IDEOGRAPH+0xE37B 0x7E35 #CJK UNIFIED IDEOGRAPH+0xE37C 0x7E39 #CJK UNIFIED IDEOGRAPH+0xE37D 0x7E43 #CJK UNIFIED IDEOGRAPH+0xE37E 0x7E37 #CJK UNIFIED IDEOGRAPH+0xE380 0x7E32 #CJK UNIFIED IDEOGRAPH+0xE381 0x7E3A #CJK UNIFIED IDEOGRAPH+0xE382 0x7E67 #CJK UNIFIED IDEOGRAPH+0xE383 0x7E5D #CJK UNIFIED IDEOGRAPH+0xE384 0x7E56 #CJK UNIFIED IDEOGRAPH+0xE385 0x7E5E #CJK UNIFIED IDEOGRAPH+0xE386 0x7E59 #CJK UNIFIED IDEOGRAPH+0xE387 0x7E5A #CJK UNIFIED IDEOGRAPH+0xE388 0x7E79 #CJK UNIFIED IDEOGRAPH+0xE389 0x7E6A #CJK UNIFIED IDEOGRAPH+0xE38A 0x7E69 #CJK UNIFIED IDEOGRAPH+0xE38B 0x7E7C #CJK UNIFIED IDEOGRAPH+0xE38C 0x7E7B #CJK UNIFIED IDEOGRAPH+0xE38D 0x7E83 #CJK UNIFIED IDEOGRAPH+0xE38E 0x7DD5 #CJK UNIFIED IDEOGRAPH+0xE38F 0x7E7D #CJK UNIFIED IDEOGRAPH+0xE390 0x8FAE #CJK UNIFIED IDEOGRAPH+0xE391 0x7E7F #CJK UNIFIED IDEOGRAPH+0xE392 0x7E88 #CJK UNIFIED IDEOGRAPH+0xE393 0x7E89 #CJK UNIFIED IDEOGRAPH+0xE394 0x7E8C #CJK UNIFIED IDEOGRAPH+0xE395 0x7E92 #CJK UNIFIED IDEOGRAPH+0xE396 0x7E90 #CJK UNIFIED IDEOGRAPH+0xE397 0x7E93 #CJK UNIFIED IDEOGRAPH+0xE398 0x7E94 #CJK UNIFIED IDEOGRAPH+0xE399 0x7E96 #CJK UNIFIED IDEOGRAPH+0xE39A 0x7E8E #CJK UNIFIED IDEOGRAPH+0xE39B 0x7E9B #CJK UNIFIED IDEOGRAPH+0xE39C 0x7E9C #CJK UNIFIED IDEOGRAPH+0xE39D 0x7F38 #CJK UNIFIED IDEOGRAPH+0xE39E 0x7F3A #CJK UNIFIED IDEOGRAPH+0xE39F 0x7F45 #CJK UNIFIED IDEOGRAPH+0xE3A0 0x7F4C #CJK UNIFIED IDEOGRAPH+0xE3A1 0x7F4D #CJK UNIFIED IDEOGRAPH+0xE3A2 0x7F4E #CJK UNIFIED IDEOGRAPH+0xE3A3 0x7F50 #CJK UNIFIED IDEOGRAPH+0xE3A4 0x7F51 #CJK UNIFIED IDEOGRAPH+0xE3A5 0x7F55 #CJK UNIFIED IDEOGRAPH+0xE3A6 0x7F54 #CJK UNIFIED IDEOGRAPH+0xE3A7 0x7F58 #CJK UNIFIED IDEOGRAPH+0xE3A8 0x7F5F #CJK UNIFIED IDEOGRAPH+0xE3A9 0x7F60 #CJK UNIFIED IDEOGRAPH+0xE3AA 0x7F68 #CJK UNIFIED IDEOGRAPH+0xE3AB 0x7F69 #CJK UNIFIED IDEOGRAPH+0xE3AC 0x7F67 #CJK UNIFIED IDEOGRAPH+0xE3AD 0x7F78 #CJK UNIFIED IDEOGRAPH+0xE3AE 0x7F82 #CJK UNIFIED IDEOGRAPH+0xE3AF 0x7F86 #CJK UNIFIED IDEOGRAPH+0xE3B0 0x7F83 #CJK UNIFIED IDEOGRAPH+0xE3B1 0x7F88 #CJK UNIFIED IDEOGRAPH+0xE3B2 0x7F87 #CJK UNIFIED IDEOGRAPH+0xE3B3 0x7F8C #CJK UNIFIED IDEOGRAPH+0xE3B4 0x7F94 #CJK UNIFIED IDEOGRAPH+0xE3B5 0x7F9E #CJK UNIFIED IDEOGRAPH+0xE3B6 0x7F9D #CJK UNIFIED IDEOGRAPH+0xE3B7 0x7F9A #CJK UNIFIED IDEOGRAPH+0xE3B8 0x7FA3 #CJK UNIFIED IDEOGRAPH+0xE3B9 0x7FAF #CJK UNIFIED IDEOGRAPH+0xE3BA 0x7FB2 #CJK UNIFIED IDEOGRAPH+0xE3BB 0x7FB9 #CJK UNIFIED IDEOGRAPH+0xE3BC 0x7FAE #CJK UNIFIED IDEOGRAPH+0xE3BD 0x7FB6 #CJK UNIFIED IDEOGRAPH+0xE3BE 0x7FB8 #CJK UNIFIED IDEOGRAPH+0xE3BF 0x8B71 #CJK UNIFIED IDEOGRAPH+0xE3C0 0x7FC5 #CJK UNIFIED IDEOGRAPH+0xE3C1 0x7FC6 #CJK UNIFIED IDEOGRAPH+0xE3C2 0x7FCA #CJK UNIFIED IDEOGRAPH+0xE3C3 0x7FD5 #CJK UNIFIED IDEOGRAPH+0xE3C4 0x7FD4 #CJK UNIFIED IDEOGRAPH+0xE3C5 0x7FE1 #CJK UNIFIED IDEOGRAPH+0xE3C6 0x7FE6 #CJK UNIFIED IDEOGRAPH+0xE3C7 0x7FE9 #CJK UNIFIED IDEOGRAPH+0xE3C8 0x7FF3 #CJK UNIFIED IDEOGRAPH+0xE3C9 0x7FF9 #CJK UNIFIED IDEOGRAPH+0xE3CA 0x98DC #CJK UNIFIED IDEOGRAPH+0xE3CB 0x8006 #CJK UNIFIED IDEOGRAPH+0xE3CC 0x8004 #CJK UNIFIED IDEOGRAPH+0xE3CD 0x800B #CJK UNIFIED IDEOGRAPH+0xE3CE 0x8012 #CJK UNIFIED IDEOGRAPH+0xE3CF 0x8018 #CJK UNIFIED IDEOGRAPH+0xE3D0 0x8019 #CJK UNIFIED IDEOGRAPH+0xE3D1 0x801C #CJK UNIFIED IDEOGRAPH+0xE3D2 0x8021 #CJK UNIFIED IDEOGRAPH+0xE3D3 0x8028 #CJK UNIFIED IDEOGRAPH+0xE3D4 0x803F #CJK UNIFIED IDEOGRAPH+0xE3D5 0x803B #CJK UNIFIED IDEOGRAPH+0xE3D6 0x804A #CJK UNIFIED IDEOGRAPH+0xE3D7 0x8046 #CJK UNIFIED IDEOGRAPH+0xE3D8 0x8052 #CJK UNIFIED IDEOGRAPH+0xE3D9 0x8058 #CJK UNIFIED IDEOGRAPH+0xE3DA 0x805A #CJK UNIFIED IDEOGRAPH+0xE3DB 0x805F #CJK UNIFIED IDEOGRAPH+0xE3DC 0x8062 #CJK UNIFIED IDEOGRAPH+0xE3DD 0x8068 #CJK UNIFIED IDEOGRAPH+0xE3DE 0x8073 #CJK UNIFIED IDEOGRAPH+0xE3DF 0x8072 #CJK UNIFIED IDEOGRAPH+0xE3E0 0x8070 #CJK UNIFIED IDEOGRAPH+0xE3E1 0x8076 #CJK UNIFIED IDEOGRAPH+0xE3E2 0x8079 #CJK UNIFIED IDEOGRAPH+0xE3E3 0x807D #CJK UNIFIED IDEOGRAPH+0xE3E4 0x807F #CJK UNIFIED IDEOGRAPH+0xE3E5 0x8084 #CJK UNIFIED IDEOGRAPH+0xE3E6 0x8086 #CJK UNIFIED IDEOGRAPH+0xE3E7 0x8085 #CJK UNIFIED IDEOGRAPH+0xE3E8 0x809B #CJK UNIFIED IDEOGRAPH+0xE3E9 0x8093 #CJK UNIFIED IDEOGRAPH+0xE3EA 0x809A #CJK UNIFIED IDEOGRAPH+0xE3EB 0x80AD #CJK UNIFIED IDEOGRAPH+0xE3EC 0x5190 #CJK UNIFIED IDEOGRAPH+0xE3ED 0x80AC #CJK UNIFIED IDEOGRAPH+0xE3EE 0x80DB #CJK UNIFIED IDEOGRAPH+0xE3EF 0x80E5 #CJK UNIFIED IDEOGRAPH+0xE3F0 0x80D9 #CJK UNIFIED IDEOGRAPH+0xE3F1 0x80DD #CJK UNIFIED IDEOGRAPH+0xE3F2 0x80C4 #CJK UNIFIED IDEOGRAPH+0xE3F3 0x80DA #CJK UNIFIED IDEOGRAPH+0xE3F4 0x80D6 #CJK UNIFIED IDEOGRAPH+0xE3F5 0x8109 #CJK UNIFIED IDEOGRAPH+0xE3F6 0x80EF #CJK UNIFIED IDEOGRAPH+0xE3F7 0x80F1 #CJK UNIFIED IDEOGRAPH+0xE3F8 0x811B #CJK UNIFIED IDEOGRAPH+0xE3F9 0x8129 #CJK UNIFIED IDEOGRAPH+0xE3FA 0x8123 #CJK UNIFIED IDEOGRAPH+0xE3FB 0x812F #CJK UNIFIED IDEOGRAPH+0xE3FC 0x814B #CJK UNIFIED IDEOGRAPH+0xE440 0x968B #CJK UNIFIED IDEOGRAPH+0xE441 0x8146 #CJK UNIFIED IDEOGRAPH+0xE442 0x813E #CJK UNIFIED IDEOGRAPH+0xE443 0x8153 #CJK UNIFIED IDEOGRAPH+0xE444 0x8151 #CJK UNIFIED IDEOGRAPH+0xE445 0x80FC #CJK UNIFIED IDEOGRAPH+0xE446 0x8171 #CJK UNIFIED IDEOGRAPH+0xE447 0x816E #CJK UNIFIED IDEOGRAPH+0xE448 0x8165 #CJK UNIFIED IDEOGRAPH+0xE449 0x8166 #CJK UNIFIED IDEOGRAPH+0xE44A 0x8174 #CJK UNIFIED IDEOGRAPH+0xE44B 0x8183 #CJK UNIFIED IDEOGRAPH+0xE44C 0x8188 #CJK UNIFIED IDEOGRAPH+0xE44D 0x818A #CJK UNIFIED IDEOGRAPH+0xE44E 0x8180 #CJK UNIFIED IDEOGRAPH+0xE44F 0x8182 #CJK UNIFIED IDEOGRAPH+0xE450 0x81A0 #CJK UNIFIED IDEOGRAPH+0xE451 0x8195 #CJK UNIFIED IDEOGRAPH+0xE452 0x81A4 #CJK UNIFIED IDEOGRAPH+0xE453 0x81A3 #CJK UNIFIED IDEOGRAPH+0xE454 0x815F #CJK UNIFIED IDEOGRAPH+0xE455 0x8193 #CJK UNIFIED IDEOGRAPH+0xE456 0x81A9 #CJK UNIFIED IDEOGRAPH+0xE457 0x81B0 #CJK UNIFIED IDEOGRAPH+0xE458 0x81B5 #CJK UNIFIED IDEOGRAPH+0xE459 0x81BE #CJK UNIFIED IDEOGRAPH+0xE45A 0x81B8 #CJK UNIFIED IDEOGRAPH+0xE45B 0x81BD #CJK UNIFIED IDEOGRAPH+0xE45C 0x81C0 #CJK UNIFIED IDEOGRAPH+0xE45D 0x81C2 #CJK UNIFIED IDEOGRAPH+0xE45E 0x81BA #CJK UNIFIED IDEOGRAPH+0xE45F 0x81C9 #CJK UNIFIED IDEOGRAPH+0xE460 0x81CD #CJK UNIFIED IDEOGRAPH+0xE461 0x81D1 #CJK UNIFIED IDEOGRAPH+0xE462 0x81D9 #CJK UNIFIED IDEOGRAPH+0xE463 0x81D8 #CJK UNIFIED IDEOGRAPH+0xE464 0x81C8 #CJK UNIFIED IDEOGRAPH+0xE465 0x81DA #CJK UNIFIED IDEOGRAPH+0xE466 0x81DF #CJK UNIFIED IDEOGRAPH+0xE467 0x81E0 #CJK UNIFIED IDEOGRAPH+0xE468 0x81E7 #CJK UNIFIED IDEOGRAPH+0xE469 0x81FA #CJK UNIFIED IDEOGRAPH+0xE46A 0x81FB #CJK UNIFIED IDEOGRAPH+0xE46B 0x81FE #CJK UNIFIED IDEOGRAPH+0xE46C 0x8201 #CJK UNIFIED IDEOGRAPH+0xE46D 0x8202 #CJK UNIFIED IDEOGRAPH+0xE46E 0x8205 #CJK UNIFIED IDEOGRAPH+0xE46F 0x8207 #CJK UNIFIED IDEOGRAPH+0xE470 0x820A #CJK UNIFIED IDEOGRAPH+0xE471 0x820D #CJK UNIFIED IDEOGRAPH+0xE472 0x8210 #CJK UNIFIED IDEOGRAPH+0xE473 0x8216 #CJK UNIFIED IDEOGRAPH+0xE474 0x8229 #CJK UNIFIED IDEOGRAPH+0xE475 0x822B #CJK UNIFIED IDEOGRAPH+0xE476 0x8238 #CJK UNIFIED IDEOGRAPH+0xE477 0x8233 #CJK UNIFIED IDEOGRAPH+0xE478 0x8240 #CJK UNIFIED IDEOGRAPH+0xE479 0x8259 #CJK UNIFIED IDEOGRAPH+0xE47A 0x8258 #CJK UNIFIED IDEOGRAPH+0xE47B 0x825D #CJK UNIFIED IDEOGRAPH+0xE47C 0x825A #CJK UNIFIED IDEOGRAPH+0xE47D 0x825F #CJK UNIFIED IDEOGRAPH+0xE47E 0x8264 #CJK UNIFIED IDEOGRAPH+0xE480 0x8262 #CJK UNIFIED IDEOGRAPH+0xE481 0x8268 #CJK UNIFIED IDEOGRAPH+0xE482 0x826A #CJK UNIFIED IDEOGRAPH+0xE483 0x826B #CJK UNIFIED IDEOGRAPH+0xE484 0x822E #CJK UNIFIED IDEOGRAPH+0xE485 0x8271 #CJK UNIFIED IDEOGRAPH+0xE486 0x8277 #CJK UNIFIED IDEOGRAPH+0xE487 0x8278 #CJK UNIFIED IDEOGRAPH+0xE488 0x827E #CJK UNIFIED IDEOGRAPH+0xE489 0x828D #CJK UNIFIED IDEOGRAPH+0xE48A 0x8292 #CJK UNIFIED IDEOGRAPH+0xE48B 0x82AB #CJK UNIFIED IDEOGRAPH+0xE48C 0x829F #CJK UNIFIED IDEOGRAPH+0xE48D 0x82BB #CJK UNIFIED IDEOGRAPH+0xE48E 0x82AC #CJK UNIFIED IDEOGRAPH+0xE48F 0x82E1 #CJK UNIFIED IDEOGRAPH+0xE490 0x82E3 #CJK UNIFIED IDEOGRAPH+0xE491 0x82DF #CJK UNIFIED IDEOGRAPH+0xE492 0x82D2 #CJK UNIFIED IDEOGRAPH+0xE493 0x82F4 #CJK UNIFIED IDEOGRAPH+0xE494 0x82F3 #CJK UNIFIED IDEOGRAPH+0xE495 0x82FA #CJK UNIFIED IDEOGRAPH+0xE496 0x8393 #CJK UNIFIED IDEOGRAPH+0xE497 0x8303 #CJK UNIFIED IDEOGRAPH+0xE498 0x82FB #CJK UNIFIED IDEOGRAPH+0xE499 0x82F9 #CJK UNIFIED IDEOGRAPH+0xE49A 0x82DE #CJK UNIFIED IDEOGRAPH+0xE49B 0x8306 #CJK UNIFIED IDEOGRAPH+0xE49C 0x82DC #CJK UNIFIED IDEOGRAPH+0xE49D 0x8309 #CJK UNIFIED IDEOGRAPH+0xE49E 0x82D9 #CJK UNIFIED IDEOGRAPH+0xE49F 0x8335 #CJK UNIFIED IDEOGRAPH+0xE4A0 0x8334 #CJK UNIFIED IDEOGRAPH+0xE4A1 0x8316 #CJK UNIFIED IDEOGRAPH+0xE4A2 0x8332 #CJK UNIFIED IDEOGRAPH+0xE4A3 0x8331 #CJK UNIFIED IDEOGRAPH+0xE4A4 0x8340 #CJK UNIFIED IDEOGRAPH+0xE4A5 0x8339 #CJK UNIFIED IDEOGRAPH+0xE4A6 0x8350 #CJK UNIFIED IDEOGRAPH+0xE4A7 0x8345 #CJK UNIFIED IDEOGRAPH+0xE4A8 0x832F #CJK UNIFIED IDEOGRAPH+0xE4A9 0x832B #CJK UNIFIED IDEOGRAPH+0xE4AA 0x8317 #CJK UNIFIED IDEOGRAPH+0xE4AB 0x8318 #CJK UNIFIED IDEOGRAPH+0xE4AC 0x8385 #CJK UNIFIED IDEOGRAPH+0xE4AD 0x839A #CJK UNIFIED IDEOGRAPH+0xE4AE 0x83AA #CJK UNIFIED IDEOGRAPH+0xE4AF 0x839F #CJK UNIFIED IDEOGRAPH+0xE4B0 0x83A2 #CJK UNIFIED IDEOGRAPH+0xE4B1 0x8396 #CJK UNIFIED IDEOGRAPH+0xE4B2 0x8323 #CJK UNIFIED IDEOGRAPH+0xE4B3 0x838E #CJK UNIFIED IDEOGRAPH+0xE4B4 0x8387 #CJK UNIFIED IDEOGRAPH+0xE4B5 0x838A #CJK UNIFIED IDEOGRAPH+0xE4B6 0x837C #CJK UNIFIED IDEOGRAPH+0xE4B7 0x83B5 #CJK UNIFIED IDEOGRAPH+0xE4B8 0x8373 #CJK UNIFIED IDEOGRAPH+0xE4B9 0x8375 #CJK UNIFIED IDEOGRAPH+0xE4BA 0x83A0 #CJK UNIFIED IDEOGRAPH+0xE4BB 0x8389 #CJK UNIFIED IDEOGRAPH+0xE4BC 0x83A8 #CJK UNIFIED IDEOGRAPH+0xE4BD 0x83F4 #CJK UNIFIED IDEOGRAPH+0xE4BE 0x8413 #CJK UNIFIED IDEOGRAPH+0xE4BF 0x83EB #CJK UNIFIED IDEOGRAPH+0xE4C0 0x83CE #CJK UNIFIED IDEOGRAPH+0xE4C1 0x83FD #CJK UNIFIED IDEOGRAPH+0xE4C2 0x8403 #CJK UNIFIED IDEOGRAPH+0xE4C3 0x83D8 #CJK UNIFIED IDEOGRAPH+0xE4C4 0x840B #CJK UNIFIED IDEOGRAPH+0xE4C5 0x83C1 #CJK UNIFIED IDEOGRAPH+0xE4C6 0x83F7 #CJK UNIFIED IDEOGRAPH+0xE4C7 0x8407 #CJK UNIFIED IDEOGRAPH+0xE4C8 0x83E0 #CJK UNIFIED IDEOGRAPH+0xE4C9 0x83F2 #CJK UNIFIED IDEOGRAPH+0xE4CA 0x840D #CJK UNIFIED IDEOGRAPH+0xE4CB 0x8422 #CJK UNIFIED IDEOGRAPH+0xE4CC 0x8420 #CJK UNIFIED IDEOGRAPH+0xE4CD 0x83BD #CJK UNIFIED IDEOGRAPH+0xE4CE 0x8438 #CJK UNIFIED IDEOGRAPH+0xE4CF 0x8506 #CJK UNIFIED IDEOGRAPH+0xE4D0 0x83FB #CJK UNIFIED IDEOGRAPH+0xE4D1 0x846D #CJK UNIFIED IDEOGRAPH+0xE4D2 0x842A #CJK UNIFIED IDEOGRAPH+0xE4D3 0x843C #CJK UNIFIED IDEOGRAPH+0xE4D4 0x855A #CJK UNIFIED IDEOGRAPH+0xE4D5 0x8484 #CJK UNIFIED IDEOGRAPH+0xE4D6 0x8477 #CJK UNIFIED IDEOGRAPH+0xE4D7 0x846B #CJK UNIFIED IDEOGRAPH+0xE4D8 0x84AD #CJK UNIFIED IDEOGRAPH+0xE4D9 0x846E #CJK UNIFIED IDEOGRAPH+0xE4DA 0x8482 #CJK UNIFIED IDEOGRAPH+0xE4DB 0x8469 #CJK UNIFIED IDEOGRAPH+0xE4DC 0x8446 #CJK UNIFIED IDEOGRAPH+0xE4DD 0x842C #CJK UNIFIED IDEOGRAPH+0xE4DE 0x846F #CJK UNIFIED IDEOGRAPH+0xE4DF 0x8479 #CJK UNIFIED IDEOGRAPH+0xE4E0 0x8435 #CJK UNIFIED IDEOGRAPH+0xE4E1 0x84CA #CJK UNIFIED IDEOGRAPH+0xE4E2 0x8462 #CJK UNIFIED IDEOGRAPH+0xE4E3 0x84B9 #CJK UNIFIED IDEOGRAPH+0xE4E4 0x84BF #CJK UNIFIED IDEOGRAPH+0xE4E5 0x849F #CJK UNIFIED IDEOGRAPH+0xE4E6 0x84D9 #CJK UNIFIED IDEOGRAPH+0xE4E7 0x84CD #CJK UNIFIED IDEOGRAPH+0xE4E8 0x84BB #CJK UNIFIED IDEOGRAPH+0xE4E9 0x84DA #CJK UNIFIED IDEOGRAPH+0xE4EA 0x84D0 #CJK UNIFIED IDEOGRAPH+0xE4EB 0x84C1 #CJK UNIFIED IDEOGRAPH+0xE4EC 0x84C6 #CJK UNIFIED IDEOGRAPH+0xE4ED 0x84D6 #CJK UNIFIED IDEOGRAPH+0xE4EE 0x84A1 #CJK UNIFIED IDEOGRAPH+0xE4EF 0x8521 #CJK UNIFIED IDEOGRAPH+0xE4F0 0x84FF #CJK UNIFIED IDEOGRAPH+0xE4F1 0x84F4 #CJK UNIFIED IDEOGRAPH+0xE4F2 0x8517 #CJK UNIFIED IDEOGRAPH+0xE4F3 0x8518 #CJK UNIFIED IDEOGRAPH+0xE4F4 0x852C #CJK UNIFIED IDEOGRAPH+0xE4F5 0x851F #CJK UNIFIED IDEOGRAPH+0xE4F6 0x8515 #CJK UNIFIED IDEOGRAPH+0xE4F7 0x8514 #CJK UNIFIED IDEOGRAPH+0xE4F8 0x84FC #CJK UNIFIED IDEOGRAPH+0xE4F9 0x8540 #CJK UNIFIED IDEOGRAPH+0xE4FA 0x8563 #CJK UNIFIED IDEOGRAPH+0xE4FB 0x8558 #CJK UNIFIED IDEOGRAPH+0xE4FC 0x8548 #CJK UNIFIED IDEOGRAPH+0xE540 0x8541 #CJK UNIFIED IDEOGRAPH+0xE541 0x8602 #CJK UNIFIED IDEOGRAPH+0xE542 0x854B #CJK UNIFIED IDEOGRAPH+0xE543 0x8555 #CJK UNIFIED IDEOGRAPH+0xE544 0x8580 #CJK UNIFIED IDEOGRAPH+0xE545 0x85A4 #CJK UNIFIED IDEOGRAPH+0xE546 0x8588 #CJK UNIFIED IDEOGRAPH+0xE547 0x8591 #CJK UNIFIED IDEOGRAPH+0xE548 0x858A #CJK UNIFIED IDEOGRAPH+0xE549 0x85A8 #CJK UNIFIED IDEOGRAPH+0xE54A 0x856D #CJK UNIFIED IDEOGRAPH+0xE54B 0x8594 #CJK UNIFIED IDEOGRAPH+0xE54C 0x859B #CJK UNIFIED IDEOGRAPH+0xE54D 0x85EA #CJK UNIFIED IDEOGRAPH+0xE54E 0x8587 #CJK UNIFIED IDEOGRAPH+0xE54F 0x859C #CJK UNIFIED IDEOGRAPH+0xE550 0x8577 #CJK UNIFIED IDEOGRAPH+0xE551 0x857E #CJK UNIFIED IDEOGRAPH+0xE552 0x8590 #CJK UNIFIED IDEOGRAPH+0xE553 0x85C9 #CJK UNIFIED IDEOGRAPH+0xE554 0x85BA #CJK UNIFIED IDEOGRAPH+0xE555 0x85CF #CJK UNIFIED IDEOGRAPH+0xE556 0x85B9 #CJK UNIFIED IDEOGRAPH+0xE557 0x85D0 #CJK UNIFIED IDEOGRAPH+0xE558 0x85D5 #CJK UNIFIED IDEOGRAPH+0xE559 0x85DD #CJK UNIFIED IDEOGRAPH+0xE55A 0x85E5 #CJK UNIFIED IDEOGRAPH+0xE55B 0x85DC #CJK UNIFIED IDEOGRAPH+0xE55C 0x85F9 #CJK UNIFIED IDEOGRAPH+0xE55D 0x860A #CJK UNIFIED IDEOGRAPH+0xE55E 0x8613 #CJK UNIFIED IDEOGRAPH+0xE55F 0x860B #CJK UNIFIED IDEOGRAPH+0xE560 0x85FE #CJK UNIFIED IDEOGRAPH+0xE561 0x85FA #CJK UNIFIED IDEOGRAPH+0xE562 0x8606 #CJK UNIFIED IDEOGRAPH+0xE563 0x8622 #CJK UNIFIED IDEOGRAPH+0xE564 0x861A #CJK UNIFIED IDEOGRAPH+0xE565 0x8630 #CJK UNIFIED IDEOGRAPH+0xE566 0x863F #CJK UNIFIED IDEOGRAPH+0xE567 0x864D #CJK UNIFIED IDEOGRAPH+0xE568 0x4E55 #CJK UNIFIED IDEOGRAPH+0xE569 0x8654 #CJK UNIFIED IDEOGRAPH+0xE56A 0x865F #CJK UNIFIED IDEOGRAPH+0xE56B 0x8667 #CJK UNIFIED IDEOGRAPH+0xE56C 0x8671 #CJK UNIFIED IDEOGRAPH+0xE56D 0x8693 #CJK UNIFIED IDEOGRAPH+0xE56E 0x86A3 #CJK UNIFIED IDEOGRAPH+0xE56F 0x86A9 #CJK UNIFIED IDEOGRAPH+0xE570 0x86AA #CJK UNIFIED IDEOGRAPH+0xE571 0x868B #CJK UNIFIED IDEOGRAPH+0xE572 0x868C #CJK UNIFIED IDEOGRAPH+0xE573 0x86B6 #CJK UNIFIED IDEOGRAPH+0xE574 0x86AF #CJK UNIFIED IDEOGRAPH+0xE575 0x86C4 #CJK UNIFIED IDEOGRAPH+0xE576 0x86C6 #CJK UNIFIED IDEOGRAPH+0xE577 0x86B0 #CJK UNIFIED IDEOGRAPH+0xE578 0x86C9 #CJK UNIFIED IDEOGRAPH+0xE579 0x8823 #CJK UNIFIED IDEOGRAPH+0xE57A 0x86AB #CJK UNIFIED IDEOGRAPH+0xE57B 0x86D4 #CJK UNIFIED IDEOGRAPH+0xE57C 0x86DE #CJK UNIFIED IDEOGRAPH+0xE57D 0x86E9 #CJK UNIFIED IDEOGRAPH+0xE57E 0x86EC #CJK UNIFIED IDEOGRAPH+0xE580 0x86DF #CJK UNIFIED IDEOGRAPH+0xE581 0x86DB #CJK UNIFIED IDEOGRAPH+0xE582 0x86EF #CJK UNIFIED IDEOGRAPH+0xE583 0x8712 #CJK UNIFIED IDEOGRAPH+0xE584 0x8706 #CJK UNIFIED IDEOGRAPH+0xE585 0x8708 #CJK UNIFIED IDEOGRAPH+0xE586 0x8700 #CJK UNIFIED IDEOGRAPH+0xE587 0x8703 #CJK UNIFIED IDEOGRAPH+0xE588 0x86FB #CJK UNIFIED IDEOGRAPH+0xE589 0x8711 #CJK UNIFIED IDEOGRAPH+0xE58A 0x8709 #CJK UNIFIED IDEOGRAPH+0xE58B 0x870D #CJK UNIFIED IDEOGRAPH+0xE58C 0x86F9 #CJK UNIFIED IDEOGRAPH+0xE58D 0x870A #CJK UNIFIED IDEOGRAPH+0xE58E 0x8734 #CJK UNIFIED IDEOGRAPH+0xE58F 0x873F #CJK UNIFIED IDEOGRAPH+0xE590 0x8737 #CJK UNIFIED IDEOGRAPH+0xE591 0x873B #CJK UNIFIED IDEOGRAPH+0xE592 0x8725 #CJK UNIFIED IDEOGRAPH+0xE593 0x8729 #CJK UNIFIED IDEOGRAPH+0xE594 0x871A #CJK UNIFIED IDEOGRAPH+0xE595 0x8760 #CJK UNIFIED IDEOGRAPH+0xE596 0x875F #CJK UNIFIED IDEOGRAPH+0xE597 0x8778 #CJK UNIFIED IDEOGRAPH+0xE598 0x874C #CJK UNIFIED IDEOGRAPH+0xE599 0x874E #CJK UNIFIED IDEOGRAPH+0xE59A 0x8774 #CJK UNIFIED IDEOGRAPH+0xE59B 0x8757 #CJK UNIFIED IDEOGRAPH+0xE59C 0x8768 #CJK UNIFIED IDEOGRAPH+0xE59D 0x876E #CJK UNIFIED IDEOGRAPH+0xE59E 0x8759 #CJK UNIFIED IDEOGRAPH+0xE59F 0x8753 #CJK UNIFIED IDEOGRAPH+0xE5A0 0x8763 #CJK UNIFIED IDEOGRAPH+0xE5A1 0x876A #CJK UNIFIED IDEOGRAPH+0xE5A2 0x8805 #CJK UNIFIED IDEOGRAPH+0xE5A3 0x87A2 #CJK UNIFIED IDEOGRAPH+0xE5A4 0x879F #CJK UNIFIED IDEOGRAPH+0xE5A5 0x8782 #CJK UNIFIED IDEOGRAPH+0xE5A6 0x87AF #CJK UNIFIED IDEOGRAPH+0xE5A7 0x87CB #CJK UNIFIED IDEOGRAPH+0xE5A8 0x87BD #CJK UNIFIED IDEOGRAPH+0xE5A9 0x87C0 #CJK UNIFIED IDEOGRAPH+0xE5AA 0x87D0 #CJK UNIFIED IDEOGRAPH+0xE5AB 0x96D6 #CJK UNIFIED IDEOGRAPH+0xE5AC 0x87AB #CJK UNIFIED IDEOGRAPH+0xE5AD 0x87C4 #CJK UNIFIED IDEOGRAPH+0xE5AE 0x87B3 #CJK UNIFIED IDEOGRAPH+0xE5AF 0x87C7 #CJK UNIFIED IDEOGRAPH+0xE5B0 0x87C6 #CJK UNIFIED IDEOGRAPH+0xE5B1 0x87BB #CJK UNIFIED IDEOGRAPH+0xE5B2 0x87EF #CJK UNIFIED IDEOGRAPH+0xE5B3 0x87F2 #CJK UNIFIED IDEOGRAPH+0xE5B4 0x87E0 #CJK UNIFIED IDEOGRAPH+0xE5B5 0x880F #CJK UNIFIED IDEOGRAPH+0xE5B6 0x880D #CJK UNIFIED IDEOGRAPH+0xE5B7 0x87FE #CJK UNIFIED IDEOGRAPH+0xE5B8 0x87F6 #CJK UNIFIED IDEOGRAPH+0xE5B9 0x87F7 #CJK UNIFIED IDEOGRAPH+0xE5BA 0x880E #CJK UNIFIED IDEOGRAPH+0xE5BB 0x87D2 #CJK UNIFIED IDEOGRAPH+0xE5BC 0x8811 #CJK UNIFIED IDEOGRAPH+0xE5BD 0x8816 #CJK UNIFIED IDEOGRAPH+0xE5BE 0x8815 #CJK UNIFIED IDEOGRAPH+0xE5BF 0x8822 #CJK UNIFIED IDEOGRAPH+0xE5C0 0x8821 #CJK UNIFIED IDEOGRAPH+0xE5C1 0x8831 #CJK UNIFIED IDEOGRAPH+0xE5C2 0x8836 #CJK UNIFIED IDEOGRAPH+0xE5C3 0x8839 #CJK UNIFIED IDEOGRAPH+0xE5C4 0x8827 #CJK UNIFIED IDEOGRAPH+0xE5C5 0x883B #CJK UNIFIED IDEOGRAPH+0xE5C6 0x8844 #CJK UNIFIED IDEOGRAPH+0xE5C7 0x8842 #CJK UNIFIED IDEOGRAPH+0xE5C8 0x8852 #CJK UNIFIED IDEOGRAPH+0xE5C9 0x8859 #CJK UNIFIED IDEOGRAPH+0xE5CA 0x885E #CJK UNIFIED IDEOGRAPH+0xE5CB 0x8862 #CJK UNIFIED IDEOGRAPH+0xE5CC 0x886B #CJK UNIFIED IDEOGRAPH+0xE5CD 0x8881 #CJK UNIFIED IDEOGRAPH+0xE5CE 0x887E #CJK UNIFIED IDEOGRAPH+0xE5CF 0x889E #CJK UNIFIED IDEOGRAPH+0xE5D0 0x8875 #CJK UNIFIED IDEOGRAPH+0xE5D1 0x887D #CJK UNIFIED IDEOGRAPH+0xE5D2 0x88B5 #CJK UNIFIED IDEOGRAPH+0xE5D3 0x8872 #CJK UNIFIED IDEOGRAPH+0xE5D4 0x8882 #CJK UNIFIED IDEOGRAPH+0xE5D5 0x8897 #CJK UNIFIED IDEOGRAPH+0xE5D6 0x8892 #CJK UNIFIED IDEOGRAPH+0xE5D7 0x88AE #CJK UNIFIED IDEOGRAPH+0xE5D8 0x8899 #CJK UNIFIED IDEOGRAPH+0xE5D9 0x88A2 #CJK UNIFIED IDEOGRAPH+0xE5DA 0x888D #CJK UNIFIED IDEOGRAPH+0xE5DB 0x88A4 #CJK UNIFIED IDEOGRAPH+0xE5DC 0x88B0 #CJK UNIFIED IDEOGRAPH+0xE5DD 0x88BF #CJK UNIFIED IDEOGRAPH+0xE5DE 0x88B1 #CJK UNIFIED IDEOGRAPH+0xE5DF 0x88C3 #CJK UNIFIED IDEOGRAPH+0xE5E0 0x88C4 #CJK UNIFIED IDEOGRAPH+0xE5E1 0x88D4 #CJK UNIFIED IDEOGRAPH+0xE5E2 0x88D8 #CJK UNIFIED IDEOGRAPH+0xE5E3 0x88D9 #CJK UNIFIED IDEOGRAPH+0xE5E4 0x88DD #CJK UNIFIED IDEOGRAPH+0xE5E5 0x88F9 #CJK UNIFIED IDEOGRAPH+0xE5E6 0x8902 #CJK UNIFIED IDEOGRAPH+0xE5E7 0x88FC #CJK UNIFIED IDEOGRAPH+0xE5E8 0x88F4 #CJK UNIFIED IDEOGRAPH+0xE5E9 0x88E8 #CJK UNIFIED IDEOGRAPH+0xE5EA 0x88F2 #CJK UNIFIED IDEOGRAPH+0xE5EB 0x8904 #CJK UNIFIED IDEOGRAPH+0xE5EC 0x890C #CJK UNIFIED IDEOGRAPH+0xE5ED 0x890A #CJK UNIFIED IDEOGRAPH+0xE5EE 0x8913 #CJK UNIFIED IDEOGRAPH+0xE5EF 0x8943 #CJK UNIFIED IDEOGRAPH+0xE5F0 0x891E #CJK UNIFIED IDEOGRAPH+0xE5F1 0x8925 #CJK UNIFIED IDEOGRAPH+0xE5F2 0x892A #CJK UNIFIED IDEOGRAPH+0xE5F3 0x892B #CJK UNIFIED IDEOGRAPH+0xE5F4 0x8941 #CJK UNIFIED IDEOGRAPH+0xE5F5 0x8944 #CJK UNIFIED IDEOGRAPH+0xE5F6 0x893B #CJK UNIFIED IDEOGRAPH+0xE5F7 0x8936 #CJK UNIFIED IDEOGRAPH+0xE5F8 0x8938 #CJK UNIFIED IDEOGRAPH+0xE5F9 0x894C #CJK UNIFIED IDEOGRAPH+0xE5FA 0x891D #CJK UNIFIED IDEOGRAPH+0xE5FB 0x8960 #CJK UNIFIED IDEOGRAPH+0xE5FC 0x895E #CJK UNIFIED IDEOGRAPH+0xE640 0x8966 #CJK UNIFIED IDEOGRAPH+0xE641 0x8964 #CJK UNIFIED IDEOGRAPH+0xE642 0x896D #CJK UNIFIED IDEOGRAPH+0xE643 0x896A #CJK UNIFIED IDEOGRAPH+0xE644 0x896F #CJK UNIFIED IDEOGRAPH+0xE645 0x8974 #CJK UNIFIED IDEOGRAPH+0xE646 0x8977 #CJK UNIFIED IDEOGRAPH+0xE647 0x897E #CJK UNIFIED IDEOGRAPH+0xE648 0x8983 #CJK UNIFIED IDEOGRAPH+0xE649 0x8988 #CJK UNIFIED IDEOGRAPH+0xE64A 0x898A #CJK UNIFIED IDEOGRAPH+0xE64B 0x8993 #CJK UNIFIED IDEOGRAPH+0xE64C 0x8998 #CJK UNIFIED IDEOGRAPH+0xE64D 0x89A1 #CJK UNIFIED IDEOGRAPH+0xE64E 0x89A9 #CJK UNIFIED IDEOGRAPH+0xE64F 0x89A6 #CJK UNIFIED IDEOGRAPH+0xE650 0x89AC #CJK UNIFIED IDEOGRAPH+0xE651 0x89AF #CJK UNIFIED IDEOGRAPH+0xE652 0x89B2 #CJK UNIFIED IDEOGRAPH+0xE653 0x89BA #CJK UNIFIED IDEOGRAPH+0xE654 0x89BD #CJK UNIFIED IDEOGRAPH+0xE655 0x89BF #CJK UNIFIED IDEOGRAPH+0xE656 0x89C0 #CJK UNIFIED IDEOGRAPH+0xE657 0x89DA #CJK UNIFIED IDEOGRAPH+0xE658 0x89DC #CJK UNIFIED IDEOGRAPH+0xE659 0x89DD #CJK UNIFIED IDEOGRAPH+0xE65A 0x89E7 #CJK UNIFIED IDEOGRAPH+0xE65B 0x89F4 #CJK UNIFIED IDEOGRAPH+0xE65C 0x89F8 #CJK UNIFIED IDEOGRAPH+0xE65D 0x8A03 #CJK UNIFIED IDEOGRAPH+0xE65E 0x8A16 #CJK UNIFIED IDEOGRAPH+0xE65F 0x8A10 #CJK UNIFIED IDEOGRAPH+0xE660 0x8A0C #CJK UNIFIED IDEOGRAPH+0xE661 0x8A1B #CJK UNIFIED IDEOGRAPH+0xE662 0x8A1D #CJK UNIFIED IDEOGRAPH+0xE663 0x8A25 #CJK UNIFIED IDEOGRAPH+0xE664 0x8A36 #CJK UNIFIED IDEOGRAPH+0xE665 0x8A41 #CJK UNIFIED IDEOGRAPH+0xE666 0x8A5B #CJK UNIFIED IDEOGRAPH+0xE667 0x8A52 #CJK UNIFIED IDEOGRAPH+0xE668 0x8A46 #CJK UNIFIED IDEOGRAPH+0xE669 0x8A48 #CJK UNIFIED IDEOGRAPH+0xE66A 0x8A7C #CJK UNIFIED IDEOGRAPH+0xE66B 0x8A6D #CJK UNIFIED IDEOGRAPH+0xE66C 0x8A6C #CJK UNIFIED IDEOGRAPH+0xE66D 0x8A62 #CJK UNIFIED IDEOGRAPH+0xE66E 0x8A85 #CJK UNIFIED IDEOGRAPH+0xE66F 0x8A82 #CJK UNIFIED IDEOGRAPH+0xE670 0x8A84 #CJK UNIFIED IDEOGRAPH+0xE671 0x8AA8 #CJK UNIFIED IDEOGRAPH+0xE672 0x8AA1 #CJK UNIFIED IDEOGRAPH+0xE673 0x8A91 #CJK UNIFIED IDEOGRAPH+0xE674 0x8AA5 #CJK UNIFIED IDEOGRAPH+0xE675 0x8AA6 #CJK UNIFIED IDEOGRAPH+0xE676 0x8A9A #CJK UNIFIED IDEOGRAPH+0xE677 0x8AA3 #CJK UNIFIED IDEOGRAPH+0xE678 0x8AC4 #CJK UNIFIED IDEOGRAPH+0xE679 0x8ACD #CJK UNIFIED IDEOGRAPH+0xE67A 0x8AC2 #CJK UNIFIED IDEOGRAPH+0xE67B 0x8ADA #CJK UNIFIED IDEOGRAPH+0xE67C 0x8AEB #CJK UNIFIED IDEOGRAPH+0xE67D 0x8AF3 #CJK UNIFIED IDEOGRAPH+0xE67E 0x8AE7 #CJK UNIFIED IDEOGRAPH+0xE680 0x8AE4 #CJK UNIFIED IDEOGRAPH+0xE681 0x8AF1 #CJK UNIFIED IDEOGRAPH+0xE682 0x8B14 #CJK UNIFIED IDEOGRAPH+0xE683 0x8AE0 #CJK UNIFIED IDEOGRAPH+0xE684 0x8AE2 #CJK UNIFIED IDEOGRAPH+0xE685 0x8AF7 #CJK UNIFIED IDEOGRAPH+0xE686 0x8ADE #CJK UNIFIED IDEOGRAPH+0xE687 0x8ADB #CJK UNIFIED IDEOGRAPH+0xE688 0x8B0C #CJK UNIFIED IDEOGRAPH+0xE689 0x8B07 #CJK UNIFIED IDEOGRAPH+0xE68A 0x8B1A #CJK UNIFIED IDEOGRAPH+0xE68B 0x8AE1 #CJK UNIFIED IDEOGRAPH+0xE68C 0x8B16 #CJK UNIFIED IDEOGRAPH+0xE68D 0x8B10 #CJK UNIFIED IDEOGRAPH+0xE68E 0x8B17 #CJK UNIFIED IDEOGRAPH+0xE68F 0x8B20 #CJK UNIFIED IDEOGRAPH+0xE690 0x8B33 #CJK UNIFIED IDEOGRAPH+0xE691 0x97AB #CJK UNIFIED IDEOGRAPH+0xE692 0x8B26 #CJK UNIFIED IDEOGRAPH+0xE693 0x8B2B #CJK UNIFIED IDEOGRAPH+0xE694 0x8B3E #CJK UNIFIED IDEOGRAPH+0xE695 0x8B28 #CJK UNIFIED IDEOGRAPH+0xE696 0x8B41 #CJK UNIFIED IDEOGRAPH+0xE697 0x8B4C #CJK UNIFIED IDEOGRAPH+0xE698 0x8B4F #CJK UNIFIED IDEOGRAPH+0xE699 0x8B4E #CJK UNIFIED IDEOGRAPH+0xE69A 0x8B49 #CJK UNIFIED IDEOGRAPH+0xE69B 0x8B56 #CJK UNIFIED IDEOGRAPH+0xE69C 0x8B5B #CJK UNIFIED IDEOGRAPH+0xE69D 0x8B5A #CJK UNIFIED IDEOGRAPH+0xE69E 0x8B6B #CJK UNIFIED IDEOGRAPH+0xE69F 0x8B5F #CJK UNIFIED IDEOGRAPH+0xE6A0 0x8B6C #CJK UNIFIED IDEOGRAPH+0xE6A1 0x8B6F #CJK UNIFIED IDEOGRAPH+0xE6A2 0x8B74 #CJK UNIFIED IDEOGRAPH+0xE6A3 0x8B7D #CJK UNIFIED IDEOGRAPH+0xE6A4 0x8B80 #CJK UNIFIED IDEOGRAPH+0xE6A5 0x8B8C #CJK UNIFIED IDEOGRAPH+0xE6A6 0x8B8E #CJK UNIFIED IDEOGRAPH+0xE6A7 0x8B92 #CJK UNIFIED IDEOGRAPH+0xE6A8 0x8B93 #CJK UNIFIED IDEOGRAPH+0xE6A9 0x8B96 #CJK UNIFIED IDEOGRAPH+0xE6AA 0x8B99 #CJK UNIFIED IDEOGRAPH+0xE6AB 0x8B9A #CJK UNIFIED IDEOGRAPH+0xE6AC 0x8C3A #CJK UNIFIED IDEOGRAPH+0xE6AD 0x8C41 #CJK UNIFIED IDEOGRAPH+0xE6AE 0x8C3F #CJK UNIFIED IDEOGRAPH+0xE6AF 0x8C48 #CJK UNIFIED IDEOGRAPH+0xE6B0 0x8C4C #CJK UNIFIED IDEOGRAPH+0xE6B1 0x8C4E #CJK UNIFIED IDEOGRAPH+0xE6B2 0x8C50 #CJK UNIFIED IDEOGRAPH+0xE6B3 0x8C55 #CJK UNIFIED IDEOGRAPH+0xE6B4 0x8C62 #CJK UNIFIED IDEOGRAPH+0xE6B5 0x8C6C #CJK UNIFIED IDEOGRAPH+0xE6B6 0x8C78 #CJK UNIFIED IDEOGRAPH+0xE6B7 0x8C7A #CJK UNIFIED IDEOGRAPH+0xE6B8 0x8C82 #CJK UNIFIED IDEOGRAPH+0xE6B9 0x8C89 #CJK UNIFIED IDEOGRAPH+0xE6BA 0x8C85 #CJK UNIFIED IDEOGRAPH+0xE6BB 0x8C8A #CJK UNIFIED IDEOGRAPH+0xE6BC 0x8C8D #CJK UNIFIED IDEOGRAPH+0xE6BD 0x8C8E #CJK UNIFIED IDEOGRAPH+0xE6BE 0x8C94 #CJK UNIFIED IDEOGRAPH+0xE6BF 0x8C7C #CJK UNIFIED IDEOGRAPH+0xE6C0 0x8C98 #CJK UNIFIED IDEOGRAPH+0xE6C1 0x621D #CJK UNIFIED IDEOGRAPH+0xE6C2 0x8CAD #CJK UNIFIED IDEOGRAPH+0xE6C3 0x8CAA #CJK UNIFIED IDEOGRAPH+0xE6C4 0x8CBD #CJK UNIFIED IDEOGRAPH+0xE6C5 0x8CB2 #CJK UNIFIED IDEOGRAPH+0xE6C6 0x8CB3 #CJK UNIFIED IDEOGRAPH+0xE6C7 0x8CAE #CJK UNIFIED IDEOGRAPH+0xE6C8 0x8CB6 #CJK UNIFIED IDEOGRAPH+0xE6C9 0x8CC8 #CJK UNIFIED IDEOGRAPH+0xE6CA 0x8CC1 #CJK UNIFIED IDEOGRAPH+0xE6CB 0x8CE4 #CJK UNIFIED IDEOGRAPH+0xE6CC 0x8CE3 #CJK UNIFIED IDEOGRAPH+0xE6CD 0x8CDA #CJK UNIFIED IDEOGRAPH+0xE6CE 0x8CFD #CJK UNIFIED IDEOGRAPH+0xE6CF 0x8CFA #CJK UNIFIED IDEOGRAPH+0xE6D0 0x8CFB #CJK UNIFIED IDEOGRAPH+0xE6D1 0x8D04 #CJK UNIFIED IDEOGRAPH+0xE6D2 0x8D05 #CJK UNIFIED IDEOGRAPH+0xE6D3 0x8D0A #CJK UNIFIED IDEOGRAPH+0xE6D4 0x8D07 #CJK UNIFIED IDEOGRAPH+0xE6D5 0x8D0F #CJK UNIFIED IDEOGRAPH+0xE6D6 0x8D0D #CJK UNIFIED IDEOGRAPH+0xE6D7 0x8D10 #CJK UNIFIED IDEOGRAPH+0xE6D8 0x9F4E #CJK UNIFIED IDEOGRAPH+0xE6D9 0x8D13 #CJK UNIFIED IDEOGRAPH+0xE6DA 0x8CCD #CJK UNIFIED IDEOGRAPH+0xE6DB 0x8D14 #CJK UNIFIED IDEOGRAPH+0xE6DC 0x8D16 #CJK UNIFIED IDEOGRAPH+0xE6DD 0x8D67 #CJK UNIFIED IDEOGRAPH+0xE6DE 0x8D6D #CJK UNIFIED IDEOGRAPH+0xE6DF 0x8D71 #CJK UNIFIED IDEOGRAPH+0xE6E0 0x8D73 #CJK UNIFIED IDEOGRAPH+0xE6E1 0x8D81 #CJK UNIFIED IDEOGRAPH+0xE6E2 0x8D99 #CJK UNIFIED IDEOGRAPH+0xE6E3 0x8DC2 #CJK UNIFIED IDEOGRAPH+0xE6E4 0x8DBE #CJK UNIFIED IDEOGRAPH+0xE6E5 0x8DBA #CJK UNIFIED IDEOGRAPH+0xE6E6 0x8DCF #CJK UNIFIED IDEOGRAPH+0xE6E7 0x8DDA #CJK UNIFIED IDEOGRAPH+0xE6E8 0x8DD6 #CJK UNIFIED IDEOGRAPH+0xE6E9 0x8DCC #CJK UNIFIED IDEOGRAPH+0xE6EA 0x8DDB #CJK UNIFIED IDEOGRAPH+0xE6EB 0x8DCB #CJK UNIFIED IDEOGRAPH+0xE6EC 0x8DEA #CJK UNIFIED IDEOGRAPH+0xE6ED 0x8DEB #CJK UNIFIED IDEOGRAPH+0xE6EE 0x8DDF #CJK UNIFIED IDEOGRAPH+0xE6EF 0x8DE3 #CJK UNIFIED IDEOGRAPH+0xE6F0 0x8DFC #CJK UNIFIED IDEOGRAPH+0xE6F1 0x8E08 #CJK UNIFIED IDEOGRAPH+0xE6F2 0x8E09 #CJK UNIFIED IDEOGRAPH+0xE6F3 0x8DFF #CJK UNIFIED IDEOGRAPH+0xE6F4 0x8E1D #CJK UNIFIED IDEOGRAPH+0xE6F5 0x8E1E #CJK UNIFIED IDEOGRAPH+0xE6F6 0x8E10 #CJK UNIFIED IDEOGRAPH+0xE6F7 0x8E1F #CJK UNIFIED IDEOGRAPH+0xE6F8 0x8E42 #CJK UNIFIED IDEOGRAPH+0xE6F9 0x8E35 #CJK UNIFIED IDEOGRAPH+0xE6FA 0x8E30 #CJK UNIFIED IDEOGRAPH+0xE6FB 0x8E34 #CJK UNIFIED IDEOGRAPH+0xE6FC 0x8E4A #CJK UNIFIED IDEOGRAPH+0xE740 0x8E47 #CJK UNIFIED IDEOGRAPH+0xE741 0x8E49 #CJK UNIFIED IDEOGRAPH+0xE742 0x8E4C #CJK UNIFIED IDEOGRAPH+0xE743 0x8E50 #CJK UNIFIED IDEOGRAPH+0xE744 0x8E48 #CJK UNIFIED IDEOGRAPH+0xE745 0x8E59 #CJK UNIFIED IDEOGRAPH+0xE746 0x8E64 #CJK UNIFIED IDEOGRAPH+0xE747 0x8E60 #CJK UNIFIED IDEOGRAPH+0xE748 0x8E2A #CJK UNIFIED IDEOGRAPH+0xE749 0x8E63 #CJK UNIFIED IDEOGRAPH+0xE74A 0x8E55 #CJK UNIFIED IDEOGRAPH+0xE74B 0x8E76 #CJK UNIFIED IDEOGRAPH+0xE74C 0x8E72 #CJK UNIFIED IDEOGRAPH+0xE74D 0x8E7C #CJK UNIFIED IDEOGRAPH+0xE74E 0x8E81 #CJK UNIFIED IDEOGRAPH+0xE74F 0x8E87 #CJK UNIFIED IDEOGRAPH+0xE750 0x8E85 #CJK UNIFIED IDEOGRAPH+0xE751 0x8E84 #CJK UNIFIED IDEOGRAPH+0xE752 0x8E8B #CJK UNIFIED IDEOGRAPH+0xE753 0x8E8A #CJK UNIFIED IDEOGRAPH+0xE754 0x8E93 #CJK UNIFIED IDEOGRAPH+0xE755 0x8E91 #CJK UNIFIED IDEOGRAPH+0xE756 0x8E94 #CJK UNIFIED IDEOGRAPH+0xE757 0x8E99 #CJK UNIFIED IDEOGRAPH+0xE758 0x8EAA #CJK UNIFIED IDEOGRAPH+0xE759 0x8EA1 #CJK UNIFIED IDEOGRAPH+0xE75A 0x8EAC #CJK UNIFIED IDEOGRAPH+0xE75B 0x8EB0 #CJK UNIFIED IDEOGRAPH+0xE75C 0x8EC6 #CJK UNIFIED IDEOGRAPH+0xE75D 0x8EB1 #CJK UNIFIED IDEOGRAPH+0xE75E 0x8EBE #CJK UNIFIED IDEOGRAPH+0xE75F 0x8EC5 #CJK UNIFIED IDEOGRAPH+0xE760 0x8EC8 #CJK UNIFIED IDEOGRAPH+0xE761 0x8ECB #CJK UNIFIED IDEOGRAPH+0xE762 0x8EDB #CJK UNIFIED IDEOGRAPH+0xE763 0x8EE3 #CJK UNIFIED IDEOGRAPH+0xE764 0x8EFC #CJK UNIFIED IDEOGRAPH+0xE765 0x8EFB #CJK UNIFIED IDEOGRAPH+0xE766 0x8EEB #CJK UNIFIED IDEOGRAPH+0xE767 0x8EFE #CJK UNIFIED IDEOGRAPH+0xE768 0x8F0A #CJK UNIFIED IDEOGRAPH+0xE769 0x8F05 #CJK UNIFIED IDEOGRAPH+0xE76A 0x8F15 #CJK UNIFIED IDEOGRAPH+0xE76B 0x8F12 #CJK UNIFIED IDEOGRAPH+0xE76C 0x8F19 #CJK UNIFIED IDEOGRAPH+0xE76D 0x8F13 #CJK UNIFIED IDEOGRAPH+0xE76E 0x8F1C #CJK UNIFIED IDEOGRAPH+0xE76F 0x8F1F #CJK UNIFIED IDEOGRAPH+0xE770 0x8F1B #CJK UNIFIED IDEOGRAPH+0xE771 0x8F0C #CJK UNIFIED IDEOGRAPH+0xE772 0x8F26 #CJK UNIFIED IDEOGRAPH+0xE773 0x8F33 #CJK UNIFIED IDEOGRAPH+0xE774 0x8F3B #CJK UNIFIED IDEOGRAPH+0xE775 0x8F39 #CJK UNIFIED IDEOGRAPH+0xE776 0x8F45 #CJK UNIFIED IDEOGRAPH+0xE777 0x8F42 #CJK UNIFIED IDEOGRAPH+0xE778 0x8F3E #CJK UNIFIED IDEOGRAPH+0xE779 0x8F4C #CJK UNIFIED IDEOGRAPH+0xE77A 0x8F49 #CJK UNIFIED IDEOGRAPH+0xE77B 0x8F46 #CJK UNIFIED IDEOGRAPH+0xE77C 0x8F4E #CJK UNIFIED IDEOGRAPH+0xE77D 0x8F57 #CJK UNIFIED IDEOGRAPH+0xE77E 0x8F5C #CJK UNIFIED IDEOGRAPH+0xE780 0x8F62 #CJK UNIFIED IDEOGRAPH+0xE781 0x8F63 #CJK UNIFIED IDEOGRAPH+0xE782 0x8F64 #CJK UNIFIED IDEOGRAPH+0xE783 0x8F9C #CJK UNIFIED IDEOGRAPH+0xE784 0x8F9F #CJK UNIFIED IDEOGRAPH+0xE785 0x8FA3 #CJK UNIFIED IDEOGRAPH+0xE786 0x8FAD #CJK UNIFIED IDEOGRAPH+0xE787 0x8FAF #CJK UNIFIED IDEOGRAPH+0xE788 0x8FB7 #CJK UNIFIED IDEOGRAPH+0xE789 0x8FDA #CJK UNIFIED IDEOGRAPH+0xE78A 0x8FE5 #CJK UNIFIED IDEOGRAPH+0xE78B 0x8FE2 #CJK UNIFIED IDEOGRAPH+0xE78C 0x8FEA #CJK UNIFIED IDEOGRAPH+0xE78D 0x8FEF #CJK UNIFIED IDEOGRAPH+0xE78E 0x9087 #CJK UNIFIED IDEOGRAPH+0xE78F 0x8FF4 #CJK UNIFIED IDEOGRAPH+0xE790 0x9005 #CJK UNIFIED IDEOGRAPH+0xE791 0x8FF9 #CJK UNIFIED IDEOGRAPH+0xE792 0x8FFA #CJK UNIFIED IDEOGRAPH+0xE793 0x9011 #CJK UNIFIED IDEOGRAPH+0xE794 0x9015 #CJK UNIFIED IDEOGRAPH+0xE795 0x9021 #CJK UNIFIED IDEOGRAPH+0xE796 0x900D #CJK UNIFIED IDEOGRAPH+0xE797 0x901E #CJK UNIFIED IDEOGRAPH+0xE798 0x9016 #CJK UNIFIED IDEOGRAPH+0xE799 0x900B #CJK UNIFIED IDEOGRAPH+0xE79A 0x9027 #CJK UNIFIED IDEOGRAPH+0xE79B 0x9036 #CJK UNIFIED IDEOGRAPH+0xE79C 0x9035 #CJK UNIFIED IDEOGRAPH+0xE79D 0x9039 #CJK UNIFIED IDEOGRAPH+0xE79E 0x8FF8 #CJK UNIFIED IDEOGRAPH+0xE79F 0x904F #CJK UNIFIED IDEOGRAPH+0xE7A0 0x9050 #CJK UNIFIED IDEOGRAPH+0xE7A1 0x9051 #CJK UNIFIED IDEOGRAPH+0xE7A2 0x9052 #CJK UNIFIED IDEOGRAPH+0xE7A3 0x900E #CJK UNIFIED IDEOGRAPH+0xE7A4 0x9049 #CJK UNIFIED IDEOGRAPH+0xE7A5 0x903E #CJK UNIFIED IDEOGRAPH+0xE7A6 0x9056 #CJK UNIFIED IDEOGRAPH+0xE7A7 0x9058 #CJK UNIFIED IDEOGRAPH+0xE7A8 0x905E #CJK UNIFIED IDEOGRAPH+0xE7A9 0x9068 #CJK UNIFIED IDEOGRAPH+0xE7AA 0x906F #CJK UNIFIED IDEOGRAPH+0xE7AB 0x9076 #CJK UNIFIED IDEOGRAPH+0xE7AC 0x96A8 #CJK UNIFIED IDEOGRAPH+0xE7AD 0x9072 #CJK UNIFIED IDEOGRAPH+0xE7AE 0x9082 #CJK UNIFIED IDEOGRAPH+0xE7AF 0x907D #CJK UNIFIED IDEOGRAPH+0xE7B0 0x9081 #CJK UNIFIED IDEOGRAPH+0xE7B1 0x9080 #CJK UNIFIED IDEOGRAPH+0xE7B2 0x908A #CJK UNIFIED IDEOGRAPH+0xE7B3 0x9089 #CJK UNIFIED IDEOGRAPH+0xE7B4 0x908F #CJK UNIFIED IDEOGRAPH+0xE7B5 0x90A8 #CJK UNIFIED IDEOGRAPH+0xE7B6 0x90AF #CJK UNIFIED IDEOGRAPH+0xE7B7 0x90B1 #CJK UNIFIED IDEOGRAPH+0xE7B8 0x90B5 #CJK UNIFIED IDEOGRAPH+0xE7B9 0x90E2 #CJK UNIFIED IDEOGRAPH+0xE7BA 0x90E4 #CJK UNIFIED IDEOGRAPH+0xE7BB 0x6248 #CJK UNIFIED IDEOGRAPH+0xE7BC 0x90DB #CJK UNIFIED IDEOGRAPH+0xE7BD 0x9102 #CJK UNIFIED IDEOGRAPH+0xE7BE 0x9112 #CJK UNIFIED IDEOGRAPH+0xE7BF 0x9119 #CJK UNIFIED IDEOGRAPH+0xE7C0 0x9132 #CJK UNIFIED IDEOGRAPH+0xE7C1 0x9130 #CJK UNIFIED IDEOGRAPH+0xE7C2 0x914A #CJK UNIFIED IDEOGRAPH+0xE7C3 0x9156 #CJK UNIFIED IDEOGRAPH+0xE7C4 0x9158 #CJK UNIFIED IDEOGRAPH+0xE7C5 0x9163 #CJK UNIFIED IDEOGRAPH+0xE7C6 0x9165 #CJK UNIFIED IDEOGRAPH+0xE7C7 0x9169 #CJK UNIFIED IDEOGRAPH+0xE7C8 0x9173 #CJK UNIFIED IDEOGRAPH+0xE7C9 0x9172 #CJK UNIFIED IDEOGRAPH+0xE7CA 0x918B #CJK UNIFIED IDEOGRAPH+0xE7CB 0x9189 #CJK UNIFIED IDEOGRAPH+0xE7CC 0x9182 #CJK UNIFIED IDEOGRAPH+0xE7CD 0x91A2 #CJK UNIFIED IDEOGRAPH+0xE7CE 0x91AB #CJK UNIFIED IDEOGRAPH+0xE7CF 0x91AF #CJK UNIFIED IDEOGRAPH+0xE7D0 0x91AA #CJK UNIFIED IDEOGRAPH+0xE7D1 0x91B5 #CJK UNIFIED IDEOGRAPH+0xE7D2 0x91B4 #CJK UNIFIED IDEOGRAPH+0xE7D3 0x91BA #CJK UNIFIED IDEOGRAPH+0xE7D4 0x91C0 #CJK UNIFIED IDEOGRAPH+0xE7D5 0x91C1 #CJK UNIFIED IDEOGRAPH+0xE7D6 0x91C9 #CJK UNIFIED IDEOGRAPH+0xE7D7 0x91CB #CJK UNIFIED IDEOGRAPH+0xE7D8 0x91D0 #CJK UNIFIED IDEOGRAPH+0xE7D9 0x91D6 #CJK UNIFIED IDEOGRAPH+0xE7DA 0x91DF #CJK UNIFIED IDEOGRAPH+0xE7DB 0x91E1 #CJK UNIFIED IDEOGRAPH+0xE7DC 0x91DB #CJK UNIFIED IDEOGRAPH+0xE7DD 0x91FC #CJK UNIFIED IDEOGRAPH+0xE7DE 0x91F5 #CJK UNIFIED IDEOGRAPH+0xE7DF 0x91F6 #CJK UNIFIED IDEOGRAPH+0xE7E0 0x921E #CJK UNIFIED IDEOGRAPH+0xE7E1 0x91FF #CJK UNIFIED IDEOGRAPH+0xE7E2 0x9214 #CJK UNIFIED IDEOGRAPH+0xE7E3 0x922C #CJK UNIFIED IDEOGRAPH+0xE7E4 0x9215 #CJK UNIFIED IDEOGRAPH+0xE7E5 0x9211 #CJK UNIFIED IDEOGRAPH+0xE7E6 0x925E #CJK UNIFIED IDEOGRAPH+0xE7E7 0x9257 #CJK UNIFIED IDEOGRAPH+0xE7E8 0x9245 #CJK UNIFIED IDEOGRAPH+0xE7E9 0x9249 #CJK UNIFIED IDEOGRAPH+0xE7EA 0x9264 #CJK UNIFIED IDEOGRAPH+0xE7EB 0x9248 #CJK UNIFIED IDEOGRAPH+0xE7EC 0x9295 #CJK UNIFIED IDEOGRAPH+0xE7ED 0x923F #CJK UNIFIED IDEOGRAPH+0xE7EE 0x924B #CJK UNIFIED IDEOGRAPH+0xE7EF 0x9250 #CJK UNIFIED IDEOGRAPH+0xE7F0 0x929C #CJK UNIFIED IDEOGRAPH+0xE7F1 0x9296 #CJK UNIFIED IDEOGRAPH+0xE7F2 0x9293 #CJK UNIFIED IDEOGRAPH+0xE7F3 0x929B #CJK UNIFIED IDEOGRAPH+0xE7F4 0x925A #CJK UNIFIED IDEOGRAPH+0xE7F5 0x92CF #CJK UNIFIED IDEOGRAPH+0xE7F6 0x92B9 #CJK UNIFIED IDEOGRAPH+0xE7F7 0x92B7 #CJK UNIFIED IDEOGRAPH+0xE7F8 0x92E9 #CJK UNIFIED IDEOGRAPH+0xE7F9 0x930F #CJK UNIFIED IDEOGRAPH+0xE7FA 0x92FA #CJK UNIFIED IDEOGRAPH+0xE7FB 0x9344 #CJK UNIFIED IDEOGRAPH+0xE7FC 0x932E #CJK UNIFIED IDEOGRAPH+0xE840 0x9319 #CJK UNIFIED IDEOGRAPH+0xE841 0x9322 #CJK UNIFIED IDEOGRAPH+0xE842 0x931A #CJK UNIFIED IDEOGRAPH+0xE843 0x9323 #CJK UNIFIED IDEOGRAPH+0xE844 0x933A #CJK UNIFIED IDEOGRAPH+0xE845 0x9335 #CJK UNIFIED IDEOGRAPH+0xE846 0x933B #CJK UNIFIED IDEOGRAPH+0xE847 0x935C #CJK UNIFIED IDEOGRAPH+0xE848 0x9360 #CJK UNIFIED IDEOGRAPH+0xE849 0x937C #CJK UNIFIED IDEOGRAPH+0xE84A 0x936E #CJK UNIFIED IDEOGRAPH+0xE84B 0x9356 #CJK UNIFIED IDEOGRAPH+0xE84C 0x93B0 #CJK UNIFIED IDEOGRAPH+0xE84D 0x93AC #CJK UNIFIED IDEOGRAPH+0xE84E 0x93AD #CJK UNIFIED IDEOGRAPH+0xE84F 0x9394 #CJK UNIFIED IDEOGRAPH+0xE850 0x93B9 #CJK UNIFIED IDEOGRAPH+0xE851 0x93D6 #CJK UNIFIED IDEOGRAPH+0xE852 0x93D7 #CJK UNIFIED IDEOGRAPH+0xE853 0x93E8 #CJK UNIFIED IDEOGRAPH+0xE854 0x93E5 #CJK UNIFIED IDEOGRAPH+0xE855 0x93D8 #CJK UNIFIED IDEOGRAPH+0xE856 0x93C3 #CJK UNIFIED IDEOGRAPH+0xE857 0x93DD #CJK UNIFIED IDEOGRAPH+0xE858 0x93D0 #CJK UNIFIED IDEOGRAPH+0xE859 0x93C8 #CJK UNIFIED IDEOGRAPH+0xE85A 0x93E4 #CJK UNIFIED IDEOGRAPH+0xE85B 0x941A #CJK UNIFIED IDEOGRAPH+0xE85C 0x9414 #CJK UNIFIED IDEOGRAPH+0xE85D 0x9413 #CJK UNIFIED IDEOGRAPH+0xE85E 0x9403 #CJK UNIFIED IDEOGRAPH+0xE85F 0x9407 #CJK UNIFIED IDEOGRAPH+0xE860 0x9410 #CJK UNIFIED IDEOGRAPH+0xE861 0x9436 #CJK UNIFIED IDEOGRAPH+0xE862 0x942B #CJK UNIFIED IDEOGRAPH+0xE863 0x9435 #CJK UNIFIED IDEOGRAPH+0xE864 0x9421 #CJK UNIFIED IDEOGRAPH+0xE865 0x943A #CJK UNIFIED IDEOGRAPH+0xE866 0x9441 #CJK UNIFIED IDEOGRAPH+0xE867 0x9452 #CJK UNIFIED IDEOGRAPH+0xE868 0x9444 #CJK UNIFIED IDEOGRAPH+0xE869 0x945B #CJK UNIFIED IDEOGRAPH+0xE86A 0x9460 #CJK UNIFIED IDEOGRAPH+0xE86B 0x9462 #CJK UNIFIED IDEOGRAPH+0xE86C 0x945E #CJK UNIFIED IDEOGRAPH+0xE86D 0x946A #CJK UNIFIED IDEOGRAPH+0xE86E 0x9229 #CJK UNIFIED IDEOGRAPH+0xE86F 0x9470 #CJK UNIFIED IDEOGRAPH+0xE870 0x9475 #CJK UNIFIED IDEOGRAPH+0xE871 0x9477 #CJK UNIFIED IDEOGRAPH+0xE872 0x947D #CJK UNIFIED IDEOGRAPH+0xE873 0x945A #CJK UNIFIED IDEOGRAPH+0xE874 0x947C #CJK UNIFIED IDEOGRAPH+0xE875 0x947E #CJK UNIFIED IDEOGRAPH+0xE876 0x9481 #CJK UNIFIED IDEOGRAPH+0xE877 0x947F #CJK UNIFIED IDEOGRAPH+0xE878 0x9582 #CJK UNIFIED IDEOGRAPH+0xE879 0x9587 #CJK UNIFIED IDEOGRAPH+0xE87A 0x958A #CJK UNIFIED IDEOGRAPH+0xE87B 0x9594 #CJK UNIFIED IDEOGRAPH+0xE87C 0x9596 #CJK UNIFIED IDEOGRAPH+0xE87D 0x9598 #CJK UNIFIED IDEOGRAPH+0xE87E 0x9599 #CJK UNIFIED IDEOGRAPH+0xE880 0x95A0 #CJK UNIFIED IDEOGRAPH+0xE881 0x95A8 #CJK UNIFIED IDEOGRAPH+0xE882 0x95A7 #CJK UNIFIED IDEOGRAPH+0xE883 0x95AD #CJK UNIFIED IDEOGRAPH+0xE884 0x95BC #CJK UNIFIED IDEOGRAPH+0xE885 0x95BB #CJK UNIFIED IDEOGRAPH+0xE886 0x95B9 #CJK UNIFIED IDEOGRAPH+0xE887 0x95BE #CJK UNIFIED IDEOGRAPH+0xE888 0x95CA #CJK UNIFIED IDEOGRAPH+0xE889 0x6FF6 #CJK UNIFIED IDEOGRAPH+0xE88A 0x95C3 #CJK UNIFIED IDEOGRAPH+0xE88B 0x95CD #CJK UNIFIED IDEOGRAPH+0xE88C 0x95CC #CJK UNIFIED IDEOGRAPH+0xE88D 0x95D5 #CJK UNIFIED IDEOGRAPH+0xE88E 0x95D4 #CJK UNIFIED IDEOGRAPH+0xE88F 0x95D6 #CJK UNIFIED IDEOGRAPH+0xE890 0x95DC #CJK UNIFIED IDEOGRAPH+0xE891 0x95E1 #CJK UNIFIED IDEOGRAPH+0xE892 0x95E5 #CJK UNIFIED IDEOGRAPH+0xE893 0x95E2 #CJK UNIFIED IDEOGRAPH+0xE894 0x9621 #CJK UNIFIED IDEOGRAPH+0xE895 0x9628 #CJK UNIFIED IDEOGRAPH+0xE896 0x962E #CJK UNIFIED IDEOGRAPH+0xE897 0x962F #CJK UNIFIED IDEOGRAPH+0xE898 0x9642 #CJK UNIFIED IDEOGRAPH+0xE899 0x964C #CJK UNIFIED IDEOGRAPH+0xE89A 0x964F #CJK UNIFIED IDEOGRAPH+0xE89B 0x964B #CJK UNIFIED IDEOGRAPH+0xE89C 0x9677 #CJK UNIFIED IDEOGRAPH+0xE89D 0x965C #CJK UNIFIED IDEOGRAPH+0xE89E 0x965E #CJK UNIFIED IDEOGRAPH+0xE89F 0x965D #CJK UNIFIED IDEOGRAPH+0xE8A0 0x965F #CJK UNIFIED IDEOGRAPH+0xE8A1 0x9666 #CJK UNIFIED IDEOGRAPH+0xE8A2 0x9672 #CJK UNIFIED IDEOGRAPH+0xE8A3 0x966C #CJK UNIFIED IDEOGRAPH+0xE8A4 0x968D #CJK UNIFIED IDEOGRAPH+0xE8A5 0x9698 #CJK UNIFIED IDEOGRAPH+0xE8A6 0x9695 #CJK UNIFIED IDEOGRAPH+0xE8A7 0x9697 #CJK UNIFIED IDEOGRAPH+0xE8A8 0x96AA #CJK UNIFIED IDEOGRAPH+0xE8A9 0x96A7 #CJK UNIFIED IDEOGRAPH+0xE8AA 0x96B1 #CJK UNIFIED IDEOGRAPH+0xE8AB 0x96B2 #CJK UNIFIED IDEOGRAPH+0xE8AC 0x96B0 #CJK UNIFIED IDEOGRAPH+0xE8AD 0x96B4 #CJK UNIFIED IDEOGRAPH+0xE8AE 0x96B6 #CJK UNIFIED IDEOGRAPH+0xE8AF 0x96B8 #CJK UNIFIED IDEOGRAPH+0xE8B0 0x96B9 #CJK UNIFIED IDEOGRAPH+0xE8B1 0x96CE #CJK UNIFIED IDEOGRAPH+0xE8B2 0x96CB #CJK UNIFIED IDEOGRAPH+0xE8B3 0x96C9 #CJK UNIFIED IDEOGRAPH+0xE8B4 0x96CD #CJK UNIFIED IDEOGRAPH+0xE8B5 0x894D #CJK UNIFIED IDEOGRAPH+0xE8B6 0x96DC #CJK UNIFIED IDEOGRAPH+0xE8B7 0x970D #CJK UNIFIED IDEOGRAPH+0xE8B8 0x96D5 #CJK UNIFIED IDEOGRAPH+0xE8B9 0x96F9 #CJK UNIFIED IDEOGRAPH+0xE8BA 0x9704 #CJK UNIFIED IDEOGRAPH+0xE8BB 0x9706 #CJK UNIFIED IDEOGRAPH+0xE8BC 0x9708 #CJK UNIFIED IDEOGRAPH+0xE8BD 0x9713 #CJK UNIFIED IDEOGRAPH+0xE8BE 0x970E #CJK UNIFIED IDEOGRAPH+0xE8BF 0x9711 #CJK UNIFIED IDEOGRAPH+0xE8C0 0x970F #CJK UNIFIED IDEOGRAPH+0xE8C1 0x9716 #CJK UNIFIED IDEOGRAPH+0xE8C2 0x9719 #CJK UNIFIED IDEOGRAPH+0xE8C3 0x9724 #CJK UNIFIED IDEOGRAPH+0xE8C4 0x972A #CJK UNIFIED IDEOGRAPH+0xE8C5 0x9730 #CJK UNIFIED IDEOGRAPH+0xE8C6 0x9739 #CJK UNIFIED IDEOGRAPH+0xE8C7 0x973D #CJK UNIFIED IDEOGRAPH+0xE8C8 0x973E #CJK UNIFIED IDEOGRAPH+0xE8C9 0x9744 #CJK UNIFIED IDEOGRAPH+0xE8CA 0x9746 #CJK UNIFIED IDEOGRAPH+0xE8CB 0x9748 #CJK UNIFIED IDEOGRAPH+0xE8CC 0x9742 #CJK UNIFIED IDEOGRAPH+0xE8CD 0x9749 #CJK UNIFIED IDEOGRAPH+0xE8CE 0x975C #CJK UNIFIED IDEOGRAPH+0xE8CF 0x9760 #CJK UNIFIED IDEOGRAPH+0xE8D0 0x9764 #CJK UNIFIED IDEOGRAPH+0xE8D1 0x9766 #CJK UNIFIED IDEOGRAPH+0xE8D2 0x9768 #CJK UNIFIED IDEOGRAPH+0xE8D3 0x52D2 #CJK UNIFIED IDEOGRAPH+0xE8D4 0x976B #CJK UNIFIED IDEOGRAPH+0xE8D5 0x9771 #CJK UNIFIED IDEOGRAPH+0xE8D6 0x9779 #CJK UNIFIED IDEOGRAPH+0xE8D7 0x9785 #CJK UNIFIED IDEOGRAPH+0xE8D8 0x977C #CJK UNIFIED IDEOGRAPH+0xE8D9 0x9781 #CJK UNIFIED IDEOGRAPH+0xE8DA 0x977A #CJK UNIFIED IDEOGRAPH+0xE8DB 0x9786 #CJK UNIFIED IDEOGRAPH+0xE8DC 0x978B #CJK UNIFIED IDEOGRAPH+0xE8DD 0x978F #CJK UNIFIED IDEOGRAPH+0xE8DE 0x9790 #CJK UNIFIED IDEOGRAPH+0xE8DF 0x979C #CJK UNIFIED IDEOGRAPH+0xE8E0 0x97A8 #CJK UNIFIED IDEOGRAPH+0xE8E1 0x97A6 #CJK UNIFIED IDEOGRAPH+0xE8E2 0x97A3 #CJK UNIFIED IDEOGRAPH+0xE8E3 0x97B3 #CJK UNIFIED IDEOGRAPH+0xE8E4 0x97B4 #CJK UNIFIED IDEOGRAPH+0xE8E5 0x97C3 #CJK UNIFIED IDEOGRAPH+0xE8E6 0x97C6 #CJK UNIFIED IDEOGRAPH+0xE8E7 0x97C8 #CJK UNIFIED IDEOGRAPH+0xE8E8 0x97CB #CJK UNIFIED IDEOGRAPH+0xE8E9 0x97DC #CJK UNIFIED IDEOGRAPH+0xE8EA 0x97ED #CJK UNIFIED IDEOGRAPH+0xE8EB 0x9F4F #CJK UNIFIED IDEOGRAPH+0xE8EC 0x97F2 #CJK UNIFIED IDEOGRAPH+0xE8ED 0x7ADF #CJK UNIFIED IDEOGRAPH+0xE8EE 0x97F6 #CJK UNIFIED IDEOGRAPH+0xE8EF 0x97F5 #CJK UNIFIED IDEOGRAPH+0xE8F0 0x980F #CJK UNIFIED IDEOGRAPH+0xE8F1 0x980C #CJK UNIFIED IDEOGRAPH+0xE8F2 0x9838 #CJK UNIFIED IDEOGRAPH+0xE8F3 0x9824 #CJK UNIFIED IDEOGRAPH+0xE8F4 0x9821 #CJK UNIFIED IDEOGRAPH+0xE8F5 0x9837 #CJK UNIFIED IDEOGRAPH+0xE8F6 0x983D #CJK UNIFIED IDEOGRAPH+0xE8F7 0x9846 #CJK UNIFIED IDEOGRAPH+0xE8F8 0x984F #CJK UNIFIED IDEOGRAPH+0xE8F9 0x984B #CJK UNIFIED IDEOGRAPH+0xE8FA 0x986B #CJK UNIFIED IDEOGRAPH+0xE8FB 0x986F #CJK UNIFIED IDEOGRAPH+0xE8FC 0x9870 #CJK UNIFIED IDEOGRAPH+0xE940 0x9871 #CJK UNIFIED IDEOGRAPH+0xE941 0x9874 #CJK UNIFIED IDEOGRAPH+0xE942 0x9873 #CJK UNIFIED IDEOGRAPH+0xE943 0x98AA #CJK UNIFIED IDEOGRAPH+0xE944 0x98AF #CJK UNIFIED IDEOGRAPH+0xE945 0x98B1 #CJK UNIFIED IDEOGRAPH+0xE946 0x98B6 #CJK UNIFIED IDEOGRAPH+0xE947 0x98C4 #CJK UNIFIED IDEOGRAPH+0xE948 0x98C3 #CJK UNIFIED IDEOGRAPH+0xE949 0x98C6 #CJK UNIFIED IDEOGRAPH+0xE94A 0x98E9 #CJK UNIFIED IDEOGRAPH+0xE94B 0x98EB #CJK UNIFIED IDEOGRAPH+0xE94C 0x9903 #CJK UNIFIED IDEOGRAPH+0xE94D 0x9909 #CJK UNIFIED IDEOGRAPH+0xE94E 0x9912 #CJK UNIFIED IDEOGRAPH+0xE94F 0x9914 #CJK UNIFIED IDEOGRAPH+0xE950 0x9918 #CJK UNIFIED IDEOGRAPH+0xE951 0x9921 #CJK UNIFIED IDEOGRAPH+0xE952 0x991D #CJK UNIFIED IDEOGRAPH+0xE953 0x991E #CJK UNIFIED IDEOGRAPH+0xE954 0x9924 #CJK UNIFIED IDEOGRAPH+0xE955 0x9920 #CJK UNIFIED IDEOGRAPH+0xE956 0x992C #CJK UNIFIED IDEOGRAPH+0xE957 0x992E #CJK UNIFIED IDEOGRAPH+0xE958 0x993D #CJK UNIFIED IDEOGRAPH+0xE959 0x993E #CJK UNIFIED IDEOGRAPH+0xE95A 0x9942 #CJK UNIFIED IDEOGRAPH+0xE95B 0x9949 #CJK UNIFIED IDEOGRAPH+0xE95C 0x9945 #CJK UNIFIED IDEOGRAPH+0xE95D 0x9950 #CJK UNIFIED IDEOGRAPH+0xE95E 0x994B #CJK UNIFIED IDEOGRAPH+0xE95F 0x9951 #CJK UNIFIED IDEOGRAPH+0xE960 0x9952 #CJK UNIFIED IDEOGRAPH+0xE961 0x994C #CJK UNIFIED IDEOGRAPH+0xE962 0x9955 #CJK UNIFIED IDEOGRAPH+0xE963 0x9997 #CJK UNIFIED IDEOGRAPH+0xE964 0x9998 #CJK UNIFIED IDEOGRAPH+0xE965 0x99A5 #CJK UNIFIED IDEOGRAPH+0xE966 0x99AD #CJK UNIFIED IDEOGRAPH+0xE967 0x99AE #CJK UNIFIED IDEOGRAPH+0xE968 0x99BC #CJK UNIFIED IDEOGRAPH+0xE969 0x99DF #CJK UNIFIED IDEOGRAPH+0xE96A 0x99DB #CJK UNIFIED IDEOGRAPH+0xE96B 0x99DD #CJK UNIFIED IDEOGRAPH+0xE96C 0x99D8 #CJK UNIFIED IDEOGRAPH+0xE96D 0x99D1 #CJK UNIFIED IDEOGRAPH+0xE96E 0x99ED #CJK UNIFIED IDEOGRAPH+0xE96F 0x99EE #CJK UNIFIED IDEOGRAPH+0xE970 0x99F1 #CJK UNIFIED IDEOGRAPH+0xE971 0x99F2 #CJK UNIFIED IDEOGRAPH+0xE972 0x99FB #CJK UNIFIED IDEOGRAPH+0xE973 0x99F8 #CJK UNIFIED IDEOGRAPH+0xE974 0x9A01 #CJK UNIFIED IDEOGRAPH+0xE975 0x9A0F #CJK UNIFIED IDEOGRAPH+0xE976 0x9A05 #CJK UNIFIED IDEOGRAPH+0xE977 0x99E2 #CJK UNIFIED IDEOGRAPH+0xE978 0x9A19 #CJK UNIFIED IDEOGRAPH+0xE979 0x9A2B #CJK UNIFIED IDEOGRAPH+0xE97A 0x9A37 #CJK UNIFIED IDEOGRAPH+0xE97B 0x9A45 #CJK UNIFIED IDEOGRAPH+0xE97C 0x9A42 #CJK UNIFIED IDEOGRAPH+0xE97D 0x9A40 #CJK UNIFIED IDEOGRAPH+0xE97E 0x9A43 #CJK UNIFIED IDEOGRAPH+0xE980 0x9A3E #CJK UNIFIED IDEOGRAPH+0xE981 0x9A55 #CJK UNIFIED IDEOGRAPH+0xE982 0x9A4D #CJK UNIFIED IDEOGRAPH+0xE983 0x9A5B #CJK UNIFIED IDEOGRAPH+0xE984 0x9A57 #CJK UNIFIED IDEOGRAPH+0xE985 0x9A5F #CJK UNIFIED IDEOGRAPH+0xE986 0x9A62 #CJK UNIFIED IDEOGRAPH+0xE987 0x9A65 #CJK UNIFIED IDEOGRAPH+0xE988 0x9A64 #CJK UNIFIED IDEOGRAPH+0xE989 0x9A69 #CJK UNIFIED IDEOGRAPH+0xE98A 0x9A6B #CJK UNIFIED IDEOGRAPH+0xE98B 0x9A6A #CJK UNIFIED IDEOGRAPH+0xE98C 0x9AAD #CJK UNIFIED IDEOGRAPH+0xE98D 0x9AB0 #CJK UNIFIED IDEOGRAPH+0xE98E 0x9ABC #CJK UNIFIED IDEOGRAPH+0xE98F 0x9AC0 #CJK UNIFIED IDEOGRAPH+0xE990 0x9ACF #CJK UNIFIED IDEOGRAPH+0xE991 0x9AD1 #CJK UNIFIED IDEOGRAPH+0xE992 0x9AD3 #CJK UNIFIED IDEOGRAPH+0xE993 0x9AD4 #CJK UNIFIED IDEOGRAPH+0xE994 0x9ADE #CJK UNIFIED IDEOGRAPH+0xE995 0x9ADF #CJK UNIFIED IDEOGRAPH+0xE996 0x9AE2 #CJK UNIFIED IDEOGRAPH+0xE997 0x9AE3 #CJK UNIFIED IDEOGRAPH+0xE998 0x9AE6 #CJK UNIFIED IDEOGRAPH+0xE999 0x9AEF #CJK UNIFIED IDEOGRAPH+0xE99A 0x9AEB #CJK UNIFIED IDEOGRAPH+0xE99B 0x9AEE #CJK UNIFIED IDEOGRAPH+0xE99C 0x9AF4 #CJK UNIFIED IDEOGRAPH+0xE99D 0x9AF1 #CJK UNIFIED IDEOGRAPH+0xE99E 0x9AF7 #CJK UNIFIED IDEOGRAPH+0xE99F 0x9AFB #CJK UNIFIED IDEOGRAPH+0xE9A0 0x9B06 #CJK UNIFIED IDEOGRAPH+0xE9A1 0x9B18 #CJK UNIFIED IDEOGRAPH+0xE9A2 0x9B1A #CJK UNIFIED IDEOGRAPH+0xE9A3 0x9B1F #CJK UNIFIED IDEOGRAPH+0xE9A4 0x9B22 #CJK UNIFIED IDEOGRAPH+0xE9A5 0x9B23 #CJK UNIFIED IDEOGRAPH+0xE9A6 0x9B25 #CJK UNIFIED IDEOGRAPH+0xE9A7 0x9B27 #CJK UNIFIED IDEOGRAPH+0xE9A8 0x9B28 #CJK UNIFIED IDEOGRAPH+0xE9A9 0x9B29 #CJK UNIFIED IDEOGRAPH+0xE9AA 0x9B2A #CJK UNIFIED IDEOGRAPH+0xE9AB 0x9B2E #CJK UNIFIED IDEOGRAPH+0xE9AC 0x9B2F #CJK UNIFIED IDEOGRAPH+0xE9AD 0x9B32 #CJK UNIFIED IDEOGRAPH+0xE9AE 0x9B44 #CJK UNIFIED IDEOGRAPH+0xE9AF 0x9B43 #CJK UNIFIED IDEOGRAPH+0xE9B0 0x9B4F #CJK UNIFIED IDEOGRAPH+0xE9B1 0x9B4D #CJK UNIFIED IDEOGRAPH+0xE9B2 0x9B4E #CJK UNIFIED IDEOGRAPH+0xE9B3 0x9B51 #CJK UNIFIED IDEOGRAPH+0xE9B4 0x9B58 #CJK UNIFIED IDEOGRAPH+0xE9B5 0x9B74 #CJK UNIFIED IDEOGRAPH+0xE9B6 0x9B93 #CJK UNIFIED IDEOGRAPH+0xE9B7 0x9B83 #CJK UNIFIED IDEOGRAPH+0xE9B8 0x9B91 #CJK UNIFIED IDEOGRAPH+0xE9B9 0x9B96 #CJK UNIFIED IDEOGRAPH+0xE9BA 0x9B97 #CJK UNIFIED IDEOGRAPH+0xE9BB 0x9B9F #CJK UNIFIED IDEOGRAPH+0xE9BC 0x9BA0 #CJK UNIFIED IDEOGRAPH+0xE9BD 0x9BA8 #CJK UNIFIED IDEOGRAPH+0xE9BE 0x9BB4 #CJK UNIFIED IDEOGRAPH+0xE9BF 0x9BC0 #CJK UNIFIED IDEOGRAPH+0xE9C0 0x9BCA #CJK UNIFIED IDEOGRAPH+0xE9C1 0x9BB9 #CJK UNIFIED IDEOGRAPH+0xE9C2 0x9BC6 #CJK UNIFIED IDEOGRAPH+0xE9C3 0x9BCF #CJK UNIFIED IDEOGRAPH+0xE9C4 0x9BD1 #CJK UNIFIED IDEOGRAPH+0xE9C5 0x9BD2 #CJK UNIFIED IDEOGRAPH+0xE9C6 0x9BE3 #CJK UNIFIED IDEOGRAPH+0xE9C7 0x9BE2 #CJK UNIFIED IDEOGRAPH+0xE9C8 0x9BE4 #CJK UNIFIED IDEOGRAPH+0xE9C9 0x9BD4 #CJK UNIFIED IDEOGRAPH+0xE9CA 0x9BE1 #CJK UNIFIED IDEOGRAPH+0xE9CB 0x9C3A #CJK UNIFIED IDEOGRAPH+0xE9CC 0x9BF2 #CJK UNIFIED IDEOGRAPH+0xE9CD 0x9BF1 #CJK UNIFIED IDEOGRAPH+0xE9CE 0x9BF0 #CJK UNIFIED IDEOGRAPH+0xE9CF 0x9C15 #CJK UNIFIED IDEOGRAPH+0xE9D0 0x9C14 #CJK UNIFIED IDEOGRAPH+0xE9D1 0x9C09 #CJK UNIFIED IDEOGRAPH+0xE9D2 0x9C13 #CJK UNIFIED IDEOGRAPH+0xE9D3 0x9C0C #CJK UNIFIED IDEOGRAPH+0xE9D4 0x9C06 #CJK UNIFIED IDEOGRAPH+0xE9D5 0x9C08 #CJK UNIFIED IDEOGRAPH+0xE9D6 0x9C12 #CJK UNIFIED IDEOGRAPH+0xE9D7 0x9C0A #CJK UNIFIED IDEOGRAPH+0xE9D8 0x9C04 #CJK UNIFIED IDEOGRAPH+0xE9D9 0x9C2E #CJK UNIFIED IDEOGRAPH+0xE9DA 0x9C1B #CJK UNIFIED IDEOGRAPH+0xE9DB 0x9C25 #CJK UNIFIED IDEOGRAPH+0xE9DC 0x9C24 #CJK UNIFIED IDEOGRAPH+0xE9DD 0x9C21 #CJK UNIFIED IDEOGRAPH+0xE9DE 0x9C30 #CJK UNIFIED IDEOGRAPH+0xE9DF 0x9C47 #CJK UNIFIED IDEOGRAPH+0xE9E0 0x9C32 #CJK UNIFIED IDEOGRAPH+0xE9E1 0x9C46 #CJK UNIFIED IDEOGRAPH+0xE9E2 0x9C3E #CJK UNIFIED IDEOGRAPH+0xE9E3 0x9C5A #CJK UNIFIED IDEOGRAPH+0xE9E4 0x9C60 #CJK UNIFIED IDEOGRAPH+0xE9E5 0x9C67 #CJK UNIFIED IDEOGRAPH+0xE9E6 0x9C76 #CJK UNIFIED IDEOGRAPH+0xE9E7 0x9C78 #CJK UNIFIED IDEOGRAPH+0xE9E8 0x9CE7 #CJK UNIFIED IDEOGRAPH+0xE9E9 0x9CEC #CJK UNIFIED IDEOGRAPH+0xE9EA 0x9CF0 #CJK UNIFIED IDEOGRAPH+0xE9EB 0x9D09 #CJK UNIFIED IDEOGRAPH+0xE9EC 0x9D08 #CJK UNIFIED IDEOGRAPH+0xE9ED 0x9CEB #CJK UNIFIED IDEOGRAPH+0xE9EE 0x9D03 #CJK UNIFIED IDEOGRAPH+0xE9EF 0x9D06 #CJK UNIFIED IDEOGRAPH+0xE9F0 0x9D2A #CJK UNIFIED IDEOGRAPH+0xE9F1 0x9D26 #CJK UNIFIED IDEOGRAPH+0xE9F2 0x9DAF #CJK UNIFIED IDEOGRAPH+0xE9F3 0x9D23 #CJK UNIFIED IDEOGRAPH+0xE9F4 0x9D1F #CJK UNIFIED IDEOGRAPH+0xE9F5 0x9D44 #CJK UNIFIED IDEOGRAPH+0xE9F6 0x9D15 #CJK UNIFIED IDEOGRAPH+0xE9F7 0x9D12 #CJK UNIFIED IDEOGRAPH+0xE9F8 0x9D41 #CJK UNIFIED IDEOGRAPH+0xE9F9 0x9D3F #CJK UNIFIED IDEOGRAPH+0xE9FA 0x9D3E #CJK UNIFIED IDEOGRAPH+0xE9FB 0x9D46 #CJK UNIFIED IDEOGRAPH+0xE9FC 0x9D48 #CJK UNIFIED IDEOGRAPH+0xEA40 0x9D5D #CJK UNIFIED IDEOGRAPH+0xEA41 0x9D5E #CJK UNIFIED IDEOGRAPH+0xEA42 0x9D64 #CJK UNIFIED IDEOGRAPH+0xEA43 0x9D51 #CJK UNIFIED IDEOGRAPH+0xEA44 0x9D50 #CJK UNIFIED IDEOGRAPH+0xEA45 0x9D59 #CJK UNIFIED IDEOGRAPH+0xEA46 0x9D72 #CJK UNIFIED IDEOGRAPH+0xEA47 0x9D89 #CJK UNIFIED IDEOGRAPH+0xEA48 0x9D87 #CJK UNIFIED IDEOGRAPH+0xEA49 0x9DAB #CJK UNIFIED IDEOGRAPH+0xEA4A 0x9D6F #CJK UNIFIED IDEOGRAPH+0xEA4B 0x9D7A #CJK UNIFIED IDEOGRAPH+0xEA4C 0x9D9A #CJK UNIFIED IDEOGRAPH+0xEA4D 0x9DA4 #CJK UNIFIED IDEOGRAPH+0xEA4E 0x9DA9 #CJK UNIFIED IDEOGRAPH+0xEA4F 0x9DB2 #CJK UNIFIED IDEOGRAPH+0xEA50 0x9DC4 #CJK UNIFIED IDEOGRAPH+0xEA51 0x9DC1 #CJK UNIFIED IDEOGRAPH+0xEA52 0x9DBB #CJK UNIFIED IDEOGRAPH+0xEA53 0x9DB8 #CJK UNIFIED IDEOGRAPH+0xEA54 0x9DBA #CJK UNIFIED IDEOGRAPH+0xEA55 0x9DC6 #CJK UNIFIED IDEOGRAPH+0xEA56 0x9DCF #CJK UNIFIED IDEOGRAPH+0xEA57 0x9DC2 #CJK UNIFIED IDEOGRAPH+0xEA58 0x9DD9 #CJK UNIFIED IDEOGRAPH+0xEA59 0x9DD3 #CJK UNIFIED IDEOGRAPH+0xEA5A 0x9DF8 #CJK UNIFIED IDEOGRAPH+0xEA5B 0x9DE6 #CJK UNIFIED IDEOGRAPH+0xEA5C 0x9DED #CJK UNIFIED IDEOGRAPH+0xEA5D 0x9DEF #CJK UNIFIED IDEOGRAPH+0xEA5E 0x9DFD #CJK UNIFIED IDEOGRAPH+0xEA5F 0x9E1A #CJK UNIFIED IDEOGRAPH+0xEA60 0x9E1B #CJK UNIFIED IDEOGRAPH+0xEA61 0x9E1E #CJK UNIFIED IDEOGRAPH+0xEA62 0x9E75 #CJK UNIFIED IDEOGRAPH+0xEA63 0x9E79 #CJK UNIFIED IDEOGRAPH+0xEA64 0x9E7D #CJK UNIFIED IDEOGRAPH+0xEA65 0x9E81 #CJK UNIFIED IDEOGRAPH+0xEA66 0x9E88 #CJK UNIFIED IDEOGRAPH+0xEA67 0x9E8B #CJK UNIFIED IDEOGRAPH+0xEA68 0x9E8C #CJK UNIFIED IDEOGRAPH+0xEA69 0x9E92 #CJK UNIFIED IDEOGRAPH+0xEA6A 0x9E95 #CJK UNIFIED IDEOGRAPH+0xEA6B 0x9E91 #CJK UNIFIED IDEOGRAPH+0xEA6C 0x9E9D #CJK UNIFIED IDEOGRAPH+0xEA6D 0x9EA5 #CJK UNIFIED IDEOGRAPH+0xEA6E 0x9EA9 #CJK UNIFIED IDEOGRAPH+0xEA6F 0x9EB8 #CJK UNIFIED IDEOGRAPH+0xEA70 0x9EAA #CJK UNIFIED IDEOGRAPH+0xEA71 0x9EAD #CJK UNIFIED IDEOGRAPH+0xEA72 0x9761 #CJK UNIFIED IDEOGRAPH+0xEA73 0x9ECC #CJK UNIFIED IDEOGRAPH+0xEA74 0x9ECE #CJK UNIFIED IDEOGRAPH+0xEA75 0x9ECF #CJK UNIFIED IDEOGRAPH+0xEA76 0x9ED0 #CJK UNIFIED IDEOGRAPH+0xEA77 0x9ED4 #CJK UNIFIED IDEOGRAPH+0xEA78 0x9EDC #CJK UNIFIED IDEOGRAPH+0xEA79 0x9EDE #CJK UNIFIED IDEOGRAPH+0xEA7A 0x9EDD #CJK UNIFIED IDEOGRAPH+0xEA7B 0x9EE0 #CJK UNIFIED IDEOGRAPH+0xEA7C 0x9EE5 #CJK UNIFIED IDEOGRAPH+0xEA7D 0x9EE8 #CJK UNIFIED IDEOGRAPH+0xEA7E 0x9EEF #CJK UNIFIED IDEOGRAPH+0xEA80 0x9EF4 #CJK UNIFIED IDEOGRAPH+0xEA81 0x9EF6 #CJK UNIFIED IDEOGRAPH+0xEA82 0x9EF7 #CJK UNIFIED IDEOGRAPH+0xEA83 0x9EF9 #CJK UNIFIED IDEOGRAPH+0xEA84 0x9EFB #CJK UNIFIED IDEOGRAPH+0xEA85 0x9EFC #CJK UNIFIED IDEOGRAPH+0xEA86 0x9EFD #CJK UNIFIED IDEOGRAPH+0xEA87 0x9F07 #CJK UNIFIED IDEOGRAPH+0xEA88 0x9F08 #CJK UNIFIED IDEOGRAPH+0xEA89 0x76B7 #CJK UNIFIED IDEOGRAPH+0xEA8A 0x9F15 #CJK UNIFIED IDEOGRAPH+0xEA8B 0x9F21 #CJK UNIFIED IDEOGRAPH+0xEA8C 0x9F2C #CJK UNIFIED IDEOGRAPH+0xEA8D 0x9F3E #CJK UNIFIED IDEOGRAPH+0xEA8E 0x9F4A #CJK UNIFIED IDEOGRAPH+0xEA8F 0x9F52 #CJK UNIFIED IDEOGRAPH+0xEA90 0x9F54 #CJK UNIFIED IDEOGRAPH+0xEA91 0x9F63 #CJK UNIFIED IDEOGRAPH+0xEA92 0x9F5F #CJK UNIFIED IDEOGRAPH+0xEA93 0x9F60 #CJK UNIFIED IDEOGRAPH+0xEA94 0x9F61 #CJK UNIFIED IDEOGRAPH+0xEA95 0x9F66 #CJK UNIFIED IDEOGRAPH+0xEA96 0x9F67 #CJK UNIFIED IDEOGRAPH+0xEA97 0x9F6C #CJK UNIFIED IDEOGRAPH+0xEA98 0x9F6A #CJK UNIFIED IDEOGRAPH+0xEA99 0x9F77 #CJK UNIFIED IDEOGRAPH+0xEA9A 0x9F72 #CJK UNIFIED IDEOGRAPH+0xEA9B 0x9F76 #CJK UNIFIED IDEOGRAPH+0xEA9C 0x9F95 #CJK UNIFIED IDEOGRAPH+0xEA9D 0x9F9C #CJK UNIFIED IDEOGRAPH+0xEA9E 0x9FA0 #CJK UNIFIED IDEOGRAPH+0xEA9F 0x582F #CJK UNIFIED IDEOGRAPH+0xEAA0 0x69C7 #CJK UNIFIED IDEOGRAPH+0xEAA1 0x9059 #CJK UNIFIED IDEOGRAPH+0xEAA2 0x7464 #CJK UNIFIED IDEOGRAPH+0xEAA3 0x51DC #CJK UNIFIED IDEOGRAPH+0xEAA4 0x7199 #CJK UNIFIED IDEOGRAPH+0xED40 0x7E8A #CJK UNIFIED IDEOGRAPH+0xED41 0x891C #CJK UNIFIED IDEOGRAPH+0xED42 0x9348 #CJK UNIFIED IDEOGRAPH+0xED43 0x9288 #CJK UNIFIED IDEOGRAPH+0xED44 0x84DC #CJK UNIFIED IDEOGRAPH+0xED45 0x4FC9 #CJK UNIFIED IDEOGRAPH+0xED46 0x70BB #CJK UNIFIED IDEOGRAPH+0xED47 0x6631 #CJK UNIFIED IDEOGRAPH+0xED48 0x68C8 #CJK UNIFIED IDEOGRAPH+0xED49 0x92F9 #CJK UNIFIED IDEOGRAPH+0xED4A 0x66FB #CJK UNIFIED IDEOGRAPH+0xED4B 0x5F45 #CJK UNIFIED IDEOGRAPH+0xED4C 0x4E28 #CJK UNIFIED IDEOGRAPH+0xED4D 0x4EE1 #CJK UNIFIED IDEOGRAPH+0xED4E 0x4EFC #CJK UNIFIED IDEOGRAPH+0xED4F 0x4F00 #CJK UNIFIED IDEOGRAPH+0xED50 0x4F03 #CJK UNIFIED IDEOGRAPH+0xED51 0x4F39 #CJK UNIFIED IDEOGRAPH+0xED52 0x4F56 #CJK UNIFIED IDEOGRAPH+0xED53 0x4F92 #CJK UNIFIED IDEOGRAPH+0xED54 0x4F8A #CJK UNIFIED IDEOGRAPH+0xED55 0x4F9A #CJK UNIFIED IDEOGRAPH+0xED56 0x4F94 #CJK UNIFIED IDEOGRAPH+0xED57 0x4FCD #CJK UNIFIED IDEOGRAPH+0xED58 0x5040 #CJK UNIFIED IDEOGRAPH+0xED59 0x5022 #CJK UNIFIED IDEOGRAPH+0xED5A 0x4FFF #CJK UNIFIED IDEOGRAPH+0xED5B 0x501E #CJK UNIFIED IDEOGRAPH+0xED5C 0x5046 #CJK UNIFIED IDEOGRAPH+0xED5D 0x5070 #CJK UNIFIED IDEOGRAPH+0xED5E 0x5042 #CJK UNIFIED IDEOGRAPH+0xED5F 0x5094 #CJK UNIFIED IDEOGRAPH+0xED60 0x50F4 #CJK UNIFIED IDEOGRAPH+0xED61 0x50D8 #CJK UNIFIED IDEOGRAPH+0xED62 0x514A #CJK UNIFIED IDEOGRAPH+0xED63 0x5164 #CJK UNIFIED IDEOGRAPH+0xED64 0x519D #CJK UNIFIED IDEOGRAPH+0xED65 0x51BE #CJK UNIFIED IDEOGRAPH+0xED66 0x51EC #CJK UNIFIED IDEOGRAPH+0xED67 0x5215 #CJK UNIFIED IDEOGRAPH+0xED68 0x529C #CJK UNIFIED IDEOGRAPH+0xED69 0x52A6 #CJK UNIFIED IDEOGRAPH+0xED6A 0x52C0 #CJK UNIFIED IDEOGRAPH+0xED6B 0x52DB #CJK UNIFIED IDEOGRAPH+0xED6C 0x5300 #CJK UNIFIED IDEOGRAPH+0xED6D 0x5307 #CJK UNIFIED IDEOGRAPH+0xED6E 0x5324 #CJK UNIFIED IDEOGRAPH+0xED6F 0x5372 #CJK UNIFIED IDEOGRAPH+0xED70 0x5393 #CJK UNIFIED IDEOGRAPH+0xED71 0x53B2 #CJK UNIFIED IDEOGRAPH+0xED72 0x53DD #CJK UNIFIED IDEOGRAPH+0xED73 0xFA0E #CJK COMPATIBILITY IDEOGRAPH+0xED74 0x549C #CJK UNIFIED IDEOGRAPH+0xED75 0x548A #CJK UNIFIED IDEOGRAPH+0xED76 0x54A9 #CJK UNIFIED IDEOGRAPH+0xED77 0x54FF #CJK UNIFIED IDEOGRAPH+0xED78 0x5586 #CJK UNIFIED IDEOGRAPH+0xED79 0x5759 #CJK UNIFIED IDEOGRAPH+0xED7A 0x5765 #CJK UNIFIED IDEOGRAPH+0xED7B 0x57AC #CJK UNIFIED IDEOGRAPH+0xED7C 0x57C8 #CJK UNIFIED IDEOGRAPH+0xED7D 0x57C7 #CJK UNIFIED IDEOGRAPH+0xED7E 0xFA0F #CJK COMPATIBILITY IDEOGRAPH+0xED80 0xFA10 #CJK COMPATIBILITY IDEOGRAPH+0xED81 0x589E #CJK UNIFIED IDEOGRAPH+0xED82 0x58B2 #CJK UNIFIED IDEOGRAPH+0xED83 0x590B #CJK UNIFIED IDEOGRAPH+0xED84 0x5953 #CJK UNIFIED IDEOGRAPH+0xED85 0x595B #CJK UNIFIED IDEOGRAPH+0xED86 0x595D #CJK UNIFIED IDEOGRAPH+0xED87 0x5963 #CJK UNIFIED IDEOGRAPH+0xED88 0x59A4 #CJK UNIFIED IDEOGRAPH+0xED89 0x59BA #CJK UNIFIED IDEOGRAPH+0xED8A 0x5B56 #CJK UNIFIED IDEOGRAPH+0xED8B 0x5BC0 #CJK UNIFIED IDEOGRAPH+0xED8C 0x752F #CJK UNIFIED IDEOGRAPH+0xED8D 0x5BD8 #CJK UNIFIED IDEOGRAPH+0xED8E 0x5BEC #CJK UNIFIED IDEOGRAPH+0xED8F 0x5C1E #CJK UNIFIED IDEOGRAPH+0xED90 0x5CA6 #CJK UNIFIED IDEOGRAPH+0xED91 0x5CBA #CJK UNIFIED IDEOGRAPH+0xED92 0x5CF5 #CJK UNIFIED IDEOGRAPH+0xED93 0x5D27 #CJK UNIFIED IDEOGRAPH+0xED94 0x5D53 #CJK UNIFIED IDEOGRAPH+0xED95 0xFA11 #CJK COMPATIBILITY IDEOGRAPH+0xED96 0x5D42 #CJK UNIFIED IDEOGRAPH+0xED97 0x5D6D #CJK UNIFIED IDEOGRAPH+0xED98 0x5DB8 #CJK UNIFIED IDEOGRAPH+0xED99 0x5DB9 #CJK UNIFIED IDEOGRAPH+0xED9A 0x5DD0 #CJK UNIFIED IDEOGRAPH+0xED9B 0x5F21 #CJK UNIFIED IDEOGRAPH+0xED9C 0x5F34 #CJK UNIFIED IDEOGRAPH+0xED9D 0x5F67 #CJK UNIFIED IDEOGRAPH+0xED9E 0x5FB7 #CJK UNIFIED IDEOGRAPH+0xED9F 0x5FDE #CJK UNIFIED IDEOGRAPH+0xEDA0 0x605D #CJK UNIFIED IDEOGRAPH+0xEDA1 0x6085 #CJK UNIFIED IDEOGRAPH+0xEDA2 0x608A #CJK UNIFIED IDEOGRAPH+0xEDA3 0x60DE #CJK UNIFIED IDEOGRAPH+0xEDA4 0x60D5 #CJK UNIFIED IDEOGRAPH+0xEDA5 0x6120 #CJK UNIFIED IDEOGRAPH+0xEDA6 0x60F2 #CJK UNIFIED IDEOGRAPH+0xEDA7 0x6111 #CJK UNIFIED IDEOGRAPH+0xEDA8 0x6137 #CJK UNIFIED IDEOGRAPH+0xEDA9 0x6130 #CJK UNIFIED IDEOGRAPH+0xEDAA 0x6198 #CJK UNIFIED IDEOGRAPH+0xEDAB 0x6213 #CJK UNIFIED IDEOGRAPH+0xEDAC 0x62A6 #CJK UNIFIED IDEOGRAPH+0xEDAD 0x63F5 #CJK UNIFIED IDEOGRAPH+0xEDAE 0x6460 #CJK UNIFIED IDEOGRAPH+0xEDAF 0x649D #CJK UNIFIED IDEOGRAPH+0xEDB0 0x64CE #CJK UNIFIED IDEOGRAPH+0xEDB1 0x654E #CJK UNIFIED IDEOGRAPH+0xEDB2 0x6600 #CJK UNIFIED IDEOGRAPH+0xEDB3 0x6615 #CJK UNIFIED IDEOGRAPH+0xEDB4 0x663B #CJK UNIFIED IDEOGRAPH+0xEDB5 0x6609 #CJK UNIFIED IDEOGRAPH+0xEDB6 0x662E #CJK UNIFIED IDEOGRAPH+0xEDB7 0x661E #CJK UNIFIED IDEOGRAPH+0xEDB8 0x6624 #CJK UNIFIED IDEOGRAPH+0xEDB9 0x6665 #CJK UNIFIED IDEOGRAPH+0xEDBA 0x6657 #CJK UNIFIED IDEOGRAPH+0xEDBB 0x6659 #CJK UNIFIED IDEOGRAPH+0xEDBC 0xFA12 #CJK COMPATIBILITY IDEOGRAPH+0xEDBD 0x6673 #CJK UNIFIED IDEOGRAPH+0xEDBE 0x6699 #CJK UNIFIED IDEOGRAPH+0xEDBF 0x66A0 #CJK UNIFIED IDEOGRAPH+0xEDC0 0x66B2 #CJK UNIFIED IDEOGRAPH+0xEDC1 0x66BF #CJK UNIFIED IDEOGRAPH+0xEDC2 0x66FA #CJK UNIFIED IDEOGRAPH+0xEDC3 0x670E #CJK UNIFIED IDEOGRAPH+0xEDC4 0xF929 #CJK COMPATIBILITY IDEOGRAPH+0xEDC5 0x6766 #CJK UNIFIED IDEOGRAPH+0xEDC6 0x67BB #CJK UNIFIED IDEOGRAPH+0xEDC7 0x6852 #CJK UNIFIED IDEOGRAPH+0xEDC8 0x67C0 #CJK UNIFIED IDEOGRAPH+0xEDC9 0x6801 #CJK UNIFIED IDEOGRAPH+0xEDCA 0x6844 #CJK UNIFIED IDEOGRAPH+0xEDCB 0x68CF #CJK UNIFIED IDEOGRAPH+0xEDCC 0xFA13 #CJK COMPATIBILITY IDEOGRAPH+0xEDCD 0x6968 #CJK UNIFIED IDEOGRAPH+0xEDCE 0xFA14 #CJK COMPATIBILITY IDEOGRAPH+0xEDCF 0x6998 #CJK UNIFIED IDEOGRAPH+0xEDD0 0x69E2 #CJK UNIFIED IDEOGRAPH+0xEDD1 0x6A30 #CJK UNIFIED IDEOGRAPH+0xEDD2 0x6A6B #CJK UNIFIED IDEOGRAPH+0xEDD3 0x6A46 #CJK UNIFIED IDEOGRAPH+0xEDD4 0x6A73 #CJK UNIFIED IDEOGRAPH+0xEDD5 0x6A7E #CJK UNIFIED IDEOGRAPH+0xEDD6 0x6AE2 #CJK UNIFIED IDEOGRAPH+0xEDD7 0x6AE4 #CJK UNIFIED IDEOGRAPH+0xEDD8 0x6BD6 #CJK UNIFIED IDEOGRAPH+0xEDD9 0x6C3F #CJK UNIFIED IDEOGRAPH+0xEDDA 0x6C5C #CJK UNIFIED IDEOGRAPH+0xEDDB 0x6C86 #CJK UNIFIED IDEOGRAPH+0xEDDC 0x6C6F #CJK UNIFIED IDEOGRAPH+0xEDDD 0x6CDA #CJK UNIFIED IDEOGRAPH+0xEDDE 0x6D04 #CJK UNIFIED IDEOGRAPH+0xEDDF 0x6D87 #CJK UNIFIED IDEOGRAPH+0xEDE0 0x6D6F #CJK UNIFIED IDEOGRAPH+0xEDE1 0x6D96 #CJK UNIFIED IDEOGRAPH+0xEDE2 0x6DAC #CJK UNIFIED IDEOGRAPH+0xEDE3 0x6DCF #CJK UNIFIED IDEOGRAPH+0xEDE4 0x6DF8 #CJK UNIFIED IDEOGRAPH+0xEDE5 0x6DF2 #CJK UNIFIED IDEOGRAPH+0xEDE6 0x6DFC #CJK UNIFIED IDEOGRAPH+0xEDE7 0x6E39 #CJK UNIFIED IDEOGRAPH+0xEDE8 0x6E5C #CJK UNIFIED IDEOGRAPH+0xEDE9 0x6E27 #CJK UNIFIED IDEOGRAPH+0xEDEA 0x6E3C #CJK UNIFIED IDEOGRAPH+0xEDEB 0x6EBF #CJK UNIFIED IDEOGRAPH+0xEDEC 0x6F88 #CJK UNIFIED IDEOGRAPH+0xEDED 0x6FB5 #CJK UNIFIED IDEOGRAPH+0xEDEE 0x6FF5 #CJK UNIFIED IDEOGRAPH+0xEDEF 0x7005 #CJK UNIFIED IDEOGRAPH+0xEDF0 0x7007 #CJK UNIFIED IDEOGRAPH+0xEDF1 0x7028 #CJK UNIFIED IDEOGRAPH+0xEDF2 0x7085 #CJK UNIFIED IDEOGRAPH+0xEDF3 0x70AB #CJK UNIFIED IDEOGRAPH+0xEDF4 0x710F #CJK UNIFIED IDEOGRAPH+0xEDF5 0x7104 #CJK UNIFIED IDEOGRAPH+0xEDF6 0x715C #CJK UNIFIED IDEOGRAPH+0xEDF7 0x7146 #CJK UNIFIED IDEOGRAPH+0xEDF8 0x7147 #CJK UNIFIED IDEOGRAPH+0xEDF9 0xFA15 #CJK COMPATIBILITY IDEOGRAPH+0xEDFA 0x71C1 #CJK UNIFIED IDEOGRAPH+0xEDFB 0x71FE #CJK UNIFIED IDEOGRAPH+0xEDFC 0x72B1 #CJK UNIFIED IDEOGRAPH+0xEE40 0x72BE #CJK UNIFIED IDEOGRAPH+0xEE41 0x7324 #CJK UNIFIED IDEOGRAPH+0xEE42 0xFA16 #CJK COMPATIBILITY IDEOGRAPH+0xEE43 0x7377 #CJK UNIFIED IDEOGRAPH+0xEE44 0x73BD #CJK UNIFIED IDEOGRAPH+0xEE45 0x73C9 #CJK UNIFIED IDEOGRAPH+0xEE46 0x73D6 #CJK UNIFIED IDEOGRAPH+0xEE47 0x73E3 #CJK UNIFIED IDEOGRAPH+0xEE48 0x73D2 #CJK UNIFIED IDEOGRAPH+0xEE49 0x7407 #CJK UNIFIED IDEOGRAPH+0xEE4A 0x73F5 #CJK UNIFIED IDEOGRAPH+0xEE4B 0x7426 #CJK UNIFIED IDEOGRAPH+0xEE4C 0x742A #CJK UNIFIED IDEOGRAPH+0xEE4D 0x7429 #CJK UNIFIED IDEOGRAPH+0xEE4E 0x742E #CJK UNIFIED IDEOGRAPH+0xEE4F 0x7462 #CJK UNIFIED IDEOGRAPH+0xEE50 0x7489 #CJK UNIFIED IDEOGRAPH+0xEE51 0x749F #CJK UNIFIED IDEOGRAPH+0xEE52 0x7501 #CJK UNIFIED IDEOGRAPH+0xEE53 0x756F #CJK UNIFIED IDEOGRAPH+0xEE54 0x7682 #CJK UNIFIED IDEOGRAPH+0xEE55 0x769C #CJK UNIFIED IDEOGRAPH+0xEE56 0x769E #CJK UNIFIED IDEOGRAPH+0xEE57 0x769B #CJK UNIFIED IDEOGRAPH+0xEE58 0x76A6 #CJK UNIFIED IDEOGRAPH+0xEE59 0xFA17 #CJK COMPATIBILITY IDEOGRAPH+0xEE5A 0x7746 #CJK UNIFIED IDEOGRAPH+0xEE5B 0x52AF #CJK UNIFIED IDEOGRAPH+0xEE5C 0x7821 #CJK UNIFIED IDEOGRAPH+0xEE5D 0x784E #CJK UNIFIED IDEOGRAPH+0xEE5E 0x7864 #CJK UNIFIED IDEOGRAPH+0xEE5F 0x787A #CJK UNIFIED IDEOGRAPH+0xEE60 0x7930 #CJK UNIFIED IDEOGRAPH+0xEE61 0xFA18 #CJK COMPATIBILITY IDEOGRAPH+0xEE62 0xFA19 #CJK COMPATIBILITY IDEOGRAPH+0xEE63 0xFA1A #CJK COMPATIBILITY IDEOGRAPH+0xEE64 0x7994 #CJK UNIFIED IDEOGRAPH+0xEE65 0xFA1B #CJK COMPATIBILITY IDEOGRAPH+0xEE66 0x799B #CJK UNIFIED IDEOGRAPH+0xEE67 0x7AD1 #CJK UNIFIED IDEOGRAPH+0xEE68 0x7AE7 #CJK UNIFIED IDEOGRAPH+0xEE69 0xFA1C #CJK COMPATIBILITY IDEOGRAPH+0xEE6A 0x7AEB #CJK UNIFIED IDEOGRAPH+0xEE6B 0x7B9E #CJK UNIFIED IDEOGRAPH+0xEE6C 0xFA1D #CJK COMPATIBILITY IDEOGRAPH+0xEE6D 0x7D48 #CJK UNIFIED IDEOGRAPH+0xEE6E 0x7D5C #CJK UNIFIED IDEOGRAPH+0xEE6F 0x7DB7 #CJK UNIFIED IDEOGRAPH+0xEE70 0x7DA0 #CJK UNIFIED IDEOGRAPH+0xEE71 0x7DD6 #CJK UNIFIED IDEOGRAPH+0xEE72 0x7E52 #CJK UNIFIED IDEOGRAPH+0xEE73 0x7F47 #CJK UNIFIED IDEOGRAPH+0xEE74 0x7FA1 #CJK UNIFIED IDEOGRAPH+0xEE75 0xFA1E #CJK COMPATIBILITY IDEOGRAPH+0xEE76 0x8301 #CJK UNIFIED IDEOGRAPH+0xEE77 0x8362 #CJK UNIFIED IDEOGRAPH+0xEE78 0x837F #CJK UNIFIED IDEOGRAPH+0xEE79 0x83C7 #CJK UNIFIED IDEOGRAPH+0xEE7A 0x83F6 #CJK UNIFIED IDEOGRAPH+0xEE7B 0x8448 #CJK UNIFIED IDEOGRAPH+0xEE7C 0x84B4 #CJK UNIFIED IDEOGRAPH+0xEE7D 0x8553 #CJK UNIFIED IDEOGRAPH+0xEE7E 0x8559 #CJK UNIFIED IDEOGRAPH+0xEE80 0x856B #CJK UNIFIED IDEOGRAPH+0xEE81 0xFA1F #CJK COMPATIBILITY IDEOGRAPH+0xEE82 0x85B0 #CJK UNIFIED IDEOGRAPH+0xEE83 0xFA20 #CJK COMPATIBILITY IDEOGRAPH+0xEE84 0xFA21 #CJK COMPATIBILITY IDEOGRAPH+0xEE85 0x8807 #CJK UNIFIED IDEOGRAPH+0xEE86 0x88F5 #CJK UNIFIED IDEOGRAPH+0xEE87 0x8A12 #CJK UNIFIED IDEOGRAPH+0xEE88 0x8A37 #CJK UNIFIED IDEOGRAPH+0xEE89 0x8A79 #CJK UNIFIED IDEOGRAPH+0xEE8A 0x8AA7 #CJK UNIFIED IDEOGRAPH+0xEE8B 0x8ABE #CJK UNIFIED IDEOGRAPH+0xEE8C 0x8ADF #CJK UNIFIED IDEOGRAPH+0xEE8D 0xFA22 #CJK COMPATIBILITY IDEOGRAPH+0xEE8E 0x8AF6 #CJK UNIFIED IDEOGRAPH+0xEE8F 0x8B53 #CJK UNIFIED IDEOGRAPH+0xEE90 0x8B7F #CJK UNIFIED IDEOGRAPH+0xEE91 0x8CF0 #CJK UNIFIED IDEOGRAPH+0xEE92 0x8CF4 #CJK UNIFIED IDEOGRAPH+0xEE93 0x8D12 #CJK UNIFIED IDEOGRAPH+0xEE94 0x8D76 #CJK UNIFIED IDEOGRAPH+0xEE95 0xFA23 #CJK COMPATIBILITY IDEOGRAPH+0xEE96 0x8ECF #CJK UNIFIED IDEOGRAPH+0xEE97 0xFA24 #CJK COMPATIBILITY IDEOGRAPH+0xEE98 0xFA25 #CJK COMPATIBILITY IDEOGRAPH+0xEE99 0x9067 #CJK UNIFIED IDEOGRAPH+0xEE9A 0x90DE #CJK UNIFIED IDEOGRAPH+0xEE9B 0xFA26 #CJK COMPATIBILITY IDEOGRAPH+0xEE9C 0x9115 #CJK UNIFIED IDEOGRAPH+0xEE9D 0x9127 #CJK UNIFIED IDEOGRAPH+0xEE9E 0x91DA #CJK UNIFIED IDEOGRAPH+0xEE9F 0x91D7 #CJK UNIFIED IDEOGRAPH+0xEEA0 0x91DE #CJK UNIFIED IDEOGRAPH+0xEEA1 0x91ED #CJK UNIFIED IDEOGRAPH+0xEEA2 0x91EE #CJK UNIFIED IDEOGRAPH+0xEEA3 0x91E4 #CJK UNIFIED IDEOGRAPH+0xEEA4 0x91E5 #CJK UNIFIED IDEOGRAPH+0xEEA5 0x9206 #CJK UNIFIED IDEOGRAPH+0xEEA6 0x9210 #CJK UNIFIED IDEOGRAPH+0xEEA7 0x920A #CJK UNIFIED IDEOGRAPH+0xEEA8 0x923A #CJK UNIFIED IDEOGRAPH+0xEEA9 0x9240 #CJK UNIFIED IDEOGRAPH+0xEEAA 0x923C #CJK UNIFIED IDEOGRAPH+0xEEAB 0x924E #CJK UNIFIED IDEOGRAPH+0xEEAC 0x9259 #CJK UNIFIED IDEOGRAPH+0xEEAD 0x9251 #CJK UNIFIED IDEOGRAPH+0xEEAE 0x9239 #CJK UNIFIED IDEOGRAPH+0xEEAF 0x9267 #CJK UNIFIED IDEOGRAPH+0xEEB0 0x92A7 #CJK UNIFIED IDEOGRAPH+0xEEB1 0x9277 #CJK UNIFIED IDEOGRAPH+0xEEB2 0x9278 #CJK UNIFIED IDEOGRAPH+0xEEB3 0x92E7 #CJK UNIFIED IDEOGRAPH+0xEEB4 0x92D7 #CJK UNIFIED IDEOGRAPH+0xEEB5 0x92D9 #CJK UNIFIED IDEOGRAPH+0xEEB6 0x92D0 #CJK UNIFIED IDEOGRAPH+0xEEB7 0xFA27 #CJK COMPATIBILITY IDEOGRAPH+0xEEB8 0x92D5 #CJK UNIFIED IDEOGRAPH+0xEEB9 0x92E0 #CJK UNIFIED IDEOGRAPH+0xEEBA 0x92D3 #CJK UNIFIED IDEOGRAPH+0xEEBB 0x9325 #CJK UNIFIED IDEOGRAPH+0xEEBC 0x9321 #CJK UNIFIED IDEOGRAPH+0xEEBD 0x92FB #CJK UNIFIED IDEOGRAPH+0xEEBE 0xFA28 #CJK COMPATIBILITY IDEOGRAPH+0xEEBF 0x931E #CJK UNIFIED IDEOGRAPH+0xEEC0 0x92FF #CJK UNIFIED IDEOGRAPH+0xEEC1 0x931D #CJK UNIFIED IDEOGRAPH+0xEEC2 0x9302 #CJK UNIFIED IDEOGRAPH+0xEEC3 0x9370 #CJK UNIFIED IDEOGRAPH+0xEEC4 0x9357 #CJK UNIFIED IDEOGRAPH+0xEEC5 0x93A4 #CJK UNIFIED IDEOGRAPH+0xEEC6 0x93C6 #CJK UNIFIED IDEOGRAPH+0xEEC7 0x93DE #CJK UNIFIED IDEOGRAPH+0xEEC8 0x93F8 #CJK UNIFIED IDEOGRAPH+0xEEC9 0x9431 #CJK UNIFIED IDEOGRAPH+0xEECA 0x9445 #CJK UNIFIED IDEOGRAPH+0xEECB 0x9448 #CJK UNIFIED IDEOGRAPH+0xEECC 0x9592 #CJK UNIFIED IDEOGRAPH+0xEECD 0xF9DC #CJK COMPATIBILITY IDEOGRAPH+0xEECE 0xFA29 #CJK COMPATIBILITY IDEOGRAPH+0xEECF 0x969D #CJK UNIFIED IDEOGRAPH+0xEED0 0x96AF #CJK UNIFIED IDEOGRAPH+0xEED1 0x9733 #CJK UNIFIED IDEOGRAPH+0xEED2 0x973B #CJK UNIFIED IDEOGRAPH+0xEED3 0x9743 #CJK UNIFIED IDEOGRAPH+0xEED4 0x974D #CJK UNIFIED IDEOGRAPH+0xEED5 0x974F #CJK UNIFIED IDEOGRAPH+0xEED6 0x9751 #CJK UNIFIED IDEOGRAPH+0xEED7 0x9755 #CJK UNIFIED IDEOGRAPH+0xEED8 0x9857 #CJK UNIFIED IDEOGRAPH+0xEED9 0x9865 #CJK UNIFIED IDEOGRAPH+0xEEDA 0xFA2A #CJK COMPATIBILITY IDEOGRAPH+0xEEDB 0xFA2B #CJK COMPATIBILITY IDEOGRAPH+0xEEDC 0x9927 #CJK UNIFIED IDEOGRAPH+0xEEDD 0xFA2C #CJK COMPATIBILITY IDEOGRAPH+0xEEDE 0x999E #CJK UNIFIED IDEOGRAPH+0xEEDF 0x9A4E #CJK UNIFIED IDEOGRAPH+0xEEE0 0x9AD9 #CJK UNIFIED IDEOGRAPH+0xEEE1 0x9ADC #CJK UNIFIED IDEOGRAPH+0xEEE2 0x9B75 #CJK UNIFIED IDEOGRAPH+0xEEE3 0x9B72 #CJK UNIFIED IDEOGRAPH+0xEEE4 0x9B8F #CJK UNIFIED IDEOGRAPH+0xEEE5 0x9BB1 #CJK UNIFIED IDEOGRAPH+0xEEE6 0x9BBB #CJK UNIFIED IDEOGRAPH+0xEEE7 0x9C00 #CJK UNIFIED IDEOGRAPH+0xEEE8 0x9D70 #CJK UNIFIED IDEOGRAPH+0xEEE9 0x9D6B #CJK UNIFIED IDEOGRAPH+0xEEEA 0xFA2D #CJK COMPATIBILITY IDEOGRAPH+0xEEEB 0x9E19 #CJK UNIFIED IDEOGRAPH+0xEEEC 0x9ED1 #CJK UNIFIED IDEOGRAPH+0xEEEF 0x2170 #SMALL ROMAN NUMERAL ONE+0xEEF0 0x2171 #SMALL ROMAN NUMERAL TWO+0xEEF1 0x2172 #SMALL ROMAN NUMERAL THREE+0xEEF2 0x2173 #SMALL ROMAN NUMERAL FOUR+0xEEF3 0x2174 #SMALL ROMAN NUMERAL FIVE+0xEEF4 0x2175 #SMALL ROMAN NUMERAL SIX+0xEEF5 0x2176 #SMALL ROMAN NUMERAL SEVEN+0xEEF6 0x2177 #SMALL ROMAN NUMERAL EIGHT+0xEEF7 0x2178 #SMALL ROMAN NUMERAL NINE+0xEEF8 0x2179 #SMALL ROMAN NUMERAL TEN+0xEEF9 0xFFE2 #FULLWIDTH NOT SIGN+0xEEFA 0xFFE4 #FULLWIDTH BROKEN BAR+0xEEFB 0xFF07 #FULLWIDTH APOSTROPHE+0xEEFC 0xFF02 #FULLWIDTH QUOTATION MARK+0xFA40 0x2170 #SMALL ROMAN NUMERAL ONE+0xFA41 0x2171 #SMALL ROMAN NUMERAL TWO+0xFA42 0x2172 #SMALL ROMAN NUMERAL THREE+0xFA43 0x2173 #SMALL ROMAN NUMERAL FOUR+0xFA44 0x2174 #SMALL ROMAN NUMERAL FIVE+0xFA45 0x2175 #SMALL ROMAN NUMERAL SIX+0xFA46 0x2176 #SMALL ROMAN NUMERAL SEVEN+0xFA47 0x2177 #SMALL ROMAN NUMERAL EIGHT+0xFA48 0x2178 #SMALL ROMAN NUMERAL NINE+0xFA49 0x2179 #SMALL ROMAN NUMERAL TEN+0xFA4A 0x2160 #ROMAN NUMERAL ONE+0xFA4B 0x2161 #ROMAN NUMERAL TWO+0xFA4C 0x2162 #ROMAN NUMERAL THREE+0xFA4D 0x2163 #ROMAN NUMERAL FOUR+0xFA4E 0x2164 #ROMAN NUMERAL FIVE+0xFA4F 0x2165 #ROMAN NUMERAL SIX+0xFA50 0x2166 #ROMAN NUMERAL SEVEN+0xFA51 0x2167 #ROMAN NUMERAL EIGHT+0xFA52 0x2168 #ROMAN NUMERAL NINE+0xFA53 0x2169 #ROMAN NUMERAL TEN+0xFA54 0xFFE2 #FULLWIDTH NOT SIGN+0xFA55 0xFFE4 #FULLWIDTH BROKEN BAR+0xFA56 0xFF07 #FULLWIDTH APOSTROPHE+0xFA57 0xFF02 #FULLWIDTH QUOTATION MARK+0xFA58 0x3231 #PARENTHESIZED IDEOGRAPH STOCK+0xFA59 0x2116 #NUMERO SIGN+0xFA5A 0x2121 #TELEPHONE SIGN+0xFA5B 0x2235 #BECAUSE+0xFA5C 0x7E8A #CJK UNIFIED IDEOGRAPH+0xFA5D 0x891C #CJK UNIFIED IDEOGRAPH+0xFA5E 0x9348 #CJK UNIFIED IDEOGRAPH+0xFA5F 0x9288 #CJK UNIFIED IDEOGRAPH+0xFA60 0x84DC #CJK UNIFIED IDEOGRAPH+0xFA61 0x4FC9 #CJK UNIFIED IDEOGRAPH+0xFA62 0x70BB #CJK UNIFIED IDEOGRAPH+0xFA63 0x6631 #CJK UNIFIED IDEOGRAPH+0xFA64 0x68C8 #CJK UNIFIED IDEOGRAPH+0xFA65 0x92F9 #CJK UNIFIED IDEOGRAPH+0xFA66 0x66FB #CJK UNIFIED IDEOGRAPH+0xFA67 0x5F45 #CJK UNIFIED IDEOGRAPH+0xFA68 0x4E28 #CJK UNIFIED IDEOGRAPH+0xFA69 0x4EE1 #CJK UNIFIED IDEOGRAPH+0xFA6A 0x4EFC #CJK UNIFIED IDEOGRAPH+0xFA6B 0x4F00 #CJK UNIFIED IDEOGRAPH+0xFA6C 0x4F03 #CJK UNIFIED IDEOGRAPH+0xFA6D 0x4F39 #CJK UNIFIED IDEOGRAPH+0xFA6E 0x4F56 #CJK UNIFIED IDEOGRAPH+0xFA6F 0x4F92 #CJK UNIFIED IDEOGRAPH+0xFA70 0x4F8A #CJK UNIFIED IDEOGRAPH+0xFA71 0x4F9A #CJK UNIFIED IDEOGRAPH+0xFA72 0x4F94 #CJK UNIFIED IDEOGRAPH+0xFA73 0x4FCD #CJK UNIFIED IDEOGRAPH+0xFA74 0x5040 #CJK UNIFIED IDEOGRAPH+0xFA75 0x5022 #CJK UNIFIED IDEOGRAPH+0xFA76 0x4FFF #CJK UNIFIED IDEOGRAPH+0xFA77 0x501E #CJK UNIFIED IDEOGRAPH+0xFA78 0x5046 #CJK UNIFIED IDEOGRAPH+0xFA79 0x5070 #CJK UNIFIED IDEOGRAPH+0xFA7A 0x5042 #CJK UNIFIED IDEOGRAPH+0xFA7B 0x5094 #CJK UNIFIED IDEOGRAPH+0xFA7C 0x50F4 #CJK UNIFIED IDEOGRAPH+0xFA7D 0x50D8 #CJK UNIFIED IDEOGRAPH+0xFA7E 0x514A #CJK UNIFIED IDEOGRAPH+0xFA80 0x5164 #CJK UNIFIED IDEOGRAPH+0xFA81 0x519D #CJK UNIFIED IDEOGRAPH+0xFA82 0x51BE #CJK UNIFIED IDEOGRAPH+0xFA83 0x51EC #CJK UNIFIED IDEOGRAPH+0xFA84 0x5215 #CJK UNIFIED IDEOGRAPH+0xFA85 0x529C #CJK UNIFIED IDEOGRAPH+0xFA86 0x52A6 #CJK UNIFIED IDEOGRAPH+0xFA87 0x52C0 #CJK UNIFIED IDEOGRAPH+0xFA88 0x52DB #CJK UNIFIED IDEOGRAPH+0xFA89 0x5300 #CJK UNIFIED IDEOGRAPH+0xFA8A 0x5307 #CJK UNIFIED IDEOGRAPH+0xFA8B 0x5324 #CJK UNIFIED IDEOGRAPH+0xFA8C 0x5372 #CJK UNIFIED IDEOGRAPH+0xFA8D 0x5393 #CJK UNIFIED IDEOGRAPH+0xFA8E 0x53B2 #CJK UNIFIED IDEOGRAPH+0xFA8F 0x53DD #CJK UNIFIED IDEOGRAPH+0xFA90 0xFA0E #CJK COMPATIBILITY IDEOGRAPH+0xFA91 0x549C #CJK UNIFIED IDEOGRAPH+0xFA92 0x548A #CJK UNIFIED IDEOGRAPH+0xFA93 0x54A9 #CJK UNIFIED IDEOGRAPH+0xFA94 0x54FF #CJK UNIFIED IDEOGRAPH+0xFA95 0x5586 #CJK UNIFIED IDEOGRAPH+0xFA96 0x5759 #CJK UNIFIED IDEOGRAPH+0xFA97 0x5765 #CJK UNIFIED IDEOGRAPH+0xFA98 0x57AC #CJK UNIFIED IDEOGRAPH+0xFA99 0x57C8 #CJK UNIFIED IDEOGRAPH+0xFA9A 0x57C7 #CJK UNIFIED IDEOGRAPH+0xFA9B 0xFA0F #CJK COMPATIBILITY IDEOGRAPH+0xFA9C 0xFA10 #CJK COMPATIBILITY IDEOGRAPH+0xFA9D 0x589E #CJK UNIFIED IDEOGRAPH+0xFA9E 0x58B2 #CJK UNIFIED IDEOGRAPH+0xFA9F 0x590B #CJK UNIFIED IDEOGRAPH+0xFAA0 0x5953 #CJK UNIFIED IDEOGRAPH+0xFAA1 0x595B #CJK UNIFIED IDEOGRAPH+0xFAA2 0x595D #CJK UNIFIED IDEOGRAPH+0xFAA3 0x5963 #CJK UNIFIED IDEOGRAPH+0xFAA4 0x59A4 #CJK UNIFIED IDEOGRAPH+0xFAA5 0x59BA #CJK UNIFIED IDEOGRAPH+0xFAA6 0x5B56 #CJK UNIFIED IDEOGRAPH+0xFAA7 0x5BC0 #CJK UNIFIED IDEOGRAPH+0xFAA8 0x752F #CJK UNIFIED IDEOGRAPH+0xFAA9 0x5BD8 #CJK UNIFIED IDEOGRAPH+0xFAAA 0x5BEC #CJK UNIFIED IDEOGRAPH+0xFAAB 0x5C1E #CJK UNIFIED IDEOGRAPH+0xFAAC 0x5CA6 #CJK UNIFIED IDEOGRAPH+0xFAAD 0x5CBA #CJK UNIFIED IDEOGRAPH+0xFAAE 0x5CF5 #CJK UNIFIED IDEOGRAPH+0xFAAF 0x5D27 #CJK UNIFIED IDEOGRAPH+0xFAB0 0x5D53 #CJK UNIFIED IDEOGRAPH+0xFAB1 0xFA11 #CJK COMPATIBILITY IDEOGRAPH+0xFAB2 0x5D42 #CJK UNIFIED IDEOGRAPH+0xFAB3 0x5D6D #CJK UNIFIED IDEOGRAPH+0xFAB4 0x5DB8 #CJK UNIFIED IDEOGRAPH+0xFAB5 0x5DB9 #CJK UNIFIED IDEOGRAPH+0xFAB6 0x5DD0 #CJK UNIFIED IDEOGRAPH+0xFAB7 0x5F21 #CJK UNIFIED IDEOGRAPH+0xFAB8 0x5F34 #CJK UNIFIED IDEOGRAPH+0xFAB9 0x5F67 #CJK UNIFIED IDEOGRAPH+0xFABA 0x5FB7 #CJK UNIFIED IDEOGRAPH+0xFABB 0x5FDE #CJK UNIFIED IDEOGRAPH+0xFABC 0x605D #CJK UNIFIED IDEOGRAPH+0xFABD 0x6085 #CJK UNIFIED IDEOGRAPH+0xFABE 0x608A #CJK UNIFIED IDEOGRAPH+0xFABF 0x60DE #CJK UNIFIED IDEOGRAPH+0xFAC0 0x60D5 #CJK UNIFIED IDEOGRAPH+0xFAC1 0x6120 #CJK UNIFIED IDEOGRAPH+0xFAC2 0x60F2 #CJK UNIFIED IDEOGRAPH+0xFAC3 0x6111 #CJK UNIFIED IDEOGRAPH+0xFAC4 0x6137 #CJK UNIFIED IDEOGRAPH+0xFAC5 0x6130 #CJK UNIFIED IDEOGRAPH+0xFAC6 0x6198 #CJK UNIFIED IDEOGRAPH+0xFAC7 0x6213 #CJK UNIFIED IDEOGRAPH+0xFAC8 0x62A6 #CJK UNIFIED IDEOGRAPH+0xFAC9 0x63F5 #CJK UNIFIED IDEOGRAPH+0xFACA 0x6460 #CJK UNIFIED IDEOGRAPH+0xFACB 0x649D #CJK UNIFIED IDEOGRAPH+0xFACC 0x64CE #CJK UNIFIED IDEOGRAPH+0xFACD 0x654E #CJK UNIFIED IDEOGRAPH+0xFACE 0x6600 #CJK UNIFIED IDEOGRAPH+0xFACF 0x6615 #CJK UNIFIED IDEOGRAPH+0xFAD0 0x663B #CJK UNIFIED IDEOGRAPH+0xFAD1 0x6609 #CJK UNIFIED IDEOGRAPH+0xFAD2 0x662E #CJK UNIFIED IDEOGRAPH+0xFAD3 0x661E #CJK UNIFIED IDEOGRAPH+0xFAD4 0x6624 #CJK UNIFIED IDEOGRAPH+0xFAD5 0x6665 #CJK UNIFIED IDEOGRAPH+0xFAD6 0x6657 #CJK UNIFIED IDEOGRAPH+0xFAD7 0x6659 #CJK UNIFIED IDEOGRAPH+0xFAD8 0xFA12 #CJK COMPATIBILITY IDEOGRAPH+0xFAD9 0x6673 #CJK UNIFIED IDEOGRAPH+0xFADA 0x6699 #CJK UNIFIED IDEOGRAPH+0xFADB 0x66A0 #CJK UNIFIED IDEOGRAPH+0xFADC 0x66B2 #CJK UNIFIED IDEOGRAPH+0xFADD 0x66BF #CJK UNIFIED IDEOGRAPH+0xFADE 0x66FA #CJK UNIFIED IDEOGRAPH+0xFADF 0x670E #CJK UNIFIED IDEOGRAPH+0xFAE0 0xF929 #CJK COMPATIBILITY IDEOGRAPH+0xFAE1 0x6766 #CJK UNIFIED IDEOGRAPH+0xFAE2 0x67BB #CJK UNIFIED IDEOGRAPH+0xFAE3 0x6852 #CJK UNIFIED IDEOGRAPH+0xFAE4 0x67C0 #CJK UNIFIED IDEOGRAPH+0xFAE5 0x6801 #CJK UNIFIED IDEOGRAPH+0xFAE6 0x6844 #CJK UNIFIED IDEOGRAPH+0xFAE7 0x68CF #CJK UNIFIED IDEOGRAPH+0xFAE8 0xFA13 #CJK COMPATIBILITY IDEOGRAPH+0xFAE9 0x6968 #CJK UNIFIED IDEOGRAPH+0xFAEA 0xFA14 #CJK COMPATIBILITY IDEOGRAPH+0xFAEB 0x6998 #CJK UNIFIED IDEOGRAPH+0xFAEC 0x69E2 #CJK UNIFIED IDEOGRAPH+0xFAED 0x6A30 #CJK UNIFIED IDEOGRAPH+0xFAEE 0x6A6B #CJK UNIFIED IDEOGRAPH+0xFAEF 0x6A46 #CJK UNIFIED IDEOGRAPH+0xFAF0 0x6A73 #CJK UNIFIED IDEOGRAPH+0xFAF1 0x6A7E #CJK UNIFIED IDEOGRAPH+0xFAF2 0x6AE2 #CJK UNIFIED IDEOGRAPH+0xFAF3 0x6AE4 #CJK UNIFIED IDEOGRAPH+0xFAF4 0x6BD6 #CJK UNIFIED IDEOGRAPH+0xFAF5 0x6C3F #CJK UNIFIED IDEOGRAPH+0xFAF6 0x6C5C #CJK UNIFIED IDEOGRAPH+0xFAF7 0x6C86 #CJK UNIFIED IDEOGRAPH+0xFAF8 0x6C6F #CJK UNIFIED IDEOGRAPH+0xFAF9 0x6CDA #CJK UNIFIED IDEOGRAPH+0xFAFA 0x6D04 #CJK UNIFIED IDEOGRAPH+0xFAFB 0x6D87 #CJK UNIFIED IDEOGRAPH+0xFAFC 0x6D6F #CJK UNIFIED IDEOGRAPH+0xFB40 0x6D96 #CJK UNIFIED IDEOGRAPH+0xFB41 0x6DAC #CJK UNIFIED IDEOGRAPH+0xFB42 0x6DCF #CJK UNIFIED IDEOGRAPH+0xFB43 0x6DF8 #CJK UNIFIED IDEOGRAPH+0xFB44 0x6DF2 #CJK UNIFIED IDEOGRAPH+0xFB45 0x6DFC #CJK UNIFIED IDEOGRAPH+0xFB46 0x6E39 #CJK UNIFIED IDEOGRAPH+0xFB47 0x6E5C #CJK UNIFIED IDEOGRAPH+0xFB48 0x6E27 #CJK UNIFIED IDEOGRAPH+0xFB49 0x6E3C #CJK UNIFIED IDEOGRAPH+0xFB4A 0x6EBF #CJK UNIFIED IDEOGRAPH+0xFB4B 0x6F88 #CJK UNIFIED IDEOGRAPH+0xFB4C 0x6FB5 #CJK UNIFIED IDEOGRAPH+0xFB4D 0x6FF5 #CJK UNIFIED IDEOGRAPH+0xFB4E 0x7005 #CJK UNIFIED IDEOGRAPH+0xFB4F 0x7007 #CJK UNIFIED IDEOGRAPH+0xFB50 0x7028 #CJK UNIFIED IDEOGRAPH+0xFB51 0x7085 #CJK UNIFIED IDEOGRAPH+0xFB52 0x70AB #CJK UNIFIED IDEOGRAPH+0xFB53 0x710F #CJK UNIFIED IDEOGRAPH+0xFB54 0x7104 #CJK UNIFIED IDEOGRAPH+0xFB55 0x715C #CJK UNIFIED IDEOGRAPH+0xFB56 0x7146 #CJK UNIFIED IDEOGRAPH+0xFB57 0x7147 #CJK UNIFIED IDEOGRAPH+0xFB58 0xFA15 #CJK COMPATIBILITY IDEOGRAPH+0xFB59 0x71C1 #CJK UNIFIED IDEOGRAPH+0xFB5A 0x71FE #CJK UNIFIED IDEOGRAPH+0xFB5B 0x72B1 #CJK UNIFIED IDEOGRAPH+0xFB5C 0x72BE #CJK UNIFIED IDEOGRAPH+0xFB5D 0x7324 #CJK UNIFIED IDEOGRAPH+0xFB5E 0xFA16 #CJK COMPATIBILITY IDEOGRAPH+0xFB5F 0x7377 #CJK UNIFIED IDEOGRAPH+0xFB60 0x73BD #CJK UNIFIED IDEOGRAPH+0xFB61 0x73C9 #CJK UNIFIED IDEOGRAPH+0xFB62 0x73D6 #CJK UNIFIED IDEOGRAPH+0xFB63 0x73E3 #CJK UNIFIED IDEOGRAPH+0xFB64 0x73D2 #CJK UNIFIED IDEOGRAPH+0xFB65 0x7407 #CJK UNIFIED IDEOGRAPH+0xFB66 0x73F5 #CJK UNIFIED IDEOGRAPH+0xFB67 0x7426 #CJK UNIFIED IDEOGRAPH+0xFB68 0x742A #CJK UNIFIED IDEOGRAPH+0xFB69 0x7429 #CJK UNIFIED IDEOGRAPH+0xFB6A 0x742E #CJK UNIFIED IDEOGRAPH+0xFB6B 0x7462 #CJK UNIFIED IDEOGRAPH+0xFB6C 0x7489 #CJK UNIFIED IDEOGRAPH+0xFB6D 0x749F #CJK UNIFIED IDEOGRAPH+0xFB6E 0x7501 #CJK UNIFIED IDEOGRAPH+0xFB6F 0x756F #CJK UNIFIED IDEOGRAPH+0xFB70 0x7682 #CJK UNIFIED IDEOGRAPH+0xFB71 0x769C #CJK UNIFIED IDEOGRAPH+0xFB72 0x769E #CJK UNIFIED IDEOGRAPH+0xFB73 0x769B #CJK UNIFIED IDEOGRAPH+0xFB74 0x76A6 #CJK UNIFIED IDEOGRAPH+0xFB75 0xFA17 #CJK COMPATIBILITY IDEOGRAPH+0xFB76 0x7746 #CJK UNIFIED IDEOGRAPH+0xFB77 0x52AF #CJK UNIFIED IDEOGRAPH+0xFB78 0x7821 #CJK UNIFIED IDEOGRAPH+0xFB79 0x784E #CJK UNIFIED IDEOGRAPH+0xFB7A 0x7864 #CJK UNIFIED IDEOGRAPH+0xFB7B 0x787A #CJK UNIFIED IDEOGRAPH+0xFB7C 0x7930 #CJK UNIFIED IDEOGRAPH+0xFB7D 0xFA18 #CJK COMPATIBILITY IDEOGRAPH+0xFB7E 0xFA19 #CJK COMPATIBILITY IDEOGRAPH+0xFB80 0xFA1A #CJK COMPATIBILITY IDEOGRAPH+0xFB81 0x7994 #CJK UNIFIED IDEOGRAPH+0xFB82 0xFA1B #CJK COMPATIBILITY IDEOGRAPH+0xFB83 0x799B #CJK UNIFIED IDEOGRAPH+0xFB84 0x7AD1 #CJK UNIFIED IDEOGRAPH+0xFB85 0x7AE7 #CJK UNIFIED IDEOGRAPH+0xFB86 0xFA1C #CJK COMPATIBILITY IDEOGRAPH+0xFB87 0x7AEB #CJK UNIFIED IDEOGRAPH+0xFB88 0x7B9E #CJK UNIFIED IDEOGRAPH+0xFB89 0xFA1D #CJK COMPATIBILITY IDEOGRAPH+0xFB8A 0x7D48 #CJK UNIFIED IDEOGRAPH+0xFB8B 0x7D5C #CJK UNIFIED IDEOGRAPH+0xFB8C 0x7DB7 #CJK UNIFIED IDEOGRAPH+0xFB8D 0x7DA0 #CJK UNIFIED IDEOGRAPH+0xFB8E 0x7DD6 #CJK UNIFIED IDEOGRAPH+0xFB8F 0x7E52 #CJK UNIFIED IDEOGRAPH+0xFB90 0x7F47 #CJK UNIFIED IDEOGRAPH+0xFB91 0x7FA1 #CJK UNIFIED IDEOGRAPH+0xFB92 0xFA1E #CJK COMPATIBILITY IDEOGRAPH+0xFB93 0x8301 #CJK UNIFIED IDEOGRAPH+0xFB94 0x8362 #CJK UNIFIED IDEOGRAPH+0xFB95 0x837F #CJK UNIFIED IDEOGRAPH+0xFB96 0x83C7 #CJK UNIFIED IDEOGRAPH+0xFB97 0x83F6 #CJK UNIFIED IDEOGRAPH+0xFB98 0x8448 #CJK UNIFIED IDEOGRAPH+0xFB99 0x84B4 #CJK UNIFIED IDEOGRAPH+0xFB9A 0x8553 #CJK UNIFIED IDEOGRAPH+0xFB9B 0x8559 #CJK UNIFIED IDEOGRAPH+0xFB9C 0x856B #CJK UNIFIED IDEOGRAPH+0xFB9D 0xFA1F #CJK COMPATIBILITY IDEOGRAPH+0xFB9E 0x85B0 #CJK UNIFIED IDEOGRAPH+0xFB9F 0xFA20 #CJK COMPATIBILITY IDEOGRAPH+0xFBA0 0xFA21 #CJK COMPATIBILITY IDEOGRAPH+0xFBA1 0x8807 #CJK UNIFIED IDEOGRAPH+0xFBA2 0x88F5 #CJK UNIFIED IDEOGRAPH+0xFBA3 0x8A12 #CJK UNIFIED IDEOGRAPH+0xFBA4 0x8A37 #CJK UNIFIED IDEOGRAPH+0xFBA5 0x8A79 #CJK UNIFIED IDEOGRAPH+0xFBA6 0x8AA7 #CJK UNIFIED IDEOGRAPH+0xFBA7 0x8ABE #CJK UNIFIED IDEOGRAPH+0xFBA8 0x8ADF #CJK UNIFIED IDEOGRAPH+0xFBA9 0xFA22 #CJK COMPATIBILITY IDEOGRAPH+0xFBAA 0x8AF6 #CJK UNIFIED IDEOGRAPH+0xFBAB 0x8B53 #CJK UNIFIED IDEOGRAPH+0xFBAC 0x8B7F #CJK UNIFIED IDEOGRAPH+0xFBAD 0x8CF0 #CJK UNIFIED IDEOGRAPH+0xFBAE 0x8CF4 #CJK UNIFIED IDEOGRAPH+0xFBAF 0x8D12 #CJK UNIFIED IDEOGRAPH+0xFBB0 0x8D76 #CJK UNIFIED IDEOGRAPH+0xFBB1 0xFA23 #CJK COMPATIBILITY IDEOGRAPH+0xFBB2 0x8ECF #CJK UNIFIED IDEOGRAPH+0xFBB3 0xFA24 #CJK COMPATIBILITY IDEOGRAPH+0xFBB4 0xFA25 #CJK COMPATIBILITY IDEOGRAPH+0xFBB5 0x9067 #CJK UNIFIED IDEOGRAPH+0xFBB6 0x90DE #CJK UNIFIED IDEOGRAPH+0xFBB7 0xFA26 #CJK COMPATIBILITY IDEOGRAPH+0xFBB8 0x9115 #CJK UNIFIED IDEOGRAPH+0xFBB9 0x9127 #CJK UNIFIED IDEOGRAPH+0xFBBA 0x91DA #CJK UNIFIED IDEOGRAPH+0xFBBB 0x91D7 #CJK UNIFIED IDEOGRAPH+0xFBBC 0x91DE #CJK UNIFIED IDEOGRAPH+0xFBBD 0x91ED #CJK UNIFIED IDEOGRAPH+0xFBBE 0x91EE #CJK UNIFIED IDEOGRAPH+0xFBBF 0x91E4 #CJK UNIFIED IDEOGRAPH+0xFBC0 0x91E5 #CJK UNIFIED IDEOGRAPH+0xFBC1 0x9206 #CJK UNIFIED IDEOGRAPH+0xFBC2 0x9210 #CJK UNIFIED IDEOGRAPH+0xFBC3 0x920A #CJK UNIFIED IDEOGRAPH+0xFBC4 0x923A #CJK UNIFIED IDEOGRAPH+0xFBC5 0x9240 #CJK UNIFIED IDEOGRAPH+0xFBC6 0x923C #CJK UNIFIED IDEOGRAPH+0xFBC7 0x924E #CJK UNIFIED IDEOGRAPH+0xFBC8 0x9259 #CJK UNIFIED IDEOGRAPH+0xFBC9 0x9251 #CJK UNIFIED IDEOGRAPH+0xFBCA 0x9239 #CJK UNIFIED IDEOGRAPH+0xFBCB 0x9267 #CJK UNIFIED IDEOGRAPH+0xFBCC 0x92A7 #CJK UNIFIED IDEOGRAPH+0xFBCD 0x9277 #CJK UNIFIED IDEOGRAPH+0xFBCE 0x9278 #CJK UNIFIED IDEOGRAPH+0xFBCF 0x92E7 #CJK UNIFIED IDEOGRAPH+0xFBD0 0x92D7 #CJK UNIFIED IDEOGRAPH+0xFBD1 0x92D9 #CJK UNIFIED IDEOGRAPH+0xFBD2 0x92D0 #CJK UNIFIED IDEOGRAPH+0xFBD3 0xFA27 #CJK COMPATIBILITY IDEOGRAPH+0xFBD4 0x92D5 #CJK UNIFIED IDEOGRAPH+0xFBD5 0x92E0 #CJK UNIFIED IDEOGRAPH+0xFBD6 0x92D3 #CJK UNIFIED IDEOGRAPH+0xFBD7 0x9325 #CJK UNIFIED IDEOGRAPH+0xFBD8 0x9321 #CJK UNIFIED IDEOGRAPH+0xFBD9 0x92FB #CJK UNIFIED IDEOGRAPH+0xFBDA 0xFA28 #CJK COMPATIBILITY IDEOGRAPH+0xFBDB 0x931E #CJK UNIFIED IDEOGRAPH+0xFBDC 0x92FF #CJK UNIFIED IDEOGRAPH+0xFBDD 0x931D #CJK UNIFIED IDEOGRAPH+0xFBDE 0x9302 #CJK UNIFIED IDEOGRAPH+0xFBDF 0x9370 #CJK UNIFIED IDEOGRAPH+0xFBE0 0x9357 #CJK UNIFIED IDEOGRAPH+0xFBE1 0x93A4 #CJK UNIFIED IDEOGRAPH+0xFBE2 0x93C6 #CJK UNIFIED IDEOGRAPH+0xFBE3 0x93DE #CJK UNIFIED IDEOGRAPH+0xFBE4 0x93F8 #CJK UNIFIED IDEOGRAPH+0xFBE5 0x9431 #CJK UNIFIED IDEOGRAPH+0xFBE6 0x9445 #CJK UNIFIED IDEOGRAPH+0xFBE7 0x9448 #CJK UNIFIED IDEOGRAPH+0xFBE8 0x9592 #CJK UNIFIED IDEOGRAPH+0xFBE9 0xF9DC #CJK COMPATIBILITY IDEOGRAPH+0xFBEA 0xFA29 #CJK COMPATIBILITY IDEOGRAPH+0xFBEB 0x969D #CJK UNIFIED IDEOGRAPH+0xFBEC 0x96AF #CJK UNIFIED IDEOGRAPH+0xFBED 0x9733 #CJK UNIFIED IDEOGRAPH+0xFBEE 0x973B #CJK UNIFIED IDEOGRAPH+0xFBEF 0x9743 #CJK UNIFIED IDEOGRAPH+0xFBF0 0x974D #CJK UNIFIED IDEOGRAPH+0xFBF1 0x974F #CJK UNIFIED IDEOGRAPH+0xFBF2 0x9751 #CJK UNIFIED IDEOGRAPH+0xFBF3 0x9755 #CJK UNIFIED IDEOGRAPH+0xFBF4 0x9857 #CJK UNIFIED IDEOGRAPH+0xFBF5 0x9865 #CJK UNIFIED IDEOGRAPH+0xFBF6 0xFA2A #CJK COMPATIBILITY IDEOGRAPH+0xFBF7 0xFA2B #CJK COMPATIBILITY IDEOGRAPH+0xFBF8 0x9927 #CJK UNIFIED IDEOGRAPH+0xFBF9 0xFA2C #CJK COMPATIBILITY IDEOGRAPH+0xFBFA 0x999E #CJK UNIFIED IDEOGRAPH+0xFBFB 0x9A4E #CJK UNIFIED IDEOGRAPH+0xFBFC 0x9AD9 #CJK UNIFIED IDEOGRAPH+0xFC40 0x9ADC #CJK UNIFIED IDEOGRAPH+0xFC41 0x9B75 #CJK UNIFIED IDEOGRAPH+0xFC42 0x9B72 #CJK UNIFIED IDEOGRAPH+0xFC43 0x9B8F #CJK UNIFIED IDEOGRAPH+0xFC44 0x9BB1 #CJK UNIFIED IDEOGRAPH+0xFC45 0x9BBB #CJK UNIFIED IDEOGRAPH+0xFC46 0x9C00 #CJK UNIFIED IDEOGRAPH+0xFC47 0x9D70 #CJK UNIFIED IDEOGRAPH+0xFC48 0x9D6B #CJK UNIFIED IDEOGRAPH+0xFC49 0xFA2D #CJK COMPATIBILITY IDEOGRAPH+0xFC4A 0x9E19 #CJK UNIFIED IDEOGRAPH+0xFC4B 0x9ED1 #CJK UNIFIED IDEOGRAPH
+ test/datafiles/unit/carolus-rex.cdtext view
binary file changed (absent → 720 bytes)
+ test/datafiles/unit/deeper-dance.cdtext view
binary file changed (absent → 684 bytes)
+ test/datafiles/unit/pearl-jam.cdtext view
binary file changed (absent → 829 bytes)
+ test/datafiles/unit/revolution-days.cdtext view
binary file changed (absent → 468 bytes)
+ test/datafiles/upstream/bad-cat1.cue view
@@ -0,0 +1,9 @@+REM $Id: bad-cat1.cue,v 1.1 2004/07/12 03:59:59 rocky Exp $+REM test catalog number - no catalog after word CATALOG++CATALOG++FILE "cdda.bin" BINARY++TRACK 01 AUDIO+ INDEX 01 00:00:00
+ test/datafiles/upstream/bad-cat1.toc view
@@ -0,0 +1,8 @@+// $Id: bad-cat1.toc,v 1.1 2004/05/08 20:36:02 rocky Exp $+// test catalog number - no catalog after word CATALOG++CATALOG++TRACK AUDIO+NO COPY+FILE "cdda.bin" 1:0:0
+ test/datafiles/upstream/bad-cat2.cue view
@@ -0,0 +1,9 @@+REM $Id: bad-cat2.cue,v 1.1 2004/07/09 20:47:08 rocky Exp $+REM test catalog number. -- not enough digits++CATALOG "167890123"++FILE "cdda.bin" BINARY++TRACK 01 AUDIO+ INDEX 01 00:00:00
+ test/datafiles/upstream/bad-cat2.toc view
@@ -0,0 +1,8 @@+// $Id: bad-cat2.toc,v 1.2 2004/07/09 20:47:08 rocky Exp $+// test catalog number. -- not enough digits++CATALOG 167890123 // Should be 13 digits++TRACK AUDIO+NO COPY+FILE "cdda.bin" 1:0:0
+ test/datafiles/upstream/bad-cat3.cue view
@@ -0,0 +1,9 @@+REM $Id: bad-cat3.cue,v 1.2 2004/07/10 01:18:02 rocky Exp $+REM test catalog number. -- invalid decimal digit++CATALOG 123456789b123++FILE "cdda.bin" BINARY++TRACK 01 AUDIO+ INDEX 01 00:00:00
+ test/datafiles/upstream/bad-cat3.toc view
@@ -0,0 +1,8 @@+// $Id: bad-cat3.toc,v 1.1 2004/05/08 20:36:02 rocky Exp $+// test catalog number - non-digit catalog name++CATALOG "123456789A123"++TRACK AUDIO+NO COPY+FILE "cdda.bin" 1:0:0
+ test/datafiles/upstream/bad-file.toc view
@@ -0,0 +1,13 @@+// $Id: bad-file.toc,v 1.1 2005/01/23 00:45:57 rocky Exp $+// XA disk +// ++CD_ROM_XA++TRACK MODE2_FORM2+FILE "foo.bin" 00:00:00 00:13:57++TRACK MODE2_FORM1+PREGAP 0:2:0+FILE "foo.bin" 00:20:71 00:00:00+
+ test/datafiles/upstream/bad-mode1.cue view
@@ -0,0 +1,7 @@+REM $Id: bad-mode1.cue,v 1.1 2004/07/10 01:18:02 rocky Exp $+REM "MODE1_FORM45" is not a valid mode.++FILE "cdda.bin" BINARY++TRACK 01 MODE3_FORM1+ INDEX 01 00:00:00
+ test/datafiles/upstream/bad-mode1.toc view
@@ -0,0 +1,5 @@+// $Id: bad-mode1.toc,v 1.1 2004/05/07 10:57:50 rocky Exp $+CD_DA++TRACK MODE1_FORM45 // "MODE1_FORM45" is not a valid mode.+SILENCE 10:0:0
+ test/datafiles/upstream/bad-msf-1.cue view
@@ -0,0 +1,7 @@+REM $Id: bad-msf-1.cue,v 1.1 2004/07/12 03:57:28 rocky Exp $+REM bad MSF in second field - frame should be less than 75++FILE "cdda.bin" BINARY++TRACK 01 AUDIO+ INDEX 01 00:00:100
+ test/datafiles/upstream/bad-msf-1.toc view
@@ -0,0 +1,6 @@+// $Id: bad-msf-1.toc,v 1.1 2004/05/07 10:57:50 rocky Exp $+// bad MSF in second field++TRACK AUDIO+NO COPY // so that all CTL flags are 0+FILE "cdda.bin" 0:0:75 // frame should be less than 75
+ test/datafiles/upstream/bad-msf-2.cue view
@@ -0,0 +1,7 @@+REM $Id: bad-msf-2.cue,v 1.1 2004/07/10 01:18:02 rocky Exp $+REM bad MSF in second field - seconds should be less than 60++FILE "cdda.bin" BINARY++TRACK 01 AUDIO+ INDEX 01 00:90:00
+ test/datafiles/upstream/bad-msf-2.toc view
@@ -0,0 +1,6 @@+// $Id: bad-msf-2.toc,v 1.1 2004/05/07 10:57:50 rocky Exp $+// bad MSF in second field++TRACK AUDIO+NO COPY // so that all CTL flags are 0+FILE "cdda.bin" 0:60:0 // seconds should be less than 60
+ test/datafiles/upstream/bad-msf-3.cue view
@@ -0,0 +1,7 @@+REM $Id: bad-msf-3.cue,v 1.1 2004/07/12 03:58:55 rocky Exp $+REM bad MSF in second field ++FILE "cdda.bin" BINARY++TRACK 01 AUDIO+ INDEX 01 xx:yy:0
+ test/datafiles/upstream/bad-msf-3.toc view
@@ -0,0 +1,6 @@+// $Id: bad-msf-3.toc,v 1.1 2004/07/10 01:18:02 rocky Exp $+// bad MSF in second field++TRACK AUDIO+NO COPY // so that all CTL flags are 0+FILE "cdda.bin" xx:yy:zz // Should be digits
+ test/datafiles/upstream/cdda.bin view
binary file changed (absent → 710304 bytes)
+ test/datafiles/upstream/cdda.cue view
@@ -0,0 +1,9 @@+TITLE "Join us now we have the software" +CATALOG 0000010271955 +PERFORMER "Richard Stallman" +FILE "CDDA.BIN" BINARY + TRACK 01 AUDIO + TITLE "Soft" + PERFORMER "Richard S" + FLAGS DCP + INDEX 01 00:00:00
+ test/datafiles/upstream/cdtext.toc view
@@ -0,0 +1,48 @@+CD_DA++// global CD-TEXT data++CD_TEXT {++ // Mapping from language number (0..7) used in 'LANGUAGE' statements + // to language code.+/// LANGUAGE_MAP {+/// 0 : EN // 9 is the code for ENGLISH,+/// // I don't know any other language code, yet+/// }++ // Language number should always start with 0+ LANGUAGE 0 {+ // Required fields - at least all CD-TEXT CDs I've seen so far have them.+ TITLE "Join us now we have the software"+ PERFORMER "Richard Stallman"+ DISC_ID "0000010271955"+ UPC_EAN "" // usually empty++ // Further possible items, all of them are optional+ ARRANGER ""+ SONGWRITER ""+ MESSAGE "" + GENRE "" // I'm not sure if this should be really ascii data+ }+}+++TRACK AUDIO+// track specific CD-TEXT data+CD_TEXT {+ LANGUAGE 0 {+ // if an item is defined for one track it should be defined for all tracks+ TITLE "Soft"++ PERFORMER "Richard S"+ ISRC "US-XX1-98-01234"++ ARRANGER ""+ SONGWRITER ""+ MESSAGE "" + }+}++SILENCE 1:0:0+
+ test/datafiles/upstream/data1.toc view
@@ -0,0 +1,8 @@+// $Id: data1.toc,v 1.1 2004/05/08 20:36:02 rocky Exp $+// Just a single MODE1 track.++CD_ROM++TRACK MODE1+SILENCE 0:59:74+
+ test/datafiles/upstream/data2.toc view
@@ -0,0 +1,13 @@+// $Id+// MODE1 track followed by an AUDIO track++CD_ROM++TRACK MODE1+FILE "isofs-m1.bin" 00:00:00 +ZERO 1:0:0++TRACK AUDIO+PREGAP 0:2:0+FILE "cdda.bin" 00:00:00 +
+ test/datafiles/upstream/data5.toc view
@@ -0,0 +1,13 @@+// $Id: data5.toc,v 1.2 2005/01/23 00:45:57 rocky Exp $+// XA disk +// ++CD_ROM_XA++TRACK MODE2_FORM2+FILE "isofs-m1.bin" 00:00:00 00:01:57++TRACK MODE2_FORM1+PREGAP 0:2:0+FILE "isofs-m1.bin" 00:20:71 00:00:10+
+ test/datafiles/upstream/data6.toc view
@@ -0,0 +1,8 @@+// $Id: data6.toc,v 1.2 2005/01/23 00:45:57 rocky Exp $+// MODE2 track+// ++CD_ROM++TRACK MODE2+FILE "isofs-m1.bin" 00:00:00 00:01:57
+ test/datafiles/upstream/data7.toc view
@@ -0,0 +1,13 @@+// $Id: data7.toc,v 1.2 2005/01/23 00:45:57 rocky Exp $+// Video CD+// ++CD_ROM_XA++TRACK MODE1 // ISO filesystem+FILE "isofs-m1.bin" 00:00:00 00:03:57++TRACK MODE2_FORM_MIX // XA track with form 1 and form 2 sectors+PREGAP 0:2:0+FILE "isofs-m1.bin" 00:20:71 00:00:00+
+ test/datafiles/upstream/isofs-m1.bin view
binary file changed (absent → 710304 bytes)
+ test/datafiles/upstream/isofs-m1.cue view
@@ -0,0 +1,4 @@+CATALOG 0000012101954 +FILE "ISOFS-M1.BIN" BINARY + TRACK 01 MODE1/2352 + INDEX 01 00:00:00
+ test/datafiles/upstream/p1.bin view
binary file changed (absent → 710304 bytes)
+ test/datafiles/upstream/p1.cue view
@@ -0,0 +1,12 @@+TITLE "Join us now we have the software" +CATALOG 0000010271955 +PERFORMER "Richard Stallman" +FILE "BOING.BIN" BINARY + TRACK 01 AUDIO + FLAGS DCP + INDEX 00 00:00:00 + INDEX 01 00:01:00 + TRACK 02 AUDIO + FLAGS DCP + INDEX 00 00:02:00 + INDEX 01 00:03:00
+ test/datafiles/upstream/p1.nrg view
binary file changed (absent → 1063470 bytes)
+ test/datafiles/upstream/t1.toc view
@@ -0,0 +1,5 @@+// simplest cue sheet++TRACK AUDIO+NO COPY // so that all CTL flags are 0+SILENCE 0:0:74 // frames are just under 75
+ test/datafiles/upstream/t10.toc view
@@ -0,0 +1,8 @@+// non default CTL flag of track 1 ++TRACK AUDIO+COPY+NO PRE_EMPHASIS+FOUR_CHANNEL_AUDIO+FILE "cdda.bin" 1:0:0+
+ test/datafiles/upstream/t2.toc view
@@ -0,0 +1,6 @@+// additional pre-gap for track 1++TRACK AUDIO+NO COPY // so that all CTL flags are 0+FILE "cdda.bin" 0:59:0 // Seconds are just under 60+START 0:10:0 // 10 second pre-gap
+ test/datafiles/upstream/t3.toc view
@@ -0,0 +1,11 @@+// simplest cue sheet for two tracks++TRACK AUDIO+NO COPY // so that all CTL flags are 0+FILE "cdda.bin" 180:0:0 // 180 for number of minutes is okay, although+ // it is not for a second or a frame value.++TRACK AUDIO+NO COPY // so that all CTL flags are 0+FILE "cdda.bin" 1:0:0+
+ test/datafiles/upstream/t4.toc view
@@ -0,0 +1,8 @@+// non default CTL flag of track 1 ++TRACK AUDIO+COPY+PRE_EMPHASIS+FOUR_CHANNEL_AUDIO+FILE "cdda.bin" 1:0:0+
+ test/datafiles/upstream/t5.toc view
@@ -0,0 +1,8 @@+// test catalog number++CATALOG "1234567890123"++TRACK AUDIO+NO COPY+FILE "cdda.bin" 1:0:0+
+ test/datafiles/upstream/t6.toc view
@@ -0,0 +1,7 @@+// test ISRC code+++TRACK AUDIO+NO COPY+ISRC "DEMUA9800001"+FILE "cdda.bin" 1:0:0
+ test/datafiles/upstream/t7.toc view
@@ -0,0 +1,12 @@+// check two tracks with pre-gap and ISRC+++TRACK AUDIO+NO COPY+FILE "cdda.bin" 1:0:0++TRACK AUDIO+NO COPY+ISRC "DEMUA9800001"+FILE "cdda.bin" 1:0:0+START 0:5:0 // pre-gap
+ test/datafiles/upstream/t8.toc view
@@ -0,0 +1,14 @@+// check index increments+++TRACK AUDIO+NO COPY+FILE "cdda.bin" 0:10:0+INDEX 1:0:0+INDEX 2:0:0+++TRACK AUDIO+NO COPY+FILE "cdda.bin" 0:10:0+START 0:5:0 // pre-gap
+ test/datafiles/upstream/t9.toc view
@@ -0,0 +1,31 @@+CD_DA+// check mulitple tracks+CATALOG "0724385356926"++TRACK AUDIO+ISRC "USEM39600078"+COPY+FILE "cdda.bin" 0:10:0+START 0:5:0++TRACK AUDIO+NO COPY+ISRC "USEM39600079"+FILE "cdda.bin" 0:10:0+START 0:2:0++TRACK AUDIO+COPY+FILE "cdda.bin" 0:10:0+START 0:1:30++TRACK AUDIO+NO COPY+START 0:0:0+FILE "cdda.bin" 0:10:0++TRACK AUDIO+ISRC "EDUMA9892346"+NO COPY+FILE "cdda.bin" 0:10:0+START 0:2:1
+ test/datafiles/upstream/vcd2.toc view
@@ -0,0 +1,22 @@+// Taken from one of Steve Schultz's VCD collection. +// The .bin and offsets have been changed and are wrong. +CD_ROM_XA+++// Track 1+TRACK MODE2_FORM_MIX+COPY+DATAFILE "cdda.bin" 00:00:00 // comment+++// Track 2+TRACK MODE2_FORM_MIX+COPY+DATAFILE "cdda.bin" #100 00:00:03 +++// Track 3+TRACK MODE2_FORM_MIX+COPY+DATAFILE "cdda.bin" #200 00:00:25 +