This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RFA: Unicode 4 and Java 1.5 Character support


Approval is required for the (attached) patch described below.

This patch adds Unicode 4 support to gcj.  

In the past, scripts/unicode-muncher.pl was used to parse the Unicode
raw data and generate classpath/gnu/java/lang/CharData.java which stores
the tables that Classpath uses.  Since GCJ stores the tables differently
than classpath, we'd then run scripts/MakeCharTables.java to convert
CharData.java to include/java-chartables.h.  However, the format of
CharData changed with the upgrade to Unicode 4 and the scripts had to be
revised.  The choice was made to replace unicode-muncher.pl and
MakeCharTables.java with one script (scripts/unicode-to-chartables.pl)
that directly parses the Unicode raw data and generates the tables that
gcj uses.

This was done and java-chartables.h was regenerated.
java/lang/natCharacter.cc and java/lang/Character.java were then edited
to add new Java 1.5 methods that use the Unicode 4 support.

make check was run both with and without this patch and the results were
the same:
# of expected passes            4065
# of expected failures          10
# of untested testcases         8

2006-03-14  Anthony Balkissoon  <abalkiss@redhat.com>

	* scripts/unicode-muncher.pl: Removed this file.
	* scripts/MakeCharTables.java: Likewise.
	* scripts/unicode-to-chartables.pl: New file.
	* java/lang/natCharacter.cc: 
	(UNASSIGNED_TYPE): New field.
	(UNASSIGNED_DIGIT): Likewise.
	(UNASSIGNED_DIRECTION): Likewise.
	(UNASSIGNED_NUMERIC_VALUE): Likewise.
	(PRIVATE_TYPE): Likewise.
	(PRIVATE_DIRECTION): Likewise.
	(readCodePoint): New method.
	(getType(jint)): Likewise.
	(toLowerCase(jint)): Likewise.
	(toUpperCase(jint)): Likewise.
	(toTitleCase(jint)): Likewise.
	(digit(jint, jint)): Likewise.
	(getNumericValue(jint)): Likewise.
	(getDirectionality(jint)): Likewise.
	(readChar),
	(getType(jchar)),
	(toLowerCase(jchar)),
	(toUpperCase(jchar)),
	(toTitleCase(jchar)),
	(digit(jchar, jint)),
	(getNumericValue(jchar)),
	(getDirectionality(jchar)): Changed references from data to data[0], 
	blocks to blocks[0], direction to direction[0], numValue to 
	numValue[0], upper to upper[0], lower to lower[0], and shift to 
	shift[0] to reflect the new structures in java-chartables.h.	
	* java/lang/Character.java:
	(readCodePoint): Declared new native method.
	(getType(int)): Likewise.
	(toLowerCase(int)): Likewise.
	(toUpperCase(int)): Likewise.
	(toTitleCase(int)): Likewise.
	(digit(int, int)): Likewise.
	(getNumericValue(int)): Likewise.
	(getDirectionality(int)): Likewise.
	(isLowerCase(int)): New method.
	(isUpperCase(int)): Likewise.
	(itTitleCase(int)): Likewise.
	(isDigit(int)): Likewise.
	(isDefined(int)): Likewise.
	(isLetter(int)): Likewise.
	(isLetterOrDigit(int)): Likewise.
	(isJavaIdentifierStart(int)): Likewise.
	(isJavaIdentifierPart(int)): Likewise.
	(isUnicodeIdentifierStart(int)): Likewise.
	(isUnicodeIdentifierPart(int)): Likewise.
	(isIdentifierIgnorable(int)): Likewise.
	(isSpaceChar(int)): Likewise.
	(isWhitespace(int)): Likewise.
	(isISOControl(int)): Likewise.
	(isMirrored(int)): Likewise.
	* include/java-chartables.h: Generated from 
	scripts/unicode-to-chartables.h.

--Tony
Index: libjava/scripts/unicode-muncher.pl
===================================================================
--- libjava/scripts/unicode-muncher.pl	(revision 112066)
+++ libjava/scripts/unicode-muncher.pl	(working copy)
@@ -1,642 +0,0 @@
-#!/usr/bin/perl -w
-# unicode-muncher.pl -- generate Unicode database for java.lang.Character
-# Copyright (C) 1998, 2002, 2004  Free Software Foundation, Inc.
-#
-# This file is part of GNU Classpath.
-#
-# GNU Classpath is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-#
-# GNU Classpath is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with GNU Classpath; see the file COPYING.  If not, write to the
-# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301 USA.
-#
-# Linking this library statically or dynamically with other modules is
-# making a combined work based on this library.  Thus, the terms and
-# conditions of the GNU General Public License cover the whole
-# combination.
-#
-# As a special exception, the copyright holders of this library give you
-# permission to link this library with independent modules to produce an
-# executable, regardless of the license terms of these independent
-# modules, and to copy and distribute the resulting executable under
-# terms of your choice, provided that you also meet, for each linked
-# independent module, the terms and conditions of the license of that
-# module.  An independent module is a module which is not derived from
-# or based on this library.  If you modify this library, you may extend
-# this exception to your version of the library, but you are not
-# obligated to do so.  If you do not wish to do so, delete this
-# exception statement from your version.
-
-# Code for reading UnicodeData-3.0.0.txt and SpecialCasing-2.txt to generate
-# the code for gnu.java.lang.CharData. The relevant files can be found here:
-#
-#   http://www.unicode.org/Public/3.0-Update/UnicodeData-3.0.0.txt
-#   http://www.unicode.org/Public/3.0-Update/SpecialCasing-2.txt
-#
-# Inspired by code from Jochen Hoenicke.
-# author Eric Blake <ebb9@email.byu.edu>
-#
-# Usage: ./unicode-muncher <UnicodeData.txt> <SpecialCasing> <CharData.java>
-#   where <UnicodeData.txt> is obtained from www.unicode.org (named
-#   UnicodeData-3.0.0.txt for Unicode version 3.0.0), <SpecialCasing>
-#   is obtained from www.unicode too (named SpecialCasing-2.txt for Unicode
-#   version 3.0.0), and <CharData.java> is the final location for the Java
-#   interface gnu.java.lang.CharData. As of JDK 1.4, use Unicode version 3.0.0
-#   for best results.
-
-##
-## Convert a 16-bit integer to a Java source code String literal character
-##
-sub javaChar($) {
-    my ($char) = @_;
-    die "Out of range: $char\n" if $char < -0x8000 or $char > 0xffff;
-    $char += 0x10000 if $char < 0;
-    # Special case characters that must be escaped, or are shorter as ASCII
-    return sprintf("\\%03o", $char) if $char < 0x20;
-    return "\\\"" if $char == 0x22;
-    return "\\\\" if $char == 0x5c;
-    return pack("C", $char) if $char < 0x7f;
-    return sprintf("\\u%04x", $char);
-}
-
-##
-## Convert the text UnicodeData file from www.unicode.org into a Java
-## interface with string constants holding the compressed information.
-##
-my @TYPECODES = qw(Cn Lu Ll Lt Lm Lo Mn Me Mc Nd Nl No Zs Zl Zp Cc Cf
-                   SKIPPED Co Cs Pd Ps Pe Pc Po Sm Sc Sk So Pi Pf);
-my @DIRCODES = qw(L R AL EN ES ET AN CS NSM BN B S WS ON LRE LRO RLE RLO PDF);
-
-my $NOBREAK_FLAG  = 32;
-my $MIRRORED_FLAG = 64;
-
-my %special = ();
-my @info = ();
-my $titlecase = "";
-my $count = 0;
-my $range = 0;
-
-die "Usage: $0 <UnicodeData.txt> <SpecialCasing.txt> <CharData.java>"
-    unless @ARGV == 3;
-$| = 1;
-print "GNU Classpath Unicode Attribute Database Generator 2.1\n";
-print "Copyright (C) 1998, 2002 Free Software Foundation, Inc.\n";
-
-# Stage 0: Parse the special casing file
-print "Parsing special casing file\n";
-open (SPECIAL, "< $ARGV[1]") || die "Can't open special casing file: $!\n";
-while (<SPECIAL>) {
-    next if /^\#/;
-    my ($ch, undef, undef, $upper) = split / *; */;
-
-    # This grabs only the special casing for multi-char uppercase. Note that
-    # there are no multi-char lowercase, and that Sun ignores multi-char
-    # titlecase rules. This script omits 3 special cases in Unicode 3.0.0,
-    # which must be hardcoded in java.lang.String:
-    #  \u03a3 (Sun ignores this special case)
-    #  \u0049 - lowercases to \u0131, but only in Turkish locale
-    #  \u0069 - uppercases to \u0130, but only in Turkish locale
-    next unless defined $upper and $upper =~ / /;
-    $special{hex $ch} = [map {hex} split ' ', $upper];
-}
-
-close SPECIAL;
-
-# Stage 1: Parse the attribute file
-print "Parsing attributes file";
-open (UNICODE, "< $ARGV[0]") || die "Can't open Unicode attribute file: $!\n";
-while (<UNICODE>) {
-    print "." unless $count++ % 1000;
-    chomp;
-    s/\r//g;
-    my ($ch, $name, $category, undef, $bidir, $decomp, undef, undef, $numeric,
-        $mirrored, undef, undef, $upcase, $lowcase, $title) = split ';';
-    $ch = hex($ch);
-    next if $ch > 0xffff; # Ignore surrogate pairs, since Java does
-
-    my ($type, $numValue, $upperchar, $lowerchar, $direction);
-
-    $type = 0;
-    while ($category !~ /^$TYPECODES[$type]$/) {
-        if (++$type == @TYPECODES) {
-            die "$ch: Unknown type: $category";
-        }
-    }
-    $type |= $NOBREAK_FLAG if ($decomp =~ /noBreak/);
-    $type |= $MIRRORED_FLAG if ($mirrored =~ /Y/);
-
-    if ($numeric =~ /^[0-9]+$/) {
-        $numValue = $numeric;
-        die "numValue too big: $ch, $numValue\n" if $numValue >= 0x7fff;
-    } elsif ($numeric eq "") {
-        # Special case sequences of 'a'-'z'
-        if ($ch >= 0x0041 && $ch <= 0x005a) {
-            $numValue = $ch - 0x0037;
-        } elsif ($ch >= 0x0061 && $ch <= 0x007a) {
-            $numValue = $ch - 0x0057;
-        } elsif ($ch >= 0xff21 && $ch <= 0xff3a) {
-            $numValue = $ch - 0xff17;
-        } elsif ($ch >= 0xff41 && $ch <= 0xff5a) {
-            $numValue = $ch - 0xff37;
-        } else {
-            $numValue = -1;
-        }
-    } else {
-        $numValue = -2;
-    }
-
-    $upperchar = $upcase ? hex($upcase) - $ch : 0;
-    $lowerchar = $lowcase ? hex($lowcase) - $ch : 0;
-    if ($title ne $upcase) {
-        my $titlechar = $title ? hex($title) : $ch;
-        $titlecase .= pack("n2", $ch, $titlechar);
-    }
-
-    $direction = 0;
-    while ($bidir !~ /^$DIRCODES[$direction]$/) {
-        if (++$direction == @DIRCODES) {
-            $direction = -1;
-            last;
-        }
-    }
-    $direction <<= 2;
-    $direction += $#{$special{$ch}} if defined $special{$ch};
-
-    if ($range) {
-        die "Expecting end of range at $ch\n" unless $name =~ /Last>$/;
-        for ($range + 1 .. $ch - 1) {
-            $info[$_] = pack("n5", $type, $numValue, $upperchar,
-                             $lowerchar, $direction);
-        }
-        $range = 0;
-    } elsif ($name =~ /First>$/) {
-        $range = $ch;
-    }
-    $info[$ch] = pack("n5", $type, $numValue, $upperchar, $lowerchar,
-                      $direction);
-}
-close UNICODE;
-
-# Stage 2: Compress the data structures
-printf "\nCompressing data structures";
-$count = 0;
-my $info = ();
-my %charhash = ();
-my @charinfo = ();
-
-for my $ch (0 .. 0xffff) {
-    print "." unless $count++ % 0x1000;
-    $info[$ch] = pack("n5", 0, -1, 0, 0, -4) unless defined $info[$ch];
-
-    my ($type, $numVal, $upper, $lower, $direction) = unpack("n5", $info[$ch]);
-    if (! exists $charhash{$info[$ch]}) {
-        push @charinfo, [ $numVal, $upper, $lower, $direction ];
-        $charhash{$info[$ch]} = $#charinfo;
-    }
-    $info .= pack("n", ($charhash{$info[$ch]} << 7) | $type);
-}
-
-my $charlen = @charinfo;
-my $bestshift;
-my $bestest = 1000000;
-my $bestblkstr;
-die "Too many unique character entries: $charlen\n" if $charlen > 512;
-print "\nUnique character entries: $charlen\n";
-
-for my $i (3 .. 8) {
-    my $blksize = 1 << $i;
-    my %blocks = ();
-    my @blkarray = ();
-    my ($j, $k);
-    print "shift: $i";
-
-    for ($j = 0; $j < 0x10000; $j += $blksize) {
-        my $blkkey = substr $info, 2 * $j, 2 * $blksize;
-        if (! exists $blocks{$blkkey}) {
-            push @blkarray, $blkkey;
-            $blocks{$blkkey} = $#blkarray;
-        }
-    }
-    my $blknum = @blkarray;
-    my $blocklen = $blknum * $blksize;
-    printf " before %5d", $blocklen;
-
-    # Now we try to pack the blkarray as tight as possible by finding matching
-    # heads and tails.
-    for ($j = $blksize - 1; $j > 0; $j--) {
-        my %tails = ();
-        for $k (0 .. $#blkarray) {
-            next unless defined $blkarray[$k];
-            my $len = length $blkarray[$k];
-            my $tail = substr $blkarray[$k], $len - $j * 2;
-            if (exists $tails{$tail}) {
-                push @{$tails{$tail}}, $k;
-            } else {
-                $tails{$tail} = [ $k ];
-            }
-        }
-
-        # tails are calculated, now calculate the heads and merge.
-      BLOCK:
-        for $k (0 .. $#blkarray) {
-            next unless defined $blkarray[$k];
-            my $tomerge = $k;
-            while (1) {
-                my $head = substr($blkarray[$tomerge], 0, $j * 2);
-                my $entry = $tails{$head};
-                next BLOCK unless defined $entry;
-
-                my $other = shift @{$entry};
-                if ($other == $tomerge) {
-                    if (@{$entry}) {
-                        push @{$entry}, $other;
-                        $other = shift @{$entry};
-                    } else {
-                        push @{$entry}, $other;
-                        next BLOCK;
-                    }
-                }
-                if (@{$entry} == 0) {
-                    delete $tails{$head};
-                }
-
-                # a match was found
-                my $merge = $blkarray[$other]
-                    . substr($blkarray[$tomerge], $j * 2);
-                $blocklen -= $j;
-                $blknum--;
-
-                if ($other < $tomerge) {
-                    $blkarray[$tomerge] = undef;
-                    $blkarray[$other] = $merge;
-                    my $len = length $merge;
-                    my $tail = substr $merge, $len - $j * 2;
-                    $tails{$tail} = [ map { $_ == $tomerge ? $other : $_ }
-                                      @{$tails{$tail}} ];
-                    next BLOCK;
-                }
-                $blkarray[$tomerge] = $merge;
-                $blkarray[$other] = undef;
-            }
-        }
-    }
-    my $blockstr;
-    for $k (0 .. $#blkarray) {
-        $blockstr .= $blkarray[$k] if defined $blkarray[$k];
-    }
-
-    die "Unexpected $blocklen" if length($blockstr) != 2 * $blocklen;
-    my $estimate = 2 * $blocklen + (0x20000 >> $i);
-
-    printf " after merge %5d: %6d bytes\n", $blocklen, $estimate;
-    if ($estimate < $bestest) {
-        $bestest = $estimate;
-        $bestshift = $i;
-        $bestblkstr = $blockstr;
-    }
-}
-
-my @blocks;
-my $blksize = 1 << $bestshift;
-for (my $j = 0; $j < 0x10000; $j += $blksize) {
-    my $blkkey = substr $info, 2 * $j, 2 * $blksize;
-    my $index = index $bestblkstr, $blkkey;
-    while ($index & 1) {
-        die "not found: $j" if $index == -1;
-        $index = index $bestblkstr, $blkkey, $index + 1;
-    }
-    push @blocks, ($index / 2 - $j) & 0xffff;
-}
-
-# Phase 3: Generate the file
-die "UTF-8 limit of blocks may be exceeded: " . scalar(@blocks) . "\n"
-    if @blocks > 0xffff / 3;
-die "UTF-8 limit of data may be exceeded: " . length($bestblkstr) . "\n"
-    if length($bestblkstr) > 0xffff / 3;
-{
-    print "Generating $ARGV[2] with shift of $bestshift";
-    my ($i, $j);
-
-    open OUTPUT, "> $ARGV[2]" or die "Failed creating output file: $!\n";
-    print OUTPUT <<EOF;
-/* gnu/java/lang/CharData -- Database for java.lang.Character Unicode info
-   Copyright (C) 2002 Free Software Foundation, Inc.
-   *** This file is generated by scripts/unicode-muncher.pl ***
-
-This file is part of GNU Classpath.
-
-GNU Classpath is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU Classpath is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Classpath; see the file COPYING.  If not, write to the
-Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301 USA.
-
-Linking this library statically or dynamically with other modules is
-making a combined work based on this library.  Thus, the terms and
-conditions of the GNU General Public License cover the whole
-combination.
-
-As a special exception, the copyright holders of this library give you
-permission to link this library with independent modules to produce an
-executable, regardless of the license terms of these independent
-modules, and to copy and distribute the resulting executable under
-terms of your choice, provided that you also meet, for each linked
-independent module, the terms and conditions of the license of that
-module.  An independent module is a module which is not derived from
-or based on this library.  If you modify this library, you may extend
-this exception to your version of the library, but you are not
-obligated to do so.  If you do not wish to do so, delete this
-exception statement from your version. */
-
-package gnu.java.lang;
-
-/**
- * This contains the info about the unicode characters, that
- * java.lang.Character needs.  It is generated automatically from
- * <code>$ARGV[0]</code> and
- * <code>$ARGV[1]</code>, by some
- * perl scripts. These Unicode definition files can be found on the
- * <a href="http://www.unicode.org";>http://www.unicode.org</a> website.
- * JDK 1.4 uses Unicode version 3.0.0.
- *
- * The data is stored as string constants, but Character will convert these
- * Strings to their respective <code>char[]</code> components.  The field
- * <code>BLOCKS</code> stores the offset of a block of 2<sup>SHIFT</sup>
- * characters within <code>DATA</code>.  The DATA field, in turn, stores
- * information about each character in the low order bits, and an offset
- * into the attribute tables <code>UPPER</code>, <code>LOWER</code>,
- * <code>NUM_VALUE</code>, and <code>DIRECTION</code>.  Notice that the
- * attribute tables are much smaller than 0xffff entries; as many characters
- * in Unicode share common attributes.  The DIRECTION table also contains
- * a field for detecting characters with multi-character uppercase expansions.
- * Next, there is a listing for <code>TITLE</code> exceptions (most characters
- * just have the same title case as upper case).  Finally, there are two
- * tables for multi-character capitalization, <code>UPPER_SPECIAL</code>
- * which lists the characters which are special cased, and
- * <code>UPPER_EXPAND</code>, which lists their expansion.
- *
- * \@author scripts/unicode-muncher.pl (written by Jochen Hoenicke,
- *         Eric Blake)
- * \@see Character
- * \@see String
- */
-public interface CharData
-{
-  /**
-   * The Unicode definition file that was parsed to build this database.
-   */
-  String SOURCE = \"$ARGV[0]\";
-
-  /**
-   * The character shift amount to look up the block offset. In other words,
-   * <code>(char) (BLOCKS.value[ch >> SHIFT] + ch)</code> is the index where
-   * <code>ch</code> is described in <code>DATA</code>.
-   */
-  int SHIFT = $bestshift;
-
-  /**
-   * The mapping of character blocks to their location in <code>DATA</code>.
-   * Each entry has been adjusted so that the 16-bit sum with the desired
-   * character gives the actual index into <code>DATA</code>.
-   */
-  String BLOCKS
-EOF
-
-    for ($i = 0; $i < @blocks / 11; $i++) {
-        print OUTPUT $i ? "\n    + \"" : "    = \"";
-        for $j (0 .. 10) {
-            last if @blocks <= $i * 11 + $j;
-            my $val = $blocks[$i * 11 + $j];
-            print OUTPUT javaChar($val);
-        }
-        print OUTPUT "\"";
-    }
-
-    print OUTPUT <<EOF;
-;
-
-  /**
-   * Information about each character.  The low order 5 bits form the
-   * character type, the next bit is a flag for non-breaking spaces, and the
-   * next bit is a flag for mirrored directionality.  The high order 9 bits
-   * form the offset into the attribute tables.  Note that this limits the
-   * number of unique character attributes to 512, which is not a problem
-   * as of Unicode version 3.2.0, but may soon become one.
-   */
-  String DATA
-EOF
-
-    my $len = length($bestblkstr) / 2;
-    for ($i = 0; $i < $len / 11; $i++) {
-        print OUTPUT $i ? "\n    + \"" : "    = \"";
-        for $j (0 .. 10) {
-            last if $len <= $i * 11 + $j;
-            my $val = unpack "n", substr($bestblkstr, 2 * ($i * 11 + $j), 2);
-            print OUTPUT javaChar($val);
-        }
-        print OUTPUT "\"";
-    }
-
-    print OUTPUT <<EOF;
-;
-
-  /**
-   * This is the attribute table for computing the numeric value of a
-   * character.  The value is -1 if Unicode does not define a value, -2
-   * if the value is not a positive integer, otherwise it is the value.
-   * Note that this is a signed value, but stored as an unsigned char
-   * since this is a String literal.
-   */
-  String NUM_VALUE
-EOF
-
-    $len = @charinfo;
-    for ($i = 0; $i < $len / 11; $i++) {
-        print OUTPUT $i ? "\n    + \"" : "    = \"";
-        for $j (0 .. 10) {
-            last if $len <= $i * 11 + $j;
-            my $val = $charinfo[$i * 11 + $j][0];
-            print OUTPUT javaChar($val);
-        }
-        print OUTPUT "\"";
-    }
-
-    print OUTPUT <<EOF;
-;
-
-  /**
-   * This is the attribute table for computing the single-character uppercase
-   * representation of a character.  The value is the signed difference
-   * between the character and its uppercase version.  Note that this is
-   * stored as an unsigned char since this is a String literal.  When
-   * capitalizing a String, you must first check if a multi-character uppercase
-   * sequence exists before using this character.
-   */
-  String UPPER
-EOF
-
-    $len = @charinfo;
-    for ($i = 0; $i < $len / 11; $i++) {
-        print OUTPUT $i ? "\n    + \"" : "    = \"";
-        for $j (0 .. 10) {
-            last if $len <= $i * 11 + $j;
-            my $val = $charinfo[$i * 11 + $j][1];
-            print OUTPUT javaChar($val);
-        }
-        print OUTPUT "\"";
-    }
-
-    print OUTPUT <<EOF;
-;
-
-  /**
-   * This is the attribute table for computing the lowercase representation
-   * of a character.  The value is the signed difference between the
-   * character and its lowercase version.  Note that this is stored as an
-   * unsigned char since this is a String literal.
-   */
-  String LOWER
-EOF
-
-    $len = @charinfo;
-    for ($i = 0; $i < $len / 13; $i++) {
-        print OUTPUT $i ? "\n    + \"" : "    = \"";
-        for $j (0 .. 12) {
-            last if $len <= $i * 13 + $j;
-            my $val = $charinfo[$i * 13 + $j][2];
-            print OUTPUT javaChar($val);
-        }
-        print OUTPUT "\"";
-    }
-
-    print OUTPUT <<EOF;
-;
-
-  /**
-   * This is the attribute table for computing the directionality class
-   * of a character, as well as a marker of characters with a multi-character
-   * capitalization.  The direction is taken by performing a signed shift
-   * right by 2 (where a result of -1 means an unknown direction, such as
-   * for undefined characters). The lower 2 bits form a count of the
-   * additional characters that will be added to a String when performing
-   * multi-character uppercase expansion. This count is also used, along with
-   * the offset in UPPER_SPECIAL, to determine how much of UPPER_EXPAND to use
-   * when performing the case conversion. Note that this information is stored
-   * as an unsigned char since this is a String literal.
-   */
-  String DIRECTION
-EOF
-
-    $len = @charinfo;
-    for ($i = 0; $i < $len / 17; $i++) {
-        print OUTPUT $i ? "\n    + \"" : "    = \"";
-        for $j (0 .. 16) {
-            last if $len <= $i * 17 + $j;
-            my $val = $charinfo[$i * 17 + $j][3];
-            print OUTPUT javaChar($val);
-        }
-        print OUTPUT "\"";
-    }
-
-    print OUTPUT <<EOF;
-;
-
-  /**
-   * This is the listing of titlecase special cases (all other characters
-   * can use <code>UPPER</code> to determine their titlecase).  The listing
-   * is a sorted sequence of character pairs; converting the first character
-   * of the pair to titlecase produces the second character.
-   */
-  String TITLE
-EOF
-
-    $len = length($titlecase) / 2;
-    for ($i = 0; $i < $len / 11; $i++) {
-        print OUTPUT $i ? "\n    + \"" : "    = \"";
-        for $j (0 .. 10) {
-            last if $len <= $i * 11 + $j;
-            my $val = unpack "n", substr($titlecase, 2 * ($i * 11 + $j), 2);
-            print OUTPUT javaChar($val);
-        }
-        print OUTPUT "\"";
-    }
-
-    print OUTPUT <<EOF;
-;
-
-  /**
-   * This is a listing of characters with multi-character uppercase sequences.
-   * A character appears in this list exactly when it has a non-zero entry
-   * in the low-order 2-bit field of DIRECTION.  The listing is a sorted
-   * sequence of pairs (hence a binary search on the even elements is an
-   * efficient way to lookup a character). The first element of a pair is the
-   * character with the expansion, and the second is the index into
-   * UPPER_EXPAND where the expansion begins. Use the 2-bit field of
-   * DIRECTION to determine where the expansion ends.
-   */
-  String UPPER_SPECIAL
-EOF
-
-    my @list = sort {$a <=> $b} keys %special;
-    my $expansion = "";
-    my $offset = 0;
-    $len = @list;
-    for ($i = 0; $i < $len / 5; $i++) {
-        print OUTPUT $i ? "\n    + \"" : "    = \"";
-        for $j (0 .. 4) {
-            last if $len <= $i * 5 + $j;
-            my $ch = $list[$i * 5 + $j];
-            print OUTPUT javaChar($ch);
-            print OUTPUT javaChar($offset);
-            $offset += @{$special{$ch}};
-            $expansion .= pack "n*", @{$special{$ch}};
-        }
-        print OUTPUT "\"";
-    }
-
-    print OUTPUT <<EOF;
-;
-
-  /**
-   * This is the listing of special case multi-character uppercase sequences.
-   * Characters listed in UPPER_SPECIAL index into this table to find their
-   * uppercase expansion. Remember that you must also perform special-casing
-   * on two single-character sequences in the Turkish locale, which are not
-   * covered here in CharData.
-   */
-  String UPPER_EXPAND
-EOF
-
-    $len = length($expansion) / 2;
-    for ($i = 0; $i < $len / 11; $i++) {
-        print OUTPUT $i ? "\n    + \"" : "    = \"";
-        for $j (0 .. 10) {
-            last if $len <= $i * 11 + $j;
-            my $val = unpack "n", substr($expansion, 2 * ($i * 11 + $j), 2);
-            print OUTPUT javaChar($val);
-        }
-        print OUTPUT "\"";
-    }
-
-    print OUTPUT ";\n}\n";
-    close OUTPUT;
-}
-print "\nDone.\n";
Index: libjava/scripts/MakeCharTables.java
===================================================================
--- libjava/scripts/MakeCharTables.java	(revision 112066)
+++ libjava/scripts/MakeCharTables.java	(working copy)
@@ -1,212 +0,0 @@
-/* MakeCharTables.java - converts gnu.java.lang.CharData into
-                         include/java-chartables.h
-   Copyright (C) 2002 Free Software Foundation, Inc.
-
-This file is part of GNU Classpath.
-
-GNU Classpath is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU Classpath is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Classpath; see the file COPYING.  If not, write to the
-Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301 USA.
-
-Linking this library statically or dynamically with other modules is
-making a combined work based on this library.  Thus, the terms and
-conditions of the GNU General Public License cover the whole
-combination.
-
-As a special exception, the copyright holders of this library give you
-permission to link this library with independent modules to produce an
-executable, regardless of the license terms of these independent
-modules, and to copy and distribute the resulting executable under
-terms of your choice, provided that you also meet, for each linked
-independent module, the terms and conditions of the license of that
-module.  An independent module is a module which is not derived from
-or based on this library.  If you modify this library, you may extend
-this exception to your version of the library, but you are not
-obligated to do so.  If you do not wish to do so, delete this
-exception statement from your version. */
-
-import gnu.java.lang.CharData;
-
-public class MakeCharTables implements CharData
-{
-  public static void main(String[] args)
-  {
-    System.out.println("/* java-chartables.h -- Character tables for java.lang.Character -*- c++ -*-\n"
-                       + "   Copyright (C) 2002 Free Software Foundation, Inc.\n"
-                       + "   *** This file is generated by scripts/MakeCharTables.java ***\n"
-                       + "\n"
-                       + "This file is part of GNU Classpath.\n"
-                       + "\n"
-                       + "GNU Classpath is free software; you can redistribute it and/or modify\n"
-                       + "it under the terms of the GNU General Public License as published by\n"
-                       + "the Free Software Foundation; either version 2, or (at your option)\n"
-                       + "any later version.\n"
-                       + "\n"
-                       + "GNU Classpath is distributed in the hope that it will be useful, but\n"
-                       + "WITHOUT ANY WARRANTY; without even the implied warranty of\n"
-                       + "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n"
-                       + "General Public License for more details.\n"
-                       + "\n"
-                       + "You should have received a copy of the GNU General Public License\n"
-                       + "along with GNU Classpath; see the file COPYING.  If not, write to the\n"
-                       + "Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\n"
-                       + "02110-1301 USA.\n"
-                       + "\n"
-                       + "Linking this library statically or dynamically with other modules is\n"
-                       + "making a combined work based on this library.  Thus, the terms and\n"
-                       + "conditions of the GNU General Public License cover the whole\n"
-                       + "combination.\n"
-                       + "\n"
-                       + "As a special exception, the copyright holders of this library give you\n"
-                       + "permission to link this library with independent modules to produce an\n"
-                       + "executable, regardless of the license terms of these independent\n"
-                       + "modules, and to copy and distribute the resulting executable under\n"
-                       + "terms of your choice, provided that you also meet, for each linked\n"
-                       + "independent module, the terms and conditions of the license of that\n"
-                       + "module.  An independent module is a module which is not derived from\n"
-                       + "or based on this library.  If you modify this library, you may extend\n"
-                       + "this exception to your version of the library, but you are not\n"
-                       + "obligated to do so.  If you do not wish to do so, delete this\n"
-                       + "exception statement from your version. */\n"
-                       + "\n"
-                       + "#ifndef __JAVA_CHARTABLES_H__\n"
-                       + "#define __JAVA_CHARTABLES_H__\n"
-                       + "\n"
-                       + "// These tables are automatically generated by scripts/MakeCharTables.java.\n"
-                       + "// This is in turn parsing gnu.java.lang.CharData, which is generated by\n"
-                       + "// scripts/unicode-muncher.pl.  The Unicode data comes from\n"
-                       + "// www.unicode.org; this header is based on\n"
-                       + "// " + SOURCE + ". JDK 1.4 uses Unicode version 3.0.0.\n"
-                       + "// DO NOT EDIT the tables.  Instead, fix the upstream scripts and run\n"
-                       + "// them again.\n"
-                       + "\n"
-                       + "// The data is stored in C style arrays of the appropriate CNI types, to\n"
-                       + "// guarantee that the data is constant and non-relocatable.  The field\n"
-                       + "// <code>blocks</code> stores the offset of a block of 2<supSHIFT</sup>\n"
-                       + "// characters within <code>data</code>. The data field, in turn, stores\n"
-                       + "// information about each character in the low order bits, and an offset\n"
-                       + "// into the attribute tables <code>upper</code>, <code>lower</code>,\n"
-                       + "// <code>numValue</code>, and <code>direction</code>.  Notice that the\n"
-                       + "// attribute tables are much smaller than 0xffff entries; as many characters\n"
-                       + "// in Unicode share common attributes.  Finally, there is a listing for\n"
-                       + "// <code>title</code> exceptions (most characters just have the same title\n"
-                       + "// case as upper case).\n"
-                       + "\n"
-                       + "// This file should only be included by natCharacter.cc\n"
-                       + "\n"
-                       + "/**\n"
-                       + " * The character shift amount to look up the block offset. In other words,\n"
-                       + " * <code>(char) (blocks[ch >> SHIFT] + ch)</code> is the index where\n"
-                       + " * <code>ch</code> is described in <code>data</code>.\n"
-                       + " */\n"
-                       + "#define SHIFT " + SHIFT);
-
-    convertString("/**\n"
-                  + " * The mapping of character blocks to their location in <code>data</code>.\n"
-                  + " * Each entry has been adjusted so that a modulo 16 sum with the desired\n"
-                  + " * character gives the actual index into <code>data</code>.\n"
-                  + " */",
-                  char.class, "blocks", BLOCKS);
-
-    convertString("/**\n"
-                  + " * Information about each character.  The low order 5 bits form the\n"
-                  + " * character type, the next bit is a flag for non-breaking spaces, and the\n"
-                  + " * next bit is a flag for mirrored directionality.  The high order 9 bits\n"
-                  + " * form the offset into the attribute tables.  Note that this limits the\n"
-                  + " * number of unique character attributes to 512, which is not a problem\n"
-                  + " * as of Unicode version 3.2.0, but may soon become one.\n"
-                  + " */",
-                  char.class, "data", DATA);
-
-    convertString("/**\n"
-                  + " * This is the attribute table for computing the numeric value of a\n"
-                  + " * character.  The value is -1 if Unicode does not define a value, -2\n"
-                  + " * if the value is not a positive integer, otherwise it is the value.\n"
-                  + " */",
-                  short.class, "numValue", NUM_VALUE);
-
-    convertString("/**\n"
-                  + " * This is the attribute table for computing the uppercase representation\n"
-                  + " * of a character.  The value is the difference between the character and\n"
-                  + " * its uppercase version.\n"
-                  + " */",
-                  short.class, "upper", UPPER);
-
-    convertString("/**\n"
-                  + " * This is the attribute table for computing the lowercase representation\n"
-                  + " * of a character.  The value is the difference between the character and\n"
-                  + " * its lowercase version.\n"
-                  + " */",
-                  short.class, "lower", LOWER);
-
-    convertString("/**\n"
-                  + " * This is the attribute table for computing the directionality class\n"
-                  + " * of a character.  At present, the value is in the range 0 - 18 if the\n"
-                  + " * character has a direction, otherwise it is -1.\n"
-                  + " */",
-                  byte.class, "direction", DIRECTION);
-
-    convertString("/**\n"
-                  + " * This is the listing of titlecase special cases (all other character\n"
-                  + " * can use <code>upper</code> to determine their titlecase).  The listing\n"
-                  + " * is a sequence of character pairs; converting the first character of the\n"
-                  + " * pair to titlecase produces the second character.\n"
-                  + " */",
-                  char.class, "title", TITLE);
-
-    System.out.println();
-    System.out.println("#endif /* __JAVA_CHARTABLES_H__ */");
-  }
-
-  private static void convertString(String header, Class type,
-                                    String name, String field)
-  {
-    System.out.println();
-    System.out.println(header);
-    System.out.println("static const j" + type.getName() + " " + name
-                       + "[] = {");
-    char[] data = field.toCharArray();
-    int wrap;
-    if (type == char.class)
-      wrap = 10;
-    else if (type == byte.class)
-      wrap = 21;
-    else if (type == short.class)
-      wrap = 13;
-    else
-      throw new Error("Unexpeced type");
-    for (int i = 0; i < data.length; i += wrap)
-      {
-        System.out.print("   ");
-        for (int j = 0; j < wrap; j++)
-          {
-            if (i + j >= data.length)
-              break;
-            System.out.print(" ");
-            if (type == char.class)
-              System.out.print((int) data[i + j]);
-            else if (type == byte.class)
-              System.out.print((byte) data[i + j]);
-            else if (type == short.class)
-              System.out.print((short) data[i + j]);
-            System.out.print(",");
-          }
-        System.out.println();
-      }
-    System.out.println("  };\n"
-                       + "/** Length of " + name + ". */\n"
-                       + "static const int " + name + "_length = "
-                       + data.length + ";");
-  }
-}
Index: libjava/scripts/unicode-to-chartables.pl
===================================================================
--- libjava/scripts/unicode-to-chartables.pl	(revision 0)
+++ libjava/scripts/unicode-to-chartables.pl	(revision 0)
@@ -0,0 +1,802 @@
+#!/usr/bin/perl -w
+# unicode-to-chartables.pl -- generate Unicode database for java.lang.Character
+# Copyright (C) 1998, 2002, 2004, 2006  Free Software Foundation, Inc.
+#
+# This file is part of GNU Classpath.
+#
+# GNU Classpath is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Classpath is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Classpath; see the file COPYING.  If not, write to the
+# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 USA.
+#
+# Linking this library statically or dynamically with other modules is
+# making a combined work based on this library.  Thus, the terms and
+# conditions of the GNU General Public License cover the whole
+# combination.
+#
+# As a special exception, the copyright holders of this library give you
+# permission to link this library with independent modules to produce an
+# executable, regardless of the license terms of these independent
+# modules, and to copy and distribute the resulting executable under
+# terms of your choice, provided that you also meet, for each linked
+# independent module, the terms and conditions of the license of that
+# module.  An independent module is a module which is not derived from
+# or based on this library.  If you modify this library, you may extend
+# this exception to your version of the library, but you are not
+# obligated to do so.  If you do not wish to do so, delete this
+# exception statement from your version.
+
+# Code for reading UnicodeData-4.0.0.txt and SpecialCasing-4.0.0.txt to generate
+# the code for java-chartables.h. The relevant files can be found here:
+#
+#   http://www.unicode.org/Public/4.0-Update/UnicodeData-4.0.0.txt
+#   http://www.unicode.org/Public/4.0-Update/SpecialCasing-4.0.0.txt
+#
+# Inspired by code from Jochen Hoenicke.
+# author Eric Blake <ebb9@email.byu.edu>
+# Unicode 4.0.0 support by Anthony Balkissoon <abalkiss@redhat.com>
+#
+# Usage: ./unicode-to-chartables.pl <UnicodeData> <SpecialCasing> <tables>
+#   where <UnicodeData.txt> is obtained from www.unicode.org (named
+#   UnicodeData-4.0.0.txt for Unicode version 4.0.0), <SpecialCasing>
+#   is obtained from www.unicode too (named SpecialCasing-4.0.0.txt for Unicode
+#   version 4.0.0), and <tables> is the final location for the header file
+#   java-chartables.h. As of JDK 1.5, use Unicode version 4.0.0
+#   for best results.
+
+
+##
+## Return the given variable interpreted as a 16 bit signed number.
+##
+sub cShort($) {
+    my ($char) = @_;
+    return unpack "s", pack "I", $char;
+}
+
+##
+## Convert the text UnicodeData file from www.unicode.org into a header file
+## interface with arrays holding the compressed information.
+##
+my @TYPECODES = qw(Cn Lu Ll Lt Lm Lo Mn Me Mc Nd Nl No Zs Zl Zp Cc Cf
+                   SKIPPED Co Cs Pd Ps Pe Pc Po Sm Sc Sk So Pi Pf);
+my @DIRCODES = qw(L R AL EN ES ET AN CS NSM BN B S WS ON LRE LRO RLE RLO PDF);
+
+my $NOBREAK_FLAG  = 32;
+my $MIRRORED_FLAG = 64;
+
+my %special = ();
+
+# infoArray is an array where each element is a list of character information
+# for characters in a plane.  The index of each list is equal to the plane 
+# that it corresponds to even though most of these lists will currently be
+# empty.  This is done so that that this script can be easily modified to 
+# accomodate future versions of Unicode.
+my @infoArray = \((), (), (), (), (), (), (), (), 
+    (), (), (), (), (), (), (), (), ());
+
+# info is a reference to one of the lists in infoArray, depending on which 
+# plane we're currently parsing.
+my $info;
+
+# largeNums is an array of numerical values that are too large to fit 
+# into the 16 bit char where most numerical values are stored.  
+# What is stored in the char then is a number N such that (-N - 3) is 
+# the index into largeNums where the numerical value can be found.
+my @largeNums = ();
+
+my $titlecase = "";
+my $count = 0;
+my $range = 0;
+
+die "Usage: $0 <UnicodeData.txt> <SpecialCasing.txt> <java-chartables.h>"
+    unless @ARGV == 3;
+$| = 1;
+print "GNU Classpath Unicode Attribute Database Generator 2.1\n";
+print "Copyright (C) 1998, 2002 Free Software Foundation, Inc.\n";
+
+
+################################################################################
+################################################################################
+# Stage 0: Parse the special casing file
+print "Parsing special casing file\n";
+open (SPECIAL, "< $ARGV[1]") || die "Can't open special casing file: $!\n";
+while (<SPECIAL>) {
+    next if /^\#/;
+    my ($ch, undef, undef, $upper) = split / *; */;
+
+    # This grabs only the special casing for multi-char uppercase. Note that
+    # there are no multi-char lowercase, and that Sun ignores multi-char
+    # titlecase rules. This script omits 3 special cases in Unicode 3.0.0,
+    # which must be hardcoded in java.lang.String:
+    #  \u03a3 (Sun ignores this special case)
+    #  \u0049 - lowercases to \u0131, but only in Turkish locale
+    #  \u0069 - uppercases to \u0130, but only in Turkish locale
+    next unless defined $upper and $upper =~ / /;
+    $special{hex $ch} = [map {hex} split ' ', $upper];
+}
+
+close SPECIAL;
+
+
+################################################################################
+################################################################################
+## Stage 1: Parse the attribute file
+print "Parsing attributes file";
+open (UNICODE, "< $ARGV[0]") || die "Can't open Unicode attribute file: $!\n";
+while (<UNICODE>) {
+    print "." unless $count++ % 1000;
+    chomp;
+    s/\r//g;
+    my ($ch, $name, $category, undef, $bidir, $decomp, undef, undef, $numeric,
+        $mirrored, undef, undef, $upcase, $lowcase, $title) = split ';';
+    $ch = hex($ch);
+
+    # plane tells us which Unicode code plane we're currently in and is an
+    # index into infoArray.
+    my $plane = int($ch / 0x10000);
+    my $planeBase = $plane * 0x10000;
+    $info = \@{$infoArray[$plane]};
+
+    my ($type, $numValue, $upperchar, $lowerchar, $direction);
+
+    $type = 0;
+    while ($category !~ /^$TYPECODES[$type]$/) {
+        if (++$type == @TYPECODES) {
+            die "$ch: Unknown type: $category";
+        }
+    }
+    $type |= $NOBREAK_FLAG if ($decomp =~ /noBreak/);
+    $type |= $MIRRORED_FLAG if ($mirrored =~ /Y/);
+
+    if ($numeric =~ /^[0-9]+$/) {
+        $numValue = $numeric;
+        # If numeric takes more than 16 bits to store we want to store that 
+	# number in a separate array and store a number N in numValue such 
+	# that (-N - 3) is the offset into the separate array containing the
+	# large numerical value.
+	if ($numValue >= 0x7fff) {
+	    $numValue = -3 - @largeNums;
+	    push @largeNums, $numeric;	    
+	}
+    } elsif ($numeric eq "") {
+        # Special case sequences of 'a'-'z'
+        if ($ch >= 0x0041 && $ch <= 0x005a) {
+            $numValue = $ch - 0x0037;
+        } elsif ($ch >= 0x0061 && $ch <= 0x007a) {
+            $numValue = $ch - 0x0057;
+        } elsif ($ch >= 0xff21 && $ch <= 0xff3a) {
+            $numValue = $ch - 0xff17;
+        } elsif ($ch >= 0xff41 && $ch <= 0xff5a) {
+            $numValue = $ch - 0xff37;
+        } else {
+            $numValue = -1;
+        }
+    } else {
+        $numValue = -2;
+    }
+
+    $upperchar = $upcase ? hex($upcase) - $ch : 0;
+    $lowerchar = $lowcase ? hex($lowcase) - $ch : 0;
+    if ($title ne $upcase) {
+        my $titlechar = $title ? hex($title) : $ch;
+        $titlecase .= pack("n2", $ch, $titlechar);
+    }
+
+    $direction = 0;
+    while ($bidir !~ /^$DIRCODES[$direction]$/) {
+        if (++$direction == @DIRCODES) {
+            $direction = -1;
+            last;
+        }
+    }
+    $direction <<= 2;
+    $direction += $#{$special{$ch}} if defined $special{$ch};
+
+    if ($range) {
+        die "Expecting end of range at $ch\n" unless $name =~ /Last>$/;
+        for ($range + 1 .. $ch - 1) {
+            $info->[$_ - $planeBase] = pack("n5", $type, $numValue, $upperchar,
+                             $lowerchar, $direction);
+        }
+        $range = 0;
+    } elsif ($name =~ /First>$/) {
+        $range = $ch;
+    }
+    # Store all this parsed information into the element in infoArray that info
+    # points to.
+    $info->[$ch - $planeBase] = pack("n5", $type, $numValue, $upperchar, $lowerchar,
+                      $direction);
+}
+close UNICODE;
+
+
+################################################################################
+################################################################################
+## Stage 2: Compress the data structures
+printf "\nCompressing data structures";
+$count = 0;
+
+# data is a String that will be used to create the DATA String containing 
+# character information and offsets into the attribute tables.
+my @data = ();
+
+# charhashArray is an array of hashtables used so that we can reuse character
+# attributes when characters share the same attributes ... this makes our
+# attribute tables smaller.  charhash is a pointer into this array.
+my @charhashArray = ({}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {});
+my $charhash = ();
+
+# charinfoArray is an array of arrays, one per plane, for storing character 
+# information.  charinfo is a pointer into this array.
+my @charinfoArray = \((), (), (), (), (), (), (), (), 
+    (), (), (), (), (), (), (), (), ());
+my $charinfo;
+
+# charlen is an array, one element per plane, that tells us how many unique
+# character attributes there are for that plane.
+my @charlen = ();
+
+for my $plane (0 .. 0x10) {
+    $info = \@{$infoArray[$plane]};
+    my $planeBase = $plane * 0x10000;
+    $charhash = \%{$charhashArray[$plane]};
+    $charinfo = \@{$charinfoArray[$plane]};
+
+    for my $ch ($planeBase .. $planeBase + 0xffff) {
+	my $index = $ch - $planeBase;
+	print "." unless $count++ % 0x1000;
+	$info->[$index] = pack("n5", 0, -1, 0, 0, -4) unless defined $info->[$index];
+	
+	my ($type, $numVal, $upper, $lower, $direction) = unpack("n5", $info->[$index]);
+	if (! exists $charhash->{$info->[$index]}) {
+	    # If we entered this loop that means the character we're looking at 
+	    # now has attributes that are unique from those that we've looked
+	    # at so far for this plane.  So we push its attributes into charinfo
+	    # and store in charhash the offset into charinfo where these
+	    # attributes can later be found.
+	    push @{$charinfo}, [ $numVal, $upper, $lower, $direction ];
+	    $charhash->{$info->[$index]} = @{$charinfo} - 1;
+	    # When the file is generaged, the number we just stored in charhas
+	    # will be the upper 9 bits in the DATA String that are an offset
+	    # into the attribute tables.
+	}
+	$data[$plane] .= pack("n", ($charhash->{$info->[$index]} << 7) | $type);
+    }
+    $charlen[$plane] = scalar(@{$charinfoArray[$plane]});
+}
+
+# the shift that results in the best compression of the table.  This is an array
+# because different shifts are better for the different tables for each plane.
+my @bestshift;
+
+# an initial guess.
+my $bestest = 1000000;
+my @bestblkstr;
+my @blksize = ();
+
+for my $plane (0 .. 0x10) {
+    print "\n\nplane: $plane\n";
+    print "Unique character entries: $charlen[$plane]\n";
+    $bestest = 1000000;
+    for my $i (3 .. 8) {
+        my $blksize = 1 << $i;
+        my %blocks = ();
+        my @blkarray = ();
+        my ($j, $k);
+        print "shift: $i";
+
+        for ($j = 0; $j < 0x10000; $j += $blksize) {
+            my $blkkey = substr $data[$plane], 2 * $j, 2 * $blksize;
+            if (! exists $blocks{$blkkey}) {
+	        push @blkarray, $blkkey;
+                $blocks{$blkkey} = $#blkarray;
+            }
+        }
+
+        my $blknum = @blkarray;
+        my $blocklen = $blknum * $blksize;
+        printf " before %5d", $blocklen;
+
+        # Now we try to pack the blkarray as tight as possible by finding matching
+        # heads and tails.
+        for ($j = $blksize - 1; $j > 0; $j--) {
+            my %tails = ();
+            for $k (0 .. $#blkarray) {
+                next unless defined $blkarray[$k];
+                my $len = length $blkarray[$k];
+                my $tail = substr $blkarray[$k], $len - $j * 2;
+                if (exists $tails{$tail}) {
+                    push @{$tails{$tail}}, $k;
+                } else {
+                    $tails{$tail} = [ $k ];
+                }
+            }
+
+            # tails are calculated, now calculate the heads and merge.
+          BLOCK:
+            for $k (0 .. $#blkarray) {
+                next unless defined $blkarray[$k];
+                my $tomerge = $k;
+                while (1) {
+                    my $head = substr($blkarray[$tomerge], 0, $j * 2);
+                    my $entry = $tails{$head};
+                    next BLOCK unless defined $entry;
+
+                    my $other = shift @{$entry};
+                    if ($other == $tomerge) {
+                        if (@{$entry}) {
+                            push @{$entry}, $other;
+                            $other = shift @{$entry};
+                        } else {
+                            push @{$entry}, $other;
+                            next BLOCK;
+                        }
+                    }
+                    if (@{$entry} == 0) {
+                        delete $tails{$head};
+                    }
+
+                    # a match was found
+                    my $merge = $blkarray[$other]
+                        . substr($blkarray[$tomerge], $j * 2);
+                    $blocklen -= $j;
+                    $blknum--;
+
+                    if ($other < $tomerge) {
+                        $blkarray[$tomerge] = undef;
+                        $blkarray[$other] = $merge;
+                        my $len = length $merge;
+                        my $tail = substr $merge, $len - $j * 2;
+                        $tails{$tail} = [ map { $_ == $tomerge ? $other : $_ }
+                                          @{$tails{$tail}} ];
+                        next BLOCK;
+                    }
+                    $blkarray[$tomerge] = $merge;
+                    $blkarray[$other] = undef;
+                }
+            }
+        }
+        my $blockstr;
+        for $k (0 .. $#blkarray) {
+            $blockstr .= $blkarray[$k] if defined $blkarray[$k];
+        }
+
+        die "Unexpected $blocklen" if length($blockstr) != 2 * $blocklen;
+        my $estimate = 2 * $blocklen + (0x20000 >> $i);
+  
+        printf " after merge %5d: %6d bytes\n", $blocklen, $estimate;
+        if ($estimate < $bestest) {
+            $bestest = $estimate;
+            $bestshift[$plane] = $i;
+            $bestblkstr[$plane] = $blockstr;
+        }
+    }
+    $blksize[$plane] = 1 << $bestshift[$plane];
+    print "best shift: ", $bestshift[$plane];
+    print "     blksize: ", $blksize[$plane];
+}
+my @blocksArray = \((), (), (), (), (), (), (), (), 
+    (), (), (), (), (), (), (), (), ());
+
+for my $plane (0 .. 0x10) {
+    for (my $j = 0; $j < 0x10000; $j += $blksize[$plane]) {
+	my $blkkey = substr $data[$plane], 2 * $j, 2 * $blksize[$plane];
+        my $index = index $bestblkstr[$plane], $blkkey;
+        while ($index & 1) {
+            die "not found: $j" if $index == -1;
+            $index = index $bestblkstr[$plane], $blkkey, $index + 1;
+        }
+        push @{$blocksArray[$plane]}, ($index / 2 - $j) & 0xffff;
+    }
+}
+
+
+################################################################################
+################################################################################
+## Stage 3: Generate the file
+for my $plane (0 .. 0x10) {
+    die "UTF-8 limit of blocks may be exceeded for plane $plane: " . scalar(@{$blocksArray[$plane]}) . "\n"
+        if @{$blocksArray[$plane]} > 0xffff / 3;
+    die "UTF-8 limit of data may be exceeded for plane $plane: " . length($bestblkstr[$plane]) . "\n"
+        if length($bestblkstr[$plane]) > 0xffff / 3;
+}
+
+{
+    print "\nGenerating $ARGV[2].";
+    my ($i, $j);
+
+    open OUTPUT, "> $ARGV[2]" or die "Failed creating output file: $!\n";
+    print OUTPUT <<EOF;
+/* java-chartables.h -- Character tables for java.lang.Character -*- c++ -*-
+   Copyright (C) 2002, 2006 Free Software Foundation, Inc.
+   *** This file is generated by scripts/unicode-to-chartables.pl ***
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+#ifndef __JAVA_CHARTABLES_H__
+#define __JAVA_CHARTABLES_H__
+
+// These tables are automatically generated by scripts/unicode_to_chartables.pl.
+// The Unicode data comes from www.unicode.org; this header is based on
+// UnicodeData-4.0.0.txt. JDK 1.5 uses Unicode version 4.0.0.
+// DO NOT EDIT the tables.  Instead, fix the upstream scripts and run
+// them again.
+
+// The data is stored in C style arrays of the appropriate CNI types, to
+// guarantee that the data is constant and non-relocatable.  The field
+// <code>blocks</code> stores the offset of a block of 2<sup>SHIFT</sup>
+// characters within <code>data</code>. The data field, in turn, stores
+// information about each character in the low order bits, and an offset
+// into the attribute tables <code>upper</code>, <code>lower</code>,
+// <code>numValue</code>, and <code>direction</code>.  Notice that the
+// attribute tables are much smaller than 0xffff entries; as many characters
+// in Unicode share common attributes.  Finally, there is a listing for
+// <code>title</code> exceptions (most characters just have the same title
+// case as upper case).
+
+// This file should only be included by natCharacter.cc
+
+/**
+ * The array containing the numeric values that are too large to be stored as
+ * chars in NUM_VALUE.  NUM_VALUE in this case will contain a negative integer
+ * N such that LARGENUMS[-N - 3] contains the correct numeric value.
+ */
+EOF
+  print OUTPUT "static const jint largenums[] = {\n    ";
+  for ($i = 0; $i < @largeNums; $i++) {
+      print OUTPUT $largeNums[$i], ", ";
+  }
+  print OUTPUT "}";
+  print OUTPUT <<EOF;
+;
+
+/**
+ * The character shift amount to look up the block offset. In other words,
+ * <code>(char) (blocks[p][off >> SHIFT[p]] + off)</code> is the index where
+ * <code>ch</code> is described in <code>data</code>, where <code>off</code>
+ * is ch & 0xffff and <code>p</code> is the plane the character belongs to.
+ */
+EOF
+  print OUTPUT "static const int shift[] = {\n    ";
+  for ($i = 0; $i < @bestshift; $i++) {
+      print OUTPUT $bestshift[$i], ", ";
+  }
+  print OUTPUT "}";
+  print OUTPUT <<EOF;
+;
+
+/**
+ * The mapping of character blocks to their location in <code>data</code>.
+ * Each entry has been adjusted so that a modulo 16 sum with the desired
+ * character gives the actual index into <code>data</code>.
+ */
+EOF
+  for ($plane = 0; $plane <= 0x10; $plane++) {
+      # The following if statement handles the cases of unassigned planes
+      # specially so we don't waste space with unused Strings.  As of 
+      # Unicode version 4.0.0 only planes 0, 1, 2, and 14 are used.  If
+      # you are updating this script to work with a later version of 
+      # Unicode you may have to alter this if statement.
+      next if ($plane > 2 && $plane != 14) ;
+      
+      print OUTPUT "static const jchar blocks", $plane, "[] = {\n";
+      for ($i = 0; $i < @{$blocksArray[$plane]} / 10; $i++) {
+	  print OUTPUT "    ";
+	  for $j (0 .. 9) {
+	      last if @{$blocksArray[$plane]} <= $i * 10 + $j;
+	      my $val = $blocksArray[$plane]->[$i * 10 + $j];
+	      print OUTPUT $val, ", ";
+	  }
+	  print OUTPUT "\n";
+      }
+      print OUTPUT "};\n\n";
+  }
+  print OUTPUT "static const int blocks_length[] = {\n    ";
+  for ($plane = 0; $plane <= 0x10; $plane++) {
+      if ($plane > 2 && $plane != 14){
+	  print OUTPUT "-1, ";
+      }
+      else {
+	  print OUTPUT scalar(@{$blocksArray[$plane]}), ", ";
+      }
+  }
+  print OUTPUT "};\n";
+  print OUTPUT <<EOF;
+static const jchar* blocks[] = {
+    blocks0, blocks1, blocks2, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
+    NULL, NULL, NULL, NULL, blocks14, NULL, NULL};
+
+/**
+ * Information about each character.  The low order 5 bits form the
+ * character type, the next bit is a flag for non-breaking spaces, and the
+ * next bit is a flag for mirrored directionality.  The high order 9 bits
+ * form the offset into the attribute tables.  Note that this limits the
+ * number of unique character attributes per plane to 512, which is not a 
+ * problem as of Unicode version 4.0.0, but may soon become one.
+ */
+EOF
+  for ($plane = 0; $plane <= 0x10; $plane++) {
+      # The following if statement handles the cases of unassigned planes
+      # specially so we don't waste space with unused Strings.  As of 
+      # Unicode version 4.0.0 only planes 0, 1, 2, and 14 are used.  If
+      # you are updating this script to work with a later version of 
+      # Unicode you may have to alter this if statement.
+      next if ($plane > 2 && $plane != 14);
+      
+      print OUTPUT "static const jchar data", $plane, "[] = {\n";
+      my $len = length($bestblkstr[$plane]) / 2;
+      for ($i = 0; $i < $len / 10; $i++) {
+	  print OUTPUT "    ";
+	  for $j (0 .. 9) {
+	      last if $len <= $i * 10 + $j;
+	      my $val = unpack "n", substr($bestblkstr[$plane], 2 * ($i * 10 + $j), 2);
+	      print OUTPUT $val, ", ";
+	  }
+	  print OUTPUT "\n";
+      }
+      print OUTPUT "};\n\n";
+  }
+  print OUTPUT "static const int data_length[] = {\n    ";
+  for ($plane = 0; $plane <= 0x10; $plane++) {
+      if ($plane > 2 && $plane != 14){
+	  print OUTPUT "-1, ";
+      }
+      else {
+	  print OUTPUT length($bestblkstr[$plane]) / 2, ", ";
+      }
+  }
+  print OUTPUT "};\n";
+  print OUTPUT <<EOF;
+static const jchar* data[] = {
+    data0, data1, data2, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
+    NULL, NULL, NULL, NULL, data14, NULL, NULL};
+
+
+/**
+ * This is the attribute table for computing the numeric value of a
+ * character.  The value is -1 if Unicode does not define a value, -2
+ * if the value is not a positive integer, otherwise it is the value.
+ */
+EOF
+  for ($plane = 0; $plane <= 0x10; $plane++) {
+      # The following if statement handles the cases of unassigned planes
+      # specially so we don't waste space with unused Strings.  As of 
+      # Unicode version 4.0.0 only planes 0, 1, 2, and 14 are used.  If
+      # you are updating this script to work with a later version of 
+      # Unicode you may have to alter this if statement.
+      next if ($plane > 2 && $plane != 14);
+      
+      print OUTPUT "static const jshort numValue", $plane, "[] = {\n";
+      $len = @{$charinfoArray[$plane]};
+      for ($i = 0; $i < $len / 13; $i++) {
+	  print OUTPUT "    ";
+	  for $j (0 .. 12) {
+	      last if $len <= $i * 13 + $j;
+	      my $val = $charinfoArray[$plane]->[$i * 13 + $j][0];
+	      print OUTPUT cShort($val), ", ";
+	  }
+	  print OUTPUT "\n";
+      }
+      print OUTPUT "};\n\n";
+  }
+  print OUTPUT "static const int numValue_length[] = {\n    ";
+  for ($plane = 0; $plane <= 0x10; $plane++) {
+      if ($plane > 2 && $plane != 14){
+	  print OUTPUT "-1, ";
+      }
+      else {
+	  print OUTPUT scalar(@{$charinfoArray[$plane]}), ", ";
+      }
+  }
+  print OUTPUT "};\n";
+  print OUTPUT <<EOF;
+static const jshort* numValue[] = {
+    numValue0, numValue1, numValue2, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
+    NULL, NULL, NULL, NULL, numValue14, NULL, NULL};
+
+
+
+/**
+ * This is the attribute table for computing the uppercase representation
+ * of a character.  The value is the difference between the character and
+ * its uppercase version.
+ */
+EOF
+  for ($plane = 0; $plane <= 0x10; $plane++) {
+      # The following if statement handles the cases of unassigned planes
+      # specially so we don't waste space with unused Strings.  As of 
+      # Unicode version 4.0.0 only planes 0, 1, 2, and 14 are used.  If
+      # you are updating this script to work with a later version of 
+      # Unicode you may have to alter this if statement.
+      next if ($plane > 2 && $plane != 14);
+      
+      print OUTPUT "static const jshort upper", $plane, "[] = {\n";
+      $len = @{$charinfoArray[$plane]};
+      for ($i = 0; $i < $len / 13; $i++) {
+	  print OUTPUT "    ";
+	  for $j (0 .. 12) {
+	      last if $len <= $i * 13 + $j;
+	      my $val = $charinfoArray[$plane]->[$i * 13 + $j][1];
+	      print OUTPUT cShort($val), ", ";
+	  }
+	  print OUTPUT "\n";
+      }
+      print OUTPUT "};\n\n";
+  }
+  print OUTPUT "static const int upper_length[] = {\n    ";
+  for ($plane = 0; $plane <= 0x10; $plane++) {
+      if ($plane > 2 && $plane != 14){
+	  print OUTPUT "-1, ";
+      }
+      else {
+	  print OUTPUT scalar(@{$charinfoArray[$plane]}), ", ";
+      }
+  }
+  print OUTPUT "};\n";
+  print OUTPUT <<EOF;
+static const jshort* upper[] = {
+    upper0, upper1, upper2, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
+    NULL, NULL, NULL, NULL, upper14, NULL, NULL};
+
+
+/**
+ * This is the attribute table for computing the lowercase representation
+ * of a character.  The value is the difference between the character and
+ * its lowercase version.
+ */
+EOF
+  for ($plane = 0; $plane <= 0x10; $plane++) {
+      # The following if statement handles the cases of unassigned planes
+      # specially so we don't waste space with unused Strings.  As of 
+      # Unicode version 4.0.0 only planes 0, 1, 2, and 14 are used.  If
+      # you are updating this script to work with a later version of 
+      # Unicode you may have to alter this if statement.
+      next if ($plane > 2 && $plane != 14);
+      
+      print OUTPUT "static const jshort lower", $plane, "[] = {\n";
+      $len = @{$charinfoArray[$plane]};
+      for ($i = 0; $i < $len / 13; $i++) {
+	  print OUTPUT "    ";
+	  for $j (0 .. 12) {
+	      last if $len <= $i * 13 + $j;
+	      my $val = $charinfoArray[$plane]->[$i * 13 + $j][2];
+	      print OUTPUT cShort($val), ", ";
+	  }
+	  print OUTPUT "\n";
+      }
+      print OUTPUT "};\n\n";
+  }
+  print OUTPUT "static const int lower_length[] = {\n    ";
+  for ($plane = 0; $plane <= 0x10; $plane++) {
+      if ($plane > 2 && $plane != 14){
+	  print OUTPUT "-1, ";
+      }
+      else {
+	  print OUTPUT scalar(@{$charinfoArray[$plane]}), ", ";
+      }
+  }
+  print OUTPUT "};\n";
+  print OUTPUT <<EOF;
+static const jshort* lower[] = {
+    lower0, lower1, lower2, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
+    NULL, NULL, NULL, NULL, lower14, NULL, NULL};
+
+
+/**
+ * This is the attribute table for computing the directionality class
+ * of a character.  At present, the value is in the range 0 - 18 if the
+ * character has a direction, otherwise it is -1.
+ */
+EOF
+  for ($plane = 0; $plane <= 0x10; $plane++) {
+      # The following if statement handles the cases of unassigned planes
+      # specially so we don't waste space with unused Strings.  As of 
+      # Unicode version 4.0.0 only planes 0, 1, 2, and 14 are used.  If
+      # you are updating this script to work with a later version of 
+      # Unicode you may have to alter this if statement.
+      next if ($plane > 2 && $plane != 14);
+      
+      print OUTPUT "static const jbyte direction", $plane, "[] = {\n";
+      $len = @{$charinfoArray[$plane]};
+      for ($i = 0; $i < $len / 19; $i++) {
+	  print OUTPUT "    ";
+	  for $j (0 .. 18) {
+	      last if $len <= $i * 19 + $j;
+	      my $val = $charinfoArray[$plane]->[$i * 19 + $j][3];
+	      $val >>= 2;
+	      if ($val < 0 || $val > 18){
+		  $val = -1;
+	      }
+	      print OUTPUT cShort($val), ", ";
+	  }
+	  print OUTPUT "\n";
+      }
+      print OUTPUT "};\n\n";
+  }
+  print OUTPUT "static const int direction_length[] = {\n    ";
+  for ($plane = 0; $plane <= 0x10; $plane++) {
+      if ($plane > 2 && $plane != 14){
+	  print OUTPUT "-1, ";
+      }
+      else {
+	  print OUTPUT scalar(@{$charinfoArray[$plane]}), ", ";
+      }
+  }
+  print OUTPUT "};\n";
+  print OUTPUT <<EOF;
+static const jbyte* direction[] = {
+    direction0, direction1, direction2, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
+    NULL, NULL, NULL, NULL, direction14, NULL, NULL};
+
+
+/**
+ * This is the listing of titlecase special cases (all other character
+ * can use <code>upper</code> to determine their titlecase).  The listing
+ * is a sequence of character pairs; converting the first character of the
+ * pair to titlecase produces the second character.
+ */
+static const jchar title[] = {
+EOF
+
+  $len = length($titlecase) / 2;
+  for ($i = 0; $i < $len / 10; $i++) {
+      print OUTPUT $i ? "\n    " : "    ";
+      for $j (0 .. 9) {
+	  last if $len <= $i * 10 + $j;
+	  my $val = unpack "n", substr($titlecase, 2 * ($i * 10 + $j), 2);
+	  print OUTPUT $val, ", ";
+      }
+  }
+
+  print OUTPUT "\n  };";
+  print OUTPUT "\n/** Length of title. */\nstatic const int title_length = ", $len;
+  print OUTPUT <<EOF;
+;
+
+#endif /* __JAVA_CHARTABLES_H__ */
+EOF
+  close OUTPUT;
+}
+print "\nDone.\n";

Property changes on: libjava/scripts/unicode-to-chartables.pl
___________________________________________________________________
Name: svn:executable
   + *

Index: libjava/java/lang/natCharacter.cc
===================================================================
--- libjava/java/lang/natCharacter.cc	(revision 112066)
+++ libjava/java/lang/natCharacter.cc	(working copy)
@@ -45,32 +45,93 @@
 
 
 
+// These constants define the return values for characters that are unassigned
+// or reserved for private use.
+#define UNASSIGNED_TYPE 0
+#define UNASSIGNED_DIGIT -1
+#define UNASSIGNED_DIRECTION -1
+#define UNASSIGNED_NUMERIC_VALUE -1
+
+#define PRIVATE_TYPE 18
+#define PRIVATE_DIRECTION 0
+
+// The methods that take a char as an argument all have counterparts that 
+// take ints.  The ones that take chars only work for the BMP or plane 0 of the
+// Unicode standard but the ones that take ints work for all Unicode code
+// points.  However, the ones that take chars don't simply redirect the calls
+// because the BMP is by far the most used plane so saving a little time on
+// each call makes sense.
+
 jchar
 java::lang::Character::readChar(jchar ch)
 {
   // Perform 16-bit addition to find the correct entry in data.
-  return data[(jchar) (blocks[ch >> SHIFT] + ch)];
+  return data[0][(jchar) (blocks[0][ch >> shift[0]] + ch)];
 }
 
+jchar
+java::lang::Character::readCodePoint(jint codePoint)
+{
+  jint plane = codePoint >> 16;
+  jchar offset = (jchar)(codePoint & 0xffff);
+  // Be careful not to call this method with an unassigned character.  The only
+  // characters assigned as of Unicode 4.0.0 belong to planes 0, 1, 2, and 14.
+  return data[plane][(jchar) (blocks[plane][offset >> shift[plane]] + offset)];
+}
+
 jint
 java::lang::Character::getType(jchar ch)
 {
   // Perform 16-bit addition to find the correct entry in data.
-  return (jint) (data[(jchar) (blocks[ch >> SHIFT] + ch)] & TYPE_MASK);
+  return (jint) (data[0][(jchar) (blocks[0][ch >> shift[0]] + ch)] & TYPE_MASK);
 }
 
+jint
+java::lang::Character::getType(jint codePoint)
+{
+  jint plane = codePoint >> 16;
+  if (plane > 2 && plane != 14)
+    {
+      if (plane > 14 && ((codePoint & 0xffff) < 0xfffe))
+        return (jint) PRIVATE_TYPE;
+      return (jint) UNASSIGNED_TYPE;
+    }
+  jint offset = codePoint & 0xffff;
+  return (jint) 
+    (data[plane]
+     [(jchar) (blocks[plane][offset >> shift[plane]] + offset)] & TYPE_MASK);
+}
+
 jchar
 java::lang::Character::toLowerCase(jchar ch)
 {
-  return (jchar) (ch + lower[readChar(ch) >> 7]);
+  return (jchar) (ch + lower[0][readChar(ch) >> 7]);
 }
 
+jint
+java::lang::Character::toLowerCase(jint codePoint)
+{
+  jint plane = codePoint >> 16;
+  if (plane > 2 && plane != 14)
+    return codePoint;
+  return (lower[plane][readCodePoint(codePoint) >> 7]) + codePoint;
+}
+
 jchar
 java::lang::Character::toUpperCase(jchar ch)
 {
-  return (jchar) (ch + upper[readChar(ch) >> 7]);
+  return (jchar) (ch + upper[0][readChar(ch) >> 7]);
 }
 
+jint
+java::lang::Character::toUpperCase(jint codePoint)
+{
+  jint plane = codePoint >> 16;
+  if (plane > 2 && plane != 14)
+    return codePoint;
+  return (upper[plane][readCodePoint(codePoint) >> 7]) + codePoint;
+}
+
 jchar
 java::lang::Character::toTitleCase(jchar ch)
 {
@@ -82,6 +143,16 @@
 }
 
 jint
+java::lang::Character::toTitleCase(jint codePoint)
+{
+  // As of Unicode 4.0.0 no characters outside of plane 0 have titlecase
+  // mappings that are different from their uppercase mapping.
+  if (codePoint < 0x10000)
+    return toTitleCase((jchar)codePoint);
+  return toUpperCase(codePoint);
+}
+
+jint
 java::lang::Character::digit(jchar ch, jint radix)
 {
   if (radix < MIN_RADIX || radix > MAX_RADIX)
@@ -93,21 +164,74 @@
           | (1 << DECIMAL_DIGIT_NUMBER))))
     {
       // Signedness doesn't matter; 0xffff vs. -1 are both rejected.
-      jint digit = (jint) numValue[attr >> 7];
+      jint digit = (jint) numValue[0][attr >> 7];
       return (digit >= 0 && digit < radix) ? digit : (jint) -1;
     }
   return (jint) -1;
 }
 
 jint
