changeset 20:496cd52a50ec

unicode: switch to sbase's mkrunetype.awk While here, update to last version of UnicodeData.txt and add uni_iscontrol function as well.
author David Demelier <markand@malikania.fr>
date Mon, 21 Mar 2022 09:00:42 +0100
parents 91879958b74d
children 887a8fd73d1e
files Makefile gen/UnicodeData.txt gen/mkutf.awk gen/src/mkunicode-c.c gen/src/utf.h gen/src/utfdef.h gen/unicode-before.c libunicode.3 unicode.c unicode.h
diffstat 10 files changed, 2682 insertions(+), 5767 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile	Sun Jan 02 10:21:47 2022 +0100
+++ b/Makefile	Mon Mar 21 09:00:42 2022 +0100
@@ -31,9 +31,12 @@
 .c:
 	${CC} ${CFLAGS} $< -o $@ ${LDFLAGS}
 
-unicode.c: gen/src/mkunicode-c gen/unicode-before.c gen/unicode-after.c
+gen/UnicodeData.txt:
+	curl http://unicode.org/Public/UCD/latest/ucd/UnicodeData.txt -o $@
+
+unicode.c: gen/UnicodeData.txt gen/mkutf.awk
 	cat gen/unicode-before.c > unicode.c
-	gen/src/mkunicode-c unicode.c gen/UnicodeData.txt
+	cat gen/UnicodeData.txt | awk -f gen/mkutf.awk >> unicode.c
 	cat gen/unicode-after.c >> unicode.c
 
 test/unicode: unicode.c unicode.h test/unicode.c
@@ -43,7 +46,6 @@
 	test/unicode
 
 clean:
-	rm -f gen/src/mkunicode-c
 	rm -f test/unicode
 
 .PHONY: all clean tests
--- a/gen/UnicodeData.txt	Sun Jan 02 10:21:47 2022 +0100
+++ b/gen/UnicodeData.txt	Mon Mar 21 09:00:42 2022 +0100
@@ -1525,6 +1525,7 @@
 061A;ARABIC SMALL KASRA;Mn;32;NSM;;;;;N;;;;;
 061B;ARABIC SEMICOLON;Po;0;AL;;;;;N;;;;;
 061C;ARABIC LETTER MARK;Cf;0;AL;;;;;N;;;;;
+061D;ARABIC END OF TEXT MARK;Po;0;AL;;;;;N;;;;;
 061E;ARABIC TRIPLE DOT PUNCTUATION MARK;Po;0;AL;;;;;N;;;;;
 061F;ARABIC QUESTION MARK;Po;0;AL;;;;;N;;;;;
 0620;ARABIC LETTER KASHMIRI YEH;Lo;0;AL;;;;;N;;;;;
@@ -2089,6 +2090,47 @@
 0868;SYRIAC LETTER MALAYALAM LLA;Lo;0;AL;;;;;N;;;;;
 0869;SYRIAC LETTER MALAYALAM LLLA;Lo;0;AL;;;;;N;;;;;
 086A;SYRIAC LETTER MALAYALAM SSA;Lo;0;AL;;;;;N;;;;;
+0870;ARABIC LETTER ALEF WITH ATTACHED FATHA;Lo;0;AL;;;;;N;;;;;
+0871;ARABIC LETTER ALEF WITH ATTACHED TOP RIGHT FATHA;Lo;0;AL;;;;;N;;;;;
+0872;ARABIC LETTER ALEF WITH RIGHT MIDDLE STROKE;Lo;0;AL;;;;;N;;;;;
+0873;ARABIC LETTER ALEF WITH LEFT MIDDLE STROKE;Lo;0;AL;;;;;N;;;;;
+0874;ARABIC LETTER ALEF WITH ATTACHED KASRA;Lo;0;AL;;;;;N;;;;;
+0875;ARABIC LETTER ALEF WITH ATTACHED BOTTOM RIGHT KASRA;Lo;0;AL;;;;;N;;;;;
+0876;ARABIC LETTER ALEF WITH ATTACHED ROUND DOT ABOVE;Lo;0;AL;;;;;N;;;;;
+0877;ARABIC LETTER ALEF WITH ATTACHED RIGHT ROUND DOT;Lo;0;AL;;;;;N;;;;;
+0878;ARABIC LETTER ALEF WITH ATTACHED LEFT ROUND DOT;Lo;0;AL;;;;;N;;;;;
+0879;ARABIC LETTER ALEF WITH ATTACHED ROUND DOT BELOW;Lo;0;AL;;;;;N;;;;;
+087A;ARABIC LETTER ALEF WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;;
+087B;ARABIC LETTER ALEF WITH ATTACHED TOP RIGHT FATHA AND DOT ABOVE;Lo;0;AL;;;;;N;;;;;
+087C;ARABIC LETTER ALEF WITH RIGHT MIDDLE STROKE AND DOT ABOVE;Lo;0;AL;;;;;N;;;;;
+087D;ARABIC LETTER ALEF WITH ATTACHED BOTTOM RIGHT KASRA AND DOT ABOVE;Lo;0;AL;;;;;N;;;;;
+087E;ARABIC LETTER ALEF WITH ATTACHED TOP RIGHT FATHA AND LEFT RING;Lo;0;AL;;;;;N;;;;;
+087F;ARABIC LETTER ALEF WITH RIGHT MIDDLE STROKE AND LEFT RING;Lo;0;AL;;;;;N;;;;;
+0880;ARABIC LETTER ALEF WITH ATTACHED BOTTOM RIGHT KASRA AND LEFT RING;Lo;0;AL;;;;;N;;;;;
+0881;ARABIC LETTER ALEF WITH ATTACHED RIGHT HAMZA;Lo;0;AL;;;;;N;;;;;
+0882;ARABIC LETTER ALEF WITH ATTACHED LEFT HAMZA;Lo;0;AL;;;;;N;;;;;
+0883;ARABIC TATWEEL WITH OVERSTRUCK HAMZA;Lo;0;AL;;;;;N;;;;;
+0884;ARABIC TATWEEL WITH OVERSTRUCK WAW;Lo;0;AL;;;;;N;;;;;
+0885;ARABIC TATWEEL WITH TWO DOTS BELOW;Lo;0;AL;;;;;N;;;;;
+0886;ARABIC LETTER THIN YEH;Lo;0;AL;;;;;N;;;;;
+0887;ARABIC BASELINE ROUND DOT;Lo;0;AL;;;;;N;;;;;
+0888;ARABIC RAISED ROUND DOT;Sk;0;AL;;;;;N;;;;;
+0889;ARABIC LETTER NOON WITH INVERTED SMALL V;Lo;0;AL;;;;;N;;;;;
+088A;ARABIC LETTER HAH WITH INVERTED SMALL V BELOW;Lo;0;AL;;;;;N;;;;;
+088B;ARABIC LETTER TAH WITH DOT BELOW;Lo;0;AL;;;;;N;;;;;
+088C;ARABIC LETTER TAH WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;;;;;
+088D;ARABIC LETTER KEHEH WITH TWO DOTS VERTICALLY BELOW;Lo;0;AL;;;;;N;;;;;
+088E;ARABIC VERTICAL TAIL;Lo;0;AL;;;;;N;;;;;
+0890;ARABIC POUND MARK ABOVE;Cf;0;AN;;;;;N;;;;;
+0891;ARABIC PIASTRE MARK ABOVE;Cf;0;AN;;;;;N;;;;;
+0898;ARABIC SMALL HIGH WORD AL-JUZ;Mn;230;NSM;;;;;N;;;;;
+0899;ARABIC SMALL LOW WORD ISHMAAM;Mn;220;NSM;;;;;N;;;;;
+089A;ARABIC SMALL LOW WORD IMAALA;Mn;220;NSM;;;;;N;;;;;
+089B;ARABIC SMALL LOW WORD TASHEEL;Mn;220;NSM;;;;;N;;;;;
+089C;ARABIC MADDA WAAJIB;Mn;230;NSM;;;;;N;;;;;
+089D;ARABIC SUPERSCRIPT ALEF MOKHASSAS;Mn;230;NSM;;;;;N;;;;;
+089E;ARABIC DOUBLED MADDA;Mn;230;NSM;;;;;N;;;;;
+089F;ARABIC HALF MADDA OVER MADDA;Mn;230;NSM;;;;;N;;;;;
 08A0;ARABIC LETTER BEH WITH SMALL V BELOW;Lo;0;AL;;;;;N;;;;;
 08A1;ARABIC LETTER BEH WITH HAMZA ABOVE;Lo;0;AL;;;;;N;;;;;
 08A2;ARABIC LETTER JEEM WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
@@ -2110,6 +2152,7 @@
 08B2;ARABIC LETTER ZAIN WITH INVERTED V ABOVE;Lo;0;AL;;;;;N;;;;;
 08B3;ARABIC LETTER AIN WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;;;;;
 08B4;ARABIC LETTER KAF WITH DOT BELOW;Lo;0;AL;;;;;N;;;;;
+08B5;ARABIC LETTER QAF WITH DOT BELOW AND NO DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
 08B6;ARABIC LETTER BEH WITH SMALL MEEM ABOVE;Lo;0;AL;;;;;N;;;;;
 08B7;ARABIC LETTER PEH WITH SMALL MEEM ABOVE;Lo;0;AL;;;;;N;;;;;
 08B8;ARABIC LETTER TEH WITH SMALL TEH ABOVE;Lo;0;AL;;;;;N;;;;;
@@ -2128,6 +2171,17 @@
 08C5;ARABIC LETTER JEEM WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
 08C6;ARABIC LETTER JEEM WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;;;;;
 08C7;ARABIC LETTER LAM WITH SMALL ARABIC LETTER TAH ABOVE;Lo;0;AL;;;;;N;;;;;
+08C8;ARABIC LETTER GRAF;Lo;0;AL;;;;;N;;;;;
+08C9;ARABIC SMALL FARSI YEH;Lm;0;AL;;;;;N;;;;;
+08CA;ARABIC SMALL HIGH FARSI YEH;Mn;230;NSM;;;;;N;;;;;
+08CB;ARABIC SMALL HIGH YEH BARREE WITH TWO DOTS BELOW;Mn;230;NSM;;;;;N;;;;;
+08CC;ARABIC SMALL HIGH WORD SAH;Mn;230;NSM;;;;;N;;;;;
+08CD;ARABIC SMALL HIGH ZAH;Mn;230;NSM;;;;;N;;;;;
+08CE;ARABIC LARGE ROUND DOT ABOVE;Mn;230;NSM;;;;;N;;;;;
+08CF;ARABIC LARGE ROUND DOT BELOW;Mn;220;NSM;;;;;N;;;;;
+08D0;ARABIC SUKUN BELOW;Mn;220;NSM;;;;;N;;;;;
+08D1;ARABIC LARGE CIRCLE BELOW;Mn;220;NSM;;;;;N;;;;;
+08D2;ARABIC LARGE ROUND DOT INSIDE CIRCLE BELOW;Mn;220;NSM;;;;;N;;;;;
 08D3;ARABIC SMALL LOW WAW;Mn;220;NSM;;;;;N;;;;;
 08D4;ARABIC SMALL HIGH WORD AR-RUB;Mn;230;NSM;;;;;N;;;;;
 08D5;ARABIC SMALL HIGH SAD;Mn;230;NSM;;;;;N;;;;;
@@ -2786,6 +2840,7 @@
 0C37;TELUGU LETTER SSA;Lo;0;L;;;;;N;;;;;
 0C38;TELUGU LETTER SA;Lo;0;L;;;;;N;;;;;
 0C39;TELUGU LETTER HA;Lo;0;L;;;;;N;;;;;
+0C3C;TELUGU SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
 0C3D;TELUGU SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;;
 0C3E;TELUGU VOWEL SIGN AA;Mn;0;NSM;;;;;N;;;;;
 0C3F;TELUGU VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
@@ -2806,6 +2861,7 @@
 0C58;TELUGU LETTER TSA;Lo;0;L;;;;;N;;;;;
 0C59;TELUGU LETTER DZA;Lo;0;L;;;;;N;;;;;
 0C5A;TELUGU LETTER RRRA;Lo;0;L;;;;;N;;;;;
+0C5D;TELUGU LETTER NAKAARA POLLU;Lo;0;L;;;;;N;;;;;
 0C60;TELUGU LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
 0C61;TELUGU LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
 0C62;TELUGU VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;
@@ -2901,6 +2957,7 @@
 0CCD;KANNADA SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
 0CD5;KANNADA LENGTH MARK;Mc;0;L;;;;;N;;;;;
 0CD6;KANNADA AI LENGTH MARK;Mc;0;L;;;;;N;;;;;
+0CDD;KANNADA LETTER NAKAARA POLLU;Lo;0;L;;;;;N;;;;;
 0CDE;KANNADA LETTER FA;Lo;0;L;;;;;N;;;;;
 0CE0;KANNADA LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
 0CE1;KANNADA LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
@@ -5258,6 +5315,7 @@
 170A;TAGALOG LETTER BA;Lo;0;L;;;;;N;;;;;
 170B;TAGALOG LETTER MA;Lo;0;L;;;;;N;;;;;
 170C;TAGALOG LETTER YA;Lo;0;L;;;;;N;;;;;
+170D;TAGALOG LETTER RA;Lo;0;L;;;;;N;;;;;
 170E;TAGALOG LETTER LA;Lo;0;L;;;;;N;;;;;
 170F;TAGALOG LETTER WA;Lo;0;L;;;;;N;;;;;
 1710;TAGALOG LETTER SA;Lo;0;L;;;;;N;;;;;
@@ -5265,6 +5323,8 @@
 1712;TAGALOG VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
 1713;TAGALOG VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
 1714;TAGALOG SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+1715;TAGALOG SIGN PAMUDPOD;Mc;9;L;;;;;N;;;;;
+171F;TAGALOG LETTER ARCHAIC RA;Lo;0;L;;;;;N;;;;;
 1720;HANUNOO LETTER A;Lo;0;L;;;;;N;;;;;
 1721;HANUNOO LETTER I;Lo;0;L;;;;;N;;;;;
 1722;HANUNOO LETTER U;Lo;0;L;;;;;N;;;;;
@@ -5285,7 +5345,7 @@
 1731;HANUNOO LETTER HA;Lo;0;L;;;;;N;;;;;
 1732;HANUNOO VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
 1733;HANUNOO VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
-1734;HANUNOO SIGN PAMUDPOD;Mn;9;NSM;;;;;N;;;;;
+1734;HANUNOO SIGN PAMUDPOD;Mc;9;L;;;;;N;;;;;
 1735;PHILIPPINE SINGLE PUNCTUATION;Po;0;L;;;;;N;;;;;
 1736;PHILIPPINE DOUBLE PUNCTUATION;Po;0;L;;;;;N;;;;;
 1740;BUHID LETTER A;Lo;0;L;;;;;N;;;;;
@@ -5455,6 +5515,7 @@
 180C;MONGOLIAN FREE VARIATION SELECTOR TWO;Mn;0;NSM;;;;;N;;;;;
 180D;MONGOLIAN FREE VARIATION SELECTOR THREE;Mn;0;NSM;;;;;N;;;;;
 180E;MONGOLIAN VOWEL SEPARATOR;Cf;0;BN;;;;;N;;;;;
+180F;MONGOLIAN FREE VARIATION SELECTOR FOUR;Mn;0;NSM;;;;;N;;;;;
 1810;MONGOLIAN DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
 1811;MONGOLIAN DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
 1812;MONGOLIAN DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
@@ -6059,6 +6120,20 @@
 1ABE;COMBINING PARENTHESES OVERLAY;Me;0;NSM;;;;;N;;;;;
 1ABF;COMBINING LATIN SMALL LETTER W BELOW;Mn;220;NSM;;;;;N;;;;;
 1AC0;COMBINING LATIN SMALL LETTER TURNED W BELOW;Mn;220;NSM;;;;;N;;;;;
+1AC1;COMBINING LEFT PARENTHESIS ABOVE LEFT;Mn;230;NSM;;;;;N;;;;;
+1AC2;COMBINING RIGHT PARENTHESIS ABOVE RIGHT;Mn;230;NSM;;;;;N;;;;;
+1AC3;COMBINING LEFT PARENTHESIS BELOW LEFT;Mn;220;NSM;;;;;N;;;;;
+1AC4;COMBINING RIGHT PARENTHESIS BELOW RIGHT;Mn;220;NSM;;;;;N;;;;;
+1AC5;COMBINING SQUARE BRACKETS ABOVE;Mn;230;NSM;;;;;N;;;;;
+1AC6;COMBINING NUMBER SIGN ABOVE;Mn;230;NSM;;;;;N;;;;;
+1AC7;COMBINING INVERTED DOUBLE ARCH ABOVE;Mn;230;NSM;;;;;N;;;;;
+1AC8;COMBINING PLUS SIGN ABOVE;Mn;230;NSM;;;;;N;;;;;
+1AC9;COMBINING DOUBLE PLUS SIGN ABOVE;Mn;230;NSM;;;;;N;;;;;
+1ACA;COMBINING DOUBLE PLUS SIGN BELOW;Mn;220;NSM;;;;;N;;;;;
+1ACB;COMBINING TRIPLE ACUTE ACCENT;Mn;230;NSM;;;;;N;;;;;
+1ACC;COMBINING LATIN SMALL LETTER INSULAR G;Mn;230;NSM;;;;;N;;;;;
+1ACD;COMBINING LATIN SMALL LETTER INSULAR R;Mn;230;NSM;;;;;N;;;;;
+1ACE;COMBINING LATIN SMALL LETTER INSULAR T;Mn;230;NSM;;;;;N;;;;;
 1B00;BALINESE SIGN ULU RICEM;Mn;0;NSM;;;;;N;;;;;
 1B01;BALINESE SIGN ULU CANDRA;Mn;0;NSM;;;;;N;;;;;
 1B02;BALINESE SIGN CECEK;Mn;0;NSM;;;;;N;;;;;
@@ -6135,6 +6210,7 @@
 1B49;BALINESE LETTER VE SASAK;Lo;0;L;;;;;N;;;;;
 1B4A;BALINESE LETTER ZAL SASAK;Lo;0;L;;;;;N;;;;;
 1B4B;BALINESE LETTER ASYURA SASAK;Lo;0;L;;;;;N;;;;;
+1B4C;BALINESE LETTER ARCHAIC JNYA;Lo;0;L;;;;;N;;;;;
 1B50;BALINESE DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
 1B51;BALINESE DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
 1B52;BALINESE DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
@@ -6180,6 +6256,8 @@
 1B7A;BALINESE MUSICAL SYMBOL LEFT-HAND CLOSED PLAK;So;0;L;;;;;N;;;;;
 1B7B;BALINESE MUSICAL SYMBOL LEFT-HAND CLOSED PLUK;So;0;L;;;;;N;;;;;
 1B7C;BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PING;So;0;L;;;;;N;;;;;
+1B7D;BALINESE PANTI LANTANG;Po;0;L;;;;;N;;;;;
+1B7E;BALINESE PAMADA LANTANG;Po;0;L;;;;;N;;;;;
 1B80;SUNDANESE SIGN PANYECEK;Mn;0;NSM;;;;;N;;;;;
 1B81;SUNDANESE SIGN PANGLAYAR;Mn;0;NSM;;;;;N;;;;;
 1B82;SUNDANESE SIGN PANGWISAD;Mc;0;L;;;;;N;;;;;
@@ -6778,6 +6856,7 @@
 1DF7;COMBINING KAVYKA ABOVE LEFT;Mn;228;NSM;;;;;N;;;;;
 1DF8;COMBINING DOT ABOVE LEFT;Mn;228;NSM;;;;;N;;;;;
 1DF9;COMBINING WIDE INVERTED BRIDGE BELOW;Mn;220;NSM;;;;;N;;;;;
+1DFA;COMBINING DOT BELOW LEFT;Mn;218;NSM;;;;;N;;;;;
 1DFB;COMBINING DELETION MARK;Mn;230;NSM;;;;;N;;;;;
 1DFC;COMBINING DOUBLE INVERTED BREVE BELOW;Mn;233;NSM;;;;;N;;;;;
 1DFD;COMBINING ALMOST EQUAL TO BELOW;Mn;220;NSM;;;;;N;;;;;
@@ -7457,6 +7536,7 @@
 20BD;RUBLE SIGN;Sc;0;ET;;;;;N;;;;;
 20BE;LARI SIGN;Sc;0;ET;;;;;N;;;;;
 20BF;BITCOIN SIGN;Sc;0;ET;;;;;N;;;;;
+20C0;SOM SIGN;Sc;0;ET;;;;;N;;;;;
 20D0;COMBINING LEFT HARPOON ABOVE;Mn;230;NSM;;;;;N;NON-SPACING LEFT HARPOON ABOVE;;;;
 20D1;COMBINING RIGHT HARPOON ABOVE;Mn;230;NSM;;;;;N;NON-SPACING RIGHT HARPOON ABOVE;;;;
 20D2;COMBINING LONG VERTICAL LINE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING LONG VERTICAL BAR OVERLAY;;;;
@@ -10300,6 +10380,7 @@
 2C2C;GLAGOLITIC CAPITAL LETTER SHTAPIC;Lu;0;L;;;;;N;;;;2C5C;
 2C2D;GLAGOLITIC CAPITAL LETTER TROKUTASTI A;Lu;0;L;;;;;N;;;;2C5D;
 2C2E;GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE;Lu;0;L;;;;;N;;;;2C5E;
+2C2F;GLAGOLITIC CAPITAL LETTER CAUDATE CHRIVI;Lu;0;L;;;;;N;;;;2C5F;
 2C30;GLAGOLITIC SMALL LETTER AZU;Ll;0;L;;;;;N;;;2C00;;2C00
 2C31;GLAGOLITIC SMALL LETTER BUKY;Ll;0;L;;;;;N;;;2C01;;2C01
 2C32;GLAGOLITIC SMALL LETTER VEDE;Ll;0;L;;;;;N;;;2C02;;2C02
@@ -10347,6 +10428,7 @@
 2C5C;GLAGOLITIC SMALL LETTER SHTAPIC;Ll;0;L;;;;;N;;;2C2C;;2C2C
 2C5D;GLAGOLITIC SMALL LETTER TROKUTASTI A;Ll;0;L;;;;;N;;;2C2D;;2C2D
 2C5E;GLAGOLITIC SMALL LETTER LATINATE MYSLITE;Ll;0;L;;;;;N;;;2C2E;;2C2E
+2C5F;GLAGOLITIC SMALL LETTER CAUDATE CHRIVI;Ll;0;L;;;;;N;;;2C2F;;2C2F
 2C60;LATIN CAPITAL LETTER L WITH DOUBLE BAR;Lu;0;L;;;;;N;;;;2C61;
 2C61;LATIN SMALL LETTER L WITH DOUBLE BAR;Ll;0;L;;;;;N;;;2C60;;2C60
 2C62;LATIN CAPITAL LETTER L WITH MIDDLE TILDE;Lu;0;L;;;;;N;;;;026B;
@@ -10795,6 +10877,17 @@
 2E50;CROSS PATTY WITH RIGHT CROSSBAR;So;0;ON;;;;;N;;;;;
 2E51;CROSS PATTY WITH LEFT CROSSBAR;So;0;ON;;;;;N;;;;;
 2E52;TIRONIAN SIGN CAPITAL ET;Po;0;ON;;;;;N;;;;;
+2E53;MEDIEVAL EXCLAMATION MARK;Po;0;ON;;;;;N;;;;;
+2E54;MEDIEVAL QUESTION MARK;Po;0;ON;;;;;N;;;;;
+2E55;LEFT SQUARE BRACKET WITH STROKE;Ps;0;ON;;;;;Y;;;;;
+2E56;RIGHT SQUARE BRACKET WITH STROKE;Pe;0;ON;;;;;Y;;;;;
+2E57;LEFT SQUARE BRACKET WITH DOUBLE STROKE;Ps;0;ON;;;;;Y;;;;;
+2E58;RIGHT SQUARE BRACKET WITH DOUBLE STROKE;Pe;0;ON;;;;;Y;;;;;
+2E59;TOP HALF LEFT PARENTHESIS;Ps;0;ON;;;;;Y;;;;;
+2E5A;TOP HALF RIGHT PARENTHESIS;Pe;0;ON;;;;;Y;;;;;
+2E5B;BOTTOM HALF LEFT PARENTHESIS;Ps;0;ON;;;;;Y;;;;;
+2E5C;BOTTOM HALF RIGHT PARENTHESIS;Pe;0;ON;;;;;Y;;;;;
+2E5D;OBLIQUE HYPHEN;Pd;0;ON;;;;;N;;;;;
 2E80;CJK RADICAL REPEAT;So;0;ON;;;;;N;;;;;
 2E81;CJK RADICAL CLIFF;So;0;ON;;;;;N;;;;;
 2E82;CJK RADICAL SECOND ONE;So;0;ON;;;;;N;;;;;
@@ -12204,7 +12297,7 @@
 4DFE;HEXAGRAM FOR AFTER COMPLETION;So;0;ON;;;;;N;;;;;
 4DFF;HEXAGRAM FOR BEFORE COMPLETION;So;0;ON;;;;;N;;;;;
 4E00;<CJK Ideograph, First>;Lo;0;L;;;;;N;;;;;
-9FFC;<CJK Ideograph, Last>;Lo;0;L;;;;;N;;;;;
+9FFF;<CJK Ideograph, Last>;Lo;0;L;;;;;N;;;;;
 A000;YI SYLLABLE IT;Lo;0;L;;;;;N;;;;;
 A001;YI SYLLABLE IX;Lo;0;L;;;;;N;;;;;
 A002;YI SYLLABLE I;Lo;0;L;;;;;N;;;;;
@@ -14149,6 +14242,8 @@
 A7BD;LATIN SMALL LETTER GLOTTAL I;Ll;0;L;;;;;N;;;A7BC;;A7BC
 A7BE;LATIN CAPITAL LETTER GLOTTAL U;Lu;0;L;;;;;N;;;;A7BF;
 A7BF;LATIN SMALL LETTER GLOTTAL U;Ll;0;L;;;;;N;;;A7BE;;A7BE
+A7C0;LATIN CAPITAL LETTER OLD POLISH O;Lu;0;L;;;;;N;;;;A7C1;
+A7C1;LATIN SMALL LETTER OLD POLISH O;Ll;0;L;;;;;N;;;A7C0;;A7C0
 A7C2;LATIN CAPITAL LETTER ANGLICANA W;Lu;0;L;;;;;N;;;;A7C3;
 A7C3;LATIN SMALL LETTER ANGLICANA W;Ll;0;L;;;;;N;;;A7C2;;A7C2
 A7C4;LATIN CAPITAL LETTER C WITH PALATAL HOOK;Lu;0;L;;;;;N;;;;A794;
@@ -14158,6 +14253,17 @@
 A7C8;LATIN SMALL LETTER D WITH SHORT STROKE OVERLAY;Ll;0;L;;;;;N;;;A7C7;;A7C7
 A7C9;LATIN CAPITAL LETTER S WITH SHORT STROKE OVERLAY;Lu;0;L;;;;;N;;;;A7CA;
 A7CA;LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY;Ll;0;L;;;;;N;;;A7C9;;A7C9
+A7D0;LATIN CAPITAL LETTER CLOSED INSULAR G;Lu;0;L;;;;;N;;;;A7D1;
+A7D1;LATIN SMALL LETTER CLOSED INSULAR G;Ll;0;L;;;;;N;;;A7D0;;A7D0
+A7D3;LATIN SMALL LETTER DOUBLE THORN;Ll;0;L;;;;;N;;;;;
+A7D5;LATIN SMALL LETTER DOUBLE WYNN;Ll;0;L;;;;;N;;;;;
+A7D6;LATIN CAPITAL LETTER MIDDLE SCOTS S;Lu;0;L;;;;;N;;;;A7D7;
+A7D7;LATIN SMALL LETTER MIDDLE SCOTS S;Ll;0;L;;;;;N;;;A7D6;;A7D6
+A7D8;LATIN CAPITAL LETTER SIGMOID S;Lu;0;L;;;;;N;;;;A7D9;
+A7D9;LATIN SMALL LETTER SIGMOID S;Ll;0;L;;;;;N;;;A7D8;;A7D8
+A7F2;MODIFIER LETTER CAPITAL C;Lm;0;L;<super> 0043;;;;N;;;;;
+A7F3;MODIFIER LETTER CAPITAL F;Lm;0;L;<super> 0046;;;;N;;;;;
+A7F4;MODIFIER LETTER CAPITAL Q;Lm;0;L;<super> 0051;;;;N;;;;;
 A7F5;LATIN CAPITAL LETTER REVERSED HALF H;Lu;0;L;;;;;N;;;;A7F6;
 A7F6;LATIN SMALL LETTER REVERSED HALF H;Ll;0;L;;;;;N;;;A7F5;;A7F5
 A7F7;LATIN EPIGRAPHIC LETTER SIDEWAYS I;Lo;0;L;;;;;N;;;;;
@@ -15794,6 +15900,7 @@
 FBBF;ARABIC SYMBOL RING;Sk;0;AL;;;;;N;;;;;
 FBC0;ARABIC SYMBOL SMALL TAH ABOVE;Sk;0;AL;;;;;N;;;;;
 FBC1;ARABIC SYMBOL SMALL TAH BELOW;Sk;0;AL;;;;;N;;;;;
+FBC2;ARABIC SYMBOL WASLA ABOVE;Sk;0;AL;;;;;N;;;;;
 FBD3;ARABIC LETTER NG ISOLATED FORM;Lo;0;AL;<isolated> 06AD;;;;N;;;;;
 FBD4;ARABIC LETTER NG FINAL FORM;Lo;0;AL;<final> 06AD;;;;N;;;;;
 FBD5;ARABIC LETTER NG INITIAL FORM;Lo;0;AL;<initial> 06AD;;;;N;;;;;
@@ -16159,6 +16266,22 @@
 FD3D;ARABIC LIGATURE ALEF WITH FATHATAN ISOLATED FORM;Lo;0;AL;<isolated> 0627 064B;;;;N;;;;;
 FD3E;ORNATE LEFT PARENTHESIS;Pe;0;ON;;;;;N;;;;;
 FD3F;ORNATE RIGHT PARENTHESIS;Ps;0;ON;;;;;N;;;;;
+FD40;ARABIC LIGATURE RAHIMAHU ALLAAH;So;0;ON;;;;;N;;;;;
+FD41;ARABIC LIGATURE RADI ALLAAHU ANH;So;0;ON;;;;;N;;;;;
+FD42;ARABIC LIGATURE RADI ALLAAHU ANHAA;So;0;ON;;;;;N;;;;;
+FD43;ARABIC LIGATURE RADI ALLAAHU ANHUM;So;0;ON;;;;;N;;;;;
+FD44;ARABIC LIGATURE RADI ALLAAHU ANHUMAA;So;0;ON;;;;;N;;;;;
+FD45;ARABIC LIGATURE RADI ALLAAHU ANHUNNA;So;0;ON;;;;;N;;;;;
+FD46;ARABIC LIGATURE SALLALLAAHU ALAYHI WA-AALIH;So;0;ON;;;;;N;;;;;
+FD47;ARABIC LIGATURE ALAYHI AS-SALAAM;So;0;ON;;;;;N;;;;;
+FD48;ARABIC LIGATURE ALAYHIM AS-SALAAM;So;0;ON;;;;;N;;;;;
+FD49;ARABIC LIGATURE ALAYHIMAA AS-SALAAM;So;0;ON;;;;;N;;;;;
+FD4A;ARABIC LIGATURE ALAYHI AS-SALAATU WAS-SALAAM;So;0;ON;;;;;N;;;;;
+FD4B;ARABIC LIGATURE QUDDISA SIRRAH;So;0;ON;;;;;N;;;;;
+FD4C;ARABIC LIGATURE SALLALLAHU ALAYHI WAAALIHEE WA-SALLAM;So;0;ON;;;;;N;;;;;
+FD4D;ARABIC LIGATURE ALAYHAA AS-SALAAM;So;0;ON;;;;;N;;;;;
+FD4E;ARABIC LIGATURE TABAARAKA WA-TAAALAA;So;0;ON;;;;;N;;;;;
+FD4F;ARABIC LIGATURE RAHIMAHUM ALLAAH;So;0;ON;;;;;N;;;;;
 FD50;ARABIC LIGATURE TEH WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 062A 062C 0645;;;;N;;;;;
 FD51;ARABIC LIGATURE TEH WITH HAH WITH JEEM FINAL FORM;Lo;0;AL;<final> 062A 062D 062C;;;;N;;;;;
 FD52;ARABIC LIGATURE TEH WITH HAH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 062A 062D 062C;;;;N;;;;;
@@ -16277,6 +16400,7 @@
 FDC5;ARABIC LIGATURE SAD WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0635 0645 0645;;;;N;;;;;
 FDC6;ARABIC LIGATURE SEEN WITH KHAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0633 062E 064A;;;;N;;;;;
 FDC7;ARABIC LIGATURE NOON WITH JEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0646 062C 064A;;;;N;;;;;
+FDCF;ARABIC LIGATURE SALAAMUHU ALAYNAA;So;0;ON;;;;;N;;;;;
 FDF0;ARABIC LIGATURE SALLA USED AS KORANIC STOP SIGN ISOLATED FORM;Lo;0;AL;<isolated> 0635 0644 06D2;;;;N;;;;;
 FDF1;ARABIC LIGATURE QALA USED AS KORANIC STOP SIGN ISOLATED FORM;Lo;0;AL;<isolated> 0642 0644 06D2;;;;N;;;;;
 FDF2;ARABIC LIGATURE ALLAH ISOLATED FORM;Lo;0;AL;<isolated> 0627 0644 0644 0647;;;;N;;;;;
@@ -16291,6 +16415,8 @@
 FDFB;ARABIC LIGATURE JALLAJALALOUHOU;Lo;0;AL;<isolated> 062C 0644 0020 062C 0644 0627 0644 0647;;;;N;ARABIC LETTER JALLAJALALOUHOU;;;;
 FDFC;RIAL SIGN;Sc;0;AL;<isolated> 0631 06CC 0627 0644;;;;N;;;;;
 FDFD;ARABIC LIGATURE BISMILLAH AR-RAHMAN AR-RAHEEM;So;0;ON;;;;;N;;;;;
+FDFE;ARABIC LIGATURE SUBHAANAHU WA TAAALAA;So;0;ON;;;;;N;;;;;
+FDFF;ARABIC LIGATURE AZZA WA JALL;So;0;ON;;;;;N;;;;;
 FE00;VARIATION SELECTOR-1;Mn;0;NSM;;;;;N;;;;;
 FE01;VARIATION SELECTOR-2;Mn;0;NSM;;;;;N;;;;;
 FE02;VARIATION SELECTOR-3;Mn;0;NSM;;;;;N;;;;;
@@ -17798,6 +17924,76 @@
 10562;CAUCASIAN ALBANIAN LETTER PIWR;Lo;0;L;;;;;N;;;;;
 10563;CAUCASIAN ALBANIAN LETTER KIW;Lo;0;L;;;;;N;;;;;
 1056F;CAUCASIAN ALBANIAN CITATION MARK;Po;0;L;;;;;N;;;;;
+10570;VITHKUQI CAPITAL LETTER A;Lu;0;L;;;;;N;;;;10597;
+10571;VITHKUQI CAPITAL LETTER BBE;Lu;0;L;;;;;N;;;;10598;
+10572;VITHKUQI CAPITAL LETTER BE;Lu;0;L;;;;;N;;;;10599;
+10573;VITHKUQI CAPITAL LETTER CE;Lu;0;L;;;;;N;;;;1059A;
+10574;VITHKUQI CAPITAL LETTER CHE;Lu;0;L;;;;;N;;;;1059B;
+10575;VITHKUQI CAPITAL LETTER DE;Lu;0;L;;;;;N;;;;1059C;
+10576;VITHKUQI CAPITAL LETTER DHE;Lu;0;L;;;;;N;;;;1059D;
+10577;VITHKUQI CAPITAL LETTER EI;Lu;0;L;;;;;N;;;;1059E;
+10578;VITHKUQI CAPITAL LETTER E;Lu;0;L;;;;;N;;;;1059F;
+10579;VITHKUQI CAPITAL LETTER FE;Lu;0;L;;;;;N;;;;105A0;
+1057A;VITHKUQI CAPITAL LETTER GA;Lu;0;L;;;;;N;;;;105A1;
+1057C;VITHKUQI CAPITAL LETTER HA;Lu;0;L;;;;;N;;;;105A3;
+1057D;VITHKUQI CAPITAL LETTER HHA;Lu;0;L;;;;;N;;;;105A4;
+1057E;VITHKUQI CAPITAL LETTER I;Lu;0;L;;;;;N;;;;105A5;
+1057F;VITHKUQI CAPITAL LETTER IJE;Lu;0;L;;;;;N;;;;105A6;
+10580;VITHKUQI CAPITAL LETTER JE;Lu;0;L;;;;;N;;;;105A7;
+10581;VITHKUQI CAPITAL LETTER KA;Lu;0;L;;;;;N;;;;105A8;
+10582;VITHKUQI CAPITAL LETTER LA;Lu;0;L;;;;;N;;;;105A9;
+10583;VITHKUQI CAPITAL LETTER LLA;Lu;0;L;;;;;N;;;;105AA;
+10584;VITHKUQI CAPITAL LETTER ME;Lu;0;L;;;;;N;;;;105AB;
+10585;VITHKUQI CAPITAL LETTER NE;Lu;0;L;;;;;N;;;;105AC;
+10586;VITHKUQI CAPITAL LETTER NJE;Lu;0;L;;;;;N;;;;105AD;
+10587;VITHKUQI CAPITAL LETTER O;Lu;0;L;;;;;N;;;;105AE;
+10588;VITHKUQI CAPITAL LETTER PE;Lu;0;L;;;;;N;;;;105AF;
+10589;VITHKUQI CAPITAL LETTER QA;Lu;0;L;;;;;N;;;;105B0;
+1058A;VITHKUQI CAPITAL LETTER RE;Lu;0;L;;;;;N;;;;105B1;
+1058C;VITHKUQI CAPITAL LETTER SE;Lu;0;L;;;;;N;;;;105B3;
+1058D;VITHKUQI CAPITAL LETTER SHE;Lu;0;L;;;;;N;;;;105B4;
+1058E;VITHKUQI CAPITAL LETTER TE;Lu;0;L;;;;;N;;;;105B5;
+1058F;VITHKUQI CAPITAL LETTER THE;Lu;0;L;;;;;N;;;;105B6;
+10590;VITHKUQI CAPITAL LETTER U;Lu;0;L;;;;;N;;;;105B7;
+10591;VITHKUQI CAPITAL LETTER VE;Lu;0;L;;;;;N;;;;105B8;
+10592;VITHKUQI CAPITAL LETTER XE;Lu;0;L;;;;;N;;;;105B9;
+10594;VITHKUQI CAPITAL LETTER Y;Lu;0;L;;;;;N;;;;105BB;
+10595;VITHKUQI CAPITAL LETTER ZE;Lu;0;L;;;;;N;;;;105BC;
+10597;VITHKUQI SMALL LETTER A;Ll;0;L;;;;;N;;;10570;;10570
+10598;VITHKUQI SMALL LETTER BBE;Ll;0;L;;;;;N;;;10571;;10571
+10599;VITHKUQI SMALL LETTER BE;Ll;0;L;;;;;N;;;10572;;10572
+1059A;VITHKUQI SMALL LETTER CE;Ll;0;L;;;;;N;;;10573;;10573
+1059B;VITHKUQI SMALL LETTER CHE;Ll;0;L;;;;;N;;;10574;;10574
+1059C;VITHKUQI SMALL LETTER DE;Ll;0;L;;;;;N;;;10575;;10575
+1059D;VITHKUQI SMALL LETTER DHE;Ll;0;L;;;;;N;;;10576;;10576
+1059E;VITHKUQI SMALL LETTER EI;Ll;0;L;;;;;N;;;10577;;10577
+1059F;VITHKUQI SMALL LETTER E;Ll;0;L;;;;;N;;;10578;;10578
+105A0;VITHKUQI SMALL LETTER FE;Ll;0;L;;;;;N;;;10579;;10579
+105A1;VITHKUQI SMALL LETTER GA;Ll;0;L;;;;;N;;;1057A;;1057A
+105A3;VITHKUQI SMALL LETTER HA;Ll;0;L;;;;;N;;;1057C;;1057C
+105A4;VITHKUQI SMALL LETTER HHA;Ll;0;L;;;;;N;;;1057D;;1057D
+105A5;VITHKUQI SMALL LETTER I;Ll;0;L;;;;;N;;;1057E;;1057E
+105A6;VITHKUQI SMALL LETTER IJE;Ll;0;L;;;;;N;;;1057F;;1057F
+105A7;VITHKUQI SMALL LETTER JE;Ll;0;L;;;;;N;;;10580;;10580
+105A8;VITHKUQI SMALL LETTER KA;Ll;0;L;;;;;N;;;10581;;10581
+105A9;VITHKUQI SMALL LETTER LA;Ll;0;L;;;;;N;;;10582;;10582
+105AA;VITHKUQI SMALL LETTER LLA;Ll;0;L;;;;;N;;;10583;;10583
+105AB;VITHKUQI SMALL LETTER ME;Ll;0;L;;;;;N;;;10584;;10584
+105AC;VITHKUQI SMALL LETTER NE;Ll;0;L;;;;;N;;;10585;;10585
+105AD;VITHKUQI SMALL LETTER NJE;Ll;0;L;;;;;N;;;10586;;10586
+105AE;VITHKUQI SMALL LETTER O;Ll;0;L;;;;;N;;;10587;;10587
+105AF;VITHKUQI SMALL LETTER PE;Ll;0;L;;;;;N;;;10588;;10588
+105B0;VITHKUQI SMALL LETTER QA;Ll;0;L;;;;;N;;;10589;;10589
+105B1;VITHKUQI SMALL LETTER RE;Ll;0;L;;;;;N;;;1058A;;1058A
+105B3;VITHKUQI SMALL LETTER SE;Ll;0;L;;;;;N;;;1058C;;1058C
+105B4;VITHKUQI SMALL LETTER SHE;Ll;0;L;;;;;N;;;1058D;;1058D
+105B5;VITHKUQI SMALL LETTER TE;Ll;0;L;;;;;N;;;1058E;;1058E
+105B6;VITHKUQI SMALL LETTER THE;Ll;0;L;;;;;N;;;1058F;;1058F
+105B7;VITHKUQI SMALL LETTER U;Ll;0;L;;;;;N;;;10590;;10590
+105B8;VITHKUQI SMALL LETTER VE;Ll;0;L;;;;;N;;;10591;;10591
+105B9;VITHKUQI SMALL LETTER XE;Ll;0;L;;;;;N;;;10592;;10592
+105BB;VITHKUQI SMALL LETTER Y;Ll;0;L;;;;;N;;;10594;;10594
+105BC;VITHKUQI SMALL LETTER ZE;Ll;0;L;;;;;N;;;10595;;10595
 10600;LINEAR A SIGN AB001;Lo;0;L;;;;;N;;;;;
 10601;LINEAR A SIGN AB002;Lo;0;L;;;;;N;;;;;
 10602;LINEAR A SIGN AB003;Lo;0;L;;;;;N;;;;;
@@ -18139,6 +18335,63 @@
 10765;LINEAR A SIGN A805;Lo;0;L;;;;;N;;;;;
 10766;LINEAR A SIGN A806;Lo;0;L;;;;;N;;;;;
 10767;LINEAR A SIGN A807;Lo;0;L;;;;;N;;;;;
+10780;MODIFIER LETTER SMALL CAPITAL AA;Lm;0;L;;;;;N;;;;;
+10781;MODIFIER LETTER SUPERSCRIPT TRIANGULAR COLON;Lm;0;L;<super> 02D0;;;;N;;;;;
+10782;MODIFIER LETTER SUPERSCRIPT HALF TRIANGULAR COLON;Lm;0;L;<super> 02D1;;;;N;;;;;
+10783;MODIFIER LETTER SMALL AE;Lm;0;L;<super> 00E6;;;;N;;;;;
+10784;MODIFIER LETTER SMALL CAPITAL B;Lm;0;L;<super> 0299;;;;N;;;;;
+10785;MODIFIER LETTER SMALL B WITH HOOK;Lm;0;L;<super> 0253;;;;N;;;;;
+10787;MODIFIER LETTER SMALL DZ DIGRAPH;Lm;0;L;<super> 02A3;;;;N;;;;;
+10788;MODIFIER LETTER SMALL DZ DIGRAPH WITH RETROFLEX HOOK;Lm;0;L;<super> AB66;;;;N;;;;;
+10789;MODIFIER LETTER SMALL DZ DIGRAPH WITH CURL;Lm;0;L;<super> 02A5;;;;N;;;;;
+1078A;MODIFIER LETTER SMALL DEZH DIGRAPH;Lm;0;L;<super> 02A4;;;;N;;;;;
+1078B;MODIFIER LETTER SMALL D WITH TAIL;Lm;0;L;<super> 0256;;;;N;;;;;
+1078C;MODIFIER LETTER SMALL D WITH HOOK;Lm;0;L;<super> 0257;;;;N;;;;;
+1078D;MODIFIER LETTER SMALL D WITH HOOK AND TAIL;Lm;0;L;<super> 1D91;;;;N;;;;;
+1078E;MODIFIER LETTER SMALL REVERSED E;Lm;0;L;<super> 0258;;;;N;;;;;
+1078F;MODIFIER LETTER SMALL CLOSED REVERSED OPEN E;Lm;0;L;<super> 025E;;;;N;;;;;
+10790;MODIFIER LETTER SMALL FENG DIGRAPH;Lm;0;L;<super> 02A9;;;;N;;;;;
+10791;MODIFIER LETTER SMALL RAMS HORN;Lm;0;L;<super> 0264;;;;N;;;;;
+10792;MODIFIER LETTER SMALL CAPITAL G;Lm;0;L;<super> 0262;;;;N;;;;;
+10793;MODIFIER LETTER SMALL G WITH HOOK;Lm;0;L;<super> 0260;;;;N;;;;;
+10794;MODIFIER LETTER SMALL CAPITAL G WITH HOOK;Lm;0;L;<super> 029B;;;;N;;;;;
+10795;MODIFIER LETTER SMALL H WITH STROKE;Lm;0;L;<super> 0127;;;;N;;;;;
+10796;MODIFIER LETTER SMALL CAPITAL H;Lm;0;L;<super> 029C;;;;N;;;;;
+10797;MODIFIER LETTER SMALL HENG WITH HOOK;Lm;0;L;<super> 0267;;;;N;;;;;
+10798;MODIFIER LETTER SMALL DOTLESS J WITH STROKE AND HOOK;Lm;0;L;<super> 0284;;;;N;;;;;
+10799;MODIFIER LETTER SMALL LS DIGRAPH;Lm;0;L;<super> 02AA;;;;N;;;;;
+1079A;MODIFIER LETTER SMALL LZ DIGRAPH;Lm;0;L;<super> 02AB;;;;N;;;;;
+1079B;MODIFIER LETTER SMALL L WITH BELT;Lm;0;L;<super> 026C;;;;N;;;;;
+1079C;MODIFIER LETTER SMALL CAPITAL L WITH BELT;Lm;0;L;<super> 1DF04;;;;N;;;;;
+1079D;MODIFIER LETTER SMALL L WITH RETROFLEX HOOK AND BELT;Lm;0;L;<super> A78E;;;;N;;;;;
+1079E;MODIFIER LETTER SMALL LEZH;Lm;0;L;<super> 026E;;;;N;;;;;
+1079F;MODIFIER LETTER SMALL LEZH WITH RETROFLEX HOOK;Lm;0;L;<super> 1DF05;;;;N;;;;;
+107A0;MODIFIER LETTER SMALL TURNED Y;Lm;0;L;<super> 028E;;;;N;;;;;
+107A1;MODIFIER LETTER SMALL TURNED Y WITH BELT;Lm;0;L;<super> 1DF06;;;;N;;;;;
+107A2;MODIFIER LETTER SMALL O WITH STROKE;Lm;0;L;<super> 00F8;;;;N;;;;;
+107A3;MODIFIER LETTER SMALL CAPITAL OE;Lm;0;L;<super> 0276;;;;N;;;;;
+107A4;MODIFIER LETTER SMALL CLOSED OMEGA;Lm;0;L;<super> 0277;;;;N;;;;;
+107A5;MODIFIER LETTER SMALL Q;Lm;0;L;<super> 0071;;;;N;;;;;
+107A6;MODIFIER LETTER SMALL TURNED R WITH LONG LEG;Lm;0;L;<super> 027A;;;;N;;;;;
+107A7;MODIFIER LETTER SMALL TURNED R WITH LONG LEG AND RETROFLEX HOOK;Lm;0;L;<super> 1DF08;;;;N;;;;;
+107A8;MODIFIER LETTER SMALL R WITH TAIL;Lm;0;L;<super> 027D;;;;N;;;;;
+107A9;MODIFIER LETTER SMALL R WITH FISHHOOK;Lm;0;L;<super> 027E;;;;N;;;;;
+107AA;MODIFIER LETTER SMALL CAPITAL R;Lm;0;L;<super> 0280;;;;N;;;;;
+107AB;MODIFIER LETTER SMALL TC DIGRAPH WITH CURL;Lm;0;L;<super> 02A8;;;;N;;;;;
+107AC;MODIFIER LETTER SMALL TS DIGRAPH;Lm;0;L;<super> 02A6;;;;N;;;;;
+107AD;MODIFIER LETTER SMALL TS DIGRAPH WITH RETROFLEX HOOK;Lm;0;L;<super> AB67;;;;N;;;;;
+107AE;MODIFIER LETTER SMALL TESH DIGRAPH;Lm;0;L;<super> 02A7;;;;N;;;;;
+107AF;MODIFIER LETTER SMALL T WITH RETROFLEX HOOK;Lm;0;L;<super> 0288;;;;N;;;;;
+107B0;MODIFIER LETTER SMALL V WITH RIGHT HOOK;Lm;0;L;<super> 2C71;;;;N;;;;;
+107B2;MODIFIER LETTER SMALL CAPITAL Y;Lm;0;L;<super> 028F;;;;N;;;;;
+107B3;MODIFIER LETTER GLOTTAL STOP WITH STROKE;Lm;0;L;<super> 02A1;;;;N;;;;;
+107B4;MODIFIER LETTER REVERSED GLOTTAL STOP WITH STROKE;Lm;0;L;<super> 02A2;;;;N;;;;;
+107B5;MODIFIER LETTER BILABIAL CLICK;Lm;0;L;<super> 0298;;;;N;;;;;
+107B6;MODIFIER LETTER DENTAL CLICK;Lm;0;L;<super> 01C0;;;;N;;;;;
+107B7;MODIFIER LETTER LATERAL CLICK;Lm;0;L;<super> 01C1;;;;N;;;;;
+107B8;MODIFIER LETTER ALVEOLAR CLICK;Lm;0;L;<super> 01C2;;;;N;;;;;
+107B9;MODIFIER LETTER RETROFLEX CLICK WITH RETROFLEX HOOK;Lm;0;L;<super> 1DF0A;;;;N;;;;;
+107BA;MODIFIER LETTER SMALL S WITH CURL;Lm;0;L;<super> 1DF1E;;;;N;;;;;
 10800;CYPRIOT SYLLABLE A;Lo;0;R;;;;;N;;;;;
 10801;CYPRIOT SYLLABLE E;Lo;0;R;;;;;N;;;;;
 10802;CYPRIOT SYLLABLE I;Lo;0;R;;;;;N;;;;;
@@ -19222,6 +19475,32 @@
 10F57;SOGDIAN PUNCTUATION CIRCLE WITH DOT;Po;0;AL;;;;;N;;;;;
 10F58;SOGDIAN PUNCTUATION TWO CIRCLES WITH DOTS;Po;0;AL;;;;;N;;;;;
 10F59;SOGDIAN PUNCTUATION HALF CIRCLE WITH DOT;Po;0;AL;;;;;N;;;;;
+10F70;OLD UYGHUR LETTER ALEPH;Lo;0;R;;;;;N;;;;;
+10F71;OLD UYGHUR LETTER BETH;Lo;0;R;;;;;N;;;;;
+10F72;OLD UYGHUR LETTER GIMEL-HETH;Lo;0;R;;;;;N;;;;;
+10F73;OLD UYGHUR LETTER WAW;Lo;0;R;;;;;N;;;;;
+10F74;OLD UYGHUR LETTER ZAYIN;Lo;0;R;;;;;N;;;;;
+10F75;OLD UYGHUR LETTER FINAL HETH;Lo;0;R;;;;;N;;;;;
+10F76;OLD UYGHUR LETTER YODH;Lo;0;R;;;;;N;;;;;
+10F77;OLD UYGHUR LETTER KAPH;Lo;0;R;;;;;N;;;;;
+10F78;OLD UYGHUR LETTER LAMEDH;Lo;0;R;;;;;N;;;;;
+10F79;OLD UYGHUR LETTER MEM;Lo;0;R;;;;;N;;;;;
+10F7A;OLD UYGHUR LETTER NUN;Lo;0;R;;;;;N;;;;;
+10F7B;OLD UYGHUR LETTER SAMEKH;Lo;0;R;;;;;N;;;;;
+10F7C;OLD UYGHUR LETTER PE;Lo;0;R;;;;;N;;;;;
+10F7D;OLD UYGHUR LETTER SADHE;Lo;0;R;;;;;N;;;;;
+10F7E;OLD UYGHUR LETTER RESH;Lo;0;R;;;;;N;;;;;
+10F7F;OLD UYGHUR LETTER SHIN;Lo;0;R;;;;;N;;;;;
+10F80;OLD UYGHUR LETTER TAW;Lo;0;R;;;;;N;;;;;
+10F81;OLD UYGHUR LETTER LESH;Lo;0;R;;;;;N;;;;;
+10F82;OLD UYGHUR COMBINING DOT ABOVE;Mn;230;NSM;;;;;N;;;;;
+10F83;OLD UYGHUR COMBINING DOT BELOW;Mn;220;NSM;;;;;N;;;;;
+10F84;OLD UYGHUR COMBINING TWO DOTS ABOVE;Mn;230;NSM;;;;;N;;;;;
+10F85;OLD UYGHUR COMBINING TWO DOTS BELOW;Mn;220;NSM;;;;;N;;;;;
+10F86;OLD UYGHUR PUNCTUATION BAR;Po;0;R;;;;;N;;;;;
+10F87;OLD UYGHUR PUNCTUATION TWO BARS;Po;0;R;;;;;N;;;;;
+10F88;OLD UYGHUR PUNCTUATION TWO DOTS;Po;0;R;;;;;N;;;;;
+10F89;OLD UYGHUR PUNCTUATION FOUR DOTS;Po;0;R;;;;;N;;;;;
 10FB0;CHORASMIAN LETTER ALEPH;Lo;0;R;;;;;N;;;;;
 10FB1;CHORASMIAN LETTER SMALL ALEPH;Lo;0;R;;;;;N;;;;;
 10FB2;CHORASMIAN LETTER BETH;Lo;0;R;;;;;N;;;;;
@@ -19381,6 +19660,12 @@
 1106D;BRAHMI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
 1106E;BRAHMI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
 1106F;BRAHMI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+11070;BRAHMI SIGN OLD TAMIL VIRAMA;Mn;9;NSM;;;;;N;;;;;
+11071;BRAHMI LETTER OLD TAMIL SHORT E;Lo;0;L;;;;;N;;;;;
+11072;BRAHMI LETTER OLD TAMIL SHORT O;Lo;0;L;;;;;N;;;;;
+11073;BRAHMI VOWEL SIGN OLD TAMIL SHORT E;Mn;0;NSM;;;;;N;;;;;
+11074;BRAHMI VOWEL SIGN OLD TAMIL SHORT O;Mn;0;NSM;;;;;N;;;;;
+11075;BRAHMI LETTER OLD TAMIL LLA;Lo;0;L;;;;;N;;;;;
 1107F;BRAHMI NUMBER JOINER;Mn;9;NSM;;;;;N;;;;;
 11080;KAITHI SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
 11081;KAITHI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
@@ -19448,6 +19733,7 @@
 110BF;KAITHI DOUBLE SECTION MARK;Po;0;L;;;;;N;;;;;
 110C0;KAITHI DANDA;Po;0;L;;;;;N;;;;;
 110C1;KAITHI DOUBLE DANDA;Po;0;L;;;;;N;;;;;
+110C2;KAITHI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;
 110CD;KAITHI NUMBER SIGN ABOVE;Cf;0;L;;;;;N;;;;;
 110D0;SORA SOMPENG LETTER SAH;Lo;0;L;;;;;N;;;;;
 110D1;SORA SOMPENG LETTER TAH;Lo;0;L;;;;;N;;;;;
@@ -20385,6 +20671,7 @@
 116B6;TAKRI SIGN VIRAMA;Mc;9;L;;;;;N;;;;;
 116B7;TAKRI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
 116B8;TAKRI LETTER ARCHAIC KHA;Lo;0;L;;;;;N;;;;;
+116B9;TAKRI ABBREVIATION SIGN;Po;0;L;;;;;N;;;;;
 116C0;TAKRI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
 116C1;TAKRI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
 116C2;TAKRI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
@@ -20453,6 +20740,13 @@
 1173D;AHOM SIGN SECTION;Po;0;L;;;;;N;;;;;
 1173E;AHOM SIGN RULAI;Po;0;L;;;;;N;;;;;
 1173F;AHOM SYMBOL VI;So;0;L;;;;;N;;;;;
+11740;AHOM LETTER CA;Lo;0;L;;;;;N;;;;;
+11741;AHOM LETTER TTA;Lo;0;L;;;;;N;;;;;
+11742;AHOM LETTER TTHA;Lo;0;L;;;;;N;;;;;
+11743;AHOM LETTER DDA;Lo;0;L;;;;;N;;;;;
+11744;AHOM LETTER DDHA;Lo;0;L;;;;;N;;;;;
+11745;AHOM LETTER NNA;Lo;0;L;;;;;N;;;;;
+11746;AHOM LETTER LLA;Lo;0;L;;;;;N;;;;;
 11800;DOGRA LETTER A;Lo;0;L;;;;;N;;;;;
 11801;DOGRA LETTER AA;Lo;0;L;;;;;N;;;;;
 11802;DOGRA LETTER I;Lo;0;L;;;;;N;;;;;
@@ -20889,6 +21183,22 @@
 11AA0;SOYOMBO HEAD MARK WITH MOON AND SUN;Po;0;L;;;;;N;;;;;
 11AA1;SOYOMBO TERMINAL MARK-1;Po;0;L;;;;;N;;;;;
 11AA2;SOYOMBO TERMINAL MARK-2;Po;0;L;;;;;N;;;;;
+11AB0;CANADIAN SYLLABICS NATTILIK HI;Lo;0;L;;;;;N;;;;;
+11AB1;CANADIAN SYLLABICS NATTILIK HII;Lo;0;L;;;;;N;;;;;
+11AB2;CANADIAN SYLLABICS NATTILIK HO;Lo;0;L;;;;;N;;;;;
+11AB3;CANADIAN SYLLABICS NATTILIK HOO;Lo;0;L;;;;;N;;;;;
+11AB4;CANADIAN SYLLABICS NATTILIK HA;Lo;0;L;;;;;N;;;;;
+11AB5;CANADIAN SYLLABICS NATTILIK HAA;Lo;0;L;;;;;N;;;;;
+11AB6;CANADIAN SYLLABICS NATTILIK SHRI;Lo;0;L;;;;;N;;;;;
+11AB7;CANADIAN SYLLABICS NATTILIK SHRII;Lo;0;L;;;;;N;;;;;
+11AB8;CANADIAN SYLLABICS NATTILIK SHRO;Lo;0;L;;;;;N;;;;;
+11AB9;CANADIAN SYLLABICS NATTILIK SHROO;Lo;0;L;;;;;N;;;;;
+11ABA;CANADIAN SYLLABICS NATTILIK SHRA;Lo;0;L;;;;;N;;;;;
+11ABB;CANADIAN SYLLABICS NATTILIK SHRAA;Lo;0;L;;;;;N;;;;;
+11ABC;CANADIAN SYLLABICS SPE;Lo;0;L;;;;;N;;;;;
+11ABD;CANADIAN SYLLABICS SPI;Lo;0;L;;;;;N;;;;;
+11ABE;CANADIAN SYLLABICS SPO;Lo;0;L;;;;;N;;;;;
+11ABF;CANADIAN SYLLABICS SPA;Lo;0;L;;;;;N;;;;;
 11AC0;PAU CIN HAU LETTER PA;Lo;0;L;;;;;N;;;;;
 11AC1;PAU CIN HAU LETTER KA;Lo;0;L;;;;;N;;;;;
 11AC2;PAU CIN HAU LETTER LA;Lo;0;L;;;;;N;;;;;
@@ -22560,6 +22870,105 @@
 12541;CUNEIFORM SIGN ZA7;Lo;0;L;;;;;N;;;;;
 12542;CUNEIFORM SIGN ZU OVER ZU PLUS SAR;Lo;0;L;;;;;N;;;;;
 12543;CUNEIFORM SIGN ZU5 TIMES THREE DISH TENU;Lo;0;L;;;;;N;;;;;
+12F90;CYPRO-MINOAN SIGN CM001;Lo;0;L;;;;;N;;;;;
+12F91;CYPRO-MINOAN SIGN CM002;Lo;0;L;;;;;N;;;;;
+12F92;CYPRO-MINOAN SIGN CM004;Lo;0;L;;;;;N;;;;;
+12F93;CYPRO-MINOAN SIGN CM005;Lo;0;L;;;;;N;;;;;
+12F94;CYPRO-MINOAN SIGN CM006;Lo;0;L;;;;;N;;;;;
+12F95;CYPRO-MINOAN SIGN CM007;Lo;0;L;;;;;N;;;;;
+12F96;CYPRO-MINOAN SIGN CM008;Lo;0;L;;;;;N;;;;;
+12F97;CYPRO-MINOAN SIGN CM009;Lo;0;L;;;;;N;;;;;
+12F98;CYPRO-MINOAN SIGN CM010;Lo;0;L;;;;;N;;;;;
+12F99;CYPRO-MINOAN SIGN CM011;Lo;0;L;;;;;N;;;;;
+12F9A;CYPRO-MINOAN SIGN CM012;Lo;0;L;;;;;N;;;;;
+12F9B;CYPRO-MINOAN SIGN CM012B;Lo;0;L;;;;;N;;;;;
+12F9C;CYPRO-MINOAN SIGN CM013;Lo;0;L;;;;;N;;;;;
+12F9D;CYPRO-MINOAN SIGN CM015;Lo;0;L;;;;;N;;;;;
+12F9E;CYPRO-MINOAN SIGN CM017;Lo;0;L;;;;;N;;;;;
+12F9F;CYPRO-MINOAN SIGN CM019;Lo;0;L;;;;;N;;;;;
+12FA0;CYPRO-MINOAN SIGN CM021;Lo;0;L;;;;;N;;;;;
+12FA1;CYPRO-MINOAN SIGN CM023;Lo;0;L;;;;;N;;;;;
+12FA2;CYPRO-MINOAN SIGN CM024;Lo;0;L;;;;;N;;;;;
+12FA3;CYPRO-MINOAN SIGN CM025;Lo;0;L;;;;;N;;;;;
+12FA4;CYPRO-MINOAN SIGN CM026;Lo;0;L;;;;;N;;;;;
+12FA5;CYPRO-MINOAN SIGN CM027;Lo;0;L;;;;;N;;;;;
+12FA6;CYPRO-MINOAN SIGN CM028;Lo;0;L;;;;;N;;;;;
+12FA7;CYPRO-MINOAN SIGN CM029;Lo;0;L;;;;;N;;;;;
+12FA8;CYPRO-MINOAN SIGN CM030;Lo;0;L;;;;;N;;;;;
+12FA9;CYPRO-MINOAN SIGN CM033;Lo;0;L;;;;;N;;;;;
+12FAA;CYPRO-MINOAN SIGN CM034;Lo;0;L;;;;;N;;;;;
+12FAB;CYPRO-MINOAN SIGN CM035;Lo;0;L;;;;;N;;;;;
+12FAC;CYPRO-MINOAN SIGN CM036;Lo;0;L;;;;;N;;;;;
+12FAD;CYPRO-MINOAN SIGN CM037;Lo;0;L;;;;;N;;;;;
+12FAE;CYPRO-MINOAN SIGN CM038;Lo;0;L;;;;;N;;;;;
+12FAF;CYPRO-MINOAN SIGN CM039;Lo;0;L;;;;;N;;;;;
+12FB0;CYPRO-MINOAN SIGN CM040;Lo;0;L;;;;;N;;;;;
+12FB1;CYPRO-MINOAN SIGN CM041;Lo;0;L;;;;;N;;;;;
+12FB2;CYPRO-MINOAN SIGN CM044;Lo;0;L;;;;;N;;;;;
+12FB3;CYPRO-MINOAN SIGN CM046;Lo;0;L;;;;;N;;;;;
+12FB4;CYPRO-MINOAN SIGN CM047;Lo;0;L;;;;;N;;;;;
+12FB5;CYPRO-MINOAN SIGN CM049;Lo;0;L;;;;;N;;;;;
+12FB6;CYPRO-MINOAN SIGN CM050;Lo;0;L;;;;;N;;;;;
+12FB7;CYPRO-MINOAN SIGN CM051;Lo;0;L;;;;;N;;;;;
+12FB8;CYPRO-MINOAN SIGN CM052;Lo;0;L;;;;;N;;;;;
+12FB9;CYPRO-MINOAN SIGN CM053;Lo;0;L;;;;;N;;;;;
+12FBA;CYPRO-MINOAN SIGN CM054;Lo;0;L;;;;;N;;;;;
+12FBB;CYPRO-MINOAN SIGN CM055;Lo;0;L;;;;;N;;;;;
+12FBC;CYPRO-MINOAN SIGN CM056;Lo;0;L;;;;;N;;;;;
+12FBD;CYPRO-MINOAN SIGN CM058;Lo;0;L;;;;;N;;;;;
+12FBE;CYPRO-MINOAN SIGN CM059;Lo;0;L;;;;;N;;;;;
+12FBF;CYPRO-MINOAN SIGN CM060;Lo;0;L;;;;;N;;;;;
+12FC0;CYPRO-MINOAN SIGN CM061;Lo;0;L;;;;;N;;;;;
+12FC1;CYPRO-MINOAN SIGN CM062;Lo;0;L;;;;;N;;;;;
+12FC2;CYPRO-MINOAN SIGN CM063;Lo;0;L;;;;;N;;;;;
+12FC3;CYPRO-MINOAN SIGN CM064;Lo;0;L;;;;;N;;;;;
+12FC4;CYPRO-MINOAN SIGN CM066;Lo;0;L;;;;;N;;;;;
+12FC5;CYPRO-MINOAN SIGN CM067;Lo;0;L;;;;;N;;;;;
+12FC6;CYPRO-MINOAN SIGN CM068;Lo;0;L;;;;;N;;;;;
+12FC7;CYPRO-MINOAN SIGN CM069;Lo;0;L;;;;;N;;;;;
+12FC8;CYPRO-MINOAN SIGN CM070;Lo;0;L;;;;;N;;;;;
+12FC9;CYPRO-MINOAN SIGN CM071;Lo;0;L;;;;;N;;;;;
+12FCA;CYPRO-MINOAN SIGN CM072;Lo;0;L;;;;;N;;;;;
+12FCB;CYPRO-MINOAN SIGN CM073;Lo;0;L;;;;;N;;;;;
+12FCC;CYPRO-MINOAN SIGN CM074;Lo;0;L;;;;;N;;;;;
+12FCD;CYPRO-MINOAN SIGN CM075;Lo;0;L;;;;;N;;;;;
+12FCE;CYPRO-MINOAN SIGN CM075B;Lo;0;L;;;;;N;;;;;
+12FCF;CYPRO-MINOAN SIGN CM076;Lo;0;L;;;;;N;;;;;
+12FD0;CYPRO-MINOAN SIGN CM078;Lo;0;L;;;;;N;;;;;
+12FD1;CYPRO-MINOAN SIGN CM079;Lo;0;L;;;;;N;;;;;
+12FD2;CYPRO-MINOAN SIGN CM080;Lo;0;L;;;;;N;;;;;
+12FD3;CYPRO-MINOAN SIGN CM081;Lo;0;L;;;;;N;;;;;
+12FD4;CYPRO-MINOAN SIGN CM082;Lo;0;L;;;;;N;;;;;
+12FD5;CYPRO-MINOAN SIGN CM083;Lo;0;L;;;;;N;;;;;
+12FD6;CYPRO-MINOAN SIGN CM084;Lo;0;L;;;;;N;;;;;
+12FD7;CYPRO-MINOAN SIGN CM085;Lo;0;L;;;;;N;;;;;
+12FD8;CYPRO-MINOAN SIGN CM086;Lo;0;L;;;;;N;;;;;
+12FD9;CYPRO-MINOAN SIGN CM087;Lo;0;L;;;;;N;;;;;
+12FDA;CYPRO-MINOAN SIGN CM088;Lo;0;L;;;;;N;;;;;
+12FDB;CYPRO-MINOAN SIGN CM089;Lo;0;L;;;;;N;;;;;
+12FDC;CYPRO-MINOAN SIGN CM090;Lo;0;L;;;;;N;;;;;
+12FDD;CYPRO-MINOAN SIGN CM091;Lo;0;L;;;;;N;;;;;
+12FDE;CYPRO-MINOAN SIGN CM092;Lo;0;L;;;;;N;;;;;
+12FDF;CYPRO-MINOAN SIGN CM094;Lo;0;L;;;;;N;;;;;
+12FE0;CYPRO-MINOAN SIGN CM095;Lo;0;L;;;;;N;;;;;
+12FE1;CYPRO-MINOAN SIGN CM096;Lo;0;L;;;;;N;;;;;
+12FE2;CYPRO-MINOAN SIGN CM097;Lo;0;L;;;;;N;;;;;
+12FE3;CYPRO-MINOAN SIGN CM098;Lo;0;L;;;;;N;;;;;
+12FE4;CYPRO-MINOAN SIGN CM099;Lo;0;L;;;;;N;;;;;
+12FE5;CYPRO-MINOAN SIGN CM100;Lo;0;L;;;;;N;;;;;
+12FE6;CYPRO-MINOAN SIGN CM101;Lo;0;L;;;;;N;;;;;
+12FE7;CYPRO-MINOAN SIGN CM102;Lo;0;L;;;;;N;;;;;
+12FE8;CYPRO-MINOAN SIGN CM103;Lo;0;L;;;;;N;;;;;
+12FE9;CYPRO-MINOAN SIGN CM104;Lo;0;L;;;;;N;;;;;
+12FEA;CYPRO-MINOAN SIGN CM105;Lo;0;L;;;;;N;;;;;
+12FEB;CYPRO-MINOAN SIGN CM107;Lo;0;L;;;;;N;;;;;
+12FEC;CYPRO-MINOAN SIGN CM108;Lo;0;L;;;;;N;;;;;
+12FED;CYPRO-MINOAN SIGN CM109;Lo;0;L;;;;;N;;;;;
+12FEE;CYPRO-MINOAN SIGN CM110;Lo;0;L;;;;;N;;;;;
+12FEF;CYPRO-MINOAN SIGN CM112;Lo;0;L;;;;;N;;;;;
+12FF0;CYPRO-MINOAN SIGN CM114;Lo;0;L;;;;;N;;;;;
+12FF1;CYPRO-MINOAN SIGN CM301;Po;0;L;;;;;N;;;;;
+12FF2;CYPRO-MINOAN SIGN CM302;Po;0;L;;;;;N;;;;;
 13000;EGYPTIAN HIEROGLYPH A001;Lo;0;L;;;;;N;;;;;
 13001;EGYPTIAN HIEROGLYPH A002;Lo;0;L;;;;;N;;;;;
 13002;EGYPTIAN HIEROGLYPH A003;Lo;0;L;;;;;N;;;;;
@@ -24835,6 +25244,95 @@
 16A69;MRO DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
 16A6E;MRO DANDA;Po;0;L;;;;;N;;;;;
 16A6F;MRO DOUBLE DANDA;Po;0;L;;;;;N;;;;;
+16A70;TANGSA LETTER OZ;Lo;0;L;;;;;N;;;;;
+16A71;TANGSA LETTER OC;Lo;0;L;;;;;N;;;;;
+16A72;TANGSA LETTER OQ;Lo;0;L;;;;;N;;;;;
+16A73;TANGSA LETTER OX;Lo;0;L;;;;;N;;;;;
+16A74;TANGSA LETTER AZ;Lo;0;L;;;;;N;;;;;
+16A75;TANGSA LETTER AC;Lo;0;L;;;;;N;;;;;
+16A76;TANGSA LETTER AQ;Lo;0;L;;;;;N;;;;;
+16A77;TANGSA LETTER AX;Lo;0;L;;;;;N;;;;;
+16A78;TANGSA LETTER VZ;Lo;0;L;;;;;N;;;;;
+16A79;TANGSA LETTER VC;Lo;0;L;;;;;N;;;;;
+16A7A;TANGSA LETTER VQ;Lo;0;L;;;;;N;;;;;
+16A7B;TANGSA LETTER VX;Lo;0;L;;;;;N;;;;;
+16A7C;TANGSA LETTER EZ;Lo;0;L;;;;;N;;;;;
+16A7D;TANGSA LETTER EC;Lo;0;L;;;;;N;;;;;
+16A7E;TANGSA LETTER EQ;Lo;0;L;;;;;N;;;;;
+16A7F;TANGSA LETTER EX;Lo;0;L;;;;;N;;;;;
+16A80;TANGSA LETTER IZ;Lo;0;L;;;;;N;;;;;
+16A81;TANGSA LETTER IC;Lo;0;L;;;;;N;;;;;
+16A82;TANGSA LETTER IQ;Lo;0;L;;;;;N;;;;;
+16A83;TANGSA LETTER IX;Lo;0;L;;;;;N;;;;;
+16A84;TANGSA LETTER UZ;Lo;0;L;;;;;N;;;;;
+16A85;TANGSA LETTER UC;Lo;0;L;;;;;N;;;;;
+16A86;TANGSA LETTER UQ;Lo;0;L;;;;;N;;;;;
+16A87;TANGSA LETTER UX;Lo;0;L;;;;;N;;;;;
+16A88;TANGSA LETTER AWZ;Lo;0;L;;;;;N;;;;;
+16A89;TANGSA LETTER AWC;Lo;0;L;;;;;N;;;;;
+16A8A;TANGSA LETTER AWQ;Lo;0;L;;;;;N;;;;;
+16A8B;TANGSA LETTER AWX;Lo;0;L;;;;;N;;;;;
+16A8C;TANGSA LETTER UIZ;Lo;0;L;;;;;N;;;;;
+16A8D;TANGSA LETTER UIC;Lo;0;L;;;;;N;;;;;
+16A8E;TANGSA LETTER UIQ;Lo;0;L;;;;;N;;;;;
+16A8F;TANGSA LETTER UIX;Lo;0;L;;;;;N;;;;;
+16A90;TANGSA LETTER FINAL NG;Lo;0;L;;;;;N;;;;;
+16A91;TANGSA LETTER LONG UEX;Lo;0;L;;;;;N;;;;;
+16A92;TANGSA LETTER SHORT UEZ;Lo;0;L;;;;;N;;;;;
+16A93;TANGSA LETTER SHORT AWX;Lo;0;L;;;;;N;;;;;
+16A94;TANGSA LETTER UEC;Lo;0;L;;;;;N;;;;;
+16A95;TANGSA LETTER UEZ;Lo;0;L;;;;;N;;;;;
+16A96;TANGSA LETTER UEQ;Lo;0;L;;;;;N;;;;;
+16A97;TANGSA LETTER UEX;Lo;0;L;;;;;N;;;;;
+16A98;TANGSA LETTER UIUZ;Lo;0;L;;;;;N;;;;;
+16A99;TANGSA LETTER UIUC;Lo;0;L;;;;;N;;;;;
+16A9A;TANGSA LETTER UIUQ;Lo;0;L;;;;;N;;;;;
+16A9B;TANGSA LETTER UIUX;Lo;0;L;;;;;N;;;;;
+16A9C;TANGSA LETTER MZ;Lo;0;L;;;;;N;;;;;
+16A9D;TANGSA LETTER MC;Lo;0;L;;;;;N;;;;;
+16A9E;TANGSA LETTER MQ;Lo;0;L;;;;;N;;;;;
+16A9F;TANGSA LETTER MX;Lo;0;L;;;;;N;;;;;
+16AA0;TANGSA LETTER KA;Lo;0;L;;;;;N;;;;;
+16AA1;TANGSA LETTER KHA;Lo;0;L;;;;;N;;;;;
+16AA2;TANGSA LETTER GA;Lo;0;L;;;;;N;;;;;
+16AA3;TANGSA LETTER NGA;Lo;0;L;;;;;N;;;;;
+16AA4;TANGSA LETTER SA;Lo;0;L;;;;;N;;;;;
+16AA5;TANGSA LETTER YA;Lo;0;L;;;;;N;;;;;
+16AA6;TANGSA LETTER WA;Lo;0;L;;;;;N;;;;;
+16AA7;TANGSA LETTER PA;Lo;0;L;;;;;N;;;;;
+16AA8;TANGSA LETTER NYA;Lo;0;L;;;;;N;;;;;
+16AA9;TANGSA LETTER PHA;Lo;0;L;;;;;N;;;;;
+16AAA;TANGSA LETTER BA;Lo;0;L;;;;;N;;;;;
+16AAB;TANGSA LETTER MA;Lo;0;L;;;;;N;;;;;
+16AAC;TANGSA LETTER NA;Lo;0;L;;;;;N;;;;;
+16AAD;TANGSA LETTER HA;Lo;0;L;;;;;N;;;;;
+16AAE;TANGSA LETTER LA;Lo;0;L;;;;;N;;;;;
+16AAF;TANGSA LETTER HTA;Lo;0;L;;;;;N;;;;;
+16AB0;TANGSA LETTER TA;Lo;0;L;;;;;N;;;;;
+16AB1;TANGSA LETTER DA;Lo;0;L;;;;;N;;;;;
+16AB2;TANGSA LETTER RA;Lo;0;L;;;;;N;;;;;
+16AB3;TANGSA LETTER NHA;Lo;0;L;;;;;N;;;;;
+16AB4;TANGSA LETTER SHA;Lo;0;L;;;;;N;;;;;
+16AB5;TANGSA LETTER CA;Lo;0;L;;;;;N;;;;;
+16AB6;TANGSA LETTER TSA;Lo;0;L;;;;;N;;;;;
+16AB7;TANGSA LETTER GHA;Lo;0;L;;;;;N;;;;;
+16AB8;TANGSA LETTER HTTA;Lo;0;L;;;;;N;;;;;
+16AB9;TANGSA LETTER THA;Lo;0;L;;;;;N;;;;;
+16ABA;TANGSA LETTER XA;Lo;0;L;;;;;N;;;;;
+16ABB;TANGSA LETTER FA;Lo;0;L;;;;;N;;;;;
+16ABC;TANGSA LETTER DHA;Lo;0;L;;;;;N;;;;;
+16ABD;TANGSA LETTER CHA;Lo;0;L;;;;;N;;;;;
+16ABE;TANGSA LETTER ZA;Lo;0;L;;;;;N;;;;;
+16AC0;TANGSA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+16AC1;TANGSA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+16AC2;TANGSA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+16AC3;TANGSA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+16AC4;TANGSA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+16AC5;TANGSA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+16AC6;TANGSA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+16AC7;TANGSA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+16AC8;TANGSA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+16AC9;TANGSA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
 16AD0;BASSA VAH LETTER ENNI;Lo;0;L;;;;;N;;;;;
 16AD1;BASSA VAH LETTER KA;Lo;0;L;;;;;N;;;;;
 16AD2;BASSA VAH LETTER SE;Lo;0;L;;;;;N;;;;;
@@ -26487,6 +26985,19 @@
 18CD5;KHITAN SMALL SCRIPT CHARACTER-18CD5;Lo;0;L;;;;;N;;;;;
 18D00;<Tangut Ideograph Supplement, First>;Lo;0;L;;;;;N;;;;;
 18D08;<Tangut Ideograph Supplement, Last>;Lo;0;L;;;;;N;;;;;
+1AFF0;KATAKANA LETTER MINNAN TONE-2;Lm;0;L;;;;;N;;;;;
+1AFF1;KATAKANA LETTER MINNAN TONE-3;Lm;0;L;;;;;N;;;;;
+1AFF2;KATAKANA LETTER MINNAN TONE-4;Lm;0;L;;;;;N;;;;;
+1AFF3;KATAKANA LETTER MINNAN TONE-5;Lm;0;L;;;;;N;;;;;
+1AFF5;KATAKANA LETTER MINNAN TONE-7;Lm;0;L;;;;;N;;;;;
+1AFF6;KATAKANA LETTER MINNAN TONE-8;Lm;0;L;;;;;N;;;;;
+1AFF7;KATAKANA LETTER MINNAN NASALIZED TONE-1;Lm;0;L;;;;;N;;;;;
+1AFF8;KATAKANA LETTER MINNAN NASALIZED TONE-2;Lm;0;L;;;;;N;;;;;
+1AFF9;KATAKANA LETTER MINNAN NASALIZED TONE-3;Lm;0;L;;;;;N;;;;;
+1AFFA;KATAKANA LETTER MINNAN NASALIZED TONE-4;Lm;0;L;;;;;N;;;;;
+1AFFB;KATAKANA LETTER MINNAN NASALIZED TONE-5;Lm;0;L;;;;;N;;;;;
+1AFFD;KATAKANA LETTER MINNAN NASALIZED TONE-7;Lm;0;L;;;;;N;;;;;
+1AFFE;KATAKANA LETTER MINNAN NASALIZED TONE-8;Lm;0;L;;;;;N;;;;;
 1B000;KATAKANA LETTER ARCHAIC E;Lo;0;L;;;;;N;;;;;
 1B001;HIRAGANA LETTER ARCHAIC YE;Lo;0;L;;;;;N;;;;;
 1B002;HENTAIGANA LETTER A-1;Lo;0;L;;;;;N;;;;;
@@ -26774,6 +27285,10 @@
 1B11C;HENTAIGANA LETTER WO-7;Lo;0;L;;;;;N;;;;;
 1B11D;HENTAIGANA LETTER N-MU-MO-1;Lo;0;L;;;;;N;;;;;
 1B11E;HENTAIGANA LETTER N-MU-MO-2;Lo;0;L;;;;;N;;;;;
+1B11F;HIRAGANA LETTER ARCHAIC WU;Lo;0;L;;;;;N;;;;;
+1B120;KATAKANA LETTER ARCHAIC YI;Lo;0;L;;;;;N;;;;;
+1B121;KATAKANA LETTER ARCHAIC YE;Lo;0;L;;;;;N;;;;;
+1B122;KATAKANA LETTER ARCHAIC WU;Lo;0;L;;;;;N;;;;;
 1B150;HIRAGANA LETTER SMALL WI;Lo;0;L;;;;;N;;;;;
 1B151;HIRAGANA LETTER SMALL WE;Lo;0;L;;;;;N;;;;;
 1B152;HIRAGANA LETTER SMALL WO;Lo;0;L;;;;;N;;;;;
@@ -27324,6 +27839,191 @@
 1BCA1;SHORTHAND FORMAT CONTINUING OVERLAP;Cf;0;BN;;;;;N;;;;;
 1BCA2;SHORTHAND FORMAT DOWN STEP;Cf;0;BN;;;;;N;;;;;
 1BCA3;SHORTHAND FORMAT UP STEP;Cf;0;BN;;;;;N;;;;;
+1CF00;ZNAMENNY COMBINING MARK GORAZDO NIZKO S KRYZHEM ON LEFT;Mn;0;NSM;;;;;N;;;;;
+1CF01;ZNAMENNY COMBINING MARK NIZKO S KRYZHEM ON LEFT;Mn;0;NSM;;;;;N;;;;;
+1CF02;ZNAMENNY COMBINING MARK TSATA ON LEFT;Mn;0;NSM;;;;;N;;;;;
+1CF03;ZNAMENNY COMBINING MARK GORAZDO NIZKO ON LEFT;Mn;0;NSM;;;;;N;;;;;
+1CF04;ZNAMENNY COMBINING MARK NIZKO ON LEFT;Mn;0;NSM;;;;;N;;;;;
+1CF05;ZNAMENNY COMBINING MARK SREDNE ON LEFT;Mn;0;NSM;;;;;N;;;;;
+1CF06;ZNAMENNY COMBINING MARK MALO POVYSHE ON LEFT;Mn;0;NSM;;;;;N;;;;;
+1CF07;ZNAMENNY COMBINING MARK POVYSHE ON LEFT;Mn;0;NSM;;;;;N;;;;;
+1CF08;ZNAMENNY COMBINING MARK VYSOKO ON LEFT;Mn;0;NSM;;;;;N;;;;;
+1CF09;ZNAMENNY COMBINING MARK MALO POVYSHE S KHOKHLOM ON LEFT;Mn;0;NSM;;;;;N;;;;;
+1CF0A;ZNAMENNY COMBINING MARK POVYSHE S KHOKHLOM ON LEFT;Mn;0;NSM;;;;;N;;;;;
+1CF0B;ZNAMENNY COMBINING MARK VYSOKO S KHOKHLOM ON LEFT;Mn;0;NSM;;;;;N;;;;;
+1CF0C;ZNAMENNY COMBINING MARK GORAZDO NIZKO S KRYZHEM ON RIGHT;Mn;0;NSM;;;;;N;;;;;
+1CF0D;ZNAMENNY COMBINING MARK NIZKO S KRYZHEM ON RIGHT;Mn;0;NSM;;;;;N;;;;;
+1CF0E;ZNAMENNY COMBINING MARK TSATA ON RIGHT;Mn;0;NSM;;;;;N;;;;;
+1CF0F;ZNAMENNY COMBINING MARK GORAZDO NIZKO ON RIGHT;Mn;0;NSM;;;;;N;;;;;
+1CF10;ZNAMENNY COMBINING MARK NIZKO ON RIGHT;Mn;0;NSM;;;;;N;;;;;
+1CF11;ZNAMENNY COMBINING MARK SREDNE ON RIGHT;Mn;0;NSM;;;;;N;;;;;
+1CF12;ZNAMENNY COMBINING MARK MALO POVYSHE ON RIGHT;Mn;0;NSM;;;;;N;;;;;
+1CF13;ZNAMENNY COMBINING MARK POVYSHE ON RIGHT;Mn;0;NSM;;;;;N;;;;;
+1CF14;ZNAMENNY COMBINING MARK VYSOKO ON RIGHT;Mn;0;NSM;;;;;N;;;;;
+1CF15;ZNAMENNY COMBINING MARK MALO POVYSHE S KHOKHLOM ON RIGHT;Mn;0;NSM;;;;;N;;;;;
+1CF16;ZNAMENNY COMBINING MARK POVYSHE S KHOKHLOM ON RIGHT;Mn;0;NSM;;;;;N;;;;;
+1CF17;ZNAMENNY COMBINING MARK VYSOKO S KHOKHLOM ON RIGHT;Mn;0;NSM;;;;;N;;;;;
+1CF18;ZNAMENNY COMBINING MARK TSATA S KRYZHEM;Mn;0;NSM;;;;;N;;;;;
+1CF19;ZNAMENNY COMBINING MARK MALO POVYSHE S KRYZHEM;Mn;0;NSM;;;;;N;;;;;
+1CF1A;ZNAMENNY COMBINING MARK STRANNO MALO POVYSHE;Mn;0;NSM;;;;;N;;;;;
+1CF1B;ZNAMENNY COMBINING MARK POVYSHE S KRYZHEM;Mn;0;NSM;;;;;N;;;;;
+1CF1C;ZNAMENNY COMBINING MARK POVYSHE STRANNO;Mn;0;NSM;;;;;N;;;;;
+1CF1D;ZNAMENNY COMBINING MARK VYSOKO S KRYZHEM;Mn;0;NSM;;;;;N;;;;;
+1CF1E;ZNAMENNY COMBINING MARK MALO POVYSHE STRANNO;Mn;0;NSM;;;;;N;;;;;
+1CF1F;ZNAMENNY COMBINING MARK GORAZDO VYSOKO;Mn;0;NSM;;;;;N;;;;;
+1CF20;ZNAMENNY COMBINING MARK ZELO;Mn;0;NSM;;;;;N;;;;;
+1CF21;ZNAMENNY COMBINING MARK ON;Mn;0;NSM;;;;;N;;;;;
+1CF22;ZNAMENNY COMBINING MARK RAVNO;Mn;0;NSM;;;;;N;;;;;
+1CF23;ZNAMENNY COMBINING MARK TIKHAYA;Mn;0;NSM;;;;;N;;;;;
+1CF24;ZNAMENNY COMBINING MARK BORZAYA;Mn;0;NSM;;;;;N;;;;;
+1CF25;ZNAMENNY COMBINING MARK UDARKA;Mn;0;NSM;;;;;N;;;;;
+1CF26;ZNAMENNY COMBINING MARK PODVERTKA;Mn;0;NSM;;;;;N;;;;;
+1CF27;ZNAMENNY COMBINING MARK LOMKA;Mn;0;NSM;;;;;N;;;;;
+1CF28;ZNAMENNY COMBINING MARK KUPNAYA;Mn;0;NSM;;;;;N;;;;;
+1CF29;ZNAMENNY COMBINING MARK KACHKA;Mn;0;NSM;;;;;N;;;;;
+1CF2A;ZNAMENNY COMBINING MARK ZEVOK;Mn;0;NSM;;;;;N;;;;;
+1CF2B;ZNAMENNY COMBINING MARK SKOBA;Mn;0;NSM;;;;;N;;;;;
+1CF2C;ZNAMENNY COMBINING MARK RAZSEKA;Mn;0;NSM;;;;;N;;;;;
+1CF2D;ZNAMENNY COMBINING MARK KRYZH ON LEFT;Mn;0;NSM;;;;;N;;;;;
+1CF30;ZNAMENNY COMBINING TONAL RANGE MARK MRACHNO;Mn;0;NSM;;;;;N;;;;;
+1CF31;ZNAMENNY COMBINING TONAL RANGE MARK SVETLO;Mn;0;NSM;;;;;N;;;;;
+1CF32;ZNAMENNY COMBINING TONAL RANGE MARK TRESVETLO;Mn;0;NSM;;;;;N;;;;;
+1CF33;ZNAMENNY COMBINING MARK ZADERZHKA;Mn;0;NSM;;;;;N;;;;;
+1CF34;ZNAMENNY COMBINING MARK DEMESTVENNY ZADERZHKA;Mn;0;NSM;;;;;N;;;;;
+1CF35;ZNAMENNY COMBINING MARK OTSECHKA;Mn;0;NSM;;;;;N;;;;;
+1CF36;ZNAMENNY COMBINING MARK PODCHASHIE;Mn;0;NSM;;;;;N;;;;;
+1CF37;ZNAMENNY COMBINING MARK PODCHASHIE WITH VERTICAL STROKE;Mn;0;NSM;;;;;N;;;;;
+1CF38;ZNAMENNY COMBINING MARK CHASHKA;Mn;0;NSM;;;;;N;;;;;
+1CF39;ZNAMENNY COMBINING MARK CHASHKA POLNAYA;Mn;0;NSM;;;;;N;;;;;
+1CF3A;ZNAMENNY COMBINING MARK OBLACHKO;Mn;0;NSM;;;;;N;;;;;
+1CF3B;ZNAMENNY COMBINING MARK SOROCHYA NOZHKA;Mn;0;NSM;;;;;N;;;;;
+1CF3C;ZNAMENNY COMBINING MARK TOCHKA;Mn;0;NSM;;;;;N;;;;;
+1CF3D;ZNAMENNY COMBINING MARK DVOETOCHIE;Mn;0;NSM;;;;;N;;;;;
+1CF3E;ZNAMENNY COMBINING ATTACHING VERTICAL OMET;Mn;0;NSM;;;;;N;;;;;
+1CF3F;ZNAMENNY COMBINING MARK CURVED OMET;Mn;0;NSM;;;;;N;;;;;
+1CF40;ZNAMENNY COMBINING MARK KRYZH;Mn;0;NSM;;;;;N;;;;;
+1CF41;ZNAMENNY COMBINING LOWER TONAL RANGE INDICATOR;Mn;0;NSM;;;;;N;;;;;
+1CF42;ZNAMENNY PRIZNAK MODIFIER LEVEL-2;Mn;0;NSM;;;;;N;;;;;
+1CF43;ZNAMENNY PRIZNAK MODIFIER LEVEL-3;Mn;0;NSM;;;;;N;;;;;
+1CF44;ZNAMENNY PRIZNAK MODIFIER DIRECTION FLIP;Mn;0;NSM;;;;;N;;;;;
+1CF45;ZNAMENNY PRIZNAK MODIFIER KRYZH;Mn;0;NSM;;;;;N;;;;;
+1CF46;ZNAMENNY PRIZNAK MODIFIER ROG;Mn;0;NSM;;;;;N;;;;;
+1CF50;ZNAMENNY NEUME KRYUK;So;0;L;;;;;N;;;;;
+1CF51;ZNAMENNY NEUME KRYUK TIKHY;So;0;L;;;;;N;;;;;
+1CF52;ZNAMENNY NEUME PARAKLIT;So;0;L;;;;;N;;;;;
+1CF53;ZNAMENNY NEUME DVA V CHELNU;So;0;L;;;;;N;;;;;
+1CF54;ZNAMENNY NEUME KLYUCH;So;0;L;;;;;N;;;;;
+1CF55;ZNAMENNY NEUME ZANOZHEK;So;0;L;;;;;N;;;;;
+1CF56;ZNAMENNY NEUME STOPITSA;So;0;L;;;;;N;;;;;
+1CF57;ZNAMENNY NEUME STOPITSA S OCHKOM;So;0;L;;;;;N;;;;;
+1CF58;ZNAMENNY NEUME PEREVODKA;So;0;L;;;;;N;;;;;
+1CF59;ZNAMENNY NEUME PEREVODKA NEPOSTOYANNAYA;So;0;L;;;;;N;;;;;
+1CF5A;ZNAMENNY NEUME STOPITSA WITH SOROCHYA NOZHKA;So;0;L;;;;;N;;;;;
+1CF5B;ZNAMENNY NEUME CHELYUSTKA;So;0;L;;;;;N;;;;;
+1CF5C;ZNAMENNY NEUME PALKA;So;0;L;;;;;N;;;;;
+1CF5D;ZNAMENNY NEUME ZAPYATAYA;So;0;L;;;;;N;;;;;
+1CF5E;ZNAMENNY NEUME GOLUBCHIK BORZY;So;0;L;;;;;N;;;;;
+1CF5F;ZNAMENNY NEUME GOLUBCHIK TIKHY;So;0;L;;;;;N;;;;;
+1CF60;ZNAMENNY NEUME GOLUBCHIK MRACHNY;So;0;L;;;;;N;;;;;
+1CF61;ZNAMENNY NEUME GOLUBCHIK SVETLY;So;0;L;;;;;N;;;;;
+1CF62;ZNAMENNY NEUME GOLUBCHIK TRESVETLY;So;0;L;;;;;N;;;;;
+1CF63;ZNAMENNY NEUME VRAKHIYA PROSTAYA;So;0;L;;;;;N;;;;;
+1CF64;ZNAMENNY NEUME VRAKHIYA MRACHNAYA;So;0;L;;;;;N;;;;;
+1CF65;ZNAMENNY NEUME VRAKHIYA SVETLAYA;So;0;L;;;;;N;;;;;
+1CF66;ZNAMENNY NEUME VRAKHIYA TRESVETLAYA;So;0;L;;;;;N;;;;;
+1CF67;ZNAMENNY NEUME VRAKHIYA KLYUCHEVAYA PROSTAYA;So;0;L;;;;;N;;;;;
+1CF68;ZNAMENNY NEUME VRAKHIYA KLYUCHEVAYA MRACHNAYA;So;0;L;;;;;N;;;;;
+1CF69;ZNAMENNY NEUME VRAKHIYA KLYUCHEVAYA SVETLAYA;So;0;L;;;;;N;;;;;
+1CF6A;ZNAMENNY NEUME VRAKHIYA KLYUCHEVAYA TRESVETLAYA;So;0;L;;;;;N;;;;;
+1CF6B;ZNAMENNY NEUME DOUBLE ZAPYATAYA;So;0;L;;;;;N;;;;;
+1CF6C;ZNAMENNY NEUME REVERSED CHELYUSTKA;So;0;L;;;;;N;;;;;
+1CF6D;ZNAMENNY NEUME DERBITSA;So;0;L;;;;;N;;;;;
+1CF6E;ZNAMENNY NEUME KHAMILO;So;0;L;;;;;N;;;;;
+1CF6F;ZNAMENNY NEUME CHASHKA;So;0;L;;;;;N;;;;;
+1CF70;ZNAMENNY NEUME PODCHASHIE;So;0;L;;;;;N;;;;;
+1CF71;ZNAMENNY NEUME SKAMEYTSA MRACHNAYA;So;0;L;;;;;N;;;;;
+1CF72;ZNAMENNY NEUME SKAMEYTSA SVETLAYA;So;0;L;;;;;N;;;;;
+1CF73;ZNAMENNY NEUME SKAMEYTSA TRESVETLAYA;So;0;L;;;;;N;;;;;
+1CF74;ZNAMENNY NEUME SKAMEYTSA TIKHAYA;So;0;L;;;;;N;;;;;
+1CF75;ZNAMENNY NEUME DEMESTVENNY KLYUCH;So;0;L;;;;;N;;;;;
+1CF76;ZNAMENNY NEUME SKAMEYTSA KLYUCHEVAYA SVETLAYA;So;0;L;;;;;N;;;;;
+1CF77;ZNAMENNY NEUME SKAMEYTSA KLYUCHENEPOSTOYANNAYA;So;0;L;;;;;N;;;;;
+1CF78;ZNAMENNY NEUME SKAMEYTSA KLYUCHEVAYA TIKHAYA;So;0;L;;;;;N;;;;;
+1CF79;ZNAMENNY NEUME SKAMEYTSA DVOECHELNAYA PROSTAYA;So;0;L;;;;;N;;;;;
+1CF7A;ZNAMENNY NEUME SKAMEYTSA DVOECHELNAYA SVETLAYA;So;0;L;;;;;N;;;;;
+1CF7B;ZNAMENNY NEUME SKAMEYTSA DVOECHELNAYA NEPOSTOYANNAYA;So;0;L;;;;;N;;;;;
+1CF7C;ZNAMENNY NEUME SKAMEYTSA DVOECHELNAYA KLYUCHEVAYA;So;0;L;;;;;N;;;;;
+1CF7D;ZNAMENNY NEUME SLOZHITIE;So;0;L;;;;;N;;;;;
+1CF7E;ZNAMENNY NEUME SLOZHITIE S ZAPYATOY;So;0;L;;;;;N;;;;;
+1CF7F;ZNAMENNY NEUME SLOZHITIE ZAKRYTOE;So;0;L;;;;;N;;;;;
+1CF80;ZNAMENNY NEUME SLOZHITIE S KRYZHEM;So;0;L;;;;;N;;;;;
+1CF81;ZNAMENNY NEUME KRYZH;So;0;L;;;;;N;;;;;
+1CF82;ZNAMENNY NEUME ROG;So;0;L;;;;;N;;;;;
+1CF83;ZNAMENNY NEUME FITA;So;0;L;;;;;N;;;;;
+1CF84;ZNAMENNY NEUME KOBYLA;So;0;L;;;;;N;;;;;
+1CF85;ZNAMENNY NEUME ZMEYTSA;So;0;L;;;;;N;;;;;
+1CF86;ZNAMENNY NEUME STATYA;So;0;L;;;;;N;;;;;
+1CF87;ZNAMENNY NEUME STATYA S ZAPYATOY;So;0;L;;;;;N;;;;;
+1CF88;ZNAMENNY NEUME STATYA S KRYZHEM;So;0;L;;;;;N;;;;;
+1CF89;ZNAMENNY NEUME STATYA S ZAPYATOY I KRYZHEM;So;0;L;;;;;N;;;;;
+1CF8A;ZNAMENNY NEUME STATYA S KRYZHEM I ZAPYATOY;So;0;L;;;;;N;;;;;
+1CF8B;ZNAMENNY NEUME STATYA ZAKRYTAYA;So;0;L;;;;;N;;;;;
+1CF8C;ZNAMENNY NEUME STATYA ZAKRYTAYA S ZAPYATOY;So;0;L;;;;;N;;;;;
+1CF8D;ZNAMENNY NEUME STATYA S ROGOM;So;0;L;;;;;N;;;;;
+1CF8E;ZNAMENNY NEUME STATYA S DVUMYA ZAPYATYMI;So;0;L;;;;;N;;;;;
+1CF8F;ZNAMENNY NEUME STATYA S ZAPYATOY I PODCHASHIEM;So;0;L;;;;;N;;;;;
+1CF90;ZNAMENNY NEUME POLKULIZMY;So;0;L;;;;;N;;;;;
+1CF91;ZNAMENNY NEUME STATYA NEPOSTOYANNAYA;So;0;L;;;;;N;;;;;
+1CF92;ZNAMENNY NEUME STRELA PROSTAYA;So;0;L;;;;;N;;;;;
+1CF93;ZNAMENNY NEUME STRELA MRACHNOTIKHAYA;So;0;L;;;;;N;;;;;
+1CF94;ZNAMENNY NEUME STRELA KRYZHEVAYA;So;0;L;;;;;N;;;;;
+1CF95;ZNAMENNY NEUME STRELA POLUPOVODNAYA;So;0;L;;;;;N;;;;;
+1CF96;ZNAMENNY NEUME STRELA POVODNAYA;So;0;L;;;;;N;;;;;
+1CF97;ZNAMENNY NEUME STRELA NEPOSTOYANNAYA;So;0;L;;;;;N;;;;;
+1CF98;ZNAMENNY NEUME STRELA KLYUCHEPOVODNAYA;So;0;L;;;;;N;;;;;
+1CF99;ZNAMENNY NEUME STRELA KLYUCHENEPOSTOYANNAYA;So;0;L;;;;;N;;;;;
+1CF9A;ZNAMENNY NEUME STRELA TIKHAYA PUTNAYA;So;0;L;;;;;N;;;;;
+1CF9B;ZNAMENNY NEUME STRELA DVOECHELNAYA;So;0;L;;;;;N;;;;;
+1CF9C;ZNAMENNY NEUME STRELA DVOECHELNOKRYZHEVAYA;So;0;L;;;;;N;;;;;
+1CF9D;ZNAMENNY NEUME STRELA DVOECHELNOPOVODNAYA;So;0;L;;;;;N;;;;;
+1CF9E;ZNAMENNY NEUME STRELA DVOECHELNAYA KLYUCHEVAYA;So;0;L;;;;;N;;;;;
+1CF9F;ZNAMENNY NEUME STRELA DVOECHELNOPOVODNAYA KLYUCHEVAYA;So;0;L;;;;;N;;;;;
+1CFA0;ZNAMENNY NEUME STRELA GROMNAYA WITH SINGLE ZAPYATAYA;So;0;L;;;;;N;;;;;
+1CFA1;ZNAMENNY NEUME STRELA GROMOPOVODNAYA WITH SINGLE ZAPYATAYA;So;0;L;;;;;N;;;;;
+1CFA2;ZNAMENNY NEUME STRELA GROMNAYA;So;0;L;;;;;N;;;;;
+1CFA3;ZNAMENNY NEUME STRELA GROMOPOVODNAYA;So;0;L;;;;;N;;;;;
+1CFA4;ZNAMENNY NEUME STRELA GROMOPOVODNAYA WITH DOUBLE ZAPYATAYA;So;0;L;;;;;N;;;;;
+1CFA5;ZNAMENNY NEUME STRELA GROMOKRYZHEVAYA;So;0;L;;;;;N;;;;;
+1CFA6;ZNAMENNY NEUME STRELA GROMOKRYZHEVAYA POVODNAYA;So;0;L;;;;;N;;;;;
+1CFA7;ZNAMENNY NEUME MECHIK;So;0;L;;;;;N;;;;;
+1CFA8;ZNAMENNY NEUME MECHIK POVODNY;So;0;L;;;;;N;;;;;
+1CFA9;ZNAMENNY NEUME MECHIK KLYUCHEVOY;So;0;L;;;;;N;;;;;
+1CFAA;ZNAMENNY NEUME MECHIK KLYUCHEPOVODNY;So;0;L;;;;;N;;;;;
+1CFAB;ZNAMENNY NEUME MECHIK KLYUCHENEPOSTOYANNY;So;0;L;;;;;N;;;;;
+1CFAC;ZNAMENNY NEUME STRELA TRYASOGLASNAYA;So;0;L;;;;;N;;;;;
+1CFAD;ZNAMENNY NEUME STRELA TRYASOPOVODNAYA;So;0;L;;;;;N;;;;;
+1CFAE;ZNAMENNY NEUME STRELA TRYASOSTRELNAYA;So;0;L;;;;;N;;;;;
+1CFAF;ZNAMENNY NEUME OSOKA;So;0;L;;;;;N;;;;;
+1CFB0;ZNAMENNY NEUME OSOKA SVETLAYA;So;0;L;;;;;N;;;;;
+1CFB1;ZNAMENNY NEUME OSOKA TRESVETLAYA;So;0;L;;;;;N;;;;;
+1CFB2;ZNAMENNY NEUME OSOKA KRYUKOVAYA SVETLAYA;So;0;L;;;;;N;;;;;
+1CFB3;ZNAMENNY NEUME OSOKA KLYUCHEVAYA SVETLAYA;So;0;L;;;;;N;;;;;
+1CFB4;ZNAMENNY NEUME OSOKA KLYUCHEVAYA NEPOSTOYANNAYA;So;0;L;;;;;N;;;;;
+1CFB5;ZNAMENNY NEUME STRELA KRYUKOVAYA;So;0;L;;;;;N;;;;;
+1CFB6;ZNAMENNY NEUME STRELA KRYUKOVAYA POVODNAYA;So;0;L;;;;;N;;;;;
+1CFB7;ZNAMENNY NEUME STRELA KRYUKOVAYA GROMNAYA WITH SINGLE ZAPYATAYA;So;0;L;;;;;N;;;;;
+1CFB8;ZNAMENNY NEUME STRELA KRYUKOVAYA GROMOPOVODNAYA WITH SINGLE ZAPYATAYA;So;0;L;;;;;N;;;;;
+1CFB9;ZNAMENNY NEUME STRELA KRYUKOVAYA GROMNAYA;So;0;L;;;;;N;;;;;
+1CFBA;ZNAMENNY NEUME STRELA KRYUKOVAYA GROMOPOVODNAYA;So;0;L;;;;;N;;;;;
+1CFBB;ZNAMENNY NEUME STRELA KRYUKOVAYA GROMOPOVODNAYA WITH DOUBLE ZAPYATAYA;So;0;L;;;;;N;;;;;
+1CFBC;ZNAMENNY NEUME STRELA KRYUKOVAYA GROMOKRYZHEVAYA;So;0;L;;;;;N;;;;;
+1CFBD;ZNAMENNY NEUME STRELA KRYUKOVAYA GROMOKRYZHEVAYA POVODNAYA;So;0;L;;;;;N;;;;;
+1CFBE;ZNAMENNY NEUME STRELA KRYUKOVAYA TRYASKA;So;0;L;;;;;N;;;;;
+1CFBF;ZNAMENNY NEUME KUFISMA;So;0;L;;;;;N;;;;;
+1CFC0;ZNAMENNY NEUME OBLAKO;So;0;L;;;;;N;;;;;
+1CFC1;ZNAMENNY NEUME DUDA;So;0;L;;;;;N;;;;;
+1CFC2;ZNAMENNY NEUME NEMKA;So;0;L;;;;;N;;;;;
+1CFC3;ZNAMENNY NEUME PAUK;So;0;L;;;;;N;;;;;
 1D000;BYZANTINE MUSICAL SYMBOL PSILI;So;0;L;;;;;N;;;;;
 1D001;BYZANTINE MUSICAL SYMBOL DASEIA;So;0;L;;;;;N;;;;;
 1D002;BYZANTINE MUSICAL SYMBOL PERISPOMENI;So;0;L;;;;;N;;;;;
@@ -27801,6 +28501,8 @@
 1D1E6;MUSICAL SYMBOL KIEVAN EIGHTH NOTE STEM DOWN;So;0;L;;;;;N;;;;;
 1D1E7;MUSICAL SYMBOL KIEVAN EIGHTH NOTE STEM UP;So;0;L;;;;;N;;;;;
 1D1E8;MUSICAL SYMBOL KIEVAN FLAT SIGN;So;0;L;;;;;N;;;;;
+1D1E9;MUSICAL SYMBOL SORI;So;0;ON;;;;;N;;;;;
+1D1EA;MUSICAL SYMBOL KORON;So;0;ON;;;;;N;;;;;
 1D200;GREEK VOCAL NOTATION SYMBOL-1;So;0;ON;;;;;N;;;;;
 1D201;GREEK VOCAL NOTATION SYMBOL-2;So;0;ON;;;;;N;;;;;
 1D202;GREEK VOCAL NOTATION SYMBOL-3;So;0;ON;;;;;N;;;;;
@@ -29671,6 +30373,37 @@
 1DAAD;SIGNWRITING ROTATION MODIFIER-14;Mn;0;NSM;;;;;N;;;;;
 1DAAE;SIGNWRITING ROTATION MODIFIER-15;Mn;0;NSM;;;;;N;;;;;
 1DAAF;SIGNWRITING ROTATION MODIFIER-16;Mn;0;NSM;;;;;N;;;;;
+1DF00;LATIN SMALL LETTER FENG DIGRAPH WITH TRILL;Ll;0;L;;;;;N;;;;;
+1DF01;LATIN SMALL LETTER REVERSED SCRIPT G;Ll;0;L;;;;;N;;;;;
+1DF02;LATIN LETTER SMALL CAPITAL TURNED G;Ll;0;L;;;;;N;;;;;
+1DF03;LATIN SMALL LETTER REVERSED K;Ll;0;L;;;;;N;;;;;
+1DF04;LATIN LETTER SMALL CAPITAL L WITH BELT;Ll;0;L;;;;;N;;;;;
+1DF05;LATIN SMALL LETTER LEZH WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
+1DF06;LATIN SMALL LETTER TURNED Y WITH BELT;Ll;0;L;;;;;N;;;;;
+1DF07;LATIN SMALL LETTER REVERSED ENG;Ll;0;L;;;;;N;;;;;
+1DF08;LATIN SMALL LETTER TURNED R WITH LONG LEG AND RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
+1DF09;LATIN SMALL LETTER T WITH HOOK AND RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
+1DF0A;LATIN LETTER RETROFLEX CLICK WITH RETROFLEX HOOK;Lo;0;L;;;;;N;;;;;
+1DF0B;LATIN SMALL LETTER ESH WITH DOUBLE BAR;Ll;0;L;;;;;N;;;;;
+1DF0C;LATIN SMALL LETTER ESH WITH DOUBLE BAR AND CURL;Ll;0;L;;;;;N;;;;;
+1DF0D;LATIN SMALL LETTER TURNED T WITH CURL;Ll;0;L;;;;;N;;;;;
+1DF0E;LATIN LETTER INVERTED GLOTTAL STOP WITH CURL;Ll;0;L;;;;;N;;;;;
+1DF0F;LATIN LETTER STRETCHED C WITH CURL;Ll;0;L;;;;;N;;;;;
+1DF10;LATIN LETTER SMALL CAPITAL TURNED K;Ll;0;L;;;;;N;;;;;
+1DF11;LATIN SMALL LETTER L WITH FISHHOOK;Ll;0;L;;;;;N;;;;;
+1DF12;LATIN SMALL LETTER DEZH DIGRAPH WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
+1DF13;LATIN SMALL LETTER L WITH BELT AND PALATAL HOOK;Ll;0;L;;;;;N;;;;;
+1DF14;LATIN SMALL LETTER ENG WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
+1DF15;LATIN SMALL LETTER TURNED R WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
+1DF16;LATIN SMALL LETTER R WITH FISHHOOK AND PALATAL HOOK;Ll;0;L;;;;;N;;;;;
+1DF17;LATIN SMALL LETTER TESH DIGRAPH WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
+1DF18;LATIN SMALL LETTER EZH WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
+1DF19;LATIN SMALL LETTER DEZH DIGRAPH WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
+1DF1A;LATIN SMALL LETTER I WITH STROKE AND RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
+1DF1B;LATIN SMALL LETTER O WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
+1DF1C;LATIN SMALL LETTER TESH DIGRAPH WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
+1DF1D;LATIN SMALL LETTER C WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
+1DF1E;LATIN SMALL LETTER S WITH CURL;Ll;0;L;;;;;N;;;;;
 1E000;COMBINING GLAGOLITIC LETTER AZU;Mn;230;NSM;;;;;N;;;;;
 1E001;COMBINING GLAGOLITIC LETTER BUKY;Mn;230;NSM;;;;;N;;;;;
 1E002;COMBINING GLAGOLITIC LETTER VEDE;Mn;230;NSM;;;;;N;;;;;
@@ -29780,6 +30513,37 @@
 1E149;NYIAKENG PUACHUE HMONG DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
 1E14E;NYIAKENG PUACHUE HMONG LOGOGRAM NYAJ;Lo;0;L;;;;;N;;;;;
 1E14F;NYIAKENG PUACHUE HMONG CIRCLED CA;So;0;L;;;;;N;;;;;
+1E290;TOTO LETTER PA;Lo;0;L;;;;;N;;;;;
+1E291;TOTO LETTER BA;Lo;0;L;;;;;N;;;;;
+1E292;TOTO LETTER TA;Lo;0;L;;;;;N;;;;;
+1E293;TOTO LETTER DA;Lo;0;L;;;;;N;;;;;
+1E294;TOTO LETTER KA;Lo;0;L;;;;;N;;;;;
+1E295;TOTO LETTER GA;Lo;0;L;;;;;N;;;;;
+1E296;TOTO LETTER MA;Lo;0;L;;;;;N;;;;;
+1E297;TOTO LETTER NA;Lo;0;L;;;;;N;;;;;
+1E298;TOTO LETTER NGA;Lo;0;L;;;;;N;;;;;
+1E299;TOTO LETTER SA;Lo;0;L;;;;;N;;;;;
+1E29A;TOTO LETTER CHA;Lo;0;L;;;;;N;;;;;
+1E29B;TOTO LETTER YA;Lo;0;L;;;;;N;;;;;
+1E29C;TOTO LETTER WA;Lo;0;L;;;;;N;;;;;
+1E29D;TOTO LETTER JA;Lo;0;L;;;;;N;;;;;
+1E29E;TOTO LETTER HA;Lo;0;L;;;;;N;;;;;
+1E29F;TOTO LETTER RA;Lo;0;L;;;;;N;;;;;
+1E2A0;TOTO LETTER LA;Lo;0;L;;;;;N;;;;;
+1E2A1;TOTO LETTER I;Lo;0;L;;;;;N;;;;;
+1E2A2;TOTO LETTER BREATHY I;Lo;0;L;;;;;N;;;;;
+1E2A3;TOTO LETTER IU;Lo;0;L;;;;;N;;;;;
+1E2A4;TOTO LETTER BREATHY IU;Lo;0;L;;;;;N;;;;;
+1E2A5;TOTO LETTER U;Lo;0;L;;;;;N;;;;;
+1E2A6;TOTO LETTER E;Lo;0;L;;;;;N;;;;;
+1E2A7;TOTO LETTER BREATHY E;Lo;0;L;;;;;N;;;;;
+1E2A8;TOTO LETTER EO;Lo;0;L;;;;;N;;;;;
+1E2A9;TOTO LETTER BREATHY EO;Lo;0;L;;;;;N;;;;;
+1E2AA;TOTO LETTER O;Lo;0;L;;;;;N;;;;;
+1E2AB;TOTO LETTER AE;Lo;0;L;;;;;N;;;;;
+1E2AC;TOTO LETTER BREATHY AE;Lo;0;L;;;;;N;;;;;
+1E2AD;TOTO LETTER A;Lo;0;L;;;;;N;;;;;
+1E2AE;TOTO SIGN RISING TONE;Mn;230;NSM;;;;;N;;;;;
 1E2C0;WANCHO LETTER AA;Lo;0;L;;;;;N;;;;;
 1E2C1;WANCHO LETTER A;Lo;0;L;;;;;N;;;;;
 1E2C2;WANCHO LETTER BA;Lo;0;L;;;;;N;;;;;
@@ -29839,6 +30603,34 @@
 1E2F8;WANCHO DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
 1E2F9;WANCHO DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
 1E2FF;WANCHO NGUN SIGN;Sc;0;ET;;;;;N;;;;;
+1E7E0;ETHIOPIC SYLLABLE HHYA;Lo;0;L;;;;;N;;;;;
+1E7E1;ETHIOPIC SYLLABLE HHYU;Lo;0;L;;;;;N;;;;;
+1E7E2;ETHIOPIC SYLLABLE HHYI;Lo;0;L;;;;;N;;;;;
+1E7E3;ETHIOPIC SYLLABLE HHYAA;Lo;0;L;;;;;N;;;;;
+1E7E4;ETHIOPIC SYLLABLE HHYEE;Lo;0;L;;;;;N;;;;;
+1E7E5;ETHIOPIC SYLLABLE HHYE;Lo;0;L;;;;;N;;;;;
+1E7E6;ETHIOPIC SYLLABLE HHYO;Lo;0;L;;;;;N;;;;;
+1E7E8;ETHIOPIC SYLLABLE GURAGE HHWA;Lo;0;L;;;;;N;;;;;
+1E7E9;ETHIOPIC SYLLABLE HHWI;Lo;0;L;;;;;N;;;;;
+1E7EA;ETHIOPIC SYLLABLE HHWEE;Lo;0;L;;;;;N;;;;;
+1E7EB;ETHIOPIC SYLLABLE HHWE;Lo;0;L;;;;;N;;;;;
+1E7ED;ETHIOPIC SYLLABLE GURAGE MWI;Lo;0;L;;;;;N;;;;;
+1E7EE;ETHIOPIC SYLLABLE GURAGE MWEE;Lo;0;L;;;;;N;;;;;
+1E7F0;ETHIOPIC SYLLABLE GURAGE QWI;Lo;0;L;;;;;N;;;;;
+1E7F1;ETHIOPIC SYLLABLE GURAGE QWEE;Lo;0;L;;;;;N;;;;;
+1E7F2;ETHIOPIC SYLLABLE GURAGE QWE;Lo;0;L;;;;;N;;;;;
+1E7F3;ETHIOPIC SYLLABLE GURAGE BWI;Lo;0;L;;;;;N;;;;;
+1E7F4;ETHIOPIC SYLLABLE GURAGE BWEE;Lo;0;L;;;;;N;;;;;
+1E7F5;ETHIOPIC SYLLABLE GURAGE KWI;Lo;0;L;;;;;N;;;;;
+1E7F6;ETHIOPIC SYLLABLE GURAGE KWEE;Lo;0;L;;;;;N;;;;;
+1E7F7;ETHIOPIC SYLLABLE GURAGE KWE;Lo;0;L;;;;;N;;;;;
+1E7F8;ETHIOPIC SYLLABLE GURAGE GWI;Lo;0;L;;;;;N;;;;;
+1E7F9;ETHIOPIC SYLLABLE GURAGE GWEE;Lo;0;L;;;;;N;;;;;
+1E7FA;ETHIOPIC SYLLABLE GURAGE GWE;Lo;0;L;;;;;N;;;;;
+1E7FB;ETHIOPIC SYLLABLE GURAGE FWI;Lo;0;L;;;;;N;;;;;
+1E7FC;ETHIOPIC SYLLABLE GURAGE FWEE;Lo;0;L;;;;;N;;;;;
+1E7FD;ETHIOPIC SYLLABLE GURAGE PWI;Lo;0;L;;;;;N;;;;;
+1E7FE;ETHIOPIC SYLLABLE GURAGE PWEE;Lo;0;L;;;;;N;;;;;
 1E800;MENDE KIKAKUI SYLLABLE M001 KI;Lo;0;R;;;;;N;;;;;
 1E801;MENDE KIKAKUI SYLLABLE M002 KA;Lo;0;R;;;;;N;;;;;
 1E802;MENDE KIKAKUI SYLLABLE M003 KU;Lo;0;R;;;;;N;;;;;
@@ -31886,6 +32678,9 @@
 1F6D5;HINDU TEMPLE;So;0;ON;;;;;N;;;;;
 1F6D6;HUT;So;0;ON;;;;;N;;;;;
 1F6D7;ELEVATOR;So;0;ON;;;;;N;;;;;
+1F6DD;PLAYGROUND SLIDE;So;0;ON;;;;;N;;;;;
+1F6DE;WHEEL;So;0;ON;;;;;N;;;;;
+1F6DF;RING BUOY;So;0;ON;;;;;N;;;;;
 1F6E0;HAMMER AND WRENCH;So;0;ON;;;;;N;;;;;
 1F6E1;SHIELD;So;0;ON;;;;;N;;;;;
 1F6E2;OIL DRUM;So;0;ON;;;;;N;;;;;
@@ -32129,6 +32924,7 @@
 1F7E9;LARGE GREEN SQUARE;So;0;ON;;;;;N;;;;;
 1F7EA;LARGE PURPLE SQUARE;So;0;ON;;;;;N;;;;;
 1F7EB;LARGE BROWN SQUARE;So;0;ON;;;;;N;;;;;
+1F7F0;HEAVY EQUALS SIGN;So;0;ON;;;;;N;;;;;
 1F800;LEFTWARDS ARROW WITH SMALL TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;
 1F801;UPWARDS ARROW WITH SMALL TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;
 1F802;RIGHTWARDS ARROW WITH SMALL TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;
@@ -32400,6 +33196,7 @@
 1F976;FREEZING FACE;So;0;ON;;;;;N;;;;;
 1F977;NINJA;So;0;ON;;;;;N;;;;;
 1F978;DISGUISED FACE;So;0;ON;;;;;N;;;;;
+1F979;FACE HOLDING BACK TEARS;So;0;ON;;;;;N;;;;;
 1F97A;FACE WITH PLEADING EYES;So;0;ON;;;;;N;;;;;
 1F97B;SARI;So;0;ON;;;;;N;;;;;
 1F97C;LAB COAT;So;0;ON;;;;;N;;;;;
@@ -32482,6 +33279,7 @@
 1F9C9;MATE DRINK;So;0;ON;;;;;N;;;;;
 1F9CA;ICE CUBE;So;0;ON;;;;;N;;;;;
 1F9CB;BUBBLE TEA;So;0;ON;;;;;N;;;;;
+1F9CC;TROLL;So;0;ON;;;;;N;;;;;
 1F9CD;STANDING PERSON;So;0;ON;;;;;N;;;;;
 1F9CE;KNEELING PERSON;So;0;ON;;;;;N;;;;;
 1F9CF;DEAF PERSON;So;0;ON;;;;;N;;;;;
@@ -32639,6 +33437,8 @@
 1FA78;DROP OF BLOOD;So;0;ON;;;;;N;;;;;
 1FA79;ADHESIVE BANDAGE;So;0;ON;;;;;N;;;;;
 1FA7A;STETHOSCOPE;So;0;ON;;;;;N;;;;;
+1FA7B;X-RAY;So;0;ON;;;;;N;;;;;
+1FA7C;CRUTCH;So;0;ON;;;;;N;;;;;
 1FA80;YO-YO;So;0;ON;;;;;N;;;;;
 1FA81;KITE;So;0;ON;;;;;N;;;;;
 1FA82;PARACHUTE;So;0;ON;;;;;N;;;;;
@@ -32671,6 +33471,10 @@
 1FAA6;HEADSTONE;So;0;ON;;;;;N;;;;;
 1FAA7;PLACARD;So;0;ON;;;;;N;;;;;
 1FAA8;ROCK;So;0;ON;;;;;N;;;;;
+1FAA9;MIRROR BALL;So;0;ON;;;;;N;;;;;
+1FAAA;IDENTIFICATION CARD;So;0;ON;;;;;N;;;;;
+1FAAB;LOW BATTERY;So;0;ON;;;;;N;;;;;
+1FAAC;HAMSA;So;0;ON;;;;;N;;;;;
 1FAB0;FLY;So;0;ON;;;;;N;;;;;
 1FAB1;WORM;So;0;ON;;;;;N;;;;;
 1FAB2;BEETLE;So;0;ON;;;;;N;;;;;
@@ -32678,9 +33482,16 @@
 1FAB4;POTTED PLANT;So;0;ON;;;;;N;;;;;
 1FAB5;WOOD;So;0;ON;;;;;N;;;;;
 1FAB6;FEATHER;So;0;ON;;;;;N;;;;;
+1FAB7;LOTUS;So;0;ON;;;;;N;;;;;
+1FAB8;CORAL;So;0;ON;;;;;N;;;;;
+1FAB9;EMPTY NEST;So;0;ON;;;;;N;;;;;
+1FABA;NEST WITH EGGS;So;0;ON;;;;;N;;;;;
 1FAC0;ANATOMICAL HEART;So;0;ON;;;;;N;;;;;
 1FAC1;LUNGS;So;0;ON;;;;;N;;;;;
 1FAC2;PEOPLE HUGGING;So;0;ON;;;;;N;;;;;
+1FAC3;PREGNANT MAN;So;0;ON;;;;;N;;;;;
+1FAC4;PREGNANT PERSON;So;0;ON;;;;;N;;;;;
+1FAC5;PERSON WITH CROWN;So;0;ON;;;;;N;;;;;
 1FAD0;BLUEBERRIES;So;0;ON;;;;;N;;;;;
 1FAD1;BELL PEPPER;So;0;ON;;;;;N;;;;;
 1FAD2;OLIVE;So;0;ON;;;;;N;;;;;
@@ -32688,6 +33499,24 @@
 1FAD4;TAMALE;So;0;ON;;;;;N;;;;;
 1FAD5;FONDUE;So;0;ON;;;;;N;;;;;
 1FAD6;TEAPOT;So;0;ON;;;;;N;;;;;
+1FAD7;POURING LIQUID;So;0;ON;;;;;N;;;;;
+1FAD8;BEANS;So;0;ON;;;;;N;;;;;
+1FAD9;JAR;So;0;ON;;;;;N;;;;;
+1FAE0;MELTING FACE;So;0;ON;;;;;N;;;;;
+1FAE1;SALUTING FACE;So;0;ON;;;;;N;;;;;
+1FAE2;FACE WITH OPEN EYES AND HAND OVER MOUTH;So;0;ON;;;;;N;;;;;
+1FAE3;FACE WITH PEEKING EYE;So;0;ON;;;;;N;;;;;
+1FAE4;FACE WITH DIAGONAL MOUTH;So;0;ON;;;;;N;;;;;
+1FAE5;DOTTED LINE FACE;So;0;ON;;;;;N;;;;;
+1FAE6;BITING LIP;So;0;ON;;;;;N;;;;;
+1FAE7;BUBBLES;So;0;ON;;;;;N;;;;;
+1FAF0;HAND WITH INDEX FINGER AND THUMB CROSSED;So;0;ON;;;;;N;;;;;
+1FAF1;RIGHTWARDS HAND;So;0;ON;;;;;N;;;;;
+1FAF2;LEFTWARDS HAND;So;0;ON;;;;;N;;;;;
+1FAF3;PALM DOWN HAND;So;0;ON;;;;;N;;;;;
+1FAF4;PALM UP HAND;So;0;ON;;;;;N;;;;;
+1FAF5;INDEX POINTING AT THE VIEWER;So;0;ON;;;;;N;;;;;
+1FAF6;HEART HANDS;So;0;ON;;;;;N;;;;;
 1FB00;BLOCK SEXTANT-1;So;0;ON;;;;;N;;;;;
 1FB01;BLOCK SEXTANT-2;So;0;ON;;;;;N;;;;;
 1FB02;BLOCK SEXTANT-12;So;0;ON;;;;;N;;;;;
@@ -32901,9 +33730,9 @@
 1FBF8;SEGMENTED DIGIT EIGHT;Nd;0;EN;<font> 0038;8;8;8;N;;;;;
 1FBF9;SEGMENTED DIGIT NINE;Nd;0;EN;<font> 0039;9;9;9;N;;;;;
 20000;<CJK Ideograph Extension B, First>;Lo;0;L;;;;;N;;;;;
-2A6DD;<CJK Ideograph Extension B, Last>;Lo;0;L;;;;;N;;;;;
+2A6DF;<CJK Ideograph Extension B, Last>;Lo;0;L;;;;;N;;;;;
 2A700;<CJK Ideograph Extension C, First>;Lo;0;L;;;;;N;;;;;
-2B734;<CJK Ideograph Extension C, Last>;Lo;0;L;;;;;N;;;;;
+2B738;<CJK Ideograph Extension C, Last>;Lo;0;L;;;;;N;;;;;
 2B740;<CJK Ideograph Extension D, First>;Lo;0;L;;;;;N;;;;;
 2B81D;<CJK Ideograph Extension D, Last>;Lo;0;L;;;;;N;;;;;
 2B820;<CJK Ideograph Extension E, First>;Lo;0;L;;;;;N;;;;;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gen/mkutf.awk	Mon Mar 21 09:00:42 2022 +0100
@@ -0,0 +1,284 @@
+#
+# This file comes from sbase (https://git.suckless.org/sbase/file/libutf/Makefile.html)
+# and has been modified to match libunicode's API.
+#
+# Original license is as following:
+#
+# MIT/X Consortium License
+#
+# © 2011 Connor Lane Smith <cls@lubutu.com>
+# © 2011-2016 Dimitris Papastamos <sin@2f30.org>
+# © 2014-2016 Laslo Hunhold <dev@frign.de>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+#
+# Authors/contributors include:
+#
+# © 2011 Kamil Cholewiński <harry666t@gmail.com>
+# © 2011 Rob Pilling <robpilling@gmail.com>
+# © 2011 Hiltjo Posthuma <hiltjo@codemadness.org>
+# © 2011 pancake <pancake@youterm.com>
+# © 2011 Random832 <random832@fastmail.us>
+# © 2012 William Haddon <william@haddonthethird.net>
+# © 2012 Kurt H. Maier <khm@sciops.net>
+# © 2012 Christoph Lohmann <20h@r-36.net>
+# © 2012 David Galos <galosd83@students.rowan.edu>
+# © 2012 Robert Ransom <rransom.8774@gmail.com>
+# © 2013 Jakob Kramer <jakob.kramer@gmx.de>
+# © 2013 Anselm R Garbe <anselm@garbe.us>
+# © 2013 Truls Becken <truls.becken@gmail.com>
+# © 2013 dsp <dsp@2f30.org>
+# © 2013 Markus Teich <markus.teich@stusta.mhn.de>
+# © 2013 Jesse Ogle <jesse.p.ogle@gmail.com>
+# © 2013 Lorenzo Cogotti <miciamail@hotmail.it>
+# © 2013 Federico G. Benavento <benavento@gmail.com>
+# © 2013 Roberto E. Vargas Caballero <k0ga@shike2.com>
+# © 2013 Christian Hesse <mail@eworm.de>
+# © 2013 Markus Wichmann <nullplan@gmx.net>
+# © 2014 Silvan Jegen <s.jegen@gmail.com>
+# © 2014 Daniel Bainton <dpb@driftaway.org>
+# © 2014 Tuukka Kataja <stuge@xor.fi>
+# © 2014 Jeffrey Picard <jeff@jeffreypicard.com>
+# © 2014 Evan Gates <evan.gates@gmail.com>
+# © 2014 Michael Forney <mforney@mforney.org>
+# © 2014 Ari Malinen <ari.malinen@gmail.com>
+# © 2014 Brandon Mulcahy <brandon@jangler.info>
+# © 2014 Adria Garriga <rhaps0dy@installgentoo.com>
+# © 2014-2015 Greg Reagle <greg.reagle@umbc.edu>
+# © 2015 Tai Chi Minh Ralph Eastwood <tcmreastwood@gmail.com>
+# © 2015 Quentin Rameau <quinq@quinq.eu.org>
+# © 2015 Dionysis Grigoropoulos <info@erethon.com>
+# © 2015 Wolfgang Corcoran-Mathe <wcm@sigwinch.xyz>
+# © 2016 Mattias Andrée <maandree@kth.se>
+# © 2016 Eivind Uggedal <eivind@uggedal.com>
+#
+
+BEGIN {
+	FS = ";"
+	# set up hexadecimal lookup table
+	for(i = 0; i < 16; i++)
+		hex[sprintf("%X",i)] = i;
+}
+
+$3  ~ /^L/ { alphav[alphac++] = $1; }
+($3  ~ /^Z/) || ($5 == "WS") || ($5 == "S") || ($5 == "B") { spacev[spacec++] = $1; }
+$3 == "Cc" { cntrlv[cntrlc++] = $1; }
+$3 == "Lu" { upperv[upperc++] = $1; tolowerv[uppercc++] = ($14 == "") ? $1 : $14; }
+$3 == "Ll" { lowerv[lowerc++] = $1; toupperv[lowercc++] = ($13 == "") ? $1 : $13; }
+$3 == "Lt" { titlev[titlec++] = $1; }
+$3 == "Nd" { digitv[digitc++] = $1; }
+
+END {
+	mkis("alpha", alphav, alphac, q, "");
+	mkis("space", spacev, spacec, q, "");
+	mkis("control", cntrlv, cntrlc, q, "");
+	mkis("upper", upperv, upperc, tolowerv, "lower");
+	mkis("lower", lowerv, lowerc, toupperv, "upper");
+	mkis("title", titlev, titlec, q, "");
+	mkis("digit", digitv, digitc, q, "");
+}
+
+# parse hexadecimal rune index to int
+function code(s) {
+	x = 0;
+	for(i = 1; i <= length(s); i++) {
+		c = substr(s, i, 1);
+		x = (x*16) + hex[c];
+	}
+	return x;
+}
+
+# generate 'is<name>rune' unicode lookup function
+function mkis(name, runev, runec, casev, casename) {
+	rune1c = 0;
+	rune2c = 0;
+	rune3c = 0;
+	rune4c = 0;
+	mode = 1;
+
+	#sort rune groups into singletons, ranges and laces
+	for(j = 0; j < runec; j++) {
+		# range
+		if(code(runev[j+1]) == code(runev[j])+1 && ((length(casev) == 0) ||
+		   code(casev[j+1]) == code(casev[j])+1) && j+1 < runec) {
+			if (mode == 2) {
+				continue;
+			} else if (mode == 3) {
+				rune3v1[rune3c] = runev[j];
+				rune3c++;
+			} else if (mode == 4) {
+				rune4v1[rune4c] = runev[j];
+				rune4c++;
+			}
+			mode = 2;
+			rune2v0[rune2c] = runev[j];
+			if(length(casev) > 0) {
+				case2v[rune2c] = casev[j];
+			}
+			continue;
+		}
+		# lace 1
+		if(code(runev[j+1]) == code(runev[j])+2 && ((length(casev) == 0) ||
+		   (code(casev[j+1]) == code(runev[j+1])+1 && code(casev[j]) == code(runev[j])+1)) &&
+		   j+1 < runec) {
+			if (mode == 3) {
+				continue;
+			} else if (mode == 2) {
+				rune2v1[rune2c] = runev[j];
+				rune2c++;
+			} else if (mode == 4) {
+				rune4v1[rune2c] = runev[j];
+				rune4c++;
+			}
+			mode = 3;
+			rune3v0[rune3c] = runev[j];
+			continue;
+		}
+		# lace 2
+		if(code(runev[j+1]) == code(runev[j])+2 && ((length(casev) == 0) ||
+		   (code(casev[j+1]) == code(runev[j+1])-1 && code(casev[j]) == code(runev[j])-1)) &&
+		   j+1 < runec) {
+			if (mode == 4) {
+				continue;
+			} else if (mode == 2) {
+				rune2v1[rune2c] = runev[j];
+				rune2c++;
+			} else if (mode == 3) {
+				rune3v1[rune2c] = runev[j];
+				rune3c++;
+			}
+			mode = 4;
+			rune4v0[rune4c] = runev[j];
+			continue;
+		}
+		# terminating case
+		if (mode == 1) {
+			rune1v[rune1c] = runev[j];
+			if (length(casev) > 0) {
+				case1v[rune1c] = casev[j];
+			}
+			rune1c++;
+		} else if (mode == 2) {
+			rune2v1[rune2c] = runev[j];
+			rune2c++;
+		} else if (mode == 3) {
+			rune3v1[rune3c] = runev[j];
+			rune3c++;
+		} else { #lace 2
+			rune4v1[rune4c] = runev[j];
+			rune4c++;
+		}
+		mode = 1;
+	}
+
+	#generate list of laces 1
+	if(rune3c > 0) {
+		print "static uint32_t "name"3[][2] = {";
+		for(j = 0; j < rune3c; j++) {
+			print "\t{ 0x"rune3v0[j]", 0x"rune3v1[j]" },";
+		}
+		print "};\n";
+	}
+
+	#generate list of laces 2
+	if(rune4c > 0) {
+		print "static uint32_t "name"4[][2] = {";
+		for(j = 0; j < rune4c; j++) {
+			print "\t{ 0x"rune4v0[j]", 0x"rune4v1[j]" },";
+		}
+		print "};\n";
+	}
+
+	# generate list of ranges
+	if(rune2c > 0) {
+		if(length(casev) > 0) {
+			print "static uint32_t "name"2[][3] = {";
+			for(j = 0; j < rune2c; j++) {
+				print "\t{ 0x"rune2v0[j]", 0x"rune2v1[j]", 0x"case2v[j]" },";
+			}
+		} else {
+			print "static uint32_t "name"2[][2] = {"
+			for(j = 0; j < rune2c; j++) {
+				print "\t{ 0x"rune2v0[j]", 0x"rune2v1[j]" },";
+			}
+		}
+		print "};\n";
+	}
+
+	# generate list of singletons
+	if(rune1c > 0) {
+		if(length(casev) > 0) {
+			print "static uint32_t "name"1[][2] = {";
+			for(j = 0; j < rune1c; j++) {
+				print "\t{ 0x"rune1v[j]", 0x"case1v[j]" },";
+			}
+		} else {
+			print "static uint32_t "name"1[] = {";
+			for(j = 0; j < rune1c; j++) {
+				print "\t0x"rune1v[j]",";
+			}
+		}
+		print "};\n";
+	}
+	# generate lookup function
+	print "int\nuni_is"name"(uint32_t r)\n{";
+	if(rune4c > 0 || rune3c > 0)
+		print "\tconst uint32_t *match;\n";
+	if(rune4c > 0) {
+		print "\tif ((match = bsearch(&r, "name"4, nelem("name"4), sizeof *"name"4, &cmp2)))";
+		print "\t\treturn !((r - match[0]) % 2);";
+	}
+	if(rune3c > 0) {
+		print "\tif ((match = bsearch(&r, "name"3, nelem("name"3), sizeof *"name"3, &cmp2)))";
+		print "\t\treturn !((r - match[0]) % 2);";
+	}
+	if(rune2c > 0) {
+		print "\tif (bsearch(&r, "name"2, nelem("name"2), sizeof *"name"2, &cmp2))\n\t\treturn 1;";
+	}
+	if(rune1c > 0) {
+		print "\tif (bsearch(&r, "name"1, nelem("name"1), sizeof *"name"1, &cmp1))\n\t\treturn 1;";
+	}
+	print "\n\treturn 0;\n}\n";
+
+	# generate case conversion function
+	if(length(casev) > 0) {
+		print "\nuint32_t\nuni_to"casename"(uint32_t r)\n{\n\tuint32_t *match;\n";
+		if(rune4c > 0) {
+			print "\tmatch = bsearch(&r, "name"4, nelem("name"4), sizeof *"name"4, &cmp2);";
+			print "\tif (match)";
+			print "\t\treturn ((r - match[0]) % 2) ? r : r - 1;";
+		}
+		if(rune3c > 0) {
+			print "\tmatch = bsearch(&r, "name"3, nelem("name"3), sizeof *"name"3, &cmp2);";
+			print "\tif (match)";
+			print "\t\treturn ((r - match[0]) % 2) ? r : r + 1;";
+		}
+		if(rune2c > 0) {
+			print "\tmatch = bsearch(&r, "name"2, nelem("name"2), sizeof *"name"2, &cmp2);";
+			print "\tif (match)";
+			print "\t\treturn match[2] + (r - match[0]);";
+		}
+		if(rune1c > 0) {
+			print "\tmatch = bsearch(&r, "name"1, nelem("name"1), sizeof *"name"1, &cmp1);";
+			print "\tif (match)";
+			print "\t\treturn match[1];";
+		}
+		print "\treturn r;\n}";
+	}
+}
--- a/gen/src/mkunicode-c.c	Sun Jan 02 10:21:47 2022 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,731 +0,0 @@
-/*
- * Tool to create our unicode.c
- *
- * Current version: 7.0.0
- *
- * Based on mkrunetype from the Go language.
- *
- * Adapted to generated C++ code.
- */
-
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-/*
- * make is(upper|lower|title|space|alpha)rune and
- * to(upper|lower|title)rune from a UnicodeData.txt file.
- * these can be found at unicode.org
- *
- * with -c, runs a check of the existing runetype functions vs.
- * those extracted from UnicodeData.
- *
- * with -p, generates tables for pairs of chars, as well as for ranges
- * and singletons.
- *
- * UnicodeData defines 4 fields of interest:
- * 1) a category
- * 2) an upper case mapping
- * 3) a lower case mapping
- * 4) a title case mapping
- *
- * toupper, tolower, and totitle are defined directly from the mapping.
- *
- * isalpharune(c) is true iff c is a "letter" category
- * isupperrune(c) is true iff c is the target of toupperrune,
- *  or is in the uppercase letter category
- * similarly for islowerrune and istitlerune.
- * isspacerune is true for space category chars, "C" locale white space chars,
- *  and two additions:
- *  0085    "next line" control char
- *  feff]   "zero-width non-break space"
- * isdigitrune is true iff c is a numeric-digit category.
- */
-
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "utf.h"
-#include "utfdef.h"
-
-#define nelem(x) (sizeof(x)/sizeof((x)[0]))
-
-enum {
-	/*
-	 * fields in the unicode data file
-	 */
-	FIELD_CODE,
-	FIELD_NAME,
-	FIELD_CATEGORY,
-	FIELD_COMBINING,
-	FIELD_BIDIR,
-	FIELD_DECOMP,
-	FIELD_DECIMAL_DIG,
-	FIELD_DIG,
-	FIELD_NUMERIC_VAL,
-	FIELD_MIRRORED,
-	FIELD_UNICODE_1_NAME,
-	FIELD_COMMENT,
-	FIELD_UPPER,
-	FIELD_LOWER,
-	FIELD_TITLE,
-	NFIELDS,
-
-	MAX_LINE        = 1024,
-
-	TO_OFFSET       = 1 << 20,
-
-	NRUNES          = 1 << 21,
-};
-
-#define TO_DELTA(xmapped,x) (TO_OFFSET + (xmapped) - (x))
-
-static FILE *out;
-static char myisspace[NRUNES];
-static char myisalpha[NRUNES];
-static char myisdigit[NRUNES];
-static char myisupper[NRUNES];
-static char myislower[NRUNES];
-static char myistitle[NRUNES];
-
-static int  mytoupper[NRUNES];
-static int  mytolower[NRUNES];
-static int  mytotitle[NRUNES];
-
-static void check(void);
-static void mktables(char *src, int usepairs);
-static void fatal(const char *fmt, ...);
-static int  mygetfields(char **fields, int nfields, char *str, const char *delim);
-static int  getunicodeline(FILE *in, char **fields, char *buf);
-static int  getcode(char *s);
-
-static void
-usage(void)
-{
-	fprintf(stderr, "usage: mktables [-cp] output UnicodeData.txt\n");
-	exit(1);
-}
-
-int
-main(int argc, char *argv[])
-{
-	FILE *in;
-	char buf[MAX_LINE], buf2[MAX_LINE];
-	char *fields[NFIELDS + 1], *fields2[NFIELDS + 1];
-	char *p;
-	int i, code, last, usepairs;
-
-	usepairs = 0;
-
-	--argc;
-	++argv;
-
-	if (argc != 2){
-		usage();
-	}
-
-	out = fopen(argv[0], "a");
-	if (out == NULL) {
-		fatal("can't open %s", argv[0]);
-	}
-
-	in = fopen(argv[1], "r");
-
-	if (in == NULL) {
-		fatal("can't open %s", argv[1]);
-	}
-
-	for(i = 0; i < NRUNES; i++){
-		mytoupper[i] = i;
-		mytolower[i] = i;
-		mytotitle[i] = i;
-	}
-
-	/*
-	 * make sure isspace has all of the "C" locale whitespace chars
-	 */
-	myisspace['\t'] = 1;
-	myisspace['\n'] = 1;
-	myisspace['\r'] = 1;
-	myisspace['\f'] = 1;
-	myisspace['\v'] = 1;
-
-	/*
-	 * a couple of other exceptions
-	 */
-	myisspace[0x85] = 1;	/* control char, "next line" */
-	myisspace[0xfeff] = 1;  /* zero-width non-break space */
-
-	last = -1;
-	while(getunicodeline(in, fields, buf)){
-		code = getcode(fields[FIELD_CODE]);
-		if (code >= NRUNES)
-			fatal("code-point value too big: %x", code);
-		if(code <= last)
-			fatal("bad code sequence: %x then %x", last, code);
-		last = code;
-
-		/*
-		 * check for ranges
-		 */
-		p = fields[FIELD_CATEGORY];
-		if(strstr(fields[FIELD_NAME], ", First>") != NULL){
-			if(!getunicodeline(in, fields2, buf2))
-				fatal("range start at eof");
-			if (strstr(fields2[FIELD_NAME], ", Last>") == NULL)
-				fatal("range start not followed by range end");
-			last = getcode(fields2[FIELD_CODE]);
-			if(last <= code)
-				fatal("range out of sequence: %x then %x", code, last);
-			if(strcmp(p, fields2[FIELD_CATEGORY]) != 0)
-				fatal("range with mismatched category");
-		}
-
-		/*
-		 * set properties and conversions
-		 */
-		for (; code <= last; code++){
-			if(p[0] == 'L')
-				myisalpha[code] = 1;
-			if(p[0] == 'Z')
-				myisspace[code] = 1;
-
-			if(strcmp(p, "Lu") == 0)
-				myisupper[code] = 1;
-			if(strcmp(p, "Ll") == 0)
-				myislower[code] = 1;
-
-			if(strcmp(p, "Lt") == 0)
-				myistitle[code] = 1;
-
-			if(strcmp(p, "Nd") == 0)
-				myisdigit[code] = 1;
-
-			/*
-			 * when finding conversions, also need to mark
-			 * upper/lower case, since some chars, like
-			 * "III" (0x2162), aren't defined as letters but have a
-			 * lower case mapping ("iii" (0x2172)).
-			 */
-			if(fields[FIELD_UPPER][0] != '\0'){
-				mytoupper[code] = getcode(fields[FIELD_UPPER]);
-			}
-			if(fields[FIELD_LOWER][0] != '\0'){
-				mytolower[code] = getcode(fields[FIELD_LOWER]);
-			}
-			if(fields[FIELD_TITLE][0] != '\0'){
-				mytotitle[code] = getcode(fields[FIELD_TITLE]);
-			}
-		}
-	}
-
-	fclose(in);
-
-	/*
-	 * check for codes with no totitle mapping but a toupper mapping.
-	 * these appear in UnicodeData-2.0.14.txt, but are almost certainly
-	 * erroneous.
-	 */
-	for(i = 0; i < NRUNES; i++){
-		if(mytotitle[i] == i
-		&& mytoupper[i] != i
-		&& !myistitle[i])
-			fprintf(stderr, "warning: code=%.4x not istitle, totitle is same, toupper=%.4x\n", i, mytoupper[i]);
-	}
-
-	/*
-	 * make sure isupper[c] is true if for some x toupper[x]  == c
-	 * ditto for islower and istitle
-	 */
-	for(i = 0; i < NRUNES; i++) {
-		if(mytoupper[i] != i)
-			myisupper[mytoupper[i]] = 1;
-		if(mytolower[i] != i)
-			myislower[mytolower[i]] = 1;
-		if(mytotitle[i] != i)
-			myistitle[mytotitle[i]] = 1;
-	}
-
-	mktables(argv[0], usepairs);
-	exit(0);
-}
-
-/*
- * generate a properties array for ranges, clearing those cases covered.
- * if force, generate one-entry ranges for singletons.
- */
-static int
-mkisrange(const char* label, char* prop, int force)
-{
-	int start, stop, some;
-
-	/*
-	 * first, the ranges
-	 */
-	some = 0;
-	for(start = 0; start < NRUNES; ) {
-		if(!prop[start]){
-			start++;
-			continue;
-		}
-
-		for(stop = start + 1; stop < NRUNES; stop++){
-			if(!prop[stop]){
-				break;
-			}
-			prop[stop] = 0;
-		}
-		if(force || stop != start + 1){
-			if(!some){
-				fprintf(out, "static const uint32_t is%sr[] = {\n", label);
-				some = 1;
-			}
-			prop[start] = 0;
-			fprintf(out, "\t0x%.4x, 0x%.4x,\n", start, stop - 1);
-		}
-
-		start = stop;
-	}
-	if(some) {
-		fprintf(out, "};\n\n");
-	}
-
-	return some;
-}
-
-/*
- * generate a mapping array for pairs with a skip between,
- * clearing those entries covered.
- */
-static int
-mkispair(const char *label, char *prop)
-{
-	int start, stop, some;
-
-	some = 0;
-	for(start = 0; start + 2 < NRUNES; ) {
-		if(!prop[start]){
-			start++;
-			continue;
-		}
-
-		for(stop = start + 2; stop < NRUNES; stop += 2){
-			if(!prop[stop]){
-				break;
-			}
-			prop[stop] = 0;
-		}
-		if(stop != start + 2){
-			if(!some){
-				fprintf(out, "static const uint32_t is%sp[] = {\n", label);
-				some = 1;
-			}
-			prop[start] = 0;
-			fprintf(out, "\t0x%.4x, 0x%.4x,\n", start, stop - 2);
-		}
-
-		start = stop;
-	}
-	if(some) {
-		fprintf(out, "};\n\n");
-	}
-	return some;
-}
-
-/*
- * generate a properties array for singletons, clearing those cases covered.
- */
-static int
-mkissingle(const char *label, char *prop)
-{
-	int start, some;
-
-	some = 0;
-	for(start = 0; start < NRUNES; start++) {
-		if(!prop[start]){
-			continue;
-		}
-
-		if(!some){
-			fprintf(out, "static const uint32_t is%ss[] = {\n", label);
-			some = 1;
-		}
-		prop[start] = 0;
-		fprintf(out, "\t0x%.4x,\n", start);
-	}
-	if(some) {
-		fprintf(out, "};\n\n");
-	}
-	return some;
-}
-
-/*
- * generate tables and a function for is<label>rune
- */
-static void
-mkis(const char* label, char* prop, int usepairs)
-{
-	int isr, isp, iss;
-
-	isr = mkisrange(label, prop, 0);
-	isp = 0;
-	if(usepairs)
-		isp = mkispair(label, prop);
-	iss = mkissingle(label, prop);
-
-	fprintf(out,
-		"int\n"
-		"uni_is%s(uint32_t c)\n"
-		"{\n"
-		"\tconst uint32_t *p;\n"
-		"\n",
-		label);
-
-	if(isr)
-		fprintf(out,
-			"\tp = search(c, is%sr, nelem (is%sr) / 2, 2);\n\n"
-			"\tif (p && c >= p[0] && c <= p[1])\n"
-			"\t\treturn 1;\n",
-			label, label);
-
-	if(isp)
-		fprintf(out,
-			"\n"
-			"\tp = search(c, is%sp, nelem (is%sp) / 2, 2);\n\n"
-			"\tif (p && c >= p[0] && c <= p[1] && !((c - p[0]) & 1))\n"
-			"\t\treturn 1;\n",
-			label, label);
-
-	if(iss)
-		fprintf(out,
-			"\n"
-			"\tp = search(c, is%ss, nelem (is%ss), 1);\n\n"
-			"\tif (p && c == p[0])\n"
-			"\t\treturn 1;\n",
-			label, label);
-
-
-	fprintf(out,
-		"\n"
-		"\treturn 0;\n"
-		"}\n"
-		"\n"
-	);
-}
-
-/*
- * generate a mapping array for ranges, clearing those entries covered.
- * if force, generate one-entry ranges for singletons.
- */
-static int
-mktorange(const char* label, int* map, int force)
-{
-	int start, stop, delta, some;
-
-	some = 0;
-	for(start = 0; start < NRUNES; ) {
-		if(map[start] == start){
-			start++;
-			continue;
-		}
-
-		delta = TO_DELTA(map[start], start);
-		if(delta != (Rune)delta)
-			fatal("bad map delta %d", delta);
-		for(stop = start + 1; stop < NRUNES; stop++){
-			if(TO_DELTA(map[stop], stop) != delta){
-				break;
-			}
-			map[stop] = stop;
-		}
-		if(stop != start + 1){
-			if(!some){
-				fprintf(out, "static const uint32_t to%sr[] = {\n", label);
-				some = 1;
-			}
-			map[start] = start;
-			fprintf(out, "\t0x%.4x, 0x%.4x, %d,\n", start, stop - 1, delta);
-		}
-
-		start = stop;
-	}
-	if(some) {
-		fprintf(out, "};\n\n");
-	}
-
-	return some;
-}
-
-/*
- * generate a mapping array for pairs with a skip between,
- * clearing those entries covered.
- */
-static int
-mktopair(const char* label, int* map)
-{
-	int start, stop, delta, some;
-
-	some = 0;
-	for(start = 0; start + 2 < NRUNES; ) {
-		if(map[start] == start){
-			start++;
-			continue;
-		}
-
-		delta = TO_DELTA(map[start], start);
-		if(delta != (Rune)delta)
-			fatal("bad map delta %d", delta);
-		for(stop = start + 2; stop < NRUNES; stop += 2){
-			if(TO_DELTA(map[stop], stop) != delta){
-				break;
-			}
-			map[stop] = stop;
-		}
-		if(stop != start + 2){
-			if(!some){
-				fprintf(out, "static const uint32_t to%sp[] = {\n", label);
-				some = 1;
-			}
-			map[start] = start;
-			fprintf(out, "\t0x%.4x, 0x%.4x, %d,\n", start, stop - 2, delta);
-		}
-
-		start = stop;
-	}
-	if(some) {
-		fprintf(out, "};\n\n");
-	}
-
-	return some;
-}
-
-/*
- * generate a mapping array for singletons, clearing those entries covered.
- */
-static int
-mktosingle(const char* label, int* map)
-{
-	int start, delta, some;
-
-	some = 0;
-	for(start = 0; start < NRUNES; start++) {
-		if(map[start] == start){
-			continue;
-		}
-
-		delta = TO_DELTA(map[start], start);
-		if(delta != (Rune)delta)
-			fatal("bad map delta %d", delta);
-		if(!some){
-			fprintf(out, "static const uint32_t to%ss[] = {\n", label);
-			some = 1;
-		}
-		map[start] = start;
-		fprintf(out, "\t0x%.4x, %d,\n", start, delta);
-	}
-	if(some) {
-		fprintf(out, "};\n\n");
-	}
-
-	return some;
-}
-
-/*
- * generate tables and a function for to<label>rune
- */
-static void
-mkto(const char* label, int* map, int usepairs)
-{
-	int tor, top, tos;
-
-	tor = mktorange(label, map, 0);
-	top = 0;
-	if(usepairs)
-		top = mktopair(label, map);
-	tos = mktosingle(label, map);
-
-	fprintf(out,
-		"uint32_t\n"
-		"uni_to%s(uint32_t c)\n"
-		"{\n"
-		"\tconst uint32_t *p;\n"
-		"\n",
-		label);
-
-	if(tor)
-		fprintf(out,
-			"\tp = search(c, to%sr, nelem (to%sr) / 3, 3);\n\n"
-			"\tif (p && c >= p[0] && c <= p[1])\n"
-			"\t\treturn c + p[2] - %d;\n",
-			label, label, TO_OFFSET);
-
-	if(top)
-		fprintf(out,
-			"\n"
-			"\tp = search(c, to%sp, nelem (to%sp) / 3, 3);\n\n"
-			"\tif (p && c >= p[0] && c <= p[1] && !((c - p[0]) & 1))\n"
-			"\t\treturn c + p[2] - %d;\n",
-			label, label, TO_OFFSET);
-
-	if(tos)
-		fprintf(out,
-			"\n"
-			"\tp = search(c, to%ss, nelem (to%ss) / 2, 2);\n\n"
-			"\tif (p && c == p[0])\n"
-			"\t\treturn c + p[1] - %d;\n\n",
-			label, label, TO_OFFSET);
-
-	fprintf(out,
-		"\treturn c;\n"
-		"}\n"
-		"\n"
-	);
-}
-
-// Make only range tables and a function for is<label>rune.
-static void
-mkisronly(const char* label, char* prop)
-{
-	mkisrange(label, prop, 1);
-	fprintf(out,
-		"int\n"
-		"uni_is%s(uint32_t c)\n"
-		"{\n"
-		"\tconst uint32_t *p;\n"
-		"\n"
-		"\tp = search(c, is%sr, nelem (is%sr) / 2, 2);\n\n"
-		"\tif (p && c >= p[0] && c <= p[1])\n"
-		"\t\treturn 1;\n\n"
-		"\treturn 0;\n"
-		"}\n"
-		"\n",
-			label, label, label);
-}
-
-/*
- * generate the body of runetype.
- * assumes there is a function Rune* search(Rune c, Rune *t, int n, int ne);
- */
-static void
-mktables(char *src, int usepairs)
-{
-	/* Add nelem macro */
-	fprintf(out,
-		"#define nelem(x) (sizeof (x) / sizeof ((x)[0]))\n\n"
-	);
-
-	/* Add the search function */
-	fprintf(out,
-		"static const uint32_t *\n"
-		"search(uint32_t c, const uint32_t *t, int n, int ne)\n"
-		"{\n"
-		"\tconst uint32_t *p;\n"
-		"\tint m;\n\n"
-		"\twhile (n > 1) {\n"
-		"\t\tm = n >> 1;\n"
-		"\t\tp = t + m * ne;\n\n"
-		"\t\tif (c >= p[0]) {\n"
-		"\t\t\tt = p;\n"
-		"\t\t\tn = n - m;\n"
-		"\t\t} else\n"
-		"\t\t\tn = m;\n"
-		"\t}\n\n"
-		"\tif (n && c >= t[0])\n"
-		"\t\treturn t;\n\n"
-		"\treturn NULL;\n"
-		"}\n\n"
-	);
-
-	/*
-	 * we special case the space and digit tables, since they are assumed
-	 * to be small with several ranges.
-	 */
-	mkisronly("space", myisspace);
-	mkisronly("digit", myisdigit);
-
-	mkis("alpha", myisalpha, 0);
-	mkis("upper", myisupper, usepairs);
-	mkis("lower", myislower, usepairs);
-	mkis("title", myistitle, usepairs);
-
-	mkto("upper", mytoupper, usepairs);
-	mkto("lower", mytolower, usepairs);
-	mkto("title", mytotitle, usepairs);
-}
-
-static int
-mygetfields(char **fields, int nfields, char *str, const char *delim)
-{
-	int nf;
-
-	fields[0] = str;
-	nf = 1;
-	if(nf >= nfields)
-		return nf;
-
-	for(; *str; str++){
-		if(strchr(delim, *str) != NULL){
-			*str = '\0';
-			fields[nf++] = str + 1;
-			if(nf >= nfields)
-				break;
-		}
-	}
-	return nf;
-}
-
-static int
-getunicodeline(FILE *in, char **fields, char *buf)
-{
-	char *p;
-
-	if(fgets(buf, MAX_LINE, in) == NULL)
-		return 0;
-
-	p = strchr(buf, '\n');
-	if (p == NULL)
-		fatal("line too long");
-	*p = '\0';
-
-	if (mygetfields(fields, NFIELDS + 1, buf, ";") != NFIELDS)
-		fatal("bad number of fields");
-
-	return 1;
-}
-
-static int
-getcode(char *s)
-{
-	int i, code;
-
-	code = 0;
-	i = 0;
-	/* Parse a hex number */
-	while(s[i]) {
-		code <<= 4;
-		if(s[i] >= '0' && s[i] <= '9')
-			code += s[i] - '0';
-		else if(s[i] >= 'A' && s[i] <= 'F')
-			code += s[i] - 'A' + 10;
-		else
-			fatal("bad code char '%c'", s[i]);
-		i++;
-	}
-	return code;
-}
-
-static void
-fatal(const char *fmt, ...)
-{
-	va_list arg;
-
-	fprintf(stderr, "mkunicode: fatal error: ");
-	va_start(arg, fmt);
-	vfprintf(stderr, fmt, arg);
-	va_end(arg);
-	fprintf(stderr, "\n");
-
-	exit(1);
-}
--- a/gen/src/utf.h	Sun Jan 02 10:21:47 2022 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,239 +0,0 @@
-/*
- * The authors of this software are Rob Pike and Ken Thompson.
- *              Copyright (c) 1998-2002 by Lucent Technologies.
- *              Portions Copyright (c) 2009 The Go Authors.  All rights reserved.
- * Permission to use, copy, modify, and distribute this software for any
- * purpose without fee is hereby granted, provided that this entire notice
- * is included in all copies of any software which is or includes a copy
- * or modification of this software and in all copies of the supporting
- * documentation for such software.
- * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
- * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
- * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
- */
-
-#ifndef _UTFH_
-#define _UTFH_ 1
-
-typedef unsigned int Rune;  /* Code-point values in Unicode 4.0 are 21 bits wide.*/
-
-enum {
-        UTFmax    = 4,        /* maximum bytes per rune */
-        Runesync  = 0x80,     /* cannot represent part of a UTF sequence (<) */
-        Runeself  = 0x80,     /* rune and UTF sequences are the same (<) */
-        Runeerror = 0xFFFD,   /* decoding error in UTF */
-        Runemax   = 0x10FFFF, /* maximum rune value */
-};
-
-#ifdef  __cplusplus
-extern "C" {
-#endif
-
-/*
- * rune routines
- */
-
-/*
- * These routines were written by Rob Pike and Ken Thompson
- * and first appeared in Plan 9.
- * SEE ALSO
- * utf (7)
- * tcs (1)
-*/
-
-// runetochar copies (encodes) one rune, pointed to by r, to at most
-// UTFmax bytes starting at s and returns the number of bytes generated.
-
-int runetochar(char* s, const Rune* r);
-
-
-// chartorune copies (decodes) at most UTFmax bytes starting at s to
-// one rune, pointed to by r, and returns the number of bytes consumed.
-// If the input is not exactly in UTF format, chartorune will set *r
-// to Runeerror and return 1.
-//
-// Note: There is no special case for a "null-terminated" string. A
-// string whose first byte has the value 0 is the UTF8 encoding of the
-// Unicode value 0 (i.e., ASCII NULL). A byte value of 0 is illegal
-// anywhere else in a UTF sequence.
-
-int chartorune(Rune* r, const char* s);
-
-
-// charntorune is like chartorune, except that it will access at most
-// n bytes of s.  If the UTF sequence is incomplete within n bytes,
-// charntorune will set *r to Runeerror and return 0. If it is complete
-// but not in UTF format, it will set *r to Runeerror and return 1.
-//
-// Added 2004-09-24 by Wei-Hwa Huang
-
-int charntorune(Rune* r, const char* s, int n);
-
-// isvalidcharntorune(str, n, r, consumed)
-// is a convenience function that calls "*consumed = charntorune(r, str, n)"
-// and returns an int (logically boolean) indicating whether the first
-// n bytes of str was a valid and complete UTF sequence.
-
-int isvalidcharntorune(const char* str, int n, Rune* r, int* consumed);
-
-// runelen returns the number of bytes required to convert r into UTF.
-
-int runelen(Rune r);
-
-
-// runenlen returns the number of bytes required to convert the n
-// runes pointed to by r into UTF.
-
-int runenlen(const Rune* r, int n);
-
-
-// fullrune returns 1 if the string s of length n is long enough to be
-// decoded by chartorune, and 0 otherwise. This does not guarantee
-// that the string contains a legal UTF encoding. This routine is used
-// by programs that obtain input one byte at a time and need to know
-// when a full rune has arrived.
-
-int fullrune(const char* s, int n);
-
-// The following routines are analogous to the corresponding string
-// routines with "utf" substituted for "str", and "rune" substituted
-// for "chr".
-
-// utflen returns the number of runes that are represented by the UTF
-// string s. (cf. strlen)
-
-int utflen(const char* s);
-
-
-// utfnlen returns the number of complete runes that are represented
-// by the first n bytes of the UTF string s. If the last few bytes of
-// the string contain an incompletely coded rune, utfnlen will not
-// count them; in this way, it differs from utflen, which includes
-// every byte of the string. (cf. strnlen)
-
-int utfnlen(const char* s, long n);
-
-
-// utfrune returns a pointer to the first occurrence of rune r in the
-// UTF string s, or 0 if r does not occur in the string.  The NULL
-// byte terminating a string is considered to be part of the string s.
-// (cf. strchr)
-
-/*const*/ char* utfrune(const char* s, Rune r);
-
-
-// utfrrune returns a pointer to the last occurrence of rune r in the
-// UTF string s, or 0 if r does not occur in the string.  The NULL
-// byte terminating a string is considered to be part of the string s.
-// (cf. strrchr)
-
-/*const*/ char* utfrrune(const char* s, Rune r);
-
-
-// utfutf returns a pointer to the first occurrence of the UTF string
-// s2 as a UTF substring of s1, or 0 if there is none. If s2 is the
-// null string, utfutf returns s1. (cf. strstr)
-
-const char* utfutf(const char* s1, const char* s2);
-
-
-// utfecpy copies UTF sequences until a null sequence has been copied,
-// but writes no sequences beyond es1.  If any sequences are copied,
-// s1 is terminated by a null sequence, and a pointer to that sequence
-// is returned.  Otherwise, the original s1 is returned. (cf. strecpy)
-
-char* utfecpy(char *s1, char *es1, const char *s2);
-
-
-
-// These functions are rune-string analogues of the corresponding
-// functions in strcat (3).
-//
-// These routines first appeared in Plan 9.
-// SEE ALSO
-// memmove (3)
-// rune (3)
-// strcat (2)
-//
-// BUGS: The outcome of overlapping moves varies among implementations.
-
-Rune* runestrcat(Rune* s1, const Rune* s2);
-Rune* runestrncat(Rune* s1, const Rune* s2, long n);
-
-const Rune* runestrchr(const Rune* s, Rune c);
-
-int runestrcmp(const Rune* s1, const Rune* s2);
-int runestrncmp(const Rune* s1, const Rune* s2, long n);
-
-Rune* runestrcpy(Rune* s1, const Rune* s2);
-Rune* runestrncpy(Rune* s1, const Rune* s2, long n);
-Rune* runestrecpy(Rune* s1, Rune* es1, const Rune* s2);
-
-Rune* runestrdup(const Rune* s);
-
-const Rune* runestrrchr(const Rune* s, Rune c);
-long runestrlen(const Rune* s);
-const Rune* runestrstr(const Rune* s1, const Rune* s2);
-
-
-
-// The following routines test types and modify cases for Unicode
-// characters.  Unicode defines some characters as letters and
-// specifies three cases: upper, lower, and title.  Mappings among the
-// cases are also defined, although they are not exhaustive: some
-// upper case letters have no lower case mapping, and so on.  Unicode
-// also defines several character properties, a subset of which are
-// checked by these routines.  These routines are based on Unicode
-// version 3.0.0.
-//
-// NOTE: The routines are implemented in C, so the boolean functions
-// (e.g., isupperrune) return 0 for false and 1 for true.
-//
-//
-// toupperrune, tolowerrune, and totitlerune are the Unicode case
-// mappings. These routines return the character unchanged if it has
-// no defined mapping.
-
-Rune toupperrune(Rune r);
-Rune tolowerrune(Rune r);
-Rune totitlerune(Rune r);
-
-
-// isupperrune tests for upper case characters, including Unicode
-// upper case letters and targets of the toupper mapping. islowerrune
-// and istitlerune are defined analogously.
-
-int isupperrune(Rune r);
-int islowerrune(Rune r);
-int istitlerune(Rune r);
-
-
-// isalpharune tests for Unicode letters; this includes ideographs in
-// addition to alphabetic characters.
-
-int isalpharune(Rune r);
-
-
-// isdigitrune tests for digits. Non-digit numbers, such as Roman
-// numerals, are not included.
-
-int isdigitrune(Rune r);
-
-
-// isspacerune tests for whitespace characters, including "C" locale
-// whitespace, Unicode defined whitespace, and the "zero-width
-// non-break space" character.
-
-int isspacerune(Rune r);
-
-
-// (The comments in this file were copied from the manpage files rune.3,
-// isalpharune.3, and runestrcat.3. Some formatting changes were also made
-// to conform to Google style. /JRM 11/11/05)
-
-#ifdef  __cplusplus
-}
-#endif
-
-#endif
--- a/gen/src/utfdef.h	Sun Jan 02 10:21:47 2022 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-/*
- * The authors of this software are Rob Pike and Ken Thompson.
- *              Copyright (c) 1998-2002 by Lucent Technologies.
- * Permission to use, copy, modify, and distribute this software for any
- * purpose without fee is hereby granted, provided that this entire notice
- * is included in all copies of any software which is or includes a copy
- * or modification of this software and in all copies of the supporting
- * documentation for such software.
- * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
- * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
- * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
- */
-
-#define uchar _utfuchar
-#define ushort _utfushort
-#define uint _utfuint
-#define ulong _utfulong
-#define vlong _utfvlong
-#define uvlong _utfuvlong
-
-typedef unsigned char       uchar;
-typedef unsigned short      ushort;
-typedef unsigned int        uint;
-typedef unsigned long       ulong;
-
-#define nelem(x) (sizeof(x)/sizeof((x)[0]))
\ No newline at end of file
--- a/gen/unicode-before.c	Sun Jan 02 10:21:47 2022 +0100
+++ b/gen/unicode-before.c	Mon Mar 21 09:00:42 2022 +0100
@@ -22,8 +22,24 @@
 
 #include "unicode.h"
 
-/*
- * The following code has been generated from Go mkrunetype adapted to our
- * needs.
- */
+#define nelem(x) (sizeof (x) / sizeof *(x))
+
+static int
+cmp1(const void *v1, const void *v2)
+{
+	uint32_t r1 = *(uint32_t *)v1, r2 = *(uint32_t *)v2;
+
+	return r1 - r2;
+}
 
+static int
+cmp2(const void *v1, const void *v2)
+{
+	uint32_t r = *(uint32_t *)v1, *p = (uint32_t *)v2;
+
+	if(r >= p[0] && r <= p[1])
+		return 0;
+	else
+		return r - p[0];
+}
+
--- a/libunicode.3	Sun Jan 02 10:21:47 2022 +0100
+++ b/libunicode.3	Mon Mar 21 09:00:42 2022 +0100
@@ -44,6 +44,8 @@
 .Ft int
 .Fn uni_isalpha "uint32_t c"
 .Ft int
+.Fn uni_iscontrol "uint32_t c"
+.Ft int
 .Fn uni_isdigit "uint32_t c"
 .Ft int
 .Fn uni_islower "uint32_t c"
@@ -163,47 +165,53 @@
 The
 .Fn uni_isalpha
 returns non-zero if the the unicode character
-.Fa point
+.Fa c
 is considered alphanumeric class.
 .Pp
 The
+.Fn uni_iscontrol
+returns non-zero if the unicode character
+.Fa c
+is considered as a control character class.
+.Pp
+The
 .Fn uni_isdigit
 returns non-zero if the the unicode character
-.Fa point
+.Fa c
 is considered numeric class.
 .Pp
 The
 .Fn uni_islower
 returns non-zero if the the unicode character
-.Fa point
+.Fa c
 is considered lower case class.
 .Pp
 The
 .Fn uni_istitle
 returns non-zero if the the unicode character
-.Fa point
+.Fa c
 is considered title case class.
 .Pp
 The
 .Fn uni_isupper
 returns non-zero if the the unicode character
-.Fa point
+.Fa c
 is considered upper case class.
 .Pp
 The
 .Fn uni_toupper
 returns the upper case variant of the unicode character
-.Fa point .
+.Fa c .
 .Pp
 The
 .Fn uni_tolower
 returns the lower case variant of the unicode character
-.Fa point .
+.Fa c .
 .Pp
 The
 .Fn uni_totitle
 returns the title case variant of the unicode character
-.Fa point .
+.Fa c .
 .\" RETURN VALUES
 .Sh RETURN VALUES
 The
--- a/unicode.c	Sun Jan 02 10:21:47 2022 +0100
+++ b/unicode.c	Mon Mar 21 09:00:42 2022 +0100
@@ -22,4822 +22,1592 @@
 
 #include "unicode.h"
 
-/*
- * The following code has been generated from Go mkrunetype adapted to our
- * needs.
- */
-
-#define nelem(x) (sizeof (x) / sizeof ((x)[0]))
-
-static const uint32_t *
-search(uint32_t c, const uint32_t *t, int n, int ne)
-{
-	const uint32_t *p;
-	int m;
-
-	while (n > 1) {
-		m = n >> 1;
-		p = t + m * ne;
-
-		if (c >= p[0]) {
-			t = p;
-			n = n - m;
-		} else
-			n = m;
-	}
-
-	if (n && c >= t[0])
-		return t;
+#define nelem(x) (sizeof (x) / sizeof *(x))
 
-	return NULL;
-}
+static int
+cmp1(const void *v1, const void *v2)
+{
+	uint32_t r1 = *(uint32_t *)v1, r2 = *(uint32_t *)v2;
 
-static const uint32_t isspacer[] = {
-	0x0009, 0x000d,
-	0x0020, 0x0020,
-	0x0085, 0x0085,
-	0x00a0, 0x00a0,
-	0x1680, 0x1680,
-	0x2000, 0x200a,
-	0x2028, 0x2029,
-	0x202f, 0x202f,
-	0x205f, 0x205f,
-	0x3000, 0x3000,
-	0xfeff, 0xfeff,
-};
-
-int
-uni_isspace(uint32_t c)
-{
-	const uint32_t *p;
-
-	p = search(c, isspacer, nelem (isspacer) / 2, 2);
-
-	if (p && c >= p[0] && c <= p[1])
-		return 1;
-
-	return 0;
+	return r1 - r2;
 }
 
-static const uint32_t isdigitr[] = {
-	0x0030, 0x0039,
-	0x0660, 0x0669,
-	0x06f0, 0x06f9,
-	0x07c0, 0x07c9,
-	0x0966, 0x096f,
-	0x09e6, 0x09ef,
-	0x0a66, 0x0a6f,
-	0x0ae6, 0x0aef,
-	0x0b66, 0x0b6f,
-	0x0be6, 0x0bef,
-	0x0c66, 0x0c6f,
-	0x0ce6, 0x0cef,
-	0x0d66, 0x0d6f,
-	0x0de6, 0x0def,
-	0x0e50, 0x0e59,
-	0x0ed0, 0x0ed9,
-	0x0f20, 0x0f29,
-	0x1040, 0x1049,
-	0x1090, 0x1099,
-	0x17e0, 0x17e9,
-	0x1810, 0x1819,
-	0x1946, 0x194f,
-	0x19d0, 0x19d9,
-	0x1a80, 0x1a89,
-	0x1a90, 0x1a99,
-	0x1b50, 0x1b59,
-	0x1bb0, 0x1bb9,
-	0x1c40, 0x1c49,
-	0x1c50, 0x1c59,
-	0xa620, 0xa629,
-	0xa8d0, 0xa8d9,
-	0xa900, 0xa909,
-	0xa9d0, 0xa9d9,
-	0xa9f0, 0xa9f9,
-	0xaa50, 0xaa59,
-	0xabf0, 0xabf9,
-	0xff10, 0xff19,
-	0x104a0, 0x104a9,
-	0x10d30, 0x10d39,
-	0x11066, 0x1106f,
-	0x110f0, 0x110f9,
-	0x11136, 0x1113f,
-	0x111d0, 0x111d9,
-	0x112f0, 0x112f9,
-	0x11450, 0x11459,
-	0x114d0, 0x114d9,
-	0x11650, 0x11659,
-	0x116c0, 0x116c9,
-	0x11730, 0x11739,
-	0x118e0, 0x118e9,
-	0x11950, 0x11959,
-	0x11c50, 0x11c59,
-	0x11d50, 0x11d59,
-	0x11da0, 0x11da9,
-	0x16a60, 0x16a69,
-	0x16b50, 0x16b59,
-	0x1d7ce, 0x1d7ff,
-	0x1e140, 0x1e149,
-	0x1e2f0, 0x1e2f9,
-	0x1e950, 0x1e959,
-	0x1fbf0, 0x1fbf9,
-};
+static int
+cmp2(const void *v1, const void *v2)
+{
+	uint32_t r = *(uint32_t *)v1, *p = (uint32_t *)v2;
 
-int
-uni_isdigit(uint32_t c)
-{
-	const uint32_t *p;
-
-	p = search(c, isdigitr, nelem (isdigitr) / 2, 2);
-
-	if (p && c >= p[0] && c <= p[1])
-		return 1;
-
-	return 0;
+	if(r >= p[0] && r <= p[1])
+		return 0;
+	else
+		return r - p[0];
 }
 
-static const uint32_t isalphar[] = {
-	0x0041, 0x005a,
-	0x0061, 0x007a,
-	0x00c0, 0x00d6,
-	0x00d8, 0x00f6,
-	0x00f8, 0x02c1,
-	0x02c6, 0x02d1,
-	0x02e0, 0x02e4,
-	0x0370, 0x0374,
-	0x0376, 0x0377,
-	0x037a, 0x037d,
-	0x0388, 0x038a,
-	0x038e, 0x03a1,
-	0x03a3, 0x03f5,
-	0x03f7, 0x0481,
-	0x048a, 0x052f,
-	0x0531, 0x0556,
-	0x0560, 0x0588,
-	0x05d0, 0x05ea,
-	0x05ef, 0x05f2,
-	0x0620, 0x064a,
-	0x066e, 0x066f,
-	0x0671, 0x06d3,
-	0x06e5, 0x06e6,
-	0x06ee, 0x06ef,
-	0x06fa, 0x06fc,
-	0x0712, 0x072f,
-	0x074d, 0x07a5,
-	0x07ca, 0x07ea,
-	0x07f4, 0x07f5,
-	0x0800, 0x0815,
-	0x0840, 0x0858,
-	0x0860, 0x086a,
-	0x08a0, 0x08b4,
-	0x08b6, 0x08c7,
-	0x0904, 0x0939,
-	0x0958, 0x0961,
-	0x0971, 0x0980,
-	0x0985, 0x098c,
-	0x098f, 0x0990,
-	0x0993, 0x09a8,
-	0x09aa, 0x09b0,
-	0x09b6, 0x09b9,
-	0x09dc, 0x09dd,
-	0x09df, 0x09e1,
-	0x09f0, 0x09f1,
-	0x0a05, 0x0a0a,
-	0x0a0f, 0x0a10,
-	0x0a13, 0x0a28,
-	0x0a2a, 0x0a30,
-	0x0a32, 0x0a33,
-	0x0a35, 0x0a36,
-	0x0a38, 0x0a39,
-	0x0a59, 0x0a5c,
-	0x0a72, 0x0a74,
-	0x0a85, 0x0a8d,
-	0x0a8f, 0x0a91,
-	0x0a93, 0x0aa8,
-	0x0aaa, 0x0ab0,
-	0x0ab2, 0x0ab3,
-	0x0ab5, 0x0ab9,
-	0x0ae0, 0x0ae1,
-	0x0b05, 0x0b0c,
-	0x0b0f, 0x0b10,
-	0x0b13, 0x0b28,
-	0x0b2a, 0x0b30,
-	0x0b32, 0x0b33,
-	0x0b35, 0x0b39,
-	0x0b5c, 0x0b5d,
-	0x0b5f, 0x0b61,
-	0x0b85, 0x0b8a,
-	0x0b8e, 0x0b90,
-	0x0b92, 0x0b95,
-	0x0b99, 0x0b9a,
-	0x0b9e, 0x0b9f,
-	0x0ba3, 0x0ba4,
-	0x0ba8, 0x0baa,
-	0x0bae, 0x0bb9,
-	0x0c05, 0x0c0c,
-	0x0c0e, 0x0c10,
-	0x0c12, 0x0c28,
-	0x0c2a, 0x0c39,
-	0x0c58, 0x0c5a,
-	0x0c60, 0x0c61,
-	0x0c85, 0x0c8c,
-	0x0c8e, 0x0c90,
-	0x0c92, 0x0ca8,
-	0x0caa, 0x0cb3,
-	0x0cb5, 0x0cb9,
-	0x0ce0, 0x0ce1,
-	0x0cf1, 0x0cf2,
-	0x0d04, 0x0d0c,
-	0x0d0e, 0x0d10,
-	0x0d12, 0x0d3a,
-	0x0d54, 0x0d56,
-	0x0d5f, 0x0d61,
-	0x0d7a, 0x0d7f,
-	0x0d85, 0x0d96,
-	0x0d9a, 0x0db1,
-	0x0db3, 0x0dbb,
-	0x0dc0, 0x0dc6,
-	0x0e01, 0x0e30,
-	0x0e32, 0x0e33,
-	0x0e40, 0x0e46,
-	0x0e81, 0x0e82,
-	0x0e86, 0x0e8a,
-	0x0e8c, 0x0ea3,
-	0x0ea7, 0x0eb0,
-	0x0eb2, 0x0eb3,
-	0x0ec0, 0x0ec4,
-	0x0edc, 0x0edf,
-	0x0f40, 0x0f47,
-	0x0f49, 0x0f6c,
-	0x0f88, 0x0f8c,
-	0x1000, 0x102a,
-	0x1050, 0x1055,
-	0x105a, 0x105d,
-	0x1065, 0x1066,
-	0x106e, 0x1070,
-	0x1075, 0x1081,
-	0x10a0, 0x10c5,
-	0x10d0, 0x10fa,
-	0x10fc, 0x1248,
-	0x124a, 0x124d,
-	0x1250, 0x1256,
-	0x125a, 0x125d,
-	0x1260, 0x1288,
-	0x128a, 0x128d,
-	0x1290, 0x12b0,
-	0x12b2, 0x12b5,
-	0x12b8, 0x12be,
-	0x12c2, 0x12c5,
-	0x12c8, 0x12d6,
-	0x12d8, 0x1310,
-	0x1312, 0x1315,
-	0x1318, 0x135a,
-	0x1380, 0x138f,
-	0x13a0, 0x13f5,
-	0x13f8, 0x13fd,
-	0x1401, 0x166c,
-	0x166f, 0x167f,
-	0x1681, 0x169a,
-	0x16a0, 0x16ea,
-	0x16f1, 0x16f8,
-	0x1700, 0x170c,
-	0x170e, 0x1711,
-	0x1720, 0x1731,
-	0x1740, 0x1751,
-	0x1760, 0x176c,
-	0x176e, 0x1770,
-	0x1780, 0x17b3,
-	0x1820, 0x1878,
-	0x1880, 0x1884,
-	0x1887, 0x18a8,
-	0x18b0, 0x18f5,
-	0x1900, 0x191e,
-	0x1950, 0x196d,
-	0x1970, 0x1974,
-	0x1980, 0x19ab,
-	0x19b0, 0x19c9,
-	0x1a00, 0x1a16,
-	0x1a20, 0x1a54,
-	0x1b05, 0x1b33,
-	0x1b45, 0x1b4b,
-	0x1b83, 0x1ba0,
-	0x1bae, 0x1baf,
-	0x1bba, 0x1be5,
-	0x1c00, 0x1c23,
-	0x1c4d, 0x1c4f,
-	0x1c5a, 0x1c7d,
-	0x1c80, 0x1c88,
-	0x1c90, 0x1cba,
-	0x1cbd, 0x1cbf,
-	0x1ce9, 0x1cec,
-	0x1cee, 0x1cf3,
-	0x1cf5, 0x1cf6,
-	0x1d00, 0x1dbf,
-	0x1e00, 0x1f15,
-	0x1f18, 0x1f1d,
-	0x1f20, 0x1f45,
-	0x1f48, 0x1f4d,
-	0x1f50, 0x1f57,
-	0x1f5f, 0x1f7d,
-	0x1f80, 0x1fb4,
-	0x1fb6, 0x1fbc,
-	0x1fc2, 0x1fc4,
-	0x1fc6, 0x1fcc,
-	0x1fd0, 0x1fd3,
-	0x1fd6, 0x1fdb,
-	0x1fe0, 0x1fec,
-	0x1ff2, 0x1ff4,
-	0x1ff6, 0x1ffc,
-	0x2090, 0x209c,
-	0x210a, 0x2113,
-	0x2119, 0x211d,
-	0x212a, 0x212d,
-	0x212f, 0x2139,
-	0x213c, 0x213f,
-	0x2145, 0x2149,
-	0x2183, 0x2184,
-	0x2c00, 0x2c2e,
-	0x2c30, 0x2c5e,
-	0x2c60, 0x2ce4,
-	0x2ceb, 0x2cee,
-	0x2cf2, 0x2cf3,
-	0x2d00, 0x2d25,
-	0x2d30, 0x2d67,
-	0x2d80, 0x2d96,
-	0x2da0, 0x2da6,
-	0x2da8, 0x2dae,
-	0x2db0, 0x2db6,
-	0x2db8, 0x2dbe,
-	0x2dc0, 0x2dc6,
-	0x2dc8, 0x2dce,
-	0x2dd0, 0x2dd6,
-	0x2dd8, 0x2dde,
-	0x3005, 0x3006,
-	0x3031, 0x3035,
-	0x303b, 0x303c,
-	0x3041, 0x3096,
-	0x309d, 0x309f,
-	0x30a1, 0x30fa,
-	0x30fc, 0x30ff,
-	0x3105, 0x312f,
-	0x3131, 0x318e,
-	0x31a0, 0x31bf,
-	0x31f0, 0x31ff,
-	0x3400, 0x4dbf,
-	0x4e00, 0x9ffc,
-	0xa000, 0xa48c,
-	0xa4d0, 0xa4fd,
-	0xa500, 0xa60c,
-	0xa610, 0xa61f,
-	0xa62a, 0xa62b,
-	0xa640, 0xa66e,
-	0xa67f, 0xa69d,
-	0xa6a0, 0xa6e5,
-	0xa717, 0xa71f,
-	0xa722, 0xa788,
-	0xa78b, 0xa7bf,
-	0xa7c2, 0xa7ca,
-	0xa7f5, 0xa801,
-	0xa803, 0xa805,
-	0xa807, 0xa80a,
-	0xa80c, 0xa822,
-	0xa840, 0xa873,
-	0xa882, 0xa8b3,
-	0xa8f2, 0xa8f7,
-	0xa8fd, 0xa8fe,
-	0xa90a, 0xa925,
-	0xa930, 0xa946,
-	0xa960, 0xa97c,
-	0xa984, 0xa9b2,
-	0xa9e0, 0xa9e4,
-	0xa9e6, 0xa9ef,
-	0xa9fa, 0xa9fe,
-	0xaa00, 0xaa28,
-	0xaa40, 0xaa42,
-	0xaa44, 0xaa4b,
-	0xaa60, 0xaa76,
-	0xaa7e, 0xaaaf,
-	0xaab5, 0xaab6,
-	0xaab9, 0xaabd,
-	0xaadb, 0xaadd,
-	0xaae0, 0xaaea,
-	0xaaf2, 0xaaf4,
-	0xab01, 0xab06,
-	0xab09, 0xab0e,
-	0xab11, 0xab16,
-	0xab20, 0xab26,
-	0xab28, 0xab2e,
-	0xab30, 0xab5a,
-	0xab5c, 0xab69,
-	0xab70, 0xabe2,
-	0xac00, 0xd7a3,
-	0xd7b0, 0xd7c6,
-	0xd7cb, 0xd7fb,
-	0xf900, 0xfa6d,
-	0xfa70, 0xfad9,
-	0xfb00, 0xfb06,
-	0xfb13, 0xfb17,
-	0xfb1f, 0xfb28,
-	0xfb2a, 0xfb36,
-	0xfb38, 0xfb3c,
-	0xfb40, 0xfb41,
-	0xfb43, 0xfb44,
-	0xfb46, 0xfbb1,
-	0xfbd3, 0xfd3d,
-	0xfd50, 0xfd8f,
-	0xfd92, 0xfdc7,
-	0xfdf0, 0xfdfb,
-	0xfe70, 0xfe74,
-	0xfe76, 0xfefc,
-	0xff21, 0xff3a,
-	0xff41, 0xff5a,
-	0xff66, 0xffbe,
-	0xffc2, 0xffc7,
-	0xffca, 0xffcf,
-	0xffd2, 0xffd7,
-	0xffda, 0xffdc,
-	0x10000, 0x1000b,
-	0x1000d, 0x10026,
-	0x10028, 0x1003a,
-	0x1003c, 0x1003d,
-	0x1003f, 0x1004d,
-	0x10050, 0x1005d,
-	0x10080, 0x100fa,
-	0x10280, 0x1029c,
-	0x102a0, 0x102d0,
-	0x10300, 0x1031f,
-	0x1032d, 0x10340,
-	0x10342, 0x10349,
-	0x10350, 0x10375,
-	0x10380, 0x1039d,
-	0x103a0, 0x103c3,
-	0x103c8, 0x103cf,
-	0x10400, 0x1049d,
-	0x104b0, 0x104d3,
-	0x104d8, 0x104fb,
-	0x10500, 0x10527,
-	0x10530, 0x10563,
-	0x10600, 0x10736,
-	0x10740, 0x10755,
-	0x10760, 0x10767,
-	0x10800, 0x10805,
-	0x1080a, 0x10835,
-	0x10837, 0x10838,
-	0x1083f, 0x10855,
-	0x10860, 0x10876,
-	0x10880, 0x1089e,
-	0x108e0, 0x108f2,
-	0x108f4, 0x108f5,
-	0x10900, 0x10915,
-	0x10920, 0x10939,
-	0x10980, 0x109b7,
-	0x109be, 0x109bf,
-	0x10a10, 0x10a13,
-	0x10a15, 0x10a17,
-	0x10a19, 0x10a35,
-	0x10a60, 0x10a7c,
-	0x10a80, 0x10a9c,
-	0x10ac0, 0x10ac7,
-	0x10ac9, 0x10ae4,
-	0x10b00, 0x10b35,
-	0x10b40, 0x10b55,
-	0x10b60, 0x10b72,
-	0x10b80, 0x10b91,
-	0x10c00, 0x10c48,
-	0x10c80, 0x10cb2,
-	0x10cc0, 0x10cf2,
-	0x10d00, 0x10d23,
-	0x10e80, 0x10ea9,
-	0x10eb0, 0x10eb1,
-	0x10f00, 0x10f1c,
-	0x10f30, 0x10f45,
-	0x10fb0, 0x10fc4,
-	0x10fe0, 0x10ff6,
-	0x11003, 0x11037,
-	0x11083, 0x110af,
-	0x110d0, 0x110e8,
-	0x11103, 0x11126,
-	0x11150, 0x11172,
-	0x11183, 0x111b2,
-	0x111c1, 0x111c4,
-	0x11200, 0x11211,
-	0x11213, 0x1122b,
-	0x11280, 0x11286,
-	0x1128a, 0x1128d,
-	0x1128f, 0x1129d,
-	0x1129f, 0x112a8,
-	0x112b0, 0x112de,
-	0x11305, 0x1130c,
-	0x1130f, 0x11310,
-	0x11313, 0x11328,
-	0x1132a, 0x11330,
-	0x11332, 0x11333,
-	0x11335, 0x11339,
-	0x1135d, 0x11361,
-	0x11400, 0x11434,
-	0x11447, 0x1144a,
-	0x1145f, 0x11461,
-	0x11480, 0x114af,
-	0x114c4, 0x114c5,
-	0x11580, 0x115ae,
-	0x115d8, 0x115db,
-	0x11600, 0x1162f,
-	0x11680, 0x116aa,
-	0x11700, 0x1171a,
-	0x11800, 0x1182b,
-	0x118a0, 0x118df,
-	0x118ff, 0x11906,
-	0x1190c, 0x11913,
-	0x11915, 0x11916,
-	0x11918, 0x1192f,
-	0x119a0, 0x119a7,
-	0x119aa, 0x119d0,
-	0x11a0b, 0x11a32,
-	0x11a5c, 0x11a89,
-	0x11ac0, 0x11af8,
-	0x11c00, 0x11c08,
-	0x11c0a, 0x11c2e,
-	0x11c72, 0x11c8f,
-	0x11d00, 0x11d06,
-	0x11d08, 0x11d09,
-	0x11d0b, 0x11d30,
-	0x11d60, 0x11d65,
-	0x11d67, 0x11d68,
-	0x11d6a, 0x11d89,
-	0x11ee0, 0x11ef2,
-	0x12000, 0x12399,
-	0x12480, 0x12543,
-	0x13000, 0x1342e,
-	0x14400, 0x14646,
-	0x16800, 0x16a38,
-	0x16a40, 0x16a5e,
-	0x16ad0, 0x16aed,
-	0x16b00, 0x16b2f,
-	0x16b40, 0x16b43,
-	0x16b63, 0x16b77,
-	0x16b7d, 0x16b8f,
-	0x16e40, 0x16e7f,
-	0x16f00, 0x16f4a,
-	0x16f93, 0x16f9f,
-	0x16fe0, 0x16fe1,
-	0x17000, 0x187f7,
-	0x18800, 0x18cd5,
-	0x18d00, 0x18d08,
-	0x1b000, 0x1b11e,
-	0x1b150, 0x1b152,
-	0x1b164, 0x1b167,
-	0x1b170, 0x1b2fb,
-	0x1bc00, 0x1bc6a,
-	0x1bc70, 0x1bc7c,
-	0x1bc80, 0x1bc88,
-	0x1bc90, 0x1bc99,
-	0x1d400, 0x1d454,
-	0x1d456, 0x1d49c,
-	0x1d49e, 0x1d49f,
-	0x1d4a5, 0x1d4a6,
-	0x1d4a9, 0x1d4ac,
-	0x1d4ae, 0x1d4b9,
-	0x1d4bd, 0x1d4c3,
-	0x1d4c5, 0x1d505,
-	0x1d507, 0x1d50a,
-	0x1d50d, 0x1d514,
-	0x1d516, 0x1d51c,
-	0x1d51e, 0x1d539,
-	0x1d53b, 0x1d53e,
-	0x1d540, 0x1d544,
-	0x1d54a, 0x1d550,
-	0x1d552, 0x1d6a5,
-	0x1d6a8, 0x1d6c0,
-	0x1d6c2, 0x1d6da,
-	0x1d6dc, 0x1d6fa,
-	0x1d6fc, 0x1d714,
-	0x1d716, 0x1d734,
-	0x1d736, 0x1d74e,
-	0x1d750, 0x1d76e,
-	0x1d770, 0x1d788,
-	0x1d78a, 0x1d7a8,
-	0x1d7aa, 0x1d7c2,
-	0x1d7c4, 0x1d7cb,
-	0x1e100, 0x1e12c,
-	0x1e137, 0x1e13d,
-	0x1e2c0, 0x1e2eb,
-	0x1e800, 0x1e8c4,
-	0x1e900, 0x1e943,
-	0x1ee00, 0x1ee03,
-	0x1ee05, 0x1ee1f,
-	0x1ee21, 0x1ee22,
-	0x1ee29, 0x1ee32,
-	0x1ee34, 0x1ee37,
-	0x1ee4d, 0x1ee4f,
-	0x1ee51, 0x1ee52,
-	0x1ee61, 0x1ee62,
-	0x1ee67, 0x1ee6a,
-	0x1ee6c, 0x1ee72,
-	0x1ee74, 0x1ee77,
-	0x1ee79, 0x1ee7c,
-	0x1ee80, 0x1ee89,
-	0x1ee8b, 0x1ee9b,
-	0x1eea1, 0x1eea3,
-	0x1eea5, 0x1eea9,
-	0x1eeab, 0x1eebb,
-	0x20000, 0x2a6dd,
-	0x2a700, 0x2b734,
-	0x2b740, 0x2b81d,
-	0x2b820, 0x2cea1,
-	0x2ceb0, 0x2ebe0,
-	0x2f800, 0x2fa1d,
-	0x30000, 0x3134a,
+static uint32_t alpha3[][2] = {
+	{ 0x00D6, 0x00D8 },
+	{ 0x00F6, 0x00F8 },
+	{ 0x02EC, 0x02EE },
+	{ 0x0374, 0x0376 },
+	{ 0x037D, 0x037F },
+	{ 0x0386, 0x0388 },
+	{ 0x038A, 0x038E },
+	{ 0x03A1, 0x03A3 },
+	{ 0x03F5, 0x03F7 },
+	{ 0x052F, 0x0531 },
+	{ 0x066F, 0x0671 },
+	{ 0x06D3, 0x06D5 },
+	{ 0x0710, 0x0712 },
+	{ 0x0887, 0x0889 },
+	{ 0x09A8, 0x09AA },
+	{ 0x09B0, 0x09B2 },
+	{ 0x09DD, 0x09DF },
+	{ 0x0A28, 0x0A2A },
+	{ 0x0A30, 0x0A32 },
+	{ 0x0A33, 0x0A35 },
+	{ 0x0A36, 0x0A38 },
+	{ 0x0A5C, 0x0A5E },
+	{ 0x0A8D, 0x0A8F },
+	{ 0x0A91, 0x0A93 },
+	{ 0x0AA8, 0x0AAA },
+	{ 0x0AB0, 0x0AB2 },
+	{ 0x0AB3, 0x0AB5 },
+	{ 0x0B28, 0x0B2A },
+	{ 0x0B30, 0x0B32 },
+	{ 0x0B33, 0x0B35 },
+	{ 0x0B5D, 0x0B5F },
+	{ 0x0B83, 0x0B85 },
+	{ 0x0B90, 0x0B92 },
+	{ 0x0B9A, 0x0B9E },
+	{ 0x0C0C, 0x0C0E },
+	{ 0x0C10, 0x0C12 },
+	{ 0x0C28, 0x0C2A },
+	{ 0x0C8C, 0x0C8E },
+	{ 0x0C90, 0x0C92 },
+	{ 0x0CA8, 0x0CAA },
+	{ 0x0CB3, 0x0CB5 },
+	{ 0x0CDE, 0x0CE0 },
+	{ 0x0D0C, 0x0D0E },
+	{ 0x0D10, 0x0D12 },
+	{ 0x0DB1, 0x0DB3 },
+	{ 0x0DBB, 0x0DBD },
+	{ 0x0E30, 0x0E32 },
+	{ 0x0E82, 0x0E86 },
+	{ 0x0E8A, 0x0E8C },
+	{ 0x0EA3, 0x0EA7 },
+	{ 0x0EB0, 0x0EB2 },
+	{ 0x0EC4, 0x0EC6 },
+	{ 0x0F47, 0x0F49 },
+	{ 0x10C5, 0x10C7 },
+	{ 0x10FA, 0x10FC },
+	{ 0x1248, 0x124A },
+	{ 0x1256, 0x125A },
+	{ 0x1288, 0x128A },
+	{ 0x12B0, 0x12B2 },
+	{ 0x12BE, 0x12C2 },
+	{ 0x12D6, 0x12D8 },
+	{ 0x1310, 0x1312 },
+	{ 0x167F, 0x1681 },
+	{ 0x176C, 0x176E },
+	{ 0x18A8, 0x18AA },
+	{ 0x1CEC, 0x1CEE },
+	{ 0x1CF3, 0x1CF5 },
+	{ 0x1F57, 0x1F5F },
+	{ 0x1FB4, 0x1FB6 },
+	{ 0x1FBC, 0x1FBE },
+	{ 0x1FC4, 0x1FC6 },
+	{ 0x1FF4, 0x1FF6 },
+	{ 0x2113, 0x2115 },
+	{ 0x2124, 0x212A },
+	{ 0x212D, 0x212F },
+	{ 0x2D25, 0x2D27 },
+	{ 0x2DA6, 0x2DA8 },
+	{ 0x2DAE, 0x2DB0 },
+	{ 0x2DB6, 0x2DB8 },
+	{ 0x2DBE, 0x2DC0 },
+	{ 0x2DC6, 0x2DC8 },
+	{ 0x2DCE, 0x2DD0 },
+	{ 0x2DD6, 0x2DD8 },
+	{ 0x309F, 0x30A1 },
+	{ 0x30FA, 0x30FC },
+	{ 0x312F, 0x3131 },
+	{ 0xA7D1, 0xA7D5 },
+	{ 0xA801, 0xA803 },
+	{ 0xA805, 0xA807 },
+	{ 0xA80A, 0xA80C },
+	{ 0xA8FB, 0xA8FD },
+	{ 0xA9E4, 0xA9E6 },
+	{ 0xA9FE, 0xAA00 },
+	{ 0xAA42, 0xAA44 },
+	{ 0xAAAF, 0xAAB1 },
+	{ 0xAAC0, 0xAAC2 },
+	{ 0xAB26, 0xAB28 },
+	{ 0xAB2E, 0xAB30 },
+	{ 0xAB5A, 0xAB5C },
+	{ 0xFB1D, 0xFB1F },
+	{ 0xFB28, 0xFB2A },
+	{ 0xFB36, 0xFB38 },
+	{ 0xFB3C, 0xFB40 },
+	{ 0xFB41, 0xFB43 },
+	{ 0xFB44, 0xFB46 },
+	{ 0xFE74, 0xFE76 },
+	{ 0x1000B, 0x1000D },
+	{ 0x10026, 0x10028 },
+	{ 0x1003A, 0x1003C },
+	{ 0x1003D, 0x1003F },
+	{ 0x10340, 0x10342 },
+	{ 0x1057A, 0x1057C },
+	{ 0x1058A, 0x1058C },
+	{ 0x10592, 0x10594 },
+	{ 0x10595, 0x10597 },
+	{ 0x105A1, 0x105A3 },
+	{ 0x105B1, 0x105B3 },
+	{ 0x105B9, 0x105BB },
+	{ 0x10785, 0x10787 },
+	{ 0x107B0, 0x107B2 },
+	{ 0x10808, 0x1080A },
+	{ 0x10835, 0x10837 },
+	{ 0x108F2, 0x108F4 },
+	{ 0x10A13, 0x10A15 },
+	{ 0x10A17, 0x10A19 },
+	{ 0x10AC7, 0x10AC9 },
+	{ 0x111DA, 0x111DC },
+	{ 0x11211, 0x11213 },
+	{ 0x11286, 0x1128A },
+	{ 0x1128D, 0x1128F },
+	{ 0x1129D, 0x1129F },
+	{ 0x11328, 0x1132A },
+	{ 0x11330, 0x11332 },
+	{ 0x11333, 0x11335 },
+	{ 0x114C5, 0x114C7 },
+	{ 0x11913, 0x11915 },
+	{ 0x11916, 0x11918 },
+	{ 0x1193F, 0x11941 },
+	{ 0x119E1, 0x119E3 },
+	{ 0x11C08, 0x11C0A },
+	{ 0x11D06, 0x11D08 },
+	{ 0x11D09, 0x11D0B },
+	{ 0x11D65, 0x11D67 },
+	{ 0x11D68, 0x11D6A },
+	{ 0x16FE1, 0x16FE3 },
+	{ 0x1AFF3, 0x1AFF5 },
+	{ 0x1AFFB, 0x1AFFD },
+	{ 0x1AFFE, 0x1B000 },
+	{ 0x1D454, 0x1D456 },
+	{ 0x1D49C, 0x1D49E },
+	{ 0x1D4AC, 0x1D4AE },
+	{ 0x1D4B9, 0x1D4BD },
+	{ 0x1D4C3, 0x1D4C5 },
+	{ 0x1D505, 0x1D507 },
+	{ 0x1D514, 0x1D516 },
+	{ 0x1D51C, 0x1D51E },
+	{ 0x1D539, 0x1D53B },
+	{ 0x1D53E, 0x1D540 },
+	{ 0x1D544, 0x1D546 },
+	{ 0x1D550, 0x1D552 },
+	{ 0x1D6C0, 0x1D6C2 },
+	{ 0x1D6DA, 0x1D6DC },
+	{ 0x1D6FA, 0x1D6FC },
+	{ 0x1D714, 0x1D716 },
+	{ 0x1D734, 0x1D736 },
+	{ 0x1D74E, 0x1D750 },
+	{ 0x1D76E, 0x1D770 },
+	{ 0x1D788, 0x1D78A },
+	{ 0x1D7A8, 0x1D7AA },
+	{ 0x1D7C2, 0x1D7C4 },
+	{ 0x1E7E6, 0x1E7E8 },
+	{ 0x1E7EB, 0x1E7ED },
+	{ 0x1E7EE, 0x1E7F0 },
+	{ 0x1E7FE, 0x1E800 },
+	{ 0x1EE03, 0x1EE05 },
+	{ 0x1EE1F, 0x1EE21 },
+	{ 0x1EE22, 0x1EE24 },
+	{ 0x1EE27, 0x1EE29 },
+	{ 0x1EE32, 0x1EE34 },
+	{ 0x1EE37, 0x1EE3B },
+	{ 0x1EE47, 0x1EE4D },
+	{ 0x1EE4F, 0x1EE51 },
+	{ 0x1EE52, 0x1EE54 },
+	{ 0x1EE57, 0x1EE61 },
+	{ 0x1EE62, 0x1EE64 },
+	{ 0x1EE6A, 0x1EE6C },
+	{ 0x1EE72, 0x1EE74 },
+	{ 0x1EE77, 0x1EE79 },
+	{ 0x1EE7C, 0x1EE80 },
+	{ 0x1EE89, 0x1EE8B },
+	{ 0x1EEA3, 0x1EEA5 },
+	{ 0x1EEA9, 0x1EEAB },
 };
 
-static const uint32_t isalphas[] = {
-	0x00aa,
-	0x00b5,
-	0x00ba,
-	0x02ec,
-	0x02ee,
-	0x037f,
-	0x0386,
-	0x038c,
+static uint32_t alpha2[][2] = {
+	{ 0x0041, 0x005A },
+	{ 0x0061, 0x007A },
+	{ 0x00C0, 0x00D6 },
+	{ 0x00D8, 0x00F6 },
+	{ 0x00F8, 0x02C1 },
+	{ 0x02C6, 0x02D1 },
+	{ 0x02E0, 0x02E4 },
+	{ 0x0370, 0x0374 },
+	{ 0x0376, 0x0377 },
+	{ 0x037A, 0x037D },
+	{ 0x0388, 0x038A },
+	{ 0x038E, 0x03A1 },
+	{ 0x03A3, 0x03F5 },
+	{ 0x03F7, 0x0481 },
+	{ 0x048A, 0x052F },
+	{ 0x0531, 0x0556 },
+	{ 0x0560, 0x0588 },
+	{ 0x05D0, 0x05EA },
+	{ 0x05EF, 0x05F2 },
+	{ 0x0620, 0x064A },
+	{ 0x066E, 0x066F },
+	{ 0x0671, 0x06D3 },
+	{ 0x06E5, 0x06E6 },
+	{ 0x06EE, 0x06EF },
+	{ 0x06FA, 0x06FC },
+	{ 0x0712, 0x072F },
+	{ 0x074D, 0x07A5 },
+	{ 0x07CA, 0x07EA },
+	{ 0x07F4, 0x07F5 },
+	{ 0x0800, 0x0815 },
+	{ 0x0840, 0x0858 },
+	{ 0x0860, 0x086A },
+	{ 0x0870, 0x0887 },
+	{ 0x0889, 0x088E },
+	{ 0x08A0, 0x08C9 },
+	{ 0x0904, 0x0939 },
+	{ 0x0958, 0x0961 },
+	{ 0x0971, 0x0980 },
+	{ 0x0985, 0x098C },
+	{ 0x098F, 0x0990 },
+	{ 0x0993, 0x09A8 },
+	{ 0x09AA, 0x09B0 },
+	{ 0x09B6, 0x09B9 },
+	{ 0x09DC, 0x09DD },
+	{ 0x09DF, 0x09E1 },
+	{ 0x09F0, 0x09F1 },
+	{ 0x0A05, 0x0A0A },
+	{ 0x0A0F, 0x0A10 },
+	{ 0x0A13, 0x0A28 },
+	{ 0x0A2A, 0x0A30 },
+	{ 0x0A32, 0x0A33 },
+	{ 0x0A35, 0x0A36 },
+	{ 0x0A38, 0x0A39 },
+	{ 0x0A59, 0x0A5C },
+	{ 0x0A72, 0x0A74 },
+	{ 0x0A85, 0x0A8D },
+	{ 0x0A8F, 0x0A91 },
+	{ 0x0A93, 0x0AA8 },
+	{ 0x0AAA, 0x0AB0 },
+	{ 0x0AB2, 0x0AB3 },
+	{ 0x0AB5, 0x0AB9 },
+	{ 0x0AE0, 0x0AE1 },
+	{ 0x0B05, 0x0B0C },
+	{ 0x0B0F, 0x0B10 },
+	{ 0x0B13, 0x0B28 },
+	{ 0x0B2A, 0x0B30 },
+	{ 0x0B32, 0x0B33 },
+	{ 0x0B35, 0x0B39 },
+	{ 0x0B5C, 0x0B5D },
+	{ 0x0B5F, 0x0B61 },
+	{ 0x0B85, 0x0B8A },
+	{ 0x0B8E, 0x0B90 },
+	{ 0x0B92, 0x0B95 },
+	{ 0x0B99, 0x0B9A },
+	{ 0x0B9E, 0x0B9F },
+	{ 0x0BA3, 0x0BA4 },
+	{ 0x0BA8, 0x0BAA },
+	{ 0x0BAE, 0x0BB9 },
+	{ 0x0C05, 0x0C0C },
+	{ 0x0C0E, 0x0C10 },
+	{ 0x0C12, 0x0C28 },
+	{ 0x0C2A, 0x0C39 },
+	{ 0x0C58, 0x0C5A },
+	{ 0x0C60, 0x0C61 },
+	{ 0x0C85, 0x0C8C },
+	{ 0x0C8E, 0x0C90 },
+	{ 0x0C92, 0x0CA8 },
+	{ 0x0CAA, 0x0CB3 },
+	{ 0x0CB5, 0x0CB9 },
+	{ 0x0CDD, 0x0CDE },
+	{ 0x0CE0, 0x0CE1 },
+	{ 0x0CF1, 0x0CF2 },
+	{ 0x0D04, 0x0D0C },
+	{ 0x0D0E, 0x0D10 },
+	{ 0x0D12, 0x0D3A },
+	{ 0x0D54, 0x0D56 },
+	{ 0x0D5F, 0x0D61 },
+	{ 0x0D7A, 0x0D7F },
+	{ 0x0D85, 0x0D96 },
+	{ 0x0D9A, 0x0DB1 },
+	{ 0x0DB3, 0x0DBB },
+	{ 0x0DC0, 0x0DC6 },
+	{ 0x0E01, 0x0E30 },
+	{ 0x0E32, 0x0E33 },
+	{ 0x0E40, 0x0E46 },
+	{ 0x0E81, 0x0E82 },
+	{ 0x0E86, 0x0E8A },
+	{ 0x0E8C, 0x0EA3 },
+	{ 0x0EA7, 0x0EB0 },
+	{ 0x0EB2, 0x0EB3 },
+	{ 0x0EC0, 0x0EC4 },
+	{ 0x0EDC, 0x0EDF },
+	{ 0x0F40, 0x0F47 },
+	{ 0x0F49, 0x0F6C },
+	{ 0x0F88, 0x0F8C },
+	{ 0x1000, 0x102A },
+	{ 0x1050, 0x1055 },
+	{ 0x105A, 0x105D },
+	{ 0x1065, 0x1066 },
+	{ 0x106E, 0x1070 },
+	{ 0x1075, 0x1081 },
+	{ 0x10A0, 0x10C5 },
+	{ 0x10D0, 0x10FA },
+	{ 0x10FC, 0x1248 },
+	{ 0x124A, 0x124D },
+	{ 0x1250, 0x1256 },
+	{ 0x125A, 0x125D },
+	{ 0x1260, 0x1288 },
+	{ 0x128A, 0x128D },
+	{ 0x1290, 0x12B0 },
+	{ 0x12B2, 0x12B5 },
+	{ 0x12B8, 0x12BE },
+	{ 0x12C2, 0x12C5 },
+	{ 0x12C8, 0x12D6 },
+	{ 0x12D8, 0x1310 },
+	{ 0x1312, 0x1315 },
+	{ 0x1318, 0x135A },
+	{ 0x1380, 0x138F },
+	{ 0x13A0, 0x13F5 },
+	{ 0x13F8, 0x13FD },
+	{ 0x1401, 0x166C },
+	{ 0x166F, 0x167F },
+	{ 0x1681, 0x169A },
+	{ 0x16A0, 0x16EA },
+	{ 0x16F1, 0x16F8 },
+	{ 0x1700, 0x1711 },
+	{ 0x171F, 0x1731 },
+	{ 0x1740, 0x1751 },
+	{ 0x1760, 0x176C },
+	{ 0x176E, 0x1770 },
+	{ 0x1780, 0x17B3 },
+	{ 0x1820, 0x1878 },
+	{ 0x1880, 0x1884 },
+	{ 0x1887, 0x18A8 },
+	{ 0x18B0, 0x18F5 },
+	{ 0x1900, 0x191E },
+	{ 0x1950, 0x196D },
+	{ 0x1970, 0x1974 },
+	{ 0x1980, 0x19AB },
+	{ 0x19B0, 0x19C9 },
+	{ 0x1A00, 0x1A16 },
+	{ 0x1A20, 0x1A54 },
+	{ 0x1B05, 0x1B33 },
+	{ 0x1B45, 0x1B4C },
+	{ 0x1B83, 0x1BA0 },
+	{ 0x1BAE, 0x1BAF },
+	{ 0x1BBA, 0x1BE5 },
+	{ 0x1C00, 0x1C23 },
+	{ 0x1C4D, 0x1C4F },
+	{ 0x1C5A, 0x1C7D },
+	{ 0x1C80, 0x1C88 },
+	{ 0x1C90, 0x1CBA },
+	{ 0x1CBD, 0x1CBF },
+	{ 0x1CE9, 0x1CEC },
+	{ 0x1CEE, 0x1CF3 },
+	{ 0x1CF5, 0x1CF6 },
+	{ 0x1D00, 0x1DBF },
+	{ 0x1E00, 0x1F15 },
+	{ 0x1F18, 0x1F1D },
+	{ 0x1F20, 0x1F45 },
+	{ 0x1F48, 0x1F4D },
+	{ 0x1F50, 0x1F57 },
+	{ 0x1F5F, 0x1F7D },
+	{ 0x1F80, 0x1FB4 },
+	{ 0x1FB6, 0x1FBC },
+	{ 0x1FC2, 0x1FC4 },
+	{ 0x1FC6, 0x1FCC },
+	{ 0x1FD0, 0x1FD3 },
+	{ 0x1FD6, 0x1FDB },
+	{ 0x1FE0, 0x1FEC },
+	{ 0x1FF2, 0x1FF4 },
+	{ 0x1FF6, 0x1FFC },
+	{ 0x2090, 0x209C },
+	{ 0x210A, 0x2113 },
+	{ 0x2119, 0x211D },
+	{ 0x212A, 0x212D },
+	{ 0x212F, 0x2139 },
+	{ 0x213C, 0x213F },
+	{ 0x2145, 0x2149 },
+	{ 0x2183, 0x2184 },
+	{ 0x2C00, 0x2CE4 },
+	{ 0x2CEB, 0x2CEE },
+	{ 0x2CF2, 0x2CF3 },
+	{ 0x2D00, 0x2D25 },
+	{ 0x2D30, 0x2D67 },
+	{ 0x2D80, 0x2D96 },
+	{ 0x2DA0, 0x2DA6 },
+	{ 0x2DA8, 0x2DAE },
+	{ 0x2DB0, 0x2DB6 },
+	{ 0x2DB8, 0x2DBE },
+	{ 0x2DC0, 0x2DC6 },
+	{ 0x2DC8, 0x2DCE },
+	{ 0x2DD0, 0x2DD6 },
+	{ 0x2DD8, 0x2DDE },
+	{ 0x3005, 0x3006 },
+	{ 0x3031, 0x3035 },
+	{ 0x303B, 0x303C },
+	{ 0x3041, 0x3096 },
+	{ 0x309D, 0x309F },
+	{ 0x30A1, 0x30FA },
+	{ 0x30FC, 0x30FF },
+	{ 0x3105, 0x312F },
+	{ 0x3131, 0x318E },
+	{ 0x31A0, 0x31BF },
+	{ 0x31F0, 0x31FF },
+	{ 0x9FFF, 0xA48C },
+	{ 0xA4D0, 0xA4FD },
+	{ 0xA500, 0xA60C },
+	{ 0xA610, 0xA61F },
+	{ 0xA62A, 0xA62B },
+	{ 0xA640, 0xA66E },
+	{ 0xA67F, 0xA69D },
+	{ 0xA6A0, 0xA6E5 },
+	{ 0xA717, 0xA71F },
+	{ 0xA722, 0xA788 },
+	{ 0xA78B, 0xA7CA },
+	{ 0xA7D0, 0xA7D1 },
+	{ 0xA7D5, 0xA7D9 },
+	{ 0xA7F2, 0xA801 },
+	{ 0xA803, 0xA805 },
+	{ 0xA807, 0xA80A },
+	{ 0xA80C, 0xA822 },
+	{ 0xA840, 0xA873 },
+	{ 0xA882, 0xA8B3 },
+	{ 0xA8F2, 0xA8F7 },
+	{ 0xA8FD, 0xA8FE },
+	{ 0xA90A, 0xA925 },
+	{ 0xA930, 0xA946 },
+	{ 0xA960, 0xA97C },
+	{ 0xA984, 0xA9B2 },
+	{ 0xA9E0, 0xA9E4 },
+	{ 0xA9E6, 0xA9EF },
+	{ 0xA9FA, 0xA9FE },
+	{ 0xAA00, 0xAA28 },
+	{ 0xAA40, 0xAA42 },
+	{ 0xAA44, 0xAA4B },
+	{ 0xAA60, 0xAA76 },
+	{ 0xAA7E, 0xAAAF },
+	{ 0xAAB5, 0xAAB6 },
+	{ 0xAAB9, 0xAABD },
+	{ 0xAADB, 0xAADD },
+	{ 0xAAE0, 0xAAEA },
+	{ 0xAAF2, 0xAAF4 },
+	{ 0xAB01, 0xAB06 },
+	{ 0xAB09, 0xAB0E },
+	{ 0xAB11, 0xAB16 },
+	{ 0xAB20, 0xAB26 },
+	{ 0xAB28, 0xAB2E },
+	{ 0xAB30, 0xAB5A },
+	{ 0xAB5C, 0xAB69 },
+	{ 0xAB70, 0xABE2 },
+	{ 0xD7B0, 0xD7C6 },
+	{ 0xD7CB, 0xD7FB },
+	{ 0xF900, 0xFA6D },
+	{ 0xFA70, 0xFAD9 },
+	{ 0xFB00, 0xFB06 },
+	{ 0xFB13, 0xFB17 },
+	{ 0xFB1F, 0xFB28 },
+	{ 0xFB2A, 0xFB36 },
+	{ 0xFB38, 0xFB3C },
+	{ 0xFB40, 0xFB41 },
+	{ 0xFB43, 0xFB44 },
+	{ 0xFB46, 0xFBB1 },
+	{ 0xFBD3, 0xFD3D },
+	{ 0xFD50, 0xFD8F },
+	{ 0xFD92, 0xFDC7 },
+	{ 0xFDF0, 0xFDFB },
+	{ 0xFE70, 0xFE74 },
+	{ 0xFE76, 0xFEFC },
+	{ 0xFF21, 0xFF3A },
+	{ 0xFF41, 0xFF5A },
+	{ 0xFF66, 0xFFBE },
+	{ 0xFFC2, 0xFFC7 },
+	{ 0xFFCA, 0xFFCF },
+	{ 0xFFD2, 0xFFD7 },
+	{ 0xFFDA, 0xFFDC },
+	{ 0x10000, 0x1000B },
+	{ 0x1000D, 0x10026 },
+	{ 0x10028, 0x1003A },
+	{ 0x1003C, 0x1003D },
+	{ 0x1003F, 0x1004D },
+	{ 0x10050, 0x1005D },
+	{ 0x10080, 0x100FA },
+	{ 0x10280, 0x1029C },
+	{ 0x102A0, 0x102D0 },
+	{ 0x10300, 0x1031F },
+	{ 0x1032D, 0x10340 },
+	{ 0x10342, 0x10349 },
+	{ 0x10350, 0x10375 },
+	{ 0x10380, 0x1039D },
+	{ 0x103A0, 0x103C3 },
+	{ 0x103C8, 0x103CF },
+	{ 0x10400, 0x1049D },
+	{ 0x104B0, 0x104D3 },
+	{ 0x104D8, 0x104FB },
+	{ 0x10500, 0x10527 },
+	{ 0x10530, 0x10563 },
+	{ 0x10570, 0x1057A },
+	{ 0x1057C, 0x1058A },
+	{ 0x1058C, 0x10592 },
+	{ 0x10594, 0x10595 },
+	{ 0x10597, 0x105A1 },
+	{ 0x105A3, 0x105B1 },
+	{ 0x105B3, 0x105B9 },
+	{ 0x105BB, 0x105BC },
+	{ 0x10600, 0x10736 },
+	{ 0x10740, 0x10755 },
+	{ 0x10760, 0x10767 },
+	{ 0x10780, 0x10785 },
+	{ 0x10787, 0x107B0 },
+	{ 0x107B2, 0x107BA },
+	{ 0x10800, 0x10805 },
+	{ 0x1080A, 0x10835 },
+	{ 0x10837, 0x10838 },
+	{ 0x1083F, 0x10855 },
+	{ 0x10860, 0x10876 },
+	{ 0x10880, 0x1089E },
+	{ 0x108E0, 0x108F2 },
+	{ 0x108F4, 0x108F5 },
+	{ 0x10900, 0x10915 },
+	{ 0x10920, 0x10939 },
+	{ 0x10980, 0x109B7 },
+	{ 0x109BE, 0x109BF },
+	{ 0x10A10, 0x10A13 },
+	{ 0x10A15, 0x10A17 },
+	{ 0x10A19, 0x10A35 },
+	{ 0x10A60, 0x10A7C },
+	{ 0x10A80, 0x10A9C },
+	{ 0x10AC0, 0x10AC7 },
+	{ 0x10AC9, 0x10AE4 },
+	{ 0x10B00, 0x10B35 },
+	{ 0x10B40, 0x10B55 },
+	{ 0x10B60, 0x10B72 },
+	{ 0x10B80, 0x10B91 },
+	{ 0x10C00, 0x10C48 },
+	{ 0x10C80, 0x10CB2 },
+	{ 0x10CC0, 0x10CF2 },
+	{ 0x10D00, 0x10D23 },
+	{ 0x10E80, 0x10EA9 },
+	{ 0x10EB0, 0x10EB1 },
+	{ 0x10F00, 0x10F1C },
+	{ 0x10F30, 0x10F45 },
+	{ 0x10F70, 0x10F81 },
+	{ 0x10FB0, 0x10FC4 },
+	{ 0x10FE0, 0x10FF6 },
+	{ 0x11003, 0x11037 },
+	{ 0x11071, 0x11072 },
+	{ 0x11083, 0x110AF },
+	{ 0x110D0, 0x110E8 },
+	{ 0x11103, 0x11126 },
+	{ 0x11150, 0x11172 },
+	{ 0x11183, 0x111B2 },
+	{ 0x111C1, 0x111C4 },
+	{ 0x11200, 0x11211 },
+	{ 0x11213, 0x1122B },
+	{ 0x11280, 0x11286 },
+	{ 0x1128A, 0x1128D },
+	{ 0x1128F, 0x1129D },
+	{ 0x1129F, 0x112A8 },
+	{ 0x112B0, 0x112DE },
+	{ 0x11305, 0x1130C },
+	{ 0x1130F, 0x11310 },
+	{ 0x11313, 0x11328 },
+	{ 0x1132A, 0x11330 },
+	{ 0x11332, 0x11333 },
+	{ 0x11335, 0x11339 },
+	{ 0x1135D, 0x11361 },
+	{ 0x11400, 0x11434 },
+	{ 0x11447, 0x1144A },
+	{ 0x1145F, 0x11461 },
+	{ 0x11480, 0x114AF },
+	{ 0x114C4, 0x114C5 },
+	{ 0x11580, 0x115AE },
+	{ 0x115D8, 0x115DB },
+	{ 0x11600, 0x1162F },
+	{ 0x11680, 0x116AA },
+	{ 0x11700, 0x1171A },
+	{ 0x11740, 0x11746 },
+	{ 0x11800, 0x1182B },
+	{ 0x118A0, 0x118DF },
+	{ 0x118FF, 0x11906 },
+	{ 0x1190C, 0x11913 },
+	{ 0x11915, 0x11916 },
+	{ 0x11918, 0x1192F },
+	{ 0x119A0, 0x119A7 },
+	{ 0x119AA, 0x119D0 },
+	{ 0x11A0B, 0x11A32 },
+	{ 0x11A5C, 0x11A89 },
+	{ 0x11AB0, 0x11AF8 },
+	{ 0x11C00, 0x11C08 },
+	{ 0x11C0A, 0x11C2E },
+	{ 0x11C72, 0x11C8F },
+	{ 0x11D00, 0x11D06 },
+	{ 0x11D08, 0x11D09 },
+	{ 0x11D0B, 0x11D30 },
+	{ 0x11D60, 0x11D65 },
+	{ 0x11D67, 0x11D68 },
+	{ 0x11D6A, 0x11D89 },
+	{ 0x11EE0, 0x11EF2 },
+	{ 0x12000, 0x12399 },
+	{ 0x12480, 0x12543 },
+	{ 0x12F90, 0x12FF0 },
+	{ 0x13000, 0x1342E },
+	{ 0x14400, 0x14646 },
+	{ 0x16800, 0x16A38 },
+	{ 0x16A40, 0x16A5E },
+	{ 0x16A70, 0x16ABE },
+	{ 0x16AD0, 0x16AED },
+	{ 0x16B00, 0x16B2F },
+	{ 0x16B40, 0x16B43 },
+	{ 0x16B63, 0x16B77 },
+	{ 0x16B7D, 0x16B8F },
+	{ 0x16E40, 0x16E7F },
+	{ 0x16F00, 0x16F4A },
+	{ 0x16F93, 0x16F9F },
+	{ 0x16FE0, 0x16FE1 },
+	{ 0x18800, 0x18CD5 },
+	{ 0x1AFF0, 0x1AFF3 },
+	{ 0x1AFF5, 0x1AFFB },
+	{ 0x1AFFD, 0x1AFFE },
+	{ 0x1B000, 0x1B122 },
+	{ 0x1B150, 0x1B152 },
+	{ 0x1B164, 0x1B167 },
+	{ 0x1B170, 0x1B2FB },
+	{ 0x1BC00, 0x1BC6A },
+	{ 0x1BC70, 0x1BC7C },
+	{ 0x1BC80, 0x1BC88 },
+	{ 0x1BC90, 0x1BC99 },
+	{ 0x1D400, 0x1D454 },
+	{ 0x1D456, 0x1D49C },
+	{ 0x1D49E, 0x1D49F },
+	{ 0x1D4A5, 0x1D4A6 },
+	{ 0x1D4A9, 0x1D4AC },
+	{ 0x1D4AE, 0x1D4B9 },
+	{ 0x1D4BD, 0x1D4C3 },
+	{ 0x1D4C5, 0x1D505 },
+	{ 0x1D507, 0x1D50A },
+	{ 0x1D50D, 0x1D514 },
+	{ 0x1D516, 0x1D51C },
+	{ 0x1D51E, 0x1D539 },
+	{ 0x1D53B, 0x1D53E },
+	{ 0x1D540, 0x1D544 },
+	{ 0x1D54A, 0x1D550 },
+	{ 0x1D552, 0x1D6A5 },
+	{ 0x1D6A8, 0x1D6C0 },
+	{ 0x1D6C2, 0x1D6DA },
+	{ 0x1D6DC, 0x1D6FA },
+	{ 0x1D6FC, 0x1D714 },
+	{ 0x1D716, 0x1D734 },
+	{ 0x1D736, 0x1D74E },
+	{ 0x1D750, 0x1D76E },
+	{ 0x1D770, 0x1D788 },
+	{ 0x1D78A, 0x1D7A8 },
+	{ 0x1D7AA, 0x1D7C2 },
+	{ 0x1D7C4, 0x1D7CB },
+	{ 0x1DF00, 0x1DF1E },
+	{ 0x1E100, 0x1E12C },
+	{ 0x1E137, 0x1E13D },
+	{ 0x1E290, 0x1E2AD },
+	{ 0x1E2C0, 0x1E2EB },
+	{ 0x1E7E0, 0x1E7E6 },
+	{ 0x1E7E8, 0x1E7EB },
+	{ 0x1E7ED, 0x1E7EE },
+	{ 0x1E7F0, 0x1E7FE },
+	{ 0x1E800, 0x1E8C4 },
+	{ 0x1E900, 0x1E943 },
+	{ 0x1EE00, 0x1EE03 },
+	{ 0x1EE05, 0x1EE1F },
+	{ 0x1EE21, 0x1EE22 },
+	{ 0x1EE29, 0x1EE32 },
+	{ 0x1EE34, 0x1EE37 },
+	{ 0x1EE4D, 0x1EE4F },
+	{ 0x1EE51, 0x1EE52 },
+	{ 0x1EE61, 0x1EE62 },
+	{ 0x1EE67, 0x1EE6A },
+	{ 0x1EE6C, 0x1EE72 },
+	{ 0x1EE74, 0x1EE77 },
+	{ 0x1EE79, 0x1EE7C },
+	{ 0x1EE80, 0x1EE89 },
+	{ 0x1EE8B, 0x1EE9B },
+	{ 0x1EEA1, 0x1EEA3 },
+	{ 0x1EEA5, 0x1EEA9 },
+	{ 0x1EEAB, 0x1EEBB },
+	{ 0x2F800, 0x2FA1D },
+};
+
+static uint32_t alpha1[] = {
+	0x00AA,
+	0x00B5,
+	0x00BA,
 	0x0559,
-	0x06d5,
-	0x06ff,
-	0x0710,
-	0x07b1,
-	0x07fa,
-	0x081a,
+	0x06FF,
+	0x07B1,
+	0x07FA,
+	0x081A,
 	0x0824,
 	0x0828,
-	0x093d,
+	0x093D,
 	0x0950,
-	0x09b2,
-	0x09bd,
-	0x09ce,
-	0x09fc,
-	0x0a5e,
-	0x0abd,
-	0x0ad0,
-	0x0af9,
-	0x0b3d,
-	0x0b71,
-	0x0b83,
-	0x0b9c,
-	0x0bd0,
-	0x0c3d,
-	0x0c80,
-	0x0cbd,
-	0x0cde,
-	0x0d3d,
-	0x0d4e,
-	0x0dbd,
-	0x0e84,
-	0x0ea5,
-	0x0ebd,
-	0x0ec6,
-	0x0f00,
-	0x103f,
+	0x09BD,
+	0x09CE,
+	0x09FC,
+	0x0ABD,
+	0x0AD0,
+	0x0AF9,
+	0x0B3D,
+	0x0B71,
+	0x0BD0,
+	0x0C3D,
+	0x0C5D,
+	0x0C80,
+	0x0CBD,
+	0x0D3D,
+	0x0D4E,
+	0x0EBD,
+	0x0F00,
+	0x103F,
 	0x1061,
-	0x108e,
-	0x10c7,
-	0x10cd,
-	0x1258,
-	0x12c0,
-	0x17d7,
-	0x17dc,
-	0x18aa,
-	0x1aa7,
-	0x1cfa,
-	0x1f59,
-	0x1f5b,
-	0x1f5d,
-	0x1fbe,
+	0x108E,
+	0x10CD,
+	0x17D7,
+	0x17DC,
+	0x1AA7,
+	0x1CFA,
 	0x2071,
-	0x207f,
+	0x207F,
 	0x2102,
 	0x2107,
-	0x2115,
-	0x2124,
-	0x2126,
-	0x2128,
-	0x214e,
-	0x2d27,
-	0x2d2d,
-	0x2d6f,
-	0x2e2f,
-	0xa8fb,
-	0xa9cf,
-	0xaa7a,
-	0xaab1,
-	0xaac0,
-	0xaac2,
-	0xfb1d,
-	0xfb3e,
-	0x10808,
-	0x1083c,
-	0x10a00,
-	0x10f27,
+	0x214E,
+	0x2D2D,
+	0x2D6F,
+	0x2E2F,
+	0x3400,
+	0x4DBF,
+	0x4E00,
+	0xA9CF,
+	0xAA7A,
+	0xAC00,
+	0xD7A3,
+	0x1083C,
+	0x10A00,
+	0x10F27,
+	0x11075,
 	0x11144,
 	0x11147,
 	0x11176,
-	0x111da,
-	0x111dc,
-	0x11288,
-	0x1133d,
+	0x1133D,
 	0x11350,
-	0x114c7,
 	0x11644,
-	0x116b8,
+	0x116B8,
 	0x11909,
-	0x1193f,
-	0x11941,
-	0x119e1,
-	0x119e3,
-	0x11a00,
-	0x11a3a,
-	0x11a50,
-	0x11a9d,
-	0x11c40,
-	0x11d46,
-	0x11d98,
-	0x11fb0,
-	0x16f50,
-	0x16fe3,
-	0x1d4a2,
-	0x1d4bb,
-	0x1d546,
-	0x1e14e,
-	0x1e94b,
-	0x1ee24,
-	0x1ee27,
-	0x1ee39,
-	0x1ee3b,
-	0x1ee42,
-	0x1ee47,
-	0x1ee49,
-	0x1ee4b,
-	0x1ee54,
-	0x1ee57,
-	0x1ee59,
-	0x1ee5b,
-	0x1ee5d,
-	0x1ee5f,
-	0x1ee64,
-	0x1ee7e,
+	0x11A00,
+	0x11A3A,
+	0x11A50,
+	0x11A9D,
+	0x11C40,
+	0x11D46,
+	0x11D98,
+	0x11FB0,
+	0x16F50,
+	0x17000,
+	0x187F7,
+	0x18D00,
+	0x18D08,
+	0x1D4A2,
+	0x1E14E,
+	0x1E94B,
+	0x1EE42,
+	0x20000,
+	0x2A6DF,
+	0x2A700,
+	0x2B738,
+	0x2B740,
+	0x2B81D,
+	0x2B820,
+	0x2CEA1,
+	0x2CEB0,
+	0x2EBE0,
+	0x30000,
+	0x3134A,
 };
 
 int
-uni_isalpha(uint32_t c)
+uni_isalpha(uint32_t r)
 {
-	const uint32_t *p;
-
-	p = search(c, isalphar, nelem (isalphar) / 2, 2);
-
-	if (p && c >= p[0] && c <= p[1])
-		return 1;
-
-	p = search(c, isalphas, nelem (isalphas), 1);
-
-	if (p && c == p[0])
-		return 1;
-
-	return 0;
-}
-
-static const uint32_t isupperr[] = {
-	0x0041, 0x005a,
-	0x00c0, 0x00d6,
-	0x00d8, 0x00de,
-	0x0178, 0x0179,
-	0x0181, 0x0182,
-	0x0186, 0x0187,
-	0x0189, 0x018b,
-	0x018e, 0x0191,
-	0x0193, 0x0194,
-	0x0196, 0x0198,
-	0x019c, 0x019d,
-	0x019f, 0x01a0,
-	0x01a6, 0x01a7,
-	0x01ae, 0x01af,
-	0x01b1, 0x01b3,
-	0x01b7, 0x01b8,
-	0x01f6, 0x01f8,
-	0x023a, 0x023b,
-	0x023d, 0x023e,
-	0x0243, 0x0246,
-	0x0388, 0x038a,
-	0x038e, 0x038f,
-	0x0391, 0x03a1,
-	0x03a3, 0x03ab,
-	0x03d2, 0x03d4,
-	0x03f9, 0x03fa,
-	0x03fd, 0x042f,
-	0x04c0, 0x04c1,
-	0x0531, 0x0556,
-	0x10a0, 0x10c5,
-	0x13a0, 0x13f5,
-	0x1c90, 0x1cba,
-	0x1cbd, 0x1cbf,
-	0x1f08, 0x1f0f,
-	0x1f18, 0x1f1d,
-	0x1f28, 0x1f2f,
-	0x1f38, 0x1f3f,
-	0x1f48, 0x1f4d,
-	0x1f68, 0x1f6f,
-	0x1f88, 0x1f8f,
-	0x1f98, 0x1f9f,
-	0x1fa8, 0x1faf,
-	0x1fb8, 0x1fbc,
-	0x1fc8, 0x1fcc,
-	0x1fd8, 0x1fdb,
-	0x1fe8, 0x1fec,
-	0x1ff8, 0x1ffc,
-	0x210b, 0x210d,
-	0x2110, 0x2112,
-	0x2119, 0x211d,
-	0x212a, 0x212d,
-	0x2130, 0x2133,
-	0x213e, 0x213f,
-	0x2160, 0x216f,
-	0x24b6, 0x24cf,
-	0x2c00, 0x2c2e,
-	0x2c62, 0x2c64,
-	0x2c6d, 0x2c70,
-	0x2c7e, 0x2c80,
-	0xa77d, 0xa77e,
-	0xa7aa, 0xa7ae,
-	0xa7b0, 0xa7b4,
-	0xa7c4, 0xa7c7,
-	0xff21, 0xff3a,
-	0x10400, 0x10427,
-	0x104b0, 0x104d3,
-	0x10c80, 0x10cb2,
-	0x118a0, 0x118bf,
-	0x16e40, 0x16e5f,
-	0x1d400, 0x1d419,
-	0x1d434, 0x1d44d,
-	0x1d468, 0x1d481,
-	0x1d49e, 0x1d49f,
-	0x1d4a5, 0x1d4a6,
-	0x1d4a9, 0x1d4ac,
-	0x1d4ae, 0x1d4b5,
-	0x1d4d0, 0x1d4e9,
-	0x1d504, 0x1d505,
-	0x1d507, 0x1d50a,
-	0x1d50d, 0x1d514,
-	0x1d516, 0x1d51c,
-	0x1d538, 0x1d539,
-	0x1d53b, 0x1d53e,
-	0x1d540, 0x1d544,
-	0x1d54a, 0x1d550,
-	0x1d56c, 0x1d585,
-	0x1d5a0, 0x1d5b9,
-	0x1d5d4, 0x1d5ed,
-	0x1d608, 0x1d621,
-	0x1d63c, 0x1d655,
-	0x1d670, 0x1d689,
-	0x1d6a8, 0x1d6c0,
-	0x1d6e2, 0x1d6fa,
-	0x1d71c, 0x1d734,
-	0x1d756, 0x1d76e,
-	0x1d790, 0x1d7a8,
-	0x1e900, 0x1e921,
-};
+	const uint32_t *match;
 
-static const uint32_t isuppers[] = {
-	0x0100,
-	0x0102,
-	0x0104,
-	0x0106,
-	0x0108,
-	0x010a,
-	0x010c,
-	0x010e,
-	0x0110,
-	0x0112,
-	0x0114,
-	0x0116,
-	0x0118,
-	0x011a,
-	0x011c,
-	0x011e,
-	0x0120,
-	0x0122,
-	0x0124,
-	0x0126,
-	0x0128,
-	0x012a,
-	0x012c,
-	0x012e,
-	0x0130,
-	0x0132,
-	0x0134,
-	0x0136,
-	0x0139,
-	0x013b,
-	0x013d,
-	0x013f,
-	0x0141,
-	0x0143,
-	0x0145,
-	0x0147,
-	0x014a,
-	0x014c,
-	0x014e,
-	0x0150,
-	0x0152,
-	0x0154,
-	0x0156,
-	0x0158,
-	0x015a,
-	0x015c,
-	0x015e,
-	0x0160,
-	0x0162,
-	0x0164,
-	0x0166,
-	0x0168,
-	0x016a,
-	0x016c,
-	0x016e,
-	0x0170,
-	0x0172,
-	0x0174,
-	0x0176,
-	0x017b,
-	0x017d,
-	0x0184,
-	0x01a2,
-	0x01a4,
-	0x01a9,
-	0x01ac,
-	0x01b5,
-	0x01bc,
-	0x01c4,
-	0x01c7,
-	0x01ca,
-	0x01cd,
-	0x01cf,
-	0x01d1,
-	0x01d3,
-	0x01d5,
-	0x01d7,
-	0x01d9,
-	0x01db,
-	0x01de,
-	0x01e0,
-	0x01e2,
-	0x01e4,
-	0x01e6,
-	0x01e8,
-	0x01ea,
-	0x01ec,
-	0x01ee,
-	0x01f1,
-	0x01f4,
-	0x01fa,
-	0x01fc,
-	0x01fe,
-	0x0200,
-	0x0202,
-	0x0204,
-	0x0206,
-	0x0208,
-	0x020a,
-	0x020c,
-	0x020e,
-	0x0210,
-	0x0212,
-	0x0214,
-	0x0216,
-	0x0218,
-	0x021a,
-	0x021c,
-	0x021e,
-	0x0220,
-	0x0222,
-	0x0224,
-	0x0226,
-	0x0228,
-	0x022a,
-	0x022c,
-	0x022e,
-	0x0230,
-	0x0232,
-	0x0241,
-	0x0248,
-	0x024a,
-	0x024c,
-	0x024e,
-	0x0370,
-	0x0372,
-	0x0376,
-	0x037f,
-	0x0386,
-	0x038c,
-	0x03cf,
-	0x03d8,
-	0x03da,
-	0x03dc,
-	0x03de,
-	0x03e0,
-	0x03e2,
-	0x03e4,
-	0x03e6,
-	0x03e8,
-	0x03ea,
-	0x03ec,
-	0x03ee,
-	0x03f4,
-	0x03f7,
-	0x0460,
-	0x0462,
-	0x0464,
-	0x0466,
-	0x0468,
-	0x046a,
-	0x046c,
-	0x046e,
-	0x0470,
-	0x0472,
-	0x0474,
-	0x0476,
-	0x0478,
-	0x047a,
-	0x047c,
-	0x047e,
-	0x0480,
-	0x048a,
-	0x048c,
-	0x048e,
-	0x0490,
-	0x0492,
-	0x0494,
-	0x0496,
-	0x0498,
-	0x049a,
-	0x049c,
-	0x049e,
-	0x04a0,
-	0x04a2,
-	0x04a4,
-	0x04a6,
-	0x04a8,
-	0x04aa,
-	0x04ac,
-	0x04ae,
-	0x04b0,
-	0x04b2,
-	0x04b4,
-	0x04b6,
-	0x04b8,
-	0x04ba,
-	0x04bc,
-	0x04be,
-	0x04c3,
-	0x04c5,
-	0x04c7,
-	0x04c9,
-	0x04cb,
-	0x04cd,
-	0x04d0,
-	0x04d2,
-	0x04d4,
-	0x04d6,
-	0x04d8,
-	0x04da,
-	0x04dc,
-	0x04de,
-	0x04e0,
-	0x04e2,
-	0x04e4,
-	0x04e6,
-	0x04e8,
-	0x04ea,
-	0x04ec,
-	0x04ee,
-	0x04f0,
-	0x04f2,
-	0x04f4,
-	0x04f6,
-	0x04f8,
-	0x04fa,
-	0x04fc,
-	0x04fe,
-	0x0500,
-	0x0502,
-	0x0504,
-	0x0506,
-	0x0508,
-	0x050a,
-	0x050c,
-	0x050e,
-	0x0510,
-	0x0512,
-	0x0514,
-	0x0516,
-	0x0518,
-	0x051a,
-	0x051c,
-	0x051e,
-	0x0520,
-	0x0522,
-	0x0524,
-	0x0526,
-	0x0528,
-	0x052a,
-	0x052c,
-	0x052e,
-	0x10c7,
-	0x10cd,
-	0x1e00,
-	0x1e02,
-	0x1e04,
-	0x1e06,
-	0x1e08,
-	0x1e0a,
-	0x1e0c,
-	0x1e0e,
-	0x1e10,
-	0x1e12,
-	0x1e14,
-	0x1e16,
-	0x1e18,
-	0x1e1a,
-	0x1e1c,
-	0x1e1e,
-	0x1e20,
-	0x1e22,
-	0x1e24,
-	0x1e26,
-	0x1e28,
-	0x1e2a,
-	0x1e2c,
-	0x1e2e,
-	0x1e30,
-	0x1e32,
-	0x1e34,
-	0x1e36,
-	0x1e38,
-	0x1e3a,
-	0x1e3c,
-	0x1e3e,
-	0x1e40,
-	0x1e42,
-	0x1e44,
-	0x1e46,
-	0x1e48,
-	0x1e4a,
-	0x1e4c,
-	0x1e4e,
-	0x1e50,
-	0x1e52,
-	0x1e54,
-	0x1e56,
-	0x1e58,
-	0x1e5a,
-	0x1e5c,
-	0x1e5e,
-	0x1e60,
-	0x1e62,
-	0x1e64,
-	0x1e66,
-	0x1e68,
-	0x1e6a,
-	0x1e6c,
-	0x1e6e,
-	0x1e70,
-	0x1e72,
-	0x1e74,
-	0x1e76,
-	0x1e78,
-	0x1e7a,
-	0x1e7c,
-	0x1e7e,
-	0x1e80,
-	0x1e82,
-	0x1e84,
-	0x1e86,
-	0x1e88,
-	0x1e8a,
-	0x1e8c,
-	0x1e8e,
-	0x1e90,
-	0x1e92,
-	0x1e94,
-	0x1e9e,
-	0x1ea0,
-	0x1ea2,
-	0x1ea4,
-	0x1ea6,
-	0x1ea8,
-	0x1eaa,
-	0x1eac,
-	0x1eae,
-	0x1eb0,
-	0x1eb2,
-	0x1eb4,
-	0x1eb6,
-	0x1eb8,
-	0x1eba,
-	0x1ebc,
-	0x1ebe,
-	0x1ec0,
-	0x1ec2,
-	0x1ec4,
-	0x1ec6,
-	0x1ec8,
-	0x1eca,
-	0x1ecc,
-	0x1ece,
-	0x1ed0,
-	0x1ed2,
-	0x1ed4,
-	0x1ed6,
-	0x1ed8,
-	0x1eda,
-	0x1edc,
-	0x1ede,
-	0x1ee0,
-	0x1ee2,
-	0x1ee4,
-	0x1ee6,
-	0x1ee8,
-	0x1eea,
-	0x1eec,
-	0x1eee,
-	0x1ef0,
-	0x1ef2,
-	0x1ef4,
-	0x1ef6,
-	0x1ef8,
-	0x1efa,
-	0x1efc,
-	0x1efe,
-	0x1f59,
-	0x1f5b,
-	0x1f5d,
-	0x1f5f,
-	0x2102,
-	0x2107,
-	0x2115,
-	0x2124,
-	0x2126,
-	0x2128,
-	0x2145,
-	0x2183,
-	0x2c60,
-	0x2c67,
-	0x2c69,
-	0x2c6b,
-	0x2c72,
-	0x2c75,
-	0x2c82,
-	0x2c84,
-	0x2c86,
-	0x2c88,
-	0x2c8a,
-	0x2c8c,
-	0x2c8e,
-	0x2c90,
-	0x2c92,
-	0x2c94,
-	0x2c96,
-	0x2c98,
-	0x2c9a,
-	0x2c9c,
-	0x2c9e,
-	0x2ca0,
-	0x2ca2,
-	0x2ca4,
-	0x2ca6,
-	0x2ca8,
-	0x2caa,
-	0x2cac,
-	0x2cae,
-	0x2cb0,
-	0x2cb2,
-	0x2cb4,
-	0x2cb6,
-	0x2cb8,
-	0x2cba,
-	0x2cbc,
-	0x2cbe,
-	0x2cc0,
-	0x2cc2,
-	0x2cc4,
-	0x2cc6,
-	0x2cc8,
-	0x2cca,
-	0x2ccc,
-	0x2cce,
-	0x2cd0,
-	0x2cd2,
-	0x2cd4,
-	0x2cd6,
-	0x2cd8,
-	0x2cda,
-	0x2cdc,
-	0x2cde,
-	0x2ce0,
-	0x2ce2,
-	0x2ceb,
-	0x2ced,
-	0x2cf2,
-	0xa640,
-	0xa642,
-	0xa644,
-	0xa646,
-	0xa648,
-	0xa64a,
-	0xa64c,
-	0xa64e,
-	0xa650,
-	0xa652,
-	0xa654,
-	0xa656,
-	0xa658,
-	0xa65a,
-	0xa65c,
-	0xa65e,
-	0xa660,
-	0xa662,
-	0xa664,
-	0xa666,
-	0xa668,
-	0xa66a,
-	0xa66c,
-	0xa680,
-	0xa682,
-	0xa684,
-	0xa686,
-	0xa688,
-	0xa68a,
-	0xa68c,
-	0xa68e,
-	0xa690,
-	0xa692,
-	0xa694,
-	0xa696,
-	0xa698,
-	0xa69a,
-	0xa722,
-	0xa724,
-	0xa726,
-	0xa728,
-	0xa72a,
-	0xa72c,
-	0xa72e,
-	0xa732,
-	0xa734,
-	0xa736,
-	0xa738,
-	0xa73a,
-	0xa73c,
-	0xa73e,
-	0xa740,
-	0xa742,
-	0xa744,
-	0xa746,
-	0xa748,
-	0xa74a,
-	0xa74c,
-	0xa74e,
-	0xa750,
-	0xa752,
-	0xa754,
-	0xa756,
-	0xa758,
-	0xa75a,
-	0xa75c,
-	0xa75e,
-	0xa760,
-	0xa762,
-	0xa764,
-	0xa766,
-	0xa768,
-	0xa76a,
-	0xa76c,
-	0xa76e,
-	0xa779,
-	0xa77b,
-	0xa780,
-	0xa782,
-	0xa784,
-	0xa786,
-	0xa78b,
-	0xa78d,
-	0xa790,
-	0xa792,
-	0xa796,
-	0xa798,
-	0xa79a,
-	0xa79c,
-	0xa79e,
-	0xa7a0,
-	0xa7a2,
-	0xa7a4,
-	0xa7a6,
-	0xa7a8,
-	0xa7b6,
-	0xa7b8,
-	0xa7ba,
-	0xa7bc,
-	0xa7be,
-	0xa7c2,
-	0xa7c9,
-	0xa7f5,
-	0x1d49c,
-	0x1d4a2,
-	0x1d546,
-	0x1d7ca,
-};
-
-int
-uni_isupper(uint32_t c)
-{
-	const uint32_t *p;
-
-	p = search(c, isupperr, nelem (isupperr) / 2, 2);
-
-	if (p && c >= p[0] && c <= p[1])
+	if ((match = bsearch(&r, alpha3, nelem(alpha3), sizeof *alpha3, &cmp2)))
+		return !((r - match[0]) % 2);
+	if (bsearch(&r, alpha2, nelem(alpha2), sizeof *alpha2, &cmp2))
 		return 1;
-
-	p = search(c, isuppers, nelem (isuppers), 1);
-
-	if (p && c == p[0])
-		return 1;
-
-	return 0;
-}
-
-static const uint32_t islowerr[] = {
-	0x0061, 0x007a,
-	0x00df, 0x00f6,
-	0x00f8, 0x00ff,
-	0x0137, 0x0138,
-	0x0148, 0x0149,
-	0x017e, 0x0180,
-	0x018c, 0x018d,
-	0x0199, 0x019b,
-	0x01aa, 0x01ab,
-	0x01b9, 0x01ba,
-	0x01bd, 0x01bf,
-	0x01dc, 0x01dd,
-	0x01ef, 0x01f0,
-	0x0233, 0x0239,
-	0x023f, 0x0240,
-	0x024f, 0x0293,
-	0x0295, 0x02af,
-	0x037b, 0x037d,
-	0x03ac, 0x03ce,
-	0x03d0, 0x03d1,
-	0x03d5, 0x03d7,
-	0x03ef, 0x03f3,
-	0x03fb, 0x03fc,
-	0x0430, 0x045f,
-	0x04ce, 0x04cf,
-	0x0560, 0x0588,
-	0x10d0, 0x10fa,
-	0x10fd, 0x10ff,
-	0x13f8, 0x13fd,
-	0x1c80, 0x1c88,
-	0x1d00, 0x1d2b,
-	0x1d6b, 0x1d77,
-	0x1d79, 0x1d9a,
-	0x1e95, 0x1e9d,
-	0x1eff, 0x1f07,
-	0x1f10, 0x1f15,
-	0x1f20, 0x1f27,
-	0x1f30, 0x1f37,
-	0x1f40, 0x1f45,
-	0x1f50, 0x1f57,
-	0x1f60, 0x1f67,
-	0x1f70, 0x1f7d,
-	0x1f80, 0x1f87,
-	0x1f90, 0x1f97,
-	0x1fa0, 0x1fa7,
-	0x1fb0, 0x1fb4,
-	0x1fb6, 0x1fb7,
-	0x1fc2, 0x1fc4,
-	0x1fc6, 0x1fc7,
-	0x1fd0, 0x1fd3,
-	0x1fd6, 0x1fd7,
-	0x1fe0, 0x1fe7,
-	0x1ff2, 0x1ff4,
-	0x1ff6, 0x1ff7,
-	0x210e, 0x210f,
-	0x213c, 0x213d,
-	0x2146, 0x2149,
-	0x2170, 0x217f,
-	0x24d0, 0x24e9,
-	0x2c30, 0x2c5e,
-	0x2c65, 0x2c66,
-	0x2c73, 0x2c74,
-	0x2c76, 0x2c7b,
-	0x2ce3, 0x2ce4,
-	0x2d00, 0x2d25,
-	0xa72f, 0xa731,
-	0xa771, 0xa778,
-	0xa793, 0xa795,
-	0xab30, 0xab5a,
-	0xab60, 0xab68,
-	0xab70, 0xabbf,
-	0xfb00, 0xfb06,
-	0xfb13, 0xfb17,
-	0xff41, 0xff5a,
-	0x10428, 0x1044f,
-	0x104d8, 0x104fb,
-	0x10cc0, 0x10cf2,
-	0x118c0, 0x118df,
-	0x16e60, 0x16e7f,
-	0x1d41a, 0x1d433,
-	0x1d44e, 0x1d454,
-	0x1d456, 0x1d467,
-	0x1d482, 0x1d49b,
-	0x1d4b6, 0x1d4b9,
-	0x1d4bd, 0x1d4c3,
-	0x1d4c5, 0x1d4cf,
-	0x1d4ea, 0x1d503,
-	0x1d51e, 0x1d537,
-	0x1d552, 0x1d56b,
-	0x1d586, 0x1d59f,
-	0x1d5ba, 0x1d5d3,
-	0x1d5ee, 0x1d607,
-	0x1d622, 0x1d63b,
-	0x1d656, 0x1d66f,
-	0x1d68a, 0x1d6a5,
-	0x1d6c2, 0x1d6da,
-	0x1d6dc, 0x1d6e1,
-	0x1d6fc, 0x1d714,
-	0x1d716, 0x1d71b,
-	0x1d736, 0x1d74e,
-	0x1d750, 0x1d755,
-	0x1d770, 0x1d788,
-	0x1d78a, 0x1d78f,
-	0x1d7aa, 0x1d7c2,
-	0x1d7c4, 0x1d7c9,
-	0x1e922, 0x1e943,
-};
-
-static const uint32_t islowers[] = {
-	0x00b5,
-	0x0101,
-	0x0103,
-	0x0105,
-	0x0107,
-	0x0109,
-	0x010b,
-	0x010d,
-	0x010f,
-	0x0111,
-	0x0113,
-	0x0115,
-	0x0117,
-	0x0119,
-	0x011b,
-	0x011d,
-	0x011f,
-	0x0121,
-	0x0123,
-	0x0125,
-	0x0127,
-	0x0129,
-	0x012b,
-	0x012d,
-	0x012f,
-	0x0131,
-	0x0133,
-	0x0135,
-	0x013a,
-	0x013c,
-	0x013e,
-	0x0140,
-	0x0142,
-	0x0144,
-	0x0146,
-	0x014b,
-	0x014d,
-	0x014f,
-	0x0151,
-	0x0153,
-	0x0155,
-	0x0157,
-	0x0159,
-	0x015b,
-	0x015d,
-	0x015f,
-	0x0161,
-	0x0163,
-	0x0165,
-	0x0167,
-	0x0169,
-	0x016b,
-	0x016d,
-	0x016f,
-	0x0171,
-	0x0173,
-	0x0175,
-	0x0177,
-	0x017a,
-	0x017c,
-	0x0183,
-	0x0185,
-	0x0188,
-	0x0192,
-	0x0195,
-	0x019e,
-	0x01a1,
-	0x01a3,
-	0x01a5,
-	0x01a8,
-	0x01ad,
-	0x01b0,
-	0x01b4,
-	0x01b6,
-	0x01c6,
-	0x01c9,
-	0x01cc,
-	0x01ce,
-	0x01d0,
-	0x01d2,
-	0x01d4,
-	0x01d6,
-	0x01d8,
-	0x01da,
-	0x01df,
-	0x01e1,
-	0x01e3,
-	0x01e5,
-	0x01e7,
-	0x01e9,
-	0x01eb,
-	0x01ed,
-	0x01f3,
-	0x01f5,
-	0x01f9,
-	0x01fb,
-	0x01fd,
-	0x01ff,
-	0x0201,
-	0x0203,
-	0x0205,
-	0x0207,
-	0x0209,
-	0x020b,
-	0x020d,
-	0x020f,
-	0x0211,
-	0x0213,
-	0x0215,
-	0x0217,
-	0x0219,
-	0x021b,
-	0x021d,
-	0x021f,
-	0x0221,
-	0x0223,
-	0x0225,
-	0x0227,
-	0x0229,
-	0x022b,
-	0x022d,
-	0x022f,
-	0x0231,
-	0x023c,
-	0x0242,
-	0x0247,
-	0x0249,
-	0x024b,
-	0x024d,
-	0x0371,
-	0x0373,
-	0x0377,
-	0x0390,
-	0x03d9,
-	0x03db,
-	0x03dd,
-	0x03df,
-	0x03e1,
-	0x03e3,
-	0x03e5,
-	0x03e7,
-	0x03e9,
-	0x03eb,
-	0x03ed,
-	0x03f5,
-	0x03f8,
-	0x0461,
-	0x0463,
-	0x0465,
-	0x0467,
-	0x0469,
-	0x046b,
-	0x046d,
-	0x046f,
-	0x0471,
-	0x0473,
-	0x0475,
-	0x0477,
-	0x0479,
-	0x047b,
-	0x047d,
-	0x047f,
-	0x0481,
-	0x048b,
-	0x048d,
-	0x048f,
-	0x0491,
-	0x0493,
-	0x0495,
-	0x0497,
-	0x0499,
-	0x049b,
-	0x049d,
-	0x049f,
-	0x04a1,
-	0x04a3,
-	0x04a5,
-	0x04a7,
-	0x04a9,
-	0x04ab,
-	0x04ad,
-	0x04af,
-	0x04b1,
-	0x04b3,
-	0x04b5,
-	0x04b7,
-	0x04b9,
-	0x04bb,
-	0x04bd,
-	0x04bf,
-	0x04c2,
-	0x04c4,
-	0x04c6,
-	0x04c8,
-	0x04ca,
-	0x04cc,
-	0x04d1,
-	0x04d3,
-	0x04d5,
-	0x04d7,
-	0x04d9,
-	0x04db,
-	0x04dd,
-	0x04df,
-	0x04e1,
-	0x04e3,
-	0x04e5,
-	0x04e7,
-	0x04e9,
-	0x04eb,
-	0x04ed,
-	0x04ef,
-	0x04f1,
-	0x04f3,
-	0x04f5,
-	0x04f7,
-	0x04f9,
-	0x04fb,
-	0x04fd,
-	0x04ff,
-	0x0501,
-	0x0503,
-	0x0505,
-	0x0507,
-	0x0509,
-	0x050b,
-	0x050d,
-	0x050f,
-	0x0511,
-	0x0513,
-	0x0515,
-	0x0517,
-	0x0519,
-	0x051b,
-	0x051d,
-	0x051f,
-	0x0521,
-	0x0523,
-	0x0525,
-	0x0527,
-	0x0529,
-	0x052b,
-	0x052d,
-	0x052f,
-	0x1e01,
-	0x1e03,
-	0x1e05,
-	0x1e07,
-	0x1e09,
-	0x1e0b,
-	0x1e0d,
-	0x1e0f,
-	0x1e11,
-	0x1e13,
-	0x1e15,
-	0x1e17,
-	0x1e19,
-	0x1e1b,
-	0x1e1d,
-	0x1e1f,
-	0x1e21,
-	0x1e23,
-	0x1e25,
-	0x1e27,
-	0x1e29,
-	0x1e2b,
-	0x1e2d,
-	0x1e2f,
-	0x1e31,
-	0x1e33,
-	0x1e35,
-	0x1e37,
-	0x1e39,
-	0x1e3b,
-	0x1e3d,
-	0x1e3f,
-	0x1e41,
-	0x1e43,
-	0x1e45,
-	0x1e47,
-	0x1e49,
-	0x1e4b,
-	0x1e4d,
-	0x1e4f,
-	0x1e51,
-	0x1e53,
-	0x1e55,
-	0x1e57,
-	0x1e59,
-	0x1e5b,
-	0x1e5d,
-	0x1e5f,
-	0x1e61,
-	0x1e63,
-	0x1e65,
-	0x1e67,
-	0x1e69,
-	0x1e6b,
-	0x1e6d,
-	0x1e6f,
-	0x1e71,
-	0x1e73,
-	0x1e75,
-	0x1e77,
-	0x1e79,
-	0x1e7b,
-	0x1e7d,
-	0x1e7f,
-	0x1e81,
-	0x1e83,
-	0x1e85,
-	0x1e87,
-	0x1e89,
-	0x1e8b,
-	0x1e8d,
-	0x1e8f,
-	0x1e91,
-	0x1e93,
-	0x1e9f,
-	0x1ea1,
-	0x1ea3,
-	0x1ea5,
-	0x1ea7,
-	0x1ea9,
-	0x1eab,
-	0x1ead,
-	0x1eaf,
-	0x1eb1,
-	0x1eb3,
-	0x1eb5,
-	0x1eb7,
-	0x1eb9,
-	0x1ebb,
-	0x1ebd,
-	0x1ebf,
-	0x1ec1,
-	0x1ec3,
-	0x1ec5,
-	0x1ec7,
-	0x1ec9,
-	0x1ecb,
-	0x1ecd,
-	0x1ecf,
-	0x1ed1,
-	0x1ed3,
-	0x1ed5,
-	0x1ed7,
-	0x1ed9,
-	0x1edb,
-	0x1edd,
-	0x1edf,
-	0x1ee1,
-	0x1ee3,
-	0x1ee5,
-	0x1ee7,
-	0x1ee9,
-	0x1eeb,
-	0x1eed,
-	0x1eef,
-	0x1ef1,
-	0x1ef3,
-	0x1ef5,
-	0x1ef7,
-	0x1ef9,
-	0x1efb,
-	0x1efd,
-	0x1fbe,
-	0x210a,
-	0x2113,
-	0x212f,
-	0x2134,
-	0x2139,
-	0x214e,
-	0x2184,
-	0x2c61,
-	0x2c68,
-	0x2c6a,
-	0x2c6c,
-	0x2c71,
-	0x2c81,
-	0x2c83,
-	0x2c85,
-	0x2c87,
-	0x2c89,
-	0x2c8b,
-	0x2c8d,
-	0x2c8f,
-	0x2c91,
-	0x2c93,
-	0x2c95,
-	0x2c97,
-	0x2c99,
-	0x2c9b,
-	0x2c9d,
-	0x2c9f,
-	0x2ca1,
-	0x2ca3,
-	0x2ca5,
-	0x2ca7,
-	0x2ca9,
-	0x2cab,
-	0x2cad,
-	0x2caf,
-	0x2cb1,
-	0x2cb3,
-	0x2cb5,
-	0x2cb7,
-	0x2cb9,
-	0x2cbb,
-	0x2cbd,
-	0x2cbf,
-	0x2cc1,
-	0x2cc3,
-	0x2cc5,
-	0x2cc7,
-	0x2cc9,
-	0x2ccb,
-	0x2ccd,
-	0x2ccf,
-	0x2cd1,
-	0x2cd3,
-	0x2cd5,
-	0x2cd7,
-	0x2cd9,
-	0x2cdb,
-	0x2cdd,
-	0x2cdf,
-	0x2ce1,
-	0x2cec,
-	0x2cee,
-	0x2cf3,
-	0x2d27,
-	0x2d2d,
-	0xa641,
-	0xa643,
-	0xa645,
-	0xa647,
-	0xa649,
-	0xa64b,
-	0xa64d,
-	0xa64f,
-	0xa651,
-	0xa653,
-	0xa655,
-	0xa657,
-	0xa659,
-	0xa65b,
-	0xa65d,
-	0xa65f,
-	0xa661,
-	0xa663,
-	0xa665,
-	0xa667,
-	0xa669,
-	0xa66b,
-	0xa66d,
-	0xa681,
-	0xa683,
-	0xa685,
-	0xa687,
-	0xa689,
-	0xa68b,
-	0xa68d,
-	0xa68f,
-	0xa691,
-	0xa693,
-	0xa695,
-	0xa697,
-	0xa699,
-	0xa69b,
-	0xa723,
-	0xa725,
-	0xa727,
-	0xa729,
-	0xa72b,
-	0xa72d,
-	0xa733,
-	0xa735,
-	0xa737,
-	0xa739,
-	0xa73b,
-	0xa73d,
-	0xa73f,
-	0xa741,
-	0xa743,
-	0xa745,
-	0xa747,
-	0xa749,
-	0xa74b,
-	0xa74d,
-	0xa74f,
-	0xa751,
-	0xa753,
-	0xa755,
-	0xa757,
-	0xa759,
-	0xa75b,
-	0xa75d,
-	0xa75f,
-	0xa761,
-	0xa763,
-	0xa765,
-	0xa767,
-	0xa769,
-	0xa76b,
-	0xa76d,
-	0xa76f,
-	0xa77a,
-	0xa77c,
-	0xa77f,
-	0xa781,
-	0xa783,
-	0xa785,
-	0xa787,
-	0xa78c,
-	0xa78e,
-	0xa791,
-	0xa797,
-	0xa799,
-	0xa79b,
-	0xa79d,
-	0xa79f,
-	0xa7a1,
-	0xa7a3,
-	0xa7a5,
-	0xa7a7,
-	0xa7a9,
-	0xa7af,
-	0xa7b5,
-	0xa7b7,
-	0xa7b9,
-	0xa7bb,
-	0xa7bd,
-	0xa7bf,
-	0xa7c3,
-	0xa7c8,
-	0xa7ca,
-	0xa7f6,
-	0xa7fa,
-	0x1d4bb,
-	0x1d7cb,
-};
-
-int
-uni_islower(uint32_t c)
-{
-	const uint32_t *p;
-
-	p = search(c, islowerr, nelem (islowerr) / 2, 2);
-
-	if (p && c >= p[0] && c <= p[1])
-		return 1;
-
-	p = search(c, islowers, nelem (islowers), 1);
-
-	if (p && c == p[0])
+	if (bsearch(&r, alpha1, nelem(alpha1), sizeof *alpha1, &cmp1))
 		return 1;
 
 	return 0;
 }
 
-static const uint32_t istitler[] = {
-	0x0041, 0x005a,
-	0x00c0, 0x00d6,
-	0x00d8, 0x00de,
-	0x0178, 0x0179,
-	0x0181, 0x0182,
-	0x0186, 0x0187,
-	0x0189, 0x018b,
-	0x018e, 0x0191,
-	0x0193, 0x0194,
-	0x0196, 0x0198,
-	0x019c, 0x019d,
-	0x019f, 0x01a0,
-	0x01a6, 0x01a7,
-	0x01ae, 0x01af,
-	0x01b1, 0x01b3,
-	0x01b7, 0x01b8,
-	0x01f6, 0x01f8,
-	0x023a, 0x023b,
-	0x023d, 0x023e,
-	0x0243, 0x0246,
-	0x0388, 0x038a,
-	0x038e, 0x038f,
-	0x0391, 0x03a1,
-	0x03a3, 0x03ab,
-	0x03f9, 0x03fa,
-	0x03fd, 0x042f,
-	0x04c0, 0x04c1,
-	0x0531, 0x0556,
-	0x10a0, 0x10c5,
-	0x13a0, 0x13f5,
-	0x1f08, 0x1f0f,
-	0x1f18, 0x1f1d,
-	0x1f28, 0x1f2f,
-	0x1f38, 0x1f3f,
-	0x1f48, 0x1f4d,
-	0x1f68, 0x1f6f,
-	0x1f88, 0x1f8f,
-	0x1f98, 0x1f9f,
-	0x1fa8, 0x1faf,
-	0x1fb8, 0x1fbc,
-	0x1fc8, 0x1fcc,
-	0x1fd8, 0x1fdb,
-	0x1fe8, 0x1fec,
-	0x1ff8, 0x1ffc,
-	0x2160, 0x216f,
-	0x24b6, 0x24cf,
-	0x2c00, 0x2c2e,
-	0x2c62, 0x2c64,
-	0x2c6d, 0x2c70,
-	0x2c7e, 0x2c80,
-	0xa77d, 0xa77e,
-	0xa7aa, 0xa7ae,
-	0xa7b0, 0xa7b4,
-	0xa7c4, 0xa7c7,
-	0xff21, 0xff3a,
-	0x10400, 0x10427,
-	0x104b0, 0x104d3,
-	0x10c80, 0x10cb2,
-	0x118a0, 0x118bf,
-	0x16e40, 0x16e5f,
-	0x1e900, 0x1e921,
+static uint32_t space2[][2] = {
+	{ 0x0009, 0x000D },
+	{ 0x001C, 0x0020 },
+	{ 0x2000, 0x200A },
+	{ 0x2028, 0x2029 },
 };
 
-static const uint32_t istitles[] = {
-	0x0100,
-	0x0102,
-	0x0104,
-	0x0106,
-	0x0108,
-	0x010a,
-	0x010c,
-	0x010e,
-	0x0110,
-	0x0112,
-	0x0114,
-	0x0116,
-	0x0118,
-	0x011a,
-	0x011c,
-	0x011e,
-	0x0120,
-	0x0122,
-	0x0124,
-	0x0126,
-	0x0128,
-	0x012a,
-	0x012c,
-	0x012e,
-	0x0132,
-	0x0134,
-	0x0136,
-	0x0139,
-	0x013b,
-	0x013d,
-	0x013f,
-	0x0141,
-	0x0143,
-	0x0145,
-	0x0147,
-	0x014a,
-	0x014c,
-	0x014e,
-	0x0150,
-	0x0152,
-	0x0154,
-	0x0156,
-	0x0158,
-	0x015a,
-	0x015c,
-	0x015e,
-	0x0160,
-	0x0162,
-	0x0164,
-	0x0166,
-	0x0168,
-	0x016a,
-	0x016c,
-	0x016e,
-	0x0170,
-	0x0172,
-	0x0174,
-	0x0176,
-	0x017b,
-	0x017d,
-	0x0184,
-	0x01a2,
-	0x01a4,
-	0x01a9,
-	0x01ac,
-	0x01b5,
-	0x01bc,
-	0x01c5,
-	0x01c8,
-	0x01cb,
-	0x01cd,
-	0x01cf,
-	0x01d1,
-	0x01d3,
-	0x01d5,
-	0x01d7,
-	0x01d9,
-	0x01db,
-	0x01de,
-	0x01e0,
-	0x01e2,
-	0x01e4,
-	0x01e6,
-	0x01e8,
-	0x01ea,
-	0x01ec,
-	0x01ee,
-	0x01f2,
-	0x01f4,
-	0x01fa,
-	0x01fc,
-	0x01fe,
-	0x0200,
-	0x0202,
-	0x0204,
-	0x0206,
-	0x0208,
-	0x020a,
-	0x020c,
-	0x020e,
-	0x0210,
-	0x0212,
-	0x0214,
-	0x0216,
-	0x0218,
-	0x021a,
-	0x021c,
-	0x021e,
-	0x0220,
-	0x0222,
-	0x0224,
-	0x0226,
-	0x0228,
-	0x022a,
-	0x022c,
-	0x022e,
-	0x0230,
-	0x0232,
-	0x0241,
-	0x0248,
-	0x024a,
-	0x024c,
-	0x024e,
-	0x0370,
-	0x0372,
-	0x0376,
-	0x037f,
-	0x0386,
-	0x038c,
-	0x03cf,
-	0x03d8,
-	0x03da,
-	0x03dc,
-	0x03de,
-	0x03e0,
-	0x03e2,
-	0x03e4,
-	0x03e6,
-	0x03e8,
-	0x03ea,
-	0x03ec,
-	0x03ee,
-	0x03f7,
-	0x0460,
-	0x0462,
-	0x0464,
-	0x0466,
-	0x0468,
-	0x046a,
-	0x046c,
-	0x046e,
-	0x0470,
-	0x0472,
-	0x0474,
-	0x0476,
-	0x0478,
-	0x047a,
-	0x047c,
-	0x047e,
-	0x0480,
-	0x048a,
-	0x048c,
-	0x048e,
-	0x0490,
-	0x0492,
-	0x0494,
-	0x0496,
-	0x0498,
-	0x049a,
-	0x049c,
-	0x049e,
-	0x04a0,
-	0x04a2,
-	0x04a4,
-	0x04a6,
-	0x04a8,
-	0x04aa,
-	0x04ac,
-	0x04ae,
-	0x04b0,
-	0x04b2,
-	0x04b4,
-	0x04b6,
-	0x04b8,
-	0x04ba,
-	0x04bc,
-	0x04be,
-	0x04c3,
-	0x04c5,
-	0x04c7,
-	0x04c9,
-	0x04cb,
-	0x04cd,
-	0x04d0,
-	0x04d2,
-	0x04d4,
-	0x04d6,
-	0x04d8,
-	0x04da,
-	0x04dc,
-	0x04de,
-	0x04e0,
-	0x04e2,
-	0x04e4,
-	0x04e6,
-	0x04e8,
-	0x04ea,
-	0x04ec,
-	0x04ee,
-	0x04f0,
-	0x04f2,
-	0x04f4,
-	0x04f6,
-	0x04f8,
-	0x04fa,
-	0x04fc,
-	0x04fe,
-	0x0500,
-	0x0502,
-	0x0504,
-	0x0506,
-	0x0508,
-	0x050a,
-	0x050c,
-	0x050e,
-	0x0510,
-	0x0512,
-	0x0514,
-	0x0516,
-	0x0518,
-	0x051a,
-	0x051c,
-	0x051e,
-	0x0520,
-	0x0522,
-	0x0524,
-	0x0526,
-	0x0528,
-	0x052a,
-	0x052c,
-	0x052e,
-	0x10c7,
-	0x10cd,
-	0x1e00,
-	0x1e02,
-	0x1e04,
-	0x1e06,
-	0x1e08,
-	0x1e0a,
-	0x1e0c,
-	0x1e0e,
-	0x1e10,
-	0x1e12,
-	0x1e14,
-	0x1e16,
-	0x1e18,
-	0x1e1a,
-	0x1e1c,
-	0x1e1e,
-	0x1e20,
-	0x1e22,
-	0x1e24,
-	0x1e26,
-	0x1e28,
-	0x1e2a,
-	0x1e2c,
-	0x1e2e,
-	0x1e30,
-	0x1e32,
-	0x1e34,
-	0x1e36,
-	0x1e38,
-	0x1e3a,
-	0x1e3c,
-	0x1e3e,
-	0x1e40,
-	0x1e42,
-	0x1e44,
-	0x1e46,
-	0x1e48,
-	0x1e4a,
-	0x1e4c,
-	0x1e4e,
-	0x1e50,
-	0x1e52,
-	0x1e54,
-	0x1e56,
-	0x1e58,
-	0x1e5a,
-	0x1e5c,
-	0x1e5e,
-	0x1e60,
-	0x1e62,
-	0x1e64,
-	0x1e66,
-	0x1e68,
-	0x1e6a,
-	0x1e6c,
-	0x1e6e,
-	0x1e70,
-	0x1e72,
-	0x1e74,
-	0x1e76,
-	0x1e78,
-	0x1e7a,
-	0x1e7c,
-	0x1e7e,
-	0x1e80,
-	0x1e82,
-	0x1e84,
-	0x1e86,
-	0x1e88,
-	0x1e8a,
-	0x1e8c,
-	0x1e8e,
-	0x1e90,
-	0x1e92,
-	0x1e94,
-	0x1ea0,
-	0x1ea2,
-	0x1ea4,
-	0x1ea6,
-	0x1ea8,
-	0x1eaa,
-	0x1eac,
-	0x1eae,
-	0x1eb0,
-	0x1eb2,
-	0x1eb4,
-	0x1eb6,
-	0x1eb8,
-	0x1eba,
-	0x1ebc,
-	0x1ebe,
-	0x1ec0,
-	0x1ec2,
-	0x1ec4,
-	0x1ec6,
-	0x1ec8,
-	0x1eca,
-	0x1ecc,
-	0x1ece,
-	0x1ed0,
-	0x1ed2,
-	0x1ed4,
-	0x1ed6,
-	0x1ed8,
-	0x1eda,
-	0x1edc,
-	0x1ede,
-	0x1ee0,
-	0x1ee2,
-	0x1ee4,
-	0x1ee6,
-	0x1ee8,
-	0x1eea,
-	0x1eec,
-	0x1eee,
-	0x1ef0,
-	0x1ef2,
-	0x1ef4,
-	0x1ef6,
-	0x1ef8,
-	0x1efa,
-	0x1efc,
-	0x1efe,
-	0x1f59,
-	0x1f5b,
-	0x1f5d,
-	0x1f5f,
-	0x2132,
-	0x2183,
-	0x2c60,
-	0x2c67,
-	0x2c69,
-	0x2c6b,
-	0x2c72,
-	0x2c75,
-	0x2c82,
-	0x2c84,
-	0x2c86,
-	0x2c88,
-	0x2c8a,
-	0x2c8c,
-	0x2c8e,
-	0x2c90,
-	0x2c92,
-	0x2c94,
-	0x2c96,
-	0x2c98,
-	0x2c9a,
-	0x2c9c,
-	0x2c9e,
-	0x2ca0,
-	0x2ca2,
-	0x2ca4,
-	0x2ca6,
-	0x2ca8,
-	0x2caa,
-	0x2cac,
-	0x2cae,
-	0x2cb0,
-	0x2cb2,
-	0x2cb4,
-	0x2cb6,
-	0x2cb8,
-	0x2cba,
-	0x2cbc,
-	0x2cbe,
-	0x2cc0,
-	0x2cc2,
-	0x2cc4,
-	0x2cc6,
-	0x2cc8,
-	0x2cca,
-	0x2ccc,
-	0x2cce,
-	0x2cd0,
-	0x2cd2,
-	0x2cd4,
-	0x2cd6,
-	0x2cd8,
-	0x2cda,
-	0x2cdc,
-	0x2cde,
-	0x2ce0,
-	0x2ce2,
-	0x2ceb,
-	0x2ced,
-	0x2cf2,
-	0xa640,
-	0xa642,
-	0xa644,
-	0xa646,
-	0xa648,
-	0xa64a,
-	0xa64c,
-	0xa64e,
-	0xa650,
-	0xa652,
-	0xa654,
-	0xa656,
-	0xa658,
-	0xa65a,
-	0xa65c,
-	0xa65e,
-	0xa660,
-	0xa662,
-	0xa664,
-	0xa666,
-	0xa668,
-	0xa66a,
-	0xa66c,
-	0xa680,
-	0xa682,
-	0xa684,
-	0xa686,
-	0xa688,
-	0xa68a,
-	0xa68c,
-	0xa68e,
-	0xa690,
-	0xa692,
-	0xa694,
-	0xa696,
-	0xa698,
-	0xa69a,
-	0xa722,
-	0xa724,
-	0xa726,
-	0xa728,
-	0xa72a,
-	0xa72c,
-	0xa72e,
-	0xa732,
-	0xa734,
-	0xa736,
-	0xa738,
-	0xa73a,
-	0xa73c,
-	0xa73e,
-	0xa740,
-	0xa742,
-	0xa744,
-	0xa746,
-	0xa748,
-	0xa74a,
-	0xa74c,
-	0xa74e,
-	0xa750,
-	0xa752,
-	0xa754,
-	0xa756,
-	0xa758,
-	0xa75a,
-	0xa75c,
-	0xa75e,
-	0xa760,
-	0xa762,
-	0xa764,
-	0xa766,
-	0xa768,
-	0xa76a,
-	0xa76c,
-	0xa76e,
-	0xa779,
-	0xa77b,
-	0xa780,
-	0xa782,
-	0xa784,
-	0xa786,
-	0xa78b,
-	0xa78d,
-	0xa790,
-	0xa792,
-	0xa796,
-	0xa798,
-	0xa79a,
-	0xa79c,
-	0xa79e,
-	0xa7a0,
-	0xa7a2,
-	0xa7a4,
-	0xa7a6,
-	0xa7a8,
-	0xa7b6,
-	0xa7b8,
-	0xa7ba,
-	0xa7bc,
-	0xa7be,
-	0xa7c2,
-	0xa7c9,
-	0xa7f5,
+static uint32_t space1[] = {
+	0x0085,
+	0x00A0,
+	0x1680,
+	0x202F,
+	0x205F,
+	0x3000,
+};
+
+int
+uni_isspace(uint32_t r)
+{
+	if (bsearch(&r, space2, nelem(space2), sizeof *space2, &cmp2))
+		return 1;
+	if (bsearch(&r, space1, nelem(space1), sizeof *space1, &cmp1))
+		return 1;
+
+	return 0;
+}
+
+static uint32_t control2[][2] = {
+	{ 0x0000, 0x001F },
+	{ 0x007F, 0x009F },
 };
 
 int
-uni_istitle(uint32_t c)
+uni_iscontrol(uint32_t r)
 {
-	const uint32_t *p;
-
-	p = search(c, istitler, nelem (istitler) / 2, 2);
-
-	if (p && c >= p[0] && c <= p[1])
+	if (bsearch(&r, control2, nelem(control2), sizeof *control2, &cmp2))
 		return 1;
 
-	p = search(c, istitles, nelem (istitles), 1);
+	return 0;
+}
+
+static uint32_t upper3[][2] = {
+	{ 0x0100, 0x012E },
+	{ 0x0132, 0x0136 },
+	{ 0x0139, 0x0147 },
+	{ 0x014A, 0x0176 },
+	{ 0x0179, 0x017D },
+	{ 0x0182, 0x0184 },
+	{ 0x01A0, 0x01A4 },
+	{ 0x01B3, 0x01B5 },
+	{ 0x01CD, 0x01DB },
+	{ 0x01DE, 0x01EE },
+	{ 0x01F8, 0x021E },
+	{ 0x0222, 0x0232 },
+	{ 0x0246, 0x024E },
+	{ 0x0370, 0x0372 },
+	{ 0x03D8, 0x03EE },
+	{ 0x0460, 0x0480 },
+	{ 0x048A, 0x04BE },
+	{ 0x04C1, 0x04CD },
+	{ 0x04D0, 0x052E },
+	{ 0x1E00, 0x1E94 },
+	{ 0x1EA0, 0x1EFE },
+	{ 0x2C67, 0x2C6B },
+	{ 0x2C80, 0x2CE2 },
+	{ 0x2CEB, 0x2CED },
+	{ 0xA640, 0xA66C },
+	{ 0xA680, 0xA69A },
+	{ 0xA722, 0xA72E },
+	{ 0xA732, 0xA76E },
+	{ 0xA779, 0xA77B },
+	{ 0xA77E, 0xA786 },
+	{ 0xA790, 0xA792 },
+	{ 0xA796, 0xA7A8 },
+	{ 0xA7B4, 0xA7C2 },
+	{ 0xA7C7, 0xA7C9 },
+	{ 0xA7D6, 0xA7D8 },
+};
 
-	if (p && c == p[0])
+static uint32_t upper2[][3] = {
+	{ 0x0041, 0x005A, 0x0061 },
+	{ 0x00C0, 0x00D6, 0x00E0 },
+	{ 0x00D8, 0x00DE, 0x00F8 },
+	{ 0x0189, 0x018A, 0x0256 },
+	{ 0x01B1, 0x01B2, 0x028A },
+	{ 0x0388, 0x038A, 0x03AD },
+	{ 0x038E, 0x038F, 0x03CD },
+	{ 0x0391, 0x03A1, 0x03B1 },
+	{ 0x03A3, 0x03AB, 0x03C3 },
+	{ 0x03D2, 0x03D4, 0x03D2 },
+	{ 0x03FD, 0x03FF, 0x037B },
+	{ 0x0400, 0x040F, 0x0450 },
+	{ 0x0410, 0x042F, 0x0430 },
+	{ 0x0531, 0x0556, 0x0561 },
+	{ 0x10A0, 0x10C5, 0x2D00 },
+	{ 0x13A0, 0x13EF, 0xAB70 },
+	{ 0x13F0, 0x13F5, 0x13F8 },
+	{ 0x1C90, 0x1CBA, 0x10D0 },
+	{ 0x1CBD, 0x1CBF, 0x10FD },
+	{ 0x1F08, 0x1F0F, 0x1F00 },
+	{ 0x1F18, 0x1F1D, 0x1F10 },
+	{ 0x1F28, 0x1F2F, 0x1F20 },
+	{ 0x1F38, 0x1F3F, 0x1F30 },
+	{ 0x1F48, 0x1F4D, 0x1F40 },
+	{ 0x1F68, 0x1F6F, 0x1F60 },
+	{ 0x1FB8, 0x1FB9, 0x1FB0 },
+	{ 0x1FBA, 0x1FBB, 0x1F70 },
+	{ 0x1FC8, 0x1FCB, 0x1F72 },
+	{ 0x1FD8, 0x1FD9, 0x1FD0 },
+	{ 0x1FDA, 0x1FDB, 0x1F76 },
+	{ 0x1FE8, 0x1FE9, 0x1FE0 },
+	{ 0x1FEA, 0x1FEB, 0x1F7A },
+	{ 0x1FF8, 0x1FF9, 0x1F78 },
+	{ 0x1FFA, 0x1FFB, 0x1F7C },
+	{ 0x210B, 0x210D, 0x210B },
+	{ 0x2110, 0x2112, 0x2110 },
+	{ 0x2119, 0x211D, 0x2119 },
+	{ 0x212C, 0x212D, 0x212C },
+	{ 0x2130, 0x2131, 0x2130 },
+	{ 0x213E, 0x213F, 0x213E },
+	{ 0x2C00, 0x2C2F, 0x2C30 },
+	{ 0x2C7E, 0x2C7F, 0x023F },
+	{ 0xFF21, 0xFF3A, 0xFF41 },
+	{ 0x10400, 0x10427, 0x10428 },
+	{ 0x104B0, 0x104D3, 0x104D8 },
+	{ 0x10570, 0x1057A, 0x10597 },
+	{ 0x1057C, 0x1058A, 0x105A3 },
+	{ 0x1058C, 0x10592, 0x105B3 },
+	{ 0x10594, 0x10595, 0x105BB },
+	{ 0x10C80, 0x10CB2, 0x10CC0 },
+	{ 0x118A0, 0x118BF, 0x118C0 },
+	{ 0x16E40, 0x16E5F, 0x16E60 },
+	{ 0x1D400, 0x1D419, 0x1D400 },
+	{ 0x1D434, 0x1D44D, 0x1D434 },
+	{ 0x1D468, 0x1D481, 0x1D468 },
+	{ 0x1D49E, 0x1D49F, 0x1D49E },
+	{ 0x1D4A5, 0x1D4A6, 0x1D4A5 },
+	{ 0x1D4A9, 0x1D4AC, 0x1D4A9 },
+	{ 0x1D4AE, 0x1D4B5, 0x1D4AE },
+	{ 0x1D4D0, 0x1D4E9, 0x1D4D0 },
+	{ 0x1D504, 0x1D505, 0x1D504 },
+	{ 0x1D507, 0x1D50A, 0x1D507 },
+	{ 0x1D50D, 0x1D514, 0x1D50D },
+	{ 0x1D516, 0x1D51C, 0x1D516 },
+	{ 0x1D538, 0x1D539, 0x1D538 },
+	{ 0x1D53B, 0x1D53E, 0x1D53B },
+	{ 0x1D540, 0x1D544, 0x1D540 },
+	{ 0x1D54A, 0x1D550, 0x1D54A },
+	{ 0x1D56C, 0x1D585, 0x1D56C },
+	{ 0x1D5A0, 0x1D5B9, 0x1D5A0 },
+	{ 0x1D5D4, 0x1D5ED, 0x1D5D4 },
+	{ 0x1D608, 0x1D621, 0x1D608 },
+	{ 0x1D63C, 0x1D655, 0x1D63C },
+	{ 0x1D670, 0x1D689, 0x1D670 },
+	{ 0x1D6A8, 0x1D6C0, 0x1D6A8 },
+	{ 0x1D6E2, 0x1D6FA, 0x1D6E2 },
+	{ 0x1D71C, 0x1D734, 0x1D71C },
+	{ 0x1D756, 0x1D76E, 0x1D756 },
+	{ 0x1D790, 0x1D7A8, 0x1D790 },
+	{ 0x1E900, 0x1E921, 0x1E922 },
+};
+
+static uint32_t upper1[][2] = {
+	{ 0x0130, 0x0069 },
+	{ 0x0178, 0x00FF },
+	{ 0x0181, 0x0253 },
+	{ 0x0186, 0x0254 },
+	{ 0x0187, 0x0188 },
+	{ 0x018B, 0x018C },
+	{ 0x018E, 0x01DD },
+	{ 0x018F, 0x0259 },
+	{ 0x0190, 0x025B },
+	{ 0x0191, 0x0192 },
+	{ 0x0193, 0x0260 },
+	{ 0x0194, 0x0263 },
+	{ 0x0196, 0x0269 },
+	{ 0x0197, 0x0268 },
+	{ 0x0198, 0x0199 },
+	{ 0x019C, 0x026F },
+	{ 0x019D, 0x0272 },
+	{ 0x019F, 0x0275 },
+	{ 0x01A6, 0x0280 },
+	{ 0x01A7, 0x01A8 },
+	{ 0x01A9, 0x0283 },
+	{ 0x01AC, 0x01AD },
+	{ 0x01AE, 0x0288 },
+	{ 0x01AF, 0x01B0 },
+	{ 0x01B7, 0x0292 },
+	{ 0x01B8, 0x01B9 },
+	{ 0x01BC, 0x01BD },
+	{ 0x01C4, 0x01C6 },
+	{ 0x01C7, 0x01C9 },
+	{ 0x01CA, 0x01CC },
+	{ 0x01F1, 0x01F3 },
+	{ 0x01F4, 0x01F5 },
+	{ 0x01F6, 0x0195 },
+	{ 0x01F7, 0x01BF },
+	{ 0x0220, 0x019E },
+	{ 0x023A, 0x2C65 },
+	{ 0x023B, 0x023C },
+	{ 0x023D, 0x019A },
+	{ 0x023E, 0x2C66 },
+	{ 0x0241, 0x0242 },
+	{ 0x0243, 0x0180 },
+	{ 0x0244, 0x0289 },
+	{ 0x0245, 0x028C },
+	{ 0x0376, 0x0377 },
+	{ 0x037F, 0x03F3 },
+	{ 0x0386, 0x03AC },
+	{ 0x038C, 0x03CC },
+	{ 0x03CF, 0x03D7 },
+	{ 0x03F4, 0x03B8 },
+	{ 0x03F7, 0x03F8 },
+	{ 0x03F9, 0x03F2 },
+	{ 0x03FA, 0x03FB },
+	{ 0x04C0, 0x04CF },
+	{ 0x10C7, 0x2D27 },
+	{ 0x10CD, 0x2D2D },
+	{ 0x1E9E, 0x00DF },
+	{ 0x1F59, 0x1F51 },
+	{ 0x1F5B, 0x1F53 },
+	{ 0x1F5D, 0x1F55 },
+	{ 0x1F5F, 0x1F57 },
+	{ 0x1FEC, 0x1FE5 },
+	{ 0x2102, 0x2102 },
+	{ 0x2107, 0x2107 },
+	{ 0x2115, 0x2115 },
+	{ 0x2124, 0x2124 },
+	{ 0x2126, 0x03C9 },
+	{ 0x2128, 0x2128 },
+	{ 0x212A, 0x006B },
+	{ 0x212B, 0x00E5 },
+	{ 0x2132, 0x214E },
+	{ 0x2133, 0x2133 },
+	{ 0x2145, 0x2145 },
+	{ 0x2183, 0x2184 },
+	{ 0x2C60, 0x2C61 },
+	{ 0x2C62, 0x026B },
+	{ 0x2C63, 0x1D7D },
+	{ 0x2C64, 0x027D },
+	{ 0x2C6D, 0x0251 },
+	{ 0x2C6E, 0x0271 },
+	{ 0x2C6F, 0x0250 },
+	{ 0x2C70, 0x0252 },
+	{ 0x2C72, 0x2C73 },
+	{ 0x2C75, 0x2C76 },
+	{ 0x2CF2, 0x2CF3 },
+	{ 0xA77D, 0x1D79 },
+	{ 0xA78B, 0xA78C },
+	{ 0xA78D, 0x0265 },
+	{ 0xA7AA, 0x0266 },
+	{ 0xA7AB, 0x025C },
+	{ 0xA7AC, 0x0261 },
+	{ 0xA7AD, 0x026C },
+	{ 0xA7AE, 0x026A },
+	{ 0xA7B0, 0x029E },
+	{ 0xA7B1, 0x0287 },
+	{ 0xA7B2, 0x029D },
+	{ 0xA7B3, 0xAB53 },
+	{ 0xA7C4, 0xA794 },
+	{ 0xA7C5, 0x0282 },
+	{ 0xA7C6, 0x1D8E },
+	{ 0xA7D0, 0xA7D1 },
+	{ 0xA7F5, 0xA7F6 },
+	{ 0x1D49C, 0x1D49C },
+	{ 0x1D4A2, 0x1D4A2 },
+	{ 0x1D546, 0x1D546 },
+	{ 0x1D7CA, 0x1D7CA },
+};
+
+int
+uni_isupper(uint32_t r)
+{
+	const uint32_t *match;
+
+	if ((match = bsearch(&r, upper3, nelem(upper3), sizeof *upper3, &cmp2)))
+		return !((r - match[0]) % 2);
+	if (bsearch(&r, upper2, nelem(upper2), sizeof *upper2, &cmp2))
+		return 1;
+	if (bsearch(&r, upper1, nelem(upper1), sizeof *upper1, &cmp1))
 		return 1;
 
 	return 0;
 }
 
-static const uint32_t toupperr[] = {
-	0x0061, 0x007a, 1048544,
-	0x00e0, 0x00f6, 1048544,
-	0x00f8, 0x00fe, 1048544,
-	0x023f, 0x0240, 1059391,
-	0x0256, 0x0257, 1048371,
-	0x028a, 0x028b, 1048359,
-	0x037b, 0x037d, 1048706,
-	0x03ad, 0x03af, 1048539,
-	0x03b1, 0x03c1, 1048544,
-	0x03c3, 0x03cb, 1048544,
-	0x03cd, 0x03ce, 1048513,
-	0x0430, 0x044f, 1048544,
-	0x0450, 0x045f, 1048496,
-	0x0561, 0x0586, 1048528,
-	0x10d0, 0x10fa, 1051584,
-	0x10fd, 0x10ff, 1051584,
-	0x13f8, 0x13fd, 1048568,
-	0x1c83, 0x1c84, 1042334,
-	0x1f00, 0x1f07, 1048584,
-	0x1f10, 0x1f15, 1048584,
-	0x1f20, 0x1f27, 1048584,
-	0x1f30, 0x1f37, 1048584,
-	0x1f40, 0x1f45, 1048584,
-	0x1f60, 0x1f67, 1048584,
-	0x1f70, 0x1f71, 1048650,
-	0x1f72, 0x1f75, 1048662,
-	0x1f76, 0x1f77, 1048676,
-	0x1f78, 0x1f79, 1048704,
-	0x1f7a, 0x1f7b, 1048688,
-	0x1f7c, 0x1f7d, 1048702,
-	0x1f80, 0x1f87, 1048584,
-	0x1f90, 0x1f97, 1048584,
-	0x1fa0, 0x1fa7, 1048584,
-	0x1fb0, 0x1fb1, 1048584,
-	0x1fd0, 0x1fd1, 1048584,
-	0x1fe0, 0x1fe1, 1048584,
-	0x2170, 0x217f, 1048560,
-	0x24d0, 0x24e9, 1048550,
-	0x2c30, 0x2c5e, 1048528,
-	0x2d00, 0x2d25, 1041312,
-	0xab70, 0xabbf, 1009712,
-	0xff41, 0xff5a, 1048544,
-	0x10428, 0x1044f, 1048536,
-	0x104d8, 0x104fb, 1048536,
-	0x10cc0, 0x10cf2, 1048512,
-	0x118c0, 0x118df, 1048544,
-	0x16e60, 0x16e7f, 1048544,
-	0x1e922, 0x1e943, 1048542,
+
+uint32_t
+uni_tolower(uint32_t r)
+{
+	uint32_t *match;
+
+	match = bsearch(&r, upper3, nelem(upper3), sizeof *upper3, &cmp2);
+	if (match)
+		return ((r - match[0]) % 2) ? r : r + 1;
+	match = bsearch(&r, upper2, nelem(upper2), sizeof *upper2, &cmp2);
+	if (match)
+		return match[2] + (r - match[0]);
+	match = bsearch(&r, upper1, nelem(upper1), sizeof *upper1, &cmp1);
+	if (match)
+		return match[1];
+	return r;
+}
+static uint32_t lower4[][2] = {
+	{ 0x0101, 0x012F },
+	{ 0x0133, 0x0137 },
+	{ 0x013A, 0x0148 },
+	{ 0x014B, 0x0177 },
+	{ 0x017A, 0x017E },
+	{ 0x0183, 0x0185 },
+	{ 0x01A1, 0x01A5 },
+	{ 0x01B4, 0x01B6 },
+	{ 0x01CE, 0x01DC },
+	{ 0x01DF, 0x01EF },
+	{ 0x01F9, 0x021F },
+	{ 0x0223, 0x0233 },
+	{ 0x0247, 0x024F },
+	{ 0x0371, 0x0373 },
+	{ 0x03D9, 0x03EF },
+	{ 0x0461, 0x0481 },
+	{ 0x048B, 0x04BF },
+	{ 0x04C2, 0x04CE },
+	{ 0x04D1, 0x052F },
+	{ 0x1E01, 0x1E95 },
+	{ 0x1EA1, 0x1EFF },
+	{ 0x2C68, 0x2C6C },
+	{ 0x2C81, 0x2CE3 },
+	{ 0x2CEC, 0x2CEE },
+	{ 0xA641, 0xA66D },
+	{ 0xA681, 0xA69B },
+	{ 0xA723, 0xA72F },
+	{ 0xA733, 0xA76F },
+	{ 0xA77A, 0xA77C },
+	{ 0xA77F, 0xA787 },
+	{ 0xA791, 0xA793 },
+	{ 0xA797, 0xA7A9 },
+	{ 0xA7B5, 0xA7C3 },
+	{ 0xA7C8, 0xA7CA },
+	{ 0xA7D7, 0xA7D9 },
 };
 
-static const uint32_t touppers[] = {
-	0x00b5, 1049319,
-	0x00ff, 1048697,
-	0x0101, 1048575,
-	0x0103, 1048575,
-	0x0105, 1048575,
-	0x0107, 1048575,
-	0x0109, 1048575,
-	0x010b, 1048575,
-	0x010d, 1048575,
-	0x010f, 1048575,
-	0x0111, 1048575,
-	0x0113, 1048575,
-	0x0115, 1048575,
-	0x0117, 1048575,
-	0x0119, 1048575,
-	0x011b, 1048575,
-	0x011d, 1048575,
-	0x011f, 1048575,
-	0x0121, 1048575,
-	0x0123, 1048575,
-	0x0125, 1048575,
-	0x0127, 1048575,
-	0x0129, 1048575,
-	0x012b, 1048575,
-	0x012d, 1048575,
-	0x012f, 1048575,
-	0x0131, 1048344,
-	0x0133, 1048575,
-	0x0135, 1048575,
-	0x0137, 1048575,
-	0x013a, 1048575,
-	0x013c, 1048575,
-	0x013e, 1048575,
-	0x0140, 1048575,
-	0x0142, 1048575,
-	0x0144, 1048575,
-	0x0146, 1048575,
-	0x0148, 1048575,
-	0x014b, 1048575,
-	0x014d, 1048575,
-	0x014f, 1048575,
-	0x0151, 1048575,
-	0x0153, 1048575,
-	0x0155, 1048575,
-	0x0157, 1048575,
-	0x0159, 1048575,
-	0x015b, 1048575,
-	0x015d, 1048575,
-	0x015f, 1048575,
-	0x0161, 1048575,
-	0x0163, 1048575,
-	0x0165, 1048575,
-	0x0167, 1048575,
-	0x0169, 1048575,
-	0x016b, 1048575,
-	0x016d, 1048575,
-	0x016f, 1048575,
-	0x0171, 1048575,
-	0x0173, 1048575,
-	0x0175, 1048575,
-	0x0177, 1048575,
-	0x017a, 1048575,
-	0x017c, 1048575,
-	0x017e, 1048575,
-	0x017f, 1048276,
-	0x0180, 1048771,
-	0x0183, 1048575,
-	0x0185, 1048575,
-	0x0188, 1048575,
-	0x018c, 1048575,
-	0x0192, 1048575,
-	0x0195, 1048673,
-	0x0199, 1048575,
-	0x019a, 1048739,
-	0x019e, 1048706,
-	0x01a1, 1048575,
-	0x01a3, 1048575,
-	0x01a5, 1048575,
-	0x01a8, 1048575,
-	0x01ad, 1048575,
-	0x01b0, 1048575,
-	0x01b4, 1048575,
-	0x01b6, 1048575,
-	0x01b9, 1048575,
-	0x01bd, 1048575,
-	0x01bf, 1048632,
-	0x01c5, 1048575,
-	0x01c6, 1048574,
-	0x01c8, 1048575,
-	0x01c9, 1048574,
-	0x01cb, 1048575,
-	0x01cc, 1048574,
-	0x01ce, 1048575,
-	0x01d0, 1048575,
-	0x01d2, 1048575,
-	0x01d4, 1048575,
-	0x01d6, 1048575,
-	0x01d8, 1048575,
-	0x01da, 1048575,
-	0x01dc, 1048575,
-	0x01dd, 1048497,
-	0x01df, 1048575,
-	0x01e1, 1048575,
-	0x01e3, 1048575,
-	0x01e5, 1048575,
-	0x01e7, 1048575,
-	0x01e9, 1048575,
-	0x01eb, 1048575,
-	0x01ed, 1048575,
-	0x01ef, 1048575,
-	0x01f2, 1048575,
-	0x01f3, 1048574,
-	0x01f5, 1048575,
-	0x01f9, 1048575,
-	0x01fb, 1048575,
-	0x01fd, 1048575,
-	0x01ff, 1048575,
-	0x0201, 1048575,
-	0x0203, 1048575,
-	0x0205, 1048575,
-	0x0207, 1048575,
-	0x0209, 1048575,
-	0x020b, 1048575,
-	0x020d, 1048575,
-	0x020f, 1048575,
-	0x0211, 1048575,
-	0x0213, 1048575,
-	0x0215, 1048575,
-	0x0217, 1048575,
-	0x0219, 1048575,
-	0x021b, 1048575,
-	0x021d, 1048575,
-	0x021f, 1048575,
-	0x0223, 1048575,
-	0x0225, 1048575,
-	0x0227, 1048575,
-	0x0229, 1048575,
-	0x022b, 1048575,
-	0x022d, 1048575,
-	0x022f, 1048575,
-	0x0231, 1048575,
-	0x0233, 1048575,
-	0x023c, 1048575,
-	0x0242, 1048575,
-	0x0247, 1048575,
-	0x0249, 1048575,
-	0x024b, 1048575,
-	0x024d, 1048575,
-	0x024f, 1048575,
-	0x0250, 1059359,
-	0x0251, 1059356,
-	0x0252, 1059358,
-	0x0253, 1048366,
-	0x0254, 1048370,
-	0x0259, 1048374,
-	0x025b, 1048373,
-	0x025c, 1090895,
-	0x0260, 1048371,
-	0x0261, 1090891,
-	0x0263, 1048369,
-	0x0265, 1090856,
-	0x0266, 1090884,
-	0x0268, 1048367,
-	0x0269, 1048365,
-	0x026a, 1090884,
-	0x026b, 1059319,
-	0x026c, 1090881,
-	0x026f, 1048365,
-	0x0271, 1059325,
-	0x0272, 1048363,
-	0x0275, 1048362,
-	0x027d, 1059303,
-	0x0280, 1048358,
-	0x0282, 1090883,
-	0x0283, 1048358,
-	0x0287, 1090858,
-	0x0288, 1048358,
-	0x0289, 1048507,
-	0x028c, 1048505,
-	0x0292, 1048357,
-	0x029d, 1090837,
-	0x029e, 1090834,
-	0x0345, 1048660,
-	0x0371, 1048575,
-	0x0373, 1048575,
-	0x0377, 1048575,
-	0x03ac, 1048538,
-	0x03c2, 1048545,
-	0x03cc, 1048512,
-	0x03d0, 1048514,
-	0x03d1, 1048519,
-	0x03d5, 1048529,
-	0x03d6, 1048522,
-	0x03d7, 1048568,
-	0x03d9, 1048575,
-	0x03db, 1048575,
-	0x03dd, 1048575,
-	0x03df, 1048575,
-	0x03e1, 1048575,
-	0x03e3, 1048575,
-	0x03e5, 1048575,
-	0x03e7, 1048575,
-	0x03e9, 1048575,
-	0x03eb, 1048575,
-	0x03ed, 1048575,
-	0x03ef, 1048575,
-	0x03f0, 1048490,
-	0x03f1, 1048496,
-	0x03f2, 1048583,
-	0x03f3, 1048460,
-	0x03f5, 1048480,
-	0x03f8, 1048575,
-	0x03fb, 1048575,
-	0x0461, 1048575,
-	0x0463, 1048575,
-	0x0465, 1048575,
-	0x0467, 1048575,
-	0x0469, 1048575,
-	0x046b, 1048575,
-	0x046d, 1048575,
-	0x046f, 1048575,
-	0x0471, 1048575,
-	0x0473, 1048575,
-	0x0475, 1048575,
-	0x0477, 1048575,
-	0x0479, 1048575,
-	0x047b, 1048575,
-	0x047d, 1048575,
-	0x047f, 1048575,
-	0x0481, 1048575,
-	0x048b, 1048575,
-	0x048d, 1048575,
-	0x048f, 1048575,
-	0x0491, 1048575,
-	0x0493, 1048575,
-	0x0495, 1048575,
-	0x0497, 1048575,
-	0x0499, 1048575,
-	0x049b, 1048575,
-	0x049d, 1048575,
-	0x049f, 1048575,
-	0x04a1, 1048575,
-	0x04a3, 1048575,
-	0x04a5, 1048575,
-	0x04a7, 1048575,
-	0x04a9, 1048575,
-	0x04ab, 1048575,
-	0x04ad, 1048575,
-	0x04af, 1048575,
-	0x04b1, 1048575,
-	0x04b3, 1048575,
-	0x04b5, 1048575,
-	0x04b7, 1048575,
-	0x04b9, 1048575,
-	0x04bb, 1048575,
-	0x04bd, 1048575,
-	0x04bf, 1048575,
-	0x04c2, 1048575,
-	0x04c4, 1048575,
-	0x04c6, 1048575,
-	0x04c8, 1048575,
-	0x04ca, 1048575,
-	0x04cc, 1048575,
-	0x04ce, 1048575,
-	0x04cf, 1048561,
-	0x04d1, 1048575,
-	0x04d3, 1048575,
-	0x04d5, 1048575,
-	0x04d7, 1048575,
-	0x04d9, 1048575,
-	0x04db, 1048575,
-	0x04dd, 1048575,
-	0x04df, 1048575,
-	0x04e1, 1048575,
-	0x04e3, 1048575,
-	0x04e5, 1048575,
-	0x04e7, 1048575,
-	0x04e9, 1048575,
-	0x04eb, 1048575,
-	0x04ed, 1048575,
-	0x04ef, 1048575,
-	0x04f1, 1048575,
-	0x04f3, 1048575,
-	0x04f5, 1048575,
-	0x04f7, 1048575,
-	0x04f9, 1048575,
-	0x04fb, 1048575,
-	0x04fd, 1048575,
-	0x04ff, 1048575,
-	0x0501, 1048575,
-	0x0503, 1048575,
-	0x0505, 1048575,
-	0x0507, 1048575,
-	0x0509, 1048575,
-	0x050b, 1048575,
-	0x050d, 1048575,
-	0x050f, 1048575,
-	0x0511, 1048575,
-	0x0513, 1048575,
-	0x0515, 1048575,
-	0x0517, 1048575,
-	0x0519, 1048575,
-	0x051b, 1048575,
-	0x051d, 1048575,
-	0x051f, 1048575,
-	0x0521, 1048575,
-	0x0523, 1048575,
-	0x0525, 1048575,
-	0x0527, 1048575,
-	0x0529, 1048575,
-	0x052b, 1048575,
-	0x052d, 1048575,
-	0x052f, 1048575,
-	0x1c80, 1042322,
-	0x1c81, 1042323,
-	0x1c82, 1042332,
-	0x1c85, 1042333,
-	0x1c86, 1042340,
-	0x1c87, 1042395,
-	0x1c88, 1083842,
-	0x1d79, 1083908,
-	0x1d7d, 1052390,
-	0x1d8e, 1083960,
-	0x1e01, 1048575,
-	0x1e03, 1048575,
-	0x1e05, 1048575,
-	0x1e07, 1048575,
-	0x1e09, 1048575,
-	0x1e0b, 1048575,
-	0x1e0d, 1048575,
-	0x1e0f, 1048575,
-	0x1e11, 1048575,
-	0x1e13, 1048575,
-	0x1e15, 1048575,
-	0x1e17, 1048575,
-	0x1e19, 1048575,
-	0x1e1b, 1048575,
-	0x1e1d, 1048575,
-	0x1e1f, 1048575,
-	0x1e21, 1048575,
-	0x1e23, 1048575,
-	0x1e25, 1048575,
-	0x1e27, 1048575,
-	0x1e29, 1048575,
-	0x1e2b, 1048575,
-	0x1e2d, 1048575,
-	0x1e2f, 1048575,
-	0x1e31, 1048575,
-	0x1e33, 1048575,
-	0x1e35, 1048575,
-	0x1e37, 1048575,
-	0x1e39, 1048575,
-	0x1e3b, 1048575,
-	0x1e3d, 1048575,
-	0x1e3f, 1048575,
-	0x1e41, 1048575,
-	0x1e43, 1048575,
-	0x1e45, 1048575,
-	0x1e47, 1048575,
-	0x1e49, 1048575,
-	0x1e4b, 1048575,
-	0x1e4d, 1048575,
-	0x1e4f, 1048575,
-	0x1e51, 1048575,
-	0x1e53, 1048575,
-	0x1e55, 1048575,
-	0x1e57, 1048575,
-	0x1e59, 1048575,
-	0x1e5b, 1048575,
-	0x1e5d, 1048575,
-	0x1e5f, 1048575,
-	0x1e61, 1048575,
-	0x1e63, 1048575,
-	0x1e65, 1048575,
-	0x1e67, 1048575,
-	0x1e69, 1048575,
-	0x1e6b, 1048575,
-	0x1e6d, 1048575,
-	0x1e6f, 1048575,
-	0x1e71, 1048575,
-	0x1e73, 1048575,
-	0x1e75, 1048575,
-	0x1e77, 1048575,
-	0x1e79, 1048575,
-	0x1e7b, 1048575,
-	0x1e7d, 1048575,
-	0x1e7f, 1048575,
-	0x1e81, 1048575,
-	0x1e83, 1048575,
-	0x1e85, 1048575,
-	0x1e87, 1048575,
-	0x1e89, 1048575,
-	0x1e8b, 1048575,
-	0x1e8d, 1048575,
-	0x1e8f, 1048575,
-	0x1e91, 1048575,
-	0x1e93, 1048575,
-	0x1e95, 1048575,
-	0x1e9b, 1048517,
-	0x1ea1, 1048575,
-	0x1ea3, 1048575,
-	0x1ea5, 1048575,
-	0x1ea7, 1048575,
-	0x1ea9, 1048575,
-	0x1eab, 1048575,
-	0x1ead, 1048575,
-	0x1eaf, 1048575,
-	0x1eb1, 1048575,
-	0x1eb3, 1048575,
-	0x1eb5, 1048575,
-	0x1eb7, 1048575,
-	0x1eb9, 1048575,
-	0x1ebb, 1048575,
-	0x1ebd, 1048575,
-	0x1ebf, 1048575,
-	0x1ec1, 1048575,
-	0x1ec3, 1048575,
-	0x1ec5, 1048575,
-	0x1ec7, 1048575,
-	0x1ec9, 1048575,
-	0x1ecb, 1048575,
-	0x1ecd, 1048575,
-	0x1ecf, 1048575,
-	0x1ed1, 1048575,
-	0x1ed3, 1048575,
-	0x1ed5, 1048575,
-	0x1ed7, 1048575,
-	0x1ed9, 1048575,
-	0x1edb, 1048575,
-	0x1edd, 1048575,
-	0x1edf, 1048575,
-	0x1ee1, 1048575,
-	0x1ee3, 1048575,
-	0x1ee5, 1048575,
-	0x1ee7, 1048575,
-	0x1ee9, 1048575,
-	0x1eeb, 1048575,
-	0x1eed, 1048575,
-	0x1eef, 1048575,
-	0x1ef1, 1048575,
-	0x1ef3, 1048575,
-	0x1ef5, 1048575,
-	0x1ef7, 1048575,
-	0x1ef9, 1048575,
-	0x1efb, 1048575,
-	0x1efd, 1048575,
-	0x1eff, 1048575,
-	0x1f51, 1048584,
-	0x1f53, 1048584,
-	0x1f55, 1048584,
-	0x1f57, 1048584,
-	0x1fb3, 1048585,
-	0x1fbe, 1041371,
-	0x1fc3, 1048585,
-	0x1fe5, 1048583,
-	0x1ff3, 1048585,
-	0x214e, 1048548,
-	0x2184, 1048575,
-	0x2c61, 1048575,
-	0x2c65, 1037781,
-	0x2c66, 1037784,
-	0x2c68, 1048575,
-	0x2c6a, 1048575,
-	0x2c6c, 1048575,
-	0x2c73, 1048575,
-	0x2c76, 1048575,
-	0x2c81, 1048575,
-	0x2c83, 1048575,
-	0x2c85, 1048575,
-	0x2c87, 1048575,
-	0x2c89, 1048575,
-	0x2c8b, 1048575,
-	0x2c8d, 1048575,
-	0x2c8f, 1048575,
-	0x2c91, 1048575,
-	0x2c93, 1048575,
-	0x2c95, 1048575,
-	0x2c97, 1048575,
-	0x2c99, 1048575,
-	0x2c9b, 1048575,
-	0x2c9d, 1048575,
-	0x2c9f, 1048575,
-	0x2ca1, 1048575,
-	0x2ca3, 1048575,
-	0x2ca5, 1048575,
-	0x2ca7, 1048575,
-	0x2ca9, 1048575,
-	0x2cab, 1048575,
-	0x2cad, 1048575,
-	0x2caf, 1048575,
-	0x2cb1, 1048575,
-	0x2cb3, 1048575,
-	0x2cb5, 1048575,
-	0x2cb7, 1048575,
-	0x2cb9, 1048575,
-	0x2cbb, 1048575,
-	0x2cbd, 1048575,
-	0x2cbf, 1048575,
-	0x2cc1, 1048575,
-	0x2cc3, 1048575,
-	0x2cc5, 1048575,
-	0x2cc7, 1048575,
-	0x2cc9, 1048575,
-	0x2ccb, 1048575,
-	0x2ccd, 1048575,
-	0x2ccf, 1048575,
-	0x2cd1, 1048575,
-	0x2cd3, 1048575,
-	0x2cd5, 1048575,
-	0x2cd7, 1048575,
-	0x2cd9, 1048575,
-	0x2cdb, 1048575,
-	0x2cdd, 1048575,
-	0x2cdf, 1048575,
-	0x2ce1, 1048575,
-	0x2ce3, 1048575,
-	0x2cec, 1048575,
-	0x2cee, 1048575,
-	0x2cf3, 1048575,
-	0x2d27, 1041312,
-	0x2d2d, 1041312,
-	0xa641, 1048575,
-	0xa643, 1048575,
-	0xa645, 1048575,
-	0xa647, 1048575,
-	0xa649, 1048575,
-	0xa64b, 1048575,
-	0xa64d, 1048575,
-	0xa64f, 1048575,
-	0xa651, 1048575,
-	0xa653, 1048575,
-	0xa655, 1048575,
-	0xa657, 1048575,
-	0xa659, 1048575,
-	0xa65b, 1048575,
-	0xa65d, 1048575,
-	0xa65f, 1048575,
-	0xa661, 1048575,
-	0xa663, 1048575,
-	0xa665, 1048575,
-	0xa667, 1048575,
-	0xa669, 1048575,
-	0xa66b, 1048575,
-	0xa66d, 1048575,
-	0xa681, 1048575,
-	0xa683, 1048575,
-	0xa685, 1048575,
-	0xa687, 1048575,
-	0xa689, 1048575,
-	0xa68b, 1048575,
-	0xa68d, 1048575,
-	0xa68f, 1048575,
-	0xa691, 1048575,
-	0xa693, 1048575,
-	0xa695, 1048575,
-	0xa697, 1048575,
-	0xa699, 1048575,
-	0xa69b, 1048575,
-	0xa723, 1048575,
-	0xa725, 1048575,
-	0xa727, 1048575,
-	0xa729, 1048575,
-	0xa72b, 1048575,
-	0xa72d, 1048575,
-	0xa72f, 1048575,
-	0xa733, 1048575,
-	0xa735, 1048575,
-	0xa737, 1048575,
-	0xa739, 1048575,
-	0xa73b, 1048575,
-	0xa73d, 1048575,
-	0xa73f, 1048575,
-	0xa741, 1048575,
-	0xa743, 1048575,
-	0xa745, 1048575,
-	0xa747, 1048575,
-	0xa749, 1048575,
-	0xa74b, 1048575,
-	0xa74d, 1048575,
-	0xa74f, 1048575,
-	0xa751, 1048575,
-	0xa753, 1048575,
-	0xa755, 1048575,
-	0xa757, 1048575,
-	0xa759, 1048575,
-	0xa75b, 1048575,
-	0xa75d, 1048575,
-	0xa75f, 1048575,
-	0xa761, 1048575,
-	0xa763, 1048575,
-	0xa765, 1048575,
-	0xa767, 1048575,
-	0xa769, 1048575,
-	0xa76b, 1048575,
-	0xa76d, 1048575,
-	0xa76f, 1048575,
-	0xa77a, 1048575,
-	0xa77c, 1048575,
-	0xa77f, 1048575,
-	0xa781, 1048575,
-	0xa783, 1048575,
-	0xa785, 1048575,
-	0xa787, 1048575,
-	0xa78c, 1048575,
-	0xa791, 1048575,
-	0xa793, 1048575,
-	0xa794, 1048624,
-	0xa797, 1048575,
-	0xa799, 1048575,
-	0xa79b, 1048575,
-	0xa79d, 1048575,
-	0xa79f, 1048575,
-	0xa7a1, 1048575,
-	0xa7a3, 1048575,
-	0xa7a5, 1048575,
-	0xa7a7, 1048575,
-	0xa7a9, 1048575,
-	0xa7b5, 1048575,
-	0xa7b7, 1048575,
-	0xa7b9, 1048575,
-	0xa7bb, 1048575,
-	0xa7bd, 1048575,
-	0xa7bf, 1048575,
-	0xa7c3, 1048575,
-	0xa7c8, 1048575,
-	0xa7ca, 1048575,
-	0xa7f6, 1048575,
-	0xab53, 1047648,
-};
-
-uint32_t
-uni_toupper(uint32_t c)
-{
-	const uint32_t *p;
-
-	p = search(c, toupperr, nelem (toupperr) / 3, 3);
-
-	if (p && c >= p[0] && c <= p[1])
-		return c + p[2] - 1048576;
-
-	p = search(c, touppers, nelem (touppers) / 2, 2);
-
-	if (p && c == p[0])
-		return c + p[1] - 1048576;
-
-	return c;
-}
-
-static const uint32_t tolowerr[] = {
-	0x0041, 0x005a, 1048608,
-	0x00c0, 0x00d6, 1048608,
-	0x00d8, 0x00de, 1048608,
-	0x0189, 0x018a, 1048781,
-	0x01b1, 0x01b2, 1048793,
-	0x0388, 0x038a, 1048613,
-	0x038e, 0x038f, 1048639,
-	0x0391, 0x03a1, 1048608,
-	0x03a3, 0x03ab, 1048608,
-	0x03fd, 0x03ff, 1048446,
-	0x0400, 0x040f, 1048656,
-	0x0410, 0x042f, 1048608,
-	0x0531, 0x0556, 1048624,
-	0x10a0, 0x10c5, 1055840,
-	0x13a0, 0x13ef, 1087440,
-	0x13f0, 0x13f5, 1048584,
-	0x1c90, 0x1cba, 1045568,
-	0x1cbd, 0x1cbf, 1045568,
-	0x1f08, 0x1f0f, 1048568,
-	0x1f18, 0x1f1d, 1048568,
-	0x1f28, 0x1f2f, 1048568,
-	0x1f38, 0x1f3f, 1048568,
-	0x1f48, 0x1f4d, 1048568,
-	0x1f68, 0x1f6f, 1048568,
-	0x1f88, 0x1f8f, 1048568,
-	0x1f98, 0x1f9f, 1048568,
-	0x1fa8, 0x1faf, 1048568,
-	0x1fb8, 0x1fb9, 1048568,
-	0x1fba, 0x1fbb, 1048502,
-	0x1fc8, 0x1fcb, 1048490,
-	0x1fd8, 0x1fd9, 1048568,
-	0x1fda, 0x1fdb, 1048476,
-	0x1fe8, 0x1fe9, 1048568,
-	0x1fea, 0x1feb, 1048464,
-	0x1ff8, 0x1ff9, 1048448,
-	0x1ffa, 0x1ffb, 1048450,
-	0x2160, 0x216f, 1048592,
-	0x24b6, 0x24cf, 1048602,
-	0x2c00, 0x2c2e, 1048624,
-	0x2c7e, 0x2c7f, 1037761,
-	0xff21, 0xff3a, 1048608,
-	0x10400, 0x10427, 1048616,
-	0x104b0, 0x104d3, 1048616,
-	0x10c80, 0x10cb2, 1048640,
-	0x118a0, 0x118bf, 1048608,
-	0x16e40, 0x16e5f, 1048608,
-	0x1e900, 0x1e921, 1048610,
+static uint32_t lower2[][3] = {
+	{ 0x0061, 0x007A, 0x0041 },
+	{ 0x00E0, 0x00F6, 0x00C0 },
+	{ 0x00F8, 0x00FE, 0x00D8 },
+	{ 0x01AA, 0x01AB, 0x01AA },
+	{ 0x0234, 0x0239, 0x0234 },
+	{ 0x023F, 0x0240, 0x2C7E },
+	{ 0x0256, 0x0257, 0x0189 },
+	{ 0x025D, 0x025F, 0x025D },
+	{ 0x026D, 0x026E, 0x026D },
+	{ 0x0273, 0x0274, 0x0273 },
+	{ 0x0276, 0x027C, 0x0276 },
+	{ 0x027E, 0x027F, 0x027E },
+	{ 0x0284, 0x0286, 0x0284 },
+	{ 0x028A, 0x028B, 0x01B1 },
+	{ 0x028D, 0x0291, 0x028D },
+	{ 0x0295, 0x029C, 0x0295 },
+	{ 0x029F, 0x02AF, 0x029F },
+	{ 0x037B, 0x037D, 0x03FD },
+	{ 0x03AD, 0x03AF, 0x0388 },
+	{ 0x03B1, 0x03C1, 0x0391 },
+	{ 0x03C3, 0x03CB, 0x03A3 },
+	{ 0x03CD, 0x03CE, 0x038E },
+	{ 0x0430, 0x044F, 0x0410 },
+	{ 0x0450, 0x045F, 0x0400 },
+	{ 0x0561, 0x0586, 0x0531 },
+	{ 0x0587, 0x0588, 0x0587 },
+	{ 0x10D0, 0x10FA, 0x1C90 },
+	{ 0x10FD, 0x10FF, 0x1CBD },
+	{ 0x13F8, 0x13FD, 0x13F0 },
+	{ 0x1C83, 0x1C84, 0x0421 },
+	{ 0x1D00, 0x1D2B, 0x1D00 },
+	{ 0x1D6B, 0x1D77, 0x1D6B },
+	{ 0x1D7A, 0x1D7C, 0x1D7A },
+	{ 0x1D7E, 0x1D8D, 0x1D7E },
+	{ 0x1D8F, 0x1D9A, 0x1D8F },
+	{ 0x1E96, 0x1E9A, 0x1E96 },
+	{ 0x1E9C, 0x1E9D, 0x1E9C },
+	{ 0x1F00, 0x1F07, 0x1F08 },
+	{ 0x1F10, 0x1F15, 0x1F18 },
+	{ 0x1F20, 0x1F27, 0x1F28 },
+	{ 0x1F30, 0x1F37, 0x1F38 },
+	{ 0x1F40, 0x1F45, 0x1F48 },
+	{ 0x1F60, 0x1F67, 0x1F68 },
+	{ 0x1F70, 0x1F71, 0x1FBA },
+	{ 0x1F72, 0x1F75, 0x1FC8 },
+	{ 0x1F76, 0x1F77, 0x1FDA },
+	{ 0x1F78, 0x1F79, 0x1FF8 },
+	{ 0x1F7A, 0x1F7B, 0x1FEA },
+	{ 0x1F7C, 0x1F7D, 0x1FFA },
+	{ 0x1F80, 0x1F87, 0x1F88 },
+	{ 0x1F90, 0x1F97, 0x1F98 },
+	{ 0x1FA0, 0x1FA7, 0x1FA8 },
+	{ 0x1FB0, 0x1FB1, 0x1FB8 },
+	{ 0x1FB6, 0x1FB7, 0x1FB6 },
+	{ 0x1FC6, 0x1FC7, 0x1FC6 },
+	{ 0x1FD0, 0x1FD1, 0x1FD8 },
+	{ 0x1FD2, 0x1FD3, 0x1FD2 },
+	{ 0x1FD6, 0x1FD7, 0x1FD6 },
+	{ 0x1FE0, 0x1FE1, 0x1FE8 },
+	{ 0x1FE2, 0x1FE4, 0x1FE2 },
+	{ 0x1FE6, 0x1FE7, 0x1FE6 },
+	{ 0x1FF6, 0x1FF7, 0x1FF6 },
+	{ 0x210E, 0x210F, 0x210E },
+	{ 0x213C, 0x213D, 0x213C },
+	{ 0x2146, 0x2149, 0x2146 },
+	{ 0x2C30, 0x2C5F, 0x2C00 },
+	{ 0x2C77, 0x2C7B, 0x2C77 },
+	{ 0x2D00, 0x2D25, 0x10A0 },
+	{ 0xA730, 0xA731, 0xA730 },
+	{ 0xA771, 0xA778, 0xA771 },
+	{ 0xAB30, 0xAB52, 0xAB30 },
+	{ 0xAB54, 0xAB5A, 0xAB54 },
+	{ 0xAB60, 0xAB68, 0xAB60 },
+	{ 0xAB70, 0xABBF, 0x13A0 },
+	{ 0xFB00, 0xFB06, 0xFB00 },
+	{ 0xFB13, 0xFB17, 0xFB13 },
+	{ 0xFF41, 0xFF5A, 0xFF21 },
+	{ 0x10428, 0x1044F, 0x10400 },
+	{ 0x104D8, 0x104FB, 0x104B0 },
+	{ 0x10597, 0x105A1, 0x10570 },
+	{ 0x105A3, 0x105B1, 0x1057C },
+	{ 0x105B3, 0x105B9, 0x1058C },
+	{ 0x105BB, 0x105BC, 0x10594 },
+	{ 0x10CC0, 0x10CF2, 0x10C80 },
+	{ 0x118C0, 0x118DF, 0x118A0 },
+	{ 0x16E60, 0x16E7F, 0x16E40 },
+	{ 0x1D41A, 0x1D433, 0x1D41A },
+	{ 0x1D44E, 0x1D454, 0x1D44E },
+	{ 0x1D456, 0x1D467, 0x1D456 },
+	{ 0x1D482, 0x1D49B, 0x1D482 },
+	{ 0x1D4B6, 0x1D4B9, 0x1D4B6 },
+	{ 0x1D4BD, 0x1D4C3, 0x1D4BD },
+	{ 0x1D4C5, 0x1D4CF, 0x1D4C5 },
+	{ 0x1D4EA, 0x1D503, 0x1D4EA },
+	{ 0x1D51E, 0x1D537, 0x1D51E },
+	{ 0x1D552, 0x1D56B, 0x1D552 },
+	{ 0x1D586, 0x1D59F, 0x1D586 },
+	{ 0x1D5BA, 0x1D5D3, 0x1D5BA },
+	{ 0x1D5EE, 0x1D607, 0x1D5EE },
+	{ 0x1D622, 0x1D63B, 0x1D622 },
+	{ 0x1D656, 0x1D66F, 0x1D656 },
+	{ 0x1D68A, 0x1D6A5, 0x1D68A },
+	{ 0x1D6C2, 0x1D6DA, 0x1D6C2 },
+	{ 0x1D6DC, 0x1D6E1, 0x1D6DC },
+	{ 0x1D6FC, 0x1D714, 0x1D6FC },
+	{ 0x1D716, 0x1D71B, 0x1D716 },
+	{ 0x1D736, 0x1D74E, 0x1D736 },
+	{ 0x1D750, 0x1D755, 0x1D750 },
+	{ 0x1D770, 0x1D788, 0x1D770 },
+	{ 0x1D78A, 0x1D78F, 0x1D78A },
+	{ 0x1D7AA, 0x1D7C2, 0x1D7AA },
+	{ 0x1D7C4, 0x1D7C9, 0x1D7C4 },
+	{ 0x1DF00, 0x1DF09, 0x1DF00 },
+	{ 0x1DF0B, 0x1DF1E, 0x1DF0B },
+	{ 0x1E922, 0x1E943, 0x1E900 },
 };
 
-static const uint32_t tolowers[] = {
-	0x0100, 1048577,
-	0x0102, 1048577,
-	0x0104, 1048577,
-	0x0106, 1048577,
-	0x0108, 1048577,
-	0x010a, 1048577,
-	0x010c, 1048577,
-	0x010e, 1048577,
-	0x0110, 1048577,
-	0x0112, 1048577,
-	0x0114, 1048577,
-	0x0116, 1048577,
-	0x0118, 1048577,
-	0x011a, 1048577,
-	0x011c, 1048577,
-	0x011e, 1048577,
-	0x0120, 1048577,
-	0x0122, 1048577,
-	0x0124, 1048577,
-	0x0126, 1048577,
-	0x0128, 1048577,
-	0x012a, 1048577,
-	0x012c, 1048577,
-	0x012e, 1048577,
-	0x0130, 1048377,
-	0x0132, 1048577,
-	0x0134, 1048577,
-	0x0136, 1048577,
-	0x0139, 1048577,
-	0x013b, 1048577,
-	0x013d, 1048577,
-	0x013f, 1048577,
-	0x0141, 1048577,
-	0x0143, 1048577,
-	0x0145, 1048577,
-	0x0147, 1048577,
-	0x014a, 1048577,
-	0x014c, 1048577,
-	0x014e, 1048577,
-	0x0150, 1048577,
-	0x0152, 1048577,
-	0x0154, 1048577,
-	0x0156, 1048577,
-	0x0158, 1048577,
-	0x015a, 1048577,
-	0x015c, 1048577,
-	0x015e, 1048577,
-	0x0160, 1048577,
-	0x0162, 1048577,
-	0x0164, 1048577,
-	0x0166, 1048577,
-	0x0168, 1048577,
-	0x016a, 1048577,
-	0x016c, 1048577,
-	0x016e, 1048577,
-	0x0170, 1048577,
-	0x0172, 1048577,
-	0x0174, 1048577,
-	0x0176, 1048577,
-	0x0178, 1048455,
-	0x0179, 1048577,
-	0x017b, 1048577,
-	0x017d, 1048577,
-	0x0181, 1048786,
-	0x0182, 1048577,
-	0x0184, 1048577,
-	0x0186, 1048782,
-	0x0187, 1048577,
-	0x018b, 1048577,
-	0x018e, 1048655,
-	0x018f, 1048778,
-	0x0190, 1048779,
-	0x0191, 1048577,
-	0x0193, 1048781,
-	0x0194, 1048783,
-	0x0196, 1048787,
-	0x0197, 1048785,
-	0x0198, 1048577,
-	0x019c, 1048787,
-	0x019d, 1048789,
-	0x019f, 1048790,
-	0x01a0, 1048577,
-	0x01a2, 1048577,
-	0x01a4, 1048577,
-	0x01a6, 1048794,
-	0x01a7, 1048577,
-	0x01a9, 1048794,
-	0x01ac, 1048577,
-	0x01ae, 1048794,
-	0x01af, 1048577,
-	0x01b3, 1048577,
-	0x01b5, 1048577,
-	0x01b7, 1048795,
-	0x01b8, 1048577,
-	0x01bc, 1048577,
-	0x01c4, 1048578,
-	0x01c5, 1048577,
-	0x01c7, 1048578,
-	0x01c8, 1048577,
-	0x01ca, 1048578,
-	0x01cb, 1048577,
-	0x01cd, 1048577,
-	0x01cf, 1048577,
-	0x01d1, 1048577,
-	0x01d3, 1048577,
-	0x01d5, 1048577,
-	0x01d7, 1048577,
-	0x01d9, 1048577,
-	0x01db, 1048577,
-	0x01de, 1048577,
-	0x01e0, 1048577,
-	0x01e2, 1048577,
-	0x01e4, 1048577,
-	0x01e6, 1048577,
-	0x01e8, 1048577,
-	0x01ea, 1048577,
-	0x01ec, 1048577,
-	0x01ee, 1048577,
-	0x01f1, 1048578,
-	0x01f2, 1048577,
-	0x01f4, 1048577,
-	0x01f6, 1048479,
-	0x01f7, 1048520,
-	0x01f8, 1048577,
-	0x01fa, 1048577,
-	0x01fc, 1048577,
-	0x01fe, 1048577,
-	0x0200, 1048577,
-	0x0202, 1048577,
-	0x0204, 1048577,
-	0x0206, 1048577,
-	0x0208, 1048577,
-	0x020a, 1048577,
-	0x020c, 1048577,
-	0x020e, 1048577,
-	0x0210, 1048577,
-	0x0212, 1048577,
-	0x0214, 1048577,
-	0x0216, 1048577,
-	0x0218, 1048577,
-	0x021a, 1048577,
-	0x021c, 1048577,
-	0x021e, 1048577,
-	0x0220, 1048446,
-	0x0222, 1048577,
-	0x0224, 1048577,
-	0x0226, 1048577,
-	0x0228, 1048577,
-	0x022a, 1048577,
-	0x022c, 1048577,
-	0x022e, 1048577,
-	0x0230, 1048577,
-	0x0232, 1048577,
-	0x023a, 1059371,
-	0x023b, 1048577,
-	0x023d, 1048413,
-	0x023e, 1059368,
-	0x0241, 1048577,
-	0x0243, 1048381,
-	0x0244, 1048645,
-	0x0245, 1048647,
-	0x0246, 1048577,
-	0x0248, 1048577,
-	0x024a, 1048577,
-	0x024c, 1048577,
-	0x024e, 1048577,
-	0x0370, 1048577,
-	0x0372, 1048577,
-	0x0376, 1048577,
-	0x037f, 1048692,
-	0x0386, 1048614,
-	0x038c, 1048640,
-	0x03cf, 1048584,
-	0x03d8, 1048577,
-	0x03da, 1048577,
-	0x03dc, 1048577,
-	0x03de, 1048577,
-	0x03e0, 1048577,
-	0x03e2, 1048577,
-	0x03e4, 1048577,
-	0x03e6, 1048577,
-	0x03e8, 1048577,
-	0x03ea, 1048577,
-	0x03ec, 1048577,
-	0x03ee, 1048577,
-	0x03f4, 1048516,
-	0x03f7, 1048577,
-	0x03f9, 1048569,
-	0x03fa, 1048577,
-	0x0460, 1048577,
-	0x0462, 1048577,
-	0x0464, 1048577,
-	0x0466, 1048577,
-	0x0468, 1048577,
-	0x046a, 1048577,
-	0x046c, 1048577,
-	0x046e, 1048577,
-	0x0470, 1048577,
-	0x0472, 1048577,
-	0x0474, 1048577,
-	0x0476, 1048577,
-	0x0478, 1048577,
-	0x047a, 1048577,
-	0x047c, 1048577,
-	0x047e, 1048577,
-	0x0480, 1048577,
-	0x048a, 1048577,
-	0x048c, 1048577,
-	0x048e, 1048577,
-	0x0490, 1048577,
-	0x0492, 1048577,
-	0x0494, 1048577,
-	0x0496, 1048577,
-	0x0498, 1048577,
-	0x049a, 1048577,
-	0x049c, 1048577,
-	0x049e, 1048577,
-	0x04a0, 1048577,
-	0x04a2, 1048577,
-	0x04a4, 1048577,
-	0x04a6, 1048577,
-	0x04a8, 1048577,
-	0x04aa, 1048577,
-	0x04ac, 1048577,
-	0x04ae, 1048577,
-	0x04b0, 1048577,
-	0x04b2, 1048577,
-	0x04b4, 1048577,
-	0x04b6, 1048577,
-	0x04b8, 1048577,
-	0x04ba, 1048577,
-	0x04bc, 1048577,
-	0x04be, 1048577,
-	0x04c0, 1048591,
-	0x04c1, 1048577,
-	0x04c3, 1048577,
-	0x04c5, 1048577,
-	0x04c7, 1048577,
-	0x04c9, 1048577,
-	0x04cb, 1048577,
-	0x04cd, 1048577,
-	0x04d0, 1048577,
-	0x04d2, 1048577,
-	0x04d4, 1048577,
-	0x04d6, 1048577,
-	0x04d8, 1048577,
-	0x04da, 1048577,
-	0x04dc, 1048577,
-	0x04de, 1048577,
-	0x04e0, 1048577,
-	0x04e2, 1048577,
-	0x04e4, 1048577,
-	0x04e6, 1048577,
-	0x04e8, 1048577,
-	0x04ea, 1048577,
-	0x04ec, 1048577,
-	0x04ee, 1048577,
-	0x04f0, 1048577,
-	0x04f2, 1048577,
-	0x04f4, 1048577,
-	0x04f6, 1048577,
-	0x04f8, 1048577,
-	0x04fa, 1048577,
-	0x04fc, 1048577,
-	0x04fe, 1048577,
-	0x0500, 1048577,
-	0x0502, 1048577,
-	0x0504, 1048577,
-	0x0506, 1048577,
-	0x0508, 1048577,
-	0x050a, 1048577,
-	0x050c, 1048577,
-	0x050e, 1048577,
-	0x0510, 1048577,
-	0x0512, 1048577,
-	0x0514, 1048577,
-	0x0516, 1048577,
-	0x0518, 1048577,
-	0x051a, 1048577,
-	0x051c, 1048577,
-	0x051e, 1048577,
-	0x0520, 1048577,
-	0x0522, 1048577,
-	0x0524, 1048577,
-	0x0526, 1048577,
-	0x0528, 1048577,
-	0x052a, 1048577,
-	0x052c, 1048577,
-	0x052e, 1048577,
-	0x10c7, 1055840,
-	0x10cd, 1055840,
-	0x1e00, 1048577,
-	0x1e02, 1048577,
-	0x1e04, 1048577,
-	0x1e06, 1048577,
-	0x1e08, 1048577,
-	0x1e0a, 1048577,
-	0x1e0c, 1048577,
-	0x1e0e, 1048577,
-	0x1e10, 1048577,
-	0x1e12, 1048577,
-	0x1e14, 1048577,
-	0x1e16, 1048577,
-	0x1e18, 1048577,
-	0x1e1a, 1048577,
-	0x1e1c, 1048577,
-	0x1e1e, 1048577,
-	0x1e20, 1048577,
-	0x1e22, 1048577,
-	0x1e24, 1048577,
-	0x1e26, 1048577,
-	0x1e28, 1048577,
-	0x1e2a, 1048577,
-	0x1e2c, 1048577,
-	0x1e2e, 1048577,
-	0x1e30, 1048577,
-	0x1e32, 1048577,
-	0x1e34, 1048577,
-	0x1e36, 1048577,
-	0x1e38, 1048577,
-	0x1e3a, 1048577,
-	0x1e3c, 1048577,
-	0x1e3e, 1048577,
-	0x1e40, 1048577,
-	0x1e42, 1048577,
-	0x1e44, 1048577,
-	0x1e46, 1048577,
-	0x1e48, 1048577,
-	0x1e4a, 1048577,
-	0x1e4c, 1048577,
-	0x1e4e, 1048577,
-	0x1e50, 1048577,
-	0x1e52, 1048577,
-	0x1e54, 1048577,
-	0x1e56, 1048577,
-	0x1e58, 1048577,
-	0x1e5a, 1048577,
-	0x1e5c, 1048577,
-	0x1e5e, 1048577,
-	0x1e60, 1048577,
-	0x1e62, 1048577,
-	0x1e64, 1048577,
-	0x1e66, 1048577,
-	0x1e68, 1048577,
-	0x1e6a, 1048577,
-	0x1e6c, 1048577,
-	0x1e6e, 1048577,
-	0x1e70, 1048577,
-	0x1e72, 1048577,
-	0x1e74, 1048577,
-	0x1e76, 1048577,
-	0x1e78, 1048577,
-	0x1e7a, 1048577,
-	0x1e7c, 1048577,
-	0x1e7e, 1048577,
-	0x1e80, 1048577,
-	0x1e82, 1048577,
-	0x1e84, 1048577,
-	0x1e86, 1048577,
-	0x1e88, 1048577,
-	0x1e8a, 1048577,
-	0x1e8c, 1048577,
-	0x1e8e, 1048577,
-	0x1e90, 1048577,
-	0x1e92, 1048577,
-	0x1e94, 1048577,
-	0x1e9e, 1040961,
-	0x1ea0, 1048577,
-	0x1ea2, 1048577,
-	0x1ea4, 1048577,
-	0x1ea6, 1048577,
-	0x1ea8, 1048577,
-	0x1eaa, 1048577,
-	0x1eac, 1048577,
-	0x1eae, 1048577,
-	0x1eb0, 1048577,
-	0x1eb2, 1048577,
-	0x1eb4, 1048577,
-	0x1eb6, 1048577,
-	0x1eb8, 1048577,
-	0x1eba, 1048577,
-	0x1ebc, 1048577,
-	0x1ebe, 1048577,
-	0x1ec0, 1048577,
-	0x1ec2, 1048577,
-	0x1ec4, 1048577,
-	0x1ec6, 1048577,
-	0x1ec8, 1048577,
-	0x1eca, 1048577,
-	0x1ecc, 1048577,
-	0x1ece, 1048577,
-	0x1ed0, 1048577,
-	0x1ed2, 1048577,
-	0x1ed4, 1048577,
-	0x1ed6, 1048577,
-	0x1ed8, 1048577,
-	0x1eda, 1048577,
-	0x1edc, 1048577,
-	0x1ede, 1048577,
-	0x1ee0, 1048577,
-	0x1ee2, 1048577,
-	0x1ee4, 1048577,
-	0x1ee6, 1048577,
-	0x1ee8, 1048577,
-	0x1eea, 1048577,
-	0x1eec, 1048577,
-	0x1eee, 1048577,
-	0x1ef0, 1048577,
-	0x1ef2, 1048577,
-	0x1ef4, 1048577,
-	0x1ef6, 1048577,
-	0x1ef8, 1048577,
-	0x1efa, 1048577,
-	0x1efc, 1048577,
-	0x1efe, 1048577,
-	0x1f59, 1048568,
-	0x1f5b, 1048568,
-	0x1f5d, 1048568,
-	0x1f5f, 1048568,
-	0x1fbc, 1048567,
-	0x1fcc, 1048567,
-	0x1fec, 1048569,
-	0x1ffc, 1048567,
-	0x2126, 1041059,
-	0x212a, 1040193,
-	0x212b, 1040314,
-	0x2132, 1048604,
-	0x2183, 1048577,
-	0x2c60, 1048577,
-	0x2c62, 1037833,
-	0x2c63, 1044762,
-	0x2c64, 1037849,
-	0x2c67, 1048577,
-	0x2c69, 1048577,
-	0x2c6b, 1048577,
-	0x2c6d, 1037796,
-	0x2c6e, 1037827,
-	0x2c6f, 1037793,
-	0x2c70, 1037794,
-	0x2c72, 1048577,
-	0x2c75, 1048577,
-	0x2c80, 1048577,
-	0x2c82, 1048577,
-	0x2c84, 1048577,
-	0x2c86, 1048577,
-	0x2c88, 1048577,
-	0x2c8a, 1048577,
-	0x2c8c, 1048577,
-	0x2c8e, 1048577,
-	0x2c90, 1048577,
-	0x2c92, 1048577,
-	0x2c94, 1048577,
-	0x2c96, 1048577,
-	0x2c98, 1048577,
-	0x2c9a, 1048577,
-	0x2c9c, 1048577,
-	0x2c9e, 1048577,
-	0x2ca0, 1048577,
-	0x2ca2, 1048577,
-	0x2ca4, 1048577,
-	0x2ca6, 1048577,
-	0x2ca8, 1048577,
-	0x2caa, 1048577,
-	0x2cac, 1048577,
-	0x2cae, 1048577,
-	0x2cb0, 1048577,
-	0x2cb2, 1048577,
-	0x2cb4, 1048577,
-	0x2cb6, 1048577,
-	0x2cb8, 1048577,
-	0x2cba, 1048577,
-	0x2cbc, 1048577,
-	0x2cbe, 1048577,
-	0x2cc0, 1048577,
-	0x2cc2, 1048577,
-	0x2cc4, 1048577,
-	0x2cc6, 1048577,
-	0x2cc8, 1048577,
-	0x2cca, 1048577,
-	0x2ccc, 1048577,
-	0x2cce, 1048577,
-	0x2cd0, 1048577,
-	0x2cd2, 1048577,
-	0x2cd4, 1048577,
-	0x2cd6, 1048577,
-	0x2cd8, 1048577,
-	0x2cda, 1048577,
-	0x2cdc, 1048577,
-	0x2cde, 1048577,
-	0x2ce0, 1048577,
-	0x2ce2, 1048577,
-	0x2ceb, 1048577,
-	0x2ced, 1048577,
-	0x2cf2, 1048577,
-	0xa640, 1048577,
-	0xa642, 1048577,
-	0xa644, 1048577,
-	0xa646, 1048577,
-	0xa648, 1048577,
-	0xa64a, 1048577,
-	0xa64c, 1048577,
-	0xa64e, 1048577,
-	0xa650, 1048577,
-	0xa652, 1048577,
-	0xa654, 1048577,
-	0xa656, 1048577,
-	0xa658, 1048577,
-	0xa65a, 1048577,
-	0xa65c, 1048577,
-	0xa65e, 1048577,
-	0xa660, 1048577,
-	0xa662, 1048577,
-	0xa664, 1048577,
-	0xa666, 1048577,
-	0xa668, 1048577,
-	0xa66a, 1048577,
-	0xa66c, 1048577,
-	0xa680, 1048577,
-	0xa682, 1048577,
-	0xa684, 1048577,
-	0xa686, 1048577,
-	0xa688, 1048577,
-	0xa68a, 1048577,
-	0xa68c, 1048577,
-	0xa68e, 1048577,
-	0xa690, 1048577,
-	0xa692, 1048577,
-	0xa694, 1048577,
-	0xa696, 1048577,
-	0xa698, 1048577,
-	0xa69a, 1048577,
-	0xa722, 1048577,
-	0xa724, 1048577,
-	0xa726, 1048577,
-	0xa728, 1048577,
-	0xa72a, 1048577,
-	0xa72c, 1048577,
-	0xa72e, 1048577,
-	0xa732, 1048577,
-	0xa734, 1048577,
-	0xa736, 1048577,
-	0xa738, 1048577,
-	0xa73a, 1048577,
-	0xa73c, 1048577,
-	0xa73e, 1048577,
-	0xa740, 1048577,
-	0xa742, 1048577,
-	0xa744, 1048577,
-	0xa746, 1048577,
-	0xa748, 1048577,
-	0xa74a, 1048577,
-	0xa74c, 1048577,
-	0xa74e, 1048577,
-	0xa750, 1048577,
-	0xa752, 1048577,
-	0xa754, 1048577,
-	0xa756, 1048577,
-	0xa758, 1048577,
-	0xa75a, 1048577,
-	0xa75c, 1048577,
-	0xa75e, 1048577,
-	0xa760, 1048577,
-	0xa762, 1048577,
-	0xa764, 1048577,
-	0xa766, 1048577,
-	0xa768, 1048577,
-	0xa76a, 1048577,
-	0xa76c, 1048577,
-	0xa76e, 1048577,
-	0xa779, 1048577,
-	0xa77b, 1048577,
-	0xa77d, 1013244,
-	0xa77e, 1048577,
-	0xa780, 1048577,
-	0xa782, 1048577,
-	0xa784, 1048577,
-	0xa786, 1048577,
-	0xa78b, 1048577,
-	0xa78d, 1006296,
-	0xa790, 1048577,
-	0xa792, 1048577,
-	0xa796, 1048577,
-	0xa798, 1048577,
-	0xa79a, 1048577,
-	0xa79c, 1048577,
-	0xa79e, 1048577,
-	0xa7a0, 1048577,
-	0xa7a2, 1048577,
-	0xa7a4, 1048577,
-	0xa7a6, 1048577,
-	0xa7a8, 1048577,
-	0xa7aa, 1006268,
-	0xa7ab, 1006257,
-	0xa7ac, 1006261,
-	0xa7ad, 1006271,
-	0xa7ae, 1006268,
-	0xa7b0, 1006318,
-	0xa7b1, 1006294,
-	0xa7b2, 1006315,
-	0xa7b3, 1049504,
-	0xa7b4, 1048577,
-	0xa7b6, 1048577,
-	0xa7b8, 1048577,
-	0xa7ba, 1048577,
-	0xa7bc, 1048577,
-	0xa7be, 1048577,
-	0xa7c2, 1048577,
-	0xa7c4, 1048528,
-	0xa7c5, 1006269,
-	0xa7c6, 1013192,
-	0xa7c7, 1048577,
-	0xa7c9, 1048577,
-	0xa7f5, 1048577,
+static uint32_t lower1[][2] = {
+	{ 0x00B5, 0x039C },
+	{ 0x00DF, 0x00DF },
+	{ 0x00FF, 0x0178 },
+	{ 0x0131, 0x0049 },
+	{ 0x0138, 0x0138 },
+	{ 0x0149, 0x0149 },
+	{ 0x017F, 0x0053 },
+	{ 0x0180, 0x0243 },
+	{ 0x0188, 0x0187 },
+	{ 0x018C, 0x018B },
+	{ 0x018D, 0x018D },
+	{ 0x0192, 0x0191 },
+	{ 0x0195, 0x01F6 },
+	{ 0x0199, 0x0198 },
+	{ 0x019A, 0x023D },
+	{ 0x019B, 0x019B },
+	{ 0x019E, 0x0220 },
+	{ 0x01A8, 0x01A7 },
+	{ 0x01AD, 0x01AC },
+	{ 0x01B0, 0x01AF },
+	{ 0x01B9, 0x01B8 },
+	{ 0x01BA, 0x01BA },
+	{ 0x01BD, 0x01BC },
+	{ 0x01BE, 0x01BE },
+	{ 0x01BF, 0x01F7 },
+	{ 0x01C6, 0x01C4 },
+	{ 0x01C9, 0x01C7 },
+	{ 0x01CC, 0x01CA },
+	{ 0x01DD, 0x018E },
+	{ 0x01F0, 0x01F0 },
+	{ 0x01F3, 0x01F1 },
+	{ 0x01F5, 0x01F4 },
+	{ 0x0221, 0x0221 },
+	{ 0x023C, 0x023B },
+	{ 0x0242, 0x0241 },
+	{ 0x0250, 0x2C6F },
+	{ 0x0251, 0x2C6D },
+	{ 0x0252, 0x2C70 },
+	{ 0x0253, 0x0181 },
+	{ 0x0254, 0x0186 },
+	{ 0x0255, 0x0255 },
+	{ 0x0258, 0x0258 },
+	{ 0x0259, 0x018F },
+	{ 0x025A, 0x025A },
+	{ 0x025B, 0x0190 },
+	{ 0x025C, 0xA7AB },
+	{ 0x0260, 0x0193 },
+	{ 0x0261, 0xA7AC },
+	{ 0x0262, 0x0262 },
+	{ 0x0263, 0x0194 },
+	{ 0x0264, 0x0264 },
+	{ 0x0265, 0xA78D },
+	{ 0x0266, 0xA7AA },
+	{ 0x0267, 0x0267 },
+	{ 0x0268, 0x0197 },
+	{ 0x0269, 0x0196 },
+	{ 0x026A, 0xA7AE },
+	{ 0x026B, 0x2C62 },
+	{ 0x026C, 0xA7AD },
+	{ 0x026F, 0x019C },
+	{ 0x0270, 0x0270 },
+	{ 0x0271, 0x2C6E },
+	{ 0x0272, 0x019D },
+	{ 0x0275, 0x019F },
+	{ 0x027D, 0x2C64 },
+	{ 0x0280, 0x01A6 },
+	{ 0x0281, 0x0281 },
+	{ 0x0282, 0xA7C5 },
+	{ 0x0283, 0x01A9 },
+	{ 0x0287, 0xA7B1 },
+	{ 0x0288, 0x01AE },
+	{ 0x0289, 0x0244 },
+	{ 0x028C, 0x0245 },
+	{ 0x0292, 0x01B7 },
+	{ 0x0293, 0x0293 },
+	{ 0x029D, 0xA7B2 },
+	{ 0x029E, 0xA7B0 },
+	{ 0x0377, 0x0376 },
+	{ 0x0390, 0x0390 },
+	{ 0x03AC, 0x0386 },
+	{ 0x03B0, 0x03B0 },
+	{ 0x03C2, 0x03A3 },
+	{ 0x03CC, 0x038C },
+	{ 0x03D0, 0x0392 },
+	{ 0x03D1, 0x0398 },
+	{ 0x03D5, 0x03A6 },
+	{ 0x03D6, 0x03A0 },
+	{ 0x03D7, 0x03CF },
+	{ 0x03F0, 0x039A },
+	{ 0x03F1, 0x03A1 },
+	{ 0x03F2, 0x03F9 },
+	{ 0x03F3, 0x037F },
+	{ 0x03F5, 0x0395 },
+	{ 0x03F8, 0x03F7 },
+	{ 0x03FB, 0x03FA },
+	{ 0x03FC, 0x03FC },
+	{ 0x04CF, 0x04C0 },
+	{ 0x0560, 0x0560 },
+	{ 0x1C80, 0x0412 },
+	{ 0x1C81, 0x0414 },
+	{ 0x1C82, 0x041E },
+	{ 0x1C85, 0x0422 },
+	{ 0x1C86, 0x042A },
+	{ 0x1C87, 0x0462 },
+	{ 0x1C88, 0xA64A },
+	{ 0x1D79, 0xA77D },
+	{ 0x1D7D, 0x2C63 },
+	{ 0x1D8E, 0xA7C6 },
+	{ 0x1E9B, 0x1E60 },
+	{ 0x1E9F, 0x1E9F },
+	{ 0x1F50, 0x1F50 },
+	{ 0x1F51, 0x1F59 },
+	{ 0x1F52, 0x1F52 },
+	{ 0x1F53, 0x1F5B },
+	{ 0x1F54, 0x1F54 },
+	{ 0x1F55, 0x1F5D },
+	{ 0x1F56, 0x1F56 },
+	{ 0x1F57, 0x1F5F },
+	{ 0x1FB2, 0x1FB2 },
+	{ 0x1FB3, 0x1FBC },
+	{ 0x1FB4, 0x1FB4 },
+	{ 0x1FBE, 0x0399 },
+	{ 0x1FC2, 0x1FC2 },
+	{ 0x1FC3, 0x1FCC },
+	{ 0x1FC4, 0x1FC4 },
+	{ 0x1FE5, 0x1FEC },
+	{ 0x1FF2, 0x1FF2 },
+	{ 0x1FF3, 0x1FFC },
+	{ 0x1FF4, 0x1FF4 },
+	{ 0x210A, 0x210A },
+	{ 0x2113, 0x2113 },
+	{ 0x212F, 0x212F },
+	{ 0x2134, 0x2134 },
+	{ 0x2139, 0x2139 },
+	{ 0x214E, 0x2132 },
+	{ 0x2184, 0x2183 },
+	{ 0x2C61, 0x2C60 },
+	{ 0x2C65, 0x023A },
+	{ 0x2C66, 0x023E },
+	{ 0x2C71, 0x2C71 },
+	{ 0x2C73, 0x2C72 },
+	{ 0x2C74, 0x2C74 },
+	{ 0x2C76, 0x2C75 },
+	{ 0x2CE4, 0x2CE4 },
+	{ 0x2CF3, 0x2CF2 },
+	{ 0x2D27, 0x10C7 },
+	{ 0x2D2D, 0x10CD },
+	{ 0xA78C, 0xA78B },
+	{ 0xA78E, 0xA78E },
+	{ 0xA794, 0xA7C4 },
+	{ 0xA795, 0xA795 },
+	{ 0xA7AF, 0xA7AF },
+	{ 0xA7D1, 0xA7D0 },
+	{ 0xA7D3, 0xA7D3 },
+	{ 0xA7D5, 0xA7D5 },
+	{ 0xA7F6, 0xA7F5 },
+	{ 0xA7FA, 0xA7FA },
+	{ 0xAB53, 0xA7B3 },
+	{ 0x1D4BB, 0x1D4BB },
+	{ 0x1D7CB, 0x1D7CB },
 };
 
-uint32_t
-uni_tolower(uint32_t c)
+int
+uni_islower(uint32_t r)
 {
-	const uint32_t *p;
-
-	p = search(c, tolowerr, nelem (tolowerr) / 3, 3);
+	const uint32_t *match;
 
-	if (p && c >= p[0] && c <= p[1])
-		return c + p[2] - 1048576;
-
-	p = search(c, tolowers, nelem (tolowers) / 2, 2);
+	if ((match = bsearch(&r, lower4, nelem(lower4), sizeof *lower4, &cmp2)))
+		return !((r - match[0]) % 2);
+	if (bsearch(&r, lower2, nelem(lower2), sizeof *lower2, &cmp2))
+		return 1;
+	if (bsearch(&r, lower1, nelem(lower1), sizeof *lower1, &cmp1))
+		return 1;
 
-	if (p && c == p[0])
-		return c + p[1] - 1048576;
-
-	return c;
+	return 0;
 }
 
-static const uint32_t totitler[] = {
-	0x0061, 0x007a, 1048544,
-	0x00e0, 0x00f6, 1048544,
-	0x00f8, 0x00fe, 1048544,
-	0x023f, 0x0240, 1059391,
-	0x0256, 0x0257, 1048371,
-	0x028a, 0x028b, 1048359,
-	0x037b, 0x037d, 1048706,
-	0x03ad, 0x03af, 1048539,
-	0x03b1, 0x03c1, 1048544,
-	0x03c3, 0x03cb, 1048544,
-	0x03cd, 0x03ce, 1048513,
-	0x0430, 0x044f, 1048544,
-	0x0450, 0x045f, 1048496,
-	0x0561, 0x0586, 1048528,
-	0x13f8, 0x13fd, 1048568,
-	0x1c83, 0x1c84, 1042334,
-	0x1f00, 0x1f07, 1048584,
-	0x1f10, 0x1f15, 1048584,
-	0x1f20, 0x1f27, 1048584,
-	0x1f30, 0x1f37, 1048584,
-	0x1f40, 0x1f45, 1048584,
-	0x1f60, 0x1f67, 1048584,
-	0x1f70, 0x1f71, 1048650,
-	0x1f72, 0x1f75, 1048662,
-	0x1f76, 0x1f77, 1048676,
-	0x1f78, 0x1f79, 1048704,
-	0x1f7a, 0x1f7b, 1048688,
-	0x1f7c, 0x1f7d, 1048702,
-	0x1f80, 0x1f87, 1048584,
-	0x1f90, 0x1f97, 1048584,
-	0x1fa0, 0x1fa7, 1048584,
-	0x1fb0, 0x1fb1, 1048584,
-	0x1fd0, 0x1fd1, 1048584,
-	0x1fe0, 0x1fe1, 1048584,
-	0x2170, 0x217f, 1048560,
-	0x24d0, 0x24e9, 1048550,
-	0x2c30, 0x2c5e, 1048528,
-	0x2d00, 0x2d25, 1041312,
-	0xab70, 0xabbf, 1009712,
-	0xff41, 0xff5a, 1048544,
-	0x10428, 0x1044f, 1048536,
-	0x104d8, 0x104fb, 1048536,
-	0x10cc0, 0x10cf2, 1048512,
-	0x118c0, 0x118df, 1048544,
-	0x16e60, 0x16e7f, 1048544,
-	0x1e922, 0x1e943, 1048542,
+
+uint32_t
+uni_toupper(uint32_t r)
+{
+	uint32_t *match;
+
+	match = bsearch(&r, lower4, nelem(lower4), sizeof *lower4, &cmp2);
+	if (match)
+		return ((r - match[0]) % 2) ? r : r - 1;
+	match = bsearch(&r, lower2, nelem(lower2), sizeof *lower2, &cmp2);
+	if (match)
+		return match[2] + (r - match[0]);
+	match = bsearch(&r, lower1, nelem(lower1), sizeof *lower1, &cmp1);
+	if (match)
+		return match[1];
+	return r;
+}
+static uint32_t title2[][2] = {
+	{ 0x1F88, 0x1F8F },
+	{ 0x1F98, 0x1F9F },
+	{ 0x1FA8, 0x1FAF },
+};
+
+static uint32_t title1[] = {
+	0x01C5,
+	0x01C8,
+	0x01CB,
+	0x01F2,
+	0x1FBC,
+	0x1FCC,
+	0x1FFC,
 };
 
-static const uint32_t totitles[] = {
-	0x00b5, 1049319,
-	0x00ff, 1048697,
-	0x0101, 1048575,
-	0x0103, 1048575,
-	0x0105, 1048575,
-	0x0107, 1048575,
-	0x0109, 1048575,
-	0x010b, 1048575,
-	0x010d, 1048575,
-	0x010f, 1048575,
-	0x0111, 1048575,
-	0x0113, 1048575,
-	0x0115, 1048575,
-	0x0117, 1048575,
-	0x0119, 1048575,
-	0x011b, 1048575,
-	0x011d, 1048575,
-	0x011f, 1048575,
-	0x0121, 1048575,
-	0x0123, 1048575,
-	0x0125, 1048575,
-	0x0127, 1048575,
-	0x0129, 1048575,
-	0x012b, 1048575,
-	0x012d, 1048575,
-	0x012f, 1048575,
-	0x0131, 1048344,
-	0x0133, 1048575,
-	0x0135, 1048575,
-	0x0137, 1048575,
-	0x013a, 1048575,
-	0x013c, 1048575,
-	0x013e, 1048575,
-	0x0140, 1048575,
-	0x0142, 1048575,
-	0x0144, 1048575,
-	0x0146, 1048575,
-	0x0148, 1048575,
-	0x014b, 1048575,
-	0x014d, 1048575,
-	0x014f, 1048575,
-	0x0151, 1048575,
-	0x0153, 1048575,
-	0x0155, 1048575,
-	0x0157, 1048575,
-	0x0159, 1048575,
-	0x015b, 1048575,
-	0x015d, 1048575,
-	0x015f, 1048575,
-	0x0161, 1048575,
-	0x0163, 1048575,
-	0x0165, 1048575,
-	0x0167, 1048575,
-	0x0169, 1048575,
-	0x016b, 1048575,
-	0x016d, 1048575,
-	0x016f, 1048575,
-	0x0171, 1048575,
-	0x0173, 1048575,
-	0x0175, 1048575,
-	0x0177, 1048575,
-	0x017a, 1048575,
-	0x017c, 1048575,
-	0x017e, 1048575,
-	0x017f, 1048276,
-	0x0180, 1048771,
-	0x0183, 1048575,
-	0x0185, 1048575,
-	0x0188, 1048575,
-	0x018c, 1048575,
-	0x0192, 1048575,
-	0x0195, 1048673,
-	0x0199, 1048575,
-	0x019a, 1048739,
-	0x019e, 1048706,
-	0x01a1, 1048575,
-	0x01a3, 1048575,
-	0x01a5, 1048575,
-	0x01a8, 1048575,
-	0x01ad, 1048575,
-	0x01b0, 1048575,
-	0x01b4, 1048575,
-	0x01b6, 1048575,
-	0x01b9, 1048575,
-	0x01bd, 1048575,
-	0x01bf, 1048632,
-	0x01c4, 1048577,
-	0x01c6, 1048575,
-	0x01c7, 1048577,
-	0x01c9, 1048575,
-	0x01ca, 1048577,
-	0x01cc, 1048575,
-	0x01ce, 1048575,
-	0x01d0, 1048575,
-	0x01d2, 1048575,
-	0x01d4, 1048575,
-	0x01d6, 1048575,
-	0x01d8, 1048575,
-	0x01da, 1048575,
-	0x01dc, 1048575,
-	0x01dd, 1048497,
-	0x01df, 1048575,
-	0x01e1, 1048575,
-	0x01e3, 1048575,
-	0x01e5, 1048575,
-	0x01e7, 1048575,
-	0x01e9, 1048575,
-	0x01eb, 1048575,
-	0x01ed, 1048575,
-	0x01ef, 1048575,
-	0x01f1, 1048577,
-	0x01f3, 1048575,
-	0x01f5, 1048575,
-	0x01f9, 1048575,
-	0x01fb, 1048575,
-	0x01fd, 1048575,
-	0x01ff, 1048575,
-	0x0201, 1048575,
-	0x0203, 1048575,
-	0x0205, 1048575,
-	0x0207, 1048575,
-	0x0209, 1048575,
-	0x020b, 1048575,
-	0x020d, 1048575,
-	0x020f, 1048575,
-	0x0211, 1048575,
-	0x0213, 1048575,
-	0x0215, 1048575,
-	0x0217, 1048575,
-	0x0219, 1048575,
-	0x021b, 1048575,
-	0x021d, 1048575,
-	0x021f, 1048575,
-	0x0223, 1048575,
-	0x0225, 1048575,
-	0x0227, 1048575,
-	0x0229, 1048575,
-	0x022b, 1048575,
-	0x022d, 1048575,
-	0x022f, 1048575,
-	0x0231, 1048575,
-	0x0233, 1048575,
-	0x023c, 1048575,
-	0x0242, 1048575,
-	0x0247, 1048575,
-	0x0249, 1048575,
-	0x024b, 1048575,
-	0x024d, 1048575,
-	0x024f, 1048575,
-	0x0250, 1059359,
-	0x0251, 1059356,
-	0x0252, 1059358,
-	0x0253, 1048366,
-	0x0254, 1048370,
-	0x0259, 1048374,
-	0x025b, 1048373,
-	0x025c, 1090895,
-	0x0260, 1048371,
-	0x0261, 1090891,
-	0x0263, 1048369,
-	0x0265, 1090856,
-	0x0266, 1090884,
-	0x0268, 1048367,
-	0x0269, 1048365,
-	0x026a, 1090884,
-	0x026b, 1059319,
-	0x026c, 1090881,
-	0x026f, 1048365,
-	0x0271, 1059325,
-	0x0272, 1048363,
-	0x0275, 1048362,
-	0x027d, 1059303,
-	0x0280, 1048358,
-	0x0282, 1090883,
-	0x0283, 1048358,
-	0x0287, 1090858,
-	0x0288, 1048358,
-	0x0289, 1048507,
-	0x028c, 1048505,
-	0x0292, 1048357,
-	0x029d, 1090837,
-	0x029e, 1090834,
-	0x0345, 1048660,
-	0x0371, 1048575,
-	0x0373, 1048575,
-	0x0377, 1048575,
-	0x03ac, 1048538,
-	0x03c2, 1048545,
-	0x03cc, 1048512,
-	0x03d0, 1048514,
-	0x03d1, 1048519,
-	0x03d5, 1048529,
-	0x03d6, 1048522,
-	0x03d7, 1048568,
-	0x03d9, 1048575,
-	0x03db, 1048575,
-	0x03dd, 1048575,
-	0x03df, 1048575,
-	0x03e1, 1048575,
-	0x03e3, 1048575,
-	0x03e5, 1048575,
-	0x03e7, 1048575,
-	0x03e9, 1048575,
-	0x03eb, 1048575,
-	0x03ed, 1048575,
-	0x03ef, 1048575,
-	0x03f0, 1048490,
-	0x03f1, 1048496,
-	0x03f2, 1048583,
-	0x03f3, 1048460,
-	0x03f5, 1048480,
-	0x03f8, 1048575,
-	0x03fb, 1048575,
-	0x0461, 1048575,
-	0x0463, 1048575,
-	0x0465, 1048575,
-	0x0467, 1048575,
-	0x0469, 1048575,
-	0x046b, 1048575,
-	0x046d, 1048575,
-	0x046f, 1048575,
-	0x0471, 1048575,
-	0x0473, 1048575,
-	0x0475, 1048575,
-	0x0477, 1048575,
-	0x0479, 1048575,
-	0x047b, 1048575,
-	0x047d, 1048575,
-	0x047f, 1048575,
-	0x0481, 1048575,
-	0x048b, 1048575,
-	0x048d, 1048575,
-	0x048f, 1048575,
-	0x0491, 1048575,
-	0x0493, 1048575,
-	0x0495, 1048575,
-	0x0497, 1048575,
-	0x0499, 1048575,
-	0x049b, 1048575,
-	0x049d, 1048575,
-	0x049f, 1048575,
-	0x04a1, 1048575,
-	0x04a3, 1048575,
-	0x04a5, 1048575,
-	0x04a7, 1048575,
-	0x04a9, 1048575,
-	0x04ab, 1048575,
-	0x04ad, 1048575,
-	0x04af, 1048575,
-	0x04b1, 1048575,
-	0x04b3, 1048575,
-	0x04b5, 1048575,
-	0x04b7, 1048575,
-	0x04b9, 1048575,
-	0x04bb, 1048575,
-	0x04bd, 1048575,
-	0x04bf, 1048575,
-	0x04c2, 1048575,
-	0x04c4, 1048575,
-	0x04c6, 1048575,
-	0x04c8, 1048575,
-	0x04ca, 1048575,
-	0x04cc, 1048575,
-	0x04ce, 1048575,
-	0x04cf, 1048561,
-	0x04d1, 1048575,
-	0x04d3, 1048575,
-	0x04d5, 1048575,
-	0x04d7, 1048575,
-	0x04d9, 1048575,
-	0x04db, 1048575,
-	0x04dd, 1048575,
-	0x04df, 1048575,
-	0x04e1, 1048575,
-	0x04e3, 1048575,
-	0x04e5, 1048575,
-	0x04e7, 1048575,
-	0x04e9, 1048575,
-	0x04eb, 1048575,
-	0x04ed, 1048575,
-	0x04ef, 1048575,
-	0x04f1, 1048575,
-	0x04f3, 1048575,
-	0x04f5, 1048575,
-	0x04f7, 1048575,
-	0x04f9, 1048575,
-	0x04fb, 1048575,
-	0x04fd, 1048575,
-	0x04ff, 1048575,
-	0x0501, 1048575,
-	0x0503, 1048575,
-	0x0505, 1048575,
-	0x0507, 1048575,
-	0x0509, 1048575,
-	0x050b, 1048575,
-	0x050d, 1048575,
-	0x050f, 1048575,
-	0x0511, 1048575,
-	0x0513, 1048575,
-	0x0515, 1048575,
-	0x0517, 1048575,
-	0x0519, 1048575,
-	0x051b, 1048575,
-	0x051d, 1048575,
-	0x051f, 1048575,
-	0x0521, 1048575,
-	0x0523, 1048575,
-	0x0525, 1048575,
-	0x0527, 1048575,
-	0x0529, 1048575,
-	0x052b, 1048575,
-	0x052d, 1048575,
-	0x052f, 1048575,
-	0x1c80, 1042322,
-	0x1c81, 1042323,
-	0x1c82, 1042332,
-	0x1c85, 1042333,
-	0x1c86, 1042340,
-	0x1c87, 1042395,
-	0x1c88, 1083842,
-	0x1d79, 1083908,
-	0x1d7d, 1052390,
-	0x1d8e, 1083960,
-	0x1e01, 1048575,
-	0x1e03, 1048575,
-	0x1e05, 1048575,
-	0x1e07, 1048575,
-	0x1e09, 1048575,
-	0x1e0b, 1048575,
-	0x1e0d, 1048575,
-	0x1e0f, 1048575,
-	0x1e11, 1048575,
-	0x1e13, 1048575,
-	0x1e15, 1048575,
-	0x1e17, 1048575,
-	0x1e19, 1048575,
-	0x1e1b, 1048575,
-	0x1e1d, 1048575,
-	0x1e1f, 1048575,
-	0x1e21, 1048575,
-	0x1e23, 1048575,
-	0x1e25, 1048575,
-	0x1e27, 1048575,
-	0x1e29, 1048575,
-	0x1e2b, 1048575,
-	0x1e2d, 1048575,
-	0x1e2f, 1048575,
-	0x1e31, 1048575,
-	0x1e33, 1048575,
-	0x1e35, 1048575,
-	0x1e37, 1048575,
-	0x1e39, 1048575,
-	0x1e3b, 1048575,
-	0x1e3d, 1048575,
-	0x1e3f, 1048575,
-	0x1e41, 1048575,
-	0x1e43, 1048575,
-	0x1e45, 1048575,
-	0x1e47, 1048575,
-	0x1e49, 1048575,
-	0x1e4b, 1048575,
-	0x1e4d, 1048575,
-	0x1e4f, 1048575,
-	0x1e51, 1048575,
-	0x1e53, 1048575,
-	0x1e55, 1048575,
-	0x1e57, 1048575,
-	0x1e59, 1048575,
-	0x1e5b, 1048575,
-	0x1e5d, 1048575,
-	0x1e5f, 1048575,
-	0x1e61, 1048575,
-	0x1e63, 1048575,
-	0x1e65, 1048575,
-	0x1e67, 1048575,
-	0x1e69, 1048575,
-	0x1e6b, 1048575,
-	0x1e6d, 1048575,
-	0x1e6f, 1048575,
-	0x1e71, 1048575,
-	0x1e73, 1048575,
-	0x1e75, 1048575,
-	0x1e77, 1048575,
-	0x1e79, 1048575,
-	0x1e7b, 1048575,
-	0x1e7d, 1048575,
-	0x1e7f, 1048575,
-	0x1e81, 1048575,
-	0x1e83, 1048575,
-	0x1e85, 1048575,
-	0x1e87, 1048575,
-	0x1e89, 1048575,
-	0x1e8b, 1048575,
-	0x1e8d, 1048575,
-	0x1e8f, 1048575,
-	0x1e91, 1048575,
-	0x1e93, 1048575,
-	0x1e95, 1048575,
-	0x1e9b, 1048517,
-	0x1ea1, 1048575,
-	0x1ea3, 1048575,
-	0x1ea5, 1048575,
-	0x1ea7, 1048575,
-	0x1ea9, 1048575,
-	0x1eab, 1048575,
-	0x1ead, 1048575,
-	0x1eaf, 1048575,
-	0x1eb1, 1048575,
-	0x1eb3, 1048575,
-	0x1eb5, 1048575,
-	0x1eb7, 1048575,
-	0x1eb9, 1048575,
-	0x1ebb, 1048575,
-	0x1ebd, 1048575,
-	0x1ebf, 1048575,
-	0x1ec1, 1048575,
-	0x1ec3, 1048575,
-	0x1ec5, 1048575,
-	0x1ec7, 1048575,
-	0x1ec9, 1048575,
-	0x1ecb, 1048575,
-	0x1ecd, 1048575,
-	0x1ecf, 1048575,
-	0x1ed1, 1048575,
-	0x1ed3, 1048575,
-	0x1ed5, 1048575,
-	0x1ed7, 1048575,
-	0x1ed9, 1048575,
-	0x1edb, 1048575,
-	0x1edd, 1048575,
-	0x1edf, 1048575,
-	0x1ee1, 1048575,
-	0x1ee3, 1048575,
-	0x1ee5, 1048575,
-	0x1ee7, 1048575,
-	0x1ee9, 1048575,
-	0x1eeb, 1048575,
-	0x1eed, 1048575,
-	0x1eef, 1048575,
-	0x1ef1, 1048575,
-	0x1ef3, 1048575,
-	0x1ef5, 1048575,
-	0x1ef7, 1048575,
-	0x1ef9, 1048575,
-	0x1efb, 1048575,
-	0x1efd, 1048575,
-	0x1eff, 1048575,
-	0x1f51, 1048584,
-	0x1f53, 1048584,
-	0x1f55, 1048584,
-	0x1f57, 1048584,
-	0x1fb3, 1048585,
-	0x1fbe, 1041371,
-	0x1fc3, 1048585,
-	0x1fe5, 1048583,
-	0x1ff3, 1048585,
-	0x214e, 1048548,
-	0x2184, 1048575,
-	0x2c61, 1048575,
-	0x2c65, 1037781,
-	0x2c66, 1037784,
-	0x2c68, 1048575,
-	0x2c6a, 1048575,
-	0x2c6c, 1048575,
-	0x2c73, 1048575,
-	0x2c76, 1048575,
-	0x2c81, 1048575,
-	0x2c83, 1048575,
-	0x2c85, 1048575,
-	0x2c87, 1048575,
-	0x2c89, 1048575,
-	0x2c8b, 1048575,
-	0x2c8d, 1048575,
-	0x2c8f, 1048575,
-	0x2c91, 1048575,
-	0x2c93, 1048575,
-	0x2c95, 1048575,
-	0x2c97, 1048575,
-	0x2c99, 1048575,
-	0x2c9b, 1048575,
-	0x2c9d, 1048575,
-	0x2c9f, 1048575,
-	0x2ca1, 1048575,
-	0x2ca3, 1048575,
-	0x2ca5, 1048575,
-	0x2ca7, 1048575,
-	0x2ca9, 1048575,
-	0x2cab, 1048575,
-	0x2cad, 1048575,
-	0x2caf, 1048575,
-	0x2cb1, 1048575,
-	0x2cb3, 1048575,
-	0x2cb5, 1048575,
-	0x2cb7, 1048575,
-	0x2cb9, 1048575,
-	0x2cbb, 1048575,
-	0x2cbd, 1048575,
-	0x2cbf, 1048575,
-	0x2cc1, 1048575,
-	0x2cc3, 1048575,
-	0x2cc5, 1048575,
-	0x2cc7, 1048575,
-	0x2cc9, 1048575,
-	0x2ccb, 1048575,
-	0x2ccd, 1048575,
-	0x2ccf, 1048575,
-	0x2cd1, 1048575,
-	0x2cd3, 1048575,
-	0x2cd5, 1048575,
-	0x2cd7, 1048575,
-	0x2cd9, 1048575,
-	0x2cdb, 1048575,
-	0x2cdd, 1048575,
-	0x2cdf, 1048575,
-	0x2ce1, 1048575,
-	0x2ce3, 1048575,
-	0x2cec, 1048575,
-	0x2cee, 1048575,
-	0x2cf3, 1048575,
-	0x2d27, 1041312,
-	0x2d2d, 1041312,
-	0xa641, 1048575,
-	0xa643, 1048575,
-	0xa645, 1048575,
-	0xa647, 1048575,
-	0xa649, 1048575,
-	0xa64b, 1048575,
-	0xa64d, 1048575,
-	0xa64f, 1048575,
-	0xa651, 1048575,
-	0xa653, 1048575,
-	0xa655, 1048575,
-	0xa657, 1048575,
-	0xa659, 1048575,
-	0xa65b, 1048575,
-	0xa65d, 1048575,
-	0xa65f, 1048575,
-	0xa661, 1048575,
-	0xa663, 1048575,
-	0xa665, 1048575,
-	0xa667, 1048575,
-	0xa669, 1048575,
-	0xa66b, 1048575,
-	0xa66d, 1048575,
-	0xa681, 1048575,
-	0xa683, 1048575,
-	0xa685, 1048575,
-	0xa687, 1048575,
-	0xa689, 1048575,
-	0xa68b, 1048575,
-	0xa68d, 1048575,
-	0xa68f, 1048575,
-	0xa691, 1048575,
-	0xa693, 1048575,
-	0xa695, 1048575,
-	0xa697, 1048575,
-	0xa699, 1048575,
-	0xa69b, 1048575,
-	0xa723, 1048575,
-	0xa725, 1048575,
-	0xa727, 1048575,
-	0xa729, 1048575,
-	0xa72b, 1048575,
-	0xa72d, 1048575,
-	0xa72f, 1048575,
-	0xa733, 1048575,
-	0xa735, 1048575,
-	0xa737, 1048575,
-	0xa739, 1048575,
-	0xa73b, 1048575,
-	0xa73d, 1048575,
-	0xa73f, 1048575,
-	0xa741, 1048575,
-	0xa743, 1048575,
-	0xa745, 1048575,
-	0xa747, 1048575,
-	0xa749, 1048575,
-	0xa74b, 1048575,
-	0xa74d, 1048575,
-	0xa74f, 1048575,
-	0xa751, 1048575,
-	0xa753, 1048575,
-	0xa755, 1048575,
-	0xa757, 1048575,
-	0xa759, 1048575,
-	0xa75b, 1048575,
-	0xa75d, 1048575,
-	0xa75f, 1048575,
-	0xa761, 1048575,
-	0xa763, 1048575,
-	0xa765, 1048575,
-	0xa767, 1048575,
-	0xa769, 1048575,
-	0xa76b, 1048575,
-	0xa76d, 1048575,
-	0xa76f, 1048575,
-	0xa77a, 1048575,
-	0xa77c, 1048575,
-	0xa77f, 1048575,
-	0xa781, 1048575,
-	0xa783, 1048575,
-	0xa785, 1048575,
-	0xa787, 1048575,
-	0xa78c, 1048575,
-	0xa791, 1048575,
-	0xa793, 1048575,
-	0xa794, 1048624,
-	0xa797, 1048575,
-	0xa799, 1048575,
-	0xa79b, 1048575,
-	0xa79d, 1048575,
-	0xa79f, 1048575,
-	0xa7a1, 1048575,
-	0xa7a3, 1048575,
-	0xa7a5, 1048575,
-	0xa7a7, 1048575,
-	0xa7a9, 1048575,
-	0xa7b5, 1048575,
-	0xa7b7, 1048575,
-	0xa7b9, 1048575,
-	0xa7bb, 1048575,
-	0xa7bd, 1048575,
-	0xa7bf, 1048575,
-	0xa7c3, 1048575,
-	0xa7c8, 1048575,
-	0xa7ca, 1048575,
-	0xa7f6, 1048575,
-	0xab53, 1047648,
+int
+uni_istitle(uint32_t r)
+{
+	if (bsearch(&r, title2, nelem(title2), sizeof *title2, &cmp2))
+		return 1;
+	if (bsearch(&r, title1, nelem(title1), sizeof *title1, &cmp1))
+		return 1;
+
+	return 0;
+}
+
+static uint32_t digit2[][2] = {
+	{ 0x0030, 0x0039 },
+	{ 0x0660, 0x0669 },
+	{ 0x06F0, 0x06F9 },
+	{ 0x07C0, 0x07C9 },
+	{ 0x0966, 0x096F },
+	{ 0x09E6, 0x09EF },
+	{ 0x0A66, 0x0A6F },
+	{ 0x0AE6, 0x0AEF },
+	{ 0x0B66, 0x0B6F },
+	{ 0x0BE6, 0x0BEF },
+	{ 0x0C66, 0x0C6F },
+	{ 0x0CE6, 0x0CEF },
+	{ 0x0D66, 0x0D6F },
+	{ 0x0DE6, 0x0DEF },
+	{ 0x0E50, 0x0E59 },
+	{ 0x0ED0, 0x0ED9 },
+	{ 0x0F20, 0x0F29 },
+	{ 0x1040, 0x1049 },
+	{ 0x1090, 0x1099 },
+	{ 0x17E0, 0x17E9 },
+	{ 0x1810, 0x1819 },
+	{ 0x1946, 0x194F },
+	{ 0x19D0, 0x19D9 },
+	{ 0x1A80, 0x1A89 },
+	{ 0x1A90, 0x1A99 },
+	{ 0x1B50, 0x1B59 },
+	{ 0x1BB0, 0x1BB9 },
+	{ 0x1C40, 0x1C49 },
+	{ 0x1C50, 0x1C59 },
+	{ 0xA620, 0xA629 },
+	{ 0xA8D0, 0xA8D9 },
+	{ 0xA900, 0xA909 },
+	{ 0xA9D0, 0xA9D9 },
+	{ 0xA9F0, 0xA9F9 },
+	{ 0xAA50, 0xAA59 },
+	{ 0xABF0, 0xABF9 },
+	{ 0xFF10, 0xFF19 },
+	{ 0x104A0, 0x104A9 },
+	{ 0x10D30, 0x10D39 },
+	{ 0x11066, 0x1106F },
+	{ 0x110F0, 0x110F9 },
+	{ 0x11136, 0x1113F },
+	{ 0x111D0, 0x111D9 },
+	{ 0x112F0, 0x112F9 },
+	{ 0x11450, 0x11459 },
+	{ 0x114D0, 0x114D9 },
+	{ 0x11650, 0x11659 },
+	{ 0x116C0, 0x116C9 },
+	{ 0x11730, 0x11739 },
+	{ 0x118E0, 0x118E9 },
+	{ 0x11950, 0x11959 },
+	{ 0x11C50, 0x11C59 },
+	{ 0x11D50, 0x11D59 },
+	{ 0x11DA0, 0x11DA9 },
+	{ 0x16A60, 0x16A69 },
+	{ 0x16AC0, 0x16AC9 },
+	{ 0x16B50, 0x16B59 },
+	{ 0x1D7CE, 0x1D7FF },
+	{ 0x1E140, 0x1E149 },
+	{ 0x1E2F0, 0x1E2F9 },
+	{ 0x1E950, 0x1E959 },
+	{ 0x1FBF0, 0x1FBF9 },
 };
 
-uint32_t
-uni_totitle(uint32_t c)
+int
+uni_isdigit(uint32_t r)
 {
-	const uint32_t *p;
-
-	p = search(c, totitler, nelem (totitler) / 3, 3);
+	if (bsearch(&r, digit2, nelem(digit2), sizeof *digit2, &cmp2))
+		return 1;
 
-	if (p && c >= p[0] && c <= p[1])
-		return c + p[2] - 1048576;
-
-	p = search(c, totitles, nelem (totitles) / 2, 2);
-
-	if (p && c == p[0])
-		return c + p[1] - 1048576;
-
-	return c;
+	return 0;
 }
 
 size_t
--- a/unicode.h	Sun Jan 02 10:21:47 2022 +0100
+++ b/unicode.h	Mon Mar 21 09:00:42 2022 +0100
@@ -53,6 +53,9 @@
 uni_isalpha(uint32_t c);
 
 int
+uni_iscontrol(uint32_t c);
+
+int
 uni_isdigit(uint32_t c);
 
 int