From 376c450a3e0fa883d7670a3a248ed7d213b93296 Mon Sep 17 00:00:00 2001
From: John Naylor <john.naylor@2ndquadrant.com>
Date: Wed, 21 Oct 2020 18:27:09 -0400
Subject: [PATCH v3 2/2] Speed up unicode recomposition.

As with decomposition, use a perfect hash function for speed.
The performance increase is much higher in this casebecause the
former implementation used linear search. This makes normalizing
to NFC and NFKC more than 40x faster in the backend, while adding
only 6kB to the binary. While this is small, keep out of the frontend
since its use is not performance critical.
---
 .../unicode/generate-unicode_norm_table.pl    |  113 ++
 src/common/unicode_norm.c                     |   37 +-
 src/include/common/unicode_norm_hashfunc.h    | 1220 +++++++++++++++++
 3 files changed, 1368 insertions(+), 2 deletions(-)

diff --git a/src/common/unicode/generate-unicode_norm_table.pl b/src/common/unicode/generate-unicode_norm_table.pl
index 5fca88796f..6bbe81f17d 100644
--- a/src/common/unicode/generate-unicode_norm_table.pl
+++ b/src/common/unicode/generate-unicode_norm_table.pl
@@ -144,6 +144,7 @@ print $OF <<HEADER;
 typedef int (*cp_hash_func) (const void *key);
 
 /* Information for lookups with perfect hash functions */
+
 typedef struct
 {
 	const pg_unicode_decomposition *decomps;
@@ -151,11 +152,20 @@ typedef struct
 	int		num_decomps;
 } pg_unicode_decompinfo;
 
+typedef struct
+{
+	const uint16	*inverse_lookup;
+	cp_hash_func	hash;
+	int		num_recomps;
+} pg_unicode_recompinfo;
+
 HEADER
 
 my $decomp_index  = 0;
 my $decomp_string = "";
 my @dec_cp_packed;
+my $main_index = 0;
+my @rec_info;
 
 my $last_code = $characters[-1]->{code};
 foreach my $char (@characters)
@@ -217,6 +227,18 @@ foreach my $char (@characters)
 				}
 			}
 		}
+
+		# Save info for recomposeable codepoints.
+		# XXX This must match the DECOMPOSITION_NO_COMPOSE C macro above!
+		# See the inverse lookup in recompose_code() found in
+		# common/unicode_norm.c.
+		if (!($flags =~ /DECOMP_COMPAT/ || $flags =~ /DECOMP_NO_COMPOSE/))
+		{
+			push @rec_info, {code => $code,
+							 main_index => $main_index,
+							 first => $first_decomp,
+							 second => $decomp_elts[0]};
+		}
 	}
 
 	if ($decomp_size == 0)
@@ -255,6 +277,8 @@ foreach my $char (@characters)
 
 	print $OT "\t/* $comment */" if ($comment ne "");
 	print $OT "\n";
+
+	$main_index++;
 }
 print $OT "\n};\n\n";
 
@@ -284,7 +308,96 @@ static const pg_unicode_decompinfo UnicodeDecompInfo =
 	$dec_funcname,
 	$num_characters
 };
+
+HEADER
+
+# Find the lowest codepoint that decomposes to each recomposeable
+# code pair and create a mapping to it.
+my $recomp_string = "";
+my @rec_cp_packed;
+my %seenit;
+my $firstentry = 1;
+foreach my $rec (sort recomp_sort @rec_info)
+{
+	# The hash key is formed by concatenating the bytes of the two
+	# codepoints. See also recompose_code() in common/unicode_norm.c.
+	my $hashkey = (hex($rec->{first}) << 32) | hex($rec->{second});
+
+	# We are only interested in the lowest code point that decomposes
+	# to the given code pair.
+	next if $seenit{$hashkey};
+
+	# Save the hash key bytes in network order
+	push @rec_cp_packed, pack('Q>', $hashkey);
+
+	# Append inverse lookup element
+	$recomp_string .= ",\n" if ! $firstentry;
+	$recomp_string .= sprintf "\t/* U+%s+%s -> U+%s */ %s",
+		$rec->{first},
+		$rec->{second},
+		$rec->{code},
+		$rec->{main_index};
+
+	$seenit{$hashkey} = 1;
+	$firstentry = 0;
+}
+
+# Emit the inverse lookup array containing indexes into UnicodeDecompMain
+my $num_recomps = scalar @rec_cp_packed;
+print $OF <<HEADER;
+/* Inverse lookup array -- contains indexes into UnicodeDecompMain[] */
+static const uint16 RecompInverseLookup[$num_recomps] =
+{
+$recomp_string
+};
+
+HEADER
+
+# Emit the definition of the recomp hash function.
+my $rec_funcname = 'Recomp_hash_func';
+my $rec_func        = PerfectHash::generate_hash_function(\@rec_cp_packed, $rec_funcname,
+	fixed_key_length => 8);
+print $OF "/* Perfect hash function for recomposition */\n";
+print $OF "static $rec_func\n";
+
+# Emit the structure that wraps the hash lookup information into
+# one variable.
+print $OF <<HEADER;
+/* Hash lookup information for recomposition */
+static const pg_unicode_recompinfo UnicodeRecompInfo =
+{
+	RecompInverseLookup,
+	$rec_funcname,
+	$num_recomps
+};
 HEADER
 
 close $OT;
 close $OF;
+
+sub recomp_sort
+{
+	my $a1 = hex($a->{first});
+	my $b1 = hex($b->{first});
+
+	my $a2 = hex($a->{second});
+	my $b2 = hex($b->{second});
+
+	# First sort by first code point
+	return -1 if $a1 < $b1;
+	return 1 if $a1 > $b1;
+
+	# Then the second code point
+	return -1 if $a2 < $b2;
+	return 1 if $a2 > $b2;
+
+	# Finally by the code point that decomposes into first and second.
+
+	my $acode = hex($a->{code});
+	my $bcode = hex($b->{code});
+
+	return -1 if $acode < $bcode;
+	return -1 if $acode > $bcode;
+
+	die "found duplicate entries of recomposeable code pairs";
+}
diff --git a/src/common/unicode_norm.c b/src/common/unicode_norm.c
index 7d0d23ab21..da7e6f8fa1 100644
--- a/src/common/unicode_norm.c
+++ b/src/common/unicode_norm.c
@@ -228,7 +228,7 @@ recompose_code(uint32 start, uint32 code, uint32 *result)
 	}
 	else
 	{
-		int			i;
+		const pg_unicode_decomposition *entry;
 
 		/*
 		 * Do an inverse lookup of the decomposition tables to see if anything
@@ -236,9 +236,41 @@ recompose_code(uint32 start, uint32 code, uint32 *result)
 		 * sub-table of size two, because the start character has already been
 		 * recomposed partially.
 		 */
+#ifndef FRONTEND
+
+		int			h, inv_lookup_index;
+		uint64		hashkey;
+		pg_unicode_recompinfo recompinfo = UnicodeRecompInfo;
+
+		/*
+		 * Compute the hash function. The hash key is formed by concatenating
+		 * bytes of the two codepoints in network order. See also
+		 * common/unicode/generate-unicode_norm_table.pl.
+		 */
+		hashkey = pg_hton64(((uint64) start << 32) | (uint64) code);
+		h = recompinfo.hash(&hashkey);
+
+		/* An out-of-range result implies no match */
+		if (h < 0 || h >= recompinfo.num_recomps)
+			return false;
+
+		inv_lookup_index = recompinfo.inverse_lookup[h];
+		entry = &UnicodeDecompMain[inv_lookup_index];
+
+		if (start == UnicodeDecomp_codepoints[entry->dec_index] &&
+			code == UnicodeDecomp_codepoints[entry->dec_index + 1])
+		{
+			*result = entry->codepoint;
+			return true;
+		}
+
+#else
+
+		int			i;
+
 		for (i = 0; i < lengthof(UnicodeDecompMain); i++)
 		{
-			const pg_unicode_decomposition *entry = &UnicodeDecompMain[i];
+			entry = &UnicodeDecompMain[i];
 
 			if (DECOMPOSITION_SIZE(entry) != 2)
 				continue;
@@ -253,6 +285,7 @@ recompose_code(uint32 start, uint32 code, uint32 *result)
 				return true;
 			}
 		}
+#endif							/* !FRONTEND */
 	}
 
 	return false;
diff --git a/src/include/common/unicode_norm_hashfunc.h b/src/include/common/unicode_norm_hashfunc.h
index d2f4ad884b..39b7138f2b 100644
--- a/src/include/common/unicode_norm_hashfunc.h
+++ b/src/include/common/unicode_norm_hashfunc.h
@@ -23,6 +23,7 @@
 typedef int (*cp_hash_func) (const void *key);
 
 /* Information for lookups with perfect hash functions */
+
 typedef struct
 {
 	const pg_unicode_decomposition *decomps;
@@ -30,6 +31,13 @@ typedef struct
 	int		num_decomps;
 } pg_unicode_decompinfo;
 
+typedef struct
+{
+	const uint16	*inverse_lookup;
+	cp_hash_func	hash;
+	int		num_recomps;
+} pg_unicode_recompinfo;
+
 /* Perfect hash function for decomposition */
 static int
 Decomp_hash_func(const void *key)
@@ -1711,3 +1719,1215 @@ static const pg_unicode_decompinfo UnicodeDecompInfo =
 	Decomp_hash_func,
 	6604
 };