+java::lang::Character::digit(jint codePoint, jint radix)
+{
+  if (radix < MIN_RADIX || radix > MAX_RADIX)
+    return (jint) -1;
+
+  jint plane = codePoint >> 16;
+  if (plane > 2 && plane != 14)
+    return UNASSIGNED_DIGIT;
+
+  jchar attr = readCodePoint(codePoint);
+  if (((1 << (attr & TYPE_MASK))
+       & ((1 << UPPERCASE_LETTER)
+          | (1 << LOWERCASE_LETTER)
+          | (1 << DECIMAL_DIGIT_NUMBER))))
+    {
+      // Signedness doesn't matter; 0xffff vs. -1 are both rejected.
+      jint digit = (jint) numValue[plane][attr >> 7];
+      if (digit <= -3)
+        digit = largenums[-digit -3];
+      return (digit >= 0 && digit < radix) ? digit : (jint) -1;
+    }
+  return (jint) -1;
+
+}
+
+jint
 java::lang::Character::getNumericValue(jchar ch)
 {
   // numValue is stored as an array of jshort, since 10000 is the maximum.
-  return (jint) numValue[readChar(ch) >> 7];
+  return (jint) numValue[0][readChar(ch) >> 7];
 }
 
+jint
+java::lang::Character::getNumericValue(jint codePoint)
+{
+  jint plane = codePoint >> 16;
+  if (plane > 2 && plane != 14)
+    return UNASSIGNED_NUMERIC_VALUE;
+  jshort num = numValue[plane][readCodePoint(codePoint) >> 7];
+  if (num <= -3)
+    return largenums[-num - 3];
+  return num;
+}
+
 jbyte
 java::lang::Character::getDirectionality(jchar ch)
 {
-  return direction[readChar(ch) >> 7];
+  return direction[0][readChar(ch) >> 7];
 }
