summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore23
-rw-r--r--AUTHORS1
-rw-r--r--COPYING510
-rw-r--r--ChangeLog0
-rw-r--r--INSTALL302
-rw-r--r--Makefile.am3
-rw-r--r--NEWS0
-rw-r--r--README29
-rw-r--r--TODO7
-rw-r--r--configure.ac35
-rw-r--r--data/A.1396
-rw-r--r--data/B.127
-rw-r--r--data/B.21371
-rw-r--r--data/B.3838
-rw-r--r--data/C.1.11
-rw-r--r--data/C.1.217
-rw-r--r--data/C.2.12
-rw-r--r--data/C.2.216
-rw-r--r--data/C.33
-rw-r--r--data/C.418
-rw-r--r--data/C.51
-rw-r--r--data/C.65
-rw-r--r--data/C.71
-rw-r--r--data/C.815
-rw-r--r--data/C.92
-rw-r--r--data/D.134
-rw-r--r--data/D.2360
-rw-r--r--data/Makefile.am22
-rwxr-xr-xdata/extract-table.pl18
-rw-r--r--doc/Makefile.am1
-rw-r--r--doc/rfc3454.txt3249
-rw-r--r--gen/.gitignore2
-rw-r--r--gen/Makefile.am29
-rw-r--r--gen/cset.c238
-rw-r--r--gen/cset.h56
-rw-r--r--gen/map.c90
-rw-r--r--gen/map.h54
-rw-r--r--gen/mapping-rep.c406
-rw-r--r--gen/mapping-rep.h68
-rw-r--r--gen/parser.c271
-rw-r--r--gen/parser.h52
-rw-r--r--gen/srcgen-cset.c130
-rw-r--r--gen/srcgen-maps.c258
-rw-r--r--m4/.gitignore2
-rw-r--r--preppie/.gitignore1
-rw-r--r--preppie/Makefile.am55
-rw-r--r--preppie/built/.gitignore1
-rw-r--r--preppie/builtin-tables.h42
-rw-r--r--preppie/internal.h40
-rw-r--r--preppie/preppie.pc.in12
-rw-r--r--preppie/profile-format.h110
-rw-r--r--preppie/sprep.c561
-rw-r--r--preppie/sprep.h67
-rw-r--r--tests/Makefile.am0
-rw-r--r--tests/internal/test-gen-cset.c90
55 files changed, 9942 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..0881eee
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,23 @@
+*.la
+*.lo
+*.o
+.deps/
+.libs/
+Makefile
+Makefile.in
+
+/aclocal.m4
+/autom4te.cache/
+/config.guess
+/config.h
+/config.h.in
+/config.log
+/config.status
+/config.sub
+/configure
+/depcomp
+/install-sh
+/libtool
+/ltmain.sh
+/missing
+/stamp-h1
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..a44ebfb
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1 @@
+Mikhail Zabaluev <mikhail.zabaluev@gmail.com>
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..2d2d780
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,510 @@
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations
+below.
+
+ When we speak of free software, we are referring to freedom of use,
+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 this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it
+becomes a de-facto standard. To achieve this, non-free programs must
+be allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control
+compilation and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at least
+ three years, to give the same user the materials specified in
+ Subsection 6a, above, for a charge no more than the cost of
+ performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+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
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply, and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License
+may add an explicit geographical distribution limitation excluding those
+countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser 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 Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "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
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY 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
+LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms
+of the ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library.
+It is safest to attach them to the start of each source file to most
+effectively convey 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 library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or
+your school, if any, to sign a "copyright disclaimer" for the library,
+if necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James
+ Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/ChangeLog
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 0000000..2550dab
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,302 @@
+Installation Instructions
+*************************
+
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
+2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+
+ This file is free documentation; the Free Software Foundation gives
+unlimited permission to copy, distribute and modify it.
+
+Basic Installation
+==================
+
+ Briefly, the shell commands `./configure; make; make install' should
+configure, build, and install this package. The following
+more-detailed instructions are generic; see the `README' file for
+instructions specific to this package.
+
+ The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation. It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions. Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+ It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring. Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.
+
+ If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release. If you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+ The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'. You need `configure.ac' if
+you want to change it or regenerate `configure' using a newer version
+of `autoconf'.
+
+The simplest way to compile this package is:
+
+ 1. `cd' to the directory containing the package's source code and type
+ `./configure' to configure the package for your system.
+
+ Running `configure' might take a while. While running, it prints
+ some messages telling which features it is checking for.
+
+ 2. Type `make' to compile the package.
+
+ 3. Optionally, type `make check' to run any self-tests that come with
+ the package.
+
+ 4. Type `make install' to install the programs and any data files and
+ documentation.
+
+ 5. You can remove the program binaries and object files from the
+ source code directory by typing `make clean'. To also remove the
+ files that `configure' created (so you can compile the package for
+ a different kind of computer), type `make distclean'. There is
+ also a `make maintainer-clean' target, but that is intended mainly
+ for the package's developers. If you use it, you may have to get
+ all sorts of other programs in order to regenerate files that came
+ with the distribution.
+
+ 6. Often, you can also type `make uninstall' to remove the installed
+ files again.
+
+Compilers and Options
+=====================
+
+ Some systems require unusual options for compilation or linking that
+the `configure' script does not know about. Run `./configure --help'
+for details on some of the pertinent environment variables.
+
+ You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment. Here
+is an example:
+
+ ./configure CC=c99 CFLAGS=-g LIBS=-lposix
+
+ *Note Defining Variables::, for more details.
+
+Compiling For Multiple Architectures
+====================================
+
+ You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory. To do this, you can use GNU `make'. `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script. `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+ With a non-GNU `make', it is safer to compile the package for one
+architecture at a time in the source code directory. After you have
+installed the package for one architecture, use `make distclean' before
+reconfiguring for another architecture.
+
+ On MacOS X 10.5 and later systems, you can create libraries and
+executables that work on multiple system types--known as "fat" or
+"universal" binaries--by specifying multiple `-arch' options to the
+compiler but only a single `-arch' option to the preprocessor. Like
+this:
+
+ ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
+ CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
+ CPP="gcc -E" CXXCPP="g++ -E"
+
+ This is not guaranteed to produce working output in all cases, you
+may have to build one architecture at a time and combine the results
+using the `lipo' tool if you have problems.
+
+Installation Names
+==================
+
+ By default, `make install' installs the package's commands under
+`/usr/local/bin', include files under `/usr/local/include', etc. You
+can specify an installation prefix other than `/usr/local' by giving
+`configure' the option `--prefix=PREFIX'.
+
+ You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files. If you
+pass the option `--exec-prefix=PREFIX' to `configure', the package uses
+PREFIX as the prefix for installing programs and libraries.
+Documentation and other data files still use the regular prefix.
+
+ In addition, if you use an unusual directory layout you can give
+options like `--bindir=DIR' to specify different values for particular
+kinds of files. Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.
+
+ If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+ Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System). The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+ For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Particular systems
+==================
+
+ On HP-UX, the default C compiler is not ANSI C compatible. If GNU
+CC is not installed, it is recommended to use the following options in
+order to use an ANSI C compiler:
+
+ ./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
+
+and if that doesn't work, install pre-built binaries of GCC for HP-UX.
+
+ On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
+parse its `<wchar.h>' header file. The option `-nodtk' can be used as
+a workaround. If GNU CC is not installed, it is therefore recommended
+to try
+
+ ./configure CC="cc"
+
+and if that doesn't work, try
+
+ ./configure CC="cc -nodtk"
+
+ On Solaris, don't put `/usr/ucb' early in your `PATH'. This
+directory contains several dysfunctional programs; working variants of
+these programs are available in `/usr/bin'. So, if you need `/usr/ucb'
+in your `PATH', put it _after_ `/usr/bin'.
+
+ On Haiku, software installed for all users goes in `/boot/common',
+not `/usr/local'. It is recommended to use the following options:
+
+ ./configure --prefix=/boot/common
+
+Specifying the System Type
+==========================
+
+ There may be some features `configure' cannot figure out
+automatically, but needs to determine by the type of machine the package
+will run on. Usually, assuming the package is built to be run on the
+_same_ architectures, `configure' can figure that out, but if it prints
+a message saying it cannot guess the machine type, give it the
+`--build=TYPE' option. TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
+ CPU-COMPANY-SYSTEM
+
+where SYSTEM can have one of these forms:
+
+ OS
+ KERNEL-OS
+
+ See the file `config.sub' for the possible values of each field. If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the machine type.
+
+ If you are _building_ compiler tools for cross-compiling, you should
+use the option `--target=TYPE' to select the type of system they will
+produce code for.
+
+ If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
+
+Sharing Defaults
+================
+
+ If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists. Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Defining Variables
+==================
+
+ Variables not defined in a site shell script can be set in the
+environment passed to `configure'. However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost. In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'. For example:
+
+ ./configure CC=/usr/local2/bin/gcc
+
+causes the specified `gcc' to be used as the C compiler (unless it is
+overridden in the site shell script).
+
+Unfortunately, this technique does not work for `CONFIG_SHELL' due to
+an Autoconf bug. Until the bug is fixed you can use this workaround:
+
+ CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
+
+`configure' Invocation
+======================
+
+ `configure' recognizes the following options to control how it
+operates.
+
+`--help'
+`-h'
+ Print a summary of all of the options to `configure', and exit.
+
+`--help=short'
+`--help=recursive'
+ Print a summary of the options unique to this package's
+ `configure', and exit. The `short' variant lists options used
+ only in the top level, while the `recursive' variant lists options
+ also present in any nested packages.
+
+`--version'
+`-V'
+ Print the version of Autoconf used to generate the `configure'
+ script, and exit.
+
+`--cache-file=FILE'
+ Enable the cache: use and save the results of the tests in FILE,
+ traditionally `config.cache'. FILE defaults to `/dev/null' to
+ disable caching.
+
+`--config-cache'
+`-C'
+ Alias for `--cache-file=config.cache'.
+
+`--quiet'
+`--silent'
+`-q'
+ Do not print messages saying which checks are being made. To
+ suppress all normal output, redirect it to `/dev/null' (any error
+ messages will still be shown).
+
+`--srcdir=DIR'
+ Look for the package's source code in directory DIR. Usually
+ `configure' can determine that directory automatically.
+
+`--prefix=DIR'
+ Use DIR as the installation prefix. *Note Installation Names::
+ for more details, including other options available for fine-tuning
+ the installation locations.
+
+`--no-create'
+`-n'
+ Run the configure checks, but stop before creating any output
+ files.
+
+`configure' also accepts some other, not widely useful, options. Run
+`configure --help' for more details.
+
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..27eab40
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,3 @@
+SUBDIRS = gen preppie data doc tests
+
+ACLOCAL_AMFLAGS = -I m4
diff --git a/NEWS b/NEWS
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/NEWS
diff --git a/README b/README
new file mode 100644
index 0000000..35fbd37
--- /dev/null
+++ b/README
@@ -0,0 +1,29 @@
+Preppie is a fast and resource-efficient implementation of Stringprep
+(RFC 3454), a framework for preparation of international characters.
+Stringprep profiles are used, in particular, in the International Domain Names
+specification, and the XMPP protocol.
+
+The library itself, the generation tools, and other auxiliary files
+are licensed under GNU Lesser General Public License version 2.1 or later,
+with an exception below. See the file COPYING for the license text.
+The file doc/rfc3454.txt is the exception; see the file contents for details.
+
+Design Goals
+------------
+
+- Support the full character code range of Unicode UCS4. The UTF-8 encoding
+ is used for input and output.
+- Easily customizable to new profiles with a bundled profile generator tool.
+- String preparation uses static non-modifiable data from a memory-mapped file.
+- The timing characteristics of the preparation routine are optimized to be
+ indifferent to the number of tables referenced in the specification
+ of the profile. The effective tables are composed during profile generation,
+ not at runtime.
+- Offer good locality of table accesses for efficiency in memory mapping and
+ data cache.
+- Use the fact that some character mapping sequences repeat or contain others,
+ saving some space for mapping data.
+- In the default installation, bundle all IANA-registered profiles.
+- The test suite thoroughly covers string preparation with storage and
+ query modes, correctness of the profile generator and the bundled profiles.
+- Written in C using GLib.
diff --git a/TODO b/TODO
new file mode 100644
index 0000000..3b088bc
--- /dev/null
+++ b/TODO
@@ -0,0 +1,7 @@
+PROBLEMS
+--------
+
+- We are using the normalization function from GLib which implements
+ some recent Unicode version, contrary to RFC 3454 Section 4 which demands
+ normalization accordingly to the Unicode version fixed in the profile.
+ We should see if it causes any practical problems.
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..d49e361
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,35 @@
+AC_INIT([preppie], [0.0.1])
+AM_INIT_AUTOMAKE([silent-rules])
+
+AC_SUBST(PREPPIE_API_VERSION, [1.0])
+
+if test x"$PREPPIE_PROFILE_DIR" = x; then
+ PREPPIE_PROFILE_DIR="\${pkglibdir}/profiles"
+fi
+AC_SUBST(PREPPIE_PROFILE_DIR)
+
+AC_CONFIG_MACRO_DIR([m4])
+
+AC_CONFIG_HEADERS([config.h])
+
+AC_PROG_CC
+AC_PROG_LIBTOOL
+
+if test x"$GCC" = xyes; then
+ CFLAGS="$CFLAGS -Wall -Werror"
+fi
+
+AC_SUBST(GLIB_PKG_DEPS, ['glib-2.0 >= 2.16'])
+
+PKG_CHECK_MODULES([GLIB], [$GLIB_PKG_DEPS])
+
+AC_CONFIG_FILES([
+ Makefile
+ data/Makefile
+ doc/Makefile
+ gen/Makefile
+ preppie/Makefile
+ preppie/preppie.pc
+ tests/Makefile
+])
+AC_OUTPUT
diff --git a/data/A.1 b/data/A.1
new file mode 100644
index 0000000..de1b6f9
--- /dev/null
+++ b/data/A.1
@@ -0,0 +1,396 @@
+0221
+0234-024F
+02AE-02AF
+02EF-02FF
+0350-035F
+0370-0373
+0376-0379
+037B-037D
+037F-0383
+038B
+038D
+03A2
+03CF
+03F7-03FF
+0487
+04CF
+04F6-04F7
+04FA-04FF
+0510-0530
+0557-0558
+0560
+0588
+058B-0590
+05A2
+05BA
+05C5-05CF
+05EB-05EF
+05F5-060B
+060D-061A
+061C-061E
+0620
+063B-063F
+0656-065F
+06EE-06EF
+06FF
+070E
+072D-072F
+074B-077F
+07B2-0900
+0904
+093A-093B
+094E-094F
+0955-0957
+0971-0980
+0984
+098D-098E
+0991-0992
+09A9
+09B1
+09B3-09B5
+09BA-09BB
+09BD
+09C5-09C6
+09C9-09CA
+09CE-09D6
+09D8-09DB
+09DE
+09E4-09E5
+09FB-0A01
+0A03-0A04
+0A0B-0A0E
+0A11-0A12
+0A29
+0A31
+0A34
+0A37
+0A3A-0A3B
+0A3D
+0A43-0A46
+0A49-0A4A
+0A4E-0A58
+0A5D
+0A5F-0A65
+0A75-0A80
+0A84
+0A8C
+0A8E
+0A92
+0AA9
+0AB1
+0AB4
+0ABA-0ABB
+0AC6
+0ACA
+0ACE-0ACF
+0AD1-0ADF
+0AE1-0AE5
+0AF0-0B00
+0B04
+0B0D-0B0E
+0B11-0B12
+0B29
+0B31
+0B34-0B35
+0B3A-0B3B
+0B44-0B46
+0B49-0B4A
+0B4E-0B55
+0B58-0B5B
+0B5E
+0B62-0B65
+0B71-0B81
+0B84
+0B8B-0B8D
+0B91
+0B96-0B98
+0B9B
+0B9D
+0BA0-0BA2
+0BA5-0BA7
+0BAB-0BAD
+0BB6
+0BBA-0BBD
+0BC3-0BC5
+0BC9
+0BCE-0BD6
+0BD8-0BE6
+0BF3-0C00
+0C04
+0C0D
+0C11
+0C29
+0C34
+0C3A-0C3D
+0C45
+0C49
+0C4E-0C54
+0C57-0C5F
+0C62-0C65
+0C70-0C81
+0C84
+0C8D
+0C91
+0CA9
+0CB4
+0CBA-0CBD
+0CC5
+0CC9
+0CCE-0CD4
+0CD7-0CDD
+0CDF
+0CE2-0CE5
+0CF0-0D01
+0D04
+0D0D
+0D11
+0D29
+0D3A-0D3D
+0D44-0D45
+0D49
+0D4E-0D56
+0D58-0D5F
+0D62-0D65
+0D70-0D81
+0D84
+0D97-0D99
+0DB2
+0DBC
+0DBE-0DBF
+0DC7-0DC9
+0DCB-0DCE
+0DD5
+0DD7
+0DE0-0DF1
+0DF5-0E00
+0E3B-0E3E
+0E5C-0E80
+0E83
+0E85-0E86
+0E89
+0E8B-0E8C
+0E8E-0E93
+0E98
+0EA0
+0EA4
+0EA6
+0EA8-0EA9
+0EAC
+0EBA
+0EBE-0EBF
+0EC5
+0EC7
+0ECE-0ECF
+0EDA-0EDB
+0EDE-0EFF
+0F48
+0F6B-0F70
+0F8C-0F8F
+0F98
+0FBD
+0FCD-0FCE
+0FD0-0FFF
+1022
+1028
+102B
+1033-1035
+103A-103F
+105A-109F
+10C6-10CF
+10F9-10FA
+10FC-10FF
+115A-115E
+11A3-11A7
+11FA-11FF
+1207
+1247
+1249
+124E-124F
+1257
+1259
+125E-125F
+1287
+1289
+128E-128F
+12AF
+12B1
+12B6-12B7
+12BF
+12C1
+12C6-12C7
+12CF
+12D7
+12EF
+130F
+1311
+1316-1317
+131F
+1347
+135B-1360
+137D-139F
+13F5-1400
+1677-167F
+169D-169F
+16F1-16FF
+170D
+1715-171F
+1737-173F
+1754-175F
+176D
+1771
+1774-177F
+17DD-17DF
+17EA-17FF
+180F
+181A-181F
+1878-187F
+18AA-1DFF
+1E9C-1E9F
+1EFA-1EFF
+1F16-1F17
+1F1E-1F1F
+1F46-1F47
+1F4E-1F4F
+1F58
+1F5A
+1F5C
+1F5E
+1F7E-1F7F
+1FB5
+1FC5
+1FD4-1FD5
+1FDC
+1FF0-1FF1
+1FF5
+1FFF
+2053-2056
+2058-205E
+2064-2069
+2072-2073
+208F-209F
+20B2-20CF
+20EB-20FF
+213B-213C
+214C-2152
+2184-218F
+23CF-23FF
+2427-243F
+244B-245F
+24FF
+2614-2615
+2618
+267E-267F
+268A-2700
+2705
+270A-270B
+2728
+274C
+274E
+2753-2755
+2757
+275F-2760
+2795-2797
+27B0
+27BF-27CF
+27EC-27EF
+2B00-2E7F
+2E9A
+2EF4-2EFF
+2FD6-2FEF
+2FFC-2FFF
+3040
+3097-3098
+3100-3104
+312D-3130
+318F
+31B8-31EF
+321D-321F
+3244-3250
+327C-327E
+32CC-32CF
+32FF
+3377-337A
+33DE-33DF
+33FF
+4DB6-4DFF
+9FA6-9FFF
+A48D-A48F
+A4C7-ABFF
+D7A4-D7FF
+FA2E-FA2F
+FA6B-FAFF
+FB07-FB12
+FB18-FB1C
+FB37
+FB3D
+FB3F
+FB42
+FB45
+FBB2-FBD2
+FD40-FD4F
+FD90-FD91
+FDC8-FDCF
+FDFD-FDFF
+FE10-FE1F
+FE24-FE2F
+FE47-FE48
+FE53
+FE67
+FE6C-FE6F
+FE75
+FEFD-FEFE
+FF00
+FFBF-FFC1
+FFC8-FFC9
+FFD0-FFD1
+FFD8-FFD9
+FFDD-FFDF
+FFE7
+FFEF-FFF8
+10000-102FF
+1031F
+10324-1032F
+1034B-103FF
+10426-10427
+1044E-1CFFF
+1D0F6-1D0FF
+1D127-1D129
+1D1DE-1D3FF
+1D455
+1D49D
+1D4A0-1D4A1
+1D4A3-1D4A4
+1D4A7-1D4A8
+1D4AD
+1D4BA
+1D4BC
+1D4C1
+1D4C4
+1D506
+1D50B-1D50C
+1D515
+1D51D
+1D53A
+1D53F
+1D545
+1D547-1D549
+1D551
+1D6A4-1D6A7
+1D7CA-1D7CD
+1D800-1FFFD
+2A6D7-2F7FF
+2FA1E-2FFFD
+30000-3FFFD
+40000-4FFFD
+50000-5FFFD
+60000-6FFFD
+70000-7FFFD
+80000-8FFFD
+90000-9FFFD
+A0000-AFFFD
+B0000-BFFFD
+C0000-CFFFD
+D0000-DFFFD
+E0000
+E0002-E001F
+E0080-EFFFD
diff --git a/data/B.1 b/data/B.1
new file mode 100644
index 0000000..f5bb616
--- /dev/null
+++ b/data/B.1
@@ -0,0 +1,27 @@
+00AD; ; Map to nothing
+034F; ; Map to nothing
+1806; ; Map to nothing
+180B; ; Map to nothing
+180C; ; Map to nothing
+180D; ; Map to nothing
+200B; ; Map to nothing
+200C; ; Map to nothing
+200D; ; Map to nothing
+2060; ; Map to nothing
+FE00; ; Map to nothing
+FE01; ; Map to nothing
+FE02; ; Map to nothing
+FE03; ; Map to nothing
+FE04; ; Map to nothing
+FE05; ; Map to nothing
+FE06; ; Map to nothing
+FE07; ; Map to nothing
+FE08; ; Map to nothing
+FE09; ; Map to nothing
+FE0A; ; Map to nothing
+FE0B; ; Map to nothing
+FE0C; ; Map to nothing
+FE0D; ; Map to nothing
+FE0E; ; Map to nothing
+FE0F; ; Map to nothing
+FEFF; ; Map to nothing
diff --git a/data/B.2 b/data/B.2
new file mode 100644
index 0000000..af50d65
--- /dev/null
+++ b/data/B.2
@@ -0,0 +1,1371 @@
+0041; 0061; Case map
+0042; 0062; Case map
+0043; 0063; Case map
+0044; 0064; Case map
+0045; 0065; Case map
+0046; 0066; Case map
+0047; 0067; Case map
+0048; 0068; Case map
+0049; 0069; Case map
+004A; 006A; Case map
+004B; 006B; Case map
+004C; 006C; Case map
+004D; 006D; Case map
+004E; 006E; Case map
+004F; 006F; Case map
+0050; 0070; Case map
+0051; 0071; Case map
+0052; 0072; Case map
+0053; 0073; Case map
+0054; 0074; Case map
+0055; 0075; Case map
+0056; 0076; Case map
+0057; 0077; Case map
+0058; 0078; Case map
+0059; 0079; Case map
+005A; 007A; Case map
+00B5; 03BC; Case map
+00C0; 00E0; Case map
+00C1; 00E1; Case map
+00C2; 00E2; Case map
+00C3; 00E3; Case map
+00C4; 00E4; Case map
+00C5; 00E5; Case map
+00C6; 00E6; Case map
+00C7; 00E7; Case map
+00C8; 00E8; Case map
+00C9; 00E9; Case map
+00CA; 00EA; Case map
+00CB; 00EB; Case map
+00CC; 00EC; Case map
+00CD; 00ED; Case map
+00CE; 00EE; Case map
+00CF; 00EF; Case map
+00D0; 00F0; Case map
+00D1; 00F1; Case map
+00D2; 00F2; Case map
+00D3; 00F3; Case map
+00D4; 00F4; Case map
+00D5; 00F5; Case map
+00D6; 00F6; Case map
+00D8; 00F8; Case map
+00D9; 00F9; Case map
+00DA; 00FA; Case map
+00DB; 00FB; Case map
+00DC; 00FC; Case map
+00DD; 00FD; Case map
+00DE; 00FE; Case map
+00DF; 0073 0073; Case map
+0100; 0101; Case map
+0102; 0103; Case map
+0104; 0105; Case map
+0106; 0107; Case map
+0108; 0109; Case map
+010A; 010B; Case map
+010C; 010D; Case map
+010E; 010F; Case map
+0110; 0111; Case map
+0112; 0113; Case map
+0114; 0115; Case map
+0116; 0117; Case map
+0118; 0119; Case map
+011A; 011B; Case map
+011C; 011D; Case map
+011E; 011F; Case map
+0120; 0121; Case map
+0122; 0123; Case map
+0124; 0125; Case map
+0126; 0127; Case map
+0128; 0129; Case map
+012A; 012B; Case map
+012C; 012D; Case map
+012E; 012F; Case map
+0130; 0069 0307; Case map
+0132; 0133; Case map
+0134; 0135; Case map
+0136; 0137; Case map
+0139; 013A; Case map
+013B; 013C; Case map
+013D; 013E; Case map
+013F; 0140; Case map
+0141; 0142; Case map
+0143; 0144; Case map
+0145; 0146; Case map
+0147; 0148; Case map
+0149; 02BC 006E; Case map
+014A; 014B; Case map
+014C; 014D; Case map
+014E; 014F; Case map
+0150; 0151; Case map
+0152; 0153; Case map
+0154; 0155; Case map
+0156; 0157; Case map
+0158; 0159; Case map
+015A; 015B; Case map
+015C; 015D; Case map
+015E; 015F; Case map
+0160; 0161; Case map
+0162; 0163; Case map
+0164; 0165; Case map
+0166; 0167; Case map
+0168; 0169; Case map
+016A; 016B; Case map
+016C; 016D; Case map
+016E; 016F; Case map
+0170; 0171; Case map
+0172; 0173; Case map
+0174; 0175; Case map
+0176; 0177; Case map
+0178; 00FF; Case map
+0179; 017A; Case map
+017B; 017C; Case map
+017D; 017E; Case map
+017F; 0073; Case map
+0181; 0253; Case map
+0182; 0183; Case map
+0184; 0185; Case map
+0186; 0254; Case map
+0187; 0188; Case map
+0189; 0256; Case map
+018A; 0257; Case map
+018B; 018C; Case map
+018E; 01DD; Case map
+018F; 0259; Case map
+0190; 025B; Case map
+0191; 0192; Case map
+0193; 0260; Case map
+0194; 0263; Case map
+0196; 0269; Case map
+0197; 0268; Case map
+0198; 0199; Case map
+019C; 026F; Case map
+019D; 0272; Case map
+019F; 0275; Case map
+01A0; 01A1; Case map
+01A2; 01A3; Case map
+01A4; 01A5; Case map
+01A6; 0280; Case map
+01A7; 01A8; Case map
+01A9; 0283; Case map
+01AC; 01AD; Case map
+01AE; 0288; Case map
+01AF; 01B0; Case map
+01B1; 028A; Case map
+01B2; 028B; Case map
+01B3; 01B4; Case map
+01B5; 01B6; Case map
+01B7; 0292; Case map
+01B8; 01B9; Case map
+01BC; 01BD; Case map
+01C4; 01C6; Case map
+01C5; 01C6; Case map
+01C7; 01C9; Case map
+01C8; 01C9; Case map
+01CA; 01CC; Case map
+01CB; 01CC; Case map
+01CD; 01CE; Case map
+01CF; 01D0; Case map
+01D1; 01D2; Case map
+01D3; 01D4; Case map
+01D5; 01D6; Case map
+01D7; 01D8; Case map
+01D9; 01DA; Case map
+01DB; 01DC; Case map
+01DE; 01DF; Case map
+01E0; 01E1; Case map
+01E2; 01E3; Case map
+01E4; 01E5; Case map
+01E6; 01E7; Case map
+01E8; 01E9; Case map
+01EA; 01EB; Case map
+01EC; 01ED; Case map
+01EE; 01EF; Case map
+01F0; 006A 030C; Case map
+01F1; 01F3; Case map
+01F2; 01F3; Case map
+01F4; 01F5; Case map
+01F6; 0195; Case map
+01F7; 01BF; Case map
+01F8; 01F9; Case map
+01FA; 01FB; Case map
+01FC; 01FD; Case map
+01FE; 01FF; Case map
+0200; 0201; Case map
+0202; 0203; Case map
+0204; 0205; Case map
+0206; 0207; Case map
+0208; 0209; Case map
+020A; 020B; Case map
+020C; 020D; Case map
+020E; 020F; Case map
+0210; 0211; Case map
+0212; 0213; Case map
+0214; 0215; Case map
+0216; 0217; Case map
+0218; 0219; Case map
+021A; 021B; Case map
+021C; 021D; Case map
+021E; 021F; Case map
+0220; 019E; Case map
+0222; 0223; Case map
+0224; 0225; Case map
+0226; 0227; Case map
+0228; 0229; Case map
+022A; 022B; Case map
+022C; 022D; Case map
+022E; 022F; Case map
+0230; 0231; Case map
+0232; 0233; Case map
+0345; 03B9; Case map
+037A; 0020 03B9; Additional folding
+0386; 03AC; Case map
+0388; 03AD; Case map
+0389; 03AE; Case map
+038A; 03AF; Case map
+038C; 03CC; Case map
+038E; 03CD; Case map
+038F; 03CE; Case map
+0390; 03B9 0308 0301; Case map
+0391; 03B1; Case map
+0392; 03B2; Case map
+0393; 03B3; Case map
+0394; 03B4; Case map
+0395; 03B5; Case map
+0396; 03B6; Case map
+0397; 03B7; Case map
+0398; 03B8; Case map
+0399; 03B9; Case map
+039A; 03BA; Case map
+039B; 03BB; Case map
+039C; 03BC; Case map
+039D; 03BD; Case map
+039E; 03BE; Case map
+039F; 03BF; Case map
+03A0; 03C0; Case map
+03A1; 03C1; Case map
+03A3; 03C3; Case map
+03A4; 03C4; Case map
+03A5; 03C5; Case map
+03A6; 03C6; Case map
+03A7; 03C7; Case map
+03A8; 03C8; Case map
+03A9; 03C9; Case map
+03AA; 03CA; Case map
+03AB; 03CB; Case map
+03B0; 03C5 0308 0301; Case map
+03C2; 03C3; Case map
+03D0; 03B2; Case map
+03D1; 03B8; Case map
+03D2; 03C5; Additional folding
+03D3; 03CD; Additional folding
+03D4; 03CB; Additional folding
+03D5; 03C6; Case map
+03D6; 03C0; Case map
+03D8; 03D9; Case map
+03DA; 03DB; Case map
+03DC; 03DD; Case map
+03DE; 03DF; Case map
+03E0; 03E1; Case map
+03E2; 03E3; Case map
+03E4; 03E5; Case map
+03E6; 03E7; Case map
+03E8; 03E9; Case map
+03EA; 03EB; Case map
+03EC; 03ED; Case map
+03EE; 03EF; Case map
+03F0; 03BA; Case map
+03F1; 03C1; Case map
+03F2; 03C3; Case map
+03F4; 03B8; Case map
+03F5; 03B5; Case map
+0400; 0450; Case map
+0401; 0451; Case map
+0402; 0452; Case map
+0403; 0453; Case map
+0404; 0454; Case map
+0405; 0455; Case map
+0406; 0456; Case map
+0407; 0457; Case map
+0408; 0458; Case map
+0409; 0459; Case map
+040A; 045A; Case map
+040B; 045B; Case map
+040C; 045C; Case map
+040D; 045D; Case map
+040E; 045E; Case map
+040F; 045F; Case map
+0410; 0430; Case map
+0411; 0431; Case map
+0412; 0432; Case map
+0413; 0433; Case map
+0414; 0434; Case map
+0415; 0435; Case map
+0416; 0436; Case map
+0417; 0437; Case map
+0418; 0438; Case map
+0419; 0439; Case map
+041A; 043A; Case map
+041B; 043B; Case map
+041C; 043C; Case map
+041D; 043D; Case map
+041E; 043E; Case map
+041F; 043F; Case map
+0420; 0440; Case map
+0421; 0441; Case map
+0422; 0442; Case map
+0423; 0443; Case map
+0424; 0444; Case map
+0425; 0445; Case map
+0426; 0446; Case map
+0427; 0447; Case map
+0428; 0448; Case map
+0429; 0449; Case map
+042A; 044A; Case map
+042B; 044B; Case map
+042C; 044C; Case map
+042D; 044D; Case map
+042E; 044E; Case map
+042F; 044F; Case map
+0460; 0461; Case map
+0462; 0463; Case map
+0464; 0465; Case map
+0466; 0467; Case map
+0468; 0469; Case map
+046A; 046B; Case map
+046C; 046D; Case map
+046E; 046F; Case map
+0470; 0471; Case map
+0472; 0473; Case map
+0474; 0475; Case map
+0476; 0477; Case map
+0478; 0479; Case map
+047A; 047B; Case map
+047C; 047D; Case map
+047E; 047F; Case map
+0480; 0481; Case map
+048A; 048B; Case map
+048C; 048D; Case map
+048E; 048F; Case map
+0490; 0491; Case map
+0492; 0493; Case map
+0494; 0495; Case map
+0496; 0497; Case map
+0498; 0499; Case map
+049A; 049B; Case map
+049C; 049D; Case map
+049E; 049F; Case map
+04A0; 04A1; Case map
+04A2; 04A3; Case map
+04A4; 04A5; Case map
+04A6; 04A7; Case map
+04A8; 04A9; Case map
+04AA; 04AB; Case map
+04AC; 04AD; Case map
+04AE; 04AF; Case map
+04B0; 04B1; Case map
+04B2; 04B3; Case map
+04B4; 04B5; Case map
+04B6; 04B7; Case map
+04B8; 04B9; Case map
+04BA; 04BB; Case map
+04BC; 04BD; Case map
+04BE; 04BF; Case map
+04C1; 04C2; Case map
+04C3; 04C4; Case map
+04C5; 04C6; Case map
+04C7; 04C8; Case map
+04C9; 04CA; Case map
+04CB; 04CC; Case map
+04CD; 04CE; Case map
+04D0; 04D1; Case map
+04D2; 04D3; Case map
+04D4; 04D5; Case map
+04D6; 04D7; Case map
+04D8; 04D9; Case map
+04DA; 04DB; Case map
+04DC; 04DD; Case map
+04DE; 04DF; Case map
+04E0; 04E1; Case map
+04E2; 04E3; Case map
+04E4; 04E5; Case map
+04E6; 04E7; Case map
+04E8; 04E9; Case map
+04EA; 04EB; Case map
+04EC; 04ED; Case map
+04EE; 04EF; Case map
+04F0; 04F1; Case map
+04F2; 04F3; Case map
+04F4; 04F5; Case map
+04F8; 04F9; Case map
+0500; 0501; Case map
+0502; 0503; Case map
+0504; 0505; Case map
+0506; 0507; Case map
+0508; 0509; Case map
+050A; 050B; Case map
+050C; 050D; Case map
+050E; 050F; Case map
+0531; 0561; Case map
+0532; 0562; Case map
+0533; 0563; Case map
+0534; 0564; Case map
+0535; 0565; Case map
+0536; 0566; Case map
+0537; 0567; Case map
+0538; 0568; Case map
+0539; 0569; Case map
+053A; 056A; Case map
+053B; 056B; Case map
+053C; 056C; Case map
+053D; 056D; Case map
+053E; 056E; Case map
+053F; 056F; Case map
+0540; 0570; Case map
+0541; 0571; Case map
+0542; 0572; Case map
+0543; 0573; Case map
+0544; 0574; Case map
+0545; 0575; Case map
+0546; 0576; Case map
+0547; 0577; Case map
+0548; 0578; Case map
+0549; 0579; Case map
+054A; 057A; Case map
+054B; 057B; Case map
+054C; 057C; Case map
+054D; 057D; Case map
+054E; 057E; Case map
+054F; 057F; Case map
+0550; 0580; Case map
+0551; 0581; Case map
+0552; 0582; Case map
+0553; 0583; Case map
+0554; 0584; Case map
+0555; 0585; Case map
+0556; 0586; Case map
+0587; 0565 0582; Case map
+1E00; 1E01; Case map
+1E02; 1E03; Case map
+1E04; 1E05; Case map
+1E06; 1E07; Case map
+1E08; 1E09; Case map
+1E0A; 1E0B; Case map
+1E0C; 1E0D; Case map
+1E0E; 1E0F; Case map
+1E10; 1E11; Case map
+1E12; 1E13; Case map
+1E14; 1E15; Case map
+1E16; 1E17; Case map
+1E18; 1E19; Case map
+1E1A; 1E1B; Case map
+1E1C; 1E1D; Case map
+1E1E; 1E1F; Case map
+1E20; 1E21; Case map
+1E22; 1E23; Case map
+1E24; 1E25; Case map
+1E26; 1E27; Case map
+1E28; 1E29; Case map
+1E2A; 1E2B; Case map
+1E2C; 1E2D; Case map
+1E2E; 1E2F; Case map
+1E30; 1E31; Case map
+1E32; 1E33; Case map
+1E34; 1E35; Case map
+1E36; 1E37; Case map
+1E38; 1E39; Case map
+1E3A; 1E3B; Case map
+1E3C; 1E3D; Case map
+1E3E; 1E3F; Case map
+1E40; 1E41; Case map
+1E42; 1E43; Case map
+1E44; 1E45; Case map
+1E46; 1E47; Case map
+1E48; 1E49; Case map
+1E4A; 1E4B; Case map
+1E4C; 1E4D; Case map
+1E4E; 1E4F; Case map
+1E50; 1E51; Case map
+1E52; 1E53; Case map
+1E54; 1E55; Case map
+1E56; 1E57; Case map
+1E58; 1E59; Case map
+1E5A; 1E5B; Case map
+1E5C; 1E5D; Case map
+1E5E; 1E5F; Case map
+1E60; 1E61; Case map
+1E62; 1E63; Case map
+1E64; 1E65; Case map
+1E66; 1E67; Case map
+1E68; 1E69; Case map
+1E6A; 1E6B; Case map
+1E6C; 1E6D; Case map
+1E6E; 1E6F; Case map
+1E70; 1E71; Case map
+1E72; 1E73; Case map
+1E74; 1E75; Case map
+1E76; 1E77; Case map
+1E78; 1E79; Case map
+1E7A; 1E7B; Case map
+1E7C; 1E7D; Case map
+1E7E; 1E7F; Case map
+1E80; 1E81; Case map
+1E82; 1E83; Case map
+1E84; 1E85; Case map
+1E86; 1E87; Case map
+1E88; 1E89; Case map
+1E8A; 1E8B; Case map
+1E8C; 1E8D; Case map
+1E8E; 1E8F; Case map
+1E90; 1E91; Case map
+1E92; 1E93; Case map
+1E94; 1E95; Case map
+1E96; 0068 0331; Case map
+1E97; 0074 0308; Case map
+1E98; 0077 030A; Case map
+1E99; 0079 030A; Case map
+1E9A; 0061 02BE; Case map
+1E9B; 1E61; Case map
+1EA0; 1EA1; Case map
+1EA2; 1EA3; Case map
+1EA4; 1EA5; Case map
+1EA6; 1EA7; Case map
+1EA8; 1EA9; Case map
+1EAA; 1EAB; Case map
+1EAC; 1EAD; Case map
+1EAE; 1EAF; Case map
+1EB0; 1EB1; Case map
+1EB2; 1EB3; Case map
+1EB4; 1EB5; Case map
+1EB6; 1EB7; Case map
+1EB8; 1EB9; Case map
+1EBA; 1EBB; Case map
+1EBC; 1EBD; Case map
+1EBE; 1EBF; Case map
+1EC0; 1EC1; Case map
+1EC2; 1EC3; Case map
+1EC4; 1EC5; Case map
+1EC6; 1EC7; Case map
+1EC8; 1EC9; Case map
+1ECA; 1ECB; Case map
+1ECC; 1ECD; Case map
+1ECE; 1ECF; Case map
+1ED0; 1ED1; Case map
+1ED2; 1ED3; Case map
+1ED4; 1ED5; Case map
+1ED6; 1ED7; Case map
+1ED8; 1ED9; Case map
+1EDA; 1EDB; Case map
+1EDC; 1EDD; Case map
+1EDE; 1EDF; Case map
+1EE0; 1EE1; Case map
+1EE2; 1EE3; Case map
+1EE4; 1EE5; Case map
+1EE6; 1EE7; Case map
+1EE8; 1EE9; Case map
+1EEA; 1EEB; Case map
+1EEC; 1EED; Case map
+1EEE; 1EEF; Case map
+1EF0; 1EF1; Case map
+1EF2; 1EF3; Case map
+1EF4; 1EF5; Case map
+1EF6; 1EF7; Case map
+1EF8; 1EF9; Case map
+1F08; 1F00; Case map
+1F09; 1F01; Case map
+1F0A; 1F02; Case map
+1F0B; 1F03; Case map
+1F0C; 1F04; Case map
+1F0D; 1F05; Case map
+1F0E; 1F06; Case map
+1F0F; 1F07; Case map
+1F18; 1F10; Case map
+1F19; 1F11; Case map
+1F1A; 1F12; Case map
+1F1B; 1F13; Case map
+1F1C; 1F14; Case map
+1F1D; 1F15; Case map
+1F28; 1F20; Case map
+1F29; 1F21; Case map
+1F2A; 1F22; Case map
+1F2B; 1F23; Case map
+1F2C; 1F24; Case map
+1F2D; 1F25; Case map
+1F2E; 1F26; Case map
+1F2F; 1F27; Case map
+1F38; 1F30; Case map
+1F39; 1F31; Case map
+1F3A; 1F32; Case map
+1F3B; 1F33; Case map
+1F3C; 1F34; Case map
+1F3D; 1F35; Case map
+1F3E; 1F36; Case map
+1F3F; 1F37; Case map
+1F48; 1F40; Case map
+1F49; 1F41; Case map
+1F4A; 1F42; Case map
+1F4B; 1F43; Case map
+1F4C; 1F44; Case map
+1F4D; 1F45; Case map
+1F50; 03C5 0313; Case map
+1F52; 03C5 0313 0300; Case map
+1F54; 03C5 0313 0301; Case map
+1F56; 03C5 0313 0342; Case map
+1F59; 1F51; Case map
+1F5B; 1F53; Case map
+1F5D; 1F55; Case map
+1F5F; 1F57; Case map
+1F68; 1F60; Case map
+1F69; 1F61; Case map
+1F6A; 1F62; Case map
+1F6B; 1F63; Case map
+1F6C; 1F64; Case map
+1F6D; 1F65; Case map
+1F6E; 1F66; Case map
+1F6F; 1F67; Case map
+1F80; 1F00 03B9; Case map
+1F81; 1F01 03B9; Case map
+1F82; 1F02 03B9; Case map
+1F83; 1F03 03B9; Case map
+1F84; 1F04 03B9; Case map
+1F85; 1F05 03B9; Case map
+1F86; 1F06 03B9; Case map
+1F87; 1F07 03B9; Case map
+1F88; 1F00 03B9; Case map
+1F89; 1F01 03B9; Case map
+1F8A; 1F02 03B9; Case map
+1F8B; 1F03 03B9; Case map
+1F8C; 1F04 03B9; Case map
+1F8D; 1F05 03B9; Case map
+1F8E; 1F06 03B9; Case map
+1F8F; 1F07 03B9; Case map
+1F90; 1F20 03B9; Case map
+1F91; 1F21 03B9; Case map
+1F92; 1F22 03B9; Case map
+1F93; 1F23 03B9; Case map
+1F94; 1F24 03B9; Case map
+1F95; 1F25 03B9; Case map
+1F96; 1F26 03B9; Case map
+1F97; 1F27 03B9; Case map
+1F98; 1F20 03B9; Case map
+1F99; 1F21 03B9; Case map
+1F9A; 1F22 03B9; Case map
+1F9B; 1F23 03B9; Case map
+1F9C; 1F24 03B9; Case map
+1F9D; 1F25 03B9; Case map
+1F9E; 1F26 03B9; Case map
+1F9F; 1F27 03B9; Case map
+1FA0; 1F60 03B9; Case map
+1FA1; 1F61 03B9; Case map
+1FA2; 1F62 03B9; Case map
+1FA3; 1F63 03B9; Case map
+1FA4; 1F64 03B9; Case map
+1FA5; 1F65 03B9; Case map
+1FA6; 1F66 03B9; Case map
+1FA7; 1F67 03B9; Case map
+1FA8; 1F60 03B9; Case map
+1FA9; 1F61 03B9; Case map
+1FAA; 1F62 03B9; Case map
+1FAB; 1F63 03B9; Case map
+1FAC; 1F64 03B9; Case map
+1FAD; 1F65 03B9; Case map
+1FAE; 1F66 03B9; Case map
+1FAF; 1F67 03B9; Case map
+1FB2; 1F70 03B9; Case map
+1FB3; 03B1 03B9; Case map
+1FB4; 03AC 03B9; Case map
+1FB6; 03B1 0342; Case map
+1FB7; 03B1 0342 03B9; Case map
+1FB8; 1FB0; Case map
+1FB9; 1FB1; Case map
+1FBA; 1F70; Case map
+1FBB; 1F71; Case map
+1FBC; 03B1 03B9; Case map
+1FBE; 03B9; Case map
+1FC2; 1F74 03B9; Case map
+1FC3; 03B7 03B9; Case map
+1FC4; 03AE 03B9; Case map
+1FC6; 03B7 0342; Case map
+1FC7; 03B7 0342 03B9; Case map
+1FC8; 1F72; Case map
+1FC9; 1F73; Case map
+1FCA; 1F74; Case map
+1FCB; 1F75; Case map
+1FCC; 03B7 03B9; Case map
+1FD2; 03B9 0308 0300; Case map
+1FD3; 03B9 0308 0301; Case map
+1FD6; 03B9 0342; Case map
+1FD7; 03B9 0308 0342; Case map
+1FD8; 1FD0; Case map
+1FD9; 1FD1; Case map
+1FDA; 1F76; Case map
+1FDB; 1F77; Case map
+1FE2; 03C5 0308 0300; Case map
+1FE3; 03C5 0308 0301; Case map
+1FE4; 03C1 0313; Case map
+1FE6; 03C5 0342; Case map
+1FE7; 03C5 0308 0342; Case map
+1FE8; 1FE0; Case map
+1FE9; 1FE1; Case map
+1FEA; 1F7A; Case map
+1FEB; 1F7B; Case map
+1FEC; 1FE5; Case map
+1FF2; 1F7C 03B9; Case map
+1FF3; 03C9 03B9; Case map
+1FF4; 03CE 03B9; Case map
+1FF6; 03C9 0342; Case map
+1FF7; 03C9 0342 03B9; Case map
+1FF8; 1F78; Case map
+1FF9; 1F79; Case map
+1FFA; 1F7C; Case map
+1FFB; 1F7D; Case map
+1FFC; 03C9 03B9; Case map
+20A8; 0072 0073; Additional folding
+2102; 0063; Additional folding
+2103; 00B0 0063; Additional folding
+2107; 025B; Additional folding
+2109; 00B0 0066; Additional folding
+210B; 0068; Additional folding
+210C; 0068; Additional folding
+210D; 0068; Additional folding
+2110; 0069; Additional folding
+2111; 0069; Additional folding
+2112; 006C; Additional folding
+2115; 006E; Additional folding
+2116; 006E 006F; Additional folding
+2119; 0070; Additional folding
+211A; 0071; Additional folding
+211B; 0072; Additional folding
+211C; 0072; Additional folding
+211D; 0072; Additional folding
+2120; 0073 006D; Additional folding
+2121; 0074 0065 006C; Additional folding
+2122; 0074 006D; Additional folding
+2124; 007A; Additional folding
+2126; 03C9; Case map
+2128; 007A; Additional folding
+212A; 006B; Case map
+212B; 00E5; Case map
+212C; 0062; Additional folding
+212D; 0063; Additional folding
+2130; 0065; Additional folding
+2131; 0066; Additional folding
+2133; 006D; Additional folding
+213E; 03B3; Additional folding
+213F; 03C0; Additional folding
+2145; 0064; Additional folding
+2160; 2170; Case map
+2161; 2171; Case map
+2162; 2172; Case map
+2163; 2173; Case map
+2164; 2174; Case map
+2165; 2175; Case map
+2166; 2176; Case map
+2167; 2177; Case map
+2168; 2178; Case map
+2169; 2179; Case map
+216A; 217A; Case map
+216B; 217B; Case map
+216C; 217C; Case map
+216D; 217D; Case map
+216E; 217E; Case map
+216F; 217F; Case map
+24B6; 24D0; Case map
+24B7; 24D1; Case map
+24B8; 24D2; Case map
+24B9; 24D3; Case map
+24BA; 24D4; Case map
+24BB; 24D5; Case map
+24BC; 24D6; Case map
+24BD; 24D7; Case map
+24BE; 24D8; Case map
+24BF; 24D9; Case map
+24C0; 24DA; Case map
+24C1; 24DB; Case map
+24C2; 24DC; Case map
+24C3; 24DD; Case map
+24C4; 24DE; Case map
+24C5; 24DF; Case map
+24C6; 24E0; Case map
+24C7; 24E1; Case map
+24C8; 24E2; Case map
+24C9; 24E3; Case map
+24CA; 24E4; Case map
+24CB; 24E5; Case map
+24CC; 24E6; Case map
+24CD; 24E7; Case map
+24CE; 24E8; Case map
+24CF; 24E9; Case map
+3371; 0068 0070 0061; Additional folding
+3373; 0061 0075; Additional folding
+3375; 006F 0076; Additional folding
+3380; 0070 0061; Additional folding
+3381; 006E 0061; Additional folding
+3382; 03BC 0061; Additional folding
+3383; 006D 0061; Additional folding
+3384; 006B 0061; Additional folding
+3385; 006B 0062; Additional folding
+3386; 006D 0062; Additional folding
+3387; 0067 0062; Additional folding
+338A; 0070 0066; Additional folding
+338B; 006E 0066; Additional folding
+338C; 03BC 0066; Additional folding
+3390; 0068 007A; Additional folding
+3391; 006B 0068 007A; Additional folding
+3392; 006D 0068 007A; Additional folding
+3393; 0067 0068 007A; Additional folding
+3394; 0074 0068 007A; Additional folding
+33A9; 0070 0061; Additional folding
+33AA; 006B 0070 0061; Additional folding
+33AB; 006D 0070 0061; Additional folding
+33AC; 0067 0070 0061; Additional folding
+33B4; 0070 0076; Additional folding
+33B5; 006E 0076; Additional folding
+33B6; 03BC 0076; Additional folding
+33B7; 006D 0076; Additional folding
+33B8; 006B 0076; Additional folding
+33B9; 006D 0076; Additional folding
+33BA; 0070 0077; Additional folding
+33BB; 006E 0077; Additional folding
+33BC; 03BC 0077; Additional folding
+33BD; 006D 0077; Additional folding
+33BE; 006B 0077; Additional folding
+33BF; 006D 0077; Additional folding
+33C0; 006B 03C9; Additional folding
+33C1; 006D 03C9; Additional folding
+33C3; 0062 0071; Additional folding
+33C6; 0063 2215 006B 0067; Additional folding
+33C7; 0063 006F 002E; Additional folding
+33C8; 0064 0062; Additional folding
+33C9; 0067 0079; Additional folding
+33CB; 0068 0070; Additional folding
+33CD; 006B 006B; Additional folding
+33CE; 006B 006D; Additional folding
+33D7; 0070 0068; Additional folding
+33D9; 0070 0070 006D; Additional folding
+33DA; 0070 0072; Additional folding
+33DC; 0073 0076; Additional folding
+33DD; 0077 0062; Additional folding
+FB00; 0066 0066; Case map
+FB01; 0066 0069; Case map
+FB02; 0066 006C; Case map
+FB03; 0066 0066 0069; Case map
+FB04; 0066 0066 006C; Case map
+FB05; 0073 0074; Case map
+FB06; 0073 0074; Case map
+FB13; 0574 0576; Case map
+FB14; 0574 0565; Case map
+FB15; 0574 056B; Case map
+FB16; 057E 0576; Case map
+FB17; 0574 056D; Case map
+FF21; FF41; Case map
+FF22; FF42; Case map
+FF23; FF43; Case map
+FF24; FF44; Case map
+FF25; FF45; Case map
+FF26; FF46; Case map
+FF27; FF47; Case map
+FF28; FF48; Case map
+FF29; FF49; Case map
+FF2A; FF4A; Case map
+FF2B; FF4B; Case map
+FF2C; FF4C; Case map
+FF2D; FF4D; Case map
+FF2E; FF4E; Case map
+FF2F; FF4F; Case map
+FF30; FF50; Case map
+FF31; FF51; Case map
+FF32; FF52; Case map
+FF33; FF53; Case map
+FF34; FF54; Case map
+FF35; FF55; Case map
+FF36; FF56; Case map
+FF37; FF57; Case map
+FF38; FF58; Case map
+FF39; FF59; Case map
+FF3A; FF5A; Case map
+10400; 10428; Case map
+10401; 10429; Case map
+10402; 1042A; Case map
+10403; 1042B; Case map
+10404; 1042C; Case map
+10405; 1042D; Case map
+10406; 1042E; Case map
+10407; 1042F; Case map
+10408; 10430; Case map
+10409; 10431; Case map
+1040A; 10432; Case map
+1040B; 10433; Case map
+1040C; 10434; Case map
+1040D; 10435; Case map
+1040E; 10436; Case map
+1040F; 10437; Case map
+10410; 10438; Case map
+10411; 10439; Case map
+10412; 1043A; Case map
+10413; 1043B; Case map
+10414; 1043C; Case map
+10415; 1043D; Case map
+10416; 1043E; Case map
+10417; 1043F; Case map
+10418; 10440; Case map
+10419; 10441; Case map
+1041A; 10442; Case map
+1041B; 10443; Case map
+1041C; 10444; Case map
+1041D; 10445; Case map
+1041E; 10446; Case map
+1041F; 10447; Case map
+10420; 10448; Case map
+10421; 10449; Case map
+10422; 1044A; Case map
+10423; 1044B; Case map
+10424; 1044C; Case map
+10425; 1044D; Case map
+1D400; 0061; Additional folding
+1D401; 0062; Additional folding
+1D402; 0063; Additional folding
+1D403; 0064; Additional folding
+1D404; 0065; Additional folding
+1D405; 0066; Additional folding
+1D406; 0067; Additional folding
+1D407; 0068; Additional folding
+1D408; 0069; Additional folding
+1D409; 006A; Additional folding
+1D40A; 006B; Additional folding
+1D40B; 006C; Additional folding
+1D40C; 006D; Additional folding
+1D40D; 006E; Additional folding
+1D40E; 006F; Additional folding
+1D40F; 0070; Additional folding
+1D410; 0071; Additional folding
+1D411; 0072; Additional folding
+1D412; 0073; Additional folding
+1D413; 0074; Additional folding
+1D414; 0075; Additional folding
+1D415; 0076; Additional folding
+1D416; 0077; Additional folding
+1D417; 0078; Additional folding
+1D418; 0079; Additional folding
+1D419; 007A; Additional folding
+1D434; 0061; Additional folding
+1D435; 0062; Additional folding
+1D436; 0063; Additional folding
+1D437; 0064; Additional folding
+1D438; 0065; Additional folding
+1D439; 0066; Additional folding
+1D43A; 0067; Additional folding
+1D43B; 0068; Additional folding
+1D43C; 0069; Additional folding
+1D43D; 006A; Additional folding
+1D43E; 006B; Additional folding
+1D43F; 006C; Additional folding
+1D440; 006D; Additional folding
+1D441; 006E; Additional folding
+1D442; 006F; Additional folding
+1D443; 0070; Additional folding
+1D444; 0071; Additional folding
+1D445; 0072; Additional folding
+1D446; 0073; Additional folding
+1D447; 0074; Additional folding
+1D448; 0075; Additional folding
+1D449; 0076; Additional folding
+1D44A; 0077; Additional folding
+1D44B; 0078; Additional folding
+1D44C; 0079; Additional folding
+1D44D; 007A; Additional folding
+1D468; 0061; Additional folding
+1D469; 0062; Additional folding
+1D46A; 0063; Additional folding
+1D46B; 0064; Additional folding
+1D46C; 0065; Additional folding
+1D46D; 0066; Additional folding
+1D46E; 0067; Additional folding
+1D46F; 0068; Additional folding
+1D470; 0069; Additional folding
+1D471; 006A; Additional folding
+1D472; 006B; Additional folding
+1D473; 006C; Additional folding
+1D474; 006D; Additional folding
+1D475; 006E; Additional folding
+1D476; 006F; Additional folding
+1D477; 0070; Additional folding
+1D478; 0071; Additional folding
+1D479; 0072; Additional folding
+1D47A; 0073; Additional folding
+1D47B; 0074; Additional folding
+1D47C; 0075; Additional folding
+1D47D; 0076; Additional folding
+1D47E; 0077; Additional folding
+1D47F; 0078; Additional folding
+1D480; 0079; Additional folding
+1D481; 007A; Additional folding
+1D49C; 0061; Additional folding
+1D49E; 0063; Additional folding
+1D49F; 0064; Additional folding
+1D4A2; 0067; Additional folding
+1D4A5; 006A; Additional folding
+1D4A6; 006B; Additional folding
+1D4A9; 006E; Additional folding
+1D4AA; 006F; Additional folding
+1D4AB; 0070; Additional folding
+1D4AC; 0071; Additional folding
+1D4AE; 0073; Additional folding
+1D4AF; 0074; Additional folding
+1D4B0; 0075; Additional folding
+1D4B1; 0076; Additional folding
+1D4B2; 0077; Additional folding
+1D4B3; 0078; Additional folding
+1D4B4; 0079; Additional folding
+1D4B5; 007A; Additional folding
+1D4D0; 0061; Additional folding
+1D4D1; 0062; Additional folding
+1D4D2; 0063; Additional folding
+1D4D3; 0064; Additional folding
+1D4D4; 0065; Additional folding
+1D4D5; 0066; Additional folding
+1D4D6; 0067; Additional folding
+1D4D7; 0068; Additional folding
+1D4D8; 0069; Additional folding
+1D4D9; 006A; Additional folding
+1D4DA; 006B; Additional folding
+1D4DB; 006C; Additional folding
+1D4DC; 006D; Additional folding
+1D4DD; 006E; Additional folding
+1D4DE; 006F; Additional folding
+1D4DF; 0070; Additional folding
+1D4E0; 0071; Additional folding
+1D4E1; 0072; Additional folding
+1D4E2; 0073; Additional folding
+1D4E3; 0074; Additional folding
+1D4E4; 0075; Additional folding
+1D4E5; 0076; Additional folding
+1D4E6; 0077; Additional folding
+1D4E7; 0078; Additional folding
+1D4E8; 0079; Additional folding
+1D4E9; 007A; Additional folding
+1D504; 0061; Additional folding
+1D505; 0062; Additional folding
+1D507; 0064; Additional folding
+1D508; 0065; Additional folding
+1D509; 0066; Additional folding
+1D50A; 0067; Additional folding
+1D50D; 006A; Additional folding
+1D50E; 006B; Additional folding
+1D50F; 006C; Additional folding
+1D510; 006D; Additional folding
+1D511; 006E; Additional folding
+1D512; 006F; Additional folding
+1D513; 0070; Additional folding
+1D514; 0071; Additional folding
+1D516; 0073; Additional folding
+1D517; 0074; Additional folding
+1D518; 0075; Additional folding
+1D519; 0076; Additional folding
+1D51A; 0077; Additional folding
+1D51B; 0078; Additional folding
+1D51C; 0079; Additional folding
+1D538; 0061; Additional folding
+1D539; 0062; Additional folding
+1D53B; 0064; Additional folding
+1D53C; 0065; Additional folding
+1D53D; 0066; Additional folding
+1D53E; 0067; Additional folding
+1D540; 0069; Additional folding
+1D541; 006A; Additional folding
+1D542; 006B; Additional folding
+1D543; 006C; Additional folding
+1D544; 006D; Additional folding
+1D546; 006F; Additional folding
+1D54A; 0073; Additional folding
+1D54B; 0074; Additional folding
+1D54C; 0075; Additional folding
+1D54D; 0076; Additional folding
+1D54E; 0077; Additional folding
+1D54F; 0078; Additional folding
+1D550; 0079; Additional folding
+1D56C; 0061; Additional folding
+1D56D; 0062; Additional folding
+1D56E; 0063; Additional folding
+1D56F; 0064; Additional folding
+1D570; 0065; Additional folding
+1D571; 0066; Additional folding
+1D572; 0067; Additional folding
+1D573; 0068; Additional folding
+1D574; 0069; Additional folding
+1D575; 006A; Additional folding
+1D576; 006B; Additional folding
+1D577; 006C; Additional folding
+1D578; 006D; Additional folding
+1D579; 006E; Additional folding
+1D57A; 006F; Additional folding
+1D57B; 0070; Additional folding
+1D57C; 0071; Additional folding
+1D57D; 0072; Additional folding
+1D57E; 0073; Additional folding
+1D57F; 0074; Additional folding
+1D580; 0075; Additional folding
+1D581; 0076; Additional folding
+1D582; 0077; Additional folding
+1D583; 0078; Additional folding
+1D584; 0079; Additional folding
+1D585; 007A; Additional folding
+1D5A0; 0061; Additional folding
+1D5A1; 0062; Additional folding
+1D5A2; 0063; Additional folding
+1D5A3; 0064; Additional folding
+1D5A4; 0065; Additional folding
+1D5A5; 0066; Additional folding
+1D5A6; 0067; Additional folding
+1D5A7; 0068; Additional folding
+1D5A8; 0069; Additional folding
+1D5A9; 006A; Additional folding
+1D5AA; 006B; Additional folding
+1D5AB; 006C; Additional folding
+1D5AC; 006D; Additional folding
+1D5AD; 006E; Additional folding
+1D5AE; 006F; Additional folding
+1D5AF; 0070; Additional folding
+1D5B0; 0071; Additional folding
+1D5B1; 0072; Additional folding
+1D5B2; 0073; Additional folding
+1D5B3; 0074; Additional folding
+1D5B4; 0075; Additional folding
+1D5B5; 0076; Additional folding
+1D5B6; 0077; Additional folding
+1D5B7; 0078; Additional folding
+1D5B8; 0079; Additional folding
+1D5B9; 007A; Additional folding
+1D5D4; 0061; Additional folding
+1D5D5; 0062; Additional folding
+1D5D6; 0063; Additional folding
+1D5D7; 0064; Additional folding
+1D5D8; 0065; Additional folding
+1D5D9; 0066; Additional folding
+1D5DA; 0067; Additional folding
+1D5DB; 0068; Additional folding
+1D5DC; 0069; Additional folding
+1D5DD; 006A; Additional folding
+1D5DE; 006B; Additional folding
+1D5DF; 006C; Additional folding
+1D5E0; 006D; Additional folding
+1D5E1; 006E; Additional folding
+1D5E2; 006F; Additional folding
+1D5E3; 0070; Additional folding
+1D5E4; 0071; Additional folding
+1D5E5; 0072; Additional folding
+1D5E6; 0073; Additional folding
+1D5E7; 0074; Additional folding
+1D5E8; 0075; Additional folding
+1D5E9; 0076; Additional folding
+1D5EA; 0077; Additional folding
+1D5EB; 0078; Additional folding
+1D5EC; 0079; Additional folding
+1D5ED; 007A; Additional folding
+1D608; 0061; Additional folding
+1D609; 0062; Additional folding
+1D60A; 0063; Additional folding
+1D60B; 0064; Additional folding
+1D60C; 0065; Additional folding
+1D60D; 0066; Additional folding
+1D60E; 0067; Additional folding
+1D60F; 0068; Additional folding
+1D610; 0069; Additional folding
+1D611; 006A; Additional folding
+1D612; 006B; Additional folding
+1D613; 006C; Additional folding
+1D614; 006D; Additional folding
+1D615; 006E; Additional folding
+1D616; 006F; Additional folding
+1D617; 0070; Additional folding
+1D618; 0071; Additional folding
+1D619; 0072; Additional folding
+1D61A; 0073; Additional folding
+1D61B; 0074; Additional folding
+1D61C; 0075; Additional folding
+1D61D; 0076; Additional folding
+1D61E; 0077; Additional folding
+1D61F; 0078; Additional folding
+1D620; 0079; Additional folding
+1D621; 007A; Additional folding
+1D63C; 0061; Additional folding
+1D63D; 0062; Additional folding
+1D63E; 0063; Additional folding
+1D63F; 0064; Additional folding
+1D640; 0065; Additional folding
+1D641; 0066; Additional folding
+1D642; 0067; Additional folding
+1D643; 0068; Additional folding
+1D644; 0069; Additional folding
+1D645; 006A; Additional folding
+1D646; 006B; Additional folding
+1D647; 006C; Additional folding
+1D648; 006D; Additional folding
+1D649; 006E; Additional folding
+1D64A; 006F; Additional folding
+1D64B; 0070; Additional folding
+1D64C; 0071; Additional folding
+1D64D; 0072; Additional folding
+1D64E; 0073; Additional folding
+1D64F; 0074; Additional folding
+1D650; 0075; Additional folding
+1D651; 0076; Additional folding
+1D652; 0077; Additional folding
+1D653; 0078; Additional folding
+1D654; 0079; Additional folding
+1D655; 007A; Additional folding
+1D670; 0061; Additional folding
+1D671; 0062; Additional folding
+1D672; 0063; Additional folding
+1D673; 0064; Additional folding
+1D674; 0065; Additional folding
+1D675; 0066; Additional folding
+1D676; 0067; Additional folding
+1D677; 0068; Additional folding
+1D678; 0069; Additional folding
+1D679; 006A; Additional folding
+1D67A; 006B; Additional folding
+1D67B; 006C; Additional folding
+1D67C; 006D; Additional folding
+1D67D; 006E; Additional folding
+1D67E; 006F; Additional folding
+1D67F; 0070; Additional folding
+1D680; 0071; Additional folding
+1D681; 0072; Additional folding
+1D682; 0073; Additional folding
+1D683; 0074; Additional folding
+1D684; 0075; Additional folding
+1D685; 0076; Additional folding
+1D686; 0077; Additional folding
+1D687; 0078; Additional folding
+1D688; 0079; Additional folding
+1D689; 007A; Additional folding
+1D6A8; 03B1; Additional folding
+1D6A9; 03B2; Additional folding
+1D6AA; 03B3; Additional folding
+1D6AB; 03B4; Additional folding
+1D6AC; 03B5; Additional folding
+1D6AD; 03B6; Additional folding
+1D6AE; 03B7; Additional folding
+1D6AF; 03B8; Additional folding
+1D6B0; 03B9; Additional folding
+1D6B1; 03BA; Additional folding
+1D6B2; 03BB; Additional folding
+1D6B3; 03BC; Additional folding
+1D6B4; 03BD; Additional folding
+1D6B5; 03BE; Additional folding
+1D6B6; 03BF; Additional folding
+1D6B7; 03C0; Additional folding
+1D6B8; 03C1; Additional folding
+1D6B9; 03B8; Additional folding
+1D6BA; 03C3; Additional folding
+1D6BB; 03C4; Additional folding
+1D6BC; 03C5; Additional folding
+1D6BD; 03C6; Additional folding
+1D6BE; 03C7; Additional folding
+1D6BF; 03C8; Additional folding
+1D6C0; 03C9; Additional folding
+1D6D3; 03C3; Additional folding
+1D6E2; 03B1; Additional folding
+1D6E3; 03B2; Additional folding
+1D6E4; 03B3; Additional folding
+1D6E5; 03B4; Additional folding
+1D6E6; 03B5; Additional folding
+1D6E7; 03B6; Additional folding
+1D6E8; 03B7; Additional folding
+1D6E9; 03B8; Additional folding
+1D6EA; 03B9; Additional folding
+1D6EB; 03BA; Additional folding
+1D6EC; 03BB; Additional folding
+1D6ED; 03BC; Additional folding
+1D6EE; 03BD; Additional folding
+1D6EF; 03BE; Additional folding
+1D6F0; 03BF; Additional folding
+1D6F1; 03C0; Additional folding
+1D6F2; 03C1; Additional folding
+1D6F3; 03B8; Additional folding
+1D6F4; 03C3; Additional folding
+1D6F5; 03C4; Additional folding
+1D6F6; 03C5; Additional folding
+1D6F7; 03C6; Additional folding
+1D6F8; 03C7; Additional folding
+1D6F9; 03C8; Additional folding
+1D6FA; 03C9; Additional folding
+1D70D; 03C3; Additional folding
+1D71C; 03B1; Additional folding
+1D71D; 03B2; Additional folding
+1D71E; 03B3; Additional folding
+1D71F; 03B4; Additional folding
+1D720; 03B5; Additional folding
+1D721; 03B6; Additional folding
+1D722; 03B7; Additional folding
+1D723; 03B8; Additional folding
+1D724; 03B9; Additional folding
+1D725; 03BA; Additional folding
+1D726; 03BB; Additional folding
+1D727; 03BC; Additional folding
+1D728; 03BD; Additional folding
+1D729; 03BE; Additional folding
+1D72A; 03BF; Additional folding
+1D72B; 03C0; Additional folding
+1D72C; 03C1; Additional folding
+1D72D; 03B8; Additional folding
+1D72E; 03C3; Additional folding
+1D72F; 03C4; Additional folding
+1D730; 03C5; Additional folding
+1D731; 03C6; Additional folding
+1D732; 03C7; Additional folding
+1D733; 03C8; Additional folding
+1D734; 03C9; Additional folding
+1D747; 03C3; Additional folding
+1D756; 03B1; Additional folding
+1D757; 03B2; Additional folding
+1D758; 03B3; Additional folding
+1D759; 03B4; Additional folding
+1D75A; 03B5; Additional folding
+1D75B; 03B6; Additional folding
+1D75C; 03B7; Additional folding
+1D75D; 03B8; Additional folding
+1D75E; 03B9; Additional folding
+1D75F; 03BA; Additional folding
+1D760; 03BB; Additional folding
+1D761; 03BC; Additional folding
+1D762; 03BD; Additional folding
+1D763; 03BE; Additional folding
+1D764; 03BF; Additional folding
+1D765; 03C0; Additional folding
+1D766; 03C1; Additional folding
+1D767; 03B8; Additional folding
+1D768; 03C3; Additional folding
+1D769; 03C4; Additional folding
+1D76A; 03C5; Additional folding
+1D76B; 03C6; Additional folding
+1D76C; 03C7; Additional folding
+1D76D; 03C8; Additional folding
+1D76E; 03C9; Additional folding
+1D781; 03C3; Additional folding
+1D790; 03B1; Additional folding
+1D791; 03B2; Additional folding
+1D792; 03B3; Additional folding
+1D793; 03B4; Additional folding
+1D794; 03B5; Additional folding
+1D795; 03B6; Additional folding
+1D796; 03B7; Additional folding
+1D797; 03B8; Additional folding
+1D798; 03B9; Additional folding
+1D799; 03BA; Additional folding
+1D79A; 03BB; Additional folding
+1D79B; 03BC; Additional folding
+1D79C; 03BD; Additional folding
+1D79D; 03BE; Additional folding
+1D79E; 03BF; Additional folding
+1D79F; 03C0; Additional folding
+1D7A0; 03C1; Additional folding
+1D7A1; 03B8; Additional folding
+1D7A2; 03C3; Additional folding
+1D7A3; 03C4; Additional folding
+1D7A4; 03C5; Additional folding
+1D7A5; 03C6; Additional folding
+1D7A6; 03C7; Additional folding
+1D7A7; 03C8; Additional folding
+1D7A8; 03C9; Additional folding
+1D7BB; 03C3; Additional folding
diff --git a/data/B.3 b/data/B.3
new file mode 100644
index 0000000..b1d1b3d
--- /dev/null
+++ b/data/B.3
@@ -0,0 +1,838 @@
+0041; 0061; Case map
+0042; 0062; Case map
+0043; 0063; Case map
+0044; 0064; Case map
+0045; 0065; Case map
+0046; 0066; Case map
+0047; 0067; Case map
+0048; 0068; Case map
+0049; 0069; Case map
+004A; 006A; Case map
+004B; 006B; Case map
+004C; 006C; Case map
+004D; 006D; Case map
+004E; 006E; Case map
+004F; 006F; Case map
+0050; 0070; Case map
+0051; 0071; Case map
+0052; 0072; Case map
+0053; 0073; Case map
+0054; 0074; Case map
+0055; 0075; Case map
+0056; 0076; Case map
+0057; 0077; Case map
+0058; 0078; Case map
+0059; 0079; Case map
+005A; 007A; Case map
+00B5; 03BC; Case map
+00C0; 00E0; Case map
+00C1; 00E1; Case map
+00C2; 00E2; Case map
+00C3; 00E3; Case map
+00C4; 00E4; Case map
+00C5; 00E5; Case map
+00C6; 00E6; Case map
+00C7; 00E7; Case map
+00C8; 00E8; Case map
+00C9; 00E9; Case map
+00CA; 00EA; Case map
+00CB; 00EB; Case map
+00CC; 00EC; Case map
+00CD; 00ED; Case map
+00CE; 00EE; Case map
+00CF; 00EF; Case map
+00D0; 00F0; Case map
+00D1; 00F1; Case map
+00D2; 00F2; Case map
+00D3; 00F3; Case map
+00D4; 00F4; Case map
+00D5; 00F5; Case map
+00D6; 00F6; Case map
+00D8; 00F8; Case map
+00D9; 00F9; Case map
+00DA; 00FA; Case map
+00DB; 00FB; Case map
+00DC; 00FC; Case map
+00DD; 00FD; Case map
+00DE; 00FE; Case map
+00DF; 0073 0073; Case map
+0100; 0101; Case map
+0102; 0103; Case map
+0104; 0105; Case map
+0106; 0107; Case map
+0108; 0109; Case map
+010A; 010B; Case map
+010C; 010D; Case map
+010E; 010F; Case map
+0110; 0111; Case map
+0112; 0113; Case map
+0114; 0115; Case map
+0116; 0117; Case map
+0118; 0119; Case map
+011A; 011B; Case map
+011C; 011D; Case map
+011E; 011F; Case map
+0120; 0121; Case map
+0122; 0123; Case map
+0124; 0125; Case map
+0126; 0127; Case map
+0128; 0129; Case map
+012A; 012B; Case map
+012C; 012D; Case map
+012E; 012F; Case map
+0130; 0069 0307; Case map
+0132; 0133; Case map
+0134; 0135; Case map
+0136; 0137; Case map
+0139; 013A; Case map
+013B; 013C; Case map
+013D; 013E; Case map
+013F; 0140; Case map
+0141; 0142; Case map
+0143; 0144; Case map
+0145; 0146; Case map
+0147; 0148; Case map
+0149; 02BC 006E; Case map
+014A; 014B; Case map
+014C; 014D; Case map
+014E; 014F; Case map
+0150; 0151; Case map
+0152; 0153; Case map
+0154; 0155; Case map
+0156; 0157; Case map
+0158; 0159; Case map
+015A; 015B; Case map
+015C; 015D; Case map
+015E; 015F; Case map
+0160; 0161; Case map
+0162; 0163; Case map
+0164; 0165; Case map
+0166; 0167; Case map
+0168; 0169; Case map
+016A; 016B; Case map
+016C; 016D; Case map
+016E; 016F; Case map
+0170; 0171; Case map
+0172; 0173; Case map
+0174; 0175; Case map
+0176; 0177; Case map
+0178; 00FF; Case map
+0179; 017A; Case map
+017B; 017C; Case map
+017D; 017E; Case map
+017F; 0073; Case map
+0181; 0253; Case map
+0182; 0183; Case map
+0184; 0185; Case map
+0186; 0254; Case map
+0187; 0188; Case map
+0189; 0256; Case map
+018A; 0257; Case map
+018B; 018C; Case map
+018E; 01DD; Case map
+018F; 0259; Case map
+0190; 025B; Case map
+0191; 0192; Case map
+0193; 0260; Case map
+0194; 0263; Case map
+0196; 0269; Case map
+0197; 0268; Case map
+0198; 0199; Case map
+019C; 026F; Case map
+019D; 0272; Case map
+019F; 0275; Case map
+01A0; 01A1; Case map
+01A2; 01A3; Case map
+01A4; 01A5; Case map
+01A6; 0280; Case map
+01A7; 01A8; Case map
+01A9; 0283; Case map
+01AC; 01AD; Case map
+01AE; 0288; Case map
+01AF; 01B0; Case map
+01B1; 028A; Case map
+01B2; 028B; Case map
+01B3; 01B4; Case map
+01B5; 01B6; Case map
+01B7; 0292; Case map
+01B8; 01B9; Case map
+01BC; 01BD; Case map
+01C4; 01C6; Case map
+01C5; 01C6; Case map
+01C7; 01C9; Case map
+01C8; 01C9; Case map
+01CA; 01CC; Case map
+01CB; 01CC; Case map
+01CD; 01CE; Case map
+01CF; 01D0; Case map
+01D1; 01D2; Case map
+01D3; 01D4; Case map
+01D5; 01D6; Case map
+01D7; 01D8; Case map
+01D9; 01DA; Case map
+01DB; 01DC; Case map
+01DE; 01DF; Case map
+01E0; 01E1; Case map
+01E2; 01E3; Case map
+01E4; 01E5; Case map
+01E6; 01E7; Case map
+01E8; 01E9; Case map
+01EA; 01EB; Case map
+01EC; 01ED; Case map
+01EE; 01EF; Case map
+01F0; 006A 030C; Case map
+01F1; 01F3; Case map
+01F2; 01F3; Case map
+01F4; 01F5; Case map
+01F6; 0195; Case map
+01F7; 01BF; Case map
+01F8; 01F9; Case map
+01FA; 01FB; Case map
+01FC; 01FD; Case map
+01FE; 01FF; Case map
+0200; 0201; Case map
+0202; 0203; Case map
+0204; 0205; Case map
+0206; 0207; Case map
+0208; 0209; Case map
+020A; 020B; Case map
+020C; 020D; Case map
+020E; 020F; Case map
+0210; 0211; Case map
+0212; 0213; Case map
+0214; 0215; Case map
+0216; 0217; Case map
+0218; 0219; Case map
+021A; 021B; Case map
+021C; 021D; Case map
+021E; 021F; Case map
+0220; 019E; Case map
+0222; 0223; Case map
+0224; 0225; Case map
+0226; 0227; Case map
+0228; 0229; Case map
+022A; 022B; Case map
+022C; 022D; Case map
+022E; 022F; Case map
+0230; 0231; Case map
+0232; 0233; Case map
+0345; 03B9; Case map
+0386; 03AC; Case map
+0388; 03AD; Case map
+0389; 03AE; Case map
+038A; 03AF; Case map
+038C; 03CC; Case map
+038E; 03CD; Case map
+038F; 03CE; Case map
+0390; 03B9 0308 0301; Case map
+0391; 03B1; Case map
+0392; 03B2; Case map
+0393; 03B3; Case map
+0394; 03B4; Case map
+0395; 03B5; Case map
+0396; 03B6; Case map
+0397; 03B7; Case map
+0398; 03B8; Case map
+0399; 03B9; Case map
+039A; 03BA; Case map
+039B; 03BB; Case map
+039C; 03BC; Case map
+039D; 03BD; Case map
+039E; 03BE; Case map
+039F; 03BF; Case map
+03A0; 03C0; Case map
+03A1; 03C1; Case map
+03A3; 03C3; Case map
+03A4; 03C4; Case map
+03A5; 03C5; Case map
+03A6; 03C6; Case map
+03A7; 03C7; Case map
+03A8; 03C8; Case map
+03A9; 03C9; Case map
+03AA; 03CA; Case map
+03AB; 03CB; Case map
+03B0; 03C5 0308 0301; Case map
+03C2; 03C3; Case map
+03D0; 03B2; Case map
+03D1; 03B8; Case map
+03D5; 03C6; Case map
+03D6; 03C0; Case map
+03D8; 03D9; Case map
+03DA; 03DB; Case map
+03DC; 03DD; Case map
+03DE; 03DF; Case map
+03E0; 03E1; Case map
+03E2; 03E3; Case map
+03E4; 03E5; Case map
+03E6; 03E7; Case map
+03E8; 03E9; Case map
+03EA; 03EB; Case map
+03EC; 03ED; Case map
+03EE; 03EF; Case map
+03F0; 03BA; Case map
+03F1; 03C1; Case map
+03F2; 03C3; Case map
+03F4; 03B8; Case map
+03F5; 03B5; Case map
+0400; 0450; Case map
+0401; 0451; Case map
+0402; 0452; Case map
+0403; 0453; Case map
+0404; 0454; Case map
+0405; 0455; Case map
+0406; 0456; Case map
+0407; 0457; Case map
+0408; 0458; Case map
+0409; 0459; Case map
+040A; 045A; Case map
+040B; 045B; Case map
+040C; 045C; Case map
+040D; 045D; Case map
+040E; 045E; Case map
+040F; 045F; Case map
+0410; 0430; Case map
+0411; 0431; Case map
+0412; 0432; Case map
+0413; 0433; Case map
+0414; 0434; Case map
+0415; 0435; Case map
+0416; 0436; Case map
+0417; 0437; Case map
+0418; 0438; Case map
+0419; 0439; Case map
+041A; 043A; Case map
+041B; 043B; Case map
+041C; 043C; Case map
+041D; 043D; Case map
+041E; 043E; Case map
+041F; 043F; Case map
+0420; 0440; Case map
+0421; 0441; Case map
+0422; 0442; Case map
+0423; 0443; Case map
+0424; 0444; Case map
+0425; 0445; Case map
+0426; 0446; Case map
+0427; 0447; Case map
+0428; 0448; Case map
+0429; 0449; Case map
+042A; 044A; Case map
+042B; 044B; Case map
+042C; 044C; Case map
+042D; 044D; Case map
+042E; 044E; Case map
+042F; 044F; Case map
+0460; 0461; Case map
+0462; 0463; Case map
+0464; 0465; Case map
+0466; 0467; Case map
+0468; 0469; Case map
+046A; 046B; Case map
+046C; 046D; Case map
+046E; 046F; Case map
+0470; 0471; Case map
+0472; 0473; Case map
+0474; 0475; Case map
+0476; 0477; Case map
+0478; 0479; Case map
+047A; 047B; Case map
+047C; 047D; Case map
+047E; 047F; Case map
+0480; 0481; Case map
+048A; 048B; Case map
+048C; 048D; Case map
+048E; 048F; Case map
+0490; 0491; Case map
+0492; 0493; Case map
+0494; 0495; Case map
+0496; 0497; Case map
+0498; 0499; Case map
+049A; 049B; Case map
+049C; 049D; Case map
+049E; 049F; Case map
+04A0; 04A1; Case map
+04A2; 04A3; Case map
+04A4; 04A5; Case map
+04A6; 04A7; Case map
+04A8; 04A9; Case map
+04AA; 04AB; Case map
+04AC; 04AD; Case map
+04AE; 04AF; Case map
+04B0; 04B1; Case map
+04B2; 04B3; Case map
+04B4; 04B5; Case map
+04B6; 04B7; Case map
+04B8; 04B9; Case map
+04BA; 04BB; Case map
+04BC; 04BD; Case map
+04BE; 04BF; Case map
+04C1; 04C2; Case map
+04C3; 04C4; Case map
+04C5; 04C6; Case map
+04C7; 04C8; Case map
+04C9; 04CA; Case map
+04CB; 04CC; Case map
+04CD; 04CE; Case map
+04D0; 04D1; Case map
+04D2; 04D3; Case map
+04D4; 04D5; Case map
+04D6; 04D7; Case map
+04D8; 04D9; Case map
+04DA; 04DB; Case map
+04DC; 04DD; Case map
+04DE; 04DF; Case map
+04E0; 04E1; Case map
+04E2; 04E3; Case map
+04E4; 04E5; Case map
+04E6; 04E7; Case map
+04E8; 04E9; Case map
+04EA; 04EB; Case map
+04EC; 04ED; Case map
+04EE; 04EF; Case map
+04F0; 04F1; Case map
+04F2; 04F3; Case map
+04F4; 04F5; Case map
+04F8; 04F9; Case map
+0500; 0501; Case map
+0502; 0503; Case map
+0504; 0505; Case map
+0506; 0507; Case map
+0508; 0509; Case map
+050A; 050B; Case map
+050C; 050D; Case map
+050E; 050F; Case map
+0531; 0561; Case map
+0532; 0562; Case map
+0533; 0563; Case map
+0534; 0564; Case map
+0535; 0565; Case map
+0536; 0566; Case map
+0537; 0567; Case map
+0538; 0568; Case map
+0539; 0569; Case map
+053A; 056A; Case map
+053B; 056B; Case map
+053C; 056C; Case map
+053D; 056D; Case map
+053E; 056E; Case map
+053F; 056F; Case map
+0540; 0570; Case map
+0541; 0571; Case map
+0542; 0572; Case map
+0543; 0573; Case map
+0544; 0574; Case map
+0545; 0575; Case map
+0546; 0576; Case map
+0547; 0577; Case map
+0548; 0578; Case map
+0549; 0579; Case map
+054A; 057A; Case map
+054B; 057B; Case map
+054C; 057C; Case map
+054D; 057D; Case map
+054E; 057E; Case map
+054F; 057F; Case map
+0550; 0580; Case map
+0551; 0581; Case map
+0552; 0582; Case map
+0553; 0583; Case map
+0554; 0584; Case map
+0555; 0585; Case map
+0556; 0586; Case map
+0587; 0565 0582; Case map
+1E00; 1E01; Case map
+1E02; 1E03; Case map
+1E04; 1E05; Case map
+1E06; 1E07; Case map
+1E08; 1E09; Case map
+1E0A; 1E0B; Case map
+1E0C; 1E0D; Case map
+1E0E; 1E0F; Case map
+1E10; 1E11; Case map
+1E12; 1E13; Case map
+1E14; 1E15; Case map
+1E16; 1E17; Case map
+1E18; 1E19; Case map
+1E1A; 1E1B; Case map
+1E1C; 1E1D; Case map
+1E1E; 1E1F; Case map
+1E20; 1E21; Case map
+1E22; 1E23; Case map
+1E24; 1E25; Case map
+1E26; 1E27; Case map
+1E28; 1E29; Case map
+1E2A; 1E2B; Case map
+1E2C; 1E2D; Case map
+1E2E; 1E2F; Case map
+1E30; 1E31; Case map
+1E32; 1E33; Case map
+1E34; 1E35; Case map
+1E36; 1E37; Case map
+1E38; 1E39; Case map
+1E3A; 1E3B; Case map
+1E3C; 1E3D; Case map
+1E3E; 1E3F; Case map
+1E40; 1E41; Case map
+1E42; 1E43; Case map
+1E44; 1E45; Case map
+1E46; 1E47; Case map
+1E48; 1E49; Case map
+1E4A; 1E4B; Case map
+1E4C; 1E4D; Case map
+1E4E; 1E4F; Case map
+1E50; 1E51; Case map
+1E52; 1E53; Case map
+1E54; 1E55; Case map
+1E56; 1E57; Case map
+1E58; 1E59; Case map
+1E5A; 1E5B; Case map
+1E5C; 1E5D; Case map
+1E5E; 1E5F; Case map
+1E60; 1E61; Case map
+1E62; 1E63; Case map
+1E64; 1E65; Case map
+1E66; 1E67; Case map
+1E68; 1E69; Case map
+1E6A; 1E6B; Case map
+1E6C; 1E6D; Case map
+1E6E; 1E6F; Case map
+1E70; 1E71; Case map
+1E72; 1E73; Case map
+1E74; 1E75; Case map
+1E76; 1E77; Case map
+1E78; 1E79; Case map
+1E7A; 1E7B; Case map
+1E7C; 1E7D; Case map
+1E7E; 1E7F; Case map
+1E80; 1E81; Case map
+1E82; 1E83; Case map
+1E84; 1E85; Case map
+1E86; 1E87; Case map
+1E88; 1E89; Case map
+1E8A; 1E8B; Case map
+1E8C; 1E8D; Case map
+1E8E; 1E8F; Case map
+1E90; 1E91; Case map
+1E92; 1E93; Case map
+1E94; 1E95; Case map
+1E96; 0068 0331; Case map
+1E97; 0074 0308; Case map
+1E98; 0077 030A; Case map
+1E99; 0079 030A; Case map
+1E9A; 0061 02BE; Case map
+1E9B; 1E61; Case map
+1EA0; 1EA1; Case map
+1EA2; 1EA3; Case map
+1EA4; 1EA5; Case map
+1EA6; 1EA7; Case map
+1EA8; 1EA9; Case map
+1EAA; 1EAB; Case map
+1EAC; 1EAD; Case map
+1EAE; 1EAF; Case map
+1EB0; 1EB1; Case map
+1EB2; 1EB3; Case map
+1EB4; 1EB5; Case map
+1EB6; 1EB7; Case map
+1EB8; 1EB9; Case map
+1EBA; 1EBB; Case map
+1EBC; 1EBD; Case map
+1EBE; 1EBF; Case map
+1EC0; 1EC1; Case map
+1EC2; 1EC3; Case map
+1EC4; 1EC5; Case map
+1EC6; 1EC7; Case map
+1EC8; 1EC9; Case map
+1ECA; 1ECB; Case map
+1ECC; 1ECD; Case map
+1ECE; 1ECF; Case map
+1ED0; 1ED1; Case map
+1ED2; 1ED3; Case map
+1ED4; 1ED5; Case map
+1ED6; 1ED7; Case map
+1ED8; 1ED9; Case map
+1EDA; 1EDB; Case map
+1EDC; 1EDD; Case map
+1EDE; 1EDF; Case map
+1EE0; 1EE1; Case map
+1EE2; 1EE3; Case map
+1EE4; 1EE5; Case map
+1EE6; 1EE7; Case map
+1EE8; 1EE9; Case map
+1EEA; 1EEB; Case map
+1EEC; 1EED; Case map
+1EEE; 1EEF; Case map
+1EF0; 1EF1; Case map
+1EF2; 1EF3; Case map
+1EF4; 1EF5; Case map
+1EF6; 1EF7; Case map
+1EF8; 1EF9; Case map
+1F08; 1F00; Case map
+1F09; 1F01; Case map
+1F0A; 1F02; Case map
+1F0B; 1F03; Case map
+1F0C; 1F04; Case map
+1F0D; 1F05; Case map
+1F0E; 1F06; Case map
+1F0F; 1F07; Case map
+1F18; 1F10; Case map
+1F19; 1F11; Case map
+1F1A; 1F12; Case map
+1F1B; 1F13; Case map
+1F1C; 1F14; Case map
+1F1D; 1F15; Case map
+1F28; 1F20; Case map
+1F29; 1F21; Case map
+1F2A; 1F22; Case map
+1F2B; 1F23; Case map
+1F2C; 1F24; Case map
+1F2D; 1F25; Case map
+1F2E; 1F26; Case map
+1F2F; 1F27; Case map
+1F38; 1F30; Case map
+1F39; 1F31; Case map
+1F3A; 1F32; Case map
+1F3B; 1F33; Case map
+1F3C; 1F34; Case map
+1F3D; 1F35; Case map
+1F3E; 1F36; Case map
+1F3F; 1F37; Case map
+1F48; 1F40; Case map
+1F49; 1F41; Case map
+1F4A; 1F42; Case map
+1F4B; 1F43; Case map
+1F4C; 1F44; Case map
+1F4D; 1F45; Case map
+1F50; 03C5 0313; Case map
+1F52; 03C5 0313 0300; Case map
+1F54; 03C5 0313 0301; Case map
+1F56; 03C5 0313 0342; Case map
+1F59; 1F51; Case map
+1F5B; 1F53; Case map
+1F5D; 1F55; Case map
+1F5F; 1F57; Case map
+1F68; 1F60; Case map
+1F69; 1F61; Case map
+1F6A; 1F62; Case map
+1F6B; 1F63; Case map
+1F6C; 1F64; Case map
+1F6D; 1F65; Case map
+1F6E; 1F66; Case map
+1F6F; 1F67; Case map
+1F80; 1F00 03B9; Case map
+1F81; 1F01 03B9; Case map
+1F82; 1F02 03B9; Case map
+1F83; 1F03 03B9; Case map
+1F84; 1F04 03B9; Case map
+1F85; 1F05 03B9; Case map
+1F86; 1F06 03B9; Case map
+1F87; 1F07 03B9; Case map
+1F88; 1F00 03B9; Case map
+1F89; 1F01 03B9; Case map
+1F8A; 1F02 03B9; Case map
+1F8B; 1F03 03B9; Case map
+1F8C; 1F04 03B9; Case map
+1F8D; 1F05 03B9; Case map
+1F8E; 1F06 03B9; Case map
+1F8F; 1F07 03B9; Case map
+1F90; 1F20 03B9; Case map
+1F91; 1F21 03B9; Case map
+1F92; 1F22 03B9; Case map
+1F93; 1F23 03B9; Case map
+1F94; 1F24 03B9; Case map
+1F95; 1F25 03B9; Case map
+1F96; 1F26 03B9; Case map
+1F97; 1F27 03B9; Case map
+1F98; 1F20 03B9; Case map
+1F99; 1F21 03B9; Case map
+1F9A; 1F22 03B9; Case map
+1F9B; 1F23 03B9; Case map
+1F9C; 1F24 03B9; Case map
+1F9D; 1F25 03B9; Case map
+1F9E; 1F26 03B9; Case map
+1F9F; 1F27 03B9; Case map
+1FA0; 1F60 03B9; Case map
+1FA1; 1F61 03B9; Case map
+1FA2; 1F62 03B9; Case map
+1FA3; 1F63 03B9; Case map
+1FA4; 1F64 03B9; Case map
+1FA5; 1F65 03B9; Case map
+1FA6; 1F66 03B9; Case map
+1FA7; 1F67 03B9; Case map
+1FA8; 1F60 03B9; Case map
+1FA9; 1F61 03B9; Case map
+1FAA; 1F62 03B9; Case map
+1FAB; 1F63 03B9; Case map
+1FAC; 1F64 03B9; Case map
+1FAD; 1F65 03B9; Case map
+1FAE; 1F66 03B9; Case map
+1FAF; 1F67 03B9; Case map
+1FB2; 1F70 03B9; Case map
+1FB3; 03B1 03B9; Case map
+1FB4; 03AC 03B9; Case map
+1FB6; 03B1 0342; Case map
+1FB7; 03B1 0342 03B9; Case map
+1FB8; 1FB0; Case map
+1FB9; 1FB1; Case map
+1FBA; 1F70; Case map
+1FBB; 1F71; Case map
+1FBC; 03B1 03B9; Case map
+1FBE; 03B9; Case map
+1FC2; 1F74 03B9; Case map
+1FC3; 03B7 03B9; Case map
+1FC4; 03AE 03B9; Case map
+1FC6; 03B7 0342; Case map
+1FC7; 03B7 0342 03B9; Case map
+1FC8; 1F72; Case map
+1FC9; 1F73; Case map
+1FCA; 1F74; Case map
+1FCB; 1F75; Case map
+1FCC; 03B7 03B9; Case map
+1FD2; 03B9 0308 0300; Case map
+1FD3; 03B9 0308 0301; Case map
+1FD6; 03B9 0342; Case map
+1FD7; 03B9 0308 0342; Case map
+1FD8; 1FD0; Case map
+1FD9; 1FD1; Case map
+1FDA; 1F76; Case map
+1FDB; 1F77; Case map
+1FE2; 03C5 0308 0300; Case map
+1FE3; 03C5 0308 0301; Case map
+1FE4; 03C1 0313; Case map
+1FE6; 03C5 0342; Case map
+1FE7; 03C5 0308 0342; Case map
+1FE8; 1FE0; Case map
+1FE9; 1FE1; Case map
+1FEA; 1F7A; Case map
+1FEB; 1F7B; Case map
+1FEC; 1FE5; Case map
+1FF2; 1F7C 03B9; Case map
+1FF3; 03C9 03B9; Case map
+1FF4; 03CE 03B9; Case map
+1FF6; 03C9 0342; Case map
+1FF7; 03C9 0342 03B9; Case map
+1FF8; 1F78; Case map
+1FF9; 1F79; Case map
+1FFA; 1F7C; Case map
+1FFB; 1F7D; Case map
+1FFC; 03C9 03B9; Case map
+2126; 03C9; Case map
+212A; 006B; Case map
+212B; 00E5; Case map
+2160; 2170; Case map
+2161; 2171; Case map
+2162; 2172; Case map
+2163; 2173; Case map
+2164; 2174; Case map
+2165; 2175; Case map
+2166; 2176; Case map
+2167; 2177; Case map
+2168; 2178; Case map
+2169; 2179; Case map
+216A; 217A; Case map
+216B; 217B; Case map
+216C; 217C; Case map
+216D; 217D; Case map
+216E; 217E; Case map
+216F; 217F; Case map
+24B6; 24D0; Case map
+24B7; 24D1; Case map
+24B8; 24D2; Case map
+24B9; 24D3; Case map
+24BA; 24D4; Case map
+24BB; 24D5; Case map
+24BC; 24D6; Case map
+24BD; 24D7; Case map
+24BE; 24D8; Case map
+24BF; 24D9; Case map
+24C0; 24DA; Case map
+24C1; 24DB; Case map
+24C2; 24DC; Case map
+24C3; 24DD; Case map
+24C4; 24DE; Case map
+24C5; 24DF; Case map
+24C6; 24E0; Case map
+24C7; 24E1; Case map
+24C8; 24E2; Case map
+24C9; 24E3; Case map
+24CA; 24E4; Case map
+24CB; 24E5; Case map
+24CC; 24E6; Case map
+24CD; 24E7; Case map
+24CE; 24E8; Case map
+24CF; 24E9; Case map
+FB00; 0066 0066; Case map
+FB01; 0066 0069; Case map
+FB02; 0066 006C; Case map
+FB03; 0066 0066 0069; Case map
+FB04; 0066 0066 006C; Case map
+FB05; 0073 0074; Case map
+FB06; 0073 0074; Case map
+FB13; 0574 0576; Case map
+FB14; 0574 0565; Case map
+FB15; 0574 056B; Case map
+FB16; 057E 0576; Case map
+FB17; 0574 056D; Case map
+FF21; FF41; Case map
+FF22; FF42; Case map
+FF23; FF43; Case map
+FF24; FF44; Case map
+FF25; FF45; Case map
+FF26; FF46; Case map
+FF27; FF47; Case map
+FF28; FF48; Case map
+FF29; FF49; Case map
+FF2A; FF4A; Case map
+FF2B; FF4B; Case map
+FF2C; FF4C; Case map
+FF2D; FF4D; Case map
+FF2E; FF4E; Case map
+FF2F; FF4F; Case map
+FF30; FF50; Case map
+FF31; FF51; Case map
+FF32; FF52; Case map
+FF33; FF53; Case map
+FF34; FF54; Case map
+FF35; FF55; Case map
+FF36; FF56; Case map
+FF37; FF57; Case map
+FF38; FF58; Case map
+FF39; FF59; Case map
+FF3A; FF5A; Case map
+10400; 10428; Case map
+10401; 10429; Case map
+10402; 1042A; Case map
+10403; 1042B; Case map
+10404; 1042C; Case map
+10405; 1042D; Case map
+10406; 1042E; Case map
+10407; 1042F; Case map
+10408; 10430; Case map
+10409; 10431; Case map
+1040A; 10432; Case map
+1040B; 10433; Case map
+1040C; 10434; Case map
+1040D; 10435; Case map
+1040E; 10436; Case map
+1040F; 10437; Case map
+10410; 10438; Case map
+10411; 10439; Case map
+10412; 1043A; Case map
+10413; 1043B; Case map
+10414; 1043C; Case map
+10415; 1043D; Case map
+10416; 1043E; Case map
+10417; 1043F; Case map
+10418; 10440; Case map
+10419; 10441; Case map
+1041A; 10442; Case map
+1041B; 10443; Case map
+1041C; 10444; Case map
+1041D; 10445; Case map
+1041E; 10446; Case map
+1041F; 10447; Case map
+10420; 10448; Case map
+10421; 10449; Case map
+10422; 1044A; Case map
+10423; 1044B; Case map
+10424; 1044C; Case map
+10425; 1044D; Case map
diff --git a/data/C.1.1 b/data/C.1.1
new file mode 100644
index 0000000..de6fa71
--- /dev/null
+++ b/data/C.1.1
@@ -0,0 +1 @@
+0020; SPACE
diff --git a/data/C.1.2 b/data/C.1.2
new file mode 100644
index 0000000..9ce5eb7
--- /dev/null
+++ b/data/C.1.2
@@ -0,0 +1,17 @@
+00A0; NO-BREAK SPACE
+1680; OGHAM SPACE MARK
+2000; EN QUAD
+2001; EM QUAD
+2002; EN SPACE
+2003; EM SPACE
+2004; THREE-PER-EM SPACE
+2005; FOUR-PER-EM SPACE
+2006; SIX-PER-EM SPACE
+2007; FIGURE SPACE
+2008; PUNCTUATION SPACE
+2009; THIN SPACE
+200A; HAIR SPACE
+200B; ZERO WIDTH SPACE
+202F; NARROW NO-BREAK SPACE
+205F; MEDIUM MATHEMATICAL SPACE
+3000; IDEOGRAPHIC SPACE
diff --git a/data/C.2.1 b/data/C.2.1
new file mode 100644
index 0000000..70cf5ee
--- /dev/null
+++ b/data/C.2.1
@@ -0,0 +1,2 @@
+0000-001F; [CONTROL CHARACTERS]
+007F; DELETE
diff --git a/data/C.2.2 b/data/C.2.2
new file mode 100644
index 0000000..665db0d
--- /dev/null
+++ b/data/C.2.2
@@ -0,0 +1,16 @@
+0080-009F; [CONTROL CHARACTERS]
+06DD; ARABIC END OF AYAH
+070F; SYRIAC ABBREVIATION MARK
+180E; MONGOLIAN VOWEL SEPARATOR
+200C; ZERO WIDTH NON-JOINER
+200D; ZERO WIDTH JOINER
+2028; LINE SEPARATOR
+2029; PARAGRAPH SEPARATOR
+2060; WORD JOINER
+2061; FUNCTION APPLICATION
+2062; INVISIBLE TIMES
+2063; INVISIBLE SEPARATOR
+206A-206F; [CONTROL CHARACTERS]
+FEFF; ZERO WIDTH NO-BREAK SPACE
+FFF9-FFFC; [CONTROL CHARACTERS]
+1D173-1D17A; [MUSICAL CONTROL CHARACTERS]
diff --git a/data/C.3 b/data/C.3
new file mode 100644
index 0000000..d333f64
--- /dev/null
+++ b/data/C.3
@@ -0,0 +1,3 @@
+E000-F8FF; [PRIVATE USE, PLANE 0]
+F0000-FFFFD; [PRIVATE USE, PLANE 15]
+100000-10FFFD; [PRIVATE USE, PLANE 16]
diff --git a/data/C.4 b/data/C.4
new file mode 100644
index 0000000..36dffa0
--- /dev/null
+++ b/data/C.4
@@ -0,0 +1,18 @@
+FDD0-FDEF; [NONCHARACTER CODE POINTS]
+FFFE-FFFF; [NONCHARACTER CODE POINTS]
+1FFFE-1FFFF; [NONCHARACTER CODE POINTS]
+2FFFE-2FFFF; [NONCHARACTER CODE POINTS]
+3FFFE-3FFFF; [NONCHARACTER CODE POINTS]
+4FFFE-4FFFF; [NONCHARACTER CODE POINTS]
+5FFFE-5FFFF; [NONCHARACTER CODE POINTS]
+6FFFE-6FFFF; [NONCHARACTER CODE POINTS]
+7FFFE-7FFFF; [NONCHARACTER CODE POINTS]
+8FFFE-8FFFF; [NONCHARACTER CODE POINTS]
+9FFFE-9FFFF; [NONCHARACTER CODE POINTS]
+AFFFE-AFFFF; [NONCHARACTER CODE POINTS]
+BFFFE-BFFFF; [NONCHARACTER CODE POINTS]
+CFFFE-CFFFF; [NONCHARACTER CODE POINTS]
+DFFFE-DFFFF; [NONCHARACTER CODE POINTS]
+EFFFE-EFFFF; [NONCHARACTER CODE POINTS]
+FFFFE-FFFFF; [NONCHARACTER CODE POINTS]
+10FFFE-10FFFF; [NONCHARACTER CODE POINTS]
diff --git a/data/C.5 b/data/C.5
new file mode 100644
index 0000000..6f0fc11
--- /dev/null
+++ b/data/C.5
@@ -0,0 +1 @@
+D800-DFFF; [SURROGATE CODES]
diff --git a/data/C.6 b/data/C.6
new file mode 100644
index 0000000..023cdc6
--- /dev/null
+++ b/data/C.6
@@ -0,0 +1,5 @@
+FFF9; INTERLINEAR ANNOTATION ANCHOR
+FFFA; INTERLINEAR ANNOTATION SEPARATOR
+FFFB; INTERLINEAR ANNOTATION TERMINATOR
+FFFC; OBJECT REPLACEMENT CHARACTER
+FFFD; REPLACEMENT CHARACTER
diff --git a/data/C.7 b/data/C.7
new file mode 100644
index 0000000..abe8977
--- /dev/null
+++ b/data/C.7
@@ -0,0 +1 @@
+2FF0-2FFB; [IDEOGRAPHIC DESCRIPTION CHARACTERS]
diff --git a/data/C.8 b/data/C.8
new file mode 100644
index 0000000..f461fba
--- /dev/null
+++ b/data/C.8
@@ -0,0 +1,15 @@
+0340; COMBINING GRAVE TONE MARK
+0341; COMBINING ACUTE TONE MARK
+200E; LEFT-TO-RIGHT MARK
+200F; RIGHT-TO-LEFT MARK
+202A; LEFT-TO-RIGHT EMBEDDING
+202B; RIGHT-TO-LEFT EMBEDDING
+202C; POP DIRECTIONAL FORMATTING
+202D; LEFT-TO-RIGHT OVERRIDE
+202E; RIGHT-TO-LEFT OVERRIDE
+206A; INHIBIT SYMMETRIC SWAPPING
+206B; ACTIVATE SYMMETRIC SWAPPING
+206C; INHIBIT ARABIC FORM SHAPING
+206D; ACTIVATE ARABIC FORM SHAPING
+206E; NATIONAL DIGIT SHAPES
+206F; NOMINAL DIGIT SHAPES
diff --git a/data/C.9 b/data/C.9
new file mode 100644
index 0000000..9c41636
--- /dev/null
+++ b/data/C.9
@@ -0,0 +1,2 @@
+E0001; LANGUAGE TAG
+E0020-E007F; [TAGGING CHARACTERS]
diff --git a/data/D.1 b/data/D.1
new file mode 100644
index 0000000..02ad2ba
--- /dev/null
+++ b/data/D.1
@@ -0,0 +1,34 @@
+05BE
+05C0
+05C3
+05D0-05EA
+05F0-05F4
+061B
+061F
+0621-063A
+0640-064A
+066D-066F
+0671-06D5
+06DD
+06E5-06E6
+06FA-06FE
+0700-070D
+0710
+0712-072C
+0780-07A5
+07B1
+200F
+FB1D
+FB1F-FB28
+FB2A-FB36
+FB38-FB3C
+FB3E
+FB40-FB41
+FB43-FB44
+FB46-FBB1
+FBD3-FD3D
+FD50-FD8F
+FD92-FDC7
+FDF0-FDFC
+FE70-FE74
+FE76-FEFC
diff --git a/data/D.2 b/data/D.2
new file mode 100644
index 0000000..b6d9934
--- /dev/null
+++ b/data/D.2
@@ -0,0 +1,360 @@
+0041-005A
+0061-007A
+00AA
+00B5
+00BA
+00C0-00D6
+00D8-00F6
+00F8-0220
+0222-0233
+0250-02AD
+02B0-02B8
+02BB-02C1
+02D0-02D1
+02E0-02E4
+02EE
+037A
+0386
+0388-038A
+038C
+038E-03A1
+03A3-03CE
+03D0-03F5
+0400-0482
+048A-04CE
+04D0-04F5
+04F8-04F9
+0500-050F
+0531-0556
+0559-055F
+0561-0587
+0589
+0903
+0905-0939
+093D-0940
+0949-094C
+0950
+0958-0961
+0964-0970
+0982-0983
+0985-098C
+098F-0990
+0993-09A8
+09AA-09B0
+09B2
+09B6-09B9
+09BE-09C0
+09C7-09C8
+09CB-09CC
+09D7
+09DC-09DD
+09DF-09E1
+09E6-09F1
+09F4-09FA
+0A05-0A0A
+0A0F-0A10
+0A13-0A28
+0A2A-0A30
+0A32-0A33
+0A35-0A36
+0A38-0A39
+0A3E-0A40
+0A59-0A5C
+0A5E
+0A66-0A6F
+0A72-0A74
+0A83
+0A85-0A8B
+0A8D
+0A8F-0A91
+0A93-0AA8
+0AAA-0AB0
+0AB2-0AB3
+0AB5-0AB9
+0ABD-0AC0
+0AC9
+0ACB-0ACC
+0AD0
+0AE0
+0AE6-0AEF
+0B02-0B03
+0B05-0B0C
+0B0F-0B10
+0B13-0B28
+0B2A-0B30
+0B32-0B33
+0B36-0B39
+0B3D-0B3E
+0B40
+0B47-0B48
+0B4B-0B4C
+0B57
+0B5C-0B5D
+0B5F-0B61
+0B66-0B70
+0B83
+0B85-0B8A
+0B8E-0B90
+0B92-0B95
+0B99-0B9A
+0B9C
+0B9E-0B9F
+0BA3-0BA4
+0BA8-0BAA
+0BAE-0BB5
+0BB7-0BB9
+0BBE-0BBF
+0BC1-0BC2
+0BC6-0BC8
+0BCA-0BCC
+0BD7
+0BE7-0BF2
+0C01-0C03
+0C05-0C0C
+0C0E-0C10
+0C12-0C28
+0C2A-0C33
+0C35-0C39
+0C41-0C44
+0C60-0C61
+0C66-0C6F
+0C82-0C83
+0C85-0C8C
+0C8E-0C90
+0C92-0CA8
+0CAA-0CB3
+0CB5-0CB9
+0CBE
+0CC0-0CC4
+0CC7-0CC8
+0CCA-0CCB
+0CD5-0CD6
+0CDE
+0CE0-0CE1
+0CE6-0CEF
+0D02-0D03
+0D05-0D0C
+0D0E-0D10
+0D12-0D28
+0D2A-0D39
+0D3E-0D40
+0D46-0D48
+0D4A-0D4C
+0D57
+0D60-0D61
+0D66-0D6F
+0D82-0D83
+0D85-0D96
+0D9A-0DB1
+0DB3-0DBB
+0DBD
+0DC0-0DC6
+0DCF-0DD1
+0DD8-0DDF
+0DF2-0DF4
+0E01-0E30
+0E32-0E33
+0E40-0E46
+0E4F-0E5B
+0E81-0E82
+0E84
+0E87-0E88
+0E8A
+0E8D
+0E94-0E97
+0E99-0E9F
+0EA1-0EA3
+0EA5
+0EA7
+0EAA-0EAB
+0EAD-0EB0
+0EB2-0EB3
+0EBD
+0EC0-0EC4
+0EC6
+0ED0-0ED9
+0EDC-0EDD
+0F00-0F17
+0F1A-0F34
+0F36
+0F38
+0F3E-0F47
+0F49-0F6A
+0F7F
+0F85
+0F88-0F8B
+0FBE-0FC5
+0FC7-0FCC
+0FCF
+1000-1021
+1023-1027
+1029-102A
+102C
+1031
+1038
+1040-1057
+10A0-10C5
+10D0-10F8
+10FB
+1100-1159
+115F-11A2
+11A8-11F9
+1200-1206
+1208-1246
+1248
+124A-124D
+1250-1256
+1258
+125A-125D
+1260-1286
+1288
+128A-128D
+1290-12AE
+12B0
+12B2-12B5
+12B8-12BE
+12C0
+12C2-12C5
+12C8-12CE
+12D0-12D6
+12D8-12EE
+12F0-130E
+1310
+1312-1315
+1318-131E
+1320-1346
+1348-135A
+1361-137C
+13A0-13F4
+1401-1676
+1681-169A
+16A0-16F0
+1700-170C
+170E-1711
+1720-1731
+1735-1736
+1740-1751
+1760-176C
+176E-1770
+1780-17B6
+17BE-17C5
+17C7-17C8
+17D4-17DA
+17DC
+17E0-17E9
+1810-1819
+1820-1877
+1880-18A8
+1E00-1E9B
+1EA0-1EF9
+1F00-1F15
+1F18-1F1D
+1F20-1F45
+1F48-1F4D
+1F50-1F57
+1F59
+1F5B
+1F5D
+1F5F-1F7D
+1F80-1FB4
+1FB6-1FBC
+1FBE
+1FC2-1FC4
+1FC6-1FCC
+1FD0-1FD3
+1FD6-1FDB
+1FE0-1FEC
+1FF2-1FF4
+1FF6-1FFC
+200E
+2071
+207F
+2102
+2107
+210A-2113
+2115
+2119-211D
+2124
+2126
+2128
+212A-212D
+212F-2131
+2133-2139
+213D-213F
+2145-2149
+2160-2183
+2336-237A
+2395
+249C-24E9
+3005-3007
+3021-3029
+3031-3035
+3038-303C
+3041-3096
+309D-309F
+30A1-30FA
+30FC-30FF
+3105-312C
+3131-318E
+3190-31B7
+31F0-321C
+3220-3243
+3260-327B
+327F-32B0
+32C0-32CB
+32D0-32FE
+3300-3376
+337B-33DD
+33E0-33FE
+3400-4DB5
+4E00-9FA5
+A000-A48C
+AC00-D7A3
+D800-FA2D
+FA30-FA6A
+FB00-FB06
+FB13-FB17
+FF21-FF3A
+FF41-FF5A
+FF66-FFBE
+FFC2-FFC7
+FFCA-FFCF
+FFD2-FFD7
+FFDA-FFDC
+10300-1031E
+10320-10323
+10330-1034A
+10400-10425
+10428-1044D
+1D000-1D0F5
+1D100-1D126
+1D12A-1D166
+1D16A-1D172
+1D183-1D184
+1D18C-1D1A9
+1D1AE-1D1DD
+1D400-1D454
+1D456-1D49C
+1D49E-1D49F
+1D4A2
+1D4A5-1D4A6
+1D4A9-1D4AC
+1D4AE-1D4B9
+1D4BB
+1D4BD-1D4C0
+1D4C2-1D4C3
+1D4C5-1D505
+1D507-1D50A
+1D50D-1D514
+1D516-1D51C
+1D51E-1D539
+1D53B-1D53E
+1D540-1D544
+1D546
+1D54A-1D550
+1D552-1D6A3
+1D6A8-1D7C9
+20000-2A6D6
+2F800-2FA1D
+F0000-FFFFD
+100000-10FFFD
diff --git a/data/Makefile.am b/data/Makefile.am
new file mode 100644
index 0000000..0ba422b
--- /dev/null
+++ b/data/Makefile.am
@@ -0,0 +1,22 @@
+tabledir = $(pkgdatadir)/tables
+
+dist_table_DATA = \
+ A.1 \
+ B.1 \
+ B.2 \
+ B.3 \
+ C.1.1 \
+ C.1.2 \
+ C.2.1 \
+ C.2.2 \
+ C.3 \
+ C.4 \
+ C.5 \
+ C.6 \
+ C.7 \
+ C.8 \
+ C.9 \
+ D.1 \
+ D.2
+
+EXTRA_DIST = extract-table.pl
diff --git a/data/extract-table.pl b/data/extract-table.pl
new file mode 100755
index 0000000..6a72633
--- /dev/null
+++ b/data/extract-table.pl
@@ -0,0 +1,18 @@
+#!/usr/bin/perl
+
+# This script can be used to extract table listings from
+# a plain text document formatted like RFC 3454 (stringprep).
+# It takes the table name from the first command line parameter, and
+# extracts the table listing from the text on input to print it
+# on standard output.
+
+$table_name = $ARGV[0];
+shift @ARGV;
+
+while (<>) {
+ next unless
+ /^ ----- Start Table \Q${table_name}\E -----/
+ ..
+ /^ ----- End Table \Q${table_name}\E -----/;
+ /^ ([[:xdigit:]]+.*)/ and print $1, "\n";
+}
diff --git a/doc/Makefile.am b/doc/Makefile.am
new file mode 100644
index 0000000..cf2dc6f
--- /dev/null
+++ b/doc/Makefile.am
@@ -0,0 +1 @@
+EXTRA_DIST = rfc3454.txt
diff --git a/doc/rfc3454.txt b/doc/rfc3454.txt
new file mode 100644
index 0000000..0d2debc
--- /dev/null
+++ b/doc/rfc3454.txt
@@ -0,0 +1,3249 @@
+The text below was copied from libidn sources;
+see http://www.gnu.org/software/libidn/
+
+Below there are data tables extracted from RFC 3454. The license for
+RFC 3454 is:
+
+ Copyright (C) The Internet Society (2002). All Rights Reserved.
+
+ This document and translations of it may be copied and furnished to
+ others, and derivative works that comment on or otherwise explain it
+ or assist in its implementation may be prepared, copied, published
+ and distributed, in whole or in part, without restriction of any
+ kind, provided that the above copyright notice and this paragraph are
+ included on all such copies and derivative works. However, this
+ document itself may not be modified in any way, such as by removing
+ the copyright notice or references to the Internet Society or other
+ Internet organizations, except as needed for the purpose of
+ developing Internet standards in which case the procedures for
+ copyrights defined in the Internet Standards process must be
+ followed, or as required to translate it into languages other than
+ English.
+
+ The limited permissions granted above are perpetual and will not be
+ revoked by the Internet Society or its successors or assigns.
+
+ This document and the information contained herein is provided on an
+ "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+ TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+ HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Unfortunately, that license is non-free according to
+licensing@fsf.org:
+
+ From: "Dave Turner via RT" <licensing@fsf.org>
+ Date: Thu, 08 Dec 2005 16:33:57 -0500
+ Subject: [gnu.org #211910] Are RFC specifications freely licensed?
+
+ > Hi Dave! I know this is an old issue (last post in this thread was
+ > about a year ago), but have you heard back from the licensing
+ > committee on the RFC 2026 and RFC 3978 licenses?
+
+ Sorry for the delay. The old terms are officially non-free.
+
+However, to be copyrightable there needs to be some originality, which
+isn't present here, see:
+
+ From: "novalis@fsf.org via RT" <licensing@fsf.org>
+ Subject: Re: [gnu.org #211910] Are RFC specifications freely licensed?
+ Date: Thu, 06 Jan 2005 18:32:02 -0500
+
+ >> >> > If not, it's entirely possible that they're not copyrightable, or that
+ >> >> > they have very thin protection. I would need to see them specifically
+ >> >> > to be able to determine this.
+ >> >>
+ >> >> The table fall under the old license. The ASN.1 schema fall under the
+ >> >> new license. I'm attaching the tables, and the ASN.1 schema below.
+ >> >> If it matters: Some tables are derived from Unicode tables, and some
+ >> >> were probably created by hand.
+ >> >
+ >> > It looks to me like these tables do not have enough originality to be
+ >> > copyrightable. The text surrounding them ("The following is the mapping
+ >> > table from section 3....") is probably minimally original and should be
+ >> > removed.
+ >>
+ >> Are you sure about this? I'm looking for something strong than "It
+ >> looks". The tables were not trivial to create, it took the IETF some
+ >> time (years) to arrive with the final tables. Perhaps the tables
+ >> could be argued to contain some artistic value. But I'm not an expert
+ >> on this, so these are just my thoughts.
+ >
+ > I'm not a lawyer. This isn't legal advice. If you need legal advice,
+ > talk to a lawyer. I can get a second opinion on this from our lawyers,
+ > if you think it's important, but it still won't be legal advice.
+ >
+ > From a copyright perspective, the time and effort ("sweat of the brow")
+ > that a given thing takes don't matter (Fiest v. Rural Telephone
+ > Service). What matters is the originality.
+ >
+ > I don't see a lot here that's original. The names are probably
+ > original, but names are generally unprotected. And if the names are
+ > needed for compatibility, the scenes a faire doctrine comes into play.
+
+ Right, the names are not required, only the actual numbers are.
+
+ Thanks, this information seem to solve my problem for the source code
+ in libidn.
+
+So we can use this material. There may be other legal analysis that
+also reach the same conclusion.
+
+ ----- Start Table A.1 -----
+ 0221
+ 0234-024F
+ 02AE-02AF
+ 02EF-02FF
+ 0350-035F
+ 0370-0373
+ 0376-0379
+ 037B-037D
+ 037F-0383
+ 038B
+ 038D
+ 03A2
+ 03CF
+ 03F7-03FF
+ 0487
+ 04CF
+ 04F6-04F7
+ 04FA-04FF
+ 0510-0530
+ 0557-0558
+ 0560
+ 0588
+ 058B-0590
+ 05A2
+ 05BA
+ 05C5-05CF
+ 05EB-05EF
+ 05F5-060B
+ 060D-061A
+ 061C-061E
+ 0620
+ 063B-063F
+ 0656-065F
+ 06EE-06EF
+ 06FF
+ 070E
+ 072D-072F
+ 074B-077F
+ 07B2-0900
+ 0904
+ 093A-093B
+ 094E-094F
+ 0955-0957
+ 0971-0980
+ 0984
+ 098D-098E
+ 0991-0992
+ 09A9
+ 09B1
+ 09B3-09B5
+ 09BA-09BB
+ 09BD
+ 09C5-09C6
+ 09C9-09CA
+ 09CE-09D6
+ 09D8-09DB
+ 09DE
+ 09E4-09E5
+ 09FB-0A01
+ 0A03-0A04
+ 0A0B-0A0E
+ 0A11-0A12
+ 0A29
+ 0A31
+ 0A34
+ 0A37
+ 0A3A-0A3B
+ 0A3D
+ 0A43-0A46
+ 0A49-0A4A
+ 0A4E-0A58
+ 0A5D
+ 0A5F-0A65
+ 0A75-0A80
+ 0A84
+ 0A8C
+ 0A8E
+ 0A92
+ 0AA9
+ 0AB1
+ 0AB4
+ 0ABA-0ABB
+ 0AC6
+ 0ACA
+ 0ACE-0ACF
+ 0AD1-0ADF
+ 0AE1-0AE5
+ 0AF0-0B00
+ 0B04
+ 0B0D-0B0E
+ 0B11-0B12
+ 0B29
+ 0B31
+ 0B34-0B35
+ 0B3A-0B3B
+ 0B44-0B46
+ 0B49-0B4A
+ 0B4E-0B55
+ 0B58-0B5B
+ 0B5E
+ 0B62-0B65
+ 0B71-0B81
+ 0B84
+ 0B8B-0B8D
+ 0B91
+ 0B96-0B98
+ 0B9B
+ 0B9D
+ 0BA0-0BA2
+ 0BA5-0BA7
+ 0BAB-0BAD
+ 0BB6
+ 0BBA-0BBD
+ 0BC3-0BC5
+ 0BC9
+ 0BCE-0BD6
+ 0BD8-0BE6
+ 0BF3-0C00
+ 0C04
+ 0C0D
+ 0C11
+ 0C29
+ 0C34
+ 0C3A-0C3D
+ 0C45
+ 0C49
+ 0C4E-0C54
+ 0C57-0C5F
+ 0C62-0C65
+ 0C70-0C81
+ 0C84
+ 0C8D
+ 0C91
+ 0CA9
+ 0CB4
+ 0CBA-0CBD
+ 0CC5
+ 0CC9
+ 0CCE-0CD4
+ 0CD7-0CDD
+ 0CDF
+ 0CE2-0CE5
+ 0CF0-0D01
+ 0D04
+ 0D0D
+ 0D11
+ 0D29
+ 0D3A-0D3D
+ 0D44-0D45
+ 0D49
+ 0D4E-0D56
+ 0D58-0D5F
+ 0D62-0D65
+ 0D70-0D81
+ 0D84
+ 0D97-0D99
+ 0DB2
+ 0DBC
+ 0DBE-0DBF
+ 0DC7-0DC9
+ 0DCB-0DCE
+ 0DD5
+ 0DD7
+ 0DE0-0DF1
+ 0DF5-0E00
+ 0E3B-0E3E
+ 0E5C-0E80
+ 0E83
+ 0E85-0E86
+ 0E89
+ 0E8B-0E8C
+ 0E8E-0E93
+ 0E98
+ 0EA0
+ 0EA4
+ 0EA6
+ 0EA8-0EA9
+ 0EAC
+ 0EBA
+ 0EBE-0EBF
+ 0EC5
+ 0EC7
+ 0ECE-0ECF
+ 0EDA-0EDB
+ 0EDE-0EFF
+ 0F48
+ 0F6B-0F70
+ 0F8C-0F8F
+ 0F98
+ 0FBD
+ 0FCD-0FCE
+ 0FD0-0FFF
+ 1022
+ 1028
+ 102B
+ 1033-1035
+ 103A-103F
+ 105A-109F
+ 10C6-10CF
+ 10F9-10FA
+ 10FC-10FF
+ 115A-115E
+ 11A3-11A7
+ 11FA-11FF
+ 1207
+ 1247
+ 1249
+ 124E-124F
+ 1257
+ 1259
+ 125E-125F
+ 1287
+ 1289
+ 128E-128F
+ 12AF
+ 12B1
+ 12B6-12B7
+ 12BF
+ 12C1
+ 12C6-12C7
+ 12CF
+ 12D7
+ 12EF
+ 130F
+ 1311
+ 1316-1317
+ 131F
+ 1347
+ 135B-1360
+ 137D-139F
+ 13F5-1400
+ 1677-167F
+ 169D-169F
+ 16F1-16FF
+ 170D
+ 1715-171F
+ 1737-173F
+ 1754-175F
+ 176D
+ 1771
+ 1774-177F
+ 17DD-17DF
+ 17EA-17FF
+ 180F
+ 181A-181F
+ 1878-187F
+ 18AA-1DFF
+ 1E9C-1E9F
+ 1EFA-1EFF
+ 1F16-1F17
+ 1F1E-1F1F
+ 1F46-1F47
+ 1F4E-1F4F
+ 1F58
+ 1F5A
+ 1F5C
+ 1F5E
+ 1F7E-1F7F
+ 1FB5
+ 1FC5
+ 1FD4-1FD5
+ 1FDC
+ 1FF0-1FF1
+ 1FF5
+ 1FFF
+ 2053-2056
+ 2058-205E
+ 2064-2069
+ 2072-2073
+ 208F-209F
+ 20B2-20CF
+ 20EB-20FF
+ 213B-213C
+ 214C-2152
+ 2184-218F
+ 23CF-23FF
+ 2427-243F
+ 244B-245F
+ 24FF
+ 2614-2615
+ 2618
+ 267E-267F
+ 268A-2700
+ 2705
+ 270A-270B
+ 2728
+ 274C
+ 274E
+ 2753-2755
+ 2757
+ 275F-2760
+ 2795-2797
+ 27B0
+ 27BF-27CF
+ 27EC-27EF
+ 2B00-2E7F
+ 2E9A
+ 2EF4-2EFF
+ 2FD6-2FEF
+ 2FFC-2FFF
+ 3040
+ 3097-3098
+ 3100-3104
+ 312D-3130
+ 318F
+ 31B8-31EF
+ 321D-321F
+ 3244-3250
+ 327C-327E
+ 32CC-32CF
+ 32FF
+ 3377-337A
+ 33DE-33DF
+ 33FF
+ 4DB6-4DFF
+ 9FA6-9FFF
+ A48D-A48F
+ A4C7-ABFF
+ D7A4-D7FF
+ FA2E-FA2F
+ FA6B-FAFF
+ FB07-FB12
+ FB18-FB1C
+ FB37
+ FB3D
+ FB3F
+ FB42
+ FB45
+ FBB2-FBD2
+ FD40-FD4F
+ FD90-FD91
+ FDC8-FDCF
+ FDFD-FDFF
+ FE10-FE1F
+ FE24-FE2F
+ FE47-FE48
+ FE53
+ FE67
+ FE6C-FE6F
+ FE75
+ FEFD-FEFE
+ FF00
+ FFBF-FFC1
+ FFC8-FFC9
+ FFD0-FFD1
+ FFD8-FFD9
+ FFDD-FFDF
+ FFE7
+ FFEF-FFF8
+ 10000-102FF
+ 1031F
+ 10324-1032F
+ 1034B-103FF
+ 10426-10427
+ 1044E-1CFFF
+ 1D0F6-1D0FF
+ 1D127-1D129
+ 1D1DE-1D3FF
+ 1D455
+ 1D49D
+ 1D4A0-1D4A1
+ 1D4A3-1D4A4
+ 1D4A7-1D4A8
+ 1D4AD
+ 1D4BA
+ 1D4BC
+ 1D4C1
+ 1D4C4
+ 1D506
+ 1D50B-1D50C
+ 1D515
+ 1D51D
+ 1D53A
+ 1D53F
+ 1D545
+ 1D547-1D549
+ 1D551
+ 1D6A4-1D6A7
+ 1D7CA-1D7CD
+ 1D800-1FFFD
+ 2A6D7-2F7FF
+ 2FA1E-2FFFD
+ 30000-3FFFD
+ 40000-4FFFD
+ 50000-5FFFD
+ 60000-6FFFD
+ 70000-7FFFD
+ 80000-8FFFD
+ 90000-9FFFD
+ A0000-AFFFD
+ B0000-BFFFD
+ C0000-CFFFD
+ D0000-DFFFD
+ E0000
+ E0002-E001F
+ E0080-EFFFD
+ ----- End Table A.1 -----
+
+ ----- Start Table B.1 -----
+ 00AD; ; Map to nothing
+ 034F; ; Map to nothing
+ 1806; ; Map to nothing
+ 180B; ; Map to nothing
+ 180C; ; Map to nothing
+ 180D; ; Map to nothing
+ 200B; ; Map to nothing
+ 200C; ; Map to nothing
+ 200D; ; Map to nothing
+ 2060; ; Map to nothing
+ FE00; ; Map to nothing
+ FE01; ; Map to nothing
+ FE02; ; Map to nothing
+ FE03; ; Map to nothing
+ FE04; ; Map to nothing
+ FE05; ; Map to nothing
+ FE06; ; Map to nothing
+ FE07; ; Map to nothing
+ FE08; ; Map to nothing
+ FE09; ; Map to nothing
+ FE0A; ; Map to nothing
+ FE0B; ; Map to nothing
+ FE0C; ; Map to nothing
+ FE0D; ; Map to nothing
+ FE0E; ; Map to nothing
+ FE0F; ; Map to nothing
+ FEFF; ; Map to nothing
+ ----- End Table B.1 -----
+
+ ----- Start Table B.2 -----
+ 0041; 0061; Case map
+ 0042; 0062; Case map
+ 0043; 0063; Case map
+ 0044; 0064; Case map
+ 0045; 0065; Case map
+ 0046; 0066; Case map
+ 0047; 0067; Case map
+ 0048; 0068; Case map
+ 0049; 0069; Case map
+ 004A; 006A; Case map
+ 004B; 006B; Case map
+ 004C; 006C; Case map
+ 004D; 006D; Case map
+ 004E; 006E; Case map
+ 004F; 006F; Case map
+ 0050; 0070; Case map
+ 0051; 0071; Case map
+ 0052; 0072; Case map
+ 0053; 0073; Case map
+ 0054; 0074; Case map
+ 0055; 0075; Case map
+ 0056; 0076; Case map
+ 0057; 0077; Case map
+ 0058; 0078; Case map
+ 0059; 0079; Case map
+ 005A; 007A; Case map
+ 00B5; 03BC; Case map
+ 00C0; 00E0; Case map
+ 00C1; 00E1; Case map
+ 00C2; 00E2; Case map
+ 00C3; 00E3; Case map
+ 00C4; 00E4; Case map
+ 00C5; 00E5; Case map
+ 00C6; 00E6; Case map
+ 00C7; 00E7; Case map
+ 00C8; 00E8; Case map
+ 00C9; 00E9; Case map
+ 00CA; 00EA; Case map
+ 00CB; 00EB; Case map
+ 00CC; 00EC; Case map
+ 00CD; 00ED; Case map
+ 00CE; 00EE; Case map
+ 00CF; 00EF; Case map
+ 00D0; 00F0; Case map
+ 00D1; 00F1; Case map
+ 00D2; 00F2; Case map
+ 00D3; 00F3; Case map
+ 00D4; 00F4; Case map
+ 00D5; 00F5; Case map
+ 00D6; 00F6; Case map
+ 00D8; 00F8; Case map
+ 00D9; 00F9; Case map
+ 00DA; 00FA; Case map
+ 00DB; 00FB; Case map
+ 00DC; 00FC; Case map
+ 00DD; 00FD; Case map
+ 00DE; 00FE; Case map
+ 00DF; 0073 0073; Case map
+ 0100; 0101; Case map
+ 0102; 0103; Case map
+ 0104; 0105; Case map
+ 0106; 0107; Case map
+ 0108; 0109; Case map
+ 010A; 010B; Case map
+ 010C; 010D; Case map
+ 010E; 010F; Case map
+ 0110; 0111; Case map
+ 0112; 0113; Case map
+ 0114; 0115; Case map
+ 0116; 0117; Case map
+ 0118; 0119; Case map
+ 011A; 011B; Case map
+ 011C; 011D; Case map
+ 011E; 011F; Case map
+ 0120; 0121; Case map
+ 0122; 0123; Case map
+ 0124; 0125; Case map
+ 0126; 0127; Case map
+ 0128; 0129; Case map
+ 012A; 012B; Case map
+ 012C; 012D; Case map
+ 012E; 012F; Case map
+ 0130; 0069 0307; Case map
+ 0132; 0133; Case map
+ 0134; 0135; Case map
+ 0136; 0137; Case map
+ 0139; 013A; Case map
+ 013B; 013C; Case map
+ 013D; 013E; Case map
+ 013F; 0140; Case map
+ 0141; 0142; Case map
+ 0143; 0144; Case map
+ 0145; 0146; Case map
+ 0147; 0148; Case map
+ 0149; 02BC 006E; Case map
+ 014A; 014B; Case map
+ 014C; 014D; Case map
+ 014E; 014F; Case map
+ 0150; 0151; Case map
+ 0152; 0153; Case map
+ 0154; 0155; Case map
+ 0156; 0157; Case map
+ 0158; 0159; Case map
+ 015A; 015B; Case map
+ 015C; 015D; Case map
+ 015E; 015F; Case map
+ 0160; 0161; Case map
+ 0162; 0163; Case map
+ 0164; 0165; Case map
+ 0166; 0167; Case map
+ 0168; 0169; Case map
+ 016A; 016B; Case map
+ 016C; 016D; Case map
+ 016E; 016F; Case map
+ 0170; 0171; Case map
+ 0172; 0173; Case map
+ 0174; 0175; Case map
+ 0176; 0177; Case map
+ 0178; 00FF; Case map
+ 0179; 017A; Case map
+ 017B; 017C; Case map
+ 017D; 017E; Case map
+ 017F; 0073; Case map
+ 0181; 0253; Case map
+ 0182; 0183; Case map
+ 0184; 0185; Case map
+ 0186; 0254; Case map
+ 0187; 0188; Case map
+ 0189; 0256; Case map
+ 018A; 0257; Case map
+ 018B; 018C; Case map
+ 018E; 01DD; Case map
+ 018F; 0259; Case map
+ 0190; 025B; Case map
+ 0191; 0192; Case map
+ 0193; 0260; Case map
+ 0194; 0263; Case map
+ 0196; 0269; Case map
+ 0197; 0268; Case map
+ 0198; 0199; Case map
+ 019C; 026F; Case map
+ 019D; 0272; Case map
+ 019F; 0275; Case map
+ 01A0; 01A1; Case map
+ 01A2; 01A3; Case map
+ 01A4; 01A5; Case map
+ 01A6; 0280; Case map
+ 01A7; 01A8; Case map
+ 01A9; 0283; Case map
+ 01AC; 01AD; Case map
+ 01AE; 0288; Case map
+ 01AF; 01B0; Case map
+ 01B1; 028A; Case map
+ 01B2; 028B; Case map
+ 01B3; 01B4; Case map
+ 01B5; 01B6; Case map
+ 01B7; 0292; Case map
+ 01B8; 01B9; Case map
+ 01BC; 01BD; Case map
+ 01C4; 01C6; Case map
+ 01C5; 01C6; Case map
+ 01C7; 01C9; Case map
+ 01C8; 01C9; Case map
+ 01CA; 01CC; Case map
+ 01CB; 01CC; Case map
+ 01CD; 01CE; Case map
+ 01CF; 01D0; Case map
+ 01D1; 01D2; Case map
+ 01D3; 01D4; Case map
+ 01D5; 01D6; Case map
+ 01D7; 01D8; Case map
+ 01D9; 01DA; Case map
+ 01DB; 01DC; Case map
+ 01DE; 01DF; Case map
+ 01E0; 01E1; Case map
+ 01E2; 01E3; Case map
+ 01E4; 01E5; Case map
+ 01E6; 01E7; Case map
+ 01E8; 01E9; Case map
+ 01EA; 01EB; Case map
+ 01EC; 01ED; Case map
+ 01EE; 01EF; Case map
+ 01F0; 006A 030C; Case map
+ 01F1; 01F3; Case map
+ 01F2; 01F3; Case map
+ 01F4; 01F5; Case map
+ 01F6; 0195; Case map
+ 01F7; 01BF; Case map
+ 01F8; 01F9; Case map
+ 01FA; 01FB; Case map
+ 01FC; 01FD; Case map
+ 01FE; 01FF; Case map
+ 0200; 0201; Case map
+ 0202; 0203; Case map
+ 0204; 0205; Case map
+ 0206; 0207; Case map
+ 0208; 0209; Case map
+ 020A; 020B; Case map
+ 020C; 020D; Case map
+ 020E; 020F; Case map
+ 0210; 0211; Case map
+ 0212; 0213; Case map
+ 0214; 0215; Case map
+ 0216; 0217; Case map
+ 0218; 0219; Case map
+ 021A; 021B; Case map
+ 021C; 021D; Case map
+ 021E; 021F; Case map
+ 0220; 019E; Case map
+ 0222; 0223; Case map
+ 0224; 0225; Case map
+ 0226; 0227; Case map
+ 0228; 0229; Case map
+ 022A; 022B; Case map
+ 022C; 022D; Case map
+ 022E; 022F; Case map
+ 0230; 0231; Case map
+ 0232; 0233; Case map
+ 0345; 03B9; Case map
+ 037A; 0020 03B9; Additional folding
+ 0386; 03AC; Case map
+ 0388; 03AD; Case map
+ 0389; 03AE; Case map
+ 038A; 03AF; Case map
+ 038C; 03CC; Case map
+ 038E; 03CD; Case map
+ 038F; 03CE; Case map
+ 0390; 03B9 0308 0301; Case map
+ 0391; 03B1; Case map
+ 0392; 03B2; Case map
+ 0393; 03B3; Case map
+ 0394; 03B4; Case map
+ 0395; 03B5; Case map
+ 0396; 03B6; Case map
+ 0397; 03B7; Case map
+ 0398; 03B8; Case map
+ 0399; 03B9; Case map
+ 039A; 03BA; Case map
+ 039B; 03BB; Case map
+ 039C; 03BC; Case map
+ 039D; 03BD; Case map
+ 039E; 03BE; Case map
+ 039F; 03BF; Case map
+ 03A0; 03C0; Case map
+ 03A1; 03C1; Case map
+ 03A3; 03C3; Case map
+ 03A4; 03C4; Case map
+ 03A5; 03C5; Case map
+ 03A6; 03C6; Case map
+ 03A7; 03C7; Case map
+ 03A8; 03C8; Case map
+ 03A9; 03C9; Case map
+ 03AA; 03CA; Case map
+ 03AB; 03CB; Case map
+ 03B0; 03C5 0308 0301; Case map
+ 03C2; 03C3; Case map
+ 03D0; 03B2; Case map
+ 03D1; 03B8; Case map
+ 03D2; 03C5; Additional folding
+ 03D3; 03CD; Additional folding
+ 03D4; 03CB; Additional folding
+ 03D5; 03C6; Case map
+ 03D6; 03C0; Case map
+ 03D8; 03D9; Case map
+ 03DA; 03DB; Case map
+ 03DC; 03DD; Case map
+ 03DE; 03DF; Case map
+ 03E0; 03E1; Case map
+ 03E2; 03E3; Case map
+ 03E4; 03E5; Case map
+ 03E6; 03E7; Case map
+ 03E8; 03E9; Case map
+ 03EA; 03EB; Case map
+ 03EC; 03ED; Case map
+ 03EE; 03EF; Case map
+ 03F0; 03BA; Case map
+ 03F1; 03C1; Case map
+ 03F2; 03C3; Case map
+ 03F4; 03B8; Case map
+ 03F5; 03B5; Case map
+ 0400; 0450; Case map
+ 0401; 0451; Case map
+ 0402; 0452; Case map
+ 0403; 0453; Case map
+ 0404; 0454; Case map
+ 0405; 0455; Case map
+ 0406; 0456; Case map
+ 0407; 0457; Case map
+ 0408; 0458; Case map
+ 0409; 0459; Case map
+ 040A; 045A; Case map
+ 040B; 045B; Case map
+ 040C; 045C; Case map
+ 040D; 045D; Case map
+ 040E; 045E; Case map
+ 040F; 045F; Case map
+ 0410; 0430; Case map
+ 0411; 0431; Case map
+ 0412; 0432; Case map
+ 0413; 0433; Case map
+ 0414; 0434; Case map
+ 0415; 0435; Case map
+ 0416; 0436; Case map
+ 0417; 0437; Case map
+ 0418; 0438; Case map
+ 0419; 0439; Case map
+ 041A; 043A; Case map
+ 041B; 043B; Case map
+ 041C; 043C; Case map
+ 041D; 043D; Case map
+ 041E; 043E; Case map
+ 041F; 043F; Case map
+ 0420; 0440; Case map
+ 0421; 0441; Case map
+ 0422; 0442; Case map
+ 0423; 0443; Case map
+ 0424; 0444; Case map
+ 0425; 0445; Case map
+ 0426; 0446; Case map
+ 0427; 0447; Case map
+ 0428; 0448; Case map
+ 0429; 0449; Case map
+ 042A; 044A; Case map
+ 042B; 044B; Case map
+ 042C; 044C; Case map
+ 042D; 044D; Case map
+ 042E; 044E; Case map
+ 042F; 044F; Case map
+ 0460; 0461; Case map
+ 0462; 0463; Case map
+ 0464; 0465; Case map
+ 0466; 0467; Case map
+ 0468; 0469; Case map
+ 046A; 046B; Case map
+ 046C; 046D; Case map
+ 046E; 046F; Case map
+ 0470; 0471; Case map
+ 0472; 0473; Case map
+ 0474; 0475; Case map
+ 0476; 0477; Case map
+ 0478; 0479; Case map
+ 047A; 047B; Case map
+ 047C; 047D; Case map
+ 047E; 047F; Case map
+ 0480; 0481; Case map
+ 048A; 048B; Case map
+ 048C; 048D; Case map
+ 048E; 048F; Case map
+ 0490; 0491; Case map
+ 0492; 0493; Case map
+ 0494; 0495; Case map
+ 0496; 0497; Case map
+ 0498; 0499; Case map
+ 049A; 049B; Case map
+ 049C; 049D; Case map
+ 049E; 049F; Case map
+ 04A0; 04A1; Case map
+ 04A2; 04A3; Case map
+ 04A4; 04A5; Case map
+ 04A6; 04A7; Case map
+ 04A8; 04A9; Case map
+ 04AA; 04AB; Case map
+ 04AC; 04AD; Case map
+ 04AE; 04AF; Case map
+ 04B0; 04B1; Case map
+ 04B2; 04B3; Case map
+ 04B4; 04B5; Case map
+ 04B6; 04B7; Case map
+ 04B8; 04B9; Case map
+ 04BA; 04BB; Case map
+ 04BC; 04BD; Case map
+ 04BE; 04BF; Case map
+ 04C1; 04C2; Case map
+ 04C3; 04C4; Case map
+ 04C5; 04C6; Case map
+ 04C7; 04C8; Case map
+ 04C9; 04CA; Case map
+ 04CB; 04CC; Case map
+ 04CD; 04CE; Case map
+ 04D0; 04D1; Case map
+ 04D2; 04D3; Case map
+ 04D4; 04D5; Case map
+ 04D6; 04D7; Case map
+ 04D8; 04D9; Case map
+ 04DA; 04DB; Case map
+ 04DC; 04DD; Case map
+ 04DE; 04DF; Case map
+ 04E0; 04E1; Case map
+ 04E2; 04E3; Case map
+ 04E4; 04E5; Case map
+ 04E6; 04E7; Case map
+ 04E8; 04E9; Case map
+ 04EA; 04EB; Case map
+ 04EC; 04ED; Case map
+ 04EE; 04EF; Case map
+ 04F0; 04F1; Case map
+ 04F2; 04F3; Case map
+ 04F4; 04F5; Case map
+ 04F8; 04F9; Case map
+ 0500; 0501; Case map
+ 0502; 0503; Case map
+ 0504; 0505; Case map
+ 0506; 0507; Case map
+ 0508; 0509; Case map
+ 050A; 050B; Case map
+ 050C; 050D; Case map
+ 050E; 050F; Case map
+ 0531; 0561; Case map
+ 0532; 0562; Case map
+ 0533; 0563; Case map
+ 0534; 0564; Case map
+ 0535; 0565; Case map
+ 0536; 0566; Case map
+ 0537; 0567; Case map
+ 0538; 0568; Case map
+ 0539; 0569; Case map
+ 053A; 056A; Case map
+ 053B; 056B; Case map
+ 053C; 056C; Case map
+ 053D; 056D; Case map
+ 053E; 056E; Case map
+ 053F; 056F; Case map
+ 0540; 0570; Case map
+ 0541; 0571; Case map
+ 0542; 0572; Case map
+ 0543; 0573; Case map
+ 0544; 0574; Case map
+ 0545; 0575; Case map
+ 0546; 0576; Case map
+ 0547; 0577; Case map
+ 0548; 0578; Case map
+ 0549; 0579; Case map
+ 054A; 057A; Case map
+ 054B; 057B; Case map
+ 054C; 057C; Case map
+ 054D; 057D; Case map
+ 054E; 057E; Case map
+ 054F; 057F; Case map
+ 0550; 0580; Case map
+ 0551; 0581; Case map
+ 0552; 0582; Case map
+ 0553; 0583; Case map
+ 0554; 0584; Case map
+ 0555; 0585; Case map
+ 0556; 0586; Case map
+ 0587; 0565 0582; Case map
+ 1E00; 1E01; Case map
+ 1E02; 1E03; Case map
+ 1E04; 1E05; Case map
+ 1E06; 1E07; Case map
+ 1E08; 1E09; Case map
+ 1E0A; 1E0B; Case map
+ 1E0C; 1E0D; Case map
+ 1E0E; 1E0F; Case map
+ 1E10; 1E11; Case map
+ 1E12; 1E13; Case map
+ 1E14; 1E15; Case map
+ 1E16; 1E17; Case map
+ 1E18; 1E19; Case map
+ 1E1A; 1E1B; Case map
+ 1E1C; 1E1D; Case map
+ 1E1E; 1E1F; Case map
+ 1E20; 1E21; Case map
+ 1E22; 1E23; Case map
+ 1E24; 1E25; Case map
+ 1E26; 1E27; Case map
+ 1E28; 1E29; Case map
+ 1E2A; 1E2B; Case map
+ 1E2C; 1E2D; Case map
+ 1E2E; 1E2F; Case map
+ 1E30; 1E31; Case map
+ 1E32; 1E33; Case map
+ 1E34; 1E35; Case map
+ 1E36; 1E37; Case map
+ 1E38; 1E39; Case map
+ 1E3A; 1E3B; Case map
+ 1E3C; 1E3D; Case map
+ 1E3E; 1E3F; Case map
+ 1E40; 1E41; Case map
+ 1E42; 1E43; Case map
+ 1E44; 1E45; Case map
+ 1E46; 1E47; Case map
+ 1E48; 1E49; Case map
+ 1E4A; 1E4B; Case map
+ 1E4C; 1E4D; Case map
+ 1E4E; 1E4F; Case map
+ 1E50; 1E51; Case map
+ 1E52; 1E53; Case map
+ 1E54; 1E55; Case map
+ 1E56; 1E57; Case map
+ 1E58; 1E59; Case map
+ 1E5A; 1E5B; Case map
+ 1E5C; 1E5D; Case map
+ 1E5E; 1E5F; Case map
+ 1E60; 1E61; Case map
+ 1E62; 1E63; Case map
+ 1E64; 1E65; Case map
+ 1E66; 1E67; Case map
+ 1E68; 1E69; Case map
+ 1E6A; 1E6B; Case map
+ 1E6C; 1E6D; Case map
+ 1E6E; 1E6F; Case map
+ 1E70; 1E71; Case map
+ 1E72; 1E73; Case map
+ 1E74; 1E75; Case map
+ 1E76; 1E77; Case map
+ 1E78; 1E79; Case map
+ 1E7A; 1E7B; Case map
+ 1E7C; 1E7D; Case map
+ 1E7E; 1E7F; Case map
+ 1E80; 1E81; Case map
+ 1E82; 1E83; Case map
+ 1E84; 1E85; Case map
+ 1E86; 1E87; Case map
+ 1E88; 1E89; Case map
+ 1E8A; 1E8B; Case map
+ 1E8C; 1E8D; Case map
+ 1E8E; 1E8F; Case map
+ 1E90; 1E91; Case map
+ 1E92; 1E93; Case map
+ 1E94; 1E95; Case map
+ 1E96; 0068 0331; Case map
+ 1E97; 0074 0308; Case map
+ 1E98; 0077 030A; Case map
+ 1E99; 0079 030A; Case map
+ 1E9A; 0061 02BE; Case map
+ 1E9B; 1E61; Case map
+ 1EA0; 1EA1; Case map
+ 1EA2; 1EA3; Case map
+ 1EA4; 1EA5; Case map
+ 1EA6; 1EA7; Case map
+ 1EA8; 1EA9; Case map
+ 1EAA; 1EAB; Case map
+ 1EAC; 1EAD; Case map
+ 1EAE; 1EAF; Case map
+ 1EB0; 1EB1; Case map
+ 1EB2; 1EB3; Case map
+ 1EB4; 1EB5; Case map
+ 1EB6; 1EB7; Case map
+ 1EB8; 1EB9; Case map
+ 1EBA; 1EBB; Case map
+ 1EBC; 1EBD; Case map
+ 1EBE; 1EBF; Case map
+ 1EC0; 1EC1; Case map
+ 1EC2; 1EC3; Case map
+ 1EC4; 1EC5; Case map
+ 1EC6; 1EC7; Case map
+ 1EC8; 1EC9; Case map
+ 1ECA; 1ECB; Case map
+ 1ECC; 1ECD; Case map
+ 1ECE; 1ECF; Case map
+ 1ED0; 1ED1; Case map
+ 1ED2; 1ED3; Case map
+ 1ED4; 1ED5; Case map
+ 1ED6; 1ED7; Case map
+ 1ED8; 1ED9; Case map
+ 1EDA; 1EDB; Case map
+ 1EDC; 1EDD; Case map
+ 1EDE; 1EDF; Case map
+ 1EE0; 1EE1; Case map
+ 1EE2; 1EE3; Case map
+ 1EE4; 1EE5; Case map
+ 1EE6; 1EE7; Case map
+ 1EE8; 1EE9; Case map
+ 1EEA; 1EEB; Case map
+ 1EEC; 1EED; Case map
+ 1EEE; 1EEF; Case map
+ 1EF0; 1EF1; Case map
+ 1EF2; 1EF3; Case map
+ 1EF4; 1EF5; Case map
+ 1EF6; 1EF7; Case map
+ 1EF8; 1EF9; Case map
+ 1F08; 1F00; Case map
+ 1F09; 1F01; Case map
+ 1F0A; 1F02; Case map
+ 1F0B; 1F03; Case map
+ 1F0C; 1F04; Case map
+ 1F0D; 1F05; Case map
+ 1F0E; 1F06; Case map
+ 1F0F; 1F07; Case map
+ 1F18; 1F10; Case map
+ 1F19; 1F11; Case map
+ 1F1A; 1F12; Case map
+ 1F1B; 1F13; Case map
+ 1F1C; 1F14; Case map
+ 1F1D; 1F15; Case map
+ 1F28; 1F20; Case map
+ 1F29; 1F21; Case map
+ 1F2A; 1F22; Case map
+ 1F2B; 1F23; Case map
+ 1F2C; 1F24; Case map
+ 1F2D; 1F25; Case map
+ 1F2E; 1F26; Case map
+ 1F2F; 1F27; Case map
+ 1F38; 1F30; Case map
+ 1F39; 1F31; Case map
+ 1F3A; 1F32; Case map
+ 1F3B; 1F33; Case map
+ 1F3C; 1F34; Case map
+ 1F3D; 1F35; Case map
+ 1F3E; 1F36; Case map
+ 1F3F; 1F37; Case map
+ 1F48; 1F40; Case map
+ 1F49; 1F41; Case map
+ 1F4A; 1F42; Case map
+ 1F4B; 1F43; Case map
+ 1F4C; 1F44; Case map
+ 1F4D; 1F45; Case map
+ 1F50; 03C5 0313; Case map
+ 1F52; 03C5 0313 0300; Case map
+ 1F54; 03C5 0313 0301; Case map
+ 1F56; 03C5 0313 0342; Case map
+ 1F59; 1F51; Case map
+ 1F5B; 1F53; Case map
+ 1F5D; 1F55; Case map
+ 1F5F; 1F57; Case map
+ 1F68; 1F60; Case map
+ 1F69; 1F61; Case map
+ 1F6A; 1F62; Case map
+ 1F6B; 1F63; Case map
+ 1F6C; 1F64; Case map
+ 1F6D; 1F65; Case map
+ 1F6E; 1F66; Case map
+ 1F6F; 1F67; Case map
+ 1F80; 1F00 03B9; Case map
+ 1F81; 1F01 03B9; Case map
+ 1F82; 1F02 03B9; Case map
+ 1F83; 1F03 03B9; Case map
+ 1F84; 1F04 03B9; Case map
+ 1F85; 1F05 03B9; Case map
+ 1F86; 1F06 03B9; Case map
+ 1F87; 1F07 03B9; Case map
+ 1F88; 1F00 03B9; Case map
+ 1F89; 1F01 03B9; Case map
+ 1F8A; 1F02 03B9; Case map
+ 1F8B; 1F03 03B9; Case map
+ 1F8C; 1F04 03B9; Case map
+ 1F8D; 1F05 03B9; Case map
+ 1F8E; 1F06 03B9; Case map
+ 1F8F; 1F07 03B9; Case map
+ 1F90; 1F20 03B9; Case map
+ 1F91; 1F21 03B9; Case map
+ 1F92; 1F22 03B9; Case map
+ 1F93; 1F23 03B9; Case map
+ 1F94; 1F24 03B9; Case map
+ 1F95; 1F25 03B9; Case map
+ 1F96; 1F26 03B9; Case map
+ 1F97; 1F27 03B9; Case map
+ 1F98; 1F20 03B9; Case map
+ 1F99; 1F21 03B9; Case map
+ 1F9A; 1F22 03B9; Case map
+ 1F9B; 1F23 03B9; Case map
+ 1F9C; 1F24 03B9; Case map
+ 1F9D; 1F25 03B9; Case map
+ 1F9E; 1F26 03B9; Case map
+ 1F9F; 1F27 03B9; Case map
+ 1FA0; 1F60 03B9; Case map
+ 1FA1; 1F61 03B9; Case map
+ 1FA2; 1F62 03B9; Case map
+ 1FA3; 1F63 03B9; Case map
+ 1FA4; 1F64 03B9; Case map
+ 1FA5; 1F65 03B9; Case map
+ 1FA6; 1F66 03B9; Case map
+ 1FA7; 1F67 03B9; Case map
+ 1FA8; 1F60 03B9; Case map
+ 1FA9; 1F61 03B9; Case map
+ 1FAA; 1F62 03B9; Case map
+ 1FAB; 1F63 03B9; Case map
+ 1FAC; 1F64 03B9; Case map
+ 1FAD; 1F65 03B9; Case map
+ 1FAE; 1F66 03B9; Case map
+ 1FAF; 1F67 03B9; Case map
+ 1FB2; 1F70 03B9; Case map
+ 1FB3; 03B1 03B9; Case map
+ 1FB4; 03AC 03B9; Case map
+ 1FB6; 03B1 0342; Case map
+ 1FB7; 03B1 0342 03B9; Case map
+ 1FB8; 1FB0; Case map
+ 1FB9; 1FB1; Case map
+ 1FBA; 1F70; Case map
+ 1FBB; 1F71; Case map
+ 1FBC; 03B1 03B9; Case map
+ 1FBE; 03B9; Case map
+ 1FC2; 1F74 03B9; Case map
+ 1FC3; 03B7 03B9; Case map
+ 1FC4; 03AE 03B9; Case map
+ 1FC6; 03B7 0342; Case map
+ 1FC7; 03B7 0342 03B9; Case map
+ 1FC8; 1F72; Case map
+ 1FC9; 1F73; Case map
+ 1FCA; 1F74; Case map
+ 1FCB; 1F75; Case map
+ 1FCC; 03B7 03B9; Case map
+ 1FD2; 03B9 0308 0300; Case map
+ 1FD3; 03B9 0308 0301; Case map
+ 1FD6; 03B9 0342; Case map
+ 1FD7; 03B9 0308 0342; Case map
+ 1FD8; 1FD0; Case map
+ 1FD9; 1FD1; Case map
+ 1FDA; 1F76; Case map
+ 1FDB; 1F77; Case map
+ 1FE2; 03C5 0308 0300; Case map
+ 1FE3; 03C5 0308 0301; Case map
+ 1FE4; 03C1 0313; Case map
+ 1FE6; 03C5 0342; Case map
+ 1FE7; 03C5 0308 0342; Case map
+ 1FE8; 1FE0; Case map
+ 1FE9; 1FE1; Case map
+ 1FEA; 1F7A; Case map
+ 1FEB; 1F7B; Case map
+ 1FEC; 1FE5; Case map
+ 1FF2; 1F7C 03B9; Case map
+ 1FF3; 03C9 03B9; Case map
+ 1FF4; 03CE 03B9; Case map
+ 1FF6; 03C9 0342; Case map
+ 1FF7; 03C9 0342 03B9; Case map
+ 1FF8; 1F78; Case map
+ 1FF9; 1F79; Case map
+ 1FFA; 1F7C; Case map
+ 1FFB; 1F7D; Case map
+ 1FFC; 03C9 03B9; Case map
+ 20A8; 0072 0073; Additional folding
+ 2102; 0063; Additional folding
+ 2103; 00B0 0063; Additional folding
+ 2107; 025B; Additional folding
+ 2109; 00B0 0066; Additional folding
+ 210B; 0068; Additional folding
+ 210C; 0068; Additional folding
+ 210D; 0068; Additional folding
+ 2110; 0069; Additional folding
+ 2111; 0069; Additional folding
+ 2112; 006C; Additional folding
+ 2115; 006E; Additional folding
+ 2116; 006E 006F; Additional folding
+ 2119; 0070; Additional folding
+ 211A; 0071; Additional folding
+ 211B; 0072; Additional folding
+ 211C; 0072; Additional folding
+ 211D; 0072; Additional folding
+ 2120; 0073 006D; Additional folding
+ 2121; 0074 0065 006C; Additional folding
+ 2122; 0074 006D; Additional folding
+ 2124; 007A; Additional folding
+ 2126; 03C9; Case map
+ 2128; 007A; Additional folding
+ 212A; 006B; Case map
+ 212B; 00E5; Case map
+ 212C; 0062; Additional folding
+ 212D; 0063; Additional folding
+ 2130; 0065; Additional folding
+ 2131; 0066; Additional folding
+ 2133; 006D; Additional folding
+ 213E; 03B3; Additional folding
+ 213F; 03C0; Additional folding
+ 2145; 0064; Additional folding
+ 2160; 2170; Case map
+ 2161; 2171; Case map
+ 2162; 2172; Case map
+ 2163; 2173; Case map
+ 2164; 2174; Case map
+ 2165; 2175; Case map
+ 2166; 2176; Case map
+ 2167; 2177; Case map
+ 2168; 2178; Case map
+ 2169; 2179; Case map
+ 216A; 217A; Case map
+ 216B; 217B; Case map
+ 216C; 217C; Case map
+ 216D; 217D; Case map
+ 216E; 217E; Case map
+ 216F; 217F; Case map
+ 24B6; 24D0; Case map
+ 24B7; 24D1; Case map
+ 24B8; 24D2; Case map
+ 24B9; 24D3; Case map
+ 24BA; 24D4; Case map
+ 24BB; 24D5; Case map
+ 24BC; 24D6; Case map
+ 24BD; 24D7; Case map
+ 24BE; 24D8; Case map
+ 24BF; 24D9; Case map
+ 24C0; 24DA; Case map
+ 24C1; 24DB; Case map
+ 24C2; 24DC; Case map
+ 24C3; 24DD; Case map
+ 24C4; 24DE; Case map
+ 24C5; 24DF; Case map
+ 24C6; 24E0; Case map
+ 24C7; 24E1; Case map
+ 24C8; 24E2; Case map
+ 24C9; 24E3; Case map
+ 24CA; 24E4; Case map
+ 24CB; 24E5; Case map
+ 24CC; 24E6; Case map
+ 24CD; 24E7; Case map
+ 24CE; 24E8; Case map
+ 24CF; 24E9; Case map
+ 3371; 0068 0070 0061; Additional folding
+ 3373; 0061 0075; Additional folding
+ 3375; 006F 0076; Additional folding
+ 3380; 0070 0061; Additional folding
+ 3381; 006E 0061; Additional folding
+ 3382; 03BC 0061; Additional folding
+ 3383; 006D 0061; Additional folding
+ 3384; 006B 0061; Additional folding
+ 3385; 006B 0062; Additional folding
+ 3386; 006D 0062; Additional folding
+ 3387; 0067 0062; Additional folding
+ 338A; 0070 0066; Additional folding
+ 338B; 006E 0066; Additional folding
+ 338C; 03BC 0066; Additional folding
+ 3390; 0068 007A; Additional folding
+ 3391; 006B 0068 007A; Additional folding
+ 3392; 006D 0068 007A; Additional folding
+ 3393; 0067 0068 007A; Additional folding
+ 3394; 0074 0068 007A; Additional folding
+ 33A9; 0070 0061; Additional folding
+ 33AA; 006B 0070 0061; Additional folding
+ 33AB; 006D 0070 0061; Additional folding
+ 33AC; 0067 0070 0061; Additional folding
+ 33B4; 0070 0076; Additional folding
+ 33B5; 006E 0076; Additional folding
+ 33B6; 03BC 0076; Additional folding
+ 33B7; 006D 0076; Additional folding
+ 33B8; 006B 0076; Additional folding
+ 33B9; 006D 0076; Additional folding
+ 33BA; 0070 0077; Additional folding
+ 33BB; 006E 0077; Additional folding
+ 33BC; 03BC 0077; Additional folding
+ 33BD; 006D 0077; Additional folding
+ 33BE; 006B 0077; Additional folding
+ 33BF; 006D 0077; Additional folding
+ 33C0; 006B 03C9; Additional folding
+ 33C1; 006D 03C9; Additional folding
+ 33C3; 0062 0071; Additional folding
+ 33C6; 0063 2215 006B 0067; Additional folding
+ 33C7; 0063 006F 002E; Additional folding
+ 33C8; 0064 0062; Additional folding
+ 33C9; 0067 0079; Additional folding
+ 33CB; 0068 0070; Additional folding
+ 33CD; 006B 006B; Additional folding
+ 33CE; 006B 006D; Additional folding
+ 33D7; 0070 0068; Additional folding
+ 33D9; 0070 0070 006D; Additional folding
+ 33DA; 0070 0072; Additional folding
+ 33DC; 0073 0076; Additional folding
+ 33DD; 0077 0062; Additional folding
+ FB00; 0066 0066; Case map
+ FB01; 0066 0069; Case map
+ FB02; 0066 006C; Case map
+ FB03; 0066 0066 0069; Case map
+ FB04; 0066 0066 006C; Case map
+ FB05; 0073 0074; Case map
+ FB06; 0073 0074; Case map
+ FB13; 0574 0576; Case map
+ FB14; 0574 0565; Case map
+ FB15; 0574 056B; Case map
+ FB16; 057E 0576; Case map
+ FB17; 0574 056D; Case map
+ FF21; FF41; Case map
+ FF22; FF42; Case map
+ FF23; FF43; Case map
+ FF24; FF44; Case map
+ FF25; FF45; Case map
+ FF26; FF46; Case map
+ FF27; FF47; Case map
+ FF28; FF48; Case map
+ FF29; FF49; Case map
+ FF2A; FF4A; Case map
+ FF2B; FF4B; Case map
+ FF2C; FF4C; Case map
+ FF2D; FF4D; Case map
+ FF2E; FF4E; Case map
+ FF2F; FF4F; Case map
+ FF30; FF50; Case map
+ FF31; FF51; Case map
+ FF32; FF52; Case map
+ FF33; FF53; Case map
+ FF34; FF54; Case map
+ FF35; FF55; Case map
+ FF36; FF56; Case map
+ FF37; FF57; Case map
+ FF38; FF58; Case map
+ FF39; FF59; Case map
+ FF3A; FF5A; Case map
+ 10400; 10428; Case map
+ 10401; 10429; Case map
+ 10402; 1042A; Case map
+ 10403; 1042B; Case map
+ 10404; 1042C; Case map
+ 10405; 1042D; Case map
+ 10406; 1042E; Case map
+ 10407; 1042F; Case map
+ 10408; 10430; Case map
+ 10409; 10431; Case map
+ 1040A; 10432; Case map
+ 1040B; 10433; Case map
+ 1040C; 10434; Case map
+ 1040D; 10435; Case map
+ 1040E; 10436; Case map
+ 1040F; 10437; Case map
+ 10410; 10438; Case map
+ 10411; 10439; Case map
+ 10412; 1043A; Case map
+ 10413; 1043B; Case map
+ 10414; 1043C; Case map
+ 10415; 1043D; Case map
+ 10416; 1043E; Case map
+ 10417; 1043F; Case map
+ 10418; 10440; Case map
+ 10419; 10441; Case map
+ 1041A; 10442; Case map
+ 1041B; 10443; Case map
+ 1041C; 10444; Case map
+ 1041D; 10445; Case map
+ 1041E; 10446; Case map
+ 1041F; 10447; Case map
+ 10420; 10448; Case map
+ 10421; 10449; Case map
+ 10422; 1044A; Case map
+ 10423; 1044B; Case map
+ 10424; 1044C; Case map
+ 10425; 1044D; Case map
+ 1D400; 0061; Additional folding
+ 1D401; 0062; Additional folding
+ 1D402; 0063; Additional folding
+ 1D403; 0064; Additional folding
+ 1D404; 0065; Additional folding
+ 1D405; 0066; Additional folding
+ 1D406; 0067; Additional folding
+ 1D407; 0068; Additional folding
+ 1D408; 0069; Additional folding
+ 1D409; 006A; Additional folding
+ 1D40A; 006B; Additional folding
+ 1D40B; 006C; Additional folding
+ 1D40C; 006D; Additional folding
+ 1D40D; 006E; Additional folding
+ 1D40E; 006F; Additional folding
+ 1D40F; 0070; Additional folding
+ 1D410; 0071; Additional folding
+ 1D411; 0072; Additional folding
+ 1D412; 0073; Additional folding
+ 1D413; 0074; Additional folding
+ 1D414; 0075; Additional folding
+ 1D415; 0076; Additional folding
+ 1D416; 0077; Additional folding
+ 1D417; 0078; Additional folding
+ 1D418; 0079; Additional folding
+ 1D419; 007A; Additional folding
+ 1D434; 0061; Additional folding
+ 1D435; 0062; Additional folding
+ 1D436; 0063; Additional folding
+ 1D437; 0064; Additional folding
+ 1D438; 0065; Additional folding
+ 1D439; 0066; Additional folding
+ 1D43A; 0067; Additional folding
+ 1D43B; 0068; Additional folding
+ 1D43C; 0069; Additional folding
+ 1D43D; 006A; Additional folding
+ 1D43E; 006B; Additional folding
+ 1D43F; 006C; Additional folding
+ 1D440; 006D; Additional folding
+ 1D441; 006E; Additional folding
+ 1D442; 006F; Additional folding
+ 1D443; 0070; Additional folding
+ 1D444; 0071; Additional folding
+ 1D445; 0072; Additional folding
+ 1D446; 0073; Additional folding
+ 1D447; 0074; Additional folding
+ 1D448; 0075; Additional folding
+ 1D449; 0076; Additional folding
+ 1D44A; 0077; Additional folding
+ 1D44B; 0078; Additional folding
+ 1D44C; 0079; Additional folding
+ 1D44D; 007A; Additional folding
+ 1D468; 0061; Additional folding
+ 1D469; 0062; Additional folding
+ 1D46A; 0063; Additional folding
+ 1D46B; 0064; Additional folding
+ 1D46C; 0065; Additional folding
+ 1D46D; 0066; Additional folding
+ 1D46E; 0067; Additional folding
+ 1D46F; 0068; Additional folding
+ 1D470; 0069; Additional folding
+ 1D471; 006A; Additional folding
+ 1D472; 006B; Additional folding
+ 1D473; 006C; Additional folding
+ 1D474; 006D; Additional folding
+ 1D475; 006E; Additional folding
+ 1D476; 006F; Additional folding
+ 1D477; 0070; Additional folding
+ 1D478; 0071; Additional folding
+ 1D479; 0072; Additional folding
+ 1D47A; 0073; Additional folding
+ 1D47B; 0074; Additional folding
+ 1D47C; 0075; Additional folding
+ 1D47D; 0076; Additional folding
+ 1D47E; 0077; Additional folding
+ 1D47F; 0078; Additional folding
+ 1D480; 0079; Additional folding
+ 1D481; 007A; Additional folding
+ 1D49C; 0061; Additional folding
+ 1D49E; 0063; Additional folding
+ 1D49F; 0064; Additional folding
+ 1D4A2; 0067; Additional folding
+ 1D4A5; 006A; Additional folding
+ 1D4A6; 006B; Additional folding
+ 1D4A9; 006E; Additional folding
+ 1D4AA; 006F; Additional folding
+ 1D4AB; 0070; Additional folding
+ 1D4AC; 0071; Additional folding
+ 1D4AE; 0073; Additional folding
+ 1D4AF; 0074; Additional folding
+ 1D4B0; 0075; Additional folding
+ 1D4B1; 0076; Additional folding
+ 1D4B2; 0077; Additional folding
+ 1D4B3; 0078; Additional folding
+ 1D4B4; 0079; Additional folding
+ 1D4B5; 007A; Additional folding
+ 1D4D0; 0061; Additional folding
+ 1D4D1; 0062; Additional folding
+ 1D4D2; 0063; Additional folding
+ 1D4D3; 0064; Additional folding
+ 1D4D4; 0065; Additional folding
+ 1D4D5; 0066; Additional folding
+ 1D4D6; 0067; Additional folding
+ 1D4D7; 0068; Additional folding
+ 1D4D8; 0069; Additional folding
+ 1D4D9; 006A; Additional folding
+ 1D4DA; 006B; Additional folding
+ 1D4DB; 006C; Additional folding
+ 1D4DC; 006D; Additional folding
+ 1D4DD; 006E; Additional folding
+ 1D4DE; 006F; Additional folding
+ 1D4DF; 0070; Additional folding
+ 1D4E0; 0071; Additional folding
+ 1D4E1; 0072; Additional folding
+ 1D4E2; 0073; Additional folding
+ 1D4E3; 0074; Additional folding
+ 1D4E4; 0075; Additional folding
+ 1D4E5; 0076; Additional folding
+ 1D4E6; 0077; Additional folding
+ 1D4E7; 0078; Additional folding
+ 1D4E8; 0079; Additional folding
+ 1D4E9; 007A; Additional folding
+ 1D504; 0061; Additional folding
+ 1D505; 0062; Additional folding
+ 1D507; 0064; Additional folding
+ 1D508; 0065; Additional folding
+ 1D509; 0066; Additional folding
+ 1D50A; 0067; Additional folding
+ 1D50D; 006A; Additional folding
+ 1D50E; 006B; Additional folding
+ 1D50F; 006C; Additional folding
+ 1D510; 006D; Additional folding
+ 1D511; 006E; Additional folding
+ 1D512; 006F; Additional folding
+ 1D513; 0070; Additional folding
+ 1D514; 0071; Additional folding
+ 1D516; 0073; Additional folding
+ 1D517; 0074; Additional folding
+ 1D518; 0075; Additional folding
+ 1D519; 0076; Additional folding
+ 1D51A; 0077; Additional folding
+ 1D51B; 0078; Additional folding
+ 1D51C; 0079; Additional folding
+ 1D538; 0061; Additional folding
+ 1D539; 0062; Additional folding
+ 1D53B; 0064; Additional folding
+ 1D53C; 0065; Additional folding
+ 1D53D; 0066; Additional folding
+ 1D53E; 0067; Additional folding
+ 1D540; 0069; Additional folding
+ 1D541; 006A; Additional folding
+ 1D542; 006B; Additional folding
+ 1D543; 006C; Additional folding
+ 1D544; 006D; Additional folding
+ 1D546; 006F; Additional folding
+ 1D54A; 0073; Additional folding
+ 1D54B; 0074; Additional folding
+ 1D54C; 0075; Additional folding
+ 1D54D; 0076; Additional folding
+ 1D54E; 0077; Additional folding
+ 1D54F; 0078; Additional folding
+ 1D550; 0079; Additional folding
+ 1D56C; 0061; Additional folding
+ 1D56D; 0062; Additional folding
+ 1D56E; 0063; Additional folding
+ 1D56F; 0064; Additional folding
+ 1D570; 0065; Additional folding
+ 1D571; 0066; Additional folding
+ 1D572; 0067; Additional folding
+ 1D573; 0068; Additional folding
+ 1D574; 0069; Additional folding
+ 1D575; 006A; Additional folding
+ 1D576; 006B; Additional folding
+ 1D577; 006C; Additional folding
+ 1D578; 006D; Additional folding
+ 1D579; 006E; Additional folding
+ 1D57A; 006F; Additional folding
+ 1D57B; 0070; Additional folding
+ 1D57C; 0071; Additional folding
+ 1D57D; 0072; Additional folding
+ 1D57E; 0073; Additional folding
+ 1D57F; 0074; Additional folding
+ 1D580; 0075; Additional folding
+ 1D581; 0076; Additional folding
+ 1D582; 0077; Additional folding
+ 1D583; 0078; Additional folding
+ 1D584; 0079; Additional folding
+ 1D585; 007A; Additional folding
+ 1D5A0; 0061; Additional folding
+ 1D5A1; 0062; Additional folding
+ 1D5A2; 0063; Additional folding
+ 1D5A3; 0064; Additional folding
+ 1D5A4; 0065; Additional folding
+ 1D5A5; 0066; Additional folding
+ 1D5A6; 0067; Additional folding
+ 1D5A7; 0068; Additional folding
+ 1D5A8; 0069; Additional folding
+ 1D5A9; 006A; Additional folding
+ 1D5AA; 006B; Additional folding
+ 1D5AB; 006C; Additional folding
+ 1D5AC; 006D; Additional folding
+ 1D5AD; 006E; Additional folding
+ 1D5AE; 006F; Additional folding
+ 1D5AF; 0070; Additional folding
+ 1D5B0; 0071; Additional folding
+ 1D5B1; 0072; Additional folding
+ 1D5B2; 0073; Additional folding
+ 1D5B3; 0074; Additional folding
+ 1D5B4; 0075; Additional folding
+ 1D5B5; 0076; Additional folding
+ 1D5B6; 0077; Additional folding
+ 1D5B7; 0078; Additional folding
+ 1D5B8; 0079; Additional folding
+ 1D5B9; 007A; Additional folding
+ 1D5D4; 0061; Additional folding
+ 1D5D5; 0062; Additional folding
+ 1D5D6; 0063; Additional folding
+ 1D5D7; 0064; Additional folding
+ 1D5D8; 0065; Additional folding
+ 1D5D9; 0066; Additional folding
+ 1D5DA; 0067; Additional folding
+ 1D5DB; 0068; Additional folding
+ 1D5DC; 0069; Additional folding
+ 1D5DD; 006A; Additional folding
+ 1D5DE; 006B; Additional folding
+ 1D5DF; 006C; Additional folding
+ 1D5E0; 006D; Additional folding
+ 1D5E1; 006E; Additional folding
+ 1D5E2; 006F; Additional folding
+ 1D5E3; 0070; Additional folding
+ 1D5E4; 0071; Additional folding
+ 1D5E5; 0072; Additional folding
+ 1D5E6; 0073; Additional folding
+ 1D5E7; 0074; Additional folding
+ 1D5E8; 0075; Additional folding
+ 1D5E9; 0076; Additional folding
+ 1D5EA; 0077; Additional folding
+ 1D5EB; 0078; Additional folding
+ 1D5EC; 0079; Additional folding
+ 1D5ED; 007A; Additional folding
+ 1D608; 0061; Additional folding
+ 1D609; 0062; Additional folding
+ 1D60A; 0063; Additional folding
+ 1D60B; 0064; Additional folding
+ 1D60C; 0065; Additional folding
+ 1D60D; 0066; Additional folding
+ 1D60E; 0067; Additional folding
+ 1D60F; 0068; Additional folding
+ 1D610; 0069; Additional folding
+ 1D611; 006A; Additional folding
+ 1D612; 006B; Additional folding
+ 1D613; 006C; Additional folding
+ 1D614; 006D; Additional folding
+ 1D615; 006E; Additional folding
+ 1D616; 006F; Additional folding
+ 1D617; 0070; Additional folding
+ 1D618; 0071; Additional folding
+ 1D619; 0072; Additional folding
+ 1D61A; 0073; Additional folding
+ 1D61B; 0074; Additional folding
+ 1D61C; 0075; Additional folding
+ 1D61D; 0076; Additional folding
+ 1D61E; 0077; Additional folding
+ 1D61F; 0078; Additional folding
+ 1D620; 0079; Additional folding
+ 1D621; 007A; Additional folding
+ 1D63C; 0061; Additional folding
+ 1D63D; 0062; Additional folding
+ 1D63E; 0063; Additional folding
+ 1D63F; 0064; Additional folding
+ 1D640; 0065; Additional folding
+ 1D641; 0066; Additional folding
+ 1D642; 0067; Additional folding
+ 1D643; 0068; Additional folding
+ 1D644; 0069; Additional folding
+ 1D645; 006A; Additional folding
+ 1D646; 006B; Additional folding
+ 1D647; 006C; Additional folding
+ 1D648; 006D; Additional folding
+ 1D649; 006E; Additional folding
+ 1D64A; 006F; Additional folding
+ 1D64B; 0070; Additional folding
+ 1D64C; 0071; Additional folding
+ 1D64D; 0072; Additional folding
+ 1D64E; 0073; Additional folding
+ 1D64F; 0074; Additional folding
+ 1D650; 0075; Additional folding
+ 1D651; 0076; Additional folding
+ 1D652; 0077; Additional folding
+ 1D653; 0078; Additional folding
+ 1D654; 0079; Additional folding
+ 1D655; 007A; Additional folding
+ 1D670; 0061; Additional folding
+ 1D671; 0062; Additional folding
+ 1D672; 0063; Additional folding
+ 1D673; 0064; Additional folding
+ 1D674; 0065; Additional folding
+ 1D675; 0066; Additional folding
+ 1D676; 0067; Additional folding
+ 1D677; 0068; Additional folding
+ 1D678; 0069; Additional folding
+ 1D679; 006A; Additional folding
+ 1D67A; 006B; Additional folding
+ 1D67B; 006C; Additional folding
+ 1D67C; 006D; Additional folding
+ 1D67D; 006E; Additional folding
+ 1D67E; 006F; Additional folding
+ 1D67F; 0070; Additional folding
+ 1D680; 0071; Additional folding
+ 1D681; 0072; Additional folding
+ 1D682; 0073; Additional folding
+ 1D683; 0074; Additional folding
+ 1D684; 0075; Additional folding
+ 1D685; 0076; Additional folding
+ 1D686; 0077; Additional folding
+ 1D687; 0078; Additional folding
+ 1D688; 0079; Additional folding
+ 1D689; 007A; Additional folding
+ 1D6A8; 03B1; Additional folding
+ 1D6A9; 03B2; Additional folding
+ 1D6AA; 03B3; Additional folding
+ 1D6AB; 03B4; Additional folding
+ 1D6AC; 03B5; Additional folding
+ 1D6AD; 03B6; Additional folding
+ 1D6AE; 03B7; Additional folding
+ 1D6AF; 03B8; Additional folding
+ 1D6B0; 03B9; Additional folding
+ 1D6B1; 03BA; Additional folding
+ 1D6B2; 03BB; Additional folding
+ 1D6B3; 03BC; Additional folding
+ 1D6B4; 03BD; Additional folding
+ 1D6B5; 03BE; Additional folding
+ 1D6B6; 03BF; Additional folding
+ 1D6B7; 03C0; Additional folding
+ 1D6B8; 03C1; Additional folding
+ 1D6B9; 03B8; Additional folding
+ 1D6BA; 03C3; Additional folding
+ 1D6BB; 03C4; Additional folding
+ 1D6BC; 03C5; Additional folding
+ 1D6BD; 03C6; Additional folding
+ 1D6BE; 03C7; Additional folding
+ 1D6BF; 03C8; Additional folding
+ 1D6C0; 03C9; Additional folding
+ 1D6D3; 03C3; Additional folding
+ 1D6E2; 03B1; Additional folding
+ 1D6E3; 03B2; Additional folding
+ 1D6E4; 03B3; Additional folding
+ 1D6E5; 03B4; Additional folding
+ 1D6E6; 03B5; Additional folding
+ 1D6E7; 03B6; Additional folding
+ 1D6E8; 03B7; Additional folding
+ 1D6E9; 03B8; Additional folding
+ 1D6EA; 03B9; Additional folding
+ 1D6EB; 03BA; Additional folding
+ 1D6EC; 03BB; Additional folding
+ 1D6ED; 03BC; Additional folding
+ 1D6EE; 03BD; Additional folding
+ 1D6EF; 03BE; Additional folding
+ 1D6F0; 03BF; Additional folding
+ 1D6F1; 03C0; Additional folding
+ 1D6F2; 03C1; Additional folding
+ 1D6F3; 03B8; Additional folding
+ 1D6F4; 03C3; Additional folding
+ 1D6F5; 03C4; Additional folding
+ 1D6F6; 03C5; Additional folding
+ 1D6F7; 03C6; Additional folding
+ 1D6F8; 03C7; Additional folding
+ 1D6F9; 03C8; Additional folding
+ 1D6FA; 03C9; Additional folding
+ 1D70D; 03C3; Additional folding
+ 1D71C; 03B1; Additional folding
+ 1D71D; 03B2; Additional folding
+ 1D71E; 03B3; Additional folding
+ 1D71F; 03B4; Additional folding
+ 1D720; 03B5; Additional folding
+ 1D721; 03B6; Additional folding
+ 1D722; 03B7; Additional folding
+ 1D723; 03B8; Additional folding
+ 1D724; 03B9; Additional folding
+ 1D725; 03BA; Additional folding
+ 1D726; 03BB; Additional folding
+ 1D727; 03BC; Additional folding
+ 1D728; 03BD; Additional folding
+ 1D729; 03BE; Additional folding
+ 1D72A; 03BF; Additional folding
+ 1D72B; 03C0; Additional folding
+ 1D72C; 03C1; Additional folding
+ 1D72D; 03B8; Additional folding
+ 1D72E; 03C3; Additional folding
+ 1D72F; 03C4; Additional folding
+ 1D730; 03C5; Additional folding
+ 1D731; 03C6; Additional folding
+ 1D732; 03C7; Additional folding
+ 1D733; 03C8; Additional folding
+ 1D734; 03C9; Additional folding
+ 1D747; 03C3; Additional folding
+ 1D756; 03B1; Additional folding
+ 1D757; 03B2; Additional folding
+ 1D758; 03B3; Additional folding
+ 1D759; 03B4; Additional folding
+ 1D75A; 03B5; Additional folding
+ 1D75B; 03B6; Additional folding
+ 1D75C; 03B7; Additional folding
+ 1D75D; 03B8; Additional folding
+ 1D75E; 03B9; Additional folding
+ 1D75F; 03BA; Additional folding
+ 1D760; 03BB; Additional folding
+ 1D761; 03BC; Additional folding
+ 1D762; 03BD; Additional folding
+ 1D763; 03BE; Additional folding
+ 1D764; 03BF; Additional folding
+ 1D765; 03C0; Additional folding
+ 1D766; 03C1; Additional folding
+ 1D767; 03B8; Additional folding
+ 1D768; 03C3; Additional folding
+ 1D769; 03C4; Additional folding
+ 1D76A; 03C5; Additional folding
+ 1D76B; 03C6; Additional folding
+ 1D76C; 03C7; Additional folding
+ 1D76D; 03C8; Additional folding
+ 1D76E; 03C9; Additional folding
+ 1D781; 03C3; Additional folding
+ 1D790; 03B1; Additional folding
+ 1D791; 03B2; Additional folding
+ 1D792; 03B3; Additional folding
+ 1D793; 03B4; Additional folding
+ 1D794; 03B5; Additional folding
+ 1D795; 03B6; Additional folding
+ 1D796; 03B7; Additional folding
+ 1D797; 03B8; Additional folding
+ 1D798; 03B9; Additional folding
+ 1D799; 03BA; Additional folding
+ 1D79A; 03BB; Additional folding
+ 1D79B; 03BC; Additional folding
+ 1D79C; 03BD; Additional folding
+ 1D79D; 03BE; Additional folding
+ 1D79E; 03BF; Additional folding
+ 1D79F; 03C0; Additional folding
+ 1D7A0; 03C1; Additional folding
+ 1D7A1; 03B8; Additional folding
+ 1D7A2; 03C3; Additional folding
+ 1D7A3; 03C4; Additional folding
+ 1D7A4; 03C5; Additional folding
+ 1D7A5; 03C6; Additional folding
+ 1D7A6; 03C7; Additional folding
+ 1D7A7; 03C8; Additional folding
+ 1D7A8; 03C9; Additional folding
+ 1D7BB; 03C3; Additional folding
+ ----- End Table B.2 -----
+
+ ----- Start Table B.3 -----
+ 0041; 0061; Case map
+ 0042; 0062; Case map
+ 0043; 0063; Case map
+ 0044; 0064; Case map
+ 0045; 0065; Case map
+ 0046; 0066; Case map
+ 0047; 0067; Case map
+ 0048; 0068; Case map
+ 0049; 0069; Case map
+ 004A; 006A; Case map
+ 004B; 006B; Case map
+ 004C; 006C; Case map
+ 004D; 006D; Case map
+ 004E; 006E; Case map
+ 004F; 006F; Case map
+ 0050; 0070; Case map
+ 0051; 0071; Case map
+ 0052; 0072; Case map
+ 0053; 0073; Case map
+ 0054; 0074; Case map
+ 0055; 0075; Case map
+ 0056; 0076; Case map
+ 0057; 0077; Case map
+ 0058; 0078; Case map
+ 0059; 0079; Case map
+ 005A; 007A; Case map
+ 00B5; 03BC; Case map
+ 00C0; 00E0; Case map
+ 00C1; 00E1; Case map
+ 00C2; 00E2; Case map
+ 00C3; 00E3; Case map
+ 00C4; 00E4; Case map
+ 00C5; 00E5; Case map
+ 00C6; 00E6; Case map
+ 00C7; 00E7; Case map
+ 00C8; 00E8; Case map
+ 00C9; 00E9; Case map
+ 00CA; 00EA; Case map
+ 00CB; 00EB; Case map
+ 00CC; 00EC; Case map
+ 00CD; 00ED; Case map
+ 00CE; 00EE; Case map
+ 00CF; 00EF; Case map
+ 00D0; 00F0; Case map
+ 00D1; 00F1; Case map
+ 00D2; 00F2; Case map
+ 00D3; 00F3; Case map
+ 00D4; 00F4; Case map
+ 00D5; 00F5; Case map
+ 00D6; 00F6; Case map
+ 00D8; 00F8; Case map
+ 00D9; 00F9; Case map
+ 00DA; 00FA; Case map
+ 00DB; 00FB; Case map
+ 00DC; 00FC; Case map
+ 00DD; 00FD; Case map
+ 00DE; 00FE; Case map
+ 00DF; 0073 0073; Case map
+ 0100; 0101; Case map
+ 0102; 0103; Case map
+ 0104; 0105; Case map
+ 0106; 0107; Case map
+ 0108; 0109; Case map
+ 010A; 010B; Case map
+ 010C; 010D; Case map
+ 010E; 010F; Case map
+ 0110; 0111; Case map
+ 0112; 0113; Case map
+ 0114; 0115; Case map
+ 0116; 0117; Case map
+ 0118; 0119; Case map
+ 011A; 011B; Case map
+ 011C; 011D; Case map
+ 011E; 011F; Case map
+ 0120; 0121; Case map
+ 0122; 0123; Case map
+ 0124; 0125; Case map
+ 0126; 0127; Case map
+ 0128; 0129; Case map
+ 012A; 012B; Case map
+ 012C; 012D; Case map
+ 012E; 012F; Case map
+ 0130; 0069 0307; Case map
+ 0132; 0133; Case map
+ 0134; 0135; Case map
+ 0136; 0137; Case map
+ 0139; 013A; Case map
+ 013B; 013C; Case map
+ 013D; 013E; Case map
+ 013F; 0140; Case map
+ 0141; 0142; Case map
+ 0143; 0144; Case map
+ 0145; 0146; Case map
+ 0147; 0148; Case map
+ 0149; 02BC 006E; Case map
+ 014A; 014B; Case map
+ 014C; 014D; Case map
+ 014E; 014F; Case map
+ 0150; 0151; Case map
+ 0152; 0153; Case map
+ 0154; 0155; Case map
+ 0156; 0157; Case map
+ 0158; 0159; Case map
+ 015A; 015B; Case map
+ 015C; 015D; Case map
+ 015E; 015F; Case map
+ 0160; 0161; Case map
+ 0162; 0163; Case map
+ 0164; 0165; Case map
+ 0166; 0167; Case map
+ 0168; 0169; Case map
+ 016A; 016B; Case map
+ 016C; 016D; Case map
+ 016E; 016F; Case map
+ 0170; 0171; Case map
+ 0172; 0173; Case map
+ 0174; 0175; Case map
+ 0176; 0177; Case map
+ 0178; 00FF; Case map
+ 0179; 017A; Case map
+ 017B; 017C; Case map
+ 017D; 017E; Case map
+ 017F; 0073; Case map
+ 0181; 0253; Case map
+ 0182; 0183; Case map
+ 0184; 0185; Case map
+ 0186; 0254; Case map
+ 0187; 0188; Case map
+ 0189; 0256; Case map
+ 018A; 0257; Case map
+ 018B; 018C; Case map
+ 018E; 01DD; Case map
+ 018F; 0259; Case map
+ 0190; 025B; Case map
+ 0191; 0192; Case map
+ 0193; 0260; Case map
+ 0194; 0263; Case map
+ 0196; 0269; Case map
+ 0197; 0268; Case map
+ 0198; 0199; Case map
+ 019C; 026F; Case map
+ 019D; 0272; Case map
+ 019F; 0275; Case map
+ 01A0; 01A1; Case map
+ 01A2; 01A3; Case map
+ 01A4; 01A5; Case map
+ 01A6; 0280; Case map
+ 01A7; 01A8; Case map
+ 01A9; 0283; Case map
+ 01AC; 01AD; Case map
+ 01AE; 0288; Case map
+ 01AF; 01B0; Case map
+ 01B1; 028A; Case map
+ 01B2; 028B; Case map
+ 01B3; 01B4; Case map
+ 01B5; 01B6; Case map
+ 01B7; 0292; Case map
+ 01B8; 01B9; Case map
+ 01BC; 01BD; Case map
+ 01C4; 01C6; Case map
+ 01C5; 01C6; Case map
+ 01C7; 01C9; Case map
+ 01C8; 01C9; Case map
+ 01CA; 01CC; Case map
+ 01CB; 01CC; Case map
+ 01CD; 01CE; Case map
+ 01CF; 01D0; Case map
+ 01D1; 01D2; Case map
+ 01D3; 01D4; Case map
+ 01D5; 01D6; Case map
+ 01D7; 01D8; Case map
+ 01D9; 01DA; Case map
+ 01DB; 01DC; Case map
+ 01DE; 01DF; Case map
+ 01E0; 01E1; Case map
+ 01E2; 01E3; Case map
+ 01E4; 01E5; Case map
+ 01E6; 01E7; Case map
+ 01E8; 01E9; Case map
+ 01EA; 01EB; Case map
+ 01EC; 01ED; Case map
+ 01EE; 01EF; Case map
+ 01F0; 006A 030C; Case map
+ 01F1; 01F3; Case map
+ 01F2; 01F3; Case map
+ 01F4; 01F5; Case map
+ 01F6; 0195; Case map
+ 01F7; 01BF; Case map
+ 01F8; 01F9; Case map
+ 01FA; 01FB; Case map
+ 01FC; 01FD; Case map
+ 01FE; 01FF; Case map
+ 0200; 0201; Case map
+ 0202; 0203; Case map
+ 0204; 0205; Case map
+ 0206; 0207; Case map
+ 0208; 0209; Case map
+ 020A; 020B; Case map
+ 020C; 020D; Case map
+ 020E; 020F; Case map
+ 0210; 0211; Case map
+ 0212; 0213; Case map
+ 0214; 0215; Case map
+ 0216; 0217; Case map
+ 0218; 0219; Case map
+ 021A; 021B; Case map
+ 021C; 021D; Case map
+ 021E; 021F; Case map
+ 0220; 019E; Case map
+ 0222; 0223; Case map
+ 0224; 0225; Case map
+ 0226; 0227; Case map
+ 0228; 0229; Case map
+ 022A; 022B; Case map
+ 022C; 022D; Case map
+ 022E; 022F; Case map
+ 0230; 0231; Case map
+ 0232; 0233; Case map
+ 0345; 03B9; Case map
+ 0386; 03AC; Case map
+ 0388; 03AD; Case map
+ 0389; 03AE; Case map
+ 038A; 03AF; Case map
+ 038C; 03CC; Case map
+ 038E; 03CD; Case map
+ 038F; 03CE; Case map
+ 0390; 03B9 0308 0301; Case map
+ 0391; 03B1; Case map
+ 0392; 03B2; Case map
+ 0393; 03B3; Case map
+ 0394; 03B4; Case map
+ 0395; 03B5; Case map
+ 0396; 03B6; Case map
+ 0397; 03B7; Case map
+ 0398; 03B8; Case map
+ 0399; 03B9; Case map
+ 039A; 03BA; Case map
+ 039B; 03BB; Case map
+ 039C; 03BC; Case map
+ 039D; 03BD; Case map
+ 039E; 03BE; Case map
+ 039F; 03BF; Case map
+ 03A0; 03C0; Case map
+ 03A1; 03C1; Case map
+ 03A3; 03C3; Case map
+ 03A4; 03C4; Case map
+ 03A5; 03C5; Case map
+ 03A6; 03C6; Case map
+ 03A7; 03C7; Case map
+ 03A8; 03C8; Case map
+ 03A9; 03C9; Case map
+ 03AA; 03CA; Case map
+ 03AB; 03CB; Case map
+ 03B0; 03C5 0308 0301; Case map
+ 03C2; 03C3; Case map
+ 03D0; 03B2; Case map
+ 03D1; 03B8; Case map
+ 03D5; 03C6; Case map
+ 03D6; 03C0; Case map
+ 03D8; 03D9; Case map
+ 03DA; 03DB; Case map
+ 03DC; 03DD; Case map
+ 03DE; 03DF; Case map
+ 03E0; 03E1; Case map
+ 03E2; 03E3; Case map
+ 03E4; 03E5; Case map
+ 03E6; 03E7; Case map
+ 03E8; 03E9; Case map
+ 03EA; 03EB; Case map
+ 03EC; 03ED; Case map
+ 03EE; 03EF; Case map
+ 03F0; 03BA; Case map
+ 03F1; 03C1; Case map
+ 03F2; 03C3; Case map
+ 03F4; 03B8; Case map
+ 03F5; 03B5; Case map
+ 0400; 0450; Case map
+ 0401; 0451; Case map
+ 0402; 0452; Case map
+ 0403; 0453; Case map
+ 0404; 0454; Case map
+ 0405; 0455; Case map
+ 0406; 0456; Case map
+ 0407; 0457; Case map
+ 0408; 0458; Case map
+ 0409; 0459; Case map
+ 040A; 045A; Case map
+ 040B; 045B; Case map
+ 040C; 045C; Case map
+ 040D; 045D; Case map
+ 040E; 045E; Case map
+ 040F; 045F; Case map
+ 0410; 0430; Case map
+ 0411; 0431; Case map
+ 0412; 0432; Case map
+ 0413; 0433; Case map
+ 0414; 0434; Case map
+ 0415; 0435; Case map
+ 0416; 0436; Case map
+ 0417; 0437; Case map
+ 0418; 0438; Case map
+ 0419; 0439; Case map
+ 041A; 043A; Case map
+ 041B; 043B; Case map
+ 041C; 043C; Case map
+ 041D; 043D; Case map
+ 041E; 043E; Case map
+ 041F; 043F; Case map
+ 0420; 0440; Case map
+ 0421; 0441; Case map
+ 0422; 0442; Case map
+ 0423; 0443; Case map
+ 0424; 0444; Case map
+ 0425; 0445; Case map
+ 0426; 0446; Case map
+ 0427; 0447; Case map
+ 0428; 0448; Case map
+ 0429; 0449; Case map
+ 042A; 044A; Case map
+ 042B; 044B; Case map
+ 042C; 044C; Case map
+ 042D; 044D; Case map
+ 042E; 044E; Case map
+ 042F; 044F; Case map
+ 0460; 0461; Case map
+ 0462; 0463; Case map
+ 0464; 0465; Case map
+ 0466; 0467; Case map
+ 0468; 0469; Case map
+ 046A; 046B; Case map
+ 046C; 046D; Case map
+ 046E; 046F; Case map
+ 0470; 0471; Case map
+ 0472; 0473; Case map
+ 0474; 0475; Case map
+ 0476; 0477; Case map
+ 0478; 0479; Case map
+ 047A; 047B; Case map
+ 047C; 047D; Case map
+ 047E; 047F; Case map
+ 0480; 0481; Case map
+ 048A; 048B; Case map
+ 048C; 048D; Case map
+ 048E; 048F; Case map
+ 0490; 0491; Case map
+ 0492; 0493; Case map
+ 0494; 0495; Case map
+ 0496; 0497; Case map
+ 0498; 0499; Case map
+ 049A; 049B; Case map
+ 049C; 049D; Case map
+ 049E; 049F; Case map
+ 04A0; 04A1; Case map
+ 04A2; 04A3; Case map
+ 04A4; 04A5; Case map
+ 04A6; 04A7; Case map
+ 04A8; 04A9; Case map
+ 04AA; 04AB; Case map
+ 04AC; 04AD; Case map
+ 04AE; 04AF; Case map
+ 04B0; 04B1; Case map
+ 04B2; 04B3; Case map
+ 04B4; 04B5; Case map
+ 04B6; 04B7; Case map
+ 04B8; 04B9; Case map
+ 04BA; 04BB; Case map
+ 04BC; 04BD; Case map
+ 04BE; 04BF; Case map
+ 04C1; 04C2; Case map
+ 04C3; 04C4; Case map
+ 04C5; 04C6; Case map
+ 04C7; 04C8; Case map
+ 04C9; 04CA; Case map
+ 04CB; 04CC; Case map
+ 04CD; 04CE; Case map
+ 04D0; 04D1; Case map
+ 04D2; 04D3; Case map
+ 04D4; 04D5; Case map
+ 04D6; 04D7; Case map
+ 04D8; 04D9; Case map
+ 04DA; 04DB; Case map
+ 04DC; 04DD; Case map
+ 04DE; 04DF; Case map
+ 04E0; 04E1; Case map
+ 04E2; 04E3; Case map
+ 04E4; 04E5; Case map
+ 04E6; 04E7; Case map
+ 04E8; 04E9; Case map
+ 04EA; 04EB; Case map
+ 04EC; 04ED; Case map
+ 04EE; 04EF; Case map
+ 04F0; 04F1; Case map
+ 04F2; 04F3; Case map
+ 04F4; 04F5; Case map
+ 04F8; 04F9; Case map
+ 0500; 0501; Case map
+ 0502; 0503; Case map
+ 0504; 0505; Case map
+ 0506; 0507; Case map
+ 0508; 0509; Case map
+ 050A; 050B; Case map
+ 050C; 050D; Case map
+ 050E; 050F; Case map
+ 0531; 0561; Case map
+ 0532; 0562; Case map
+ 0533; 0563; Case map
+ 0534; 0564; Case map
+ 0535; 0565; Case map
+ 0536; 0566; Case map
+ 0537; 0567; Case map
+ 0538; 0568; Case map
+ 0539; 0569; Case map
+ 053A; 056A; Case map
+ 053B; 056B; Case map
+ 053C; 056C; Case map
+ 053D; 056D; Case map
+ 053E; 056E; Case map
+ 053F; 056F; Case map
+ 0540; 0570; Case map
+ 0541; 0571; Case map
+ 0542; 0572; Case map
+ 0543; 0573; Case map
+ 0544; 0574; Case map
+ 0545; 0575; Case map
+ 0546; 0576; Case map
+ 0547; 0577; Case map
+ 0548; 0578; Case map
+ 0549; 0579; Case map
+ 054A; 057A; Case map
+ 054B; 057B; Case map
+ 054C; 057C; Case map
+ 054D; 057D; Case map
+ 054E; 057E; Case map
+ 054F; 057F; Case map
+ 0550; 0580; Case map
+ 0551; 0581; Case map
+ 0552; 0582; Case map
+ 0553; 0583; Case map
+ 0554; 0584; Case map
+ 0555; 0585; Case map
+ 0556; 0586; Case map
+ 0587; 0565 0582; Case map
+ 1E00; 1E01; Case map
+ 1E02; 1E03; Case map
+ 1E04; 1E05; Case map
+ 1E06; 1E07; Case map
+ 1E08; 1E09; Case map
+ 1E0A; 1E0B; Case map
+ 1E0C; 1E0D; Case map
+ 1E0E; 1E0F; Case map
+ 1E10; 1E11; Case map
+ 1E12; 1E13; Case map
+ 1E14; 1E15; Case map
+ 1E16; 1E17; Case map
+ 1E18; 1E19; Case map
+ 1E1A; 1E1B; Case map
+ 1E1C; 1E1D; Case map
+ 1E1E; 1E1F; Case map
+ 1E20; 1E21; Case map
+ 1E22; 1E23; Case map
+ 1E24; 1E25; Case map
+ 1E26; 1E27; Case map
+ 1E28; 1E29; Case map
+ 1E2A; 1E2B; Case map
+ 1E2C; 1E2D; Case map
+ 1E2E; 1E2F; Case map
+ 1E30; 1E31; Case map
+ 1E32; 1E33; Case map
+ 1E34; 1E35; Case map
+ 1E36; 1E37; Case map
+ 1E38; 1E39; Case map
+ 1E3A; 1E3B; Case map
+ 1E3C; 1E3D; Case map
+ 1E3E; 1E3F; Case map
+ 1E40; 1E41; Case map
+ 1E42; 1E43; Case map
+ 1E44; 1E45; Case map
+ 1E46; 1E47; Case map
+ 1E48; 1E49; Case map
+ 1E4A; 1E4B; Case map
+ 1E4C; 1E4D; Case map
+ 1E4E; 1E4F; Case map
+ 1E50; 1E51; Case map
+ 1E52; 1E53; Case map
+ 1E54; 1E55; Case map
+ 1E56; 1E57; Case map
+ 1E58; 1E59; Case map
+ 1E5A; 1E5B; Case map
+ 1E5C; 1E5D; Case map
+ 1E5E; 1E5F; Case map
+ 1E60; 1E61; Case map
+ 1E62; 1E63; Case map
+ 1E64; 1E65; Case map
+ 1E66; 1E67; Case map
+ 1E68; 1E69; Case map
+ 1E6A; 1E6B; Case map
+ 1E6C; 1E6D; Case map
+ 1E6E; 1E6F; Case map
+ 1E70; 1E71; Case map
+ 1E72; 1E73; Case map
+ 1E74; 1E75; Case map
+ 1E76; 1E77; Case map
+ 1E78; 1E79; Case map
+ 1E7A; 1E7B; Case map
+ 1E7C; 1E7D; Case map
+ 1E7E; 1E7F; Case map
+ 1E80; 1E81; Case map
+ 1E82; 1E83; Case map
+ 1E84; 1E85; Case map
+ 1E86; 1E87; Case map
+ 1E88; 1E89; Case map
+ 1E8A; 1E8B; Case map
+ 1E8C; 1E8D; Case map
+ 1E8E; 1E8F; Case map
+ 1E90; 1E91; Case map
+ 1E92; 1E93; Case map
+ 1E94; 1E95; Case map
+ 1E96; 0068 0331; Case map
+ 1E97; 0074 0308; Case map
+ 1E98; 0077 030A; Case map
+ 1E99; 0079 030A; Case map
+ 1E9A; 0061 02BE; Case map
+ 1E9B; 1E61; Case map
+ 1EA0; 1EA1; Case map
+ 1EA2; 1EA3; Case map
+ 1EA4; 1EA5; Case map
+ 1EA6; 1EA7; Case map
+ 1EA8; 1EA9; Case map
+ 1EAA; 1EAB; Case map
+ 1EAC; 1EAD; Case map
+ 1EAE; 1EAF; Case map
+ 1EB0; 1EB1; Case map
+ 1EB2; 1EB3; Case map
+ 1EB4; 1EB5; Case map
+ 1EB6; 1EB7; Case map
+ 1EB8; 1EB9; Case map
+ 1EBA; 1EBB; Case map
+ 1EBC; 1EBD; Case map
+ 1EBE; 1EBF; Case map
+ 1EC0; 1EC1; Case map
+ 1EC2; 1EC3; Case map
+ 1EC4; 1EC5; Case map
+ 1EC6; 1EC7; Case map
+ 1EC8; 1EC9; Case map
+ 1ECA; 1ECB; Case map
+ 1ECC; 1ECD; Case map
+ 1ECE; 1ECF; Case map
+ 1ED0; 1ED1; Case map
+ 1ED2; 1ED3; Case map
+ 1ED4; 1ED5; Case map
+ 1ED6; 1ED7; Case map
+ 1ED8; 1ED9; Case map
+ 1EDA; 1EDB; Case map
+ 1EDC; 1EDD; Case map
+ 1EDE; 1EDF; Case map
+ 1EE0; 1EE1; Case map
+ 1EE2; 1EE3; Case map
+ 1EE4; 1EE5; Case map
+ 1EE6; 1EE7; Case map
+ 1EE8; 1EE9; Case map
+ 1EEA; 1EEB; Case map
+ 1EEC; 1EED; Case map
+ 1EEE; 1EEF; Case map
+ 1EF0; 1EF1; Case map
+ 1EF2; 1EF3; Case map
+ 1EF4; 1EF5; Case map
+ 1EF6; 1EF7; Case map
+ 1EF8; 1EF9; Case map
+ 1F08; 1F00; Case map
+ 1F09; 1F01; Case map
+ 1F0A; 1F02; Case map
+ 1F0B; 1F03; Case map
+ 1F0C; 1F04; Case map
+ 1F0D; 1F05; Case map
+ 1F0E; 1F06; Case map
+ 1F0F; 1F07; Case map
+ 1F18; 1F10; Case map
+ 1F19; 1F11; Case map
+ 1F1A; 1F12; Case map
+ 1F1B; 1F13; Case map
+ 1F1C; 1F14; Case map
+ 1F1D; 1F15; Case map
+ 1F28; 1F20; Case map
+ 1F29; 1F21; Case map
+ 1F2A; 1F22; Case map
+ 1F2B; 1F23; Case map
+ 1F2C; 1F24; Case map
+ 1F2D; 1F25; Case map
+ 1F2E; 1F26; Case map
+ 1F2F; 1F27; Case map
+ 1F38; 1F30; Case map
+ 1F39; 1F31; Case map
+ 1F3A; 1F32; Case map
+ 1F3B; 1F33; Case map
+ 1F3C; 1F34; Case map
+ 1F3D; 1F35; Case map
+ 1F3E; 1F36; Case map
+ 1F3F; 1F37; Case map
+ 1F48; 1F40; Case map
+ 1F49; 1F41; Case map
+ 1F4A; 1F42; Case map
+ 1F4B; 1F43; Case map
+ 1F4C; 1F44; Case map
+ 1F4D; 1F45; Case map
+ 1F50; 03C5 0313; Case map
+ 1F52; 03C5 0313 0300; Case map
+ 1F54; 03C5 0313 0301; Case map
+ 1F56; 03C5 0313 0342; Case map
+ 1F59; 1F51; Case map
+ 1F5B; 1F53; Case map
+ 1F5D; 1F55; Case map
+ 1F5F; 1F57; Case map
+ 1F68; 1F60; Case map
+ 1F69; 1F61; Case map
+ 1F6A; 1F62; Case map
+ 1F6B; 1F63; Case map
+ 1F6C; 1F64; Case map
+ 1F6D; 1F65; Case map
+ 1F6E; 1F66; Case map
+ 1F6F; 1F67; Case map
+ 1F80; 1F00 03B9; Case map
+ 1F81; 1F01 03B9; Case map
+ 1F82; 1F02 03B9; Case map
+ 1F83; 1F03 03B9; Case map
+ 1F84; 1F04 03B9; Case map
+ 1F85; 1F05 03B9; Case map
+ 1F86; 1F06 03B9; Case map
+ 1F87; 1F07 03B9; Case map
+ 1F88; 1F00 03B9; Case map
+ 1F89; 1F01 03B9; Case map
+ 1F8A; 1F02 03B9; Case map
+ 1F8B; 1F03 03B9; Case map
+ 1F8C; 1F04 03B9; Case map
+ 1F8D; 1F05 03B9; Case map
+ 1F8E; 1F06 03B9; Case map
+ 1F8F; 1F07 03B9; Case map
+ 1F90; 1F20 03B9; Case map
+ 1F91; 1F21 03B9; Case map
+ 1F92; 1F22 03B9; Case map
+ 1F93; 1F23 03B9; Case map
+ 1F94; 1F24 03B9; Case map
+ 1F95; 1F25 03B9; Case map
+ 1F96; 1F26 03B9; Case map
+ 1F97; 1F27 03B9; Case map
+ 1F98; 1F20 03B9; Case map
+ 1F99; 1F21 03B9; Case map
+ 1F9A; 1F22 03B9; Case map
+ 1F9B; 1F23 03B9; Case map
+ 1F9C; 1F24 03B9; Case map
+ 1F9D; 1F25 03B9; Case map
+ 1F9E; 1F26 03B9; Case map
+ 1F9F; 1F27 03B9; Case map
+ 1FA0; 1F60 03B9; Case map
+ 1FA1; 1F61 03B9; Case map
+ 1FA2; 1F62 03B9; Case map
+ 1FA3; 1F63 03B9; Case map
+ 1FA4; 1F64 03B9; Case map
+ 1FA5; 1F65 03B9; Case map
+ 1FA6; 1F66 03B9; Case map
+ 1FA7; 1F67 03B9; Case map
+ 1FA8; 1F60 03B9; Case map
+ 1FA9; 1F61 03B9; Case map
+ 1FAA; 1F62 03B9; Case map
+ 1FAB; 1F63 03B9; Case map
+ 1FAC; 1F64 03B9; Case map
+ 1FAD; 1F65 03B9; Case map
+ 1FAE; 1F66 03B9; Case map
+ 1FAF; 1F67 03B9; Case map
+ 1FB2; 1F70 03B9; Case map
+ 1FB3; 03B1 03B9; Case map
+ 1FB4; 03AC 03B9; Case map
+ 1FB6; 03B1 0342; Case map
+ 1FB7; 03B1 0342 03B9; Case map
+ 1FB8; 1FB0; Case map
+ 1FB9; 1FB1; Case map
+ 1FBA; 1F70; Case map
+ 1FBB; 1F71; Case map
+ 1FBC; 03B1 03B9; Case map
+ 1FBE; 03B9; Case map
+ 1FC2; 1F74 03B9; Case map
+ 1FC3; 03B7 03B9; Case map
+ 1FC4; 03AE 03B9; Case map
+ 1FC6; 03B7 0342; Case map
+ 1FC7; 03B7 0342 03B9; Case map
+ 1FC8; 1F72; Case map
+ 1FC9; 1F73; Case map
+ 1FCA; 1F74; Case map
+ 1FCB; 1F75; Case map
+ 1FCC; 03B7 03B9; Case map
+ 1FD2; 03B9 0308 0300; Case map
+ 1FD3; 03B9 0308 0301; Case map
+ 1FD6; 03B9 0342; Case map
+ 1FD7; 03B9 0308 0342; Case map
+ 1FD8; 1FD0; Case map
+ 1FD9; 1FD1; Case map
+ 1FDA; 1F76; Case map
+ 1FDB; 1F77; Case map
+ 1FE2; 03C5 0308 0300; Case map
+ 1FE3; 03C5 0308 0301; Case map
+ 1FE4; 03C1 0313; Case map
+ 1FE6; 03C5 0342; Case map
+ 1FE7; 03C5 0308 0342; Case map
+ 1FE8; 1FE0; Case map
+ 1FE9; 1FE1; Case map
+ 1FEA; 1F7A; Case map
+ 1FEB; 1F7B; Case map
+ 1FEC; 1FE5; Case map
+ 1FF2; 1F7C 03B9; Case map
+ 1FF3; 03C9 03B9; Case map
+ 1FF4; 03CE 03B9; Case map
+ 1FF6; 03C9 0342; Case map
+ 1FF7; 03C9 0342 03B9; Case map
+ 1FF8; 1F78; Case map
+ 1FF9; 1F79; Case map
+ 1FFA; 1F7C; Case map
+ 1FFB; 1F7D; Case map
+ 1FFC; 03C9 03B9; Case map
+ 2126; 03C9; Case map
+ 212A; 006B; Case map
+ 212B; 00E5; Case map
+ 2160; 2170; Case map
+ 2161; 2171; Case map
+ 2162; 2172; Case map
+ 2163; 2173; Case map
+ 2164; 2174; Case map
+ 2165; 2175; Case map
+ 2166; 2176; Case map
+ 2167; 2177; Case map
+ 2168; 2178; Case map
+ 2169; 2179; Case map
+ 216A; 217A; Case map
+ 216B; 217B; Case map
+ 216C; 217C; Case map
+ 216D; 217D; Case map
+ 216E; 217E; Case map
+ 216F; 217F; Case map
+ 24B6; 24D0; Case map
+ 24B7; 24D1; Case map
+ 24B8; 24D2; Case map
+ 24B9; 24D3; Case map
+ 24BA; 24D4; Case map
+ 24BB; 24D5; Case map
+ 24BC; 24D6; Case map
+ 24BD; 24D7; Case map
+ 24BE; 24D8; Case map
+ 24BF; 24D9; Case map
+ 24C0; 24DA; Case map
+ 24C1; 24DB; Case map
+ 24C2; 24DC; Case map
+ 24C3; 24DD; Case map
+ 24C4; 24DE; Case map
+ 24C5; 24DF; Case map
+ 24C6; 24E0; Case map
+ 24C7; 24E1; Case map
+ 24C8; 24E2; Case map
+ 24C9; 24E3; Case map
+ 24CA; 24E4; Case map
+ 24CB; 24E5; Case map
+ 24CC; 24E6; Case map
+ 24CD; 24E7; Case map
+ 24CE; 24E8; Case map
+ 24CF; 24E9; Case map
+ FB00; 0066 0066; Case map
+ FB01; 0066 0069; Case map
+ FB02; 0066 006C; Case map
+ FB03; 0066 0066 0069; Case map
+ FB04; 0066 0066 006C; Case map
+ FB05; 0073 0074; Case map
+ FB06; 0073 0074; Case map
+ FB13; 0574 0576; Case map
+ FB14; 0574 0565; Case map
+ FB15; 0574 056B; Case map
+ FB16; 057E 0576; Case map
+ FB17; 0574 056D; Case map
+ FF21; FF41; Case map
+ FF22; FF42; Case map
+ FF23; FF43; Case map
+ FF24; FF44; Case map
+ FF25; FF45; Case map
+ FF26; FF46; Case map
+ FF27; FF47; Case map
+ FF28; FF48; Case map
+ FF29; FF49; Case map
+ FF2A; FF4A; Case map
+ FF2B; FF4B; Case map
+ FF2C; FF4C; Case map
+ FF2D; FF4D; Case map
+ FF2E; FF4E; Case map
+ FF2F; FF4F; Case map
+ FF30; FF50; Case map
+ FF31; FF51; Case map
+ FF32; FF52; Case map
+ FF33; FF53; Case map
+ FF34; FF54; Case map
+ FF35; FF55; Case map
+ FF36; FF56; Case map
+ FF37; FF57; Case map
+ FF38; FF58; Case map
+ FF39; FF59; Case map
+ FF3A; FF5A; Case map
+ 10400; 10428; Case map
+ 10401; 10429; Case map
+ 10402; 1042A; Case map
+ 10403; 1042B; Case map
+ 10404; 1042C; Case map
+ 10405; 1042D; Case map
+ 10406; 1042E; Case map
+ 10407; 1042F; Case map
+ 10408; 10430; Case map
+ 10409; 10431; Case map
+ 1040A; 10432; Case map
+ 1040B; 10433; Case map
+ 1040C; 10434; Case map
+ 1040D; 10435; Case map
+ 1040E; 10436; Case map
+ 1040F; 10437; Case map
+ 10410; 10438; Case map
+ 10411; 10439; Case map
+ 10412; 1043A; Case map
+ 10413; 1043B; Case map
+ 10414; 1043C; Case map
+ 10415; 1043D; Case map
+ 10416; 1043E; Case map
+ 10417; 1043F; Case map
+ 10418; 10440; Case map
+ 10419; 10441; Case map
+ 1041A; 10442; Case map
+ 1041B; 10443; Case map
+ 1041C; 10444; Case map
+ 1041D; 10445; Case map
+ 1041E; 10446; Case map
+ 1041F; 10447; Case map
+ 10420; 10448; Case map
+ 10421; 10449; Case map
+ 10422; 1044A; Case map
+ 10423; 1044B; Case map
+ 10424; 1044C; Case map
+ 10425; 1044D; Case map
+ ----- End Table B.3 -----
+
+ ----- Start Table C.1.1 -----
+ 0020; SPACE
+ ----- End Table C.1.1 -----
+
+ ----- Start Table C.1.2 -----
+ 00A0; NO-BREAK SPACE
+ 1680; OGHAM SPACE MARK
+ 2000; EN QUAD
+ 2001; EM QUAD
+ 2002; EN SPACE
+ 2003; EM SPACE
+ 2004; THREE-PER-EM SPACE
+ 2005; FOUR-PER-EM SPACE
+ 2006; SIX-PER-EM SPACE
+ 2007; FIGURE SPACE
+ 2008; PUNCTUATION SPACE
+ 2009; THIN SPACE
+ 200A; HAIR SPACE
+ 200B; ZERO WIDTH SPACE
+ 202F; NARROW NO-BREAK SPACE
+ 205F; MEDIUM MATHEMATICAL SPACE
+ 3000; IDEOGRAPHIC SPACE
+ ----- End Table C.1.2 -----
+
+ ----- Start Table C.2.1 -----
+ 0000-001F; [CONTROL CHARACTERS]
+ 007F; DELETE
+ ----- End Table C.2.1 -----
+
+ ----- Start Table C.2.2 -----
+ 0080-009F; [CONTROL CHARACTERS]
+ 06DD; ARABIC END OF AYAH
+ 070F; SYRIAC ABBREVIATION MARK
+ 180E; MONGOLIAN VOWEL SEPARATOR
+ 200C; ZERO WIDTH NON-JOINER
+ 200D; ZERO WIDTH JOINER
+ 2028; LINE SEPARATOR
+ 2029; PARAGRAPH SEPARATOR
+ 2060; WORD JOINER
+ 2061; FUNCTION APPLICATION
+ 2062; INVISIBLE TIMES
+ 2063; INVISIBLE SEPARATOR
+ 206A-206F; [CONTROL CHARACTERS]
+ FEFF; ZERO WIDTH NO-BREAK SPACE
+ FFF9-FFFC; [CONTROL CHARACTERS]
+ 1D173-1D17A; [MUSICAL CONTROL CHARACTERS]
+ ----- End Table C.2.2 -----
+
+ ----- Start Table C.3 -----
+ E000-F8FF; [PRIVATE USE, PLANE 0]
+ F0000-FFFFD; [PRIVATE USE, PLANE 15]
+ 100000-10FFFD; [PRIVATE USE, PLANE 16]
+ ----- End Table C.3 -----
+
+ ----- Start Table C.4 -----
+ FDD0-FDEF; [NONCHARACTER CODE POINTS]
+ FFFE-FFFF; [NONCHARACTER CODE POINTS]
+ 1FFFE-1FFFF; [NONCHARACTER CODE POINTS]
+ 2FFFE-2FFFF; [NONCHARACTER CODE POINTS]
+ 3FFFE-3FFFF; [NONCHARACTER CODE POINTS]
+ 4FFFE-4FFFF; [NONCHARACTER CODE POINTS]
+ 5FFFE-5FFFF; [NONCHARACTER CODE POINTS]
+ 6FFFE-6FFFF; [NONCHARACTER CODE POINTS]
+ 7FFFE-7FFFF; [NONCHARACTER CODE POINTS]
+ 8FFFE-8FFFF; [NONCHARACTER CODE POINTS]
+ 9FFFE-9FFFF; [NONCHARACTER CODE POINTS]
+ AFFFE-AFFFF; [NONCHARACTER CODE POINTS]
+ BFFFE-BFFFF; [NONCHARACTER CODE POINTS]
+ CFFFE-CFFFF; [NONCHARACTER CODE POINTS]
+ DFFFE-DFFFF; [NONCHARACTER CODE POINTS]
+ EFFFE-EFFFF; [NONCHARACTER CODE POINTS]
+ FFFFE-FFFFF; [NONCHARACTER CODE POINTS]
+ 10FFFE-10FFFF; [NONCHARACTER CODE POINTS]
+ ----- End Table C.4 -----
+
+ ----- Start Table C.5 -----
+ D800-DFFF; [SURROGATE CODES]
+ ----- End Table C.5 -----
+
+ ----- Start Table C.6 -----
+ FFF9; INTERLINEAR ANNOTATION ANCHOR
+ FFFA; INTERLINEAR ANNOTATION SEPARATOR
+ FFFB; INTERLINEAR ANNOTATION TERMINATOR
+ FFFC; OBJECT REPLACEMENT CHARACTER
+ FFFD; REPLACEMENT CHARACTER
+ ----- End Table C.6 -----
+
+ ----- Start Table C.7 -----
+ 2FF0-2FFB; [IDEOGRAPHIC DESCRIPTION CHARACTERS]
+ ----- End Table C.7 -----
+
+ ----- Start Table C.8 -----
+ 0340; COMBINING GRAVE TONE MARK
+ 0341; COMBINING ACUTE TONE MARK
+ 200E; LEFT-TO-RIGHT MARK
+ 200F; RIGHT-TO-LEFT MARK
+ 202A; LEFT-TO-RIGHT EMBEDDING
+ 202B; RIGHT-TO-LEFT EMBEDDING
+ 202C; POP DIRECTIONAL FORMATTING
+ 202D; LEFT-TO-RIGHT OVERRIDE
+ 202E; RIGHT-TO-LEFT OVERRIDE
+ 206A; INHIBIT SYMMETRIC SWAPPING
+ 206B; ACTIVATE SYMMETRIC SWAPPING
+ 206C; INHIBIT ARABIC FORM SHAPING
+ 206D; ACTIVATE ARABIC FORM SHAPING
+ 206E; NATIONAL DIGIT SHAPES
+ 206F; NOMINAL DIGIT SHAPES
+ ----- End Table C.8 -----
+
+ ----- Start Table C.9 -----
+ E0001; LANGUAGE TAG
+ E0020-E007F; [TAGGING CHARACTERS]
+ ----- End Table C.9 -----
+
+ ----- Start Table D.1 -----
+ 05BE
+ 05C0
+ 05C3
+ 05D0-05EA
+ 05F0-05F4
+ 061B
+ 061F
+ 0621-063A
+ 0640-064A
+ 066D-066F
+ 0671-06D5
+ 06DD
+ 06E5-06E6
+ 06FA-06FE
+ 0700-070D
+ 0710
+ 0712-072C
+ 0780-07A5
+ 07B1
+ 200F
+ FB1D
+ FB1F-FB28
+ FB2A-FB36
+ FB38-FB3C
+ FB3E
+ FB40-FB41
+ FB43-FB44
+ FB46-FBB1
+ FBD3-FD3D
+ FD50-FD8F
+ FD92-FDC7
+ FDF0-FDFC
+ FE70-FE74
+ FE76-FEFC
+ ----- End Table D.1 -----
+
+ ----- Start Table D.2 -----
+ 0041-005A
+ 0061-007A
+ 00AA
+ 00B5
+ 00BA
+ 00C0-00D6
+ 00D8-00F6
+ 00F8-0220
+ 0222-0233
+ 0250-02AD
+ 02B0-02B8
+ 02BB-02C1
+ 02D0-02D1
+ 02E0-02E4
+ 02EE
+ 037A
+ 0386
+ 0388-038A
+ 038C
+ 038E-03A1
+ 03A3-03CE
+ 03D0-03F5
+ 0400-0482
+ 048A-04CE
+ 04D0-04F5
+ 04F8-04F9
+ 0500-050F
+ 0531-0556
+ 0559-055F
+ 0561-0587
+ 0589
+ 0903
+ 0905-0939
+ 093D-0940
+ 0949-094C
+ 0950
+ 0958-0961
+ 0964-0970
+ 0982-0983
+ 0985-098C
+ 098F-0990
+ 0993-09A8
+ 09AA-09B0
+ 09B2
+ 09B6-09B9
+ 09BE-09C0
+ 09C7-09C8
+ 09CB-09CC
+ 09D7
+ 09DC-09DD
+ 09DF-09E1
+ 09E6-09F1
+ 09F4-09FA
+ 0A05-0A0A
+ 0A0F-0A10
+ 0A13-0A28
+ 0A2A-0A30
+ 0A32-0A33
+ 0A35-0A36
+ 0A38-0A39
+ 0A3E-0A40
+ 0A59-0A5C
+ 0A5E
+ 0A66-0A6F
+ 0A72-0A74
+ 0A83
+ 0A85-0A8B
+ 0A8D
+ 0A8F-0A91
+ 0A93-0AA8
+ 0AAA-0AB0
+ 0AB2-0AB3
+ 0AB5-0AB9
+ 0ABD-0AC0
+ 0AC9
+ 0ACB-0ACC
+ 0AD0
+ 0AE0
+ 0AE6-0AEF
+ 0B02-0B03
+ 0B05-0B0C
+ 0B0F-0B10
+ 0B13-0B28
+ 0B2A-0B30
+ 0B32-0B33
+ 0B36-0B39
+ 0B3D-0B3E
+ 0B40
+ 0B47-0B48
+ 0B4B-0B4C
+ 0B57
+ 0B5C-0B5D
+ 0B5F-0B61
+ 0B66-0B70
+ 0B83
+ 0B85-0B8A
+ 0B8E-0B90
+ 0B92-0B95
+ 0B99-0B9A
+ 0B9C
+ 0B9E-0B9F
+ 0BA3-0BA4
+ 0BA8-0BAA
+ 0BAE-0BB5
+ 0BB7-0BB9
+ 0BBE-0BBF
+ 0BC1-0BC2
+ 0BC6-0BC8
+ 0BCA-0BCC
+ 0BD7
+ 0BE7-0BF2
+ 0C01-0C03
+ 0C05-0C0C
+ 0C0E-0C10
+ 0C12-0C28
+ 0C2A-0C33
+ 0C35-0C39
+ 0C41-0C44
+ 0C60-0C61
+ 0C66-0C6F
+ 0C82-0C83
+ 0C85-0C8C
+ 0C8E-0C90
+ 0C92-0CA8
+ 0CAA-0CB3
+ 0CB5-0CB9
+ 0CBE
+ 0CC0-0CC4
+ 0CC7-0CC8
+ 0CCA-0CCB
+ 0CD5-0CD6
+ 0CDE
+ 0CE0-0CE1
+ 0CE6-0CEF
+ 0D02-0D03
+ 0D05-0D0C
+ 0D0E-0D10
+ 0D12-0D28
+ 0D2A-0D39
+ 0D3E-0D40
+ 0D46-0D48
+ 0D4A-0D4C
+ 0D57
+ 0D60-0D61
+ 0D66-0D6F
+ 0D82-0D83
+ 0D85-0D96
+ 0D9A-0DB1
+ 0DB3-0DBB
+ 0DBD
+ 0DC0-0DC6
+ 0DCF-0DD1
+ 0DD8-0DDF
+ 0DF2-0DF4
+ 0E01-0E30
+ 0E32-0E33
+ 0E40-0E46
+ 0E4F-0E5B
+ 0E81-0E82
+ 0E84
+ 0E87-0E88
+ 0E8A
+ 0E8D
+ 0E94-0E97
+ 0E99-0E9F
+ 0EA1-0EA3
+ 0EA5
+ 0EA7
+ 0EAA-0EAB
+ 0EAD-0EB0
+ 0EB2-0EB3
+ 0EBD
+ 0EC0-0EC4
+ 0EC6
+ 0ED0-0ED9
+ 0EDC-0EDD
+ 0F00-0F17
+ 0F1A-0F34
+ 0F36
+ 0F38
+ 0F3E-0F47
+ 0F49-0F6A
+ 0F7F
+ 0F85
+ 0F88-0F8B
+ 0FBE-0FC5
+ 0FC7-0FCC
+ 0FCF
+ 1000-1021
+ 1023-1027
+ 1029-102A
+ 102C
+ 1031
+ 1038
+ 1040-1057
+ 10A0-10C5
+ 10D0-10F8
+ 10FB
+ 1100-1159
+ 115F-11A2
+ 11A8-11F9
+ 1200-1206
+ 1208-1246
+ 1248
+ 124A-124D
+ 1250-1256
+ 1258
+ 125A-125D
+ 1260-1286
+ 1288
+ 128A-128D
+ 1290-12AE
+ 12B0
+ 12B2-12B5
+ 12B8-12BE
+ 12C0
+ 12C2-12C5
+ 12C8-12CE
+ 12D0-12D6
+ 12D8-12EE
+ 12F0-130E
+ 1310
+ 1312-1315
+ 1318-131E
+ 1320-1346
+ 1348-135A
+ 1361-137C
+ 13A0-13F4
+ 1401-1676
+ 1681-169A
+ 16A0-16F0
+ 1700-170C
+ 170E-1711
+ 1720-1731
+ 1735-1736
+ 1740-1751
+ 1760-176C
+ 176E-1770
+ 1780-17B6
+ 17BE-17C5
+ 17C7-17C8
+ 17D4-17DA
+ 17DC
+ 17E0-17E9
+ 1810-1819
+ 1820-1877
+ 1880-18A8
+ 1E00-1E9B
+ 1EA0-1EF9
+ 1F00-1F15
+ 1F18-1F1D
+ 1F20-1F45
+ 1F48-1F4D
+ 1F50-1F57
+ 1F59
+ 1F5B
+ 1F5D
+ 1F5F-1F7D
+ 1F80-1FB4
+ 1FB6-1FBC
+ 1FBE
+ 1FC2-1FC4
+ 1FC6-1FCC
+ 1FD0-1FD3
+ 1FD6-1FDB
+ 1FE0-1FEC
+ 1FF2-1FF4
+ 1FF6-1FFC
+ 200E
+ 2071
+ 207F
+ 2102
+ 2107
+ 210A-2113
+ 2115
+ 2119-211D
+ 2124
+ 2126
+ 2128
+ 212A-212D
+ 212F-2131
+ 2133-2139
+ 213D-213F
+ 2145-2149
+ 2160-2183
+ 2336-237A
+ 2395
+ 249C-24E9
+ 3005-3007
+ 3021-3029
+ 3031-3035
+ 3038-303C
+ 3041-3096
+ 309D-309F
+ 30A1-30FA
+ 30FC-30FF
+ 3105-312C
+ 3131-318E
+ 3190-31B7
+ 31F0-321C
+ 3220-3243
+ 3260-327B
+ 327F-32B0
+ 32C0-32CB
+ 32D0-32FE
+ 3300-3376
+ 337B-33DD
+ 33E0-33FE
+ 3400-4DB5
+ 4E00-9FA5
+ A000-A48C
+ AC00-D7A3
+ D800-FA2D
+ FA30-FA6A
+ FB00-FB06
+ FB13-FB17
+ FF21-FF3A
+ FF41-FF5A
+ FF66-FFBE
+ FFC2-FFC7
+ FFCA-FFCF
+ FFD2-FFD7
+ FFDA-FFDC
+ 10300-1031E
+ 10320-10323
+ 10330-1034A
+ 10400-10425
+ 10428-1044D
+ 1D000-1D0F5
+ 1D100-1D126
+ 1D12A-1D166
+ 1D16A-1D172
+ 1D183-1D184
+ 1D18C-1D1A9
+ 1D1AE-1D1DD
+ 1D400-1D454
+ 1D456-1D49C
+ 1D49E-1D49F
+ 1D4A2
+ 1D4A5-1D4A6
+ 1D4A9-1D4AC
+ 1D4AE-1D4B9
+ 1D4BB
+ 1D4BD-1D4C0
+ 1D4C2-1D4C3
+ 1D4C5-1D505
+ 1D507-1D50A
+ 1D50D-1D514
+ 1D516-1D51C
+ 1D51E-1D539
+ 1D53B-1D53E
+ 1D540-1D544
+ 1D546
+ 1D54A-1D550
+ 1D552-1D6A3
+ 1D6A8-1D7C9
+ 20000-2A6D6
+ 2F800-2FA1D
+ F0000-FFFFD
+ 100000-10FFFD
+ ----- End Table D.2 -----
diff --git a/gen/.gitignore b/gen/.gitignore
new file mode 100644
index 0000000..33641a1
--- /dev/null
+++ b/gen/.gitignore
@@ -0,0 +1,2 @@
+/srcgen-cset
+/srcgen-maps
diff --git a/gen/Makefile.am b/gen/Makefile.am
new file mode 100644
index 0000000..4564ec1
--- /dev/null
+++ b/gen/Makefile.am
@@ -0,0 +1,29 @@
+# bin_PROGRAMS = preppie-gen
+
+noinst_LTLIBRARIES = libpreppiegen.la
+
+libpreppiegen_la_SOURCES = \
+ cset.c \
+ cset.h \
+ map.c \
+ map.h \
+ mapping-rep.c \
+ mapping-rep.h \
+ parser.c \
+ parser.h
+
+libpreppiegen_la_LIBADD = $(GLIB_LIBS)
+
+noinst_PROGRAMS = srcgen-cset srcgen-maps
+
+srcgen_cset_SOURCES = srcgen-cset.c
+
+srcgen_cset_LDADD = $(GLIB_LIBS) libpreppiegen.la
+
+srcgen_maps_SOURCES = srcgen-maps.c
+
+srcgen_maps_LDADD = $(GLIB_LIBS) libpreppiegen.la
+
+AM_CPPFLAGS = $(GLIB_CFLAGS) -I$(top_srcdir)
+
+# preppie_gen_LDADD = libpreppiegen.la
diff --git a/gen/cset.c b/gen/cset.c
new file mode 100644
index 0000000..3635774
--- /dev/null
+++ b/gen/cset.c
@@ -0,0 +1,238 @@
+/*
+ * This file is part of preppie.
+ *
+ * Copyright (C) 2010 Mikhail Zabaluev <mikhail.zabaluev@gmail.com>
+ *
+ * This work is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This work 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this work; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#include "cset.h"
+
+
+static void sprep_gen_cset_page_set_range (SprepGenCsetPage *page,
+ guint index_first,
+ guint index_last);
+
+static void sprep_gen_cset_page_set_full (SprepGenCsetPage *page);
+
+static guint32 * sprep_gen_cset_page_ensure_bitset (SprepGenCsetPage *page);
+
+
+#define sprep_gen_cset_bitset_new() \
+ (g_slice_alloc0 (sizeof(guint32) * SPREP_CSET_BITSET_SIZE))
+
+#define sprep_gen_cset_bitset_free(bitset) \
+ g_slice_free1 (sizeof(guint32) * SPREP_CSET_BITSET_SIZE, bitset)
+
+
+SprepGenCset *
+sprep_gen_cset_new ()
+{
+ return g_new0 (SprepGenCset, 1);
+}
+
+void
+sprep_gen_cset_destroy (SprepGenCset *cset)
+{
+ int i;
+
+ for (i = 0; i < SPREP_PAGE_TABLE_SIZE; i++) {
+ guint32 *bitset = cset->pages[i].bitset;
+ if (bitset != NULL) {
+ sprep_gen_cset_bitset_free (bitset);
+ }
+ }
+
+ g_free (cset);
+}
+
+void
+sprep_gen_cset_add (SprepGenCset *cset, gunichar c)
+{
+ SprepGenCsetPage *page;
+ guint32 *bitset;
+ guint bitset_index;
+
+ g_return_if_fail (c <= SPREP_UNICHAR_MAX);
+
+ page = &cset->pages[c >> SPREP_PAGE_SIZE_SHIFT];
+
+ if ((page->flags & SPREP_CSET_PAGE_FULL) != 0) {
+ return;
+ }
+
+ bitset = sprep_gen_cset_page_ensure_bitset (page);
+
+ bitset_index = (c & SPREP_PAGE_INDEX_MASK) >> 5;
+
+ bitset[bitset_index] |= 1 << (c & 0x1f);
+}
+
+void
+sprep_gen_cset_add_range (SprepGenCset *cset, gunichar first, gunichar last)
+{
+ SprepGenCsetPage *page;
+ guint page_first;
+ guint i;
+
+ g_return_if_fail (first <= SPREP_UNICHAR_MAX);
+ g_return_if_fail (last <= SPREP_UNICHAR_MAX);
+ g_return_if_fail (first <= last);
+
+ i = first;
+ page = &cset->pages[first >> SPREP_PAGE_SIZE_SHIFT];
+
+ page_first = first & SPREP_PAGE_INDEX_MASK;
+ if (page_first != 0) {
+ guint page_last = MIN(first | SPREP_PAGE_INDEX_MASK, last)
+ & SPREP_PAGE_INDEX_MASK;
+ sprep_gen_cset_page_set_range (
+ page,
+ page_first,
+ page_last);
+ i += SPREP_PAGE_SIZE - page_first;
+ ++page;
+ }
+
+ while (i + SPREP_PAGE_INDEX_LAST <= last) {
+ sprep_gen_cset_page_set_full (page);
+ i += SPREP_PAGE_SIZE;
+ ++page;
+ }
+
+ if (i <= last) {
+ sprep_gen_cset_page_set_range (
+ page,
+ i & SPREP_PAGE_INDEX_MASK,
+ last & SPREP_PAGE_INDEX_MASK);
+ }
+}
+
+static void
+sprep_gen_cset_page_set_range (SprepGenCsetPage *page,
+ guint index_first,
+ guint index_last)
+{
+ guint32 *bitset;
+ guint32 *pb;
+ guint shift_first;
+ guint i;
+
+ if ((page->flags & SPREP_CSET_PAGE_FULL) != 0) {
+ return;
+ }
+
+ bitset = sprep_gen_cset_page_ensure_bitset (page);
+
+ pb = bitset + (index_first >> 5);
+
+ i = index_first;
+
+ /* set bits in the first incomplete word, if any */
+ shift_first = index_first & 0x1f;
+ if (shift_first != 0) {
+ guint index_stop = MIN(index_first | 0x1f, index_last);
+ guint32 acc = 0;
+ guint32 bit = 1 << shift_first;
+
+ do {
+ acc |= bit;
+ bit <<= 1;
+ ++i;
+ } while (i <= index_stop);
+
+ *pb++ |= acc;
+ }
+
+ /* fill all complete words in the range */
+ while (i + 0x1f <= index_last) {
+ *pb++ = 0xffffffff;
+ i += 0x20;
+ }
+
+ /* set bits in the last incomplete word, if any */
+ if (i <= index_last) {
+ guint32 acc = 0;
+ guint32 bit = 1;
+
+ do {
+ acc |= bit;
+ bit <<= 1;
+ ++i;
+ } while (i <= index_last);
+
+ *pb |= acc;
+ }
+}
+
+static void
+sprep_gen_cset_page_set_full (SprepGenCsetPage *page)
+{
+ page->flags |= SPREP_CSET_PAGE_FULL;
+ page->offset = 0;
+ if (page->bitset != NULL) {
+ sprep_gen_cset_bitset_free (page->bitset);
+ page->bitset = NULL;
+ }
+}
+
+static guint32 *
+sprep_gen_cset_page_ensure_bitset (SprepGenCsetPage *page)
+{
+ guint32 *bitset = page->bitset;
+ if (bitset == NULL) {
+ bitset = sprep_gen_cset_bitset_new();
+ page->bitset = bitset;
+ }
+ return bitset;
+}
+
+gsize
+sprep_gen_cset_prepare_layout (SprepGenCset *cset)
+{
+ guint next_offset = SPREP_PAGE_TABLE_SIZE;
+ int ip;
+
+ for (ip = 0; ip < SPREP_PAGE_TABLE_SIZE; ip++) {
+ SprepGenCsetPage *page = &cset->pages[ip];
+
+ if (page->bitset != NULL) {
+ gboolean found_hole = FALSE;
+ int iw;
+
+ /* Check if the bitset is full
+ * so we can compress the pag. */
+ for (iw = 0; iw < SPREP_CSET_BITSET_SIZE; iw++) {
+ if (page->bitset[iw] != 0xffffffff) {
+ found_hole = TRUE;
+ break;
+ }
+ }
+
+ if (found_hole) {
+ /* Need to allocate the bitset */
+ page->offset = next_offset;
+ next_offset += SPREP_CSET_BITSET_SIZE;
+ } else {
+ /* Can mark the page full
+ * and remove the bitset */
+ sprep_gen_cset_page_set_full (page);
+ }
+ }
+ }
+
+ return next_offset;
+}
diff --git a/gen/cset.h b/gen/cset.h
new file mode 100644
index 0000000..3a6f492
--- /dev/null
+++ b/gen/cset.h
@@ -0,0 +1,56 @@
+/*
+ * This file is part of preppie.
+ *
+ * Copyright (C) 2010 Mikhail Zabaluev <mikhail.zabaluev@gmail.com>
+ *
+ * This work is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This work 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this work; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#ifndef _PREPPIE_GEN_CSET_H_
+#define _PREPPIE_GEN_CSET_H_
+
+#include <glib.h>
+#include <preppie/profile-format.h>
+
+G_BEGIN_DECLS
+
+
+typedef struct _SprepGenCset SprepGenCset;
+typedef struct _SprepGenCsetPage SprepGenCsetPage;
+
+struct _SprepGenCsetPage {
+ guint flags;
+ guint offset;
+ guint32 *bitset;
+};
+
+struct _SprepGenCset {
+ SprepGenCsetPage pages[SPREP_PAGE_TABLE_SIZE];
+};
+
+SprepGenCset *sprep_gen_cset_new ();
+void sprep_gen_cset_destroy (SprepGenCset *cset);
+void sprep_gen_cset_add (SprepGenCset *cset, gunichar c);
+void sprep_gen_cset_add_range (SprepGenCset *cset,
+ gunichar first_char,
+ gunichar last_char);
+gsize sprep_gen_cset_prepare_layout (SprepGenCset *cset);
+
+
+G_END_DECLS
+
+
+#endif /* !_PREPPIE_GEN_CSET_H_ */
diff --git a/gen/map.c b/gen/map.c
new file mode 100644
index 0000000..bc871f3
--- /dev/null
+++ b/gen/map.c
@@ -0,0 +1,90 @@
+/*
+ * This file is part of preppie.
+ *
+ * Copyright (C) 2010 Mikhail Zabaluev <mikhail.zabaluev@gmail.com>
+ *
+ * This work is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This work 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this work; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#include "map.h"
+
+
+SprepGenMap *
+sprep_gen_map_new ()
+{
+ return g_new0 (SprepGenMap, 1);
+}
+
+void
+sprep_gen_map_destroy (SprepGenMap *map)
+{
+ int i;
+
+ for (i = 0; i < SPREP_PAGE_TABLE_SIZE; i++) {
+ const SprepGenMapping **mappings = map->pages[i].mappings;
+ if (mappings != NULL) {
+ g_free (mappings);
+ }
+ }
+
+ g_free (map);
+}
+
+void
+sprep_gen_map_add (SprepGenMap *map,
+ gunichar key,
+ const SprepGenMapping *value)
+{
+ const SprepGenMapping **mappings;
+ guint ptable_index;
+ guint mapping_index;
+
+ g_return_if_fail (key <= SPREP_UNICHAR_MAX);
+
+ ptable_index = key >> SPREP_PAGE_SIZE_SHIFT;
+
+ mappings = map->pages[ptable_index].mappings;
+
+ if (mappings == NULL) {
+ mappings = g_new0 (const SprepGenMapping *, SPREP_PAGE_SIZE);
+ map->pages[ptable_index].mappings = mappings;
+ }
+
+ mapping_index = key & SPREP_PAGE_INDEX_MASK;
+
+ if (G_UNLIKELY (mappings[mapping_index] != NULL
+ && mappings[mapping_index] != value)) {
+ g_warning ("remapping for character <U+%04X>", (guint) key);
+ }
+
+ mappings[mapping_index] = value;
+}
+
+gsize
+sprep_gen_map_prepare_layout (SprepGenMap *map)
+{
+ guint next_offset = SPREP_PAGE_TABLE_SIZE;
+ int i;
+
+ for (i = 0; i < SPREP_PAGE_TABLE_SIZE; i++) {
+ if (map->pages[i].mappings != NULL) {
+ map->pages[i].offset = next_offset;
+ next_offset += SPREP_PAGE_SIZE;
+ }
+ }
+
+ return next_offset;
+}
diff --git a/gen/map.h b/gen/map.h
new file mode 100644
index 0000000..9ce72e4
--- /dev/null
+++ b/gen/map.h
@@ -0,0 +1,54 @@
+/*
+ * This file is part of preppie.
+ *
+ * Copyright (C) 2010 Mikhail Zabaluev <mikhail.zabaluev@gmail.com>
+ *
+ * This work is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This work 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this work; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#ifndef _PREPPIE_GEN_MAP_H_
+#define _PREPPIE_GEN_MAP_H_
+
+#include <glib.h>
+#include <preppie/profile-format.h>
+#include "mapping-rep.h"
+
+G_BEGIN_DECLS
+
+
+typedef struct _SprepGenMap SprepGenMap;
+typedef struct _SprepGenMapPage SprepGenMapPage;
+
+struct _SprepGenMapPage {
+ const SprepGenMapping **mappings;
+ guint offset;
+};
+
+struct _SprepGenMap {
+ SprepGenMapPage pages[SPREP_PAGE_TABLE_SIZE];
+};
+
+SprepGenMap * sprep_gen_map_new ();
+void sprep_gen_map_destroy (SprepGenMap *map);
+void sprep_gen_map_add (SprepGenMap *map,
+ gunichar key,
+ const SprepGenMapping *value);
+gsize sprep_gen_map_prepare_layout (SprepGenMap *map);
+
+
+G_END_DECLS
+
+#endif /* _PREPPIE_GEN_MAP_H_ */
diff --git a/gen/mapping-rep.c b/gen/mapping-rep.c
new file mode 100644
index 0000000..14af986
--- /dev/null
+++ b/gen/mapping-rep.c
@@ -0,0 +1,406 @@
+/*
+ * This file is part of preppie.
+ *
+ * Copyright (C) 2010 Mikhail Zabaluev <mikhail.zabaluev@gmail.com>
+ *
+ * This work is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This work 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this work; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#include "mapping-rep.h"
+
+#include <string.h>
+
+typedef struct _SprepGenMappingKey SprepGenMappingKey;
+
+struct _SprepGenMappingKey {
+ gunichar *chars;
+ guint length;
+};
+
+static SprepGenMapping *sprep_gen_mapping_new (const gunichar *chars,
+ guint length,
+ const SprepGenMapping *substring_of,
+ guint substring_index);
+static gboolean sprep_gen_mapping_free_key_val (gpointer key, gpointer val,
+ gpointer user_data);
+static gint sprep_gen_compare_mappings (gconstpointer p1, gconstpointer p2);
+
+
+static const SprepGenMapping map_to_nothing = { 0, "", };
+
+
+SprepGenMappingRep *
+sprep_gen_mapping_rep_new ()
+{
+ return g_new0(SprepGenMappingRep, 1);
+}
+
+static void
+sprep_gen_mapping_rep_free_page (SprepGenMappingRepPage page)
+{
+ GTree **buckets = page;
+ int i;
+
+ for (i = 0; i < SPREP_GEN_REP_PAGE_SIZE; i++) {
+ GTree *bucket = buckets[i];
+ if (bucket != NULL) {
+ g_tree_foreach (bucket,
+ sprep_gen_mapping_free_key_val, NULL);
+ g_tree_destroy (bucket);
+ }
+ }
+}
+
+void
+sprep_gen_mapping_rep_destroy (SprepGenMappingRep *rep)
+{
+ int i;
+
+ for (i = 0; i < SPREP_GEN_REP_PAGE_TABLE_SIZE; i++) {
+ SprepGenMappingRepPage page = rep->pages[i];
+ if (page != NULL) {
+ sprep_gen_mapping_rep_free_page (page);
+ }
+ }
+
+ g_free (rep);
+}
+
+static gboolean
+sprep_allowed_submapping (const SprepGenMapping *mapping,
+ const SprepGenMapping *super)
+{
+ if (mapping->length == 1
+ && (guchar) mapping->chars[0] < 128
+ && (guchar) super->chars[0] >= 128) {
+ /* ASCII characters are grandfathered to not be absorbed
+ * into superstrings sorted too far away, for better cache
+ * locality of the vast majority of real-world lookups */
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static SprepGenMapping *
+sprep_gen_mapping_rep_add_internal (SprepGenMappingRep *rep,
+ gunichar *chars,
+ guint length,
+ const SprepGenMapping *substring_of,
+ guint substring_index,
+ gunichar **key_chars)
+{
+ SprepGenMappingKey search_key;
+ SprepGenMappingKey *key;
+ SprepGenMapping *mapping;
+ SprepGenMappingRepPage page;
+ GTree *bucket;
+ guint ptable_index;
+ guint page_index;
+
+ ptable_index = chars[0] >> SPREP_GEN_REP_PAGE_SIZE_SHIFT;
+
+ page = rep->pages[ptable_index];
+ if (page == NULL) {
+ page = g_new0 (GTree *, SPREP_GEN_REP_PAGE_SIZE);
+ rep->pages[ptable_index] = page;
+ }
+
+ page_index = chars[0] & SPREP_GEN_REP_PAGE_INDEX_MASK;
+ bucket = page[page_index];
+ if (bucket == NULL) {
+ /* NOTE: we never replace entries in the tree,
+ * so we can get away without the destroy functions */
+ bucket = g_tree_new (sprep_gen_compare_mappings);
+ page[page_index] = bucket;
+ }
+
+ search_key.chars = chars;
+ search_key.length = length;
+
+ /* Look up if the mapping already exists */
+ if (!g_tree_lookup_extended (bucket, &search_key,
+ (gpointer *) &key, (gpointer *) &mapping)) {
+ /* No entry yet, create it */
+ mapping = sprep_gen_mapping_new (chars, length,
+ substring_of, substring_index);
+
+ g_return_val_if_fail (mapping != NULL, NULL);
+
+ key = g_slice_new (SprepGenMappingKey);
+ key->length = length;
+ key->chars = (substring_of == NULL)
+ ? g_slice_copy (length * sizeof (gunichar),
+ chars)
+ : chars;
+
+ g_tree_insert (bucket, key, mapping);
+ } else if (substring_of == NULL) {
+ /* The mapping already exists,
+ * but we have no superstring to optimize it further. */
+ } else if (!sprep_allowed_submapping (mapping, substring_of)) {
+ /* U can't touch this. */
+ } else if (mapping->substring_of == NULL
+ || mapping->substring_of->length < substring_of->length) {
+ /* Return the existing entry, but optimize it as a substring.
+ * NOTE: The order in which substrings are added and
+ * the condition above make sure that no shorter mappings
+ * point to this one, so it is OK to change the
+ * string pointers. */
+ gchar *substr_begin = g_utf8_offset_to_pointer (
+ substring_of->chars,
+ substring_index);
+ g_assert (strncmp (substr_begin, mapping->chars, mapping->length) == 0);
+ if (mapping->substring_of == NULL) {
+ g_slice_free1 (key->length * sizeof (gunichar),
+ key->chars);
+ g_free (mapping->chars);
+ }
+ mapping->chars = substr_begin;
+ mapping->substring_of = substring_of;
+ mapping->substring_index = substr_begin - substring_of->chars;
+
+ key->chars = chars;
+ } else {
+ /* The mapping already exists as a substring
+ * and its superstring isn't any less favorable than ours. */
+ }
+
+ if (key_chars != NULL) {
+ *key_chars = key->chars;
+ }
+
+ return mapping;
+}
+
+const SprepGenMapping *
+sprep_gen_mapping_rep_add (SprepGenMappingRep *rep,
+ const gunichar *chars,
+ guint length)
+{
+ SprepGenMapping *mapping;
+ gunichar *key_chars;
+ guint sub_length;
+
+ if (length == 0) {
+ return &map_to_nothing;
+ }
+
+ mapping = sprep_gen_mapping_rep_add_internal (rep, (gunichar *) chars,
+ length, NULL, 0, &key_chars);
+
+ mapping->in_use = TRUE;
+
+ /* Add all substrings.
+ * It's important to the implementation that shorter substrings
+ * are added first. */
+ sub_length = 1;
+ while (sub_length < length) {
+ int i = 0;
+ do {
+ sprep_gen_mapping_rep_add_internal (rep, key_chars + i,
+ sub_length, mapping, i, NULL);
+ ++i;
+ } while (i + sub_length <= length);
+ ++sub_length;
+ }
+
+ return mapping;
+}
+
+static gboolean
+sprep_gen_mapping_base_layout_traverse (gpointer key,
+ gpointer value,
+ gpointer user_data)
+{
+ SprepGenMapping *mapping = (SprepGenMapping *) value;
+ if (mapping->substring_of != NULL) {
+ return FALSE;
+ }
+ if (mapping->length == 0) {
+ mapping->offset = 0;
+ } else {
+ gsize *offset = (gsize *) user_data;
+ mapping->offset = *offset;
+ *offset = mapping->offset + mapping->length;
+ }
+ return FALSE;
+}
+
+static gboolean
+sprep_gen_mapping_subs_layout_traverse (gpointer key,
+ gpointer value,
+ gpointer user_data)
+{
+ SprepGenMapping *mapping = (SprepGenMapping *) value;
+ const SprepGenMapping *super = mapping->substring_of;
+ if (super != NULL) {
+ g_assert (super->substring_of == NULL);
+ mapping->offset = super->offset + mapping->substring_index;
+ }
+ return FALSE;
+}
+
+static void
+sprep_gen_mapping_rep_prepare_page_base_layout (SprepGenMappingRepPage page,
+ gsize *offset)
+{
+ GTree **buckets = page;
+ int i;
+
+ for (i = 0; i < SPREP_GEN_REP_PAGE_SIZE; i++) {
+ GTree *bucket = buckets[i];
+ if (bucket != NULL) {
+ g_tree_foreach (bucket,
+ sprep_gen_mapping_base_layout_traverse,
+ offset);
+ }
+ }
+}
+
+static void
+sprep_gen_mapping_rep_prepare_page_subs_layout (SprepGenMappingRepPage page)
+{
+ GTree **buckets = page;
+ int i;
+
+ for (i = 0; i < SPREP_GEN_REP_PAGE_SIZE; i++) {
+ GTree *bucket = buckets[i];
+ if (bucket != NULL) {
+ g_tree_foreach (bucket,
+ sprep_gen_mapping_subs_layout_traverse,
+ NULL);
+ }
+ }
+}
+
+gsize
+sprep_gen_mapping_rep_prepare_layout (SprepGenMappingRep *rep)
+{
+ gsize offset = 0;
+ int i;
+
+ for (i = 0; i < SPREP_GEN_REP_PAGE_TABLE_SIZE; i++) {
+ SprepGenMappingRepPage page = rep->pages[i];
+ if (page != NULL) {
+ sprep_gen_mapping_rep_prepare_page_base_layout (
+ page, &offset);
+ }
+ }
+
+ for (i = 0; i < SPREP_GEN_REP_PAGE_TABLE_SIZE; i++) {
+ SprepGenMappingRepPage page = rep->pages[i];
+ if (page != NULL) {
+ sprep_gen_mapping_rep_prepare_page_subs_layout (
+ page);
+ }
+ }
+
+ return offset;
+}
+
+static SprepGenMapping *
+sprep_gen_mapping_new (const gunichar *chars, guint length,
+ const SprepGenMapping *substring_of, guint substring_index)
+{
+ SprepGenMapping *mapping = g_slice_new (SprepGenMapping);
+
+ if (substring_of == NULL) {
+ glong length_utf8;
+ GError *error;
+
+ mapping->chars = g_ucs4_to_utf8 (chars,
+ length,
+ NULL,
+ &length_utf8,
+ &error);
+ if (G_UNLIKELY (mapping->chars == NULL)) {
+ g_critical ("conversion to UTF-8 failed: %s",
+ error->message);
+ g_error_free (error);
+ g_slice_free (SprepGenMapping, mapping);
+ return NULL;
+ }
+ g_assert (length_utf8 > 0);
+ mapping->length = length_utf8;
+ mapping->substring_of = NULL;
+ } else {
+ /* Locate the corresponding UTF-8 substring in another mapping */
+ gchar *substr_begin = g_utf8_offset_to_pointer (
+ substring_of->chars, substring_index);
+ gchar *substr_end = g_utf8_offset_to_pointer (
+ substr_begin, length);
+ mapping->chars = substr_begin;
+ mapping->length = substr_end - substr_begin;
+ mapping->substring_of = substring_of;
+ mapping->substring_index = substr_begin - substring_of->chars;
+ }
+
+ mapping->in_use = FALSE;
+
+ return mapping;
+}
+
+static gboolean
+sprep_gen_mapping_free_key_val (gpointer k, gpointer v, gpointer user_data)
+{
+ SprepGenMappingKey *key = k;
+ SprepGenMapping *mapping = v;
+ if (mapping->substring_of == NULL) {
+ g_slice_free1 (key->length * sizeof (gunichar), key->chars);
+ g_free (mapping->chars);
+ }
+ g_slice_free (SprepGenMappingKey, key);
+ g_slice_free (SprepGenMapping, mapping);
+
+ return FALSE;
+}
+
+static gint
+sprep_gen_compare_prefixes (const gunichar *s1, const gunichar *s2, gsize len)
+{
+ gsize i;
+
+ /* All mappings in one bucket must have the same first character */
+ g_assert (s1[0] == s2[0]);
+
+ for (i = 1; i != len; ++i) {
+ gint diff = (gint) s1[i] - (gint) s2[i];
+ if (diff != 0)
+ return diff;
+ }
+
+ return 0;
+}
+
+static gint
+sprep_gen_compare_mappings (gconstpointer p1, gconstpointer p2)
+{
+ const SprepGenMappingKey *key1 = p1;
+ const SprepGenMappingKey *key2 = p2;
+
+ if (key1->length == key2->length) {
+ return sprep_gen_compare_prefixes (key1->chars, key2->chars,
+ key1->length);
+ } else if (key1->length < key2->length) {
+ int res = sprep_gen_compare_prefixes (key1->chars, key2->chars,
+ key1->length);
+ return (res != 0)? res : -1;
+ } else /* if (key1->length > key2->length) */ {
+ int res = sprep_gen_compare_prefixes (key1->chars, key2->chars,
+ key2->length);
+ return (res != 0)? res : 1;
+ }
+}
diff --git a/gen/mapping-rep.h b/gen/mapping-rep.h
new file mode 100644
index 0000000..59ee393
--- /dev/null
+++ b/gen/mapping-rep.h
@@ -0,0 +1,68 @@
+/*
+ * This file is part of preppie.
+ *
+ * Copyright (C) 2010 Mikhail Zabaluev <mikhail.zabaluev@gmail.com>
+ *
+ * This work is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This work 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this work; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#ifndef _PREPPIE_GEN_REPERTOIRE_H_
+#define _PREPPIE_GEN_REPERTOIRE_H_
+
+
+#include <glib.h>
+#include <preppie/profile-format.h>
+
+
+G_BEGIN_DECLS
+
+typedef struct _SprepGenMapping SprepGenMapping;
+
+struct _SprepGenMapping {
+ guint length; /* length in bytes */
+ gchar *chars; /* characters of the mapping */
+ gsize offset; /* file offset assigned */
+ const SprepGenMapping *substring_of;
+ /* if non-null, a mapping containing
+ * the characters in a larger string */
+ guint substring_index; /* index of the mapping characters
+ * in the containing mapping */
+ gboolean in_use;
+};
+
+#define SPREP_GEN_REP_PAGE_SIZE_SHIFT 7
+#define SPREP_GEN_REP_PAGE_TABLE_SIZE \
+ ((SPREP_UNICHAR_MAX + 1) >> SPREP_GEN_REP_PAGE_SIZE_SHIFT)
+#define SPREP_GEN_REP_PAGE_SIZE (1 << SPREP_GEN_REP_PAGE_SIZE_SHIFT)
+#define SPREP_GEN_REP_PAGE_INDEX_MASK (SPREP_GEN_REP_PAGE_SIZE - 1)
+
+typedef GTree **SprepGenMappingRepPage;
+
+typedef struct _SprepGenMappingRep {
+ SprepGenMappingRepPage pages[SPREP_GEN_REP_PAGE_TABLE_SIZE];
+} SprepGenMappingRep;
+
+SprepGenMappingRep * sprep_gen_mapping_rep_new ();
+void sprep_gen_mapping_rep_destroy (SprepGenMappingRep *rep);
+const SprepGenMapping * sprep_gen_mapping_rep_add (SprepGenMappingRep *rep,
+ const gunichar *mapping,
+ guint length);
+gsize sprep_gen_mapping_rep_prepare_layout (SprepGenMappingRep *rep);
+
+
+G_END_DECLS
+
+#endif /* _PREPPIE_GEN_REPERTOIRE_H_ */
diff --git a/gen/parser.c b/gen/parser.c
new file mode 100644
index 0000000..f52920d
--- /dev/null
+++ b/gen/parser.c
@@ -0,0 +1,271 @@
+/*
+ * This file is part of preppie.
+ *
+ * Copyright (C) 2010 Mikhail Zabaluev <mikhail.zabaluev@gmail.com>
+ *
+ * This work is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This work 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this work; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#include "parser.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#define SPREP_PARSE_LINE_MAX 256
+
+
+GQuark
+sprep_gen_parse_error_quark (void)
+{
+ static GQuark quark = 0;
+
+ if (G_UNLIKELY (quark == 0)) {
+ quark = g_quark_from_static_string ("sprep-gen-parse-error");
+ }
+ return quark;
+}
+
+static void
+sprep_gen_report_parse_error (const gchar *filename, gint lineno,
+ const gchar *message)
+{
+ g_printerr ("%s:%d: error: %s\n", filename, lineno, message);
+}
+
+static void
+sprep_gen_report_input_error (const gchar *filename)
+{
+ int err_code = errno;
+ if (err_code) {
+ g_printerr ("error reading file '%s': %s\n",
+ filename, g_strerror (err_code));
+ } else {
+ g_printerr ("error reading file '%s'\n", filename);
+ }
+}
+
+static gunichar
+sprep_gen_parse_character_code (const gchar *pos, gchar **endptr, GError **error)
+{
+ guint64 code_token;
+ code_token = g_ascii_strtoull (pos, endptr, 16);
+ if (*endptr == pos) {
+ while (g_ascii_isspace (*pos)) {
+ ++pos;
+ }
+ switch (*pos) {
+ case '\0':
+ case '\n':
+ case '\r':
+ case ';':
+ return 0;
+ default:
+ g_set_error (error, SPREP_GEN_PARSE_ERRORS,
+ SPREP_PARSE_ERROR_SYNTAX,
+ "character code expected");
+ return 0;
+ }
+ }
+
+ if (code_token > SPREP_UNICHAR_MAX) {
+ g_set_error (error, SPREP_GEN_PARSE_ERRORS,
+ SPREP_PARSE_ERROR_CODE_OUT_OF_RANGE,
+ "character code %" G_GINT64_MODIFIER "X"
+ " is out of Unicode range",
+ code_token);
+ return 0;
+ }
+ return (gunichar) code_token;
+}
+
+gboolean
+sprep_gen_parse_set (const char *filename, SprepGenCset *set)
+{
+ gboolean res = FALSE;
+ FILE *file;
+ gint lineno = 0;
+ char *linebuf = NULL;
+ GError *error = NULL;
+
+ file = fopen (filename, "r");
+ if (file == NULL) {
+ sprep_gen_report_input_error (filename);
+ return FALSE;
+ }
+
+ linebuf = g_malloc (SPREP_PARSE_LINE_MAX);
+
+ while (fgets (linebuf, SPREP_PARSE_LINE_MAX, file) != NULL) {
+ const gchar* pos;
+ gchar* endptr;
+ gunichar first;
+ gunichar last;
+
+ ++lineno;
+ pos = linebuf;
+ first = sprep_gen_parse_character_code (pos, &endptr, &error);
+ if (error != NULL) {
+ sprep_gen_report_parse_error (filename, lineno,
+ error->message);
+ goto end;
+ }
+ if (endptr == pos) {
+ /* an empty line or a comment */
+ continue;
+ }
+ pos = endptr;
+ switch (*pos) {
+ case '\0':
+ case '\n':
+ case '\r':
+ case ';':
+ sprep_gen_cset_add (set, first);
+ break;
+ case '-':
+ ++pos;
+ last = sprep_gen_parse_character_code (pos, &endptr, &error);
+ if (error != NULL) {
+ sprep_gen_report_parse_error (filename, lineno,
+ error->message);
+ goto end;
+ }
+ if (endptr == pos) {
+ sprep_gen_report_parse_error (filename, lineno,
+ "end code for a character"
+ " range expected");
+ goto end;
+ }
+ sprep_gen_cset_add_range (set, first, last);
+ break;
+ default:
+ sprep_gen_report_parse_error (filename, lineno,
+ "unexpected text after character code");
+ }
+ }
+ if (ferror (file)) {
+ sprep_gen_report_input_error (filename);
+ goto end;
+ }
+ g_assert (feof (file));
+ res = TRUE;
+
+end:
+ if (file != NULL) {
+ fclose (file);
+ }
+ if (error != NULL) {
+ g_error_free (error);
+ }
+ g_free (linebuf);
+ return res;
+}
+
+gboolean
+sprep_gen_parse_map (const char *filename,
+ SprepGenMap *map,
+ SprepGenMappingRep *rep)
+{
+ gboolean res = FALSE;
+ FILE *file;
+ gint lineno = 0;
+ char *linebuf = NULL;
+ GArray *unichar_buf = NULL;
+ GError *error = NULL;
+
+ file = fopen (filename, "r");
+ if (file == NULL) {
+ sprep_gen_report_input_error (filename);
+ goto end;
+ }
+
+ linebuf = g_malloc (SPREP_PARSE_LINE_MAX);
+
+ unichar_buf = g_array_new (FALSE, FALSE, sizeof (gunichar));
+
+ while (fgets (linebuf, SPREP_PARSE_LINE_MAX, file) != NULL) {
+ const gchar* pos;
+ gchar* endptr;
+ gunichar key;
+ const SprepGenMapping *mapping;
+
+ ++lineno;
+ pos = linebuf;
+ key = sprep_gen_parse_character_code (pos, &endptr, &error);
+ if (error != NULL) {
+ sprep_gen_report_parse_error (filename, lineno,
+ error->message);
+ goto end;
+ }
+ if (endptr == pos) {
+ /* an empty line or a comment */
+ continue;
+ }
+ pos = endptr;
+ while (g_ascii_isspace (*pos)) {
+ ++pos;
+ }
+ if (*pos != ';') {
+ sprep_gen_report_parse_error (filename, lineno,
+ "semicolon expected after character code");
+ goto end;
+ }
+ ++pos;
+ for (;;) {
+ gunichar ch;
+ ch = sprep_gen_parse_character_code (pos, &endptr, &error);
+ if (error != NULL) {
+ sprep_gen_report_parse_error (filename, lineno,
+ error->message);
+ goto end;
+ }
+ if (endptr == pos) {
+ /* end of mapping's character codes */
+ break;
+ }
+ g_array_append_val (unichar_buf, ch);
+ pos = endptr;
+ }
+
+ mapping = sprep_gen_mapping_rep_add (rep,
+ (const gunichar *) unichar_buf->data,
+ unichar_buf->len);
+ g_return_val_if_fail (mapping != NULL, FALSE);
+
+ sprep_gen_map_add (map, key, mapping);
+
+ g_array_set_size (unichar_buf, 0);
+ }
+ if (ferror (file)) {
+ sprep_gen_report_input_error (filename);
+ goto end;
+ }
+ g_assert (feof (file));
+ res = TRUE;
+
+end:
+ if (file != NULL) {
+ fclose (file);
+ }
+ if (error != NULL) {
+ g_error_free (error);
+ }
+ if (unichar_buf != NULL) {
+ g_array_free (unichar_buf, TRUE);
+ }
+ g_free (linebuf);
+ return res;
+}
diff --git a/gen/parser.h b/gen/parser.h
new file mode 100644
index 0000000..4d62328
--- /dev/null
+++ b/gen/parser.h
@@ -0,0 +1,52 @@
+/*
+ * This file is part of preppie.
+ *
+ * Copyright (C) 2010 Mikhail Zabaluev <mikhail.zabaluev@gmail.com>
+ *
+ * This work is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This work 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this work; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#ifndef PREPPIE_GEN_PARSER_H_
+#define PREPPIE_GEN_PARSER_H_
+
+#include <glib.h>
+
+#include "cset.h"
+#include "map.h"
+#include "mapping-rep.h"
+
+G_BEGIN_DECLS
+
+
+#define SPREP_GEN_PARSE_ERRORS (sprep_gen_parse_error_quark ())
+
+typedef enum {
+ SPREP_PARSE_ERROR_SYNTAX = 1,
+ SPREP_PARSE_ERROR_CODE_OUT_OF_RANGE
+} SprepGenParseErrors;
+
+gboolean sprep_gen_parse_set (const char *filename, SprepGenCset *set);
+
+gboolean sprep_gen_parse_map (const char *filename,
+ SprepGenMap *map,
+ SprepGenMappingRep *dict);
+
+GQuark sprep_gen_parse_error_quark (void);
+
+
+G_END_DECLS
+
+#endif /* !PREPPIE_GEN_PARSER_H_ */
diff --git a/gen/srcgen-cset.c b/gen/srcgen-cset.c
new file mode 100644
index 0000000..f003fe1
--- /dev/null
+++ b/gen/srcgen-cset.c
@@ -0,0 +1,130 @@
+/*
+ * This file is part of preppie.
+ *
+ * Copyright (C) 2010 Mikhail Zabaluev <mikhail.zabaluev@gmail.com>
+ *
+ * This work is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This work 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this work; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#include <stdio.h>
+#include <glib.h>
+
+#include "cset.h"
+#include "parser.h"
+
+
+static gchar *table_name = NULL;
+
+static const GOptionEntry options[] = {
+ { "table-name", 'n', 0, G_OPTION_ARG_STRING, &table_name,
+ "Use NAME as the table array name", "NAME" },
+ { NULL }
+};
+
+
+static void
+dump_bitset (const guint32 *bitset, gunichar first, gunichar last)
+{
+ int i;
+
+ fputs (" ", stdout);
+
+ for (i = 0; i < SPREP_CSET_BITSET_SIZE; ++i) {
+ printf (" 0x%08X,", (guint) bitset[i]);
+ }
+
+ printf (" /* %04X-%04X */\n", (guint) first, (guint) last);
+}
+
+static void
+dump_set (const SprepGenCset *set)
+{
+ const SprepGenCsetPage *page;
+ guint32 page_desc;
+ guint i;
+
+ for (i = 0; i < SPREP_PAGE_TABLE_SIZE; i++) {
+ page = &set->pages[i];
+ page_desc = page->flags
+ | (page->offset & SPREP_PAGE_OFFSET_MASK);
+ printf (" 0x%08X,\n", (guint) page_desc);
+ }
+ fputs ("\n /* Bitsets */\n", stdout);
+
+ for (i = 0; i < SPREP_PAGE_TABLE_SIZE; i++) {
+ const guint32 *bitset = set->pages[i].bitset;
+ if (bitset != NULL) {
+ gunichar first = i << SPREP_PAGE_SIZE_SHIFT;
+ gunichar last = first + SPREP_PAGE_INDEX_LAST;
+ dump_bitset (bitset, first, last);
+ }
+ }
+}
+
+int
+main (int argc, char **argv)
+{
+ GOptionContext *option_ctx;
+ GError *error = NULL;
+ SprepGenCset *set;
+ gsize layout_size;
+
+ option_ctx = g_option_context_new ("FILE");
+ g_option_context_set_summary (option_ctx,
+ "Outputs the source for a built-in character set"
+ " data table.");
+ g_option_context_add_main_entries (option_ctx, options, NULL);
+ if (!g_option_context_parse (option_ctx, &argc, &argv, &error)) {
+ g_printerr ("error parsing options: %s\n", error->message);
+ return 1;
+ }
+ g_option_context_free (option_ctx);
+
+ if (table_name == NULL) {
+ g_printerr ("the table name is not specified\n");
+ return 1;
+ }
+ if (argc < 2) {
+ g_printerr ("the source set file is not specified\n");
+ return 1;
+ }
+ if (argc > 2) {
+ g_printerr ("cannot handle more than one source file parameter\n");
+ return 1;
+ }
+
+ set = sprep_gen_cset_new ();
+
+ if (!sprep_gen_parse_set (argv[1], set)) {
+ return 2;
+ }
+
+ layout_size = sprep_gen_cset_prepare_layout (set);
+
+ /* g_debug ("array size %u", (guint) layout_size); */
+
+ printf ("#include <glib.h>\n"
+ "\n"
+ "const guint32 %s[] = {\n", table_name);
+
+ dump_set (set);
+
+ fputs ("};\n", stdout);
+
+ sprep_gen_cset_destroy (set);
+
+ return 0;
+}
diff --git a/gen/srcgen-maps.c b/gen/srcgen-maps.c
new file mode 100644
index 0000000..877a9d9
--- /dev/null
+++ b/gen/srcgen-maps.c
@@ -0,0 +1,258 @@
+/*
+ * This file is part of preppie.
+ *
+ * Copyright (C) 2010 Mikhail Zabaluev <mikhail.zabaluev@gmail.com>
+ *
+ * This work is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This work 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this work; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#include <stdio.h>
+#include <glib.h>
+
+#include "map.h"
+#include "parser.h"
+
+
+static gchar *filename_b1 = NULL;
+static gchar *filename_b2 = NULL;
+static gchar *filename_b3 = NULL;
+static gchar *name_prefix = NULL;
+
+static const GOptionEntry options[] = {
+ { "input-b1", '1', 0, G_OPTION_ARG_FILENAME, &filename_b1,
+ "Name of the B.1 table file", "FILE" },
+ { "input-b2", '2', 0, G_OPTION_ARG_FILENAME, &filename_b2,
+ "Name of the B.2 table file", "FILE" },
+ { "input-b3", '3', 0, G_OPTION_ARG_FILENAME, &filename_b3,
+ "Name of the B.3 table file", "FILE" },
+ { "name-prefix", 'p', 0, G_OPTION_ARG_STRING, &name_prefix,
+ "Prefix for table array names", "STR" },
+ { NULL }
+};
+
+static void
+print_map_page (const SprepGenMapping *mappings[],
+ gunichar first,
+ gunichar last)
+{
+ int i;
+
+ printf ("\n /* Mappings %04X-%04X */\n", (guint) first, (guint) last);
+
+ for (i = 0; i < SPREP_PAGE_SIZE; i++) {
+ const SprepGenMapping *mapping = mappings[i];
+ if (mapping == NULL) {
+ fputs (" 0,\n", stdout);
+ } else {
+ guint32 mapping_desc;
+ gchar *str;
+
+ str = g_strndup (mapping->chars, mapping->length);
+
+ mapping_desc = mapping->offset
+ | ((mapping->length - 1)
+ << SPREP_MAP_CHARS_LENGTH_SHIFT);
+ printf (" 0x%08X, /* \"%s\" */\n",
+ (guint) mapping_desc, str);
+
+ g_free (str);
+ }
+ }
+}
+
+static void
+print_map (const SprepGenMap *map,
+ const gchar *name_prefix,
+ const char *name_suffix)
+{
+ int i;
+
+ printf ("\nconst guint32 %s%s[] = {\n",
+ name_prefix, name_suffix);
+
+ for (i = 0; i < SPREP_PAGE_TABLE_SIZE; i++) {
+ printf (" 0x%08X,\n", (guint) map->pages[i].offset);
+ }
+
+ for (i = 0; i < SPREP_PAGE_TABLE_SIZE; i++) {
+ const SprepGenMapping **mappings = map->pages[i].mappings;
+ if (mappings != NULL) {
+ gunichar first = i << SPREP_PAGE_SIZE_SHIFT;
+ gunichar last = first + SPREP_PAGE_INDEX_LAST;
+ print_map_page (mappings, first, last);
+ }
+ }
+
+ fputs ("};\n", stdout);
+}
+
+static gboolean
+print_mapping_traverse (gpointer key, gpointer value, gpointer user_data)
+{
+ const SprepGenMapping *mapping = value;
+ const SprepGenMapping *super = mapping->substring_of;
+ guint i;
+
+ if (!mapping->in_use) {
+ g_assert (super != NULL);
+ return FALSE;
+ }
+
+ if (super != NULL) {
+ /* No characters here, but make a comment for debugging */
+ gchar *this_str = g_strndup (mapping->chars,
+ mapping->length);
+ gchar *that_str = g_strndup (super->chars,
+ super->length);
+
+ printf (" /* \"%s\" -> \"%s\" */\n",
+ this_str, that_str);
+
+ g_free (that_str);
+ g_free (this_str);
+ return FALSE;
+ }
+
+ fputs (" ", stdout);
+ for (i = 0; i != mapping->length; ++i) {
+ printf (" '\\x%02X',", (guint) (guchar) mapping->chars[i]);
+ }
+ {
+ /* Print the string in a comment for debugging */
+ gchar *str = g_strndup (mapping->chars, mapping->length);
+ printf (" /* \"%s\" */", str);
+ g_free (str);
+ }
+ fputs ("\n", stdout);
+
+ return FALSE;
+}
+
+static void
+print_rep_page (GTree *buckets[])
+{
+ int i;
+
+ for (i = 0; i < SPREP_GEN_REP_PAGE_SIZE; i++) {
+ GTree *bucket = buckets[i];
+ if (bucket != NULL) {
+ g_tree_foreach (bucket,
+ print_mapping_traverse,
+ NULL);
+ }
+ }
+}
+
+static void
+print_rep (const SprepGenMappingRep *rep, const gchar *name_prefix)
+{
+ int i;
+
+ printf ("\nstatic const gchar %s_chars_base[] = {\n", name_prefix);
+
+ for (i = 0; i < SPREP_GEN_REP_PAGE_TABLE_SIZE; i++) {
+ SprepGenMappingRepPage page = rep->pages[i];
+ if (page != NULL) {
+ print_rep_page (page);
+ }
+ }
+
+ fputs ("};\n", stdout);
+}
+
+int
+main (int argc, char **argv)
+{
+ GOptionContext *option_ctx;
+ GError *error = NULL;
+ SprepGenMappingRep *rep;
+ SprepGenMap *map_b1;
+ SprepGenMap *map_b1_b2;
+ SprepGenMap *map_b1_b3;
+
+ option_ctx = g_option_context_new ("FILE");
+ g_option_context_set_summary (option_ctx,
+ "Outputs the source for the built-in tables\n"
+ "representing common stringprep mappings.");
+ g_option_context_add_main_entries (option_ctx, options, NULL);
+ if (!g_option_context_parse (option_ctx, &argc, &argv, &error)) {
+ g_printerr ("error parsing options: %s\n", error->message);
+ return 1;
+ }
+ g_option_context_free (option_ctx);
+
+ if (filename_b1 == NULL) {
+ g_printerr ("input file with table B.1 is not specified\n");
+ return 1;
+ }
+ if (filename_b2 == NULL) {
+ g_printerr ("input file with table B.2 is not specified\n");
+ return 1;
+ }
+ if (filename_b3 == NULL) {
+ g_printerr ("input file with table B.3 is not specified\n");
+ return 1;
+ }
+ if (name_prefix == NULL) {
+ g_printerr ("name prefix is not specified\n");
+ return 1;
+ }
+
+ rep = sprep_gen_mapping_rep_new ();
+
+ map_b1 = sprep_gen_map_new ();
+ if (!sprep_gen_parse_map (filename_b1, map_b1, rep)) {
+ return 2;
+ }
+
+ map_b1_b2 = sprep_gen_map_new ();
+ if (!sprep_gen_parse_map (filename_b1, map_b1_b2, rep)) {
+ return 2;
+ }
+ if (!sprep_gen_parse_map (filename_b2, map_b1_b2, rep)) {
+ return 2;
+ }
+
+ map_b1_b3 = sprep_gen_map_new ();
+ if (!sprep_gen_parse_map (filename_b1, map_b1_b3, rep)) {
+ return 2;
+ }
+ if (!sprep_gen_parse_map (filename_b3, map_b1_b3, rep)) {
+ return 2;
+ }
+
+ sprep_gen_mapping_rep_prepare_layout (rep);
+
+ sprep_gen_map_prepare_layout (map_b1);
+ sprep_gen_map_prepare_layout (map_b1_b2);
+ sprep_gen_map_prepare_layout (map_b1_b3);
+
+ fputs ("#include <glib.h>\n", stdout);
+
+ print_map (map_b1, name_prefix, "_b1_base");
+ print_map (map_b1_b2, name_prefix, "_b1_b2_base");
+ print_map (map_b1_b3, name_prefix, "_b1_b3_base");
+
+ print_rep (rep, name_prefix);
+
+ sprep_gen_map_destroy (map_b1_b3);
+ sprep_gen_map_destroy (map_b1_b2);
+ sprep_gen_map_destroy (map_b1);
+
+ sprep_gen_mapping_rep_destroy (rep);
+
+ return 0;
+}
diff --git a/m4/.gitignore b/m4/.gitignore
new file mode 100644
index 0000000..64d9bbc
--- /dev/null
+++ b/m4/.gitignore
@@ -0,0 +1,2 @@
+/libtool.m4
+/lt*.m4
diff --git a/preppie/.gitignore b/preppie/.gitignore
new file mode 100644
index 0000000..6133138
--- /dev/null
+++ b/preppie/.gitignore
@@ -0,0 +1 @@
+/preppie.pc \ No newline at end of file
diff --git a/preppie/Makefile.am b/preppie/Makefile.am
new file mode 100644
index 0000000..a3431b6
--- /dev/null
+++ b/preppie/Makefile.am
@@ -0,0 +1,55 @@
+lib_LTLIBRARIES = libpreppie.la
+
+libpreppie_la_SOURCES = \
+ sprep.c \
+ builtin-tables.h \
+ internal.h
+
+BUILT_TABLE_SOURCES = \
+ built/maps.c \
+ built/unassigned-unicode-3.2.c \
+ built/bidi-rtl.c \
+ built/bidi-ltr.c
+
+nodist_libpreppie_la_SOURCES = $(BUILT_TABLE_SOURCES)
+
+preppie_includedir = \
+ $(includedir)/preppie-$(PREPPIE_API_VERSION)/preppie
+
+preppie_include_HEADERS = \
+ sprep.h
+
+noinst_HEADERS = \
+ profile-format.h
+
+EXTRA_DIST = preppie.pc.in
+
+pkgconfigdir=$(libdir)/pkgconfig
+pkgconfig_DATA = preppie.pc
+
+libpreppie_la_LIBADD = $(GLIB_LIBS)
+
+AM_CPPFLAGS = $(GLIB_CFLAGS) -DSPREP_PROFILE_DIR=\"$(PREPPIE_PROFILE_DIR)\"
+
+CLEANFILES = $(BUILT_TABLE_SOURCES)
+
+GEN_MAPS = $(top_builddir)/gen/srcgen-maps
+GEN_CSET = $(top_builddir)/gen/srcgen-cset
+
+built/maps.c: $(top_srcdir)/data/B.1 $(top_srcdir)/data/B.2 $(top_srcdir)/data/B.3 $(GEN_MAPS)
+ $(GEN_MAPS) --name-prefix=_sprep_map \
+ --input-b1=$(top_srcdir)/data/B.1 \
+ --input-b2=$(top_srcdir)/data/B.2 \
+ --input-b3=$(top_srcdir)/data/B.3 \
+ > $@
+
+built/unassigned-unicode-3.2.c: $(top_srcdir)/data/A.1 $(GEN_CSET)
+ $(GEN_CSET) --table-name=_sprep_unassigned_set_unicode_3_2_base $< > $@
+
+built/bidi-rtl.c: $(top_srcdir)/data/D.1 $(GEN_CSET)
+ $(GEN_CSET) --table-name=_sprep_bidi_set_r_or_al_base $< > $@
+
+built/bidi-ltr.c: $(top_srcdir)/data/D.2 $(GEN_CSET)
+ $(GEN_CSET) --table-name=_sprep_bidi_set_l_base $< > $@
+
+.DELETE_ON_ERROR: $(BUILT_TABLE_SOURCES)
diff --git a/preppie/built/.gitignore b/preppie/built/.gitignore
new file mode 100644
index 0000000..064a8d8
--- /dev/null
+++ b/preppie/built/.gitignore
@@ -0,0 +1 @@
+*.c
diff --git a/preppie/builtin-tables.h b/preppie/builtin-tables.h
new file mode 100644
index 0000000..ef18de3
--- /dev/null
+++ b/preppie/builtin-tables.h
@@ -0,0 +1,42 @@
+/*
+ * This file is part of preppie, an efficient implementation of stringprep.
+ *
+ * Copyright (C) 2010 Mikhail Zabaluev <mikhail.zabaluev@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#ifndef _PREPPIE_BUILTIN_TABLES_H_
+#define _PREPPIE_BUILTIN_TABLES_H_
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+
+extern const guint32 _sprep_map_b1_base[];
+extern const guint32 _sprep_map_b1_b2_base[];
+extern const guint32 _sprep_map_b1_b3_base[];
+extern const gchar _sprep_chars_base[];
+
+extern const guint32 _sprep_unassigned_set_unicode_3_2_base[];
+extern const guint32 _sprep_bidi_set_r_or_al_base[];
+extern const guint32 _sprep_bidi_set_l_base[];
+
+
+G_END_DECLS
+
+#endif /* _PREPPIE_BUILTIN_TABLES_H_ */
diff --git a/preppie/internal.h b/preppie/internal.h
new file mode 100644
index 0000000..9d5984a
--- /dev/null
+++ b/preppie/internal.h
@@ -0,0 +1,40 @@
+/*
+ * This file is part of preppie.
+ *
+ * Copyright (C) 2010 Mikhail Zabaluev <mikhail.zabaluev@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#ifndef PREPPIE_INTERNAL_H_
+#define PREPPIE_INTERNAL_H_
+
+/* Internal function definitions. These are made extern only for unit tests. */
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+G_GNUC_INTERNAL
+guint _sprep_map_lookup (const guint32 *map_base, gunichar ch,
+ guint *length, gsize *chars_offset);
+
+G_GNUC_INTERNAL
+gboolean _sprep_cset_has (const guint32 *set_base, gunichar ch);
+
+G_END_DECLS
+
+#endif /* !PREPPIE_INTERNAL_H_ */
diff --git a/preppie/preppie.pc.in b/preppie/preppie.pc.in
new file mode 100644
index 0000000..bddcf1d
--- /dev/null
+++ b/preppie/preppie.pc.in
@@ -0,0 +1,12 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+includedir=@includedir@
+libdir=@libdir@
+
+Name: Preppie
+Description: An efficient stringprep implementation
+Version: @PACKAGE_VERSION@
+Requires: @GLIB_PKG_DEPS@
+
+Cflags: -I${includedir}/preppie-@PREPPIE_API_VERSION@
+Libs: -L${libdir} -lpreppie
diff --git a/preppie/profile-format.h b/preppie/profile-format.h
new file mode 100644
index 0000000..1cf2d30
--- /dev/null
+++ b/preppie/profile-format.h
@@ -0,0 +1,110 @@
+/*
+ * This file is part of Preppie, an efficient implementation of stringprep.
+ *
+ * Copyright (C) 2010 Mikhail Zabaluev <mikhail.zabaluev@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#ifndef _PREPPIE_FORMAT_H_
+#define _PREPPIE_FORMAT_H_
+
+#include <glib.h>
+
+
+#define SPREP_FILE_MAGIC "Prp0"
+
+
+/* The maximum valid Unicode character code point. */
+#define SPREP_UNICHAR_MAX 0x10FFFF
+
+
+G_BEGIN_DECLS
+
+
+typedef struct _SprepProfileHeader SprepProfileHeader;
+
+struct _SprepProfileHeader {
+ gchar magic[4]; /* Initialized to "Prp<N>" with N the file version number */
+ guint16 flags; /* Profile flags as defined in SprepProfileFlags */
+ guint8 mapping_selection; /* Selection of the mapping tables as defined in SprepMappingSelection */
+ guint8 unassigned_set_selection; /* Selection of the unassigned set as defined in SprepUnassignedSetType */
+ guint32 mapping_map_offset; /* Offset of the step 1 (Mapping) map in bytes */
+ guint32 mapping_chars_offset; /* Offset of the character area for mappped characters */
+ guint32 prohibited_set_offset; /* Offset of the prohibited character set in bytes */
+ guint32 unassigned_set_offset; /* Offset of the unassigned character set in bytes */
+};
+
+
+typedef enum {
+ SPREP_PROFILE_NORMALIZE = 1 << 0,
+ SPREP_PROFILE_CHECK_BIDI = 1 << 1,
+} SprepProfileFlags;
+
+typedef enum {
+ SPREP_UNASSIGNED_PROFILE, /* Use the custom set from the profile */
+ SPREP_UNASSIGNED_UNICODE_3_2, /* Use the built-in table of unassigned character codes in Unicode 3.2 */
+} SprepUnassignedSetSelection;
+
+typedef enum {
+ SPREP_MAPPING_NONE, /* No mapping */
+ SPREP_MAPPING_PROFILE, /* Use the mapping tables from the profile */
+ SPREP_MAPPING_B1, /* Use the built-in mapping table B.1 */
+ SPREP_MAPPING_B1_B2, /* Use the built-in mapping table composed from B.1 and B.2 */
+ SPREP_MAPPING_B1_B3, /* Use the built-in mapping table composed from B.1 and B.3 */
+} SprepMappingSelection;
+
+
+/* The power of two that defines the page size for sets and replacement maps */
+#define SPREP_PAGE_SIZE_SHIFT 9
+
+#define SPREP_PAGE_SIZE (1 << SPREP_PAGE_SIZE_SHIFT)
+
+#define SPREP_PAGE_INDEX_MASK (SPREP_PAGE_SIZE - 1)
+#define SPREP_PAGE_INDEX_LAST (SPREP_PAGE_SIZE - 1)
+
+#define SPREP_PAGE_TABLE_SIZE (SPREP_UNICHAR_MAX + 1) >> SPREP_PAGE_SIZE_SHIFT
+
+#define SPREP_PAGE_FLAGS_SHIFT 24
+#define SPREP_PAGE_OFFSET_MASK 0x00ffffff
+
+
+#define SPREP_MAP_CHARS_LENGTH_SHIFT 26
+#define SPREP_MAP_CHARS_OFFSET_MASK ((1 << SPREP_MAP_CHARS_LENGTH_SHIFT) - 1)
+
+#define SPREP_MAP_CHARS_LENGTH_MODULO_MASK \
+ ((1 << (32 - SPREP_MAP_CHARS_LENGTH_SHIFT)) - 1)
+
+/* Maximum possible length of a UTF-8 mapping sequence in bytes */
+#define SPREP_MAP_CHARS_LENGTH_MAX SPREP_MAP_CHARS_LENGTH_MODULO_MASK
+
+
+#define SPREP_CSET_PAGE_FLAG_SHIFT_FULL (SPREP_PAGE_FLAGS_SHIFT + 0)
+
+typedef enum {
+ SPREP_CSET_PAGE_FULL = 1 << SPREP_CSET_PAGE_FLAG_SHIFT_FULL,
+} SprepCsetPageFlags;
+
+/* Size of a bitset page in 32-bit words */
+#define SPREP_CSET_BITSET_SIZE (1 << (SPREP_PAGE_SIZE_SHIFT - 5))
+
+
+gboolean sprep_cset_has (const guint32 *set_base, gunichar ch);
+
+
+G_END_DECLS
+
+#endif /* !_PREPPIE_FORMAT_H_ */
diff --git a/preppie/sprep.c b/preppie/sprep.c
new file mode 100644
index 0000000..392ed67
--- /dev/null
+++ b/preppie/sprep.c
@@ -0,0 +1,561 @@
+/*
+ * This file is part of preppie, an efficient implementation of stringprep.
+ *
+ * Copyright (C) 2010 Mikhail Zabaluev <mikhail.zabaluev@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#include "config.h"
+
+#include "sprep.h"
+#include "internal.h"
+
+#include <string.h>
+
+#include "profile-format.h"
+#include "builtin-tables.h"
+
+
+#ifndef SPREP_PROFILE_DIR
+#define SPREP_PROFILE_DIR "/usr/lib/" PACKAGE_NAME "/profiles"
+#endif
+
+
+struct _SprepProfile {
+ GMappedFile *mapped_file;
+ const SprepProfileHeader *header;
+ const guint32 *map_base;
+ const gchar *chars_base;
+ const guint32 *prohibit_set_base;
+ const guint32 *unassigned_set_base;
+};
+
+
+GQuark sprep_error_quark ()
+{
+ static GQuark quark = 0;
+
+ if (G_UNLIKELY (quark == 0)) {
+ quark = g_quark_from_static_string ("sprep-error");
+ }
+ return quark;
+}
+
+static gchar *
+sprep_filename_from_profile_name (const gchar *profile_name, GError **error)
+{
+ gchar *filename;
+ gchar *sanitized_name;
+ GError *conv_error = NULL;
+ gsize len;
+ gsize bytes_read;
+ gsize i;
+
+ len = strlen (profile_name);
+
+ /* Replace troublesome ASCII non-alphanumerics with underscores */
+ sanitized_name = g_malloc (len + 1);
+ for (i = 0; i < len; i++) {
+ gchar ch = profile_name[i];
+ sanitized_name[i] = ((guchar) ch >= 128
+ || g_ascii_isalnum (ch)
+ || ch == '-')?
+ ch : '_';
+ }
+ sanitized_name[i] = '\0';
+
+ /* Convert to the filename encoding */
+ filename = g_filename_from_utf8 (sanitized_name, len, &bytes_read,
+ NULL, &conv_error);
+ if (filename == NULL) {
+ g_set_error (error, SPREP_ERRORS,
+ SPREP_ERROR_BAD_PROFILE_NAME,
+ "profile name cannot be converted to file name: %s",
+ conv_error->message);
+ g_error_free (conv_error);
+ } else if (bytes_read != len) {
+ g_set_error (error, SPREP_ERRORS,
+ SPREP_ERROR_BAD_PROFILE_NAME,
+ "profile name cannot be converted to file name"
+ " due to an incomplete UTF-8 character sequence");
+ g_free (filename);
+ filename = NULL;
+ }
+
+ g_free (sanitized_name);
+
+ return filename;
+}
+
+static GMappedFile *
+sprep_profile_map_file (const gchar *profile_name, GError **error)
+{
+ GMappedFile *mapped_file;
+ gchar *file_path;
+ gchar *file_basename;
+ const gchar *profile_dir;
+ GError *file_error = NULL;
+
+ profile_dir = g_getenv ("SPREP_PROFILE_DIR");
+ if (profile_dir == NULL) {
+ profile_dir = SPREP_PROFILE_DIR;
+ }
+
+ file_basename = sprep_filename_from_profile_name (profile_name, error);
+ if (file_basename == NULL) {
+ return NULL;
+ }
+ file_path = g_build_filename (profile_dir, file_basename, NULL);
+ g_free (file_basename);
+
+ mapped_file = g_mapped_file_new (file_path, FALSE, &file_error);
+
+ if (mapped_file == NULL) {
+ g_set_error (error, SPREP_ERRORS,
+ SPREP_ERROR_PROFILE_NOT_AVAILABLE,
+ "cannot map profile file %s: %s",
+ file_path, file_error->message);
+ g_error_free (file_error);
+ }
+
+ g_free (file_path);
+
+ return mapped_file;
+}
+
+SprepProfile *
+sprep_profile_open (const gchar *profile_name, GError **error)
+{
+ SprepProfile *profile = NULL;
+ const gchar *file_base;
+ const SprepProfileHeader *header;
+ GMappedFile *mapped_file;
+
+ mapped_file = sprep_profile_map_file (profile_name, error);
+ if (mapped_file == NULL) {
+ return NULL;
+ }
+
+ file_base = g_mapped_file_get_contents (mapped_file);
+ header = (const SprepProfileHeader *) file_base;
+
+ if (memcmp (header->magic, SPREP_FILE_MAGIC, sizeof (header->magic))
+ != 0) {
+ g_set_error (error, SPREP_ERRORS,
+ SPREP_ERROR_UNSUPPORTED_PROFILE_FORMAT,
+ "the profile file format is not recognized");
+ goto err;
+ }
+
+ profile = g_slice_new0 (SprepProfile);
+ profile->mapped_file = mapped_file;
+ profile->header = header;
+
+ switch (header->unassigned_set_selection) {
+ case SPREP_UNASSIGNED_PROFILE:
+ profile->unassigned_set_base = (const guint32 *)
+ (file_base + header->unassigned_set_offset);
+ break;
+ case SPREP_UNASSIGNED_UNICODE_3_2:
+ profile->unassigned_set_base =
+ _sprep_unassigned_set_unicode_3_2_base;
+ break;
+ default:
+ g_set_error (error, SPREP_ERRORS,
+ SPREP_ERROR_PROFILE_MALFORMED,
+ "unknown unassigned set selection %u",
+ (guint) header->unassigned_set_selection);
+ goto err;
+ }
+
+ switch (header->mapping_selection) {
+ case SPREP_MAPPING_NONE:
+ profile->map_base = NULL;
+ profile->chars_base = NULL;
+ break;
+ case SPREP_MAPPING_PROFILE:
+ profile->map_base = (const guint32 *)
+ (file_base + header->mapping_map_offset);
+ profile->chars_base = file_base + header->mapping_chars_offset;
+ break;
+ case SPREP_MAPPING_B1:
+ profile->map_base = _sprep_map_b1_base;
+ profile->chars_base = _sprep_chars_base;
+ break;
+ case SPREP_MAPPING_B1_B2:
+ profile->map_base = _sprep_map_b1_b2_base;
+ profile->chars_base = _sprep_chars_base;
+ break;
+ case SPREP_MAPPING_B1_B3:
+ profile->map_base = _sprep_map_b1_b3_base;
+ profile->chars_base = _sprep_chars_base;
+ break;
+ default:
+ g_set_error (error, SPREP_ERRORS,
+ SPREP_ERROR_PROFILE_MALFORMED,
+ "unknown mapping selection %u",
+ (guint) header->mapping_selection);
+ goto err;
+ }
+
+ profile->prohibit_set_base = (const guint32 *)
+ (file_base + header->prohibited_set_offset);
+
+ return profile;
+
+err:
+ g_mapped_file_unref (mapped_file);
+ if (profile != NULL) {
+ g_slice_free (SprepProfile, profile);
+ }
+ return NULL;
+}
+
+void
+sprep_profile_destroy (SprepProfile *profile)
+{
+ if (profile->mapped_file != NULL)
+ g_mapped_file_unref (profile->mapped_file);
+ g_slice_free (SprepProfile, profile);
+}
+
+guint
+_sprep_map_lookup (const guint32 *map_base, gunichar ch,
+ guint *length, gsize *chars_offset)
+{
+ const guint32 *page_base;
+ guint32 page_desc;
+ guint32 chars_desc;
+
+ page_desc = map_base[ch >> SPREP_PAGE_SIZE_SHIFT];
+
+ if (page_desc == 0) {
+ /* The page has no mappings */
+ return FALSE;
+ }
+
+ page_base = map_base + (page_desc & SPREP_PAGE_OFFSET_MASK);
+ chars_desc = page_base[ch & SPREP_PAGE_INDEX_MASK];
+
+ if (chars_desc == 0) {
+ /* Trivial mapping */
+ return FALSE;
+ }
+
+ *length = ((chars_desc >> SPREP_MAP_CHARS_LENGTH_SHIFT) + 1)
+ & SPREP_MAP_CHARS_LENGTH_MODULO_MASK;
+ *chars_offset = chars_desc & SPREP_MAP_CHARS_OFFSET_MASK;
+ return TRUE;
+}
+
+gboolean
+_sprep_cset_has (const guint32 *set_base, gunichar ch)
+{
+ const guint32 *bitset;
+ guint bitset_index;
+ guint32 page_desc;
+
+ /* Get the page descriptor for the character */
+ page_desc = set_base[ch >> SPREP_PAGE_SIZE_SHIFT];
+
+ if (page_desc == 0) {
+ /* The page is empty */
+ return FALSE;
+ }
+
+ if ((page_desc & SPREP_CSET_PAGE_FULL) != 0) {
+ /* The page is full */
+ return TRUE;
+ }
+
+ /* Look up in the bitset */
+
+ bitset = set_base + (page_desc & SPREP_PAGE_OFFSET_MASK);
+
+ bitset_index = (ch & SPREP_PAGE_INDEX_MASK) >> 5;
+
+ return ((bitset[bitset_index] & (1 << (ch & 0x1f))) != 0);
+}
+
+static gboolean
+sprep_check_unassigned (SprepProfile *profile,
+ const gchar *str,
+ gssize len,
+ GError **error)
+{
+ const guint32 *unassigned_set_base = profile->unassigned_set_base;
+ const gchar *p = str;
+ const gchar *end = str + len;
+
+ while (p != end) {
+ gunichar ch = g_utf8_get_char (p);
+
+ if (_sprep_cset_has (unassigned_set_base, ch)) {
+ g_set_error (error, SPREP_ERRORS,
+ SPREP_ERROR_UNASSIGNED_CODE_POINT,
+ "code point <U+%04X>"
+ " is not assigned in the profile,"
+ " hence not allowed in a stored string",
+ (guint) ch);
+ return FALSE;
+ }
+
+ p = g_utf8_next_char (p);
+ }
+
+ return TRUE;
+}
+
+static gchar *
+sprep_step_map (SprepProfile *profile,
+ const gchar *str,
+ gssize *len)
+{
+ GString *mapped_buf;
+ const gchar *p;
+ const gchar *q;
+ const gchar *end;
+
+ if (profile->map_base == NULL) {
+ /* The profile does not perform mapping */
+ return g_strndup (str, *len);
+ }
+
+ mapped_buf = g_string_sized_new (*len);
+
+ p = str;
+ q = str;
+ end = str + *len;
+
+ while (p != end) {
+ guint mapping_len;
+ gsize mapping_offset;
+ gunichar ch = g_utf8_get_char (p);
+
+ if (!_sprep_map_lookup (profile->map_base, ch,
+ &mapping_len, &mapping_offset)) {
+ /* Skip, will copy later */
+ p = g_utf8_next_char (p);
+ } else {
+ /* Copy the preceding substitution-free run in bulk */
+ if (p != q) {
+ g_string_append_len (mapped_buf, p, p - q);
+ }
+
+ /* Append the non-trivial mapping */
+ if (mapping_len != 0) {
+ g_string_append_len (
+ mapped_buf,
+ profile->chars_base
+ + mapping_offset,
+ mapping_len);
+ }
+
+ p = g_utf8_next_char (p);
+ q = p;
+ }
+ }
+ /* Copy the trailing no-substitutions chunk, if any */
+ if (p != q) {
+ g_string_append_len (mapped_buf, p, p - q);
+ }
+
+ *len = mapped_buf->len;
+ return g_string_free (mapped_buf, FALSE);
+}
+
+static gboolean
+sprep_step_prohibit (SprepProfile *profile,
+ const gchar *str,
+ const gchar **endptr,
+ GError **error)
+{
+ const guint32 *prohibit_set_base = profile->prohibit_set_base;
+ const gchar *p = str;
+ gunichar ch;
+
+ while ((ch = g_utf8_get_char (p)) != 0) {
+
+ if (_sprep_cset_has (prohibit_set_base, ch)) {
+ g_set_error (error, SPREP_ERRORS,
+ SPREP_ERROR_PROHIBITED_CHARACTER,
+ "prohibited character <U+%04X>"
+ " in the prepared string",
+ (guint) ch);
+ return FALSE;
+ }
+
+ p = g_utf8_next_char (p);
+ }
+
+ *endptr = p;
+ return TRUE;
+}
+
+static gboolean
+sprep_step_check_bidi (SprepProfile *profile,
+ const gchar *str,
+ const gchar *end,
+ GError **error)
+{
+ const gchar *p;
+ gunichar ch;
+
+ if ((profile->header->flags & SPREP_PROFILE_CHECK_BIDI) == 0) {
+ return TRUE;
+ }
+
+ p = str;
+
+ /* Check for any character with Unicode bidi categories R or AL */
+ while (p != end) {
+ ch = g_utf8_get_char (p);
+
+ if (_sprep_cset_has (_sprep_bidi_set_r_or_al_base, ch)) {
+ goto has_r_or_al;
+ }
+
+ p = g_utf8_next_char (p);
+ }
+
+ return TRUE;
+
+has_r_or_al:
+
+ /* If a string contains any RandALCat character, a RandALCat
+ * character MUST be the first character of the string, and a
+ * RandALCat character MUST be the last character of the string.
+ */
+ ch = g_utf8_get_char (str);
+ if (!_sprep_cset_has (_sprep_bidi_set_r_or_al_base, ch)) {
+ g_set_error (error, SPREP_ERRORS,
+ SPREP_ERROR_BIDI_CHECK_FAILED,
+ "string containing right-to-left characters"
+ " must begin with a right-to-left character");
+ return FALSE;
+ }
+ p = g_utf8_find_prev_char (str, end);
+ if (p != str
+ && !_sprep_cset_has (_sprep_bidi_set_r_or_al_base,
+ g_utf8_get_char (p))) {
+ g_set_error (error, SPREP_ERRORS,
+ SPREP_ERROR_BIDI_CHECK_FAILED,
+ "string containing right-to-left characters"
+ " must end with a right-to-left character");
+ return FALSE;
+ }
+
+ /* If a string contains any RandALCat character, the string MUST NOT
+ * contain any LCat character.
+ */
+ p = str;
+ while (p != end) {
+ ch = g_utf8_get_char (p);
+
+ if (_sprep_cset_has (_sprep_bidi_set_l_base, ch)) {
+ g_set_error (error, SPREP_ERRORS,
+ SPREP_ERROR_BIDI_CHECK_FAILED,
+ "string containing right-to-left characters"
+ " must not contain left-to-right characters");
+ return FALSE;
+ }
+
+ p = g_utf8_next_char (p);
+ }
+
+ return TRUE;
+}
+
+gchar *
+sprep_prepare (SprepProfile *profile,
+ const gchar *str,
+ gssize len,
+ SprepStrictness strictness,
+ GError **error)
+{
+ gchar *mapped;
+ gchar *res = NULL;
+ const gchar *end;
+
+ if (len < 0) {
+ len = strlen (str);
+ }
+
+ if (G_UNLIKELY (!g_utf8_validate (str, len, NULL))) {
+ g_set_error (error,
+ SPREP_ERRORS, SPREP_ERROR_INVALID_INPUT,
+ "the input string is not valid UTF-8");
+ return NULL;
+ }
+
+ /* If the string is prepared for storage, check for
+ * unassigned code points */
+ if (strictness == SPREP_STORED
+ && !sprep_check_unassigned (profile, str, len, error)) {
+ return NULL;
+ }
+
+ /* The steps quoted from RFC 3454 Section 2:
+ */
+
+ /* 1) Map -- For each character in the input, check if it has a mapping
+ * and, if so, replace it with its mapping.
+ */
+ mapped = sprep_step_map (profile, str, &len);
+
+ /* 2) Normalize -- Possibly normalize the result of step 1 using
+ * Unicode normalization.
+ */
+ if ((profile->header->flags & SPREP_PROFILE_NORMALIZE)) {
+
+ /* XXX: we are using the normalization function from GLib which
+ * implements some recent Unicode version, contrary to
+ * RFC 3454 Section 4 which demands normalization
+ * accordingly to the Unicode version fixed in the profile */
+
+ res = g_utf8_normalize (mapped, len, G_NORMALIZE_NFKC);
+
+ g_free (mapped);
+
+ g_return_val_if_fail (res != NULL, NULL);
+ } else {
+ res = mapped;
+ }
+
+ /* 3) Prohibit -- Check for any characters that are not allowed in the
+ * output. If any are found, return an error.
+ */
+ if (!sprep_step_prohibit (profile, res, &end, error)) {
+ goto err;
+ }
+
+ /* 4) Check bidi -- Possibly check for right-to-left characters, and if
+ * any are found, make sure that the whole string satisfies the
+ * requirements for bidirectional strings. If the string does not
+ * satisfy the requirements for bidirectional strings, return an
+ * error.
+ */
+ if (!sprep_step_check_bidi (profile, res, end, error)) {
+ goto err;
+ }
+
+ return res;
+
+err:
+ g_free (res);
+ return NULL;
+}
diff --git a/preppie/sprep.h b/preppie/sprep.h
new file mode 100644
index 0000000..d5f28a8
--- /dev/null
+++ b/preppie/sprep.h
@@ -0,0 +1,67 @@
+/*
+ * This file is part of preppie.
+ *
+ * Copyright (C) 2010 Mikhail Zabaluev <mikhail.zabaluev@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#ifndef PREPPIE_SPREP_H_
+#define PREPPIE_SPREP_H_
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+
+#define SPREP_ERRORS (sprep_error_quark ())
+
+typedef enum {
+ SPREP_ERROR_NONE = 0,
+ SPREP_ERROR_INVALID_INPUT,
+ SPREP_ERROR_UNASSIGNED_CODE_POINT,
+ SPREP_ERROR_PROHIBITED_CHARACTER,
+ SPREP_ERROR_BIDI_CHECK_FAILED,
+ SPREP_ERROR_BAD_PROFILE_NAME,
+ SPREP_ERROR_PROFILE_NOT_AVAILABLE,
+ SPREP_ERROR_UNSUPPORTED_PROFILE_FORMAT,
+ SPREP_ERROR_PROFILE_MALFORMED,
+} SprepError;
+
+typedef struct _SprepProfile SprepProfile;
+
+typedef enum {
+ SPREP_QUERY,
+ SPREP_STORED
+} SprepStrictness;
+
+
+SprepProfile *sprep_profile_open (const gchar *profile_name, GError **error);
+
+void sprep_profile_destroy (SprepProfile *profile);
+
+gchar *sprep_prepare (SprepProfile *profile,
+ const gchar *str,
+ gssize len,
+ SprepStrictness strictness,
+ GError **error);
+
+GQuark sprep_error_quark (void);
+
+
+G_END_DECLS
+
+#endif /* !PREPPIE_SPREP_H_ */
diff --git a/tests/Makefile.am b/tests/Makefile.am
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/Makefile.am
diff --git a/tests/internal/test-gen-cset.c b/tests/internal/test-gen-cset.c
new file mode 100644
index 0000000..3656ca4
--- /dev/null
+++ b/tests/internal/test-gen-cset.c
@@ -0,0 +1,90 @@
+/* TODO: old code, to be rewritten */
+
+#include <check.h>
+
+#include <glib.h>
+#include <libpreppie/preppie-gen-cset.h>
+
+#define SPREP_TEST_DATA_DIR "data"
+
+static SprepGenCset *cset;
+static SprepGenOutput *out;
+static GMappedFile *mapped_file;
+gconstpointer cset_base;
+static gchar *file_path;
+
+
+static void
+test_gen_cset_setup ()
+{
+ cset = sprep_gen_cset_new ();
+ fail_unless (cset != NULL, "NULL returned on SprepGenCset creation");
+
+ file_path = g_build_filename (SPREP_TEST_DATA_DIR, "test-cset", NULL);
+
+ out = sprep_gen_output_open (file_path);
+ g_free (file_path);
+
+ fail_unless (out != NULL, "NULL returned on SprepGenOutput creation");
+}
+
+static void
+test_gen_cset_setup_stage2 ()
+{
+ GError *error = NULL;
+
+ if (!sprep_gen_cset_write (cset, out, &error)) {
+ fail_unless (error != NULL, "GError not set when sprep_gen_cset_write() failed");
+ fail ("sprep_gen_cset_write() failed: %s", error->message);
+ }
+
+ sprep_gen_output_close (out);
+
+ sprep_gen_cset_destroy (cset);
+
+ mapped_file = g_mapped_file_new (file_path, FALSE, NULL);
+
+ fail_unless (mapped_file != NULL, "Could not map the created file");
+
+ cset_base = g_mapped_file_get_contents (mapped_file);
+}
+
+static void
+test_gen_cset_teardown ()
+{
+ g_mapped_file_free (mapped_file);
+}
+
+START_TEST(test_gen_cset_bare)
+{
+ sprep_gen_cset_add (cset, 'B');
+
+ test_gen_cset_setup_stage2 ();
+
+ fail_unless (!sprep_cset_has (cset_base, 'A'));
+ fail_unless (sprep_cset_has (cset_base, 'B'));
+ fail_unless (!sprep_cset_has (cset_base, 'C'));
+ fail_unless (!sprep_cset_has (cset_base, 0x800 + 'B'));
+}
+END_TEST
+
+Suite *
+test_gen_cset_suite ()
+{
+ Suite *s;
+ TCase *core_tests;
+
+ s = suite_create ("Cset");
+
+ core_tests = tcase_create ("roundtrip");
+ tcase_add_checked_fixture (core_tests,
+ test_gen_cset_setup,
+ test_gen_cset_teardown);
+ {
+ tcase_add_test (core_tests, test_gen_cset_bare);
+ /* Add new core tests above */
+ }
+ suite_add_tcase (s, core_tests);
+
+ return s;
+}