+
+/* Inverse lookup array -- contains indexes into UnicodeDecompMain[] */
+static const uint16 RecompInverseLookup[941] =
+{
+	/* U+003C+0338 -> U+226E */ 1823,
+	/* U+003D+0338 -> U+2260 */ 1820,
+	/* U+003E+0338 -> U+226F */ 1824,
+	/* U+0041+0300 -> U+00C0 */ 14,
+	/* U+0041+0301 -> U+00C1 */ 15,
+	/* U+0041+0302 -> U+00C2 */ 16,
+	/* U+0041+0303 -> U+00C3 */ 17,
+	/* U+0041+0304 -> U+0100 */ 67,
+	/* U+0041+0306 -> U+0102 */ 69,
+	/* U+0041+0307 -> U+0226 */ 270,
+	/* U+0041+0308 -> U+00C4 */ 18,
+	/* U+0041+0309 -> U+1EA2 */ 1278,
+	/* U+0041+030A -> U+00C5 */ 19,
+	/* U+0041+030C -> U+01CD */ 194,
+	/* U+0041+030F -> U+0200 */ 240,
+	/* U+0041+0311 -> U+0202 */ 242,
+	/* U+0041+0323 -> U+1EA0 */ 1276,
+	/* U+0041+0325 -> U+1E00 */ 1120,
+	/* U+0041+0328 -> U+0104 */ 71,
+	/* U+0042+0307 -> U+1E02 */ 1122,
+	/* U+0042+0323 -> U+1E04 */ 1124,
+	/* U+0042+0331 -> U+1E06 */ 1126,
+	/* U+0043+0301 -> U+0106 */ 73,
+	/* U+0043+0302 -> U+0108 */ 75,
+	/* U+0043+0307 -> U+010A */ 77,
+	/* U+0043+030C -> U+010C */ 79,
+	/* U+0043+0327 -> U+00C7 */ 20,
+	/* U+0044+0307 -> U+1E0A */ 1130,
+	/* U+0044+030C -> U+010E */ 81,
+	/* U+0044+0323 -> U+1E0C */ 1132,
+	/* U+0044+0327 -> U+1E10 */ 1136,
+	/* U+0044+032D -> U+1E12 */ 1138,
+	/* U+0044+0331 -> U+1E0E */ 1134,
+	/* U+0045+0300 -> U+00C8 */ 21,
+	/* U+0045+0301 -> U+00C9 */ 22,
+	/* U+0045+0302 -> U+00CA */ 23,
+	/* U+0045+0303 -> U+1EBC */ 1304,
+	/* U+0045+0304 -> U+0112 */ 83,
+	/* U+0045+0306 -> U+0114 */ 85,
+	/* U+0045+0307 -> U+0116 */ 87,
+	/* U+0045+0308 -> U+00CB */ 24,
+	/* U+0045+0309 -> U+1EBA */ 1302,
+	/* U+0045+030C -> U+011A */ 91,
+	/* U+0045+030F -> U+0204 */ 244,
+	/* U+0045+0311 -> U+0206 */ 246,
+	/* U+0045+0323 -> U+1EB8 */ 1300,
+	/* U+0045+0327 -> U+0228 */ 272,
+	/* U+0045+0328 -> U+0118 */ 89,
+	/* U+0045+032D -> U+1E18 */ 1144,
+	/* U+0045+0330 -> U+1E1A */ 1146,
+	/* U+0046+0307 -> U+1E1E */ 1150,
+	/* U+0047+0301 -> U+01F4 */ 230,
+	/* U+0047+0302 -> U+011C */ 93,
+	/* U+0047+0304 -> U+1E20 */ 1152,
+	/* U+0047+0306 -> U+011E */ 95,
+	/* U+0047+0307 -> U+0120 */ 97,
+	/* U+0047+030C -> U+01E6 */ 216,
+	/* U+0047+0327 -> U+0122 */ 99,
+	/* U+0048+0302 -> U+0124 */ 101,
+	/* U+0048+0307 -> U+1E22 */ 1154,
+	/* U+0048+0308 -> U+1E26 */ 1158,
+	/* U+0048+030C -> U+021E */ 268,
+	/* U+0048+0323 -> U+1E24 */ 1156,
+	/* U+0048+0327 -> U+1E28 */ 1160,
+	/* U+0048+032E -> U+1E2A */ 1162,
+	/* U+0049+0300 -> U+00CC */ 25,
+	/* U+0049+0301 -> U+00CD */ 26,
+	/* U+0049+0302 -> U+00CE */ 27,
+	/* U+0049+0303 -> U+0128 */ 103,
+	/* U+0049+0304 -> U+012A */ 105,
+	/* U+0049+0306 -> U+012C */ 107,
+	/* U+0049+0307 -> U+0130 */ 111,
+	/* U+0049+0308 -> U+00CF */ 28,
+	/* U+0049+0309 -> U+1EC8 */ 1316,
+	/* U+0049+030C -> U+01CF */ 196,
+	/* U+0049+030F -> U+0208 */ 248,
+	/* U+0049+0311 -> U+020A */ 250,
+	/* U+0049+0323 -> U+1ECA */ 1318,
+	/* U+0049+0328 -> U+012E */ 109,
+	/* U+0049+0330 -> U+1E2C */ 1164,
+	/* U+004A+0302 -> U+0134 */ 114,
+	/* U+004B+0301 -> U+1E30 */ 1168,
+	/* U+004B+030C -> U+01E8 */ 218,
+	/* U+004B+0323 -> U+1E32 */ 1170,
+	/* U+004B+0327 -> U+0136 */ 116,
+	/* U+004B+0331 -> U+1E34 */ 1172,
+	/* U+004C+0301 -> U+0139 */ 118,
+	/* U+004C+030C -> U+013D */ 122,
+	/* U+004C+0323 -> U+1E36 */ 1174,
+	/* U+004C+0327 -> U+013B */ 120,
+	/* U+004C+032D -> U+1E3C */ 1180,
+	/* U+004C+0331 -> U+1E3A */ 1178,
+	/* U+004D+0301 -> U+1E3E */ 1182,
+	/* U+004D+0307 -> U+1E40 */ 1184,
+	/* U+004D+0323 -> U+1E42 */ 1186,
+	/* U+004E+0300 -> U+01F8 */ 232,
+	/* U+004E+0301 -> U+0143 */ 126,
+	/* U+004E+0303 -> U+00D1 */ 29,
+	/* U+004E+0307 -> U+1E44 */ 1188,
+	/* U+004E+030C -> U+0147 */ 130,
+	/* U+004E+0323 -> U+1E46 */ 1190,
+	/* U+004E+0327 -> U+0145 */ 128,
+	/* U+004E+032D -> U+1E4A */ 1194,
+	/* U+004E+0331 -> U+1E48 */ 1192,
+	/* U+004F+0300 -> U+00D2 */ 30,
+	/* U+004F+0301 -> U+00D3 */ 31,
+	/* U+004F+0302 -> U+00D4 */ 32,
+	/* U+004F+0303 -> U+00D5 */ 33,
+	/* U+004F+0304 -> U+014C */ 133,
+	/* U+004F+0306 -> U+014E */ 135,
+	/* U+004F+0307 -> U+022E */ 278,
+	/* U+004F+0308 -> U+00D6 */ 34,
+	/* U+004F+0309 -> U+1ECE */ 1322,
+	/* U+004F+030B -> U+0150 */ 137,
+	/* U+004F+030C -> U+01D1 */ 198,
+	/* U+004F+030F -> U+020C */ 252,
+	/* U+004F+0311 -> U+020E */ 254,
+	/* U+004F+031B -> U+01A0 */ 181,
+	/* U+004F+0323 -> U+1ECC */ 1320,
+	/* U+004F+0328 -> U+01EA */ 220,
+	/* U+0050+0301 -> U+1E54 */ 1204,
+	/* U+0050+0307 -> U+1E56 */ 1206,
+	/* U+0052+0301 -> U+0154 */ 139,
+	/* U+0052+0307 -> U+1E58 */ 1208,
+	/* U+0052+030C -> U+0158 */ 143,
+	/* U+0052+030F -> U+0210 */ 256,
+	/* U+0052+0311 -> U+0212 */ 258,
+	/* U+0052+0323 -> U+1E5A */ 1210,
+	/* U+0052+0327 -> U+0156 */ 141,
+	/* U+0052+0331 -> U+1E5E */ 1214,
+	/* U+0053+0301 -> U+015A */ 145,
+	/* U+0053+0302 -> U+015C */ 147,
+	/* U+0053+0307 -> U+1E60 */ 1216,
+	/* U+0053+030C -> U+0160 */ 151,
+	/* U+0053+0323 -> U+1E62 */ 1218,
+	/* U+0053+0326 -> U+0218 */ 264,
+	/* U+0053+0327 -> U+015E */ 149,
+	/* U+0054+0307 -> U+1E6A */ 1226,
+	/* U+0054+030C -> U+0164 */ 155,
+	/* U+0054+0323 -> U+1E6C */ 1228,
+	/* U+0054+0326 -> U+021A */ 266,
+	/* U+0054+0327 -> U+0162 */ 153,
+	/* U+0054+032D -> U+1E70 */ 1232,
+	/* U+0054+0331 -> U+1E6E */ 1230,
+	/* U+0055+0300 -> U+00D9 */ 35,
+	/* U+0055+0301 -> U+00DA */ 36,
+	/* U+0055+0302 -> U+00DB */ 37,
+	/* U+0055+0303 -> U+0168 */ 157,
+	/* U+0055+0304 -> U+016A */ 159,
+	/* U+0055+0306 -> U+016C */ 161,
+	/* U+0055+0308 -> U+00DC */ 38,
+	/* U+0055+0309 -> U+1EE6 */ 1346,
+	/* U+0055+030A -> U+016E */ 163,
+	/* U+0055+030B -> U+0170 */ 165,
+	/* U+0055+030C -> U+01D3 */ 200,
+	/* U+0055+030F -> U+0214 */ 260,
+	/* U+0055+0311 -> U+0216 */ 262,
+	/* U+0055+031B -> U+01AF */ 183,
+	/* U+0055+0323 -> U+1EE4 */ 1344,
+	/* U+0055+0324 -> U+1E72 */ 1234,
+	/* U+0055+0328 -> U+0172 */ 167,
+	/* U+0055+032D -> U+1E76 */ 1238,
+	/* U+0055+0330 -> U+1E74 */ 1236,
+	/* U+0056+0303 -> U+1E7C */ 1244,
+	/* U+0056+0323 -> U+1E7E */ 1246,
+	/* U+0057+0300 -> U+1E80 */ 1248,
+	/* U+0057+0301 -> U+1E82 */ 1250,
+	/* U+0057+0302 -> U+0174 */ 169,
+	/* U+0057+0307 -> U+1E86 */ 1254,
+	/* U+0057+0308 -> U+1E84 */ 1252,
+	/* U+0057+0323 -> U+1E88 */ 1256,
+	/* U+0058+0307 -> U+1E8A */ 1258,
+	/* U+0058+0308 -> U+1E8C */ 1260,
+	/* U+0059+0300 -> U+1EF2 */ 1358,
+	/* U+0059+0301 -> U+00DD */ 39,
+	/* U+0059+0302 -> U+0176 */ 171,
+	/* U+0059+0303 -> U+1EF8 */ 1364,
+	/* U+0059+0304 -> U+0232 */ 282,
+	/* U+0059+0307 -> U+1E8E */ 1262,
+	/* U+0059+0308 -> U+0178 */ 173,
+	/* U+0059+0309 -> U+1EF6 */ 1362,
+	/* U+0059+0323 -> U+1EF4 */ 1360,
+	/* U+005A+0301 -> U+0179 */ 174,
+	/* U+005A+0302 -> U+1E90 */ 1264,
+	/* U+005A+0307 -> U+017B */ 176,
+	/* U+005A+030C -> U+017D */ 178,
+	/* U+005A+0323 -> U+1E92 */ 1266,
+	/* U+005A+0331 -> U+1E94 */ 1268,
+	/* U+0061+0300 -> U+00E0 */ 40,
+	/* U+0061+0301 -> U+00E1 */ 41,
+	/* U+0061+0302 -> U+00E2 */ 42,
+	/* U+0061+0303 -> U+00E3 */ 43,
+	/* U+0061+0304 -> U+0101 */ 68,
+	/* U+0061+0306 -> U+0103 */ 70,
+	/* U+0061+0307 -> U+0227 */ 271,
+	/* U+0061+0308 -> U+00E4 */ 44,
+	/* U+0061+0309 -> U+1EA3 */ 1279,
+	/* U+0061+030A -> U+00E5 */ 45,
+	/* U+0061+030C -> U+01CE */ 195,
+	/* U+0061+030F -> U+0201 */ 241,
+	/* U+0061+0311 -> U+0203 */ 243,
+	/* U+0061+0323 -> U+1EA1 */ 1277,
+	/* U+0061+0325 -> U+1E01 */ 1121,
+	/* U+0061+0328 -> U+0105 */ 72,
+	/* U+0062+0307 -> U+1E03 */ 1123,
+	/* U+0062+0323 -> U+1E05 */ 1125,
+	/* U+0062+0331 -> U+1E07 */ 1127,
+	/* U+0063+0301 -> U+0107 */ 74,
+	/* U+0063+0302 -> U+0109 */ 76,
+	/* U+0063+0307 -> U+010B */ 78,
+	/* U+0063+030C -> U+010D */ 80,
+	/* U+0063+0327 -> U+00E7 */ 46,
+	/* U+0064+0307 -> U+1E0B */ 1131,
+	/* U+0064+030C -> U+010F */ 82,
+	/* U+0064+0323 -> U+1E0D */ 1133,
+	/* U+0064+0327 -> U+1E11 */ 1137,
+	/* U+0064+032D -> U+1E13 */ 1139,
+	/* U+0064+0331 -> U+1E0F */ 1135,
+	/* U+0065+0300 -> U+00E8 */ 47,
+	/* U+0065+0301 -> U+00E9 */ 48,
+	/* U+0065+0302 -> U+00EA */ 49,
+	/* U+0065+0303 -> U+1EBD */ 1305,
+	/* U+0065+0304 -> U+0113 */ 84,
+	/* U+0065+0306 -> U+0115 */ 86,
+	/* U+0065+0307 -> U+0117 */ 88,
+	/* U+0065+0308 -> U+00EB */ 50,
+	/* U+0065+0309 -> U+1EBB */ 1303,
+	/* U+0065+030C -> U+011B */ 92,
+	/* U+0065+030F -> U+0205 */ 245,
+	/* U+0065+0311 -> U+0207 */ 247,
+	/* U+0065+0323 -> U+1EB9 */ 1301,
+	/* U+0065+0327 -> U+0229 */ 273,
+	/* U+0065+0328 -> U+0119 */ 90,
+	/* U+0065+032D -> U+1E19 */ 1145,
+	/* U+0065+0330 -> U+1E1B */ 1147,
+	/* U+0066+0307 -> U+1E1F */ 1151,
+	/* U+0067+0301 -> U+01F5 */ 231,
+	/* U+0067+0302 -> U+011D */ 94,
+	/* U+0067+0304 -> U+1E21 */ 1153,
+	/* U+0067+0306 -> U+011F */ 96,
+	/* U+0067+0307 -> U+0121 */ 98,
+	/* U+0067+030C -> U+01E7 */ 217,
+	/* U+0067+0327 -> U+0123 */ 100,
+	/* U+0068+0302 -> U+0125 */ 102,
+	/* U+0068+0307 -> U+1E23 */ 1155,
+	/* U+0068+0308 -> U+1E27 */ 1159,
+	/* U+0068+030C -> U+021F */ 269,
+	/* U+0068+0323 -> U+1E25 */ 1157,
+	/* U+0068+0327 -> U+1E29 */ 1161,
+	/* U+0068+032E -> U+1E2B */ 1163,
+	/* U+0068+0331 -> U+1E96 */ 1270,
+	/* U+0069+0300 -> U+00EC */ 51,
+	/* U+0069+0301 -> U+00ED */ 52,
+	/* U+0069+0302 -> U+00EE */ 53,
+	/* U+0069+0303 -> U+0129 */ 104,
+	/* U+0069+0304 -> U+012B */ 106,
+	/* U+0069+0306 -> U+012D */ 108,
+	/* U+0069+0308 -> U+00EF */ 54,
+	/* U+0069+0309 -> U+1EC9 */ 1317,
+	/* U+0069+030C -> U+01D0 */ 197,
+	/* U+0069+030F -> U+0209 */ 249,
+	/* U+0069+0311 -> U+020B */ 251,
+	/* U+0069+0323 -> U+1ECB */ 1319,
+	/* U+0069+0328 -> U+012F */ 110,
+	/* U+0069+0330 -> U+1E2D */ 1165,
+	/* U+006A+0302 -> U+0135 */ 115,
+	/* U+006A+030C -> U+01F0 */ 226,
+	/* U+006B+0301 -> U+1E31 */ 1169,
+	/* U+006B+030C -> U+01E9 */ 219,
+	/* U+006B+0323 -> U+1E33 */ 1171,
+	/* U+006B+0327 -> U+0137 */ 117,
+	/* U+006B+0331 -> U+1E35 */ 1173,
+	/* U+006C+0301 -> U+013A */ 119,
+	/* U+006C+030C -> U+013E */ 123,
+	/* U+006C+0323 -> U+1E37 */ 1175,
+	/* U+006C+0327 -> U+013C */ 121,
+	/* U+006C+032D -> U+1E3D */ 1181,
+	/* U+006C+0331 -> U+1E3B */ 1179,
+	/* U+006D+0301 -> U+1E3F */ 1183,
+	/* U+006D+0307 -> U+1E41 */ 1185,
+	/* U+006D+0323 -> U+1E43 */ 1187,
+	/* U+006E+0300 -> U+01F9 */ 233,
+	/* U+006E+0301 -> U+0144 */ 127,
+	/* U+006E+0303 -> U+00F1 */ 55,
+	/* U+006E+0307 -> U+1E45 */ 1189,
+	/* U+006E+030C -> U+0148 */ 131,
+	/* U+006E+0323 -> U+1E47 */ 1191,
+	/* U+006E+0327 -> U+0146 */ 129,
+	/* U+006E+032D -> U+1E4B */ 1195,
+	/* U+006E+0331 -> U+1E49 */ 1193,
+	/* U+006F+0300 -> U+00F2 */ 56,
+	/* U+006F+0301 -> U+00F3 */ 57,
+	/* U+006F+0302 -> U+00F4 */ 58,
+	/* U+006F+0303 -> U+00F5 */ 59,
+	/* U+006F+0304 -> U+014D */ 134,
+	/* U+006F+0306 -> U+014F */ 136,
+	/* U+006F+0307 -> U+022F */ 279,
+	/* U+006F+0308 -> U+00F6 */ 60,
+	/* U+006F+0309 -> U+1ECF */ 1323,
+	/* U+006F+030B -> U+0151 */ 138,
+	/* U+006F+030C -> U+01D2 */ 199,
+	/* U+006F+030F -> U+020D */ 253,
+	/* U+006F+0311 -> U+020F */ 255,
+	/* U+006F+031B -> U+01A1 */ 182,
+	/* U+006F+0323 -> U+1ECD */ 1321,
+	/* U+006F+0328 -> U+01EB */ 221,
+	/* U+0070+0301 -> U+1E55 */ 1205,
+	/* U+0070+0307 -> U+1E57 */ 1207,
+	/* U+0072+0301 -> U+0155 */ 140,
+	/* U+0072+0307 -> U+1E59 */ 1209,
+	/* U+0072+030C -> U+0159 */ 144,
+	/* U+0072+030F -> U+0211 */ 257,
+	/* U+0072+0311 -> U+0213 */ 259,
+	/* U+0072+0323 -> U+1E5B */ 1211,
+	/* U+0072+0327 -> U+0157 */ 142,
+	/* U+0072+0331 -> U+1E5F */ 1215,
+	/* U+0073+0301 -> U+015B */ 146,
+	/* U+0073+0302 -> U+015D */ 148,
+	/* U+0073+0307 -> U+1E61 */ 1217,
+	/* U+0073+030C -> U+0161 */ 152,
+	/* U+0073+0323 -> U+1E63 */ 1219,
+	/* U+0073+0326 -> U+0219 */ 265,
+	/* U+0073+0327 -> U+015F */ 150,
+	/* U+0074+0307 -> U+1E6B */ 1227,
+	/* U+0074+0308 -> U+1E97 */ 1271,
+	/* U+0074+030C -> U+0165 */ 156,
+	/* U+0074+0323 -> U+1E6D */ 1229,
+	/* U+0074+0326 -> U+021B */ 267,
+	/* U+0074+0327 -> U+0163 */ 154,
+	/* U+0074+032D -> U+1E71 */ 1233,
+	/* U+0074+0331 -> U+1E6F */ 1231,
+	/* U+0075+0300 -> U+00F9 */ 61,
+	/* U+0075+0301 -> U+00FA */ 62,
+	/* U+0075+0302 -> U+00FB */ 63,
+	/* U+0075+0303 -> U+0169 */ 158,
+	/* U+0075+0304 -> U+016B */ 160,
+	/* U+0075+0306 -> U+016D */ 162,
+	/* U+0075+0308 -> U+00FC */ 64,
+	/* U+0075+0309 -> U+1EE7 */ 1347,
+	/* U+0075+030A -> U+016F */ 164,
+	/* U+0075+030B -> U+0171 */ 166,
+	/* U+0075+030C -> U+01D4 */ 201,
+	/* U+0075+030F -> U+0215 */ 261,
+	/* U+0075+0311 -> U+0217 */ 263,
+	/* U+0075+031B -> U+01B0 */ 184,
+	/* U+0075+0323 -> U+1EE5 */ 1345,
+	/* U+0075+0324 -> U+1E73 */ 1235,
+	/* U+0075+0328 -> U+0173 */ 168,
+	/* U+0075+032D -> U+1E77 */ 1239,
+	/* U+0075+0330 -> U+1E75 */ 1237,
+	/* U+0076+0303 -> U+1E7D */ 1245,
+	/* U+0076+0323 -> U+1E7F */ 1247,
+	/* U+0077+0300 -> U+1E81 */ 1249,
+	/* U+0077+0301 -> U+1E83 */ 1251,
+	/* U+0077+0302 -> U+0175 */ 170,
+	/* U+0077+0307 -> U+1E87 */ 1255,
+	/* U+0077+0308 -> U+1E85 */ 1253,
+	/* U+0077+030A -> U+1E98 */ 1272,
+	/* U+0077+0323 -> U+1E89 */ 1257,
+	/* U+0078+0307 -> U+1E8B */ 1259,
+	/* U+0078+0308 -> U+1E8D */ 1261,
+	/* U+0079+0300 -> U+1EF3 */ 1359,
+	/* U+0079+0301 -> U+00FD */ 65,
+	/* U+0079+0302 -> U+0177 */ 172,
+	/* U+0079+0303 -> U+1EF9 */ 1365,
+	/* U+0079+0304 -> U+0233 */ 283,
+	/* U+0079+0307 -> U+1E8F */ 1263,
+	/* U+0079+0308 -> U+00FF */ 66,
+	/* U+0079+0309 -> U+1EF7 */ 1363,
+	/* U+0079+030A -> U+1E99 */ 1273,
+	/* U+0079+0323 -> U+1EF5 */ 1361,
+	/* U+007A+0301 -> U+017A */ 175,
+	/* U+007A+0302 -> U+1E91 */ 1265,
+	/* U+007A+0307 -> U+017C */ 177,
+	/* U+007A+030C -> U+017E */ 179,
+	/* U+007A+0323 -> U+1E93 */ 1267,
+	/* U+007A+0331 -> U+1E95 */ 1269,
+	/* U+00A8+0300 -> U+1FED */ 1584,
+	/* U+00A8+0301 -> U+0385 */ 419,
+	/* U+00A8+0342 -> U+1FC1 */ 1544,
+	/* U+00C2+0300 -> U+1EA6 */ 1282,
+	/* U+00C2+0301 -> U+1EA4 */ 1280,
+	/* U+00C2+0303 -> U+1EAA */ 1286,
+	/* U+00C2+0309 -> U+1EA8 */ 1284,
+	/* U+00C4+0304 -> U+01DE */ 210,
+	/* U+00C5+0301 -> U+01FA */ 234,
+	/* U+00C6+0301 -> U+01FC */ 236,
+	/* U+00C6+0304 -> U+01E2 */ 214,
+	/* U+00C7+0301 -> U+1E08 */ 1128,
+	/* U+00CA+0300 -> U+1EC0 */ 1308,
+	/* U+00CA+0301 -> U+1EBE */ 1306,
+	/* U+00CA+0303 -> U+1EC4 */ 1312,
+	/* U+00CA+0309 -> U+1EC2 */ 1310,
+	/* U+00CF+0301 -> U+1E2E */ 1166,
+	/* U+00D4+0300 -> U+1ED2 */ 1326,
+	/* U+00D4+0301 -> U+1ED0 */ 1324,
+	/* U+00D4+0303 -> U+1ED6 */ 1330,
+	/* U+00D4+0309 -> U+1ED4 */ 1328,
+	/* U+00D5+0301 -> U+1E4C */ 1196,
+	/* U+00D5+0304 -> U+022C */ 276,
+	/* U+00D5+0308 -> U+1E4E */ 1198,
+	/* U+00D6+0304 -> U+022A */ 274,
+	/* U+00D8+0301 -> U+01FE */ 238,
+	/* U+00DC+0300 -> U+01DB */ 208,
+	/* U+00DC+0301 -> U+01D7 */ 204,
+	/* U+00DC+0304 -> U+01D5 */ 202,
+	/* U+00DC+030C -> U+01D9 */ 206,
+	/* U+00E2+0300 -> U+1EA7 */ 1283,
+	/* U+00E2+0301 -> U+1EA5 */ 1281,
+	/* U+00E2+0303 -> U+1EAB */ 1287,
+	/* U+00E2+0309 -> U+1EA9 */ 1285,
+	/* U+00E4+0304 -> U+01DF */ 211,
+	/* U+00E5+0301 -> U+01FB */ 235,
+	/* U+00E6+0301 -> U+01FD */ 237,
+	/* U+00E6+0304 -> U+01E3 */ 215,
+	/* U+00E7+0301 -> U+1E09 */ 1129,
+	/* U+00EA+0300 -> U+1EC1 */ 1309,
+	/* U+00EA+0301 -> U+1EBF */ 1307,
+	/* U+00EA+0303 -> U+1EC5 */ 1313,
+	/* U+00EA+0309 -> U+1EC3 */ 1311,
+	/* U+00EF+0301 -> U+1E2F */ 1167,
+	/* U+00F4+0300 -> U+1ED3 */ 1327,
+	/* U+00F4+0301 -> U+1ED1 */ 1325,
+	/* U+00F4+0303 -> U+1ED7 */ 1331,
+	/* U+00F4+0309 -> U+1ED5 */ 1329,
+	/* U+00F5+0301 -> U+1E4D */ 1197,
+	/* U+00F5+0304 -> U+022D */ 277,
+	/* U+00F5+0308 -> U+1E4F */ 1199,
+	/* U+00F6+0304 -> U+022B */ 275,
+	/* U+00F8+0301 -> U+01FF */ 239,
+	/* U+00FC+0300 -> U+01DC */ 209,
+	/* U+00FC+0301 -> U+01D8 */ 205,
+	/* U+00FC+0304 -> U+01D6 */ 203,
+	/* U+00FC+030C -> U+01DA */ 207,
+	/* U+0102+0300 -> U+1EB0 */ 1292,
+	/* U+0102+0301 -> U+1EAE */ 1290,
+	/* U+0102+0303 -> U+1EB4 */ 1296,
+	/* U+0102+0309 -> U+1EB2 */ 1294,
+	/* U+0103+0300 -> U+1EB1 */ 1293,
+	/* U+0103+0301 -> U+1EAF */ 1291,
+	/* U+0103+0303 -> U+1EB5 */ 1297,
+	/* U+0103+0309 -> U+1EB3 */ 1295,
+	/* U+0112+0300 -> U+1E14 */ 1140,
+	/* U+0112+0301 -> U+1E16 */ 1142,
+	/* U+0113+0300 -> U+1E15 */ 1141,
+	/* U+0113+0301 -> U+1E17 */ 1143,
+	/* U+014C+0300 -> U+1E50 */ 1200,
+	/* U+014C+0301 -> U+1E52 */ 1202,
+	/* U+014D+0300 -> U+1E51 */ 1201,
+	/* U+014D+0301 -> U+1E53 */ 1203,
+	/* U+015A+0307 -> U+1E64 */ 1220,
+	/* U+015B+0307 -> U+1E65 */ 1221,
+	/* U+0160+0307 -> U+1E66 */ 1222,
+	/* U+0161+0307 -> U+1E67 */ 1223,
+	/* U+0168+0301 -> U+1E78 */ 1240,
+	/* U+0169+0301 -> U+1E79 */ 1241,
+	/* U+016A+0308 -> U+1E7A */ 1242,
+	/* U+016B+0308 -> U+1E7B */ 1243,
+	/* U+017F+0307 -> U+1E9B */ 1275,
+	/* U+01A0+0300 -> U+1EDC */ 1336,
+	/* U+01A0+0301 -> U+1EDA */ 1334,
+	/* U+01A0+0303 -> U+1EE0 */ 1340,
+	/* U+01A0+0309 -> U+1EDE */ 1338,
+	/* U+01A0+0323 -> U+1EE2 */ 1342,
+	/* U+01A1+0300 -> U+1EDD */ 1337,
+	/* U+01A1+0301 -> U+1EDB */ 1335,
+	/* U+01A1+0303 -> U+1EE1 */ 1341,
+	/* U+01A1+0309 -> U+1EDF */ 1339,
+	/* U+01A1+0323 -> U+1EE3 */ 1343,
+	/* U+01AF+0300 -> U+1EEA */ 1350,
+	/* U+01AF+0301 -> U+1EE8 */ 1348,
+	/* U+01AF+0303 -> U+1EEE */ 1354,
+	/* U+01AF+0309 -> U+1EEC */ 1352,
+	/* U+01AF+0323 -> U+1EF0 */ 1356,
+	/* U+01B0+0300 -> U+1EEB */ 1351,
+	/* U+01B0+0301 -> U+1EE9 */ 1349,
+	/* U+01B0+0303 -> U+1EEF */ 1355,
+	/* U+01B0+0309 -> U+1EED */ 1353,
+	/* U+01B0+0323 -> U+1EF1 */ 1357,
+	/* U+01B7+030C -> U+01EE */ 224,
+	/* U+01EA+0304 -> U+01EC */ 222,
+	/* U+01EB+0304 -> U+01ED */ 223,
+	/* U+0226+0304 -> U+01E0 */ 212,
+	/* U+0227+0304 -> U+01E1 */ 213,
+	/* U+0228+0306 -> U+1E1C */ 1148,
+	/* U+0229+0306 -> U+1E1D */ 1149,
+	/* U+022E+0304 -> U+0230 */ 280,
+	/* U+022F+0304 -> U+0231 */ 281,
+	/* U+0292+030C -> U+01EF */ 225,
+	/* U+0391+0300 -> U+1FBA */ 1537,
+	/* U+0391+0301 -> U+0386 */ 420,
+	/* U+0391+0304 -> U+1FB9 */ 1536,
+	/* U+0391+0306 -> U+1FB8 */ 1535,
+	/* U+0391+0313 -> U+1F08 */ 1374,
+	/* U+0391+0314 -> U+1F09 */ 1375,
+	/* U+0391+0345 -> U+1FBC */ 1539,
+	/* U+0395+0300 -> U+1FC8 */ 1550,
+	/* U+0395+0301 -> U+0388 */ 422,
+	/* U+0395+0313 -> U+1F18 */ 1388,
+	/* U+0395+0314 -> U+1F19 */ 1389,
+	/* U+0397+0300 -> U+1FCA */ 1552,
+	/* U+0397+0301 -> U+0389 */ 423,
+	/* U+0397+0313 -> U+1F28 */ 1402,
+	/* U+0397+0314 -> U+1F29 */ 1403,
+	/* U+0397+0345 -> U+1FCC */ 1554,
+	/* U+0399+0300 -> U+1FDA */ 1566,
+	/* U+0399+0301 -> U+038A */ 424,
+	/* U+0399+0304 -> U+1FD9 */ 1565,
+	/* U+0399+0306 -> U+1FD8 */ 1564,
+	/* U+0399+0308 -> U+03AA */ 429,
+	/* U+0399+0313 -> U+1F38 */ 1418,
+	/* U+0399+0314 -> U+1F39 */ 1419,
+	/* U+039F+0300 -> U+1FF8 */ 1592,
+	/* U+039F+0301 -> U+038C */ 425,
+	/* U+039F+0313 -> U+1F48 */ 1432,
+	/* U+039F+0314 -> U+1F49 */ 1433,
+	/* U+03A1+0314 -> U+1FEC */ 1583,
+	/* U+03A5+0300 -> U+1FEA */ 1581,
+	/* U+03A5+0301 -> U+038E */ 426,
+	/* U+03A5+0304 -> U+1FE9 */ 1580,
+	/* U+03A5+0306 -> U+1FE8 */ 1579,
+	/* U+03A5+0308 -> U+03AB */ 430,
+	/* U+03A5+0314 -> U+1F59 */ 1446,
+	/* U+03A9+0300 -> U+1FFA */ 1594,
+	/* U+03A9+0301 -> U+038F */ 427,
+	/* U+03A9+0313 -> U+1F68 */ 1458,
+	/* U+03A9+0314 -> U+1F69 */ 1459,
+	/* U+03A9+0345 -> U+1FFC */ 1596,
+	/* U+03AC+0345 -> U+1FB4 */ 1532,
+	/* U+03AE+0345 -> U+1FC4 */ 1547,
+	/* U+03B1+0300 -> U+1F70 */ 1466,
+	/* U+03B1+0301 -> U+03AC */ 431,
+	/* U+03B1+0304 -> U+1FB1 */ 1529,
+	/* U+03B1+0306 -> U+1FB0 */ 1528,
+	/* U+03B1+0313 -> U+1F00 */ 1366,
+	/* U+03B1+0314 -> U+1F01 */ 1367,
+	/* U+03B1+0342 -> U+1FB6 */ 1533,
+	/* U+03B1+0345 -> U+1FB3 */ 1531,
+	/* U+03B5+0300 -> U+1F72 */ 1468,
+	/* U+03B5+0301 -> U+03AD */ 432,
+	/* U+03B5+0313 -> U+1F10 */ 1382,
+	/* U+03B5+0314 -> U+1F11 */ 1383,
+	/* U+03B7+0300 -> U+1F74 */ 1470,
+	/* U+03B7+0301 -> U+03AE */ 433,
+	/* U+03B7+0313 -> U+1F20 */ 1394,
+	/* U+03B7+0314 -> U+1F21 */ 1395,
+	/* U+03B7+0342 -> U+1FC6 */ 1548,
+	/* U+03B7+0345 -> U+1FC3 */ 1546,
+	/* U+03B9+0300 -> U+1F76 */ 1472,
+	/* U+03B9+0301 -> U+03AF */ 434,
+	/* U+03B9+0304 -> U+1FD1 */ 1559,
+	/* U+03B9+0306 -> U+1FD0 */ 1558,
+	/* U+03B9+0308 -> U+03CA */ 436,
+	/* U+03B9+0313 -> U+1F30 */ 1410,
+	/* U+03B9+0314 -> U+1F31 */ 1411,
+	/* U+03B9+0342 -> U+1FD6 */ 1562,
+	/* U+03BF+0300 -> U+1F78 */ 1474,
+	/* U+03BF+0301 -> U+03CC */ 438,
+	/* U+03BF+0313 -> U+1F40 */ 1426,
+	/* U+03BF+0314 -> U+1F41 */ 1427,
+	/* U+03C1+0313 -> U+1FE4 */ 1575,
+	/* U+03C1+0314 -> U+1FE5 */ 1576,
+	/* U+03C5+0300 -> U+1F7A */ 1476,
+	/* U+03C5+0301 -> U+03CD */ 439,
+	/* U+03C5+0304 -> U+1FE1 */ 1572,
+	/* U+03C5+0306 -> U+1FE0 */ 1571,
+	/* U+03C5+0308 -> U+03CB */ 437,
+	/* U+03C5+0313 -> U+1F50 */ 1438,
+	/* U+03C5+0314 -> U+1F51 */ 1439,
+	/* U+03C5+0342 -> U+1FE6 */ 1577,
+	/* U+03C9+0300 -> U+1F7C */ 1478,
+	/* U+03C9+0301 -> U+03CE */ 440,
+	/* U+03C9+0313 -> U+1F60 */ 1450,
+	/* U+03C9+0314 -> U+1F61 */ 1451,
+	/* U+03C9+0342 -> U+1FF6 */ 1590,
+	/* U+03C9+0345 -> U+1FF3 */ 1588,
+	/* U+03CA+0300 -> U+1FD2 */ 1560,
+	/* U+03CA+0301 -> U+0390 */ 428,
+	/* U+03CA+0342 -> U+1FD7 */ 1563,
+	/* U+03CB+0300 -> U+1FE2 */ 1573,
+	/* U+03CB+0301 -> U+03B0 */ 435,
+	/* U+03CB+0342 -> U+1FE7 */ 1578,
+	/* U+03CE+0345 -> U+1FF4 */ 1589,
+	/* U+03D2+0301 -> U+03D3 */ 444,
+	/* U+03D2+0308 -> U+03D4 */ 445,
+	/* U+0406+0308 -> U+0407 */ 457,
+	/* U+0410+0306 -> U+04D0 */ 479,
+	/* U+0410+0308 -> U+04D2 */ 481,
+	/* U+0413+0301 -> U+0403 */ 456,
+	/* U+0415+0300 -> U+0400 */ 454,
+	/* U+0415+0306 -> U+04D6 */ 483,
+	/* U+0415+0308 -> U+0401 */ 455,
+	/* U+0416+0306 -> U+04C1 */ 477,
+	/* U+0416+0308 -> U+04DC */ 487,
+	/* U+0417+0308 -> U+04DE */ 489,
+	/* U+0418+0300 -> U+040D */ 459,
+	/* U+0418+0304 -> U+04E2 */ 491,
+	/* U+0418+0306 -> U+0419 */ 461,
+	/* U+0418+0308 -> U+04E4 */ 493,
+	/* U+041A+0301 -> U+040C */ 458,
+	/* U+041E+0308 -> U+04E6 */ 495,
+	/* U+0423+0304 -> U+04EE */ 501,
+	/* U+0423+0306 -> U+040E */ 460,
+	/* U+0423+0308 -> U+04F0 */ 503,
+	/* U+0423+030B -> U+04F2 */ 505,
+	/* U+0427+0308 -> U+04F4 */ 507,
+	/* U+042B+0308 -> U+04F8 */ 509,
+	/* U+042D+0308 -> U+04EC */ 499,
+	/* U+0430+0306 -> U+04D1 */ 480,
+	/* U+0430+0308 -> U+04D3 */ 482,
+	/* U+0433+0301 -> U+0453 */ 465,
+	/* U+0435+0300 -> U+0450 */ 463,
+	/* U+0435+0306 -> U+04D7 */ 484,
+	/* U+0435+0308 -> U+0451 */ 464,
+	/* U+0436+0306 -> U+04C2 */ 478,
+	/* U+0436+0308 -> U+04DD */ 488,
+	/* U+0437+0308 -> U+04DF */ 490,
+	/* U+0438+0300 -> U+045D */ 468,
+	/* U+0438+0304 -> U+04E3 */ 492,
+	/* U+0438+0306 -> U+0439 */ 462,
+	/* U+0438+0308 -> U+04E5 */ 494,
+	/* U+043A+0301 -> U+045C */ 467,
+	/* U+043E+0308 -> U+04E7 */ 496,
+	/* U+0443+0304 -> U+04EF */ 502,
+	/* U+0443+0306 -> U+045E */ 469,
+	/* U+0443+0308 -> U+04F1 */ 504,
+	/* U+0443+030B -> U+04F3 */ 506,
+	/* U+0447+0308 -> U+04F5 */ 508,
+	/* U+044B+0308 -> U+04F9 */ 510,
+	/* U+044D+0308 -> U+04ED */ 500,
+	/* U+0456+0308 -> U+0457 */ 466,
+	/* U+0474+030F -> U+0476 */ 470,
+	/* U+0475+030F -> U+0477 */ 471,
+	/* U+04D8+0308 -> U+04DA */ 485,
+	/* U+04D9+0308 -> U+04DB */ 486,
+	/* U+04E8+0308 -> U+04EA */ 497,
+	/* U+04E9+0308 -> U+04EB */ 498,
+	/* U+0627+0653 -> U+0622 */ 574,
+	/* U+0627+0654 -> U+0623 */ 575,
+	/* U+0627+0655 -> U+0625 */ 577,
+	/* U+0648+0654 -> U+0624 */ 576,
+	/* U+064A+0654 -> U+0626 */ 578,
+	/* U+06C1+0654 -> U+06C2 */ 606,
+	/* U+06D2+0654 -> U+06D3 */ 607,
+	/* U+06D5+0654 -> U+06C0 */ 605,
+	/* U+0928+093C -> U+0929 */ 733,
+	/* U+0930+093C -> U+0931 */ 734,
+	/* U+0933+093C -> U+0934 */ 735,
+	/* U+09C7+09BE -> U+09CB */ 751,
+	/* U+09C7+09D7 -> U+09CC */ 752,
+	/* U+0B47+0B3E -> U+0B4B */ 770,
+	/* U+0B47+0B56 -> U+0B48 */ 769,
+	/* U+0B47+0B57 -> U+0B4C */ 771,
+	/* U+0B92+0BD7 -> U+0B94 */ 775,
+	/* U+0BC6+0BBE -> U+0BCA */ 776,
+	/* U+0BC6+0BD7 -> U+0BCC */ 778,
+	/* U+0BC7+0BBE -> U+0BCB */ 777,
+	/* U+0C46+0C56 -> U+0C48 */ 780,
+	/* U+0CBF+0CD5 -> U+0CC0 */ 785,
+	/* U+0CC6+0CC2 -> U+0CCA */ 788,
+	/* U+0CC6+0CD5 -> U+0CC7 */ 786,
+	/* U+0CC6+0CD6 -> U+0CC8 */ 787,
+	/* U+0CCA+0CD5 -> U+0CCB */ 789,
+	/* U+0D46+0D3E -> U+0D4A */ 793,
+	/* U+0D46+0D57 -> U+0D4C */ 795,
+	/* U+0D47+0D3E -> U+0D4B */ 794,
+	/* U+0DD9+0DCA -> U+0DDA */ 798,
+	/* U+0DD9+0DCF -> U+0DDC */ 799,
+	/* U+0DD9+0DDF -> U+0DDE */ 801,
+	/* U+0DDC+0DCA -> U+0DDD */ 800,
+	/* U+1025+102E -> U+1026 */ 859,
+	/* U+1B05+1B35 -> U+1B06 */ 904,
+	/* U+1B07+1B35 -> U+1B08 */ 905,
+	/* U+1B09+1B35 -> U+1B0A */ 906,
+	/* U+1B0B+1B35 -> U+1B0C */ 907,
+	/* U+1B0D+1B35 -> U+1B0E */ 908,
+	/* U+1B11+1B35 -> U+1B12 */ 909,
+	/* U+1B3A+1B35 -> U+1B3B */ 911,
+	/* U+1B3C+1B35 -> U+1B3D */ 912,
+	/* U+1B3E+1B35 -> U+1B40 */ 913,
+	/* U+1B3F+1B35 -> U+1B41 */ 914,
+	/* U+1B42+1B35 -> U+1B43 */ 915,
+	/* U+1E36+0304 -> U+1E38 */ 1176,
+	/* U+1E37+0304 -> U+1E39 */ 1177,
+	/* U+1E5A+0304 -> U+1E5C */ 1212,
+	/* U+1E5B+0304 -> U+1E5D */ 1213,
+	/* U+1E62+0307 -> U+1E68 */ 1224,
+	/* U+1E63+0307 -> U+1E69 */ 1225,
+	/* U+1EA0+0302 -> U+1EAC */ 1288,
+	/* U+1EA0+0306 -> U+1EB6 */ 1298,
+	/* U+1EA1+0302 -> U+1EAD */ 1289,
+	/* U+1EA1+0306 -> U+1EB7 */ 1299,
+	/* U+1EB8+0302 -> U+1EC6 */ 1314,
+	/* U+1EB9+0302 -> U+1EC7 */ 1315,
+	/* U+1ECC+0302 -> U+1ED8 */ 1332,
+	/* U+1ECD+0302 -> U+1ED9 */ 1333,
+	/* U+1F00+0300 -> U+1F02 */ 1368,
+	/* U+1F00+0301 -> U+1F04 */ 1370,
+	/* U+1F00+0342 -> U+1F06 */ 1372,
+	/* U+1F00+0345 -> U+1F80 */ 1480,
+	/* U+1F01+0300 -> U+1F03 */ 1369,
+	/* U+1F01+0301 -> U+1F05 */ 1371,
+	/* U+1F01+0342 -> U+1F07 */ 1373,
+	/* U+1F01+0345 -> U+1F81 */ 1481,
+	/* U+1F02+0345 -> U+1F82 */ 1482,
+	/* U+1F03+0345 -> U+1F83 */ 1483,
+	/* U+1F04+0345 -> U+1F84 */ 1484,
+	/* U+1F05+0345 -> U+1F85 */ 1485,
+	/* U+1F06+0345 -> U+1F86 */ 1486,
+	/* U+1F07+0345 -> U+1F87 */ 1487,
+	/* U+1F08+0300 -> U+1F0A */ 1376,
+	/* U+1F08+0301 -> U+1F0C */ 1378,
+	/* U+1F08+0342 -> U+1F0E */ 1380,
+	/* U+1F08+0345 -> U+1F88 */ 1488,
+	/* U+1F09+0300 -> U+1F0B */ 1377,
+	/* U+1F09+0301 -> U+1F0D */ 1379,
+	/* U+1F09+0342 -> U+1F0F */ 1381,
+	/* U+1F09+0345 -> U+1F89 */ 1489,
+	/* U+1F0A+0345 -> U+1F8A */ 1490,
+	/* U+1F0B+0345 -> U+1F8B */ 1491,
+	/* U+1F0C+0345 -> U+1F8C */ 1492,
+	/* U+1F0D+0345 -> U+1F8D */ 1493,
+	/* U+1F0E+0345 -> U+1F8E */ 1494,
+	/* U+1F0F+0345 -> U+1F8F */ 1495,
+	/* U+1F10+0300 -> U+1F12 */ 1384,
+	/* U+1F10+0301 -> U+1F14 */ 1386,
+	/* U+1F11+0300 -> U+1F13 */ 1385,
+	/* U+1F11+0301 -> U+1F15 */ 1387,
+	/* U+1F18+0300 -> U+1F1A */ 1390,
+	/* U+1F18+0301 -> U+1F1C */ 1392,
+	/* U+1F19+0300 -> U+1F1B */ 1391,
+	/* U+1F19+0301 -> U+1F1D */ 1393,
+	/* U+1F20+0300 -> U+1F22 */ 1396,
+	/* U+1F20+0301 -> U+1F24 */ 1398,
+	/* U+1F20+0342 -> U+1F26 */ 1400,
+	/* U+1F20+0345 -> U+1F90 */ 1496,
+	/* U+1F21+0300 -> U+1F23 */ 1397,
+	/* U+1F21+0301 -> U+1F25 */ 1399,
+	/* U+1F21+0342 -> U+1F27 */ 1401,
+	/* U+1F21+0345 -> U+1F91 */ 1497,
+	/* U+1F22+0345 -> U+1F92 */ 1498,
+	/* U+1F23+0345 -> U+1F93 */ 1499,
+	/* U+1F24+0345 -> U+1F94 */ 1500,
+	/* U+1F25+0345 -> U+1F95 */ 1501,
+	/* U+1F26+0345 -> U+1F96 */ 1502,
+	/* U+1F27+0345 -> U+1F97 */ 1503,
+	/* U+1F28+0300 -> U+1F2A */ 1404,
+	/* U+1F28+0301 -> U+1F2C */ 1406,
+	/* U+1F28+0342 -> U+1F2E */ 1408,
+	/* U+1F28+0345 -> U+1F98 */ 1504,
+	/* U+1F29+0300 -> U+1F2B */ 1405,
+	/* U+1F29+0301 -> U+1F2D */ 1407,
+	/* U+1F29+0342 -> U+1F2F */ 1409,
+	/* U+1F29+0345 -> U+1F99 */ 1505,
+	/* U+1F2A+0345 -> U+1F9A */ 1506,
+	/* U+1F2B+0345 -> U+1F9B */ 1507,
+	/* U+1F2C+0345 -> U+1F9C */ 1508,
+	/* U+1F2D+0345 -> U+1F9D */ 1509,
+	/* U+1F2E+0345 -> U+1F9E */ 1510,
+	/* U+1F2F+0345 -> U+1F9F */ 1511,
+	/* U+1F30+0300 -> U+1F32 */ 1412,
+	/* U+1F30+0301 -> U+1F34 */ 1414,
+	/* U+1F30+0342 -> U+1F36 */ 1416,
+	/* U+1F31+0300 -> U+1F33 */ 1413,
+	/* U+1F31+0301 -> U+1F35 */ 1415,
+	/* U+1F31+0342 -> U+1F37 */ 1417,
+	/* U+1F38+0300 -> U+1F3A */ 1420,
+	/* U+1F38+0301 -> U+1F3C */ 1422,
+	/* U+1F38+0342 -> U+1F3E */ 1424,
+	/* U+1F39+0300 -> U+1F3B */ 1421,
+	/* U+1F39+0301 -> U+1F3D */ 1423,
+	/* U+1F39+0342 -> U+1F3F */ 1425,
+	/* U+1F40+0300 -> U+1F42 */ 1428,
+	/* U+1F40+0301 -> U+1F44 */ 1430,
+	/* U+1F41+0300 -> U+1F43 */ 1429,
+	/* U+1F41+0301 -> U+1F45 */ 1431,
+	/* U+1F48+0300 -> U+1F4A */ 1434,
+	/* U+1F48+0301 -> U+1F4C */ 1436,
+	/* U+1F49+0300 -> U+1F4B */ 1435,
+	/* U+1F49+0301 -> U+1F4D */ 1437,
+	/* U+1F50+0300 -> U+1F52 */ 1440,
+	/* U+1F50+0301 -> U+1F54 */ 1442,
+	/* U+1F50+0342 -> U+1F56 */ 1444,
+	/* U+1F51+0300 -> U+1F53 */ 1441,
+	/* U+1F51+0301 -> U+1F55 */ 1443,
+	/* U+1F51+0342 -> U+1F57 */ 1445,
+	/* U+1F59+0300 -> U+1F5B */ 1447,
+	/* U+1F59+0301 -> U+1F5D */ 1448,
+	/* U+1F59+0342 -> U+1F5F */ 1449,
+	/* U+1F60+0300 -> U+1F62 */ 1452,
+	/* U+1F60+0301 -> U+1F64 */ 1454,
+	/* U+1F60+0342 -> U+1F66 */ 1456,
+	/* U+1F60+0345 -> U+1FA0 */ 1512,
+	/* U+1F61+0300 -> U+1F63 */ 1453,
+	/* U+1F61+0301 -> U+1F65 */ 1455,
+	/* U+1F61+0342 -> U+1F67 */ 1457,
+	/* U+1F61+0345 -> U+1FA1 */ 1513,
+	/* U+1F62+0345 -> U+1FA2 */ 1514,
+	/* U+1F63+0345 -> U+1FA3 */ 1515,
+	/* U+1F64+0345 -> U+1FA4 */ 1516,
+	/* U+1F65+0345 -> U+1FA5 */ 1517,
+	/* U+1F66+0345 -> U+1FA6 */ 1518,
+	/* U+1F67+0345 -> U+1FA7 */ 1519,
+	/* U+1F68+0300 -> U+1F6A */ 1460,
+	/* U+1F68+0301 -> U+1F6C */ 1462,
+	/* U+1F68+0342 -> U+1F6E */ 1464,
+	/* U+1F68+0345 -> U+1FA8 */ 1520,
+	/* U+1F69+0300 -> U+1F6B */ 1461,
+	/* U+1F69+0301 -> U+1F6D */ 1463,
+	/* U+1F69+0342 -> U+1F6F */ 1465,
+	/* U+1F69+0345 -> U+1FA9 */ 1521,
+	/* U+1F6A+0345 -> U+1FAA */ 1522,
+	/* U+1F6B+0345 -> U+1FAB */ 1523,
+	/* U+1F6C+0345 -> U+1FAC */ 1524,
+	/* U+1F6D+0345 -> U+1FAD */ 1525,
+	/* U+1F6E+0345 -> U+1FAE */ 1526,
+	/* U+1F6F+0345 -> U+1FAF */ 1527,
+	/* U+1F70+0345 -> U+1FB2 */ 1530,
+	/* U+1F74+0345 -> U+1FC2 */ 1545,
+	/* U+1F7C+0345 -> U+1FF2 */ 1587,
+	/* U+1FB6+0345 -> U+1FB7 */ 1534,
+	/* U+1FBF+0300 -> U+1FCD */ 1555,
+	/* U+1FBF+0301 -> U+1FCE */ 1556,
+	/* U+1FBF+0342 -> U+1FCF */ 1557,
+	/* U+1FC6+0345 -> U+1FC7 */ 1549,
+	/* U+1FF6+0345 -> U+1FF7 */ 1591,
+	/* U+1FFE+0300 -> U+1FDD */ 1568,
+	/* U+1FFE+0301 -> U+1FDE */ 1569,
+	/* U+1FFE+0342 -> U+1FDF */ 1570,
+	/* U+2190+0338 -> U+219A */ 1801,
+	/* U+2192+0338 -> U+219B */ 1802,
+	/* U+2194+0338 -> U+21AE */ 1803,
+	/* U+21D0+0338 -> U+21CD */ 1804,
+	/* U+21D2+0338 -> U+21CF */ 1806,
+	/* U+21D4+0338 -> U+21CE */ 1805,
+	/* U+2203+0338 -> U+2204 */ 1807,
+	/* U+2208+0338 -> U+2209 */ 1808,
+	/* U+220B+0338 -> U+220C */ 1809,
+	/* U+2223+0338 -> U+2224 */ 1810,
+	/* U+2225+0338 -> U+2226 */ 1811,
+	/* U+223C+0338 -> U+2241 */ 1816,
+	/* U+2243+0338 -> U+2244 */ 1817,
+	/* U+2245+0338 -> U+2247 */ 1818,
+	/* U+2248+0338 -> U+2249 */ 1819,
+	/* U+224D+0338 -> U+226D */ 1822,
+	/* U+2261+0338 -> U+2262 */ 1821,
+	/* U+2264+0338 -> U+2270 */ 1825,
+	/* U+2265+0338 -> U+2271 */ 1826,
+	/* U+2272+0338 -> U+2274 */ 1827,
+	/* U+2273+0338 -> U+2275 */ 1828,
+	/* U+2276+0338 -> U+2278 */ 1829,
+	/* U+2277+0338 -> U+2279 */ 1830,
+	/* U+227A+0338 -> U+2280 */ 1831,
+	/* U+227B+0338 -> U+2281 */ 1832,
+	/* U+227C+0338 -> U+22E0 */ 1841,
+	/* U+227D+0338 -> U+22E1 */ 1842,
+	/* U+2282+0338 -> U+2284 */ 1833,
+	/* U+2283+0338 -> U+2285 */ 1834,
+	/* U+2286+0338 -> U+2288 */ 1835,
+	/* U+2287+0338 -> U+2289 */ 1836,
+	/* U+2291+0338 -> U+22E2 */ 1843,
+	/* U+2292+0338 -> U+22E3 */ 1844,
+	/* U+22A2+0338 -> U+22AC */ 1837,
+	/* U+22A8+0338 -> U+22AD */ 1838,
+	/* U+22A9+0338 -> U+22AE */ 1839,
+	/* U+22AB+0338 -> U+22AF */ 1840,
+	/* U+22B2+0338 -> U+22EA */ 1845,
+	/* U+22B3+0338 -> U+22EB */ 1846,
+	/* U+22B4+0338 -> U+22EC */ 1847,
+	/* U+22B5+0338 -> U+22ED */ 1848,
+	/* U+3046+3099 -> U+3094 */ 2286,
+	/* U+304B+3099 -> U+304C */ 2261,
+	/* U+304D+3099 -> U+304E */ 2262,
+	/* U+304F+3099 -> U+3050 */ 2263,
+	/* U+3051+3099 -> U+3052 */ 2264,
+	/* U+3053+3099 -> U+3054 */ 2265,
+	/* U+3055+3099 -> U+3056 */ 2266,
+	/* U+3057+3099 -> U+3058 */ 2267,
+	/* U+3059+3099 -> U+305A */ 2268,
+	/* U+305B+3099 -> U+305C */ 2269,
+	/* U+305D+3099 -> U+305E */ 2270,
+	/* U+305F+3099 -> U+3060 */ 2271,
+	/* U+3061+3099 -> U+3062 */ 2272,
+	/* U+3064+3099 -> U+3065 */ 2273,
+	/* U+3066+3099 -> U+3067 */ 2274,
+	/* U+3068+3099 -> U+3069 */ 2275,
+	/* U+306F+3099 -> U+3070 */ 2276,
+	/* U+306F+309A -> U+3071 */ 2277,
+	/* U+3072+3099 -> U+3073 */ 2278,
+	/* U+3072+309A -> U+3074 */ 2279,
+	/* U+3075+3099 -> U+3076 */ 2280,
+	/* U+3075+309A -> U+3077 */ 2281,
+	/* U+3078+3099 -> U+3079 */ 2282,
+	/* U+3078+309A -> U+307A */ 2283,
+	/* U+307B+3099 -> U+307C */ 2284,
+	/* U+307B+309A -> U+307D */ 2285,
+	/* U+309D+3099 -> U+309E */ 2291,
+	/* U+30A6+3099 -> U+30F4 */ 2318,
+	/* U+30AB+3099 -> U+30AC */ 2293,
+	/* U+30AD+3099 -> U+30AE */ 2294,
+	/* U+30AF+3099 -> U+30B0 */ 2295,
+	/* U+30B1+3099 -> U+30B2 */ 2296,
+	/* U+30B3+3099 -> U+30B4 */ 2297,
+	/* U+30B5+3099 -> U+30B6 */ 2298,
+	/* U+30B7+3099 -> U+30B8 */ 2299,
+	/* U+30B9+3099 -> U+30BA */ 2300,
+	/* U+30BB+3099 -> U+30BC */ 2301,
+	/* U+30BD+3099 -> U+30BE */ 2302,
+	/* U+30BF+3099 -> U+30C0 */ 2303,
+	/* U+30C1+3099 -> U+30C2 */ 2304,
+	/* U+30C4+3099 -> U+30C5 */ 2305,
+	/* U+30C6+3099 -> U+30C7 */ 2306,
+	/* U+30C8+3099 -> U+30C9 */ 2307,
+	/* U+30CF+3099 -> U+30D0 */ 2308,
+	/* U+30CF+309A -> U+30D1 */ 2309,
+	/* U+30D2+3099 -> U+30D3 */ 2310,
+	/* U+30D2+309A -> U+30D4 */ 2311,
+	/* U+30D5+3099 -> U+30D6 */ 2312,
+	/* U+30D5+309A -> U+30D7 */ 2313,
+	/* U+30D8+3099 -> U+30D9 */ 2314,
+	/* U+30D8+309A -> U+30DA */ 2315,
+	/* U+30DB+3099 -> U+30DC */ 2316,
+	/* U+30DB+309A -> U+30DD */ 2317,
+	/* U+30EF+3099 -> U+30F7 */ 2319,
+	/* U+30F0+3099 -> U+30F8 */ 2320,
+	/* U+30F1+3099 -> U+30F9 */ 2321,
+	/* U+30F2+3099 -> U+30FA */ 2322,
+	/* U+30FD+3099 -> U+30FE */ 2323,
+	/* U+11099+110BA -> U+1109A */ 4588,
+	/* U+1109B+110BA -> U+1109C */ 4589,
+	/* U+110A5+110BA -> U+110AB */ 4590,
+	/* U+11131+11127 -> U+1112E */ 4596,
+	/* U+11132+11127 -> U+1112F */ 4597,
+	/* U+11347+1133E -> U+1134B */ 4609,
+	/* U+11347+11357 -> U+1134C */ 4610,
+	/* U+114B9+114B0 -> U+114BC */ 4628,
+	/* U+114B9+114BA -> U+114BB */ 4627,
+	/* U+114B9+114BD -> U+114BE */ 4629,
+	/* U+115B8+115AF -> U+115BA */ 4632,
+	/* U+115B9+115AF -> U+115BB */ 4633,
+	/* U+11935+11930 -> U+11938 */ 4642
+};
+
+/* Perfect hash function for recomposition */
+static int
+Recomp_hash_func(const void *key)
+{
+	static const int16 h[1883] = {
+		772,   773,   621,   32767, 32767, 387,   653,   196,
+		32767, 32767, 855,   463,   -19,   651,   32767, 32767,
+		32767, 364,   32767, 32767, -108,  32767, 32767, 32767,
+		32767, 0,     -568,  32767, 32767, 32767, 0,     0,
+		0,     -103,  364,   0,     210,   732,   0,     0,
+		-506,  0,     0,     0,     32767, 32767, 0,     32767,
+		407,   -140,  32767, 409,   32767, 772,   0,     86,
+		842,   934,   32767, 32767, -499,  -355,  32767, 32767,
+		532,   138,   174,   -243,  860,   1870,  742,   32767,
+		32767, 339,   32767, 1290,  0,     32767, 32767, 0,
+		-449,  -1386, 1633,  560,   561,   32767, 1219,  1004,
+		139,   -804,  32767, -179,  141,   579,   1586,  32767,
+		32767, 32767, 142,   199,   32767, 32767, 143,   0,
+		32767, 32767, 314,   896,   32767, 32767, 428,   129,
+		286,   -58,   0,     68,    32767, 0,     244,   -566,
+		32767, 32767, 32767, 246,   32767, 32767, 0,     32767,
+		32767, 271,   -108,  928,   32767, 715,   32767, 32767,
+		-211,  -497,  32767, 0,     1055,  1339,  32767, 0,
+		32767, 32767, -968,  -144,  32767, 32767, 248,   32767,
+		-161,  32767, 32767, 282,   32767, -372,  0,     2,
+		-137,  1116,  32767, 687,   32767, 459,   913,   0,
+		461,   879,   -816,  443,   32767, 32767, 462,   1089,
+		32767, 1054,  0,     314,   447,   -26,   480,   32767,
+		64,    0,     0,     112,   32767, 66,    0,     646,
+		603,   22,    -292,  0,     710,   475,   32767, 24,
+		-781,  32767, 32767, 32767, 281,   307,   32767, 1289,
+		32767, 0,     1064,  -149,  454,   118,   32767, 32767,
+		0,     32767, -126,  0,     32767, 32767, 858,   32767,
+		32767, 32767, 1029,  886,   665,   209,   0,     26,
+		359,   0,     0,     -108,  -508,  -603,  894,   906,
+		32767, 32767, 14,    0,     0,     534,   984,   876,
+		32767, -93,   110,   -367,  167,   843,   32767, 32767,
+		-947,  -290,  169,   0,     0,     32767, -42,   564,
+		0,     -927,  32767, 817,   32767, 32767, 32767, 110,
+		0,     32767, 32767, -38,   32767, 32767, -101,  694,
+		-142,  190,   191,   1288,  32767, -687,  194,   -579,
+		534,   -452,  0,     -72,   536,   765,   823,   266,
+		-259,  684,   767,   32767, 654,   32767, 32767, 64,
+		920,   32767, 32767, 32767, 0,     1653,  0,     0,
+		32767, 32767, -452,  -222,  855,   0,     32767, -1153,
+		127,   490,   449,   863,   32767, -144,  32767, -379,
+		545,   32767, 32767, 32767, 530,   32767, 32767, 1331,
+		611,   -612,  332,   545,   -73,   0,     604,   201,
+		32767, -279,  338,   836,   340,   408,   32767, -60,
+		-358,  32767, 343,   69,    707,   0,     -129,  582,
+		32767, 0,     32767, 96,    392,   490,   639,   157,
+		-4,    406,   32767, 32767, -571,  1077,  546,   32767,
+		551,   0,     0,     0,     32767, 32767, 348,   32767,
+		498,   -181,  0,     -433,  1057,  260,   0,     32767,
+		32767, 397,   32767, 816,   -130,  32767, 624,   0,
+		0,     32767, 32767, 32767, 485,   0,     32767, 32767,
+		32767, 32767, 32767, 0,     32767, 32767, 32767, 1222,
+		-230,  32767, 797,   -538,  32767, 974,   32767, 32767,
+		831,   70,    -658,  145,   0,     147,   0,     32767,
+		1295,  32767, 0,     0,     895,   0,     0,     -385,
+		491,   -287,  32767, -587,  32767, 32767, 32767, 813,
+		-471,  -13,   32767, 32767, 32767, 0,     203,   411,
+		470,   0,     -546,  -179,  146,   0,     0,     32767,
+		-468,  32767, 0,     0,     32767, 32767, 32767, 211,
+		32767, 32767, 0,     32767, 0,     52,    32767, 0,
+		32767, 0,     692,   990,   32767, 32767, 32767, 56,
+		-507,  784,   951,   0,     32767, 0,     697,   32767,
+		187,   0,     32767, 32767, 430,   1209,  682,   32767,
+		130,   0,     -25,   0,     -1006, 0,     32767, 214,
+		433,   22,    0,     -1119, 32767, 285,   32767, 32767,
+		32767, 216,   32767, 32767, 32767, 217,   527,   32767,
+		32767, 32767, 829,   485,   419,   717,   620,   731,
+		32767, 470,   0,     -145,  -620,  1162,  -644,  848,
+		287,   -632,  32767, 32767, 32767, 32767, 381,   32767,
+		510,   511,   -554,  -2,    32767, 0,     0,     698,
+		32767, 32767, 436,   1154,  32767, 463,   32767, 32767,
+		627,   517,   32767, 32767, 854,   579,   723,   396,
+		110,   -42,   354,   32767, 664,   32767, 32767, 0,
+		0,     32767, 65,    -163,  67,    140,   69,    341,
+		70,    71,    402,   73,    623,   544,   624,   417,
+		-1375, 648,   32767, -26,   904,   0,     548,   0,
+		0,     32767, 32767, 855,   32767, 488,   -524,  599,
+		130,   131,   32767, 32767, 542,   -1110, -324,  -462,
+		32767, -405,  -440,  0,     0,     629,   850,   0,
+		741,   257,   258,   32767, 32767, 0,     32767, 923,
+		0,     32767, 0,     32767, 1559,  32767, 32767, 32767,
+		671,   32767, 134,   32767, 32767, -336,  -104,  576,
+		577,   829,   32767, 32767, 762,   902,   32767, 0,
+		32767, 0,     1506,  887,   32767, 636,   601,   2465,
+		426,   0,     236,   317,   427,   968,   32767, -975,
+		-559,  -343,  341,   32767, 937,   241,   0,     32767,
+		32767, 547,   32767, 32767, 32767, 32767, 32767, 789,
+		0,     32767, 32767, 32767, 0,     0,     0,     32767,
+		-192,  859,   1185,  1153,  69,    32767, 32767, 32767,
+		-539,  32767, 32767, 0,     32767, 32767, 32767, 32767,
+		640,   578,   32767, 32767, -766,  32767, 32767, 32767,
+		32767, 1050,  -572,  32767, 32767, 32767, 32767, 1268,
+		32767, 32767, 32767, 754,   32767, 32767, 1640,  179,
+		804,   32767, 32767, 32767, 32767, 0,     684,   943,
+		1006,  32767, 32767, 652,   0,     32767, 1041,  32767,
+		718,   791,   32767, 274,   697,   32767, 32767, 0,
+		32767, 32767, 32767, 0,     32767, 32767, 32767, 32767,
+		32767, 32767, 32767, 32767, 32767, 32767, 32767, 735,
+		0,     32767, 32767, 32767, 275,   358,   688,   32767,
+		32767, 32767, 548,   -87,   770,   32767, -42,   0,
+		551,   32767, 691,   222,   32767, 32767, 32767, 32767,
+		0,     1273,  403,   -121,  806,   553,   554,   163,
+		32767, 32767, 892,   825,   32767, 32767, -490,  32767,
+		32767, 32767, 32767, 32767, -109,  744,   910,   32767,
+		91,    32767, 32767, 0,     0,     32767, 32767, 32767,
+		1521,  50,    701,   32767, 32767, 32767, 32767, 164,
+		658,   32767, 288,   0,     32767, 0,     51,    0,
+		32767, 32767, 32767, 32767, 555,   1547,  32767, 32767,
+		595,   585,   429,   32767, -80,   32767, 1258,  0,
+		540,   486,   -434,  865,   0,     192,   0,     884,
+		0,     0,     0,     175,   555,   0,     32767, 32767,
+		0,     32767, -566,  866,   591,   32767, 32767, 32767,
+		32767, 32767, 496,   495,   -215,  32767, 849,   -772,
+		32767, 32767, 502,   178,   483,   32767, 912,   793,
+		794,   0,     32767, 32767, 32767, -556,  499,   838,
+		32767, 32767, -506,  331,   0,     0,     -1096, 512,
+		880,   0,     774,   -338,  649,   32767, 270,   32767,
+		32767, -624,  328,   459,   32767, 32767, 32767, 32767,
+		329,   -201,  -835,  813,   -879,  560,   0,     -212,
+		-114,  35,    -494,  37,    523,   653,   751,   -653,
+		-743,  32767, 1356,  818,   32767, 32767, 856,   0,
+		44,    902,   0,     0,     0,     0,     32767, -26,
+		526,   795,   456,   32767, 104,   -209,  -341,  133,
+		-372,  0,     45,    110,   111,   0,     511,   47,
+		114,   32767, 32767, 93,    48,    116,   -1031, -279,
+		32767, 192,   0,     32767, 453,   415,   0,     -190,
+		32767, 471,   240,   175,   29,    665,   684,   0,
+		-11,   -95,   -344,  32767, 245,   148,   0,     530,
+		0,     1185,  -615,  -712,  693,   784,   32767, 0,
+		-776,  32767, 32767, -813,  0,     0,     0,     207,
+		208,   32767, 674,   32767, 742,   -289,  249,   32767,
+		520,   929,   -50,   781,   0,     -778,  32767, 0,
+		302,   32767, 720,   -465,  0,     32767, 32767, 32767,
+		0,     0,     32767, 833,   328,   806,   32767, -403,
+		0,     32767, -77,   32767, 0,     441,   930,   32767,
+		643,   0,     32767, 1938,  0,     1334,  381,   32767,
+		216,   32767, 32767, 0,     32767, 484,   383,   0,
+		242,   395,   0,     32767, 32767, 32767, -781,  355,
+		356,   32767, 292,   706,   32767, 32767, 32767, 32767,
+		32767, -410,  32767, 32767, 782,   32767, 189,   32767,
+		32767, 943,   0,     -212,  407,   335,   0,     135,
+		32767, 616,   0,     -497,  0,     -67,   853,   32767,
+		700,   32767, 0,     32767, 32767, 32767, 32767, 32767,
+		32767, 32767, 0,     459,   -48,   32767, 58,    0,
+		-856,  1017,  32767, 59,    916,   -731,  32767, 940,
+		-855,  347,   650,   0,     678,   32767, 0,     32767,
+		32767, 530,   32767, 0,     -80,   32767, -730,  32767,
+		1214,  799,   58,    651,   841,   0,     0,     -589,
+		-1530, -478,  651,   652,   93,    576,   -1215, 32767,
+		125,   32767, 1279,  32767, 32767, 0,     32767, 0,
+		-367,  416,   -1236, 32767, 418,   32767, 815,   558,
+		559,   781,   419,   32767, 739,   32767, 0,     32767,
+		128,   570,   1349,  -298,  -66,   0,     147,   -488,
+		32767, 590,   189,   274,   524,   32767, 1082,  -209,
+		32767, 423,   32767, 32767, 975,   573,   32767, 424,
+		32767, 32767, 1241,  32767, 32767, 32767, 32767, 32767,
+		612,   391,   32767, 0,     -803,  1004,  -561,  32767,
+		32767, 735,   870,   32767, 0,     32767, 32767, -123,
+		99,    210,   600,   1294,  109,   1053,  32767, 307,
+		834,   32767, 0,     1651,  32767, 644,   32767, 32767,
+		0,     32767, -801,  385,   379,   32767, -368,  32767,
+		32767, 830,   0,     32767, 32767, 739,   371,   372,
+		-275,  32767, 32767, 331,   -780,  32767, 0,     1229,
+		-1462, 913,   266,   827,   125,   32767, 32767, 32767,
+		393,   32767, 631,   -33,   -883,  -661,  -204,  6,
+		-19,   257,   8,     9,     118,   519,   615,   -541,
+		-893,  0,     32767, 0,     1156,  15,    900,   32767,
+		32767, 32767, 32767, 32767, 32767, 1022,  376,   0,
+		32767, 32767, -972,  676,   840,   -661,  631,   58,
+		0,     17,    32767, 0,     -799,  82,    0,     32767,
+		32767, 680,   32767, 905,   0,     0,     32767, 32767,
+		0,     0,     32767, 0,     828,   386,   802,   0,
+		146,   0,     148,   32767, -1146, 0,     150,   151,
+		-743,  153,   154,   32767, 32767, 442,   32767, 743,
+		0,     0,     746,   0,     32767, 32767, 32767, 98,
+		32767, 157,   0,     696,   0,     32767, 32767, -294,
+		32767, 158,   159,   32767, 0,     32767, 160,   32767,
+		933,   32767, 32767, -50,   759,   824,   162,   672,
+		32767, 356,   0,     356,   32767, 32767, 0,     0,
+		656,   692,   253,   254,   -374,  102,   256,   32767,
+		0,     0,     32767, 32767, 259,   32767, 63,    260,
+		510,   261,   32767, 0,     32767, 1061,  32767, 521,
+		32767, 32767, 32767, 32767, 32767, 32767, 316,   317,
+		846,   0,     32767, -500,  318,   0,     32767, 32767,
+		263,   0,     790,   872,   32767, 32767, 32767, 2171,
+		264,   32767, 32767, 32767, 32767, 486,   334,   465,
+		32767, 466,   32767, 444,   606,   32767, 0,     445,
+		320,   -317,  0,     520,   322,   718,   32767, 32767,
+		32767, 0,     1013,  32767, 32767, 32767, 32767, 32767,
+		32767, 611,   32767, 0,     0,     32767, 32767, -120,
+		156,   613,   0,     0,     32767, -68,   32767, 622,
+		32767, 32767, 32767, 32767, 32767, 455,   32767, 32767,
+		32767, 403,   533,   0,     -161,  405,   95,    96,
+		32767, 97,    32767, 0,     29,    0,     32767, 32767,
+		30,    32767, 99,    32767, 32767, 0,     161,   32767,
+		97,    0,     32,    32767, 32767, 0,     0,     315,
+		32767, 32767, 414,   966,   0,     585,   32767, 32767,
+		-616,  -256,  171,   172,   666,   101,   562,   563,
+		32767, 95,    0,     0,     1492,  390,   -251,  103,
+		32767, 0,     32767, 188,   1487,  32767, 0,     0,
+		586,   668,   -126,  0,     0,     32767, 32767, 204,
+		32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767,
+		32767, 32767, 32767, 32767, 32767, 656,   32767, 32767,
+		599,   0,     222,   32767, 0,     1368,  -412,  435,
+		32767, 936,   32767, -17,   32767, 832,   32767, 437,
+		0,     -518,  787,   32767, 864,   -449,  0,     636,
+		713,   206,   592,   572,   0,     483,   -139,  32767,
+		32767, 180,   818,   32767, 32767, 1304,  0,     32767,
+		274,   0,     0,     0,     0,     705,   32767, 32767,
+		32767, 0,     -272,  0,     502,   503,   319,   0,
+		32767, 0,     13,    32767, 32767, 0,     32767, 270,
+		737,   0,     32767, 32767, 32767, 901,   32767, 616,
+		180,   32767, 721,   353,   32767, 0,     32767, 32767,
+		-199,  0,     280,   788,   32767, 940,   32767, 51,
+		0,     400,   53,    0,     54,    -637,  0,     -453,
+		0,     0,     0,     380,   0,     32767, 504,   0,
+		2049,  0,     -964,  32767, 0,     32767, 32767, 32767,
+		32767, 32767, 32767, 798,   32767, 32767, 32767, 0,
+		538,   488,   0,     32767, -528,  57,    819,   32767,
+		32767, 1244,  0,     488,   739,   908,   32767, 32767,
+		0,     32767, 32767, 0,     55,    533,   0,     32767,
+		814,   0,     32767, 458,   0,     32767, 32767, 32767,
+		32767, 32767, 32767, 32767, 776,   777,   920,   0,
+		0,     755,   32767, 0,     32767, 32767, 0,     32767,
+		55,    -954,  0,     372,   166,   218,   165,   857,
+		221,   675,   0,     223,   224,   -155,  226,   32767,
+		1851,  227,   32767, 32767, 1192,  0,     229,   0,
+		-72,   0,     865,   0,     0,     -330,  0,     683,
+		32767, -550,  -196,  725,   -573,  293,   102,   32767,
+		-589,  296,   297,   298,   231,   -256,  300,   32767,
+		32767, 301,   233,   868,   32767, 234,   0,     811,
+		1187,  32767, 32767, 0,     32767, 518,   0,     361,
+		362,   466,   0,     365,   32767, -179,  366,   367,
+		874,   369,   305,   0,     32767, 0,     32767, 0,
+		32767, 2000,  1215,  451,   652,   0,     0,     799,
+		32767, 32767, 32767
+	};
+
+	const unsigned char *k = (const unsigned char *) key;
+	size_t		keylen = 8;
+	uint32		a = 0;
+	uint32		b = 0;
+
+	while (keylen--)
+	{
+		unsigned char c = *k++;
+
+		a = a * 257 + c;
+		b = b * 17 + c;
+	}
+	return h[a % 1883] + h[b % 1883];
+}
+
+/* Hash lookup information for recomposition */
+static const pg_unicode_recompinfo UnicodeRecompInfo =
+{
+	RecompInverseLookup,
+	Recomp_hash_func,
+	941
+};
-- 
2.22.0