+
+jbyte
+java::lang::Character::getDirectionality(jint codePoint)
+{
+  jint plane = codePoint >> 16;
+  if (plane > 2 && plane != 14)
+    {
+      if (plane > 14 && ((codePoint & 0xffff) < 0xfffe))
+        return (jint) PRIVATE_DIRECTION;
+      return (jint) UNASSIGNED_DIRECTION;
+    }
+  return direction[plane][readCodePoint(codePoint) >> 7];
+}
+
+
Index: libjava/java/lang/Character.java
===================================================================
--- libjava/java/lang/Character.java	(revision 112066)
+++ libjava/java/lang/Character.java	(working copy)
@@ -2169,6 +2169,21 @@
   private static native char readChar(char ch);
 
   /**
+   * Grabs an attribute offset from the Unicode attribute database. The lower
+   * 5 bits are the character type, the next 2 bits are flags, and the top
+   * 9 bits are the offset into the attribute tables. Note that the top 9
+   * bits are meaningless in this context; they are useful only in the native
+   * code.
+   *
+   * @param codePoint the character to look up
+   * @return the character's attribute offset and type
+   * @see #TYPE_MASK
+   * @see #NO_BREAK_MASK
+   * @see #MIRROR_MASK
+   */
+  private static native char readCodePoint(int codePoint);
+
+  /**
    * Wraps up a character.
    *
    * @param value the character to wrap
@@ -2257,6 +2272,26 @@
   }
 
   /**
+   * Determines if a character is a Unicode lowercase letter. For example,
+   * <code>'a'</code> is lowercase.  Unlike isLowerCase(char), this method
+   * supports supplementary Unicode code points.
+   * <br>
+   * lowercase = [Ll]
+   *
+   * @param codePoint character to test
+   * @return true if codePoint is a Unicode lowercase letter, else false
+   * @see #isUpperCase(int)
+   * @see #isTitleCase(int)
+   * @see #toLowerCase(int)
+   * @see #getType(int)
+   * @since 1.5
+   */
+  public static boolean isLowerCase(int codePoint)
+  {
+    return getType(codePoint) == LOWERCASE_LETTER;
+  }
+
+  /**
    * Determines if a character is a Unicode uppercase letter. For example,
    * <code>'A'</code> is uppercase.
    * <br>
@@ -2275,6 +2310,26 @@
   }
 
   /**
+   * Determines if a character is a Unicode uppercase letter. For example,
+   * <code>'A'</code> is uppercase.  Unlike isUpperCase(char), this method
+   * supports supplementary Unicode code points.
+   * <br>
+   * uppercase = [Lu]
+   *
+   * @param codePoint character to test
+   * @return true if codePoint is a Unicode uppercase letter, else false
+   * @see #isLowerCase(int)
+   * @see #isTitleCase(int)
+   * @see #toUpperCase(int)
+   * @see #getType(int)
+   * @since 1.5
+   */
+  public static boolean isUpperCase(int codePoint)
+  {
+    return getType(codePoint) == UPPERCASE_LETTER;
+  }
+
+  /**
    * Determines if a character is a Unicode titlecase letter. For example,
    * the character "Lj" (Latin capital L with small letter j) is titlecase.
    * <br>
@@ -2293,6 +2348,27 @@
   }
 
   /**
+   * Determines if a character is a Unicode titlecase letter. For example,
+   * the character "Lj" (Latin capital L with small letter j) is titlecase.
+   * Unlike isTitleCase(char), this method supports supplementary Unicode
+   * code points.
+   * <br>
+   * titlecase = [Lt]
+   *
+   * @param codePoint character to test
+   * @return true if codePoint is a Unicode titlecase letter, else false
+   * @see #isLowerCase(int)
+   * @see #isUpperCase(int)
+   * @see #toTitleCase(int)
+   * @see #getType(int)
+   * @since 1.5
+   */
+  public static boolean isTitleCase(int codePoint)
+  {
+    return getType(codePoint) == TITLECASE_LETTER;
+  }
+
+  /**
    * Determines if a character is a Unicode decimal digit. For example,
    * <code>'0'</code> is a digit.
    * <br>
@@ -2310,6 +2386,25 @@
   }
 
   /**
+   * Determines if a character is a Unicode decimal digit. For example,
+   * <code>'0'</code> is a digit.  Unlike isDigit(char), this method
+   * supports supplementary Unicode code points.
+   * <br>
+   * Unicode decimal digit = [Nd]
+   *
+   * @param codePoint character to test
+   * @return true if ccodePoint is a Unicode decimal digit, else false
+   * @see #digit(int, int)
+   * @see #forDigit(int, int)
+   * @see #getType(int)
+   * @since 1.5
+   */
+  public static boolean isDigit(int codePoint)
+  {
+    return getType(codePoint) == DECIMAL_DIGIT_NUMBER;
+  }
+
+  /**
    * Determines if a character is part of the Unicode Standard. This is an
    * evolving standard, but covers every character in the data file.
    * <br>
@@ -2330,6 +2425,28 @@
   }
 
   /**
+   * Determines if a character is part of the Unicode Standard. This is an
+   * evolving standard, but covers every character in the data file.  Unlike
+   * isDefined(char), this method supports supplementary Unicode code points.
+   * <br>
+   * defined = not [Cn]
+   *
+   * @param codePoint character to test
+   * @return true if codePoint is a Unicode character, else false
+   * @see #isDigit(int)
+   * @see #isLetter(int)
+   * @see #isLetterOrDigit(int)
+   * @see #isLowerCase(int)
+   * @see #isTitleCase(int)
+   * @see #isUpperCase(int)
+   * @since 1.5
+   */
+  public static boolean isDefined(int codePoint)
+  {
+    return getType(codePoint) != UNASSIGNED;
+  }
+
+  /**
    * Determines if a character is a Unicode letter. Not all letters have case,
    * so this may return true when isLowerCase and isUpperCase return false.
    * <br>
@@ -2358,6 +2475,37 @@
   }
 
   /**
+   * Determines if a character is a Unicode letter. Not all letters have case,
+   * so this may return true when isLowerCase and isUpperCase return false.
+   * Unlike isLetter(char), this method supports supplementary Unicode code
+   * points.
+   * <br>
+   * letter = [Lu]|[Ll]|[Lt]|[Lm]|[Lo]
+   *
+   * @param codePoint character to test
+   * @return true if codePoint is a Unicode letter, else false
+   * @see #isDigit(int)
+   * @see #isJavaIdentifierStart(int)
+   * @see #isJavaLetter(int)
+   * @see #isJavaLetterOrDigit(int)
+   * @see #isLetterOrDigit(int)
+   * @see #isLowerCase(int)
+   * @see #isTitleCase(int)
+   * @see #isUnicodeIdentifierStart(int)
+   * @see #isUpperCase(int)
+   * @since 1.5
+   */
+  public static boolean isLetter(int codePoint)
+  {
+    return ((1 << getType(codePoint))
+            & ((1 << UPPERCASE_LETTER)
+               | (1 << LOWERCASE_LETTER)
+               | (1 << TITLECASE_LETTER)
+               | (1 << MODIFIER_LETTER)
+               | (1 << OTHER_LETTER))) != 0;
+  }
+
+  /**
    * Determines if a character is a Unicode letter or a Unicode digit. This
    * is the combination of isLetter and isDigit.
    * <br>
@@ -2384,6 +2532,34 @@
   }
 
   /**
+   * Determines if a character is a Unicode letter or a Unicode digit. This
+   * is the combination of isLetter and isDigit.  Unlike isLetterOrDigit(char),
+   * this method supports supplementary Unicode code points.
+   * <br>
+   * letter or digit = [Lu]|[Ll]|[Lt]|[Lm]|[Lo]|[Nd]
+   *
+   * @param codePoint character to test
+   * @return true if codePoint is a Unicode letter or a Unicode digit, else false
+   * @see #isDigit(int)
+   * @see #isJavaIdentifierPart(int)
+   * @see #isJavaLetter(int)
+   * @see #isJavaLetterOrDigit(int)
+   * @see #isLetter(int)
+   * @see #isUnicodeIdentifierPart(int)
+   * @since 1.5
+   */
+  public static boolean isLetterOrDigit(int codePoint)
+  {
+    return ((1 << getType(codePoint)
+            & ((1 << UPPERCASE_LETTER)
+               | (1 << LOWERCASE_LETTER)
+               | (1 << TITLECASE_LETTER)
+               | (1 << MODIFIER_LETTER)
+               | (1 << OTHER_LETTER)
+               | (1 << DECIMAL_DIGIT_NUMBER))) != 0);
+  }
+
+  /**
    * Determines if a character can start a Java identifier. This is the
    * combination of isLetter, any character where getType returns
    * LETTER_NUMBER, currency symbols (like '$'), and connecting punctuation
@@ -2405,6 +2581,35 @@
   }
 
   /**
+   * Determines if a character can start a Java identifier. This is the
+   * combination of isLetter, any character where getType returns
+   * LETTER_NUMBER, currency symbols (like '$'), and connecting punctuation
+   * (like '_'). Unlike isJavaIdentifierStart(char), this method supports
+   * supplementary Unicode code points.
+   * <br>
+   * Java identifier start = [Lu]|[Ll]|[Lt]|[Lm]|[Lo]|[Nl]|[Sc]|[Pc]
+   *
+   * @param codePoint character to test
+   * @return true if codePoint can start a Java identifier, else false
+   * @see #isJavaIdentifierPart(int)
+   * @see #isLetter(int)
+   * @see #isUnicodeIdentifierStart(int)
+   * @since 1.5
+   */
+  public static boolean isJavaIdentifierStart(int codePoint)
+  {
+    return ((1 << getType(codePoint))
+            & ((1 << UPPERCASE_LETTER)
+               | (1 << LOWERCASE_LETTER)
+               | (1 << TITLECASE_LETTER)
+               | (1 << MODIFIER_LETTER)
+               | (1 << OTHER_LETTER)
+               | (1 << LETTER_NUMBER)
+               | (1 << CURRENCY_SYMBOL)
+               | (1 << CONNECTOR_PUNCTUATION))) != 0;
+  }
+
+  /**
    * Determines if a character can follow the first letter in
    * a Java identifier.  This is the combination of isJavaLetter (isLetter,
    * type of LETTER_NUMBER, currency, connecting punctuation) and digit,
@@ -2494,6 +2699,45 @@
   }
 
   /**
+   * Determines if a character can follow the first letter in
+   * a Java identifier.  This is the combination of isJavaLetter (isLetter,
+   * type of LETTER_NUMBER, currency, connecting punctuation) and digit,
+   * numeric letter (like Roman numerals), combining marks, non-spacing marks,
+   * or isIdentifierIgnorable. Unlike isJavaIdentifierPart(char), this method
+   * supports supplementary Unicode code points.
+   * <br>
+   * Java identifier extender =
+   *   [Lu]|[Ll]|[Lt]|[Lm]|[Lo]|[Nl]|[Sc]|[Pc]|[Mn]|[Mc]|[Nd]|[Cf]
+   *   |U+0000-U+0008|U+000E-U+001B|U+007F-U+009F
+   *
+   * @param codePoint character to test
+   * @return true if codePoint can follow the first letter in a Java identifier
+   * @see #isIdentifierIgnorable(int)
+   * @see #isJavaIdentifierStart(int)
+   * @see #isLetterOrDigit(int)
+   * @see #isUnicodeIdentifierPart(int)
+   * @since 1.5
+   */
+  public static boolean isJavaIdentifierPart(int codePoint)
+  {
+    int category = getType(codePoint);
+    return ((1 << category)
+            & ((1 << UPPERCASE_LETTER)
+               | (1 << LOWERCASE_LETTER)
+               | (1 << TITLECASE_LETTER)
+               | (1 << MODIFIER_LETTER)
+               | (1 << OTHER_LETTER)
+               | (1 << NON_SPACING_MARK)
+               | (1 << COMBINING_SPACING_MARK)
+               | (1 << DECIMAL_DIGIT_NUMBER)
+               | (1 << LETTER_NUMBER)
+               | (1 << CURRENCY_SYMBOL)
+               | (1 << CONNECTOR_PUNCTUATION)
+               | (1 << FORMAT))) != 0
+      || (category == CONTROL && isIdentifierIgnorable(codePoint));
+  }
+
+  /**
    * Determines if a character can start a Unicode identifier.  Only
    * letters can start a Unicode identifier, but this includes characters
    * in LETTER_NUMBER.
@@ -2519,6 +2763,32 @@
   }
 
   /**
+   * Determines if a character can start a Unicode identifier.  Only
+   * letters can start a Unicode identifier, but this includes characters
+   * in LETTER_NUMBER.  Unlike isUnicodeIdentifierStart(char), this method
+   * supports supplementary Unicode code points.
+   * <br>
+   * Unicode identifier start = [Lu]|[Ll]|[Lt]|[Lm]|[Lo]|[Nl]
+   *
+   * @param codePoint character to test
+   * @return true if codePoint can start a Unicode identifier, else false
+   * @see #isJavaIdentifierStart(int)
+   * @see #isLetter(int)
+   * @see #isUnicodeIdentifierPart(int)
+   * @since 1.5
+   */
+  public static boolean isUnicodeIdentifierStart(int codePoint)
+  {
+    return ((1 << getType(codePoint))
+            & ((1 << UPPERCASE_LETTER)
+               | (1 << LOWERCASE_LETTER)
+               | (1 << TITLECASE_LETTER)
+               | (1 << MODIFIER_LETTER)
+               | (1 << OTHER_LETTER)
+               | (1 << LETTER_NUMBER))) != 0;
+  }
+
+  /**
    * Determines if a character can follow the first letter in
    * a Unicode identifier. This includes letters, connecting punctuation,
    * digits, numeric letters, combining marks, non-spacing marks, and
@@ -2555,6 +2825,44 @@
   }
 
   /**
+   * Determines if a character can follow the first letter in
+   * a Unicode identifier. This includes letters, connecting punctuation,
+   * digits, numeric letters, combining marks, non-spacing marks, and
+   * isIdentifierIgnorable.  Unlike isUnicodeIdentifierPart(char), this method
+   * supports supplementary Unicode code points.
+   * <br>
+   * Unicode identifier extender =
+   *   [Lu]|[Ll]|[Lt]|[Lm]|[Lo]|[Nl]|[Mn]|[Mc]|[Nd]|[Pc]|[Cf]|
+   *   |U+0000-U+0008|U+000E-U+001B|U+007F-U+009F
+   *
+   * @param codePoint character to test
+   * @return true if codePoint can follow the first letter in a Unicode 
+   *         identifier
+   * @see #isIdentifierIgnorable(int)
+   * @see #isJavaIdentifierPart(int)
+   * @see #isLetterOrDigit(int)
+   * @see #isUnicodeIdentifierStart(int)
+   * @since 1.5
+   */
+  public static boolean isUnicodeIdentifierPart(int codePoint)
+  {
+    int category = getType(codePoint);
+    return ((1 << category)
+            & ((1 << UPPERCASE_LETTER)
+               | (1 << LOWERCASE_LETTER)
+               | (1 << TITLECASE_LETTER)
+               | (1 << MODIFIER_LETTER)
+               | (1 << OTHER_LETTER)
+               | (1 << NON_SPACING_MARK)
+               | (1 << COMBINING_SPACING_MARK)
+               | (1 << DECIMAL_DIGIT_NUMBER)
+               | (1 << LETTER_NUMBER)
+               | (1 << CONNECTOR_PUNCTUATION)
+               | (1 << FORMAT))) != 0
+      || (category == CONTROL && isIdentifierIgnorable(codePoint));
+  }
+
+  /**
    * Determines if a character is ignorable in a Unicode identifier. This
    * includes the non-whitespace ISO control characters (<code>'\u0000'</code>
    * through <code>'\u0008'</code>, <code>'\u000E'</code> through
@@ -2578,6 +2886,32 @@
   }
 
   /**
+   * Determines if a character is ignorable in a Unicode identifier. This
+   * includes the non-whitespace ISO control characters (<code>'\u0000'</code>
+   * through <code>'\u0008'</code>, <code>'\u000E'</code> through
+   * <code>'\u001B'</code>, and <code>'\u007F'</code> through
+   * <code>'\u009F'</code>), and FORMAT characters.  Unlike 
+   * isIdentifierIgnorable(char), this method supports supplementary Unicode
+   * code points.
+   * <br>
+   * Unicode identifier ignorable = [Cf]|U+0000-U+0008|U+000E-U+001B
+   *    |U+007F-U+009F
+   *
+   * @param codePoint character to test
+   * @return true if codePoint is ignorable in a Unicode or Java identifier
+   * @see #isJavaIdentifierPart(int)
+   * @see #isUnicodeIdentifierPart(int)
+   * @since 1.5
+   */
+  public static boolean isIdentifierIgnorable(int codePoint)
+  {
+    return ((codePoint >= 0 && codePoint <= 0x0008)
+        || (codePoint >= 0x000E && codePoint <= 0x001B)
+        || (codePoint >= 0x007F && codePoint <= 0x009F)
+            || getType(codePoint) == FORMAT);
+  }
+
+  /**
    * Converts a Unicode character into its lowercase equivalent mapping.
    * If a mapping does not exist, then the character passed is returned.
    * Note that isLowerCase(toLowerCase(ch)) does not always return true.
@@ -2593,6 +2927,24 @@
   public static native char toLowerCase(char ch);
 
   /**
+   * Converts a Unicode character into its lowercase equivalent mapping.
+   * If a mapping does not exist, then the character passed is returned.
+   * Note that isLowerCase(toLowerCase(codePoint)) does not always return true.
+   * Unlike toLowerCase(char), this method supports supplementary Unicode
+   * code points.
+   *
+   * @param codePoint character to convert to lowercase
+   * @return lowercase mapping of codePoint, or codePoint if lowercase 
+   *         mapping does not exist
+   * @see #isLowerCase(int)
+   * @see #isUpperCase(int)
+   * @see #toTitleCase(int)
+   * @see #toUpperCase(int)
+   * @since 1.5
+   */
+  public static native int toLowerCase(int codePoint);
+
+  /**
    * Converts a Unicode character into its uppercase equivalent mapping.
    * If a mapping does not exist, then the character passed is returned.
    * Note that isUpperCase(toUpperCase(ch)) does not always return true.
@@ -2608,6 +2960,24 @@
   public static native char toUpperCase(char ch);
 
   /**
+   * Converts a Unicode character into its uppercase equivalent mapping.
+   * If a mapping does not exist, then the character passed is returned.
+   * Note that isUpperCase(toUpperCase(codePoint)) does not always return true.
+   * Unlike toUpperCase(char), this method supports supplementary 
+   * Unicode code points.
+   *
+   * @param codePoint character to convert to uppercase
+   * @return uppercase mapping of codePoint, or codePoint if uppercase 
+   *         mapping does not exist
+   * @see #isLowerCase(int)
+   * @see #isUpperCase(int)
+   * @see #toLowerCase(int)
+   * @see #toTitleCase(int)
+   * @since 1.5
+   */
+  public static native int toUpperCase(int codePoint);
+
+  /**
    * Converts a Unicode character into its titlecase equivalent mapping.
    * If a mapping does not exist, then the character passed is returned.
    * Note that isTitleCase(toTitleCase(ch)) does not always return true.
@@ -2622,6 +2992,23 @@
   public static native char toTitleCase(char ch);
 
   /**
+   * Converts a Unicode character into its titlecase equivalent mapping.
+   * If a mapping does not exist, then the character passed is returned.
+   * Note that isTitleCase(toTitleCase(codePoint)) does not always return true.
+   * Unlike toTitleCase(char), this method supports supplementary 
+   * Unicode code points.
+   * 
+   * @param codePoint character to convert to titlecase
+   * @return titlecase mapping of codePoint, or codePoint if titlecase 
+   *         mapping does not exist
+   * @see #isTitleCase(int)
+   * @see #toLowerCase(int)
+   * @see #toUpperCase(int)
+   * @since 1.5
+   */
+  public static native int toTitleCase(int codePoint);
+
+  /**
    * Converts a character into a digit of the specified radix. If the radix
    * exceeds MIN_RADIX or MAX_RADIX, or if the result of getNumericValue(ch)
    * exceeds the radix, or if ch is not a decimal digit or in the case
@@ -2642,6 +3029,28 @@
   public static native int digit(char ch, int radix);
 
   /**
+   * Converts a character into a digit of the specified radix. If the radix
+   * exceeds MIN_RADIX or MAX_RADIX, or if the result of getNumericValue(int)
+   * exceeds the radix, or if codePoint is not a decimal digit or in the case
+   * insensitive set of 'a'-'z', the result is -1.  Unlike digit(char, int), 
+   * this method supports supplementary Unicode code points.
+   * <br>
+   * character argument boundary = [Nd]|U+0041-U+005A|U+0061-U+007A
+   *    |U+FF21-U+FF3A|U+FF41-U+FF5A
+   *
+   * @param codePoint character to convert into a digit
+   * @param radix radix in which codePoint is a digit
+   * @return digit which codePoint represents in radix, or -1 not a valid digit
+   * @see #MIN_RADIX
+   * @see #MAX_RADIX
+   * @see #forDigit(int, int)
+   * @see #isDigit(int)
+   * @see #getNumericValue(int)
+   * @since 1.5
+   */
+  public static native int digit(int codePoint, int radix);
+
+  /**
    * Returns the Unicode numeric value property of a character. For example,
    * <code>'\\u216C'</code> (the Roman numeral fifty) returns 50.
    *
@@ -2671,6 +3080,38 @@
   public static native int getNumericValue(char ch);
 
   /**
+   * Returns the Unicode numeric value property of a character. For example,
+   * <code>'\\u216C'</code> (the Roman numeral fifty) returns 50.
+   *
+   * <p>This method also returns values for the letters A through Z, (not
+   * specified by Unicode), in these ranges: <code>'\u0041'</code>
+   * through <code>'\u005A'</code> (uppercase); <code>'\u0061'</code>
+   * through <code>'\u007A'</code> (lowercase); and <code>'\uFF21'</code>
+   * through <code>'\uFF3A'</code>, <code>'\uFF41'</code> through
+   * <code>'\uFF5A'</code> (full width variants).
+   *
+   * <p>If the character lacks a numeric value property, -1 is returned.
+   * If the character has a numeric value property which is not representable
+   * as a nonnegative integer, such as a fraction, -2 is returned.
+   *
+   * Unlike getNumericValue(char), this method supports supplementary Unicode
+   * code points.
+   *
+   * character argument boundary = [Nd]|[Nl]|[No]|U+0041-U+005A|U+0061-U+007A
+   *    |U+FF21-U+FF3A|U+FF41-U+FF5A
+   *
+   * @param codePoint character from which the numeric value property will
+   *        be retrieved
+   * @return the numeric value property of codePoint, or -1 if it does not 
+   *         exist, or -2 if it is not representable as a nonnegative integer
+   * @see #forDigit(int, int)
+   * @see #digit(int, int)
+   * @see #isDigit(int)
+   * @since 1.5
+   */
+  public static native int getNumericValue(int codePoint);
+
+  /**
    * Determines if a character is a ISO-LATIN-1 space. This is only the five
    * characters <code>'\t'</code>, <code>'\n'</code>, <code>'\f'</code>,
    * <code>'\r'</code>, and <code>' '</code>.
@@ -2714,6 +3155,26 @@
   }
 
   /**
+   * Determines if a character is a Unicode space character. This includes
+   * SPACE_SEPARATOR, LINE_SEPARATOR, and PARAGRAPH_SEPARATOR.  Unlike
+   * isSpaceChar(char), this method supports supplementary Unicode code points.
+   * <br>
+   * Unicode space = [Zs]|[Zp]|[Zl]
+   *
+   * @param codePoint character to test
+   * @return true if codePoint is a Unicode space, else false
+   * @see #isWhitespace(int)
+   * @since 1.5
+   */
+  public static boolean isSpaceChar(int codePoint)
+  {
+    return ((1 << getType(codePoint))
+            & ((1 << SPACE_SEPARATOR)
+               | (1 << LINE_SEPARATOR)
+               | (1 << PARAGRAPH_SEPARATOR))) != 0;
+  }
+
+  /**
    * Determines if a character is Java whitespace. This includes Unicode
    * space characters (SPACE_SEPARATOR, LINE_SEPARATOR, and
    * PARAGRAPH_SEPARATOR) except the non-breaking spaces
@@ -2751,6 +3212,47 @@
   }
 
   /**
+   * Determines if a character is Java whitespace. This includes Unicode
+   * space characters (SPACE_SEPARATOR, LINE_SEPARATOR, and
+   * PARAGRAPH_SEPARATOR) except the non-breaking spaces
+   * (<code>'\u00A0'</code>, <code>'\u2007'</code>, and <code>'\u202F'</code>);
+   * and these characters: <code>'\u0009'</code>, <code>'\u000A'</code>,
+   * <code>'\u000B'</code>, <code>'\u000C'</code>, <code>'\u000D'</code>,
+   * <code>'\u001C'</code>, <code>'\u001D'</code>, <code>'\u001E'</code>,
+   * and <code>'\u001F'</code>.  Unlike isWhitespace(char), this method
+   * supports supplementary Unicode code points.
+   * <br>
+   * Java whitespace = ([Zs] not Nb)|[Zl]|[Zp]|U+0009-U+000D|U+001C-U+001F
+   *
+   * @param codePoint character to test
+   * @return true if codePoint is Java whitespace, else false
+   * @see #isSpaceChar(int)
+   * @since 1.5
+   */
+  public static boolean isWhitespace(int codePoint)
+  {
+    int plane = codePoint >>> 16;
+    if (plane > 2 && plane != 14)
+      return false;
+    int attr = readCodePoint(codePoint);
+    return ((((1 << (attr & TYPE_MASK))
+              & ((1 << SPACE_SEPARATOR)
+                 | (1 << LINE_SEPARATOR)
+                 | (1 << PARAGRAPH_SEPARATOR))) != 0)
+            && (attr & NO_BREAK_MASK) == 0)
+      || (codePoint <= '\u001F' && ((1 << codePoint)
+                             & ((1 << '\t')
+                                | (1 << '\n')
+                                | (1 << '\u000B')
+                                | (1 << '\u000C')
+                                | (1 << '\r')
+                                | (1 << '\u001C')
+                                | (1 << '\u001D')
+                                | (1 << '\u001E')
+                                | (1 << '\u001F'))) != 0);
+  }
+
+  /**
    * Determines if a character has the ISO Control property.
    * <br>
    * ISO Control = [Cc]
@@ -2767,6 +3269,24 @@
   }
 
   /**
+   * Determines if a character has the ISO Control property.  Unlike
+   * isISOControl(char), this method supports supplementary unicode
+   * code points.
+   * <br>
+   * ISO Control = [Cc]
+   *
+   * @param codePoint character to test
+   * @return true if codePoint is an ISO Control character, else false
+   * @see #isSpaceChar(int)
+   * @see #isWhitespace(int)
+   * @since 1.5
+   */
+  public static boolean isISOControl(int codePoint)
+  {
+    return getType(codePoint) == CONTROL;
+  }
+
+  /**
    * Returns the Unicode general category property of a character.
    *
    * @param ch character from which the general category property will
@@ -2806,6 +3326,46 @@
   public static native int getType(char ch);
 
   /**
+   * Returns the Unicode general category property of a character.  Supports
+   * supplementary Unicode code points.
+   *
+   * @param codePoint character from which the general category property will
+   *        be retrieved
+   * @return the character category property of codePoint as an integer
+   * @see #UNASSIGNED
+   * @see #UPPERCASE_LETTER
+   * @see #LOWERCASE_LETTER
+   * @see #TITLECASE_LETTER
+   * @see #MODIFIER_LETTER
+   * @see #OTHER_LETTER
+   * @see #NON_SPACING_MARK
+   * @see #ENCLOSING_MARK
+   * @see #COMBINING_SPACING_MARK
+   * @see #DECIMAL_DIGIT_NUMBER
+   * @see #LETTER_NUMBER
+   * @see #OTHER_NUMBER
+   * @see #SPACE_SEPARATOR
+   * @see #LINE_SEPARATOR
+   * @see #PARAGRAPH_SEPARATOR
+   * @see #CONTROL
+   * @see #FORMAT
+   * @see #PRIVATE_USE
+   * @see #SURROGATE
+   * @see #DASH_PUNCTUATION
+   * @see #START_PUNCTUATION
+   * @see #END_PUNCTUATION
+   * @see #CONNECTOR_PUNCTUATION
+   * @see #OTHER_PUNCTUATION
+   * @see #MATH_SYMBOL
+   * @see #CURRENCY_SYMBOL
+   * @see #MODIFIER_SYMBOL
+   * @see #INITIAL_QUOTE_PUNCTUATION
+   * @see #FINAL_QUOTE_PUNCTUATION
+   * @since 1.5
+   */
+  public static native int getType(int codePoint);
+
+  /**
    * Converts a digit into a character which represents that digit
    * in a specified radix. If the radix exceeds MIN_RADIX or MAX_RADIX,
    * or the digit exceeds the radix, then the null character <code>'\0'</code>
@@ -2859,6 +3419,37 @@
   public static native byte getDirectionality(char ch);
 
   /**
+   * Returns the Unicode directionality property of the character. This
+   * is used in the visual ordering of text.  Unlike getDirectionality(char),
+   * this method supports supplementary Unicode code points.
+   *
+   * @param codePoint the character to look up
+   * @return the directionality constant, or DIRECTIONALITY_UNDEFINED
+   * @see #DIRECTIONALITY_UNDEFINED
+   * @see #DIRECTIONALITY_LEFT_TO_RIGHT
+   * @see #DIRECTIONALITY_RIGHT_TO_LEFT
+   * @see #DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC
+   * @see #DIRECTIONALITY_EUROPEAN_NUMBER
+   * @see #DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR
+   * @see #DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR
+   * @see #DIRECTIONALITY_ARABIC_NUMBER
+   * @see #DIRECTIONALITY_COMMON_NUMBER_SEPARATOR
+   * @see #DIRECTIONALITY_NONSPACING_MARK
+   * @see #DIRECTIONALITY_BOUNDARY_NEUTRAL
+   * @see #DIRECTIONALITY_PARAGRAPH_SEPARATOR
+   * @see #DIRECTIONALITY_SEGMENT_SEPARATOR
+   * @see #DIRECTIONALITY_WHITESPACE
+   * @see #DIRECTIONALITY_OTHER_NEUTRALS
+   * @see #DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING
+   * @see #DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE
+   * @see #DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING
+   * @see #DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE
+   * @see #DIRECTIONALITY_POP_DIRECTIONAL_FORMAT
+   * @since 1.5
+   */
+  public static native byte getDirectionality(int codePoint);
+
+  /**
    * Determines whether the character is mirrored according to Unicode. For
    * example, <code>\u0028</code> (LEFT PARENTHESIS) appears as '(' in
    * left-to-right text, but ')' in right-to-left text.
@@ -2873,6 +3464,24 @@
   }
 
   /**
+   * Determines whether the character is mirrored according to Unicode. For
+   * example, <code>\u0028</code> (LEFT PARENTHESIS) appears as '(' in
+   * left-to-right text, but ')' in right-to-left text.  Unlike 
+   * isMirrored(char), this method supports supplementary Unicode code points.
+   *
+   * @param codePoint the character to look up
+   * @return true if the character is mirrored
+   * @since 1.5
+   */
+  public static boolean isMirrored(int codePoint)
+  {
+    int plane = codePoint >>> 16;
+    if (plane > 2 && plane != 14)
+      return false;
+    return (readCodePoint(codePoint) & MIRROR_MASK) != 0;
+  }
+
+  /**
    * Compares another Character to this Character, numerically.
    *
    * @param anotherCharacter Character to compare with this Character
Index: libjava/include/java-chartables.h
===================================================================
--- libjava/include/java-chartables.h	(revision 112066)
+++ libjava/include/java-chartables.h	(working copy)
@@ -1,6 +1,6 @@
 /* java-chartables.h -- Character tables for java.lang.Character -*- c++ -*-
-   Copyright (C) 2002 Free Software Foundation, Inc.
-   *** This file is generated by scripts/MakeCharTables.java ***
+   Copyright (C) 2002, 2006 Free Software Foundation, Inc.
+   *** This file is generated by scripts/unicode_to_chartables.pl ***
 
 This file is part of GNU Classpath.
 
@@ -39,17 +39,15 @@
 #ifndef __JAVA_CHARTABLES_H__
 #define __JAVA_CHARTABLES_H__
 
-// These tables are automatically generated by scripts/MakeCharTables.java.
-// This is in turn parsing gnu.java.lang.CharData, which is generated by
-// scripts/unicode-muncher.pl.  The Unicode data comes from
-// www.unicode.org; this header is based on
-// gnu/gcj/convert/UnicodeData-3.0.0.txt. JDK 1.4 uses Unicode version 3.0.0.
+// These tables are automatically generated by scripts/unicode_to_chartables.pl.
+// The Unicode data comes from www.unicode.org; this header is based on
+// UnicodeData-4.0.0.txt. JDK 1.5 uses Unicode version 4.0.0.
 // DO NOT EDIT the tables.  Instead, fix the upstream scripts and run
 // them again.
 
 // The data is stored in C style arrays of the appropriate CNI types, to
 // guarantee that the data is constant and non-relocatable.  The field
-// <code>blocks</code> stores the offset of a block of 2<supSHIFT</sup>
+// <code>blocks</code> stores the offset of a block of 2<sup>SHIFT</sup>
 // characters within <code>data</code>. The data field, in turn, stores
 // information about each character in the low order bits, and an offset
 // into the attribute tables <code>upper</code>, <code>lower</code>,
@@ -62,914 +60,1546 @@
 // This file should only be included by natCharacter.cc
 
 /**
+ * The array containing the numeric values that are too large to be stored as
+ * chars in NUM_VALUE.  NUM_VALUE in this case will contain a negative integer
+ * N such that LARGENUMS[-N - 3] contains the correct numeric value.
+ */
+static const jint largenums[] = {
+    40000, 50000, 60000, 70000, 80000, 90000, };
+
+/**
  * The character shift amount to look up the block offset. In other words,
- * <code>(char) (blocks[ch >> SHIFT] + ch)</code> is the index where
- * <code>ch</code> is described in <code>data</code>.
+ * <code>(char) (blocks[p][off >> SHIFT[p]] + off)</code> is the index where
+ * <code>ch</code> is described in <code>data</code>, where <code>off</code>
+ * is ch & 0xffff and <code>p</code> is the plane the character belongs to.
  */
-#define SHIFT 5
+static const int shift[] = {
+    4, 6, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 8, 8, };
 
 /**
  * The mapping of character blocks to their location in <code>data</code>.
  * Each entry has been adjusted so that a modulo 16 sum with the desired
  * character gives the actual index into <code>data</code>.
  */
-static const jchar blocks[] = {
-    450, 450, 449, 300, 299, 416, 504, 732, 607, 750,
-    533, 838, 732, 806, 700, 534, 351, 724, 886, 886,
-    886, 873, 65167, 836, 65413, 65381, 64949, 64929, 27, 708,
-    28, 71, 65192, 65420, 565, 65279, 26, 65215, 38, 64288,
-    65064, 275, 260, 64353, 64346, 267, 265, 254, 65288, 553,
-    606, 455, 508, 476, 64582, 553, 65063, 64341, 361, 64456,
-    252, 259, 64360, 64328, 64296, 64264, 64232, 64200, 64168, 64136,
-    64104, 64072, 101, 80, 171, 313, 65038, 99, 341, 424,
-    63081, 297, 296, 63775, 65110, 264, 263, 64192, 64654, 65197,
-    198, 64679, 64405, 62589, 159, 64279, 65056, 64808, 64303, 59,
-    62393, 65111, 64718, 65467, 62265, 64152, 65419, 65339, 64084, 63459,
-    65323, 64215, 64361, 64570, 65253, 62664, 64688, 64136, 64959, 62536,
-    65093, 64711, 65103, 63473, 63253, 62184, 64927, 62280, 63850, 64514,
-    64919, 62152, 62120, 62649, 62643, 61291, 63594, 63562, 64600, 63498,
-    63466, 64527, 63402, 61084, 64400, 63306, 63482, 63242, 63434, 63378,
-    62577, 62674, 63282, 63050, 62465, 63053, 61352, 62922, 62890, 60577,
-    62825, 62794, 62762, 62730, 62698, 62666, 62634, 62602, 62570, 62538,
-    62506, 62474, 62442, 62410, 62378, 62346, 62314, 62282, 62250, 62089,
-    63351, 62154, 62122, 63287, 60456, 60424, 60392, 60360, 61930, 62626,
-    62789, 60870, 62167, 61770, 59629, 59422, 61674, 62871, 60008, 59976,
-    59944, 59912, 59880, 59848, 59816, 59784, 59752, 59720, 59688, 59656,
-    59624, 59592, 59560, 59528, 59496, 59464, 59432, 59400, 59368, 59336,
-    59304, 59272, 59240, 59208, 59176, 59144, 59112, 59080, 59048, 59016,
-    58984, 58952, 58920, 58888, 58856, 58824, 58792, 58760, 58728, 58696,
-    58719, 58687, 58655, 58623, 61399, 58559, 58527, 58501, 61319, 61271,
-    61271, 61271, 61271, 61255, 57773, 61254, 61254, 61254, 57824, 58333,
-    61190, 59865, 60395, 57924, 61140, 61285, 57845, 61253, 61161, 61308,
-    61044, 61296, 61309, 61304, 61073, 61395, 61053, 60965, 60967, 61285,
-    61405, 61078, 61395, 61409, 61289, 57224, 57192, 57160, 60715, 60733,
-    60697, 61212, 61192, 60743, 60733, 60723, 60459, 60427, 60395, 60363,
-    60366, 60028, 60265, 60268, 59830, 60171, 60139, 59881, 56488, 56456,
-    56424, 56392, 59664, 59939, 60248, 60239, 60229, 60133, 56168, 56136,
-    59691, 59659, 59627, 59595, 59563, 59531, 59499, 59467, 55848, 55816,
-    55784, 55752, 55720, 55688, 55656, 55624, 55592, 55560, 55528, 55496,
-    55464, 55432, 55400, 55368, 55336, 55304, 55272, 55240, 55208, 55176,
-    55144, 55112, 55080, 55048, 55016, 54984, 54952, 54920, 54888, 54856,
-    54824, 54792, 54760, 54728, 54696, 54664, 54632, 54600, 54568, 54536,
-    54504, 54472, 58033, 57995, 57963, 57968, 57899, 57867, 57835, 57803,
-    57771, 57739, 57742, 56719, 58280, 57299, 55593, 55562, 58184, 55497,
-    55466, 56535, 56498, 54913, 55338, 55306, 57960, 52958, 53608, 53576,
-    57622, 57577, 57803, 57527, 57527, 57694, 57111, 57396, 57363, 57331,
-    57299, 56940, 57235, 57203, 57173, 57140, 54634, 54602, 54570, 54538,
-    54506, 54474, 54442, 54410, 54378, 54346, 54314, 54282, 54250, 54218,
-    54186, 54154, 54122, 54090, 54058, 54026, 53994, 53962, 53930, 53898,
-    53866, 53834, 53802, 53770, 53738, 53706, 53674, 53642, 53610, 53578,
-    53546, 53514, 53482, 53450, 53418, 53386, 53354, 53322, 53290, 53258,
-    53226, 53194, 53162, 53130, 53098, 53066, 53034, 53002, 52970, 52938,
-    52906, 52874, 52842, 52810, 52778, 52746, 52714, 52682, 52650, 52618,
-    52586, 52554, 52522, 52490, 52458, 52426, 52394, 52362, 52330, 52298,
-    52266, 52234, 52202, 52170, 52138, 52106, 52074, 52042, 52010, 51978,
-    51946, 51914, 51882, 51850, 51818, 51786, 51754, 51722, 51690, 51658,
-    51626, 51594, 51562, 51530, 51498, 51466, 51434, 51402, 51370, 51338,
-    51306, 51274, 51242, 51210, 51178, 51146, 51114, 51082, 51050, 51018,
-    50986, 50954, 50922, 50890, 50858, 50826, 50794, 50762, 50730, 50698,
-    50666, 50634, 50602, 50570, 50538, 50506, 50474, 50442, 50410, 50378,
-    50346, 50314, 50282, 50250, 50218, 50186, 50154, 50122, 50090, 50058,
-    50026, 49994, 49962, 49930, 49898, 49866, 49834, 49802, 49770, 49738,
-    49706, 49674, 49642, 49610, 49578, 49546, 49514, 49482, 49450, 49418,
-    49386, 49354, 49322, 49290, 49258, 49226, 49194, 49162, 49130, 49098,
-    49066, 49034, 49002, 48970, 48938, 48906, 48874, 48842, 48810, 48778,
-    48746, 48714, 48682, 48650, 48618, 48586, 48554, 48522, 48490, 48458,
-    48426, 48394, 48362, 48330, 48298, 48266, 48234, 48202, 48170, 48138,
-    48106, 45792, 46440, 46408, 47978, 47946, 47914, 47882, 47850, 47818,
-    47786, 47754, 47722, 47690, 47658, 47626, 47594, 47562, 47530, 47498,
-    47466, 47434, 47402, 47370, 47338, 47306, 47274, 47242, 47210, 47178,
-    47146, 47114, 47082, 47050, 47018, 46986, 46954, 46922, 46890, 46858,
-    46826, 46794, 46762, 46730, 46698, 46666, 46634, 46602, 46570, 46538,
-    46506, 46474, 46442, 46410, 46378, 46346, 46314, 46282, 46250, 46218,
-    46186, 46154, 46122, 46090, 46058, 46026, 45994, 45962, 45930, 45898,
-    45866, 45834, 45802, 45770, 45738, 45706, 45674, 45642, 45610, 45578,
-    45546, 45514, 45482, 45450, 45418, 45386, 45354, 45322, 45290, 45258,
-    45226, 45194, 45162, 45130, 45098, 45066, 45034, 45002, 44970, 44938,
-    44906, 44874, 44842, 44810, 44778, 44746, 44714, 44682, 44650, 44618,
-    44586, 44554, 44522, 44490, 44458, 44426, 44394, 44362, 44330, 44298,
-    44266, 44234, 44202, 44170, 44138, 44106, 44074, 44042, 44010, 43978,
-    43946, 43914, 43882, 43850, 43818, 43786, 43754, 43722, 43690, 43658,
-    43626, 43594, 43562, 43530, 43498, 43466, 43434, 43402, 43370, 43338,
-    43306, 43274, 43242, 43210, 43178, 43146, 43114, 43082, 43050, 43018,
-    42986, 42954, 42922, 42890, 42858, 42826, 42794, 42762, 42730, 42698,
-    42666, 42634, 42602, 42570, 42538, 42506, 42474, 42442, 42410, 42378,
-    42346, 42314, 42282, 42250, 42218, 42186, 42154, 42122, 42090, 42058,
-    42026, 41994, 41962, 41930, 41898, 41866, 41834, 41802, 41770, 41738,
-    41706, 41674, 41642, 41610, 41578, 41546, 41514, 41482, 41450, 41418,
-    41386, 41354, 41322, 41290, 41258, 41226, 41194, 41162, 41130, 41098,
-    41066, 41034, 41002, 40970, 40938, 40906, 40874, 40842, 40810, 40778,
-    40746, 40714, 40682, 40650, 40618, 40586, 40554, 40522, 40490, 40458,
-    40426, 40394, 40362, 40330, 40298, 40266, 40234, 40202, 40170, 40138,
-    40106, 40074, 40042, 40010, 39978, 39946, 39914, 39882, 39850, 39818,
-    39786, 39754, 39722, 39690, 39658, 39626, 39594, 39562, 39530, 39498,
-    39466, 39434, 39402, 39370, 39338, 39306, 39274, 39242, 39210, 39178,
-    39146, 39114, 39082, 39050, 39018, 38986, 38954, 38922, 38890, 38858,
-    38826, 38794, 38762, 38730, 38698, 38666, 38634, 38602, 38570, 38538,
-    38506, 38474, 38442, 38410, 38378, 38346, 38314, 38282, 38250, 38218,
-    38186, 38154, 38122, 38090, 38058, 38026, 37994, 37962, 37930, 37898,
-    37866, 37834, 37802, 37770, 37738, 37706, 37674, 37642, 37610, 37578,
-    37546, 37514, 37482, 37450, 37418, 37386, 37354, 37322, 37290, 37258,
-    37226, 37194, 37162, 37130, 37098, 37066, 37034, 37002, 36970, 36938,
-    36906, 36874, 36842, 36810, 36778, 36746, 36714, 36682, 36650, 36618,
-    36586, 36554, 36522, 36490, 36458, 36426, 36394, 36362, 36330, 36298,
-    36266, 36234, 36202, 36170, 36138, 36106, 36074, 36042, 36010, 35978,
-    35946, 35914, 35882, 35850, 35818, 35786, 35754, 35722, 35690, 35658,
-    35626, 35594, 35562, 35530, 35498, 35466, 35434, 35402, 35370, 35338,
-    35306, 35274, 35242, 35210, 35178, 35146, 35114, 35082, 35050, 35018,
-    34986, 34954, 34922, 34890, 34858, 34826, 34794, 34762, 34730, 34698,
-    34666, 34634, 34602, 34570, 34538, 34506, 34474, 34442, 34410, 34378,
-    34346, 34314, 34282, 34250, 34218, 34186, 34154, 34122, 34090, 34058,
-    34026, 33994, 33962, 33930, 33898, 33866, 33834, 33802, 33770, 33738,
-    33706, 33674, 33642, 33610, 33578, 33546, 33514, 33482, 33450, 33418,
-    33386, 33354, 33322, 33290, 33258, 33226, 33194, 33162, 33130, 33098,
-    33066, 33034, 33002, 32970, 32938, 32906, 32874, 32842, 32810, 32778,
-    32746, 32714, 32682, 32650, 32618, 32586, 32554, 32522, 32490, 32458,
-    32426, 32394, 32362, 32330, 32298, 32266, 32234, 32202, 32170, 32138,
-    32106, 32074, 32042, 32010, 31978, 31946, 31914, 31882, 31850, 31818,
-    31786, 31754, 31722, 31690, 31658, 31626, 31594, 31562, 31530, 31498,
-    31466, 31434, 31402, 31370, 31338, 31306, 31274, 31242, 31210, 31178,
-    31146, 31114, 31082, 31050, 31018, 30986, 30954, 30922, 30890, 30858,
-    30826, 30794, 30762, 30730, 30698, 30666, 30634, 30602, 30570, 30538,
-    30506, 30474, 30442, 30410, 30378, 30346, 30314, 30282, 30250, 30218,
-    30186, 30154, 30122, 30090, 30058, 30026, 29994, 29962, 29930, 29898,
-    29866, 29834, 29802, 29770, 29738, 29706, 29674, 29642, 29610, 29578,
-    29546, 29514, 29482, 29450, 29418, 29386, 29354, 29322, 29290, 29258,
-    29226, 29194, 29162, 29130, 29098, 29066, 29034, 29002, 28970, 28938,
-    28906, 28874, 28842, 28810, 28778, 28746, 28714, 28682, 28650, 28618,
-    28586, 28554, 28522, 28490, 28458, 28426, 28394, 28362, 28330, 28298,
-    28266, 28234, 28202, 28170, 28138, 28106, 28074, 28042, 28010, 27978,
-    27946, 27914, 27882, 27850, 27818, 27786, 27754, 27722, 27690, 27658,
-    27626, 27594, 27562, 27530, 27498, 27466, 27434, 27402, 27370, 27338,
-    27306, 27274, 27242, 27210, 27178, 27146, 27114, 24816, 25448, 25416,
-    26986, 26954, 26922, 26890, 26858, 26826, 26794, 26762, 26730, 26698,
-    26666, 26634, 26602, 26570, 26538, 26506, 26474, 26442, 26410, 26378,
-    26346, 26314, 26282, 26250, 26218, 26186, 26154, 26122, 26090, 26058,
-    26026, 25994, 25962, 25930, 25898, 25866, 27430, 28129, 28316, 24136,
-    24104, 24072, 24040, 24008, 23976, 23944, 23912, 23880, 23848, 23816,
-    23784, 23752, 23720, 23688, 23656, 23624, 23592, 23560, 23528, 23496,
-    23464, 23432, 23400, 23368, 23336, 23304, 23272, 23240, 23208, 23176,
-    23144, 23112, 23080, 23048, 23016, 22984, 22952, 22920, 22888, 22856,
-    22824, 22792, 22760, 22728, 22696, 22664, 22632, 22600, 22568, 22536,
-    22504, 22472, 22440, 22408, 22376, 22344, 23914, 23882, 23850, 23818,
-    23786, 23754, 23722, 23690, 23658, 23626, 23594, 23562, 23530, 23498,
-    23466, 23434, 23402, 23370, 23338, 23306, 23274, 23242, 23210, 23178,
-    23146, 23114, 23082, 23050, 23018, 22986, 22954, 22922, 22890, 22858,
-    22826, 22794, 22762, 22730, 22698, 22666, 22634, 22602, 22570, 22538,
-    22506, 22474, 22442, 22410, 22378, 22346, 22314, 22282, 22250, 22218,
-    22186, 22154, 22122, 22090, 22058, 22026, 21994, 21962, 21930, 21898,
-    21866, 21834, 21802, 21770, 21738, 21706, 21674, 21642, 21610, 21578,
-    21546, 21514, 21482, 21450, 21418, 21386, 21354, 21322, 21290, 21258,
-    21226, 21194, 21162, 21130, 21098, 21066, 21034, 21002, 20970, 20938,
-    20906, 20874, 20842, 20810, 20778, 20746, 20714, 20682, 20650, 20618,
-    20586, 20554, 20522, 20490, 20458, 20426, 20394, 20362, 20330, 20298,
-    20266, 20234, 20202, 20170, 20138, 20106, 20074, 20042, 20010, 19978,
-    19946, 19914, 19882, 19850, 19818, 19786, 19754, 19722, 19690, 19658,
-    19626, 19594, 19562, 19530, 19498, 19466, 19434, 19402, 19370, 19338,
-    19306, 19274, 19242, 19210, 19178, 19146, 19114, 19082, 19050, 19018,
-    18986, 18954, 18922, 18890, 18858, 18826, 18794, 18762, 18730, 18698,
-    18666, 18634, 18602, 18570, 18538, 18506, 18474, 18442, 18410, 18378,
-    18346, 18314, 18282, 18250, 18218, 18186, 18154, 18122, 18090, 18058,
-    18026, 17994, 17962, 17930, 17898, 17866, 17834, 17802, 17770, 17738,
-    17706, 17674, 17642, 17610, 17578, 17546, 17514, 17482, 17450, 17418,
-    17386, 17354, 17322, 17290, 17258, 17226, 17194, 17162, 17130, 17098,
-    17066, 17034, 17002, 16970, 16938, 16906, 16874, 16842, 16810, 16778,
-    16746, 16714, 16682, 16650, 16618, 16586, 16554, 16522, 16490, 16458,
-    16426, 16394, 16362, 16330, 16298, 16266, 16234, 16202, 16170, 16138,
-    16106, 16074, 16042, 16010, 15978, 15946, 15914, 15882, 15850, 15818,
-    15786, 15754, 15722, 15690, 15658, 15626, 15594, 15562, 15530, 15498,
-    15466, 15434, 15402, 15370, 15338, 15306, 15274, 15242, 15210, 15178,
-    15146, 15114, 15082, 15050, 15018, 14986, 14954, 14922, 14890, 14858,
-    14826, 14794, 14762, 14730, 14698, 14666, 14634, 14602, 14570, 14538,
-    14506, 14474, 14442, 14410, 14378, 14346, 14314, 14282, 14250, 14218,
-    14186, 14154, 14122, 14090, 14058, 14026, 13994, 13962, 13930, 13898,
-    13866, 13834, 13802, 13770, 13738, 13706, 13674, 13642, 13610, 13578,
-    13546, 13514, 13482, 13450, 13418, 13386, 13354, 13322, 13290, 13258,
-    13226, 13194, 13162, 13130, 13098, 13066, 13034, 13002, 12970, 12938,
-    12906, 12874, 12842, 12810, 12778, 10482, 11112, 11080, 15403, 15371,
-    15339, 15307, 15275, 15243, 15211, 15179, 15147, 15115, 15083, 15051,
-    15019, 14987, 14955, 14923, 14891, 14859, 14827, 14795, 14763, 14731,
-    14699, 14667, 14635, 14603, 14571, 14539, 14507, 14475, 14443, 14411,
-    14379, 14347, 14315, 14283, 14251, 14219, 14187, 14155, 14123, 14091,
-    14059, 14027, 13995, 13963, 13931, 13899, 13867, 13835, 13803, 13771,
-    13739, 13707, 13675, 13643, 13611, 13579, 13547, 13515, 13483, 13451,
-    13419, 13387, 13387, 13355, 13323, 13291, 13259, 13227, 13195, 13163,
-    13131, 13099, 13067, 13035, 13003, 12971, 12939, 12907, 12875, 12843,
-    12811, 12779, 12747, 12715, 12683, 12651, 12619, 12587, 12555, 12523,
-    12491, 12459, 12427, 12395, 12363, 12331, 12299, 12267, 12235, 12203,
-    12171, 12139, 12107, 12075, 12043, 12011, 11979, 11947, 11915, 11883,
-    11851, 11819, 11787, 11755, 11723, 11691, 11659, 11627, 11595, 11563,
-    11531, 11499, 11467, 11435, 11403, 11371, 11339, 11307, 11275, 11243,
-    11211, 11179, 11147, 11115, 11083, 11051, 11019, 10987, 10955, 10923,
-    10891, 10859, 10827, 10795, 10763, 10731, 10699, 10667, 10635, 10603,
-    10571, 10539, 10507, 10475, 10443, 10411, 10379, 10347, 10315, 10283,
-    10251, 10219, 10187, 10155, 10123, 10091, 10059, 10027, 9995, 9963,
-    9931, 9899, 9867, 9835, 9803, 9771, 9739, 9707, 9675, 9643,
-    9611, 9579, 9547, 9515, 9483, 9451, 9419, 9387, 9355, 9323,
-    9291, 9259, 9227, 9195, 9163, 9131, 9099, 9067, 9035, 9003,
-    8971, 8939, 8907, 8875, 8843, 8811, 8779, 8747, 8715, 8683,
-    8651, 8619, 8587, 8555, 8523, 8491, 8459, 8427, 8395, 8363,
-    8331, 8299, 8267, 8235, 8203, 8171, 8139, 8107, 8075, 8043,
-    8011, 7979, 7947, 7915, 7883, 7851, 7819, 7787, 7755, 7723,
-    7691, 7659, 7627, 7595, 7563, 7531, 7499, 7467, 7435, 7403,
-    7371, 7339, 7307, 7275, 7243, 7211, 7179, 7147, 7115, 7083,
-    7051, 7019, 4202, 4170, 4138, 4106, 4074, 4042, 4010, 3978,
-    3946, 1640, 2280, 2248, 2216, 2184, 2152, 2120, 2007, 6475,
-    1974, 3356, 3324, 3250, 3241, 3228, 3196, 3164, 3132, 3100,
-    3068, 3036, 3004, 2972, 2940, 2910, 2860, 2844, 2744, 2780,
-    2716, 706, 1320, 5739, 5735, 1023, 2556, 2524, 2492, 1625,
-    3000, 5543, 4038, 448, 433, 2507, 2092, 4741,
-  };
-/** Length of blocks. */
-static const int blocks_length = 2048;
+static const jchar blocks0[] = {
+    15, 23, 53, 7, 52, 52, 90, 65424, 65437, 65427, 
+    11, 65461, 11, 4, 28, 21, 23, 7, 65527, 173, 
+    269, 65479, 65463, 65403, 273, 273, 183, 257, 65500, 65354, 
+    65335, 65267, 65303, 65287, 65269, 65401, 220, 50, 321, 5, 
+    65511, 317, 304, 311, 355, 355, 274, 325, 358, 342, 
+    326, 310, 65409, 401, 262, 65156, 458, 64826, 442, 64843, 
+    426, 65140, 64823, 334, 435, 64699, 64683, 64716, 64700, 371, 
+    64695, 64679, 64680, 64647, 64631, 64615, 275, 64583, 64567, 64578, 
+    64535, 65036, 65020, 64723, 64708, 64701, 65034, 65019, 65012, 65237, 
+    65219, 64791, 64789, 138, 127, 181, 64945, 220, 64878, 249, 
+    203, 65507, 107, 249, 64783, 64767, 64751, 64735, 64719, 9, 
+    171, 105, 65531, 88, 64623, 64822, 65494, 64460, 64444, 64428, 
+    64527, 64511, 65392, 65529, 64348, 64332, 64316, 64300, 64284, 64268, 
+    64252, 64236, 64220, 64204, 64188, 64172, 64156, 64140, 64124, 64108, 
+    64092, 64076, 64060, 64044, 65249, 64259, 64243, 65267, 64724, 65291, 
+    65299, 63915, 64394, 63482, 64105, 64485, 64366, 63758, 65193, 65199, 
+    64377, 63354, 63977, 63687, 65020, 63328, 64386, 65087, 63204, 63872, 
+    63849, 63246, 64454, 63332, 64937, 64989, 64010, 63098, 63721, 64328, 
+    63117, 62956, 64913, 63171, 63428, 63323, 63407, 63323, 63803, 64222, 
+    64347, 64791, 63236, 63489, 63465, 64420, 64727, 63279, 64657, 63148, 
+    64331, 63361, 63337, 64631, 64369, 63898, 64529, 63020, 64203, 63233, 
+    63209, 64143, 64503, 63838, 64401, 62892, 64468, 62443, 63091, 63450, 
+    64391, 63538, 62780, 62759, 62994, 62979, 62963, 64143, 64157, 64041, 
+    62652, 62636, 62151, 63220, 63096, 64185, 64185, 63935, 62524, 62508, 
+    64137, 62218, 63176, 63172, 62666, 62659, 63643, 62845, 63847, 62669, 
+    62662, 62649, 62052, 62284, 62268, 62252, 62483, 62467, 62722, 63849, 
+    63671, 63833, 62140, 62124, 62108, 62092, 63783, 63767, 63761, 62275, 
+    62259, 63347, 62227, 62211, 62195, 62179, 62163, 63148, 62131, 62115, 
+    62099, 62083, 63075, 62051, 62035, 62019, 62003, 63473, 61963, 61955, 
+    61939, 61923, 61227, 61211, 61875, 61859, 61163, 61827, 61795, 61123, 
+    61107, 61755, 61731, 61731, 61699, 61027, 61683, 61667, 61643, 62635, 
+    62147, 62425, 61340, 61324, 61555, 61539, 61523, 61507, 61491, 62966, 
+    61458, 61443, 61427, 61411, 61395, 61379, 61363, 61347, 61331, 61315, 
+    61299, 61283, 61267, 61251, 61235, 61219, 61203, 61187, 61171, 61155, 
+    61139, 61123, 61107, 61091, 61075, 61059, 61043, 61027, 61011, 60995, 
+    60979, 60963, 60947, 60931, 60915, 60899, 60883, 60867, 60205, 62324, 
+    61814, 61782, 60787, 60771, 60755, 60739, 62073, 62215, 60677, 62199, 
+    60659, 62183, 60627, 62167, 60581, 62151, 60563, 60547, 60531, 62103, 
+    61004, 62098, 60246, 62097, 62097, 60198, 60403, 60387, 61402, 60355, 
+    60339, 61811, 60307, 60291, 61953, 60012, 59996, 59980, 59964, 59948, 
+    60179, 61161, 61746, 60531, 59888, 60099, 61080, 61558, 59804, 59788, 
+    59772, 59756, 59740, 59724, 61668, 61652, 59676, 59660, 59644, 59628, 
+    59612, 59596, 59580, 59564, 59548, 59532, 59516, 59500, 59484, 59468, 
+    59452, 59436, 59420, 59404, 59388, 59372, 59356, 59340, 59324, 59308, 
+    59292, 59276, 59260, 59244, 59228, 59212, 59196, 59180, 59164, 59148, 
+    59132, 59116, 59100, 59084, 59068, 59052, 59036, 59020, 59004, 58988, 
+    58972, 58956, 58940, 58924, 59088, 59072, 59060, 59056, 59040, 59024, 
+    61022, 58796, 58780, 58764, 58748, 58732, 58716, 58700, 58684, 58668, 
+    58135, 58119, 58103, 58087, 58071, 58055, 58039, 58023, 58007, 58200, 
+    57975, 57959, 57943, 57927, 57911, 59112, 60622, 60622, 60590, 60574, 
+    60574, 60574, 60526, 60558, 60558, 60542, 60526, 60526, 58499, 60510, 
+    60510, 57701, 60494, 60494, 57467, 60493, 57427, 57334, 59163, 60445, 
+    60445, 57996, 60429, 60427, 57948, 60411, 58887, 57900, 58047, 59809, 
+    60046, 59529, 60439, 58731, 60423, 60423, 60423, 59922, 60407, 59668, 
+    59654, 59631, 59620, 59616, 59751, 60187, 60182, 59602, 60111, 60058, 
+    59577, 60060, 59602, 59637, 60006, 60003, 59952, 59516, 59950, 59932, 
+    60070, 59316, 60048, 60043, 60033, 60017, 60001, 57613, 59204, 57620, 
+    59188, 57600, 59140, 59945, 57148, 57132, 59076, 59060, 59859, 57068, 
+    59823, 57036, 59825, 59805, 59785, 59785, 59681, 59818, 59808, 59808, 
+    59798, 58754, 58820, 58804, 58788, 58772, 58756, 58740, 58724, 58708, 
+    58692, 58676, 58660, 59374, 58626, 58612, 58596, 58588, 58564, 57001, 
+    58532, 58516, 58500, 58484, 58469, 59260, 58436, 59240, 59224, 56428, 
+    56412, 56396, 56380, 56364, 56728, 58292, 56729, 58260, 56650, 59204, 
+    56673, 56667, 56657, 58964, 58148, 58939, 56156, 58635, 59076, 58084, 
+    58052, 58036, 58020, 58004, 57988, 57972, 57956, 57940, 57924, 57908, 
+    57892, 57876, 57860, 57844, 57828, 57812, 57812, 57796, 57780, 57764, 
+    57748, 57732, 57716, 57700, 57710, 57702, 58220, 57822, 57775, 58235, 
+    57679, 57584, 57562, 58161, 57661, 57673, 57492, 57671, 58045, 57561, 
+    57996, 57980, 57473, 57948, 57932, 57405, 57879, 57420, 58092, 55308, 
+    55292, 55276, 55260, 55244, 55228, 55212, 55196, 55180, 55164, 55148, 
+    55132, 55116, 55100, 55084, 55068, 55052, 55036, 55020, 55004, 54988, 
+    54972, 54956, 54940, 54924, 54908, 54892, 54876, 54860, 54844, 54828, 
+    54812, 54796, 54780, 54764, 54748, 54732, 54716, 54700, 54684, 54668, 
+    54652, 54636, 54620, 54604, 54588, 54572, 54556, 54540, 54524, 54508, 
+    54492, 54476, 54460, 54444, 56388, 54823, 56356, 56340, 56324, 56308, 
+    56292, 57094, 56260, 56244, 56228, 56212, 56196, 56180, 56164, 56148, 
+    56132, 56116, 56100, 56084, 56068, 56868, 54076, 56830, 57012, 57010, 
+    54323, 56918, 54226, 54211, 54195, 54179, 54163, 55228, 54114, 54115, 
+    54099, 54083, 54067, 55067, 55046, 54019, 55001, 53986, 53971, 53955, 
+    53939, 53923, 53891, 53991, 53875, 55347, 53596, 53580, 53564, 53795, 
+    56257, 56244, 56368, 56209, 56320, 56450, 56161, 56149, 56272, 56113, 
+    56097, 56100, 56165, 56049, 56033, 56133, 56001, 55985, 55969, 55953, 
+    55937, 55921, 55905, 55994, 55873, 55857, 55841, 55825, 55809, 55795, 
+    55777, 55762, 53267, 53251, 53235, 53219, 53203, 53187, 53171, 53155, 
+    53139, 53123, 53107, 53091, 53075, 53059, 53043, 53027, 53011, 52995, 
+    52979, 52963, 52947, 52931, 52915, 52899, 52883, 52867, 52851, 52835, 
+    52819, 52803, 52787, 52771, 52755, 52739, 52723, 52707, 52691, 52675, 
+    52659, 52643, 52627, 52611, 52595, 52579, 52563, 52547, 52531, 52515, 
+    52499, 52483, 52467, 52451, 52435, 52419, 52403, 52387, 52371, 52355, 
+    52339, 52323, 52307, 52291, 52275, 52259, 52243, 52227, 52211, 52195, 
+    52179, 52163, 52147, 52131, 52115, 52099, 52083, 52067, 52051, 52035, 
+    52019, 52003, 51987, 51971, 51955, 51939, 51923, 51907, 51891, 51875, 
+    51859, 51843, 51827, 51811, 51795, 51779, 51763, 51747, 51731, 51715, 
+    51699, 51683, 51667, 51651, 51635, 51619, 51603, 51587, 51571, 51555, 
+    51539, 51523, 51507, 51491, 51475, 51459, 51443, 51427, 51411, 51395, 
+    51379, 51363, 51347, 51331, 51315, 51299, 51283, 51267, 51251, 51235, 
+    51219, 51203, 51187, 51171, 51155, 51139, 51123, 51107, 51091, 51075, 
+    51059, 51043, 51027, 51011, 50995, 50979, 50963, 50947, 50931, 50915, 
+    50899, 50883, 50867, 50851, 50835, 50819, 50803, 50787, 50771, 50755, 
+    50739, 50723, 50707, 50691, 50675, 50659, 50643, 50627, 50611, 50595, 
+    50579, 50563, 50547, 50531, 50515, 50499, 50483, 50467, 50451, 50435, 
+    50419, 50403, 50387, 50371, 50355, 50339, 50323, 50307, 50291, 50275, 
+    50259, 50243, 50227, 50211, 50195, 50179, 50163, 50147, 50131, 50115, 
+    50099, 50083, 50067, 50051, 50035, 50019, 50003, 49987, 49971, 49955, 
+    49939, 49923, 49907, 49891, 49875, 49859, 49843, 49827, 49811, 49795, 
+    49779, 49763, 49747, 49731, 49715, 49699, 49683, 49667, 49651, 49635, 
+    49619, 49603, 49587, 49571, 49555, 49539, 49523, 49507, 49491, 49475, 
+    49459, 49443, 49427, 49411, 49395, 49379, 49363, 49347, 49331, 49315, 
+    49299, 49283, 49267, 49251, 49235, 49219, 49203, 49187, 49171, 49155, 
+    49139, 49123, 49107, 49091, 49075, 49059, 49043, 49027, 49011, 48995, 
+    48979, 48963, 48947, 48931, 48915, 48899, 48883, 48867, 48851, 48835, 
+    48819, 48803, 48787, 48771, 48755, 48739, 48723, 48707, 48691, 48675, 
+    48659, 48643, 48627, 48611, 48595, 48579, 48563, 48547, 48531, 48515, 
+    48499, 48483, 48467, 48451, 48435, 48419, 48403, 48387, 48371, 48355, 
+    48339, 48323, 48307, 48291, 48275, 48259, 48243, 48227, 48211, 48195, 
+    48179, 48163, 48147, 48131, 48115, 48099, 48083, 48067, 48051, 48035, 
+    48019, 48003, 47987, 47971, 47955, 47939, 47923, 47907, 47891, 47875, 
+    47859, 47843, 47827, 47811, 47795, 47779, 47763, 47747, 47731, 47715, 
+    47699, 47683, 47667, 47651, 47635, 47619, 47603, 47587, 47571, 47555, 
+    47539, 47523, 47507, 47491, 47475, 47459, 47443, 47427, 47411, 47395, 
+    47379, 47363, 47347, 47331, 47315, 47299, 47283, 47267, 47251, 47235, 
+    47219, 47203, 47187, 47171, 47155, 47139, 47123, 47107, 47091, 47075, 
+    47059, 47043, 47027, 47011, 46995, 46979, 46963, 46947, 46931, 46915, 
+    46899, 46883, 46867, 46851, 46835, 46819, 46803, 46787, 46771, 46755, 
+    46739, 46723, 46707, 48181, 48388, 48372, 48356, 48340, 46611, 46595, 
+    46579, 46563, 46547, 46531, 46515, 46499, 46483, 46467, 46451, 46435, 
+    46419, 46403, 46387, 46371, 46355, 46339, 46323, 46307, 46291, 46275, 
+    46259, 46243, 46227, 46211, 46195, 46179, 46163, 46147, 46131, 46115, 
+    46099, 46083, 46067, 46051, 46035, 46019, 46003, 45987, 45971, 45955, 
+    45939, 45923, 45907, 45891, 45875, 45859, 45843, 45827, 45811, 45795, 
+    45779, 45763, 45747, 45731, 45715, 45699, 45683, 45667, 45651, 45635, 
+    45619, 45603, 45587, 45571, 45555, 45539, 45523, 45507, 45491, 45475, 
+    45459, 45443, 45427, 45411, 45395, 45379, 45363, 45347, 45331, 45315, 
+    45299, 45283, 45267, 45251, 45235, 45219, 45203, 45187, 45171, 45155, 
+    45139, 45123, 45107, 45091, 45075, 45059, 45043, 45027, 45011, 44995, 
+    44979, 44963, 44947, 44931, 44915, 44899, 44883, 44867, 44851, 44835, 
+    44819, 44803, 44787, 44771, 44755, 44739, 44723, 44707, 44691, 44675, 
+    44659, 44643, 44627, 44611, 44595, 44579, 44563, 44547, 44531, 44515, 
+    44499, 44483, 44467, 44451, 44435, 44419, 44403, 44387, 44371, 44355, 
+    44339, 44323, 44307, 44291, 44275, 44259, 44243, 44227, 44211, 44195, 
+    44179, 44163, 44147, 44131, 44115, 44099, 44083, 44067, 44051, 44035, 
+    44019, 44003, 43987, 43971, 43955, 43939, 43923, 43907, 43891, 43875, 
+    43859, 43843, 43827, 43811, 43795, 43779, 43763, 43747, 43731, 43715, 
+    43699, 43683, 43667, 43651, 43635, 43619, 43603, 43587, 43571, 43555, 
+    43539, 43523, 43507, 43491, 43475, 43459, 43443, 43427, 43411, 43395, 
+    43379, 43363, 43347, 43331, 43315, 43299, 43283, 43267, 43251, 43235, 
+    43219, 43203, 43187, 43171, 43155, 43139, 43123, 43107, 43091, 43075, 
+    43059, 43043, 43027, 43011, 42995, 42979, 42963, 42947, 42931, 42915, 
+    42899, 42883, 42867, 42851, 42835, 42819, 42803, 42787, 42771, 42755, 
+    42739, 42723, 42707, 42691, 42675, 42659, 42643, 42627, 42611, 42595, 
+    42579, 42563, 42547, 42531, 42515, 42499, 42483, 42467, 42451, 42435, 
+    42419, 42403, 42387, 42371, 42355, 42339, 42323, 42307, 42291, 42275, 
+    42259, 42243, 42227, 42211, 42195, 42179, 42163, 42147, 42131, 42115, 
+    42099, 42083, 42067, 42051, 42035, 42019, 42003, 41987, 41971, 41955, 
+    41939, 41923, 41907, 41891, 41875, 41859, 41843, 41827, 41811, 41795, 
+    41779, 41763, 41747, 41731, 41715, 41699, 41683, 41667, 41651, 41635, 
+    41619, 41603, 41587, 41571, 41555, 41539, 41523, 41507, 41491, 41475, 
+    41459, 41443, 41427, 41411, 41395, 41379, 41363, 41347, 41331, 41315, 
+    41299, 41283, 41267, 41251, 41235, 41219, 41203, 41187, 41171, 41155, 
+    41139, 41123, 41107, 41091, 41075, 41059, 41043, 41027, 41011, 40995, 
+    40979, 40963, 40947, 40931, 40915, 40899, 40883, 40867, 40851, 40835, 
+    40819, 40803, 40787, 40771, 40755, 40739, 40723, 40707, 40691, 40675, 
+    40659, 40643, 40627, 40611, 40595, 40579, 40563, 40547, 40531, 40515, 
+    40499, 40483, 40467, 40451, 40435, 40419, 40403, 40387, 40371, 40355, 
+    40339, 40323, 40307, 40291, 40275, 40259, 40243, 40227, 40211, 40195, 
+    40179, 40163, 40147, 40131, 40115, 40099, 40083, 40067, 40051, 40035, 
+    40019, 40003, 39987, 39971, 39955, 39939, 39923, 39907, 39891, 39875, 
+    39859, 39843, 39827, 39811, 39795, 39779, 39763, 39747, 39731, 39715, 
+    39699, 39683, 39667, 39651, 39635, 39619, 39603, 39587, 39571, 39555, 
+    39539, 39523, 39507, 39491, 39475, 39459, 39443, 39427, 39411, 39395, 
+    39379, 39363, 39347, 39331, 39315, 39299, 39283, 39267, 39251, 39235, 
+    39219, 39203, 39187, 39171, 39155, 39139, 39123, 39107, 39091, 39075, 
+    39059, 39043, 39027, 39011, 38995, 38979, 38963, 38947, 38931, 38915, 
+    38899, 38883, 38867, 38851, 38835, 38819, 38803, 38787, 38771, 38755, 
+    38739, 38723, 38707, 38691, 38675, 38659, 38643, 38627, 38611, 38595, 
+    38579, 38563, 38547, 38531, 38515, 38499, 38483, 38467, 38451, 38435, 
+    38419, 38403, 38387, 38371, 38355, 38339, 38323, 38307, 38291, 38275, 
+    38259, 38243, 38227, 38211, 38195, 38179, 38163, 38147, 38131, 38115, 
+    38099, 38083, 38067, 38051, 38035, 38019, 38003, 37987, 37971, 37955, 
+    37939, 37923, 37907, 37891, 37875, 37859, 37843, 37827, 37811, 37795, 
+    37779, 37763, 37747, 37731, 37715, 37699, 37683, 37667, 37651, 37635, 
+    37619, 37603, 37587, 37571, 37555, 37539, 37523, 37507, 37491, 37475, 
+    37459, 37443, 37427, 37411, 37395, 37379, 37363, 37347, 37331, 37315, 
+    37299, 37283, 37267, 37251, 37235, 37219, 37203, 37187, 37171, 37155, 
+    37139, 37123, 37107, 37091, 37075, 37059, 37043, 37027, 37011, 36995, 
+    36979, 36963, 36947, 36931, 36915, 36899, 36883, 36867, 36851, 36835, 
+    36819, 36803, 36787, 36771, 36755, 36739, 36723, 36707, 36691, 36675, 
+    36659, 36643, 36627, 36611, 36595, 36579, 36563, 36547, 36531, 36515, 
+    36499, 36483, 36467, 36451, 36435, 36419, 36403, 36387, 36371, 36355, 
+    36339, 36323, 36307, 36291, 36275, 36259, 36243, 36227, 36211, 36195, 
+    36179, 36163, 36147, 36131, 36115, 36099, 36083, 36067, 36051, 36035, 
+    36019, 36003, 35987, 35971, 35955, 35939, 35923, 35907, 35891, 35875, 
+    35859, 35843, 35827, 35811, 35795, 35779, 35763, 35747, 35731, 35715, 
+    35699, 35683, 35667, 35651, 35635, 35619, 35603, 35587, 35571, 35555, 
+    35539, 35523, 35507, 35491, 35475, 35459, 35443, 35427, 35411, 35395, 
+    35379, 35363, 35347, 35331, 35315, 35299, 35283, 35267, 35251, 35235, 
+    35219, 35203, 35187, 35171, 35155, 35139, 35123, 35107, 35091, 35075, 
+    35059, 35043, 35027, 35011, 34995, 34979, 34963, 34947, 34931, 34915, 
+    34899, 34883, 34867, 34851, 34835, 34819, 34803, 34787, 34771, 34755, 
+    34739, 34723, 34707, 34691, 34675, 34659, 34643, 34627, 34611, 34595, 
+    34579, 34563, 34547, 34531, 34515, 34499, 34483, 34467, 34451, 34435, 
+    34419, 34403, 34387, 34371, 34355, 34339, 34323, 34307, 34291, 34275, 
+    34259, 34243, 34227, 34211, 34195, 34179, 34163, 34147, 34131, 34115, 
+    34099, 34083, 34067, 34051, 34035, 34019, 34003, 33987, 33971, 33955, 
+    33939, 33923, 33907, 33891, 33875, 33859, 33843, 33827, 33811, 33795, 
+    33779, 33763, 33747, 33731, 33715, 33699, 33683, 33667, 33651, 33635, 
+    33619, 33603, 33587, 33571, 33555, 33539, 33523, 33507, 33491, 33475, 
+    33459, 33443, 33427, 33411, 33395, 33379, 33363, 33347, 33331, 33315, 
+    33299, 33283, 33267, 33251, 33235, 33219, 33203, 33187, 33171, 33155, 
+    33139, 33123, 33107, 33091, 33075, 33059, 33043, 33027, 33011, 32995, 
+    32979, 32963, 32947, 32931, 32915, 32899, 32883, 32867, 32851, 32835, 
+    32819, 32803, 32787, 32771, 32755, 32739, 32723, 32707, 32691, 32675, 
+    32659, 32643, 32627, 32611, 32595, 32579, 32563, 32547, 32531, 32515, 
+    32499, 32483, 32467, 32451, 32435, 32419, 32403, 32387, 32371, 32355, 
+    32339, 32323, 32307, 32291, 32275, 32259, 32243, 32227, 32211, 32195, 
+    32179, 32163, 32147, 32131, 32115, 32099, 32083, 32067, 32051, 32035, 
+    32019, 32003, 31987, 31971, 31955, 31939, 31923, 31907, 31891, 31875, 
+    31859, 31843, 31827, 31811, 31795, 31779, 31763, 31747, 31731, 31715, 
+    31699, 31683, 31667, 31651, 31635, 31619, 31603, 31587, 31571, 31555, 
+    31539, 31523, 31507, 31491, 31475, 31459, 31443, 31427, 31411, 31395, 
+    31379, 31363, 31347, 31331, 31315, 31299, 31283, 31267, 31251, 31235, 
+    31219, 31203, 31187, 31171, 31155, 31139, 31123, 31107, 31091, 31075, 
+    31059, 31043, 31027, 31011, 30995, 30979, 30963, 30947, 30931, 30915, 
+    30899, 30883, 30867, 30851, 30835, 30819, 30803, 30787, 30771, 30755, 
+    30739, 30723, 30707, 30691, 30675, 30659, 30643, 30627, 30611, 30595, 
+    30579, 30563, 30547, 30531, 30515, 30499, 30483, 30467, 30451, 30435, 
+    30419, 30403, 30387, 30371, 30355, 30339, 30323, 30307, 30291, 30275, 
+    30259, 30243, 30227, 30211, 30195, 30179, 30163, 30147, 30131, 30115, 
+    30099, 30083, 30067, 30051, 30035, 30019, 30003, 29987, 29971, 29955, 
+    29939, 29923, 29907, 29891, 29875, 29859, 29843, 29827, 29811, 29795, 
+    29779, 29763, 29747, 29731, 29715, 29699, 29683, 29667, 29651, 29635, 
+    29619, 29603, 29587, 29571, 29555, 29539, 29523, 29507, 29491, 29475, 
+    29459, 29443, 29427, 29411, 29395, 29379, 29363, 29347, 29331, 29315, 
+    29299, 29283, 29267, 29251, 29235, 29219, 29203, 29187, 29171, 29155, 
+    29139, 29123, 29107, 29091, 29075, 29059, 29043, 29027, 29011, 28995, 
+    28979, 28963, 28947, 28931, 28915, 28899, 28883, 28867, 28851, 28835, 
+    28819, 28803, 28787, 28771, 28755, 28739, 28723, 28707, 28691, 28675, 
+    28659, 28643, 28627, 28611, 28595, 28579, 28563, 28547, 28531, 28515, 
+    28499, 28483, 28467, 28451, 28435, 28419, 28403, 28387, 28371, 28355, 
+    28339, 28323, 28307, 28291, 28275, 28259, 28243, 28227, 28211, 28195, 
+    28179, 28163, 28147, 28131, 28115, 28099, 28083, 28067, 28051, 28035, 
+    28019, 28003, 27987, 27971, 27955, 27939, 27923, 27907, 27891, 27875, 
+    27859, 27843, 27827, 27811, 27795, 27779, 27763, 27747, 27731, 27715, 
+    27699, 27683, 27667, 27651, 27635, 27619, 27603, 27587, 27571, 27555, 
+    27539, 27523, 27507, 27491, 27475, 27459, 27443, 27427, 27411, 27395, 
+    27379, 27363, 27347, 27331, 27315, 27299, 27283, 27267, 27251, 27235, 
+    27219, 27203, 27187, 27171, 27155, 27139, 27123, 27107, 27091, 27075, 
+    27059, 27043, 27027, 27011, 26995, 26979, 26963, 26947, 26931, 26915, 
+    26899, 26883, 26867, 26851, 26835, 26819, 26803, 26787, 26771, 26755, 
+    26739, 26723, 26707, 26691, 26675, 26659, 26643, 26627, 26611, 26595, 
+    26579, 26563, 26547, 26531, 26515, 26499, 26483, 26467, 26451, 26435, 
+    26419, 26403, 26387, 26371, 26355, 26339, 26323, 26307, 26291, 26275, 
+    26259, 26243, 26227, 26211, 26195, 26179, 26163, 26147, 26131, 26115, 
+    26099, 26083, 26067, 26051, 26035, 26019, 26003, 25987, 25971, 25955, 
+    25939, 25923, 25907, 25891, 25875, 25859, 25843, 25827, 25811, 25795, 
+    25779, 25763, 25747, 25731, 27205, 25452, 25436, 25420, 25404, 25388, 
+    25619, 25603, 25587, 25571, 25555, 25539, 25523, 25507, 25491, 25475, 
+    25459, 25443, 25427, 25411, 25395, 25379, 25363, 25347, 25331, 25315, 
+    25299, 25283, 25267, 25251, 25235, 25219, 25203, 25187, 25171, 25155, 
+    25139, 25123, 25107, 25091, 25075, 25059, 25043, 25027, 25011, 24995, 
+    24979, 24963, 24947, 24931, 24915, 24899, 24883, 24867, 24851, 24835, 
+    24819, 24803, 24787, 24771, 24755, 24739, 24723, 24707, 24691, 24675, 
+    24659, 24643, 24627, 24611, 24595, 24579, 24563, 24547, 24531, 24515, 
+    24499, 24483, 25465, 26164, 26148, 26132, 26931, 24140, 24124, 24108, 
+    24092, 24076, 24060, 24044, 24028, 24012, 23996, 23980, 23964, 23948, 
+    23932, 23916, 23900, 23884, 23868, 23852, 23836, 23820, 23804, 23788, 
+    23772, 23756, 23740, 23724, 23708, 23692, 23676, 23660, 23644, 23628, 
+    23612, 23596, 23580, 23564, 23548, 23532, 23516, 23500, 23484, 23468, 
+    23452, 23436, 23420, 23404, 23388, 23372, 23356, 23340, 23324, 23308, 
+    23292, 23276, 23260, 23244, 23228, 23212, 23196, 23180, 23164, 23148, 
+    23132, 23116, 23100, 23084, 23068, 23052, 23036, 23020, 23004, 22988, 
+    22972, 22956, 22940, 22924, 22908, 22892, 22876, 22860, 22844, 22828, 
+    22812, 22796, 22780, 22764, 22748, 22732, 22716, 22700, 22684, 22668, 
+    22652, 22636, 22620, 22604, 22588, 22572, 22556, 22540, 22524, 22508, 
+    22492, 22476, 22460, 22444, 22428, 22412, 22396, 22380, 22364, 22348, 
+    22332, 22316, 22547, 22531, 22515, 22499, 22483, 22467, 22451, 22435, 
+    22419, 22403, 22387, 22371, 22355, 22339, 22323, 22307, 22291, 22275, 
+    22259, 22243, 22227, 22211, 22195, 22179, 22163, 22147, 22131, 22115, 
+    22099, 22083, 22067, 22051, 22035, 22019, 22003, 21987, 21971, 21955, 
+    21939, 21923, 21907, 21891, 21875, 21859, 21843, 21827, 21811, 21795, 
+    21779, 21763, 21747, 21731, 21715, 21699, 21683, 21667, 21651, 21635, 
+    21619, 21603, 21587, 21571, 21555, 21539, 21523, 21507, 21491, 21475, 
+    21459, 21443, 21427, 21411, 21395, 21379, 21363, 21347, 21331, 21315, 
+    21299, 21283, 21267, 21251, 21235, 21219, 21203, 21187, 21171, 21155, 
+    21139, 21123, 21107, 21091, 21075, 21059, 21043, 21027, 21011, 20995, 
+    20979, 20963, 20947, 20931, 20915, 20899, 20883, 20867, 20851, 20835, 
+    20819, 20803, 20787, 20771, 20755, 20739, 20723, 20707, 20691, 20675, 
+    20659, 20643, 20627, 20611, 20595, 20579, 20563, 20547, 20531, 20515, 
+    20499, 20483, 20467, 20451, 20435, 20419, 20403, 20387, 20371, 20355, 
+    20339, 20323, 20307, 20291, 20275, 20259, 20243, 20227, 20211, 20195, 
+    20179, 20163, 20147, 20131, 20115, 20099, 20083, 20067, 20051, 20035, 
+    20019, 20003, 19987, 19971, 19955, 19939, 19923, 19907, 19891, 19875, 
+    19859, 19843, 19827, 19811, 19795, 19779, 19763, 19747, 19731, 19715, 
+    19699, 19683, 19667, 19651, 19635, 19619, 19603, 19587, 19571, 19555, 
+    19539, 19523, 19507, 19491, 19475, 19459, 19443, 19427, 19411, 19395, 
+    19379, 19363, 19347, 19331, 19315, 19299, 19283, 19267, 19251, 19235, 
+    19219, 19203, 19187, 19171, 19155, 19139, 19123, 19107, 19091, 19075, 
+    19059, 19043, 19027, 19011, 18995, 18979, 18963, 18947, 18931, 18915, 
+    18899, 18883, 18867, 18851, 18835, 18819, 18803, 18787, 18771, 18755, 
+    18739, 18723, 18707, 18691, 18675, 18659, 18643, 18627, 18611, 18595, 
+    18579, 18563, 18547, 18531, 18515, 18499, 18483, 18467, 18451, 18435, 
+    18419, 18403, 18387, 18371, 18355, 18339, 18323, 18307, 18291, 18275, 
+    18259, 18243, 18227, 18211, 18195, 18179, 18163, 18147, 18131, 18115, 
+    18099, 18083, 18067, 18051, 18035, 18019, 18003, 17987, 17971, 17955, 
+    17939, 17923, 17907, 17891, 17875, 17859, 17843, 17827, 17811, 17795, 
+    17779, 17763, 17747, 17731, 17715, 17699, 17683, 17667, 17651, 17635, 
+    17619, 17603, 17587, 17571, 17555, 17539, 17523, 17507, 17491, 17475, 
+    17459, 17443, 17427, 17411, 17395, 17379, 17363, 17347, 17331, 17315, 
+    17299, 17283, 17267, 17251, 17235, 17219, 17203, 17187, 17171, 17155, 
+    17139, 17123, 17107, 17091, 17075, 17059, 17043, 17027, 17011, 16995, 
+    16979, 16963, 16947, 16931, 16915, 16899, 16883, 16867, 16851, 16835, 
+    16819, 16803, 16787, 16771, 16755, 16739, 16723, 16707, 16691, 16675, 
+    16659, 16643, 16627, 16611, 16595, 16579, 16563, 16547, 16531, 16515, 
+    16499, 16483, 16467, 16451, 16435, 16419, 16403, 16387, 16371, 16355, 
+    16339, 16323, 16307, 16291, 16275, 16259, 16243, 16227, 16211, 16195, 
+    16179, 16163, 16147, 16131, 16115, 16099, 16083, 16067, 16051, 16035, 
+    16019, 16003, 15987, 15971, 15955, 15939, 15923, 15907, 15891, 15875, 
+    15859, 15843, 15827, 15811, 15795, 15779, 15763, 15747, 15731, 15715, 
+    15699, 15683, 15667, 15651, 15635, 15619, 15603, 15587, 15571, 15555, 
+    15539, 15523, 15507, 15491, 15475, 15459, 15443, 15427, 15411, 15395, 
+    15379, 15363, 15347, 15331, 15315, 15299, 15283, 15267, 15251, 15235, 
+    15219, 15203, 15187, 15171, 15155, 15139, 15123, 15107, 15091, 15075, 
+    15059, 15043, 15027, 15011, 14995, 14979, 14963, 14947, 14931, 14915, 
+    14899, 14883, 14867, 14851, 14835, 14819, 14803, 14787, 14771, 14755, 
+    14739, 14723, 14707, 14691, 14675, 14659, 14643, 14627, 14611, 14595, 
+    14579, 14563, 14547, 14531, 14515, 14499, 14483, 14467, 14451, 14435, 
+    14419, 14403, 14387, 14371, 14355, 14339, 14323, 14307, 14291, 14275, 
+    14259, 14243, 14227, 14211, 14195, 14179, 14163, 14147, 14131, 14115, 
+    14099, 14083, 14067, 14051, 14035, 14019, 14003, 13987, 13971, 13955, 
+    13939, 13923, 13907, 13891, 13875, 13859, 13843, 13827, 13811, 13795, 
+    13779, 13763, 13747, 13731, 13715, 13699, 13683, 13667, 13651, 13635, 
+    13619, 13603, 13587, 13571, 13555, 13539, 13523, 13507, 13491, 13475, 
+    13459, 13443, 13427, 13411, 13395, 13379, 13363, 13347, 13331, 13315, 
+    13299, 13283, 13267, 13251, 13235, 13219, 13203, 13187, 13171, 13155, 
+    13139, 13123, 13107, 13091, 13075, 13059, 13043, 13027, 13011, 12995, 
+    12979, 12963, 12947, 12931, 12915, 12899, 12883, 12867, 12851, 12835, 
+    12819, 12803, 12787, 12771, 12755, 12739, 12723, 12707, 12691, 12675, 
+    12659, 12643, 12627, 12611, 12595, 12579, 12563, 12547, 12531, 12515, 
+    12499, 12483, 12467, 12451, 12435, 12419, 12403, 12387, 12371, 12355, 
+    12339, 12323, 12307, 12291, 12275, 12259, 12243, 12227, 12211, 12195, 
+    12179, 12163, 12147, 12131, 12115, 12099, 12083, 12067, 12051, 12035, 
+    12019, 12003, 11987, 11971, 11955, 11939, 11923, 11907, 11891, 11875, 
+    11859, 11843, 11827, 11811, 11795, 11779, 11763, 11747, 11731, 11715, 
+    11699, 11683, 11667, 11651, 11635, 11619, 11603, 11587, 11571, 11555, 
+    11539, 11523, 11507, 11491, 11475, 11459, 11443, 11427, 11411, 11395, 
+    12871, 11116, 11100, 11084, 11068, 11052, 14050, 14034, 14018, 14002, 
+    13986, 13970, 13954, 13938, 13922, 13906, 13890, 13874, 13858, 13842, 
+    13826, 13810, 13794, 13778, 13762, 13746, 13730, 13714, 13698, 13682, 
+    13666, 13650, 13634, 13618, 13602, 13586, 13570, 13554, 13538, 13522, 
+    13506, 13490, 13474, 13458, 13442, 13426, 13410, 13394, 13378, 13362, 
+    13346, 13330, 13314, 13298, 13282, 13266, 13250, 13234, 13218, 13202, 
+    13186, 13170, 13154, 13138, 13122, 13106, 13090, 13074, 13058, 13042, 
+    13026, 13010, 12994, 12978, 12962, 12946, 12930, 12914, 12898, 12882, 
+    12866, 12850, 12834, 12818, 12802, 12786, 12770, 12754, 12738, 12722, 
+    12706, 12690, 12674, 12658, 12642, 12626, 12610, 12594, 12578, 12562, 
+    12546, 12530, 12514, 12498, 12482, 12466, 12450, 12434, 12418, 12402, 
+    12386, 12370, 12354, 12338, 12322, 12306, 12290, 12274, 12258, 12242, 
+    12226, 12210, 12194, 12178, 12162, 12146, 12130, 12114, 12098, 12082, 
+    12066, 12050, 12034, 12018, 12018, 12002, 11986, 11970, 11954, 11938, 
+    11922, 11906, 11890, 11874, 11858, 11842, 11826, 11810, 11794, 11778, 
+    11762, 11746, 11730, 11714, 11698, 11682, 11666, 11650, 11634, 11618, 
+    11602, 11586, 11570, 11554, 11538, 11522, 11506, 11490, 11474, 11458, 
+    11442, 11426, 11410, 11394, 11378, 11362, 11346, 11330, 11314, 11298, 
+    11282, 11266, 11250, 11234, 11218, 11202, 11186, 11170, 11154, 11138, 
+    11122, 11106, 11090, 11074, 11058, 11042, 11026, 11010, 10994, 10978, 
+    10962, 10946, 10930, 10914, 10898, 10882, 10866, 10850, 10834, 10818, 
+    10802, 10786, 10770, 10754, 10738, 10722, 10706, 10690, 10674, 10658, 
+    10642, 10626, 10610, 10594, 10578, 10562, 10546, 10530, 10514, 10498, 
+    10482, 10466, 10450, 10434, 10418, 10402, 10386, 10370, 10354, 10338, 
+    10322, 10306, 10290, 10274, 10258, 10242, 10226, 10210, 10194, 10178, 
+    10162, 10146, 10130, 10114, 10098, 10082, 10066, 10050, 10034, 10018, 
+    10002, 9986, 9970, 9954, 9938, 9922, 9906, 9890, 9874, 9858, 
+    9842, 9826, 9810, 9794, 9778, 9762, 9746, 9730, 9714, 9698, 
+    9682, 9666, 9650, 9634, 9618, 9602, 9586, 9570, 9554, 9538, 
+    9522, 9506, 9490, 9474, 9458, 9442, 9426, 9410, 9394, 9378, 
+    9362, 9346, 9330, 9314, 9298, 9282, 9266, 9250, 9234, 9218, 
+    9202, 9186, 9170, 9154, 9138, 9122, 9106, 9090, 9074, 9058, 
+    9042, 9026, 9010, 8994, 8978, 8962, 8946, 8930, 8914, 8898, 
+    8882, 8866, 8850, 8834, 8818, 8802, 8786, 8770, 8754, 8738, 
+    8722, 8706, 8690, 8674, 8658, 8642, 8626, 8610, 8594, 8578, 
+    8562, 8546, 8530, 8514, 8498, 8482, 8466, 8450, 8434, 8418, 
+    8402, 8386, 8370, 8354, 8338, 8322, 8306, 8290, 8274, 8258, 
+    8242, 8226, 8210, 8194, 8178, 8162, 8146, 8130, 8114, 8098, 
+    8082, 8066, 8050, 8034, 8018, 8002, 7986, 7970, 7954, 7938, 
+    7922, 7906, 7890, 7874, 7858, 7842, 7826, 7810, 7794, 7778, 
+    7762, 7746, 7730, 7714, 7698, 7682, 7666, 7650, 7634, 7618, 
+    7602, 7586, 7570, 7554, 7538, 7522, 7506, 7490, 7474, 7458, 
+    7442, 7426, 7410, 7394, 7378, 7362, 7346, 7330, 7314, 7298, 
+    7282, 7266, 7250, 7234, 7218, 7202, 7186, 7170, 7154, 7138, 
+    7122, 7106, 7090, 7074, 7058, 7042, 7026, 7010, 6994, 6978, 
+    6962, 6946, 6930, 6914, 6898, 6882, 6866, 6850, 6834, 6818, 
+    6802, 6786, 6770, 6754, 6738, 6722, 6706, 6690, 6674, 6658, 
+    6642, 6626, 6610, 6594, 6578, 6562, 6546, 6530, 6514, 6498, 
+    6482, 6466, 6450, 6434, 6418, 6402, 6386, 6370, 6354, 6338, 
+    6322, 6306, 6290, 6274, 6258, 6242, 6226, 6210, 6194, 6178, 
+    6162, 6146, 6130, 6114, 6098, 6082, 6066, 6050, 6034, 6018, 
+    6002, 5986, 5970, 5954, 5938, 5922, 5906, 5890, 5874, 5858, 
+    5842, 5826, 5810, 5794, 5778, 5762, 5746, 5730, 5714, 5698, 
+    5682, 5666, 5650, 5634, 2835, 2819, 2803, 2787, 2771, 2755, 
+    2739, 2723, 2707, 2691, 2675, 2659, 2643, 2627, 2611, 2595, 
+    2579, 2563, 3544, 2531, 2515, 2499, 3483, 2220, 2204, 2188, 
+    2172, 2156, 2140, 2124, 2108, 2092, 5122, 2869, 5106, 5100, 
+    2836, 2111, 2095, 2079, 2063, 2047, 2031, 2946, 1884, 1980, 
+    1967, 1951, 1935, 1919, 1903, 1887, 1871, 1855, 1839, 1823, 
+    1807, 1791, 1775, 1759, 1743, 1727, 1711, 1695, 1679, 1663, 
+    1647, 1633, 1500, 1599, 1583, 1567, 1551, 1533, 1519, 1503, 
+    2412, 1356, 1340, 2473, 1638, 1292, 2072, 4348, 4344, 3614, 
+    4328, 2227, 1295, 1279, 1263, 1247, 1231, 1215, 1199, 2172, 
+    1941, 295, 340, 340, 378, 4104, 2137, 2221, 1171, 1157, 
+    1139, 1107, 451, 907, 3976, 819, 
+};
 
+static const jchar blocks1[] = {
+    0, 65535, 63, 4, 4, 253, 189, 125, 61, 65533, 
+    65469, 65405, 65405, 65266, 65325, 65149, 64639, 64623, 65133, 64893, 
+    64829, 64765, 64701, 64637, 64573, 64509, 64445, 64381, 64317, 64253, 
+    64189, 64125, 64301, 63997, 63933, 63869, 63805, 63741, 63677, 63613, 
+    63549, 63485, 63421, 63357, 63293, 63229, 63165, 63101, 63037, 62973, 
+    62909, 62845, 62781, 62717, 62653, 62589, 62525, 62461, 62397, 62333, 
+    62269, 62205, 62141, 62077, 62013, 61949, 61885, 61821, 61757, 61693, 
+    61629, 61565, 61501, 61437, 61373, 61309, 61245, 61181, 61117, 61053, 
+    60989, 60925, 60861, 60797, 60733, 60669, 60605, 60541, 60477, 60413, 
+    60349, 60285, 60221, 60157, 60093, 60029, 59965, 59901, 59837, 59773, 
+    59709, 59645, 59581, 59517, 59453, 59389, 59325, 59261, 59197, 59133, 
+    59069, 59005, 58941, 58877, 58813, 58749, 58685, 58621, 58557, 58493, 
+    58429, 58365, 58301, 58237, 58173, 58109, 58045, 57981, 57917, 57853, 
+    57789, 57725, 57661, 57597, 57533, 57469, 57405, 57341, 57277, 57213, 
+    57149, 57085, 57021, 56957, 56893, 56829, 56765, 56701, 56637, 56573, 
+    56509, 56445, 56381, 56317, 56253, 56189, 56125, 56061, 55997, 55933, 
+    55869, 55805, 55741, 55677, 55613, 55549, 55485, 55421, 55357, 55293, 
+    55229, 55165, 55101, 55037, 54973, 54909, 54845, 54781, 54717, 54653, 
+    54589, 54525, 54461, 54397, 54333, 54269, 54205, 54141, 54077, 54013, 
+    53949, 53885, 53821, 53757, 53693, 53629, 53565, 53501, 53437, 53373, 
+    53309, 53245, 53181, 53117, 53053, 52989, 52925, 52861, 52797, 52733, 
+    52669, 52605, 52541, 52477, 52413, 52349, 52285, 52221, 52157, 52093, 
+    52029, 51965, 51901, 51837, 51773, 51709, 51645, 51581, 51517, 51453, 
+    51389, 51325, 51261, 51197, 51133, 51069, 51005, 50941, 50877, 50813, 
+    50749, 50685, 50621, 50557, 50493, 50429, 50365, 50301, 50237, 50173, 
+    50109, 50045, 49981, 49917, 49853, 49789, 49725, 49661, 49597, 49533, 
+    49469, 49405, 49341, 49277, 49213, 49149, 49085, 49021, 48957, 48893, 
+    48829, 48765, 48701, 48637, 48573, 48509, 48445, 48381, 48317, 48253, 
+    48189, 48125, 48061, 47997, 47933, 47869, 47805, 47741, 47677, 47613, 
+    47549, 47485, 47421, 47357, 47293, 47229, 47165, 47101, 47037, 46973, 
+    46909, 46845, 46781, 46717, 46653, 46589, 46525, 46461, 46397, 46333, 
+    46269, 46205, 46141, 46077, 46013, 45949, 45885, 45821, 45757, 45693, 
+    45629, 45565, 45501, 45437, 45373, 45309, 45245, 45181, 45117, 45053, 
+    44989, 44925, 44861, 44797, 44733, 44669, 44605, 44541, 44477, 44413, 
+    44349, 44285, 44221, 44157, 44093, 44029, 43965, 43901, 43837, 43773, 
+    43709, 43645, 43581, 43517, 43453, 43389, 43325, 43261, 43197, 43133, 
+    43069, 43005, 42941, 42877, 42813, 42749, 42685, 42621, 42557, 42493, 
+    42429, 42365, 42301, 42237, 42173, 42109, 42045, 41981, 41917, 41853, 
+    41789, 41725, 41661, 41597, 41533, 41469, 41405, 41341, 41277, 41213, 
+    41149, 41085, 41021, 40957, 40893, 40829, 40765, 40701, 40637, 40573, 
+    40509, 40445, 40381, 40317, 40253, 40189, 40125, 40061, 39997, 39933, 
+    39869, 39805, 39741, 39677, 39613, 39549, 39485, 39421, 39357, 39293, 
+    39229, 39165, 39101, 39037, 38973, 38909, 38845, 38781, 38717, 38653, 
+    38589, 38525, 38461, 38397, 38333, 38269, 38205, 38141, 38077, 38013, 
+    37949, 37885, 37821, 37757, 37693, 37629, 37565, 37501, 37437, 37373, 
+    37309, 37245, 37181, 37117, 37053, 36989, 36925, 36861, 36797, 36733, 
+    36669, 36605, 36541, 36477, 36413, 36349, 36285, 36221, 36157, 36093, 
+    36029, 35965, 35901, 35837, 35773, 35709, 35645, 35581, 35517, 35453, 
+    35389, 35325, 35261, 35197, 35133, 35069, 35005, 34941, 34877, 34813, 
+    34749, 34685, 34621, 34557, 34493, 34429, 34365, 34301, 34237, 34173, 
+    34109, 34045, 33981, 33917, 33853, 33789, 33725, 33661, 33597, 33533, 
+    33469, 33405, 33341, 33277, 33213, 33149, 33085, 33021, 32957, 32893, 
+    32829, 32765, 32701, 32637, 32573, 32509, 32445, 32381, 32317, 32253, 
+    32189, 32125, 32061, 31997, 31933, 31869, 31805, 31741, 31677, 31613, 
+    31549, 31485, 31421, 31357, 31293, 31229, 31165, 31101, 31037, 30973, 
+    30909, 30845, 30781, 30717, 30653, 30589, 30525, 30461, 30397, 30333, 
+    30269, 30205, 30141, 30077, 30013, 29949, 29885, 29821, 29757, 29693, 
+    29629, 29565, 29501, 29437, 29373, 29309, 29245, 29181, 29117, 29053, 
+    28989, 28925, 28861, 28797, 28733, 28669, 28605, 28541, 28477, 28413, 
+    28349, 28285, 28221, 28157, 28093, 28029, 27965, 27901, 27837, 27773, 
+    27709, 27645, 27581, 27517, 27453, 27389, 27325, 27261, 27197, 27133, 
+    27069, 27005, 26941, 26877, 26813, 26749, 26685, 26621, 26557, 26493, 
+    26429, 26365, 26301, 26237, 26173, 26109, 26045, 25981, 25917, 25853, 
+    25789, 25725, 25661, 25597, 25533, 25469, 25405, 25341, 25277, 25213, 
+    25149, 25085, 25021, 24957, 24893, 24829, 24765, 24701, 24637, 24573, 
+    24509, 24445, 24381, 24317, 24253, 24189, 24125, 24061, 23997, 23933, 
+    23869, 23805, 23741, 23677, 23613, 23549, 23485, 23421, 23357, 23293, 
+    23229, 23165, 23101, 23037, 22973, 22909, 22845, 22781, 22717, 22653, 
+    22589, 22525, 22461, 22397, 22333, 22269, 22205, 22141, 22077, 22013, 
+    21949, 21885, 21821, 21757, 21693, 21629, 21565, 21501, 21437, 21373, 
+    21309, 21245, 21181, 21117, 21053, 20989, 20925, 20861, 20797, 20733, 
+    20669, 20605, 20541, 20477, 20413, 20349, 20285, 20221, 20157, 20093, 
+    20029, 19965, 19901, 19837, 19773, 19709, 19645, 19581, 19517, 19453, 
+    19389, 19325, 19261, 19197, 19133, 19069, 19005, 18941, 18877, 18813, 
+    18749, 18685, 18621, 18557, 18493, 18429, 18365, 18301, 18237, 18173, 
+    18109, 18045, 17981, 17917, 17853, 17789, 17725, 17661, 17597, 17533, 
+    17469, 17405, 17341, 17277, 17213, 17149, 17085, 17021, 16957, 16893, 
+    16829, 16765, 16701, 16637, 16573, 16509, 16445, 16381, 16317, 16253, 
+    16189, 16125, 16061, 15997, 15933, 15869, 15805, 15741, 15677, 15613, 
+    15549, 15485, 15421, 15357, 15293, 15229, 15165, 15101, 15037, 14973, 
+    14909, 14845, 14781, 14717, 14653, 14589, 14525, 14461, 14397, 14333, 
+    14269, 14205, 14141, 14077, 14013, 13949, 13885, 13821, 13757, 13693, 
+    13629, 13565, 13501, 13437, 13373, 13309, 13245, 13181, 13117, 13053, 
+    12989, 12925, 12752, 12688, 12624, 12570, 12454, 12283, 12280, 12338, 
+    12349, 12285, 12221, 12157, 12397, 12374, 11965, 11901, 12340, 12394, 
+    12451, 12132, 12384, 12197, 11976, 11924, 11820, 11768, 11768, 11542, 
+    11484, 11426, 11368, 11744, 10813, 10749, 10685, 10621, 10557, 10493, 
+    10429, 10365, 10301, 10237, 10173, 10109, 10045, 9981, 9917, 9853, 
+    9789, 9725, 9661, 9597, 9533, 9469, 9405, 9341, 9277, 9213, 
+    9149, 9085, 9021, 8957, 8893, 8829, 8765, 8701, 8637, 8573, 
+    8509, 8445, 8381, 8317, 8253, 8189, 8125, 8061, 7997, 7933, 
+    7869, 7805, 7741, 7677, 7613, 7549, 7485, 7421, 7357, 7293, 
+    7229, 7165, 7101, 7037, 6973, 6909, 6845, 6781, 6717, 6653, 
+    6589, 6525, 6461, 6397, 6333, 6269, 6205, 6141, 6077, 6013, 
+    5949, 5885, 5821, 5757, 5693, 5629, 5565, 5501, 5437, 5373, 
+    5309, 5245, 5181, 5117, 5053, 4989, 4925, 4861, 4797, 4733, 
+    4669, 4605, 4541, 4477, 4413, 4349, 4285, 4221, 4157, 4093, 
+    4029, 3965, 3901, 3837, 3773, 3709, 3645, 3581, 3517, 3453, 
+    3389, 3325, 3261, 3197, 3133, 3069, 3005, 2941, 2877, 2813, 
+    2749, 2685, 2621, 2557, 2493, 2429, 2365, 2301, 2237, 2173, 
+    2109, 2045, 1981, 1917, 1853, 1789, 1725, 1661, 1597, 1533, 
+    1469, 1405, 1341, 1277, 1213, 1149, 1085, 1021, 957, 893, 
+    829, 765, 701, 637, 
+};
+
+static const jchar blocks2[] = {
+    0, 65408, 65280, 65152, 65024, 64896, 64768, 64640, 64512, 64384, 
+    64256, 64128, 64000, 63872, 63744, 63616, 63488, 63360, 63232, 63104, 
+    62976, 62848, 62720, 62592, 62464, 62336, 62208, 62080, 61952, 61824, 
+    61696, 61568, 61440, 61312, 61184, 61056, 60928, 60800, 60672, 60544, 
+    60416, 60288, 60160, 60032, 59904, 59776, 59648, 59520, 59392, 59264, 
+    59136, 59008, 58880, 58752, 58624, 58496, 58368, 58240, 58112, 57984, 
+    57856, 57728, 57600, 57472, 57344, 57216, 57088, 56960, 56832, 56704, 
+    56576, 56448, 56320, 56192, 56064, 55936, 55808, 55680, 55552, 55424, 
+    55296, 55168, 55040, 54912, 54784, 54656, 54528, 54400, 54272, 54144, 
+    54016, 53888, 53760, 53632, 53504, 53376, 53248, 53120, 52992, 52864, 
+    52736, 52608, 52480, 52352, 52224, 52096, 51968, 51840, 51712, 51584, 
+    51456, 51328, 51200, 51072, 50944, 50816, 50688, 50560, 50432, 50304, 
+    50176, 50048, 49920, 49792, 49664, 49536, 49408, 49280, 49152, 49024, 
+    48896, 48768, 48640, 48512, 48384, 48256, 48128, 48000, 47872, 47744, 
+    47616, 47488, 47360, 47232, 47104, 46976, 46848, 46720, 46592, 46464, 
+    46336, 46208, 46080, 45952, 45824, 45696, 45568, 45440, 45312, 45184, 
+    45056, 44928, 44800, 44672, 44544, 44416, 44288, 44160, 44032, 43904, 
+    43776, 43648, 43520, 43392, 43264, 43136, 43008, 42880, 42752, 42624, 
+    42496, 42368, 42240, 42112, 41984, 41856, 41728, 41600, 41472, 41344, 
+    41216, 41088, 40960, 40832, 40704, 40576, 40448, 40320, 40192, 40064, 
+    39936, 39808, 39680, 39552, 39424, 39296, 39168, 39040, 38912, 38784, 
+    38656, 38528, 38400, 38272, 38144, 38016, 37888, 37760, 37632, 37504, 
+    37376, 37248, 37120, 36992, 36864, 36736, 36608, 36480, 36352, 36224, 
+    36096, 35968, 35840, 35712, 35584, 35456, 35328, 35200, 35072, 34944, 
+    34816, 34688, 34560, 34432, 34304, 34176, 34048, 33920, 33792, 33664, 
+    33536, 33408, 33280, 33152, 33024, 32896, 32768, 32640, 32512, 32384, 
+    32256, 32128, 32000, 31872, 31744, 31616, 31488, 31360, 31232, 31104, 
+    30976, 30848, 30720, 30592, 30464, 30336, 30208, 30080, 29952, 29824, 
+    29696, 29568, 29440, 29312, 29184, 29056, 28928, 28800, 28672, 28544, 
+    28416, 28288, 28160, 28032, 27904, 27776, 27648, 27520, 27392, 27264, 
+    27136, 27008, 26880, 26752, 26624, 26496, 26368, 26240, 26112, 25984, 
+    25856, 25728, 25600, 25472, 25344, 25216, 25088, 24960, 24832, 24704, 
+    24576, 24448, 24320, 24192, 24064, 23936, 23808, 23680, 23552, 23424, 
+    23296, 23168, 23040, 22953, 22912, 22784, 22656, 22528, 22400, 22272, 
+    22144, 22016, 21888, 21760, 21632, 21504, 21376, 21248, 21120, 20992, 
+    20864, 20736, 20608, 20480, 20352, 20224, 20096, 19968, 19840, 19712, 
+    19584, 19456, 19328, 19200, 19072, 18944, 18816, 18688, 18560, 18432, 
+    18304, 18176, 18048, 17920, 17792, 17664, 17536, 17408, 17280, 17152, 
+    17024, 16896, 16768, 16640, 16512, 16384, 16256, 16128, 16000, 15872, 
+    15744, 15616, 15488, 15360, 15232, 15104, 14976, 14848, 14720, 14592, 
+    14464, 14336, 14208, 14080, 13952, 13824, 13696, 13568, 13440, 13312, 
+    13184, 13056, 12928, 12800, 12672, 12544, 12416, 12288, 12160, 12032, 
+    11904, 11776, 11648, 11520, 11392, 11264, 11136, 11008, 10880, 10752, 
+    10624, 10496, 10368, 10240, 10112, 9984, 9856, 9728, 9600, 9472, 
+    9344, 9216, 9088, 8960, 8832, 8704, 8576, 8448, 8320, 8192, 
+    8064, 7936, 7808, 7680, 7552, 7424, 7296, 7168, 7040, 6912, 
+    6784, 6656, 6528, 6400, 6272, 6144, 6016, 5888, 5760, 5632, 
+    5504, 5376, 5248, 5120, 4992, 4864, 4736, 4608, 4480, 4352, 
+    4224, 4096, 3968, 3840, 3712, 3584, 3456, 3328, 3200, 3072, 
+    2944, 2816, 2688, 2560, 2432, 2304, 2048, 1920, 1792, 1664, 
+    1634, 1536, 1408, 1280, 1152, 1024, 896, 768, 640, 512, 
+    384, 256, 
+};
+
+static const jchar blocks14[] = {
+    255, 0, 65280, 65168, 65152, 65024, 64896, 64768, 64640, 64512, 
+    64384, 64256, 64128, 64000, 63872, 63744, 63616, 63488, 63360, 63232, 
+    63104, 62976, 62848, 62720, 62592, 62464, 62336, 62208, 62080, 61952, 
+    61824, 61696, 61568, 61440, 61312, 61184, 61056, 60928, 60800, 60672, 
+    60544, 60416, 60288, 60160, 60032, 59904, 59776, 59648, 59520, 59392, 
+    59264, 59136, 59008, 58880, 58752, 58624, 58496, 58368, 58240, 58112, 
+    57984, 57856, 57728, 57600, 57472, 57344, 57216, 57088, 56960, 56832, 
+    56704, 56576, 56448, 56320, 56192, 56064, 55936, 55808, 55680, 55552, 
+    55424, 55296, 55168, 55040, 54912, 54784, 54656, 54528, 54400, 54272, 
+    54144, 54016, 53888, 53760, 53632, 53504, 53376, 53248, 53120, 52992, 
+    52864, 52736, 52608, 52480, 52352, 52224, 52096, 51968, 51840, 51712, 
+    51584, 51456, 51328, 51200, 51072, 50944, 50816, 50688, 50560, 50432, 
+    50304, 50176, 50048, 49920, 49792, 49664, 49536, 49408, 49280, 49152, 
+    49024, 48896, 48768, 48640, 48512, 48384, 48256, 48128, 48000, 47872, 
+    47744, 47616, 47488, 47360, 47232, 47104, 46976, 46848, 46720, 46592, 
+    46464, 46336, 46208, 46080, 45952, 45824, 45696, 45568, 45440, 45312, 
+    45184, 45056, 44928, 44800, 44672, 44544, 44416, 44288, 44160, 44032, 
+    43904, 43776, 43648, 43520, 43392, 43264, 43136, 43008, 42880, 42752, 
+    42624, 42496, 42368, 42240, 42112, 41984, 41856, 41728, 41600, 41472, 
+    41344, 41216, 41088, 40960, 40832, 40704, 40576, 40448, 40320, 40192, 
+    40064, 39936, 39808, 39680, 39552, 39424, 39296, 39168, 39040, 38912, 
+    38784, 38656, 38528, 38400, 38272, 38144, 38016, 37888, 37760, 37632, 
+    37504, 37376, 37248, 37120, 36992, 36864, 36736, 36608, 36480, 36352, 
+    36224, 36096, 35968, 35840, 35712, 35584, 35456, 35328, 35200, 35072, 
+    34944, 34816, 34688, 34560, 34432, 34304, 34176, 34048, 33920, 33792, 
+    33664, 33536, 33408, 33280, 33152, 33024, 32896, 32768, 32640, 32512, 
+    32384, 32256, 32128, 32000, 31872, 31744, 31616, 31488, 31360, 31232, 
+    31104, 30976, 30848, 30720, 30592, 30464, 30336, 30208, 30080, 29952, 
+    29824, 29696, 29568, 29440, 29312, 29184, 29056, 28928, 28800, 28672, 
+    28544, 28416, 28288, 28160, 28032, 27904, 27776, 27648, 27520, 27392, 
+    27264, 27136, 27008, 26880, 26752, 26624, 26496, 26368, 26240, 26112, 
+    25984, 25856, 25728, 25600, 25472, 25344, 25216, 25088, 24960, 24832, 
+    24704, 24576, 24448, 24320, 24192, 24064, 23936, 23808, 23680, 23552, 
+    23424, 23296, 23168, 23040, 22912, 22784, 22656, 22528, 22400, 22272, 
+    22144, 22016, 21888, 21760, 21632, 21504, 21376, 21248, 21120, 20992, 
+    20864, 20736, 20608, 20480, 20352, 20224, 20096, 19968, 19840, 19712, 
+    19584, 19456, 19328, 19200, 19072, 18944, 18816, 18688, 18560, 18432, 
+    18304, 18176, 18048, 17920, 17792, 17664, 17536, 17408, 17280, 17152, 
+    17024, 16896, 16768, 16640, 16512, 16384, 16256, 16128, 16000, 15872, 
+    15744, 15616, 15488, 15360, 15232, 15104, 14976, 14848, 14720, 14592, 
+    14464, 14336, 14208, 14080, 13952, 13824, 13696, 13568, 13440, 13312, 
+    13184, 13056, 12928, 12800, 12672, 12544, 12416, 12288, 12160, 12032, 
+    11904, 11776, 11648, 11520, 11392, 11264, 11136, 11008, 10880, 10752, 
+    10624, 10496, 10368, 10240, 10112, 9984, 9856, 9728, 9600, 9472, 
+    9344, 9216, 9088, 8960, 8832, 8704, 8576, 8448, 8320, 8192, 
+    8064, 7936, 7808, 7680, 7552, 7424, 7296, 7168, 7040, 6912, 
+    6784, 6656, 6528, 6400, 6272, 6144, 6016, 5888, 5760, 5632, 
+    5504, 5376, 5248, 5120, 4992, 4864, 4736, 4608, 4480, 4352, 
+    4224, 4096, 3968, 3840, 3712, 3584, 3456, 3328, 3200, 3072, 
+    2944, 2816, 2688, 2560, 2432, 2304, 2176, 2048, 1920, 1792, 
+    1664, 1536, 1408, 1280, 1152, 1024, 896, 768, 640, 512, 
+    384, 256, 
+};
+
+static const int blocks_length[] = {
+    4096, 1024, 512, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 512, -1, -1, };
+static const jchar* blocks[] = {
+    blocks0, blocks1, blocks2, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
+    NULL, NULL, NULL, NULL, blocks14, NULL, NULL};
+
 /**
  * Information about each character.  The low order 5 bits form the
  * character type, the next bit is a flag for non-breaking spaces, and the
  * next bit is a flag for mirrored directionality.  The high order 9 bits
  * form the offset into the attribute tables.  Note that this limits the
- * number of unique character attributes to 512, which is not a problem
- * as of Unicode version 3.2.0, but may soon become one.
+ * number of unique character attributes per plane to 512, which is not a 
+ * problem as of Unicode version 4.0.0, but may soon become one.
  */
-static const jchar data[] = {
-    12289, 12418, 12289, 12418, 12289, 12418, 12289, 12418, 12289, 12418,
-    12289, 12418, 12289, 12418, 12289, 12418, 12289, 12418, 12289, 12418,
-    12289, 12418, 16000, 16000, 12289, 12418, 16000, 16000, 16000, 16000,
-    16000, 16000, 14981, 14981, 16000, 16000, 16000, 14981, 14981, 14981,
-    16000, 16000, 16000, 14981, 14981, 14981, 14981, 14981, 14981, 14981,
-    14981, 16000, 14981, 14981, 14981, 16000, 16000, 16000, 16000, 23432,
-    23432, 16000, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981,
-    16000, 14981, 14981, 14981, 16000, 14981, 14981, 14981, 14981, 14981,
-    14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981,
-    14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 16000, 16000,
-    16000, 16000, 20888, 16000, 16000, 16000, 16000, 17926, 16000, 16000,
-    14981, 14981, 14981, 14981, 14981, 14981, 16000, 16000, 16000, 16000,
-    14981, 14981, 16000, 16000, 14981, 14981, 14981, 14981, 14981, 14981,
-    14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981,
-    14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981,
-    16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000,
-    16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000,
-    16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 21509, 21509,
-    21509, 21509, 21509, 21509, 21509, 21509, 21509, 21509, 21509, 21509,
-    16000, 16000, 16000, 16000, 20994, 20994, 20994, 20994, 20994, 20994,
-    20994, 20994, 20994, 20994, 20994, 20994, 20994, 20994, 20994, 20994,
-    20994, 20994, 20994, 20994, 20994, 20994, 20994, 20994, 20994, 20994,
-    20994, 20994, 20994, 20994, 20994, 11906, 16000, 20888, 10772, 16000,
-    16000, 16000, 16000, 16000, 16000, 17926, 17926, 17926, 17926, 17926,
-    17926, 17926, 17926, 17926, 17926, 17926, 17926, 17926, 17926, 17926,
-    18054, 17926, 17926, 17926, 17926, 17926, 17926, 17926, 17926, 17926,
-    16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000,
-    16000, 16000, 16000, 16000, 16000, 16000, 16000, 6683, 6683, 16000,
-    16000, 16000, 16000, 17796, 16000, 16000, 16000, 664, 16000, 664,
-    26133, 26262, 664, 6807, 14981, 14981, 14981, 14981, 14981, 14981,
-    14981, 14981, 14981, 14981, 17796, 14981, 14981, 14981, 14981, 14981,
-    14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981,
-    14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981,
-    14981, 14981, 14981, 14981, 14981, 17796, 17796, 6683, 6683, 6683,
-    6683, 6683, 6683, 6683, 6683, 6683, 6683, 6683, 6683, 6683,
-    6683, 17796, 17796, 6683, 6683, 6683, 6683, 6683, 6683, 6683,
-    6683, 6683, 6683, 6683, 6683, 6683, 6683, 11906, 29314, 11906,
-    16000, 11906, 18690, 29825, 29825, 29825, 29825, 29571, 6683, 6683,
-    6683, 28034, 28034, 18690, 18690, 16000, 16000, 11906, 18690, 28161,
-    28161, 29953, 29953, 16000, 6683, 6683, 6683, 6914, 7042, 7170,
-    7298, 7426, 7554, 7682, 7810, 7938, 8066, 8194, 8322, 8450,
-    8578, 8706, 8834, 8962, 9090, 9218, 9346, 9474, 9602, 9730,
-    9858, 9986, 10114, 1109, 3225, 1238, 3225, 15, 15, 15,
-    15, 15, 271, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 143,
-    271, 143, 399, 271, 15, 15, 15, 15, 15, 15,
-    15, 15, 15, 15, 15, 15, 15, 15, 271, 271,
-    271, 143, 524, 664, 664, 792, 922, 792, 664, 664,
-    1109, 1238, 664, 1305, 1432, 1556, 1432, 1688, 1801, 1929,
-    2057, 2185, 2313, 2441, 2569, 2697, 2825, 2953, 1432, 664,
-    3161, 3225, 3161, 664, 3329, 3457, 3585, 3713, 3841, 3969,
-    4097, 4225, 4353, 4481, 4609, 4737, 4865, 4993, 5121, 5249,
-    5377, 5505, 5633, 5761, 5889, 6017, 6145, 6273, 6401, 6529,
-    1109, 664, 1238, 6683, 6807, 664, 664, 664, 3225, 1109,
-    1238, 16000, 664, 664, 664, 664, 664, 664, 16000, 16000,
-    16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000,
-    16000, 16000, 16000, 16000, 16000, 16000, 10284, 664, 922, 922,
-    922, 922, 10396, 10396, 6683, 10396, 10498, 10717, 3225, 10772,
-    10396, 6683, 10908, 1305, 11019, 11147, 6683, 11266, 10396, 664,
-    6683, 11403, 10498, 11614, 11659, 11659, 11659, 664, 664, 1305,
-    1556, 3225, 3225, 3225, 16000, 664, 922, 792, 664, 16000,
-    16000, 16000, 16000, 21509, 21509, 21509, 16000, 21509, 16000, 21509,
-    21509, 21509, 21509, 21509, 21509, 21509, 21509, 21509, 21509, 21509,
-    21509, 21509, 16000, 16000, 16000, 17926, 17926, 17926, 17926, 17926,
-    17926, 17926, 17926, 17926, 17926, 17926, 17926, 17926, 17926, 17926,
-    17926, 17926, 17926, 17926, 17926, 17926, 17926, 17926, 17926, 17926,
-    17926, 17926, 17926, 17926, 17926, 17926, 17926, 16000, 20508, 20508,
-    20353, 20353, 20353, 20353, 20353, 20353, 20353, 20353, 20353, 20353,
-    20353, 20353, 20353, 20353, 20353, 20353, 11777, 11777, 11777, 11777,
-    11777, 11777, 11777, 11777, 11777, 11777, 11777, 11777, 11777, 11777,
-    11777, 11777, 11777, 11777, 11777, 11777, 11777, 11777, 11777, 3225,
-    11777, 11777, 11777, 11777, 11777, 11777, 11777, 11906, 11906, 11906,
-    18690, 18690, 11906, 11906, 16000, 16000, 16000, 16000, 16000, 16000,
-    16000, 16000, 16000, 16000, 16000, 16000, 11906, 11906, 11906, 11906,
-    11906, 16000, 16000, 16000, 16000, 16000, 21253, 17926, 21253, 21253,
-    16000, 21253, 21253, 16000, 21253, 21253, 21253, 21253, 21253, 21253,
-    21253, 21253, 21253, 21253, 21509, 21509, 21509, 21509, 21509, 21509,
-    21509, 21509, 21509, 21509, 21509, 21509, 21509, 21509, 21509, 21509,
-    21509, 21509, 21509, 21509, 21400, 21509, 17926, 17926, 17926, 17926,
-    17926, 17926, 17926, 20615, 20615, 17926, 20615, 20615, 16000, 16000,
-    16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000,
-    16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000,
-    16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000,
-    11659, 11659, 11659, 11659, 11659, 11659, 11659, 11659, 11659, 11659,
-    11659, 11659, 33803, 12418, 12289, 12418, 12289, 12418, 12289, 12418,
-    12289, 12418, 11906, 12289, 12418, 12289, 12418, 12289, 12418, 12289,
-    12418, 12289, 12418, 12289, 12418, 12289, 12418, 12289, 12418, 12289,
-    12418, 12289, 12418, 12289, 12418, 12289, 12418, 12289, 12418, 12289,
-    12418, 12289, 12418, 12289, 12418, 16000, 16000, 16000, 16000, 16000,
-    16000, 23561, 23689, 23817, 23945, 24073, 24201, 24329, 24457, 24585,
-    24713, 17926, 17926, 14981, 14981, 14981, 16000, 16000, 16000, 16000,
-    16000, 16000, 16000, 16000, 16000, 16000, 16000, 6683, 6683, 18177,
-    664, 18305, 18305, 18305, 16000, 18433, 16000, 18561, 18561, 18690,
-    11777, 11777, 11777, 11777, 11777, 11777, 11777, 11777, 11777, 11777,
-    11777, 11777, 11777, 11777, 11777, 11777, 12034, 12034, 12034, 12034,
-    12034, 12034, 12034, 12034, 12034, 12034, 12034, 12034, 12034, 12034,
-    12034, 12034, 12034, 12034, 12034, 12034, 12034, 12034, 12034, 3225,
-    12034, 12034, 12034, 12034, 12034, 12034, 12034, 12162, 12034, 12034,
-    19074, 12034, 12034, 12034, 12034, 12034, 12034, 12034, 12034, 12034,
-    19202, 19330, 19330, 16000, 19458, 19586, 19713, 19713, 19713, 19842,
-    19970, 10498, 16000, 16000, 12289, 12418, 12289, 12418, 12289, 12418,
-    12289, 12418, 12289, 12418, 12289, 12418, 12289, 12418, 12289, 12418,
-    11906, 15233, 15363, 15490, 12289, 12418, 15745, 15873, 12289, 12418,
-    12289, 12418, 12289, 12418, 12289, 12418, 12289, 12418, 12289, 12418,
-    12289, 12418, 12289, 12418, 12545, 12674, 12289, 12418, 12289, 12418,
-    12289, 12418, 10498, 12289, 12418, 12289, 12418, 12289, 12418, 12289,
-    12418, 12289, 12418, 12289, 12418, 12289, 12418, 12289, 12418, 20098,
-    20226, 15618, 10498, 16000, 16000, 16000, 16000, 16000, 16000, 16000,
-    16000, 16000, 16000, 16000, 16000, 23312, 23312, 23312, 23312, 23312,
-    23312, 32523, 16000, 16000, 16000, 32651, 32779, 32907, 33035, 33163,
-    33291, 1305, 1305, 3225, 1109, 1238, 10498, 13057, 12289, 12418,
-    12289, 12418, 13185, 12289, 12418, 13313, 13313, 12289, 12418, 10498,
-    13441, 13569, 13697, 12289, 12418, 13313, 13825, 13954, 14081, 14209,
-    12289, 12418, 10498, 10498, 14081, 14337, 10498, 14465, 14981, 14981,
-    14981, 14981, 15233, 15363, 15490, 15233, 15363, 15490, 15233, 15363,
-    15490, 12289, 12418, 12289, 12418, 12289, 12418, 12289, 12418, 12289,
-    12418, 12289, 12418, 12289, 12418, 12289, 12418, 15618, 12289, 12418,
-    20508, 17926, 17926, 17926, 17926, 16000, 20615, 20615, 16000, 16000,
-    12289, 12418, 12289, 12418, 12289, 12418, 12289, 12418, 12289, 12418,
-    12289, 12418, 12289, 12418, 12289, 12418, 12289, 12418, 12289, 12418,
-    12289, 12418, 12289, 12418, 12801, 12289, 12418, 12289, 12418, 12289,
-    12418, 12930, 12289, 12418, 12289, 12418, 12289, 12418, 14593, 12289,
-    12418, 14593, 10498, 10498, 12289, 12418, 14593, 12289, 12418, 14721,
-    14721, 12289, 12418, 12289, 12418, 14849, 12289, 12418, 10498, 14981,
-    12289, 12418, 10498, 15106, 19713, 12289, 12418, 12289, 12418, 16000,
-    16000, 12289, 12418, 16000, 16000, 12289, 12418, 16000, 16000, 16000,
-    12289, 12418, 12289, 12418, 12289, 12418, 12289, 12418, 12289, 12418,
-    12289, 12418, 12289, 12418, 12289, 12418, 12289, 12418, 16000, 16000,
-    16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000,
-    1432, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000,
-    16000, 16000, 16000, 16000, 16000, 21400, 16000, 16000, 16000, 21400,
-    21400, 21400, 21400, 21400, 21400, 21400, 21400, 21400, 21400, 21400,
-    21400, 21400, 21400, 16000, 23312, 21509, 17926, 21509, 21509, 21509,
-    21509, 21509, 21509, 21509, 21509, 21509, 21509, 21509, 21509, 21509,
-    21509, 21509, 21509, 21509, 21509, 21509, 21509, 21509, 21509, 21509,
-    21509, 21509, 21509, 21509, 21509, 21509, 16000, 16000, 23312, 19713,
-    19713, 19713, 19713, 19713, 19713, 19713, 19713, 19713, 19713, 19713,
-    19713, 19713, 19713, 19713, 19713, 19713, 19713, 19713, 19713, 19713,
-    19713, 19713, 19713, 19713, 19713, 19713, 19713, 19713, 19713, 19713,
-    19713, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000,
-    16000, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981,
-    14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 16000,
-    14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 16000,
-    14981, 16000, 16000, 16000, 16000, 16000, 23561, 23689, 23817, 23945,
-    24073, 24201, 24329, 24457, 24585, 24713, 16000, 16000, 16000, 16000,
-    16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000,
-    16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 10498, 10498,
-    10498, 16130, 16258, 10498, 16386, 16386, 10498, 16514, 10498, 16642,
-    10498, 10498, 10498, 10498, 16386, 10498, 10498, 16770, 10498, 10498,
-    10498, 10498, 16898, 17026, 10498, 10498, 10498, 10498, 10498, 17026,
-    10498, 10498, 17154, 10498, 10498, 17282, 10498, 10498, 10498, 10498,
-    10498, 10498, 10498, 10498, 10498, 10498, 17410, 10498, 10498, 17410,
-    10498, 10498, 10498, 10498, 17410, 10498, 17538, 17538, 10498, 10498,
-    10498, 10498, 10498, 10498, 17666, 10498, 10498, 10498, 10498, 10498,
-    10498, 10498, 10498, 10498, 10498, 10498, 10498, 10498, 10498, 16000,
-    16000, 17796, 17796, 17796, 17796, 17796, 17796, 17796, 17796, 17796,
-    6683, 6683, 17796, 17796, 17796, 17796, 17796, 6683, 6683, 6683,
-    6683, 6683, 6683, 6683, 6683, 6683, 17796, 16000, 16000, 16000,
-    16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000,
-    16000, 16000, 16000, 16000, 20737, 20737, 20737, 20737, 20737, 20737,
-    20737, 20737, 20737, 20737, 20737, 20737, 20737, 20737, 20737, 20737,
-    20737, 20737, 20737, 20737, 20737, 20737, 20737, 16000, 16000, 17796,
-    20888, 20888, 20888, 20888, 20888, 20888, 11777, 11777, 16000, 11777,
-    11777, 11777, 11777, 11777, 11777, 11777, 11777, 11777, 18818, 18946,
-    18946, 18946, 18690, 12034, 12034, 12034, 12034, 12034, 12034, 12034,
-    12034, 12034, 12034, 12034, 12034, 12034, 12034, 12034, 12034, 20226,
-    20226, 20226, 20226, 20226, 20226, 20226, 20226, 20226, 20226, 20226,
-    20226, 20226, 20226, 20226, 20226, 17926, 17926, 17926, 17926, 17926,
-    20888, 17926, 17926, 14981, 14981, 14981, 14981, 16000, 16000, 16000,
-    16000, 17926, 17926, 17926, 17926, 17926, 17926, 17926, 17926, 16000,
-    17926, 17926, 17926, 17926, 17926, 17926, 17926, 17926, 17926, 17926,
-    17926, 17926, 17926, 17926, 17926, 17926, 17926, 17926, 17926, 17926,
-    17926, 17926, 17926, 16000, 17926, 17926, 17926, 21144, 17926, 17926,
-    21144, 17926, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000,
-    16000, 16000, 16000, 21253, 21253, 21253, 21253, 21253, 21253, 21253,
-    21253, 21253, 21253, 21253, 21253, 21253, 21253, 21253, 21253, 16000,
-    16000, 16000, 16000, 16000, 21253, 21253, 21253, 21144, 21144, 16000,
-    16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000,
-    23689, 23817, 23945, 24073, 24201, 24329, 24457, 24585, 24713, 25611,
-    25739, 25867, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000,
-    16000, 16000, 16000, 16000, 16000, 17926, 23432, 16000, 14981, 14981,
-    14981, 14981, 14981, 14981, 16000, 16000, 16000, 14981, 14981, 14981,
-    16000, 14981, 14981, 14981, 14981, 16000, 16000, 16000, 14981, 14981,
-    16000, 14981, 16000, 14981, 14981, 14981, 14981, 16000, 16000, 14981,
-    14981, 14981, 14981, 14981, 14981, 14981, 16000, 14981, 14981, 14981,
-    14981, 14981, 14981, 14981, 16000, 14981, 14981, 14981, 14981, 14981,
-    14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981,
-    14981, 14981, 14981, 14981, 16000, 16000, 16000, 16000, 16000, 16000,
-    17926, 17926, 17926, 17926, 17926, 17926, 17926, 17926, 17926, 17926,
-    17926, 17926, 17926, 17926, 23432, 23432, 23432, 23432, 16000, 17926,
-    17926, 17926, 16000, 17926, 17926, 17926, 17926, 16000, 16000, 16000,
-    16000, 16000, 16000, 16000, 17926, 17926, 16000, 16000, 16000, 16000,
-    16000, 16000, 16000, 16000, 16000, 17926, 23432, 23432, 16000, 14981,
-    14981, 14981, 14981, 14981, 14981, 14981, 14981, 16000, 16000, 14981,
-    14981, 16000, 16000, 14981, 14981, 14981, 14981, 14981, 14981, 14981,
-    14981, 14981, 14981, 14981, 14981, 14981, 16000, 16000, 16000, 16000,
-    14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981,
-    14981, 14981, 14981, 14981, 14981, 16000, 14981, 14981, 14981, 14981,
-    14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981,
-    14981, 14981, 16000, 16000, 16000, 16000, 23432, 23432, 16000, 14981,
-    14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981,
-    14981, 14981, 14981, 14981, 14981, 14981, 14981, 16000, 16000, 16000,
-    14981, 14981, 14981, 14981, 14981, 14981, 16000, 16000, 14981, 14981,
-    14981, 14981, 14981, 14981, 16000, 16000, 14981, 14981, 14981, 14981,
-    14981, 14981, 16000, 16000, 14981, 14981, 14981, 16000, 16000, 16000,
-    16000, 23561, 23689, 23817, 23945, 24073, 24201, 24329, 24457, 24585,
-    24713, 20508, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000,
-    16000, 16000, 16000, 16000, 16000, 16000, 16000, 21769, 21897, 22025,
-    22153, 22281, 22409, 22537, 22665, 22793, 22921, 792, 23064, 23064,
-    21400, 16000, 16000, 17926, 21509, 21509, 21509, 21509, 21509, 21509,
-    21509, 21509, 21509, 21509, 21509, 21509, 21509, 21509, 21509, 21509,
-    16000, 16000, 21509, 21509, 21509, 21509, 21509, 21509, 21509, 21509,
-    21509, 21509, 21509, 21509, 21509, 21509, 21509, 21509, 21509, 21509,
-    21509, 21509, 21509, 21509, 21509, 21509, 21509, 21509, 16000, 16000,
-    16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000,
-    16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000,
-    16000, 16000, 21509, 21509, 21509, 21509, 21509, 21509, 21509, 21509,
-    21509, 21509, 21509, 21509, 21509, 21509, 21509, 21509, 21509, 21509,
-    21509, 21509, 21509, 21509, 21509, 21509, 21509, 21509, 21509, 21509,
-    21509, 21509, 21509, 21509, 26133, 26262, 21636, 21509, 21509, 21509,
-    21509, 21509, 21509, 21509, 21509, 21509, 21509, 17926, 17926, 17926,
-    17926, 17926, 17926, 17926, 17926, 17926, 17926, 17926, 16000, 16000,
-    16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000,
-    16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 23432,
-    23432, 20888, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000,
-    16000, 16000, 16000, 17926, 17926, 23432, 16000, 14981, 14981, 14981,
-    14981, 14981, 14981, 14981, 16000, 14981, 16000, 14981, 14981, 14981,
-    16000, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981,
-    14981, 14981, 14981, 14981, 20888, 20888, 14981, 14981, 14981, 14981,
-    14981, 14981, 14981, 14981, 16000, 16000, 16000, 16000, 16000, 16000,
-    16000, 16000, 16000, 17926, 17926, 17926, 17926, 17926, 21636, 21636,
-    17926, 17926, 10396, 17926, 17926, 17926, 17926, 16000, 16000, 1801,
-    1929, 2057, 2185, 2313, 2441, 2569, 2697, 2825, 2953, 21509,
-    21509, 21509, 23196, 23196, 16000, 14981, 14981, 14981, 16000, 14981,
-    16000, 14981, 16000, 16000, 14981, 14981, 16000, 14981, 14981, 14981,
-    14981, 17926, 14981, 14981, 17926, 17926, 17926, 17926, 17926, 17926,
-    16000, 17926, 17926, 14981, 16000, 16000, 14981, 14981, 14981, 14981,
-    14981, 14981, 14981, 14981, 14981, 16000, 14981, 14981, 14981, 14981,
-    14981, 14981, 14981, 14981, 14981, 14981, 16000, 14981, 14981, 14981,
-    14981, 14981, 16000, 16000, 16000, 16000, 17926, 17926, 23432, 16000,
-    14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981,
-    14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981,
-    14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981,
-    14981, 14981, 16000, 16000, 17926, 14981, 23432, 23432, 23432, 23432,
-    23432, 16000, 17926, 23432, 23432, 16000, 23432, 23432, 17926, 17926,
-    16000, 16000, 16000, 16000, 16000, 16000, 16000, 23432, 23432, 16000,
-    16000, 16000, 16000, 16000, 16000, 16000, 14981, 16000, 20888, 20888,
-    20888, 20888, 20888, 20888, 20888, 20888, 23689, 23817, 23945, 24073,
-    24201, 24329, 24457, 24585, 24713, 25611, 26379, 26507, 26635, 26763,
-    26891, 27019, 27147, 27275, 25739, 27403, 16000, 16000, 16000, 14981,
-    14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 16000, 14981,
-    14981, 14981, 14981, 14981, 14981, 14981, 16000, 14981, 14981, 16000,
-    16000, 14981, 14981, 14981, 14981, 16000, 16000, 17926, 14981, 23432,
-    17926, 17926, 17926, 17926, 17926, 17926, 17926, 17926, 23432, 23432,
-    23432, 23432, 17926, 16000, 16000, 14981, 17926, 17926, 17926, 17926,
-    16000, 16000, 16000, 14981, 14981, 14981, 14981, 14981, 14981, 14981,
-    14981, 14981, 16000, 14981, 14981, 14981, 14981, 14981, 14981, 14981,
-    16000, 14981, 16000, 16000, 16000, 14981, 14981, 14981, 14981, 16000,
-    16000, 17926, 16000, 23432, 23432, 23432, 16000, 14981, 14981, 14981,
-    14981, 14981, 14981, 14981, 14981, 16000, 14981, 14981, 14981, 16000,
-    14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981,
-    14981, 14981, 14981, 14981, 14981, 16000, 14981, 16000, 14981, 14981,
-    14981, 14981, 16000, 16000, 14981, 14981, 14981, 14981, 14981, 14981,
-    14981, 16000, 14981, 16000, 14981, 14981, 14981, 14981, 16000, 16000,
-    14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981,
-    14981, 14981, 14981, 14981, 14981, 14981, 14981, 17926, 14981, 14981,
-    17926, 17926, 17926, 17926, 17926, 17926, 17926, 16000, 16000, 16000,
-    16000, 922, 922, 922, 922, 922, 922, 922, 922, 922,
-    922, 922, 922, 922, 922, 922, 922, 16000, 16000, 16000,
-    16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000,
-    16000, 16000, 16000, 14981, 14981, 17926, 17926, 20888, 20888, 23561,
-    23689, 23817, 23945, 24073, 24201, 24329, 24457, 24585, 24713, 20888,
-    16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000,
-    16000, 16000, 16000, 16000, 16000, 664, 664, 792, 922, 792,
-    664, 664, 26133, 26262, 664, 1305, 1432, 1556, 1432, 1688,
-    1801, 1929, 2057, 2185, 2313, 2441, 2569, 2697, 2825, 2953,
-    1432, 664, 3225, 3225, 3225, 664, 664, 664, 664, 664,
-    664, 10772, 664, 664, 664, 664, 23312, 23312, 23312, 23312,
-    16000, 23561, 23689, 23817, 23945, 24073, 24201, 24329, 24457, 24585,
-    24713, 16000, 16000, 16000, 16000, 16000, 16000, 14981, 14981, 14981,
-    14981, 14981, 14981, 14981, 14981, 14981, 16000, 14981, 14981, 14981,
-    14981, 14981, 14981, 14981, 14981, 14981, 14981, 16000, 14981, 14981,
-    14981, 14981, 14981, 16000, 16000, 16000, 16000, 23432, 17926, 17926,
-    17926, 17926, 16000, 16000, 23432, 23432, 16000, 16000, 23432, 23432,
-    17926, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000,
-    23432, 16000, 16000, 16000, 16000, 14981, 14981, 16000, 14981, 16000,
-    16000, 14981, 14981, 16000, 14981, 16000, 16000, 14981, 16000, 16000,
-    16000, 16000, 16000, 16000, 14981, 14981, 14981, 14981, 16000, 14981,
-    14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 16000, 14981,
-    14981, 14981, 14981, 14981, 14981, 14981, 16000, 14981, 14981, 16000,
-    14981, 14981, 16000, 14981, 14981, 16000, 16000, 17926, 16000, 23432,
-    23432, 17926, 17926, 16000, 16000, 16000, 16000, 17926, 17926, 16000,
-    16000, 17926, 17926, 17926, 16000, 16000, 16000, 16000, 16000, 16000,
-    16000, 16000, 16000, 16000, 16000, 14981, 14981, 14981, 14981, 16000,
-    14981, 16000, 14981, 14981, 17926, 17926, 16000, 16000, 23561, 23689,
-    23817, 23945, 24073, 24201, 24329, 24457, 24585, 24713, 14981, 14981,
-    922, 922, 24843, 24971, 25099, 25227, 25355, 25483, 20508, 16000,
-    16000, 16000, 16000, 16000, 14981, 14981, 14981, 14981, 14981, 14981,
-    14981, 14981, 14981, 16000, 14981, 14981, 14981, 14981, 14981, 14981,
-    14981, 16000, 14981, 14981, 16000, 14981, 14981, 14981, 14981, 14981,
-    16000, 16000, 17926, 14981, 23432, 23432, 17926, 17926, 17926, 17926,
-    17926, 16000, 17926, 17926, 23432, 16000, 23432, 23432, 17926, 16000,
-    16000, 14981, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000,
-    16000, 16000, 16000, 16000, 16000, 16000, 16000, 23561, 23689, 23817,
-    23945, 24073, 24201, 24329, 24457, 24585, 24713, 25355, 25355, 25355,
-    25355, 25355, 25355, 25355, 25355, 25355, 25355, 20508, 17926, 20508,
-    17926, 20508, 17926, 26133, 26262, 26133, 26262, 23432, 23432, 17926,
-    17926, 17926, 16000, 16000, 16000, 23432, 23432, 16000, 16000, 23432,
-    23432, 17926, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000,
-    17926, 23432, 16000, 16000, 16000, 16000, 14981, 14981, 16000, 14981,
-    14981, 14981, 14981, 14981, 16000, 14981, 14981, 16000, 23432, 17926,
-    17926, 17926, 17926, 23432, 17926, 16000, 16000, 16000, 17926, 17926,
-    23432, 17926, 16000, 16000, 16000, 16000, 16000, 16000, 14981, 14981,
-    14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981,
-    14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 23432, 23432,
-    23432, 17926, 17926, 17926, 17926, 17926, 17926, 17926, 23432, 23432,
-    16000, 16000, 16000, 23432, 23432, 23432, 16000, 23432, 23432, 23432,
-    17926, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000,
-    23432, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 14981,
-    14981, 14981, 14981, 14981, 16000, 17796, 16000, 17926, 17926, 17926,
-    17926, 17926, 17926, 16000, 16000, 23561, 23689, 23817, 23945, 24073,
-    24201, 24329, 24457, 24585, 24713, 16000, 16000, 14981, 14981, 16000,
-    16000, 16000, 16000, 23561, 23689, 23817, 23945, 24073, 24201, 24329,
-    24457, 24585, 24713, 16000, 16000, 16000, 16000, 16000, 16000, 16000,
-    16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 17926,
-    17926, 17926, 17926, 17926, 17926, 17926, 17926, 17926, 17926, 17926,
-    17926, 17926, 20615, 20615, 20615, 23432, 17926, 17926, 17926, 16000,
-    16000, 23432, 23432, 23432, 16000, 23432, 23432, 23432, 17926, 16000,
-    16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 23432, 16000,
-    16000, 16000, 16000, 16000, 16000, 16000, 16000, 14981, 14981, 14981,
-    14981, 14981, 14981, 14981, 16000, 16000, 16000, 17926, 16000, 16000,
-    16000, 16000, 23432, 23432, 23432, 17926, 17926, 17926, 16000, 17926,
-    16000, 23432, 23432, 23432, 23432, 23432, 23432, 23432, 23432, 17926,
-    23432, 23432, 17926, 17926, 17926, 17926, 17926, 17926, 17926, 17926,
-    17926, 17926, 17926, 20888, 20888, 20888, 20888, 20888, 20888, 20888,
-    922, 20888, 16000, 16000, 16000, 14981, 14981, 14981, 14981, 14981,
-    14981, 17796, 17926, 17926, 17926, 17926, 17926, 17926, 17926, 17926,
-    20888, 23561, 23689, 23817, 23945, 24073, 24201, 24329, 24457, 24585,
-    24713, 20888, 20888, 16000, 16000, 16000, 16000, 14981, 20508, 20508,
-    20508, 20888, 20888, 20888, 20888, 20888, 20888, 20888, 20888, 26040,
-    20888, 20888, 20888, 20888, 20888, 20888, 20508, 20508, 20508, 20508,
-    20508, 17926, 17926, 20508, 20508, 20508, 20508, 20508, 20508, 17926,
-    20508, 20508, 20508, 20508, 20508, 20508, 16000, 16000, 20508, 16000,
-    16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000,
-    16000, 16000, 16000, 16000, 16000, 10396, 10396, 10396, 10396, 10396,
-    10396, 10396, 10396, 10396, 10396, 10396, 10396, 16000, 16000, 16000,
-    16000, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 16000,
-    14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981,
-    14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981,
-    14981, 14981, 14981, 14981, 14981, 14981, 16000, 16000, 16000, 16000,
-    16000, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981,
-    14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981,
-    14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 6807, 17796,
-    17796, 17796, 16000, 23561, 23689, 23817, 23945, 24073, 24201, 24329,
-    24457, 24585, 24713, 20888, 20888, 20888, 20888, 20888, 20888, 14981,
-    14981, 14981, 14981, 14981, 14981, 23432, 23432, 17926, 17926, 16000,
-    16000, 16000, 16000, 16000, 16000, 524, 14981, 14981, 14981, 14981,
-    14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981,
-    14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981,
-    14981, 14981, 26133, 26262, 16000, 16000, 16000, 14981, 14981, 14981,
-    14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 20888, 20888,
-    20888, 27531, 27659, 27787, 16000, 16000, 16000, 16000, 16000, 16000,
-    16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 14981,
-    14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 17926, 16000,
-    16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000,
-    16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000,
-    16000, 12289, 12418, 12289, 12418, 12289, 12418, 12289, 12418, 12289,
-    12418, 12289, 12418, 12289, 12418, 12289, 12418, 12289, 12418, 12289,
-    12418, 12289, 12418, 11906, 11906, 11906, 11906, 11906, 27906, 16000,
-    16000, 16000, 16000, 28034, 28034, 28034, 28034, 28034, 28034, 28034,
-    28034, 28161, 28161, 28161, 28161, 28161, 28161, 28161, 28161, 28034,
-    28034, 28034, 28034, 28034, 28034, 28034, 28034, 28161, 28161, 28161,
-    28161, 28161, 28161, 28161, 28161, 28034, 28034, 28034, 28034, 28034,
-    28034, 16000, 16000, 28161, 28161, 28161, 28161, 28161, 28161, 16000,
-    16000, 11906, 28034, 18690, 28034, 18690, 28034, 18690, 28034, 16000,
-    28161, 16000, 28161, 16000, 28161, 16000, 28161, 28034, 28034, 28034,
-    28034, 28034, 28034, 28034, 28034, 28161, 28161, 28161, 28161, 28161,
-    28161, 28161, 28161, 28290, 28290, 28418, 28418, 28418, 28418, 28546,
-    28546, 28674, 28674, 28802, 28802, 28930, 28930, 16000, 16000, 29058,
-    29058, 29058, 29058, 29058, 29058, 29058, 29058, 29187, 29187, 29187,
-    29187, 29187, 29187, 29187, 29187, 29058, 29058, 29058, 29058, 29058,
-    29058, 29058, 29058, 29187, 29187, 29187, 29187, 29187, 29187, 29187,
-    29187, 28034, 28034, 11906, 29314, 11906, 16000, 11906, 18690, 28161,
-    28161, 29441, 29441, 29571, 6683, 29698, 6683, 6914, 7042, 7170,
-    7298, 7426, 7554, 7682, 7810, 7938, 8066, 8194, 8322, 8450,
-    8578, 8706, 8834, 8962, 9090, 9218, 9346, 9474, 9602, 9730,
-    9858, 9986, 10114, 26133, 3225, 26262, 3225, 16000, 28034, 28034,
-    18690, 18690, 11906, 30082, 11906, 18690, 28161, 28161, 30209, 30209,
-    30337, 6683, 6683, 6683, 16000, 16000, 11906, 29314, 11906, 16000,
-    11906, 18690, 30465, 30465, 30593, 30593, 29571, 6683, 6683, 16000,
-    524, 524, 524, 524, 524, 524, 524, 30764, 524, 524,
-    524, 30860, 23312, 23312, 30992, 31120, 10772, 31284, 10772, 10772,
-    10772, 10772, 664, 664, 31389, 31518, 26133, 31389, 31389, 31518,
-    26133, 31389, 664, 664, 664, 664, 664, 664, 664, 664,
-    31629, 31758, 31888, 32016, 32144, 32272, 32400, 30764, 792, 792,
-    792, 792, 792, 664, 664, 664, 664, 10717, 11614, 664,
-    664, 664, 664, 6807, 32523, 11403, 11019, 11147, 32651, 32779,
-    32907, 33035, 33163, 33291, 1305, 1305, 3225, 1109, 1238, 16000,
-    16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000,
-    16000, 16000, 16000, 16000, 16000, 16000, 14981, 14981, 14981, 14981,
-    14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 16000,
-    16000, 16000, 10396, 10396, 10396, 10396, 10396, 10396, 10396, 10396,
-    10396, 10396, 10396, 10396, 10396, 10396, 10396, 10396, 10396, 10396,
-    10396, 10396, 16000, 16000, 16000, 16000, 16000, 10396, 10396, 10396,
-    10396, 10396, 10396, 10396, 19713, 10396, 10396, 10396, 10396, 19713,
-    10396, 10396, 10498, 19713, 19713, 19713, 10498, 10498, 19713, 19713,
-    19713, 10498, 10396, 19713, 10396, 10396, 10396, 19713, 19713, 19713,
-    19713, 19713, 10396, 10396, 41482, 41610, 41738, 41866, 41994, 42122,
-    42250, 42378, 42506, 17926, 17926, 17926, 17926, 17926, 17926, 10772,
-    17796, 17796, 17796, 17796, 17796, 10396, 10396, 42634, 42762, 42890,
-    16000, 16000, 16000, 10396, 10396, 10396, 10396, 16000, 10396, 10396,
-    10396, 10396, 16000, 16000, 10396, 10396, 10396, 10396, 10396, 10396,
-    10396, 10396, 10396, 10396, 10396, 10396, 10396, 10396, 10396, 10396,
-    10396, 10396, 10396, 10396, 10396, 10396, 10396, 3225, 10396, 10396,
-    10396, 10396, 10396, 10396, 10396, 10396, 10396, 10396, 10396, 10396,
-    10396, 10396, 3225, 3225, 10396, 10396, 3225, 10396, 3225, 10396,
-    10396, 10396, 10396, 10396, 10396, 10396, 10396, 10396, 10396, 10396,
-    10396, 10396, 10396, 10396, 3225, 10396, 10396, 16000, 16000, 16000,
-    16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000,
-    16000, 38026, 38154, 38282, 38410, 16000, 16000, 16000, 16000, 16000,
-    16000, 16000, 16000, 16000, 16000, 16000, 16000, 3225, 3225, 3225,
-    3225, 3225, 10396, 10396, 10396, 10396, 10396, 3225, 3225, 10396,
-    10396, 10396, 10396, 19713, 10396, 33409, 10396, 19713, 10396, 33537,
-    33665, 19713, 19713, 10908, 10498, 19713, 19713, 10396, 19713, 10498,
-    14981, 14981, 14981, 14981, 10498, 10396, 16000, 16000, 16000, 16000,
-    16000, 33930, 34058, 34186, 34314, 34442, 34570, 34698, 34826, 34954,
-    35082, 35210, 35338, 35466, 35594, 35722, 35850, 35978, 36106, 36234,
-    36362, 36490, 36618, 36746, 36874, 37002, 37130, 37258, 37386, 37514,
-    37642, 37770, 37898, 3225, 3225, 3161, 3161, 3225, 3225, 3161,
-    3161, 3161, 3161, 3161, 3161, 3161, 3161, 3161, 3161, 3161,
-    3161, 3161, 3161, 3161, 3161, 3161, 3161, 3161, 3225, 3225,
-    3225, 3225, 3225, 3161, 3161, 3161, 3161, 3225, 3225, 3225,
-    3225, 3225, 3225, 3225, 3225, 3225, 3161, 3161, 3161, 3161,
-    3161, 3225, 3225, 3161, 3161, 3225, 3225, 3225, 3225, 3161,
-    3161, 3161, 3161, 3161, 3161, 3161, 3161, 3161, 3161, 3161,
-    3161, 3161, 3225, 3225, 3161, 3161, 3161, 3161, 3225, 3225,
-    3225, 3225, 3225, 3161, 3225, 3225, 3225, 3225, 3225, 3225,
-    3225, 10396, 10396, 3225, 10396, 10396, 3225, 10396, 10396, 10396,
-    10396, 10396, 10396, 10396, 3225, 10396, 10396, 10396, 10396, 10396,
-    10396, 10396, 10396, 10396, 10396, 10396, 10396, 10396, 10396, 10396,
-    10396, 10396, 10396, 10396, 10396, 10396, 10396, 10396, 10396, 10396,
-    10396, 10396, 10396, 10396, 10396, 10396, 10396, 16000, 10396, 10396,
-    10396, 10396, 10396, 10396, 10396, 10396, 10396, 10396, 10396, 10396,
-    10396, 10396, 10396, 10396, 10396, 10396, 10396, 10396, 10396, 10396,
-    10396, 10396, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000,
-    16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000,
-    16000, 16000, 16000, 16000, 16000, 16000, 16000, 3225, 3161, 3161,
-    3161, 3161, 3225, 3225, 3225, 3161, 3161, 3161, 3161, 3161,
-    3161, 3225, 3225, 3225, 3161, 1305, 1305, 3225, 3161, 3161,
-    3225, 3225, 3225, 3161, 3161, 3161, 3161, 3225, 3161, 3225,
-    3161, 3225, 3225, 3225, 3225, 3161, 3161, 3161, 3161, 3161,
-    3161, 3161, 3161, 3161, 3225, 3225, 3225, 3225, 3225, 3161,
-    3225, 3161, 3161, 3161, 3161, 3161, 10396, 10396, 10396, 10396,
-    10396, 10396, 10396, 1109, 1238, 10396, 10396, 10396, 10396, 10396,
-    10396, 10396, 10396, 10396, 10396, 10396, 20508, 20508, 20508, 20508,
-    20508, 20508, 20508, 20508, 20508, 20508, 20508, 20508, 20508, 20508,
-    20508, 20508, 20508, 20508, 20508, 20508, 20508, 20508, 20508, 16000,
-    16000, 16000, 16000, 20508, 20508, 20508, 20508, 20508, 20508, 20508,
-    20508, 20508, 20508, 20508, 20508, 20508, 20508, 20508, 20508, 20508,
-    20508, 20508, 20508, 20508, 20508, 39964, 39964, 39964, 39964, 39964,
-    39964, 39964, 39964, 39964, 39964, 39964, 39964, 39964, 39964, 39964,
-    39964, 40092, 40092, 40092, 40092, 40092, 40092, 40092, 40092, 40092,
-    40092, 40092, 40092, 40092, 40092, 40092, 40092, 32523, 16000, 16000,
-    16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000,
-    16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 3161,
-    3225, 3161, 3225, 3161, 3161, 3161, 3161, 3161, 3161, 3161,
-    3161, 3225, 3225, 3161, 3161, 3161, 3161, 3161, 3161, 3161,
-    3161, 3161, 3161, 3161, 3161, 3161, 3161, 3161, 3161, 3161,
-    3161, 3225, 3225, 3161, 3161, 16000, 16000, 16000, 16000, 16000,
-    16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 922,
-    922, 3225, 6683, 10396, 922, 922, 16000, 10396, 3225, 3225,
-    3225, 3225, 10396, 10396, 16000, 16000, 16000, 16000, 16000, 16000,
-    16000, 16000, 16000, 16000, 23312, 23312, 23312, 10396, 10396, 16000,
-    16000, 10396, 10396, 10396, 10396, 10396, 10396, 10396, 10396, 10396,
-    10396, 10396, 10396, 10396, 10396, 10396, 10396, 16000, 10396, 10396,
-    10396, 10396, 10396, 10396, 10396, 10396, 10396, 10396, 10396, 10396,
-    10396, 10396, 16000, 10396, 16000, 10396, 10396, 10396, 10396, 16000,
-    16000, 16000, 10396, 16000, 10396, 10396, 10396, 10396, 10396, 10396,
-    10396, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000,
-    16000, 16000, 16000, 16000, 16000, 33803, 40203, 40331, 40459, 40587,
-    40715, 40843, 40971, 41099, 41227, 33803, 40203, 40331, 40459, 40587,
-    40715, 40843, 40971, 41099, 41227, 10396, 16000, 16000, 16000, 10396,
-    10396, 10396, 10396, 10396, 10396, 10396, 10396, 3161, 3161, 3161,
-    3161, 10396, 10396, 10396, 10396, 10396, 10396, 10396, 10396, 10396,
-    10396, 10396, 10396, 10396, 10396, 10396, 10396, 10396, 10396, 10396,
-    10396, 10396, 20508, 10396, 10396, 10396, 10396, 10396, 16000, 16000,
-    16000, 16000, 16000, 25355, 25355, 25355, 25355, 25355, 25355, 25355,
-    25355, 25355, 25355, 20508, 20508, 20508, 20508, 20508, 20508, 20508,
-    20508, 20508, 20508, 20508, 20508, 20508, 20508, 20508, 20508, 20508,
-    20508, 20508, 20508, 20508, 20508, 20508, 20508, 20508, 20508, 20508,
-    20508, 20508, 20508, 20508, 20508, 16000, 16000, 16000, 20508, 24843,
-    24971, 25099, 25227, 43019, 43147, 43275, 43403, 43531, 25611, 20508,
-    20508, 20508, 20508, 20508, 20508, 20508, 20508, 20508, 20508, 20508,
-    20508, 20508, 20508, 20508, 20508, 20508, 20508, 20508, 20508, 20508,
-    20508, 20508, 20508, 20508, 20508, 20508, 10396, 16000, 10396, 10396,
-    10396, 16000, 10396, 16000, 16000, 16000, 16000, 16000, 16000, 16000,
-    16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000,
-    16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 11403, 11019,
-    11147, 32651, 32779, 32907, 33035, 33163, 33291, 38539, 38667, 38795,
-    38923, 39051, 39179, 39307, 39435, 39563, 39691, 39819, 11403, 11019,
-    11147, 32651, 32779, 32907, 33035, 33163, 33291, 38539, 38667, 38795,
-    38923, 39051, 39179, 39307, 39435, 39563, 39691, 39819, 20508, 20508,
-    20508, 20508, 524, 664, 664, 664, 10396, 17796, 14981, 41354,
-    1109, 1238, 1109, 1238, 1109, 1238, 1109, 1238, 1109, 1238,
-    10396, 10396, 1109, 1238, 1109, 1238, 1109, 1238, 1109, 1238,
-    10772, 26133, 26262, 26262, 14981, 14981, 14981, 14981, 14981, 14981,
-    14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981,
-    14981, 14981, 14981, 14981, 14981, 16000, 16000, 16000, 16000, 17926,
-    17926, 6683, 6683, 17796, 17796, 16000, 14981, 14981, 14981, 14981,
-    14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981, 14981,
-    14981, 16000, 20508, 20508, 25355, 25355, 25355, 25355, 20508, 20508,
-    20508, 20508, 20508, 20508, 20508, 20508, 20508, 20508, 20508, 20508,
-    20508, 20508, 20508, 20508, 20508, 16000, 16000, 16000, 16000, 16000,
-    16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000,
-    16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000,
-    16000, 16000, 16000, 43667, 43667, 43667, 43667, 43667, 43667, 43667,
-    43667, 43667, 43667, 43667, 43667, 43667, 43667, 43667, 43667, 43667,
-    43667, 43667, 43667, 43667, 43667, 43667, 43667, 43667, 43667, 43667,
-    43667, 43667, 43667, 43667, 43667, 43794, 43794, 43794, 43794, 43794,
-    43794, 43794, 43794, 43794, 43794, 43794, 43794, 43794, 43794, 43794,
-    43794, 43794, 43794, 43794, 43794, 43794, 43794, 43794, 43794, 43794,
-    43794, 43794, 43794, 43794, 43794, 43794, 43794, 21253, 21253, 21253,
-    21253, 21253, 21253, 21253, 21253, 21253, 1305, 21253, 21253, 21253,
-    21253, 21253, 21253, 21253, 21253, 21253, 21253, 21253, 21253, 21253,
-    16000, 21253, 21253, 21253, 21253, 21253, 16000, 21253, 16000, 17926,
-    17926, 17926, 17926, 16000, 16000, 16000, 16000, 16000, 16000, 16000,
-    16000, 16000, 16000, 16000, 16000, 664, 10772, 10772, 6807, 6807,
-    26133, 26262, 26133, 26262, 26133, 26262, 26133, 26262, 26133, 26262,
-    26133, 26262, 16000, 16000, 16000, 16000, 664, 664, 664, 664,
-    6807, 6807, 6807, 1432, 664, 1432, 16000, 664, 1432, 664,
-    664, 10772, 26133, 26262, 26133, 26262, 26133, 26262, 792, 664,
-    3329, 3457, 3585, 3713, 3841, 3969, 4097, 4225, 4353, 4481,
-    4609, 4737, 4865, 4993, 5121, 5249, 5377, 5505, 5633, 5761,
-    5889, 6017, 6145, 6273, 6401, 6529, 26133, 664, 26262, 6683,
-    6807,
-  };
-/** Length of data. */
-static const int data_length = 5351;
+static const jchar data0[] = {
+    8834, 8962, 9090, 9218, 9346, 9474, 9602, 9730, 9858, 9986, 
+    10114, 1109, 3225, 1238, 3225, 15, 15, 15, 15, 15, 
+    15, 15, 15, 15, 143, 271, 143, 399, 271, 15, 
+    15, 15, 15, 15, 271, 15, 15, 15, 15, 15, 
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
+    15, 271, 271, 271, 143, 1801, 1929, 2057, 2185, 2313, 
+    2441, 2569, 2697, 2825, 2953, 1432, 664, 3161, 3225, 3161, 
+    664, 664, 3225, 664, 6807, 16256, 16256, 664, 16256, 16256, 
+    16256, 16256, 16256, 16256, 16256, 524, 664, 664, 792, 922, 
+    792, 664, 664, 1109, 1238, 664, 1305, 1432, 1556, 1432, 
+    1688, 10908, 1305, 11019, 11147, 6683, 11266, 10396, 664, 6683, 
+    11403, 10498, 11614, 11659, 11659, 11659, 664, 3329, 3457, 3585, 
+    3713, 3841, 3969, 4097, 4225, 4353, 4481, 4609, 4737, 4865, 
+    4993, 5121, 5249, 5377, 5505, 5633, 5761, 5889, 6017, 6145, 
+    6273, 6401, 6529, 1109, 664, 1238, 6683, 6807, 664, 664, 
+    664, 3225, 1109, 1238, 664, 664, 664, 664, 664, 664, 
+    664, 664, 664, 34189, 34318, 34448, 34576, 34704, 34832, 34960, 
+    33452, 10284, 664, 922, 922, 922, 922, 10396, 10396, 6683, 
+    10396, 10498, 10717, 3225, 10768, 10396, 6683, 6914, 7042, 7170, 
+    7298, 7426, 7554, 7682, 7810, 7938, 8066, 8194, 8322, 8450, 
+    8578, 8706, 19074, 11777, 11777, 11777, 11777, 11777, 11777, 11777, 
+    11777, 11777, 11777, 11777, 11777, 11777, 11777, 11777, 11777, 3225, 
+    11777, 11777, 11777, 11777, 11777, 11777, 11777, 11906, 15361, 15491, 
+    15618, 12289, 12418, 15873, 16001, 12289, 12418, 12289, 12418, 12289, 
+    12418, 12289, 12418, 12801, 12289, 12418, 12289, 12418, 12289, 12418, 
+    12930, 19074, 12034, 12034, 12034, 12034, 12034, 12034, 12034, 12034, 
+    12034, 12034, 12034, 12034, 12034, 12034, 12034, 12034, 3225, 12034, 
+    12034, 12034, 12034, 12034, 12034, 12034, 12162, 16129, 10498, 12289, 
+    12418, 12289, 12418, 12289, 12418, 12289, 12418, 12289, 12418, 12289, 
+    12418, 12289, 12418, 12289, 12418, 15746, 12289, 12418, 21404, 18310, 
+    18310, 18310, 18310, 16256, 21511, 21511, 12289, 12418, 12289, 12418, 
+    12289, 12418, 16256, 16256, 12289, 12418, 16256, 16256, 16256, 16256, 
+    16256, 16256, 18310, 24584, 16256, 16256, 16256, 16256, 15109, 15109, 
+    16256, 15109, 16256, 16256, 15109, 15109, 16256, 15109, 16256, 16256, 
+    15109, 16256, 16256, 11906, 32258, 11906, 16256, 11906, 19074, 33153, 
+    33153, 33281, 33281, 32515, 6683, 6683, 16256, 18310, 18310, 24584, 
+    16256, 15109, 15109, 15109, 15109, 15109, 15109, 15109, 15109, 15109, 
+    16256, 15109, 16256, 15109, 15109, 15109, 15109, 16256, 16256, 15109, 
+    15109, 15109, 15109, 15109, 15109, 15109, 16256, 16256, 16256, 15109, 
+    15109, 15109, 15109, 15109, 15109, 16256, 16256, 15109, 15109, 15109, 
+    15109, 15109, 15109, 15109, 15109, 15109, 15109, 15109, 15109, 15109, 
+    21784, 21784, 15109, 15109, 15109, 15109, 15361, 15491, 15618, 15361, 
+    15491, 15618, 15361, 15491, 15618, 12289, 12418, 12289, 12418, 10498, 
+    10498, 10498, 16256, 16256, 16256, 16256, 16256, 16256, 16256, 16256, 
+    16256, 15109, 15109, 15109, 15109, 16256, 15109, 16256, 15109, 15109, 
+    16256, 15109, 15109, 15109, 15109, 15109, 16256, 16256, 18310, 15109, 
+    24584, 24584, 18310, 18310, 18310, 16256, 16256, 16256, 24584, 24584, 
+    16256, 16256, 24584, 24584, 18310, 16256, 16256, 12545, 12674, 12289, 
+    12418, 12289, 12418, 12289, 12418, 10498, 12289, 12418, 12289, 12418, 
+    12289, 12418, 12289, 12418, 11906, 11906, 11906, 11906, 11906, 30850, 
+    16256, 16256, 16256, 16256, 6683, 6683, 16256, 16256, 16256, 16256, 
+    18052, 16256, 16256, 16256, 664, 16256, 21633, 21633, 21633, 21633, 
+    21633, 21633, 21633, 21633, 21633, 21633, 21633, 21633, 21633, 21633, 
+    21633, 21633, 16256, 16256, 18052, 21784, 21784, 21784, 21784, 21784, 
+    21784, 21404, 21404, 21404, 21404, 21404, 18310, 18310, 21404, 21404, 
+    21404, 21404, 21404, 21404, 18310, 21404, 21404, 21404, 21404, 21404, 
+    21404, 16256, 16256, 21404, 15109, 16256, 16256, 16256, 16256, 16256, 
+    16256, 16256, 16256, 16256, 16256, 16256, 16256, 16256, 16256, 16256, 
+    19842, 19970, 20097, 20097, 20097, 20226, 20354, 10498, 12289, 12418, 
+    12289, 12418, 12289, 12418, 12289, 12418, 12289, 12418, 11906, 12289, 
+    12418, 12289, 12418, 12289, 12418, 14721, 12289, 12418, 14721, 10498, 
+    10498, 12289, 12418, 14721, 12289, 17666, 10498, 10498, 17666, 10498, 
+    10498, 10498, 10498, 17666, 10498, 17794, 17794, 10498, 10498, 10498, 
+    10498, 17410, 10498, 10498, 17538, 10498, 10498, 10498, 10498, 10498, 
+    10498, 10498, 10498, 10498, 10498, 16386, 16514, 10498, 16642, 16642, 
+    10498, 16770, 10498, 16898, 10498, 10498, 10498, 10498, 13057, 12289, 
+    12418, 12289, 12418, 13185, 12289, 12418, 13313, 13313, 12289, 12418, 
+    10498, 13441, 13569, 13697, 12289, 12418, 13313, 13825, 13954, 14081, 
+    14209, 12289, 12418, 10498, 10498, 14081, 14337, 14466, 14593, 12418, 
+    14849, 14849, 12289, 12418, 12289, 12418, 14977, 12289, 12418, 10498, 
+    15109, 12289, 12418, 10498, 15234, 18310, 18310, 18310, 18310, 18310, 
+    18438, 18310, 18310, 18310, 18310, 18310, 18310, 18310, 18310, 18310, 
+    18310, 16256, 18310, 18310, 18310, 22168, 18310, 18310, 22168, 18310, 
+    16256, 16256, 16256, 16256, 16256, 16256, 16256, 16256, 16256, 16256, 
+    16256, 24584, 16256, 16256, 16256, 16256, 15109, 15109, 16256, 15109, 
+    15109, 15109, 15109, 16256, 16256, 16256, 15109, 15109, 16256, 15109, 
+    16256, 15109, 15109, 16256, 15109, 15109, 16256, 15109, 15109, 16256, 
+    16256, 18310, 16256, 24584, 24584, 24584, 16256, 15109, 15109, 15109, 
+    15109, 15109, 15109, 15109, 15109, 16256, 15109, 15109, 15109, 16256, 
+    16256, 16256, 16256, 24584, 24584, 21784, 16256, 16256, 16256, 16256, 
+    16256, 16256, 16256, 16256, 16256, 16256, 16256, 16256, 16256, 16256, 
+    16256, 16256, 24464, 24464, 24464, 10396, 10396, 16256, 16256, 16256, 
+    664, 664, 24713, 24841, 24969, 25097, 25225, 25353, 25481, 25609, 
+    25737, 25865, 16256, 16256, 16256, 16256, 16256, 16256, 18310, 15109, 
+    16256, 15109, 15109, 15109, 15109, 15109, 15109, 16256, 16256, 16256, 
+    15109, 15109, 16256, 16256, 16256, 15109, 15109, 15109, 16256, 16256, 
+    16256, 15109, 15109, 15109, 15109, 15109, 15109, 16256, 16256, 15109, 
+    15109, 15109, 16256, 16256, 16256, 21890, 21890, 21890, 21890, 21890, 
+    21890, 21890, 21890, 21890, 21890, 21890, 21890, 21890, 21890, 21890, 
+    21890, 11906, 16256, 21784, 22036, 16256, 16256, 16256, 16256, 16256, 
+    18310, 18310, 16256, 16256, 16256, 16256, 16256, 16256, 16256, 16256, 
+    16256, 22661, 22661, 22661, 22661, 22661, 22661, 22661, 22661, 22661, 
+    22661, 22661, 22661, 22661, 22661, 22661, 22661, 27541, 27670, 16642, 
+    10498, 10498, 17026, 10498, 10498, 10498, 10498, 17154, 17282, 10498, 
+    10498, 10498, 10498, 10498, 17282, 22416, 22416, 22416, 22416, 16256, 
+    16256, 16256, 16256, 16256, 16256, 16256, 16256, 1432, 22552, 10396, 
+    10396, 20097, 10396, 10396, 10396, 10396, 20097, 10396, 10396, 10498, 
+    20097, 20097, 20097, 10498, 10498, 17922, 10498, 10498, 10498, 10498, 
+    10498, 10498, 10498, 10498, 10498, 10498, 10498, 10498, 10498, 10498, 
+    10498, 10498, 18052, 18052, 18052, 18052, 18052, 18052, 18052, 18052, 
+    18052, 18052, 18052, 18052, 18052, 18052, 18052, 18052, 18180, 18180, 
+    18052, 18052, 18052, 18052, 18052, 6683, 6683, 6683, 6683, 6683, 
+    6683, 6683, 6683, 6683, 18052, 6683, 22036, 15109, 15109, 15109, 
+    15109, 15109, 15109, 15109, 15109, 15109, 15109, 15109, 15109, 15109, 
+    15109, 15109, 16256, 15109, 15109, 15109, 15109, 15109, 15109, 15109, 
+    15109, 15109, 15109, 15109, 15109, 15109, 15109, 15109, 15109, 18052, 
+    18052, 6683, 6683, 6683, 6683, 18180, 18180, 18180, 18180, 18180, 
+    18180, 18180, 18180, 18180, 18180, 18052, 18052, 6683, 6683, 6683, 
+    6683, 6683, 6683, 6683, 6683, 6683, 6683, 6683, 6683, 6683, 
+    6683, 6683, 6683, 11906, 32258, 11906, 16256, 11906, 19074, 32769, 
+    32769, 32769, 32769, 32515, 6683, 6683, 6683, 10396, 44170, 44298, 
+    44426, 44554, 44682, 44810, 44938, 45066, 45194, 18310, 18310, 18310, 
+    18310, 18310, 18310, 18310, 18310, 16256, 18310, 18310, 18310, 18310, 
+    18310, 18310, 18310, 18310, 18310, 18310, 18310, 18310, 18310, 18310, 
+    18310, 18310, 16256, 21404, 21404, 25995, 26123, 26251, 26379, 21404, 
+    21404, 21404, 21404, 21404, 21404, 21404, 21404, 21404, 21404, 21404, 
+    10396, 3225, 10396, 10396, 10396, 10396, 10396, 10396, 10396, 10396, 
+    10396, 10396, 10396, 10396, 16256, 10396, 16256, 10396, 10396, 10396, 
+    10396, 16256, 10396, 10396, 10396, 10396, 16256, 16256, 10396, 10396, 
+    10396, 10396, 10396, 21404, 10396, 10396, 10396, 10396, 10396, 3225, 
+    3225, 3225, 3225, 3225, 27541, 27670, 664, 10396, 10396, 10396, 
+    10396, 10396, 10396, 10396, 10396, 10396, 10396, 16256, 10396, 10396, 
+    10396, 10396, 10396, 10396, 10396, 1109, 1238, 1109, 1238, 1109, 
+    1238, 1109, 1238, 29579, 29707, 29835, 29963, 30091, 30219, 30347, 
+    30475, 30603, 43915, 29579, 29707, 29835, 29963, 30091, 30219, 18310, 
+    18310, 18310, 18310, 18310, 18310, 18310, 18310, 16256, 16256, 16256, 
+    16256, 16256, 18310, 18310, 18310, 18310, 18310, 18310, 18310, 18310, 
+    18310, 18310, 18310, 18310, 18310, 18310, 24584, 24584, 16256, 16256, 
+    16256, 24584, 24584, 24584, 16256, 24584, 24584, 24584, 18310, 16256, 
+    16256, 18310, 24584, 24584, 16256, 15109, 15109, 15109, 15109, 15109, 
+    15109, 15109, 15109, 16256, 16256, 15109, 15109, 15109, 16256, 15109, 
+    16256, 15109, 16256, 16256, 15109, 15109, 16256, 15109, 15109, 15109, 
+    15109, 15109, 16256, 15109, 15109, 16256, 24584, 18310, 18310, 18310, 
+    18310, 16256, 16256, 24584, 24584, 16256, 16256, 24584, 24584, 18310, 
+    16256, 16256, 20482, 20610, 20738, 10498, 20865, 20994, 3225, 12289, 
+    12418, 21121, 12289, 12418, 16256, 16256, 16256, 16256, 6683, 6683, 
+    18561, 664, 18689, 18689, 18689, 16256, 18817, 16256, 18945, 18945, 
+    11777, 11777, 16256, 11777, 11777, 11777, 11777, 11777, 11777, 11777, 
+    11777, 11777, 19202, 19330, 19330, 19330, 12034, 12034, 19458, 12034, 
+    12034, 12034, 12034, 12034, 12034, 12034, 12034, 12034, 19586, 19714, 
+    19714, 16256, 18310, 18310, 24584, 16256, 15109, 15109, 15109, 15109, 
+    15109, 15109, 16256, 16256, 16256, 16256, 15109, 15109, 15109, 15109, 
+    16256, 15109, 15109, 15109, 15109, 15109, 15109, 15109, 15109, 15109, 
+    16256, 15109, 16256, 16256, 16256, 15109, 15109, 15109, 15109, 16256, 
+    16256, 18310, 15109, 24584, 24584, 18310, 24584, 24584, 24584, 24584, 
+    24584, 24584, 18310, 18310, 18310, 16256, 16256, 16256, 16256, 21249, 
+    21249, 21249, 21249, 21249, 21249, 21249, 21249, 21249, 21249, 21249, 
+    21249, 21249, 21249, 21249, 21249, 20610, 20610, 20610, 20610, 20610, 
+    20610, 20610, 20610, 20610, 20610, 20610, 20610, 20610, 20610, 20610, 
+    20610, 20097, 12289, 12418, 12289, 12418, 12289, 12418, 12289, 12418, 
+    12289, 12418, 12289, 12418, 12289, 12418, 16256, 16256, 16256, 16256, 
+    16256, 16256, 24713, 24841, 24969, 25097, 25225, 25353, 25481, 25609, 
+    25737, 25865, 27403, 27403, 27403, 27403, 27403, 27403, 21404, 18310, 
+    21404, 18310, 21404, 18310, 27541, 27670, 27541, 27670, 24584, 24584, 
+    18310, 18310, 18310, 16256, 18310, 16256, 24584, 24584, 24584, 24584, 
+    24584, 24584, 24584, 24584, 18310, 24584, 24584, 18310, 18310, 18310, 
+    18310, 18310, 18310, 18310, 18310, 24584, 24584, 24584, 24584, 18310, 
+    16256, 16256, 21784, 21784, 21784, 21784, 21784, 21784, 21784, 21784, 
+    24841, 24969, 25097, 25225, 25353, 25481, 25609, 18310, 18310, 18310, 
+    18310, 18310, 18310, 18310, 18310, 18310, 16256, 16256, 16256, 16256, 
+    16256, 16256, 16256, 16256, 16256, 16256, 16256, 16256, 11906, 11906, 
+    11906, 11906, 11906, 16256, 16256, 16256, 16256, 16256, 22277, 18310, 
+    22277, 22277, 16256, 22277, 22277, 16256, 22277, 22277, 22277, 22277, 
+    22277, 22277, 22277, 22277, 22277, 22277, 22277, 22277, 22277, 22277, 
+    22277, 22277, 16256, 16256, 16256, 16256, 16256, 24584, 24584, 16256, 
+    16256, 16256, 16256, 16256, 16256, 16256, 15109, 16256, 15109, 15109, 
+    16256, 15109, 15109, 15109, 15109, 15109, 16256, 16256, 18310, 15109, 
+    24584, 18310, 18310, 18310, 18310, 18310, 16256, 18310, 18310, 24584, 
+    16256, 24584, 24584, 18310, 16256, 16256, 664, 664, 792, 922, 
+    792, 664, 664, 1109, 1238, 664, 1305, 1432, 1556, 1432, 
+    1688, 22277, 22277, 22277, 22168, 22168, 16256, 16256, 16256, 16256, 
+    16256, 16256, 16256, 16256, 16256, 16256, 16256, 24584, 16256, 16256, 
+    16256, 16256, 16256, 16256, 16256, 16256, 11659, 11659, 11659, 11659, 
+    11659, 11659, 11659, 11659, 11659, 11659, 11659, 11659, 29579, 22921, 
+    23049, 23177, 23305, 23433, 23561, 23689, 23817, 23945, 24073, 792, 
+    24216, 24216, 22552, 22661, 22661, 22661, 22661, 22552, 22661, 18310, 
+    18310, 18310, 18310, 18310, 18310, 18310, 22416, 21511, 18310, 21511, 
+    21511, 21511, 18310, 18310, 18310, 18310, 18310, 18310, 16256, 16256, 
+    16256, 16256, 16256, 22552, 16256, 16256, 16256, 22552, 22552, 22552, 
+    22552, 22552, 22552, 22552, 22552, 22552, 22552, 22552, 22552, 22552, 
+    22552, 16256, 24464, 22788, 22661, 22661, 22661, 22661, 22661, 22661, 
+    22661, 22661, 22661, 22661, 18310, 18310, 18310, 18310, 18310, 18310, 
+    18310, 18310, 18310, 18310, 18310, 16256, 16256, 22661, 22661, 22661, 
+    22661, 22661, 16256, 22661, 22661, 22661, 22661, 22661, 22661, 22661, 
+    22661, 22661, 22661, 22661, 16256, 16256, 16256, 16256, 16256, 16256, 
+    16256, 16256, 16256, 16256, 16256, 16256, 16256, 16256, 24841, 24969, 
+    25097, 25225, 25353, 25481, 25609, 25737, 25865, 26763, 27787, 27915, 
+    28043, 28171, 28299, 28427, 28555, 28683, 26891, 28811, 16256, 16256, 
+    16256, 1801, 1929, 2057, 2185, 2313, 2441, 2569, 2697, 2825, 
+    2953, 22661, 22661, 22661, 24348, 24348, 22661, 18310, 22661, 22661, 
+    22661, 22661, 22661, 22661, 22661, 22661, 22661, 22661, 22661, 22661, 
+    22661, 22661, 22661, 16256, 16256, 24464, 24464, 24464, 24464, 16256, 
+    16256, 16256, 16256, 16256, 16256, 24464, 24464, 24464, 24464, 24464, 
+    24464, 18310, 18310, 18310, 18310, 18310, 22788, 22788, 18310, 18310, 
+    10396, 18310, 18310, 18310, 18310, 22661, 22661, 22661, 22661, 22661, 
+    22661, 22661, 22661, 22661, 22661, 22661, 22661, 50458, 10396, 16256, 
+    16256, 18310, 22661, 16256, 16256, 16256, 16256, 16256, 16256, 16256, 
+    16256, 16256, 16256, 16256, 16256, 16256, 16256, 1238, 664, 1109, 
+    1238, 664, 6807, 15109, 15109, 15109, 15109, 15109, 15109, 15109, 
+    15109, 15109, 15109, 16256, 16256, 16256, 16256, 24584, 24584, 16256, 
+    15109, 15109, 15109, 15109, 15109, 15109, 15109, 15109, 16256, 15109, 
+    15109, 15109, 15109, 15109, 16256, 16256, 16256, 16256, 18310, 18310, 
+    24584, 15109, 15109, 15109, 15109, 15109, 15109, 15109, 15109, 15109, 
+    15109, 15109, 15109, 27541, 27670, 16256, 16256, 16256, 524, 15109, 
+    15109, 15109, 15109, 15109, 15109, 15109, 15109, 15109, 15109, 15109, 
+    15109, 15109, 15109, 15109, 16256, 16256, 16256, 16256, 16256, 15109, 
+    15109, 15109, 15109, 15109, 15109, 15109, 15109, 15109, 15109, 15109, 
+    6807, 18052, 18052, 18052, 15109, 15109, 15109, 18052, 15109, 15109, 
+    15109, 15109, 15109, 15109, 15109, 15109, 15109, 15109, 15109, 15109, 
+    15109, 15109, 15109, 16256, 16256, 18310, 15109, 24584, 24584, 24584, 
+    24584, 24584, 16256, 27142, 24584, 24584, 16256, 24584, 24584, 18310, 
+    18310, 16256, 16256, 16256, 16256, 18310, 18310, 16256, 16256, 18310, 
+    18310, 18310, 16256, 16256, 15109, 15109, 15109, 15109, 15109, 15109, 
+    15109, 16256, 16256, 18310, 18310, 6683, 6683, 18052, 18052, 15109, 
+    18310, 18310, 18310, 18310, 16256, 16256, 16256, 15109, 15109, 15109, 
+    15109, 15109, 15109, 15109, 15109, 15109, 16256, 16256, 21784, 16256, 
+    16256, 16256, 16256, 15109, 15109, 18310, 18310, 21784, 21784, 24713, 
+    24841, 24969, 25097, 25225, 25353, 25481, 25609, 25737, 25865, 21784, 
+    21784, 16256, 16256, 16256, 16256, 15109, 15109, 18310, 18310, 16256, 
+    16256, 24713, 24841, 24969, 25097, 25225, 25353, 25481, 25609, 25737, 
+    25865, 16256, 16256, 15109, 15109, 16256, 16256, 15109, 15109, 922, 
+    922, 25995, 26123, 26251, 26379, 26507, 26635, 21404, 16256, 16256, 
+    16256, 16256, 16256, 18310, 18310, 15109, 15109, 15109, 16256, 16256, 
+    16256, 16256, 16256, 16256, 16256, 16256, 16256, 16256, 16256, 15109, 
+    18310, 15109, 15109, 18310, 18310, 18310, 18310, 18310, 18310, 18310, 
+    16256, 16256, 16256, 16256, 922, 16256, 16256, 16256, 16256, 16256, 
+    16256, 16256, 16256, 16256, 16256, 16256, 16256, 16256, 16256, 15109, 
+    15109, 15109, 15109, 15109, 15109, 18052, 18310, 18310, 18310, 18310, 
+    18310, 18310, 18310, 18310, 21784, 18310, 18310, 15109, 15109, 15109, 
+    15109, 16256, 16256, 16256, 16256, 24713, 24841, 24969, 25097, 25225, 
+    25353, 25481, 25609, 25737, 25865, 21784, 21784, 21784, 21784, 21784, 
+    21784, 26763, 26891, 27019, 10396, 10396, 10396, 10396, 10396, 10396, 
+    922, 10396, 16256, 16256, 16256, 16256, 16256, 18310, 24584, 24584, 
+    24584, 24584, 16256, 18310, 18310, 18310, 16256, 18310, 18310, 18310, 
+    18310, 16256, 16256, 15109, 15109, 15109, 15109, 16256, 15109, 15109, 
+    15109, 15109, 15109, 16256, 16256, 18310, 15109, 24584, 27142, 24584, 
+    18310, 18310, 18310, 16256, 16256, 24584, 24584, 24584, 16256, 24584, 
+    24584, 24584, 18310, 16256, 16256, 15109, 15109, 15109, 15109, 15109, 
+    15109, 15109, 16256, 16256, 16256, 18310, 16256, 16256, 16256, 16256, 
+    24584, 24584, 16256, 15109, 15109, 15109, 15109, 15109, 15109, 15109, 
+    15109, 15109, 15109, 15109, 21784, 21784, 21784, 28938, 29066, 15109, 
+    18310, 15109, 15109, 18310, 18310, 18310, 18310, 18310, 18310, 16256, 
+    18310, 18310, 15109, 16256, 16256, 15109, 15109, 15109, 15109, 15109, 
+    16256, 18052, 16256, 18310, 18310, 18310, 18310, 18310, 18310, 16256, 
+    16256, 15109, 21404, 21404, 21404, 21784, 21784, 21784, 21784, 21784, 
+    21784, 21784, 21784, 27320, 21784, 21784, 21784, 18310, 24584, 18310, 
+    16256, 16256, 16256, 18310, 18310, 24584, 18310, 16256, 16256, 16256, 
+    16256, 16256, 16256, 15109, 15109, 15109, 15109, 15109, 15109, 24584, 
+    24584, 18310, 18310, 16256, 16256, 16256, 16256, 16256, 16256, 20097, 
+    20097, 10396, 20097, 10498, 15109, 15109, 15109, 15109, 10498, 10396, 
+    10396, 16256, 10498, 20097, 20097, 20097, 20097, 20097, 20097, 20097, 
+    20097, 20097, 20097, 20097, 20097, 20097, 20097, 20097, 20097, 16256, 
+    16256, 16256, 16256, 16256, 16256, 16256, 16256, 16256, 16256, 15109, 
+    15109, 15109, 15109, 15109, 15109, 15109, 15109, 15109, 15109, 16256, 
+    16256, 16256, 16256, 16256, 16256, 16256, 16256, 16256, 16256, 16256, 
+    16256, 29194, 16256, 16256, 16256, 16256, 16256, 16256, 16256, 16256, 
+    16256, 16256, 16256, 16256, 16256, 16256, 16256, 15109, 15109, 18310, 
+    18310, 18310, 16256, 16256, 16256, 16256, 16256, 16256, 16256, 16256, 
+    16256, 16256, 16256, 15109, 15109, 18310, 18310, 18310, 21784, 21784, 
+    16256, 16256, 16256, 16256, 16256, 16256, 16256, 16256, 16256, 15109, 
+    15109, 18310, 18310, 16256, 16256, 16256, 16256, 16256, 16256, 16256, 
+    16256, 16256, 16256, 16256, 16256, 15109, 16256, 18310, 18310, 16256, 
+    16256, 16256, 16256, 16256, 16256, 16256, 16256, 16256, 16256, 16256, 
+    16256, 15109, 15109, 15109, 15109, 29328, 29328, 24584, 18310, 18310, 
+    18310, 18310, 18310, 18310, 18310, 24584, 24584, 24584, 24584, 18310, 
+    18310, 30728, 30728, 30728, 16256, 16256, 16256, 16256, 18310, 18310, 
+    18310, 18310, 21784, 21784, 21784, 18052, 21784, 21784, 21784, 922, 
+    15109, 18310, 16256, 16256, 43275, 43403, 43531, 43659, 43787, 29579, 
+    29707, 29835, 29963, 30091, 30219, 30347, 30475, 30603, 43915, 29451, 
+    29579, 29707, 29835, 29963, 30091, 30219, 30347, 30475, 30603, 16256, 
+    16256, 16256, 16256, 16256, 16256, 664, 664, 664, 664, 664, 
+    664, 22036, 664, 664, 664, 664, 18310, 18310, 18310, 524, 
+    16256, 15109, 15109, 15109, 15109, 15109, 15109, 15109, 15109, 15109, 
+    18310, 16256, 16256, 16256, 16256, 16256, 16256, 20097, 20097, 20097, 
+    10498, 10396, 20097, 10396, 10396, 10396, 20097, 20097, 20097, 20097, 
+    20097, 10396, 10396, 3225, 10396, 3225, 10396, 10396, 10396, 10396, 
+    10396, 10396, 10396, 10396, 10396, 10396, 10396, 10396, 10396, 10396, 
+    10396, 10396, 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, 
+    3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3161, 3161, 
+    3161, 3161, 3161, 3161, 3225, 3225, 1109, 1238, 3225, 3225, 
+    3225, 1109, 1238, 1109, 1238, 1109, 1238, 1109, 1238, 1109, 
+    1238, 1109, 1238, 1109, 1238, 3225, 3225, 3161, 3161, 3161, 
+    3161, 3161, 3225, 3225, 3225, 3225, 3225, 3161, 3225, 3161, 
+    3161, 3161, 3161, 3161, 3161, 3161, 3225, 3225, 3225, 3225, 
+    3225, 3161, 3225, 3161, 3225, 3161, 3161, 3161, 3161, 3161, 
+    3161, 3161, 3161, 3225, 3225, 3161, 3161, 3161, 3161, 3161, 
+    3161, 3161, 3161, 3225, 3161, 3225, 3161, 3161, 3161, 3225, 
+    3225, 3161, 3161, 3225, 3225, 3225, 3225, 3225, 3225, 3161, 
+    3225, 3225, 3225, 3161, 3161, 3161, 3161, 3161, 3225, 3161, 
+    3225, 3225, 3161, 3161, 3225, 3225, 3225, 3225, 3161, 3161, 
+    3161, 3161, 3161, 3161, 3161, 3161, 3161, 3161, 3161, 3161, 
+    3161, 3225, 3225, 3161, 3225, 3161, 3225, 3225, 3161, 3225, 
+    3161, 3161, 3161, 3161, 3225, 3225, 3225, 3161, 3161, 3161, 
+    3161, 3161, 3161, 3225, 3225, 3225, 3161, 3225, 3225, 3225, 
+    3225, 3161, 3161, 3225, 3225, 3225, 3225, 3225, 3225, 3161, 
+    3161, 3161, 3225, 3225, 3225, 3225, 3225, 3161, 3225, 3225, 
+    3225, 3225, 3225, 3225, 3225, 3225, 3161, 3225, 3225, 3225, 
+    3225, 3225, 3225, 3225, 3161, 3161, 3225, 3225, 3225, 3225, 
+    3225, 3225, 3225, 10396, 10396, 10396, 10396, 10396, 3225, 3225, 
+    10396, 10396, 10396, 10396, 20097, 10396, 35969, 10396, 20097, 10396, 
+    36097, 36225, 20097, 20097, 10908, 10498, 18052, 18052, 10498, 10498, 
+    10498, 10498, 10498, 10498, 10498, 10498, 10498, 10498, 16256, 16256, 
+    16256, 16256, 30978, 30978, 30978, 30978, 30978, 30978, 30978, 30978, 
+    31105, 31105, 31105, 31105, 31105, 31105, 31105, 31105, 30978, 30978, 
+    30978, 30978, 30978, 30978, 16256, 16256, 31105, 31105, 31105, 31105, 
+    31105, 31105, 16256, 16256, 11906, 30978, 19074, 30978, 19074, 30978, 
+    19074, 30978, 16256, 31105, 16256, 31105, 16256, 31105, 16256, 31105, 
+    31234, 31234, 31362, 31362, 31362, 31362, 31490, 31490, 31618, 31618, 
+    31746, 31746, 31874, 31874, 16256, 16256, 32002, 32002, 32002, 32002, 
+    32002, 32002, 32002, 32002, 32131, 32131, 32131, 32131, 32131, 32131, 
+    32131, 32131, 30978, 30978, 11906, 32258, 11906, 16256, 11906, 19074, 
+    31105, 31105, 32385, 32385, 32515, 6683, 32642, 6683, 30978, 30978, 
+    19074, 19074, 16256, 16256, 11906, 19074, 31105, 31105, 32897, 32897, 
+    16256, 6683, 6683, 6683, 30978, 30978, 19074, 19074, 11906, 20738, 
+    11906, 19074, 31105, 31105, 33025, 33025, 21121, 6683, 6683, 6683, 
+    524, 524, 524, 524, 524, 524, 524, 33452, 524, 524, 
+    524, 33548, 24464, 24464, 29328, 33680, 22036, 33844, 22036, 22036, 
+    22036, 22036, 664, 664, 33949, 34078, 27541, 33949, 33949, 34078, 
+    27541, 33949, 1432, 664, 1432, 16256, 664, 1432, 664, 664, 
+    22036, 27541, 27670, 27541, 27670, 27541, 27670, 792, 792, 792, 
+    792, 792, 664, 664, 664, 664, 10717, 11614, 664, 664, 
+    664, 664, 6807, 35083, 10498, 16256, 16256, 35211, 35339, 35467, 
+    35595, 35723, 35851, 1305, 1305, 3225, 1109, 1238, 10498, 35083, 
+    11403, 11019, 11147, 35211, 35339, 35467, 35595, 35723, 35851, 1305, 
+    1305, 3225, 1109, 1238, 16256, 922, 922, 922, 922, 922, 
+    922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 
+    922, 16256, 16256, 16256, 16256, 16256, 16256, 16256, 16256, 16256, 
+    16256, 16256, 16256, 16256, 16256, 18310, 18310, 18310, 18310, 18310, 
+    18310, 18310, 18310, 18310, 18310, 18310, 18310, 18310, 21511, 21511, 
+    21511, 3225, 3225, 3225, 3161, 3161, 3161, 3161, 3225, 3225, 
+    3225, 3225, 3225, 3161, 3161, 3161, 3225, 3225, 3161, 3161, 
+    3161, 3161, 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, 
+    3225, 3161, 3161, 3161, 3161, 3161, 3225, 3225, 3225, 3225, 
+    3225, 3161, 3161, 3161, 3225, 3225, 3161, 3161, 3225, 3225, 
+    3161, 3161, 3161, 3161, 3161, 3161, 3161, 3161, 3161, 3161, 
+    3161, 3161, 3161, 3161, 3161, 3161, 3225, 3225, 3225, 3225, 
+    3225, 3161, 3161, 3225, 3225, 3225, 3225, 3161, 3161, 3161, 
+    3161, 3225, 3161, 1305, 1305, 3225, 3161, 3161, 3225, 3225, 
+    3225, 3161, 3161, 3161, 3161, 3225, 3161, 3225, 3161, 3225, 
+    3225, 3225, 3225, 3161, 3161, 3161, 3161, 3161, 3161, 3161, 
+    3161, 3161, 3161, 3161, 3161, 3161, 3225, 3161, 3161, 3225, 
+    3225, 1109, 1238, 1109, 1238, 3161, 3225, 3225, 3225, 3225, 
+    20097, 10498, 10498, 10498, 10498, 10396, 3225, 16256, 16256, 16256, 
+    16256, 36362, 36490, 36618, 36746, 36874, 37002, 37130, 37258, 37386, 
+    37514, 37642, 37770, 37898, 38026, 38154, 38282, 38410, 38538, 38666, 
+    38794, 38922, 39050, 39178, 39306, 39434, 39562, 39690, 39818, 39946, 
+    40074, 40202, 40330, 40458, 40586, 40714, 40842, 16256, 16256, 16256, 
+    16256, 16256, 16256, 16256, 16256, 16256, 16256, 16256, 16256, 3225, 
+    10396, 10396, 3225, 10396, 10396, 3225, 10396, 10396, 10396, 10396, 
+    10396, 10396, 10396, 3225, 10396, 10396, 10396, 10396, 10396, 10396, 
+    10396, 10396, 3161, 3161, 3161, 3161, 10396, 10396, 10396, 10396, 
+    10396, 10396, 10396, 1109, 1238, 10396, 10396, 10396, 10396, 10396, 
+    10396, 21404, 21404, 21404, 21404, 21404, 21404, 21404, 21404, 21404, 
+    21404, 21404, 21404, 21404, 21404, 21404, 21404, 10396, 10396, 16256, 
+    21404, 48267, 48395, 48523, 48651, 48779, 48907, 49035, 49163, 49291, 
+    49419, 49547, 49675, 49803, 49931, 50059, 30347, 30475, 30603, 43915, 
+    10396, 16256, 16256, 16256, 10396, 10396, 10396, 10396, 10396, 10396, 
+    10396, 10396, 10396, 10396, 10396, 10396, 10396, 10396, 16256, 16256, 
+    16256, 16256, 16256, 16256, 16256, 16256, 16256, 16256, 16256, 16256, 
+    16256, 16256, 16256, 41355, 41483, 41611, 41739, 41867, 41995, 42123, 
+    42251, 11403, 11019, 11147, 35211, 35339, 35467, 35595, 35723, 35851, 
+    40971, 41099, 41227, 41355, 41483, 41611, 41739, 41867, 41995, 42123, 
+    42251, 21404, 21404, 21404, 21404, 21404, 21404, 21404, 21404, 21404, 
+    21404, 21404, 21404, 10396, 10396, 10396, 10396, 21404, 21404, 21404, 
+    21404, 21404, 21404, 21404, 21404, 21404, 21404, 21404, 21404, 21404, 
+    21404, 21404, 16256, 16256, 16256, 16256, 16256, 16256, 16256, 16256, 
+    16256, 16256, 16256, 16256, 25995, 26123, 26251, 26379, 45707, 45835, 
+    45963, 46091, 46219, 26763, 21404, 21404, 21404, 21404, 21404, 21404, 
+    42396, 42396, 42396, 42396, 42396, 42396, 42396, 42396, 42396, 42396, 
+    42396, 42396, 42396, 42396, 42396, 42396, 42524, 42524, 42524, 42524, 
+    42524, 42524, 42524, 42524, 42524, 42524, 42524, 42524, 42524, 42524, 
+    42524, 42524, 35083, 42635, 42763, 42891, 43019, 43147, 22036, 18052, 
+    18052, 18052, 18052, 18052, 10396, 10396, 45322, 45450, 45578, 18052, 
+    15109, 664, 10396, 10396, 10396, 16256, 16256, 16256, 10396, 16256, 
+    10396, 10396, 10396, 10396, 10396, 10396, 10396, 16256, 3225, 3225, 
+    3161, 3161, 3161, 3161, 1109, 1238, 1109, 1238, 1109, 1238, 
+    16256, 16256, 16256, 16256, 524, 664, 664, 664, 10396, 18052, 
+    15109, 44042, 1109, 1238, 1109, 1238, 1109, 1238, 1109, 1238, 
+    10396, 10396, 1109, 1238, 1109, 1238, 1109, 1238, 1109, 1238, 
+    22036, 27541, 27670, 27670, 10396, 46347, 46475, 46603, 46731, 46859, 
+    46987, 47115, 47243, 47371, 47499, 47627, 47755, 47883, 48011, 48139, 
+    50195, 50195, 50195, 50195, 50195, 50195, 50195, 50195, 50195, 50195, 
+    50195, 50195, 50195, 50195, 50195, 50195, 50322, 50322, 50322, 50322, 
+    50322, 50322, 50322, 50322, 50322, 50322, 50322, 50322, 50322, 50322, 
+    50322, 50322, 11906, 11906, 11906, 19074, 19074, 11906, 11906, 16256, 
+    16256, 16256, 16256, 16256, 16256, 16256, 16256, 16256, 22277, 22277, 
+    22277, 22277, 22277, 22277, 22277, 22277, 22277, 1305, 22277, 22277, 
+    22277, 22277, 22277, 22277, 22277, 16256, 22277, 22277, 22277, 22277, 
+    22277, 16256, 22277, 16256, 664, 22036, 22036, 6807, 6807, 27541, 
+    27670, 27541, 27670, 27541, 27670, 27541, 27670, 27541, 27670, 27541, 
+    27670, 664, 664, 27541, 27670, 664, 664, 664, 664, 6807, 
+    6807, 6807, 664, 664, 1305, 1556, 3225, 3225, 3225, 16256, 
+    664, 922, 792, 664, 16256, 16256, 16256, 16256, 8834, 8962, 
+    9090, 9218, 9346, 9474, 9602, 9730, 9858, 9986, 10114, 1109, 
+    3225, 1238, 3225, 1109, 922, 922, 3225, 6683, 10396, 922, 
+    922, 16256, 10396, 3225, 3225, 3225, 3225, 10396, 10396, 16256, 
+};
 
+static const jchar data1[] = {
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
+    5, 5, 128, 5, 5, 5, 5, 5, 5, 5, 
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 128, 
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 128, 
+    5, 5, 128, 5, 5, 5, 5, 5, 5, 5, 
+    5, 5, 5, 5, 5, 5, 5, 128, 128, 5, 
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
+    5, 5, 5, 128, 128, 128, 128, 128, 128, 128, 
+    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 
+    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 
+    128, 128, 128, 128, 128, 128, 128, 6529, 6529, 6529, 
+    6529, 6529, 6529, 6529, 6529, 6529, 6529, 6529, 6529, 6529, 
+    6529, 6529, 6529, 6529, 6529, 6529, 6529, 6529, 6529, 6529, 
+    6529, 6529, 6529, 6529, 6529, 6529, 6529, 6529, 6529, 6529, 
+    6529, 6529, 6529, 6529, 6529, 6529, 6529, 6658, 6658, 6658, 
+    6658, 6658, 6658, 6658, 6658, 6658, 6658, 6658, 6658, 6658, 
+    6658, 6658, 6658, 6658, 6658, 6658, 6658, 6658, 6658, 6658, 
+    6658, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
+    5, 5, 5, 5, 5, 128, 128, 128, 128, 128, 
+    280, 408, 540, 128, 128, 128, 128, 651, 779, 907, 
+    1035, 1163, 1291, 1419, 1547, 1675, 1803, 1931, 2059, 2187, 
+    2315, 2443, 2571, 2699, 2827, 2955, 3083, 3211, 3339, 3467, 
+    3595, 3723, 3851, 3979, 4107, 4235, 4363, 4491, 4619, 4747, 
+    4875, 5003, 5131, 5259, 5387, 5515, 5643, 5771, 5899, 6027, 
+    6155, 6283, 128, 128, 128, 540, 540, 540, 540, 540, 
+    540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 
+    540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 
+    540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 
+    540, 540, 8200, 8200, 8326, 8326, 8326, 540, 540, 540, 
+    8200, 8200, 8200, 8200, 8200, 8200, 8464, 8464, 8464, 8464, 
+    8464, 8464, 8464, 8464, 8326, 8326, 8326, 8326, 8326, 540, 
+    540, 8326, 8326, 8326, 8326, 8326, 8326, 8326, 540, 540, 
+    540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 
+    540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 
+    540, 540, 540, 540, 540, 540, 540, 540, 8326, 8326, 
+    8326, 8326, 540, 540, 540, 540, 540, 540, 540, 540, 
+    540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 
+    540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 
+    540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 
+    540, 128, 128, 128, 540, 540, 540, 540, 540, 540, 
+    540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 
+    540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 
+    540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 
+    540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 
+    540, 540, 540, 540, 540, 540, 540, 540, 540, 540, 
+    540, 540, 540, 540, 540, 540, 540, 540, 128, 128, 
+    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 
+    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 
+    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 
+    128, 128, 5, 5, 5, 5, 5, 5, 5, 5, 
+    5, 5, 6410, 128, 128, 128, 128, 128, 128, 128, 
+    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 
+    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 
+    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 
+    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 
+    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 
+    128, 128, 128, 128, 128, 128, 128, 5, 5, 5, 
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
+    5, 5, 5, 5, 5, 5, 5, 5, 128, 651, 
+    1163, 1803, 2315, 128, 128, 128, 128, 128, 128, 128, 
+    128, 128, 128, 128, 128, 5, 5, 5, 5, 5, 
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
+    5, 5, 5, 5, 5, 128, 280, 128, 128, 128, 
+    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 
+    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 
+    128, 128, 128, 128, 128, 128, 128, 128, 128, 5, 
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 128, 
+    128, 6793, 6921, 7049, 7177, 7305, 7433, 7561, 7689, 7817, 
+    7945, 128, 128, 128, 128, 128, 128, 128, 128, 128, 
+    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 
+    128, 128, 128, 8069, 8069, 8069, 8069, 8069, 8069, 128, 
+    128, 8069, 128, 8069, 8069, 8069, 8069, 8069, 8069, 8069, 
+    8069, 8069, 8069, 8069, 8069, 8069, 8069, 8069, 8069, 8069, 
+    8069, 8069, 8069, 8069, 8069, 8069, 8069, 8069, 8069, 8069, 
+    8069, 8069, 8069, 8069, 8069, 8069, 8069, 8069, 8069, 8069, 
+    8069, 8069, 8069, 8069, 8069, 8069, 8069, 128, 8069, 8069, 
+    128, 128, 128, 8069, 128, 128, 8069, 8604, 8604, 8604, 
+    8604, 8604, 8604, 8604, 8604, 8604, 8604, 8604, 8604, 8604, 
+    8604, 8604, 8604, 8604, 8604, 8604, 8604, 8604, 8604, 8604, 
+    8604, 8604, 8604, 8604, 8604, 8604, 8604, 8604, 8604, 8604, 
+    8604, 8604, 8604, 8604, 8604, 8604, 8604, 8604, 8604, 8604, 
+    8604, 8604, 8604, 8604, 8604, 8604, 8604, 8604, 8604, 8604, 
+    8604, 8604, 8604, 8604, 8604, 8604, 8604, 8604, 8604, 8604, 
+    8604, 128, 128, 128, 128, 128, 128, 128, 128, 128, 
+    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 
+    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 
+    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 
+    128, 128, 8705, 8985, 8834, 8834, 8834, 8834, 8834, 8834, 
+    8834, 8834, 8834, 8834, 8834, 8834, 8834, 8834, 8834, 8834, 
+    8834, 8834, 8834, 8834, 8834, 8834, 8834, 8834, 8834, 8985, 
+    8834, 8834, 8834, 8834, 8834, 8834, 8705, 8705, 8705, 8705, 
+    8705, 8705, 8705, 8705, 8705, 8705, 8705, 8705, 8705, 8705, 
+    8705, 8705, 8705, 8705, 8705, 8705, 8705, 8705, 8705, 8705, 
+    8705, 8985, 8834, 8834, 8834, 8834, 8834, 8834, 8834, 8834, 
+    8834, 8834, 8834, 8834, 8834, 8834, 8834, 8834, 8834, 8834, 
+    8834, 8834, 8834, 8834, 128, 8834, 8834, 8834, 8834, 8834, 
+    8834, 8834, 8834, 8834, 8834, 8834, 8705, 8705, 8705, 8705, 
+    8705, 8705, 8705, 8705, 8705, 8705, 8705, 8705, 8705, 8705, 
+    8705, 8705, 8705, 8705, 8705, 8705, 8705, 8705, 8705, 8705, 
+    8705, 8705, 8834, 8834, 8834, 8834, 8834, 8834, 8834, 8834, 
+    8834, 8834, 8834, 8834, 8834, 8834, 8834, 8834, 8834, 8834, 
+    8834, 8834, 8834, 8834, 8834, 8834, 8834, 8834, 8705, 8705, 
+    8705, 8705, 8705, 8705, 8705, 8705, 8705, 8705, 8705, 8705, 
+    8705, 8705, 8705, 8705, 8705, 8705, 8705, 8705, 8705, 8705, 
+    8705, 8705, 8705, 8705, 8834, 8834, 8834, 8834, 8834, 8834, 
+    8834, 8834, 8834, 8834, 8834, 8834, 8834, 8834, 8834, 8834, 
+    8834, 8834, 8834, 8834, 8834, 8834, 8834, 8834, 8834, 8834, 
+    128, 128, 128, 128, 8705, 8705, 8705, 8705, 8705, 8705, 
+    8705, 8705, 8705, 8705, 8705, 8705, 8705, 8705, 8705, 8705, 
+    8705, 8705, 8705, 8705, 8705, 8705, 8705, 8705, 8834, 8834, 
+    8834, 8834, 8834, 8834, 8834, 128, 8834, 8834, 8834, 8834, 
+    8834, 8834, 8834, 8834, 8834, 8834, 8834, 8834, 8834, 8834, 
+    8834, 8834, 8834, 8834, 8705, 8705, 8705, 8705, 8705, 8705, 
+    8705, 8705, 8705, 8705, 8705, 8705, 8705, 8705, 8705, 8705, 
+    8705, 8705, 8705, 8705, 8705, 8705, 8705, 8705, 128, 8705, 
+    128, 128, 128, 8705, 8705, 8705, 8705, 8705, 8705, 8705, 
+    128, 8834, 8834, 8834, 8834, 8834, 8834, 8834, 8834, 8834, 
+    8834, 8834, 8834, 8834, 8834, 8834, 8834, 8834, 8834, 8834, 
+    8834, 8834, 8834, 8834, 8834, 8834, 8834, 8705, 8705, 8705, 
+    8705, 8705, 8705, 8705, 8705, 8705, 8705, 8705, 8705, 8705, 
+    8705, 8705, 8705, 8705, 8705, 8705, 8705, 8834, 8834, 8834, 
+    8834, 8834, 8834, 8834, 8834, 8834, 8834, 8834, 8834, 8834, 
+    8834, 8834, 8834, 8834, 8834, 8834, 8834, 8834, 8834, 8834, 
+    8834, 8834, 8834, 8705, 128, 8705, 8705, 128, 128, 8705, 
+    128, 128, 8705, 8705, 128, 128, 8705, 8705, 8705, 8705, 
+    128, 8705, 8705, 8705, 8705, 8705, 8705, 8705, 8705, 8834, 
+    8834, 8834, 8834, 128, 8834, 128, 8834, 8834, 8834, 8834, 
+    8705, 8705, 128, 8705, 8705, 8705, 8705, 128, 128, 8705, 
+    8705, 8705, 8705, 8705, 8705, 8705, 8705, 128, 8705, 8705, 
+    8705, 8705, 8705, 8705, 8705, 128, 8834, 8834, 8834, 8834, 
+    8834, 8834, 8834, 8834, 8834, 8834, 8834, 8834, 8834, 8834, 
+    8834, 8834, 8834, 8834, 8834, 8834, 8834, 8834, 8834, 8834, 
+    8834, 8834, 8705, 8705, 128, 8705, 8705, 8705, 8705, 128, 
+    8834, 8834, 8834, 8985, 8834, 8834, 8834, 8834, 8834, 8834, 
+    128, 128, 128, 128, 9097, 9225, 9353, 9481, 9609, 9737, 
+    9865, 9993, 10121, 10249, 9097, 9225, 9353, 9481, 9609, 9737, 
+    9865, 9993, 10121, 10249, 9097, 9225, 9353, 9481, 9609, 9737, 
+    9865, 9993, 10121, 10249, 9097, 9225, 9353, 9481, 9609, 9737, 
+    9865, 9993, 10121, 10249, 9097, 9225, 9353, 9481, 9609, 9737, 
+    9865, 9993, 10121, 10249, 
+};
+
+static const jchar data2[] = {
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
+    5, 5, 5, 5, 5, 5, 5, 5, 128, 128, 
+    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 
+    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 
+    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 
+    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 
+    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 
+    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 
+    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 
+    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 
+    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 
+    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 
+    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 
+    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 
+    128, 128, 128, 128, 128, 128, 
+};
+
+static const jchar data14[] = {
+    262, 262, 262, 262, 262, 262, 262, 262, 262, 262, 
+    262, 262, 262, 262, 262, 262, 262, 262, 262, 262, 
+    262, 262, 262, 262, 262, 262, 262, 262, 262, 262, 
+    262, 262, 262, 262, 262, 262, 262, 262, 262, 262, 
+    262, 262, 262, 262, 262, 262, 262, 262, 262, 262, 
+    262, 262, 262, 262, 262, 262, 262, 262, 262, 262, 
+    262, 262, 262, 262, 262, 262, 262, 262, 262, 262, 
+    262, 262, 262, 262, 262, 262, 262, 262, 262, 262, 
+    262, 262, 262, 262, 262, 262, 262, 262, 262, 262, 
+    262, 262, 262, 262, 262, 262, 262, 262, 262, 262, 
+    262, 262, 262, 262, 262, 262, 262, 262, 262, 262, 
+    262, 262, 262, 262, 262, 262, 262, 262, 262, 262, 
+    262, 262, 262, 262, 262, 262, 262, 262, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 144, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 144, 144, 144, 
+    144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 
+    144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 
+    144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 
+    144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 
+    144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 
+    144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 
+    144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 
+    144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 
+    144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 
+    144, 144, 144, 
+};
+
+static const int data_length[] = {
+    3960, 1504, 256, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 383, -1, -1, };
+static const jchar* data[] = {
+    data0, data1, data2, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
+    NULL, NULL, NULL, NULL, data14, NULL, NULL};
+
+
 /**
  * This is the attribute table for computing the numeric value of a
  * character.  The value is -1 if Unicode does not define a value, -2
  * if the value is not a positive integer, otherwise it is the value.
  */
-static const jshort numValue[] = {
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-    -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1,
-    10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
-    23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
-    -1, -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
-    21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
-    34, 35, -1, -1, -1, -1, -1, -1, 2, 3, -1, 1, -1,
-    -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-    -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1,
-    -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1,
-    2, 3, 4, -1, 16, 10, 100, 1000, -1, -1, -1, 20, 30,
-    40, 50, 60, 70, 80, 90, 10000, 17, 18, 19, -1, -1, -1,
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-    -1, -1, -1, -1, -1, -1, -1, 0, 4, 5, 6, 7, 8,
-    9, -1, -1, -1, 1, 1, 2, 3, 4, 5, 6, 7, 8,
-    9, 10, 11, 12, 50, 100, 500, 1000, 1, 2, 3, 4, 5,
-    6, 7, 8, 9, 10, 11, 12, 50, 100, 500, 1000, 1000, 5000,
-    10000, -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
-    -1, -1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 1,
-    2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30, 5, 6,
-    7, 8, 9, -1, -1,
-  };
-/** Length of numValue. */
-static const int numValue_length = 343;
+static const jshort numValue0[] = {
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
+    -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, 
+    10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 
+    23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 
+    -1, -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 
+    21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 
+    34, 35, -1, -1, -1, -1, -1, -1, 2, 3, -1, 1, -1, 
+    -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 
+    3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, 0, 1, 
+    2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, -1, 
+    16, 10, 100, 1000, -1, -1, -2, -1, -1, 20, 30, 40, 50, 
+    60, 70, 80, 90, 10000, 17, 18, 19, -1, 0, 1, 2, 3, 
+    4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, -1, 
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
+    -1, 0, 4, 5, 6, 7, 8, 9, -1, -1, -1, 1, 2, 
+    3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 50, 100, 500, 
+    1000, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 
+    50, 100, 500, 1000, 1000, 5000, 10000, -1, 10, 11, 12, 13, 14, 
+    15, 16, 17, 18, 19, 20, -1, -1, 11, 12, 13, 14, 15, 
+    16, 17, 18, 19, 20, 10, 0, 1, 2, 3, 4, 5, 6, 
+    7, 8, 9, 10, 20, 30, 5, 6, 7, 8, 9, 21, 22, 
+    23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 
+    36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 
+    49, 50, -1, -1, -1, 
+};
 
+static const jshort numValue1[] = {
+    -1, -1, -1, -1, -1, 1, 2, 3, 4, 5, 6, 7, 8, 
+    9, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 200, 300, 
+    400, 500, 600, 700, 800, 900, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 
+    8000, 9000, 10000, 20000, 30000, -3, -4, -5, -6, -7, -8, -1, -1, 
+    -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, 
+    -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 
+    7, 8, 9, 
+};
+
+static const jshort numValue2[] = {
+    -1, -1, 
+};
+
+static const jshort numValue14[] = {
+    -1, -1, -1, 
+};
+
+static const int numValue_length[] = {
+    395, 81, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3, -1, -1, };
+static const jshort* numValue[] = {
+    numValue0, numValue1, numValue2, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
+    NULL, NULL, NULL, NULL, numValue14, NULL, NULL};
+
+
+
 /**
  * This is the attribute table for computing the uppercase representation
  * of a character.  The value is the difference between the character and
  * its uppercase version.
  */
-static const jshort upper[] = {
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32,
-    -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32,
-    -32, -32, 0, 0, 0, 0, 0, 0, 0, 0, 743, 0, 0,
-    0, 0, 0, -32, 121, 0, -1, 0, -232, 0, -300, 0, 0,
-    0, 0, 0, 0, 0, 97, 0, 0, 0, 0, 0, 0, 0,
-    0, 56, 0, -1, -2, -79, 0, 0, 0, -210, -206, -205, -202,
-    -203, -207, -209, -211, -213, -214, -218, -217, -219, 0, 0, 84, 0,
-    0, 0, 0, 0, -38, -37, -31, -64, -63, -62, -57, 0, -47,
-    -54, -86, -80, 0, 0, 0, 0, 0, -48, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -59, 8, 0,
-    74, 86, 100, 128, 112, 126, 8, 0, 9, 0, 0, -7205, 0,
-    0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, -16, -16, -16, -16, -16,
-    -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, -26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0,
-  };
-/** Length of upper. */
-static const int upper_length = 343;
+static const jshort upper0[] = {
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, 
+    -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, 
+    -32, -32, 0, 0, 0, 0, 0, 0, 0, 0, 743, 0, 0, 
+    0, 0, 0, -32, 121, 0, -1, 0, -232, 0, -300, 0, 0, 
+    0, 0, 0, 0, 0, 97, 0, 0, 0, 130, 0, 0, 0, 
+    0, 0, 56, 0, -1, -2, -79, 0, 0, 0, 0, -210, -206, 
+    -205, -202, -203, -207, -209, -211, -213, -214, -218, -217, -219, 0, 0, 
+    0, 84, 0, 0, 0, 0, 0, -38, -37, -31, -64, -63, -62, 
+    -57, 0, -47, -54, -86, -80, 7, 0, -96, 0, 0, 0, 0, 
+    0, 0, -48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, -59, 8, 0, 74, 86, 100, 
+    128, 112, 126, 8, 0, 9, 0, 0, -7205, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, 
+    -16, -16, -16, -16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, -26, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 
+};
 
+static const jshort upper1[] = {
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    -40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 
+};
+
+static const jshort upper2[] = {
+    0, 0, 
+};
+
+static const jshort upper14[] = {
+    0, 0, 0, 
+};
+
+static const int upper_length[] = {
+    395, 81, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3, -1, -1, };
+static const jshort* upper[] = {
+    upper0, upper1, upper2, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
+    NULL, NULL, NULL, NULL, upper14, NULL, NULL};
+
+
 /**
  * This is the attribute table for computing the lowercase representation
  * of a character.  The value is the difference between the character and
  * its lowercase version.
  */
-static const jshort lower[] = {
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 32, 0, 0, 0, 1, 0, -199, 0, -121, 0, 210, 206,
-    205, 79, 202, 203, 207, 0, 211, 209, 213, 214, 218, 217, 219,
-    0, 0, 2, 1, 0, 0, -97, -56, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38,
-    37, 64, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 80, 0, 0, 48, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -8,
-    0, 0, 0, 0, 0, 0, 0, -8, 0, -74, -9, 0, -86,
-    -100, 0, -112, -7, -128, -126, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, -7517, -8383, -8262, 0, 16, 16, 16, 16, 16, 16, 16, 16,
-    16, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0,
-  };
-/** Length of lower. */
-static const int lower_length = 343;
+static const jshort lower0[] = {
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 32, 0, 0, 0, 1, 0, -199, 0, -121, 0, 210, 206, 
+    205, 79, 202, 203, 207, 0, 211, 209, 213, 0, 214, 218, 217, 
+    219, 0, 0, 2, 1, 0, 0, -97, -56, -130, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 38, 37, 64, 63, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, -60, 0, -7, 80, 0, 0, 
+    48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, -8, 0, 0, 0, 
+    0, 0, 0, 0, -8, 0, -74, -9, 0, -86, -100, -112, -128, 
+    -126, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, -7517, -8383, -8262, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 
+};
 
+static const jshort lower1[] = {
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 
+};
+
+static const jshort lower2[] = {
+    0, 0, 
+};
+
+static const jshort lower14[] = {
+    0, 0, 0, 
+};
+
+static const int lower_length[] = {
+    395, 81, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3, -1, -1, };
+static const jshort* lower[] = {
+    lower0, lower1, lower2, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
+    NULL, NULL, NULL, NULL, lower14, NULL, NULL};
+
+
 /**
  * This is the attribute table for computing the directionality class
  * of a character.  At present, the value is in the range 0 - 18 if the
  * character has a direction, otherwise it is -1.
  */
-static const jbyte direction[] = {
-    36, 44, 40, 48, 48, 52, 20, 20, 52, 52, 20, 28, 20, 16, 12, 12, 12, 12, 12, 12, 12,
-    12, 12, 12, 52, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 52, 0, 52,
-    52, 20, 12, 12, 0, 12, 52, 52, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -4,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 32, 0, 0, 0, 0, 2,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 4, 4, 8,
-    8, 8, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 8, 36, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 52, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0,
-    1, 0, 0, 0, 0, 0, 0, 0, 0, 48, 36, 0, 4, 52, 52, 52, 48, 40, 56, 64, 72,
-    60, 68, 12, 12, 12, 12, 12, 12, 12, 0, 0, 0, 52, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 0, 0, 52,
-    52, 52, 52, 52, 52, 52, 52, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0,
-  };
-/** Length of direction. */
-static const int direction_length = 343;
+static const jbyte direction0[] = {
+    9, 11, 10, 12, 12, 13, 5, 5, 13, 13, 5, 7, 5, 4, 3, 3, 3, 3, 3, 
+    3, 3, 3, 3, 3, 13, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 13, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 7, 13, 0, 13, 13, 5, 3, 3, 0, 3, 13, 13, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 8, 8, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 
+    0, 13, 1, 1, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
+    2, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 13, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 8, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 9, 1, 13, 13, 
+    13, 12, 10, 14, 16, 18, 15, 17, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 
+    3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 13, 13, 13, 13, 13, 13, 13, 13, 13, 
+    13, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 
+    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 0, 0, 2, 
+};
 
+static const jbyte direction1[] = {
+    0, -1, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 1, 0, 8, 9, 13, 0, 0, 0, 3, 3, 3, 3, 3, 
+    3, 3, 3, 3, 3, 
+};
+
+static const jbyte direction2[] = {
+    0, -1, 
+};
+
+static const jbyte direction14[] = {
+    -1, 9, 8, 
+};
+
+static const int direction_length[] = {
+    395, 81, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3, -1, -1, };
+static const jbyte* direction[] = {
+    direction0, direction1, direction2, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
+    NULL, NULL, NULL, NULL, direction14, NULL, NULL};
+
+
 /**
  * This is the listing of titlecase special cases (all other character
  * can use <code>upper</code> to determine their titlecase).  The listing
@@ -977,9 +1607,9 @@
  * pair to titlecase produces the second character.
  */
 static const jchar title[] = {
-    452, 453, 453, 453, 454, 453, 455, 456, 456, 456,
-    457, 456, 458, 459, 459, 459, 460, 459, 497, 498,
-    498, 498, 499, 498,
+    452, 453, 453, 453, 454, 453, 455, 456, 456, 456, 
+    457, 456, 458, 459, 459, 459, 460, 459, 497, 498, 
+    498, 498, 499, 498, 
   };
 /** Length of title. */
 static const int title_length = 24;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]