Import Cobalt 21.master.0.300910
diff --git a/src/third_party/icu/source/common/Makefile.in b/src/third_party/icu/source/common/Makefile.in
index b187af6..67bcf00 100644
--- a/src/third_party/icu/source/common/Makefile.in
+++ b/src/third_party/icu/source/common/Makefile.in
@@ -1,6 +1,8 @@
+# Copyright (C) 2016 and later: Unicode, Inc. and others.
+# License & terms of use: http://www.unicode.org/copyright.html
 #******************************************************************************
 #
-#   Copyright (C) 1999-2015, International Business Machines
+#   Copyright (C) 1999-2016, International Business Machines
 #   Corporation and others.  All Rights Reserved.
 #
 #******************************************************************************
@@ -77,36 +79,8 @@
 # $(LIBICUDT) is either stub data or the real DLL common data.
 LIBS = $(LIBICUDT) $(DEFAULT_LIBS)
 
-OBJECTS = errorcode.o putil.o umath.o utypes.o uinvchar.o umutex.o ucln_cmn.o \
-uinit.o uobject.o cmemory.o charstr.o \
-udata.o ucmndata.o udatamem.o umapfile.o udataswp.o ucol_swp.o utrace.o \
-uhash.o uhash_us.o uenum.o ustrenum.o uvector.o ustack.o uvectr32.o uvectr64.o \
-ucnv.o ucnv_bld.o ucnv_cnv.o ucnv_io.o ucnv_cb.o ucnv_err.o ucnvlat1.o \
-ucnv_u7.o ucnv_u8.o ucnv_u16.o ucnv_u32.o ucnvscsu.o ucnvbocu.o \
-ucnv_ext.o ucnvmbcs.o ucnv2022.o ucnvhz.o ucnv_lmb.o ucnvisci.o ucnvdisp.o ucnv_set.o ucnv_ct.o \
-resource.o uresbund.o ures_cnv.o uresdata.o resbund.o resbund_cnv.o \
-messagepattern.o ucat.o locmap.o uloc.o locid.o locutil.o locavailable.o locdispnames.o loclikely.o locresdata.o \
-bytestream.o stringpiece.o \
-stringtriebuilder.o bytestriebuilder.o \
-bytestrie.o bytestrieiterator.o \
-ucharstrie.o ucharstriebuilder.o ucharstrieiterator.o \
-dictionarydata.o \
-appendable.o ustr_cnv.o unistr_cnv.o unistr.o unistr_case.o unistr_props.o \
-utf_impl.o ustring.o ustrcase.o ucasemap.o ucasemap_titlecase_brkiter.o cstring.o ustrfmt.o ustrtrns.o ustr_wcs.o utext.o \
-unistr_case_locale.o ustrcase_locale.o unistr_titlecase_brkiter.o ustr_titlecase_brkiter.o \
-normalizer2impl.o normalizer2.o filterednormalizer2.o normlzr.o unorm.o unormcmp.o loadednormalizer2impl.o \
-chariter.o schriter.o uchriter.o uiter.o \
-patternprops.o uchar.o uprops.o ucase.o propname.o ubidi_props.o ubidi.o ubidiwrt.o ubidiln.o ushape.o \
-uscript.o uscript_props.o usc_impl.o unames.o \
-utrie.o utrie2.o utrie2_builder.o bmpset.o unisetspan.o uset_props.o uniset_props.o uniset_closure.o uset.o uniset.o usetiter.o ruleiter.o caniter.o unifilt.o unifunct.o \
-uarrsort.o brkiter.o ubrk.o brkeng.o dictbe.o filteredbrk.o \
-rbbi.o rbbidata.o rbbinode.o rbbirb.o rbbiscan.o rbbisetb.o rbbistbl.o rbbitblb.o \
-serv.o servnotf.o servls.o servlk.o servlkf.o servrbf.o servslkf.o \
-uidna.o usprep.o uts46.o punycode.o \
-util.o util_props.o parsepos.o locbased.o cwchar.o wintz.o dtintrv.o ucnvsel.o propsvec.o \
-ulist.o uloc_tag.o icudataver.o icuplug.o listformatter.o ulistformatter.o \
-sharedobject.o simplepatternformatter.o unifiedcache.o uloc_keytype.o \
-pluralmap.o
+SOURCES = $(shell cat $(srcdir)/sources.txt)
+OBJECTS = $(SOURCES:.cpp=.o)
 
 ## Header files to install
 HEADERS = $(srcdir)/unicode/*.h
@@ -148,6 +122,11 @@
 	$(INSTALL-L) $(TARGET) $(DESTDIR)$(libdir)
 endif
 ifneq ($(ENABLE_SHARED),)
+# For MinGW, do we want the DLL to go in the bin location?
+ifeq ($(MINGW_MOVEDLLSTOBINDIR),YES)
+	$(MKINSTALLDIRS) $(DESTDIR)$(bindir)
+	$(INSTALL-L) $(FINAL_SO_TARGET) $(DESTDIR)$(bindir)
+else
 	$(INSTALL-L) $(FINAL_SO_TARGET) $(DESTDIR)$(libdir)
 ifneq ($(FINAL_SO_TARGET),$(SO_TARGET))
 	cd $(DESTDIR)$(libdir) && $(RM) $(notdir $(SO_TARGET)) && ln -s $(notdir $(FINAL_SO_TARGET)) $(notdir $(SO_TARGET))
@@ -155,6 +134,7 @@
 	cd $(DESTDIR)$(libdir) && $(RM) $(notdir $(MIDDLE_SO_TARGET)) && ln -s $(notdir $(FINAL_SO_TARGET)) $(notdir $(MIDDLE_SO_TARGET))
 endif
 endif
+endif
 ifneq ($(IMPORT_LIB_EXT),)
 	$(INSTALL-L) $(FINAL_IMPORT_LIB) $(DESTDIR)$(libdir)
 ifneq ($(IMPORT_LIB),$(FINAL_IMPORT_LIB))
diff --git a/src/third_party/icu/source/common/appendable.cpp b/src/third_party/icu/source/common/appendable.cpp
index e46d079..fca3c1e 100644
--- a/src/third_party/icu/source/common/appendable.cpp
+++ b/src/third_party/icu/source/common/appendable.cpp
@@ -1,10 +1,12 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *   Copyright (C) 2011-2012, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *******************************************************************************
 *   file name:  appendable.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
diff --git a/src/third_party/icu/source/common/bmpset.cpp b/src/third_party/icu/source/common/bmpset.cpp
index 18e450c..c6b9a32 100644
--- a/src/third_party/icu/source/common/bmpset.cpp
+++ b/src/third_party/icu/source/common/bmpset.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 ******************************************************************************
 *   file name:  bmpset.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -14,8 +16,10 @@
 *   created by: Markus W. Scherer
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/utypes.h"
 #include "unicode/uniset.h"
 #include "unicode/utf8.h"
@@ -28,7 +32,7 @@
 
 BMPSet::BMPSet(const int32_t *parentList, int32_t parentListLength) :
         list(parentList), listLength(parentListLength) {
-    uprv_memset(asciiBytes, 0, sizeof(asciiBytes));
+    uprv_memset(latin1Contains, 0, sizeof(latin1Contains));
     uprv_memset(table7FF, 0, sizeof(table7FF));
     uprv_memset(bmpBlockBits, 0, sizeof(bmpBlockBits));
 
@@ -45,14 +49,16 @@
         list4kStarts[i]=findCodePoint(i<<12, list4kStarts[i-1], listLength-1);
     }
     list4kStarts[0x11]=listLength-1;
+    containsFFFD=containsSlow(0xfffd, list4kStarts[0xf], list4kStarts[0x10]);
 
     initBits();
     overrideIllegal();
 }
 
 BMPSet::BMPSet(const BMPSet &otherBMPSet, const int32_t *newParentList, int32_t newParentListLength) :
+        containsFFFD(otherBMPSet.containsFFFD),
         list(newParentList), listLength(newParentListLength) {
-    uprv_memcpy(asciiBytes, otherBMPSet.asciiBytes, sizeof(asciiBytes));
+    uprv_memcpy(latin1Contains, otherBMPSet.latin1Contains, sizeof(latin1Contains));
     uprv_memcpy(table7FF, otherBMPSet.table7FF, sizeof(table7FF));
     uprv_memcpy(bmpBlockBits, otherBMPSet.bmpBlockBits, sizeof(bmpBlockBits));
     uprv_memcpy(list4kStarts, otherBMPSet.list4kStarts, sizeof(list4kStarts));
@@ -98,9 +104,9 @@
             ++lead;
         }
         if(lead<limitLead) {
-            bits=~((1<<lead)-1);
+            bits=~(((unsigned)1<<lead)-1);
             if(limitLead<0x20) {
-                bits&=(1<<limitLead)-1;
+                bits&=((unsigned)1<<limitLead)-1;
             }
             for(trail=0; trail<64; ++trail) {
                 table[trail]|=bits;
@@ -120,7 +126,7 @@
     UChar32 start, limit;
     int32_t listIndex=0;
 
-    // Set asciiBytes[].
+    // Set latin1Contains[].
     do {
         start=list[listIndex++];
         if(listIndex<listLength) {
@@ -128,13 +134,30 @@
         } else {
             limit=0x110000;
         }
-        if(start>=0x80) {
+        if(start>=0x100) {
             break;
         }
         do {
-            asciiBytes[start++]=1;
-        } while(start<limit && start<0x80);
-    } while(limit<=0x80);
+            latin1Contains[start++]=1;
+        } while(start<limit && start<0x100);
+    } while(limit<=0x100);
+
+    // Find the first range overlapping with (or after) 80..FF again,
+    // to include them in table7FF as well.
+    for(listIndex=0;;) {
+        start=list[listIndex++];
+        if(listIndex<listLength) {
+            limit=list[listIndex++];
+        } else {
+            limit=0x110000;
+        }
+        if(limit>0x80) {
+            if(start<0x80) {
+                start=0x80;
+            }
+            break;
+        }
+    }
 
     // Set table7FF[].
     while(start<0x800) {
@@ -204,19 +227,14 @@
  * for faster validity checking at runtime.
  * No need to set 0 values where they were reset to 0 in the constructor
  * and not modified by initBits().
- * (asciiBytes[] trail bytes, table7FF[] 0..7F, bmpBlockBits[] 0..7FF)
+ * (table7FF[] 0..7F, bmpBlockBits[] 0..7FF)
  * Need to set 0 values for surrogates D800..DFFF.
  */
 void BMPSet::overrideIllegal() {
     uint32_t bits, mask;
     int32_t i;
 
-    if(containsSlow(0xfffd, list4kStarts[0xf], list4kStarts[0x10])) {
-        // contains(FFFD)==TRUE
-        for(i=0x80; i<0xc0; ++i) {
-            asciiBytes[i]=1;
-        }
-
+    if(containsFFFD) {
         bits=3;                 // Lead bytes 0xC0 and 0xC1.
         for(i=0; i<64; ++i) {
             table7FF[i]|=bits;
@@ -227,14 +245,13 @@
             bmpBlockBits[i]|=bits;
         }
 
-        mask=~(0x10001<<0xd);   // Lead byte 0xED.
+        mask= static_cast<uint32_t>(~(0x10001<<0xd));   // Lead byte 0xED.
         bits=1<<0xd;
         for(i=32; i<64; ++i) {  // Second half of 4k block.
             bmpBlockBits[i]=(bmpBlockBits[i]&mask)|bits;
         }
     } else {
-        // contains(FFFD)==FALSE
-        mask=~(0x10001<<0xd);   // Lead byte 0xED.
+        mask= static_cast<uint32_t>(~(0x10001<<0xd));   // Lead byte 0xED.
         for(i=32; i<64; ++i) {  // Second half of 4k block.
             bmpBlockBits[i]&=mask;
         }
@@ -277,8 +294,8 @@
 
 UBool
 BMPSet::contains(UChar32 c) const {
-    if((uint32_t)c<=0x7f) {
-        return (UBool)asciiBytes[c];
+    if((uint32_t)c<=0xff) {
+        return (UBool)latin1Contains[c];
     } else if((uint32_t)c<=0x7ff) {
         return (UBool)((table7FF[c&0x3f]&((uint32_t)1<<(c>>6)))!=0);
     } else if((uint32_t)c<0xd800 || (c>=0xe000 && c<=0xffff)) {
@@ -314,8 +331,8 @@
         // span
         do {
             c=*s;
-            if(c<=0x7f) {
-                if(!asciiBytes[c]) {
+            if(c<=0xff) {
+                if(!latin1Contains[c]) {
                     break;
                 }
             } else if(c<=0x7ff) {
@@ -354,8 +371,8 @@
         // span not
         do {
             c=*s;
-            if(c<=0x7f) {
-                if(asciiBytes[c]) {
+            if(c<=0xff) {
+                if(latin1Contains[c]) {
                     break;
                 }
             } else if(c<=0x7ff) {
@@ -403,8 +420,8 @@
         // span
         for(;;) {
             c=*(--limit);
-            if(c<=0x7f) {
-                if(!asciiBytes[c]) {
+            if(c<=0xff) {
+                if(!latin1Contains[c]) {
                     break;
                 }
             } else if(c<=0x7ff) {
@@ -446,8 +463,8 @@
         // span not
         for(;;) {
             c=*(--limit);
-            if(c<=0x7f) {
-                if(asciiBytes[c]) {
+            if(c<=0xff) {
+                if(latin1Contains[c]) {
                     break;
                 }
             } else if(c<=0x7ff) {
@@ -497,22 +514,22 @@
 BMPSet::spanUTF8(const uint8_t *s, int32_t length, USetSpanCondition spanCondition) const {
     const uint8_t *limit=s+length;
     uint8_t b=*s;
-    if((int8_t)b>=0) {
+    if(U8_IS_SINGLE(b)) {
         // Initial all-ASCII span.
         if(spanCondition) {
             do {
-                if(!asciiBytes[b] || ++s==limit) {
+                if(!latin1Contains[b] || ++s==limit) {
                     return s;
                 }
                 b=*s;
-            } while((int8_t)b>=0);
+            } while(U8_IS_SINGLE(b));
         } else {
             do {
-                if(asciiBytes[b] || ++s==limit) {
+                if(latin1Contains[b] || ++s==limit) {
                     return s;
                 }
                 b=*s;
-            } while((int8_t)b>=0);
+            } while(U8_IS_SINGLE(b));
         }
         length=(int32_t)(limit-s);
     }
@@ -540,20 +557,20 @@
             // single trail byte, check for preceding 3- or 4-byte lead byte
             if(length>=2 && (b=*(limit-2))>=0xe0) {
                 limit-=2;
-                if(asciiBytes[0x80]!=spanCondition) {
+                if(containsFFFD!=spanCondition) {
                     limit0=limit;
                 }
             } else if(b<0xc0 && b>=0x80 && length>=3 && (b=*(limit-3))>=0xf0) {
                 // 4-byte lead byte with only two trail bytes
                 limit-=3;
-                if(asciiBytes[0x80]!=spanCondition) {
+                if(containsFFFD!=spanCondition) {
                     limit0=limit;
                 }
             }
         } else {
             // lead byte with no trail bytes
             --limit;
-            if(asciiBytes[0x80]!=spanCondition) {
+            if(containsFFFD!=spanCondition) {
                 limit0=limit;
             }
         }
@@ -563,26 +580,26 @@
 
     while(s<limit) {
         b=*s;
-        if(b<0xc0) {
-            // ASCII; or trail bytes with the result of contains(FFFD).
+        if(U8_IS_SINGLE(b)) {
+            // ASCII
             if(spanCondition) {
                 do {
-                    if(!asciiBytes[b]) {
+                    if(!latin1Contains[b]) {
                         return s;
                     } else if(++s==limit) {
                         return limit0;
                     }
                     b=*s;
-                } while(b<0xc0);
+                } while(U8_IS_SINGLE(b));
             } else {
                 do {
-                    if(asciiBytes[b]) {
+                    if(latin1Contains[b]) {
                         return s;
                     } else if(++s==limit) {
                         return limit0;
                     }
                     b=*s;
-                } while(b<0xc0);
+                } while(U8_IS_SINGLE(b));
             }
         }
         ++s;  // Advance past the lead byte.
@@ -619,7 +636,7 @@
                 UChar32 c=((UChar32)(b-0xf0)<<18)|((UChar32)t1<<12)|(t2<<6)|t3;
                 if( (   (0x10000<=c && c<=0x10ffff) ?
                             containsSlow(c, list4kStarts[0x10], list4kStarts[0x11]) :
-                            asciiBytes[0x80]
+                            containsFFFD
                     ) != spanCondition
                 ) {
                     return s-1;
@@ -627,8 +644,9 @@
                 s+=3;
                 continue;
             }
-        } else /* 0xc0<=b<0xe0 */ {
+        } else {
             if( /* handle U+0000..U+07FF inline */
+                b>=0xc0 &&
                 (t1=(uint8_t)(*s-0x80)) <= 0x3f
             ) {
                 if((USetSpanCondition)((table7FF[t1]&((uint32_t)1<<(b&0x1f)))!=0) != spanCondition) {
@@ -642,7 +660,7 @@
         // Give an illegal sequence the same value as the result of contains(FFFD).
         // Handle each byte of an illegal sequence separately to simplify the code;
         // no need to optimize error handling.
-        if(asciiBytes[0x80]!=spanCondition) {
+        if(containsFFFD!=spanCondition) {
             return s-1;
         }
     }
@@ -667,26 +685,26 @@
 
     do {
         b=s[--length];
-        if((int8_t)b>=0) {
+        if(U8_IS_SINGLE(b)) {
             // ASCII sub-span
             if(spanCondition) {
                 do {
-                    if(!asciiBytes[b]) {
+                    if(!latin1Contains[b]) {
                         return length+1;
                     } else if(length==0) {
                         return 0;
                     }
                     b=s[--length];
-                } while((int8_t)b>=0);
+                } while(U8_IS_SINGLE(b));
             } else {
                 do {
-                    if(asciiBytes[b]) {
+                    if(latin1Contains[b]) {
                         return length+1;
                     } else if(length==0) {
                         return 0;
                     }
                     b=s[--length];
-                } while((int8_t)b>=0);
+                } while(U8_IS_SINGLE(b));
             }
         }
 
diff --git a/src/third_party/icu/source/common/bmpset.h b/src/third_party/icu/source/common/bmpset.h
index d9e08ea..e1982ac 100644
--- a/src/third_party/icu/source/common/bmpset.h
+++ b/src/third_party/icu/source/common/bmpset.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 ******************************************************************************
 *   file name:  bmpset.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -26,11 +28,12 @@
  * Helper class for frozen UnicodeSets, implements contains() and span()
  * optimized for BMP code points. Structured to be UTF-8-friendly.
  *
- * ASCII: Look up bytes.
+ * Latin-1: Look up bytes.
  * 2-byte characters: Bits organized vertically.
  * 3-byte characters: Use zero/one/mixed data per 64-block in U+0000..U+FFFF,
  *                    with mixed for illegal ranges.
- * Supplementary characters: Call contains() on the parent set.
+ * Supplementary characters: Binary search over
+ * the supplementary part of the parent set's inversion list.
  */
 class BMPSet : public UMemory {
 public:
@@ -94,12 +97,12 @@
     inline UBool containsSlow(UChar32 c, int32_t lo, int32_t hi) const;
 
     /*
-     * One byte per ASCII character, or trail byte in lead position.
-     * 0 or 1 for ASCII characters.
-     * The value for trail bytes is the result of contains(FFFD)
-     * for faster validity checking at runtime.
+     * One byte 0 or 1 per Latin-1 character.
      */
-    UBool asciiBytes[0xc0];
+    UBool latin1Contains[0x100];
+
+    /* true if contains(U+FFFD). */
+    UBool containsFFFD;
 
     /*
      * One bit per code point from U+0000..U+07FF.
diff --git a/src/third_party/icu/source/common/brkeng.cpp b/src/third_party/icu/source/common/brkeng.cpp
index 6cdda98..cc8f975 100644
--- a/src/third_party/icu/source/common/brkeng.cpp
+++ b/src/third_party/icu/source/common/brkeng.cpp
@@ -1,6 +1,8 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
  ************************************************************************************
- * Copyright (C) 2006-2015, International Business Machines Corporation
+ * Copyright (C) 2006-2016, International Business Machines Corporation
  * and others. All Rights Reserved.
  ************************************************************************************
  */
@@ -9,9 +11,10 @@
 
 #if !UCONFIG_NO_BREAK_ITERATION
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
-#include "brkeng.h"
-#include "dictbe.h"
+#endif  // defined(STARBOARD)
+
 #include "unicode/uchar.h"
 #include "unicode/uniset.h"
 #include "unicode/chariter.h"
@@ -22,6 +25,10 @@
 #include "unicode/uscript.h"
 #include "unicode/ucharstrie.h"
 #include "unicode/bytestrie.h"
+
+#include "brkeng.h"
+#include "cmemory.h"
+#include "dictbe.h"
 #include "charstr.h"
 #include "dictionarydata.h"
 #include "mutex.h"
@@ -56,65 +63,46 @@
  ******************************************************************
  */
 
-UnhandledEngine::UnhandledEngine(UErrorCode &/*status*/) {
-    for (int32_t i = 0; i < (int32_t)(sizeof(fHandled)/sizeof(fHandled[0])); ++i) {
-        fHandled[i] = 0;
-    }
+UnhandledEngine::UnhandledEngine(UErrorCode &status) : fHandled(nullptr) {
+    (void)status;
 }
 
 UnhandledEngine::~UnhandledEngine() {
-    for (int32_t i = 0; i < (int32_t)(sizeof(fHandled)/sizeof(fHandled[0])); ++i) {
-        if (fHandled[i] != 0) {
-            delete fHandled[i];
-        }
-    }
+    delete fHandled;
+    fHandled = nullptr;
 }
 
 UBool
-UnhandledEngine::handles(UChar32 c, int32_t breakType) const {
-    return (breakType >= 0 && breakType < (int32_t)(sizeof(fHandled)/sizeof(fHandled[0]))
-        && fHandled[breakType] != 0 && fHandled[breakType]->contains(c));
+UnhandledEngine::handles(UChar32 c) const {
+    return fHandled && fHandled->contains(c);
 }
 
 int32_t
 UnhandledEngine::findBreaks( UText *text,
-                                 int32_t startPos,
-                                 int32_t endPos,
-                                 UBool reverse,
-                                 int32_t breakType,
-                                 UStack &/*foundBreaks*/ ) const {
-    if (breakType >= 0 && breakType < (int32_t)(sizeof(fHandled)/sizeof(fHandled[0]))) {
-        UChar32 c = utext_current32(text); 
-        if (reverse) {
-            while((int32_t)utext_getNativeIndex(text) > startPos && fHandled[breakType]->contains(c)) {
-                c = utext_previous32(text);
-            }
-        }
-        else {
-            while((int32_t)utext_getNativeIndex(text) < endPos && fHandled[breakType]->contains(c)) {
-                utext_next32(text);            // TODO:  recast loop to work with post-increment operations.
-                c = utext_current32(text);
-            }
-        }
+                             int32_t /* startPos */,
+                             int32_t endPos,
+                             UVector32 &/*foundBreaks*/ ) const {
+    UChar32 c = utext_current32(text); 
+    while((int32_t)utext_getNativeIndex(text) < endPos && fHandled->contains(c)) {
+        utext_next32(text);            // TODO:  recast loop to work with post-increment operations.
+        c = utext_current32(text);
     }
     return 0;
 }
 
 void
-UnhandledEngine::handleCharacter(UChar32 c, int32_t breakType) {
-    if (breakType >= 0 && breakType < (int32_t)(sizeof(fHandled)/sizeof(fHandled[0]))) {
-        if (fHandled[breakType] == 0) {
-            fHandled[breakType] = new UnicodeSet();
-            if (fHandled[breakType] == 0) {
-                return;
-            }
+UnhandledEngine::handleCharacter(UChar32 c) {
+    if (fHandled == nullptr) {
+        fHandled = new UnicodeSet();
+        if (fHandled == nullptr) {
+            return;
         }
-        if (!fHandled[breakType]->contains(c)) {
-            UErrorCode status = U_ZERO_ERROR;
-            // Apply the entire script of the character.
-            int32_t script = u_getIntPropertyValue(c, UCHAR_SCRIPT);
-            fHandled[breakType]->applyIntPropertyValue(UCHAR_SCRIPT, script, status);
-        }
+    }
+    if (!fHandled->contains(c)) {
+        UErrorCode status = U_ZERO_ERROR;
+        // Apply the entire script of the character.
+        int32_t script = u_getIntPropertyValue(c, UCHAR_SCRIPT);
+        fHandled->applyIntPropertyValue(UCHAR_SCRIPT, script, status);
     }
 }
 
@@ -140,13 +128,12 @@
 U_CDECL_END
 U_NAMESPACE_BEGIN
 
-static UMutex gBreakEngineMutex = U_MUTEX_INITIALIZER;
-
 const LanguageBreakEngine *
-ICULanguageBreakFactory::getEngineFor(UChar32 c, int32_t breakType) {
+ICULanguageBreakFactory::getEngineFor(UChar32 c) {
     const LanguageBreakEngine *lbe = NULL;
     UErrorCode  status = U_ZERO_ERROR;
 
+    static UMutex gBreakEngineMutex;
     Mutex m(&gBreakEngineMutex);
 
     if (fEngines == NULL) {
@@ -161,14 +148,14 @@
         int32_t i = fEngines->size();
         while (--i >= 0) {
             lbe = (const LanguageBreakEngine *)(fEngines->elementAt(i));
-            if (lbe != NULL && lbe->handles(c, breakType)) {
+            if (lbe != NULL && lbe->handles(c)) {
                 return lbe;
             }
         }
     }
     
     // We didn't find an engine. Create one.
-    lbe = loadEngineFor(c, breakType);
+    lbe = loadEngineFor(c);
     if (lbe != NULL) {
         fEngines->push((void *)lbe, status);
     }
@@ -176,11 +163,11 @@
 }
 
 const LanguageBreakEngine *
-ICULanguageBreakFactory::loadEngineFor(UChar32 c, int32_t breakType) {
+ICULanguageBreakFactory::loadEngineFor(UChar32 c) {
     UErrorCode status = U_ZERO_ERROR;
     UScriptCode code = uscript_getScript(c, &status);
     if (U_SUCCESS(status)) {
-        DictionaryMatcher *m = loadDictionaryMatcherFor(code, breakType);
+        DictionaryMatcher *m = loadDictionaryMatcherFor(code);
         if (m != NULL) {
             const LanguageBreakEngine *engine = NULL;
             switch(code) {
@@ -241,7 +228,7 @@
 }
 
 DictionaryMatcher *
-ICULanguageBreakFactory::loadDictionaryMatcherFor(UScriptCode script, int32_t /* brkType */) { 
+ICULanguageBreakFactory::loadDictionaryMatcherFor(UScriptCode script) { 
     UErrorCode status = U_ZERO_ERROR;
     // open root from brkitr tree.
     UResourceBundle *b = ures_open(U_ICUDATA_BRKITR, "", &status);
diff --git a/src/third_party/icu/source/common/brkeng.h b/src/third_party/icu/source/common/brkeng.h
index 7f926f1..155433b 100644
--- a/src/third_party/icu/source/common/brkeng.h
+++ b/src/third_party/icu/source/common/brkeng.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /**
  ************************************************************************************
  * Copyright (C) 2006-2012, International Business Machines Corporation and others. *
@@ -17,6 +19,7 @@
 
 class UnicodeSet;
 class UStack;
+class UVector32;
 class DictionaryMatcher;
 
 /*******************************************************************
@@ -51,11 +54,10 @@
   * a particular kind of break.</p>
   *
   * @param c A character which begins a run that the engine might handle
-  * @param breakType The type of text break which the caller wants to determine
-  * @return TRUE if this engine handles the particular character and break
+  * @return true if this engine handles the particular character and break
   * type.
   */
-  virtual UBool handles(UChar32 c, int32_t breakType) const = 0;
+  virtual UBool handles(UChar32 c) const = 0;
 
  /**
   * <p>Find any breaks within a run in the supplied text.</p>
@@ -65,18 +67,13 @@
   * is capable of handling.
   * @param startPos The start of the run within the supplied text.
   * @param endPos The end of the run within the supplied text.
-  * @param reverse Whether the caller is looking for breaks in a reverse
-  * direction.
-  * @param breakType The type of break desired, or -1.
-  * @param foundBreaks An allocated C array of the breaks found, if any
+  * @param foundBreaks A Vector of int32_t to receive the breaks.
   * @return The number of breaks found.
   */
   virtual int32_t findBreaks( UText *text,
                               int32_t startPos,
                               int32_t endPos,
-                              UBool reverse,
-                              int32_t breakType,
-                              UStack &foundBreaks ) const = 0;
+                              UVector32 &foundBreaks ) const = 0;
 
 };
 
@@ -125,11 +122,9 @@
   *
   * @param c A character that begins a run for which a LanguageBreakEngine is
   * sought.
-  * @param breakType The kind of text break for which a LanguageBreakEngine is
-  * sought.
   * @return A LanguageBreakEngine with the desired characteristics, or 0.
   */
-  virtual const LanguageBreakEngine *getEngineFor(UChar32 c, int32_t breakType) = 0;
+  virtual const LanguageBreakEngine *getEngineFor(UChar32 c) = 0;
 
 };
 
@@ -152,11 +147,11 @@
  private:
 
     /**
-     * The sets of characters handled, for each break type
+     * The sets of characters handled.
      * @internal
      */
 
-  UnicodeSet    *fHandled[4];
+  UnicodeSet    *fHandled;
 
  public:
 
@@ -176,11 +171,10 @@
   * a particular kind of break.</p>
   *
   * @param c A character which begins a run that the engine might handle
-  * @param breakType The type of text break which the caller wants to determine
-  * @return TRUE if this engine handles the particular character and break
+  * @return true if this engine handles the particular character and break
   * type.
   */
-  virtual UBool handles(UChar32 c, int32_t breakType) const;
+  virtual UBool handles(UChar32 c) const;
 
  /**
   * <p>Find any breaks within a run in the supplied text.</p>
@@ -190,26 +184,20 @@
   * is capable of handling.
   * @param startPos The start of the run within the supplied text.
   * @param endPos The end of the run within the supplied text.
-  * @param reverse Whether the caller is looking for breaks in a reverse
-  * direction.
-  * @param breakType The type of break desired, or -1.
   * @param foundBreaks An allocated C array of the breaks found, if any
   * @return The number of breaks found.
   */
   virtual int32_t findBreaks( UText *text,
                               int32_t startPos,
                               int32_t endPos,
-                              UBool reverse,
-                              int32_t breakType,
-                              UStack &foundBreaks ) const;
+                              UVector32 &foundBreaks ) const;
 
  /**
   * <p>Tell the engine to handle a particular character and break type.</p>
   *
   * @param c A character which the engine should handle
-  * @param breakType The type of text break for which the engine should handle c
   */
-  virtual void handleCharacter(UChar32 c, int32_t breakType);
+  virtual void handleCharacter(UChar32 c);
 
 };
 
@@ -253,11 +241,9 @@
   *
   * @param c A character that begins a run for which a LanguageBreakEngine is
   * sought.
-  * @param breakType The kind of text break for which a LanguageBreakEngine is
-  * sought.
   * @return A LanguageBreakEngine with the desired characteristics, or 0.
   */
-  virtual const LanguageBreakEngine *getEngineFor(UChar32 c, int32_t breakType);
+  virtual const LanguageBreakEngine *getEngineFor(UChar32 c);
 
 protected:
  /**
@@ -266,21 +252,17 @@
   *
   * @param c A character that begins a run for which a LanguageBreakEngine is
   * sought.
-  * @param breakType The kind of text break for which a LanguageBreakEngine is
-  * sought.
   * @return A LanguageBreakEngine with the desired characteristics, or 0.
   */
-  virtual const LanguageBreakEngine *loadEngineFor(UChar32 c, int32_t breakType);
+  virtual const LanguageBreakEngine *loadEngineFor(UChar32 c);
 
   /**
    * <p>Create a DictionaryMatcher for the specified script and break type.</p>
    * @param script An ISO 15924 script code that identifies the dictionary to be
    * created.
-   * @param breakType The kind of text break for which a dictionary is 
-   * sought.
    * @return A DictionaryMatcher with the desired characteristics, or NULL.
    */
-  virtual DictionaryMatcher *loadDictionaryMatcherFor(UScriptCode script, int32_t breakType);
+  virtual DictionaryMatcher *loadDictionaryMatcherFor(UScriptCode script);
 };
 
 U_NAMESPACE_END
diff --git a/src/third_party/icu/source/common/brkiter.cpp b/src/third_party/icu/source/common/brkiter.cpp
index e9e7f9c..61f1fd2 100644
--- a/src/third_party/icu/source/common/brkiter.cpp
+++ b/src/third_party/icu/source/common/brkiter.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 * Copyright (C) 1997-2015, International Business Machines Corporation and
@@ -23,8 +25,10 @@
 
 #if !UCONFIG_NO_BREAK_ITERATION
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/rbbi.h"
 #include "unicode/brkiter.h"
 #include "unicode/udata.h"
@@ -39,6 +43,7 @@
 #include "uresimp.h"
 #include "uassert.h"
 #include "ubrkimpl.h"
+#include "utracimp.h"
 #include "charstr.h"
 
 // *****************************************************************************
@@ -53,7 +58,7 @@
 // -------------------------------------
 
 BreakIterator*
-BreakIterator::buildInstance(const Locale& loc, const char *type, int32_t kind, UErrorCode &status)
+BreakIterator::buildInstance(const Locale& loc, const char *type, UErrorCode &status)
 {
     char fnbuff[256];
     char ext[4]={'\0'};
@@ -122,7 +127,6 @@
         U_LOCALE_BASED(locBased, *(BreakIterator*)result);
         locBased.setLocaleIDs(ures_getLocaleByType(b, ULOC_VALID_LOCALE, &status), 
                               actualLocale.data());
-        result->setBreakType(kind);
     }
 
     ures_close(b);
@@ -196,7 +200,7 @@
 
 // ------------------------------------------
 //
-// Default constructor and destructor
+// Constructors, destructor and assignment operator
 //
 //-------------------------------------------
 
@@ -205,6 +209,19 @@
     *validLocale = *actualLocale = 0;
 }
 
+BreakIterator::BreakIterator(const BreakIterator &other) : UObject(other) {
+    uprv_strncpy(actualLocale, other.actualLocale, sizeof(actualLocale));
+    uprv_strncpy(validLocale, other.validLocale, sizeof(validLocale));
+}
+
+BreakIterator &BreakIterator::operator =(const BreakIterator &other) {
+    if (this != &other) {
+        uprv_strncpy(actualLocale, other.actualLocale, sizeof(actualLocale));
+        uprv_strncpy(validLocale, other.validLocale, sizeof(validLocale));
+    }
+    return *this;
+}
+
 BreakIterator::~BreakIterator()
 {
 }
@@ -266,7 +283,7 @@
 // defined in ucln_cmn.h
 U_NAMESPACE_END
 
-static icu::UInitOnce gInitOnce;
+static icu::UInitOnce gInitOnceBrkiter = U_INITONCE_INITIALIZER;
 static icu::ICULocaleService* gService = NULL;
 
 
@@ -281,7 +298,7 @@
         delete gService;
         gService = NULL;
     }
-    gInitOnce.reset();
+    gInitOnceBrkiter.reset();
 #endif
     return TRUE;
 }
@@ -297,7 +314,7 @@
 static ICULocaleService*
 getService(void)
 {
-    umtx_initOnce(gInitOnce, &initService);
+    umtx_initOnce(gInitOnceBrkiter, &initService);
     return gService;
 }
 
@@ -307,7 +324,7 @@
 static inline UBool
 hasService(void)
 {
-    return !gInitOnce.isReset() && getService() != NULL;
+    return !gInitOnceBrkiter.isReset() && getService() != NULL;
 }
 
 // -------------------------------------
@@ -401,14 +418,23 @@
     BreakIterator *result = NULL;
     switch (kind) {
     case UBRK_CHARACTER:
-        result = BreakIterator::buildInstance(loc, "grapheme", kind, status);
+        {
+            UTRACE_ENTRY(UTRACE_UBRK_CREATE_CHARACTER);
+            result = BreakIterator::buildInstance(loc, "grapheme", status);
+            UTRACE_EXIT_STATUS(status);
+        }
         break;
     case UBRK_WORD:
-        result = BreakIterator::buildInstance(loc, "word", kind, status);
+        {
+            UTRACE_ENTRY(UTRACE_UBRK_CREATE_WORD);
+            result = BreakIterator::buildInstance(loc, "word", status);
+            UTRACE_EXIT_STATUS(status);
+        }
         break;
     case UBRK_LINE:
-        uprv_strcpy(lbType, "line");
         {
+            UTRACE_ENTRY(UTRACE_UBRK_CREATE_LINE);
+            uprv_strcpy(lbType, "line");
             char lbKeyValue[kKeyValueLenMax] = {0};
             UErrorCode kvStatus = U_ZERO_ERROR;
             int32_t kLen = loc.getKeywordValue("lb", lbKeyValue, kKeyValueLenMax, kvStatus);
@@ -416,12 +442,17 @@
                 uprv_strcat(lbType, "_");
                 uprv_strcat(lbType, lbKeyValue);
             }
+            result = BreakIterator::buildInstance(loc, lbType, status);
+
+            UTRACE_DATA1(UTRACE_INFO, "lb=%s", lbKeyValue);
+            UTRACE_EXIT_STATUS(status);
         }
-        result = BreakIterator::buildInstance(loc, lbType, kind, status);
         break;
     case UBRK_SENTENCE:
-        result = BreakIterator::buildInstance(loc, "sentence", kind, status);
         {
+            UTRACE_ENTRY(UTRACE_UBRK_CREATE_SENTENCE);
+            result = BreakIterator::buildInstance(loc, "sentence", status);
+#if !UCONFIG_NO_FILTERED_BREAK_ITERATION
             char ssKeyValue[kKeyValueLenMax] = {0};
             UErrorCode kvStatus = U_ZERO_ERROR;
             int32_t kLen = loc.getKeywordValue("ss", ssKeyValue, kKeyValueLenMax, kvStatus);
@@ -432,10 +463,16 @@
                     delete fbiBuilder;
                 }
             }
+#endif
+            UTRACE_EXIT_STATUS(status);
         }
         break;
     case UBRK_TITLE:
-        result = BreakIterator::buildInstance(loc, "title", kind, status);
+        {
+            UTRACE_ENTRY(UTRACE_UBRK_CREATE_TITLE);
+            result = BreakIterator::buildInstance(loc, "title", status);
+            UTRACE_EXIT_STATUS(status);
+        }
         break;
     default:
         status = U_ILLEGAL_ARGUMENT_ERROR;
diff --git a/src/third_party/icu/source/common/bytesinkutil.cpp b/src/third_party/icu/source/common/bytesinkutil.cpp
new file mode 100644
index 0000000..c64a845
--- /dev/null
+++ b/src/third_party/icu/source/common/bytesinkutil.cpp
@@ -0,0 +1,161 @@
+// © 2017 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+// bytesinkutil.cpp
+// created: 2017sep14 Markus W. Scherer
+
+#include "unicode/utypes.h"
+#include "unicode/bytestream.h"
+#include "unicode/edits.h"
+#include "unicode/stringoptions.h"
+#include "unicode/utf8.h"
+#include "unicode/utf16.h"
+#include "bytesinkutil.h"
+#include "charstr.h"
+#include "cmemory.h"
+#include "uassert.h"
+
+U_NAMESPACE_BEGIN
+
+UBool
+ByteSinkUtil::appendChange(int32_t length, const char16_t *s16, int32_t s16Length,
+                           ByteSink &sink, Edits *edits, UErrorCode &errorCode) {
+    if (U_FAILURE(errorCode)) { return FALSE; }
+    char scratch[200];
+    int32_t s8Length = 0;
+    for (int32_t i = 0; i < s16Length;) {
+        int32_t capacity;
+        int32_t desiredCapacity = s16Length - i;
+        if (desiredCapacity < (INT32_MAX / 3)) {
+            desiredCapacity *= 3;  // max 3 UTF-8 bytes per UTF-16 code unit
+        } else if (desiredCapacity < (INT32_MAX / 2)) {
+            desiredCapacity *= 2;
+        } else {
+            desiredCapacity = INT32_MAX;
+        }
+        char *buffer = sink.GetAppendBuffer(U8_MAX_LENGTH, desiredCapacity,
+                                            scratch, UPRV_LENGTHOF(scratch), &capacity);
+        capacity -= U8_MAX_LENGTH - 1;
+        int32_t j = 0;
+        for (; i < s16Length && j < capacity;) {
+            UChar32 c;
+            U16_NEXT_UNSAFE(s16, i, c);
+            U8_APPEND_UNSAFE(buffer, j, c);
+        }
+        if (j > (INT32_MAX - s8Length)) {
+            errorCode = U_INDEX_OUTOFBOUNDS_ERROR;
+            return FALSE;
+        }
+        sink.Append(buffer, j);
+        s8Length += j;
+    }
+    if (edits != nullptr) {
+        edits->addReplace(length, s8Length);
+    }
+    return TRUE;
+}
+
+UBool
+ByteSinkUtil::appendChange(const uint8_t *s, const uint8_t *limit,
+                           const char16_t *s16, int32_t s16Length,
+                           ByteSink &sink, Edits *edits, UErrorCode &errorCode) {
+    if (U_FAILURE(errorCode)) { return FALSE; }
+    if ((limit - s) > INT32_MAX) {
+        errorCode = U_INDEX_OUTOFBOUNDS_ERROR;
+        return FALSE;
+    }
+    return appendChange((int32_t)(limit - s), s16, s16Length, sink, edits, errorCode);
+}
+
+void
+ByteSinkUtil::appendCodePoint(int32_t length, UChar32 c, ByteSink &sink, Edits *edits) {
+    char s8[U8_MAX_LENGTH];
+    int32_t s8Length = 0;
+    U8_APPEND_UNSAFE(s8, s8Length, c);
+    if (edits != nullptr) {
+        edits->addReplace(length, s8Length);
+    }
+    sink.Append(s8, s8Length);
+}
+
+namespace {
+
+// See unicode/utf8.h U8_APPEND_UNSAFE().
+inline uint8_t getTwoByteLead(UChar32 c) { return (uint8_t)((c >> 6) | 0xc0); }
+inline uint8_t getTwoByteTrail(UChar32 c) { return (uint8_t)((c & 0x3f) | 0x80); }
+
+}  // namespace
+
+void
+ByteSinkUtil::appendTwoBytes(UChar32 c, ByteSink &sink) {
+    U_ASSERT(0x80 <= c && c <= 0x7ff);  // 2-byte UTF-8
+    char s8[2] = { (char)getTwoByteLead(c), (char)getTwoByteTrail(c) };
+    sink.Append(s8, 2);
+}
+
+void
+ByteSinkUtil::appendNonEmptyUnchanged(const uint8_t *s, int32_t length,
+                                      ByteSink &sink, uint32_t options, Edits *edits) {
+    U_ASSERT(length > 0);
+    if (edits != nullptr) {
+        edits->addUnchanged(length);
+    }
+    if ((options & U_OMIT_UNCHANGED_TEXT) == 0) {
+        sink.Append(reinterpret_cast<const char *>(s), length);
+    }
+}
+
+UBool
+ByteSinkUtil::appendUnchanged(const uint8_t *s, const uint8_t *limit,
+                              ByteSink &sink, uint32_t options, Edits *edits,
+                              UErrorCode &errorCode) {
+    if (U_FAILURE(errorCode)) { return FALSE; }
+    if ((limit - s) > INT32_MAX) {
+        errorCode = U_INDEX_OUTOFBOUNDS_ERROR;
+        return FALSE;
+    }
+    int32_t length = (int32_t)(limit - s);
+    if (length > 0) {
+        appendNonEmptyUnchanged(s, length, sink, options, edits);
+    }
+    return TRUE;
+}
+
+CharStringByteSink::CharStringByteSink(CharString* dest) : dest_(*dest) {
+}
+
+CharStringByteSink::~CharStringByteSink() = default;
+
+void
+CharStringByteSink::Append(const char* bytes, int32_t n) {
+    UErrorCode status = U_ZERO_ERROR;
+    dest_.append(bytes, n, status);
+    // Any errors are silently ignored.
+}
+
+char*
+CharStringByteSink::GetAppendBuffer(int32_t min_capacity,
+                                    int32_t desired_capacity_hint,
+                                    char* scratch,
+                                    int32_t scratch_capacity,
+                                    int32_t* result_capacity) {
+    if (min_capacity < 1 || scratch_capacity < min_capacity) {
+        *result_capacity = 0;
+        return nullptr;
+    }
+
+    UErrorCode status = U_ZERO_ERROR;
+    char* result = dest_.getAppendBuffer(
+            min_capacity,
+            desired_capacity_hint,
+            *result_capacity,
+            status);
+    if (U_SUCCESS(status)) {
+        return result;
+    }
+
+    *result_capacity = scratch_capacity;
+    return scratch;
+}
+
+U_NAMESPACE_END
diff --git a/src/third_party/icu/source/common/bytesinkutil.h b/src/third_party/icu/source/common/bytesinkutil.h
new file mode 100644
index 0000000..ab25164
--- /dev/null
+++ b/src/third_party/icu/source/common/bytesinkutil.h
@@ -0,0 +1,83 @@
+// © 2017 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+// bytesinkutil.h
+// created: 2017sep14 Markus W. Scherer
+
+#include "unicode/utypes.h"
+#include "unicode/bytestream.h"
+#include "unicode/edits.h"
+#include "cmemory.h"
+#include "uassert.h"
+
+U_NAMESPACE_BEGIN
+
+class ByteSink;
+class CharString;
+class Edits;
+
+class U_COMMON_API ByteSinkUtil {
+public:
+    ByteSinkUtil() = delete;  // all static
+
+    /** (length) bytes were mapped to valid (s16, s16Length). */
+    static UBool appendChange(int32_t length,
+                              const char16_t *s16, int32_t s16Length,
+                              ByteSink &sink, Edits *edits, UErrorCode &errorCode);
+
+    /** The bytes at [s, limit[ were mapped to valid (s16, s16Length). */
+    static UBool appendChange(const uint8_t *s, const uint8_t *limit,
+                              const char16_t *s16, int32_t s16Length,
+                              ByteSink &sink, Edits *edits, UErrorCode &errorCode);
+
+    /** (length) bytes were mapped/changed to valid code point c. */
+    static void appendCodePoint(int32_t length, UChar32 c, ByteSink &sink, Edits *edits = nullptr);
+
+    /** The few bytes at [src, nextSrc[ were mapped/changed to valid code point c. */
+    static inline void appendCodePoint(const uint8_t *src, const uint8_t *nextSrc, UChar32 c,
+                                       ByteSink &sink, Edits *edits = nullptr) {
+        appendCodePoint((int32_t)(nextSrc - src), c, sink, edits);
+    }
+
+    /** Append the two-byte character (U+0080..U+07FF). */
+    static void appendTwoBytes(UChar32 c, ByteSink &sink);
+
+    static UBool appendUnchanged(const uint8_t *s, int32_t length,
+                                 ByteSink &sink, uint32_t options, Edits *edits,
+                                 UErrorCode &errorCode) {
+        if (U_FAILURE(errorCode)) { return false; }
+        if (length > 0) { appendNonEmptyUnchanged(s, length, sink, options, edits); }
+        return true;
+    }
+
+    static UBool appendUnchanged(const uint8_t *s, const uint8_t *limit,
+                                 ByteSink &sink, uint32_t options, Edits *edits,
+                                 UErrorCode &errorCode);
+
+private:
+    static void appendNonEmptyUnchanged(const uint8_t *s, int32_t length,
+                                        ByteSink &sink, uint32_t options, Edits *edits);
+};
+
+class U_COMMON_API CharStringByteSink : public ByteSink {
+public:
+    CharStringByteSink(CharString* dest);
+    ~CharStringByteSink() override;
+
+    CharStringByteSink() = delete;
+    CharStringByteSink(const CharStringByteSink&) = delete;
+    CharStringByteSink& operator=(const CharStringByteSink&) = delete;
+
+    void Append(const char* bytes, int32_t n) override;
+
+    char* GetAppendBuffer(int32_t min_capacity,
+                          int32_t desired_capacity_hint,
+                          char* scratch,
+                          int32_t scratch_capacity,
+                          int32_t* result_capacity) override;
+
+private:
+    CharString& dest_;
+};
+
+U_NAMESPACE_END
diff --git a/src/third_party/icu/source/common/bytestream.cpp b/src/third_party/icu/source/common/bytestream.cpp
index c07b0ae..fa01f6c 100644
--- a/src/third_party/icu/source/common/bytestream.cpp
+++ b/src/third_party/icu/source/common/bytestream.cpp
@@ -1,10 +1,14 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 // Copyright (C) 2009-2011, International Business Machines
 // Corporation and others. All Rights Reserved.
 //
 // Copyright 2007 Google Inc. All Rights Reserved.
 // Author: sanjay@google.com (Sanjay Ghemawat)
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/utypes.h"
 #include "unicode/bytestream.h"
 #include "cmemory.h"
@@ -44,6 +48,12 @@
   if (n <= 0) {
     return;
   }
+  if (n > (INT32_MAX - appended_)) {
+    // TODO: Report as integer overflow, not merely buffer overflow.
+    appended_ = INT32_MAX;
+    overflowed_ = TRUE;
+    return;
+  }
   appended_ += n;
   int32_t available = capacity_ - size_;
   if (n > available) {
diff --git a/src/third_party/icu/source/common/bytestrie.cpp b/src/third_party/icu/source/common/bytestrie.cpp
index c2ca618..8bd4f02 100644
--- a/src/third_party/icu/source/common/bytestrie.cpp
+++ b/src/third_party/icu/source/common/bytestrie.cpp
@@ -1,10 +1,12 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *   Copyright (C) 2010-2011, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *******************************************************************************
 *   file name:  bytestrie.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -12,8 +14,10 @@
 *   created by: Markus W. Scherer
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/utypes.h"
 #include "unicode/bytestream.h"
 #include "unicode/bytestrie.h"
diff --git a/src/third_party/icu/source/common/bytestriebuilder.cpp b/src/third_party/icu/source/common/bytestriebuilder.cpp
index 99c81e0..b3e8e9a 100644
--- a/src/third_party/icu/source/common/bytestriebuilder.cpp
+++ b/src/third_party/icu/source/common/bytestriebuilder.cpp
@@ -1,10 +1,12 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *   Copyright (C) 2010-2012, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *******************************************************************************
 *   file name:  bytestriebuilder.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -12,8 +14,10 @@
 *   created by: Markus W. Scherer
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/utypes.h"
 #include "unicode/bytestrie.h"
 #include "unicode/bytestriebuilder.h"
@@ -37,7 +41,7 @@
 public:
     // Use compiler's default constructor, initializes nothing.
 
-    void setTo(const StringPiece &s, int32_t val, CharString &strings, UErrorCode &errorCode);
+    void setTo(StringPiece s, int32_t val, CharString &strings, UErrorCode &errorCode);
 
     StringPiece getString(const CharString &strings) const {
         int32_t offset=stringOffset;
@@ -88,7 +92,7 @@
 };
 
 void
-BytesTrieElement::setTo(const StringPiece &s, int32_t val,
+BytesTrieElement::setTo(StringPiece s, int32_t val,
                         CharString &strings, UErrorCode &errorCode) {
     if(U_FAILURE(errorCode)) {
         return;
@@ -145,7 +149,7 @@
 }
 
 BytesTrieBuilder &
-BytesTrieBuilder::add(const StringPiece &s, int32_t value, UErrorCode &errorCode) {
+BytesTrieBuilder::add(StringPiece s, int32_t value, UErrorCode &errorCode) {
     if(U_FAILURE(errorCode)) {
         return *this;
     }
@@ -167,7 +171,7 @@
             return *this; // error instead of dereferencing null
         }
         if(elementsLength>0) {
-            uprv_memcpy(newElements, elements, elementsLength*sizeof(BytesTrieElement));
+            uprv_memcpy(newElements, elements, (size_t)elementsLength*sizeof(BytesTrieElement));
         }
         delete[] elements;
         elements=newElements;
@@ -339,7 +343,8 @@
 
 BytesTrieBuilder::BTLinearMatchNode::BTLinearMatchNode(const char *bytes, int32_t len, Node *nextNode)
         : LinearMatchNode(len, nextNode), s(bytes) {
-    hash=hash*37+ustr_hashCharsN(bytes, len);
+    hash=static_cast<int32_t>(
+        static_cast<uint32_t>(hash)*37u + static_cast<uint32_t>(ustr_hashCharsN(bytes, len)));
 }
 
 UBool
diff --git a/src/third_party/icu/source/common/bytestrieiterator.cpp b/src/third_party/icu/source/common/bytestrieiterator.cpp
index a63ee5d..7b14bbe 100644
--- a/src/third_party/icu/source/common/bytestrieiterator.cpp
+++ b/src/third_party/icu/source/common/bytestrieiterator.cpp
@@ -1,10 +1,12 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *   Copyright (C) 2010-2012, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *******************************************************************************
 *   file name:  bytestrieiterator.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -12,8 +14,10 @@
 *   created by: Markus W. Scherer
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/utypes.h"
 #include "unicode/bytestrie.h"
 #include "unicode/stringpiece.h"
@@ -141,7 +145,6 @@
             } else {
                 pos_=skipValue(pos, node);
             }
-            sp_.set(str_->data(), str_->length());
             return TRUE;
         }
         if(maxLength_>0 && str_->length()==maxLength_) {
@@ -169,10 +172,14 @@
     }
 }
 
+StringPiece
+BytesTrie::Iterator::getString() const {
+    return str_ == NULL ? StringPiece() : str_->toStringPiece();
+}
+
 UBool
 BytesTrie::Iterator::truncateAndStop() {
     pos_=NULL;
-    sp_.set(str_->data(), str_->length());
     value_=-1;  // no real value for str
     return TRUE;
 }
@@ -201,7 +208,6 @@
     str_->append((char)trieByte, errorCode);
     if(isFinal) {
         pos_=NULL;
-        sp_.set(str_->data(), str_->length());
         value_=value;
         return NULL;
     } else {
diff --git a/src/third_party/icu/source/common/caniter.cpp b/src/third_party/icu/source/common/caniter.cpp
index acebd49..f2275a8 100644
--- a/src/third_party/icu/source/common/caniter.cpp
+++ b/src/third_party/icu/source/common/caniter.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
  *****************************************************************************
  * Copyright (C) 1996-2015, International Business Machines Corporation and
@@ -7,7 +9,9 @@
 
 #include "unicode/utypes.h"
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #if !UCONFIG_NO_NORMALIZATION
 
 #include "unicode/caniter.h"
@@ -310,12 +314,12 @@
 
         // see what the permutations of the characters before and after this one are
         //Hashtable *subpermute = permute(source.substring(0,i) + source.substring(i + UTF16.getCharCount(cp)));
-        permute(subPermuteString.replace(i, U16_LENGTH(cp), NULL, 0), skipZeros, &subpermute, status);
+        permute(subPermuteString.remove(i, U16_LENGTH(cp)), skipZeros, &subpermute, status);
         /* Test for buffer overflows */
         if(U_FAILURE(status)) {
             return;
         }
-        // The upper replace is destructive. The question is do we have to make a copy, or we don't care about the contents 
+        // The upper remove is destructive. The question is do we have to make a copy, or we don't care about the contents 
         // of source at this point.
 
         // prefix this character to all of them
@@ -404,7 +408,7 @@
     //String[] finalResult = new String[result.size()];
     UnicodeString *finalResult = NULL;
     int32_t resultCount;
-    if((resultCount = result.count())) {
+    if((resultCount = result.count()) != 0) {
         finalResult = new UnicodeString[resultCount];
         if (finalResult == 0) {
             status = U_MEMORY_ALLOCATION_ERROR;
diff --git a/src/third_party/icu/source/common/capi_helper.h b/src/third_party/icu/source/common/capi_helper.h
new file mode 100644
index 0000000..54b1db9
--- /dev/null
+++ b/src/third_party/icu/source/common/capi_helper.h
@@ -0,0 +1,97 @@
+// © 2018 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+#ifndef __CAPI_HELPER_H__
+#define __CAPI_HELPER_H__
+
+#include "unicode/utypes.h"
+
+U_NAMESPACE_BEGIN
+
+/**
+ * An internal helper class to help convert between C and C++ APIs.
+ */
+template<typename CType, typename CPPType, int32_t kMagic>
+class IcuCApiHelper {
+  public:
+    /**
+     * Convert from the C type to the C++ type (const version).
+     */
+    static const CPPType* validate(const CType* input, UErrorCode& status);
+
+    /**
+     * Convert from the C type to the C++ type (non-const version).
+     */
+    static CPPType* validate(CType* input, UErrorCode& status);
+
+    /**
+     * Convert from the C++ type to the C type (const version).
+     */
+    const CType* exportConstForC() const;
+
+    /**
+     * Convert from the C++ type to the C type (non-const version).
+     */
+    CType* exportForC();
+
+    /**
+     * Invalidates the object.
+     */
+    ~IcuCApiHelper();
+
+  private:
+    /**
+     * While the object is valid, fMagic equals kMagic.
+     */
+    int32_t fMagic = kMagic;
+};
+
+
+template<typename CType, typename CPPType, int32_t kMagic>
+const CPPType*
+IcuCApiHelper<CType, CPPType, kMagic>::validate(const CType* input, UErrorCode& status) {
+    if (U_FAILURE(status)) {
+        return nullptr;
+    }
+    if (input == nullptr) {
+        status = U_ILLEGAL_ARGUMENT_ERROR;
+        return nullptr;
+    }
+    auto* impl = reinterpret_cast<const CPPType*>(input);
+    if (static_cast<const IcuCApiHelper<CType, CPPType, kMagic>*>(impl)->fMagic != kMagic) {
+        status = U_INVALID_FORMAT_ERROR;
+        return nullptr;
+    }
+    return impl;
+}
+
+template<typename CType, typename CPPType, int32_t kMagic>
+CPPType*
+IcuCApiHelper<CType, CPPType, kMagic>::validate(CType* input, UErrorCode& status) {
+    auto* constInput = static_cast<const CType*>(input);
+    auto* validated = validate(constInput, status);
+    return const_cast<CPPType*>(validated);
+}
+
+template<typename CType, typename CPPType, int32_t kMagic>
+const CType*
+IcuCApiHelper<CType, CPPType, kMagic>::exportConstForC() const {
+    return reinterpret_cast<const CType*>(static_cast<const CPPType*>(this));
+}
+
+template<typename CType, typename CPPType, int32_t kMagic>
+CType*
+IcuCApiHelper<CType, CPPType, kMagic>::exportForC() {
+    return reinterpret_cast<CType*>(static_cast<CPPType*>(this));
+}
+
+template<typename CType, typename CPPType, int32_t kMagic>
+IcuCApiHelper<CType, CPPType, kMagic>::~IcuCApiHelper() {
+    // head off application errors by preventing use of of deleted objects.
+    fMagic = 0;
+}
+
+
+U_NAMESPACE_END
+
+#endif // __CAPI_HELPER_H__
diff --git a/src/third_party/icu/source/common/characterproperties.cpp b/src/third_party/icu/source/common/characterproperties.cpp
new file mode 100644
index 0000000..7b50a4e
--- /dev/null
+++ b/src/third_party/icu/source/common/characterproperties.cpp
@@ -0,0 +1,383 @@
+// © 2018 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+// characterproperties.cpp
+// created: 2018sep03 Markus W. Scherer
+
+#include "unicode/utypes.h"
+#include "unicode/localpointer.h"
+#include "unicode/uchar.h"
+#include "unicode/ucpmap.h"
+#include "unicode/ucptrie.h"
+#include "unicode/umutablecptrie.h"
+#include "unicode/uniset.h"
+#include "unicode/uscript.h"
+#include "unicode/uset.h"
+#include "cmemory.h"
+#include "mutex.h"
+#include "normalizer2impl.h"
+#include "uassert.h"
+#include "ubidi_props.h"
+#include "ucase.h"
+#include "ucln_cmn.h"
+#include "umutex.h"
+#include "uprops.h"
+
+using icu::LocalPointer;
+#if !UCONFIG_NO_NORMALIZATION
+using icu::Normalizer2Factory;
+using icu::Normalizer2Impl;
+#endif
+using icu::UInitOnce;
+using icu::UnicodeSet;
+
+namespace {
+
+UBool U_CALLCONV characterproperties_cleanup();
+
+constexpr int32_t NUM_INCLUSIONS = UPROPS_SRC_COUNT + UCHAR_INT_LIMIT - UCHAR_INT_START;
+
+struct Inclusion {
+    UnicodeSet  *fSet = nullptr;
+    UInitOnce    fInitOnce = U_INITONCE_INITIALIZER;
+};
+Inclusion gInclusions[NUM_INCLUSIONS]; // cached getInclusions()
+
+UnicodeSet *sets[UCHAR_BINARY_LIMIT] = {};
+
+UCPMap *maps[UCHAR_INT_LIMIT - UCHAR_INT_START] = {};
+
+icu::UMutex cpMutex;
+
+//----------------------------------------------------------------
+// Inclusions list
+//----------------------------------------------------------------
+
+// USetAdder implementation
+// Does not use uset.h to reduce code dependencies
+void U_CALLCONV
+_set_add(USet *set, UChar32 c) {
+    ((UnicodeSet *)set)->add(c);
+}
+
+void U_CALLCONV
+_set_addRange(USet *set, UChar32 start, UChar32 end) {
+    ((UnicodeSet *)set)->add(start, end);
+}
+
+void U_CALLCONV
+_set_addString(USet *set, const UChar *str, int32_t length) {
+    ((UnicodeSet *)set)->add(icu::UnicodeString((UBool)(length<0), str, length));
+}
+
+UBool U_CALLCONV characterproperties_cleanup() {
+    for (Inclusion &in: gInclusions) {
+        delete in.fSet;
+        in.fSet = nullptr;
+        in.fInitOnce.reset();
+    }
+    for (int32_t i = 0; i < UPRV_LENGTHOF(sets); ++i) {
+        delete sets[i];
+        sets[i] = nullptr;
+    }
+    for (int32_t i = 0; i < UPRV_LENGTHOF(maps); ++i) {
+        ucptrie_close(reinterpret_cast<UCPTrie *>(maps[i]));
+        maps[i] = nullptr;
+    }
+    return TRUE;
+}
+
+void U_CALLCONV initInclusion(UPropertySource src, UErrorCode &errorCode) {
+    // This function is invoked only via umtx_initOnce().
+    U_ASSERT(0 <= src && src < UPROPS_SRC_COUNT);
+    if (src == UPROPS_SRC_NONE) {
+        errorCode = U_INTERNAL_PROGRAM_ERROR;
+        return;
+    }
+    U_ASSERT(gInclusions[src].fSet == nullptr);
+
+    LocalPointer<UnicodeSet> incl(new UnicodeSet());
+    if (incl.isNull()) {
+        errorCode = U_MEMORY_ALLOCATION_ERROR;
+        return;
+    }
+    USetAdder sa = {
+        (USet *)incl.getAlias(),
+        _set_add,
+        _set_addRange,
+        _set_addString,
+        nullptr, // don't need remove()
+        nullptr // don't need removeRange()
+    };
+
+    switch(src) {
+    case UPROPS_SRC_CHAR:
+        uchar_addPropertyStarts(&sa, &errorCode);
+        break;
+    case UPROPS_SRC_PROPSVEC:
+        upropsvec_addPropertyStarts(&sa, &errorCode);
+        break;
+    case UPROPS_SRC_CHAR_AND_PROPSVEC:
+        uchar_addPropertyStarts(&sa, &errorCode);
+        upropsvec_addPropertyStarts(&sa, &errorCode);
+        break;
+#if !UCONFIG_NO_NORMALIZATION
+    case UPROPS_SRC_CASE_AND_NORM: {
+        const Normalizer2Impl *impl=Normalizer2Factory::getNFCImpl(errorCode);
+        if(U_SUCCESS(errorCode)) {
+            impl->addPropertyStarts(&sa, errorCode);
+        }
+        ucase_addPropertyStarts(&sa, &errorCode);
+        break;
+    }
+    case UPROPS_SRC_NFC: {
+        const Normalizer2Impl *impl=Normalizer2Factory::getNFCImpl(errorCode);
+        if(U_SUCCESS(errorCode)) {
+            impl->addPropertyStarts(&sa, errorCode);
+        }
+        break;
+    }
+    case UPROPS_SRC_NFKC: {
+        const Normalizer2Impl *impl=Normalizer2Factory::getNFKCImpl(errorCode);
+        if(U_SUCCESS(errorCode)) {
+            impl->addPropertyStarts(&sa, errorCode);
+        }
+        break;
+    }
+    case UPROPS_SRC_NFKC_CF: {
+        const Normalizer2Impl *impl=Normalizer2Factory::getNFKC_CFImpl(errorCode);
+        if(U_SUCCESS(errorCode)) {
+            impl->addPropertyStarts(&sa, errorCode);
+        }
+        break;
+    }
+    case UPROPS_SRC_NFC_CANON_ITER: {
+        const Normalizer2Impl *impl=Normalizer2Factory::getNFCImpl(errorCode);
+        if(U_SUCCESS(errorCode)) {
+            impl->addCanonIterPropertyStarts(&sa, errorCode);
+        }
+        break;
+    }
+#endif
+    case UPROPS_SRC_CASE:
+        ucase_addPropertyStarts(&sa, &errorCode);
+        break;
+    case UPROPS_SRC_BIDI:
+        ubidi_addPropertyStarts(&sa, &errorCode);
+        break;
+    case UPROPS_SRC_INPC:
+    case UPROPS_SRC_INSC:
+    case UPROPS_SRC_VO:
+        uprops_addPropertyStarts((UPropertySource)src, &sa, &errorCode);
+        break;
+    default:
+        errorCode = U_INTERNAL_PROGRAM_ERROR;
+        break;
+    }
+
+    if (U_FAILURE(errorCode)) {
+        return;
+    }
+    if (incl->isBogus()) {
+        errorCode = U_MEMORY_ALLOCATION_ERROR;
+        return;
+    }
+    // Compact for caching.
+    incl->compact();
+    gInclusions[src].fSet = incl.orphan();
+    ucln_common_registerCleanup(UCLN_COMMON_CHARACTERPROPERTIES, characterproperties_cleanup);
+}
+
+const UnicodeSet *getInclusionsForSource(UPropertySource src, UErrorCode &errorCode) {
+    if (U_FAILURE(errorCode)) { return nullptr; }
+    if (src < 0 || UPROPS_SRC_COUNT <= src) {
+        errorCode = U_ILLEGAL_ARGUMENT_ERROR;
+        return nullptr;
+    }
+    Inclusion &i = gInclusions[src];
+    umtx_initOnce(i.fInitOnce, &initInclusion, src, errorCode);
+    return i.fSet;
+}
+
+void U_CALLCONV initIntPropInclusion(UProperty prop, UErrorCode &errorCode) {
+    // This function is invoked only via umtx_initOnce().
+    U_ASSERT(UCHAR_INT_START <= prop && prop < UCHAR_INT_LIMIT);
+    int32_t inclIndex = UPROPS_SRC_COUNT + prop - UCHAR_INT_START;
+    U_ASSERT(gInclusions[inclIndex].fSet == nullptr);
+    UPropertySource src = uprops_getSource(prop);
+    const UnicodeSet *incl = getInclusionsForSource(src, errorCode);
+    if (U_FAILURE(errorCode)) {
+        return;
+    }
+
+    LocalPointer<UnicodeSet> intPropIncl(new UnicodeSet(0, 0));
+    if (intPropIncl.isNull()) {
+        errorCode = U_MEMORY_ALLOCATION_ERROR;
+        return;
+    }
+    int32_t numRanges = incl->getRangeCount();
+    int32_t prevValue = 0;
+    for (int32_t i = 0; i < numRanges; ++i) {
+        UChar32 rangeEnd = incl->getRangeEnd(i);
+        for (UChar32 c = incl->getRangeStart(i); c <= rangeEnd; ++c) {
+            // TODO: Get a UCharacterProperty.IntProperty to avoid the property dispatch.
+            int32_t value = u_getIntPropertyValue(c, prop);
+            if (value != prevValue) {
+                intPropIncl->add(c);
+                prevValue = value;
+            }
+        }
+    }
+
+    if (intPropIncl->isBogus()) {
+        errorCode = U_MEMORY_ALLOCATION_ERROR;
+        return;
+    }
+    // Compact for caching.
+    intPropIncl->compact();
+    gInclusions[inclIndex].fSet = intPropIncl.orphan();
+    ucln_common_registerCleanup(UCLN_COMMON_CHARACTERPROPERTIES, characterproperties_cleanup);
+}
+
+}  // namespace
+
+U_NAMESPACE_BEGIN
+
+const UnicodeSet *CharacterProperties::getInclusionsForProperty(
+        UProperty prop, UErrorCode &errorCode) {
+    if (U_FAILURE(errorCode)) { return nullptr; }
+    if (UCHAR_INT_START <= prop && prop < UCHAR_INT_LIMIT) {
+        int32_t inclIndex = UPROPS_SRC_COUNT + prop - UCHAR_INT_START;
+        Inclusion &i = gInclusions[inclIndex];
+        umtx_initOnce(i.fInitOnce, &initIntPropInclusion, prop, errorCode);
+        return i.fSet;
+    } else {
+        UPropertySource src = uprops_getSource(prop);
+        return getInclusionsForSource(src, errorCode);
+    }
+}
+
+U_NAMESPACE_END
+
+namespace {
+
+UnicodeSet *makeSet(UProperty property, UErrorCode &errorCode) {
+    if (U_FAILURE(errorCode)) { return nullptr; }
+    LocalPointer<UnicodeSet> set(new UnicodeSet());
+    if (set.isNull()) {
+        errorCode = U_MEMORY_ALLOCATION_ERROR;
+        return nullptr;
+    }
+    const UnicodeSet *inclusions =
+        icu::CharacterProperties::getInclusionsForProperty(property, errorCode);
+    if (U_FAILURE(errorCode)) { return nullptr; }
+    int32_t numRanges = inclusions->getRangeCount();
+    UChar32 startHasProperty = -1;
+
+    for (int32_t i = 0; i < numRanges; ++i) {
+        UChar32 rangeEnd = inclusions->getRangeEnd(i);
+        for (UChar32 c = inclusions->getRangeStart(i); c <= rangeEnd; ++c) {
+            // TODO: Get a UCharacterProperty.BinaryProperty to avoid the property dispatch.
+            if (u_hasBinaryProperty(c, property)) {
+                if (startHasProperty < 0) {
+                    // Transition from false to true.
+                    startHasProperty = c;
+                }
+            } else if (startHasProperty >= 0) {
+                // Transition from true to false.
+                set->add(startHasProperty, c - 1);
+                startHasProperty = -1;
+            }
+        }
+    }
+    if (startHasProperty >= 0) {
+        set->add(startHasProperty, 0x10FFFF);
+    }
+    set->freeze();
+    return set.orphan();
+}
+
+UCPMap *makeMap(UProperty property, UErrorCode &errorCode) {
+    if (U_FAILURE(errorCode)) { return nullptr; }
+    uint32_t nullValue = property == UCHAR_SCRIPT ? USCRIPT_UNKNOWN : 0;
+    icu::LocalUMutableCPTriePointer mutableTrie(
+        umutablecptrie_open(nullValue, nullValue, &errorCode));
+    const UnicodeSet *inclusions =
+        icu::CharacterProperties::getInclusionsForProperty(property, errorCode);
+    if (U_FAILURE(errorCode)) { return nullptr; }
+    int32_t numRanges = inclusions->getRangeCount();
+    UChar32 start = 0;
+    uint32_t value = nullValue;
+
+    for (int32_t i = 0; i < numRanges; ++i) {
+        UChar32 rangeEnd = inclusions->getRangeEnd(i);
+        for (UChar32 c = inclusions->getRangeStart(i); c <= rangeEnd; ++c) {
+            // TODO: Get a UCharacterProperty.IntProperty to avoid the property dispatch.
+            uint32_t nextValue = u_getIntPropertyValue(c, property);
+            if (value != nextValue) {
+                if (value != nullValue) {
+                    umutablecptrie_setRange(mutableTrie.getAlias(), start, c - 1, value, &errorCode);
+                }
+                start = c;
+                value = nextValue;
+            }
+        }
+    }
+    if (value != 0) {
+        umutablecptrie_setRange(mutableTrie.getAlias(), start, 0x10FFFF, value, &errorCode);
+    }
+
+    UCPTrieType type;
+    if (property == UCHAR_BIDI_CLASS || property == UCHAR_GENERAL_CATEGORY) {
+        type = UCPTRIE_TYPE_FAST;
+    } else {
+        type = UCPTRIE_TYPE_SMALL;
+    }
+    UCPTrieValueWidth valueWidth;
+    // TODO: UCharacterProperty.IntProperty
+    int32_t max = u_getIntPropertyMaxValue(property);
+    if (max <= 0xff) {
+        valueWidth = UCPTRIE_VALUE_BITS_8;
+    } else if (max <= 0xffff) {
+        valueWidth = UCPTRIE_VALUE_BITS_16;
+    } else {
+        valueWidth = UCPTRIE_VALUE_BITS_32;
+    }
+    return reinterpret_cast<UCPMap *>(
+        umutablecptrie_buildImmutable(mutableTrie.getAlias(), type, valueWidth, &errorCode));
+}
+
+}  // namespace
+
+U_NAMESPACE_USE
+
+U_CAPI const USet * U_EXPORT2
+u_getBinaryPropertySet(UProperty property, UErrorCode *pErrorCode) {
+    if (U_FAILURE(*pErrorCode)) { return nullptr; }
+    if (property < 0 || UCHAR_BINARY_LIMIT <= property) {
+        *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR;
+        return nullptr;
+    }
+    Mutex m(&cpMutex);
+    UnicodeSet *set = sets[property];
+    if (set == nullptr) {
+        sets[property] = set = makeSet(property, *pErrorCode);
+    }
+    if (U_FAILURE(*pErrorCode)) { return nullptr; }
+    return set->toUSet();
+}
+
+U_CAPI const UCPMap * U_EXPORT2
+u_getIntPropertyMap(UProperty property, UErrorCode *pErrorCode) {
+    if (U_FAILURE(*pErrorCode)) { return nullptr; }
+    if (property < UCHAR_INT_START || UCHAR_INT_LIMIT <= property) {
+        *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR;
+        return nullptr;
+    }
+    Mutex m(&cpMutex);
+    UCPMap *map = maps[property - UCHAR_INT_START];
+    if (map == nullptr) {
+        maps[property - UCHAR_INT_START] = map = makeMap(property, *pErrorCode);
+    }
+    return map;
+}
diff --git a/src/third_party/icu/source/common/chariter.cpp b/src/third_party/icu/source/common/chariter.cpp
index 2d923ea..887119a 100644
--- a/src/third_party/icu/source/common/chariter.cpp
+++ b/src/third_party/icu/source/common/chariter.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
 *   Copyright (C) 1999-2011, International Business Machines
diff --git a/src/third_party/icu/source/common/charstr.cpp b/src/third_party/icu/source/common/charstr.cpp
index a075e5b..4d2326c 100644
--- a/src/third_party/icu/source/common/charstr.cpp
+++ b/src/third_party/icu/source/common/charstr.cpp
@@ -1,10 +1,12 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *   Copyright (C) 2010-2015, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *******************************************************************************
 *   file name:  charstr.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -12,15 +14,55 @@
 *   created by: Markus W. Scherer
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/utypes.h"
+#include "unicode/putil.h"
 #include "charstr.h"
 #include "cmemory.h"
 #include "cstring.h"
 #include "uinvchar.h"
+#include "ustr_imp.h"
 
 U_NAMESPACE_BEGIN
 
+CharString::CharString(CharString&& src) U_NOEXCEPT
+        : buffer(std::move(src.buffer)), len(src.len) {
+    src.len = 0;  // not strictly necessary because we make no guarantees on the source string
+}
+
+CharString& CharString::operator=(CharString&& src) U_NOEXCEPT {
+    buffer = std::move(src.buffer);
+    len = src.len;
+    src.len = 0;  // not strictly necessary because we make no guarantees on the source string
+    return *this;
+}
+
+char *CharString::cloneData(UErrorCode &errorCode) const {
+    if (U_FAILURE(errorCode)) { return nullptr; }
+    char *p = static_cast<char *>(uprv_malloc(len + 1));
+    if (p == nullptr) {
+        errorCode = U_MEMORY_ALLOCATION_ERROR;
+        return nullptr;
+    }
+    uprv_memcpy(p, buffer.getAlias(), len + 1);
+    return p;
+}
+
+int32_t CharString::extract(char *dest, int32_t capacity, UErrorCode &errorCode) const {
+    if (U_FAILURE(errorCode)) { return len; }
+    if (capacity < 0 || (capacity > 0 && dest == nullptr)) {
+        errorCode = U_ILLEGAL_ARGUMENT_ERROR;
+        return len;
+    }
+    const char *src = buffer.getAlias();
+    if (0 < len && len <= capacity && src != dest) {
+        uprv_memcpy(dest, src, len);
+    }
+    return u_terminateChars(dest, capacity, len, &errorCode);
+}
+
 CharString &CharString::copyFrom(const CharString &s, UErrorCode &errorCode) {
     if(U_SUCCESS(errorCode) && this!=&s && ensureCapacity(s.len+1, 0, errorCode)) {
         len=s.len;
@@ -38,6 +80,18 @@
     return -1;
 }
 
+bool CharString::contains(StringPiece s) const {
+    if (s.empty()) { return false; }
+    const char *p = buffer.getAlias();
+    int32_t lastStart = len - s.length();
+    for (int32_t i = 0; i <= lastStart; ++i) {
+        if (uprv_memcmp(p + i, s.data(), s.length()) == 0) {
+            return true;
+        }
+    }
+    return false;
+}
+
 CharString &CharString::truncate(int32_t newLength) {
     if(newLength<0) {
         newLength=0;
@@ -65,7 +119,7 @@
         return *this;
     }
     if(sLength<0) {
-        sLength=uprv_strlen(s);
+        sLength= static_cast<int32_t>(uprv_strlen(s));
     }
     if(sLength>0) {
         if(s==(buffer.getAlias()+len)) {
@@ -112,15 +166,21 @@
 }
 
 CharString &CharString::appendInvariantChars(const UnicodeString &s, UErrorCode &errorCode) {
+    return appendInvariantChars(s.getBuffer(), s.length(), errorCode);
+}
+
+CharString &CharString::appendInvariantChars(const UChar* uchars, int32_t ucharsLen, UErrorCode &errorCode) {
     if(U_FAILURE(errorCode)) {
         return *this;
     }
-    if (!uprv_isInvariantUnicodeString(s)) {
+    if (!uprv_isInvariantUString(uchars, ucharsLen)) {
         errorCode = U_INVARIANT_CONVERSION_ERROR;
         return *this;
     }
-    if(ensureCapacity(len+s.length()+1, 0, errorCode)) {
-        len+=s.extract(0, 0x7fffffff, buffer.getAlias()+len, buffer.getCapacity()-len, US_INV);
+    if(ensureCapacity(len+ucharsLen+1, 0, errorCode)) {
+        u_UCharsToChars(uchars, buffer.getAlias()+len, ucharsLen);
+        len += ucharsLen;
+        buffer[len] = 0;
     }
     return *this;
 }
@@ -145,7 +205,7 @@
     return TRUE;
 }
 
-CharString &CharString::appendPathPart(const StringPiece &s, UErrorCode &errorCode) {
+CharString &CharString::appendPathPart(StringPiece s, UErrorCode &errorCode) {
     if(U_FAILURE(errorCode)) {
         return *this;
     }
@@ -154,7 +214,7 @@
     }
     char c;
     if(len>0 && (c=buffer[len-1])!=U_FILE_SEP_CHAR && c!=U_FILE_ALT_SEP_CHAR) {
-        append(U_FILE_SEP_CHAR, errorCode);
+        append(getDirSepChar(), errorCode);
     }
     append(s, errorCode);
     return *this;
@@ -164,9 +224,19 @@
     char c;
     if(U_SUCCESS(errorCode) && len>0 &&
             (c=buffer[len-1])!=U_FILE_SEP_CHAR && c!=U_FILE_ALT_SEP_CHAR) {
-        append(U_FILE_SEP_CHAR, errorCode);
+        append(getDirSepChar(), errorCode);
     }
     return *this;
 }
 
+char CharString::getDirSepChar() const {
+    char dirSepChar = U_FILE_SEP_CHAR;
+#if (U_FILE_SEP_CHAR != U_FILE_ALT_SEP_CHAR)
+    // We may need to return a different directory separator when building for Cygwin or MSYS2.
+    if(len>0 && !uprv_strchr(data(), U_FILE_SEP_CHAR) && uprv_strchr(data(), U_FILE_ALT_SEP_CHAR))
+        dirSepChar = U_FILE_ALT_SEP_CHAR;
+#endif
+    return dirSepChar;
+}
+
 U_NAMESPACE_END
diff --git a/src/third_party/icu/source/common/charstr.h b/src/third_party/icu/source/common/charstr.h
index d2e20c4..6619faa 100644
--- a/src/third_party/icu/source/common/charstr.h
+++ b/src/third_party/icu/source/common/charstr.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
 *   Copyright (c) 2001-2015, International Business Machines
@@ -39,7 +41,7 @@
 class U_COMMON_API CharString : public UMemory {
 public:
     CharString() : len(0) { buffer[0]=0; }
-    CharString(const StringPiece &s, UErrorCode &errorCode) : len(0) {
+    CharString(StringPiece s, UErrorCode &errorCode) : len(0) {
         buffer[0]=0;
         append(s, errorCode);
     }
@@ -54,6 +56,18 @@
     ~CharString() {}
 
     /**
+     * Move constructor; might leave src in an undefined state.
+     * This string will have the same contents and state that the source string had.
+     */
+    CharString(CharString &&src) U_NOEXCEPT;
+    /**
+     * Move assignment operator; might leave src in an undefined state.
+     * This string will have the same contents and state that the source string had.
+     * The behavior is undefined if *this and src are the same object.
+     */
+    CharString &operator=(CharString &&src) U_NOEXCEPT;
+
+    /**
      * Replaces this string's contents with the other string's contents.
      * CharString does not support the standard copy constructor nor
      * the assignment operator, to make copies explicit and to
@@ -68,15 +82,45 @@
 
     const char *data() const { return buffer.getAlias(); }
     char *data() { return buffer.getAlias(); }
+    /**
+     * Allocates length()+1 chars and copies the NUL-terminated data().
+     * The caller must uprv_free() the result.
+     */
+    char *cloneData(UErrorCode &errorCode) const;
+    /**
+     * Copies the contents of the string into dest.
+     * Checks if there is enough space in dest, extracts the entire string if possible,
+     * and NUL-terminates dest if possible.
+     *
+     * If the string fits into dest but cannot be NUL-terminated (length()==capacity),
+     * then the error code is set to U_STRING_NOT_TERMINATED_WARNING.
+     * If the string itself does not fit into dest (length()>capacity),
+     * then the error code is set to U_BUFFER_OVERFLOW_ERROR.
+     *
+     * @param dest Destination string buffer.
+     * @param capacity Size of the dest buffer (number of chars).
+     * @param errorCode ICU error code.
+     * @return length()
+     */
+    int32_t extract(char *dest, int32_t capacity, UErrorCode &errorCode) const;
+
+    bool operator==(StringPiece other) const {
+        return len == other.length() && (len == 0 || uprv_memcmp(data(), other.data(), len) == 0);
+    }
+    bool operator!=(StringPiece other) const {
+        return !operator==(other);
+    }
 
     /** @return last index of c, or -1 if c is not in this string */
     int32_t lastIndexOf(char c) const;
 
+    bool contains(StringPiece s) const;
+
     CharString &clear() { len=0; buffer[0]=0; return *this; }
     CharString &truncate(int32_t newLength);
 
     CharString &append(char c, UErrorCode &errorCode);
-    CharString &append(const StringPiece &s, UErrorCode &errorCode) {
+    CharString &append(StringPiece s, UErrorCode &errorCode) {
         return append(s.data(), s.length(), errorCode);
     }
     CharString &append(const CharString &s, UErrorCode &errorCode) {
@@ -109,16 +153,17 @@
                           UErrorCode &errorCode);
 
     CharString &appendInvariantChars(const UnicodeString &s, UErrorCode &errorCode);
+    CharString &appendInvariantChars(const UChar* uchars, int32_t ucharsLen, UErrorCode& errorCode);
 
     /**
      * Appends a filename/path part, e.g., a directory name.
-     * First appends a U_FILE_SEP_CHAR if necessary.
+     * First appends a U_FILE_SEP_CHAR or U_FILE_ALT_SEP_CHAR if necessary.
      * Does nothing if s is empty.
      */
-    CharString &appendPathPart(const StringPiece &s, UErrorCode &errorCode);
+    CharString &appendPathPart(StringPiece s, UErrorCode &errorCode);
 
     /**
-     * Appends a U_FILE_SEP_CHAR if this string is not empty
+     * Appends a U_FILE_SEP_CHAR or U_FILE_ALT_SEP_CHAR if this string is not empty
      * and does not already end with a U_FILE_SEP_CHAR or U_FILE_ALT_SEP_CHAR.
      */
     CharString &ensureEndsWithFileSeparator(UErrorCode &errorCode);
@@ -131,6 +176,12 @@
 
     CharString(const CharString &other); // forbid copying of this class
     CharString &operator=(const CharString &other); // forbid copying of this class
+
+    /**
+     * Returns U_FILE_ALT_SEP_CHAR if found in string, and U_FILE_SEP_CHAR is not found.
+     * Otherwise returns U_FILE_SEP_CHAR.
+     */
+    char getDirSepChar() const;
 };
 
 U_NAMESPACE_END
diff --git a/src/third_party/icu/source/common/charstrmap.h b/src/third_party/icu/source/common/charstrmap.h
new file mode 100644
index 0000000..3320a46
--- /dev/null
+++ b/src/third_party/icu/source/common/charstrmap.h
@@ -0,0 +1,55 @@
+// © 2020 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+// charstrmap.h
+// created: 2020sep01 Frank Yung-Fong Tang
+
+#ifndef __CHARSTRMAP_H__
+#define __CHARSTRMAP_H__
+
+#include <utility>
+#include "unicode/utypes.h"
+#include "unicode/uobject.h"
+#include "uhash.h"
+
+U_NAMESPACE_BEGIN
+
+/**
+ * Map of const char * keys & values.
+ * Stores pointers as is: Does not own/copy/adopt/release strings.
+ */
+class CharStringMap final : public UMemory {
+public:
+    /** Constructs an unusable non-map. */
+    CharStringMap() : map(nullptr) {}
+    CharStringMap(int32_t size, UErrorCode &errorCode) {
+        map = uhash_openSize(uhash_hashChars, uhash_compareChars, uhash_compareChars,
+                             size, &errorCode);
+    }
+    CharStringMap(CharStringMap &&other) U_NOEXCEPT : map(other.map) {
+        other.map = nullptr;
+    }
+    CharStringMap(const CharStringMap &other) = delete;
+    ~CharStringMap() {
+        uhash_close(map);
+    }
+
+    CharStringMap &operator=(CharStringMap &&other) U_NOEXCEPT {
+        map = other.map;
+        other.map = nullptr;
+        return *this;
+    }
+    CharStringMap &operator=(const CharStringMap &other) = delete;
+
+    const char *get(const char *key) const { return static_cast<const char *>(uhash_get(map, key)); }
+    void put(const char *key, const char *value, UErrorCode &errorCode) {
+        uhash_put(map, const_cast<char *>(key), const_cast<char *>(value), &errorCode);
+    }
+
+private:
+    UHashtable *map;
+};
+
+U_NAMESPACE_END
+
+#endif  //  __CHARSTRMAP_H__
diff --git a/src/third_party/icu/source/common/cmemory.c b/src/third_party/icu/source/common/cmemory.cpp
similarity index 83%
rename from src/third_party/icu/source/common/cmemory.c
rename to src/third_party/icu/source/common/cmemory.cpp
index a6576d9..e40fa93 100644
--- a/src/third_party/icu/source/common/cmemory.c
+++ b/src/third_party/icu/source/common/cmemory.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
@@ -18,9 +20,11 @@
 *
 ******************************************************************************
 */
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
 #include "starboard/client_porting/poem/stdio_poem.h"
 #include "starboard/client_porting/poem/assert_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/uclean.h"
 #include "cmemory.h"
 #include "putilimp.h"
@@ -39,37 +43,15 @@
 static UMemFreeFn     *pFree;
 
 #if U_DEBUG && defined(UPRV_MALLOC_COUNT)
-#if !defined(STARBOARD)
+#if defined(STARBOARD)
+#include "starboard/client_porting/poem/stdio_poem.h"
+#else
 #include <stdio.h>
 #endif
 static int n=0;
 static long b=0; 
 #endif
 
-#if U_DEBUG
-
-static char gValidMemorySink = 0;
-
-U_CAPI void uprv_checkValidMemory(const void *p, size_t n) {
-    /*
-     * Access the memory to ensure that it's all valid.
-     * Load and save a computed value to try to ensure that the compiler
-     * does not throw away the whole loop.
-     * A thread analyzer might complain about un-mutexed access to gValidMemorySink
-     * which is true but harmless because no one ever uses the value in gValidMemorySink.
-     */
-    const char *s = (const char *)p;
-    char c = gValidMemorySink;
-    size_t i;
-    U_ASSERT(p != NULL);
-    for(i = 0; i < n; ++i) {
-        c ^= s[i];
-    }
-    gValidMemorySink = c;
-}
-
-#endif  /* U_DEBUG */
-
 U_CAPI void * U_EXPORT2
 uprv_malloc(size_t s) {
 #if U_DEBUG && defined(UPRV_MALLOC_COUNT)
diff --git a/src/third_party/icu/source/common/cmemory.h b/src/third_party/icu/source/common/cmemory.h
index b7d4feb..57dd917 100644
--- a/src/third_party/icu/source/common/cmemory.h
+++ b/src/third_party/icu/source/common/cmemory.h
@@ -1,7 +1,9 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
-*   Copyright (C) 1997-2015, International Business Machines
+*   Copyright (C) 1997-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *
 ******************************************************************************
@@ -26,7 +28,10 @@
 
 #include "unicode/utypes.h"
 
-#if !defined(STARBOARD)
+#if defined(STARBOARD)
+#include "starboard/client_porting/poem/string_poem.h"
+#include "starboard/client_porting/poem/assert_poem.h"
+#else
 #include <stddef.h>
 #include <string.h>
 #endif
@@ -36,31 +41,10 @@
 #include <stdio.h>
 #endif
 
-#if U_DEBUG
-
-/*
- * The C++ standard requires that the source pointer for memcpy() & memmove()
- * is valid, not NULL, and not at the end of an allocated memory block.
- * In debug mode, we read one byte from the source point to verify that it's
- * a valid, readable pointer.
- */
-
-U_CAPI void uprv_checkValidMemory(const void *p, size_t n);
-
-#define uprv_memcpy(dst, src, size) ( \
-    uprv_checkValidMemory(src, 1), \
-    U_STANDARD_CPP_NAMESPACE memcpy(dst, src, size))
-#define uprv_memmove(dst, src, size) ( \
-    uprv_checkValidMemory(src, 1), \
-    U_STANDARD_CPP_NAMESPACE memmove(dst, src, size))
-
-#else
 
 #define uprv_memcpy(dst, src, size) U_STANDARD_CPP_NAMESPACE memcpy(dst, src, size)
 #define uprv_memmove(dst, src, size) U_STANDARD_CPP_NAMESPACE memmove(dst, src, size)
 
-#endif  /* U_DEBUG */
-
 /**
  * \def UPRV_LENGTHOF
  * Convenience macro to determine the length of a fixed array at compile-time.
@@ -71,6 +55,7 @@
 #define UPRV_LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0]))
 #define uprv_memset(buffer, mark, size) U_STANDARD_CPP_NAMESPACE memset(buffer, mark, size)
 #define uprv_memcmp(buffer1, buffer2, size) U_STANDARD_CPP_NAMESPACE memcmp(buffer1, buffer2,size)
+#define uprv_memchr(ptr, value, num) U_STANDARD_CPP_NAMESPACE memchr(ptr, value, num)
 
 U_CAPI void * U_EXPORT2
 uprv_malloc(size_t s) U_MALLOC_ATTR U_ALLOC_SIZE_ATTR(1);
@@ -85,37 +70,36 @@
 uprv_calloc(size_t num, size_t size) U_MALLOC_ATTR U_ALLOC_SIZE_ATTR2(1,2);
 
 /**
- * This should align the memory properly on any machine.
- * This is very useful for the safeClone functions.
- */
-typedef union {
-    long    t1;
-    double  t2;
-    void   *t3;
-} UAlignedMemory;
-
-/**
  * Get the least significant bits of a pointer (a memory address).
  * For example, with a mask of 3, the macro gets the 2 least significant bits,
  * which will be 0 if the pointer is 32-bit (4-byte) aligned.
  *
- * ptrdiff_t is the most appropriate integer type to cast to.
- * size_t should work too, since on most (or all?) platforms it has the same
- * width as ptrdiff_t.
+ * uintptr_t is the most appropriate integer type to cast to.
  */
-#define U_POINTER_MASK_LSB(ptr, mask) (((ptrdiff_t)(char *)(ptr)) & (mask))
+#define U_POINTER_MASK_LSB(ptr, mask) ((uintptr_t)(ptr) & (mask))
 
 /**
- * Get the amount of bytes that a pointer is off by from
- * the previous UAlignedMemory-aligned pointer.
+ * Create & return an instance of "type" in statically allocated storage.
+ * e.g.
+ *    static std::mutex *myMutex = STATIC_NEW(std::mutex);
+ * To destroy an object created in this way, invoke the destructor explicitly, e.g.
+ *    myMutex->~mutex();
+ * DO NOT use delete.
+ * DO NOT use with class UMutex, which has specific support for static instances.
+ *
+ * STATIC_NEW is intended for use when
+ *   - We want a static (or global) object.
+ *   - We don't want it to ever be destructed, or to explicitly control destruction,
+ *     to avoid use-after-destruction problems.
+ *   - We want to avoid an ordinary heap allocated object,
+ *     to avoid the possibility of memory allocation failures, and
+ *     to avoid memory leak reports, from valgrind, for example.
+ * This is defined as a macro rather than a template function because each invocation
+ * must define distinct static storage for the object being returned.
  */
-#define U_ALIGNMENT_OFFSET(ptr) U_POINTER_MASK_LSB(ptr, sizeof(UAlignedMemory) - 1)
-
-/**
- * Get the amount of bytes to add to a pointer
- * in order to get the next UAlignedMemory-aligned address.
- */
-#define U_ALIGNMENT_OFFSET_UP(ptr) (sizeof(UAlignedMemory) - U_ALIGNMENT_OFFSET(ptr))
+#define STATIC_NEW(type) [] () { \
+    alignas(type) static char storage[sizeof(type)]; \
+    return new(storage) type();} ()
 
 /**
   *  Heap clean up function, called from u_cleanup()
@@ -143,6 +127,9 @@
 
 #ifdef __cplusplus
 
+#include <utility>
+#include "unicode/uobject.h"
+
 U_NAMESPACE_BEGIN
 
 /**
@@ -155,12 +142,13 @@
 template<typename T>
 class LocalMemory : public LocalPointerBase<T> {
 public:
+    using LocalPointerBase<T>::operator*;
+    using LocalPointerBase<T>::operator->;
     /**
      * Constructor takes ownership.
      * @param p simple pointer to an array of T items that is adopted
      */
     explicit LocalMemory(T *p=NULL) : LocalPointerBase<T>(p) {}
-#if U_HAVE_RVALUE_REFERENCES
     /**
      * Move constructor, leaves src with isNull().
      * @param src source smart pointer
@@ -168,14 +156,12 @@
     LocalMemory(LocalMemory<T> &&src) U_NOEXCEPT : LocalPointerBase<T>(src.ptr) {
         src.ptr=NULL;
     }
-#endif
     /**
      * Destructor deletes the memory it owns.
      */
     ~LocalMemory() {
         uprv_free(LocalPointerBase<T>::ptr);
     }
-#if U_HAVE_RVALUE_REFERENCES
     /**
      * Move assignment operator, leaves src with isNull().
      * The behavior is undefined if *this and src are the same object.
@@ -183,19 +169,7 @@
      * @return *this
      */
     LocalMemory<T> &operator=(LocalMemory<T> &&src) U_NOEXCEPT {
-        return moveFrom(src);
-    }
-#endif
-    /**
-     * Move assignment, leaves src with isNull().
-     * The behavior is undefined if *this and src are the same object.
-     *
-     * Can be called explicitly, does not need C++11 support.
-     * @param src source smart pointer
-     * @return *this
-     */
-    LocalMemory<T> &moveFrom(LocalMemory<T> &src) U_NOEXCEPT {
-        delete[] LocalPointerBase<T>::ptr;
+        uprv_free(LocalPointerBase<T>::ptr);
         LocalPointerBase<T>::ptr=src.ptr;
         src.ptr=NULL;
         return *this;
@@ -281,7 +255,7 @@
                 if(length>newCapacity) {
                     length=newCapacity;
                 }
-                uprv_memcpy(p, LocalPointerBase<T>::ptr, length*sizeof(T));
+                uprv_memcpy(p, LocalPointerBase<T>::ptr, (size_t)length*sizeof(T));
             }
             uprv_free(LocalPointerBase<T>::ptr);
             LocalPointerBase<T>::ptr=p;
@@ -302,19 +276,56 @@
  *
  * Unlike LocalMemory and LocalArray, this class never adopts
  * (takes ownership of) another array.
+ *
+ * WARNING: MaybeStackArray only works with primitive (plain-old data) types.
+ * It does NOT know how to call a destructor! If you work with classes with
+ * destructors, consider:
+ *
+ * - LocalArray in localpointer.h if you know the length ahead of time
+ * - MaybeStackVector if you know the length at runtime
  */
 template<typename T, int32_t stackCapacity>
 class MaybeStackArray {
 public:
+    // No heap allocation. Use only on the stack.
+    static void* U_EXPORT2 operator new(size_t) U_NOEXCEPT = delete;
+    static void* U_EXPORT2 operator new[](size_t) U_NOEXCEPT = delete;
+#if U_HAVE_PLACEMENT_NEW
+    static void* U_EXPORT2 operator new(size_t, void*) U_NOEXCEPT = delete;
+#endif
+
     /**
      * Default constructor initializes with internal T[stackCapacity] buffer.
      */
-    MaybeStackArray() : ptr(stackArray), capacity(stackCapacity), needToRelease(FALSE) {}
+    MaybeStackArray() : ptr(stackArray), capacity(stackCapacity), needToRelease(false) {}
+    /**
+     * Automatically allocates the heap array if the argument is larger than the stack capacity.
+     * Intended for use when an approximate capacity is known at compile time but the true
+     * capacity is not known until runtime.
+     */
+    MaybeStackArray(int32_t newCapacity, UErrorCode status) : MaybeStackArray() {
+        if (U_FAILURE(status)) {
+            return;
+        }
+        if (capacity < newCapacity) {
+            if (resize(newCapacity) == nullptr) {
+                status = U_MEMORY_ALLOCATION_ERROR;
+            }
+        }
+    }
     /**
      * Destructor deletes the array (if owned).
      */
     ~MaybeStackArray() { releaseArray(); }
     /**
+     * Move constructor: transfers ownership or copies the stack array.
+     */
+    MaybeStackArray(MaybeStackArray<T, stackCapacity> &&src) U_NOEXCEPT;
+    /**
+     * Move assignment: transfers ownership or copies the stack array.
+     */
+    MaybeStackArray<T, stackCapacity> &operator=(MaybeStackArray<T, stackCapacity> &&src) U_NOEXCEPT;
+    /**
      * Returns the array capacity (number of T items).
      * @return array capacity
      */
@@ -356,7 +367,7 @@
             releaseArray();
             ptr=otherArray;
             capacity=otherCapacity;
-            needToRelease=FALSE;
+            needToRelease=false;
         }
     }
     /**
@@ -381,6 +392,20 @@
      *         caller becomes responsible for deleting the array
      */
     inline T *orphanOrClone(int32_t length, int32_t &resultCapacity);
+
+protected:
+    // Resizes the array to the size of src, then copies the contents of src.
+    void copyFrom(const MaybeStackArray &src, UErrorCode &status) {
+        if (U_FAILURE(status)) {
+            return;
+        }
+        if (this->resize(src.capacity, 0) == NULL) {
+            status = U_MEMORY_ALLOCATION_ERROR;
+            return;
+        }
+        uprv_memcpy(this->ptr, src.ptr, (size_t)capacity * sizeof(T));
+    }
+
 private:
     T *ptr;
     int32_t capacity;
@@ -391,33 +416,52 @@
             uprv_free(ptr);
         }
     }
+    void resetToStackArray() {
+        ptr=stackArray;
+        capacity=stackCapacity;
+        needToRelease=false;
+    }
     /* No comparison operators with other MaybeStackArray's. */
-    bool operator==(const MaybeStackArray & /*other*/) {return FALSE;}
-    bool operator!=(const MaybeStackArray & /*other*/) {return TRUE;}
+    bool operator==(const MaybeStackArray & /*other*/) = delete;
+    bool operator!=(const MaybeStackArray & /*other*/) = delete;
     /* No ownership transfer: No copy constructor, no assignment operator. */
-    MaybeStackArray(const MaybeStackArray & /*other*/) {}
-    void operator=(const MaybeStackArray & /*other*/) {}
-
-    // No heap allocation. Use only on the stack.
-    //   (Declaring these functions private triggers a cascade of problems:
-    //      MSVC insists on exporting an instantiation of MaybeStackArray, which
-    //      requires that all functions be defined.
-    //      An empty implementation of new() is rejected, it must return a value.
-    //      Returning NULL is rejected by gcc for operator new.
-    //      The expedient thing is just not to override operator new.
-    //      While relatively pointless, heap allocated instances will function.
-    // static void * U_EXPORT2 operator new(size_t size); 
-    // static void * U_EXPORT2 operator new[](size_t size);
-#if U_HAVE_PLACEMENT_NEW
-    // static void * U_EXPORT2 operator new(size_t, void *ptr);
-#endif
+    MaybeStackArray(const MaybeStackArray & /*other*/) = delete;
+    void operator=(const MaybeStackArray & /*other*/) = delete;
 };
 
 template<typename T, int32_t stackCapacity>
+icu::MaybeStackArray<T, stackCapacity>::MaybeStackArray(
+        MaybeStackArray <T, stackCapacity>&& src) U_NOEXCEPT
+        : ptr(src.ptr), capacity(src.capacity), needToRelease(src.needToRelease) {
+    if (src.ptr == src.stackArray) {
+        ptr = stackArray;
+        uprv_memcpy(stackArray, src.stackArray, sizeof(T) * src.capacity);
+    } else {
+        src.resetToStackArray();  // take ownership away from src
+    }
+}
+
+template<typename T, int32_t stackCapacity>
+inline MaybeStackArray <T, stackCapacity>&
+MaybeStackArray<T, stackCapacity>::operator=(MaybeStackArray <T, stackCapacity>&& src) U_NOEXCEPT {
+    releaseArray();  // in case this instance had its own memory allocated
+    capacity = src.capacity;
+    needToRelease = src.needToRelease;
+    if (src.ptr == src.stackArray) {
+        ptr = stackArray;
+        uprv_memcpy(stackArray, src.stackArray, sizeof(T) * src.capacity);
+    } else {
+        ptr = src.ptr;
+        src.resetToStackArray();  // take ownership away from src
+    }
+    return *this;
+}
+
+template<typename T, int32_t stackCapacity>
 inline T *MaybeStackArray<T, stackCapacity>::resize(int32_t newCapacity, int32_t length) {
     if(newCapacity>0) {
 #if U_DEBUG && defined(UPRV_MALLOC_COUNT)
-      ::fprintf(::stderr,"MaybeStacArray (resize) alloc %d * %lu\n", newCapacity,sizeof(T));
+        ::fprintf(::stderr, "MaybeStackArray (resize) alloc %d * %lu\n", newCapacity, sizeof(T));
 #endif
         T *p=(T *)uprv_malloc(newCapacity*sizeof(T));
         if(p!=NULL) {
@@ -428,12 +472,12 @@
                 if(length>newCapacity) {
                     length=newCapacity;
                 }
-                uprv_memcpy(p, ptr, length*sizeof(T));
+                uprv_memcpy(p, ptr, (size_t)length*sizeof(T));
             }
             releaseArray();
             ptr=p;
             capacity=newCapacity;
-            needToRelease=TRUE;
+            needToRelease=true;
         }
         return p;
     } else {
@@ -459,12 +503,10 @@
         if(p==NULL) {
             return NULL;
         }
-        uprv_memcpy(p, ptr, length*sizeof(T));
+        uprv_memcpy(p, ptr, (size_t)length*sizeof(T));
     }
     resultCapacity=length;
-    ptr=stackArray;
-    capacity=stackCapacity;
-    needToRelease=FALSE;
+    resetToStackArray();
     return p;
 }
 
@@ -481,10 +523,17 @@
 template<typename H, typename T, int32_t stackCapacity>
 class MaybeStackHeaderAndArray {
 public:
+    // No heap allocation. Use only on the stack.
+    static void* U_EXPORT2 operator new(size_t) U_NOEXCEPT = delete;
+    static void* U_EXPORT2 operator new[](size_t) U_NOEXCEPT = delete;
+#if U_HAVE_PLACEMENT_NEW
+    static void* U_EXPORT2 operator new(size_t, void*) U_NOEXCEPT = delete;
+#endif
+
     /**
      * Default constructor initializes with internal H+T[stackCapacity] buffer.
      */
-    MaybeStackHeaderAndArray() : ptr(&stackHeader), capacity(stackCapacity), needToRelease(FALSE) {}
+    MaybeStackHeaderAndArray() : ptr(&stackHeader), capacity(stackCapacity), needToRelease(false) {}
     /**
      * Destructor deletes the memory (if owned).
      */
@@ -533,7 +582,7 @@
             releaseMemory();
             ptr=otherMemory;
             capacity=otherCapacity;
-            needToRelease=FALSE;
+            needToRelease=false;
         }
     }
     /**
@@ -572,20 +621,11 @@
         }
     }
     /* No comparison operators with other MaybeStackHeaderAndArray's. */
-    bool operator==(const MaybeStackHeaderAndArray & /*other*/) {return FALSE;}
-    bool operator!=(const MaybeStackHeaderAndArray & /*other*/) {return TRUE;}
+    bool operator==(const MaybeStackHeaderAndArray & /*other*/) {return false;}
+    bool operator!=(const MaybeStackHeaderAndArray & /*other*/) {return true;}
     /* No ownership transfer: No copy constructor, no assignment operator. */
     MaybeStackHeaderAndArray(const MaybeStackHeaderAndArray & /*other*/) {}
     void operator=(const MaybeStackHeaderAndArray & /*other*/) {}
-
-    // No heap allocation. Use only on the stack.
-    //   (Declaring these functions private triggers a cascade of problems;
-    //    see the MaybeStackArray class for details.)
-    // static void * U_EXPORT2 operator new(size_t size); 
-    // static void * U_EXPORT2 operator new[](size_t size);
-#if U_HAVE_PLACEMENT_NEW
-    // static void * U_EXPORT2 operator new(size_t, void *ptr);
-#endif
 };
 
 template<typename H, typename T, int32_t stackCapacity>
@@ -607,11 +647,11 @@
                     length=newCapacity;
                 }
             }
-            uprv_memcpy(p, ptr, sizeof(H)+length*sizeof(T));
+            uprv_memcpy(p, ptr, sizeof(H)+(size_t)length*sizeof(T));
             releaseMemory();
             ptr=p;
             capacity=newCapacity;
-            needToRelease=TRUE;
+            needToRelease=true;
         }
         return p;
     } else {
@@ -638,15 +678,176 @@
         if(p==NULL) {
             return NULL;
         }
-        uprv_memcpy(p, ptr, sizeof(H)+length*sizeof(T));
+        uprv_memcpy(p, ptr, sizeof(H)+(size_t)length*sizeof(T));
     }
     resultCapacity=length;
     ptr=&stackHeader;
     capacity=stackCapacity;
-    needToRelease=FALSE;
+    needToRelease=false;
     return p;
 }
 
+/**
+ * A simple memory management class that creates new heap allocated objects (of
+ * any class that has a public constructor), keeps track of them and eventually
+ * deletes them all in its own destructor.
+ *
+ * A typical use-case would be code like this:
+ *
+ *     MemoryPool<MyType> pool;
+ *
+ *     MyType* o1 = pool.create();
+ *     if (o1 != nullptr) {
+ *         foo(o1);
+ *     }
+ *
+ *     MyType* o2 = pool.create(1, 2, 3);
+ *     if (o2 != nullptr) {
+ *         bar(o2);
+ *     }
+ *
+ *     // MemoryPool will take care of deleting the MyType objects.
+ *
+ * It doesn't do anything more than that, and is intentionally kept minimalist.
+ */
+template<typename T, int32_t stackCapacity = 8>
+class MemoryPool : public UMemory {
+public:
+    MemoryPool() : fCount(0), fPool() {}
+
+    ~MemoryPool() {
+        for (int32_t i = 0; i < fCount; ++i) {
+            delete fPool[i];
+        }
+    }
+
+    MemoryPool(const MemoryPool&) = delete;
+    MemoryPool& operator=(const MemoryPool&) = delete;
+
+    MemoryPool(MemoryPool&& other) U_NOEXCEPT : fCount(other.fCount),
+                                                fPool(std::move(other.fPool)) {
+        other.fCount = 0;
+    }
+
+    MemoryPool& operator=(MemoryPool&& other) U_NOEXCEPT {
+        fCount = other.fCount;
+        fPool = std::move(other.fPool);
+        other.fCount = 0;
+        return *this;
+    }
+
+    /**
+     * Creates a new object of typename T, by forwarding any and all arguments
+     * to the typename T constructor.
+     *
+     * @param args Arguments to be forwarded to the typename T constructor.
+     * @return A pointer to the newly created object, or nullptr on error.
+     */
+    template<typename... Args>
+    T* create(Args&&... args) {
+        int32_t capacity = fPool.getCapacity();
+        if (fCount == capacity &&
+            fPool.resize(capacity == stackCapacity ? 4 * capacity : 2 * capacity,
+                         capacity) == nullptr) {
+            return nullptr;
+        }
+        return fPool[fCount++] = new T(std::forward<Args>(args)...);
+    }
+
+    template <typename... Args>
+    T* createAndCheckErrorCode(UErrorCode &status, Args &&... args) {
+        if (U_FAILURE(status)) {
+            return nullptr;
+        }
+        T *pointer = this->create(args...);
+        if (U_SUCCESS(status) && pointer == nullptr) {
+            status = U_MEMORY_ALLOCATION_ERROR;
+        }
+        return pointer;
+    }
+
+    /**
+     * @return Number of elements that have been allocated.
+     */
+    int32_t count() const {
+        return fCount;
+    }
+
+protected:
+    int32_t fCount;
+    MaybeStackArray<T*, stackCapacity> fPool;
+};
+
+/**
+ * An internal Vector-like implementation based on MemoryPool.
+ *
+ * Heap-allocates each element and stores pointers.
+ *
+ * To append an item to the vector, use emplaceBack.
+ *
+ *     MaybeStackVector<MyType> vector;
+ *     MyType* element = vector.emplaceBack();
+ *     if (!element) {
+ *         status = U_MEMORY_ALLOCATION_ERROR;
+ *     }
+ *     // do stuff with element
+ *
+ * To loop over the vector, use a for loop with indices:
+ *
+ *     for (int32_t i = 0; i < vector.length(); i++) {
+ *         MyType* element = vector[i];
+ *     }
+ */
+template<typename T, int32_t stackCapacity = 8>
+class MaybeStackVector : protected MemoryPool<T, stackCapacity> {
+public:
+    using MemoryPool<T, stackCapacity>::MemoryPool;
+    using MemoryPool<T, stackCapacity>::operator=;
+
+    template<typename... Args>
+    T* emplaceBack(Args&&... args) {
+        return this->create(args...);
+    }
+
+    template <typename... Args>
+    T *emplaceBackAndCheckErrorCode(UErrorCode &status, Args &&... args) {
+        return this->createAndCheckErrorCode(status, args...);
+    }
+
+    int32_t length() const {
+        return this->fCount;
+    }
+
+    T** getAlias() {
+        return this->fPool.getAlias();
+    }
+
+    const T *const *getAlias() const {
+        return this->fPool.getAlias();
+    }
+
+    /**
+     * Array item access (read-only).
+     * No index bounds check.
+     * @param i array index
+     * @return reference to the array item
+     */
+    const T* operator[](ptrdiff_t i) const {
+        return this->fPool[i];
+    }
+
+    /**
+     * Array item access (writable).
+     * No index bounds check.
+     * @param i array index
+     * @return reference to the array item
+     */
+    T* operator[](ptrdiff_t i) {
+        return this->fPool[i];
+    }
+};
+
+
 U_NAMESPACE_END
 
 #endif  /* __cplusplus */
diff --git a/src/third_party/icu/source/common/common.rc b/src/third_party/icu/source/common/common.rc
index e0820bb..020abac 100644
--- a/src/third_party/icu/source/common/common.rc
+++ b/src/third_party/icu/source/common/common.rc
@@ -1,6 +1,8 @@
 // Do not edit with Microsoft Developer Studio Resource Editor.
 //   It will permanently substitute version numbers that are intended to be
 //   picked up by the pre-processor during each build.
+// Copyright (C) 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 // Copyright (c) 2001-2010 International Business Machines
 // Corporation and others. All Rights Reserved.
 //
diff --git a/src/third_party/icu/source/common/common.vcxproj b/src/third_party/icu/source/common/common.vcxproj
deleted file mode 100644
index 18ca9a3..0000000
--- a/src/third_party/icu/source/common/common.vcxproj
+++ /dev/null
@@ -1,1779 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup Label="ProjectConfigurations">
-    <ProjectConfiguration Include="Debug|Win32">
-      <Configuration>Debug</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Debug|x64">
-      <Configuration>Debug</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|Win32">
-      <Configuration>Release</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|x64">
-      <Configuration>Release</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-  </ItemGroup>
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>{73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}</ProjectGuid>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
-    <ConfigurationType>DynamicLibrary</ConfigurationType>
-    <UseOfMfc>false</UseOfMfc>
-    <CharacterSet>MultiByte</CharacterSet>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
-    <ConfigurationType>DynamicLibrary</ConfigurationType>
-    <UseOfMfc>false</UseOfMfc>
-    <CharacterSet>MultiByte</CharacterSet>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
-    <ConfigurationType>DynamicLibrary</ConfigurationType>
-    <UseOfMfc>false</UseOfMfc>
-    <CharacterSet>MultiByte</CharacterSet>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
-    <ConfigurationType>DynamicLibrary</ConfigurationType>
-    <UseOfMfc>false</UseOfMfc>
-    <CharacterSet>MultiByte</CharacterSet>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
-  <ImportGroup Label="ExtensionSettings">
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
-  </ImportGroup>
-  <PropertyGroup Label="UserMacros" />
-  <PropertyGroup>
-    <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\..\..\lib\</OutDir>
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\x86\Release\</IntDir>
-    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\..\..\lib\</OutDir>
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\x86\Debug\</IntDir>
-    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\x64\Release\</OutDir>
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\x64\Release\</IntDir>
-    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\x64\Debug\</OutDir>
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\x64\Debug\</IntDir>
-    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
-  </PropertyGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <Midl>
-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <MkTypLibCompatible>true</MkTypLibCompatible>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-      <TargetEnvironment>Win32</TargetEnvironment>
-      <TypeLibraryName>.\..\..\lib\icuuc.tlb</TypeLibraryName>
-    </Midl>
-    <ClCompile>
-      <PreprocessorDefinitions>U_ATTRIBUTE_DEPRECATED=;WIN32;NDEBUG;_CRT_SECURE_NO_DEPRECATE;U_COMMON_IMPLEMENTATION;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <StringPooling>true</StringPooling>
-      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <DisableLanguageExtensions>false</DisableLanguageExtensions>
-      <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
-      <PrecompiledHeaderOutputFile>.\x86\Release/common.pch</PrecompiledHeaderOutputFile>
-      <AssemblerListingLocation>.\x86\Release/</AssemblerListingLocation>
-      <ObjectFileName>.\x86\Release/</ObjectFileName>
-      <ProgramDataBaseFileName>.\x86\Release/</ProgramDataBaseFileName>
-      <WarningLevel>Level3</WarningLevel>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-    </ClCompile>
-    <ResourceCompile>
-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <Culture>0x0409</Culture>
-    </ResourceCompile>
-    <Link>
-      <OutputFile>..\..\bin\icuuc56.dll</OutputFile>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-      <ProgramDatabaseFile>.\..\..\lib\icuuc.pdb</ProgramDatabaseFile>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <BaseAddress>0x4a800000</BaseAddress>
-      <RandomizedBaseAddress>false</RandomizedBaseAddress>
-      <DataExecutionPrevention>
-      </DataExecutionPrevention>
-      <ImportLibrary>..\..\lib\icuuc.lib</ImportLibrary>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <Midl>
-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <MkTypLibCompatible>true</MkTypLibCompatible>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-      <TargetEnvironment>Win32</TargetEnvironment>
-      <TypeLibraryName>.\..\..\lib\icuucd.tlb</TypeLibraryName>
-    </Midl>
-    <ClCompile>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>U_ATTRIBUTE_DEPRECATED=;WIN32;_DEBUG;_CRT_SECURE_NO_DEPRECATE;U_COMMON_IMPLEMENTATION;RBBI_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
-      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
-      <BufferSecurityCheck>true</BufferSecurityCheck>
-      <DisableLanguageExtensions>false</DisableLanguageExtensions>
-      <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
-      <PrecompiledHeaderOutputFile>.\x86\Debug/common.pch</PrecompiledHeaderOutputFile>
-      <AssemblerListingLocation>.\x86\Debug/</AssemblerListingLocation>
-      <ObjectFileName>.\x86\Debug/</ObjectFileName>
-      <ProgramDataBaseFileName>.\x86\Debug/</ProgramDataBaseFileName>
-      <BrowseInformation>true</BrowseInformation>
-      <WarningLevel>Level3</WarningLevel>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
-    </ClCompile>
-    <ResourceCompile>
-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <Culture>0x0409</Culture>
-    </ResourceCompile>
-    <Link>
-      <OutputFile>..\..\bin\icuuc56d.dll</OutputFile>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <ProgramDatabaseFile>.\..\..\lib\icuucd.pdb</ProgramDatabaseFile>
-      <BaseAddress>0x4a800000</BaseAddress>
-      <RandomizedBaseAddress>false</RandomizedBaseAddress>
-      <DataExecutionPrevention>
-      </DataExecutionPrevention>
-      <ImportLibrary>..\..\lib\icuucd.lib</ImportLibrary>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <Midl>
-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <MkTypLibCompatible>true</MkTypLibCompatible>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-      <TargetEnvironment>X64</TargetEnvironment>
-      <TypeLibraryName>.\..\..\lib64\icuuc.tlb</TypeLibraryName>
-    </Midl>
-    <ClCompile>
-      <PreprocessorDefinitions>U_ATTRIBUTE_DEPRECATED=;WIN64;WIN32;NDEBUG;_CRT_SECURE_NO_DEPRECATE;U_COMMON_IMPLEMENTATION;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <StringPooling>true</StringPooling>
-      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <DisableLanguageExtensions>false</DisableLanguageExtensions>
-      <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
-      <PrecompiledHeaderOutputFile>.\x64\Release/common.pch</PrecompiledHeaderOutputFile>
-      <AssemblerListingLocation>.\x64\Release/</AssemblerListingLocation>
-      <ObjectFileName>.\x64\Release/</ObjectFileName>
-      <ProgramDataBaseFileName>.\x64\Release/</ProgramDataBaseFileName>
-      <WarningLevel>Level3</WarningLevel>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-    </ClCompile>
-    <ResourceCompile>
-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <Culture>0x0409</Culture>
-    </ResourceCompile>
-    <Link>
-      <OutputFile>..\..\bin64\icuuc56.dll</OutputFile>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-      <ProgramDatabaseFile>.\..\..\lib64\icuuc.pdb</ProgramDatabaseFile>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <BaseAddress>0x4a800000</BaseAddress>
-      <ImportLibrary>..\..\lib64\icuuc.lib</ImportLibrary>
-      <TargetMachine>MachineX64</TargetMachine>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <Midl>
-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <MkTypLibCompatible>true</MkTypLibCompatible>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-      <TargetEnvironment>X64</TargetEnvironment>
-      <TypeLibraryName>.\..\..\lib64\icuucd.tlb</TypeLibraryName>
-    </Midl>
-    <ClCompile>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>U_ATTRIBUTE_DEPRECATED=;WIN64;WIN32;_DEBUG;_CRT_SECURE_NO_DEPRECATE;U_COMMON_IMPLEMENTATION;RBBI_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
-      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
-      <BufferSecurityCheck>true</BufferSecurityCheck>
-      <DisableLanguageExtensions>false</DisableLanguageExtensions>
-      <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
-      <PrecompiledHeaderOutputFile>.\x64\Debug/common.pch</PrecompiledHeaderOutputFile>
-      <AssemblerListingLocation>.\x64\Debug/</AssemblerListingLocation>
-      <ObjectFileName>.\x64\Debug/</ObjectFileName>
-      <ProgramDataBaseFileName>.\x64\Debug/</ProgramDataBaseFileName>
-      <BrowseInformation>true</BrowseInformation>
-      <WarningLevel>Level3</WarningLevel>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-    </ClCompile>
-    <ResourceCompile>
-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <Culture>0x0409</Culture>
-    </ResourceCompile>
-    <Link>
-      <OutputFile>..\..\bin64\icuuc56d.dll</OutputFile>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <ProgramDatabaseFile>.\..\..\lib64\icuucd.pdb</ProgramDatabaseFile>
-      <BaseAddress>0x4a800000</BaseAddress>
-      <ImportLibrary>..\..\lib64\icuucd.lib</ImportLibrary>
-      <TargetMachine>MachineX64</TargetMachine>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemGroup>
-    <ClCompile Include="filteredbrk.cpp" />
-    <ClCompile Include="ubidi.c" />
-    <ClCompile Include="ubidi_props.c" />
-    <ClCompile Include="ubidiln.c" />
-    <ClCompile Include="ubidiwrt.c" />
-    <ClCompile Include="uloc_keytype.cpp" />
-    <ClCompile Include="ushape.cpp" />
-    <ClCompile Include="brkeng.cpp">
-    </ClCompile>
-    <ClCompile Include="brkiter.cpp">
-    </ClCompile>
-    <ClCompile Include="dictbe.cpp" />
-    <ClCompile Include="pluralmap.cpp" />
-    <ClCompile Include="rbbi.cpp">
-    </ClCompile>
-    <ClCompile Include="rbbidata.cpp">
-    </ClCompile>
-    <ClCompile Include="rbbinode.cpp" />
-    <ClCompile Include="rbbirb.cpp">
-    </ClCompile>
-    <ClCompile Include="rbbiscan.cpp" />
-    <ClCompile Include="rbbisetb.cpp" />
-    <ClCompile Include="rbbistbl.cpp">
-    </ClCompile>
-    <ClCompile Include="rbbitblb.cpp">
-    </ClCompile>
-    <ClCompile Include="dictionarydata.cpp" />
-    <ClCompile Include="ubrk.cpp" />
-    <ClCompile Include="ucol_swp.cpp">
-      <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\i18n;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\i18n;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\i18n;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\i18n;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-    </ClCompile>
-    <ClCompile Include="propsvec.c" />
-    <ClCompile Include="uarrsort.c" />
-    <ClCompile Include="uenum.c" />
-    <ClCompile Include="uhash.c" />
-    <ClCompile Include="uhash_us.cpp" />
-    <ClCompile Include="ulist.c" />
-    <ClCompile Include="ustack.cpp" />
-    <ClCompile Include="ustrenum.cpp" />
-    <ClCompile Include="utrie.cpp" />
-    <ClCompile Include="utrie2.cpp" />
-    <ClCompile Include="utrie2_builder.cpp" />
-    <ClCompile Include="uvector.cpp" />
-    <ClCompile Include="uvectr32.cpp" />
-    <ClCompile Include="uvectr64.cpp" />
-    <ClCompile Include="errorcode.cpp" />
-    <ClCompile Include="icudataver.c" />
-    <ClCompile Include="locmap.c">
-      <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</DisableLanguageExtensions>
-      <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</DisableLanguageExtensions>
-      <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</DisableLanguageExtensions>
-      <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</DisableLanguageExtensions>
-    </ClCompile>
-    <ClCompile Include="putil.cpp">
-      <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</DisableLanguageExtensions>
-      <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</DisableLanguageExtensions>
-      <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</DisableLanguageExtensions>
-      <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</DisableLanguageExtensions>
-    </ClCompile>
-    <ClCompile Include="umath.c" />
-    <ClCompile Include="umutex.cpp">
-      <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</DisableLanguageExtensions>
-      <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</DisableLanguageExtensions>
-      <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</DisableLanguageExtensions>
-      <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</DisableLanguageExtensions>
-    </ClCompile>
-    <ClCompile Include="utrace.c" />
-    <ClCompile Include="utypes.c" />
-    <ClCompile Include="wintz.c">
-      <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</DisableLanguageExtensions>
-      <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</DisableLanguageExtensions>
-      <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</DisableLanguageExtensions>
-      <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</DisableLanguageExtensions>
-    </ClCompile>
-    <ClCompile Include="ucnv.c" />
-    <ClCompile Include="ucnv2022.cpp" />
-    <ClCompile Include="ucnv_bld.cpp">
-    </ClCompile>
-    <ClCompile Include="ucnv_cb.c" />
-    <ClCompile Include="ucnv_cnv.c" />
-    <ClCompile Include="ucnv_ct.c" />
-    <ClCompile Include="ucnv_err.c" />
-    <ClCompile Include="ucnv_ext.cpp" />
-    <ClCompile Include="ucnv_io.cpp">
-    </ClCompile>
-    <ClCompile Include="ucnv_lmb.c" />
-    <ClCompile Include="ucnv_set.c" />
-    <ClCompile Include="ucnv_u16.c" />
-    <ClCompile Include="ucnv_u32.c" />
-    <ClCompile Include="ucnv_u7.c" />
-    <ClCompile Include="ucnv_u8.c" />
-    <ClCompile Include="ucnvbocu.cpp" />
-    <ClCompile Include="ucnvdisp.c" />
-    <ClCompile Include="ucnvhz.c" />
-    <ClCompile Include="ucnvisci.c" />
-    <ClCompile Include="ucnvlat1.c" />
-    <ClCompile Include="ucnvmbcs.cpp" />
-    <ClCompile Include="ucnvscsu.c" />
-    <ClCompile Include="ucnvsel.cpp">
-    </ClCompile>
-    <ClCompile Include="cmemory.c" />
-    <ClCompile Include="ucln_cmn.cpp">
-      <DisableLanguageExtensions>false</DisableLanguageExtensions>
-    </ClCompile>
-    <ClCompile Include="ucmndata.c" />
-    <ClCompile Include="udata.cpp" />
-    <ClCompile Include="udatamem.c" />
-    <ClCompile Include="udataswp.c" />
-    <ClCompile Include="uinit.cpp">
-      <DisableLanguageExtensions>false</DisableLanguageExtensions>
-    </ClCompile>
-    <ClCompile Include="umapfile.c">
-      <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</DisableLanguageExtensions>
-      <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</DisableLanguageExtensions>
-      <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</DisableLanguageExtensions>
-      <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</DisableLanguageExtensions>
-    </ClCompile>
-    <ClCompile Include="uobject.cpp" />
-    <ClCompile Include="dtintrv.cpp" />
-    <ClCompile Include="parsepos.cpp" />
-    <ClCompile Include="ustrfmt.c" />
-    <ClCompile Include="util.cpp" />
-    <ClCompile Include="util_props.cpp" />
-    <ClCompile Include="punycode.cpp" />
-    <ClCompile Include="uidna.cpp" />
-    <ClCompile Include="uts46.cpp" />
-    <ClCompile Include="locavailable.cpp">
-    </ClCompile>
-    <ClCompile Include="locbased.cpp" />
-    <ClCompile Include="locdispnames.cpp" />
-    <ClCompile Include="locid.cpp">
-    </ClCompile>
-    <ClCompile Include="loclikely.cpp" />
-    <ClCompile Include="locresdata.cpp" />
-    <ClCompile Include="locutil.cpp">
-    </ClCompile>
-    <ClCompile Include="resbund.cpp">
-    </ClCompile>
-    <ClCompile Include="resbund_cnv.cpp" />
-    <ClCompile Include="ucat.c" />
-    <ClCompile Include="uloc.cpp" />
-    <ClCompile Include="uloc_tag.c" />
-    <ClCompile Include="ures_cnv.c" />
-    <ClCompile Include="uresbund.cpp" />
-    <ClCompile Include="uresdata.cpp" />
-    <ClCompile Include="resource.cpp" />
-    <ClCompile Include="caniter.cpp">
-    </ClCompile>
-    <ClCompile Include="filterednormalizer2.cpp" />
-    <ClCompile Include="loadednormalizer2impl.cpp" />
-    <ClCompile Include="normalizer2.cpp" />
-    <ClCompile Include="normalizer2impl.cpp" />
-    <ClCompile Include="normlzr.cpp">
-    </ClCompile>
-    <ClCompile Include="unorm.cpp" />
-    <ClCompile Include="unormcmp.cpp" />
-    <ClCompile Include="bmpset.cpp" />
-    <ClCompile Include="patternprops.cpp" />
-    <ClCompile Include="propname.cpp">
-    </ClCompile>
-    <ClCompile Include="ruleiter.cpp" />
-    <ClCompile Include="ucase.cpp">
-    </ClCompile>
-    <ClCompile Include="uchar.c" />
-    <ClCompile Include="unames.cpp" />
-    <ClCompile Include="unifiedcache.cpp">
-      <DisableLanguageExtensions>false</DisableLanguageExtensions>
-    </ClCompile>
-    <ClCompile Include="unifilt.cpp" />
-    <ClCompile Include="unifunct.cpp" />
-    <ClCompile Include="uniset.cpp" />
-    <ClCompile Include="uniset_closure.cpp" />
-    <ClCompile Include="uniset_props.cpp" />
-    <ClCompile Include="unisetspan.cpp" />
-    <ClCompile Include="uprops.cpp" />
-    <ClCompile Include="usc_impl.c" />
-    <ClCompile Include="uscript.c" />
-    <ClCompile Include="uscript_props.cpp" />
-    <ClCompile Include="uset.cpp" />
-    <ClCompile Include="uset_props.cpp" />
-    <ClCompile Include="usetiter.cpp" />
-    <ClCompile Include="icuplug.cpp" />
-    <ClCompile Include="serv.cpp">
-    </ClCompile>
-    <ClCompile Include="servlk.cpp">
-    </ClCompile>
-    <ClCompile Include="servlkf.cpp">
-    </ClCompile>
-    <ClCompile Include="servls.cpp">
-    </ClCompile>
-    <ClCompile Include="servnotf.cpp">
-    </ClCompile>
-    <ClCompile Include="servrbf.cpp">
-    </ClCompile>
-    <ClCompile Include="servslkf.cpp">
-    </ClCompile>
-    <ClCompile Include="usprep.cpp" />
-    <ClCompile Include="appendable.cpp" />
-    <ClCompile Include="bytestream.cpp" />
-    <ClCompile Include="bytestrie.cpp" />
-    <ClCompile Include="bytestriebuilder.cpp" />
-    <ClCompile Include="bytestrieiterator.cpp" />
-    <ClCompile Include="chariter.cpp" />
-    <ClCompile Include="charstr.cpp" />
-    <ClCompile Include="cstring.c" />
-    <ClCompile Include="cwchar.c" />
-    <ClCompile Include="messagepattern.cpp" />
-    <ClCompile Include="schriter.cpp" />
-    <ClCompile Include="stringpiece.cpp" />
-    <ClCompile Include="stringtriebuilder.cpp" />
-    <ClCompile Include="simplepatternformatter.cpp" />
-    <ClCompile Include="ucasemap.cpp" />
-    <ClCompile Include="ucasemap_titlecase_brkiter.cpp" />
-    <ClCompile Include="ucharstrie.cpp" />
-    <ClCompile Include="ucharstriebuilder.cpp" />
-    <ClCompile Include="ucharstrieiterator.cpp" />
-    <ClCompile Include="uchriter.cpp" />
-    <ClCompile Include="uinvchar.c" />
-    <ClCompile Include="uiter.cpp" />
-    <ClCompile Include="unistr.cpp" />
-    <ClCompile Include="unistr_case.cpp" />
-    <ClCompile Include="unistr_case_locale.cpp" />
-    <ClCompile Include="unistr_cnv.cpp" />
-    <ClCompile Include="unistr_props.cpp" />
-    <ClCompile Include="unistr_titlecase_brkiter.cpp" />
-    <ClCompile Include="ustr_cnv.cpp" />
-    <ClCompile Include="ustr_titlecase_brkiter.cpp" />
-    <ClCompile Include="ustr_wcs.cpp" />
-    <ClCompile Include="ustrcase.cpp" />
-    <ClCompile Include="ustrcase_locale.cpp" />
-    <ClCompile Include="ustring.cpp" />
-    <ClCompile Include="ustrtrns.cpp" />
-    <ClCompile Include="utext.cpp" />
-    <ClCompile Include="utf_impl.c" />
-    <ClCompile Include="listformatter.cpp" />
-    <ClCompile Include="ulistformatter.cpp" />
-  </ItemGroup>
-  <ItemGroup>
-    <CustomBuild Include="unicode\ubidi.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <ClInclude Include="localsvc.h" />
-    <ClInclude Include="msvcres.h" />
-    <ClInclude Include="pluralmap.h" />
-    <ClInclude Include="propname_data.h" />
-    <ClInclude Include="ubidi_props.h" />
-    <ClInclude Include="ubidiimp.h" />
-    <CustomBuild Include="unicode\ushape.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <ClInclude Include="brkeng.h" />
-    <CustomBuild Include="unicode\brkiter.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <CustomBuild Include="unicode\dbbi.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <ClInclude Include="dictbe.h" />
-    <CustomBuild Include="unicode\rbbi.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <ClInclude Include="rbbidata.h" />
-    <ClInclude Include="rbbinode.h" />
-    <ClInclude Include="rbbirb.h" />
-    <ClInclude Include="rbbirpt.h" />
-    <ClInclude Include="rbbiscan.h" />
-    <ClInclude Include="rbbisetb.h" />
-    <ClInclude Include="rbbitblb.h" />
-    <ClInclude Include="dictionarydata.h" />
-    <CustomBuild Include="unicode\ubrk.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <ClInclude Include="ubidi_props_data.h" />
-    <ClInclude Include="ubrkimpl.h" />
-    <ClInclude Include="ucase_props_data.h" />
-    <ClInclude Include="uchar_props_data.h" />
-    <ClInclude Include="ucol_data.h" />
-    <ClInclude Include="ucol_swp.h" />
-    <ClInclude Include="unistrappender.h" />
-    <ClInclude Include="hash.h" />
-    <ClInclude Include="propsvec.h" />
-    <CustomBuild Include="unicode\strenum.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <ClInclude Include="uarrsort.h" />
-    <CustomBuild Include="unicode\uenum.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <ClInclude Include="uelement.h" />
-    <ClInclude Include="uenumimp.h" />
-    <ClInclude Include="uhash.h" />
-    <ClInclude Include="ulist.h" />
-    <CustomBuild Include="unicode\enumset.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <ClInclude Include="unicode\filteredbrk.h" />
-    <ClInclude Include="ustrenum.h" />
-    <ClInclude Include="utrie.h" />
-    <ClInclude Include="utrie2.h" />
-    <ClInclude Include="utrie2_impl.h" />
-    <ClInclude Include="utypeinfo.h" />
-    <ClInclude Include="uvector.h" />
-    <ClInclude Include="uvectr32.h" />
-    <ClInclude Include="uvectr64.h" />
-    <ClInclude Include="cpputils.h" />
-    <CustomBuild Include="unicode\docmain.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <CustomBuild Include="unicode\errorcode.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <CustomBuild Include="unicode\icudataver.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <ClInclude Include="locmap.h" />
-    <ClInclude Include="mutex.h" />
-    <CustomBuild Include="unicode\platform.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <CustomBuild Include="unicode\ptypes.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <CustomBuild Include="unicode\putil.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <ClInclude Include="putilimp.h" />
-    <CustomBuild Include="unicode\std_string.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <ClInclude Include="uassert.h" />
-    <CustomBuild Include="unicode\uconfig.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <CustomBuild Include="unicode\umachine.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <ClInclude Include="umutex.h" />
-    <ClInclude Include="uposixdefs.h" />
-    <CustomBuild Include="unicode\urename.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <CustomBuild Include="unicode\utrace.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <ClInclude Include="utracimp.h" />
-    <CustomBuild Include="unicode\utypes.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <CustomBuild Include="unicode\uvernum.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <CustomBuild Include="unicode\uversion.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <ClInclude Include="wintz.h" />
-    <CustomBuild Include="unicode\ucnv.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <ClInclude Include="ucnv_bld.h" />
-    <CustomBuild Include="unicode\ucnv_cb.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <ClInclude Include="ucnv_cnv.h" />
-    <CustomBuild Include="unicode\ucnv_err.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <ClInclude Include="ucnv_ext.h" />
-    <ClInclude Include="ucnv_imp.h" />
-    <ClInclude Include="ucnv_io.h" />
-    <ClInclude Include="ucnvmbcs.h" />
-    <CustomBuild Include="unicode\ucnvsel.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <ClInclude Include="cmemory.h" />
-    <CustomBuild Include="unicode\localpointer.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <CustomBuild Include="unicode\uclean.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <ClInclude Include="ucln.h" />
-    <ClInclude Include="ucln_cmn.h" />
-    <ClInclude Include="ucln_imp.h" />
-    <ClInclude Include="ucmndata.h" />
-    <CustomBuild Include="unicode\udata.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <ClInclude Include="udatamem.h" />
-    <ClInclude Include="udataswp.h" />
-    <ClInclude Include="umapfile.h" />
-    <CustomBuild Include="unicode\uobject.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <CustomBuild Include="unicode\dtintrv.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <CustomBuild Include="unicode\parseerr.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <CustomBuild Include="unicode\parsepos.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <CustomBuild Include="unicode\umisc.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <ClInclude Include="ustrfmt.h" />
-    <ClInclude Include="util.h" />
-    <CustomBuild Include="unicode\idna.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <ClInclude Include="punycode.h" />
-    <CustomBuild Include="unicode\uidna.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <ClInclude Include="locbased.h" />
-    <CustomBuild Include="unicode\locid.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <ClInclude Include="locutil.h" />
-    <CustomBuild Include="unicode\resbund.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <ClInclude Include="sharedobject.h" />
-    <ClCompile Include="sharedobject.cpp" />
-    <ClInclude Include="simplepatternformatter.h" />
-    <CustomBuild Include="unicode\ucat.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <CustomBuild Include="unicode\uloc.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <ClInclude Include="ulocimp.h" />
-    <CustomBuild Include="unicode\ures.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <ClInclude Include="unifiedcache.h" />
-    <ClInclude Include="uresdata.h" />
-    <ClInclude Include="uresimp.h" />
-    <ClInclude Include="ureslocs.h" />
-    <ClInclude Include="resource.h" />
-    <CustomBuild Include="unicode\caniter.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <ClInclude Include="norm2allmodes.h" />
-    <CustomBuild Include="unicode\normalizer2.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <ClInclude Include="normalizer2impl.h" />
-    <CustomBuild Include="unicode\normlzr.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <CustomBuild Include="unicode\unorm.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <CustomBuild Include="unicode\unorm2.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <ClInclude Include="unormimp.h" />
-    <ClInclude Include="bmpset.h" />
-    <ClInclude Include="messageimpl.h" />
-    <ClInclude Include="patternprops.h" />
-    <ClInclude Include="propname.h" />
-    <ClInclude Include="ruleiter.h" />
-    <CustomBuild Include="unicode\symtable.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <ClInclude Include="ucase.h" />
-    <CustomBuild Include="unicode\uchar.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <CustomBuild Include="unicode\unifilt.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <CustomBuild Include="unicode\unifunct.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <CustomBuild Include="unicode\unimatch.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <CustomBuild Include="unicode\uniset.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <ClInclude Include="unisetspan.h" />
-    <ClInclude Include="uprops.h" />
-    <ClInclude Include="usc_impl.h" />
-    <CustomBuild Include="unicode\uscript.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <CustomBuild Include="unicode\uset.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <ClInclude Include="uset_imp.h" />
-    <CustomBuild Include="unicode\usetiter.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <CustomBuild Include="unicode\icuplug.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <ClInclude Include="icuplugimp.h" />
-    <ClInclude Include="serv.h" />
-    <ClInclude Include="servloc.h" />
-    <ClInclude Include="servnotf.h" />
-    <ClInclude Include="sprpimpl.h" />
-    <CustomBuild Include="unicode\usprep.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <CustomBuild Include="unicode\appendable.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <CustomBuild Include="unicode\bytestream.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <CustomBuild Include="unicode\bytestrie.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <CustomBuild Include="unicode\bytestriebuilder.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <CustomBuild Include="unicode\chariter.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <ClInclude Include="charstr.h" />
-    <ClInclude Include="cstring.h" />
-    <ClInclude Include="cwchar.h" />
-    <CustomBuild Include="unicode\messagepattern.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <CustomBuild Include="unicode\rep.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <CustomBuild Include="unicode\schriter.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <CustomBuild Include="unicode\stringpiece.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <CustomBuild Include="unicode\stringtriebuilder.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <CustomBuild Include="unicode\ucasemap.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <CustomBuild Include="unicode\ucharstrie.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <CustomBuild Include="unicode\ucharstriebuilder.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <CustomBuild Include="unicode\uchriter.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <ClInclude Include="uinvchar.h" />
-    <CustomBuild Include="unicode\uiter.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <CustomBuild Include="unicode\unistr.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <CustomBuild Include="unicode\urep.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <ClInclude Include="ustr_cnv.h" />
-    <ClInclude Include="ustr_imp.h" />
-    <CustomBuild Include="unicode\ustring.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <CustomBuild Include="unicode\ustringtrie.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <CustomBuild Include="unicode\utext.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <CustomBuild Include="unicode\utf.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <CustomBuild Include="unicode\utf16.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <CustomBuild Include="unicode\utf32.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <CustomBuild Include="unicode\utf8.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <CustomBuild Include="unicode\utf_old.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <CustomBuild Include="unicode\listformatter.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-    <CustomBuild Include="unicode\ulistformatter.h">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
-</Command>
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
-    </CustomBuild>
-  </ItemGroup>
-  <ItemGroup>
-    <ResourceCompile Include="common.rc" />
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\stubdata\stubdata.vcxproj">
-      <Project>{203ec78a-0531-43f0-a636-285439bde025}</Project>
-      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
-    </ProjectReference>
-  </ItemGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-  <ImportGroup Label="ExtensionTargets">
-  </ImportGroup>
-</Project>
diff --git a/src/third_party/icu/source/common/common.vcxproj.filters b/src/third_party/icu/source/common/common.vcxproj.filters
deleted file mode 100644
index 4a4954b..0000000
--- a/src/third_party/icu/source/common/common.vcxproj.filters
+++ /dev/null
@@ -1,1149 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup>
-    <Filter Include="bidi">
-      <UniqueIdentifier>{8049805d-3f8b-4731-ac8a-aa19b3cbea45}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="break iteration">
-      <UniqueIdentifier>{7668dce2-7846-4b48-8bd4-4ef781671b62}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="collation">
-      <UniqueIdentifier>{f08dc85c-73ea-47b5-a867-b67589e6bebf}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="collections">
-      <UniqueIdentifier>{51edbf4b-fe36-401e-9571-0472d9dae727}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="configuration">
-      <UniqueIdentifier>{3fd9d1ea-6efc-4768-a43d-811379162322}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="conversion">
-      <UniqueIdentifier>{f74f43ea-8ea9-49a9-a097-e2aa5a409368}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="data &amp; memory">
-      <UniqueIdentifier>{c7b856da-4f50-42c5-a741-8995df25dc6b}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="formatting">
-      <UniqueIdentifier>{c76cfce3-cfe6-4de0-aa37-44c599377e2f}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="idna">
-      <UniqueIdentifier>{9abf6a02-9db0-4ecd-a8d9-bbb28073a424}</UniqueIdentifier>
-      <Extensions>*.c,*.h</Extensions>
-    </Filter>
-    <Filter Include="locales &amp; resources">
-      <UniqueIdentifier>{b481ca81-7bc8-4399-a220-27fc29a7b74d}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="normalization">
-      <UniqueIdentifier>{923074b3-0112-4faf-b8c7-59feb85a0835}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="properties &amp; sets">
-      <UniqueIdentifier>{17948745-0376-4851-bf12-7dabf94622e7}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="registration">
-      <UniqueIdentifier>{b32b9445-b6dc-4800-94a6-28641e586cd4}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="sprep">
-      <UniqueIdentifier>{ea285df7-8e35-4b10-ae2a-86cb32c0d477}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="strings">
-      <UniqueIdentifier>{2c52192a-7b17-4c3b-998e-ca025063bd3c}</UniqueIdentifier>
-    </Filter>
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="ubidi.c">
-      <Filter>bidi</Filter>
-    </ClCompile>
-    <ClCompile Include="ubidi_props.c">
-      <Filter>bidi</Filter>
-    </ClCompile>
-    <ClCompile Include="ubidiln.c">
-      <Filter>bidi</Filter>
-    </ClCompile>
-    <ClCompile Include="ubidiwrt.c">
-      <Filter>bidi</Filter>
-    </ClCompile>
-    <ClCompile Include="ushape.cpp">
-      <Filter>bidi</Filter>
-    </ClCompile>
-    <ClCompile Include="brkeng.cpp">
-      <Filter>break iteration</Filter>
-    </ClCompile>
-    <ClCompile Include="brkiter.cpp">
-      <Filter>break iteration</Filter>
-    </ClCompile>
-    <ClCompile Include="dictbe.cpp">
-      <Filter>break iteration</Filter>
-    </ClCompile>
-    <ClCompile Include="rbbi.cpp">
-      <Filter>break iteration</Filter>
-    </ClCompile>
-    <ClCompile Include="rbbidata.cpp">
-      <Filter>break iteration</Filter>
-    </ClCompile>
-    <ClCompile Include="rbbinode.cpp">
-      <Filter>break iteration</Filter>
-    </ClCompile>
-    <ClCompile Include="rbbirb.cpp">
-      <Filter>break iteration</Filter>
-    </ClCompile>
-    <ClCompile Include="rbbiscan.cpp">
-      <Filter>break iteration</Filter>
-    </ClCompile>
-    <ClCompile Include="rbbisetb.cpp">
-      <Filter>break iteration</Filter>
-    </ClCompile>
-    <ClCompile Include="rbbistbl.cpp">
-      <Filter>break iteration</Filter>
-    </ClCompile>
-    <ClCompile Include="rbbitblb.cpp">
-      <Filter>break iteration</Filter>
-    </ClCompile>
-    <ClCompile Include="ubrk.cpp">
-      <Filter>break iteration</Filter>
-    </ClCompile>
-    <ClCompile Include="ucol_swp.cpp">
-      <Filter>collation</Filter>
-    </ClCompile>
-    <ClCompile Include="pluralmap.cpp">
-      <Filter>collections</Filter>
-    </ClCompile>
-    <ClCompile Include="propsvec.c">
-      <Filter>collections</Filter>
-    </ClCompile>
-    <ClCompile Include="uarrsort.c">
-      <Filter>collections</Filter>
-    </ClCompile>
-    <ClCompile Include="uenum.c">
-      <Filter>collections</Filter>
-    </ClCompile>
-    <ClCompile Include="uhash.c">
-      <Filter>collections</Filter>
-    </ClCompile>
-    <ClCompile Include="uhash_us.cpp">
-      <Filter>collections</Filter>
-    </ClCompile>
-    <ClCompile Include="ulist.c">
-      <Filter>collections</Filter>
-    </ClCompile>
-    <ClCompile Include="unifiedcache.cpp">
-      <Filter>collections</Filter>
-    </ClCompile>
-    <ClCompile Include="ustack.cpp">
-      <Filter>collections</Filter>
-    </ClCompile>
-    <ClCompile Include="ustrenum.cpp">
-      <Filter>collections</Filter>
-    </ClCompile>
-    <ClCompile Include="utrie.cpp">
-      <Filter>collections</Filter>
-    </ClCompile>
-    <ClCompile Include="utrie2.cpp">
-      <Filter>collections</Filter>
-    </ClCompile>
-    <ClCompile Include="utrie2_builder.cpp">
-      <Filter>collections</Filter>
-    </ClCompile>
-    <ClCompile Include="uvector.cpp">
-      <Filter>collections</Filter>
-    </ClCompile>
-    <ClCompile Include="uvectr32.cpp">
-      <Filter>collections</Filter>
-    </ClCompile>
-    <ClCompile Include="uvectr64.cpp">
-      <Filter>collections</Filter>
-    </ClCompile>
-    <ClCompile Include="errorcode.cpp">
-      <Filter>configuration</Filter>
-    </ClCompile>
-    <ClCompile Include="icudataver.c">
-      <Filter>configuration</Filter>
-    </ClCompile>
-    <ClCompile Include="locmap.c">
-      <Filter>configuration</Filter>
-    </ClCompile>
-    <ClCompile Include="putil.cpp">
-      <Filter>configuration</Filter>
-    </ClCompile>
-    <ClCompile Include="umath.c">
-      <Filter>configuration</Filter>
-    </ClCompile>
-    <ClCompile Include="umutex.cpp">
-      <Filter>configuration</Filter>
-    </ClCompile>
-    <ClCompile Include="utrace.c">
-      <Filter>configuration</Filter>
-    </ClCompile>
-    <ClCompile Include="utypes.c">
-      <Filter>configuration</Filter>
-    </ClCompile>
-    <ClCompile Include="wintz.c">
-      <Filter>configuration</Filter>
-    </ClCompile>
-    <ClCompile Include="ucnv.c">
-      <Filter>conversion</Filter>
-    </ClCompile>
-    <ClCompile Include="ucnv2022.cpp">
-      <Filter>conversion</Filter>
-    </ClCompile>
-    <ClCompile Include="ucnv_bld.cpp">
-      <Filter>conversion</Filter>
-    </ClCompile>
-    <ClCompile Include="ucnv_cb.c">
-      <Filter>conversion</Filter>
-    </ClCompile>
-    <ClCompile Include="ucnv_cnv.c">
-      <Filter>conversion</Filter>
-    </ClCompile>
-    <ClCompile Include="ucnv_err.c">
-      <Filter>conversion</Filter>
-    </ClCompile>
-    <ClCompile Include="ucnv_ext.cpp">
-      <Filter>conversion</Filter>
-    </ClCompile>
-    <ClCompile Include="ucnv_io.cpp">
-      <Filter>conversion</Filter>
-    </ClCompile>
-    <ClCompile Include="ucnv_lmb.c">
-      <Filter>conversion</Filter>
-    </ClCompile>
-    <ClCompile Include="ucnv_set.c">
-      <Filter>conversion</Filter>
-    </ClCompile>
-    <ClCompile Include="ucnv_u16.c">
-      <Filter>conversion</Filter>
-    </ClCompile>
-    <ClCompile Include="ucnv_u32.c">
-      <Filter>conversion</Filter>
-    </ClCompile>
-    <ClCompile Include="ucnv_u7.c">
-      <Filter>conversion</Filter>
-    </ClCompile>
-    <ClCompile Include="ucnv_u8.c">
-      <Filter>conversion</Filter>
-    </ClCompile>
-    <ClCompile Include="ucnvbocu.cpp">
-      <Filter>conversion</Filter>
-    </ClCompile>
-    <ClCompile Include="ucnvdisp.c">
-      <Filter>conversion</Filter>
-    </ClCompile>
-    <ClCompile Include="ucnvhz.c">
-      <Filter>conversion</Filter>
-    </ClCompile>
-    <ClCompile Include="ucnvisci.c">
-      <Filter>conversion</Filter>
-    </ClCompile>
-    <ClCompile Include="ucnvlat1.c">
-      <Filter>conversion</Filter>
-    </ClCompile>
-    <ClCompile Include="ucnvmbcs.cpp">
-      <Filter>conversion</Filter>
-    </ClCompile>
-    <ClCompile Include="ucnvscsu.c">
-      <Filter>conversion</Filter>
-    </ClCompile>
-    <ClCompile Include="ucnvsel.cpp">
-      <Filter>conversion</Filter>
-    </ClCompile>
-    <ClCompile Include="cmemory.c">
-      <Filter>data &amp; memory</Filter>
-    </ClCompile>
-    <ClCompile Include="sharedobject.cpp">
-      <Filter>data &amp; memory</Filter>
-    </ClCompile>
-    <ClCompile Include="ucln_cmn.cpp">
-      <Filter>data &amp; memory</Filter>
-    </ClCompile>
-    <ClCompile Include="ucmndata.c">
-      <Filter>data &amp; memory</Filter>
-    </ClCompile>
-    <ClCompile Include="udata.cpp">
-      <Filter>data &amp; memory</Filter>
-    </ClCompile>
-    <ClCompile Include="udatamem.c">
-      <Filter>data &amp; memory</Filter>
-    </ClCompile>
-    <ClCompile Include="udataswp.c">
-      <Filter>data &amp; memory</Filter>
-    </ClCompile>
-    <ClCompile Include="uinit.cpp">
-      <Filter>data &amp; memory</Filter>
-    </ClCompile>
-    <ClCompile Include="umapfile.c">
-      <Filter>data &amp; memory</Filter>
-    </ClCompile>
-    <ClCompile Include="uobject.cpp">
-      <Filter>data &amp; memory</Filter>
-    </ClCompile>
-    <ClCompile Include="dtintrv.cpp">
-      <Filter>formatting</Filter>
-    </ClCompile>
-    <ClCompile Include="parsepos.cpp">
-      <Filter>formatting</Filter>
-    </ClCompile>
-    <ClCompile Include="simplepatternformatter.cpp">
-      <Filter>formatting</Filter>
-    </ClCompile>
-    <ClCompile Include="ustrfmt.c">
-      <Filter>formatting</Filter>
-    </ClCompile>
-    <ClCompile Include="util.cpp">
-      <Filter>formatting</Filter>
-    </ClCompile>
-    <ClCompile Include="util_props.cpp">
-      <Filter>formatting</Filter>
-    </ClCompile>
-    <ClCompile Include="punycode.cpp">
-      <Filter>idna</Filter>
-    </ClCompile>
-    <ClCompile Include="uidna.cpp">
-      <Filter>idna</Filter>
-    </ClCompile>
-    <ClCompile Include="uts46.cpp">
-      <Filter>idna</Filter>
-    </ClCompile>
-    <ClCompile Include="locavailable.cpp">
-      <Filter>locales &amp; resources</Filter>
-    </ClCompile>
-    <ClCompile Include="locbased.cpp">
-      <Filter>locales &amp; resources</Filter>
-    </ClCompile>
-    <ClCompile Include="locdispnames.cpp">
-      <Filter>locales &amp; resources</Filter>
-    </ClCompile>
-    <ClCompile Include="locid.cpp">
-      <Filter>locales &amp; resources</Filter>
-    </ClCompile>
-    <ClCompile Include="loclikely.cpp">
-      <Filter>locales &amp; resources</Filter>
-    </ClCompile>
-    <ClCompile Include="locresdata.cpp">
-      <Filter>locales &amp; resources</Filter>
-    </ClCompile>
-    <ClCompile Include="locutil.cpp">
-      <Filter>locales &amp; resources</Filter>
-    </ClCompile>
-    <ClCompile Include="resbund.cpp">
-      <Filter>locales &amp; resources</Filter>
-    </ClCompile>
-    <ClCompile Include="resbund_cnv.cpp">
-      <Filter>locales &amp; resources</Filter>
-    </ClCompile>
-    <ClCompile Include="ucat.c">
-      <Filter>locales &amp; resources</Filter>
-    </ClCompile>
-    <ClCompile Include="uloc.cpp">
-      <Filter>locales &amp; resources</Filter>
-    </ClCompile>
-    <ClCompile Include="uloc_tag.c">
-      <Filter>locales &amp; resources</Filter>
-    </ClCompile>
-    <ClCompile Include="ures_cnv.c">
-      <Filter>locales &amp; resources</Filter>
-    </ClCompile>
-    <ClCompile Include="uresbund.cpp">
-      <Filter>locales &amp; resources</Filter>
-    </ClCompile>
-    <ClCompile Include="uresdata.cpp">
-      <Filter>locales &amp; resources</Filter>
-    </ClCompile>
-    <ClCompile Include="resource.cpp">
-      <Filter>locales &amp; resources</Filter>
-    </ClCompile>
-    <ClCompile Include="caniter.cpp">
-      <Filter>normalization</Filter>
-    </ClCompile>
-    <ClCompile Include="filterednormalizer2.cpp">
-      <Filter>normalization</Filter>
-    </ClCompile>
-    <ClCompile Include="loadednormalizer2impl.cpp">
-      <Filter>normalization</Filter>
-    </ClCompile>
-    <ClCompile Include="normalizer2.cpp">
-      <Filter>normalization</Filter>
-    </ClCompile>
-    <ClCompile Include="normalizer2impl.cpp">
-      <Filter>normalization</Filter>
-    </ClCompile>
-    <ClCompile Include="normlzr.cpp">
-      <Filter>normalization</Filter>
-    </ClCompile>
-    <ClCompile Include="unorm.cpp">
-      <Filter>normalization</Filter>
-    </ClCompile>
-    <ClCompile Include="unormcmp.cpp">
-      <Filter>normalization</Filter>
-    </ClCompile>
-    <ClCompile Include="bmpset.cpp">
-      <Filter>properties &amp; sets</Filter>
-    </ClCompile>
-    <ClCompile Include="propname.cpp">
-      <Filter>properties &amp; sets</Filter>
-    </ClCompile>
-    <ClCompile Include="ruleiter.cpp">
-      <Filter>properties &amp; sets</Filter>
-    </ClCompile>
-    <ClCompile Include="ucase.cpp">
-      <Filter>properties &amp; sets</Filter>
-    </ClCompile>
-    <ClCompile Include="uchar.c">
-      <Filter>properties &amp; sets</Filter>
-    </ClCompile>
-    <ClCompile Include="unames.cpp">
-      <Filter>properties &amp; sets</Filter>
-    </ClCompile>
-    <ClCompile Include="unifilt.cpp">
-      <Filter>properties &amp; sets</Filter>
-    </ClCompile>
-    <ClCompile Include="unifunct.cpp">
-      <Filter>properties &amp; sets</Filter>
-    </ClCompile>
-    <ClCompile Include="uniset.cpp">
-      <Filter>properties &amp; sets</Filter>
-    </ClCompile>
-    <ClCompile Include="uniset_closure.cpp">
-      <Filter>properties &amp; sets</Filter>
-    </ClCompile>
-    <ClCompile Include="uniset_props.cpp">
-      <Filter>properties &amp; sets</Filter>
-    </ClCompile>
-    <ClCompile Include="unisetspan.cpp">
-      <Filter>properties &amp; sets</Filter>
-    </ClCompile>
-    <ClCompile Include="uprops.cpp">
-      <Filter>properties &amp; sets</Filter>
-    </ClCompile>
-    <ClCompile Include="usc_impl.c">
-      <Filter>properties &amp; sets</Filter>
-    </ClCompile>
-    <ClCompile Include="uscript.c">
-      <Filter>properties &amp; sets</Filter>
-    </ClCompile>
-    <ClCompile Include="uscript_props.cpp">
-      <Filter>properties &amp; sets</Filter>
-    </ClCompile>
-    <ClCompile Include="uset.cpp">
-      <Filter>properties &amp; sets</Filter>
-    </ClCompile>
-    <ClCompile Include="uset_props.cpp">
-      <Filter>properties &amp; sets</Filter>
-    </ClCompile>
-    <ClCompile Include="usetiter.cpp">
-      <Filter>properties &amp; sets</Filter>
-    </ClCompile>
-    <ClCompile Include="serv.cpp">
-      <Filter>registration</Filter>
-    </ClCompile>
-    <ClCompile Include="servlk.cpp">
-      <Filter>registration</Filter>
-    </ClCompile>
-    <ClCompile Include="servlkf.cpp">
-      <Filter>registration</Filter>
-    </ClCompile>
-    <ClCompile Include="servls.cpp">
-      <Filter>registration</Filter>
-    </ClCompile>
-    <ClCompile Include="servnotf.cpp">
-      <Filter>registration</Filter>
-    </ClCompile>
-    <ClCompile Include="servrbf.cpp">
-      <Filter>registration</Filter>
-    </ClCompile>
-    <ClCompile Include="servslkf.cpp">
-      <Filter>registration</Filter>
-    </ClCompile>
-    <ClCompile Include="usprep.cpp">
-      <Filter>sprep</Filter>
-    </ClCompile>
-    <ClCompile Include="bytestream.cpp">
-      <Filter>strings</Filter>
-    </ClCompile>
-    <ClCompile Include="chariter.cpp">
-      <Filter>strings</Filter>
-    </ClCompile>
-    <ClCompile Include="charstr.cpp">
-      <Filter>strings</Filter>
-    </ClCompile>
-    <ClCompile Include="cstring.c">
-      <Filter>strings</Filter>
-    </ClCompile>
-    <ClCompile Include="cwchar.c">
-      <Filter>strings</Filter>
-    </ClCompile>
-    <ClCompile Include="schriter.cpp">
-      <Filter>strings</Filter>
-    </ClCompile>
-    <ClCompile Include="stringpiece.cpp">
-      <Filter>strings</Filter>
-    </ClCompile>
-    <ClCompile Include="ucasemap.cpp">
-      <Filter>strings</Filter>
-    </ClCompile>
-    <ClCompile Include="ucasemap_titlecase_brkiter.cpp">
-      <Filter>strings</Filter>
-    </ClCompile>
-    <ClCompile Include="uchriter.cpp">
-      <Filter>strings</Filter>
-    </ClCompile>
-    <ClCompile Include="uinvchar.c">
-      <Filter>strings</Filter>
-    </ClCompile>
-    <ClCompile Include="uiter.cpp">
-      <Filter>strings</Filter>
-    </ClCompile>
-    <ClCompile Include="unistr.cpp">
-      <Filter>strings</Filter>
-    </ClCompile>
-    <ClCompile Include="unistr_case.cpp">
-      <Filter>strings</Filter>
-    </ClCompile>
-    <ClCompile Include="unistr_case_locale.cpp">
-      <Filter>strings</Filter>
-    </ClCompile>
-    <ClCompile Include="unistr_cnv.cpp">
-      <Filter>strings</Filter>
-    </ClCompile>
-    <ClCompile Include="unistr_props.cpp">
-      <Filter>strings</Filter>
-    </ClCompile>
-    <ClCompile Include="unistr_titlecase_brkiter.cpp">
-      <Filter>strings</Filter>
-    </ClCompile>
-    <ClCompile Include="ustr_cnv.cpp">
-      <Filter>strings</Filter>
-    </ClCompile>
-    <ClCompile Include="ustr_titlecase_brkiter.cpp">
-      <Filter>strings</Filter>
-    </ClCompile>
-    <ClCompile Include="ustr_wcs.cpp">
-      <Filter>strings</Filter>
-    </ClCompile>
-    <ClCompile Include="ustrcase.cpp">
-      <Filter>strings</Filter>
-    </ClCompile>
-    <ClCompile Include="ustrcase_locale.cpp">
-      <Filter>strings</Filter>
-    </ClCompile>
-    <ClCompile Include="ustring.cpp">
-      <Filter>strings</Filter>
-    </ClCompile>
-    <ClCompile Include="ustrtrns.cpp">
-      <Filter>strings</Filter>
-    </ClCompile>
-    <ClCompile Include="utext.cpp">
-      <Filter>strings</Filter>
-    </ClCompile>
-    <ClCompile Include="utf_impl.c">
-      <Filter>strings</Filter>
-    </ClCompile>
-    <ClCompile Include="bytestrie.cpp">
-      <Filter>collections</Filter>
-    </ClCompile>
-    <ClCompile Include="bytestrieiterator.cpp">
-      <Filter>collections</Filter>
-    </ClCompile>
-    <ClCompile Include="bytestriebuilder.cpp">
-      <Filter>collections</Filter>
-    </ClCompile>
-    <ClCompile Include="listformatter.cpp">
-      <Filter>formatting</Filter>
-    </ClCompile>
-    <ClCompile Include="ulistformatter.cpp">
-      <Filter>formatting</Filter>
-    </ClCompile>
-    <ClCompile Include="messagepattern.cpp">
-      <Filter>formatting</Filter>
-    </ClCompile>
-    <ClCompile Include="appendable.cpp">
-      <Filter>strings</Filter>
-    </ClCompile>
-    <ClCompile Include="dictionarydata.cpp">
-      <Filter>break iteration</Filter>
-    </ClCompile>
-    <ClCompile Include="ucnv_ct.c">
-      <Filter>conversion</Filter>
-    </ClCompile>
-    <ClCompile Include="ucharstrie.cpp">
-      <Filter>collections</Filter>
-    </ClCompile>
-    <ClCompile Include="ucharstriebuilder.cpp">
-      <Filter>collections</Filter>
-    </ClCompile>
-    <ClCompile Include="ucharstrieiterator.cpp">
-      <Filter>collections</Filter>
-    </ClCompile>
-    <ClCompile Include="patternprops.cpp">
-      <Filter>properties &amp; sets</Filter>
-    </ClCompile>
-    <ClCompile Include="stringtriebuilder.cpp">
-      <Filter>collections</Filter>
-    </ClCompile>
-    <ClCompile Include="icuplug.cpp" />
-    <ClCompile Include="uloc_keytype.cpp">
-      <Filter>locales &amp; resources</Filter>
-    </ClCompile>
-    <ClCompile Include="filteredbrk.cpp">
-      <Filter>break iteration</Filter>
-    </ClCompile>
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="ubidi_props.h">
-      <Filter>bidi</Filter>
-    </ClInclude>
-    <ClInclude Include="ubidiimp.h">
-      <Filter>bidi</Filter>
-    </ClInclude>
-    <ClInclude Include="brkeng.h">
-      <Filter>break iteration</Filter>
-    </ClInclude>
-    <ClInclude Include="dictbe.h">
-      <Filter>break iteration</Filter>
-    </ClInclude>
-    <ClInclude Include="rbbidata.h">
-      <Filter>break iteration</Filter>
-    </ClInclude>
-    <ClInclude Include="rbbinode.h">
-      <Filter>break iteration</Filter>
-    </ClInclude>
-    <ClInclude Include="rbbirb.h">
-      <Filter>break iteration</Filter>
-    </ClInclude>
-    <ClInclude Include="rbbirpt.h">
-      <Filter>break iteration</Filter>
-    </ClInclude>
-    <ClInclude Include="rbbiscan.h">
-      <Filter>break iteration</Filter>
-    </ClInclude>
-    <ClInclude Include="rbbisetb.h">
-      <Filter>break iteration</Filter>
-    </ClInclude>
-    <ClInclude Include="rbbitblb.h">
-      <Filter>break iteration</Filter>
-    </ClInclude>
-    <ClInclude Include="ubrkimpl.h">
-      <Filter>break iteration</Filter>
-    </ClInclude>
-    <ClInclude Include="ucol_data.h">
-      <Filter>collation</Filter>
-    </ClInclude>
-    <ClInclude Include="ucol_swp.h">
-      <Filter>collation</Filter>
-    </ClInclude>
-    <ClInclude Include="hash.h">
-      <Filter>collections</Filter>
-    </ClInclude>
-    <ClInclude Include="pluralmap.h">
-      <Filter>collections</Filter>
-    </ClInclude>
-    <ClInclude Include="propsvec.h">
-      <Filter>collections</Filter>
-    </ClInclude>
-    <ClInclude Include="uarrsort.h">
-      <Filter>collections</Filter>
-    </ClInclude>
-    <ClInclude Include="uelement.h">
-      <Filter>collections</Filter>
-    </ClInclude>
-    <ClInclude Include="uenumimp.h">
-      <Filter>collections</Filter>
-    </ClInclude>
-    <ClInclude Include="uhash.h">
-      <Filter>collections</Filter>
-    </ClInclude>
-    <ClInclude Include="ulist.h">
-      <Filter>collections</Filter>
-    </ClInclude>
-    <ClInclude Include="unifiedcache.h">
-      <Filter>collections</Filter>
-    </ClInclude>
-    <ClInclude Include="ustrenum.h">
-      <Filter>collections</Filter>
-    </ClInclude>
-    <ClInclude Include="utrie.h">
-      <Filter>collections</Filter>
-    </ClInclude>
-    <ClInclude Include="utrie2.h">
-      <Filter>collections</Filter>
-    </ClInclude>
-    <ClInclude Include="utrie2_impl.h">
-      <Filter>collections</Filter>
-    </ClInclude>
-    <ClInclude Include="uvector.h">
-      <Filter>collections</Filter>
-    </ClInclude>
-    <ClInclude Include="uvectr32.h">
-      <Filter>collections</Filter>
-    </ClInclude>
-    <ClInclude Include="uvectr64.h">
-      <Filter>collections</Filter>
-    </ClInclude>
-    <ClInclude Include="cpputils.h">
-      <Filter>configuration</Filter>
-    </ClInclude>
-    <ClInclude Include="locmap.h">
-      <Filter>configuration</Filter>
-    </ClInclude>
-    <ClInclude Include="mutex.h">
-      <Filter>configuration</Filter>
-    </ClInclude>
-    <ClInclude Include="putilimp.h">
-      <Filter>configuration</Filter>
-    </ClInclude>
-    <ClInclude Include="uassert.h">
-      <Filter>configuration</Filter>
-    </ClInclude>
-    <ClInclude Include="umutex.h">
-      <Filter>configuration</Filter>
-    </ClInclude>
-    <ClInclude Include="uposixdefs.h">
-      <Filter>configuration</Filter>
-    </ClInclude>
-    <ClInclude Include="utracimp.h">
-      <Filter>configuration</Filter>
-    </ClInclude>
-    <ClInclude Include="wintz.h">
-      <Filter>configuration</Filter>
-    </ClInclude>
-    <ClInclude Include="ucnv_bld.h">
-      <Filter>conversion</Filter>
-    </ClInclude>
-    <ClInclude Include="ucnv_cnv.h">
-      <Filter>conversion</Filter>
-    </ClInclude>
-    <ClInclude Include="ucnv_ext.h">
-      <Filter>conversion</Filter>
-    </ClInclude>
-    <ClInclude Include="ucnv_imp.h">
-      <Filter>conversion</Filter>
-    </ClInclude>
-    <ClInclude Include="ucnv_io.h">
-      <Filter>conversion</Filter>
-    </ClInclude>
-    <ClInclude Include="ucnvmbcs.h">
-      <Filter>conversion</Filter>
-    </ClInclude>
-    <ClInclude Include="cmemory.h">
-      <Filter>data &amp; memory</Filter>
-    </ClInclude>
-    <ClInclude Include="sharedobject.h">
-      <Filter>data &amp; memory</Filter>
-    </ClInclude>
-    <ClInclude Include="ucln.h">
-      <Filter>data &amp; memory</Filter>
-    </ClInclude>
-    <ClInclude Include="ucln_cmn.h">
-      <Filter>data &amp; memory</Filter>
-    </ClInclude>
-    <ClInclude Include="ucln_imp.h">
-      <Filter>data &amp; memory</Filter>
-    </ClInclude>
-    <ClInclude Include="ucmndata.h">
-      <Filter>data &amp; memory</Filter>
-    </ClInclude>
-    <ClInclude Include="udatamem.h">
-      <Filter>data &amp; memory</Filter>
-    </ClInclude>
-    <ClInclude Include="udataswp.h">
-      <Filter>data &amp; memory</Filter>
-    </ClInclude>
-    <ClInclude Include="umapfile.h">
-      <Filter>data &amp; memory</Filter>
-    </ClInclude>
-    <ClInclude Include="simplepatternformatter.h">
-      <Filter>formatting</Filter>
-    </ClInclude>
-    <ClInclude Include="ustrfmt.h">
-      <Filter>formatting</Filter>
-    </ClInclude>
-    <ClInclude Include="util.h">
-      <Filter>formatting</Filter>
-    </ClInclude>
-    <ClInclude Include="punycode.h">
-      <Filter>idna</Filter>
-    </ClInclude>
-    <ClInclude Include="locbased.h">
-      <Filter>locales &amp; resources</Filter>
-    </ClInclude>
-    <ClInclude Include="locutil.h">
-      <Filter>locales &amp; resources</Filter>
-    </ClInclude>
-    <ClInclude Include="ulocimp.h">
-      <Filter>locales &amp; resources</Filter>
-    </ClInclude>
-    <ClInclude Include="uresdata.h">
-      <Filter>locales &amp; resources</Filter>
-    </ClInclude>
-    <ClInclude Include="resource.h">
-      <Filter>locales &amp; resources</Filter>
-    </ClInclude>
-    <ClInclude Include="uresimp.h">
-      <Filter>locales &amp; resources</Filter>
-    </ClInclude>
-    <ClInclude Include="ureslocs.h">
-      <Filter>locales &amp; resources</Filter>
-    </ClInclude>
-    <ClInclude Include="norm2allmodes.h">
-      <Filter>normalization</Filter>
-    </ClInclude>
-    <ClInclude Include="normalizer2impl.h">
-      <Filter>normalization</Filter>
-    </ClInclude>
-    <ClInclude Include="unormimp.h">
-      <Filter>normalization</Filter>
-    </ClInclude>
-    <ClInclude Include="bmpset.h">
-      <Filter>properties &amp; sets</Filter>
-    </ClInclude>
-    <ClInclude Include="propname.h">
-      <Filter>properties &amp; sets</Filter>
-    </ClInclude>
-    <ClInclude Include="ruleiter.h">
-      <Filter>properties &amp; sets</Filter>
-    </ClInclude>
-    <ClInclude Include="ucase.h">
-      <Filter>properties &amp; sets</Filter>
-    </ClInclude>
-    <ClInclude Include="unisetspan.h">
-      <Filter>properties &amp; sets</Filter>
-    </ClInclude>
-    <ClInclude Include="uprops.h">
-      <Filter>properties &amp; sets</Filter>
-    </ClInclude>
-    <ClInclude Include="usc_impl.h">
-      <Filter>properties &amp; sets</Filter>
-    </ClInclude>
-    <ClInclude Include="uset_imp.h">
-      <Filter>properties &amp; sets</Filter>
-    </ClInclude>
-    <ClInclude Include="icuplugimp.h">
-      <Filter>registration</Filter>
-    </ClInclude>
-    <ClInclude Include="serv.h">
-      <Filter>registration</Filter>
-    </ClInclude>
-    <ClInclude Include="servloc.h">
-      <Filter>registration</Filter>
-    </ClInclude>
-    <ClInclude Include="servnotf.h">
-      <Filter>registration</Filter>
-    </ClInclude>
-    <ClInclude Include="sprpimpl.h">
-      <Filter>sprep</Filter>
-    </ClInclude>
-    <ClInclude Include="charstr.h">
-      <Filter>strings</Filter>
-    </ClInclude>
-    <ClInclude Include="cstring.h">
-      <Filter>strings</Filter>
-    </ClInclude>
-    <ClInclude Include="cwchar.h">
-      <Filter>strings</Filter>
-    </ClInclude>
-    <ClInclude Include="uinvchar.h">
-      <Filter>strings</Filter>
-    </ClInclude>
-    <ClInclude Include="unistrappender.h">
-      <Filter>strings</Filter>
-    </ClInclude>
-    <ClInclude Include="ustr_cnv.h">
-      <Filter>strings</Filter>
-    </ClInclude>
-    <ClInclude Include="ustr_imp.h">
-      <Filter>strings</Filter>
-    </ClInclude>
-    <ClInclude Include="utypeinfo.h">
-      <Filter>configuration</Filter>
-    </ClInclude>
-    <ClInclude Include="localsvc.h">
-      <Filter>locales &amp; resources</Filter>
-    </ClInclude>
-    <ClInclude Include="msvcres.h">
-      <Filter>configuration</Filter>
-    </ClInclude>
-    <ClInclude Include="propname_data.h">
-      <Filter>properties &amp; sets</Filter>
-    </ClInclude>
-    <ClInclude Include="ubidi_props_data.h">
-      <Filter>bidi</Filter>
-    </ClInclude>
-    <ClInclude Include="ucase_props_data.h">
-      <Filter>properties &amp; sets</Filter>
-    </ClInclude>
-    <ClInclude Include="uchar_props_data.h">
-      <Filter>properties &amp; sets</Filter>
-    </ClInclude>
-    <ClInclude Include="messageimpl.h">
-      <Filter>formatting</Filter>
-    </ClInclude>
-    <ClInclude Include="dictionarydata.h">
-      <Filter>break iteration</Filter>
-    </ClInclude>
-    <ClInclude Include="patternprops.h">
-      <Filter>properties &amp; sets</Filter>
-    </ClInclude>
-    <ClInclude Include="unicode\filteredbrk.h">
-      <Filter>break iteration</Filter>
-    </ClInclude>
-  </ItemGroup>
-  <ItemGroup>
-    <ResourceCompile Include="common.rc">
-      <Filter>configuration</Filter>
-    </ResourceCompile>
-  </ItemGroup>
-  <ItemGroup>
-    <CustomBuild Include="unicode\ubidi.h">
-      <Filter>bidi</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\ushape.h">
-      <Filter>bidi</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\brkiter.h">
-      <Filter>break iteration</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\dbbi.h">
-      <Filter>break iteration</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\rbbi.h">
-      <Filter>break iteration</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\ubrk.h">
-      <Filter>break iteration</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\strenum.h">
-      <Filter>collections</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\uenum.h">
-      <Filter>collections</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\docmain.h">
-      <Filter>configuration</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\errorcode.h">
-      <Filter>configuration</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\icudataver.h">
-      <Filter>configuration</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\platform.h">
-      <Filter>configuration</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\ptypes.h">
-      <Filter>configuration</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\putil.h">
-      <Filter>configuration</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\std_string.h">
-      <Filter>configuration</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\uconfig.h">
-      <Filter>configuration</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\umachine.h">
-      <Filter>configuration</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\urename.h">
-      <Filter>configuration</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\utrace.h">
-      <Filter>configuration</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\utypes.h">
-      <Filter>configuration</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\uvernum.h">
-      <Filter>configuration</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\uversion.h">
-      <Filter>configuration</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\ucnv.h">
-      <Filter>conversion</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\ucnv_cb.h">
-      <Filter>conversion</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\ucnv_err.h">
-      <Filter>conversion</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\ucnvsel.h">
-      <Filter>conversion</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\localpointer.h">
-      <Filter>data &amp; memory</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\uclean.h">
-      <Filter>data &amp; memory</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\udata.h">
-      <Filter>data &amp; memory</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\uobject.h">
-      <Filter>data &amp; memory</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\dtintrv.h">
-      <Filter>formatting</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\parseerr.h">
-      <Filter>formatting</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\parsepos.h">
-      <Filter>formatting</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\umisc.h">
-      <Filter>formatting</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\idna.h">
-      <Filter>idna</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\uidna.h">
-      <Filter>idna</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\locid.h">
-      <Filter>locales &amp; resources</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\resbund.h">
-      <Filter>locales &amp; resources</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\ucat.h">
-      <Filter>locales &amp; resources</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\uloc.h">
-      <Filter>locales &amp; resources</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\ures.h">
-      <Filter>locales &amp; resources</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\caniter.h">
-      <Filter>normalization</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\normalizer2.h">
-      <Filter>normalization</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\normlzr.h">
-      <Filter>normalization</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\unorm.h">
-      <Filter>normalization</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\unorm2.h">
-      <Filter>normalization</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\symtable.h">
-      <Filter>properties &amp; sets</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\uchar.h">
-      <Filter>properties &amp; sets</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\unifilt.h">
-      <Filter>properties &amp; sets</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\unifunct.h">
-      <Filter>properties &amp; sets</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\unimatch.h">
-      <Filter>properties &amp; sets</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\uniset.h">
-      <Filter>properties &amp; sets</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\uscript.h">
-      <Filter>properties &amp; sets</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\uset.h">
-      <Filter>properties &amp; sets</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\usetiter.h">
-      <Filter>properties &amp; sets</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\usprep.h">
-      <Filter>sprep</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\bytestream.h">
-      <Filter>strings</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\chariter.h">
-      <Filter>strings</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\rep.h">
-      <Filter>strings</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\schriter.h">
-      <Filter>strings</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\stringpiece.h">
-      <Filter>strings</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\ucasemap.h">
-      <Filter>strings</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\uchriter.h">
-      <Filter>strings</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\uiter.h">
-      <Filter>strings</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\unistr.h">
-      <Filter>strings</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\urep.h">
-      <Filter>strings</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\ustring.h">
-      <Filter>strings</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\utext.h">
-      <Filter>strings</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\utf.h">
-      <Filter>strings</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\utf16.h">
-      <Filter>strings</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\utf32.h">
-      <Filter>strings</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\utf8.h">
-      <Filter>strings</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\utf_old.h">
-      <Filter>strings</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\bytestrie.h">
-      <Filter>collections</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\bytestriebuilder.h">
-      <Filter>collections</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\messagepattern.h">
-      <Filter>formatting</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\listformatter.h">
-      <Filter>formatting</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\ulistformatter.h">
-      <Filter>formatting</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\appendable.h">
-      <Filter>strings</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\ustringtrie.h">
-      <Filter>collections</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\ucharstrie.h">
-      <Filter>collections</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\ucharstriebuilder.h">
-      <Filter>collections</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\enumset.h">
-      <Filter>data &amp; memory</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\icuplug.h">
-      <Filter>configuration</Filter>
-    </CustomBuild>
-    <CustomBuild Include="unicode\stringtriebuilder.h">
-      <Filter>collections</Filter>
-    </CustomBuild>
-  </ItemGroup>
-</Project>
diff --git a/src/third_party/icu/source/common/cpputils.h b/src/third_party/icu/source/common/cpputils.h
index 6c1c2cf..5e509dd 100644
--- a/src/third_party/icu/source/common/cpputils.h
+++ b/src/third_party/icu/source/common/cpputils.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 ******************************************************************************
 *   file name:  cpputils.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 */
@@ -14,7 +16,9 @@
 #ifndef CPPUTILS_H
 #define CPPUTILS_H
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/utypes.h"
 #include "unicode/unistr.h"
 #include "cmemory.h"
@@ -25,45 +29,45 @@
 
 static
 inline void uprv_arrayCopy(const double* src, double* dst, int32_t count)
-{ uprv_memcpy(dst, src, (size_t)(count * sizeof(*src))); }
+{ uprv_memcpy(dst, src, (size_t)count * sizeof(*src)); }
 
 static
 inline void uprv_arrayCopy(const double* src, int32_t srcStart,
               double* dst, int32_t dstStart, int32_t count)
-{ uprv_memcpy(dst+dstStart, src+srcStart, (size_t)(count * sizeof(*src))); }
+{ uprv_memcpy(dst+dstStart, src+srcStart, (size_t)count * sizeof(*src)); }
 
 static
 inline void uprv_arrayCopy(const int8_t* src, int8_t* dst, int32_t count)
-    { uprv_memcpy(dst, src, (size_t)(count * sizeof(*src))); }
+    { uprv_memcpy(dst, src, (size_t)count * sizeof(*src)); }
 
 static
 inline void uprv_arrayCopy(const int8_t* src, int32_t srcStart,
               int8_t* dst, int32_t dstStart, int32_t count)
-{ uprv_memcpy(dst+dstStart, src+srcStart, (size_t)(count * sizeof(*src))); }
+{ uprv_memcpy(dst+dstStart, src+srcStart, (size_t)count * sizeof(*src)); }
 
 static
 inline void uprv_arrayCopy(const int16_t* src, int16_t* dst, int32_t count)
-{ uprv_memcpy(dst, src, (size_t)(count * sizeof(*src))); }
+{ uprv_memcpy(dst, src, (size_t)count * sizeof(*src)); }
 
 static
 inline void uprv_arrayCopy(const int16_t* src, int32_t srcStart,
               int16_t* dst, int32_t dstStart, int32_t count)
-{ uprv_memcpy(dst+dstStart, src+srcStart, (size_t)(count * sizeof(*src))); }
+{ uprv_memcpy(dst+dstStart, src+srcStart, (size_t)count * sizeof(*src)); }
 
 static
 inline void uprv_arrayCopy(const int32_t* src, int32_t* dst, int32_t count)
-{ uprv_memcpy(dst, src, (size_t)(count * sizeof(*src))); }
+{ uprv_memcpy(dst, src, (size_t)count * sizeof(*src)); }
 
 static
 inline void uprv_arrayCopy(const int32_t* src, int32_t srcStart,
               int32_t* dst, int32_t dstStart, int32_t count)
-{ uprv_memcpy(dst+dstStart, src+srcStart, (size_t)(count * sizeof(*src))); }
+{ uprv_memcpy(dst+dstStart, src+srcStart, (size_t)count * sizeof(*src)); }
 
 static
 inline void
 uprv_arrayCopy(const UChar *src, int32_t srcStart,
         UChar *dst, int32_t dstStart, int32_t count)
-{ uprv_memcpy(dst+dstStart, src+srcStart, (size_t)(count * sizeof(*src))); }
+{ uprv_memcpy(dst+dstStart, src+srcStart, (size_t)count * sizeof(*src)); }
 
 /**
  * Copy an array of UnicodeString OBJECTS (not pointers).
diff --git a/src/third_party/icu/source/common/cstr.cpp b/src/third_party/icu/source/common/cstr.cpp
new file mode 100644
index 0000000..24654f8
--- /dev/null
+++ b/src/third_party/icu/source/common/cstr.cpp
@@ -0,0 +1,54 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+/*
+*******************************************************************************
+*   Copyright (C) 2015-2016, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*******************************************************************************
+*   file name:  charstr.cpp
+*/
+#include "unicode/utypes.h"
+#include "unicode/putil.h"
+#include "unicode/unistr.h"
+
+#include "cstr.h"
+
+#include "charstr.h"
+#include "uinvchar.h"
+
+U_NAMESPACE_BEGIN
+
+CStr::CStr(const UnicodeString &in) {
+    UErrorCode status = U_ZERO_ERROR;
+#if !UCONFIG_NO_CONVERSION || U_CHARSET_IS_UTF8
+    int32_t length = in.extract(0, in.length(), static_cast<char *>(NULL), static_cast<uint32_t>(0));
+    int32_t resultCapacity = 0;
+    char *buf = s.getAppendBuffer(length, length, resultCapacity, status);
+    if (U_SUCCESS(status)) {
+        in.extract(0, in.length(), buf, resultCapacity);
+        s.append(buf, length, status);
+    }
+#else
+    // No conversion available. Convert any invariant characters; substitute '?' for the rest.
+    // Note: can't just call u_UCharsToChars() or CharString.appendInvariantChars() on the 
+    //       whole string because they require that the entire input be invariant.
+    char buf[2];
+    for (int i=0; i<in.length(); i = in.moveIndex32(i, 1)) {
+        if (uprv_isInvariantUString(in.getBuffer()+i, 1)) {
+            u_UCharsToChars(in.getBuffer()+i, buf, 1);
+        } else {
+            buf[0] = '?';
+        }
+        s.append(buf, 1, status);
+    }
+#endif
+}
+
+CStr::~CStr() {
+}
+
+const char * CStr::operator ()() const {
+    return s.data();
+}
+
+U_NAMESPACE_END
diff --git a/src/third_party/icu/source/common/cstr.h b/src/third_party/icu/source/common/cstr.h
new file mode 100644
index 0000000..c33f487
--- /dev/null
+++ b/src/third_party/icu/source/common/cstr.h
@@ -0,0 +1,60 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+/*
+******************************************************************************
+*
+*   Copyright (C) 2016, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+******************************************************************************
+*
+* File: cstr.h
+*/
+
+#ifndef CSTR_H
+#define CSTR_H
+
+#include "unicode/unistr.h"
+#include "unicode/uobject.h"
+#include "unicode/utypes.h"
+
+#include "charstr.h"
+
+/**
+ * ICU-internal class CStr, a small helper class to facilitate passing UnicodeStrings
+ * to functions needing (const char *) strings, such as printf().
+ *
+ * It is intended primarily for use in debugging or in tests. Uses platform 
+ * default code page conversion, which will do the best job possible,
+ * but may be lossy, depending on the platform.
+ *
+ * If no other conversion is available, use invariant conversion and substitue
+ * '?' for non-invariant characters.
+ *
+ * Example Usage:
+ *   UnicodeString s = whatever;
+ *   printf("%s", CStr(s)());
+ *
+ *   The explicit call to the CStr() constructor creates a temporary object.
+ *   Operator () on the temporary object returns a (const char *) pointer.
+ *   The lifetime of the (const char *) data is that of the temporary object,
+ *   which works well when passing it as a parameter to another function, such as printf.
+ */
+
+U_NAMESPACE_BEGIN
+
+class U_COMMON_API CStr : public UMemory {
+  public:
+    CStr(const UnicodeString &in);
+    ~CStr();
+    const char * operator ()() const;
+
+  private:
+    CharString s;
+    CStr(const CStr &other);               //  Forbid copying of this class.
+    CStr &operator =(const CStr &other);   //  Forbid assignment.
+};
+
+U_NAMESPACE_END
+
+#endif
diff --git a/src/third_party/icu/source/common/cstring.c b/src/third_party/icu/source/common/cstring.cpp
similarity index 98%
rename from src/third_party/icu/source/common/cstring.c
rename to src/third_party/icu/source/common/cstring.cpp
index 63c6244..d2633cc 100644
--- a/src/third_party/icu/source/common/cstring.c
+++ b/src/third_party/icu/source/common/cstring.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
diff --git a/src/third_party/icu/source/common/cstring.h b/src/third_party/icu/source/common/cstring.h
index 1af2a20..a925678 100644
--- a/src/third_party/icu/source/common/cstring.h
+++ b/src/third_party/icu/source/common/cstring.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
@@ -25,7 +27,9 @@
 #ifndef CSTRING_H
 #define CSTRING_H 1
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/utypes.h"
 #include "cmemory.h"
 #if !defined(STARBOARD)
@@ -41,28 +45,10 @@
 #define uprv_strchr(s, c) U_STANDARD_CPP_NAMESPACE strchr(s, c)
 #define uprv_strstr(s, c) U_STANDARD_CPP_NAMESPACE strstr(s, c)
 #define uprv_strrchr(s, c) U_STANDARD_CPP_NAMESPACE strrchr(s, c)
-
-#if U_DEBUG
-
-#define uprv_strncpy(dst, src, size) ( \
-    uprv_checkValidMemory(src, 1), \
-    U_STANDARD_CPP_NAMESPACE strncpy(dst, src, size))
-#define uprv_strncmp(s1, s2, n) ( \
-    uprv_checkValidMemory(s1, 1), \
-    uprv_checkValidMemory(s2, 1), \
-    U_STANDARD_CPP_NAMESPACE strncmp(s1, s2, n))
-#define uprv_strncat(dst, src, n) ( \
-    uprv_checkValidMemory(src, 1), \
-    U_STANDARD_CPP_NAMESPACE strncat(dst, src, n))
-
-#else
-
 #define uprv_strncpy(dst, src, size) U_STANDARD_CPP_NAMESPACE strncpy(dst, src, size)
 #define uprv_strncmp(s1, s2, n) U_STANDARD_CPP_NAMESPACE strncmp(s1, s2, n)
 #define uprv_strncat(dst, src, n) U_STANDARD_CPP_NAMESPACE strncat(dst, src, n)
 
-#endif  /* U_DEBUG */
-
 /**
  * Is c an ASCII-repertoire letter a-z or A-Z?
  * Note: The implementation is specific to whether ICU is compiled for
@@ -71,6 +57,8 @@
 U_CAPI UBool U_EXPORT2
 uprv_isASCIILetter(char c);
 
+// NOTE: For u_asciiToUpper that takes a UChar, see ustr_imp.h
+
 U_CAPI char U_EXPORT2
 uprv_toupper(char c);
 
diff --git a/src/third_party/icu/source/common/cwchar.c b/src/third_party/icu/source/common/cwchar.cpp
similarity index 88%
rename from src/third_party/icu/source/common/cwchar.c
rename to src/third_party/icu/source/common/cwchar.cpp
index 80bc760..6bd7044 100644
--- a/src/third_party/icu/source/common/cwchar.c
+++ b/src/third_party/icu/source/common/cwchar.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*  
 ******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 ******************************************************************************
 *   file name:  cwchar.c
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -18,7 +20,6 @@
 
 #if !U_HAVE_WCSCPY && !defined(STARBOARD)
 
-
 #include "cwchar.h"
 
 U_CAPI wchar_t *uprv_wcscat(wchar_t *dst, const wchar_t *src) {
@@ -51,3 +52,4 @@
 }
 
 #endif
+
diff --git a/src/third_party/icu/source/common/cwchar.h b/src/third_party/icu/source/common/cwchar.h
index 5558079..e166480 100644
--- a/src/third_party/icu/source/common/cwchar.h
+++ b/src/third_party/icu/source/common/cwchar.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*  
 ******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 ******************************************************************************
 *   file name:  cwchar.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
diff --git a/src/third_party/icu/source/common/dictbe.cpp b/src/third_party/icu/source/common/dictbe.cpp
index c290ac8..f10c471 100644
--- a/src/third_party/icu/source/common/dictbe.cpp
+++ b/src/third_party/icu/source/common/dictbe.cpp
@@ -1,21 +1,28 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /**
  *******************************************************************************
- * Copyright (C) 2006-2015, International Business Machines Corporation
+ * Copyright (C) 2006-2016, International Business Machines Corporation
  * and others. All Rights Reserved.
  *******************************************************************************
  */
 
+#include <utility>
+
 #include "unicode/utypes.h"
 
 #if !UCONFIG_NO_BREAK_ITERATION
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "brkeng.h"
 #include "dictbe.h"
 #include "unicode/uniset.h"
 #include "unicode/chariter.h"
 #include "unicode/ubrk.h"
+#include "utracimp.h"
 #include "uvectr32.h"
 #include "uvector.h"
 #include "uassert.h"
@@ -29,26 +36,23 @@
  ******************************************************************
  */
 
-DictionaryBreakEngine::DictionaryBreakEngine(uint32_t breakTypes) {
-    fTypes = breakTypes;
+DictionaryBreakEngine::DictionaryBreakEngine() {
 }
 
 DictionaryBreakEngine::~DictionaryBreakEngine() {
 }
 
 UBool
-DictionaryBreakEngine::handles(UChar32 c, int32_t breakType) const {
-    return (breakType >= 0 && breakType < 32 && (((uint32_t)1 << breakType) & fTypes)
-            && fSet.contains(c));
+DictionaryBreakEngine::handles(UChar32 c) const {
+    return fSet.contains(c);
 }
 
 int32_t
 DictionaryBreakEngine::findBreaks( UText *text,
                                  int32_t startPos,
                                  int32_t endPos,
-                                 UBool reverse,
-                                 int32_t breakType,
-                                 UStack &foundBreaks ) const {
+                                 UVector32 &foundBreaks ) const {
+    (void)startPos;            // TODO: remove this param?
     int32_t result = 0;
 
     // Find the span of characters included in the set.
@@ -60,38 +64,14 @@
     int32_t rangeStart;
     int32_t rangeEnd;
     UChar32 c = utext_current32(text);
-    if (reverse) {
-        UBool   isDict = fSet.contains(c);
-        while((current = (int32_t)utext_getNativeIndex(text)) > startPos && isDict) {
-            c = utext_previous32(text);
-            isDict = fSet.contains(c);
-        }
-        if (current < startPos) {
-            rangeStart = startPos;
-        } else {
-            rangeStart = current;
-            if (!isDict) {
-                utext_next32(text);
-                rangeStart = utext_getNativeIndex(text);
-            }
-        }
-        // rangeEnd = start + 1;
-        utext_setNativeIndex(text, start);
-        utext_next32(text);
-        rangeEnd = utext_getNativeIndex(text);
+    while((current = (int32_t)utext_getNativeIndex(text)) < endPos && fSet.contains(c)) {
+        utext_next32(text);         // TODO:  recast loop for postincrement
+        c = utext_current32(text);
     }
-    else {
-        while((current = (int32_t)utext_getNativeIndex(text)) < endPos && fSet.contains(c)) {
-            utext_next32(text);         // TODO:  recast loop for postincrement
-            c = utext_current32(text);
-        }
-        rangeStart = start;
-        rangeEnd = current;
-    }
-    if (breakType >= 0 && breakType < 32 && (((uint32_t)1 << breakType) & fTypes)) {
-        result = divideUpDictionaryRange(text, rangeStart, rangeEnd, foundBreaks);
-        utext_setNativeIndex(text, current);
-    }
+    rangeStart = start;
+    rangeEnd = current;
+    result = divideUpDictionaryRange(text, rangeStart, rangeEnd, foundBreaks);
+    utext_setNativeIndex(text, current);
     
     return result;
 }
@@ -128,8 +108,8 @@
     int32_t   cpLengths[POSSIBLE_WORD_LIST_MAX];   // Word Lengths, in code points.
 
 public:
-    PossibleWord() : count(0), prefix(0), offset(-1), mark(0), current(0) {};
-    ~PossibleWord() {};
+    PossibleWord() : count(0), prefix(0), offset(-1), mark(0), current(0) {}
+    ~PossibleWord() {}
   
     // Fill the list of candidates if needed, select the longest, and return the number found
     int32_t   candidates( UText *text, DictionaryMatcher *dict, int32_t rangeEnd );
@@ -143,13 +123,13 @@
   
     // Return the longest prefix this candidate location shares with a dictionary word
     // Return value is in code points.
-    int32_t   longestPrefix() { return prefix; };
+    int32_t   longestPrefix() { return prefix; }
   
     // Mark the current candidate as the one we like
-    void      markCurrent() { mark = current; };
+    void      markCurrent() { mark = current; }
     
     // Get length in code points of the marked word.
-    int32_t   markedCPLength() { return cpLengths[mark]; };
+    int32_t   markedCPLength() { return cpLengths[mark]; }
 };
 
 
@@ -216,9 +196,11 @@
 static const int32_t THAI_MIN_WORD_SPAN = THAI_MIN_WORD * 2;
 
 ThaiBreakEngine::ThaiBreakEngine(DictionaryMatcher *adoptDictionary, UErrorCode &status)
-    : DictionaryBreakEngine((1<<UBRK_WORD) | (1<<UBRK_LINE)),
+    : DictionaryBreakEngine(),
       fDictionary(adoptDictionary)
 {
+    UTRACE_ENTRY(UTRACE_UBRK_CREATE_BREAK_ENGINE);
+    UTRACE_DATA1(UTRACE_INFO, "dictbe=%s", "Thai");
     fThaiWordSet.applyPattern(UNICODE_STRING_SIMPLE("[[:Thai:]&[:LineBreak=SA:]]"), status);
     if (U_SUCCESS(status)) {
         setCharacters(fThaiWordSet);
@@ -238,6 +220,7 @@
     fEndWordSet.compact();
     fBeginWordSet.compact();
     fSuffixSet.compact();
+    UTRACE_EXIT_STATUS(status);
 }
 
 ThaiBreakEngine::~ThaiBreakEngine() {
@@ -248,7 +231,7 @@
 ThaiBreakEngine::divideUpDictionaryRange( UText *text,
                                                 int32_t rangeStart,
                                                 int32_t rangeEnd,
-                                                UStack &foundBreaks ) const {
+                                                UVector32 &foundBreaks ) const {
     utext_setNativeIndex(text, rangeStart);
     utext_moveIndex32(text, THAI_MIN_WORD_SPAN);
     if (utext_getNativeIndex(text) >= rangeEnd) {
@@ -337,9 +320,9 @@
                 UChar32 pc;
                 int32_t chars = 0;
                 for (;;) {
-                    int32_t pcIndex = utext_getNativeIndex(text);
+                    int32_t pcIndex = (int32_t)utext_getNativeIndex(text);
                     pc = utext_next32(text);
-                    int32_t pcSize = utext_getNativeIndex(text) - pcIndex;
+                    int32_t pcSize = (int32_t)utext_getNativeIndex(text) - pcIndex;
                     chars += pcSize;
                     remaining -= pcSize;
                     if (remaining <= 0) {
@@ -352,9 +335,9 @@
                         // two characters after uc were not 0x0E4C THANTHAKHAT before
                         // checking the dictionary. That is just a performance filter,
                         // but it's not clear it's faster than checking the trie.
-                        int32_t candidates = words[(wordsFound + 1) % THAI_LOOKAHEAD].candidates(text, fDictionary, rangeEnd);
+                        int32_t num_candidates = words[(wordsFound + 1) % THAI_LOOKAHEAD].candidates(text, fDictionary, rangeEnd);
                         utext_setNativeIndex(text, current + cuWordLength + chars);
-                        if (candidates > 0) {
+                        if (num_candidates > 0) {
                             break;
                         }
                     }
@@ -392,9 +375,9 @@
                     if (!fSuffixSet.contains(utext_previous32(text))) {
                         // Skip over previous end and PAIYANNOI
                         utext_next32(text);
-                        int32_t paiyannoiIndex = utext_getNativeIndex(text);
+                        int32_t paiyannoiIndex = (int32_t)utext_getNativeIndex(text);
                         utext_next32(text);
-                        cuWordLength += utext_getNativeIndex(text) - paiyannoiIndex;    // Add PAIYANNOI to word
+                        cuWordLength += (int32_t)utext_getNativeIndex(text) - paiyannoiIndex;    // Add PAIYANNOI to word
                         uc = utext_current32(text);     // Fetch next character
                     }
                     else {
@@ -406,9 +389,9 @@
                     if (utext_previous32(text) != THAI_MAIYAMOK) {
                         // Skip over previous end and MAIYAMOK
                         utext_next32(text);
-                        int32_t maiyamokIndex = utext_getNativeIndex(text);
+                        int32_t maiyamokIndex = (int32_t)utext_getNativeIndex(text);
                         utext_next32(text);
-                        cuWordLength += utext_getNativeIndex(text) - maiyamokIndex;    // Add MAIYAMOK to word
+                        cuWordLength += (int32_t)utext_getNativeIndex(text) - maiyamokIndex;    // Add MAIYAMOK to word
                     }
                     else {
                         // Restore prior position
@@ -458,9 +441,11 @@
 static const int32_t LAO_MIN_WORD_SPAN = LAO_MIN_WORD * 2;
 
 LaoBreakEngine::LaoBreakEngine(DictionaryMatcher *adoptDictionary, UErrorCode &status)
-    : DictionaryBreakEngine((1<<UBRK_WORD) | (1<<UBRK_LINE)),
+    : DictionaryBreakEngine(),
       fDictionary(adoptDictionary)
 {
+    UTRACE_ENTRY(UTRACE_UBRK_CREATE_BREAK_ENGINE);
+    UTRACE_DATA1(UTRACE_INFO, "dictbe=%s", "Laoo");
     fLaoWordSet.applyPattern(UNICODE_STRING_SIMPLE("[[:Laoo:]&[:LineBreak=SA:]]"), status);
     if (U_SUCCESS(status)) {
         setCharacters(fLaoWordSet);
@@ -477,6 +462,7 @@
     fMarkSet.compact();
     fEndWordSet.compact();
     fBeginWordSet.compact();
+    UTRACE_EXIT_STATUS(status);
 }
 
 LaoBreakEngine::~LaoBreakEngine() {
@@ -487,7 +473,7 @@
 LaoBreakEngine::divideUpDictionaryRange( UText *text,
                                                 int32_t rangeStart,
                                                 int32_t rangeEnd,
-                                                UStack &foundBreaks ) const {
+                                                UVector32 &foundBreaks ) const {
     if ((rangeEnd - rangeStart) < LAO_MIN_WORD_SPAN) {
         return 0;       // Not enough characters for two words
     }
@@ -570,9 +556,9 @@
                 UChar32 uc;
                 int32_t chars = 0;
                 for (;;) {
-                    int32_t pcIndex = utext_getNativeIndex(text);
+                    int32_t pcIndex = (int32_t)utext_getNativeIndex(text);
                     pc = utext_next32(text);
-                    int32_t pcSize = utext_getNativeIndex(text) - pcIndex;
+                    int32_t pcSize = (int32_t)utext_getNativeIndex(text) - pcIndex;
                     chars += pcSize;
                     remaining -= pcSize;
                     if (remaining <= 0) {
@@ -582,9 +568,9 @@
                     if (fEndWordSet.contains(pc) && fBeginWordSet.contains(uc)) {
                         // Maybe. See if it's in the dictionary.
                         // TODO: this looks iffy; compare with old code.
-                        int32_t candidates = words[(wordsFound + 1) % LAO_LOOKAHEAD].candidates(text, fDictionary, rangeEnd);
+                        int32_t num_candidates = words[(wordsFound + 1) % LAO_LOOKAHEAD].candidates(text, fDictionary, rangeEnd);
                         utext_setNativeIndex(text, current + cuWordLength + chars);
-                        if (candidates > 0) {
+                        if (num_candidates > 0) {
                             break;
                         }
                     }
@@ -654,9 +640,11 @@
 static const int32_t BURMESE_MIN_WORD_SPAN = BURMESE_MIN_WORD * 2;
 
 BurmeseBreakEngine::BurmeseBreakEngine(DictionaryMatcher *adoptDictionary, UErrorCode &status)
-    : DictionaryBreakEngine((1<<UBRK_WORD) | (1<<UBRK_LINE)),
+    : DictionaryBreakEngine(),
       fDictionary(adoptDictionary)
 {
+    UTRACE_ENTRY(UTRACE_UBRK_CREATE_BREAK_ENGINE);
+    UTRACE_DATA1(UTRACE_INFO, "dictbe=%s", "Mymr");
     fBurmeseWordSet.applyPattern(UNICODE_STRING_SIMPLE("[[:Mymr:]&[:LineBreak=SA:]]"), status);
     if (U_SUCCESS(status)) {
         setCharacters(fBurmeseWordSet);
@@ -670,6 +658,7 @@
     fMarkSet.compact();
     fEndWordSet.compact();
     fBeginWordSet.compact();
+    UTRACE_EXIT_STATUS(status);
 }
 
 BurmeseBreakEngine::~BurmeseBreakEngine() {
@@ -680,7 +669,7 @@
 BurmeseBreakEngine::divideUpDictionaryRange( UText *text,
                                                 int32_t rangeStart,
                                                 int32_t rangeEnd,
-                                                UStack &foundBreaks ) const {
+                                                UVector32 &foundBreaks ) const {
     if ((rangeEnd - rangeStart) < BURMESE_MIN_WORD_SPAN) {
         return 0;       // Not enough characters for two words
     }
@@ -763,9 +752,9 @@
                 UChar32 uc;
                 int32_t chars = 0;
                 for (;;) {
-                    int32_t pcIndex = utext_getNativeIndex(text);
+                    int32_t pcIndex = (int32_t)utext_getNativeIndex(text);
                     pc = utext_next32(text);
-                    int32_t pcSize = utext_getNativeIndex(text) - pcIndex;
+                    int32_t pcSize = (int32_t)utext_getNativeIndex(text) - pcIndex;
                     chars += pcSize;
                     remaining -= pcSize;
                     if (remaining <= 0) {
@@ -775,9 +764,9 @@
                     if (fEndWordSet.contains(pc) && fBeginWordSet.contains(uc)) {
                         // Maybe. See if it's in the dictionary.
                         // TODO: this looks iffy; compare with old code.
-                        int32_t candidates = words[(wordsFound + 1) % BURMESE_LOOKAHEAD].candidates(text, fDictionary, rangeEnd);
+                        int32_t num_candidates = words[(wordsFound + 1) % BURMESE_LOOKAHEAD].candidates(text, fDictionary, rangeEnd);
                         utext_setNativeIndex(text, current + cuWordLength + chars);
-                        if (candidates > 0) {
+                        if (num_candidates > 0) {
                             break;
                         }
                     }
@@ -847,9 +836,11 @@
 static const int32_t KHMER_MIN_WORD_SPAN = KHMER_MIN_WORD * 2;
 
 KhmerBreakEngine::KhmerBreakEngine(DictionaryMatcher *adoptDictionary, UErrorCode &status)
-    : DictionaryBreakEngine((1 << UBRK_WORD) | (1 << UBRK_LINE)),
+    : DictionaryBreakEngine(),
       fDictionary(adoptDictionary)
 {
+    UTRACE_ENTRY(UTRACE_UBRK_CREATE_BREAK_ENGINE);
+    UTRACE_DATA1(UTRACE_INFO, "dictbe=%s", "Khmr");
     fKhmerWordSet.applyPattern(UNICODE_STRING_SIMPLE("[[:Khmr:]&[:LineBreak=SA:]]"), status);
     if (U_SUCCESS(status)) {
         setCharacters(fKhmerWordSet);
@@ -875,6 +866,7 @@
     fEndWordSet.compact();
     fBeginWordSet.compact();
 //    fSuffixSet.compact();
+    UTRACE_EXIT_STATUS(status);
 }
 
 KhmerBreakEngine::~KhmerBreakEngine() {
@@ -885,7 +877,7 @@
 KhmerBreakEngine::divideUpDictionaryRange( UText *text,
                                                 int32_t rangeStart,
                                                 int32_t rangeEnd,
-                                                UStack &foundBreaks ) const {
+                                                UVector32 &foundBreaks ) const {
     if ((rangeEnd - rangeStart) < KHMER_MIN_WORD_SPAN) {
         return 0;       // Not enough characters for two words
     }
@@ -969,9 +961,9 @@
                 UChar32 uc;
                 int32_t chars = 0;
                 for (;;) {
-                    int32_t pcIndex = utext_getNativeIndex(text);
+                    int32_t pcIndex = (int32_t)utext_getNativeIndex(text);
                     pc = utext_next32(text);
-                    int32_t pcSize = utext_getNativeIndex(text) - pcIndex;
+                    int32_t pcSize = (int32_t)utext_getNativeIndex(text) - pcIndex;
                     chars += pcSize;
                     remaining -= pcSize;
                     if (remaining <= 0) {
@@ -980,9 +972,9 @@
                     uc = utext_current32(text);
                     if (fEndWordSet.contains(pc) && fBeginWordSet.contains(uc)) {
                         // Maybe. See if it's in the dictionary.
-                        int32_t candidates = words[(wordsFound + 1) % KHMER_LOOKAHEAD].candidates(text, fDictionary, rangeEnd);
+                        int32_t num_candidates = words[(wordsFound + 1) % KHMER_LOOKAHEAD].candidates(text, fDictionary, rangeEnd);
                         utext_setNativeIndex(text, current+cuWordLength+chars);
-                        if (candidates > 0) {
+                        if (num_candidates > 0) {
                             break;
                         }
                     }
@@ -1069,7 +1061,9 @@
  */
 static const uint32_t kuint32max = 0xFFFFFFFF;
 CjkBreakEngine::CjkBreakEngine(DictionaryMatcher *adoptDictionary, LanguageType type, UErrorCode &status)
-: DictionaryBreakEngine(1 << UBRK_WORD), fDictionary(adoptDictionary) {
+: DictionaryBreakEngine(), fDictionary(adoptDictionary) {
+    UTRACE_ENTRY(UTRACE_UBRK_CREATE_BREAK_ENGINE);
+    UTRACE_DATA1(UTRACE_INFO, "dictbe=%s", "Hani");
     // Korean dictionary only includes Hangul syllables
     fHangulWordSet.applyPattern(UNICODE_STRING_SIMPLE("[\\uac00-\\ud7a3]"), status);
     fHanWordSet.applyPattern(UNICODE_STRING_SIMPLE("[:Han:]"), status);
@@ -1091,6 +1085,7 @@
             setCharacters(cjSet);
         }
     }
+    UTRACE_EXIT_STATUS(status);
 }
 
 CjkBreakEngine::~CjkBreakEngine(){
@@ -1110,9 +1105,9 @@
     return (wordLength > kMaxKatakanaLength) ? 8192 : katakanaCost[wordLength];
 }
 
-static inline bool isKatakana(uint16_t value) {
-    return (value >= 0x30A1u && value <= 0x30FEu && value != 0x30FBu) ||
-            (value >= 0xFF66u && value <= 0xFF9fu);
+static inline bool isKatakana(UChar32 value) {
+    return (value >= 0x30A1 && value <= 0x30FE && value != 0x30FB) ||
+            (value >= 0xFF66 && value <= 0xFF9f);
 }
 
 
@@ -1128,14 +1123,14 @@
  * @param text A UText representing the text
  * @param rangeStart The start of the range of dictionary characters
  * @param rangeEnd The end of the range of dictionary characters
- * @param foundBreaks Output of C array of int32_t break positions, or 0
+ * @param foundBreaks vector<int32> to receive the break positions
  * @return The number of breaks found
  */
 int32_t 
 CjkBreakEngine::divideUpDictionaryRange( UText *inText,
         int32_t rangeStart,
         int32_t rangeEnd,
-        UStack &foundBreaks ) const {
+        UVector32 &foundBreaks ) const {
     if (rangeStart >= rangeEnd) {
         return 0;
     }
@@ -1168,14 +1163,14 @@
         int32_t limit = rangeEnd;
         U_ASSERT(limit <= utext_nativeLength(inText));
         if (limit > utext_nativeLength(inText)) {
-            limit = utext_nativeLength(inText);
+            limit = (int32_t)utext_nativeLength(inText);
         }
         inputMap.adoptInsteadAndCheckErrorCode(new UVector32(status), status);
         if (U_FAILURE(status)) {
             return 0;
         }
         while (utext_getNativeIndex(inText) < limit) {
-            int32_t nativePosition = utext_getNativeIndex(inText);
+            int32_t nativePosition = (int32_t)utext_getNativeIndex(inText);
             UChar32 c = utext_next32(inText);
             U_ASSERT(c != U_SENTINEL);
             inString.append(c);
@@ -1231,8 +1226,8 @@
                 inputMap->elementAti(inString.length()) : inString.length()+rangeStart;
         normalizedMap->addElement(nativeEnd, status);
 
-        inputMap.moveFrom(normalizedMap);
-        inString.moveFrom(normalizedInput);
+        inputMap = std::move(normalizedMap);
+        inString = std::move(normalizedInput);
     }
 
     int32_t numCodePts = inString.countChar32();
@@ -1295,6 +1290,7 @@
     //                ix is the corresponding string (code unit) index.
     //    They differ when the string contains supplementary characters.
     int32_t ix = 0;
+    bool is_prev_katakana = false;
     for (int32_t i = 0;  i < numCodePts;  ++i, ix = inString.moveIndex32(ix, 1)) {
         if ((uint32_t)bestSnlp.elementAti(i) == kuint32max) {
             continue;
@@ -1308,7 +1304,7 @@
                              //       The NULL parameter is the ignored code unit lengths.
 
         // if there are no single character matches found in the dictionary 
-        // starting with this charcter, treat character as a 1-character word 
+        // starting with this character, treat character as a 1-character word 
         // with the highest value possible, i.e. the least likely to occur.
         // Exclude Korean characters from this treatment, as they should be left
         // together by default.
@@ -1333,7 +1329,6 @@
         // characters is considered a candidate word with a default cost
         // specified in the katakanaCost table according to its length.
 
-        bool is_prev_katakana = false;
         bool is_katakana = isKatakana(inString.char32At(ix));
         int32_t katakanaRunLength = 1;
         if (!is_prev_katakana && is_katakana) {
@@ -1346,8 +1341,8 @@
             }
             if (katakanaRunLength < kMaxKatakanaGroupLength) {
                 uint32_t newSnlp = bestSnlp.elementAti(i) + getKatakanaCost(katakanaRunLength);
-                if (newSnlp < (uint32_t)bestSnlp.elementAti(j)) {
-                    bestSnlp.setElementAt(newSnlp, j);
+                if (newSnlp < (uint32_t)bestSnlp.elementAti(i+katakanaRunLength)) {
+                    bestSnlp.setElementAt(newSnlp, i+katakanaRunLength);
                     prev.setElementAt(i, i+katakanaRunLength);  // prev[j] = i;
                 }
             }
@@ -1385,13 +1380,27 @@
     // Now that we're done, convert positions in t_boundary[] (indices in 
     // the normalized input string) back to indices in the original input UText
     // while reversing t_boundary and pushing values to foundBreaks.
+    int32_t prevCPPos = -1;
+    int32_t prevUTextPos = -1;
     for (int32_t i = numBreaks-1; i >= 0; i--) {
         int32_t cpPos = t_boundary.elementAti(i);
+        U_ASSERT(cpPos > prevCPPos);
         int32_t utextPos =  inputMap.isValid() ? inputMap->elementAti(cpPos) : cpPos + rangeStart;
-        // Boundaries are added to foundBreaks output in ascending order.
-        U_ASSERT(foundBreaks.size() == 0 ||foundBreaks.peeki() < utextPos);
-        foundBreaks.push(utextPos, status);
+        U_ASSERT(utextPos >= prevUTextPos);
+        if (utextPos > prevUTextPos) {
+            // Boundaries are added to foundBreaks output in ascending order.
+            U_ASSERT(foundBreaks.size() == 0 || foundBreaks.peeki() < utextPos);
+            foundBreaks.push(utextPos, status);
+        } else {
+            // Normalization expanded the input text, the dictionary found a boundary
+            // within the expansion, giving two boundaries with the same index in the
+            // original text. Ignore the second. See ticket #12918.
+            --numBreaks;
+        }
+        prevCPPos = cpPos;
+        prevUTextPos = utextPos;
     }
+    (void)prevCPPos; // suppress compiler warnings about unused variable
 
     // inString goes out of scope
     // inputMap goes out of scope
diff --git a/src/third_party/icu/source/common/dictbe.h b/src/third_party/icu/source/common/dictbe.h
index d3488cd..4ea676f 100644
--- a/src/third_party/icu/source/common/dictbe.h
+++ b/src/third_party/icu/source/common/dictbe.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /**
  *******************************************************************************
  * Copyright (C) 2006-2014, International Business Machines Corporation   *
@@ -13,6 +15,7 @@
 #include "unicode/utext.h"
 
 #include "brkeng.h"
+#include "uvectr32.h"
 
 U_NAMESPACE_BEGIN
 
@@ -39,27 +42,12 @@
 
   UnicodeSet    fSet;
 
-    /**
-     * The set of break types handled by this engine
-     * @internal
-     */
-
-  uint32_t      fTypes;
-
-  /**
-   * <p>Default constructor.</p>
-   *
-   */
-  DictionaryBreakEngine();
-
  public:
 
   /**
-   * <p>Constructor setting the break types handled.</p>
-   *
-   * @param breakTypes A bitmap of types handled by the engine.
+   * <p>Constructor </p>
    */
-  DictionaryBreakEngine( uint32_t breakTypes );
+  DictionaryBreakEngine();
 
   /**
    * <p>Virtual destructor.</p>
@@ -71,32 +59,26 @@
    * a particular kind of break.</p>
    *
    * @param c A character which begins a run that the engine might handle
-   * @param breakType The type of text break which the caller wants to determine
-   * @return TRUE if this engine handles the particular character and break
+   * @return true if this engine handles the particular character and break
    * type.
    */
-  virtual UBool handles( UChar32 c, int32_t breakType ) const;
+  virtual UBool handles(UChar32 c) const;
 
   /**
    * <p>Find any breaks within a run in the supplied text.</p>
    *
    * @param text A UText representing the text. The iterator is left at
    * the end of the run of characters which the engine is capable of handling 
-   * that starts from the first (or last) character in the range.
+   * that starts from the first character in the range.
    * @param startPos The start of the run within the supplied text.
    * @param endPos The end of the run within the supplied text.
-   * @param reverse Whether the caller is looking for breaks in a reverse
-   * direction.
-   * @param breakType The type of break desired, or -1.
-   * @param foundBreaks An allocated C array of the breaks found, if any
+   * @param foundBreaks vector of int32_t to receive the break positions
    * @return The number of breaks found.
    */
   virtual int32_t findBreaks( UText *text,
                               int32_t startPos,
                               int32_t endPos,
-                              UBool reverse,
-                              int32_t breakType,
-                              UStack &foundBreaks ) const;
+                              UVector32 &foundBreaks ) const;
 
  protected:
 
@@ -108,13 +90,6 @@
   virtual void setCharacters( const UnicodeSet &set );
 
  /**
-  * <p>Set the break types handled by this engine.</p>
-  *
-  * @param breakTypes A bitmap of types handled by the engine.
-  */
-//  virtual void setBreakTypes( uint32_t breakTypes );
-
- /**
   * <p>Divide up a range of known dictionary characters handled by this break engine.</p>
   *
   * @param text A UText representing the text
@@ -126,7 +101,7 @@
   virtual int32_t divideUpDictionaryRange( UText *text,
                                            int32_t rangeStart,
                                            int32_t rangeEnd,
-                                           UStack &foundBreaks ) const = 0;
+                                           UVector32 &foundBreaks ) const = 0;
 
 };
 
@@ -183,7 +158,7 @@
   virtual int32_t divideUpDictionaryRange( UText *text,
                                            int32_t rangeStart,
                                            int32_t rangeEnd,
-                                           UStack &foundBreaks ) const;
+                                           UVector32 &foundBreaks ) const;
 
 };
 
@@ -239,7 +214,7 @@
   virtual int32_t divideUpDictionaryRange( UText *text,
                                            int32_t rangeStart,
                                            int32_t rangeEnd,
-                                           UStack &foundBreaks ) const;
+                                           UVector32 &foundBreaks ) const;
 
 };
 
@@ -295,7 +270,7 @@
   virtual int32_t divideUpDictionaryRange( UText *text, 
                                            int32_t rangeStart, 
                                            int32_t rangeEnd, 
-                                           UStack &foundBreaks ) const; 
+                                           UVector32 &foundBreaks ) const; 
  
 }; 
  
@@ -351,7 +326,7 @@
   virtual int32_t divideUpDictionaryRange( UText *text, 
                                            int32_t rangeStart, 
                                            int32_t rangeEnd, 
-                                           UStack &foundBreaks ) const; 
+                                           UVector32 &foundBreaks ) const; 
  
 }; 
  
@@ -415,7 +390,7 @@
   virtual int32_t divideUpDictionaryRange( UText *text,
           int32_t rangeStart,
           int32_t rangeEnd,
-          UStack &foundBreaks ) const;
+          UVector32 &foundBreaks ) const;
 
 };
 
diff --git a/src/third_party/icu/source/common/dictionarydata.cpp b/src/third_party/icu/source/common/dictionarydata.cpp
index ffcf745..0a5f676 100644
--- a/src/third_party/icu/source/common/dictionarydata.cpp
+++ b/src/third_party/icu/source/common/dictionarydata.cpp
@@ -1,6 +1,8 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
-* Copyright (C) 2014, International Business Machines
+* Copyright (C) 2014-2016, International Business Machines
 * Corporation and others.  All Rights Reserved.
 *******************************************************************************
 * dictionarydata.h
@@ -9,7 +11,9 @@
 * created by: Markus W. Scherer & Maxime Serrano
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "dictionarydata.h"
 #include "unicode/ucharstrie.h"
 #include "unicode/bytestrie.h"
@@ -46,13 +50,13 @@
                             int32_t *prefix) const {
 
     UCharsTrie uct(characters);
-    int32_t startingTextIndex = utext_getNativeIndex(text);
+    int32_t startingTextIndex = (int32_t)utext_getNativeIndex(text);
     int32_t wordCount = 0;
     int32_t codePointsMatched = 0;
 
     for (UChar32 c = utext_next32(text); c >= 0; c=utext_next32(text)) {
         UStringTrieResult result = (codePointsMatched == 0) ? uct.first(c) : uct.next(c);
-        int32_t lengthMatched = utext_getNativeIndex(text) - startingTextIndex;
+        int32_t lengthMatched = (int32_t)utext_getNativeIndex(text) - startingTextIndex;
         codePointsMatched += 1;
         if (USTRINGTRIE_HAS_VALUE(result)) {
             if (wordCount < limit) {
@@ -113,13 +117,13 @@
                             int32_t *lengths, int32_t *cpLengths, int32_t *values,
                             int32_t *prefix) const {
     BytesTrie bt(characters);
-    int32_t startingTextIndex = utext_getNativeIndex(text);
+    int32_t startingTextIndex = (int32_t)utext_getNativeIndex(text);
     int32_t wordCount = 0;
     int32_t codePointsMatched = 0;
 
     for (UChar32 c = utext_next32(text); c >= 0; c=utext_next32(text)) {
         UStringTrieResult result = (codePointsMatched == 0) ? bt.first(transform(c)) : bt.next(transform(c));
-        int32_t lengthMatched = utext_getNativeIndex(text) - startingTextIndex;
+        int32_t lengthMatched = (int32_t)utext_getNativeIndex(text) - startingTextIndex;
         codePointsMatched += 1;
         if (USTRINGTRIE_HAS_VALUE(result)) {
             if (wordCount < limit) {
diff --git a/src/third_party/icu/source/common/dictionarydata.h b/src/third_party/icu/source/common/dictionarydata.h
index 0216ab0..0d303d9 100644
--- a/src/third_party/icu/source/common/dictionarydata.h
+++ b/src/third_party/icu/source/common/dictionarydata.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 * Copyright (C) 2014, International Business Machines
@@ -66,7 +68,7 @@
  */
 class U_COMMON_API DictionaryMatcher : public UMemory {
 public:
-    DictionaryMatcher() {};
+    DictionaryMatcher() {}
     virtual ~DictionaryMatcher();
     // this should emulate CompactTrieDictionary::matches()
     /*  @param text      The text in which to look for matching words. Matching begins
diff --git a/src/third_party/icu/source/common/dtintrv.cpp b/src/third_party/icu/source/common/dtintrv.cpp
index bece836..80bb5d6 100644
--- a/src/third_party/icu/source/common/dtintrv.cpp
+++ b/src/third_party/icu/source/common/dtintrv.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*******************************************************************************
 * Copyright (C) 2008, International Business Machines Corporation and
 * others. All Rights Reserved.
diff --git a/src/third_party/icu/source/common/edits.cpp b/src/third_party/icu/source/common/edits.cpp
new file mode 100644
index 0000000..95f0c19
--- /dev/null
+++ b/src/third_party/icu/source/common/edits.cpp
@@ -0,0 +1,803 @@
+// © 2017 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+// edits.cpp
+// created: 2017feb08 Markus W. Scherer
+
+#include "unicode/edits.h"
+#include "unicode/unistr.h"
+#include "unicode/utypes.h"
+#include "cmemory.h"
+#include "uassert.h"
+#include "util.h"
+
+U_NAMESPACE_BEGIN
+
+namespace {
+
+// 0000uuuuuuuuuuuu records u+1 unchanged text units.
+const int32_t MAX_UNCHANGED_LENGTH = 0x1000;
+const int32_t MAX_UNCHANGED = MAX_UNCHANGED_LENGTH - 1;
+
+// 0mmmnnnccccccccc with m=1..6 records ccc+1 replacements of m:n text units.
+const int32_t MAX_SHORT_CHANGE_OLD_LENGTH = 6;
+const int32_t MAX_SHORT_CHANGE_NEW_LENGTH = 7;
+const int32_t SHORT_CHANGE_NUM_MASK = 0x1ff;
+const int32_t MAX_SHORT_CHANGE = 0x6fff;
+
+// 0111mmmmmmnnnnnn records a replacement of m text units with n.
+// m or n = 61: actual length follows in the next edits array unit.
+// m or n = 62..63: actual length follows in the next two edits array units.
+// Bit 30 of the actual length is in the head unit.
+// Trailing units have bit 15 set.
+const int32_t LENGTH_IN_1TRAIL = 61;
+const int32_t LENGTH_IN_2TRAIL = 62;
+
+}  // namespace
+
+void Edits::releaseArray() U_NOEXCEPT {
+    if (array != stackArray) {
+        uprv_free(array);
+    }
+}
+
+Edits &Edits::copyArray(const Edits &other) {
+    if (U_FAILURE(errorCode_)) {
+        length = delta = numChanges = 0;
+        return *this;
+    }
+    if (length > capacity) {
+        uint16_t *newArray = (uint16_t *)uprv_malloc((size_t)length * 2);
+        if (newArray == nullptr) {
+            length = delta = numChanges = 0;
+            errorCode_ = U_MEMORY_ALLOCATION_ERROR;
+            return *this;
+        }
+        releaseArray();
+        array = newArray;
+        capacity = length;
+    }
+    if (length > 0) {
+        uprv_memcpy(array, other.array, (size_t)length * 2);
+    }
+    return *this;
+}
+
+Edits &Edits::moveArray(Edits &src) U_NOEXCEPT {
+    if (U_FAILURE(errorCode_)) {
+        length = delta = numChanges = 0;
+        return *this;
+    }
+    releaseArray();
+    if (length > STACK_CAPACITY) {
+        array = src.array;
+        capacity = src.capacity;
+        src.array = src.stackArray;
+        src.capacity = STACK_CAPACITY;
+        src.reset();
+        return *this;
+    }
+    array = stackArray;
+    capacity = STACK_CAPACITY;
+    if (length > 0) {
+        uprv_memcpy(array, src.array, (size_t)length * 2);
+    }
+    return *this;
+}
+
+Edits &Edits::operator=(const Edits &other) {
+    length = other.length;
+    delta = other.delta;
+    numChanges = other.numChanges;
+    errorCode_ = other.errorCode_;
+    return copyArray(other);
+}
+
+Edits &Edits::operator=(Edits &&src) U_NOEXCEPT {
+    length = src.length;
+    delta = src.delta;
+    numChanges = src.numChanges;
+    errorCode_ = src.errorCode_;
+    return moveArray(src);
+}
+
+Edits::~Edits() {
+    releaseArray();
+}
+
+void Edits::reset() U_NOEXCEPT {
+    length = delta = numChanges = 0;
+    errorCode_ = U_ZERO_ERROR;
+}
+
+void Edits::addUnchanged(int32_t unchangedLength) {
+    if(U_FAILURE(errorCode_) || unchangedLength == 0) { return; }
+    if(unchangedLength < 0) {
+        errorCode_ = U_ILLEGAL_ARGUMENT_ERROR;
+        return;
+    }
+    // Merge into previous unchanged-text record, if any.
+    int32_t last = lastUnit();
+    if(last < MAX_UNCHANGED) {
+        int32_t remaining = MAX_UNCHANGED - last;
+        if (remaining >= unchangedLength) {
+            setLastUnit(last + unchangedLength);
+            return;
+        }
+        setLastUnit(MAX_UNCHANGED);
+        unchangedLength -= remaining;
+    }
+    // Split large lengths into multiple units.
+    while(unchangedLength >= MAX_UNCHANGED_LENGTH) {
+        append(MAX_UNCHANGED);
+        unchangedLength -= MAX_UNCHANGED_LENGTH;
+    }
+    // Write a small (remaining) length.
+    if(unchangedLength > 0) {
+        append(unchangedLength - 1);
+    }
+}
+
+void Edits::addReplace(int32_t oldLength, int32_t newLength) {
+    if(U_FAILURE(errorCode_)) { return; }
+    if(oldLength < 0 || newLength < 0) {
+        errorCode_ = U_ILLEGAL_ARGUMENT_ERROR;
+        return;
+    }
+    if (oldLength == 0 && newLength == 0) {
+        return;
+    }
+    ++numChanges;
+    int32_t newDelta = newLength - oldLength;
+    if (newDelta != 0) {
+        if ((newDelta > 0 && delta >= 0 && newDelta > (INT32_MAX - delta)) ||
+                (newDelta < 0 && delta < 0 && newDelta < (INT32_MIN - delta))) {
+            // Integer overflow or underflow.
+            errorCode_ = U_INDEX_OUTOFBOUNDS_ERROR;
+            return;
+        }
+        delta += newDelta;
+    }
+
+    if(0 < oldLength && oldLength <= MAX_SHORT_CHANGE_OLD_LENGTH &&
+            newLength <= MAX_SHORT_CHANGE_NEW_LENGTH) {
+        // Merge into previous same-lengths short-replacement record, if any.
+        int32_t u = (oldLength << 12) | (newLength << 9);
+        int32_t last = lastUnit();
+        if(MAX_UNCHANGED < last && last < MAX_SHORT_CHANGE &&
+                (last & ~SHORT_CHANGE_NUM_MASK) == u &&
+                (last & SHORT_CHANGE_NUM_MASK) < SHORT_CHANGE_NUM_MASK) {
+            setLastUnit(last + 1);
+            return;
+        }
+        append(u);
+        return;
+    }
+
+    int32_t head = 0x7000;
+    if (oldLength < LENGTH_IN_1TRAIL && newLength < LENGTH_IN_1TRAIL) {
+        head |= oldLength << 6;
+        head |= newLength;
+        append(head);
+    } else if ((capacity - length) >= 5 || growArray()) {
+        int32_t limit = length + 1;
+        if(oldLength < LENGTH_IN_1TRAIL) {
+            head |= oldLength << 6;
+        } else if(oldLength <= 0x7fff) {
+            head |= LENGTH_IN_1TRAIL << 6;
+            array[limit++] = (uint16_t)(0x8000 | oldLength);
+        } else {
+            head |= (LENGTH_IN_2TRAIL + (oldLength >> 30)) << 6;
+            array[limit++] = (uint16_t)(0x8000 | (oldLength >> 15));
+            array[limit++] = (uint16_t)(0x8000 | oldLength);
+        }
+        if(newLength < LENGTH_IN_1TRAIL) {
+            head |= newLength;
+        } else if(newLength <= 0x7fff) {
+            head |= LENGTH_IN_1TRAIL;
+            array[limit++] = (uint16_t)(0x8000 | newLength);
+        } else {
+            head |= LENGTH_IN_2TRAIL + (newLength >> 30);
+            array[limit++] = (uint16_t)(0x8000 | (newLength >> 15));
+            array[limit++] = (uint16_t)(0x8000 | newLength);
+        }
+        array[length] = (uint16_t)head;
+        length = limit;
+    }
+}
+
+void Edits::append(int32_t r) {
+    if(length < capacity || growArray()) {
+        array[length++] = (uint16_t)r;
+    }
+}
+
+UBool Edits::growArray() {
+    int32_t newCapacity;
+    if (array == stackArray) {
+        newCapacity = 2000;
+    } else if (capacity == INT32_MAX) {
+        // Not U_BUFFER_OVERFLOW_ERROR because that could be confused on a string transform API
+        // with a result-string-buffer overflow.
+        errorCode_ = U_INDEX_OUTOFBOUNDS_ERROR;
+        return FALSE;
+    } else if (capacity >= (INT32_MAX / 2)) {
+        newCapacity = INT32_MAX;
+    } else {
+        newCapacity = 2 * capacity;
+    }
+    // Grow by at least 5 units so that a maximal change record will fit.
+    if ((newCapacity - capacity) < 5) {
+        errorCode_ = U_INDEX_OUTOFBOUNDS_ERROR;
+        return FALSE;
+    }
+    uint16_t *newArray = (uint16_t *)uprv_malloc((size_t)newCapacity * 2);
+    if (newArray == NULL) {
+        errorCode_ = U_MEMORY_ALLOCATION_ERROR;
+        return FALSE;
+    }
+    uprv_memcpy(newArray, array, (size_t)length * 2);
+    releaseArray();
+    array = newArray;
+    capacity = newCapacity;
+    return TRUE;
+}
+
+UBool Edits::copyErrorTo(UErrorCode &outErrorCode) const {
+    if (U_FAILURE(outErrorCode)) { return TRUE; }
+    if (U_SUCCESS(errorCode_)) { return FALSE; }
+    outErrorCode = errorCode_;
+    return TRUE;
+}
+
+Edits &Edits::mergeAndAppend(const Edits &ab, const Edits &bc, UErrorCode &errorCode) {
+    if (copyErrorTo(errorCode)) { return *this; }
+    // Picture string a --(Edits ab)--> string b --(Edits bc)--> string c.
+    // Parallel iteration over both Edits.
+    Iterator abIter = ab.getFineIterator();
+    Iterator bcIter = bc.getFineIterator();
+    UBool abHasNext = TRUE, bcHasNext = TRUE;
+    // Copy iterator state into local variables, so that we can modify and subdivide spans.
+    // ab old & new length, bc old & new length
+    int32_t aLength = 0, ab_bLength = 0, bc_bLength = 0, cLength = 0;
+    // When we have different-intermediate-length changes, we accumulate a larger change.
+    int32_t pending_aLength = 0, pending_cLength = 0;
+    for (;;) {
+        // At this point, for each of the two iterators:
+        // Either we are done with the locally cached current edit,
+        // and its intermediate-string length has been reset,
+        // or we will continue to work with a truncated remainder of this edit.
+        //
+        // If the current edit is done, and the iterator has not yet reached the end,
+        // then we fetch the next edit. This is true for at least one of the iterators.
+        //
+        // Normally it does not matter whether we fetch from ab and then bc or vice versa.
+        // However, the result is observably different when
+        // ab deletions meet bc insertions at the same intermediate-string index.
+        // Some users expect the bc insertions to come first, so we fetch from bc first.
+        if (bc_bLength == 0) {
+            if (bcHasNext && (bcHasNext = bcIter.next(errorCode)) != 0) {
+                bc_bLength = bcIter.oldLength();
+                cLength = bcIter.newLength();
+                if (bc_bLength == 0) {
+                    // insertion
+                    if (ab_bLength == 0 || !abIter.hasChange()) {
+                        addReplace(pending_aLength, pending_cLength + cLength);
+                        pending_aLength = pending_cLength = 0;
+                    } else {
+                        pending_cLength += cLength;
+                    }
+                    continue;
+                }
+            }
+            // else see if the other iterator is done, too.
+        }
+        if (ab_bLength == 0) {
+            if (abHasNext && (abHasNext = abIter.next(errorCode)) != 0) {
+                aLength = abIter.oldLength();
+                ab_bLength = abIter.newLength();
+                if (ab_bLength == 0) {
+                    // deletion
+                    if (bc_bLength == bcIter.oldLength() || !bcIter.hasChange()) {
+                        addReplace(pending_aLength + aLength, pending_cLength);
+                        pending_aLength = pending_cLength = 0;
+                    } else {
+                        pending_aLength += aLength;
+                    }
+                    continue;
+                }
+            } else if (bc_bLength == 0) {
+                // Both iterators are done at the same time:
+                // The intermediate-string lengths match.
+                break;
+            } else {
+                // The ab output string is shorter than the bc input string.
+                if (!copyErrorTo(errorCode)) {
+                    errorCode = U_ILLEGAL_ARGUMENT_ERROR;
+                }
+                return *this;
+            }
+        }
+        if (bc_bLength == 0) {
+            // The bc input string is shorter than the ab output string.
+            if (!copyErrorTo(errorCode)) {
+                errorCode = U_ILLEGAL_ARGUMENT_ERROR;
+            }
+            return *this;
+        }
+        //  Done fetching: ab_bLength > 0 && bc_bLength > 0
+
+        // The current state has two parts:
+        // - Past: We accumulate a longer ac edit in the "pending" variables.
+        // - Current: We have copies of the current ab/bc edits in local variables.
+        //   At least one side is newly fetched.
+        //   One side might be a truncated remainder of an edit we fetched earlier.
+
+        if (!abIter.hasChange() && !bcIter.hasChange()) {
+            // An unchanged span all the way from string a to string c.
+            if (pending_aLength != 0 || pending_cLength != 0) {
+                addReplace(pending_aLength, pending_cLength);
+                pending_aLength = pending_cLength = 0;
+            }
+            int32_t unchangedLength = aLength <= cLength ? aLength : cLength;
+            addUnchanged(unchangedLength);
+            ab_bLength = aLength -= unchangedLength;
+            bc_bLength = cLength -= unchangedLength;
+            // At least one of the unchanged spans is now empty.
+            continue;
+        }
+        if (!abIter.hasChange() && bcIter.hasChange()) {
+            // Unchanged a->b but changed b->c.
+            if (ab_bLength >= bc_bLength) {
+                // Split the longer unchanged span into change + remainder.
+                addReplace(pending_aLength + bc_bLength, pending_cLength + cLength);
+                pending_aLength = pending_cLength = 0;
+                aLength = ab_bLength -= bc_bLength;
+                bc_bLength = 0;
+                continue;
+            }
+            // Handle the shorter unchanged span below like a change.
+        } else if (abIter.hasChange() && !bcIter.hasChange()) {
+            // Changed a->b and then unchanged b->c.
+            if (ab_bLength <= bc_bLength) {
+                // Split the longer unchanged span into change + remainder.
+                addReplace(pending_aLength + aLength, pending_cLength + ab_bLength);
+                pending_aLength = pending_cLength = 0;
+                cLength = bc_bLength -= ab_bLength;
+                ab_bLength = 0;
+                continue;
+            }
+            // Handle the shorter unchanged span below like a change.
+        } else {  // both abIter.hasChange() && bcIter.hasChange()
+            if (ab_bLength == bc_bLength) {
+                // Changes on both sides up to the same position. Emit & reset.
+                addReplace(pending_aLength + aLength, pending_cLength + cLength);
+                pending_aLength = pending_cLength = 0;
+                ab_bLength = bc_bLength = 0;
+                continue;
+            }
+        }
+        // Accumulate the a->c change, reset the shorter side,
+        // keep a remainder of the longer one.
+        pending_aLength += aLength;
+        pending_cLength += cLength;
+        if (ab_bLength < bc_bLength) {
+            bc_bLength -= ab_bLength;
+            cLength = ab_bLength = 0;
+        } else {  // ab_bLength > bc_bLength
+            ab_bLength -= bc_bLength;
+            aLength = bc_bLength = 0;
+        }
+    }
+    if (pending_aLength != 0 || pending_cLength != 0) {
+        addReplace(pending_aLength, pending_cLength);
+    }
+    copyErrorTo(errorCode);
+    return *this;
+}
+
+Edits::Iterator::Iterator(const uint16_t *a, int32_t len, UBool oc, UBool crs) :
+        array(a), index(0), length(len), remaining(0),
+        onlyChanges_(oc), coarse(crs),
+        dir(0), changed(FALSE), oldLength_(0), newLength_(0),
+        srcIndex(0), replIndex(0), destIndex(0) {}
+
+int32_t Edits::Iterator::readLength(int32_t head) {
+    if (head < LENGTH_IN_1TRAIL) {
+        return head;
+    } else if (head < LENGTH_IN_2TRAIL) {
+        U_ASSERT(index < length);
+        U_ASSERT(array[index] >= 0x8000);
+        return array[index++] & 0x7fff;
+    } else {
+        U_ASSERT((index + 2) <= length);
+        U_ASSERT(array[index] >= 0x8000);
+        U_ASSERT(array[index + 1] >= 0x8000);
+        int32_t len = ((head & 1) << 30) |
+                ((int32_t)(array[index] & 0x7fff) << 15) |
+                (array[index + 1] & 0x7fff);
+        index += 2;
+        return len;
+    }
+}
+
+void Edits::Iterator::updateNextIndexes() {
+    srcIndex += oldLength_;
+    if (changed) {
+        replIndex += newLength_;
+    }
+    destIndex += newLength_;
+}
+
+void Edits::Iterator::updatePreviousIndexes() {
+    srcIndex -= oldLength_;
+    if (changed) {
+        replIndex -= newLength_;
+    }
+    destIndex -= newLength_;
+}
+
+UBool Edits::Iterator::noNext() {
+    // No change before or beyond the string.
+    dir = 0;
+    changed = FALSE;
+    oldLength_ = newLength_ = 0;
+    return FALSE;
+}
+
+UBool Edits::Iterator::next(UBool onlyChanges, UErrorCode &errorCode) {
+    // Forward iteration: Update the string indexes to the limit of the current span,
+    // and post-increment-read array units to assemble a new span.
+    // Leaves the array index one after the last unit of that span.
+    if (U_FAILURE(errorCode)) { return FALSE; }
+    // We have an errorCode in case we need to start guarding against integer overflows.
+    // It is also convenient for caller loops if we bail out when an error was set elsewhere.
+    if (dir > 0) {
+        updateNextIndexes();
+    } else {
+        if (dir < 0) {
+            // Turn around from previous() to next().
+            // Post-increment-read the same span again.
+            if (remaining > 0) {
+                // Fine-grained iterator:
+                // Stay on the current one of a sequence of compressed changes.
+                ++index;  // next() rests on the index after the sequence unit.
+                dir = 1;
+                return TRUE;
+            }
+        }
+        dir = 1;
+    }
+    if (remaining >= 1) {
+        // Fine-grained iterator: Continue a sequence of compressed changes.
+        if (remaining > 1) {
+            --remaining;
+            return TRUE;
+        }
+        remaining = 0;
+    }
+    if (index >= length) {
+        return noNext();
+    }
+    int32_t u = array[index++];
+    if (u <= MAX_UNCHANGED) {
+        // Combine adjacent unchanged ranges.
+        changed = FALSE;
+        oldLength_ = u + 1;
+        while (index < length && (u = array[index]) <= MAX_UNCHANGED) {
+            ++index;
+            oldLength_ += u + 1;
+        }
+        newLength_ = oldLength_;
+        if (onlyChanges) {
+            updateNextIndexes();
+            if (index >= length) {
+                return noNext();
+            }
+            // already fetched u > MAX_UNCHANGED at index
+            ++index;
+        } else {
+            return TRUE;
+        }
+    }
+    changed = TRUE;
+    if (u <= MAX_SHORT_CHANGE) {
+        int32_t oldLen = u >> 12;
+        int32_t newLen = (u >> 9) & MAX_SHORT_CHANGE_NEW_LENGTH;
+        int32_t num = (u & SHORT_CHANGE_NUM_MASK) + 1;
+        if (coarse) {
+            oldLength_ = num * oldLen;
+            newLength_ = num * newLen;
+        } else {
+            // Split a sequence of changes that was compressed into one unit.
+            oldLength_ = oldLen;
+            newLength_ = newLen;
+            if (num > 1) {
+                remaining = num;  // This is the first of two or more changes.
+            }
+            return TRUE;
+        }
+    } else {
+        U_ASSERT(u <= 0x7fff);
+        oldLength_ = readLength((u >> 6) & 0x3f);
+        newLength_ = readLength(u & 0x3f);
+        if (!coarse) {
+            return TRUE;
+        }
+    }
+    // Combine adjacent changes.
+    while (index < length && (u = array[index]) > MAX_UNCHANGED) {
+        ++index;
+        if (u <= MAX_SHORT_CHANGE) {
+            int32_t num = (u & SHORT_CHANGE_NUM_MASK) + 1;
+            oldLength_ += (u >> 12) * num;
+            newLength_ += ((u >> 9) & MAX_SHORT_CHANGE_NEW_LENGTH) * num;
+        } else {
+            U_ASSERT(u <= 0x7fff);
+            oldLength_ += readLength((u >> 6) & 0x3f);
+            newLength_ += readLength(u & 0x3f);
+        }
+    }
+    return TRUE;
+}
+
+UBool Edits::Iterator::previous(UErrorCode &errorCode) {
+    // Backward iteration: Pre-decrement-read array units to assemble a new span,
+    // then update the string indexes to the start of that span.
+    // Leaves the array index on the head unit of that span.
+    if (U_FAILURE(errorCode)) { return FALSE; }
+    // We have an errorCode in case we need to start guarding against integer overflows.
+    // It is also convenient for caller loops if we bail out when an error was set elsewhere.
+    if (dir >= 0) {
+        if (dir > 0) {
+            // Turn around from next() to previous().
+            // Set the string indexes to the span limit and
+            // pre-decrement-read the same span again.
+            if (remaining > 0) {
+                // Fine-grained iterator:
+                // Stay on the current one of a sequence of compressed changes.
+                --index;  // previous() rests on the sequence unit.
+                dir = -1;
+                return TRUE;
+            }
+            updateNextIndexes();
+        }
+        dir = -1;
+    }
+    if (remaining > 0) {
+        // Fine-grained iterator: Continue a sequence of compressed changes.
+        int32_t u = array[index];
+        U_ASSERT(MAX_UNCHANGED < u && u <= MAX_SHORT_CHANGE);
+        if (remaining <= (u & SHORT_CHANGE_NUM_MASK)) {
+            ++remaining;
+            updatePreviousIndexes();
+            return TRUE;
+        }
+        remaining = 0;
+    }
+    if (index <= 0) {
+        return noNext();
+    }
+    int32_t u = array[--index];
+    if (u <= MAX_UNCHANGED) {
+        // Combine adjacent unchanged ranges.
+        changed = FALSE;
+        oldLength_ = u + 1;
+        while (index > 0 && (u = array[index - 1]) <= MAX_UNCHANGED) {
+            --index;
+            oldLength_ += u + 1;
+        }
+        newLength_ = oldLength_;
+        // No need to handle onlyChanges as long as previous() is called only from findIndex().
+        updatePreviousIndexes();
+        return TRUE;
+    }
+    changed = TRUE;
+    if (u <= MAX_SHORT_CHANGE) {
+        int32_t oldLen = u >> 12;
+        int32_t newLen = (u >> 9) & MAX_SHORT_CHANGE_NEW_LENGTH;
+        int32_t num = (u & SHORT_CHANGE_NUM_MASK) + 1;
+        if (coarse) {
+            oldLength_ = num * oldLen;
+            newLength_ = num * newLen;
+        } else {
+            // Split a sequence of changes that was compressed into one unit.
+            oldLength_ = oldLen;
+            newLength_ = newLen;
+            if (num > 1) {
+                remaining = 1;  // This is the last of two or more changes.
+            }
+            updatePreviousIndexes();
+            return TRUE;
+        }
+    } else {
+        if (u <= 0x7fff) {
+            // The change is encoded in u alone.
+            oldLength_ = readLength((u >> 6) & 0x3f);
+            newLength_ = readLength(u & 0x3f);
+        } else {
+            // Back up to the head of the change, read the lengths,
+            // and reset the index to the head again.
+            U_ASSERT(index > 0);
+            while ((u = array[--index]) > 0x7fff) {}
+            U_ASSERT(u > MAX_SHORT_CHANGE);
+            int32_t headIndex = index++;
+            oldLength_ = readLength((u >> 6) & 0x3f);
+            newLength_ = readLength(u & 0x3f);
+            index = headIndex;
+        }
+        if (!coarse) {
+            updatePreviousIndexes();
+            return TRUE;
+        }
+    }
+    // Combine adjacent changes.
+    while (index > 0 && (u = array[index - 1]) > MAX_UNCHANGED) {
+        --index;
+        if (u <= MAX_SHORT_CHANGE) {
+            int32_t num = (u & SHORT_CHANGE_NUM_MASK) + 1;
+            oldLength_ += (u >> 12) * num;
+            newLength_ += ((u >> 9) & MAX_SHORT_CHANGE_NEW_LENGTH) * num;
+        } else if (u <= 0x7fff) {
+            // Read the lengths, and reset the index to the head again.
+            int32_t headIndex = index++;
+            oldLength_ += readLength((u >> 6) & 0x3f);
+            newLength_ += readLength(u & 0x3f);
+            index = headIndex;
+        }
+    }
+    updatePreviousIndexes();
+    return TRUE;
+}
+
+int32_t Edits::Iterator::findIndex(int32_t i, UBool findSource, UErrorCode &errorCode) {
+    if (U_FAILURE(errorCode) || i < 0) { return -1; }
+    int32_t spanStart, spanLength;
+    if (findSource) {  // find source index
+        spanStart = srcIndex;
+        spanLength = oldLength_;
+    } else {  // find destination index
+        spanStart = destIndex;
+        spanLength = newLength_;
+    }
+    if (i < spanStart) {
+        if (i >= (spanStart / 2)) {
+            // Search backwards.
+            for (;;) {
+                UBool hasPrevious = previous(errorCode);
+                U_ASSERT(hasPrevious);  // because i>=0 and the first span starts at 0
+                (void)hasPrevious;  // avoid unused-variable warning
+                spanStart = findSource ? srcIndex : destIndex;
+                if (i >= spanStart) {
+                    // The index is in the current span.
+                    return 0;
+                }
+                if (remaining > 0) {
+                    // Is the index in one of the remaining compressed edits?
+                    // spanStart is the start of the current span, first of the remaining ones.
+                    spanLength = findSource ? oldLength_ : newLength_;
+                    int32_t u = array[index];
+                    U_ASSERT(MAX_UNCHANGED < u && u <= MAX_SHORT_CHANGE);
+                    int32_t num = (u & SHORT_CHANGE_NUM_MASK) + 1 - remaining;
+                    int32_t len = num * spanLength;
+                    if (i >= (spanStart - len)) {
+                        int32_t n = ((spanStart - i - 1) / spanLength) + 1;
+                        // 1 <= n <= num
+                        srcIndex -= n * oldLength_;
+                        replIndex -= n * newLength_;
+                        destIndex -= n * newLength_;
+                        remaining += n;
+                        return 0;
+                    }
+                    // Skip all of these edits at once.
+                    srcIndex -= num * oldLength_;
+                    replIndex -= num * newLength_;
+                    destIndex -= num * newLength_;
+                    remaining = 0;
+                }
+            }
+        }
+        // Reset the iterator to the start.
+        dir = 0;
+        index = remaining = oldLength_ = newLength_ = srcIndex = replIndex = destIndex = 0;
+    } else if (i < (spanStart + spanLength)) {
+        // The index is in the current span.
+        return 0;
+    }
+    while (next(FALSE, errorCode)) {
+        if (findSource) {
+            spanStart = srcIndex;
+            spanLength = oldLength_;
+        } else {
+            spanStart = destIndex;
+            spanLength = newLength_;
+        }
+        if (i < (spanStart + spanLength)) {
+            // The index is in the current span.
+            return 0;
+        }
+        if (remaining > 1) {
+            // Is the index in one of the remaining compressed edits?
+            // spanStart is the start of the current span, first of the remaining ones.
+            int32_t len = remaining * spanLength;
+            if (i < (spanStart + len)) {
+                int32_t n = (i - spanStart) / spanLength;  // 1 <= n <= remaining - 1
+                srcIndex += n * oldLength_;
+                replIndex += n * newLength_;
+                destIndex += n * newLength_;
+                remaining -= n;
+                return 0;
+            }
+            // Make next() skip all of these edits at once.
+            oldLength_ *= remaining;
+            newLength_ *= remaining;
+            remaining = 0;
+        }
+    }
+    return 1;
+}
+
+int32_t Edits::Iterator::destinationIndexFromSourceIndex(int32_t i, UErrorCode &errorCode) {
+    int32_t where = findIndex(i, TRUE, errorCode);
+    if (where < 0) {
+        // Error or before the string.
+        return 0;
+    }
+    if (where > 0 || i == srcIndex) {
+        // At or after string length, or at start of the found span.
+        return destIndex;
+    }
+    if (changed) {
+        // In a change span, map to its end.
+        return destIndex + newLength_;
+    } else {
+        // In an unchanged span, offset 1:1 within it.
+        return destIndex + (i - srcIndex);
+    }
+}
+
+int32_t Edits::Iterator::sourceIndexFromDestinationIndex(int32_t i, UErrorCode &errorCode) {
+    int32_t where = findIndex(i, FALSE, errorCode);
+    if (where < 0) {
+        // Error or before the string.
+        return 0;
+    }
+    if (where > 0 || i == destIndex) {
+        // At or after string length, or at start of the found span.
+        return srcIndex;
+    }
+    if (changed) {
+        // In a change span, map to its end.
+        return srcIndex + oldLength_;
+    } else {
+        // In an unchanged span, offset within it.
+        return srcIndex + (i - destIndex);
+    }
+}
+
+UnicodeString& Edits::Iterator::toString(UnicodeString& sb) const {
+    sb.append(u"{ src[", -1);
+    ICU_Utility::appendNumber(sb, srcIndex);
+    sb.append(u"..", -1);
+    ICU_Utility::appendNumber(sb, srcIndex + oldLength_);
+    if (changed) {
+        sb.append(u"] ⇝ dest[", -1);
+    } else {
+        sb.append(u"] ≡ dest[", -1);
+    }
+    ICU_Utility::appendNumber(sb, destIndex);
+    sb.append(u"..", -1);
+    ICU_Utility::appendNumber(sb, destIndex + newLength_);
+    if (changed) {
+        sb.append(u"], repl[", -1);
+        ICU_Utility::appendNumber(sb, replIndex);
+        sb.append(u"..", -1);
+        ICU_Utility::appendNumber(sb, replIndex + newLength_);
+        sb.append(u"] }", -1);
+    } else {
+        sb.append(u"] (no-change) }", -1);
+    }
+    return sb;
+}
+
+U_NAMESPACE_END
diff --git a/src/third_party/icu/source/common/errorcode.cpp b/src/third_party/icu/source/common/errorcode.cpp
index 43868b7..e7ac43b 100644
--- a/src/third_party/icu/source/common/errorcode.cpp
+++ b/src/third_party/icu/source/common/errorcode.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  errorcode.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
diff --git a/src/third_party/icu/source/common/filteredbrk.cpp b/src/third_party/icu/source/common/filteredbrk.cpp
index 4499055..88db2bd 100644
--- a/src/third_party/icu/source/common/filteredbrk.cpp
+++ b/src/third_party/icu/source/common/filteredbrk.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 * Copyright (C) 2014-2015, International Business Machines Corporation and
@@ -5,7 +7,9 @@
 *******************************************************************************
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/utypes.h"
 #if !UCONFIG_NO_BREAK_ITERATION && !UCONFIG_NO_FILTERED_BREAK_ITERATION
 
@@ -172,7 +176,7 @@
     status = U_SAFECLONE_ALLOCATED_WARNING;
     return clone();
   }
-  virtual BreakIterator* clone(void) const { return new SimpleFilteredSentenceBreakIterator(*this); }
+  virtual SimpleFilteredSentenceBreakIterator* clone() const { return new SimpleFilteredSentenceBreakIterator(*this); }
   virtual UClassID getDynamicClassID(void) const { return NULL; }
   virtual UBool operator==(const BreakIterator& o) const { if(this==&o) return true; return false; }
 
@@ -402,7 +406,8 @@
 
 int32_t
 SimpleFilteredSentenceBreakIterator::first(void) {
-  return internalNext(fDelegate->first());
+  // Don't suppress a break opportunity at the beginning of text.
+  return fDelegate->first();
 }
 
 int32_t
@@ -416,7 +421,9 @@
 }
 
 UBool SimpleFilteredSentenceBreakIterator::isBoundary(int32_t offset) {
-  if(!fDelegate->isBoundary(offset)) return false; // no break to suppress
+  if (!fDelegate->isBoundary(offset)) return false; // no break to suppress
+
+  if (fData->fBackwardsTrie.isNull()) return true; // no data = no suppressions
 
   UErrorCode status = U_ZERO_ERROR;
   resetState(status);
@@ -477,13 +484,42 @@
   : fSet(status)
 {
   if(U_SUCCESS(status)) {
-    LocalUResourceBundlePointer b(ures_open(U_ICUDATA_BRKITR, fromLocale.getBaseName(), &status));
-    LocalUResourceBundlePointer exceptions(ures_getByKeyWithFallback(b.getAlias(), "exceptions", NULL, &status));
-    LocalUResourceBundlePointer breaks(ures_getByKeyWithFallback(exceptions.getAlias(), "SentenceBreak", NULL, &status));
-    if(U_FAILURE(status)) return; // leaves the builder empty, if you try to use it.
+    UErrorCode subStatus = U_ZERO_ERROR;
+    LocalUResourceBundlePointer b(ures_open(U_ICUDATA_BRKITR, fromLocale.getBaseName(), &subStatus));
+    if (U_FAILURE(subStatus) || (subStatus == U_USING_DEFAULT_WARNING) ) {    
+      status = subStatus; // copy the failing status 
+#if FB_DEBUG
+      fprintf(stderr, "open BUNDLE %s : %s, %s\n", fromLocale.getBaseName(), "[exit]", u_errorName(status));
+#endif
+      return;  // leaves the builder empty, if you try to use it.
+    }
+    LocalUResourceBundlePointer exceptions(ures_getByKeyWithFallback(b.getAlias(), "exceptions", NULL, &subStatus));
+    if (U_FAILURE(subStatus) || (subStatus == U_USING_DEFAULT_WARNING) ) {    
+      status = subStatus; // copy the failing status 
+#if FB_DEBUG
+      fprintf(stderr, "open EXCEPTIONS %s : %s, %s\n", fromLocale.getBaseName(), "[exit]", u_errorName(status));
+#endif
+      return;  // leaves the builder empty, if you try to use it.
+    }
+    LocalUResourceBundlePointer breaks(ures_getByKeyWithFallback(exceptions.getAlias(), "SentenceBreak", NULL, &subStatus));
+
+#if FB_DEBUG
+    {
+      UErrorCode subsub = subStatus;
+      fprintf(stderr, "open SentenceBreak %s => %s, %s\n", fromLocale.getBaseName(), ures_getLocale(breaks.getAlias(), &subsub), u_errorName(subStatus));
+    }
+#endif
+    
+    if (U_FAILURE(subStatus) || (subStatus == U_USING_DEFAULT_WARNING) ) {    
+      status = subStatus; // copy the failing status 
+#if FB_DEBUG
+      fprintf(stderr, "open %s : %s, %s\n", fromLocale.getBaseName(), "[exit]", u_errorName(status));
+#endif
+      return;  // leaves the builder empty, if you try to use it.
+    }
 
     LocalUResourceBundlePointer strs;
-    UErrorCode subStatus = status;
+    subStatus = status; // Pick up inherited warning status now 
     do {
       strs.adoptInstead(ures_getNextResource(breaks.getAlias(), strs.orphan(), &subStatus));
       if(strs.isValid() && U_SUCCESS(subStatus)) {
@@ -661,7 +697,12 @@
 }
 
 FilteredBreakIteratorBuilder *
-FilteredBreakIteratorBuilder::createInstance(UErrorCode& status) {
+FilteredBreakIteratorBuilder::createInstance(UErrorCode &status) {
+  return createEmptyInstance(status);
+}
+
+FilteredBreakIteratorBuilder *
+FilteredBreakIteratorBuilder::createEmptyInstance(UErrorCode& status) {
   if(U_FAILURE(status)) return NULL;
   LocalPointer<FilteredBreakIteratorBuilder> ret(new SimpleFilteredBreakIteratorBuilder(status), status);
   return (U_SUCCESS(status))? ret.orphan(): NULL;
@@ -669,4 +710,4 @@
 
 U_NAMESPACE_END
 
-#endif //#if !UCONFIG_NO_BREAK_ITERATION && U_HAVE_STD_STRING && !UCONFIG_NO_FILTERED_BREAK_ITERATION
+#endif //#if !UCONFIG_NO_BREAK_ITERATION && !UCONFIG_NO_FILTERED_BREAK_ITERATION
diff --git a/src/third_party/icu/source/common/filterednormalizer2.cpp b/src/third_party/icu/source/common/filterednormalizer2.cpp
index 9239c85..61fcca6 100644
--- a/src/third_party/icu/source/common/filterednormalizer2.cpp
+++ b/src/third_party/icu/source/common/filterednormalizer2.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  filterednormalizer2.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -18,8 +20,12 @@
 
 #if !UCONFIG_NO_NORMALIZATION
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
+#include "unicode/edits.h"
 #include "unicode/normalizer2.h"
+#include "unicode/stringoptions.h"
 #include "unicode/uniset.h"
 #include "unicode/unistr.h"
 #include "unicode/unorm.h"
@@ -84,6 +90,52 @@
     return dest;
 }
 
+void
+FilteredNormalizer2::normalizeUTF8(uint32_t options, StringPiece src, ByteSink &sink,
+                                   Edits *edits, UErrorCode &errorCode) const {
+    if (U_FAILURE(errorCode)) {
+        return;
+    }
+    if (edits != nullptr && (options & U_EDITS_NO_RESET) == 0) {
+        edits->reset();
+    }
+    options |= U_EDITS_NO_RESET;  // Do not reset for each span.
+    normalizeUTF8(options, src.data(), src.length(), sink, edits, USET_SPAN_SIMPLE, errorCode);
+}
+
+void
+FilteredNormalizer2::normalizeUTF8(uint32_t options, const char *src, int32_t length,
+                                   ByteSink &sink, Edits *edits,
+                                   USetSpanCondition spanCondition,
+                                   UErrorCode &errorCode) const {
+    while (length > 0) {
+        int32_t spanLength = set.spanUTF8(src, length, spanCondition);
+        if (spanCondition == USET_SPAN_NOT_CONTAINED) {
+            if (spanLength != 0) {
+                if (edits != nullptr) {
+                    edits->addUnchanged(spanLength);
+                }
+                if ((options & U_OMIT_UNCHANGED_TEXT) == 0) {
+                    sink.Append(src, spanLength);
+                }
+            }
+            spanCondition = USET_SPAN_SIMPLE;
+        } else {
+            if (spanLength != 0) {
+                // Not norm2.normalizeSecondAndAppend() because we do not want
+                // to modify the non-filter part of dest.
+                norm2.normalizeUTF8(options, StringPiece(src, spanLength), sink, edits, errorCode);
+                if (U_FAILURE(errorCode)) {
+                    break;
+                }
+            }
+            spanCondition = USET_SPAN_NOT_CONTAINED;
+        }
+        src += spanLength;
+        length -= spanLength;
+    }
+}
+
 UnicodeString &
 FilteredNormalizer2::normalizeSecondAndAppend(UnicodeString &first,
                                               const UnicodeString &second,
@@ -195,6 +247,31 @@
     return TRUE;
 }
 
+UBool
+FilteredNormalizer2::isNormalizedUTF8(StringPiece sp, UErrorCode &errorCode) const {
+    if(U_FAILURE(errorCode)) {
+        return FALSE;
+    }
+    const char *s = sp.data();
+    int32_t length = sp.length();
+    USetSpanCondition spanCondition = USET_SPAN_SIMPLE;
+    while (length > 0) {
+        int32_t spanLength = set.spanUTF8(s, length, spanCondition);
+        if (spanCondition == USET_SPAN_NOT_CONTAINED) {
+            spanCondition = USET_SPAN_SIMPLE;
+        } else {
+            if (!norm2.isNormalizedUTF8(StringPiece(s, spanLength), errorCode) ||
+                    U_FAILURE(errorCode)) {
+                return FALSE;
+            }
+            spanCondition = USET_SPAN_NOT_CONTAINED;
+        }
+        s += spanLength;
+        length -= spanLength;
+    }
+    return TRUE;
+}
+
 UNormalizationCheckResult
 FilteredNormalizer2::quickCheck(const UnicodeString &s, UErrorCode &errorCode) const {
     uprv_checkCanGetBuffer(s, errorCode);
diff --git a/src/third_party/icu/source/common/hash.h b/src/third_party/icu/source/common/hash.h
index ab5fbf6..f02cb70 100644
--- a/src/third_party/icu/source/common/hash.h
+++ b/src/third_party/icu/source/common/hash.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *   Copyright (C) 1997-2014, International Business Machines
@@ -31,13 +33,23 @@
 
     inline void init(UHashFunction *keyHash, UKeyComparator *keyComp, UValueComparator *valueComp, UErrorCode& status);
 
+    inline void initSize(UHashFunction *keyHash, UKeyComparator *keyComp, UValueComparator *valueComp, int32_t size, UErrorCode& status);
+
 public:
     /**
      * Construct a hashtable
      * @param ignoreKeyCase If true, keys are case insensitive.
      * @param status Error code
     */
-    Hashtable(UBool ignoreKeyCase, UErrorCode& status);
+    inline Hashtable(UBool ignoreKeyCase, UErrorCode& status);
+
+    /**
+     * Construct a hashtable
+     * @param ignoreKeyCase If true, keys are case insensitive.
+     * @param size initial size allocation
+     * @param status Error code
+    */
+    inline Hashtable(UBool ignoreKeyCase, int32_t size, UErrorCode& status);
 
     /**
      * Construct a hashtable
@@ -45,57 +57,57 @@
      * @param valueComp Comparator for comparing the values
      * @param status Error code
     */
-    Hashtable(UKeyComparator *keyComp, UValueComparator *valueComp, UErrorCode& status);
+    inline Hashtable(UKeyComparator *keyComp, UValueComparator *valueComp, UErrorCode& status);
 
     /**
      * Construct a hashtable
      * @param status Error code
     */
-    Hashtable(UErrorCode& status);
+    inline Hashtable(UErrorCode& status);
 
     /**
      * Construct a hashtable, _disregarding any error_.  Use this constructor
      * with caution.
      */
-    Hashtable();
+    inline Hashtable();
 
     /**
      * Non-virtual destructor; make this virtual if Hashtable is subclassed
      * in the future.
      */
-    ~Hashtable();
+    inline ~Hashtable();
 
-    UObjectDeleter *setValueDeleter(UObjectDeleter *fn);
+    inline UObjectDeleter *setValueDeleter(UObjectDeleter *fn);
 
-    int32_t count() const;
+    inline int32_t count() const;
 
-    void* put(const UnicodeString& key, void* value, UErrorCode& status);
+    inline void* put(const UnicodeString& key, void* value, UErrorCode& status);
 
-    int32_t puti(const UnicodeString& key, int32_t value, UErrorCode& status);
+    inline int32_t puti(const UnicodeString& key, int32_t value, UErrorCode& status);
 
-    void* get(const UnicodeString& key) const;
-    
-    int32_t geti(const UnicodeString& key) const;
-    
-    void* remove(const UnicodeString& key);
+    inline void* get(const UnicodeString& key) const;
 
-    int32_t removei(const UnicodeString& key);
+    inline int32_t geti(const UnicodeString& key) const;
 
-    void removeAll(void);
+    inline void* remove(const UnicodeString& key);
 
-    const UHashElement* find(const UnicodeString& key) const;
+    inline int32_t removei(const UnicodeString& key);
+
+    inline void removeAll(void);
+
+    inline const UHashElement* find(const UnicodeString& key) const;
 
     /**
      * @param pos - must be UHASH_FIRST on first call, and untouched afterwards.
      * @see uhash_nextElement
      */
-    const UHashElement* nextElement(int32_t& pos) const;
-    
-    UKeyComparator* setKeyComparator(UKeyComparator*keyComp);
-    
-    UValueComparator* setValueComparator(UValueComparator* valueComp);
+    inline const UHashElement* nextElement(int32_t& pos) const;
 
-    UBool equals(const Hashtable& that) const;
+    inline UKeyComparator* setKeyComparator(UKeyComparator*keyComp);
+
+    inline UValueComparator* setValueComparator(UValueComparator* valueComp);
+
+    inline UBool equals(const Hashtable& that) const;
 private:
     Hashtable(const Hashtable &other); // forbid copying of this class
     Hashtable &operator=(const Hashtable &other); // forbid copying of this class
@@ -105,7 +117,7 @@
  * Implementation
  ********************************************************************/
 
-inline void Hashtable::init(UHashFunction *keyHash, UKeyComparator *keyComp, 
+inline void Hashtable::init(UHashFunction *keyHash, UKeyComparator *keyComp,
                             UValueComparator *valueComp, UErrorCode& status) {
     if (U_FAILURE(status)) {
         return;
@@ -117,10 +129,23 @@
     }
 }
 
-inline Hashtable::Hashtable(UKeyComparator *keyComp, UValueComparator *valueComp, 
+inline void Hashtable::initSize(UHashFunction *keyHash, UKeyComparator *keyComp,
+                                UValueComparator *valueComp, int32_t size, UErrorCode& status) {
+    if (U_FAILURE(status)) {
+        return;
+    }
+    uhash_initSize(&hashObj, keyHash, keyComp, valueComp, size, &status);
+    if (U_SUCCESS(status)) {
+        hash = &hashObj;
+        uhash_setKeyDeleter(hash, uprv_deleteUObject);
+    }
+}
+
+inline Hashtable::Hashtable(UKeyComparator *keyComp, UValueComparator *valueComp,
                  UErrorCode& status) : hash(0) {
     init( uhash_hashUnicodeString, keyComp, valueComp, status);
 }
+
 inline Hashtable::Hashtable(UBool ignoreKeyCase, UErrorCode& status)
  : hash(0)
 {
@@ -132,6 +157,17 @@
             status);
 }
 
+inline Hashtable::Hashtable(UBool ignoreKeyCase, int32_t size, UErrorCode& status)
+ : hash(0)
+{
+    initSize(ignoreKeyCase ? uhash_hashCaselessUnicodeString
+                        : uhash_hashUnicodeString,
+            ignoreKeyCase ? uhash_compareCaselessUnicodeString
+                        : uhash_compareUnicodeString,
+            NULL, size,
+            status);
+}
+
 inline Hashtable::Hashtable(UErrorCode& status)
  : hash(0)
 {
@@ -198,7 +234,7 @@
 inline UKeyComparator* Hashtable::setKeyComparator(UKeyComparator*keyComp){
     return uhash_setKeyComparator(hash, keyComp);
 }
-    
+
 inline UValueComparator* Hashtable::setValueComparator(UValueComparator* valueComp){
     return uhash_setValueComparator(hash, valueComp);
 }
diff --git a/src/third_party/icu/source/common/icudataver.c b/src/third_party/icu/source/common/icudataver.cpp
similarity index 88%
rename from src/third_party/icu/source/common/icudataver.c
rename to src/third_party/icu/source/common/icudataver.cpp
index beb5e73..d314411 100644
--- a/src/third_party/icu/source/common/icudataver.c
+++ b/src/third_party/icu/source/common/icudataver.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
diff --git a/src/third_party/icu/source/common/icuplug.cpp b/src/third_party/icu/source/common/icuplug.cpp
index bca7798..4ab8c66 100644
--- a/src/third_party/icu/source/common/icuplug.cpp
+++ b/src/third_party/icu/source/common/icuplug.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
@@ -143,7 +145,7 @@
   return -1;
 }
 
-U_INTERNAL char * U_EXPORT2
+U_CAPI char * U_EXPORT2
 uplug_findLibrary(void *lib, UErrorCode *status) {
   int32_t libEnt;
   char *ret = NULL;
@@ -159,7 +161,7 @@
   return ret;
 }
 
-U_INTERNAL void * U_EXPORT2
+U_CAPI void * U_EXPORT2
 uplug_openLibrary(const char *libName, UErrorCode *status) {
   int32_t libEntry = -1;
   void *lib = NULL;
@@ -207,7 +209,7 @@
   return lib;
 }
 
-U_INTERNAL void U_EXPORT2
+U_CAPI void U_EXPORT2
 uplug_closeLibrary(void *lib, UErrorCode *status) {
   int32_t i;
     
@@ -505,7 +507,7 @@
   return data->config;
 }
 
-U_INTERNAL UPlugData* U_EXPORT2
+U_CAPI UPlugData* U_EXPORT2
 uplug_getPlugInternal(int32_t n) { 
   if(n <0 || n >= pluginCount) {
     return NULL;
@@ -705,7 +707,7 @@
 static char plugin_file[2048] = "";
 #endif
 
-U_INTERNAL const char* U_EXPORT2
+U_CAPI const char* U_EXPORT2
 uplug_getPluginFile() {
 #if U_ENABLE_DYLOAD && !UCONFIG_NO_FILE_IO
   return plugin_file;
@@ -780,8 +782,8 @@
     /* plugin_file is not used for processing - it is only used 
        so that uplug_getPluginFile() works (i.e. icuinfo)
     */
-    uprv_strncpy(plugin_file, pluginFile.data(), sizeof(plugin_file));
-        
+    pluginFile.extract(plugin_file, sizeof(plugin_file), *status);
+
 #if UPLUG_TRACE
     DBG((stderr, "pluginfile= %s len %d/%d\n", plugin_file, (int)strlen(plugin_file), (int)sizeof(plugin_file)));
 #endif
diff --git a/src/third_party/icu/source/common/icuplugimp.h b/src/third_party/icu/source/common/icuplugimp.h
index 6b4f122..9df3092 100644
--- a/src/third_party/icu/source/common/icuplugimp.h
+++ b/src/third_party/icu/source/common/icuplugimp.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
@@ -34,7 +36,7 @@
  * @return the library pointer, or NULL
  * @internal internal use only
  */
-U_INTERNAL void * U_EXPORT2
+U_CAPI void * U_EXPORT2
 uplug_openLibrary(const char *libName, UErrorCode *status);
 
 /**
@@ -43,7 +45,7 @@
  * @param status error code
  * @internal internal use only
  */
-U_INTERNAL void U_EXPORT2
+U_CAPI void U_EXPORT2
 uplug_closeLibrary(void *lib, UErrorCode *status);
 
 /**
@@ -53,7 +55,7 @@
  * @return the library name, or NULL if not found.
  * @internal internal use only
  */
-U_INTERNAL  char * U_EXPORT2
+U_CAPI  char * U_EXPORT2
 uplug_findLibrary(void *lib, UErrorCode *status);
 
 /** @} */
@@ -67,21 +69,21 @@
  * @param status error result
  * @internal - Internal use only.
  */
-U_INTERNAL void U_EXPORT2
+U_CAPI void U_EXPORT2
 uplug_init(UErrorCode *status);
 
 /**
  * Get raw plug N
  * @internal - Internal use only
  */ 
-U_INTERNAL UPlugData* U_EXPORT2
+U_CAPI UPlugData* U_EXPORT2
 uplug_getPlugInternal(int32_t n);
 
 /**
  * Get the name of the plugin file. 
  * @internal - Internal use only.
  */
-U_INTERNAL const char* U_EXPORT2
+U_CAPI const char* U_EXPORT2
 uplug_getPluginFile(void);
 
 /** @} */
diff --git a/src/third_party/icu/source/common/listformatter.cpp b/src/third_party/icu/source/common/listformatter.cpp
index 5b05e4a..593e90b 100644
--- a/src/third_party/icu/source/common/listformatter.cpp
+++ b/src/third_party/icu/source/common/listformatter.cpp
@@ -14,7 +14,9 @@
 *   created by: Umesh P. Nair
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/listformatter.h"
 #include "simplepatternformatter.h"
 #include "mutex.h"
diff --git a/src/third_party/icu/source/common/loadednormalizer2impl.cpp b/src/third_party/icu/source/common/loadednormalizer2impl.cpp
index 250787b..776604e 100644
--- a/src/third_party/icu/source/common/loadednormalizer2impl.cpp
+++ b/src/third_party/icu/source/common/loadednormalizer2impl.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 * Copyright (C) 2014, International Business Machines
@@ -13,11 +15,14 @@
 
 #if !UCONFIG_NO_NORMALIZATION
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/udata.h"
 #include "unicode/localpointer.h"
 #include "unicode/normalizer2.h"
+#include "unicode/ucptrie.h"
 #include "unicode/unistr.h"
 #include "unicode/unorm.h"
 #include "cstring.h"
@@ -42,12 +47,12 @@
     isAcceptable(void *context, const char *type, const char *name, const UDataInfo *pInfo);
 
     UDataMemory *memory;
-    UTrie2 *ownedTrie;
+    UCPTrie *ownedTrie;
 };
 
 LoadedNormalizer2Impl::~LoadedNormalizer2Impl() {
     udata_close(memory);
-    utrie2_close(ownedTrie);
+    ucptrie_close(ownedTrie);
 }
 
 UBool U_CALLCONV
@@ -62,7 +67,7 @@
         pInfo->dataFormat[1]==0x72 &&
         pInfo->dataFormat[2]==0x6d &&
         pInfo->dataFormat[3]==0x32 &&
-        pInfo->formatVersion[0]==2
+        pInfo->formatVersion[0]==4
     ) {
         // Normalizer2Impl *me=(Normalizer2Impl *)context;
         // uprv_memcpy(me->dataVersion, pInfo->dataVersion, 4);
@@ -84,16 +89,16 @@
     const uint8_t *inBytes=(const uint8_t *)udata_getMemory(memory);
     const int32_t *inIndexes=(const int32_t *)inBytes;
     int32_t indexesLength=inIndexes[IX_NORM_TRIE_OFFSET]/4;
-    if(indexesLength<=IX_MIN_MAYBE_YES) {
+    if(indexesLength<=IX_MIN_LCCC_CP) {
         errorCode=U_INVALID_FORMAT_ERROR;  // Not enough indexes.
         return;
     }
 
     int32_t offset=inIndexes[IX_NORM_TRIE_OFFSET];
     int32_t nextOffset=inIndexes[IX_EXTRA_DATA_OFFSET];
-    ownedTrie=utrie2_openFromSerialized(UTRIE2_16_VALUE_BITS,
-                                        inBytes+offset, nextOffset-offset, NULL,
-                                        &errorCode);
+    ownedTrie=ucptrie_openFromBinary(UCPTRIE_TYPE_FAST, UCPTRIE_VALUE_BITS_16,
+                                     inBytes+offset, nextOffset-offset, NULL,
+                                     &errorCode);
     if(U_FAILURE(errorCode)) {
         return;
     }
@@ -131,21 +136,32 @@
 static UBool U_CALLCONV uprv_loaded_normalizer2_cleanup();
 U_CDECL_END
 
-static Norm2AllModes *nfkcSingleton;
-static Norm2AllModes *nfkc_cfSingleton;
-static UHashtable    *cache=NULL;
+#if !NORM2_HARDCODE_NFC_DATA
+static Norm2AllModes *nfcSingleton;
+static icu::UInitOnce nfcInitOnce = U_INITONCE_INITIALIZER;
+#endif
 
+static Norm2AllModes *nfkcSingleton;
 static icu::UInitOnce nfkcInitOnce = U_INITONCE_INITIALIZER;
+
+static Norm2AllModes *nfkc_cfSingleton;
 static icu::UInitOnce nfkc_cfInitOnce = U_INITONCE_INITIALIZER;
 
+static UHashtable    *cache=NULL;
+
 // UInitOnce singleton initialization function
 static void U_CALLCONV initSingletons(const char *what, UErrorCode &errorCode) {
+#if !NORM2_HARDCODE_NFC_DATA
+    if (uprv_strcmp(what, "nfc") == 0) {
+        nfcSingleton    = Norm2AllModes::createInstance(NULL, "nfc", errorCode);
+    } else
+#endif
     if (uprv_strcmp(what, "nfkc") == 0) {
         nfkcSingleton    = Norm2AllModes::createInstance(NULL, "nfkc", errorCode);
     } else if (uprv_strcmp(what, "nfkc_cf") == 0) {
         nfkc_cfSingleton = Norm2AllModes::createInstance(NULL, "nfkc_cf", errorCode);
     } else {
-        U_ASSERT(FALSE);   // Unknown singleton
+        UPRV_UNREACHABLE;   // Unknown singleton
     }
     ucln_common_registerCleanup(UCLN_COMMON_LOADED_NORMALIZER2, uprv_loaded_normalizer2_cleanup);
 }
@@ -157,19 +173,36 @@
 }
 
 static UBool U_CALLCONV uprv_loaded_normalizer2_cleanup() {
+#if !NORM2_HARDCODE_NFC_DATA
+    delete nfcSingleton;
+    nfcSingleton = NULL;
+    nfcInitOnce.reset();
+#endif
+
     delete nfkcSingleton;
     nfkcSingleton = NULL;
+    nfkcInitOnce.reset();
+
     delete nfkc_cfSingleton;
     nfkc_cfSingleton = NULL;
+    nfkc_cfInitOnce.reset();
+
     uhash_close(cache);
     cache=NULL;
-    nfkcInitOnce.reset(); 
-    nfkc_cfInitOnce.reset(); 
     return TRUE;
 }
 
 U_CDECL_END
 
+#if !NORM2_HARDCODE_NFC_DATA
+const Norm2AllModes *
+Norm2AllModes::getNFCInstance(UErrorCode &errorCode) {
+    if(U_FAILURE(errorCode)) { return NULL; }
+    umtx_initOnce(nfcInitOnce, &initSingletons, "nfc", errorCode);
+    return nfcSingleton;
+}
+#endif
+
 const Norm2AllModes *
 Norm2AllModes::getNFKCInstance(UErrorCode &errorCode) {
     if(U_FAILURE(errorCode)) { return NULL; }
@@ -184,6 +217,36 @@
     return nfkc_cfSingleton;
 }
 
+#if !NORM2_HARDCODE_NFC_DATA
+const Normalizer2 *
+Normalizer2::getNFCInstance(UErrorCode &errorCode) {
+    const Norm2AllModes *allModes=Norm2AllModes::getNFCInstance(errorCode);
+    return allModes!=NULL ? &allModes->comp : NULL;
+}
+
+const Normalizer2 *
+Normalizer2::getNFDInstance(UErrorCode &errorCode) {
+    const Norm2AllModes *allModes=Norm2AllModes::getNFCInstance(errorCode);
+    return allModes!=NULL ? &allModes->decomp : NULL;
+}
+
+const Normalizer2 *Normalizer2Factory::getFCDInstance(UErrorCode &errorCode) {
+    const Norm2AllModes *allModes=Norm2AllModes::getNFCInstance(errorCode);
+    return allModes!=NULL ? &allModes->fcd : NULL;
+}
+
+const Normalizer2 *Normalizer2Factory::getFCCInstance(UErrorCode &errorCode) {
+    const Norm2AllModes *allModes=Norm2AllModes::getNFCInstance(errorCode);
+    return allModes!=NULL ? &allModes->fcc : NULL;
+}
+
+const Normalizer2Impl *
+Normalizer2Factory::getNFCImpl(UErrorCode &errorCode) {
+    const Norm2AllModes *allModes=Norm2AllModes::getNFCInstance(errorCode);
+    return allModes!=NULL ? allModes->impl : NULL;
+}
+#endif
+
 const Normalizer2 *
 Normalizer2::getNFKCInstance(UErrorCode &errorCode) {
     const Norm2AllModes *allModes=Norm2AllModes::getNFKCInstance(errorCode);
@@ -232,6 +295,7 @@
             }
         }
         if(allModes==NULL) {
+            ucln_common_registerCleanup(UCLN_COMMON_LOADED_NORMALIZER2, uprv_loaded_normalizer2_cleanup);
             LocalPointer<Norm2AllModes> localAllModes(
                 Norm2AllModes::createInstance(packageName, name, errorCode));
             if(U_SUCCESS(errorCode)) {
@@ -246,7 +310,7 @@
                 }
                 void *temp=uhash_get(cache, name);
                 if(temp==NULL) {
-                    int32_t keyLength=uprv_strlen(name)+1;
+                    int32_t keyLength= static_cast<int32_t>(uprv_strlen(name)+1);
                     char *nameCopy=(char *)uprv_malloc(keyLength);
                     if(nameCopy==NULL) {
                         errorCode=U_MEMORY_ALLOCATION_ERROR;
diff --git a/src/third_party/icu/source/common/localebuilder.cpp b/src/third_party/icu/source/common/localebuilder.cpp
new file mode 100644
index 0000000..1dd8131
--- /dev/null
+++ b/src/third_party/icu/source/common/localebuilder.cpp
@@ -0,0 +1,468 @@
+// © 2019 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+#include <utility>
+
+#include "bytesinkutil.h"  // CharStringByteSink
+#include "charstr.h"
+#include "cstring.h"
+#include "ulocimp.h"
+#include "unicode/localebuilder.h"
+#include "unicode/locid.h"
+
+U_NAMESPACE_BEGIN
+
+#define UPRV_ISDIGIT(c) (((c) >= '0') && ((c) <= '9'))
+#define UPRV_ISALPHANUM(c) (uprv_isASCIILetter(c) || UPRV_ISDIGIT(c) )
+
+const char* kAttributeKey = "attribute";
+
+static bool _isExtensionSubtags(char key, const char* s, int32_t len) {
+    switch (uprv_tolower(key)) {
+        case 'u':
+            return ultag_isUnicodeExtensionSubtags(s, len);
+        case 't':
+            return ultag_isTransformedExtensionSubtags(s, len);
+        case 'x':
+            return ultag_isPrivateuseValueSubtags(s, len);
+        default:
+            return ultag_isExtensionSubtags(s, len);
+    }
+}
+
+LocaleBuilder::LocaleBuilder() : UObject(), status_(U_ZERO_ERROR), language_(),
+    script_(), region_(), variant_(nullptr), extensions_(nullptr)
+{
+    language_[0] = 0;
+    script_[0] = 0;
+    region_[0] = 0;
+}
+
+LocaleBuilder::~LocaleBuilder()
+{
+    delete variant_;
+    delete extensions_;
+}
+
+LocaleBuilder& LocaleBuilder::setLocale(const Locale& locale)
+{
+    clear();
+    setLanguage(locale.getLanguage());
+    setScript(locale.getScript());
+    setRegion(locale.getCountry());
+    setVariant(locale.getVariant());
+    extensions_ = locale.clone();
+    if (extensions_ == nullptr) {
+        status_ = U_MEMORY_ALLOCATION_ERROR;
+    }
+    return *this;
+}
+
+LocaleBuilder& LocaleBuilder::setLanguageTag(StringPiece tag)
+{
+    Locale l = Locale::forLanguageTag(tag, status_);
+    if (U_FAILURE(status_)) { return *this; }
+    // Because setLocale will reset status_ we need to return
+    // first if we have error in forLanguageTag.
+    setLocale(l);
+    return *this;
+}
+
+static void setField(StringPiece input, char* dest, UErrorCode& errorCode,
+                     UBool (*test)(const char*, int32_t)) {
+    if (U_FAILURE(errorCode)) { return; }
+    if (input.empty()) {
+        dest[0] = '\0';
+    } else if (test(input.data(), input.length())) {
+        uprv_memcpy(dest, input.data(), input.length());
+        dest[input.length()] = '\0';
+    } else {
+        errorCode = U_ILLEGAL_ARGUMENT_ERROR;
+    }
+}
+
+LocaleBuilder& LocaleBuilder::setLanguage(StringPiece language)
+{
+    setField(language, language_, status_, &ultag_isLanguageSubtag);
+    return *this;
+}
+
+LocaleBuilder& LocaleBuilder::setScript(StringPiece script)
+{
+    setField(script, script_, status_, &ultag_isScriptSubtag);
+    return *this;
+}
+
+LocaleBuilder& LocaleBuilder::setRegion(StringPiece region)
+{
+    setField(region, region_, status_, &ultag_isRegionSubtag);
+    return *this;
+}
+
+static void transform(char* data, int32_t len) {
+    for (int32_t i = 0; i < len; i++, data++) {
+        if (*data == '_') {
+            *data = '-';
+        } else {
+            *data = uprv_tolower(*data);
+        }
+    }
+}
+
+LocaleBuilder& LocaleBuilder::setVariant(StringPiece variant)
+{
+    if (U_FAILURE(status_)) { return *this; }
+    if (variant.empty()) {
+        delete variant_;
+        variant_ = nullptr;
+        return *this;
+    }
+    CharString* new_variant = new CharString(variant, status_);
+    if (U_FAILURE(status_)) { return *this; }
+    if (new_variant == nullptr) {
+        status_ = U_MEMORY_ALLOCATION_ERROR;
+        return *this;
+    }
+    transform(new_variant->data(), new_variant->length());
+    if (!ultag_isVariantSubtags(new_variant->data(), new_variant->length())) {
+        delete new_variant;
+        status_ = U_ILLEGAL_ARGUMENT_ERROR;
+        return *this;
+    }
+    delete variant_;
+    variant_ = new_variant;
+    return *this;
+}
+
+static bool
+_isKeywordValue(const char* key, const char* value, int32_t value_len)
+{
+    if (key[1] == '\0') {
+        // one char key
+        return (UPRV_ISALPHANUM(uprv_tolower(key[0])) &&
+                _isExtensionSubtags(key[0], value, value_len));
+    } else if (uprv_strcmp(key, kAttributeKey) == 0) {
+        // unicode attributes
+        return ultag_isUnicodeLocaleAttributes(value, value_len);
+    }
+    // otherwise: unicode extension value
+    // We need to convert from legacy key/value to unicode
+    // key/value
+    const char* unicode_locale_key = uloc_toUnicodeLocaleKey(key);
+    const char* unicode_locale_type = uloc_toUnicodeLocaleType(key, value);
+
+    return unicode_locale_key && unicode_locale_type &&
+           ultag_isUnicodeLocaleKey(unicode_locale_key, -1) &&
+           ultag_isUnicodeLocaleType(unicode_locale_type, -1);
+}
+
+static void
+_copyExtensions(const Locale& from, icu::StringEnumeration *keywords,
+                Locale& to, bool validate, UErrorCode& errorCode)
+{
+    if (U_FAILURE(errorCode)) { return; }
+    LocalPointer<icu::StringEnumeration> ownedKeywords;
+    if (keywords == nullptr) {
+        ownedKeywords.adoptInstead(from.createKeywords(errorCode));
+        if (U_FAILURE(errorCode) || ownedKeywords.isNull()) { return; }
+        keywords = ownedKeywords.getAlias();
+    }
+    const char* key;
+    while ((key = keywords->next(nullptr, errorCode)) != nullptr) {
+        CharString value;
+        CharStringByteSink sink(&value);
+        from.getKeywordValue(key, sink, errorCode);
+        if (U_FAILURE(errorCode)) { return; }
+        if (uprv_strcmp(key, kAttributeKey) == 0) {
+            transform(value.data(), value.length());
+        }
+        if (validate &&
+            !_isKeywordValue(key, value.data(), value.length())) {
+            errorCode = U_ILLEGAL_ARGUMENT_ERROR;
+            return;
+        }
+        to.setKeywordValue(key, value.data(), errorCode);
+        if (U_FAILURE(errorCode)) { return; }
+    }
+}
+
+void static
+_clearUAttributesAndKeyType(Locale& locale, UErrorCode& errorCode)
+{
+    // Clear Unicode attributes
+    locale.setKeywordValue(kAttributeKey, "", errorCode);
+
+    // Clear all Unicode keyword values
+    LocalPointer<icu::StringEnumeration> iter(locale.createUnicodeKeywords(errorCode));
+    if (U_FAILURE(errorCode) || iter.isNull()) { return; }
+    const char* key;
+    while ((key = iter->next(nullptr, errorCode)) != nullptr) {
+        locale.setUnicodeKeywordValue(key, nullptr, errorCode);
+    }
+}
+
+static void
+_setUnicodeExtensions(Locale& locale, const CharString& value, UErrorCode& errorCode)
+{
+    // Add the unicode extensions to extensions_
+    CharString locale_str("und-u-", errorCode);
+    locale_str.append(value, errorCode);
+    _copyExtensions(
+        Locale::forLanguageTag(locale_str.data(), errorCode), nullptr,
+        locale, false, errorCode);
+}
+
+LocaleBuilder& LocaleBuilder::setExtension(char key, StringPiece value)
+{
+    if (U_FAILURE(status_)) { return *this; }
+    if (!UPRV_ISALPHANUM(key)) {
+        status_ = U_ILLEGAL_ARGUMENT_ERROR;
+        return *this;
+    }
+    CharString value_str(value, status_);
+    if (U_FAILURE(status_)) { return *this; }
+    transform(value_str.data(), value_str.length());
+    if (!value_str.isEmpty() &&
+            !_isExtensionSubtags(key, value_str.data(), value_str.length())) {
+        status_ = U_ILLEGAL_ARGUMENT_ERROR;
+        return *this;
+    }
+    if (extensions_ == nullptr) {
+        extensions_ = new Locale();
+        if (extensions_ == nullptr) {
+            status_ = U_MEMORY_ALLOCATION_ERROR;
+            return *this;
+        }
+    }
+    if (uprv_tolower(key) != 'u') {
+        // for t, x and others extension.
+        extensions_->setKeywordValue(StringPiece(&key, 1), value_str.data(),
+                                     status_);
+        return *this;
+    }
+    _clearUAttributesAndKeyType(*extensions_, status_);
+    if (U_FAILURE(status_)) { return *this; }
+    if (!value.empty()) {
+        _setUnicodeExtensions(*extensions_, value_str, status_);
+    }
+    return *this;
+}
+
+LocaleBuilder& LocaleBuilder::setUnicodeLocaleKeyword(
+      StringPiece key, StringPiece type)
+{
+    if (U_FAILURE(status_)) { return *this; }
+    if (!ultag_isUnicodeLocaleKey(key.data(), key.length()) ||
+            (!type.empty() &&
+                 !ultag_isUnicodeLocaleType(type.data(), type.length()))) {
+      status_ = U_ILLEGAL_ARGUMENT_ERROR;
+      return *this;
+    }
+    if (extensions_ == nullptr) {
+        extensions_ = new Locale();
+    }
+    if (extensions_ == nullptr) {
+        status_ = U_MEMORY_ALLOCATION_ERROR;
+        return *this;
+    }
+    extensions_->setUnicodeKeywordValue(key, type, status_);
+    return *this;
+}
+
+LocaleBuilder& LocaleBuilder::addUnicodeLocaleAttribute(
+    StringPiece value)
+{
+    CharString value_str(value, status_);
+    if (U_FAILURE(status_)) { return *this; }
+    transform(value_str.data(), value_str.length());
+    if (!ultag_isUnicodeLocaleAttribute(value_str.data(), value_str.length())) {
+        status_ = U_ILLEGAL_ARGUMENT_ERROR;
+        return *this;
+    }
+    if (extensions_ == nullptr) {
+        extensions_ = new Locale();
+        if (extensions_ == nullptr) {
+            status_ = U_MEMORY_ALLOCATION_ERROR;
+            return *this;
+        }
+        extensions_->setKeywordValue(kAttributeKey, value_str.data(), status_);
+        return *this;
+    }
+
+    CharString attributes;
+    CharStringByteSink sink(&attributes);
+    UErrorCode localErrorCode = U_ZERO_ERROR;
+    extensions_->getKeywordValue(kAttributeKey, sink, localErrorCode);
+    if (U_FAILURE(localErrorCode)) {
+        CharString new_attributes(value_str.data(), status_);
+        // No attributes, set the attribute.
+        extensions_->setKeywordValue(kAttributeKey, new_attributes.data(), status_);
+        return *this;
+    }
+
+    transform(attributes.data(),attributes.length());
+    const char* start = attributes.data();
+    const char* limit = attributes.data() + attributes.length();
+    CharString new_attributes;
+    bool inserted = false;
+    while (start < limit) {
+        if (!inserted) {
+            int cmp = uprv_strcmp(start, value_str.data());
+            if (cmp == 0) { return *this; }  // Found it in attributes: Just return
+            if (cmp > 0) {
+                if (!new_attributes.isEmpty()) new_attributes.append('_', status_);
+                new_attributes.append(value_str.data(), status_);
+                inserted = true;
+            }
+        }
+        if (!new_attributes.isEmpty()) {
+            new_attributes.append('_', status_);
+        }
+        new_attributes.append(start, status_);
+        start += uprv_strlen(start) + 1;
+    }
+    if (!inserted) {
+        if (!new_attributes.isEmpty()) {
+            new_attributes.append('_', status_);
+        }
+        new_attributes.append(value_str.data(), status_);
+    }
+    // Not yet in the attributes, set the attribute.
+    extensions_->setKeywordValue(kAttributeKey, new_attributes.data(), status_);
+    return *this;
+}
+
+LocaleBuilder& LocaleBuilder::removeUnicodeLocaleAttribute(
+    StringPiece value)
+{
+    CharString value_str(value, status_);
+    if (U_FAILURE(status_)) { return *this; }
+    transform(value_str.data(), value_str.length());
+    if (!ultag_isUnicodeLocaleAttribute(value_str.data(), value_str.length())) {
+        status_ = U_ILLEGAL_ARGUMENT_ERROR;
+        return *this;
+    }
+    if (extensions_ == nullptr) { return *this; }
+    UErrorCode localErrorCode = U_ZERO_ERROR;
+    CharString attributes;
+    CharStringByteSink sink(&attributes);
+    extensions_->getKeywordValue(kAttributeKey, sink, localErrorCode);
+    // get failure, just return
+    if (U_FAILURE(localErrorCode)) { return *this; }
+    // Do not have any attributes, just return.
+    if (attributes.isEmpty()) { return *this; }
+
+    char* p = attributes.data();
+    // Replace null terminiator in place for _ and - so later
+    // we can use uprv_strcmp to compare.
+    for (int32_t i = 0; i < attributes.length(); i++, p++) {
+        *p = (*p == '_' || *p == '-') ? '\0' : uprv_tolower(*p);
+    }
+
+    const char* start = attributes.data();
+    const char* limit = attributes.data() + attributes.length();
+    CharString new_attributes;
+    bool found = false;
+    while (start < limit) {
+        if (uprv_strcmp(start, value_str.data()) == 0) {
+            found = true;
+        } else {
+            if (!new_attributes.isEmpty()) {
+                new_attributes.append('_', status_);
+            }
+            new_attributes.append(start, status_);
+        }
+        start += uprv_strlen(start) + 1;
+    }
+    // Found the value in attributes, set the attribute.
+    if (found) {
+        extensions_->setKeywordValue(kAttributeKey, new_attributes.data(), status_);
+    }
+    return *this;
+}
+
+LocaleBuilder& LocaleBuilder::clear()
+{
+    status_ = U_ZERO_ERROR;
+    language_[0] = 0;
+    script_[0] = 0;
+    region_[0] = 0;
+    delete variant_;
+    variant_ = nullptr;
+    clearExtensions();
+    return *this;
+}
+
+LocaleBuilder& LocaleBuilder::clearExtensions()
+{
+    delete extensions_;
+    extensions_ = nullptr;
+    return *this;
+}
+
+Locale makeBogusLocale() {
+  Locale bogus;
+  bogus.setToBogus();
+  return bogus;
+}
+
+void LocaleBuilder::copyExtensionsFrom(const Locale& src, UErrorCode& errorCode)
+{
+    if (U_FAILURE(errorCode)) { return; }
+    LocalPointer<icu::StringEnumeration> keywords(src.createKeywords(errorCode));
+    if (U_FAILURE(errorCode) || keywords.isNull() || keywords->count(errorCode) == 0) {
+        // Error, or no extensions to copy.
+        return;
+    }
+    if (extensions_ == nullptr) {
+        extensions_ = new Locale();
+        if (extensions_ == nullptr) {
+            status_ = U_MEMORY_ALLOCATION_ERROR;
+            return;
+        }
+    }
+    _copyExtensions(src, keywords.getAlias(), *extensions_, false, errorCode);
+}
+
+Locale LocaleBuilder::build(UErrorCode& errorCode)
+{
+    if (U_FAILURE(errorCode)) {
+        return makeBogusLocale();
+    }
+    if (U_FAILURE(status_)) {
+        errorCode = status_;
+        return makeBogusLocale();
+    }
+    CharString locale_str(language_, errorCode);
+    if (uprv_strlen(script_) > 0) {
+        locale_str.append('-', errorCode).append(StringPiece(script_), errorCode);
+    }
+    if (uprv_strlen(region_) > 0) {
+        locale_str.append('-', errorCode).append(StringPiece(region_), errorCode);
+    }
+    if (variant_ != nullptr) {
+        locale_str.append('-', errorCode).append(StringPiece(variant_->data()), errorCode);
+    }
+    if (U_FAILURE(errorCode)) {
+        return makeBogusLocale();
+    }
+    Locale product(locale_str.data());
+    if (extensions_ != nullptr) {
+        _copyExtensions(*extensions_, nullptr, product, true, errorCode);
+    }
+    if (U_FAILURE(errorCode)) {
+        return makeBogusLocale();
+    }
+    return product;
+}
+
+UBool LocaleBuilder::copyErrorTo(UErrorCode &outErrorCode) const {
+    if (U_FAILURE(outErrorCode)) {
+        // Do not overwrite the older error code
+        return TRUE;
+    }
+    outErrorCode = status_;
+    return U_FAILURE(outErrorCode);
+}
+
+U_NAMESPACE_END
diff --git a/src/third_party/icu/source/common/localematcher.cpp b/src/third_party/icu/source/common/localematcher.cpp
new file mode 100644
index 0000000..5795cbf
--- /dev/null
+++ b/src/third_party/icu/source/common/localematcher.cpp
@@ -0,0 +1,846 @@
+// © 2019 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+// localematcher.cpp
+// created: 2019may08 Markus W. Scherer
+
+#include "unicode/utypes.h"
+#include "unicode/localebuilder.h"
+#include "unicode/localematcher.h"
+#include "unicode/locid.h"
+#include "unicode/stringpiece.h"
+#include "unicode/uloc.h"
+#include "unicode/uobject.h"
+#include "cstring.h"
+#include "localeprioritylist.h"
+#include "loclikelysubtags.h"
+#include "locdistance.h"
+#include "lsr.h"
+#include "uassert.h"
+#include "uhash.h"
+#include "ustr_imp.h"
+#include "uvector.h"
+
+#define UND_LSR LSR("und", "", "", LSR::EXPLICIT_LSR)
+
+/**
+ * Indicator for the lifetime of desired-locale objects passed into the LocaleMatcher.
+ *
+ * @draft ICU 65
+ */
+enum ULocMatchLifetime {
+    /**
+     * Locale objects are temporary.
+     * The matcher will make a copy of a locale that will be used beyond one function call.
+     *
+     * @draft ICU 65
+     */
+    ULOCMATCH_TEMPORARY_LOCALES,
+    /**
+     * Locale objects are stored at least as long as the matcher is used.
+     * The matcher will keep only a pointer to a locale that will be used beyond one function call,
+     * avoiding a copy.
+     *
+     * @draft ICU 65
+     */
+    ULOCMATCH_STORED_LOCALES  // TODO: permanent? cached? clone?
+};
+#ifndef U_IN_DOXYGEN
+typedef enum ULocMatchLifetime ULocMatchLifetime;
+#endif
+
+U_NAMESPACE_BEGIN
+
+LocaleMatcher::Result::Result(LocaleMatcher::Result &&src) U_NOEXCEPT :
+        desiredLocale(src.desiredLocale),
+        supportedLocale(src.supportedLocale),
+        desiredIndex(src.desiredIndex),
+        supportedIndex(src.supportedIndex),
+        desiredIsOwned(src.desiredIsOwned) {
+    if (desiredIsOwned) {
+        src.desiredLocale = nullptr;
+        src.desiredIndex = -1;
+        src.desiredIsOwned = FALSE;
+    }
+}
+
+LocaleMatcher::Result::~Result() {
+    if (desiredIsOwned) {
+        delete desiredLocale;
+    }
+}
+
+LocaleMatcher::Result &LocaleMatcher::Result::operator=(LocaleMatcher::Result &&src) U_NOEXCEPT {
+    this->~Result();
+
+    desiredLocale = src.desiredLocale;
+    supportedLocale = src.supportedLocale;
+    desiredIndex = src.desiredIndex;
+    supportedIndex = src.supportedIndex;
+    desiredIsOwned = src.desiredIsOwned;
+
+    if (desiredIsOwned) {
+        src.desiredLocale = nullptr;
+        src.desiredIndex = -1;
+        src.desiredIsOwned = FALSE;
+    }
+    return *this;
+}
+
+Locale LocaleMatcher::Result::makeResolvedLocale(UErrorCode &errorCode) const {
+    if (U_FAILURE(errorCode) || supportedLocale == nullptr) {
+        return Locale::getRoot();
+    }
+    const Locale *bestDesired = getDesiredLocale();
+    if (bestDesired == nullptr || *supportedLocale == *bestDesired) {
+        return *supportedLocale;
+    }
+    LocaleBuilder b;
+    b.setLocale(*supportedLocale);
+
+    // Copy the region from bestDesired, if there is one.
+    const char *region = bestDesired->getCountry();
+    if (*region != 0) {
+        b.setRegion(region);
+    }
+
+    // Copy the variants from bestDesired, if there are any.
+    // Note that this will override any supportedLocale variants.
+    // For example, "sco-ulster-fonipa" + "...-fonupa" => "sco-fonupa" (replacing ulster).
+    const char *variants = bestDesired->getVariant();
+    if (*variants != 0) {
+        b.setVariant(variants);
+    }
+
+    // Copy the extensions from bestDesired, if there are any.
+    // C++ note: The following note, copied from Java, may not be true,
+    // as long as C++ copies by legacy ICU keyword, not by extension singleton.
+    // Note that this will override any supportedLocale extensions.
+    // For example, "th-u-nu-latn-ca-buddhist" + "...-u-nu-native" => "th-u-nu-native"
+    // (replacing calendar).
+    b.copyExtensionsFrom(*bestDesired, errorCode);
+    return b.build(errorCode);
+}
+
+LocaleMatcher::Builder::Builder(LocaleMatcher::Builder &&src) U_NOEXCEPT :
+        errorCode_(src.errorCode_),
+        supportedLocales_(src.supportedLocales_),
+        thresholdDistance_(src.thresholdDistance_),
+        demotion_(src.demotion_),
+        defaultLocale_(src.defaultLocale_),
+        withDefault_(src.withDefault_),
+        favor_(src.favor_),
+        direction_(src.direction_) {
+    src.supportedLocales_ = nullptr;
+    src.defaultLocale_ = nullptr;
+}
+
+LocaleMatcher::Builder::~Builder() {
+    delete supportedLocales_;
+    delete defaultLocale_;
+    delete maxDistanceDesired_;
+    delete maxDistanceSupported_;
+}
+
+LocaleMatcher::Builder &LocaleMatcher::Builder::operator=(LocaleMatcher::Builder &&src) U_NOEXCEPT {
+    this->~Builder();
+
+    errorCode_ = src.errorCode_;
+    supportedLocales_ = src.supportedLocales_;
+    thresholdDistance_ = src.thresholdDistance_;
+    demotion_ = src.demotion_;
+    defaultLocale_ = src.defaultLocale_;
+    withDefault_ = src.withDefault_,
+    favor_ = src.favor_;
+    direction_ = src.direction_;
+
+    src.supportedLocales_ = nullptr;
+    src.defaultLocale_ = nullptr;
+    return *this;
+}
+
+void LocaleMatcher::Builder::clearSupportedLocales() {
+    if (supportedLocales_ != nullptr) {
+        supportedLocales_->removeAllElements();
+    }
+}
+
+bool LocaleMatcher::Builder::ensureSupportedLocaleVector() {
+    if (U_FAILURE(errorCode_)) { return false; }
+    if (supportedLocales_ != nullptr) { return true; }
+    supportedLocales_ = new UVector(uprv_deleteUObject, nullptr, errorCode_);
+    if (U_FAILURE(errorCode_)) { return false; }
+    if (supportedLocales_ == nullptr) {
+        errorCode_ = U_MEMORY_ALLOCATION_ERROR;
+        return false;
+    }
+    return true;
+}
+
+LocaleMatcher::Builder &LocaleMatcher::Builder::setSupportedLocalesFromListString(
+        StringPiece locales) {
+    LocalePriorityList list(locales, errorCode_);
+    if (U_FAILURE(errorCode_)) { return *this; }
+    clearSupportedLocales();
+    if (!ensureSupportedLocaleVector()) { return *this; }
+    int32_t length = list.getLengthIncludingRemoved();
+    for (int32_t i = 0; i < length; ++i) {
+        Locale *locale = list.orphanLocaleAt(i);
+        if (locale == nullptr) { continue; }
+        supportedLocales_->addElement(locale, errorCode_);
+        if (U_FAILURE(errorCode_)) {
+            delete locale;
+            break;
+        }
+    }
+    return *this;
+}
+
+LocaleMatcher::Builder &LocaleMatcher::Builder::setSupportedLocales(Locale::Iterator &locales) {
+    if (U_FAILURE(errorCode_)) { return *this; }
+    clearSupportedLocales();
+    if (!ensureSupportedLocaleVector()) { return *this; }
+    while (locales.hasNext()) {
+        const Locale &locale = locales.next();
+        Locale *clone = locale.clone();
+        if (clone == nullptr) {
+            errorCode_ = U_MEMORY_ALLOCATION_ERROR;
+            break;
+        }
+        supportedLocales_->addElement(clone, errorCode_);
+        if (U_FAILURE(errorCode_)) {
+            delete clone;
+            break;
+        }
+    }
+    return *this;
+}
+
+LocaleMatcher::Builder &LocaleMatcher::Builder::addSupportedLocale(const Locale &locale) {
+    if (!ensureSupportedLocaleVector()) { return *this; }
+    Locale *clone = locale.clone();
+    if (clone == nullptr) {
+        errorCode_ = U_MEMORY_ALLOCATION_ERROR;
+        return *this;
+    }
+    supportedLocales_->addElement(clone, errorCode_);
+    if (U_FAILURE(errorCode_)) {
+        delete clone;
+    }
+    return *this;
+}
+
+LocaleMatcher::Builder &LocaleMatcher::Builder::setNoDefaultLocale() {
+    if (U_FAILURE(errorCode_)) { return *this; }
+    delete defaultLocale_;
+    defaultLocale_ = nullptr;
+    withDefault_ = false;
+    return *this;
+}
+
+LocaleMatcher::Builder &LocaleMatcher::Builder::setDefaultLocale(const Locale *defaultLocale) {
+    if (U_FAILURE(errorCode_)) { return *this; }
+    Locale *clone = nullptr;
+    if (defaultLocale != nullptr) {
+        clone = defaultLocale->clone();
+        if (clone == nullptr) {
+            errorCode_ = U_MEMORY_ALLOCATION_ERROR;
+            return *this;
+        }
+    }
+    delete defaultLocale_;
+    defaultLocale_ = clone;
+    withDefault_ = true;
+    return *this;
+}
+
+LocaleMatcher::Builder &LocaleMatcher::Builder::setFavorSubtag(ULocMatchFavorSubtag subtag) {
+    if (U_FAILURE(errorCode_)) { return *this; }
+    favor_ = subtag;
+    return *this;
+}
+
+LocaleMatcher::Builder &LocaleMatcher::Builder::setDemotionPerDesiredLocale(ULocMatchDemotion demotion) {
+    if (U_FAILURE(errorCode_)) { return *this; }
+    demotion_ = demotion;
+    return *this;
+}
+
+LocaleMatcher::Builder &LocaleMatcher::Builder::setMaxDistance(const Locale &desired,
+                                                               const Locale &supported) {
+    if (U_FAILURE(errorCode_)) { return *this; }
+    Locale *desiredClone = desired.clone();
+    Locale *supportedClone = supported.clone();
+    if (desiredClone == nullptr || supportedClone == nullptr) {
+        delete desiredClone;  // in case only one could not be allocated
+        delete supportedClone;
+        errorCode_ = U_MEMORY_ALLOCATION_ERROR;
+        return *this;
+    }
+    delete maxDistanceDesired_;
+    delete maxDistanceSupported_;
+    maxDistanceDesired_ = desiredClone;
+    maxDistanceSupported_ = supportedClone;
+    return *this;
+}
+
+#if 0
+/**
+ * <i>Internal only!</i>
+ *
+ * @param thresholdDistance the thresholdDistance to set, with -1 = default
+ * @return this Builder object
+ * @internal
+ * @deprecated This API is ICU internal only.
+ */
+@Deprecated
+LocaleMatcher::Builder &LocaleMatcher::Builder::internalSetThresholdDistance(int32_t thresholdDistance) {
+    if (U_FAILURE(errorCode_)) { return *this; }
+    if (thresholdDistance > 100) {
+        thresholdDistance = 100;
+    }
+    thresholdDistance_ = thresholdDistance;
+    return *this;
+}
+#endif
+
+UBool LocaleMatcher::Builder::copyErrorTo(UErrorCode &outErrorCode) const {
+    if (U_FAILURE(outErrorCode)) { return TRUE; }
+    if (U_SUCCESS(errorCode_)) { return FALSE; }
+    outErrorCode = errorCode_;
+    return TRUE;
+}
+
+LocaleMatcher LocaleMatcher::Builder::build(UErrorCode &errorCode) const {
+    if (U_SUCCESS(errorCode) && U_FAILURE(errorCode_)) {
+        errorCode = errorCode_;
+    }
+    return LocaleMatcher(*this, errorCode);
+}
+
+namespace {
+
+LSR getMaximalLsrOrUnd(const XLikelySubtags &likelySubtags, const Locale &locale,
+                       UErrorCode &errorCode) {
+    if (U_FAILURE(errorCode) || locale.isBogus() || *locale.getName() == 0 /* "und" */) {
+        return UND_LSR;
+    } else {
+        return likelySubtags.makeMaximizedLsrFrom(locale, errorCode);
+    }
+}
+
+int32_t hashLSR(const UHashTok token) {
+    const LSR *lsr = static_cast<const LSR *>(token.pointer);
+    return lsr->hashCode;
+}
+
+UBool compareLSRs(const UHashTok t1, const UHashTok t2) {
+    const LSR *lsr1 = static_cast<const LSR *>(t1.pointer);
+    const LSR *lsr2 = static_cast<const LSR *>(t2.pointer);
+    return *lsr1 == *lsr2;
+}
+
+}  // namespace
+
+int32_t LocaleMatcher::putIfAbsent(const LSR &lsr, int32_t i, int32_t suppLength,
+                                   UErrorCode &errorCode) {
+    if (U_FAILURE(errorCode)) { return suppLength; }
+    int32_t index = uhash_geti(supportedLsrToIndex, &lsr);
+    if (index == 0) {
+        uhash_puti(supportedLsrToIndex, const_cast<LSR *>(&lsr), i + 1, &errorCode);
+        if (U_SUCCESS(errorCode)) {
+            supportedLSRs[suppLength] = &lsr;
+            supportedIndexes[suppLength++] = i;
+        }
+    }
+    return suppLength;
+}
+
+LocaleMatcher::LocaleMatcher(const Builder &builder, UErrorCode &errorCode) :
+        likelySubtags(*XLikelySubtags::getSingleton(errorCode)),
+        localeDistance(*LocaleDistance::getSingleton(errorCode)),
+        thresholdDistance(builder.thresholdDistance_),
+        demotionPerDesiredLocale(0),
+        favorSubtag(builder.favor_),
+        direction(builder.direction_),
+        supportedLocales(nullptr), lsrs(nullptr), supportedLocalesLength(0),
+        supportedLsrToIndex(nullptr),
+        supportedLSRs(nullptr), supportedIndexes(nullptr), supportedLSRsLength(0),
+        ownedDefaultLocale(nullptr), defaultLocale(nullptr) {
+    if (U_FAILURE(errorCode)) { return; }
+    const Locale *def = builder.defaultLocale_;
+    LSR builderDefaultLSR;
+    const LSR *defLSR = nullptr;
+    if (def != nullptr) {
+        ownedDefaultLocale = def->clone();
+        if (ownedDefaultLocale == nullptr) {
+            errorCode = U_MEMORY_ALLOCATION_ERROR;
+            return;
+        }
+        def = ownedDefaultLocale;
+        builderDefaultLSR = getMaximalLsrOrUnd(likelySubtags, *def, errorCode);
+        if (U_FAILURE(errorCode)) { return; }
+        defLSR = &builderDefaultLSR;
+    }
+    supportedLocalesLength = builder.supportedLocales_ != nullptr ?
+        builder.supportedLocales_->size() : 0;
+    if (supportedLocalesLength > 0) {
+        // Store the supported locales in input order,
+        // so that when different types are used (e.g., language tag strings)
+        // we can return those by parallel index.
+        supportedLocales = static_cast<const Locale **>(
+            uprv_malloc(supportedLocalesLength * sizeof(const Locale *)));
+        // Supported LRSs in input order.
+        // In C++, we store these permanently to simplify ownership management
+        // in the hash tables. Duplicate LSRs (if any) are unused overhead.
+        lsrs = new LSR[supportedLocalesLength];
+        if (supportedLocales == nullptr || lsrs == nullptr) {
+            errorCode = U_MEMORY_ALLOCATION_ERROR;
+            return;
+        }
+        // If the constructor fails partway, we need null pointers for destructibility.
+        uprv_memset(supportedLocales, 0, supportedLocalesLength * sizeof(const Locale *));
+        for (int32_t i = 0; i < supportedLocalesLength; ++i) {
+            const Locale &locale = *static_cast<Locale *>(builder.supportedLocales_->elementAt(i));
+            supportedLocales[i] = locale.clone();
+            if (supportedLocales[i] == nullptr) {
+                errorCode = U_MEMORY_ALLOCATION_ERROR;
+                return;
+            }
+            const Locale &supportedLocale = *supportedLocales[i];
+            LSR &lsr = lsrs[i] = getMaximalLsrOrUnd(likelySubtags, supportedLocale, errorCode);
+            lsr.setHashCode();
+            if (U_FAILURE(errorCode)) { return; }
+        }
+
+        // We need an unordered map from LSR to first supported locale with that LSR,
+        // and an ordered list of (LSR, supported index) for
+        // the supported locales in the following order:
+        // 1. Default locale, if it is supported.
+        // 2. Priority locales (aka "paradigm locales") in builder order.
+        // 3. Remaining locales in builder order.
+        supportedLsrToIndex = uhash_openSize(hashLSR, compareLSRs, uhash_compareLong,
+                                             supportedLocalesLength, &errorCode);
+        if (U_FAILURE(errorCode)) { return; }
+        supportedLSRs = static_cast<const LSR **>(
+            uprv_malloc(supportedLocalesLength * sizeof(const LSR *)));
+        supportedIndexes = static_cast<int32_t *>(
+            uprv_malloc(supportedLocalesLength * sizeof(int32_t)));
+        if (supportedLSRs == nullptr || supportedIndexes == nullptr) {
+            errorCode = U_MEMORY_ALLOCATION_ERROR;
+            return;
+        }
+        int32_t suppLength = 0;
+        // Determine insertion order.
+        // Add locales immediately that are equivalent to the default.
+        MaybeStackArray<int8_t, 100> order(supportedLocalesLength, errorCode);
+        if (U_FAILURE(errorCode)) { return; }
+        int32_t numParadigms = 0;
+        for (int32_t i = 0; i < supportedLocalesLength; ++i) {
+            const Locale &locale = *supportedLocales[i];
+            const LSR &lsr = lsrs[i];
+            if (defLSR == nullptr && builder.withDefault_) {
+                // Implicit default locale = first supported locale, if not turned off.
+                U_ASSERT(i == 0);
+                def = &locale;
+                defLSR = &lsr;
+                order[i] = 1;
+                suppLength = putIfAbsent(lsr, 0, suppLength, errorCode);
+            } else if (defLSR != nullptr && lsr.isEquivalentTo(*defLSR)) {
+                order[i] = 1;
+                suppLength = putIfAbsent(lsr, i, suppLength, errorCode);
+            } else if (localeDistance.isParadigmLSR(lsr)) {
+                order[i] = 2;
+                ++numParadigms;
+            } else {
+                order[i] = 3;
+            }
+            if (U_FAILURE(errorCode)) { return; }
+        }
+        // Add supported paradigm locales.
+        int32_t paradigmLimit = suppLength + numParadigms;
+        for (int32_t i = 0; i < supportedLocalesLength && suppLength < paradigmLimit; ++i) {
+            if (order[i] == 2) {
+                suppLength = putIfAbsent(lsrs[i], i, suppLength, errorCode);
+            }
+        }
+        // Add remaining supported locales.
+        for (int32_t i = 0; i < supportedLocalesLength; ++i) {
+            if (order[i] == 3) {
+                suppLength = putIfAbsent(lsrs[i], i, suppLength, errorCode);
+            }
+        }
+        supportedLSRsLength = suppLength;
+        // If supportedLSRsLength < supportedLocalesLength then
+        // we waste as many array slots as there are duplicate supported LSRs,
+        // but the amount of wasted space is small as long as there are few duplicates.
+    }
+
+    defaultLocale = def;
+
+    if (builder.demotion_ == ULOCMATCH_DEMOTION_REGION) {
+        demotionPerDesiredLocale = localeDistance.getDefaultDemotionPerDesiredLocale();
+    }
+
+    if (thresholdDistance >= 0) {
+        // already copied
+    } else if (builder.maxDistanceDesired_ != nullptr) {
+        LSR suppLSR = getMaximalLsrOrUnd(likelySubtags, *builder.maxDistanceSupported_, errorCode);
+        const LSR *pSuppLSR = &suppLSR;
+        int32_t indexAndDistance = localeDistance.getBestIndexAndDistance(
+                getMaximalLsrOrUnd(likelySubtags, *builder.maxDistanceDesired_, errorCode),
+                &pSuppLSR, 1,
+                LocaleDistance::shiftDistance(100), favorSubtag, direction);
+        if (U_SUCCESS(errorCode)) {
+            // +1 for an exclusive threshold from an inclusive max.
+            thresholdDistance = LocaleDistance::getDistanceFloor(indexAndDistance) + 1;
+        } else {
+            thresholdDistance = 0;
+        }
+    } else {
+        thresholdDistance = localeDistance.getDefaultScriptDistance();
+    }
+}
+
+LocaleMatcher::LocaleMatcher(LocaleMatcher &&src) U_NOEXCEPT :
+        likelySubtags(src.likelySubtags),
+        localeDistance(src.localeDistance),
+        thresholdDistance(src.thresholdDistance),
+        demotionPerDesiredLocale(src.demotionPerDesiredLocale),
+        favorSubtag(src.favorSubtag),
+        direction(src.direction),
+        supportedLocales(src.supportedLocales), lsrs(src.lsrs),
+        supportedLocalesLength(src.supportedLocalesLength),
+        supportedLsrToIndex(src.supportedLsrToIndex),
+        supportedLSRs(src.supportedLSRs),
+        supportedIndexes(src.supportedIndexes),
+        supportedLSRsLength(src.supportedLSRsLength),
+        ownedDefaultLocale(src.ownedDefaultLocale), defaultLocale(src.defaultLocale) {
+    src.supportedLocales = nullptr;
+    src.lsrs = nullptr;
+    src.supportedLocalesLength = 0;
+    src.supportedLsrToIndex = nullptr;
+    src.supportedLSRs = nullptr;
+    src.supportedIndexes = nullptr;
+    src.supportedLSRsLength = 0;
+    src.ownedDefaultLocale = nullptr;
+    src.defaultLocale = nullptr;
+}
+
+LocaleMatcher::~LocaleMatcher() {
+    for (int32_t i = 0; i < supportedLocalesLength; ++i) {
+        delete supportedLocales[i];
+    }
+    uprv_free(supportedLocales);
+    delete[] lsrs;
+    uhash_close(supportedLsrToIndex);
+    uprv_free(supportedLSRs);
+    uprv_free(supportedIndexes);
+    delete ownedDefaultLocale;
+}
+
+LocaleMatcher &LocaleMatcher::operator=(LocaleMatcher &&src) U_NOEXCEPT {
+    this->~LocaleMatcher();
+
+    thresholdDistance = src.thresholdDistance;
+    demotionPerDesiredLocale = src.demotionPerDesiredLocale;
+    favorSubtag = src.favorSubtag;
+    direction = src.direction;
+    supportedLocales = src.supportedLocales;
+    lsrs = src.lsrs;
+    supportedLocalesLength = src.supportedLocalesLength;
+    supportedLsrToIndex = src.supportedLsrToIndex;
+    supportedLSRs = src.supportedLSRs;
+    supportedIndexes = src.supportedIndexes;
+    supportedLSRsLength = src.supportedLSRsLength;
+    ownedDefaultLocale = src.ownedDefaultLocale;
+    defaultLocale = src.defaultLocale;
+
+    src.supportedLocales = nullptr;
+    src.lsrs = nullptr;
+    src.supportedLocalesLength = 0;
+    src.supportedLsrToIndex = nullptr;
+    src.supportedLSRs = nullptr;
+    src.supportedIndexes = nullptr;
+    src.supportedLSRsLength = 0;
+    src.ownedDefaultLocale = nullptr;
+    src.defaultLocale = nullptr;
+    return *this;
+}
+
+class LocaleLsrIterator {
+public:
+    LocaleLsrIterator(const XLikelySubtags &likelySubtags, Locale::Iterator &locales,
+                      ULocMatchLifetime lifetime) :
+            likelySubtags(likelySubtags), locales(locales), lifetime(lifetime) {}
+
+    ~LocaleLsrIterator() {
+        if (lifetime == ULOCMATCH_TEMPORARY_LOCALES) {
+            delete remembered;
+        }
+    }
+
+    bool hasNext() const {
+        return locales.hasNext();
+    }
+
+    LSR next(UErrorCode &errorCode) {
+        current = &locales.next();
+        return getMaximalLsrOrUnd(likelySubtags, *current, errorCode);
+    }
+
+    void rememberCurrent(int32_t desiredIndex, UErrorCode &errorCode) {
+        if (U_FAILURE(errorCode)) { return; }
+        bestDesiredIndex = desiredIndex;
+        if (lifetime == ULOCMATCH_STORED_LOCALES) {
+            remembered = current;
+        } else {
+            // ULOCMATCH_TEMPORARY_LOCALES
+            delete remembered;
+            remembered = new Locale(*current);
+            if (remembered == nullptr) {
+                errorCode = U_MEMORY_ALLOCATION_ERROR;
+            }
+        }
+    }
+
+    const Locale *orphanRemembered() {
+        const Locale *rem = remembered;
+        remembered = nullptr;
+        return rem;
+    }
+
+    int32_t getBestDesiredIndex() const {
+        return bestDesiredIndex;
+    }
+
+private:
+    const XLikelySubtags &likelySubtags;
+    Locale::Iterator &locales;
+    ULocMatchLifetime lifetime;
+    const Locale *current = nullptr, *remembered = nullptr;
+    int32_t bestDesiredIndex = -1;
+};
+
+const Locale *LocaleMatcher::getBestMatch(const Locale &desiredLocale, UErrorCode &errorCode) const {
+    if (U_FAILURE(errorCode)) { return nullptr; }
+    int32_t suppIndex = getBestSuppIndex(
+        getMaximalLsrOrUnd(likelySubtags, desiredLocale, errorCode),
+        nullptr, errorCode);
+    return U_SUCCESS(errorCode) && suppIndex >= 0 ? supportedLocales[suppIndex] : defaultLocale;
+}
+
+const Locale *LocaleMatcher::getBestMatch(Locale::Iterator &desiredLocales,
+                                          UErrorCode &errorCode) const {
+    if (U_FAILURE(errorCode)) { return nullptr; }
+    if (!desiredLocales.hasNext()) {
+        return defaultLocale;
+    }
+    LocaleLsrIterator lsrIter(likelySubtags, desiredLocales, ULOCMATCH_TEMPORARY_LOCALES);
+    int32_t suppIndex = getBestSuppIndex(lsrIter.next(errorCode), &lsrIter, errorCode);
+    return U_SUCCESS(errorCode) && suppIndex >= 0 ? supportedLocales[suppIndex] : defaultLocale;
+}
+
+const Locale *LocaleMatcher::getBestMatchForListString(
+        StringPiece desiredLocaleList, UErrorCode &errorCode) const {
+    LocalePriorityList list(desiredLocaleList, errorCode);
+    LocalePriorityList::Iterator iter = list.iterator();
+    return getBestMatch(iter, errorCode);
+}
+
+LocaleMatcher::Result LocaleMatcher::getBestMatchResult(
+        const Locale &desiredLocale, UErrorCode &errorCode) const {
+    if (U_FAILURE(errorCode)) {
+        return Result(nullptr, defaultLocale, -1, -1, FALSE);
+    }
+    int32_t suppIndex = getBestSuppIndex(
+        getMaximalLsrOrUnd(likelySubtags, desiredLocale, errorCode),
+        nullptr, errorCode);
+    if (U_FAILURE(errorCode) || suppIndex < 0) {
+        return Result(nullptr, defaultLocale, -1, -1, FALSE);
+    } else {
+        return Result(&desiredLocale, supportedLocales[suppIndex], 0, suppIndex, FALSE);
+    }
+}
+
+LocaleMatcher::Result LocaleMatcher::getBestMatchResult(
+        Locale::Iterator &desiredLocales, UErrorCode &errorCode) const {
+    if (U_FAILURE(errorCode) || !desiredLocales.hasNext()) {
+        return Result(nullptr, defaultLocale, -1, -1, FALSE);
+    }
+    LocaleLsrIterator lsrIter(likelySubtags, desiredLocales, ULOCMATCH_TEMPORARY_LOCALES);
+    int32_t suppIndex = getBestSuppIndex(lsrIter.next(errorCode), &lsrIter, errorCode);
+    if (U_FAILURE(errorCode) || suppIndex < 0) {
+        return Result(nullptr, defaultLocale, -1, -1, FALSE);
+    } else {
+        return Result(lsrIter.orphanRemembered(), supportedLocales[suppIndex],
+                      lsrIter.getBestDesiredIndex(), suppIndex, TRUE);
+    }
+}
+
+int32_t LocaleMatcher::getBestSuppIndex(LSR desiredLSR, LocaleLsrIterator *remainingIter,
+                                        UErrorCode &errorCode) const {
+    if (U_FAILURE(errorCode)) { return -1; }
+    int32_t desiredIndex = 0;
+    int32_t bestSupportedLsrIndex = -1;
+    for (int32_t bestShiftedDistance = LocaleDistance::shiftDistance(thresholdDistance);;) {
+        // Quick check for exact maximized LSR.
+        // Returns suppIndex+1 where 0 means not found.
+        if (supportedLsrToIndex != nullptr) {
+            desiredLSR.setHashCode();
+            int32_t index = uhash_geti(supportedLsrToIndex, &desiredLSR);
+            if (index != 0) {
+                int32_t suppIndex = index - 1;
+                if (remainingIter != nullptr) {
+                    remainingIter->rememberCurrent(desiredIndex, errorCode);
+                }
+                return suppIndex;
+            }
+        }
+        int32_t bestIndexAndDistance = localeDistance.getBestIndexAndDistance(
+                desiredLSR, supportedLSRs, supportedLSRsLength,
+                bestShiftedDistance, favorSubtag, direction);
+        if (bestIndexAndDistance >= 0) {
+            bestShiftedDistance = LocaleDistance::getShiftedDistance(bestIndexAndDistance);
+            if (remainingIter != nullptr) {
+                remainingIter->rememberCurrent(desiredIndex, errorCode);
+                if (U_FAILURE(errorCode)) { return -1; }
+            }
+            bestSupportedLsrIndex = LocaleDistance::getIndex(bestIndexAndDistance);
+        }
+        if ((bestShiftedDistance -= LocaleDistance::shiftDistance(demotionPerDesiredLocale)) <= 0) {
+            break;
+        }
+        if (remainingIter == nullptr || !remainingIter->hasNext()) {
+            break;
+        }
+        desiredLSR = remainingIter->next(errorCode);
+        if (U_FAILURE(errorCode)) { return -1; }
+        ++desiredIndex;
+    }
+    if (bestSupportedLsrIndex < 0) {
+        // no good match
+        return -1;
+    }
+    return supportedIndexes[bestSupportedLsrIndex];
+}
+
+UBool LocaleMatcher::isMatch(const Locale &desired, const Locale &supported,
+                             UErrorCode &errorCode) const {
+    LSR suppLSR = getMaximalLsrOrUnd(likelySubtags, supported, errorCode);
+    if (U_FAILURE(errorCode)) { return 0; }
+    const LSR *pSuppLSR = &suppLSR;
+    int32_t indexAndDistance = localeDistance.getBestIndexAndDistance(
+            getMaximalLsrOrUnd(likelySubtags, desired, errorCode),
+            &pSuppLSR, 1,
+            LocaleDistance::shiftDistance(thresholdDistance), favorSubtag, direction);
+    return indexAndDistance >= 0;
+}
+
+double LocaleMatcher::internalMatch(const Locale &desired, const Locale &supported, UErrorCode &errorCode) const {
+    // Returns the inverse of the distance: That is, 1-distance(desired, supported).
+    LSR suppLSR = getMaximalLsrOrUnd(likelySubtags, supported, errorCode);
+    if (U_FAILURE(errorCode)) { return 0; }
+    const LSR *pSuppLSR = &suppLSR;
+    int32_t indexAndDistance = localeDistance.getBestIndexAndDistance(
+            getMaximalLsrOrUnd(likelySubtags, desired, errorCode),
+            &pSuppLSR, 1,
+            LocaleDistance::shiftDistance(thresholdDistance), favorSubtag, direction);
+    double distance = LocaleDistance::getDistanceDouble(indexAndDistance);
+    return (100.0 - distance) / 100.0;
+}
+
+U_NAMESPACE_END
+
+// uloc_acceptLanguage() --------------------------------------------------- ***
+
+U_NAMESPACE_USE
+
+namespace {
+
+class LocaleFromTag {
+public:
+    LocaleFromTag() : locale(Locale::getRoot()) {}
+    const Locale &operator()(const char *tag) { return locale = Locale(tag); }
+
+private:
+    // Store the locale in the converter, rather than return a reference to a temporary,
+    // or a value which could go out of scope with the caller's reference to it.
+    Locale locale;
+};
+
+int32_t acceptLanguage(UEnumeration &supportedLocales, Locale::Iterator &desiredLocales,
+                       char *dest, int32_t capacity, UAcceptResult *acceptResult,
+                       UErrorCode &errorCode) {
+    if (U_FAILURE(errorCode)) { return 0; }
+    LocaleMatcher::Builder builder;
+    const char *locString;
+    while ((locString = uenum_next(&supportedLocales, nullptr, &errorCode)) != nullptr) {
+        Locale loc(locString);
+        if (loc.isBogus()) {
+            errorCode = U_ILLEGAL_ARGUMENT_ERROR;
+            return 0;
+        }
+        builder.addSupportedLocale(loc);
+    }
+    LocaleMatcher matcher = builder.build(errorCode);
+    LocaleMatcher::Result result = matcher.getBestMatchResult(desiredLocales, errorCode);
+    if (U_FAILURE(errorCode)) { return 0; }
+    if (result.getDesiredIndex() >= 0) {
+        if (acceptResult != nullptr) {
+            *acceptResult = *result.getDesiredLocale() == *result.getSupportedLocale() ?
+                ULOC_ACCEPT_VALID : ULOC_ACCEPT_FALLBACK;
+        }
+        const char *bestStr = result.getSupportedLocale()->getName();
+        int32_t bestLength = (int32_t)uprv_strlen(bestStr);
+        if (bestLength <= capacity) {
+            uprv_memcpy(dest, bestStr, bestLength);
+        }
+        return u_terminateChars(dest, capacity, bestLength, &errorCode);
+    } else {
+        if (acceptResult != nullptr) {
+            *acceptResult = ULOC_ACCEPT_FAILED;
+        }
+        return u_terminateChars(dest, capacity, 0, &errorCode);
+    }
+}
+
+}  // namespace
+
+U_CAPI int32_t U_EXPORT2
+uloc_acceptLanguage(char *result, int32_t resultAvailable,
+                    UAcceptResult *outResult,
+                    const char **acceptList, int32_t acceptListCount,
+                    UEnumeration *availableLocales,
+                    UErrorCode *status) {
+    if (U_FAILURE(*status)) { return 0; }
+    if ((result == nullptr ? resultAvailable != 0 : resultAvailable < 0) ||
+            (acceptList == nullptr ? acceptListCount != 0 : acceptListCount < 0) ||
+            availableLocales == nullptr) {
+        *status = U_ILLEGAL_ARGUMENT_ERROR;
+        return 0;
+    }
+    LocaleFromTag converter;
+    Locale::ConvertingIterator<const char **, LocaleFromTag> desiredLocales(
+        acceptList, acceptList + acceptListCount, converter);
+    return acceptLanguage(*availableLocales, desiredLocales,
+                          result, resultAvailable, outResult, *status);
+}
+
+U_CAPI int32_t U_EXPORT2
+uloc_acceptLanguageFromHTTP(char *result, int32_t resultAvailable,
+                            UAcceptResult *outResult,
+                            const char *httpAcceptLanguage,
+                            UEnumeration *availableLocales,
+                            UErrorCode *status) {
+    if (U_FAILURE(*status)) { return 0; }
+    if ((result == nullptr ? resultAvailable != 0 : resultAvailable < 0) ||
+            httpAcceptLanguage == nullptr || availableLocales == nullptr) {
+        *status = U_ILLEGAL_ARGUMENT_ERROR;
+        return 0;
+    }
+    LocalePriorityList list(httpAcceptLanguage, *status);
+    LocalePriorityList::Iterator desiredLocales = list.iterator();
+    return acceptLanguage(*availableLocales, desiredLocales,
+                          result, resultAvailable, outResult, *status);
+}
diff --git a/src/third_party/icu/source/common/localeprioritylist.cpp b/src/third_party/icu/source/common/localeprioritylist.cpp
new file mode 100644
index 0000000..8916b12
--- /dev/null
+++ b/src/third_party/icu/source/common/localeprioritylist.cpp
@@ -0,0 +1,239 @@
+// © 2019 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+// localeprioritylist.cpp
+// created: 2019jul11 Markus W. Scherer
+
+#include "unicode/utypes.h"
+#include "unicode/localpointer.h"
+#include "unicode/locid.h"
+#include "unicode/stringpiece.h"
+#include "unicode/uobject.h"
+#include "charstr.h"
+#include "cmemory.h"
+#include "localeprioritylist.h"
+#include "uarrsort.h"
+#include "uassert.h"
+#include "uhash.h"
+
+U_NAMESPACE_BEGIN
+
+namespace {
+
+int32_t hashLocale(const UHashTok token) {
+    auto *locale = static_cast<const Locale *>(token.pointer);
+    return locale->hashCode();
+}
+
+UBool compareLocales(const UHashTok t1, const UHashTok t2) {
+    auto *l1 = static_cast<const Locale *>(t1.pointer);
+    auto *l2 = static_cast<const Locale *>(t2.pointer);
+    return *l1 == *l2;
+}
+
+constexpr int32_t WEIGHT_ONE = 1000;
+
+struct LocaleAndWeight {
+    Locale *locale;
+    int32_t weight;  // 0..1000 = 0.0..1.0
+    int32_t index;  // force stable sort
+
+    int32_t compare(const LocaleAndWeight &other) const {
+        int32_t diff = other.weight - weight;  // descending: other-this
+        if (diff != 0) { return diff; }
+        return index - other.index;
+    }
+};
+
+int32_t U_CALLCONV
+compareLocaleAndWeight(const void * /*context*/, const void *left, const void *right) {
+    return static_cast<const LocaleAndWeight *>(left)->
+        compare(*static_cast<const LocaleAndWeight *>(right));
+}
+
+const char *skipSpaces(const char *p, const char *limit) {
+    while (p < limit && *p == ' ') { ++p; }
+    return p;
+}
+
+int32_t findTagLength(const char *p, const char *limit) {
+    // Look for accept-language delimiters.
+    // Leave other validation up to the Locale constructor.
+    const char *q;
+    for (q = p; q < limit; ++q) {
+        char c = *q;
+        if (c == ' ' || c == ',' || c == ';') { break; }
+    }
+    return static_cast<int32_t>(q - p);
+}
+
+/**
+ * Parses and returns a qvalue weight in millis.
+ * Advances p to after the parsed substring.
+ * Returns a negative value if parsing fails.
+ */
+int32_t parseWeight(const char *&p, const char *limit) {
+    p = skipSpaces(p, limit);
+    char c;
+    if (p == limit || ((c = *p) != '0' && c != '1')) { return -1; }
+    int32_t weight = (c - '0') * 1000;
+    if (++p == limit || *p != '.') { return weight; }
+    int32_t multiplier = 100;
+    while (++p != limit && '0' <= (c = *p) && c <= '9') {
+        c -= '0';
+        if (multiplier > 0) {
+            weight += c * multiplier;
+            multiplier /= 10;
+        } else if (multiplier == 0) {
+            // round up
+            if (c >= 5) { ++weight; }
+            multiplier = -1;
+        }  // else ignore further fraction digits
+    }
+    return weight <= WEIGHT_ONE ? weight : -1;  // bad if > 1.0
+}
+
+}  // namespace
+
+/**
+ * Nothing but a wrapper over a MaybeStackArray of LocaleAndWeight.
+ *
+ * This wrapper exists (and is not in an anonymous namespace)
+ * so that we can forward-declare it in the header file and
+ * don't have to expose the MaybeStackArray specialization and
+ * the LocaleAndWeight to code (like the test) that #includes localeprioritylist.h.
+ * Also, otherwise we would have to do a platform-specific
+ * template export declaration of some kind for the MaybeStackArray specialization
+ * to be properly exported from the common DLL.
+ */
+struct LocaleAndWeightArray : public UMemory {
+    MaybeStackArray<LocaleAndWeight, 20> array;
+};
+
+LocalePriorityList::LocalePriorityList(StringPiece s, UErrorCode &errorCode) {
+    if (U_FAILURE(errorCode)) { return; }
+    list = new LocaleAndWeightArray();
+    if (list == nullptr) {
+        errorCode = U_MEMORY_ALLOCATION_ERROR;
+        return;
+    }
+    const char *p = s.data();
+    const char *limit = p + s.length();
+    while ((p = skipSpaces(p, limit)) != limit) {
+        if (*p == ',') {  // empty range field
+            ++p;
+            continue;
+        }
+        int32_t tagLength = findTagLength(p, limit);
+        if (tagLength == 0) {
+            errorCode = U_ILLEGAL_ARGUMENT_ERROR;
+            return;
+        }
+        CharString tag(p, tagLength, errorCode);
+        if (U_FAILURE(errorCode)) { return; }
+        Locale locale = Locale(tag.data());
+        if (locale.isBogus()) {
+            errorCode = U_ILLEGAL_ARGUMENT_ERROR;
+            return;
+        }
+        int32_t weight = WEIGHT_ONE;
+        if ((p = skipSpaces(p + tagLength, limit)) != limit && *p == ';') {
+            if ((p = skipSpaces(p + 1, limit)) == limit || *p != 'q' ||
+                    (p = skipSpaces(p + 1, limit)) == limit || *p != '=' ||
+                    (++p, (weight = parseWeight(p, limit)) < 0)) {
+                errorCode = U_ILLEGAL_ARGUMENT_ERROR;
+                return;
+            }
+            p = skipSpaces(p, limit);
+        }
+        if (p != limit && *p != ',') {  // trailing junk
+            errorCode = U_ILLEGAL_ARGUMENT_ERROR;
+            return;
+        }
+        add(locale, weight, errorCode);
+        if (p == limit) { break; }
+        ++p;
+    }
+    sort(errorCode);
+}
+
+LocalePriorityList::~LocalePriorityList() {
+    if (list != nullptr) {
+        for (int32_t i = 0; i < listLength; ++i) {
+            delete list->array[i].locale;
+        }
+        delete list;
+    }
+    uhash_close(map);
+}
+
+const Locale *LocalePriorityList::localeAt(int32_t i) const {
+    return list->array[i].locale;
+}
+
+Locale *LocalePriorityList::orphanLocaleAt(int32_t i) {
+    if (list == nullptr) { return nullptr; }
+    LocaleAndWeight &lw = list->array[i];
+    Locale *l = lw.locale;
+    lw.locale = nullptr;
+    return l;
+}
+
+bool LocalePriorityList::add(const Locale &locale, int32_t weight, UErrorCode &errorCode) {
+    if (U_FAILURE(errorCode)) { return false; }
+    if (map == nullptr) {
+        if (weight <= 0) { return true; }  // do not add q=0
+        map = uhash_open(hashLocale, compareLocales, uhash_compareLong, &errorCode);
+        if (U_FAILURE(errorCode)) { return false; }
+    }
+    LocalPointer<Locale> clone;
+    int32_t index = uhash_geti(map, &locale);
+    if (index != 0) {
+        // Duplicate: Remove the old item and append it anew.
+        LocaleAndWeight &lw = list->array[index - 1];
+        clone.adoptInstead(lw.locale);
+        lw.locale = nullptr;
+        lw.weight = 0;
+        ++numRemoved;
+    }
+    if (weight <= 0) {  // do not add q=0
+        if (index != 0) {
+            // Not strictly necessary but cleaner.
+            uhash_removei(map, &locale);
+        }
+        return true;
+    }
+    if (clone.isNull()) {
+        clone.adoptInstead(locale.clone());
+        if (clone.isNull() || (clone->isBogus() && !locale.isBogus())) {
+            errorCode = U_MEMORY_ALLOCATION_ERROR;
+            return false;
+        }
+    }
+    if (listLength == list->array.getCapacity()) {
+        int32_t newCapacity = listLength < 50 ? 100 : 4 * listLength;
+        if (list->array.resize(newCapacity, listLength) == nullptr) {
+            errorCode = U_MEMORY_ALLOCATION_ERROR;
+            return false;
+        }
+    }
+    uhash_puti(map, clone.getAlias(), listLength + 1, &errorCode);
+    if (U_FAILURE(errorCode)) { return false; }
+    LocaleAndWeight &lw = list->array[listLength];
+    lw.locale = clone.orphan();
+    lw.weight = weight;
+    lw.index = listLength++;
+    if (weight < WEIGHT_ONE) { hasWeights = true; }
+    U_ASSERT(uhash_count(map) == getLength());
+    return true;
+}
+
+void LocalePriorityList::sort(UErrorCode &errorCode) {
+    // Sort by descending weights if there is a mix of weights.
+    // The comparator forces a stable sort via the item index.
+    if (U_FAILURE(errorCode) || getLength() <= 1 || !hasWeights) { return; }
+    uprv_sortArray(list->array.getAlias(), listLength, sizeof(LocaleAndWeight),
+                   compareLocaleAndWeight, nullptr, FALSE, &errorCode);
+}
+
+U_NAMESPACE_END
diff --git a/src/third_party/icu/source/common/localeprioritylist.h b/src/third_party/icu/source/common/localeprioritylist.h
new file mode 100644
index 0000000..41e9d3e
--- /dev/null
+++ b/src/third_party/icu/source/common/localeprioritylist.h
@@ -0,0 +1,115 @@
+// © 2019 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+// localeprioritylist.h
+// created: 2019jul11 Markus W. Scherer
+
+#ifndef __LOCALEPRIORITYLIST_H__
+#define __LOCALEPRIORITYLIST_H__
+
+#include "unicode/utypes.h"
+#include "unicode/locid.h"
+#include "unicode/stringpiece.h"
+#include "unicode/uobject.h"
+
+struct UHashtable;
+
+U_NAMESPACE_BEGIN
+
+struct LocaleAndWeightArray;
+
+/**
+ * Parses a list of locales from an accept-language string.
+ * We are a bit more lenient than the spec:
+ * We accept extra whitespace in more places, empty range fields,
+ * and any number of qvalue fraction digits.
+ *
+ * https://tools.ietf.org/html/rfc2616#section-14.4
+ * 14.4 Accept-Language
+ *
+ *        Accept-Language = "Accept-Language" ":"
+ *                          1#( language-range [ ";" "q" "=" qvalue ] )
+ *        language-range  = ( ( 1*8ALPHA *( "-" 1*8ALPHA ) ) | "*" )
+ *
+ *    Each language-range MAY be given an associated quality value which
+ *    represents an estimate of the user's preference for the languages
+ *    specified by that range. The quality value defaults to "q=1". For
+ *    example,
+ *
+ *        Accept-Language: da, en-gb;q=0.8, en;q=0.7
+ *
+ * https://tools.ietf.org/html/rfc2616#section-3.9
+ * 3.9 Quality Values
+ *
+ *    HTTP content negotiation (section 12) uses short "floating point"
+ *    numbers to indicate the relative importance ("weight") of various
+ *    negotiable parameters.  A weight is normalized to a real number in
+ *    the range 0 through 1, where 0 is the minimum and 1 the maximum
+ *    value. If a parameter has a quality value of 0, then content with
+ *    this parameter is `not acceptable' for the client. HTTP/1.1
+ *    applications MUST NOT generate more than three digits after the
+ *    decimal point. User configuration of these values SHOULD also be
+ *    limited in this fashion.
+ *
+ *        qvalue         = ( "0" [ "." 0*3DIGIT ] )
+ *                       | ( "1" [ "." 0*3("0") ] )
+ */
+class U_COMMON_API LocalePriorityList : public UMemory {
+public:
+    class Iterator : public Locale::Iterator {
+    public:
+        UBool hasNext() const override { return count < length; }
+
+        const Locale &next() override {
+            for(;;) {
+                const Locale *locale = list.localeAt(index++);
+                if (locale != nullptr) {
+                    ++count;
+                    return *locale;
+                }
+            }
+        }
+
+    private:
+        friend class LocalePriorityList;
+
+        Iterator(const LocalePriorityList &list) : list(list), length(list.getLength()) {}
+
+        const LocalePriorityList &list;
+        int32_t index = 0;
+        int32_t count = 0;
+        const int32_t length;
+    };
+
+    LocalePriorityList(StringPiece s, UErrorCode &errorCode);
+
+    ~LocalePriorityList();
+
+    int32_t getLength() const { return listLength - numRemoved; }
+
+    int32_t getLengthIncludingRemoved() const { return listLength; }
+
+    Iterator iterator() const { return Iterator(*this); }
+
+    const Locale *localeAt(int32_t i) const;
+
+    Locale *orphanLocaleAt(int32_t i);
+
+private:
+    LocalePriorityList(const LocalePriorityList &) = delete;
+    LocalePriorityList &operator=(const LocalePriorityList &) = delete;
+
+    bool add(const Locale &locale, int32_t weight, UErrorCode &errorCode);
+
+    void sort(UErrorCode &errorCode);
+
+    LocaleAndWeightArray *list = nullptr;
+    int32_t listLength = 0;
+    int32_t numRemoved = 0;
+    bool hasWeights = false;  // other than 1.0
+    UHashtable *map = nullptr;
+};
+
+U_NAMESPACE_END
+
+#endif  // __LOCALEPRIORITYLIST_H__
diff --git a/src/third_party/icu/source/common/localsvc.h b/src/third_party/icu/source/common/localsvc.h
index 67e5a84..3364019 100644
--- a/src/third_party/icu/source/common/localsvc.h
+++ b/src/third_party/icu/source/common/localsvc.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ***************************************************************************
 *   Copyright (C) 2006 International Business Machines Corporation        *
@@ -10,7 +12,7 @@
 
 #include "unicode/utypes.h"
 
-#if U_LOCAL_SERVICE_HOOK
+#if defined(U_LOCAL_SERVICE_HOOK) && U_LOCAL_SERVICE_HOOK
 /**
  * Prototype for user-supplied service hook. This function is expected to return
  * a type of factory object specific to the requested service.
diff --git a/src/third_party/icu/source/common/locavailable.cpp b/src/third_party/icu/source/common/locavailable.cpp
index 7c2f6c6..a422992 100644
--- a/src/third_party/icu/source/common/locavailable.cpp
+++ b/src/third_party/icu/source/common/locavailable.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  locavailable.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -17,13 +19,17 @@
 *   that then do not depend on resource bundle code and res_index bundles.
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
+#include "unicode/errorcode.h"
 #include "unicode/utypes.h"
 #include "unicode/locid.h"
 #include "unicode/uloc.h"
 #include "unicode/ures.h"
 #include "cmemory.h"
+#include "cstring.h"
 #include "ucln_cmn.h"
 #include "uassert.h"
 #include "umutex.h"
@@ -35,7 +41,7 @@
 
 static icu::Locale*  availableLocaleList = NULL;
 static int32_t  availableLocaleListCount;
-static icu::UInitOnce gInitOnce = U_INITONCE_INITIALIZER;
+static icu::UInitOnce gInitOnceLocale = U_INITONCE_INITIALIZER;
 
 U_NAMESPACE_END
 
@@ -50,7 +56,7 @@
         availableLocaleList = NULL;
     }
     availableLocaleListCount = 0;
-    gInitOnce.reset();
+    gInitOnceLocale.reset();
 
     return TRUE;
 }
@@ -81,7 +87,7 @@
 const Locale* U_EXPORT2
 Locale::getAvailableLocales(int32_t& count)
 {
-    umtx_initOnce(gInitOnce, &locale_available_init);
+    umtx_initOnce(gInitOnceLocale, &locale_available_init);
     count = availableLocaleListCount;
     return availableLocaleList;
 }
@@ -95,87 +101,174 @@
 
 /* ### Constants **************************************************/
 
-/* These strings describe the resources we attempt to load from
- the locale ResourceBundle data file.*/
-static const char _kIndexLocaleName[] = "res_index";
-static const char _kIndexTag[]        = "InstalledLocales";
+namespace {
 
-static char** _installedLocales = NULL;
-static int32_t _installedLocalesCount = 0;
-static icu::UInitOnce _installedLocalesInitOnce;
+// Enough capacity for the two lists in the res_index.res file
+const char** gAvailableLocaleNames[2] = {};
+int32_t gAvailableLocaleCounts[2] = {};
+icu::UInitOnce ginstalledLocalesInitOnce = U_INITONCE_INITIALIZER;
+
+class AvailableLocalesSink : public ResourceSink {
+  public:
+    void put(const char *key, ResourceValue &value, UBool /*noFallback*/, UErrorCode &status) U_OVERRIDE {
+        ResourceTable resIndexTable = value.getTable(status);
+        if (U_FAILURE(status)) {
+            return;
+        }
+        for (int32_t i = 0; resIndexTable.getKeyAndValue(i, key, value); ++i) {
+            ULocAvailableType type;
+            if (uprv_strcmp(key, "InstalledLocales") == 0) {
+                type = ULOC_AVAILABLE_DEFAULT;
+            } else if (uprv_strcmp(key, "AliasLocales") == 0) {
+                type = ULOC_AVAILABLE_ONLY_LEGACY_ALIASES;
+            } else {
+                // CLDRVersion, etc.
+                continue;
+            }
+            ResourceTable availableLocalesTable = value.getTable(status);
+            if (U_FAILURE(status)) {
+                return;
+            }
+            gAvailableLocaleCounts[type] = availableLocalesTable.getSize();
+            gAvailableLocaleNames[type] = static_cast<const char**>(
+                uprv_malloc(gAvailableLocaleCounts[type] * sizeof(const char*)));
+            if (gAvailableLocaleNames[type] == nullptr) {
+                status = U_MEMORY_ALLOCATION_ERROR;
+                return;
+            }
+            for (int32_t j = 0; availableLocalesTable.getKeyAndValue(j, key, value); ++j) {
+                gAvailableLocaleNames[type][j] = key;
+            }
+        }
+    }
+};
+
+class AvailableLocalesStringEnumeration : public StringEnumeration {
+  public:
+    AvailableLocalesStringEnumeration(ULocAvailableType type) : fType(type) {
+    }
+
+    const char* next(int32_t *resultLength, UErrorCode&) override {
+        ULocAvailableType actualType = fType;
+        int32_t actualIndex = fIndex++;
+
+        // If the "combined" list was requested, resolve that now
+        if (fType == ULOC_AVAILABLE_WITH_LEGACY_ALIASES) {
+            int32_t defaultLocalesCount = gAvailableLocaleCounts[ULOC_AVAILABLE_DEFAULT];
+            if (actualIndex < defaultLocalesCount) {
+                actualType = ULOC_AVAILABLE_DEFAULT;
+            } else {
+                actualIndex -= defaultLocalesCount;
+                actualType = ULOC_AVAILABLE_ONLY_LEGACY_ALIASES;
+            }
+        }
+
+        // Return the requested string
+        int32_t count = gAvailableLocaleCounts[actualType];
+        const char* result;
+        if (actualIndex < count) {
+            result = gAvailableLocaleNames[actualType][actualIndex];
+            if (resultLength != nullptr) {
+                *resultLength = static_cast<int32_t>(uprv_strlen(result));
+            }
+        } else {
+            result = nullptr;
+            if (resultLength != nullptr) {
+                *resultLength = 0;
+            }
+        }
+        return result;
+    }
+
+    void reset(UErrorCode&) override {
+        fIndex = 0;
+    }
+
+    int32_t count(UErrorCode&) const override {
+        if (fType == ULOC_AVAILABLE_WITH_LEGACY_ALIASES) {
+            return gAvailableLocaleCounts[ULOC_AVAILABLE_DEFAULT]
+                + gAvailableLocaleCounts[ULOC_AVAILABLE_ONLY_LEGACY_ALIASES];
+        } else {
+            return gAvailableLocaleCounts[fType];
+        }
+    }
+
+  private:
+    ULocAvailableType fType;
+    int32_t fIndex = 0;
+};
 
 /* ### Get available **************************************************/
 
 static UBool U_CALLCONV uloc_cleanup(void) {
-    char ** temp;
-
-    if (_installedLocales) {
-        temp = _installedLocales;
-        _installedLocales = NULL;
-
-        _installedLocalesCount = 0;
-        _installedLocalesInitOnce.reset();
-
-        uprv_free(temp);
+    for (int32_t i = 0; i < UPRV_LENGTHOF(gAvailableLocaleNames); i++) {
+        uprv_free(gAvailableLocaleNames[i]);
+        gAvailableLocaleNames[i] = nullptr;
+        gAvailableLocaleCounts[i] = 0;
     }
+    ginstalledLocalesInitOnce.reset();
     return TRUE;
 }
 
 // Load Installed Locales. This function will be called exactly once
 //   via the initOnce mechanism.
 
-static void U_CALLCONV loadInstalledLocales() {
-    UResourceBundle *indexLocale = NULL;
-    UResourceBundle installed;
-    UErrorCode status = U_ZERO_ERROR;
-    int32_t i = 0;
-    int32_t localeCount;
-    
-    U_ASSERT(_installedLocales == NULL);
-    U_ASSERT(_installedLocalesCount == 0);
+static void U_CALLCONV loadInstalledLocales(UErrorCode& status) {
+    ucln_common_registerCleanup(UCLN_COMMON_ULOC, uloc_cleanup);
 
-    _installedLocalesCount = 0;
-    ures_initStackObject(&installed);
-    indexLocale = ures_openDirect(NULL, _kIndexLocaleName, &status);
-    ures_getByKey(indexLocale, _kIndexTag, &installed, &status);
-    
-    if(U_SUCCESS(status)) {
-        localeCount = ures_getSize(&installed);
-        _installedLocales = (char **) uprv_malloc(sizeof(char*) * (localeCount+1));
-        if (_installedLocales != NULL) {
-            ures_resetIterator(&installed);
-            while(ures_hasNext(&installed)) {
-                ures_getNextString(&installed, NULL, (const char **)&_installedLocales[i++], &status);
-            }
-            _installedLocales[i] = NULL;
-            _installedLocalesCount = localeCount;
-            ucln_common_registerCleanup(UCLN_COMMON_ULOC, uloc_cleanup);
-        }
-    }
-    ures_close(&installed);
-    ures_close(indexLocale);
+    icu::LocalUResourceBundlePointer rb(ures_openDirect(NULL, "res_index", &status));
+    AvailableLocalesSink sink;
+    ures_getAllItemsWithFallback(rb.getAlias(), "", sink, status);
 }
 
-static void _load_installedLocales()
-{
-    umtx_initOnce(_installedLocalesInitOnce, &loadInstalledLocales);
+void _load_installedLocales(UErrorCode& status) {
+    umtx_initOnce(ginstalledLocalesInitOnce, &loadInstalledLocales, status);
 }
 
+} // namespace
+
 U_CAPI const char* U_EXPORT2
-uloc_getAvailable(int32_t offset) 
-{
-    
-    _load_installedLocales();
-    
-    if (offset > _installedLocalesCount)
-        return NULL;
-    return _installedLocales[offset];
+uloc_getAvailable(int32_t offset) {
+    icu::ErrorCode status;
+    _load_installedLocales(status);
+    if (status.isFailure()) {
+        return nullptr;
+    }
+    if (offset > gAvailableLocaleCounts[0]) {
+        // *status = U_ILLEGAL_ARGUMENT_ERROR;
+        return nullptr;
+    }
+    return gAvailableLocaleNames[0][offset];
 }
 
 U_CAPI int32_t  U_EXPORT2
-uloc_countAvailable()
-{
-    _load_installedLocales();
-    return _installedLocalesCount;
+uloc_countAvailable() {
+    icu::ErrorCode status;
+    _load_installedLocales(status);
+    if (status.isFailure()) {
+        return 0;
+    }
+    return gAvailableLocaleCounts[0];
+}
+
+U_CAPI UEnumeration* U_EXPORT2
+uloc_openAvailableByType(ULocAvailableType type, UErrorCode* status) {
+    if (U_FAILURE(*status)) {
+        return nullptr;
+    }
+    if (type < 0 || type >= ULOC_AVAILABLE_COUNT) {
+        *status = U_ILLEGAL_ARGUMENT_ERROR;
+        return nullptr;
+    }
+    _load_installedLocales(*status);
+    if (U_FAILURE(*status)) {
+        return nullptr;
+    }
+    LocalPointer<AvailableLocalesStringEnumeration> result(
+        new AvailableLocalesStringEnumeration(type), *status);
+    if (U_FAILURE(*status)) {
+        return nullptr;
+    }
+    return uenum_openFromStringEnumeration(result.orphan(), status);
 }
 
diff --git a/src/third_party/icu/source/common/locbased.cpp b/src/third_party/icu/source/common/locbased.cpp
index 362c732..9252c83 100644
--- a/src/third_party/icu/source/common/locbased.cpp
+++ b/src/third_party/icu/source/common/locbased.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
 * Copyright (c) 2004-2014, International Business Machines
@@ -8,7 +10,9 @@
 * Since: ICU 2.8
 **********************************************************************
 */
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "locbased.h"
 #include "cstring.h"
 
diff --git a/src/third_party/icu/source/common/locbased.h b/src/third_party/icu/source/common/locbased.h
index 2e0400e..4573886 100644
--- a/src/third_party/icu/source/common/locbased.h
+++ b/src/third_party/icu/source/common/locbased.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
 * Copyright (c) 2004-2014, International Business Machines
@@ -20,7 +22,7 @@
  * `actualLocale' of size ULOC_FULLNAME_CAPACITY
  */
 #define U_LOCALE_BASED(varname, objname) \
-  LocaleBased varname((objname).validLocale, (objname).actualLocale);
+  LocaleBased varname((objname).validLocale, (objname).actualLocale)
 
 U_NAMESPACE_BEGIN
 
diff --git a/src/third_party/icu/source/common/locdispnames.cpp b/src/third_party/icu/source/common/locdispnames.cpp
index 2aefd25..90875df 100644
--- a/src/third_party/icu/source/common/locdispnames.cpp
+++ b/src/third_party/icu/source/common/locdispnames.cpp
@@ -1,12 +1,14 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
-*   Copyright (C) 1997-2013, International Business Machines
+*   Copyright (C) 1997-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *
 *******************************************************************************
 *   file name:  locdispnames.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -17,13 +19,18 @@
 *   that then do not depend on resource bundle code and display name data.
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/utypes.h"
 #include "unicode/brkiter.h"
 #include "unicode/locid.h"
+#include "unicode/uenum.h"
 #include "unicode/uloc.h"
 #include "unicode/ures.h"
 #include "unicode/ustring.h"
+#include "bytesinkutil.h"
+#include "charstr.h"
 #include "cmemory.h"
 #include "cstring.h"
 #include "putilimp.h"
@@ -305,14 +312,11 @@
 
     if(itemKey==NULL) {
         /* top-level item: normal resource bundle access */
-        UResourceBundle *rb;
-
-        rb=ures_open(path, locale, pErrorCode);
+        icu::LocalUResourceBundlePointer rb(ures_open(path, locale, pErrorCode));
 
         if(U_SUCCESS(*pErrorCode)) {
-            s=ures_getStringByKey(rb, tableKey, &length, pErrorCode);
+            s=ures_getStringByKey(rb.getAlias(), tableKey, &length, pErrorCode);
             /* see comment about closing rb near "return item;" in _res_getTableStringWithFallback() */
-            ures_close(rb);
         }
     } else {
         /* Language code should not be a number. If it is, set the error code. */
@@ -375,7 +379,12 @@
         return 0;
     }
     if(length==0) {
-        return u_terminateUChars(dest, destCapacity, 0, pErrorCode);
+        // For the display name, we treat this as unknown language (ICU-20273).
+        if (getter == uloc_getLanguage) {
+            uprv_strcpy(localeBuffer, "und");
+        } else {
+            return u_terminateUChars(dest, destCapacity, 0, pErrorCode);
+        }
     }
 
     root = tag == _kCountries ? U_ICUDATA_REGION : U_ICUDATA_LANG;
@@ -402,20 +411,26 @@
                       UChar *dest, int32_t destCapacity,
                       UErrorCode *pErrorCode)
 {
-	UErrorCode err = U_ZERO_ERROR;
-	int32_t res = _getDisplayNameForComponent(locale, displayLocale, dest, destCapacity,
+    UErrorCode err = U_ZERO_ERROR;
+    int32_t res = _getDisplayNameForComponent(locale, displayLocale, dest, destCapacity,
                 uloc_getScript, _kScriptsStandAlone, &err);
-	
-	if ( err == U_USING_DEFAULT_WARNING ) {
+
+    if (destCapacity == 0 && err == U_BUFFER_OVERFLOW_ERROR) {
+        // For preflight, return the max of the value and the fallback.
+        int32_t fallback_res = _getDisplayNameForComponent(locale, displayLocale, dest, destCapacity,
+                                                           uloc_getScript, _kScripts, pErrorCode);
+        return (fallback_res > res) ? fallback_res : res;
+    }
+    if ( err == U_USING_DEFAULT_WARNING ) {
         return _getDisplayNameForComponent(locale, displayLocale, dest, destCapacity,
-                    uloc_getScript, _kScripts, pErrorCode);
-	} else {
-		*pErrorCode = err;
-		return res;
-	}
+                                           uloc_getScript, _kScripts, pErrorCode);
+    } else {
+        *pErrorCode = err;
+        return res;
+    }
 }
 
-U_INTERNAL int32_t U_EXPORT2
+static int32_t
 uloc_getDisplayScriptInContext(const char* locale,
                       const char* displayLocale,
                       UChar *dest, int32_t destCapacity,
@@ -509,15 +524,14 @@
 
     {
         UErrorCode status = U_ZERO_ERROR;
-        UResourceBundle* locbundle=ures_open(U_ICUDATA_LANG, displayLocale, &status);
-        UResourceBundle* dspbundle=ures_getByKeyWithFallback(locbundle, _kLocaleDisplayPattern,
-                                                             NULL, &status);
 
-        separator=ures_getStringByKeyWithFallback(dspbundle, _kSeparator, &sepLen, &status);
-        pattern=ures_getStringByKeyWithFallback(dspbundle, _kPattern, &patLen, &status);
+        icu::LocalUResourceBundlePointer locbundle(
+                ures_open(U_ICUDATA_LANG, displayLocale, &status));
+        icu::LocalUResourceBundlePointer dspbundle(
+                ures_getByKeyWithFallback(locbundle.getAlias(), _kLocaleDisplayPattern, NULL, &status));
 
-        ures_close(dspbundle);
-        ures_close(locbundle);
+        separator=ures_getStringByKeyWithFallback(dspbundle.getAlias(), _kSeparator, &sepLen, &status);
+        pattern=ures_getStringByKeyWithFallback(dspbundle.getAlias(), _kPattern, &patLen, &status);
     }
 
     /* If we couldn't find any data, then use the defaults */
@@ -541,7 +555,7 @@
             return 0;
         }
         separator = (const UChar *)p0 + subLen;
-        sepLen = p1 - separator;
+        sepLen = static_cast<int32_t>(p1 - separator);
     }
 
     if(patLen==0 || (patLen==defaultPatLen && !u_strncmp(pattern, defaultPattern, patLen))) {
@@ -557,8 +571,8 @@
             *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
             return 0;
         }
-        sub0Pos=p0-pattern;
-        sub1Pos=p1-pattern;
+        sub0Pos = static_cast<int32_t>(p0-pattern);
+        sub1Pos = static_cast<int32_t>(p1-pattern);
         if (sub1Pos < sub0Pos) { /* a very odd pattern */
             int32_t t=sub0Pos; sub0Pos=sub1Pos; sub1Pos=t;
             langi=1;
@@ -585,7 +599,7 @@
         int32_t langPos=0; /* position in output of language substitution */
         int32_t restLen=0; /* length of 'everything else' substitution */
         int32_t restPos=0; /* position in output of 'everything else' substitution */
-        UEnumeration* kenum = NULL; /* keyword enumeration */
+        icu::LocalUEnumerationPointer kenum; /* keyword enumeration */
 
         /* prefix of pattern, extremely likely to be empty */
         if(sub0Pos) {
@@ -638,12 +652,11 @@
                             len=uloc_getDisplayVariant(locale, displayLocale, p, cap, pErrorCode);
                             break;
                         case 3:
-                            kenum = uloc_openKeywords(locale, pErrorCode);
-                            /* fall through */
+                            kenum.adoptInstead(uloc_openKeywords(locale, pErrorCode));
+                            U_FALLTHROUGH;
                         default: {
-                            const char* kw=uenum_next(kenum, &len, pErrorCode);
+                            const char* kw=uenum_next(kenum.getAlias(), &len, pErrorCode);
                             if (kw == NULL) {
-                                uenum_close(kenum);
                                 len=0; /* mark that we didn't add a component */
                                 subdone=TRUE;
                             } else {
@@ -725,7 +738,7 @@
                     int32_t padLen;
                     patPos+=subLen;
                     padLen=(subi==0 ? sub1Pos : patLen)-patPos;
-                    if(length+padLen < destCapacity) {
+                    if(length+padLen <= destCapacity) {
                         p=dest+length;
                         for(int32_t i=0;i<padLen;++i) {
                             *p++=pattern[patPos++];
@@ -803,10 +816,6 @@
                                UErrorCode* status){
 
 
-    char keywordValue[ULOC_FULLNAME_CAPACITY*4];
-    int32_t capacity = ULOC_FULLNAME_CAPACITY*4;
-    int32_t keywordValueLen =0;
-
     /* argument checking */
     if(status==NULL || U_FAILURE(*status)) {
         return 0;
@@ -818,8 +827,11 @@
     }
 
     /* get the keyword value */
-    keywordValue[0]=0;
-    keywordValueLen = uloc_getKeywordValue(locale, keyword, keywordValue, capacity, status);
+    CharString keywordValue;
+    {
+        CharStringByteSink sink(&keywordValue);
+        ulocimp_getKeywordValue(locale, keyword, sink, status);
+    }
 
     /* 
      * if the keyword is equal to currency .. then to get the display name 
@@ -829,18 +841,16 @@
 
         int32_t dispNameLen = 0;
         const UChar *dispName = NULL;
-        
-        UResourceBundle *bundle     = ures_open(U_ICUDATA_CURR, displayLocale, status);
-        UResourceBundle *currencies = ures_getByKey(bundle, _kCurrencies, NULL, status);
-        UResourceBundle *currency   = ures_getByKeyWithFallback(currencies, keywordValue, NULL, status);
-        
-        dispName = ures_getStringByIndex(currency, UCURRENCY_DISPLAY_NAME_INDEX, &dispNameLen, status);
-        
-        /*close the bundles */
-        ures_close(currency);
-        ures_close(currencies);
-        ures_close(bundle);
-        
+
+        icu::LocalUResourceBundlePointer bundle(
+                ures_open(U_ICUDATA_CURR, displayLocale, status));
+        icu::LocalUResourceBundlePointer currencies(
+                ures_getByKey(bundle.getAlias(), _kCurrencies, NULL, status));
+        icu::LocalUResourceBundlePointer currency(
+                ures_getByKeyWithFallback(currencies.getAlias(), keywordValue.data(), NULL, status));
+
+        dispName = ures_getStringByIndex(currency.getAlias(), UCURRENCY_DISPLAY_NAME_INDEX, &dispNameLen, status);
+
         if(U_FAILURE(*status)){
             if(*status == U_MISSING_RESOURCE_ERROR){
                 /* we just want to write the value over if nothing is available */
@@ -853,7 +863,7 @@
         /* now copy the dispName over if not NULL */
         if(dispName != NULL){
             if(dispNameLen <= destCapacity){
-                uprv_memcpy(dest, dispName, dispNameLen * U_SIZEOF_UCHAR);
+                u_memcpy(dest, dispName, dispNameLen);
                 return u_terminateUChars(dest, destCapacity, dispNameLen, status);
             }else{
                 *status = U_BUFFER_OVERFLOW_ERROR;
@@ -861,12 +871,12 @@
             }
         }else{
             /* we have not found the display name for the value .. just copy over */
-            if(keywordValueLen <= destCapacity){
-                u_charsToUChars(keywordValue, dest, keywordValueLen);
-                return u_terminateUChars(dest, destCapacity, keywordValueLen, status);
+            if(keywordValue.length() <= destCapacity){
+                u_charsToUChars(keywordValue.data(), dest, keywordValue.length());
+                return u_terminateUChars(dest, destCapacity, keywordValue.length(), status);
             }else{
                  *status = U_BUFFER_OVERFLOW_ERROR;
-                return keywordValueLen;
+                return keywordValue.length();
             }
         }
 
@@ -875,8 +885,8 @@
 
         return _getStringOrCopyKey(U_ICUDATA_LANG, displayLocale,
                                    _kTypes, keyword, 
-                                   keywordValue,
-                                   keywordValue,
+                                   keywordValue.data(),
+                                   keywordValue.data(),
                                    dest, destCapacity,
                                    status);
     }
diff --git a/src/third_party/icu/source/common/locdistance.cpp b/src/third_party/icu/source/common/locdistance.cpp
new file mode 100644
index 0000000..ff88927
--- /dev/null
+++ b/src/third_party/icu/source/common/locdistance.cpp
@@ -0,0 +1,415 @@
+// © 2019 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+// locdistance.cpp
+// created: 2019may08 Markus W. Scherer
+
+#include "unicode/utypes.h"
+#include "unicode/bytestrie.h"
+#include "unicode/localematcher.h"
+#include "unicode/locid.h"
+#include "unicode/uobject.h"
+#include "unicode/ures.h"
+#include "cstring.h"
+#include "locdistance.h"
+#include "loclikelysubtags.h"
+#include "uassert.h"
+#include "ucln_cmn.h"
+#include "uinvchar.h"
+#include "umutex.h"
+
+U_NAMESPACE_BEGIN
+
+namespace {
+
+/**
+ * Bit flag used on the last character of a subtag in the trie.
+ * Must be set consistently by the builder and the lookup code.
+ */
+constexpr int32_t END_OF_SUBTAG = 0x80;
+/** Distance value bit flag, set by the builder. */
+constexpr int32_t DISTANCE_SKIP_SCRIPT = 0x80;
+/** Distance value bit flag, set by trieNext(). */
+constexpr int32_t DISTANCE_IS_FINAL = 0x100;
+constexpr int32_t DISTANCE_IS_FINAL_OR_SKIP_SCRIPT = DISTANCE_IS_FINAL | DISTANCE_SKIP_SCRIPT;
+
+constexpr int32_t ABOVE_THRESHOLD = 100;
+
+// Indexes into array of distances.
+enum {
+    IX_DEF_LANG_DISTANCE,
+    IX_DEF_SCRIPT_DISTANCE,
+    IX_DEF_REGION_DISTANCE,
+    IX_MIN_REGION_DISTANCE,
+    IX_LIMIT
+};
+
+LocaleDistance *gLocaleDistance = nullptr;
+UInitOnce gInitOnce = U_INITONCE_INITIALIZER;
+
+UBool U_CALLCONV cleanup() {
+    delete gLocaleDistance;
+    gLocaleDistance = nullptr;
+    gInitOnce.reset();
+    return TRUE;
+}
+
+}  // namespace
+
+void U_CALLCONV LocaleDistance::initLocaleDistance(UErrorCode &errorCode) {
+    // This function is invoked only via umtx_initOnce().
+    U_ASSERT(gLocaleDistance == nullptr);
+    const XLikelySubtags &likely = *XLikelySubtags::getSingleton(errorCode);
+    if (U_FAILURE(errorCode)) { return; }
+    const LocaleDistanceData &data = likely.getDistanceData();
+    if (data.distanceTrieBytes == nullptr ||
+            data.regionToPartitions == nullptr || data.partitions == nullptr ||
+            // ok if no paradigms
+            data.distances == nullptr) {
+        errorCode = U_MISSING_RESOURCE_ERROR;
+        return;
+    }
+    gLocaleDistance = new LocaleDistance(data, likely);
+    if (gLocaleDistance == nullptr) {
+        errorCode = U_MEMORY_ALLOCATION_ERROR;
+        return;
+    }
+    ucln_common_registerCleanup(UCLN_COMMON_LOCALE_DISTANCE, cleanup);
+}
+
+const LocaleDistance *LocaleDistance::getSingleton(UErrorCode &errorCode) {
+    if (U_FAILURE(errorCode)) { return nullptr; }
+    umtx_initOnce(gInitOnce, &LocaleDistance::initLocaleDistance, errorCode);
+    return gLocaleDistance;
+}
+
+LocaleDistance::LocaleDistance(const LocaleDistanceData &data, const XLikelySubtags &likely) :
+        likelySubtags(likely),
+        trie(data.distanceTrieBytes),
+        regionToPartitionsIndex(data.regionToPartitions), partitionArrays(data.partitions),
+        paradigmLSRs(data.paradigms), paradigmLSRsLength(data.paradigmsLength),
+        defaultLanguageDistance(data.distances[IX_DEF_LANG_DISTANCE]),
+        defaultScriptDistance(data.distances[IX_DEF_SCRIPT_DISTANCE]),
+        defaultRegionDistance(data.distances[IX_DEF_REGION_DISTANCE]),
+        minRegionDistance(data.distances[IX_MIN_REGION_DISTANCE]) {
+    // For the default demotion value, use the
+    // default region distance between unrelated Englishes.
+    // Thus, unless demotion is turned off,
+    // a mere region difference for one desired locale
+    // is as good as a perfect match for the next following desired locale.
+    // As of CLDR 36, we have <languageMatch desired="en_*_*" supported="en_*_*" distance="5"/>.
+    LSR en("en", "Latn", "US", LSR::EXPLICIT_LSR);
+    LSR enGB("en", "Latn", "GB", LSR::EXPLICIT_LSR);
+    const LSR *p_enGB = &enGB;
+    int32_t indexAndDistance = getBestIndexAndDistance(en, &p_enGB, 1,
+            shiftDistance(50), ULOCMATCH_FAVOR_LANGUAGE, ULOCMATCH_DIRECTION_WITH_ONE_WAY);
+    defaultDemotionPerDesiredLocale  = getDistanceFloor(indexAndDistance);
+}
+
+int32_t LocaleDistance::getBestIndexAndDistance(
+        const LSR &desired,
+        const LSR **supportedLSRs, int32_t supportedLSRsLength,
+        int32_t shiftedThreshold,
+        ULocMatchFavorSubtag favorSubtag, ULocMatchDirection direction) const {
+    BytesTrie iter(trie);
+    // Look up the desired language only once for all supported LSRs.
+    // Its "distance" is either a match point value of 0, or a non-match negative value.
+    // Note: The data builder verifies that there are no <*, supported> or <desired, *> rules.
+    int32_t desLangDistance = trieNext(iter, desired.language, false);
+    uint64_t desLangState = desLangDistance >= 0 && supportedLSRsLength > 1 ? iter.getState64() : 0;
+    // Index of the supported LSR with the lowest distance.
+    int32_t bestIndex = -1;
+    // Cached lookup info from XLikelySubtags.compareLikely().
+    int32_t bestLikelyInfo = -1;
+    for (int32_t slIndex = 0; slIndex < supportedLSRsLength; ++slIndex) {
+        const LSR &supported = *supportedLSRs[slIndex];
+        bool star = false;
+        int32_t distance = desLangDistance;
+        if (distance >= 0) {
+            U_ASSERT((distance & DISTANCE_IS_FINAL) == 0);
+            if (slIndex != 0) {
+                iter.resetToState64(desLangState);
+            }
+            distance = trieNext(iter, supported.language, true);
+        }
+        // Note: The data builder verifies that there are no rules with "any" (*) language and
+        // real (non *) script or region subtags.
+        // This means that if the lookup for either language fails we can use
+        // the default distances without further lookups.
+        int32_t flags;
+        if (distance >= 0) {
+            flags = distance & DISTANCE_IS_FINAL_OR_SKIP_SCRIPT;
+            distance &= ~DISTANCE_IS_FINAL_OR_SKIP_SCRIPT;
+        } else {  // <*, *>
+            if (uprv_strcmp(desired.language, supported.language) == 0) {
+                distance = 0;
+            } else {
+                distance = defaultLanguageDistance;
+            }
+            flags = 0;
+            star = true;
+        }
+        U_ASSERT(0 <= distance && distance <= 100);
+        // Round up the shifted threshold (if fraction bits are not 0)
+        // for comparison with un-shifted distances until we need fraction bits.
+        // (If we simply shifted non-zero fraction bits away, then we might ignore a language
+        // when it's really still a micro distance below the threshold.)
+        int32_t roundedThreshold = (shiftedThreshold + DISTANCE_FRACTION_MASK) >> DISTANCE_SHIFT;
+        // We implement "favor subtag" by reducing the language subtag distance
+        // (unscientifically reducing it to a quarter of the normal value),
+        // so that the script distance is relatively more important.
+        // For example, given a default language distance of 80, we reduce it to 20,
+        // which is below the default threshold of 50, which is the default script distance.
+        if (favorSubtag == ULOCMATCH_FAVOR_SCRIPT) {
+            distance >>= 2;
+        }
+        // Let distance == roundedThreshold pass until the tie-breaker logic
+        // at the end of the loop.
+        if (distance > roundedThreshold) {
+            continue;
+        }
+
+        int32_t scriptDistance;
+        if (star || flags != 0) {
+            if (uprv_strcmp(desired.script, supported.script) == 0) {
+                scriptDistance = 0;
+            } else {
+                scriptDistance = defaultScriptDistance;
+            }
+        } else {
+            scriptDistance = getDesSuppScriptDistance(iter, iter.getState64(),
+                    desired.script, supported.script);
+            flags = scriptDistance & DISTANCE_IS_FINAL;
+            scriptDistance &= ~DISTANCE_IS_FINAL;
+        }
+        distance += scriptDistance;
+        if (distance > roundedThreshold) {
+            continue;
+        }
+
+        if (uprv_strcmp(desired.region, supported.region) == 0) {
+            // regionDistance = 0
+        } else if (star || (flags & DISTANCE_IS_FINAL) != 0) {
+            distance += defaultRegionDistance;
+        } else {
+            int32_t remainingThreshold = roundedThreshold - distance;
+            if (minRegionDistance > remainingThreshold) {
+                continue;
+            }
+
+            // From here on we know the regions are not equal.
+            // Map each region to zero or more partitions. (zero = one non-matching string)
+            // (Each array of single-character partition strings is encoded as one string.)
+            // If either side has more than one, then we find the maximum distance.
+            // This could be optimized by adding some more structure, but probably not worth it.
+            distance += getRegionPartitionsDistance(
+                    iter, iter.getState64(),
+                    partitionsForRegion(desired),
+                    partitionsForRegion(supported),
+                    remainingThreshold);
+        }
+        int32_t shiftedDistance = shiftDistance(distance);
+        if (shiftedDistance == 0) {
+            // Distinguish between equivalent but originally unequal locales via an
+            // additional micro distance.
+            shiftedDistance |= (desired.flags ^ supported.flags);
+            if (shiftedDistance < shiftedThreshold) {
+                if (direction != ULOCMATCH_DIRECTION_ONLY_TWO_WAY ||
+                        // Is there also a match when we swap desired/supported?
+                        isMatch(supported, desired, shiftedThreshold, favorSubtag)) {
+                    if (shiftedDistance == 0) {
+                        return slIndex << INDEX_SHIFT;
+                    }
+                    bestIndex = slIndex;
+                    shiftedThreshold = shiftedDistance;
+                    bestLikelyInfo = -1;
+                }
+            }
+        } else {
+            if (shiftedDistance < shiftedThreshold) {
+                if (direction != ULOCMATCH_DIRECTION_ONLY_TWO_WAY ||
+                        // Is there also a match when we swap desired/supported?
+                        isMatch(supported, desired, shiftedThreshold, favorSubtag)) {
+                    bestIndex = slIndex;
+                    shiftedThreshold = shiftedDistance;
+                    bestLikelyInfo = -1;
+                }
+            } else if (shiftedDistance == shiftedThreshold && bestIndex >= 0) {
+                if (direction != ULOCMATCH_DIRECTION_ONLY_TWO_WAY ||
+                        // Is there also a match when we swap desired/supported?
+                        isMatch(supported, desired, shiftedThreshold, favorSubtag)) {
+                    bestLikelyInfo = likelySubtags.compareLikely(
+                            supported, *supportedLSRs[bestIndex], bestLikelyInfo);
+                    if ((bestLikelyInfo & 1) != 0) {
+                        // This supported locale matches as well as the previous best match,
+                        // and neither matches perfectly,
+                        // but this one is "more likely" (has more-default subtags).
+                        bestIndex = slIndex;
+                    }
+                }
+            }
+        }
+    }
+    return bestIndex >= 0 ?
+            (bestIndex << INDEX_SHIFT) | shiftedThreshold :
+            INDEX_NEG_1 | shiftDistance(ABOVE_THRESHOLD);
+}
+
+int32_t LocaleDistance::getDesSuppScriptDistance(
+        BytesTrie &iter, uint64_t startState, const char *desired, const char *supported) {
+    // Note: The data builder verifies that there are no <*, supported> or <desired, *> rules.
+    int32_t distance = trieNext(iter, desired, false);
+    if (distance >= 0) {
+        distance = trieNext(iter, supported, true);
+    }
+    if (distance < 0) {
+        UStringTrieResult result = iter.resetToState64(startState).next(u'*');  // <*, *>
+        U_ASSERT(USTRINGTRIE_HAS_VALUE(result));
+        if (uprv_strcmp(desired, supported) == 0) {
+            distance = 0;  // same script
+        } else {
+            distance = iter.getValue();
+            U_ASSERT(distance >= 0);
+        }
+        if (result == USTRINGTRIE_FINAL_VALUE) {
+            distance |= DISTANCE_IS_FINAL;
+        }
+    }
+    return distance;
+}
+
+int32_t LocaleDistance::getRegionPartitionsDistance(
+        BytesTrie &iter, uint64_t startState,
+        const char *desiredPartitions, const char *supportedPartitions, int32_t threshold) {
+    char desired = *desiredPartitions++;
+    char supported = *supportedPartitions++;
+    U_ASSERT(desired != 0 && supported != 0);
+    // See if we have single desired/supported partitions, from NUL-terminated
+    // partition strings without explicit length.
+    bool suppLengthGt1 = *supportedPartitions != 0;  // gt1: more than 1 character
+    // equivalent to: if (desLength == 1 && suppLength == 1)
+    if (*desiredPartitions == 0 && !suppLengthGt1) {
+        // Fastpath for single desired/supported partitions.
+        UStringTrieResult result = iter.next(uprv_invCharToAscii(desired) | END_OF_SUBTAG);
+        if (USTRINGTRIE_HAS_NEXT(result)) {
+            result = iter.next(uprv_invCharToAscii(supported) | END_OF_SUBTAG);
+            if (USTRINGTRIE_HAS_VALUE(result)) {
+                return iter.getValue();
+            }
+        }
+        return getFallbackRegionDistance(iter, startState);
+    }
+
+    const char *supportedStart = supportedPartitions - 1;  // for restart of inner loop
+    int32_t regionDistance = 0;
+    // Fall back to * only once, not for each pair of partition strings.
+    bool star = false;
+    for (;;) {
+        // Look up each desired-partition string only once,
+        // not for each (desired, supported) pair.
+        UStringTrieResult result = iter.next(uprv_invCharToAscii(desired) | END_OF_SUBTAG);
+        if (USTRINGTRIE_HAS_NEXT(result)) {
+            uint64_t desState = suppLengthGt1 ? iter.getState64() : 0;
+            for (;;) {
+                result = iter.next(uprv_invCharToAscii(supported) | END_OF_SUBTAG);
+                int32_t d;
+                if (USTRINGTRIE_HAS_VALUE(result)) {
+                    d = iter.getValue();
+                } else if (star) {
+                    d = 0;
+                } else {
+                    d = getFallbackRegionDistance(iter, startState);
+                    star = true;
+                }
+                if (d > threshold) {
+                    return d;
+                } else if (regionDistance < d) {
+                    regionDistance = d;
+                }
+                if ((supported = *supportedPartitions++) != 0) {
+                    iter.resetToState64(desState);
+                } else {
+                    break;
+                }
+            }
+        } else if (!star) {
+            int32_t d = getFallbackRegionDistance(iter, startState);
+            if (d > threshold) {
+                return d;
+            } else if (regionDistance < d) {
+                regionDistance = d;
+            }
+            star = true;
+        }
+        if ((desired = *desiredPartitions++) != 0) {
+            iter.resetToState64(startState);
+            supportedPartitions = supportedStart;
+            supported = *supportedPartitions++;
+        } else {
+            break;
+        }
+    }
+    return regionDistance;
+}
+
+int32_t LocaleDistance::getFallbackRegionDistance(BytesTrie &iter, uint64_t startState) {
+#if U_DEBUG
+    UStringTrieResult result =
+#endif
+    iter.resetToState64(startState).next(u'*');  // <*, *>
+    U_ASSERT(USTRINGTRIE_HAS_VALUE(result));
+    int32_t distance = iter.getValue();
+    U_ASSERT(distance >= 0);
+    return distance;
+}
+
+int32_t LocaleDistance::trieNext(BytesTrie &iter, const char *s, bool wantValue) {
+    uint8_t c;
+    if ((c = *s) == 0) {
+        return -1;  // no empty subtags in the distance data
+    }
+    for (;;) {
+        c = uprv_invCharToAscii(c);
+        // EBCDIC: If *s is not an invariant character,
+        // then c is now 0 and will simply not match anything, which is harmless.
+        uint8_t next = *++s;
+        if (next != 0) {
+            if (!USTRINGTRIE_HAS_NEXT(iter.next(c))) {
+                return -1;
+            }
+        } else {
+            // last character of this subtag
+            UStringTrieResult result = iter.next(c | END_OF_SUBTAG);
+            if (wantValue) {
+                if (USTRINGTRIE_HAS_VALUE(result)) {
+                    int32_t value = iter.getValue();
+                    if (result == USTRINGTRIE_FINAL_VALUE) {
+                        value |= DISTANCE_IS_FINAL;
+                    }
+                    return value;
+                }
+            } else {
+                if (USTRINGTRIE_HAS_NEXT(result)) {
+                    return 0;
+                }
+            }
+            return -1;
+        }
+        c = next;
+    }
+}
+
+UBool LocaleDistance::isParadigmLSR(const LSR &lsr) const {
+    // Linear search for a very short list (length 6 as of 2019),
+    // because we look for equivalence not equality, and
+    // because it's easy.
+    // If there are many paradigm LSRs we should use a hash set
+    // with custom comparator and hasher.
+    U_ASSERT(paradigmLSRsLength <= 15);
+    for (int32_t i = 0; i < paradigmLSRsLength; ++i) {
+        if (lsr.isEquivalentTo(paradigmLSRs[i])) { return true; }
+    }
+    return false;
+}
+
+U_NAMESPACE_END
diff --git a/src/third_party/icu/source/common/locdistance.h b/src/third_party/icu/source/common/locdistance.h
new file mode 100644
index 0000000..51b777e
--- /dev/null
+++ b/src/third_party/icu/source/common/locdistance.h
@@ -0,0 +1,151 @@
+// © 2019 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+// locdistance.h
+// created: 2019may08 Markus W. Scherer
+
+#ifndef __LOCDISTANCE_H__
+#define __LOCDISTANCE_H__
+
+#include "unicode/utypes.h"
+#include "unicode/bytestrie.h"
+#include "unicode/localematcher.h"
+#include "unicode/locid.h"
+#include "unicode/uobject.h"
+#include "lsr.h"
+
+U_NAMESPACE_BEGIN
+
+struct LocaleDistanceData;
+
+/**
+ * Offline-built data for LocaleMatcher.
+ * Mostly but not only the data for mapping locales to their maximized forms.
+ */
+class LocaleDistance final : public UMemory {
+public:
+    static const LocaleDistance *getSingleton(UErrorCode &errorCode);
+
+    static int32_t shiftDistance(int32_t distance) {
+        return distance << DISTANCE_SHIFT;
+    }
+
+    static int32_t getShiftedDistance(int32_t indexAndDistance) {
+        return indexAndDistance & DISTANCE_MASK;
+    }
+
+    static double getDistanceDouble(int32_t indexAndDistance) {
+        double shiftedDistance = getShiftedDistance(indexAndDistance);
+        return shiftedDistance / (1 << DISTANCE_SHIFT);
+    }
+
+    static int32_t getDistanceFloor(int32_t indexAndDistance) {
+        return (indexAndDistance & DISTANCE_MASK) >> DISTANCE_SHIFT;
+    }
+
+    static int32_t getIndex(int32_t indexAndDistance) {
+        // assert indexAndDistance >= 0;
+        return indexAndDistance >> INDEX_SHIFT;
+    }
+
+    /**
+     * Finds the supported LSR with the smallest distance from the desired one.
+     * Equivalent LSR subtags must be normalized into a canonical form.
+     *
+     * <p>Returns the index of the lowest-distance supported LSR in the high bits
+     * (negative if none has a distance below the threshold),
+     * and its distance (0..ABOVE_THRESHOLD) in the low bits.
+     */
+    int32_t getBestIndexAndDistance(const LSR &desired,
+                                    const LSR **supportedLSRs, int32_t supportedLSRsLength,
+                                    int32_t shiftedThreshold,
+                                    ULocMatchFavorSubtag favorSubtag,
+                                    ULocMatchDirection direction) const;
+
+    UBool isParadigmLSR(const LSR &lsr) const;
+
+    int32_t getDefaultScriptDistance() const {
+        return defaultScriptDistance;
+    }
+
+    int32_t getDefaultDemotionPerDesiredLocale() const {
+        return defaultDemotionPerDesiredLocale;
+    }
+
+private:
+    // The distance is shifted left to gain some fraction bits.
+    static constexpr int32_t DISTANCE_SHIFT = 3;
+    static constexpr int32_t DISTANCE_FRACTION_MASK = 7;
+    // 7 bits for 0..100
+    static constexpr int32_t DISTANCE_INT_SHIFT = 7;
+    static constexpr int32_t INDEX_SHIFT = DISTANCE_INT_SHIFT + DISTANCE_SHIFT;
+    static constexpr int32_t DISTANCE_MASK = 0x3ff;
+    // tic constexpr int32_t MAX_INDEX = 0x1fffff;  // avoids sign bit
+    static constexpr int32_t INDEX_NEG_1 = 0xfffffc00;
+
+    LocaleDistance(const LocaleDistanceData &data, const XLikelySubtags &likely);
+    LocaleDistance(const LocaleDistance &other) = delete;
+    LocaleDistance &operator=(const LocaleDistance &other) = delete;
+
+    static void initLocaleDistance(UErrorCode &errorCode);
+
+    UBool isMatch(const LSR &desired, const LSR &supported,
+                  int32_t shiftedThreshold, ULocMatchFavorSubtag favorSubtag) const {
+        const LSR *pSupp = &supported;
+        return getBestIndexAndDistance(
+            desired, &pSupp, 1,
+            shiftedThreshold, favorSubtag, ULOCMATCH_DIRECTION_WITH_ONE_WAY) >= 0;
+    }
+
+    static int32_t getDesSuppScriptDistance(BytesTrie &iter, uint64_t startState,
+                                            const char *desired, const char *supported);
+
+    static int32_t getRegionPartitionsDistance(
+        BytesTrie &iter, uint64_t startState,
+        const char *desiredPartitions, const char *supportedPartitions,
+        int32_t threshold);
+
+    static int32_t getFallbackRegionDistance(BytesTrie &iter, uint64_t startState);
+
+    static int32_t trieNext(BytesTrie &iter, const char *s, bool wantValue);
+
+    const char *partitionsForRegion(const LSR &lsr) const {
+        // ill-formed region -> one non-matching string
+        int32_t pIndex = regionToPartitionsIndex[lsr.regionIndex];
+        return partitionArrays[pIndex];
+    }
+
+    int32_t getDefaultRegionDistance() const {
+        return defaultRegionDistance;
+    }
+
+    const XLikelySubtags &likelySubtags;
+
+    // The trie maps each dlang+slang+dscript+sscript+dregion+sregion
+    // (encoded in ASCII with bit 7 set on the last character of each subtag) to a distance.
+    // There is also a trie value for each subsequence of whole subtags.
+    // One '*' is used for a (desired, supported) pair of "und", "Zzzz"/"", or "ZZ"/"".
+    BytesTrie trie;
+
+    /**
+     * Maps each region to zero or more single-character partitions.
+     */
+    const uint8_t *regionToPartitionsIndex;
+    const char **partitionArrays;
+
+    /**
+     * Used to get the paradigm region for a cluster, if there is one.
+     */
+    const LSR *paradigmLSRs;
+    int32_t paradigmLSRsLength;
+
+    int32_t defaultLanguageDistance;
+    int32_t defaultScriptDistance;
+    int32_t defaultRegionDistance;
+    int32_t minRegionDistance;
+    int32_t defaultDemotionPerDesiredLocale;
+};
+
+U_NAMESPACE_END
+
+#endif  // __LOCDISTANCE_H__
diff --git a/src/third_party/icu/source/common/locdspnm.cpp b/src/third_party/icu/source/common/locdspnm.cpp
new file mode 100644
index 0000000..43334f5
--- /dev/null
+++ b/src/third_party/icu/source/common/locdspnm.cpp
@@ -0,0 +1,1110 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+/*
+*******************************************************************************
+* Copyright (C) 2010-2016, International Business Machines Corporation and
+* others. All Rights Reserved.
+*******************************************************************************
+*/
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_FORMATTING
+
+#include "unicode/locdspnm.h"
+#include "unicode/simpleformatter.h"
+#include "unicode/ucasemap.h"
+#include "unicode/ures.h"
+#include "unicode/udisplaycontext.h"
+#include "unicode/brkiter.h"
+#include "unicode/ucurr.h"
+#include "cmemory.h"
+#include "cstring.h"
+#include "mutex.h"
+#include "ulocimp.h"
+#include "umutex.h"
+#include "ureslocs.h"
+#include "uresimp.h"
+
+#include <stdarg.h>
+
+/**
+ * Concatenate a number of null-terminated strings to buffer, leaving a
+ * null-terminated string.  The last argument should be the null pointer.
+ * Return the length of the string in the buffer, not counting the trailing
+ * null.  Return -1 if there is an error (buffer is null, or buflen < 1).
+ */
+static int32_t ncat(char *buffer, uint32_t buflen, ...) {
+  va_list args;
+  char *str;
+  char *p = buffer;
+  const char* e = buffer + buflen - 1;
+
+  if (buffer == NULL || buflen < 1) {
+    return -1;
+  }
+
+  va_start(args, buflen);
+  while ((str = va_arg(args, char *)) != 0) {
+    char c;
+    while (p != e && (c = *str++) != 0) {
+      *p++ = c;
+    }
+  }
+  *p = 0;
+  va_end(args);
+
+  return static_cast<int32_t>(p - buffer);
+}
+
+U_NAMESPACE_BEGIN
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+// Access resource data for locale components.
+// Wrap code in uloc.c for now.
+class ICUDataTable {
+    const char* path;
+    Locale locale;
+
+public:
+    ICUDataTable(const char* path, const Locale& locale);
+    ~ICUDataTable();
+
+    const Locale& getLocale();
+
+    UnicodeString& get(const char* tableKey, const char* itemKey,
+                        UnicodeString& result) const;
+    UnicodeString& get(const char* tableKey, const char* subTableKey, const char* itemKey,
+                        UnicodeString& result) const;
+
+    UnicodeString& getNoFallback(const char* tableKey, const char* itemKey,
+                                UnicodeString &result) const;
+    UnicodeString& getNoFallback(const char* tableKey, const char* subTableKey, const char* itemKey,
+                                UnicodeString &result) const;
+};
+
+inline UnicodeString &
+ICUDataTable::get(const char* tableKey, const char* itemKey, UnicodeString& result) const {
+    return get(tableKey, NULL, itemKey, result);
+}
+
+inline UnicodeString &
+ICUDataTable::getNoFallback(const char* tableKey, const char* itemKey, UnicodeString& result) const {
+    return getNoFallback(tableKey, NULL, itemKey, result);
+}
+
+ICUDataTable::ICUDataTable(const char* path, const Locale& locale)
+    : path(NULL), locale(Locale::getRoot())
+{
+  if (path) {
+    int32_t len = static_cast<int32_t>(uprv_strlen(path));
+    this->path = (const char*) uprv_malloc(len + 1);
+    if (this->path) {
+      uprv_strcpy((char *)this->path, path);
+      this->locale = locale;
+    }
+  }
+}
+
+ICUDataTable::~ICUDataTable() {
+  if (path) {
+    uprv_free((void*) path);
+    path = NULL;
+  }
+}
+
+const Locale&
+ICUDataTable::getLocale() {
+  return locale;
+}
+
+UnicodeString &
+ICUDataTable::get(const char* tableKey, const char* subTableKey, const char* itemKey,
+                  UnicodeString &result) const {
+  UErrorCode status = U_ZERO_ERROR;
+  int32_t len = 0;
+
+  const UChar *s = uloc_getTableStringWithFallback(path, locale.getName(),
+                                                   tableKey, subTableKey, itemKey,
+                                                   &len, &status);
+  if (U_SUCCESS(status) && len > 0) {
+    return result.setTo(s, len);
+  }
+  return result.setTo(UnicodeString(itemKey, -1, US_INV));
+}
+
+UnicodeString &
+ICUDataTable::getNoFallback(const char* tableKey, const char* subTableKey, const char* itemKey,
+                            UnicodeString& result) const {
+  UErrorCode status = U_ZERO_ERROR;
+  int32_t len = 0;
+
+  const UChar *s = uloc_getTableStringWithFallback(path, locale.getName(),
+                                                   tableKey, subTableKey, itemKey,
+                                                   &len, &status);
+  if (U_SUCCESS(status)) {
+    return result.setTo(s, len);
+  }
+
+  result.setToBogus();
+  return result;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+LocaleDisplayNames::~LocaleDisplayNames() {}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#if 0  // currently unused
+
+class DefaultLocaleDisplayNames : public LocaleDisplayNames {
+  UDialectHandling dialectHandling;
+
+public:
+  // constructor
+  DefaultLocaleDisplayNames(UDialectHandling dialectHandling);
+
+  virtual ~DefaultLocaleDisplayNames();
+
+  virtual const Locale& getLocale() const;
+  virtual UDialectHandling getDialectHandling() const;
+
+  virtual UnicodeString& localeDisplayName(const Locale& locale,
+                                           UnicodeString& result) const;
+  virtual UnicodeString& localeDisplayName(const char* localeId,
+                                           UnicodeString& result) const;
+  virtual UnicodeString& languageDisplayName(const char* lang,
+                                             UnicodeString& result) const;
+  virtual UnicodeString& scriptDisplayName(const char* script,
+                                           UnicodeString& result) const;
+  virtual UnicodeString& scriptDisplayName(UScriptCode scriptCode,
+                                           UnicodeString& result) const;
+  virtual UnicodeString& regionDisplayName(const char* region,
+                                           UnicodeString& result) const;
+  virtual UnicodeString& variantDisplayName(const char* variant,
+                                            UnicodeString& result) const;
+  virtual UnicodeString& keyDisplayName(const char* key,
+                                        UnicodeString& result) const;
+  virtual UnicodeString& keyValueDisplayName(const char* key,
+                                             const char* value,
+                                             UnicodeString& result) const;
+};
+
+DefaultLocaleDisplayNames::DefaultLocaleDisplayNames(UDialectHandling dialectHandling)
+    : dialectHandling(dialectHandling) {
+}
+
+DefaultLocaleDisplayNames::~DefaultLocaleDisplayNames() {
+}
+
+const Locale&
+DefaultLocaleDisplayNames::getLocale() const {
+  return Locale::getRoot();
+}
+
+UDialectHandling
+DefaultLocaleDisplayNames::getDialectHandling() const {
+  return dialectHandling;
+}
+
+UnicodeString&
+DefaultLocaleDisplayNames::localeDisplayName(const Locale& locale,
+                                             UnicodeString& result) const {
+  return result = UnicodeString(locale.getName(), -1, US_INV);
+}
+
+UnicodeString&
+DefaultLocaleDisplayNames::localeDisplayName(const char* localeId,
+                                             UnicodeString& result) const {
+  return result = UnicodeString(localeId, -1, US_INV);
+}
+
+UnicodeString&
+DefaultLocaleDisplayNames::languageDisplayName(const char* lang,
+                                               UnicodeString& result) const {
+  return result = UnicodeString(lang, -1, US_INV);
+}
+
+UnicodeString&
+DefaultLocaleDisplayNames::scriptDisplayName(const char* script,
+                                             UnicodeString& result) const {
+  return result = UnicodeString(script, -1, US_INV);
+}
+
+UnicodeString&
+DefaultLocaleDisplayNames::scriptDisplayName(UScriptCode scriptCode,
+                                             UnicodeString& result) const {
+  const char* name = uscript_getName(scriptCode);
+  if (name) {
+    return result = UnicodeString(name, -1, US_INV);
+  }
+  return result.remove();
+}
+
+UnicodeString&
+DefaultLocaleDisplayNames::regionDisplayName(const char* region,
+                                             UnicodeString& result) const {
+  return result = UnicodeString(region, -1, US_INV);
+}
+
+UnicodeString&
+DefaultLocaleDisplayNames::variantDisplayName(const char* variant,
+                                              UnicodeString& result) const {
+  return result = UnicodeString(variant, -1, US_INV);
+}
+
+UnicodeString&
+DefaultLocaleDisplayNames::keyDisplayName(const char* key,
+                                          UnicodeString& result) const {
+  return result = UnicodeString(key, -1, US_INV);
+}
+
+UnicodeString&
+DefaultLocaleDisplayNames::keyValueDisplayName(const char* /* key */,
+                                               const char* value,
+                                               UnicodeString& result) const {
+  return result = UnicodeString(value, -1, US_INV);
+}
+
+#endif  // currently unused class DefaultLocaleDisplayNames
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+class LocaleDisplayNamesImpl : public LocaleDisplayNames {
+    Locale locale;
+    UDialectHandling dialectHandling;
+    ICUDataTable langData;
+    ICUDataTable regionData;
+    SimpleFormatter separatorFormat;
+    SimpleFormatter format;
+    SimpleFormatter keyTypeFormat;
+    UDisplayContext capitalizationContext;
+#if !UCONFIG_NO_BREAK_ITERATION
+    BreakIterator* capitalizationBrkIter;
+#else
+    UObject* capitalizationBrkIter;
+#endif
+    UnicodeString formatOpenParen;
+    UnicodeString formatReplaceOpenParen;
+    UnicodeString formatCloseParen;
+    UnicodeString formatReplaceCloseParen;
+    UDisplayContext nameLength;
+    UDisplayContext substitute;
+
+    // Constants for capitalization context usage types.
+    enum CapContextUsage {
+        kCapContextUsageLanguage,
+        kCapContextUsageScript,
+        kCapContextUsageTerritory,
+        kCapContextUsageVariant,
+        kCapContextUsageKey,
+        kCapContextUsageKeyValue,
+        kCapContextUsageCount
+    };
+    // Capitalization transforms. For each usage type, indicates whether to titlecase for
+    // the context specified in capitalizationContext (which we know at construction time)
+     UBool fCapitalization[kCapContextUsageCount];
+
+public:
+    // constructor
+    LocaleDisplayNamesImpl(const Locale& locale, UDialectHandling dialectHandling);
+    LocaleDisplayNamesImpl(const Locale& locale, UDisplayContext *contexts, int32_t length);
+    virtual ~LocaleDisplayNamesImpl();
+
+    virtual const Locale& getLocale() const;
+    virtual UDialectHandling getDialectHandling() const;
+    virtual UDisplayContext getContext(UDisplayContextType type) const;
+
+    virtual UnicodeString& localeDisplayName(const Locale& locale,
+                                                UnicodeString& result) const;
+    virtual UnicodeString& localeDisplayName(const char* localeId,
+                                                UnicodeString& result) const;
+    virtual UnicodeString& languageDisplayName(const char* lang,
+                                               UnicodeString& result) const;
+    virtual UnicodeString& scriptDisplayName(const char* script,
+                                                UnicodeString& result) const;
+    virtual UnicodeString& scriptDisplayName(UScriptCode scriptCode,
+                                                UnicodeString& result) const;
+    virtual UnicodeString& regionDisplayName(const char* region,
+                                                UnicodeString& result) const;
+    virtual UnicodeString& variantDisplayName(const char* variant,
+                                                UnicodeString& result) const;
+    virtual UnicodeString& keyDisplayName(const char* key,
+                                                UnicodeString& result) const;
+    virtual UnicodeString& keyValueDisplayName(const char* key,
+                                                const char* value,
+                                                UnicodeString& result) const;
+private:
+    UnicodeString& localeIdName(const char* localeId,
+                                UnicodeString& result, bool substitute) const;
+    UnicodeString& appendWithSep(UnicodeString& buffer, const UnicodeString& src) const;
+    UnicodeString& adjustForUsageAndContext(CapContextUsage usage, UnicodeString& result) const;
+    UnicodeString& scriptDisplayName(const char* script, UnicodeString& result, UBool skipAdjust) const;
+    UnicodeString& regionDisplayName(const char* region, UnicodeString& result, UBool skipAdjust) const;
+    UnicodeString& variantDisplayName(const char* variant, UnicodeString& result, UBool skipAdjust) const;
+    UnicodeString& keyDisplayName(const char* key, UnicodeString& result, UBool skipAdjust) const;
+    UnicodeString& keyValueDisplayName(const char* key, const char* value,
+                                        UnicodeString& result, UBool skipAdjust) const;
+    void initialize(void);
+
+    struct CapitalizationContextSink;
+};
+
+LocaleDisplayNamesImpl::LocaleDisplayNamesImpl(const Locale& locale,
+                                               UDialectHandling dialectHandling)
+    : dialectHandling(dialectHandling)
+    , langData(U_ICUDATA_LANG, locale)
+    , regionData(U_ICUDATA_REGION, locale)
+    , capitalizationContext(UDISPCTX_CAPITALIZATION_NONE)
+    , capitalizationBrkIter(NULL)
+    , nameLength(UDISPCTX_LENGTH_FULL)
+    , substitute(UDISPCTX_SUBSTITUTE)
+{
+    initialize();
+}
+
+LocaleDisplayNamesImpl::LocaleDisplayNamesImpl(const Locale& locale,
+                                               UDisplayContext *contexts, int32_t length)
+    : dialectHandling(ULDN_STANDARD_NAMES)
+    , langData(U_ICUDATA_LANG, locale)
+    , regionData(U_ICUDATA_REGION, locale)
+    , capitalizationContext(UDISPCTX_CAPITALIZATION_NONE)
+    , capitalizationBrkIter(NULL)
+    , nameLength(UDISPCTX_LENGTH_FULL)
+    , substitute(UDISPCTX_SUBSTITUTE)
+{
+    while (length-- > 0) {
+        UDisplayContext value = *contexts++;
+        UDisplayContextType selector = (UDisplayContextType)((uint32_t)value >> 8);
+        switch (selector) {
+            case UDISPCTX_TYPE_DIALECT_HANDLING:
+                dialectHandling = (UDialectHandling)value;
+                break;
+            case UDISPCTX_TYPE_CAPITALIZATION:
+                capitalizationContext = value;
+                break;
+            case UDISPCTX_TYPE_DISPLAY_LENGTH:
+                nameLength = value;
+                break;
+            case UDISPCTX_TYPE_SUBSTITUTE_HANDLING:
+                substitute = value;
+                break;
+            default:
+                break;
+        }
+    }
+    initialize();
+}
+
+struct LocaleDisplayNamesImpl::CapitalizationContextSink : public ResourceSink {
+    UBool hasCapitalizationUsage;
+    LocaleDisplayNamesImpl& parent;
+
+    CapitalizationContextSink(LocaleDisplayNamesImpl& _parent)
+      : hasCapitalizationUsage(FALSE), parent(_parent) {}
+    virtual ~CapitalizationContextSink();
+
+    virtual void put(const char *key, ResourceValue &value, UBool /*noFallback*/,
+            UErrorCode &errorCode) {
+        ResourceTable contexts = value.getTable(errorCode);
+        if (U_FAILURE(errorCode)) { return; }
+        for (int i = 0; contexts.getKeyAndValue(i, key, value); ++i) {
+
+            CapContextUsage usageEnum;
+            if (uprv_strcmp(key, "key") == 0) {
+                usageEnum = kCapContextUsageKey;
+            } else if (uprv_strcmp(key, "keyValue") == 0) {
+                usageEnum = kCapContextUsageKeyValue;
+            } else if (uprv_strcmp(key, "languages") == 0) {
+                usageEnum = kCapContextUsageLanguage;
+            } else if (uprv_strcmp(key, "script") == 0) {
+                usageEnum = kCapContextUsageScript;
+            } else if (uprv_strcmp(key, "territory") == 0) {
+                usageEnum = kCapContextUsageTerritory;
+            } else if (uprv_strcmp(key, "variant") == 0) {
+                usageEnum = kCapContextUsageVariant;
+            } else {
+                continue;
+            }
+
+            int32_t len = 0;
+            const int32_t* intVector = value.getIntVector(len, errorCode);
+            if (U_FAILURE(errorCode)) { return; }
+            if (len < 2) { continue; }
+
+            int32_t titlecaseInt = (parent.capitalizationContext == UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU) ? intVector[0] : intVector[1];
+            if (titlecaseInt == 0) { continue; }
+
+            parent.fCapitalization[usageEnum] = TRUE;
+            hasCapitalizationUsage = TRUE;
+        }
+    }
+};
+
+// Virtual destructors must be defined out of line.
+LocaleDisplayNamesImpl::CapitalizationContextSink::~CapitalizationContextSink() {}
+
+void
+LocaleDisplayNamesImpl::initialize(void) {
+    LocaleDisplayNamesImpl *nonConstThis = (LocaleDisplayNamesImpl *)this;
+    nonConstThis->locale = langData.getLocale() == Locale::getRoot()
+        ? regionData.getLocale()
+        : langData.getLocale();
+
+    UnicodeString sep;
+    langData.getNoFallback("localeDisplayPattern", "separator", sep);
+    if (sep.isBogus()) {
+        sep = UnicodeString("{0}, {1}", -1, US_INV);
+    }
+    UErrorCode status = U_ZERO_ERROR;
+    separatorFormat.applyPatternMinMaxArguments(sep, 2, 2, status);
+
+    UnicodeString pattern;
+    langData.getNoFallback("localeDisplayPattern", "pattern", pattern);
+    if (pattern.isBogus()) {
+        pattern = UnicodeString("{0} ({1})", -1, US_INV);
+    }
+    format.applyPatternMinMaxArguments(pattern, 2, 2, status);
+    if (pattern.indexOf((UChar)0xFF08) >= 0) {
+        formatOpenParen.setTo((UChar)0xFF08);         // fullwidth (
+        formatReplaceOpenParen.setTo((UChar)0xFF3B);  // fullwidth [
+        formatCloseParen.setTo((UChar)0xFF09);        // fullwidth )
+        formatReplaceCloseParen.setTo((UChar)0xFF3D); // fullwidth ]
+    } else {
+        formatOpenParen.setTo((UChar)0x0028);         // (
+        formatReplaceOpenParen.setTo((UChar)0x005B);  // [
+        formatCloseParen.setTo((UChar)0x0029);        // )
+        formatReplaceCloseParen.setTo((UChar)0x005D); // ]
+    }
+
+    UnicodeString ktPattern;
+    langData.get("localeDisplayPattern", "keyTypePattern", ktPattern);
+    if (ktPattern.isBogus()) {
+        ktPattern = UnicodeString("{0}={1}", -1, US_INV);
+    }
+    keyTypeFormat.applyPatternMinMaxArguments(ktPattern, 2, 2, status);
+
+    uprv_memset(fCapitalization, 0, sizeof(fCapitalization));
+#if !UCONFIG_NO_BREAK_ITERATION
+    // Only get the context data if we need it! This is a const object so we know now...
+    // Also check whether we will need a break iterator (depends on the data)
+    UBool needBrkIter = FALSE;
+    if (capitalizationContext == UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU || capitalizationContext == UDISPCTX_CAPITALIZATION_FOR_STANDALONE) {
+        LocalUResourceBundlePointer resource(ures_open(NULL, locale.getName(), &status));
+        if (U_FAILURE(status)) { return; }
+        CapitalizationContextSink sink(*this);
+        ures_getAllItemsWithFallback(resource.getAlias(), "contextTransforms", sink, status);
+        if (status == U_MISSING_RESOURCE_ERROR) {
+            // Silently ignore.  Not every locale has contextTransforms.
+            status = U_ZERO_ERROR;
+        } else if (U_FAILURE(status)) {
+            return;
+        }
+        needBrkIter = sink.hasCapitalizationUsage;
+    }
+    // Get a sentence break iterator if we will need it
+    if (needBrkIter || capitalizationContext == UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE) {
+        status = U_ZERO_ERROR;
+        capitalizationBrkIter = BreakIterator::createSentenceInstance(locale, status);
+        if (U_FAILURE(status)) {
+            delete capitalizationBrkIter;
+            capitalizationBrkIter = NULL;
+        }
+    }
+#endif
+}
+
+LocaleDisplayNamesImpl::~LocaleDisplayNamesImpl() {
+#if !UCONFIG_NO_BREAK_ITERATION
+    delete capitalizationBrkIter;
+#endif
+}
+
+const Locale&
+LocaleDisplayNamesImpl::getLocale() const {
+    return locale;
+}
+
+UDialectHandling
+LocaleDisplayNamesImpl::getDialectHandling() const {
+    return dialectHandling;
+}
+
+UDisplayContext
+LocaleDisplayNamesImpl::getContext(UDisplayContextType type) const {
+    switch (type) {
+        case UDISPCTX_TYPE_DIALECT_HANDLING:
+            return (UDisplayContext)dialectHandling;
+        case UDISPCTX_TYPE_CAPITALIZATION:
+            return capitalizationContext;
+        case UDISPCTX_TYPE_DISPLAY_LENGTH:
+            return nameLength;
+        case UDISPCTX_TYPE_SUBSTITUTE_HANDLING:
+            return substitute;
+        default:
+            break;
+    }
+    return (UDisplayContext)0;
+}
+
+UnicodeString&
+LocaleDisplayNamesImpl::adjustForUsageAndContext(CapContextUsage usage,
+                                                UnicodeString& result) const {
+#if !UCONFIG_NO_BREAK_ITERATION
+    // check to see whether we need to titlecase result
+    if ( result.length() > 0 && u_islower(result.char32At(0)) && capitalizationBrkIter!= NULL &&
+          ( capitalizationContext==UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE || fCapitalization[usage] ) ) {
+        // note fCapitalization[usage] won't be set unless capitalizationContext is UI_LIST_OR_MENU or STANDALONE
+        static UMutex capitalizationBrkIterLock;
+        Mutex lock(&capitalizationBrkIterLock);
+        result.toTitle(capitalizationBrkIter, locale, U_TITLECASE_NO_LOWERCASE | U_TITLECASE_NO_BREAK_ADJUSTMENT);
+    }
+#endif
+    return result;
+}
+
+UnicodeString&
+LocaleDisplayNamesImpl::localeDisplayName(const Locale& loc,
+                                          UnicodeString& result) const {
+  if (loc.isBogus()) {
+    result.setToBogus();
+    return result;
+  }
+  UnicodeString resultName;
+
+  const char* lang = loc.getLanguage();
+  if (uprv_strlen(lang) == 0) {
+    lang = "root";
+  }
+  const char* script = loc.getScript();
+  const char* country = loc.getCountry();
+  const char* variant = loc.getVariant();
+
+  UBool hasScript = uprv_strlen(script) > 0;
+  UBool hasCountry = uprv_strlen(country) > 0;
+  UBool hasVariant = uprv_strlen(variant) > 0;
+
+  if (dialectHandling == ULDN_DIALECT_NAMES) {
+    char buffer[ULOC_FULLNAME_CAPACITY];
+    do { // loop construct is so we can break early out of search
+      if (hasScript && hasCountry) {
+        ncat(buffer, ULOC_FULLNAME_CAPACITY, lang, "_", script, "_", country, (char *)0);
+        localeIdName(buffer, resultName, false);
+        if (!resultName.isBogus()) {
+          hasScript = FALSE;
+          hasCountry = FALSE;
+          break;
+        }
+      }
+      if (hasScript) {
+        ncat(buffer, ULOC_FULLNAME_CAPACITY, lang, "_", script, (char *)0);
+        localeIdName(buffer, resultName, false);
+        if (!resultName.isBogus()) {
+          hasScript = FALSE;
+          break;
+        }
+      }
+      if (hasCountry) {
+        ncat(buffer, ULOC_FULLNAME_CAPACITY, lang, "_", country, (char*)0);
+        localeIdName(buffer, resultName, false);
+        if (!resultName.isBogus()) {
+          hasCountry = FALSE;
+          break;
+        }
+      }
+    } while (FALSE);
+  }
+  if (resultName.isBogus() || resultName.isEmpty()) {
+    localeIdName(lang, resultName, substitute == UDISPCTX_SUBSTITUTE);
+    if (resultName.isBogus()) {
+      result.setToBogus();
+      return result;
+    }
+  }
+
+  UnicodeString resultRemainder;
+  UnicodeString temp;
+  UErrorCode status = U_ZERO_ERROR;
+
+  if (hasScript) {
+    UnicodeString script_str = scriptDisplayName(script, temp, TRUE);
+    if (script_str.isBogus()) {
+      result.setToBogus();
+      return result;
+    }
+    resultRemainder.append(script_str);
+  }
+  if (hasCountry) {
+    UnicodeString region_str = regionDisplayName(country, temp, TRUE);
+    if (region_str.isBogus()) {
+      result.setToBogus();
+      return result;
+    }
+    appendWithSep(resultRemainder, region_str);
+  }
+  if (hasVariant) {
+    UnicodeString variant_str = variantDisplayName(variant, temp, TRUE);
+    if (variant_str.isBogus()) {
+      result.setToBogus();
+      return result;
+    }
+    appendWithSep(resultRemainder, variant_str);
+  }
+  resultRemainder.findAndReplace(formatOpenParen, formatReplaceOpenParen);
+  resultRemainder.findAndReplace(formatCloseParen, formatReplaceCloseParen);
+
+  LocalPointer<StringEnumeration> e(loc.createKeywords(status));
+  if (e.isValid() && U_SUCCESS(status)) {
+    UnicodeString temp2;
+    char value[ULOC_KEYWORD_AND_VALUES_CAPACITY]; // sigh, no ULOC_VALUE_CAPACITY
+    const char* key;
+    while ((key = e->next((int32_t *)0, status)) != NULL) {
+      value[0] = 0;
+      loc.getKeywordValue(key, value, ULOC_KEYWORD_AND_VALUES_CAPACITY, status);
+      if (U_FAILURE(status) || status == U_STRING_NOT_TERMINATED_WARNING) {
+        return result;
+      }
+      keyDisplayName(key, temp, TRUE);
+      temp.findAndReplace(formatOpenParen, formatReplaceOpenParen);
+      temp.findAndReplace(formatCloseParen, formatReplaceCloseParen);
+      keyValueDisplayName(key, value, temp2, TRUE);
+      temp2.findAndReplace(formatOpenParen, formatReplaceOpenParen);
+      temp2.findAndReplace(formatCloseParen, formatReplaceCloseParen);
+      if (temp2 != UnicodeString(value, -1, US_INV)) {
+        appendWithSep(resultRemainder, temp2);
+      } else if (temp != UnicodeString(key, -1, US_INV)) {
+        UnicodeString temp3;
+        keyTypeFormat.format(temp, temp2, temp3, status);
+        appendWithSep(resultRemainder, temp3);
+      } else {
+        appendWithSep(resultRemainder, temp)
+          .append((UChar)0x3d /* = */)
+          .append(temp2);
+      }
+    }
+  }
+
+  if (!resultRemainder.isEmpty()) {
+    format.format(resultName, resultRemainder, result.remove(), status);
+    return adjustForUsageAndContext(kCapContextUsageLanguage, result);
+  }
+
+  result = resultName;
+  return adjustForUsageAndContext(kCapContextUsageLanguage, result);
+}
+
+UnicodeString&
+LocaleDisplayNamesImpl::appendWithSep(UnicodeString& buffer, const UnicodeString& src) const {
+    if (buffer.isEmpty()) {
+        buffer.setTo(src);
+    } else {
+        const UnicodeString *values[2] = { &buffer, &src };
+        UErrorCode status = U_ZERO_ERROR;
+        separatorFormat.formatAndReplace(values, 2, buffer, NULL, 0, status);
+    }
+    return buffer;
+}
+
+UnicodeString&
+LocaleDisplayNamesImpl::localeDisplayName(const char* localeId,
+                                          UnicodeString& result) const {
+    return localeDisplayName(Locale(localeId), result);
+}
+
+// private
+UnicodeString&
+LocaleDisplayNamesImpl::localeIdName(const char* localeId,
+                                     UnicodeString& result, bool substitute) const {
+    if (nameLength == UDISPCTX_LENGTH_SHORT) {
+        langData.getNoFallback("Languages%short", localeId, result);
+        if (!result.isBogus()) {
+            return result;
+        }
+    }
+    if (substitute) {
+        return langData.get("Languages", localeId, result);
+    } else {
+        return langData.getNoFallback("Languages", localeId, result);
+    }
+}
+
+UnicodeString&
+LocaleDisplayNamesImpl::languageDisplayName(const char* lang,
+                                            UnicodeString& result) const {
+    if (uprv_strcmp("root", lang) == 0 || uprv_strchr(lang, '_') != NULL) {
+        return result = UnicodeString(lang, -1, US_INV);
+    }
+    if (nameLength == UDISPCTX_LENGTH_SHORT) {
+        langData.getNoFallback("Languages%short", lang, result);
+        if (!result.isBogus()) {
+            return adjustForUsageAndContext(kCapContextUsageLanguage, result);
+        }
+    }
+    if (substitute == UDISPCTX_SUBSTITUTE) {
+        langData.get("Languages", lang, result);
+    } else {
+        langData.getNoFallback("Languages", lang, result);
+    }
+    return adjustForUsageAndContext(kCapContextUsageLanguage, result);
+}
+
+UnicodeString&
+LocaleDisplayNamesImpl::scriptDisplayName(const char* script,
+                                          UnicodeString& result,
+                                          UBool skipAdjust) const {
+    if (nameLength == UDISPCTX_LENGTH_SHORT) {
+        langData.getNoFallback("Scripts%short", script, result);
+        if (!result.isBogus()) {
+            return skipAdjust? result: adjustForUsageAndContext(kCapContextUsageScript, result);
+        }
+    }
+    if (substitute == UDISPCTX_SUBSTITUTE) {
+        langData.get("Scripts", script, result);
+    } else {
+        langData.getNoFallback("Scripts", script, result);
+    }
+    return skipAdjust? result: adjustForUsageAndContext(kCapContextUsageScript, result);
+}
+
+UnicodeString&
+LocaleDisplayNamesImpl::scriptDisplayName(const char* script,
+                                          UnicodeString& result) const {
+    return scriptDisplayName(script, result, FALSE);
+}
+
+UnicodeString&
+LocaleDisplayNamesImpl::scriptDisplayName(UScriptCode scriptCode,
+                                          UnicodeString& result) const {
+    return scriptDisplayName(uscript_getName(scriptCode), result, FALSE);
+}
+
+UnicodeString&
+LocaleDisplayNamesImpl::regionDisplayName(const char* region,
+                                          UnicodeString& result,
+                                          UBool skipAdjust) const {
+    if (nameLength == UDISPCTX_LENGTH_SHORT) {
+         regionData.getNoFallback("Countries%short", region, result);
+        if (!result.isBogus()) {
+            return skipAdjust? result: adjustForUsageAndContext(kCapContextUsageTerritory, result);
+        }
+    }
+    if (substitute == UDISPCTX_SUBSTITUTE) {
+        regionData.get("Countries", region, result);
+    } else {
+        regionData.getNoFallback("Countries", region, result);
+    }
+    return skipAdjust? result: adjustForUsageAndContext(kCapContextUsageTerritory, result);
+}
+
+UnicodeString&
+LocaleDisplayNamesImpl::regionDisplayName(const char* region,
+                                          UnicodeString& result) const {
+    return regionDisplayName(region, result, FALSE);
+}
+
+
+UnicodeString&
+LocaleDisplayNamesImpl::variantDisplayName(const char* variant,
+                                           UnicodeString& result,
+                                           UBool skipAdjust) const {
+    // don't have a resource for short variant names
+    if (substitute == UDISPCTX_SUBSTITUTE) {
+        langData.get("Variants", variant, result);
+    } else {
+        langData.getNoFallback("Variants", variant, result);
+    }
+    return skipAdjust? result: adjustForUsageAndContext(kCapContextUsageVariant, result);
+}
+
+UnicodeString&
+LocaleDisplayNamesImpl::variantDisplayName(const char* variant,
+                                           UnicodeString& result) const {
+    return variantDisplayName(variant, result, FALSE);
+}
+
+UnicodeString&
+LocaleDisplayNamesImpl::keyDisplayName(const char* key,
+                                       UnicodeString& result,
+                                       UBool skipAdjust) const {
+    // don't have a resource for short key names
+    if (substitute == UDISPCTX_SUBSTITUTE) {
+        langData.get("Keys", key, result);
+    } else {
+        langData.getNoFallback("Keys", key, result);
+    }
+    return skipAdjust? result: adjustForUsageAndContext(kCapContextUsageKey, result);
+}
+
+UnicodeString&
+LocaleDisplayNamesImpl::keyDisplayName(const char* key,
+                                       UnicodeString& result) const {
+    return keyDisplayName(key, result, FALSE);
+}
+
+UnicodeString&
+LocaleDisplayNamesImpl::keyValueDisplayName(const char* key,
+                                            const char* value,
+                                            UnicodeString& result,
+                                            UBool skipAdjust) const {
+    if (uprv_strcmp(key, "currency") == 0) {
+        // ICU4C does not have ICU4J CurrencyDisplayInfo equivalent for now.
+        UErrorCode sts = U_ZERO_ERROR;
+        UnicodeString ustrValue(value, -1, US_INV);
+        int32_t len;
+        const UChar *currencyName = ucurr_getName(ustrValue.getTerminatedBuffer(),
+            locale.getBaseName(), UCURR_LONG_NAME, nullptr /* isChoiceFormat */, &len, &sts);
+        if (U_FAILURE(sts)) {
+            // Return the value as is on failure
+            result = ustrValue;
+            return result;
+        }
+        result.setTo(currencyName, len);
+        return skipAdjust? result: adjustForUsageAndContext(kCapContextUsageKeyValue, result);
+    }
+
+    if (nameLength == UDISPCTX_LENGTH_SHORT) {
+        langData.getNoFallback("Types%short", key, value, result);
+        if (!result.isBogus()) {
+            return skipAdjust? result: adjustForUsageAndContext(kCapContextUsageKeyValue, result);
+        }
+    }
+    if (substitute == UDISPCTX_SUBSTITUTE) {
+        langData.get("Types", key, value, result);
+    } else {
+        langData.getNoFallback("Types", key, value, result);
+    }
+    return skipAdjust? result: adjustForUsageAndContext(kCapContextUsageKeyValue, result);
+}
+
+UnicodeString&
+LocaleDisplayNamesImpl::keyValueDisplayName(const char* key,
+                                            const char* value,
+                                            UnicodeString& result) const {
+    return keyValueDisplayName(key, value, result, FALSE);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+LocaleDisplayNames*
+LocaleDisplayNames::createInstance(const Locale& locale,
+                                   UDialectHandling dialectHandling) {
+    return new LocaleDisplayNamesImpl(locale, dialectHandling);
+}
+
+LocaleDisplayNames*
+LocaleDisplayNames::createInstance(const Locale& locale,
+                                   UDisplayContext *contexts, int32_t length) {
+    if (contexts == NULL) {
+        length = 0;
+    }
+    return new LocaleDisplayNamesImpl(locale, contexts, length);
+}
+
+U_NAMESPACE_END
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+U_NAMESPACE_USE
+
+U_CAPI ULocaleDisplayNames * U_EXPORT2
+uldn_open(const char * locale,
+          UDialectHandling dialectHandling,
+          UErrorCode *pErrorCode) {
+  if (U_FAILURE(*pErrorCode)) {
+    return 0;
+  }
+  if (locale == NULL) {
+    locale = uloc_getDefault();
+  }
+  return (ULocaleDisplayNames *)LocaleDisplayNames::createInstance(Locale(locale), dialectHandling);
+}
+
+U_CAPI ULocaleDisplayNames * U_EXPORT2
+uldn_openForContext(const char * locale,
+                    UDisplayContext *contexts, int32_t length,
+                    UErrorCode *pErrorCode) {
+  if (U_FAILURE(*pErrorCode)) {
+    return 0;
+  }
+  if (locale == NULL) {
+    locale = uloc_getDefault();
+  }
+  return (ULocaleDisplayNames *)LocaleDisplayNames::createInstance(Locale(locale), contexts, length);
+}
+
+
+U_CAPI void U_EXPORT2
+uldn_close(ULocaleDisplayNames *ldn) {
+  delete (LocaleDisplayNames *)ldn;
+}
+
+U_CAPI const char * U_EXPORT2
+uldn_getLocale(const ULocaleDisplayNames *ldn) {
+  if (ldn) {
+    return ((const LocaleDisplayNames *)ldn)->getLocale().getName();
+  }
+  return NULL;
+}
+
+U_CAPI UDialectHandling U_EXPORT2
+uldn_getDialectHandling(const ULocaleDisplayNames *ldn) {
+  if (ldn) {
+    return ((const LocaleDisplayNames *)ldn)->getDialectHandling();
+  }
+  return ULDN_STANDARD_NAMES;
+}
+
+U_CAPI UDisplayContext U_EXPORT2
+uldn_getContext(const ULocaleDisplayNames *ldn,
+              UDisplayContextType type,
+              UErrorCode *pErrorCode) {
+  if (U_FAILURE(*pErrorCode)) {
+    return (UDisplayContext)0;
+  }
+  return ((const LocaleDisplayNames *)ldn)->getContext(type);
+}
+
+U_CAPI int32_t U_EXPORT2
+uldn_localeDisplayName(const ULocaleDisplayNames *ldn,
+                       const char *locale,
+                       UChar *result,
+                       int32_t maxResultSize,
+                       UErrorCode *pErrorCode) {
+  if (U_FAILURE(*pErrorCode)) {
+    return 0;
+  }
+  if (ldn == NULL || locale == NULL || (result == NULL && maxResultSize > 0) || maxResultSize < 0) {
+    *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR;
+    return 0;
+  }
+  UnicodeString temp(result, 0, maxResultSize);
+  ((const LocaleDisplayNames *)ldn)->localeDisplayName(locale, temp);
+  if (temp.isBogus()) {
+    *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR;
+    return 0;
+  }
+  return temp.extract(result, maxResultSize, *pErrorCode);
+}
+
+U_CAPI int32_t U_EXPORT2
+uldn_languageDisplayName(const ULocaleDisplayNames *ldn,
+                         const char *lang,
+                         UChar *result,
+                         int32_t maxResultSize,
+                         UErrorCode *pErrorCode) {
+  if (U_FAILURE(*pErrorCode)) {
+    return 0;
+  }
+  if (ldn == NULL || lang == NULL || (result == NULL && maxResultSize > 0) || maxResultSize < 0) {
+    *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR;
+    return 0;
+  }
+  UnicodeString temp(result, 0, maxResultSize);
+  ((const LocaleDisplayNames *)ldn)->languageDisplayName(lang, temp);
+  return temp.extract(result, maxResultSize, *pErrorCode);
+}
+
+U_CAPI int32_t U_EXPORT2
+uldn_scriptDisplayName(const ULocaleDisplayNames *ldn,
+                       const char *script,
+                       UChar *result,
+                       int32_t maxResultSize,
+                       UErrorCode *pErrorCode) {
+  if (U_FAILURE(*pErrorCode)) {
+    return 0;
+  }
+  if (ldn == NULL || script == NULL || (result == NULL && maxResultSize > 0) || maxResultSize < 0) {
+    *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR;
+    return 0;
+  }
+  UnicodeString temp(result, 0, maxResultSize);
+  ((const LocaleDisplayNames *)ldn)->scriptDisplayName(script, temp);
+  return temp.extract(result, maxResultSize, *pErrorCode);
+}
+
+U_CAPI int32_t U_EXPORT2
+uldn_scriptCodeDisplayName(const ULocaleDisplayNames *ldn,
+                           UScriptCode scriptCode,
+                           UChar *result,
+                           int32_t maxResultSize,
+                           UErrorCode *pErrorCode) {
+  return uldn_scriptDisplayName(ldn, uscript_getName(scriptCode), result, maxResultSize, pErrorCode);
+}
+
+U_CAPI int32_t U_EXPORT2
+uldn_regionDisplayName(const ULocaleDisplayNames *ldn,
+                       const char *region,
+                       UChar *result,
+                       int32_t maxResultSize,
+                       UErrorCode *pErrorCode) {
+  if (U_FAILURE(*pErrorCode)) {
+    return 0;
+  }
+  if (ldn == NULL || region == NULL || (result == NULL && maxResultSize > 0) || maxResultSize < 0) {
+    *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR;
+    return 0;
+  }
+  UnicodeString temp(result, 0, maxResultSize);
+  ((const LocaleDisplayNames *)ldn)->regionDisplayName(region, temp);
+  return temp.extract(result, maxResultSize, *pErrorCode);
+}
+
+U_CAPI int32_t U_EXPORT2
+uldn_variantDisplayName(const ULocaleDisplayNames *ldn,
+                        const char *variant,
+                        UChar *result,
+                        int32_t maxResultSize,
+                        UErrorCode *pErrorCode) {
+  if (U_FAILURE(*pErrorCode)) {
+    return 0;
+  }
+  if (ldn == NULL || variant == NULL || (result == NULL && maxResultSize > 0) || maxResultSize < 0) {
+    *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR;
+    return 0;
+  }
+  UnicodeString temp(result, 0, maxResultSize);
+  ((const LocaleDisplayNames *)ldn)->variantDisplayName(variant, temp);
+  return temp.extract(result, maxResultSize, *pErrorCode);
+}
+
+U_CAPI int32_t U_EXPORT2
+uldn_keyDisplayName(const ULocaleDisplayNames *ldn,
+                    const char *key,
+                    UChar *result,
+                    int32_t maxResultSize,
+                    UErrorCode *pErrorCode) {
+  if (U_FAILURE(*pErrorCode)) {
+    return 0;
+  }
+  if (ldn == NULL || key == NULL || (result == NULL && maxResultSize > 0) || maxResultSize < 0) {
+    *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR;
+    return 0;
+  }
+  UnicodeString temp(result, 0, maxResultSize);
+  ((const LocaleDisplayNames *)ldn)->keyDisplayName(key, temp);
+  return temp.extract(result, maxResultSize, *pErrorCode);
+}
+
+U_CAPI int32_t U_EXPORT2
+uldn_keyValueDisplayName(const ULocaleDisplayNames *ldn,
+                         const char *key,
+                         const char *value,
+                         UChar *result,
+                         int32_t maxResultSize,
+                         UErrorCode *pErrorCode) {
+  if (U_FAILURE(*pErrorCode)) {
+    return 0;
+  }
+  if (ldn == NULL || key == NULL || value == NULL || (result == NULL && maxResultSize > 0)
+      || maxResultSize < 0) {
+    *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR;
+    return 0;
+  }
+  UnicodeString temp(result, 0, maxResultSize);
+  ((const LocaleDisplayNames *)ldn)->keyValueDisplayName(key, value, temp);
+  return temp.extract(result, maxResultSize, *pErrorCode);
+}
+
+#endif
diff --git a/src/third_party/icu/source/common/locid.cpp b/src/third_party/icu/source/common/locid.cpp
index cf77b8e..d0b1d47 100644
--- a/src/third_party/icu/source/common/locid.cpp
+++ b/src/third_party/icu/source/common/locid.cpp
@@ -1,6 +1,8 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
  **********************************************************************
- *   Copyright (C) 1997-2015, International Business Machines
+ *   Copyright (C) 1997-2016, International Business Machines
  *   Corporation and others.  All Rights Reserved.
  **********************************************************************
 *
@@ -29,20 +31,36 @@
 ******************************************************************************
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
+
+#include <utility>
+
+#include "unicode/bytestream.h"
 #include "unicode/locid.h"
+#include "unicode/localebuilder.h"
+#include "unicode/strenum.h"
+#include "unicode/stringpiece.h"
 #include "unicode/uloc.h"
-#include "putilimp.h"
-#include "mutex.h"
-#include "umutex.h"
-#include "uassert.h"
+#include "unicode/ures.h"
+
+#include "bytesinkutil.h"
+#include "charstr.h"
+#include "charstrmap.h"
 #include "cmemory.h"
 #include "cstring.h"
+#include "mutex.h"
+#include "putilimp.h"
 #include "uassert.h"
-#include "uhash.h"
 #include "ucln_cmn.h"
+#include "uhash.h"
+#include "ulocimp.h"
+#include "umutex.h"
+#include "uniquecharstr.h"
 #include "ustr_imp.h"
+#include "uvector.h"
 
 U_CDECL_BEGIN
 static UBool U_CALLCONV locale_cleanup(void);
@@ -54,10 +72,16 @@
 static UInitOnce gLocaleCacheInitOnce = U_INITONCE_INITIALIZER;
 
 // gDefaultLocaleMutex protects all access to gDefaultLocalesHashT and gDefaultLocale.
-static UMutex gDefaultLocaleMutex = U_MUTEX_INITIALIZER;
+static UMutex gDefaultLocaleMutex;
 static UHashtable *gDefaultLocalesHashT = NULL;
 static Locale *gDefaultLocale = NULL;
 
+/**
+ * \def ULOC_STRING_LIMIT
+ * strings beyond this value crash in CharString
+ */
+#define ULOC_STRING_LIMIT 357913941
+
 U_NAMESPACE_END
 
 typedef enum ELocalePos {
@@ -87,13 +111,6 @@
     eMAX_LOCALES
 } ELocalePos;
 
-U_CFUNC int32_t locale_getKeywords(const char *localeID,
-            char prev,
-            char *keywords, int32_t keywordCapacity,
-            char *values, int32_t valuesCapacity, int32_t *valLen,
-            UBool valuesToo,
-            UErrorCode *status);
-
 U_CDECL_BEGIN
 //
 // Deleter function for Locales owned by the default Locale hash table/
@@ -170,17 +187,16 @@
         canonicalize = TRUE; // always canonicalize host ID
     }
 
-    char localeNameBuf[512];
-
-    if (canonicalize) {
-        uloc_canonicalize(id, localeNameBuf, sizeof(localeNameBuf)-1, &status);
-    } else {
-        uloc_getName(id, localeNameBuf, sizeof(localeNameBuf)-1, &status);
+    CharString localeNameBuf;
+    {
+        CharStringByteSink sink(&localeNameBuf);
+        if (canonicalize) {
+            ulocimp_canonicalize(id, sink, &status);
+        } else {
+            ulocimp_getName(id, sink, &status);
+        }
     }
-    localeNameBuf[sizeof(localeNameBuf)-1] = 0;  // Force null termination in event of
-                                                 //   a long name filling the buffer.
-                                                 //   (long names are truncated.)
-                                                 //
+
     if (U_FAILURE(status)) {
         return gDefaultLocale;
     }
@@ -194,14 +210,14 @@
         ucln_common_registerCleanup(UCLN_COMMON_LOCALE, locale_cleanup);
     }
 
-    Locale *newDefault = (Locale *)uhash_get(gDefaultLocalesHashT, localeNameBuf);
+    Locale *newDefault = (Locale *)uhash_get(gDefaultLocalesHashT, localeNameBuf.data());
     if (newDefault == NULL) {
         newDefault = new Locale(Locale::eBOGUS);
         if (newDefault == NULL) {
             status = U_MEMORY_ALLOCATION_ERROR;
             return gDefaultLocale;
         }
-        newDefault->init(localeNameBuf, FALSE);
+        newDefault->init(localeNameBuf.data(), FALSE);
         uhash_put(gDefaultLocalesHashT, (char*) newDefault->getName(), newDefault, &status);
         if (U_FAILURE(status)) {
             return gDefaultLocale;
@@ -239,6 +255,7 @@
 // '_'
 // In the platform codepage.
 #define SEP_CHAR '_'
+#define NULL_CHAR '\0'
 
 Locale::~Locale()
 {
@@ -284,13 +301,12 @@
     }
     else
     {
-        MaybeStackArray<char, ULOC_FULLNAME_CAPACITY> togo;
+        UErrorCode status = U_ZERO_ERROR;
         int32_t size = 0;
         int32_t lsize = 0;
         int32_t csize = 0;
         int32_t vsize = 0;
         int32_t ksize = 0;
-        char    *p;
 
         // Calculate the size of the resulting string.
 
@@ -298,13 +314,23 @@
         if ( newLanguage != NULL )
         {
             lsize = (int32_t)uprv_strlen(newLanguage);
+            if ( lsize < 0 || lsize > ULOC_STRING_LIMIT ) { // int32 wrap
+                setToBogus();
+                return;
+            }
             size = lsize;
         }
 
+        CharString togo(newLanguage, lsize, status); // start with newLanguage
+
         // _Country
         if ( newCountry != NULL )
         {
             csize = (int32_t)uprv_strlen(newCountry);
+            if ( csize < 0 || csize > ULOC_STRING_LIMIT ) { // int32 wrap
+                setToBogus();
+                return;
+            }
             size += csize;
         }
 
@@ -319,6 +345,10 @@
 
             // remove trailing _'s
             vsize = (int32_t)uprv_strlen(newVariant);
+            if ( vsize < 0 || vsize > ULOC_STRING_LIMIT ) { // int32 wrap
+                setToBogus();
+                return;
+            }
             while( (vsize>1) && (newVariant[vsize-1] == SEP_CHAR) )
             {
                 vsize--;
@@ -343,70 +373,56 @@
         if ( newKeywords != NULL)
         {
             ksize = (int32_t)uprv_strlen(newKeywords);
+            if ( ksize < 0 || ksize > ULOC_STRING_LIMIT ) {
+              setToBogus();
+              return;
+            }
             size += ksize + 1;
         }
 
-
         //  NOW we have the full locale string..
-
-        /*if the whole string is longer than our internal limit, we need
-        to go to the heap for temporary buffers*/
-        if (size >= togo.getCapacity())
-        {
-            // If togo_heap could not be created, initialize with default settings.
-            if (togo.resize(size+1) == NULL) {
-                init(NULL, FALSE);
-            }
-        }
-
-        togo[0] = 0;
-
         // Now, copy it back.
-        p = togo.getAlias();
-        if ( lsize != 0 )
-        {
-            uprv_strcpy(p, newLanguage);
-            p += lsize;
-        }
+
+        // newLanguage is already copied
 
         if ( ( vsize != 0 ) || (csize != 0) )  // at least:  __v
         {                                      //            ^
-            *p++ = SEP_CHAR;
+            togo.append(SEP_CHAR, status);
         }
 
         if ( csize != 0 )
         {
-            uprv_strcpy(p, newCountry);
-            p += csize;
+            togo.append(newCountry, status);
         }
 
         if ( vsize != 0)
         {
-            *p++ = SEP_CHAR; // at least: __v
-
-            uprv_strncpy(p, newVariant, vsize);  // Must use strncpy because
-            p += vsize;                          // of trimming (above).
-            *p = 0; // terminate
+            togo.append(SEP_CHAR, status)
+                .append(newVariant, vsize, status);
         }
 
         if ( ksize != 0)
         {
             if (uprv_strchr(newKeywords, '=')) {
-                *p++ = '@'; /* keyword parsing */
+                togo.append('@', status); /* keyword parsing */
             }
             else {
-                *p++ = '_'; /* Variant parsing with a script */
+                togo.append('_', status); /* Variant parsing with a script */
                 if ( vsize == 0) {
-                    *p++ = '_'; /* No country found */
+                    togo.append('_', status); /* No country found */
                 }
             }
-            uprv_strcpy(p, newKeywords);
-            p += ksize;
+            togo.append(newKeywords, status);
         }
 
+        if (U_FAILURE(status)) {
+            // Something went wrong with appending, etc.
+            setToBogus();
+            return;
+        }
         // Parse it, because for example 'language' might really be a complete
         // string.
-        init(togo.getAlias(), FALSE);
+        init(togo.data(), FALSE);
     }
 }
 
@@ -416,49 +432,70 @@
     *this = other;
 }
 
-Locale &Locale::operator=(const Locale &other)
-{
+Locale::Locale(Locale&& other) U_NOEXCEPT
+    : UObject(other), fullName(fullNameBuffer), baseName(fullName) {
+  *this = std::move(other);
+}
+
+Locale& Locale::operator=(const Locale& other) {
     if (this == &other) {
         return *this;
     }
 
-    /* Free our current storage */
-    if (baseName != fullName) {
-        uprv_free(baseName);
-    }
-    baseName = NULL;
-    if(fullName != fullNameBuffer) {
-        uprv_free(fullName);
-        fullName = fullNameBuffer;
+    setToBogus();
+
+    if (other.fullName == other.fullNameBuffer) {
+        uprv_strcpy(fullNameBuffer, other.fullNameBuffer);
+    } else if (other.fullName == nullptr) {
+        fullName = nullptr;
+    } else {
+        fullName = uprv_strdup(other.fullName);
+        if (fullName == nullptr) return *this;
     }
 
-    /* Allocate the full name if necessary */
-    if(other.fullName != other.fullNameBuffer) {
-        fullName = (char *)uprv_malloc(sizeof(char)*(uprv_strlen(other.fullName)+1));
-        if (fullName == NULL) {
-            return *this;
-        }
-    }
-    /* Copy the full name */
-    uprv_strcpy(fullName, other.fullName);
-
-    /* Copy the baseName if it differs from fullName. */
     if (other.baseName == other.fullName) {
         baseName = fullName;
-    } else {
-        if (other.baseName) {
-            baseName = uprv_strdup(other.baseName);
-        }
+    } else if (other.baseName != nullptr) {
+        baseName = uprv_strdup(other.baseName);
+        if (baseName == nullptr) return *this;
     }
 
-    /* Copy the language and country fields */
     uprv_strcpy(language, other.language);
     uprv_strcpy(script, other.script);
     uprv_strcpy(country, other.country);
 
-    /* The variantBegin is an offset, just copy it */
     variantBegin = other.variantBegin;
     fIsBogus = other.fIsBogus;
+
+    return *this;
+}
+
+Locale& Locale::operator=(Locale&& other) U_NOEXCEPT {
+    if (baseName != fullName) uprv_free(baseName);
+    if (fullName != fullNameBuffer) uprv_free(fullName);
+
+    if (other.fullName == other.fullNameBuffer) {
+        uprv_strcpy(fullNameBuffer, other.fullNameBuffer);
+        fullName = fullNameBuffer;
+    } else {
+        fullName = other.fullName;
+    }
+
+    if (other.baseName == other.fullName) {
+        baseName = fullName;
+    } else {
+        baseName = other.baseName;
+    }
+
+    uprv_strcpy(language, other.language);
+    uprv_strcpy(script, other.script);
+    uprv_strcpy(country, other.country);
+
+    variantBegin = other.variantBegin;
+    fIsBogus = other.fIsBogus;
+
+    other.baseName = other.fullName = other.fullNameBuffer;
+
     return *this;
 }
 
@@ -473,7 +510,1129 @@
     return (uprv_strcmp(other.fullName, fullName) == 0);
 }
 
-#define ISASCIIALPHA(c) (((c) >= 'a' && (c) <= 'z') || ((c) >= 'A' && (c) <= 'Z'))
+namespace {
+
+UInitOnce gKnownCanonicalizedInitOnce = U_INITONCE_INITIALIZER;
+UHashtable *gKnownCanonicalized = nullptr;
+
+static const char* const KNOWN_CANONICALIZED[] = {
+    "c",
+    // Commonly used locales known are already canonicalized
+    "af", "af_ZA", "am", "am_ET", "ar", "ar_001", "as", "as_IN", "az", "az_AZ",
+    "be", "be_BY", "bg", "bg_BG", "bn", "bn_IN", "bs", "bs_BA", "ca", "ca_ES",
+    "cs", "cs_CZ", "cy", "cy_GB", "da", "da_DK", "de", "de_DE", "el", "el_GR",
+    "en", "en_GB", "en_US", "es", "es_419", "es_ES", "et", "et_EE", "eu",
+    "eu_ES", "fa", "fa_IR", "fi", "fi_FI", "fil", "fil_PH", "fr", "fr_FR",
+    "ga", "ga_IE", "gl", "gl_ES", "gu", "gu_IN", "he", "he_IL", "hi", "hi_IN",
+    "hr", "hr_HR", "hu", "hu_HU", "hy", "hy_AM", "id", "id_ID", "is", "is_IS",
+    "it", "it_IT", "ja", "ja_JP", "jv", "jv_ID", "ka", "ka_GE", "kk", "kk_KZ",
+    "km", "km_KH", "kn", "kn_IN", "ko", "ko_KR", "ky", "ky_KG", "lo", "lo_LA",
+    "lt", "lt_LT", "lv", "lv_LV", "mk", "mk_MK", "ml", "ml_IN", "mn", "mn_MN",
+    "mr", "mr_IN", "ms", "ms_MY", "my", "my_MM", "nb", "nb_NO", "ne", "ne_NP",
+    "nl", "nl_NL", "or", "or_IN", "pa", "pa_IN", "pl", "pl_PL", "ps", "ps_AF",
+    "pt", "pt_BR", "pt_PT", "ro", "ro_RO", "ru", "ru_RU", "sd", "sd_IN", "si",
+    "si_LK", "sk", "sk_SK", "sl", "sl_SI", "so", "so_SO", "sq", "sq_AL", "sr",
+    "sr_Cyrl_RS", "sr_Latn", "sr_RS", "sv", "sv_SE", "sw", "sw_TZ", "ta",
+    "ta_IN", "te", "te_IN", "th", "th_TH", "tk", "tk_TM", "tr", "tr_TR", "uk",
+    "uk_UA", "ur", "ur_PK", "uz", "uz_UZ", "vi", "vi_VN", "yue", "yue_Hant",
+    "yue_Hant_HK", "yue_HK", "zh", "zh_CN", "zh_Hans", "zh_Hans_CN", "zh_Hant",
+    "zh_Hant_TW", "zh_TW", "zu", "zu_ZA"
+};
+
+static UBool U_CALLCONV cleanupKnownCanonicalized() {
+    gKnownCanonicalizedInitOnce.reset();
+    if (gKnownCanonicalized) { uhash_close(gKnownCanonicalized); }
+    return TRUE;
+}
+
+static void U_CALLCONV loadKnownCanonicalized(UErrorCode &status) {
+    ucln_common_registerCleanup(UCLN_COMMON_LOCALE_KNOWN_CANONICALIZED,
+                                cleanupKnownCanonicalized);
+    LocalUHashtablePointer newKnownCanonicalizedMap(
+        uhash_open(uhash_hashChars, uhash_compareChars, nullptr, &status));
+    for (int32_t i = 0;
+            U_SUCCESS(status) && i < UPRV_LENGTHOF(KNOWN_CANONICALIZED);
+            i++) {
+        uhash_puti(newKnownCanonicalizedMap.getAlias(),
+                   (void*)KNOWN_CANONICALIZED[i],
+                   1, &status);
+    }
+    if (U_FAILURE(status)) {
+        return;
+    }
+
+    gKnownCanonicalized = newKnownCanonicalizedMap.orphan();
+}
+
+class AliasData;
+
+/**
+ * A Builder class to build the alias data.
+ */
+class AliasDataBuilder {
+public:
+    AliasDataBuilder() {
+    }
+
+    // Build the AliasData from resource.
+    AliasData* build(UErrorCode &status);
+
+private:
+    void readAlias(UResourceBundle* alias,
+                   UniqueCharStrings* strings,
+                   LocalMemory<const char*>& types,
+                   LocalMemory<int32_t>& replacementIndexes,
+                   int32_t &length,
+                   void (*checkType)(const char* type),
+                   void (*checkReplacement)(const UnicodeString& replacement),
+                   UErrorCode &status);
+
+    // Read the languageAlias data from alias to
+    // strings+types+replacementIndexes
+    // The number of record will be stored into length.
+    // Allocate length items for types, to store the type field.
+    // Allocate length items for replacementIndexes,
+    // to store the index in the strings for the replacement script.
+    void readLanguageAlias(UResourceBundle* alias,
+                           UniqueCharStrings* strings,
+                           LocalMemory<const char*>& types,
+                           LocalMemory<int32_t>& replacementIndexes,
+                           int32_t &length,
+                           UErrorCode &status);
+
+    // Read the scriptAlias data from alias to
+    // strings+types+replacementIndexes
+    // Allocate length items for types, to store the type field.
+    // Allocate length items for replacementIndexes,
+    // to store the index in the strings for the replacement script.
+    void readScriptAlias(UResourceBundle* alias,
+                         UniqueCharStrings* strings,
+                         LocalMemory<const char*>& types,
+                         LocalMemory<int32_t>& replacementIndexes,
+                         int32_t &length, UErrorCode &status);
+
+    // Read the territoryAlias data from alias to
+    // strings+types+replacementIndexes
+    // Allocate length items for types, to store the type field.
+    // Allocate length items for replacementIndexes,
+    // to store the index in the strings for the replacement script.
+    void readTerritoryAlias(UResourceBundle* alias,
+                            UniqueCharStrings* strings,
+                            LocalMemory<const char*>& types,
+                            LocalMemory<int32_t>& replacementIndexes,
+                            int32_t &length, UErrorCode &status);
+
+    // Read the variantAlias data from alias to
+    // strings+types+replacementIndexes
+    // Allocate length items for types, to store the type field.
+    // Allocate length items for replacementIndexes,
+    // to store the index in the strings for the replacement variant.
+    void readVariantAlias(UResourceBundle* alias,
+                          UniqueCharStrings* strings,
+                          LocalMemory<const char*>& types,
+                          LocalMemory<int32_t>& replacementIndexes,
+                          int32_t &length, UErrorCode &status);
+};
+
+/**
+ * A class to hold the Alias Data.
+ */
+class AliasData : public UMemory {
+public:
+    static const AliasData* singleton(UErrorCode& status) {
+        if (U_FAILURE(status)) {
+            // Do not get into loadData if the status already has error.
+            return nullptr;
+        }
+        umtx_initOnce(AliasData::gInitOnce, &AliasData::loadData, status);
+        return gSingleton;
+    }
+
+    const CharStringMap& languageMap() const { return language; }
+    const CharStringMap& scriptMap() const { return script; }
+    const CharStringMap& territoryMap() const { return territory; }
+    const CharStringMap& variantMap() const { return variant; }
+
+    static void U_CALLCONV loadData(UErrorCode &status);
+    static UBool U_CALLCONV cleanup();
+
+    static UInitOnce gInitOnce;
+
+private:
+    AliasData(CharStringMap languageMap,
+              CharStringMap scriptMap,
+              CharStringMap territoryMap,
+              CharStringMap variantMap,
+              CharString* strings)
+        : language(std::move(languageMap)),
+          script(std::move(scriptMap)),
+          territory(std::move(territoryMap)),
+          variant(std::move(variantMap)),
+          strings(strings) {
+    }
+
+    ~AliasData() {
+        delete strings;
+    }
+
+    static const AliasData* gSingleton;
+
+    CharStringMap language;
+    CharStringMap script;
+    CharStringMap territory;
+    CharStringMap variant;
+    CharString* strings;
+
+    friend class AliasDataBuilder;
+};
+
+
+const AliasData* AliasData::gSingleton = nullptr;
+UInitOnce AliasData::gInitOnce = U_INITONCE_INITIALIZER;
+
+UBool U_CALLCONV
+AliasData::cleanup()
+{
+    gInitOnce.reset();
+    delete gSingleton;
+    return TRUE;
+}
+
+void
+AliasDataBuilder::readAlias(
+        UResourceBundle* alias,
+        UniqueCharStrings* strings,
+        LocalMemory<const char*>& types,
+        LocalMemory<int32_t>& replacementIndexes,
+        int32_t &length,
+        void (*checkType)(const char* type),
+        void (*checkReplacement)(const UnicodeString& replacement),
+        UErrorCode &status) {
+    if (U_FAILURE(status)) {
+        return;
+    }
+    length = ures_getSize(alias);
+    const char** rawTypes = types.allocateInsteadAndCopy(length);
+    if (rawTypes == nullptr) {
+        status = U_MEMORY_ALLOCATION_ERROR;
+        return;
+    }
+    int32_t* rawIndexes = replacementIndexes.allocateInsteadAndCopy(length);
+    if (rawIndexes == nullptr) {
+        status = U_MEMORY_ALLOCATION_ERROR;
+        return;
+    }
+    int i = 0;
+    while (ures_hasNext(alias)) {
+        LocalUResourceBundlePointer res(
+            ures_getNextResource(alias, nullptr, &status));
+        const char* aliasFrom = ures_getKey(res.getAlias());
+        UnicodeString aliasTo =
+            ures_getUnicodeStringByKey(res.getAlias(), "replacement", &status);
+
+        checkType(aliasFrom);
+        checkReplacement(aliasTo);
+
+        rawTypes[i] = aliasFrom;
+        rawIndexes[i] = strings->add(aliasTo, status);
+        i++;
+    }
+}
+
+/**
+ * Read the languageAlias data from alias to strings+types+replacementIndexes.
+ * Allocate length items for types, to store the type field. Allocate length
+ * items for replacementIndexes, to store the index in the strings for the
+ * replacement language.
+ */
+void
+AliasDataBuilder::readLanguageAlias(
+        UResourceBundle* alias,
+        UniqueCharStrings* strings,
+        LocalMemory<const char*>& types,
+        LocalMemory<int32_t>& replacementIndexes,
+        int32_t &length,
+        UErrorCode &status)
+{
+    return readAlias(
+        alias, strings, types, replacementIndexes, length,
+#if U_DEBUG
+        [](const char* type) {
+            // Assert the aliasFrom only contains the following possibilties
+            // language_REGION_variant
+            // language_REGION
+            // language_variant
+            // language
+            // und_variant
+            Locale test(type);
+            // Assert no script in aliasFrom
+            U_ASSERT(test.getScript()[0] == '\0');
+            // Assert when language is und, no REGION in aliasFrom.
+            U_ASSERT(test.getLanguage()[0] != '\0' || test.getCountry()[0] == '\0');
+        },
+#else
+        [](const char*) {},
+#endif
+        [](const UnicodeString&) {}, status);
+}
+
+/**
+ * Read the scriptAlias data from alias to strings+types+replacementIndexes.
+ * Allocate length items for types, to store the type field. Allocate length
+ * items for replacementIndexes, to store the index in the strings for the
+ * replacement script.
+ */
+void
+AliasDataBuilder::readScriptAlias(
+        UResourceBundle* alias,
+        UniqueCharStrings* strings,
+        LocalMemory<const char*>& types,
+        LocalMemory<int32_t>& replacementIndexes,
+        int32_t &length,
+        UErrorCode &status)
+{
+    return readAlias(
+        alias, strings, types, replacementIndexes, length,
+#if U_DEBUG
+        [](const char* type) {
+            U_ASSERT(uprv_strlen(type) == 4);
+        },
+        [](const UnicodeString& replacement) {
+            U_ASSERT(replacement.length() == 4);
+        },
+#else
+        [](const char*) {},
+        [](const UnicodeString&) { },
+#endif
+        status);
+}
+
+/**
+ * Read the territoryAlias data from alias to strings+types+replacementIndexes.
+ * Allocate length items for types, to store the type field. Allocate length
+ * items for replacementIndexes, to store the index in the strings for the
+ * replacement regions.
+ */
+void
+AliasDataBuilder::readTerritoryAlias(
+        UResourceBundle* alias,
+        UniqueCharStrings* strings,
+        LocalMemory<const char*>& types,
+        LocalMemory<int32_t>& replacementIndexes,
+        int32_t &length,
+        UErrorCode &status)
+{
+    return readAlias(
+        alias, strings, types, replacementIndexes, length,
+#if U_DEBUG
+        [](const char* type) {
+            U_ASSERT(uprv_strlen(type) == 2 || uprv_strlen(type) == 3);
+        },
+#else
+        [](const char*) {},
+#endif
+        [](const UnicodeString&) { },
+        status);
+}
+
+/**
+ * Read the variantAlias data from alias to strings+types+replacementIndexes.
+ * Allocate length items for types, to store the type field. Allocate length
+ * items for replacementIndexes, to store the index in the strings for the
+ * replacement variant.
+ */
+void
+AliasDataBuilder::readVariantAlias(
+        UResourceBundle* alias,
+        UniqueCharStrings* strings,
+        LocalMemory<const char*>& types,
+        LocalMemory<int32_t>& replacementIndexes,
+        int32_t &length,
+        UErrorCode &status)
+{
+    return readAlias(
+        alias, strings, types, replacementIndexes, length,
+#if U_DEBUG
+        [](const char* type) {
+            U_ASSERT(uprv_strlen(type) >= 4 && uprv_strlen(type) <= 8);
+            U_ASSERT(uprv_strlen(type) != 4 ||
+                     (type[0] >= '0' && type[0] <= '9'));
+        },
+        [](const UnicodeString& replacement) {
+            U_ASSERT(replacement.length() >= 4 && replacement.length() <= 8);
+            U_ASSERT(replacement.length() != 4 ||
+                     (replacement.charAt(0) >= u'0' &&
+                      replacement.charAt(0) <= u'9'));
+        },
+#else
+        [](const char*) {},
+        [](const UnicodeString&) { },
+#endif
+        status);
+}
+
+/**
+ * Initializes the alias data from the ICU resource bundles. The alias data
+ * contains alias of language, country, script and variants.
+ *
+ * If the alias data has already loaded, then this method simply returns without
+ * doing anything meaningful.
+ */
+void U_CALLCONV
+AliasData::loadData(UErrorCode &status)
+{
+#ifdef LOCALE_CANONICALIZATION_DEBUG
+    UDate start = uprv_getRawUTCtime();
+#endif  // LOCALE_CANONICALIZATION_DEBUG
+    ucln_common_registerCleanup(UCLN_COMMON_LOCALE_ALIAS, cleanup);
+    AliasDataBuilder builder;
+    gSingleton = builder.build(status);
+#ifdef LOCALE_CANONICALIZATION_DEBUG
+    UDate end = uprv_getRawUTCtime();
+    printf("AliasData::loadData took total %f ms\n", end - start);
+#endif  // LOCALE_CANONICALIZATION_DEBUG
+}
+
+/**
+ * Build the alias data from resources.
+ */
+AliasData*
+AliasDataBuilder::build(UErrorCode &status) {
+    LocalUResourceBundlePointer metadata(
+        ures_openDirect(nullptr, "metadata", &status));
+    LocalUResourceBundlePointer metadataAlias(
+        ures_getByKey(metadata.getAlias(), "alias", nullptr, &status));
+    LocalUResourceBundlePointer languageAlias(
+        ures_getByKey(metadataAlias.getAlias(), "language", nullptr, &status));
+    LocalUResourceBundlePointer scriptAlias(
+        ures_getByKey(metadataAlias.getAlias(), "script", nullptr, &status));
+    LocalUResourceBundlePointer territoryAlias(
+        ures_getByKey(metadataAlias.getAlias(), "territory", nullptr, &status));
+    LocalUResourceBundlePointer variantAlias(
+        ures_getByKey(metadataAlias.getAlias(), "variant", nullptr, &status));
+
+    if (U_FAILURE(status)) {
+        return nullptr;
+    }
+    int32_t languagesLength = 0, scriptLength = 0, territoryLength = 0,
+            variantLength = 0;
+
+    // Read the languageAlias into languageTypes, languageReplacementIndexes
+    // and strings
+    UniqueCharStrings strings(status);
+    LocalMemory<const char*> languageTypes;
+    LocalMemory<int32_t> languageReplacementIndexes;
+    readLanguageAlias(languageAlias.getAlias(),
+                      &strings,
+                      languageTypes,
+                      languageReplacementIndexes,
+                      languagesLength,
+                      status);
+
+    // Read the scriptAlias into scriptTypes, scriptReplacementIndexes
+    // and strings
+    LocalMemory<const char*> scriptTypes;
+    LocalMemory<int32_t> scriptReplacementIndexes;
+    readScriptAlias(scriptAlias.getAlias(),
+                    &strings,
+                    scriptTypes,
+                    scriptReplacementIndexes,
+                    scriptLength,
+                    status);
+
+    // Read the territoryAlias into territoryTypes, territoryReplacementIndexes
+    // and strings
+    LocalMemory<const char*> territoryTypes;
+    LocalMemory<int32_t> territoryReplacementIndexes;
+    readTerritoryAlias(territoryAlias.getAlias(),
+                       &strings,
+                       territoryTypes,
+                       territoryReplacementIndexes,
+                       territoryLength, status);
+
+    // Read the variantAlias into variantTypes, variantReplacementIndexes
+    // and strings
+    LocalMemory<const char*> variantTypes;
+    LocalMemory<int32_t> variantReplacementIndexes;
+    readVariantAlias(variantAlias.getAlias(),
+                     &strings,
+                     variantTypes,
+                     variantReplacementIndexes,
+                     variantLength, status);
+
+    if (U_FAILURE(status)) {
+        return nullptr;
+    }
+
+    // We can only use strings after freeze it.
+    strings.freeze();
+
+    // Build the languageMap from languageTypes & languageReplacementIndexes
+    CharStringMap languageMap(490, status);
+    for (int32_t i = 0; U_SUCCESS(status) && i < languagesLength; i++) {
+        languageMap.put(languageTypes[i],
+                        strings.get(languageReplacementIndexes[i]),
+                        status);
+    }
+
+    // Build the scriptMap from scriptTypes & scriptReplacementIndexes
+    CharStringMap scriptMap(1, status);
+    for (int32_t i = 0; U_SUCCESS(status) && i < scriptLength; i++) {
+        scriptMap.put(scriptTypes[i],
+                      strings.get(scriptReplacementIndexes[i]),
+                      status);
+    }
+
+    // Build the territoryMap from territoryTypes & territoryReplacementIndexes
+    CharStringMap territoryMap(650, status);
+    for (int32_t i = 0; U_SUCCESS(status) && i < territoryLength; i++) {
+        territoryMap.put(territoryTypes[i],
+                         strings.get(territoryReplacementIndexes[i]),
+                         status);
+    }
+
+    // Build the variantMap from variantTypes & variantReplacementIndexes.
+    CharStringMap variantMap(2, status);
+    for (int32_t i = 0; U_SUCCESS(status) && i < variantLength; i++) {
+        variantMap.put(variantTypes[i],
+                       strings.get(variantReplacementIndexes[i]),
+                       status);
+    }
+
+    if (U_FAILURE(status)) {
+        return nullptr;
+    }
+
+    // copy hashtables
+    auto *data = new AliasData(
+        std::move(languageMap),
+        std::move(scriptMap),
+        std::move(territoryMap),
+        std::move(variantMap),
+        strings.orphanCharStrings());
+
+    if (data == nullptr) {
+        status = U_MEMORY_ALLOCATION_ERROR;
+    }
+    return data;
+}
+
+/**
+ * A class that find the replacement values of locale fields by using AliasData.
+ */
+class AliasReplacer {
+public:
+    AliasReplacer(UErrorCode status) :
+            language(nullptr), script(nullptr), region(nullptr),
+            extensions(nullptr), variants(status),
+            data(nullptr) {
+    }
+    ~AliasReplacer() {
+    }
+
+    // Check the fields inside locale, if need to replace fields,
+    // place the the replaced locale ID in out and return true.
+    // Otherwise return false for no replacement or error.
+    bool replace(
+        const Locale& locale, CharString& out, UErrorCode status);
+
+private:
+    const char* language;
+    const char* script;
+    const char* region;
+    const char* extensions;
+    UVector variants;
+
+    const AliasData* data;
+
+    inline bool notEmpty(const char* str) {
+        return str && str[0] != NULL_CHAR;
+    }
+
+    /**
+     * If replacement is neither null nor empty and input is either null or empty,
+     * return replacement.
+     * If replacement is neither null nor empty but input is not empty, return input.
+     * If replacement is either null or empty and type is either null or empty,
+     * return input.
+     * Otherwise return null.
+     *   replacement     input      type        return
+     *    AAA             nullptr    *           AAA
+     *    AAA             BBB        *           BBB
+     *    nullptr || ""   CCC        nullptr     CCC
+     *    nullptr || ""   *          DDD         nullptr
+     */
+    inline const char* deleteOrReplace(
+            const char* input, const char* type, const char* replacement) {
+        return notEmpty(replacement) ?
+            ((input == nullptr) ?  replacement : input) :
+            ((type == nullptr) ? input  : nullptr);
+    }
+
+    inline bool same(const char* a, const char* b) {
+        if (a == nullptr && b == nullptr) {
+            return true;
+        }
+        if ((a == nullptr && b != nullptr) ||
+            (a != nullptr && b == nullptr)) {
+          return false;
+        }
+        return uprv_strcmp(a, b) == 0;
+    }
+
+    // Gather fields and generate locale ID into out.
+    CharString& outputToString(CharString& out, UErrorCode status);
+
+    // Generate the lookup key.
+    CharString& generateKey(const char* language, const char* region,
+                            const char* variant, CharString& out,
+                            UErrorCode status);
+
+    void parseLanguageReplacement(const char* replacement,
+                                  const char*& replaceLanguage,
+                                  const char*& replaceScript,
+                                  const char*& replaceRegion,
+                                  const char*& replaceVariant,
+                                  const char*& replaceExtensions,
+                                  UVector& toBeFreed,
+                                  UErrorCode& status);
+
+    // Replace by using languageAlias.
+    bool replaceLanguage(bool checkLanguage, bool checkRegion,
+                         bool checkVariants, UVector& toBeFreed,
+                         UErrorCode& status);
+
+    // Replace by using territoryAlias.
+    bool replaceTerritory(UVector& toBeFreed, UErrorCode& status);
+
+    // Replace by using scriptAlias.
+    bool replaceScript(UErrorCode& status);
+
+    // Replace by using variantAlias.
+    bool replaceVariant(UErrorCode& status);
+};
+
+CharString&
+AliasReplacer::generateKey(
+        const char* language, const char* region, const char* variant,
+        CharString& out, UErrorCode status)
+{
+    out.append(language, status);
+    if (notEmpty(region)) {
+        out.append(SEP_CHAR, status)
+            .append(region, status);
+    }
+    if (notEmpty(variant)) {
+       out.append(SEP_CHAR, status)
+           .append(variant, status);
+    }
+    return out;
+}
+
+void
+AliasReplacer::parseLanguageReplacement(
+    const char* replacement,
+    const char*& replacedLanguage,
+    const char*& replacedScript,
+    const char*& replacedRegion,
+    const char*& replacedVariant,
+    const char*& replacedExtensions,
+    UVector& toBeFreed,
+    UErrorCode& status)
+{
+    if (U_FAILURE(status)) {
+        return;
+    }
+    replacedScript = replacedRegion = replacedVariant
+        = replacedExtensions = nullptr;
+    if (uprv_strchr(replacement, '_') == nullptr) {
+        replacedLanguage = replacement;
+        // reach the end, just return it.
+        return;
+    }
+    // We have multiple field so we have to allocate and parse
+    CharString* str = new CharString(
+        replacement, (int32_t)uprv_strlen(replacement), status);
+    if (U_FAILURE(status)) {
+        return;
+    }
+    if (str == nullptr) {
+        status = U_MEMORY_ALLOCATION_ERROR;
+        return;
+    }
+    toBeFreed.addElement(str, status);
+    char* data = str->data();
+    replacedLanguage = (const char*) data;
+    char* endOfField = uprv_strchr(data, '_');
+    *endOfField = '\0'; // null terminiate it.
+    endOfField++;
+    const char* start = endOfField;
+    endOfField = (char*) uprv_strchr(start, '_');
+    size_t len = 0;
+    if (endOfField == nullptr) {
+        len = uprv_strlen(start);
+    } else {
+        len = endOfField - start;
+        *endOfField = '\0'; // null terminiate it.
+    }
+    if (len == 4 && uprv_isASCIILetter(*start)) {
+        // Got a script
+        replacedScript = start;
+        if (endOfField == nullptr) {
+            return;
+        }
+        start = endOfField++;
+        endOfField = (char*)uprv_strchr(start, '_');
+        if (endOfField == nullptr) {
+            len = uprv_strlen(start);
+        } else {
+            len = endOfField - start;
+            *endOfField = '\0'; // null terminiate it.
+        }
+    }
+    if (len >= 2 && len <= 3) {
+        // Got a region
+        replacedRegion = start;
+        if (endOfField == nullptr) {
+            return;
+        }
+        start = endOfField++;
+        endOfField = (char*)uprv_strchr(start, '_');
+        if (endOfField == nullptr) {
+            len = uprv_strlen(start);
+        } else {
+            len = endOfField - start;
+            *endOfField = '\0'; // null terminiate it.
+        }
+    }
+    if (len >= 4) {
+        // Got a variant
+        replacedVariant = start;
+        if (endOfField == nullptr) {
+            return;
+        }
+        start = endOfField++;
+    }
+    replacedExtensions = start;
+}
+
+bool
+AliasReplacer::replaceLanguage(
+        bool checkLanguage, bool checkRegion,
+        bool checkVariants, UVector& toBeFreed, UErrorCode& status)
+{
+    if (U_FAILURE(status)) {
+        return false;
+    }
+    if (    (checkRegion && region == nullptr) ||
+            (checkVariants && variants.size() == 0)) {
+        // Nothing to search.
+        return false;
+    }
+    int32_t variant_size = checkVariants ? variants.size() : 1;
+    // Since we may have more than one variant, we need to loop through them.
+    const char* searchLanguage = checkLanguage ? language : "und";
+    const char* searchRegion = checkRegion ? region : nullptr;
+    const char* searchVariant = nullptr;
+    for (int32_t variant_index = 0;
+            variant_index < variant_size;
+            variant_index++) {
+        if (checkVariants) {
+            U_ASSERT(variant_index < variant_size);
+            searchVariant = (const char*)(variants.elementAt(variant_index));
+        }
+
+        if (searchVariant != nullptr && uprv_strlen(searchVariant) < 4) {
+            // Do not consider  ill-formed variant subtag.
+            searchVariant = nullptr;
+        }
+        CharString typeKey;
+        generateKey(searchLanguage, searchRegion, searchVariant, typeKey,
+                    status);
+        if (U_FAILURE(status)) {
+            return false;
+        }
+        const char *replacement = data->languageMap().get(typeKey.data());
+        if (replacement == nullptr) {
+            // Found no replacement data.
+            continue;
+        }
+
+        const char* replacedLanguage = nullptr;
+        const char* replacedScript = nullptr;
+        const char* replacedRegion = nullptr;
+        const char* replacedVariant = nullptr;
+        const char* replacedExtensions = nullptr;
+        parseLanguageReplacement(replacement,
+                                 replacedLanguage,
+                                 replacedScript,
+                                 replacedRegion,
+                                 replacedVariant,
+                                 replacedExtensions,
+                                 toBeFreed,
+                                 status);
+        replacedLanguage =
+            (replacedLanguage != nullptr && uprv_strcmp(replacedLanguage, "und") == 0) ?
+            language : replacedLanguage;
+        replacedScript = deleteOrReplace(script, nullptr, replacedScript);
+        replacedRegion = deleteOrReplace(region, searchRegion, replacedRegion);
+        replacedVariant = deleteOrReplace(
+            searchVariant, searchVariant, replacedVariant);
+
+        if (    same(language, replacedLanguage) &&
+                same(script, replacedScript) &&
+                same(region, replacedRegion) &&
+                same(searchVariant, replacedVariant) &&
+                replacedExtensions == nullptr) {
+            // Replacement produce no changes.
+            continue;
+        }
+
+        language = replacedLanguage;
+        region = replacedRegion;
+        script = replacedScript;
+        if (searchVariant != nullptr) {
+            if (notEmpty(replacedVariant)) {
+                variants.setElementAt((void*)replacedVariant, variant_index);
+            } else {
+                variants.removeElementAt(variant_index);
+            }
+        }
+        if (replacedExtensions != nullptr) {
+            // TODO(ICU-21292)
+            // DO NOTHING
+            // UTS35 does not specifiy what should we do if we have extensions in the
+            // replacement. Currently we know only the following 4 "BCP47 LegacyRules" have
+            // extensions in them languageAlias:
+            //  i_default => en_x_i_default
+            //  i_enochian => und_x_i_enochian
+            //  i_mingo => see_x_i_mingo
+            //  zh_min => nan_x_zh_min
+            // But all of them are already changed by code inside ultag_parse() before
+            // hitting this code.
+        }
+
+        // Something changed by language alias data.
+        return true;
+    }
+    // Nothing changed by language alias data.
+    return false;
+}
+
+bool
+AliasReplacer::replaceTerritory(UVector& toBeFreed, UErrorCode& status)
+{
+    if (U_FAILURE(status)) {
+        return false;
+    }
+    if (region == nullptr) {
+        // No region to search.
+        return false;
+    }
+    const char *replacement = data->territoryMap().get(region);
+    if (replacement == nullptr) {
+        // Found no replacement data for this region.
+        return false;
+    }
+    const char* replacedRegion = replacement;
+    const char* firstSpace = uprv_strchr(replacement, ' ');
+    if (firstSpace != nullptr) {
+        // If there are are more than one region in the replacement.
+        // We need to check which one match based on the language.
+        // Cannot use nullptr for language because that will construct
+        // the default locale, in that case, use "und" to get the correct
+        // locale.
+        Locale l = LocaleBuilder()
+            .setLanguage(language == nullptr ? "und" : language)
+            .setScript(script)
+            .build(status);
+        l.addLikelySubtags(status);
+        const char* likelyRegion = l.getCountry();
+        CharString* item = nullptr;
+        if (likelyRegion != nullptr && uprv_strlen(likelyRegion) > 0) {
+            size_t len = uprv_strlen(likelyRegion);
+            const char* foundInReplacement = uprv_strstr(replacement,
+                                                         likelyRegion);
+            if (foundInReplacement != nullptr) {
+                // Assuming the case there are no three letter region code in
+                // the replacement of territoryAlias
+                U_ASSERT(foundInReplacement == replacement ||
+                         *(foundInReplacement-1) == ' ');
+                U_ASSERT(foundInReplacement[len] == ' ' ||
+                         foundInReplacement[len] == '\0');
+                item = new CharString(foundInReplacement, (int32_t)len, status);
+            }
+        }
+        if (item == nullptr) {
+            item = new CharString(replacement,
+                                  (int32_t)(firstSpace - replacement), status);
+        }
+        if (U_FAILURE(status)) { return false; }
+        if (item == nullptr) {
+            status = U_MEMORY_ALLOCATION_ERROR;
+            return false;
+        }
+        replacedRegion = item->data();
+        toBeFreed.addElement(item, status);
+    }
+    U_ASSERT(!same(region, replacedRegion));
+    region = replacedRegion;
+    // The region is changed by data in territory alias.
+    return true;
+}
+
+bool
+AliasReplacer::replaceScript(UErrorCode& status)
+{
+    if (U_FAILURE(status)) {
+        return false;
+    }
+    if (script == nullptr) {
+        // No script to search.
+        return false;
+    }
+    const char *replacement = data->scriptMap().get(script);
+    if (replacement == nullptr) {
+        // Found no replacement data for this script.
+        return false;
+    }
+    U_ASSERT(!same(script, replacement));
+    script = replacement;
+    // The script is changed by data in script alias.
+    return true;
+}
+
+bool
+AliasReplacer::replaceVariant(UErrorCode& status)
+{
+    if (U_FAILURE(status)) {
+        return false;
+    }
+    // Since we may have more than one variant, we need to loop through them.
+    for (int32_t i = 0; i < variants.size(); i++) {
+        const char *variant = (const char*)(variants.elementAt(i));
+        const char *replacement = data->variantMap().get(variant);
+        if (replacement == nullptr) {
+            // Found no replacement data for this variant.
+            continue;
+        }
+        U_ASSERT((uprv_strlen(replacement) >= 5  &&
+                  uprv_strlen(replacement) <= 8) ||
+                 (uprv_strlen(replacement) == 4 &&
+                  replacement[0] >= '0' &&
+                  replacement[0] <= '9'));
+        if (!same(variant, replacement)) {
+            variants.setElementAt((void*)replacement, i);
+            // Special hack to handle hepburn-heploc => alalc97
+            if (uprv_strcmp(variant, "heploc") == 0) {
+                for (int32_t j = 0; j < variants.size(); j++) {
+                     if (uprv_strcmp((const char*)(variants.elementAt(j)),
+                                     "hepburn") == 0) {
+                         variants.removeElementAt(j);
+                     }
+                }
+            }
+            return true;
+        }
+    }
+    return false;
+}
+
+CharString&
+AliasReplacer::outputToString(
+    CharString& out, UErrorCode status)
+{
+    out.append(language, status);
+    if (notEmpty(script)) {
+        out.append(SEP_CHAR, status)
+            .append(script, status);
+    }
+    if (notEmpty(region)) {
+        out.append(SEP_CHAR, status)
+            .append(region, status);
+    }
+    if (variants.size() > 0) {
+        if (!notEmpty(script) && !notEmpty(region)) {
+          out.append(SEP_CHAR, status);
+        }
+        variants.sort([](UElement e1, UElement e2) -> int8_t {
+            return uprv_strcmp(
+                (const char*)e1.pointer, (const char*)e2.pointer);
+        }, status);
+        int32_t variantsStart = out.length();
+        for (int32_t i = 0; i < variants.size(); i++) {
+             out.append(SEP_CHAR, status)
+                 .append((const char*)(variants.elementAt(i)),
+                         status);
+        }
+        T_CString_toUpperCase(out.data() + variantsStart);
+    }
+    if (notEmpty(extensions)) {
+        CharString tmp("und_", status);
+        tmp.append(extensions, status);
+        Locale tmpLocale(tmp.data());
+        // only support x extension inside CLDR for now.
+        U_ASSERT(extensions[0] == 'x');
+        out.append(tmpLocale.getName() + 1, status);
+    }
+    return out;
+}
+
+bool
+AliasReplacer::replace(const Locale& locale, CharString& out, UErrorCode status)
+{
+    data = AliasData::singleton(status);
+    if (U_FAILURE(status)) {
+        return false;
+    }
+    U_ASSERT(data != nullptr);
+    out.clear();
+    language = locale.getLanguage();
+    if (!notEmpty(language)) {
+        language = nullptr;
+    }
+    script = locale.getScript();
+    if (!notEmpty(script)) {
+        script = nullptr;
+    }
+    region = locale.getCountry();
+    if (!notEmpty(region)) {
+        region = nullptr;
+    }
+    const char* variantsStr = locale.getVariant();
+    const char* extensionsStr = locale_getKeywordsStart(locale.getName());
+    CharString variantsBuff(variantsStr, -1, status);
+    if (!variantsBuff.isEmpty()) {
+        if (U_FAILURE(status)) { return false; }
+        char* start = variantsBuff.data();
+        T_CString_toLowerCase(start);
+        char* end;
+        while ((end = uprv_strchr(start, SEP_CHAR)) != nullptr &&
+               U_SUCCESS(status)) {
+            *end = NULL_CHAR;  // null terminate inside variantsBuff
+            variants.addElement(start, status);
+            start = end + 1;
+        }
+        variants.addElement(start, status);
+    }
+    if (U_FAILURE(status)) { return false; }
+
+    // Sort the variants
+    variants.sort([](UElement e1, UElement e2) -> int8_t {
+        return uprv_strcmp(
+            (const char*)e1.pointer, (const char*)e2.pointer);
+    }, status);
+
+    // A changed count to assert when loop too many times.
+    int changed = 0;
+    // A UVector to to hold CharString allocated by the replace* method
+    // and freed when out of scope from his function.
+    UVector stringsToBeFreed([](void *obj){ delete ((CharString*) obj); },
+                             nullptr, 10, status);
+    while (U_SUCCESS(status)) {
+        // Something wrong with the data cause looping here more than 10 times
+        // already.
+        U_ASSERT(changed < 5);
+        // From observation of key in data/misc/metadata.txt
+        // we know currently we only need to search in the following combination
+        // of fields for type in languageAlias:
+        // * lang_region_variant
+        // * lang_region
+        // * lang_variant
+        // * lang
+        // * und_variant
+        // This assumption is ensured by the U_ASSERT in readLanguageAlias
+        //
+        //                      lang  REGION variant
+        if (    replaceLanguage(true, true,  true,  stringsToBeFreed, status) ||
+                replaceLanguage(true, true,  false, stringsToBeFreed, status) ||
+                replaceLanguage(true, false, true,  stringsToBeFreed, status) ||
+                replaceLanguage(true, false, false, stringsToBeFreed, status) ||
+                replaceLanguage(false,false, true,  stringsToBeFreed, status) ||
+                replaceTerritory(stringsToBeFreed, status) ||
+                replaceScript(status) ||
+                replaceVariant(status)) {
+            // Some values in data is changed, try to match from the beginning
+            // again.
+            changed++;
+            continue;
+        }
+        // Nothing changed. Break out.
+        break;
+    }  // while(1)
+
+    if (U_FAILURE(status)) { return false; }
+    // Nothing changed and we know the order of the vaiants are not change
+    // because we have no variant or only one.
+    if (changed == 0 && variants.size() <= 1) {
+        return false;
+    }
+    outputToString(out, status);
+    if (extensionsStr != nullptr) {
+        out.append(extensionsStr, status);
+    }
+    if (U_FAILURE(status)) {
+        return false;
+    }
+    // If the tag is not changed, return.
+    if (uprv_strcmp(out.data(), locale.getName()) == 0) {
+        U_ASSERT(changed == 0);
+        U_ASSERT(variants.size() > 1);
+        out.clear();
+        return false;
+    }
+    return true;
+}
+
+// Return true if the locale is changed during canonicalization.
+// The replaced value then will be put into out.
+bool
+canonicalizeLocale(const Locale& locale, CharString& out, UErrorCode& status)
+{
+    AliasReplacer replacer(status);
+    return replacer.replace(locale, out, status);
+}
+
+// Function to optimize for known cases without so we can skip the loading
+// of resources in the startup time until we really need it.
+bool
+isKnownCanonicalizedLocale(const char* locale, UErrorCode& status)
+{
+    if (    uprv_strcmp(locale, "c") == 0 ||
+            uprv_strcmp(locale, "en") == 0 ||
+            uprv_strcmp(locale, "en_US") == 0) {
+        return true;
+    }
+
+    // common well-known Canonicalized.
+    umtx_initOnce(gKnownCanonicalizedInitOnce,
+                  &loadKnownCanonicalized, status);
+    if (U_FAILURE(status)) {
+        return false;
+    }
+    U_ASSERT(gKnownCanonicalized != nullptr);
+    return uhash_geti(gKnownCanonicalized, locale) != 0;
+}
+
+}  // namespace
+
+// Function for testing.
+U_CAPI const char* const*
+ulocimp_getKnownCanonicalizedLocaleForTest(int32_t* length)
+{
+    *length = UPRV_LENGTHOF(KNOWN_CANONICALIZED);
+    return KNOWN_CANONICALIZED;
+}
+
+// Function for testing.
+U_CAPI bool
+ulocimp_isCanonicalizedLocaleForTest(const char* localeName)
+{
+    Locale l(localeName);
+    UErrorCode status = U_ZERO_ERROR;
+    CharString temp;
+    return !canonicalizeLocale(l, temp, status) && U_SUCCESS(status);
+}
 
 /*This function initializes a Locale from a C locale ID*/
 Locale& Locale::init(const char* localeID, UBool canonicalize)
@@ -535,9 +1694,13 @@
         variantBegin = length;
 
         /* after uloc_getName/canonicalize() we know that only '_' are separators */
+        /* But _ could also appeared in timezone such as "en@timezone=America/Los_Angeles" */
         separator = field[0] = fullName;
         fieldIdx = 1;
-        while ((separator = uprv_strchr(field[fieldIdx-1], SEP_CHAR)) && fieldIdx < (int32_t)(sizeof(field)/sizeof(field[0]))-1) {
+        char* at = uprv_strchr(fullName, '@');
+        while ((separator = uprv_strchr(field[fieldIdx-1], SEP_CHAR)) != 0 &&
+               fieldIdx < UPRV_LENGTHOF(field)-1 &&
+               (at == nullptr || separator < at)) {
             field[fieldIdx] = separator + 1;
             fieldLen[fieldIdx-1] = (int32_t)(separator - field[fieldIdx-1]);
             fieldIdx++;
@@ -565,9 +1728,9 @@
             uprv_memcpy(language, fullName, fieldLen[0]);
             language[fieldLen[0]] = 0;
         }
-        if (fieldLen[1] == 4 && ISASCIIALPHA(field[1][0]) &&
-                ISASCIIALPHA(field[1][1]) && ISASCIIALPHA(field[1][2]) &&
-                ISASCIIALPHA(field[1][3])) {
+        if (fieldLen[1] == 4 && uprv_isASCIILetter(field[1][0]) &&
+                uprv_isASCIILetter(field[1][1]) && uprv_isASCIILetter(field[1][2]) &&
+                uprv_isASCIILetter(field[1][3])) {
             /* We have at least a script */
             uprv_memcpy(script, field[1], fieldLen[1]);
             script[fieldLen[1]] = 0;
@@ -594,6 +1757,21 @@
             break;
         }
 
+        if (canonicalize) {
+            if (!isKnownCanonicalizedLocale(fullName, err)) {
+                CharString replaced;
+                // Not sure it is already canonicalized
+                if (canonicalizeLocale(*this, replaced, err)) {
+                    U_ASSERT(U_SUCCESS(err));
+                    // If need replacement, call init again.
+                    init(replaced.data(), false);
+                }
+                if (U_FAILURE(err)) {
+                    break;
+                }
+            }
+        }   // if (canonicalize) {
+
         // successful end of init()
         return *this;
     } while(0); /*loop doesn't iterate*/
@@ -644,7 +1822,7 @@
 int32_t
 Locale::hashCode() const
 {
-    return ustr_hashCharsN(fullName, uprv_strlen(fullName));
+    return ustr_hashCharsN(fullName, static_cast<int32_t>(uprv_strlen(fullName)));
 }
 
 void
@@ -663,6 +1841,7 @@
     *script = 0;
     *country = 0;
     fIsBogus = TRUE;
+    variantBegin = 0;
 }
 
 const Locale& U_EXPORT2
@@ -695,6 +1874,132 @@
     locale_set_default_internal(localeID, status);
 }
 
+void
+Locale::addLikelySubtags(UErrorCode& status) {
+    if (U_FAILURE(status)) {
+        return;
+    }
+
+    CharString maximizedLocaleID;
+    {
+        CharStringByteSink sink(&maximizedLocaleID);
+        ulocimp_addLikelySubtags(fullName, sink, &status);
+    }
+
+    if (U_FAILURE(status)) {
+        return;
+    }
+
+    init(maximizedLocaleID.data(), /*canonicalize=*/FALSE);
+    if (isBogus()) {
+        status = U_ILLEGAL_ARGUMENT_ERROR;
+    }
+}
+
+void
+Locale::minimizeSubtags(UErrorCode& status) {
+    if (U_FAILURE(status)) {
+        return;
+    }
+
+    CharString minimizedLocaleID;
+    {
+        CharStringByteSink sink(&minimizedLocaleID);
+        ulocimp_minimizeSubtags(fullName, sink, &status);
+    }
+
+    if (U_FAILURE(status)) {
+        return;
+    }
+
+    init(minimizedLocaleID.data(), /*canonicalize=*/FALSE);
+    if (isBogus()) {
+        status = U_ILLEGAL_ARGUMENT_ERROR;
+    }
+}
+
+void
+Locale::canonicalize(UErrorCode& status) {
+    if (U_FAILURE(status)) {
+        return;
+    }
+    if (isBogus()) {
+        status = U_ILLEGAL_ARGUMENT_ERROR;
+        return;
+    }
+    CharString uncanonicalized(fullName, status);
+    if (U_FAILURE(status)) {
+        return;
+    }
+    init(uncanonicalized.data(), /*canonicalize=*/TRUE);
+    if (isBogus()) {
+        status = U_ILLEGAL_ARGUMENT_ERROR;
+    }
+}
+
+Locale U_EXPORT2
+Locale::forLanguageTag(StringPiece tag, UErrorCode& status)
+{
+    Locale result(Locale::eBOGUS);
+
+    if (U_FAILURE(status)) {
+        return result;
+    }
+
+    // If a BCP 47 language tag is passed as the language parameter to the
+    // normal Locale constructor, it will actually fall back to invoking
+    // uloc_forLanguageTag() to parse it if it somehow is able to detect that
+    // the string actually is BCP 47. This works well for things like strings
+    // using BCP 47 extensions, but it does not at all work for things like
+    // legacy language tags (marked as “Type: grandfathered” in BCP 47,
+    // e.g., "en-GB-oed") which are possible to also
+    // interpret as ICU locale IDs and because of that won't trigger the BCP 47
+    // parsing. Therefore the code here explicitly calls uloc_forLanguageTag()
+    // and then Locale::init(), instead of just calling the normal constructor.
+
+    CharString localeID;
+    int32_t parsedLength;
+    {
+        CharStringByteSink sink(&localeID);
+        ulocimp_forLanguageTag(
+                tag.data(),
+                tag.length(),
+                sink,
+                &parsedLength,
+                &status);
+    }
+
+    if (U_FAILURE(status)) {
+        return result;
+    }
+
+    if (parsedLength != tag.size()) {
+        status = U_ILLEGAL_ARGUMENT_ERROR;
+        return result;
+    }
+
+    result.init(localeID.data(), /*canonicalize=*/FALSE);
+    if (result.isBogus()) {
+        status = U_ILLEGAL_ARGUMENT_ERROR;
+    }
+    return result;
+}
+
+void
+Locale::toLanguageTag(ByteSink& sink, UErrorCode& status) const
+{
+    if (U_FAILURE(status)) {
+        return;
+    }
+
+    if (fIsBogus) {
+        status = U_ILLEGAL_ARGUMENT_ERROR;
+        return;
+    }
+
+    ulocimp_toLanguageTag(fullName, sink, /*strict=*/FALSE, &status);
+}
+
 Locale U_EXPORT2
 Locale::createFromName (const char *name)
 {
@@ -1001,20 +2306,84 @@
     uprv_free(keywords);
 }
 
+// A wrapper around KeywordEnumeration that calls uloc_toUnicodeLocaleKey() in
+// the next() method for each keyword before returning it.
+class UnicodeKeywordEnumeration : public KeywordEnumeration {
+public:
+    using KeywordEnumeration::KeywordEnumeration;
+    virtual ~UnicodeKeywordEnumeration();
+
+    virtual const char* next(int32_t* resultLength, UErrorCode& status) {
+        const char* legacy_key = KeywordEnumeration::next(nullptr, status);
+        if (U_SUCCESS(status) && legacy_key != nullptr) {
+            const char* key = uloc_toUnicodeLocaleKey(legacy_key);
+            if (key == nullptr) {
+                status = U_ILLEGAL_ARGUMENT_ERROR;
+            } else {
+                if (resultLength != nullptr) {
+                    *resultLength = static_cast<int32_t>(uprv_strlen(key));
+                }
+                return key;
+            }
+        }
+        if (resultLength != nullptr) *resultLength = 0;
+        return nullptr;
+    }
+};
+
+// Out-of-line virtual destructor to serve as the "key function".
+UnicodeKeywordEnumeration::~UnicodeKeywordEnumeration() = default;
+
 StringEnumeration *
 Locale::createKeywords(UErrorCode &status) const
 {
-    char keywords[256];
-    int32_t keywordCapacity = 256;
     StringEnumeration *result = NULL;
 
+    if (U_FAILURE(status)) {
+        return result;
+    }
+
     const char* variantStart = uprv_strchr(fullName, '@');
     const char* assignment = uprv_strchr(fullName, '=');
     if(variantStart) {
         if(assignment > variantStart) {
-            int32_t keyLen = locale_getKeywords(variantStart+1, '@', keywords, keywordCapacity, NULL, 0, NULL, FALSE, &status);
-            if(keyLen) {
-                result = new KeywordEnumeration(keywords, keyLen, 0, status);
+            CharString keywords;
+            CharStringByteSink sink(&keywords);
+            ulocimp_getKeywords(variantStart+1, '@', sink, FALSE, &status);
+            if (U_SUCCESS(status) && !keywords.isEmpty()) {
+                result = new KeywordEnumeration(keywords.data(), keywords.length(), 0, status);
+                if (!result) {
+                    status = U_MEMORY_ALLOCATION_ERROR;
+                }
+            }
+        } else {
+            status = U_INVALID_FORMAT_ERROR;
+        }
+    }
+    return result;
+}
+
+StringEnumeration *
+Locale::createUnicodeKeywords(UErrorCode &status) const
+{
+    StringEnumeration *result = NULL;
+
+    if (U_FAILURE(status)) {
+        return result;
+    }
+
+    const char* variantStart = uprv_strchr(fullName, '@');
+    const char* assignment = uprv_strchr(fullName, '=');
+    if(variantStart) {
+        if(assignment > variantStart) {
+            CharString keywords;
+            CharStringByteSink sink(&keywords);
+            ulocimp_getKeywords(variantStart+1, '@', sink, FALSE, &status);
+            if (U_SUCCESS(status) && !keywords.isEmpty()) {
+                result = new UnicodeKeywordEnumeration(keywords.data(), keywords.length(), 0, status);
+                if (!result) {
+                    status = U_MEMORY_ALLOCATION_ERROR;
+                }
             }
         } else {
             status = U_INVALID_FORMAT_ERROR;
@@ -1030,19 +2399,152 @@
 }
 
 void
+Locale::getKeywordValue(StringPiece keywordName, ByteSink& sink, UErrorCode& status) const {
+    if (U_FAILURE(status)) {
+        return;
+    }
+
+    if (fIsBogus) {
+        status = U_ILLEGAL_ARGUMENT_ERROR;
+        return;
+    }
+
+    // TODO: Remove the need for a const char* to a NUL terminated buffer.
+    const CharString keywordName_nul(keywordName, status);
+    if (U_FAILURE(status)) {
+        return;
+    }
+
+    ulocimp_getKeywordValue(fullName, keywordName_nul.data(), sink, &status);
+}
+
+void
+Locale::getUnicodeKeywordValue(StringPiece keywordName,
+                               ByteSink& sink,
+                               UErrorCode& status) const {
+    // TODO: Remove the need for a const char* to a NUL terminated buffer.
+    const CharString keywordName_nul(keywordName, status);
+    if (U_FAILURE(status)) {
+        return;
+    }
+
+    const char* legacy_key = uloc_toLegacyKey(keywordName_nul.data());
+
+    if (legacy_key == nullptr) {
+        status = U_ILLEGAL_ARGUMENT_ERROR;
+        return;
+    }
+
+    CharString legacy_value;
+    {
+        CharStringByteSink sink(&legacy_value);
+        getKeywordValue(legacy_key, sink, status);
+    }
+
+    if (U_FAILURE(status)) {
+        return;
+    }
+
+    const char* unicode_value = uloc_toUnicodeLocaleType(
+            keywordName_nul.data(), legacy_value.data());
+
+    if (unicode_value == nullptr) {
+        status = U_ILLEGAL_ARGUMENT_ERROR;
+        return;
+    }
+
+    sink.Append(unicode_value, static_cast<int32_t>(uprv_strlen(unicode_value)));
+}
+
+void
 Locale::setKeywordValue(const char* keywordName, const char* keywordValue, UErrorCode &status)
 {
-    uloc_setKeywordValue(keywordName, keywordValue, fullName, ULOC_FULLNAME_CAPACITY, &status);
+    if (U_FAILURE(status)) {
+        return;
+    }
+    if (status == U_STRING_NOT_TERMINATED_WARNING) {
+        status = U_ZERO_ERROR;
+    }
+    int32_t bufferLength = uprv_max((int32_t)(uprv_strlen(fullName) + 1), ULOC_FULLNAME_CAPACITY);
+    int32_t newLength = uloc_setKeywordValue(keywordName, keywordValue, fullName,
+                                             bufferLength, &status) + 1;
+    U_ASSERT(status != U_STRING_NOT_TERMINATED_WARNING);
+    /* Handle the case the current buffer is not enough to hold the new id */
+    if (status == U_BUFFER_OVERFLOW_ERROR) {
+        U_ASSERT(newLength > bufferLength);
+        char* newFullName = (char *)uprv_malloc(newLength);
+        if (newFullName == nullptr) {
+            status = U_MEMORY_ALLOCATION_ERROR;
+            return;
+        }
+        uprv_strcpy(newFullName, fullName);
+        if (fullName != fullNameBuffer) {
+            // if full Name is already on the heap, need to free it.
+            uprv_free(fullName);
+        }
+        fullName = newFullName;
+        status = U_ZERO_ERROR;
+        uloc_setKeywordValue(keywordName, keywordValue, fullName, newLength, &status);
+        U_ASSERT(status != U_STRING_NOT_TERMINATED_WARNING);
+    } else {
+        U_ASSERT(newLength <= bufferLength);
+    }
     if (U_SUCCESS(status) && baseName == fullName) {
         // May have added the first keyword, meaning that the fullName is no longer also the baseName.
         initBaseName(status);
     }
 }
 
+void
+Locale::setKeywordValue(StringPiece keywordName,
+                        StringPiece keywordValue,
+                        UErrorCode& status) {
+    // TODO: Remove the need for a const char* to a NUL terminated buffer.
+    const CharString keywordName_nul(keywordName, status);
+    const CharString keywordValue_nul(keywordValue, status);
+    setKeywordValue(keywordName_nul.data(), keywordValue_nul.data(), status);
+}
+
+void
+Locale::setUnicodeKeywordValue(StringPiece keywordName,
+                               StringPiece keywordValue,
+                               UErrorCode& status) {
+    // TODO: Remove the need for a const char* to a NUL terminated buffer.
+    const CharString keywordName_nul(keywordName, status);
+    const CharString keywordValue_nul(keywordValue, status);
+
+    if (U_FAILURE(status)) {
+        return;
+    }
+
+    const char* legacy_key = uloc_toLegacyKey(keywordName_nul.data());
+
+    if (legacy_key == nullptr) {
+        status = U_ILLEGAL_ARGUMENT_ERROR;
+        return;
+    }
+
+    const char* legacy_value = nullptr;
+
+    if (!keywordValue_nul.isEmpty()) {
+        legacy_value =
+            uloc_toLegacyType(keywordName_nul.data(), keywordValue_nul.data());
+
+        if (legacy_value == nullptr) {
+            status = U_ILLEGAL_ARGUMENT_ERROR;
+            return;
+        }
+    }
+
+    setKeywordValue(legacy_key, legacy_value, status);
+}
+
 const char *
 Locale::getBaseName() const {
     return baseName;
 }
 
+Locale::Iterator::~Iterator() = default;
+
 //eof
 U_NAMESPACE_END
diff --git a/src/third_party/icu/source/common/loclikely.cpp b/src/third_party/icu/source/common/loclikely.cpp
index 60bc208..5c9b7d7 100644
--- a/src/third_party/icu/source/common/loclikely.cpp
+++ b/src/third_party/icu/source/common/loclikely.cpp
@@ -1,12 +1,14 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
-*   Copyright (C) 1997-2014, International Business Machines
+*   Copyright (C) 1997-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *
 *******************************************************************************
 *   file name:  loclikely.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -17,19 +19,32 @@
 *   that then do not depend on resource bundle code and likely-subtags data.
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
+#include "unicode/bytestream.h"
 #include "unicode/utypes.h"
 #include "unicode/locid.h"
 #include "unicode/putil.h"
+#include "unicode/uchar.h"
 #include "unicode/uloc.h"
 #include "unicode/ures.h"
 #include "unicode/uscript.h"
+#include "bytesinkutil.h"
+#include "charstr.h"
 #include "cmemory.h"
 #include "cstring.h"
 #include "ulocimp.h"
 #include "ustr_imp.h"
 
 /**
+ * These are the canonical strings for unknown languages, scripts and regions.
+ **/
+static const char* const unknownLanguage = "und";
+static const char* const unknownScript = "Zzzz";
+static const char* const unknownRegion = "ZZ";
+
+/**
  * This function looks for the localeID in the likelySubtags resource.
  *
  * @param localeID The tag to find.
@@ -48,9 +63,22 @@
         int32_t resLen = 0;
         const UChar* s = NULL;
         UErrorCode tmpErr = U_ZERO_ERROR;
-        UResourceBundle* subtags = ures_openDirect(NULL, "likelySubtags", &tmpErr);
+        icu::LocalUResourceBundlePointer subtags(ures_openDirect(NULL, "likelySubtags", &tmpErr));
         if (U_SUCCESS(tmpErr)) {
-            s = ures_getStringByKey(subtags, localeID, &resLen, &tmpErr);
+            icu::CharString und;
+            if (localeID != NULL) {
+                if (*localeID == '\0') {
+                    localeID = unknownLanguage;
+                } else if (*localeID == '_') {
+                    und.append(unknownLanguage, *err);
+                    und.append(localeID, *err);
+                    if (U_FAILURE(*err)) {
+                        return NULL;
+                    }
+                    localeID = und.data();
+                }
+            }
+            s = ures_getStringByKey(subtags.getAlias(), localeID, &resLen, &tmpErr);
 
             if (U_FAILURE(tmpErr)) {
                 /*
@@ -67,10 +95,13 @@
             }
             else {
                 u_UCharsToChars(s, buffer, resLen + 1);
+                if (resLen >= 3 &&
+                    uprv_strnicmp(buffer, unknownLanguage, 3) == 0 &&
+                    (resLen == 3 || buffer[3] == '_')) {
+                    uprv_memmove(buffer, buffer + 3, resLen - 3 + 1);
+                }
                 result = buffer;
             }
-
-            ures_close(subtags);
         } else {
             *err = tmpErr;
         }
@@ -94,9 +125,10 @@
     const char* tag,
     int32_t tagLength,
     char* buffer,
-    int32_t* bufferLength) {
+    int32_t* bufferLength,
+    UBool withSeparator) {
 
-    if (*bufferLength > 0) {
+    if (withSeparator) {
         buffer[*bufferLength] = '_';
         ++(*bufferLength);
     }
@@ -110,13 +142,6 @@
 }
 
 /**
- * These are the canonical strings for unknown languages, scripts and regions.
- **/
-static const char* const unknownLanguage = "und";
-static const char* const unknownScript = "Zzzz";
-static const char* const unknownRegion = "ZZ";
-
-/**
  * Create a tag string from the supplied parameters.  The lang, script and region
  * parameters may be NULL pointers. If they are, their corresponding length parameters
  * must be less than or equal to 0.
@@ -145,12 +170,10 @@
  * @param trailing Any trailing data to append to the new tag.
  * @param trailingLength The length of the trailing data.
  * @param alternateTags A string containing any alternate tags.
- * @param tag The output buffer.
- * @param tagCapacity The capacity of the output buffer.
+ * @param sink The output sink receiving the tag string.
  * @param err A pointer to a UErrorCode for error reporting.
- * @return The length of the tag string, which may be greater than tagCapacity, or -1 on error.
  **/
-static int32_t U_CALLCONV
+static void U_CALLCONV
 createTagStringWithAlternates(
     const char* lang,
     int32_t langLength,
@@ -161,16 +184,13 @@
     const char* trailing,
     int32_t trailingLength,
     const char* alternateTags,
-    char* tag,
-    int32_t tagCapacity,
+    icu::ByteSink& sink,
     UErrorCode* err) {
 
     if (U_FAILURE(*err)) {
         goto error;
     }
-    else if (tag == NULL ||
-             tagCapacity <= 0 ||
-             langLength >= ULOC_LANG_CAPACITY ||
+    else if (langLength >= ULOC_LANG_CAPACITY ||
              scriptLength >= ULOC_SCRIPT_CAPACITY ||
              regionLength >= ULOC_COUNTRY_CAPACITY) {
         goto error;
@@ -184,7 +204,6 @@
          **/
         char tagBuffer[ULOC_FULLNAME_CAPACITY];
         int32_t tagLength = 0;
-        int32_t capacityRemaining = tagCapacity;
         UBool regionAppended = FALSE;
 
         if (langLength > 0) {
@@ -192,18 +211,14 @@
                 lang,
                 langLength,
                 tagBuffer,
-                &tagLength);
+                &tagLength,
+                /*withSeparator=*/FALSE);
         }
         else if (alternateTags == NULL) {
             /*
-             * Append the value for an unknown language, if
+             * Use the empty string for an unknown language, if
              * we found no language.
              */
-            appendTag(
-                unknownLanguage,
-                (int32_t)uprv_strlen(unknownLanguage),
-                tagBuffer,
-                &tagLength);
         }
         else {
             /*
@@ -224,21 +239,17 @@
             }
             else if (alternateLangLength == 0) {
                 /*
-                 * Append the value for an unknown language, if
+                 * Use the empty string for an unknown language, if
                  * we found no language.
                  */
-                appendTag(
-                    unknownLanguage,
-                    (int32_t)uprv_strlen(unknownLanguage),
-                    tagBuffer,
-                    &tagLength);
             }
             else {
                 appendTag(
                     alternateLang,
                     alternateLangLength,
                     tagBuffer,
-                    &tagLength);
+                    &tagLength,
+                    /*withSeparator=*/FALSE);
             }
         }
 
@@ -247,7 +258,8 @@
                 script,
                 scriptLength,
                 tagBuffer,
-                &tagLength);
+                &tagLength,
+                /*withSeparator=*/TRUE);
         }
         else if (alternateTags != NULL) {
             /*
@@ -271,7 +283,8 @@
                     alternateScript,
                     alternateScriptLength,
                     tagBuffer,
-                    &tagLength);
+                    &tagLength,
+                    /*withSeparator=*/TRUE);
             }
         }
 
@@ -280,7 +293,8 @@
                 region,
                 regionLength,
                 tagBuffer,
-                &tagLength);
+                &tagLength,
+                /*withSeparator=*/TRUE);
 
             regionAppended = TRUE;
         }
@@ -305,61 +319,35 @@
                     alternateRegion,
                     alternateRegionLength,
                     tagBuffer,
-                    &tagLength);
+                    &tagLength,
+                    /*withSeparator=*/TRUE);
 
                 regionAppended = TRUE;
             }
         }
 
-        {
-            const int32_t toCopy =
-                tagLength >= tagCapacity ? tagCapacity : tagLength;
-
-            /**
-             * Copy the partial tag from our internal buffer to the supplied
-             * target.
-             **/
-            uprv_memcpy(
-                tag,
-                tagBuffer,
-                toCopy);
-
-            capacityRemaining -= toCopy;
-        }
+        /**
+         * Copy the partial tag from our internal buffer to the supplied
+         * target.
+         **/
+        sink.Append(tagBuffer, tagLength);
 
         if (trailingLength > 0) {
-            if (*trailing != '@' && capacityRemaining > 0) {
-                tag[tagLength++] = '_';
-                --capacityRemaining;
-                if (capacityRemaining > 0 && !regionAppended) {
+            if (*trailing != '@') {
+                sink.Append("_", 1);
+                if (!regionAppended) {
                     /* extra separator is required */
-                    tag[tagLength++] = '_';
-                    --capacityRemaining;
+                    sink.Append("_", 1);
                 }
             }
 
-            if (capacityRemaining > 0) {
-                /*
-                 * Copy the trailing data into the supplied buffer.  Use uprv_memmove, since we
-                 * don't know if the user-supplied buffers overlap.
-                 */
-                const int32_t toCopy =
-                    trailingLength >= capacityRemaining ? capacityRemaining : trailingLength;
-
-                uprv_memmove(
-                    &tag[tagLength],
-                    trailing,
-                    toCopy);
-            }
+            /*
+             * Copy the trailing data into the supplied buffer.
+             */
+            sink.Append(trailing, trailingLength);
         }
 
-        tagLength += trailingLength;
-
-        return u_terminateChars(
-                    tag,
-                    tagCapacity,
-                    tagLength,
-                    err);
+        return;
     }
 
 error:
@@ -373,8 +361,6 @@
         U_SUCCESS(*err)) {
         *err = U_ILLEGAL_ARGUMENT_ERROR;
     }
-
-    return -1;
 }
 
 /**
@@ -398,12 +384,10 @@
  * @param regionLength The length of the region tag.
  * @param trailing Any trailing data to append to the new tag.
  * @param trailingLength The length of the trailing data.
- * @param tag The output buffer.
- * @param tagCapacity The capacity of the output buffer.
+ * @param sink The output sink receiving the tag string.
  * @param err A pointer to a UErrorCode for error reporting.
- * @return The length of the tag string, which may be greater than tagCapacity.
  **/
-static int32_t U_CALLCONV
+static void U_CALLCONV
 createTagString(
     const char* lang,
     int32_t langLength,
@@ -413,11 +397,10 @@
     int32_t regionLength,
     const char* trailing,
     int32_t trailingLength,
-    char* tag,
-    int32_t tagCapacity,
+    icu::ByteSink& sink,
     UErrorCode* err)
 {
-    return createTagStringWithAlternates(
+    createTagStringWithAlternates(
                 lang,
                 langLength,
                 script,
@@ -427,8 +410,7 @@
                 trailing,
                 trailingLength,
                 NULL,
-                tag,
-                tagCapacity,
+                sink,
                 err);
 }
 
@@ -485,8 +467,7 @@
         goto error;
     }
 
-    subtagLength = ulocimp_getLanguage(position, lang, *langLength, &position);
-    u_terminateChars(lang, *langLength, subtagLength, err);
+    subtagLength = ulocimp_getLanguage(position, &position, *err).extract(lang, *langLength, *err);
 
     /*
      * Note that we explicit consider U_STRING_NOT_TERMINATED_WARNING
@@ -500,21 +481,14 @@
     *langLength = subtagLength;
 
     /*
-     * If no language was present, use the value of unknownLanguage
-     * instead.  Otherwise, move past any separator.
+     * If no language was present, use the empty string instead.
+     * Otherwise, move past any separator.
      */
-    if (*langLength == 0) {
-        uprv_strcpy(
-            lang,
-            unknownLanguage);
-        *langLength = (int32_t)uprv_strlen(lang);
-    }
-    else if (_isIDSeparator(*position)) {
+    if (_isIDSeparator(*position)) {
         ++position;
     }
 
-    subtagLength = ulocimp_getScript(position, script, *scriptLength, &position);
-    u_terminateChars(script, *scriptLength, subtagLength, err);
+    subtagLength = ulocimp_getScript(position, &position, *err).extract(script, *scriptLength, *err);
 
     if(U_FAILURE(*err)) {
         goto error;
@@ -538,8 +512,7 @@
         }    
     }
 
-    subtagLength = ulocimp_getCountry(position, region, *regionLength, &position);
-    u_terminateChars(region, *regionLength, subtagLength, err);
+    subtagLength = ulocimp_getCountry(position, &position, *err).extract(region, *regionLength, *err);
 
     if(U_FAILURE(*err)) {
         goto error;
@@ -576,7 +549,7 @@
     goto exit;
 }
 
-static int32_t U_CALLCONV
+static UBool U_CALLCONV
 createLikelySubtagsString(
     const char* lang,
     int32_t langLength,
@@ -586,17 +559,14 @@
     int32_t regionLength,
     const char* variants,
     int32_t variantsLength,
-    char* tag,
-    int32_t tagCapacity,
-    UErrorCode* err)
-{
+    icu::ByteSink& sink,
+    UErrorCode* err) {
     /**
      * ULOC_FULLNAME_CAPACITY will provide enough capacity
      * that we can build a string that contains the language,
      * script and region code without worrying about overrunning
      * the user-supplied buffer.
      **/
-    char tagBuffer[ULOC_FULLNAME_CAPACITY];
     char likelySubtagsBuffer[ULOC_FULLNAME_CAPACITY];
 
     if(U_FAILURE(*err)) {
@@ -610,25 +580,28 @@
 
         const char* likelySubtags = NULL;
 
-        createTagString(
-            lang,
-            langLength,
-            script,
-            scriptLength,
-            region,
-            regionLength,
-            NULL,
-            0,
-            tagBuffer,
-            sizeof(tagBuffer),
-            err);
+        icu::CharString tagBuffer;
+        {
+            icu::CharStringByteSink sink(&tagBuffer);
+            createTagString(
+                lang,
+                langLength,
+                script,
+                scriptLength,
+                region,
+                regionLength,
+                NULL,
+                0,
+                sink,
+                err);
+        }
         if(U_FAILURE(*err)) {
             goto error;
         }
 
         likelySubtags =
             findLikelySubtags(
-                tagBuffer,
+                tagBuffer.data(),
                 likelySubtagsBuffer,
                 sizeof(likelySubtagsBuffer),
                 err);
@@ -640,7 +613,7 @@
             /* Always use the language tag from the
                maximal string, since it may be more
                specific than the one provided. */
-            return createTagStringWithAlternates(
+            createTagStringWithAlternates(
                         NULL,
                         0,
                         NULL,
@@ -650,9 +623,9 @@
                         variants,
                         variantsLength,
                         likelySubtags,
-                        tag,
-                        tagCapacity,
+                        sink,
                         err);
+            return TRUE;
         }
     }
 
@@ -663,25 +636,28 @@
 
         const char* likelySubtags = NULL;
 
-        createTagString(
-            lang,
-            langLength,
-            script,
-            scriptLength,
-            NULL,
-            0,
-            NULL,
-            0,
-            tagBuffer,
-            sizeof(tagBuffer),
-            err);
+        icu::CharString tagBuffer;
+        {
+            icu::CharStringByteSink sink(&tagBuffer);
+            createTagString(
+                lang,
+                langLength,
+                script,
+                scriptLength,
+                NULL,
+                0,
+                NULL,
+                0,
+                sink,
+                err);
+        }
         if(U_FAILURE(*err)) {
             goto error;
         }
 
         likelySubtags =
             findLikelySubtags(
-                tagBuffer,
+                tagBuffer.data(),
                 likelySubtagsBuffer,
                 sizeof(likelySubtagsBuffer),
                 err);
@@ -693,7 +669,7 @@
             /* Always use the language tag from the
                maximal string, since it may be more
                specific than the one provided. */
-            return createTagStringWithAlternates(
+            createTagStringWithAlternates(
                         NULL,
                         0,
                         NULL,
@@ -703,9 +679,9 @@
                         variants,
                         variantsLength,
                         likelySubtags,
-                        tag,
-                        tagCapacity,
+                        sink,
                         err);
+            return TRUE;
         }
     }
 
@@ -716,25 +692,28 @@
 
         const char* likelySubtags = NULL;
 
-        createTagString(
-            lang,
-            langLength,
-            NULL,
-            0,
-            region,
-            regionLength,
-            NULL,
-            0,
-            tagBuffer,
-            sizeof(tagBuffer),
-            err);
+        icu::CharString tagBuffer;
+        {
+            icu::CharStringByteSink sink(&tagBuffer);
+            createTagString(
+                lang,
+                langLength,
+                NULL,
+                0,
+                region,
+                regionLength,
+                NULL,
+                0,
+                sink,
+                err);
+        }
         if(U_FAILURE(*err)) {
             goto error;
         }
 
         likelySubtags =
             findLikelySubtags(
-                tagBuffer,
+                tagBuffer.data(),
                 likelySubtagsBuffer,
                 sizeof(likelySubtagsBuffer),
                 err);
@@ -746,7 +725,7 @@
             /* Always use the language tag from the
                maximal string, since it may be more
                specific than the one provided. */
-            return createTagStringWithAlternates(
+            createTagStringWithAlternates(
                         NULL,
                         0,
                         script,
@@ -756,9 +735,9 @@
                         variants,
                         variantsLength,
                         likelySubtags,
-                        tag,
-                        tagCapacity,
+                        sink,
                         err);
+            return TRUE;
         }
     }
 
@@ -768,25 +747,28 @@
     {
         const char* likelySubtags = NULL;
 
-        createTagString(
-            lang,
-            langLength,
-            NULL,
-            0,
-            NULL,
-            0,
-            NULL,
-            0,
-            tagBuffer,
-            sizeof(tagBuffer),
-            err);
+        icu::CharString tagBuffer;
+        {
+            icu::CharStringByteSink sink(&tagBuffer);
+            createTagString(
+                lang,
+                langLength,
+                NULL,
+                0,
+                NULL,
+                0,
+                NULL,
+                0,
+                sink,
+                err);
+        }
         if(U_FAILURE(*err)) {
             goto error;
         }
 
         likelySubtags =
             findLikelySubtags(
-                tagBuffer,
+                tagBuffer.data(),
                 likelySubtagsBuffer,
                 sizeof(likelySubtagsBuffer),
                 err);
@@ -798,7 +780,7 @@
             /* Always use the language tag from the
                maximal string, since it may be more
                specific than the one provided. */
-            return createTagStringWithAlternates(
+            createTagStringWithAlternates(
                         NULL,
                         0,
                         script,
@@ -808,17 +790,13 @@
                         variants,
                         variantsLength,
                         likelySubtags,
-                        tag,
-                        tagCapacity,
+                        sink,
                         err);
+            return TRUE;
         }
     }
 
-    return u_terminateChars(
-                tag,
-                tagCapacity,
-                0,
-                err);
+    return FALSE;
 
 error:
 
@@ -826,34 +804,32 @@
         *err = U_ILLEGAL_ARGUMENT_ERROR;
     }
 
-    return -1;
+    return FALSE;
 }
 
-#define CHECK_TRAILING_VARIANT_SIZE(trailing, trailingLength) \
-    {   int32_t count = 0; \
-        int32_t i; \
-        for (i = 0; i < trailingLength; i++) { \
-            if (trailing[i] == '-' || trailing[i] == '_') { \
-                count = 0; \
-                if (count > 8) { \
-                    goto error; \
-                } \
-            } else if (trailing[i] == '@') { \
-                break; \
-            } else if (count > 8) { \
+#define CHECK_TRAILING_VARIANT_SIZE(trailing, trailingLength) UPRV_BLOCK_MACRO_BEGIN { \
+    int32_t count = 0; \
+    int32_t i; \
+    for (i = 0; i < trailingLength; i++) { \
+        if (trailing[i] == '-' || trailing[i] == '_') { \
+            count = 0; \
+            if (count > 8) { \
                 goto error; \
-            } else { \
-                count++; \
             } \
+        } else if (trailing[i] == '@') { \
+            break; \
+        } else if (count > 8) { \
+            goto error; \
+        } else { \
+            count++; \
         } \
-    }
+    } \
+} UPRV_BLOCK_MACRO_END
 
-static int32_t
-_uloc_addLikelySubtags(const char*    localeID,
-         char* maximizedLocaleID,
-         int32_t maximizedLocaleIDCapacity,
-         UErrorCode* err)
-{
+static UBool
+_uloc_addLikelySubtags(const char* localeID,
+                       icu::ByteSink& sink,
+                       UErrorCode* err) {
     char lang[ULOC_LANG_CAPACITY];
     int32_t langLength = sizeof(lang);
     char script[ULOC_SCRIPT_CAPACITY];
@@ -863,14 +839,12 @@
     const char* trailing = "";
     int32_t trailingLength = 0;
     int32_t trailingIndex = 0;
-    int32_t resultLength = 0;
+    UBool success = FALSE;
 
     if(U_FAILURE(*err)) {
         goto error;
     }
-    else if (localeID == NULL ||
-             maximizedLocaleID == NULL ||
-             maximizedLocaleIDCapacity <= 0) {
+    if (localeID == NULL) {
         goto error;
     }
 
@@ -901,7 +875,7 @@
 
     CHECK_TRAILING_VARIANT_SIZE(trailing, trailingLength);
 
-    resultLength =
+    success =
         createLikelySubtagsString(
             lang,
             langLength,
@@ -911,55 +885,39 @@
             regionLength,
             trailing,
             trailingLength,
-            maximizedLocaleID,
-            maximizedLocaleIDCapacity,
+            sink,
             err);
 
-    if (resultLength == 0) {
+    if (!success) {
         const int32_t localIDLength = (int32_t)uprv_strlen(localeID);
 
         /*
          * If we get here, we need to return localeID.
          */
-        uprv_memcpy(
-            maximizedLocaleID,
-            localeID,
-            localIDLength <= maximizedLocaleIDCapacity ? 
-                localIDLength : maximizedLocaleIDCapacity);
-
-        resultLength =
-            u_terminateChars(
-                maximizedLocaleID,
-                maximizedLocaleIDCapacity,
-                localIDLength,
-                err);
+        sink.Append(localeID, localIDLength);
     }
 
-    return resultLength;
+    return success;
 
 error:
 
     if (!U_FAILURE(*err)) {
         *err = U_ILLEGAL_ARGUMENT_ERROR;
     }
-
-    return -1;
+    return FALSE;
 }
 
-static int32_t
-_uloc_minimizeSubtags(const char*    localeID,
-         char* minimizedLocaleID,
-         int32_t minimizedLocaleIDCapacity,
-         UErrorCode* err)
-{
-    /**
-     * ULOC_FULLNAME_CAPACITY will provide enough capacity
-     * that we can build a string that contains the language,
-     * script and region code without worrying about overrunning
-     * the user-supplied buffer.
-     **/
-    char maximizedTagBuffer[ULOC_FULLNAME_CAPACITY];
-    int32_t maximizedTagBufferLength = sizeof(maximizedTagBuffer);
+// Add likely subtags to the sink
+// return true if the value in the sink is produced by a match during the lookup
+// return false if the value in the sink is the same as input because there are
+// no match after the lookup.
+static UBool _ulocimp_addLikelySubtags(const char*, icu::ByteSink&, UErrorCode*);
+
+static void
+_uloc_minimizeSubtags(const char* localeID,
+                      icu::ByteSink& sink,
+                      UErrorCode* err) {
+    icu::CharString maximizedTagBuffer;
 
     char lang[ULOC_LANG_CAPACITY];
     int32_t langLength = sizeof(lang);
@@ -970,13 +928,12 @@
     const char* trailing = "";
     int32_t trailingLength = 0;
     int32_t trailingIndex = 0;
+    UBool successGetMax = FALSE;
 
     if(U_FAILURE(*err)) {
         goto error;
     }
-    else if (localeID == NULL ||
-             minimizedLocaleID == NULL ||
-             minimizedLocaleIDCapacity <= 0) {
+    else if (localeID == NULL) {
         goto error;
     }
 
@@ -1009,33 +966,60 @@
 
     CHECK_TRAILING_VARIANT_SIZE(trailing, trailingLength);
 
-    createTagString(
-        lang,
-        langLength,
-        script,
-        scriptLength,
-        region,
-        regionLength,
-        NULL,
-        0,
-        maximizedTagBuffer,
-        maximizedTagBufferLength,
-        err);
+    {
+        icu::CharString base;
+        {
+            icu::CharStringByteSink baseSink(&base);
+            createTagString(
+                lang,
+                langLength,
+                script,
+                scriptLength,
+                region,
+                regionLength,
+                NULL,
+                0,
+                baseSink,
+                err);
+        }
+
+        /**
+         * First, we need to first get the maximization
+         * from AddLikelySubtags.
+         **/
+        {
+            icu::CharStringByteSink maxSink(&maximizedTagBuffer);
+            successGetMax = _ulocimp_addLikelySubtags(base.data(), maxSink, err);
+        }
+    }
+
     if(U_FAILURE(*err)) {
         goto error;
     }
 
-    /**
-     * First, we need to first get the maximization
-     * from AddLikelySubtags.
-     **/
-    maximizedTagBufferLength =
-        uloc_addLikelySubtags(
-            maximizedTagBuffer,
-            maximizedTagBuffer,
-            maximizedTagBufferLength,
-            err);
+    if (!successGetMax) {
+        /**
+         * If we got here, return the locale ID parameter unchanged.
+         **/
+        const int32_t localeIDLength = (int32_t)uprv_strlen(localeID);
+        sink.Append(localeID, localeIDLength);
+        return;
+    }
 
+    // In the following, the lang, script, region are referring to those in
+    // the maximizedTagBuffer, not the one in the localeID.
+    langLength = sizeof(lang);
+    scriptLength = sizeof(script);
+    regionLength = sizeof(region);
+    parseTagString(
+        maximizedTagBuffer.data(),
+        lang,
+        &langLength,
+        script,
+        &scriptLength,
+        region,
+        &regionLength,
+        err);
     if(U_FAILURE(*err)) {
         goto error;
     }
@@ -1044,9 +1028,9 @@
      * Start first with just the language.
      **/
     {
-        char tagBuffer[ULOC_FULLNAME_CAPACITY];
-
-        const int32_t tagBufferLength =
+        icu::CharString tagBuffer;
+        {
+            icu::CharStringByteSink tagSink(&tagBuffer);
             createLikelySubtagsString(
                 lang,
                 langLength,
@@ -1056,19 +1040,20 @@
                 0,
                 NULL,
                 0,
-                tagBuffer,
-                sizeof(tagBuffer),
+                tagSink,
                 err);
+        }
 
         if(U_FAILURE(*err)) {
             goto error;
         }
-        else if (uprv_strnicmp(
-                    maximizedTagBuffer,
-                    tagBuffer,
-                    tagBufferLength) == 0) {
+        else if (!tagBuffer.isEmpty() &&
+                 uprv_strnicmp(
+                    maximizedTagBuffer.data(),
+                    tagBuffer.data(),
+                    tagBuffer.length()) == 0) {
 
-            return createTagString(
+            createTagString(
                         lang,
                         langLength,
                         NULL,
@@ -1077,9 +1062,9 @@
                         0,
                         trailing,
                         trailingLength,
-                        minimizedLocaleID,
-                        minimizedLocaleIDCapacity,
+                        sink,
                         err);
+            return;
         }
     }
 
@@ -1088,9 +1073,9 @@
      **/
     if (regionLength > 0) {
 
-        char tagBuffer[ULOC_FULLNAME_CAPACITY];
-
-        const int32_t tagBufferLength =
+        icu::CharString tagBuffer;
+        {
+            icu::CharStringByteSink tagSink(&tagBuffer);
             createLikelySubtagsString(
                 lang,
                 langLength,
@@ -1100,19 +1085,20 @@
                 regionLength,
                 NULL,
                 0,
-                tagBuffer,
-                sizeof(tagBuffer),
+                tagSink,
                 err);
+        }
 
         if(U_FAILURE(*err)) {
             goto error;
         }
-        else if (uprv_strnicmp(
-                    maximizedTagBuffer,
-                    tagBuffer,
-                    tagBufferLength) == 0) {
+        else if (!tagBuffer.isEmpty() &&
+                 uprv_strnicmp(
+                    maximizedTagBuffer.data(),
+                    tagBuffer.data(),
+                    tagBuffer.length()) == 0) {
 
-            return createTagString(
+            createTagString(
                         lang,
                         langLength,
                         NULL,
@@ -1121,9 +1107,9 @@
                         regionLength,
                         trailing,
                         trailingLength,
-                        minimizedLocaleID,
-                        minimizedLocaleIDCapacity,
+                        sink,
                         err);
+            return;
         }
     }
 
@@ -1132,10 +1118,10 @@
      * since trying with all three subtags would only yield the
      * maximal version that we already have.
      **/
-    if (scriptLength > 0 && regionLength > 0) {
-        char tagBuffer[ULOC_FULLNAME_CAPACITY];
-
-        const int32_t tagBufferLength =
+    if (scriptLength > 0) {
+        icu::CharString tagBuffer;
+        {
+            icu::CharStringByteSink tagSink(&tagBuffer);
             createLikelySubtagsString(
                 lang,
                 langLength,
@@ -1145,19 +1131,20 @@
                 0,
                 NULL,
                 0,
-                tagBuffer,
-                sizeof(tagBuffer),
+                tagSink,
                 err);
+        }
 
         if(U_FAILURE(*err)) {
             goto error;
         }
-        else if (uprv_strnicmp(
-                    maximizedTagBuffer,
-                    tagBuffer,
-                    tagBufferLength) == 0) {
+        else if (!tagBuffer.isEmpty() &&
+                 uprv_strnicmp(
+                    maximizedTagBuffer.data(),
+                    tagBuffer.data(),
+                    tagBuffer.length()) == 0) {
 
-            return createTagString(
+            createTagString(
                         lang,
                         langLength,
                         script,
@@ -1166,29 +1153,28 @@
                         0,
                         trailing,
                         trailingLength,
-                        minimizedLocaleID,
-                        minimizedLocaleIDCapacity,
+                        sink,
                         err);
+            return;
         }
     }
 
     {
         /**
-         * If we got here, return the locale ID parameter.
+         * If we got here, return the max + trail.
          **/
-        const int32_t localeIDLength = (int32_t)uprv_strlen(localeID);
-
-        uprv_memcpy(
-            minimizedLocaleID,
-            localeID,
-            localeIDLength <= minimizedLocaleIDCapacity ? 
-                localeIDLength : minimizedLocaleIDCapacity);
-
-        return u_terminateChars(
-                    minimizedLocaleID,
-                    minimizedLocaleIDCapacity,
-                    localeIDLength,
+        createTagString(
+                    lang,
+                    langLength,
+                    script,
+                    scriptLength,
+                    region,
+                    regionLength,
+                    trailing,
+                    trailingLength,
+                    sink,
                     err);
+        return;
     }
 
 error:
@@ -1196,10 +1182,6 @@
     if (!U_FAILURE(*err)) {
         *err = U_ILLEGAL_ARGUMENT_ERROR;
     }
-
-    return -1;
-
-
 }
 
 static UBool
@@ -1230,59 +1212,99 @@
 }
 
 U_CAPI int32_t U_EXPORT2
-uloc_addLikelySubtags(const char*    localeID,
-         char* maximizedLocaleID,
-         int32_t maximizedLocaleIDCapacity,
-         UErrorCode* err)
-{
+uloc_addLikelySubtags(const char* localeID,
+                      char* maximizedLocaleID,
+                      int32_t maximizedLocaleIDCapacity,
+                      UErrorCode* status) {
+    if (U_FAILURE(*status)) {
+        return 0;
+    }
+
+    icu::CheckedArrayByteSink sink(
+            maximizedLocaleID, maximizedLocaleIDCapacity);
+
+    ulocimp_addLikelySubtags(localeID, sink, status);
+    int32_t reslen = sink.NumberOfBytesAppended();
+
+    if (U_FAILURE(*status)) {
+        return sink.Overflowed() ? reslen : -1;
+    }
+
+    if (sink.Overflowed()) {
+        *status = U_BUFFER_OVERFLOW_ERROR;
+    } else {
+        u_terminateChars(
+                maximizedLocaleID, maximizedLocaleIDCapacity, reslen, status);
+    }
+
+    return reslen;
+}
+
+static UBool
+_ulocimp_addLikelySubtags(const char* localeID,
+                          icu::ByteSink& sink,
+                          UErrorCode* status) {
     char localeBuffer[ULOC_FULLNAME_CAPACITY];
 
-    if (!do_canonicalize(
-        localeID,
-        localeBuffer,
-        sizeof(localeBuffer),
-        err)) {
-        return -1;
+    if (do_canonicalize(localeID, localeBuffer, sizeof localeBuffer, status)) {
+        return _uloc_addLikelySubtags(localeBuffer, sink, status);
     }
-    else {
-        return _uloc_addLikelySubtags(
-                    localeBuffer,
-                    maximizedLocaleID,
-                    maximizedLocaleIDCapacity,
-                    err);
-    }    
+    return FALSE;
+}
+
+U_CAPI void U_EXPORT2
+ulocimp_addLikelySubtags(const char* localeID,
+                         icu::ByteSink& sink,
+                         UErrorCode* status) {
+    _ulocimp_addLikelySubtags(localeID, sink, status);
 }
 
 U_CAPI int32_t U_EXPORT2
-uloc_minimizeSubtags(const char*    localeID,
-         char* minimizedLocaleID,
-         int32_t minimizedLocaleIDCapacity,
-         UErrorCode* err)
-{
+uloc_minimizeSubtags(const char* localeID,
+                     char* minimizedLocaleID,
+                     int32_t minimizedLocaleIDCapacity,
+                     UErrorCode* status) {
+    if (U_FAILURE(*status)) {
+        return 0;
+    }
+
+    icu::CheckedArrayByteSink sink(
+            minimizedLocaleID, minimizedLocaleIDCapacity);
+
+    ulocimp_minimizeSubtags(localeID, sink, status);
+    int32_t reslen = sink.NumberOfBytesAppended();
+
+    if (U_FAILURE(*status)) {
+        return sink.Overflowed() ? reslen : -1;
+    }
+
+    if (sink.Overflowed()) {
+        *status = U_BUFFER_OVERFLOW_ERROR;
+    } else {
+        u_terminateChars(
+                minimizedLocaleID, minimizedLocaleIDCapacity, reslen, status);
+    }
+
+    return reslen;
+}
+
+U_CAPI void U_EXPORT2
+ulocimp_minimizeSubtags(const char* localeID,
+                        icu::ByteSink& sink,
+                        UErrorCode* status) {
     char localeBuffer[ULOC_FULLNAME_CAPACITY];
 
-    if (!do_canonicalize(
-        localeID,
-        localeBuffer,
-        sizeof(localeBuffer),
-        err)) {
-        return -1;
+    if (do_canonicalize(localeID, localeBuffer, sizeof localeBuffer, status)) {
+        _uloc_minimizeSubtags(localeBuffer, sink, status);
     }
-    else {
-        return _uloc_minimizeSubtags(
-                    localeBuffer,
-                    minimizedLocaleID,
-                    minimizedLocaleIDCapacity,
-                    err);
-    }    
 }
 
 // Pairs of (language subtag, + or -) for finding out fast if common languages
 // are LTR (minus) or RTL (plus).
-static const char* LANG_DIR_STRING =
+static const char LANG_DIR_STRING[] =
         "root-en-es-pt-zh-ja-ko-de-fr-it-ar+he+fa+ru-nl-pl-th-tr-";
 
-// Implemented here because this calls uloc_addLikelySubtags().
+// Implemented here because this calls ulocimp_addLikelySubtags().
 U_CAPI UBool U_EXPORT2
 uloc_isRightToLeft(const char *locale) {
     UErrorCode errorCode = U_ZERO_ERROR;
@@ -1295,26 +1317,30 @@
         errorCode = U_ZERO_ERROR;
         char lang[8];
         int32_t langLength = uloc_getLanguage(locale, lang, UPRV_LENGTHOF(lang), &errorCode);
-        if (U_FAILURE(errorCode) || errorCode == U_STRING_NOT_TERMINATED_WARNING ||
-                langLength == 0) {
+        if (U_FAILURE(errorCode) || errorCode == U_STRING_NOT_TERMINATED_WARNING) {
             return FALSE;
         }
-        const char* langPtr = uprv_strstr(LANG_DIR_STRING, lang);
-        if (langPtr != NULL) {
-            switch (langPtr[langLength]) {
-            case '-': return FALSE;
-            case '+': return TRUE;
-            default: break;  // partial match of a longer code
+        if (langLength > 0) {
+            const char* langPtr = uprv_strstr(LANG_DIR_STRING, lang);
+            if (langPtr != NULL) {
+                switch (langPtr[langLength]) {
+                case '-': return FALSE;
+                case '+': return TRUE;
+                default: break;  // partial match of a longer code
+                }
             }
         }
         // Otherwise, find the likely script.
         errorCode = U_ZERO_ERROR;
-        char likely[ULOC_FULLNAME_CAPACITY];
-        (void)uloc_addLikelySubtags(locale, likely, UPRV_LENGTHOF(likely), &errorCode);
+        icu::CharString likely;
+        {
+            icu::CharStringByteSink sink(&likely);
+            ulocimp_addLikelySubtags(locale, sink, &errorCode);
+        }
         if (U_FAILURE(errorCode) || errorCode == U_STRING_NOT_TERMINATED_WARNING) {
             return FALSE;
         }
-        scriptLength = uloc_getScript(likely, script, UPRV_LENGTHOF(script), &errorCode);
+        scriptLength = uloc_getScript(likely.data(), script, UPRV_LENGTHOF(script), &errorCode);
         if (U_FAILURE(errorCode) || errorCode == U_STRING_NOT_TERMINATED_WARNING ||
                 scriptLength == 0) {
             return FALSE;
@@ -1332,3 +1358,56 @@
 }
 
 U_NAMESPACE_END
+
+// The following must at least allow for rg key value (6) plus terminator (1).
+#define ULOC_RG_BUFLEN 8
+
+U_CAPI int32_t U_EXPORT2
+ulocimp_getRegionForSupplementalData(const char *localeID, UBool inferRegion,
+                                     char *region, int32_t regionCapacity, UErrorCode* status) {
+    if (U_FAILURE(*status)) {
+        return 0;
+    }
+    char rgBuf[ULOC_RG_BUFLEN];
+    UErrorCode rgStatus = U_ZERO_ERROR;
+
+    // First check for rg keyword value
+    int32_t rgLen = uloc_getKeywordValue(localeID, "rg", rgBuf, ULOC_RG_BUFLEN, &rgStatus);
+    if (U_FAILURE(rgStatus) || rgLen != 6) {
+        rgLen = 0;
+    } else {
+        // rgBuf guaranteed to be zero terminated here, with text len 6
+        char *rgPtr = rgBuf;
+        for (; *rgPtr!= 0; rgPtr++) {
+            *rgPtr = uprv_toupper(*rgPtr);
+        }
+        rgLen = (uprv_strcmp(rgBuf+2, "ZZZZ") == 0)? 2: 0;
+    }
+
+    if (rgLen == 0) {
+        // No valid rg keyword value, try for unicode_region_subtag
+        rgLen = uloc_getCountry(localeID, rgBuf, ULOC_RG_BUFLEN, status);
+        if (U_FAILURE(*status)) {
+            rgLen = 0;
+        } else if (rgLen == 0 && inferRegion) {
+            // no unicode_region_subtag but inferRegion TRUE, try likely subtags
+            rgStatus = U_ZERO_ERROR;
+            icu::CharString locBuf;
+            {
+                icu::CharStringByteSink sink(&locBuf);
+                ulocimp_addLikelySubtags(localeID, sink, &rgStatus);
+            }
+            if (U_SUCCESS(rgStatus)) {
+                rgLen = uloc_getCountry(locBuf.data(), rgBuf, ULOC_RG_BUFLEN, status);
+                if (U_FAILURE(*status)) {
+                    rgLen = 0;
+                }
+            }
+        }
+    }
+
+    rgBuf[rgLen] = 0;
+    uprv_strncpy(region, rgBuf, regionCapacity);
+    return u_terminateChars(region, regionCapacity, rgLen, status);
+}
+
diff --git a/src/third_party/icu/source/common/loclikelysubtags.cpp b/src/third_party/icu/source/common/loclikelysubtags.cpp
new file mode 100644
index 0000000..a031bfa
--- /dev/null
+++ b/src/third_party/icu/source/common/loclikelysubtags.cpp
@@ -0,0 +1,682 @@
+// © 2019 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+// loclikelysubtags.cpp
+// created: 2019may08 Markus W. Scherer
+
+#include <utility>
+#include "unicode/utypes.h"
+#include "unicode/bytestrie.h"
+#include "unicode/localpointer.h"
+#include "unicode/locid.h"
+#include "unicode/uobject.h"
+#include "unicode/ures.h"
+#include "charstr.h"
+#include "cstring.h"
+#include "loclikelysubtags.h"
+#include "lsr.h"
+#include "uassert.h"
+#include "ucln_cmn.h"
+#include "uhash.h"
+#include "uinvchar.h"
+#include "umutex.h"
+#include "uniquecharstr.h"
+#include "uresdata.h"
+#include "uresimp.h"
+
+U_NAMESPACE_BEGIN
+
+namespace {
+
+constexpr char PSEUDO_ACCENTS_PREFIX = '\'';  // -XA, -PSACCENT
+constexpr char PSEUDO_BIDI_PREFIX = '+';  // -XB, -PSBIDI
+constexpr char PSEUDO_CRACKED_PREFIX = ',';  // -XC, -PSCRACK
+
+}  // namespace
+
+LocaleDistanceData::LocaleDistanceData(LocaleDistanceData &&data) :
+        distanceTrieBytes(data.distanceTrieBytes),
+        regionToPartitions(data.regionToPartitions),
+        partitions(data.partitions),
+        paradigms(data.paradigms), paradigmsLength(data.paradigmsLength),
+        distances(data.distances) {
+    data.partitions = nullptr;
+    data.paradigms = nullptr;
+}
+
+LocaleDistanceData::~LocaleDistanceData() {
+    uprv_free(partitions);
+    delete[] paradigms;
+}
+
+// TODO(ICU-20777): Rename to just LikelySubtagsData.
+struct XLikelySubtagsData {
+    UResourceBundle *langInfoBundle = nullptr;
+    UniqueCharStrings strings;
+    CharStringMap languageAliases;
+    CharStringMap regionAliases;
+    const uint8_t *trieBytes = nullptr;
+    LSR *lsrs = nullptr;
+    int32_t lsrsLength = 0;
+
+    LocaleDistanceData distanceData;
+
+    XLikelySubtagsData(UErrorCode &errorCode) : strings(errorCode) {}
+
+    ~XLikelySubtagsData() {
+        ures_close(langInfoBundle);
+        delete[] lsrs;
+    }
+
+    void load(UErrorCode &errorCode) {
+        langInfoBundle = ures_openDirect(nullptr, "langInfo", &errorCode);
+        if (U_FAILURE(errorCode)) { return; }
+        StackUResourceBundle stackTempBundle;
+        ResourceDataValue value;
+        ures_getValueWithFallback(langInfoBundle, "likely", stackTempBundle.getAlias(),
+                                  value, errorCode);
+        ResourceTable likelyTable = value.getTable(errorCode);
+        if (U_FAILURE(errorCode)) { return; }
+
+        // Read all strings in the resource bundle and convert them to invariant char *.
+        LocalMemory<int32_t> languageIndexes, regionIndexes, lsrSubtagIndexes;
+        int32_t languagesLength = 0, regionsLength = 0, lsrSubtagsLength = 0;
+        if (!readStrings(likelyTable, "languageAliases", value,
+                         languageIndexes, languagesLength, errorCode) ||
+                !readStrings(likelyTable, "regionAliases", value,
+                             regionIndexes, regionsLength, errorCode) ||
+                !readStrings(likelyTable, "lsrs", value,
+                             lsrSubtagIndexes,lsrSubtagsLength, errorCode)) {
+            return;
+        }
+        if ((languagesLength & 1) != 0 ||
+                (regionsLength & 1) != 0 ||
+                (lsrSubtagsLength % 3) != 0) {
+            errorCode = U_INVALID_FORMAT_ERROR;
+            return;
+        }
+        if (lsrSubtagsLength == 0) {
+            errorCode = U_MISSING_RESOURCE_ERROR;
+            return;
+        }
+
+        if (!likelyTable.findValue("trie", value)) {
+            errorCode = U_MISSING_RESOURCE_ERROR;
+            return;
+        }
+        int32_t length;
+        trieBytes = value.getBinary(length, errorCode);
+        if (U_FAILURE(errorCode)) { return; }
+
+        // Also read distance/matcher data if available,
+        // to open & keep only one resource bundle pointer
+        // and to use one single UniqueCharStrings.
+        UErrorCode matchErrorCode = U_ZERO_ERROR;
+        ures_getValueWithFallback(langInfoBundle, "match", stackTempBundle.getAlias(),
+                                  value, matchErrorCode);
+        LocalMemory<int32_t> partitionIndexes, paradigmSubtagIndexes;
+        int32_t partitionsLength = 0, paradigmSubtagsLength = 0;
+        if (U_SUCCESS(matchErrorCode)) {
+            ResourceTable matchTable = value.getTable(errorCode);
+            if (U_FAILURE(errorCode)) { return; }
+
+            if (matchTable.findValue("trie", value)) {
+                distanceData.distanceTrieBytes = value.getBinary(length, errorCode);
+                if (U_FAILURE(errorCode)) { return; }
+            }
+
+            if (matchTable.findValue("regionToPartitions", value)) {
+                distanceData.regionToPartitions = value.getBinary(length, errorCode);
+                if (U_FAILURE(errorCode)) { return; }
+                if (length < LSR::REGION_INDEX_LIMIT) {
+                    errorCode = U_INVALID_FORMAT_ERROR;
+                    return;
+                }
+            }
+
+            if (!readStrings(matchTable, "partitions", value,
+                             partitionIndexes, partitionsLength, errorCode) ||
+                    !readStrings(matchTable, "paradigms", value,
+                                 paradigmSubtagIndexes, paradigmSubtagsLength, errorCode)) {
+                return;
+            }
+            if ((paradigmSubtagsLength % 3) != 0) {
+                errorCode = U_INVALID_FORMAT_ERROR;
+                return;
+            }
+
+            if (matchTable.findValue("distances", value)) {
+                distanceData.distances = value.getIntVector(length, errorCode);
+                if (U_FAILURE(errorCode)) { return; }
+                if (length < 4) {  // LocaleDistance IX_LIMIT
+                    errorCode = U_INVALID_FORMAT_ERROR;
+                    return;
+                }
+            }
+        } else if (matchErrorCode == U_MISSING_RESOURCE_ERROR) {
+            // ok for likely subtags
+        } else {  // error other than missing resource
+            errorCode = matchErrorCode;
+            return;
+        }
+
+        // Fetch & store invariant-character versions of strings
+        // only after we have collected and de-duplicated all of them.
+        strings.freeze();
+
+        languageAliases = CharStringMap(languagesLength / 2, errorCode);
+        for (int32_t i = 0; i < languagesLength; i += 2) {
+            languageAliases.put(strings.get(languageIndexes[i]),
+                                strings.get(languageIndexes[i + 1]), errorCode);
+        }
+
+        regionAliases = CharStringMap(regionsLength / 2, errorCode);
+        for (int32_t i = 0; i < regionsLength; i += 2) {
+            regionAliases.put(strings.get(regionIndexes[i]),
+                              strings.get(regionIndexes[i + 1]), errorCode);
+        }
+        if (U_FAILURE(errorCode)) { return; }
+
+        lsrsLength = lsrSubtagsLength / 3;
+        lsrs = new LSR[lsrsLength];
+        if (lsrs == nullptr) {
+            errorCode = U_MEMORY_ALLOCATION_ERROR;
+            return;
+        }
+        for (int32_t i = 0, j = 0; i < lsrSubtagsLength; i += 3, ++j) {
+            lsrs[j] = LSR(strings.get(lsrSubtagIndexes[i]),
+                          strings.get(lsrSubtagIndexes[i + 1]),
+                          strings.get(lsrSubtagIndexes[i + 2]),
+                          LSR::IMPLICIT_LSR);
+        }
+
+        if (partitionsLength > 0) {
+            distanceData.partitions = static_cast<const char **>(
+                uprv_malloc(partitionsLength * sizeof(const char *)));
+            if (distanceData.partitions == nullptr) {
+                errorCode = U_MEMORY_ALLOCATION_ERROR;
+                return;
+            }
+            for (int32_t i = 0; i < partitionsLength; ++i) {
+                distanceData.partitions[i] = strings.get(partitionIndexes[i]);
+            }
+        }
+
+        if (paradigmSubtagsLength > 0) {
+            distanceData.paradigmsLength = paradigmSubtagsLength / 3;
+            LSR *paradigms = new LSR[distanceData.paradigmsLength];
+            if (paradigms == nullptr) {
+                errorCode = U_MEMORY_ALLOCATION_ERROR;
+                return;
+            }
+            for (int32_t i = 0, j = 0; i < paradigmSubtagsLength; i += 3, ++j) {
+                paradigms[j] = LSR(strings.get(paradigmSubtagIndexes[i]),
+                                   strings.get(paradigmSubtagIndexes[i + 1]),
+                                   strings.get(paradigmSubtagIndexes[i + 2]),
+                                   LSR::DONT_CARE_FLAGS);
+            }
+            distanceData.paradigms = paradigms;
+        }
+    }
+
+private:
+    bool readStrings(const ResourceTable &table, const char *key, ResourceValue &value,
+                     LocalMemory<int32_t> &indexes, int32_t &length, UErrorCode &errorCode) {
+        if (table.findValue(key, value)) {
+            ResourceArray stringArray = value.getArray(errorCode);
+            if (U_FAILURE(errorCode)) { return false; }
+            length = stringArray.getSize();
+            if (length == 0) { return true; }
+            int32_t *rawIndexes = indexes.allocateInsteadAndCopy(length);
+            if (rawIndexes == nullptr) {
+                errorCode = U_MEMORY_ALLOCATION_ERROR;
+                return false;
+            }
+            for (int i = 0; i < length; ++i) {
+                stringArray.getValue(i, value);  // returns TRUE because i < length
+                rawIndexes[i] = strings.add(value.getUnicodeString(errorCode), errorCode);
+                if (U_FAILURE(errorCode)) { return false; }
+            }
+        }
+        return true;
+    }
+};
+
+namespace {
+
+XLikelySubtags *gLikelySubtags = nullptr;
+UInitOnce gInitOnce = U_INITONCE_INITIALIZER;
+
+UBool U_CALLCONV cleanup() {
+    delete gLikelySubtags;
+    gLikelySubtags = nullptr;
+    gInitOnce.reset();
+    return TRUE;
+}
+
+}  // namespace
+
+void U_CALLCONV XLikelySubtags::initLikelySubtags(UErrorCode &errorCode) {
+    // This function is invoked only via umtx_initOnce().
+    U_ASSERT(gLikelySubtags == nullptr);
+    XLikelySubtagsData data(errorCode);
+    data.load(errorCode);
+    if (U_FAILURE(errorCode)) { return; }
+    gLikelySubtags = new XLikelySubtags(data);
+    if (gLikelySubtags == nullptr) {
+        errorCode = U_MEMORY_ALLOCATION_ERROR;
+        return;
+    }
+    ucln_common_registerCleanup(UCLN_COMMON_LIKELY_SUBTAGS, cleanup);
+}
+
+const XLikelySubtags *XLikelySubtags::getSingleton(UErrorCode &errorCode) {
+    if (U_FAILURE(errorCode)) { return nullptr; }
+    umtx_initOnce(gInitOnce, &XLikelySubtags::initLikelySubtags, errorCode);
+    return gLikelySubtags;
+}
+
+XLikelySubtags::XLikelySubtags(XLikelySubtagsData &data) :
+        langInfoBundle(data.langInfoBundle),
+        strings(data.strings.orphanCharStrings()),
+        languageAliases(std::move(data.languageAliases)),
+        regionAliases(std::move(data.regionAliases)),
+        trie(data.trieBytes),
+        lsrs(data.lsrs),
+#if U_DEBUG
+        lsrsLength(data.lsrsLength),
+#endif
+        distanceData(std::move(data.distanceData)) {
+    data.langInfoBundle = nullptr;
+    data.lsrs = nullptr;
+
+    // Cache the result of looking up language="und" encoded as "*", and "und-Zzzz" ("**").
+    UStringTrieResult result = trie.next(u'*');
+    U_ASSERT(USTRINGTRIE_HAS_NEXT(result));
+    trieUndState = trie.getState64();
+    result = trie.next(u'*');
+    U_ASSERT(USTRINGTRIE_HAS_NEXT(result));
+    trieUndZzzzState = trie.getState64();
+    result = trie.next(u'*');
+    U_ASSERT(USTRINGTRIE_HAS_VALUE(result));
+    defaultLsrIndex = trie.getValue();
+    trie.reset();
+
+    for (char16_t c = u'a'; c <= u'z'; ++c) {
+        result = trie.next(c);
+        if (result == USTRINGTRIE_NO_VALUE) {
+            trieFirstLetterStates[c - u'a'] = trie.getState64();
+        }
+        trie.reset();
+    }
+}
+
+XLikelySubtags::~XLikelySubtags() {
+    ures_close(langInfoBundle);
+    delete strings;
+    delete[] lsrs;
+}
+
+LSR XLikelySubtags::makeMaximizedLsrFrom(const Locale &locale, UErrorCode &errorCode) const {
+    const char *name = locale.getName();
+    if (uprv_isAtSign(name[0]) && name[1] == 'x' && name[2] == '=') {  // name.startsWith("@x=")
+        // Private use language tag x-subtag-subtag...
+        return LSR(name, "", "", LSR::EXPLICIT_LSR);
+    }
+    return makeMaximizedLsr(locale.getLanguage(), locale.getScript(), locale.getCountry(),
+                            locale.getVariant(), errorCode);
+}
+
+namespace {
+
+const char *getCanonical(const CharStringMap &aliases, const char *alias) {
+    const char *canonical = aliases.get(alias);
+    return canonical == nullptr ? alias : canonical;
+}
+
+}  // namespace
+
+LSR XLikelySubtags::makeMaximizedLsr(const char *language, const char *script, const char *region,
+                                     const char *variant, UErrorCode &errorCode) const {
+    // Handle pseudolocales like en-XA, ar-XB, fr-PSCRACK.
+    // They should match only themselves,
+    // not other locales with what looks like the same language and script subtags.
+    char c1;
+    if (region[0] == 'X' && (c1 = region[1]) != 0 && region[2] == 0) {
+        switch (c1) {
+        case 'A':
+            return LSR(PSEUDO_ACCENTS_PREFIX, language, script, region,
+                       LSR::EXPLICIT_LSR, errorCode);
+        case 'B':
+            return LSR(PSEUDO_BIDI_PREFIX, language, script, region,
+                       LSR::EXPLICIT_LSR, errorCode);
+        case 'C':
+            return LSR(PSEUDO_CRACKED_PREFIX, language, script, region,
+                       LSR::EXPLICIT_LSR, errorCode);
+        default:  // normal locale
+            break;
+        }
+    }
+
+    if (variant[0] == 'P' && variant[1] == 'S') {
+        int32_t lsrFlags = *region == 0 ?
+            LSR::EXPLICIT_LANGUAGE | LSR::EXPLICIT_SCRIPT : LSR::EXPLICIT_LSR;
+        if (uprv_strcmp(variant, "PSACCENT") == 0) {
+            return LSR(PSEUDO_ACCENTS_PREFIX, language, script,
+                       *region == 0 ? "XA" : region, lsrFlags, errorCode);
+        } else if (uprv_strcmp(variant, "PSBIDI") == 0) {
+            return LSR(PSEUDO_BIDI_PREFIX, language, script,
+                       *region == 0 ? "XB" : region, lsrFlags, errorCode);
+        } else if (uprv_strcmp(variant, "PSCRACK") == 0) {
+            return LSR(PSEUDO_CRACKED_PREFIX, language, script,
+                       *region == 0 ? "XC" : region, lsrFlags, errorCode);
+        }
+        // else normal locale
+    }
+
+    language = getCanonical(languageAliases, language);
+    // (We have no script mappings.)
+    region = getCanonical(regionAliases, region);
+    return maximize(language, script, region);
+}
+
+LSR XLikelySubtags::maximize(const char *language, const char *script, const char *region) const {
+    if (uprv_strcmp(language, "und") == 0) {
+        language = "";
+    }
+    if (uprv_strcmp(script, "Zzzz") == 0) {
+        script = "";
+    }
+    if (uprv_strcmp(region, "ZZ") == 0) {
+        region = "";
+    }
+    if (*script != 0 && *region != 0 && *language != 0) {
+        return LSR(language, script, region, LSR::EXPLICIT_LSR);  // already maximized
+    }
+
+    uint32_t retainOldMask = 0;
+    BytesTrie iter(trie);
+    uint64_t state;
+    int32_t value;
+    // Small optimization: Array lookup for first language letter.
+    int32_t c0;
+    if (0 <= (c0 = uprv_lowerOrdinal(language[0])) && c0 <= 25 &&
+            language[1] != 0 &&  // language.length() >= 2
+            (state = trieFirstLetterStates[c0]) != 0) {
+        value = trieNext(iter.resetToState64(state), language, 1);
+    } else {
+        value = trieNext(iter, language, 0);
+    }
+    if (value >= 0) {
+        if (*language != 0) {
+            retainOldMask |= 4;
+        }
+        state = iter.getState64();
+    } else {
+        retainOldMask |= 4;
+        iter.resetToState64(trieUndState);  // "und" ("*")
+        state = 0;
+    }
+
+    if (value > 0) {
+        // Intermediate or final value from just language.
+        if (value == SKIP_SCRIPT) {
+            value = 0;
+        }
+        if (*script != 0) {
+            retainOldMask |= 2;
+        }
+    } else {
+        value = trieNext(iter, script, 0);
+        if (value >= 0) {
+            if (*script != 0) {
+                retainOldMask |= 2;
+            }
+            state = iter.getState64();
+        } else {
+            retainOldMask |= 2;
+            if (state == 0) {
+                iter.resetToState64(trieUndZzzzState);  // "und-Zzzz" ("**")
+            } else {
+                iter.resetToState64(state);
+                value = trieNext(iter, "", 0);
+                U_ASSERT(value >= 0);
+                state = iter.getState64();
+            }
+        }
+    }
+
+    if (value > 0) {
+        // Final value from just language or language+script.
+        if (*region != 0) {
+            retainOldMask |= 1;
+        }
+    } else {
+        value = trieNext(iter, region, 0);
+        if (value >= 0) {
+            if (*region != 0) {
+                retainOldMask |= 1;
+            }
+        } else {
+            retainOldMask |= 1;
+            if (state == 0) {
+                value = defaultLsrIndex;
+            } else {
+                iter.resetToState64(state);
+                value = trieNext(iter, "", 0);
+                U_ASSERT(value > 0);
+            }
+        }
+    }
+    U_ASSERT(value < lsrsLength);
+    const LSR &result = lsrs[value];
+
+    if (*language == 0) {
+        language = "und";
+    }
+
+    if (retainOldMask == 0) {
+        // Quickly return a copy of the lookup-result LSR
+        // without new allocation of the subtags.
+        return LSR(result.language, result.script, result.region, result.flags);
+    }
+    if ((retainOldMask & 4) == 0) {
+        language = result.language;
+    }
+    if ((retainOldMask & 2) == 0) {
+        script = result.script;
+    }
+    if ((retainOldMask & 1) == 0) {
+        region = result.region;
+    }
+    // retainOldMask flags = LSR explicit-subtag flags
+    return LSR(language, script, region, retainOldMask);
+}
+
+int32_t XLikelySubtags::compareLikely(const LSR &lsr, const LSR &other, int32_t likelyInfo) const {
+    // If likelyInfo >= 0:
+    // likelyInfo bit 1 is set if the previous comparison with lsr
+    // was for equal language and script.
+    // Otherwise the scripts differed.
+    if (uprv_strcmp(lsr.language, other.language) != 0) {
+        return 0xfffffffc;  // negative, lsr not better than other
+    }
+    if (uprv_strcmp(lsr.script, other.script) != 0) {
+        int32_t index;
+        if (likelyInfo >= 0 && (likelyInfo & 2) == 0) {
+            index = likelyInfo >> 2;
+        } else {
+            index = getLikelyIndex(lsr.language, "");
+            likelyInfo = index << 2;
+        }
+        const LSR &likely = lsrs[index];
+        if (uprv_strcmp(lsr.script, likely.script) == 0) {
+            return likelyInfo | 1;
+        } else {
+            return likelyInfo & ~1;
+        }
+    }
+    if (uprv_strcmp(lsr.region, other.region) != 0) {
+        int32_t index;
+        if (likelyInfo >= 0 && (likelyInfo & 2) != 0) {
+            index = likelyInfo >> 2;
+        } else {
+            index = getLikelyIndex(lsr.language, lsr.region);
+            likelyInfo = (index << 2) | 2;
+        }
+        const LSR &likely = lsrs[index];
+        if (uprv_strcmp(lsr.region, likely.region) == 0) {
+            return likelyInfo | 1;
+        } else {
+            return likelyInfo & ~1;
+        }
+    }
+    return likelyInfo & ~1;  // lsr not better than other
+}
+
+// Subset of maximize().
+int32_t XLikelySubtags::getLikelyIndex(const char *language, const char *script) const {
+    if (uprv_strcmp(language, "und") == 0) {
+        language = "";
+    }
+    if (uprv_strcmp(script, "Zzzz") == 0) {
+        script = "";
+    }
+
+    BytesTrie iter(trie);
+    uint64_t state;
+    int32_t value;
+    // Small optimization: Array lookup for first language letter.
+    int32_t c0;
+    if (0 <= (c0 = uprv_lowerOrdinal(language[0])) && c0 <= 25 &&
+            language[1] != 0 &&  // language.length() >= 2
+            (state = trieFirstLetterStates[c0]) != 0) {
+        value = trieNext(iter.resetToState64(state), language, 1);
+    } else {
+        value = trieNext(iter, language, 0);
+    }
+    if (value >= 0) {
+        state = iter.getState64();
+    } else {
+        iter.resetToState64(trieUndState);  // "und" ("*")
+        state = 0;
+    }
+
+    if (value > 0) {
+        // Intermediate or final value from just language.
+        if (value == SKIP_SCRIPT) {
+            value = 0;
+        }
+    } else {
+        value = trieNext(iter, script, 0);
+        if (value >= 0) {
+            state = iter.getState64();
+        } else {
+            if (state == 0) {
+                iter.resetToState64(trieUndZzzzState);  // "und-Zzzz" ("**")
+            } else {
+                iter.resetToState64(state);
+                value = trieNext(iter, "", 0);
+                U_ASSERT(value >= 0);
+                state = iter.getState64();
+            }
+        }
+    }
+
+    if (value > 0) {
+        // Final value from just language or language+script.
+    } else {
+        value = trieNext(iter, "", 0);
+        U_ASSERT(value > 0);
+    }
+    U_ASSERT(value < lsrsLength);
+    return value;
+}
+
+int32_t XLikelySubtags::trieNext(BytesTrie &iter, const char *s, int32_t i) {
+    UStringTrieResult result;
+    uint8_t c;
+    if ((c = s[i]) == 0) {
+        result = iter.next(u'*');
+    } else {
+        for (;;) {
+            c = uprv_invCharToAscii(c);
+            // EBCDIC: If s[i] is not an invariant character,
+            // then c is now 0 and will simply not match anything, which is harmless.
+            uint8_t next = s[++i];
+            if (next != 0) {
+                if (!USTRINGTRIE_HAS_NEXT(iter.next(c))) {
+                    return -1;
+                }
+            } else {
+                // last character of this subtag
+                result = iter.next(c | 0x80);
+                break;
+            }
+            c = next;
+        }
+    }
+    switch (result) {
+    case USTRINGTRIE_NO_MATCH: return -1;
+    case USTRINGTRIE_NO_VALUE: return 0;
+    case USTRINGTRIE_INTERMEDIATE_VALUE:
+        U_ASSERT(iter.getValue() == SKIP_SCRIPT);
+        return SKIP_SCRIPT;
+    case USTRINGTRIE_FINAL_VALUE: return iter.getValue();
+    default: return -1;
+    }
+}
+
+// TODO(ICU-20777): Switch Locale/uloc_ likely-subtags API from the old code
+// in loclikely.cpp to this new code, including activating this
+// minimizeSubtags() function. The LocaleMatcher does not minimize.
+#if 0
+LSR XLikelySubtags::minimizeSubtags(const char *languageIn, const char *scriptIn,
+                                    const char *regionIn, ULocale.Minimize fieldToFavor,
+                                    UErrorCode &errorCode) const {
+    LSR result = maximize(languageIn, scriptIn, regionIn);
+
+    // We could try just a series of checks, like:
+    // LSR result2 = addLikelySubtags(languageIn, "", "");
+    // if result.equals(result2) return result2;
+    // However, we can optimize 2 of the cases:
+    //   (languageIn, "", "")
+    //   (languageIn, "", regionIn)
+
+    // value00 = lookup(result.language, "", "")
+    BytesTrie iter = new BytesTrie(trie);
+    int value = trieNext(iter, result.language, 0);
+    U_ASSERT(value >= 0);
+    if (value == 0) {
+        value = trieNext(iter, "", 0);
+        U_ASSERT(value >= 0);
+        if (value == 0) {
+            value = trieNext(iter, "", 0);
+        }
+    }
+    U_ASSERT(value > 0);
+    LSR value00 = lsrs[value];
+    boolean favorRegionOk = false;
+    if (result.script.equals(value00.script)) { //script is default
+        if (result.region.equals(value00.region)) {
+            return new LSR(result.language, "", "", LSR.DONT_CARE_FLAGS);
+        } else if (fieldToFavor == ULocale.Minimize.FAVOR_REGION) {
+            return new LSR(result.language, "", result.region, LSR.DONT_CARE_FLAGS);
+        } else {
+            favorRegionOk = true;
+        }
+    }
+
+    // The last case is not as easy to optimize.
+    // Maybe do later, but for now use the straightforward code.
+    LSR result2 = maximize(languageIn, scriptIn, "");
+    if (result2.equals(result)) {
+        return new LSR(result.language, result.script, "", LSR.DONT_CARE_FLAGS);
+    } else if (favorRegionOk) {
+        return new LSR(result.language, "", result.region, LSR.DONT_CARE_FLAGS);
+    }
+    return result;
+}
+#endif
+
+U_NAMESPACE_END
diff --git a/src/third_party/icu/source/common/loclikelysubtags.h b/src/third_party/icu/source/common/loclikelysubtags.h
new file mode 100644
index 0000000..14a01a5
--- /dev/null
+++ b/src/third_party/icu/source/common/loclikelysubtags.h
@@ -0,0 +1,121 @@
+// © 2019 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+// loclikelysubtags.h
+// created: 2019may08 Markus W. Scherer
+
+#ifndef __LOCLIKELYSUBTAGS_H__
+#define __LOCLIKELYSUBTAGS_H__
+
+#include <utility>
+#include "unicode/utypes.h"
+#include "unicode/bytestrie.h"
+#include "unicode/locid.h"
+#include "unicode/uobject.h"
+#include "unicode/ures.h"
+#include "charstrmap.h"
+#include "lsr.h"
+
+U_NAMESPACE_BEGIN
+
+struct XLikelySubtagsData;
+
+struct LocaleDistanceData {
+    LocaleDistanceData() = default;
+    LocaleDistanceData(LocaleDistanceData &&data);
+    ~LocaleDistanceData();
+
+    const uint8_t *distanceTrieBytes = nullptr;
+    const uint8_t *regionToPartitions = nullptr;
+    const char **partitions = nullptr;
+    const LSR *paradigms = nullptr;
+    int32_t paradigmsLength = 0;
+    const int32_t *distances = nullptr;
+
+private:
+    LocaleDistanceData &operator=(const LocaleDistanceData &) = delete;
+};
+
+// TODO(ICU-20777): Rename to just LikelySubtags.
+class XLikelySubtags final : public UMemory {
+public:
+    ~XLikelySubtags();
+
+    static constexpr int32_t SKIP_SCRIPT = 1;
+
+    // VisibleForTesting
+    static const XLikelySubtags *getSingleton(UErrorCode &errorCode);
+
+    // VisibleForTesting
+    LSR makeMaximizedLsrFrom(const Locale &locale, UErrorCode &errorCode) const;
+
+    /**
+     * Tests whether lsr is "more likely" than other.
+     * For example, fr-Latn-FR is more likely than fr-Latn-CH because
+     * FR is the default region for fr-Latn.
+     *
+     * The likelyInfo caches lookup information between calls.
+     * The return value is an updated likelyInfo value,
+     * with bit 0 set if lsr is "more likely".
+     * The initial value of likelyInfo must be negative.
+     */
+    int32_t compareLikely(const LSR &lsr, const LSR &other, int32_t likelyInfo) const;
+
+    // TODO(ICU-20777): Switch Locale/uloc_ likely-subtags API from the old code
+    // in loclikely.cpp to this new code, including activating this
+    // minimizeSubtags() function. The LocaleMatcher does not minimize.
+#if 0
+    LSR minimizeSubtags(const char *languageIn, const char *scriptIn, const char *regionIn,
+                        ULocale.Minimize fieldToFavor, UErrorCode &errorCode) const;
+#endif
+
+    // visible for LocaleDistance
+    const LocaleDistanceData &getDistanceData() const { return distanceData; }
+
+private:
+    XLikelySubtags(XLikelySubtagsData &data);
+    XLikelySubtags(const XLikelySubtags &other) = delete;
+    XLikelySubtags &operator=(const XLikelySubtags &other) = delete;
+
+    static void initLikelySubtags(UErrorCode &errorCode);
+
+    LSR makeMaximizedLsr(const char *language, const char *script, const char *region,
+                         const char *variant, UErrorCode &errorCode) const;
+
+    /**
+     * Raw access to addLikelySubtags. Input must be in canonical format, eg "en", not "eng" or "EN".
+     */
+    LSR maximize(const char *language, const char *script, const char *region) const;
+
+    int32_t getLikelyIndex(const char *language, const char *script) const;
+
+    static int32_t trieNext(BytesTrie &iter, const char *s, int32_t i);
+
+    UResourceBundle *langInfoBundle;
+    // We could store the strings by value, except that if there were few enough strings,
+    // moving the contents could copy it to a different array,
+    // invalidating the pointers stored in the maps.
+    CharString *strings;
+    CharStringMap languageAliases;
+    CharStringMap regionAliases;
+
+    // The trie maps each lang+script+region (encoded in ASCII) to an index into lsrs.
+    // There is also a trie value for each intermediate lang and lang+script.
+    // '*' is used instead of "und", "Zzzz"/"" and "ZZ"/"".
+    BytesTrie trie;
+    uint64_t trieUndState;
+    uint64_t trieUndZzzzState;
+    int32_t defaultLsrIndex;
+    uint64_t trieFirstLetterStates[26];
+    const LSR *lsrs;
+#if U_DEBUG
+    int32_t lsrsLength;
+#endif
+
+    // distance/matcher data: see comment in XLikelySubtagsData::load()
+    LocaleDistanceData distanceData;
+};
+
+U_NAMESPACE_END
+
+#endif  // __LOCLIKELYSUBTAGS_H__
diff --git a/src/third_party/icu/source/common/locmap.c b/src/third_party/icu/source/common/locmap.cpp
similarity index 76%
rename from src/third_party/icu/source/common/locmap.c
rename to src/third_party/icu/source/common/locmap.cpp
index 3a08420..2702168 100644
--- a/src/third_party/icu/source/common/locmap.c
+++ b/src/third_party/icu/source/common/locmap.cpp
@@ -1,6 +1,8 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
  **********************************************************************
- *   Copyright (C) 1996-2014, International Business Machines
+ *   Copyright (C) 1996-2016, International Business Machines
  *   Corporation and others.  All Rights Reserved.
  **********************************************************************
  *
@@ -25,28 +27,20 @@
  * 08/23/01     george      Convert to C
  */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "locmap.h"
+#include "bytesinkutil.h"
+#include "charstr.h"
 #include "cstring.h"
 #include "cmemory.h"
+#include "ulocimp.h"
+#include "unicode/uloc.h"
 
-#if 0
-#if U_PLATFORM == U_PF_WINDOWS && defined(_MSC_VER) && (_MSC_VER >= 1500)
-/*
- * TODO: It seems like we should widen this to
- * either U_PLATFORM_USES_ONLY_WIN32_API (includes MinGW)
- * or U_PLATFORM_HAS_WIN32_API (includes MinGW and Cygwin)
- * but those use gcc and won't have defined(_MSC_VER).
- * We might need to #include some Windows header and test for some version macro from there.
- * Or call some Windows function and see what it returns.
- */
-#define USE_WINDOWS_LOCALE_API
-#endif
-#endif
-
-#ifdef USE_WINDOWS_LOCALE_API
+#if U_PLATFORM_HAS_WIN32_API && UCONFIG_USE_WINDOWS_LCID_MAPPING_API
 #include <windows.h>
-#include <winnls.h>
+#include <winnls.h> // LCIDToLocaleName and LocaleNameToLCID
 #endif
 
 /*
@@ -54,8 +48,8 @@
  * The mapping from Win32 locale ID numbers to POSIX locale strings should
  * be the faster one.
  *
- * Many LCID values come from winnt.h
- * Some also come from http://www.microsoft.com/globaldev/reference/lcid-all.mspx
+ * Windows LCIDs are defined at https://msdn.microsoft.com/en-us/library/cc233965.aspx
+ * [MS-LCID] Windows Language Code Identifier (LCID) Reference
  */
 
 /*
@@ -116,7 +110,7 @@
  * @param _posixID the full POSIX ID for this entry.
  */
 #define ILCID_POSIX_MAP(_posixID) \
-    {sizeof(locmap_ ## _posixID)/sizeof(ILcidPosixElement), locmap_ ## _posixID}
+    {UPRV_LENGTHOF(locmap_ ## _posixID), locmap_ ## _posixID}
 
 /*
 ////////////////////////////////////////////
@@ -127,7 +121,9 @@
 // Keep static locale variables inside the function so that
 // it can be created properly during static init.
 //
-// Note: This table should be updated periodically. Check the National Lanaguage Support API Reference Website.
+// Note: This table should be updated periodically. Check the [MS-LCID] Windows Language Code Identifier 
+//       (LCID) Reference defined at https://msdn.microsoft.com/en-us/library/cc233965.aspx
+//
 //       Microsoft is moving away from LCID in favor of locale name as of Vista.  This table needs to be
 //       maintained for support of older Windows version.
 //       Update: Windows 7 (091130)
@@ -139,6 +135,9 @@
 ////////////////////////////////////////////
 */
 
+// TODO: For Windows ideally this table would be a list of exceptions rather than a complete list as 
+// LocaleNameToLCID and LCIDToLocaleName provide 90% of these.
+
 ILCID_POSIX_ELEMENT_ARRAY(0x0436, af, af_ZA)
 
 ILCID_POSIX_SUBTABLE(ar) {
@@ -188,7 +187,10 @@
 
 ILCID_POSIX_ELEMENT_ARRAY(0x0402, bg, bg_BG)
 
-ILCID_POSIX_ELEMENT_ARRAY(0x0466, bin, bin_NG)
+ILCID_POSIX_SUBTABLE(bin) {
+    {0x66, "bin"},
+    {0x0466, "bin_NG"}
+};
 
 ILCID_POSIX_SUBTABLE(bn) {
     {0x45,   "bn"},
@@ -199,7 +201,8 @@
 ILCID_POSIX_SUBTABLE(bo) {
     {0x51,   "bo"},
     {0x0851, "bo_BT"},
-    {0x0451, "bo_CN"}
+    {0x0451, "bo_CN"},
+    {0x0c51, "dz_BT"}
 };
 
 ILCID_POSIX_ELEMENT_ARRAY(0x047e, br, br_FR)
@@ -211,15 +214,19 @@
 };
 
 ILCID_POSIX_ELEMENT_ARRAY(0x0483, co, co_FR)
-ILCID_POSIX_ELEMENT_ARRAY(0x045c, chr,chr_US)
 
+ILCID_POSIX_SUBTABLE(chr) {
+    {0x05c,  "chr"},
+    {0x7c5c, "chr_Cher"},
+    {0x045c, "chr_Cher_US"},
+    {0x045c, "chr_US"}
+};
+
+// ICU has chosen different names for these.
 ILCID_POSIX_SUBTABLE(ckb) {
     {0x92,   "ckb"},
-    {0x92,   "ku"},
     {0x7c92, "ckb_Arab"},
-    {0x7c92, "ku_Arab"},
-    {0x0492, "ckb_Arab_IQ"},
-    {0x0492, "ku_Arab_IQ"}
+    {0x0492, "ckb_Arab_IQ"}
 };
 
 /* Declared as cs_CZ to get around compiler errors on z/OS, which defines cs as a function */
@@ -228,6 +235,7 @@
 ILCID_POSIX_ELEMENT_ARRAY(0x0452, cy, cy_GB)
 ILCID_POSIX_ELEMENT_ARRAY(0x0406, da, da_DK)
 
+// Windows doesn't know POSIX or BCP47 Unicode phonebook sort names
 ILCID_POSIX_SUBTABLE(de) {
     {0x07,   "de"},
     {0x0c07, "de_AT"},
@@ -242,6 +250,7 @@
 ILCID_POSIX_ELEMENT_ARRAY(0x0465, dv, dv_MV)
 ILCID_POSIX_ELEMENT_ARRAY(0x0408, el, el_GR)
 
+// Windows uses an empty string for 'invariant'
 ILCID_POSIX_SUBTABLE(en) {
     {0x09,   "en"},
     {0x0c09, "en_AU"},
@@ -259,22 +268,23 @@
     {0x4809, "en_SG"},
     {0x2C09, "en_TT"},
     {0x0409, "en_US"},
-    {0x007f, "en_US_POSIX"}, /* duplicate for roundtripping */
-    {0x2409, "en_VI"},  /* Virgin Islands AKA Caribbean Islands (en_CB). */
+    {0x007f, "en_US_POSIX"}, /* duplicate for round-tripping */
+    {0x2409, "en_029"},
     {0x1c09, "en_ZA"},
     {0x3009, "en_ZW"},
-    {0x2409, "en_029"},
-    {0x0409, "en_AS"},  /* Alias for en_US. Leave last. */
-    {0x0409, "en_GU"},  /* Alias for en_US. Leave last. */
-    {0x0409, "en_MH"},  /* Alias for en_US. Leave last. */
-    {0x0409, "en_MP"},  /* Alias for en_US. Leave last. */
-    {0x0409, "en_UM"}   /* Alias for en_US. Leave last. */
+    {0x2409, "en_VI"},  /* Virgin Islands AKA Caribbean Islands (en_CB). On Windows8+ This is 0x1000 or dynamically assigned */
+    {0x0409, "en_AS"},  /* Alias for en_US. Leave last.  On Windows8+ This is 0x1000 or dynamically assigned */
+    {0x0409, "en_GU"},  /* Alias for en_US. Leave last.  On Windows8+ This is 0x1000 or dynamically assigned */
+    {0x0409, "en_MH"},  /* Alias for en_US. Leave last.  On Windows8+ This is 0x1000 or dynamically assigned */
+    {0x0409, "en_MP"},  /* Alias for en_US. Leave last.  On Windows8+ This is 0x1000 or dynamically assigned */
+    {0x0409, "en_UM"}   /* Alias for en_US. Leave last.  On Windows8+ This is 0x1000 or dynamically assigned */
 };
 
 ILCID_POSIX_SUBTABLE(en_US_POSIX) {
     {0x007f, "en_US_POSIX"} /* duplicate for roundtripping */
 };
 
+// Windows doesn't know POSIX or BCP47 Unicode traditional sort names
 ILCID_POSIX_SUBTABLE(es) {
     {0x0a,   "es"},
     {0x2c0a, "es_AR"},
@@ -282,6 +292,7 @@
     {0x340a, "es_CL"},
     {0x240a, "es_CO"},
     {0x140a, "es_CR"},
+    {0x5c0a, "es_CU"},
     {0x1c0a, "es_DO"},
     {0x300a, "es_EC"},
     {0x0c0a, "es_ES"},      /*Modern sort.*/
@@ -299,7 +310,7 @@
     {0x200a, "es_VE"},
     {0x580a, "es_419"},
     {0x040a, "es_ES@collation=traditional"},
-    {0x040a, "es@collation=traditional"}
+    {0x040a, "es@collation=traditional"}        // Windows will treat this as es-ES@collation=traditional
 };
 
 ILCID_POSIX_ELEMENT_ARRAY(0x0425, et, et_EE)
@@ -312,6 +323,7 @@
     {0x048c, "fa_AF"}   /* Persian/Dari (Afghanistan) */
 };
 
+
 /* duplicate for roundtripping */
 ILCID_POSIX_SUBTABLE(fa_AF) {
     {0x8c,   "fa_AF"},  /* Persian/Dari (Afghanistan) */
@@ -321,7 +333,8 @@
 ILCID_POSIX_SUBTABLE(ff) {
     {0x67,   "ff"},
     {0x7c67, "ff_Latn"},
-    {0x0867, "ff_Latn_SN"}
+    {0x0867, "ff_Latn_SN"},
+    {0x0467, "ff_NG"}
 };
 
 ILCID_POSIX_ELEMENT_ARRAY(0x040b, fi, fi_FI)
@@ -412,7 +425,12 @@
 
 ILCID_POSIX_ELEMENT_ARRAY(0x040e, hu, hu_HU)
 ILCID_POSIX_ELEMENT_ARRAY(0x042b, hy, hy_AM)
-ILCID_POSIX_ELEMENT_ARRAY(0x0469, ibb, ibb_NG)
+
+ILCID_POSIX_SUBTABLE(ibb) {
+    {0x69, "ibb"},
+    {0x0469, "ibb_NG"}
+};
+
 ILCID_POSIX_ELEMENT_ARRAY(0x0421, id, id_ID)
 ILCID_POSIX_ELEMENT_ARRAY(0x0470, ig, ig_NG)
 ILCID_POSIX_ELEMENT_ARRAY(0x0478, ii, ii_CN)
@@ -451,13 +469,18 @@
 
 ILCID_POSIX_SUBTABLE(ks) {         /* We could add PK and CN too */
     {0x60,   "ks"},
-    {0x0860, "ks_IN"},              /* Documentation doesn't mention script */
     {0x0460, "ks_Arab_IN"},
     {0x0860, "ks_Deva_IN"}
 };
 
 ILCID_POSIX_ELEMENT_ARRAY(0x0440, ky, ky_KG)   /* Kyrgyz is spoken in Kyrgyzstan */
-ILCID_POSIX_ELEMENT_ARRAY(0x0476, la, la_IT)   /* TODO: Verify the country */
+
+ILCID_POSIX_SUBTABLE(la) {
+    {0x76,   "la"},
+    {0x0476, "la_001"},
+    {0x0476, "la_IT"}       /*Left in for compatibility*/
+};
+
 ILCID_POSIX_ELEMENT_ARRAY(0x046e, lb, lb_LU)
 ILCID_POSIX_ELEMENT_ARRAY(0x0454, lo, lo_LA)
 ILCID_POSIX_ELEMENT_ARRAY(0x0427, lt, lt_LT)
@@ -502,8 +525,9 @@
 };
 
 /* The "no" locale split into nb and nn.  By default in ICU, "no" is nb.*/
+// TODO: Not all of these are needed on Windows, but I don't know how ICU treats preferred ones here.
 ILCID_POSIX_SUBTABLE(no) {
-    {0x14,   "no"},     /* really nb_NO */
+    {0x14,   "no"},     /* really nb_NO - actually Windows differentiates between neutral (no region) and specific (with region) */ 
     {0x7c14, "nb"},     /* really nb */
     {0x0414, "nb_NO"},  /* really nb_NO. Keep first in the 414 list. */
     {0x0414, "no_NO"},  /* really nb_NO */
@@ -527,15 +551,19 @@
     {0x0448, "or_IN"},
 };
 
-
 ILCID_POSIX_SUBTABLE(pa) {
     {0x46,   "pa"},
     {0x0446, "pa_IN"},
-    {0x0846, "pa_PK"},
-    {0x0846, "pa_Arab_PK"}
+    {0x0846, "pa_Arab_PK"},
+    {0x0846, "pa_PK"}
 };
 
-ILCID_POSIX_ELEMENT_ARRAY(0x0479, pap, pap_AN)
+ILCID_POSIX_SUBTABLE(pap) {
+    {0x79, "pap"},
+    {0x0479, "pap_029"},
+    {0x0479, "pap_AN"}     /*Left in for compatibility*/
+};
+
 ILCID_POSIX_ELEMENT_ARRAY(0x0415, pl, pl_PL)
 ILCID_POSIX_ELEMENT_ARRAY(0x0463, ps, ps_AF)
 
@@ -555,7 +583,35 @@
     {0x0C6b, "quz_PE"}
 };
 
-ILCID_POSIX_ELEMENT_ARRAY(0x0486, qut, qut_GT) /* qut is an ISO-639-3 code */
+ILCID_POSIX_SUBTABLE(quc) {
+    {0x93,   "quc"},
+    {0x0493, "quc_CO"},
+    /*
+        "quc_Latn_GT" is an exceptional case. Language ID of "quc"
+        is 0x93, but LCID of "quc_Latn_GT" is 0x486, which should be
+        under the group of "qut". "qut" is a retired ISO 639-3 language
+        code for West Central Quiche, and merged to "quc".
+        It looks Windows previously reserved "qut" for K'iche', but,
+        decided to use "quc" when adding a locale for K'iche' (Guatemala).
+
+        This data structure used here assumes language ID bits in
+        LCID is unique for alphabetic language code. But this is not true
+        for "quc_Latn_GT". If we don't have the data below, LCID look up
+        by alphabetic locale ID (POSIX) will fail. The same entry is found
+        under "qut" below, which is required for reverse look up.
+    */
+    {0x0486, "quc_Latn_GT"}
+};
+
+ILCID_POSIX_SUBTABLE(qut) {
+    {0x86,   "qut"},
+    {0x0486, "qut_GT"},
+    /*
+        See the note in "quc" above.
+    */
+    {0x0486, "quc_Latn_GT"}
+};
+
 ILCID_POSIX_ELEMENT_ARRAY(0x0417, rm, rm_CH)
 
 ILCID_POSIX_SUBTABLE(ro) {
@@ -564,6 +620,9 @@
     {0x0818, "ro_MD"}
 };
 
+// TODO: This is almost certainly 'wrong'.  0 in Windows is a synonym for LOCALE_USER_DEFAULT.
+// More likely this is a similar concept to the Windows 0x7f Invariant locale ""
+// (Except that it's not invariant in ICU)
 ILCID_POSIX_SUBTABLE(root) {
     {0x00,   "root"}
 };
@@ -580,8 +639,11 @@
 
 ILCID_POSIX_SUBTABLE(sd) {
     {0x59,   "sd"},
+    {0x0459, "sd_Deva_IN"},
     {0x0459, "sd_IN"},
-    {0x0859, "sd_PK"}
+    {0x0859, "sd_Arab_PK"},
+    {0x0859, "sd_PK"},
+    {0x7c59, "sd_Arab"}
 };
 
 ILCID_POSIX_SUBTABLE(se) {
@@ -605,9 +667,8 @@
 ILCID_POSIX_ELEMENT_ARRAY(0x041b, sk, sk_SK)
 ILCID_POSIX_ELEMENT_ARRAY(0x0424, sl, sl_SI)
 
-ILCID_POSIX_SUBTABLE(so) { /* TODO: Verify the country */
+ILCID_POSIX_SUBTABLE(so) {
     {0x77,   "so"},
-    {0x0477, "so_ET"},
     {0x0477, "so_SO"}
 };
 
@@ -663,6 +724,7 @@
     {0x7c5f, "tzm_Latn"},
     {0x085f, "tzm_Latn_DZ"},
     {0x105f, "tzm_Tfng_MA"},
+    {0x045f, "tzm_Arab_MA"},
     {0x045f, "tmz"}
 };
 
@@ -698,9 +760,16 @@
 ILCID_POSIX_ELEMENT_ARRAY(0x042a, vi, vi_VN)
 ILCID_POSIX_ELEMENT_ARRAY(0x0488, wo, wo_SN)
 ILCID_POSIX_ELEMENT_ARRAY(0x0434, xh, xh_ZA)
-ILCID_POSIX_ELEMENT_ARRAY(0x043d, yi, yi)
+
+ILCID_POSIX_SUBTABLE(yi) {
+    {0x003d, "yi"},
+    {0x043d, "yi_001"}
+};
+
 ILCID_POSIX_ELEMENT_ARRAY(0x046a, yo, yo_NG)
 
+// Windows & ICU tend to different names for some of these
+// TODO: Windows probably does not need all of these entries, but I don't know how the precedence works.
 ILCID_POSIX_SUBTABLE(zh) {
     {0x0004, "zh_Hans"},
     {0x7804, "zh"},
@@ -724,6 +793,7 @@
     {0x20804,"zh_Hans@collation=stroke"},
     {0x20804,"zh_Hans_CN@collation=stroke"},
     {0x20804,"zh_CN@collation=stroke"}
+    // TODO: Alternate collations for other LCIDs are missing, eg: 0x50804
 };
 
 ILCID_POSIX_ELEMENT_ARRAY(0x0435, zu, zu_ZA)
@@ -831,6 +901,7 @@
     ILCID_POSIX_MAP(ps),    /*  ps  Pashto                    0x63 */
     ILCID_POSIX_MAP(pt),    /*  pt  Portuguese                0x16 */
     ILCID_POSIX_MAP(qu),    /*  qu  Quechua                   0x6B */
+    ILCID_POSIX_MAP(quc),   /*  quc K'iche                    0x93 */
     ILCID_POSIX_MAP(qut),   /*  qut K'iche                    0x86 */
     ILCID_POSIX_MAP(rm),    /*  rm  Raeto-Romance/Romansh     0x17 */
     ILCID_POSIX_MAP(ro),    /*  ro  Romanian                  0x18 */
@@ -877,7 +948,7 @@
     ILCID_POSIX_MAP(zu),    /*  zu  Zulu                      0x35 */
 };
 
-static const uint32_t gLocaleCount = sizeof(gPosixIDmap)/sizeof(ILcidPosixMap);
+static const uint32_t gLocaleCount = UPRV_LENGTHOF(gPosixIDmap);
 
 /**
  * Do not call this function. It is called by hostID.
@@ -899,7 +970,7 @@
 /**
  * Searches for a Windows LCID
  *
- * @param posixid the Posix style locale id.
+ * @param posixID the Posix style locale id.
  * @param status gets set to U_ILLEGAL_ARGUMENT_ERROR when the Posix ID has
  *               no equivalent Windows LCID.
  * @return the LCID
@@ -941,7 +1012,7 @@
 getPosixID(const ILcidPosixMap *this_0, uint32_t hostID)
 {
     uint32_t i;
-    for (i = 0; i <= this_0->numRegions; i++)
+    for (i = 0; i < this_0->numRegions; i++)
     {
         if (this_0->regionMaps[i].hostID == hostID)
         {
@@ -961,7 +1032,7 @@
 //
 /////////////////////////////////////
 */
-#ifdef USE_WINDOWS_LOCALE_API
+#if U_PLATFORM_HAS_WIN32_API && UCONFIG_USE_WINDOWS_LCID_MAPPING_API
 /*
  * Various language tags needs to be changed:
  * quz -> qu
@@ -979,6 +1050,7 @@
     }
 
 #endif
+
 U_CAPI int32_t
 uprv_convertToPosix(uint32_t hostid, char *posixID, int32_t posixIDCapacity, UErrorCode* status)
 {
@@ -987,36 +1059,59 @@
     UBool bLookup = TRUE;
     const char *pPosixID = NULL;
 
-#ifdef USE_WINDOWS_LOCALE_API
-    int32_t tmpLen = 0;
-    char locName[157];  /* ULOC_FULLNAME_CAPACITY */
+#if U_PLATFORM_HAS_WIN32_API && UCONFIG_USE_WINDOWS_LCID_MAPPING_API
+    static_assert(ULOC_FULLNAME_CAPACITY > LOCALE_NAME_MAX_LENGTH, "Windows locale names have smaller length than ICU locale names.");
 
-    tmpLen = GetLocaleInfoA(hostid, LOCALE_SNAME, (LPSTR)locName, sizeof(locName)/sizeof(locName[0]));
-    if (tmpLen > 1) {
-        /* Windows locale name may contain sorting variant, such as "es-ES_tradnl".
-           In such case, we need special mapping data found in the hardcoded table
-           in this source file. */
-        char *p = uprv_strchr(locName, '_');
-        if (p) {
-            /* Keep the base locale, without variant */
-            *p = 0;
-            tmpLen = uprv_strlen(locName);
-        } else {
-            /* No hardcoded table lookup necessary */
+    char locName[LOCALE_NAME_MAX_LENGTH] = {};
+
+    // Note: Windows primary lang ID 0x92 in LCID is used for Central Kurdish and
+    // GetLocaleInfo() maps such LCID to "ku". However, CLDR uses "ku" for
+    // Northern Kurdish and "ckb" for Central Kurdish. For this reason, we cannot
+    // use the Windows API to resolve locale ID for this specific case.
+    if ((hostid & 0x3FF) != 0x92) {
+        int32_t tmpLen = 0;
+        char16_t windowsLocaleName[LOCALE_NAME_MAX_LENGTH] = {};
+
+        // Note: LOCALE_ALLOW_NEUTRAL_NAMES was enabled in Windows7+, prior versions did not handle neutral (no-region) locale names.
+        tmpLen = LCIDToLocaleName(hostid, (PWSTR)windowsLocaleName, UPRV_LENGTHOF(windowsLocaleName), LOCALE_ALLOW_NEUTRAL_NAMES);
+        if (tmpLen > 1) {
+            int32_t i = 0;
+            // Only need to look up in table if have _, eg for de-de_phoneb type alternate sort.
             bLookup = FALSE;
-        }
-        /* Change the tag separator from '-' to '_' */
-        p = locName;
-        while (*p) {
-            if (*p == '-') {
-                *p = '_';
+            for (i = 0; i < UPRV_LENGTHOF(locName); i++)
+            {
+                locName[i] = (char)(windowsLocaleName[i]);
+
+                // Windows locale name may contain sorting variant, such as "es-ES_tradnl".
+                // In such cases, we need special mapping data found in the hardcoded table
+                // in this source file.
+                if (windowsLocaleName[i] == L'_')
+                {
+                    // Keep the base locale, without variant
+                    // TODO: Should these be mapped from _phoneb to @collation=phonebook, etc.?
+                    locName[i] = '\0';
+                    tmpLen = i;
+                    bLookup = TRUE;
+                    break;
+                }
+                else if (windowsLocaleName[i] == L'-')
+                {
+                    // Windows names use -, ICU uses _
+                    locName[i] = '_';
+                }
+                else if (windowsLocaleName[i] == L'\0')
+                {
+                    // No point in doing more work than necessary
+                    break;
+                }
             }
-            p++;
+            // TODO: Need to understand this better, why isn't it an alias?
+            FIX_LANGUAGE_ID_TAG(locName, tmpLen);
+            pPosixID = locName;
         }
-        FIX_LANGUAGE_ID_TAG(locName, tmpLen);
-        pPosixID = locName;
     }
 #endif
+
     if (bLookup) {
         const char *pCandidate = NULL;
         langID = LANGUAGE_LCID(hostid);
@@ -1037,7 +1132,7 @@
     }
 
     if (pPosixID) {
-        int32_t resLen = uprv_strlen(pPosixID);
+        int32_t resLen = static_cast<int32_t>(uprv_strlen(pPosixID));
         int32_t copyLen = resLen <= posixIDCapacity ? resLen : posixIDCapacity;
         uprv_memcpy(posixID, pPosixID, copyLen);
         if (resLen < posixIDCapacity) {
@@ -1064,15 +1159,101 @@
 // POSIX --> LCID
 // This should only be called from uloc_getLCID.
 // The locale ID must be in canonical form.
-// langID is separate so that this file doesn't depend on the uloc_* API.
 //
 /////////////////////////////////////
 */
+U_CAPI uint32_t
+uprv_convertToLCIDPlatform(const char* localeID, UErrorCode* status)
+{
+    if (U_FAILURE(*status)) {
+        return 0;
+    }
+
+    // The purpose of this function is to leverage the Windows platform name->lcid
+    // conversion functionality when available.
+#if U_PLATFORM_HAS_WIN32_API && UCONFIG_USE_WINDOWS_LCID_MAPPING_API
+    int32_t len;
+    char baseName[ULOC_FULLNAME_CAPACITY] = {};
+    const char * mylocaleID = localeID;
+
+    // Check any for keywords.
+    if (uprv_strchr(localeID, '@'))
+    {
+        icu::CharString collVal;
+        {
+            icu::CharStringByteSink sink(&collVal);
+            ulocimp_getKeywordValue(localeID, "collation", sink, status);
+        }
+        if (U_SUCCESS(*status) && !collVal.isEmpty())
+        {
+            // If it contains the keyword collation, return 0 so that the LCID lookup table will be used.
+            return 0;
+        }
+        else
+        {
+            // If the locale ID contains keywords other than collation, just use the base name.
+            len = uloc_getBaseName(localeID, baseName, UPRV_LENGTHOF(baseName) - 1, status);
+
+            if (U_SUCCESS(*status) && len > 0)
+            {
+                baseName[len] = 0;
+                mylocaleID = baseName;
+            }
+        }
+    }
+
+    char asciiBCP47Tag[LOCALE_NAME_MAX_LENGTH] = {};
+    // this will change it from de_DE@collation=phonebook to de-DE-u-co-phonebk form
+    (void)uloc_toLanguageTag(mylocaleID, asciiBCP47Tag, UPRV_LENGTHOF(asciiBCP47Tag), FALSE, status);
+
+    if (U_SUCCESS(*status))
+    {
+        // Need it to be UTF-16, not 8-bit
+        wchar_t bcp47Tag[LOCALE_NAME_MAX_LENGTH] = {};
+        int32_t i;
+        for (i = 0; i < UPRV_LENGTHOF(bcp47Tag); i++)
+        {
+            if (asciiBCP47Tag[i] == '\0')
+            {
+                break;
+            }
+            else
+            {
+                // Copy the character
+                bcp47Tag[i] = static_cast<wchar_t>(asciiBCP47Tag[i]);
+            }
+        }
+
+        if (i < (UPRV_LENGTHOF(bcp47Tag) - 1))
+        {
+            // Ensure it's null terminated
+            bcp47Tag[i] = L'\0';
+            LCID lcid = LocaleNameToLCID(bcp47Tag, LOCALE_ALLOW_NEUTRAL_NAMES);
+            if (lcid > 0)
+            {
+                // Found LCID from windows, return that one, unless its completely ambiguous
+                // LOCALE_USER_DEFAULT and transients are OK because they will round trip
+                // for this process.
+                if (lcid != LOCALE_CUSTOM_UNSPECIFIED)
+                {
+                    return lcid;
+                }
+            }
+        }
+    }
+#else
+    (void) localeID; // Suppress unused variable warning.
+#endif
+
+    // Nothing found, or not implemented.
+    return 0;
+}
 
 U_CAPI uint32_t
 uprv_convertToLCID(const char *langID, const char* posixID, UErrorCode* status)
 {
-
+    // This function does the table lookup when native platform name->lcid conversion isn't available,
+    // or for locales that don't follow patterns the platform expects.
     uint32_t   low    = 0;
     uint32_t   high   = gLocaleCount;
     uint32_t   mid;
@@ -1135,4 +1316,3 @@
     *status = U_ILLEGAL_ARGUMENT_ERROR;
     return 0;   /* return international (root) */
 }
-
diff --git a/src/third_party/icu/source/common/locmap.h b/src/third_party/icu/source/common/locmap.h
index 214bbce..e669873 100644
--- a/src/third_party/icu/source/common/locmap.h
+++ b/src/third_party/icu/source/common/locmap.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
@@ -30,8 +32,9 @@
 
 U_CAPI int32_t uprv_convertToPosix(uint32_t hostid, char* posixID, int32_t posixIDCapacity, UErrorCode* status);
 
-/* Don't call this function directly. Use uloc_getLCID instead. */
-U_CAPI uint32_t uprv_convertToLCID(const char *langID, const char* posixID, UErrorCode* status);
+/* Don't call these functions directly. Use uloc_getLCID instead. */
+U_CAPI uint32_t uprv_convertToLCIDPlatform(const char* localeID, UErrorCode* status); // Leverage platform conversion if possible
+U_CAPI uint32_t uprv_convertToLCID(const char* langID, const char* posixID, UErrorCode* status);
 
 #endif /* LOCMAP_H */
 
diff --git a/src/third_party/icu/source/common/locresdata.cpp b/src/third_party/icu/source/common/locresdata.cpp
index 68996f2..d1d9a47 100644
--- a/src/third_party/icu/source/common/locresdata.cpp
+++ b/src/third_party/icu/source/common/locresdata.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  loclikely.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -47,7 +49,6 @@
                               UErrorCode *pErrorCode)
 {
 /*    char localeBuffer[ULOC_FULLNAME_CAPACITY*4];*/
-    UResourceBundle *rb=NULL, table, subTable;
     const UChar *item=NULL;
     UErrorCode errorCode;
     char explicitFallbackName[ULOC_FULLNAME_CAPACITY] = {0};
@@ -57,7 +58,7 @@
      * this falls back through the locale's chain to root
      */
     errorCode=U_ZERO_ERROR;
-    rb=ures_open(path, locale, &errorCode);
+    icu::LocalUResourceBundlePointer rb(ures_open(path, locale, &errorCode));
 
     if(U_FAILURE(errorCode)) {
         /* total failure, not even root could be opened */
@@ -71,24 +72,24 @@
     }
 
     for(;;){
-        ures_initStackObject(&table);
-        ures_initStackObject(&subTable);
-        ures_getByKeyWithFallback(rb, tableKey, &table, &errorCode);
+        icu::StackUResourceBundle table;
+        icu::StackUResourceBundle subTable;
+        ures_getByKeyWithFallback(rb.getAlias(), tableKey, table.getAlias(), &errorCode);
 
         if (subTableKey != NULL) {
             /*
-            ures_getByKeyWithFallback(&table,subTableKey, &subTable, &errorCode);
-            item = ures_getStringByKeyWithFallback(&subTable, itemKey, pLength, &errorCode);
+            ures_getByKeyWithFallback(table.getAlias(), subTableKey, subTable.getAlias(), &errorCode);
+            item = ures_getStringByKeyWithFallback(subTable.getAlias(), itemKey, pLength, &errorCode);
             if(U_FAILURE(errorCode)){
                 *pErrorCode = errorCode;
             }
             
             break;*/
             
-            ures_getByKeyWithFallback(&table,subTableKey, &table, &errorCode);
+            ures_getByKeyWithFallback(table.getAlias(), subTableKey, table.getAlias(), &errorCode);
         }
         if(U_SUCCESS(errorCode)){
-            item = ures_getStringByKeyWithFallback(&table, itemKey, pLength, &errorCode);
+            item = ures_getStringByKeyWithFallback(table.getAlias(), itemKey, pLength, &errorCode);
             if(U_FAILURE(errorCode)){
                 const char* replacement = NULL;
                 *pErrorCode = errorCode; /*save the errorCode*/
@@ -101,7 +102,7 @@
                 }
                 /*pointer comparison is ok since uloc_getCurrentCountryID & uloc_getCurrentLanguageID return the key itself is replacement is not found*/
                 if(replacement!=NULL && itemKey != replacement){
-                    item = ures_getStringByKeyWithFallback(&table, replacement, pLength, &errorCode);
+                    item = ures_getStringByKeyWithFallback(table.getAlias(), replacement, pLength, &errorCode);
                     if(U_SUCCESS(errorCode)){
                         *pErrorCode = errorCode;
                         break;
@@ -120,7 +121,7 @@
             *pErrorCode = errorCode;
             errorCode = U_ZERO_ERROR;
 
-            fallbackLocale = ures_getStringByKeyWithFallback(&table, "Fallback", &len, &errorCode);
+            fallbackLocale = ures_getStringByKeyWithFallback(table.getAlias(), "Fallback", &len, &errorCode);
             if(U_FAILURE(errorCode)){
                *pErrorCode = errorCode;
                 break;
@@ -133,8 +134,7 @@
                 *pErrorCode = U_INTERNAL_PROGRAM_ERROR;
                 break;
             }
-            ures_close(rb);
-            rb = ures_open(path, explicitFallbackName, &errorCode);
+            rb.adoptInstead(ures_open(path, explicitFallbackName, &errorCode));
             if(U_FAILURE(errorCode)){
                 *pErrorCode = errorCode;
                 break;
@@ -144,10 +144,7 @@
             break;
         }
     }
-    /* done with the locale string - ready to close table and rb */
-    ures_close(&subTable);
-    ures_close(&table);
-    ures_close(rb);
+
     return item;
 }
 
diff --git a/src/third_party/icu/source/common/locutil.cpp b/src/third_party/icu/source/common/locutil.cpp
index 96e82ac..32c3912 100644
--- a/src/third_party/icu/source/common/locutil.cpp
+++ b/src/third_party/icu/source/common/locutil.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
  *******************************************************************************
  * Copyright (C) 2002-2014, International Business Machines Corporation and
@@ -8,9 +10,12 @@
 
 #if !UCONFIG_NO_SERVICE || !UCONFIG_NO_TRANSLITERATION
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/resbund.h"
+#include "unicode/uenum.h"
 #include "cmemory.h"
 #include "ustrfmt.h"
 #include "locutil.h"
@@ -229,15 +234,14 @@
             CharString cbundleID;
             cbundleID.appendInvariantChars(bundleID, status);
             const char* path = cbundleID.isEmpty() ? NULL : cbundleID.data();
-            UEnumeration *uenum = ures_openAvailableLocales(path, &status);
+            icu::LocalUEnumerationPointer uenum(ures_openAvailableLocales(path, &status));
             for (;;) {
-                const UChar* id = uenum_unext(uenum, NULL, &status);
+                const UChar* id = uenum_unext(uenum.getAlias(), NULL, &status);
                 if (id == NULL) {
                     break;
                 }
                 htp->put(UnicodeString(id), (void*)htp, status);
             }
-            uenum_close(uenum);
             if (U_FAILURE(status)) {
                 delete htp;
                 return NULL;
diff --git a/src/third_party/icu/source/common/locutil.h b/src/third_party/icu/source/common/locutil.h
index cf64e34..31bfffd 100644
--- a/src/third_party/icu/source/common/locutil.h
+++ b/src/third_party/icu/source/common/locutil.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /**
  *******************************************************************************
  * Copyright (C) 2002-2005, International Business Machines Corporation and    *
diff --git a/src/third_party/icu/source/common/lsr.cpp b/src/third_party/icu/source/common/lsr.cpp
new file mode 100644
index 0000000..b81808f
--- /dev/null
+++ b/src/third_party/icu/source/common/lsr.cpp
@@ -0,0 +1,114 @@
+// © 2019 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+// lsr.cpp
+// created: 2019may08 Markus W. Scherer
+
+#include "unicode/utypes.h"
+#include "charstr.h"
+#include "cmemory.h"
+#include "cstring.h"
+#include "lsr.h"
+#include "uinvchar.h"
+#include "ustr_imp.h"
+
+U_NAMESPACE_BEGIN
+
+LSR::LSR(char prefix, const char *lang, const char *scr, const char *r, int32_t f,
+         UErrorCode &errorCode) :
+        language(nullptr), script(nullptr), region(r),
+        regionIndex(indexForRegion(region)), flags(f) {
+    if (U_SUCCESS(errorCode)) {
+        CharString langScript;
+        langScript.append(prefix, errorCode).append(lang, errorCode).append('\0', errorCode);
+        int32_t scriptOffset = langScript.length();
+        langScript.append(prefix, errorCode).append(scr, errorCode);
+        owned = langScript.cloneData(errorCode);
+        if (U_SUCCESS(errorCode)) {
+            language = owned;
+            script = owned + scriptOffset;
+        }
+    }
+}
+
+LSR::LSR(LSR &&other) U_NOEXCEPT :
+        language(other.language), script(other.script), region(other.region), owned(other.owned),
+        regionIndex(other.regionIndex), flags(other.flags),
+        hashCode(other.hashCode) {
+    if (owned != nullptr) {
+        other.language = other.script = "";
+        other.owned = nullptr;
+        other.hashCode = 0;
+    }
+}
+
+void LSR::deleteOwned() {
+    uprv_free(owned);
+}
+
+LSR &LSR::operator=(LSR &&other) U_NOEXCEPT {
+    this->~LSR();
+    language = other.language;
+    script = other.script;
+    region = other.region;
+    regionIndex = other.regionIndex;
+    flags = other.flags;
+    owned = other.owned;
+    hashCode = other.hashCode;
+    if (owned != nullptr) {
+        other.language = other.script = "";
+        other.owned = nullptr;
+        other.hashCode = 0;
+    }
+    return *this;
+}
+
+UBool LSR::isEquivalentTo(const LSR &other) const {
+    return
+        uprv_strcmp(language, other.language) == 0 &&
+        uprv_strcmp(script, other.script) == 0 &&
+        regionIndex == other.regionIndex &&
+        // Compare regions if both are ill-formed (and their indexes are 0).
+        (regionIndex > 0 || uprv_strcmp(region, other.region) == 0);
+}
+
+UBool LSR::operator==(const LSR &other) const {
+    return
+        uprv_strcmp(language, other.language) == 0 &&
+        uprv_strcmp(script, other.script) == 0 &&
+        regionIndex == other.regionIndex &&
+        // Compare regions if both are ill-formed (and their indexes are 0).
+        (regionIndex > 0 || uprv_strcmp(region, other.region) == 0) &&
+        flags == other.flags;
+}
+
+int32_t LSR::indexForRegion(const char *region) {
+    int32_t c = region[0];
+    int32_t a = c - '0';
+    if (0 <= a && a <= 9) {  // digits: "419"
+        int32_t b = region[1] - '0';
+        if (b < 0 || 9 < b) { return 0; }
+        c = region[2] - '0';
+        if (c < 0 || 9 < c || region[3] != 0) { return 0; }
+        return (10 * a + b) * 10 + c + 1;
+    } else {  // letters: "DE"
+        a = uprv_upperOrdinal(c);
+        if (a < 0 || 25 < a) { return 0; }
+        int32_t b = uprv_upperOrdinal(region[1]);
+        if (b < 0 || 25 < b || region[2] != 0) { return 0; }
+        return 26 * a + b + 1001;
+    }
+    return 0;
+}
+
+LSR &LSR::setHashCode() {
+    if (hashCode == 0) {
+        uint32_t h = ustr_hashCharsN(language, static_cast<int32_t>(uprv_strlen(language)));
+        h = h * 37 + ustr_hashCharsN(script, static_cast<int32_t>(uprv_strlen(script)));
+        h = h * 37 + regionIndex;
+        hashCode = h * 37 + flags;
+    }
+    return *this;
+}
+
+U_NAMESPACE_END
diff --git a/src/third_party/icu/source/common/lsr.h b/src/third_party/icu/source/common/lsr.h
new file mode 100644
index 0000000..a33f855
--- /dev/null
+++ b/src/third_party/icu/source/common/lsr.h
@@ -0,0 +1,82 @@
+// © 2019 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+// lsr.h
+// created: 2019may08 Markus W. Scherer
+
+#ifndef __LSR_H__
+#define __LSR_H__
+
+#include "unicode/utypes.h"
+#include "unicode/uobject.h"
+#include "cstring.h"
+
+U_NAMESPACE_BEGIN
+
+struct LSR final : public UMemory {
+    static constexpr int32_t REGION_INDEX_LIMIT = 1001 + 26 * 26;
+
+    static constexpr int32_t EXPLICIT_LSR = 7;
+    static constexpr int32_t EXPLICIT_LANGUAGE = 4;
+    static constexpr int32_t EXPLICIT_SCRIPT = 2;
+    static constexpr int32_t EXPLICIT_REGION = 1;
+    static constexpr int32_t IMPLICIT_LSR = 0;
+    static constexpr int32_t DONT_CARE_FLAGS = 0;
+
+    const char *language;
+    const char *script;
+    const char *region;
+    char *owned = nullptr;
+    /** Index for region, 0 if ill-formed. @see indexForRegion */
+    int32_t regionIndex = 0;
+    int32_t flags = 0;
+    /** Only set for LSRs that will be used in a hash table. */
+    int32_t hashCode = 0;
+
+    LSR() : language("und"), script(""), region("") {}
+
+    /** Constructor which aliases all subtag pointers. */
+    LSR(const char *lang, const char *scr, const char *r, int32_t f) :
+            language(lang),  script(scr), region(r),
+            regionIndex(indexForRegion(region)), flags(f) {}
+    /**
+     * Constructor which prepends the prefix to the language and script,
+     * copies those into owned memory, and aliases the region.
+     */
+    LSR(char prefix, const char *lang, const char *scr, const char *r, int32_t f,
+        UErrorCode &errorCode);
+    LSR(LSR &&other) U_NOEXCEPT;
+    LSR(const LSR &other) = delete;
+    inline ~LSR() {
+        // Pure inline code for almost all instances.
+        if (owned != nullptr) {
+            deleteOwned();
+        }
+    }
+
+    LSR &operator=(LSR &&other) U_NOEXCEPT;
+    LSR &operator=(const LSR &other) = delete;
+
+    /**
+     * Returns a positive index (>0) for a well-formed region code.
+     * Do not rely on a particular region->index mapping; it may change.
+     * Returns 0 for ill-formed strings.
+     */
+    static int32_t indexForRegion(const char *region);
+
+    UBool isEquivalentTo(const LSR &other) const;
+    UBool operator==(const LSR &other) const;
+
+    inline UBool operator!=(const LSR &other) const {
+        return !operator==(other);
+    }
+
+    LSR &setHashCode();
+
+private:
+    void deleteOwned();
+};
+
+U_NAMESPACE_END
+
+#endif  // __LSR_H__
diff --git a/src/third_party/icu/source/common/messageimpl.h b/src/third_party/icu/source/common/messageimpl.h
index 9af400c..a564790 100644
--- a/src/third_party/icu/source/common/messageimpl.h
+++ b/src/third_party/icu/source/common/messageimpl.h
@@ -1,10 +1,12 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *   Copyright (C) 2011, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *******************************************************************************
 *   file name:  messageimpl.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -31,7 +33,7 @@
 class U_COMMON_API MessageImpl {
 public:
     /**
-     * @return TRUE if getApostropheMode()==UMSGPAT_APOS_DOUBLE_REQUIRED
+     * @return true if getApostropheMode()==UMSGPAT_APOS_DOUBLE_REQUIRED
      */
     static UBool jdkAposMode(const MessagePattern &msgPattern) {
         return msgPattern.getApostropheMode()==UMSGPAT_APOS_DOUBLE_REQUIRED;
diff --git a/src/third_party/icu/source/common/messagepattern.cpp b/src/third_party/icu/source/common/messagepattern.cpp
index 69fa342..2fc1b8d 100644
--- a/src/third_party/icu/source/common/messagepattern.cpp
+++ b/src/third_party/icu/source/common/messagepattern.cpp
@@ -1,10 +1,12 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *   Copyright (C) 2011-2012, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *******************************************************************************
 *   file name:  messagepattern.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -16,8 +18,10 @@
 
 #if !UCONFIG_NO_FORMATTING
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/messagepattern.h"
 #include "unicode/unistr.h"
 #include "unicode/utf16.h"
@@ -116,7 +120,7 @@
             errorCode=U_MEMORY_ALLOCATION_ERROR;
             return;
         }
-        uprv_memcpy(a.getAlias(), other.a.getAlias(), length*sizeof(T));
+        uprv_memcpy(a.getAlias(), other.a.getAlias(), (size_t)length*sizeof(T));
     }
 }
 
diff --git a/src/third_party/icu/source/common/msvcres.h b/src/third_party/icu/source/common/msvcres.h
index 7ed61b4..0cace85 100644
--- a/src/third_party/icu/source/common/msvcres.h
+++ b/src/third_party/icu/source/common/msvcres.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 //{{NO_DEPENDENCIES}}
 // Copyright (c) 2003-2010 International Business Machines
 // Corporation and others. All Rights Reserved.
diff --git a/src/third_party/icu/source/common/mutex.h b/src/third_party/icu/source/common/mutex.h
index 07dcdbb..44b1f90 100644
--- a/src/third_party/icu/source/common/mutex.h
+++ b/src/third_party/icu/source/common/mutex.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
@@ -26,50 +28,48 @@
 
 U_NAMESPACE_BEGIN
 
-//----------------------------------------------------------------------------
-// Code within that accesses shared static or global data should
-// should instantiate a Mutex object while doing so. You should make your own 
-// private mutex where possible.
-
-// For example:
-// 
-// UMutex myMutex;
-// 
-// void Function(int arg1, int arg2)
-// {
-//    static Object* foo;     // Shared read-write object
-//    Mutex mutex(&myMutex);  // or no args for the global lock
-//    foo->Method();
-//    // When 'mutex' goes out of scope and gets destroyed here, the lock is released
-// }
-//
-// Note:  Do NOT use the form 'Mutex mutex();' as that merely forward-declares a function
-//        returning a Mutex. This is a common mistake which silently slips through the
-//        compiler!!
-//
+/**
+  * Mutex is a helper class for convenient locking and unlocking of a UMutex.
+  *
+  * Creating a local scope Mutex will lock a UMutex, holding the lock until the Mutex
+  * goes out of scope.
+  *
+  *  If no UMutex is specified, the ICU global mutex is implied.
+  *
+  *  For example:
+  *
+  *  static UMutex myMutex;
+  *
+  *  void Function(int arg1, int arg2)
+  *  {
+  *     static Object* foo;      // Shared read-write object
+  *     Mutex mutex(&myMutex);   // or no args for the global lock
+  *     foo->Method();
+  *     // When 'mutex' goes out of scope and gets destroyed here, the lock is released
+  *  }
+  *
+  *  Note:  Do NOT use the form 'Mutex mutex();' as that merely forward-declares a function
+  *         returning a Mutex. This is a common mistake which silently slips through the
+  *         compiler!!
+  */
 
 class U_COMMON_API Mutex : public UMemory {
 public:
-  inline Mutex(UMutex *mutex = NULL);
-  inline ~Mutex();
+    Mutex(UMutex *mutex = nullptr) : fMutex(mutex) {
+        umtx_lock(fMutex);
+    }
+    ~Mutex() {
+        umtx_unlock(fMutex);
+    }
+
+    Mutex(const Mutex &other) = delete; // forbid assigning of this class
+    Mutex &operator=(const Mutex &other) = delete; // forbid copying of this class
+    void *operator new(size_t s) = delete;  // forbid heap allocation. Locals only.
 
 private:
-  UMutex   *fMutex;
-
-  Mutex(const Mutex &other); // forbid copying of this class
-  Mutex &operator=(const Mutex &other); // forbid copying of this class
+    UMutex   *fMutex;
 };
 
-inline Mutex::Mutex(UMutex *mutex)
-  : fMutex(mutex)
-{
-  umtx_lock(fMutex);
-}
-
-inline Mutex::~Mutex()
-{
-  umtx_unlock(fMutex);
-}
 
 U_NAMESPACE_END
 
diff --git a/src/third_party/icu/source/common/norm2_nfc_data.h b/src/third_party/icu/source/common/norm2_nfc_data.h
index 0b9124b..455cc0c 100644
--- a/src/third_party/icu/source/common/norm2_nfc_data.h
+++ b/src/third_party/icu/source/common/norm2_nfc_data.h
@@ -1,611 +1,646 @@
-/*
- * Copyright (C) 1999-2015, International Business Machines
- * Corporation and others.  All Rights Reserved.
- *
- * file name: norm2_nfc_data.h
- *
- * machine-generated by: icu/source/tools/gennorm2/n2builder.cpp
- */
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+//
+// Copyright (C) 1999-2016, International Business Machines
+// Corporation and others.  All Rights Reserved.
+//
+// file name: norm2_nfc_data.h
+//
+// machine-generated by: icu/source/tools/gennorm2/n2builder.cpp
 
-static const UVersionInfo norm2_nfc_data_formatVersion={2,0,0,0};
-static const UVersionInfo norm2_nfc_data_dataVersion={8,0,0,0};
+
+#ifdef INCLUDED_FROM_NORMALIZER2_CPP
+
+static const UVersionInfo norm2_nfc_data_formatVersion={4,0,0,0};
+static const UVersionInfo norm2_nfc_data_dataVersion={0xd,0,0,0};
 
 static const int32_t norm2_nfc_data_indexes[Normalizer2Impl::IX_COUNT]={
-0x40,0x49c0,0x8614,0x8714,0x8714,0x8714,0x8714,0x8714,0xc0,0x300,0x56e,0x14e7,0x1e2a,0xfe00,0x941,0
+0x50,0x4bac,0x8814,0x8914,0x8914,0x8914,0x8914,0x8914,0xc0,0x300,0xae2,0x29e0,0x3c66,0xfc00,0x1288,0x3b9c,
+0x3c34,0x3c66,0x300,0
 };
 
-static const uint16_t norm2_nfc_data_trieIndex[9400]={
-0x28d,0x295,0x29d,0x2a5,0x2b3,0x2bb,0x2c3,0x2cb,0x2d3,0x2db,0x2e3,0x2eb,0x2f3,0x2fb,0x301,0x309,
-0x311,0x319,0x2ac,0x2b4,0x31e,0x326,0x2ac,0x2b4,0x32e,0x336,0x33e,0x346,0x34e,0x356,0x35e,0x366,
-0x36e,0x376,0x37e,0x386,0x38e,0x396,0x39e,0x3a6,0x2ac,0x2b4,0x2ac,0x2b4,0x3ad,0x3b5,0x3bd,0x3c5,
-0x3c9,0x3d1,0x3d7,0x3df,0x2ac,0x2b4,0x3e7,0x3ef,0x3f3,0x3fb,0x403,0x40b,0x2ac,0x2b4,0x409,0x411,
-0x416,0x41d,0x421,0x2ac,0x2ac,0x2ac,0x2ac,0x429,0x2ac,0x431,0x439,0x2ac,0x2ac,0x441,0x449,0x2ac,
-0x2ac,0x451,0x459,0x2ac,0x2ac,0x461,0x469,0x2ac,0x2ac,0x441,0x470,0x2ac,0x478,0x47e,0x486,0x2ac,
-0x2ac,0x2ac,0x48d,0x2ac,0x2ac,0x493,0x49b,0x2ac,0x2ac,0x47e,0x4a2,0x2ac,0x2ac,0x2ac,0x4a8,0x2ac,
-0x2ac,0x4b0,0x4b7,0x2ac,0x2ac,0x4ba,0x4c1,0x2ac,0x4c4,0x4cb,0x4d3,0x4db,0x4e3,0x4eb,0x4f2,0x2ac,
-0x2ac,0x4f9,0x2ac,0x2ac,0x500,0x2ac,0x2ac,0x2ac,0x8ea,0x2ac,0x2ac,0x8f2,0x2ac,0x8f8,0x900,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x504,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x50c,0x50c,0x2ac,0x2ac,0x2ac,0x2ac,0x512,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x51a,0x2ac,0x2ac,0x2ac,0x51d,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x524,0x2ac,0x2ac,0x52c,0x2ac,0x534,0x2ac,0x2ac,0x53c,0x541,0x549,0x54f,0x2ac,0x555,0x2ac,0x55c,
-0x2ac,0x561,0x2ac,0x2ac,0x2ac,0x2ac,0x567,0x56f,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x577,0x57c,
-0x584,0x58c,0x594,0x59c,0x5a4,0x5ac,0x5b4,0x5bc,0x5c4,0x5cc,0x5d4,0x5dc,0x5e4,0x5ec,0x5f4,0x5fc,
-0x604,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x608,0x610,0x2ac,0x617,0x2ac,0x2ac,0x61b,0x622,0x627,0x2ac,
-0x62f,0x637,0x63f,0x647,0x64f,0x657,0x2ac,0x65f,0x2ac,0x665,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x668,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x670,0x2ac,0x2ac,0x2ac,0x675,0x2ac,0x2ac,0x2ac,0x67d,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x685,0x68c,0x694,0x69c,0x6a4,0x6ac,0x6b4,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x6bc,0x6c4,0x2ac,0x2ac,0x6cc,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x6d3,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x6da,0x6e2,0x2ac,0x6e8,0x6ec,0x2ac,0x2ac,0x562,0x6f4,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x6f8,0x700,0x703,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x469,
-0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,
-0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,
-0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,
-0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,
-0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,
-0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,
-0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,
-0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,
-0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,
-0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,
-0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,
-0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,
-0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,
-0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,
-0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,
-0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,
-0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,
-0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,
-0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,
-0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,
-0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,
-0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x908,0x90f,0x2ac,0x2ac,
-0x917,0x91e,0x28d,0x925,0x28d,0x28d,0x28d,0x28d,0x28d,0x28d,0x28d,0x28d,0x28d,0x28d,0x28d,0x28d,
-0x28d,0x28d,0x28d,0x28d,0x28d,0x28d,0x28d,0x28d,0x28d,0x28d,0x28d,0x28d,0x28d,0x28d,0x28d,0x28d,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x70b,0x713,0x71b,0x723,0x72b,0x733,0x73b,0x743,
-0x74b,0x753,0x75b,0x763,0x76b,0x773,0x77b,0x2ac,0x782,0x78a,0x792,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x79a,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0xab4,0xab4,0xacc,0xb0c,0xb4c,0xb8c,0xbcc,0xc04,0xc44,0xab0,0xc78,0xab0,0xcb8,0xcf8,0xd38,0xd78,
-0xdb8,0xdf8,0xe38,0xe78,0xab0,0xab0,0xeb4,0xef4,0xf24,0xf5c,0xab0,0xf9c,0xfcc,0x100c,0xab0,0x1024,
-0x880,0x8b0,0x8ee,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x928,0x188,0x188,
-0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x944,0x188,0x188,0x97a,0x188,0x188,0x9b4,0x188,0x188,
-0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,
-0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x9f4,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x79e,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x7a6,0x2ac,0x2ac,0x2ac,0x7a9,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x7b0,0x7b4,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x7bc,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x6d3,0x675,0x7be,0x7c6,0x2ac,0x2ac,0x7ce,0x7d5,0x2ac,0x562,0x2ac,0x2ac,0x7dd,0x2ac,0x2ac,0x7e0,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x7e6,0x2ac,0x441,0x7ed,0x7f4,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x7fa,0x802,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x807,0x80f,0x2ac,0x2ac,0x675,
-0x2ac,0x2ac,0x2ac,0x812,0x2ac,0x2ac,0x2ac,0x818,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x81c,
-0x2ac,0x822,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x828,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x830,0x838,0x840,0x846,0x84e,0x2ac,0x2ac,0x2ac,0x856,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x85a,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x862,0x86a,0x872,0x87a,0x882,0x88a,0x892,0x89a,0x8a2,0x8aa,0x8b2,0x8ba,
-0x8c2,0x8ca,0x8d2,0x8da,0x8e2,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,
-0x2ac,0x2ac,0x2ac,0x2ac,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-2,4,6,0,0,8,0x28,0x2e,0x38,0x44,0x66,0x68,0x76,0x84,0xa2,0xa4,
-0xae,0xba,0xc0,0xd2,0xf2,0,0xf6,0x106,0x114,0x122,0x148,0x14c,0x158,0x15c,0x16e,0,
-0,0,0,0,0,0x17a,0x19a,0x1a0,0x1aa,0x1b6,0x1d8,0x1da,0x1e8,0x1f8,0x214,0x218,
-0x222,0x22e,0x234,0x246,0x266,0,0x26a,0x27a,0x288,0x298,0x2be,0x2c2,0x2d0,0x2d4,0x2e8,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0x2f4,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0x941,0x944,0x56f,0x947,
-0x57a,0x57f,0x2fa,0x584,0x94a,0x94d,0x589,0x950,0x953,0x956,0x959,0x594,0,0x95c,0x95f,0x962,
-0x599,0x5a4,0x5ad,0,0x2fe,0x965,0x968,0x96b,0x5b2,0x96e,0,0,0x971,0x974,0x5bd,0x977,
-0x5c8,0x5cd,0x300,0x5d2,0x97a,0x97d,0x5d7,0x980,0x983,0x986,0x989,0x5e2,0,0x98c,0x98f,0x992,
-0x5e7,0x5f2,0x5fb,0,0x304,0x995,0x998,0x99b,0x600,0x99e,0,0x9a1,0x9a4,0x9a7,0x60b,0x616,
-0x9aa,0x9ad,0x9b0,0x9b3,0x9b6,0x9b9,0x9bc,0x9bf,0x9c2,0x9c5,0x9c8,0x9cb,0,0,0x621,0x628,
-0x9ce,0x9d1,0x9d4,0x9d7,0x9da,0x9dd,0x9e0,0x9e3,0x9e6,0x9e9,0x9ec,0x9ef,0x9f2,0x9f5,0x9f8,0x9fb,
-0x9fe,0xa01,0,0,0xa04,0xa07,0xa0a,0xa0d,0xa10,0xa13,0xa16,0xa19,0xa1c,0,0,0,
-0xa1f,0xa22,0xa25,0xa28,0,0xa2b,0xa2e,0xa31,0xa34,0xa37,0xa3a,0,0,0,0,0xa3d,
-0xa40,0xa43,0xa46,0xa49,0xa4c,0,0,0,0x62f,0x636,0xa4f,0xa52,0xa55,0xa58,0,0,
-0xa5b,0xa5e,0xa61,0xa64,0xa67,0xa6a,0x63d,0x642,0xa6d,0xa70,0xa73,0xa76,0x647,0x64c,0xa79,0xa7c,
-0xa7f,0xa82,0,0,0x651,0x656,0x65b,0x660,0xa85,0xa88,0xa8b,0xa8e,0xa91,0xa94,0xa97,0xa9a,
-0xa9d,0xaa0,0xaa3,0xaa6,0xaa9,0xaac,0xaaf,0xab2,0xab5,0xab8,0xabb,0x306,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0x665,0x672,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0x67f,0x68c,0,0,0,
-0,0,0,0x308,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0xabe,0xac1,0xac4,0xac7,0xaca,0xacd,0xad0,0xad3,0xad7,0xadc,0xae1,0xae6,0xaeb,0xaf0,0xaf5,
-0xafa,0,0xaff,0xb04,0xb09,0xb0e,0xb12,0xb15,0,0,0xb18,0xb1b,0xb1e,0xb21,0x699,0x69e,
-0xb25,0xb2a,0xb2e,0xb31,0xb34,0,0,0,0xb37,0xb3a,0,0,0xb3d,0xb40,0xb44,0xb49,
-0xb4d,0xb50,0xb53,0xb56,0xb59,0xb5c,0xb5f,0xb62,0xb65,0xb68,0xb6b,0xb6e,0xb71,0xb74,0xb77,0xb7a,
-0xb7d,0xb80,0xb83,0xb86,0xb89,0xb8c,0xb8f,0xb92,0xb95,0xb98,0xb9b,0xb9e,0xba1,0xba4,0xba7,0xbaa,
-0,0,0xbad,0xbb0,0,0,0,0,0,0,0x6a3,0x6a8,0x6ad,0x6b2,0xbb4,0xbb9,
-0xbbe,0xbc3,0x6b7,0x6bc,0xbc8,0xbcd,0xbd1,0xbd4,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0x30a,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0xfee6,0xfee6,0xfee6,0xfee6,0xfee6,0xffe6,0xfee6,0xfee6,
-0xfee6,0xfee6,0xfee6,0xfee6,0xfee6,0xffe6,0xffe6,0xfee6,0xffe6,0xfee6,0xffe6,0xfee6,0xfee6,0xffe8,0xffdc,0xffdc,
-0xffdc,0xffdc,0xffe8,0xfed8,0xffdc,0xffdc,0xffdc,0xffdc,0xffdc,0xffca,0xffca,0xfedc,0xfedc,0xfedc,0xfedc,0xfeca,
-0xfeca,0xffdc,0xffdc,0xffdc,0xffdc,0xfedc,0xfedc,0xffdc,0xfedc,0xfedc,0xffdc,0xffdc,0xff01,0xff01,0xff01,0xff01,
-0xfe01,0xffdc,0xffdc,0xffdc,0xffdc,0xffe6,0xffe6,0xffe6,0x14e8,0x14eb,0xfee6,0x14ee,0x14f1,0xfef0,0xffe6,0xffdc,
-0xffdc,0xffdc,0xffe6,0xffe6,0xffe6,0xffdc,0xffdc,0,0xffe6,0xffe6,0xffe6,0xffdc,0xffdc,0xffdc,0xffdc,0xffe6,
-0xffe8,0xffdc,0xffdc,0xffe6,0xffe9,0xffea,0xffea,0xffe9,0xffea,0xffea,0xffe9,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,
-0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0,0,0,0,0x14f4,0,0,0,
-0,0,0,0,0,0,0x14f6,0,0,0,0,0,0,0xbd7,0xbda,0x14f8,
-0xbdd,0xbe0,0xbe3,0,0xbe6,0,0xbe9,0xbec,0xbf0,0x30c,0,0,0,0x31a,0,0x322,
-0,0x32c,0,0,0,0,0,0x33a,0,0x342,0,0,0,0x344,0,0,
-0,0x350,0xbf4,0xbf7,0x6c1,0xbfa,0x6c6,0xbfd,0xc01,0x35a,0,0,0,0x36a,0,0x372,
-0,0x37e,0,0,0,0,0,0x38e,0,0x396,0,0,0,0x39a,0,0,
-0,0x3aa,0x6cb,0x6d4,0xc05,0xc08,0x6dd,0,0,0,0x3b6,0xc0b,0xc0e,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0xc11,0xc14,0,0xc17,0,0,0x3ba,0xc1a,
-0,0,0,0,0xc1d,0xc20,0xc23,0,0x3bc,0,0,0x3c0,0,0x3c2,0x3c8,0x3cc,
-0x3ce,0xc26,0x3d6,0,0,0,0x3d8,0,0,0,0,0x3da,0,0,0,0x3e2,
-0,0,0,0x3e4,0,0x3e6,0,0,0x3e8,0,0,0x3ec,0,0x3ee,0x3f4,0x3f8,
-0x3fa,0xc29,0x402,0,0,0,0x404,0,0,0,0,0x406,0,0,0,0x40e,
-0,0,0,0x410,0,0x412,0,0,0xc2c,0xc2f,0,0xc32,0,0,0x414,0xc35,
-0,0,0,0,0xc38,0xc3b,0xc3e,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0x416,0x418,0xc41,0xc44,
-0,0,0,0,0,0,0,0,0,0,0,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0xc47,0xc4a,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0xc4d,0xc50,0xc53,0xc56,0,0,0xc59,0xc5c,
-0x41a,0x41c,0xc5f,0xc62,0xc65,0xc68,0xc6b,0xc6e,0,0,0xc71,0xc74,0xc77,0xc7a,0xc7d,0xc80,
-0x41e,0x420,0xc83,0xc86,0xc89,0xc8c,0xc8f,0xc92,0xc95,0xc98,0xc9b,0xc9e,0xca1,0xca4,0,0,
-0xca7,0xcaa,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0xffdc,0xffe6,0xffe6,0xffe6,0xffe6,0xffdc,0xffe6,0xffe6,0xffe6,0xffde,0xffdc,
-0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffdc,0xffdc,0xffdc,0xffdc,0xffdc,0xffdc,0xffe6,0xffe6,0xffdc,0xffe6,
-0xffe6,0xffde,0xffe4,0xffe6,0xff0a,0xff0b,0xff0c,0xff0d,0xff0e,0xff0f,0xff10,0xff11,0xff12,0xff13,0xff13,0xff14,
-0xff15,0xff16,0,0xff17,0,0xff18,0xff19,0,0xffe6,0xffdc,0,0xff12,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xff1e,0xff1f,0xff20,0,
-0,0,0,0,0,0,0xcad,0xcb0,0xcb3,0xcb6,0xcb9,0x422,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0x428,0,0x42a,0xff1b,0xff1c,0xff1d,0xff1e,0xff1f,0xff20,0xff21,0xff22,0xfee6,
-0xfee6,0xfedc,0xffdc,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffdc,0xffe6,0xffe6,0xffdc,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0xff23,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0xcbc,0x42c,0xcbf,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x42e,0xcc2,
-0,0x430,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0,0,0xffe6,0xffe6,0xffe6,0xffe6,0xffdc,
-0xffe6,0,0,0xffe6,0xffe6,0,0xffdc,0xffe6,0xffe6,0xffdc,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0xff24,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0xffe6,0xffdc,0xffe6,0xffe6,
-0xffdc,0xffe6,0xffe6,0xffdc,0xffdc,0xffdc,0xffe6,0xffdc,0xffdc,0xffe6,0xffdc,0xffe6,0xffe6,0xffe6,0xffdc,0xffe6,
-0xffdc,0xffe6,0xffdc,0xffe6,0xffdc,0xffe6,0xffe6,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xffe6,
-0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffdc,0xffe6,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xffe6,0xffe6,
-0xffe6,0xffe6,0,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0,0xffe6,0xffe6,0xffe6,0,0xffe6,0xffe6,0xffe6,
-0xffe6,0xffe6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0xffdc,0xffdc,0xffdc,
-0,0,0,0,0,0,0,0xffdc,0xffe6,0xffe6,0xffdc,0xffe6,0xffe6,0xffdc,0xffe6,0xffe6,
-0xffe6,0xffdc,0xffdc,0xffdc,0xff1b,0xff1c,0xff1d,0xffe6,0xffe6,0xffe6,0xffdc,0xffe6,0xffe6,0xffdc,0xffdc,0xffe6,
-0xffe6,0xffe6,0xffe6,0xffe6,0,0,0,0,0,0,0,0,0x432,0xcc5,0,0,
-0,0,0,0,0x434,0xcc8,0,0x436,0xccb,0,0,0,0,0,0,0,
-0xfe07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0xff09,0,0,0,0xffe6,0xffdc,0xffe6,0xffe6,0,0,0,0x14fa,0x14fd,0x1500,0x1503,
-0x1506,0x1509,0x150c,0x150f,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0xff07,0,0xfe00,0,0,0,0,0,0,0,0,0x438,0,0,0,0xcce,
-0xcd1,0xff09,0,0,0,0,0,0,0,0,0,0xfe00,0,0,0,0,
-0x1512,0x1515,0,0x1518,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0x151b,0,0,0x151e,0,0,0,0,0,
-0xff07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0xff09,0,0,0,0,0,0,0,0,0,0,0,0x1521,0x1524,0x1527,
-0,0,0x152a,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0xff07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0xff09,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0x43c,0xcd4,0,0,0xcd7,0xcda,0xff09,0,0,
-0,0,0,0,0,0,0xfe00,0xfe00,0,0,0,0,0x152d,0x1530,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0x442,0,0xcdd,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0xfe00,0,0,0,0,0,0,0,0x444,0x448,
-0,0,0xce0,0xce3,0xce6,0xff09,0,0,0,0,0,0,0,0,0,0xfe00,
-0,0,0,0,0,0,0,0,0,0,0x44a,0,0xce9,0,0,0,
-0,0xff09,0,0,0,0,0,0,0,0xff54,0xfe5b,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0xff07,0,0,0x44c,0xcec,0,0xfe00,0,
-0,0,0x44e,0xcef,0xcf2,0,0x6e2,0xcf6,0,0xff09,0,0,0,0,0,0,
-0,0xfe00,0xfe00,0,0,0,0,0,0,0,0,0,0,0,0x454,0x458,
-0,0,0xcfa,0xcfd,0xd00,0xff09,0,0,0,0,0,0,0,0,0,0xfe00,
-0,0,0,0,0,0,0,0,0,0,0xfe09,0,0,0,0,0xfe00,
-0,0,0,0,0,0,0,0,0,0x45a,0xd03,0,0x6e7,0xd07,0xd0b,0xfe00,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0xff67,0xff67,0xff09,0,0,0,0,0,
-0,0,0,0,0xff6b,0xff6b,0xff6b,0xff6b,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0xff76,0xff76,0,0,0,0,0,0,0,0,0,0,0xff7a,0xff7a,0xff7a,0xff7a,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0xffdc,0xffdc,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0xffdc,0,0xffdc,0,0xffd8,0,0,0,0,0,0,0,0,0,0x1533,
-0,0,0,0,0,0,0,0,0,0x1536,0,0,0,0,0x1539,0,
-0,0,0,0x153c,0,0,0,0,0x153f,0,0,0,0,0,0,0,
-0,0,0,0,0,0x1542,0,0,0,0,0,0,0,0xff81,0xff82,0x1546,
-0xff84,0x154a,0x154d,0,0x1550,0,0xff82,0xff82,0xff82,0xff82,0,0,0xff82,0x1554,0xffe6,0xffe6,
-0xff09,0,0xffe6,0xffe6,0,0,0,0,0,0,0,0,0,0,0,0x1557,
-0,0,0,0,0,0,0,0,0,0x155a,0,0,0,0,0x155d,0,
-0,0,0,0x1560,0,0,0,0,0x1563,0,0,0,0,0,0,0,
-0,0,0,0,0,0x1566,0,0,0,0,0,0,0,0,0xffdc,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0x460,0xd0e,0,0,0,0,0,
-0,0,0xfe00,0,0,0,0,0,0,0,0,0xff07,0,0xff09,0xff09,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0xffdc,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0xffe6,0xffe6,0xffe6,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0xff09,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0xff09,0,0,0,0,0,
-0,0,0,0,0,0xffe6,0,0,0,0,0,0,0,0,0,0,
-0,0xffe4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0xffde,0xffe6,0xffdc,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0xffe6,0xffdc,0,0,0,0,0,0,0,
-0xff09,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0,0,0xffdc,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffdc,0xffdc,0xffdc,0xffdc,0xffdc,0xffdc,0xffe6,0xffe6,0xffdc,0,0,
-0,0,0,0,0,0x462,0xd11,0x464,0xd14,0x466,0xd17,0x468,0xd1a,0x46a,0xd1d,0,
-0,0x46c,0xd20,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0xff07,0xfe00,0,0,0,0,0x46e,0xd23,
-0x470,0xd26,0x472,0x474,0xd29,0xd2c,0x476,0xd2f,0xff09,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0xffe6,0xffdc,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xff09,0xff09,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0xff07,0,0,0,0,0,0,0,0,0,
-0,0,0xff09,0xff09,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0xff07,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0xffe6,0xffe6,0xffe6,0,
-0xff01,0xffdc,0xffdc,0xffdc,0xffdc,0xffdc,0xffe6,0xffe6,0xffdc,0xffdc,0xffdc,0xffdc,0xffe6,0,0xff01,0xff01,
-0xff01,0xff01,0xff01,0xff01,0xff01,0,0,0,0,0xffdc,0,0,0,0,0,0,
-0xffe6,0,0,0,0xffe6,0xffe6,0,0,0,0,0,0,0xffe6,0xffe6,0xffdc,0xffe6,
-0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffdc,0xffe6,0xffe6,0xffea,0xffd6,0xffdc,0xffca,0xffe6,0xffe6,0xffe6,
-0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,
-0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0,0,0,0,0,0,0xffe9,0xffdc,0xffe6,0xffdc,
-0xd32,0xd35,0xd38,0xd3b,0xd3e,0xd41,0xd44,0xd47,0xd4b,0xd50,0xd54,0xd57,0xd5a,0xd5d,0xd60,0xd63,
-0xd66,0xd69,0xd6c,0xd6f,0xd73,0xd78,0xd7d,0xd82,0xd86,0xd89,0xd8c,0xd8f,0xd93,0xd98,0xd9c,0xd9f,
-0xda2,0xda5,0xda8,0xdab,0xdae,0xdb1,0xdb4,0xdb7,0xdba,0xdbd,0xdc0,0xdc3,0xdc6,0xdc9,0xdcd,0xdd2,
-0xdd6,0xdd9,0xddc,0xddf,0xde2,0xde5,0x6ec,0x6f1,0xde9,0xdee,0xdf2,0xdf5,0xdf8,0xdfb,0xdfe,0xe01,
-0xe04,0xe07,0xe0a,0xe0d,0xe10,0xe13,0xe16,0xe19,0xe1c,0xe1f,0xe22,0xe25,0xe29,0xe2e,0xe33,0xe38,
-0xe3d,0xe42,0xe47,0xe4c,0xe50,0xe53,0xe56,0xe59,0xe5c,0xe5f,0x6f6,0x6fb,0xe63,0xe68,0xe6c,0xe6f,
-0xe72,0xe75,0x700,0x705,0xe79,0xe7e,0xe83,0xe88,0xe8d,0xe92,0xe96,0xe99,0xe9c,0xe9f,0xea2,0xea5,
-0xea8,0xeab,0xeae,0xeb1,0xeb4,0xeb7,0xeba,0xebd,0xec1,0xec6,0xecb,0xed0,0xed4,0xed7,0xeda,0xedd,
-0xee0,0xee3,0xee6,0xee9,0xeec,0xeef,0xef2,0xef5,0xef8,0xefb,0xefe,0xf01,0xf04,0xf07,0xf0a,0xf0d,
-0xf10,0xf13,0xf16,0xf19,0xf1c,0xf1f,0xf22,0xf25,0xf28,0xf2b,0,0xf2e,0,0,0,0,
-0x70a,0x711,0xf31,0xf34,0xf38,0xf3d,0xf42,0xf47,0xf4c,0xf51,0xf56,0xf5b,0xf60,0xf65,0xf6a,0xf6f,
-0xf74,0xf79,0xf7e,0xf83,0xf88,0xf8d,0xf92,0xf97,0x718,0x71d,0xf9b,0xf9e,0xfa1,0xfa4,0xfa8,0xfad,
-0xfb2,0xfb7,0xfbc,0xfc1,0xfc6,0xfcb,0xfd0,0xfd5,0xfd9,0xfdc,0xfdf,0xfe2,0x722,0x727,0xfe5,0xfe8,
-0xfec,0xff1,0xff6,0xffb,0x1000,0x1005,0x100a,0x100f,0x1014,0x1019,0x101e,0x1023,0x1028,0x102d,0x1032,0x1037,
-0x103c,0x1041,0x1046,0x104b,0x104f,0x1052,0x1055,0x1058,0x105c,0x1061,0x1066,0x106b,0x1070,0x1075,0x107a,0x107f,
-0x1084,0x1089,0x108d,0x1090,0x1093,0x1096,0x1099,0x109c,0x109f,0x10a2,0,0,0,0,0,0,
-0x72c,0x737,0x743,0x74a,0x751,0x758,0x75f,0x766,0x76c,0x777,0x783,0x78a,0x791,0x798,0x79f,0x7a6,
-0x7ac,0x7b3,0x10a6,0x10ab,0x10b0,0x10b5,0,0,0x7ba,0x7c1,0x10ba,0x10bf,0x10c4,0x10c9,0,0,
-0x7c8,0x7d3,0x7df,0x7e6,0x7ed,0x7f4,0x7fb,0x802,0x808,0x813,0x81f,0x826,0x82d,0x834,0x83b,0x842,
-0x848,0x851,0x10ce,0x10d3,0x10d8,0x10dd,0x10e2,0x10e7,0x85a,0x863,0x10ec,0x10f1,0x10f6,0x10fb,0x1100,0x1105,
-0x86c,0x873,0x110a,0x110f,0x1114,0x1119,0,0,0x87a,0x881,0x111e,0x1123,0x1128,0x112d,0,0,
-0x888,0x891,0x1132,0x1137,0x113c,0x1141,0x1146,0x114b,0,0x89a,0,0x1150,0,0x1155,0,0x115a,
-0x8a3,0x8ae,0x8ba,0x8c1,0x8c8,0x8cf,0x8d6,0x8dd,0x8e3,0x8ee,0x8fa,0x901,0x908,0x90f,0x916,0x91d,
-0x923,0x156a,0x115e,0x156e,0x928,0x1572,0x1161,0x1576,0x1164,0x157a,0x1167,0x157e,0x92d,0x1582,0,0,
-0x116b,0x1170,0x1177,0x117f,0x1187,0x118f,0x1197,0x119f,0x11a5,0x11aa,0x11b1,0x11b9,0x11c1,0x11c9,0x11d1,0x11d9,
-0x11df,0x11e4,0x11eb,0x11f3,0x11fb,0x1203,0x120b,0x1213,0x1219,0x121e,0x1225,0x122d,0x1235,0x123d,0x1245,0x124d,
-0x1253,0x1258,0x125f,0x1267,0x126f,0x1277,0x127f,0x1287,0x128d,0x1292,0x1299,0x12a1,0x12a9,0x12b1,0x12b9,0x12c1,
-0x12c6,0x12c9,0x12cd,0x12d1,0x12d5,0,0x932,0x12da,0x12de,0x12e1,0x12e4,0x1586,0x12e7,0,0x1589,0x478,
-0,0x12ea,0x12ee,0x12f2,0x12f6,0,0x937,0x12fb,0x12ff,0x158c,0x1302,0x1590,0x1305,0x1308,0x130b,0x130e,
-0x1311,0x1314,0x1318,0x1595,0,0,0x131c,0x1320,0x1324,0x1327,0x132a,0x159a,0,0x132d,0x1330,0x1333,
-0x1336,0x1339,0x133d,0x159f,0x1341,0x1344,0x1347,0x134b,0x134f,0x1352,0x1355,0x15a4,0x1358,0x135b,0x15a8,0x15ab,
-0,0,0x135f,0x1363,0x1367,0,0x93c,0x136c,0x1370,0x15ae,0x1373,0x15b2,0x1376,0x15b5,0x47e,0,
-0xfdc1,0xfdc1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0xffe6,0xffe6,0xff01,0xff01,0xffe6,0xffe6,0xffe6,0xffe6,0xff01,0xff01,0xff01,0xffe6,0xffe6,0,0,0,
-0,0xffe6,0,0,0,0xff01,0xff01,0xffe6,0xffdc,0xffe6,0xff01,0xff01,0xffdc,0xffdc,0xffdc,0xffdc,
-0xffe6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0x15b7,0,0,0,0x15b9,0x15bc,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0x484,0,0x486,0,
-0x488,0,0,0,0,0,0x1379,0x137c,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0x137f,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0x1382,0x1385,0x1388,0x48a,0,0x48c,0,
-0x48e,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x490,
-0x138b,0,0,0,0x492,0x138e,0,0x494,0x1391,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x496,
-0x1394,0x498,0x1397,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0x49a,0,0,0,0,0x139a,0,0x49c,
-0x139d,0x49e,0,0x13a0,0x4a0,0x13a3,0,0,0,0x4a2,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0x13a6,0x4a4,0x13a9,0,
-0x4a6,0x4a8,0,0,0,0,0,0,0,0x13ac,0x13af,0x13b2,0x13b5,0x13b8,0x4aa,0x4ac,
-0x13bb,0x13be,0x4ae,0x4b0,0x13c1,0x13c4,0x4b2,0x4b4,0x4b6,0x4b8,0,0,0x13c7,0x13ca,0x4ba,0x4bc,
-0x13cd,0x13d0,0x4be,0x4c0,0x13d3,0x13d6,0,0,0,0,0,0,0,0x4c2,0x4c4,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x4c6,0,
-0,0,0,0,0x4c8,0x4ca,0,0x4cc,0x13d9,0x13dc,0x13df,0x13e2,0,0,0x4ce,0x4d0,
-0x4d2,0x4d4,0,0,0,0,0,0,0,0,0,0,0x13e5,0x13e8,0x13eb,0x13ee,
-0,0,0,0,0,0,0x13f1,0x13f4,0x13f7,0x13fa,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0x15bf,0x15c1,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0x15c3,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xffe6,
-0xffe6,0xffe6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0xff09,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,
-0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,
-0xffe6,0xffe6,0xffe6,0xffe6,0,0,0,0,0,0,0,0,0,0,0xffda,0xffe4,
-0xffe8,0xffde,0xffe0,0xffe0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0x4d6,0,0,0,0,0x4d8,0x13fd,0x4da,0x1400,0x4dc,
-0x1403,0x4de,0x1406,0x4e0,0x1409,0x4e2,0x140c,0x4e4,0x140f,0x4e6,0x1412,0x4e8,0x1415,0x4ea,0x1418,0x4ec,
-0x141b,0x4ee,0x141e,0,0x4f0,0x1421,0x4f2,0x1424,0x4f4,0x1427,0,0,0,0,0,0x4f6,
-0x142a,0x142d,0x4fa,0x1430,0x1433,0x4fe,0x1436,0x1439,0x502,0x143c,0x143f,0x506,0x1442,0x1445,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0x1448,0,0,0,0,0xfe08,0xfe08,0,0,0x50a,0x144b,0,
-0,0,0,0,0,0,0x50c,0,0,0,0,0x50e,0x144e,0x510,0x1451,0x512,
-0x1454,0x514,0x1457,0x516,0x145a,0x518,0x145d,0x51a,0x1460,0x51c,0x1463,0x51e,0x1466,0x520,0x1469,0x522,
-0x146c,0x524,0x146f,0,0x526,0x1472,0x528,0x1475,0x52a,0x1478,0,0,0,0,0,0x52c,
-0x147b,0x147e,0x530,0x1481,0x1484,0x534,0x1487,0x148a,0x538,0x148d,0x1490,0x53c,0x1493,0x1496,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x540,
-0x542,0x544,0x546,0,0x1499,0,0,0x149c,0x149f,0x14a2,0x14a5,0,0,0x548,0x14a8,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xffe6,
-0,0,0,0,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xffe6,0xffe6,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0xffe6,0xffe6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0xff09,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0xff09,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,
-0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0xffdc,0xffdc,0xffdc,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0xff09,0,0,0,0,0,0,0,0,0,0,0,0,
-0xff09,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0xffe6,0,0xffe6,0xffe6,0xffdc,0,0,0xffe6,0xffe6,0,0,0,0,0,0xffe6,0xffe6,
-0,0xffe6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0xff09,0,0,0,0,0,0,0,0,0,0x15c6,0x15c8,0x15ca,0x15cc,
-0x15ce,0x15d0,0x15d2,0x15d4,0x15d4,0x15d6,0x15d8,0x15da,0x15dc,0x15de,0x15e0,0x15e2,0x15e4,0x15e6,0x15e8,0x15ea,
-0x15ec,0x15ee,0x15f0,0x15f2,0x15f4,0x15f6,0x15f8,0x15fa,0x15fc,0x15fe,0x1600,0x1602,0x1604,0x1606,0x1608,0x160a,
-0x160c,0x160e,0x1610,0x1612,0x1614,0x1616,0x1618,0x161a,0x161c,0x161e,0x1620,0x1622,0x1624,0x1626,0x1628,0x162a,
-0x162c,0x162e,0x1630,0x1632,0x1634,0x1636,0x1638,0x163a,0x163c,0x163e,0x1640,0x1642,0x1644,0x1646,0x1648,0x164a,
-0x164c,0x164e,0x1650,0x1652,0x1654,0x1656,0x1658,0x165a,0x165c,0x165e,0x1660,0x1662,0x1664,0x1666,0x1668,0x166a,
-0x166c,0x166e,0x1670,0x1672,0x1674,0x1676,0x1678,0x167a,0x15ec,0x167c,0x167e,0x1680,0x1682,0x1684,0x1686,0x1688,
-0x168a,0x168c,0x168e,0x1690,0x1692,0x1694,0x1696,0x1698,0x169a,0x169c,0x169e,0x16a0,0x16a2,0x16a4,0x16a6,0x16a8,
-0x16aa,0x16ac,0x16ae,0x16b0,0x16b2,0x16b4,0x16b6,0x16b8,0x16ba,0x16bc,0x16be,0x16c0,0x16c2,0x16c4,0x16c6,0x16c8,
-0x16ca,0x16cc,0x16ce,0x16d0,0x16d2,0x16d4,0x16d6,0x16d8,0x16da,0x16dc,0x16de,0x16e0,0x16e2,0x16e4,0x16e6,0x16e8,
-0x16ea,0x16ec,0x16ee,0x16f0,0x16f2,0x16f4,0x16f6,0x16f8,0x16fa,0x16fc,0x16fe,0x1700,0x1702,0x16a0,0x1704,0x1706,
-0x1708,0x170a,0x170c,0x170e,0x1710,0x1712,0x1680,0x1714,0x1716,0x1718,0x171a,0x171c,0x171e,0x1720,0x1722,0x1724,
-0x1726,0x1728,0x172a,0x172c,0x172e,0x1730,0x1732,0x1734,0x1736,0x1738,0x173a,0x15ec,0x173c,0x173e,0x1740,0x1742,
-0x1744,0x1746,0x1748,0x174a,0x174c,0x174e,0x1750,0x1752,0x1754,0x1756,0x1758,0x175a,0x175c,0x175e,0x1760,0x1762,
-0x1764,0x1766,0x1768,0x176a,0x176c,0x176e,0x1770,0x1684,0x1772,0x1774,0x1776,0x1778,0x177a,0x177c,0x177e,0x1780,
-0x1782,0x1784,0x1786,0x1788,0x178a,0x178c,0x178e,0x1790,0x1792,0x1794,0x1796,0x1798,0x179a,0x179c,0x179e,0x17a0,
-0x17a2,0x17a4,0x17a6,0x17a8,0x17aa,0x17ac,0x17ae,0x17b0,0x17b2,0x17b4,0x17b6,0x17b8,0x17ba,0x17bc,0x17be,0x17c0,
-0x17c2,0x17c4,0x17c6,0x17c8,0x17ca,0x17cc,0x17ce,0x17d0,0x17d2,0x17d4,0,0,0x17d6,0,0x17d8,0,
-0,0x17da,0x17dc,0x17de,0x17e0,0x17e2,0x17e4,0x17e6,0x17e8,0x17ea,0x17ec,0,0x17ee,0,0x17f0,0,
-0,0x17f2,0x17f4,0,0,0,0x17f6,0x17f8,0x17fa,0x17fc,0x17fe,0x1800,0x1802,0x1804,0x1806,0x1808,
-0x180a,0x180c,0x180e,0x1810,0x1812,0x1814,0x1816,0x1818,0x181a,0x181c,0x181e,0x1820,0x1822,0x1824,0x1826,0x1828,
-0x182a,0x182c,0x182e,0x1830,0x1832,0x1834,0x1836,0x1838,0x183a,0x183c,0x183e,0x1840,0x1842,0x1844,0x1846,0x1848,
-0x184a,0x184c,0x184e,0x16ee,0x1850,0x1852,0x1854,0x1856,0x1858,0x185a,0x185a,0x185c,0x185e,0x1860,0x1862,0x1864,
-0x1866,0x1868,0x186a,0x17f2,0x186c,0x186e,0x1870,0x1872,0x1874,0x1877,0,0,0x1879,0x187b,0x187d,0x187f,
-0x1881,0x1883,0x1885,0x1887,0x180e,0x1889,0x188b,0x188d,0x17d6,0x188f,0x1891,0x1893,0x1895,0x1897,0x1899,0x189b,
-0x189d,0x189f,0x18a1,0x18a3,0x18a5,0x1820,0x18a7,0x1822,0x18a9,0x18ab,0x18ad,0x18af,0x18b1,0x17d8,0x1616,0x18b3,
-0x18b5,0x18b7,0x16a2,0x1750,0x18b9,0x18bb,0x1830,0x18bd,0x1832,0x18bf,0x18c1,0x18c3,0x17dc,0x18c5,0x18c7,0x18c9,
-0x18cb,0x18cd,0x17de,0x18cf,0x18d1,0x18d3,0x18d5,0x18d7,0x18d9,0x184e,0x18db,0x18dd,0x16ee,0x18df,0x1856,0x18e1,
-0x18e3,0x18e5,0x18e7,0x18e9,0x1860,0x18eb,0x17f0,0x18ed,0x1862,0x167c,0x18ef,0x1864,0x18f1,0x1868,0x18f3,0x18f5,
-0x18f7,0x18f9,0x18fb,0x186c,0x17e8,0x18fd,0x186e,0x18ff,0x1870,0x1901,0x15d4,0x1903,0x1906,0x1909,0x190c,0x190e,
-0x1910,0x1912,0x1915,0x1918,0x191b,0x191d,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0x191f,0xff1a,0x1922,0,0,0,0,0,0,0,0,
-0,0,0x1925,0x1928,0x192c,0x1931,0x1935,0x1938,0x193b,0x193e,0x1941,0x1944,0x1947,0x194a,0x194d,0,
-0x1950,0x1953,0x1956,0x1959,0x195c,0,0x195f,0,0x1962,0x1965,0,0x1968,0x196b,0,0x196e,0x1971,
-0x1974,0x1977,0x197a,0x197d,0x1980,0x1983,0x1986,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffdc,
-0xffdc,0xffdc,0xffdc,0xffdc,0xffdc,0xffdc,0xffe6,0xffe6,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0xffdc,0,0,0xffdc,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0xffdc,0,0xffe6,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0xffe6,0xff01,0xffdc,0,0,0,0,0xff09,
-0,0,0,0,0,0xffe6,0xffdc,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0x54a,0x14ab,0x54d,0x14b0,0,0,0,0,0,0,0,0,0x550,0,0,
-0,0,0,0x14b5,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0xff09,0xfe07,0,0,0,0,0,0xffe6,0xffe6,0xffe6,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0xfe00,0,0,0,0,
-0,0,0x14ba,0x14bf,0,0x553,0x556,0xff09,0xff09,0,0,0,0,0,0,0,
-0,0,0,0,0xff09,0,0,0,0,0,0,0,0,0,0xff07,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0xff09,0xff07,0,0,0,0,0,0,0,0,0,
-0,0xff07,0xff09,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0x559,0,0,0,0x14c4,
-0x14c9,0xff09,0,0,0,0,0,0,0,0,0,0xfe00,0,0,0,0,
-0,0,0,0,0,0,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0,0,0,
-0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0xfe00,0,0,0,0,0,0,0,
-0,0x55f,0xfe00,0x14ce,0x14d3,0xfe00,0x14d8,0,0,0,0xff09,0xff07,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0xfe00,0,0,0,0,
-0,0,0,0,0x568,0x56b,0x14dd,0x14e2,0,0,0,0xff09,0xff07,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xff09,0xff07,
-0,0,0,0,0,0,0,0,0,0,0,0xff09,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0xff01,0xff01,0xff01,0xff01,0xff01,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xff01,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x1989,0x198e,
-0x1998,0x19a4,0x19b0,0x19bc,0x19c8,0xffd8,0xffd8,0xff01,0xff01,0xff01,0,0,0,0xffe2,0xffd8,0xffd8,
-0xffd8,0xffd8,0xffd8,0,0,0,0,0,0,0,0,0xffdc,0xffdc,0xffdc,0xffdc,0xffdc,
-0xffdc,0xffdc,0xffdc,0,0,0xffe6,0xffe6,0xffe6,0xffe6,0xffe6,0xffdc,0xffdc,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0xffe6,0xffe6,0xffe6,0xffe6,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0x19cf,0x19d4,0x19de,0x19ea,0x19f6,0x1a02,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0xffe6,0xffe6,0xffe6,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0xffdc,0xffdc,0xffdc,0xffdc,0xffdc,0xffdc,0xffdc,0,
-0,0,0,0,0,0,0,0,0x1a09,0x1a0b,0x1a0d,0x1a0f,0x1a12,0x1802,0x1a14,0x1a16,
-0x1a18,0x1a1a,0x1804,0x1a1c,0x1a1e,0x1a20,0x1806,0x1a23,0x1a25,0x1a27,0x1a29,0x1a2c,0x1a2e,0x1a30,0x1a32,0x1a35,
-0x1a37,0x1a39,0x1a3b,0x187b,0x1a3d,0x1a40,0x1a42,0x1a44,0x1a46,0x1a48,0x1a4a,0x1a4c,0x1a4e,0x1885,0x1808,0x180a,
-0x1887,0x1a50,0x1a52,0x1688,0x1a54,0x180c,0x1a56,0x1a58,0x1a5a,0x1a5c,0x1a5c,0x1a5c,0x1a5e,0x1a61,0x1a63,0x1a65,
-0x1a67,0x1a6a,0x1a6c,0x1a6e,0x1a70,0x1a72,0x1a74,0x1a76,0x1a78,0x1a7a,0x1a7c,0x1a7e,0x1a80,0x1a82,0x1a82,0x188b,
-0x1a84,0x1a86,0x1a88,0x1a8a,0x1810,0x1a8c,0x1a8e,0x1a90,0x17ba,0x1a92,0x1a94,0x1a96,0x1a98,0x1a9a,0x1a9c,0x1a9e,
-0x1aa0,0x1aa2,0x1aa5,0x1aa7,0x1aa9,0x1aab,0x1aad,0x1aaf,0x1ab1,0x1ab4,0x1ab7,0x1ab9,0x1abb,0x1abd,0x1abf,0x1ac1,
-0x1ac3,0x1ac5,0x1ac7,0x1ac7,0x1ac9,0x1acc,0x1ace,0x1680,0x1ad0,0x1ad2,0x1ad5,0x1ad7,0x1ad9,0x1adb,0x1add,0x1adf,
-0x181a,0x1ae1,0x1ae3,0x1ae5,0x1ae8,0x1aea,0x1aed,0x1aef,0x1af1,0x1af3,0x1af5,0x1af7,0x1af9,0x1afb,0x1afd,0x1aff,
-0x1b01,0x1b03,0x1b06,0x1b08,0x1b0a,0x1b0c,0x1614,0x1b0e,0x1b11,0x1b13,0x1b13,0x1b16,0x1b18,0x1b18,0x1b1a,0x1b1c,
-0x1b1f,0x1b22,0x1b24,0x1b26,0x1b28,0x1b2a,0x1b2c,0x1b2e,0x1b30,0x1b32,0x1b34,0x181c,0x1b36,0x1b39,0x1b3b,0x1b3d,
-0x18a3,0x1b3d,0x1b3f,0x1820,0x1b41,0x1b43,0x1b45,0x1b47,0x1822,0x15de,0x1b49,0x1b4b,0x1b4d,0x1b4f,0x1b51,0x1b53,
-0x1b55,0x1b58,0x1b5a,0x1b5c,0x1b5e,0x1b60,0x1b62,0x1b65,0x1b67,0x1b69,0x1b6b,0x1b6d,0x1b6f,0x1b71,0x1b73,0x1b75,
-0x1824,0x1b77,0x1b79,0x1b7c,0x1b7e,0x1b80,0x1b82,0x1828,0x1b84,0x1b86,0x1b88,0x1b8a,0x1b8c,0x1b8e,0x1b90,0x1b92,
-0x1616,0x18b3,0x1b94,0x1b96,0x1b98,0x1b9a,0x1b9d,0x1b9f,0x1ba1,0x1ba3,0x182a,0x1ba5,0x1ba8,0x1baa,0x1bac,0x190c,
-0x1bae,0x1bb0,0x1bb2,0x1bb4,0x1bb6,0x1bb9,0x1bbb,0x1bbd,0x1bbf,0x1bc2,0x1bc4,0x1bc6,0x1bc8,0x16a2,0x1bca,0x1bcc,
-0x1bcf,0x1bd2,0x1bd5,0x1bd7,0x1bda,0x1bdc,0x1bde,0x1be0,0x1be2,0x182c,0x1750,0x1be4,0x1be6,0x1be8,0x1bea,0x1bed,
-0x1bef,0x1bf1,0x1bf3,0x18bb,0x1bf5,0x1bf7,0x1bfa,0x1bfc,0x1bfe,0x1c01,0x1c04,0x1c06,0x18bd,0x1c08,0x1c0a,0x1c0c,
-0x1c0e,0x1c10,0x1c12,0x1c14,0x1c17,0x1c19,0x1c1c,0x1c1e,0x1c21,0x18c1,0x1c23,0x1c25,0x1c28,0x1c2a,0x1c2c,0x1c2f,
-0x1c32,0x1c34,0x1c36,0x1c38,0x1c3a,0x1c3a,0x1c3c,0x1c3e,0x18c5,0x1c40,0x1c42,0x1c44,0x1c46,0x1c48,0x1c4b,0x1c4d,
-0x1686,0x1c50,0x1c53,0x1c55,0x1c58,0x1c5b,0x1c5e,0x1c60,0x18d1,0x1c62,0x1c65,0x1c68,0x1c6b,0x1c6e,0x1c70,0x1c70,
-0x18d3,0x1910,0x1c72,0x1c74,0x1c76,0x1c78,0x1c7b,0x163a,0x18d7,0x1c7d,0x1c7f,0x1842,0x1c82,0x1c85,0x17e6,0x1c88,
-0x1c8a,0x184a,0x1c8c,0x1c8e,0x1c90,0x1c93,0x1c93,0x1c96,0x1c98,0x1c9a,0x1c9d,0x1c9f,0x1ca1,0x1ca3,0x1ca6,0x1ca8,
-0x1caa,0x1cac,0x1cae,0x1cb0,0x1cb3,0x1cb5,0x1cb7,0x1cb9,0x1cbb,0x1cbd,0x1cbf,0x1cc2,0x1cc5,0x1cc7,0x1cca,0x1ccc,
-0x1ccf,0x1cd1,0x1856,0x1cd3,0x1cd6,0x1cd9,0x1cdb,0x1cde,0x1ce0,0x1ce3,0x1ce5,0x1ce7,0x1ce9,0x1ceb,0x1ced,0x1cef,
-0x1cf2,0x1cf5,0x1cf8,0x1b16,0x1cfb,0x1cfd,0x1cff,0x1d01,0x1d03,0x1d05,0x1d07,0x1d09,0x1d0b,0x1d0d,0x1d0f,0x1d11,
-0x16aa,0x1d14,0x1d16,0x1d18,0x1d1a,0x1d1c,0x1d1e,0x185c,0x1d20,0x1d22,0x1d24,0x1d26,0x1d28,0x1d2b,0x1d2e,0x1d31,
-0x1d33,0x1d35,0x1d37,0x1d39,0x1d3c,0x1d3e,0x1d41,0x1d43,0x1d45,0x1d48,0x1d4b,0x1d4d,0x1630,0x1d4f,0x1d51,0x1d53,
-0x1d55,0x1d57,0x1d59,0x18e5,0x1d5b,0x1d5d,0x1d5f,0x1d61,0x1d63,0x1d65,0x1d67,0x1d69,0x1d6b,0x1d6d,0x1d70,0x1d72,
-0x1d74,0x1d76,0x1d78,0x1d7a,0x1d7d,0x1d80,0x1d82,0x1d84,0x18ef,0x18f1,0x1d86,0x1d88,0x1d8b,0x1d8d,0x1d8f,0x1d91,
-0x1d93,0x1d96,0x1d99,0x1d9b,0x1d9d,0x1d9f,0x1da2,0x18f3,0x1da4,0x1da7,0x1daa,0x1dac,0x1dae,0x1db0,0x1db3,0x1db5,
-0x1db7,0x1db9,0x1dbb,0x1dbd,0x1dbf,0x1dc1,0x1dc4,0x1dc6,0x1dc8,0x1dca,0x1dcd,0x1dcf,0x1dd1,0x1dd3,0x1dd5,0x1dd8,
-0x1ddb,0x1ddd,0x1ddf,0x1de1,0x1de4,0x1de6,0x18ff,0x18ff,0x1de9,0x1deb,0x1dee,0x1df0,0x1df2,0x1df4,0x1df6,0x1df8,
-0x1dfa,0x1dfc,0x1901,0x1dff,0x1e01,0x1e03,0x1e05,0x1e07,0x1e09,0x1e0c,0x1e0e,0x1e11,0x1e14,0x1e17,0x1e19,0x1e1b,
-0x1e1d,0x1e1f,0x1e21,0x1e23,0x1e25,0x1e27,0,0,1,1,1,1,1,1,1,1,
-1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,
-0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0,0,
-0,0,0,0,0,0,0,0,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,
-0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,
-0xff00,0xff00,0xff00,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0x56e,0x56e,0x56e,0x56e,0x56e,0x56e,0x56e,0x56e,0x56e,0x56e,0x56e,0x56e,0x56e,0x56e,0x56e,0x56e,
-0x56e,0x56e,0x56e,0x56e,0x56e,0x56e,0x56e,0x56e,0x56e,0x56e,0x56e,0x56e,0x56e,0x56e,0x56e,0x56e,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0x1e29,0,0x1e29,0,
-0x1e29,0x1e29,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0x1e29,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0x1e29,0,0,0,0,0x1e29,0,0,0,
-0,0,0x1e29,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0x1e27,0,0,0,0,0
+static const uint16_t norm2_nfc_data_trieIndex[1746]={
+0,0x40,0x7b,0xbb,0xfb,0x13a,0x17a,0x1b2,0x1f2,0x226,0x254,0x226,0x294,0x2d4,0x313,0x353,
+0x393,0x3d2,0x40f,0x44e,0x226,0x226,0x488,0x4c8,0x4f8,0x530,0x226,0x570,0x59f,0x5de,0x226,0x5f3,
+0x631,0x65f,0x226,0x68c,0x6cc,0x709,0x729,0x768,0x7a7,0x7e4,0x803,0x840,0x729,0x879,0x8a7,0x8e6,
+0x226,0x920,0x937,0x977,0x98e,0x9cd,0x226,0xa03,0xa23,0xa5e,0xa6a,0xaa5,0xacd,0xb0a,0xb4a,0xb84,
+0xb9f,0x226,0xbda,0x226,0xc1a,0xc39,0xc6f,0xcac,0x226,0x226,0x226,0x226,0x226,0xccf,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0xcfb,0x226,0x226,0xd30,
+0x226,0x226,0xd4e,0x226,0xd78,0x226,0x226,0x226,0xdb4,0xdd4,0xe14,0xe53,0xe8e,0xece,0xf02,0xf2e,
+0x808,0x226,0x226,0xf62,0x226,0x226,0x226,0xfa2,0xfe2,0x1022,0x1062,0x10a2,0x10e2,0x1122,0x1162,0x11a2,
+0x11e2,0x226,0x226,0x1212,0x1243,0x226,0x1273,0x12a6,0x12e3,0x1322,0x1362,0x1398,0x13c6,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x13f1,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0xcbd,0x226,0x140e,0x226,0x144e,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x148e,0x14c8,0x1506,0x1546,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x1585,0x15c3,0x15e3,0x226,0x226,0x226,0x226,
+0x161d,0x226,0x226,0x1645,0x1677,0x16a5,0x80c,0x16b8,0x226,0x226,0x16c8,0x1708,0x226,0x226,0x226,0x1420,
+0x1748,0x1750,0x1758,0x1760,0x174c,0x1754,0x175c,0x1748,0x1750,0x1758,0x1760,0x174c,0x1754,0x175c,0x1748,0x1750,
+0x1758,0x1760,0x174c,0x1754,0x175c,0x1748,0x1750,0x1758,0x1760,0x174c,0x1754,0x175c,0x1748,0x1750,0x1758,0x1760,
+0x174c,0x1754,0x175c,0x1748,0x1750,0x1758,0x1760,0x174c,0x1754,0x175c,0x1748,0x1750,0x1758,0x1760,0x174c,0x1754,
+0x175c,0x1748,0x1750,0x1758,0x1760,0x174c,0x1754,0x175c,0x1748,0x1750,0x1758,0x1760,0x174c,0x1754,0x175c,0x1748,
+0x1750,0x1758,0x1760,0x174c,0x1754,0x175c,0x1748,0x1750,0x1758,0x1760,0x174c,0x1754,0x175c,0x1748,0x1750,0x1758,
+0x1760,0x174c,0x1754,0x175c,0x1748,0x1750,0x1758,0x1760,0x174c,0x1754,0x175c,0x1748,0x1750,0x1758,0x1760,0x174c,
+0x1754,0x175c,0x1748,0x1750,0x1758,0x1760,0x174c,0x1754,0x175c,0x1748,0x1750,0x1758,0x1760,0x174c,0x1754,0x175c,
+0x1748,0x1750,0x1758,0x1760,0x174c,0x1754,0x175c,0x1748,0x1750,0x1758,0x1760,0x174c,0x1754,0x175c,0x1748,0x1750,
+0x1758,0x1760,0x174c,0x1754,0x175c,0x1748,0x1750,0x1758,0x1760,0x174c,0x1754,0x175c,0x1748,0x1750,0x1758,0x1760,
+0x174c,0x1754,0x175c,0x1748,0x1750,0x1758,0x1760,0x174c,0x1754,0x175c,0x1748,0x1750,0x1758,0x1760,0x174c,0x1754,
+0x175c,0x1748,0x1750,0x1758,0x1760,0x174c,0x1754,0x175c,0x1748,0x1750,0x1758,0x1760,0x174c,0x1754,0x1794,0x226,
+0x17d4,0x180f,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x184f,0x188f,0x18cf,0x190f,0x194f,0x198f,0x19cf,0x1a0f,0x1a32,0x1a72,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x1a92,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x655,0x664,0x67c,0x69b,0x6b0,0x6b0,0x6b0,0x6b4,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x226,0x226,0xbda,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x226,0x54f,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x40c,
+0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x1ac5,0x226,0x226,0x1ad5,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x226,0xdc6,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x1ae5,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x15d6,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x1aef,0x54f,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x7eb,0x226,0x226,
+0x9ba,0x226,0x1aff,0x1b0c,0x1b18,0x226,0x226,0x226,0x226,0x414,0x226,0x1b23,0x1b33,0x226,0x226,0x226,
+0x7e0,0x226,0x226,0x226,0x226,0x1b43,0x226,0x226,0x226,0x1b4e,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x1b55,0x226,0x226,0x226,0x226,0x1b60,0x1b6f,0x8f6,0x1b7d,0x412,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x226,0x1b8b,0x798,0x226,0x226,0x226,0x226,0x226,0x1b9b,0x1baa,0x226,
+0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x8d6,0x1bb2,0x1bc2,0x226,
+0x226,0x226,0x9ba,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x1bcc,0x226,0x226,0x226,0x226,0x226,
+0x226,0x7e6,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x1bc9,
+0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x1bdc,
+0x7e0,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x84d,0x226,0x226,0x226,0x7ed,0x7ea,
+0x226,0x226,0x226,0x226,0x7e8,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x9ba,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0xbd4,0x226,0x226,0x226,
+0x226,0x7ea,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x1bec,0x226,0x226,0x226,0xefb,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x1bfc,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x1bfe,
+0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x226,0x1c0d,0x1c1d,0x1c2b,0x1c38,0x226,0x1c44,0x1c52,0x1c62,0x226,0x226,
+0x226,0x226,0xcea,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x1c72,0x1c7a,
+0x1c88,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0xefb,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x4fc,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x226,0x1c98,0x226,0x226,0x226,0x226,0x226,0x226,0x1ca4,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x1cb4,0x1cc4,0x1cd4,0x1ce4,0x1cf4,0x1d04,0x1d14,0x1d24,0x1d34,0x1d44,0x1d54,
+0x1d64,0x1d74,0x1d84,0x1d94,0x1da4,0x1db4,0x1dc4,0x1dd4,0x1de4,0x1df4,0x1e04,0x1e14,0x1e24,0x1e34,0x1e44,0x1e54,
+0x1e64,0x1e74,0x1e84,0x1e94,0x1ea4,0x1eb4,0x1ec4,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,0x226,
+0x226,0x226,0x226,0x226,0x226,0x408,0x428,0xc4,0xc4,0xc4,0x448,0x457,0x46d,0x489,0x4a6,0x4c2,
+0x4df,0x4fc,0x51b,0x538,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,
+0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0x552,0xc4,0x566,0xc4,0xc4,0xc4,0xc4,
+0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,
+0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0x586,0xc4,0xc4,0xc4,0xc4,0xc4,
+0xc4,0xc4,0xc4,0x591,0x5ae,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0x5ce,0x5e2,0xc4,0xc4,0x5f5,
+0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,
+0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,
+0x615,0x635
 };
 
-static const uint16_t norm2_nfc_data_extraData[7722]={
+static const uint16_t norm2_nfc_data_trieData[7892]={
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,4,8,0xc,1,
+1,0x10,0x50,0x5c,0x70,0x88,0xcc,0xd0,0xec,0x108,0x144,0x148,0x15c,0x174,0x180,0x1a4,
+0x1e4,1,0x1ec,0x20c,0x228,0x244,0x290,0x298,0x2b0,0x2b8,0x2dc,1,1,1,1,1,
+1,0x2f4,0x334,0x340,0x354,0x36c,0x3b0,0x3b4,0x3d0,0x3f0,0x428,0x430,0x444,0x45c,0x468,0x48c,
+0x4cc,1,0x4d4,0x4f4,0x510,0x530,0x57c,0x584,0x5a0,0x5a8,0x5d0,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,0x5e8,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,0x128a,0x1290,0xae4,0x1296,0xafa,
+0xb04,0x5f4,0xb0e,0x129c,0x12a2,0xb18,0x12a8,0x12ae,0x12b4,0x12ba,0xb2e,1,0x12c0,0x12c6,0x12cc,0xb38,
+0xb4e,0xb60,1,0x5fc,0x12d2,0x12d8,0x12de,0xb6a,0x12e4,1,1,0x12ea,0x12f0,0xb80,0x12f6,0xb96,
+0xba0,0x600,0xbaa,0x12fc,0x1302,0xbb4,0x1308,0x130e,0x1314,0x131a,0xbca,1,0x1320,0x1326,0x132c,0xbd4,
+0xbea,0xbfc,1,0x608,0x1332,0x1338,0x133e,0xc06,0x1344,1,0x134a,0x1350,0x1356,0xc1c,0xc32,0x135d,
+0x1363,0x1368,0x136e,0x1374,0x137a,0x1380,0x1386,0x138c,0x1392,0x1398,0x139e,1,1,0xc48,0xc56,0x13a4,
+0x13aa,0x13b0,0x13b6,0x13bd,0x13c3,0x13c8,0x13ce,0x13d4,0x13da,0x13e0,0x13e6,0x13ec,0x13f2,0x13f9,0x13ff,0x1404,
+0x140a,1,1,0x1410,0x1416,0x141c,0x1422,0x1428,0x142e,0x1435,0x143b,0x1440,1,1,1,0x1447,
+0x144d,0x1453,0x1459,1,0x145e,0x1464,0x146b,0x1471,0x1476,0x147c,1,1,1,0x1482,0x1488,0x148f,
+0x1495,0x149a,0x14a0,1,1,1,0xc64,0xc72,0x14a6,0x14ac,0x14b2,0x14b8,1,1,0x14be,0x14c4,
+0x14cb,0x14d1,0x14d6,0x14dc,0xc80,0xc8a,0x14e2,0x14e8,0x14ef,0x14f5,0xc94,0xc9e,0x14fb,0x1501,0x1506,0x150c,
+1,1,0xca8,0xcb2,0xcbc,0xcc6,0x1512,0x1518,0x151e,0x1524,0x152a,0x1530,0x1537,0x153d,0x1542,0x1548,
+0x154e,0x1554,0x155a,0x1560,0x1566,0x156c,0x1572,0x1578,0x157e,0x60c,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,0xcd0,0xcea,1,1,1,1,
+1,1,1,1,1,1,1,1,1,0xd04,0xd1e,1,1,1,1,1,
+1,0x610,1,1,1,1,1,1,1,1,1,1,1,1,1,0x1584,
+0x158a,0x1590,0x1596,0x159c,0x15a2,0x15a8,0x15ae,0x15b6,0x15c0,0x15ca,0x15d4,0x15de,0x15e8,0x15f2,0x15fc,1,
+0x1606,0x1610,0x161a,0x1624,0x162d,0x1633,1,1,0x1638,0x163e,0x1644,0x164a,0xd38,0xd42,0x1653,0x165d,
+0x1665,0x166b,0x1671,1,1,1,0x1676,0x167c,1,1,0x1682,0x1688,0x1690,0x169a,0x16a3,0x16a9,
+0x16af,0x16b5,0x16ba,0x16c0,0x16c6,0x16cc,0x16d2,0x16d8,0x16de,0x16e4,0x16ea,0x16f0,0x16f6,0x16fc,0x1702,0x1708,
+0x170e,0x1714,0x171a,0x1720,0x1726,0x172c,0x1732,0x1738,0x173e,0x1744,0x174a,0x1750,0x1756,0x175c,1,1,
+0x1762,0x1768,1,1,1,1,1,1,0xd4c,0xd56,0xd60,0xd6a,0x1770,0x177a,0x1784,0x178e,
+0xd74,0xd7e,0x1798,0x17a2,0x17aa,0x17b0,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,0x614,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,0xfdcc,0xfdcc,0xfdcc,0xfdcc,0xfdcc,0xffcc,0xfdcc,0xfdcc,0xfdcc,0xfdcc,0xfdcc,0xfdcc,
+0xfdcc,0xffcc,0xffcc,0xfdcc,0xffcc,0xfdcc,0xffcc,0xfdcc,0xfdcc,0xffd0,0xffb8,0xffb8,0xffb8,0xffb8,0xffd0,0xfdb0,
+0xffb8,0xffb8,0xffb8,0xffb8,0xffb8,0xff94,0xff94,0xfdb8,0xfdb8,0xfdb8,0xfdb8,0xfd94,0xfd94,0xffb8,0xffb8,0xffb8,
+0xffb8,0xfdb8,0xfdb8,0xffb8,0xfdb8,0xfdb8,0xffb8,0xffb8,0xfe02,0xfe02,0xfe02,0xfe02,0xfc02,0xffb8,0xffb8,0xffb8,
+0xffb8,0xffcc,0xffcc,0xffcc,0x3c36,0x3c3c,0xfdcc,0x3c42,0x3c48,0xfde0,0xffcc,0xffb8,0xffb8,0xffb8,0xffcc,0xffcc,
+0xffcc,0xffb8,0xffb8,1,0xffcc,0xffcc,0xffcc,0xffb8,0xffb8,0xffb8,0xffb8,0xffcc,0xffd0,0xffb8,0xffb8,0xffcc,
+0xffd2,0xffd4,0xffd4,0xffd2,0xffd4,0xffd4,0xffd2,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,
+0xffcc,0xffcc,0xffcc,0xffcc,1,1,1,1,0x29e1,1,1,1,1,1,1,1,
+1,1,0x29e5,1,1,1,1,1,0x17b7,0x17bd,0x29e9,0x17c3,0x17c9,0x17cf,1,0x17d5,
+1,0x17db,0x17e1,0x17e9,0x618,1,1,1,0x634,1,0x644,1,0x658,1,1,1,
+1,1,0x674,1,0x684,1,1,1,0x688,1,1,1,0x6a0,0x17f1,0x17f7,0xd88,
+0x17fd,0xd92,0x1803,0x180b,0x6b4,1,1,1,0x6d4,1,0x6e4,1,0x6fc,1,1,1,
+1,1,0x71c,1,0x72c,1,1,1,0x734,1,1,1,0x754,0xd9c,0xdae,0x1813,
+0x1819,0xdc0,1,1,1,0x76c,0x181f,0x1825,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,0x182b,0x1831,1,0x1837,1,1,0x774,0x183d,1,1,1,1,0x1843,
+0x1849,0x184f,1,0x778,1,1,0x780,1,0x784,0x790,0x798,0x79c,0x1855,0x7ac,1,1,
+1,0x7b0,1,1,1,1,0x7b4,1,1,1,0x7c4,1,1,1,0x7c8,1,
+0x7cc,1,1,0x7d0,1,1,0x7d8,1,0x7dc,0x7e8,0x7f0,0x7f4,0x185b,0x804,1,1,
+1,0x808,1,1,1,0x80c,1,1,1,0x81c,1,1,1,0x820,1,0x824,
+1,1,0x1861,0x1867,1,0x186d,1,1,0x828,0x1873,1,1,1,1,0x1879,0x187f,
+0x1885,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,0x82c,0x830,0x188b,0x1891,1,1,1,1,1,1,
+1,1,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0x1897,
+0x189d,1,1,1,1,1,1,1,1,1,1,1,1,1,0x18a3,0x18a9,
+0x18af,0x18b5,1,1,0x18bb,0x18c1,0x834,0x838,0x18c7,0x18cd,0x18d3,0x18d9,0x18df,0x18e5,1,1,
+0x18eb,0x18f1,0x18f7,0x18fd,0x1903,0x1909,0x83c,0x840,0x190f,0x1915,0x191b,0x1921,0x1927,0x192d,0x1933,0x1939,
+0x193f,0x1945,0x194b,0x1951,1,1,0x1957,0x195d,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,0xffb8,0xffcc,0xffcc,0xffcc,0xffcc,0xffb8,0xffcc,
+0xffcc,0xffcc,0xffbc,0xffb8,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffb8,0xffb8,0xffb8,0xffb8,0xffb8,0xffb8,
+0xffcc,0xffcc,0xffb8,0xffcc,0xffcc,0xffbc,0xffc8,0xffcc,0xfe14,0xfe16,0xfe18,0xfe1a,0xfe1c,0xfe1e,0xfe20,0xfe22,
+0xfe24,0xfe26,0xfe26,0xfe28,0xfe2a,0xfe2c,1,0xfe2e,1,0xfe30,0xfe32,1,0xffcc,0xffb8,1,0xfe24,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,
+0xfe3c,0xfe3e,0xfe40,1,1,1,1,1,1,1,0x1962,0x1968,0x196f,0x1975,0x197b,0x844,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,0x850,1,0x854,0xfe36,0xfe38,0xfe3a,0xfe3c,0xfe3e,
+0xfe40,0xfe42,0xfe44,0xfdcc,0xfdcc,0xfdb8,0xffb8,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffb8,0xffcc,0xffcc,0xffb8,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+0xfe46,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+0x1981,0x858,0x1987,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,0x85c,0x198d,1,0x860,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,1,1,0xffcc,
+0xffcc,0xffcc,0xffcc,0xffb8,0xffcc,1,1,0xffcc,0xffcc,1,0xffb8,0xffcc,0xffcc,0xffb8,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+0xfe48,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0xffcc,
+0xffb8,0xffcc,0xffcc,0xffb8,0xffcc,0xffcc,0xffb8,0xffb8,0xffb8,0xffcc,0xffb8,0xffb8,0xffcc,0xffb8,0xffcc,0xffcc,
+0xffb8,0xffcc,0xffb8,0xffcc,0xffb8,0xffcc,0xffb8,0xffcc,0xffcc,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,0xffcc,0xffcc,
+0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffb8,0xffcc,1,1,1,1,1,1,1,1,1,
+0xffb8,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,0xffcc,0xffcc,0xffcc,0xffcc,1,0xffcc,0xffcc,0xffcc,0xffcc,
+0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,1,0xffcc,0xffcc,0xffcc,1,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,0xffb8,0xffb8,0xffb8,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0xffb8,
+0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,1,0xffb8,
+0xffcc,0xffcc,0xffb8,0xffcc,0xffcc,0xffb8,0xffcc,0xffcc,0xffcc,0xffb8,0xffb8,0xffb8,0xfe36,0xfe38,0xfe3a,0xffcc,
+0xffcc,0xffcc,0xffb8,0xffcc,0xffcc,0xffb8,0xffb8,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,0x864,0x1993,1,1,1,1,1,1,0x868,0x1999,1,0x86c,
+0x199f,1,1,1,1,1,1,1,0xfc0e,1,1,1,1,1,1,1,
+1,1,1,1,1,1,0xfe12,1,1,1,0xffcc,0xffb8,0xffcc,0xffcc,1,1,
+1,0x29ec,0x29f2,0x29f8,0x29fe,0x2a04,0x2a0a,0x2a10,0x2a16,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,0xfe0e,1,0xfc00,1,1,1,1,1,1,1,0x870,
+1,1,1,0x19a5,0x19ab,0xfe12,1,1,1,1,1,1,1,1,1,0xfc00,
+1,1,1,1,0x2a1c,0x2a22,1,0x2a28,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,0xffcc,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,0x2a2e,1,1,0x2a34,1,1,
+1,1,1,0xfe0e,1,1,1,1,1,1,1,1,1,1,1,1,
+1,0xfe12,1,1,1,1,1,1,1,1,1,1,1,0x2a3a,0x2a40,0x2a46,
+1,1,0x2a4c,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0xfe0e,
+1,1,1,1,1,1,1,1,1,1,1,1,1,0xfe12,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+0x878,0x19b1,1,1,0x19b7,0x19bd,0xfe12,1,1,1,1,1,1,1,1,0xfc00,
+0xfc00,1,1,1,1,0x2a52,0x2a58,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,0x884,1,0x19c3,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,0xfc00,1,1,1,1,1,1,0x888,0x890,1,1,
+0x19c9,0x19cf,0x19d5,0xfe12,1,1,1,1,1,1,1,1,1,0xfc00,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,0x894,1,0x19db,1,1,1,1,0xfe12,1,1,
+1,1,1,1,1,0xfea8,0xfcb6,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,0xfe0e,1,1,0x898,0x19e1,1,0xfc00,1,1,1,0x89c,0x19e7,0x19ed,
+1,0xdca,0x19f5,1,0xfe12,1,1,1,1,1,1,1,0xfc00,0xfc00,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,0xfe12,0xfe12,1,0xfc00,1,1,1,
+1,1,1,0x8a8,0x8b0,1,1,0x19fd,0x1a03,0x1a09,0xfe12,1,1,1,1,1,
+1,1,1,1,0xfc00,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,0xfc12,1,1,
+1,1,0xfc00,1,1,1,1,1,1,1,1,1,0x8b4,0x1a0f,1,0xdd4,
+0x1a17,0x1a1f,0xfc00,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,0xfece,0xfece,0xfe12,1,1,
+1,1,1,1,1,1,0xfed6,0xfed6,0xfed6,0xfed6,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,0xfeec,0xfeec,0xfe12,1,1,1,1,1,1,1,1,0xfef4,0xfef4,0xfef4,
+0xfef4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,0xffb8,0xffb8,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,0xffb8,1,0xffb8,1,0xffb0,1,1,1,1,1,1,0x2a5f,1,1,
+1,1,1,1,1,1,1,0x2a65,1,1,1,1,0x2a6b,1,1,1,
+1,0x2a71,1,1,1,1,0x2a77,1,1,1,1,1,1,1,1,1,
+1,1,1,0x2a7d,1,1,1,1,1,1,1,0xff02,0xff04,0x3c50,0xff08,0x3c58,
+0x2a82,1,0x2a88,1,0xff04,0xff04,0xff04,0xff04,1,1,0xff04,0x3c60,0xffcc,0xffcc,0xfe12,1,
+0xffcc,0xffcc,1,1,1,1,1,1,1,1,1,1,1,0x2a8f,1,1,
+1,1,1,1,1,1,1,0x2a95,1,1,1,1,0x2a9b,1,1,1,
+1,0x2aa1,1,1,1,1,0x2aa7,1,1,1,1,1,1,1,1,1,
+1,1,1,0x2aad,1,1,1,1,1,1,0xffb8,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,0x8c0,0x1a25,1,1,1,1,1,1,1,0xfc00,1,1,
+1,1,1,1,1,1,0xfe0e,1,0xfe12,0xfe12,1,1,1,1,1,1,
+1,1,1,1,1,1,1,0xffb8,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,
+0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,
+0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,0xffcc,0xffcc,0xffcc,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0xfe12,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0xfe12,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,0xfe12,1,1,1,1,1,1,1,1,1,1,0xffcc,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,0xffc8,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,0xffbc,0xffcc,0xffb8,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,0xffcc,0xffb8,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,0xfe12,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,
+0xffcc,1,1,0xffb8,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffb8,0xffb8,0xffb8,0xffb8,0xffb8,0xffb8,0xffcc,
+0xffcc,0xffb8,1,0xffb8,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,0x8c4,0x1a2b,0x8c8,0x1a31,0x8cc,0x1a37,0x8d0,0x1a3d,0x8d4,0x1a43,1,1,0x8d8,
+0x1a49,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,0xfe0e,0xfc00,1,1,1,1,0x8dc,0x1a4f,0x8e0,0x1a55,0x8e4,0x8e8,0x1a5b,0x1a61,
+0x8ec,0x1a67,0xfe12,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,0xffcc,0xffb8,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,
+0xffcc,0xffcc,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,0xfe12,0xfe12,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,0xfe0e,1,1,1,1,1,1,1,1,1,1,1,
+0xfe12,0xfe12,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,0xffcc,0xffcc,0xffcc,1,0xfe02,0xffb8,0xffb8,0xffb8,0xffb8,0xffb8,0xffcc,0xffcc,0xffb8,0xffb8,
+0xffb8,0xffb8,0xffcc,1,0xfe02,0xfe02,0xfe02,0xfe02,0xfe02,0xfe02,0xfe02,1,1,1,1,0xffb8,
+1,1,1,1,1,1,0xffcc,1,1,1,0xffcc,0xffcc,1,1,1,1,
+1,1,0xffcc,0xffcc,0xffb8,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffb8,0xffcc,0xffcc,0xffd4,
+0xffac,0xffb8,0xff94,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,
+0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,
+0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffd0,0xffc8,0xffc8,0xffb8,1,0xffcc,0xffd2,0xffb8,
+0xffcc,0xffb8,0x1a6c,0x1a72,0x1a78,0x1a7e,0x1a85,0x1a8b,0x1a91,0x1a97,0x1a9f,0x1aa9,0x1ab0,0x1ab6,0x1abc,0x1ac2,
+0x1ac8,0x1ace,0x1ad5,0x1adb,0x1ae0,0x1ae6,0x1aee,0x1af8,0x1b02,0x1b0c,0x1b14,0x1b1a,0x1b20,0x1b26,0x1b2f,0x1b39,
+0x1b41,0x1b47,0x1b4c,0x1b52,0x1b58,0x1b5e,0x1b64,0x1b6a,0x1b70,0x1b76,0x1b7d,0x1b83,0x1b88,0x1b8e,0x1b94,0x1b9a,
+0x1ba2,0x1bac,0x1bb4,0x1bba,0x1bc0,0x1bc6,0x1bcc,0x1bd2,0xdde,0xde8,0x1bda,0x1be4,0x1bec,0x1bf2,0x1bf8,0x1bfe,
+0x1c04,0x1c0a,0x1c10,0x1c16,0x1c1d,0x1c23,0x1c28,0x1c2e,0x1c34,0x1c3a,0x1c40,0x1c46,0x1c4c,0x1c52,0x1c5a,0x1c64,
+0x1c6e,0x1c78,0x1c82,0x1c8c,0x1c96,0x1ca0,0x1ca9,0x1caf,0x1cb5,0x1cbb,0x1cc0,0x1cc6,0xdf2,0xdfc,0x1cce,0x1cd8,
+0x1ce0,0x1ce6,0x1cec,0x1cf2,0xe06,0xe10,0x1cfa,0x1d04,0x1d0e,0x1d18,0x1d22,0x1d2c,0x1d34,0x1d3a,0x1d40,0x1d46,
+0x1d4c,0x1d52,0x1d58,0x1d5e,0x1d64,0x1d6a,0x1d70,0x1d76,0x1d7c,0x1d82,0x1d8a,0x1d94,0x1d9e,0x1da8,0x1db0,0x1db6,
+0x1dbd,0x1dc3,0x1dc8,0x1dce,0x1dd4,0x1dda,0x1de0,0x1de6,0x1dec,0x1df2,0x1df9,0x1dff,0x1e05,0x1e0b,0x1e11,0x1e17,
+0x1e1c,0x1e22,0x1e28,0x1e2e,0x1e35,0x1e3b,0x1e41,0x1e47,0x1e4c,0x1e52,0x1e58,0x1e5e,1,0x1e65,1,1,
+1,1,0xe1a,0xe28,0x1e6a,0x1e70,0x1e78,0x1e82,0x1e8c,0x1e96,0x1ea0,0x1eaa,0x1eb4,0x1ebe,0x1ec8,0x1ed2,
+0x1edc,0x1ee6,0x1ef0,0x1efa,0x1f04,0x1f0e,0x1f18,0x1f22,0x1f2c,0x1f36,0xe36,0xe40,0x1f3e,0x1f44,0x1f4a,0x1f50,
+0x1f58,0x1f62,0x1f6c,0x1f76,0x1f80,0x1f8a,0x1f94,0x1f9e,0x1fa8,0x1fb2,0x1fba,0x1fc0,0x1fc6,0x1fcc,0xe4a,0xe54,
+0x1fd2,0x1fd8,0x1fe0,0x1fea,0x1ff4,0x1ffe,0x2008,0x2012,0x201c,0x2026,0x2030,0x203a,0x2044,0x204e,0x2058,0x2062,
+0x206c,0x2076,0x2080,0x208a,0x2094,0x209e,0x20a6,0x20ac,0x20b2,0x20b8,0x20c0,0x20ca,0x20d4,0x20de,0x20e8,0x20f2,
+0x20fc,0x2106,0x2110,0x211a,0x2122,0x2128,0x212f,0x2135,0x213a,0x2140,0x2146,0x214c,1,1,1,1,
+1,1,0xe5e,0xe74,0xe8c,0xe9a,0xea8,0xeb6,0xec4,0xed2,0xede,0xef4,0xf0c,0xf1a,0xf28,0xf36,
+0xf44,0xf52,0xf5e,0xf6c,0x2155,0x215f,0x2169,0x2173,1,1,0xf7a,0xf88,0x217d,0x2187,0x2191,0x219b,
+1,1,0xf96,0xfac,0xfc4,0xfd2,0xfe0,0xfee,0xffc,0x100a,0x1016,0x102c,0x1044,0x1052,0x1060,0x106e,
+0x107c,0x108a,0x1096,0x10a8,0x21a5,0x21af,0x21b9,0x21c3,0x21cd,0x21d7,0x10ba,0x10cc,0x21e1,0x21eb,0x21f5,0x21ff,
+0x2209,0x2213,0x10de,0x10ec,0x221d,0x2227,0x2231,0x223b,1,1,0x10fa,0x1108,0x2245,0x224f,0x2259,0x2263,
+1,1,0x1116,0x1128,0x226d,0x2277,0x2281,0x228b,0x2295,0x229f,1,0x113a,1,0x22a9,1,0x22b3,
+1,0x22bd,0x114c,0x1162,0x117a,0x1188,0x1196,0x11a4,0x11b2,0x11c0,0x11cc,0x11e2,0x11fa,0x1208,0x1216,0x1224,
+0x1232,0x1240,0x124c,0x3b9e,0x22c5,0x3ba6,0x1256,0x3bae,0x22cb,0x3bb6,0x22d1,0x3bbe,0x22d7,0x3bc6,0x1260,0x3bce,
+1,1,0x22de,0x22e8,0x22f7,0x2307,0x2317,0x2327,0x2337,0x2347,0x2352,0x235c,0x236b,0x237b,0x238b,0x239b,
+0x23ab,0x23bb,0x23c6,0x23d0,0x23df,0x23ef,0x23ff,0x240f,0x241f,0x242f,0x243a,0x2444,0x2453,0x2463,0x2473,0x2483,
+0x2493,0x24a3,0x24ae,0x24b8,0x24c7,0x24d7,0x24e7,0x24f7,0x2507,0x2517,0x2522,0x252c,0x253b,0x254b,0x255b,0x256b,
+0x257b,0x258b,0x2595,0x259b,0x25a3,0x25aa,0x25b3,1,0x126a,0x25bd,0x25c5,0x25cb,0x25d1,0x3bd6,0x25d6,1,
+0x2ab2,0x8f0,1,0x25dd,0x25e5,0x25ec,0x25f5,1,0x1274,0x25ff,0x2607,0x3bde,0x260d,0x3be6,0x2612,0x2619,
+0x261f,0x2625,0x262b,0x2631,0x2639,0x3bf0,1,1,0x2641,0x2649,0x2651,0x2657,0x265d,0x3bfa,1,0x2663,
+0x2669,0x266f,0x2675,0x267b,0x2683,0x3c04,0x268b,0x2691,0x2697,0x269f,0x26a7,0x26ad,0x26b3,0x3c0e,0x26b9,0x26bf,
+0x3c16,0x2ab7,1,1,0x26c7,0x26ce,0x26d7,1,0x127e,0x26e1,0x26e9,0x3c1e,0x26ef,0x3c26,0x26f4,0x2abb,
+0x8fc,1,0xfa09,0xfa09,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,0xffcc,0xffcc,0xfe02,0xfe02,0xffcc,0xffcc,0xffcc,0xffcc,0xfe02,0xfe02,0xfe02,0xffcc,0xffcc,1,
+1,1,1,0xffcc,1,1,1,0xfe02,0xfe02,0xffcc,0xffb8,0xffcc,0xfe02,0xfe02,0xffb8,0xffb8,
+0xffb8,0xffb8,0xffcc,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,0x2abe,1,1,1,0x2ac2,0x3c2e,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,0x908,1,0x90c,1,0x910,1,1,1,1,1,0x26fb,0x2701,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,0x2707,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,0x270d,0x2713,0x2719,0x914,1,0x918,1,0x91c,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,0x920,0x271f,1,1,1,0x924,0x2725,1,0x928,0x272b,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,0x92c,0x2731,0x930,0x2737,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0x934,
+1,1,1,0x273d,1,0x938,0x2743,0x93c,1,0x2749,0x940,0x274f,1,1,1,0x944,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,0x2755,0x948,0x275b,1,0x94c,0x950,1,1,1,1,1,1,1,0x2761,
+0x2767,0x276d,0x2773,0x2779,0x954,0x958,0x277f,0x2785,0x95c,0x960,0x278b,0x2791,0x964,0x968,0x96c,0x970,
+1,1,0x2797,0x279d,0x974,0x978,0x27a3,0x27a9,0x97c,0x980,0x27af,0x27b5,1,1,1,1,
+1,1,1,0x984,0x988,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,0x98c,1,1,1,1,1,0x990,0x994,1,0x998,0x27bb,0x27c1,
+0x27c7,0x27cd,1,1,0x99c,0x9a0,0x9a4,0x9a8,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,0x27d3,0x27d9,0x27df,0x27e5,1,1,1,1,
+1,1,0x27eb,0x27f1,0x27f7,0x27fd,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0x2ac7,
+0x2acb,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,0x2acf,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,0xfe12,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,0xffcc,0xffcc,
+0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,
+0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,0xffb4,0xffc8,0xffd0,0xffbc,0xffc0,0xffc0,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,0x9ac,1,
+1,1,1,0x9b0,0x2803,0x9b4,0x2809,0x9b8,0x280f,0x9bc,0x2815,0x9c0,0x281b,0x9c4,0x2821,0x9c8,
+0x2827,0x9cc,0x282d,0x9d0,0x2833,0x9d4,0x2839,0x9d8,0x283f,0x9dc,0x2845,1,0x9e0,0x284b,0x9e4,0x2851,
+0x9e8,0x2857,1,1,1,1,1,0x9ec,0x285d,0x2863,0x9f4,0x2869,0x286f,0x9fc,0x2875,0x287b,
+0xa04,0x2881,0x2887,0xa0c,0x288d,0x2893,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,0x2899,1,1,1,1,0xfc10,
+0xfc10,1,1,0xa14,0x289f,1,1,1,1,1,1,1,0xa18,1,1,1,
+1,0xa1c,0x28a5,0xa20,0x28ab,0xa24,0x28b1,0xa28,0x28b7,0xa2c,0x28bd,0xa30,0x28c3,0xa34,0x28c9,0xa38,
+0x28cf,0xa3c,0x28d5,0xa40,0x28db,0xa44,0x28e1,0xa48,0x28e7,1,0xa4c,0x28ed,0xa50,0x28f3,0xa54,0x28f9,
+1,1,1,1,1,0xa58,0x28ff,0x2905,0xa60,0x290b,0x2911,0xa68,0x2917,0x291d,0xa70,0x2923,
+0x2929,0xa78,0x292f,0x2935,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,0xa80,0xa84,0xa88,0xa8c,1,0x293b,1,1,0x2941,0x2947,0x294d,
+0x2953,1,1,0xa90,0x2959,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,0xffcc,1,1,1,1,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,
+0xffcc,0xffcc,0xffcc,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,0xffcc,0xffcc,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,0xffcc,0xffcc,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,0xfe12,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,0xfe12,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,
+0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,0xffb8,0xffb8,0xffb8,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,0xfe12,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,0xffcc,1,0xffcc,0xffcc,0xffb8,1,1,0xffcc,
+0xffcc,1,1,1,1,1,0xffcc,0xffcc,1,0xffcc,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,0xfe12,1,
+1,1,1,1,1,1,1,1,0xae2,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,
+0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,
+0x1289,0x1289,0x1289,0x1289,0xae2,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,
+0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,
+0xae2,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,
+0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,0xae2,0x1289,0x1289,0x1289,
+0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,
+0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,0x1289,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,0x3c66,1,0x3c66,0x3c66,0x3c66,0x3c66,0x3c66,0x3c66,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,0x3c66,0x3c66,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,0x3c66,1,1,1,1,0x3c66,1,1,1,0x3c66,1,0x3c66,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,0x3b97,1,0x2ad5,
+0x2ad9,0x2add,0x2ae1,0x2ae5,0x2ae9,0x2aed,0x2af1,0x2af1,0x2af5,0x2af9,0x2afd,0x2b01,0x2b05,0x2b09,0x2b0d,0x2b11,
+0x2b15,0x2b19,0x2b1d,0x2b21,0x2b25,0x2b29,0x2b2d,0x2b31,0x2b35,0x2b39,0x2b3d,0x2b41,0x2b45,0x2b49,0x2b4d,0x2b51,
+0x2b55,0x2b59,0x2b5d,0x2b61,0x2b65,0x2b69,0x2b6d,0x2b71,0x2b75,0x2b79,0x2b7d,0x2b81,0x2b85,0x2b89,0x2b8d,0x2b91,
+0x2b95,0x2b99,0x2b9d,0x2ba1,0x2ba5,0x2ba9,0x2bad,0x2bb1,0x2bb5,0x2bb9,0x2bbd,0x2bc1,0x2bc5,0x2bc9,0x2bcd,0x2bd1,
+0x2bd5,0x2bd9,0x2bdd,0x2be1,0x2be5,0x2be9,0x2bed,0x2bf1,0x2bf5,0x2bf9,0x2bfd,0x2c01,0x2c05,0x2c09,0x2c0d,0x2c11,
+0x2c15,0x2c19,0x2c1d,0x2c21,0x2c25,0x2c29,0x2c2d,0x2c31,0x2c35,0x2c39,0x2c3d,0x2b21,0x2c41,0x2c45,0x2c49,0x2c4d,
+0x2c51,0x2c55,0x2c59,0x2c5d,0x2c61,0x2c65,0x2c69,0x2c6d,0x2c71,0x2c75,0x2c79,0x2c7d,0x2c81,0x2c85,0x2c89,0x2c8d,
+0x2c91,0x2c95,0x2c99,0x2c9d,0x2ca1,0x2ca5,0x2ca9,0x2cad,0x2cb1,0x2cb5,0x2cb9,0x2cbd,0x2cc1,0x2cc5,0x2cc9,0x2ccd,
+0x2cd1,0x2cd5,0x2cd9,0x2cdd,0x2ce1,0x2ce5,0x2ce9,0x2ced,0x2cf1,0x2cf5,0x2cf9,0x2cfd,0x2d01,0x2d05,0x2d09,0x2d0d,
+0x2d11,0x2d15,0x2d19,0x2d1d,0x2d21,0x2d25,0x2d29,0x2d2d,0x2d31,0x2d35,0x2d39,0x2d3d,0x2d41,0x2d45,0x2d49,0x2d4d,
+0x2c89,0x2d51,0x2d55,0x2d59,0x2d5d,0x2d61,0x2d65,0x2d69,0x2d6d,0x2c49,0x2d71,0x2d75,0x2d79,0x2d7d,0x2d81,0x2d85,
+0x2d89,0x2d8d,0x2d91,0x2d95,0x2d99,0x2d9d,0x2da1,0x2da5,0x2da9,0x2dad,0x2db1,0x2db5,0x2db9,0x2dbd,0x2b21,0x2dc1,
+0x2dc5,0x2dc9,0x2dcd,0x2dd1,0x2dd5,0x2dd9,0x2ddd,0x2de1,0x2de5,0x2de9,0x2ded,0x2df1,0x2df5,0x2df9,0x2dfd,0x2e01,
+0x2e05,0x2e09,0x2e0d,0x2e11,0x2e15,0x2e19,0x2e1d,0x2e21,0x2e25,0x2e29,0x2c51,0x2e2d,0x2e31,0x2e35,0x2e39,0x2e3d,
+0x2e41,0x2e45,0x2e49,0x2e4d,0x2e51,0x2e55,0x2e59,0x2e5d,0x2e61,0x2e65,0x2e69,0x2e6d,0x2e71,0x2e75,0x2e79,0x2e7d,
+0x2e81,0x2e85,0x2e89,0x2e8d,0x2e91,0x2e95,0x2e99,0x2e9d,0x2ea1,0x2ea5,0x2ea9,0x2ead,0x2eb1,0x2eb5,0x2eb9,0x2ebd,
+0x2ec1,0x2ec5,0x2ec9,0x2ecd,0x2ed1,0x2ed5,0x2ed9,0x2edd,0x2ee1,0x2ee5,0x2ee9,0x2eed,0x2ef1,1,1,0x2ef5,
+1,0x2ef9,1,1,0x2efd,0x2f01,0x2f05,0x2f09,0x2f0d,0x2f11,0x2f15,0x2f19,0x2f1d,0x2f21,1,0x2f25,
+1,0x2f29,1,1,0x2f2d,0x2f31,1,1,1,0x2f35,0x2f39,0x2f3d,0x2f41,0x2f45,0x2f49,0x2f4d,
+0x2f51,0x2f55,0x2f59,0x2f5d,0x2f61,0x2f65,0x2f69,0x2f6d,0x2f71,0x2f75,0x2f79,0x2f7d,0x2f81,0x2f85,0x2f89,0x2f8d,
+0x2f91,0x2f95,0x2f99,0x2f9d,0x2fa1,0x2fa5,0x2fa9,0x2fad,0x2fb1,0x2fb5,0x2fb9,0x2fbd,0x2fc1,0x2fc5,0x2fc9,0x2fcd,
+0x2fd1,0x2fd5,0x2fd9,0x2fdd,0x2fe1,0x2fe5,0x2d25,0x2fe9,0x2fed,0x2ff1,0x2ff5,0x2ff9,0x2ffd,0x2ffd,0x3001,0x3005,
+0x3009,0x300d,0x3011,0x3015,0x3019,0x301d,0x2f2d,0x3021,0x3025,0x3029,0x302d,0x3031,0x3037,1,1,0x303b,
+0x303f,0x3043,0x3047,0x304b,0x304f,0x3053,0x3057,0x2f65,0x305b,0x305f,0x3063,0x2ef5,0x3067,0x306b,0x306f,0x3073,
+0x3077,0x307b,0x307f,0x3083,0x3087,0x308b,0x308f,0x3093,0x2f89,0x3097,0x2f8d,0x309b,0x309f,0x30a3,0x30a7,0x30ab,
+0x2ef9,0x2b75,0x30af,0x30b3,0x30b7,0x2c8d,0x2de9,0x30bb,0x30bf,0x2fa9,0x30c3,0x2fad,0x30c7,0x30cb,0x30cf,0x2f01,
+0x30d3,0x30d7,0x30db,0x30df,0x30e3,0x2f05,0x30e7,0x30eb,0x30ef,0x30f3,0x30f7,0x30fb,0x2fe5,0x30ff,0x3103,0x2d25,
+0x3107,0x2ff5,0x310b,0x310f,0x3113,0x3117,0x311b,0x3009,0x311f,0x2f29,0x3123,0x300d,0x2c41,0x3127,0x3011,0x312b,
+0x3019,0x312f,0x3133,0x3137,0x313b,0x313f,0x3021,0x2f19,0x3143,0x3025,0x3147,0x3029,0x314b,0x2af1,0x314f,0x3155,
+0x315b,0x3161,0x3165,0x3169,0x316d,0x3173,0x3179,0x317f,0x3183,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0x3186,
+0xfe34,0x318c,1,1,1,1,1,1,1,1,1,1,0x3192,0x3198,0x31a0,0x31aa,
+0x31b2,0x31b8,0x31be,0x31c4,0x31ca,0x31d0,0x31d6,0x31dc,0x31e2,1,0x31e8,0x31ee,0x31f4,0x31fa,0x3200,1,
+0x3206,1,0x320c,0x3212,1,0x3218,0x321e,1,0x3224,0x322a,0x3230,0x3236,0x323c,0x3242,0x3248,0x324e,
+0x3254,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffb8,0xffb8,0xffb8,0xffb8,0xffb8,0xffb8,0xffb8,
+0xffcc,0xffcc,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,0xffb8,1,0xffcc,1,1,1,1,1,1,1,1,0xffcc,0xfe02,0xffb8,
+1,1,1,1,0xfe12,1,1,1,1,0xffcc,0xffcc,0xffcc,0xffcc,1,1,1,
+1,1,1,1,1,0xffb8,0xffb8,0xffcc,0xffcc,0xffcc,0xffb8,0xffcc,0xffb8,0xffb8,0xffb8,1,
+1,1,1,1,1,1,1,1,0xa94,0x295f,0xa9a,0x2969,1,1,1,1,
+1,0xaa0,1,1,1,1,1,0x2973,1,1,1,1,1,1,1,1,
+1,0xfe12,0xfc0e,1,1,1,1,1,1,1,0xfc00,1,1,1,1,1,
+1,0x297d,0x2987,1,0xaa6,0xaac,0xfe12,0xfe12,1,1,1,1,1,1,1,1,
+1,1,1,0xfe12,1,1,1,1,1,1,1,1,1,0xfe0e,1,1,
+1,1,1,0xfe12,0xfe0e,1,1,1,1,1,1,1,1,1,0xfe0e,0xfe12,
+1,1,1,1,1,1,1,1,1,1,1,0xfe0e,0xfe0e,1,0xfc00,1,
+1,1,1,1,1,1,0xab2,1,1,1,0x2991,0x299b,0xfe12,1,1,1,
+1,1,1,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,1,1,1,0xfe12,1,1,
+1,0xfe0e,1,1,1,1,1,1,1,1,1,0xfc00,1,1,1,1,
+1,1,1,1,0xabe,0xfc00,0x29a5,0x29af,0xfc00,0x29b9,1,1,0xfe12,0xfe0e,1,1,
+1,1,1,1,1,1,1,1,1,1,0xad0,0xad6,0x29c3,0x29cd,1,1,
+1,0xfe12,0xfe0e,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,0xfe12,0xfe0e,1,1,1,1,1,1,1,1,0xfc00,1,1,1,
+1,0xadc,1,1,0x29d7,1,1,1,1,0xfe12,0xfe12,1,0xfe02,0xfe02,0xfe02,0xfe02,
+0xfe02,1,1,1,1,1,1,1,1,1,1,1,0xfe0c,0xfe0c,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,0xfe02,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,0x325a,0x3264,0x3278,0x3290,0x32a8,
+0x32c0,0x32d8,0xffb0,0xffb0,0xfe02,0xfe02,0xfe02,1,1,1,0xffc4,0xffb0,0xffb0,0xffb0,1,1,
+1,1,1,1,1,1,0xffb8,0xffb8,0xffb8,0xffb8,0xffb8,1,1,0xffcc,0xffcc,0xffcc,
+0xffcc,0xffcc,0xffb8,0xffb8,1,1,1,1,1,1,1,1,1,1,0xffcc,0xffcc,
+0xffcc,0xffcc,1,1,1,1,1,1,1,1,1,1,1,0x32e6,0x32f0,0x3304,
+0x331c,0x3334,0x334c,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,1,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,
+0xffcc,0xffcc,0xffcc,1,1,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,1,0xffcc,0xffcc,1,0xffcc,0xffcc,
+0xffcc,0xffcc,0xffcc,1,1,1,1,1,0xffb8,0xffb8,0xffb8,0xffb8,0xffb8,0xffb8,0xffb8,1,
+1,1,1,1,1,1,1,1,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xffcc,0xfe0e,1,
+1,1,1,1,0x335b,0x335f,0x3363,0x3367,0x336d,0x2f4d,0x3371,0x3375,0x3379,0x337d,0x2f51,0x3381,
+0x3385,0x3389,0x2f55,0x338f,0x3393,0x3397,0x339b,0x33a1,0x33a5,0x33a9,0x33ad,0x33b3,0x33b7,0x33bb,0x33bf,0x303f,
+0x33c3,0x33c9,0x33cd,0x33d1,0x33d5,0x33d9,0x33dd,0x33e1,0x33e5,0x3053,0x2f59,0x2f5d,0x3057,0x33e9,0x33ed,0x2c59,
+0x33f1,0x2f61,0x33f5,0x33f9,0x33fd,0x3401,0x3401,0x3401,0x3405,0x340b,0x340f,0x3413,0x3417,0x341d,0x3421,0x3425,
+0x3429,0x342d,0x3431,0x3435,0x3439,0x343d,0x3441,0x3445,0x3449,0x344d,0x344d,0x305f,0x3451,0x3455,0x3459,0x345d,
+0x2f69,0x3461,0x3465,0x3469,0x2ebd,0x346d,0x3471,0x3475,0x3479,0x347d,0x3481,0x3485,0x3489,0x348d,0x3493,0x3497,
+0x349b,0x349f,0x34a3,0x34a7,0x34ab,0x34b1,0x34b7,0x34bb,0x34bf,0x34c3,0x34c7,0x34cb,0x34cf,0x34d3,0x34d7,0x34d7,
+0x34db,0x34e1,0x34e5,0x2c49,0x34e9,0x34ed,0x34f3,0x34f7,0x34fb,0x34ff,0x3503,0x3507,0x2f7d,0x350b,0x350f,0x3513,
+0x3519,0x351d,0x3523,0x3527,0x352b,0x352f,0x3533,0x3537,0x353b,0x353f,0x3543,0x3547,0x354b,0x354f,0x3555,0x3559,
+0x355d,0x3561,0x2b71,0x3565,0x356b,0x356f,0x356f,0x3575,0x3579,0x3579,0x357d,0x3581,0x3587,0x358d,0x3591,0x3595,
+0x3599,0x359d,0x35a1,0x35a5,0x35a9,0x35ad,0x35b1,0x2f81,0x35b5,0x35bb,0x35bf,0x35c3,0x308f,0x35c3,0x35c7,0x2f89,
+0x35cb,0x35cf,0x35d3,0x35d7,0x2f8d,0x2b05,0x35db,0x35df,0x35e3,0x35e7,0x35eb,0x35ef,0x35f3,0x35f9,0x35fd,0x3601,
+0x3605,0x3609,0x360d,0x3613,0x3617,0x361b,0x361f,0x3623,0x3627,0x362b,0x362f,0x3633,0x2f91,0x3637,0x363b,0x3641,
+0x3645,0x3649,0x364d,0x2f99,0x3651,0x3655,0x3659,0x365d,0x3661,0x3665,0x3669,0x366d,0x2b75,0x30af,0x3671,0x3675,
+0x3679,0x367d,0x3683,0x3687,0x368b,0x368f,0x2f9d,0x3693,0x3699,0x369d,0x36a1,0x3161,0x36a5,0x36a9,0x36ad,0x36b1,
+0x36b5,0x36bb,0x36bf,0x36c3,0x36c7,0x36cd,0x36d1,0x36d5,0x36d9,0x2c8d,0x36dd,0x36e1,0x36e7,0x36ed,0x36f3,0x36f7,
+0x36fd,0x3701,0x3705,0x3709,0x370d,0x2fa1,0x2de9,0x3711,0x3715,0x3719,0x371d,0x3723,0x3727,0x372b,0x372f,0x30bf,
+0x3733,0x3737,0x373d,0x3741,0x3745,0x374b,0x3751,0x3755,0x30c3,0x3759,0x375d,0x3761,0x3765,0x3769,0x376d,0x3771,
+0x3777,0x377b,0x3781,0x3785,0x378b,0x30cb,0x378f,0x3793,0x3799,0x379d,0x37a1,0x37a7,0x37ad,0x37b1,0x37b5,0x37b9,
+0x37bd,0x37bd,0x37c1,0x37c5,0x30d3,0x37c9,0x37cd,0x37d1,0x37d5,0x37d9,0x37df,0x37e3,0x2c55,0x37e9,0x37ef,0x37f3,
+0x37f9,0x37ff,0x3805,0x3809,0x30eb,0x380d,0x3813,0x3819,0x381f,0x3825,0x3829,0x3829,0x30ef,0x3169,0x382d,0x3831,
+0x3835,0x3839,0x383f,0x2bbd,0x30f7,0x3843,0x3847,0x2fcd,0x384d,0x3853,0x2f15,0x3859,0x385d,0x2fdd,0x3861,0x3865,
+0x3869,0x386f,0x386f,0x3875,0x3879,0x387d,0x3883,0x3887,0x388b,0x388f,0x3895,0x3899,0x389d,0x38a1,0x38a5,0x38a9,
+0x38af,0x38b3,0x38b7,0x38bb,0x38bf,0x38c3,0x38c7,0x38cd,0x38d3,0x38d7,0x38dd,0x38e1,0x38e7,0x38eb,0x2ff5,0x38ef,
+0x38f5,0x38fb,0x38ff,0x3905,0x3909,0x390f,0x3913,0x3917,0x391b,0x391f,0x3923,0x3927,0x392d,0x3933,0x3939,0x3575,
+0x393f,0x3943,0x3947,0x394b,0x394f,0x3953,0x3957,0x395b,0x395f,0x3963,0x3967,0x396b,0x2c9d,0x3971,0x3975,0x3979,
+0x397d,0x3981,0x3985,0x3001,0x3989,0x398d,0x3991,0x3995,0x3999,0x399f,0x39a5,0x39ab,0x39af,0x39b3,0x39b7,0x39bb,
+0x39c1,0x39c5,0x39cb,0x39cf,0x39d3,0x39d9,0x39df,0x39e3,0x2ba9,0x39e7,0x39eb,0x39ef,0x39f3,0x39f7,0x39fb,0x3113,
+0x39ff,0x3a03,0x3a07,0x3a0b,0x3a0f,0x3a13,0x3a17,0x3a1b,0x3a1f,0x3a23,0x3a29,0x3a2d,0x3a31,0x3a35,0x3a39,0x3a3d,
+0x3a43,0x3a49,0x3a4d,0x3a51,0x3127,0x312b,0x3a55,0x3a59,0x3a5f,0x3a63,0x3a67,0x3a6b,0x3a6f,0x3a75,0x3a7b,0x3a7f,
+0x3a83,0x3a87,0x3a8d,0x312f,0x3a91,0x3a97,0x3a9d,0x3aa1,0x3aa5,0x3aa9,0x3aaf,0x3ab3,0x3ab7,0x3abb,0x3abf,0x3ac3,
+0x3ac7,0x3acb,0x3ad1,0x3ad5,0x3ad9,0x3add,0x3ae3,0x3ae7,0x3aeb,0x3aef,0x3af3,0x3af9,0x3aff,0x3b03,0x3b07,0x3b0b,
+0x3b11,0x3b15,0x3147,0x3147,0x3b1b,0x3b1f,0x3b25,0x3b29,0x3b2d,0x3b31,0x3b35,0x3b39,0x3b3d,0x3b41,0x314b,0x3b47,
+0x3b4b,0x3b4f,0x3b53,0x3b57,0x3b5b,0x3b61,0x3b65,0x3b6b,0x3b71,0x3b77,0x3b7b,0x3b7f,0x3b83,0x3b87,0x3b8b,0x3b8f,
+0x3b93,0x3b97,1,1
+};
+
+static const UCPTrie norm2_nfc_data_trie={
+    norm2_nfc_data_trieIndex,
+    { norm2_nfc_data_trieData },
+    1746, 7892,
+    0x2fc00, 0x30,
+    0, 0,
+    0, 0,
+    0xc4, 0x226,
+    0x1,
+};
+
+static const uint16_t norm2_nfc_data_extraData[7732]={
 0xffff,0xffff,0x8670,0x44dc,0x8670,0x44c0,0x8670,0x44de,0x600,0x180,0x602,0x182,0x604,0x185,0x606,0x186,
 0x608,0x200,0x60c,0x205,0x60e,0x44d,0x610,0x189,0x612,0x3d44,0x614,0x18b,0x618,0x39a,0x61e,0x400,
 0x622,0x404,0x646,0x3d41,0x64a,0x3c00,0x8650,0x208,0x60e,0x3c04,0x646,0x3c08,0x8662,0x3c0c,0x602,0x20c,
@@ -692,408 +727,409 @@
 0x6132,0x61a6,0xe134,0x61a8,0x6132,0x61ac,0xe134,0x61ae,0x6132,0x61b2,0xe134,0x61b4,0x6132,0x61b8,0xe134,0x61ba,
 0xe132,0x61ee,0xe132,0x61f0,0xe132,0x61f2,0xe132,0x61f4,0xe132,0x61fc,0xb489,0x2e82,0x2134,0xb489,0x2e82,0x2138,
 0xb489,0x2e82,0x2156,0xb489,0x49c2,0x225c,0xb489,0x49c2,0x225e,0x3489,0xcf82,0x2696,0xb489,0xd5c2,0x2698,0x348b,
-0x2c02,0x2978,0x348b,0x2e82,0x2976,0xb48b,0x2f42,0x297c,0xb48b,0x6bc2,0x2b74,0xb48b,0x6bc2,0x2b76,0,0xe622,
-0x41,0x302,0x600,0x3d4c,0x602,0x3d48,0x606,0x3d54,0x8612,0x3d50,0xe622,0x41,0x308,0x8608,0x3bc,0xe622,
-0x41,0x30a,0x8602,0x3f4,0xca22,0x43,0x327,0x8602,0x3c10,0xe622,0x45,0x302,0x600,0x3d80,0x602,0x3d7c,
-0x606,0x3d88,0x8612,0x3d84,0xe622,0x49,0x308,0x8602,0x3c5c,0xe622,0x4f,0x302,0x600,0x3da4,0x602,0x3da0,
-0x606,0x3dac,0x8612,0x3da8,0xe622,0x4f,0x303,0x602,0x3c98,0x608,0x458,0x8610,0x3c9c,0xe622,0x4f,0x308,
-0x8608,0x454,0xe622,0x55,0x308,0x600,0x3b6,0x602,0x3ae,0x608,0x3aa,0x8618,0x3b2,0xe622,0x61,0x302,
-0x600,0x3d4e,0x602,0x3d4a,0x606,0x3d56,0x8612,0x3d52,0xe622,0x61,0x308,0x8608,0x3be,0xe622,0x61,0x30a,
-0x8602,0x3f6,0xca22,0x63,0x327,0x8602,0x3c12,0xe622,0x65,0x302,0x600,0x3d82,0x602,0x3d7e,0x606,0x3d8a,
-0x8612,0x3d86,0xe622,0x69,0x308,0x8602,0x3c5e,0xe622,0x6f,0x302,0x600,0x3da6,0x602,0x3da2,0x606,0x3dae,
-0x8612,0x3daa,0xe622,0x6f,0x303,0x602,0x3c9a,0x608,0x45a,0x8610,0x3c9e,0xe622,0x6f,0x308,0x8608,0x456,
-0xe622,0x75,0x308,0x600,0x3b8,0x602,0x3b0,0x608,0x3ac,0x8618,0x3b4,0xe622,0x41,0x306,0x600,0x3d60,
-0x602,0x3d5c,0x606,0x3d68,0x8612,0x3d64,0xe622,0x61,0x306,0x600,0x3d62,0x602,0x3d5e,0x606,0x3d6a,0x8612,
-0x3d66,0xe622,0x45,0x304,0x600,0x3c28,0x8602,0x3c2c,0xe622,0x65,0x304,0x600,0x3c2a,0x8602,0x3c2e,0xe622,
-0x4f,0x304,0x600,0x3ca0,0x8602,0x3ca4,0xe622,0x6f,0x304,0x600,0x3ca2,0x8602,0x3ca6,0xe622,0x53,0x301,
-0x860e,0x3cc8,0xe622,0x73,0x301,0x860e,0x3cca,0xe622,0x53,0x30c,0x860e,0x3ccc,0xe622,0x73,0x30c,0x860e,
-0x3cce,0xe622,0x55,0x303,0x8602,0x3cf0,0xe622,0x75,0x303,0x8602,0x3cf2,0xe622,0x55,0x304,0x8610,0x3cf4,
-0xe622,0x75,0x304,0x8610,0x3cf6,0xd822,0x4f,0x31b,0x600,0x3db8,0x602,0x3db4,0x606,0x3dc0,0x612,0x3dbc,
-0x8646,0x3dc4,0xd822,0x6f,0x31b,0x600,0x3dba,0x602,0x3db6,0x606,0x3dc2,0x612,0x3dbe,0x8646,0x3dc6,0xd822,
-0x55,0x31b,0x600,0x3dd4,0x602,0x3dd0,0x606,0x3ddc,0x612,0x3dd8,0x8646,0x3de0,0xd822,0x75,0x31b,0x600,
-0x3dd6,0x602,0x3dd2,0x606,0x3dde,0x612,0x3dda,0x8646,0x3de2,0xca22,0x4f,0x328,0x8608,0x3d8,0xca22,0x6f,
-0x328,0x8608,0x3da,0xe622,0x41,0x307,0x8608,0x3c0,0xe622,0x61,0x307,0x8608,0x3c2,0xca22,0x45,0x327,
-0x860c,0x3c38,0xca22,0x65,0x327,0x860c,0x3c3a,0xe622,0x4f,0x307,0x8608,0x460,0xe622,0x6f,0x307,0x8608,
-0x462,0xe622,0x3b1,0x301,0x868a,0x3f68,0xe622,0x3b7,0x301,0x868a,0x3f88,0xe622,0x3b9,0x308,0x600,0x3fa4,
-0x602,0x720,0x8684,0x3fae,0xe622,0x3c5,0x308,0x600,0x3fc4,0x602,0x760,0x8684,0x3fce,0xe622,0x3c9,0x301,
-0x868a,0x3fe8,0x22,0xcc6,0xcc2,0x99aa,0x1996,0x22,0xdd9,0xdcf,0x9b94,0x1bba,0xdc22,0x4c,0x323,0x8608,
-0x3c70,0xdc22,0x6c,0x323,0x8608,0x3c72,0xdc22,0x52,0x323,0x8608,0x3cb8,0xdc22,0x72,0x323,0x8608,0x3cba,
-0xdc22,0x53,0x323,0x860e,0x3cd0,0xdc22,0x73,0x323,0x860e,0x3cd2,0xdc22,0x41,0x323,0x604,0x3d58,0x860c,
-0x3d6c,0xdc22,0x61,0x323,0x604,0x3d5a,0x860c,0x3d6e,0xdc22,0x45,0x323,0x8604,0x3d8c,0xdc22,0x65,0x323,
-0x8604,0x3d8e,0xdc22,0x4f,0x323,0x8604,0x3db0,0xdc22,0x6f,0x323,0x8604,0x3db2,0xe622,0x3b1,0x313,0x600,
-0x3e05,0x602,0x3e09,0x684,0x3e0d,0x868a,0x3f00,0xe622,0x3b1,0x314,0x600,0x3e07,0x602,0x3e0b,0x684,0x3e0f,
-0x868a,0x3f02,0x1f00,0xe663,0x3b1,0x313,0x300,0x868a,0x3f04,0x1f01,0xe663,0x3b1,0x314,0x300,0x868a,0x3f06,
-0x1f00,0xe663,0x3b1,0x313,0x301,0x868a,0x3f08,0x1f01,0xe663,0x3b1,0x314,0x301,0x868a,0x3f0a,0x1f00,0xe663,
-0x3b1,0x313,0x342,0x868a,0x3f0c,0x1f01,0xe663,0x3b1,0x314,0x342,0x868a,0x3f0e,0xe622,0x391,0x313,0x600,
-0x3e15,0x602,0x3e19,0x684,0x3e1d,0x868a,0x3f10,0xe622,0x391,0x314,0x600,0x3e17,0x602,0x3e1b,0x684,0x3e1f,
-0x868a,0x3f12,0x1f08,0xe663,0x391,0x313,0x300,0x868a,0x3f14,0x1f09,0xe663,0x391,0x314,0x300,0x868a,0x3f16,
-0x1f08,0xe663,0x391,0x313,0x301,0x868a,0x3f18,0x1f09,0xe663,0x391,0x314,0x301,0x868a,0x3f1a,0x1f08,0xe663,
-0x391,0x313,0x342,0x868a,0x3f1c,0x1f09,0xe663,0x391,0x314,0x342,0x868a,0x3f1e,0xe622,0x3b5,0x313,0x600,
-0x3e24,0x8602,0x3e28,0xe622,0x3b5,0x314,0x600,0x3e26,0x8602,0x3e2a,0xe622,0x395,0x313,0x600,0x3e34,0x8602,
-0x3e38,0xe622,0x395,0x314,0x600,0x3e36,0x8602,0x3e3a,0xe622,0x3b7,0x313,0x600,0x3e45,0x602,0x3e49,0x684,
-0x3e4d,0x868a,0x3f20,0xe622,0x3b7,0x314,0x600,0x3e47,0x602,0x3e4b,0x684,0x3e4f,0x868a,0x3f22,0x1f20,0xe663,
-0x3b7,0x313,0x300,0x868a,0x3f24,0x1f21,0xe663,0x3b7,0x314,0x300,0x868a,0x3f26,0x1f20,0xe663,0x3b7,0x313,
-0x301,0x868a,0x3f28,0x1f21,0xe663,0x3b7,0x314,0x301,0x868a,0x3f2a,0x1f20,0xe663,0x3b7,0x313,0x342,0x868a,
-0x3f2c,0x1f21,0xe663,0x3b7,0x314,0x342,0x868a,0x3f2e,0xe622,0x397,0x313,0x600,0x3e55,0x602,0x3e59,0x684,
-0x3e5d,0x868a,0x3f30,0xe622,0x397,0x314,0x600,0x3e57,0x602,0x3e5b,0x684,0x3e5f,0x868a,0x3f32,0x1f28,0xe663,
-0x397,0x313,0x300,0x868a,0x3f34,0x1f29,0xe663,0x397,0x314,0x300,0x868a,0x3f36,0x1f28,0xe663,0x397,0x313,
-0x301,0x868a,0x3f38,0x1f29,0xe663,0x397,0x314,0x301,0x868a,0x3f3a,0x1f28,0xe663,0x397,0x313,0x342,0x868a,
-0x3f3c,0x1f29,0xe663,0x397,0x314,0x342,0x868a,0x3f3e,0xe622,0x3b9,0x313,0x600,0x3e64,0x602,0x3e68,0x8684,
-0x3e6c,0xe622,0x3b9,0x314,0x600,0x3e66,0x602,0x3e6a,0x8684,0x3e6e,0xe622,0x399,0x313,0x600,0x3e74,0x602,
-0x3e78,0x8684,0x3e7c,0xe622,0x399,0x314,0x600,0x3e76,0x602,0x3e7a,0x8684,0x3e7e,0xe622,0x3bf,0x313,0x600,
-0x3e84,0x8602,0x3e88,0xe622,0x3bf,0x314,0x600,0x3e86,0x8602,0x3e8a,0xe622,0x39f,0x313,0x600,0x3e94,0x8602,
-0x3e98,0xe622,0x39f,0x314,0x600,0x3e96,0x8602,0x3e9a,0xe622,0x3c5,0x313,0x600,0x3ea4,0x602,0x3ea8,0x8684,
-0x3eac,0xe622,0x3c5,0x314,0x600,0x3ea6,0x602,0x3eaa,0x8684,0x3eae,0xe622,0x3a5,0x314,0x600,0x3eb6,0x602,
-0x3eba,0x8684,0x3ebe,0xe622,0x3c9,0x313,0x600,0x3ec5,0x602,0x3ec9,0x684,0x3ecd,0x868a,0x3f40,0xe622,0x3c9,
-0x314,0x600,0x3ec7,0x602,0x3ecb,0x684,0x3ecf,0x868a,0x3f42,0x1f60,0xe663,0x3c9,0x313,0x300,0x868a,0x3f44,
-0x1f61,0xe663,0x3c9,0x314,0x300,0x868a,0x3f46,0x1f60,0xe663,0x3c9,0x313,0x301,0x868a,0x3f48,0x1f61,0xe663,
-0x3c9,0x314,0x301,0x868a,0x3f4a,0x1f60,0xe663,0x3c9,0x313,0x342,0x868a,0x3f4c,0x1f61,0xe663,0x3c9,0x314,
-0x342,0x868a,0x3f4e,0xe622,0x3a9,0x313,0x600,0x3ed5,0x602,0x3ed9,0x684,0x3edd,0x868a,0x3f50,0xe622,0x3a9,
-0x314,0x600,0x3ed7,0x602,0x3edb,0x684,0x3edf,0x868a,0x3f52,0x1f68,0xe663,0x3a9,0x313,0x300,0x868a,0x3f54,
-0x1f69,0xe663,0x3a9,0x314,0x300,0x868a,0x3f56,0x1f68,0xe663,0x3a9,0x313,0x301,0x868a,0x3f58,0x1f69,0xe663,
-0x3a9,0x314,0x301,0x868a,0x3f5a,0x1f68,0xe663,0x3a9,0x313,0x342,0x868a,0x3f5c,0x1f69,0xe663,0x3a9,0x314,
-0x342,0x868a,0x3f5e,0xe622,0x3b1,0x300,0x868a,0x3f64,0xe622,0x3b7,0x300,0x868a,0x3f84,0xe622,0x3c9,0x300,
-0x868a,0x3fe4,0xe622,0x3b1,0x342,0x868a,0x3f6e,0xe622,0x3b7,0x342,0x868a,0x3f8e,0xe622,0x3c9,0x342,0x868a,
-0x3fee,0xe622,0x41,0x300,0xe622,0x41,0x301,0xe622,0x41,0x303,0xe622,0x45,0x300,0xe622,0x45,0x301,
-0xe622,0x45,0x308,0xe622,0x49,0x300,0xe622,0x49,0x301,0xe622,0x49,0x302,0xe622,0x4e,0x303,0xe622,
-0x4f,0x300,0xe622,0x4f,0x301,0xe622,0x55,0x300,0xe622,0x55,0x301,0xe622,0x55,0x302,0xe622,0x59,
-0x301,0xe622,0x61,0x300,0xe622,0x61,0x301,0xe622,0x61,0x303,0xe622,0x65,0x300,0xe622,0x65,0x301,
-0xe622,0x65,0x308,0xe622,0x69,0x300,0xe622,0x69,0x301,0xe622,0x69,0x302,0xe622,0x6e,0x303,0xe622,
-0x6f,0x300,0xe622,0x6f,0x301,0xe622,0x75,0x300,0xe622,0x75,0x301,0xe622,0x75,0x302,0xe622,0x79,
-0x301,0xe622,0x79,0x308,0xe622,0x41,0x304,0xe622,0x61,0x304,0xca02,0x41,0x328,0xca02,0x61,0x328,
-0xe622,0x43,0x301,0xe622,0x63,0x301,0xe622,0x43,0x302,0xe622,0x63,0x302,0xe622,0x43,0x307,0xe622,
-0x63,0x307,0xe622,0x43,0x30c,0xe622,0x63,0x30c,0xe622,0x44,0x30c,0xe622,0x64,0x30c,0xe622,0x45,
-0x306,0xe622,0x65,0x306,0xe622,0x45,0x307,0xe622,0x65,0x307,0xca02,0x45,0x328,0xca02,0x65,0x328,
-0xe622,0x45,0x30c,0xe622,0x65,0x30c,0xe622,0x47,0x302,0xe622,0x67,0x302,0xe622,0x47,0x306,0xe622,
-0x67,0x306,0xe622,0x47,0x307,0xe622,0x67,0x307,0xca02,0x47,0x327,0xca02,0x67,0x327,0xe622,0x48,
-0x302,0xe622,0x68,0x302,0xe622,0x49,0x303,0xe622,0x69,0x303,0xe622,0x49,0x304,0xe622,0x69,0x304,
-0xe622,0x49,0x306,0xe622,0x69,0x306,0xca02,0x49,0x328,0xca02,0x69,0x328,0xe622,0x49,0x307,0xe602,
-0x4a,0x302,0xe602,0x6a,0x302,0xca02,0x4b,0x327,0xca02,0x6b,0x327,0xe622,0x4c,0x301,0xe622,0x6c,
-0x301,0xca02,0x4c,0x327,0xca02,0x6c,0x327,0xe622,0x4c,0x30c,0xe622,0x6c,0x30c,0xe622,0x4e,0x301,
-0xe622,0x6e,0x301,0xca02,0x4e,0x327,0xca02,0x6e,0x327,0xe622,0x4e,0x30c,0xe622,0x6e,0x30c,0xe622,
-0x4f,0x306,0xe622,0x6f,0x306,0xe622,0x4f,0x30b,0xe622,0x6f,0x30b,0xe622,0x52,0x301,0xe622,0x72,
-0x301,0xca02,0x52,0x327,0xca02,0x72,0x327,0xe622,0x52,0x30c,0xe622,0x72,0x30c,0xe622,0x53,0x302,
-0xe622,0x73,0x302,0xca02,0x53,0x327,0xca02,0x73,0x327,0xca02,0x54,0x327,0xca02,0x74,0x327,0xe622,
-0x54,0x30c,0xe622,0x74,0x30c,0xe622,0x55,0x306,0xe622,0x75,0x306,0xe622,0x55,0x30a,0xe622,0x75,
-0x30a,0xe622,0x55,0x30b,0xe622,0x75,0x30b,0xca02,0x55,0x328,0xca02,0x75,0x328,0xe622,0x57,0x302,
-0xe622,0x77,0x302,0xe622,0x59,0x302,0xe622,0x79,0x302,0xe622,0x59,0x308,0xe622,0x5a,0x301,0xe622,
-0x7a,0x301,0xe622,0x5a,0x307,0xe622,0x7a,0x307,0xe622,0x5a,0x30c,0xe622,0x7a,0x30c,0xe622,0x41,
-0x30c,0xe622,0x61,0x30c,0xe622,0x49,0x30c,0xe622,0x69,0x30c,0xe622,0x4f,0x30c,0xe622,0x6f,0x30c,
-0xe622,0x55,0x30c,0xe622,0x75,0x30c,0xdc,0xe663,0x55,0x308,0x304,0xfc,0xe663,0x75,0x308,0x304,
-0xdc,0xe663,0x55,0x308,0x301,0xfc,0xe663,0x75,0x308,0x301,0xdc,0xe663,0x55,0x308,0x30c,0xfc,
-0xe663,0x75,0x308,0x30c,0xdc,0xe663,0x55,0x308,0x300,0xfc,0xe663,0x75,0x308,0x300,0xc4,0xe663,
-0x41,0x308,0x304,0xe4,0xe663,0x61,0x308,0x304,0x226,0xe663,0x41,0x307,0x304,0x227,0xe663,0x61,
-0x307,0x304,0xe602,0xc6,0x304,0xe602,0xe6,0x304,0xe622,0x47,0x30c,0xe622,0x67,0x30c,0xe622,0x4b,
-0x30c,0xe622,0x6b,0x30c,0x1ea,0xe643,0x4f,0x328,0x304,0x1eb,0xe643,0x6f,0x328,0x304,0xe602,0x1b7,
-0x30c,0xe602,0x292,0x30c,0xe602,0x6a,0x30c,0xe622,0x47,0x301,0xe622,0x67,0x301,0xe622,0x4e,0x300,
-0xe622,0x6e,0x300,0xc5,0xe663,0x41,0x30a,0x301,0xe5,0xe663,0x61,0x30a,0x301,0xe602,0xc6,0x301,
-0xe602,0xe6,0x301,0xe602,0xd8,0x301,0xe602,0xf8,0x301,0xe622,0x41,0x30f,0xe622,0x61,0x30f,0xe622,
-0x41,0x311,0xe622,0x61,0x311,0xe622,0x45,0x30f,0xe622,0x65,0x30f,0xe622,0x45,0x311,0xe622,0x65,
-0x311,0xe622,0x49,0x30f,0xe622,0x69,0x30f,0xe622,0x49,0x311,0xe622,0x69,0x311,0xe622,0x4f,0x30f,
-0xe622,0x6f,0x30f,0xe622,0x4f,0x311,0xe622,0x6f,0x311,0xe622,0x52,0x30f,0xe622,0x72,0x30f,0xe622,
-0x52,0x311,0xe622,0x72,0x311,0xe622,0x55,0x30f,0xe622,0x75,0x30f,0xe622,0x55,0x311,0xe622,0x75,
-0x311,0xdc22,0x53,0x326,0xdc22,0x73,0x326,0xdc22,0x54,0x326,0xdc22,0x74,0x326,0xe622,0x48,0x30c,
-0xe622,0x68,0x30c,0xd6,0xe663,0x4f,0x308,0x304,0xf6,0xe663,0x6f,0x308,0x304,0xd5,0xe663,0x4f,
-0x303,0x304,0xf5,0xe663,0x6f,0x303,0x304,0x22e,0xe663,0x4f,0x307,0x304,0x22f,0xe663,0x6f,0x307,
-0x304,0xe622,0x59,0x304,0xe622,0x79,0x304,0xe602,0xa8,0x301,0xe602,0x391,0x301,0xe602,0x395,0x301,
-0xe602,0x397,0x301,0xe602,0x399,0x301,0xe602,0x39f,0x301,0xe602,0x3a5,0x301,0xe602,0x3a9,0x301,0x3ca,
-0xe643,0x3b9,0x308,0x301,0xe602,0x399,0x308,0xe602,0x3a5,0x308,0xe602,0x3b5,0x301,0xe602,0x3b9,0x301,
-0x3cb,0xe643,0x3c5,0x308,0x301,0xe602,0x3bf,0x301,0xe602,0x3c5,0x301,0xe602,0x3d2,0x301,0xe602,0x3d2,
-0x308,0xe602,0x415,0x300,0xe602,0x415,0x308,0xe602,0x413,0x301,0xe602,0x406,0x308,0xe602,0x41a,0x301,
-0xe602,0x418,0x300,0xe602,0x423,0x306,0xe602,0x418,0x306,0xe602,0x438,0x306,0xe602,0x435,0x300,0xe602,
-0x435,0x308,0xe602,0x433,0x301,0xe602,0x456,0x308,0xe602,0x43a,0x301,0xe602,0x438,0x300,0xe602,0x443,
-0x306,0xe602,0x474,0x30f,0xe602,0x475,0x30f,0xe602,0x416,0x306,0xe602,0x436,0x306,0xe602,0x410,0x306,
-0xe602,0x430,0x306,0xe602,0x410,0x308,0xe602,0x430,0x308,0xe602,0x415,0x306,0xe602,0x435,0x306,0xe602,
-0x4d8,0x308,0xe602,0x4d9,0x308,0xe602,0x416,0x308,0xe602,0x436,0x308,0xe602,0x417,0x308,0xe602,0x437,
-0x308,0xe602,0x418,0x304,0xe602,0x438,0x304,0xe602,0x418,0x308,0xe602,0x438,0x308,0xe602,0x41e,0x308,
-0xe602,0x43e,0x308,0xe602,0x4e8,0x308,0xe602,0x4e9,0x308,0xe602,0x42d,0x308,0xe602,0x44d,0x308,0xe602,
-0x423,0x304,0xe602,0x443,0x304,0xe602,0x423,0x308,0xe602,0x443,0x308,0xe602,0x423,0x30b,0xe602,0x443,
-0x30b,0xe602,0x427,0x308,0xe602,0x447,0x308,0xe602,0x42b,0x308,0xe602,0x44b,0x308,0xe622,0x627,0x653,
-0xe622,0x627,0x654,0xe602,0x648,0x654,0xdc02,0x627,0x655,0xe602,0x64a,0x654,0xe602,0x6d5,0x654,0xe602,
-0x6c1,0x654,0xe602,0x6d2,0x654,0x702,0x928,0x93c,0x702,0x930,0x93c,0x702,0x933,0x93c,2,0x9c7,
-0x9be,2,0x9c7,0x9d7,2,0xb47,0xb56,2,0xb47,0xb3e,2,0xb47,0xb57,2,0xb92,0xbd7,
-2,0xbc6,0xbbe,2,0xbc7,0xbbe,2,0xbc6,0xbd7,0x5b02,0xc46,0xc56,2,0xcbf,0xcd5,2,
-0xcc6,0xcd5,2,0xcc6,0xcd6,0xcca,0x43,0xcc6,0xcc2,0xcd5,2,0xd46,0xd3e,2,0xd47,0xd3e,
-2,0xd46,0xd57,0x902,0xdd9,0xdca,0xddc,0x943,0xdd9,0xdcf,0xdca,2,0xdd9,0xddf,2,0x1025,
-0x102e,2,0x1b05,0x1b35,2,0x1b07,0x1b35,2,0x1b09,0x1b35,2,0x1b0b,0x1b35,2,0x1b0d,0x1b35,
-2,0x1b11,0x1b35,2,0x1b3a,0x1b35,2,0x1b3c,0x1b35,2,0x1b3e,0x1b35,2,0x1b3f,0x1b35,2,
-0x1b42,0x1b35,0xdc22,0x41,0x325,0xdc22,0x61,0x325,0xe622,0x42,0x307,0xe622,0x62,0x307,0xdc02,0x42,
-0x323,0xdc02,0x62,0x323,0xdc02,0x42,0x331,0xdc02,0x62,0x331,0xc7,0xe643,0x43,0x327,0x301,0xe7,
-0xe643,0x63,0x327,0x301,0xe622,0x44,0x307,0xe622,0x64,0x307,0xdc22,0x44,0x323,0xdc22,0x64,0x323,
-0xdc22,0x44,0x331,0xdc22,0x64,0x331,0xca02,0x44,0x327,0xca02,0x64,0x327,0xdc22,0x44,0x32d,0xdc22,
-0x64,0x32d,0x112,0xe663,0x45,0x304,0x300,0x113,0xe663,0x65,0x304,0x300,0x112,0xe663,0x45,0x304,
-0x301,0x113,0xe663,0x65,0x304,0x301,0xdc22,0x45,0x32d,0xdc22,0x65,0x32d,0xdc22,0x45,0x330,0xdc22,
-0x65,0x330,0x228,0xe643,0x45,0x327,0x306,0x229,0xe643,0x65,0x327,0x306,0xe602,0x46,0x307,0xe602,
-0x66,0x307,0xe622,0x47,0x304,0xe622,0x67,0x304,0xe622,0x48,0x307,0xe622,0x68,0x307,0xdc22,0x48,
-0x323,0xdc22,0x68,0x323,0xe622,0x48,0x308,0xe622,0x68,0x308,0xca02,0x48,0x327,0xca02,0x68,0x327,
-0xdc22,0x48,0x32e,0xdc22,0x68,0x32e,0xdc22,0x49,0x330,0xdc22,0x69,0x330,0xcf,0xe663,0x49,0x308,
-0x301,0xef,0xe663,0x69,0x308,0x301,0xe622,0x4b,0x301,0xe622,0x6b,0x301,0xdc22,0x4b,0x323,0xdc22,
-0x6b,0x323,0xdc22,0x4b,0x331,0xdc22,0x6b,0x331,0x1e36,0xe663,0x4c,0x323,0x304,0x1e37,0xe663,0x6c,
-0x323,0x304,0xdc22,0x4c,0x331,0xdc22,0x6c,0x331,0xdc22,0x4c,0x32d,0xdc22,0x6c,0x32d,0xe622,0x4d,
-0x301,0xe622,0x6d,0x301,0xe622,0x4d,0x307,0xe622,0x6d,0x307,0xdc02,0x4d,0x323,0xdc02,0x6d,0x323,
-0xe622,0x4e,0x307,0xe622,0x6e,0x307,0xdc22,0x4e,0x323,0xdc22,0x6e,0x323,0xdc22,0x4e,0x331,0xdc22,
-0x6e,0x331,0xdc22,0x4e,0x32d,0xdc22,0x6e,0x32d,0xd5,0xe663,0x4f,0x303,0x301,0xf5,0xe663,0x6f,
-0x303,0x301,0xd5,0xe663,0x4f,0x303,0x308,0xf5,0xe663,0x6f,0x303,0x308,0x14c,0xe663,0x4f,0x304,
-0x300,0x14d,0xe663,0x6f,0x304,0x300,0x14c,0xe663,0x4f,0x304,0x301,0x14d,0xe663,0x6f,0x304,0x301,
-0xe602,0x50,0x301,0xe602,0x70,0x301,0xe602,0x50,0x307,0xe602,0x70,0x307,0xe622,0x52,0x307,0xe622,
-0x72,0x307,0x1e5a,0xe663,0x52,0x323,0x304,0x1e5b,0xe663,0x72,0x323,0x304,0xdc22,0x52,0x331,0xdc22,
-0x72,0x331,0xe622,0x53,0x307,0xe622,0x73,0x307,0x15a,0xe663,0x53,0x301,0x307,0x15b,0xe663,0x73,
-0x301,0x307,0x160,0xe663,0x53,0x30c,0x307,0x161,0xe663,0x73,0x30c,0x307,0x1e62,0xe663,0x53,0x323,
-0x307,0x1e63,0xe663,0x73,0x323,0x307,0xe622,0x54,0x307,0xe622,0x74,0x307,0xdc22,0x54,0x323,0xdc22,
-0x74,0x323,0xdc22,0x54,0x331,0xdc22,0x74,0x331,0xdc22,0x54,0x32d,0xdc22,0x74,0x32d,0xdc22,0x55,
-0x324,0xdc22,0x75,0x324,0xdc22,0x55,0x330,0xdc22,0x75,0x330,0xdc22,0x55,0x32d,0xdc22,0x75,0x32d,
-0x168,0xe663,0x55,0x303,0x301,0x169,0xe663,0x75,0x303,0x301,0x16a,0xe663,0x55,0x304,0x308,0x16b,
-0xe663,0x75,0x304,0x308,0xe622,0x56,0x303,0xe622,0x76,0x303,0xdc02,0x56,0x323,0xdc02,0x76,0x323,
-0xe622,0x57,0x300,0xe622,0x77,0x300,0xe622,0x57,0x301,0xe622,0x77,0x301,0xe622,0x57,0x308,0xe622,
-0x77,0x308,0xe622,0x57,0x307,0xe622,0x77,0x307,0xdc02,0x57,0x323,0xdc02,0x77,0x323,0xe602,0x58,
-0x307,0xe602,0x78,0x307,0xe602,0x58,0x308,0xe602,0x78,0x308,0xe622,0x59,0x307,0xe622,0x79,0x307,
-0xe622,0x5a,0x302,0xe622,0x7a,0x302,0xdc02,0x5a,0x323,0xdc02,0x7a,0x323,0xdc02,0x5a,0x331,0xdc02,
-0x7a,0x331,0xdc22,0x68,0x331,0xe622,0x74,0x308,0xe622,0x77,0x30a,0xe622,0x79,0x30a,0xe602,0x17f,
-0x307,0xe622,0x41,0x309,0xe622,0x61,0x309,0xc2,0xe663,0x41,0x302,0x301,0xe2,0xe663,0x61,0x302,
-0x301,0xc2,0xe663,0x41,0x302,0x300,0xe2,0xe663,0x61,0x302,0x300,0xc2,0xe663,0x41,0x302,0x309,
-0xe2,0xe663,0x61,0x302,0x309,0xc2,0xe663,0x41,0x302,0x303,0xe2,0xe663,0x61,0x302,0x303,0x1ea0,
-0xe663,0x41,0x323,0x302,0x1ea1,0xe663,0x61,0x323,0x302,0x102,0xe663,0x41,0x306,0x301,0x103,0xe663,
-0x61,0x306,0x301,0x102,0xe663,0x41,0x306,0x300,0x103,0xe663,0x61,0x306,0x300,0x102,0xe663,0x41,
-0x306,0x309,0x103,0xe663,0x61,0x306,0x309,0x102,0xe663,0x41,0x306,0x303,0x103,0xe663,0x61,0x306,
-0x303,0x1ea0,0xe663,0x41,0x323,0x306,0x1ea1,0xe663,0x61,0x323,0x306,0xe622,0x45,0x309,0xe622,0x65,
-0x309,0xe622,0x45,0x303,0xe622,0x65,0x303,0xca,0xe663,0x45,0x302,0x301,0xea,0xe663,0x65,0x302,
-0x301,0xca,0xe663,0x45,0x302,0x300,0xea,0xe663,0x65,0x302,0x300,0xca,0xe663,0x45,0x302,0x309,
-0xea,0xe663,0x65,0x302,0x309,0xca,0xe663,0x45,0x302,0x303,0xea,0xe663,0x65,0x302,0x303,0x1eb8,
-0xe663,0x45,0x323,0x302,0x1eb9,0xe663,0x65,0x323,0x302,0xe622,0x49,0x309,0xe622,0x69,0x309,0xdc22,
-0x49,0x323,0xdc22,0x69,0x323,0xe622,0x4f,0x309,0xe622,0x6f,0x309,0xd4,0xe663,0x4f,0x302,0x301,
-0xf4,0xe663,0x6f,0x302,0x301,0xd4,0xe663,0x4f,0x302,0x300,0xf4,0xe663,0x6f,0x302,0x300,0xd4,
-0xe663,0x4f,0x302,0x309,0xf4,0xe663,0x6f,0x302,0x309,0xd4,0xe663,0x4f,0x302,0x303,0xf4,0xe663,
-0x6f,0x302,0x303,0x1ecc,0xe663,0x4f,0x323,0x302,0x1ecd,0xe663,0x6f,0x323,0x302,0x1a0,0xe663,0x4f,
-0x31b,0x301,0x1a1,0xe663,0x6f,0x31b,0x301,0x1a0,0xe663,0x4f,0x31b,0x300,0x1a1,0xe663,0x6f,0x31b,
-0x300,0x1a0,0xe663,0x4f,0x31b,0x309,0x1a1,0xe663,0x6f,0x31b,0x309,0x1a0,0xe663,0x4f,0x31b,0x303,
-0x1a1,0xe663,0x6f,0x31b,0x303,0x1a0,0xdc63,0x4f,0x31b,0x323,0x1a1,0xdc63,0x6f,0x31b,0x323,0xdc22,
-0x55,0x323,0xdc22,0x75,0x323,0xe622,0x55,0x309,0xe622,0x75,0x309,0x1af,0xe663,0x55,0x31b,0x301,
-0x1b0,0xe663,0x75,0x31b,0x301,0x1af,0xe663,0x55,0x31b,0x300,0x1b0,0xe663,0x75,0x31b,0x300,0x1af,
-0xe663,0x55,0x31b,0x309,0x1b0,0xe663,0x75,0x31b,0x309,0x1af,0xe663,0x55,0x31b,0x303,0x1b0,0xe663,
-0x75,0x31b,0x303,0x1af,0xdc63,0x55,0x31b,0x323,0x1b0,0xdc63,0x75,0x31b,0x323,0xe622,0x59,0x300,
-0xe622,0x79,0x300,0xdc02,0x59,0x323,0xdc02,0x79,0x323,0xe622,0x59,0x309,0xe622,0x79,0x309,0xe622,
-0x59,0x303,0xe622,0x79,0x303,0x1f10,0xe643,0x3b5,0x313,0x300,0x1f11,0xe643,0x3b5,0x314,0x300,0x1f10,
-0xe643,0x3b5,0x313,0x301,0x1f11,0xe643,0x3b5,0x314,0x301,0x1f18,0xe643,0x395,0x313,0x300,0x1f19,0xe643,
-0x395,0x314,0x300,0x1f18,0xe643,0x395,0x313,0x301,0x1f19,0xe643,0x395,0x314,0x301,0x1f30,0xe643,0x3b9,
-0x313,0x300,0x1f31,0xe643,0x3b9,0x314,0x300,0x1f30,0xe643,0x3b9,0x313,0x301,0x1f31,0xe643,0x3b9,0x314,
-0x301,0x1f30,0xe643,0x3b9,0x313,0x342,0x1f31,0xe643,0x3b9,0x314,0x342,0x1f38,0xe643,0x399,0x313,0x300,
-0x1f39,0xe643,0x399,0x314,0x300,0x1f38,0xe643,0x399,0x313,0x301,0x1f39,0xe643,0x399,0x314,0x301,0x1f38,
-0xe643,0x399,0x313,0x342,0x1f39,0xe643,0x399,0x314,0x342,0x1f40,0xe643,0x3bf,0x313,0x300,0x1f41,0xe643,
-0x3bf,0x314,0x300,0x1f40,0xe643,0x3bf,0x313,0x301,0x1f41,0xe643,0x3bf,0x314,0x301,0x1f48,0xe643,0x39f,
-0x313,0x300,0x1f49,0xe643,0x39f,0x314,0x300,0x1f48,0xe643,0x39f,0x313,0x301,0x1f49,0xe643,0x39f,0x314,
-0x301,0x1f50,0xe643,0x3c5,0x313,0x300,0x1f51,0xe643,0x3c5,0x314,0x300,0x1f50,0xe643,0x3c5,0x313,0x301,
-0x1f51,0xe643,0x3c5,0x314,0x301,0x1f50,0xe643,0x3c5,0x313,0x342,0x1f51,0xe643,0x3c5,0x314,0x342,0x1f59,
-0xe643,0x3a5,0x314,0x300,0x1f59,0xe643,0x3a5,0x314,0x301,0x1f59,0xe643,0x3a5,0x314,0x342,0xe602,0x3b5,
-0x300,0xe602,0x3b9,0x300,0xe602,0x3bf,0x300,0xe602,0x3c5,0x300,0x1f00,0xf063,0x3b1,0x313,0x345,0x1f01,
-0xf063,0x3b1,0x314,0x345,0x1f02,0x345,2,0xf044,0x3b1,0x313,0x300,0x345,0x1f03,0x345,2,0xf044,
-0x3b1,0x314,0x300,0x345,0x1f04,0x345,2,0xf044,0x3b1,0x313,0x301,0x345,0x1f05,0x345,2,0xf044,
-0x3b1,0x314,0x301,0x345,0x1f06,0x345,2,0xf044,0x3b1,0x313,0x342,0x345,0x1f07,0x345,2,0xf044,
-0x3b1,0x314,0x342,0x345,0x1f08,0xf063,0x391,0x313,0x345,0x1f09,0xf063,0x391,0x314,0x345,0x1f0a,0x345,
-2,0xf044,0x391,0x313,0x300,0x345,0x1f0b,0x345,2,0xf044,0x391,0x314,0x300,0x345,0x1f0c,0x345,
-2,0xf044,0x391,0x313,0x301,0x345,0x1f0d,0x345,2,0xf044,0x391,0x314,0x301,0x345,0x1f0e,0x345,
-2,0xf044,0x391,0x313,0x342,0x345,0x1f0f,0x345,2,0xf044,0x391,0x314,0x342,0x345,0x1f20,0xf063,
-0x3b7,0x313,0x345,0x1f21,0xf063,0x3b7,0x314,0x345,0x1f22,0x345,2,0xf044,0x3b7,0x313,0x300,0x345,
-0x1f23,0x345,2,0xf044,0x3b7,0x314,0x300,0x345,0x1f24,0x345,2,0xf044,0x3b7,0x313,0x301,0x345,
-0x1f25,0x345,2,0xf044,0x3b7,0x314,0x301,0x345,0x1f26,0x345,2,0xf044,0x3b7,0x313,0x342,0x345,
-0x1f27,0x345,2,0xf044,0x3b7,0x314,0x342,0x345,0x1f28,0xf063,0x397,0x313,0x345,0x1f29,0xf063,0x397,
-0x314,0x345,0x1f2a,0x345,2,0xf044,0x397,0x313,0x300,0x345,0x1f2b,0x345,2,0xf044,0x397,0x314,
-0x300,0x345,0x1f2c,0x345,2,0xf044,0x397,0x313,0x301,0x345,0x1f2d,0x345,2,0xf044,0x397,0x314,
-0x301,0x345,0x1f2e,0x345,2,0xf044,0x397,0x313,0x342,0x345,0x1f2f,0x345,2,0xf044,0x397,0x314,
-0x342,0x345,0x1f60,0xf063,0x3c9,0x313,0x345,0x1f61,0xf063,0x3c9,0x314,0x345,0x1f62,0x345,2,0xf044,
-0x3c9,0x313,0x300,0x345,0x1f63,0x345,2,0xf044,0x3c9,0x314,0x300,0x345,0x1f64,0x345,2,0xf044,
-0x3c9,0x313,0x301,0x345,0x1f65,0x345,2,0xf044,0x3c9,0x314,0x301,0x345,0x1f66,0x345,2,0xf044,
-0x3c9,0x313,0x342,0x345,0x1f67,0x345,2,0xf044,0x3c9,0x314,0x342,0x345,0x1f68,0xf063,0x3a9,0x313,
-0x345,0x1f69,0xf063,0x3a9,0x314,0x345,0x1f6a,0x345,2,0xf044,0x3a9,0x313,0x300,0x345,0x1f6b,0x345,
-2,0xf044,0x3a9,0x314,0x300,0x345,0x1f6c,0x345,2,0xf044,0x3a9,0x313,0x301,0x345,0x1f6d,0x345,
-2,0xf044,0x3a9,0x314,0x301,0x345,0x1f6e,0x345,2,0xf044,0x3a9,0x313,0x342,0x345,0x1f6f,0x345,
-2,0xf044,0x3a9,0x314,0x342,0x345,0xe602,0x3b1,0x306,0xe602,0x3b1,0x304,0x1f70,0xf043,0x3b1,0x300,
-0x345,0xf022,0x3b1,0x345,0x3ac,0xf043,0x3b1,0x301,0x345,0x1fb6,0xf043,0x3b1,0x342,0x345,0xe602,0x391,
-0x306,0xe602,0x391,0x304,0xe602,0x391,0x300,0xf022,0x391,0x345,0xe602,0xa8,0x342,0x1f74,0xf043,0x3b7,
-0x300,0x345,0xf022,0x3b7,0x345,0x3ae,0xf043,0x3b7,0x301,0x345,0x1fc6,0xf043,0x3b7,0x342,0x345,0xe602,
-0x395,0x300,0xe602,0x397,0x300,0xf022,0x397,0x345,0xe602,0x1fbf,0x300,0xe602,0x1fbf,0x301,0xe602,0x1fbf,
-0x342,0xe602,0x3b9,0x306,0xe602,0x3b9,0x304,0x3ca,0xe643,0x3b9,0x308,0x300,0xe602,0x3b9,0x342,0x3ca,
-0xe643,0x3b9,0x308,0x342,0xe602,0x399,0x306,0xe602,0x399,0x304,0xe602,0x399,0x300,0xe602,0x1ffe,0x300,
-0xe602,0x1ffe,0x301,0xe602,0x1ffe,0x342,0xe602,0x3c5,0x306,0xe602,0x3c5,0x304,0x3cb,0xe643,0x3c5,0x308,
-0x300,0xe602,0x3c1,0x313,0xe602,0x3c1,0x314,0xe602,0x3c5,0x342,0x3cb,0xe643,0x3c5,0x308,0x342,0xe602,
-0x3a5,0x306,0xe602,0x3a5,0x304,0xe602,0x3a5,0x300,0xe602,0x3a1,0x314,0xe602,0xa8,0x300,0x1f7c,0xf043,
-0x3c9,0x300,0x345,0xf022,0x3c9,0x345,0x3ce,0xf043,0x3c9,0x301,0x345,0x1ff6,0xf043,0x3c9,0x342,0x345,
-0xe602,0x39f,0x300,0xe602,0x3a9,0x300,0xf022,0x3a9,0x345,0x102,0x2190,0x338,0x102,0x2192,0x338,0x102,
-0x2194,0x338,0x102,0x21d0,0x338,0x102,0x21d4,0x338,0x102,0x21d2,0x338,0x102,0x2203,0x338,0x102,0x2208,
-0x338,0x102,0x220b,0x338,0x102,0x2223,0x338,0x102,0x2225,0x338,0x102,0x223c,0x338,0x102,0x2243,0x338,
-0x102,0x2245,0x338,0x102,0x2248,0x338,0x102,0x3d,0x338,0x102,0x2261,0x338,0x102,0x224d,0x338,0x102,
-0x3c,0x338,0x102,0x3e,0x338,0x102,0x2264,0x338,0x102,0x2265,0x338,0x102,0x2272,0x338,0x102,0x2273,
-0x338,0x102,0x2276,0x338,0x102,0x2277,0x338,0x102,0x227a,0x338,0x102,0x227b,0x338,0x102,0x2282,0x338,
-0x102,0x2283,0x338,0x102,0x2286,0x338,0x102,0x2287,0x338,0x102,0x22a2,0x338,0x102,0x22a8,0x338,0x102,
-0x22a9,0x338,0x102,0x22ab,0x338,0x102,0x227c,0x338,0x102,0x227d,0x338,0x102,0x2291,0x338,0x102,0x2292,
-0x338,0x102,0x22b2,0x338,0x102,0x22b3,0x338,0x102,0x22b4,0x338,0x102,0x22b5,0x338,0x802,0x304b,0x3099,
-0x802,0x304d,0x3099,0x802,0x304f,0x3099,0x802,0x3051,0x3099,0x802,0x3053,0x3099,0x802,0x3055,0x3099,0x802,
-0x3057,0x3099,0x802,0x3059,0x3099,0x802,0x305b,0x3099,0x802,0x305d,0x3099,0x802,0x305f,0x3099,0x802,0x3061,
-0x3099,0x802,0x3064,0x3099,0x802,0x3066,0x3099,0x802,0x3068,0x3099,0x802,0x306f,0x3099,0x802,0x306f,0x309a,
-0x802,0x3072,0x3099,0x802,0x3072,0x309a,0x802,0x3075,0x3099,0x802,0x3075,0x309a,0x802,0x3078,0x3099,0x802,
-0x3078,0x309a,0x802,0x307b,0x3099,0x802,0x307b,0x309a,0x802,0x3046,0x3099,0x802,0x309d,0x3099,0x802,0x30ab,
-0x3099,0x802,0x30ad,0x3099,0x802,0x30af,0x3099,0x802,0x30b1,0x3099,0x802,0x30b3,0x3099,0x802,0x30b5,0x3099,
-0x802,0x30b7,0x3099,0x802,0x30b9,0x3099,0x802,0x30bb,0x3099,0x802,0x30bd,0x3099,0x802,0x30bf,0x3099,0x802,
-0x30c1,0x3099,0x802,0x30c4,0x3099,0x802,0x30c6,0x3099,0x802,0x30c8,0x3099,0x802,0x30cf,0x3099,0x802,0x30cf,
-0x309a,0x802,0x30d2,0x3099,0x802,0x30d2,0x309a,0x802,0x30d5,0x3099,0x802,0x30d5,0x309a,0x802,0x30d8,0x3099,
-0x802,0x30d8,0x309a,0x802,0x30db,0x3099,0x802,0x30db,0x309a,0x802,0x30a6,0x3099,0x802,0x30ef,0x3099,0x802,
-0x30f0,0x3099,0x802,0x30f1,0x3099,0x802,0x30f2,0x3099,0x802,0x30fd,0x3099,0x704,0xd804,0xdc99,0xd804,0xdcba,
-0x704,0xd804,0xdc9b,0xd804,0xdcba,0x704,0xd804,0xdca5,0xd804,0xdcba,4,0xd804,0xdd31,0xd804,0xdd27,4,
-0xd804,0xdd32,0xd804,0xdd27,4,0xd804,0xdf47,0xd804,0xdf3e,4,0xd804,0xdf47,0xd804,0xdf57,4,0xd805,
-0xdcb9,0xd805,0xdcba,4,0xd805,0xdcb9,0xd805,0xdcb0,4,0xd805,0xdcb9,0xd805,0xdcbd,4,0xd805,0xddb8,
-0xd805,0xddaf,4,0xd805,0xddb9,0xd805,0xddaf,0xe6e6,0xe6a1,0x300,0xe6e6,0xe6a1,0x301,0xe6e6,0xe6a1,0x313,
-0xe6e6,0xe6a2,0x308,0x301,1,0x2b9,1,0x3b,1,0xb7,0x702,0x915,0x93c,0x702,0x916,0x93c,
-0x702,0x917,0x93c,0x702,0x91c,0x93c,0x702,0x921,0x93c,0x702,0x922,0x93c,0x702,0x92b,0x93c,0x702,
-0x92f,0x93c,0x702,0x9a1,0x9bc,0x702,0x9a2,0x9bc,0x702,0x9af,0x9bc,0x702,0xa32,0xa3c,0x702,0xa38,
-0xa3c,0x702,0xa16,0xa3c,0x702,0xa17,0xa3c,0x702,0xa1c,0xa3c,0x702,0xa2b,0xa3c,0x702,0xb21,0xb3c,
-0x702,0xb22,0xb3c,2,0xf42,0xfb7,2,0xf4c,0xfb7,2,0xf51,0xfb7,2,0xf56,0xfb7,2,
-0xf5b,0xfb7,2,0xf40,0xfb5,0x8100,0x82a2,0xf71,0xf72,0x8100,0x84a2,0xf71,0xf74,0x8202,0xfb2,0xf80,
-0x8202,0xfb3,0xf80,0x8100,0x82a2,0xf71,0xf80,2,0xf92,0xfb7,2,0xf9c,0xfb7,2,0xfa1,0xfb7,
-2,0xfa6,0xfb7,2,0xfab,0xfb7,2,0xf90,0xfb5,0x3ac,0xe662,0x3b1,0x301,0x3ad,0xe642,0x3b5,
-0x301,0x3ae,0xe662,0x3b7,0x301,0x3af,0xe642,0x3b9,0x301,0x3cc,0xe642,0x3bf,0x301,0x3cd,0xe642,0x3c5,
-0x301,0x3ce,0xe662,0x3c9,0x301,0x386,0xe642,0x391,0x301,0x21,0x3b9,0x388,0xe642,0x395,0x301,0x389,
-0xe642,0x397,0x301,0x390,1,0xe643,0x3b9,0x308,0x301,0x38a,0xe642,0x399,0x301,0x3b0,1,0xe643,
-0x3c5,0x308,0x301,0x38e,0xe642,0x3a5,0x301,0x385,0xe642,0xa8,0x301,1,0x60,0x38c,0xe642,0x39f,
-0x301,0x38f,0xe642,0x3a9,0x301,1,0xb4,0x21,0x3a9,0x21,0x4b,0xc5,0xe662,0x41,0x30a,1,
-0x3008,1,0x3009,0x102,0x2add,0x338,1,0x8c48,1,0x66f4,1,0x8eca,1,0x8cc8,1,0x6ed1,
-1,0x4e32,1,0x53e5,1,0x9f9c,1,0x5951,1,0x91d1,1,0x5587,1,0x5948,1,0x61f6,
-1,0x7669,1,0x7f85,1,0x863f,1,0x87ba,1,0x88f8,1,0x908f,1,0x6a02,1,0x6d1b,
-1,0x70d9,1,0x73de,1,0x843d,1,0x916a,1,0x99f1,1,0x4e82,1,0x5375,1,0x6b04,
-1,0x721b,1,0x862d,1,0x9e1e,1,0x5d50,1,0x6feb,1,0x85cd,1,0x8964,1,0x62c9,
-1,0x81d8,1,0x881f,1,0x5eca,1,0x6717,1,0x6d6a,1,0x72fc,1,0x90ce,1,0x4f86,
-1,0x51b7,1,0x52de,1,0x64c4,1,0x6ad3,1,0x7210,1,0x76e7,1,0x8001,1,0x8606,
-1,0x865c,1,0x8def,1,0x9732,1,0x9b6f,1,0x9dfa,1,0x788c,1,0x797f,1,0x7da0,
-1,0x83c9,1,0x9304,1,0x9e7f,1,0x8ad6,1,0x58df,1,0x5f04,1,0x7c60,1,0x807e,
-1,0x7262,1,0x78ca,1,0x8cc2,1,0x96f7,1,0x58d8,1,0x5c62,1,0x6a13,1,0x6dda,
-1,0x6f0f,1,0x7d2f,1,0x7e37,1,0x964b,1,0x52d2,1,0x808b,1,0x51dc,1,0x51cc,
-1,0x7a1c,1,0x7dbe,1,0x83f1,1,0x9675,1,0x8b80,1,0x62cf,1,0x8afe,1,0x4e39,
-1,0x5be7,1,0x6012,1,0x7387,1,0x7570,1,0x5317,1,0x78fb,1,0x4fbf,1,0x5fa9,
-1,0x4e0d,1,0x6ccc,1,0x6578,1,0x7d22,1,0x53c3,1,0x585e,1,0x7701,1,0x8449,
-1,0x8aaa,1,0x6bba,1,0x8fb0,1,0x6c88,1,0x62fe,1,0x82e5,1,0x63a0,1,0x7565,
-1,0x4eae,1,0x5169,1,0x51c9,1,0x6881,1,0x7ce7,1,0x826f,1,0x8ad2,1,0x91cf,
-1,0x52f5,1,0x5442,1,0x5973,1,0x5eec,1,0x65c5,1,0x6ffe,1,0x792a,1,0x95ad,
-1,0x9a6a,1,0x9e97,1,0x9ece,1,0x529b,1,0x66c6,1,0x6b77,1,0x8f62,1,0x5e74,
-1,0x6190,1,0x6200,1,0x649a,1,0x6f23,1,0x7149,1,0x7489,1,0x79ca,1,0x7df4,
-1,0x806f,1,0x8f26,1,0x84ee,1,0x9023,1,0x934a,1,0x5217,1,0x52a3,1,0x54bd,
-1,0x70c8,1,0x88c2,1,0x5ec9,1,0x5ff5,1,0x637b,1,0x6bae,1,0x7c3e,1,0x7375,
-1,0x4ee4,1,0x56f9,1,0x5dba,1,0x601c,1,0x73b2,1,0x7469,1,0x7f9a,1,0x8046,
-1,0x9234,1,0x96f6,1,0x9748,1,0x9818,1,0x4f8b,1,0x79ae,1,0x91b4,1,0x96b8,
-1,0x60e1,1,0x4e86,1,0x50da,1,0x5bee,1,0x5c3f,1,0x6599,1,0x71ce,1,0x7642,
-1,0x84fc,1,0x907c,1,0x9f8d,1,0x6688,1,0x962e,1,0x5289,1,0x677b,1,0x67f3,
-1,0x6d41,1,0x6e9c,1,0x7409,1,0x7559,1,0x786b,1,0x7d10,1,0x985e,1,0x516d,
-1,0x622e,1,0x9678,1,0x502b,1,0x5d19,1,0x6dea,1,0x8f2a,1,0x5f8b,1,0x6144,
-1,0x6817,1,0x9686,1,0x5229,1,0x540f,1,0x5c65,1,0x6613,1,0x674e,1,0x68a8,
-1,0x6ce5,1,0x7406,1,0x75e2,1,0x7f79,1,0x88cf,1,0x88e1,1,0x91cc,1,0x96e2,
-1,0x533f,1,0x6eba,1,0x541d,1,0x71d0,1,0x7498,1,0x85fa,1,0x96a3,1,0x9c57,
-1,0x9e9f,1,0x6797,1,0x6dcb,1,0x81e8,1,0x7acb,1,0x7b20,1,0x7c92,1,0x72c0,
-1,0x7099,1,0x8b58,1,0x4ec0,1,0x8336,1,0x523a,1,0x5207,1,0x5ea6,1,0x62d3,
-1,0x7cd6,1,0x5b85,1,0x6d1e,1,0x66b4,1,0x8f3b,1,0x884c,1,0x964d,1,0x898b,
-1,0x5ed3,1,0x5140,1,0x55c0,1,0x585a,1,0x6674,1,0x51de,1,0x732a,1,0x76ca,
-1,0x793c,1,0x795e,1,0x7965,1,0x798f,1,0x9756,1,0x7cbe,1,0x7fbd,1,0x8612,
-1,0x8af8,1,0x9038,1,0x90fd,1,0x98ef,1,0x98fc,1,0x9928,1,0x9db4,1,0x90de,
-1,0x96b7,1,0x4fae,1,0x50e7,1,0x514d,1,0x52c9,1,0x52e4,1,0x5351,1,0x559d,
-1,0x5606,1,0x5668,1,0x5840,1,0x58a8,1,0x5c64,1,0x5c6e,1,0x6094,1,0x6168,
-1,0x618e,1,0x61f2,1,0x654f,1,0x65e2,1,0x6691,1,0x6885,1,0x6d77,1,0x6e1a,
-1,0x6f22,1,0x716e,1,0x722b,1,0x7422,1,0x7891,1,0x793e,1,0x7949,1,0x7948,
-1,0x7950,1,0x7956,1,0x795d,1,0x798d,1,0x798e,1,0x7a40,1,0x7a81,1,0x7bc0,
-1,0x7e09,1,0x7e41,1,0x7f72,1,0x8005,1,0x81ed,1,0x8279,1,0x8457,1,0x8910,
-1,0x8996,1,0x8b01,1,0x8b39,1,0x8cd3,1,0x8d08,1,0x8fb6,1,0x96e3,1,0x97ff,
-1,0x983b,1,0x6075,2,0xd850,0xdeee,1,0x8218,1,0x4e26,1,0x51b5,1,0x5168,1,
-0x4f80,1,0x5145,1,0x5180,1,0x52c7,1,0x52fa,1,0x5555,1,0x5599,1,0x55e2,1,
-0x58b3,1,0x5944,1,0x5954,1,0x5a62,1,0x5b28,1,0x5ed2,1,0x5ed9,1,0x5f69,1,
-0x5fad,1,0x60d8,1,0x614e,1,0x6108,1,0x6160,1,0x6234,1,0x63c4,1,0x641c,1,
-0x6452,1,0x6556,1,0x671b,1,0x6756,1,0x6b79,1,0x6edb,1,0x6ecb,1,0x701e,1,
-0x77a7,1,0x7235,1,0x72af,1,0x7471,1,0x7506,1,0x753b,1,0x761d,1,0x761f,1,
-0x76db,1,0x76f4,1,0x774a,1,0x7740,1,0x78cc,1,0x7ab1,1,0x7c7b,1,0x7d5b,1,
-0x7f3e,1,0x8352,1,0x83ef,1,0x8779,1,0x8941,1,0x8986,1,0x8abf,1,0x8acb,1,
-0x8aed,1,0x8b8a,1,0x8f38,1,0x9072,1,0x9199,1,0x9276,1,0x967c,1,0x97db,1,
-0x980b,1,0x9b12,2,0xd84a,0xdc4a,2,0xd84a,0xdc44,2,0xd84c,0xdfd5,1,0x3b9d,1,0x4018,
-1,0x4039,2,0xd854,0xde49,2,0xd857,0xdcd0,2,0xd85f,0xded3,1,0x9f43,1,0x9f8e,0xe02,
-0x5d9,0x5b4,0x1102,0x5f2,0x5b7,0x1802,0x5e9,0x5c1,0x1902,0x5e9,0x5c2,0xfb49,0x1843,0x5e9,0x5bc,0x5c1,
-0xfb49,0x1943,0x5e9,0x5bc,0x5c2,0x1102,0x5d0,0x5b7,0x1202,0x5d0,0x5b8,0x1502,0x5d0,0x5bc,0x1502,0x5d1,
-0x5bc,0x1502,0x5d2,0x5bc,0x1502,0x5d3,0x5bc,0x1502,0x5d4,0x5bc,0x1502,0x5d5,0x5bc,0x1502,0x5d6,0x5bc,
-0x1502,0x5d8,0x5bc,0x1502,0x5d9,0x5bc,0x1502,0x5da,0x5bc,0x1502,0x5db,0x5bc,0x1502,0x5dc,0x5bc,0x1502,
-0x5de,0x5bc,0x1502,0x5e0,0x5bc,0x1502,0x5e1,0x5bc,0x1502,0x5e3,0x5bc,0x1502,0x5e4,0x5bc,0x1502,0x5e6,
-0x5bc,0x1502,0x5e7,0x5bc,0x1502,0x5e8,0x5bc,0x1502,0x5e9,0x5bc,0x1502,0x5ea,0x5bc,0x1302,0x5d5,0x5b9,
-0x1702,0x5d1,0x5bf,0x1702,0x5db,0x5bf,0x1702,0x5e4,0x5bf,0xd804,0xd834,0xdd57,0xd834,0xdd65,0xd804,0xd834,
-0xdd58,0xd834,0xdd65,0xd834,0xdd5f,0xd834,0xdd6e,4,0xd846,0xd834,0xdd58,0xd834,0xdd65,0xd834,0xdd6e,0xd834,
-0xdd5f,0xd834,0xdd6f,4,0xd846,0xd834,0xdd58,0xd834,0xdd65,0xd834,0xdd6f,0xd834,0xdd5f,0xd834,0xdd70,4,
-0xd846,0xd834,0xdd58,0xd834,0xdd65,0xd834,0xdd70,0xd834,0xdd5f,0xd834,0xdd71,4,0xd846,0xd834,0xdd58,0xd834,
-0xdd65,0xd834,0xdd71,0xd834,0xdd5f,0xd834,0xdd72,4,0xd846,0xd834,0xdd58,0xd834,0xdd65,0xd834,0xdd72,0xd804,
-0xd834,0xddb9,0xd834,0xdd65,0xd804,0xd834,0xddba,0xd834,0xdd65,0xd834,0xddbb,0xd834,0xdd6e,4,0xd846,0xd834,
-0xddb9,0xd834,0xdd65,0xd834,0xdd6e,0xd834,0xddbc,0xd834,0xdd6e,4,0xd846,0xd834,0xddba,0xd834,0xdd65,0xd834,
-0xdd6e,0xd834,0xddbb,0xd834,0xdd6f,4,0xd846,0xd834,0xddb9,0xd834,0xdd65,0xd834,0xdd6f,0xd834,0xddbc,0xd834,
-0xdd6f,4,0xd846,0xd834,0xddba,0xd834,0xdd65,0xd834,0xdd6f,1,0x4e3d,1,0x4e38,1,0x4e41,2,
-0xd840,0xdd22,1,0x4f60,1,0x4fbb,1,0x5002,1,0x507a,1,0x5099,1,0x50cf,1,0x349e,
-2,0xd841,0xde3a,1,0x5154,1,0x5164,1,0x5177,2,0xd841,0xdd1c,1,0x34b9,1,0x5167,
-1,0x518d,2,0xd841,0xdd4b,1,0x5197,1,0x51a4,1,0x4ecc,1,0x51ac,2,0xd864,0xdddf,
-1,0x51f5,1,0x5203,1,0x34df,1,0x523b,1,0x5246,1,0x5272,1,0x5277,1,0x3515,
-1,0x5305,1,0x5306,1,0x5349,1,0x535a,1,0x5373,1,0x537d,1,0x537f,2,0xd842,
-0xde2c,1,0x7070,1,0x53ca,1,0x53df,2,0xd842,0xdf63,1,0x53eb,1,0x53f1,1,0x5406,
-1,0x549e,1,0x5438,1,0x5448,1,0x5468,1,0x54a2,1,0x54f6,1,0x5510,1,0x5553,
-1,0x5563,1,0x5584,1,0x55ab,1,0x55b3,1,0x55c2,1,0x5716,1,0x5717,1,0x5651,
-1,0x5674,1,0x58ee,1,0x57ce,1,0x57f4,1,0x580d,1,0x578b,1,0x5832,1,0x5831,
-1,0x58ac,2,0xd845,0xdce4,1,0x58f2,1,0x58f7,1,0x5906,1,0x591a,1,0x5922,1,
-0x5962,2,0xd845,0xdea8,2,0xd845,0xdeea,1,0x59ec,1,0x5a1b,1,0x5a27,1,0x59d8,1,
-0x5a66,1,0x36ee,1,0x36fc,1,0x5b08,1,0x5b3e,2,0xd846,0xddc8,1,0x5bc3,1,0x5bd8,
-1,0x5bf3,2,0xd846,0xdf18,1,0x5bff,1,0x5c06,1,0x5f53,1,0x5c22,1,0x3781,1,
-0x5c60,1,0x5cc0,1,0x5c8d,2,0xd847,0xdde4,1,0x5d43,2,0xd847,0xdde6,1,0x5d6e,1,
-0x5d6b,1,0x5d7c,1,0x5de1,1,0x5de2,1,0x382f,1,0x5dfd,1,0x5e28,1,0x5e3d,1,
-0x5e69,1,0x3862,2,0xd848,0xdd83,1,0x387c,1,0x5eb0,1,0x5eb3,1,0x5eb6,2,0xd868,
-0xdf92,1,0x5efe,2,0xd848,0xdf31,1,0x8201,1,0x5f22,1,0x38c7,2,0xd84c,0xdeb8,2,
-0xd858,0xddda,1,0x5f62,1,0x5f6b,1,0x38e3,1,0x5f9a,1,0x5fcd,1,0x5fd7,1,0x5ff9,
-1,0x6081,1,0x393a,1,0x391c,2,0xd849,0xded4,1,0x60c7,1,0x6148,1,0x614c,1,
-0x617a,1,0x61b2,1,0x61a4,1,0x61af,1,0x61de,1,0x6210,1,0x621b,1,0x625d,1,
-0x62b1,1,0x62d4,1,0x6350,2,0xd84a,0xdf0c,1,0x633d,1,0x62fc,1,0x6368,1,0x6383,
-1,0x63e4,2,0xd84a,0xdff1,1,0x6422,1,0x63c5,1,0x63a9,1,0x3a2e,1,0x6469,1,
-0x647e,1,0x649d,1,0x6477,1,0x3a6c,1,0x656c,2,0xd84c,0xdc0a,1,0x65e3,1,0x66f8,
-1,0x6649,1,0x3b19,1,0x3b08,1,0x3ae4,1,0x5192,1,0x5195,1,0x6700,1,0x669c,
-1,0x80ad,1,0x43d9,1,0x6721,1,0x675e,1,0x6753,2,0xd84c,0xdfc3,1,0x3b49,1,
-0x67fa,1,0x6785,1,0x6852,2,0xd84d,0xdc6d,1,0x688e,1,0x681f,1,0x6914,1,0x6942,
-1,0x69a3,1,0x69ea,1,0x6aa8,2,0xd84d,0xdea3,1,0x6adb,1,0x3c18,1,0x6b21,2,
-0xd84e,0xdca7,1,0x6b54,1,0x3c4e,1,0x6b72,1,0x6b9f,1,0x6bbb,2,0xd84e,0xde8d,2,
-0xd847,0xdd0b,2,0xd84e,0xdefa,1,0x6c4e,2,0xd84f,0xdcbc,1,0x6cbf,1,0x6ccd,1,0x6c67,
-1,0x6d16,1,0x6d3e,1,0x6d69,1,0x6d78,1,0x6d85,2,0xd84f,0xdd1e,1,0x6d34,1,
-0x6e2f,1,0x6e6e,1,0x3d33,1,0x6ec7,2,0xd84f,0xded1,1,0x6df9,1,0x6f6e,2,0xd84f,
-0xdf5e,2,0xd84f,0xdf8e,1,0x6fc6,1,0x7039,1,0x701b,1,0x3d96,1,0x704a,1,0x707d,
-1,0x7077,1,0x70ad,2,0xd841,0xdd25,1,0x7145,2,0xd850,0xde63,1,0x719c,2,0xd850,
-0xdfab,1,0x7228,1,0x7250,2,0xd851,0xde08,1,0x7280,1,0x7295,2,0xd851,0xdf35,2,
-0xd852,0xdc14,1,0x737a,1,0x738b,1,0x3eac,1,0x73a5,1,0x3eb8,1,0x7447,1,0x745c,
-1,0x7485,1,0x74ca,1,0x3f1b,1,0x7524,2,0xd853,0xdc36,1,0x753e,2,0xd853,0xdc92,
-2,0xd848,0xdd9f,1,0x7610,2,0xd853,0xdfa1,2,0xd853,0xdfb8,2,0xd854,0xdc44,1,0x3ffc,
-1,0x4008,2,0xd854,0xdcf3,2,0xd854,0xdcf2,2,0xd854,0xdd19,2,0xd854,0xdd33,1,0x771e,
-1,0x771f,1,0x778b,1,0x4046,1,0x4096,2,0xd855,0xdc1d,1,0x784e,1,0x40e3,2,
-0xd855,0xde26,2,0xd855,0xde9a,2,0xd855,0xdec5,1,0x79eb,1,0x412f,1,0x7a4a,1,0x7a4f,
-2,0xd856,0xdd7c,2,0xd856,0xdea7,1,0x7aee,1,0x4202,2,0xd856,0xdfab,1,0x7bc6,1,
-0x7bc9,1,0x4227,2,0xd857,0xdc80,1,0x7cd2,1,0x42a0,1,0x7ce8,1,0x7ce3,1,0x7d00,
-2,0xd857,0xdf86,1,0x7d63,1,0x4301,1,0x7dc7,1,0x7e02,1,0x7e45,1,0x4334,2,
-0xd858,0xde28,2,0xd858,0xde47,1,0x4359,2,0xd858,0xded9,1,0x7f7a,2,0xd858,0xdf3e,1,
-0x7f95,1,0x7ffa,2,0xd859,0xdcda,2,0xd859,0xdd23,1,0x8060,2,0xd859,0xdda8,1,0x8070,
-2,0xd84c,0xdf5f,1,0x43d5,1,0x80b2,1,0x8103,1,0x440b,1,0x813e,1,0x5ab5,2,
-0xd859,0xdfa7,2,0xd859,0xdfb5,2,0xd84c,0xdf93,2,0xd84c,0xdf9c,1,0x8204,1,0x8f9e,1,
-0x446b,1,0x8291,1,0x828b,1,0x829d,1,0x52b3,1,0x82b1,1,0x82b3,1,0x82bd,1,
-0x82e6,2,0xd85a,0xdf3c,1,0x831d,1,0x8363,1,0x83ad,1,0x8323,1,0x83bd,1,0x83e7,
-1,0x8353,1,0x83ca,1,0x83cc,1,0x83dc,2,0xd85b,0xdc36,2,0xd85b,0xdd6b,2,0xd85b,
-0xdcd5,1,0x452b,1,0x84f1,1,0x84f3,1,0x8516,2,0xd85c,0xdfca,1,0x8564,2,0xd85b,
-0xdf2c,1,0x455d,1,0x4561,2,0xd85b,0xdfb1,2,0xd85c,0xdcd2,1,0x456b,1,0x8650,1,
-0x8667,1,0x8669,1,0x86a9,1,0x8688,1,0x870e,1,0x86e2,1,0x8728,1,0x876b,1,
-0x8786,1,0x45d7,1,0x87e1,1,0x8801,1,0x45f9,1,0x8860,1,0x8863,2,0xd85d,0xde67,
-1,0x88d7,1,0x88de,1,0x4635,1,0x88fa,1,0x34bb,2,0xd85e,0xdcae,2,0xd85e,0xdd66,
-1,0x46be,1,0x46c7,1,0x8aa0,1,0x8c55,2,0xd85f,0xdca8,1,0x8cab,1,0x8cc1,1,
-0x8d1b,1,0x8d77,2,0xd85f,0xdf2f,2,0xd842,0xdc04,1,0x8dcb,1,0x8dbc,1,0x8df0,2,
-0xd842,0xdcde,1,0x8ed4,2,0xd861,0xddd2,2,0xd861,0xdded,1,0x9094,1,0x90f1,1,0x9111,
-2,0xd861,0xdf2e,1,0x911b,1,0x9238,1,0x92d7,1,0x92d8,1,0x927c,1,0x93f9,1,
-0x9415,2,0xd862,0xdffa,1,0x958b,1,0x4995,1,0x95b7,2,0xd863,0xdd77,1,0x49e6,1,
-0x96c3,1,0x5db2,1,0x9723,2,0xd864,0xdd45,2,0xd864,0xde1a,1,0x4a6e,1,0x4a76,1,
-0x97e0,2,0xd865,0xdc0a,1,0x4ab2,2,0xd865,0xdc96,1,0x9829,2,0xd865,0xddb6,1,0x98e2,
-1,0x4b33,1,0x9929,1,0x99a7,1,0x99c2,1,0x99fe,1,0x4bce,2,0xd866,0xdf30,1,
-0x9c40,1,0x9cfd,1,0x4cce,1,0x4ced,1,0x9d67,2,0xd868,0xdcce,1,0x4cf8,2,0xd868,
-0xdd05,2,0xd868,0xde0e,2,0xd868,0xde91,1,0x9ebb,1,0x4d56,1,0x9ef9,1,0x9efe,1,
-0x9f05,1,0x9f0f,1,0x9f16,1,0x9f3b,2,0xd869,0xde00
+0x2c02,0x2978,0x348b,0x2e82,0x2976,0xb48b,0x2f42,0x297c,0xb48b,0x6bc2,0x2b74,0xb48b,0x6bc2,0x2b76,0xb48d,0x4c02,
+0x3270,2,0xe602,0x41,0x302,0x600,0x3d4c,0x602,0x3d48,0x606,0x3d54,0x8612,0x3d50,0xe602,0x41,0x308,
+0x8608,0x3bc,0xe602,0x41,0x30a,0x8602,0x3f4,0xca02,0x43,0x327,0x8602,0x3c10,0xe602,0x45,0x302,0x600,
+0x3d80,0x602,0x3d7c,0x606,0x3d88,0x8612,0x3d84,0xe602,0x49,0x308,0x8602,0x3c5c,0xe602,0x4f,0x302,0x600,
+0x3da4,0x602,0x3da0,0x606,0x3dac,0x8612,0x3da8,0xe602,0x4f,0x303,0x602,0x3c98,0x608,0x458,0x8610,0x3c9c,
+0xe602,0x4f,0x308,0x8608,0x454,0xe602,0x55,0x308,0x600,0x3b6,0x602,0x3ae,0x608,0x3aa,0x8618,0x3b2,
+0xe602,0x61,0x302,0x600,0x3d4e,0x602,0x3d4a,0x606,0x3d56,0x8612,0x3d52,0xe602,0x61,0x308,0x8608,0x3be,
+0xe602,0x61,0x30a,0x8602,0x3f6,0xca02,0x63,0x327,0x8602,0x3c12,0xe602,0x65,0x302,0x600,0x3d82,0x602,
+0x3d7e,0x606,0x3d8a,0x8612,0x3d86,0xe602,0x69,0x308,0x8602,0x3c5e,0xe602,0x6f,0x302,0x600,0x3da6,0x602,
+0x3da2,0x606,0x3dae,0x8612,0x3daa,0xe602,0x6f,0x303,0x602,0x3c9a,0x608,0x45a,0x8610,0x3c9e,0xe602,0x6f,
+0x308,0x8608,0x456,0xe602,0x75,0x308,0x600,0x3b8,0x602,0x3b0,0x608,0x3ac,0x8618,0x3b4,0xe602,0x41,
+0x306,0x600,0x3d60,0x602,0x3d5c,0x606,0x3d68,0x8612,0x3d64,0xe602,0x61,0x306,0x600,0x3d62,0x602,0x3d5e,
+0x606,0x3d6a,0x8612,0x3d66,0xe602,0x45,0x304,0x600,0x3c28,0x8602,0x3c2c,0xe602,0x65,0x304,0x600,0x3c2a,
+0x8602,0x3c2e,0xe602,0x4f,0x304,0x600,0x3ca0,0x8602,0x3ca4,0xe602,0x6f,0x304,0x600,0x3ca2,0x8602,0x3ca6,
+0xe602,0x53,0x301,0x860e,0x3cc8,0xe602,0x73,0x301,0x860e,0x3cca,0xe602,0x53,0x30c,0x860e,0x3ccc,0xe602,
+0x73,0x30c,0x860e,0x3cce,0xe602,0x55,0x303,0x8602,0x3cf0,0xe602,0x75,0x303,0x8602,0x3cf2,0xe602,0x55,
+0x304,0x8610,0x3cf4,0xe602,0x75,0x304,0x8610,0x3cf6,0xd802,0x4f,0x31b,0x600,0x3db8,0x602,0x3db4,0x606,
+0x3dc0,0x612,0x3dbc,0x8646,0x3dc4,0xd802,0x6f,0x31b,0x600,0x3dba,0x602,0x3db6,0x606,0x3dc2,0x612,0x3dbe,
+0x8646,0x3dc6,0xd802,0x55,0x31b,0x600,0x3dd4,0x602,0x3dd0,0x606,0x3ddc,0x612,0x3dd8,0x8646,0x3de0,0xd802,
+0x75,0x31b,0x600,0x3dd6,0x602,0x3dd2,0x606,0x3dde,0x612,0x3dda,0x8646,0x3de2,0xca02,0x4f,0x328,0x8608,
+0x3d8,0xca02,0x6f,0x328,0x8608,0x3da,0xe602,0x41,0x307,0x8608,0x3c0,0xe602,0x61,0x307,0x8608,0x3c2,
+0xca02,0x45,0x327,0x860c,0x3c38,0xca02,0x65,0x327,0x860c,0x3c3a,0xe602,0x4f,0x307,0x8608,0x460,0xe602,
+0x6f,0x307,0x8608,0x462,0xe602,0x3b1,0x301,0x868a,0x3f68,0xe602,0x3b7,0x301,0x868a,0x3f88,0xe602,0x3b9,
+0x308,0x600,0x3fa4,0x602,0x720,0x8684,0x3fae,0xe602,0x3c5,0x308,0x600,0x3fc4,0x602,0x760,0x8684,0x3fce,
+0xe602,0x3c9,0x301,0x868a,0x3fe8,2,0xcc6,0xcc2,0x99aa,0x1996,2,0xdd9,0xdcf,0x9b94,0x1bba,0xdc02,
+0x4c,0x323,0x8608,0x3c70,0xdc02,0x6c,0x323,0x8608,0x3c72,0xdc02,0x52,0x323,0x8608,0x3cb8,0xdc02,0x72,
+0x323,0x8608,0x3cba,0xdc02,0x53,0x323,0x860e,0x3cd0,0xdc02,0x73,0x323,0x860e,0x3cd2,0xdc02,0x41,0x323,
+0x604,0x3d58,0x860c,0x3d6c,0xdc02,0x61,0x323,0x604,0x3d5a,0x860c,0x3d6e,0xdc02,0x45,0x323,0x8604,0x3d8c,
+0xdc02,0x65,0x323,0x8604,0x3d8e,0xdc02,0x4f,0x323,0x8604,0x3db0,0xdc02,0x6f,0x323,0x8604,0x3db2,0xe602,
+0x3b1,0x313,0x600,0x3e05,0x602,0x3e09,0x684,0x3e0d,0x868a,0x3f00,0xe602,0x3b1,0x314,0x600,0x3e07,0x602,
+0x3e0b,0x684,0x3e0f,0x868a,0x3f02,0x1f00,0xe643,0x3b1,0x313,0x300,0x868a,0x3f04,0x1f01,0xe643,0x3b1,0x314,
+0x300,0x868a,0x3f06,0x1f00,0xe643,0x3b1,0x313,0x301,0x868a,0x3f08,0x1f01,0xe643,0x3b1,0x314,0x301,0x868a,
+0x3f0a,0x1f00,0xe643,0x3b1,0x313,0x342,0x868a,0x3f0c,0x1f01,0xe643,0x3b1,0x314,0x342,0x868a,0x3f0e,0xe602,
+0x391,0x313,0x600,0x3e15,0x602,0x3e19,0x684,0x3e1d,0x868a,0x3f10,0xe602,0x391,0x314,0x600,0x3e17,0x602,
+0x3e1b,0x684,0x3e1f,0x868a,0x3f12,0x1f08,0xe643,0x391,0x313,0x300,0x868a,0x3f14,0x1f09,0xe643,0x391,0x314,
+0x300,0x868a,0x3f16,0x1f08,0xe643,0x391,0x313,0x301,0x868a,0x3f18,0x1f09,0xe643,0x391,0x314,0x301,0x868a,
+0x3f1a,0x1f08,0xe643,0x391,0x313,0x342,0x868a,0x3f1c,0x1f09,0xe643,0x391,0x314,0x342,0x868a,0x3f1e,0xe602,
+0x3b5,0x313,0x600,0x3e24,0x8602,0x3e28,0xe602,0x3b5,0x314,0x600,0x3e26,0x8602,0x3e2a,0xe602,0x395,0x313,
+0x600,0x3e34,0x8602,0x3e38,0xe602,0x395,0x314,0x600,0x3e36,0x8602,0x3e3a,0xe602,0x3b7,0x313,0x600,0x3e45,
+0x602,0x3e49,0x684,0x3e4d,0x868a,0x3f20,0xe602,0x3b7,0x314,0x600,0x3e47,0x602,0x3e4b,0x684,0x3e4f,0x868a,
+0x3f22,0x1f20,0xe643,0x3b7,0x313,0x300,0x868a,0x3f24,0x1f21,0xe643,0x3b7,0x314,0x300,0x868a,0x3f26,0x1f20,
+0xe643,0x3b7,0x313,0x301,0x868a,0x3f28,0x1f21,0xe643,0x3b7,0x314,0x301,0x868a,0x3f2a,0x1f20,0xe643,0x3b7,
+0x313,0x342,0x868a,0x3f2c,0x1f21,0xe643,0x3b7,0x314,0x342,0x868a,0x3f2e,0xe602,0x397,0x313,0x600,0x3e55,
+0x602,0x3e59,0x684,0x3e5d,0x868a,0x3f30,0xe602,0x397,0x314,0x600,0x3e57,0x602,0x3e5b,0x684,0x3e5f,0x868a,
+0x3f32,0x1f28,0xe643,0x397,0x313,0x300,0x868a,0x3f34,0x1f29,0xe643,0x397,0x314,0x300,0x868a,0x3f36,0x1f28,
+0xe643,0x397,0x313,0x301,0x868a,0x3f38,0x1f29,0xe643,0x397,0x314,0x301,0x868a,0x3f3a,0x1f28,0xe643,0x397,
+0x313,0x342,0x868a,0x3f3c,0x1f29,0xe643,0x397,0x314,0x342,0x868a,0x3f3e,0xe602,0x3b9,0x313,0x600,0x3e64,
+0x602,0x3e68,0x8684,0x3e6c,0xe602,0x3b9,0x314,0x600,0x3e66,0x602,0x3e6a,0x8684,0x3e6e,0xe602,0x399,0x313,
+0x600,0x3e74,0x602,0x3e78,0x8684,0x3e7c,0xe602,0x399,0x314,0x600,0x3e76,0x602,0x3e7a,0x8684,0x3e7e,0xe602,
+0x3bf,0x313,0x600,0x3e84,0x8602,0x3e88,0xe602,0x3bf,0x314,0x600,0x3e86,0x8602,0x3e8a,0xe602,0x39f,0x313,
+0x600,0x3e94,0x8602,0x3e98,0xe602,0x39f,0x314,0x600,0x3e96,0x8602,0x3e9a,0xe602,0x3c5,0x313,0x600,0x3ea4,
+0x602,0x3ea8,0x8684,0x3eac,0xe602,0x3c5,0x314,0x600,0x3ea6,0x602,0x3eaa,0x8684,0x3eae,0xe602,0x3a5,0x314,
+0x600,0x3eb6,0x602,0x3eba,0x8684,0x3ebe,0xe602,0x3c9,0x313,0x600,0x3ec5,0x602,0x3ec9,0x684,0x3ecd,0x868a,
+0x3f40,0xe602,0x3c9,0x314,0x600,0x3ec7,0x602,0x3ecb,0x684,0x3ecf,0x868a,0x3f42,0x1f60,0xe643,0x3c9,0x313,
+0x300,0x868a,0x3f44,0x1f61,0xe643,0x3c9,0x314,0x300,0x868a,0x3f46,0x1f60,0xe643,0x3c9,0x313,0x301,0x868a,
+0x3f48,0x1f61,0xe643,0x3c9,0x314,0x301,0x868a,0x3f4a,0x1f60,0xe643,0x3c9,0x313,0x342,0x868a,0x3f4c,0x1f61,
+0xe643,0x3c9,0x314,0x342,0x868a,0x3f4e,0xe602,0x3a9,0x313,0x600,0x3ed5,0x602,0x3ed9,0x684,0x3edd,0x868a,
+0x3f50,0xe602,0x3a9,0x314,0x600,0x3ed7,0x602,0x3edb,0x684,0x3edf,0x868a,0x3f52,0x1f68,0xe643,0x3a9,0x313,
+0x300,0x868a,0x3f54,0x1f69,0xe643,0x3a9,0x314,0x300,0x868a,0x3f56,0x1f68,0xe643,0x3a9,0x313,0x301,0x868a,
+0x3f58,0x1f69,0xe643,0x3a9,0x314,0x301,0x868a,0x3f5a,0x1f68,0xe643,0x3a9,0x313,0x342,0x868a,0x3f5c,0x1f69,
+0xe643,0x3a9,0x314,0x342,0x868a,0x3f5e,0xe602,0x3b1,0x300,0x868a,0x3f64,0xe602,0x3b7,0x300,0x868a,0x3f84,
+0xe602,0x3c9,0x300,0x868a,0x3fe4,0xe602,0x3b1,0x342,0x868a,0x3f6e,0xe602,0x3b7,0x342,0x868a,0x3f8e,0xe602,
+0x3c9,0x342,0x868a,0x3fee,3,0xe602,0x41,0x300,0xe602,0x41,0x301,0xe602,0x41,0x303,0xe602,0x45,
+0x300,0xe602,0x45,0x301,0xe602,0x45,0x308,0xe602,0x49,0x300,0xe602,0x49,0x301,0xe602,0x49,0x302,
+0xe602,0x4e,0x303,0xe602,0x4f,0x300,0xe602,0x4f,0x301,0xe602,0x55,0x300,0xe602,0x55,0x301,0xe602,
+0x55,0x302,0xe602,0x59,0x301,0xe602,0x61,0x300,0xe602,0x61,0x301,0xe602,0x61,0x303,0xe602,0x65,
+0x300,0xe602,0x65,0x301,0xe602,0x65,0x308,0xe602,0x69,0x300,0xe602,0x69,0x301,0xe602,0x69,0x302,
+0xe602,0x6e,0x303,0xe602,0x6f,0x300,0xe602,0x6f,0x301,0xe602,0x75,0x300,0xe602,0x75,0x301,0xe602,
+0x75,0x302,0xe602,0x79,0x301,0xe602,0x79,0x308,0xe602,0x41,0x304,0xe602,0x61,0x304,0xca02,0x41,
+0x328,0xca02,0x61,0x328,0xe602,0x43,0x301,0xe602,0x63,0x301,0xe602,0x43,0x302,0xe602,0x63,0x302,
+0xe602,0x43,0x307,0xe602,0x63,0x307,0xe602,0x43,0x30c,0xe602,0x63,0x30c,0xe602,0x44,0x30c,0xe602,
+0x64,0x30c,0xe602,0x45,0x306,0xe602,0x65,0x306,0xe602,0x45,0x307,0xe602,0x65,0x307,0xca02,0x45,
+0x328,0xca02,0x65,0x328,0xe602,0x45,0x30c,0xe602,0x65,0x30c,0xe602,0x47,0x302,0xe602,0x67,0x302,
+0xe602,0x47,0x306,0xe602,0x67,0x306,0xe602,0x47,0x307,0xe602,0x67,0x307,0xca02,0x47,0x327,0xca02,
+0x67,0x327,0xe602,0x48,0x302,0xe602,0x68,0x302,0xe602,0x49,0x303,0xe602,0x69,0x303,0xe602,0x49,
+0x304,0xe602,0x69,0x304,0xe602,0x49,0x306,0xe602,0x69,0x306,0xca02,0x49,0x328,0xca02,0x69,0x328,
+0xe602,0x49,0x307,0xe602,0x4a,0x302,0xe602,0x6a,0x302,0xca02,0x4b,0x327,0xca02,0x6b,0x327,0xe602,
+0x4c,0x301,0xe602,0x6c,0x301,0xca02,0x4c,0x327,0xca02,0x6c,0x327,0xe602,0x4c,0x30c,0xe602,0x6c,
+0x30c,0xe602,0x4e,0x301,0xe602,0x6e,0x301,0xca02,0x4e,0x327,0xca02,0x6e,0x327,0xe602,0x4e,0x30c,
+0xe602,0x6e,0x30c,0xe602,0x4f,0x306,0xe602,0x6f,0x306,0xe602,0x4f,0x30b,0xe602,0x6f,0x30b,0xe602,
+0x52,0x301,0xe602,0x72,0x301,0xca02,0x52,0x327,0xca02,0x72,0x327,0xe602,0x52,0x30c,0xe602,0x72,
+0x30c,0xe602,0x53,0x302,0xe602,0x73,0x302,0xca02,0x53,0x327,0xca02,0x73,0x327,0xca02,0x54,0x327,
+0xca02,0x74,0x327,0xe602,0x54,0x30c,0xe602,0x74,0x30c,0xe602,0x55,0x306,0xe602,0x75,0x306,0xe602,
+0x55,0x30a,0xe602,0x75,0x30a,0xe602,0x55,0x30b,0xe602,0x75,0x30b,0xca02,0x55,0x328,0xca02,0x75,
+0x328,0xe602,0x57,0x302,0xe602,0x77,0x302,0xe602,0x59,0x302,0xe602,0x79,0x302,0xe602,0x59,0x308,
+0xe602,0x5a,0x301,0xe602,0x7a,0x301,0xe602,0x5a,0x307,0xe602,0x7a,0x307,0xe602,0x5a,0x30c,0xe602,
+0x7a,0x30c,0xe602,0x41,0x30c,0xe602,0x61,0x30c,0xe602,0x49,0x30c,0xe602,0x69,0x30c,0xe602,0x4f,
+0x30c,0xe602,0x6f,0x30c,0xe602,0x55,0x30c,0xe602,0x75,0x30c,0xdc,0xe643,0x55,0x308,0x304,0xfc,
+0xe643,0x75,0x308,0x304,0xdc,0xe643,0x55,0x308,0x301,0xfc,0xe643,0x75,0x308,0x301,0xdc,0xe643,
+0x55,0x308,0x30c,0xfc,0xe643,0x75,0x308,0x30c,0xdc,0xe643,0x55,0x308,0x300,0xfc,0xe643,0x75,
+0x308,0x300,0xc4,0xe643,0x41,0x308,0x304,0xe4,0xe643,0x61,0x308,0x304,0x226,0xe643,0x41,0x307,
+0x304,0x227,0xe643,0x61,0x307,0x304,0xe602,0xc6,0x304,0xe602,0xe6,0x304,0xe602,0x47,0x30c,0xe602,
+0x67,0x30c,0xe602,0x4b,0x30c,0xe602,0x6b,0x30c,0x1ea,0xe643,0x4f,0x328,0x304,0x1eb,0xe643,0x6f,
+0x328,0x304,0xe602,0x1b7,0x30c,0xe602,0x292,0x30c,0xe602,0x6a,0x30c,0xe602,0x47,0x301,0xe602,0x67,
+0x301,0xe602,0x4e,0x300,0xe602,0x6e,0x300,0xc5,0xe643,0x41,0x30a,0x301,0xe5,0xe643,0x61,0x30a,
+0x301,0xe602,0xc6,0x301,0xe602,0xe6,0x301,0xe602,0xd8,0x301,0xe602,0xf8,0x301,0xe602,0x41,0x30f,
+0xe602,0x61,0x30f,0xe602,0x41,0x311,0xe602,0x61,0x311,0xe602,0x45,0x30f,0xe602,0x65,0x30f,0xe602,
+0x45,0x311,0xe602,0x65,0x311,0xe602,0x49,0x30f,0xe602,0x69,0x30f,0xe602,0x49,0x311,0xe602,0x69,
+0x311,0xe602,0x4f,0x30f,0xe602,0x6f,0x30f,0xe602,0x4f,0x311,0xe602,0x6f,0x311,0xe602,0x52,0x30f,
+0xe602,0x72,0x30f,0xe602,0x52,0x311,0xe602,0x72,0x311,0xe602,0x55,0x30f,0xe602,0x75,0x30f,0xe602,
+0x55,0x311,0xe602,0x75,0x311,0xdc02,0x53,0x326,0xdc02,0x73,0x326,0xdc02,0x54,0x326,0xdc02,0x74,
+0x326,0xe602,0x48,0x30c,0xe602,0x68,0x30c,0xd6,0xe643,0x4f,0x308,0x304,0xf6,0xe643,0x6f,0x308,
+0x304,0xd5,0xe643,0x4f,0x303,0x304,0xf5,0xe643,0x6f,0x303,0x304,0x22e,0xe643,0x4f,0x307,0x304,
+0x22f,0xe643,0x6f,0x307,0x304,0xe602,0x59,0x304,0xe602,0x79,0x304,0xe602,0xa8,0x301,0xe602,0x391,
+0x301,0xe602,0x395,0x301,0xe602,0x397,0x301,0xe602,0x399,0x301,0xe602,0x39f,0x301,0xe602,0x3a5,0x301,
+0xe602,0x3a9,0x301,0x3ca,0xe643,0x3b9,0x308,0x301,0xe602,0x399,0x308,0xe602,0x3a5,0x308,0xe602,0x3b5,
+0x301,0xe602,0x3b9,0x301,0x3cb,0xe643,0x3c5,0x308,0x301,0xe602,0x3bf,0x301,0xe602,0x3c5,0x301,0xe602,
+0x3d2,0x301,0xe602,0x3d2,0x308,0xe602,0x415,0x300,0xe602,0x415,0x308,0xe602,0x413,0x301,0xe602,0x406,
+0x308,0xe602,0x41a,0x301,0xe602,0x418,0x300,0xe602,0x423,0x306,0xe602,0x418,0x306,0xe602,0x438,0x306,
+0xe602,0x435,0x300,0xe602,0x435,0x308,0xe602,0x433,0x301,0xe602,0x456,0x308,0xe602,0x43a,0x301,0xe602,
+0x438,0x300,0xe602,0x443,0x306,0xe602,0x474,0x30f,0xe602,0x475,0x30f,0xe602,0x416,0x306,0xe602,0x436,
+0x306,0xe602,0x410,0x306,0xe602,0x430,0x306,0xe602,0x410,0x308,0xe602,0x430,0x308,0xe602,0x415,0x306,
+0xe602,0x435,0x306,0xe602,0x4d8,0x308,0xe602,0x4d9,0x308,0xe602,0x416,0x308,0xe602,0x436,0x308,0xe602,
+0x417,0x308,0xe602,0x437,0x308,0xe602,0x418,0x304,0xe602,0x438,0x304,0xe602,0x418,0x308,0xe602,0x438,
+0x308,0xe602,0x41e,0x308,0xe602,0x43e,0x308,0xe602,0x4e8,0x308,0xe602,0x4e9,0x308,0xe602,0x42d,0x308,
+0xe602,0x44d,0x308,0xe602,0x423,0x304,0xe602,0x443,0x304,0xe602,0x423,0x308,0xe602,0x443,0x308,0xe602,
+0x423,0x30b,0xe602,0x443,0x30b,0xe602,0x427,0x308,0xe602,0x447,0x308,0xe602,0x42b,0x308,0xe602,0x44b,
+0x308,0xe602,0x627,0x653,0xe602,0x627,0x654,0xe602,0x648,0x654,0xdc02,0x627,0x655,0xe602,0x64a,0x654,
+0xe602,0x6d5,0x654,0xe602,0x6c1,0x654,0xe602,0x6d2,0x654,0x702,0x928,0x93c,0x702,0x930,0x93c,0x702,
+0x933,0x93c,2,0x9c7,0x9be,2,0x9c7,0x9d7,2,0xb47,0xb56,2,0xb47,0xb3e,2,0xb47,
+0xb57,2,0xb92,0xbd7,2,0xbc6,0xbbe,2,0xbc7,0xbbe,2,0xbc6,0xbd7,0x5b02,0xc46,0xc56,
+2,0xcbf,0xcd5,2,0xcc6,0xcd5,2,0xcc6,0xcd6,0xcca,0x43,0xcc6,0xcc2,0xcd5,2,0xd46,
+0xd3e,2,0xd47,0xd3e,2,0xd46,0xd57,0x902,0xdd9,0xdca,0xddc,0x943,0xdd9,0xdcf,0xdca,2,
+0xdd9,0xddf,2,0x1025,0x102e,2,0x1b05,0x1b35,2,0x1b07,0x1b35,2,0x1b09,0x1b35,2,0x1b0b,
+0x1b35,2,0x1b0d,0x1b35,2,0x1b11,0x1b35,2,0x1b3a,0x1b35,2,0x1b3c,0x1b35,2,0x1b3e,0x1b35,
+2,0x1b3f,0x1b35,2,0x1b42,0x1b35,0xdc02,0x41,0x325,0xdc02,0x61,0x325,0xe602,0x42,0x307,0xe602,
+0x62,0x307,0xdc02,0x42,0x323,0xdc02,0x62,0x323,0xdc02,0x42,0x331,0xdc02,0x62,0x331,0xc7,0xe643,
+0x43,0x327,0x301,0xe7,0xe643,0x63,0x327,0x301,0xe602,0x44,0x307,0xe602,0x64,0x307,0xdc02,0x44,
+0x323,0xdc02,0x64,0x323,0xdc02,0x44,0x331,0xdc02,0x64,0x331,0xca02,0x44,0x327,0xca02,0x64,0x327,
+0xdc02,0x44,0x32d,0xdc02,0x64,0x32d,0x112,0xe643,0x45,0x304,0x300,0x113,0xe643,0x65,0x304,0x300,
+0x112,0xe643,0x45,0x304,0x301,0x113,0xe643,0x65,0x304,0x301,0xdc02,0x45,0x32d,0xdc02,0x65,0x32d,
+0xdc02,0x45,0x330,0xdc02,0x65,0x330,0x228,0xe643,0x45,0x327,0x306,0x229,0xe643,0x65,0x327,0x306,
+0xe602,0x46,0x307,0xe602,0x66,0x307,0xe602,0x47,0x304,0xe602,0x67,0x304,0xe602,0x48,0x307,0xe602,
+0x68,0x307,0xdc02,0x48,0x323,0xdc02,0x68,0x323,0xe602,0x48,0x308,0xe602,0x68,0x308,0xca02,0x48,
+0x327,0xca02,0x68,0x327,0xdc02,0x48,0x32e,0xdc02,0x68,0x32e,0xdc02,0x49,0x330,0xdc02,0x69,0x330,
+0xcf,0xe643,0x49,0x308,0x301,0xef,0xe643,0x69,0x308,0x301,0xe602,0x4b,0x301,0xe602,0x6b,0x301,
+0xdc02,0x4b,0x323,0xdc02,0x6b,0x323,0xdc02,0x4b,0x331,0xdc02,0x6b,0x331,0x1e36,0xe643,0x4c,0x323,
+0x304,0x1e37,0xe643,0x6c,0x323,0x304,0xdc02,0x4c,0x331,0xdc02,0x6c,0x331,0xdc02,0x4c,0x32d,0xdc02,
+0x6c,0x32d,0xe602,0x4d,0x301,0xe602,0x6d,0x301,0xe602,0x4d,0x307,0xe602,0x6d,0x307,0xdc02,0x4d,
+0x323,0xdc02,0x6d,0x323,0xe602,0x4e,0x307,0xe602,0x6e,0x307,0xdc02,0x4e,0x323,0xdc02,0x6e,0x323,
+0xdc02,0x4e,0x331,0xdc02,0x6e,0x331,0xdc02,0x4e,0x32d,0xdc02,0x6e,0x32d,0xd5,0xe643,0x4f,0x303,
+0x301,0xf5,0xe643,0x6f,0x303,0x301,0xd5,0xe643,0x4f,0x303,0x308,0xf5,0xe643,0x6f,0x303,0x308,
+0x14c,0xe643,0x4f,0x304,0x300,0x14d,0xe643,0x6f,0x304,0x300,0x14c,0xe643,0x4f,0x304,0x301,0x14d,
+0xe643,0x6f,0x304,0x301,0xe602,0x50,0x301,0xe602,0x70,0x301,0xe602,0x50,0x307,0xe602,0x70,0x307,
+0xe602,0x52,0x307,0xe602,0x72,0x307,0x1e5a,0xe643,0x52,0x323,0x304,0x1e5b,0xe643,0x72,0x323,0x304,
+0xdc02,0x52,0x331,0xdc02,0x72,0x331,0xe602,0x53,0x307,0xe602,0x73,0x307,0x15a,0xe643,0x53,0x301,
+0x307,0x15b,0xe643,0x73,0x301,0x307,0x160,0xe643,0x53,0x30c,0x307,0x161,0xe643,0x73,0x30c,0x307,
+0x1e62,0xe643,0x53,0x323,0x307,0x1e63,0xe643,0x73,0x323,0x307,0xe602,0x54,0x307,0xe602,0x74,0x307,
+0xdc02,0x54,0x323,0xdc02,0x74,0x323,0xdc02,0x54,0x331,0xdc02,0x74,0x331,0xdc02,0x54,0x32d,0xdc02,
+0x74,0x32d,0xdc02,0x55,0x324,0xdc02,0x75,0x324,0xdc02,0x55,0x330,0xdc02,0x75,0x330,0xdc02,0x55,
+0x32d,0xdc02,0x75,0x32d,0x168,0xe643,0x55,0x303,0x301,0x169,0xe643,0x75,0x303,0x301,0x16a,0xe643,
+0x55,0x304,0x308,0x16b,0xe643,0x75,0x304,0x308,0xe602,0x56,0x303,0xe602,0x76,0x303,0xdc02,0x56,
+0x323,0xdc02,0x76,0x323,0xe602,0x57,0x300,0xe602,0x77,0x300,0xe602,0x57,0x301,0xe602,0x77,0x301,
+0xe602,0x57,0x308,0xe602,0x77,0x308,0xe602,0x57,0x307,0xe602,0x77,0x307,0xdc02,0x57,0x323,0xdc02,
+0x77,0x323,0xe602,0x58,0x307,0xe602,0x78,0x307,0xe602,0x58,0x308,0xe602,0x78,0x308,0xe602,0x59,
+0x307,0xe602,0x79,0x307,0xe602,0x5a,0x302,0xe602,0x7a,0x302,0xdc02,0x5a,0x323,0xdc02,0x7a,0x323,
+0xdc02,0x5a,0x331,0xdc02,0x7a,0x331,0xdc02,0x68,0x331,0xe602,0x74,0x308,0xe602,0x77,0x30a,0xe602,
+0x79,0x30a,0xe602,0x17f,0x307,0xe602,0x41,0x309,0xe602,0x61,0x309,0xc2,0xe643,0x41,0x302,0x301,
+0xe2,0xe643,0x61,0x302,0x301,0xc2,0xe643,0x41,0x302,0x300,0xe2,0xe643,0x61,0x302,0x300,0xc2,
+0xe643,0x41,0x302,0x309,0xe2,0xe643,0x61,0x302,0x309,0xc2,0xe643,0x41,0x302,0x303,0xe2,0xe643,
+0x61,0x302,0x303,0x1ea0,0xe643,0x41,0x323,0x302,0x1ea1,0xe643,0x61,0x323,0x302,0x102,0xe643,0x41,
+0x306,0x301,0x103,0xe643,0x61,0x306,0x301,0x102,0xe643,0x41,0x306,0x300,0x103,0xe643,0x61,0x306,
+0x300,0x102,0xe643,0x41,0x306,0x309,0x103,0xe643,0x61,0x306,0x309,0x102,0xe643,0x41,0x306,0x303,
+0x103,0xe643,0x61,0x306,0x303,0x1ea0,0xe643,0x41,0x323,0x306,0x1ea1,0xe643,0x61,0x323,0x306,0xe602,
+0x45,0x309,0xe602,0x65,0x309,0xe602,0x45,0x303,0xe602,0x65,0x303,0xca,0xe643,0x45,0x302,0x301,
+0xea,0xe643,0x65,0x302,0x301,0xca,0xe643,0x45,0x302,0x300,0xea,0xe643,0x65,0x302,0x300,0xca,
+0xe643,0x45,0x302,0x309,0xea,0xe643,0x65,0x302,0x309,0xca,0xe643,0x45,0x302,0x303,0xea,0xe643,
+0x65,0x302,0x303,0x1eb8,0xe643,0x45,0x323,0x302,0x1eb9,0xe643,0x65,0x323,0x302,0xe602,0x49,0x309,
+0xe602,0x69,0x309,0xdc02,0x49,0x323,0xdc02,0x69,0x323,0xe602,0x4f,0x309,0xe602,0x6f,0x309,0xd4,
+0xe643,0x4f,0x302,0x301,0xf4,0xe643,0x6f,0x302,0x301,0xd4,0xe643,0x4f,0x302,0x300,0xf4,0xe643,
+0x6f,0x302,0x300,0xd4,0xe643,0x4f,0x302,0x309,0xf4,0xe643,0x6f,0x302,0x309,0xd4,0xe643,0x4f,
+0x302,0x303,0xf4,0xe643,0x6f,0x302,0x303,0x1ecc,0xe643,0x4f,0x323,0x302,0x1ecd,0xe643,0x6f,0x323,
+0x302,0x1a0,0xe643,0x4f,0x31b,0x301,0x1a1,0xe643,0x6f,0x31b,0x301,0x1a0,0xe643,0x4f,0x31b,0x300,
+0x1a1,0xe643,0x6f,0x31b,0x300,0x1a0,0xe643,0x4f,0x31b,0x309,0x1a1,0xe643,0x6f,0x31b,0x309,0x1a0,
+0xe643,0x4f,0x31b,0x303,0x1a1,0xe643,0x6f,0x31b,0x303,0x1a0,0xdc43,0x4f,0x31b,0x323,0x1a1,0xdc43,
+0x6f,0x31b,0x323,0xdc02,0x55,0x323,0xdc02,0x75,0x323,0xe602,0x55,0x309,0xe602,0x75,0x309,0x1af,
+0xe643,0x55,0x31b,0x301,0x1b0,0xe643,0x75,0x31b,0x301,0x1af,0xe643,0x55,0x31b,0x300,0x1b0,0xe643,
+0x75,0x31b,0x300,0x1af,0xe643,0x55,0x31b,0x309,0x1b0,0xe643,0x75,0x31b,0x309,0x1af,0xe643,0x55,
+0x31b,0x303,0x1b0,0xe643,0x75,0x31b,0x303,0x1af,0xdc43,0x55,0x31b,0x323,0x1b0,0xdc43,0x75,0x31b,
+0x323,0xe602,0x59,0x300,0xe602,0x79,0x300,0xdc02,0x59,0x323,0xdc02,0x79,0x323,0xe602,0x59,0x309,
+0xe602,0x79,0x309,0xe602,0x59,0x303,0xe602,0x79,0x303,0x1f10,0xe643,0x3b5,0x313,0x300,0x1f11,0xe643,
+0x3b5,0x314,0x300,0x1f10,0xe643,0x3b5,0x313,0x301,0x1f11,0xe643,0x3b5,0x314,0x301,0x1f18,0xe643,0x395,
+0x313,0x300,0x1f19,0xe643,0x395,0x314,0x300,0x1f18,0xe643,0x395,0x313,0x301,0x1f19,0xe643,0x395,0x314,
+0x301,0x1f30,0xe643,0x3b9,0x313,0x300,0x1f31,0xe643,0x3b9,0x314,0x300,0x1f30,0xe643,0x3b9,0x313,0x301,
+0x1f31,0xe643,0x3b9,0x314,0x301,0x1f30,0xe643,0x3b9,0x313,0x342,0x1f31,0xe643,0x3b9,0x314,0x342,0x1f38,
+0xe643,0x399,0x313,0x300,0x1f39,0xe643,0x399,0x314,0x300,0x1f38,0xe643,0x399,0x313,0x301,0x1f39,0xe643,
+0x399,0x314,0x301,0x1f38,0xe643,0x399,0x313,0x342,0x1f39,0xe643,0x399,0x314,0x342,0x1f40,0xe643,0x3bf,
+0x313,0x300,0x1f41,0xe643,0x3bf,0x314,0x300,0x1f40,0xe643,0x3bf,0x313,0x301,0x1f41,0xe643,0x3bf,0x314,
+0x301,0x1f48,0xe643,0x39f,0x313,0x300,0x1f49,0xe643,0x39f,0x314,0x300,0x1f48,0xe643,0x39f,0x313,0x301,
+0x1f49,0xe643,0x39f,0x314,0x301,0x1f50,0xe643,0x3c5,0x313,0x300,0x1f51,0xe643,0x3c5,0x314,0x300,0x1f50,
+0xe643,0x3c5,0x313,0x301,0x1f51,0xe643,0x3c5,0x314,0x301,0x1f50,0xe643,0x3c5,0x313,0x342,0x1f51,0xe643,
+0x3c5,0x314,0x342,0x1f59,0xe643,0x3a5,0x314,0x300,0x1f59,0xe643,0x3a5,0x314,0x301,0x1f59,0xe643,0x3a5,
+0x314,0x342,0xe602,0x3b5,0x300,0xe602,0x3b9,0x300,0xe602,0x3bf,0x300,0xe602,0x3c5,0x300,0x1f00,0xf043,
+0x3b1,0x313,0x345,0x1f01,0xf043,0x3b1,0x314,0x345,0x1f02,0x345,2,0xf044,0x3b1,0x313,0x300,0x345,
+0x1f03,0x345,2,0xf044,0x3b1,0x314,0x300,0x345,0x1f04,0x345,2,0xf044,0x3b1,0x313,0x301,0x345,
+0x1f05,0x345,2,0xf044,0x3b1,0x314,0x301,0x345,0x1f06,0x345,2,0xf044,0x3b1,0x313,0x342,0x345,
+0x1f07,0x345,2,0xf044,0x3b1,0x314,0x342,0x345,0x1f08,0xf043,0x391,0x313,0x345,0x1f09,0xf043,0x391,
+0x314,0x345,0x1f0a,0x345,2,0xf044,0x391,0x313,0x300,0x345,0x1f0b,0x345,2,0xf044,0x391,0x314,
+0x300,0x345,0x1f0c,0x345,2,0xf044,0x391,0x313,0x301,0x345,0x1f0d,0x345,2,0xf044,0x391,0x314,
+0x301,0x345,0x1f0e,0x345,2,0xf044,0x391,0x313,0x342,0x345,0x1f0f,0x345,2,0xf044,0x391,0x314,
+0x342,0x345,0x1f20,0xf043,0x3b7,0x313,0x345,0x1f21,0xf043,0x3b7,0x314,0x345,0x1f22,0x345,2,0xf044,
+0x3b7,0x313,0x300,0x345,0x1f23,0x345,2,0xf044,0x3b7,0x314,0x300,0x345,0x1f24,0x345,2,0xf044,
+0x3b7,0x313,0x301,0x345,0x1f25,0x345,2,0xf044,0x3b7,0x314,0x301,0x345,0x1f26,0x345,2,0xf044,
+0x3b7,0x313,0x342,0x345,0x1f27,0x345,2,0xf044,0x3b7,0x314,0x342,0x345,0x1f28,0xf043,0x397,0x313,
+0x345,0x1f29,0xf043,0x397,0x314,0x345,0x1f2a,0x345,2,0xf044,0x397,0x313,0x300,0x345,0x1f2b,0x345,
+2,0xf044,0x397,0x314,0x300,0x345,0x1f2c,0x345,2,0xf044,0x397,0x313,0x301,0x345,0x1f2d,0x345,
+2,0xf044,0x397,0x314,0x301,0x345,0x1f2e,0x345,2,0xf044,0x397,0x313,0x342,0x345,0x1f2f,0x345,
+2,0xf044,0x397,0x314,0x342,0x345,0x1f60,0xf043,0x3c9,0x313,0x345,0x1f61,0xf043,0x3c9,0x314,0x345,
+0x1f62,0x345,2,0xf044,0x3c9,0x313,0x300,0x345,0x1f63,0x345,2,0xf044,0x3c9,0x314,0x300,0x345,
+0x1f64,0x345,2,0xf044,0x3c9,0x313,0x301,0x345,0x1f65,0x345,2,0xf044,0x3c9,0x314,0x301,0x345,
+0x1f66,0x345,2,0xf044,0x3c9,0x313,0x342,0x345,0x1f67,0x345,2,0xf044,0x3c9,0x314,0x342,0x345,
+0x1f68,0xf043,0x3a9,0x313,0x345,0x1f69,0xf043,0x3a9,0x314,0x345,0x1f6a,0x345,2,0xf044,0x3a9,0x313,
+0x300,0x345,0x1f6b,0x345,2,0xf044,0x3a9,0x314,0x300,0x345,0x1f6c,0x345,2,0xf044,0x3a9,0x313,
+0x301,0x345,0x1f6d,0x345,2,0xf044,0x3a9,0x314,0x301,0x345,0x1f6e,0x345,2,0xf044,0x3a9,0x313,
+0x342,0x345,0x1f6f,0x345,2,0xf044,0x3a9,0x314,0x342,0x345,0xe602,0x3b1,0x306,0xe602,0x3b1,0x304,
+0x1f70,0xf043,0x3b1,0x300,0x345,0xf002,0x3b1,0x345,0x3ac,0xf043,0x3b1,0x301,0x345,0x1fb6,0xf043,0x3b1,
+0x342,0x345,0xe602,0x391,0x306,0xe602,0x391,0x304,0xe602,0x391,0x300,0xf002,0x391,0x345,0xe602,0xa8,
+0x342,0x1f74,0xf043,0x3b7,0x300,0x345,0xf002,0x3b7,0x345,0x3ae,0xf043,0x3b7,0x301,0x345,0x1fc6,0xf043,
+0x3b7,0x342,0x345,0xe602,0x395,0x300,0xe602,0x397,0x300,0xf002,0x397,0x345,0xe602,0x1fbf,0x300,0xe602,
+0x1fbf,0x301,0xe602,0x1fbf,0x342,0xe602,0x3b9,0x306,0xe602,0x3b9,0x304,0x3ca,0xe643,0x3b9,0x308,0x300,
+0xe602,0x3b9,0x342,0x3ca,0xe643,0x3b9,0x308,0x342,0xe602,0x399,0x306,0xe602,0x399,0x304,0xe602,0x399,
+0x300,0xe602,0x1ffe,0x300,0xe602,0x1ffe,0x301,0xe602,0x1ffe,0x342,0xe602,0x3c5,0x306,0xe602,0x3c5,0x304,
+0x3cb,0xe643,0x3c5,0x308,0x300,0xe602,0x3c1,0x313,0xe602,0x3c1,0x314,0xe602,0x3c5,0x342,0x3cb,0xe643,
+0x3c5,0x308,0x342,0xe602,0x3a5,0x306,0xe602,0x3a5,0x304,0xe602,0x3a5,0x300,0xe602,0x3a1,0x314,0xe602,
+0xa8,0x300,0x1f7c,0xf043,0x3c9,0x300,0x345,0xf002,0x3c9,0x345,0x3ce,0xf043,0x3c9,0x301,0x345,0x1ff6,
+0xf043,0x3c9,0x342,0x345,0xe602,0x39f,0x300,0xe602,0x3a9,0x300,0xf002,0x3a9,0x345,0x102,0x2190,0x338,
+0x102,0x2192,0x338,0x102,0x2194,0x338,0x102,0x21d0,0x338,0x102,0x21d4,0x338,0x102,0x21d2,0x338,0x102,
+0x2203,0x338,0x102,0x2208,0x338,0x102,0x220b,0x338,0x102,0x2223,0x338,0x102,0x2225,0x338,0x102,0x223c,
+0x338,0x102,0x2243,0x338,0x102,0x2245,0x338,0x102,0x2248,0x338,0x102,0x3d,0x338,0x102,0x2261,0x338,
+0x102,0x224d,0x338,0x102,0x3c,0x338,0x102,0x3e,0x338,0x102,0x2264,0x338,0x102,0x2265,0x338,0x102,
+0x2272,0x338,0x102,0x2273,0x338,0x102,0x2276,0x338,0x102,0x2277,0x338,0x102,0x227a,0x338,0x102,0x227b,
+0x338,0x102,0x2282,0x338,0x102,0x2283,0x338,0x102,0x2286,0x338,0x102,0x2287,0x338,0x102,0x22a2,0x338,
+0x102,0x22a8,0x338,0x102,0x22a9,0x338,0x102,0x22ab,0x338,0x102,0x227c,0x338,0x102,0x227d,0x338,0x102,
+0x2291,0x338,0x102,0x2292,0x338,0x102,0x22b2,0x338,0x102,0x22b3,0x338,0x102,0x22b4,0x338,0x102,0x22b5,
+0x338,0x802,0x304b,0x3099,0x802,0x304d,0x3099,0x802,0x304f,0x3099,0x802,0x3051,0x3099,0x802,0x3053,0x3099,
+0x802,0x3055,0x3099,0x802,0x3057,0x3099,0x802,0x3059,0x3099,0x802,0x305b,0x3099,0x802,0x305d,0x3099,0x802,
+0x305f,0x3099,0x802,0x3061,0x3099,0x802,0x3064,0x3099,0x802,0x3066,0x3099,0x802,0x3068,0x3099,0x802,0x306f,
+0x3099,0x802,0x306f,0x309a,0x802,0x3072,0x3099,0x802,0x3072,0x309a,0x802,0x3075,0x3099,0x802,0x3075,0x309a,
+0x802,0x3078,0x3099,0x802,0x3078,0x309a,0x802,0x307b,0x3099,0x802,0x307b,0x309a,0x802,0x3046,0x3099,0x802,
+0x309d,0x3099,0x802,0x30ab,0x3099,0x802,0x30ad,0x3099,0x802,0x30af,0x3099,0x802,0x30b1,0x3099,0x802,0x30b3,
+0x3099,0x802,0x30b5,0x3099,0x802,0x30b7,0x3099,0x802,0x30b9,0x3099,0x802,0x30bb,0x3099,0x802,0x30bd,0x3099,
+0x802,0x30bf,0x3099,0x802,0x30c1,0x3099,0x802,0x30c4,0x3099,0x802,0x30c6,0x3099,0x802,0x30c8,0x3099,0x802,
+0x30cf,0x3099,0x802,0x30cf,0x309a,0x802,0x30d2,0x3099,0x802,0x30d2,0x309a,0x802,0x30d5,0x3099,0x802,0x30d5,
+0x309a,0x802,0x30d8,0x3099,0x802,0x30d8,0x309a,0x802,0x30db,0x3099,0x802,0x30db,0x309a,0x802,0x30a6,0x3099,
+0x802,0x30ef,0x3099,0x802,0x30f0,0x3099,0x802,0x30f1,0x3099,0x802,0x30f2,0x3099,0x802,0x30fd,0x3099,0x704,
+0xd804,0xdc99,0xd804,0xdcba,0x704,0xd804,0xdc9b,0xd804,0xdcba,0x704,0xd804,0xdca5,0xd804,0xdcba,4,0xd804,
+0xdd31,0xd804,0xdd27,4,0xd804,0xdd32,0xd804,0xdd27,4,0xd804,0xdf47,0xd804,0xdf3e,4,0xd804,0xdf47,
+0xd804,0xdf57,4,0xd805,0xdcb9,0xd805,0xdcba,4,0xd805,0xdcb9,0xd805,0xdcb0,4,0xd805,0xdcb9,0xd805,
+0xdcbd,4,0xd805,0xddb8,0xd805,0xddaf,4,0xd805,0xddb9,0xd805,0xddaf,4,0xd806,0xdd35,0xd806,0xdd30,
+1,0x2b9,1,0x3b,1,0xb7,0x702,0x915,0x93c,0x702,0x916,0x93c,0x702,0x917,0x93c,0x702,
+0x91c,0x93c,0x702,0x921,0x93c,0x702,0x922,0x93c,0x702,0x92b,0x93c,0x702,0x92f,0x93c,0x702,0x9a1,
+0x9bc,0x702,0x9a2,0x9bc,0x702,0x9af,0x9bc,0x702,0xa32,0xa3c,0x702,0xa38,0xa3c,0x702,0xa16,0xa3c,
+0x702,0xa17,0xa3c,0x702,0xa1c,0xa3c,0x702,0xa2b,0xa3c,0x702,0xb21,0xb3c,0x702,0xb22,0xb3c,2,
+0xf42,0xfb7,2,0xf4c,0xfb7,2,0xf51,0xfb7,2,0xf56,0xfb7,2,0xf5b,0xfb7,2,0xf40,
+0xfb5,0x8202,0xfb2,0xf80,0x8202,0xfb3,0xf80,2,0xf92,0xfb7,2,0xf9c,0xfb7,2,0xfa1,0xfb7,
+2,0xfa6,0xfb7,2,0xfab,0xfb7,2,0xf90,0xfb5,1,0x3b9,1,0x60,1,0xb4,1,
+0x3a9,1,0x4b,1,0x3008,1,0x3009,0x102,0x2add,0x338,1,0x8c48,1,0x66f4,1,0x8eca,
+1,0x8cc8,1,0x6ed1,1,0x4e32,1,0x53e5,1,0x9f9c,1,0x5951,1,0x91d1,1,0x5587,
+1,0x5948,1,0x61f6,1,0x7669,1,0x7f85,1,0x863f,1,0x87ba,1,0x88f8,1,0x908f,
+1,0x6a02,1,0x6d1b,1,0x70d9,1,0x73de,1,0x843d,1,0x916a,1,0x99f1,1,0x4e82,
+1,0x5375,1,0x6b04,1,0x721b,1,0x862d,1,0x9e1e,1,0x5d50,1,0x6feb,1,0x85cd,
+1,0x8964,1,0x62c9,1,0x81d8,1,0x881f,1,0x5eca,1,0x6717,1,0x6d6a,1,0x72fc,
+1,0x90ce,1,0x4f86,1,0x51b7,1,0x52de,1,0x64c4,1,0x6ad3,1,0x7210,1,0x76e7,
+1,0x8001,1,0x8606,1,0x865c,1,0x8def,1,0x9732,1,0x9b6f,1,0x9dfa,1,0x788c,
+1,0x797f,1,0x7da0,1,0x83c9,1,0x9304,1,0x9e7f,1,0x8ad6,1,0x58df,1,0x5f04,
+1,0x7c60,1,0x807e,1,0x7262,1,0x78ca,1,0x8cc2,1,0x96f7,1,0x58d8,1,0x5c62,
+1,0x6a13,1,0x6dda,1,0x6f0f,1,0x7d2f,1,0x7e37,1,0x964b,1,0x52d2,1,0x808b,
+1,0x51dc,1,0x51cc,1,0x7a1c,1,0x7dbe,1,0x83f1,1,0x9675,1,0x8b80,1,0x62cf,
+1,0x8afe,1,0x4e39,1,0x5be7,1,0x6012,1,0x7387,1,0x7570,1,0x5317,1,0x78fb,
+1,0x4fbf,1,0x5fa9,1,0x4e0d,1,0x6ccc,1,0x6578,1,0x7d22,1,0x53c3,1,0x585e,
+1,0x7701,1,0x8449,1,0x8aaa,1,0x6bba,1,0x8fb0,1,0x6c88,1,0x62fe,1,0x82e5,
+1,0x63a0,1,0x7565,1,0x4eae,1,0x5169,1,0x51c9,1,0x6881,1,0x7ce7,1,0x826f,
+1,0x8ad2,1,0x91cf,1,0x52f5,1,0x5442,1,0x5973,1,0x5eec,1,0x65c5,1,0x6ffe,
+1,0x792a,1,0x95ad,1,0x9a6a,1,0x9e97,1,0x9ece,1,0x529b,1,0x66c6,1,0x6b77,
+1,0x8f62,1,0x5e74,1,0x6190,1,0x6200,1,0x649a,1,0x6f23,1,0x7149,1,0x7489,
+1,0x79ca,1,0x7df4,1,0x806f,1,0x8f26,1,0x84ee,1,0x9023,1,0x934a,1,0x5217,
+1,0x52a3,1,0x54bd,1,0x70c8,1,0x88c2,1,0x5ec9,1,0x5ff5,1,0x637b,1,0x6bae,
+1,0x7c3e,1,0x7375,1,0x4ee4,1,0x56f9,1,0x5dba,1,0x601c,1,0x73b2,1,0x7469,
+1,0x7f9a,1,0x8046,1,0x9234,1,0x96f6,1,0x9748,1,0x9818,1,0x4f8b,1,0x79ae,
+1,0x91b4,1,0x96b8,1,0x60e1,1,0x4e86,1,0x50da,1,0x5bee,1,0x5c3f,1,0x6599,
+1,0x71ce,1,0x7642,1,0x84fc,1,0x907c,1,0x9f8d,1,0x6688,1,0x962e,1,0x5289,
+1,0x677b,1,0x67f3,1,0x6d41,1,0x6e9c,1,0x7409,1,0x7559,1,0x786b,1,0x7d10,
+1,0x985e,1,0x516d,1,0x622e,1,0x9678,1,0x502b,1,0x5d19,1,0x6dea,1,0x8f2a,
+1,0x5f8b,1,0x6144,1,0x6817,1,0x9686,1,0x5229,1,0x540f,1,0x5c65,1,0x6613,
+1,0x674e,1,0x68a8,1,0x6ce5,1,0x7406,1,0x75e2,1,0x7f79,1,0x88cf,1,0x88e1,
+1,0x91cc,1,0x96e2,1,0x533f,1,0x6eba,1,0x541d,1,0x71d0,1,0x7498,1,0x85fa,
+1,0x96a3,1,0x9c57,1,0x9e9f,1,0x6797,1,0x6dcb,1,0x81e8,1,0x7acb,1,0x7b20,
+1,0x7c92,1,0x72c0,1,0x7099,1,0x8b58,1,0x4ec0,1,0x8336,1,0x523a,1,0x5207,
+1,0x5ea6,1,0x62d3,1,0x7cd6,1,0x5b85,1,0x6d1e,1,0x66b4,1,0x8f3b,1,0x884c,
+1,0x964d,1,0x898b,1,0x5ed3,1,0x5140,1,0x55c0,1,0x585a,1,0x6674,1,0x51de,
+1,0x732a,1,0x76ca,1,0x793c,1,0x795e,1,0x7965,1,0x798f,1,0x9756,1,0x7cbe,
+1,0x7fbd,1,0x8612,1,0x8af8,1,0x9038,1,0x90fd,1,0x98ef,1,0x98fc,1,0x9928,
+1,0x9db4,1,0x90de,1,0x96b7,1,0x4fae,1,0x50e7,1,0x514d,1,0x52c9,1,0x52e4,
+1,0x5351,1,0x559d,1,0x5606,1,0x5668,1,0x5840,1,0x58a8,1,0x5c64,1,0x5c6e,
+1,0x6094,1,0x6168,1,0x618e,1,0x61f2,1,0x654f,1,0x65e2,1,0x6691,1,0x6885,
+1,0x6d77,1,0x6e1a,1,0x6f22,1,0x716e,1,0x722b,1,0x7422,1,0x7891,1,0x793e,
+1,0x7949,1,0x7948,1,0x7950,1,0x7956,1,0x795d,1,0x798d,1,0x798e,1,0x7a40,
+1,0x7a81,1,0x7bc0,1,0x7e09,1,0x7e41,1,0x7f72,1,0x8005,1,0x81ed,1,0x8279,
+1,0x8457,1,0x8910,1,0x8996,1,0x8b01,1,0x8b39,1,0x8cd3,1,0x8d08,1,0x8fb6,
+1,0x96e3,1,0x97ff,1,0x983b,1,0x6075,2,0xd850,0xdeee,1,0x8218,1,0x4e26,1,
+0x51b5,1,0x5168,1,0x4f80,1,0x5145,1,0x5180,1,0x52c7,1,0x52fa,1,0x5555,1,
+0x5599,1,0x55e2,1,0x58b3,1,0x5944,1,0x5954,1,0x5a62,1,0x5b28,1,0x5ed2,1,
+0x5ed9,1,0x5f69,1,0x5fad,1,0x60d8,1,0x614e,1,0x6108,1,0x6160,1,0x6234,1,
+0x63c4,1,0x641c,1,0x6452,1,0x6556,1,0x671b,1,0x6756,1,0x6b79,1,0x6edb,1,
+0x6ecb,1,0x701e,1,0x77a7,1,0x7235,1,0x72af,1,0x7471,1,0x7506,1,0x753b,1,
+0x761d,1,0x761f,1,0x76db,1,0x76f4,1,0x774a,1,0x7740,1,0x78cc,1,0x7ab1,1,
+0x7c7b,1,0x7d5b,1,0x7f3e,1,0x8352,1,0x83ef,1,0x8779,1,0x8941,1,0x8986,1,
+0x8abf,1,0x8acb,1,0x8aed,1,0x8b8a,1,0x8f38,1,0x9072,1,0x9199,1,0x9276,1,
+0x967c,1,0x97db,1,0x980b,1,0x9b12,2,0xd84a,0xdc4a,2,0xd84a,0xdc44,2,0xd84c,0xdfd5,
+1,0x3b9d,1,0x4018,1,0x4039,2,0xd854,0xde49,2,0xd857,0xdcd0,2,0xd85f,0xded3,1,
+0x9f43,1,0x9f8e,0xe02,0x5d9,0x5b4,0x1102,0x5f2,0x5b7,0x1802,0x5e9,0x5c1,0x1902,0x5e9,0x5c2,0xfb49,
+0x1843,0x5e9,0x5bc,0x5c1,0xfb49,0x1943,0x5e9,0x5bc,0x5c2,0x1102,0x5d0,0x5b7,0x1202,0x5d0,0x5b8,0x1502,
+0x5d0,0x5bc,0x1502,0x5d1,0x5bc,0x1502,0x5d2,0x5bc,0x1502,0x5d3,0x5bc,0x1502,0x5d4,0x5bc,0x1502,0x5d5,
+0x5bc,0x1502,0x5d6,0x5bc,0x1502,0x5d8,0x5bc,0x1502,0x5d9,0x5bc,0x1502,0x5da,0x5bc,0x1502,0x5db,0x5bc,
+0x1502,0x5dc,0x5bc,0x1502,0x5de,0x5bc,0x1502,0x5e0,0x5bc,0x1502,0x5e1,0x5bc,0x1502,0x5e3,0x5bc,0x1502,
+0x5e4,0x5bc,0x1502,0x5e6,0x5bc,0x1502,0x5e7,0x5bc,0x1502,0x5e8,0x5bc,0x1502,0x5e9,0x5bc,0x1502,0x5ea,
+0x5bc,0x1302,0x5d5,0x5b9,0x1702,0x5d1,0x5bf,0x1702,0x5db,0x5bf,0x1702,0x5e4,0x5bf,0xd804,0xd834,0xdd57,
+0xd834,0xdd65,0xd804,0xd834,0xdd58,0xd834,0xdd65,0xd834,0xdd5f,0xd834,0xdd6e,4,0xd846,0xd834,0xdd58,0xd834,
+0xdd65,0xd834,0xdd6e,0xd834,0xdd5f,0xd834,0xdd6f,4,0xd846,0xd834,0xdd58,0xd834,0xdd65,0xd834,0xdd6f,0xd834,
+0xdd5f,0xd834,0xdd70,4,0xd846,0xd834,0xdd58,0xd834,0xdd65,0xd834,0xdd70,0xd834,0xdd5f,0xd834,0xdd71,4,
+0xd846,0xd834,0xdd58,0xd834,0xdd65,0xd834,0xdd71,0xd834,0xdd5f,0xd834,0xdd72,4,0xd846,0xd834,0xdd58,0xd834,
+0xdd65,0xd834,0xdd72,0xd804,0xd834,0xddb9,0xd834,0xdd65,0xd804,0xd834,0xddba,0xd834,0xdd65,0xd834,0xddbb,0xd834,
+0xdd6e,4,0xd846,0xd834,0xddb9,0xd834,0xdd65,0xd834,0xdd6e,0xd834,0xddbc,0xd834,0xdd6e,4,0xd846,0xd834,
+0xddba,0xd834,0xdd65,0xd834,0xdd6e,0xd834,0xddbb,0xd834,0xdd6f,4,0xd846,0xd834,0xddb9,0xd834,0xdd65,0xd834,
+0xdd6f,0xd834,0xddbc,0xd834,0xdd6f,4,0xd846,0xd834,0xddba,0xd834,0xdd65,0xd834,0xdd6f,1,0x4e3d,1,
+0x4e38,1,0x4e41,2,0xd840,0xdd22,1,0x4f60,1,0x4fbb,1,0x5002,1,0x507a,1,0x5099,
+1,0x50cf,1,0x349e,2,0xd841,0xde3a,1,0x5154,1,0x5164,1,0x5177,2,0xd841,0xdd1c,
+1,0x34b9,1,0x5167,1,0x518d,2,0xd841,0xdd4b,1,0x5197,1,0x51a4,1,0x4ecc,1,
+0x51ac,2,0xd864,0xdddf,1,0x51f5,1,0x5203,1,0x34df,1,0x523b,1,0x5246,1,0x5272,
+1,0x5277,1,0x3515,1,0x5305,1,0x5306,1,0x5349,1,0x535a,1,0x5373,1,0x537d,
+1,0x537f,2,0xd842,0xde2c,1,0x7070,1,0x53ca,1,0x53df,2,0xd842,0xdf63,1,0x53eb,
+1,0x53f1,1,0x5406,1,0x549e,1,0x5438,1,0x5448,1,0x5468,1,0x54a2,1,0x54f6,
+1,0x5510,1,0x5553,1,0x5563,1,0x5584,1,0x55ab,1,0x55b3,1,0x55c2,1,0x5716,
+1,0x5717,1,0x5651,1,0x5674,1,0x58ee,1,0x57ce,1,0x57f4,1,0x580d,1,0x578b,
+1,0x5832,1,0x5831,1,0x58ac,2,0xd845,0xdce4,1,0x58f2,1,0x58f7,1,0x5906,1,
+0x591a,1,0x5922,1,0x5962,2,0xd845,0xdea8,2,0xd845,0xdeea,1,0x59ec,1,0x5a1b,1,
+0x5a27,1,0x59d8,1,0x5a66,1,0x36ee,1,0x36fc,1,0x5b08,1,0x5b3e,2,0xd846,0xddc8,
+1,0x5bc3,1,0x5bd8,1,0x5bf3,2,0xd846,0xdf18,1,0x5bff,1,0x5c06,1,0x5f53,1,
+0x5c22,1,0x3781,1,0x5c60,1,0x5cc0,1,0x5c8d,2,0xd847,0xdde4,1,0x5d43,2,0xd847,
+0xdde6,1,0x5d6e,1,0x5d6b,1,0x5d7c,1,0x5de1,1,0x5de2,1,0x382f,1,0x5dfd,1,
+0x5e28,1,0x5e3d,1,0x5e69,1,0x3862,2,0xd848,0xdd83,1,0x387c,1,0x5eb0,1,0x5eb3,
+1,0x5eb6,2,0xd868,0xdf92,1,0x5efe,2,0xd848,0xdf31,1,0x8201,1,0x5f22,1,0x38c7,
+2,0xd84c,0xdeb8,2,0xd858,0xddda,1,0x5f62,1,0x5f6b,1,0x38e3,1,0x5f9a,1,0x5fcd,
+1,0x5fd7,1,0x5ff9,1,0x6081,1,0x393a,1,0x391c,2,0xd849,0xded4,1,0x60c7,1,
+0x6148,1,0x614c,1,0x617a,1,0x61b2,1,0x61a4,1,0x61af,1,0x61de,1,0x6210,1,
+0x621b,1,0x625d,1,0x62b1,1,0x62d4,1,0x6350,2,0xd84a,0xdf0c,1,0x633d,1,0x62fc,
+1,0x6368,1,0x6383,1,0x63e4,2,0xd84a,0xdff1,1,0x6422,1,0x63c5,1,0x63a9,1,
+0x3a2e,1,0x6469,1,0x647e,1,0x649d,1,0x6477,1,0x3a6c,1,0x656c,2,0xd84c,0xdc0a,
+1,0x65e3,1,0x66f8,1,0x6649,1,0x3b19,1,0x3b08,1,0x3ae4,1,0x5192,1,0x5195,
+1,0x6700,1,0x669c,1,0x80ad,1,0x43d9,1,0x6721,1,0x675e,1,0x6753,2,0xd84c,
+0xdfc3,1,0x3b49,1,0x67fa,1,0x6785,1,0x6852,2,0xd84d,0xdc6d,1,0x688e,1,0x681f,
+1,0x6914,1,0x6942,1,0x69a3,1,0x69ea,1,0x6aa8,2,0xd84d,0xdea3,1,0x6adb,1,
+0x3c18,1,0x6b21,2,0xd84e,0xdca7,1,0x6b54,1,0x3c4e,1,0x6b72,1,0x6b9f,1,0x6bbb,
+2,0xd84e,0xde8d,2,0xd847,0xdd0b,2,0xd84e,0xdefa,1,0x6c4e,2,0xd84f,0xdcbc,1,0x6cbf,
+1,0x6ccd,1,0x6c67,1,0x6d16,1,0x6d3e,1,0x6d69,1,0x6d78,1,0x6d85,2,0xd84f,
+0xdd1e,1,0x6d34,1,0x6e2f,1,0x6e6e,1,0x3d33,1,0x6ec7,2,0xd84f,0xded1,1,0x6df9,
+1,0x6f6e,2,0xd84f,0xdf5e,2,0xd84f,0xdf8e,1,0x6fc6,1,0x7039,1,0x701b,1,0x3d96,
+1,0x704a,1,0x707d,1,0x7077,1,0x70ad,2,0xd841,0xdd25,1,0x7145,2,0xd850,0xde63,
+1,0x719c,2,0xd850,0xdfab,1,0x7228,1,0x7250,2,0xd851,0xde08,1,0x7280,1,0x7295,
+2,0xd851,0xdf35,2,0xd852,0xdc14,1,0x737a,1,0x738b,1,0x3eac,1,0x73a5,1,0x3eb8,
+1,0x7447,1,0x745c,1,0x7485,1,0x74ca,1,0x3f1b,1,0x7524,2,0xd853,0xdc36,1,
+0x753e,2,0xd853,0xdc92,2,0xd848,0xdd9f,1,0x7610,2,0xd853,0xdfa1,2,0xd853,0xdfb8,2,
+0xd854,0xdc44,1,0x3ffc,1,0x4008,2,0xd854,0xdcf3,2,0xd854,0xdcf2,2,0xd854,0xdd19,2,
+0xd854,0xdd33,1,0x771e,1,0x771f,1,0x778b,1,0x4046,1,0x4096,2,0xd855,0xdc1d,1,
+0x784e,1,0x40e3,2,0xd855,0xde26,2,0xd855,0xde9a,2,0xd855,0xdec5,1,0x79eb,1,0x412f,
+1,0x7a4a,1,0x7a4f,2,0xd856,0xdd7c,2,0xd856,0xdea7,1,0x7aee,1,0x4202,2,0xd856,
+0xdfab,1,0x7bc6,1,0x7bc9,1,0x4227,2,0xd857,0xdc80,1,0x7cd2,1,0x42a0,1,0x7ce8,
+1,0x7ce3,1,0x7d00,2,0xd857,0xdf86,1,0x7d63,1,0x4301,1,0x7dc7,1,0x7e02,1,
+0x7e45,1,0x4334,2,0xd858,0xde28,2,0xd858,0xde47,1,0x4359,2,0xd858,0xded9,1,0x7f7a,
+2,0xd858,0xdf3e,1,0x7f95,1,0x7ffa,2,0xd859,0xdcda,2,0xd859,0xdd23,1,0x8060,2,
+0xd859,0xdda8,1,0x8070,2,0xd84c,0xdf5f,1,0x43d5,1,0x80b2,1,0x8103,1,0x440b,1,
+0x813e,1,0x5ab5,2,0xd859,0xdfa7,2,0xd859,0xdfb5,2,0xd84c,0xdf93,2,0xd84c,0xdf9c,1,
+0x8204,1,0x8f9e,1,0x446b,1,0x8291,1,0x828b,1,0x829d,1,0x52b3,1,0x82b1,1,
+0x82b3,1,0x82bd,1,0x82e6,2,0xd85a,0xdf3c,1,0x831d,1,0x8363,1,0x83ad,1,0x8323,
+1,0x83bd,1,0x83e7,1,0x8353,1,0x83ca,1,0x83cc,1,0x83dc,2,0xd85b,0xdc36,2,
+0xd85b,0xdd6b,2,0xd85b,0xdcd5,1,0x452b,1,0x84f1,1,0x84f3,1,0x8516,2,0xd85c,0xdfca,
+1,0x8564,2,0xd85b,0xdf2c,1,0x455d,1,0x4561,2,0xd85b,0xdfb1,2,0xd85c,0xdcd2,1,
+0x456b,1,0x8650,1,0x8667,1,0x8669,1,0x86a9,1,0x8688,1,0x870e,1,0x86e2,1,
+0x8728,1,0x876b,1,0x8786,1,0x45d7,1,0x87e1,1,0x8801,1,0x45f9,1,0x8860,1,
+0x8863,2,0xd85d,0xde67,1,0x88d7,1,0x88de,1,0x4635,1,0x88fa,1,0x34bb,2,0xd85e,
+0xdcae,2,0xd85e,0xdd66,1,0x46be,1,0x46c7,1,0x8aa0,1,0x8c55,2,0xd85f,0xdca8,1,
+0x8cab,1,0x8cc1,1,0x8d1b,1,0x8d77,2,0xd85f,0xdf2f,2,0xd842,0xdc04,1,0x8dcb,1,
+0x8dbc,1,0x8df0,2,0xd842,0xdcde,1,0x8ed4,2,0xd861,0xddd2,2,0xd861,0xdded,1,0x9094,
+1,0x90f1,1,0x9111,2,0xd861,0xdf2e,1,0x911b,1,0x9238,1,0x92d7,1,0x92d8,1,
+0x927c,1,0x93f9,1,0x9415,2,0xd862,0xdffa,1,0x958b,1,0x4995,1,0x95b7,2,0xd863,
+0xdd77,1,0x49e6,1,0x96c3,1,0x5db2,1,0x9723,2,0xd864,0xdd45,2,0xd864,0xde1a,1,
+0x4a6e,1,0x4a76,1,0x97e0,2,0xd865,0xdc0a,1,0x4ab2,2,0xd865,0xdc96,1,0x9829,2,
+0xd865,0xddb6,1,0x98e2,1,0x4b33,1,0x9929,1,0x99a7,1,0x99c2,1,0x99fe,1,0x4bce,
+2,0xd866,0xdf30,1,0x9c40,1,0x9cfd,1,0x4cce,1,0x4ced,1,0x9d67,2,0xd868,0xdcce,
+1,0x4cf8,2,0xd868,0xdd05,2,0xd868,0xde0e,2,0xd868,0xde91,1,0x9ebb,1,0x4d56,1,
+0x9ef9,1,0x9efe,1,0x9f05,1,0x9f0f,1,0x9f16,1,0x9f3b,2,0xd869,0xde00,0x3ac,0xe642,
+0x3b1,0x301,0x3ad,0xe642,0x3b5,0x301,0x3ae,0xe642,0x3b7,0x301,0x3af,0xe642,0x3b9,0x301,0x3cc,0xe642,
+0x3bf,0x301,0x3cd,0xe642,0x3c5,0x301,0x3ce,0xe642,0x3c9,0x301,0x386,0xe642,0x391,0x301,0x388,0xe642,
+0x395,0x301,0x389,0xe642,0x397,0x301,0x390,1,0xe643,0x3b9,0x308,0x301,0x38a,0xe642,0x399,0x301,
+0x3b0,1,0xe643,0x3c5,0x308,0x301,0x38e,0xe642,0x3a5,0x301,0x385,0xe642,0xa8,0x301,0x38c,0xe642,
+0x39f,0x301,0x38f,0xe642,0x3a9,0x301,0xc5,0xe642,0x41,0x30a,0xe6e6,0xe681,0x300,0xe6e6,0xe681,0x301,
+0xe6e6,0xe681,0x313,0xe6e6,0xe682,0x308,0x301,0x8100,0x8282,0xf71,0xf72,0x8100,0x8482,0xf71,0xf74,0x8100,
+0x8282,0xf71,0xf80,0
 };
 
 static const uint8_t norm2_nfc_data_smallFCD[256]={
-0xc0,0xef,3,0x7f,0xdf,0x70,0xcf,0x87,0x87,0x66,0x66,0x46,0x64,0x44,0x66,0x5b,
-0x12,0,0,4,0,0,0,0x43,0x20,2,0x29,0xae,0xc2,0xc0,0xff,0xff,
+0xc0,0xef,3,0x7f,0xdf,0x70,0xcf,0x87,0xc7,0xe6,0x66,0x46,0x64,0x46,0x66,0x5b,
+0x12,0,0,4,0,0,0,0x43,0x20,2,0x69,0xae,0xc2,0xc0,0xff,0xff,
 0xc0,0x72,0xbf,0,0,0,0,0,0,0,0x40,0,0x80,0x88,0,0,
 0xfe,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
@@ -1102,7 +1138,7 @@
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0x98,0,0xc1,0x66,0xe0,0x80,0,0,0,0,
+0,0,0,0,0,0,0x98,0,0xc3,0x66,0xe0,0x80,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,
@@ -1110,17 +1146,4 @@
 0,0,0,0,0,0,0,0,0,0,0,7,0,0,2,0
 };
 
-static const UTrie2 norm2_nfc_data_trie={
-    norm2_nfc_data_trieIndex,
-    norm2_nfc_data_trieIndex+2612,
-    NULL,
-    2612,
-    6788,
-    0x188,
-    0xab0,
-    0x0,
-    0x0,
-    0x30000,
-    0x24b4,
-    NULL, 0, FALSE, FALSE, 0, NULL
-};
+#endif  // INCLUDED_FROM_NORMALIZER2_CPP
diff --git a/src/third_party/icu/source/common/norm2allmodes.h b/src/third_party/icu/source/common/norm2allmodes.h
index 64c84a2..e8bd52c 100644
--- a/src/third_party/icu/source/common/norm2allmodes.h
+++ b/src/third_party/icu/source/common/norm2allmodes.h
@@ -1,9 +1,11 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 * Copyright (C) 2014, International Business Machines
 * Corporation and others.  All Rights Reserved.
 *******************************************************************************
-* loadednormalizer2impl.h
+* norm2allmodes.h
 *
 * created on: 2014sep07
 * created by: Markus W. Scherer
@@ -16,7 +18,9 @@
 
 #if !UCONFIG_NO_NORMALIZATION
 
+#include "unicode/edits.h"
 #include "unicode/normalizer2.h"
+#include "unicode/stringoptions.h"
 #include "unicode/unistr.h"
 #include "cpputils.h"
 #include "normalizer2impl.h"
@@ -61,13 +65,13 @@
     normalizeSecondAndAppend(UnicodeString &first,
                              const UnicodeString &second,
                              UErrorCode &errorCode) const {
-        return normalizeSecondAndAppend(first, second, TRUE, errorCode);
+        return normalizeSecondAndAppend(first, second, true, errorCode);
     }
     virtual UnicodeString &
     append(UnicodeString &first,
            const UnicodeString &second,
            UErrorCode &errorCode) const {
-        return normalizeSecondAndAppend(first, second, FALSE, errorCode);
+        return normalizeSecondAndAppend(first, second, false, errorCode);
     }
     UnicodeString &
     normalizeSecondAndAppend(UnicodeString &first,
@@ -108,14 +112,14 @@
         int32_t length;
         const UChar *d=impl.getDecomposition(c, buffer, length);
         if(d==NULL) {
-            return FALSE;
+            return false;
         }
         if(d==buffer) {
             decomposition.setTo(buffer, length);  // copy the string (Jamos from Hangul syllable c)
         } else {
-            decomposition.setTo(FALSE, d, length);  // read-only alias
+            decomposition.setTo(false, d, length);  // read-only alias
         }
-        return TRUE;
+        return true;
     }
     virtual UBool
     getRawDecomposition(UChar32 c, UnicodeString &decomposition) const {
@@ -123,14 +127,14 @@
         int32_t length;
         const UChar *d=impl.getRawDecomposition(c, buffer, length);
         if(d==NULL) {
-            return FALSE;
+            return false;
         }
         if(d==buffer) {
             decomposition.setTo(buffer, length);  // copy the string (algorithmic decomposition)
         } else {
-            decomposition.setTo(FALSE, d, length);  // read-only alias
+            decomposition.setTo(false, d, length);  // read-only alias
         }
-        return TRUE;
+        return true;
     }
     virtual UChar32
     composePair(UChar32 a, UChar32 b) const {
@@ -146,12 +150,12 @@
     virtual UBool
     isNormalized(const UnicodeString &s, UErrorCode &errorCode) const {
         if(U_FAILURE(errorCode)) {
-            return FALSE;
+            return false;
         }
         const UChar *sArray=s.getBuffer();
         if(sArray==NULL) {
             errorCode=U_ILLEGAL_ARGUMENT_ERROR;
-            return FALSE;
+            return false;
         }
         const UChar *sLimit=sArray+s.length();
         return sLimit==spanQuickCheckYes(sArray, sLimit, errorCode);
@@ -208,8 +212,8 @@
     virtual UNormalizationCheckResult getQuickCheck(UChar32 c) const {
         return impl.isDecompYes(impl.getNorm16(c)) ? UNORM_YES : UNORM_NO;
     }
-    virtual UBool hasBoundaryBefore(UChar32 c) const { return impl.hasDecompBoundary(c, TRUE); }
-    virtual UBool hasBoundaryAfter(UChar32 c) const { return impl.hasDecompBoundary(c, FALSE); }
+    virtual UBool hasBoundaryBefore(UChar32 c) const { return impl.hasDecompBoundaryBefore(c); }
+    virtual UBool hasBoundaryAfter(UChar32 c) const { return impl.hasDecompBoundaryAfter(c); }
     virtual UBool isInert(UChar32 c) const { return impl.isDecompInert(c); }
 };
 
@@ -222,36 +226,60 @@
 private:
     virtual void
     normalize(const UChar *src, const UChar *limit,
-              ReorderingBuffer &buffer, UErrorCode &errorCode) const {
-        impl.compose(src, limit, onlyContiguous, TRUE, buffer, errorCode);
+              ReorderingBuffer &buffer, UErrorCode &errorCode) const U_OVERRIDE {
+        impl.compose(src, limit, onlyContiguous, true, buffer, errorCode);
     }
     using Normalizer2WithImpl::normalize;  // Avoid warning about hiding base class function.
+
+    void
+    normalizeUTF8(uint32_t options, StringPiece src, ByteSink &sink,
+                  Edits *edits, UErrorCode &errorCode) const U_OVERRIDE {
+        if (U_FAILURE(errorCode)) {
+            return;
+        }
+        if (edits != nullptr && (options & U_EDITS_NO_RESET) == 0) {
+            edits->reset();
+        }
+        const uint8_t *s = reinterpret_cast<const uint8_t *>(src.data());
+        impl.composeUTF8(options, onlyContiguous, s, s + src.length(),
+                         &sink, edits, errorCode);
+        sink.Flush();
+    }
+
     virtual void
     normalizeAndAppend(const UChar *src, const UChar *limit, UBool doNormalize,
                        UnicodeString &safeMiddle,
-                       ReorderingBuffer &buffer, UErrorCode &errorCode) const {
+                       ReorderingBuffer &buffer, UErrorCode &errorCode) const U_OVERRIDE {
         impl.composeAndAppend(src, limit, doNormalize, onlyContiguous, safeMiddle, buffer, errorCode);
     }
 
     virtual UBool
-    isNormalized(const UnicodeString &s, UErrorCode &errorCode) const {
+    isNormalized(const UnicodeString &s, UErrorCode &errorCode) const U_OVERRIDE {
         if(U_FAILURE(errorCode)) {
-            return FALSE;
+            return false;
         }
         const UChar *sArray=s.getBuffer();
         if(sArray==NULL) {
             errorCode=U_ILLEGAL_ARGUMENT_ERROR;
-            return FALSE;
+            return false;
         }
         UnicodeString temp;
         ReorderingBuffer buffer(impl, temp);
         if(!buffer.init(5, errorCode)) {  // small destCapacity for substring normalization
-            return FALSE;
+            return false;
         }
-        return impl.compose(sArray, sArray+s.length(), onlyContiguous, FALSE, buffer, errorCode);
+        return impl.compose(sArray, sArray+s.length(), onlyContiguous, false, buffer, errorCode);
+    }
+    virtual UBool
+    isNormalizedUTF8(StringPiece sp, UErrorCode &errorCode) const U_OVERRIDE {
+        if(U_FAILURE(errorCode)) {
+            return false;
+        }
+        const uint8_t *s = reinterpret_cast<const uint8_t *>(sp.data());
+        return impl.composeUTF8(0, onlyContiguous, s, s + sp.length(), nullptr, nullptr, errorCode);
     }
     virtual UNormalizationCheckResult
-    quickCheck(const UnicodeString &s, UErrorCode &errorCode) const {
+    quickCheck(const UnicodeString &s, UErrorCode &errorCode) const U_OVERRIDE {
         if(U_FAILURE(errorCode)) {
             return UNORM_MAYBE;
         }
@@ -265,21 +293,21 @@
         return qcResult;
     }
     virtual const UChar *
-    spanQuickCheckYes(const UChar *src, const UChar *limit, UErrorCode &) const {
+    spanQuickCheckYes(const UChar *src, const UChar *limit, UErrorCode &) const U_OVERRIDE {
         return impl.composeQuickCheck(src, limit, onlyContiguous, NULL);
     }
     using Normalizer2WithImpl::spanQuickCheckYes;  // Avoid warning about hiding base class function.
-    virtual UNormalizationCheckResult getQuickCheck(UChar32 c) const {
+    virtual UNormalizationCheckResult getQuickCheck(UChar32 c) const U_OVERRIDE {
         return impl.getCompQuickCheck(impl.getNorm16(c));
     }
-    virtual UBool hasBoundaryBefore(UChar32 c) const {
+    virtual UBool hasBoundaryBefore(UChar32 c) const U_OVERRIDE {
         return impl.hasCompBoundaryBefore(c);
     }
-    virtual UBool hasBoundaryAfter(UChar32 c) const {
-        return impl.hasCompBoundaryAfter(c, onlyContiguous, FALSE);
+    virtual UBool hasBoundaryAfter(UChar32 c) const U_OVERRIDE {
+        return impl.hasCompBoundaryAfter(c, onlyContiguous);
     }
-    virtual UBool isInert(UChar32 c) const {
-        return impl.hasCompBoundaryAfter(c, onlyContiguous, TRUE);
+    virtual UBool isInert(UChar32 c) const U_OVERRIDE {
+        return impl.isCompInert(c, onlyContiguous);
     }
 
     const UBool onlyContiguous;
@@ -315,7 +343,7 @@
 
 struct Norm2AllModes : public UMemory {
     Norm2AllModes(Normalizer2Impl *i)
-            : impl(i), comp(*i, FALSE), decomp(*i), fcd(*i), fcc(*i, TRUE) {}
+            : impl(i), comp(*i, false), decomp(*i), fcd(*i), fcc(*i, true) {}
     ~Norm2AllModes();
 
     static Norm2AllModes *createInstance(Normalizer2Impl *impl, UErrorCode &errorCode);
diff --git a/src/third_party/icu/source/common/normalizer2.cpp b/src/third_party/icu/source/common/normalizer2.cpp
index eacc571..6be7e0b 100644
--- a/src/third_party/icu/source/common/normalizer2.cpp
+++ b/src/third_party/icu/source/common/normalizer2.cpp
@@ -1,12 +1,14 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
-*   Copyright (C) 2009-2014, International Business Machines
+*   Copyright (C) 2009-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *
 *******************************************************************************
 *   file name:  normalizer2.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -18,7 +20,9 @@
 
 #if !UCONFIG_NO_NORMALIZATION
 
+#include "unicode/edits.h"
 #include "unicode/normalizer2.h"
+#include "unicode/stringoptions.h"
 #include "unicode/unistr.h"
 #include "unicode/unorm.h"
 #include "cstring.h"
@@ -30,8 +34,11 @@
 
 using icu::Normalizer2Impl;
 
+#if NORM2_HARDCODE_NFC_DATA
 // NFC/NFD data machine-generated by gennorm2 --csource
+#define INCLUDED_FROM_NORMALIZER2_CPP
 #include "norm2_nfc_data.h"
+#endif
 
 U_NAMESPACE_BEGIN
 
@@ -39,6 +46,20 @@
 
 Normalizer2::~Normalizer2() {}
 
+void
+Normalizer2::normalizeUTF8(uint32_t /*options*/, StringPiece src, ByteSink &sink,
+                           Edits *edits, UErrorCode &errorCode) const {
+    if (U_FAILURE(errorCode)) {
+        return;
+    }
+    if (edits != nullptr) {
+        errorCode = U_UNSUPPORTED_ERROR;
+        return;
+    }
+    UnicodeString src16 = UnicodeString::fromUTF8(src);
+    normalize(src16, errorCode).toUTF8(sink);
+}
+
 UBool
 Normalizer2::getRawDecomposition(UChar32, UnicodeString &) const {
     return FALSE;
@@ -54,6 +75,11 @@
     return 0;
 }
 
+UBool
+Normalizer2::isNormalizedUTF8(StringPiece s, UErrorCode &errorCode) const {
+    return U_SUCCESS(errorCode) && isNormalized(UnicodeString::fromUTF8(s), errorCode);
+}
+
 // Normalizer2 implementation for the old UNORM_NONE.
 class NoopNormalizer2 : public Normalizer2 {
     virtual ~NoopNormalizer2();
@@ -61,7 +87,7 @@
     virtual UnicodeString &
     normalize(const UnicodeString &src,
               UnicodeString &dest,
-              UErrorCode &errorCode) const {
+              UErrorCode &errorCode) const U_OVERRIDE {
         if(U_SUCCESS(errorCode)) {
             if(&dest!=&src) {
                 dest=src;
@@ -71,10 +97,27 @@
         }
         return dest;
     }
+    virtual void
+    normalizeUTF8(uint32_t options, StringPiece src, ByteSink &sink,
+                  Edits *edits, UErrorCode &errorCode) const U_OVERRIDE {
+        if(U_SUCCESS(errorCode)) {
+            if (edits != nullptr) {
+                if ((options & U_EDITS_NO_RESET) == 0) {
+                    edits->reset();
+                }
+                edits->addUnchanged(src.length());
+            }
+            if ((options & U_OMIT_UNCHANGED_TEXT) == 0) {
+                sink.Append(src.data(), src.length());
+            }
+            sink.Flush();
+        }
+    }
+
     virtual UnicodeString &
     normalizeSecondAndAppend(UnicodeString &first,
                              const UnicodeString &second,
-                             UErrorCode &errorCode) const {
+                             UErrorCode &errorCode) const U_OVERRIDE {
         if(U_SUCCESS(errorCode)) {
             if(&first!=&second) {
                 first.append(second);
@@ -87,7 +130,7 @@
     virtual UnicodeString &
     append(UnicodeString &first,
            const UnicodeString &second,
-           UErrorCode &errorCode) const {
+           UErrorCode &errorCode) const U_OVERRIDE {
         if(U_SUCCESS(errorCode)) {
             if(&first!=&second) {
                 first.append(second);
@@ -98,25 +141,29 @@
         return first;
     }
     virtual UBool
-    getDecomposition(UChar32, UnicodeString &) const {
+    getDecomposition(UChar32, UnicodeString &) const U_OVERRIDE {
         return FALSE;
     }
-    // No need to override the default getRawDecomposition().
+    // No need to U_OVERRIDE the default getRawDecomposition().
     virtual UBool
-    isNormalized(const UnicodeString &, UErrorCode &) const {
-        return TRUE;
+    isNormalized(const UnicodeString &, UErrorCode &errorCode) const U_OVERRIDE {
+        return U_SUCCESS(errorCode);
+    }
+    virtual UBool
+    isNormalizedUTF8(StringPiece, UErrorCode &errorCode) const U_OVERRIDE {
+        return U_SUCCESS(errorCode);
     }
     virtual UNormalizationCheckResult
-    quickCheck(const UnicodeString &, UErrorCode &) const {
+    quickCheck(const UnicodeString &, UErrorCode &) const U_OVERRIDE {
         return UNORM_YES;
     }
     virtual int32_t
-    spanQuickCheckYes(const UnicodeString &s, UErrorCode &) const {
+    spanQuickCheckYes(const UnicodeString &s, UErrorCode &) const U_OVERRIDE {
         return s.length();
     }
-    virtual UBool hasBoundaryBefore(UChar32) const { return TRUE; }
-    virtual UBool hasBoundaryAfter(UChar32) const { return TRUE; }
-    virtual UBool isInert(UChar32) const { return TRUE; }
+    virtual UBool hasBoundaryBefore(UChar32) const U_OVERRIDE { return TRUE; }
+    virtual UBool hasBoundaryAfter(UChar32) const U_OVERRIDE { return TRUE; }
+    virtual UBool isInert(UChar32) const U_OVERRIDE { return TRUE; }
 };
 
 NoopNormalizer2::~NoopNormalizer2() {}
@@ -131,6 +178,36 @@
 
 // instance cache ---------------------------------------------------------- ***
 
+U_CDECL_BEGIN
+static UBool U_CALLCONV uprv_normalizer2_cleanup();
+U_CDECL_END
+
+static Normalizer2   *noopSingleton;
+static icu::UInitOnce noopInitOnce = U_INITONCE_INITIALIZER;
+
+static void U_CALLCONV initNoopSingleton(UErrorCode &errorCode) {
+    if(U_FAILURE(errorCode)) {
+        return;
+    }
+    noopSingleton=new NoopNormalizer2;
+    if(noopSingleton==NULL) {
+        errorCode=U_MEMORY_ALLOCATION_ERROR;
+        return;
+    }
+    ucln_common_registerCleanup(UCLN_COMMON_NORMALIZER2, uprv_normalizer2_cleanup);
+}
+
+const Normalizer2 *Normalizer2Factory::getNoopInstance(UErrorCode &errorCode) {
+    if(U_FAILURE(errorCode)) { return NULL; }
+    umtx_initOnce(noopInitOnce, &initNoopSingleton, errorCode);
+    return noopSingleton;
+}
+
+const Normalizer2Impl *
+Normalizer2Factory::getImpl(const Normalizer2 *norm2) {
+    return &((Normalizer2WithImpl *)norm2)->impl;
+}
+
 Norm2AllModes::~Norm2AllModes() {
     delete impl;
 }
@@ -150,6 +227,7 @@
     return allModes;
 }
 
+#if NORM2_HARDCODE_NFC_DATA
 Norm2AllModes *
 Norm2AllModes::createNFCInstance(UErrorCode &errorCode) {
     if(U_FAILURE(errorCode)) {
@@ -165,48 +243,15 @@
     return createInstance(impl, errorCode);
 }
 
-U_CDECL_BEGIN
-static UBool U_CALLCONV uprv_normalizer2_cleanup();
-U_CDECL_END
-
 static Norm2AllModes *nfcSingleton;
-static Normalizer2   *noopSingleton;
 
 static icu::UInitOnce nfcInitOnce = U_INITONCE_INITIALIZER;
-static icu::UInitOnce noopInitOnce = U_INITONCE_INITIALIZER;
 
-// UInitOnce singleton initialization functions
 static void U_CALLCONV initNFCSingleton(UErrorCode &errorCode) {
     nfcSingleton=Norm2AllModes::createNFCInstance(errorCode);
     ucln_common_registerCleanup(UCLN_COMMON_NORMALIZER2, uprv_normalizer2_cleanup);
 }
 
-static void U_CALLCONV initNoopSingleton(UErrorCode &errorCode) {
-    if(U_FAILURE(errorCode)) {
-        return;
-    }
-    noopSingleton=new NoopNormalizer2;
-    if(noopSingleton==NULL) {
-        errorCode=U_MEMORY_ALLOCATION_ERROR;
-        return;
-    }
-    ucln_common_registerCleanup(UCLN_COMMON_NORMALIZER2, uprv_normalizer2_cleanup);
-}
-
-U_CDECL_BEGIN
-
-static UBool U_CALLCONV uprv_normalizer2_cleanup() {
-    delete nfcSingleton;
-    nfcSingleton = NULL;
-    delete noopSingleton;
-    noopSingleton = NULL;
-    nfcInitOnce.reset(); 
-    noopInitOnce.reset(); 
-    return TRUE;
-}
-
-U_CDECL_END
-
 const Norm2AllModes *
 Norm2AllModes::getNFCInstance(UErrorCode &errorCode) {
     if(U_FAILURE(errorCode)) { return NULL; }
@@ -236,23 +281,29 @@
     return allModes!=NULL ? &allModes->fcc : NULL;
 }
 
-const Normalizer2 *Normalizer2Factory::getNoopInstance(UErrorCode &errorCode) {
-    if(U_FAILURE(errorCode)) { return NULL; }
-    umtx_initOnce(noopInitOnce, &initNoopSingleton, errorCode);
-    return noopSingleton;
-}
-
 const Normalizer2Impl *
 Normalizer2Factory::getNFCImpl(UErrorCode &errorCode) {
     const Norm2AllModes *allModes=Norm2AllModes::getNFCInstance(errorCode);
     return allModes!=NULL ? allModes->impl : NULL;
 }
+#endif  // NORM2_HARDCODE_NFC_DATA
 
-const Normalizer2Impl *
-Normalizer2Factory::getImpl(const Normalizer2 *norm2) {
-    return &((Normalizer2WithImpl *)norm2)->impl;
+U_CDECL_BEGIN
+
+static UBool U_CALLCONV uprv_normalizer2_cleanup() {
+    delete noopSingleton;
+    noopSingleton = NULL;
+    noopInitOnce.reset(); 
+#if NORM2_HARDCODE_NFC_DATA
+    delete nfcSingleton;
+    nfcSingleton = NULL;
+    nfcInitOnce.reset(); 
+#endif
+    return TRUE;
 }
 
+U_CDECL_END
+
 U_NAMESPACE_END
 
 // C API ------------------------------------------------------------------- ***
diff --git a/src/third_party/icu/source/common/normalizer2impl.cpp b/src/third_party/icu/source/common/normalizer2impl.cpp
index 786d0b2..5d4ae00 100644
--- a/src/third_party/icu/source/common/normalizer2impl.cpp
+++ b/src/third_party/icu/source/common/normalizer2impl.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  normalizer2impl.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -14,29 +16,173 @@
 *   created by: Markus W. Scherer
 */
 
+// #define UCPTRIE_DEBUG
+
 #include "unicode/utypes.h"
 
 #if !UCONFIG_NO_NORMALIZATION
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
+#include "unicode/bytestream.h"
+#include "unicode/edits.h"
 #include "unicode/normalizer2.h"
+#include "unicode/stringoptions.h"
+#include "unicode/ucptrie.h"
 #include "unicode/udata.h"
+#include "unicode/umutablecptrie.h"
 #include "unicode/ustring.h"
 #include "unicode/utf16.h"
+#include "unicode/utf8.h"
+#include "bytesinkutil.h"
 #include "cmemory.h"
 #include "mutex.h"
 #include "normalizer2impl.h"
 #include "putilimp.h"
 #include "uassert.h"
+#include "ucptrie_impl.h"
 #include "uset_imp.h"
-#include "utrie2.h"
 #include "uvector.h"
 
 U_NAMESPACE_BEGIN
 
+namespace {
+
+/**
+ * UTF-8 lead byte for minNoMaybeCP.
+ * Can be lower than the actual lead byte for c.
+ * Typically U+0300 for NFC/NFD, U+00A0 for NFKC/NFKD, U+0041 for NFKC_Casefold.
+ */
+inline uint8_t leadByteForCP(UChar32 c) {
+    if (c <= 0x7f) {
+        return (uint8_t)c;
+    } else if (c <= 0x7ff) {
+        return (uint8_t)(0xc0+(c>>6));
+    } else {
+        // Should not occur because ccc(U+0300)!=0.
+        return 0xe0;
+    }
+}
+
+/**
+ * Returns the code point from one single well-formed UTF-8 byte sequence
+ * between cpStart and cpLimit.
+ *
+ * Trie UTF-8 macros do not assemble whole code points (for efficiency).
+ * When we do need the code point, we call this function.
+ * We should not need it for normalization-inert data (norm16==0).
+ * Illegal sequences yield the error value norm16==0 just like real normalization-inert code points.
+ */
+UChar32 codePointFromValidUTF8(const uint8_t *cpStart, const uint8_t *cpLimit) {
+    // Similar to U8_NEXT_UNSAFE(s, i, c).
+    U_ASSERT(cpStart < cpLimit);
+    uint8_t c = *cpStart;
+    switch(cpLimit-cpStart) {
+    case 1:
+        return c;
+    case 2:
+        return ((c&0x1f)<<6) | (cpStart[1]&0x3f);
+    case 3:
+        // no need for (c&0xf) because the upper bits are truncated after <<12 in the cast to (UChar)
+        return (UChar)((c<<12) | ((cpStart[1]&0x3f)<<6) | (cpStart[2]&0x3f));
+    case 4:
+        return ((c&7)<<18) | ((cpStart[1]&0x3f)<<12) | ((cpStart[2]&0x3f)<<6) | (cpStart[3]&0x3f);
+    default:
+        UPRV_UNREACHABLE;  // Should not occur.
+    }
+}
+
+/**
+ * Returns the last code point in [start, p[ if it is valid and in U+1000..U+D7FF.
+ * Otherwise returns a negative value.
+ */
+UChar32 previousHangulOrJamo(const uint8_t *start, const uint8_t *p) {
+    if ((p - start) >= 3) {
+        p -= 3;
+        uint8_t l = *p;
+        uint8_t t1, t2;
+        if (0xe1 <= l && l <= 0xed &&
+                (t1 = (uint8_t)(p[1] - 0x80)) <= 0x3f &&
+                (t2 = (uint8_t)(p[2] - 0x80)) <= 0x3f &&
+                (l < 0xed || t1 <= 0x1f)) {
+            return ((l & 0xf) << 12) | (t1 << 6) | t2;
+        }
+    }
+    return U_SENTINEL;
+}
+
+/**
+ * Returns the offset from the Jamo T base if [src, limit[ starts with a single Jamo T code point.
+ * Otherwise returns a negative value.
+ */
+int32_t getJamoTMinusBase(const uint8_t *src, const uint8_t *limit) {
+    // Jamo T: E1 86 A8..E1 87 82
+    if ((limit - src) >= 3 && *src == 0xe1) {
+        if (src[1] == 0x86) {
+            uint8_t t = src[2];
+            // The first Jamo T is U+11A8 but JAMO_T_BASE is 11A7.
+            // Offset 0 does not correspond to any conjoining Jamo.
+            if (0xa8 <= t && t <= 0xbf) {
+                return t - 0xa7;
+            }
+        } else if (src[1] == 0x87) {
+            uint8_t t = src[2];
+            if ((int8_t)t <= (int8_t)0x82u) {
+                return t - (0xa7 - 0x40);
+            }
+        }
+    }
+    return -1;
+}
+
+void
+appendCodePointDelta(const uint8_t *cpStart, const uint8_t *cpLimit, int32_t delta,
+                     ByteSink &sink, Edits *edits) {
+    char buffer[U8_MAX_LENGTH];
+    int32_t length;
+    int32_t cpLength = (int32_t)(cpLimit - cpStart);
+    if (cpLength == 1) {
+        // The builder makes ASCII map to ASCII.
+        buffer[0] = (uint8_t)(*cpStart + delta);
+        length = 1;
+    } else {
+        int32_t trail = *(cpLimit-1) + delta;
+        if (0x80 <= trail && trail <= 0xbf) {
+            // The delta only changes the last trail byte.
+            --cpLimit;
+            length = 0;
+            do { buffer[length++] = *cpStart++; } while (cpStart < cpLimit);
+            buffer[length++] = (uint8_t)trail;
+        } else {
+            // Decode the code point, add the delta, re-encode.
+            UChar32 c = codePointFromValidUTF8(cpStart, cpLimit) + delta;
+            length = 0;
+            U8_APPEND_UNSAFE(buffer, length, c);
+        }
+    }
+    if (edits != nullptr) {
+        edits->addReplace(cpLength, length);
+    }
+    sink.Append(buffer, length);
+}
+
+}  // namespace
+
 // ReorderingBuffer -------------------------------------------------------- ***
 
+ReorderingBuffer::ReorderingBuffer(const Normalizer2Impl &ni, UnicodeString &dest,
+                                   UErrorCode &errorCode) :
+        impl(ni), str(dest),
+        start(str.getBuffer(8)), reorderStart(start), limit(start),
+        remainingCapacity(str.getCapacity()), lastCC(0) {
+    if (start == nullptr && U_SUCCESS(errorCode)) {
+        // getBuffer() already did str.setToBogus()
+        errorCode = U_MEMORY_ALLOCATION_ERROR;
+    }
+}
+
 UBool ReorderingBuffer::init(int32_t destCapacity, UErrorCode &errorCode) {
     int32_t length=str.length();
     start=str.getBuffer(destCapacity);
@@ -69,6 +215,32 @@
         0==u_memcmp(start, otherStart, length);
 }
 
+UBool ReorderingBuffer::equals(const uint8_t *otherStart, const uint8_t *otherLimit) const {
+    U_ASSERT((otherLimit - otherStart) <= INT32_MAX);  // ensured by caller
+    int32_t length = (int32_t)(limit - start);
+    int32_t otherLength = (int32_t)(otherLimit - otherStart);
+    // For equal strings, UTF-8 is at least as long as UTF-16, and at most three times as long.
+    if (otherLength < length || (otherLength / 3) > length) {
+        return FALSE;
+    }
+    // Compare valid strings from between normalization boundaries.
+    // (Invalid sequences are normalization-inert.)
+    for (int32_t i = 0, j = 0;;) {
+        if (i >= length) {
+            return j >= otherLength;
+        } else if (j >= otherLength) {
+            return FALSE;
+        }
+        // Not at the end of either string yet.
+        UChar32 c, other;
+        U16_NEXT_UNSAFE(start, i, c);
+        U8_NEXT_UNSAFE(otherStart, j, other);
+        if (c != other) {
+            return FALSE;
+        }
+    }
+}
+
 UBool ReorderingBuffer::appendSupplementary(UChar32 c, uint8_t cc, UErrorCode &errorCode) {
     if(remainingCapacity<2 && !resize(2, errorCode)) {
         return FALSE;
@@ -88,7 +260,7 @@
     return TRUE;
 }
 
-UBool ReorderingBuffer::append(const UChar *s, int32_t length,
+UBool ReorderingBuffer::append(const UChar *s, int32_t length, UBool isNFD,
                                uint8_t leadCC, uint8_t trailCC,
                                UErrorCode &errorCode) {
     if(length==0) {
@@ -115,8 +287,11 @@
         while(i<length) {
             U16_NEXT(s, i, length, c);
             if(i<length) {
-                // s must be in NFD, otherwise we need to use getCC().
-                leadCC=Normalizer2Impl::getCCFromYesOrMaybe(impl.getNorm16(c));
+                if (isNFD) {
+                    leadCC = Normalizer2Impl::getCCFromYesOrMaybe(impl.getRawNorm16(c));
+                } else {
+                    leadCC = impl.getCC(impl.getNorm16(c));
+                }
             } else {
                 leadCC=trailCC;
             }
@@ -216,16 +391,12 @@
         return 0;
     }
     UChar32 c=*--codePointStart;
-    if(c<Normalizer2Impl::MIN_CCC_LCCC_CP) {
-        return 0;
-    }
-
     UChar c2;
     if(U16_IS_TRAIL(c) && start<codePointStart && U16_IS_LEAD(c2=*(codePointStart-1))) {
         --codePointStart;
         c=U16_GET_SUPPLEMENTARY(c2, c);
     }
-    return Normalizer2Impl::getCCFromYesOrMaybe(impl.getNorm16(c));
+    return impl.getCCFromYesOrMaybeCP(c);
 }
 
 // Inserts c somewhere before the last character.
@@ -250,7 +421,8 @@
     CanonIterData(UErrorCode &errorCode);
     ~CanonIterData();
     void addToStartSet(UChar32 origin, UChar32 decompLead, UErrorCode &errorCode);
-    UTrie2 *trie;
+    UMutableCPTrie *mutableTrie;
+    UCPTrie *trie;
     UVector canonStartSets;  // contains UnicodeSet *
 };
 
@@ -259,129 +431,33 @@
 }
 
 void
-Normalizer2Impl::init(const int32_t *inIndexes, const UTrie2 *inTrie,
+Normalizer2Impl::init(const int32_t *inIndexes, const UCPTrie *inTrie,
                       const uint16_t *inExtraData, const uint8_t *inSmallFCD) {
-    minDecompNoCP=inIndexes[IX_MIN_DECOMP_NO_CP];
-    minCompNoMaybeCP=inIndexes[IX_MIN_COMP_NO_MAYBE_CP];
+    minDecompNoCP = static_cast<UChar>(inIndexes[IX_MIN_DECOMP_NO_CP]);
+    minCompNoMaybeCP = static_cast<UChar>(inIndexes[IX_MIN_COMP_NO_MAYBE_CP]);
+    minLcccCP = static_cast<UChar>(inIndexes[IX_MIN_LCCC_CP]);
 
-    minYesNo=inIndexes[IX_MIN_YES_NO];
-    minYesNoMappingsOnly=inIndexes[IX_MIN_YES_NO_MAPPINGS_ONLY];
-    minNoNo=inIndexes[IX_MIN_NO_NO];
-    limitNoNo=inIndexes[IX_LIMIT_NO_NO];
-    minMaybeYes=inIndexes[IX_MIN_MAYBE_YES];
+    minYesNo = static_cast<uint16_t>(inIndexes[IX_MIN_YES_NO]);
+    minYesNoMappingsOnly = static_cast<uint16_t>(inIndexes[IX_MIN_YES_NO_MAPPINGS_ONLY]);
+    minNoNo = static_cast<uint16_t>(inIndexes[IX_MIN_NO_NO]);
+    minNoNoCompBoundaryBefore = static_cast<uint16_t>(inIndexes[IX_MIN_NO_NO_COMP_BOUNDARY_BEFORE]);
+    minNoNoCompNoMaybeCC = static_cast<uint16_t>(inIndexes[IX_MIN_NO_NO_COMP_NO_MAYBE_CC]);
+    minNoNoEmpty = static_cast<uint16_t>(inIndexes[IX_MIN_NO_NO_EMPTY]);
+    limitNoNo = static_cast<uint16_t>(inIndexes[IX_LIMIT_NO_NO]);
+    minMaybeYes = static_cast<uint16_t>(inIndexes[IX_MIN_MAYBE_YES]);
+    U_ASSERT((minMaybeYes & 7) == 0);  // 8-aligned for noNoDelta bit fields
+    centerNoNoDelta = (minMaybeYes >> DELTA_SHIFT) - MAX_DELTA - 1;
 
     normTrie=inTrie;
 
     maybeYesCompositions=inExtraData;
-    extraData=maybeYesCompositions+(MIN_NORMAL_MAYBE_YES-minMaybeYes);
+    extraData=maybeYesCompositions+((MIN_NORMAL_MAYBE_YES-minMaybeYes)>>OFFSET_SHIFT);
 
     smallFCD=inSmallFCD;
-
-    // Build tccc180[].
-    // gennorm2 enforces lccc=0 for c<MIN_CCC_LCCC_CP=U+0300.
-    uint8_t bits=0;
-    for(UChar c=0; c<0x180; bits>>=1) {
-        if((c&0xff)==0) {
-            bits=smallFCD[c>>8];  // one byte per 0x100 code points
-        }
-        if(bits&1) {
-            for(int i=0; i<0x20; ++i, ++c) {
-                tccc180[c]=(uint8_t)getFCD16FromNormData(c);
-            }
-        } else {
-            uprv_memset(tccc180+c, 0, 0x20);
-            c+=0x20;
-        }
-    }
 }
 
-uint8_t Normalizer2Impl::getTrailCCFromCompYesAndZeroCC(const UChar *cpStart, const UChar *cpLimit) const {
-    UChar32 c;
-    if(cpStart==(cpLimit-1)) {
-        c=*cpStart;
-    } else {
-        c=U16_GET_SUPPLEMENTARY(cpStart[0], cpStart[1]);
-    }
-    uint16_t prevNorm16=getNorm16(c);
-    if(prevNorm16<=minYesNo) {
-        return 0;  // yesYes and Hangul LV/LVT have ccc=tccc=0
-    } else {
-        return (uint8_t)(*getMapping(prevNorm16)>>8);  // tccc from yesNo
-    }
-}
-
-namespace {
-
-class LcccContext {
-public:
-    LcccContext(const Normalizer2Impl &ni, UnicodeSet &s) : impl(ni), set(s) {}
-
-    void handleRange(UChar32 start, UChar32 end, uint16_t norm16) {
-        if(impl.isAlgorithmicNoNo(norm16)) {
-            // Range of code points with same-norm16-value algorithmic decompositions.
-            // They might have different non-zero FCD16 values.
-            do {
-                uint16_t fcd16=impl.getFCD16(start);
-                if(fcd16>0xff) { set.add(start); }
-            } while(++start<=end);
-        } else {
-            uint16_t fcd16=impl.getFCD16(start);
-            if(fcd16>0xff) { set.add(start, end); }
-        }
-    }
-
-private:
-    const Normalizer2Impl &impl;
-    UnicodeSet &set;
-};
-
-struct PropertyStartsContext {
-    PropertyStartsContext(const Normalizer2Impl &ni, const USetAdder *adder)
-            : impl(ni), sa(adder) {}
-
-    const Normalizer2Impl &impl;
-    const USetAdder *sa;
-};
-
-}  // namespace
-
 U_CDECL_BEGIN
 
-static UBool U_CALLCONV
-enumLcccRange(const void *context, UChar32 start, UChar32 end, uint32_t value) {
-    ((LcccContext *)context)->handleRange(start, end, (uint16_t)value);
-    return TRUE;
-}
-
-static UBool U_CALLCONV
-enumNorm16PropertyStartsRange(const void *context, UChar32 start, UChar32 end, uint32_t value) {
-    /* add the start code point to the USet */
-    const PropertyStartsContext *ctx=(const PropertyStartsContext *)context;
-    const USetAdder *sa=ctx->sa;
-    sa->add(sa->set, start);
-    if(start!=end && ctx->impl.isAlgorithmicNoNo((uint16_t)value)) {
-        // Range of code points with same-norm16-value algorithmic decompositions.
-        // They might have different non-zero FCD16 values.
-        uint16_t prevFCD16=ctx->impl.getFCD16(start);
-        while(++start<=end) {
-            uint16_t fcd16=ctx->impl.getFCD16(start);
-            if(fcd16!=prevFCD16) {
-                sa->add(sa->set, start);
-                prevFCD16=fcd16;
-            }
-        }
-    }
-    return TRUE;
-}
-
-static UBool U_CALLCONV
-enumPropertyStartsRange(const void *context, UChar32 start, UChar32 /*end*/, uint32_t /*value*/) {
-    /* add the start code point to the USet */
-    const USetAdder *sa=(const USetAdder *)context;
-    sa->add(sa->set, start);
-    return TRUE;
-}
-
 static uint32_t U_CALLCONV
 segmentStarterMapper(const void * /*context*/, uint32_t value) {
     return value&CANON_NOT_SEGMENT_STARTER;
@@ -391,16 +467,44 @@
 
 void
 Normalizer2Impl::addLcccChars(UnicodeSet &set) const {
-    /* add the start code point of each same-value range of each trie */
-    LcccContext context(*this, set);
-    utrie2_enum(normTrie, NULL, enumLcccRange, &context);
+    UChar32 start = 0, end;
+    uint32_t norm16;
+    while ((end = ucptrie_getRange(normTrie, start, UCPMAP_RANGE_FIXED_LEAD_SURROGATES, INERT,
+                                   nullptr, nullptr, &norm16)) >= 0) {
+        if (norm16 > Normalizer2Impl::MIN_NORMAL_MAYBE_YES &&
+                norm16 != Normalizer2Impl::JAMO_VT) {
+            set.add(start, end);
+        } else if (minNoNoCompNoMaybeCC <= norm16 && norm16 < limitNoNo) {
+            uint16_t fcd16 = getFCD16(start);
+            if (fcd16 > 0xff) { set.add(start, end); }
+        }
+        start = end + 1;
+    }
 }
 
 void
 Normalizer2Impl::addPropertyStarts(const USetAdder *sa, UErrorCode & /*errorCode*/) const {
-    /* add the start code point of each same-value range of each trie */
-    PropertyStartsContext context(*this, sa);
-    utrie2_enum(normTrie, NULL, enumNorm16PropertyStartsRange, &context);
+    // Add the start code point of each same-value range of the trie.
+    UChar32 start = 0, end;
+    uint32_t value;
+    while ((end = ucptrie_getRange(normTrie, start, UCPMAP_RANGE_FIXED_LEAD_SURROGATES, INERT,
+                                   nullptr, nullptr, &value)) >= 0) {
+        sa->add(sa->set, start);
+        if (start != end && isAlgorithmicNoNo((uint16_t)value) &&
+                (value & Normalizer2Impl::DELTA_TCCC_MASK) > Normalizer2Impl::DELTA_TCCC_1) {
+            // Range of code points with same-norm16-value algorithmic decompositions.
+            // They might have different non-zero FCD16 values.
+            uint16_t prevFCD16 = getFCD16(start);
+            while (++start <= end) {
+                uint16_t fcd16 = getFCD16(start);
+                if (fcd16 != prevFCD16) {
+                    sa->add(sa->set, start);
+                    prevFCD16 = fcd16;
+                }
+            }
+        }
+        start = end + 1;
+    }
 
     /* add Hangul LV syllables and LV+1 because of skippables */
     for(UChar c=Hangul::HANGUL_BASE; c<Hangul::HANGUL_LIMIT; c+=Hangul::JAMO_T_COUNT) {
@@ -412,10 +516,15 @@
 
 void
 Normalizer2Impl::addCanonIterPropertyStarts(const USetAdder *sa, UErrorCode &errorCode) const {
-    /* add the start code point of each same-value range of the canonical iterator data trie */
-    if(ensureCanonIterData(errorCode)) {
-        // currently only used for the SEGMENT_STARTER property
-        utrie2_enum(fCanonIterData->trie, segmentStarterMapper, enumPropertyStartsRange, sa);
+    // Add the start code point of each same-value range of the canonical iterator data trie.
+    if (!ensureCanonIterData(errorCode)) { return; }
+    // Currently only used for the SEGMENT_STARTER property.
+    UChar32 start = 0, end;
+    uint32_t value;
+    while ((end = ucptrie_getRange(fCanonIterData->trie, start, UCPMAP_RANGE_NORMAL, 0,
+                                   segmentStarterMapper, nullptr, &value)) >= 0) {
+        sa->add(sa->set, start);
+        start = end + 1;
     }
 }
 
@@ -502,27 +611,23 @@
         // count code units below the minimum or with irrelevant data for the quick check
         for(prevSrc=src; src!=limit;) {
             if( (c=*src)<minNoCP ||
-                isMostDecompYesAndZeroCC(norm16=UTRIE2_GET16_FROM_U16_SINGLE_LEAD(normTrie, c))
+                isMostDecompYesAndZeroCC(norm16=UCPTRIE_FAST_BMP_GET(normTrie, UCPTRIE_16, c))
             ) {
                 ++src;
-            } else if(!U16_IS_SURROGATE(c)) {
+            } else if(!U16_IS_LEAD(c)) {
                 break;
             } else {
                 UChar c2;
-                if(U16_IS_SURROGATE_LEAD(c)) {
-                    if((src+1)!=limit && U16_IS_TRAIL(c2=src[1])) {
-                        c=U16_GET_SUPPLEMENTARY(c, c2);
+                if((src+1)!=limit && U16_IS_TRAIL(c2=src[1])) {
+                    c=U16_GET_SUPPLEMENTARY(c, c2);
+                    norm16=UCPTRIE_FAST_SUPP_GET(normTrie, UCPTRIE_16, c);
+                    if(isMostDecompYesAndZeroCC(norm16)) {
+                        src+=2;
+                    } else {
+                        break;
                     }
-                } else /* trail surrogate */ {
-                    if(prevSrc<src && U16_IS_LEAD(c2=*(src-1))) {
-                        --src;
-                        c=U16_GET_SUPPLEMENTARY(c2, c);
-                    }
-                }
-                if(isMostDecompYesAndZeroCC(norm16=getNorm16(c))) {
-                    src+=U16_LENGTH(c);
                 } else {
-                    break;
+                    ++src;  // unpaired lead surrogate: inert
                 }
             }
         }
@@ -568,77 +673,174 @@
 // fail the quick check loop and/or where the quick check loop's overhead
 // is unlikely to be amortized.
 // Called by the compose() and makeFCD() implementations.
-UBool Normalizer2Impl::decomposeShort(const UChar *src, const UChar *limit,
-                                      ReorderingBuffer &buffer,
-                                      UErrorCode &errorCode) const {
+const UChar *
+Normalizer2Impl::decomposeShort(const UChar *src, const UChar *limit,
+                                UBool stopAtCompBoundary, UBool onlyContiguous,
+                                ReorderingBuffer &buffer, UErrorCode &errorCode) const {
+    if (U_FAILURE(errorCode)) {
+        return nullptr;
+    }
     while(src<limit) {
+        if (stopAtCompBoundary && *src < minCompNoMaybeCP) {
+            return src;
+        }
+        const UChar *prevSrc = src;
         UChar32 c;
         uint16_t norm16;
-        UTRIE2_U16_NEXT16(normTrie, src, limit, c, norm16);
+        UCPTRIE_FAST_U16_NEXT(normTrie, UCPTRIE_16, src, limit, c, norm16);
+        if (stopAtCompBoundary && norm16HasCompBoundaryBefore(norm16)) {
+            return prevSrc;
+        }
         if(!decompose(c, norm16, buffer, errorCode)) {
-            return FALSE;
+            return nullptr;
+        }
+        if (stopAtCompBoundary && norm16HasCompBoundaryAfter(norm16, onlyContiguous)) {
+            return src;
         }
     }
-    return TRUE;
+    return src;
 }
 
 UBool Normalizer2Impl::decompose(UChar32 c, uint16_t norm16,
                                  ReorderingBuffer &buffer,
                                  UErrorCode &errorCode) const {
-    // Only loops for 1:1 algorithmic mappings.
-    for(;;) {
-        // get the decomposition and the lead and trail cc's
-        if(isDecompYes(norm16)) {
-            // c does not decompose
+    // get the decomposition and the lead and trail cc's
+    if (norm16 >= limitNoNo) {
+        if (isMaybeOrNonZeroCC(norm16)) {
             return buffer.append(c, getCCFromYesOrMaybe(norm16), errorCode);
-        } else if(isHangul(norm16)) {
-            // Hangul syllable: decompose algorithmically
-            UChar jamos[3];
-            return buffer.appendZeroCC(jamos, jamos+Hangul::decompose(c, jamos), errorCode);
-        } else if(isDecompNoAlgorithmic(norm16)) {
-            c=mapAlgorithmic(c, norm16);
-            norm16=getNorm16(c);
-        } else {
-            // c decomposes, get everything from the variable-length extra data
-            const uint16_t *mapping=getMapping(norm16);
-            uint16_t firstUnit=*mapping;
-            int32_t length=firstUnit&MAPPING_LENGTH_MASK;
-            uint8_t leadCC, trailCC;
-            trailCC=(uint8_t)(firstUnit>>8);
-            if(firstUnit&MAPPING_HAS_CCC_LCCC_WORD) {
-                leadCC=(uint8_t)(*(mapping-1)>>8);
-            } else {
-                leadCC=0;
+        }
+        // Maps to an isCompYesAndZeroCC.
+        c=mapAlgorithmic(c, norm16);
+        norm16=getRawNorm16(c);
+    }
+    if (norm16 < minYesNo) {
+        // c does not decompose
+        return buffer.append(c, 0, errorCode);
+    } else if(isHangulLV(norm16) || isHangulLVT(norm16)) {
+        // Hangul syllable: decompose algorithmically
+        UChar jamos[3];
+        return buffer.appendZeroCC(jamos, jamos+Hangul::decompose(c, jamos), errorCode);
+    }
+    // c decomposes, get everything from the variable-length extra data
+    const uint16_t *mapping=getMapping(norm16);
+    uint16_t firstUnit=*mapping;
+    int32_t length=firstUnit&MAPPING_LENGTH_MASK;
+    uint8_t leadCC, trailCC;
+    trailCC=(uint8_t)(firstUnit>>8);
+    if(firstUnit&MAPPING_HAS_CCC_LCCC_WORD) {
+        leadCC=(uint8_t)(*(mapping-1)>>8);
+    } else {
+        leadCC=0;
+    }
+    return buffer.append((const UChar *)mapping+1, length, TRUE, leadCC, trailCC, errorCode);
+}
+
+const uint8_t *
+Normalizer2Impl::decomposeShort(const uint8_t *src, const uint8_t *limit,
+                                UBool stopAtCompBoundary, UBool onlyContiguous,
+                                ReorderingBuffer &buffer, UErrorCode &errorCode) const {
+    if (U_FAILURE(errorCode)) {
+        return nullptr;
+    }
+    while (src < limit) {
+        const uint8_t *prevSrc = src;
+        uint16_t norm16;
+        UCPTRIE_FAST_U8_NEXT(normTrie, UCPTRIE_16, src, limit, norm16);
+        // Get the decomposition and the lead and trail cc's.
+        UChar32 c = U_SENTINEL;
+        if (norm16 >= limitNoNo) {
+            if (isMaybeOrNonZeroCC(norm16)) {
+                // No boundaries around this character.
+                c = codePointFromValidUTF8(prevSrc, src);
+                if (!buffer.append(c, getCCFromYesOrMaybe(norm16), errorCode)) {
+                    return nullptr;
+                }
+                continue;
             }
-            return buffer.append((const UChar *)mapping+1, length, leadCC, trailCC, errorCode);
+            // Maps to an isCompYesAndZeroCC.
+            if (stopAtCompBoundary) {
+                return prevSrc;
+            }
+            c = codePointFromValidUTF8(prevSrc, src);
+            c = mapAlgorithmic(c, norm16);
+            norm16 = getRawNorm16(c);
+        } else if (stopAtCompBoundary && norm16 < minNoNoCompNoMaybeCC) {
+            return prevSrc;
+        }
+        // norm16!=INERT guarantees that [prevSrc, src[ is valid UTF-8.
+        // We do not see invalid UTF-8 here because
+        // its norm16==INERT is normalization-inert,
+        // so it gets copied unchanged in the fast path,
+        // and we stop the slow path where invalid UTF-8 begins.
+        U_ASSERT(norm16 != INERT);
+        if (norm16 < minYesNo) {
+            if (c < 0) {
+                c = codePointFromValidUTF8(prevSrc, src);
+            }
+            // does not decompose
+            if (!buffer.append(c, 0, errorCode)) {
+                return nullptr;
+            }
+        } else if (isHangulLV(norm16) || isHangulLVT(norm16)) {
+            // Hangul syllable: decompose algorithmically
+            if (c < 0) {
+                c = codePointFromValidUTF8(prevSrc, src);
+            }
+            char16_t jamos[3];
+            if (!buffer.appendZeroCC(jamos, jamos+Hangul::decompose(c, jamos), errorCode)) {
+                return nullptr;
+            }
+        } else {
+            // The character decomposes, get everything from the variable-length extra data.
+            const uint16_t *mapping = getMapping(norm16);
+            uint16_t firstUnit = *mapping;
+            int32_t length = firstUnit & MAPPING_LENGTH_MASK;
+            uint8_t trailCC = (uint8_t)(firstUnit >> 8);
+            uint8_t leadCC;
+            if (firstUnit & MAPPING_HAS_CCC_LCCC_WORD) {
+                leadCC = (uint8_t)(*(mapping-1) >> 8);
+            } else {
+                leadCC = 0;
+            }
+            if (!buffer.append((const char16_t *)mapping+1, length, TRUE, leadCC, trailCC, errorCode)) {
+                return nullptr;
+            }
+        }
+        if (stopAtCompBoundary && norm16HasCompBoundaryAfter(norm16, onlyContiguous)) {
+            return src;
         }
     }
+    return src;
 }
 
 const UChar *
 Normalizer2Impl::getDecomposition(UChar32 c, UChar buffer[4], int32_t &length) const {
-    const UChar *decomp=NULL;
     uint16_t norm16;
-    for(;;) {
-        if(c<minDecompNoCP || isDecompYes(norm16=getNorm16(c))) {
-            // c does not decompose
-            return decomp;
-        } else if(isHangul(norm16)) {
-            // Hangul syllable: decompose algorithmically
-            length=Hangul::decompose(c, buffer);
-            return buffer;
-        } else if(isDecompNoAlgorithmic(norm16)) {
-            c=mapAlgorithmic(c, norm16);
-            decomp=buffer;
-            length=0;
-            U16_APPEND_UNSAFE(buffer, length, c);
-        } else {
-            // c decomposes, get everything from the variable-length extra data
-            const uint16_t *mapping=getMapping(norm16);
-            length=*mapping&MAPPING_LENGTH_MASK;
-            return (const UChar *)mapping+1;
-        }
+    if(c<minDecompNoCP || isMaybeOrNonZeroCC(norm16=getNorm16(c))) {
+        // c does not decompose
+        return nullptr;
     }
+    const UChar *decomp = nullptr;
+    if(isDecompNoAlgorithmic(norm16)) {
+        // Maps to an isCompYesAndZeroCC.
+        c=mapAlgorithmic(c, norm16);
+        decomp=buffer;
+        length=0;
+        U16_APPEND_UNSAFE(buffer, length, c);
+        // The mapping might decompose further.
+        norm16 = getRawNorm16(c);
+    }
+    if (norm16 < minYesNo) {
+        return decomp;
+    } else if(isHangulLV(norm16) || isHangulLVT(norm16)) {
+        // Hangul syllable: decompose algorithmically
+        length=Hangul::decompose(c, buffer);
+        return buffer;
+    }
+    // c decomposes, get everything from the variable-length extra data
+    const uint16_t *mapping=getMapping(norm16);
+    length=*mapping&MAPPING_LENGTH_MASK;
+    return (const UChar *)mapping+1;
 }
 
 // The capacity of the buffer must be 30=MAPPING_LENGTH_MASK-1
@@ -647,13 +849,11 @@
 // The maximum length of a normal mapping is 31=MAPPING_LENGTH_MASK.
 const UChar *
 Normalizer2Impl::getRawDecomposition(UChar32 c, UChar buffer[30], int32_t &length) const {
-    // We do not loop in this method because an algorithmic mapping itself
-    // becomes a final result rather than having to be decomposed recursively.
     uint16_t norm16;
     if(c<minDecompNoCP || isDecompYes(norm16=getNorm16(c))) {
         // c does not decompose
         return NULL;
-    } else if(isHangul(norm16)) {
+    } else if(isHangulLV(norm16) || isHangulLVT(norm16)) {
         // Hangul syllable: decompose algorithmically
         Hangul::getRawDecomposition(c, buffer);
         length=2;
@@ -663,30 +863,29 @@
         length=0;
         U16_APPEND_UNSAFE(buffer, length, c);
         return buffer;
-    } else {
-        // c decomposes, get everything from the variable-length extra data
-        const uint16_t *mapping=getMapping(norm16);
-        uint16_t firstUnit=*mapping;
-        int32_t mLength=firstUnit&MAPPING_LENGTH_MASK;  // length of normal mapping
-        if(firstUnit&MAPPING_HAS_RAW_MAPPING) {
-            // Read the raw mapping from before the firstUnit and before the optional ccc/lccc word.
-            // Bit 7=MAPPING_HAS_CCC_LCCC_WORD
-            const uint16_t *rawMapping=mapping-((firstUnit>>7)&1)-1;
-            uint16_t rm0=*rawMapping;
-            if(rm0<=MAPPING_LENGTH_MASK) {
-                length=rm0;
-                return (const UChar *)rawMapping-rm0;
-            } else {
-                // Copy the normal mapping and replace its first two code units with rm0.
-                buffer[0]=(UChar)rm0;
-                u_memcpy(buffer+1, (const UChar *)mapping+1+2, mLength-2);
-                length=mLength-1;
-                return buffer;
-            }
+    }
+    // c decomposes, get everything from the variable-length extra data
+    const uint16_t *mapping=getMapping(norm16);
+    uint16_t firstUnit=*mapping;
+    int32_t mLength=firstUnit&MAPPING_LENGTH_MASK;  // length of normal mapping
+    if(firstUnit&MAPPING_HAS_RAW_MAPPING) {
+        // Read the raw mapping from before the firstUnit and before the optional ccc/lccc word.
+        // Bit 7=MAPPING_HAS_CCC_LCCC_WORD
+        const uint16_t *rawMapping=mapping-((firstUnit>>7)&1)-1;
+        uint16_t rm0=*rawMapping;
+        if(rm0<=MAPPING_LENGTH_MASK) {
+            length=rm0;
+            return (const UChar *)rawMapping-rm0;
         } else {
-            length=mLength;
-            return (const UChar *)mapping+1;
+            // Copy the normal mapping and replace its first two code units with rm0.
+            buffer[0]=(UChar)rm0;
+            u_memcpy(buffer+1, (const UChar *)mapping+1+2, mLength-2);
+            length=mLength-1;
+            return buffer;
         }
+    } else {
+        length=mLength;
+        return (const UChar *)mapping+1;
     }
 }
 
@@ -701,59 +900,87 @@
         return;
     }
     // Just merge the strings at the boundary.
-    ForwardUTrie2StringIterator iter(normTrie, src, limit);
-    uint8_t firstCC, prevCC, cc;
-    firstCC=prevCC=cc=getCC(iter.next16());
-    while(cc!=0) {
-        prevCC=cc;
-        cc=getCC(iter.next16());
-    };
+    bool isFirst = true;
+    uint8_t firstCC = 0, prevCC = 0, cc;
+    const UChar *p = src;
+    while (p != limit) {
+        const UChar *codePointStart = p;
+        UChar32 c;
+        uint16_t norm16;
+        UCPTRIE_FAST_U16_NEXT(normTrie, UCPTRIE_16, p, limit, c, norm16);
+        if ((cc = getCC(norm16)) == 0) {
+            p = codePointStart;
+            break;
+        }
+        if (isFirst) {
+            firstCC = cc;
+            isFirst = false;
+        }
+        prevCC = cc;
+    }
     if(limit==NULL) {  // appendZeroCC() needs limit!=NULL
-        limit=u_strchr(iter.codePointStart, 0);
+        limit=u_strchr(p, 0);
     }
 
-    if (buffer.append(src, (int32_t)(iter.codePointStart-src), firstCC, prevCC, errorCode)) {
-        buffer.appendZeroCC(iter.codePointStart, limit, errorCode);
+    if (buffer.append(src, (int32_t)(p - src), FALSE, firstCC, prevCC, errorCode)) {
+        buffer.appendZeroCC(p, limit, errorCode);
     }
 }
 
-// Note: hasDecompBoundary() could be implemented as aliases to
-// hasFCDBoundaryBefore() and hasFCDBoundaryAfter()
-// at the cost of building the FCD trie for a decomposition normalizer.
-UBool Normalizer2Impl::hasDecompBoundary(UChar32 c, UBool before) const {
-    for(;;) {
-        if(c<minDecompNoCP) {
-            return TRUE;
-        }
-        uint16_t norm16=getNorm16(c);
-        if(isHangul(norm16) || isDecompYesAndZeroCC(norm16)) {
-            return TRUE;
-        } else if(norm16>MIN_NORMAL_MAYBE_YES) {
-            return FALSE;  // ccc!=0
-        } else if(isDecompNoAlgorithmic(norm16)) {
-            c=mapAlgorithmic(c, norm16);
-        } else {
-            // c decomposes, get everything from the variable-length extra data
-            const uint16_t *mapping=getMapping(norm16);
-            uint16_t firstUnit=*mapping;
-            if((firstUnit&MAPPING_LENGTH_MASK)==0) {
-                return FALSE;
-            }
-            if(!before) {
-                // decomp after-boundary: same as hasFCDBoundaryAfter(),
-                // fcd16<=1 || trailCC==0
-                if(firstUnit>0x1ff) {
-                    return FALSE;  // trailCC>1
-                }
-                if(firstUnit<=0xff) {
-                    return TRUE;  // trailCC==0
-                }
-                // if(trailCC==1) test leadCC==0, same as checking for before-boundary
-            }
-            // TRUE if leadCC==0 (hasFCDBoundaryBefore())
-            return (firstUnit&MAPPING_HAS_CCC_LCCC_WORD)==0 || (*(mapping-1)&0xff00)==0;
-        }
+UBool Normalizer2Impl::hasDecompBoundaryBefore(UChar32 c) const {
+    return c < minLcccCP || (c <= 0xffff && !singleLeadMightHaveNonZeroFCD16(c)) ||
+        norm16HasDecompBoundaryBefore(getNorm16(c));
+}
+
+UBool Normalizer2Impl::norm16HasDecompBoundaryBefore(uint16_t norm16) const {
+    if (norm16 < minNoNoCompNoMaybeCC) {
+        return TRUE;
     }
+    if (norm16 >= limitNoNo) {
+        return norm16 <= MIN_NORMAL_MAYBE_YES || norm16 == JAMO_VT;
+    }
+    // c decomposes, get everything from the variable-length extra data
+    const uint16_t *mapping=getMapping(norm16);
+    uint16_t firstUnit=*mapping;
+    // TRUE if leadCC==0 (hasFCDBoundaryBefore())
+    return (firstUnit&MAPPING_HAS_CCC_LCCC_WORD)==0 || (*(mapping-1)&0xff00)==0;
+}
+
+UBool Normalizer2Impl::hasDecompBoundaryAfter(UChar32 c) const {
+    if (c < minDecompNoCP) {
+        return TRUE;
+    }
+    if (c <= 0xffff && !singleLeadMightHaveNonZeroFCD16(c)) {
+        return TRUE;
+    }
+    return norm16HasDecompBoundaryAfter(getNorm16(c));
+}
+
+UBool Normalizer2Impl::norm16HasDecompBoundaryAfter(uint16_t norm16) const {
+    if(norm16 <= minYesNo || isHangulLVT(norm16)) {
+        return TRUE;
+    }
+    if (norm16 >= limitNoNo) {
+        if (isMaybeOrNonZeroCC(norm16)) {
+            return norm16 <= MIN_NORMAL_MAYBE_YES || norm16 == JAMO_VT;
+        }
+        // Maps to an isCompYesAndZeroCC.
+        return (norm16 & DELTA_TCCC_MASK) <= DELTA_TCCC_1;
+    }
+    // c decomposes, get everything from the variable-length extra data
+    const uint16_t *mapping=getMapping(norm16);
+    uint16_t firstUnit=*mapping;
+    // decomp after-boundary: same as hasFCDBoundaryAfter(),
+    // fcd16<=1 || trailCC==0
+    if(firstUnit>0x1ff) {
+        return FALSE;  // trailCC>1
+    }
+    if(firstUnit<=0xff) {
+        return TRUE;  // trailCC==0
+    }
+    // if(trailCC==1) test leadCC==0, same as checking for before-boundary
+    // TRUE if leadCC==0 (hasFCDBoundaryBefore())
+    return (firstUnit&MAPPING_HAS_CCC_LCCC_WORD)==0 || (*(mapping-1)&0xff00)==0;
 }
 
 /*
@@ -843,7 +1070,7 @@
         }
         UChar32 composite=compositeAndFwd>>1;
         if((compositeAndFwd&1)!=0) {
-            addComposites(getCompositionsListForComposite(getNorm16(composite)), set);
+            addComposites(getCompositionsListForComposite(getRawNorm16(composite)), set);
         }
         set.add(composite);
     } while((firstUnit&COMP_1_LAST_TUPLE)==0);
@@ -882,7 +1109,7 @@
     prevCC=0;
 
     for(;;) {
-        UTRIE2_U16_NEXT16(normTrie, p, limit, c, norm16);
+        UCPTRIE_FAST_U16_NEXT(normTrie, UCPTRIE_16, p, limit, c, norm16);
         cc=getCCFromYesOrMaybe(norm16);
         if( // this character combines backward and
             isMaybe(norm16) &&
@@ -987,7 +1214,7 @@
                 // Is the composite a starter that combines forward?
                 if(compositeAndFwd&1) {
                     compositionsList=
-                        getCompositionsListForComposite(getNorm16(composite));
+                        getCompositionsListForComposite(getRawNorm16(composite));
                 } else {
                     compositionsList=NULL;
                 }
@@ -1026,11 +1253,12 @@
 
 UChar32
 Normalizer2Impl::composePair(UChar32 a, UChar32 b) const {
-    uint16_t norm16=getNorm16(a);  // maps an out-of-range 'a' to inert norm16=0
+    uint16_t norm16=getNorm16(a);  // maps an out-of-range 'a' to inert norm16
     const uint16_t *list;
     if(isInert(norm16)) {
         return U_SENTINEL;
     } else if(norm16<minYesNoMappingsOnly) {
+        // a combines forward.
         if(isJamoL(norm16)) {
             b-=Hangul::JAMO_V_BASE;
             if(0<=b && b<Hangul::JAMO_V_COUNT) {
@@ -1041,26 +1269,26 @@
             } else {
                 return U_SENTINEL;
             }
-        } else if(isHangul(norm16)) {
+        } else if(isHangulLV(norm16)) {
             b-=Hangul::JAMO_T_BASE;
-            if(Hangul::isHangulWithoutJamoT(a) && 0<b && b<Hangul::JAMO_T_COUNT) {  // not b==0!
+            if(0<b && b<Hangul::JAMO_T_COUNT) {  // not b==0!
                 return a+b;
             } else {
                 return U_SENTINEL;
             }
         } else {
             // 'a' has a compositions list in extraData
-            list=extraData+norm16;
+            list=getMapping(norm16);
             if(norm16>minYesNo) {  // composite 'a' has both mapping & compositions list
                 list+=  // mapping pointer
-                    1+  // +1 to skip the first unit with the mapping lenth
+                    1+  // +1 to skip the first unit with the mapping length
                     (*list&MAPPING_LENGTH_MASK);  // + mapping length
             }
         }
     } else if(norm16<minMaybeYes || MIN_NORMAL_MAYBE_YES<=norm16) {
         return U_SENTINEL;
     } else {
-        list=maybeYesCompositions+norm16-minMaybeYes;
+        list=getCompositionsListForMaybe(norm16);
     }
     if(b<0 || 0x10ffff<b) {  // combine(list, b) requires a valid code point b
         return U_SENTINEL;
@@ -1082,18 +1310,6 @@
                          UBool doCompose,
                          ReorderingBuffer &buffer,
                          UErrorCode &errorCode) const {
-    /*
-     * prevBoundary points to the last character before the current one
-     * that has a composition boundary before it with ccc==0 and quick check "yes".
-     * Keeping track of prevBoundary saves us looking for a composition boundary
-     * when we find a "no" or "maybe".
-     *
-     * When we back out from prevSrc back to prevBoundary,
-     * then we also remove those same characters (which had been simply copied
-     * or canonically-order-inserted) from the ReorderingBuffer.
-     * Therefore, at all times, the [prevBoundary..prevSrc[ source units
-     * must correspond 1:1 to destination units at the end of the destination buffer.
-     */
     const UChar *prevBoundary=src;
     UChar32 minNoMaybeCP=minCompNoMaybeCP;
     if(limit==NULL) {
@@ -1103,231 +1319,254 @@
         if(U_FAILURE(errorCode)) {
             return FALSE;
         }
-        if(prevBoundary<src) {
-            // Set prevBoundary to the last character in the prefix.
-            prevBoundary=src-1;
-        }
         limit=u_strchr(src, 0);
+        if (prevBoundary != src) {
+            if (hasCompBoundaryAfter(*(src-1), onlyContiguous)) {
+                prevBoundary = src;
+            } else {
+                buffer.removeSuffix(1);
+                prevBoundary = --src;
+            }
+        }
     }
 
-    const UChar *prevSrc;
-    UChar32 c=0;
-    uint16_t norm16=0;
-
-    // only for isNormalized
-    uint8_t prevCC=0;
-
-    for(;;) {
-        // count code units below the minimum or with irrelevant data for the quick check
-        for(prevSrc=src; src!=limit;) {
+    for (;;) {
+        // Fast path: Scan over a sequence of characters below the minimum "no or maybe" code point,
+        // or with (compYes && ccc==0) properties.
+        const UChar *prevSrc;
+        UChar32 c = 0;
+        uint16_t norm16 = 0;
+        for (;;) {
+            if (src == limit) {
+                if (prevBoundary != limit && doCompose) {
+                    buffer.appendZeroCC(prevBoundary, limit, errorCode);
+                }
+                return TRUE;
+            }
             if( (c=*src)<minNoMaybeCP ||
-                isCompYesAndZeroCC(norm16=UTRIE2_GET16_FROM_U16_SINGLE_LEAD(normTrie, c))
+                isCompYesAndZeroCC(norm16=UCPTRIE_FAST_BMP_GET(normTrie, UCPTRIE_16, c))
             ) {
                 ++src;
-            } else if(!U16_IS_SURROGATE(c)) {
-                break;
             } else {
-                UChar c2;
-                if(U16_IS_SURROGATE_LEAD(c)) {
-                    if((src+1)!=limit && U16_IS_TRAIL(c2=src[1])) {
-                        c=U16_GET_SUPPLEMENTARY(c, c2);
-                    }
-                } else /* trail surrogate */ {
-                    if(prevSrc<src && U16_IS_LEAD(c2=*(src-1))) {
-                        --src;
-                        c=U16_GET_SUPPLEMENTARY(c2, c);
-                    }
-                }
-                if(isCompYesAndZeroCC(norm16=getNorm16(c))) {
-                    src+=U16_LENGTH(c);
+                prevSrc = src++;
+                if(!U16_IS_LEAD(c)) {
+                    break;
                 } else {
-                    break;
+                    UChar c2;
+                    if(src!=limit && U16_IS_TRAIL(c2=*src)) {
+                        ++src;
+                        c=U16_GET_SUPPLEMENTARY(c, c2);
+                        norm16=UCPTRIE_FAST_SUPP_GET(normTrie, UCPTRIE_16, c);
+                        if(!isCompYesAndZeroCC(norm16)) {
+                            break;
+                        }
+                    }
                 }
             }
         }
-        // copy these code units all at once
-        if(src!=prevSrc) {
-            if(doCompose) {
-                if(!buffer.appendZeroCC(prevSrc, src, errorCode)) {
-                    break;
-                }
-            } else {
-                prevCC=0;
-            }
-            if(src==limit) {
-                break;
-            }
-            // Set prevBoundary to the last character in the quick check loop.
-            prevBoundary=src-1;
-            if( U16_IS_TRAIL(*prevBoundary) && prevSrc<prevBoundary &&
-                U16_IS_LEAD(*(prevBoundary-1))
-            ) {
-                --prevBoundary;
-            }
-            // The start of the current character (c).
-            prevSrc=src;
-        } else if(src==limit) {
-            break;
-        }
+        // isCompYesAndZeroCC(norm16) is false, that is, norm16>=minNoNo.
+        // The current character is either a "noNo" (has a mapping)
+        // or a "maybeYes" (combines backward)
+        // or a "yesYes" with ccc!=0.
+        // It is not a Hangul syllable or Jamo L because those have "yes" properties.
 
-        src+=U16_LENGTH(c);
-        /*
-         * isCompYesAndZeroCC(norm16) is false, that is, norm16>=minNoNo.
-         * c is either a "noNo" (has a mapping) or a "maybeYes" (combines backward)
-         * or has ccc!=0.
-         * Check for Jamo V/T, then for regular characters.
-         * c is not a Hangul syllable or Jamo L because those have "yes" properties.
-         */
-        if(isJamoVT(norm16) && prevBoundary!=prevSrc) {
+        // Medium-fast path: Handle cases that do not require full decomposition and recomposition.
+        if (!isMaybeOrNonZeroCC(norm16)) {  // minNoNo <= norm16 < minMaybeYes
+            if (!doCompose) {
+                return FALSE;
+            }
+            // Fast path for mapping a character that is immediately surrounded by boundaries.
+            // In this case, we need not decompose around the current character.
+            if (isDecompNoAlgorithmic(norm16)) {
+                // Maps to a single isCompYesAndZeroCC character
+                // which also implies hasCompBoundaryBefore.
+                if (norm16HasCompBoundaryAfter(norm16, onlyContiguous) ||
+                        hasCompBoundaryBefore(src, limit)) {
+                    if (prevBoundary != prevSrc && !buffer.appendZeroCC(prevBoundary, prevSrc, errorCode)) {
+                        break;
+                    }
+                    if(!buffer.append(mapAlgorithmic(c, norm16), 0, errorCode)) {
+                        break;
+                    }
+                    prevBoundary = src;
+                    continue;
+                }
+            } else if (norm16 < minNoNoCompBoundaryBefore) {
+                // The mapping is comp-normalized which also implies hasCompBoundaryBefore.
+                if (norm16HasCompBoundaryAfter(norm16, onlyContiguous) ||
+                        hasCompBoundaryBefore(src, limit)) {
+                    if (prevBoundary != prevSrc && !buffer.appendZeroCC(prevBoundary, prevSrc, errorCode)) {
+                        break;
+                    }
+                    const UChar *mapping = reinterpret_cast<const UChar *>(getMapping(norm16));
+                    int32_t length = *mapping++ & MAPPING_LENGTH_MASK;
+                    if(!buffer.appendZeroCC(mapping, mapping + length, errorCode)) {
+                        break;
+                    }
+                    prevBoundary = src;
+                    continue;
+                }
+            } else if (norm16 >= minNoNoEmpty) {
+                // The current character maps to nothing.
+                // Simply omit it from the output if there is a boundary before _or_ after it.
+                // The character itself implies no boundaries.
+                if (hasCompBoundaryBefore(src, limit) ||
+                        hasCompBoundaryAfter(prevBoundary, prevSrc, onlyContiguous)) {
+                    if (prevBoundary != prevSrc && !buffer.appendZeroCC(prevBoundary, prevSrc, errorCode)) {
+                        break;
+                    }
+                    prevBoundary = src;
+                    continue;
+                }
+            }
+            // Other "noNo" type, or need to examine more text around this character:
+            // Fall through to the slow path.
+        } else if (isJamoVT(norm16) && prevBoundary != prevSrc) {
             UChar prev=*(prevSrc-1);
-            UBool needToDecompose=FALSE;
             if(c<Hangul::JAMO_T_BASE) {
-                // c is a Jamo Vowel, compose with previous Jamo L and following Jamo T.
-                prev=(UChar)(prev-Hangul::JAMO_L_BASE);
-                if(prev<Hangul::JAMO_L_COUNT) {
-                    if(!doCompose) {
+                // The current character is a Jamo Vowel,
+                // compose with previous Jamo L and following Jamo T.
+                UChar l = (UChar)(prev-Hangul::JAMO_L_BASE);
+                if(l<Hangul::JAMO_L_COUNT) {
+                    if (!doCompose) {
                         return FALSE;
                     }
-                    UChar syllable=(UChar)
-                        (Hangul::HANGUL_BASE+
-                         (prev*Hangul::JAMO_V_COUNT+(c-Hangul::JAMO_V_BASE))*
-                         Hangul::JAMO_T_COUNT);
-                    UChar t;
-                    if(src!=limit && (t=(UChar)(*src-Hangul::JAMO_T_BASE))<Hangul::JAMO_T_COUNT) {
+                    int32_t t;
+                    if (src != limit &&
+                            0 < (t = ((int32_t)*src - Hangul::JAMO_T_BASE)) &&
+                            t < Hangul::JAMO_T_COUNT) {
+                        // The next character is a Jamo T.
                         ++src;
-                        syllable+=t;  // The next character was a Jamo T.
-                        prevBoundary=src;
-                        buffer.setLastChar(syllable);
+                    } else if (hasCompBoundaryBefore(src, limit)) {
+                        // No Jamo T follows, not even via decomposition.
+                        t = 0;
+                    } else {
+                        t = -1;
+                    }
+                    if (t >= 0) {
+                        UChar32 syllable = Hangul::HANGUL_BASE +
+                            (l*Hangul::JAMO_V_COUNT + (c-Hangul::JAMO_V_BASE)) *
+                            Hangul::JAMO_T_COUNT + t;
+                        --prevSrc;  // Replace the Jamo L as well.
+                        if (prevBoundary != prevSrc && !buffer.appendZeroCC(prevBoundary, prevSrc, errorCode)) {
+                            break;
+                        }
+                        if(!buffer.appendBMP((UChar)syllable, 0, errorCode)) {
+                            break;
+                        }
+                        prevBoundary = src;
                         continue;
                     }
                     // If we see L+V+x where x!=T then we drop to the slow path,
                     // decompose and recompose.
                     // This is to deal with NFKC finding normal L and V but a
-                    // compatibility variant of a T. We need to either fully compose that
-                    // combination here (which would complicate the code and may not work
-                    // with strange custom data) or use the slow path -- or else our replacing
-                    // two input characters (L+V) with one output character (LV syllable)
-                    // would violate the invariant that [prevBoundary..prevSrc[ has the same
-                    // length as what we appended to the buffer since prevBoundary.
-                    needToDecompose=TRUE;
+                    // compatibility variant of a T.
+                    // We need to either fully compose that combination here
+                    // (which would complicate the code and may not work with strange custom data)
+                    // or use the slow path.
                 }
-            } else if(Hangul::isHangulWithoutJamoT(prev)) {
-                // c is a Jamo Trailing consonant,
+            } else if (Hangul::isHangulLV(prev)) {
+                // The current character is a Jamo Trailing consonant,
                 // compose with previous Hangul LV that does not contain a Jamo T.
-                if(!doCompose) {
+                if (!doCompose) {
                     return FALSE;
                 }
-                buffer.setLastChar((UChar)(prev+c-Hangul::JAMO_T_BASE));
-                prevBoundary=src;
-                continue;
-            }
-            if(!needToDecompose) {
-                // The Jamo V/T did not compose into a Hangul syllable.
-                if(doCompose) {
-                    if(!buffer.appendBMP((UChar)c, 0, errorCode)) {
-                        break;
-                    }
-                } else {
-                    prevCC=0;
-                }
-                continue;
-            }
-        }
-        /*
-         * Source buffer pointers:
-         *
-         *  all done      quick check   current char  not yet
-         *                "yes" but     (c)           processed
-         *                may combine
-         *                forward
-         * [-------------[-------------[-------------[-------------[
-         * |             |             |             |             |
-         * orig. src     prevBoundary  prevSrc       src           limit
-         *
-         *
-         * Destination buffer pointers inside the ReorderingBuffer:
-         *
-         *  all done      might take    not filled yet
-         *                characters for
-         *                reordering
-         * [-------------[-------------[-------------[
-         * |             |             |             |
-         * start         reorderStart  limit         |
-         *                             +remainingCap.+
-         */
-        if(norm16>=MIN_YES_YES_WITH_CC) {
-            uint8_t cc=(uint8_t)norm16;  // cc!=0
-            if( onlyContiguous &&  // FCC
-                (doCompose ? buffer.getLastCC() : prevCC)==0 &&
-                prevBoundary<prevSrc &&
-                // buffer.getLastCC()==0 && prevBoundary<prevSrc tell us that
-                // [prevBoundary..prevSrc[ (which is exactly one character under these conditions)
-                // passed the quick check "yes && ccc==0" test.
-                // Check whether the last character was a "yesYes" or a "yesNo".
-                // If a "yesNo", then we get its trailing ccc from its
-                // mapping and check for canonical order.
-                // All other cases are ok.
-                getTrailCCFromCompYesAndZeroCC(prevBoundary, prevSrc)>cc
-            ) {
-                // Fails FCD test, need to decompose and contiguously recompose.
-                if(!doCompose) {
-                    return FALSE;
-                }
-            } else if(doCompose) {
-                if(!buffer.append(c, cc, errorCode)) {
+                UChar32 syllable = prev + c - Hangul::JAMO_T_BASE;
+                --prevSrc;  // Replace the Hangul LV as well.
+                if (prevBoundary != prevSrc && !buffer.appendZeroCC(prevBoundary, prevSrc, errorCode)) {
                     break;
                 }
+                if(!buffer.appendBMP((UChar)syllable, 0, errorCode)) {
+                    break;
+                }
+                prevBoundary = src;
                 continue;
-            } else if(prevCC<=cc) {
-                prevCC=cc;
-                continue;
-            } else {
-                return FALSE;
             }
-        } else if(!doCompose && !isMaybeOrNonZeroCC(norm16)) {
-            return FALSE;
+            // No matching context, or may need to decompose surrounding text first:
+            // Fall through to the slow path.
+        } else if (norm16 > JAMO_VT) {  // norm16 >= MIN_YES_YES_WITH_CC
+            // One or more combining marks that do not combine-back:
+            // Check for canonical order, copy unchanged if ok and
+            // if followed by a character with a boundary-before.
+            uint8_t cc = getCCFromNormalYesOrMaybe(norm16);  // cc!=0
+            if (onlyContiguous /* FCC */ && getPreviousTrailCC(prevBoundary, prevSrc) > cc) {
+                // Fails FCD test, need to decompose and contiguously recompose.
+                if (!doCompose) {
+                    return FALSE;
+                }
+            } else {
+                // If !onlyContiguous (not FCC), then we ignore the tccc of
+                // the previous character which passed the quick check "yes && ccc==0" test.
+                const UChar *nextSrc;
+                uint16_t n16;
+                for (;;) {
+                    if (src == limit) {
+                        if (doCompose) {
+                            buffer.appendZeroCC(prevBoundary, limit, errorCode);
+                        }
+                        return TRUE;
+                    }
+                    uint8_t prevCC = cc;
+                    nextSrc = src;
+                    UCPTRIE_FAST_U16_NEXT(normTrie, UCPTRIE_16, nextSrc, limit, c, n16);
+                    if (n16 >= MIN_YES_YES_WITH_CC) {
+                        cc = getCCFromNormalYesOrMaybe(n16);
+                        if (prevCC > cc) {
+                            if (!doCompose) {
+                                return FALSE;
+                            }
+                            break;
+                        }
+                    } else {
+                        break;
+                    }
+                    src = nextSrc;
+                }
+                // src is after the last in-order combining mark.
+                // If there is a boundary here, then we continue with no change.
+                if (norm16HasCompBoundaryBefore(n16)) {
+                    if (isCompYesAndZeroCC(n16)) {
+                        src = nextSrc;
+                    }
+                    continue;
+                }
+                // Use the slow path. There is no boundary in [prevSrc, src[.
+            }
         }
 
-        /*
-         * Find appropriate boundaries around this character,
-         * decompose the source text from between the boundaries,
-         * and recompose it.
-         *
-         * We may need to remove the last few characters from the ReorderingBuffer
-         * to account for source text that was copied or appended
-         * but needs to take part in the recomposition.
-         */
-
-        /*
-         * Find the last composition boundary in [prevBoundary..src[.
-         * It is either the decomposition of the current character (at prevSrc),
-         * or prevBoundary.
-         */
-        if(hasCompBoundaryBefore(c, norm16)) {
-            prevBoundary=prevSrc;
-        } else if(doCompose) {
-            buffer.removeSuffix((int32_t)(prevSrc-prevBoundary));
+        // Slow path: Find the nearest boundaries around the current character,
+        // decompose and recompose.
+        if (prevBoundary != prevSrc && !norm16HasCompBoundaryBefore(norm16)) {
+            const UChar *p = prevSrc;
+            UCPTRIE_FAST_U16_PREV(normTrie, UCPTRIE_16, prevBoundary, p, c, norm16);
+            if (!norm16HasCompBoundaryAfter(norm16, onlyContiguous)) {
+                prevSrc = p;
+            }
         }
-
-        // Find the next composition boundary in [src..limit[ -
-        // modifies src to point to the next starter.
-        src=(UChar *)findNextCompBoundary(src, limit);
-
-        // Decompose [prevBoundary..src[ into the buffer and then recompose that part of it.
-        int32_t recomposeStartIndex=buffer.length();
-        if(!decomposeShort(prevBoundary, src, buffer, errorCode)) {
+        if (doCompose && prevBoundary != prevSrc && !buffer.appendZeroCC(prevBoundary, prevSrc, errorCode)) {
             break;
         }
+        int32_t recomposeStartIndex=buffer.length();
+        // We know there is not a boundary here.
+        decomposeShort(prevSrc, src, FALSE /* !stopAtCompBoundary */, onlyContiguous,
+                       buffer, errorCode);
+        // Decompose until the next boundary.
+        src = decomposeShort(src, limit, TRUE /* stopAtCompBoundary */, onlyContiguous,
+                             buffer, errorCode);
+        if (U_FAILURE(errorCode)) {
+            break;
+        }
+        if ((src - prevSrc) > INT32_MAX) {  // guard before buffer.equals()
+            errorCode = U_INDEX_OUTOFBOUNDS_ERROR;
+            return TRUE;
+        }
         recompose(buffer, recomposeStartIndex, onlyContiguous);
         if(!doCompose) {
-            if(!buffer.equals(prevBoundary, src)) {
+            if(!buffer.equals(prevSrc, src)) {
                 return FALSE;
             }
             buffer.remove();
-            prevCC=0;
         }
-
-        // Move to the next starter. We never need to look back before this point again.
         prevBoundary=src;
     }
     return TRUE;
@@ -1340,103 +1579,116 @@
 Normalizer2Impl::composeQuickCheck(const UChar *src, const UChar *limit,
                                    UBool onlyContiguous,
                                    UNormalizationCheckResult *pQCResult) const {
-    /*
-     * prevBoundary points to the last character before the current one
-     * that has a composition boundary before it with ccc==0 and quick check "yes".
-     */
     const UChar *prevBoundary=src;
     UChar32 minNoMaybeCP=minCompNoMaybeCP;
     if(limit==NULL) {
         UErrorCode errorCode=U_ZERO_ERROR;
         src=copyLowPrefixFromNulTerminated(src, minNoMaybeCP, NULL, errorCode);
-        if(prevBoundary<src) {
-            // Set prevBoundary to the last character in the prefix.
-            prevBoundary=src-1;
-        }
         limit=u_strchr(src, 0);
+        if (prevBoundary != src) {
+            if (hasCompBoundaryAfter(*(src-1), onlyContiguous)) {
+                prevBoundary = src;
+            } else {
+                prevBoundary = --src;
+            }
+        }
     }
 
-    const UChar *prevSrc;
-    UChar32 c=0;
-    uint16_t norm16=0;
-    uint8_t prevCC=0;
-
     for(;;) {
-        // count code units below the minimum or with irrelevant data for the quick check
-        for(prevSrc=src;;) {
+        // Fast path: Scan over a sequence of characters below the minimum "no or maybe" code point,
+        // or with (compYes && ccc==0) properties.
+        const UChar *prevSrc;
+        UChar32 c = 0;
+        uint16_t norm16 = 0;
+        for (;;) {
             if(src==limit) {
                 return src;
             }
             if( (c=*src)<minNoMaybeCP ||
-                isCompYesAndZeroCC(norm16=UTRIE2_GET16_FROM_U16_SINGLE_LEAD(normTrie, c))
+                isCompYesAndZeroCC(norm16=UCPTRIE_FAST_BMP_GET(normTrie, UCPTRIE_16, c))
             ) {
                 ++src;
-            } else if(!U16_IS_SURROGATE(c)) {
-                break;
             } else {
-                UChar c2;
-                if(U16_IS_SURROGATE_LEAD(c)) {
-                    if((src+1)!=limit && U16_IS_TRAIL(c2=src[1])) {
-                        c=U16_GET_SUPPLEMENTARY(c, c2);
-                    }
-                } else /* trail surrogate */ {
-                    if(prevSrc<src && U16_IS_LEAD(c2=*(src-1))) {
-                        --src;
-                        c=U16_GET_SUPPLEMENTARY(c2, c);
-                    }
-                }
-                if(isCompYesAndZeroCC(norm16=getNorm16(c))) {
-                    src+=U16_LENGTH(c);
-                } else {
+                prevSrc = src++;
+                if(!U16_IS_LEAD(c)) {
                     break;
+                } else {
+                    UChar c2;
+                    if(src!=limit && U16_IS_TRAIL(c2=*src)) {
+                        ++src;
+                        c=U16_GET_SUPPLEMENTARY(c, c2);
+                        norm16=UCPTRIE_FAST_SUPP_GET(normTrie, UCPTRIE_16, c);
+                        if(!isCompYesAndZeroCC(norm16)) {
+                            break;
+                        }
+                    }
                 }
             }
         }
-        if(src!=prevSrc) {
-            // Set prevBoundary to the last character in the quick check loop.
-            prevBoundary=src-1;
-            if( U16_IS_TRAIL(*prevBoundary) && prevSrc<prevBoundary &&
-                U16_IS_LEAD(*(prevBoundary-1))
-            ) {
-                --prevBoundary;
+        // isCompYesAndZeroCC(norm16) is false, that is, norm16>=minNoNo.
+        // The current character is either a "noNo" (has a mapping)
+        // or a "maybeYes" (combines backward)
+        // or a "yesYes" with ccc!=0.
+        // It is not a Hangul syllable or Jamo L because those have "yes" properties.
+
+        uint16_t prevNorm16 = INERT;
+        if (prevBoundary != prevSrc) {
+            if (norm16HasCompBoundaryBefore(norm16)) {
+                prevBoundary = prevSrc;
+            } else {
+                const UChar *p = prevSrc;
+                uint16_t n16;
+                UCPTRIE_FAST_U16_PREV(normTrie, UCPTRIE_16, prevBoundary, p, c, n16);
+                if (norm16HasCompBoundaryAfter(n16, onlyContiguous)) {
+                    prevBoundary = prevSrc;
+                } else {
+                    prevBoundary = p;
+                    prevNorm16 = n16;
+                }
             }
-            prevCC=0;
-            // The start of the current character (c).
-            prevSrc=src;
         }
 
-        src+=U16_LENGTH(c);
-        /*
-         * isCompYesAndZeroCC(norm16) is false, that is, norm16>=minNoNo.
-         * c is either a "noNo" (has a mapping) or a "maybeYes" (combines backward)
-         * or has ccc!=0.
-         */
         if(isMaybeOrNonZeroCC(norm16)) {
             uint8_t cc=getCCFromYesOrMaybe(norm16);
-            if( onlyContiguous &&  // FCC
-                cc!=0 &&
-                prevCC==0 &&
-                prevBoundary<prevSrc &&
-                // prevCC==0 && prevBoundary<prevSrc tell us that
-                // [prevBoundary..prevSrc[ (which is exactly one character under these conditions)
-                // passed the quick check "yes && ccc==0" test.
-                // Check whether the last character was a "yesYes" or a "yesNo".
-                // If a "yesNo", then we get its trailing ccc from its
-                // mapping and check for canonical order.
-                // All other cases are ok.
-                getTrailCCFromCompYesAndZeroCC(prevBoundary, prevSrc)>cc
-            ) {
-                // Fails FCD test.
-            } else if(prevCC<=cc || cc==0) {
-                prevCC=cc;
-                if(norm16<MIN_YES_YES_WITH_CC) {
-                    if(pQCResult!=NULL) {
-                        *pQCResult=UNORM_MAYBE;
-                    } else {
-                        return prevBoundary;
+            if (onlyContiguous /* FCC */ && cc != 0 &&
+                    getTrailCCFromCompYesAndZeroCC(prevNorm16) > cc) {
+                // The [prevBoundary..prevSrc[ character
+                // passed the quick check "yes && ccc==0" test
+                // but is out of canonical order with the current combining mark.
+            } else {
+                // If !onlyContiguous (not FCC), then we ignore the tccc of
+                // the previous character which passed the quick check "yes && ccc==0" test.
+                const UChar *nextSrc;
+                for (;;) {
+                    if (norm16 < MIN_YES_YES_WITH_CC) {
+                        if (pQCResult != nullptr) {
+                            *pQCResult = UNORM_MAYBE;
+                        } else {
+                            return prevBoundary;
+                        }
                     }
+                    if (src == limit) {
+                        return src;
+                    }
+                    uint8_t prevCC = cc;
+                    nextSrc = src;
+                    UCPTRIE_FAST_U16_NEXT(normTrie, UCPTRIE_16, nextSrc, limit, c, norm16);
+                    if (isMaybeOrNonZeroCC(norm16)) {
+                        cc = getCCFromYesOrMaybe(norm16);
+                        if (!(prevCC <= cc || cc == 0)) {
+                            break;
+                        }
+                    } else {
+                        break;
+                    }
+                    src = nextSrc;
                 }
-                continue;
+                // src is after the last in-order combining mark.
+                if (isCompYesAndZeroCC(norm16)) {
+                    prevBoundary = src;
+                    src = nextSrc;
+                    continue;
+                }
             }
         }
         if(pQCResult!=NULL) {
@@ -1453,10 +1705,10 @@
                                        ReorderingBuffer &buffer,
                                        UErrorCode &errorCode) const {
     if(!buffer.isEmpty()) {
-        const UChar *firstStarterInSrc=findNextCompBoundary(src, limit);
+        const UChar *firstStarterInSrc=findNextCompBoundary(src, limit, onlyContiguous);
         if(src!=firstStarterInSrc) {
             const UChar *lastStarterInDest=findPreviousCompBoundary(buffer.getStart(),
-                                                                    buffer.getLimit());
+                                                                    buffer.getLimit(), onlyContiguous);
             int32_t destSuffixLength=(int32_t)(buffer.getLimit()-lastStarterInDest);
             UnicodeString middle(lastStarterInDest, destSuffixLength);
             buffer.removeSuffix(destSuffixLength);
@@ -1481,91 +1733,355 @@
     }
 }
 
-/**
- * Does c have a composition boundary before it?
- * True if its decomposition begins with a character that has
- * ccc=0 && NFC_QC=Yes (isCompYesAndZeroCC()).
- * As a shortcut, this is true if c itself has ccc=0 && NFC_QC=Yes
- * (isCompYesAndZeroCC()) so we need not decompose.
- */
-UBool Normalizer2Impl::hasCompBoundaryBefore(UChar32 c, uint16_t norm16) const {
-    for(;;) {
-        if(isCompYesAndZeroCC(norm16)) {
-            return TRUE;
-        } else if(isMaybeOrNonZeroCC(norm16)) {
-            return FALSE;
-        } else if(isDecompNoAlgorithmic(norm16)) {
-            c=mapAlgorithmic(c, norm16);
-            norm16=getNorm16(c);
-        } else {
-            // c decomposes, get everything from the variable-length extra data
-            const uint16_t *mapping=getMapping(norm16);
-            uint16_t firstUnit=*mapping;
-            if((firstUnit&MAPPING_LENGTH_MASK)==0) {
+UBool
+Normalizer2Impl::composeUTF8(uint32_t options, UBool onlyContiguous,
+                             const uint8_t *src, const uint8_t *limit,
+                             ByteSink *sink, Edits *edits, UErrorCode &errorCode) const {
+    U_ASSERT(limit != nullptr);
+    UnicodeString s16;
+    uint8_t minNoMaybeLead = leadByteForCP(minCompNoMaybeCP);
+    const uint8_t *prevBoundary = src;
+
+    for (;;) {
+        // Fast path: Scan over a sequence of characters below the minimum "no or maybe" code point,
+        // or with (compYes && ccc==0) properties.
+        const uint8_t *prevSrc;
+        uint16_t norm16 = 0;
+        for (;;) {
+            if (src == limit) {
+                if (prevBoundary != limit && sink != nullptr) {
+                    ByteSinkUtil::appendUnchanged(prevBoundary, limit,
+                                                  *sink, options, edits, errorCode);
+                }
+                return TRUE;
+            }
+            if (*src < minNoMaybeLead) {
+                ++src;
+            } else {
+                prevSrc = src;
+                UCPTRIE_FAST_U8_NEXT(normTrie, UCPTRIE_16, src, limit, norm16);
+                if (!isCompYesAndZeroCC(norm16)) {
+                    break;
+                }
+            }
+        }
+        // isCompYesAndZeroCC(norm16) is false, that is, norm16>=minNoNo.
+        // The current character is either a "noNo" (has a mapping)
+        // or a "maybeYes" (combines backward)
+        // or a "yesYes" with ccc!=0.
+        // It is not a Hangul syllable or Jamo L because those have "yes" properties.
+
+        // Medium-fast path: Handle cases that do not require full decomposition and recomposition.
+        if (!isMaybeOrNonZeroCC(norm16)) {  // minNoNo <= norm16 < minMaybeYes
+            if (sink == nullptr) {
                 return FALSE;
             }
-            if((firstUnit&MAPPING_HAS_CCC_LCCC_WORD) && (*(mapping-1)&0xff00)) {
-                return FALSE;  // non-zero leadCC
+            // Fast path for mapping a character that is immediately surrounded by boundaries.
+            // In this case, we need not decompose around the current character.
+            if (isDecompNoAlgorithmic(norm16)) {
+                // Maps to a single isCompYesAndZeroCC character
+                // which also implies hasCompBoundaryBefore.
+                if (norm16HasCompBoundaryAfter(norm16, onlyContiguous) ||
+                        hasCompBoundaryBefore(src, limit)) {
+                    if (prevBoundary != prevSrc &&
+                            !ByteSinkUtil::appendUnchanged(prevBoundary, prevSrc,
+                                                           *sink, options, edits, errorCode)) {
+                        break;
+                    }
+                    appendCodePointDelta(prevSrc, src, getAlgorithmicDelta(norm16), *sink, edits);
+                    prevBoundary = src;
+                    continue;
+                }
+            } else if (norm16 < minNoNoCompBoundaryBefore) {
+                // The mapping is comp-normalized which also implies hasCompBoundaryBefore.
+                if (norm16HasCompBoundaryAfter(norm16, onlyContiguous) ||
+                        hasCompBoundaryBefore(src, limit)) {
+                    if (prevBoundary != prevSrc &&
+                            !ByteSinkUtil::appendUnchanged(prevBoundary, prevSrc,
+                                                           *sink, options, edits, errorCode)) {
+                        break;
+                    }
+                    const uint16_t *mapping = getMapping(norm16);
+                    int32_t length = *mapping++ & MAPPING_LENGTH_MASK;
+                    if (!ByteSinkUtil::appendChange(prevSrc, src, (const UChar *)mapping, length,
+                                                    *sink, edits, errorCode)) {
+                        break;
+                    }
+                    prevBoundary = src;
+                    continue;
+                }
+            } else if (norm16 >= minNoNoEmpty) {
+                // The current character maps to nothing.
+                // Simply omit it from the output if there is a boundary before _or_ after it.
+                // The character itself implies no boundaries.
+                if (hasCompBoundaryBefore(src, limit) ||
+                        hasCompBoundaryAfter(prevBoundary, prevSrc, onlyContiguous)) {
+                    if (prevBoundary != prevSrc &&
+                            !ByteSinkUtil::appendUnchanged(prevBoundary, prevSrc,
+                                                           *sink, options, edits, errorCode)) {
+                        break;
+                    }
+                    if (edits != nullptr) {
+                        edits->addReplace((int32_t)(src - prevSrc), 0);
+                    }
+                    prevBoundary = src;
+                    continue;
+                }
             }
-            int32_t i=1;  // skip over the firstUnit
-            UChar32 c;
-            U16_NEXT_UNSAFE(mapping, i, c);
-            return isCompYesAndZeroCC(getNorm16(c));
+            // Other "noNo" type, or need to examine more text around this character:
+            // Fall through to the slow path.
+        } else if (isJamoVT(norm16)) {
+            // Jamo L: E1 84 80..92
+            // Jamo V: E1 85 A1..B5
+            // Jamo T: E1 86 A8..E1 87 82
+            U_ASSERT((src - prevSrc) == 3 && *prevSrc == 0xe1);
+            UChar32 prev = previousHangulOrJamo(prevBoundary, prevSrc);
+            if (prevSrc[1] == 0x85) {
+                // The current character is a Jamo Vowel,
+                // compose with previous Jamo L and following Jamo T.
+                UChar32 l = prev - Hangul::JAMO_L_BASE;
+                if ((uint32_t)l < Hangul::JAMO_L_COUNT) {
+                    if (sink == nullptr) {
+                        return FALSE;
+                    }
+                    int32_t t = getJamoTMinusBase(src, limit);
+                    if (t >= 0) {
+                        // The next character is a Jamo T.
+                        src += 3;
+                    } else if (hasCompBoundaryBefore(src, limit)) {
+                        // No Jamo T follows, not even via decomposition.
+                        t = 0;
+                    }
+                    if (t >= 0) {
+                        UChar32 syllable = Hangul::HANGUL_BASE +
+                            (l*Hangul::JAMO_V_COUNT + (prevSrc[2]-0xa1)) *
+                            Hangul::JAMO_T_COUNT + t;
+                        prevSrc -= 3;  // Replace the Jamo L as well.
+                        if (prevBoundary != prevSrc &&
+                                !ByteSinkUtil::appendUnchanged(prevBoundary, prevSrc,
+                                                               *sink, options, edits, errorCode)) {
+                            break;
+                        }
+                        ByteSinkUtil::appendCodePoint(prevSrc, src, syllable, *sink, edits);
+                        prevBoundary = src;
+                        continue;
+                    }
+                    // If we see L+V+x where x!=T then we drop to the slow path,
+                    // decompose and recompose.
+                    // This is to deal with NFKC finding normal L and V but a
+                    // compatibility variant of a T.
+                    // We need to either fully compose that combination here
+                    // (which would complicate the code and may not work with strange custom data)
+                    // or use the slow path.
+                }
+            } else if (Hangul::isHangulLV(prev)) {
+                // The current character is a Jamo Trailing consonant,
+                // compose with previous Hangul LV that does not contain a Jamo T.
+                if (sink == nullptr) {
+                    return FALSE;
+                }
+                UChar32 syllable = prev + getJamoTMinusBase(prevSrc, src);
+                prevSrc -= 3;  // Replace the Hangul LV as well.
+                if (prevBoundary != prevSrc &&
+                        !ByteSinkUtil::appendUnchanged(prevBoundary, prevSrc,
+                                                       *sink, options, edits, errorCode)) {
+                    break;
+                }
+                ByteSinkUtil::appendCodePoint(prevSrc, src, syllable, *sink, edits);
+                prevBoundary = src;
+                continue;
+            }
+            // No matching context, or may need to decompose surrounding text first:
+            // Fall through to the slow path.
+        } else if (norm16 > JAMO_VT) {  // norm16 >= MIN_YES_YES_WITH_CC
+            // One or more combining marks that do not combine-back:
+            // Check for canonical order, copy unchanged if ok and
+            // if followed by a character with a boundary-before.
+            uint8_t cc = getCCFromNormalYesOrMaybe(norm16);  // cc!=0
+            if (onlyContiguous /* FCC */ && getPreviousTrailCC(prevBoundary, prevSrc) > cc) {
+                // Fails FCD test, need to decompose and contiguously recompose.
+                if (sink == nullptr) {
+                    return FALSE;
+                }
+            } else {
+                // If !onlyContiguous (not FCC), then we ignore the tccc of
+                // the previous character which passed the quick check "yes && ccc==0" test.
+                const uint8_t *nextSrc;
+                uint16_t n16;
+                for (;;) {
+                    if (src == limit) {
+                        if (sink != nullptr) {
+                            ByteSinkUtil::appendUnchanged(prevBoundary, limit,
+                                                          *sink, options, edits, errorCode);
+                        }
+                        return TRUE;
+                    }
+                    uint8_t prevCC = cc;
+                    nextSrc = src;
+                    UCPTRIE_FAST_U8_NEXT(normTrie, UCPTRIE_16, nextSrc, limit, n16);
+                    if (n16 >= MIN_YES_YES_WITH_CC) {
+                        cc = getCCFromNormalYesOrMaybe(n16);
+                        if (prevCC > cc) {
+                            if (sink == nullptr) {
+                                return FALSE;
+                            }
+                            break;
+                        }
+                    } else {
+                        break;
+                    }
+                    src = nextSrc;
+                }
+                // src is after the last in-order combining mark.
+                // If there is a boundary here, then we continue with no change.
+                if (norm16HasCompBoundaryBefore(n16)) {
+                    if (isCompYesAndZeroCC(n16)) {
+                        src = nextSrc;
+                    }
+                    continue;
+                }
+                // Use the slow path. There is no boundary in [prevSrc, src[.
+            }
         }
-    }
-}
 
-UBool Normalizer2Impl::hasCompBoundaryAfter(UChar32 c, UBool onlyContiguous, UBool testInert) const {
-    for(;;) {
-        uint16_t norm16=getNorm16(c);
-        if(isInert(norm16)) {
+        // Slow path: Find the nearest boundaries around the current character,
+        // decompose and recompose.
+        if (prevBoundary != prevSrc && !norm16HasCompBoundaryBefore(norm16)) {
+            const uint8_t *p = prevSrc;
+            UCPTRIE_FAST_U8_PREV(normTrie, UCPTRIE_16, prevBoundary, p, norm16);
+            if (!norm16HasCompBoundaryAfter(norm16, onlyContiguous)) {
+                prevSrc = p;
+            }
+        }
+        ReorderingBuffer buffer(*this, s16, errorCode);
+        if (U_FAILURE(errorCode)) {
+            break;
+        }
+        // We know there is not a boundary here.
+        decomposeShort(prevSrc, src, FALSE /* !stopAtCompBoundary */, onlyContiguous,
+                       buffer, errorCode);
+        // Decompose until the next boundary.
+        src = decomposeShort(src, limit, TRUE /* stopAtCompBoundary */, onlyContiguous,
+                             buffer, errorCode);
+        if (U_FAILURE(errorCode)) {
+            break;
+        }
+        if ((src - prevSrc) > INT32_MAX) {  // guard before buffer.equals()
+            errorCode = U_INDEX_OUTOFBOUNDS_ERROR;
             return TRUE;
-        } else if(norm16<=minYesNo) {
-            // Hangul: norm16==minYesNo
-            // Hangul LVT has a boundary after it.
-            // Hangul LV and non-inert yesYes characters combine forward.
-            return isHangul(norm16) && !Hangul::isHangulWithoutJamoT((UChar)c);
-        } else if(norm16>= (testInert ? minNoNo : minMaybeYes)) {
-            return FALSE;
-        } else if(isDecompNoAlgorithmic(norm16)) {
-            c=mapAlgorithmic(c, norm16);
-        } else {
-            // c decomposes, get everything from the variable-length extra data.
-            // If testInert, then c must be a yesNo character which has lccc=0,
-            // otherwise it could be a noNo.
-            const uint16_t *mapping=getMapping(norm16);
-            uint16_t firstUnit=*mapping;
-            // TRUE if
-            //   not MAPPING_NO_COMP_BOUNDARY_AFTER
-            //     (which is set if
-            //       c is not deleted, and
-            //       it and its decomposition do not combine forward, and it has a starter)
-            //   and if FCC then trailCC<=1
-            return
-                (firstUnit&MAPPING_NO_COMP_BOUNDARY_AFTER)==0 &&
-                (!onlyContiguous || firstUnit<=0x1ff);
+        }
+        recompose(buffer, 0, onlyContiguous);
+        if (!buffer.equals(prevSrc, src)) {
+            if (sink == nullptr) {
+                return FALSE;
+            }
+            if (prevBoundary != prevSrc &&
+                    !ByteSinkUtil::appendUnchanged(prevBoundary, prevSrc,
+                                                   *sink, options, edits, errorCode)) {
+                break;
+            }
+            if (!ByteSinkUtil::appendChange(prevSrc, src, buffer.getStart(), buffer.length(),
+                                            *sink, edits, errorCode)) {
+                break;
+            }
+            prevBoundary = src;
         }
     }
+    return TRUE;
 }
 
-const UChar *Normalizer2Impl::findPreviousCompBoundary(const UChar *start, const UChar *p) const {
-    BackwardUTrie2StringIterator iter(normTrie, start, p);
+UBool Normalizer2Impl::hasCompBoundaryBefore(const UChar *src, const UChar *limit) const {
+    if (src == limit || *src < minCompNoMaybeCP) {
+        return TRUE;
+    }
+    UChar32 c;
     uint16_t norm16;
-    do {
-        norm16=iter.previous16();
-    } while(!hasCompBoundaryBefore(iter.codePoint, norm16));
-    // We could also test hasCompBoundaryAfter() and return iter.codePointLimit,
-    // but that's probably not worth the extra cost.
-    return iter.codePointStart;
+    UCPTRIE_FAST_U16_NEXT(normTrie, UCPTRIE_16, src, limit, c, norm16);
+    return norm16HasCompBoundaryBefore(norm16);
 }
 
-const UChar *Normalizer2Impl::findNextCompBoundary(const UChar *p, const UChar *limit) const {
-    ForwardUTrie2StringIterator iter(normTrie, p, limit);
+UBool Normalizer2Impl::hasCompBoundaryBefore(const uint8_t *src, const uint8_t *limit) const {
+    if (src == limit) {
+        return TRUE;
+    }
     uint16_t norm16;
-    do {
-        norm16=iter.next16();
-    } while(!hasCompBoundaryBefore(iter.codePoint, norm16));
-    return iter.codePointStart;
+    UCPTRIE_FAST_U8_NEXT(normTrie, UCPTRIE_16, src, limit, norm16);
+    return norm16HasCompBoundaryBefore(norm16);
+}
+
+UBool Normalizer2Impl::hasCompBoundaryAfter(const UChar *start, const UChar *p,
+                                            UBool onlyContiguous) const {
+    if (start == p) {
+        return TRUE;
+    }
+    UChar32 c;
+    uint16_t norm16;
+    UCPTRIE_FAST_U16_PREV(normTrie, UCPTRIE_16, start, p, c, norm16);
+    return norm16HasCompBoundaryAfter(norm16, onlyContiguous);
+}
+
+UBool Normalizer2Impl::hasCompBoundaryAfter(const uint8_t *start, const uint8_t *p,
+                                            UBool onlyContiguous) const {
+    if (start == p) {
+        return TRUE;
+    }
+    uint16_t norm16;
+    UCPTRIE_FAST_U8_PREV(normTrie, UCPTRIE_16, start, p, norm16);
+    return norm16HasCompBoundaryAfter(norm16, onlyContiguous);
+}
+
+const UChar *Normalizer2Impl::findPreviousCompBoundary(const UChar *start, const UChar *p,
+                                                       UBool onlyContiguous) const {
+    while (p != start) {
+        const UChar *codePointLimit = p;
+        UChar32 c;
+        uint16_t norm16;
+        UCPTRIE_FAST_U16_PREV(normTrie, UCPTRIE_16, start, p, c, norm16);
+        if (norm16HasCompBoundaryAfter(norm16, onlyContiguous)) {
+            return codePointLimit;
+        }
+        if (hasCompBoundaryBefore(c, norm16)) {
+            return p;
+        }
+    }
+    return p;
+}
+
+const UChar *Normalizer2Impl::findNextCompBoundary(const UChar *p, const UChar *limit,
+                                                   UBool onlyContiguous) const {
+    while (p != limit) {
+        const UChar *codePointStart = p;
+        UChar32 c;
+        uint16_t norm16;
+        UCPTRIE_FAST_U16_NEXT(normTrie, UCPTRIE_16, p, limit, c, norm16);
+        if (hasCompBoundaryBefore(c, norm16)) {
+            return codePointStart;
+        }
+        if (norm16HasCompBoundaryAfter(norm16, onlyContiguous)) {
+            return p;
+        }
+    }
+    return p;
+}
+
+uint8_t Normalizer2Impl::getPreviousTrailCC(const UChar *start, const UChar *p) const {
+    if (start == p) {
+        return 0;
+    }
+    int32_t i = (int32_t)(p - start);
+    UChar32 c;
+    U16_PREV(start, 0, i, c);
+    return (uint8_t)getFCD16(c);
+}
+
+uint8_t Normalizer2Impl::getPreviousTrailCC(const uint8_t *start, const uint8_t *p) const {
+    if (start == p) {
+        return 0;
+    }
+    int32_t i = (int32_t)(p - start);
+    UChar32 c;
+    U8_PREV(start, 0, i, c);
+    return (uint8_t)getFCD16(c);
 }
 
 // Note: normalizer2impl.cpp r30982 (2011-nov-27)
@@ -1573,44 +2089,52 @@
 // That provided faster access to FCD data than getFCD16FromNormData()
 // but required synchronization and consumed some 10kB of heap memory
 // in any process that uses FCD (e.g., via collation).
-// tccc180[] and smallFCD[] are intended to help with any loss of performance,
-// at least for Latin & CJK.
+// minDecompNoCP etc. and smallFCD[] are intended to help with any loss of performance,
+// at least for ASCII & CJK.
 
+// Ticket 20907 - The optimizer in MSVC/Visual Studio versions below 16.4 has trouble with this
+// function on Windows ARM64. As a work-around, we disable optimizations for this function.
+// This work-around could/should be removed once the following versions of Visual Studio are no
+// longer supported: All versions of VS2017, and versions of VS2019 below 16.4.
+#if (defined(_MSC_VER) && (defined(_M_ARM64)) && (_MSC_VER < 1924))
+#pragma optimize( "", off )
+#endif
 // Gets the FCD value from the regular normalization data.
 uint16_t Normalizer2Impl::getFCD16FromNormData(UChar32 c) const {
-    // Only loops for 1:1 algorithmic mappings.
-    for(;;) {
-        uint16_t norm16=getNorm16(c);
-        if(norm16<=minYesNo) {
-            // no decomposition or Hangul syllable, all zeros
-            return 0;
-        } else if(norm16>=MIN_NORMAL_MAYBE_YES) {
+    uint16_t norm16=getNorm16(c);
+    if (norm16 >= limitNoNo) {
+        if(norm16>=MIN_NORMAL_MAYBE_YES) {
             // combining mark
-            norm16&=0xff;
+            norm16=getCCFromNormalYesOrMaybe(norm16);
             return norm16|(norm16<<8);
         } else if(norm16>=minMaybeYes) {
             return 0;
-        } else if(isDecompNoAlgorithmic(norm16)) {
-            c=mapAlgorithmic(c, norm16);
-        } else {
-            // c decomposes, get everything from the variable-length extra data
-            const uint16_t *mapping=getMapping(norm16);
-            uint16_t firstUnit=*mapping;
-            if((firstUnit&MAPPING_LENGTH_MASK)==0) {
-                // A character that is deleted (maps to an empty string) must
-                // get the worst-case lccc and tccc values because arbitrary
-                // characters on both sides will become adjacent.
-                return 0x1ff;
-            } else {
-                norm16=firstUnit>>8;  // tccc
-                if(firstUnit&MAPPING_HAS_CCC_LCCC_WORD) {
-                    norm16|=*(mapping-1)&0xff00;  // lccc
-                }
-                return norm16;
+        } else {  // isDecompNoAlgorithmic(norm16)
+            uint16_t deltaTrailCC = norm16 & DELTA_TCCC_MASK;
+            if (deltaTrailCC <= DELTA_TCCC_1) {
+                return deltaTrailCC >> OFFSET_SHIFT;
             }
+            // Maps to an isCompYesAndZeroCC.
+            c=mapAlgorithmic(c, norm16);
+            norm16=getRawNorm16(c);
         }
     }
+    if(norm16<=minYesNo || isHangulLVT(norm16)) {
+        // no decomposition or Hangul syllable, all zeros
+        return 0;
+    }
+    // c decomposes, get everything from the variable-length extra data
+    const uint16_t *mapping=getMapping(norm16);
+    uint16_t firstUnit=*mapping;
+    norm16=firstUnit>>8;  // tccc
+    if(firstUnit&MAPPING_HAS_CCC_LCCC_WORD) {
+        norm16|=*(mapping-1)&0xff00;  // lccc
+    }
+    return norm16;
 }
+#if (defined(_MSC_VER) && (defined(_M_ARM64)) && (_MSC_VER < 1924))
+#pragma optimize( "", on )
+#endif
 
 // Dual functionality:
 // buffer!=NULL: normalize
@@ -1624,7 +2148,7 @@
     const UChar *prevBoundary=src;
     int32_t prevFCD16=0;
     if(limit==NULL) {
-        src=copyLowPrefixFromNulTerminated(src, MIN_CCC_LCCC_CP, buffer, errorCode);
+        src=copyLowPrefixFromNulTerminated(src, minLcccCP, buffer, errorCode);
         if(U_FAILURE(errorCode)) {
             return src;
         }
@@ -1653,24 +2177,17 @@
     for(;;) {
         // count code units with lccc==0
         for(prevSrc=src; src!=limit;) {
-            if((c=*src)<MIN_CCC_LCCC_CP) {
+            if((c=*src)<minLcccCP) {
                 prevFCD16=~c;
                 ++src;
             } else if(!singleLeadMightHaveNonZeroFCD16(c)) {
                 prevFCD16=0;
                 ++src;
             } else {
-                if(U16_IS_SURROGATE(c)) {
+                if(U16_IS_LEAD(c)) {
                     UChar c2;
-                    if(U16_IS_SURROGATE_LEAD(c)) {
-                        if((src+1)!=limit && U16_IS_TRAIL(c2=src[1])) {
-                            c=U16_GET_SUPPLEMENTARY(c, c2);
-                        }
-                    } else /* trail surrogate */ {
-                        if(prevSrc<src && U16_IS_LEAD(c2=*(src-1))) {
-                            --src;
-                            c=U16_GET_SUPPLEMENTARY(c2, c);
-                        }
+                    if((src+1)!=limit && U16_IS_TRAIL(c2=src[1])) {
+                        c=U16_GET_SUPPLEMENTARY(c, c2);
                     }
                 }
                 if((fcd16=getFCD16FromNormData(c))<=0xff) {
@@ -1692,11 +2209,15 @@
             prevBoundary=src;
             // We know that the previous character's lccc==0.
             if(prevFCD16<0) {
-                // Fetching the fcd16 value was deferred for this below-U+0300 code point.
+                // Fetching the fcd16 value was deferred for this below-minLcccCP code point.
                 UChar32 prev=~prevFCD16;
-                prevFCD16= prev<0x180 ? tccc180[prev] : getFCD16FromNormData(prev);
-                if(prevFCD16>1) {
-                    --prevBoundary;
+                if(prev<minDecompNoCP) {
+                    prevFCD16=0;
+                } else {
+                    prevFCD16=getFCD16FromNormData(prev);
+                    if(prevFCD16>1) {
+                        --prevBoundary;
+                    }
                 }
             } else {
                 const UChar *p=src-1;
@@ -1748,7 +2269,8 @@
              * The source text does not fulfill the conditions for FCD.
              * Decompose and reorder a limited piece of the text.
              */
-            if(!decomposeShort(prevBoundary, src, *buffer, errorCode)) {
+            decomposeShort(prevBoundary, src, FALSE, FALSE, *buffer, errorCode);
+            if (U_FAILURE(errorCode)) {
                 break;
             }
             prevBoundary=src;
@@ -1792,16 +2314,33 @@
 }
 
 const UChar *Normalizer2Impl::findPreviousFCDBoundary(const UChar *start, const UChar *p) const {
-    while(start<p && previousFCD16(start, p)>0xff) {}
+    while(start<p) {
+        const UChar *codePointLimit = p;
+        UChar32 c;
+        uint16_t norm16;
+        UCPTRIE_FAST_U16_PREV(normTrie, UCPTRIE_16, start, p, c, norm16);
+        if (c < minDecompNoCP || norm16HasDecompBoundaryAfter(norm16)) {
+            return codePointLimit;
+        }
+        if (norm16HasDecompBoundaryBefore(norm16)) {
+            return p;
+        }
+    }
     return p;
 }
 
 const UChar *Normalizer2Impl::findNextFCDBoundary(const UChar *p, const UChar *limit) const {
     while(p<limit) {
         const UChar *codePointStart=p;
-        if(nextFCD16(p, limit)<=0xff) {
+        UChar32 c;
+        uint16_t norm16;
+        UCPTRIE_FAST_U16_NEXT(normTrie, UCPTRIE_16, p, limit, c, norm16);
+        if (c < minLcccCP || norm16HasDecompBoundaryBefore(norm16)) {
             return codePointStart;
         }
+        if (norm16HasDecompBoundaryAfter(norm16)) {
+            return p;
+        }
     }
     return p;
 }
@@ -1809,19 +2348,20 @@
 // CanonicalIterator data -------------------------------------------------- ***
 
 CanonIterData::CanonIterData(UErrorCode &errorCode) :
-        trie(utrie2_open(0, 0, &errorCode)),
+        mutableTrie(umutablecptrie_open(0, 0, &errorCode)), trie(nullptr),
         canonStartSets(uprv_deleteUObject, NULL, errorCode) {}
 
 CanonIterData::~CanonIterData() {
-    utrie2_close(trie);
+    umutablecptrie_close(mutableTrie);
+    ucptrie_close(trie);
 }
 
 void CanonIterData::addToStartSet(UChar32 origin, UChar32 decompLead, UErrorCode &errorCode) {
-    uint32_t canonValue=utrie2_get32(trie, decompLead);
+    uint32_t canonValue = umutablecptrie_get(mutableTrie, decompLead);
     if((canonValue&(CANON_HAS_SET|CANON_VALUE_MASK))==0 && origin!=0) {
         // origin is the first character whose decomposition starts with
         // the character for which we are setting the value.
-        utrie2_set32(trie, decompLead, canonValue|origin, &errorCode);
+        umutablecptrie_set(mutableTrie, decompLead, canonValue|origin, &errorCode);
     } else {
         // origin is not the first character, or it is U+0000.
         UnicodeSet *set;
@@ -1833,7 +2373,7 @@
             }
             UChar32 firstOrigin=(UChar32)(canonValue&CANON_VALUE_MASK);
             canonValue=(canonValue&~CANON_VALUE_MASK)|CANON_HAS_SET|(uint32_t)canonStartSets.size();
-            utrie2_set32(trie, decompLead, canonValue, &errorCode);
+            umutablecptrie_set(mutableTrie, decompLead, canonValue, &errorCode);
             canonStartSets.addElement(set, errorCode);
             if(firstOrigin!=0) {
                 set->add(firstOrigin);
@@ -1845,35 +2385,47 @@
     }
 }
 
+// C++ class for friend access to private Normalizer2Impl members.
+class InitCanonIterData {
+public:
+    static void doInit(Normalizer2Impl *impl, UErrorCode &errorCode);
+};
+
 U_CDECL_BEGIN
 
-// Call Normalizer2Impl::makeCanonIterDataFromNorm16() for a range of same-norm16 characters.
-//     context: the Normalizer2Impl
-static UBool U_CALLCONV
-enumCIDRangeHandler(const void *context, UChar32 start, UChar32 end, uint32_t value) {
-    UErrorCode errorCode = U_ZERO_ERROR;
-    if (value != 0) {
-        Normalizer2Impl *impl = (Normalizer2Impl *)context;
-        impl->makeCanonIterDataFromNorm16(
-            start, end, (uint16_t)value, *impl->fCanonIterData, errorCode);
-    }
-    return U_SUCCESS(errorCode);
+// UInitOnce instantiation function for CanonIterData
+static void U_CALLCONV
+initCanonIterData(Normalizer2Impl *impl, UErrorCode &errorCode) {
+    InitCanonIterData::doInit(impl, errorCode);
 }
 
+U_CDECL_END
 
-
-// UInitOnce instantiation function for CanonIterData
-
-static void U_CALLCONV 
-initCanonIterData(Normalizer2Impl *impl, UErrorCode &errorCode) {
+void InitCanonIterData::doInit(Normalizer2Impl *impl, UErrorCode &errorCode) {
     U_ASSERT(impl->fCanonIterData == NULL);
     impl->fCanonIterData = new CanonIterData(errorCode);
     if (impl->fCanonIterData == NULL) {
         errorCode=U_MEMORY_ALLOCATION_ERROR;
     }
     if (U_SUCCESS(errorCode)) {
-        utrie2_enum(impl->getNormTrie(), NULL, enumCIDRangeHandler, impl);
-        utrie2_freeze(impl->fCanonIterData->trie, UTRIE2_32_VALUE_BITS, &errorCode);
+        UChar32 start = 0, end;
+        uint32_t value;
+        while ((end = ucptrie_getRange(impl->normTrie, start,
+                                       UCPMAP_RANGE_FIXED_LEAD_SURROGATES, Normalizer2Impl::INERT,
+                                       nullptr, nullptr, &value)) >= 0) {
+            // Call Normalizer2Impl::makeCanonIterDataFromNorm16() for a range of same-norm16 characters.
+            if (value != Normalizer2Impl::INERT) {
+                impl->makeCanonIterDataFromNorm16(start, end, value, *impl->fCanonIterData, errorCode);
+            }
+            start = end + 1;
+        }
+#ifdef UCPTRIE_DEBUG
+        umutablecptrie_setName(impl->fCanonIterData->mutableTrie, "CanonIterData");
+#endif
+        impl->fCanonIterData->trie = umutablecptrie_buildImmutable(
+            impl->fCanonIterData->mutableTrie, UCPTRIE_TYPE_SMALL, UCPTRIE_VALUE_BITS_32, &errorCode);
+        umutablecptrie_close(impl->fCanonIterData->mutableTrie);
+        impl->fCanonIterData->mutableTrie = nullptr;
     }
     if (U_FAILURE(errorCode)) {
         delete impl->fCanonIterData;
@@ -1881,12 +2433,10 @@
     }
 }
 
-U_CDECL_END
-
-void Normalizer2Impl::makeCanonIterDataFromNorm16(UChar32 start, UChar32 end, uint16_t norm16,
+void Normalizer2Impl::makeCanonIterDataFromNorm16(UChar32 start, UChar32 end, const uint16_t norm16,
                                                   CanonIterData &newData,
                                                   UErrorCode &errorCode) const {
-    if(norm16==0 || (minYesNo<=norm16 && norm16<minNoNo)) {
+    if(isInert(norm16) || (minYesNo<=norm16 && norm16<minNoNo)) {
         // Inert, or 2-way mapping (including Hangul syllable).
         // We do not write a canonStartSet for any yesNo character.
         // Composites from 2-way mappings are added at runtime from the
@@ -1896,9 +2446,9 @@
         return;
     }
     for(UChar32 c=start; c<=end; ++c) {
-        uint32_t oldValue=utrie2_get32(newData.trie, c);
+        uint32_t oldValue = umutablecptrie_get(newData.mutableTrie, c);
         uint32_t newValue=oldValue;
-        if(norm16>=minMaybeYes) {
+        if(isMaybeOrNonZeroCC(norm16)) {
             // not a segment starter if it occurs in a decomposition or has cc!=0
             newValue|=CANON_NOT_SEGMENT_STARTER;
             if(norm16<MIN_NORMAL_MAYBE_YES) {
@@ -1909,12 +2459,16 @@
         } else {
             // c has a one-way decomposition
             UChar32 c2=c;
+            // Do not modify the whole-range norm16 value.
             uint16_t norm16_2=norm16;
-            while(limitNoNo<=norm16_2 && norm16_2<minMaybeYes) {
-                c2=mapAlgorithmic(c2, norm16_2);
-                norm16_2=getNorm16(c2);
+            if (isDecompNoAlgorithmic(norm16_2)) {
+                // Maps to an isCompYesAndZeroCC.
+                c2 = mapAlgorithmic(c2, norm16_2);
+                norm16_2 = getRawNorm16(c2);
+                // No compatibility mappings for the CanonicalIterator.
+                U_ASSERT(!(isHangulLV(norm16_2) || isHangulLVT(norm16_2)));
             }
-            if(minYesNo<=norm16_2 && norm16_2<limitNoNo) {
+            if (norm16_2 > minYesNo) {
                 // c decomposes, get everything from the variable-length extra data
                 const uint16_t *mapping=getMapping(norm16_2);
                 uint16_t firstUnit=*mapping;
@@ -1937,10 +2491,10 @@
                     if(norm16_2>=minNoNo) {
                         while(i<length) {
                             U16_NEXT_UNSAFE(mapping, i, c2);
-                            uint32_t c2Value=utrie2_get32(newData.trie, c2);
+                            uint32_t c2Value = umutablecptrie_get(newData.mutableTrie, c2);
                             if((c2Value&CANON_NOT_SEGMENT_STARTER)==0) {
-                                utrie2_set32(newData.trie, c2, c2Value|CANON_NOT_SEGMENT_STARTER,
-                                             &errorCode);
+                                umutablecptrie_set(newData.mutableTrie, c2,
+                                                   c2Value|CANON_NOT_SEGMENT_STARTER, &errorCode);
                             }
                         }
                     }
@@ -1951,7 +2505,7 @@
             }
         }
         if(newValue!=oldValue) {
-            utrie2_set32(newData.trie, c, newValue, &errorCode);
+            umutablecptrie_set(newData.mutableTrie, c, newValue, &errorCode);
         }
     }
 }
@@ -1964,7 +2518,7 @@
 }
 
 int32_t Normalizer2Impl::getCanonValue(UChar32 c) const {
-    return (int32_t)utrie2_get32(fCanonIterData->trie, c);
+    return (int32_t)ucptrie_get(fCanonIterData->trie, c);
 }
 
 const UnicodeSet &Normalizer2Impl::getCanonStartSet(int32_t n) const {
@@ -1988,7 +2542,7 @@
         set.add(value);
     }
     if((canonValue&CANON_HAS_COMPOSITIONS)!=0) {
-        uint16_t norm16=getNorm16(c);
+        uint16_t norm16=getRawNorm16(c);
         if(norm16==JAMO_L) {
             UChar32 syllable=
                 (UChar32)(Hangul::HANGUL_BASE+(c-Hangul::JAMO_L_BASE)*Hangul::JAMO_VT_COUNT);
@@ -2017,7 +2571,7 @@
     uint8_t *outBytes;
 
     const int32_t *inIndexes;
-    int32_t indexes[Normalizer2Impl::IX_MIN_MAYBE_YES+1];
+    int32_t indexes[Normalizer2Impl::IX_TOTAL_SIZE+1];
 
     int32_t i, offset, nextOffset, size;
 
@@ -2029,12 +2583,13 @@
 
     /* check data format and format version */
     pInfo=(const UDataInfo *)((const char *)inData+4);
+    uint8_t formatVersion0=pInfo->formatVersion[0];
     if(!(
         pInfo->dataFormat[0]==0x4e &&   /* dataFormat="Nrm2" */
         pInfo->dataFormat[1]==0x72 &&
         pInfo->dataFormat[2]==0x6d &&
         pInfo->dataFormat[3]==0x32 &&
-        (pInfo->formatVersion[0]==1 || pInfo->formatVersion[0]==2)
+        (1<=formatVersion0 && formatVersion0<=4)
     )) {
         udata_printError(ds, "unorm2_swap(): data format %02x.%02x.%02x.%02x (format version %02x) is not recognized as Normalizer2 data\n",
                          pInfo->dataFormat[0], pInfo->dataFormat[1],
@@ -2048,10 +2603,18 @@
     outBytes=(uint8_t *)outData+headerSize;
 
     inIndexes=(const int32_t *)inBytes;
+    int32_t minIndexesLength;
+    if(formatVersion0==1) {
+        minIndexesLength=Normalizer2Impl::IX_MIN_MAYBE_YES+1;
+    } else if(formatVersion0==2) {
+        minIndexesLength=Normalizer2Impl::IX_MIN_YES_NO_MAPPINGS_ONLY+1;
+    } else {
+        minIndexesLength=Normalizer2Impl::IX_MIN_LCCC_CP+1;
+    }
 
     if(length>=0) {
         length-=headerSize;
-        if(length<(int32_t)sizeof(indexes)) {
+        if(length<minIndexesLength*4) {
             udata_printError(ds, "unorm2_swap(): too few bytes (%d after header) for Normalizer2 data\n",
                              length);
             *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
@@ -2060,7 +2623,7 @@
     }
 
     /* read the first few indexes */
-    for(i=0; i<=Normalizer2Impl::IX_MIN_MAYBE_YES; ++i) {
+    for(i=0; i<UPRV_LENGTHOF(indexes); ++i) {
         indexes[i]=udata_readInt32(ds, inIndexes[i]);
     }
 
@@ -2087,9 +2650,9 @@
         ds->swapArray32(ds, inBytes, nextOffset-offset, outBytes, pErrorCode);
         offset=nextOffset;
 
-        /* swap the UTrie2 */
+        /* swap the trie */
         nextOffset=indexes[Normalizer2Impl::IX_EXTRA_DATA_OFFSET];
-        utrie2_swap(ds, inBytes+offset, nextOffset-offset, outBytes+offset, pErrorCode);
+        utrie_swapAnyVersion(ds, inBytes+offset, nextOffset-offset, outBytes+offset, pErrorCode);
         offset=nextOffset;
 
         /* swap the uint16_t extraData[] */
diff --git a/src/third_party/icu/source/common/normalizer2impl.h b/src/third_party/icu/source/common/normalizer2impl.h
index eb026db..4218a30 100644
--- a/src/third_party/icu/source/common/normalizer2impl.h
+++ b/src/third_party/icu/source/common/normalizer2impl.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  normalizer2impl.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -22,17 +24,30 @@
 #if !UCONFIG_NO_NORMALIZATION
 
 #include "unicode/normalizer2.h"
+#include "unicode/ucptrie.h"
 #include "unicode/unistr.h"
 #include "unicode/unorm.h"
+#include "unicode/utf.h"
 #include "unicode/utf16.h"
 #include "mutex.h"
+#include "udataswp.h"
 #include "uset_imp.h"
-#include "utrie2.h"
+
+// When the nfc.nrm data is *not* hardcoded into the common library
+// (with this constant set to 0),
+// then it needs to be built into the data package:
+// Add nfc.nrm to icu4c/source/data/Makefile.in DAT_FILES_SHORT
+#define NORM2_HARDCODE_NFC_DATA 1
 
 U_NAMESPACE_BEGIN
 
 struct CanonIterData;
 
+class ByteSink;
+class Edits;
+class InitCanonIterData;
+class LcccContext;
+
 class U_COMMON_API Hangul {
 public:
     /* Korean Hangul and Jamo constants */
@@ -61,9 +76,9 @@
         return HANGUL_BASE<=c && c<HANGUL_LIMIT;
     }
     static inline UBool
-    isHangulWithoutJamoT(UChar c) {
+    isHangulLV(UChar32 c) {
         c-=HANGUL_BASE;
-        return c<HANGUL_COUNT && c%JAMO_T_COUNT==0;
+        return 0<=c && c<HANGUL_COUNT && c%JAMO_T_COUNT==0;
     }
     static inline UBool isJamoL(UChar32 c) {
         return (uint32_t)(c-JAMO_L_BASE)<JAMO_L_COUNT;
@@ -71,6 +86,14 @@
     static inline UBool isJamoV(UChar32 c) {
         return (uint32_t)(c-JAMO_V_BASE)<JAMO_V_COUNT;
     }
+    static inline UBool isJamoT(UChar32 c) {
+        int32_t t=c-JAMO_T_BASE;
+        return 0<t && t<JAMO_T_COUNT;  // not JAMO_T_BASE itself
+    }
+    static UBool isJamo(UChar32 c) {
+        return JAMO_L_BASE<=c && c<=JAMO_T_END &&
+            (c<=JAMO_L_END || (JAMO_V_BASE<=c && c<=JAMO_V_END) || JAMO_T_BASE<c);
+    }
 
     /**
      * Decomposes c, which must be a Hangul syllable, into buffer
@@ -103,7 +126,7 @@
             buffer[0]=(UChar)(JAMO_L_BASE+c/JAMO_V_COUNT);
             buffer[1]=(UChar)(JAMO_V_BASE+c%JAMO_V_COUNT);
         } else {
-            buffer[0]=orig-c2;  // LV syllable
+            buffer[0]=(UChar)(orig-c2);  // LV syllable
             buffer[1]=(UChar)(JAMO_T_BASE+c2);
         }
     }
@@ -115,10 +138,13 @@
 
 class U_COMMON_API ReorderingBuffer : public UMemory {
 public:
+    /** Constructs only; init() should be called. */
     ReorderingBuffer(const Normalizer2Impl &ni, UnicodeString &dest) :
         impl(ni), str(dest),
         start(NULL), reorderStart(NULL), limit(NULL),
         remainingCapacity(0), lastCC(0) {}
+    /** Constructs, removes the string contents, and initializes for a small initial capacity. */
+    ReorderingBuffer(const Normalizer2Impl &ni, UnicodeString &dest, UErrorCode &errorCode);
     ~ReorderingBuffer() {
         if(start!=NULL) {
             str.releaseBuffer((int32_t)(limit-start));
@@ -133,24 +159,19 @@
     uint8_t getLastCC() const { return lastCC; }
 
     UBool equals(const UChar *start, const UChar *limit) const;
-
-    // For Hangul composition, replacing the Leading consonant Jamo with the syllable.
-    void setLastChar(UChar c) {
-        *(limit-1)=c;
-    }
+    UBool equals(const uint8_t *otherStart, const uint8_t *otherLimit) const;
 
     UBool append(UChar32 c, uint8_t cc, UErrorCode &errorCode) {
         return (c<=0xffff) ?
             appendBMP((UChar)c, cc, errorCode) :
             appendSupplementary(c, cc, errorCode);
     }
-    // s must be in NFD, otherwise change the implementation.
-    UBool append(const UChar *s, int32_t length,
+    UBool append(const UChar *s, int32_t length, UBool isNFD,
                  uint8_t leadCC, uint8_t trailCC,
                  UErrorCode &errorCode);
     UBool appendBMP(UChar c, uint8_t cc, UErrorCode &errorCode) {
         if(remainingCapacity==0 && !resize(1, errorCode)) {
-            return FALSE;
+            return false;
         }
         if(lastCC<=cc || cc==0) {
             *limit++=c;
@@ -162,7 +183,7 @@
             insert(c, cc);
         }
         --remainingCapacity;
-        return TRUE;
+        return true;
     }
     UBool appendZeroCC(UChar32 c, UErrorCode &errorCode);
     UBool appendZeroCC(const UChar *s, const UChar *sLimit, UErrorCode &errorCode);
@@ -174,7 +195,7 @@
         lastCC=0;
     }
     void copyReorderableSuffixTo(UnicodeString &s) const {
-        s.setTo(reorderStart, (int32_t)(limit-reorderStart));
+        s.setTo(ConstChar16Ptr(reorderStart), (int32_t)(limit-reorderStart));
     }
 private:
     /*
@@ -216,14 +237,18 @@
     UChar *codePointStart, *codePointLimit;
 };
 
+/**
+ * Low-level implementation of the Unicode Normalization Algorithm.
+ * For the data structure and details see the documentation at the end of
+ * this normalizer2impl.h and in the design doc at
+ * http://site.icu-project.org/design/normalization/custom
+ */
 class U_COMMON_API Normalizer2Impl : public UObject {
 public:
-    Normalizer2Impl() : normTrie(NULL), fCanonIterData(NULL) {
-        fCanonIterDataInitOnce.reset();
-    }
+    Normalizer2Impl() : normTrie(NULL), fCanonIterData(NULL) { }
     virtual ~Normalizer2Impl();
 
-    void init(const int32_t *inIndexes, const UTrie2 *inTrie,
+    void init(const int32_t *inIndexes, const UCPTrie *inTrie,
               const uint16_t *inExtraData, const uint8_t *inSmallFCD);
 
     void addLcccChars(UnicodeSet &set) const;
@@ -232,11 +257,16 @@
 
     // low-level properties ------------------------------------------------ ***
 
-    const UTrie2 *getNormTrie() const { return normTrie; }
-
     UBool ensureCanonIterData(UErrorCode &errorCode) const;
 
-    uint16_t getNorm16(UChar32 c) const { return UTRIE2_GET16(normTrie, c); }
+    // The trie stores values for lead surrogate code *units*.
+    // Surrogate code *points* are inert.
+    uint16_t getNorm16(UChar32 c) const {
+        return U_IS_LEAD(c) ?
+            static_cast<uint16_t>(INERT) :
+            UCPTRIE_FAST_GET(normTrie, UCPTRIE_16, c);
+    }
+    uint16_t getRawNorm16(UChar32 c) const { return UCPTRIE_FAST_GET(normTrie, UCPTRIE_16, c); }
 
     UNormalizationCheckResult getCompQuickCheck(uint16_t norm16) const {
         if(norm16<minNoNo || MIN_YES_YES_WITH_CC<=norm16) {
@@ -253,15 +283,22 @@
 
     uint8_t getCC(uint16_t norm16) const {
         if(norm16>=MIN_NORMAL_MAYBE_YES) {
-            return (uint8_t)norm16;
+            return getCCFromNormalYesOrMaybe(norm16);
         }
         if(norm16<minNoNo || limitNoNo<=norm16) {
             return 0;
         }
         return getCCFromNoNo(norm16);
     }
+    static uint8_t getCCFromNormalYesOrMaybe(uint16_t norm16) {
+        return (uint8_t)(norm16 >> OFFSET_SHIFT);
+    }
     static uint8_t getCCFromYesOrMaybe(uint16_t norm16) {
-        return norm16>=MIN_NORMAL_MAYBE_YES ? (uint8_t)norm16 : 0;
+        return norm16>=MIN_NORMAL_MAYBE_YES ? getCCFromNormalYesOrMaybe(norm16) : 0;
+    }
+    uint8_t getCCFromYesOrMaybeCP(UChar32 c) const {
+        if (c < minCompNoMaybeCP) { return 0; }
+        return getCCFromYesOrMaybe(getNorm16(c));
     }
 
     /**
@@ -270,10 +307,8 @@
      * @return The lccc(c) in bits 15..8 and tccc(c) in bits 7..0.
      */
     uint16_t getFCD16(UChar32 c) const {
-        if(c<0) {
+        if(c<minDecompNoCP) {
             return 0;
-        } else if(c<0x180) {
-            return tccc180[c];
         } else if(c<=0xffff) {
             if(!singleLeadMightHaveNonZeroFCD16(c)) { return 0; }
         }
@@ -289,9 +324,7 @@
      */
     uint16_t nextFCD16(const UChar *&s, const UChar *limit) const {
         UChar32 c=*s++;
-        if(c<0x180) {
-            return tccc180[c];
-        } else if(!singleLeadMightHaveNonZeroFCD16(c)) {
+        if(c<minDecompNoCP || !singleLeadMightHaveNonZeroFCD16(c)) {
             return 0;
         }
         UChar c2;
@@ -309,8 +342,8 @@
      */
     uint16_t previousFCD16(const UChar *start, const UChar *&s) const {
         UChar32 c=*--s;
-        if(c<0x180) {
-            return tccc180[c];
+        if(c<minDecompNoCP) {
+            return 0;
         }
         if(!U16_IS_TRAIL(c)) {
             if(!singleLeadMightHaveNonZeroFCD16(c)) {
@@ -326,9 +359,7 @@
         return getFCD16FromNormData(c);
     }
 
-    /** Returns the FCD data for U+0000<=c<U+0180. */
-    uint16_t getFCD16FromBelow180(UChar32 c) const { return tccc180[c]; }
-    /** Returns TRUE if the single-or-lead code unit c might have non-zero FCD data. */
+    /** Returns true if the single-or-lead code unit c might have non-zero FCD data. */
     UBool singleLeadMightHaveNonZeroFCD16(UChar32 lead) const {
         // 0<=lead<=0xffff
         uint8_t bits=smallFCD[lead>>8];
@@ -338,9 +369,6 @@
     /** Returns the FCD value from the regular normalization data. */
     uint16_t getFCD16FromNormData(UChar32 c) const;
 
-    void makeCanonIterDataFromNorm16(UChar32 start, UChar32 end, uint16_t norm16,
-                                     CanonIterData &newData, UErrorCode &errorCode) const;
-
     /**
      * Gets the decomposition for one code point.
      * @param c code point
@@ -365,14 +393,25 @@
     UBool getCanonStartSet(UChar32 c, UnicodeSet &set) const;
 
     enum {
-        MIN_CCC_LCCC_CP=0x300
-    };
+        // Fixed norm16 values.
+        MIN_YES_YES_WITH_CC=0xfe02,
+        JAMO_VT=0xfe00,
+        MIN_NORMAL_MAYBE_YES=0xfc00,
+        JAMO_L=2,  // offset=1 hasCompBoundaryAfter=false
+        INERT=1,  // offset=0 hasCompBoundaryAfter=true
 
-    enum {
-        MIN_YES_YES_WITH_CC=0xff01,
-        JAMO_VT=0xff00,
-        MIN_NORMAL_MAYBE_YES=0xfe00,
-        JAMO_L=1,
+        // norm16 bit 0 is comp-boundary-after.
+        HAS_COMP_BOUNDARY_AFTER=1,
+        OFFSET_SHIFT=1,
+
+        // For algorithmic one-way mappings, norm16 bits 2..1 indicate the
+        // tccc (0, 1, >1) for quick FCC boundary-after tests.
+        DELTA_TCCC_0=0,
+        DELTA_TCCC_1=2,
+        DELTA_TCCC_GT_1=4,
+        DELTA_TCCC_MASK=6,
+        DELTA_SHIFT=3,
+
         MAX_DELTA=0x40
     };
 
@@ -392,21 +431,32 @@
         IX_MIN_COMP_NO_MAYBE_CP,
 
         // Norm16 value thresholds for quick check combinations and types of extra data.
-        IX_MIN_YES_NO,  // Mappings & compositions in [minYesNo..minYesNoMappingsOnly[.
+
+        /** Mappings & compositions in [minYesNo..minYesNoMappingsOnly[. */
+        IX_MIN_YES_NO,
+        /** Mappings are comp-normalized. */
         IX_MIN_NO_NO,
         IX_LIMIT_NO_NO,
         IX_MIN_MAYBE_YES,
 
-        IX_MIN_YES_NO_MAPPINGS_ONLY,  // Mappings only in [minYesNoMappingsOnly..minNoNo[.
+        /** Mappings only in [minYesNoMappingsOnly..minNoNo[. */
+        IX_MIN_YES_NO_MAPPINGS_ONLY,
+        /** Mappings are not comp-normalized but have a comp boundary before. */
+        IX_MIN_NO_NO_COMP_BOUNDARY_BEFORE,
+        /** Mappings do not have a comp boundary before. */
+        IX_MIN_NO_NO_COMP_NO_MAYBE_CC,
+        /** Mappings to the empty string. */
+        IX_MIN_NO_NO_EMPTY,
 
-        IX_RESERVED15,
+        IX_MIN_LCCC_CP,
+        IX_RESERVED19,
         IX_COUNT
     };
 
     enum {
         MAPPING_HAS_CCC_LCCC_WORD=0x80,
         MAPPING_HAS_RAW_MAPPING=0x40,
-        MAPPING_NO_COMP_BOUNDARY_AFTER=0x20,
+        // unused bit 0x20,
         MAPPING_LENGTH_MASK=0x1f
     };
 
@@ -455,6 +505,12 @@
                           UnicodeString &safeMiddle,
                           ReorderingBuffer &buffer,
                           UErrorCode &errorCode) const;
+
+    /** sink==nullptr: isNormalized() */
+    UBool composeUTF8(uint32_t options, UBool onlyContiguous,
+                      const uint8_t *src, const uint8_t *limit,
+                      ByteSink *sink, icu::Edits *edits, UErrorCode &errorCode) const;
+
     const UChar *makeFCD(const UChar *src, const UChar *limit,
                          ReorderingBuffer *buffer, UErrorCode &errorCode) const;
     void makeFCDAndAppend(const UChar *src, const UChar *limit,
@@ -463,27 +519,42 @@
                           ReorderingBuffer &buffer,
                           UErrorCode &errorCode) const;
 
-    UBool hasDecompBoundary(UChar32 c, UBool before) const;
+    UBool hasDecompBoundaryBefore(UChar32 c) const;
+    UBool norm16HasDecompBoundaryBefore(uint16_t norm16) const;
+    UBool hasDecompBoundaryAfter(UChar32 c) const;
+    UBool norm16HasDecompBoundaryAfter(uint16_t norm16) const;
     UBool isDecompInert(UChar32 c) const { return isDecompYesAndZeroCC(getNorm16(c)); }
 
     UBool hasCompBoundaryBefore(UChar32 c) const {
-        return c<minCompNoMaybeCP || hasCompBoundaryBefore(c, getNorm16(c));
+        return c<minCompNoMaybeCP || norm16HasCompBoundaryBefore(getNorm16(c));
     }
-    UBool hasCompBoundaryAfter(UChar32 c, UBool onlyContiguous, UBool testInert) const;
+    UBool hasCompBoundaryAfter(UChar32 c, UBool onlyContiguous) const {
+        return norm16HasCompBoundaryAfter(getNorm16(c), onlyContiguous);
+    }
+    UBool isCompInert(UChar32 c, UBool onlyContiguous) const {
+        uint16_t norm16=getNorm16(c);
+        return isCompYesAndZeroCC(norm16) &&
+            (norm16 & HAS_COMP_BOUNDARY_AFTER) != 0 &&
+            (!onlyContiguous || isInert(norm16) || *getMapping(norm16) <= 0x1ff);
+    }
 
-    UBool hasFCDBoundaryBefore(UChar32 c) const { return c<MIN_CCC_LCCC_CP || getFCD16(c)<=0xff; }
-    UBool hasFCDBoundaryAfter(UChar32 c) const {
-        uint16_t fcd16=getFCD16(c);
-        return fcd16<=1 || (fcd16&0xff)==0;
-    }
+    UBool hasFCDBoundaryBefore(UChar32 c) const { return hasDecompBoundaryBefore(c); }
+    UBool hasFCDBoundaryAfter(UChar32 c) const { return hasDecompBoundaryAfter(c); }
     UBool isFCDInert(UChar32 c) const { return getFCD16(c)<=1; }
 private:
+    friend class InitCanonIterData;
+    friend class LcccContext;
+
     UBool isMaybe(uint16_t norm16) const { return minMaybeYes<=norm16 && norm16<=JAMO_VT; }
     UBool isMaybeOrNonZeroCC(uint16_t norm16) const { return norm16>=minMaybeYes; }
-    static UBool isInert(uint16_t norm16) { return norm16==0; }
-    static UBool isJamoL(uint16_t norm16) { return norm16==1; }
+    static UBool isInert(uint16_t norm16) { return norm16==INERT; }
+    static UBool isJamoL(uint16_t norm16) { return norm16==JAMO_L; }
     static UBool isJamoVT(uint16_t norm16) { return norm16==JAMO_VT; }
-    UBool isHangul(uint16_t norm16) const { return norm16==minYesNo; }
+    uint16_t hangulLVT() const { return minYesNoMappingsOnly|HAS_COMP_BOUNDARY_AFTER; }
+    UBool isHangulLV(uint16_t norm16) const { return norm16==minYesNo; }
+    UBool isHangulLVT(uint16_t norm16) const {
+        return norm16==hangulLVT();
+    }
     UBool isCompYesAndZeroCC(uint16_t norm16) const { return norm16<minNoNo; }
     // UBool isCompYes(uint16_t norm16) const {
     //     return norm16>=MIN_YES_YES_WITH_CC || norm16<minNoNo;
@@ -502,7 +573,7 @@
     /**
      * A little faster and simpler than isDecompYesAndZeroCC() but does not include
      * the MaybeYes which combine-forward and have ccc=0.
-     * (Standard Unicode 5.2 normalization does not have such characters.)
+     * (Standard Unicode 10 normalization does not have such characters.)
      */
     UBool isMostDecompYesAndZeroCC(uint16_t norm16) const {
         return norm16<minYesNo || norm16==MIN_NORMAL_MAYBE_YES || norm16==JAMO_VT;
@@ -512,7 +583,7 @@
     // For use with isCompYes().
     // Perhaps the compiler can combine the two tests for MIN_YES_YES_WITH_CC.
     // static uint8_t getCCFromYes(uint16_t norm16) {
-    //     return norm16>=MIN_YES_YES_WITH_CC ? (uint8_t)norm16 : 0;
+    //     return norm16>=MIN_YES_YES_WITH_CC ? getCCFromNormalYesOrMaybe(norm16) : 0;
     // }
     uint8_t getCCFromNoNo(uint16_t norm16) const {
         const uint16_t *mapping=getMapping(norm16);
@@ -523,30 +594,47 @@
         }
     }
     // requires that the [cpStart..cpLimit[ character passes isCompYesAndZeroCC()
-    uint8_t getTrailCCFromCompYesAndZeroCC(const UChar *cpStart, const UChar *cpLimit) const;
+    uint8_t getTrailCCFromCompYesAndZeroCC(uint16_t norm16) const {
+        if(norm16<=minYesNo) {
+            return 0;  // yesYes and Hangul LV have ccc=tccc=0
+        } else {
+            // For Hangul LVT we harmlessly fetch a firstUnit with tccc=0 here.
+            return (uint8_t)(*getMapping(norm16)>>8);  // tccc from yesNo
+        }
+    }
+    uint8_t getPreviousTrailCC(const UChar *start, const UChar *p) const;
+    uint8_t getPreviousTrailCC(const uint8_t *start, const uint8_t *p) const;
 
     // Requires algorithmic-NoNo.
     UChar32 mapAlgorithmic(UChar32 c, uint16_t norm16) const {
-        return c+norm16-(minMaybeYes-MAX_DELTA-1);
+        return c+(norm16>>DELTA_SHIFT)-centerNoNoDelta;
+    }
+    UChar32 getAlgorithmicDelta(uint16_t norm16) const {
+        return (norm16>>DELTA_SHIFT)-centerNoNoDelta;
     }
 
     // Requires minYesNo<norm16<limitNoNo.
-    const uint16_t *getMapping(uint16_t norm16) const { return extraData+norm16; }
+    const uint16_t *getMapping(uint16_t norm16) const { return extraData+(norm16>>OFFSET_SHIFT); }
     const uint16_t *getCompositionsListForDecompYes(uint16_t norm16) const {
-        if(norm16==0 || MIN_NORMAL_MAYBE_YES<=norm16) {
+        if(norm16<JAMO_L || MIN_NORMAL_MAYBE_YES<=norm16) {
             return NULL;
         } else if(norm16<minMaybeYes) {
-            return extraData+norm16;  // for yesYes; if Jamo L: harmless empty list
+            return getMapping(norm16);  // for yesYes; if Jamo L: harmless empty list
         } else {
             return maybeYesCompositions+norm16-minMaybeYes;
         }
     }
     const uint16_t *getCompositionsListForComposite(uint16_t norm16) const {
-        const uint16_t *list=extraData+norm16;  // composite has both mapping & compositions list
+        // A composite has both mapping & compositions list.
+        const uint16_t *list=getMapping(norm16);
         return list+  // mapping pointer
-            1+  // +1 to skip the first unit with the mapping lenth
+            1+  // +1 to skip the first unit with the mapping length
             (*list&MAPPING_LENGTH_MASK);  // + mapping length
     }
+    const uint16_t *getCompositionsListForMaybe(uint16_t norm16) const {
+        // minMaybeYes<=norm16<MIN_NORMAL_MAYBE_YES
+        return maybeYesCompositions+((norm16-minMaybeYes)>>OFFSET_SHIFT);
+    }
     /**
      * @param c code point must have compositions
      * @return compositions list pointer
@@ -561,47 +649,79 @@
                                                 UChar32 minNeedDataCP,
                                                 ReorderingBuffer *buffer,
                                                 UErrorCode &errorCode) const;
-    UBool decomposeShort(const UChar *src, const UChar *limit,
-                         ReorderingBuffer &buffer, UErrorCode &errorCode) const;
+    const UChar *decomposeShort(const UChar *src, const UChar *limit,
+                                UBool stopAtCompBoundary, UBool onlyContiguous,
+                                ReorderingBuffer &buffer, UErrorCode &errorCode) const;
     UBool decompose(UChar32 c, uint16_t norm16,
                     ReorderingBuffer &buffer, UErrorCode &errorCode) const;
 
+    const uint8_t *decomposeShort(const uint8_t *src, const uint8_t *limit,
+                                  UBool stopAtCompBoundary, UBool onlyContiguous,
+                                  ReorderingBuffer &buffer, UErrorCode &errorCode) const;
+
     static int32_t combine(const uint16_t *list, UChar32 trail);
     void addComposites(const uint16_t *list, UnicodeSet &set) const;
     void recompose(ReorderingBuffer &buffer, int32_t recomposeStartIndex,
                    UBool onlyContiguous) const;
 
-    UBool hasCompBoundaryBefore(UChar32 c, uint16_t norm16) const;
-    const UChar *findPreviousCompBoundary(const UChar *start, const UChar *p) const;
-    const UChar *findNextCompBoundary(const UChar *p, const UChar *limit) const;
+    UBool hasCompBoundaryBefore(UChar32 c, uint16_t norm16) const {
+        return c<minCompNoMaybeCP || norm16HasCompBoundaryBefore(norm16);
+    }
+    UBool norm16HasCompBoundaryBefore(uint16_t norm16) const  {
+        return norm16 < minNoNoCompNoMaybeCC || isAlgorithmicNoNo(norm16);
+    }
+    UBool hasCompBoundaryBefore(const UChar *src, const UChar *limit) const;
+    UBool hasCompBoundaryBefore(const uint8_t *src, const uint8_t *limit) const;
+    UBool hasCompBoundaryAfter(const UChar *start, const UChar *p,
+                               UBool onlyContiguous) const;
+    UBool hasCompBoundaryAfter(const uint8_t *start, const uint8_t *p,
+                               UBool onlyContiguous) const;
+    UBool norm16HasCompBoundaryAfter(uint16_t norm16, UBool onlyContiguous) const {
+        return (norm16 & HAS_COMP_BOUNDARY_AFTER) != 0 &&
+            (!onlyContiguous || isTrailCC01ForCompBoundaryAfter(norm16));
+    }
+    /** For FCC: Given norm16 HAS_COMP_BOUNDARY_AFTER, does it have tccc<=1? */
+    UBool isTrailCC01ForCompBoundaryAfter(uint16_t norm16) const {
+        return isInert(norm16) || (isDecompNoAlgorithmic(norm16) ?
+            (norm16 & DELTA_TCCC_MASK) <= DELTA_TCCC_1 : *getMapping(norm16) <= 0x1ff);
+    }
+
+    const UChar *findPreviousCompBoundary(const UChar *start, const UChar *p, UBool onlyContiguous) const;
+    const UChar *findNextCompBoundary(const UChar *p, const UChar *limit, UBool onlyContiguous) const;
 
     const UChar *findPreviousFCDBoundary(const UChar *start, const UChar *p) const;
     const UChar *findNextFCDBoundary(const UChar *p, const UChar *limit) const;
 
+    void makeCanonIterDataFromNorm16(UChar32 start, UChar32 end, const uint16_t norm16,
+                                     CanonIterData &newData, UErrorCode &errorCode) const;
+
     int32_t getCanonValue(UChar32 c) const;
     const UnicodeSet &getCanonStartSet(int32_t n) const;
 
     // UVersionInfo dataVersion;
 
-    // Code point thresholds for quick check codes.
-    UChar32 minDecompNoCP;
-    UChar32 minCompNoMaybeCP;
+    // BMP code point thresholds for quick check loops looking at single UTF-16 code units.
+    UChar minDecompNoCP;
+    UChar minCompNoMaybeCP;
+    UChar minLcccCP;
 
     // Norm16 value thresholds for quick check combinations and types of extra data.
     uint16_t minYesNo;
     uint16_t minYesNoMappingsOnly;
     uint16_t minNoNo;
+    uint16_t minNoNoCompBoundaryBefore;
+    uint16_t minNoNoCompNoMaybeCC;
+    uint16_t minNoNoEmpty;
     uint16_t limitNoNo;
+    uint16_t centerNoNoDelta;
     uint16_t minMaybeYes;
 
-    const UTrie2 *normTrie;
+    const UCPTrie *normTrie;
     const uint16_t *maybeYesCompositions;
     const uint16_t *extraData;  // mappings and/or compositions for yesYes, yesNo & noNo characters
     const uint8_t *smallFCD;  // [0x100] one bit per 32 BMP code points, set if any FCD!=0
-    uint8_t tccc180[0x180];  // tccc values for U+0000..U+017F
 
-public:  // CanonIterData is public to allow access from C callback functions.
-    UInitOnce       fCanonIterDataInitOnce;
+    UInitOnce       fCanonIterDataInitOnce = U_INITONCE_INITIALIZER;
     CanonIterData  *fCanonIterData;
 };
 
@@ -656,13 +776,14 @@
 
 /**
  * Format of Normalizer2 .nrm data files.
- * Format version 2.0.
+ * Format version 4.0.
  *
  * Normalizer2 .nrm data files provide data for the Unicode Normalization algorithms.
  * ICU ships with data files for standard Unicode Normalization Forms
  * NFC and NFD (nfc.nrm), NFKC and NFKD (nfkc.nrm) and NFKC_Casefold (nfkc_cf.nrm).
  * Custom (application-specific) data can be built into additional .nrm files
  * with the gennorm2 build tool.
+ * ICU ships with one such file, uts46.nrm, for the implementation of UTS #46.
  *
  * Normalizer2.getInstance() causes a .nrm file to be loaded, unless it has been
  * cached already. Internally, Normalizer2Impl.load() reads the .nrm file.
@@ -693,27 +814,35 @@
  *      with a decomposition mapping, that is, with NF*D_QC=No.
  *      minCompNoMaybeCP=indexes[IX_MIN_COMP_NO_MAYBE_CP] is the lowest code point
  *      with NF*C_QC=No (has a one-way mapping) or Maybe (combines backward).
+ *      minLcccCP=indexes[IX_MIN_LCCC_CP] (index 18, new in formatVersion 3)
+ *      is the lowest code point with lccc!=0.
  *
- *      The next five indexes are thresholds of 16-bit trie values for ranges of
+ *      The next eight indexes are thresholds of 16-bit trie values for ranges of
  *      values indicating multiple normalization properties.
+ *      They are listed here in threshold order, not in the order they are stored in the indexes.
  *          minYesNo=indexes[IX_MIN_YES_NO];
+ *          minYesNoMappingsOnly=indexes[IX_MIN_YES_NO_MAPPINGS_ONLY];
  *          minNoNo=indexes[IX_MIN_NO_NO];
+ *          minNoNoCompBoundaryBefore=indexes[IX_MIN_NO_NO_COMP_BOUNDARY_BEFORE];
+ *          minNoNoCompNoMaybeCC=indexes[IX_MIN_NO_NO_COMP_NO_MAYBE_CC];
+ *          minNoNoEmpty=indexes[IX_MIN_NO_NO_EMPTY];
  *          limitNoNo=indexes[IX_LIMIT_NO_NO];
  *          minMaybeYes=indexes[IX_MIN_MAYBE_YES];
- *          minYesNoMappingsOnly=indexes[IX_MIN_YES_NO_MAPPINGS_ONLY];
  *      See the normTrie description below and the design doc for details.
  *
- * UTrie2 normTrie; -- see utrie2_impl.h and utrie2.h
+ * UCPTrie normTrie; -- see ucptrie_impl.h and ucptrie.h, same as Java CodePointTrie
  *
  *      The trie holds the main normalization data. Each code point is mapped to a 16-bit value.
  *      Rather than using independent bits in the value (which would require more than 16 bits),
  *      information is extracted primarily via range checks.
+ *      Except, format version 3 uses bit 0 for hasCompBoundaryAfter().
  *      For example, a 16-bit value norm16 in the range minYesNo<=norm16<minNoNo
  *      means that the character has NF*C_QC=Yes and NF*D_QC=No properties,
  *      which means it has a two-way (round-trip) decomposition mapping.
  *      Values in the range 2<=norm16<limitNoNo are also directly indexes into the extraData
  *      pointing to mappings, compositions lists, or both.
- *      Value norm16==0 means that the character is normalization-inert, that is,
+ *      Value norm16==INERT (0 in versions 1 & 2, 1 in version 3)
+ *      means that the character is normalization-inert, that is,
  *      it does not have a mapping, does not participate in composition, has a zero
  *      canonical combining class, and forms a boundary where text before it and after it
  *      can be normalized independently.
@@ -727,7 +856,7 @@
  *      The trie has a value for each lead surrogate code unit representing the "worst case"
  *      properties of the 1024 supplementary characters whose UTF-16 form starts with
  *      the lead surrogate. If all of the 1024 supplementary characters are normalization-inert,
- *      then their lead surrogate code unit has the trie value 0.
+ *      then their lead surrogate code unit has the trie value INERT.
  *      When the lead surrogate unit's value exceeds the quick check minimum during processing,
  *      the properties for the full supplementary code point need to be looked up.
  *
@@ -736,6 +865,7 @@
  *
  *      There is only one byte offset for the end of these two arrays.
  *      The split between them is given by the constant and variable mentioned above.
+ *      In version 3, the difference must be shifted right by OFFSET_SHIFT.
  *
  *      The maybeYesCompositions array contains compositions lists for characters that
  *      combine both forward (as starters in composition pairs)
@@ -752,6 +882,8 @@
  *      followed by only mappings for "NoNo" characters.
  *      (Referring to pairs of NFC/NFD quick check values.)
  *      The norm16 values of those characters are directly indexes into the extraData array.
+ *      In version 3, the norm16 values must be shifted right by OFFSET_SHIFT
+ *      for accessing extraData.
  *
  *      The data structures for compositions lists and mappings are described in the design doc.
  *
@@ -782,6 +914,64 @@
  *   This is fully equivalent with formatVersion 1's MAPPING_PLUS_COMPOSITION_LIST flag.
  *   It is needed for the new (in ICU 49) composePair(), not for other normalization.
  * - Addition of the smallFCD[] bit set.
+ *
+ * Changes from format version 2 to format version 3 (ICU 60) ------------------
+ *
+ * - norm16 bit 0 indicates hasCompBoundaryAfter(),
+ *   except that for contiguous composition (FCC) the tccc must be checked as well.
+ *   Data indexes and ccc values are shifted left by one (OFFSET_SHIFT).
+ *   Thresholds like minNoNo are tested before shifting.
+ *
+ * - Algorithmic mapping deltas are shifted left by two more bits (total DELTA_SHIFT),
+ *   to make room for two bits (three values) indicating whether the tccc is 0, 1, or greater.
+ *   See DELTA_TCCC_MASK etc.
+ *   This helps with fetching tccc/FCD values and FCC hasCompBoundaryAfter().
+ *   minMaybeYes is 8-aligned so that the DELTA_TCCC_MASK bits can be tested directly.
+ *
+ * - Algorithmic mappings are only used for mapping to "comp yes and ccc=0" characters,
+ *   and ASCII characters are mapped algorithmically only to other ASCII characters.
+ *   This helps with hasCompBoundaryBefore() and compose() fast paths.
+ *   It is never necessary any more to loop for algorithmic mappings.
+ *
+ * - Addition of indexes[IX_MIN_NO_NO_COMP_BOUNDARY_BEFORE],
+ *   indexes[IX_MIN_NO_NO_COMP_NO_MAYBE_CC], and indexes[IX_MIN_NO_NO_EMPTY],
+ *   and separation of the noNo extraData into distinct ranges.
+ *   With this, the noNo norm16 value indicates whether the mapping is
+ *   compose-normalized, not normalized but hasCompBoundaryBefore(),
+ *   not even that, or maps to an empty string.
+ *   hasCompBoundaryBefore() can be determined solely from the norm16 value.
+ *
+ * - The norm16 value for Hangul LVT is now different from that for Hangul LV,
+ *   so that hasCompBoundaryAfter() need not check for the syllable type.
+ *   For Hangul LV, minYesNo continues to be used (no comp-boundary-after).
+ *   For Hangul LVT, minYesNoMappingsOnly|HAS_COMP_BOUNDARY_AFTER is used.
+ *   The extraData units at these indexes are set to firstUnit=2 and firstUnit=3, respectively,
+ *   to simplify some code.
+ *
+ * - The extraData firstUnit bit 5 is no longer necessary
+ *   (norm16 bit 0 used instead of firstUnit MAPPING_NO_COMP_BOUNDARY_AFTER),
+ *   is reserved again, and always set to 0.
+ *
+ * - Addition of indexes[IX_MIN_LCCC_CP], the first code point where lccc!=0.
+ *   This used to be hardcoded to U+0300, but in data like NFKC_Casefold it is lower:
+ *   U+00AD Soft Hyphen maps to an empty string,
+ *   which is artificially assigned "worst case" values lccc=1 and tccc=255.
+ *
+ * - A mapping to an empty string has explicit lccc=1 and tccc=255 values.
+ *
+ * Changes from format version 3 to format version 4 (ICU 63) ------------------
+ *
+ * Switched from UTrie2 to UCPTrie/CodePointTrie.
+ *
+ * The new trie no longer stores different values for surrogate code *units* vs.
+ * surrogate code *points*.
+ * Lead surrogates still have values for optimized UTF-16 string processing.
+ * When looking up code point properties, the code now checks for lead surrogates and
+ * treats them as inert.
+ *
+ * gennorm2 now has to reject mappings for surrogate code points.
+ * UTS #46 maps unpaired surrogates to U+FFFD in code rather than via its
+ * custom normalization data file.
  */
 
 #endif  /* !UCONFIG_NO_NORMALIZATION */
diff --git a/src/third_party/icu/source/common/normlzr.cpp b/src/third_party/icu/source/common/normlzr.cpp
index 81af0f3..feb793d 100644
--- a/src/third_party/icu/source/common/normlzr.cpp
+++ b/src/third_party/icu/source/common/normlzr.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
  *************************************************************************
  * COPYRIGHT: 
@@ -10,7 +12,9 @@
 
 #if !UCONFIG_NO_NORMALIZATION
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/uniset.h"
 #include "unicode/unistr.h"
 #include "unicode/chariter.h"
@@ -22,6 +26,12 @@
 #include "normalizer2impl.h"
 #include "uprops.h"  // for uniset_getUnicode32Instance()
 
+#if defined(move32)
+ // System can define move32 intrinsics, but the char iters define move32 method
+ // using same undef trick in headers, so undef here to re-enable the method.
+#undef move32
+#endif
+
 U_NAMESPACE_BEGIN
 
 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(Normalizer)
@@ -39,7 +49,7 @@
     init();
 }
 
-Normalizer::Normalizer(const UChar *str, int32_t length, UNormalizationMode mode) :
+Normalizer::Normalizer(ConstChar16Ptr str, int32_t length, UNormalizationMode mode) :
     UObject(), fFilteredNorm2(NULL), fNorm2(NULL), fUMode(mode), fOptions(0),
     text(new UCharCharacterIterator(str, length)),
     currentIndex(0), nextIndex(0),
@@ -434,7 +444,7 @@
 }
 
 void
-Normalizer::setText(const UChar* newText,
+Normalizer::setText(ConstChar16Ptr newText,
                     int32_t length,
                     UErrorCode &status)
 {
diff --git a/src/third_party/icu/source/common/parsepos.cpp b/src/third_party/icu/source/common/parsepos.cpp
index 26f8820..56c6c78 100644
--- a/src/third_party/icu/source/common/parsepos.cpp
+++ b/src/third_party/icu/source/common/parsepos.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
 *   Copyright (C) 2003-2003, International Business Machines
diff --git a/src/third_party/icu/source/common/patternprops.cpp b/src/third_party/icu/source/common/patternprops.cpp
index b2c5249..c38a7e2 100644
--- a/src/third_party/icu/source/common/patternprops.cpp
+++ b/src/third_party/icu/source/common/patternprops.cpp
@@ -1,10 +1,12 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *   Copyright (C) 2011, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *******************************************************************************
 *   file name:  patternprops.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -171,6 +173,16 @@
     return s;
 }
 
+int32_t
+PatternProps::skipWhiteSpace(const UnicodeString& s, int32_t start) {
+    int32_t i = start;
+    int32_t length = s.length();
+    while(i<length && isWhiteSpace(s.charAt(i))) {
+        ++i;
+    }
+    return i;
+}
+
 const UChar *
 PatternProps::trimWhiteSpace(const UChar *s, int32_t &length) {
     if(length<=0 || (!isWhiteSpace(s[0]) && !isWhiteSpace(s[length-1]))) {
diff --git a/src/third_party/icu/source/common/patternprops.h b/src/third_party/icu/source/common/patternprops.h
index 0ceab51..95898d5 100644
--- a/src/third_party/icu/source/common/patternprops.h
+++ b/src/third_party/icu/source/common/patternprops.h
@@ -1,10 +1,12 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *   Copyright (C) 2011, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *******************************************************************************
 *   file name:  patternprops.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -15,6 +17,7 @@
 #ifndef __PATTERNPROPS_H__
 #define __PATTERNPROPS_H__
 
+#include "unicode/unistr.h"
 #include "unicode/utypes.h"
 
 U_NAMESPACE_BEGIN
@@ -41,17 +44,17 @@
 class U_COMMON_API PatternProps {
 public:
     /**
-     * @return TRUE if c is a Pattern_Syntax code point.
+     * @return true if c is a Pattern_Syntax code point.
      */
     static UBool isSyntax(UChar32 c);
 
     /**
-     * @return TRUE if c is a Pattern_Syntax or Pattern_White_Space code point.
+     * @return true if c is a Pattern_Syntax or Pattern_White_Space code point.
      */
     static UBool isSyntaxOrWhiteSpace(UChar32 c);
 
     /**
-     * @return TRUE if c is a Pattern_White_Space character.
+     * @return true if c is a Pattern_White_Space character.
      */
     static UBool isWhiteSpace(UChar32 c);
 
@@ -62,6 +65,12 @@
     static const UChar *skipWhiteSpace(const UChar *s, int32_t length);
 
     /**
+     * Skips over Pattern_White_Space starting at index start in s.
+     * @return The smallest index at or after start with a non-white space character.
+     */
+    static int32_t skipWhiteSpace(const UnicodeString &s, int32_t start);
+
+    /**
      * @return s except with leading and trailing Pattern_White_Space removed and length adjusted.
      */
     static const UChar *trimWhiteSpace(const UChar *s, int32_t &length);
@@ -69,7 +78,7 @@
     /**
      * Tests whether the string contains a "pattern identifier", that is,
      * whether it contains only non-Pattern_White_Space, non-Pattern_Syntax characters.
-     * @return TRUE if there are no Pattern_White_Space or Pattern_Syntax characters in s.
+     * @return true if there are no Pattern_White_Space or Pattern_Syntax characters in s.
      */
     static UBool isIdentifier(const UChar *s, int32_t length);
 
diff --git a/src/third_party/icu/source/common/pluralmap.cpp b/src/third_party/icu/source/common/pluralmap.cpp
index 08a183b..92744b3 100644
--- a/src/third_party/icu/source/common/pluralmap.cpp
+++ b/src/third_party/icu/source/common/pluralmap.cpp
@@ -1,9 +1,13 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
  * Copyright (C) 2015, International Business Machines Corporation and
  * others. All Rights Reserved.
  */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/unistr.h"
 #include "charstr.h"
 #include "cstring.h"
diff --git a/src/third_party/icu/source/common/pluralmap.h b/src/third_party/icu/source/common/pluralmap.h
index 63ccf8d..d898ac4 100644
--- a/src/third_party/icu/source/common/pluralmap.h
+++ b/src/third_party/icu/source/common/pluralmap.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 * Copyright (C) 2015, International Business Machines Corporation and
@@ -232,7 +234,7 @@
     }
 
     /**
-     * Returns TRUE if this object equals rhs.
+     * Returns true if this object equals rhs.
      */
     UBool equals(
             const PluralMap<T> &rhs,
@@ -242,13 +244,13 @@
                 continue;
             }
             if (fVariants[i] == NULL || rhs.fVariants[i] == NULL) {
-                return FALSE;
+                return false;
             }
             if (!eqFunc(*fVariants[i], *rhs.fVariants[i])) {
-                return FALSE;
+                return false;
             }
         }
-        return TRUE;
+        return true;
     }
 
 private:
diff --git a/src/third_party/icu/source/common/propname.cpp b/src/third_party/icu/source/common/propname.cpp
index 7e37af9..e5d1131 100644
--- a/src/third_party/icu/source/common/propname.cpp
+++ b/src/third_party/icu/source/common/propname.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
 * Copyright (c) 2002-2014, International Business Machines
@@ -9,7 +11,9 @@
 * 2010nov19 Markus Scherer  Rewrite for formatVersion 2.
 **********************************************************************
 */
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "propname.h"
 #include "unicode/uchar.h"
 #include "unicode/udata.h"
diff --git a/src/third_party/icu/source/common/propname.h b/src/third_party/icu/source/common/propname.h
index c20ae45..1a8ced5 100644
--- a/src/third_party/icu/source/common/propname.h
+++ b/src/third_party/icu/source/common/propname.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
 * Copyright (c) 2002-2011, International Business Machines
diff --git a/src/third_party/icu/source/common/propname_data.h b/src/third_party/icu/source/common/propname_data.h
index 521b9db..6f63e9c 100644
--- a/src/third_party/icu/source/common/propname_data.h
+++ b/src/third_party/icu/source/common/propname_data.h
@@ -1,238 +1,265 @@
-/*
- * Copyright (C) 1999-2016, International Business Machines
- * Corporation and others.  All Rights Reserved.
- *
- * file name: propname_data.h
- *
- * machine-generated by: icu/tools/unicode/c/genprops/pnamesbuilder.cpp
- */
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+//
+// Copyright (C) 1999-2016, International Business Machines
+// Corporation and others.  All Rights Reserved.
+//
+// file name: propname_data.h
+//
+// machine-generated by: icu/tools/unicode/c/genprops/pnamesbuilder.cpp
 
-#ifndef INCLUDED_FROM_PROPNAME_CPP
-#   error This file must be #included from propname.cpp only.
-#endif
+
+#ifdef INCLUDED_FROM_PROPNAME_CPP
 
 U_NAMESPACE_BEGIN
 
-const int32_t PropNameData::indexes[8]={0x20,0x12d0,0x446f,0x8a58,0x8a58,0x8a58,0x2f,0};
+const int32_t PropNameData::indexes[8]={0x20,0x15b8,0x5048,0xa69a,0xa69a,0xa69a,0x2f,0};
 
-const int32_t PropNameData::valueMaps[1196]={
-6,0,0x3d,0,0xd5,0x356,0xd5,0x36c,0xd5,0x381,0xd5,0x397,0xd5,0x3a2,0xd5,0x3c3,
-0xd5,0x3d3,0xd5,0x3e2,0xd5,0x3f0,0xd5,0x414,0xd5,0x42b,0xd5,0x443,0xd5,0x45a,0xd5,0x469,
-0xd5,0x478,0xd5,0x489,0xd5,0x497,0xd5,0x4a9,0xd5,0x4c3,0xd5,0x4de,0xd5,0x4f3,0xd5,0x510,
-0xd5,0x521,0xd5,0x52c,0xd5,0x54b,0xd5,0x561,0xd5,0x572,0xd5,0x582,0xd5,0x59d,0xd5,0x5b6,
-0xd5,0x5c7,0xd5,0x5e1,0xd5,0x5f4,0xd5,0x604,0xd5,0x61e,0xd5,0x62b,0xd5,0x642,0xd5,0x656,
-0xd5,0x66c,0xd5,0x680,0xd5,0x696,0xd5,0x6b0,0xd5,0x6c8,0xd5,0x6e4,0xd5,0x6ec,0xd5,0x6f4,
-0xd5,0x6fc,0xd5,0x704,0xd5,0x70d,0xd5,0x71a,0xd5,0x72d,0xd5,0x74a,0xd5,0x767,0xd5,0x784,
-0xd5,0x7a2,0xd5,0x7c0,0xd5,0x7e4,0xd5,0x7f1,0xd5,0x818,0xd5,0x837,0xd5,0x1000,0x1016,0x860,
-0x14f,0xa80,0x16a,0x292f,0xdb,0x294e,0x275,0x2a8c,0x28b,0x2ae6,0x295,0x2d43,0x2b7,0x3458,0x311,0x34c8,
-0x31b,0x3756,0x347,0x3794,0x34f,0x40ea,0x3fa,0x4168,0x404,0x418d,0x40a,0x41a7,0x410,0x41c8,0x417,0x41e2,
-0xdb,0x4207,0xdb,0x422d,0x41e,0x42b3,0x42f,0x432c,0x442,0x43c9,0x457,0x2000,0x2001,0x4400,0x45e,0x3000,
-0x3001,0x448c,0,0x4000,0x400e,0x449e,0,0x44a7,0,0x44c1,0,0x44d2,0,0x44e3,0,0x44f9,
-0,0x4502,0,0x451f,0,0x453d,0,0x455b,0,0x4579,0,0x458f,0,0x45a3,0,0x45b9,
-0,0x7000,0x7001,0x45d2,0,0x6f5,0x12,0,1,0x12,0x20,0x713,0x49,0,1,7,
-8,9,0xa,0xb,0xc,0xd,0xe,0xf,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x54,0x5b,0x67,
-0x6b,0x76,0x7a,0x81,0x82,0x84,0x85,0xc8,0xca,0xd6,0xd8,0xda,0xdc,0xde,0xe0,0xe2,
-0xe4,0xe6,0xe8,0xe9,0xea,0xf0,0x2e,0x40,0x4c,0x56,0x67,0x72,0x7f,0x8c,0x99,0xa6,
-0xb3,0xc0,0xcd,0xda,0xe7,0xf4,0x101,0x10e,0x11b,0x128,0x135,0x142,0x14f,0x15c,0x169,0x176,
-0x183,0x190,0x19d,0x1aa,0x1b7,0x1c4,0x1d1,0x1de,0x1eb,0x1fa,0x209,0x218,0x227,0x236,0x245,0x254,
-0x263,0x27d,0x291,0x2a5,0x2c0,0x2cf,0x2d8,0x2e8,0x2f0,0x2f9,0x308,0x311,0x321,0x332,0x343,0x8a5,
-1,0,0x17,0x86f,0x880,0x891,0x8a5,0x8bc,0x8d4,0x8e6,0x8fb,0x912,0x927,0x937,0x949,0x966,
-0x982,0x994,0x9b1,0x9cd,0x9e9,0x9fe,0xa13,0xa2d,0xa48,0xa63,0xa47,1,0,0x107,0xa8b,0xa98,
-0xaab,0xad3,0xaf1,0xb0f,0xb27,0xb52,0xb7c,0xb94,0xba7,0xbba,0xbc9,0xbd8,0xbe7,0xbf6,0xc0d,0xc1e,
-0xc31,0xc44,0xc51,0xc5e,0xc6d,0xc7e,0xc93,0xca4,0xcaf,0xcb8,0xcc9,0xcda,0xced,0xcff,0xd12,0xd25,
-0xd64,0xd71,0xd7e,0xd8b,0xda0,0xdd0,0xdea,0xe0b,0xe36,0xe59,0xeb7,0xede,0xef9,0xf08,0xf2f,0xf57,
-0xf7a,0xf9d,0xfc7,0xfe0,0xfff,0x1022,0x1046,0x1059,0x1073,0x109d,0x10b5,0x10dd,0x1106,0x1119,0x112c,0x113f,
-0x1166,0x1175,0x1195,0x11c3,0x11e1,0x120f,0x122b,0x1246,0x125f,0x1278,0x1299,0x12c9,0x12e8,0x130a,0x133e,0x136b,
-0x13b0,0x13d1,0x13fb,0x141c,0x1445,0x1458,0x148b,0x14a2,0x14b1,0x14c2,0x14ed,0x1504,0x1535,0x1563,0x15a6,0x15b1,
-0x15ea,0x15fb,0x160c,0x1619,0x162c,0x1666,0x168a,0x16ae,0x16e8,0x1720,0x174b,0x1763,0x178f,0x17bb,0x17c8,0x17d7,
-0x17f4,0x1816,0x1844,0x1864,0x188b,0x18b2,0x18d1,0x18e4,0x18f5,0x1906,0x192b,0x1950,0x1977,0x19ab,0x19d8,0x19f6,
-0x1a09,0x1a22,0x1a5b,0x1a6a,0x1a8a,0x1aac,0x1ace,0x1ae5,0x1afc,0x1b29,0x1b42,0x1b5b,0x1b8c,0x1bb6,0x1bd1,0x1be4,
-0x1c03,0x1c0c,0x1c1f,0x1c3d,0x1c5b,0x1c6e,0x1c85,0x1c9a,0x1ccf,0x1cf3,0x1d08,0x1d17,0x1d2a,0x1d4e,0x1d57,0x1d7b,
-0x1d92,0x1da5,0x1db4,0x1dbf,0x1de0,0x1df8,0x1e07,0x1e16,0x1e25,0x1e3c,0x1e51,0x1e66,0x1e9f,0x1eb2,0x1ece,0x1ed9,
-0x1ee6,0x1f14,0x1f38,0x1f5b,0x1f6e,0x1f90,0x1fa3,0x1fbe,0x1fe1,0x2004,0x2029,0x203a,0x2069,0x2096,0x20ad,0x20c8,
-0x20d7,0x2102,0x213a,0x2174,0x21a2,0x21b3,0x21c0,0x21e4,0x21f3,0x220f,0x2229,0x2246,0x227e,0x2293,0x22c0,0x22df,
-0x230d,0x232d,0x2361,0x2370,0x239a,0x23bd,0x23e8,0x23f3,0x2404,0x241f,0x2443,0x2450,0x2465,0x248c,0x24b7,0x24ee,
-0x2501,0x2512,0x2542,0x2553,0x2562,0x2577,0x2595,0x25a8,0x25bb,0x25d2,0x25ef,0x25fa,0x2603,0x2625,0x263a,0x265f,
-0x2676,0x269f,0x26ba,0x26cf,0x26e8,0x2709,0x273e,0x274f,0x2780,0x27a4,0x27b5,0x27ce,0x27d9,0x2806,0x2828,0x2856,
-0x2889,0x2898,0x28a9,0x28c6,0x2908,0x1afc,1,0,0x12,0x2965,0x2975,0x2988,0x2998,0x29a8,0x29b7,0x29c7,
-0x29d9,0x29ec,0x29fe,0x2a0e,0x2a1e,0x2a2d,0x2a3c,0x2a4c,0x2a59,0x2a68,0x2a7c,0x1bba,1,0,6,0x2aa1,
-0x2aac,0x2ab9,0x2ac6,0x2ad3,0x2ade,0x1bfe,1,0,0x1e,0x2afb,0x2b0a,0x2b1f,0x2b34,0x2b49,0x2b5d,0x2b6e,
-0x2b82,0x2b95,0x2ba6,0x2bbf,0x2bd1,0x2be2,0x2bf6,0x2c09,0x2c21,0x2c33,0x2c3e,0x2c4e,0x2c5c,0x2c71,0x2c86,0x2c9c,
-0x2cb6,0x2ccc,0x2cdc,0x2cf0,0x2d04,0x2d15,0x2d2d,0x1e29,1,0,0x56,0x2d55,0x2d78,0x2d81,0x2d8e,0x2d99,
-0x2da2,0x2dad,0x2db6,0x2dcf,0x2dd4,0x2ddd,0x2dfa,0x2e03,0x2e10,0x2e19,0x2e3d,0x2e44,0x2e4d,0x2e60,0x2e6b,0x2e74,
-0x2e7f,0x2e98,0x2ea1,0x2eb0,0x2ebb,0x2ec4,0x2ecf,0x2ed8,0x2edf,0x2ee8,0x2ef3,0x2efc,0x2f15,0x2f1e,0x2f2b,0x2f36,
-0x2f47,0x2f52,0x2f67,0x2f7e,0x2f87,0x2f90,0x2fa9,0x2fb4,0x2fbd,0x2fc6,0x2fdd,0x2ffa,0x3005,0x3016,0x3021,0x3028,
-0x3035,0x3042,0x306f,0x3084,0x308d,0x30a8,0x30cb,0x30ec,0x310d,0x3132,0x3159,0x317a,0x319d,0x31be,0x31e5,0x3206,
-0x322b,0x324a,0x3269,0x3288,0x32a5,0x32c6,0x32e7,0x330a,0x332f,0x334e,0x336d,0x338e,0x33b5,0x33da,0x33f9,0x341a,
-0x343d,0x20dd,1,0,6,0x3469,0x3478,0x3488,0x3498,0x34a8,0x34b9,0x213b,1,0,0x28,0x34d7,
-0x34e3,0x34f1,0x3500,0x350f,0x351f,0x3530,0x3544,0x3559,0x356f,0x3582,0x3596,0x35a6,0x35af,0x35ba,0x35ca,0x35e6,
-0x35f8,0x3606,0x3615,0x3621,0x3636,0x364a,0x365d,0x366b,0x367f,0x368d,0x3697,0x36a9,0x36b5,0x36c3,0x36d3,0x36da,
-0x36e1,0x36e8,0x36ef,0x36f6,0x370c,0x372d,0x373f,0x237d,1,0,4,0x3767,0x3772,0x377e,0x3788,0x23a3,
-1,0,0xa7,0x379f,0x37ac,0x37c1,0x37ce,0x37dd,0x37eb,0x37fa,0x3809,0x381b,0x382a,0x3838,0x3849,0x3858,
-0x3867,0x3874,0x3880,0x388f,0x389e,0x38a8,0x38b5,0x38c2,0x38d1,0x38df,0x38ee,0x38fa,0x3904,0x3910,0x3920,0x3930,
-0x393e,0x394a,0x395b,0x3967,0x3973,0x3981,0x398e,0x399a,0x39a7,0xca4,0x39b4,0x39c2,0x39dc,0x39e5,0x39f3,0x3a01,
-0x3a0d,0x3a1c,0x3a2a,0x3a38,0x3a44,0x3a53,0x3a61,0x3a6f,0x3a7c,0x3a8b,0x3aa6,0x3ab5,0x3ac6,0x3ad7,0x3aea,0x3afc,
-0x3b0b,0x3b1d,0x3b2c,0x3b38,0x3b43,0x1db4,0x3b50,0x3b5b,0x3b66,0x3b71,0x3b7c,0x3b97,0x3ba2,0x3bad,0x3bb8,0x3bcb,
-0x3bdf,0x3bea,0x3bf9,0x3c08,0x3c13,0x3c1e,0x3c2b,0x3c3a,0x3c48,0x3c53,0x3c6e,0x3c78,0x3c89,0x3c9a,0x3ca9,0x3cba,
-0x3cc5,0x3cd0,0x3cdb,0x3ce6,0x3cf1,0x3cfc,0x3d07,0x3d11,0x3d1c,0x3d2c,0x3d37,0x3d45,0x3d52,0x3d5d,0x3d6c,0x3d79,
-0x3d86,0x3d95,0x3da2,0x3db3,0x3dc5,0x3dd5,0x3de0,0x3df3,0x3e0a,0x3e18,0x3e25,0x3e30,0x3e3d,0x3e4e,0x3e6a,0x3e80,
-0x3e8b,0x3ea8,0x3eb8,0x3ec7,0x3ed2,0x3edd,0x1ece,0x3ee9,0x3ef4,0x3f0c,0x3f1c,0x3f2b,0x3f39,0x3f47,0x3f52,0x3f5d,
-0x3f71,0x3f88,0x3fa0,0x3fb0,0x3fc0,0x3fd0,0x3fe2,0x3fed,0x3ff8,0x4002,0x400d,0x401b,0x402e,0x403a,0x4045,0x4050,
-0x406c,0x4079,0x4087,0x40a0,0x27ce,0x40af,0x25ef,0x40bc,0x40ca,0x40dc,0x2c00,1,0,6,0x4104,0x4117,
-0x4127,0x4135,0x4146,0x4156,0x2c5c,0x12,0,1,0x4180,0x4186,0x2c69,0x12,0,1,0x4180,0x4186,
-0x2c76,1,0,3,0x4180,0x4186,0x41bf,0x2c8c,1,0,3,0x4180,0x4186,0x41bf,0x2ca2,1,
-0,0xd,0x4249,0x4253,0x425f,0x4266,0x4271,0x4276,0x427d,0x4284,0x428d,0x4292,0x4297,0x42a7,0x373f,0x2d10,
-1,0,0xf,0x4249,0x42c6,0x42d0,0x42da,0x42e5,0x3615,0x42ef,0x42fb,0x4303,0x430a,0x4314,0x425f,0x4266,
-0x4276,0x431e,0x2d97,1,0,0x11,0x4249,0x433b,0x42da,0x4347,0x4354,0x4362,0x3615,0x436d,0x425f,0x437e,
-0x4276,0x438d,0x439b,0x373f,0x372d,0x43a7,0x43b8,0x2e6f,1,0,3,0x43e7,0x43ef,0x43f7,0x2e88,0x36,
-1,2,4,8,0xe,0x10,0x20,0x3e,0x40,0x80,0x100,0x1c0,0x200,0x400,0x800,0xe00,
-0x1000,0x2000,0x4000,0x7000,0x8000,0x10000,0x20000,0x40000,0x78001,0x80000,0x100000,0x200000,0x400000,0x800000,0x1000000,0x2000000,
-0x4000000,0x8000000,0xf000000,0x10000000,0x20000000,0x30f80000,0x2afb,0x2b0a,0x2b1f,0x2b34,0x442e,0x2b49,0x2b5d,0x4424,0x2b6e,0x2b82,
-0x2b95,0x443f,0x2ba6,0x2bbf,0x2bd1,0x4456,0x2be2,0x2bf6,0x2c09,0x447f,0x2c21,0x2c33,0x2c3e,0x2c4e,0x441b,0x2c5c,
-0x2c71,0x2c86,0x2c9c,0x2cb6,0x2ccc,0x2cdc,0x2cf0,0x2d04,0x4475,0x2d15,0x2d2d,0x4460
+const int32_t PropNameData::valueMaps[1382]={
+6,0,0x41,0,0xe3,0x368,0xe3,0x37e,0xe3,0x393,0xe3,0x3a9,0xe3,0x3b4,0xe3,0x3d5,
+0xe3,0x3e5,0xe3,0x3f4,0xe3,0x402,0xe3,0x426,0xe3,0x43d,0xe3,0x455,0xe3,0x46c,0xe3,0x47b,
+0xe3,0x48a,0xe3,0x49b,0xe3,0x4a9,0xe3,0x4bb,0xe3,0x4d5,0xe3,0x4f0,0xe3,0x505,0xe3,0x522,
+0xe3,0x533,0xe3,0x53e,0xe3,0x55d,0xe3,0x573,0xe3,0x584,0xe3,0x594,0xe3,0x5af,0xe3,0x5c8,
+0xe3,0x5d9,0xe3,0x5f3,0xe3,0x606,0xe3,0x616,0xe3,0x630,0xe3,0x649,0xe3,0x660,0xe3,0x674,
+0xe3,0x68a,0xe3,0x69e,0xe3,0x6b4,0xe3,0x6ce,0xe3,0x6e6,0xe3,0x702,0xe3,0x70a,0xe3,0x712,
+0xe3,0x71a,0xe3,0x722,0xe3,0x72b,0xe3,0x738,0xe3,0x74b,0xe3,0x768,0xe3,0x785,0xe3,0x7a2,
+0xe3,0x7c0,0xe3,0x7de,0xe3,0x802,0xe3,0x80f,0xe3,0x829,0xe3,0x83e,0xe3,0x859,0xe3,0x870,
+0xe3,0x887,0xe3,0x8a9,0xe3,0x1000,0x1019,0x8c8,0x15f,0xae8,0x17a,0x2f11,0xe9,0x2f30,0x2b3,0x306e,
+0x2c9,0x30c8,0x2d3,0x3325,0x2f5,0x3c20,0x35f,0x3c90,0x369,0x3f2a,0x398,0x3f68,0x3a0,0x4a5b,0x465,0x4ad9,
+0x46f,0x4afe,0x475,0x4b18,0x47b,0x4b39,0x482,0x4b53,0xe9,0x4b78,0xe9,0x4b9e,0x489,0x4c48,0x49f,0x4cc1,
+0x4b2,0x4d73,0x4cd,0x4daa,0x4d4,0x4f8a,0x4e8,0x540a,0x510,0x2000,0x2001,0x5469,0x518,0x3000,0x3001,0x54f5,
+0,0x4000,0x400e,0x5507,0,0x5510,0,0x552a,0,0x553b,0,0x554c,0,0x5562,0,0x556b,
+0,0x5588,0,0x55a6,0,0x55c4,0,0x55e2,0,0x55f8,0,0x560c,0,0x5622,0,0x7000,
+0x7001,0x563b,0,0x7d6,0x12,0,1,0x12,0x20,0x7f4,0x4a,0,1,6,7,8,
+9,0xa,0xb,0xc,0xd,0xe,0xf,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,
+0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x54,0x5b,0x67,0x6b,
+0x76,0x7a,0x81,0x82,0x84,0x85,0xc8,0xca,0xd6,0xd8,0xda,0xdc,0xde,0xe0,0xe2,0xe4,
+0xe6,0xe8,0xe9,0xea,0xf0,0x2e,0x40,0x4c,0x5e,0x68,0x79,0x84,0x91,0x9e,0xab,0xb8,
+0xc5,0xd2,0xdf,0xec,0xf9,0x106,0x113,0x120,0x12d,0x13a,0x147,0x154,0x161,0x16e,0x17b,0x188,
+0x195,0x1a2,0x1af,0x1bc,0x1c9,0x1d6,0x1e3,0x1f0,0x1fd,0x20c,0x21b,0x22a,0x239,0x248,0x257,0x266,
+0x275,0x28f,0x2a3,0x2b7,0x2d2,0x2e1,0x2ea,0x2fa,0x302,0x30b,0x31a,0x323,0x333,0x344,0x355,0x995,
+1,0,0x17,0x8d7,0x8e8,0x8f9,0x90d,0x924,0x93c,0x94e,0x963,0x97a,0x98f,0x99f,0x9b1,0x9ce,
+0x9ea,0x9fc,0xa19,0xa35,0xa51,0xa66,0xa7b,0xa95,0xab0,0xacb,0xb37,1,0,0x135,0xaf3,0xb00,
+0xb13,0xb3b,0xb59,0xb77,0xb8f,0xbba,0xbe4,0xbfc,0xc0f,0xc22,0xc31,0xc40,0xc4f,0xc5e,0xc75,0xc86,
+0xc99,0xcac,0xcb9,0xcc6,0xcd5,0xce6,0xcfb,0xd0c,0xd17,0xd20,0xd31,0xd42,0xd55,0xd67,0xd7a,0xd8d,
+0xdcc,0xdd9,0xde6,0xdf3,0xe08,0xe38,0xe52,0xe73,0xe9e,0xec1,0xf1f,0xf46,0xf61,0xf70,0xf97,0xfbf,
+0xfe2,0x1005,0x102f,0x1048,0x1067,0x108a,0x10ae,0x10c1,0x10db,0x1105,0x111d,0x1145,0x116e,0x1181,0x1194,0x11a7,
+0x11ce,0x11dd,0x11fd,0x122b,0x1249,0x1277,0x1293,0x12ae,0x12c7,0x12e0,0x1301,0x1331,0x1350,0x1372,0x13a6,0x13d3,
+0x1418,0x1439,0x1463,0x1484,0x14ad,0x14c0,0x14f3,0x150a,0x1519,0x152a,0x1555,0x156c,0x159d,0x15cb,0x160e,0x1619,
+0x1652,0x1663,0x1674,0x1681,0x1694,0x16ce,0x16f2,0x1716,0x1750,0x1788,0x17b3,0x17cb,0x17f7,0x1823,0x1830,0x183f,
+0x185c,0x187e,0x18ac,0x18cc,0x18f3,0x191a,0x1939,0x194c,0x195d,0x196e,0x1993,0x19b8,0x19df,0x1a13,0x1a40,0x1a5e,
+0x1a71,0x1a8a,0x1ac3,0x1ad2,0x1af2,0x1b14,0x1b36,0x1b4d,0x1b64,0x1b91,0x1baa,0x1bc3,0x1bf4,0x1c1e,0x1c39,0x1c4c,
+0x1c6b,0x1c74,0x1c87,0x1ca5,0x1cc3,0x1cd6,0x1ced,0x1d02,0x1d37,0x1d5b,0x1d70,0x1d7f,0x1d92,0x1db6,0x1dbf,0x1de3,
+0x1dfa,0x1e0d,0x1e1c,0x1e27,0x1e48,0x1e60,0x1e6f,0x1e7e,0x1e8d,0x1ea4,0x1eb9,0x1ece,0x1f07,0x1f1a,0x1f36,0x1f41,
+0x1f4e,0x1f7c,0x1fa0,0x1fc3,0x1fd6,0x1ff8,0x200b,0x2026,0x2049,0x206c,0x2091,0x20a2,0x20d1,0x20fe,0x2115,0x2130,
+0x213f,0x216a,0x21a2,0x21dc,0x220a,0x221b,0x2228,0x224c,0x225b,0x2277,0x2291,0x22ae,0x22e6,0x22fb,0x2328,0x2347,
+0x2375,0x2395,0x23c9,0x23d8,0x2402,0x2425,0x2450,0x245b,0x246c,0x2487,0x24ab,0x24b8,0x24cd,0x24f4,0x251f,0x2556,
+0x2569,0x257a,0x25aa,0x25bb,0x25ca,0x25df,0x25fd,0x2610,0x2623,0x263a,0x2657,0x2662,0x266b,0x268d,0x26a2,0x26c7,
+0x26de,0x2707,0x2722,0x2737,0x2750,0x2771,0x27a6,0x27b7,0x27e8,0x280c,0x281d,0x2836,0x2841,0x286e,0x2890,0x28be,
+0x28f1,0x2900,0x2911,0x292e,0x2970,0x2997,0x29a4,0x29b9,0x29dd,0x2a03,0x2a3c,0x2a4d,0x2a71,0x2a7c,0x2a89,0x2a98,
+0x2abd,0x2aeb,0x2b07,0x2b24,0x2b31,0x2b42,0x2b60,0x2b83,0x2ba0,0x2bad,0x2bcd,0x2bea,0x2c0b,0x2c34,0x2c45,0x2c64,
+0x2c7d,0x2c96,0x2ca7,0x2cf0,0x2d01,0x2d1a,0x2d49,0x2d76,0x2d9b,0x2ddd,0x2df9,0x2e08,0x2e1f,0x2e4d,0x2e66,0x2e8f,
+0x2ea9,0x2ee4,0x2f02,0x1e85,1,0,0x12,0x2f47,0x2f57,0x2f6a,0x2f7a,0x2f8a,0x2f99,0x2fa9,0x2fbb,0x2fce,
+0x2fe0,0x2ff0,0x3000,0x300f,0x301e,0x302e,0x303b,0x304a,0x305e,0x1f43,1,0,6,0x3083,0x308e,0x309b,
+0x30a8,0x30b5,0x30c0,0x1f87,1,0,0x1e,0x30dd,0x30ec,0x3101,0x3116,0x312b,0x313f,0x3150,0x3164,0x3177,
+0x3188,0x31a1,0x31b3,0x31c4,0x31d8,0x31eb,0x3203,0x3215,0x3220,0x3230,0x323e,0x3253,0x3268,0x327e,0x3298,0x32ae,
+0x32be,0x32d2,0x32e6,0x32f7,0x330f,0x21b2,1,0,0x66,0x3337,0x335a,0x3363,0x3370,0x337b,0x3384,0x338f,
+0x3398,0x33b1,0x33b6,0x33bf,0x33dc,0x33e5,0x33f2,0x33fb,0x341f,0x3426,0x342f,0x3442,0x344d,0x3456,0x3461,0x347a,
+0x3483,0x3492,0x349d,0x34a6,0x34b1,0x34ba,0x34c1,0x34ca,0x34d5,0x34de,0x34f7,0x3500,0x350d,0x3518,0x3529,0x3534,
+0x3549,0x3560,0x3569,0x3572,0x358b,0x3596,0x359f,0x35a8,0x35bf,0x35dc,0x35e7,0x35f8,0x3603,0x360a,0x3617,0x3624,
+0x3651,0x3666,0x366f,0x368a,0x36ad,0x36ce,0x36ef,0x3714,0x373b,0x375c,0x377f,0x37a0,0x37c7,0x37e8,0x380d,0x382c,
+0x384b,0x386a,0x3887,0x38a8,0x38c9,0x38ec,0x3911,0x3930,0x394f,0x3970,0x3997,0x39bc,0x39db,0x39fc,0x3a1f,0x3a3a,
+0x3a53,0x3a6e,0x3a87,0x3aa4,0x3abf,0x3adc,0x3afb,0x3b18,0x3b35,0x3b54,0x3b71,0x3b8c,0x3ba9,0x3bc6,0x3bf9,0x24f7,
+1,0,6,0x3c31,0x3c40,0x3c50,0x3c60,0x3c70,0x3c81,0x2555,1,0,0x2b,0x3c9f,0x3cab,0x3cb9,
+0x3cc8,0x3cd7,0x3ce7,0x3cf8,0x3d0c,0x3d21,0x3d37,0x3d4a,0x3d5e,0x3d6e,0x3d77,0x3d82,0x3d92,0x3dae,0x3dc0,0x3dce,
+0x3ddd,0x3de9,0x3dfe,0x3e12,0x3e25,0x3e33,0x3e47,0x3e55,0x3e5f,0x3e71,0x3e7d,0x3e8b,0x3e9b,0x3ea2,0x3ea9,0x3eb0,
+0x3eb7,0x3ebe,0x3ed4,0x3ef5,0x870,0x3f07,0x3f12,0x3f21,0x27ae,1,0,4,0x3f3b,0x3f46,0x3f52,0x3f5c,
+0x27d4,1,0,0xc1,0x3f73,0x3f80,0x3f95,0x3fa2,0x3fb1,0x3fbf,0x3fce,0x3fdd,0x3fef,0x3ffe,0x400c,0x401d,
+0x402c,0x403b,0x4048,0x4054,0x4063,0x4072,0x407c,0x4089,0x4096,0x40a5,0x40b3,0x40c2,0x40ce,0x40d8,0x40e4,0x40f4,
+0x4104,0x4112,0x411e,0x412f,0x413b,0x4147,0x4155,0x4162,0x416e,0x417b,0xd0c,0x4188,0x4196,0x41b0,0x41b9,0x41c7,
+0x41d5,0x41e1,0x41f0,0x41fe,0x420c,0x4218,0x4227,0x4235,0x4243,0x4250,0x425f,0x427a,0x4289,0x429a,0x42ab,0x42be,
+0x42d0,0x42df,0x42f1,0x4300,0x430c,0x4317,0x1e1c,0x4324,0x432f,0x433a,0x4345,0x4350,0x436b,0x4376,0x4381,0x438c,
+0x439f,0x43b3,0x43be,0x43cd,0x43dc,0x43e7,0x43f2,0x43ff,0x440e,0x441c,0x4427,0x4442,0x444c,0x445d,0x446e,0x447d,
+0x448e,0x4499,0x44a4,0x44af,0x44ba,0x44c5,0x44d0,0x44db,0x44e5,0x44f0,0x4500,0x450b,0x4519,0x4526,0x4531,0x4540,
+0x454d,0x455a,0x4569,0x4576,0x4587,0x4599,0x45a9,0x45b4,0x45c7,0x45de,0x45ec,0x45f9,0x4604,0x4611,0x4622,0x463e,
+0x4654,0x465f,0x467c,0x468c,0x469b,0x46a6,0x46b1,0x1f36,0x46bd,0x46c8,0x46e0,0x46f0,0x46ff,0x470d,0x471b,0x4726,
+0x4731,0x4745,0x475c,0x4774,0x4784,0x4794,0x47a4,0x47b6,0x47c1,0x47cc,0x47d6,0x47e2,0x47f0,0x4803,0x480f,0x481c,
+0x4827,0x4843,0x4850,0x485e,0x4877,0x2836,0x4886,0x2657,0x4893,0x48a1,0x48b3,0x48c1,0x48cd,0x48dd,0x2a71,0x48eb,
+0x48f7,0x4902,0x490d,0x4918,0x492c,0x493a,0x4951,0x495d,0x4971,0x497f,0x4991,0x49a7,0x49b5,0x49c7,0x49d5,0x49f2,
+0x4a04,0x4a11,0x4a22,0x4a34,0x4a4e,0x31cc,1,0,6,0x4a75,0x4a88,0x4a98,0x4aa6,0x4ab7,0x4ac7,0x3228,
+0x12,0,1,0x4af1,0x4af7,0x3235,0x12,0,1,0x4af1,0x4af7,0x3242,1,0,3,0x4af1,
+0x4af7,0x4b30,0x3258,1,0,3,0x4af1,0x4af7,0x4b30,0x326e,1,0,0x12,0x4bba,0x4bc4,0x4bd0,
+0x4bd7,0x4be2,0x4be7,0x4bee,0x4bf5,0x4bfe,0x4c03,0x4c08,0x4c18,0x870,0x3f07,0x4c24,0x3f12,0x4c34,0x3f21,0x3317,
+1,0,0xf,0x4bba,0x4c5b,0x4c65,0x4c6f,0x4c7a,0x3ddd,0x4c84,0x4c90,0x4c98,0x4c9f,0x4ca9,0x4bd0,0x4bd7,
+0x4be7,0x4cb3,0x339e,1,0,0x17,0x4bba,0x4cd0,0x4c6f,0x4cdc,0x4ce9,0x4cf7,0x3ddd,0x4d02,0x4bd0,0x4d13,
+0x4be7,0x4d22,0x4d30,0x870,0x3ef5,0x4d3c,0x4d4d,0x3f07,0x4c24,0x3f12,0x4c34,0x3f21,0x4d5e,0x34bb,1,0,
+3,0x4d91,0x4d99,0x4da1,0x34d4,1,0,0x10,0x4dca,0x4dd1,0x4de0,0x4e01,0x4e24,0x4e2f,0x4e4e,0x4e65,
+0x4e72,0x4e7b,0x4e9a,0x4ecd,0x4ee8,0x4f17,0x4f34,0x4f59,0x356d,1,0,0x24,0x4fa8,0x4fb5,0x4fc8,0x4fd5,
+0x5002,0x5027,0x503c,0x505b,0x507c,0x50a9,0x50e2,0x5105,0x5128,0x5155,0x518a,0x51b1,0x51da,0x5211,0x5240,0x5261,
+0x5286,0x5295,0x52b8,0x52cf,0x52dc,0x52eb,0x5308,0x5321,0x5344,0x5369,0x5382,0x5397,0x53a6,0x53b7,0x53c4,0x53e5,
+0x373d,1,0,4,0x5423,0x542e,0x5446,0x545e,0x3779,0x36,1,2,4,8,0xe,0x10,
+0x20,0x3e,0x40,0x80,0x100,0x1c0,0x200,0x400,0x800,0xe00,0x1000,0x2000,0x4000,0x7000,0x8000,0x10000,
+0x20000,0x40000,0x78001,0x80000,0x100000,0x200000,0x400000,0x800000,0x1000000,0x2000000,0x4000000,0x8000000,0xf000000,0x10000000,0x20000000,0x30f80000,
+0x30dd,0x30ec,0x3101,0x3116,0x5497,0x312b,0x313f,0x548d,0x3150,0x3164,0x3177,0x54a8,0x3188,0x31a1,0x31b3,0x54bf,
+0x31c4,0x31d8,0x31eb,0x54e8,0x3203,0x3215,0x3220,0x3230,0x5484,0x323e,0x3253,0x3268,0x327e,0x3298,0x32ae,0x32be,
+0x32d2,0x32e6,0x54de,0x32f7,0x330f,0x54c9
 };
 
-const uint8_t PropNameData::bytesTries[12703]={
-0,0x15,0x6d,0xc3,0x16,0x73,0xc1,0xea,0x76,0x5f,0x76,0x68,0x77,0x90,0x78,1,
-0x64,0x50,0x69,0x10,0x64,1,0x63,0x30,0x73,0x62,0x13,0x74,0x61,0x72,0x74,0x63,
-0x60,0x16,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x61,0x13,0x69,0x67,0x69,0x74,0x81,
-1,0x61,0x24,0x73,0x69,0x1e,0x72,0x69,0x61,0x74,0x69,0x6f,0x6e,0x73,0x65,0x6c,
-0x65,0x63,0x74,0x6f,0x72,0x69,3,0x62,0xc3,0x14,0x68,0x32,0x6f,0x42,0x73,0x13,
-0x70,0x61,0x63,0x65,0x5f,0x17,0x69,0x74,0x65,0x73,0x70,0x61,0x63,0x65,0x5f,0x16,
-0x72,0x64,0x62,0x72,0x65,0x61,0x6b,0xc3,0x14,0x73,0xa2,0x49,0x74,0xa4,0x2e,0x75,
-3,0x63,0xd9,0x40,0xc,0x69,0x52,0x6e,0x58,0x70,0x12,0x70,0x65,0x72,0x5c,0x13,
-0x63,0x61,0x73,0x65,0x5c,0x16,0x6d,0x61,0x70,0x70,0x69,0x6e,0x67,0xd9,0x40,0xc,
-0x12,0x64,0x65,0x6f,0x5b,0x10,0x69,1,0x63,0x3e,0x66,0x1b,0x69,0x65,0x64,0x69,
-0x64,0x65,0x6f,0x67,0x72,0x61,0x70,0x68,0x5b,0x17,0x6f,0x64,0x65,0x31,0x6e,0x61,
-0x6d,0x65,0xd9,0x40,0xb,0xa,0x69,0x84,0x70,0x19,0x70,0x30,0x74,0x36,0x75,0x10,
-0x63,0xd9,0x40,9,0x12,0x61,0x63,0x65,0x5f,1,0x63,0xd9,0x40,8,0x65,0x11,
-0x72,0x6d,0x67,0x69,0x3c,0x6c,0xa2,0x5f,0x6f,0x17,0x66,0x74,0x64,0x6f,0x74,0x74,
-0x65,0x64,0x57,0x13,0x6d,0x70,0x6c,0x65,3,0x63,0x50,0x6c,0x68,0x74,0x8a,0x75,
-0x1e,0x70,0x70,0x65,0x72,0x63,0x61,0x73,0x65,0x6d,0x61,0x70,0x70,0x69,0x6e,0x67,
-0xd9,0x40,9,0x19,0x61,0x73,0x65,0x66,0x6f,0x6c,0x64,0x69,0x6e,0x67,0xd9,0x40,
-6,0x1e,0x6f,0x77,0x65,0x72,0x63,0x61,0x73,0x65,0x6d,0x61,0x70,0x70,0x69,0x6e,
-0x67,0xd9,0x40,7,0x1e,0x69,0x74,0x6c,0x65,0x63,0x61,0x73,0x65,0x6d,0x61,0x70,
-0x70,0x69,0x6e,0x67,0xd9,0x40,8,0x10,0x63,0xd9,0x40,7,0x62,0xc3,0x13,0x63,
-0x34,0x64,0x57,0x65,0x6e,0x66,0x10,0x63,0xd9,0x40,6,0xc2,0xa,2,0x66,0xd9,
-0x40,6,0x72,0x28,0x78,0xd9,0x70,0,0x12,0x69,0x70,0x74,0xc2,0xa,0x19,0x65,
-0x78,0x74,0x65,0x6e,0x73,0x69,0x6f,0x6e,0x73,0xd9,0x70,0,1,0x67,0x50,0x6e,
-1,0x73,0x3a,0x74,0x18,0x65,0x6e,0x63,0x65,0x62,0x72,0x65,0x61,0x6b,0xc3,0x13,
-0x14,0x69,0x74,0x69,0x76,0x65,0x65,1,0x6d,0x2e,0x73,0x13,0x74,0x61,0x72,0x74,
-0x73,0x19,0x65,0x6e,0x74,0x73,0x74,0x61,0x72,0x74,0x65,0x72,0x73,3,0x63,0x66,
-0x65,0x72,0x69,0x98,0x72,0x19,0x61,0x69,0x6c,0x63,0x61,0x6e,0x6f,0x6e,0x69,0x63,
-0x1f,0x61,0x6c,0x63,0x6f,0x6d,0x62,0x69,0x6e,0x69,0x6e,0x67,0x63,0x6c,0x61,0x73,
-0x73,0xc3,0x11,0xd8,0x40,0xa,0x11,0x63,0x63,0xc3,0x11,0x11,0x72,0x6d,0x58,0x1e,
-0x69,0x6e,0x61,0x6c,0x70,0x75,0x6e,0x63,0x74,0x75,0x61,0x74,0x69,0x6f,0x6e,0x59,
-0x1d,0x74,0x6c,0x65,0x63,0x61,0x73,0x65,0x6d,0x61,0x70,0x70,0x69,0x6e,0x67,0xd9,
-0x40,0xa,0x6d,0x42,0x6e,0x48,0x70,0xa2,0xda,0x71,0xa4,9,0x72,0x15,0x61,0x64,
-0x69,0x63,0x61,0x6c,0x55,0x12,0x61,0x74,0x68,0x4f,6,0x6f,0x39,0x6f,0x32,0x74,
-0xc3,9,0x75,0x54,0x76,0xd9,0x30,0,0x12,0x6e,0x63,0x68,0x1f,0x61,0x72,0x61,
-0x63,0x74,0x65,0x72,0x63,0x6f,0x64,0x65,0x70,0x6f,0x69,0x6e,0x74,0x51,0x14,0x6d,
-0x65,0x72,0x69,0x63,1,0x74,0x32,0x76,0x13,0x61,0x6c,0x75,0x65,0xd9,0x30,0,
-0x12,0x79,0x70,0x65,0xc3,9,0x61,0xa2,0x77,0x63,0xa2,0x82,0x66,2,0x63,0x98,
-0x64,0xa2,0x53,0x6b,1,0x63,0x56,0x64,1,0x69,0x42,0x71,1,0x63,0xc3,0xd,
-0x75,0x17,0x69,0x63,0x6b,0x63,0x68,0x65,0x63,0x6b,0xc3,0xd,0x13,0x6e,0x65,0x72,
-0x74,0x6d,1,0x69,0x42,0x71,1,0x63,0xc3,0xf,0x75,0x17,0x69,0x63,0x6b,0x63,
-0x68,0x65,0x63,0x6b,0xc3,0xf,0x13,0x6e,0x65,0x72,0x74,0x71,1,0x69,0x42,0x71,
-1,0x63,0xc3,0xe,0x75,0x17,0x69,0x63,0x6b,0x63,0x68,0x65,0x63,0x6b,0xc3,0xe,
-0x13,0x6e,0x65,0x72,0x74,0x6f,1,0x69,0x42,0x71,1,0x63,0xc3,0xc,0x75,0x17,
-0x69,0x63,0x6b,0x63,0x68,0x65,0x63,0x6b,0xc3,0xc,0x13,0x6e,0x65,0x72,0x74,0x6b,
-0xd8,0x40,5,1,0x31,0xd9,0x40,0xb,0x6d,0x10,0x65,0xd9,0x40,5,0x12,0x68,
-0x61,0x72,0x51,1,0x61,0x2c,0x72,0x12,0x69,0x6e,0x74,0x7f,0x10,0x74,2,0x73,
-0x2c,0x74,0x30,0x77,0x10,0x73,0x77,0x11,0x79,0x6e,0x75,0x12,0x65,0x72,0x6e,1,
-0x73,0x38,0x77,0x18,0x68,0x69,0x74,0x65,0x73,0x70,0x61,0x63,0x65,0x77,0x14,0x79,
-0x6e,0x74,0x61,0x78,0x75,1,0x6d,0x3c,0x75,0x1a,0x6f,0x74,0x61,0x74,0x69,0x6f,
-0x6e,0x6d,0x61,0x72,0x6b,0x53,0x12,0x61,0x72,0x6b,0x53,0x66,0xc1,0xb9,0x69,0xc0,
-0xfd,0x69,0xa2,0x6f,0x6a,0xa2,0xca,0x6c,4,0x62,0xc3,8,0x63,0x8c,0x65,0x98,
-0x69,0xa2,0x56,0x6f,2,0x65,0x4b,0x67,0x4c,0x77,0x11,0x65,0x72,0x4c,0x13,0x63,
-0x61,0x73,0x65,0x4c,0x16,0x6d,0x61,0x70,0x70,0x69,0x6e,0x67,0xd9,0x40,4,0x11,
-0x69,0x63,0x1f,0x61,0x6c,0x6f,0x72,0x64,0x65,0x72,0x65,0x78,0x63,0x65,0x70,0x74,
-0x69,0x6f,0x6e,0x4b,0xd8,0x40,4,0x11,0x63,0x63,0xc3,0x10,0x18,0x61,0x64,0x63,
-0x61,0x6e,0x6f,0x6e,0x69,0x63,0x1f,0x61,0x6c,0x63,0x6f,0x6d,0x62,0x69,0x6e,0x69,
-0x6e,0x67,0x63,0x6c,0x61,0x73,0x73,0xc3,0x10,0x16,0x6e,0x65,0x62,0x72,0x65,0x61,
-0x6b,0xc3,8,1,0x64,0x44,0x73,1,0x63,0xd9,0x40,3,0x6f,0x16,0x63,0x6f,
-0x6d,0x6d,0x65,0x6e,0x74,0xd9,0x40,3,2,0x63,0x80,0x65,0x90,0x73,0x40,1,
-0x62,0x52,0x74,0x46,1,0x61,0x40,0x72,0x1c,0x69,0x6e,0x61,0x72,0x79,0x6f,0x70,
-0x65,0x72,0x61,0x74,0x6f,0x72,0x47,0x11,0x72,0x74,0x41,0x44,0x1c,0x69,0x6e,0x61,
-0x72,0x79,0x6f,0x70,0x65,0x72,0x61,0x74,0x6f,0x72,0x45,0x3e,0x16,0x6f,0x6e,0x74,
-0x69,0x6e,0x75,0x65,0x3f,0x10,0x6f,0x42,0x16,0x67,0x72,0x61,0x70,0x68,0x69,0x63,
-0x43,2,0x67,0xc3,6,0x6f,0x26,0x74,0xc3,7,0x11,0x69,0x6e,1,0x63,0x4a,
-0x69,0x11,0x6e,0x67,1,0x67,0x2e,0x74,0x12,0x79,0x70,0x65,0xc3,7,0x13,0x72,
-0x6f,0x75,0x70,0xc3,6,0x48,0x15,0x6f,0x6e,0x74,0x72,0x6f,0x6c,0x49,0x66,0x86,
-0x67,0xa2,0x4a,0x68,3,0x61,0x36,0x65,0x58,0x73,0x68,0x79,0x13,0x70,0x68,0x65,
-0x6e,0x3d,0x1f,0x6e,0x67,0x75,0x6c,0x73,0x79,0x6c,0x6c,0x61,0x62,0x6c,0x65,0x74,
-0x79,0x70,0x65,0xc3,0xb,0x10,0x78,0x3a,0x14,0x64,0x69,0x67,0x69,0x74,0x3b,0x10,
-0x74,0xc3,0xb,0x16,0x75,0x6c,0x6c,0x63,0x6f,0x6d,0x70,0x1f,0x6f,0x73,0x69,0x74,
-0x69,0x6f,0x6e,0x65,0x78,0x63,0x6c,0x75,0x73,0x69,0x6f,0x6e,0x33,2,0x63,0xa2,
-0x44,0x65,0xa2,0x4b,0x72,3,0x61,0x34,0x62,0x84,0x65,0x8a,0x6c,0x12,0x69,0x6e,
-0x6b,0x39,0x11,0x70,0x68,0x7c,0x12,0x65,0x6d,0x65,3,0x62,0x5e,0x63,0x30,0x65,
-0x48,0x6c,0x12,0x69,0x6e,0x6b,0x39,0x1a,0x6c,0x75,0x73,0x74,0x65,0x72,0x62,0x72,
-0x65,0x61,0x6b,0xc3,0x12,0x14,0x78,0x74,0x65,0x6e,0x64,0x37,0x12,0x61,0x73,0x65,
-0x35,0x11,0x78,0x74,0x37,0xc2,5,1,0x62,0xc3,0x12,0x6d,0xd9,0x20,0,0x1c,
-0x6e,0x65,0x72,0x61,0x6c,0x63,0x61,0x74,0x65,0x67,0x6f,0x72,0x79,0xc2,5,0x13,
-0x6d,0x61,0x73,0x6b,0xd9,0x20,0,0x61,0xa2,0x50,0x62,0xa2,0x7e,0x63,0xa2,0xf0,
-0x64,0xa4,0xbd,0x65,2,0x61,0x3a,0x6d,0x58,0x78,0x10,0x74,0x30,0x14,0x65,0x6e,
-0x64,0x65,0x72,0x31,0xc2,4,0x1b,0x73,0x74,0x61,0x73,0x69,0x61,0x6e,0x77,0x69,
-0x64,0x74,0x68,0xc3,4,0x12,0x6f,0x6a,0x69,0x92,1,0x6d,0x3c,0x70,0x1a,0x72,
-0x65,0x73,0x65,0x6e,0x74,0x61,0x74,0x69,0x6f,0x6e,0x95,0x16,0x6f,0x64,0x69,0x66,
-0x69,0x65,0x72,0x96,0x13,0x62,0x61,0x73,0x65,0x99,3,0x67,0x44,0x68,0x4a,0x6c,
-0x4e,0x73,0x1a,0x63,0x69,0x69,0x68,0x65,0x78,0x64,0x69,0x67,0x69,0x74,0x23,0x10,
-0x65,0xd9,0x40,0,0x11,0x65,0x78,0x23,1,0x6e,0x38,0x70,0x11,0x68,0x61,0x20,
-0x14,0x62,0x65,0x74,0x69,0x63,0x21,0x11,0x75,0x6d,0x79,4,0x63,0xc3,0,0x69,
-0x3e,0x6c,0xa2,0x57,0x6d,0xa2,0x64,0x70,1,0x62,0xd9,0x40,0xd,0x74,0xc3,0x15,
-0x11,0x64,0x69,2,0x63,0x54,0x6d,0x74,0x70,0x1b,0x61,0x69,0x72,0x65,0x64,0x62,
-0x72,0x61,0x63,0x6b,0x65,0x74,0xd8,0x40,0xd,0x13,0x74,0x79,0x70,0x65,0xc3,0x15,
-0x24,1,0x6c,0x30,0x6f,0x14,0x6e,0x74,0x72,0x6f,0x6c,0x25,0x12,0x61,0x73,0x73,
-0xc3,0,0x26,0x14,0x69,0x72,0x72,0x6f,0x72,1,0x65,0x38,0x69,0x16,0x6e,0x67,
-0x67,0x6c,0x79,0x70,0x68,0xd9,0x40,1,0x10,0x64,0x27,2,0x61,0x32,0x6b,0xc3,
-1,0x6f,0x11,0x63,0x6b,0xc3,1,0x11,0x6e,0x6b,0x7b,0x10,0x67,0xd9,0x40,1,
-6,0x68,0x7c,0x68,0x54,0x69,0x85,0x6f,0xa2,0x6f,0x77,4,0x63,0x30,0x6b,0x36,
-0x6c,0x87,0x74,0x8b,0x75,0x89,1,0x66,0x8d,0x6d,0x8f,0x11,0x63,0x66,0x91,0x18,
-0x61,0x6e,0x67,0x65,0x73,0x77,0x68,0x65,0x6e,4,0x63,0x44,0x6c,0x6c,0x6e,0x7e,
-0x74,0x98,0x75,0x18,0x70,0x70,0x65,0x72,0x63,0x61,0x73,0x65,0x64,0x89,0x12,0x61,
-0x73,0x65,1,0x66,0x30,0x6d,0x14,0x61,0x70,0x70,0x65,0x64,0x8f,0x14,0x6f,0x6c,
-0x64,0x65,0x64,0x8d,0x18,0x6f,0x77,0x65,0x72,0x63,0x61,0x73,0x65,0x64,0x87,0x1c,
-0x66,0x6b,0x63,0x63,0x61,0x73,0x65,0x66,0x6f,0x6c,0x64,0x65,0x64,0x91,0x18,0x69,
-0x74,0x6c,0x65,0x63,0x61,0x73,0x65,0x64,0x8b,0x13,0x6d,0x70,0x65,0x78,0x33,0x61,
-0x2e,0x63,0xa2,0x48,0x66,0xd9,0x40,2,1,0x6e,0x72,0x73,0x10,0x65,3,0x64,
-0x83,0x66,0x3a,0x69,0x4a,0x73,0x17,0x65,0x6e,0x73,0x69,0x74,0x69,0x76,0x65,0x65,
-0x15,0x6f,0x6c,0x64,0x69,0x6e,0x67,0xd9,0x40,2,0x17,0x67,0x6e,0x6f,0x72,0x61,
-0x62,0x6c,0x65,0x85,0x13,0x6f,0x6e,0x69,0x63,0x1f,0x61,0x6c,0x63,0x6f,0x6d,0x62,
-0x69,0x6e,0x69,0x6e,0x67,0x63,0x6c,0x61,0x73,0x73,0xc3,2,0x10,0x63,0xc3,2,
-3,0x61,0x30,0x65,0x34,0x69,0xa2,0x41,0x74,0xc3,3,0x11,0x73,0x68,0x29,2,
-0x63,0x3a,0x66,0x58,0x70,0x2c,0x16,0x72,0x65,0x63,0x61,0x74,0x65,0x64,0x2d,0x1d,
-0x6f,0x6d,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x74,0x79,0x70,0x65,0xc3,3,
-0x15,0x61,0x75,0x6c,0x74,0x69,0x67,0x1f,0x6e,0x6f,0x72,0x61,0x62,0x6c,0x65,0x63,
-0x6f,0x64,0x65,0x70,0x6f,0x69,0x6e,0x74,0x2b,0x2a,0x10,0x61,0x2e,0x15,0x63,0x72,
-0x69,0x74,0x69,0x63,0x2f,3,0x66,0x34,0x6e,0x3e,0x74,0x42,0x79,0x22,0x11,0x65,
-0x73,0x23,0x20,0x13,0x61,0x6c,0x73,0x65,0x21,0x20,0x10,0x6f,0x21,0x22,0x12,0x72,
-0x75,0x65,0x23,0xa,0x6b,0x5b,0x6f,0x23,0x6f,0x3c,0x72,0x4c,0x76,1,0x69,0x24,
-0x72,0x33,0x13,0x72,0x61,0x6d,0x61,0x33,0x10,0x76,0x22,0x14,0x65,0x72,0x6c,0x61,
-0x79,0x23,0xa2,0xe2,0x13,0x69,0x67,0x68,0x74,0xa3,0xe2,0x6b,0x58,0x6c,0x74,0x6e,
-3,0x6b,0x2f,0x6f,0x30,0x72,0x21,0x75,0x12,0x6b,0x74,0x61,0x2f,0x19,0x74,0x72,
-0x65,0x6f,0x72,0x64,0x65,0x72,0x65,0x64,0x21,1,0x61,0x24,0x76,0x31,0x18,0x6e,
-0x61,0x76,0x6f,0x69,0x63,0x69,0x6e,0x67,0x31,0xa2,0xe0,0x12,0x65,0x66,0x74,0xa3,
-0xe0,0x61,0x5c,0x62,0xa2,0x77,0x63,0xa2,0x96,0x64,0xa4,0xa,0x69,1,0x6f,0x26,
-0x73,0xa3,0xf0,0x1a,0x74,0x61,0x73,0x75,0x62,0x73,0x63,0x72,0x69,0x70,0x74,0xa3,
-0xf0,0xa2,0xe6,3,0x62,0xa0,0x6c,0xa3,0xe4,0x72,0xa3,0xe8,0x74,2,0x61,0x74,
-0x62,0x7c,0x74,0x14,0x61,0x63,0x68,0x65,0x64,1,0x61,0x3e,0x62,0x13,0x65,0x6c,
-0x6f,0x77,0xa2,0xca,0x13,0x6c,0x65,0x66,0x74,0xa3,0xc8,0x13,0x62,0x6f,0x76,0x65,
-0xa2,0xd6,0x14,0x72,0x69,0x67,0x68,0x74,0xa3,0xd8,0xa2,0xd6,0x10,0x72,0xa3,0xd8,
-0xa2,0xca,0x10,0x6c,0xa3,0xc8,0x12,0x6f,0x76,0x65,0xa2,0xe6,1,0x6c,0x30,0x72,
-0x13,0x69,0x67,0x68,0x74,0xa3,0xe8,0x12,0x65,0x66,0x74,0xa3,0xe4,0xa2,0xdc,2,
-0x65,0x2c,0x6c,0xa3,0xda,0x72,0xa3,0xde,0x12,0x6c,0x6f,0x77,0xa2,0xdc,1,0x6c,
-0x30,0x72,0x13,0x69,0x67,0x68,0x74,0xa3,0xde,0x12,0x65,0x66,0x74,0xa3,0xda,0x11,
-0x63,0x63,4,0x31,0x3c,0x32,0xa2,0x42,0x33,0xa2,0x56,0x38,0xa2,0x64,0x39,0x10,
-0x31,0xa3,0x5b,9,0x35,0xa,0x35,0x3f,0x36,0x41,0x37,0x43,0x38,0x45,0x39,0x47,
-0x30,0x30,0x31,0x3c,0x32,0x42,0x33,0x4e,0x34,0x3d,0x34,1,0x33,0xa3,0x67,0x37,
-0xa3,0x6b,0x36,0x10,0x38,0xa3,0x76,0x38,1,0x32,0xa3,0x7a,0x39,0xa3,0x81,0x3a,
-2,0x30,0xa3,0x82,0x32,0xa3,0x84,0x33,0xa3,0x85,9,0x35,0xa,0x35,0x53,0x36,
-0x55,0x37,0x57,0x38,0x59,0x39,0x5b,0x30,0x49,0x31,0x4b,0x32,0x4d,0x33,0x4f,0x34,
-0x51,6,0x33,8,0x33,0x63,0x34,0x65,0x35,0x67,0x36,0x69,0x30,0x5d,0x31,0x5f,
-0x32,0x61,0x10,0x34,0xa3,0x54,2,0x61,0xa3,0xea,0x62,0xa3,0xe9,0x6f,0x13,0x75,
-0x62,0x6c,0x65,1,0x61,0x30,0x62,0x13,0x65,0x6c,0x6f,0x77,0xa3,0xe9,0x13,0x62,
-0x6f,0x76,0x65,0xa3,0xea,0xb,0x6e,0xc0,0xca,0x72,0x5f,0x72,0x46,0x73,0xa2,0x48,
+const uint8_t PropNameData::bytesTries[14992]={
+0,0x15,0x6d,0xc3,0x78,0x73,0xc2,0x12,0x76,0x7a,0x76,0x6a,0x77,0xa2,0x52,0x78,
+1,0x64,0x50,0x69,0x10,0x64,1,0x63,0x30,0x73,0x62,0x13,0x74,0x61,0x72,0x74,
+0x63,0x60,0x16,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x61,0x13,0x69,0x67,0x69,0x74,
+0x81,3,0x61,0x2e,0x65,0x4c,0x6f,0xc3,0x18,0x73,0x69,0x1e,0x72,0x69,0x61,0x74,
+0x69,0x6f,0x6e,0x73,0x65,0x6c,0x65,0x63,0x74,0x6f,0x72,0x69,0x10,0x72,0x1f,0x74,
+0x69,0x63,0x61,0x6c,0x6f,0x72,0x69,0x65,0x6e,0x74,0x61,0x74,0x69,0x6f,0x6e,0xc3,
+0x18,3,0x62,0xc3,0x14,0x68,0x32,0x6f,0x42,0x73,0x13,0x70,0x61,0x63,0x65,0x5f,
+0x17,0x69,0x74,0x65,0x73,0x70,0x61,0x63,0x65,0x5f,0x16,0x72,0x64,0x62,0x72,0x65,
+0x61,0x6b,0xc3,0x14,0x73,0xa2,0x49,0x74,0xa4,0x3b,0x75,3,0x63,0xd9,0x40,0xc,
+0x69,0x52,0x6e,0x58,0x70,0x12,0x70,0x65,0x72,0x5c,0x13,0x63,0x61,0x73,0x65,0x5c,
+0x16,0x6d,0x61,0x70,0x70,0x69,0x6e,0x67,0xd9,0x40,0xc,0x12,0x64,0x65,0x6f,0x5b,
+0x10,0x69,1,0x63,0x3e,0x66,0x1b,0x69,0x65,0x64,0x69,0x64,0x65,0x6f,0x67,0x72,
+0x61,0x70,0x68,0x5b,0x17,0x6f,0x64,0x65,0x31,0x6e,0x61,0x6d,0x65,0xd9,0x40,0xb,
+0xa,0x69,0x84,0x70,0x19,0x70,0x30,0x74,0x36,0x75,0x10,0x63,0xd9,0x40,9,0x12,
+0x61,0x63,0x65,0x5f,1,0x63,0xd9,0x40,8,0x65,0x11,0x72,0x6d,0x67,0x69,0x3c,
+0x6c,0xa2,0x5f,0x6f,0x17,0x66,0x74,0x64,0x6f,0x74,0x74,0x65,0x64,0x57,0x13,0x6d,
+0x70,0x6c,0x65,3,0x63,0x50,0x6c,0x68,0x74,0x8a,0x75,0x1e,0x70,0x70,0x65,0x72,
+0x63,0x61,0x73,0x65,0x6d,0x61,0x70,0x70,0x69,0x6e,0x67,0xd9,0x40,9,0x19,0x61,
+0x73,0x65,0x66,0x6f,0x6c,0x64,0x69,0x6e,0x67,0xd9,0x40,6,0x1e,0x6f,0x77,0x65,
+0x72,0x63,0x61,0x73,0x65,0x6d,0x61,0x70,0x70,0x69,0x6e,0x67,0xd9,0x40,7,0x1e,
+0x69,0x74,0x6c,0x65,0x63,0x61,0x73,0x65,0x6d,0x61,0x70,0x70,0x69,0x6e,0x67,0xd9,
+0x40,8,0x10,0x63,0xd9,0x40,7,0x62,0xc3,0x13,0x63,0x34,0x64,0x57,0x65,0x6e,
+0x66,0x10,0x63,0xd9,0x40,6,0xc2,0xa,2,0x66,0xd9,0x40,6,0x72,0x28,0x78,
+0xd9,0x70,0,0x12,0x69,0x70,0x74,0xc2,0xa,0x19,0x65,0x78,0x74,0x65,0x6e,0x73,
+0x69,0x6f,0x6e,0x73,0xd9,0x70,0,1,0x67,0x6a,0x6e,1,0x73,0x54,0x74,0x13,
+0x65,0x6e,0x63,0x65,1,0x62,0x34,0x74,0x16,0x65,0x72,0x6d,0x69,0x6e,0x61,0x6c,
+0x67,0x13,0x72,0x65,0x61,0x6b,0xc3,0x13,0x14,0x69,0x74,0x69,0x76,0x65,0x65,1,
+0x6d,0x2e,0x73,0x13,0x74,0x61,0x72,0x74,0x73,0x19,0x65,0x6e,0x74,0x73,0x74,0x61,
+0x72,0x74,0x65,0x72,0x73,3,0x63,0x66,0x65,0x72,0x69,0x98,0x72,0x19,0x61,0x69,
+0x6c,0x63,0x61,0x6e,0x6f,0x6e,0x69,0x63,0x1f,0x61,0x6c,0x63,0x6f,0x6d,0x62,0x69,
+0x6e,0x69,0x6e,0x67,0x63,0x6c,0x61,0x73,0x73,0xc3,0x11,0xd8,0x40,0xa,0x11,0x63,
+0x63,0xc3,0x11,0x11,0x72,0x6d,0x58,0x1e,0x69,0x6e,0x61,0x6c,0x70,0x75,0x6e,0x63,
+0x74,0x75,0x61,0x74,0x69,0x6f,0x6e,0x59,0x1d,0x74,0x6c,0x65,0x63,0x61,0x73,0x65,
+0x6d,0x61,0x70,0x70,0x69,0x6e,0x67,0xd9,0x40,0xa,0x6d,0x70,0x6e,0x76,0x70,0xa2,
+0xf1,0x71,0xa4,0x43,0x72,2,0x61,0x28,0x65,0x32,0x69,0x9d,0x14,0x64,0x69,0x63,
+0x61,0x6c,0x55,0x1e,0x67,0x69,0x6f,0x6e,0x61,0x6c,0x69,0x6e,0x64,0x69,0x63,0x61,
+0x74,0x6f,0x72,0x9d,0x12,0x61,0x74,0x68,0x4f,6,0x6f,0x39,0x6f,0x32,0x74,0xc3,
+9,0x75,0x54,0x76,0xd9,0x30,0,0x12,0x6e,0x63,0x68,0x1f,0x61,0x72,0x61,0x63,
+0x74,0x65,0x72,0x63,0x6f,0x64,0x65,0x70,0x6f,0x69,0x6e,0x74,0x51,0x14,0x6d,0x65,
+0x72,0x69,0x63,1,0x74,0x32,0x76,0x13,0x61,0x6c,0x75,0x65,0xd9,0x30,0,0x12,
+0x79,0x70,0x65,0xc3,9,0x61,0xa2,0x77,0x63,0xa2,0x82,0x66,2,0x63,0x98,0x64,
+0xa2,0x53,0x6b,1,0x63,0x56,0x64,1,0x69,0x42,0x71,1,0x63,0xc3,0xd,0x75,
+0x17,0x69,0x63,0x6b,0x63,0x68,0x65,0x63,0x6b,0xc3,0xd,0x13,0x6e,0x65,0x72,0x74,
+0x6d,1,0x69,0x42,0x71,1,0x63,0xc3,0xf,0x75,0x17,0x69,0x63,0x6b,0x63,0x68,
+0x65,0x63,0x6b,0xc3,0xf,0x13,0x6e,0x65,0x72,0x74,0x71,1,0x69,0x42,0x71,1,
+0x63,0xc3,0xe,0x75,0x17,0x69,0x63,0x6b,0x63,0x68,0x65,0x63,0x6b,0xc3,0xe,0x13,
+0x6e,0x65,0x72,0x74,0x6f,1,0x69,0x42,0x71,1,0x63,0xc3,0xc,0x75,0x17,0x69,
+0x63,0x6b,0x63,0x68,0x65,0x63,0x6b,0xc3,0xc,0x13,0x6e,0x65,0x72,0x74,0x6b,0xd8,
+0x40,5,1,0x31,0xd9,0x40,0xb,0x6d,0x10,0x65,0xd9,0x40,5,0x12,0x68,0x61,
+0x72,0x51,2,0x61,0x6c,0x63,0xa2,0x4c,0x72,1,0x65,0x2a,0x69,0x11,0x6e,0x74,
+0x7f,0x16,0x70,0x65,0x6e,0x64,0x65,0x64,0x63,0x1f,0x6f,0x6e,0x63,0x61,0x74,0x65,
+0x6e,0x61,0x74,0x69,0x6f,0x6e,0x6d,0x61,0x72,0x6b,0x9f,0x10,0x74,2,0x73,0x2c,
+0x74,0x30,0x77,0x10,0x73,0x77,0x11,0x79,0x6e,0x75,0x12,0x65,0x72,0x6e,1,0x73,
+0x38,0x77,0x18,0x68,0x69,0x74,0x65,0x73,0x70,0x61,0x63,0x65,0x77,0x14,0x79,0x6e,
+0x74,0x61,0x78,0x75,0x10,0x6d,0x9f,1,0x6d,0x3c,0x75,0x1a,0x6f,0x74,0x61,0x74,
+0x69,0x6f,0x6e,0x6d,0x61,0x72,0x6b,0x53,0x12,0x61,0x72,0x6b,0x53,0x66,0xc1,0xf8,
+0x69,0xc1,0x3c,0x69,0xa2,0x6f,0x6a,0xa4,9,0x6c,4,0x62,0xc3,8,0x63,0x8c,
+0x65,0x98,0x69,0xa2,0x56,0x6f,2,0x65,0x4b,0x67,0x4c,0x77,0x11,0x65,0x72,0x4c,
+0x13,0x63,0x61,0x73,0x65,0x4c,0x16,0x6d,0x61,0x70,0x70,0x69,0x6e,0x67,0xd9,0x40,
+4,0x11,0x69,0x63,0x1f,0x61,0x6c,0x6f,0x72,0x64,0x65,0x72,0x65,0x78,0x63,0x65,
+0x70,0x74,0x69,0x6f,0x6e,0x4b,0xd8,0x40,4,0x11,0x63,0x63,0xc3,0x10,0x18,0x61,
+0x64,0x63,0x61,0x6e,0x6f,0x6e,0x69,0x63,0x1f,0x61,0x6c,0x63,0x6f,0x6d,0x62,0x69,
+0x6e,0x69,0x6e,0x67,0x63,0x6c,0x61,0x73,0x73,0xc3,0x10,0x16,0x6e,0x65,0x62,0x72,
+0x65,0x61,0x6b,0xc3,8,2,0x64,0x4a,0x6e,0xa2,0x5b,0x73,1,0x63,0xd9,0x40,
+3,0x6f,0x16,0x63,0x6f,0x6d,0x6d,0x65,0x6e,0x74,0xd9,0x40,3,2,0x63,0x80,
+0x65,0x90,0x73,0x40,1,0x62,0x52,0x74,0x46,1,0x61,0x40,0x72,0x1c,0x69,0x6e,
+0x61,0x72,0x79,0x6f,0x70,0x65,0x72,0x61,0x74,0x6f,0x72,0x47,0x11,0x72,0x74,0x41,
+0x44,0x1c,0x69,0x6e,0x61,0x72,0x79,0x6f,0x70,0x65,0x72,0x61,0x74,0x6f,0x72,0x45,
+0x3e,0x16,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3f,0x10,0x6f,0x42,0x16,0x67,0x72,
+0x61,0x70,0x68,0x69,0x63,0x43,2,0x64,0x2e,0x70,0x86,0x73,0x10,0x63,0xc3,0x17,
+0x11,0x69,0x63,1,0x70,0x46,0x73,0x1e,0x79,0x6c,0x6c,0x61,0x62,0x69,0x63,0x63,
+0x61,0x74,0x65,0x67,0x6f,0x72,0x79,0xc3,0x17,0x10,0x6f,0x1f,0x73,0x69,0x74,0x69,
+0x6f,0x6e,0x61,0x6c,0x63,0x61,0x74,0x65,0x67,0x6f,0x72,0x79,0xc3,0x16,0x10,0x63,
+0xc3,0x16,2,0x67,0xc3,6,0x6f,0x26,0x74,0xc3,7,0x11,0x69,0x6e,1,0x63,
+0x4a,0x69,0x11,0x6e,0x67,1,0x67,0x2e,0x74,0x12,0x79,0x70,0x65,0xc3,7,0x13,
+0x72,0x6f,0x75,0x70,0xc3,6,0x48,0x15,0x6f,0x6e,0x74,0x72,0x6f,0x6c,0x49,0x66,
+0x86,0x67,0xa2,0x4a,0x68,3,0x61,0x36,0x65,0x58,0x73,0x68,0x79,0x13,0x70,0x68,
+0x65,0x6e,0x3d,0x1f,0x6e,0x67,0x75,0x6c,0x73,0x79,0x6c,0x6c,0x61,0x62,0x6c,0x65,
+0x74,0x79,0x70,0x65,0xc3,0xb,0x10,0x78,0x3a,0x14,0x64,0x69,0x67,0x69,0x74,0x3b,
+0x10,0x74,0xc3,0xb,0x16,0x75,0x6c,0x6c,0x63,0x6f,0x6d,0x70,0x1f,0x6f,0x73,0x69,
+0x74,0x69,0x6f,0x6e,0x65,0x78,0x63,0x6c,0x75,0x73,0x69,0x6f,0x6e,0x33,2,0x63,
+0xa2,0x44,0x65,0xa2,0x4b,0x72,3,0x61,0x34,0x62,0x84,0x65,0x8a,0x6c,0x12,0x69,
+0x6e,0x6b,0x39,0x11,0x70,0x68,0x7c,0x12,0x65,0x6d,0x65,3,0x62,0x5e,0x63,0x30,
+0x65,0x48,0x6c,0x12,0x69,0x6e,0x6b,0x39,0x1a,0x6c,0x75,0x73,0x74,0x65,0x72,0x62,
+0x72,0x65,0x61,0x6b,0xc3,0x12,0x14,0x78,0x74,0x65,0x6e,0x64,0x37,0x12,0x61,0x73,
+0x65,0x35,0x11,0x78,0x74,0x37,0xc2,5,1,0x62,0xc3,0x12,0x6d,0xd9,0x20,0,
+0x1c,0x6e,0x65,0x72,0x61,0x6c,0x63,0x61,0x74,0x65,0x67,0x6f,0x72,0x79,0xc2,5,
+0x13,0x6d,0x61,0x73,0x6b,0xd9,0x20,0,0x61,0xa2,0x90,0x62,0xa2,0xbe,0x63,0xa4,
+0x30,0x64,0xa4,0xfd,0x65,5,0x6d,0x63,0x6d,0x6e,0x70,0xa2,0x59,0x78,0x10,0x74,
+0x30,1,0x65,0x2c,0x70,0x12,0x69,0x63,0x74,0xa1,0x12,0x6e,0x64,0x65,1,0x64,
+0x24,0x72,0x31,0x1b,0x70,0x69,0x63,0x74,0x6f,0x67,0x72,0x61,0x70,0x68,0x69,0x63,
+0xa1,0x10,0x6f,1,0x64,0x97,0x6a,0x10,0x69,0x92,2,0x63,0x40,0x6d,0x50,0x70,
+0x1a,0x72,0x65,0x73,0x65,0x6e,0x74,0x61,0x74,0x69,0x6f,0x6e,0x95,0x17,0x6f,0x6d,
+0x70,0x6f,0x6e,0x65,0x6e,0x74,0x9b,0x16,0x6f,0x64,0x69,0x66,0x69,0x65,0x72,0x96,
+0x13,0x62,0x61,0x73,0x65,0x99,0x12,0x72,0x65,0x73,0x95,0x61,0x30,0x62,0x4e,0x63,
+0x12,0x6f,0x6d,0x70,0x9b,0xc2,4,0x1b,0x73,0x74,0x61,0x73,0x69,0x61,0x6e,0x77,
+0x69,0x64,0x74,0x68,0xc3,4,0x12,0x61,0x73,0x65,0x99,3,0x67,0x44,0x68,0x4a,
+0x6c,0x4e,0x73,0x1a,0x63,0x69,0x69,0x68,0x65,0x78,0x64,0x69,0x67,0x69,0x74,0x23,
+0x10,0x65,0xd9,0x40,0,0x11,0x65,0x78,0x23,1,0x6e,0x38,0x70,0x11,0x68,0x61,
+0x20,0x14,0x62,0x65,0x74,0x69,0x63,0x21,0x11,0x75,0x6d,0x79,4,0x63,0xc3,0,
+0x69,0x3e,0x6c,0xa2,0x57,0x6d,0xa2,0x64,0x70,1,0x62,0xd9,0x40,0xd,0x74,0xc3,
+0x15,0x11,0x64,0x69,2,0x63,0x54,0x6d,0x74,0x70,0x1b,0x61,0x69,0x72,0x65,0x64,
+0x62,0x72,0x61,0x63,0x6b,0x65,0x74,0xd8,0x40,0xd,0x13,0x74,0x79,0x70,0x65,0xc3,
+0x15,0x24,1,0x6c,0x30,0x6f,0x14,0x6e,0x74,0x72,0x6f,0x6c,0x25,0x12,0x61,0x73,
+0x73,0xc3,0,0x26,0x14,0x69,0x72,0x72,0x6f,0x72,1,0x65,0x38,0x69,0x16,0x6e,
+0x67,0x67,0x6c,0x79,0x70,0x68,0xd9,0x40,1,0x10,0x64,0x27,2,0x61,0x32,0x6b,
+0xc3,1,0x6f,0x11,0x63,0x6b,0xc3,1,0x11,0x6e,0x6b,0x7b,0x10,0x67,0xd9,0x40,
+1,6,0x68,0x7c,0x68,0x54,0x69,0x85,0x6f,0xa2,0x6f,0x77,4,0x63,0x30,0x6b,
+0x36,0x6c,0x87,0x74,0x8b,0x75,0x89,1,0x66,0x8d,0x6d,0x8f,0x11,0x63,0x66,0x91,
+0x18,0x61,0x6e,0x67,0x65,0x73,0x77,0x68,0x65,0x6e,4,0x63,0x44,0x6c,0x6c,0x6e,
+0x7e,0x74,0x98,0x75,0x18,0x70,0x70,0x65,0x72,0x63,0x61,0x73,0x65,0x64,0x89,0x12,
+0x61,0x73,0x65,1,0x66,0x30,0x6d,0x14,0x61,0x70,0x70,0x65,0x64,0x8f,0x14,0x6f,
+0x6c,0x64,0x65,0x64,0x8d,0x18,0x6f,0x77,0x65,0x72,0x63,0x61,0x73,0x65,0x64,0x87,
+0x1c,0x66,0x6b,0x63,0x63,0x61,0x73,0x65,0x66,0x6f,0x6c,0x64,0x65,0x64,0x91,0x18,
+0x69,0x74,0x6c,0x65,0x63,0x61,0x73,0x65,0x64,0x8b,0x13,0x6d,0x70,0x65,0x78,0x33,
+0x61,0x2e,0x63,0xa2,0x48,0x66,0xd9,0x40,2,1,0x6e,0x72,0x73,0x10,0x65,3,
+0x64,0x83,0x66,0x3a,0x69,0x4a,0x73,0x17,0x65,0x6e,0x73,0x69,0x74,0x69,0x76,0x65,
+0x65,0x15,0x6f,0x6c,0x64,0x69,0x6e,0x67,0xd9,0x40,2,0x17,0x67,0x6e,0x6f,0x72,
+0x61,0x62,0x6c,0x65,0x85,0x13,0x6f,0x6e,0x69,0x63,0x1f,0x61,0x6c,0x63,0x6f,0x6d,
+0x62,0x69,0x6e,0x69,0x6e,0x67,0x63,0x6c,0x61,0x73,0x73,0xc3,2,0x10,0x63,0xc3,
+2,3,0x61,0x30,0x65,0x34,0x69,0xa2,0x41,0x74,0xc3,3,0x11,0x73,0x68,0x29,
+2,0x63,0x3a,0x66,0x58,0x70,0x2c,0x16,0x72,0x65,0x63,0x61,0x74,0x65,0x64,0x2d,
+0x1d,0x6f,0x6d,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x74,0x79,0x70,0x65,0xc3,
+3,0x15,0x61,0x75,0x6c,0x74,0x69,0x67,0x1f,0x6e,0x6f,0x72,0x61,0x62,0x6c,0x65,
+0x63,0x6f,0x64,0x65,0x70,0x6f,0x69,0x6e,0x74,0x2b,0x2a,0x10,0x61,0x2e,0x15,0x63,
+0x72,0x69,0x74,0x69,0x63,0x2f,3,0x66,0x34,0x6e,0x3e,0x74,0x42,0x79,0x22,0x11,
+0x65,0x73,0x23,0x20,0x13,0x61,0x6c,0x73,0x65,0x21,0x20,0x10,0x6f,0x21,0x22,0x12,
+0x72,0x75,0x65,0x23,0xb,0x6b,0x5b,0x6f,0x23,0x6f,0x3c,0x72,0x4c,0x76,1,0x69,
+0x24,0x72,0x33,0x13,0x72,0x61,0x6d,0x61,0x33,0x10,0x76,0x22,0x14,0x65,0x72,0x6c,
+0x61,0x79,0x23,0xa2,0xe2,0x13,0x69,0x67,0x68,0x74,0xa3,0xe2,0x6b,0x58,0x6c,0x74,
+0x6e,3,0x6b,0x2f,0x6f,0x30,0x72,0x21,0x75,0x12,0x6b,0x74,0x61,0x2f,0x19,0x74,
+0x72,0x65,0x6f,0x72,0x64,0x65,0x72,0x65,0x64,0x21,1,0x61,0x24,0x76,0x31,0x18,
+0x6e,0x61,0x76,0x6f,0x69,0x63,0x69,0x6e,0x67,0x31,0xa2,0xe0,0x12,0x65,0x66,0x74,
+0xa3,0xe0,0x64,0x45,0x64,0x4e,0x68,0x88,0x69,1,0x6f,0x26,0x73,0xa3,0xf0,0x1a,
+0x74,0x61,0x73,0x75,0x62,0x73,0x63,0x72,0x69,0x70,0x74,0xa3,0xf0,2,0x61,0xa3,
+0xea,0x62,0xa3,0xe9,0x6f,0x13,0x75,0x62,0x6c,0x65,1,0x61,0x30,0x62,0x13,0x65,
+0x6c,0x6f,0x77,0xa3,0xe9,0x13,0x62,0x6f,0x76,0x65,0xa3,0xea,0x12,0x61,0x6e,0x72,
+0x2c,0x15,0x65,0x61,0x64,0x69,0x6e,0x67,0x2d,0x61,0xa2,0x7b,0x62,0xa2,0xd4,0x63,
+0x11,0x63,0x63,4,0x31,0x3c,0x32,0xa2,0x42,0x33,0xa2,0x56,0x38,0xa2,0x64,0x39,
+0x10,0x31,0xa3,0x5b,9,0x35,0xa,0x35,0x3f,0x36,0x41,0x37,0x43,0x38,0x45,0x39,
+0x47,0x30,0x30,0x31,0x3c,0x32,0x42,0x33,0x4e,0x34,0x3d,0x34,1,0x33,0xa3,0x67,
+0x37,0xa3,0x6b,0x36,0x10,0x38,0xa3,0x76,0x38,1,0x32,0xa3,0x7a,0x39,0xa3,0x81,
+0x3a,2,0x30,0xa3,0x82,0x32,0xa3,0x84,0x33,0xa3,0x85,9,0x35,0xa,0x35,0x53,
+0x36,0x55,0x37,0x57,0x38,0x59,0x39,0x5b,0x30,0x49,0x31,0x4b,0x32,0x4d,0x33,0x4f,
+0x34,0x51,6,0x33,8,0x33,0x63,0x34,0x65,0x35,0x67,0x36,0x69,0x30,0x5d,0x31,
+0x5f,0x32,0x61,0x10,0x34,0xa3,0x54,0xa2,0xe6,3,0x62,0xa0,0x6c,0xa3,0xe4,0x72,
+0xa3,0xe8,0x74,2,0x61,0x74,0x62,0x7c,0x74,0x14,0x61,0x63,0x68,0x65,0x64,1,
+0x61,0x3e,0x62,0x13,0x65,0x6c,0x6f,0x77,0xa2,0xca,0x13,0x6c,0x65,0x66,0x74,0xa3,
+0xc8,0x13,0x62,0x6f,0x76,0x65,0xa2,0xd6,0x14,0x72,0x69,0x67,0x68,0x74,0xa3,0xd8,
+0xa2,0xd6,0x10,0x72,0xa3,0xd8,0xa2,0xca,0x10,0x6c,0xa3,0xc8,0x12,0x6f,0x76,0x65,
+0xa2,0xe6,1,0x6c,0x30,0x72,0x13,0x69,0x67,0x68,0x74,0xa3,0xe8,0x12,0x65,0x66,
+0x74,0xa3,0xe4,0xa2,0xdc,2,0x65,0x2c,0x6c,0xa3,0xda,0x72,0xa3,0xde,0x12,0x6c,
+0x6f,0x77,0xa2,0xdc,1,0x6c,0x30,0x72,0x13,0x69,0x67,0x68,0x74,0xa3,0xde,0x12,
+0x65,0x66,0x74,0xa3,0xda,0xb,0x6e,0xc0,0xca,0x72,0x5f,0x72,0x46,0x73,0xa2,0x48,
 0x77,1,0x68,0x24,0x73,0x33,0x17,0x69,0x74,0x65,0x73,0x70,0x61,0x63,0x65,0x33,
 0x22,1,0x69,0x30,0x6c,2,0x65,0x3d,0x69,0x4b,0x6f,0x3f,0x18,0x67,0x68,0x74,
 0x74,0x6f,0x6c,0x65,0x66,0x74,0x22,2,0x65,0x38,0x69,0x48,0x6f,0x16,0x76,0x65,
@@ -258,644 +285,772 @@
 0x72,0x61,0x74,0x6f,0x72,0x2d,2,0x6c,0x3b,0x6e,0x2b,0x72,0x13,0x61,0x62,0x69,
 0x63,1,0x6c,0x30,0x6e,0x14,0x75,0x6d,0x62,0x65,0x72,0x2b,0x14,0x65,0x74,0x74,
 0x65,0x72,0x3b,0x2e,1,0x6e,0x45,0x6f,0x1c,0x75,0x6e,0x64,0x61,0x72,0x79,0x6e,
-0x65,0x75,0x74,0x72,0x61,0x6c,0x45,0,0x15,0x6d,0xc7,0x44,0x73,0xc3,0x75,0x76,
-0x9c,0x76,0x92,0x77,0xa2,0x8b,0x79,0x10,0x69,2,0x6a,0x3c,0x72,0x68,0x73,0x17,
-0x79,0x6c,0x6c,0x61,0x62,0x6c,0x65,0x73,0xa3,0x48,0x12,0x69,0x6e,0x67,0xa2,0x74,
-0x1e,0x68,0x65,0x78,0x61,0x67,0x72,0x61,0x6d,0x73,0x79,0x6d,0x62,0x6f,0x6c,0x73,
-0xa3,0x74,0x16,0x61,0x64,0x69,0x63,0x61,0x6c,0x73,0xa3,0x49,2,0x61,0x36,0x65,
-0x7a,0x73,0xa2,0x6c,0x12,0x73,0x75,0x70,0xa3,0x7d,1,0x69,0xa3,0x9f,0x72,0x1e,
-0x69,0x61,0x74,0x69,0x6f,0x6e,0x73,0x65,0x6c,0x65,0x63,0x74,0x6f,0x72,0x73,0xa2,
-0x6c,0x19,0x73,0x75,0x70,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0xa3,0x7d,1,0x64,
-0x3c,0x72,0x19,0x74,0x69,0x63,0x61,0x6c,0x66,0x6f,0x72,0x6d,0x73,0xa3,0x91,0x14,
-0x69,0x63,0x65,0x78,0x74,0xa2,0xaf,0x16,0x65,0x6e,0x73,0x69,0x6f,0x6e,0x73,0xa3,
-0xaf,0x18,0x61,0x72,0x61,0x6e,0x67,0x63,0x69,0x74,0x69,0xa3,0xfc,0x73,0xa2,0x4b,
-0x74,0xa6,0x2b,0x75,2,0x63,0x82,0x67,0x92,0x6e,0x1f,0x69,0x66,0x69,0x65,0x64,
-0x63,0x61,0x6e,0x61,0x64,0x69,0x61,0x6e,0x61,0x62,0x6f,0x1f,0x72,0x69,0x67,0x69,
-0x6e,0x61,0x6c,0x73,0x79,0x6c,0x6c,0x61,0x62,0x69,0x63,0x73,0x62,0x17,0x65,0x78,
-0x74,0x65,0x6e,0x64,0x65,0x64,0xa3,0xad,0x11,0x61,0x73,0x62,0x12,0x65,0x78,0x74,
-0xa3,0xad,0x15,0x61,0x72,0x69,0x74,0x69,0x63,0xa3,0x78,7,0x6f,0xc1,0x5b,0x6f,
-0x54,0x70,0x68,0x75,0xa2,0x43,0x79,1,0x6c,0x2c,0x72,0x12,0x69,0x61,0x63,0x3b,
-0x17,0x6f,0x74,0x69,0x6e,0x61,0x67,0x72,0x69,0xa3,0x8f,0x18,0x72,0x61,0x73,0x6f,
-0x6d,0x70,0x65,0x6e,0x67,0xa3,0xda,1,0x61,0x32,0x65,0x14,0x63,0x69,0x61,0x6c,
-0x73,0xa3,0x56,0x12,0x63,0x69,0x6e,0x1f,0x67,0x6d,0x6f,0x64,0x69,0x66,0x69,0x65,
-0x72,0x6c,0x65,0x74,0x74,0x65,0x72,0x73,0x2d,2,0x6e,0x48,0x70,0x76,0x74,0x1d,
-0x74,0x6f,0x6e,0x73,0x69,0x67,0x6e,0x77,0x72,0x69,0x74,0x69,0x6e,0x67,0xa5,6,
-0x15,0x64,0x61,0x6e,0x65,0x73,0x65,0xa2,0x9b,0x12,0x73,0x75,0x70,0xa2,0xdb,0x16,
-0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0xa3,0xdb,4,0x61,0xa2,0xa8,0x65,0x5c,0x6d,
-0x9e,0x70,0xa2,0x4b,0x73,0x13,0x79,0x6d,0x62,0x6f,0x1f,0x6c,0x73,0x61,0x6e,0x64,
-0x70,0x69,0x63,0x74,0x6f,0x67,0x72,0x61,0x70,0x68,0x73,0xa5,5,0x10,0x72,1,
-0x61,0x4e,0x73,0x12,0x63,0x72,0x69,0x1f,0x70,0x74,0x73,0x61,0x6e,0x64,0x73,0x75,
-0x62,0x73,0x63,0x72,0x69,0x70,0x74,0x73,0x73,0x14,0x6e,0x64,0x73,0x75,0x62,0x73,
-0x1b,0x61,0x74,0x68,0x6f,0x70,0x65,0x72,0x61,0x74,0x6f,0x72,0x73,0xa3,0x6a,1,
-0x6c,0x40,0x75,1,0x61,0x6e,0x6e,0x17,0x63,0x74,0x75,0x61,0x74,0x69,0x6f,0x6e,
-0xa3,0x8e,0x15,0x65,0x6d,0x65,0x6e,0x74,0x61,1,0x6c,0x50,0x72,0x1e,0x79,0x70,
-0x72,0x69,0x76,0x61,0x74,0x65,0x75,0x73,0x65,0x61,0x72,0x65,0x61,1,0x61,0xa3,
-0x6d,0x62,0xa3,0x6e,3,0x61,0x5c,0x6d,0x78,0x70,0xa2,0x41,0x73,0x13,0x79,0x6d,
-0x62,0x6f,0x1f,0x6c,0x73,0x61,0x6e,0x64,0x70,0x69,0x63,0x74,0x6f,0x67,0x72,0x61,
-0x70,0x68,0x73,0xa5,5,0x14,0x72,0x72,0x6f,0x77,0x73,2,0x61,0xa3,0x67,0x62,
-0xa3,0x68,0x63,0xa3,0xfa,0x13,0x61,0x74,0x68,0x65,0x1f,0x6d,0x61,0x74,0x69,0x63,
-0x61,0x6c,0x6f,0x70,0x65,0x72,0x61,0x74,0x6f,0x72,0x73,0xa3,0x6a,0x19,0x75,0x6e,
-0x63,0x74,0x75,0x61,0x74,0x69,0x6f,0x6e,0xa3,0x8e,0x61,0x5a,0x68,0x84,0x69,0xa2,
-0x5b,0x6d,0x16,0x61,0x6c,0x6c,0x66,0x6f,0x72,0x6d,1,0x73,0xa3,0x54,0x76,0x16,
-0x61,0x72,0x69,0x61,0x6e,0x74,0x73,0xa3,0x54,1,0x6d,0x36,0x75,0x16,0x72,0x61,
-0x73,0x68,0x74,0x72,0x61,0xa3,0xa1,0x15,0x61,0x72,0x69,0x74,0x61,0x6e,0xa3,0xac,
-1,0x61,0x52,0x6f,0x13,0x72,0x74,0x68,0x61,0x1f,0x6e,0x64,0x66,0x6f,0x72,0x6d,
-0x61,0x74,0x63,0x6f,0x6e,0x74,0x72,0x6f,0x6c,0x73,0xa3,0xf7,1,0x72,0x2e,0x76,
-0x12,0x69,0x61,0x6e,0xa3,0x79,0x12,0x61,0x64,0x61,0xa3,0xd9,1,0x64,0x50,0x6e,
-0x13,0x68,0x61,0x6c,0x61,0x50,0x1d,0x61,0x72,0x63,0x68,0x61,0x69,0x63,0x6e,0x75,
-0x6d,0x62,0x65,0x72,0x73,0xa3,0xf9,0x13,0x64,0x68,0x61,0x6d,0xa3,0xf8,4,0x61,
-0x68,0x65,0xa2,0x74,0x68,0xa2,0x77,0x69,0xa2,0x7f,0x72,0x1c,0x61,0x6e,0x73,0x70,
-0x6f,0x72,0x74,0x61,0x6e,0x64,0x6d,0x61,0x70,0xa2,0xcf,0x16,0x73,0x79,0x6d,0x62,
-0x6f,0x6c,0x73,0xa3,0xcf,3,0x67,0x34,0x69,0x5a,0x6b,0xa2,0x46,0x6d,0x11,0x69,
-0x6c,0x49,2,0x61,0x2a,0x62,0x32,0x73,0xa3,0x60,0x12,0x6c,0x6f,0x67,0xa3,0x62,
-0x13,0x61,0x6e,0x77,0x61,0xa3,0x65,3,0x6c,0x52,0x74,0x56,0x76,0x5e,0x78,0x16,
-0x75,0x61,0x6e,0x6a,0x69,0x6e,0x67,0xa2,0x7c,0x16,0x73,0x79,0x6d,0x62,0x6f,0x6c,
-0x73,0xa3,0x7c,0x10,0x65,0xa3,0x70,0x12,0x68,0x61,0x6d,0xa3,0xae,0x12,0x69,0x65,
-0x74,0xa3,0xb7,0x11,0x72,0x69,0xa3,0xdc,0x13,0x6c,0x75,0x67,0x75,0x4b,0x10,0x61,
-1,0x61,0x24,0x69,0x53,0x11,0x6e,0x61,0x3d,2,0x62,0x34,0x66,0x3c,0x72,0x13,
-0x68,0x75,0x74,0x61,0xa3,0xfb,0x13,0x65,0x74,0x61,0x6e,0x57,0x14,0x69,0x6e,0x61,
-0x67,0x68,0xa3,0x90,0x6d,0x84,0x6e,0xa6,0x1a,0x6f,0xa6,0x4e,0x70,0xa8,2,0x72,
-1,0x65,0x5c,0x75,1,0x6d,0x2a,0x6e,0x11,0x69,0x63,0x67,0x10,0x69,0xa2,0xc0,
-0x1d,0x6e,0x75,0x6d,0x65,0x72,0x61,0x6c,0x73,0x79,0x6d,0x62,0x6f,0x6c,0x73,0xa3,
-0xc0,0x13,0x6a,0x61,0x6e,0x67,0xa3,0xa3,6,0x6f,0x76,0x6f,0x6c,0x72,0xa2,0x51,
-0x75,0xa2,0x52,0x79,0x14,0x61,0x6e,0x6d,0x61,0x72,0x58,0x12,0x65,0x78,0x74,2,
-0x61,0xa3,0xb6,0x62,0xa3,0xee,0x65,0x13,0x6e,0x64,0x65,0x64,1,0x61,0xa3,0xb6,
-0x62,0xa3,0xee,1,0x64,0x32,0x6e,0x15,0x67,0x6f,0x6c,0x69,0x61,0x6e,0x6b,0x10,
-0x69,0xa2,0xec,0x13,0x66,0x69,0x65,0x72,1,0x6c,0x3c,0x74,0x19,0x6f,0x6e,0x65,
-0x6c,0x65,0x74,0x74,0x65,0x72,0x73,0xa3,0x8a,0x15,0x65,0x74,0x74,0x65,0x72,0x73,
-0x2d,0x10,0x6f,0xa3,0xed,1,0x6c,0x44,0x73,0x11,0x69,0x63,0xa2,0x5c,0x18,0x61,
-0x6c,0x73,0x79,0x6d,0x62,0x6f,0x6c,0x73,0xa3,0x5c,0x13,0x74,0x61,0x6e,0x69,0xa5,
-3,0x61,0xa2,0x9b,0x65,0xa4,0x1f,0x69,1,0x61,0xa2,0x8f,0x73,0x10,0x63,5,
-0x70,0x18,0x70,0xa2,0x71,0x73,0x36,0x74,0x17,0x65,0x63,0x68,0x6e,0x69,0x63,0x61,
-0x6c,0x81,0x15,0x79,0x6d,0x62,0x6f,0x6c,0x73,0x8f,0x61,0xa2,0x66,0x65,0x46,0x6d,
-0x19,0x61,0x74,0x68,0x73,0x79,0x6d,0x62,0x6f,0x6c,0x73,1,0x61,0xa3,0x66,0x62,
-0xa3,0x69,0x17,0x6c,0x6c,0x61,0x6e,0x65,0x6f,0x75,0x73,2,0x6d,0x3a,0x73,0x6c,
-0x74,0x17,0x65,0x63,0x68,0x6e,0x69,0x63,0x61,0x6c,0x81,0x11,0x61,0x74,0x1f,0x68,
-0x65,0x6d,0x61,0x74,0x69,0x63,0x61,0x6c,0x73,0x79,0x6d,0x62,0x6f,0x6c,0x73,1,
-0x61,0xa3,0x66,0x62,0xa3,0x69,0x15,0x79,0x6d,0x62,0x6f,0x6c,0x73,0x8e,0x12,0x61,
-0x6e,0x64,1,0x61,0x3c,0x70,0x19,0x69,0x63,0x74,0x6f,0x67,0x72,0x61,0x70,0x68,
-0x73,0xa3,0xcd,0x14,0x72,0x72,0x6f,0x77,0x73,0xa3,0x73,0x10,0x6f,0xa3,0xd8,3,
-0x68,0xa2,0x4f,0x6c,0xa2,0x65,0x6e,0xa2,0x6a,0x74,0x10,0x68,2,0x61,0x3a,0x65,
-0x4a,0x6f,0x17,0x70,0x65,0x72,0x61,0x74,0x6f,0x72,0x73,0x7f,0x16,0x6c,0x70,0x68,
-0x61,0x6e,0x75,0x6d,0xa3,0x5d,0x16,0x6d,0x61,0x74,0x69,0x63,0x61,0x6c,1,0x61,
-0x36,0x6f,0x17,0x70,0x65,0x72,0x61,0x74,0x6f,0x72,0x73,0x7f,0x11,0x6c,0x70,0x1f,
-0x68,0x61,0x6e,0x75,0x6d,0x65,0x72,0x69,0x63,0x73,0x79,0x6d,0x62,0x6f,0x6c,0x73,
-0xa3,0x5d,1,0x61,0x3e,0x6a,0x12,0x6f,0x6e,0x67,0xa2,0xaa,0x14,0x74,0x69,0x6c,
-0x65,0x73,0xa3,0xaa,0x13,0x6a,0x61,0x6e,0x69,0xa3,0xe9,0x15,0x61,0x79,0x61,0x6c,
-0x61,0x6d,0x4f,1,0x64,0x34,0x69,0x15,0x63,0x68,0x61,0x65,0x61,0x6e,0xa3,0xea,
-0x12,0x61,0x69,0x63,0xa3,0xc6,2,0x65,0x66,0x6e,0x98,0x72,0x14,0x6f,0x69,0x74,
-0x69,0x63,1,0x63,0x3c,0x68,0x19,0x69,0x65,0x72,0x6f,0x67,0x6c,0x79,0x70,0x68,
-0x73,0xa3,0xd7,0x15,0x75,0x72,0x73,0x69,0x76,0x65,0xa3,0xd6,0x17,0x74,0x65,0x69,
-0x6d,0x61,0x79,0x65,0x6b,0xa2,0xb8,0x12,0x65,0x78,0x74,0xa2,0xd5,0x16,0x65,0x6e,
-0x73,0x69,0x6f,0x6e,0x73,0xa3,0xd5,0x18,0x64,0x65,0x6b,0x69,0x6b,0x61,0x6b,0x75,
-0x69,0xa3,0xeb,5,0x6b,0x1b,0x6b,0x3c,0x6f,0x40,0x75,0x18,0x6d,0x62,0x65,0x72,
-0x66,0x6f,0x72,0x6d,0x73,0x7b,0x10,0x6f,0xa3,0x92,0x14,0x62,0x6c,0x6f,0x63,0x6b,
-0x21,0x61,0x3a,0x62,0x21,0x65,0x16,0x77,0x74,0x61,0x69,0x6c,0x75,0x65,0xa3,0x8b,
-0x16,0x62,0x61,0x74,0x61,0x65,0x61,0x6e,0xa3,0xef,5,0x70,0x43,0x70,0x36,0x72,
-0x6a,0x73,0x14,0x6d,0x61,0x6e,0x79,0x61,0xa3,0x7a,0x18,0x74,0x69,0x63,0x61,0x6c,
-0x63,0x68,0x61,0x72,0x1f,0x61,0x63,0x74,0x65,0x72,0x72,0x65,0x63,0x6f,0x67,0x6e,
-0x69,0x74,0x69,0x6f,0x6e,0x85,1,0x69,0x46,0x6e,0x1e,0x61,0x6d,0x65,0x6e,0x74,
-0x61,0x6c,0x64,0x69,0x6e,0x67,0x62,0x61,0x74,0x73,0xa3,0xf2,0x11,0x79,0x61,0x47,
-0x63,0xa2,0x66,0x67,0xa2,0x66,0x6c,1,0x63,0xa2,0x57,0x64,5,0x70,0x2d,0x70,
-0x36,0x73,0x56,0x74,0x14,0x75,0x72,0x6b,0x69,0x63,0xa3,0xbf,0x11,0x65,0x72,1,
-0x6d,0x2e,0x73,0x12,0x69,0x61,0x6e,0xa3,0x8c,0x11,0x69,0x63,0xa3,0xf1,0x1a,0x6f,
-0x75,0x74,0x68,0x61,0x72,0x61,0x62,0x69,0x61,0x6e,0xa3,0xbb,0x68,0x42,0x69,0x54,
-0x6e,0x1a,0x6f,0x72,0x74,0x68,0x61,0x72,0x61,0x62,0x69,0x61,0x6e,0xa3,0xf0,0x17,
-0x75,0x6e,0x67,0x61,0x72,0x69,0x61,0x6e,0xa5,4,0x14,0x74,0x61,0x6c,0x69,0x63,
-0xa3,0x58,0x13,0x68,0x69,0x6b,0x69,0xa3,0x9d,0x10,0x72,0x85,0x12,0x68,0x61,0x6d,
-0x65,5,0x72,0x35,0x72,0x44,0x73,0x64,0x75,1,0x61,0xa3,0x4e,0x6e,0x17,0x63,
-0x74,0x75,0x61,0x74,0x69,0x6f,0x6e,0x71,0x17,0x69,0x76,0x61,0x74,0x65,0x75,0x73,
-0x65,0xa2,0x4e,0x13,0x61,0x72,0x65,0x61,0xa3,0x4e,0x1b,0x61,0x6c,0x74,0x65,0x72,
-0x70,0x61,0x68,0x6c,0x61,0x76,0x69,0xa3,0xf6,0x61,0x40,0x68,0x82,0x6c,0x19,0x61,
-0x79,0x69,0x6e,0x67,0x63,0x61,0x72,0x64,0x73,0xa3,0xcc,2,0x68,0x38,0x6c,0x4a,
-0x75,0x15,0x63,0x69,0x6e,0x68,0x61,0x75,0xa3,0xf5,0x17,0x61,0x77,0x68,0x68,0x6d,
-0x6f,0x6e,0x67,0xa3,0xf3,0x15,0x6d,0x79,0x72,0x65,0x6e,0x65,0xa3,0xf4,1,0x61,
-0x8e,0x6f,1,0x65,0x74,0x6e,0x16,0x65,0x74,0x69,0x63,0x65,0x78,0x74,0xa2,0x72,
-1,0x65,0x2c,0x73,0x11,0x75,0x70,0xa3,0x8d,0x15,0x6e,0x73,0x69,0x6f,0x6e,0x73,
-0xa2,0x72,0x19,0x73,0x75,0x70,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0xa3,0x8d,0x15,
-0x6e,0x69,0x63,0x69,0x61,0x6e,0xa3,0x97,1,0x67,0x3e,0x69,0x13,0x73,0x74,0x6f,
-0x73,0xa2,0xa6,0x13,0x64,0x69,0x73,0x63,0xa3,0xa6,0x12,0x73,0x70,0x61,0xa3,0x96,
-0x67,0xc3,0x8a,0x6a,0xc1,0x81,0x6a,0xa2,0xc5,0x6b,0xa2,0xde,0x6c,4,0x61,0x54,
-0x65,0xa2,0x61,0x69,0xa2,0x78,0x6f,0xa2,0xa7,0x79,1,0x63,0x2e,0x64,0x12,0x69,
-0x61,0x6e,0xa3,0xa9,0x12,0x69,0x61,0x6e,0xa3,0xa7,1,0x6f,0x55,0x74,0x11,0x69,
-0x6e,1,0x31,0x82,0x65,0x11,0x78,0x74,4,0x61,0x5c,0x62,0x29,0x63,0xa3,0x94,
-0x64,0xa3,0x95,0x65,0xa2,0xe7,0x13,0x6e,0x64,0x65,0x64,4,0x61,0x36,0x62,0x29,
-0x63,0xa3,0x94,0x64,0xa3,0x95,0x65,0xa3,0xe7,0x26,0x18,0x64,0x64,0x69,0x74,0x69,
-0x6f,0x6e,0x61,0x6c,0x6d,0x24,0x12,0x73,0x75,0x70,0x24,0x16,0x70,0x6c,0x65,0x6d,
-0x65,0x6e,0x74,0x25,1,0x70,0x42,0x74,0x1d,0x74,0x65,0x72,0x6c,0x69,0x6b,0x65,
-0x73,0x79,0x6d,0x62,0x6f,0x6c,0x73,0x79,0x12,0x63,0x68,0x61,0xa3,0x9c,2,0x6d,
-0x2e,0x6e,0x34,0x73,0x10,0x75,0xa3,0xb0,0x11,0x62,0x75,0xa3,0x6f,0x12,0x65,0x61,
-0x72,1,0x61,0xa3,0xe8,0x62,1,0x69,0x38,0x73,0x17,0x79,0x6c,0x6c,0x61,0x62,
-0x61,0x72,0x79,0xa3,0x75,0x17,0x64,0x65,0x6f,0x67,0x72,0x61,0x6d,0x73,0xa3,0x76,
-0x1a,0x77,0x73,0x75,0x72,0x72,0x6f,0x67,0x61,0x74,0x65,0x73,0xa3,0x4d,0x10,0x61,
-1,0x6d,0x32,0x76,0x14,0x61,0x6e,0x65,0x73,0x65,0xa3,0xb5,0x10,0x6f,0x5c,0x12,
-0x65,0x78,0x74,1,0x61,0xa3,0xb4,0x62,0xa3,0xb9,1,0x61,0x80,0x68,3,0x61,
-0x3c,0x6d,0x4c,0x6f,0x64,0x75,0x15,0x64,0x61,0x77,0x61,0x64,0x69,0xa3,0xe6,0x16,
-0x72,0x6f,0x73,0x68,0x74,0x68,0x69,0xa3,0x89,0x11,0x65,0x72,0x68,0x16,0x73,0x79,
-0x6d,0x62,0x6f,0x6c,0x73,0xa3,0x71,0x12,0x6a,0x6b,0x69,0xa3,0xe5,3,0x69,0x38,
-0x6e,0x40,0x74,0x9c,0x79,0x13,0x61,0x68,0x6c,0x69,0xa3,0xa2,0x12,0x74,0x68,0x69,
-0xa3,0xc1,3,0x61,0x34,0x62,0x50,0x67,0x56,0x6e,0x12,0x61,0x64,0x61,0x4d,0x12,
-0x73,0x75,0x70,0xa2,0xcb,0x16,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0xa3,0xcb,0x11,
-0x75,0x6e,0xa3,0x42,0x11,0x78,0x69,0x96,0x17,0x72,0x61,0x64,0x69,0x63,0x61,0x6c,
-0x73,0x97,0x14,0x61,0x6b,0x61,0x6e,0x61,0x9e,1,0x65,0x4c,0x70,0x10,0x68,0x1f,
-0x6f,0x6e,0x65,0x74,0x69,0x63,0x65,0x78,0x74,0x65,0x6e,0x73,0x69,0x6f,0x6e,0x73,
-0xa3,0x6b,0x11,0x78,0x74,0xa3,0x6b,0x67,0xa2,0x84,0x68,0xa4,0x24,0x69,3,0x64,
-0x4a,0x6d,0x8e,0x6e,0xa2,0x44,0x70,0x13,0x61,0x65,0x78,0x74,0x2a,0x16,0x65,0x6e,
-0x73,0x69,0x6f,0x6e,0x73,0x2b,1,0x63,0x99,0x65,0x1c,0x6f,0x67,0x72,0x61,0x70,
-0x68,0x69,0x63,0x64,0x65,0x73,0x63,0x72,0x1f,0x69,0x70,0x74,0x69,0x6f,0x6e,0x63,
-0x68,0x61,0x72,0x61,0x63,0x74,0x65,0x72,0x73,0x99,0x1c,0x70,0x65,0x72,0x69,0x61,
-0x6c,0x61,0x72,0x61,0x6d,0x61,0x69,0x63,0xa3,0xba,1,0x64,0x62,0x73,0x1b,0x63,
-0x72,0x69,0x70,0x74,0x69,0x6f,0x6e,0x61,0x6c,0x70,0x61,1,0x68,0x32,0x72,0x14,
-0x74,0x68,0x69,0x61,0x6e,0xa3,0xbd,0x13,0x6c,0x61,0x76,0x69,0xa3,0xbe,0x1c,0x69,
-0x63,0x6e,0x75,0x6d,0x62,0x65,0x72,0x66,0x6f,0x72,0x6d,0x73,0xa3,0xb2,4,0x65,
-0x58,0x6c,0xa2,0x63,0x6f,0xa2,0x6b,0x72,0xa2,0x6f,0x75,1,0x6a,0x30,0x72,0x14,
-0x6d,0x75,0x6b,0x68,0x69,0x43,0x14,0x61,0x72,0x61,0x74,0x69,0x45,1,0x6e,0x8c,
-0x6f,1,0x6d,0x4e,0x72,0x13,0x67,0x69,0x61,0x6e,0x5a,0x12,0x73,0x75,0x70,0xa2,
-0x87,0x16,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0xa3,0x87,0x1a,0x65,0x74,0x72,0x69,
-0x63,0x73,0x68,0x61,0x70,0x65,0x73,0x8c,0x12,0x65,0x78,0x74,0xa2,0xe3,0x14,0x65,
-0x6e,0x64,0x65,0x64,0xa3,0xe3,0x1e,0x65,0x72,0x61,0x6c,0x70,0x75,0x6e,0x63,0x74,
-0x75,0x61,0x74,0x69,0x6f,0x6e,0x71,0x17,0x61,0x67,0x6f,0x6c,0x69,0x74,0x69,0x63,
-0xa3,0x88,0x13,0x74,0x68,0x69,0x63,0xa3,0x59,1,0x61,0x5c,0x65,0x11,0x65,0x6b,
-0x30,1,0x61,0x38,0x65,0x11,0x78,0x74,0x6e,0x14,0x65,0x6e,0x64,0x65,0x64,0x6f,
-0x17,0x6e,0x64,0x63,0x6f,0x70,0x74,0x69,0x63,0x31,0x13,0x6e,0x74,0x68,0x61,0xa3,
-0xe4,2,0x61,0xa2,0x48,0x65,0xa2,0xcf,0x69,1,0x67,0x30,0x72,0x14,0x61,0x67,
-0x61,0x6e,0x61,0x9d,0x10,0x68,1,0x70,0x3a,0x73,0x18,0x75,0x72,0x72,0x6f,0x67,
-0x61,0x74,0x65,0x73,0xa3,0x4b,1,0x72,0x3c,0x75,0x19,0x73,0x75,0x72,0x72,0x6f,
-0x67,0x61,0x74,0x65,0x73,0xa3,0x4c,0x11,0x69,0x76,0x1f,0x61,0x74,0x65,0x75,0x73,
-0x65,0x73,0x75,0x72,0x72,0x6f,0x67,0x61,0x74,0x65,0x73,0xa3,0x4c,2,0x6c,0x32,
-0x6e,0x9a,0x74,0x12,0x72,0x61,0x6e,0xa5,2,0x10,0x66,2,0x61,0x58,0x6d,0x70,
-0x77,0x14,0x69,0x64,0x74,0x68,0x61,0x1f,0x6e,0x64,0x66,0x75,0x6c,0x6c,0x77,0x69,
-0x64,0x74,0x68,0x66,0x6f,0x72,0x6d,0x73,0xa3,0x57,0x1a,0x6e,0x64,0x66,0x75,0x6c,
-0x6c,0x66,0x6f,0x72,0x6d,0x73,0xa3,0x57,0x13,0x61,0x72,0x6b,0x73,0xa3,0x52,1,
-0x67,0x2e,0x75,0x12,0x6e,0x6f,0x6f,0xa3,0x63,0x11,0x75,0x6c,0xa2,0x4a,2,0x63,
-0x3c,0x6a,0x5e,0x73,0x17,0x79,0x6c,0x6c,0x61,0x62,0x6c,0x65,0x73,0xa3,0x4a,0x1f,
-0x6f,0x6d,0x70,0x61,0x74,0x69,0x62,0x69,0x6c,0x69,0x74,0x79,0x6a,0x61,0x6d,0x6f,
-0xa3,0x41,0x12,0x61,0x6d,0x6f,0x5c,0x17,0x65,0x78,0x74,0x65,0x6e,0x64,0x65,0x64,
-1,0x61,0xa3,0xb4,0x62,0xa3,0xb9,0x13,0x62,0x72,0x65,0x77,0x37,0x61,0xa2,0xe9,
-0x62,0xa6,0x20,0x63,0xa6,0xe8,0x64,0xac,0x5f,0x65,5,0x6d,0xa2,0x6d,0x86,0x6e,
-0x96,0x74,0x15,0x68,0x69,0x6f,0x70,0x69,0x63,0x5e,1,0x65,0x40,0x73,0x11,0x75,
-0x70,0xa2,0x86,0x16,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0xa3,0x86,0x11,0x78,0x74,
-0xa2,0x85,1,0x61,0xa3,0xc8,0x65,0x13,0x6e,0x64,0x65,0x64,0xa2,0x85,0x10,0x61,
-0xa3,0xc8,0x16,0x6f,0x74,0x69,0x63,0x6f,0x6e,0x73,0xa3,0xce,0x15,0x63,0x6c,0x6f,
-0x73,0x65,0x64,2,0x61,0x5a,0x63,0x9e,0x69,0x1c,0x64,0x65,0x6f,0x67,0x72,0x61,
-0x70,0x68,0x69,0x63,0x73,0x75,0x70,0xa2,0xc4,0x16,0x70,0x6c,0x65,0x6d,0x65,0x6e,
-0x74,0xa3,0xc4,0x16,0x6c,0x70,0x68,0x61,0x6e,0x75,0x6d,0x86,1,0x65,0x2c,0x73,
-0x11,0x75,0x70,0xa3,0xc3,0x13,0x72,0x69,0x63,0x73,0x86,0x18,0x75,0x70,0x70,0x6c,
-0x65,0x6d,0x65,0x6e,0x74,0xa3,0xc3,0x11,0x6a,0x6b,0xa2,0x44,0x1f,0x6c,0x65,0x74,
-0x74,0x65,0x72,0x73,0x61,0x6e,0x64,0x6d,0x6f,0x6e,0x74,0x68,0x73,0xa3,0x44,0x61,
-0x36,0x67,0x62,0x6c,0x14,0x62,0x61,0x73,0x61,0x6e,0xa3,0xe2,0x13,0x72,0x6c,0x79,
-0x64,0x1f,0x79,0x6e,0x61,0x73,0x74,0x69,0x63,0x63,0x75,0x6e,0x65,0x69,0x66,0x6f,
-0x72,0x6d,0xa5,1,0x10,0x79,0x1f,0x70,0x74,0x69,0x61,0x6e,0x68,0x69,0x65,0x72,
-0x6f,0x67,0x6c,0x79,0x70,0x68,0x73,0xa3,0xc2,6,0x6e,0xc0,0xe5,0x6e,0x3e,0x72,
-0xa2,0x5d,0x73,0xa2,0xd8,0x76,0x14,0x65,0x73,0x74,0x61,0x6e,0xa3,0xbc,1,0x61,
-0x92,0x63,0x13,0x69,0x65,0x6e,0x74,1,0x67,0x34,0x73,0x15,0x79,0x6d,0x62,0x6f,
-0x6c,0x73,0xa3,0xa5,0x13,0x72,0x65,0x65,0x6b,1,0x6d,0x34,0x6e,0x15,0x75,0x6d,
-0x62,0x65,0x72,0x73,0xa3,0x7f,0x13,0x75,0x73,0x69,0x63,0xa2,0x7e,0x19,0x61,0x6c,
-0x6e,0x6f,0x74,0x61,0x74,0x69,0x6f,0x6e,0xa3,0x7e,0x10,0x74,0x1f,0x6f,0x6c,0x69,
-0x61,0x6e,0x68,0x69,0x65,0x72,0x6f,0x67,0x6c,0x79,0x70,0x68,0x73,0xa3,0xfe,2,
-0x61,0x32,0x6d,0xa2,0x71,0x72,0x12,0x6f,0x77,0x73,0x7d,0x12,0x62,0x69,0x63,0x38,
-3,0x65,0x4a,0x6d,0x66,0x70,0xa2,0x43,0x73,0x11,0x75,0x70,0xa2,0x80,0x16,0x70,
-0x6c,0x65,0x6d,0x65,0x6e,0x74,0xa3,0x80,0x11,0x78,0x74,1,0x61,0xa3,0xd2,0x65,
-0x14,0x6e,0x64,0x65,0x64,0x61,0xa3,0xd2,0x12,0x61,0x74,0x68,0xa2,0xd3,0x18,0x65,
-0x6d,0x61,0x74,0x69,0x63,0x61,0x6c,0x61,0x1f,0x6c,0x70,0x68,0x61,0x62,0x65,0x74,
-0x69,0x63,0x73,0x79,0x6d,0x62,0x6f,0x6c,0x73,0xa3,0xd3,1,0x66,0x42,0x72,0x1e,
-0x65,0x73,0x65,0x6e,0x74,0x61,0x74,0x69,0x6f,0x6e,0x66,0x6f,0x72,0x6d,0x73,1,
-0x61,0xa3,0x51,0x62,0xa3,0x55,0x14,0x65,0x6e,0x69,0x61,0x6e,0x35,0x12,0x63,0x69,
-0x69,0x23,0x65,0x98,0x68,0xa2,0x47,0x6c,1,0x63,0x62,0x70,0x17,0x68,0x61,0x62,
-0x65,0x74,0x69,0x63,0x70,1,0x66,0xa3,0x50,0x72,0x1e,0x65,0x73,0x65,0x6e,0x74,
-0x61,0x74,0x69,0x6f,0x6e,0x66,0x6f,0x72,0x6d,0x73,0xa3,0x50,0x16,0x68,0x65,0x6d,
-0x69,0x63,0x61,0x6c,0xa2,0xd0,0x16,0x73,0x79,0x6d,0x62,0x6f,0x6c,0x73,0xa3,0xd0,
-0x1a,0x67,0x65,0x61,0x6e,0x6e,0x75,0x6d,0x62,0x65,0x72,0x73,0xa3,0x77,0x11,0x6f,
-0x6d,0xa3,0xfd,6,0x6f,0x71,0x6f,0x64,0x72,0xa2,0x41,0x75,0xa2,0x58,0x79,0x1b,
-0x7a,0x61,0x6e,0x74,0x69,0x6e,0x65,0x6d,0x75,0x73,0x69,0x63,0xa2,0x5b,0x18,0x61,
-0x6c,0x73,0x79,0x6d,0x62,0x6f,0x6c,0x73,0xa3,0x5b,1,0x70,0x34,0x78,0x16,0x64,
-0x72,0x61,0x77,0x69,0x6e,0x67,0x89,0x14,0x6f,0x6d,0x6f,0x66,0x6f,0xa0,0x12,0x65,
-0x78,0x74,0xa2,0x43,0x14,0x65,0x6e,0x64,0x65,0x64,0xa3,0x43,0x10,0x61,1,0x68,
-0x40,0x69,0x12,0x6c,0x6c,0x65,0x92,0x17,0x70,0x61,0x74,0x74,0x65,0x72,0x6e,0x73,
-0x93,0x11,0x6d,0x69,0xa3,0xc9,1,0x67,0x2c,0x68,0x11,0x69,0x64,0xa3,0x64,0x14,
-0x69,0x6e,0x65,0x73,0x65,0xa3,0x81,0x61,0x42,0x65,0xa2,0x4b,0x6c,0x1a,0x6f,0x63,
-0x6b,0x65,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x73,0x8b,3,0x6c,0x34,0x6d,0x40,0x73,
-0x66,0x74,0x11,0x61,0x6b,0xa3,0xc7,0x14,0x69,0x6e,0x65,0x73,0x65,0xa3,0x93,0x11,
-0x75,0x6d,0xa2,0xb1,0x12,0x73,0x75,0x70,0xa2,0xca,0x16,0x70,0x6c,0x65,0x6d,0x65,
-0x6e,0x74,0xa3,0xca,1,0x69,0x30,0x73,0x13,0x61,0x76,0x61,0x68,0xa3,0xdd,0x15,
-0x63,0x6c,0x61,0x74,0x69,0x6e,0x23,0x14,0x6e,0x67,0x61,0x6c,0x69,0x41,5,0x6f,
-0xc1,0x46,0x6f,0xa2,0x4f,0x75,0xa4,0xa,0x79,1,0x70,0x90,0x72,0x14,0x69,0x6c,
-0x6c,0x69,0x63,0x32,1,0x65,0x4c,0x73,0x11,0x75,0x70,0xa2,0x61,0x16,0x70,0x6c,
-0x65,0x6d,0x65,0x6e,0x74,0xa2,0x61,0x12,0x61,0x72,0x79,0xa3,0x61,0x11,0x78,0x74,
-2,0x61,0xa3,0x9e,0x62,0xa3,0xa0,0x65,0x13,0x6e,0x64,0x65,0x64,1,0x61,0xa3,
-0x9e,0x62,0xa3,0xa0,0x1c,0x72,0x69,0x6f,0x74,0x73,0x79,0x6c,0x6c,0x61,0x62,0x61,
-0x72,0x79,0xa3,0x7b,3,0x6d,0x5a,0x6e,0xa2,0x95,0x70,0xa2,0xa0,0x75,0x17,0x6e,
-0x74,0x69,0x6e,0x67,0x72,0x6f,0x64,0xa2,0x9a,0x17,0x6e,0x75,0x6d,0x65,0x72,0x61,
-0x6c,0x73,0xa3,0x9a,2,0x62,0x3a,0x6d,0xa2,0x5f,0x70,0x15,0x61,0x74,0x6a,0x61,
-0x6d,0x6f,0xa3,0x41,0x14,0x69,0x6e,0x69,0x6e,0x67,2,0x64,0x46,0x68,0x9e,0x6d,
-0x1d,0x61,0x72,0x6b,0x73,0x66,0x6f,0x72,0x73,0x79,0x6d,0x62,0x6f,0x6c,0x73,0x77,
-0x1e,0x69,0x61,0x63,0x72,0x69,0x74,0x69,0x63,0x61,0x6c,0x6d,0x61,0x72,0x6b,0x73,
-0x2e,2,0x65,0x40,0x66,0xa6,0x1b,0x73,0x18,0x75,0x70,0x70,0x6c,0x65,0x6d,0x65,
-0x6e,0x74,0xa3,0x83,0x16,0x78,0x74,0x65,0x6e,0x64,0x65,0x64,0xa3,0xe0,0x17,0x61,
-0x6c,0x66,0x6d,0x61,0x72,0x6b,0x73,0xa3,0x52,0x11,0x6f,0x6e,0x1f,0x69,0x6e,0x64,
-0x69,0x63,0x6e,0x75,0x6d,0x62,0x65,0x72,0x66,0x6f,0x72,0x6d,0x73,0xa3,0xb2,0x1b,
-0x74,0x72,0x6f,0x6c,0x70,0x69,0x63,0x74,0x75,0x72,0x65,0x73,0x83,0x12,0x74,0x69,
-0x63,0xa2,0x84,0x1b,0x65,0x70,0x61,0x63,0x74,0x6e,0x75,0x6d,0x62,0x65,0x72,0x73,
-0xa3,0xdf,1,0x6e,0x3e,0x72,0x1b,0x72,0x65,0x6e,0x63,0x79,0x73,0x79,0x6d,0x62,
-0x6f,0x6c,0x73,0x75,0x15,0x65,0x69,0x66,0x6f,0x72,0x6d,0xa2,0x98,0x16,0x6e,0x75,
-0x6d,0x62,0x65,0x72,0x73,0xa2,0x99,0x1d,0x61,0x6e,0x64,0x70,0x75,0x6e,0x63,0x74,
-0x75,0x61,0x74,0x69,0x6f,0x6e,0xa3,0x99,0x61,0xa2,0xda,0x68,0xa4,4,0x6a,0x10,
-0x6b,0xa2,0x47,4,0x63,0x8e,0x65,0xa2,0x81,0x72,0xa2,0x91,0x73,0xa2,0xa3,0x75,
-0x1f,0x6e,0x69,0x66,0x69,0x65,0x64,0x69,0x64,0x65,0x6f,0x67,0x72,0x61,0x70,0x68,
-0x73,0xa2,0x47,0x18,0x65,0x78,0x74,0x65,0x6e,0x73,0x69,0x6f,0x6e,4,0x61,0xa3,
-0x46,0x62,0xa3,0x5e,0x63,0xa3,0xc5,0x64,0xa3,0xd1,0x65,0xa5,0,0x14,0x6f,0x6d,
-0x70,0x61,0x74,0xa2,0x45,1,0x66,0x96,0x69,1,0x62,0x44,0x64,0x17,0x65,0x6f,
-0x67,0x72,0x61,0x70,0x68,0x73,0xa2,0x4f,0x12,0x73,0x75,0x70,0xa3,0x5f,0x14,0x69,
-0x6c,0x69,0x74,0x79,0xa2,0x45,1,0x66,0x54,0x69,0x18,0x64,0x65,0x6f,0x67,0x72,
-0x61,0x70,0x68,0x73,0xa2,0x4f,0x19,0x73,0x75,0x70,0x70,0x6c,0x65,0x6d,0x65,0x6e,
-0x74,0xa3,0x5f,0x13,0x6f,0x72,0x6d,0x73,0xa3,0x53,0x11,0x78,0x74,4,0x61,0xa3,
-0x46,0x62,0xa3,0x5e,0x63,0xa3,0xc5,0x64,0xa3,0xd1,0x65,0xa5,0,0x19,0x61,0x64,
-0x69,0x63,0x61,0x6c,0x73,0x73,0x75,0x70,0x94,0x16,0x70,0x6c,0x65,0x6d,0x65,0x6e,
-0x74,0x95,1,0x74,0x50,0x79,0x14,0x6d,0x62,0x6f,0x6c,0x73,0x9a,0x1d,0x61,0x6e,
-0x64,0x70,0x75,0x6e,0x63,0x74,0x75,0x61,0x74,0x69,0x6f,0x6e,0x9b,0x14,0x72,0x6f,
-0x6b,0x65,0x73,0xa3,0x82,2,0x6e,0x48,0x72,0x64,0x75,0x1d,0x63,0x61,0x73,0x69,
-0x61,0x6e,0x61,0x6c,0x62,0x61,0x6e,0x69,0x61,0x6e,0xa3,0xde,0x1d,0x61,0x64,0x69,
-0x61,0x6e,0x73,0x79,0x6c,0x6c,0x61,0x62,0x69,0x63,0x73,0x63,0x12,0x69,0x61,0x6e,
-0xa3,0xa8,1,0x61,0x50,0x65,0x14,0x72,0x6f,0x6b,0x65,0x65,0x60,0x12,0x73,0x75,
-0x70,0xa2,0xff,0x16,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0xa3,0xff,1,0x6b,0x26,
-0x6d,0xa3,0xa4,0x11,0x6d,0x61,0xa3,0xd4,3,0x65,0x3e,0x69,0x7e,0x6f,0xa2,0x5d,
-0x75,0x15,0x70,0x6c,0x6f,0x79,0x61,0x6e,0xa3,0xe1,1,0x73,0x50,0x76,0x16,0x61,
-0x6e,0x61,0x67,0x61,0x72,0x69,0x3e,0x12,0x65,0x78,0x74,0xa2,0xb3,0x14,0x65,0x6e,
-0x64,0x65,0x64,0xa3,0xb3,0x13,0x65,0x72,0x65,0x74,0xa3,0x5a,1,0x61,0x30,0x6e,
-0x14,0x67,0x62,0x61,0x74,0x73,0x91,0x18,0x63,0x72,0x69,0x74,0x69,0x63,0x61,0x6c,
-0x73,0x2e,2,0x65,0x30,0x66,0x36,0x73,0x11,0x75,0x70,0xa3,0x83,0x11,0x78,0x74,
-0xa3,0xe0,0x18,0x6f,0x72,0x73,0x79,0x6d,0x62,0x6f,0x6c,0x73,0x77,0x13,0x6d,0x69,
-0x6e,0x6f,0xa2,0xab,0x14,0x74,0x69,0x6c,0x65,0x73,0xa3,0xab,8,0x6d,0x5f,0x6d,
-0x3a,0x6e,0x48,0x73,0x7a,0x76,0xa2,0x4b,0x77,0x12,0x69,0x64,0x65,0x43,0x11,0x65,
-0x64,0x32,0x12,0x69,0x61,0x6c,0x33,2,0x61,0x40,0x62,0x37,0x6f,1,0x62,0x28,
-0x6e,0x10,0x65,0x21,0x13,0x72,0x65,0x61,0x6b,0x37,0x10,0x72,0x34,0x12,0x72,0x6f,
-0x77,0x35,2,0x6d,0x38,0x71,0x46,0x75,1,0x62,0x3d,0x70,0x3e,0x11,0x65,0x72,
-0x3f,1,0x61,0x24,0x6c,0x39,0x11,0x6c,0x6c,0x39,1,0x72,0x3b,0x75,0x12,0x61,
-0x72,0x65,0x3b,0x12,0x65,0x72,0x74,0x40,0x13,0x69,0x63,0x61,0x6c,0x41,0x63,0x58,
-0x65,0x92,0x66,0x96,0x69,1,0x6e,0x36,0x73,0x10,0x6f,0x30,0x14,0x6c,0x61,0x74,
-0x65,0x64,0x31,0x11,0x69,0x74,0x2e,0x12,0x69,0x61,0x6c,0x2f,2,0x61,0x36,0x69,
-0x48,0x6f,0x10,0x6d,0x24,0x12,0x70,0x61,0x74,0x25,0x10,0x6e,0x22,0x15,0x6f,0x6e,
-0x69,0x63,0x61,0x6c,0x23,0x13,0x72,0x63,0x6c,0x65,0x27,0x11,0x6e,0x63,0x27,2,
-0x69,0x3a,0x6f,0x44,0x72,0x10,0x61,0x2c,0x14,0x63,0x74,0x69,0x6f,0x6e,0x2d,0x10,
-0x6e,0x28,0x11,0x61,0x6c,0x29,0x11,0x6e,0x74,0x2b,4,0x61,0x3a,0x66,0x4c,0x68,
-0x5e,0x6e,0x70,0x77,0x2a,0x12,0x69,0x64,0x65,0x2b,0x22,0x17,0x6d,0x62,0x69,0x67,
-0x75,0x6f,0x75,0x73,0x23,0x26,0x17,0x75,0x6c,0x6c,0x77,0x69,0x64,0x74,0x68,0x27,
-0x24,0x17,0x61,0x6c,0x66,0x77,0x69,0x64,0x74,0x68,0x25,0x20,1,0x61,0x30,0x65,
-0x14,0x75,0x74,0x72,0x61,0x6c,0x21,0x28,0x13,0x72,0x72,0x6f,0x77,0x29,0xd,0x6e,
-0xc0,0xfb,0x73,0x6d,0x73,0x3a,0x74,0x98,0x75,0xa2,0x49,0x7a,2,0x6c,0x3b,0x70,
-0x3d,0x73,0x39,5,0x6f,0x28,0x6f,0x57,0x70,0x34,0x75,0x16,0x72,0x72,0x6f,0x67,
-0x61,0x74,0x65,0x45,0x11,0x61,0x63,1,0x65,0x32,0x69,0x15,0x6e,0x67,0x6d,0x61,
-0x72,0x6b,0x31,0x18,0x73,0x65,0x70,0x61,0x72,0x61,0x74,0x6f,0x72,0x39,0x63,0x53,
-0x6b,0x55,0x6d,0x51,0x1d,0x69,0x74,0x6c,0x65,0x63,0x61,0x73,0x65,0x6c,0x65,0x74,
-0x74,0x65,0x72,0x27,1,0x6e,0x40,0x70,0x1c,0x70,0x65,0x72,0x63,0x61,0x73,0x65,
-0x6c,0x65,0x74,0x74,0x65,0x72,0x23,0x17,0x61,0x73,0x73,0x69,0x67,0x6e,0x65,0x64,
-0x21,0x6e,0x8a,0x6f,0xa2,0x47,0x70,8,0x66,0x14,0x66,0x5b,0x69,0x59,0x6f,0x4f,
-0x72,0x24,0x73,0x49,0x17,0x69,0x76,0x61,0x74,0x65,0x75,0x73,0x65,0x43,0x61,0x2c,
-0x63,0x4d,0x64,0x47,0x65,0x4b,0x1f,0x72,0x61,0x67,0x72,0x61,0x70,0x68,0x73,0x65,
-0x70,0x61,0x72,0x61,0x74,0x6f,0x72,0x3d,2,0x64,0x33,0x6c,0x35,0x6f,0x36,0x1b,
-0x6e,0x73,0x70,0x61,0x63,0x69,0x6e,0x67,0x6d,0x61,0x72,0x6b,0x2d,1,0x70,0x7c,
-0x74,0x12,0x68,0x65,0x72,3,0x6c,0x38,0x6e,0x42,0x70,0x4c,0x73,0x14,0x79,0x6d,
-0x62,0x6f,0x6c,0x57,0x14,0x65,0x74,0x74,0x65,0x72,0x2b,0x14,0x75,0x6d,0x62,0x65,
-0x72,0x37,0x19,0x75,0x6e,0x63,0x74,0x75,0x61,0x74,0x69,0x6f,0x6e,0x4f,0x1c,0x65,
-0x6e,0x70,0x75,0x6e,0x63,0x74,0x75,0x61,0x74,0x69,0x6f,0x6e,0x49,0x66,0x9e,0x66,
-0x88,0x69,0xa2,0x4b,0x6c,0xa2,0x5c,0x6d,4,0x61,0x60,0x63,0x31,0x65,0x2f,0x6e,
-0x2d,0x6f,0x15,0x64,0x69,0x66,0x69,0x65,0x72,1,0x6c,0x30,0x73,0x14,0x79,0x6d,
-0x62,0x6f,0x6c,0x55,0x14,0x65,0x74,0x74,0x65,0x72,0x29,0x17,0x74,0x68,0x73,0x79,
-0x6d,0x62,0x6f,0x6c,0x51,1,0x69,0x2e,0x6f,0x13,0x72,0x6d,0x61,0x74,0x41,0x1d,
-0x6e,0x61,0x6c,0x70,0x75,0x6e,0x63,0x74,0x75,0x61,0x74,0x69,0x6f,0x6e,0x5b,0x10,
-0x6e,0x1f,0x69,0x74,0x69,0x61,0x6c,0x70,0x75,0x6e,0x63,0x74,0x75,0x61,0x74,0x69,
-0x6f,0x6e,0x59,6,0x6d,0x18,0x6d,0x29,0x6f,0x28,0x74,0x27,0x75,0x23,0x2a,0x1c,
-0x77,0x65,0x72,0x63,0x61,0x73,0x65,0x6c,0x65,0x74,0x74,0x65,0x72,0x25,0x65,0x28,
-0x69,0x3c,0x6c,0x25,0x19,0x74,0x74,0x65,0x72,0x6e,0x75,0x6d,0x62,0x65,0x72,0x35,
-0x1a,0x6e,0x65,0x73,0x65,0x70,0x61,0x72,0x61,0x74,0x6f,0x72,0x3b,0x63,0x44,0x64,
-0xa2,0x60,0x65,0x1b,0x6e,0x63,0x6c,0x6f,0x73,0x69,0x6e,0x67,0x6d,0x61,0x72,0x6b,
-0x2f,6,0x6e,0x39,0x6e,0x46,0x6f,0x4e,0x73,0x45,0x75,0x1b,0x72,0x72,0x65,0x6e,
-0x63,0x79,0x73,0x79,0x6d,0x62,0x6f,0x6c,0x53,0x20,0x12,0x74,0x72,0x6c,0x3f,0x42,
-0x10,0x6e,1,0x6e,0x2c,0x74,0x12,0x72,0x6f,0x6c,0x3f,0x1f,0x65,0x63,0x74,0x6f,
-0x72,0x70,0x75,0x6e,0x63,0x74,0x75,0x61,0x74,0x69,0x6f,0x6e,0x4d,0x63,0x3f,0x66,
-0x41,0x6c,0x1d,0x6f,0x73,0x65,0x70,0x75,0x6e,0x63,0x74,0x75,0x61,0x74,0x69,0x6f,
-0x6e,0x4b,2,0x61,0x30,0x65,0x4a,0x69,0x12,0x67,0x69,0x74,0x33,0x1c,0x73,0x68,
-0x70,0x75,0x6e,0x63,0x74,0x75,0x61,0x74,0x69,0x6f,0x6e,0x47,0x1a,0x63,0x69,0x6d,
-0x61,0x6c,0x6e,0x75,0x6d,0x62,0x65,0x72,0x33,0,0x12,0x6d,0xc1,0xec,0x73,0xa1,
-0x73,0x4e,0x74,0xa2,0x56,0x77,0xa2,0x72,0x79,0xa2,0x73,0x7a,1,0x61,0x2c,0x68,
-0x12,0x61,0x69,0x6e,0x8b,0x11,0x69,0x6e,0x85,5,0x74,0x22,0x74,0x38,0x77,0x4c,
-0x79,0x16,0x72,0x69,0x61,0x63,0x77,0x61,0x77,0x6f,0x18,0x72,0x61,0x69,0x67,0x68,
-0x74,0x77,0x61,0x77,0xa3,0x55,0x15,0x61,0x73,0x68,0x6b,0x61,0x66,0x6d,0x61,0x2e,
-0x65,0x38,0x68,0x11,0x69,0x6e,0x6b,0x10,0x64,0x62,0x11,0x68,0x65,0x65,1,0x65,
-0x2e,0x6d,0x13,0x6b,0x61,0x74,0x68,0x69,0x10,0x6e,0x67,1,0x61,0x4e,0x65,1,
-0x68,0x28,0x74,0x10,0x68,0x77,0x16,0x6d,0x61,0x72,0x62,0x75,0x74,0x61,0x74,0x13,
-0x67,0x6f,0x61,0x6c,0x3d,1,0x68,0x71,0x77,0x73,0x11,0x61,0x77,0x79,1,0x65,
-0x32,0x75,0x11,0x64,0x68,0x80,0x11,0x68,0x65,0x83,0x10,0x68,0x7a,1,0x62,0x34,
-0x77,0x16,0x69,0x74,0x68,0x74,0x61,0x69,0x6c,0x7f,0x14,0x61,0x72,0x72,0x65,0x65,
-0x7d,0x6d,0x6c,0x6e,0xa4,0x18,0x70,0xa4,0x35,0x71,0xa4,0x35,0x72,1,0x65,0x38,
-0x6f,0x18,0x68,0x69,0x6e,0x67,0x79,0x61,0x79,0x65,0x68,0x93,1,0x68,0x5f,0x76,
-0x16,0x65,0x72,0x73,0x65,0x64,0x70,0x65,0x61,2,0x61,0x2e,0x65,0xa2,0xeb,0x69,
-0x10,0x6d,0x53,0x17,0x6e,0x69,0x63,0x68,0x61,0x65,0x61,0x6e,0,0x12,0x6e,0x76,
-0x73,0x51,0x73,0x3e,0x74,0x5c,0x77,0xa0,0x79,0xa2,0x42,0x7a,0x13,0x61,0x79,0x69,
-0x6e,0xa3,0x54,0x10,0x61,1,0x64,0x2e,0x6d,0x12,0x65,0x6b,0x68,0xa3,0x4c,0x11,
-0x68,0x65,0xa3,0x4b,3,0x61,0x38,0x65,0x3c,0x68,0x4a,0x77,0x13,0x65,0x6e,0x74,
-0x79,0xa3,0x51,0x10,0x77,0xa3,0x4d,1,0x6e,0xa3,0x4e,0x74,0x10,0x68,0xa3,0x4f,
-0x14,0x61,0x6d,0x65,0x64,0x68,0xa3,0x50,0x11,0x61,0x77,0xa3,0x52,0x12,0x6f,0x64,
-0x68,0xa3,0x53,0x6e,0x3a,0x6f,0x40,0x70,0x46,0x71,0x4a,0x72,0x12,0x65,0x73,0x68,
-0xa3,0x4a,0x11,0x75,0x6e,0xa3,0x46,0x11,0x6e,0x65,0xa3,0x47,0x10,0x65,0xa3,0x48,
-0x12,0x6f,0x70,0x68,0xa3,0x49,0x67,0x33,0x67,0x38,0x68,0x40,0x6b,0x5e,0x6c,0x66,
-0x6d,0x11,0x65,0x6d,0xa3,0x45,0x13,0x69,0x6d,0x65,0x6c,0xa1,1,0x65,0x32,0x75,
-0x14,0x6e,0x64,0x72,0x65,0x64,0xa3,0x42,0x11,0x74,0x68,0xa3,0x41,0x12,0x61,0x70,
-0x68,0xa3,0x43,0x14,0x61,0x6d,0x65,0x64,0x68,0xa3,0x44,0x61,0x34,0x62,0x4a,0x64,
-0x50,0x66,0x12,0x69,0x76,0x65,0x9f,1,0x6c,0x2a,0x79,0x11,0x69,0x6e,0x97,0x12,
-0x65,0x70,0x68,0x95,0x12,0x65,0x74,0x68,0x99,1,0x61,0x30,0x68,0x14,0x61,0x6d,
-0x65,0x64,0x68,0x9d,0x13,0x6c,0x65,0x74,0x68,0x9b,0x11,0x65,0x6d,0x51,2,0x6f,
-0x2c,0x75,0x50,0x79,0x10,0x61,0x91,1,0x6a,0x28,0x6f,0x10,0x6e,0x55,0x1a,0x6f,
-0x69,0x6e,0x69,0x6e,0x67,0x67,0x72,0x6f,0x75,0x70,0x21,0x10,0x6e,0x57,0x10,0x65,
-0x59,0x10,0x61,1,0x66,0x5b,0x70,0x10,0x68,0x5d,0x66,0x7b,0x66,0x42,0x67,0x7a,
-0x68,0x8a,0x6b,0xa2,0x56,0x6c,0x11,0x61,0x6d,0x4c,0x12,0x61,0x64,0x68,0x4f,2,
-0x61,0x3e,0x65,0x4a,0x69,0x19,0x6e,0x61,0x6c,0x73,0x65,0x6d,0x6b,0x61,0x74,0x68,
-0x35,0x15,0x72,0x73,0x69,0x79,0x65,0x68,0x8f,0x86,0x10,0x68,0x33,0x10,0x61,1,
-0x66,0x37,0x6d,0x11,0x61,0x6c,0x39,1,0x61,0x40,0x65,0x3e,1,0x68,0x28,0x74,
-0x10,0x68,0x45,0x40,0x13,0x67,0x6f,0x61,0x6c,0x43,1,0x68,0x3b,0x6d,0x1a,0x7a,
-0x61,0x6f,0x6e,0x68,0x65,0x68,0x67,0x6f,0x61,0x6c,0x3d,2,0x61,0x3a,0x68,0x44,
-0x6e,0x17,0x6f,0x74,0x74,0x65,0x64,0x68,0x65,0x68,0x4b,1,0x66,0x47,0x70,0x10,
-0x68,0x49,0x12,0x61,0x70,0x68,0x89,0x61,0x2c,0x62,0x4c,0x64,0x86,0x65,0x31,1,
-0x69,0x38,0x6c,1,0x61,0x28,0x65,0x10,0x66,0x27,0x11,0x70,0x68,0x25,0x10,0x6e,
-0x23,1,0x65,0x4a,0x75,0x10,0x72,0x1f,0x75,0x73,0x68,0x61,0x73,0x6b,0x69,0x79,
-0x65,0x68,0x62,0x61,0x72,0x72,0x65,0x65,0x8d,1,0x68,0x29,0x74,0x10,0x68,0x2b,
-0x11,0x61,0x6c,0x2c,0x16,0x61,0x74,0x68,0x72,0x69,0x73,0x68,0x2f,7,0x6e,0x2e,
-0x6e,0x2c,0x72,0x3e,0x74,0x56,0x75,0x21,0x18,0x6f,0x6e,0x6a,0x6f,0x69,0x6e,0x69,
-0x6e,0x67,0x21,0x28,0x1a,0x69,0x67,0x68,0x74,0x6a,0x6f,0x69,0x6e,0x69,0x6e,0x67,
-0x29,0x2a,0x19,0x72,0x61,0x6e,0x73,0x70,0x61,0x72,0x65,0x6e,0x74,0x2b,0x63,0x23,
-0x64,0x40,0x6a,0x56,0x6c,0x26,0x19,0x65,0x66,0x74,0x6a,0x6f,0x69,0x6e,0x69,0x6e,
-0x67,0x27,0x24,0x19,0x75,0x61,0x6c,0x6a,0x6f,0x69,0x6e,0x69,0x6e,0x67,0x25,0x19,
-0x6f,0x69,0x6e,0x63,0x61,0x75,0x73,0x69,0x6e,0x67,0x23,0,0x13,0x6e,0xc0,0xcd,
-0x73,0x46,0x73,0x42,0x75,0x72,0x77,0x7e,0x78,0x96,0x7a,0x10,0x77,0x58,0x14,0x73,
-0x70,0x61,0x63,0x65,0x59,4,0x61,0x51,0x67,0x53,0x70,0x28,0x75,0x30,0x79,0x57,
-0x54,0x12,0x61,0x63,0x65,0x55,0x16,0x72,0x72,0x6f,0x67,0x61,0x74,0x65,0x53,0x15,
-0x6e,0x6b,0x6e,0x6f,0x77,0x6e,0x21,1,0x6a,0x5d,0x6f,0x17,0x72,0x64,0x6a,0x6f,
-0x69,0x6e,0x65,0x72,0x5d,0x10,0x78,0x21,0x6e,0x60,0x6f,0xa2,0x41,0x70,0xa2,0x50,
-0x71,0xa2,0x6e,0x72,1,0x65,0x24,0x69,0x6f,0x1e,0x67,0x69,0x6f,0x6e,0x61,0x6c,
-0x69,0x6e,0x64,0x69,0x63,0x61,0x74,0x6f,0x72,0x6f,4,0x65,0x3e,0x6c,0x5b,0x6f,
-0x46,0x73,0x45,0x75,0x46,0x14,0x6d,0x65,0x72,0x69,0x63,0x47,0x15,0x78,0x74,0x6c,
-0x69,0x6e,0x65,0x5b,0x17,0x6e,0x73,0x74,0x61,0x72,0x74,0x65,0x72,0x45,0x10,0x70,
-0x48,0x1c,0x65,0x6e,0x70,0x75,0x6e,0x63,0x74,0x75,0x61,0x74,0x69,0x6f,0x6e,0x49,
-1,0x6f,0x3e,0x72,0x4c,0x1a,0x65,0x66,0x69,0x78,0x6e,0x75,0x6d,0x65,0x72,0x69,
-0x63,0x4d,0x4a,0x1b,0x73,0x74,0x66,0x69,0x78,0x6e,0x75,0x6d,0x65,0x72,0x69,0x63,
-0x4b,0x10,0x75,0x4e,0x16,0x6f,0x74,0x61,0x74,0x69,0x6f,0x6e,0x4f,0x68,0x7b,0x68,
-0x50,0x69,0x86,0x6a,0xa2,0x61,0x6c,0xa2,0x65,0x6d,0x1c,0x61,0x6e,0x64,0x61,0x74,
-0x6f,0x72,0x79,0x62,0x72,0x65,0x61,0x6b,0x2d,4,0x32,0x5f,0x33,0x61,0x65,0x34,
-0x6c,0x6d,0x79,0x3a,0x13,0x70,0x68,0x65,0x6e,0x3b,0x19,0x62,0x72,0x65,0x77,0x6c,
-0x65,0x74,0x74,0x65,0x72,0x6d,2,0x64,0x28,0x6e,0x3c,0x73,0x41,0x3c,0x18,0x65,
-0x6f,0x67,0x72,0x61,0x70,0x68,0x69,0x63,0x3d,0x3e,1,0x66,0x3e,0x73,0x11,0x65,
-0x70,1,0x61,0x22,0x65,0x14,0x72,0x61,0x62,0x6c,0x65,0x3f,0x18,0x69,0x78,0x6e,
-0x75,0x6d,0x65,0x72,0x69,0x63,0x41,2,0x6c,0x63,0x74,0x65,0x76,0x67,1,0x66,
-0x43,0x69,0x15,0x6e,0x65,0x66,0x65,0x65,0x64,0x43,0x61,0x40,0x62,0x70,0x63,0xa2,
-0x55,0x65,0xa2,0xdb,0x67,0x10,0x6c,0x38,0x11,0x75,0x65,0x39,2,0x69,0x23,0x6c,
-0x34,0x6d,0x16,0x62,0x69,0x67,0x75,0x6f,0x75,0x73,0x23,0x24,0x17,0x70,0x68,0x61,
-0x62,0x65,0x74,0x69,0x63,0x25,4,0x32,0x27,0x61,0x29,0x62,0x2b,0x6b,0x2d,0x72,
-0x12,0x65,0x61,0x6b,2,0x61,0x36,0x62,0x3e,0x73,0x15,0x79,0x6d,0x62,0x6f,0x6c,
-0x73,0x57,0x13,0x66,0x74,0x65,0x72,0x29,1,0x65,0x2a,0x6f,0x11,0x74,0x68,0x27,
-0x13,0x66,0x6f,0x72,0x65,0x2b,7,0x6d,0x51,0x6d,0x33,0x6f,0x28,0x70,0x69,0x72,
-0x35,1,0x6d,0x76,0x6e,1,0x64,0x3c,0x74,0x1a,0x69,0x6e,0x67,0x65,0x6e,0x74,
-0x62,0x72,0x65,0x61,0x6b,0x2f,0x15,0x69,0x74,0x69,0x6f,0x6e,0x61,0x1f,0x6c,0x6a,
-0x61,0x70,0x61,0x6e,0x65,0x73,0x65,0x73,0x74,0x61,0x72,0x74,0x65,0x72,0x6b,1,
-0x62,0x3a,0x70,0x19,0x6c,0x65,0x78,0x63,0x6f,0x6e,0x74,0x65,0x78,0x74,0x51,0x18,
-0x69,0x6e,0x69,0x6e,0x67,0x6d,0x61,0x72,0x6b,0x33,0x61,0x6a,0x62,0x2f,0x6a,0x6b,
-0x6c,0x30,0x13,0x6f,0x73,0x65,0x70,1,0x61,0x38,0x75,0x18,0x6e,0x63,0x74,0x75,
-0x61,0x74,0x69,0x6f,0x6e,0x31,0x18,0x72,0x65,0x6e,0x74,0x68,0x65,0x73,0x69,0x73,
-0x69,0x1b,0x72,0x72,0x69,0x61,0x67,0x65,0x72,0x65,0x74,0x75,0x72,0x6e,0x35,0x10,
-0x78,0x36,0x18,0x63,0x6c,0x61,0x6d,0x61,0x74,0x69,0x6f,0x6e,0x37,1,0x64,0x42,
-0x6e,1,0x6f,0x32,0x75,0x26,0x14,0x6d,0x65,0x72,0x69,0x63,0x27,0x11,0x6e,0x65,
-0x21,1,0x65,0x2e,0x69,0x24,0x12,0x67,0x69,0x74,0x25,0x22,0x14,0x63,0x69,0x6d,
-0x61,0x6c,0x23,0,0x18,0x6e,0xc3,0x79,0x74,0xc1,0x2f,0x77,0x5d,0x77,0x80,0x78,
-0xa2,0x44,0x79,0xa2,0x4e,0x7a,5,0x78,0x13,0x78,0x30,0x79,0x36,0x7a,0x11,0x7a,
-0x7a,0xa3,0x67,0x11,0x78,0x78,0xa3,0x66,0x11,0x79,0x79,0x21,0x69,0x30,0x6d,0x34,
-0x73,0x11,0x79,0x6d,0xa3,0x81,0x11,0x6e,0x68,0x23,0x11,0x74,0x68,0xa3,0x80,1,
-0x61,0x2c,0x6f,0x11,0x6c,0x65,0xa3,0x9b,0x11,0x72,0x61,0xa2,0x92,0x15,0x6e,0x67,
-0x63,0x69,0x74,0x69,0xa3,0x92,1,0x70,0x2c,0x73,0x11,0x75,0x78,0xa3,0x65,0x11,
-0x65,0x6f,0x9b,0x10,0x69,0x72,0x11,0x69,0x69,0x73,0x74,0x4a,0x75,0xa2,0xb5,0x76,
-1,0x61,0x2c,0x69,0x11,0x73,0x70,0xa3,0x64,0x10,0x69,0xa2,0x63,0x10,0x69,0xa3,
-0x63,5,0x67,0x36,0x67,0x68,0x68,0x6c,0x69,2,0x62,0x3a,0x66,0x4a,0x72,0x10,
-0x68,0xa2,0x9e,0x12,0x75,0x74,0x61,0xa3,0x9e,1,0x65,0x24,0x74,0x6f,0x12,0x74,
-0x61,0x6e,0x6f,0x14,0x69,0x6e,0x61,0x67,0x68,0x99,0x11,0x6c,0x67,0x75,0x10,0x61,
-1,0x61,0x24,0x69,0x6d,0x6a,0x11,0x6e,0x61,0x6b,0x61,0x30,0x65,0xa2,0x56,0x66,
-0x11,0x6e,0x67,0x99,6,0x6c,0x1c,0x6c,0x32,0x6d,0x38,0x6e,0x44,0x76,0x10,0x74,
-0xa3,0x7f,1,0x65,0x89,0x75,0x97,1,0x69,0x24,0x6c,0x67,0x10,0x6c,0x67,0x10,
-0x67,0xa3,0x9a,0x67,0x36,0x69,0x52,0x6b,0x10,0x72,0xa2,0x99,0x10,0x69,0xa3,0x99,
-1,0x61,0x30,0x62,0x7a,0x13,0x61,0x6e,0x77,0x61,0x7b,0x12,0x6c,0x6f,0x67,0x75,
-2,0x6c,0x32,0x74,0x34,0x76,0x12,0x69,0x65,0x74,0xa3,0x7f,0x10,0x65,0x89,0x12,
-0x68,0x61,0x6d,0xa3,0x6a,1,0x6c,0x2a,0x6e,0x10,0x67,0xa3,0x62,0x10,0x75,0x68,
-0x11,0x67,0x75,0x69,1,0x67,0x32,0x6e,0x14,0x6b,0x6e,0x6f,0x77,0x6e,0xa3,0x67,
-0x11,0x61,0x72,0x8a,0x13,0x69,0x74,0x69,0x63,0x8b,0x71,0xc0,0xef,0x71,0xa2,0xc1,
-0x72,0xa2,0xc6,0x73,6,0x69,0x6d,0x69,0x72,0x6f,0xa2,0x4c,0x75,0xa2,0x58,0x79,
-1,0x6c,0x46,0x72,4,0x63,0x65,0x65,0xa3,0x5f,0x69,0x2c,0x6a,0xa3,0x60,0x6e,
-0xa3,0x61,0x11,0x61,0x63,0x65,0x10,0x6f,0x94,0x16,0x74,0x69,0x6e,0x61,0x67,0x72,
-0x69,0x95,2,0x64,0x3c,0x67,0x4c,0x6e,1,0x64,0xa3,0x91,0x68,0x62,0x12,0x61,
-0x6c,0x61,0x63,0x10,0x64,0xa2,0xa6,0x12,0x68,0x61,0x6d,0xa3,0xa6,0x17,0x6e,0x77,
-0x72,0x69,0x74,0x69,0x6e,0x67,0xa3,0x70,0x11,0x72,0x61,0xa2,0x98,0x16,0x73,0x6f,
-0x6d,0x70,0x65,0x6e,0x67,0xa3,0x98,0x11,0x6e,0x64,0xa2,0x71,0x14,0x61,0x6e,0x65,
-0x73,0x65,0xa3,0x71,0x61,0x5c,0x67,0xa2,0x43,0x68,1,0x61,0x2a,0x72,0x10,0x64,
-0xa3,0x97,2,0x72,0x28,0x76,0x30,0x77,0x87,0x12,0x61,0x64,0x61,0xa3,0x97,0x12,
-0x69,0x61,0x6e,0x87,2,0x6d,0x40,0x72,0x58,0x75,0x10,0x72,0xa2,0x6f,0x15,0x61,
-0x73,0x68,0x74,0x72,0x61,0xa3,0x6f,1,0x61,0x26,0x72,0xa3,0x7e,0x14,0x72,0x69,
-0x74,0x61,0x6e,0xa3,0x7e,1,0x61,0xa3,0x5e,0x62,0xa3,0x85,0x11,0x6e,0x77,0xa3,
-0x70,0x11,0x61,0x61,1,0x63,0x2f,0x69,0x23,3,0x65,0x3e,0x6a,0x48,0x6f,0x4e,
-0x75,0x10,0x6e,1,0x69,0x24,0x72,0x61,0x10,0x63,0x61,0x13,0x6a,0x61,0x6e,0x67,
-0xa3,0x6e,0x11,0x6e,0x67,0xa3,0x6e,0x11,0x72,0x6f,0xa3,0x5d,0x6e,0xa2,0x83,0x6f,
-0xa2,0xbc,0x70,5,0x6c,0x1e,0x6c,0x44,0x72,0x4a,0x73,0x1b,0x61,0x6c,0x74,0x65,
-0x72,0x70,0x61,0x68,0x6c,0x61,0x76,0x69,0xa3,0x7b,0x11,0x72,0x64,0xa3,0x5c,0x11,
-0x74,0x69,0xa3,0x7d,0x61,0x7c,0x65,0xa2,0x54,0x68,3,0x61,0x3e,0x6c,0x4e,0x6e,
-0x5e,0x6f,0x16,0x65,0x6e,0x69,0x63,0x69,0x61,0x6e,0xa3,0x5b,0x10,0x67,0xa2,0x5a,
-0x12,0x73,0x70,0x61,0xa3,0x5a,2,0x69,0xa3,0x7a,0x70,0xa3,0x7b,0x76,0xa3,0x7c,
-0x10,0x78,0xa3,0x5b,2,0x68,0x3e,0x6c,0x50,0x75,0x10,0x63,0xa2,0xa5,0x14,0x69,
-0x6e,0x68,0x61,0x75,0xa3,0xa5,0x17,0x61,0x77,0x68,0x68,0x6d,0x6f,0x6e,0x67,0xa3,
-0x4b,0x10,0x6d,0xa2,0x90,0x14,0x79,0x72,0x65,0x6e,0x65,0xa3,0x90,0x11,0x72,0x6d,
-0xa3,0x59,4,0x61,0x38,0x62,0x56,0x65,0x5c,0x6b,0x6a,0x73,0x11,0x68,0x75,0xa3,
-0x96,1,0x62,0x2a,0x72,0x10,0x62,0xa3,0x8e,0x15,0x61,0x74,0x61,0x65,0x61,0x6e,
-0xa3,0x8f,0x11,0x61,0x74,0xa3,0x8f,0x16,0x77,0x74,0x61,0x69,0x6c,0x75,0x65,0x97,
-1,0x67,0x2e,0x6f,0xa2,0x57,0x10,0x6f,0xa3,0x57,0x10,0x62,0xa3,0x84,3,0x67,
-0x3e,0x6c,0x50,0x72,0xa2,0x7a,0x73,0x11,0x6d,0x61,0x84,0x12,0x6e,0x79,0x61,0x85,
-1,0x61,0x2a,0x68,0x11,0x61,0x6d,0x5b,0x10,0x6d,0x5b,1,0x63,0xa2,0x55,0x64,
-5,0x70,0x2c,0x70,0x36,0x73,0x54,0x74,0x14,0x75,0x72,0x6b,0x69,0x63,0xa3,0x58,
-0x11,0x65,0x72,1,0x6d,0x2c,0x73,0x12,0x69,0x61,0x6e,0x9b,0x11,0x69,0x63,0xa3,
-0x59,0x1a,0x6f,0x75,0x74,0x68,0x61,0x72,0x61,0x62,0x69,0x61,0x6e,0xa3,0x85,0x68,
+0x65,0x75,0x74,0x72,0x61,0x6c,0x45,0,0x16,0x6d,0xc8,0xc8,0x74,0xc1,0xee,0x77,
+0x6a,0x77,0x48,0x79,0x70,0x7a,0x1d,0x61,0x6e,0x61,0x62,0x61,0x7a,0x61,0x72,0x73,
+0x71,0x75,0x61,0x72,0x65,0xa5,0x18,0x10,0x61,1,0x6e,0x36,0x72,0x16,0x61,0x6e,
+0x67,0x63,0x69,0x74,0x69,0xa3,0xfc,0x12,0x63,0x68,0x6f,0xa5,0x2c,1,0x65,0x88,
+0x69,2,0x6a,0x3c,0x72,0x68,0x73,0x17,0x79,0x6c,0x6c,0x61,0x62,0x6c,0x65,0x73,
+0xa3,0x48,0x12,0x69,0x6e,0x67,0xa2,0x74,0x1e,0x68,0x65,0x78,0x61,0x67,0x72,0x61,
+0x6d,0x73,0x79,0x6d,0x62,0x6f,0x6c,0x73,0xa3,0x74,0x16,0x61,0x64,0x69,0x63,0x61,
+0x6c,0x73,0xa3,0x49,0x13,0x7a,0x69,0x64,0x69,0xa5,0x34,0x74,0xa2,0x59,0x75,0xa4,
+0x35,0x76,2,0x61,0x36,0x65,0x7a,0x73,0xa2,0x6c,0x12,0x73,0x75,0x70,0xa3,0x7d,
+1,0x69,0xa3,0x9f,0x72,0x1e,0x69,0x61,0x74,0x69,0x6f,0x6e,0x73,0x65,0x6c,0x65,
+0x63,0x74,0x6f,0x72,0x73,0xa2,0x6c,0x19,0x73,0x75,0x70,0x70,0x6c,0x65,0x6d,0x65,
+0x6e,0x74,0xa3,0x7d,1,0x64,0x3c,0x72,0x19,0x74,0x69,0x63,0x61,0x6c,0x66,0x6f,
+0x72,0x6d,0x73,0xa3,0x91,0x14,0x69,0x63,0x65,0x78,0x74,0xa2,0xaf,0x16,0x65,0x6e,
+0x73,0x69,0x6f,0x6e,0x73,0xa3,0xaf,4,0x61,0x68,0x65,0xa2,0xad,0x68,0xa2,0xb0,
+0x69,0xa2,0xb8,0x72,0x1c,0x61,0x6e,0x73,0x70,0x6f,0x72,0x74,0x61,0x6e,0x64,0x6d,
+0x61,0x70,0xa2,0xcf,0x16,0x73,0x79,0x6d,0x62,0x6f,0x6c,0x73,0xa3,0xcf,4,0x67,
+0x7e,0x69,0xa2,0x41,0x6b,0xa2,0x6a,0x6d,0xa2,0x6c,0x6e,0x12,0x67,0x75,0x74,0xa4,
+0x10,1,0x63,0x40,0x73,0x11,0x75,0x70,0xa4,0x33,0x16,0x70,0x6c,0x65,0x6d,0x65,
+0x6e,0x74,0xa5,0x33,0x18,0x6f,0x6d,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x73,0xa5,0x11,
+2,0x61,0x2a,0x62,0x32,0x73,0xa3,0x60,0x12,0x6c,0x6f,0x67,0xa3,0x62,0x13,0x61,
+0x6e,0x77,0x61,0xa3,0x65,3,0x6c,0x52,0x74,0x56,0x76,0x5e,0x78,0x16,0x75,0x61,
+0x6e,0x6a,0x69,0x6e,0x67,0xa2,0x7c,0x16,0x73,0x79,0x6d,0x62,0x6f,0x6c,0x73,0xa3,
+0x7c,0x10,0x65,0xa3,0x70,0x12,0x68,0x61,0x6d,0xa3,0xae,0x12,0x69,0x65,0x74,0xa3,
+0xb7,0x11,0x72,0x69,0xa3,0xdc,0x11,0x69,0x6c,0x48,0x12,0x73,0x75,0x70,0xa4,0x2b,
+0x16,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0xa5,0x2b,0x13,0x6c,0x75,0x67,0x75,0x4b,
+0x10,0x61,1,0x61,0x24,0x69,0x53,0x11,0x6e,0x61,0x3d,2,0x62,0x34,0x66,0x3c,
+0x72,0x13,0x68,0x75,0x74,0x61,0xa3,0xfb,0x13,0x65,0x74,0x61,0x6e,0x57,0x14,0x69,
+0x6e,0x61,0x67,0x68,0xa3,0x90,2,0x63,0x82,0x67,0x92,0x6e,0x1f,0x69,0x66,0x69,
+0x65,0x64,0x63,0x61,0x6e,0x61,0x64,0x69,0x61,0x6e,0x61,0x62,0x6f,0x1f,0x72,0x69,
+0x67,0x69,0x6e,0x61,0x6c,0x73,0x79,0x6c,0x6c,0x61,0x62,0x69,0x63,0x73,0x62,0x17,
+0x65,0x78,0x74,0x65,0x6e,0x64,0x65,0x64,0xa3,0xad,0x11,0x61,0x73,0x62,0x12,0x65,
+0x78,0x74,0xa3,0xad,0x15,0x61,0x72,0x69,0x74,0x69,0x63,0xa3,0x78,0x70,0xc3,0x4b,
+0x70,0xa6,0x61,0x72,0xa8,0x1d,0x73,7,0x6f,0xc1,0xbe,0x6f,0xa2,0x69,0x70,0xa2,
+0x85,0x75,0xa2,0xa4,0x79,2,0x6c,0x50,0x6d,0x62,0x72,0x12,0x69,0x61,0x63,0x3a,
+0x12,0x73,0x75,0x70,0xa4,0x17,0x16,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0xa5,0x17,
+0x17,0x6f,0x74,0x69,0x6e,0x61,0x67,0x72,0x69,0xa3,0x8f,0x13,0x62,0x6f,0x6c,0x73,
+1,0x61,0x4c,0x66,0x10,0x6f,0x1f,0x72,0x6c,0x65,0x67,0x61,0x63,0x79,0x63,0x6f,
+0x6d,0x70,0x75,0x74,0x69,0x6e,0x67,0xa5,0x32,0x1f,0x6e,0x64,0x70,0x69,0x63,0x74,
+0x6f,0x67,0x72,0x61,0x70,0x68,0x73,0x65,0x78,0x74,1,0x61,0xa5,0x2a,0x65,0x14,
+0x6e,0x64,0x65,0x64,0x61,0xa5,0x2a,2,0x67,0x34,0x72,0x3e,0x79,0x13,0x6f,0x6d,
+0x62,0x6f,0xa5,0x16,0x13,0x64,0x69,0x61,0x6e,0xa5,0x23,0x17,0x61,0x73,0x6f,0x6d,
+0x70,0x65,0x6e,0x67,0xa3,0xda,1,0x61,0x32,0x65,0x14,0x63,0x69,0x61,0x6c,0x73,
+0xa3,0x56,0x12,0x63,0x69,0x6e,0x1f,0x67,0x6d,0x6f,0x64,0x69,0x66,0x69,0x65,0x72,
+0x6c,0x65,0x74,0x74,0x65,0x72,0x73,0x2d,2,0x6e,0x48,0x70,0x76,0x74,0x1d,0x74,
+0x6f,0x6e,0x73,0x69,0x67,0x6e,0x77,0x72,0x69,0x74,0x69,0x6e,0x67,0xa5,6,0x15,
+0x64,0x61,0x6e,0x65,0x73,0x65,0xa2,0x9b,0x12,0x73,0x75,0x70,0xa2,0xdb,0x16,0x70,
+0x6c,0x65,0x6d,0x65,0x6e,0x74,0xa3,0xdb,4,0x61,0xa2,0xa8,0x65,0x5c,0x6d,0x9e,
+0x70,0xa2,0x4b,0x73,0x13,0x79,0x6d,0x62,0x6f,0x1f,0x6c,0x73,0x61,0x6e,0x64,0x70,
+0x69,0x63,0x74,0x6f,0x67,0x72,0x61,0x70,0x68,0x73,0xa5,5,0x10,0x72,1,0x61,
+0x4e,0x73,0x12,0x63,0x72,0x69,0x1f,0x70,0x74,0x73,0x61,0x6e,0x64,0x73,0x75,0x62,
+0x73,0x63,0x72,0x69,0x70,0x74,0x73,0x73,0x14,0x6e,0x64,0x73,0x75,0x62,0x73,0x1b,
+0x61,0x74,0x68,0x6f,0x70,0x65,0x72,0x61,0x74,0x6f,0x72,0x73,0xa3,0x6a,1,0x6c,
+0x40,0x75,1,0x61,0x6e,0x6e,0x17,0x63,0x74,0x75,0x61,0x74,0x69,0x6f,0x6e,0xa3,
+0x8e,0x15,0x65,0x6d,0x65,0x6e,0x74,0x61,1,0x6c,0x50,0x72,0x1e,0x79,0x70,0x72,
+0x69,0x76,0x61,0x74,0x65,0x75,0x73,0x65,0x61,0x72,0x65,0x61,1,0x61,0xa3,0x6d,
+0x62,0xa3,0x6e,3,0x61,0x5c,0x6d,0x78,0x70,0xa2,0x41,0x73,0x13,0x79,0x6d,0x62,
+0x6f,0x1f,0x6c,0x73,0x61,0x6e,0x64,0x70,0x69,0x63,0x74,0x6f,0x67,0x72,0x61,0x70,
+0x68,0x73,0xa5,5,0x14,0x72,0x72,0x6f,0x77,0x73,2,0x61,0xa3,0x67,0x62,0xa3,
+0x68,0x63,0xa3,0xfa,0x13,0x61,0x74,0x68,0x65,0x1f,0x6d,0x61,0x74,0x69,0x63,0x61,
+0x6c,0x6f,0x70,0x65,0x72,0x61,0x74,0x6f,0x72,0x73,0xa3,0x6a,0x19,0x75,0x6e,0x63,
+0x74,0x75,0x61,0x74,0x69,0x6f,0x6e,0xa3,0x8e,0x61,0x88,0x68,0xa2,0x48,0x69,0xa2,
+0x71,0x6d,0x12,0x61,0x6c,0x6c,1,0x66,0x46,0x6b,0x15,0x61,0x6e,0x61,0x65,0x78,
+0x74,0xa4,0x29,0x15,0x65,0x6e,0x73,0x69,0x6f,0x6e,0xa5,0x29,0x12,0x6f,0x72,0x6d,
+1,0x73,0xa3,0x54,0x76,0x16,0x61,0x72,0x69,0x61,0x6e,0x74,0x73,0xa3,0x54,1,
+0x6d,0x36,0x75,0x16,0x72,0x61,0x73,0x68,0x74,0x72,0x61,0xa3,0xa1,0x15,0x61,0x72,
+0x69,0x74,0x61,0x6e,0xa3,0xac,1,0x61,0x52,0x6f,0x13,0x72,0x74,0x68,0x61,0x1f,
+0x6e,0x64,0x66,0x6f,0x72,0x6d,0x61,0x74,0x63,0x6f,0x6e,0x74,0x72,0x6f,0x6c,0x73,
+0xa3,0xf7,1,0x72,0x2e,0x76,0x12,0x69,0x61,0x6e,0xa3,0x79,0x12,0x61,0x64,0x61,
+0xa3,0xd9,1,0x64,0x50,0x6e,0x13,0x68,0x61,0x6c,0x61,0x50,0x1d,0x61,0x72,0x63,
+0x68,0x61,0x69,0x63,0x6e,0x75,0x6d,0x62,0x65,0x72,0x73,0xa3,0xf9,0x13,0x64,0x68,
+0x61,0x6d,0xa3,0xf8,5,0x72,0x35,0x72,0x44,0x73,0x64,0x75,1,0x61,0xa3,0x4e,
+0x6e,0x17,0x63,0x74,0x75,0x61,0x74,0x69,0x6f,0x6e,0x71,0x17,0x69,0x76,0x61,0x74,
+0x65,0x75,0x73,0x65,0xa2,0x4e,0x13,0x61,0x72,0x65,0x61,0xa3,0x4e,0x1b,0x61,0x6c,
+0x74,0x65,0x72,0x70,0x61,0x68,0x6c,0x61,0x76,0x69,0xa3,0xf6,0x61,0x40,0x68,0x82,
+0x6c,0x19,0x61,0x79,0x69,0x6e,0x67,0x63,0x61,0x72,0x64,0x73,0xa3,0xcc,2,0x68,
+0x38,0x6c,0x4a,0x75,0x15,0x63,0x69,0x6e,0x68,0x61,0x75,0xa3,0xf5,0x17,0x61,0x77,
+0x68,0x68,0x6d,0x6f,0x6e,0x67,0xa3,0xf3,0x15,0x6d,0x79,0x72,0x65,0x6e,0x65,0xa3,
+0xf4,1,0x61,0x8e,0x6f,1,0x65,0x74,0x6e,0x16,0x65,0x74,0x69,0x63,0x65,0x78,
+0x74,0xa2,0x72,1,0x65,0x2c,0x73,0x11,0x75,0x70,0xa3,0x8d,0x15,0x6e,0x73,0x69,
+0x6f,0x6e,0x73,0xa2,0x72,0x19,0x73,0x75,0x70,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,
+0xa3,0x8d,0x15,0x6e,0x69,0x63,0x69,0x61,0x6e,0xa3,0x97,1,0x67,0x3e,0x69,0x13,
+0x73,0x74,0x6f,0x73,0xa2,0xa6,0x13,0x64,0x69,0x73,0x63,0xa3,0xa6,0x12,0x73,0x70,
+0x61,0xa3,0x96,1,0x65,0x5c,0x75,1,0x6d,0x2a,0x6e,0x11,0x69,0x63,0x67,0x10,
+0x69,0xa2,0xc0,0x1d,0x6e,0x75,0x6d,0x65,0x72,0x61,0x6c,0x73,0x79,0x6d,0x62,0x6f,
+0x6c,0x73,0xa3,0xc0,0x13,0x6a,0x61,0x6e,0x67,0xa3,0xa3,0x6d,0xa2,0xe6,0x6e,0xa8,
+0x19,0x6f,6,0x70,0x63,0x70,0x56,0x72,0x8a,0x73,0xa2,0x4c,0x74,0x10,0x74,0x1f,
+0x6f,0x6d,0x61,0x6e,0x73,0x69,0x79,0x61,0x71,0x6e,0x75,0x6d,0x62,0x65,0x72,0x73,
+0xa5,0x28,0x18,0x74,0x69,0x63,0x61,0x6c,0x63,0x68,0x61,0x72,0x1f,0x61,0x63,0x74,
+0x65,0x72,0x72,0x65,0x63,0x6f,0x67,0x6e,0x69,0x74,0x69,0x6f,0x6e,0x85,1,0x69,
+0x46,0x6e,0x1e,0x61,0x6d,0x65,0x6e,0x74,0x61,0x6c,0x64,0x69,0x6e,0x67,0x62,0x61,
+0x74,0x73,0xa3,0xf2,0x11,0x79,0x61,0x47,1,0x61,0x30,0x6d,0x13,0x61,0x6e,0x79,
+0x61,0xa3,0x7a,0x11,0x67,0x65,0xa5,0xf,0x63,0xa2,0x71,0x67,0xa2,0x71,0x6c,1,
+0x63,0xa2,0x62,0x64,5,0x70,0x38,0x70,0x36,0x73,0x56,0x74,0x14,0x75,0x72,0x6b,
+0x69,0x63,0xa3,0xbf,0x11,0x65,0x72,1,0x6d,0x2e,0x73,0x12,0x69,0x61,0x6e,0xa3,
+0x8c,0x11,0x69,0x63,0xa3,0xf1,0x10,0x6f,1,0x67,0x3a,0x75,0x18,0x74,0x68,0x61,
+0x72,0x61,0x62,0x69,0x61,0x6e,0xa3,0xbb,0x13,0x64,0x69,0x61,0x6e,0xa5,0x22,0x68,
 0x42,0x69,0x54,0x6e,0x1a,0x6f,0x72,0x74,0x68,0x61,0x72,0x61,0x62,0x69,0x61,0x6e,
-0xa3,0x8e,0x17,0x75,0x6e,0x67,0x61,0x72,0x69,0x61,0x6e,0xa3,0x4c,0x14,0x74,0x61,
-0x6c,0x69,0x63,0x5d,1,0x68,0x26,0x6b,0xa3,0x6d,0x12,0x69,0x6b,0x69,0xa3,0x6d,
-2,0x69,0x2c,0x6b,0x30,0x79,0x10,0x61,0x5f,0x11,0x79,0x61,0x5f,0x10,0x68,0xa3,
-0x58,0x68,0xc2,0x9c,0x6b,0xc1,0xcf,0x6b,0xa2,0xdc,0x6c,0xa4,0x5d,0x6d,8,0x6f,
-0x46,0x6f,0x48,0x72,0x74,0x74,0x80,0x75,0x86,0x79,1,0x61,0x28,0x6d,0x10,0x72,
-0x59,0x13,0x6e,0x6d,0x61,0x72,0x59,2,0x64,0x2e,0x6e,0x32,0x6f,0x10,0x6e,0xa3,
-0x72,0x10,0x69,0xa3,0xa3,0x10,0x67,0x56,0x14,0x6f,0x6c,0x69,0x61,0x6e,0x57,0x10,
-0x6f,0xa2,0x95,0x10,0x6f,0xa3,0x95,0x11,0x65,0x69,0xa3,0x73,0x11,0x6c,0x74,0xa2,
-0xa4,0x12,0x61,0x6e,0x69,0xa3,0xa4,0x61,0x34,0x65,0xa0,0x69,0xa2,0x83,0x6c,0x11,
-0x79,0x6d,0x55,3,0x68,0x32,0x6c,0x48,0x6e,0x54,0x79,0x10,0x61,0xa3,0x55,1,
-0x61,0x26,0x6a,0xa3,0xa0,0x13,0x6a,0x61,0x6e,0x69,0xa3,0xa0,0x15,0x61,0x79,0x61,
-0x6c,0x61,0x6d,0x55,1,0x64,0x38,0x69,0xa2,0x79,0x15,0x63,0x68,0x61,0x65,0x61,
-0x6e,0xa3,0x79,0xa2,0x54,0x12,0x61,0x69,0x63,0xa3,0x54,2,0x65,0x72,0x6e,0x84,
-0x72,1,0x63,0xa3,0x8d,0x6f,0xa2,0x56,0x13,0x69,0x74,0x69,0x63,1,0x63,0x3c,
-0x68,0x19,0x69,0x65,0x72,0x6f,0x67,0x6c,0x79,0x70,0x68,0x73,0xa3,0x56,0x15,0x75,
-0x72,0x73,0x69,0x76,0x65,0xa3,0x8d,0x17,0x74,0x65,0x69,0x6d,0x61,0x79,0x65,0x6b,
-0xa3,0x73,0x10,0x64,0xa2,0x8c,0x17,0x65,0x6b,0x69,0x6b,0x61,0x6b,0x75,0x69,0xa3,
-0x8c,0x11,0x61,0x6f,0xa3,0x5c,5,0x6f,0x14,0x6f,0x30,0x70,0x36,0x74,0x11,0x68,
-0x69,0xa3,0x78,0x11,0x72,0x65,0xa3,0x77,0x11,0x65,0x6c,0xa3,0x8a,0x61,0x2e,0x68,
-0x98,0x6e,0x11,0x64,0x61,0x4b,4,0x69,0x3c,0x6c,0x44,0x6e,0x48,0x74,0x56,0x79,
-0x13,0x61,0x68,0x6c,0x69,0xa3,0x4f,0x12,0x74,0x68,0x69,0xa3,0x78,0x10,0x69,0xa3,
-0x4f,1,0x61,0x4d,0x6e,0x12,0x61,0x64,0x61,0x4b,0x14,0x61,0x6b,0x61,0x6e,0x61,
-0x4c,0x19,0x6f,0x72,0x68,0x69,0x72,0x61,0x67,0x61,0x6e,0x61,0x8d,3,0x61,0x3c,
-0x6d,0x4e,0x6f,0x5a,0x75,0x15,0x64,0x61,0x77,0x61,0x64,0x69,0xa3,0x91,0x10,0x72,
-0x92,0x15,0x6f,0x73,0x68,0x74,0x68,0x69,0x93,1,0x65,0x24,0x72,0x4f,0x10,0x72,
-0x4f,0x10,0x6a,0xa2,0x9d,0x11,0x6b,0x69,0xa3,0x9d,4,0x61,0x5c,0x65,0x90,0x69,
-0xa0,0x6f,0xa2,0x5d,0x79,1,0x63,0x34,0x64,0x10,0x69,0xa2,0x6c,0x11,0x61,0x6e,
-0xa3,0x6c,0x10,0x69,0xa2,0x6b,0x11,0x61,0x6e,0xa3,0x6b,2,0x6e,0x42,0x6f,0x46,
-0x74,3,0x66,0xa3,0x50,0x67,0xa3,0x51,0x69,0x24,0x6e,0x53,0x10,0x6e,0x53,0x10,
-0x61,0xa3,0x6a,0x50,0x10,0x6f,0x51,0x11,0x70,0x63,0xa2,0x52,0x11,0x68,0x61,0xa3,
-0x52,2,0x6d,0x2e,0x6e,0x36,0x73,0x10,0x75,0xa3,0x83,0x10,0x62,0x80,0x10,0x75,
-0x81,2,0x61,0xa3,0x53,0x62,0x83,0x65,0x11,0x61,0x72,1,0x61,0xa3,0x53,0x62,
-0x83,0x11,0x6d,0x61,0xa3,0x8b,0x68,0x60,0x69,0xa2,0x79,0x6a,2,0x61,0x30,0x70,
-0x44,0x75,0x11,0x72,0x63,0xa3,0x94,0x11,0x76,0x61,0xa2,0x4e,0x13,0x6e,0x65,0x73,
-0x65,0xa3,0x4e,0x11,0x61,0x6e,0xa3,0x69,6,0x6c,0x1a,0x6c,0x34,0x6d,0x3a,0x72,
-0x40,0x75,0x11,0x6e,0x67,0xa3,0x4c,0x11,0x75,0x77,0xa3,0x9c,0x11,0x6e,0x67,0xa3,
-0x4b,0x11,0x6b,0x74,0x8d,0x61,0x3a,0x65,0x86,0x69,0x11,0x72,0x61,0x48,0x13,0x67,
-0x61,0x6e,0x61,0x49,1,0x6e,0x34,0x74,0x10,0x72,0xa2,0xa2,0x11,0x61,0x6e,0xa3,
-0xa2,0x42,5,0x73,0xc,0x73,0xa3,0x49,0x74,0xa3,0x4a,0x75,0x12,0x6e,0x6f,0x6f,
-0x77,0x67,0x28,0x69,0x43,0x6f,0x77,0x44,0x11,0x75,0x6c,0x45,0x11,0x62,0x72,0x46,
-0x11,0x65,0x77,0x47,2,0x6d,0x2e,0x6e,0x4a,0x74,0x11,0x61,0x6c,0x5d,0x1c,0x70,
-0x65,0x72,0x69,0x61,0x6c,0x61,0x72,0x61,0x6d,0x61,0x69,0x63,0xa3,0x74,2,0x64,
-0x66,0x68,0x6a,0x73,0x1b,0x63,0x72,0x69,0x70,0x74,0x69,0x6f,0x6e,0x61,0x6c,0x70,
-0x61,1,0x68,0x32,0x72,0x14,0x74,0x68,0x69,0x61,0x6e,0xa3,0x7d,0x13,0x6c,0x61,
-0x76,0x69,0xa3,0x7a,0x10,0x73,0xa3,0x4d,0x15,0x65,0x72,0x69,0x74,0x65,0x64,0x23,
-0x64,0xc0,0xc7,0x64,0xa2,0x60,0x65,0xa2,0x88,0x67,4,0x65,0x62,0x6c,0x7a,0x6f,
-0x8e,0x72,0x9a,0x75,1,0x6a,0x38,0x72,1,0x6d,0x24,0x75,0x41,0x13,0x75,0x6b,
-0x68,0x69,0x41,1,0x61,0x24,0x72,0x3f,0x13,0x72,0x61,0x74,0x69,0x3f,0x10,0x6f,
-1,0x6b,0xa3,0x48,0x72,0x38,0x13,0x67,0x69,0x61,0x6e,0x39,0x11,0x61,0x67,0x90,
-0x15,0x6f,0x6c,0x69,0x74,0x69,0x63,0x91,0x11,0x74,0x68,0x3a,0x11,0x69,0x63,0x3b,
-1,0x61,0x32,0x65,1,0x65,0x24,0x6b,0x3d,0x10,0x6b,0x3d,0x10,0x6e,0xa2,0x89,
-0x12,0x74,0x68,0x61,0xa3,0x89,2,0x65,0x3e,0x73,0x64,0x75,0x11,0x70,0x6c,0xa2,
-0x87,0x13,0x6f,0x79,0x61,0x6e,0xa3,0x87,1,0x73,0x38,0x76,0x10,0x61,0x34,0x15,
-0x6e,0x61,0x67,0x61,0x72,0x69,0x35,0x13,0x65,0x72,0x65,0x74,0x33,0x11,0x72,0x74,
-0x33,2,0x67,0x3a,0x6c,0x72,0x74,0x11,0x68,0x69,0x36,0x13,0x6f,0x70,0x69,0x63,
-0x37,0x10,0x79,2,0x64,0xa3,0x45,0x68,0xa3,0x46,0x70,0xa2,0x47,0x1e,0x74,0x69,
-0x61,0x6e,0x68,0x69,0x65,0x72,0x6f,0x67,0x6c,0x79,0x70,0x68,0x73,0xa3,0x47,0x11,
-0x62,0x61,0xa2,0x88,0x12,0x73,0x61,0x6e,0xa3,0x88,0x61,0xa2,0xa2,0x62,0xa2,0xf9,
-0x63,6,0x6f,0x3d,0x6f,0x5a,0x70,0x76,0x75,0x7a,0x79,1,0x70,0x3e,0x72,2,
-0x69,0x2a,0x6c,0x31,0x73,0xa3,0x44,0x13,0x6c,0x6c,0x69,0x63,0x31,0x13,0x72,0x69,
-0x6f,0x74,0x7f,1,0x6d,0x30,0x70,0x10,0x74,0x2e,0x11,0x69,0x63,0x2f,0x12,0x6d,
-0x6f,0x6e,0x21,0x11,0x72,0x74,0x7f,0x16,0x6e,0x65,0x69,0x66,0x6f,0x72,0x6d,0xa3,
-0x65,0x61,0x32,0x68,0xa2,0x41,0x69,0x11,0x72,0x74,0xa3,0x43,3,0x6b,0x4c,0x6e,
-0x50,0x72,0x76,0x75,0x1d,0x63,0x61,0x73,0x69,0x61,0x6e,0x61,0x6c,0x62,0x61,0x6e,
-0x69,0x61,0x6e,0xa3,0x9f,0x10,0x6d,0xa3,0x76,1,0x61,0x24,0x73,0x71,0x1d,0x64,
-0x69,0x61,0x6e,0x61,0x62,0x6f,0x72,0x69,0x67,0x69,0x6e,0x61,0x6c,0x71,0x10,0x69,
-0xa2,0x68,0x11,0x61,0x6e,0xa3,0x68,1,0x61,0x34,0x65,0x10,0x72,0x2c,0x13,0x6f,
-0x6b,0x65,0x65,0x2d,1,0x6b,0x26,0x6d,0xa3,0x42,0x11,0x6d,0x61,0xa3,0x76,5,
-0x6e,0x43,0x6e,0x44,0x72,0x6c,0x76,1,0x65,0x2a,0x73,0x10,0x74,0xa3,0x75,0x13,
-0x73,0x74,0x61,0x6e,0xa3,0x75,0x11,0x61,0x74,0x1f,0x6f,0x6c,0x69,0x61,0x6e,0x68,
-0x69,0x65,0x72,0x6f,0x67,0x6c,0x79,0x70,0x68,0x73,0xa3,0x9c,1,0x61,0x3e,0x6d,
-2,0x65,0x2a,0x69,0xa3,0x74,0x6e,0x27,0x13,0x6e,0x69,0x61,0x6e,0x27,0x10,0x62,
-0x24,0x11,0x69,0x63,0x25,0x66,0x30,0x67,0x36,0x68,0x11,0x6f,0x6d,0xa3,0xa1,0x11,
-0x61,0x6b,0xa3,0x93,0x11,0x68,0x62,0xa3,0x9f,5,0x6f,0x36,0x6f,0x4e,0x72,0x5e,
-0x75,1,0x67,0x30,0x68,1,0x64,0x79,0x69,0x10,0x64,0x79,0x10,0x69,0x8e,0x13,
-0x6e,0x65,0x73,0x65,0x8f,0x11,0x70,0x6f,0x2a,0x13,0x6d,0x6f,0x66,0x6f,0x2b,0x10,
-0x61,1,0x68,0x2e,0x69,0x7c,0x12,0x6c,0x6c,0x65,0x7d,0xa2,0x41,0x11,0x6d,0x69,
-0xa3,0x41,0x61,0x2e,0x65,0x82,0x6c,0x11,0x69,0x73,0xa1,3,0x6c,0x3a,0x6d,0x48,
-0x73,0x54,0x74,1,0x61,0x24,0x6b,0x9f,0x10,0x6b,0x9f,0x10,0x69,0x9c,0x13,0x6e,
-0x65,0x73,0x65,0x9d,0x10,0x75,0xa2,0x82,0x10,0x6d,0xa3,0x82,0x10,0x73,0xa2,0x86,
-0x13,0x61,0x76,0x61,0x68,0xa3,0x86,0x11,0x6e,0x67,0x28,0x12,0x61,0x6c,0x69,0x29,
-3,0x6c,0x42,0x6e,0x90,0x74,0xa2,0x46,0x76,0x24,0x17,0x6f,0x77,0x65,0x6c,0x6a,
-0x61,0x6d,0x6f,0x25,0x22,1,0x65,0x54,0x76,0x28,1,0x73,0x38,0x74,0x2a,0x17,
-0x73,0x79,0x6c,0x6c,0x61,0x62,0x6c,0x65,0x2b,0x16,0x79,0x6c,0x6c,0x61,0x62,0x6c,
-0x65,0x29,0x18,0x61,0x64,0x69,0x6e,0x67,0x6a,0x61,0x6d,0x6f,0x23,1,0x61,0x21,
-0x6f,0x1a,0x74,0x61,0x70,0x70,0x6c,0x69,0x63,0x61,0x62,0x6c,0x65,0x21,0x26,0x1a,
-0x72,0x61,0x69,0x6c,0x69,0x6e,0x67,0x6a,0x61,0x6d,0x6f,0x27,1,0x6e,0x2c,0x79,
-0x22,0x11,0x65,0x73,0x23,0x20,0x10,0x6f,0x21,1,0x6e,0x2c,0x79,0x22,0x11,0x65,
-0x73,0x23,0x20,0x10,0x6f,0x21,2,0x6d,0x30,0x6e,0x3a,0x79,0x22,0x11,0x65,0x73,
-0x23,0x24,0x13,0x61,0x79,0x62,0x65,0x25,0x20,0x10,0x6f,0x21,2,0x6d,0x30,0x6e,
-0x3a,0x79,0x22,0x11,0x65,0x73,0x23,0x24,0x13,0x61,0x79,0x62,0x65,0x25,0x20,0x10,
-0x6f,0x21,9,0x72,0x31,0x72,0x34,0x73,0x5c,0x74,0x31,0x76,0x33,0x78,0x10,0x78,
-0x21,1,0x65,0x24,0x69,0x39,0x1e,0x67,0x69,0x6f,0x6e,0x61,0x6c,0x69,0x6e,0x64,
-0x69,0x63,0x61,0x74,0x6f,0x72,0x39,1,0x6d,0x35,0x70,0x18,0x61,0x63,0x69,0x6e,
-0x67,0x6d,0x61,0x72,0x6b,0x35,0x63,0x44,0x65,0x5c,0x6c,0x6a,0x6f,0x78,0x70,1,
-0x70,0x37,0x72,0x14,0x65,0x70,0x65,0x6e,0x64,0x37,2,0x6e,0x23,0x6f,0x24,0x72,
-0x25,0x14,0x6e,0x74,0x72,0x6f,0x6c,0x23,0x10,0x78,0x26,0x13,0x74,0x65,0x6e,0x64,
-0x27,0x28,1,0x66,0x2b,0x76,0x2c,0x10,0x74,0x2f,0x13,0x74,0x68,0x65,0x72,0x21,
-9,0x6e,0x4a,0x6e,0x34,0x6f,0x44,0x73,0x60,0x75,0x94,0x78,0x10,0x78,0x21,0x10,
-0x75,0x2a,0x14,0x6d,0x65,0x72,0x69,0x63,0x2b,1,0x6c,0x2c,0x74,0x12,0x68,0x65,
-0x72,0x21,0x14,0x65,0x74,0x74,0x65,0x72,0x2d,3,0x63,0x36,0x65,0x46,0x70,0x31,
-0x74,0x32,0x12,0x65,0x72,0x6d,0x33,0x3c,0x16,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,
-0x3d,0x2e,0x10,0x70,0x2f,0x10,0x70,0x34,0x12,0x70,0x65,0x72,0x35,0x61,0x46,0x63,
-0x52,0x65,0x64,0x66,0x72,0x6c,2,0x65,0x2d,0x66,0x3b,0x6f,0x28,0x12,0x77,0x65,
-0x72,0x29,0x10,0x74,0x22,0x12,0x65,0x72,0x6d,0x23,1,0x6c,0x24,0x72,0x37,0x24,
-0x12,0x6f,0x73,0x65,0x25,0x10,0x78,0x38,0x13,0x74,0x65,0x6e,0x64,0x39,0x10,0x6f,
-0x26,0x13,0x72,0x6d,0x61,0x74,0x27,0xd,0x6c,0x76,0x6f,0x36,0x6f,0x30,0x72,0x38,
-0x73,0x60,0x78,0x10,0x78,0x21,0x13,0x74,0x68,0x65,0x72,0x21,1,0x65,0x24,0x69,
-0x3b,0x1e,0x67,0x69,0x6f,0x6e,0x61,0x6c,0x69,0x6e,0x64,0x69,0x63,0x61,0x74,0x6f,
-0x72,0x3b,1,0x69,0x24,0x71,0x3f,0x18,0x6e,0x67,0x6c,0x65,0x71,0x75,0x6f,0x74,
-0x65,0x3f,0x6c,0x50,0x6d,0x56,0x6e,2,0x65,0x36,0x6c,0x39,0x75,0x2c,0x14,0x6d,
-0x65,0x72,0x69,0x63,0x2d,0x14,0x77,0x6c,0x69,0x6e,0x65,0x39,1,0x65,0x23,0x66,
-0x35,3,0x62,0x37,0x69,0x28,0x6c,0x29,0x6e,0x2b,0x10,0x64,1,0x6c,0x34,0x6e,
-0x11,0x75,0x6d,0x2a,0x12,0x6c,0x65,0x74,0x37,0x14,0x65,0x74,0x74,0x65,0x72,0x29,
-0x65,0x3d,0x65,0x40,0x66,0x5e,0x68,0x6c,0x6b,0x10,0x61,0x26,0x15,0x74,0x61,0x6b,
-0x61,0x6e,0x61,0x27,0x10,0x78,0x2e,0x13,0x74,0x65,0x6e,0x64,0x32,0x15,0x6e,0x75,
-0x6d,0x6c,0x65,0x74,0x2f,0x10,0x6f,0x24,0x13,0x72,0x6d,0x61,0x74,0x25,1,0x65,
-0x24,0x6c,0x3d,0x19,0x62,0x72,0x65,0x77,0x6c,0x65,0x74,0x74,0x65,0x72,0x3d,0x61,
-0x46,0x63,0x52,0x64,1,0x6f,0x24,0x71,0x41,0x18,0x75,0x62,0x6c,0x65,0x71,0x75,
-0x6f,0x74,0x65,0x41,0x15,0x6c,0x65,0x74,0x74,0x65,0x72,0x23,0x10,0x72,0x31,2,
-0x63,0x32,0x6e,0x3c,0x6f,0x22,0x12,0x70,0x65,0x6e,0x23,0x24,0x13,0x6c,0x6f,0x73,
-0x65,0x25,0x20,0x12,0x6f,0x6e,0x65,0x21,0xd,0x6e,0xc1,0x86,0x73,0xa8,0x73,0x4c,
-0x74,0xa2,0x76,0x75,0xa2,0x83,0x7a,0xd8,0x70,0,2,0x6c,0xd9,0x20,0,0x70,
-0xd9,0x40,0,0x73,0xc3,0,0xfe,0xf,0,0,0,7,0x6f,0x3c,0x6f,0xff,
-8,0,0,0,0x70,0x3a,0x75,0x6e,0x79,0x13,0x6d,0x62,0x6f,0x6c,0xff,0xf,
-0,0,0,0x11,0x61,0x63,1,0x65,0x34,0x69,0x15,0x6e,0x67,0x6d,0x61,0x72,
-0x6b,0xa5,0,0x18,0x73,0x65,0x70,0x61,0x72,0x61,0x74,0x6f,0x72,0xc3,0,0x16,
-0x72,0x72,0x6f,0x67,0x61,0x74,0x65,0xe1,0,0,0x63,0xff,2,0,0,0,
-0x65,0x38,0x6b,0xff,4,0,0,0,0x6d,0xff,1,0,0,0,0x16,0x70,
-0x61,0x72,0x61,0x74,0x6f,0x72,0xd9,0x70,0,0x1d,0x69,0x74,0x6c,0x65,0x63,0x61,
-0x73,0x65,0x6c,0x65,0x74,0x74,0x65,0x72,0x31,1,0x6e,0x40,0x70,0x1c,0x70,0x65,
-0x72,0x63,0x61,0x73,0x65,0x6c,0x65,0x74,0x74,0x65,0x72,0x25,0x17,0x61,0x73,0x73,
-0x69,0x67,0x6e,0x65,0x64,0x23,0x6e,0xa2,0x69,0x6f,0xa2,0x89,0x70,0xfe,0x30,0xf8,
-0,0,9,0x69,0x33,0x69,0xff,0x10,0,0,0,0x6f,0xfd,0x80,0,0,
-0x72,0x54,0x73,0xf9,0,0,0x75,0x12,0x6e,0x63,0x74,0xfe,0x30,0xf8,0,0,
-0x15,0x75,0x61,0x74,0x69,0x6f,0x6e,0xff,0x30,0xf8,0,0,0x17,0x69,0x76,0x61,
-0x74,0x65,0x75,0x73,0x65,0xdd,0,0,0x61,0x48,0x63,0xfd,0x40,0,0,0x64,
-0xe9,0,0,0x65,0xfd,0x20,0,0,0x66,0xff,0x20,0,0,0,0x1f,0x72,
-0x61,0x67,0x72,0x61,0x70,0x68,0x73,0x65,0x70,0x61,0x72,0x61,0x74,0x6f,0x72,0xd9,
-0x40,0,0xbe,0,3,0x64,0xa7,0,0x6c,0xab,0,0x6f,0x30,0x75,0x13,0x6d,
-0x62,0x65,0x72,0xbf,0,0xb2,0,0x1b,0x6e,0x73,0x70,0x61,0x63,0x69,0x6e,0x67,
-0x6d,0x61,0x72,0x6b,0xa1,1,0x70,0x92,0x74,0x12,0x68,0x65,0x72,0xe6,0x80,1,
-3,0x6c,0x40,0x6e,0x4a,0x70,0x56,0x73,0x14,0x79,0x6d,0x62,0x6f,0x6c,0xff,8,
-0,0,0,0x14,0x65,0x74,0x74,0x65,0x72,0x61,0x14,0x75,0x6d,0x62,0x65,0x72,
-0xb3,0,0x19,0x75,0x6e,0x63,0x74,0x75,0x61,0x74,0x69,0x6f,0x6e,0xfd,0x80,0,
-0,0x1c,0x65,0x6e,0x70,0x75,0x6e,0x63,0x74,0x75,0x61,0x74,0x69,0x6f,0x6e,0xf9,
-0,0,0x66,0xc0,0xc4,0x66,0xa2,0x47,0x69,0xa2,0x64,0x6c,0xa2,0x79,0x6d,0xa4,
-0xc0,4,0x61,0x6c,0x63,0xa5,0,0x65,0xa3,0x80,0x6e,0xa1,0x6f,0x15,0x64,0x69,
-0x66,0x69,0x65,0x72,1,0x6c,0x38,0x73,0x14,0x79,0x6d,0x62,0x6f,0x6c,0xff,4,
-0,0,0,0x14,0x65,0x74,0x74,0x65,0x72,0x41,1,0x72,0x3c,0x74,0x16,0x68,
-0x73,0x79,0x6d,0x62,0x6f,0x6c,0xff,1,0,0,0,0x10,0x6b,0xa5,0xc0,1,
-0x69,0x32,0x6f,0x13,0x72,0x6d,0x61,0x74,0xdb,0,0,0x1d,0x6e,0x61,0x6c,0x70,
-0x75,0x6e,0x63,0x74,0x75,0x61,0x74,0x69,0x6f,0x6e,0xff,0x20,0,0,0,0x10,
-0x6e,0x1f,0x69,0x74,0x69,0x61,0x6c,0x70,0x75,0x6e,0x63,0x74,0x75,0x61,0x74,0x69,
-0x6f,0x6e,0xff,0x10,0,0,0,0x9c,7,0x6d,0x18,0x6d,0x41,0x6f,0x28,0x74,
-0x31,0x75,0x25,0x60,0x1c,0x77,0x65,0x72,0x63,0x61,0x73,0x65,0x6c,0x65,0x74,0x74,
-0x65,0x72,0x29,0x63,0x3d,0x65,0x28,0x69,0x42,0x6c,0x29,0x13,0x74,0x74,0x65,0x72,
-0x9c,0x15,0x6e,0x75,0x6d,0x62,0x65,0x72,0xab,0,0x1a,0x6e,0x65,0x73,0x65,0x70,
-0x61,0x72,0x61,0x74,0x6f,0x72,0xd9,0x20,0,0x63,0x46,0x64,0xa2,0x96,0x65,0x1b,
-0x6e,0x63,0x6c,0x6f,0x73,0x69,0x6e,0x67,0x6d,0x61,0x72,0x6b,0xa3,0x80,0xe6,0x80,
-1,7,0x6e,0x57,0x6e,0x52,0x6f,0x5e,0x73,0xe1,0,0,0x75,0x1b,0x72,0x72,
-0x65,0x6e,0x63,0x79,0x73,0x79,0x6d,0x62,0x6f,0x6c,0xff,2,0,0,0,0x22,
-0x12,0x74,0x72,0x6c,0xd9,0x80,0,0xdc,0,0,1,0x6d,0x62,0x6e,1,0x6e,
-0x30,0x74,0x12,0x72,0x6f,0x6c,0xd9,0x80,0,0x1f,0x65,0x63,0x74,0x6f,0x72,0x70,
-0x75,0x6e,0x63,0x74,0x75,0x61,0x74,0x69,0x6f,0x6e,0xfd,0x40,0,0,0x19,0x62,
-0x69,0x6e,0x69,0x6e,0x67,0x6d,0x61,0x72,0x6b,0xa5,0xc0,0x61,0x58,0x63,0xd9,0x80,
-0,0x66,0xdb,0,0,0x6c,0x1d,0x6f,0x73,0x65,0x70,0x75,0x6e,0x63,0x74,0x75,
-0x61,0x74,0x69,0x6f,0x6e,0xfd,0x20,0,0,0x18,0x73,0x65,0x64,0x6c,0x65,0x74,
-0x74,0x65,0x72,0x3d,2,0x61,0x32,0x65,0x50,0x69,0x12,0x67,0x69,0x74,0xa7,0,
-0x1c,0x73,0x68,0x70,0x75,0x6e,0x63,0x74,0x75,0x61,0x74,0x69,0x6f,0x6e,0xe9,0,
-0,0x1a,0x63,0x69,0x6d,0x61,0x6c,0x6e,0x75,0x6d,0x62,0x65,0x72,0xa7,0
+0xa3,0xf0,0x17,0x75,0x6e,0x67,0x61,0x72,0x69,0x61,0x6e,0xa5,4,0x14,0x74,0x61,
+0x6c,0x69,0x63,0xa3,0x58,0x13,0x68,0x69,0x6b,0x69,0xa3,0x9d,0x10,0x72,0x85,0x12,
+0x68,0x61,0x6d,0x65,6,0x6f,0x86,0x6f,0x6c,0x72,0xa2,0x61,0x75,0xa2,0x62,0x79,
+0x14,0x61,0x6e,0x6d,0x61,0x72,0x58,0x12,0x65,0x78,0x74,2,0x61,0xa3,0xb6,0x62,
+0xa3,0xee,0x65,0x13,0x6e,0x64,0x65,0x64,1,0x61,0xa3,0xb6,0x62,0xa3,0xee,1,
+0x64,0x52,0x6e,0x15,0x67,0x6f,0x6c,0x69,0x61,0x6e,0x6a,0x12,0x73,0x75,0x70,0xa4,
+0xd,0x16,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0xa5,0xd,0x10,0x69,0xa2,0xec,0x13,
+0x66,0x69,0x65,0x72,1,0x6c,0x3c,0x74,0x19,0x6f,0x6e,0x65,0x6c,0x65,0x74,0x74,
+0x65,0x72,0x73,0xa3,0x8a,0x15,0x65,0x74,0x74,0x65,0x72,0x73,0x2d,0x10,0x6f,0xa3,
+0xed,1,0x6c,0x44,0x73,0x11,0x69,0x63,0xa2,0x5c,0x18,0x61,0x6c,0x73,0x79,0x6d,
+0x62,0x6f,0x6c,0x73,0xa3,0x5c,0x13,0x74,0x61,0x6e,0x69,0xa5,3,0x61,0xa2,0x9b,
+0x65,0xa4,0x4c,0x69,1,0x61,0xa2,0x8f,0x73,0x10,0x63,5,0x70,0x18,0x70,0xa2,
+0x71,0x73,0x36,0x74,0x17,0x65,0x63,0x68,0x6e,0x69,0x63,0x61,0x6c,0x81,0x15,0x79,
+0x6d,0x62,0x6f,0x6c,0x73,0x8f,0x61,0xa2,0x66,0x65,0x46,0x6d,0x19,0x61,0x74,0x68,
+0x73,0x79,0x6d,0x62,0x6f,0x6c,0x73,1,0x61,0xa3,0x66,0x62,0xa3,0x69,0x17,0x6c,
+0x6c,0x61,0x6e,0x65,0x6f,0x75,0x73,2,0x6d,0x3a,0x73,0x6c,0x74,0x17,0x65,0x63,
+0x68,0x6e,0x69,0x63,0x61,0x6c,0x81,0x11,0x61,0x74,0x1f,0x68,0x65,0x6d,0x61,0x74,
+0x69,0x63,0x61,0x6c,0x73,0x79,0x6d,0x62,0x6f,0x6c,0x73,1,0x61,0xa3,0x66,0x62,
+0xa3,0x69,0x15,0x79,0x6d,0x62,0x6f,0x6c,0x73,0x8e,0x12,0x61,0x6e,0x64,1,0x61,
+0x3c,0x70,0x19,0x69,0x63,0x74,0x6f,0x67,0x72,0x61,0x70,0x68,0x73,0xa3,0xcd,0x14,
+0x72,0x72,0x6f,0x77,0x73,0xa3,0x73,0x10,0x6f,0xa3,0xd8,7,0x72,0x6f,0x72,0x44,
+0x73,0x4e,0x74,0x62,0x79,0x19,0x61,0x6e,0x6e,0x75,0x6d,0x65,0x72,0x61,0x6c,0x73,
+0xa5,0x20,0x13,0x63,0x68,0x65,0x6e,0xa5,0xc,0x18,0x61,0x72,0x61,0x6d,0x67,0x6f,
+0x6e,0x64,0x69,0xa5,0x14,0x10,0x68,2,0x61,0x3a,0x65,0x4a,0x6f,0x17,0x70,0x65,
+0x72,0x61,0x74,0x6f,0x72,0x73,0x7f,0x16,0x6c,0x70,0x68,0x61,0x6e,0x75,0x6d,0xa3,
+0x5d,0x16,0x6d,0x61,0x74,0x69,0x63,0x61,0x6c,1,0x61,0x36,0x6f,0x17,0x70,0x65,
+0x72,0x61,0x74,0x6f,0x72,0x73,0x7f,0x11,0x6c,0x70,0x1f,0x68,0x61,0x6e,0x75,0x6d,
+0x65,0x72,0x69,0x63,0x73,0x79,0x6d,0x62,0x6f,0x6c,0x73,0xa3,0x5d,0x68,0x50,0x6b,
+0x7e,0x6c,0x88,0x6e,1,0x64,0x34,0x69,0x15,0x63,0x68,0x61,0x65,0x61,0x6e,0xa3,
+0xea,0x12,0x61,0x69,0x63,0xa3,0xc6,1,0x61,0x3e,0x6a,0x12,0x6f,0x6e,0x67,0xa2,
+0xaa,0x14,0x74,0x69,0x6c,0x65,0x73,0xa3,0xaa,0x13,0x6a,0x61,0x6e,0x69,0xa3,0xe9,
+0x13,0x61,0x73,0x61,0x72,0xa5,0x1f,0x15,0x61,0x79,0x61,0x6c,0x61,0x6d,0x4f,3,
+0x64,0x6c,0x65,0x7e,0x6e,0xa2,0x47,0x72,0x14,0x6f,0x69,0x74,0x69,0x63,1,0x63,
+0x3c,0x68,0x19,0x69,0x65,0x72,0x6f,0x67,0x6c,0x79,0x70,0x68,0x73,0xa3,0xd7,0x15,
+0x75,0x72,0x73,0x69,0x76,0x65,0xa3,0xd6,0x17,0x65,0x66,0x61,0x69,0x64,0x72,0x69,
+0x6e,0xa5,0x21,0x17,0x74,0x65,0x69,0x6d,0x61,0x79,0x65,0x6b,0xa2,0xb8,0x12,0x65,
+0x78,0x74,0xa2,0xd5,0x16,0x65,0x6e,0x73,0x69,0x6f,0x6e,0x73,0xa3,0xd5,0x18,0x64,
+0x65,0x6b,0x69,0x6b,0x61,0x6b,0x75,0x69,0xa3,0xeb,6,0x6b,0x3b,0x6b,0x56,0x6f,
+0x5a,0x75,0x64,0x79,0x11,0x69,0x61,0x1f,0x6b,0x65,0x6e,0x67,0x70,0x75,0x61,0x63,
+0x68,0x75,0x65,0x68,0x6d,0x6f,0x6e,0x67,0xa5,0x27,0x10,0x6f,0xa3,0x92,0x14,0x62,
+0x6c,0x6f,0x63,0x6b,0x21,1,0x6d,0x2c,0x73,0x11,0x68,0x75,0xa5,0x15,0x17,0x62,
+0x65,0x72,0x66,0x6f,0x72,0x6d,0x73,0x7b,0x61,0x44,0x62,0x21,0x65,0x10,0x77,1,
+0x61,0xa5,0xe,0x74,0x14,0x61,0x69,0x6c,0x75,0x65,0xa3,0x8b,1,0x62,0x38,0x6e,
+0x17,0x64,0x69,0x6e,0x61,0x67,0x61,0x72,0x69,0xa5,0x26,0x15,0x61,0x74,0x61,0x65,
+0x61,0x6e,0xa3,0xef,0x67,0xc4,0x32,0x6a,0xc1,0xb9,0x6a,0xa2,0xd5,0x6b,0xa2,0xee,
+0x6c,4,0x61,0x54,0x65,0xa2,0x61,0x69,0xa2,0x78,0x6f,0xa2,0xb7,0x79,1,0x63,
+0x2e,0x64,0x12,0x69,0x61,0x6e,0xa3,0xa9,0x12,0x69,0x61,0x6e,0xa3,0xa7,1,0x6f,
+0x55,0x74,0x11,0x69,0x6e,1,0x31,0x82,0x65,0x11,0x78,0x74,4,0x61,0x5c,0x62,
+0x29,0x63,0xa3,0x94,0x64,0xa3,0x95,0x65,0xa2,0xe7,0x13,0x6e,0x64,0x65,0x64,4,
+0x61,0x36,0x62,0x29,0x63,0xa3,0x94,0x64,0xa3,0x95,0x65,0xa3,0xe7,0x26,0x18,0x64,
+0x64,0x69,0x74,0x69,0x6f,0x6e,0x61,0x6c,0x6d,0x24,0x12,0x73,0x75,0x70,0x24,0x16,
+0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x25,1,0x70,0x42,0x74,0x1d,0x74,0x65,0x72,
+0x6c,0x69,0x6b,0x65,0x73,0x79,0x6d,0x62,0x6f,0x6c,0x73,0x79,0x12,0x63,0x68,0x61,
+0xa3,0x9c,2,0x6d,0x4e,0x6e,0x54,0x73,0x10,0x75,0xa2,0xb0,0x12,0x73,0x75,0x70,
+0xa4,0x31,0x16,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0xa5,0x31,0x11,0x62,0x75,0xa3,
+0x6f,0x12,0x65,0x61,0x72,1,0x61,0xa3,0xe8,0x62,1,0x69,0x38,0x73,0x17,0x79,
+0x6c,0x6c,0x61,0x62,0x61,0x72,0x79,0xa3,0x75,0x17,0x64,0x65,0x6f,0x67,0x72,0x61,
+0x6d,0x73,0xa3,0x76,0x1a,0x77,0x73,0x75,0x72,0x72,0x6f,0x67,0x61,0x74,0x65,0x73,
+0xa3,0x4d,0x10,0x61,1,0x6d,0x32,0x76,0x14,0x61,0x6e,0x65,0x73,0x65,0xa3,0xb5,
+0x10,0x6f,0x5c,0x12,0x65,0x78,0x74,1,0x61,0xa3,0xb4,0x62,0xa3,0xb9,1,0x61,
+0xa2,0x43,0x68,4,0x61,0x40,0x69,0x50,0x6d,0x6e,0x6f,0x86,0x75,0x15,0x64,0x61,
+0x77,0x61,0x64,0x69,0xa3,0xe6,0x16,0x72,0x6f,0x73,0x68,0x74,0x68,0x69,0xa3,0x89,
+0x1d,0x74,0x61,0x6e,0x73,0x6d,0x61,0x6c,0x6c,0x73,0x63,0x72,0x69,0x70,0x74,0xa5,
+0x30,0x11,0x65,0x72,0x68,0x16,0x73,0x79,0x6d,0x62,0x6f,0x6c,0x73,0xa3,0x71,0x12,
+0x6a,0x6b,0x69,0xa3,0xe5,3,0x69,0x3a,0x6e,0x42,0x74,0xa2,0x51,0x79,0x13,0x61,
+0x68,0x6c,0x69,0xa3,0xa2,0x12,0x74,0x68,0x69,0xa3,0xc1,3,0x61,0x34,0x62,0x76,
+0x67,0x7c,0x6e,0x12,0x61,0x64,0x61,0x4d,1,0x65,0x40,0x73,0x11,0x75,0x70,0xa2,
+0xcb,0x16,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0xa3,0xcb,0x11,0x78,0x74,1,0x61,
+0xa5,0x13,0x65,0x14,0x6e,0x64,0x65,0x64,0x61,0xa5,0x13,0x11,0x75,0x6e,0xa3,0x42,
+0x11,0x78,0x69,0x96,0x17,0x72,0x61,0x64,0x69,0x63,0x61,0x6c,0x73,0x97,0x14,0x61,
+0x6b,0x61,0x6e,0x61,0x9e,1,0x65,0x4c,0x70,0x10,0x68,0x1f,0x6f,0x6e,0x65,0x74,
+0x69,0x63,0x65,0x78,0x74,0x65,0x6e,0x73,0x69,0x6f,0x6e,0x73,0xa3,0x6b,0x11,0x78,
+0x74,0xa3,0x6b,0x67,0xa2,0xb5,0x68,0xa4,0x84,0x69,3,0x64,0x4c,0x6d,0xa2,0x55,
+0x6e,0xa2,0x62,0x70,0x13,0x61,0x65,0x78,0x74,0x2a,0x16,0x65,0x6e,0x73,0x69,0x6f,
+0x6e,0x73,0x2b,1,0x63,0x99,0x65,0x17,0x6f,0x67,0x72,0x61,0x70,0x68,0x69,0x63,
+1,0x64,0x56,0x73,0x15,0x79,0x6d,0x62,0x6f,0x6c,0x73,0xa4,0xb,0x1d,0x61,0x6e,
+0x64,0x70,0x75,0x6e,0x63,0x74,0x75,0x61,0x74,0x69,0x6f,0x6e,0xa5,0xb,0x13,0x65,
+0x73,0x63,0x72,0x1f,0x69,0x70,0x74,0x69,0x6f,0x6e,0x63,0x68,0x61,0x72,0x61,0x63,
+0x74,0x65,0x72,0x73,0x99,0x1c,0x70,0x65,0x72,0x69,0x61,0x6c,0x61,0x72,0x61,0x6d,
+0x61,0x69,0x63,0xa3,0xba,1,0x64,0x62,0x73,0x1b,0x63,0x72,0x69,0x70,0x74,0x69,
+0x6f,0x6e,0x61,0x6c,0x70,0x61,1,0x68,0x32,0x72,0x14,0x74,0x68,0x69,0x61,0x6e,
+0xa3,0xbd,0x13,0x6c,0x61,0x76,0x69,0xa3,0xbe,0x11,0x69,0x63,1,0x6e,0x3e,0x73,
+0x1a,0x69,0x79,0x61,0x71,0x6e,0x75,0x6d,0x62,0x65,0x72,0x73,0xa5,0x1e,0x19,0x75,
+0x6d,0x62,0x65,0x72,0x66,0x6f,0x72,0x6d,0x73,0xa3,0xb2,4,0x65,0x74,0x6c,0xa2,
+0x82,0x6f,0xa2,0x9a,0x72,0xa2,0x9e,0x75,2,0x6a,0x34,0x6e,0x3e,0x72,0x14,0x6d,
+0x75,0x6b,0x68,0x69,0x43,0x14,0x61,0x72,0x61,0x74,0x69,0x45,0x18,0x6a,0x61,0x6c,
+0x61,0x67,0x6f,0x6e,0x64,0x69,0xa5,0x1c,1,0x6e,0xa2,0x46,0x6f,1,0x6d,0x6e,
+0x72,0x13,0x67,0x69,0x61,0x6e,0x5a,1,0x65,0x40,0x73,0x11,0x75,0x70,0xa2,0x87,
+0x16,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0xa3,0x87,0x11,0x78,0x74,0xa4,0x1b,0x14,
+0x65,0x6e,0x64,0x65,0x64,0xa5,0x1b,0x1a,0x65,0x74,0x72,0x69,0x63,0x73,0x68,0x61,
+0x70,0x65,0x73,0x8c,0x12,0x65,0x78,0x74,0xa2,0xe3,0x14,0x65,0x6e,0x64,0x65,0x64,
+0xa3,0xe3,0x1e,0x65,0x72,0x61,0x6c,0x70,0x75,0x6e,0x63,0x74,0x75,0x61,0x74,0x69,
+0x6f,0x6e,0x71,0x17,0x61,0x67,0x6f,0x6c,0x69,0x74,0x69,0x63,0xa2,0x88,0x12,0x73,
+0x75,0x70,0xa4,0xa,0x16,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0xa5,0xa,0x13,0x74,
+0x68,0x69,0x63,0xa3,0x59,1,0x61,0x5c,0x65,0x11,0x65,0x6b,0x30,1,0x61,0x38,
+0x65,0x11,0x78,0x74,0x6e,0x14,0x65,0x6e,0x64,0x65,0x64,0x6f,0x17,0x6e,0x64,0x63,
+0x6f,0x70,0x74,0x69,0x63,0x31,0x13,0x6e,0x74,0x68,0x61,0xa3,0xe4,2,0x61,0xa2,
+0x48,0x65,0xa2,0xdf,0x69,1,0x67,0x30,0x72,0x14,0x61,0x67,0x61,0x6e,0x61,0x9d,
+0x10,0x68,1,0x70,0x3a,0x73,0x18,0x75,0x72,0x72,0x6f,0x67,0x61,0x74,0x65,0x73,
+0xa3,0x4b,1,0x72,0x3c,0x75,0x19,0x73,0x75,0x72,0x72,0x6f,0x67,0x61,0x74,0x65,
+0x73,0xa3,0x4c,0x11,0x69,0x76,0x1f,0x61,0x74,0x65,0x75,0x73,0x65,0x73,0x75,0x72,
+0x72,0x6f,0x67,0x61,0x74,0x65,0x73,0xa3,0x4c,2,0x6c,0x32,0x6e,0x9a,0x74,0x12,
+0x72,0x61,0x6e,0xa5,2,0x10,0x66,2,0x61,0x58,0x6d,0x70,0x77,0x14,0x69,0x64,
+0x74,0x68,0x61,0x1f,0x6e,0x64,0x66,0x75,0x6c,0x6c,0x77,0x69,0x64,0x74,0x68,0x66,
+0x6f,0x72,0x6d,0x73,0xa3,0x57,0x1a,0x6e,0x64,0x66,0x75,0x6c,0x6c,0x66,0x6f,0x72,
+0x6d,0x73,0xa3,0x57,0x13,0x61,0x72,0x6b,0x73,0xa3,0x52,2,0x67,0x34,0x69,0xa2,
+0x45,0x75,0x12,0x6e,0x6f,0x6f,0xa3,0x63,0x11,0x75,0x6c,0xa2,0x4a,2,0x63,0x3c,
+0x6a,0x5e,0x73,0x17,0x79,0x6c,0x6c,0x61,0x62,0x6c,0x65,0x73,0xa3,0x4a,0x1f,0x6f,
+0x6d,0x70,0x61,0x74,0x69,0x62,0x69,0x6c,0x69,0x74,0x79,0x6a,0x61,0x6d,0x6f,0xa3,
+0x41,0x12,0x61,0x6d,0x6f,0x5c,0x17,0x65,0x78,0x74,0x65,0x6e,0x64,0x65,0x64,1,
+0x61,0xa3,0xb4,0x62,0xa3,0xb9,0x19,0x66,0x69,0x72,0x6f,0x68,0x69,0x6e,0x67,0x79,
+0x61,0xa5,0x1d,0x13,0x62,0x72,0x65,0x77,0x37,0x61,0xa4,5,0x62,0xa6,0x45,0x63,
+0xa8,0x1a,0x64,0xac,0xb8,0x65,5,0x6d,0xa2,0x6d,0x86,0x6e,0x96,0x74,0x15,0x68,
+0x69,0x6f,0x70,0x69,0x63,0x5e,1,0x65,0x40,0x73,0x11,0x75,0x70,0xa2,0x86,0x16,
+0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0xa3,0x86,0x11,0x78,0x74,0xa2,0x85,1,0x61,
+0xa3,0xc8,0x65,0x13,0x6e,0x64,0x65,0x64,0xa2,0x85,0x10,0x61,0xa3,0xc8,0x16,0x6f,
+0x74,0x69,0x63,0x6f,0x6e,0x73,0xa3,0xce,0x15,0x63,0x6c,0x6f,0x73,0x65,0x64,2,
+0x61,0x5a,0x63,0x9e,0x69,0x1c,0x64,0x65,0x6f,0x67,0x72,0x61,0x70,0x68,0x69,0x63,
+0x73,0x75,0x70,0xa2,0xc4,0x16,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0xa3,0xc4,0x16,
+0x6c,0x70,0x68,0x61,0x6e,0x75,0x6d,0x86,1,0x65,0x2c,0x73,0x11,0x75,0x70,0xa3,
+0xc3,0x13,0x72,0x69,0x63,0x73,0x86,0x18,0x75,0x70,0x70,0x6c,0x65,0x6d,0x65,0x6e,
+0x74,0xa3,0xc3,0x11,0x6a,0x6b,0xa2,0x44,0x1f,0x6c,0x65,0x74,0x74,0x65,0x72,0x73,
+0x61,0x6e,0x64,0x6d,0x6f,0x6e,0x74,0x68,0x73,0xa3,0x44,0x61,0x4a,0x67,0x76,0x6c,
+1,0x62,0x30,0x79,0x13,0x6d,0x61,0x69,0x63,0xa5,0x25,0x13,0x61,0x73,0x61,0x6e,
+0xa3,0xe2,0x13,0x72,0x6c,0x79,0x64,0x1f,0x79,0x6e,0x61,0x73,0x74,0x69,0x63,0x63,
+0x75,0x6e,0x65,0x69,0x66,0x6f,0x72,0x6d,0xa5,1,0x1f,0x79,0x70,0x74,0x69,0x61,
+0x6e,0x68,0x69,0x65,0x72,0x6f,0x67,0x6c,0x79,0x70,0x68,1,0x66,0x26,0x73,0xa3,
+0xc2,0x1c,0x6f,0x72,0x6d,0x61,0x74,0x63,0x6f,0x6e,0x74,0x72,0x6f,0x6c,0x73,0xa5,
+0x24,7,0x6e,0xc0,0xe5,0x6e,0x3e,0x72,0xa2,0x5d,0x73,0xa2,0xd8,0x76,0x14,0x65,
+0x73,0x74,0x61,0x6e,0xa3,0xbc,1,0x61,0x92,0x63,0x13,0x69,0x65,0x6e,0x74,1,
+0x67,0x34,0x73,0x15,0x79,0x6d,0x62,0x6f,0x6c,0x73,0xa3,0xa5,0x13,0x72,0x65,0x65,
+0x6b,1,0x6d,0x34,0x6e,0x15,0x75,0x6d,0x62,0x65,0x72,0x73,0xa3,0x7f,0x13,0x75,
+0x73,0x69,0x63,0xa2,0x7e,0x19,0x61,0x6c,0x6e,0x6f,0x74,0x61,0x74,0x69,0x6f,0x6e,
+0xa3,0x7e,0x10,0x74,0x1f,0x6f,0x6c,0x69,0x61,0x6e,0x68,0x69,0x65,0x72,0x6f,0x67,
+0x6c,0x79,0x70,0x68,0x73,0xa3,0xfe,2,0x61,0x32,0x6d,0xa2,0x71,0x72,0x12,0x6f,
+0x77,0x73,0x7d,0x12,0x62,0x69,0x63,0x38,3,0x65,0x4a,0x6d,0x66,0x70,0xa2,0x43,
+0x73,0x11,0x75,0x70,0xa2,0x80,0x16,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0xa3,0x80,
+0x11,0x78,0x74,1,0x61,0xa3,0xd2,0x65,0x14,0x6e,0x64,0x65,0x64,0x61,0xa3,0xd2,
+0x12,0x61,0x74,0x68,0xa2,0xd3,0x18,0x65,0x6d,0x61,0x74,0x69,0x63,0x61,0x6c,0x61,
+0x1f,0x6c,0x70,0x68,0x61,0x62,0x65,0x74,0x69,0x63,0x73,0x79,0x6d,0x62,0x6f,0x6c,
+0x73,0xa3,0xd3,1,0x66,0x42,0x72,0x1e,0x65,0x73,0x65,0x6e,0x74,0x61,0x74,0x69,
+0x6f,0x6e,0x66,0x6f,0x72,0x6d,0x73,1,0x61,0xa3,0x51,0x62,0xa3,0x55,0x14,0x65,
+0x6e,0x69,0x61,0x6e,0x35,0x12,0x63,0x69,0x69,0x23,0x64,0x9e,0x65,0xa2,0x42,0x68,
+0xa2,0x4d,0x6c,1,0x63,0x62,0x70,0x17,0x68,0x61,0x62,0x65,0x74,0x69,0x63,0x70,
+1,0x66,0xa3,0x50,0x72,0x1e,0x65,0x73,0x65,0x6e,0x74,0x61,0x74,0x69,0x6f,0x6e,
+0x66,0x6f,0x72,0x6d,0x73,0xa3,0x50,0x16,0x68,0x65,0x6d,0x69,0x63,0x61,0x6c,0xa2,
+0xd0,0x16,0x73,0x79,0x6d,0x62,0x6f,0x6c,0x73,0xa3,0xd0,0x12,0x6c,0x61,0x6d,0xa5,
+7,0x1a,0x67,0x65,0x61,0x6e,0x6e,0x75,0x6d,0x62,0x65,0x72,0x73,0xa3,0x77,0x11,
+0x6f,0x6d,0xa3,0xfd,7,0x6f,0x71,0x6f,0x64,0x72,0xa2,0x41,0x75,0xa2,0x58,0x79,
+0x1b,0x7a,0x61,0x6e,0x74,0x69,0x6e,0x65,0x6d,0x75,0x73,0x69,0x63,0xa2,0x5b,0x18,
+0x61,0x6c,0x73,0x79,0x6d,0x62,0x6f,0x6c,0x73,0xa3,0x5b,1,0x70,0x34,0x78,0x16,
+0x64,0x72,0x61,0x77,0x69,0x6e,0x67,0x89,0x14,0x6f,0x6d,0x6f,0x66,0x6f,0xa0,0x12,
+0x65,0x78,0x74,0xa2,0x43,0x14,0x65,0x6e,0x64,0x65,0x64,0xa3,0x43,0x10,0x61,1,
+0x68,0x40,0x69,0x12,0x6c,0x6c,0x65,0x92,0x17,0x70,0x61,0x74,0x74,0x65,0x72,0x6e,
+0x73,0x93,0x11,0x6d,0x69,0xa3,0xc9,1,0x67,0x2c,0x68,0x11,0x69,0x64,0xa3,0x64,
+0x14,0x69,0x6e,0x65,0x73,0x65,0xa3,0x81,0x61,0x48,0x65,0xa2,0x4e,0x68,0xa2,0x52,
+0x6c,0x1a,0x6f,0x63,0x6b,0x65,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x73,0x8b,3,0x6c,
+0x34,0x6d,0x40,0x73,0x66,0x74,0x11,0x61,0x6b,0xa3,0xc7,0x14,0x69,0x6e,0x65,0x73,
+0x65,0xa3,0x93,0x11,0x75,0x6d,0xa2,0xb1,0x12,0x73,0x75,0x70,0xa2,0xca,0x16,0x70,
+0x6c,0x65,0x6d,0x65,0x6e,0x74,0xa3,0xca,1,0x69,0x30,0x73,0x13,0x61,0x76,0x61,
+0x68,0xa3,0xdd,0x15,0x63,0x6c,0x61,0x74,0x69,0x6e,0x23,0x14,0x6e,0x67,0x61,0x6c,
+0x69,0x41,0x16,0x61,0x69,0x6b,0x73,0x75,0x6b,0x69,0xa5,8,5,0x6f,0xc1,0x4c,
+0x6f,0xa2,0x55,0x75,0xa4,0x10,0x79,1,0x70,0x9c,0x72,0x14,0x69,0x6c,0x6c,0x69,
+0x63,0x32,1,0x65,0x4c,0x73,0x11,0x75,0x70,0xa2,0x61,0x16,0x70,0x6c,0x65,0x6d,
+0x65,0x6e,0x74,0xa2,0x61,0x12,0x61,0x72,0x79,0xa3,0x61,0x11,0x78,0x74,3,0x61,
+0xa3,0x9e,0x62,0xa3,0xa0,0x63,0xa5,9,0x65,0x13,0x6e,0x64,0x65,0x64,2,0x61,
+0xa3,0x9e,0x62,0xa3,0xa0,0x63,0xa5,9,0x1c,0x72,0x69,0x6f,0x74,0x73,0x79,0x6c,
+0x6c,0x61,0x62,0x61,0x72,0x79,0xa3,0x7b,3,0x6d,0x5a,0x6e,0xa2,0x95,0x70,0xa2,
+0xa0,0x75,0x17,0x6e,0x74,0x69,0x6e,0x67,0x72,0x6f,0x64,0xa2,0x9a,0x17,0x6e,0x75,
+0x6d,0x65,0x72,0x61,0x6c,0x73,0xa3,0x9a,2,0x62,0x3a,0x6d,0xa2,0x5f,0x70,0x15,
+0x61,0x74,0x6a,0x61,0x6d,0x6f,0xa3,0x41,0x14,0x69,0x6e,0x69,0x6e,0x67,2,0x64,
+0x46,0x68,0x9e,0x6d,0x1d,0x61,0x72,0x6b,0x73,0x66,0x6f,0x72,0x73,0x79,0x6d,0x62,
+0x6f,0x6c,0x73,0x77,0x1e,0x69,0x61,0x63,0x72,0x69,0x74,0x69,0x63,0x61,0x6c,0x6d,
+0x61,0x72,0x6b,0x73,0x2e,2,0x65,0x40,0x66,0xa6,0x41,0x73,0x18,0x75,0x70,0x70,
+0x6c,0x65,0x6d,0x65,0x6e,0x74,0xa3,0x83,0x16,0x78,0x74,0x65,0x6e,0x64,0x65,0x64,
+0xa3,0xe0,0x17,0x61,0x6c,0x66,0x6d,0x61,0x72,0x6b,0x73,0xa3,0x52,0x11,0x6f,0x6e,
+0x1f,0x69,0x6e,0x64,0x69,0x63,0x6e,0x75,0x6d,0x62,0x65,0x72,0x66,0x6f,0x72,0x6d,
+0x73,0xa3,0xb2,0x1b,0x74,0x72,0x6f,0x6c,0x70,0x69,0x63,0x74,0x75,0x72,0x65,0x73,
+0x83,0x12,0x74,0x69,0x63,0xa2,0x84,0x1b,0x65,0x70,0x61,0x63,0x74,0x6e,0x75,0x6d,
+0x62,0x65,0x72,0x73,0xa3,0xdf,1,0x6e,0x3e,0x72,0x1b,0x72,0x65,0x6e,0x63,0x79,
+0x73,0x79,0x6d,0x62,0x6f,0x6c,0x73,0x75,0x15,0x65,0x69,0x66,0x6f,0x72,0x6d,0xa2,
+0x98,0x16,0x6e,0x75,0x6d,0x62,0x65,0x72,0x73,0xa2,0x99,0x1d,0x61,0x6e,0x64,0x70,
+0x75,0x6e,0x63,0x74,0x75,0x61,0x74,0x69,0x6f,0x6e,0xa3,0x99,0x61,0xa2,0xe1,0x68,
+0xa4,0xb,0x6a,0x10,0x6b,0xa2,0x47,4,0x63,0x8c,0x65,0xa2,0x80,0x72,0xa2,0x98,
+0x73,0xa2,0xaa,0x75,0x1f,0x6e,0x69,0x66,0x69,0x65,0x64,0x69,0x64,0x65,0x6f,0x67,
+0x72,0x61,0x70,0x68,0x73,0xa2,0x47,0x18,0x65,0x78,0x74,0x65,0x6e,0x73,0x69,0x6f,
+0x6e,6,0x64,0x6b,0x64,0xa3,0xd1,0x65,0xa5,0,0x66,0xa5,0x12,0x67,0xa5,0x2e,
+0x14,0x6f,0x6d,0x70,0x61,0x74,0xa2,0x45,1,0x66,0x96,0x69,1,0x62,0x44,0x64,
+0x17,0x65,0x6f,0x67,0x72,0x61,0x70,0x68,0x73,0xa2,0x4f,0x12,0x73,0x75,0x70,0xa3,
+0x5f,0x14,0x69,0x6c,0x69,0x74,0x79,0xa2,0x45,1,0x66,0x54,0x69,0x18,0x64,0x65,
+0x6f,0x67,0x72,0x61,0x70,0x68,0x73,0xa2,0x4f,0x19,0x73,0x75,0x70,0x70,0x6c,0x65,
+0x6d,0x65,0x6e,0x74,0xa3,0x5f,0x13,0x6f,0x72,0x6d,0x73,0xa3,0x53,0x11,0x78,0x74,
+6,0x64,0xc,0x64,0xa3,0xd1,0x65,0xa5,0,0x66,0xa5,0x12,0x67,0xa5,0x2e,0x61,
+0xa3,0x46,0x62,0xa3,0x5e,0x63,0xa3,0xc5,0x19,0x61,0x64,0x69,0x63,0x61,0x6c,0x73,
+0x73,0x75,0x70,0x94,0x16,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x95,1,0x74,0x50,
+0x79,0x14,0x6d,0x62,0x6f,0x6c,0x73,0x9a,0x1d,0x61,0x6e,0x64,0x70,0x75,0x6e,0x63,
+0x74,0x75,0x61,0x74,0x69,0x6f,0x6e,0x9b,0x14,0x72,0x6f,0x6b,0x65,0x73,0xa3,0x82,
+2,0x6e,0x48,0x72,0x64,0x75,0x1d,0x63,0x61,0x73,0x69,0x61,0x6e,0x61,0x6c,0x62,
+0x61,0x6e,0x69,0x61,0x6e,0xa3,0xde,0x1d,0x61,0x64,0x69,0x61,0x6e,0x73,0x79,0x6c,
+0x6c,0x61,0x62,0x69,0x63,0x73,0x63,0x12,0x69,0x61,0x6e,0xa3,0xa8,2,0x61,0x3a,
+0x65,0x4c,0x6f,0x16,0x72,0x61,0x73,0x6d,0x69,0x61,0x6e,0xa5,0x2d,1,0x6b,0x26,
+0x6d,0xa3,0xa4,0x11,0x6d,0x61,0xa3,0xd4,1,0x72,0x38,0x73,0x17,0x73,0x73,0x79,
+0x6d,0x62,0x6f,0x6c,0x73,0xa5,0x19,0x13,0x6f,0x6b,0x65,0x65,0x60,0x12,0x73,0x75,
+0x70,0xa2,0xff,0x16,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0xa3,0xff,3,0x65,0x3e,
+0x69,0x7e,0x6f,0xa2,0x69,0x75,0x15,0x70,0x6c,0x6f,0x79,0x61,0x6e,0xa3,0xe1,1,
+0x73,0x50,0x76,0x16,0x61,0x6e,0x61,0x67,0x61,0x72,0x69,0x3e,0x12,0x65,0x78,0x74,
+0xa2,0xb3,0x14,0x65,0x6e,0x64,0x65,0x64,0xa3,0xb3,0x13,0x65,0x72,0x65,0x74,0xa3,
+0x5a,2,0x61,0x3a,0x6e,0x82,0x76,0x16,0x65,0x73,0x61,0x6b,0x75,0x72,0x75,0xa5,
+0x2f,0x18,0x63,0x72,0x69,0x74,0x69,0x63,0x61,0x6c,0x73,0x2e,2,0x65,0x30,0x66,
+0x36,0x73,0x11,0x75,0x70,0xa3,0x83,0x11,0x78,0x74,0xa3,0xe0,0x18,0x6f,0x72,0x73,
+0x79,0x6d,0x62,0x6f,0x6c,0x73,0x77,0x14,0x67,0x62,0x61,0x74,0x73,0x91,1,0x67,
+0x3e,0x6d,0x12,0x69,0x6e,0x6f,0xa2,0xab,0x14,0x74,0x69,0x6c,0x65,0x73,0xa3,0xab,
+0x11,0x72,0x61,0xa5,0x1a,8,0x6d,0x5f,0x6d,0x3a,0x6e,0x48,0x73,0x7a,0x76,0xa2,
+0x4b,0x77,0x12,0x69,0x64,0x65,0x43,0x11,0x65,0x64,0x32,0x12,0x69,0x61,0x6c,0x33,
+2,0x61,0x40,0x62,0x37,0x6f,1,0x62,0x28,0x6e,0x10,0x65,0x21,0x13,0x72,0x65,
+0x61,0x6b,0x37,0x10,0x72,0x34,0x12,0x72,0x6f,0x77,0x35,2,0x6d,0x38,0x71,0x46,
+0x75,1,0x62,0x3d,0x70,0x3e,0x11,0x65,0x72,0x3f,1,0x61,0x24,0x6c,0x39,0x11,
+0x6c,0x6c,0x39,1,0x72,0x3b,0x75,0x12,0x61,0x72,0x65,0x3b,0x12,0x65,0x72,0x74,
+0x40,0x13,0x69,0x63,0x61,0x6c,0x41,0x63,0x58,0x65,0x92,0x66,0x96,0x69,1,0x6e,
+0x36,0x73,0x10,0x6f,0x30,0x14,0x6c,0x61,0x74,0x65,0x64,0x31,0x11,0x69,0x74,0x2e,
+0x12,0x69,0x61,0x6c,0x2f,2,0x61,0x36,0x69,0x48,0x6f,0x10,0x6d,0x24,0x12,0x70,
+0x61,0x74,0x25,0x10,0x6e,0x22,0x15,0x6f,0x6e,0x69,0x63,0x61,0x6c,0x23,0x13,0x72,
+0x63,0x6c,0x65,0x27,0x11,0x6e,0x63,0x27,2,0x69,0x3a,0x6f,0x44,0x72,0x10,0x61,
+0x2c,0x14,0x63,0x74,0x69,0x6f,0x6e,0x2d,0x10,0x6e,0x28,0x11,0x61,0x6c,0x29,0x11,
+0x6e,0x74,0x2b,4,0x61,0x3a,0x66,0x4c,0x68,0x5e,0x6e,0x70,0x77,0x2a,0x12,0x69,
+0x64,0x65,0x2b,0x22,0x17,0x6d,0x62,0x69,0x67,0x75,0x6f,0x75,0x73,0x23,0x26,0x17,
+0x75,0x6c,0x6c,0x77,0x69,0x64,0x74,0x68,0x27,0x24,0x17,0x61,0x6c,0x66,0x77,0x69,
+0x64,0x74,0x68,0x25,0x20,1,0x61,0x30,0x65,0x14,0x75,0x74,0x72,0x61,0x6c,0x21,
+0x28,0x13,0x72,0x72,0x6f,0x77,0x29,0xd,0x6e,0xc0,0xfb,0x73,0x6d,0x73,0x3a,0x74,
+0x98,0x75,0xa2,0x49,0x7a,2,0x6c,0x3b,0x70,0x3d,0x73,0x39,5,0x6f,0x28,0x6f,
+0x57,0x70,0x34,0x75,0x16,0x72,0x72,0x6f,0x67,0x61,0x74,0x65,0x45,0x11,0x61,0x63,
+1,0x65,0x32,0x69,0x15,0x6e,0x67,0x6d,0x61,0x72,0x6b,0x31,0x18,0x73,0x65,0x70,
+0x61,0x72,0x61,0x74,0x6f,0x72,0x39,0x63,0x53,0x6b,0x55,0x6d,0x51,0x1d,0x69,0x74,
+0x6c,0x65,0x63,0x61,0x73,0x65,0x6c,0x65,0x74,0x74,0x65,0x72,0x27,1,0x6e,0x40,
+0x70,0x1c,0x70,0x65,0x72,0x63,0x61,0x73,0x65,0x6c,0x65,0x74,0x74,0x65,0x72,0x23,
+0x17,0x61,0x73,0x73,0x69,0x67,0x6e,0x65,0x64,0x21,0x6e,0x8a,0x6f,0xa2,0x47,0x70,
+8,0x66,0x14,0x66,0x5b,0x69,0x59,0x6f,0x4f,0x72,0x24,0x73,0x49,0x17,0x69,0x76,
+0x61,0x74,0x65,0x75,0x73,0x65,0x43,0x61,0x2c,0x63,0x4d,0x64,0x47,0x65,0x4b,0x1f,
+0x72,0x61,0x67,0x72,0x61,0x70,0x68,0x73,0x65,0x70,0x61,0x72,0x61,0x74,0x6f,0x72,
+0x3d,2,0x64,0x33,0x6c,0x35,0x6f,0x36,0x1b,0x6e,0x73,0x70,0x61,0x63,0x69,0x6e,
+0x67,0x6d,0x61,0x72,0x6b,0x2d,1,0x70,0x7c,0x74,0x12,0x68,0x65,0x72,3,0x6c,
+0x38,0x6e,0x42,0x70,0x4c,0x73,0x14,0x79,0x6d,0x62,0x6f,0x6c,0x57,0x14,0x65,0x74,
+0x74,0x65,0x72,0x2b,0x14,0x75,0x6d,0x62,0x65,0x72,0x37,0x19,0x75,0x6e,0x63,0x74,
+0x75,0x61,0x74,0x69,0x6f,0x6e,0x4f,0x1c,0x65,0x6e,0x70,0x75,0x6e,0x63,0x74,0x75,
+0x61,0x74,0x69,0x6f,0x6e,0x49,0x66,0x9e,0x66,0x88,0x69,0xa2,0x4b,0x6c,0xa2,0x5c,
+0x6d,4,0x61,0x60,0x63,0x31,0x65,0x2f,0x6e,0x2d,0x6f,0x15,0x64,0x69,0x66,0x69,
+0x65,0x72,1,0x6c,0x30,0x73,0x14,0x79,0x6d,0x62,0x6f,0x6c,0x55,0x14,0x65,0x74,
+0x74,0x65,0x72,0x29,0x17,0x74,0x68,0x73,0x79,0x6d,0x62,0x6f,0x6c,0x51,1,0x69,
+0x2e,0x6f,0x13,0x72,0x6d,0x61,0x74,0x41,0x1d,0x6e,0x61,0x6c,0x70,0x75,0x6e,0x63,
+0x74,0x75,0x61,0x74,0x69,0x6f,0x6e,0x5b,0x10,0x6e,0x1f,0x69,0x74,0x69,0x61,0x6c,
+0x70,0x75,0x6e,0x63,0x74,0x75,0x61,0x74,0x69,0x6f,0x6e,0x59,6,0x6d,0x18,0x6d,
+0x29,0x6f,0x28,0x74,0x27,0x75,0x23,0x2a,0x1c,0x77,0x65,0x72,0x63,0x61,0x73,0x65,
+0x6c,0x65,0x74,0x74,0x65,0x72,0x25,0x65,0x28,0x69,0x3c,0x6c,0x25,0x19,0x74,0x74,
+0x65,0x72,0x6e,0x75,0x6d,0x62,0x65,0x72,0x35,0x1a,0x6e,0x65,0x73,0x65,0x70,0x61,
+0x72,0x61,0x74,0x6f,0x72,0x3b,0x63,0x44,0x64,0xa2,0x60,0x65,0x1b,0x6e,0x63,0x6c,
+0x6f,0x73,0x69,0x6e,0x67,0x6d,0x61,0x72,0x6b,0x2f,6,0x6e,0x39,0x6e,0x46,0x6f,
+0x4e,0x73,0x45,0x75,0x1b,0x72,0x72,0x65,0x6e,0x63,0x79,0x73,0x79,0x6d,0x62,0x6f,
+0x6c,0x53,0x20,0x12,0x74,0x72,0x6c,0x3f,0x42,0x10,0x6e,1,0x6e,0x2c,0x74,0x12,
+0x72,0x6f,0x6c,0x3f,0x1f,0x65,0x63,0x74,0x6f,0x72,0x70,0x75,0x6e,0x63,0x74,0x75,
+0x61,0x74,0x69,0x6f,0x6e,0x4d,0x63,0x3f,0x66,0x41,0x6c,0x1d,0x6f,0x73,0x65,0x70,
+0x75,0x6e,0x63,0x74,0x75,0x61,0x74,0x69,0x6f,0x6e,0x4b,2,0x61,0x30,0x65,0x4a,
+0x69,0x12,0x67,0x69,0x74,0x33,0x1c,0x73,0x68,0x70,0x75,0x6e,0x63,0x74,0x75,0x61,
+0x74,0x69,0x6f,0x6e,0x47,0x1a,0x63,0x69,0x6d,0x61,0x6c,0x6e,0x75,0x6d,0x62,0x65,
+0x72,0x33,0,0x12,0x6d,0xc2,0x3f,0x73,0xa1,0x73,0x4e,0x74,0xa2,0x56,0x77,0xa2,
+0x72,0x79,0xa2,0x73,0x7a,1,0x61,0x2c,0x68,0x12,0x61,0x69,0x6e,0x8b,0x11,0x69,
+0x6e,0x85,5,0x74,0x22,0x74,0x38,0x77,0x4c,0x79,0x16,0x72,0x69,0x61,0x63,0x77,
+0x61,0x77,0x6f,0x18,0x72,0x61,0x69,0x67,0x68,0x74,0x77,0x61,0x77,0xa3,0x55,0x15,
+0x61,0x73,0x68,0x6b,0x61,0x66,0x6d,0x61,0x2e,0x65,0x38,0x68,0x11,0x69,0x6e,0x6b,
+0x10,0x64,0x62,0x11,0x68,0x65,0x65,1,0x65,0x2e,0x6d,0x13,0x6b,0x61,0x74,0x68,
+0x69,0x10,0x6e,0x67,1,0x61,0x4e,0x65,1,0x68,0x28,0x74,0x10,0x68,0x77,0x16,
+0x6d,0x61,0x72,0x62,0x75,0x74,0x61,0x74,0x13,0x67,0x6f,0x61,0x6c,0x3d,1,0x68,
+0x71,0x77,0x73,0x11,0x61,0x77,0x79,1,0x65,0x32,0x75,0x11,0x64,0x68,0x80,0x11,
+0x68,0x65,0x83,0x10,0x68,0x7a,1,0x62,0x34,0x77,0x16,0x69,0x74,0x68,0x74,0x61,
+0x69,0x6c,0x7f,0x14,0x61,0x72,0x72,0x65,0x65,0x7d,0x6d,0x6c,0x6e,0xa4,0x6b,0x70,
+0xa4,0x88,0x71,0xa4,0x88,0x72,1,0x65,0x38,0x6f,0x18,0x68,0x69,0x6e,0x67,0x79,
+0x61,0x79,0x65,0x68,0x93,1,0x68,0x5f,0x76,0x16,0x65,0x72,0x73,0x65,0x64,0x70,
+0x65,0x61,2,0x61,0x2e,0x65,0xa4,0x3e,0x69,0x10,0x6d,0x53,1,0x6c,0xa2,0xe7,
+0x6e,0x16,0x69,0x63,0x68,0x61,0x65,0x61,0x6e,0,0x12,0x6e,0x76,0x73,0x51,0x73,
+0x3e,0x74,0x5c,0x77,0xa0,0x79,0xa2,0x42,0x7a,0x13,0x61,0x79,0x69,0x6e,0xa3,0x54,
+0x10,0x61,1,0x64,0x2e,0x6d,0x12,0x65,0x6b,0x68,0xa3,0x4c,0x11,0x68,0x65,0xa3,
+0x4b,3,0x61,0x38,0x65,0x3c,0x68,0x4a,0x77,0x13,0x65,0x6e,0x74,0x79,0xa3,0x51,
+0x10,0x77,0xa3,0x4d,1,0x6e,0xa3,0x4e,0x74,0x10,0x68,0xa3,0x4f,0x14,0x61,0x6d,
+0x65,0x64,0x68,0xa3,0x50,0x11,0x61,0x77,0xa3,0x52,0x12,0x6f,0x64,0x68,0xa3,0x53,
+0x6e,0x3a,0x6f,0x40,0x70,0x46,0x71,0x4a,0x72,0x12,0x65,0x73,0x68,0xa3,0x4a,0x11,
+0x75,0x6e,0xa3,0x46,0x11,0x6e,0x65,0xa3,0x47,0x10,0x65,0xa3,0x48,0x12,0x6f,0x70,
+0x68,0xa3,0x49,0x67,0x33,0x67,0x38,0x68,0x40,0x6b,0x5e,0x6c,0x66,0x6d,0x11,0x65,
+0x6d,0xa3,0x45,0x13,0x69,0x6d,0x65,0x6c,0xa1,1,0x65,0x32,0x75,0x14,0x6e,0x64,
+0x72,0x65,0x64,0xa3,0x42,0x11,0x74,0x68,0xa3,0x41,0x12,0x61,0x70,0x68,0xa3,0x43,
+0x14,0x61,0x6d,0x65,0x64,0x68,0xa3,0x44,0x61,0x34,0x62,0x4a,0x64,0x50,0x66,0x12,
+0x69,0x76,0x65,0x9f,1,0x6c,0x2a,0x79,0x11,0x69,0x6e,0x97,0x12,0x65,0x70,0x68,
+0x95,0x12,0x65,0x74,0x68,0x99,1,0x61,0x30,0x68,0x14,0x61,0x6d,0x65,0x64,0x68,
+0x9d,0x13,0x6c,0x65,0x74,0x68,0x9b,0x15,0x61,0x79,0x61,0x6c,0x61,0x6d,6,0x6e,
+0x2c,0x6e,0x34,0x72,0x5e,0x73,0x62,0x74,0x11,0x74,0x61,0xa3,0x63,2,0x67,0x2e,
+0x6e,0x32,0x79,0x10,0x61,0xa3,0x60,0x10,0x61,0xa3,0x5d,1,0x61,0xa3,0x5e,0x6e,
+0x10,0x61,0xa3,0x5f,0x10,0x61,0xa3,0x61,0x11,0x73,0x61,0xa3,0x62,0x62,0x3c,0x6a,
+0x42,0x6c,0x10,0x6c,1,0x61,0xa3,0x5b,0x6c,0x10,0x61,0xa3,0x5c,0x11,0x68,0x61,
+0xa3,0x59,0x10,0x61,0xa3,0x5a,0x11,0x65,0x6d,0x51,2,0x6f,0x2c,0x75,0x50,0x79,
+0x10,0x61,0x91,1,0x6a,0x28,0x6f,0x10,0x6e,0x55,0x1a,0x6f,0x69,0x6e,0x69,0x6e,
+0x67,0x67,0x72,0x6f,0x75,0x70,0x21,0x10,0x6e,0x57,0x10,0x65,0x59,0x10,0x61,1,
+0x66,0x5b,0x70,0x10,0x68,0x5d,0x66,0x9a,0x66,0x42,0x67,0x7a,0x68,0x8a,0x6b,0xa2,
+0x75,0x6c,0x11,0x61,0x6d,0x4c,0x12,0x61,0x64,0x68,0x4f,2,0x61,0x3e,0x65,0x4a,
+0x69,0x19,0x6e,0x61,0x6c,0x73,0x65,0x6d,0x6b,0x61,0x74,0x68,0x35,0x15,0x72,0x73,
+0x69,0x79,0x65,0x68,0x8f,0x86,0x10,0x68,0x33,0x10,0x61,1,0x66,0x37,0x6d,0x11,
+0x61,0x6c,0x39,1,0x61,0x40,0x65,0x3e,1,0x68,0x28,0x74,0x10,0x68,0x45,0x40,
+0x13,0x67,0x6f,0x61,0x6c,0x43,2,0x68,0x3b,0x6d,0x5c,0x6e,0x1a,0x69,0x66,0x69,
+0x72,0x6f,0x68,0x69,0x6e,0x67,0x79,0x61,1,0x6b,0x2a,0x70,0x10,0x61,0xa3,0x65,
+0x15,0x69,0x6e,0x6e,0x61,0x79,0x61,0xa3,0x64,0x1a,0x7a,0x61,0x6f,0x6e,0x68,0x65,
+0x68,0x67,0x6f,0x61,0x6c,0x3d,2,0x61,0x3a,0x68,0x44,0x6e,0x17,0x6f,0x74,0x74,
+0x65,0x64,0x68,0x65,0x68,0x4b,1,0x66,0x47,0x70,0x10,0x68,0x49,0x12,0x61,0x70,
+0x68,0x89,0x61,0x2e,0x62,0x8a,0x64,0xa2,0x51,0x65,0x31,2,0x66,0x3c,0x69,0x70,
+0x6c,1,0x61,0x28,0x65,0x10,0x66,0x27,0x11,0x70,0x68,0x25,0x14,0x72,0x69,0x63,
+0x61,0x6e,2,0x66,0x30,0x6e,0x36,0x71,0x11,0x61,0x66,0xa3,0x58,0x11,0x65,0x68,
+0xa3,0x56,0x12,0x6f,0x6f,0x6e,0xa3,0x57,0x10,0x6e,0x23,1,0x65,0x4a,0x75,0x10,
+0x72,0x1f,0x75,0x73,0x68,0x61,0x73,0x6b,0x69,0x79,0x65,0x68,0x62,0x61,0x72,0x72,
+0x65,0x65,0x8d,1,0x68,0x29,0x74,0x10,0x68,0x2b,0x11,0x61,0x6c,0x2c,0x16,0x61,
+0x74,0x68,0x72,0x69,0x73,0x68,0x2f,7,0x6e,0x2e,0x6e,0x2c,0x72,0x3e,0x74,0x56,
+0x75,0x21,0x18,0x6f,0x6e,0x6a,0x6f,0x69,0x6e,0x69,0x6e,0x67,0x21,0x28,0x1a,0x69,
+0x67,0x68,0x74,0x6a,0x6f,0x69,0x6e,0x69,0x6e,0x67,0x29,0x2a,0x19,0x72,0x61,0x6e,
+0x73,0x70,0x61,0x72,0x65,0x6e,0x74,0x2b,0x63,0x23,0x64,0x40,0x6a,0x56,0x6c,0x26,
+0x19,0x65,0x66,0x74,0x6a,0x6f,0x69,0x6e,0x69,0x6e,0x67,0x27,0x24,0x19,0x75,0x61,
+0x6c,0x6a,0x6f,0x69,0x6e,0x69,0x6e,0x67,0x25,0x19,0x6f,0x69,0x6e,0x63,0x61,0x75,
+0x73,0x69,0x6e,0x67,0x23,0,0x13,0x6e,0xc0,0xd0,0x73,0x49,0x73,0x48,0x75,0x78,
+0x77,0x84,0x78,0x9c,0x7a,0x10,0x77,0x58,1,0x6a,0x75,0x73,0x13,0x70,0x61,0x63,
+0x65,0x59,4,0x61,0x51,0x67,0x53,0x70,0x28,0x75,0x30,0x79,0x57,0x54,0x12,0x61,
+0x63,0x65,0x55,0x16,0x72,0x72,0x6f,0x67,0x61,0x74,0x65,0x53,0x15,0x6e,0x6b,0x6e,
+0x6f,0x77,0x6e,0x21,1,0x6a,0x5d,0x6f,0x17,0x72,0x64,0x6a,0x6f,0x69,0x6e,0x65,
+0x72,0x5d,0x10,0x78,0x21,0x6e,0x60,0x6f,0xa2,0x41,0x70,0xa2,0x50,0x71,0xa2,0x6e,
+0x72,1,0x65,0x24,0x69,0x6f,0x1e,0x67,0x69,0x6f,0x6e,0x61,0x6c,0x69,0x6e,0x64,
+0x69,0x63,0x61,0x74,0x6f,0x72,0x6f,4,0x65,0x3e,0x6c,0x5b,0x6f,0x46,0x73,0x45,
+0x75,0x46,0x14,0x6d,0x65,0x72,0x69,0x63,0x47,0x15,0x78,0x74,0x6c,0x69,0x6e,0x65,
+0x5b,0x17,0x6e,0x73,0x74,0x61,0x72,0x74,0x65,0x72,0x45,0x10,0x70,0x48,0x1c,0x65,
+0x6e,0x70,0x75,0x6e,0x63,0x74,0x75,0x61,0x74,0x69,0x6f,0x6e,0x49,1,0x6f,0x3e,
+0x72,0x4c,0x1a,0x65,0x66,0x69,0x78,0x6e,0x75,0x6d,0x65,0x72,0x69,0x63,0x4d,0x4a,
+0x1b,0x73,0x74,0x66,0x69,0x78,0x6e,0x75,0x6d,0x65,0x72,0x69,0x63,0x4b,0x10,0x75,
+0x4e,0x16,0x6f,0x74,0x61,0x74,0x69,0x6f,0x6e,0x4f,0x68,0x7b,0x68,0x50,0x69,0x86,
+0x6a,0xa2,0x61,0x6c,0xa2,0x65,0x6d,0x1c,0x61,0x6e,0x64,0x61,0x74,0x6f,0x72,0x79,
+0x62,0x72,0x65,0x61,0x6b,0x2d,4,0x32,0x5f,0x33,0x61,0x65,0x34,0x6c,0x6d,0x79,
+0x3a,0x13,0x70,0x68,0x65,0x6e,0x3b,0x19,0x62,0x72,0x65,0x77,0x6c,0x65,0x74,0x74,
+0x65,0x72,0x6d,2,0x64,0x28,0x6e,0x3c,0x73,0x41,0x3c,0x18,0x65,0x6f,0x67,0x72,
+0x61,0x70,0x68,0x69,0x63,0x3d,0x3e,1,0x66,0x3e,0x73,0x11,0x65,0x70,1,0x61,
+0x22,0x65,0x14,0x72,0x61,0x62,0x6c,0x65,0x3f,0x18,0x69,0x78,0x6e,0x75,0x6d,0x65,
+0x72,0x69,0x63,0x41,2,0x6c,0x63,0x74,0x65,0x76,0x67,1,0x66,0x43,0x69,0x15,
+0x6e,0x65,0x66,0x65,0x65,0x64,0x43,0x61,0x40,0x62,0x70,0x63,0xa2,0x55,0x65,0xa2,
+0xdb,0x67,0x10,0x6c,0x38,0x11,0x75,0x65,0x39,2,0x69,0x23,0x6c,0x34,0x6d,0x16,
+0x62,0x69,0x67,0x75,0x6f,0x75,0x73,0x23,0x24,0x17,0x70,0x68,0x61,0x62,0x65,0x74,
+0x69,0x63,0x25,4,0x32,0x27,0x61,0x29,0x62,0x2b,0x6b,0x2d,0x72,0x12,0x65,0x61,
+0x6b,2,0x61,0x36,0x62,0x3e,0x73,0x15,0x79,0x6d,0x62,0x6f,0x6c,0x73,0x57,0x13,
+0x66,0x74,0x65,0x72,0x29,1,0x65,0x2a,0x6f,0x11,0x74,0x68,0x27,0x13,0x66,0x6f,
+0x72,0x65,0x2b,7,0x6d,0x51,0x6d,0x33,0x6f,0x28,0x70,0x69,0x72,0x35,1,0x6d,
+0x76,0x6e,1,0x64,0x3c,0x74,0x1a,0x69,0x6e,0x67,0x65,0x6e,0x74,0x62,0x72,0x65,
+0x61,0x6b,0x2f,0x15,0x69,0x74,0x69,0x6f,0x6e,0x61,0x1f,0x6c,0x6a,0x61,0x70,0x61,
+0x6e,0x65,0x73,0x65,0x73,0x74,0x61,0x72,0x74,0x65,0x72,0x6b,1,0x62,0x3a,0x70,
+0x19,0x6c,0x65,0x78,0x63,0x6f,0x6e,0x74,0x65,0x78,0x74,0x51,0x18,0x69,0x6e,0x69,
+0x6e,0x67,0x6d,0x61,0x72,0x6b,0x33,0x61,0x6a,0x62,0x2f,0x6a,0x6b,0x6c,0x30,0x13,
+0x6f,0x73,0x65,0x70,1,0x61,0x38,0x75,0x18,0x6e,0x63,0x74,0x75,0x61,0x74,0x69,
+0x6f,0x6e,0x31,0x18,0x72,0x65,0x6e,0x74,0x68,0x65,0x73,0x69,0x73,0x69,0x1b,0x72,
+0x72,0x69,0x61,0x67,0x65,0x72,0x65,0x74,0x75,0x72,0x6e,0x35,2,0x62,0x3e,0x6d,
+0x46,0x78,0x36,0x18,0x63,0x6c,0x61,0x6d,0x61,0x74,0x69,0x6f,0x6e,0x37,0x70,0x12,
+0x61,0x73,0x65,0x71,0x72,0x16,0x6f,0x64,0x69,0x66,0x69,0x65,0x72,0x73,1,0x64,
+0x42,0x6e,1,0x6f,0x32,0x75,0x26,0x14,0x6d,0x65,0x72,0x69,0x63,0x27,0x11,0x6e,
+0x65,0x21,1,0x65,0x2e,0x69,0x24,0x12,0x67,0x69,0x74,0x25,0x22,0x14,0x63,0x69,
+0x6d,0x61,0x6c,0x23,0,0x18,0x6e,0xc4,0x2a,0x74,0xc1,0x6d,0x77,0x96,0x77,0xa2,
+0x4c,0x78,0xa2,0x70,0x79,0xa2,0x7a,0x7a,6,0x73,0x1e,0x73,0x34,0x78,0x42,0x79,
+0x48,0x7a,0x11,0x7a,0x7a,0xa3,0x67,0x10,0x79,1,0x65,0xa3,0xae,0x6d,0xa3,0x81,
+0x11,0x78,0x78,0xa3,0x66,0x11,0x79,0x79,0x21,0x61,0x30,0x69,0x58,0x6d,0x11,0x74,
+0x68,0xa3,0x80,0x10,0x6e,1,0x61,0x26,0x62,0xa3,0xb1,0x1a,0x62,0x61,0x7a,0x61,
+0x72,0x73,0x71,0x75,0x61,0x72,0x65,0xa3,0xb1,0x11,0x6e,0x68,0x23,2,0x61,0x30,
+0x63,0x5a,0x6f,0x11,0x6c,0x65,0xa3,0x9b,1,0x6e,0x3c,0x72,0x10,0x61,0xa2,0x92,
+0x15,0x6e,0x67,0x63,0x69,0x74,0x69,0xa3,0x92,0x12,0x63,0x68,0x6f,0xa3,0xbc,0x11,
+0x68,0x6f,0xa3,0xbc,1,0x70,0x2c,0x73,0x11,0x75,0x78,0xa3,0x65,0x11,0x65,0x6f,
+0x9b,1,0x65,0x2c,0x69,0x72,0x11,0x69,0x69,0x73,0x11,0x7a,0x69,0xa2,0xc0,0x11,
+0x64,0x69,0xa3,0xc0,0x74,0x4a,0x75,0xa2,0xba,0x76,1,0x61,0x2c,0x69,0x11,0x73,
+0x70,0xa3,0x64,0x10,0x69,0xa2,0x63,0x10,0x69,0xa3,0x63,5,0x67,0x36,0x67,0x68,
+0x68,0x6c,0x69,2,0x62,0x3a,0x66,0x4a,0x72,0x10,0x68,0xa2,0x9e,0x12,0x75,0x74,
+0x61,0xa3,0x9e,1,0x65,0x24,0x74,0x6f,0x12,0x74,0x61,0x6e,0x6f,0x14,0x69,0x6e,
+0x61,0x67,0x68,0x99,0x11,0x6c,0x67,0x75,0x10,0x61,1,0x61,0x24,0x69,0x6d,0x6a,
+0x11,0x6e,0x61,0x6b,0x61,0x30,0x65,0xa2,0x5b,0x66,0x11,0x6e,0x67,0x99,6,0x6c,
+0x21,0x6c,0x32,0x6d,0x38,0x6e,0x44,0x76,0x10,0x74,0xa3,0x7f,1,0x65,0x89,0x75,
+0x97,1,0x69,0x24,0x6c,0x67,0x10,0x6c,0x67,0x10,0x67,0xa2,0x9a,0x11,0x75,0x74,
+0xa3,0x9a,0x67,0x36,0x69,0x52,0x6b,0x10,0x72,0xa2,0x99,0x10,0x69,0xa3,0x99,1,
+0x61,0x30,0x62,0x7a,0x13,0x61,0x6e,0x77,0x61,0x7b,0x12,0x6c,0x6f,0x67,0x75,2,
+0x6c,0x32,0x74,0x34,0x76,0x12,0x69,0x65,0x74,0xa3,0x7f,0x10,0x65,0x89,0x12,0x68,
+0x61,0x6d,0xa3,0x6a,1,0x6c,0x2a,0x6e,0x10,0x67,0xa3,0x62,0x10,0x75,0x68,0x11,
+0x67,0x75,0x69,1,0x67,0x32,0x6e,0x14,0x6b,0x6e,0x6f,0x77,0x6e,0xa3,0x67,0x11,
+0x61,0x72,0x8a,0x13,0x69,0x74,0x69,0x63,0x8b,0x71,0xc1,0x13,0x71,0xa2,0xde,0x72,
+0xa2,0xe3,0x73,6,0x69,0x8a,0x69,0x72,0x6f,0xa2,0x4c,0x75,0xa2,0x75,0x79,1,
+0x6c,0x46,0x72,4,0x63,0x65,0x65,0xa3,0x5f,0x69,0x2c,0x6a,0xa3,0x60,0x6e,0xa3,
+0x61,0x11,0x61,0x63,0x65,0x10,0x6f,0x94,0x16,0x74,0x69,0x6e,0x61,0x67,0x72,0x69,
+0x95,2,0x64,0x3c,0x67,0x4c,0x6e,1,0x64,0xa3,0x91,0x68,0x62,0x12,0x61,0x6c,
+0x61,0x63,0x10,0x64,0xa2,0xa6,0x12,0x68,0x61,0x6d,0xa3,0xa6,0x17,0x6e,0x77,0x72,
+0x69,0x74,0x69,0x6e,0x67,0xa3,0x70,2,0x67,0x3a,0x72,0x52,0x79,0x10,0x6f,0xa2,
+0xb0,0x12,0x6d,0x62,0x6f,0xa3,0xb0,1,0x64,0x26,0x6f,0xa3,0xb8,0xa2,0xb7,0x12,
+0x69,0x61,0x6e,0xa3,0xb7,0x10,0x61,0xa2,0x98,0x16,0x73,0x6f,0x6d,0x70,0x65,0x6e,
+0x67,0xa3,0x98,0x11,0x6e,0x64,0xa2,0x71,0x14,0x61,0x6e,0x65,0x73,0x65,0xa3,0x71,
+0x61,0x5c,0x67,0xa2,0x43,0x68,1,0x61,0x2a,0x72,0x10,0x64,0xa3,0x97,2,0x72,
+0x28,0x76,0x30,0x77,0x87,0x12,0x61,0x64,0x61,0xa3,0x97,0x12,0x69,0x61,0x6e,0x87,
+2,0x6d,0x40,0x72,0x58,0x75,0x10,0x72,0xa2,0x6f,0x15,0x61,0x73,0x68,0x74,0x72,
+0x61,0xa3,0x6f,1,0x61,0x26,0x72,0xa3,0x7e,0x14,0x72,0x69,0x74,0x61,0x6e,0xa3,
+0x7e,1,0x61,0xa3,0x5e,0x62,0xa3,0x85,0x11,0x6e,0x77,0xa3,0x70,0x11,0x61,0x61,
+1,0x63,0x2f,0x69,0x23,3,0x65,0x3e,0x6a,0x48,0x6f,0x4e,0x75,0x10,0x6e,1,
+0x69,0x24,0x72,0x61,0x10,0x63,0x61,0x13,0x6a,0x61,0x6e,0x67,0xa3,0x6e,0x11,0x6e,
+0x67,0xa3,0x6e,1,0x68,0x2a,0x72,0x10,0x6f,0xa3,0x5d,0x10,0x67,0xa3,0xb6,0x6e,
+0xa2,0x83,0x6f,0xa2,0xf2,0x70,5,0x6c,0x1e,0x6c,0x44,0x72,0x4a,0x73,0x1b,0x61,
+0x6c,0x74,0x65,0x72,0x70,0x61,0x68,0x6c,0x61,0x76,0x69,0xa3,0x7b,0x11,0x72,0x64,
+0xa3,0x5c,0x11,0x74,0x69,0xa3,0x7d,0x61,0x7c,0x65,0xa2,0x54,0x68,3,0x61,0x3e,
+0x6c,0x4e,0x6e,0x5e,0x6f,0x16,0x65,0x6e,0x69,0x63,0x69,0x61,0x6e,0xa3,0x5b,0x10,
+0x67,0xa2,0x5a,0x12,0x73,0x70,0x61,0xa3,0x5a,2,0x69,0xa3,0x7a,0x70,0xa3,0x7b,
+0x76,0xa3,0x7c,0x10,0x78,0xa3,0x5b,2,0x68,0x3e,0x6c,0x50,0x75,0x10,0x63,0xa2,
+0xa5,0x14,0x69,0x6e,0x68,0x61,0x75,0xa3,0xa5,0x17,0x61,0x77,0x68,0x68,0x6d,0x6f,
+0x6e,0x67,0xa3,0x4b,0x10,0x6d,0xa2,0x90,0x14,0x79,0x72,0x65,0x6e,0x65,0xa3,0x90,
+0x11,0x72,0x6d,0xa3,0x59,6,0x6b,0x36,0x6b,0x56,0x73,0x6e,0x75,0x74,0x79,0x11,
+0x69,0x61,0x1f,0x6b,0x65,0x6e,0x67,0x70,0x75,0x61,0x63,0x68,0x75,0x65,0x68,0x6d,
+0x6f,0x6e,0x67,0xa3,0xba,1,0x67,0x2e,0x6f,0xa2,0x57,0x10,0x6f,0xa3,0x57,0x10,
+0x62,0xa3,0x84,0x11,0x68,0x75,0xa3,0x96,0x12,0x73,0x68,0x75,0xa3,0x96,0x61,0x42,
+0x62,0x80,0x65,0x10,0x77,1,0x61,0xa3,0xaa,0x74,0x14,0x61,0x69,0x6c,0x75,0x65,
+0x97,2,0x62,0x2e,0x6e,0x3c,0x72,0x10,0x62,0xa3,0x8e,0x15,0x61,0x74,0x61,0x65,
+0x61,0x6e,0xa3,0x8f,0x10,0x64,0xa2,0xbb,0x16,0x69,0x6e,0x61,0x67,0x61,0x72,0x69,
+0xa3,0xbb,0x11,0x61,0x74,0xa3,0x8f,3,0x67,0x5a,0x6c,0x6c,0x72,0xa2,0x93,0x73,
+2,0x61,0x36,0x67,0x3c,0x6d,0x10,0x61,0x84,0x12,0x6e,0x79,0x61,0x85,0x11,0x67,
+0x65,0xa3,0xab,0x10,0x65,0xa3,0xab,1,0x61,0x2a,0x68,0x11,0x61,0x6d,0x5b,0x10,
+0x6d,0x5b,1,0x63,0xa2,0x60,0x64,5,0x70,0x37,0x70,0x36,0x73,0x54,0x74,0x14,
+0x75,0x72,0x6b,0x69,0x63,0xa3,0x58,0x11,0x65,0x72,1,0x6d,0x2c,0x73,0x12,0x69,
+0x61,0x6e,0x9b,0x11,0x69,0x63,0xa3,0x59,0x10,0x6f,1,0x67,0x3a,0x75,0x18,0x74,
+0x68,0x61,0x72,0x61,0x62,0x69,0x61,0x6e,0xa3,0x85,0x13,0x64,0x69,0x61,0x6e,0xa3,
+0xb8,0x68,0x42,0x69,0x54,0x6e,0x1a,0x6f,0x72,0x74,0x68,0x61,0x72,0x61,0x62,0x69,
+0x61,0x6e,0xa3,0x8e,0x17,0x75,0x6e,0x67,0x61,0x72,0x69,0x61,0x6e,0xa3,0x4c,0x14,
+0x74,0x61,0x6c,0x69,0x63,0x5d,1,0x68,0x26,0x6b,0xa3,0x6d,0x12,0x69,0x6b,0x69,
+0xa3,0x6d,2,0x69,0x2c,0x6b,0x30,0x79,0x10,0x61,0x5f,0x11,0x79,0x61,0x5f,0x10,
+0x68,0xa3,0x58,0x68,0xc3,0xd,0x6b,0xc2,0x24,0x6b,0xa4,0x17,0x6c,0xa4,0xb2,0x6d,
+8,0x6f,0x46,0x6f,0x48,0x72,0x74,0x74,0x80,0x75,0x86,0x79,1,0x61,0x28,0x6d,
+0x10,0x72,0x59,0x13,0x6e,0x6d,0x61,0x72,0x59,2,0x64,0x2e,0x6e,0x32,0x6f,0x10,
+0x6e,0xa3,0x72,0x10,0x69,0xa3,0xa3,0x10,0x67,0x56,0x14,0x6f,0x6c,0x69,0x61,0x6e,
+0x57,0x10,0x6f,0xa2,0x95,0x10,0x6f,0xa3,0x95,0x11,0x65,0x69,0xa3,0x73,0x11,0x6c,
+0x74,0xa2,0xa4,0x12,0x61,0x6e,0x69,0xa3,0xa4,0x61,0x36,0x65,0xa2,0x67,0x69,0xa2,
+0xbd,0x6c,0x11,0x79,0x6d,0x55,6,0x6e,0x38,0x6e,0x32,0x72,0x5c,0x73,0x6c,0x79,
+0x10,0x61,0xa3,0x55,1,0x64,0x38,0x69,0xa2,0x79,0x15,0x63,0x68,0x61,0x65,0x61,
+0x6e,0xa3,0x79,0xa2,0x54,0x12,0x61,0x69,0x63,0xa3,0x54,0x10,0x63,0xa2,0xa9,0x12,
+0x68,0x65,0x6e,0xa3,0xa9,0x18,0x61,0x72,0x61,0x6d,0x67,0x6f,0x6e,0x64,0x69,0xa3,
+0xaf,0x68,0x36,0x6b,0x4c,0x6c,0x15,0x61,0x79,0x61,0x6c,0x61,0x6d,0x55,1,0x61,
+0x26,0x6a,0xa3,0xa0,0x13,0x6a,0x61,0x6e,0x69,0xa3,0xa0,0x10,0x61,0xa2,0xb4,0x12,
+0x73,0x61,0x72,0xa3,0xb4,3,0x64,0x78,0x65,0x94,0x6e,0xa2,0x42,0x72,1,0x63,
+0xa3,0x8d,0x6f,0xa2,0x56,0x13,0x69,0x74,0x69,0x63,1,0x63,0x3c,0x68,0x19,0x69,
+0x65,0x72,0x6f,0x67,0x6c,0x79,0x70,0x68,0x73,0xa3,0x56,0x15,0x75,0x72,0x73,0x69,
+0x76,0x65,0xa3,0x8d,1,0x65,0x26,0x66,0xa3,0xb5,0x16,0x66,0x61,0x69,0x64,0x72,
+0x69,0x6e,0xa3,0xb5,0x17,0x74,0x65,0x69,0x6d,0x61,0x79,0x65,0x6b,0xa3,0x73,0x10,
+0x64,0xa2,0x8c,0x17,0x65,0x6b,0x69,0x6b,0x61,0x6b,0x75,0x69,0xa3,0x8c,0x11,0x61,
+0x6f,0xa3,0x5c,6,0x6e,0x1a,0x6e,0x34,0x6f,0x38,0x70,0x3e,0x74,0x11,0x68,0x69,
+0xa3,0x78,0x11,0x64,0x61,0x4b,0x11,0x72,0x65,0xa3,0x77,0x11,0x65,0x6c,0xa3,0x8a,
+0x61,0x30,0x68,0x9a,0x69,0x11,0x74,0x73,0xa3,0xbf,4,0x69,0x3c,0x6c,0x44,0x6e,
+0x48,0x74,0x56,0x79,0x13,0x61,0x68,0x6c,0x69,0xa3,0x4f,0x12,0x74,0x68,0x69,0xa3,
+0x78,0x10,0x69,0xa3,0x4f,1,0x61,0x4d,0x6e,0x12,0x61,0x64,0x61,0x4b,0x14,0x61,
+0x6b,0x61,0x6e,0x61,0x4c,0x19,0x6f,0x72,0x68,0x69,0x72,0x61,0x67,0x61,0x6e,0x61,
+0x8d,4,0x61,0x40,0x69,0x52,0x6d,0x70,0x6f,0x7c,0x75,0x15,0x64,0x61,0x77,0x61,
+0x64,0x69,0xa3,0x91,0x10,0x72,0x92,0x15,0x6f,0x73,0x68,0x74,0x68,0x69,0x93,0x1d,
+0x74,0x61,0x6e,0x73,0x6d,0x61,0x6c,0x6c,0x73,0x63,0x72,0x69,0x70,0x74,0xa3,0xbf,
+1,0x65,0x24,0x72,0x4f,0x10,0x72,0x4f,0x10,0x6a,0xa2,0x9d,0x11,0x6b,0x69,0xa3,
+0x9d,4,0x61,0x5c,0x65,0x90,0x69,0xa0,0x6f,0xa2,0x5d,0x79,1,0x63,0x34,0x64,
+0x10,0x69,0xa2,0x6c,0x11,0x61,0x6e,0xa3,0x6c,0x10,0x69,0xa2,0x6b,0x11,0x61,0x6e,
+0xa3,0x6b,2,0x6e,0x42,0x6f,0x46,0x74,3,0x66,0xa3,0x50,0x67,0xa3,0x51,0x69,
+0x24,0x6e,0x53,0x10,0x6e,0x53,0x10,0x61,0xa3,0x6a,0x50,0x10,0x6f,0x51,0x11,0x70,
+0x63,0xa2,0x52,0x11,0x68,0x61,0xa3,0x52,2,0x6d,0x2e,0x6e,0x36,0x73,0x10,0x75,
+0xa3,0x83,0x10,0x62,0x80,0x10,0x75,0x81,2,0x61,0xa3,0x53,0x62,0x83,0x65,0x11,
+0x61,0x72,1,0x61,0xa3,0x53,0x62,0x83,0x11,0x6d,0x61,0xa3,0x8b,0x68,0x6e,0x69,
+0xa2,0x95,0x6a,2,0x61,0x30,0x70,0x52,0x75,0x11,0x72,0x63,0xa3,0x94,1,0x6d,
+0x38,0x76,0x10,0x61,0xa2,0x4e,0x13,0x6e,0x65,0x73,0x65,0xa3,0x4e,0x10,0x6f,0xa3,
+0xad,0x11,0x61,0x6e,0xa3,0x69,6,0x6c,0x1e,0x6c,0x34,0x6d,0x3a,0x72,0x48,0x75,
+0x11,0x6e,0x67,0xa3,0x4c,0x11,0x75,0x77,0xa3,0x9c,0x10,0x6e,1,0x67,0xa3,0x4b,
+0x70,0xa3,0xba,0x11,0x6b,0x74,0x8d,0x61,0x3c,0x65,0xa2,0x43,0x69,0x11,0x72,0x61,
+0x48,0x13,0x67,0x61,0x6e,0x61,0x49,1,0x6e,0x34,0x74,0x10,0x72,0xa2,0xa2,0x11,
+0x61,0x6e,0xa3,0xa2,0x42,6,0x6f,0xe,0x6f,0x77,0x73,0xa3,0x49,0x74,0xa3,0x4a,
+0x75,0x12,0x6e,0x6f,0x6f,0x77,0x62,0xa3,0xac,0x67,0x3e,0x69,0x42,0x19,0x66,0x69,
+0x72,0x6f,0x68,0x69,0x6e,0x67,0x79,0x61,0xa3,0xb6,0x44,0x11,0x75,0x6c,0x45,0x11,
+0x62,0x72,0x46,0x11,0x65,0x77,0x47,2,0x6d,0x2e,0x6e,0x4a,0x74,0x11,0x61,0x6c,
+0x5d,0x1c,0x70,0x65,0x72,0x69,0x61,0x6c,0x61,0x72,0x61,0x6d,0x61,0x69,0x63,0xa3,
+0x74,2,0x64,0x66,0x68,0x6a,0x73,0x1b,0x63,0x72,0x69,0x70,0x74,0x69,0x6f,0x6e,
+0x61,0x6c,0x70,0x61,1,0x68,0x32,0x72,0x14,0x74,0x68,0x69,0x61,0x6e,0xa3,0x7d,
+0x13,0x6c,0x61,0x76,0x69,0xa3,0x7a,0x10,0x73,0xa3,0x4d,0x15,0x65,0x72,0x69,0x74,
+0x65,0x64,0x23,0x64,0xc1,0xd,0x64,0xa2,0x7a,0x65,0xa2,0xc1,0x67,4,0x65,0x82,
+0x6c,0x9a,0x6f,0xa2,0x46,0x72,0xa2,0x55,0x75,2,0x6a,0x3c,0x6e,0x4e,0x72,1,
+0x6d,0x24,0x75,0x41,0x13,0x75,0x6b,0x68,0x69,0x41,1,0x61,0x24,0x72,0x3f,0x13,
+0x72,0x61,0x74,0x69,0x3f,0x18,0x6a,0x61,0x6c,0x61,0x67,0x6f,0x6e,0x64,0x69,0xa3,
+0xb3,0x10,0x6f,1,0x6b,0xa3,0x48,0x72,0x38,0x13,0x67,0x69,0x61,0x6e,0x39,0x11,
+0x61,0x67,0x90,0x15,0x6f,0x6c,0x69,0x74,0x69,0x63,0x91,1,0x6e,0x30,0x74,0x10,
+0x68,0x3a,0x11,0x69,0x63,0x3b,1,0x67,0xa3,0xb3,0x6d,0xa3,0xaf,1,0x61,0x32,
+0x65,1,0x65,0x24,0x6b,0x3d,0x10,0x6b,0x3d,0x10,0x6e,0xa2,0x89,0x12,0x74,0x68,
+0x61,0xa3,0x89,4,0x65,0x46,0x69,0x6c,0x6f,0x8c,0x73,0x9a,0x75,0x11,0x70,0x6c,
+0xa2,0x87,0x13,0x6f,0x79,0x61,0x6e,0xa3,0x87,1,0x73,0x38,0x76,0x10,0x61,0x34,
+0x15,0x6e,0x61,0x67,0x61,0x72,0x69,0x35,0x13,0x65,0x72,0x65,0x74,0x33,1,0x61,
+0x36,0x76,0x16,0x65,0x73,0x61,0x6b,0x75,0x72,0x75,0xa3,0xbe,0x10,0x6b,0xa3,0xbe,
+0x11,0x67,0x72,0xa2,0xb2,0x10,0x61,0xa3,0xb2,0x11,0x72,0x74,0x33,2,0x67,0x3a,
+0x6c,0x72,0x74,0x11,0x68,0x69,0x36,0x13,0x6f,0x70,0x69,0x63,0x37,0x10,0x79,2,
+0x64,0xa3,0x45,0x68,0xa3,0x46,0x70,0xa2,0x47,0x1e,0x74,0x69,0x61,0x6e,0x68,0x69,
+0x65,0x72,0x6f,0x67,0x6c,0x79,0x70,0x68,0x73,0xa3,0x47,1,0x62,0x36,0x79,0x10,
+0x6d,0xa2,0xb9,0x12,0x61,0x69,0x63,0xa3,0xb9,0x10,0x61,0xa2,0x88,0x12,0x73,0x61,
+0x6e,0xa3,0x88,0x61,0xa2,0xb4,0x62,0xa4,0x19,0x63,6,0x6f,0x3d,0x6f,0x5a,0x70,
+0x76,0x75,0x7a,0x79,1,0x70,0x3e,0x72,2,0x69,0x2a,0x6c,0x31,0x73,0xa3,0x44,
+0x13,0x6c,0x6c,0x69,0x63,0x31,0x13,0x72,0x69,0x6f,0x74,0x7f,1,0x6d,0x30,0x70,
+0x10,0x74,0x2e,0x11,0x69,0x63,0x2f,0x12,0x6d,0x6f,0x6e,0x21,0x11,0x72,0x74,0x7f,
+0x16,0x6e,0x65,0x69,0x66,0x6f,0x72,0x6d,0xa3,0x65,0x61,0x32,0x68,0xa2,0x41,0x69,
+0x11,0x72,0x74,0xa3,0x43,3,0x6b,0x4c,0x6e,0x50,0x72,0x76,0x75,0x1d,0x63,0x61,
+0x73,0x69,0x61,0x6e,0x61,0x6c,0x62,0x61,0x6e,0x69,0x61,0x6e,0xa3,0x9f,0x10,0x6d,
+0xa3,0x76,1,0x61,0x24,0x73,0x71,0x1d,0x64,0x69,0x61,0x6e,0x61,0x62,0x6f,0x72,
+0x69,0x67,0x69,0x6e,0x61,0x6c,0x71,0x10,0x69,0xa2,0x68,0x11,0x61,0x6e,0xa3,0x68,
+3,0x61,0x32,0x65,0x44,0x6f,0x52,0x72,0x10,0x73,0xa3,0xbd,1,0x6b,0x26,0x6d,
+0xa3,0x42,0x11,0x6d,0x61,0xa3,0x76,0x10,0x72,0x2c,0x13,0x6f,0x6b,0x65,0x65,0x2d,
+0x16,0x72,0x61,0x73,0x6d,0x69,0x61,0x6e,0xa3,0xbd,6,0x68,0x4a,0x68,0x48,0x6e,
+0x4e,0x72,0x76,0x76,1,0x65,0x2a,0x73,0x10,0x74,0xa3,0x75,0x13,0x73,0x74,0x61,
+0x6e,0xa3,0x75,0x11,0x6f,0x6d,0xa3,0xa1,0x11,0x61,0x74,0x1f,0x6f,0x6c,0x69,0x61,
+0x6e,0x68,0x69,0x65,0x72,0x6f,0x67,0x6c,0x79,0x70,0x68,0x73,0xa3,0x9c,1,0x61,
+0x3e,0x6d,2,0x65,0x2a,0x69,0xa3,0x74,0x6e,0x27,0x13,0x6e,0x69,0x61,0x6e,0x27,
+0x10,0x62,0x24,0x11,0x69,0x63,0x25,0x64,0x30,0x66,0x44,0x67,0x11,0x68,0x62,0xa3,
+0x9f,0x10,0x6c,1,0x61,0x26,0x6d,0xa3,0xa7,0x10,0x6d,0xa3,0xa7,0x11,0x61,0x6b,
+0xa3,0x93,6,0x6c,0x3c,0x6c,0x52,0x6f,0x56,0x72,0x66,0x75,1,0x67,0x30,0x68,
+1,0x64,0x79,0x69,0x10,0x64,0x79,0x10,0x69,0x8e,0x13,0x6e,0x65,0x73,0x65,0x8f,
+0x11,0x69,0x73,0xa1,0x11,0x70,0x6f,0x2a,0x13,0x6d,0x6f,0x66,0x6f,0x2b,0x10,0x61,
+1,0x68,0x2e,0x69,0x7c,0x12,0x6c,0x6c,0x65,0x7d,0xa2,0x41,0x11,0x6d,0x69,0xa3,
+0x41,0x61,0x48,0x65,0x9c,0x68,1,0x61,0x2a,0x6b,0x10,0x73,0xa3,0xa8,0x15,0x69,
+0x6b,0x73,0x75,0x6b,0x69,0xa3,0xa8,3,0x6c,0x3a,0x6d,0x48,0x73,0x54,0x74,1,
+0x61,0x24,0x6b,0x9f,0x10,0x6b,0x9f,0x10,0x69,0x9c,0x13,0x6e,0x65,0x73,0x65,0x9d,
+0x10,0x75,0xa2,0x82,0x10,0x6d,0xa3,0x82,0x10,0x73,0xa2,0x86,0x13,0x61,0x76,0x61,
+0x68,0xa3,0x86,0x11,0x6e,0x67,0x28,0x12,0x61,0x6c,0x69,0x29,3,0x6c,0x42,0x6e,
+0x90,0x74,0xa2,0x46,0x76,0x24,0x17,0x6f,0x77,0x65,0x6c,0x6a,0x61,0x6d,0x6f,0x25,
+0x22,1,0x65,0x54,0x76,0x28,1,0x73,0x38,0x74,0x2a,0x17,0x73,0x79,0x6c,0x6c,
+0x61,0x62,0x6c,0x65,0x2b,0x16,0x79,0x6c,0x6c,0x61,0x62,0x6c,0x65,0x29,0x18,0x61,
+0x64,0x69,0x6e,0x67,0x6a,0x61,0x6d,0x6f,0x23,1,0x61,0x21,0x6f,0x1a,0x74,0x61,
+0x70,0x70,0x6c,0x69,0x63,0x61,0x62,0x6c,0x65,0x21,0x26,0x1a,0x72,0x61,0x69,0x6c,
+0x69,0x6e,0x67,0x6a,0x61,0x6d,0x6f,0x27,1,0x6e,0x2c,0x79,0x22,0x11,0x65,0x73,
+0x23,0x20,0x10,0x6f,0x21,1,0x6e,0x2c,0x79,0x22,0x11,0x65,0x73,0x23,0x20,0x10,
+0x6f,0x21,2,0x6d,0x30,0x6e,0x3a,0x79,0x22,0x11,0x65,0x73,0x23,0x24,0x13,0x61,
+0x79,0x62,0x65,0x25,0x20,0x10,0x6f,0x21,2,0x6d,0x30,0x6e,0x3a,0x79,0x22,0x11,
+0x65,0x73,0x23,0x24,0x13,0x61,0x79,0x62,0x65,0x25,0x20,0x10,0x6f,0x21,0xb,0x72,
+0x39,0x76,0xc,0x76,0x33,0x78,0x2a,0x7a,0x11,0x77,0x6a,0x43,0x10,0x78,0x21,0x72,
+0x28,0x73,0x50,0x74,0x31,1,0x65,0x24,0x69,0x39,0x1e,0x67,0x69,0x6f,0x6e,0x61,
+0x6c,0x69,0x6e,0x64,0x69,0x63,0x61,0x74,0x6f,0x72,0x39,1,0x6d,0x35,0x70,0x18,
+0x61,0x63,0x69,0x6e,0x67,0x6d,0x61,0x72,0x6b,0x35,0x6c,0x1f,0x6c,0x3c,0x6f,0x4a,
+0x70,1,0x70,0x37,0x72,0x14,0x65,0x70,0x65,0x6e,0x64,0x37,0x28,1,0x66,0x2b,
+0x76,0x2c,0x10,0x74,0x2f,0x13,0x74,0x68,0x65,0x72,0x21,0x63,0x4c,0x65,0x64,0x67,
+1,0x61,0x3a,0x6c,0x19,0x75,0x65,0x61,0x66,0x74,0x65,0x72,0x7a,0x77,0x6a,0x41,
+0x10,0x7a,0x41,2,0x6e,0x23,0x6f,0x24,0x72,0x25,0x14,0x6e,0x74,0x72,0x6f,0x6c,
+0x23,2,0x62,0x34,0x6d,0x4e,0x78,0x26,0x13,0x74,0x65,0x6e,0x64,0x27,0x3a,1,
+0x61,0x24,0x67,0x3d,0x11,0x73,0x65,0x3a,0x12,0x67,0x61,0x7a,0x3d,0x3e,0x16,0x6f,
+0x64,0x69,0x66,0x69,0x65,0x72,0x3f,9,0x6e,0x4a,0x6e,0x34,0x6f,0x44,0x73,0x60,
+0x75,0x94,0x78,0x10,0x78,0x21,0x10,0x75,0x2a,0x14,0x6d,0x65,0x72,0x69,0x63,0x2b,
+1,0x6c,0x2c,0x74,0x12,0x68,0x65,0x72,0x21,0x14,0x65,0x74,0x74,0x65,0x72,0x2d,
+3,0x63,0x36,0x65,0x46,0x70,0x31,0x74,0x32,0x12,0x65,0x72,0x6d,0x33,0x3c,0x16,
+0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3d,0x2e,0x10,0x70,0x2f,0x10,0x70,0x34,0x12,
+0x70,0x65,0x72,0x35,0x61,0x46,0x63,0x52,0x65,0x64,0x66,0x72,0x6c,2,0x65,0x2d,
+0x66,0x3b,0x6f,0x28,0x12,0x77,0x65,0x72,0x29,0x10,0x74,0x22,0x12,0x65,0x72,0x6d,
+0x23,1,0x6c,0x24,0x72,0x37,0x24,0x12,0x6f,0x73,0x65,0x25,0x10,0x78,0x38,0x13,
+0x74,0x65,0x6e,0x64,0x39,0x10,0x6f,0x26,0x13,0x72,0x6d,0x61,0x74,0x27,0,0x10,
+0x6c,0x88,0x72,0x40,0x72,0x36,0x73,0x5e,0x77,0x7a,0x78,0x8a,0x7a,0x11,0x77,0x6a,
+0x4b,1,0x65,0x24,0x69,0x3b,0x1e,0x67,0x69,0x6f,0x6e,0x61,0x6c,0x69,0x6e,0x64,
+0x69,0x63,0x61,0x74,0x6f,0x72,0x3b,1,0x69,0x24,0x71,0x3f,0x18,0x6e,0x67,0x6c,
+0x65,0x71,0x75,0x6f,0x74,0x65,0x3f,0x17,0x73,0x65,0x67,0x73,0x70,0x61,0x63,0x65,
+0x4d,0x10,0x78,0x21,0x6c,0x36,0x6d,0x3c,0x6e,0x76,0x6f,0x13,0x74,0x68,0x65,0x72,
+0x21,1,0x65,0x23,0x66,0x35,3,0x62,0x37,0x69,0x28,0x6c,0x29,0x6e,0x2b,0x10,
+0x64,1,0x6c,0x34,0x6e,0x11,0x75,0x6d,0x2a,0x12,0x6c,0x65,0x74,0x37,0x14,0x65,
+0x74,0x74,0x65,0x72,0x29,2,0x65,0x36,0x6c,0x39,0x75,0x2c,0x14,0x6d,0x65,0x72,
+0x69,0x63,0x2d,0x14,0x77,0x6c,0x69,0x6e,0x65,0x39,0x66,0x3f,0x66,0x40,0x67,0x4e,
+0x68,0x70,0x6b,0x10,0x61,0x26,0x15,0x74,0x61,0x6b,0x61,0x6e,0x61,0x27,0x10,0x6f,
+0x24,0x13,0x72,0x6d,0x61,0x74,0x25,1,0x61,0x3a,0x6c,0x19,0x75,0x65,0x61,0x66,
+0x74,0x65,0x72,0x7a,0x77,0x6a,0x49,0x10,0x7a,0x49,1,0x65,0x24,0x6c,0x3d,0x19,
+0x62,0x72,0x65,0x77,0x6c,0x65,0x74,0x74,0x65,0x72,0x3d,0x61,0x86,0x63,0x92,0x64,
+0x94,0x65,2,0x62,0x44,0x6d,0x5e,0x78,0x2e,0x13,0x74,0x65,0x6e,0x64,0x32,0x15,
+0x6e,0x75,0x6d,0x6c,0x65,0x74,0x2f,0x42,1,0x61,0x24,0x67,0x45,0x11,0x73,0x65,
+0x42,0x12,0x67,0x61,0x7a,0x45,0x46,0x16,0x6f,0x64,0x69,0x66,0x69,0x65,0x72,0x47,
+0x15,0x6c,0x65,0x74,0x74,0x65,0x72,0x23,0x10,0x72,0x31,1,0x6f,0x24,0x71,0x41,
+0x18,0x75,0x62,0x6c,0x65,0x71,0x75,0x6f,0x74,0x65,0x41,2,0x63,0x32,0x6e,0x3c,
+0x6f,0x22,0x12,0x70,0x65,0x6e,0x23,0x24,0x13,0x6c,0x6f,0x73,0x65,0x25,0x20,0x12,
+0x6f,0x6e,0x65,0x21,6,0x6f,0x65,0x6f,0x4a,0x72,0x5c,0x74,0x64,0x76,0x1d,0x69,
+0x73,0x75,0x61,0x6c,0x6f,0x72,0x64,0x65,0x72,0x6c,0x65,0x66,0x74,0x3d,0x18,0x76,
+0x65,0x72,0x73,0x74,0x72,0x75,0x63,0x6b,0x2d,0x13,0x69,0x67,0x68,0x74,0x2f,0x11,
+0x6f,0x70,0x30,0x12,0x61,0x6e,0x64,2,0x62,0x32,0x6c,0x62,0x72,0x13,0x69,0x67,
+0x68,0x74,0x3b,0x14,0x6f,0x74,0x74,0x6f,0x6d,0x32,0x12,0x61,0x6e,0x64,1,0x6c,
+0x2e,0x72,0x13,0x69,0x67,0x68,0x74,0x35,0x12,0x65,0x66,0x74,0x3f,0x12,0x65,0x66,
+0x74,0x36,0x17,0x61,0x6e,0x64,0x72,0x69,0x67,0x68,0x74,0x39,0x62,0x2c,0x6c,0x5c,
+0x6e,0x10,0x61,0x21,0x14,0x6f,0x74,0x74,0x6f,0x6d,0x22,0x12,0x61,0x6e,0x64,1,
+0x6c,0x2e,0x72,0x13,0x69,0x67,0x68,0x74,0x27,0x12,0x65,0x66,0x74,0x25,0x12,0x65,
+0x66,0x74,0x28,0x17,0x61,0x6e,0x64,0x72,0x69,0x67,0x68,0x74,0x2b,0xd,0x6e,0xaa,
+0x72,0x70,0x72,0x92,0x73,0xa2,0x46,0x74,0xa2,0x54,0x76,1,0x69,0x60,0x6f,0x12,
+0x77,0x65,0x6c,0x62,1,0x64,0x3a,0x69,0x19,0x6e,0x64,0x65,0x70,0x65,0x6e,0x64,
+0x65,0x6e,0x74,0x67,0x17,0x65,0x70,0x65,0x6e,0x64,0x65,0x6e,0x74,0x65,1,0x72,
+0x2e,0x73,0x13,0x61,0x72,0x67,0x61,0x61,0x12,0x61,0x6d,0x61,0x5f,0x1d,0x65,0x67,
+0x69,0x73,0x74,0x65,0x72,0x73,0x68,0x69,0x66,0x74,0x65,0x72,0x57,0x1e,0x79,0x6c,
+0x6c,0x61,0x62,0x6c,0x65,0x6d,0x6f,0x64,0x69,0x66,0x69,0x65,0x72,0x59,0x12,0x6f,
+0x6e,0x65,1,0x6c,0x2c,0x6d,0x12,0x61,0x72,0x6b,0x5d,0x14,0x65,0x74,0x74,0x65,
+0x72,0x5b,0x6e,0x3c,0x6f,0x7c,0x70,0x18,0x75,0x72,0x65,0x6b,0x69,0x6c,0x6c,0x65,
+0x72,0x55,1,0x6f,0x4c,0x75,1,0x6b,0x3c,0x6d,0x12,0x62,0x65,0x72,0x50,0x15,
+0x6a,0x6f,0x69,0x6e,0x65,0x72,0x53,0x11,0x74,0x61,0x4f,0x16,0x6e,0x6a,0x6f,0x69,
+0x6e,0x65,0x72,0x4d,0x13,0x74,0x68,0x65,0x72,0x21,0x67,0x3e,0x67,0x4a,0x69,0x64,
+0x6a,0x82,0x6d,0x1d,0x6f,0x64,0x69,0x66,0x79,0x69,0x6e,0x67,0x6c,0x65,0x74,0x74,
+0x65,0x72,0x4b,0x1c,0x65,0x6d,0x69,0x6e,0x61,0x74,0x69,0x6f,0x6e,0x6d,0x61,0x72,
+0x6b,0x45,0x1e,0x6e,0x76,0x69,0x73,0x69,0x62,0x6c,0x65,0x73,0x74,0x61,0x63,0x6b,
+0x65,0x72,0x47,0x14,0x6f,0x69,0x6e,0x65,0x72,0x49,0x61,0xa2,0xba,0x62,0xa2,0xc0,
+0x63,1,0x61,0xa2,0xa2,0x6f,0x16,0x6e,0x73,0x6f,0x6e,0x61,0x6e,0x74,0x2a,8,
+0x6b,0x67,0x6b,0x48,0x6d,0x52,0x70,0x5c,0x73,0xa2,0x42,0x77,0x19,0x69,0x74,0x68,
+0x73,0x74,0x61,0x63,0x6b,0x65,0x72,0x43,0x14,0x69,0x6c,0x6c,0x65,0x72,0x35,0x14,
+0x65,0x64,0x69,0x61,0x6c,0x37,1,0x6c,0x52,0x72,0x10,0x65,1,0x63,0x2e,0x66,
+0x13,0x69,0x78,0x65,0x64,0x3d,0x19,0x65,0x64,0x69,0x6e,0x67,0x72,0x65,0x70,0x68,
+0x61,0x3b,0x18,0x61,0x63,0x65,0x68,0x6f,0x6c,0x64,0x65,0x72,0x39,0x10,0x75,1,
+0x62,0x3e,0x63,0x1b,0x63,0x65,0x65,0x64,0x69,0x6e,0x67,0x72,0x65,0x70,0x68,0x61,
+0x41,0x15,0x6a,0x6f,0x69,0x6e,0x65,0x64,0x3f,0x64,0x4c,0x66,0x52,0x68,0x5a,0x69,
+0x1e,0x6e,0x69,0x74,0x69,0x61,0x6c,0x70,0x6f,0x73,0x74,0x66,0x69,0x78,0x65,0x64,
+0x33,0x12,0x65,0x61,0x64,0x2d,0x13,0x69,0x6e,0x61,0x6c,0x2f,0x18,0x65,0x61,0x64,
+0x6c,0x65,0x74,0x74,0x65,0x72,0x31,0x1d,0x6e,0x74,0x69,0x6c,0x6c,0x61,0x74,0x69,
+0x6f,0x6e,0x6d,0x61,0x72,0x6b,0x29,0x16,0x76,0x61,0x67,0x72,0x61,0x68,0x61,0x23,
+1,0x69,0x4a,0x72,0x10,0x61,0x1f,0x68,0x6d,0x69,0x6a,0x6f,0x69,0x6e,0x69,0x6e,
+0x67,0x6e,0x75,0x6d,0x62,0x65,0x72,0x27,0x12,0x6e,0x64,0x75,0x25,2,0x72,0x38,
+0x74,0x46,0x75,0x26,0x15,0x70,0x72,0x69,0x67,0x68,0x74,0x27,0x20,0x15,0x6f,0x74,
+0x61,0x74,0x65,0x64,0x21,1,0x72,0x24,0x75,0x25,0x22,0x18,0x61,0x6e,0x73,0x66,
+0x6f,0x72,0x6d,0x65,0x64,1,0x72,0x32,0x75,0x15,0x70,0x72,0x69,0x67,0x68,0x74,
+0x25,0x15,0x6f,0x74,0x61,0x74,0x65,0x64,0x23,0xd,0x6e,0xc1,0x86,0x73,0xa8,0x73,
+0x4c,0x74,0xa2,0x76,0x75,0xa2,0x83,0x7a,0xd8,0x70,0,2,0x6c,0xd9,0x20,0,
+0x70,0xd9,0x40,0,0x73,0xc3,0,0xfe,0xf,0,0,0,7,0x6f,0x3c,0x6f,
+0xff,8,0,0,0,0x70,0x3a,0x75,0x6e,0x79,0x13,0x6d,0x62,0x6f,0x6c,0xff,
+0xf,0,0,0,0x11,0x61,0x63,1,0x65,0x34,0x69,0x15,0x6e,0x67,0x6d,0x61,
+0x72,0x6b,0xa5,0,0x18,0x73,0x65,0x70,0x61,0x72,0x61,0x74,0x6f,0x72,0xc3,0,
+0x16,0x72,0x72,0x6f,0x67,0x61,0x74,0x65,0xe1,0,0,0x63,0xff,2,0,0,
+0,0x65,0x38,0x6b,0xff,4,0,0,0,0x6d,0xff,1,0,0,0,0x16,
+0x70,0x61,0x72,0x61,0x74,0x6f,0x72,0xd9,0x70,0,0x1d,0x69,0x74,0x6c,0x65,0x63,
+0x61,0x73,0x65,0x6c,0x65,0x74,0x74,0x65,0x72,0x31,1,0x6e,0x40,0x70,0x1c,0x70,
+0x65,0x72,0x63,0x61,0x73,0x65,0x6c,0x65,0x74,0x74,0x65,0x72,0x25,0x17,0x61,0x73,
+0x73,0x69,0x67,0x6e,0x65,0x64,0x23,0x6e,0xa2,0x69,0x6f,0xa2,0x89,0x70,0xfe,0x30,
+0xf8,0,0,9,0x69,0x33,0x69,0xff,0x10,0,0,0,0x6f,0xfd,0x80,0,
+0,0x72,0x54,0x73,0xf9,0,0,0x75,0x12,0x6e,0x63,0x74,0xfe,0x30,0xf8,0,
+0,0x15,0x75,0x61,0x74,0x69,0x6f,0x6e,0xff,0x30,0xf8,0,0,0x17,0x69,0x76,
+0x61,0x74,0x65,0x75,0x73,0x65,0xdd,0,0,0x61,0x48,0x63,0xfd,0x40,0,0,
+0x64,0xe9,0,0,0x65,0xfd,0x20,0,0,0x66,0xff,0x20,0,0,0,0x1f,
+0x72,0x61,0x67,0x72,0x61,0x70,0x68,0x73,0x65,0x70,0x61,0x72,0x61,0x74,0x6f,0x72,
+0xd9,0x40,0,0xbe,0,3,0x64,0xa7,0,0x6c,0xab,0,0x6f,0x30,0x75,0x13,
+0x6d,0x62,0x65,0x72,0xbf,0,0xb2,0,0x1b,0x6e,0x73,0x70,0x61,0x63,0x69,0x6e,
+0x67,0x6d,0x61,0x72,0x6b,0xa1,1,0x70,0x92,0x74,0x12,0x68,0x65,0x72,0xe6,0x80,
+1,3,0x6c,0x40,0x6e,0x4a,0x70,0x56,0x73,0x14,0x79,0x6d,0x62,0x6f,0x6c,0xff,
+8,0,0,0,0x14,0x65,0x74,0x74,0x65,0x72,0x61,0x14,0x75,0x6d,0x62,0x65,
+0x72,0xb3,0,0x19,0x75,0x6e,0x63,0x74,0x75,0x61,0x74,0x69,0x6f,0x6e,0xfd,0x80,
+0,0,0x1c,0x65,0x6e,0x70,0x75,0x6e,0x63,0x74,0x75,0x61,0x74,0x69,0x6f,0x6e,
+0xf9,0,0,0x66,0xc0,0xc4,0x66,0xa2,0x47,0x69,0xa2,0x64,0x6c,0xa2,0x79,0x6d,
+0xa4,0xc0,4,0x61,0x6c,0x63,0xa5,0,0x65,0xa3,0x80,0x6e,0xa1,0x6f,0x15,0x64,
+0x69,0x66,0x69,0x65,0x72,1,0x6c,0x38,0x73,0x14,0x79,0x6d,0x62,0x6f,0x6c,0xff,
+4,0,0,0,0x14,0x65,0x74,0x74,0x65,0x72,0x41,1,0x72,0x3c,0x74,0x16,
+0x68,0x73,0x79,0x6d,0x62,0x6f,0x6c,0xff,1,0,0,0,0x10,0x6b,0xa5,0xc0,
+1,0x69,0x32,0x6f,0x13,0x72,0x6d,0x61,0x74,0xdb,0,0,0x1d,0x6e,0x61,0x6c,
+0x70,0x75,0x6e,0x63,0x74,0x75,0x61,0x74,0x69,0x6f,0x6e,0xff,0x20,0,0,0,
+0x10,0x6e,0x1f,0x69,0x74,0x69,0x61,0x6c,0x70,0x75,0x6e,0x63,0x74,0x75,0x61,0x74,
+0x69,0x6f,0x6e,0xff,0x10,0,0,0,0x9c,7,0x6d,0x18,0x6d,0x41,0x6f,0x28,
+0x74,0x31,0x75,0x25,0x60,0x1c,0x77,0x65,0x72,0x63,0x61,0x73,0x65,0x6c,0x65,0x74,
+0x74,0x65,0x72,0x29,0x63,0x3d,0x65,0x28,0x69,0x42,0x6c,0x29,0x13,0x74,0x74,0x65,
+0x72,0x9c,0x15,0x6e,0x75,0x6d,0x62,0x65,0x72,0xab,0,0x1a,0x6e,0x65,0x73,0x65,
+0x70,0x61,0x72,0x61,0x74,0x6f,0x72,0xd9,0x20,0,0x63,0x46,0x64,0xa2,0x96,0x65,
+0x1b,0x6e,0x63,0x6c,0x6f,0x73,0x69,0x6e,0x67,0x6d,0x61,0x72,0x6b,0xa3,0x80,0xe6,
+0x80,1,7,0x6e,0x57,0x6e,0x52,0x6f,0x5e,0x73,0xe1,0,0,0x75,0x1b,0x72,
+0x72,0x65,0x6e,0x63,0x79,0x73,0x79,0x6d,0x62,0x6f,0x6c,0xff,2,0,0,0,
+0x22,0x12,0x74,0x72,0x6c,0xd9,0x80,0,0xdc,0,0,1,0x6d,0x62,0x6e,1,
+0x6e,0x30,0x74,0x12,0x72,0x6f,0x6c,0xd9,0x80,0,0x1f,0x65,0x63,0x74,0x6f,0x72,
+0x70,0x75,0x6e,0x63,0x74,0x75,0x61,0x74,0x69,0x6f,0x6e,0xfd,0x40,0,0,0x19,
+0x62,0x69,0x6e,0x69,0x6e,0x67,0x6d,0x61,0x72,0x6b,0xa5,0xc0,0x61,0x58,0x63,0xd9,
+0x80,0,0x66,0xdb,0,0,0x6c,0x1d,0x6f,0x73,0x65,0x70,0x75,0x6e,0x63,0x74,
+0x75,0x61,0x74,0x69,0x6f,0x6e,0xfd,0x20,0,0,0x18,0x73,0x65,0x64,0x6c,0x65,
+0x74,0x74,0x65,0x72,0x3d,2,0x61,0x32,0x65,0x50,0x69,0x12,0x67,0x69,0x74,0xa7,
+0,0x1c,0x73,0x68,0x70,0x75,0x6e,0x63,0x74,0x75,0x61,0x74,0x69,0x6f,0x6e,0xe9,
+0,0,0x1a,0x63,0x69,0x6d,0x61,0x6c,0x6e,0x75,0x6d,0x62,0x65,0x72,0xa7,0
 };
 
-const char PropNameData::nameGroups[17897]={
+const char PropNameData::nameGroups[22098]={
 2,'A','l','p','h','a',0,'A','l','p','h','a','b','e','t','i','c',0,
 4,'N',0,'N','o',0,'F',0,'F','a','l','s','e',0,4,'Y',0,'Y','e','s',0,'T',0,'T','r','u','e',0,
 2,'N','R',0,'N','o','t','_','R','e','o','r','d','e','r','e','d',0,
-2,'O','V',0,'O','v','e','r','l','a','y',0,2,'N','K',0,'N','u','k','t','a',0,
-2,'K','V',0,'K','a','n','a','_','V','o','i','c','i','n','g',0,
+2,'O','V',0,'O','v','e','r','l','a','y',0,2,'H','A','N','R',0,'H','a','n','_','R','e','a','d','i','n','g',0,
+2,'N','K',0,'N','u','k','t','a',0,2,'K','V',0,'K','a','n','a','_','V','o','i','c','i','n','g',0,
 2,'V','R',0,'V','i','r','a','m','a',0,2,'C','C','C','1','0',0,'C','C','C','1','0',0,
 2,'C','C','C','1','1',0,'C','C','C','1','1',0,2,'C','C','C','1','2',0,'C','C','C','1','2',0,
 2,'C','C','C','1','3',0,'C','C','C','1','3',0,2,'C','C','C','1','4',0,'C','C','C','1','4',0,
@@ -956,8 +1111,9 @@
 2,'X','I','D','C',0,'X','I','D','_','C','o','n','t','i','n','u','e',0,
 2,'X','I','D','S',0,'X','I','D','_','S','t','a','r','t',0,
 2,'S','e','n','s','i','t','i','v','e',0,'C','a','s','e','_','S','e','n','s','i','t','i','v','e',0,
-2,'S','T','e','r','m',0,'S','T','e','r','m',0,2,'V','S',0,'V','a','r','i','a','t','i','o','n','_','S','e','l','e','c',
-'t','o','r',0,2,'n','f','d','i','n','e','r','t',0,'N','F','D','_','I','n','e','r','t',0,
+2,'S','T','e','r','m',0,'S','e','n','t','e','n','c','e','_','T','e','r','m','i','n','a','l',0,
+2,'V','S',0,'V','a','r','i','a','t','i','o','n','_','S','e','l','e','c','t','o','r',0,
+2,'n','f','d','i','n','e','r','t',0,'N','F','D','_','I','n','e','r','t',0,
 2,'n','f','k','d','i','n','e','r','t',0,'N','F','K','D','_','I','n','e','r','t',0,
 2,'n','f','c','i','n','e','r','t',0,'N','F','C','_','I','n','e','r','t',0,
 2,'n','f','k','c','i','n','e','r','t',0,'N','F','K','C','_','I','n','e','r','t',0,
@@ -975,11 +1131,15 @@
 2,'C','W','C','M',0,'C','h','a','n','g','e','s','_','W','h','e','n','_','C','a','s','e','m','a','p','p','e','d',0,
 2,'C','W','K','C','F',0,'C','h','a','n','g','e','s','_','W','h','e','n','_','N','F','K','C','_','C','a','s','e','f','o','l',
 'd','e','d',0,2,'E','m','o','j','i',0,'E','m','o','j','i',0,
-2,'E','m','o','j','i','_','P','r','e','s','e','n','t','a','t','i','o','n',0,'E','m','o','j','i','_','P','r','e','s','e','n',
-'t','a','t','i','o','n',0,2,'E','m','o','j','i','_','M','o','d','i','f','i','e','r',0,'E','m','o','j','i','_','M','o','d',
-'i','f','i','e','r',0,2,'E','m','o','j','i','_','M','o','d','i','f','i','e','r','_','B','a','s','e',0,
-'E','m','o','j','i','_','M','o','d','i','f','i','e','r','_','B','a','s','e',0,
-2,'b','c',0,'B','i','d','i','_','C','l','a','s','s',0,2,'L',0,'L','e','f','t','_','T','o','_','R','i','g','h','t',0,
+2,'E','P','r','e','s',0,'E','m','o','j','i','_','P','r','e','s','e','n','t','a','t','i','o','n',0,
+2,'E','M','o','d',0,'E','m','o','j','i','_','M','o','d','i','f','i','e','r',0,
+2,'E','B','a','s','e',0,'E','m','o','j','i','_','M','o','d','i','f','i','e','r','_','B','a','s','e',0,
+2,'E','C','o','m','p',0,'E','m','o','j','i','_','C','o','m','p','o','n','e','n','t',0,
+2,'R','I',0,'R','e','g','i','o','n','a','l','_','I','n','d','i','c','a','t','o','r',0,
+2,'P','C','M',0,'P','r','e','p','e','n','d','e','d','_','C','o','n','c','a','t','e','n','a','t','i','o','n','_','M','a','r',
+'k',0,2,'E','x','t','P','i','c','t',0,'E','x','t','e','n','d','e','d','_','P','i','c','t','o','g','r','a','p','h','i','c',
+0,2,'b','c',0,'B','i','d','i','_','C','l','a','s','s',0,
+2,'L',0,'L','e','f','t','_','T','o','_','R','i','g','h','t',0,
 2,'R',0,'R','i','g','h','t','_','T','o','_','L','e','f','t',0,
 2,'E','N',0,'E','u','r','o','p','e','a','n','_','N','u','m','b','e','r',0,
 2,'E','S',0,'E','u','r','o','p','e','a','n','_','S','e','p','a','r','a','t','o','r',0,
@@ -1299,9 +1459,59 @@
 's',0,'S','u','p','p','l','e','m','e','n','t','a','l','_','S','y','m','b','o','l','s','_','A','n','d','_','P','i','c','t','o',
 'g','r','a','p','h','s',0,2,'S','u','t','t','o','n','_','S','i','g','n','W','r','i','t','i','n','g',0,
 'S','u','t','t','o','n','_','S','i','g','n','W','r','i','t','i','n','g',0,
-2,'c','c','c',0,'C','a','n','o','n','i','c','a','l','_','C','o','m','b','i','n','i','n','g','_','C','l','a','s','s',0,
-2,'d','t',0,'D','e','c','o','m','p','o','s','i','t','i','o','n','_','T','y','p','e',0,
-3,'N','o','n','e',0,'N','o','n','e',0,'n','o','n','e',0,
+2,'A','d','l','a','m',0,'A','d','l','a','m',0,2,'B','h','a','i','k','s','u','k','i',0,
+'B','h','a','i','k','s','u','k','i',0,2,'C','y','r','i','l','l','i','c','_','E','x','t','_','C',0,
+'C','y','r','i','l','l','i','c','_','E','x','t','e','n','d','e','d','_','C',0,
+2,'G','l','a','g','o','l','i','t','i','c','_','S','u','p',0,'G','l','a','g','o','l','i','t','i','c','_','S','u','p','p','l',
+'e','m','e','n','t',0,2,'I','d','e','o','g','r','a','p','h','i','c','_','S','y','m','b','o','l','s',0,
+'I','d','e','o','g','r','a','p','h','i','c','_','S','y','m','b','o','l','s','_','A','n','d','_','P','u','n','c','t','u','a','t',
+'i','o','n',0,2,'M','a','r','c','h','e','n',0,'M','a','r','c','h','e','n',0,
+2,'M','o','n','g','o','l','i','a','n','_','S','u','p',0,'M','o','n','g','o','l','i','a','n','_','S','u','p','p','l','e','m',
+'e','n','t',0,2,'N','e','w','a',0,'N','e','w','a',0,2,'O','s','a','g','e',0,'O','s','a','g','e',0,
+2,'T','a','n','g','u','t',0,'T','a','n','g','u','t',0,2,'T','a','n','g','u','t','_','C','o','m','p','o','n','e','n','t',
+'s',0,'T','a','n','g','u','t','_','C','o','m','p','o','n','e','n','t','s',0,
+2,'C','J','K','_','E','x','t','_','F',0,'C','J','K','_','U','n','i','f','i','e','d','_','I','d','e','o','g','r','a','p','h',
+'s','_','E','x','t','e','n','s','i','o','n','_','F',0,2,'K','a','n','a','_','E','x','t','_','A',0,
+'K','a','n','a','_','E','x','t','e','n','d','e','d','_','A',0,
+2,'M','a','s','a','r','a','m','_','G','o','n','d','i',0,'M','a','s','a','r','a','m','_','G','o','n','d','i',0,
+2,'N','u','s','h','u',0,'N','u','s','h','u',0,2,'S','o','y','o','m','b','o',0,'S','o','y','o','m','b','o',0,
+2,'S','y','r','i','a','c','_','S','u','p',0,'S','y','r','i','a','c','_','S','u','p','p','l','e','m','e','n','t',0,
+2,'Z','a','n','a','b','a','z','a','r','_','S','q','u','a','r','e',0,'Z','a','n','a','b','a','z','a','r','_','S','q','u','a',
+'r','e',0,2,'C','h','e','s','s','_','S','y','m','b','o','l','s',0,'C','h','e','s','s','_','S','y','m','b','o','l','s',0,
+2,'D','o','g','r','a',0,'D','o','g','r','a',0,2,'G','e','o','r','g','i','a','n','_','E','x','t',0,
+'G','e','o','r','g','i','a','n','_','E','x','t','e','n','d','e','d',0,
+2,'G','u','n','j','a','l','a','_','G','o','n','d','i',0,'G','u','n','j','a','l','a','_','G','o','n','d','i',0,
+2,'H','a','n','i','f','i','_','R','o','h','i','n','g','y','a',0,'H','a','n','i','f','i','_','R','o','h','i','n','g','y','a',
+0,2,'I','n','d','i','c','_','S','i','y','a','q','_','N','u','m','b','e','r','s',0,'I','n','d','i','c','_','S','i','y','a',
+'q','_','N','u','m','b','e','r','s',0,2,'M','a','k','a','s','a','r',0,'M','a','k','a','s','a','r',0,
+2,'M','a','y','a','n','_','N','u','m','e','r','a','l','s',0,'M','a','y','a','n','_','N','u','m','e','r','a','l','s',0,
+2,'M','e','d','e','f','a','i','d','r','i','n',0,'M','e','d','e','f','a','i','d','r','i','n',0,
+2,'O','l','d','_','S','o','g','d','i','a','n',0,'O','l','d','_','S','o','g','d','i','a','n',0,
+2,'S','o','g','d','i','a','n',0,'S','o','g','d','i','a','n',0,
+2,'E','g','y','p','t','i','a','n','_','H','i','e','r','o','g','l','y','p','h','_','F','o','r','m','a','t','_','C','o','n','t',
+'r','o','l','s',0,'E','g','y','p','t','i','a','n','_','H','i','e','r','o','g','l','y','p','h','_','F','o','r','m','a','t','_',
+'C','o','n','t','r','o','l','s',0,2,'E','l','y','m','a','i','c',0,'E','l','y','m','a','i','c',0,
+2,'N','a','n','d','i','n','a','g','a','r','i',0,'N','a','n','d','i','n','a','g','a','r','i',0,
+2,'N','y','i','a','k','e','n','g','_','P','u','a','c','h','u','e','_','H','m','o','n','g',0,
+'N','y','i','a','k','e','n','g','_','P','u','a','c','h','u','e','_','H','m','o','n','g',0,
+2,'O','t','t','o','m','a','n','_','S','i','y','a','q','_','N','u','m','b','e','r','s',0,'O','t','t','o','m','a','n','_','S',
+'i','y','a','q','_','N','u','m','b','e','r','s',0,2,'S','m','a','l','l','_','K','a','n','a','_','E','x','t',0,
+'S','m','a','l','l','_','K','a','n','a','_','E','x','t','e','n','s','i','o','n',0,
+2,'S','y','m','b','o','l','s','_','A','n','d','_','P','i','c','t','o','g','r','a','p','h','s','_','E','x','t','_','A',0,
+'S','y','m','b','o','l','s','_','A','n','d','_','P','i','c','t','o','g','r','a','p','h','s','_','E','x','t','e','n','d','e','d',
+'_','A',0,2,'T','a','m','i','l','_','S','u','p',0,'T','a','m','i','l','_','S','u','p','p','l','e','m','e','n','t',0,
+2,'W','a','n','c','h','o',0,'W','a','n','c','h','o',0,2,'C','h','o','r','a','s','m','i','a','n',0,
+'C','h','o','r','a','s','m','i','a','n',0,2,'C','J','K','_','E','x','t','_','G',0,'C','J','K','_','U','n','i','f','i','e',
+'d','_','I','d','e','o','g','r','a','p','h','s','_','E','x','t','e','n','s','i','o','n','_','G',0,
+2,'D','i','v','e','s','_','A','k','u','r','u',0,'D','i','v','e','s','_','A','k','u','r','u',0,
+2,'K','h','i','t','a','n','_','S','m','a','l','l','_','S','c','r','i','p','t',0,'K','h','i','t','a','n','_','S','m','a','l',
+'l','_','S','c','r','i','p','t',0,2,'L','i','s','u','_','S','u','p',0,'L','i','s','u','_','S','u','p','p','l','e','m','e',
+'n','t',0,2,'S','y','m','b','o','l','s','_','F','o','r','_','L','e','g','a','c','y','_','C','o','m','p','u','t','i','n','g',
+0,'S','y','m','b','o','l','s','_','F','o','r','_','L','e','g','a','c','y','_','C','o','m','p','u','t','i','n','g',0,
+2,'T','a','n','g','u','t','_','S','u','p',0,'T','a','n','g','u','t','_','S','u','p','p','l','e','m','e','n','t',0,
+2,'Y','e','z','i','d','i',0,'Y','e','z','i','d','i',0,2,'c','c','c',0,'C','a','n','o','n','i','c','a','l','_','C','o',
+'m','b','i','n','i','n','g','_','C','l','a','s','s',0,2,'d','t',0,'D','e','c','o','m','p','o','s','i','t','i','o','n','_',
+'T','y','p','e',0,3,'N','o','n','e',0,'N','o','n','e',0,'n','o','n','e',0,
 3,'C','a','n',0,'C','a','n','o','n','i','c','a','l',0,'c','a','n',0,
 3,'C','o','m',0,'C','o','m','p','a','t',0,'c','o','m',0,
 3,'E','n','c',0,'C','i','r','c','l','e',0,'e','n','c',0,
@@ -1417,7 +1627,24 @@
 2,'M','a','n','i','c','h','a','e','a','n','_','Y','o','d','h',0,'M','a','n','i','c','h','a','e','a','n','_','Y','o','d','h',
 0,2,'M','a','n','i','c','h','a','e','a','n','_','Z','a','y','i','n',0,'M','a','n','i','c','h','a','e','a','n','_','Z','a',
 'y','i','n',0,2,'S','t','r','a','i','g','h','t','_','W','a','w',0,'S','t','r','a','i','g','h','t','_','W','a','w',0,
-2,'j','t',0,'J','o','i','n','i','n','g','_','T','y','p','e',0,
+2,'A','f','r','i','c','a','n','_','F','e','h',0,'A','f','r','i','c','a','n','_','F','e','h',0,
+2,'A','f','r','i','c','a','n','_','N','o','o','n',0,'A','f','r','i','c','a','n','_','N','o','o','n',0,
+2,'A','f','r','i','c','a','n','_','Q','a','f',0,'A','f','r','i','c','a','n','_','Q','a','f',0,
+2,'M','a','l','a','y','a','l','a','m','_','B','h','a',0,'M','a','l','a','y','a','l','a','m','_','B','h','a',0,
+2,'M','a','l','a','y','a','l','a','m','_','J','a',0,'M','a','l','a','y','a','l','a','m','_','J','a',0,
+2,'M','a','l','a','y','a','l','a','m','_','L','l','a',0,'M','a','l','a','y','a','l','a','m','_','L','l','a',0,
+2,'M','a','l','a','y','a','l','a','m','_','L','l','l','a',0,'M','a','l','a','y','a','l','a','m','_','L','l','l','a',0,
+2,'M','a','l','a','y','a','l','a','m','_','N','g','a',0,'M','a','l','a','y','a','l','a','m','_','N','g','a',0,
+2,'M','a','l','a','y','a','l','a','m','_','N','n','a',0,'M','a','l','a','y','a','l','a','m','_','N','n','a',0,
+2,'M','a','l','a','y','a','l','a','m','_','N','n','n','a',0,'M','a','l','a','y','a','l','a','m','_','N','n','n','a',0,
+2,'M','a','l','a','y','a','l','a','m','_','N','y','a',0,'M','a','l','a','y','a','l','a','m','_','N','y','a',0,
+2,'M','a','l','a','y','a','l','a','m','_','R','a',0,'M','a','l','a','y','a','l','a','m','_','R','a',0,
+2,'M','a','l','a','y','a','l','a','m','_','S','s','a',0,'M','a','l','a','y','a','l','a','m','_','S','s','a',0,
+2,'M','a','l','a','y','a','l','a','m','_','T','t','a',0,'M','a','l','a','y','a','l','a','m','_','T','t','a',0,
+2,'H','a','n','i','f','i','_','R','o','h','i','n','g','y','a','_','K','i','n','n','a','_','Y','a',0,
+'H','a','n','i','f','i','_','R','o','h','i','n','g','y','a','_','K','i','n','n','a','_','Y','a',0,
+2,'H','a','n','i','f','i','_','R','o','h','i','n','g','y','a','_','P','a',0,'H','a','n','i','f','i','_','R','o','h','i','n',
+'g','y','a','_','P','a',0,2,'j','t',0,'J','o','i','n','i','n','g','_','T','y','p','e',0,
 2,'U',0,'N','o','n','_','J','o','i','n','i','n','g',0,2,'C',0,'J','o','i','n','_','C','a','u','s','i','n','g',0,
 2,'D',0,'D','u','a','l','_','J','o','i','n','i','n','g',0,
 2,'L',0,'L','e','f','t','_','J','o','i','n','i','n','g',0,
@@ -1450,8 +1677,8 @@
 2,'J','T',0,'J','T',0,2,'J','V',0,'J','V',0,2,'C','P',0,'C','l','o','s','e','_','P','a','r','e','n','t','h','e',
 's','i','s',0,2,'C','J',0,'C','o','n','d','i','t','i','o','n','a','l','_','J','a','p','a','n','e','s','e','_','S','t','a',
 'r','t','e','r',0,2,'H','L',0,'H','e','b','r','e','w','_','L','e','t','t','e','r',0,
-2,'R','I',0,'R','e','g','i','o','n','a','l','_','I','n','d','i','c','a','t','o','r',0,
-2,'n','t',0,'N','u','m','e','r','i','c','_','T','y','p','e',0,
+2,'E','B',0,'E','_','B','a','s','e',0,2,'E','M',0,'E','_','M','o','d','i','f','i','e','r',0,
+2,'Z','W','J',0,'Z','W','J',0,2,'n','t',0,'N','u','m','e','r','i','c','_','T','y','p','e',0,
 2,'N','o','n','e',0,'N','o','n','e',0,2,'D','e',0,'D','e','c','i','m','a','l',0,
 2,'D','i',0,'D','i','g','i','t',0,2,'N','u',0,'N','u','m','e','r','i','c',0,
 2,'s','c',0,'S','c','r','i','p','t',0,2,'Z','y','y','y',0,'C','o','m','m','o','n',0,
@@ -1543,17 +1770,33 @@
 2,'S','i','n','d',0,'K','h','u','d','a','w','a','d','i',0,
 2,'W','a','r','a',0,'W','a','r','a','n','g','_','C','i','t','i',0,
 2,'A','f','a','k',0,'A','f','a','k',0,2,'J','u','r','c',0,'J','u','r','c',0,
-2,'M','r','o','o',0,'M','r','o',0,2,'N','s','h','u',0,'N','s','h','u',0,
+2,'M','r','o','o',0,'M','r','o',0,2,'N','s','h','u',0,'N','u','s','h','u',0,
 2,'S','h','r','d',0,'S','h','a','r','a','d','a',0,2,'S','o','r','a',0,'S','o','r','a','_','S','o','m','p','e','n','g',
-0,2,'T','a','k','r',0,'T','a','k','r','i',0,2,'T','a','n','g',0,'T','a','n','g',0,
+0,2,'T','a','k','r',0,'T','a','k','r','i',0,2,'T','a','n','g',0,'T','a','n','g','u','t',0,
 2,'W','o','l','e',0,'W','o','l','e',0,2,'H','l','u','w',0,'A','n','a','t','o','l','i','a','n','_','H','i','e','r','o',
 'g','l','y','p','h','s',0,2,'K','h','o','j',0,'K','h','o','j','k','i',0,
 2,'T','i','r','h',0,'T','i','r','h','u','t','a',0,2,'A','g','h','b',0,'C','a','u','c','a','s','i','a','n','_','A','l',
 'b','a','n','i','a','n',0,2,'M','a','h','j',0,'M','a','h','a','j','a','n','i',0,
 2,'H','a','t','r',0,'H','a','t','r','a','n',0,2,'M','u','l','t',0,'M','u','l','t','a','n','i',0,
 2,'P','a','u','c',0,'P','a','u','_','C','i','n','_','H','a','u',0,
-2,'S','i','d','d',0,'S','i','d','d','h','a','m',0,2,'h','s','t',0,'H','a','n','g','u','l','_','S','y','l','l','a','b',
-'l','e','_','T','y','p','e',0,2,'N','A',0,'N','o','t','_','A','p','p','l','i','c','a','b','l','e',0,
+2,'S','i','d','d',0,'S','i','d','d','h','a','m',0,2,'A','d','l','m',0,'A','d','l','a','m',0,
+2,'B','h','k','s',0,'B','h','a','i','k','s','u','k','i',0,
+2,'M','a','r','c',0,'M','a','r','c','h','e','n',0,2,'O','s','g','e',0,'O','s','a','g','e',0,
+2,'H','a','n','b',0,'H','a','n','b',0,2,'J','a','m','o',0,'J','a','m','o',0,
+2,'Z','s','y','e',0,'Z','s','y','e',0,2,'G','o','n','m',0,'M','a','s','a','r','a','m','_','G','o','n','d','i',0,
+2,'S','o','y','o',0,'S','o','y','o','m','b','o',0,2,'Z','a','n','b',0,'Z','a','n','a','b','a','z','a','r','_','S','q',
+'u','a','r','e',0,2,'D','o','g','r',0,'D','o','g','r','a',0,
+2,'G','o','n','g',0,'G','u','n','j','a','l','a','_','G','o','n','d','i',0,
+2,'M','a','k','a',0,'M','a','k','a','s','a','r',0,2,'M','e','d','f',0,'M','e','d','e','f','a','i','d','r','i','n',0,
+2,'R','o','h','g',0,'H','a','n','i','f','i','_','R','o','h','i','n','g','y','a',0,
+2,'S','o','g','d',0,'S','o','g','d','i','a','n',0,2,'S','o','g','o',0,'O','l','d','_','S','o','g','d','i','a','n',0,
+2,'E','l','y','m',0,'E','l','y','m','a','i','c',0,2,'H','m','n','p',0,'N','y','i','a','k','e','n','g','_','P','u','a',
+'c','h','u','e','_','H','m','o','n','g',0,2,'N','a','n','d',0,'N','a','n','d','i','n','a','g','a','r','i',0,
+2,'W','c','h','o',0,'W','a','n','c','h','o',0,2,'C','h','r','s',0,'C','h','o','r','a','s','m','i','a','n',0,
+2,'D','i','a','k',0,'D','i','v','e','s','_','A','k','u','r','u',0,
+2,'K','i','t','s',0,'K','h','i','t','a','n','_','S','m','a','l','l','_','S','c','r','i','p','t',0,
+2,'Y','e','z','i',0,'Y','e','z','i','d','i',0,2,'h','s','t',0,'H','a','n','g','u','l','_','S','y','l','l','a','b','l',
+'e','_','T','y','p','e',0,2,'N','A',0,'N','o','t','_','A','p','p','l','i','c','a','b','l','e',0,
 2,'L',0,'L','e','a','d','i','n','g','_','J','a','m','o',0,
 2,'V',0,'V','o','w','e','l','_','J','a','m','o',0,2,'T',0,'T','r','a','i','l','i','n','g','_','J','a','m','o',0,
 2,'L','V',0,'L','V','_','S','y','l','l','a','b','l','e',0,
@@ -1570,7 +1813,9 @@
 2,'E','X',0,'E','x','t','e','n','d',0,2,'L',0,'L',0,
 2,'L','F',0,'L','F',0,2,'L','V',0,'L','V',0,2,'L','V','T',0,'L','V','T',0,
 2,'T',0,'T',0,2,'V',0,'V',0,2,'S','M',0,'S','p','a','c','i','n','g','M','a','r','k',0,
-2,'P','P',0,'P','r','e','p','e','n','d',0,2,'S','B',0,'S','e','n','t','e','n','c','e','_','B','r','e','a','k',0,
+2,'P','P',0,'P','r','e','p','e','n','d',0,2,'E','B','G',0,'E','_','B','a','s','e','_','G','A','Z',0,
+2,'G','A','Z',0,'G','l','u','e','_','A','f','t','e','r','_','Z','w','j',0,
+2,'S','B',0,'S','e','n','t','e','n','c','e','_','B','r','e','a','k',0,
 2,'A','T',0,'A','T','e','r','m',0,2,'C','L',0,'C','l','o','s','e',0,
 2,'F','O',0,'F','o','r','m','a','t',0,2,'L','O',0,'L','o','w','e','r',0,
 2,'L','E',0,'O','L','e','t','t','e','r',0,2,'S','E',0,'S','e','p',0,
@@ -1582,10 +1827,73 @@
 2,'E','x','t','e','n','d',0,'E','x','t','e','n','d',0,2,'M','B',0,'M','i','d','N','u','m','L','e','t',0,
 2,'N','L',0,'N','e','w','l','i','n','e',0,2,'S','Q',0,'S','i','n','g','l','e','_','Q','u','o','t','e',0,
 2,'D','Q',0,'D','o','u','b','l','e','_','Q','u','o','t','e',0,
+2,'W','S','e','g','S','p','a','c','e',0,'W','S','e','g','S','p','a','c','e',0,
 2,'b','p','t',0,'B','i','d','i','_','P','a','i','r','e','d','_','B','r','a','c','k','e','t','_','T','y','p','e',0,
 2,'n',0,'N','o','n','e',0,2,'o',0,'O','p','e','n',0,
-2,'c',0,'C','l','o','s','e',0,2,'g','c','m',0,'G','e','n','e','r','a','l','_','C','a','t','e','g','o','r','y','_','M',
-'a','s','k',0,2,'C',0,'O','t','h','e','r',0,2,'L',0,'L','e','t','t','e','r',0,
+2,'c',0,'C','l','o','s','e',0,2,'I','n','P','C',0,'I','n','d','i','c','_','P','o','s','i','t','i','o','n','a','l','_',
+'C','a','t','e','g','o','r','y',0,2,'N','A',0,'N','A',0,
+2,'B','o','t','t','o','m',0,'B','o','t','t','o','m',0,2,'B','o','t','t','o','m','_','A','n','d','_','L','e','f','t',0,
+'B','o','t','t','o','m','_','A','n','d','_','L','e','f','t',0,
+2,'B','o','t','t','o','m','_','A','n','d','_','R','i','g','h','t',0,'B','o','t','t','o','m','_','A','n','d','_','R','i','g',
+'h','t',0,2,'L','e','f','t',0,'L','e','f','t',0,2,'L','e','f','t','_','A','n','d','_','R','i','g','h','t',0,
+'L','e','f','t','_','A','n','d','_','R','i','g','h','t',0,2,'O','v','e','r','s','t','r','u','c','k',0,
+'O','v','e','r','s','t','r','u','c','k',0,2,'R','i','g','h','t',0,'R','i','g','h','t',0,
+2,'T','o','p',0,'T','o','p',0,2,'T','o','p','_','A','n','d','_','B','o','t','t','o','m',0,
+'T','o','p','_','A','n','d','_','B','o','t','t','o','m',0,2,'T','o','p','_','A','n','d','_','B','o','t','t','o','m','_','A',
+'n','d','_','R','i','g','h','t',0,'T','o','p','_','A','n','d','_','B','o','t','t','o','m','_','A','n','d','_','R','i','g','h',
+'t',0,2,'T','o','p','_','A','n','d','_','L','e','f','t',0,'T','o','p','_','A','n','d','_','L','e','f','t',0,
+2,'T','o','p','_','A','n','d','_','L','e','f','t','_','A','n','d','_','R','i','g','h','t',0,
+'T','o','p','_','A','n','d','_','L','e','f','t','_','A','n','d','_','R','i','g','h','t',0,
+2,'T','o','p','_','A','n','d','_','R','i','g','h','t',0,'T','o','p','_','A','n','d','_','R','i','g','h','t',0,
+2,'V','i','s','u','a','l','_','O','r','d','e','r','_','L','e','f','t',0,'V','i','s','u','a','l','_','O','r','d','e','r','_',
+'L','e','f','t',0,2,'T','o','p','_','A','n','d','_','B','o','t','t','o','m','_','A','n','d','_','L','e','f','t',0,
+'T','o','p','_','A','n','d','_','B','o','t','t','o','m','_','A','n','d','_','L','e','f','t',0,
+2,'I','n','S','C',0,'I','n','d','i','c','_','S','y','l','l','a','b','i','c','_','C','a','t','e','g','o','r','y',0,
+2,'O','t','h','e','r',0,'O','t','h','e','r',0,2,'A','v','a','g','r','a','h','a',0,'A','v','a','g','r','a','h','a',0,
+2,'B','i','n','d','u',0,'B','i','n','d','u',0,2,'B','r','a','h','m','i','_','J','o','i','n','i','n','g','_','N','u','m',
+'b','e','r',0,'B','r','a','h','m','i','_','J','o','i','n','i','n','g','_','N','u','m','b','e','r',0,
+2,'C','a','n','t','i','l','l','a','t','i','o','n','_','M','a','r','k',0,'C','a','n','t','i','l','l','a','t','i','o','n','_',
+'M','a','r','k',0,2,'C','o','n','s','o','n','a','n','t',0,'C','o','n','s','o','n','a','n','t',0,
+2,'C','o','n','s','o','n','a','n','t','_','D','e','a','d',0,'C','o','n','s','o','n','a','n','t','_','D','e','a','d',0,
+2,'C','o','n','s','o','n','a','n','t','_','F','i','n','a','l',0,'C','o','n','s','o','n','a','n','t','_','F','i','n','a','l',
+0,2,'C','o','n','s','o','n','a','n','t','_','H','e','a','d','_','L','e','t','t','e','r',0,
+'C','o','n','s','o','n','a','n','t','_','H','e','a','d','_','L','e','t','t','e','r',0,
+2,'C','o','n','s','o','n','a','n','t','_','I','n','i','t','i','a','l','_','P','o','s','t','f','i','x','e','d',0,
+'C','o','n','s','o','n','a','n','t','_','I','n','i','t','i','a','l','_','P','o','s','t','f','i','x','e','d',0,
+2,'C','o','n','s','o','n','a','n','t','_','K','i','l','l','e','r',0,'C','o','n','s','o','n','a','n','t','_','K','i','l','l',
+'e','r',0,2,'C','o','n','s','o','n','a','n','t','_','M','e','d','i','a','l',0,'C','o','n','s','o','n','a','n','t','_','M',
+'e','d','i','a','l',0,2,'C','o','n','s','o','n','a','n','t','_','P','l','a','c','e','h','o','l','d','e','r',0,
+'C','o','n','s','o','n','a','n','t','_','P','l','a','c','e','h','o','l','d','e','r',0,
+2,'C','o','n','s','o','n','a','n','t','_','P','r','e','c','e','d','i','n','g','_','R','e','p','h','a',0,
+'C','o','n','s','o','n','a','n','t','_','P','r','e','c','e','d','i','n','g','_','R','e','p','h','a',0,
+2,'C','o','n','s','o','n','a','n','t','_','P','r','e','f','i','x','e','d',0,'C','o','n','s','o','n','a','n','t','_','P','r',
+'e','f','i','x','e','d',0,2,'C','o','n','s','o','n','a','n','t','_','S','u','b','j','o','i','n','e','d',0,
+'C','o','n','s','o','n','a','n','t','_','S','u','b','j','o','i','n','e','d',0,
+2,'C','o','n','s','o','n','a','n','t','_','S','u','c','c','e','e','d','i','n','g','_','R','e','p','h','a',0,
+'C','o','n','s','o','n','a','n','t','_','S','u','c','c','e','e','d','i','n','g','_','R','e','p','h','a',0,
+2,'C','o','n','s','o','n','a','n','t','_','W','i','t','h','_','S','t','a','c','k','e','r',0,
+'C','o','n','s','o','n','a','n','t','_','W','i','t','h','_','S','t','a','c','k','e','r',0,
+2,'G','e','m','i','n','a','t','i','o','n','_','M','a','r','k',0,'G','e','m','i','n','a','t','i','o','n','_','M','a','r','k',
+0,2,'I','n','v','i','s','i','b','l','e','_','S','t','a','c','k','e','r',0,'I','n','v','i','s','i','b','l','e','_','S','t',
+'a','c','k','e','r',0,2,'J','o','i','n','e','r',0,'J','o','i','n','e','r',0,
+2,'M','o','d','i','f','y','i','n','g','_','L','e','t','t','e','r',0,'M','o','d','i','f','y','i','n','g','_','L','e','t','t',
+'e','r',0,2,'N','o','n','_','J','o','i','n','e','r',0,'N','o','n','_','J','o','i','n','e','r',0,
+2,'N','u','k','t','a',0,'N','u','k','t','a',0,2,'N','u','m','b','e','r',0,'N','u','m','b','e','r',0,
+2,'N','u','m','b','e','r','_','J','o','i','n','e','r',0,'N','u','m','b','e','r','_','J','o','i','n','e','r',0,
+2,'P','u','r','e','_','K','i','l','l','e','r',0,'P','u','r','e','_','K','i','l','l','e','r',0,
+2,'R','e','g','i','s','t','e','r','_','S','h','i','f','t','e','r',0,'R','e','g','i','s','t','e','r','_','S','h','i','f','t',
+'e','r',0,2,'S','y','l','l','a','b','l','e','_','M','o','d','i','f','i','e','r',0,'S','y','l','l','a','b','l','e','_','M',
+'o','d','i','f','i','e','r',0,2,'T','o','n','e','_','L','e','t','t','e','r',0,'T','o','n','e','_','L','e','t','t','e','r',
+0,2,'T','o','n','e','_','M','a','r','k',0,'T','o','n','e','_','M','a','r','k',0,
+2,'V','i','r','a','m','a',0,'V','i','r','a','m','a',0,2,'V','i','s','a','r','g','a',0,
+'V','i','s','a','r','g','a',0,2,'V','o','w','e','l',0,'V','o','w','e','l',0,
+2,'V','o','w','e','l','_','D','e','p','e','n','d','e','n','t',0,'V','o','w','e','l','_','D','e','p','e','n','d','e','n','t',
+0,2,'V','o','w','e','l','_','I','n','d','e','p','e','n','d','e','n','t',0,'V','o','w','e','l','_','I','n','d','e','p','e',
+'n','d','e','n','t',0,2,'v','o',0,'V','e','r','t','i','c','a','l','_','O','r','i','e','n','t','a','t','i','o','n',0,
+2,'R',0,'R','o','t','a','t','e','d',0,2,'T','r',0,'T','r','a','n','s','f','o','r','m','e','d','_','R','o','t','a','t',
+'e','d',0,2,'T','u',0,'T','r','a','n','s','f','o','r','m','e','d','_','U','p','r','i','g','h','t',0,
+2,'U',0,'U','p','r','i','g','h','t',0,2,'g','c','m',0,'G','e','n','e','r','a','l','_','C','a','t','e','g','o','r','y',
+'_','M','a','s','k',0,2,'C',0,'O','t','h','e','r',0,2,'L',0,'L','e','t','t','e','r',0,
 2,'L','C',0,'C','a','s','e','d','_','L','e','t','t','e','r',0,
 3,'M',0,'M','a','r','k',0,'C','o','m','b','i','n','i','n','g','_','M','a','r','k',0,
 2,'N',0,'N','u','m','b','e','r',0,3,'P',0,'P','u','n','c','t','u','a','t','i','o','n',0,
@@ -1607,3 +1915,5 @@
 };
 
 U_NAMESPACE_END
+
+#endif  // INCLUDED_FROM_PROPNAME_CPP
diff --git a/src/third_party/icu/source/common/propsvec.c b/src/third_party/icu/source/common/propsvec.cpp
similarity index 96%
rename from src/third_party/icu/source/common/propsvec.c
rename to src/third_party/icu/source/common/propsvec.cpp
index 4fa4069..4bf95fd 100644
--- a/src/third_party/icu/source/common/propsvec.c
+++ b/src/third_party/icu/source/common/propsvec.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  propsvec.c
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -16,11 +18,12 @@
 *   Store bits (Unicode character properties) in bit set vectors.
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
 #include "starboard/client_porting/poem/string_poem.h"
-#if !defined(STARBOARD)
+#else
 #include <stdlib.h>
-#endif
+#endif  // defined(STARBOARD)
 #include "unicode/utypes.h"
 #include "cmemory.h"
 #include "utrie.h"
@@ -222,7 +225,7 @@
                 *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
                 return;
             }
-            uprv_memcpy(newVectors, pv->v, rows*columns*4);
+            uprv_memcpy(newVectors, pv->v, (size_t)rows*columns*4);
             firstRow=newVectors+(firstRow-pv->v);
             lastRow=newVectors+(lastRow-pv->v);
             uprv_free(pv->v);
@@ -244,7 +247,7 @@
         if(splitFirstRow) {
             /* copy all affected rows up one and move the lastRow pointer */
             count = (int32_t)((lastRow-firstRow)+columns);
-            uprv_memmove(firstRow+columns, firstRow, count*4);
+            uprv_memmove(firstRow+columns, firstRow, (size_t)count*4);
             lastRow+=columns;
 
             /* split the range and move the firstRow pointer */
@@ -255,7 +258,7 @@
         /* split the last row */
         if(splitLastRow) {
             /* copy the last row data */
-            uprv_memcpy(lastRow+columns, lastRow, columns*4);
+            uprv_memcpy(lastRow+columns, lastRow, (size_t)columns*4);
 
             /* split the range and move the firstRow pointer */
             lastRow[1]=lastRow[columns]=(uint32_t)limit;
@@ -419,7 +422,7 @@
         /* add a new values vector if it is different from the current one */
         if(count<0 || 0!=uprv_memcmp(row+2, pv->v+count, valueColumns*4)) {
             count+=valueColumns;
-            uprv_memmove(pv->v+count, row+2, valueColumns*4);
+            uprv_memmove(pv->v+count, row+2, (size_t)valueColumns*4);
         }
 
         if(start<UPVEC_FIRST_SPECIAL_CP) {
@@ -481,7 +484,7 @@
 
 U_CAPI UTrie2 * U_EXPORT2
 upvec_compactToUTrie2WithRowIndexes(UPropsVectors *pv, UErrorCode *pErrorCode) {
-    UPVecToUTrie2Context toUTrie2={ NULL };
+    UPVecToUTrie2Context toUTrie2={ NULL, 0, 0, 0 };
     upvec_compact(pv, upvec_compactToUTrie2Handler, &toUTrie2, pErrorCode);
     utrie2_freeze(toUTrie2.trie, UTRIE2_16_VALUE_BITS, pErrorCode);
     if(U_FAILURE(*pErrorCode)) {
@@ -501,6 +504,8 @@
                              UChar32 start, UChar32 end,
                              int32_t rowIndex, uint32_t *row, int32_t columns,
                              UErrorCode *pErrorCode) {
+    (void)row;
+    (void)columns;
     UPVecToUTrie2Context *toUTrie2=(UPVecToUTrie2Context *)context;
     if(start<UPVEC_FIRST_SPECIAL_CP) {
         utrie2_setRange32(toUTrie2->trie, start, end, (uint32_t)rowIndex, TRUE, pErrorCode);
diff --git a/src/third_party/icu/source/common/propsvec.h b/src/third_party/icu/source/common/propsvec.h
index fb62809..3908061 100644
--- a/src/third_party/icu/source/common/propsvec.h
+++ b/src/third_party/icu/source/common/propsvec.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  propsvec.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
diff --git a/src/third_party/icu/source/common/punycode.cpp b/src/third_party/icu/source/common/punycode.cpp
index 904d9b5..3e57f15 100644
--- a/src/third_party/icu/source/common/punycode.cpp
+++ b/src/third_party/icu/source/common/punycode.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  punycode.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -42,7 +44,9 @@
  * - UTF-16 handling
  */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/utypes.h"
 
 #if !UCONFIG_NO_IDNA
@@ -106,36 +110,26 @@
 }
 
 /**
- * basicToDigit[] contains the numeric value of a basic code
- * point (for use in representing integers) in the range 0 to
- * BASE-1, or -1 if b is does not represent a value.
+ * @return the numeric value of a basic code point (for use in representing integers)
+ *         in the range 0 to BASE-1, or a negative value if cp is invalid.
  */
-static const int8_t
-basicToDigit[256]={
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-    26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, -1,
-
-    -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
-    15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
-
-    -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
-    15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
-
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
-};
+static int32_t decodeDigit(int32_t cp) {
+    if(cp<=u'Z') {
+        if(cp<=u'9') {
+            if(cp<u'0') {
+                return -1;
+            } else {
+                return cp-u'0'+26;  // 0..9 -> 26..35
+            }
+        } else {
+            return cp-u'A';  // A-Z -> 0..25
+        }
+    } else if(cp<=u'z') {
+        return cp-'a';  // a..z -> 0..25
+    } else {
+        return -1;
+    }
+}
 
 static inline char
 asciiCaseMap(char b, UBool uppercase) {
@@ -177,15 +171,23 @@
     return count+(((BASE-TMIN+1)*delta)/(delta+SKEW));
 }
 
-#define MAX_CP_COUNT    200
+namespace {
 
-U_CFUNC int32_t
+// ICU-13727: Limit input length for n^2 algorithm
+// where well-formed strings are at most 59 characters long.
+constexpr int32_t ENCODE_MAX_CODE_UNITS=1000;
+constexpr int32_t DECODE_MAX_CHARS=2000;
+
+}  // namespace
+
+// encode
+U_CAPI int32_t
 u_strToPunycode(const UChar *src, int32_t srcLength,
                 UChar *dest, int32_t destCapacity,
                 const UBool *caseFlags,
                 UErrorCode *pErrorCode) {
 
-    int32_t cpBuffer[MAX_CP_COUNT];
+    int32_t cpBuffer[ENCODE_MAX_CODE_UNITS];
     int32_t n, delta, handledCPCount, basicLength, destLength, bias, j, m, q, k, t, srcCPCount;
     UChar c, c2;
 
@@ -198,6 +200,10 @@
         *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
         return 0;
     }
+    if (srcLength>ENCODE_MAX_CODE_UNITS) {
+        *pErrorCode=U_INPUT_TOO_LONG_ERROR;
+        return 0;
+    }
 
     /*
      * Handle the basic code points and
@@ -210,9 +216,8 @@
             if((c=src[j])==0) {
                 break;
             }
-            if(srcCPCount==MAX_CP_COUNT) {
-                /* too many input code points */
-                *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
+            if(j>=ENCODE_MAX_CODE_UNITS) {
+                *pErrorCode=U_INPUT_TOO_LONG_ERROR;
                 return 0;
             }
             if(IS_BASIC(c)) {
@@ -242,11 +247,6 @@
     } else {
         /* length-specified input */
         for(j=0; j<srcLength; ++j) {
-            if(srcCPCount==MAX_CP_COUNT) {
-                /* too many input code points */
-                *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
-                return 0;
-            }
             c=src[j];
             if(IS_BASIC(c)) {
                 cpBuffer[srcCPCount++]=0;
@@ -311,7 +311,7 @@
          * Increase delta enough to advance the decoder's
          * <n,i> state to <m,0>, but guard against overflow:
          */
-        if(m-n>(0x7fffffff-MAX_CP_COUNT-delta)/(handledCPCount+1)) {
+        if(m-n>(0x7fffffff-handledCPCount-delta)/(handledCPCount+1)) {
             *pErrorCode=U_INTERNAL_PROGRAM_ERROR;
             return 0;
         }
@@ -372,7 +372,8 @@
     return u_terminateUChars(dest, destCapacity, destLength, pErrorCode);
 }
 
-U_CFUNC int32_t
+// decode
+U_CAPI int32_t
 u_strFromPunycode(const UChar *src, int32_t srcLength,
                   UChar *dest, int32_t destCapacity,
                   UBool *caseFlags,
@@ -394,6 +395,10 @@
     if(srcLength==-1) {
         srcLength=u_strlen(src);
     }
+    if (srcLength>DECODE_MAX_CHARS) {
+        *pErrorCode=U_INPUT_TOO_LONG_ERROR;
+        return 0;
+    }
 
     /*
      * Handle the basic code points:
@@ -454,7 +459,7 @@
                 return 0;
             }
 
-            digit=basicToDigit[(uint8_t)src[in++]];
+            digit=decodeDigit(src[in++]);
             if(digit<0) {
                 *pErrorCode=U_INVALID_CHAR_FOUND;
                 return 0;
diff --git a/src/third_party/icu/source/common/punycode.h b/src/third_party/icu/source/common/punycode.h
index 21ae91d..9e28f77 100644
--- a/src/third_party/icu/source/common/punycode.h
+++ b/src/third_party/icu/source/common/punycode.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  punycode.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -48,7 +50,7 @@
  * @param caseFlags Vector of boolean values, one per input UChar,
  *                  indicating that the corresponding character is to be
  *                  marked for the decoder optionally
- *                  uppercasing (TRUE) or lowercasing (FALSE)
+ *                  uppercasing (true) or lowercasing (false)
  *                  the character.
  *                  ASCII characters are output directly in the case as marked.
  *                  Flags corresponding to trail surrogates are ignored.
@@ -63,7 +65,7 @@
  *
  * @see u_strFromPunycode
  */
-U_CFUNC int32_t
+U_CAPI int32_t
 u_strToPunycode(const UChar *src, int32_t srcLength,
                 UChar *dest, int32_t destCapacity,
                 const UBool *caseFlags,
@@ -81,10 +83,10 @@
  *                     and of caseFlags in numbers of UBools.
  * @param caseFlags Output array for case flags as
  *                  defined by the Punycode string.
- *                  The caller should uppercase (TRUE) or lowercase (FASLE)
+ *                  The caller should uppercase (true) or lowercase (FASLE)
  *                  the corresponding character in dest.
  *                  For supplementary characters, only the lead surrogate
- *                  is marked, and FALSE is stored for the trail surrogate.
+ *                  is marked, and false is stored for the trail surrogate.
  *                  This is redundant and not necessary for ASCII characters
  *                  because they are already in the case indicated.
  *                  Can be NULL if the case flags are not needed.
@@ -98,7 +100,7 @@
  *
  * @see u_strToPunycode
  */
-U_CFUNC int32_t
+U_CAPI int32_t
 u_strFromPunycode(const UChar *src, int32_t srcLength,
                   UChar *dest, int32_t destCapacity,
                   UBool *caseFlags,
diff --git a/src/third_party/icu/source/common/putil.cpp b/src/third_party/icu/source/common/putil.cpp
index 5b28dc2..7419654 100644
--- a/src/third_party/icu/source/common/putil.cpp
+++ b/src/third_party/icu/source/common/putil.cpp
@@ -1,7 +1,9 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
-*   Copyright (C) 1997-2014, International Business Machines
+*   Copyright (C) 1997-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *
 ******************************************************************************
@@ -39,17 +41,34 @@
 
 // Starboard poems must be included before uposixdefs.h, or else they cause
 // compiler errors on some platforms.
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
 #include "starboard/client_porting/poem/stdio_poem.h"
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 
 // Defines _XOPEN_SOURCE for access to POSIX functions.
 // Must be before any other #includes.
 #include "uposixdefs.h"
 
-/* include ICU headers */
-#include "unicode/utypes.h"
+// First, the platform type. Need this for U_PLATFORM.
 #include "unicode/platform.h"
+
+#if U_PLATFORM == U_PF_MINGW && defined __STRICT_ANSI__
+/* tzset isn't defined in strict ANSI on MinGW. */
+#undef __STRICT_ANSI__
+#endif
+
+/*
+ * Cygwin with GCC requires inclusion of time.h after the above disabling strict asci mode statement.
+ */
+#include <time.h>
+
+#if !U_PLATFORM_USES_ONLY_WIN32_APII && !defined(STARBOARD)
+#include <sys/time.h>
+#endif
+
+/* include the rest of the ICU headers */
 #include "unicode/putil.h"
 #include "unicode/ustring.h"
 #include "putilimp.h"
@@ -61,8 +80,10 @@
 #include "ucln_cmn.h"
 #include "charstr.h"
 
+#if defined(STARBOARD)
 // Must be after "umitex.h" which includes "time.h" on some platforms.
 #include "starboard/client_porting/poem/eztime_poem.h"
+#endif  // defined(STARBOARD)
 
 #include <math.h>
 
@@ -76,7 +97,7 @@
 #endif
 
 #ifndef U_COMMON_IMPLEMENTATION
-#error U_COMMON_IMPLEMENTATION not set - must be set for all ICU source files in common/ - see http://userguide.icu-project.org/howtouseicu
+#error U_COMMON_IMPLEMENTATION not set - must be set for all ICU source files in common/ - see https://unicode-org.github.io/icu/userguide/howtouseicu
 #endif
 
 /* include system headers */
@@ -93,13 +114,16 @@
      * Should Cygwin be included as well (U_PLATFORM_HAS_WIN32_API)
      * to use native APIs as much as possible?
      */
+#ifndef WIN32_LEAN_AND_MEAN
 #   define WIN32_LEAN_AND_MEAN
+#endif
 #   define VC_EXTRALEAN
 #   define NOUSER
 #   define NOSERVICE
 #   define NOIME
 #   define NOMCX
 #   include <windows.h>
+#   include "unicode/uloc.h"
 #   include "wintz.h"
 #elif U_PLATFORM == U_PF_OS400
 #   include <float.h>
@@ -116,24 +140,14 @@
 #       ifndef _XPG4_2
 #           define _XPG4_2
 #       endif
+#   elif U_PLATFORM == U_PF_ANDROID
+#       include <sys/system_properties.h>
+#       include <dlfcn.h>
 #   endif
 #elif U_PLATFORM == U_PF_QNX
 #   include <sys/neutrino.h>
 #endif
 
-#if (U_PF_MINGW <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN) && defined(__STRICT_ANSI__)
-/* tzset isn't defined in strict ANSI on Cygwin and MinGW. */
-#undef __STRICT_ANSI__
-#endif
-
-/*
- * Cygwin with GCC requires inclusion of time.h after the above disabling strict asci mode statement.
- */
-#include <time.h>
-
-#if !U_PLATFORM_USES_ONLY_WIN32_API && !defined(STARBOARD)
-#include <sys/time.h>
-#endif
 
 /*
  * Only include langinfo.h if we have a way to get the codeset. If we later
@@ -253,7 +267,6 @@
 UDate fakeClock_t0 = 0; /** Time to start the clock from **/
 UDate fakeClock_dt = 0; /** Offset (fake time - real time) **/
 UBool fakeClock_set = FALSE; /** True if fake clock has spun up **/
-static UMutex fakeClockMutex = U_MUTEX_INTIALIZER;
 
 static UDate getUTCtime_real() {
     struct timeval posixTime;
@@ -262,6 +275,7 @@
 }
 
 static UDate getUTCtime_fake() {
+    static UMutex fakeClockMutex;
     umtx_lock(&fakeClockMutex);
     if(!fakeClock_set) {
         UDate real = getUTCtime_real();
@@ -533,6 +547,28 @@
     return (x > y ? y : x);
 }
 
+U_CAPI UBool U_EXPORT2
+uprv_add32_overflow(int32_t a, int32_t b, int32_t* res) {
+    // NOTE: Some compilers (GCC, Clang) have primitives available, like __builtin_add_overflow.
+    // This function could be optimized by calling one of those primitives.
+    auto a64 = static_cast<int64_t>(a);
+    auto b64 = static_cast<int64_t>(b);
+    int64_t res64 = a64 + b64;
+    *res = static_cast<int32_t>(res64);
+    return res64 != *res;
+}
+
+U_CAPI UBool U_EXPORT2
+uprv_mul32_overflow(int32_t a, int32_t b, int32_t* res) {
+    // NOTE: Some compilers (GCC, Clang) have primitives available, like __builtin_mul_overflow.
+    // This function could be optimized by calling one of those primitives.
+    auto a64 = static_cast<int64_t>(a);
+    auto b64 = static_cast<int64_t>(b);
+    int64_t res64 = a64 * b64;
+    *res = static_cast<int32_t>(res64);
+    return res64 != *res;
+}
+
 /**
  * Truncates the given double.
  * trunc(3.3) = 3.0, trunc (-3.3) = -3.0
@@ -672,13 +708,23 @@
 /* Note that U_TZNAME does *not* have to be tzname, but if it is,
    some platforms need to have it declared here. */
 
-#if defined(U_TZNAME) && (U_PLATFORM == U_PF_IRIX || U_PLATFORM_IS_DARWIN_BASED || (U_PLATFORM == U_PF_CYGWIN && !U_PLATFORM_USES_ONLY_WIN32_API))
+#if defined(U_TZNAME) && (U_PLATFORM == U_PF_IRIX || U_PLATFORM_IS_DARWIN_BASED)
 /* RS6000 and others reject char **tzname.  */
 extern U_IMPORT char *U_TZNAME[];
 #endif
 
 #if !UCONFIG_NO_FILE_IO && ((U_PLATFORM_IS_DARWIN_BASED && (U_PLATFORM != U_PF_IPHONE || defined(U_TIMEZONE))) || U_PLATFORM_IS_LINUX_BASED || U_PLATFORM == U_PF_BSD || U_PLATFORM == U_PF_SOLARIS) && (U_PLATFORM != U_STARBOARD)
 /* These platforms are likely to use Olson timezone IDs. */
+/* common targets of the symbolic link at TZDEFAULT are:
+ * "/usr/share/zoneinfo/<olsonID>" default, older Linux distros, macOS to 10.12
+ * "../usr/share/zoneinfo/<olsonID>" newer Linux distros: Red Hat Enterprise Linux 7, Ubuntu 16, SuSe Linux 12
+ * "/usr/share/lib/zoneinfo/<olsonID>" Solaris
+ * "../usr/share/lib/zoneinfo/<olsonID>" Solaris
+ * "/var/db/timezone/zoneinfo/<olsonID>" macOS 10.13
+ * To avoid checking lots of paths, just check that the target path
+ * before the <olsonID> ends with "/zoneinfo/", and the <olsonID> is valid.
+ */
+
 #define CHECK_LOCALTIME_LINK 1
 #if U_PLATFORM_IS_DARWIN_BASED
 #include <tzfile.h>
@@ -686,12 +732,12 @@
 #elif U_PLATFORM == U_PF_SOLARIS
 #define TZDEFAULT       "/etc/localtime"
 #define TZZONEINFO      "/usr/share/lib/zoneinfo/"
-#define TZZONEINFO2     "../usr/share/lib/zoneinfo/"
 #define TZ_ENV_CHECK    "localtime"
 #else
 #define TZDEFAULT       "/etc/localtime"
 #define TZZONEINFO      "/usr/share/zoneinfo/"
 #endif
+#define TZZONEINFOTAIL  "/zoneinfo/"
 #if U_HAVE_DIRENT_H
 #define TZFILE_SKIP     "posixrules" /* tz file to skip when searching. */
 /* Some Linux distributions have 'localtime' in /usr/share/zoneinfo
@@ -855,7 +901,6 @@
 #endif
 
 #ifdef SEARCH_TZFILE
-#define MAX_PATH_SIZE PATH_MAX /* Set the limit for the size of the path. */
 #define MAX_READ_SIZE 512
 
 typedef struct DefaultTZInfo {
@@ -871,7 +916,7 @@
  * It is currently use to compare two TZ files.
  */
 static UBool compareBinaryFiles(const char* defaultTZFileName, const char* TZFileName, DefaultTZInfo* tzInfo) {
-    FILE* file; 
+    FILE* file;
     int64_t sizeFile;
     int64_t sizeFileLeft;
     int32_t sizeFileRead;
@@ -931,42 +976,64 @@
 
     return result;
 }
-/*
- * This method recursively traverses the directory given for a matching TZ file and returns the first match.
- */
+
+
 /* dirent also lists two entries: "." and ".." that we can safely ignore. */
 #define SKIP1 "."
 #define SKIP2 ".."
-static char SEARCH_TZFILE_RESULT[MAX_PATH_SIZE] = "";
-static char* searchForTZFile(const char* path, DefaultTZInfo* tzInfo) {
-    char curpath[MAX_PATH_SIZE];
-    DIR* dirp = opendir(path);
-    DIR* subDirp = NULL;
-    struct dirent* dirEntry = NULL;
+static UBool U_CALLCONV putil_cleanup(void);
+static CharString *gSearchTZFileResult = NULL;
 
+/*
+ * This method recursively traverses the directory given for a matching TZ file and returns the first match.
+ * This function is not thread safe - it uses a global, gSearchTZFileResult, to hold its results.
+ */
+static char* searchForTZFile(const char* path, DefaultTZInfo* tzInfo) {
+    DIR* dirp = NULL;
+    struct dirent* dirEntry = NULL;
     char* result = NULL;
-    if (dirp == NULL) {
-        return result;
-    }
+    UErrorCode status = U_ZERO_ERROR;
 
     /* Save the current path */
-    uprv_memset(curpath, 0, MAX_PATH_SIZE);
-    uprv_strcpy(curpath, path);
+    CharString curpath(path, -1, status);
+    if (U_FAILURE(status)) {
+        goto cleanupAndReturn;
+    }
+
+    dirp = opendir(path);
+    if (dirp == NULL) {
+        goto cleanupAndReturn;
+    }
+
+    if (gSearchTZFileResult == NULL) {
+        gSearchTZFileResult = new CharString;
+        if (gSearchTZFileResult == NULL) {
+            goto cleanupAndReturn;
+        }
+        ucln_common_registerCleanup(UCLN_COMMON_PUTIL, putil_cleanup);
+    }
 
     /* Check each entry in the directory. */
     while((dirEntry = readdir(dirp)) != NULL) {
         const char* dirName = dirEntry->d_name;
-        if (uprv_strcmp(dirName, SKIP1) != 0 && uprv_strcmp(dirName, SKIP2) != 0) {
+        if (uprv_strcmp(dirName, SKIP1) != 0 && uprv_strcmp(dirName, SKIP2) != 0
+            && uprv_strcmp(TZFILE_SKIP, dirName) != 0 && uprv_strcmp(TZFILE_SKIP2, dirName) != 0) {
             /* Create a newpath with the new entry to test each entry in the directory. */
-            char newpath[MAX_PATH_SIZE];
-            uprv_strcpy(newpath, curpath);
-            uprv_strcat(newpath, dirName);
+            CharString newpath(curpath, status);
+            newpath.append(dirName, -1, status);
+            if (U_FAILURE(status)) {
+                break;
+            }
 
-            if ((subDirp = opendir(newpath)) != NULL) {
+            DIR* subDirp = NULL;
+            if ((subDirp = opendir(newpath.data())) != NULL) {
                 /* If this new path is a directory, make a recursive call with the newpath. */
                 closedir(subDirp);
-                uprv_strcat(newpath, "/");
-                result = searchForTZFile(newpath, tzInfo);
+                newpath.append('/', status);
+                if (U_FAILURE(status)) {
+                    break;
+                }
+                result = searchForTZFile(newpath.data(), tzInfo);
                 /*
                  Have to get out here. Otherwise, we'd keep looking
                  and return the first match in the top-level directory
@@ -977,26 +1044,82 @@
                 */
                 if (result != NULL)
                     break;
-            } else if (uprv_strcmp(TZFILE_SKIP, dirName) != 0 && uprv_strcmp(TZFILE_SKIP2, dirName) != 0) {
-                if(compareBinaryFiles(TZDEFAULT, newpath, tzInfo)) {
-                    const char* zoneid = newpath + (sizeof(TZZONEINFO)) - 1;
+            } else {
+                if(compareBinaryFiles(TZDEFAULT, newpath.data(), tzInfo)) {
+                    int32_t amountToSkip = sizeof(TZZONEINFO) - 1;
+                    if (amountToSkip > newpath.length()) {
+                        amountToSkip = newpath.length();
+                    }
+                    const char* zoneid = newpath.data() + amountToSkip;
                     skipZoneIDPrefix(&zoneid);
-                    uprv_strcpy(SEARCH_TZFILE_RESULT, zoneid);
-                    result = SEARCH_TZFILE_RESULT;
+                    gSearchTZFileResult->clear();
+                    gSearchTZFileResult->append(zoneid, -1, status);
+                    if (U_FAILURE(status)) {
+                        break;
+                    }
+                    result = gSearchTZFileResult->data();
                     /* Get out after the first one found. */
                     break;
                 }
             }
         }
     }
-    closedir(dirp);
+
+  cleanupAndReturn:
+    if (dirp) {
+        closedir(dirp);
+    }
     return result;
 }
 #endif
 
+#if U_PLATFORM == U_PF_ANDROID
+typedef int(system_property_read_callback)(const prop_info* info,
+                                           void (*callback)(void* cookie,
+                                                            const char* name,
+                                                            const char* value,
+                                                            uint32_t serial),
+                                           void* cookie);
+typedef int(system_property_get)(const char*, char*);
+
+static char gAndroidTimeZone[PROP_VALUE_MAX] = { '\0' };
+
+static void u_property_read(void* cookie, const char* name, const char* value,
+                            uint32_t serial) {
+    uprv_strcpy((char* )cookie, value);
+}
+#endif
+
 U_CAPI void U_EXPORT2
-uprv_tzname_clear_cache()
+uprv_tzname_clear_cache(void)
 {
+#if U_PLATFORM == U_PF_ANDROID
+    /* Android's timezone is stored in system property. */
+    gAndroidTimeZone[0] = '\0';
+    void* libc = dlopen("libc.so", RTLD_NOLOAD);
+    if (libc) {
+        /* Android API 26+ has new API to get system property and old API
+         * (__system_property_get) is deprecated */
+        system_property_read_callback* property_read_callback =
+            (system_property_read_callback*)dlsym(
+                libc, "__system_property_read_callback");
+        if (property_read_callback) {
+            const prop_info* info =
+                __system_property_find("persist.sys.timezone");
+            if (info) {
+                property_read_callback(info, &u_property_read, gAndroidTimeZone);
+            }
+        } else {
+            system_property_get* property_get =
+                (system_property_get*)dlsym(libc, "__system_property_get");
+            if (property_get) {
+                property_get("persist.sys.timezone", gAndroidTimeZone);
+            }
+        }
+        dlclose(libc);
+    }
+#endif
+
 #if defined(CHECK_LOCALTIME_LINK) && !defined(DEBUG_SKIP_LOCALTIME_LINK)
     gTimeZoneBufferPtr = NULL;
 #endif
@@ -1005,6 +1128,7 @@
 U_CAPI const char* U_EXPORT2
 uprv_tzname(int n)
 {
+    (void)n; // Avoid unreferenced parameter warning.
     const char *tzid = NULL;
 #if (U_PLATFORM == U_STARBOARD)
     tzid = SbTimeZoneGetName();
@@ -1017,6 +1141,15 @@
     if (tzid != NULL) {
         return tzid;
     }
+
+#ifndef U_TZNAME
+    // The return value is free'd in timezone.cpp on Windows because
+    // the other code path returns a pointer to a heap location.
+    // If we don't have a name already, then tzname wouldn't be any
+    // better, so just fall back.
+    return uprv_strdup("");
+#endif // !U_TZNAME
+
 #else
 
 /*#if U_PLATFORM_IS_DARWIN_BASED
@@ -1030,13 +1163,21 @@
 
 /* This code can be temporarily disabled to test tzname resolution later on. */
 #ifndef DEBUG_TZNAME
+#if U_PLATFORM == U_PF_ANDROID
+    tzid = gAndroidTimeZone;
+#else
     tzid = getenv("TZ");
+#endif
     if (tzid != NULL && isValidOlsonID(tzid)
 #if U_PLATFORM == U_PF_SOLARIS
     /* When TZ equals localtime on Solaris, check the /etc/localtime file. */
         && uprv_strcmp(tzid, TZ_ENV_CHECK) != 0
 #endif
     ) {
+        /* The colon forces tzset() to treat the remainder as zoneinfo path */
+        if (tzid[0] == ':') {
+            tzid++;
+        }
         /* This might be a good Olson ID. */
         skipZoneIDPrefix(&tzid);
         return tzid;
@@ -1052,26 +1193,17 @@
         because the tzfile contents is underspecified.
         This isn't guaranteed to work because it may not be a symlink.
         */
-        int32_t ret = (int32_t)readlink(TZDEFAULT, gTimeZoneBuffer, sizeof(gTimeZoneBuffer));
+        int32_t ret = (int32_t)readlink(TZDEFAULT, gTimeZoneBuffer, sizeof(gTimeZoneBuffer)-1);
         if (0 < ret) {
-            int32_t tzZoneInfoLen = uprv_strlen(TZZONEINFO);
+            int32_t tzZoneInfoTailLen = uprv_strlen(TZZONEINFOTAIL);
             gTimeZoneBuffer[ret] = 0;
-            if (uprv_strncmp(gTimeZoneBuffer, TZZONEINFO, tzZoneInfoLen) == 0
-                && isValidOlsonID(gTimeZoneBuffer + tzZoneInfoLen))
+            char *  tzZoneInfoTailPtr = uprv_strstr(gTimeZoneBuffer, TZZONEINFOTAIL);
+
+            if (tzZoneInfoTailPtr != NULL
+                && isValidOlsonID(tzZoneInfoTailPtr + tzZoneInfoTailLen))
             {
-                return (gTimeZoneBufferPtr = gTimeZoneBuffer + tzZoneInfoLen);
+                return (gTimeZoneBufferPtr = tzZoneInfoTailPtr + tzZoneInfoTailLen);
             }
-#if U_PLATFORM == U_PF_SOLARIS
-            else
-            {
-                tzZoneInfoLen = uprv_strlen(TZZONEINFO2);
-                if (uprv_strncmp(gTimeZoneBuffer, TZZONEINFO2, tzZoneInfoLen) == 0
-                                && isValidOlsonID(gTimeZoneBuffer + tzZoneInfoLen))
-                {
-                    return (gTimeZoneBufferPtr = gTimeZoneBuffer + tzZoneInfoLen);
-                }
-            }
-#endif
         } else {
 #if defined(SEARCH_TZFILE)
             DefaultTZInfo* tzInfo = (DefaultTZInfo*)uprv_malloc(sizeof(DefaultTZInfo));
@@ -1157,7 +1289,8 @@
 static CharString *gTimeZoneFilesDirectory = NULL;
 
 #if U_POSIX_LOCALE || U_PLATFORM_USES_ONLY_WIN32_API
- static char *gCorrectedPOSIXLocale = NULL; /* Heap allocated */
+ static const char *gCorrectedPOSIXLocale = NULL; /* Sometimes heap allocated */
+ static bool gCorrectedPOSIXLocaleHeapAllocated = false;
 #endif
 
 static UBool U_CALLCONV putil_cleanup(void)
@@ -1172,10 +1305,16 @@
     gTimeZoneFilesDirectory = NULL;
     gTimeZoneFilesInitOnce.reset();
 
+#ifdef SEARCH_TZFILE
+    delete gSearchTZFileResult;
+    gSearchTZFileResult = NULL;
+#endif
+
 #if U_POSIX_LOCALE || U_PLATFORM_USES_ONLY_WIN32_API
-    if (gCorrectedPOSIXLocale) {
-        uprv_free(gCorrectedPOSIXLocale);
+    if (gCorrectedPOSIXLocale && gCorrectedPOSIXLocaleHeapAllocated) {
+        uprv_free(const_cast<char *>(gCorrectedPOSIXLocale));
         gCorrectedPOSIXLocale = NULL;
+        gCorrectedPOSIXLocaleHeapAllocated = false;
     }
 #endif
     return TRUE;
@@ -1206,11 +1345,13 @@
         }
         uprv_strcpy(newDataDir, directory);
 
-        if (U_FILE_SEP_CHAR != U_FILE_ALT_SEP_CHAR) {
-          char* p;
-          while ((p = uprv_strchr(newDataDir, U_FILE_ALT_SEP_CHAR))) {
-            *p = U_FILE_SEP_CHAR;
-          }
+    if (U_FILE_SEP_CHAR != U_FILE_ALT_SEP_CHAR) {
+        {
+                char *p;
+                while((p = uprv_strchr(newDataDir, U_FILE_ALT_SEP_CHAR)) != NULL) {
+                    *p = U_FILE_SEP_CHAR;
+                }
+            }
         }
     }
 
@@ -1249,14 +1390,49 @@
   return FALSE;
 }
 
-/* Temporary backup setting of ICU_DATA_DIR_PREFIX_ENV_VAR
-   until some client wrapper makefiles are updated */
-#if U_PLATFORM_IS_DARWIN_BASED && TARGET_IPHONE_SIMULATOR
+/* Backup setting of ICU_DATA_DIR_PREFIX_ENV_VAR
+   (needed for some Darwin ICU build environments) */
+#if U_PLATFORM_IS_DARWIN_BASED && TARGET_OS_SIMULATOR
 # if !defined(ICU_DATA_DIR_PREFIX_ENV_VAR)
 #  define ICU_DATA_DIR_PREFIX_ENV_VAR "IPHONE_SIMULATOR_ROOT"
 # endif
 #endif
 
+#if defined(ICU_DATA_DIR_WINDOWS)
+// Helper function to get the ICU Data Directory under the Windows directory location.
+static BOOL U_CALLCONV getIcuDataDirectoryUnderWindowsDirectory(char* directoryBuffer, UINT bufferLength)
+{
+    wchar_t windowsPath[MAX_PATH];
+    char windowsPathUtf8[MAX_PATH];
+
+    UINT length = GetSystemWindowsDirectoryW(windowsPath, UPRV_LENGTHOF(windowsPath));
+    if ((length > 0) && (length < (UPRV_LENGTHOF(windowsPath) - 1))) {
+        // Convert UTF-16 to a UTF-8 string.
+        UErrorCode status = U_ZERO_ERROR;
+        int32_t windowsPathUtf8Len = 0;
+        u_strToUTF8(windowsPathUtf8, static_cast<int32_t>(UPRV_LENGTHOF(windowsPathUtf8)),
+            &windowsPathUtf8Len, reinterpret_cast<const UChar*>(windowsPath), -1, &status);
+
+        if (U_SUCCESS(status) && (status != U_STRING_NOT_TERMINATED_WARNING) &&
+            (windowsPathUtf8Len < (UPRV_LENGTHOF(windowsPathUtf8) - 1))) {
+            // Ensure it always has a separator, so we can append the ICU data path.
+            if (windowsPathUtf8[windowsPathUtf8Len - 1] != U_FILE_SEP_CHAR) {
+                windowsPathUtf8[windowsPathUtf8Len++] = U_FILE_SEP_CHAR;
+                windowsPathUtf8[windowsPathUtf8Len] = '\0';
+            }
+            // Check if the concatenated string will fit.
+            if ((windowsPathUtf8Len + UPRV_LENGTHOF(ICU_DATA_DIR_WINDOWS)) < bufferLength) {
+                uprv_strcpy(directoryBuffer, windowsPathUtf8);
+                uprv_strcat(directoryBuffer, ICU_DATA_DIR_WINDOWS);
+                return TRUE;
+            }
+        }
+    }
+
+    return FALSE;
+}
+#endif
+
 static void U_CALLCONV dataDirectoryInitFn() {
     /* If we already have the directory, then return immediately. Will happen if user called
      * u_setDataDirectory().
@@ -1285,7 +1461,9 @@
     */
 #   if !defined(ICU_NO_USER_DATA_OVERRIDE) && !UCONFIG_NO_FILE_IO
     /* First try to get the environment variable */
-    path=getenv("ICU_DATA");
+#     if U_PLATFORM_HAS_WINUWP_API == 0  // Windows UWP does not support getenv
+        path=getenv("ICU_DATA");
+#     endif
 #   endif
 
     /* ICU_DATA_DIR may be set as a compile option.
@@ -1314,6 +1492,13 @@
     }
 #endif
 
+#if defined(ICU_DATA_DIR_WINDOWS)
+    char datadir_path_buffer[MAX_PATH];
+    if (getIcuDataDirectoryUnderWindowsDirectory(datadir_path_buffer, UPRV_LENGTHOF(datadir_path_buffer))) {
+        path = datadir_path_buffer;
+    }
+#endif
+
     if(path==NULL) {
         /* It looks really bad, set it to something. */
         path = "";
@@ -1336,14 +1521,14 @@
     gTimeZoneFilesDirectory->clear();
     gTimeZoneFilesDirectory->append(path, status);
     if (U_FILE_SEP_CHAR != U_FILE_ALT_SEP_CHAR) {
-      char* p = gTimeZoneFilesDirectory->data();
-      while ((p = uprv_strchr(p, U_FILE_ALT_SEP_CHAR))) {
-        *p = U_FILE_SEP_CHAR;
-      }
+        char *p = gTimeZoneFilesDirectory->data();
+        while ((p = uprv_strchr(p, U_FILE_ALT_SEP_CHAR)) != NULL) {
+            *p = U_FILE_SEP_CHAR;
+        }
     }
 }
 
-#define TO_STRING(x) TO_STRING_2(x) 
+#define TO_STRING(x) TO_STRING_2(x)
 #define TO_STRING_2(x) #x
 
 static void U_CALLCONV TimeZoneDataDirInitFn(UErrorCode &status) {
@@ -1354,15 +1539,47 @@
         status = U_MEMORY_ALLOCATION_ERROR;
         return;
     }
-    const char *dir = getenv("ICU_TIMEZONE_FILES_DIR");
+
+    const char *dir = "";
+
+#if defined(ICU_TIMEZONE_FILES_DIR_PREFIX_ENV_VAR)
+    char timezonefilesdir_path_buffer[PATH_MAX];
+    const char *prefix = getenv(ICU_TIMEZONE_FILES_DIR_PREFIX_ENV_VAR);
+#endif
+
+#if U_PLATFORM_HAS_WINUWP_API == 1
+// The UWP version does not support the environment variable setting.
+
+# if defined(ICU_DATA_DIR_WINDOWS)
+    // When using the Windows system data, we can possibly pick up time zone data from the Windows directory.
+    char datadir_path_buffer[MAX_PATH];
+    if (getIcuDataDirectoryUnderWindowsDirectory(datadir_path_buffer, UPRV_LENGTHOF(datadir_path_buffer))) {
+        dir = datadir_path_buffer;
+    }
+# endif
+
+#else
+    dir = getenv("ICU_TIMEZONE_FILES_DIR");
+#endif // U_PLATFORM_HAS_WINUWP_API
+
 #if defined(U_TIMEZONE_FILES_DIR)
     if (dir == NULL) {
+        // Build time configuration setting.
         dir = TO_STRING(U_TIMEZONE_FILES_DIR);
     }
 #endif
+
     if (dir == NULL) {
         dir = "";
     }
+
+#if defined(ICU_TIMEZONE_FILES_DIR_PREFIX_ENV_VAR)
+    if (prefix != NULL) {
+        snprintf(timezonefilesdir_path_buffer, PATH_MAX, "%s%s", prefix, dir);
+        dir = timezonefilesdir_path_buffer;
+    }
+#endif
+
     setTimeZoneFilesDir(dir, status);
 }
 
@@ -1421,9 +1638,18 @@
         {
             /* Maybe we got some garbage.  Try something more reasonable */
             posixID = getenv("LC_ALL");
+            /* Solaris speaks POSIX -  See IEEE Std 1003.1-2008
+             * This is needed to properly handle empty env. variables
+             */
+#if U_PLATFORM == U_PF_SOLARIS
+            if ((posixID == 0) || (posixID[0] == '\0')) {
+                posixID = getenv(category == LC_MESSAGES ? "LC_MESSAGES" : "LC_CTYPE");
+                if ((posixID == 0) || (posixID[0] == '\0')) {
+#else
             if (posixID == 0) {
                 posixID = getenv(category == LC_MESSAGES ? "LC_MESSAGES" : "LC_CTYPE");
                 if (posixID == 0) {
+#endif
                     posixID = getenv("LANG");
                 }
             }
@@ -1436,6 +1662,10 @@
     {
         /* Nothing worked.  Give it a nice POSIX default value. */
         posixID = "en_US_POSIX";
+        // Note: this test will not catch 'C.UTF-8',
+        // that will be handled in uprv_getDefaultLocaleID().
+        // Leave this mapping here for the uprv_getPOSIXIDForDefaultCodepage()
+        // caller which expects to see "en_US_POSIX" in many branches.
     }
     return posixID;
 }
@@ -1502,11 +1732,7 @@
 The 'rightmost' variant (@xxx) wins.
 The leftmost codepage (.xxx) wins.
 */
-    char *correctedPOSIXLocale = 0;
     const char* posixID = uprv_getPOSIXIDForDefaultLocale();
-    const char *p;
-    const char *q;
-    int32_t len;
 
     /* Format: (no spaces)
     ll [ _CC ] [ . MM ] [ @ VV]
@@ -1514,37 +1740,36 @@
       l = lang, C = ctry, M = charmap, V = variant
     */
 
-    if (gCorrectedPOSIXLocale != NULL) {
+    if (gCorrectedPOSIXLocale != nullptr) {
         return gCorrectedPOSIXLocale;
     }
 
-    if ((p = uprv_strchr(posixID, '.')) != NULL) {
-        /* assume new locale can't be larger than old one? */
-        correctedPOSIXLocale = static_cast<char *>(uprv_malloc(uprv_strlen(posixID)+1));
-        /* Exit on memory allocation error. */
-        if (correctedPOSIXLocale == NULL) {
-            return NULL;
-        }
-        uprv_strncpy(correctedPOSIXLocale, posixID, p-posixID);
-        correctedPOSIXLocale[p-posixID] = 0;
+    // Copy the ID into owned memory.
+    // Over-allocate in case we replace "C" with "en_US_POSIX" (+10), + null termination
+    char *correctedPOSIXLocale = static_cast<char *>(uprv_malloc(uprv_strlen(posixID) + 10 + 1));
+    if (correctedPOSIXLocale == nullptr) {
+        return nullptr;
+    }
+    uprv_strcpy(correctedPOSIXLocale, posixID);
 
-        /* do not copy after the @ */
-        if ((p = uprv_strchr(correctedPOSIXLocale, '@')) != NULL) {
-            correctedPOSIXLocale[p-correctedPOSIXLocale] = 0;
-        }
+    char *limit;
+    if ((limit = uprv_strchr(correctedPOSIXLocale, '.')) != nullptr) {
+        *limit = 0;
+    }
+    if ((limit = uprv_strchr(correctedPOSIXLocale, '@')) != nullptr) {
+        *limit = 0;
+    }
+
+    if ((uprv_strcmp("C", correctedPOSIXLocale) == 0) // no @ variant
+        || (uprv_strcmp("POSIX", correctedPOSIXLocale) == 0)) {
+      // Raw input was C.* or POSIX.*, Give it a nice POSIX default value.
+      // (The "C"/"POSIX" case is handled in uprv_getPOSIXIDForCategory())
+      uprv_strcpy(correctedPOSIXLocale, "en_US_POSIX");
     }
 
     /* Note that we scan the *uncorrected* ID. */
-    if ((p = uprv_strrchr(posixID, '@')) != NULL) {
-        if (correctedPOSIXLocale == NULL) {
-            correctedPOSIXLocale = static_cast<char *>(uprv_malloc(uprv_strlen(posixID)+1));
-            /* Exit on memory allocation error. */
-            if (correctedPOSIXLocale == NULL) {
-                return NULL;
-            }
-            uprv_strncpy(correctedPOSIXLocale, posixID, p-posixID);
-            correctedPOSIXLocale[p-posixID] = 0;
-        }
+    const char *p;
+    if ((p = uprv_strrchr(posixID, '@')) != nullptr) {
         p++;
 
         /* Take care of any special cases here.. */
@@ -1553,17 +1778,18 @@
             /* Don't worry about no__NY. In practice, it won't appear. */
         }
 
-        if (uprv_strchr(correctedPOSIXLocale,'_') == NULL) {
-            uprv_strcat(correctedPOSIXLocale, "__"); /* aa@b -> aa__b */
+        if (uprv_strchr(correctedPOSIXLocale,'_') == nullptr) {
+            uprv_strcat(correctedPOSIXLocale, "__"); /* aa@b -> aa__b (note this can make the new locale 1 char longer) */
         }
         else {
             uprv_strcat(correctedPOSIXLocale, "_"); /* aa_CC@b -> aa_CC_b */
         }
 
-        if ((q = uprv_strchr(p, '.')) != NULL) {
+        const char *q;
+        if ((q = uprv_strchr(p, '.')) != nullptr) {
             /* How big will the resulting string be? */
-            len = (int32_t)(uprv_strlen(correctedPOSIXLocale) + (q-p));
-            uprv_strncat(correctedPOSIXLocale, p, q-p);
+            int32_t len = (int32_t)(uprv_strlen(correctedPOSIXLocale) + (q-p));
+            uprv_strncat(correctedPOSIXLocale, p, q-p); // do not include charset
             correctedPOSIXLocale[len] = 0;
         }
         else {
@@ -1578,27 +1804,15 @@
          */
     }
 
-    /* Was a correction made? */
-    if (correctedPOSIXLocale != NULL) {
-        posixID = correctedPOSIXLocale;
-    }
-    else {
-        /* copy it, just in case the original pointer goes away.  See j2395 */
-        correctedPOSIXLocale = (char *)uprv_malloc(uprv_strlen(posixID) + 1);
-        /* Exit on memory allocation error. */
-        if (correctedPOSIXLocale == NULL) {
-            return NULL;
-        }
-        posixID = uprv_strcpy(correctedPOSIXLocale, posixID);
-    }
-
-    if (gCorrectedPOSIXLocale == NULL) {
+    if (gCorrectedPOSIXLocale == nullptr) {
         gCorrectedPOSIXLocale = correctedPOSIXLocale;
+        gCorrectedPOSIXLocaleHeapAllocated = true;
         ucln_common_registerCleanup(UCLN_COMMON_PUTIL, putil_cleanup);
-        correctedPOSIXLocale = NULL;
+        correctedPOSIXLocale = nullptr;
     }
+    posixID = gCorrectedPOSIXLocale;
 
-    if (correctedPOSIXLocale != NULL) {  /* Was already set - clean up. */
+    if (correctedPOSIXLocale != nullptr) {  /* Was already set - clean up. */
         uprv_free(correctedPOSIXLocale);
     }
 
@@ -1607,27 +1821,71 @@
 #elif U_PLATFORM_USES_ONLY_WIN32_API
 #define POSIX_LOCALE_CAPACITY 64
     UErrorCode status = U_ZERO_ERROR;
-    char *correctedPOSIXLocale = 0;
+    char *correctedPOSIXLocale = nullptr;
 
-    if (gCorrectedPOSIXLocale != NULL) {
+    // If we have already figured this out just use the cached value
+    if (gCorrectedPOSIXLocale != nullptr) {
         return gCorrectedPOSIXLocale;
     }
 
-    LCID id = GetThreadLocale();
-    correctedPOSIXLocale = static_cast<char *>(uprv_malloc(POSIX_LOCALE_CAPACITY + 1));
-    if (correctedPOSIXLocale) {
-        int32_t posixLen = uprv_convertToPosix(id, correctedPOSIXLocale, POSIX_LOCALE_CAPACITY, &status);
-        if (U_SUCCESS(status)) {
-            *(correctedPOSIXLocale + posixLen) = 0;
-            gCorrectedPOSIXLocale = correctedPOSIXLocale;
-            ucln_common_registerCleanup(UCLN_COMMON_PUTIL, putil_cleanup);
-        } else {
-            uprv_free(correctedPOSIXLocale);
+    // No cached value, need to determine the current value
+    static WCHAR windowsLocale[LOCALE_NAME_MAX_LENGTH] = {};
+    int length = GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT, LOCALE_SNAME, windowsLocale, LOCALE_NAME_MAX_LENGTH);
+
+    // Now we should have a Windows locale name that needs converted to the POSIX style.
+    if (length > 0) // If length is 0, then the GetLocaleInfoEx failed.
+    {
+        // First we need to go from UTF-16 to char (and also convert from _ to - while we're at it.)
+        char modifiedWindowsLocale[LOCALE_NAME_MAX_LENGTH] = {};
+
+        int32_t i;
+        for (i = 0; i < UPRV_LENGTHOF(modifiedWindowsLocale); i++)
+        {
+            if (windowsLocale[i] == '_')
+            {
+                modifiedWindowsLocale[i] = '-';
+            }
+            else
+            {
+                modifiedWindowsLocale[i] = static_cast<char>(windowsLocale[i]);
+            }
+
+            if (modifiedWindowsLocale[i] == '\0')
+            {
+                break;
+            }
+        }
+
+        if (i >= UPRV_LENGTHOF(modifiedWindowsLocale))
+        {
+            // Ran out of room, can't really happen, maybe we'll be lucky about a matching
+            // locale when tags are dropped
+            modifiedWindowsLocale[UPRV_LENGTHOF(modifiedWindowsLocale) - 1] = '\0';
+        }
+
+        // Now normalize the resulting name
+        correctedPOSIXLocale = static_cast<char *>(uprv_malloc(POSIX_LOCALE_CAPACITY + 1));
+        /* TODO: Should we just exit on memory allocation failure? */
+        if (correctedPOSIXLocale)
+        {
+            int32_t posixLen = uloc_canonicalize(modifiedWindowsLocale, correctedPOSIXLocale, POSIX_LOCALE_CAPACITY, &status);
+            if (U_SUCCESS(status))
+            {
+                *(correctedPOSIXLocale + posixLen) = 0;
+                gCorrectedPOSIXLocale = correctedPOSIXLocale;
+                gCorrectedPOSIXLocaleHeapAllocated = true;
+                ucln_common_registerCleanup(UCLN_COMMON_PUTIL, putil_cleanup);
+            }
+            else
+            {
+                uprv_free(correctedPOSIXLocale);
+            }
         }
     }
 
-    if (gCorrectedPOSIXLocale == NULL) {
-        return "en_US";
+    // If unable to find a locale we can agree upon, use en-US by default
+    if (gCorrectedPOSIXLocale == nullptr) {
+        gCorrectedPOSIXLocale = "en_US";
     }
     return gCorrectedPOSIXLocale;
 
@@ -1914,8 +2172,34 @@
 
 #elif U_PLATFORM_USES_ONLY_WIN32_API
     static char codepage[64];
-    sprintf(codepage, "windows-%d", GetACP());
-    return codepage;
+    DWORD codepageNumber = 0;
+
+#if U_PLATFORM_HAS_WINUWP_API == 1
+    // UWP doesn't have a direct API to get the default ACP as Microsoft would rather
+    // have folks use Unicode than a "system" code page, however this is the same
+    // codepage as the system default locale codepage.  (FWIW, the system locale is
+    // ONLY used for codepage, it should never be used for anything else)
+    GetLocaleInfoEx(LOCALE_NAME_SYSTEM_DEFAULT, LOCALE_IDEFAULTANSICODEPAGE | LOCALE_RETURN_NUMBER,
+        (LPWSTR)&codepageNumber, sizeof(codepageNumber) / sizeof(WCHAR));
+#else
+    // Win32 apps can call GetACP
+    codepageNumber = GetACP();
+#endif
+    // Special case for UTF-8
+    if (codepageNumber == 65001)
+    {
+        return "UTF-8";
+    }
+    // Windows codepages can look like windows-1252, so format the found number
+    // the numbers are eclectic, however all valid system code pages, besides UTF-8
+    // are between 3 and 19999
+    if (codepageNumber > 0 && codepageNumber < 20000)
+    {
+        sprintf(codepage, "windows-%ld", codepageNumber);
+        return codepage;
+    }
+    // If the codepage number call failed then return UTF-8
+    return "UTF-8";
 
 #elif U_POSIX_LOCALE
     static char codesetName[100];
@@ -1924,7 +2208,10 @@
 
     localeName = uprv_getPOSIXIDForDefaultCodepage();
     uprv_memset(codesetName, 0, sizeof(codesetName));
-#if U_HAVE_NL_LANGINFO_CODESET
+    /* On Solaris nl_langinfo returns C locale values unless setlocale
+     * was called earlier.
+     */
+#if (U_HAVE_NL_LANGINFO_CODESET && U_PLATFORM != U_PF_SOLARIS)
     /* When available, check nl_langinfo first because it usually gives more
        useful names. It depends on LC_CTYPE.
        nl_langinfo may use the same buffer as setlocale. */
@@ -2093,24 +2380,21 @@
 }
 
 /**
- * icucfg.h dependent code 
+ * icucfg.h dependent code
  */
 
-#if U_ENABLE_DYLOAD
- 
-#if HAVE_DLOPEN && !U_PLATFORM_USES_ONLY_WIN32_API
+#if U_ENABLE_DYLOAD && HAVE_DLOPEN && !U_PLATFORM_USES_ONLY_WIN32_API
 
 #if HAVE_DLFCN_H
-
 #ifdef __MVS__
 #ifndef __SUSV3
 #define __SUSV3 1
 #endif
 #endif
 #include <dlfcn.h>
-#endif
+#endif /* HAVE_DLFCN_H */
 
-U_INTERNAL void * U_EXPORT2
+U_CAPI void * U_EXPORT2
 uprv_dl_open(const char *libName, UErrorCode *status) {
   void *ret = NULL;
   if(U_FAILURE(*status)) return ret;
@@ -2124,13 +2408,13 @@
   return ret;
 }
 
-U_INTERNAL void U_EXPORT2
+U_CAPI void U_EXPORT2
 uprv_dl_close(void *lib, UErrorCode *status) {
   if(U_FAILURE(*status)) return;
   dlclose(lib);
 }
 
-U_INTERNAL UVoidFunction* U_EXPORT2
+U_CAPI UVoidFunction* U_EXPORT2
 uprv_dlsym_func(void *lib, const char* sym, UErrorCode *status) {
   union {
       UVoidFunction *fp;
@@ -2148,74 +2432,45 @@
   return uret.fp;
 }
 
-#else
+#elif U_ENABLE_DYLOAD && U_PLATFORM_USES_ONLY_WIN32_API && !U_PLATFORM_HAS_WINUWP_API
 
-/* null (nonexistent) implementation. */
+/* Windows API implementation. */
+// Note: UWP does not expose/allow these APIs, so the UWP version gets the null implementation. */
 
-U_INTERNAL void * U_EXPORT2
-uprv_dl_open(const char *libName, UErrorCode *status) {
-  if(U_FAILURE(*status)) return NULL;
-  *status = U_UNSUPPORTED_ERROR;
-  return NULL;
-}
-
-U_INTERNAL void U_EXPORT2
-uprv_dl_close(void *lib, UErrorCode *status) {
-  if(U_FAILURE(*status)) return;
-  *status = U_UNSUPPORTED_ERROR;
-  return;
-}
-
-
-U_INTERNAL UVoidFunction* U_EXPORT2
-uprv_dlsym_func(void *lib, const char* sym, UErrorCode *status) {
-  if(U_SUCCESS(*status)) {
-    *status = U_UNSUPPORTED_ERROR;
-  }
-  return (UVoidFunction*)NULL;
-}
-
-
-
-#endif
-
-#elif U_PLATFORM_USES_ONLY_WIN32_API
-
-U_INTERNAL void * U_EXPORT2
+U_CAPI void * U_EXPORT2
 uprv_dl_open(const char *libName, UErrorCode *status) {
   HMODULE lib = NULL;
-  
+
   if(U_FAILURE(*status)) return NULL;
-  
+
   lib = LoadLibraryA(libName);
-  
+
   if(lib==NULL) {
     *status = U_MISSING_RESOURCE_ERROR;
   }
-  
+
   return (void*)lib;
 }
 
-U_INTERNAL void U_EXPORT2
+U_CAPI void U_EXPORT2
 uprv_dl_close(void *lib, UErrorCode *status) {
   HMODULE handle = (HMODULE)lib;
   if(U_FAILURE(*status)) return;
-  
+
   FreeLibrary(handle);
-  
+
   return;
 }
 
-
-U_INTERNAL UVoidFunction* U_EXPORT2
+U_CAPI UVoidFunction* U_EXPORT2
 uprv_dlsym_func(void *lib, const char* sym, UErrorCode *status) {
   HMODULE handle = (HMODULE)lib;
   UVoidFunction* addr = NULL;
-  
+
   if(U_FAILURE(*status) || lib==NULL) return NULL;
-  
+
   addr = (UVoidFunction*)GetProcAddress(handle, sym);
-  
+
   if(addr==NULL) {
     DWORD lastError = GetLastError();
     if(lastError == ERROR_PROC_NOT_FOUND) {
@@ -2224,39 +2479,41 @@
       *status = U_UNSUPPORTED_ERROR; /* other unknown error. */
     }
   }
-  
+
   return addr;
 }
 
-
 #else
 
-/* No dynamic loading set. */
+/* No dynamic loading, null (nonexistent) implementation. */
 
-U_INTERNAL void * U_EXPORT2
+U_CAPI void * U_EXPORT2
 uprv_dl_open(const char *libName, UErrorCode *status) {
+    (void)libName;
     if(U_FAILURE(*status)) return NULL;
     *status = U_UNSUPPORTED_ERROR;
     return NULL;
 }
 
-U_INTERNAL void U_EXPORT2
+U_CAPI void U_EXPORT2
 uprv_dl_close(void *lib, UErrorCode *status) {
+    (void)lib;
     if(U_FAILURE(*status)) return;
     *status = U_UNSUPPORTED_ERROR;
     return;
 }
 
-
-U_INTERNAL UVoidFunction* U_EXPORT2
+U_CAPI UVoidFunction* U_EXPORT2
 uprv_dlsym_func(void *lib, const char* sym, UErrorCode *status) {
+  (void)lib;
+  (void)sym;
   if(U_SUCCESS(*status)) {
     *status = U_UNSUPPORTED_ERROR;
   }
   return (UVoidFunction*)NULL;
 }
 
-#endif /* U_ENABLE_DYLOAD */
+#endif
 
 /*
  * Hey, Emacs, please set the following:
diff --git a/src/third_party/icu/source/common/putilimp.h b/src/third_party/icu/source/common/putilimp.h
index 666df3d..b463fbb 100644
--- a/src/third_party/icu/source/common/putilimp.h
+++ b/src/third_party/icu/source/common/putilimp.h
@@ -1,7 +1,9 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
-*   Copyright (C) 1997-2015, International Business Machines
+*   Copyright (C) 1997-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *
 ******************************************************************************
@@ -70,15 +72,6 @@
 typedef size_t uintptr_t;
 #endif
 
-/**
- * \def U_HAVE_MSVC_2003_OR_EARLIER
- * Flag for workaround of MSVC 2003 optimization bugs
- * @internal
- */
-#if !defined(U_HAVE_MSVC_2003_OR_EARLIER) && defined(_MSC_VER) && (_MSC_VER < 1400)
-#define U_HAVE_MSVC_2003_OR_EARLIER
-#endif
-
 /*===========================================================================*/
 /** @{ Information about POSIX support                                       */
 /*===========================================================================*/
@@ -87,7 +80,7 @@
     /* Use the predefined value. */
 #elif U_PLATFORM == U_STARBOARD
 #   define U_HAVE_NL_LANGINFO_CODESET 0
-#elif U_PLATFORM_HAS_WIN32_API || U_PLATFORM == U_PF_ANDROID || U_PLATFORM == U_PF_QNX
+#elif U_PLATFORM_USES_ONLY_WIN32_API || U_PLATFORM == U_PF_ANDROID || U_PLATFORM == U_PF_QNX
 #   define U_HAVE_NL_LANGINFO_CODESET 0
 #else
 #   define U_HAVE_NL_LANGINFO_CODESET 1
@@ -103,10 +96,13 @@
 #   define U_NL_LANGINFO_CODESET CODESET
 #endif
 
-#ifdef U_TZSET
+#if defined(U_TZSET) || defined(U_HAVE_TZSET)
     /* Use the predefined value. */
 #elif U_PLATFORM_USES_ONLY_WIN32_API
+    // UWP doesn't support tzset or environment variables for tz
+#if U_PLATFORM_HAS_WINUWP_API == 0
 #   define U_TZSET _tzset
+#endif
 #elif U_PLATFORM == U_PF_OS400
    /* not defined */
 #elif U_PLATFORM == U_STARBOARD
@@ -119,15 +115,15 @@
     /* Use the predefined value. */
 #elif U_PLATFORM == U_PF_ANDROID
 #   define U_TIMEZONE timezone
+#elif defined(__UCLIBC__)
+    // uClibc does not have __timezone or _timezone.
+#elif defined(_NEWLIB_VERSION)
+#   define U_TIMEZONE _timezone
+#elif defined(__GLIBC__)
+    // glibc
+#   define U_TIMEZONE __timezone
 #elif U_PLATFORM_IS_LINUX_BASED
-#   if defined(__UCLIBC__)
-       /* uClibc does not have __timezone or _timezone. */
-#   elif defined(_NEWLIB_VERSION)
-#      define U_TIMEZONE      _timezone
-#   elif defined(__GLIBC__)
-       /* glibc */
-#      define U_TIMEZONE      __timezone
-#   endif
+    // not defined
 #elif U_PLATFORM_USES_ONLY_WIN32_API
 #   define U_TIMEZONE _timezone
 #elif U_PLATFORM == U_PF_BSD && !defined(__NetBSD__)
@@ -142,10 +138,13 @@
 #   define U_TIMEZONE timezone
 #endif
 
-#ifdef U_TZNAME
+#if defined(U_TZNAME) || defined(U_HAVE_TZNAME)
     /* Use the predefined value. */
 #elif U_PLATFORM_USES_ONLY_WIN32_API
+    /* not usable on all windows platforms */
+#if U_PLATFORM_HAS_WINUWP_API == 0
 #   define U_TZNAME _tzname
+#endif
 #elif U_PLATFORM == U_PF_OS400
    /* not defined */
 #elif U_PLATFORM == U_STARBOARD
@@ -158,7 +157,7 @@
     /* Use the predefined value. */
 #elif (U_PLATFORM == U_STARBOARD) || defined(__LB_XB1__) || defined(__LB_PS3__)
 #   define U_HAVE_MMAP 0
-#elif U_PLATFORM_HAS_WIN32_API
+#elif U_PLATFORM_USES_ONLY_WIN32_API
 #   define U_HAVE_MMAP 0
 #else
 #   define U_HAVE_MMAP 1
@@ -187,7 +186,7 @@
 #   define U_HAVE_DIRENT_H 0
 #elif defined(__LB_PS3__)
 #   define U_HAVE_DIRENT_H 1
-#elif U_PLATFORM_HAS_WIN32_API
+#elif U_PLATFORM_USES_ONLY_WIN32_API
 #   define U_HAVE_DIRENT_H 0
 #else
 #   define U_HAVE_DIRENT_H 1
@@ -196,74 +195,6 @@
 /** @} */
 
 /*===========================================================================*/
-/** @{ GCC built in functions for atomic memory operations                   */
-/*===========================================================================*/
-
-/**
- * \def U_HAVE_GCC_ATOMICS
- * @internal
- */
-#ifdef U_HAVE_GCC_ATOMICS
-    /* Use the predefined value. */
-#elif U_PLATFORM == U_STARBOARD
-    #define U_HAVE_GCC_ATOMICS 0
-#elif U_PLATFORM == U_PF_MINGW
-    #define U_HAVE_GCC_ATOMICS 0
-#elif U_GCC_MAJOR_MINOR >= 404 || defined(__clang__)
-    /* TODO: Intel icc and IBM xlc on AIX also support gcc atomics.  (Intel originated them.)
-     *       Add them for these compilers.
-     * Note: Clang sets __GNUC__ defines for version 4.2, so misses the 4.4 test here.
-     */
-#   define U_HAVE_GCC_ATOMICS 1
-#else
-#   define U_HAVE_GCC_ATOMICS 0
-#endif
-
-/** @} */
-
-/**
- * \def U_HAVE_STD_ATOMICS
- * Defines whether the standard C++11 <atomic> is available.
- * ICU will use this when avialable,
- * otherwise will fall back to compiler or platform specific alternatives.
- * @internal
- */
-#ifdef U_HAVE_STD_ATOMICS
-    /* Use the predefined value. */
-#elif U_CPLUSPLUS_VERSION < 11
-    /* Not C++11, disable use of atomics */
-#   define U_HAVE_STD_ATOMICS 0
-#elif __clang__ && __clang_major__==3 && __clang_minor__<=1
-    /* Clang 3.1, has atomic variable initializer bug. */
-#   define U_HAVE_STD_ATOMICS 0
-#else 
-    /* U_HAVE_ATOMIC is typically set by an autoconf test of #include <atomic>  */
-    /*   Can be set manually, or left undefined, on platforms without autoconf. */
-#   if defined(U_HAVE_ATOMIC) &&  U_HAVE_ATOMIC 
-#      define U_HAVE_STD_ATOMICS 1
-#   else
-#      define U_HAVE_STD_ATOMICS 0
-#   endif
-#endif
-
-
-/**
- *  \def U_HAVE_CLANG_ATOMICS
- *  Defines whether Clang c11 style built-in atomics are avaialable.
- *  These are used in preference to gcc atomics when both are available.
- */
-#ifdef U_HAVE_CLANG_ATOMICS
-    /* Use the predefined value. */
-#elif __has_builtin(__c11_atomic_load) && \
-    __has_builtin(__c11_atomic_store) && \
-    __has_builtin(__c11_atomic_fetch_add) && \
-    __has_builtin(__c11_atomic_fetch_sub)
-#    define U_HAVE_CLANG_ATOMICS 1
-#else
-#    define U_HAVE_CLANG_ATOMICS 0
-#endif
-
-/*===========================================================================*/
 /** @{ Programs used by ICU code                                             */
 /*===========================================================================*/
 
@@ -287,7 +218,7 @@
 
 /**
  * Platform utilities isolates the platform dependencies of the
- * libarary.  For each platform which this code is ported to, these
+ * library.  For each platform which this code is ported to, these
  * functions may have to be re-implemented.
  */
 
@@ -295,93 +226,93 @@
  * Floating point utility to determine if a double is Not a Number (NaN).
  * @internal
  */
-U_INTERNAL UBool   U_EXPORT2 uprv_isNaN(double d);
+U_CAPI UBool   U_EXPORT2 uprv_isNaN(double d);
 /**
  * Floating point utility to determine if a double has an infinite value.
  * @internal
  */
-U_INTERNAL UBool   U_EXPORT2 uprv_isInfinite(double d);
+U_CAPI UBool   U_EXPORT2 uprv_isInfinite(double d);
 /**
  * Floating point utility to determine if a double has a positive infinite value.
  * @internal
  */
-U_INTERNAL UBool   U_EXPORT2 uprv_isPositiveInfinity(double d);
+U_CAPI UBool   U_EXPORT2 uprv_isPositiveInfinity(double d);
 /**
  * Floating point utility to determine if a double has a negative infinite value.
  * @internal
  */
-U_INTERNAL UBool   U_EXPORT2 uprv_isNegativeInfinity(double d);
+U_CAPI UBool   U_EXPORT2 uprv_isNegativeInfinity(double d);
 /**
  * Floating point utility that returns a Not a Number (NaN) value.
  * @internal
  */
-U_INTERNAL double  U_EXPORT2 uprv_getNaN(void);
+U_CAPI double  U_EXPORT2 uprv_getNaN(void);
 /**
  * Floating point utility that returns an infinite value.
  * @internal
  */
-U_INTERNAL double  U_EXPORT2 uprv_getInfinity(void);
+U_CAPI double  U_EXPORT2 uprv_getInfinity(void);
 
 /**
  * Floating point utility to truncate a double.
  * @internal
  */
-U_INTERNAL double  U_EXPORT2 uprv_trunc(double d);
+U_CAPI double  U_EXPORT2 uprv_trunc(double d);
 /**
  * Floating point utility to calculate the floor of a double.
  * @internal
  */
-U_INTERNAL double  U_EXPORT2 uprv_floor(double d);
+U_CAPI double  U_EXPORT2 uprv_floor(double d);
 /**
  * Floating point utility to calculate the ceiling of a double.
  * @internal
  */
-U_INTERNAL double  U_EXPORT2 uprv_ceil(double d);
+U_CAPI double  U_EXPORT2 uprv_ceil(double d);
 /**
  * Floating point utility to calculate the absolute value of a double.
  * @internal
  */
-U_INTERNAL double  U_EXPORT2 uprv_fabs(double d);
+U_CAPI double  U_EXPORT2 uprv_fabs(double d);
 /**
  * Floating point utility to calculate the fractional and integer parts of a double.
  * @internal
  */
-U_INTERNAL double  U_EXPORT2 uprv_modf(double d, double* pinteger);
+U_CAPI double  U_EXPORT2 uprv_modf(double d, double* pinteger);
 /**
  * Floating point utility to calculate the remainder of a double divided by another double.
  * @internal
  */
-U_INTERNAL double  U_EXPORT2 uprv_fmod(double d, double y);
+U_CAPI double  U_EXPORT2 uprv_fmod(double d, double y);
 /**
  * Floating point utility to calculate d to the power of exponent (d^exponent).
  * @internal
  */
-U_INTERNAL double  U_EXPORT2 uprv_pow(double d, double exponent);
+U_CAPI double  U_EXPORT2 uprv_pow(double d, double exponent);
 /**
  * Floating point utility to calculate 10 to the power of exponent (10^exponent).
  * @internal
  */
-U_INTERNAL double  U_EXPORT2 uprv_pow10(int32_t exponent);
+U_CAPI double  U_EXPORT2 uprv_pow10(int32_t exponent);
 /**
  * Floating point utility to calculate the maximum value of two doubles.
  * @internal
  */
-U_INTERNAL double  U_EXPORT2 uprv_fmax(double d, double y);
+U_CAPI double  U_EXPORT2 uprv_fmax(double d, double y);
 /**
  * Floating point utility to calculate the minimum value of two doubles.
  * @internal
  */
-U_INTERNAL double  U_EXPORT2 uprv_fmin(double d, double y);
+U_CAPI double  U_EXPORT2 uprv_fmin(double d, double y);
 /**
  * Private utility to calculate the maximum value of two integers.
  * @internal
  */
-U_INTERNAL int32_t U_EXPORT2 uprv_max(int32_t d, int32_t y);
+U_CAPI int32_t U_EXPORT2 uprv_max(int32_t d, int32_t y);
 /**
  * Private utility to calculate the minimum value of two integers.
  * @internal
  */
-U_INTERNAL int32_t U_EXPORT2 uprv_min(int32_t d, int32_t y);
+U_CAPI int32_t U_EXPORT2 uprv_min(int32_t d, int32_t y);
 
 #if U_IS_BIG_ENDIAN
 #   define uprv_isNegative(number) (*((signed char *)&(number))<0)
@@ -394,13 +325,13 @@
  * type of arbitrary bit length.
  * @internal
  */
-U_INTERNAL double  U_EXPORT2 uprv_maxMantissa(void);
+U_CAPI double  U_EXPORT2 uprv_maxMantissa(void);
 
 /**
  * Floating point utility to calculate the logarithm of a double.
  * @internal
  */
-U_INTERNAL double  U_EXPORT2 uprv_log(double d);
+U_CAPI double  U_EXPORT2 uprv_log(double d);
 
 /**
  * Does common notion of rounding e.g. uprv_floor(x + 0.5);
@@ -408,7 +339,33 @@
  * @return the rounded double
  * @internal
  */
-U_INTERNAL double  U_EXPORT2 uprv_round(double x);
+U_CAPI double  U_EXPORT2 uprv_round(double x);
+
+/**
+ * Adds the signed integers a and b, storing the result in res.
+ * Checks for signed integer overflow.
+ * Similar to the GCC/Clang extension __builtin_add_overflow
+ *
+ * @param a The first operand.
+ * @param b The second operand.
+ * @param res a + b
+ * @return true if overflow occurred; false if no overflow occurred.
+ * @internal
+ */
+U_CAPI UBool U_EXPORT2 uprv_add32_overflow(int32_t a, int32_t b, int32_t* res);
+
+/**
+ * Multiplies the signed integers a and b, storing the result in res.
+ * Checks for signed integer overflow.
+ * Similar to the GCC/Clang extension __builtin_mul_overflow
+ *
+ * @param a The first multiplicand.
+ * @param b The second multiplicand.
+ * @param res a * b
+ * @return true if overflow occurred; false if no overflow occurred.
+ * @internal
+ */
+U_CAPI UBool U_EXPORT2 uprv_mul32_overflow(int32_t a, int32_t b, int32_t* res);
 
 #if 0
 /**
@@ -418,7 +375,7 @@
  * @return the number of digits after the decimal point in a double number x.
  * @internal
  */
-/*U_INTERNAL int32_t  U_EXPORT2 uprv_digitsAfterDecimal(double x);*/
+/*U_CAPI int32_t  U_EXPORT2 uprv_digitsAfterDecimal(double x);*/
 #endif
 
 #if !U_CHARSET_IS_UTF8
@@ -427,22 +384,22 @@
  * Return the default codepage for this platform and locale.
  * This function can call setlocale() on Unix platforms. Please read the
  * platform documentation on setlocale() before calling this function.
- * @return the default codepage for this platform 
+ * @return the default codepage for this platform
  * @internal
  */
-U_INTERNAL const char*  U_EXPORT2 uprv_getDefaultCodepage(void);
+U_CAPI const char*  U_EXPORT2 uprv_getDefaultCodepage(void);
 #endif
 
 /**
  * Please use uloc_getDefault() instead.
- * Return the default locale ID string by querying ths system, or
- *     zero if one cannot be found. 
+ * Return the default locale ID string by querying the system, or
+ *     zero if one cannot be found.
  * This function can call setlocale() on Unix platforms. Please read the
  * platform documentation on setlocale() before calling this function.
  * @return the default locale ID string
  * @internal
  */
-U_INTERNAL const char*  U_EXPORT2 uprv_getDefaultLocaleID(void);
+U_CAPI const char*  U_EXPORT2 uprv_getDefaultLocaleID(void);
 
 /**
  * Time zone utilities
@@ -476,7 +433,7 @@
  * Date/Time application.
  * @internal
  */
-U_INTERNAL void     U_EXPORT2 uprv_tzset(void);
+U_CAPI void     U_EXPORT2 uprv_tzset(void);
 
 /**
  * Difference in seconds between coordinated universal
@@ -484,7 +441,7 @@
  * @return the difference in seconds between coordinated universal time and local time.
  * @internal
  */
-U_INTERNAL int32_t  U_EXPORT2 uprv_timezone(void);
+U_CAPI int32_t  U_EXPORT2 uprv_timezone(void);
 
 /**
  *   tzname(0)  Three-letter time-zone name derived from TZ environment
@@ -494,13 +451,13 @@
  *              tzname(1) is an empty string.
  * @internal
  */
-U_INTERNAL const char* U_EXPORT2 uprv_tzname(int n);
+U_CAPI const char* U_EXPORT2 uprv_tzname(int n);
 
 /**
  * Reset the global tzname cache.
  * @internal
  */
-U_INTERNAL void uprv_tzname_clear_cache();
+U_CAPI void uprv_tzname_clear_cache(void);
 
 /**
  * Get UTC (GMT) time measured in milliseconds since 0:00 on 1/1/1970.
@@ -508,7 +465,7 @@
  * @return the UTC time measured in milliseconds
  * @internal
  */
-U_INTERNAL UDate U_EXPORT2 uprv_getUTCtime(void);
+U_CAPI UDate U_EXPORT2 uprv_getUTCtime(void);
 
 /**
  * Get UTC (GMT) time measured in milliseconds since 0:00 on 1/1/1970.
@@ -517,15 +474,15 @@
  * @return the UTC time measured in milliseconds
  * @internal
  */
-U_INTERNAL UDate U_EXPORT2 uprv_getRawUTCtime(void);
+U_CAPI UDate U_EXPORT2 uprv_getRawUTCtime(void);
 
 /**
  * Determine whether a pathname is absolute or not, as defined by the platform.
  * @param path Pathname to test
- * @return TRUE if the path is absolute
+ * @return true if the path is absolute
  * @internal (ICU 3.0)
  */
-U_INTERNAL UBool U_EXPORT2 uprv_pathIsAbsolute(const char *path);
+U_CAPI UBool U_EXPORT2 uprv_pathIsAbsolute(const char *path);
 
 /**
  * Use U_MAX_PTR instead of this function.
@@ -533,7 +490,7 @@
  * @return the largest possible pointer greater than the base
  * @internal (ICU 3.8)
  */
-U_INTERNAL void * U_EXPORT2 uprv_maximumPtr(void *base);
+U_CAPI void * U_EXPORT2 uprv_maximumPtr(void *base);
 
 /**
  * Maximum value of a (void*) - use to indicate the limit of an 'infinite' buffer.
@@ -579,6 +536,49 @@
 #  endif
 #endif
 
+
+#ifdef __cplusplus
+/**
+ * Pin a buffer capacity such that doing pointer arithmetic
+ * on the destination pointer and capacity cannot overflow.
+ *
+ * The pinned capacity must fulfill the following conditions (for positive capacities):
+ *   - dest + capacity is a valid pointer according to the machine arcitecture (AS/400, 64-bit, etc.)
+ *   - (dest + capacity) >= dest
+ *   - The size (in bytes) of T[capacity] does not exceed 0x7fffffff
+ *
+ * @param dest the destination buffer pointer.
+ * @param capacity the requested buffer capacity, in units of type T.
+ * @return the pinned capacity.
+ * @internal
+ */
+template <typename T>
+inline int32_t pinCapacity(T *dest, int32_t capacity) {
+    if (capacity <= 0) { return capacity; }
+
+    uintptr_t destInt = (uintptr_t)dest;
+    uintptr_t maxInt;
+
+#  if U_PLATFORM == U_PF_OS390 && !defined(_LP64)
+    // We have 31-bit pointers.
+    maxInt = 0x7fffffff;
+#  elif U_PLATFORM == U_PF_OS400
+    maxInt = (uintptr_t)uprv_maximumPtr((void *)dest);
+#  else
+    maxInt = destInt + 0x7fffffffu;
+    if (maxInt < destInt) {
+        // Less than 2GB to the end of the address space.
+        // Pin to that to prevent address overflow.
+        maxInt = (uintptr_t)-1;
+    }
+#  endif
+
+    uintptr_t maxBytes = maxInt - destInt;  // max. 2GB
+    int32_t maxCapacity = (int32_t)(maxBytes / sizeof(T));
+    return capacity <= maxCapacity ? capacity : maxCapacity;
+}
+#endif   // __cplusplus
+
 /*  Dynamic Library Functions */
 
 typedef void (UVoidFunction)(void);
@@ -588,26 +588,26 @@
  * Load a library
  * @internal (ICU 4.4)
  */
-U_INTERNAL void * U_EXPORT2 uprv_dl_open(const char *libName, UErrorCode *status);
+U_CAPI void * U_EXPORT2 uprv_dl_open(const char *libName, UErrorCode *status);
 
 /**
  * Close a library
  * @internal (ICU 4.4)
  */
-U_INTERNAL void U_EXPORT2 uprv_dl_close( void *lib, UErrorCode *status);
+U_CAPI void U_EXPORT2 uprv_dl_close( void *lib, UErrorCode *status);
 
 /**
  * Extract a symbol from a library (function)
  * @internal (ICU 4.8)
  */
-U_INTERNAL UVoidFunction* U_EXPORT2 uprv_dlsym_func( void *lib, const char *symbolName, UErrorCode *status);
+U_CAPI UVoidFunction* U_EXPORT2 uprv_dlsym_func( void *lib, const char *symbolName, UErrorCode *status);
 
 /**
  * Extract a symbol from a library (function)
  * Not implemented, no clients.
  * @internal
  */
-/* U_INTERNAL void * U_EXPORT2 uprv_dlsym_data( void *lib, const char *symbolName, UErrorCode *status); */
+/* U_CAPI void * U_EXPORT2 uprv_dlsym_data( void *lib, const char *symbolName, UErrorCode *status); */
 
 #endif
 
diff --git a/src/third_party/icu/source/common/rbbi.cpp b/src/third_party/icu/source/common/rbbi.cpp
index 11dc2e7..cc30c4f 100644
--- a/src/third_party/icu/source/common/rbbi.cpp
+++ b/src/third_party/icu/source/common/rbbi.cpp
@@ -1,11 +1,13 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ***************************************************************************
-*   Copyright (C) 1999-2014 International Business Machines Corporation
+*   Copyright (C) 1999-2016 International Business Machines Corporation
 *   and others. All rights reserved.
 ***************************************************************************
 */
 //
-//  file:  rbbi.c    Contains the implementation of the rule based break iterator
+//  file:  rbbi.cpp  Contains the implementation of the rule based break iterator
 //                   runtime engine and the API implementation for
 //                   class RuleBasedBreakIterator
 //
@@ -16,40 +18,42 @@
 
 #if !UCONFIG_NO_BREAK_ITERATION
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
+
+#include <cinttypes>
+
 #include "unicode/rbbi.h"
 #include "unicode/schriter.h"
 #include "unicode/uchriter.h"
-#include "unicode/udata.h"
 #include "unicode/uclean.h"
-#include "rbbidata.h"
-#include "rbbirb.h"
+#include "unicode/udata.h"
+
+#include "brkeng.h"
+#include "ucln_cmn.h"
 #include "cmemory.h"
 #include "cstring.h"
-#include "umutex.h"
-#include "ucln_cmn.h"
-#include "brkeng.h"
-
-#include "uassert.h"
-#include "uvector.h"
-
-// if U_LOCAL_SERVICE_HOOK is defined, then localsvc.cpp is expected to be included.
-#if U_LOCAL_SERVICE_HOOK
 #include "localsvc.h"
-#endif
+#include "rbbidata.h"
+#include "rbbi_cache.h"
+#include "rbbirb.h"
+#include "uassert.h"
+#include "umutex.h"
+#include "uvectr32.h"
 
 #ifdef RBBI_DEBUG
-static UBool fTrace = FALSE;
+static UBool gTrace = FALSE;
 #endif
 
 U_NAMESPACE_BEGIN
 
 // The state number of the starting state
-#define START_STATE 1
+constexpr int32_t START_STATE = 1;
 
 // The state-transition value indicating "stop"
-#define STOP_STATE  0
+constexpr int32_t STOP_STATE = 0;
 
 
 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(RuleBasedBreakIterator)
@@ -64,39 +68,35 @@
  * tables object that is passed in as a parameter.
  */
 RuleBasedBreakIterator::RuleBasedBreakIterator(RBBIDataHeader* data, UErrorCode &status)
+ : fSCharIter(UnicodeString())
 {
-    init();
+    init(status);
     fData = new RBBIDataWrapper(data, status); // status checked in constructor
     if (U_FAILURE(status)) {return;}
-    if(fData == 0) {
+    if(fData == nullptr) {
         status = U_MEMORY_ALLOCATION_ERROR;
         return;
     }
-}
-
-/**
- * Same as above but does not adopt memory
- */
-RuleBasedBreakIterator::RuleBasedBreakIterator(const RBBIDataHeader* data, enum EDontAdopt, UErrorCode &status)
-{
-    init();
-    fData = new RBBIDataWrapper(data, RBBIDataWrapper::kDontAdopt, status); // status checked in constructor
-    if (U_FAILURE(status)) {return;}
-    if(fData == 0) {
-        status = U_MEMORY_ALLOCATION_ERROR;
-        return;
+    if (fData->fForwardTable->fLookAheadResultsSize > 0) {
+        fLookAheadMatches = static_cast<int32_t *>(
+            uprv_malloc(fData->fForwardTable->fLookAheadResultsSize * sizeof(int32_t)));
+        if (fLookAheadMatches == nullptr) {
+            status = U_MEMORY_ALLOCATION_ERROR;
+            return;
+        }
     }
 }
 
-
 //
 //  Construct from precompiled binary rules (tables).  This constructor is public API,
 //  taking the rules as a (const uint8_t *) to match the type produced by getBinaryRules().
 //
 RuleBasedBreakIterator::RuleBasedBreakIterator(const uint8_t *compiledRules,
                        uint32_t       ruleLength,
-                       UErrorCode     &status) {
-    init();
+                       UErrorCode     &status)
+ : fSCharIter(UnicodeString())
+{
+    init(status);
     if (U_FAILURE(status)) {
         return;
     }
@@ -109,13 +109,21 @@
         status = U_ILLEGAL_ARGUMENT_ERROR;
         return;
     }
-    fData = new RBBIDataWrapper(data, RBBIDataWrapper::kDontAdopt, status); 
+    fData = new RBBIDataWrapper(data, RBBIDataWrapper::kDontAdopt, status);
     if (U_FAILURE(status)) {return;}
-    if(fData == 0) {
+    if(fData == nullptr) {
         status = U_MEMORY_ALLOCATION_ERROR;
         return;
     }
-}    
+    if (fData->fForwardTable->fLookAheadResultsSize > 0) {
+        fLookAheadMatches = static_cast<int32_t *>(
+            uprv_malloc(fData->fForwardTable->fLookAheadResultsSize * sizeof(int32_t)));
+        if (fLookAheadMatches == nullptr) {
+            status = U_MEMORY_ALLOCATION_ERROR;
+            return;
+        }
+    }
+}
 
 
 //-------------------------------------------------------------------------------
@@ -125,14 +133,23 @@
 //
 //-------------------------------------------------------------------------------
 RuleBasedBreakIterator::RuleBasedBreakIterator(UDataMemory* udm, UErrorCode &status)
+ : fSCharIter(UnicodeString())
 {
-    init();
+    init(status);
     fData = new RBBIDataWrapper(udm, status); // status checked in constructor
     if (U_FAILURE(status)) {return;}
-    if(fData == 0) {
+    if(fData == nullptr) {
         status = U_MEMORY_ALLOCATION_ERROR;
         return;
     }
+    if (fData->fForwardTable->fLookAheadResultsSize > 0) {
+        fLookAheadMatches = static_cast<int32_t *>(
+            uprv_malloc(fData->fForwardTable->fLookAheadResultsSize * sizeof(int32_t)));
+        if (fLookAheadMatches == nullptr) {
+            status = U_MEMORY_ALLOCATION_ERROR;
+            return;
+        }
+    }
 }
 
 
@@ -145,8 +162,9 @@
 RuleBasedBreakIterator::RuleBasedBreakIterator( const UnicodeString  &rules,
                                                 UParseError          &parseError,
                                                 UErrorCode           &status)
+ : fSCharIter(UnicodeString())
 {
-    init();
+    init(status);
     if (U_FAILURE(status)) {return;}
     RuleBasedBreakIterator *bi = (RuleBasedBreakIterator *)
         RBBIRuleBuilder::createRuleBasedBreakIterator(rules, &parseError, status);
@@ -167,8 +185,11 @@
 //                           Used when creating a RuleBasedBreakIterator from a set
 //                           of rules.
 //-------------------------------------------------------------------------------
-RuleBasedBreakIterator::RuleBasedBreakIterator() {
-    init();
+RuleBasedBreakIterator::RuleBasedBreakIterator()
+ : fSCharIter(UnicodeString())
+{
+    UErrorCode status = U_ZERO_ERROR;
+    init(status);
 }
 
 
@@ -179,9 +200,11 @@
 //
 //-------------------------------------------------------------------------------
 RuleBasedBreakIterator::RuleBasedBreakIterator(const RuleBasedBreakIterator& other)
-: BreakIterator(other)
+: BreakIterator(other),
+  fSCharIter(UnicodeString())
 {
-    this->init();
+    UErrorCode status = U_ZERO_ERROR;
+    this->init(status);
     *this = other;
 }
 
@@ -190,66 +213,69 @@
  * Destructor
  */
 RuleBasedBreakIterator::~RuleBasedBreakIterator() {
-    if (fCharIter!=fSCharIter && fCharIter!=fDCharIter) {
+    if (fCharIter != &fSCharIter) {
         // fCharIter was adopted from the outside.
         delete fCharIter;
     }
-    fCharIter = NULL;
-    delete fSCharIter;
-    fCharIter = NULL;
-    delete fDCharIter;
-    fDCharIter = NULL;
-    
-    utext_close(fText);
+    fCharIter = nullptr;
 
-    if (fData != NULL) {
+    utext_close(&fText);
+
+    if (fData != nullptr) {
         fData->removeReference();
-        fData = NULL;
+        fData = nullptr;
     }
-    if (fCachedBreakPositions) {
-        uprv_free(fCachedBreakPositions);
-        fCachedBreakPositions = NULL;
-    }
-    if (fLanguageBreakEngines) {
-        delete fLanguageBreakEngines;
-        fLanguageBreakEngines = NULL;
-    }
-    if (fUnhandledBreakEngine) {
-        delete fUnhandledBreakEngine;
-        fUnhandledBreakEngine = NULL;
-    }
+    delete fBreakCache;
+    fBreakCache = nullptr;
+
+    delete fDictionaryCache;
+    fDictionaryCache = nullptr;
+
+    delete fLanguageBreakEngines;
+    fLanguageBreakEngines = nullptr;
+
+    delete fUnhandledBreakEngine;
+    fUnhandledBreakEngine = nullptr;
+
+    uprv_free(fLookAheadMatches);
+    fLookAheadMatches = nullptr;
 }
 
 /**
  * Assignment operator.  Sets this iterator to have the same behavior,
  * and iterate over the same text, as the one passed in.
+ * TODO: needs better handling of memory allocation errors.
  */
 RuleBasedBreakIterator&
 RuleBasedBreakIterator::operator=(const RuleBasedBreakIterator& that) {
     if (this == &that) {
         return *this;
     }
-    reset();    // Delete break cache information
-    fBreakType = that.fBreakType;
+    BreakIterator::operator=(that);
+
     if (fLanguageBreakEngines != NULL) {
         delete fLanguageBreakEngines;
         fLanguageBreakEngines = NULL;   // Just rebuild for now
     }
     // TODO: clone fLanguageBreakEngines from "that"
     UErrorCode status = U_ZERO_ERROR;
-    fText = utext_clone(fText, that.fText, FALSE, TRUE, &status);
+    utext_clone(&fText, &that.fText, FALSE, TRUE, &status);
 
-    if (fCharIter!=fSCharIter && fCharIter!=fDCharIter) {
+    if (fCharIter != &fSCharIter) {
         delete fCharIter;
     }
-    fCharIter = NULL;
+    fCharIter = &fSCharIter;
 
-    if (that.fCharIter != NULL ) {
+    if (that.fCharIter != NULL && that.fCharIter != &that.fSCharIter) {
         // This is a little bit tricky - it will intially appear that
         //  this->fCharIter is adopted, even if that->fCharIter was
         //  not adopted.  That's ok.
         fCharIter = that.fCharIter->clone();
     }
+    fSCharIter = that.fSCharIter;
+    if (fCharIter == NULL) {
+        fCharIter = &fSCharIter;
+    }
 
     if (fData != NULL) {
         fData->removeReference();
@@ -259,6 +285,25 @@
         fData = that.fData->addReference();
     }
 
+    uprv_free(fLookAheadMatches);
+    fLookAheadMatches = nullptr;
+    if (fData && fData->fForwardTable->fLookAheadResultsSize > 0) {
+        fLookAheadMatches = static_cast<int32_t *>(
+            uprv_malloc(fData->fForwardTable->fLookAheadResultsSize * sizeof(int32_t)));
+    }
+
+
+    fPosition = that.fPosition;
+    fRuleStatusIndex = that.fRuleStatusIndex;
+    fDone = that.fDone;
+
+    // TODO: both the dictionary and the main cache need to be copied.
+    //       Current position could be within a dictionary range. Trying to continue
+    //       the iteration without the caches present would go to the rules, with
+    //       the assumption that the current position is on a rule boundary.
+    fBreakCache->reset(fPosition, fRuleStatusIndex);
+    fDictionaryCache->reset();
+
     return *this;
 }
 
@@ -270,33 +315,41 @@
 //                Initializes all fields, leaving the object in a consistent state.
 //
 //-----------------------------------------------------------------------------
-void RuleBasedBreakIterator::init() {
-    UErrorCode  status    = U_ZERO_ERROR;
-    fText                 = utext_openUChars(NULL, NULL, 0, &status);
-    fCharIter             = NULL;
-    fSCharIter            = NULL;
-    fDCharIter            = NULL;
-    fData                 = NULL;
-    fLastRuleStatusIndex  = 0;
-    fLastStatusIndexValid = TRUE;
+void RuleBasedBreakIterator::init(UErrorCode &status) {
+    fCharIter             = nullptr;
+    fData                 = nullptr;
+    fPosition             = 0;
+    fRuleStatusIndex      = 0;
+    fDone                 = false;
     fDictionaryCharCount  = 0;
-    fBreakType            = UBRK_WORD;  // Defaulting BreakType to word gives reasonable
-                                        //   dictionary behavior for Break Iterators that are
-                                        //   built from rules.  Even better would be the ability to
-                                        //   declare the type in the rules.
+    fLanguageBreakEngines = nullptr;
+    fUnhandledBreakEngine = nullptr;
+    fBreakCache           = nullptr;
+    fDictionaryCache      = nullptr;
+    fLookAheadMatches     = nullptr;
 
-    fCachedBreakPositions    = NULL;
-    fLanguageBreakEngines    = NULL;
-    fUnhandledBreakEngine    = NULL;
-    fNumCachedBreakPositions = 0;
-    fPositionInCache         = 0;
+    // Note: IBM xlC is unable to assign or initialize member fText from UTEXT_INITIALIZER.
+    // fText                 = UTEXT_INITIALIZER;
+    static const UText initializedUText = UTEXT_INITIALIZER;
+    uprv_memcpy(&fText, &initializedUText, sizeof(UText));
+
+   if (U_FAILURE(status)) {
+        return;
+    }
+
+    utext_openUChars(&fText, NULL, 0, &status);
+    fDictionaryCache = new DictionaryCache(this, status);
+    fBreakCache      = new BreakCache(this, status);
+    if (U_SUCCESS(status) && (fDictionaryCache == NULL || fBreakCache == NULL)) {
+        status = U_MEMORY_ALLOCATION_ERROR;
+    }
 
 #ifdef RBBI_DEBUG
     static UBool debugInitDone = FALSE;
     if (debugInitDone == FALSE) {
         char *debugEnv = getenv("U_RBBIDEBUG");
         if (debugEnv && uprv_strstr(debugEnv, "trace")) {
-            fTrace = TRUE;
+            gTrace = TRUE;
         }
         debugInitDone = TRUE;
     }
@@ -312,8 +365,8 @@
 //            Virtual function: does the right thing with subclasses.
 //
 //-----------------------------------------------------------------------------
-BreakIterator*
-RuleBasedBreakIterator::clone(void) const {
+RuleBasedBreakIterator*
+RuleBasedBreakIterator::clone() const {
     return new RuleBasedBreakIterator(*this);
 }
 
@@ -326,16 +379,28 @@
     if (typeid(*this) != typeid(that)) {
         return FALSE;
     }
+    if (this == &that) {
+        return TRUE;
+    }
+
+    // The base class BreakIterator carries no state that participates in equality,
+    // and does not implement an equality function that would otherwise be
+    // checked at this point.
 
     const RuleBasedBreakIterator& that2 = (const RuleBasedBreakIterator&) that;
 
-    if (!utext_equals(fText, that2.fText)) {
+    if (!utext_equals(&fText, &that2.fText)) {
         // The two break iterators are operating on different text,
-        //   or have a different interation position.
+        //   or have a different iteration position.
+        //   Note that fText's position is always the same as the break iterator's position.
         return FALSE;
-    };
+    }
 
-    // TODO:  need a check for when in a dictionary region at different offsets.
+    if (!(fPosition == that2.fPosition &&
+            fRuleStatusIndex == that2.fRuleStatusIndex &&
+            fDone == that2.fDone)) {
+        return FALSE;
+    }
 
     if (that2.fData == fData ||
         (fData != NULL && that2.fData != NULL && *that2.fData == *fData)) {
@@ -363,8 +428,9 @@
     if (U_FAILURE(status)) {
         return;
     }
-    reset();
-    fText = utext_clone(fText, ut, FALSE, TRUE, &status);
+    fBreakCache->reset();
+    fDictionaryCache->reset();
+    utext_clone(&fText, ut, FALSE, TRUE, &status);
 
     // Set up a dummy CharacterIterator to be returned if anyone
     //   calls getText().  With input from UText, there is no reasonable
@@ -372,58 +438,30 @@
     //   Return one over an empty string instead - this is the closest
     //   we can come to signaling a failure.
     //   (GetText() is obsolete, this failure is sort of OK)
-    if (fDCharIter == NULL) {
-        static const UChar c = 0;
-        fDCharIter = new UCharCharacterIterator(&c, 0);
-        if (fDCharIter == NULL) {
-            status = U_MEMORY_ALLOCATION_ERROR;
-            return;
-        }
-    }
+    fSCharIter.setText(UnicodeString());
 
-    if (fCharIter!=fSCharIter && fCharIter!=fDCharIter) {
+    if (fCharIter != &fSCharIter) {
         // existing fCharIter was adopted from the outside.  Delete it now.
         delete fCharIter;
     }
-    fCharIter = fDCharIter;
+    fCharIter = &fSCharIter;
 
     this->first();
 }
 
 
 UText *RuleBasedBreakIterator::getUText(UText *fillIn, UErrorCode &status) const {
-    UText *result = utext_clone(fillIn, fText, FALSE, TRUE, &status);  
+    UText *result = utext_clone(fillIn, &fText, FALSE, TRUE, &status);
     return result;
 }
 
 
-
-/**
- * Returns the description used to create this iterator
- */
-const UnicodeString&
-RuleBasedBreakIterator::getRules() const {
-    if (fData != NULL) {
-        return fData->getRuleSourceString();
-    } else {
-        static const UnicodeString *s;
-        if (s == NULL) {
-            // TODO:  something more elegant here.
-            //        perhaps API should return the string by value.
-            //        Note:  thread unsafe init & leak are semi-ok, better than
-            //               what was before.  Sould be cleaned up, though.
-            s = new UnicodeString;
-        }
-        return *s;
-    }
-}
-
 //=======================================================================
 // BreakIterator overrides
 //=======================================================================
 
 /**
- * Return a CharacterIterator over the text being analyzed.  
+ * Return a CharacterIterator over the text being analyzed.
  */
 CharacterIterator&
 RuleBasedBreakIterator::getText() const {
@@ -437,21 +475,22 @@
  */
 void
 RuleBasedBreakIterator::adoptText(CharacterIterator* newText) {
-    // If we are holding a CharacterIterator adopted from a 
+    // If we are holding a CharacterIterator adopted from a
     //   previous call to this function, delete it now.
-    if (fCharIter!=fSCharIter && fCharIter!=fDCharIter) {
+    if (fCharIter != &fSCharIter) {
         delete fCharIter;
     }
 
     fCharIter = newText;
     UErrorCode status = U_ZERO_ERROR;
-    reset();
-    if (newText==NULL || newText->startIndex() != 0) {   
+    fBreakCache->reset();
+    fDictionaryCache->reset();
+    if (newText==NULL || newText->startIndex() != 0) {
         // startIndex !=0 wants to be an error, but there's no way to report it.
         // Make the iterator text be an empty string.
-        fText = utext_openUChars(fText, NULL, 0, &status);
+        utext_openUChars(&fText, NULL, 0, &status);
     } else {
-        fText = utext_openCharacterIterator(fText, newText, &status);
+        utext_openCharacterIterator(&fText, newText, &status);
     }
     this->first();
 }
@@ -464,24 +503,21 @@
 void
 RuleBasedBreakIterator::setText(const UnicodeString& newText) {
     UErrorCode status = U_ZERO_ERROR;
-    reset();
-    fText = utext_openConstUnicodeString(fText, &newText, &status);
+    fBreakCache->reset();
+    fDictionaryCache->reset();
+    utext_openConstUnicodeString(&fText, &newText, &status);
 
-    // Set up a character iterator on the string.  
+    // Set up a character iterator on the string.
     //   Needed in case someone calls getText().
     //  Can not, unfortunately, do this lazily on the (probably never)
     //  call to getText(), because getText is const.
-    if (fSCharIter == NULL) {
-        fSCharIter = new StringCharacterIterator(newText);
-    } else {
-        fSCharIter->setText(newText);
-    }
+    fSCharIter.setText(newText);
 
-    if (fCharIter!=fSCharIter && fCharIter!=fDCharIter) {
+    if (fCharIter != &fSCharIter) {
         // old fCharIter was adopted from the outside.  Delete it.
         delete fCharIter;
     }
-    fCharIter = fSCharIter;
+    fCharIter = &fSCharIter;
 
     this->first();
 }
@@ -501,14 +537,14 @@
         status = U_ILLEGAL_ARGUMENT_ERROR;
         return *this;
     }
-    int64_t pos = utext_getNativeIndex(fText);
+    int64_t pos = utext_getNativeIndex(&fText);
     //  Shallow read-only clone of the new UText into the existing input UText
-    fText = utext_clone(fText, input, FALSE, TRUE, &status);
+    utext_clone(&fText, input, FALSE, TRUE, &status);
     if (U_FAILURE(status)) {
         return *this;
     }
-    utext_setNativeIndex(fText, pos);
-    if (utext_getNativeIndex(fText) != pos) {
+    utext_setNativeIndex(&fText, pos);
+    if (utext_getNativeIndex(&fText) != pos) {
         // Sanity check.  The new input utext is supposed to have the exact same
         // contents as the old.  If we can't set to the same position, it doesn't.
         // The contents underlying the old utext might be invalid at this point,
@@ -524,13 +560,12 @@
  * @return The new iterator position, which is zero.
  */
 int32_t RuleBasedBreakIterator::first(void) {
-    reset();
-    fLastRuleStatusIndex  = 0;
-    fLastStatusIndexValid = TRUE;
-    //if (fText == NULL)
-    //    return BreakIterator::DONE;
-
-    utext_setNativeIndex(fText, 0);
+    UErrorCode status = U_ZERO_ERROR;
+    if (!fBreakCache->seek(0)) {
+        fBreakCache->populateNear(0, status);
+    }
+    fBreakCache->current();
+    U_ASSERT(fPosition == 0);
     return 0;
 }
 
@@ -539,17 +574,12 @@
  * @return The text's past-the-end offset.
  */
 int32_t RuleBasedBreakIterator::last(void) {
-    reset();
-    if (fText == NULL) {
-        fLastRuleStatusIndex  = 0;
-        fLastStatusIndexValid = TRUE;
-        return BreakIterator::DONE;
-    }
-
-    fLastStatusIndexValid = FALSE;
-    int32_t pos = (int32_t)utext_nativeLength(fText);
-    utext_setNativeIndex(fText, pos);
-    return pos;
+    int32_t endPos = (int32_t)utext_nativeLength(&fText);
+    UBool endShouldBeBoundary = isBoundary(endPos);      // Has side effect of setting iterator position.
+    (void)endShouldBeBoundary;
+    U_ASSERT(endShouldBeBoundary);
+    U_ASSERT(fPosition == endPos);
+    return endPos;
 }
 
 /**
@@ -562,14 +592,17 @@
  * the current one.
  */
 int32_t RuleBasedBreakIterator::next(int32_t n) {
-    int32_t result = current();
-    while (n > 0) {
-        result = next();
-        --n;
-    }
-    while (n < 0) {
-        result = previous();
-        ++n;
+    int32_t result = 0;
+    if (n > 0) {
+        for (; n > 0 && result != UBRK_DONE; --n) {
+            result = next();
+        }
+    } else if (n < 0) {
+        for (; n < 0 && result != UBRK_DONE; ++n) {
+            result = previous();
+        }
+    } else {
+        result = current();
     }
     return result;
 }
@@ -579,396 +612,120 @@
  * @return The position of the first boundary after this one.
  */
 int32_t RuleBasedBreakIterator::next(void) {
-    // if we have cached break positions and we're still in the range
-    // covered by them, just move one step forward in the cache
-    if (fCachedBreakPositions != NULL) {
-        if (fPositionInCache < fNumCachedBreakPositions - 1) {
-            ++fPositionInCache;
-            int32_t pos = fCachedBreakPositions[fPositionInCache];
-            utext_setNativeIndex(fText, pos);
-            return pos;
-        }
-        else {
-            reset();
-        }
-    }
-
-    int32_t startPos = current();
-    fDictionaryCharCount = 0;
-    int32_t result = handleNext(fData->fForwardTable);
-    if (fDictionaryCharCount > 0) {
-        result = checkDictionary(startPos, result, FALSE);
-    }
-    return result;
+    fBreakCache->next();
+    return fDone ? UBRK_DONE : fPosition;
 }
 
 /**
- * Advances the iterator backwards, to the last boundary preceding this one.
- * @return The position of the last boundary position preceding this one.
+ * Move the iterator backwards, to the boundary preceding the current one.
+ *
+ *         Starts from the current position within fText.
+ *         Starting position need not be on a boundary.
+ *
+ * @return The position of the boundary position immediately preceding the starting position.
  */
 int32_t RuleBasedBreakIterator::previous(void) {
-    int32_t result;
-    int32_t startPos;
-
-    // if we have cached break positions and we're still in the range
-    // covered by them, just move one step backward in the cache
-    if (fCachedBreakPositions != NULL) {
-        if (fPositionInCache > 0) {
-            --fPositionInCache;
-            // If we're at the beginning of the cache, need to reevaluate the
-            // rule status
-            if (fPositionInCache <= 0) {
-                fLastStatusIndexValid = FALSE;
-            }
-            int32_t pos = fCachedBreakPositions[fPositionInCache];
-            utext_setNativeIndex(fText, pos);
-            return pos;
-        }
-        else {
-            reset();
-        }
-    }
-
-    // if we're already sitting at the beginning of the text, return DONE
-    if (fText == NULL || (startPos = current()) == 0) {
-        fLastRuleStatusIndex  = 0;
-        fLastStatusIndexValid = TRUE;
-        return BreakIterator::DONE;
-    }
-
-    if (fData->fSafeRevTable != NULL || fData->fSafeFwdTable != NULL) {
-        result = handlePrevious(fData->fReverseTable);
-        if (fDictionaryCharCount > 0) {
-            result = checkDictionary(result, startPos, TRUE);
-        }
-        return result;
-    }
-
-    // old rule syntax
-    // set things up.  handlePrevious() will back us up to some valid
-    // break position before the current position (we back our internal
-    // iterator up one step to prevent handlePrevious() from returning
-    // the current position), but not necessarily the last one before
-    // where we started
-
-    int32_t start = current();
-
-    (void)UTEXT_PREVIOUS32(fText);
-    int32_t lastResult    = handlePrevious(fData->fReverseTable);
-    if (lastResult == UBRK_DONE) {
-        lastResult = 0;
-        utext_setNativeIndex(fText, 0);
-    }
-    result = lastResult;
-    int32_t lastTag       = 0;
-    UBool   breakTagValid = FALSE;
-
-    // iterate forward from the known break position until we pass our
-    // starting point.  The last break position before the starting
-    // point is our return value
-
-    for (;;) {
-        result         = next();
-        if (result == BreakIterator::DONE || result >= start) {
-            break;
-        }
-        lastResult     = result;
-        lastTag        = fLastRuleStatusIndex;
-        breakTagValid  = TRUE;
-    }
-
-    // fLastBreakTag wants to have the value for section of text preceding
-    // the result position that we are to return (in lastResult.)  If
-    // the backwards rules overshot and the above loop had to do two or more
-    // next()s to move up to the desired return position, we will have a valid
-    // tag value. But, if handlePrevious() took us to exactly the correct result position,
-    // we wont have a tag value for that position, which is only set by handleNext().
-
-    // Set the current iteration position to be the last break position
-    // before where we started, and then return that value.
-    utext_setNativeIndex(fText, lastResult);
-    fLastRuleStatusIndex  = lastTag;       // for use by getRuleStatus()
-    fLastStatusIndexValid = breakTagValid;
-
-    // No need to check the dictionary; it will have been handled by
-    // next()
-
-    return lastResult;
+    UErrorCode status = U_ZERO_ERROR;
+    fBreakCache->previous(status);
+    return fDone ? UBRK_DONE : fPosition;
 }
 
 /**
  * Sets the iterator to refer to the first boundary position following
  * the specified position.
- * @offset The position from which to begin searching for a break position.
+ * @param startPos The position from which to begin searching for a break position.
  * @return The position of the first break after the current position.
  */
-int32_t RuleBasedBreakIterator::following(int32_t offset) {
-    // if the offset passed in is already past the end of the text,
-    // just return DONE; if it's before the beginning, return the
+int32_t RuleBasedBreakIterator::following(int32_t startPos) {
+    // if the supplied position is before the beginning, return the
     // text's starting offset
-    if (fText == NULL || offset >= utext_nativeLength(fText)) {
-        last();
-        return next();
-    }
-    else if (offset < 0) {
+    if (startPos < 0) {
         return first();
     }
 
     // Move requested offset to a code point start. It might be on a trail surrogate,
-    // or on a trail byte if the input is UTF-8.
-    utext_setNativeIndex(fText, offset);
-    offset = utext_getNativeIndex(fText);
+    // or on a trail byte if the input is UTF-8. Or it may be beyond the end of the text.
+    utext_setNativeIndex(&fText, startPos);
+    startPos = (int32_t)utext_getNativeIndex(&fText);
 
-    // if we have cached break positions and offset is in the range
-    // covered by them, use them
-    // TODO: could use binary search
-    // TODO: what if offset is outside range, but break is not?
-    if (fCachedBreakPositions != NULL) {
-        if (offset >= fCachedBreakPositions[0]
-                && offset < fCachedBreakPositions[fNumCachedBreakPositions - 1]) {
-            fPositionInCache = 0;
-            // We are guaranteed not to leave the array due to range test above
-            while (offset >= fCachedBreakPositions[fPositionInCache]) {
-                ++fPositionInCache;
-            }
-            int32_t pos = fCachedBreakPositions[fPositionInCache];
-            utext_setNativeIndex(fText, pos);
-            return pos;
-        }
-        else {
-            reset();
-        }
-    }
-
-    // Set our internal iteration position (temporarily)
-    // to the position passed in.  If this is the _beginning_ position,
-    // then we can just use next() to get our return value
-
-    int32_t result = 0;
-
-    if (fData->fSafeRevTable != NULL) {
-        // new rule syntax
-        utext_setNativeIndex(fText, offset);
-        // move forward one codepoint to prepare for moving back to a
-        // safe point.
-        // this handles offset being between a supplementary character
-        // TODO: is this still needed, with move to code point boundary handled above?
-        (void)UTEXT_NEXT32(fText);
-        // handlePrevious will move most of the time to < 1 boundary away
-        handlePrevious(fData->fSafeRevTable);
-        int32_t result = next();
-        while (result <= offset) {
-            result = next();
-        }
-        return result;
-    }
-    if (fData->fSafeFwdTable != NULL) {
-        // backup plan if forward safe table is not available
-        utext_setNativeIndex(fText, offset);
-        (void)UTEXT_PREVIOUS32(fText);
-        // handle next will give result >= offset
-        handleNext(fData->fSafeFwdTable);
-        // previous will give result 0 or 1 boundary away from offset,
-        // most of the time
-        // we have to
-        int32_t oldresult = previous();
-        while (oldresult > offset) {
-            int32_t result = previous();
-            if (result <= offset) {
-                return oldresult;
-            }
-            oldresult = result;
-        }
-        int32_t result = next();
-        if (result <= offset) {
-            return next();
-        }
-        return result;
-    }
-    // otherwise, we have to sync up first.  Use handlePrevious() to back
-    // up to a known break position before the specified position (if
-    // we can determine that the specified position is a break position,
-    // we don't back up at all).  This may or may not be the last break
-    // position at or before our starting position.  Advance forward
-    // from here until we've passed the starting position.  The position
-    // we stop on will be the first break position after the specified one.
-    // old rule syntax
-
-    utext_setNativeIndex(fText, offset);
-    if (offset==0 || 
-        (offset==1  && utext_getNativeIndex(fText)==0)) {
-        return next();
-    }
-    result = previous();
-
-    while (result != BreakIterator::DONE && result <= offset) {
-        result = next();
-    }
-
-    return result;
+    UErrorCode status = U_ZERO_ERROR;
+    fBreakCache->following(startPos, status);
+    return fDone ? UBRK_DONE : fPosition;
 }
 
 /**
  * Sets the iterator to refer to the last boundary position before the
  * specified position.
- * @offset The position to begin searching for a break from.
+ * @param offset The position to begin searching for a break from.
  * @return The position of the last boundary before the starting position.
  */
 int32_t RuleBasedBreakIterator::preceding(int32_t offset) {
-    // if the offset passed in is already past the end of the text,
-    // just return DONE; if it's before the beginning, return the
-    // text's starting offset
-    if (fText == NULL || offset > utext_nativeLength(fText)) {
+    if (offset > utext_nativeLength(&fText)) {
         return last();
     }
-    else if (offset < 0) {
-        return first();
-    }
 
     // Move requested offset to a code point start. It might be on a trail surrogate,
     // or on a trail byte if the input is UTF-8.
-    utext_setNativeIndex(fText, offset);
-    offset = utext_getNativeIndex(fText);
 
-    // if we have cached break positions and offset is in the range
-    // covered by them, use them
-    if (fCachedBreakPositions != NULL) {
-        // TODO: binary search?
-        // TODO: What if offset is outside range, but break is not?
-        if (offset > fCachedBreakPositions[0]
-                && offset <= fCachedBreakPositions[fNumCachedBreakPositions - 1]) {
-            fPositionInCache = 0;
-            while (fPositionInCache < fNumCachedBreakPositions
-                   && offset > fCachedBreakPositions[fPositionInCache])
-                ++fPositionInCache;
-            --fPositionInCache;
-            // If we're at the beginning of the cache, need to reevaluate the
-            // rule status
-            if (fPositionInCache <= 0) {
-                fLastStatusIndexValid = FALSE;
-            }
-            utext_setNativeIndex(fText, fCachedBreakPositions[fPositionInCache]);
-            return fCachedBreakPositions[fPositionInCache];
-        }
-        else {
-            reset();
-        }
-    }
+    utext_setNativeIndex(&fText, offset);
+    int32_t adjustedOffset = static_cast<int32_t>(utext_getNativeIndex(&fText));
 
-    // if we start by updating the current iteration position to the
-    // position specified by the caller, we can just use previous()
-    // to carry out this operation
-
-    if (fData->fSafeFwdTable != NULL) {
-        // new rule syntax
-        utext_setNativeIndex(fText, offset);
-        int32_t newOffset = (int32_t)UTEXT_GETNATIVEINDEX(fText);
-        if (newOffset != offset) {
-            // Will come here if specified offset was not a code point boundary AND
-            //   the underlying implmentation is using UText, which snaps any non-code-point-boundary
-            //   indices to the containing code point.
-            // For breakitereator::preceding only, these non-code-point indices need to be moved
-            //   up to refer to the following codepoint.
-            (void)UTEXT_NEXT32(fText);
-            offset = (int32_t)UTEXT_GETNATIVEINDEX(fText);
-        }
-
-        // TODO:  (synwee) would it be better to just check for being in the middle of a surrogate pair,
-        //        rather than adjusting the position unconditionally?
-        //        (Change would interact with safe rules.)
-        // TODO:  change RBBI behavior for off-boundary indices to match that of UText?
-        //        affects only preceding(), seems cleaner, but is slightly different.
-        (void)UTEXT_PREVIOUS32(fText);
-        handleNext(fData->fSafeFwdTable);
-        int32_t result = (int32_t)UTEXT_GETNATIVEINDEX(fText);
-        while (result >= offset) {
-            result = previous();
-        }
-        return result;
-    }
-    if (fData->fSafeRevTable != NULL) {
-        // backup plan if forward safe table is not available
-        //  TODO:  check whether this path can be discarded
-        //         It's probably OK to say that rules must supply both safe tables
-        //            if they use safe tables at all.  We have certainly never described
-        //            to anyone how to work with just one safe table.
-        utext_setNativeIndex(fText, offset);
-        (void)UTEXT_NEXT32(fText);
-        
-        // handle previous will give result <= offset
-        handlePrevious(fData->fSafeRevTable);
-
-        // next will give result 0 or 1 boundary away from offset,
-        // most of the time
-        // we have to
-        int32_t oldresult = next();
-        while (oldresult < offset) {
-            int32_t result = next();
-            if (result >= offset) {
-                return oldresult;
-            }
-            oldresult = result;
-        }
-        int32_t result = previous();
-        if (result >= offset) {
-            return previous();
-        }
-        return result;
-    }
-
-    // old rule syntax
-    utext_setNativeIndex(fText, offset);
-    return previous();
+    UErrorCode status = U_ZERO_ERROR;
+    fBreakCache->preceding(adjustedOffset, status);
+    return fDone ? UBRK_DONE : fPosition;
 }
 
 /**
  * Returns true if the specfied position is a boundary position.  As a side
  * effect, leaves the iterator pointing to the first boundary position at
  * or after "offset".
+ *
  * @param offset the offset to check.
  * @return True if "offset" is a boundary position.
  */
 UBool RuleBasedBreakIterator::isBoundary(int32_t offset) {
-    // the beginning index of the iterator is always a boundary position by definition
-    if (offset == 0) {
-        first();       // For side effects on current position, tag values.
-        return TRUE;
-    }
-
-    if (offset == (int32_t)utext_nativeLength(fText)) {
-        last();       // For side effects on current position, tag values.
-        return TRUE;
-    }
-
     // out-of-range indexes are never boundary positions
     if (offset < 0) {
         first();       // For side effects on current position, tag values.
         return FALSE;
     }
 
-    if (offset > utext_nativeLength(fText)) {
-        last();        // For side effects on current position, tag values.
-        return FALSE;
+    // Adjust offset to be on a code point boundary and not beyond the end of the text.
+    // Note that isBoundary() is always false for offsets that are not on code point boundaries.
+    // But we still need the side effect of leaving iteration at the following boundary.
+
+    utext_setNativeIndex(&fText, offset);
+    int32_t adjustedOffset = static_cast<int32_t>(utext_getNativeIndex(&fText));
+
+    bool result = false;
+    UErrorCode status = U_ZERO_ERROR;
+    if (fBreakCache->seek(adjustedOffset) || fBreakCache->populateNear(adjustedOffset, status)) {
+        result = (fBreakCache->current() == offset);
     }
 
-    // otherwise, we can use following() on the position before the specified
-    // one and return true if the position we get back is the one the user
-    // specified
-    utext_previous32From(fText, offset);
-    int32_t backOne = (int32_t)UTEXT_GETNATIVEINDEX(fText);
-    UBool    result  = following(backOne) == offset;
+    if (result && adjustedOffset < offset && utext_char32At(&fText, offset) == U_SENTINEL) {
+        // Original offset is beyond the end of the text. Return FALSE, it's not a boundary,
+        // but the iteration position remains set to the end of the text, which is a boundary.
+        return FALSE;
+    }
+    if (!result) {
+        // Not on a boundary. isBoundary() must leave iterator on the following boundary.
+        // Cache->seek(), above, left us on the preceding boundary, so advance one.
+        next();
+    }
     return result;
 }
 
+
 /**
  * Returns the current iteration position.
  * @return The current iteration position.
  */
 int32_t RuleBasedBreakIterator::current(void) const {
-    int32_t  pos = (int32_t)UTEXT_GETNATIVEINDEX(fText);
-    return pos;
+    return fPosition;
 }
- 
+
+
 //=======================================================================
 // implementation
 //=======================================================================
@@ -985,57 +742,104 @@
 };
 
 
+// Wrapper functions to select the appropriate handleNext() or handleSafePrevious()
+// instantiation, based on whether an 8 or 16 bit table is required.
+//
+// These Trie access functions will be inlined within the handleNext()/Previous() instantions.
+static inline uint16_t TrieFunc8(const UCPTrie *trie, UChar32 c) {
+    return UCPTRIE_FAST_GET(trie, UCPTRIE_8, c);
+}
+
+static inline uint16_t TrieFunc16(const UCPTrie *trie, UChar32 c) {
+    return UCPTRIE_FAST_GET(trie, UCPTRIE_16, c);
+}
+
+int32_t RuleBasedBreakIterator::handleNext() {
+    const RBBIStateTable *statetable = fData->fForwardTable;
+    bool use8BitsTrie = ucptrie_getValueWidth(fData->fTrie) == UCPTRIE_VALUE_BITS_8;
+    if (statetable->fFlags & RBBI_8BITS_ROWS) {
+        if (use8BitsTrie) {
+            return handleNext<RBBIStateTableRow8, TrieFunc8>();
+        } else {
+            return handleNext<RBBIStateTableRow8, TrieFunc16>();
+        }
+    } else {
+        if (use8BitsTrie) {
+            return handleNext<RBBIStateTableRow16, TrieFunc8>();
+        } else {
+            return handleNext<RBBIStateTableRow16, TrieFunc16>();
+        }
+    }
+}
+
+int32_t RuleBasedBreakIterator::handleSafePrevious(int32_t fromPosition) {
+    const RBBIStateTable *statetable = fData->fReverseTable;
+    bool use8BitsTrie = ucptrie_getValueWidth(fData->fTrie) == UCPTRIE_VALUE_BITS_8;
+    if (statetable->fFlags & RBBI_8BITS_ROWS) {
+        if (use8BitsTrie) {
+            return handleSafePrevious<RBBIStateTableRow8, TrieFunc8>(fromPosition);
+        } else {
+            return handleSafePrevious<RBBIStateTableRow8, TrieFunc16>(fromPosition);
+        }
+    } else {
+        if (use8BitsTrie) {
+            return handleSafePrevious<RBBIStateTableRow16, TrieFunc8>(fromPosition);
+        } else {
+            return handleSafePrevious<RBBIStateTableRow16, TrieFunc16>(fromPosition);
+        }
+    }
+}
+
+
 //-----------------------------------------------------------------------------------
 //
-//  handleNext(stateTable)
-//     This method is the actual implementation of the rbbi next() method. 
-//     This method initializes the state machine to state 1
-//     and advances through the text character by character until we reach the end
-//     of the text or the state machine transitions to state 0.  We update our return
-//     value every time the state machine passes through an accepting state.
+//  handleNext()
+//     Run the state machine to find a boundary
 //
 //-----------------------------------------------------------------------------------
-int32_t RuleBasedBreakIterator::handleNext(const RBBIStateTable *statetable) {
+template <typename RowType, RuleBasedBreakIterator::PTrieFunc trieFunc>
+int32_t RuleBasedBreakIterator::handleNext() {
     int32_t             state;
     uint16_t            category        = 0;
     RBBIRunMode         mode;
-    
-    RBBIStateTableRow  *row;
-    UChar32             c;
-    int32_t             lookaheadStatus = 0;
-    int32_t             lookaheadTagIdx = 0;
-    int32_t             result          = 0;
-    int32_t             initialPosition = 0;
-    int32_t             lookaheadResult = 0;
-    UBool               lookAheadHardBreak = (statetable->fFlags & RBBI_LOOKAHEAD_HARD_BREAK) != 0;
-    const char         *tableData       = statetable->fTableData;
-    uint32_t            tableRowLen     = statetable->fRowLen;
 
+    RowType             *row;
+    UChar32             c;
+    int32_t             result             = 0;
+    int32_t             initialPosition    = 0;
+    const RBBIStateTable *statetable       = fData->fForwardTable;
+    const char         *tableData          = statetable->fTableData;
+    uint32_t            tableRowLen        = statetable->fRowLen;
+    uint32_t            dictStart          = statetable->fDictCategoriesStart;
     #ifdef RBBI_DEBUG
-        if (fTrace) {
+        if (gTrace) {
             RBBIDebugPuts("Handle Next   pos   char  state category");
         }
     #endif
 
-    // No matter what, handleNext alway correctly sets the break tag value.
-    fLastStatusIndexValid = TRUE;
-    fLastRuleStatusIndex = 0;
+    // handleNext alway sets the break tag value.
+    // Set the default for it.
+    fRuleStatusIndex = 0;
+
+    fDictionaryCharCount = 0;
 
     // if we're already at the end of the text, return DONE.
-    initialPosition = (int32_t)UTEXT_GETNATIVEINDEX(fText); 
+    initialPosition = fPosition;
+    UTEXT_SETNATIVEINDEX(&fText, initialPosition);
     result          = initialPosition;
-    c               = UTEXT_NEXT32(fText);
-    if (fData == NULL || c==U_SENTINEL) {
-        return BreakIterator::DONE;
+    c               = UTEXT_NEXT32(&fText);
+    if (c==U_SENTINEL) {
+        fDone = TRUE;
+        return UBRK_DONE;
     }
 
     //  Set the initial state for the state machine
     state = START_STATE;
-    row = (RBBIStateTableRow *)
+    row = (RowType *)
             //(statetable->fTableData + (statetable->fRowLen * state));
             (tableData + tableRowLen * state);
-            
-    
+
+
     mode     = RBBI_RUN;
     if (statetable->fFlags & RBBI_BOF_REQUIRED) {
         category = 2;
@@ -1049,17 +853,9 @@
         if (c == U_SENTINEL) {
             // Reached end of input string.
             if (mode == RBBI_END) {
-                // We have already run the loop one last time with the 
+                // We have already run the loop one last time with the
                 //   character set to the psueudo {eof} value.  Now it is time
                 //   to unconditionally bail out.
-                if (lookaheadResult > result) {
-                    // We ran off the end of the string with a pending look-ahead match.
-                    // Treat this as if the look-ahead condition had been met, and return
-                    //  the match at the / position from the look-ahead rule.
-                    result               = lookaheadResult;
-                    fLastRuleStatusIndex = lookaheadTagIdx;
-                    lookaheadStatus = 0;
-                } 
                 break;
             }
             // Run the loop one last time with the fake end-of-input character category.
@@ -1075,26 +871,13 @@
         if (mode == RBBI_RUN) {
             // look up the current character's character category, which tells us
             // which column in the state table to look at.
-            // Note:  the 16 in UTRIE_GET16 refers to the size of the data being returned,
-            //        not the size of the character going in, which is a UChar32.
-            //
-            UTRIE_GET16(&fData->fTrie, c, category);
-
-            // Check the dictionary bit in the character's category.
-            //    Counter is only used by dictionary based iterators (subclasses).
-            //    Chars that need to be handled by a dictionary have a flag bit set
-            //    in their category values.
-            //
-            if ((category & 0x4000) != 0)  {
-                fDictionaryCharCount++;
-                //  And off the dictionary flag bit.
-                category &= ~0x4000;
-            }
+            category = trieFunc(fData->fTrie, c);
+            fDictionaryCharCount += (category >= dictStart);
         }
 
        #ifdef RBBI_DEBUG
-            if (fTrace) {
-                RBBIDebugPrintf("             %4ld   ", utext_getNativeIndex(fText));
+            if (gTrace) {
+                RBBIDebugPrintf("             %4" PRId64 "   ", utext_getNativeIndex(&fText));
                 if (0x20<=c && c<0x7f) {
                     RBBIDebugPrintf("\"%c\"  ", c);
                 } else {
@@ -1107,76 +890,64 @@
         // State Transition - move machine to its next state
         //
 
-        // Note: fNextState is defined as uint16_t[2], but we are casting
-        // a generated RBBI table to RBBIStateTableRow and some tables
-        // actually have more than 2 categories.
+        // fNextState is a variable-length array.
         U_ASSERT(category<fData->fHeader->fCatCount);
         state = row->fNextState[category];  /*Not accessing beyond memory*/
-        row = (RBBIStateTableRow *)
+        row = (RowType *)
             // (statetable->fTableData + (statetable->fRowLen * state));
             (tableData + tableRowLen * state);
 
 
-        if (row->fAccepting == -1) {
+        uint16_t accepting = row->fAccepting;
+        if (accepting == ACCEPTING_UNCONDITIONAL) {
             // Match found, common case.
             if (mode != RBBI_START) {
-                result = (int32_t)UTEXT_GETNATIVEINDEX(fText);
+                result = (int32_t)UTEXT_GETNATIVEINDEX(&fText);
             }
-            fLastRuleStatusIndex = row->fTagIdx;   // Remember the break status (tag) values.
-        }
-
-        if (row->fLookAhead != 0) {
-            if (lookaheadStatus != 0
-                && row->fAccepting == lookaheadStatus) {
-                // Lookahead match is completed.  
-                result               = lookaheadResult;
-                fLastRuleStatusIndex = lookaheadTagIdx;
-                lookaheadStatus      = 0;
-                // TODO:  make a standalone hard break in a rule work.
-                if (lookAheadHardBreak) {
-                    UTEXT_SETNATIVEINDEX(fText, result);
-                    return result;
-                }
-                // Look-ahead completed, but other rules may match further.  Continue on
-                //  TODO:  junk this feature?  I don't think it's used anywhwere.
-                goto continueOn;
+            fRuleStatusIndex = row->fTagsIdx;   // Remember the break status (tag) values.
+        } else if (accepting > ACCEPTING_UNCONDITIONAL) {
+            // Lookahead match is completed.
+            U_ASSERT(accepting < fData->fForwardTable->fLookAheadResultsSize);
+            int32_t lookaheadResult = fLookAheadMatches[accepting];
+            if (lookaheadResult >= 0) {
+                fRuleStatusIndex = row->fTagsIdx;
+                fPosition = lookaheadResult;
+                return lookaheadResult;
             }
-
-            int32_t  r = (int32_t)UTEXT_GETNATIVEINDEX(fText);
-            lookaheadResult = r;
-            lookaheadStatus = row->fLookAhead;
-            lookaheadTagIdx = row->fTagIdx;
-            goto continueOn;
         }
 
-
-        if (row->fAccepting != 0) {
-            // Because this is an accepting state, any in-progress look-ahead match
-            //   is no longer relavant.  Clear out the pending lookahead status.
-            lookaheadStatus = 0;           // clear out any pending look-ahead match.
+        // If we are at the position of the '/' in a look-ahead (hard break) rule;
+        // record the current position, to be returned later, if the full rule matches.
+        // TODO: Move this check before the previous check of fAccepting.
+        //       This would enable hard-break rules with no following context.
+        //       But there are line break test failures when trying this. Investigate.
+        //       Issue ICU-20837
+        uint16_t rule = row->fLookAhead;
+        U_ASSERT(rule == 0 || rule > ACCEPTING_UNCONDITIONAL);
+        U_ASSERT(rule == 0 || rule < fData->fForwardTable->fLookAheadResultsSize);
+        if (rule > ACCEPTING_UNCONDITIONAL) {
+            int32_t  pos = (int32_t)UTEXT_GETNATIVEINDEX(&fText);
+            fLookAheadMatches[rule] = pos;
         }
 
-continueOn:
         if (state == STOP_STATE) {
             // This is the normal exit from the lookup state machine.
             // We have advanced through the string until it is certain that no
             //   longer match is possible, no matter what characters follow.
             break;
         }
-        
-        // Advance to the next character.  
+
+        // Advance to the next character.
         // If this is a beginning-of-input loop iteration, don't advance
         //    the input position.  The next iteration will be processing the
         //    first real input character.
         if (mode == RBBI_RUN) {
-            c = UTEXT_NEXT32(fText);
+            c = UTEXT_NEXT32(&fText);
         } else {
             if (mode == RBBI_START) {
                 mode = RBBI_RUN;
             }
         }
-
-
     }
 
     // The state machine is done.  Check whether it found a match...
@@ -1185,15 +956,16 @@
     //   (This really indicates a defect in the break rules.  They should always match
     //    at least one character.)
     if (result == initialPosition) {
-        UTEXT_SETNATIVEINDEX(fText, initialPosition);
-        UTEXT_NEXT32(fText);
-        result = (int32_t)UTEXT_GETNATIVEINDEX(fText);
+        utext_setNativeIndex(&fText, initialPosition);
+        utext_next32(&fText);
+        result = (int32_t)utext_getNativeIndex(&fText);
+        fRuleStatusIndex = 0;
     }
 
     // Leave the iterator at our result position.
-    UTEXT_SETNATIVEINDEX(fText, result);
+    fPosition = result;
     #ifdef RBBI_DEBUG
-        if (fTrace) {
+        if (gTrace) {
             RBBIDebugPrintf("result = %d\n\n", result);
         }
     #endif
@@ -1201,120 +973,56 @@
 }
 
 
+//-----------------------------------------------------------------------------------
+//
+//  handleSafePrevious()
+//
+//      Iterate backwards using the safe reverse rules.
+//      The logic of this function is similar to handleNext(), but simpler
+//      because the safe table does not require as many options.
+//
+//-----------------------------------------------------------------------------------
+template <typename RowType, RuleBasedBreakIterator::PTrieFunc trieFunc>
+int32_t RuleBasedBreakIterator::handleSafePrevious(int32_t fromPosition) {
 
-//-----------------------------------------------------------------------------------
-//
-//  handlePrevious()
-//
-//      Iterate backwards, according to the logic of the reverse rules.
-//      This version handles the exact style backwards rules.
-//
-//      The logic of this function is very similar to handleNext(), above.
-//
-//-----------------------------------------------------------------------------------
-int32_t RuleBasedBreakIterator::handlePrevious(const RBBIStateTable *statetable) {
     int32_t             state;
     uint16_t            category        = 0;
-    RBBIRunMode         mode;
-    RBBIStateTableRow  *row;
+    RowType            *row;
     UChar32             c;
-    int32_t             lookaheadStatus = 0;
     int32_t             result          = 0;
-    int32_t             initialPosition = 0;
-    int32_t             lookaheadResult = 0;
-    UBool               lookAheadHardBreak = (statetable->fFlags & RBBI_LOOKAHEAD_HARD_BREAK) != 0;
 
+    const RBBIStateTable *stateTable = fData->fReverseTable;
+    UTEXT_SETNATIVEINDEX(&fText, fromPosition);
     #ifdef RBBI_DEBUG
-        if (fTrace) {
+        if (gTrace) {
             RBBIDebugPuts("Handle Previous   pos   char  state category");
         }
     #endif
 
-    // handlePrevious() never gets the rule status.
-    // Flag the status as invalid; if the user ever asks for status, we will need
-    // to back up, then re-find the break position using handleNext(), which does
-    // get the status value.
-    fLastStatusIndexValid = FALSE;
-    fLastRuleStatusIndex = 0;
-
     // if we're already at the start of the text, return DONE.
-    if (fText == NULL || fData == NULL || UTEXT_GETNATIVEINDEX(fText)==0) {
+    if (fData == NULL || UTEXT_GETNATIVEINDEX(&fText)==0) {
         return BreakIterator::DONE;
     }
 
-    //  Set up the starting char.
-    initialPosition = (int32_t)UTEXT_GETNATIVEINDEX(fText);
-    result          = initialPosition;
-    c               = UTEXT_PREVIOUS32(fText);
-
     //  Set the initial state for the state machine
+    c = UTEXT_PREVIOUS32(&fText);
     state = START_STATE;
-    row = (RBBIStateTableRow *)
-            (statetable->fTableData + (statetable->fRowLen * state));
-    category = 3;
-    mode     = RBBI_RUN;
-    if (statetable->fFlags & RBBI_BOF_REQUIRED) {
-        category = 2;
-        mode     = RBBI_START;
-    }
-
+    row = (RowType *)
+            (stateTable->fTableData + (stateTable->fRowLen * state));
 
     // loop until we reach the start of the text or transition to state 0
     //
-    for (;;) {
-        if (c == U_SENTINEL) {
-            // Reached end of input string.
-            if (mode == RBBI_END) {
-                // We have already run the loop one last time with the 
-                //   character set to the psueudo {eof} value.  Now it is time
-                //   to unconditionally bail out.
-                if (lookaheadResult < result) {
-                    // We ran off the end of the string with a pending look-ahead match.
-                    // Treat this as if the look-ahead condition had been met, and return
-                    //  the match at the / position from the look-ahead rule.
-                    result               = lookaheadResult;
-                    lookaheadStatus = 0;
-                } else if (result == initialPosition) {
-                    // Ran off start, no match found.
-                    // move one index one (towards the start, since we are doing a previous())
-                    UTEXT_SETNATIVEINDEX(fText, initialPosition);
-                    (void)UTEXT_PREVIOUS32(fText);   // TODO:  shouldn't be necessary.  We're already at beginning.  Check.
-                }
-                break;
-            }
-            // Run the loop one last time with the fake end-of-input character category.
-            mode = RBBI_END;
-            category = 1;
-        }
+    for (; c != U_SENTINEL; c = UTEXT_PREVIOUS32(&fText)) {
 
+        // look up the current character's character category, which tells us
+        // which column in the state table to look at.
         //
-        // Get the char category.  An incoming category of 1 or 2 means that
-        //      we are preset for doing the beginning or end of input, and
-        //      that we shouldn't get a category from an actual text input character.
-        //
-        if (mode == RBBI_RUN) {
-            // look up the current character's character category, which tells us
-            // which column in the state table to look at.
-            // Note:  the 16 in UTRIE_GET16 refers to the size of the data being returned,
-            //        not the size of the character going in, which is a UChar32.
-            //
-            UTRIE_GET16(&fData->fTrie, c, category);
-
-            // Check the dictionary bit in the character's category.
-            //    Counter is only used by dictionary based iterators (subclasses).
-            //    Chars that need to be handled by a dictionary have a flag bit set
-            //    in their category values.
-            //
-            if ((category & 0x4000) != 0)  {
-                fDictionaryCharCount++;
-                //  And off the dictionary flag bit.
-                category &= ~0x4000;
-            }
-        }
+        //  Off the dictionary flag bit. For reverse iteration it is not used.
+        category = trieFunc(fData->fTrie, c);
 
         #ifdef RBBI_DEBUG
-            if (fTrace) {
-                RBBIDebugPrintf("             %4d   ", (int32_t)utext_getNativeIndex(fText));
+            if (gTrace) {
+                RBBIDebugPrintf("             %4d   ", (int32_t)utext_getNativeIndex(&fText));
                 if (0x20<=c && c<0x7f) {
                     RBBIDebugPrintf("\"%c\"  ", c);
                 } else {
@@ -1326,85 +1034,23 @@
 
         // State Transition - move machine to its next state
         //
-
-        // Note: fNextState is defined as uint16_t[2], but we are casting
-        // a generated RBBI table to RBBIStateTableRow and some tables
-        // actually have more than 2 categories.
+        // fNextState is a variable-length array.
         U_ASSERT(category<fData->fHeader->fCatCount);
         state = row->fNextState[category];  /*Not accessing beyond memory*/
-        row = (RBBIStateTableRow *)
-            (statetable->fTableData + (statetable->fRowLen * state));
+        row = (RowType *)
+            (stateTable->fTableData + (stateTable->fRowLen * state));
 
-        if (row->fAccepting == -1) {
-            // Match found, common case.
-            result = (int32_t)UTEXT_GETNATIVEINDEX(fText);
-        }
-
-        if (row->fLookAhead != 0) {
-            if (lookaheadStatus != 0
-                && row->fAccepting == lookaheadStatus) {
-                // Lookahead match is completed.  
-                result               = lookaheadResult;
-                lookaheadStatus      = 0;
-                // TODO:  make a standalone hard break in a rule work.
-                if (lookAheadHardBreak) {
-                    UTEXT_SETNATIVEINDEX(fText, result);
-                    return result;
-                }
-                // Look-ahead completed, but other rules may match further.  Continue on
-                //  TODO:  junk this feature?  I don't think it's used anywhwere.
-                goto continueOn;
-            }
-
-            int32_t  r = (int32_t)UTEXT_GETNATIVEINDEX(fText);
-            lookaheadResult = r;
-            lookaheadStatus = row->fLookAhead;
-            goto continueOn;
-        }
-
-
-        if (row->fAccepting != 0) {
-            // Because this is an accepting state, any in-progress look-ahead match
-            //   is no longer relavant.  Clear out the pending lookahead status.
-            lookaheadStatus = 0;    
-        }
-
-continueOn:
         if (state == STOP_STATE) {
             // This is the normal exit from the lookup state machine.
-            // We have advanced through the string until it is certain that no
-            //   longer match is possible, no matter what characters follow.
+            // Transistion to state zero means we have found a safe point.
             break;
         }
-
-        // Move (backwards) to the next character to process.  
-        // If this is a beginning-of-input loop iteration, don't advance
-        //    the input position.  The next iteration will be processing the
-        //    first real input character.
-        if (mode == RBBI_RUN) {
-            c = UTEXT_PREVIOUS32(fText);
-        } else {            
-            if (mode == RBBI_START) {
-                mode = RBBI_RUN;
-            }
-        }
     }
 
     // The state machine is done.  Check whether it found a match...
-
-    // If the iterator failed to advance in the match engine, force it ahead by one.
-    //   (This really indicates a defect in the break rules.  They should always match
-    //    at least one character.)
-    if (result == initialPosition) {
-        UTEXT_SETNATIVEINDEX(fText, initialPosition);
-        UTEXT_PREVIOUS32(fText);
-        result = (int32_t)UTEXT_GETNATIVEINDEX(fText);
-    }
-
-    // Leave the iterator at our result position.
-    UTEXT_SETNATIVEINDEX(fText, result);
+    result = (int32_t)UTEXT_GETNATIVEINDEX(&fText);
     #ifdef RBBI_DEBUG
-        if (fTrace) {
+        if (gTrace) {
             RBBIDebugPrintf("result = %d\n\n", result);
         }
     #endif
@@ -1412,20 +1058,6 @@
 }
 
 
-void
-RuleBasedBreakIterator::reset()
-{
-    if (fCachedBreakPositions) {
-        uprv_free(fCachedBreakPositions);
-    }
-    fCachedBreakPositions = NULL;
-    fNumCachedBreakPositions = 0;
-    fDictionaryCharCount = 0;
-    fPositionInCache = 0;
-}
-
-
-
 //-------------------------------------------------------------------------------
 //
 //   getRuleStatus()   Return the break rule tag associated with the current
@@ -1433,64 +1065,27 @@
 //                     position by iterating forwards, the value will have been
 //                     cached by the handleNext() function.
 //
-//                     If no cached status value is available, the status is
-//                     found by doing a previous() followed by a next(), which
-//                     leaves the iterator where it started, and computes the
-//                     status while doing the next().
-//
 //-------------------------------------------------------------------------------
-void RuleBasedBreakIterator::makeRuleStatusValid() {
-    if (fLastStatusIndexValid == FALSE) {
-        //  No cached status is available.
-        if (fText == NULL || current() == 0) {
-            //  At start of text, or there is no text.  Status is always zero.
-            fLastRuleStatusIndex = 0;
-            fLastStatusIndexValid = TRUE;
-        } else {
-            //  Not at start of text.  Find status the tedious way.
-            int32_t pa = current();
-            previous();
-            if (fNumCachedBreakPositions > 0) {
-                reset();                // Blow off the dictionary cache
-            }
-            int32_t pb = next();
-            if (pa != pb) {
-                // note: the if (pa != pb) test is here only to eliminate warnings for
-                //       unused local variables on gcc.  Logically, it isn't needed.
-                U_ASSERT(pa == pb);
-            }
-        }
-    }
-    U_ASSERT(fLastRuleStatusIndex >= 0  &&  fLastRuleStatusIndex < fData->fStatusMaxIdx);
-}
-
 
 int32_t  RuleBasedBreakIterator::getRuleStatus() const {
-    RuleBasedBreakIterator *nonConstThis  = (RuleBasedBreakIterator *)this;
-    nonConstThis->makeRuleStatusValid();
 
     // fLastRuleStatusIndex indexes to the start of the appropriate status record
     //                                                 (the number of status values.)
     //   This function returns the last (largest) of the array of status values.
-    int32_t  idx = fLastRuleStatusIndex + fData->fRuleStatusTable[fLastRuleStatusIndex];
+    int32_t  idx = fRuleStatusIndex + fData->fRuleStatusTable[fRuleStatusIndex];
     int32_t  tagVal = fData->fRuleStatusTable[idx];
 
     return tagVal;
 }
 
 
-
-
 int32_t RuleBasedBreakIterator::getRuleStatusVec(
-             int32_t *fillInVec, int32_t capacity, UErrorCode &status)
-{
+             int32_t *fillInVec, int32_t capacity, UErrorCode &status) {
     if (U_FAILURE(status)) {
         return 0;
     }
 
-    RuleBasedBreakIterator *nonConstThis  = (RuleBasedBreakIterator *)this;
-    nonConstThis->makeRuleStatusValid();
-    int32_t  numVals = fData->fRuleStatusTable[fLastRuleStatusIndex];
+    int32_t  numVals = fData->fRuleStatusTable[fRuleStatusIndex];
     int32_t  numValsToCopy = numVals;
     if (numVals > capacity) {
         status = U_BUFFER_OVERFLOW_ERROR;
@@ -1498,7 +1093,7 @@
     }
     int i;
     for (i=0; i<numValsToCopy; i++) {
-        fillInVec[i] = fData->fRuleStatusTable[fLastRuleStatusIndex + i + 1];
+        fillInVec[i] = fData->fRuleStatusTable[fRuleStatusIndex + i + 1];
     }
     return numVals;
 }
@@ -1524,10 +1119,8 @@
 }
 
 
-BreakIterator *  RuleBasedBreakIterator::createBufferClone(void * /*stackBuffer*/,
-                                   int32_t &bufferSize,
-                                   UErrorCode &status)
-{
+RuleBasedBreakIterator *RuleBasedBreakIterator::createBufferClone(
+        void * /*stackBuffer*/, int32_t &bufferSize, UErrorCode &status) {
     if (U_FAILURE(status)){
         return NULL;
     }
@@ -1546,205 +1139,25 @@
     return (RuleBasedBreakIterator *)clonedBI;
 }
 
-
-//-------------------------------------------------------------------------------
-//
-//  isDictionaryChar      Return true if the category lookup for this char
-//                        indicates that it is in the set of dictionary lookup
-//                        chars.
-//
-//                        This function is intended for use by dictionary based
-//                        break iterators.
-//
-//-------------------------------------------------------------------------------
-/*UBool RuleBasedBreakIterator::isDictionaryChar(UChar32   c) {
-    if (fData == NULL) {
-        return FALSE;
-    }
-    uint16_t category;
-    UTRIE_GET16(&fData->fTrie, c, category);
-    return (category & 0x4000) != 0;
-}*/
-
-
-//-------------------------------------------------------------------------------
-//
-//  checkDictionary       This function handles all processing of characters in
-//                        the "dictionary" set. It will determine the appropriate
-//                        course of action, and possibly set up a cache in the
-//                        process.
-//
-//-------------------------------------------------------------------------------
-int32_t RuleBasedBreakIterator::checkDictionary(int32_t startPos,
-                            int32_t endPos,
-                            UBool reverse) {
-    // Reset the old break cache first.
-    reset();
-
-    // note: code segment below assumes that dictionary chars are in the 
-    // startPos-endPos range
-    // value returned should be next character in sequence
-    if ((endPos - startPos) <= 1) {
-        return (reverse ? startPos : endPos);
-    }
-    
-    // Starting from the starting point, scan towards the proposed result,
-    // looking for the first dictionary character (which may be the one
-    // we're on, if we're starting in the middle of a range).
-    utext_setNativeIndex(fText, reverse ? endPos : startPos);
-    if (reverse) {
-        UTEXT_PREVIOUS32(fText);
-    }
-    
-    int32_t rangeStart = startPos;
-    int32_t rangeEnd = endPos;
-
-    uint16_t    category;
-    int32_t     current;
-    UErrorCode  status = U_ZERO_ERROR;
-    UStack      breaks(status);
-    int32_t     foundBreakCount = 0;
-    UChar32     c = utext_current32(fText);
-
-    UTRIE_GET16(&fData->fTrie, c, category);
-    
-    // Is the character we're starting on a dictionary character? If so, we
-    // need to back up to include the entire run; otherwise the results of
-    // the break algorithm will differ depending on where we start. Since
-    // the result is cached and there is typically a non-dictionary break
-    // within a small number of words, there should be little performance impact.
-    if (category & 0x4000) {
-        if (reverse) {
-            do {
-                utext_next32(fText);          // TODO:  recast to work directly with postincrement.
-                c = utext_current32(fText);
-                UTRIE_GET16(&fData->fTrie, c, category);
-            } while (c != U_SENTINEL && (category & 0x4000));
-            // Back up to the last dictionary character
-            rangeEnd = (int32_t)UTEXT_GETNATIVEINDEX(fText);
-            if (c == U_SENTINEL) {
-                // c = fText->last32();
-                //   TODO:  why was this if needed?
-                c = UTEXT_PREVIOUS32(fText);
-            }
-            else {
-                c = UTEXT_PREVIOUS32(fText);
-            }
-        }
-        else {
-            do {
-                c = UTEXT_PREVIOUS32(fText);
-                UTRIE_GET16(&fData->fTrie, c, category);
-            }
-            while (c != U_SENTINEL && (category & 0x4000));
-            // Back up to the last dictionary character
-            if (c == U_SENTINEL) {
-                // c = fText->first32();
-                c = utext_current32(fText);
-            }
-            else {
-                utext_next32(fText);
-                c = utext_current32(fText);
-            }
-            rangeStart = (int32_t)UTEXT_GETNATIVEINDEX(fText);;
-        }
-        UTRIE_GET16(&fData->fTrie, c, category);
-    }
-    
-    // Loop through the text, looking for ranges of dictionary characters.
-    // For each span, find the appropriate break engine, and ask it to find
-    // any breaks within the span.
-    // Note: we always do this in the forward direction, so that the break
-    // cache is built in the right order.
-    if (reverse) {
-        utext_setNativeIndex(fText, rangeStart);
-        c = utext_current32(fText);
-        UTRIE_GET16(&fData->fTrie, c, category);
-    }
-    while(U_SUCCESS(status)) {
-        while((current = (int32_t)UTEXT_GETNATIVEINDEX(fText)) < rangeEnd && (category & 0x4000) == 0) {
-            utext_next32(fText);           // TODO:  tweak for post-increment operation
-            c = utext_current32(fText);
-            UTRIE_GET16(&fData->fTrie, c, category);
-        }
-        if (current >= rangeEnd) {
-            break;
-        }
-        
-        // We now have a dictionary character. Get the appropriate language object
-        // to deal with it.
-        const LanguageBreakEngine *lbe = getLanguageBreakEngine(c);
-        
-        // Ask the language object if there are any breaks. It will leave the text
-        // pointer on the other side of its range, ready to search for the next one.
-        if (lbe != NULL) {
-            foundBreakCount += lbe->findBreaks(fText, rangeStart, rangeEnd, FALSE, fBreakType, breaks);
-        }
-        
-        // Reload the loop variables for the next go-round
-        c = utext_current32(fText);
-        UTRIE_GET16(&fData->fTrie, c, category);
-    }
-    
-    // If we found breaks, build a new break cache. The first and last entries must
-    // be the original starting and ending position.
-    if (foundBreakCount > 0) {
-        U_ASSERT(foundBreakCount == breaks.size());
-        int32_t totalBreaks = foundBreakCount;
-        if (startPos < breaks.elementAti(0)) {
-            totalBreaks += 1;
-        }
-        if (endPos > breaks.peeki()) {
-            totalBreaks += 1;
-        }
-        fCachedBreakPositions = (int32_t *)uprv_malloc(totalBreaks * sizeof(int32_t));
-        if (fCachedBreakPositions != NULL) {
-            int32_t out = 0;
-            fNumCachedBreakPositions = totalBreaks;
-            if (startPos < breaks.elementAti(0)) {
-                fCachedBreakPositions[out++] = startPos;
-            }
-            for (int32_t i = 0; i < foundBreakCount; ++i) {
-                fCachedBreakPositions[out++] = breaks.elementAti(i);
-            }
-            if (endPos > fCachedBreakPositions[out-1]) {
-                fCachedBreakPositions[out] = endPos;
-            }
-            // If there are breaks, then by definition, we are replacing the original
-            // proposed break by one of the breaks we found. Use following() and
-            // preceding() to do the work. They should never recurse in this case.
-            if (reverse) {
-                return preceding(endPos);
-            }
-            else {
-                return following(startPos);
-            }
-        }
-        // If the allocation failed, just fall through to the "no breaks found" case.
-    }
-
-    // If we get here, there were no language-based breaks. Set the text pointer
-    // to the original proposed break.
-    utext_setNativeIndex(fText, reverse ? startPos : endPos);
-    return (reverse ? startPos : endPos);
-}
-
 U_NAMESPACE_END
 
 
-static icu::UStack *gLanguageBreakFactories = NULL;
+static icu::UStack *gLanguageBreakFactories = nullptr;
+static const icu::UnicodeString *gEmptyString = nullptr;
 static icu::UInitOnce gLanguageBreakFactoriesInitOnce = U_INITONCE_INITIALIZER;
+static icu::UInitOnce gRBBIInitOnce = U_INITONCE_INITIALIZER;
 
 /**
- * Release all static memory held by breakiterator.  
+ * Release all static memory held by breakiterator.
  */
 U_CDECL_BEGIN
-static UBool U_CALLCONV breakiterator_cleanup_dict(void) {
-    if (gLanguageBreakFactories) {
-        delete gLanguageBreakFactories;
-        gLanguageBreakFactories = NULL;
-    }
+UBool U_CALLCONV rbbi_cleanup(void) {
+    delete gLanguageBreakFactories;
+    gLanguageBreakFactories = nullptr;
+    delete gEmptyString;
+    gEmptyString = nullptr;
     gLanguageBreakFactoriesInitOnce.reset();
+    gRBBIInitOnce.reset();
     return TRUE;
 }
 U_CDECL_END
@@ -1756,6 +1169,11 @@
 U_CDECL_END
 U_NAMESPACE_BEGIN
 
+static void U_CALLCONV rbbiInit() {
+    gEmptyString = new UnicodeString();
+    ucln_common_registerCleanup(UCLN_COMMON_RBBI, rbbi_cleanup);
+}
+
 static void U_CALLCONV initLanguageFactories() {
     UErrorCode status = U_ZERO_ERROR;
     U_ASSERT(gLanguageBreakFactories == NULL);
@@ -1770,23 +1188,23 @@
         }
 #endif
     }
-    ucln_common_registerCleanup(UCLN_COMMON_BREAKITERATOR_DICT, breakiterator_cleanup_dict);
+    ucln_common_registerCleanup(UCLN_COMMON_RBBI, rbbi_cleanup);
 }
 
 
 static const LanguageBreakEngine*
-getLanguageBreakEngineFromFactory(UChar32 c, int32_t breakType)
+getLanguageBreakEngineFromFactory(UChar32 c)
 {
     umtx_initOnce(gLanguageBreakFactoriesInitOnce, &initLanguageFactories);
     if (gLanguageBreakFactories == NULL) {
         return NULL;
     }
-    
+
     int32_t i = gLanguageBreakFactories->size();
     const LanguageBreakEngine *lbe = NULL;
     while (--i >= 0) {
         LanguageBreakFactory *factory = (LanguageBreakFactory *)(gLanguageBreakFactories->elementAt(i));
-        lbe = factory->getEngineFor(c, breakType);
+        lbe = factory->getEngineFor(c);
         if (lbe != NULL) {
             break;
         }
@@ -1805,7 +1223,7 @@
 RuleBasedBreakIterator::getLanguageBreakEngine(UChar32 c) {
     const LanguageBreakEngine *lbe = NULL;
     UErrorCode status = U_ZERO_ERROR;
-    
+
     if (fLanguageBreakEngines == NULL) {
         fLanguageBreakEngines = new UStack(status);
         if (fLanguageBreakEngines == NULL || U_FAILURE(status)) {
@@ -1814,19 +1232,19 @@
             return NULL;
         }
     }
-    
+
     int32_t i = fLanguageBreakEngines->size();
     while (--i >= 0) {
         lbe = (const LanguageBreakEngine *)(fLanguageBreakEngines->elementAt(i));
-        if (lbe->handles(c, fBreakType)) {
+        if (lbe->handles(c)) {
             return lbe;
         }
     }
-    
+
     // No existing dictionary took the character. See if a factory wants to
     // give us a new LanguageBreakEngine for this character.
-    lbe = getLanguageBreakEngineFromFactory(c, fBreakType);
-    
+    lbe = getLanguageBreakEngineFromFactory(c);
+
     // If we got one, use it and push it on our stack.
     if (lbe != NULL) {
         fLanguageBreakEngines->push((void *)lbe, status);
@@ -1834,13 +1252,14 @@
         // return it even if the push fails.
         return lbe;
     }
-    
+
     // No engine is forthcoming for this character. Add it to the
     // reject set. Create the reject break engine if needed.
     if (fUnhandledBreakEngine == NULL) {
         fUnhandledBreakEngine = new UnhandledEngine(status);
         if (U_SUCCESS(status) && fUnhandledBreakEngine == NULL) {
             status = U_MEMORY_ALLOCATION_ERROR;
+            return nullptr;
         }
         // Put it last so that scripts for which we have an engine get tried
         // first.
@@ -1852,23 +1271,34 @@
             return NULL;
         }
     }
-    
+
     // Tell the reject engine about the character; at its discretion, it may
     // add more than just the one character.
-    fUnhandledBreakEngine->handleCharacter(c, fBreakType);
-        
+    fUnhandledBreakEngine->handleCharacter(c);
+
     return fUnhandledBreakEngine;
 }
 
+void RuleBasedBreakIterator::dumpCache() {
+    fBreakCache->dumpCache();
+}
 
+void RuleBasedBreakIterator::dumpTables() {
+    fData->printData();
+}
 
-/*int32_t RuleBasedBreakIterator::getBreakType() const {
-    return fBreakType;
-}*/
+/**
+ * Returns the description used to create this iterator
+ */
 
-void RuleBasedBreakIterator::setBreakType(int32_t type) {
-    fBreakType = type;
-    reset();
+const UnicodeString&
+RuleBasedBreakIterator::getRules() const {
+    if (fData != NULL) {
+        return fData->getRuleSourceString();
+    } else {
+        umtx_initOnce(gRBBIInitOnce, &rbbiInit);
+        return *gEmptyString;
+    }
 }
 
 U_NAMESPACE_END
diff --git a/src/third_party/icu/source/common/rbbi_cache.cpp b/src/third_party/icu/source/common/rbbi_cache.cpp
new file mode 100644
index 0000000..63ff300
--- /dev/null
+++ b/src/third_party/icu/source/common/rbbi_cache.cpp
@@ -0,0 +1,655 @@
+// Copyright (C) 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+// file: rbbi_cache.cpp
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_BREAK_ITERATION
+
+#include "unicode/ubrk.h"
+#include "unicode/rbbi.h"
+
+#include "rbbi_cache.h"
+
+#include "brkeng.h"
+#include "cmemory.h"
+#include "rbbidata.h"
+#include "rbbirb.h"
+#include "uassert.h"
+#include "uvectr32.h"
+
+U_NAMESPACE_BEGIN
+
+/*
+ * DictionaryCache implementation
+ */
+
+RuleBasedBreakIterator::DictionaryCache::DictionaryCache(RuleBasedBreakIterator *bi, UErrorCode &status) :
+        fBI(bi), fBreaks(status), fPositionInCache(-1),
+        fStart(0), fLimit(0), fFirstRuleStatusIndex(0), fOtherRuleStatusIndex(0) {
+}
+
+RuleBasedBreakIterator::DictionaryCache::~DictionaryCache() {
+}
+
+void RuleBasedBreakIterator::DictionaryCache::reset() {
+    fPositionInCache = -1;
+    fStart = 0;
+    fLimit = 0;
+    fFirstRuleStatusIndex = 0;
+    fOtherRuleStatusIndex = 0;
+    fBreaks.removeAllElements();
+}
+
+UBool RuleBasedBreakIterator::DictionaryCache::following(int32_t fromPos, int32_t *result, int32_t *statusIndex) {
+    if (fromPos >= fLimit || fromPos < fStart) {
+        fPositionInCache = -1;
+        return FALSE;
+    }
+
+    // Sequential iteration, move from previous boundary to the following
+
+    int32_t r = 0;
+    if (fPositionInCache >= 0 && fPositionInCache < fBreaks.size() && fBreaks.elementAti(fPositionInCache) == fromPos) {
+        ++fPositionInCache;
+        if (fPositionInCache >= fBreaks.size()) {
+            fPositionInCache = -1;
+            return FALSE;
+        }
+        r = fBreaks.elementAti(fPositionInCache);
+        U_ASSERT(r > fromPos);
+        *result = r;
+        *statusIndex = fOtherRuleStatusIndex;
+        return TRUE;
+    }
+
+    // Random indexing. Linear search for the boundary following the given position.
+
+    for (fPositionInCache = 0; fPositionInCache < fBreaks.size(); ++fPositionInCache) {
+        r= fBreaks.elementAti(fPositionInCache);
+        if (r > fromPos) {
+            *result = r;
+            *statusIndex = fOtherRuleStatusIndex;
+            return TRUE;
+        }
+    }
+    UPRV_UNREACHABLE;
+}
+
+
+UBool RuleBasedBreakIterator::DictionaryCache::preceding(int32_t fromPos, int32_t *result, int32_t *statusIndex) {
+    if (fromPos <= fStart || fromPos > fLimit) {
+        fPositionInCache = -1;
+        return FALSE;
+    }
+
+    if (fromPos == fLimit) {
+        fPositionInCache = fBreaks.size() - 1;
+        if (fPositionInCache >= 0) {
+            U_ASSERT(fBreaks.elementAti(fPositionInCache) == fromPos);
+        }
+    }
+
+    int32_t r;
+    if (fPositionInCache > 0 && fPositionInCache < fBreaks.size() && fBreaks.elementAti(fPositionInCache) == fromPos) {
+        --fPositionInCache;
+        r = fBreaks.elementAti(fPositionInCache);
+        U_ASSERT(r < fromPos);
+        *result = r;
+        *statusIndex = ( r== fStart) ? fFirstRuleStatusIndex : fOtherRuleStatusIndex;
+        return TRUE;
+    }
+
+    if (fPositionInCache == 0) {
+        fPositionInCache = -1;
+        return FALSE;
+    }
+
+    for (fPositionInCache = fBreaks.size()-1; fPositionInCache >= 0; --fPositionInCache) {
+        r = fBreaks.elementAti(fPositionInCache);
+        if (r < fromPos) {
+            *result = r;
+            *statusIndex = ( r == fStart) ? fFirstRuleStatusIndex : fOtherRuleStatusIndex;
+            return TRUE;
+        }
+    }
+    UPRV_UNREACHABLE;
+}
+
+void RuleBasedBreakIterator::DictionaryCache::populateDictionary(int32_t startPos, int32_t endPos,
+                                       int32_t firstRuleStatus, int32_t otherRuleStatus) {
+    if ((endPos - startPos) <= 1) {
+        return;
+    }
+
+    reset();
+    fFirstRuleStatusIndex = firstRuleStatus;
+    fOtherRuleStatusIndex = otherRuleStatus;
+
+    int32_t rangeStart = startPos;
+    int32_t rangeEnd = endPos;
+
+    uint16_t    category;
+    int32_t     current;
+    UErrorCode  status = U_ZERO_ERROR;
+    int32_t     foundBreakCount = 0;
+    UText      *text = &fBI->fText;
+
+    // Loop through the text, looking for ranges of dictionary characters.
+    // For each span, find the appropriate break engine, and ask it to find
+    // any breaks within the span.
+
+    utext_setNativeIndex(text, rangeStart);
+    UChar32     c = utext_current32(text);
+    category = ucptrie_get(fBI->fData->fTrie, c);
+    uint32_t dictStart = fBI->fData->fForwardTable->fDictCategoriesStart;
+
+    while(U_SUCCESS(status)) {
+        while((current = (int32_t)UTEXT_GETNATIVEINDEX(text)) < rangeEnd
+                && (category < dictStart)) {
+            utext_next32(text);           // TODO: cleaner loop structure.
+            c = utext_current32(text);
+            category = ucptrie_get(fBI->fData->fTrie, c);
+        }
+        if (current >= rangeEnd) {
+            break;
+        }
+
+        // We now have a dictionary character. Get the appropriate language object
+        // to deal with it.
+        const LanguageBreakEngine *lbe = fBI->getLanguageBreakEngine(c);
+
+        // Ask the language object if there are any breaks. It will add them to the cache and
+        // leave the text pointer on the other side of its range, ready to search for the next one.
+        if (lbe != NULL) {
+            foundBreakCount += lbe->findBreaks(text, rangeStart, rangeEnd, fBreaks);
+        }
+
+        // Reload the loop variables for the next go-round
+        c = utext_current32(text);
+        category = ucptrie_get(fBI->fData->fTrie, c);
+    }
+
+    // If we found breaks, ensure that the first and last entries are
+    // the original starting and ending position. And initialize the
+    // cache iteration position to the first entry.
+
+    // printf("foundBreakCount = %d\n", foundBreakCount);
+    if (foundBreakCount > 0) {
+        U_ASSERT(foundBreakCount == fBreaks.size());
+        if (startPos < fBreaks.elementAti(0)) {
+            // The dictionary did not place a boundary at the start of the segment of text.
+            // Add one now. This should not commonly happen, but it would be easy for interactions
+            // of the rules for dictionary segments and the break engine implementations to
+            // inadvertently cause it. Cover it here, just in case.
+            fBreaks.insertElementAt(startPos, 0, status);
+        }
+        if (endPos > fBreaks.peeki()) {
+            fBreaks.push(endPos, status);
+        }
+        fPositionInCache = 0;
+        // Note: Dictionary matching may extend beyond the original limit.
+        fStart = fBreaks.elementAti(0);
+        fLimit = fBreaks.peeki();
+    } else {
+        // there were no language-based breaks, even though the segment contained
+        // dictionary characters. Subsequent attempts to fetch boundaries from the dictionary cache
+        // for this range will fail, and the calling code will fall back to the rule based boundaries.
+    }
+}
+
+
+/*
+ *   BreakCache implemetation
+ */
+
+RuleBasedBreakIterator::BreakCache::BreakCache(RuleBasedBreakIterator *bi, UErrorCode &status) :
+        fBI(bi), fSideBuffer(status) {
+    reset();
+}
+
+
+RuleBasedBreakIterator::BreakCache::~BreakCache() {
+}
+
+
+void RuleBasedBreakIterator::BreakCache::reset(int32_t pos, int32_t ruleStatus) {
+    fStartBufIdx = 0;
+    fEndBufIdx = 0;
+    fTextIdx = pos;
+    fBufIdx = 0;
+    fBoundaries[0] = pos;
+    fStatuses[0] = (uint16_t)ruleStatus;
+}
+
+
+int32_t  RuleBasedBreakIterator::BreakCache::current() {
+    fBI->fPosition = fTextIdx;
+    fBI->fRuleStatusIndex = fStatuses[fBufIdx];
+    fBI->fDone = FALSE;
+    return fTextIdx;
+}
+
+
+void RuleBasedBreakIterator::BreakCache::following(int32_t startPos, UErrorCode &status) {
+    if (U_FAILURE(status)) {
+        return;
+    }
+    if (startPos == fTextIdx || seek(startPos) || populateNear(startPos, status)) {
+        // startPos is in the cache. Do a next() from that position.
+        // TODO: an awkward set of interactions with bi->fDone
+        //       seek() does not clear it; it can't because of interactions with populateNear().
+        //       next() does not clear it in the fast-path case, where everything matters. Maybe it should.
+        //       So clear it here, for the case where seek() succeeded on an iterator that had previously run off the end.
+        fBI->fDone = false;
+        next();
+    }
+    return;
+}
+
+
+void RuleBasedBreakIterator::BreakCache::preceding(int32_t startPos, UErrorCode &status) {
+    if (U_FAILURE(status)) {
+        return;
+    }
+    if (startPos == fTextIdx || seek(startPos) || populateNear(startPos, status)) {
+        if (startPos == fTextIdx) {
+            previous(status);
+        } else {
+            // seek() leaves the BreakCache positioned at the preceding boundary
+            //        if the requested position is between two bounaries.
+            // current() pushes the BreakCache position out to the BreakIterator itself.
+            U_ASSERT(startPos > fTextIdx);
+            current();
+        }
+    }
+    return;
+}
+
+
+/*
+ * Out-of-line code for BreakCache::next().
+ * Cache does not already contain the boundary
+ */
+void RuleBasedBreakIterator::BreakCache::nextOL() {
+    fBI->fDone = !populateFollowing();
+    fBI->fPosition = fTextIdx;
+    fBI->fRuleStatusIndex = fStatuses[fBufIdx];
+    return;
+}
+
+
+void RuleBasedBreakIterator::BreakCache::previous(UErrorCode &status) {
+    if (U_FAILURE(status)) {
+        return;
+    }
+    int32_t initialBufIdx = fBufIdx;
+    if (fBufIdx == fStartBufIdx) {
+        // At start of cache. Prepend to it.
+        populatePreceding(status);
+    } else {
+        // Cache already holds the next boundary
+        fBufIdx = modChunkSize(fBufIdx - 1);
+        fTextIdx = fBoundaries[fBufIdx];
+    }
+    fBI->fDone = (fBufIdx == initialBufIdx);
+    fBI->fPosition = fTextIdx;
+    fBI->fRuleStatusIndex = fStatuses[fBufIdx];
+    return;
+}
+
+
+UBool RuleBasedBreakIterator::BreakCache::seek(int32_t pos) {
+    if (pos < fBoundaries[fStartBufIdx] || pos > fBoundaries[fEndBufIdx]) {
+        return FALSE;
+    }
+    if (pos == fBoundaries[fStartBufIdx]) {
+        // Common case: seek(0), from BreakIterator::first()
+        fBufIdx = fStartBufIdx;
+        fTextIdx = fBoundaries[fBufIdx];
+        return TRUE;
+    }
+    if (pos == fBoundaries[fEndBufIdx]) {
+        fBufIdx = fEndBufIdx;
+        fTextIdx = fBoundaries[fBufIdx];
+        return TRUE;
+    }
+
+    int32_t min = fStartBufIdx;
+    int32_t max = fEndBufIdx;
+    while (min != max) {
+        int32_t probe = (min + max + (min>max ? CACHE_SIZE : 0)) / 2;
+        probe = modChunkSize(probe);
+        if (fBoundaries[probe] > pos) {
+            max = probe;
+        } else {
+            min = modChunkSize(probe + 1);
+        }
+    }
+    U_ASSERT(fBoundaries[max] > pos);
+    fBufIdx = modChunkSize(max - 1);
+    fTextIdx = fBoundaries[fBufIdx];
+    U_ASSERT(fTextIdx <= pos);
+    return TRUE;
+}
+
+
+UBool RuleBasedBreakIterator::BreakCache::populateNear(int32_t position, UErrorCode &status) {
+    if (U_FAILURE(status)) {
+        return FALSE;
+    }
+    U_ASSERT(position < fBoundaries[fStartBufIdx] || position > fBoundaries[fEndBufIdx]);
+
+    // Find a boundary somewhere in the vicinity of the requested position.
+    // Depending on the safe rules and the text data, it could be either before, at, or after
+    // the requested position.
+
+
+    // If the requested position is not near already cached positions, clear the existing cache,
+    // find a near-by boundary and begin new cache contents there.
+
+    if ((position < fBoundaries[fStartBufIdx] - 15) || position > (fBoundaries[fEndBufIdx] + 15)) {
+        int32_t aBoundary = 0;
+        int32_t ruleStatusIndex = 0;
+        if (position > 20) {
+            int32_t backupPos = fBI->handleSafePrevious(position);
+
+            if (backupPos > 0) {
+                // Advance to the boundary following the backup position.
+                // There is a complication: the safe reverse rules identify pairs of code points
+                // that are safe. If advancing from the safe point moves forwards by less than
+                // two code points, we need to advance one more time to ensure that the boundary
+                // is good, including a correct rules status value.
+                //
+                fBI->fPosition = backupPos;
+                aBoundary = fBI->handleNext();
+                if (aBoundary <= backupPos + 4) {
+                    // +4 is a quick test for possibly having advanced only one codepoint.
+                    // Four being the length of the longest potential code point, a supplementary in UTF-8
+                    utext_setNativeIndex(&fBI->fText, aBoundary);
+                    if (backupPos == utext_getPreviousNativeIndex(&fBI->fText)) {
+                        // The initial handleNext() only advanced by a single code point. Go again.
+                        aBoundary = fBI->handleNext();   // Safe rules identify safe pairs.
+                    }
+                }
+                ruleStatusIndex = fBI->fRuleStatusIndex;
+            }
+        }
+        reset(aBoundary, ruleStatusIndex);        // Reset cache to hold aBoundary as a single starting point.
+    }
+
+    // Fill in boundaries between existing cache content and the new requested position.
+
+    if (fBoundaries[fEndBufIdx] < position) {
+        // The last position in the cache precedes the requested position.
+        // Add following position(s) to the cache.
+        while (fBoundaries[fEndBufIdx] < position) {
+            if (!populateFollowing()) {
+                UPRV_UNREACHABLE;
+            }
+        }
+        fBufIdx = fEndBufIdx;                      // Set iterator position to the end of the buffer.
+        fTextIdx = fBoundaries[fBufIdx];           // Required because populateFollowing may add extra boundaries.
+        while (fTextIdx > position) {              // Move backwards to a position at or preceding the requested pos.
+            previous(status);
+        }
+        return true;
+    }
+
+    if (fBoundaries[fStartBufIdx] > position) {
+        // The first position in the cache is beyond the requested position.
+        // back up more until we get a boundary <= the requested position.
+        while (fBoundaries[fStartBufIdx] > position) {
+            populatePreceding(status);
+        }
+        fBufIdx = fStartBufIdx;                    // Set iterator position to the start of the buffer.
+        fTextIdx = fBoundaries[fBufIdx];           // Required because populatePreceding may add extra boundaries.
+        while (fTextIdx < position) {              // Move forwards to a position at or following the requested pos.
+            next();
+        }
+        if (fTextIdx > position) {
+            // If position is not itself a boundary, the next() loop above will overshoot.
+            // Back up one, leaving cache position at the boundary preceding the requested position.
+            previous(status);
+        }
+        return true;
+    }
+
+    U_ASSERT(fTextIdx == position);
+    return true;
+}
+
+
+
+UBool RuleBasedBreakIterator::BreakCache::populateFollowing() {
+    int32_t fromPosition = fBoundaries[fEndBufIdx];
+    int32_t fromRuleStatusIdx = fStatuses[fEndBufIdx];
+    int32_t pos = 0;
+    int32_t ruleStatusIdx = 0;
+
+    if (fBI->fDictionaryCache->following(fromPosition, &pos, &ruleStatusIdx)) {
+        addFollowing(pos, ruleStatusIdx, UpdateCachePosition);
+        return TRUE;
+    }
+
+    fBI->fPosition = fromPosition;
+    pos = fBI->handleNext();
+    if (pos == UBRK_DONE) {
+        return FALSE;
+    }
+
+    ruleStatusIdx = fBI->fRuleStatusIndex;
+    if (fBI->fDictionaryCharCount > 0) {
+        // The text segment obtained from the rules includes dictionary characters.
+        // Subdivide it, with subdivided results going into the dictionary cache.
+        fBI->fDictionaryCache->populateDictionary(fromPosition, pos, fromRuleStatusIdx, ruleStatusIdx);
+        if (fBI->fDictionaryCache->following(fromPosition, &pos, &ruleStatusIdx)) {
+            addFollowing(pos, ruleStatusIdx, UpdateCachePosition);
+            return TRUE;
+            // TODO: may want to move a sizable chunk of dictionary cache to break cache at this point.
+            //       But be careful with interactions with populateNear().
+        }
+    }
+
+    // Rule based segment did not include dictionary characters.
+    // Or, it did contain dictionary chars, but the dictionary segmenter didn't handle them,
+    //    meaning that we didn't take the return, above.
+    // Add its end point to the cache.
+    addFollowing(pos, ruleStatusIdx, UpdateCachePosition);
+
+    // Add several non-dictionary boundaries at this point, to optimize straight forward iteration.
+    //    (subsequent calls to BreakIterator::next() will take the fast path, getting cached results.
+    //
+    for (int count=0; count<6; ++count) {
+        pos = fBI->handleNext();
+        if (pos == UBRK_DONE || fBI->fDictionaryCharCount > 0) {
+            break;
+        }
+        addFollowing(pos, fBI->fRuleStatusIndex, RetainCachePosition);
+    }
+
+    return TRUE;
+}
+
+
+UBool RuleBasedBreakIterator::BreakCache::populatePreceding(UErrorCode &status) {
+    if (U_FAILURE(status)) {
+        return FALSE;
+    }
+
+    int32_t fromPosition = fBoundaries[fStartBufIdx];
+    if (fromPosition == 0) {
+        return FALSE;
+    }
+
+    int32_t position = 0;
+    int32_t positionStatusIdx = 0;
+
+    if (fBI->fDictionaryCache->preceding(fromPosition, &position, &positionStatusIdx)) {
+        addPreceding(position, positionStatusIdx, UpdateCachePosition);
+        return TRUE;
+    }
+
+    int32_t backupPosition = fromPosition;
+
+    // Find a boundary somewhere preceding the first already-cached boundary
+    do {
+        backupPosition = backupPosition - 30;
+        if (backupPosition <= 0) {
+            backupPosition = 0;
+        } else {
+            backupPosition = fBI->handleSafePrevious(backupPosition);
+        }
+        if (backupPosition == UBRK_DONE || backupPosition == 0) {
+            position = 0;
+            positionStatusIdx = 0;
+        } else {
+            // Advance to the boundary following the backup position.
+            // There is a complication: the safe reverse rules identify pairs of code points
+            // that are safe. If advancing from the safe point moves forwards by less than
+            // two code points, we need to advance one more time to ensure that the boundary
+            // is good, including a correct rules status value.
+            //
+            fBI->fPosition = backupPosition;
+            position = fBI->handleNext();
+            if (position <= backupPosition + 4) {
+                // +4 is a quick test for possibly having advanced only one codepoint.
+                // Four being the length of the longest potential code point, a supplementary in UTF-8
+                utext_setNativeIndex(&fBI->fText, position);
+                if (backupPosition == utext_getPreviousNativeIndex(&fBI->fText)) {
+                    // The initial handleNext() only advanced by a single code point. Go again.
+                    position = fBI->handleNext();   // Safe rules identify safe pairs.
+                }
+            }
+            positionStatusIdx = fBI->fRuleStatusIndex;
+        }
+    } while (position >= fromPosition);
+
+    // Find boundaries between the one we just located and the first already-cached boundary
+    // Put them in a side buffer, because we don't yet know where they will fall in the circular cache buffer..
+
+    fSideBuffer.removeAllElements();
+    fSideBuffer.addElement(position, status);
+    fSideBuffer.addElement(positionStatusIdx, status);
+
+    do {
+        int32_t prevPosition = fBI->fPosition = position;
+        int32_t prevStatusIdx = positionStatusIdx;
+        position = fBI->handleNext();
+        positionStatusIdx = fBI->fRuleStatusIndex;
+        if (position == UBRK_DONE) {
+            break;
+        }
+
+        UBool segmentHandledByDictionary = FALSE;
+        if (fBI->fDictionaryCharCount != 0) {
+            // Segment from the rules includes dictionary characters.
+            // Subdivide it, with subdivided results going into the dictionary cache.
+            int32_t dictSegEndPosition = position;
+            fBI->fDictionaryCache->populateDictionary(prevPosition, dictSegEndPosition, prevStatusIdx, positionStatusIdx);
+            while (fBI->fDictionaryCache->following(prevPosition, &position, &positionStatusIdx)) {
+                segmentHandledByDictionary = true;
+                U_ASSERT(position > prevPosition);
+                if (position >= fromPosition) {
+                    break;
+                }
+                U_ASSERT(position <= dictSegEndPosition);
+                fSideBuffer.addElement(position, status);
+                fSideBuffer.addElement(positionStatusIdx, status);
+                prevPosition = position;
+            }
+            U_ASSERT(position==dictSegEndPosition || position>=fromPosition);
+        }
+
+        if (!segmentHandledByDictionary && position < fromPosition) {
+            fSideBuffer.addElement(position, status);
+            fSideBuffer.addElement(positionStatusIdx, status);
+        }
+    } while (position < fromPosition);
+
+    // Move boundaries from the side buffer to the main circular buffer.
+    UBool success = FALSE;
+    if (!fSideBuffer.isEmpty()) {
+        positionStatusIdx = fSideBuffer.popi();
+        position = fSideBuffer.popi();
+        addPreceding(position, positionStatusIdx, UpdateCachePosition);
+        success = TRUE;
+    }
+
+    while (!fSideBuffer.isEmpty()) {
+        positionStatusIdx = fSideBuffer.popi();
+        position = fSideBuffer.popi();
+        if (!addPreceding(position, positionStatusIdx, RetainCachePosition)) {
+            // No space in circular buffer to hold a new preceding result while
+            // also retaining the current cache (iteration) position.
+            // Bailing out is safe; the cache will refill again if needed.
+            break;
+        }
+    }
+
+    return success;
+}
+
+
+void RuleBasedBreakIterator::BreakCache::addFollowing(int32_t position, int32_t ruleStatusIdx, UpdatePositionValues update) {
+    U_ASSERT(position > fBoundaries[fEndBufIdx]);
+    U_ASSERT(ruleStatusIdx <= UINT16_MAX);
+    int32_t nextIdx = modChunkSize(fEndBufIdx + 1);
+    if (nextIdx == fStartBufIdx) {
+        fStartBufIdx = modChunkSize(fStartBufIdx + 6);    // TODO: experiment. Probably revert to 1.
+    }
+    fBoundaries[nextIdx] = position;
+    fStatuses[nextIdx] = static_cast<uint16_t>(ruleStatusIdx);
+    fEndBufIdx = nextIdx;
+    if (update == UpdateCachePosition) {
+        // Set current position to the newly added boundary.
+        fBufIdx = nextIdx;
+        fTextIdx = position;
+    } else {
+        // Retaining the original cache position.
+        // Check if the added boundary wraps around the buffer, and would over-write the original position.
+        // It's the responsibility of callers of this function to not add too many.
+        U_ASSERT(nextIdx != fBufIdx);
+    }
+}
+
+bool RuleBasedBreakIterator::BreakCache::addPreceding(int32_t position, int32_t ruleStatusIdx, UpdatePositionValues update) {
+    U_ASSERT(position < fBoundaries[fStartBufIdx]);
+    U_ASSERT(ruleStatusIdx <= UINT16_MAX);
+    int32_t nextIdx = modChunkSize(fStartBufIdx - 1);
+    if (nextIdx == fEndBufIdx) {
+        if (fBufIdx == fEndBufIdx && update == RetainCachePosition) {
+            // Failure. The insertion of the new boundary would claim the buffer position that is the
+            // current iteration position. And we also want to retain the current iteration position.
+            // (The buffer is already completely full of entries that precede the iteration position.)
+            return false;
+        }
+        fEndBufIdx = modChunkSize(fEndBufIdx - 1);
+    }
+    fBoundaries[nextIdx] = position;
+    fStatuses[nextIdx] = static_cast<uint16_t>(ruleStatusIdx);
+    fStartBufIdx = nextIdx;
+    if (update == UpdateCachePosition) {
+        fBufIdx = nextIdx;
+        fTextIdx = position;
+    }
+    return true;
+}
+
+
+void RuleBasedBreakIterator::BreakCache::dumpCache() {
+#ifdef RBBI_DEBUG
+    RBBIDebugPrintf("fTextIdx:%d   fBufIdx:%d\n", fTextIdx, fBufIdx);
+    for (int32_t i=fStartBufIdx; ; i=modChunkSize(i+1)) {
+        RBBIDebugPrintf("%d  %d\n", i, fBoundaries[i]);
+        if (i == fEndBufIdx) {
+            break;
+        }
+    }
+#endif
+}
+
+U_NAMESPACE_END
+
+#endif // #if !UCONFIG_NO_BREAK_ITERATION
diff --git a/src/third_party/icu/source/common/rbbi_cache.h b/src/third_party/icu/source/common/rbbi_cache.h
new file mode 100644
index 0000000..597312e
--- /dev/null
+++ b/src/third_party/icu/source/common/rbbi_cache.h
@@ -0,0 +1,203 @@
+// Copyright (C) 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+// file: rbbi_cache.h
+//
+#ifndef RBBI_CACHE_H
+#define RBBI_CACHE_H
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_BREAK_ITERATION
+
+#include "unicode/rbbi.h"
+#include "unicode/uobject.h"
+
+#include "uvectr32.h"
+
+U_NAMESPACE_BEGIN
+
+/* DictionaryCache  stores the boundaries obtained from a run of dictionary characters.
+ *                 Dictionary boundaries are moved first to this cache, then from here
+ *                 to the main BreakCache, where they may inter-leave with non-dictionary
+ *                 boundaries. The public BreakIterator API always fetches directly
+ *                 from the main BreakCache, not from here.
+ *
+ *                 In common situations, the number of boundaries in a single dictionary run
+ *                 should be quite small, it will be terminated by punctuation, spaces,
+ *                 or any other non-dictionary characters. The main BreakCache may end
+ *                 up with boundaries from multiple dictionary based runs.
+ *
+ *                 The boundaries are stored in a simple ArrayList (vector), with the
+ *                 assumption that they will be accessed sequentially.
+ */                 
+class RuleBasedBreakIterator::DictionaryCache: public UMemory {
+  public:
+     DictionaryCache(RuleBasedBreakIterator *bi, UErrorCode &status);
+     ~DictionaryCache();
+
+     void reset();
+
+     UBool following(int32_t fromPos, int32_t *pos, int32_t *statusIndex);
+     UBool preceding(int32_t fromPos, int32_t *pos, int32_t *statusIndex);
+
+    /**
+     * Populate the cache with the dictionary based boundaries within a region of text.
+     * @param startPos  The start position of a range of text
+     * @param endPos    The end position of a range of text
+     * @param firstRuleStatus The rule status index that applies to the break at startPos
+     * @param otherRuleStatus The rule status index that applies to boundaries other than startPos
+     * @internal
+     */
+    void populateDictionary(int32_t startPos, int32_t endPos,
+                         int32_t firstRuleStatus, int32_t otherRuleStatus);
+
+
+
+    RuleBasedBreakIterator *fBI;
+    
+    UVector32           fBreaks;                // A vector containing the boundaries.
+    int32_t             fPositionInCache;       // Index in fBreaks of last boundary returned by following()
+                                                //    or preceding(). Optimizes sequential access.
+    int32_t             fStart;                 // Text position of first boundary in cache.
+    int32_t             fLimit;                 // Last boundary in cache. Which is the limit of the
+                                                //    text segment being handled by the dictionary.
+    int32_t             fFirstRuleStatusIndex;  // Rule status info for first boundary.
+    int32_t             fOtherRuleStatusIndex;  // Rule status info for 2nd through last boundaries.
+};
+
+
+/*
+ * class BreakCache
+ *
+ * Cache of break boundary positions and rule status values.
+ * Break iterator API functions, next(), previous(), etc., will use cached results
+ * when possible, and otherwise cache new results as they are obtained.
+ *
+ * Uniformly caches both dictionary and rule based (non-dictionary) boundaries.
+ *
+ * The cache is implemented as a single circular buffer.
+ */
+
+/*
+ * size of the circular cache buffer.
+ */
+
+class RuleBasedBreakIterator::BreakCache: public UMemory {
+  public:
+                BreakCache(RuleBasedBreakIterator *bi, UErrorCode &status);
+    virtual     ~BreakCache();
+    void        reset(int32_t pos = 0, int32_t ruleStatus = 0);
+    void        next() {    if (fBufIdx == fEndBufIdx) {
+                                nextOL();
+                            } else {
+                                fBufIdx = modChunkSize(fBufIdx + 1);
+                                fTextIdx = fBI->fPosition = fBoundaries[fBufIdx];
+                                fBI->fRuleStatusIndex = fStatuses[fBufIdx];
+                            }
+                }
+
+
+    void        nextOL();
+    void        previous(UErrorCode &status);
+
+    // Move the iteration state to the position following the startPosition.
+    // Input position must be pinned to the input length.
+    void        following(int32_t startPosition, UErrorCode &status);
+
+    void        preceding(int32_t startPosition, UErrorCode &status);
+
+    /*
+     * Update the state of the public BreakIterator (fBI) to reflect the
+     * current state of the break iterator cache (this).
+     */
+    int32_t     current();
+
+    /**
+     * Add boundaries to the cache near the specified position.
+     * The given position need not be a boundary itself.
+     * The input position must be within the range of the text, and
+     * on a code point boundary.
+     * If the requested position is a break boundary, leave the iteration
+     * position on it.
+     * If the requested position is not a boundary, leave the iteration
+     * position on the preceding boundary and include both the
+     * preceding and following boundaries in the cache.
+     * Additional boundaries, either preceding or following, may be added
+     * to the cache as a side effect.
+     *
+     * Return false if the operation failed.
+     */
+    UBool populateNear(int32_t position, UErrorCode &status);
+
+    /**
+     *  Add boundary(s) to the cache following the current last boundary.
+     *  Return false if at the end of the text, and no more boundaries can be added.
+     *  Leave iteration position at the first newly added boundary, or unchanged if no boundary was added.
+     */
+    UBool populateFollowing();
+
+    /**
+     *  Add one or more boundaries to the cache preceding the first currently cached boundary.
+     *  Leave the iteration position on the first added boundary.
+     *  Return false if no boundaries could be added (if at the start of the text.)
+     */
+    UBool populatePreceding(UErrorCode &status);
+
+    enum UpdatePositionValues {
+        RetainCachePosition = 0,
+        UpdateCachePosition = 1
+    };
+
+    /*
+     * Add the boundary following the current position.
+     * The current position can be left as it was, or changed to the newly added boundary,
+     * as specified by the update parameter.
+     */
+    void addFollowing(int32_t position, int32_t ruleStatusIdx, UpdatePositionValues update);
+
+
+    /*
+     * Add the boundary preceding the current position.
+     * The current position can be left as it was, or changed to the newly added boundary,
+     * as specified by the update parameter.
+     */
+    bool addPreceding(int32_t position, int32_t ruleStatusIdx, UpdatePositionValues update);
+
+    /**
+     *  Set the cache position to the specified position, or, if the position
+     *  falls between to cached boundaries, to the preceding boundary.
+     *  Fails if the requested position is outside of the range of boundaries currently held by the cache.
+     *  The startPosition must be on a code point boundary.
+     *
+     *  Return true if successful, false if the specified position is after
+     *  the last cached boundary or before the first.
+     */
+    UBool                   seek(int32_t startPosition);
+
+    void dumpCache();
+
+  private:
+    static inline int32_t   modChunkSize(int index) { return index & (CACHE_SIZE - 1); }
+
+    static constexpr int32_t CACHE_SIZE = 128;
+    static_assert((CACHE_SIZE & (CACHE_SIZE-1)) == 0, "CACHE_SIZE must be power of two.");
+
+    RuleBasedBreakIterator *fBI;
+    int32_t                 fStartBufIdx;
+    int32_t                 fEndBufIdx;    // inclusive
+
+    int32_t                 fTextIdx;
+    int32_t                 fBufIdx;
+
+    int32_t                 fBoundaries[CACHE_SIZE];
+    uint16_t                fStatuses[CACHE_SIZE];
+
+    UVector32               fSideBuffer;
+};
+
+U_NAMESPACE_END
+
+#endif // #if !UCONFIG_NO_BREAK_ITERATION
+
+#endif // RBBI_CACHE_H
diff --git a/src/third_party/icu/source/common/rbbicst.pl b/src/third_party/icu/source/common/rbbicst.pl
index 98b06cb..9aee3c1 100755
--- a/src/third_party/icu/source/common/rbbicst.pl
+++ b/src/third_party/icu/source/common/rbbicst.pl
@@ -1,6 +1,10 @@
 #**************************************************************************
-#   Copyright (C) 2002-2005 International Business Machines Corporation   *
-#   and others. All rights reserved.                                      *
+#   Copyright (C) 2016 and later: Unicode, Inc. and others.
+#   License & terms of use: http://www.unicode.org/copyright.html
+#**************************************************************************
+#**************************************************************************
+#   Copyright (C) 2002-2016 International Business Machines Corporation
+#   and others. All rights reserved.
 #**************************************************************************
 #
 #  rbbicst   Compile the RBBI rule paser state table data into initialized C data.
@@ -348,6 +352,8 @@
     print "#ifndef RBBIRPT_H\n";
     print "#define RBBIRPT_H\n";
     print "\n";
+    print "#include \"unicode/utypes.h\"\n";
+    print "\n";
     print "U_NAMESPACE_BEGIN\n";
 
     #
diff --git a/src/third_party/icu/source/common/rbbidata.cpp b/src/third_party/icu/source/common/rbbidata.cpp
index 8e4ce1a..f395697 100644
--- a/src/third_party/icu/source/common/rbbidata.cpp
+++ b/src/third_party/icu/source/common/rbbidata.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ***************************************************************************
 *   Copyright (C) 1999-2014 International Business Machines Corporation   *
@@ -9,12 +11,14 @@
 
 #if !UCONFIG_NO_BREAK_ITERATION
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
+#include "unicode/ucptrie.h"
 #include "unicode/utypes.h"
 #include "rbbidata.h"
 #include "rbbirb.h"
-#include "utrie.h"
 #include "udatamem.h"
 #include "cmemory.h"
 #include "cstring.h"
@@ -23,23 +27,6 @@
 #include "uassert.h"
 
 
-//-----------------------------------------------------------------------------------
-//
-//   Trie access folding function.  Copied as-is from properties code in uchar.c
-//
-//-----------------------------------------------------------------------------------
-U_CDECL_BEGIN
-static int32_t U_CALLCONV
-getFoldingOffset(uint32_t data) {
-    /* if bit 15 is set, then the folding offset is in bits 14..0 of the 16-bit trie result */
-    if(data&0x8000) {
-        return (int32_t)(data&0x7fff);
-    } else {
-        return 0;
-    }
-}
-U_CDECL_END
-
 U_NAMESPACE_BEGIN
 
 //-----------------------------------------------------------------------------
@@ -71,9 +58,8 @@
             dh->info.dataFormat[0] == 0x42 &&  // dataFormat="Brk "
             dh->info.dataFormat[1] == 0x72 &&
             dh->info.dataFormat[2] == 0x6b &&
-            dh->info.dataFormat[3] == 0x20)
-            // Note: info.fFormatVersion is duplicated in the RBBIDataHeader, and is
-            //       validated when checking that.
+            dh->info.dataFormat[3] == 0x20 &&
+            isDataVersionAcceptable(dh->info.formatVersion))
         ) {
         status = U_INVALID_FORMAT_ERROR;
         return;
@@ -84,6 +70,11 @@
     fUDataMem = udm;
 }
 
+UBool RBBIDataWrapper::isDataVersionAcceptable(const UVersionInfo version) {
+    return RBBI_DATA_FORMAT_VERSION[0] == version[0];
+}
+
+
 //-----------------------------------------------------------------------------
 //
 //    init().   Does most of the work of construction, shared between the
@@ -94,12 +85,11 @@
     fHeader = NULL;
     fForwardTable = NULL;
     fReverseTable = NULL;
-    fSafeFwdTable = NULL;
-    fSafeRevTable = NULL;
-    fRuleSource = NULL;
+    fRuleSource   = NULL;
     fRuleStatusTable = NULL;
-    fUDataMem = NULL;
-    fRefCount = 0;
+    fTrie         = NULL;
+    fUDataMem     = NULL;
+    fRefCount     = 0;
     fDontFreeData = TRUE;
 }
 
@@ -108,8 +98,7 @@
         return;
     }
     fHeader = data;
-    if (fHeader->fMagic != 0xb1a0 || fHeader->fFormatVersion[0] != 3) 
-    {
+    if (fHeader->fMagic != 0xb1a0 || !isDataVersionAcceptable(fHeader->fFormatVersion)) {
         status = U_INVALID_FORMAT_ERROR;
         return;
     }
@@ -124,26 +113,25 @@
     if (data->fRTableLen != 0) {
         fReverseTable = (RBBIStateTable *)((char *)data + fHeader->fRTable);
     }
-    if (data->fSFTableLen != 0) {
-        fSafeFwdTable = (RBBIStateTable *)((char *)data + fHeader->fSFTable);
-    }
-    if (data->fSRTableLen != 0) {
-        fSafeRevTable = (RBBIStateTable *)((char *)data + fHeader->fSRTable);
-    }
 
-
-    utrie_unserialize(&fTrie,
-                       (uint8_t *)data + fHeader->fTrie,
-                       fHeader->fTrieLen,
-                       &status);
+    fTrie = ucptrie_openFromBinary(UCPTRIE_TYPE_FAST,
+                                   UCPTRIE_VALUE_BITS_ANY,
+                                   (uint8_t *)data + fHeader->fTrie,
+                                   fHeader->fTrieLen,
+                                   nullptr,           // *actual length
+                                   &status);
     if (U_FAILURE(status)) {
         return;
     }
-    fTrie.getFoldingOffset=getFoldingOffset;
 
+    UCPTrieValueWidth width = ucptrie_getValueWidth(fTrie);
+    if (!(width == UCPTRIE_VALUE_BITS_8 || width == UCPTRIE_VALUE_BITS_16)) {
+        status = U_INVALID_FORMAT_ERROR;
+        return;
+    }
 
-    fRuleSource   = (UChar *)((char *)data + fHeader->fRuleSource);
-    fRuleString.setTo(TRUE, fRuleSource, -1);
+    fRuleSource   = ((char *)data + fHeader->fRuleSource);
+    fRuleString = UnicodeString::fromUTF8(StringPiece(fRuleSource, fHeader->fRuleSourceLen));
     U_ASSERT(data->fRuleSourceLen > 0);
 
     fRuleStatusTable = (int32_t *)((char *)data + fHeader->fStatusTable);
@@ -165,6 +153,8 @@
 //-----------------------------------------------------------------------------
 RBBIDataWrapper::~RBBIDataWrapper() {
     U_ASSERT(fRefCount == 0);
+    ucptrie_close(fTrie);
+    fTrie = nullptr;
     if (fUDataMem) {
         udata_close(fUDataMem);
     } else if (!fDontFreeData) {
@@ -244,9 +234,16 @@
     uint32_t   c;
     uint32_t   s;
 
-    RBBIDebugPrintf("   %s\n", heading);
+    RBBIDebugPrintf("%s\n", heading);
 
-    RBBIDebugPrintf("State |  Acc  LA TagIx");
+    RBBIDebugPrintf("   fDictCategoriesStart: %d\n", table->fDictCategoriesStart);
+    RBBIDebugPrintf("   fLookAheadResultsSize: %d\n", table->fLookAheadResultsSize);
+    RBBIDebugPrintf("   Flags: %4x RBBI_LOOKAHEAD_HARD_BREAK=%s RBBI_BOF_REQUIRED=%s  RBBI_8BITS_ROWS=%s\n",
+                    table->fFlags,
+                    table->fFlags & RBBI_LOOKAHEAD_HARD_BREAK ? "T" : "F",
+                    table->fFlags & RBBI_BOF_REQUIRED ? "T" : "F",
+                    table->fFlags & RBBI_8BITS_ROWS ? "T" : "F");
+    RBBIDebugPrintf("\nState |  Acc  LA TagIx");
     for (c=0; c<fHeader->fCatCount; c++) {RBBIDebugPrintf("%3d ", c);}
     RBBIDebugPrintf("\n------|---------------"); for (c=0;c<fHeader->fCatCount; c++) {
         RBBIDebugPrintf("----");
@@ -257,12 +254,20 @@
         RBBIDebugPrintf("         N U L L   T A B L E\n\n");
         return;
     }
+    UBool use8Bits = table->fFlags & RBBI_8BITS_ROWS;
     for (s=0; s<table->fNumStates; s++) {
         RBBIStateTableRow *row = (RBBIStateTableRow *)
                                   (table->fTableData + (table->fRowLen * s));
-        RBBIDebugPrintf("%4d  |  %3d %3d %3d ", s, row->fAccepting, row->fLookAhead, row->fTagIdx);
-        for (c=0; c<fHeader->fCatCount; c++)  {
-            RBBIDebugPrintf("%3d ", row->fNextState[c]);
+        if (use8Bits) {
+            RBBIDebugPrintf("%4d  |  %3d %3d %3d ", s, row->r8.fAccepting, row->r8.fLookAhead, row->r8.fTagsIdx);
+            for (c=0; c<fHeader->fCatCount; c++)  {
+                RBBIDebugPrintf("%3d ", row->r8.fNextState[c]);
+            }
+        } else {
+            RBBIDebugPrintf("%4d  |  %3d %3d %3d ", s, row->r16.fAccepting, row->r16.fLookAhead, row->r16.fTagsIdx);
+            for (c=0; c<fHeader->fCatCount; c++)  {
+                RBBIDebugPrintf("%3d ", row->r16.fNextState[c]);
+            }
         }
         RBBIDebugPrintf("\n");
     }
@@ -271,8 +276,8 @@
 #endif
 
 
-#ifdef RBBI_DEBUG
 void  RBBIDataWrapper::printData() {
+#ifdef RBBI_DEBUG
     RBBIDebugPrintf("RBBI Data at %p\n", (void *)fHeader);
     RBBIDebugPrintf("   Version = {%d %d %d %d}\n", fHeader->fFormatVersion[0], fHeader->fFormatVersion[1],
                                                     fHeader->fFormatVersion[2], fHeader->fFormatVersion[3]);
@@ -281,16 +286,14 @@
 
     printTable("Forward State Transition Table", fForwardTable);
     printTable("Reverse State Transition Table", fReverseTable);
-    printTable("Safe Forward State Transition Table", fSafeFwdTable);
-    printTable("Safe Reverse State Transition Table", fSafeRevTable);
 
     RBBIDebugPrintf("\nOrignal Rules source:\n");
     for (int32_t c=0; fRuleSource[c] != 0; c++) {
         RBBIDebugPrintf("%c", fRuleSource[c]);
     }
     RBBIDebugPrintf("\n\n");
-}
 #endif
+}
 
 
 U_NAMESPACE_END
@@ -323,7 +326,7 @@
            pInfo->dataFormat[1]==0x72 &&
            pInfo->dataFormat[2]==0x6b &&
            pInfo->dataFormat[3]==0x20 &&
-           pInfo->formatVersion[0]==3  )) {
+           RBBIDataWrapper::isDataVersionAcceptable(pInfo->formatVersion) )) {
         udata_printError(ds, "ubrk_swap(): data format %02x.%02x.%02x.%02x (format version %02x) is not recognized\n",
                          pInfo->dataFormat[0], pInfo->dataFormat[1],
                          pInfo->dataFormat[2], pInfo->dataFormat[3],
@@ -344,17 +347,11 @@
     //
     // Get the RRBI Data Header, and check that it appears to be OK.
     //
-    //    Note:  ICU 3.2 and earlier, RBBIDataHeader::fDataFormat was actually 
-    //           an int32_t with a value of 1.  Starting with ICU 3.4,
-    //           RBBI's fDataFormat matches the dataFormat field from the
-    //           UDataInfo header, four int8_t bytes.  The value is {3,1,0,0}
-    //
     const uint8_t  *inBytes =(const uint8_t *)inData+headerSize;
     RBBIDataHeader *rbbiDH = (RBBIDataHeader *)inBytes;
     if (ds->readUInt32(rbbiDH->fMagic) != 0xb1a0 || 
-        rbbiDH->fFormatVersion[0] != 3 ||
-        ds->readUInt32(rbbiDH->fLength)  <  sizeof(RBBIDataHeader)) 
-    {
+            !RBBIDataWrapper::isDataVersionAcceptable(rbbiDH->fFormatVersion) ||
+            ds->readUInt32(rbbiDH->fLength)  <  sizeof(RBBIDataHeader)) {
         udata_printError(ds, "ubrk_swap(): RBBI Data header is invalid.\n");
         *status=U_UNSUPPORTED_ERROR;
         return 0;
@@ -406,57 +403,64 @@
     //
     int32_t         topSize = offsetof(RBBIStateTable, fTableData);
 
-    // Forward state table.  
+    // Forward state table.
     tableStartOffset = ds->readUInt32(rbbiDH->fFTable);
     tableLength      = ds->readUInt32(rbbiDH->fFTableLen);
 
     if (tableLength > 0) {
-        ds->swapArray32(ds, inBytes+tableStartOffset, topSize, 
+        RBBIStateTable *rbbiST = (RBBIStateTable *)(inBytes+tableStartOffset);
+        UBool use8Bits = ds->readUInt32(rbbiST->fFlags) & RBBI_8BITS_ROWS;
+
+        ds->swapArray32(ds, inBytes+tableStartOffset, topSize,
                             outBytes+tableStartOffset, status);
-        ds->swapArray16(ds, inBytes+tableStartOffset+topSize, tableLength-topSize,
-                            outBytes+tableStartOffset+topSize, status);
+
+        // Swap the state table if the table is in 16 bits.
+        if (use8Bits) {
+            if (outBytes != inBytes) {
+                uprv_memmove(outBytes+tableStartOffset+topSize,
+                             inBytes+tableStartOffset+topSize,
+                             tableLength-topSize);
+            }
+        } else {
+            ds->swapArray16(ds, inBytes+tableStartOffset+topSize, tableLength-topSize,
+                                outBytes+tableStartOffset+topSize, status);
+        }
     }
-    
+
     // Reverse state table.  Same layout as forward table, above.
     tableStartOffset = ds->readUInt32(rbbiDH->fRTable);
     tableLength      = ds->readUInt32(rbbiDH->fRTableLen);
 
     if (tableLength > 0) {
-        ds->swapArray32(ds, inBytes+tableStartOffset, topSize, 
+        RBBIStateTable *rbbiST = (RBBIStateTable *)(inBytes+tableStartOffset);
+        UBool use8Bits = ds->readUInt32(rbbiST->fFlags) & RBBI_8BITS_ROWS;
+
+        ds->swapArray32(ds, inBytes+tableStartOffset, topSize,
                             outBytes+tableStartOffset, status);
-        ds->swapArray16(ds, inBytes+tableStartOffset+topSize, tableLength-topSize,
-                            outBytes+tableStartOffset+topSize, status);
-    }
 
-    // Safe Forward state table.  Same layout as forward table, above.
-    tableStartOffset = ds->readUInt32(rbbiDH->fSFTable);
-    tableLength      = ds->readUInt32(rbbiDH->fSFTableLen);
-
-    if (tableLength > 0) {
-        ds->swapArray32(ds, inBytes+tableStartOffset, topSize, 
-                            outBytes+tableStartOffset, status);
-        ds->swapArray16(ds, inBytes+tableStartOffset+topSize, tableLength-topSize,
-                            outBytes+tableStartOffset+topSize, status);
-    }
-
-    // Safe Reverse state table.  Same layout as forward table, above.
-    tableStartOffset = ds->readUInt32(rbbiDH->fSRTable);
-    tableLength      = ds->readUInt32(rbbiDH->fSRTableLen);
-
-    if (tableLength > 0) {
-        ds->swapArray32(ds, inBytes+tableStartOffset, topSize, 
-                            outBytes+tableStartOffset, status);
-        ds->swapArray16(ds, inBytes+tableStartOffset+topSize, tableLength-topSize,
-                            outBytes+tableStartOffset+topSize, status);
+        // Swap the state table if the table is in 16 bits.
+        if (use8Bits) {
+            if (outBytes != inBytes) {
+                uprv_memmove(outBytes+tableStartOffset+topSize,
+                             inBytes+tableStartOffset+topSize,
+                             tableLength-topSize);
+            }
+        } else {
+            ds->swapArray16(ds, inBytes+tableStartOffset+topSize, tableLength-topSize,
+                                outBytes+tableStartOffset+topSize, status);
+        }
     }
 
     // Trie table for character categories
-    utrie_swap(ds, inBytes+ds->readUInt32(rbbiDH->fTrie), ds->readUInt32(rbbiDH->fTrieLen),
-                            outBytes+ds->readUInt32(rbbiDH->fTrie), status);
+    ucptrie_swap(ds, inBytes+ds->readUInt32(rbbiDH->fTrie), ds->readUInt32(rbbiDH->fTrieLen),
+                     outBytes+ds->readUInt32(rbbiDH->fTrie), status);
 
-    // Source Rules Text.  It's UChar data
-    ds->swapArray16(ds, inBytes+ds->readUInt32(rbbiDH->fRuleSource), ds->readUInt32(rbbiDH->fRuleSourceLen),
-                        outBytes+ds->readUInt32(rbbiDH->fRuleSource), status);
+    // Source Rules Text.  It's UTF8 data
+    if (outBytes != inBytes) {
+        uprv_memmove(outBytes+ds->readUInt32(rbbiDH->fRuleSource),
+                     inBytes+ds->readUInt32(rbbiDH->fRuleSource),
+                     ds->readUInt32(rbbiDH->fRuleSourceLen));
+    }
 
     // Table of rule status values.  It's all int_32 values
     ds->swapArray32(ds, inBytes+ds->readUInt32(rbbiDH->fStatusTable), ds->readUInt32(rbbiDH->fStatusTableLen),
diff --git a/src/third_party/icu/source/common/rbbidata.h b/src/third_party/icu/source/common/rbbidata.h
index 65274c3..3749f16 100644
--- a/src/third_party/icu/source/common/rbbidata.h
+++ b/src/third_party/icu/source/common/rbbidata.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  rbbidata.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -47,24 +49,26 @@
 
 #ifdef __cplusplus
 
+#include "unicode/ucptrie.h"
 #include "unicode/uobject.h"
 #include "unicode/unistr.h"
+#include "unicode/uversion.h"
 #include "umutex.h"
-#include "utrie.h"
+
 
 U_NAMESPACE_BEGIN
 
+// The current RBBI data format version.
+static const uint8_t RBBI_DATA_FORMAT_VERSION[] = {6, 0, 0, 0};
+
 /*  
  *   The following structs map exactly onto the raw data from ICU common data file. 
  */
 struct RBBIDataHeader {
     uint32_t         fMagic;           /*  == 0xbla0                                               */
-    uint8_t          fFormatVersion[4]; /* Data Format.  Same as the value in struct UDataInfo      */
+    UVersionInfo     fFormatVersion;   /* Data Format.  Same as the value in struct UDataInfo      */
                                        /*   if there is one associated with this data.             */
                                        /*     (version originates in rbbi, is copied to UDataInfo) */
-                                       /*   For ICU 3.2 and earlier, this field was                */
-                                       /*       uint32_t  fVersion                                 */
-                                       /*   with a value of 1.                                     */
     uint32_t         fLength;          /*  Total length in bytes of this RBBI Data,                */
                                        /*      including all sections, not just the header.        */
     uint32_t         fCatCount;        /*  Number of character categories.                         */
@@ -78,10 +82,6 @@
     uint32_t         fFTableLen;
     uint32_t         fRTable;         /*  Offset to the reverse state transition table. */
     uint32_t         fRTableLen;
-    uint32_t         fSFTable;        /*  safe point forward transition table */
-    uint32_t         fSFTableLen;
-    uint32_t         fSRTable;        /*  safe point reverse transition table */
-    uint32_t         fSRTableLen;
     uint32_t         fTrie;           /*  Offset to Trie data for character categories */
     uint32_t         fTrieLen;
     uint32_t         fRuleSource;     /*  Offset to the source for for the break */
@@ -95,46 +95,61 @@
 
 
 
-struct  RBBIStateTableRow {
-    int16_t          fAccepting;    /*  Non-zero if this row is for an accepting state.   */
-                                    /*  Value 0: not an accepting state.                  */
-                                    /*       -1: Unconditional Accepting state.           */
-                                    /*    positive:  Look-ahead match has completed.      */
-                                    /*           Actual boundary position happened earlier */
-                                    /*           Value here == fLookAhead in earlier      */
-                                    /*              state, at actual boundary pos.        */
-    int16_t          fLookAhead;    /*  Non-zero if this row is for a state that          */
-                                    /*    corresponds to a '/' in the rule source.        */
-                                    /*    Value is the same as the fAccepting             */
-                                    /*      value for the rule (which will appear         */
-                                    /*      in a different state.                         */
-    int16_t          fTagIdx;       /*  Non-zero if this row covers a {tagged} position   */
-                                    /*     from a rule.  Value is the index in the        */
-                                    /*     StatusTable of the set of matching             */
-                                    /*     tags (rule status values)                      */
-    int16_t          fReserved;
-    uint16_t         fNextState[2]; /*  Next State, indexed by char category.             */
-                                    /*  This array does not have two elements             */
-                                    /*    Array Size is actually fData->fHeader->fCatCount         */
-                                    /*    CAUTION:  see RBBITableBuilder::getTableSize()  */
-                                    /*              before changing anything here.        */
+template <typename T>
+struct RBBIStateTableRowT {
+    T               fAccepting;    //  Non-zero if this row is for an accepting state.
+                                   //  Value 0: not an accepting state.
+                                   //        1: (ACCEPTING_UNCONDITIONAL) Unconditional Accepting state.
+                                   //       >1: Look-ahead match has completed.
+                                   //           Actual boundary position happened earlier.
+                                   //           Value here == fLookAhead in earlier
+                                   //           state, at actual boundary pos.
+    T               fLookAhead;    //  Non-zero if this row is for a state that
+                                   //    corresponds to a '/' in the rule source.
+                                   //    Value is the same as the fAccepting
+                                   //    value for the rule (which will appear
+                                   //    in a different state.
+    T               fTagsIdx;      //  Non-zero if this row covers a {tagged} position
+                                   //    from a rule.  Value is the index in the
+                                   //    StatusTable of the set of matching
+                                   //    tags (rule status values)
+    T               fNextState[1]; //  Next State, indexed by char category.
+                                   //    Variable-length array declared with length 1
+                                   //    to disable bounds checkers.
+                                   //    Array Size is actually fData->fHeader->fCatCount
+                                   //    CAUTION:  see RBBITableBuilder::getTableSize()
+                                   //              before changing anything here.
 };
 
+typedef RBBIStateTableRowT<uint8_t> RBBIStateTableRow8;
+typedef RBBIStateTableRowT<uint16_t> RBBIStateTableRow16;
+
+constexpr uint16_t ACCEPTING_UNCONDITIONAL = 1;   // Value constant for RBBIStateTableRow::fAccepting
+
+union RBBIStateTableRow {
+  RBBIStateTableRow16 r16;
+  RBBIStateTableRow8 r8;
+};
 
 struct RBBIStateTable {
-    uint32_t         fNumStates;    /*  Number of states.                                 */
-    uint32_t         fRowLen;       /*  Length of a state table row, in bytes.            */
-    uint32_t         fFlags;        /*  Option Flags for this state table                 */
-    uint32_t         fReserved;     /*  reserved                                          */
-    char             fTableData[4]; /*  First RBBIStateTableRow begins here.              */
-                                    /*    (making it char[] simplifies ugly address       */
-                                    /*     arithmetic for indexing variable length rows.) */
+    uint32_t         fNumStates;            // Number of states.
+    uint32_t         fRowLen;               // Length of a state table row, in bytes.
+    uint32_t         fDictCategoriesStart;  // Char category number of the first dictionary
+                                            //   char class, or the the largest category number + 1
+                                            //   if there are no dictionary categories.
+    uint32_t         fLookAheadResultsSize; // Size of run-time array required for holding
+                                            //   look-ahead results. Indexed by row.fLookAhead.
+    uint32_t         fFlags;                // Option Flags for this state table.
+    char             fTableData[1];         // First RBBIStateTableRow begins here.
+                                            //   Variable-length array declared with length 1
+                                            //   to disable bounds checkers.
+                                            //   (making it char[] simplifies ugly address
+                                            //   arithmetic for indexing variable length rows.)
 };
 
-typedef enum {
-    RBBI_LOOKAHEAD_HARD_BREAK = 1,
-    RBBI_BOF_REQUIRED = 2
-} RBBIStateTableFlags;
+constexpr uint32_t RBBI_LOOKAHEAD_HARD_BREAK = 1;
+constexpr uint32_t RBBI_BOF_REQUIRED = 2;
+constexpr uint32_t RBBI_8BITS_ROWS = 4;
 
 
 /*                                        */
@@ -150,6 +165,8 @@
     RBBIDataWrapper(UDataMemory* udm, UErrorCode &status);
     ~RBBIDataWrapper();
 
+    static UBool          isDataVersionAcceptable(const UVersionInfo version);
+
     void                  init0();
     void                  init(const RBBIDataHeader *data, UErrorCode &status);
     RBBIDataWrapper      *addReference();
@@ -157,13 +174,8 @@
     UBool                 operator ==(const RBBIDataWrapper &other) const;
     int32_t               hashCode();
     const UnicodeString  &getRuleSourceString() const;
-#ifdef RBBI_DEBUG
     void                  printData();
     void                  printTable(const char *heading, const RBBIStateTable *table);
-#else
-    #define printData()
-    #define printTable(heading, table)
-#endif
 
     /*                                     */
     /*   Pointers to items within the data */
@@ -171,30 +183,30 @@
     const RBBIDataHeader     *fHeader;
     const RBBIStateTable     *fForwardTable;
     const RBBIStateTable     *fReverseTable;
-    const RBBIStateTable     *fSafeFwdTable;
-    const RBBIStateTable     *fSafeRevTable;
-    const UChar              *fRuleSource;
+    const char               *fRuleSource;
     const int32_t            *fRuleStatusTable; 
 
     /* number of int32_t values in the rule status table.   Used to sanity check indexing */
     int32_t             fStatusMaxIdx;
 
-    UTrie               fTrie;
+    UCPTrie             *fTrie;
 
 private:
     u_atomic_int32_t    fRefCount;
-    UDataMemory  *fUDataMem;
+    UDataMemory        *fUDataMem;
     UnicodeString       fRuleString;
     UBool               fDontFreeData;
 
-    RBBIDataWrapper(const RBBIDataWrapper &other); /*  forbid copying of this class */
-    RBBIDataWrapper &operator=(const RBBIDataWrapper &other); /*  forbid copying of this class */
+    RBBIDataWrapper(const RBBIDataWrapper &other) = delete; /*  forbid copying of this class */
+    RBBIDataWrapper &operator=(const RBBIDataWrapper &other) = delete; /*  forbid copying of this class */
 };
 
 
 
 U_NAMESPACE_END
 
+U_CFUNC UBool rbbi_cleanup(void);
+
 #endif /* C++ */
 
 #endif
diff --git a/src/third_party/icu/source/common/rbbinode.cpp b/src/third_party/icu/source/common/rbbinode.cpp
index 90ef4f0..d99577c 100644
--- a/src/third_party/icu/source/common/rbbinode.cpp
+++ b/src/third_party/icu/source/common/rbbinode.cpp
@@ -1,6 +1,8 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ***************************************************************************
-*   Copyright (C) 2002-2008 International Business Machines Corporation   *
+*   Copyright (C) 2002-2016 International Business Machines Corporation   *
 *   and others. All rights reserved.                                      *
 ***************************************************************************
 */
@@ -19,12 +21,16 @@
 
 #if !UCONFIG_NO_BREAK_ITERATION
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/unistr.h"
 #include "unicode/uniset.h"
 #include "unicode/uchar.h"
 #include "unicode/parsepos.h"
+
+#include "cstr.h"
 #include "uvector.h"
 
 #include "rbbirb.h"
@@ -58,6 +64,8 @@
     fLastPos      = 0;
     fNullable     = FALSE;
     fLookAheadEnd = FALSE;
+    fRuleRoot     = FALSE;
+    fChainIn      = FALSE;
     fVal          = 0;
     fPrecedence   = precZero;
 
@@ -88,6 +96,8 @@
     fLastPos     = other.fLastPos;
     fNullable    = other.fNullable;
     fVal         = other.fVal;
+    fRuleRoot    = FALSE;
+    fChainIn     = other.fChainIn;
     UErrorCode     status = U_ZERO_ERROR;
     fFirstPosSet = new UVector(status);   // TODO - get a real status from somewhere
     fLastPosSet  = new UVector(status);
@@ -188,8 +198,12 @@
 //-------------------------------------------------------------------------
 RBBINode *RBBINode::flattenVariables() {
     if (fType == varRef) {
-        RBBINode *retNode = fLeftChild->cloneTree();
-        delete this;
+        RBBINode *retNode  = fLeftChild->cloneTree();
+        if (retNode != NULL) {
+            retNode->fRuleRoot = this->fRuleRoot;
+            retNode->fChainIn  = this->fChainIn;
+        }
+        delete this;   // TODO: undefined behavior. Fix.
         return retNode;
     }
 
@@ -274,7 +288,13 @@
 //
 //-------------------------------------------------------------------------
 #ifdef RBBI_DEBUG
-void RBBINode::printNode() {
+
+static int32_t serial(const RBBINode *node) {
+    return (node == NULL? -1 : node->fSerialNum);
+}
+
+
+void RBBINode::printNode(const RBBINode *node) {
     static const char * const nodeTypeNames[] = {
                 "setRef",
                 "uset",
@@ -294,14 +314,16 @@
                 "opLParen"
     };
 
-    if (this==NULL) {
-        RBBIDebugPrintf("%10p", (void *)this);
+    if (node==NULL) {
+        RBBIDebugPrintf("%10p", (void *)node);
     } else {
-        RBBIDebugPrintf("%10p  %12s  %10p  %10p  %10p      %4d     %6d   %d ",
-            (void *)this, nodeTypeNames[fType], (void *)fParent, (void *)fLeftChild, (void *)fRightChild,
-            fSerialNum, fFirstPos, fVal);
-        if (fType == varRef) {
-            RBBI_DEBUG_printUnicodeString(fText);
+        RBBIDebugPrintf("%10p %5d %12s %c%c  %5d       %5d     %5d       %6d     %d ",
+            (void *)node, node->fSerialNum, nodeTypeNames[node->fType],
+            node->fRuleRoot?'R':' ', node->fChainIn?'C':' ',
+            serial(node->fLeftChild), serial(node->fRightChild), serial(node->fParent),
+            node->fFirstPos, node->fVal);
+        if (node->fType == varRef) {
+            RBBI_DEBUG_printUnicodeString(node->fText);
         }
     }
     RBBIDebugPrintf("\n");
@@ -310,16 +332,8 @@
 
 
 #ifdef RBBI_DEBUG
-U_CFUNC void RBBI_DEBUG_printUnicodeString(const UnicodeString &s, int minWidth)
-{
-    int i;
-    for (i=0; i<s.length(); i++) {
-        RBBIDebugPrintf("%c", s.charAt(i));
-        // putc(s.charAt(i), stdout);
-    }
-    for (i=s.length(); i<minWidth; i++) {
-        RBBIDebugPrintf(" ");
-    }
+U_CFUNC void RBBI_DEBUG_printUnicodeString(const UnicodeString &s, int minWidth) {
+    RBBIDebugPrintf("%*s", minWidth, CStr(s)());
 }
 #endif
 
@@ -330,23 +344,25 @@
 //
 //-------------------------------------------------------------------------
 #ifdef RBBI_DEBUG
-void RBBINode::printTree(UBool printHeading) {
+void RBBINode::printNodeHeader() {
+    RBBIDebugPrintf(" Address   serial        type     LeftChild  RightChild   Parent   position value\n");
+}
+    
+void RBBINode::printTree(const RBBINode *node, UBool printHeading) {
     if (printHeading) {
-        RBBIDebugPrintf( "-------------------------------------------------------------------\n"
-                         "    Address       type         Parent   LeftChild  RightChild    serial  position value\n"
-              );
+        printNodeHeader();
     }
-    this->printNode();
-    if (this != NULL) {
+    printNode(node);
+    if (node != NULL) {
         // Only dump the definition under a variable reference if asked to.
         // Unconditinally dump children of all other node types.
-        if (fType != varRef) {
-            if (fLeftChild != NULL) {
-                fLeftChild->printTree(FALSE);
+        if (node->fType != varRef) {
+            if (node->fLeftChild != NULL) {
+                printTree(node->fLeftChild, FALSE);
             }
             
-            if (fRightChild != NULL) {
-                fRightChild->printTree(FALSE);
+            if (node->fRightChild != NULL) {
+                printTree(node->fRightChild, FALSE);
             }
         }
     }
diff --git a/src/third_party/icu/source/common/rbbinode.h b/src/third_party/icu/source/common/rbbinode.h
index 0cbf6a7..cff3ba7 100644
--- a/src/third_party/icu/source/common/rbbinode.h
+++ b/src/third_party/icu/source/common/rbbinode.h
@@ -1,6 +1,8 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /********************************************************************
  * COPYRIGHT:
- * Copyright (c) 2001-2006, International Business Machines Corporation and
+ * Copyright (c) 2001-2016, International Business Machines Corporation and
  * others. All Rights Reserved.
  ********************************************************************/
 
@@ -8,6 +10,7 @@
 #define RBBINODE_H
 
 #include "unicode/utypes.h"
+#include "unicode/unistr.h"
 #include "unicode/uobject.h"
 
 //
@@ -76,9 +79,13 @@
                                             //   corresponds to columns in the final
                                             //   state transition table.
 
-        UBool         fLookAheadEnd;        // For endMark nodes, set TRUE if
+        UBool         fLookAheadEnd;        // For endMark nodes, set true if
                                             //   marking the end of a look-ahead rule.
 
+        UBool         fRuleRoot;            // True if this node is the root of a rule.
+        UBool         fChainIn;             // True if chaining into this rule is allowed
+                                            //     (no '^' present).
+
         UVector       *fFirstPosSet;
         UVector       *fLastPosSet;         // TODO: rename fFirstPos & fLastPos to avoid confusion.
         UVector       *fFollowPos;
@@ -94,8 +101,9 @@
         void         findNodes(UVector *dest, RBBINode::NodeType kind, UErrorCode &status);
 
 #ifdef RBBI_DEBUG
-        void        printNode();
-        void        printTree(UBool withHeading);
+        static void printNodeHeader();
+        static void printNode(const RBBINode *n);
+        static void printTree(const RBBINode *n, UBool withHeading);
 #endif
 
     private:
@@ -103,6 +111,7 @@
         UBool operator == (const RBBINode &other);    // Private, so these functions won't accidently be used.
 
 #ifdef RBBI_DEBUG
+    public:
         int           fSerialNum;           //  Debugging aids.
 #endif
 };
diff --git a/src/third_party/icu/source/common/rbbirb.cpp b/src/third_party/icu/source/common/rbbirb.cpp
index b7f5a75..bb67c3b 100644
--- a/src/third_party/icu/source/common/rbbirb.cpp
+++ b/src/third_party/icu/source/common/rbbirb.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 //
 //  file:  rbbirb.cpp
 //
@@ -13,7 +15,9 @@
 
 #if !UCONFIG_NO_BREAK_ITERATION
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/brkiter.h"
 #include "unicode/rbbi.h"
 #include "unicode/ubrk.h"
@@ -21,18 +25,19 @@
 #include "unicode/uniset.h"
 #include "unicode/uchar.h"
 #include "unicode/uchriter.h"
+#include "unicode/ustring.h"
 #include "unicode/parsepos.h"
 #include "unicode/parseerr.h"
+
 #include "cmemory.h"
 #include "cstring.h"
-
 #include "rbbirb.h"
 #include "rbbinode.h"
-
 #include "rbbiscan.h"
 #include "rbbisetb.h"
 #include "rbbitblb.h"
 #include "rbbidata.h"
+#include "uassert.h"
 
 
 U_NAMESPACE_BEGIN
@@ -46,7 +51,7 @@
 RBBIRuleBuilder::RBBIRuleBuilder(const UnicodeString   &rules,
                                        UParseError     *parseErr,
                                        UErrorCode      &status)
- : fRules(rules)
+ : fRules(rules), fStrippedRules(rules)
 {
     fStatus = &status; // status is checked below
     fParseError = parseErr;
@@ -61,10 +66,7 @@
     fSafeFwdTree        = NULL;
     fSafeRevTree        = NULL;
     fDefaultTree        = &fForwardTree;
-    fForwardTables      = NULL;
-    fReverseTables      = NULL;
-    fSafeFwdTables      = NULL;
-    fSafeRevTables      = NULL;
+    fForwardTable       = NULL;
     fRuleStatusVals     = NULL;
     fChainRules         = FALSE;
     fLBCMNoChain        = FALSE;
@@ -113,11 +115,7 @@
 
     delete fUSetNodes;
     delete fSetBuilder;
-    delete fForwardTables;
-    delete fReverseTables;
-    delete fSafeFwdTables;
-    delete fSafeRevTables;
-
+    delete fForwardTable;
     delete fForwardTree;
     delete fReverseTree;
     delete fSafeFwdTree;
@@ -146,8 +144,9 @@
         return NULL;
     }
 
-    // Remove comments and whitespace from the rules to make it smaller.
-    UnicodeString strippedRules((const UnicodeString&)RBBIRuleScanner::stripRules(fRules));
+    // Remove whitespace from the rules to make it smaller.
+    // The rule parser has already removed comments.
+    fStrippedRules = fScanner->stripRules(fStrippedRules);
 
     // Calculate the size of each section in the data.
     //   Sizes here are padded up to a multiple of 8 for better memory alignment.
@@ -155,18 +154,37 @@
     //     without the padding.
     //
     int32_t headerSize        = align8(sizeof(RBBIDataHeader));
-    int32_t forwardTableSize  = align8(fForwardTables->getTableSize());
-    int32_t reverseTableSize  = align8(fReverseTables->getTableSize());
-    int32_t safeFwdTableSize  = align8(fSafeFwdTables->getTableSize());
-    int32_t safeRevTableSize  = align8(fSafeRevTables->getTableSize());
+    int32_t forwardTableSize  = align8(fForwardTable->getTableSize());
+    int32_t reverseTableSize  = align8(fForwardTable->getSafeTableSize());
     int32_t trieSize          = align8(fSetBuilder->getTrieSize());
     int32_t statusTableSize   = align8(fRuleStatusVals->size() * sizeof(int32_t));
-    int32_t rulesSize         = align8((strippedRules.length()+1) * sizeof(UChar));
 
-    int32_t         totalSize = headerSize + forwardTableSize + reverseTableSize
-                                + safeFwdTableSize + safeRevTableSize 
+    int32_t rulesLengthInUTF8 = 0;
+    u_strToUTF8WithSub(0, 0, &rulesLengthInUTF8,
+                       fStrippedRules.getBuffer(), fStrippedRules.length(),
+                       0xfffd, nullptr, fStatus);
+    *fStatus = U_ZERO_ERROR;
+
+    int32_t rulesSize         = align8((rulesLengthInUTF8+1));
+
+    int32_t         totalSize = headerSize
+                                + forwardTableSize
+                                + reverseTableSize
                                 + statusTableSize + trieSize + rulesSize;
 
+#ifdef RBBI_DEBUG
+    if (fDebugEnv && uprv_strstr(fDebugEnv, "size")) {
+        RBBIDebugPrintf("Header Size:        %8d\n", headerSize);
+        RBBIDebugPrintf("Forward Table Size: %8d\n", forwardTableSize);
+        RBBIDebugPrintf("Reverse Table Size: %8d\n", reverseTableSize);
+        RBBIDebugPrintf("Trie Size:          %8d\n", trieSize);
+        RBBIDebugPrintf("Status Table Size:  %8d\n", statusTableSize);
+        RBBIDebugPrintf("Rules Size:         %8d\n", rulesSize);
+        RBBIDebugPrintf("-----------------------------\n");
+        RBBIDebugPrintf("Total Size:         %8d\n", totalSize);
+    }
+#endif
+
     RBBIDataHeader  *data     = (RBBIDataHeader *)uprv_malloc(totalSize);
     if (data == NULL) {
         *fStatus = U_MEMORY_ALLOCATION_ERROR;
@@ -176,35 +194,30 @@
 
 
     data->fMagic            = 0xb1a0;
-    data->fFormatVersion[0] = 3;
-    data->fFormatVersion[1] = 1;
-    data->fFormatVersion[2] = 0;
-    data->fFormatVersion[3] = 0;
+    data->fFormatVersion[0] = RBBI_DATA_FORMAT_VERSION[0];
+    data->fFormatVersion[1] = RBBI_DATA_FORMAT_VERSION[1];
+    data->fFormatVersion[2] = RBBI_DATA_FORMAT_VERSION[2];
+    data->fFormatVersion[3] = RBBI_DATA_FORMAT_VERSION[3];
     data->fLength           = totalSize;
     data->fCatCount         = fSetBuilder->getNumCharCategories();
 
     data->fFTable        = headerSize;
     data->fFTableLen     = forwardTableSize;
-    data->fRTable        = data->fFTable  + forwardTableSize;
-    data->fRTableLen     = reverseTableSize;
-    data->fSFTable       = data->fRTable  + reverseTableSize;
-    data->fSFTableLen    = safeFwdTableSize;
-    data->fSRTable       = data->fSFTable + safeFwdTableSize;
-    data->fSRTableLen    = safeRevTableSize;
 
-    data->fTrie          = data->fSRTable + safeRevTableSize;
-    data->fTrieLen       = fSetBuilder->getTrieSize();
-    data->fStatusTable   = data->fTrie    + trieSize;
+    data->fRTable        = data->fFTable  + data->fFTableLen;
+    data->fRTableLen     = reverseTableSize;
+
+    data->fTrie          = data->fRTable + data->fRTableLen;
+    data->fTrieLen       = trieSize;
+    data->fStatusTable   = data->fTrie    + data->fTrieLen;
     data->fStatusTableLen= statusTableSize;
     data->fRuleSource    = data->fStatusTable + statusTableSize;
-    data->fRuleSourceLen = strippedRules.length() * sizeof(UChar);
+    data->fRuleSourceLen = rulesLengthInUTF8;
 
     uprv_memset(data->fReserved, 0, sizeof(data->fReserved));
 
-    fForwardTables->exportTable((uint8_t *)data + data->fFTable);
-    fReverseTables->exportTable((uint8_t *)data + data->fRTable);
-    fSafeFwdTables->exportTable((uint8_t *)data + data->fSFTable);
-    fSafeRevTables->exportTable((uint8_t *)data + data->fSRTable);
+    fForwardTable->exportTable((uint8_t *)data + data->fFTable);
+    fForwardTable->exportSafeTable((uint8_t *)data + data->fRTable);
     fSetBuilder->serializeTrie ((uint8_t *)data + data->fTrie);
 
     int32_t *ruleStatusTable = (int32_t *)((uint8_t *)data + data->fStatusTable);
@@ -212,16 +225,17 @@
         ruleStatusTable[i] = fRuleStatusVals->elementAti(i);
     }
 
-    strippedRules.extract((UChar *)((uint8_t *)data+data->fRuleSource), rulesSize/2+1, *fStatus);
+    u_strToUTF8WithSub((char *)data+data->fRuleSource, rulesSize, &rulesLengthInUTF8,
+                       fStrippedRules.getBuffer(), fStrippedRules.length(),
+                       0xfffd, nullptr, fStatus);
+    if (U_FAILURE(*fStatus)) {
+        return NULL;
+    }
 
     return data;
 }
 
 
-
-
-
-
 //----------------------------------------------------------------------------------------
 //
 //  createRuleBasedBreakIterator    construct from source rules that are passed in
@@ -233,8 +247,6 @@
                                     UParseError      *parseError,
                                     UErrorCode       &status)
 {
-    // status checked below
-
     //
     // Read the input rules, generate a parse tree, symbol table,
     // and list of all Unicode Sets referenced by the rules.
@@ -243,61 +255,13 @@
     if (U_FAILURE(status)) { // status checked here bcos build below doesn't
         return NULL;
     }
-    builder.fScanner->parse();
 
-    //
-    // UnicodeSet processing.
-    //    Munge the Unicode Sets to create a set of character categories.
-    //    Generate the mapping tables (TRIE) from input 32-bit characters to
-    //    the character categories.
-    //
-    builder.fSetBuilder->build();
+    RBBIDataHeader *data = builder.build(status);
 
-
-    //
-    //   Generate the DFA state transition table.
-    //
-    builder.fForwardTables = new RBBITableBuilder(&builder, &builder.fForwardTree);
-    builder.fReverseTables = new RBBITableBuilder(&builder, &builder.fReverseTree);
-    builder.fSafeFwdTables = new RBBITableBuilder(&builder, &builder.fSafeFwdTree);
-    builder.fSafeRevTables = new RBBITableBuilder(&builder, &builder.fSafeRevTree);
-    if (builder.fForwardTables == NULL || builder.fReverseTables == NULL ||
-        builder.fSafeFwdTables == NULL || builder.fSafeRevTables == NULL)
-    {
-        status = U_MEMORY_ALLOCATION_ERROR;
-        delete builder.fForwardTables; builder.fForwardTables = NULL;
-        delete builder.fReverseTables; builder.fReverseTables = NULL;
-        delete builder.fSafeFwdTables; builder.fSafeFwdTables = NULL;
-        delete builder.fSafeRevTables; builder.fSafeRevTables = NULL;
-        return NULL;
+    if (U_FAILURE(status)) {
+        return nullptr;
     }
 
-    builder.fForwardTables->build();
-    builder.fReverseTables->build();
-    builder.fSafeFwdTables->build();
-    builder.fSafeRevTables->build();
-
-#ifdef RBBI_DEBUG
-    if (builder.fDebugEnv && uprv_strstr(builder.fDebugEnv, "states")) {
-        builder.fForwardTables->printRuleStatusTable();
-    }
-#endif
-
-    //
-    //   Package up the compiled data into a memory image
-    //      in the run-time format.
-    //
-    RBBIDataHeader *data = builder.flattenData(); // returns NULL if error
-    if (U_FAILURE(*builder.fStatus)) {
-        return NULL;
-    }
-
-
-    //
-    //  Clean up the compiler related stuff
-    //
-
-
     //
     //  Create a break iterator from the compiled rules.
     //     (Identical to creation from stored pre-compiled rules)
@@ -314,6 +278,87 @@
     return This;
 }
 
+RBBIDataHeader *RBBIRuleBuilder::build(UErrorCode &status) {
+    if (U_FAILURE(status)) {
+        return nullptr;
+    }
+
+    fScanner->parse();
+    if (U_FAILURE(status)) {
+        return nullptr;
+    }
+
+    //
+    // UnicodeSet processing.
+    //    Munge the Unicode Sets to create an initial set of character categories.
+    //
+    fSetBuilder->buildRanges();
+
+    //
+    //   Generate the DFA state transition table.
+    //
+    fForwardTable = new RBBITableBuilder(this, &fForwardTree, status);
+    if (fForwardTable == nullptr) {
+        status = U_MEMORY_ALLOCATION_ERROR;
+        return nullptr;
+    }
+
+    fForwardTable->buildForwardTable();
+
+    // State table and character category optimization.
+    // Merge equivalent rows and columns.
+    // Note that this process alters the initial set of character categories,
+    // causing the representation of UnicodeSets in the parse tree to become invalid.
+
+    optimizeTables();
+    fForwardTable->buildSafeReverseTable(status);
+
+
+#ifdef RBBI_DEBUG
+    if (fDebugEnv && uprv_strstr(fDebugEnv, "states")) {
+        fForwardTable->printStates();
+        fForwardTable->printRuleStatusTable();
+        fForwardTable->printReverseTable();
+    }
+#endif
+
+    //    Generate the mapping tables (TRIE) from input code points to
+    //    the character categories.
+    //
+    fSetBuilder->buildTrie();
+
+    //
+    //   Package up the compiled data into a memory image
+    //      in the run-time format.
+    //
+    RBBIDataHeader *data = flattenData(); // returns NULL if error
+    if (U_FAILURE(status)) {
+        return nullptr;
+    }
+    return data;
+}
+
+void RBBIRuleBuilder::optimizeTables() {
+    bool didSomething;
+    do {
+        didSomething = false;
+
+        // Begin looking for duplicates with char class 3.
+        // Classes 0, 1 and 2 are special; they are unused, {bof} and {eof} respectively,
+        // and should not have other categories merged into them.
+        IntPair duplPair = {3, 0};
+        while (fForwardTable->findDuplCharClassFrom(&duplPair)) {
+            fSetBuilder->mergeCategories(duplPair);
+            fForwardTable->removeColumn(duplPair.second);
+            didSomething = true;
+        }
+
+        while (fForwardTable->removeDuplicateStates() > 0) {
+            didSomething = true;
+        }
+    } while (didSomething);
+}
+
 U_NAMESPACE_END
 
 #endif /* #if !UCONFIG_NO_BREAK_ITERATION */
diff --git a/src/third_party/icu/source/common/rbbirb.h b/src/third_party/icu/source/common/rbbirb.h
index deb9b0e..037c1dc 100644
--- a/src/third_party/icu/source/common/rbbirb.h
+++ b/src/third_party/icu/source/common/rbbirb.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 //
 //  rbbirb.h
 //
@@ -13,6 +15,11 @@
 #define RBBIRB_H
 
 #include "unicode/utypes.h"
+
+#if !UCONFIG_NO_BREAK_ITERATION
+
+#include <utility>
+
 #include "unicode/uobject.h"
 #include "unicode/rbbi.h"
 #include "unicode/uniset.h"
@@ -20,8 +27,7 @@
 #include "uhash.h"
 #include "uvector.h"
 #include "unicode/symtable.h"// For UnicodeSet parsing, is the interface that
-                          //    looks up references to $variables within a set.
-
+                             //    looks up references to $variables within a set.
 
 
 U_NAMESPACE_BEGIN
@@ -118,13 +124,28 @@
     RBBIRuleBuilder(const UnicodeString  &rules,
                     UParseError          *parseErr,
                     UErrorCode           &status
-        );
+    );
 
     virtual    ~RBBIRuleBuilder();
+
+    /**
+     *  Build the state tables and char class Trie from the source rules.
+     */
+    RBBIDataHeader  *build(UErrorCode &status);
+
+
+    /**
+     * Fold together redundant character classes (table columns) and
+     * redundant states (table rows). Done after initial table generation,
+     * before serializing the result.
+     */
+    void optimizeTables();
+
     char                          *fDebugEnv;        // controls debug trace output
     UErrorCode                    *fStatus;          // Error reporting.  Keeping status
     UParseError                   *fParseError;      //   here avoids passing it everywhere.
     const UnicodeString           &fRules;           // The rule string that we are compiling
+    UnicodeString                 fStrippedRules;    // The rule string, with comments stripped.
 
     RBBIRuleScanner               *fScanner;         // The scanner.
     RBBINode                      *fForwardTree;     // The parse trees, generated by the scanner,
@@ -148,10 +169,7 @@
     RBBISetBuilder                *fSetBuilder;      // Set and Character Category builder.
     UVector                       *fUSetNodes;       // Vector of all uset nodes.
 
-    RBBITableBuilder              *fForwardTables;   // State transition tables
-    RBBITableBuilder              *fReverseTables;
-    RBBITableBuilder              *fSafeFwdTables;
-    RBBITableBuilder              *fSafeRevTables;
+    RBBITableBuilder              *fForwardTable;    // State transition table, build time form.
 
     UVector                       *fRuleStatusVals;  // The values that can be returned
                                                      //   from getRuleStatus().
@@ -186,6 +204,11 @@
     RBBINode      *val;
 };
 
+/**
+ *   A pair of ints, used to bundle pairs of states or pairs of character classes.
+ */
+typedef std::pair<int32_t, int32_t> IntPair;
+
 
 //----------------------------------------------------------------------------
 //
@@ -205,6 +228,9 @@
 #endif
 
 U_NAMESPACE_END
+
+#endif /* #if !UCONFIG_NO_BREAK_ITERATION */
+
 #endif
 
 
diff --git a/src/third_party/icu/source/common/rbbirpt.h b/src/third_party/icu/source/common/rbbirpt.h
index deea57b..586953c 100644
--- a/src/third_party/icu/source/common/rbbirpt.h
+++ b/src/third_party/icu/source/common/rbbirpt.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 //---------------------------------------------------------------------------------
 //
 // Generated Header File.  Do not edit by hand.
@@ -6,13 +8,15 @@
 //    It is generated by the Perl script "rbbicst.pl" from
 //    the rule parser state definitions file "rbbirpt.txt".
 //
-//   Copyright (C) 2002-2005 International Business Machines Corporation 
+//   Copyright (C) 2002-2016 International Business Machines Corporation 
 //   and others. All rights reserved.  
 //
 //---------------------------------------------------------------------------------
 #ifndef RBBIRPT_H
 #define RBBIRPT_H
 
+#include "unicode/utypes.h"
+
 U_NAMESPACE_BEGIN
 //
 // Character classes for RBBI rule scanning.
@@ -38,6 +42,7 @@
     doExprStart,
     doLParen,
     doNOP,
+    doNoChain,
     doOptionEnd,
     doOptionStart,
     doReverseDir,
@@ -75,101 +80,109 @@
 
 static const struct RBBIRuleTableEl gRuleParseStateTable[] = {
     {doNOP, 0, 0, 0, TRUE}
-    , {doExprStart, 254, 21, 8, FALSE}     //  1      start
+    , {doExprStart, 254, 29, 9, FALSE}     //  1      start
     , {doNOP, 132, 1,0,  TRUE}     //  2 
-    , {doExprStart, 36 /* $ */, 80, 90, FALSE}     //  3 
-    , {doNOP, 33 /* ! */, 11,0,  TRUE}     //  4 
-    , {doNOP, 59 /* ; */, 1,0,  TRUE}     //  5 
-    , {doNOP, 252, 0,0,  FALSE}     //  6 
-    , {doExprStart, 255, 21, 8, FALSE}     //  7 
-    , {doEndOfRule, 59 /* ; */, 1,0,  TRUE}     //  8      break-rule-end
-    , {doNOP, 132, 8,0,  TRUE}     //  9 
-    , {doRuleError, 255, 95,0,  FALSE}     //  10 
-    , {doNOP, 33 /* ! */, 13,0,  TRUE}     //  11      rev-option
-    , {doReverseDir, 255, 20, 8, FALSE}     //  12 
-    , {doOptionStart, 130, 15,0,  TRUE}     //  13      option-scan1
-    , {doRuleError, 255, 95,0,  FALSE}     //  14 
-    , {doNOP, 129, 15,0,  TRUE}     //  15      option-scan2
-    , {doOptionEnd, 255, 17,0,  FALSE}     //  16 
-    , {doNOP, 59 /* ; */, 1,0,  TRUE}     //  17      option-scan3
-    , {doNOP, 132, 17,0,  TRUE}     //  18 
-    , {doRuleError, 255, 95,0,  FALSE}     //  19 
-    , {doExprStart, 255, 21, 8, FALSE}     //  20      reverse-rule
-    , {doRuleChar, 254, 30,0,  TRUE}     //  21      term
-    , {doNOP, 132, 21,0,  TRUE}     //  22 
-    , {doRuleChar, 131, 30,0,  TRUE}     //  23 
-    , {doNOP, 91 /* [ */, 86, 30, FALSE}     //  24 
-    , {doLParen, 40 /* ( */, 21, 30, TRUE}     //  25 
-    , {doNOP, 36 /* $ */, 80, 29, FALSE}     //  26 
-    , {doDotAny, 46 /* . */, 30,0,  TRUE}     //  27 
-    , {doRuleError, 255, 95,0,  FALSE}     //  28 
-    , {doCheckVarDef, 255, 30,0,  FALSE}     //  29      term-var-ref
-    , {doNOP, 132, 30,0,  TRUE}     //  30      expr-mod
-    , {doUnaryOpStar, 42 /* * */, 35,0,  TRUE}     //  31 
-    , {doUnaryOpPlus, 43 /* + */, 35,0,  TRUE}     //  32 
-    , {doUnaryOpQuestion, 63 /* ? */, 35,0,  TRUE}     //  33 
-    , {doNOP, 255, 35,0,  FALSE}     //  34 
-    , {doExprCatOperator, 254, 21,0,  FALSE}     //  35      expr-cont
-    , {doNOP, 132, 35,0,  TRUE}     //  36 
-    , {doExprCatOperator, 131, 21,0,  FALSE}     //  37 
-    , {doExprCatOperator, 91 /* [ */, 21,0,  FALSE}     //  38 
-    , {doExprCatOperator, 40 /* ( */, 21,0,  FALSE}     //  39 
-    , {doExprCatOperator, 36 /* $ */, 21,0,  FALSE}     //  40 
-    , {doExprCatOperator, 46 /* . */, 21,0,  FALSE}     //  41 
-    , {doExprCatOperator, 47 /* / */, 47,0,  FALSE}     //  42 
-    , {doExprCatOperator, 123 /* { */, 59,0,  TRUE}     //  43 
-    , {doExprOrOperator, 124 /* | */, 21,0,  TRUE}     //  44 
-    , {doExprRParen, 41 /* ) */, 255,0,  TRUE}     //  45 
-    , {doExprFinished, 255, 255,0,  FALSE}     //  46 
-    , {doSlash, 47 /* / */, 49,0,  TRUE}     //  47      look-ahead
-    , {doNOP, 255, 95,0,  FALSE}     //  48 
-    , {doExprCatOperator, 254, 21,0,  FALSE}     //  49      expr-cont-no-slash
-    , {doNOP, 132, 35,0,  TRUE}     //  50 
-    , {doExprCatOperator, 131, 21,0,  FALSE}     //  51 
-    , {doExprCatOperator, 91 /* [ */, 21,0,  FALSE}     //  52 
-    , {doExprCatOperator, 40 /* ( */, 21,0,  FALSE}     //  53 
-    , {doExprCatOperator, 36 /* $ */, 21,0,  FALSE}     //  54 
-    , {doExprCatOperator, 46 /* . */, 21,0,  FALSE}     //  55 
-    , {doExprOrOperator, 124 /* | */, 21,0,  TRUE}     //  56 
-    , {doExprRParen, 41 /* ) */, 255,0,  TRUE}     //  57 
-    , {doExprFinished, 255, 255,0,  FALSE}     //  58 
-    , {doNOP, 132, 59,0,  TRUE}     //  59      tag-open
-    , {doStartTagValue, 128, 62,0,  FALSE}     //  60 
-    , {doTagExpectedError, 255, 95,0,  FALSE}     //  61 
-    , {doNOP, 132, 66,0,  TRUE}     //  62      tag-value
-    , {doNOP, 125 /* } */, 66,0,  FALSE}     //  63 
-    , {doTagDigit, 128, 62,0,  TRUE}     //  64 
-    , {doTagExpectedError, 255, 95,0,  FALSE}     //  65 
-    , {doNOP, 132, 66,0,  TRUE}     //  66      tag-close
-    , {doTagValue, 125 /* } */, 69,0,  TRUE}     //  67 
-    , {doTagExpectedError, 255, 95,0,  FALSE}     //  68 
-    , {doExprCatOperator, 254, 21,0,  FALSE}     //  69      expr-cont-no-tag
-    , {doNOP, 132, 69,0,  TRUE}     //  70 
-    , {doExprCatOperator, 131, 21,0,  FALSE}     //  71 
-    , {doExprCatOperator, 91 /* [ */, 21,0,  FALSE}     //  72 
-    , {doExprCatOperator, 40 /* ( */, 21,0,  FALSE}     //  73 
-    , {doExprCatOperator, 36 /* $ */, 21,0,  FALSE}     //  74 
-    , {doExprCatOperator, 46 /* . */, 21,0,  FALSE}     //  75 
-    , {doExprCatOperator, 47 /* / */, 47,0,  FALSE}     //  76 
-    , {doExprOrOperator, 124 /* | */, 21,0,  TRUE}     //  77 
-    , {doExprRParen, 41 /* ) */, 255,0,  TRUE}     //  78 
-    , {doExprFinished, 255, 255,0,  FALSE}     //  79 
-    , {doStartVariableName, 36 /* $ */, 82,0,  TRUE}     //  80      scan-var-name
-    , {doNOP, 255, 95,0,  FALSE}     //  81 
-    , {doNOP, 130, 84,0,  TRUE}     //  82      scan-var-start
-    , {doVariableNameExpectedErr, 255, 95,0,  FALSE}     //  83 
-    , {doNOP, 129, 84,0,  TRUE}     //  84      scan-var-body
-    , {doEndVariableName, 255, 255,0,  FALSE}     //  85 
-    , {doScanUnicodeSet, 91 /* [ */, 255,0,  TRUE}     //  86      scan-unicode-set
-    , {doScanUnicodeSet, 112 /* p */, 255,0,  TRUE}     //  87 
-    , {doScanUnicodeSet, 80 /* P */, 255,0,  TRUE}     //  88 
-    , {doNOP, 255, 95,0,  FALSE}     //  89 
-    , {doNOP, 132, 90,0,  TRUE}     //  90      assign-or-rule
-    , {doStartAssign, 61 /* = */, 21, 93, TRUE}     //  91 
-    , {doNOP, 255, 29, 8, FALSE}     //  92 
-    , {doEndAssign, 59 /* ; */, 1,0,  TRUE}     //  93      assign-end
-    , {doRuleErrorAssignExpr, 255, 95,0,  FALSE}     //  94 
-    , {doExit, 255, 95,0,  TRUE}     //  95      errorDeath
+    , {doNoChain, 94 /* ^ */, 12, 9, TRUE}     //  3 
+    , {doExprStart, 36 /* $ */, 88, 98, FALSE}     //  4 
+    , {doNOP, 33 /* ! */, 19,0,  TRUE}     //  5 
+    , {doNOP, 59 /* ; */, 1,0,  TRUE}     //  6 
+    , {doNOP, 252, 0,0,  FALSE}     //  7 
+    , {doExprStart, 255, 29, 9, FALSE}     //  8 
+    , {doEndOfRule, 59 /* ; */, 1,0,  TRUE}     //  9      break-rule-end
+    , {doNOP, 132, 9,0,  TRUE}     //  10 
+    , {doRuleError, 255, 103,0,  FALSE}     //  11 
+    , {doExprStart, 254, 29,0,  FALSE}     //  12      start-after-caret
+    , {doNOP, 132, 12,0,  TRUE}     //  13 
+    , {doRuleError, 94 /* ^ */, 103,0,  FALSE}     //  14 
+    , {doExprStart, 36 /* $ */, 88, 37, FALSE}     //  15 
+    , {doRuleError, 59 /* ; */, 103,0,  FALSE}     //  16 
+    , {doRuleError, 252, 103,0,  FALSE}     //  17 
+    , {doExprStart, 255, 29,0,  FALSE}     //  18 
+    , {doNOP, 33 /* ! */, 21,0,  TRUE}     //  19      rev-option
+    , {doReverseDir, 255, 28, 9, FALSE}     //  20 
+    , {doOptionStart, 130, 23,0,  TRUE}     //  21      option-scan1
+    , {doRuleError, 255, 103,0,  FALSE}     //  22 
+    , {doNOP, 129, 23,0,  TRUE}     //  23      option-scan2
+    , {doOptionEnd, 255, 25,0,  FALSE}     //  24 
+    , {doNOP, 59 /* ; */, 1,0,  TRUE}     //  25      option-scan3
+    , {doNOP, 132, 25,0,  TRUE}     //  26 
+    , {doRuleError, 255, 103,0,  FALSE}     //  27 
+    , {doExprStart, 255, 29, 9, FALSE}     //  28      reverse-rule
+    , {doRuleChar, 254, 38,0,  TRUE}     //  29      term
+    , {doNOP, 132, 29,0,  TRUE}     //  30 
+    , {doRuleChar, 131, 38,0,  TRUE}     //  31 
+    , {doNOP, 91 /* [ */, 94, 38, FALSE}     //  32 
+    , {doLParen, 40 /* ( */, 29, 38, TRUE}     //  33 
+    , {doNOP, 36 /* $ */, 88, 37, FALSE}     //  34 
+    , {doDotAny, 46 /* . */, 38,0,  TRUE}     //  35 
+    , {doRuleError, 255, 103,0,  FALSE}     //  36 
+    , {doCheckVarDef, 255, 38,0,  FALSE}     //  37      term-var-ref
+    , {doNOP, 132, 38,0,  TRUE}     //  38      expr-mod
+    , {doUnaryOpStar, 42 /* * */, 43,0,  TRUE}     //  39 
+    , {doUnaryOpPlus, 43 /* + */, 43,0,  TRUE}     //  40 
+    , {doUnaryOpQuestion, 63 /* ? */, 43,0,  TRUE}     //  41 
+    , {doNOP, 255, 43,0,  FALSE}     //  42 
+    , {doExprCatOperator, 254, 29,0,  FALSE}     //  43      expr-cont
+    , {doNOP, 132, 43,0,  TRUE}     //  44 
+    , {doExprCatOperator, 131, 29,0,  FALSE}     //  45 
+    , {doExprCatOperator, 91 /* [ */, 29,0,  FALSE}     //  46 
+    , {doExprCatOperator, 40 /* ( */, 29,0,  FALSE}     //  47 
+    , {doExprCatOperator, 36 /* $ */, 29,0,  FALSE}     //  48 
+    , {doExprCatOperator, 46 /* . */, 29,0,  FALSE}     //  49 
+    , {doExprCatOperator, 47 /* / */, 55,0,  FALSE}     //  50 
+    , {doExprCatOperator, 123 /* { */, 67,0,  TRUE}     //  51 
+    , {doExprOrOperator, 124 /* | */, 29,0,  TRUE}     //  52 
+    , {doExprRParen, 41 /* ) */, 255,0,  TRUE}     //  53 
+    , {doExprFinished, 255, 255,0,  FALSE}     //  54 
+    , {doSlash, 47 /* / */, 57,0,  TRUE}     //  55      look-ahead
+    , {doNOP, 255, 103,0,  FALSE}     //  56 
+    , {doExprCatOperator, 254, 29,0,  FALSE}     //  57      expr-cont-no-slash
+    , {doNOP, 132, 43,0,  TRUE}     //  58 
+    , {doExprCatOperator, 131, 29,0,  FALSE}     //  59 
+    , {doExprCatOperator, 91 /* [ */, 29,0,  FALSE}     //  60 
+    , {doExprCatOperator, 40 /* ( */, 29,0,  FALSE}     //  61 
+    , {doExprCatOperator, 36 /* $ */, 29,0,  FALSE}     //  62 
+    , {doExprCatOperator, 46 /* . */, 29,0,  FALSE}     //  63 
+    , {doExprOrOperator, 124 /* | */, 29,0,  TRUE}     //  64 
+    , {doExprRParen, 41 /* ) */, 255,0,  TRUE}     //  65 
+    , {doExprFinished, 255, 255,0,  FALSE}     //  66 
+    , {doNOP, 132, 67,0,  TRUE}     //  67      tag-open
+    , {doStartTagValue, 128, 70,0,  FALSE}     //  68 
+    , {doTagExpectedError, 255, 103,0,  FALSE}     //  69 
+    , {doNOP, 132, 74,0,  TRUE}     //  70      tag-value
+    , {doNOP, 125 /* } */, 74,0,  FALSE}     //  71 
+    , {doTagDigit, 128, 70,0,  TRUE}     //  72 
+    , {doTagExpectedError, 255, 103,0,  FALSE}     //  73 
+    , {doNOP, 132, 74,0,  TRUE}     //  74      tag-close
+    , {doTagValue, 125 /* } */, 77,0,  TRUE}     //  75 
+    , {doTagExpectedError, 255, 103,0,  FALSE}     //  76 
+    , {doExprCatOperator, 254, 29,0,  FALSE}     //  77      expr-cont-no-tag
+    , {doNOP, 132, 77,0,  TRUE}     //  78 
+    , {doExprCatOperator, 131, 29,0,  FALSE}     //  79 
+    , {doExprCatOperator, 91 /* [ */, 29,0,  FALSE}     //  80 
+    , {doExprCatOperator, 40 /* ( */, 29,0,  FALSE}     //  81 
+    , {doExprCatOperator, 36 /* $ */, 29,0,  FALSE}     //  82 
+    , {doExprCatOperator, 46 /* . */, 29,0,  FALSE}     //  83 
+    , {doExprCatOperator, 47 /* / */, 55,0,  FALSE}     //  84 
+    , {doExprOrOperator, 124 /* | */, 29,0,  TRUE}     //  85 
+    , {doExprRParen, 41 /* ) */, 255,0,  TRUE}     //  86 
+    , {doExprFinished, 255, 255,0,  FALSE}     //  87 
+    , {doStartVariableName, 36 /* $ */, 90,0,  TRUE}     //  88      scan-var-name
+    , {doNOP, 255, 103,0,  FALSE}     //  89 
+    , {doNOP, 130, 92,0,  TRUE}     //  90      scan-var-start
+    , {doVariableNameExpectedErr, 255, 103,0,  FALSE}     //  91 
+    , {doNOP, 129, 92,0,  TRUE}     //  92      scan-var-body
+    , {doEndVariableName, 255, 255,0,  FALSE}     //  93 
+    , {doScanUnicodeSet, 91 /* [ */, 255,0,  TRUE}     //  94      scan-unicode-set
+    , {doScanUnicodeSet, 112 /* p */, 255,0,  TRUE}     //  95 
+    , {doScanUnicodeSet, 80 /* P */, 255,0,  TRUE}     //  96 
+    , {doNOP, 255, 103,0,  FALSE}     //  97 
+    , {doNOP, 132, 98,0,  TRUE}     //  98      assign-or-rule
+    , {doStartAssign, 61 /* = */, 29, 101, TRUE}     //  99 
+    , {doNOP, 255, 37, 9, FALSE}     //  100 
+    , {doEndAssign, 59 /* ; */, 1,0,  TRUE}     //  101      assign-end
+    , {doRuleErrorAssignExpr, 255, 103,0,  FALSE}     //  102 
+    , {doExit, 255, 103,0,  TRUE}     //  103      errorDeath
  };
 #ifdef RBBI_DEBUG
 static const char * const RBBIRuleStateNames[] = {    0,
@@ -180,9 +193,17 @@
     0,
     0,
     0,
+    0,
      "break-rule-end",
     0,
     0,
+     "start-after-caret",
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
      "rev-option",
     0,
      "option-scan1",
diff --git a/src/third_party/icu/source/common/rbbirpt.txt b/src/third_party/icu/source/common/rbbirpt.txt
index 8e932a6..83f7aa4 100644
--- a/src/third_party/icu/source/common/rbbirpt.txt
+++ b/src/third_party/icu/source/common/rbbirpt.txt
@@ -1,7 +1,13 @@
 
 #*****************************************************************************
 #
-#   Copyright (C) 2002-2003, International Business Machines Corporation and others.
+#   Copyright (C) 2016 and later: Unicode, Inc. and others.
+#   License & terms of use: http://www.unicode.org/copyright.html
+#
+#*****************************************************************************
+#*****************************************************************************
+#
+#   Copyright (C) 2002-2016, International Business Machines Corporation and others.
 #   All Rights Reserved.
 #
 #*****************************************************************************
@@ -19,6 +25,7 @@
 #     This file is processed by a perl script "rbbicst.pl" to produce initialized C arrays
 #     that are then built with the rule parser.
 #
+#    perl rbbicst.pl    < rbbirpt.txt > rbbirpt.h
 
 #
 # Here is the syntax of the state definitions in this file:
@@ -57,6 +64,7 @@
 start:
     escaped                term                  ^break-rule-end    doExprStart                       
     white_space          n start                     
+    '^'                  n start-after-caret     ^break-rule-end    doNoChain
     '$'                    scan-var-name         ^assign-or-rule    doExprStart
     '!'                  n rev-option                             
     ';'                  n start                                                  # ignore empty rules.
@@ -71,7 +79,21 @@
     white_space          n break-rule-end
     default                errorDeath                               doRuleError
      
-
+#
+# start of a rule, after having seen a '^' (inhibits rule chain in).
+#     Similar to the main 'start' state in most respects, except
+#          - empty rule is an error.
+#          - A second '^' is an error.
+#
+start-after-caret:
+    escaped                term                                     doExprStart
+    white_space          n start-after-caret
+    '^'                    errorDeath                               doRuleError    # two '^'s
+    '$'                    scan-var-name         ^term-var-ref      doExprStart
+    ';'                    errorDeath                               doRuleError    # ^ ;
+    eof                    errorDeath                               doRuleError
+    default                term                                     doExprStart
+ 
 #
 #   !               We've just scanned a '!', indicating either a !!key word flag or a
 #                   !Reverse rule.
diff --git a/src/third_party/icu/source/common/rbbiscan.cpp b/src/third_party/icu/source/common/rbbiscan.cpp
index 82690ef..7d0fa21 100644
--- a/src/third_party/icu/source/common/rbbiscan.cpp
+++ b/src/third_party/icu/source/common/rbbiscan.cpp
@@ -1,7 +1,9 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 //
 //  file:  rbbiscan.cpp
 //
-//  Copyright (C) 2002-2015, International Business Machines Corporation and others.
+//  Copyright (C) 2002-2016, International Business Machines Corporation and others.
 //  All Rights Reserved.
 //
 //  This file contains the Rule Based Break Iterator Rule Builder functions for
@@ -16,8 +18,10 @@
 
 #if !UCONFIG_NO_BREAK_ITERATION
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/unistr.h"
 #include "unicode/uniset.h"
 #include "unicode/uchar.h"
@@ -47,6 +51,7 @@
 //
 //------------------------------------------------------------------------------
 static const UChar gRuleSet_rule_char_pattern[]       = {
+ // Characters that may appear as literals in patterns without escaping or quoting.
  //   [    ^      [    \     p     {      Z     }     \     u    0      0    2      0
     0x5b, 0x5e, 0x5b, 0x5c, 0x70, 0x7b, 0x5a, 0x7d, 0x5c, 0x75, 0x30, 0x30, 0x32, 0x30,
  //   -    \      u    0     0     7      f     ]     -     [    \      p
@@ -89,24 +94,27 @@
 RBBIRuleScanner::RBBIRuleScanner(RBBIRuleBuilder *rb)
 {
     fRB                 = rb;
+    fScanIndex          = 0;
+    fNextIndex          = 0;
+    fQuoteMode          = FALSE;
+    fLineNum            = 1;
+    fCharNum            = 0;
+    fLastChar           = 0;
+    
+    fStateTable         = NULL;
+    fStack[0]           = 0;
     fStackPtr           = 0;
-    fStack[fStackPtr]   = 0;
-    fNodeStackPtr       = 0;
-    fRuleNum            = 0;
     fNodeStack[0]       = NULL;
-
-    fSymbolTable                            = NULL;
-    fSetTable                               = NULL;
-
-    fScanIndex = 0;
-    fNextIndex = 0;
+    fNodeStackPtr       = 0;
 
     fReverseRule        = FALSE;
     fLookAheadRule      = FALSE;
+    fNoChainInRule      = FALSE;
 
-    fLineNum    = 1;
-    fCharNum    = 0;
-    fQuoteMode  = FALSE;
+    fSymbolTable        = NULL;
+    fSetTable           = NULL;
+    fRuleNum            = 0;
+    fOptionStart        = 0;
 
     // Do not check status until after all critical fields are sufficiently initialized
     //   that the destructor can run cleanly.
@@ -207,6 +215,12 @@
         break;
 
 
+    case doNoChain:
+        // Scanned a '^' while on the rule start state.
+        fNoChainInRule = TRUE;
+        break;
+
+
     case doExprOrOperator:
         {
             fixOpStack(RBBINode::precOpCat);
@@ -320,11 +334,11 @@
         if (fRB->fDebugEnv && uprv_strstr(fRB->fDebugEnv, "rtree")) {printNodeStack("end of rule");}
 #endif
         U_ASSERT(fNodeStackPtr == 1);
+        RBBINode *thisRule = fNodeStack[fNodeStackPtr];
 
         // If this rule includes a look-ahead '/', add a endMark node to the
         //   expression tree.
         if (fLookAheadRule) {
-            RBBINode  *thisRule       = fNodeStack[fNodeStackPtr];
             RBBINode  *endNode        = pushNewNode(RBBINode::endMark);
             RBBINode  *catNode        = pushNewNode(RBBINode::opCat);
             if (U_FAILURE(*fRB->fStatus)) {
@@ -336,8 +350,24 @@
             fNodeStack[fNodeStackPtr] = catNode;
             endNode->fVal             = fRuleNum;
             endNode->fLookAheadEnd    = TRUE;
+            thisRule                  = catNode;
+
+            // TODO: Disable chaining out of look-ahead (hard break) rules.
+            //   The break on rule match is forced, so there is no point in building up
+            //   the state table to chain into another rule for a longer match.
         }
 
+        // Mark this node as being the root of a rule.
+        thisRule->fRuleRoot = TRUE;
+
+        // Flag if chaining into this rule is wanted.
+        //    
+        if (fRB->fChainRules &&         // If rule chaining is enabled globally via !!chain
+                !fNoChainInRule) {      //     and no '^' chain-in inhibit was on this rule
+            thisRule->fChainIn = TRUE;
+        }
+
+
         // All rule expressions are ORed together.
         // The ';' that terminates an expression really just functions as a '|' with
         //   a low operator prededence.
@@ -346,7 +376,7 @@
         //  (forward, reverse, safe_forward, safe_reverse)
         //  OR this rule into the appropriate group of them.
         //
-        RBBINode **destRules = (fReverseRule? &fRB->fReverseTree : fRB->fDefaultTree);
+        RBBINode **destRules = (fReverseRule? &fRB->fSafeRevTree : fRB->fDefaultTree);
 
         if (*destRules != NULL) {
             // This is not the first rule encounted.
@@ -354,7 +384,7 @@
             // with the current rule expression (on the Node Stack)
             //  with the resulting OR expression going to *destRules
             //
-            RBBINode  *thisRule    = fNodeStack[fNodeStackPtr];
+                       thisRule    = fNodeStack[fNodeStackPtr];
             RBBINode  *prevRules   = *destRules;
             RBBINode  *orNode      = pushNewNode(RBBINode::opOr);
             if (U_FAILURE(*fRB->fStatus)) {
@@ -374,6 +404,7 @@
         }
         fReverseRule   = FALSE;   // in preparation for the next rule.
         fLookAheadRule = FALSE;
+        fNoChainInRule = FALSE;
         fNodeStackPtr  = 0;
         }
         break;
@@ -532,6 +563,10 @@
                 fRB->fDefaultTree   = &fRB->fSafeRevTree;
             } else if (opt == UNICODE_STRING("lookAheadHardBreak", 18)) {
                 fRB->fLookAheadHardBreak = TRUE;
+            } else if (opt == UNICODE_STRING("quoted_literals_only", 20)) {
+                fRuleSets[kRuleSet_rule_char-128].clear();
+            } else if (opt == UNICODE_STRING("unquoted_literals",  17)) {
+                fRuleSets[kRuleSet_rule_char-128].applyPattern(UnicodeString(gRuleSet_rule_char_pattern), *fRB->fStatus);
             } else {
                 error(U_BRK_UNRECOGNIZED_OPTION);
             }
@@ -791,27 +826,22 @@
 
 //------------------------------------------------------------------------------
 //
-//  stripRules    Return a rules string without unnecessary
-//                characters.
+//  stripRules    Return a rules string without extra spaces.
+//                (Comments are removed separately, during rule parsing.)
 //
 //------------------------------------------------------------------------------
 UnicodeString RBBIRuleScanner::stripRules(const UnicodeString &rules) {
     UnicodeString strippedRules;
-    int rulesLength = rules.length();
-    for (int idx = 0; idx < rulesLength; ) {
-        UChar ch = rules[idx++];
-        if (ch == chPound) {
-            while (idx < rulesLength
-                && ch != chCR && ch != chLF && ch != chNEL)
-            {
-                ch = rules[idx++];
-            }
+    int32_t rulesLength = rules.length();
+
+    for (int32_t idx=0; idx<rulesLength; idx = rules.moveIndex32(idx, 1)) {
+        UChar32 cp = rules.char32At(idx);
+        bool whiteSpace = u_hasBinaryProperty(cp, UCHAR_PATTERN_WHITE_SPACE);
+        if (whiteSpace) {
+            continue;
         }
-        if (!u_isISOControl(ch)) {
-            strippedRules.append(ch);
-        }
+        strippedRules.append(cp);
     }
-    // strippedRules = strippedRules.unescape();
     return strippedRules;
 }
 
@@ -911,6 +941,7 @@
             //  It will be treated as white-space, and serves to break up anything
             //    that might otherwise incorrectly clump together with a comment in
             //    the middle (a variable name, for example.)
+            int32_t commentStart = fScanIndex;
             for (;;) {
                 c.fChar = nextCharLL();
                 if (c.fChar == (UChar32)-1 ||  // EOF
@@ -919,6 +950,9 @@
                     c.fChar == chNEL    ||
                     c.fChar == chLS)       {break;}
             }
+            for (int32_t i=commentStart; i<fNextIndex-1; ++i) {
+                fRB->fStrippedRules.setCharAt(i, u' ');
+            }
         }
         if (c.fChar == (UChar32)-1) {
             return;
@@ -996,7 +1030,7 @@
 
         for (;;) {
             #ifdef RBBI_DEBUG
-                if (fRB->fDebugEnv && uprv_strstr(fRB->fDebugEnv, "scan")) { RBBIDebugPrintf(".");}
+                if (fRB->fDebugEnv && uprv_strstr(fRB->fDebugEnv, "scan")) { RBBIDebugPrintf("."); fflush(stdout);}
             #endif
             if (tableEl->fCharClass < 127 && fC.fEscaped == FALSE &&   tableEl->fCharClass == fC.fChar) {
                 // Table row specified an individual character, not a set, and
@@ -1079,21 +1113,16 @@
 
     }
 
-    //
-    // If there were NO user specified reverse rules, set up the equivalent of ".*;"
-    //
-    if (fRB->fReverseTree == NULL) {
-        fRB->fReverseTree  = pushNewNode(RBBINode::opStar);
-        RBBINode  *operand = pushNewNode(RBBINode::setRef);
-        if (U_FAILURE(*fRB->fStatus)) {
-            return;
-        }
-        findSetFor(UnicodeString(TRUE, kAny, 3), operand);
-        fRB->fReverseTree->fLeftChild = operand;
-        operand->fParent              = fRB->fReverseTree;
-        fNodeStackPtr -= 2;
+    if (U_FAILURE(*fRB->fStatus)) {
+        return;
     }
-
+    
+    // If there are no forward rules set an error.
+    //
+    if (fRB->fForwardTree == NULL) {
+        error(U_BRK_RULE_SYNTAX);
+        return;
+    }
 
     //
     // Parsing of the input RBBI rules is complete.
@@ -1102,16 +1131,15 @@
     //
 #ifdef RBBI_DEBUG
     if (fRB->fDebugEnv && uprv_strstr(fRB->fDebugEnv, "symbols")) {fSymbolTable->rbbiSymtablePrint();}
-    if (fRB->fDebugEnv && uprv_strstr(fRB->fDebugEnv, "ptree"))
-    {
+    if (fRB->fDebugEnv && uprv_strstr(fRB->fDebugEnv, "ptree")) {
         RBBIDebugPrintf("Completed Forward Rules Parse Tree...\n");
-        fRB->fForwardTree->printTree(TRUE);
+        RBBINode::printTree(fRB->fForwardTree, TRUE);
         RBBIDebugPrintf("\nCompleted Reverse Rules Parse Tree...\n");
-        fRB->fReverseTree->printTree(TRUE);
+        RBBINode::printTree(fRB->fReverseTree, TRUE);
         RBBIDebugPrintf("\nCompleted Safe Point Forward Rules Parse Tree...\n");
-        fRB->fSafeFwdTree->printTree(TRUE);
+        RBBINode::printTree(fRB->fSafeFwdTree, TRUE);
         RBBIDebugPrintf("\nCompleted Safe Point Reverse Rules Parse Tree...\n");
-        fRB->fSafeRevTree->printTree(TRUE);
+        RBBINode::printTree(fRB->fSafeRevTree, TRUE);
     }
 #endif
 }
@@ -1126,7 +1154,7 @@
 void RBBIRuleScanner::printNodeStack(const char *title) {
     int i;
     RBBIDebugPrintf("%s.  Dumping node stack...\n", title);
-    for (i=fNodeStackPtr; i>0; i--) {fNodeStack[i]->printTree(TRUE);}
+    for (i=fNodeStackPtr; i>0; i--) {RBBINode::printTree(fNodeStack[i], TRUE);}
 }
 #endif
 
@@ -1143,13 +1171,12 @@
     if (U_FAILURE(*fRB->fStatus)) {
         return NULL;
     }
-    fNodeStackPtr++;
-    if (fNodeStackPtr >= kStackSize) {
-        error(U_BRK_INTERNAL_ERROR);
+    if (fNodeStackPtr >= kStackSize - 1) {
+        error(U_BRK_RULE_SYNTAX);
         RBBIDebugPuts("RBBIRuleScanner::pushNewNode - stack overflow.");
-        *fRB->fStatus = U_BRK_INTERNAL_ERROR;
         return NULL;
     }
+    fNodeStackPtr++;
     fNodeStack[fNodeStackPtr] = new RBBINode(t);
     if (fNodeStack[fNodeStackPtr] == NULL) {
         *fRB->fStatus = U_MEMORY_ALLOCATION_ERROR;
@@ -1249,6 +1276,10 @@
 
 }
 
+int32_t RBBIRuleScanner::numRules() {
+    return fRuleNum;
+}
+
 U_NAMESPACE_END
 
 #endif /* #if !UCONFIG_NO_BREAK_ITERATION */
diff --git a/src/third_party/icu/source/common/rbbiscan.h b/src/third_party/icu/source/common/rbbiscan.h
index dd9b8e6..5802200 100644
--- a/src/third_party/icu/source/common/rbbiscan.h
+++ b/src/third_party/icu/source/common/rbbiscan.h
@@ -1,7 +1,9 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 //
 //  rbbiscan.h
 //
-//  Copyright (C) 2002-2008, International Business Machines Corporation and others.
+//  Copyright (C) 2002-2016, International Business Machines Corporation and others.
 //  All Rights Reserved.
 //
 //  This file contains declarations for class RBBIRuleScanner
@@ -21,9 +23,7 @@
 #include "unicode/symtable.h"// For UnicodeSet parsing, is the interface that
                           //    looks up references to $variables within a set.
 #include "rbbinode.h"
-//#include "rbbitblb.h"
-
-
+#include "rbbirpt.h"
 
 U_NAMESPACE_BEGIN
 
@@ -54,6 +54,7 @@
     struct RBBIRuleChar {
         UChar32             fChar;
         UBool               fEscaped;
+        RBBIRuleChar() : fChar(0), fEscaped(false) {}
     };
 
     RBBIRuleScanner(RBBIRuleBuilder  *rb);
@@ -72,6 +73,8 @@
                                                     //   reverse rules,
                                                     //   and a list of UnicodeSets encountered.
 
+    int32_t     numRules();                         // Return the number of rules that have been seen.
+
     /**
      * Return a rules string without unnecessary
      * characters.
@@ -129,6 +132,8 @@
     UBool                          fLookAheadRule;   // True if the rule includes a '/'
                                                      //   somewhere within it.
 
+    UBool                          fNoChainInRule;   // True if the current rule starts with a '^'.
+
     RBBISymbolTable               *fSymbolTable;     // symbol table, holds definitions of
                                                      //   $variable symbols.
 
diff --git a/src/third_party/icu/source/common/rbbisetb.cpp b/src/third_party/icu/source/common/rbbisetb.cpp
index 9b91c38..29aa35f 100644
--- a/src/third_party/icu/source/common/rbbisetb.cpp
+++ b/src/third_party/icu/source/common/rbbisetb.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 //
 //  rbbisetb.cpp
 //
@@ -17,7 +19,7 @@
 //                      by the RBBI rules.
 //                   -  compute a set of non-overlapping character ranges
 //                      with all characters within a range belonging to the same
-//                      set of input uniocde sets.
+//                      set of input unicode sets.
 //                   -  Derive a set of non-overlapping UnicodeSet (like things)
 //                      that will correspond to columns in the state table for
 //                      the RBBI execution engine.  All characters within one
@@ -32,10 +34,11 @@
 
 #if !UCONFIG_NO_BREAK_ITERATION
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/uniset.h"
-#include "utrie.h"
 #include "uvector.h"
 #include "uassert.h"
 #include "cmemory.h"
@@ -44,45 +47,9 @@
 #include "rbbisetb.h"
 #include "rbbinode.h"
 
-
-//------------------------------------------------------------------------
-//
-//   getFoldedRBBIValue        Call-back function used during building of Trie table.
-//                             Folding value: just store the offset (16 bits)
-//                             if there is any non-0 entry.
-//                             (It'd really be nice if the Trie builder would provide a
-//                             simple default, so this function could go away from here.)
-//
-//------------------------------------------------------------------------
-/* folding value: just store the offset (16 bits) if there is any non-0 entry */
-U_CDECL_BEGIN
-static uint32_t U_CALLCONV
-getFoldedRBBIValue(UNewTrie *trie, UChar32 start, int32_t offset) {
-    uint32_t value;
-    UChar32 limit;
-    UBool inBlockZero;
-
-    limit=start+0x400;
-    while(start<limit) {
-        value=utrie_get32(trie, start, &inBlockZero);
-        if(inBlockZero) {
-            start+=UTRIE_DATA_BLOCK_LENGTH;
-        } else if(value!=0) {
-            return (uint32_t)(offset|0x8000);
-        } else {
-            ++start;
-        }
-    }
-    return 0;
-}
-
-
-U_CDECL_END
-
-
-
 U_NAMESPACE_BEGIN
 
+const int32_t kMaxCharCategoriesFor8BitsTrie = 255;
 //------------------------------------------------------------------------
 //
 //   Constructor
@@ -92,11 +59,12 @@
 {
     fRB             = rb;
     fStatus         = rb->fStatus;
-    fRangeList      = 0;
-    fTrie           = 0;
+    fRangeList      = nullptr;
+    fMutableTrie    = nullptr;
+    fTrie           = nullptr;
     fTrieSize       = 0;
     fGroupCount     = 0;
-    fSawBOF         = FALSE;
+    fSawBOF         = false;
 }
 
 
@@ -116,7 +84,8 @@
         delete r;
     }
 
-    utrie_close(fTrie);
+    ucptrie_close(fTrie);
+    umutablecptrie_close(fMutableTrie);
 }
 
 
@@ -128,7 +97,7 @@
 //                  from the Unicode Sets.
 //
 //------------------------------------------------------------------------
-void RBBISetBuilder::build() {
+void RBBISetBuilder::buildRanges() {
     RBBINode        *usetNode;
     RangeDescriptor *rlRange;
 
@@ -231,25 +200,48 @@
     //
     //    Numbering: # 0  (state table column 0) is unused.
     //               # 1  is reserved - table column 1 is for end-of-input
-    //               # 2  is reserved - table column 2 is for beginning-in-input
+    //               # 2  is reserved - table column 2 is for beginning-of-input
     //               # 3  is the first range list.
     //
     RangeDescriptor *rlSearchRange;
-    for (rlRange = fRangeList; rlRange!=0; rlRange=rlRange->fNext) {
+    int32_t dictGroupCount = 0;
+
+    for (rlRange = fRangeList; rlRange!=nullptr; rlRange=rlRange->fNext) {
         for (rlSearchRange=fRangeList; rlSearchRange != rlRange; rlSearchRange=rlSearchRange->fNext) {
             if (rlRange->fIncludesSets->equals(*rlSearchRange->fIncludesSets)) {
                 rlRange->fNum = rlSearchRange->fNum;
+                rlRange->fIncludesDict = rlSearchRange->fIncludesDict;
                 break;
             }
         }
         if (rlRange->fNum == 0) {
-            fGroupCount ++;
-            rlRange->fNum = fGroupCount+2; 
-            rlRange->setDictionaryFlag();
-            addValToSets(rlRange->fIncludesSets, fGroupCount+2);
+            rlRange->fFirstInGroup = true;
+            if (rlRange->isDictionaryRange()) {
+                rlRange->fNum = ++dictGroupCount;
+                rlRange->fIncludesDict = true;
+            } else {
+                fGroupCount++;
+                rlRange->fNum = fGroupCount+2;
+                addValToSets(rlRange->fIncludesSets, rlRange->fNum);
+            }
         }
     }
 
+    // Move the character category numbers for any dictionary ranges up, so that they
+    // immediately follow the non-dictionary ranges.
+
+    fDictCategoriesStart = fGroupCount + 3;
+    for (rlRange = fRangeList; rlRange!=nullptr; rlRange=rlRange->fNext) {
+        if (rlRange->fIncludesDict) {
+            rlRange->fNum += fDictCategoriesStart - 1;
+            if (rlRange->fFirstInGroup) {
+                addValToSets(rlRange->fIncludesSets, rlRange->fNum);
+            }
+        }
+    }
+    fGroupCount += dictGroupCount;
+
+
     // Handle input sets that contain the special string {eof}.
     //   Column 1 of the state table is reserved for EOF on input.
     //   Column 2 is reserved for before-the-start-input.
@@ -257,13 +249,11 @@
     //             references to {bof}.)
     //   Add this column value (1 or 2) to the equivalent expression
     //     subtree for each UnicodeSet that contains the string {eof}
-    //   Because {bof} and {eof} are not a characters in the normal sense,
-    //   they doesn't affect the computation of ranges or TRIE.
-    static const UChar eofUString[] = {0x65, 0x6f, 0x66, 0};
-    static const UChar bofUString[] = {0x62, 0x6f, 0x66, 0};
+    //   Because {bof} and {eof} are not characters in the normal sense,
+    //   they don't affect the computation of the ranges or TRIE.
 
-    UnicodeString eofString(eofUString);
-    UnicodeString bofString(bofUString);
+    UnicodeString eofString(u"eof");
+    UnicodeString bofString(u"bof");
     for (ni=0; ; ni++) {        // Loop over each of the UnicodeSets encountered in the input rules
         usetNode = (RBBINode *)this->fRB->fUSetNodes->elementAt(ni);
         if (usetNode==NULL) {
@@ -282,39 +272,71 @@
 
     if (fRB->fDebugEnv && uprv_strstr(fRB->fDebugEnv, "rgroup")) {printRangeGroups();}
     if (fRB->fDebugEnv && uprv_strstr(fRB->fDebugEnv, "esets")) {printSets();}
-
-    //
-    // Build the Trie table for mapping UChar32 values to the corresponding
-    //   range group number
-    //
-    fTrie = utrie_open(NULL,    //  Pre-existing trie to be filled in
-                      NULL,    //  Data array  (utrie will allocate one)
-                      100000,  //  Max Data Length
-                      0,       //  Initial value for all code points
-                      0,       //  Lead surrogate unit value
-                      TRUE);   //  Keep Latin 1 in separately
+}
 
 
-    for (rlRange = fRangeList; rlRange!=0; rlRange=rlRange->fNext) {
-        utrie_setRange32(fTrie, rlRange->fStartChar, rlRange->fEndChar+1, rlRange->fNum, TRUE);
+//
+// Build the Trie table for mapping UChar32 values to the corresponding
+// range group number.
+//
+void RBBISetBuilder::buildTrie() {
+    fMutableTrie = umutablecptrie_open(
+                        0,       //  Initial value for all code points.
+                        0,       //  Error value for out-of-range input.
+                        fStatus);
+
+    for (RangeDescriptor *range = fRangeList; range!=nullptr && U_SUCCESS(*fStatus); range=range->fNext) {
+        umutablecptrie_setRange(fMutableTrie,
+                                range->fStartChar,     // Range start
+                                range->fEndChar,       // Range end (inclusive)
+                                range->fNum,           // value for range
+                                fStatus);
     }
 }
 
 
+void RBBISetBuilder::mergeCategories(IntPair categories) {
+    U_ASSERT(categories.first >= 1);
+    U_ASSERT(categories.second > categories.first);
+    U_ASSERT((categories.first <  fDictCategoriesStart && categories.second <  fDictCategoriesStart) ||
+             (categories.first >= fDictCategoriesStart && categories.second >= fDictCategoriesStart));
+
+    for (RangeDescriptor *rd = fRangeList; rd != nullptr; rd = rd->fNext) {
+        int32_t rangeNum = rd->fNum;
+        if (rangeNum == categories.second) {
+            rd->fNum = categories.first;
+        } else if (rangeNum > categories.second) {
+            rd->fNum--;
+        }
+    }
+    --fGroupCount;
+    if (categories.second <= fDictCategoriesStart) {
+        --fDictCategoriesStart;
+    }
+}
+
 
 //-----------------------------------------------------------------------------------
 //
 //  getTrieSize()    Return the size that will be required to serialize the Trie.
 //
 //-----------------------------------------------------------------------------------
-int32_t RBBISetBuilder::getTrieSize() /*const*/ {
-    fTrieSize  = utrie_serialize(fTrie,
-                                    NULL,                // Buffer
-                                    0,                   // Capacity
-                                    getFoldedRBBIValue,
-                                    TRUE,                // Reduce to 16 bits
-                                    fStatus);
-    // RBBIDebugPrintf("Trie table size is %d\n", trieSize);
+int32_t RBBISetBuilder::getTrieSize()  {
+    if (U_FAILURE(*fStatus)) {
+        return 0;
+    }
+    if (fTrie == nullptr) {
+        bool use8Bits = getNumCharCategories() <= kMaxCharCategoriesFor8BitsTrie;
+        fTrie = umutablecptrie_buildImmutable(
+            fMutableTrie,
+            UCPTRIE_TYPE_FAST,
+            use8Bits ? UCPTRIE_VALUE_BITS_8 : UCPTRIE_VALUE_BITS_16,
+            fStatus);
+        fTrieSize = ucptrie_toBinary(fTrie, nullptr, 0, fStatus);
+        if (*fStatus == U_BUFFER_OVERFLOW_ERROR) {
+            *fStatus = U_ZERO_ERROR;
+        }
+    }
     return fTrieSize;
 }
 
@@ -327,12 +349,10 @@
 //
 //-----------------------------------------------------------------------------------
 void RBBISetBuilder::serializeTrie(uint8_t *where) {
-    utrie_serialize(fTrie,
-                    where,                   // Buffer
-                    fTrieSize,               // Capacity
-                    getFoldedRBBIValue,
-                    TRUE,                    // Reduce to 16 bits
-                    fStatus);
+    ucptrie_toBinary(fTrie,
+                     where,                // Buffer
+                     fTrieSize,            // Capacity
+                     fStatus);
 }
 
 //------------------------------------------------------------------------
@@ -399,6 +419,16 @@
 
 //------------------------------------------------------------------------
 //
+//   getDictCategoriesStart
+//
+//------------------------------------------------------------------------
+int32_t  RBBISetBuilder::getDictCategoriesStart() const {
+    return fDictCategoriesStart;
+}
+
+
+//------------------------------------------------------------------------
+//
 //   sawBOF
 //
 //------------------------------------------------------------------------
@@ -416,7 +446,7 @@
 UChar32  RBBISetBuilder::getFirstChar(int32_t category) const {
     RangeDescriptor   *rlRange;
     UChar32            retVal = (UChar32)-1;
-    for (rlRange = fRangeList; rlRange!=0; rlRange=rlRange->fNext) {
+    for (rlRange = fRangeList; rlRange!=nullptr; rlRange=rlRange->fNext) {
         if (rlRange->fNum == category) {
             retVal = rlRange->fStartChar;
             break;
@@ -426,7 +456,6 @@
 }
 
 
-
 //------------------------------------------------------------------------
 //
 //   printRanges        A debugging function.
@@ -439,16 +468,16 @@
     int                    i;
 
     RBBIDebugPrintf("\n\n Nonoverlapping Ranges ...\n");
-    for (rlRange = fRangeList; rlRange!=0; rlRange=rlRange->fNext) {
-        RBBIDebugPrintf("%2i  %4x-%4x  ", rlRange->fNum, rlRange->fStartChar, rlRange->fEndChar);
+    for (rlRange = fRangeList; rlRange!=nullptr; rlRange=rlRange->fNext) {
+        RBBIDebugPrintf("%4x-%4x  ", rlRange->fStartChar, rlRange->fEndChar);
 
         for (i=0; i<rlRange->fIncludesSets->size(); i++) {
             RBBINode       *usetNode    = (RBBINode *)rlRange->fIncludesSets->elementAt(i);
-            UnicodeString   setName = UNICODE_STRING("anon", 4);
+            UnicodeString   setName {u"anon"};
             RBBINode       *setRef = usetNode->fParent;
-            if (setRef != NULL) {
+            if (setRef != nullptr) {
                 RBBINode *varRef = setRef->fParent;
-                if (varRef != NULL  &&  varRef->fType == RBBINode::varRef) {
+                if (varRef != nullptr  &&  varRef->fType == RBBINode::varRef) {
                     setName = varRef->fText;
                 }
             }
@@ -468,19 +497,15 @@
 //------------------------------------------------------------------------
 #ifdef RBBI_DEBUG
 void RBBISetBuilder::printRangeGroups() {
-    RangeDescriptor       *rlRange;
-    RangeDescriptor       *tRange;
     int                    i;
-    int                    lastPrintedGroupNum = 0;
 
     RBBIDebugPrintf("\nRanges grouped by Unicode Set Membership...\n");
-    for (rlRange = fRangeList; rlRange!=0; rlRange=rlRange->fNext) {
-        int groupNum = rlRange->fNum & 0xbfff;
-        if (groupNum > lastPrintedGroupNum) {
-            lastPrintedGroupNum = groupNum;
+    for (RangeDescriptor *rlRange = fRangeList; rlRange!=nullptr; rlRange=rlRange->fNext) {
+        if (rlRange->fFirstInGroup) {
+            int groupNum = rlRange->fNum;
             RBBIDebugPrintf("%2i  ", groupNum);
 
-            if (rlRange->fNum & 0x4000) { RBBIDebugPrintf(" <DICT> ");}
+            if (groupNum >= fDictCategoriesStart) { RBBIDebugPrintf(" <DICT> ");}
 
             for (i=0; i<rlRange->fIncludesSets->size(); i++) {
                 RBBINode       *usetNode    = (RBBINode *)rlRange->fIncludesSets->elementAt(i);
@@ -496,7 +521,7 @@
             }
 
             i = 0;
-            for (tRange = rlRange; tRange != 0; tRange = tRange->fNext) {
+            for (RangeDescriptor *tRange = rlRange; tRange != nullptr; tRange = tRange->fNext) {
                 if (tRange->fNum == rlRange->fNum) {
                     if (i++ % 5 == 0) {
                         RBBIDebugPrintf("\n    ");
@@ -548,7 +573,7 @@
         RBBI_DEBUG_printUnicodeString(usetNode->fText);
         RBBIDebugPrintf("\n");
         if (usetNode->fLeftChild != NULL) {
-            usetNode->fLeftChild->printTree(TRUE);
+            RBBINode::printTree(usetNode->fLeftChild, TRUE);
         }
     }
     RBBIDebugPrintf("\n");
@@ -563,28 +588,22 @@
 //
 //-------------------------------------------------------------------------------------
 
-RangeDescriptor::RangeDescriptor(const RangeDescriptor &other, UErrorCode &status) {
-    int  i;
+RangeDescriptor::RangeDescriptor(const RangeDescriptor &other, UErrorCode &status) :
+        fStartChar(other.fStartChar), fEndChar {other.fEndChar}, fNum {other.fNum},
+        fIncludesDict{other.fIncludesDict}, fFirstInGroup{other.fFirstInGroup} {
 
-    this->fStartChar    = other.fStartChar;
-    this->fEndChar      = other.fEndChar;
-    this->fNum          = other.fNum;
-    this->fNext         = NULL;
-    UErrorCode oldstatus = status;
-    this->fIncludesSets = new UVector(status);
-    if (U_FAILURE(oldstatus)) {
-        status = oldstatus;
+    if (U_FAILURE(status)) {
+        return;
+    }
+    fIncludesSets = new UVector(status);
+    if (this->fIncludesSets == nullptr) {
+        status = U_MEMORY_ALLOCATION_ERROR;
     }
     if (U_FAILURE(status)) {
         return;
     }
-    /* test for NULL */
-    if (this->fIncludesSets == 0) {
-        status = U_MEMORY_ALLOCATION_ERROR;
-        return;
-    }
 
-    for (i=0; i<other.fIncludesSets->size(); i++) {
+    for (int32_t i=0; i<other.fIncludesSets->size(); i++) {
         this->fIncludesSets->addElement(other.fIncludesSets->elementAt(i), status);
     }
 }
@@ -596,24 +615,13 @@
 //
 //-------------------------------------------------------------------------------------
 RangeDescriptor::RangeDescriptor(UErrorCode &status) {
-    this->fStartChar    = 0;
-    this->fEndChar      = 0;
-    this->fNum          = 0;
-    this->fNext         = NULL;
-    UErrorCode oldstatus = status;
-    this->fIncludesSets = new UVector(status);
-    if (U_FAILURE(oldstatus)) {
-        status = oldstatus;
-    }
     if (U_FAILURE(status)) {
         return;
     }
-    /* test for NULL */
-    if(this->fIncludesSets == 0) {
+    fIncludesSets = new UVector(status);
+    if (fIncludesSets == nullptr) {
         status = U_MEMORY_ALLOCATION_ERROR;
-        return;
     }
-
 }
 
 
@@ -624,7 +632,7 @@
 //-------------------------------------------------------------------------------------
 RangeDescriptor::~RangeDescriptor() {
     delete  fIncludesSets;
-    fIncludesSets = NULL;
+    fIncludesSets = nullptr;
 }
 
 //-------------------------------------------------------------------------------------
@@ -635,7 +643,7 @@
 void RangeDescriptor::split(UChar32 where, UErrorCode &status) {
     U_ASSERT(where>fStartChar && where<=fEndChar);
     RangeDescriptor *nr = new RangeDescriptor(*this, status);
-    if(nr == 0) {
+    if(nr == nullptr) {
         status = U_MEMORY_ALLOCATION_ERROR;
         return;
     }
@@ -654,44 +662,37 @@
 
 //-------------------------------------------------------------------------------------
 //
-//   RangeDescriptor::setDictionaryFlag
+//   RangeDescriptor::isDictionaryRange
 //
-//            Character Category Numbers that include characters from
-//            the original Unicode Set named "dictionary" have bit 14
-//            set to 1.  The RBBI runtime engine uses this to trigger
-//            use of the word dictionary.
+//            Test whether this range includes characters from
+//            the original Unicode Set named "dictionary".
 //
-//            This function looks through the Unicode Sets that it
-//            (the range) includes, and sets the bit in fNum when
-//            "dictionary" is among them.
+//            This function looks through the Unicode Sets that
+//            the range includes, checking for one named "dictionary"
 //
 //            TODO:  a faster way would be to find the set node for
 //                   "dictionary" just once, rather than looking it
 //                   up by name every time.
 //
 //-------------------------------------------------------------------------------------
-void RangeDescriptor::setDictionaryFlag() {
-    int i;
-
-    for (i=0; i<this->fIncludesSets->size(); i++) {
-        RBBINode       *usetNode    = (RBBINode *)fIncludesSets->elementAt(i);
-        UnicodeString   setName;
-        RBBINode       *setRef = usetNode->fParent;
-        if (setRef != NULL) {
+bool RangeDescriptor::isDictionaryRange() {
+    static const char16_t *dictionary = u"dictionary";
+    for (int32_t i=0; i<fIncludesSets->size(); i++) {
+        RBBINode *usetNode  = (RBBINode *)fIncludesSets->elementAt(i);
+        RBBINode *setRef = usetNode->fParent;
+        if (setRef != nullptr) {
             RBBINode *varRef = setRef->fParent;
-            if (varRef != NULL  &&  varRef->fType == RBBINode::varRef) {
-                setName = varRef->fText;
+            if (varRef && varRef->fType == RBBINode::varRef) {
+                const UnicodeString *setName = &varRef->fText;
+                if (setName->compare(dictionary, -1) == 0) {
+                    return true;
+                }
             }
         }
-        if (setName.compare(UNICODE_STRING("dictionary", 10)) == 0) {   // TODO:  no string literals.
-            this->fNum |= 0x4000;
-            break;
-        }
     }
+    return false;
 }
 
-
-
 U_NAMESPACE_END
 
 #endif /* #if !UCONFIG_NO_BREAK_ITERATION */
diff --git a/src/third_party/icu/source/common/rbbisetb.h b/src/third_party/icu/source/common/rbbisetb.h
index c8bc1df..6409a4e 100644
--- a/src/third_party/icu/source/common/rbbisetb.h
+++ b/src/third_party/icu/source/common/rbbisetb.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 //
 //  rbbisetb.h
 /*
@@ -11,12 +13,15 @@
 #define RBBISETB_H
 
 #include "unicode/utypes.h"
+
+#if !UCONFIG_NO_BREAK_ITERATION
+
+#include "unicode/ucptrie.h"
+#include "unicode/umutablecptrie.h"
 #include "unicode/uobject.h"
 #include "rbbirb.h"
 #include "uvector.h"
 
-struct  UNewTrie;
-
 U_NAMESPACE_BEGIN
 
 //
@@ -36,25 +41,26 @@
 //
 class RangeDescriptor : public UMemory {
 public:
-    UChar32            fStartChar;      // Start of range, unicode 32 bit value.
-    UChar32            fEndChar;        // End of range, unicode 32 bit value.
-    int32_t            fNum;            // runtime-mapped input value for this range.
-    UVector           *fIncludesSets;   // vector of the the original
-                                        //   Unicode sets that include this range.
-                                        //    (Contains ptrs to uset nodes)
-    RangeDescriptor   *fNext;           // Next RangeDescriptor in the linked list.
+    UChar32            fStartChar {};            // Start of range, unicode 32 bit value.
+    UChar32            fEndChar {};              // End of range, unicode 32 bit value.
+    int32_t            fNum {0};                 // runtime-mapped input value for this range.
+    bool               fIncludesDict {false};    // True if the range includes $dictionary.
+    bool               fFirstInGroup {false};    // True if first range in a group with the same fNum.
+    UVector           *fIncludesSets {nullptr};  // vector of the the original
+                                                 //   Unicode sets that include this range.
+                                                 //    (Contains ptrs to uset nodes)
+    RangeDescriptor   *fNext {nullptr};          // Next RangeDescriptor in the linked list.
 
     RangeDescriptor(UErrorCode &status);
     RangeDescriptor(const RangeDescriptor &other, UErrorCode &status);
     ~RangeDescriptor();
     void split(UChar32 where, UErrorCode &status);   // Spit this range in two at "where", with
                                         //   where appearing in the second (higher) part.
-    void setDictionaryFlag();           // Check whether this range appears as part of
+    bool isDictionaryRange();           // Check whether this range appears as part of
                                         //   the Unicode set named "dictionary"
 
-private:
-    RangeDescriptor(const RangeDescriptor &other); // forbid copying of this class
-    RangeDescriptor &operator=(const RangeDescriptor &other); // forbid copying of this class
+    RangeDescriptor(const RangeDescriptor &other) = delete; // forbid default copying of this class
+    RangeDescriptor &operator=(const RangeDescriptor &other) = delete; // forbid assigning of this class
 };
 
 
@@ -78,17 +84,27 @@
     RBBISetBuilder(RBBIRuleBuilder *rb);
     ~RBBISetBuilder();
 
-    void     build();
+    void     buildRanges();
+    void     buildTrie();
     void     addValToSets(UVector *sets,      uint32_t val);
     void     addValToSet (RBBINode *usetNode, uint32_t val);
     int32_t  getNumCharCategories() const;   // CharCategories are the same as input symbol set to the
                                              //    runtime state machine, which are the same as
                                              //    columns in the DFA state table
+    int32_t  getDictCategoriesStart() const; // First char category that includes $dictionary, or
+                                             // last category + 1 if there are no dictionary categories.
     int32_t  getTrieSize() /*const*/;        // Size in bytes of the serialized Trie.
     void     serializeTrie(uint8_t *where);  // write out the serialized Trie.
     UChar32  getFirstChar(int32_t  val) const;
     UBool    sawBOF() const;                 // Indicate whether any references to the {bof} pseudo
                                              //   character were encountered.
+    /**
+     * Merge two character categories that have been identified as having equivalent behavior.
+     * The ranges belonging to the second category (table column) will be added to the first.
+     * @param categories the pair of categories to be merged.
+     */
+    void     mergeCategories(IntPair categories);
+
 #ifdef RBBI_DEBUG
     void     printSets();
     void     printRanges();
@@ -100,24 +116,22 @@
 #endif
 
 private:
-    void           numberSets();
-
     RBBIRuleBuilder       *fRB;             // The RBBI Rule Compiler that owns us.
     UErrorCode            *fStatus;
 
     RangeDescriptor       *fRangeList;      // Head of the linked list of RangeDescriptors
 
-    UNewTrie              *fTrie;           // The mapping TRIE that is the end result of processing
-    uint32_t              fTrieSize;        //  the Unicode Sets.
+    UMutableCPTrie        *fMutableTrie;    // The mapping TRIE that is the end result of processing
+    UCPTrie               *fTrie;           //  the Unicode Sets.
+    uint32_t               fTrieSize;
 
-    // Groups correspond to character categories -
-    //       groups of ranges that are in the same original UnicodeSets.
-    //       fGroupCount is the index of the last used group.
-    //       fGroupCount+1 is also the number of columns in the RBBI state table being compiled.
-    //       State table column 0 is not used.  Column 1 is for end-of-input.
-    //       column 2 is for group 0.  Funny counting.
+    // Number of range groups, which are groups of ranges that are in the same original UnicodeSets.
     int32_t               fGroupCount;
 
+    // The number of the first dictionary char category.
+    // If there are no Dictionary categories, set to the last category + 1.
+    int32_t               fDictCategoriesStart;
+
     UBool                 fSawBOF;
 
     RBBISetBuilder(const RBBISetBuilder &other); // forbid copying of this class
@@ -127,4 +141,7 @@
 
 
 U_NAMESPACE_END
+
+#endif /* #if !UCONFIG_NO_BREAK_ITERATION */
+
 #endif
diff --git a/src/third_party/icu/source/common/rbbistbl.cpp b/src/third_party/icu/source/common/rbbistbl.cpp
index 8207baa..e049e49 100644
--- a/src/third_party/icu/source/common/rbbistbl.cpp
+++ b/src/third_party/icu/source/common/rbbistbl.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 //
 //  file:  rbbistbl.cpp    Implementation of the ICU RBBISymbolTable class
 //
@@ -12,16 +14,18 @@
 
 #if !UCONFIG_NO_BREAK_ITERATION
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/unistr.h"
 #include "unicode/uniset.h"
 #include "unicode/uchar.h"
 #include "unicode/parsepos.h"
 
-#include "umutex.h"
-
-#include "rbbirb.h"
+#include "cstr.h"
 #include "rbbinode.h"
+#include "rbbirb.h"
+#include "umutex.h"
 
 
 //
@@ -227,9 +231,9 @@
 //
 #ifdef RBBI_DEBUG
 void RBBISymbolTable::rbbiSymtablePrint() const {
-    RBBIDebugPrintf("Variable Definitions\n"
-           "Name               Node Val     String Val\n"
-           "----------------------------------------------------------------------\n");
+    RBBIDebugPrintf("Variable Definitions Symbol Table\n"
+           "Name                  Node         serial  String Val\n"
+           "-------------------------------------------------------------------\n");
 
     int32_t pos = UHASH_FIRST;
     const UHashElement  *e   = NULL;
@@ -240,10 +244,8 @@
         }
         RBBISymbolTableEntry  *s   = (RBBISymbolTableEntry *)e->value.pointer;
 
-        RBBI_DEBUG_printUnicodeString(s->key, 15);
-        RBBIDebugPrintf("   %8p   ", (void *)s->val);
-        RBBI_DEBUG_printUnicodeString(s->val->fLeftChild->fText);
-        RBBIDebugPrintf("\n");
+        RBBIDebugPrintf("%-19s   %8p %7d ", CStr(s->key)(), (void *)s->val, s->val->fSerialNum);
+        RBBIDebugPrintf(" %s\n", CStr(s->val->fLeftChild->fText)());
     }
 
     RBBIDebugPrintf("\nParsed Variable Definitions\n");
@@ -254,8 +256,9 @@
             break;
         }
         RBBISymbolTableEntry  *s   = (RBBISymbolTableEntry *)e->value.pointer;
-        RBBI_DEBUG_printUnicodeString(s->key);
-        s->val->fLeftChild->printTree(TRUE);
+        RBBIDebugPrintf("%s\n", CStr(s->key)());
+        RBBINode::printTree(s->val, TRUE);
+        RBBINode::printTree(s->val->fLeftChild, FALSE);
         RBBIDebugPrintf("\n");
     }
 }
diff --git a/src/third_party/icu/source/common/rbbitblb.cpp b/src/third_party/icu/source/common/rbbitblb.cpp
index 039836d..9fe1eca 100644
--- a/src/third_party/icu/source/common/rbbitblb.cpp
+++ b/src/third_party/icu/source/common/rbbitblb.cpp
@@ -1,6 +1,8 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
-*   Copyright (c) 2002-2009, International Business Machines
+*   Copyright (c) 2002-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 **********************************************************************
 */
@@ -13,34 +15,38 @@
 
 #if !UCONFIG_NO_BREAK_ITERATION
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/unistr.h"
 #include "rbbitblb.h"
 #include "rbbirb.h"
+#include "rbbiscan.h"
 #include "rbbisetb.h"
 #include "rbbidata.h"
 #include "cstring.h"
 #include "uassert.h"
+#include "uvectr32.h"
 #include "cmemory.h"
 
 U_NAMESPACE_BEGIN
 
-RBBITableBuilder::RBBITableBuilder(RBBIRuleBuilder *rb, RBBINode **rootNode) :
- fTree(*rootNode) {
-    fRB                 = rb;
-    fStatus             = fRB->fStatus;
-    UErrorCode status   = U_ZERO_ERROR;
-    fDStates            = new UVector(status);
-    if (U_FAILURE(*fStatus)) {
-        return;
-    }
+const int32_t kMaxStateFor8BitsTable = 255;
+
+RBBITableBuilder::RBBITableBuilder(RBBIRuleBuilder *rb, RBBINode **rootNode, UErrorCode &status) :
+        fRB(rb),
+        fTree(*rootNode),
+        fStatus(&status),
+        fDStates(nullptr),
+        fSafeTable(nullptr) {
     if (U_FAILURE(status)) {
-        *fStatus = status;
         return;
     }
-    if (fDStates == NULL) {
-        *fStatus = U_MEMORY_ALLOCATION_ERROR;;
+    // fDStates is UVector<RBBIStateDescriptor *>
+    fDStates = new UVector(status);
+    if (U_SUCCESS(status) && fDStates == nullptr ) {
+        status = U_MEMORY_ALLOCATION_ERROR;
     }
 }
 
@@ -51,17 +57,19 @@
     for (i=0; i<fDStates->size(); i++) {
         delete (RBBIStateDescriptor *)fDStates->elementAt(i);
     }
-    delete   fDStates;
+    delete fDStates;
+    delete fSafeTable;
+    delete fLookAheadRuleMap;
 }
 
 
 //-----------------------------------------------------------------------------
 //
-//   RBBITableBuilder::build  -  This is the main function for building the DFA state transtion
-//                               table from the RBBI rules parse tree.
+//   RBBITableBuilder::buildForwardTable  -  This is the main function for building
+//                               the DFA state transition table from the RBBI rules parse tree.
 //
 //-----------------------------------------------------------------------------
-void  RBBITableBuilder::build() {
+void  RBBITableBuilder::buildForwardTable() {
 
     if (U_FAILURE(*fStatus)) {
         return;
@@ -80,8 +88,8 @@
     fTree = fTree->flattenVariables();
 #ifdef RBBI_DEBUG
     if (fRB->fDebugEnv && uprv_strstr(fRB->fDebugEnv, "ftree")) {
-        RBBIDebugPuts("Parse tree after flattening variable references.");
-        fTree->printTree(TRUE);
+        RBBIDebugPuts("\nParse tree after flattening variable references.");
+        RBBINode::printTree(fTree, TRUE);
     }
 #endif
 
@@ -121,7 +129,7 @@
     }
     cn->fLeftChild = fTree;
     fTree->fParent = cn;
-    cn->fRightChild = new RBBINode(RBBINode::endMark);
+    RBBINode *endMarkerNode = cn->fRightChild = new RBBINode(RBBINode::endMark);
     // Delete and exit if memory allocation failed.
     if (cn->fRightChild == NULL) {
         *fStatus = U_MEMORY_ALLOCATION_ERROR;
@@ -138,8 +146,8 @@
     fTree->flattenSets();
 #ifdef RBBI_DEBUG
     if (fRB->fDebugEnv && uprv_strstr(fRB->fDebugEnv, "stree")) {
-        RBBIDebugPuts("Parse tree after flattening Unicode Set references.");
-        fTree->printTree(TRUE);
+        RBBIDebugPuts("\nParse tree after flattening Unicode Set references.");
+        RBBINode::printTree(fTree, TRUE);
     }
 #endif
 
@@ -164,7 +172,7 @@
     //  For "chained" rules, modify the followPos sets
     //
     if (fRB->fChainRules) {
-        calcChainedFollowPos(fTree);
+        calcChainedFollowPos(fTree, endMarkerNode);
     }
 
     //
@@ -178,6 +186,7 @@
     // Build the DFA state transition tables.
     //
     buildStateTable();
+    mapLookAheadRules();
     flagAcceptingStates();
     flagLookAheadStates();
     flagTaggedStates();
@@ -188,8 +197,6 @@
     //    for all tables.  Merge the ones from this table into the global set.
     //
     mergeRuleStatusVals();
-
-    if (fRB->fDebugEnv && uprv_strstr(fRB->fDebugEnv, "states")) {printStates();};
 }
 
 
@@ -377,6 +384,25 @@
 
 }
 
+//-----------------------------------------------------------------------------
+//
+//    addRuleRootNodes    Recursively walk a parse tree, adding all nodes flagged
+//                        as roots of a rule to a destination vector.
+//
+//-----------------------------------------------------------------------------
+void RBBITableBuilder::addRuleRootNodes(UVector *dest, RBBINode *node) {
+    if (node == NULL || U_FAILURE(*fStatus)) {
+        return;
+    }
+    if (node->fRuleRoot) {
+        dest->addElement(node, *fStatus);
+        // Note: rules cannot nest. If we found a rule start node,
+        //       no child node can also be a start node.
+        return;
+    }
+    addRuleRootNodes(dest, node->fLeftChild);
+    addRuleRootNodes(dest, node->fRightChild);
+}
 
 //-----------------------------------------------------------------------------
 //
@@ -384,64 +410,61 @@
 //                            to implement rule chaining.  NOT described by Aho
 //
 //-----------------------------------------------------------------------------
-void RBBITableBuilder::calcChainedFollowPos(RBBINode *tree) {
+void RBBITableBuilder::calcChainedFollowPos(RBBINode *tree, RBBINode *endMarkNode) {
 
-    UVector         endMarkerNodes(*fStatus);
     UVector         leafNodes(*fStatus);
-    int32_t         i;
-
     if (U_FAILURE(*fStatus)) {
         return;
     }
 
-    // get a list of all endmarker nodes.
-    tree->findNodes(&endMarkerNodes, RBBINode::endMark, *fStatus);
-
     // get a list all leaf nodes
     tree->findNodes(&leafNodes, RBBINode::leafChar, *fStatus);
     if (U_FAILURE(*fStatus)) {
         return;
     }
 
-    // Get all nodes that can be the start a match, which is FirstPosition()
-    // of the portion of the tree corresponding to user-written rules.
-    // See the tree description in bofFixup().
-    RBBINode *userRuleRoot = tree;
-    if (fRB->fSetBuilder->sawBOF()) {
-        userRuleRoot = tree->fLeftChild->fRightChild;
+    // Collect all leaf nodes that can start matches for rules
+    // with inbound chaining enabled, which is the union of the 
+    // firstPosition sets from each of the rule root nodes.
+    
+    UVector ruleRootNodes(*fStatus);
+    addRuleRootNodes(&ruleRootNodes, tree);
+
+    UVector matchStartNodes(*fStatus);
+    for (int j=0; j<ruleRootNodes.size(); ++j) {
+        RBBINode *node = static_cast<RBBINode *>(ruleRootNodes.elementAt(j));
+        if (node->fChainIn) {
+            setAdd(&matchStartNodes, node->fFirstPosSet);
+        }
     }
-    U_ASSERT(userRuleRoot != NULL);
-    UVector *matchStartNodes = userRuleRoot->fFirstPosSet;
+    if (U_FAILURE(*fStatus)) {
+        return;
+    }
 
-
-    // Iteratate over all leaf nodes,
-    //
     int32_t  endNodeIx;
     int32_t  startNodeIx;
 
     for (endNodeIx=0; endNodeIx<leafNodes.size(); endNodeIx++) {
-        RBBINode *tNode   = (RBBINode *)leafNodes.elementAt(endNodeIx);
-        RBBINode *endNode = NULL;
+        RBBINode *endNode   = (RBBINode *)leafNodes.elementAt(endNodeIx);
 
         // Identify leaf nodes that correspond to overall rule match positions.
-        //   These include an endMarkerNode in their followPos sets.
-        for (i=0; i<endMarkerNodes.size(); i++) {
-            if (tNode->fFollowPos->contains(endMarkerNodes.elementAt(i))) {
-                endNode = tNode;
-                break;
-            }
-        }
-        if (endNode == NULL) {
-            // node wasn't an end node.  Try again with the next.
+        // These include the endMarkNode in their followPos sets.
+        //
+        // Note: do not consider other end marker nodes, those that are added to
+        //       look-ahead rules. These can't chain; a match immediately stops
+        //       further matching. This leaves exactly one end marker node, the one
+        //       at the end of the complete tree.
+
+        if (!endNode->fFollowPos->contains(endMarkNode)) {
             continue;
         }
 
         // We've got a node that can end a match.
 
-        // Line Break Specific hack:  If this node's val correspond to the $CM char class,
-        //                            don't chain from it.
-        // TODO:  Add rule syntax for this behavior, get specifics out of here and
-        //        into the rule file.
+        // !!LBCMNoChain implementation:  If this node's val correspond to
+        // the Line Break $CM char class, don't chain from it.
+        // TODO:  Remove this. !!LBCMNoChain is deprecated, and is not used
+        //        by any of the standard ICU rules.
         if (fRB->fLBCMNoChain) {
             UChar32 c = this->fRB->fSetBuilder->getFirstChar(endNode->fVal);
             if (c != -1) {
@@ -453,12 +476,11 @@
             }
         }
 
-
         // Now iterate over the nodes that can start a match, looking for ones
         //   with the same char class as our ending node.
         RBBINode *startNode;
-        for (startNodeIx = 0; startNodeIx<matchStartNodes->size(); startNodeIx++) {
-            startNode = (RBBINode *)matchStartNodes->elementAt(startNodeIx);
+        for (startNodeIx = 0; startNodeIx<matchStartNodes.size(); startNodeIx++) {
+            startNode = (RBBINode *)matchStartNodes.elementAt(startNodeIx);
             if (startNode->fType != RBBINode::leafChar) {
                 continue;
             }
@@ -683,6 +705,76 @@
 }
 
 
+/**
+ * mapLookAheadRules
+ *
+ */
+void RBBITableBuilder::mapLookAheadRules() {
+    fLookAheadRuleMap =  new UVector32(fRB->fScanner->numRules() + 1, *fStatus);
+    if (fLookAheadRuleMap == nullptr) {
+        *fStatus = U_MEMORY_ALLOCATION_ERROR;
+    }
+    if (U_FAILURE(*fStatus)) {
+        return;
+    }
+    fLookAheadRuleMap->setSize(fRB->fScanner->numRules() + 1);
+
+    for (int32_t n=0; n<fDStates->size(); n++) {
+        RBBIStateDescriptor *sd = (RBBIStateDescriptor *)fDStates->elementAt(n);
+        int32_t laSlotForState = 0;
+
+        // Establish the look-ahead slot for this state, if the state covers
+        // any look-ahead nodes - corresponding to the '/' in look-ahead rules.
+
+        // If any of the look-ahead nodes already have a slot assigned, use it,
+        // otherwise assign a new one.
+
+        bool sawLookAheadNode = false;
+        for (int32_t ipos=0; ipos<sd->fPositions->size(); ++ipos) {
+            RBBINode *node = static_cast<RBBINode *>(sd->fPositions->elementAt(ipos));
+            if (node->fType != RBBINode::NodeType::lookAhead) {
+                continue;
+            }
+            sawLookAheadNode = true;
+            int32_t ruleNum = node->fVal;     // Set when rule was originally parsed.
+            U_ASSERT(ruleNum < fLookAheadRuleMap->size());
+            U_ASSERT(ruleNum > 0);
+            int32_t laSlot = fLookAheadRuleMap->elementAti(ruleNum);
+            if (laSlot != 0) {
+                if (laSlotForState == 0) {
+                    laSlotForState = laSlot;
+                } else {
+                    // TODO: figure out if this can fail, change to setting an error code if so.
+                    U_ASSERT(laSlot == laSlotForState);
+                }
+            }
+        }
+        if (!sawLookAheadNode) {
+            continue;
+        }
+
+        if (laSlotForState == 0) {
+            laSlotForState = ++fLASlotsInUse;
+        }
+
+        // For each look ahead node covered by this state,
+        // set the mapping from the node's rule number to the look ahead slot.
+        // There can be multiple nodes/rule numbers going to the same la slot.
+
+        for (int32_t ipos=0; ipos<sd->fPositions->size(); ++ipos) {
+            RBBINode *node = static_cast<RBBINode *>(sd->fPositions->elementAt(ipos));
+            if (node->fType != RBBINode::NodeType::lookAhead) {
+                continue;
+            }
+            int32_t ruleNum = node->fVal;     // Set when rule was originally parsed.
+            int32_t existingVal = fLookAheadRuleMap->elementAti(ruleNum);
+            (void)existingVal;
+            U_ASSERT(existingVal == 0 || existingVal == laSlotForState);
+            fLookAheadRuleMap->setElementAt(laSlotForState, ruleNum);
+        }
+    }
+
+}
 
 //-----------------------------------------------------------------------------
 //
@@ -718,32 +810,23 @@
             if (sd->fPositions->indexOf(endMarker) >= 0) {
                 // Any non-zero value for fAccepting means this is an accepting node.
                 // The value is what will be returned to the user as the break status.
-                // If no other value was specified, force it to -1.
+                // If no other value was specified, force it to ACCEPTING_UNCONDITIONAL (1).
 
                 if (sd->fAccepting==0) {
                     // State hasn't been marked as accepting yet.  Do it now.
-                    sd->fAccepting = endMarker->fVal;
+                    sd->fAccepting = fLookAheadRuleMap->elementAti(endMarker->fVal);
                     if (sd->fAccepting == 0) {
-                        sd->fAccepting = -1;
+                        sd->fAccepting = ACCEPTING_UNCONDITIONAL;
                     }
                 }
-                if (sd->fAccepting==-1 && endMarker->fVal != 0) {
+                if (sd->fAccepting==ACCEPTING_UNCONDITIONAL && endMarker->fVal != 0) {
                     // Both lookahead and non-lookahead accepting for this state.
-                    // Favor the look-ahead.  Expedient for line break.
-                    // TODO:  need a more elegant resolution for conflicting rules.
-                    sd->fAccepting = endMarker->fVal;
+                    // Favor the look-ahead, because a look-ahead match needs to
+                    // immediately stop the run-time engine. First match, not longest.
+                    sd->fAccepting = fLookAheadRuleMap->elementAti(endMarker->fVal);
                 }
                 // implicit else:
-                // if sd->fAccepting already had a value other than 0 or -1, leave it be.
-
-                // If the end marker node is from a look-ahead rule, set
-                //   the fLookAhead field or this state also.
-                if (endMarker->fLookAheadEnd) {
-                    // TODO:  don't change value if already set?
-                    // TODO:  allow for more than one active look-ahead rule in engine.
-                    //        Make value here an index to a side array in engine?
-                    sd->fLookAhead = sd->fAccepting;
-                }
+                // if sd->fAccepting already had a value other than 0 or 1, leave it be.
             }
         }
     }
@@ -770,11 +853,20 @@
     }
     for (i=0; i<lookAheadNodes.size(); i++) {
         lookAheadNode = (RBBINode *)lookAheadNodes.elementAt(i);
+        U_ASSERT(lookAheadNode->fType == RBBINode::NodeType::lookAhead);
 
         for (n=0; n<fDStates->size(); n++) {
             RBBIStateDescriptor *sd = (RBBIStateDescriptor *)fDStates->elementAt(n);
-            if (sd->fPositions->indexOf(lookAheadNode) >= 0) {
-                sd->fLookAhead = lookAheadNode->fVal;
+            int32_t positionsIdx = sd->fPositions->indexOf(lookAheadNode);
+            if (positionsIdx >= 0) {
+                U_ASSERT(lookAheadNode == sd->fPositions->elementAt(positionsIdx));
+                uint32_t lookaheadSlot = fLookAheadRuleMap->elementAti(lookAheadNode->fVal);
+                U_ASSERT(sd->fLookAhead == 0 || sd->fLookAhead == lookaheadSlot);
+                // if (sd->fLookAhead != 0 && sd->fLookAhead != lookaheadSlot) {
+                //     printf("%s:%d Bingo. sd->fLookAhead:%d   lookaheadSlot:%d\n",
+                //            __FILE__, __LINE__, sd->fLookAhead, lookaheadSlot);
+                // }
+                sd->fLookAhead = lookaheadSlot;
             }
         }
     }
@@ -1034,7 +1126,9 @@
     if (n==NULL) {
         return;
     }
-    n->printNode();
+    printf("\n");
+    RBBINode::printNodeHeader();
+    RBBINode::printNode(n);
     RBBIDebugPrintf("         Nullable:  %s\n", n->fNullable?"TRUE":"FALSE");
 
     RBBIDebugPrintf("         firstpos:  ");
@@ -1051,6 +1145,184 @@
 }
 #endif
 
+//
+//    findDuplCharClassFrom()
+//
+bool RBBITableBuilder::findDuplCharClassFrom(IntPair *categories) {
+    int32_t numStates = fDStates->size();
+    int32_t numCols = fRB->fSetBuilder->getNumCharCategories();
+
+    for (; categories->first < numCols-1; categories->first++) {
+        // Note: dictionary & non-dictionary columns cannot be merged.
+        //       The limitSecond value prevents considering mixed pairs.
+        //       Dictionary categories are >= DictCategoriesStart.
+        //       Non dict categories are   <  DictCategoriesStart.
+        int limitSecond = categories->first < fRB->fSetBuilder->getDictCategoriesStart() ?
+            fRB->fSetBuilder->getDictCategoriesStart() : numCols;
+        for (categories->second=categories->first+1; categories->second < limitSecond; categories->second++) {
+            // Initialized to different values to prevent returning true if numStates = 0 (implies no duplicates).
+            uint16_t table_base = 0;
+            uint16_t table_dupl = 1;
+            for (int32_t state=0; state<numStates; state++) {
+                RBBIStateDescriptor *sd = (RBBIStateDescriptor *)fDStates->elementAt(state);
+                table_base = (uint16_t)sd->fDtran->elementAti(categories->first);
+                table_dupl = (uint16_t)sd->fDtran->elementAti(categories->second);
+                if (table_base != table_dupl) {
+                    break;
+                }
+            }
+            if (table_base == table_dupl) {
+                return true;
+            }
+        }
+    }
+    return false;
+}
+
+
+//
+//    removeColumn()
+//
+void RBBITableBuilder::removeColumn(int32_t column) {
+    int32_t numStates = fDStates->size();
+    for (int32_t state=0; state<numStates; state++) {
+        RBBIStateDescriptor *sd = (RBBIStateDescriptor *)fDStates->elementAt(state);
+        U_ASSERT(column < sd->fDtran->size());
+        sd->fDtran->removeElementAt(column);
+    }
+}
+
+/*
+ * findDuplicateState
+ */
+bool RBBITableBuilder::findDuplicateState(IntPair *states) {
+    int32_t numStates = fDStates->size();
+    int32_t numCols = fRB->fSetBuilder->getNumCharCategories();
+
+    for (; states->first<numStates-1; states->first++) {
+        RBBIStateDescriptor *firstSD = (RBBIStateDescriptor *)fDStates->elementAt(states->first);
+        for (states->second=states->first+1; states->second<numStates; states->second++) {
+            RBBIStateDescriptor *duplSD = (RBBIStateDescriptor *)fDStates->elementAt(states->second);
+            if (firstSD->fAccepting != duplSD->fAccepting ||
+                firstSD->fLookAhead != duplSD->fLookAhead ||
+                firstSD->fTagsIdx   != duplSD->fTagsIdx) {
+                continue;
+            }
+            bool rowsMatch = true;
+            for (int32_t col=0; col < numCols; ++col) {
+                int32_t firstVal = firstSD->fDtran->elementAti(col);
+                int32_t duplVal = duplSD->fDtran->elementAti(col);
+                if (!((firstVal == duplVal) ||
+                        ((firstVal == states->first || firstVal == states->second) &&
+                        (duplVal  == states->first || duplVal  == states->second)))) {
+                    rowsMatch = false;
+                    break;
+                }
+            }
+            if (rowsMatch) {
+                return true;
+            }
+        }
+    }
+    return false;
+}
+
+
+bool RBBITableBuilder::findDuplicateSafeState(IntPair *states) {
+    int32_t numStates = fSafeTable->size();
+
+    for (; states->first<numStates-1; states->first++) {
+        UnicodeString *firstRow = static_cast<UnicodeString *>(fSafeTable->elementAt(states->first));
+        for (states->second=states->first+1; states->second<numStates; states->second++) {
+            UnicodeString *duplRow = static_cast<UnicodeString *>(fSafeTable->elementAt(states->second));
+            bool rowsMatch = true;
+            int32_t numCols = firstRow->length();
+            for (int32_t col=0; col < numCols; ++col) {
+                int32_t firstVal = firstRow->charAt(col);
+                int32_t duplVal = duplRow->charAt(col);
+                if (!((firstVal == duplVal) ||
+                        ((firstVal == states->first || firstVal == states->second) &&
+                        (duplVal  == states->first || duplVal  == states->second)))) {
+                    rowsMatch = false;
+                    break;
+                }
+            }
+            if (rowsMatch) {
+                return true;
+            }
+        }
+    }
+    return false;
+}
+
+
+void RBBITableBuilder::removeState(IntPair duplStates) {
+    const int32_t keepState = duplStates.first;
+    const int32_t duplState = duplStates.second;
+    U_ASSERT(keepState < duplState);
+    U_ASSERT(duplState < fDStates->size());
+
+    RBBIStateDescriptor *duplSD = (RBBIStateDescriptor *)fDStates->elementAt(duplState);
+    fDStates->removeElementAt(duplState);
+    delete duplSD;
+
+    int32_t numStates = fDStates->size();
+    int32_t numCols = fRB->fSetBuilder->getNumCharCategories();
+    for (int32_t state=0; state<numStates; ++state) {
+        RBBIStateDescriptor *sd = (RBBIStateDescriptor *)fDStates->elementAt(state);
+        for (int32_t col=0; col<numCols; col++) {
+            int32_t existingVal = sd->fDtran->elementAti(col);
+            int32_t newVal = existingVal;
+            if (existingVal == duplState) {
+                newVal = keepState;
+            } else if (existingVal > duplState) {
+                newVal = existingVal - 1;
+            }
+            sd->fDtran->setElementAt(newVal, col);
+        }
+    }
+}
+
+void RBBITableBuilder::removeSafeState(IntPair duplStates) {
+    const int32_t keepState = duplStates.first;
+    const int32_t duplState = duplStates.second;
+    U_ASSERT(keepState < duplState);
+    U_ASSERT(duplState < fSafeTable->size());
+
+    fSafeTable->removeElementAt(duplState);   // Note that fSafeTable has a deleter function
+                                              // and will auto-delete the removed element.
+    int32_t numStates = fSafeTable->size();
+    for (int32_t state=0; state<numStates; ++state) {
+        UnicodeString *sd = (UnicodeString *)fSafeTable->elementAt(state);
+        int32_t numCols = sd->length();
+        for (int32_t col=0; col<numCols; col++) {
+            int32_t existingVal = sd->charAt(col);
+            int32_t newVal = existingVal;
+            if (existingVal == duplState) {
+                newVal = keepState;
+            } else if (existingVal > duplState) {
+                newVal = existingVal - 1;
+            }
+            sd->setCharAt(col, static_cast<char16_t>(newVal));
+        }
+    }
+}
+
+
+/*
+ * RemoveDuplicateStates
+ */
+int32_t RBBITableBuilder::removeDuplicateStates() {
+    IntPair dupls = {3, 0};
+    int32_t numStatesRemoved = 0;
+
+    while (findDuplicateState(&dupls)) {
+        // printf("Removing duplicate states (%d, %d)\n", dupls.first, dupls.second);
+        removeState(dupls);
+        ++numStatesRemoved;
+    }
+    return numStatesRemoved;
+}
 
 
 //-----------------------------------------------------------------------------
@@ -1069,20 +1341,23 @@
         return 0;
     }
 
-    size    = sizeof(RBBIStateTable) - 4;    // The header, with no rows to the table.
+    size    = offsetof(RBBIStateTable, fTableData);    // The header, with no rows to the table.
 
     numRows = fDStates->size();
     numCols = fRB->fSetBuilder->getNumCharCategories();
 
-    //  Note  The declaration of RBBIStateTableRow is for a table of two columns.
-    //        Therefore we subtract two from numCols when determining
-    //        how much storage to add to a row for the total columns.
-    rowSize = sizeof(RBBIStateTableRow) + sizeof(uint16_t)*(numCols-2);
+    if (use8BitsForTable()) {
+        rowSize = offsetof(RBBIStateTableRow8, fNextState) + sizeof(int8_t)*numCols;
+    } else {
+        rowSize = offsetof(RBBIStateTableRow16, fNextState) + sizeof(int16_t)*numCols;
+    }
     size   += numRows * rowSize;
     return size;
 }
 
-
+bool RBBITableBuilder::use8BitsForTable() const {
+    return fDStates->size() <= kMaxStateFor8BitsTable;
+}
 
 //-----------------------------------------------------------------------------
 //
@@ -1100,39 +1375,258 @@
         return;
     }
 
-    if (fRB->fSetBuilder->getNumCharCategories() > 0x7fff ||
+    int32_t catCount = fRB->fSetBuilder->getNumCharCategories();
+    if (catCount > 0x7fff ||
         fDStates->size() > 0x7fff) {
         *fStatus = U_BRK_INTERNAL_ERROR;
         return;
     }
 
-    table->fRowLen    = sizeof(RBBIStateTableRow) +
-                            sizeof(uint16_t) * (fRB->fSetBuilder->getNumCharCategories() - 2);
     table->fNumStates = fDStates->size();
+    table->fDictCategoriesStart = fRB->fSetBuilder->getDictCategoriesStart();
+    table->fLookAheadResultsSize = fLASlotsInUse == ACCEPTING_UNCONDITIONAL ? 0 : fLASlotsInUse + 1;
     table->fFlags     = 0;
+    if (use8BitsForTable()) {
+        table->fRowLen    = offsetof(RBBIStateTableRow8, fNextState) + sizeof(uint8_t) * catCount;
+        table->fFlags  |= RBBI_8BITS_ROWS;
+    } else {
+        table->fRowLen    = offsetof(RBBIStateTableRow16, fNextState) + sizeof(int16_t) * catCount;
+    }
     if (fRB->fLookAheadHardBreak) {
         table->fFlags  |= RBBI_LOOKAHEAD_HARD_BREAK;
     }
     if (fRB->fSetBuilder->sawBOF()) {
         table->fFlags  |= RBBI_BOF_REQUIRED;
     }
-    table->fReserved  = 0;
 
     for (state=0; state<table->fNumStates; state++) {
         RBBIStateDescriptor *sd = (RBBIStateDescriptor *)fDStates->elementAt(state);
         RBBIStateTableRow   *row = (RBBIStateTableRow *)(table->fTableData + state*table->fRowLen);
-        U_ASSERT (-32768 < sd->fAccepting && sd->fAccepting <= 32767);
-        U_ASSERT (-32768 < sd->fLookAhead && sd->fLookAhead <= 32767);
-        row->fAccepting = (int16_t)sd->fAccepting;
-        row->fLookAhead = (int16_t)sd->fLookAhead;
-        row->fTagIdx    = (int16_t)sd->fTagsIdx;
-        for (col=0; col<fRB->fSetBuilder->getNumCharCategories(); col++) {
-            row->fNextState[col] = (uint16_t)sd->fDtran->elementAti(col);
+        if (use8BitsForTable()) {
+            U_ASSERT (sd->fAccepting <= 255);
+            U_ASSERT (sd->fLookAhead <= 255);
+            U_ASSERT (0 <= sd->fTagsIdx && sd->fTagsIdx <= 255);
+            row->r8.fAccepting = sd->fAccepting;
+            row->r8.fLookAhead = sd->fLookAhead;
+            row->r8.fTagsIdx   = sd->fTagsIdx;
+            for (col=0; col<catCount; col++) {
+                U_ASSERT (sd->fDtran->elementAti(col) <= kMaxStateFor8BitsTable);
+                row->r8.fNextState[col] = sd->fDtran->elementAti(col);
+            }
+        } else {
+            U_ASSERT (sd->fAccepting <= 0xffff);
+            U_ASSERT (sd->fLookAhead <= 0xffff);
+            U_ASSERT (0 <= sd->fTagsIdx && sd->fTagsIdx <= 0xffff);
+            row->r16.fAccepting = sd->fAccepting;
+            row->r16.fLookAhead = sd->fLookAhead;
+            row->r16.fTagsIdx   = sd->fTagsIdx;
+            for (col=0; col<catCount; col++) {
+                row->r16.fNextState[col] = sd->fDtran->elementAti(col);
+            }
         }
     }
 }
 
 
+/**
+ *   Synthesize a safe state table from the main state table.
+ */
+void RBBITableBuilder::buildSafeReverseTable(UErrorCode &status) {
+    // The safe table creation has three steps:
+
+    // 1. Identifiy pairs of character classes that are "safe." Safe means that boundaries
+    // following the pair do not depend on context or state before the pair. To test
+    // whether a pair is safe, run it through the main forward state table, starting
+    // from each state. If the the final state is the same, no matter what the starting state,
+    // the pair is safe.
+    //
+    // 2. Build a state table that recognizes the safe pairs. It's similar to their
+    // forward table, with a column for each input character [class], and a row for
+    // each state. Row 1 is the start state, and row 0 is the stop state. Initially
+    // create an additional state for each input character category; being in
+    // one of these states means that the character has been seen, and is potentially
+    // the first of a pair. In each of these rows, the entry for the second character
+    // of a safe pair is set to the stop state (0), indicating that a match was found.
+    // All other table entries are set to the state corresponding the current input
+    // character, allowing that charcter to be the of a start following pair.
+    //
+    // Because the safe rules are to be run in reverse, moving backwards in the text,
+    // the first and second pair categories are swapped when building the table.
+    //
+    // 3. Compress the table. There are typically many rows (states) that are
+    // equivalent - that have zeroes (match completed) in the same columns -
+    // and can be folded together.
+
+    // Each safe pair is stored as two UChars in the safePair string.
+    UnicodeString safePairs;
+
+    int32_t numCharClasses = fRB->fSetBuilder->getNumCharCategories();
+    int32_t numStates = fDStates->size();
+
+    for (int32_t c1=0; c1<numCharClasses; ++c1) {
+        for (int32_t c2=0; c2 < numCharClasses; ++c2) {
+            int32_t wantedEndState = -1;
+            int32_t endState = 0;
+            for (int32_t startState = 1; startState < numStates; ++startState) {
+                RBBIStateDescriptor *startStateD = static_cast<RBBIStateDescriptor *>(fDStates->elementAt(startState));
+                int32_t s2 = startStateD->fDtran->elementAti(c1);
+                RBBIStateDescriptor *s2StateD = static_cast<RBBIStateDescriptor *>(fDStates->elementAt(s2));
+                endState = s2StateD->fDtran->elementAti(c2);
+                if (wantedEndState < 0) {
+                    wantedEndState = endState;
+                } else {
+                    if (wantedEndState != endState) {
+                        break;
+                    }
+                }
+            }
+            if (wantedEndState == endState) {
+                safePairs.append((char16_t)c1);
+                safePairs.append((char16_t)c2);
+                // printf("(%d, %d) ", c1, c2);
+            }
+        }
+        // printf("\n");
+    }
+
+    // Populate the initial safe table.
+    // The table as a whole is UVector<UnicodeString>
+    // Each row is represented by a UnicodeString, being used as a Vector<int16>.
+    // Row 0 is the stop state.
+    // Row 1 is the start sate.
+    // Row 2 and beyond are other states, initially one per char class, but
+    //   after initial construction, many of the states will be combined, compacting the table.
+    // The String holds the nextState data only. The four leading fields of a row, fAccepting,
+    // fLookAhead, etc. are not needed for the safe table, and are omitted at this stage of building.
+
+    U_ASSERT(fSafeTable == nullptr);
+    fSafeTable = new UVector(uprv_deleteUObject, uhash_compareUnicodeString, numCharClasses + 2, status);
+    for (int32_t row=0; row<numCharClasses + 2; ++row) {
+        fSafeTable->addElement(new UnicodeString(numCharClasses, 0, numCharClasses+4), status);
+    }
+
+    // From the start state, each input char class transitions to the state for that input.
+    UnicodeString &startState = *static_cast<UnicodeString *>(fSafeTable->elementAt(1));
+    for (int32_t charClass=0; charClass < numCharClasses; ++charClass) {
+        // Note: +2 for the start & stop state.
+        startState.setCharAt(charClass, static_cast<char16_t>(charClass+2));
+    }
+
+    // Initially make every other state table row look like the start state row,
+    for (int32_t row=2; row<numCharClasses+2; ++row) {
+        UnicodeString &rowState = *static_cast<UnicodeString *>(fSafeTable->elementAt(row));
+        rowState = startState;   // UnicodeString assignment, copies contents.
+    }
+
+    // Run through the safe pairs, set the next state to zero when pair has been seen.
+    // Zero being the stop state, meaning we found a safe point.
+    for (int32_t pairIdx=0; pairIdx<safePairs.length(); pairIdx+=2) {
+        int32_t c1 = safePairs.charAt(pairIdx);
+        int32_t c2 = safePairs.charAt(pairIdx + 1);
+
+        UnicodeString &rowState = *static_cast<UnicodeString *>(fSafeTable->elementAt(c2 + 2));
+        rowState.setCharAt(c1, 0);
+    }
+
+    // Remove duplicate or redundant rows from the table.
+    IntPair states = {1, 0};
+    while (findDuplicateSafeState(&states)) {
+        // printf("Removing duplicate safe states (%d, %d)\n", states.first, states.second);
+        removeSafeState(states);
+    }
+}
+
+
+//-----------------------------------------------------------------------------
+//
+//   getSafeTableSize()    Calculate the size of the runtime form of this
+//                         safe state table.
+//
+//-----------------------------------------------------------------------------
+int32_t  RBBITableBuilder::getSafeTableSize() const {
+    int32_t    size = 0;
+    int32_t    numRows;
+    int32_t    numCols;
+    int32_t    rowSize;
+
+    if (fSafeTable == nullptr) {
+        return 0;
+    }
+
+    size    = offsetof(RBBIStateTable, fTableData);    // The header, with no rows to the table.
+
+    numRows = fSafeTable->size();
+    numCols = fRB->fSetBuilder->getNumCharCategories();
+
+    if (use8BitsForSafeTable()) {
+        rowSize = offsetof(RBBIStateTableRow8, fNextState) + sizeof(int8_t)*numCols;
+    } else {
+        rowSize = offsetof(RBBIStateTableRow16, fNextState) + sizeof(int16_t)*numCols;
+    }
+    size   += numRows * rowSize;
+    return size;
+}
+
+bool RBBITableBuilder::use8BitsForSafeTable() const {
+    return fSafeTable->size() <= kMaxStateFor8BitsTable;
+}
+
+//-----------------------------------------------------------------------------
+//
+//   exportSafeTable()   export the state transition table in the format required
+//                       by the runtime engine.  getTableSize() bytes of memory
+//                       must be available at the output address "where".
+//
+//-----------------------------------------------------------------------------
+void RBBITableBuilder::exportSafeTable(void *where) {
+    RBBIStateTable    *table = (RBBIStateTable *)where;
+    uint32_t           state;
+    int                col;
+
+    if (U_FAILURE(*fStatus) || fSafeTable == nullptr) {
+        return;
+    }
+
+    int32_t catCount = fRB->fSetBuilder->getNumCharCategories();
+    if (catCount > 0x7fff ||
+            fSafeTable->size() > 0x7fff) {
+        *fStatus = U_BRK_INTERNAL_ERROR;
+        return;
+    }
+
+    table->fNumStates = fSafeTable->size();
+    table->fFlags     = 0;
+    if (use8BitsForSafeTable()) {
+        table->fRowLen    = offsetof(RBBIStateTableRow8, fNextState) + sizeof(uint8_t) * catCount;
+        table->fFlags  |= RBBI_8BITS_ROWS;
+    } else {
+        table->fRowLen    = offsetof(RBBIStateTableRow16, fNextState) + sizeof(int16_t) * catCount;
+    }
+
+    for (state=0; state<table->fNumStates; state++) {
+        UnicodeString *rowString = (UnicodeString *)fSafeTable->elementAt(state);
+        RBBIStateTableRow   *row = (RBBIStateTableRow *)(table->fTableData + state*table->fRowLen);
+        if (use8BitsForSafeTable()) {
+            row->r8.fAccepting = 0;
+            row->r8.fLookAhead = 0;
+            row->r8.fTagsIdx    = 0;
+            for (col=0; col<catCount; col++) {
+                U_ASSERT(rowString->charAt(col) <= kMaxStateFor8BitsTable);
+                row->r8.fNextState[col] = static_cast<uint8_t>(rowString->charAt(col));
+            }
+        } else {
+            row->r16.fAccepting = 0;
+            row->r16.fLookAhead = 0;
+            row->r16.fTagsIdx    = 0;
+            for (col=0; col<catCount; col++) {
+                row->r16.fNextState[col] = rowString->charAt(col);
+            }
+        }
+    }
+}
+
+
+
 
 //-----------------------------------------------------------------------------
 //
@@ -1143,8 +1637,8 @@
 void RBBITableBuilder::printSet(UVector *s) {
     int32_t  i;
     for (i=0; i<s->size(); i++) {
-        void *v = s->elementAt(i);
-        RBBIDebugPrintf("%10p", v);
+        const RBBINode *v = static_cast<const RBBINode *>(s->elementAt(i));
+        RBBIDebugPrintf("%5d", v==NULL? -1 : v->fSerialNum);
     }
     RBBIDebugPrintf("\n");
 }
@@ -1164,6 +1658,47 @@
     RBBIDebugPrintf("state |           i n p u t     s y m b o l s \n");
     RBBIDebugPrintf("      | Acc  LA    Tag");
     for (c=0; c<fRB->fSetBuilder->getNumCharCategories(); c++) {
+        RBBIDebugPrintf(" %3d", c);
+    }
+    RBBIDebugPrintf("\n");
+    RBBIDebugPrintf("      |---------------");
+    for (c=0; c<fRB->fSetBuilder->getNumCharCategories(); c++) {
+        RBBIDebugPrintf("----");
+    }
+    RBBIDebugPrintf("\n");
+
+    for (n=0; n<fDStates->size(); n++) {
+        RBBIStateDescriptor *sd = (RBBIStateDescriptor *)fDStates->elementAt(n);
+        RBBIDebugPrintf("  %3d | " , n);
+        RBBIDebugPrintf("%3d %3d %5d ", sd->fAccepting, sd->fLookAhead, sd->fTagsIdx);
+        for (c=0; c<fRB->fSetBuilder->getNumCharCategories(); c++) {
+            RBBIDebugPrintf(" %3d", sd->fDtran->elementAti(c));
+        }
+        RBBIDebugPrintf("\n");
+    }
+    RBBIDebugPrintf("\n\n");
+}
+#endif
+
+
+//-----------------------------------------------------------------------------
+//
+//   printSafeTable    Debug Function.  Dump the fully constructed safe table.
+//
+//-----------------------------------------------------------------------------
+#ifdef RBBI_DEBUG
+void RBBITableBuilder::printReverseTable() {
+    int     c;    // input "character"
+    int     n;    // state number
+
+    RBBIDebugPrintf("    Safe Reverse Table \n");
+    if (fSafeTable == nullptr) {
+        RBBIDebugPrintf("   --- nullptr ---\n");
+        return;
+    }
+    RBBIDebugPrintf("state |           i n p u t     s y m b o l s \n");
+    RBBIDebugPrintf("      | Acc  LA    Tag");
+    for (c=0; c<fRB->fSetBuilder->getNumCharCategories(); c++) {
         RBBIDebugPrintf(" %2d", c);
     }
     RBBIDebugPrintf("\n");
@@ -1173,12 +1708,12 @@
     }
     RBBIDebugPrintf("\n");
 
-    for (n=0; n<fDStates->size(); n++) {
-        RBBIStateDescriptor *sd = (RBBIStateDescriptor *)fDStates->elementAt(n);
+    for (n=0; n<fSafeTable->size(); n++) {
+        UnicodeString *rowString = (UnicodeString *)fSafeTable->elementAt(n);
         RBBIDebugPrintf("  %3d | " , n);
-        RBBIDebugPrintf("%3d %3d %5d ", sd->fAccepting, sd->fLookAhead, sd->fTagsIdx);
+        RBBIDebugPrintf("%3d %3d %5d ", 0, 0, 0);  // Accepting, LookAhead, Tags
         for (c=0; c<fRB->fSetBuilder->getNumCharCategories(); c++) {
-            RBBIDebugPrintf(" %2d", sd->fDtran->elementAti(c));
+            RBBIDebugPrintf(" %2d", rowString->charAt(c));
         }
         RBBIDebugPrintf("\n");
     }
@@ -1233,7 +1768,7 @@
     fPositions = NULL;
     fDtran     = NULL;
 
-    fDtran     = new UVector(lastInputSymbol+1, *fStatus);
+    fDtran     = new UVector32(lastInputSymbol+1, *fStatus);
     if (U_FAILURE(*fStatus)) {
         return;
     }
@@ -1241,7 +1776,7 @@
         *fStatus = U_MEMORY_ALLOCATION_ERROR;
         return;
     }
-    fDtran->setSize(lastInputSymbol+1, *fStatus);    // fDtran needs to be pre-sized.
+    fDtran->setSize(lastInputSymbol+1);    // fDtran needs to be pre-sized.
                                            //   It is indexed by input symbols, and will
                                            //   hold  the next state number for each
                                            //   symbol.
diff --git a/src/third_party/icu/source/common/rbbitblb.h b/src/third_party/icu/source/common/rbbitblb.h
index 3805b67..fe3db8d 100644
--- a/src/third_party/icu/source/common/rbbitblb.h
+++ b/src/third_party/icu/source/common/rbbitblb.h
@@ -1,10 +1,12 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 //
 //  rbbitblb.h
 //
 
 /*
 **********************************************************************
-*   Copyright (c) 2002-2005, International Business Machines
+*   Copyright (c) 2002-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 **********************************************************************
 */
@@ -13,8 +15,13 @@
 #define RBBITBLB_H
 
 #include "unicode/utypes.h"
+
+#if !UCONFIG_NO_BREAK_ITERATION
+
 #include "unicode/uobject.h"
 #include "unicode/rbbi.h"
+#include "rbbidata.h"
+#include "rbbirb.h"
 #include "rbbinode.h"
 
 
@@ -22,6 +29,7 @@
 
 class RBBIRuleScanner;
 class RBBIRuleBuilder;
+class UVector32;
 
 //
 //  class RBBITableBuilder is part of the RBBI rule compiler.
@@ -34,30 +42,109 @@
 
 class RBBITableBuilder : public UMemory {
 public:
-    RBBITableBuilder(RBBIRuleBuilder *rb, RBBINode **rootNode);
+    RBBITableBuilder(RBBIRuleBuilder *rb, RBBINode **rootNode, UErrorCode &status);
     ~RBBITableBuilder();
 
-    void     build();
-    int32_t  getTableSize() const;      // Return the runtime size in bytes of
-                                        //     the built state table
-    void     exportTable(void *where);  // fill in the runtime state table.
-                                        //     Sufficient memory must exist at
-                                        //     the specified location.
+    void     buildForwardTable();
 
+    /** Return the runtime size in bytes of the built state table.  */
+    int32_t  getTableSize() const;
+
+    /** Fill in the runtime state table. Sufficient memory must exist at the specified location.
+     */
+    void     exportTable(void *where);
+
+    /** Use 8 bits to encode the forward table */
+    bool     use8BitsForTable() const;
+
+    /**
+     *  Find duplicate (redundant) character classes. Begin looking with categories.first.
+     *  Duplicate, if found are returned in the categories parameter.
+     *  This is an iterator-like function, used to identify character classes
+     *  (state table columns) that can be eliminated.
+     *  @param categories in/out parameter, specifies where to start looking for duplicates,
+     *                and returns the first pair of duplicates found, if any.
+     *  @return true if duplicate char classes were found, false otherwise.
+     */
+    bool     findDuplCharClassFrom(IntPair *categories);
+
+    /** Remove a column from the state table. Used when two character categories
+     *  have been found equivalent, and merged together, to eliminate the uneeded table column.
+     */
+    void     removeColumn(int32_t column);
+
+    /**
+     * Check for, and remove dupicate states (table rows).
+     * @return the number of states removed.
+     */
+    int32_t  removeDuplicateStates();
+
+    /** Build the safe reverse table from the already-constructed forward table. */
+    void     buildSafeReverseTable(UErrorCode &status);
+
+    /** Return the runtime size in bytes of the built safe reverse state table. */
+    int32_t  getSafeTableSize() const;
+
+    /** Fill in the runtime safe state table. Sufficient memory must exist at the specified location.
+     */
+    void     exportSafeTable(void *where);
+
+    /** Use 8 bits to encode the safe reverse table */
+    bool     use8BitsForSafeTable() const;
 
 private:
     void     calcNullable(RBBINode *n);
     void     calcFirstPos(RBBINode *n);
     void     calcLastPos(RBBINode  *n);
     void     calcFollowPos(RBBINode *n);
-    void     calcChainedFollowPos(RBBINode *n);
+    void     calcChainedFollowPos(RBBINode *n, RBBINode *endMarkNode);
     void     bofFixup();
     void     buildStateTable();
+    void     mapLookAheadRules();
     void     flagAcceptingStates();
     void     flagLookAheadStates();
     void     flagTaggedStates();
     void     mergeRuleStatusVals();
 
+    /**
+     * Merge redundant state table columns, eliminating character classes with identical behavior.
+     * Done after the state tables are generated, just before converting to their run-time format.
+     */
+    int32_t  mergeColumns();
+
+    void     addRuleRootNodes(UVector *dest, RBBINode *node);
+
+    /**
+     *  Find duplicate (redundant) states, beginning at the specified pair,
+     *  within this state table. This is an iterator-like function, used to
+     *  identify states (state table rows) that can be eliminated.
+     *  @param states in/out parameter, specifies where to start looking for duplicates,
+     *                and returns the first pair of duplicates found, if any.
+     *  @return true if duplicate states were found, false otherwise.
+     */
+    bool findDuplicateState(IntPair *states);
+
+    /** Remove a duplicate state.
+     * @param duplStates The duplicate states. The first is kept, the second is removed.
+     *                   All references to the second in the state table are retargeted
+     *                   to the first.
+     */
+    void removeState(IntPair duplStates);
+
+    /** Find the next duplicate state in the safe reverse table. An iterator function.
+     *  @param states in/out parameter, specifies where to start looking for duplicates,
+     *                and returns the first pair of duplicates found, if any.
+     *  @return true if a duplicate pair of states was found.
+     */
+    bool findDuplicateSafeState(IntPair *states);
+
+    /** Remove a duplicate state from the safe table.
+     * @param duplStates The duplicate states. The first is kept, the second is removed.
+     *                   All references to the second in the state table are retargeted
+     *                   to the first.
+     */
+    void removeSafeState(IntPair duplStates);
+
     // Set functions for UVector.
     //   TODO:  make a USet subclass of UVector
 
@@ -72,11 +159,13 @@
     void     printPosSets(RBBINode *n /* = NULL*/);
     void     printStates();
     void     printRuleStatusTable();
+    void     printReverseTable();
 #else
     #define  printSet(s)
     #define  printPosSets(n)
     #define  printStates()
     #define  printRuleStatusTable()
+    #define  printReverseTable()
 #endif
 
 private:
@@ -85,13 +174,26 @@
                                            //   table for.
     UErrorCode       *fStatus;
 
+    /** State Descriptors, UVector<RBBIStateDescriptor> */
     UVector          *fDStates;            //  D states (Aho's terminology)
                                            //  Index is state number
                                            //  Contents are RBBIStateDescriptor pointers.
 
+    /** Synthesized safe table, UVector of UnicodeString, one string per table row.   */
+    UVector          *fSafeTable;
 
-    RBBITableBuilder(const RBBITableBuilder &other); // forbid copying of this class
-    RBBITableBuilder &operator=(const RBBITableBuilder &other); // forbid copying of this class
+    /** Map from rule number (fVal in look ahead nodes) to sequential lookahead index. */
+    UVector32        *fLookAheadRuleMap = nullptr;
+
+    /* Counter used when assigning lookahead rule numbers.
+     * Contains the last look-ahead number already in use.
+     * The first look-ahead number is 2; Number 1 (ACCEPTING_UNCONDITIONAL) is reserved
+     * for non-lookahead accepting states. See the declarations of RBBIStateTableRowT.   */
+    int32_t          fLASlotsInUse = ACCEPTING_UNCONDITIONAL;
+
+
+    RBBITableBuilder(const RBBITableBuilder &other) = delete; // forbid copying of this class
+    RBBITableBuilder &operator=(const RBBITableBuilder &other) = delete; // forbid copying of this class
 };
 
 //
@@ -100,15 +202,15 @@
 class RBBIStateDescriptor : public UMemory {
 public:
     UBool            fMarked;
-    int32_t          fAccepting;
-    int32_t          fLookAhead;
+    uint32_t         fAccepting;
+    uint32_t         fLookAhead;
     UVector          *fTagVals;
     int32_t          fTagsIdx;
     UVector          *fPositions;          // Set of parse tree positions associated
                                            //   with this state.  Unordered (it's a set).
                                            //   UVector contents are RBBINode *
 
-    UVector          *fDtran;              // Transitions out of this state.
+    UVector32        *fDtran;              // Transitions out of this state.
                                            //   indexed by input character
                                            //   contents is int index of dest state
                                            //   in RBBITableBuilder.fDStates
@@ -124,4 +226,7 @@
 
 
 U_NAMESPACE_END
+
+#endif /* #if !UCONFIG_NO_BREAK_ITERATION */
+
 #endif
diff --git a/src/third_party/icu/source/common/resbund.cpp b/src/third_party/icu/source/common/resbund.cpp
index a2282e1..7c5063b 100644
--- a/src/third_party/icu/source/common/resbund.cpp
+++ b/src/third_party/icu/source/common/resbund.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
 *   Copyright (C) 1997-2013, International Business Machines
@@ -49,6 +51,7 @@
 #include "unicode/utypes.h"
 #include "unicode/resbund.h"
 
+#include "cmemory.h"
 #include "mutex.h"
 #include "uassert.h"
 #include "umutex.h"
@@ -374,8 +377,8 @@
     ures_getVersion(fResource, versionInfo);
 }
 
-static UMutex gLocaleLock = U_MUTEX_INITIALIZER;
 const Locale &ResourceBundle::getLocale(void) const {
+    static UMutex gLocaleLock;
     Mutex lock(&gLocaleLock);
     if (fLocale != NULL) {
         return *fLocale;
diff --git a/src/third_party/icu/source/common/resbund_cnv.cpp b/src/third_party/icu/source/common/resbund_cnv.cpp
index a18e57e..45c0b39 100644
--- a/src/third_party/icu/source/common/resbund_cnv.cpp
+++ b/src/third_party/icu/source/common/resbund_cnv.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  resbund_cnv.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
diff --git a/src/third_party/icu/source/common/resource.cpp b/src/third_party/icu/source/common/resource.cpp
index 7a4c418..3d41a16 100644
--- a/src/third_party/icu/source/common/resource.cpp
+++ b/src/third_party/icu/source/common/resource.cpp
@@ -1,6 +1,8 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
-* Copyright (C) 2015, International Business Machines
+* Copyright (C) 2015-2016, International Business Machines
 * Corporation and others.  All Rights Reserved.
 *******************************************************************************
 * resource.cpp
@@ -11,50 +13,10 @@
 
 #include "resource.h"
 
-#include "unicode/utypes.h"
-#include "unicode/uobject.h"
-#include "unicode/ures.h"
-
 U_NAMESPACE_BEGIN
 
 ResourceValue::~ResourceValue() {}
 
-
-ResourceArraySink::~ResourceArraySink() {}
-
-void ResourceArraySink::put(
-        int32_t /*index*/, const ResourceValue & /*value*/, UErrorCode & /*errorCode*/) {}
-
-ResourceArraySink *ResourceArraySink::getOrCreateArraySink(
-        int32_t /*index*/, int32_t /*size*/, UErrorCode & /*errorCode*/) {
-    return NULL;
-}
-
-ResourceTableSink *ResourceArraySink::getOrCreateTableSink(
-        int32_t /*index*/, int32_t /*initialSize*/, UErrorCode & /*errorCode*/) {
-    return NULL;
-}
-
-void ResourceArraySink::leave(UErrorCode & /*errorCode*/) {}
-
-
-ResourceTableSink::~ResourceTableSink() {}
-
-void ResourceTableSink::put(
-        const char * /*key*/, const ResourceValue & /*value*/, UErrorCode & /*errorCode*/) {}
-
-void ResourceTableSink::putNoFallback(const char * /*key*/, UErrorCode & /*errorCode*/) {}
-
-ResourceArraySink *ResourceTableSink::getOrCreateArraySink(
-        const char * /*key*/, int32_t /*size*/, UErrorCode & /*errorCode*/) {
-    return NULL;
-}
-
-ResourceTableSink *ResourceTableSink::getOrCreateTableSink(
-        const char * /*key*/, int32_t /*initialSize*/, UErrorCode & /*errorCode*/) {
-    return NULL;
-}
-
-void ResourceTableSink::leave(UErrorCode & /*errorCode*/) {}
+ResourceSink::~ResourceSink() {}
 
 U_NAMESPACE_END
diff --git a/src/third_party/icu/source/common/resource.h b/src/third_party/icu/source/common/resource.h
index 042e298..3795694 100644
--- a/src/third_party/icu/source/common/resource.h
+++ b/src/third_party/icu/source/common/resource.h
@@ -1,6 +1,8 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
-* Copyright (C) 2015, International Business Machines
+* Copyright (C) 2015-2016, International Business Machines
 * Corporation and others.  All Rights Reserved.
 *******************************************************************************
 * resource.h
@@ -26,15 +28,96 @@
 #include "unicode/utypes.h"
 #include "unicode/unistr.h"
 #include "unicode/ures.h"
+#include "restrace.h"
+
+struct ResourceData;
 
 U_NAMESPACE_BEGIN
 
-class ResourceTableSink;
+class ResourceValue;
 
 // Note: In C++, we use const char * pointers for keys,
 // rather than an abstraction like Java UResource.Key.
 
 /**
+ * Interface for iterating over a resource bundle array resource.
+ */
+class U_COMMON_API ResourceArray {
+public:
+    /** Constructs an empty array object. */
+    ResourceArray() : items16(NULL), items32(NULL), length(0) {}
+
+    /** Only for implementation use. @internal */
+    ResourceArray(const uint16_t *i16, const uint32_t *i32, int32_t len,
+                  const ResourceTracer& traceInfo) :
+            items16(i16), items32(i32), length(len),
+            fTraceInfo(traceInfo) {}
+
+    /**
+     * @return The number of items in the array resource.
+     */
+    int32_t getSize() const { return length; }
+    /**
+     * @param i Array item index.
+     * @param value Output-only, receives the value of the i'th item.
+     * @return true if i is non-negative and less than getSize().
+     */
+    UBool getValue(int32_t i, ResourceValue &value) const;
+
+    /** Only for implementation use. @internal */
+    uint32_t internalGetResource(const ResourceData *pResData, int32_t i) const;
+
+private:
+    const uint16_t *items16;
+    const uint32_t *items32;
+    int32_t length;
+    ResourceTracer fTraceInfo;
+};
+
+/**
+ * Interface for iterating over a resource bundle table resource.
+ */
+class U_COMMON_API ResourceTable {
+public:
+    /** Constructs an empty table object. */
+    ResourceTable() : keys16(NULL), keys32(NULL), items16(NULL), items32(NULL), length(0) {}
+
+    /** Only for implementation use. @internal */
+    ResourceTable(const uint16_t *k16, const int32_t *k32,
+                  const uint16_t *i16, const uint32_t *i32, int32_t len,
+                  const ResourceTracer& traceInfo) :
+            keys16(k16), keys32(k32), items16(i16), items32(i32), length(len),
+            fTraceInfo(traceInfo) {}
+
+    /**
+     * @return The number of items in the array resource.
+     */
+    int32_t getSize() const { return length; }
+    /**
+     * @param i Table item index.
+     * @param key Output-only, receives the key of the i'th item.
+     * @param value Output-only, receives the value of the i'th item.
+     * @return true if i is non-negative and less than getSize().
+     */
+    UBool getKeyAndValue(int32_t i, const char *&key, ResourceValue &value) const;
+
+    /**
+     * @param key Key string to find in the table.
+     * @param value Output-only, receives the value of the item with that key.
+     * @return true if the table contains the key.
+     */
+    UBool findValue(const char *key, ResourceValue &value) const;
+
+private:
+    const uint16_t *keys16;
+    const int32_t *keys32;
+    const uint16_t *items16;
+    const uint32_t *items32;
+    int32_t length;
+    ResourceTracer fTraceInfo;
+};
+
+/**
  * Represents a resource bundle item's value.
  * Avoids object creations as much as possible.
  * Mutable, not thread-safe.
@@ -58,7 +141,7 @@
     inline UnicodeString getUnicodeString(UErrorCode &errorCode) const {
         int32_t len = 0;
         const UChar *r = getString(len, errorCode);
-        return UnicodeString(TRUE, r, len);
+        return UnicodeString(true, r, len);
     }
 
     /**
@@ -69,7 +152,7 @@
     inline UnicodeString getAliasUnicodeString(UErrorCode &errorCode) const {
         int32_t len = 0;
         const UChar *r = getAliasString(len, errorCode);
-        return UnicodeString(TRUE, r, len);
+        return UnicodeString(true, r, len);
     }
 
     /**
@@ -100,6 +183,73 @@
      */
     virtual const uint8_t *getBinary(int32_t &length, UErrorCode &errorCode) const = 0;
 
+    /**
+     * Sets U_RESOURCE_TYPE_MISMATCH if this is not an array resource
+     */
+    virtual ResourceArray getArray(UErrorCode &errorCode) const = 0;
+
+    /**
+     * Sets U_RESOURCE_TYPE_MISMATCH if this is not a table resource
+     */
+    virtual ResourceTable getTable(UErrorCode &errorCode) const = 0;
+
+    /**
+     * Is this a no-fallback/no-inheritance marker string?
+     * Such a marker is used for
+     * CLDR no-fallback data values of (three empty-set symbols)=={2205, 2205, 2205}
+     * when enumerating tables with fallback from the specific resource bundle to root.
+     *
+     * @return true if this is a no-inheritance marker string
+     */
+    virtual UBool isNoInheritanceMarker() const = 0;
+
+    /**
+     * Sets the dest strings from the string values in this array resource.
+     *
+     * @return the number of strings in this array resource.
+     *     If greater than capacity, then an overflow error is set.
+     *
+     * Sets U_RESOURCE_TYPE_MISMATCH if this is not an array resource
+     *     or if any of the array items is not a string
+     */
+    virtual int32_t getStringArray(UnicodeString *dest, int32_t capacity,
+                                   UErrorCode &errorCode) const = 0;
+
+    /**
+     * Same as
+     * <pre>
+     * if (getType() == URES_STRING) {
+     *     return new String[] { getString(); }
+     * } else {
+     *     return getStringArray();
+     * }
+     * </pre>
+     *
+     * Sets U_RESOURCE_TYPE_MISMATCH if this is
+     *     neither a string resource nor an array resource containing strings
+     * @see getString()
+     * @see getStringArray()
+     */
+    virtual int32_t getStringArrayOrStringAsArray(UnicodeString *dest, int32_t capacity,
+                                                  UErrorCode &errorCode) const = 0;
+
+    /**
+     * Same as
+     * <pre>
+     * if (getType() == URES_STRING) {
+     *     return getString();
+     * } else {
+     *     return getStringArray()[0];
+     * }
+     * </pre>
+     *
+     * Sets U_RESOURCE_TYPE_MISMATCH if this is
+     *     neither a string resource nor an array resource containing strings
+     * @see getString()
+     * @see getStringArray()
+     */
+    virtual UnicodeString getStringOrFirstOfArray(UErrorCode &errorCode) const = 0;
+
 protected:
     ResourceValue() {}
 
@@ -109,138 +259,33 @@
 };
 
 /**
- * Sink for ICU resource array contents.
- * The base class does nothing.
- *
- * Nested arrays and tables are stored as nested sinks,
- * never put() as ResourceValue items.
+ * Sink for ICU resource bundle contents.
  */
-class U_COMMON_API ResourceArraySink : public UObject {
+class U_COMMON_API ResourceSink : public UObject {
 public:
-    ResourceArraySink() {}
-    virtual ~ResourceArraySink();
+    ResourceSink() {}
+    virtual ~ResourceSink();
 
     /**
-     * Adds a value from a resource array.
+     * Called once for each bundle (child-parent-...-root).
+     * The value is normally an array or table resource,
+     * and implementations of this method normally iterate over the
+     * tree of resource items stored there.
      *
-     * @param index of the resource array item
-     * @param value resource value
+     * @param key The key string of the enumeration-start resource.
+     *     Empty if the enumeration starts at the top level of the bundle.
+     * @param value Call getArray() or getTable() as appropriate.
+     *     Then reuse for output values from Array and Table getters.
+     * @param noFallback true if the bundle has no parent;
+     *     that is, its top-level table has the nofallback attribute,
+     *     or it is the root bundle of a locale tree.
      */
-    virtual void put(int32_t index, const ResourceValue &value, UErrorCode &errorCode);
-
-    /**
-     * Returns a nested resource array at the array index as another sink.
-     * Creates the sink if none exists for the key.
-     * Returns NULL if nested arrays are not supported.
-     * The default implementation always returns NULL.
-     *
-     * This sink (not the caller) owns the nested sink.
-     *
-     * @param index of the resource array item
-     * @param size number of array items
-     * @return nested-array sink, or NULL
-     */
-    virtual ResourceArraySink *getOrCreateArraySink(
-            int32_t index, int32_t size, UErrorCode &errorCode);
-
-    /**
-     * Returns a nested resource table at the array index as another sink.
-     * Creates the sink if none exists for the key.
-     * Returns NULL if nested tables are not supported.
-     * The default implementation always returns NULL.
-     *
-     * This sink (not the caller) owns the nested sink.
-     *
-     * @param index of the resource array item
-     * @param initialSize size hint for creating the sink if necessary
-     * @return nested-table sink, or NULL
-     */
-    virtual ResourceTableSink *getOrCreateTableSink(
-            int32_t index, int32_t initialSize, UErrorCode &errorCode);
-
-    /**
-     * "Leaves" the array.
-     * Indicates that all of the resources and sub-resources of the current array
-     * have been enumerated.
-     */
-    virtual void leave(UErrorCode &errorCode);
+    virtual void put(const char *key, ResourceValue &value, UBool noFallback,
+                     UErrorCode &errorCode) = 0;
 
 private:
-    ResourceArraySink(const ResourceArraySink &);  // no copy constructor
-    ResourceArraySink &operator=(const ResourceArraySink &);  // no assignment operator
-};
-
-/**
- * Sink for ICU resource table contents.
- * The base class does nothing.
- *
- * Nested arrays and tables are stored as nested sinks,
- * never put() as ResourceValue items.
- */
-class U_COMMON_API ResourceTableSink : public UObject {
-public:
-    ResourceTableSink() {}
-    virtual ~ResourceTableSink();
-
-    /**
-     * Adds a key-value pair from a resource table.
-     *
-     * @param key resource key string
-     * @param value resource value
-     */
-    virtual void put(const char *key, const ResourceValue &value, UErrorCode &errorCode);
-
-    /**
-     * Adds a no-fallback/no-inheritance marker for this key.
-     * Used for CLDR no-fallback data values of (three empty-set symbols)=={2205, 2205, 2205}
-     * when enumerating tables with fallback from the specific resource bundle to root.
-     *
-     * The default implementation does nothing.
-     *
-     * @param key to be removed
-     */
-    virtual void putNoFallback(const char *key, UErrorCode &errorCode);
-
-    /**
-     * Returns a nested resource array for the key as another sink.
-     * Creates the sink if none exists for the key.
-     * Returns NULL if nested arrays are not supported.
-     * The default implementation always returns NULL.
-     *
-     * This sink (not the caller) owns the nested sink.
-     *
-     * @param key resource key string
-     * @param size number of array items
-     * @return nested-array sink, or NULL
-     */
-    virtual ResourceArraySink *getOrCreateArraySink(
-            const char *key, int32_t size, UErrorCode &errorCode);
-
-    /**
-     * Returns a nested resource table for the key as another sink.
-     * Creates the sink if none exists for the key.
-     * Returns NULL if nested tables are not supported.
-     * The default implementation always returns NULL.
-     *
-     * This sink (not the caller) owns the nested sink.
-     *
-     * @param key resource key string
-     * @param initialSize size hint for creating the sink if necessary
-     * @return nested-table sink, or NULL
-     */
-    virtual ResourceTableSink *getOrCreateTableSink(
-            const char *key, int32_t initialSize, UErrorCode &errorCode);
-
-    /**
-     * "Leaves" the table.
-     * Indicates that all of the resources and sub-resources of the current table
-     * have been enumerated.
-     */
-    virtual void leave(UErrorCode &errorCode);
-
-private:
-    ResourceTableSink(const ResourceTableSink &);  // no copy constructor
-    ResourceTableSink &operator=(const ResourceTableSink &);  // no assignment operator
+    ResourceSink(const ResourceSink &);  // no copy constructor
+    ResourceSink &operator=(const ResourceSink &);  // no assignment operator
 };
 
 U_NAMESPACE_END
diff --git a/src/third_party/icu/source/common/restrace.cpp b/src/third_party/icu/source/common/restrace.cpp
new file mode 100644
index 0000000..0391574
--- /dev/null
+++ b/src/third_party/icu/source/common/restrace.cpp
@@ -0,0 +1,136 @@
+// © 2019 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+#include "unicode/utypes.h"
+
+#if U_ENABLE_TRACING
+
+#include "restrace.h"
+#include "charstr.h"
+#include "cstring.h"
+#include "utracimp.h"
+#include "uresimp.h"
+#include "uassert.h"
+#include "util.h"
+
+U_NAMESPACE_BEGIN
+
+ResourceTracer::~ResourceTracer() = default;
+
+void ResourceTracer::trace(const char* resType) const {
+#if U_ENABLE_RESOURCE_TRACING
+    U_ASSERT(fResB || fParent);
+    UTRACE_ENTRY(UTRACE_UDATA_RESOURCE);
+    UErrorCode status = U_ZERO_ERROR;
+
+    CharString filePath;
+    getFilePath(filePath, status);
+
+    CharString resPath;
+    getResPath(resPath, status);
+
+    // The longest type ("intvector") is 9 chars
+    const char kSpaces[] = "         ";
+    CharString format;
+    format.append(kSpaces, sizeof(kSpaces) - 1 - uprv_strlen(resType), status);
+    format.append("(%s) %s @ %s", status);
+
+    UTRACE_DATA3(UTRACE_VERBOSE,
+        format.data(),
+        resType,
+        filePath.data(),
+        resPath.data());
+    UTRACE_EXIT_STATUS(status);
+#endif  // U_ENABLE_RESOURCE_TRACING
+}
+
+void ResourceTracer::traceOpen() const {
+#if U_ENABLE_RESOURCE_TRACING
+    U_ASSERT(fResB);
+    UTRACE_ENTRY(UTRACE_UDATA_BUNDLE);
+    UErrorCode status = U_ZERO_ERROR;
+
+    CharString filePath;
+    UTRACE_DATA1(UTRACE_VERBOSE, "%s", getFilePath(filePath, status).data());
+    UTRACE_EXIT_STATUS(status);
+#endif  // U_ENABLE_RESOURCE_TRACING
+}
+
+CharString& ResourceTracer::getFilePath(CharString& output, UErrorCode& status) const {
+    if (fResB) {
+        output.append(fResB->fData->fPath, status);
+        output.append('/', status);
+        output.append(fResB->fData->fName, status);
+        output.append(".res", status);
+    } else {
+        fParent->getFilePath(output, status);
+    }
+    return output;
+}
+
+CharString& ResourceTracer::getResPath(CharString& output, UErrorCode& status) const {
+    if (fResB) {
+        output.append('/', status);
+        output.append(fResB->fResPath, status);
+        // removing the trailing /
+        U_ASSERT(output[output.length()-1] == '/');
+        output.truncate(output.length()-1);
+    } else {
+        fParent->getResPath(output, status);
+    }
+    if (fKey) {
+        output.append('/', status);
+        output.append(fKey, status);
+    }
+    if (fIndex != -1) {
+        output.append('[', status);
+        UnicodeString indexString;
+        ICU_Utility::appendNumber(indexString, fIndex);
+        output.appendInvariantChars(indexString, status);
+        output.append(']', status);
+    }
+    return output;
+}
+
+void FileTracer::traceOpen(const char* path, const char* type, const char* name) {
+    if (uprv_strcmp(type, "res") == 0) {
+        traceOpenResFile(path, name);
+    } else {
+        traceOpenDataFile(path, type, name);
+    }
+}
+
+void FileTracer::traceOpenDataFile(const char* path, const char* type, const char* name) {
+    UTRACE_ENTRY(UTRACE_UDATA_DATA_FILE);
+    UErrorCode status = U_ZERO_ERROR;
+
+    CharString filePath;
+    filePath.append(path, status);
+    filePath.append('/', status);
+    filePath.append(name, status);
+    filePath.append('.', status);
+    filePath.append(type, status);
+
+    UTRACE_DATA1(UTRACE_VERBOSE, "%s", filePath.data());
+    UTRACE_EXIT_STATUS(status);
+}
+
+void FileTracer::traceOpenResFile(const char* path, const char* name) {
+#if U_ENABLE_RESOURCE_TRACING
+    UTRACE_ENTRY(UTRACE_UDATA_RES_FILE);
+    UErrorCode status = U_ZERO_ERROR;
+
+    CharString filePath;
+    filePath.append(path, status);
+    filePath.append('/', status);
+    filePath.append(name, status);
+    filePath.append(".res", status);
+
+    UTRACE_DATA1(UTRACE_VERBOSE, "%s", filePath.data());
+    UTRACE_EXIT_STATUS(status);
+#endif  // U_ENABLE_RESOURCE_TRACING
+}
+
+U_NAMESPACE_END
+
+#endif // U_ENABLE_TRACING
diff --git a/src/third_party/icu/source/common/restrace.h b/src/third_party/icu/source/common/restrace.h
new file mode 100644
index 0000000..ef29eae
--- /dev/null
+++ b/src/third_party/icu/source/common/restrace.h
@@ -0,0 +1,147 @@
+// © 2019 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+#ifndef __RESTRACE_H__
+#define __RESTRACE_H__
+
+#include "unicode/utypes.h"
+
+#if U_ENABLE_TRACING
+
+struct UResourceBundle;
+
+U_NAMESPACE_BEGIN
+
+class CharString;
+
+/**
+ * Instances of this class store information used to trace reads from resource
+ * bundles when ICU is built with --enable-tracing.
+ *
+ * All arguments of type const UResourceBundle*, const char*, and
+ * const ResourceTracer& are stored as pointers. The caller must retain
+ * ownership for the lifetime of this ResourceTracer.
+ *
+ * Exported as U_COMMON_API for Windows because it is a value field
+ * in other exported types.
+ */
+class U_COMMON_API ResourceTracer {
+public:
+    ResourceTracer() :
+        fResB(nullptr),
+        fParent(nullptr),
+        fKey(nullptr),
+        fIndex(-1) {}
+
+    ResourceTracer(const UResourceBundle* resB) :
+        fResB(resB),
+        fParent(nullptr),
+        fKey(nullptr),
+        fIndex(-1) {}
+
+    ResourceTracer(const UResourceBundle* resB, const char* key) :
+        fResB(resB),
+        fParent(nullptr),
+        fKey(key),
+        fIndex(-1) {}
+
+    ResourceTracer(const UResourceBundle* resB, int32_t index) :
+        fResB(resB),
+        fParent(nullptr),
+        fKey(nullptr),
+        fIndex(index) {}
+
+    ResourceTracer(const ResourceTracer& parent, const char* key) :
+        fResB(nullptr),
+        fParent(&parent),
+        fKey(key),
+        fIndex(-1) {}
+
+    ResourceTracer(const ResourceTracer& parent, int32_t index) :
+        fResB(nullptr),
+        fParent(&parent),
+        fKey(nullptr),
+        fIndex(index) {}
+
+    ~ResourceTracer();
+
+    void trace(const char* type) const;
+    void traceOpen() const;
+
+    /**
+     * Calls trace() if the resB or parent provided to the constructor was
+     * non-null; otherwise, does nothing.
+     */
+    void maybeTrace(const char* type) const {
+        if (fResB || fParent) {
+            trace(type);
+        }
+    }
+
+private:
+    const UResourceBundle* fResB;
+    const ResourceTracer* fParent;
+    const char* fKey;
+    int32_t fIndex;
+
+    CharString& getFilePath(CharString& output, UErrorCode& status) const;
+
+    CharString& getResPath(CharString& output, UErrorCode& status) const;
+};
+
+/**
+ * This class provides methods to trace data file reads when ICU is built
+ * with --enable-tracing.
+ */
+class FileTracer {
+public:
+    static void traceOpen(const char* path, const char* type, const char* name);
+
+private:
+    static void traceOpenDataFile(const char* path, const char* type, const char* name);
+    static void traceOpenResFile(const char* path, const char* name);
+};
+
+U_NAMESPACE_END
+
+#else // U_ENABLE_TRACING
+
+U_NAMESPACE_BEGIN
+
+/**
+ * Default trivial implementation when --enable-tracing is not used.
+ */
+class U_COMMON_API ResourceTracer {
+public:
+    ResourceTracer() {}
+
+    ResourceTracer(const void*) {}
+
+    ResourceTracer(const void*, const char*) {}
+
+    ResourceTracer(const void*, int32_t) {}
+
+    ResourceTracer(const ResourceTracer&, const char*) {}
+
+    ResourceTracer(const ResourceTracer&, int32_t) {}
+
+    void trace(const char*) const {}
+
+    void traceOpen() const {}
+
+    void maybeTrace(const char*) const {}
+};
+
+/**
+ * Default trivial implementation when --enable-tracing is not used.
+ */
+class FileTracer {
+public:
+    static void traceOpen(const char*, const char*, const char*) {}
+};
+
+U_NAMESPACE_END
+
+#endif // U_ENABLE_TRACING
+
+#endif //__RESTRACE_H__
diff --git a/src/third_party/icu/source/common/ruleiter.cpp b/src/third_party/icu/source/common/ruleiter.cpp
index 667795e..41eea23 100644
--- a/src/third_party/icu/source/common/ruleiter.cpp
+++ b/src/third_party/icu/source/common/ruleiter.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
 * Copyright (c) 2003-2011, International Business Machines
diff --git a/src/third_party/icu/source/common/ruleiter.h b/src/third_party/icu/source/common/ruleiter.h
index d8fe212..28e2ca5 100644
--- a/src/third_party/icu/source/common/ruleiter.h
+++ b/src/third_party/icu/source/common/ruleiter.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
 * Copyright (c) 2003-2011, International Business Machines
@@ -112,7 +114,7 @@
      * character.
      * @param options one or more of the following options, bitwise-OR-ed
      * together: PARSE_VARIABLES, PARSE_ESCAPES, SKIP_WHITESPACE.
-     * @param isEscaped output parameter set to TRUE if the character
+     * @param isEscaped output parameter set to true if the character
      * was escaped
      * @param ec input-output error code.  An error will only be set by
      * this routing if options includes PARSE_VARIABLES and an unknown
diff --git a/src/third_party/icu/source/common/schriter.cpp b/src/third_party/icu/source/common/schriter.cpp
index 17ce400..17b68ae 100644
--- a/src/third_party/icu/source/common/schriter.cpp
+++ b/src/third_party/icu/source/common/schriter.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 * Copyright (C) 1998-2012, International Business Machines Corporation and
@@ -99,7 +101,7 @@
         && end == realThat.end;
 }
 
-CharacterIterator*
+StringCharacterIterator*
 StringCharacterIterator::clone() const {
     return new StringCharacterIterator(*this);
 }
diff --git a/src/third_party/icu/source/common/serv.cpp b/src/third_party/icu/source/common/serv.cpp
index d1de373..e6d5140 100644
--- a/src/third_party/icu/source/common/serv.cpp
+++ b/src/third_party/icu/source/common/serv.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /**
 *******************************************************************************
 * Copyright (C) 2001-2014, International Business Machines Corporation.
@@ -9,7 +11,9 @@
 
 #if !UCONFIG_NO_SERVICE
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "serv.h"
 #include "umutex.h"
 
@@ -332,7 +336,7 @@
 ******************************************************************
 */
 
-static UMutex lock = U_MUTEX_INITIALIZER;
+static UMutex lock;
 
 ICUService::ICUService()
 : name()
@@ -546,16 +550,15 @@
             if (putInCache && cacheResult) {
                 serviceCache->put(result->actualDescriptor, result, status);
                 if (U_FAILURE(status)) {
-                    delete result;
                     return NULL;
                 }
 
                 if (cacheDescriptorList._obj != NULL) {
                     for (int32_t i = cacheDescriptorList._obj->size(); --i >= 0;) {
                         UnicodeString* desc = (UnicodeString*)cacheDescriptorList._obj->elementAt(i);
+
                         serviceCache->put(*desc, result, status);
                         if (U_FAILURE(status)) {
-                            delete result;
                             return NULL;
                         }
 
@@ -702,9 +705,9 @@
             }
 
             // fallback
-            UErrorCode status = U_ZERO_ERROR;
+            status = U_ZERO_ERROR;
             ICUServiceKey* fallbackKey = createKey(&id, status);
-            while (fallbackKey->fallback()) {
+            while (fallbackKey != NULL && fallbackKey->fallback()) {
                 UnicodeString us;
                 fallbackKey->currentID(us);
                 f = (ICUServiceFactory*)map->get(us);
diff --git a/src/third_party/icu/source/common/serv.h b/src/third_party/icu/source/common/serv.h
index 5100809..ca070b6 100644
--- a/src/third_party/icu/source/common/serv.h
+++ b/src/third_party/icu/source/common/serv.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /**
  *******************************************************************************
  * Copyright (C) 2001-2011, International Business Machines Corporation.       *
@@ -136,16 +138,16 @@
   * must eventually return false.  This implementation has no fallbacks
   * and always returns false.</p>
   *
-  * @return TRUE if the ICUServiceKey changed to a valid fallback value.
+  * @return true if the ICUServiceKey changed to a valid fallback value.
   */
   virtual UBool fallback();
 
  /**
-  * <p>Return TRUE if a key created from id matches, or would eventually
+  * <p>Return true if a key created from id matches, or would eventually
   * fallback to match, the canonical ID of this ICUServiceKey.</p>
   *
   * @param id the id to test.
-  * @return TRUE if this ICUServiceKey's canonical ID is a fallback of id.
+  * @return true if this ICUServiceKey's canonical ID is a fallback of id.
   */
   virtual UBool isFallbackOf(const UnicodeString& id) const;
 
@@ -289,15 +291,15 @@
  public:
   /**
    * <p>Construct a SimpleFactory that maps a single ID to a single 
-   * service instance.  If visible is TRUE, the ID will be visible.
+   * service instance.  If visible is true, the ID will be visible.
    * The instance must not be NULL.  The SimpleFactory will adopt
    * the instance, which must not be changed subsequent to this call.</p>
    *
    * @param instanceToAdopt the service instance to adopt.
    * @param id the ID to assign to this service instance.
-   * @param visible if TRUE, the ID will be visible.
+   * @param visible if true, the ID will be visible.
    */
-  SimpleFactory(UObject* instanceToAdopt, const UnicodeString& id, UBool visible = TRUE);
+  SimpleFactory(UObject* instanceToAdopt, const UnicodeString& id, UBool visible = true);
 
   /**
    * <p>Destructor.</p>
@@ -316,7 +318,7 @@
   virtual UObject* create(const ICUServiceKey& key, const ICUService* service, UErrorCode& status) const;
 
   /**
-   * <p>This implementation adds a mapping from ID -> this to result if visible is TRUE, 
+   * <p>This implementation adds a mapping from ID -> this to result if visible is true, 
    * otherwise it removes ID from result.</p>
    *
    * @param result the mapping table to update.
@@ -325,7 +327,7 @@
   virtual void updateVisibleIDs(Hashtable& result, UErrorCode& status) const;
 
   /**
-   * <p>This implementation returns the factory ID if it equals id and visible is TRUE,
+   * <p>This implementation returns the factory ID if it equals id and visible is true,
    * otherwise it returns the empty string.  (This implementation provides
    * no localized id information.)</p>
    *
@@ -425,8 +427,8 @@
                             UErrorCode& status);
 
   /**
-   * <p>Return TRUE if either string of the pair is bogus.</p>
-   * @return TRUE if either string of the pair is bogus.
+   * <p>Return true if either string of the pair is bogus.</p>
+   * @return true if either string of the pair is bogus.
    */
   UBool isBogus() const;
 
@@ -759,7 +761,7 @@
 
     /**
      * <p>A convenience override of registerInstance(UObject*, const UnicodeString&, UBool)
-     * that defaults visible to TRUE.</p>
+     * that defaults visible to true.</p>
      *
      * @param objToAdopt the object to register and adopt.
      * @param id the ID to assign to this object.
@@ -772,7 +774,7 @@
     /**
      * <p>Register a service instance with the provided ID.  The ID will be 
      * canonicalized.  The canonicalized ID will be returned by
-     * getVisibleIDs if visible is TRUE.  The service instance will be adopted and
+     * getVisibleIDs if visible is true.  The service instance will be adopted and
      * must not be modified subsequent to this call.</p>
      *
      * <p>This issues a serviceChanged notification to registered listeners.</p>
@@ -782,7 +784,7 @@
      *
      * @param objToAdopt the object to register and adopt.
      * @param id the ID to assign to this object.
-     * @param visible TRUE if getVisibleIDs is to return this ID.
+     * @param visible true if getVisibleIDs is to return this ID.
      * @param status the error code status.
      * @return a registry key that can be passed to unregister() to unregister
      * (and discard) this instance.
@@ -818,7 +820,7 @@
      *
      * @param rkey the registry key.
      * @param status the error code status.  
-     * @return TRUE if the call successfully unregistered the factory.
+     * @return true if the call successfully unregistered the factory.
      */
     virtual UBool unregister(URegistryKey rkey, UErrorCode& status);
 
@@ -831,9 +833,9 @@
     virtual void reset(void);
 
     /**
-     * <p>Return TRUE if the service is in its default state.</p>
+     * <p>Return true if the service is in its default state.</p>
      *
-     * <p>The default implementation returns TRUE if there are no 
+     * <p>The default implementation returns true if there are no 
      * factories registered.</p>
      */
     virtual UBool isDefault(void) const;
@@ -875,7 +877,7 @@
      *
      * @param instanceToAdopt the service instance to adopt.
      * @param id the ID to assign to this service instance.
-     * @param visible if TRUE, the ID will be visible.
+     * @param visible if true, the ID will be visible.
      * @param status the error code status.
      * @return an instance of ICUServiceFactory that maps this instance to the provided ID.
      */
@@ -883,7 +885,7 @@
 
     /**
      * <p>Reinitialize the factory list to its default state.  After this call, isDefault()
-     * must return TRUE.</p>
+     * must return true.</p>
      *
      * <p>This issues a serviceChanged notification to registered listeners.</p>
      *
@@ -926,7 +928,7 @@
      * different listeners.</p>
      *
      * @param l the listener to test.
-     * @return TRUE if the service accepts the listener.
+     * @return true if the service accepts the listener.
      */
     virtual UBool acceptsListener(const EventListener& l) const;
 
diff --git a/src/third_party/icu/source/common/servlk.cpp b/src/third_party/icu/source/common/servlk.cpp
index e693f21..f0bedf9 100644
--- a/src/third_party/icu/source/common/servlk.cpp
+++ b/src/third_party/icu/source/common/servlk.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /**
  *******************************************************************************
  * Copyright (C) 2001-2014, International Business Machines Corporation and    *
@@ -10,7 +12,9 @@
 
 #if !UCONFIG_NO_SERVICE
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/resbund.h"
 #include "uresimp.h"
 #include "cmemory.h"
diff --git a/src/third_party/icu/source/common/servlkf.cpp b/src/third_party/icu/source/common/servlkf.cpp
index 4e614b6..4cd7189 100644
--- a/src/third_party/icu/source/common/servlkf.cpp
+++ b/src/third_party/icu/source/common/servlkf.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /**
  *******************************************************************************
  * Copyright (C) 2001-2014, International Business Machines Corporation and    *
@@ -10,7 +12,9 @@
 
 #if !UCONFIG_NO_SERVICE
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/resbund.h"
 #include "uresimp.h"
 #include "cmemory.h"
diff --git a/src/third_party/icu/source/common/servloc.h b/src/third_party/icu/source/common/servloc.h
index 1054cd9..ccf6433 100644
--- a/src/third_party/icu/source/common/servloc.h
+++ b/src/third_party/icu/source/common/servloc.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /**
  *******************************************************************************
  * Copyright (C) 2001-2011, International Business Machines Corporation and    *
diff --git a/src/third_party/icu/source/common/servls.cpp b/src/third_party/icu/source/common/servls.cpp
index 0c83094..71464c8 100644
--- a/src/third_party/icu/source/common/servls.cpp
+++ b/src/third_party/icu/source/common/servls.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /**
  *******************************************************************************
  * Copyright (C) 2001-2014, International Business Machines Corporation and    *
@@ -10,7 +12,9 @@
 
 #if !UCONFIG_NO_SERVICE
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/resbund.h"
 #include "uresimp.h"
 #include "cmemory.h"
@@ -25,7 +29,6 @@
 
 U_NAMESPACE_BEGIN
 
-static UMutex llock = U_MUTEX_INITIALIZER;
 ICULocaleService::ICULocaleService()
   : fallbackLocale(Locale::getDefault())
 {
@@ -263,6 +266,7 @@
 {
     const Locale&     loc    = Locale::getDefault();
     ICULocaleService* ncThis = (ICULocaleService*)this;
+    static UMutex llock;
     {
         Mutex mutex(&llock);
         if (loc != fallbackLocale) {
diff --git a/src/third_party/icu/source/common/servnotf.cpp b/src/third_party/icu/source/common/servnotf.cpp
index 2415a0f..1fd1fd9 100644
--- a/src/third_party/icu/source/common/servnotf.cpp
+++ b/src/third_party/icu/source/common/servnotf.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /**
  *******************************************************************************
  * Copyright (C) 2001-2012, International Business Machines Corporation and    *
@@ -9,7 +11,9 @@
 
 #if !UCONFIG_NO_SERVICE
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "servnotf.h"
 #ifdef NOTIFIER_DEBUG
 #include <stdio.h>
@@ -20,7 +24,7 @@
 EventListener::~EventListener() {}
 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(EventListener)
 
-static UMutex notifyLock = U_MUTEX_INITIALIZER;
+static UMutex notifyLock;
 
 ICUNotifier::ICUNotifier(void) 
 : listeners(NULL) 
diff --git a/src/third_party/icu/source/common/servnotf.h b/src/third_party/icu/source/common/servnotf.h
index 362696f..305570c 100644
--- a/src/third_party/icu/source/common/servnotf.h
+++ b/src/third_party/icu/source/common/servnotf.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /**
  *******************************************************************************
  * Copyright (C) 2001-2014, International Business Machines Corporation and    *
@@ -103,7 +105,7 @@
     
 protected: 
     /**
-     * Subclasses implement this to return TRUE if the listener is
+     * Subclasses implement this to return true if the listener is
      * of the appropriate type.
      */
     virtual UBool acceptsListener(const EventListener& l) const = 0;
diff --git a/src/third_party/icu/source/common/servrbf.cpp b/src/third_party/icu/source/common/servrbf.cpp
index ac750a7..e6f73ee 100644
--- a/src/third_party/icu/source/common/servrbf.cpp
+++ b/src/third_party/icu/source/common/servrbf.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /**
  *******************************************************************************
  * Copyright (C) 2001-2014, International Business Machines Corporation and    *
@@ -10,7 +12,9 @@
 
 #if !UCONFIG_NO_SERVICE
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/resbund.h"
 #include "uresimp.h"
 #include "cmemory.h"
diff --git a/src/third_party/icu/source/common/servslkf.cpp b/src/third_party/icu/source/common/servslkf.cpp
index cb8aeee..2cd8504 100644
--- a/src/third_party/icu/source/common/servslkf.cpp
+++ b/src/third_party/icu/source/common/servslkf.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /**
  *******************************************************************************
  * Copyright (C) 2001-2014, International Business Machines Corporation and    *
@@ -10,7 +12,9 @@
 
 #if !UCONFIG_NO_SERVICE
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/resbund.h"
 #include "uresimp.h"
 #include "cmemory.h"
diff --git a/src/third_party/icu/source/common/sharedobject.cpp b/src/third_party/icu/source/common/sharedobject.cpp
index 392eaf9..20030a6 100644
--- a/src/third_party/icu/source/common/sharedobject.cpp
+++ b/src/third_party/icu/source/common/sharedobject.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 * Copyright (C) 2015, International Business Machines
@@ -5,9 +7,14 @@
 ******************************************************************************
 * sharedobject.cpp
 */
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
+#endif  // defined(STARBOARD)
 #include "sharedobject.h"
+#include "mutex.h"
 #include "uassert.h"
+#include "umutex.h"
+#include "unifiedcache.h"
 
 U_NAMESPACE_BEGIN
 
@@ -16,68 +23,41 @@
 UnifiedCacheBase::~UnifiedCacheBase() {}
 
 void
-SharedObject::addRef(UBool fromWithinCache) const {
-    umtx_atomic_inc(&totalRefCount);
-
-    // Although items in use may not be correct immediately, it
-    // will be correct eventually.
-    if (umtx_atomic_inc(&hardRefCount) == 1 && cachePtr != NULL) {
-        // If this object is cached, and the hardRefCount goes from 0 to 1,
-        // then the increment must happen from within the cache while the
-        // cache global mutex is locked. In this way, we can be rest assured
-        // that data races can't happen if the cache performs some task if
-        // the hardRefCount is zero while the global cache mutex is locked.
-        U_ASSERT(fromWithinCache);
-        cachePtr->incrementItemsInUse();
-    }
+SharedObject::addRef() const {
+    umtx_atomic_inc(&hardRefCount);
 }
 
+// removeRef Decrement the reference count and delete if it is zero.
+//           Note that SharedObjects with a non-null cachePtr are owned by the
+//           unified cache, and the cache will be responsible for the actual deletion.
+//           The deletion could be as soon as immediately following the
+//           update to the reference count, if another thread is running
+//           a cache eviction cycle concurrently.
+//           NO ACCESS TO *this PERMITTED AFTER REFERENCE COUNT == 0 for cached objects.
+//           THE OBJECT MAY ALREADY BE GONE.
 void
-SharedObject::removeRef(UBool fromWithinCache) const {
-    UBool decrementItemsInUse = (umtx_atomic_dec(&hardRefCount) == 0);
-    UBool allReferencesGone = (umtx_atomic_dec(&totalRefCount) == 0);
-
-    // Although items in use may not be correct immediately, it
-    // will be correct eventually.
-    if (decrementItemsInUse && cachePtr != NULL) {
-        if (fromWithinCache) {
-            cachePtr->decrementItemsInUse();
+SharedObject::removeRef() const {
+    const UnifiedCacheBase *cache = this->cachePtr;
+    int32_t updatedRefCount = umtx_atomic_dec(&hardRefCount);
+    U_ASSERT(updatedRefCount >= 0);
+    if (updatedRefCount == 0) {
+        if (cache) {
+            cache->handleUnreferencedObject();
         } else {
-            cachePtr->decrementItemsInUseWithLockingAndEviction();
+            delete this;
         }
     }
-    if (allReferencesGone) {
-        delete this;
-    }
 }
 
-void
-SharedObject::addSoftRef() const {
-    umtx_atomic_inc(&totalRefCount);
-    ++softRefCount;
-}
-
-void
-SharedObject::removeSoftRef() const {
-    --softRefCount;
-    if (umtx_atomic_dec(&totalRefCount) == 0) {
-        delete this;
-    }
-}
 
 int32_t
 SharedObject::getRefCount() const {
-    return umtx_loadAcquire(totalRefCount);
-}
-
-int32_t
-SharedObject::getHardRefCount() const {
     return umtx_loadAcquire(hardRefCount);
 }
 
 void
 SharedObject::deleteIfZeroRefCount() const {
-    if(getRefCount() == 0) {
+    if (this->cachePtr == nullptr && getRefCount() == 0) {
         delete this;
     }
 }
diff --git a/src/third_party/icu/source/common/sharedobject.h b/src/third_party/icu/source/common/sharedobject.h
index e5062cc..6ccfb27 100644
--- a/src/third_party/icu/source/common/sharedobject.h
+++ b/src/third_party/icu/source/common/sharedobject.h
@@ -1,6 +1,8 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
-* Copyright (C) 2015, International Business Machines
+* Copyright (C) 2015-2016, International Business Machines
 * Corporation and others.  All Rights Reserved.
 ******************************************************************************
 * sharedobject.h
@@ -15,6 +17,8 @@
 
 U_NAMESPACE_BEGIN
 
+class SharedObject;
+
 /**
  * Base class for unified cache exposing enough methods to SharedObject
  * instances to allow their addRef() and removeRef() methods to
@@ -26,22 +30,12 @@
     UnifiedCacheBase() { }
 
     /**
-     * Called by addRefWhileHoldingCacheLock() when the hard reference count
-     * of its instance goes from 0 to 1.
+     * Notify the cache implementation that an object was seen transitioning to
+     * zero hard references. The cache may use this to keep track the number of
+     * unreferenced SharedObjects, and to trigger evictions.
      */
-    virtual void incrementItemsInUse() const = 0;
+    virtual void handleUnreferencedObject() const = 0;
 
-    /**
-     * Called by removeRef() when the hard reference count of its instance
-     * drops from 1 to 0.
-     */
-    virtual void decrementItemsInUseWithLockingAndEviction() const = 0;
-
-    /**
-     * Called by removeRefWhileHoldingCacheLock() when the hard reference
-     * count of its instance drops from 1 to 0.
-     */
-    virtual void decrementItemsInUse() const = 0;
     virtual ~UnifiedCacheBase();
 private:
     UnifiedCacheBase(const UnifiedCacheBase &);
@@ -61,7 +55,6 @@
 public:
     /** Initializes totalRefCount, softRefCount to 0. */
     SharedObject() :
-            totalRefCount(0),
             softRefCount(0),
             hardRefCount(0),
             cachePtr(NULL) {}
@@ -69,7 +62,6 @@
     /** Initializes totalRefCount, softRefCount to 0. */
     SharedObject(const SharedObject &other) :
             UObject(other),
-            totalRefCount(0),
             softRefCount(0),
             hardRefCount(0),
             cachePtr(NULL) {}
@@ -77,93 +69,45 @@
     virtual ~SharedObject();
 
     /**
-     * Increments the number of references to this object. Thread-safe.
+     * Increments the number of hard references to this object. Thread-safe.
+     * Not for use from within the Unified Cache implementation.
      */
-    void addRef() const { addRef(FALSE); }
+    void addRef() const;
 
     /**
-     * Increments the number of references to this object.
-     * Must be called only from within the internals of UnifiedCache and
-     * only while the cache global mutex is held.
+     * Decrements the number of hard references to this object, and
+     * arrange for possible cache-eviction and/or deletion if ref
+     * count goes to zero. Thread-safe.
+     * 
+     * Not for use from within the UnifiedCache implementation.
      */
-    void addRefWhileHoldingCacheLock() const { addRef(TRUE); }
+    void removeRef() const;
 
     /**
-     * Increments the number of soft references to this object.
-     * Must be called only from within the internals of UnifiedCache and
-     * only while the cache global mutex is held.
-     */
-    void addSoftRef() const;
-
-    /**
-     * Decrements the number of references to this object. Thread-safe.
-     */
-    void removeRef() const { removeRef(FALSE); }
-
-    /**
-     * Decrements the number of references to this object.
-     * Must be called only from within the internals of UnifiedCache and
-     * only while the cache global mutex is held.
-     */
-    void removeRefWhileHoldingCacheLock() const { removeRef(TRUE); }
-
-    /**
-     * Decrements the number of soft references to this object.
-     * Must be called only from within the internals of UnifiedCache and
-     * only while the cache global mutex is held.
-     */
-    void removeSoftRef() const;
-
-    /**
-     * Returns the reference counter including soft references.
+     * Returns the number of hard references for this object.
      * Uses a memory barrier.
      */
     int32_t getRefCount() const;
 
     /**
-     * Returns the count of soft references only.
-     * Must be called only from within the internals of UnifiedCache and
-     * only while the cache global mutex is held.
-     */
-    int32_t getSoftRefCount() const { return softRefCount; }
-
-    /**
-     * Returns the count of hard references only. Uses a memory barrier.
-     * Used for testing the cache. Regular clients won't need this.
-     */
-    int32_t getHardRefCount() const;
-
-    /**
-     * If noHardReferences() == TRUE then this object has no hard references.
+     * If noHardReferences() == true then this object has no hard references.
      * Must be called only from within the internals of UnifiedCache.
      */
-    inline UBool noHardReferences() const { return getHardRefCount() == 0; }
+    inline UBool noHardReferences() const { return getRefCount() == 0; }
 
     /**
-     * If hasHardReferences() == TRUE then this object has hard references.
+     * If hasHardReferences() == true then this object has hard references.
      * Must be called only from within the internals of UnifiedCache.
      */
-    inline UBool hasHardReferences() const { return getHardRefCount() != 0; }
+    inline UBool hasHardReferences() const { return getRefCount() != 0; }
 
     /**
-     * If noSoftReferences() == TRUE then this object has no soft references.
-     * Must be called only from within the internals of UnifiedCache and
-     * only while the cache global mutex is held.
-     */
-    UBool noSoftReferences() const { return (softRefCount == 0); }
-
-    /**
-     * Deletes this object if it has no references or soft references.
+     * Deletes this object if it has no references.
+     * Available for non-cached SharedObjects only. Ownership of cached objects
+     * is with the UnifiedCache, which is solely responsible for eviction and deletion.
      */
     void deleteIfZeroRefCount() const;
 
-    /**
-     * @internal For UnifedCache use only to register this object with itself.
-     *   Must be called before this object is exposed to multiple threads.
-     */ 
-    void registerWithCache(const UnifiedCacheBase *ptr) const {
-        cachePtr = ptr;
-    }
         
     /**
      * Returns a writable version of ptr.
@@ -217,15 +161,21 @@
     }
 
 private:
-    mutable u_atomic_int32_t totalRefCount;
-
-    // Any thread modifying softRefCount must hold the global cache mutex
+    /**
+     * The number of references from the UnifiedCache, which is
+     * the number of times that the sharedObject is stored as a hash table value.
+     * For use by UnifiedCache implementation code only.
+     * All access is synchronized by UnifiedCache's gCacheMutex
+     */
     mutable int32_t softRefCount;
+    friend class UnifiedCache;
 
+    /**
+     * Reference count, excluding references from within the UnifiedCache implementation.
+     */
     mutable u_atomic_int32_t hardRefCount;
+    
     mutable const UnifiedCacheBase *cachePtr;
-    void addRef(UBool withCacheLock) const;
-    void removeRef(UBool withCacheLock) const;
 
 };
 
diff --git a/src/third_party/icu/source/common/simpleformatter.cpp b/src/third_party/icu/source/common/simpleformatter.cpp
new file mode 100644
index 0000000..f7f7aea
--- /dev/null
+++ b/src/third_party/icu/source/common/simpleformatter.cpp
@@ -0,0 +1,325 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+/*
+******************************************************************************
+* Copyright (C) 2014-2016, International Business Machines
+* Corporation and others.  All Rights Reserved.
+******************************************************************************
+* simpleformatter.cpp
+*/
+
+#include "unicode/utypes.h"
+#include "unicode/simpleformatter.h"
+#include "unicode/unistr.h"
+#include "uassert.h"
+
+U_NAMESPACE_BEGIN
+
+namespace {
+
+/**
+ * Argument numbers must be smaller than this limit.
+ * Text segment lengths are offset by this much.
+ * This is currently the only unused char value in compiled patterns,
+ * except it is the maximum value of the first unit (max arg +1).
+ */
+const int32_t ARG_NUM_LIMIT = 0x100;
+/**
+ * Initial and maximum char/UChar value set for a text segment.
+ * Segment length char values are from ARG_NUM_LIMIT+1 to this value here.
+ * Normally 0xffff, but can be as small as ARG_NUM_LIMIT+1 for testing.
+ */
+const UChar SEGMENT_LENGTH_PLACEHOLDER_CHAR = 0xffff;
+/**
+ * Maximum length of a text segment. Longer segments are split into shorter ones.
+ */
+const int32_t MAX_SEGMENT_LENGTH = SEGMENT_LENGTH_PLACEHOLDER_CHAR - ARG_NUM_LIMIT;
+
+enum {
+    APOS = 0x27,
+    DIGIT_ZERO = 0x30,
+    DIGIT_ONE = 0x31,
+    DIGIT_NINE = 0x39,
+    OPEN_BRACE = 0x7b,
+    CLOSE_BRACE = 0x7d
+};
+
+inline UBool isInvalidArray(const void *array, int32_t length) {
+   return (length < 0 || (array == NULL && length != 0));
+}
+
+}  // namespace
+
+SimpleFormatter &SimpleFormatter::operator=(const SimpleFormatter& other) {
+    if (this == &other) {
+        return *this;
+    }
+    compiledPattern = other.compiledPattern;
+    return *this;
+}
+
+SimpleFormatter::~SimpleFormatter() {}
+
+UBool SimpleFormatter::applyPatternMinMaxArguments(
+        const UnicodeString &pattern,
+        int32_t min, int32_t max,
+        UErrorCode &errorCode) {
+    if (U_FAILURE(errorCode)) {
+        return FALSE;
+    }
+    // Parse consistent with MessagePattern, but
+    // - support only simple numbered arguments
+    // - build a simple binary structure into the result string
+    const UChar *patternBuffer = pattern.getBuffer();
+    int32_t patternLength = pattern.length();
+    // Reserve the first char for the number of arguments.
+    compiledPattern.setTo((UChar)0);
+    int32_t textLength = 0;
+    int32_t maxArg = -1;
+    UBool inQuote = FALSE;
+    for (int32_t i = 0; i < patternLength;) {
+        UChar c = patternBuffer[i++];
+        if (c == APOS) {
+            if (i < patternLength && (c = patternBuffer[i]) == APOS) {
+                // double apostrophe, skip the second one
+                ++i;
+            } else if (inQuote) {
+                // skip the quote-ending apostrophe
+                inQuote = FALSE;
+                continue;
+            } else if (c == OPEN_BRACE || c == CLOSE_BRACE) {
+                // Skip the quote-starting apostrophe, find the end of the quoted literal text.
+                ++i;
+                inQuote = TRUE;
+            } else {
+                // The apostrophe is part of literal text.
+                c = APOS;
+            }
+        } else if (!inQuote && c == OPEN_BRACE) {
+            if (textLength > 0) {
+                compiledPattern.setCharAt(compiledPattern.length() - textLength - 1,
+                                          (UChar)(ARG_NUM_LIMIT + textLength));
+                textLength = 0;
+            }
+            int32_t argNumber;
+            if ((i + 1) < patternLength &&
+                    0 <= (argNumber = patternBuffer[i] - DIGIT_ZERO) && argNumber <= 9 &&
+                    patternBuffer[i + 1] == CLOSE_BRACE) {
+                i += 2;
+            } else {
+                // Multi-digit argument number (no leading zero) or syntax error.
+                // MessagePattern permits PatternProps.skipWhiteSpace(pattern, index)
+                // around the number, but this class does not.
+                argNumber = -1;
+                if (i < patternLength && DIGIT_ONE <= (c = patternBuffer[i++]) && c <= DIGIT_NINE) {
+                    argNumber = c - DIGIT_ZERO;
+                    while (i < patternLength &&
+                            DIGIT_ZERO <= (c = patternBuffer[i++]) && c <= DIGIT_NINE) {
+                        argNumber = argNumber * 10 + (c - DIGIT_ZERO);
+                        if (argNumber >= ARG_NUM_LIMIT) {
+                            break;
+                        }
+                    }
+                }
+                if (argNumber < 0 || c != CLOSE_BRACE) {
+                    errorCode = U_ILLEGAL_ARGUMENT_ERROR;
+                    return FALSE;
+                }
+            }
+            if (argNumber > maxArg) {
+                maxArg = argNumber;
+            }
+            compiledPattern.append((UChar)argNumber);
+            continue;
+        }  // else: c is part of literal text
+        // Append c and track the literal-text segment length.
+        if (textLength == 0) {
+            // Reserve a char for the length of a new text segment, preset the maximum length.
+            compiledPattern.append(SEGMENT_LENGTH_PLACEHOLDER_CHAR);
+        }
+        compiledPattern.append(c);
+        if (++textLength == MAX_SEGMENT_LENGTH) {
+            textLength = 0;
+        }
+    }
+    if (textLength > 0) {
+        compiledPattern.setCharAt(compiledPattern.length() - textLength - 1,
+                                  (UChar)(ARG_NUM_LIMIT + textLength));
+    }
+    int32_t argCount = maxArg + 1;
+    if (argCount < min || max < argCount) {
+        errorCode = U_ILLEGAL_ARGUMENT_ERROR;
+        return FALSE;
+    }
+    compiledPattern.setCharAt(0, (UChar)argCount);
+    return TRUE;
+}
+
+UnicodeString& SimpleFormatter::format(
+        const UnicodeString &value0,
+        UnicodeString &appendTo, UErrorCode &errorCode) const {
+    const UnicodeString *values[] = { &value0 };
+    return formatAndAppend(values, 1, appendTo, NULL, 0, errorCode);
+}
+
+UnicodeString& SimpleFormatter::format(
+        const UnicodeString &value0,
+        const UnicodeString &value1,
+        UnicodeString &appendTo, UErrorCode &errorCode) const {
+    const UnicodeString *values[] = { &value0, &value1 };
+    return formatAndAppend(values, 2, appendTo, NULL, 0, errorCode);
+}
+
+UnicodeString& SimpleFormatter::format(
+        const UnicodeString &value0,
+        const UnicodeString &value1,
+        const UnicodeString &value2,
+        UnicodeString &appendTo, UErrorCode &errorCode) const {
+    const UnicodeString *values[] = { &value0, &value1, &value2 };
+    return formatAndAppend(values, 3, appendTo, NULL, 0, errorCode);
+}
+
+UnicodeString& SimpleFormatter::formatAndAppend(
+        const UnicodeString *const *values, int32_t valuesLength,
+        UnicodeString &appendTo,
+        int32_t *offsets, int32_t offsetsLength, UErrorCode &errorCode) const {
+    if (U_FAILURE(errorCode)) {
+        return appendTo;
+    }
+    if (isInvalidArray(values, valuesLength) || isInvalidArray(offsets, offsetsLength) ||
+            valuesLength < getArgumentLimit()) {
+        errorCode = U_ILLEGAL_ARGUMENT_ERROR;
+        return appendTo;
+    }
+    return format(compiledPattern.getBuffer(), compiledPattern.length(), values,
+                  appendTo, NULL, TRUE,
+                  offsets, offsetsLength, errorCode);
+}
+
+UnicodeString &SimpleFormatter::formatAndReplace(
+        const UnicodeString *const *values, int32_t valuesLength,
+        UnicodeString &result,
+        int32_t *offsets, int32_t offsetsLength, UErrorCode &errorCode) const {
+    if (U_FAILURE(errorCode)) {
+        return result;
+    }
+    if (isInvalidArray(values, valuesLength) || isInvalidArray(offsets, offsetsLength)) {
+        errorCode = U_ILLEGAL_ARGUMENT_ERROR;
+        return result;
+    }
+    const UChar *cp = compiledPattern.getBuffer();
+    int32_t cpLength = compiledPattern.length();
+    if (valuesLength < getArgumentLimit(cp, cpLength)) {
+        errorCode = U_ILLEGAL_ARGUMENT_ERROR;
+        return result;
+    }
+
+    // If the pattern starts with an argument whose value is the same object
+    // as the result, then we keep the result contents and append to it.
+    // Otherwise we replace its contents.
+    int32_t firstArg = -1;
+    // If any non-initial argument value is the same object as the result,
+    // then we first copy its contents and use that instead while formatting.
+    UnicodeString resultCopy;
+    if (getArgumentLimit(cp, cpLength) > 0) {
+        for (int32_t i = 1; i < cpLength;) {
+            int32_t n = cp[i++];
+            if (n < ARG_NUM_LIMIT) {
+                if (values[n] == &result) {
+                    if (i == 2) {
+                        firstArg = n;
+                    } else if (resultCopy.isEmpty() && !result.isEmpty()) {
+                        resultCopy = result;
+                    }
+                }
+            } else {
+                i += n - ARG_NUM_LIMIT;
+            }
+        }
+    }
+    if (firstArg < 0) {
+        result.remove();
+    }
+    return format(cp, cpLength, values,
+                  result, &resultCopy, FALSE,
+                  offsets, offsetsLength, errorCode);
+}
+
+UnicodeString SimpleFormatter::getTextWithNoArguments(
+        const UChar *compiledPattern,
+        int32_t compiledPatternLength,
+        int32_t* offsets,
+        int32_t offsetsLength) {
+    for (int32_t i = 0; i < offsetsLength; i++) {
+        offsets[i] = -1;
+    }
+    int32_t capacity = compiledPatternLength - 1 -
+            getArgumentLimit(compiledPattern, compiledPatternLength);
+    UnicodeString sb(capacity, 0, 0);  // Java: StringBuilder
+    for (int32_t i = 1; i < compiledPatternLength;) {
+        int32_t n = compiledPattern[i++];
+        if (n > ARG_NUM_LIMIT) {
+            n -= ARG_NUM_LIMIT;
+            sb.append(compiledPattern + i, n);
+            i += n;
+        } else if (n < offsetsLength) {
+            // TODO(ICU-20406): This does not distinguish between "{0}{1}" and "{1}{0}".
+            // Consider removing this function and replacing it with an iterator interface.
+            offsets[n] = sb.length();
+        }
+    }
+    return sb;
+}
+
+UnicodeString &SimpleFormatter::format(
+        const UChar *compiledPattern, int32_t compiledPatternLength,
+        const UnicodeString *const *values,
+        UnicodeString &result, const UnicodeString *resultCopy, UBool forbidResultAsValue,
+        int32_t *offsets, int32_t offsetsLength,
+        UErrorCode &errorCode) {
+    if (U_FAILURE(errorCode)) {
+        return result;
+    }
+    for (int32_t i = 0; i < offsetsLength; i++) {
+        offsets[i] = -1;
+    }
+    for (int32_t i = 1; i < compiledPatternLength;) {
+        int32_t n = compiledPattern[i++];
+        if (n < ARG_NUM_LIMIT) {
+            const UnicodeString *value = values[n];
+            if (value == NULL) {
+                errorCode = U_ILLEGAL_ARGUMENT_ERROR;
+                return result;
+            }
+            if (value == &result) {
+                if (forbidResultAsValue) {
+                    errorCode = U_ILLEGAL_ARGUMENT_ERROR;
+                    return result;
+                }
+                if (i == 2) {
+                    // We are appending to result which is also the first value object.
+                    if (n < offsetsLength) {
+                        offsets[n] = 0;
+                    }
+                } else {
+                    if (n < offsetsLength) {
+                        offsets[n] = result.length();
+                    }
+                    result.append(*resultCopy);
+                }
+            } else {
+                if (n < offsetsLength) {
+                    offsets[n] = result.length();
+                }
+                result.append(*value);
+            }
+        } else {
+            int32_t length = n - ARG_NUM_LIMIT;
+            result.append(compiledPattern + i, length);
+            i += length;
+        }
+    }
+    return result;
+}
+
+U_NAMESPACE_END
diff --git a/src/third_party/icu/source/common/simplepatternformatter.cpp b/src/third_party/icu/source/common/simplepatternformatter.cpp
index fca27a8..ca7416c 100644
--- a/src/third_party/icu/source/common/simplepatternformatter.cpp
+++ b/src/third_party/icu/source/common/simplepatternformatter.cpp
@@ -5,8 +5,10 @@
 ******************************************************************************
 * simplepatternformatter.cpp
 */
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "simplepatternformatter.h"
 #include "cstring.h"
 #include "uassert.h"
diff --git a/src/third_party/icu/source/common/simplepatternformatter.h b/src/third_party/icu/source/common/simplepatternformatter.h
deleted file mode 100644
index 782a29c..0000000
--- a/src/third_party/icu/source/common/simplepatternformatter.h
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
-******************************************************************************
-* Copyright (C) 2014-2015, International Business Machines
-* Corporation and others.  All Rights Reserved.
-******************************************************************************
-* simplepatternformatter.h
-*/
-
-#ifndef __SIMPLEPATTERNFORMATTER_H__
-#define __SIMPLEPATTERNFORMATTER_H__ 
-
-#define EXPECTED_PLACEHOLDER_COUNT 3
-
-#include "cmemory.h"
-#include "unicode/utypes.h"
-#include "unicode/unistr.h"
-
-U_NAMESPACE_BEGIN
-
-class SimplePatternFormatterPlaceholderValues;
-
-struct PlaceholderInfo {
-  int32_t id;
-  int32_t offset;
-};
-
-/**
- * Compiled version of a pattern string such as "{1} was born in {0}".
- * <p>
- * Using SimplePatternFormatter is both faster and safer than adhoc replacement.
- * They are faster because they are precompiled; they are safer because they
- * account for curly braces escaped by apostrophe (').
- * 
- * Placeholders are of the form \{[0-9]+\}. If a curly brace is preceded
- * by a single quote, it becomes a curly brace instead of the start of a
- * placeholder. Two single quotes resolve to one single quote. 
- * <p>
- * Example:
- * <pre>
- * SimplePatternFormatter fmt("{1} '{born} in {0}");
- * UnicodeString result;
- * UErrorCode status = U_ZERO_ERROR;
- * // Evaluates to: "paul {born} in england"
- * fmt.format("england", "paul", result, status);
- * </pre>
- */
-class U_COMMON_API SimplePatternFormatter : public UMemory {
-public:
-    /**
-     * Default constructor
-     */
-    SimplePatternFormatter();
-
-    /**
-     * Constructs from a pattern. Will never fail if pattern has three or
-     * fewer placeholders in it.
-     */
-    explicit SimplePatternFormatter(const UnicodeString& pattern);
-
-    /**
-     * Constructs from a pattern. Will never fail if pattern has three or
-     * fewer placeholders in it.
-     *
-     * @param min The pattern must have at least this many placeholders.
-     * @param max The pattern must have at most this many placeholders.
-     */
-    SimplePatternFormatter(const UnicodeString& pattern, int32_t min, int32_t max,
-                           UErrorCode &errorCode);
-
-    /**
-     * Copy constructor.
-     */
-    SimplePatternFormatter(const SimplePatternFormatter& other);
-
-    /**
-     * Assignment operator
-     */
-    SimplePatternFormatter &operator=(const SimplePatternFormatter& other);
-
-    /**
-     * Destructor.
-     */
-    ~SimplePatternFormatter();
-
-    /**
-     * Compiles pattern and makes this object represent pattern.
-     *
-     * Returns TRUE on success; FALSE on failure. Will not fail if
-     * there are three or fewer placeholders in pattern. May fail with
-     * U_MEMORY_ALLOCATION_ERROR if there are more than three placeholders.
-     */
-    UBool compile(const UnicodeString &pattern, UErrorCode &status) {
-        return compileMinMaxPlaceholders(pattern, 0, INT32_MAX, status);
-    }
-
-    /**
-     * Compiles pattern and makes this object represent pattern.
-     *
-     * Returns TRUE on success; FALSE on failure. Will not fail if
-     * there are three or fewer placeholders in pattern. May fail with
-     * U_MEMORY_ALLOCATION_ERROR if there are more than three placeholders.
-     *
-     * @param min The pattern must have at least this many placeholders.
-     * @param max The pattern must have at most this many placeholders.
-     */
-    UBool compileMinMaxPlaceholders(const UnicodeString &pattern,
-                                    int32_t min, int32_t max, UErrorCode &status);
-
-    /**
-     * Returns (maxPlaceholderId + 1). For example
-     * <code>SimplePatternFormatter("{0} {2}").getPlaceholderCount()
-     * evaluates to 3.
-     * Callers use this function to find out how many values this object
-     * expects when formatting.
-     */
-    int32_t getPlaceholderCount() const {
-        return placeholderCount;
-    }
-
-    /**
-     * Returns this pattern with none of the placeholders.
-     */
-    const UnicodeString &getPatternWithNoPlaceholders() const {
-        return noPlaceholders;
-    }
-
-    /**
-     * Formats given value. arg0 cannot be appendTo.
-     */
-    UnicodeString &format(
-            const UnicodeString &args0,
-            UnicodeString &appendTo,
-            UErrorCode &status) const;
-    
-    /**
-     * Formats given values. Neither arg0 nor arg1 can be appendTo.
-     */
-    UnicodeString &format(
-            const UnicodeString &args0,
-            const UnicodeString &args1,
-            UnicodeString &appendTo,
-            UErrorCode &status) const;
-    
-    /**
-     * Formats given values. Neither arg0, arg1, nor arg2 can be appendTo.
-     */
-    UnicodeString &format(
-            const UnicodeString &args0,
-            const UnicodeString &args1,
-            const UnicodeString &args2,
-            UnicodeString &appendTo,
-            UErrorCode &status) const;
-    
-    /**
-     * Formats given values.
-     *
-     * The caller retains ownership of all pointers.
-     * @param placeholderValues 1st one corresponds to {0}; 2nd to {1};
-     *  3rd to {2} etc. If any of these point to appendTo, this method
-     *  sets status to U_ILLEGAL_ARGUMENT_ERROR.
-     * @param placeholderValueCount the number of placeholder values
-     *  must be at least large enough to provide values for all placeholders
-     *  in this object. Otherwise status set to U_ILLEGAL_ARGUMENT_ERROR.
-     * @param appendTo resulting string appended here.
-     * @param offsetArray The offset of each placeholder value in appendTo
-     *  stored here. The first value gets the offset of the value for {0};
-     *  the 2nd for {1}; the 3rd for {2} etc. -1 means that the corresponding
-     *  placeholder does not exist in this object. If caller is not
-     *  interested in offsets, it may pass NULL and 0 for the length.
-     * @param offsetArrayLength the size of offsetArray. If less than
-     *  placeholderValueCount only the first offsets get recorded. If
-     * greater than placeholderValueCount, then extra values in offset
-     * array are set to -1.
-     * @param status any error stored here.
-     */
-    UnicodeString &formatAndAppend(
-            const UnicodeString * const *placeholderValues,
-            int32_t placeholderValueCount,
-            UnicodeString &appendTo,
-            int32_t *offsetArray,
-            int32_t offsetArrayLength,
-            UErrorCode &status) const;
-
-    /**
-     * Formats given values.
-     *
-     * The caller retains ownership of all pointers.
-     * @param placeholderValues 1st one corresponds to {0}; 2nd to {1};
-     *  3rd to {2} etc. May include pointer to result in which case
-     *  the previous value of result is used for the corresponding
-     *  placeholder.
-     * @param placeholderValueCount the number of placeholder values
-     *  must be at least large enough to provide values for all placeholders
-     *  in this object. Otherwise status set to U_ILLEGAL_ARGUMENT_ERROR.
-     * @param result resulting string stored here overwriting any previous
-     *   value.
-     * @param offsetArray The offset of each placeholder value in result
-     *  stored here. The first value gets the offset of the value for {0};
-     *  the 2nd for {1}; the 3rd for {2} etc. -1 means that the corresponding
-     *  placeholder does not exist in this object. If caller is not
-     *  interested in offsets, it may pass NULL and 0 for the length.
-     * @param offsetArrayLength the size of offsetArray. If less than
-     *  placeholderValueCount only the first offsets get recorded. If
-     * greater than placeholderValueCount, then extra values in offset
-     * array are set to -1.
-     * @param status any error stored here.
-     */
-    UnicodeString &formatAndReplace(
-            const UnicodeString * const *placeholderValues,
-            int32_t placeholderValueCount,
-            UnicodeString &result,
-            int32_t *offsetArray,
-            int32_t offsetArrayLength,
-            UErrorCode &status) const;
-private:
-    UnicodeString noPlaceholders;
-    MaybeStackArray<PlaceholderInfo, 3> placeholders;
-    int32_t placeholderSize;
-    int32_t placeholderCount;
-    UBool firstPlaceholderReused;
-
-    // A Placeholder value that is the same as appendTo is treated as the
-    // empty string.
-    UnicodeString &formatAndAppend(
-            const SimplePatternFormatterPlaceholderValues &placeholderValues,
-            UnicodeString &appendTo,
-            int32_t *offsetArray,
-            int32_t offsetArrayLength) const;
-
-    // Returns the placeholder at the beginning of this pattern
-    // (e.g 3 for placeholder {3}). Returns -1 if the beginning of pattern
-    // is text or if the placeholder at the beginning of this pattern
-    // is used again in the middle of the pattern.
-    int32_t getUniquePlaceholderAtStart() const;
-    
-    // ensureCapacity ensures that the capacity of the placeholders array
-    // is desiredCapacity. If ensureCapacity must resize the placeholders
-    // array, the first placeholderSize elements stay in the array. Note
-    // that ensureCapcity NEVER changes the value of placeholderSize only
-    // the capacity of the placeholders array.
-    // If there is no memory allocation error when resizing, this
-    // function returns desiredCapacity. If there is a memory allocation
-    // error, this function leaves the placeholders array unchanged and
-    // returns the smaller, old capacity. ensureCapacity resizes only if
-    // the current capacity of placeholders array is less than desiredCapacity.
-    // Otherwise, it leaves the placeholders array unchanged. If caller
-    // specifies an allocation size, then it must be at least as large as
-    // desiredCapacity. In that case, if ensureCapacity resizes, it will
-    // allocate allocationSize spots instead of desiredCapacity spots in
-    // the array. If caller is calling ensureCapacity in a loop while adding
-    // elements, it is recommended that it use an allocationSize of
-    // approximately twice desiredCapacity to avoid memory allocation with
-    // every call to ensureCapacity.
-    int32_t ensureCapacity(int32_t desiredCapacity, int32_t allocationSize=0);
-
-    // Records the offset of an individual placeholder in the noPlaceholders
-    // string.
-    UBool addPlaceholder(int32_t id, int32_t offset);
-};
-
-U_NAMESPACE_END
-
-#endif
diff --git a/src/third_party/icu/source/common/sources.txt b/src/third_party/icu/source/common/sources.txt
new file mode 100644
index 0000000..e0410da
--- /dev/null
+++ b/src/third_party/icu/source/common/sources.txt
@@ -0,0 +1,196 @@
+appendable.cpp
+bmpset.cpp
+brkeng.cpp
+brkiter.cpp
+bytesinkutil.cpp
+bytestream.cpp
+bytestrie.cpp
+bytestriebuilder.cpp
+bytestrieiterator.cpp
+caniter.cpp
+characterproperties.cpp
+chariter.cpp
+charstr.cpp
+cmemory.cpp
+cstr.cpp
+cstring.cpp
+cwchar.cpp
+dictbe.cpp
+dictionarydata.cpp
+dtintrv.cpp
+edits.cpp
+errorcode.cpp
+filteredbrk.cpp
+filterednormalizer2.cpp
+icudataver.cpp
+icuplug.cpp
+loadednormalizer2impl.cpp
+localebuilder.cpp
+localematcher.cpp
+localeprioritylist.cpp
+locavailable.cpp
+locbased.cpp
+locdispnames.cpp
+locdistance.cpp
+locdspnm.cpp
+locid.cpp
+loclikely.cpp
+loclikelysubtags.cpp
+locmap.cpp
+locresdata.cpp
+locutil.cpp
+lsr.cpp
+messagepattern.cpp
+normalizer2.cpp
+normalizer2impl.cpp
+normlzr.cpp
+parsepos.cpp
+patternprops.cpp
+pluralmap.cpp
+propname.cpp
+propsvec.cpp
+punycode.cpp
+putil.cpp
+rbbi.cpp
+rbbi_cache.cpp
+rbbidata.cpp
+rbbinode.cpp
+rbbirb.cpp
+rbbiscan.cpp
+rbbisetb.cpp
+rbbistbl.cpp
+rbbitblb.cpp
+resbund.cpp
+resbund_cnv.cpp
+resource.cpp
+restrace.cpp
+ruleiter.cpp
+schriter.cpp
+serv.cpp
+servlk.cpp
+servlkf.cpp
+servls.cpp
+servnotf.cpp
+servrbf.cpp
+servslkf.cpp
+sharedobject.cpp
+simpleformatter.cpp
+static_unicode_sets.cpp
+stringpiece.cpp
+stringtriebuilder.cpp
+uarrsort.cpp
+ubidi.cpp
+ubidi_props.cpp
+ubidiln.cpp
+ubiditransform.cpp
+ubidiwrt.cpp
+ubrk.cpp
+ucase.cpp
+ucasemap.cpp
+ucasemap_titlecase_brkiter.cpp
+ucat.cpp
+uchar.cpp
+ucharstrie.cpp
+ucharstriebuilder.cpp
+ucharstrieiterator.cpp
+uchriter.cpp
+ucln_cmn.cpp
+ucmndata.cpp
+ucnv.cpp
+ucnv2022.cpp
+ucnv_bld.cpp
+ucnv_cb.cpp
+ucnv_cnv.cpp
+ucnv_ct.cpp
+ucnv_err.cpp
+ucnv_ext.cpp
+ucnv_io.cpp
+ucnv_lmb.cpp
+ucnv_set.cpp
+ucnv_u16.cpp
+ucnv_u32.cpp
+ucnv_u7.cpp
+ucnv_u8.cpp
+ucnvbocu.cpp
+ucnvdisp.cpp
+ucnvhz.cpp
+ucnvisci.cpp
+ucnvlat1.cpp
+ucnvmbcs.cpp
+ucnvscsu.cpp
+ucnvsel.cpp
+ucol_swp.cpp
+ucptrie.cpp
+ucurr.cpp
+udata.cpp
+udatamem.cpp
+udataswp.cpp
+uenum.cpp
+uhash.cpp
+uhash_us.cpp
+uidna.cpp
+uinit.cpp
+uinvchar.cpp
+uiter.cpp
+ulist.cpp
+uloc.cpp
+uloc_keytype.cpp
+uloc_tag.cpp
+umapfile.cpp
+umath.cpp
+umutablecptrie.cpp
+umutex.cpp
+unames.cpp
+unifiedcache.cpp
+unifilt.cpp
+unifunct.cpp
+uniset.cpp
+uniset_closure.cpp
+uniset_props.cpp
+unisetspan.cpp
+unistr.cpp
+unistr_case.cpp
+unistr_case_locale.cpp
+unistr_cnv.cpp
+unistr_props.cpp
+unistr_titlecase_brkiter.cpp
+unorm.cpp
+unormcmp.cpp
+uobject.cpp
+uprops.cpp
+ures_cnv.cpp
+uresbund.cpp
+uresdata.cpp
+usc_impl.cpp
+uscript.cpp
+uscript_props.cpp
+uset.cpp
+uset_props.cpp
+usetiter.cpp
+ushape.cpp
+usprep.cpp
+ustack.cpp
+ustr_cnv.cpp
+ustr_titlecase_brkiter.cpp
+ustr_wcs.cpp
+ustrcase.cpp
+ustrcase_locale.cpp
+ustrenum.cpp
+ustrfmt.cpp
+ustring.cpp
+ustrtrns.cpp
+utext.cpp
+utf_impl.cpp
+util.cpp
+util_props.cpp
+utrace.cpp
+utrie.cpp
+utrie2.cpp
+utrie2_builder.cpp
+utrie_swap.cpp
+uts46.cpp
+utypes.cpp
+uvector.cpp
+uvectr32.cpp
+uvectr64.cpp
+wintz.cpp
diff --git a/src/third_party/icu/source/common/sprpimpl.h b/src/third_party/icu/source/common/sprpimpl.h
index 1422cc3..ca0bcdb 100644
--- a/src/third_party/icu/source/common/sprpimpl.h
+++ b/src/third_party/icu/source/common/sprpimpl.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
  *******************************************************************************
  *
@@ -6,7 +8,7 @@
  *
  *******************************************************************************
  *   file name:  sprpimpl.h
- *   encoding:   US-ASCII
+ *   encoding:   UTF-8
  *   tab size:   8 (not used)
  *   indentation:4
  *
@@ -88,7 +90,6 @@
     UTrie sprepTrie;
     const uint16_t* mappingData;
     UDataMemory* sprepData;
-    const UBiDiProps *bdp; /* used only if checkBiDi is set */
     int32_t refCount;
     UBool isDataLoaded;
     UBool doNFKC;
diff --git a/src/third_party/icu/source/common/static_unicode_sets.cpp b/src/third_party/icu/source/common/static_unicode_sets.cpp
new file mode 100644
index 0000000..5dab393
--- /dev/null
+++ b/src/third_party/icu/source/common/static_unicode_sets.cpp
@@ -0,0 +1,245 @@
+// © 2018 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_FORMATTING
+
+// Allow implicit conversion from char16_t* to UnicodeString for this file:
+// Helpful in toString methods and elsewhere.
+#define UNISTR_FROM_STRING_EXPLICIT
+
+#include "static_unicode_sets.h"
+#include "umutex.h"
+#include "ucln_cmn.h"
+#include "unicode/uniset.h"
+#include "uresimp.h"
+#include "cstring.h"
+#include "uassert.h"
+
+using namespace icu;
+using namespace icu::unisets;
+
+
+namespace {
+
+UnicodeSet* gUnicodeSets[UNISETS_KEY_COUNT] = {};
+
+// Save the empty instance in static memory to have well-defined behavior if a
+// regular UnicodeSet cannot be allocated.
+alignas(UnicodeSet)
+char gEmptyUnicodeSet[sizeof(UnicodeSet)];
+
+// Whether the gEmptyUnicodeSet is initialized and ready to use.
+UBool gEmptyUnicodeSetInitialized = FALSE;
+
+inline UnicodeSet* getImpl(Key key) {
+    UnicodeSet* candidate = gUnicodeSets[key];
+    if (candidate == nullptr) {
+        return reinterpret_cast<UnicodeSet*>(gEmptyUnicodeSet);
+    }
+    return candidate;
+}
+
+UnicodeSet* computeUnion(Key k1, Key k2) {
+    UnicodeSet* result = new UnicodeSet();
+    if (result == nullptr) {
+        return nullptr;
+    }
+    result->addAll(*getImpl(k1));
+    result->addAll(*getImpl(k2));
+    result->freeze();
+    return result;
+}
+
+UnicodeSet* computeUnion(Key k1, Key k2, Key k3) {
+    UnicodeSet* result = new UnicodeSet();
+    if (result == nullptr) {
+        return nullptr;
+    }
+    result->addAll(*getImpl(k1));
+    result->addAll(*getImpl(k2));
+    result->addAll(*getImpl(k3));
+    result->freeze();
+    return result;
+}
+
+
+void saveSet(Key key, const UnicodeString& unicodeSetPattern, UErrorCode& status) {
+    // assert unicodeSets.get(key) == null;
+    gUnicodeSets[key] = new UnicodeSet(unicodeSetPattern, status);
+}
+
+class ParseDataSink : public ResourceSink {
+  public:
+    void put(const char* key, ResourceValue& value, UBool /*noFallback*/, UErrorCode& status) U_OVERRIDE {
+        ResourceTable contextsTable = value.getTable(status);
+        if (U_FAILURE(status)) { return; }
+        for (int i = 0; contextsTable.getKeyAndValue(i, key, value); i++) {
+            if (uprv_strcmp(key, "date") == 0) {
+                // ignore
+            } else {
+                ResourceTable strictnessTable = value.getTable(status);
+                if (U_FAILURE(status)) { return; }
+                for (int j = 0; strictnessTable.getKeyAndValue(j, key, value); j++) {
+                    bool isLenient = (uprv_strcmp(key, "lenient") == 0);
+                    ResourceArray array = value.getArray(status);
+                    if (U_FAILURE(status)) { return; }
+                    for (int k = 0; k < array.getSize(); k++) {
+                        array.getValue(k, value);
+                        UnicodeString str = value.getUnicodeString(status);
+                        if (U_FAILURE(status)) { return; }
+                        // There is both lenient and strict data for comma/period,
+                        // but not for any of the other symbols.
+                        if (str.indexOf(u'.') != -1) {
+                            saveSet(isLenient ? PERIOD : STRICT_PERIOD, str, status);
+                        } else if (str.indexOf(u',') != -1) {
+                            saveSet(isLenient ? COMMA : STRICT_COMMA, str, status);
+                        } else if (str.indexOf(u'+') != -1) {
+                            saveSet(PLUS_SIGN, str, status);
+                        } else if (str.indexOf(u'-') != -1) {
+                            saveSet(MINUS_SIGN, str, status);
+                        } else if (str.indexOf(u'$') != -1) {
+                            saveSet(DOLLAR_SIGN, str, status);
+                        } else if (str.indexOf(u'£') != -1) {
+                            saveSet(POUND_SIGN, str, status);
+                        } else if (str.indexOf(u'₹') != -1) {
+                            saveSet(RUPEE_SIGN, str, status);
+                        } else if (str.indexOf(u'¥') != -1) {
+                            saveSet(YEN_SIGN, str, status);
+                        } else if (str.indexOf(u'₩') != -1) {
+                            saveSet(WON_SIGN, str, status);
+                        } else if (str.indexOf(u'%') != -1) {
+                            saveSet(PERCENT_SIGN, str, status);
+                        } else if (str.indexOf(u'‰') != -1) {
+                            saveSet(PERMILLE_SIGN, str, status);
+                        } else if (str.indexOf(u'’') != -1) {
+                            saveSet(APOSTROPHE_SIGN, str, status);
+                        } else {
+                            // Unknown class of parse lenients
+                            // TODO(ICU-20428): Make ICU automatically accept new classes?
+                            U_ASSERT(FALSE);
+                        }
+                        if (U_FAILURE(status)) { return; }
+                    }
+                }
+            }
+        }
+    }
+};
+
+
+icu::UInitOnce gNumberParseUniSetsInitOnce = U_INITONCE_INITIALIZER;
+
+UBool U_CALLCONV cleanupNumberParseUniSets() {
+    if (gEmptyUnicodeSetInitialized) {
+        reinterpret_cast<UnicodeSet*>(gEmptyUnicodeSet)->~UnicodeSet();
+        gEmptyUnicodeSetInitialized = FALSE;
+    }
+    for (int32_t i = 0; i < UNISETS_KEY_COUNT; i++) {
+        delete gUnicodeSets[i];
+        gUnicodeSets[i] = nullptr;
+    }
+    gNumberParseUniSetsInitOnce.reset();
+    return TRUE;
+}
+
+void U_CALLCONV initNumberParseUniSets(UErrorCode& status) {
+    ucln_common_registerCleanup(UCLN_COMMON_NUMPARSE_UNISETS, cleanupNumberParseUniSets);
+
+    // Initialize the empty instance for well-defined fallback behavior
+    new(gEmptyUnicodeSet) UnicodeSet();
+    reinterpret_cast<UnicodeSet*>(gEmptyUnicodeSet)->freeze();
+    gEmptyUnicodeSetInitialized = TRUE;
+
+    // These sets were decided after discussion with icu-design@. See tickets #13084 and #13309.
+    // Zs+TAB is "horizontal whitespace" according to UTS #18 (blank property).
+    gUnicodeSets[DEFAULT_IGNORABLES] = new UnicodeSet(
+            u"[[:Zs:][\\u0009][:Bidi_Control:][:Variation_Selector:]]", status);
+    gUnicodeSets[STRICT_IGNORABLES] = new UnicodeSet(u"[[:Bidi_Control:]]", status);
+
+    LocalUResourceBundlePointer rb(ures_open(nullptr, "root", &status));
+    if (U_FAILURE(status)) { return; }
+    ParseDataSink sink;
+    ures_getAllItemsWithFallback(rb.getAlias(), "parse", sink, status);
+    if (U_FAILURE(status)) { return; }
+
+    // NOTE: It is OK for these assertions to fail if there was a no-data build.
+    U_ASSERT(gUnicodeSets[COMMA] != nullptr);
+    U_ASSERT(gUnicodeSets[STRICT_COMMA] != nullptr);
+    U_ASSERT(gUnicodeSets[PERIOD] != nullptr);
+    U_ASSERT(gUnicodeSets[STRICT_PERIOD] != nullptr);
+    U_ASSERT(gUnicodeSets[APOSTROPHE_SIGN] != nullptr);
+
+    LocalPointer<UnicodeSet> otherGrouping(new UnicodeSet(
+        u"[٬‘\\u0020\\u00A0\\u2000-\\u200A\\u202F\\u205F\\u3000]",
+        status
+    ), status);
+    if (U_FAILURE(status)) { return; }
+    otherGrouping->addAll(*gUnicodeSets[APOSTROPHE_SIGN]);
+    gUnicodeSets[OTHER_GROUPING_SEPARATORS] = otherGrouping.orphan();
+    gUnicodeSets[ALL_SEPARATORS] = computeUnion(COMMA, PERIOD, OTHER_GROUPING_SEPARATORS);
+    gUnicodeSets[STRICT_ALL_SEPARATORS] = computeUnion(
+            STRICT_COMMA, STRICT_PERIOD, OTHER_GROUPING_SEPARATORS);
+
+    U_ASSERT(gUnicodeSets[MINUS_SIGN] != nullptr);
+    U_ASSERT(gUnicodeSets[PLUS_SIGN] != nullptr);
+    U_ASSERT(gUnicodeSets[PERCENT_SIGN] != nullptr);
+    U_ASSERT(gUnicodeSets[PERMILLE_SIGN] != nullptr);
+
+    gUnicodeSets[INFINITY_SIGN] = new UnicodeSet(u"[∞]", status);
+    if (U_FAILURE(status)) { return; }
+
+    U_ASSERT(gUnicodeSets[DOLLAR_SIGN] != nullptr);
+    U_ASSERT(gUnicodeSets[POUND_SIGN] != nullptr);
+    U_ASSERT(gUnicodeSets[RUPEE_SIGN] != nullptr);
+    U_ASSERT(gUnicodeSets[YEN_SIGN] != nullptr);
+    U_ASSERT(gUnicodeSets[WON_SIGN] != nullptr);
+
+    gUnicodeSets[DIGITS] = new UnicodeSet(u"[:digit:]", status);
+    if (U_FAILURE(status)) { return; }
+    gUnicodeSets[DIGITS_OR_ALL_SEPARATORS] = computeUnion(DIGITS, ALL_SEPARATORS);
+    gUnicodeSets[DIGITS_OR_STRICT_ALL_SEPARATORS] = computeUnion(DIGITS, STRICT_ALL_SEPARATORS);
+
+    for (auto* uniset : gUnicodeSets) {
+        if (uniset != nullptr) {
+            uniset->freeze();
+        }
+    }
+}
+
+}
+
+const UnicodeSet* unisets::get(Key key) {
+    UErrorCode localStatus = U_ZERO_ERROR;
+    umtx_initOnce(gNumberParseUniSetsInitOnce, &initNumberParseUniSets, localStatus);
+    if (U_FAILURE(localStatus)) {
+        return reinterpret_cast<UnicodeSet*>(gEmptyUnicodeSet);
+    }
+    return getImpl(key);
+}
+
+Key unisets::chooseFrom(UnicodeString str, Key key1) {
+    return get(key1)->contains(str) ? key1 : NONE;
+}
+
+Key unisets::chooseFrom(UnicodeString str, Key key1, Key key2) {
+    return get(key1)->contains(str) ? key1 : chooseFrom(str, key2);
+}
+
+//Key unisets::chooseCurrency(UnicodeString str) {
+//    if (get(DOLLAR_SIGN)->contains(str)) {
+//        return DOLLAR_SIGN;
+//    } else if (get(POUND_SIGN)->contains(str)) {
+//        return POUND_SIGN;
+//    } else if (get(RUPEE_SIGN)->contains(str)) {
+//        return RUPEE_SIGN;
+//    } else if (get(YEN_SIGN)->contains(str)) {
+//        return YEN_SIGN;
+//    } else {
+//        return NONE;
+//    }
+//}
+
+
+#endif /* #if !UCONFIG_NO_FORMATTING */
diff --git a/src/third_party/icu/source/common/static_unicode_sets.h b/src/third_party/icu/source/common/static_unicode_sets.h
new file mode 100644
index 0000000..5d90ce5
--- /dev/null
+++ b/src/third_party/icu/source/common/static_unicode_sets.h
@@ -0,0 +1,140 @@
+// © 2018 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+// This file contains utilities to deal with static-allocated UnicodeSets.
+//
+// Common use case: you write a "private static final" UnicodeSet in Java, and
+// want something similarly easy in C++.  Originally written for number
+// parsing, but this header can be used for other applications.
+//
+// Main entrypoint: `unisets::get(unisets::MY_SET_ID_HERE)`
+//
+// This file is in common instead of i18n because it is needed by ucurr.cpp.
+//
+// Author: sffc
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_FORMATTING
+#ifndef __STATIC_UNICODE_SETS_H__
+#define __STATIC_UNICODE_SETS_H__
+
+#include "unicode/uniset.h"
+#include "unicode/unistr.h"
+
+U_NAMESPACE_BEGIN
+namespace unisets {
+
+enum Key {
+    // NONE is used to indicate null in chooseFrom().
+    // EMPTY is used to get an empty UnicodeSet.
+    NONE = -1,
+    EMPTY = 0,
+
+    // Ignorables
+    DEFAULT_IGNORABLES,
+    STRICT_IGNORABLES,
+
+    // Separators
+    // Notes:
+    // - COMMA is a superset of STRICT_COMMA
+    // - PERIOD is a superset of SCRICT_PERIOD
+    // - ALL_SEPARATORS is the union of COMMA, PERIOD, and OTHER_GROUPING_SEPARATORS
+    // - STRICT_ALL_SEPARATORS is the union of STRICT_COMMA, STRICT_PERIOD, and OTHER_GRP_SEPARATORS
+    COMMA,
+    PERIOD,
+    STRICT_COMMA,
+    STRICT_PERIOD,
+    APOSTROPHE_SIGN,
+    OTHER_GROUPING_SEPARATORS,
+    ALL_SEPARATORS,
+    STRICT_ALL_SEPARATORS,
+
+    // Symbols
+    MINUS_SIGN,
+    PLUS_SIGN,
+    PERCENT_SIGN,
+    PERMILLE_SIGN,
+    INFINITY_SIGN,
+
+    // Currency Symbols
+    DOLLAR_SIGN,
+    POUND_SIGN,
+    RUPEE_SIGN,
+    YEN_SIGN,
+    WON_SIGN,
+
+    // Other
+    DIGITS,
+
+    // Combined Separators with Digits (for lead code points)
+    DIGITS_OR_ALL_SEPARATORS,
+    DIGITS_OR_STRICT_ALL_SEPARATORS,
+
+    // The number of elements in the enum.
+    UNISETS_KEY_COUNT
+};
+
+/**
+ * Gets the static-allocated UnicodeSet according to the provided key. The
+ * pointer will be deleted during u_cleanup(); the caller should NOT delete it.
+ *
+ * Exported as U_COMMON_API for ucurr.cpp
+ *
+ * This method is always safe and OK to chain: in the case of a memory or other
+ * error, it returns an empty set from static memory.
+ * 
+ * Example:
+ * 
+ *     UBool hasIgnorables = unisets::get(unisets::DEFAULT_IGNORABLES)->contains(...);
+ *
+ * @param key The desired UnicodeSet according to the enum in this file.
+ * @return The requested UnicodeSet. Guaranteed to be frozen and non-null, but
+ *         may be empty if an error occurred during data loading.
+ */
+U_COMMON_API const UnicodeSet* get(Key key);
+
+/**
+ * Checks if the UnicodeSet given by key1 contains the given string.
+ *
+ * Exported as U_COMMON_API for numparse_decimal.cpp
+ *
+ * @param str The string to check.
+ * @param key1 The set to check.
+ * @return key1 if the set contains str, or NONE if not.
+ */
+U_COMMON_API Key chooseFrom(UnicodeString str, Key key1);
+
+/**
+ * Checks if the UnicodeSet given by either key1 or key2 contains the string.
+ *
+ * Exported as U_COMMON_API for numparse_decimal.cpp
+ *
+ * @param str The string to check.
+ * @param key1 The first set to check.
+ * @param key2 The second set to check.
+ * @return key1 if that set contains str; key2 if that set contains str; or
+ *         NONE if neither set contains str.
+ */
+U_COMMON_API Key chooseFrom(UnicodeString str, Key key1, Key key2);
+
+// TODO: Load these from data: ICU-20108
+// Unused in C++:
+// Key chooseCurrency(UnicodeString str);
+// Used instead:
+static const struct {
+    Key key;
+    UChar32 exemplar;
+} kCurrencyEntries[] = {
+    {DOLLAR_SIGN, u'$'},
+    {POUND_SIGN, u'£'},
+    {RUPEE_SIGN, u'₹'},
+    {YEN_SIGN, u'¥'},
+    {WON_SIGN, u'₩'},
+};
+
+} // namespace unisets
+U_NAMESPACE_END
+
+#endif //__STATIC_UNICODE_SETS_H__
+#endif /* #if !UCONFIG_NO_FORMATTING */
diff --git a/src/third_party/icu/source/common/stringpiece.cpp b/src/third_party/icu/source/common/stringpiece.cpp
index 007713e..99089e0 100644
--- a/src/third_party/icu/source/common/stringpiece.cpp
+++ b/src/third_party/icu/source/common/stringpiece.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 // Copyright (C) 2009-2013, International Business Machines
 // Corporation and others. All Rights Reserved.
 //
@@ -49,6 +51,47 @@
     length_ = 0;
 }
 
+int32_t StringPiece::find(StringPiece needle, int32_t offset) {
+  if (length() == 0 && needle.length() == 0) {
+    return 0;
+  }
+  // TODO: Improve to be better than O(N^2)?
+  for (int32_t i = offset; i < length(); i++) {
+    int32_t j = 0;
+    for (; j < needle.length(); i++, j++) {
+      if (data()[i] != needle.data()[j]) {
+        i -= j;
+        goto outer_end;
+      }
+    }
+    return i - j;
+    outer_end: void();
+  }
+  return -1;
+}
+
+int32_t StringPiece::compare(StringPiece other) {
+  int32_t i = 0;
+  for (; i < length(); i++) {
+    if (i == other.length()) {
+      // this is longer
+      return 1;
+    }
+    char a = data()[i];
+    char b = other.data()[i];
+    if (a < b) {
+      return -1;
+    } else if (a > b) {
+      return 1;
+    }
+  }
+  if (i < other.length()) {
+    // other is longer
+    return -1;
+  }
+  return 0;
+}
+
 U_EXPORT UBool U_EXPORT2
 operator==(const StringPiece& x, const StringPiece& y) {
   int32_t len = x.size();
@@ -68,14 +111,6 @@
 }
 
 
-/* Microsoft Visual Studio (even 2013) complains about redefinition of this
- * static const class variable. However, the C++ standard states that this
- * definition is correct. Perhaps there is a bug in the Microsoft compiler.
- * This is not an issue on any other compilers (that we know of).
- * Cygwin with MSVC 9.0 also complains here about redefinition.
- */
-#if (!defined(_MSC_VER) || (_MSC_VER > 1800)) && !defined(CYGWINMSVC)
 const int32_t StringPiece::npos = 0x7fffffff;
-#endif
 
 U_NAMESPACE_END
diff --git a/src/third_party/icu/source/common/stringtriebuilder.cpp b/src/third_party/icu/source/common/stringtriebuilder.cpp
index a496ea7..1153f14 100644
--- a/src/third_party/icu/source/common/stringtriebuilder.cpp
+++ b/src/third_party/icu/source/common/stringtriebuilder.cpp
@@ -1,10 +1,12 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *   Copyright (C) 2010-2012, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *******************************************************************************
 *   file name:  stringtriebuilder.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -12,8 +14,10 @@
 *   created by: Markus W. Scherer
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "utypeinfo.h"  // for 'typeid' to work
 #include "unicode/utypes.h"
 #include "unicode/stringtriebuilder.h"
@@ -377,7 +381,7 @@
     return newNode;
 }
 
-UBool
+int32_t
 StringTrieBuilder::hashNode(const void *node) {
     return ((const Node *)node)->hashCode();
 }
diff --git a/src/third_party/icu/source/common/uarrsort.c b/src/third_party/icu/source/common/uarrsort.cpp
similarity index 82%
rename from src/third_party/icu/source/common/uarrsort.c
rename to src/third_party/icu/source/common/uarrsort.cpp
index 043ac11..66cba24 100644
--- a/src/third_party/icu/source/common/uarrsort.c
+++ b/src/third_party/icu/source/common/uarrsort.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  uarrsort.c
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -16,7 +18,11 @@
 *   Internal function for sorting arrays.
 */
 
+#include <cstddef>
+
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/utypes.h"
 #include "cmemory.h"
 #include "uarrsort.h"
@@ -33,20 +39,27 @@
     STACK_ITEM_SIZE=200
 };
 
+static constexpr int32_t sizeInMaxAlignTs(int32_t sizeInBytes) {
+    return (sizeInBytes + sizeof(std::max_align_t) - 1) / sizeof(std::max_align_t);
+}
+
 /* UComparator convenience implementations ---------------------------------- */
 
 U_CAPI int32_t U_EXPORT2
 uprv_uint16Comparator(const void *context, const void *left, const void *right) {
+    (void)context;
     return (int32_t)*(const uint16_t *)left - (int32_t)*(const uint16_t *)right;
 }
 
 U_CAPI int32_t U_EXPORT2
 uprv_int32Comparator(const void *context, const void *left, const void *right) {
+    (void)context;
     return *(const int32_t *)left - *(const int32_t *)right;
 }
 
 U_CAPI int32_t U_EXPORT2
 uprv_uint32Comparator(const void *context, const void *left, const void *right) {
+    (void)context;
     uint32_t l=*(const uint32_t *)left, r=*(const uint32_t *)right;
 
     /* compare directly because (l-r) would overflow the int32_t result */
@@ -121,7 +134,7 @@
         if(insertionPoint<j) {
             char *dest=array+insertionPoint*itemSize;
             uprv_memcpy(pv, item, itemSize);  /* v=array[j] */
-            uprv_memmove(dest+itemSize, dest, (j-insertionPoint)*itemSize);
+            uprv_memmove(dest+itemSize, dest, (j-insertionPoint)*(size_t)itemSize);
             uprv_memcpy(dest, pv, itemSize);  /* array[insertionPoint]=v */
         }
     }
@@ -130,25 +143,15 @@
 static void
 insertionSort(char *array, int32_t length, int32_t itemSize,
               UComparator *cmp, const void *context, UErrorCode *pErrorCode) {
-    UAlignedMemory v[STACK_ITEM_SIZE/sizeof(UAlignedMemory)+1];
-    void *pv;
 
-    /* allocate an intermediate item variable (v) */
-    if(itemSize<=STACK_ITEM_SIZE) {
-        pv=v;
-    } else {
-        pv=uprv_malloc(itemSize);
-        if(pv==NULL) {
-            *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
-            return;
-        }
+    icu::MaybeStackArray<std::max_align_t, sizeInMaxAlignTs(STACK_ITEM_SIZE)> v;
+    if (sizeInMaxAlignTs(itemSize) > v.getCapacity() &&
+            v.resize(sizeInMaxAlignTs(itemSize)) == nullptr) {
+        *pErrorCode = U_MEMORY_ALLOCATION_ERROR;
+        return;
     }
 
-    doInsertionSort(array, length, itemSize, cmp, context, pv);
-
-    if(pv!=v) {
-        uprv_free(pv);
-    }
+    doInsertionSort(array, length, itemSize, cmp, context, v.getAlias());
 }
 
 /* QuickSort ---------------------------------------------------------------- */
@@ -182,7 +185,7 @@
         right=limit;
 
         /* x=array[middle] */
-        uprv_memcpy(px, array+((start+limit)/2)*itemSize, itemSize);
+        uprv_memcpy(px, array+(size_t)((start+limit)/2)*itemSize, itemSize);
 
         do {
             while(/* array[left]<x */
@@ -201,9 +204,9 @@
                 --right;
 
                 if(left<right) {
-                    uprv_memcpy(pw, array+left*itemSize, itemSize);
-                    uprv_memcpy(array+left*itemSize, array+right*itemSize, itemSize);
-                    uprv_memcpy(array+right*itemSize, pw, itemSize);
+                    uprv_memcpy(pw, array+(size_t)left*itemSize, itemSize);
+                    uprv_memcpy(array+(size_t)left*itemSize, array+(size_t)right*itemSize, itemSize);
+                    uprv_memcpy(array+(size_t)right*itemSize, pw, itemSize);
                 }
 
                 ++left;
@@ -234,26 +237,16 @@
 static void
 quickSort(char *array, int32_t length, int32_t itemSize,
             UComparator *cmp, const void *context, UErrorCode *pErrorCode) {
-    UAlignedMemory xw[(2*STACK_ITEM_SIZE)/sizeof(UAlignedMemory)+1];
-    void *p;
-
     /* allocate two intermediate item variables (x and w) */
-    if(itemSize<=STACK_ITEM_SIZE) {
-        p=xw;
-    } else {
-        p=uprv_malloc(2*itemSize);
-        if(p==NULL) {
-            *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
-            return;
-        }
+    icu::MaybeStackArray<std::max_align_t, sizeInMaxAlignTs(STACK_ITEM_SIZE) * 2> xw;
+    if(sizeInMaxAlignTs(itemSize)*2 > xw.getCapacity() &&
+            xw.resize(sizeInMaxAlignTs(itemSize) * 2) == nullptr) {
+        *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
+        return;
     }
 
-    subQuickSort(array, 0, length, itemSize,
-                 cmp, context, p, (char *)p+itemSize);
-
-    if(p!=xw) {
-        uprv_free(p);
-    }
+    subQuickSort(array, 0, length, itemSize, cmp, context,
+                 xw.getAlias(), xw.getAlias() + sizeInMaxAlignTs(itemSize));
 }
 
 /* uprv_sortArray() API ----------------------------------------------------- */
diff --git a/src/third_party/icu/source/common/uarrsort.h b/src/third_party/icu/source/common/uarrsort.h
index aece6da..a55dca5 100644
--- a/src/third_party/icu/source/common/uarrsort.h
+++ b/src/third_party/icu/source/common/uarrsort.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  uarrsort.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
diff --git a/src/third_party/icu/source/common/uassert.h b/src/third_party/icu/source/common/uassert.h
index e5aabc6..a42f823 100644
--- a/src/third_party/icu/source/common/uassert.h
+++ b/src/third_party/icu/source/common/uassert.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
@@ -8,30 +10,47 @@
 *
 * File uassert.h
 *
-*  Contains U_ASSERT macro
-*
-*    By default, U_ASSERT just wraps the C library assert macro.
-*    By changing the definition here, the assert behavior for ICU can be changed
-*    without affecting other non-ICU uses of the C library assert().
+*  Contains the U_ASSERT and UPRV_UNREACHABLE macros
 *
 ******************************************************************************
 */
-
 #ifndef U_ASSERT_H
 #define U_ASSERT_H
+
 /* utypes.h is included to get the proper define for uint8_t */
 #include "unicode/utypes.h"
+/* for abort */
+#include <stdlib.h>
+
+/**
+ * \def U_ASSERT
+ * By default, U_ASSERT just wraps the C library assert macro.
+ * By changing the definition here, the assert behavior for ICU can be changed
+ * without affecting other non - ICU uses of the C library assert().
+*/
 #if defined(STARBOARD)
 #include "starboard/configuration.h"
-#endif
+#endif  // defined(STARBOARD)
 #if U_DEBUG
 #if !defined(STARBOARD)
 #   include <assert.h>
 #endif
 #   define U_ASSERT(exp) assert(exp)
+#elif U_CPLUSPLUS_VERSION
+#   define U_ASSERT(exp) (void)0
 #else
 #   define U_ASSERT(exp)
 #endif
+
+/**
+ * \def UPRV_UNREACHABLE
+ * This macro is used to unconditionally abort if unreachable code is ever executed.
+ * @internal
+*/
+#if defined(UPRV_UNREACHABLE)
+    // Use the predefined value.
+#else
+#   define UPRV_UNREACHABLE abort()
 #endif
 
-
+#endif
diff --git a/src/third_party/icu/source/common/ubidi.c b/src/third_party/icu/source/common/ubidi.cpp
similarity index 95%
rename from src/third_party/icu/source/common/ubidi.c
rename to src/third_party/icu/source/common/ubidi.cpp
index f96b409..7d8b7a6 100644
--- a/src/third_party/icu/source/common/ubidi.c
+++ b/src/third_party/icu/source/common/ubidi.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 ******************************************************************************
 *   file name:  ubidi.c
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -15,7 +17,9 @@
 *
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
+#endif  // defined(STARBOARD)
 #include "cmemory.h"
 #include "unicode/utypes.h"
 #include "unicode/ustring.h"
@@ -108,7 +112,6 @@
  */
 
 /* to avoid some conditional statements, use tiny constant arrays */
-#include "starboard/client_porting/poem/string_poem.h"
 static const Flags flagLR[2]={ DIRPROP_FLAG(L), DIRPROP_FLAG(R) };
 static const Flags flagE[2]={ DIRPROP_FLAG(LRE), DIRPROP_FLAG(RLE) };
 static const Flags flagO[2]={ DIRPROP_FLAG(LRO), DIRPROP_FLAG(RLO) };
@@ -152,9 +155,6 @@
     /* reset the object, all pointers NULL, all flags FALSE, all sizes 0 */
     uprv_memset(pBiDi, 0, sizeof(UBiDi));
 
-    /* get BiDi properties */
-    pBiDi->bdp=ubidi_getSingleton();
-
     /* allocate memory for arrays as requested */
     if(maxLength>0) {
         if( !getInitialDirPropsMemory(pBiDi, maxLength) ||
@@ -447,12 +447,12 @@
     UBool removeBiDiControls = (UBool)(pBiDi->reorderingOptions &
                                        UBIDI_OPTION_REMOVE_CONTROLS);
 
-    typedef enum {
+    enum State {
          NOT_SEEKING_STRONG,            /* 0: not contextual paraLevel, not after FSI */
          SEEKING_STRONG_FOR_PARA,       /* 1: looking for first strong char in para */
          SEEKING_STRONG_FOR_FSI,        /* 2: looking for first strong after FSI */
          LOOKING_FOR_PDI                /* 3: found strong after FSI, looking for PDI */
-    } State;
+    };
     State state;
     DirProp lastStrong=ON;              /* for default level & inverse BiDi */
     /* The following stacks are used to manage isolate sequences. Those
@@ -466,7 +466,7 @@
     int32_t isolateStartStack[UBIDI_MAX_EXPLICIT_LEVEL+1];
     /* The following stack contains the last known state before
        encountering the initiator of an isolate sequence */
-    int8_t  previousStateStack[UBIDI_MAX_EXPLICIT_LEVEL+1];
+    State  previousStateStack[UBIDI_MAX_EXPLICIT_LEVEL+1];
     int32_t stackLast=-1;
 
     if(pBiDi->reorderingOptions & UBIDI_OPTION_STREAMING)
@@ -627,7 +627,7 @@
         pBiDi->paras[pBiDi->paraCount-1].level=1;
     }
     if(isDefaultLevel) {
-        pBiDi->paraLevel=pBiDi->paras[0].level;
+        pBiDi->paraLevel=static_cast<UBiDiLevel>(pBiDi->paras[0].level);
     }
     /* The following is needed to resolve the text direction for default level
        paragraphs containing no strong character */
@@ -677,7 +677,9 @@
     bd->isoRuns[0].start=0;
     bd->isoRuns[0].limit=0;
     bd->isoRuns[0].level=GET_PARALEVEL(pBiDi, 0);
-    bd->isoRuns[0].lastStrong=bd->isoRuns[0].lastBase=bd->isoRuns[0].contextDir=GET_PARALEVEL(pBiDi, 0)&1;
+    UBiDiLevel t = GET_PARALEVEL(pBiDi, 0) & 1;
+    bd->isoRuns[0].lastStrong = bd->isoRuns[0].lastBase = t;
+    bd->isoRuns[0].contextDir = (UBiDiDirection)t;
     bd->isoRuns[0].contextPos=0;
     if(pBiDi->openingsMemory) {
         bd->openings=pBiDi->openingsMemory;
@@ -696,7 +698,8 @@
     bd->isoRunLast=0;
     bd->isoRuns[0].limit=0;
     bd->isoRuns[0].level=level;
-    bd->isoRuns[0].lastStrong=bd->isoRuns[0].lastBase=bd->isoRuns[0].contextDir=level&1;
+    bd->isoRuns[0].lastStrong=bd->isoRuns[0].lastBase=level&1;
+    bd->isoRuns[0].contextDir=(UBiDiDirection)(level&1);
     bd->isoRuns[0].contextPos=0;
 }
 
@@ -712,8 +715,9 @@
         contextLevel=embeddingLevel;
     pLastIsoRun->limit=pLastIsoRun->start;
     pLastIsoRun->level=embeddingLevel;
-    pLastIsoRun->lastStrong=pLastIsoRun->lastBase=pLastIsoRun->contextDir=contextLevel&1;
-    pLastIsoRun->contextPos=lastCcPos;
+    pLastIsoRun->lastStrong=pLastIsoRun->lastBase=contextLevel&1;
+    pLastIsoRun->contextDir=(UBiDiDirection)(contextLevel&1);
+    pLastIsoRun->contextPos=(UBiDiDirection)lastCcPos;
 }
 
 /* LRI or RLI */
@@ -727,7 +731,8 @@
     pLastIsoRun++;
     pLastIsoRun->start=pLastIsoRun->limit=lastLimit;
     pLastIsoRun->level=level;
-    pLastIsoRun->lastStrong=pLastIsoRun->lastBase=pLastIsoRun->contextDir=level&1;
+    pLastIsoRun->lastStrong=pLastIsoRun->lastBase=level&1;
+    pLastIsoRun->contextDir=(UBiDiDirection)(level&1);
     pLastIsoRun->contextPos=0;
 }
 
@@ -801,7 +806,7 @@
     UBool stable;
     DirProp newProp;
     pOpening=&bd->openings[openIdx];
-    direction=pLastIsoRun->level&1;
+    direction=(UBiDiDirection)(pLastIsoRun->level&1);
     stable=TRUE;            /* assume stable until proved otherwise */
 
     /* The stable flag is set when brackets are paired and their
@@ -823,28 +828,28 @@
        N0c1. */
 
     if((direction==0 && pOpening->flags&FOUND_L) ||
-       (direction==1 && pOpening->flags&FOUND_R)) { /* N0b */
-        newProp=direction;
+       (direction==1 && pOpening->flags&FOUND_R)) {                         /* N0b */
+        newProp=static_cast<DirProp>(direction);
     }
-    else if(pOpening->flags&(FOUND_L|FOUND_R)) {    /* N0c */
+    else if(pOpening->flags&(FOUND_L|FOUND_R)) {                            /* N0c */
         /* it is stable if there is no containing pair or in
            conditions too complicated and not worth checking */
         stable=(openIdx==pLastIsoRun->start);
         if(direction!=pOpening->contextDir)
-            newProp=pOpening->contextDir;           /* N0c1 */
+            newProp= static_cast<DirProp>(pOpening->contextDir);           /* N0c1 */
         else
-            newProp=direction;                      /* N0c2 */
+            newProp= static_cast<DirProp>(direction);                      /* N0c2 */
     } else {
         /* forget this and any brackets nested within this pair */
-        pLastIsoRun->limit=openIdx;
-        return ON;                                  /* N0d */
+        pLastIsoRun->limit= static_cast<uint16_t>(openIdx);
+        return ON;                                                          /* N0d */
     }
     bd->pBiDi->dirProps[pOpening->position]=newProp;
     bd->pBiDi->dirProps[position]=newProp;
     /* Update nested N0c pairs that may be affected */
     fixN0c(bd, openIdx, pOpening->position, newProp);
     if(stable) {
-        pLastIsoRun->limit=openIdx; /* forget any brackets nested within this pair */
+        pLastIsoRun->limit= static_cast<uint16_t>(openIdx); /* forget any brackets nested within this pair */
         /* remove lower located synonyms if any */
         while(pLastIsoRun->limit>pLastIsoRun->start &&
               bd->openings[pLastIsoRun->limit-1].position==pOpening->position)
@@ -894,7 +899,7 @@
                 break;
             }
             pLastIsoRun->lastBase=ON;
-            pLastIsoRun->contextDir=newProp;
+            pLastIsoRun->contextDir=(UBiDiDirection)newProp;
             pLastIsoRun->contextPos=position;
             level=bd->pBiDi->levels[position];
             if(level&UBIDI_LEVEL_OVERRIDE) {    /* X4, X5 */
@@ -916,11 +921,11 @@
            bracket or it is a case of N0d */
         /* Now see if it is an opening bracket */
         if(c)
-            match=u_getBidiPairedBracket(c);    /* get the matching char */
+            match= static_cast<UChar>(u_getBidiPairedBracket(c));    /* get the matching char */
         else
             match=0;
         if(match!=c &&                  /* has a matching char */
-           ubidi_getPairedBracketType(bd->pBiDi->bdp, c)==U_BPT_OPEN) { /* opening bracket */
+           ubidi_getPairedBracketType(c)==U_BPT_OPEN) { /* opening bracket */
             /* special case: process synonyms
                create an opening entry for each synonym */
             if(match==0x232A) {     /* RIGHT-POINTING ANGLE BRACKET */
@@ -942,14 +947,14 @@
             dirProps[position]=newProp;
         pLastIsoRun->lastBase=newProp;
         pLastIsoRun->lastStrong=newProp;
-        pLastIsoRun->contextDir=newProp;
+        pLastIsoRun->contextDir=(UBiDiDirection)newProp;
         pLastIsoRun->contextPos=position;
     }
     else if(dirProp<=R || dirProp==AL) {
-        newProp=DIR_FROM_STRONG(dirProp);
+        newProp= static_cast<DirProp>(DIR_FROM_STRONG(dirProp));
         pLastIsoRun->lastBase=dirProp;
         pLastIsoRun->lastStrong=dirProp;
-        pLastIsoRun->contextDir=newProp;
+        pLastIsoRun->contextDir=(UBiDiDirection)newProp;
         pLastIsoRun->contextPos=position;
     }
     else if(dirProp==EN) {
@@ -958,7 +963,7 @@
             newProp=L;                  /* W7 */
             if(!bd->isNumbersSpecial)
                 dirProps[position]=ENL;
-            pLastIsoRun->contextDir=L;
+            pLastIsoRun->contextDir=(UBiDiDirection)L;
             pLastIsoRun->contextPos=position;
         }
         else {
@@ -967,14 +972,14 @@
                 dirProps[position]=AN;  /* W2 */
             else
                 dirProps[position]=ENR;
-            pLastIsoRun->contextDir=R;
+            pLastIsoRun->contextDir=(UBiDiDirection)R;
             pLastIsoRun->contextPos=position;
         }
     }
     else if(dirProp==AN) {
         newProp=R;                      /* N0 */
         pLastIsoRun->lastBase=AN;
-        pLastIsoRun->contextDir=R;
+        pLastIsoRun->contextDir=(UBiDiDirection)R;
         pLastIsoRun->contextPos=position;
     }
     else if(dirProp==NSM) {
@@ -1099,7 +1104,7 @@
             else
                 start=pBiDi->paras[paraIndex-1].limit;
             limit=pBiDi->paras[paraIndex].limit;
-            level=pBiDi->paras[paraIndex].level;
+            level= static_cast<UBiDiLevel>(pBiDi->paras[paraIndex].level);
             for(i=start; i<limit; i++)
                 levels[i]=level;
         }
@@ -1117,7 +1122,7 @@
             else
                 start=pBiDi->paras[paraIndex-1].limit;
             limit=pBiDi->paras[paraIndex].limit;
-            level=pBiDi->paras[paraIndex].level;
+            level= static_cast<UBiDiLevel>(pBiDi->paras[paraIndex].level);
             for(i=start; i<limit; i++) {
                 levels[i]=level;
                 dirProp=dirProps[i];
@@ -1313,7 +1318,7 @@
                 previousLevel=embeddingLevel;
                 levels[i]=embeddingLevel;
                 if(!bracketProcessChar(&bracketData, i))
-                    return -1;
+                    return (UBiDiDirection)-1;
                 /* the dirProp may have been changed in bracketProcessChar() */
                 flags|=DIRPROP_FLAG(dirProps[i]);
                 break;
@@ -1343,18 +1348,20 @@
 static UBiDiDirection
 checkExplicitLevels(UBiDi *pBiDi, UErrorCode *pErrorCode) {
     DirProp *dirProps=pBiDi->dirProps;
-    DirProp dirProp;
     UBiDiLevel *levels=pBiDi->levels;
     int32_t isolateCount=0;
 
-    int32_t i, length=pBiDi->length;
+    int32_t length=pBiDi->length;
     Flags flags=0;  /* collect all directionalities in the text */
-    UBiDiLevel level;
     pBiDi->isolateCount=0;
 
-    for(i=0; i<length; ++i) {
-        level=levels[i];
-        dirProp=dirProps[i];
+    int32_t currentParaIndex = 0;
+    int32_t currentParaLimit = pBiDi->paras[0].limit;
+    int32_t currentParaLevel = pBiDi->paraLevel;
+
+    for(int32_t i=0; i<length; ++i) {
+        UBiDiLevel level=levels[i];
+        DirProp dirProp=dirProps[i];
         if(dirProp==LRI || dirProp==RLI) {
             isolateCount++;
             if(isolateCount>pBiDi->isolateCount)
@@ -1364,21 +1371,41 @@
             isolateCount--;
         else if(dirProp==B)
             isolateCount=0;
-        if(level&UBIDI_LEVEL_OVERRIDE) {
+
+        // optimized version of  int32_t currentParaLevel = GET_PARALEVEL(pBiDi, i);
+        if (pBiDi->defaultParaLevel != 0 &&
+                i == currentParaLimit && (currentParaIndex + 1) < pBiDi->paraCount) {
+            currentParaLevel = pBiDi->paras[++currentParaIndex].level;
+            currentParaLimit = pBiDi->paras[currentParaIndex].limit;
+        }
+
+        UBiDiLevel overrideFlag = level & UBIDI_LEVEL_OVERRIDE;
+        level &= ~UBIDI_LEVEL_OVERRIDE;
+        if (level < currentParaLevel || UBIDI_MAX_EXPLICIT_LEVEL < level) {
+            if (level == 0) {
+                if (dirProp == B) {
+                    // Paragraph separators are ok with explicit level 0.
+                    // Prevents reordering of paragraphs.
+                } else {
+                    // Treat explicit level 0 as a wildcard for the paragraph level.
+                    // Avoid making the caller guess what the paragraph level would be.
+                    level = (UBiDiLevel)currentParaLevel;
+                    levels[i] = level | overrideFlag;
+                }
+            } else {
+                // 1 <= level < currentParaLevel or UBIDI_MAX_EXPLICIT_LEVEL < level
+                /* level out of bounds */
+                *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
+                return UBIDI_LTR;
+            }
+        }
+        if (overrideFlag != 0) {
             /* keep the override flag in levels[i] but adjust the flags */
-            level&=~UBIDI_LEVEL_OVERRIDE;     /* make the range check below simpler */
             flags|=DIRPROP_FLAG_O(level);
         } else {
             /* set the flags */
             flags|=DIRPROP_FLAG_E(level)|DIRPROP_FLAG(dirProp);
         }
-        if((level<GET_PARALEVEL(pBiDi, i) &&
-            !((0==level)&&(dirProp==B))) ||
-           (UBIDI_MAX_EXPLICIT_LEVEL<level)) {
-            /* level out of bounds */
-            *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
-            return UBIDI_LTR;
-        }
     }
     if(flags&MASK_EMBEDDING)
         flags|=DIRPROP_FLAG_LR(pBiDi->paraLevel);
@@ -1772,7 +1799,7 @@
 
     if (pInsertPoints->capacity == 0)
     {
-        pInsertPoints->points=uprv_malloc(sizeof(Point)*FIRSTALLOC);
+        pInsertPoints->points=static_cast<Point *>(uprv_malloc(sizeof(Point)*FIRSTALLOC));
         if (pInsertPoints->points == NULL)
         {
             pInsertPoints->errorCode=U_MEMORY_ALLOCATION_ERROR;
@@ -1782,9 +1809,9 @@
     }
     if (pInsertPoints->size >= pInsertPoints->capacity) /* no room for new point */
     {
-        void * savePoints=pInsertPoints->points;
-        pInsertPoints->points=uprv_realloc(pInsertPoints->points,
-                                           pInsertPoints->capacity*2*sizeof(Point));
+        Point * savePoints=pInsertPoints->points;
+        pInsertPoints->points=static_cast<Point *>(uprv_realloc(pInsertPoints->points,
+                                           pInsertPoints->capacity*2*sizeof(Point)));
         if (pInsertPoints->points == NULL)
         {
             pInsertPoints->points=savePoints;
@@ -2023,8 +2050,7 @@
             break;
 
         default:                        /* we should never get here */
-            U_ASSERT(FALSE);
-            break;
+            UPRV_UNREACHABLE;
         }
     }
     if((addLevel) || (start < start0)) {
@@ -2227,8 +2253,7 @@
                 start2=i;
                 break;
             default:            /* we should never get here */
-                U_ASSERT(FALSE);
-                break;
+                UPRV_UNREACHABLE;
             }
         }
     }
@@ -2342,7 +2367,7 @@
 static void
 setParaRunsOnly(UBiDi *pBiDi, const UChar *text, int32_t length,
                 UBiDiLevel paraLevel, UErrorCode *pErrorCode) {
-    void *runsOnlyMemory = NULL;
+    int32_t *runsOnlyMemory = NULL;
     int32_t *visualMap;
     UChar *visualText;
     int32_t saveLength, saveTrailingWSStart;
@@ -2363,7 +2388,7 @@
         goto cleanup3;
     }
     /* obtain memory for mapping table and visual text */
-    runsOnlyMemory=uprv_malloc(length*(sizeof(int32_t)+sizeof(UChar)+sizeof(UBiDiLevel)));
+    runsOnlyMemory=static_cast<int32_t *>(uprv_malloc(length*(sizeof(int32_t)+sizeof(UChar)+sizeof(UBiDiLevel))));
     if(runsOnlyMemory==NULL) {
         *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
         goto cleanup3;
@@ -2385,7 +2410,7 @@
      * direction is not MIXED
      */
     levels=ubidi_getLevels(pBiDi, pErrorCode);
-    uprv_memcpy(saveLevels, levels, pBiDi->length*sizeof(UBiDiLevel));
+    uprv_memcpy(saveLevels, levels, (size_t)pBiDi->length*sizeof(UBiDiLevel));
     saveTrailingWSStart=pBiDi->trailingWSStart;
     saveLength=pBiDi->length;
     saveDirection=pBiDi->direction;
@@ -2514,7 +2539,7 @@
     if(saveLength>pBiDi->levelsSize) {
         saveLength=pBiDi->levelsSize;
     }
-    uprv_memcpy(pBiDi->levels, saveLevels, saveLength*sizeof(UBiDiLevel));
+    uprv_memcpy(pBiDi->levels, saveLevels, (size_t)saveLength*sizeof(UBiDiLevel));
     pBiDi->trailingWSStart=saveTrailingWSStart;
     if(pBiDi->runCount>1) {
         pBiDi->direction=UBIDI_MIXED;
@@ -2558,7 +2583,7 @@
     pBiDi->text=text;
     pBiDi->length=pBiDi->originalLength=pBiDi->resultLength=length;
     pBiDi->paraLevel=paraLevel;
-    pBiDi->direction=paraLevel&1;
+    pBiDi->direction=(UBiDiDirection)(paraLevel&1);
     pBiDi->paraCount=1;
 
     pBiDi->dirProps=NULL;
@@ -2702,8 +2727,7 @@
             break;
         default:
             /* we should never get here */
-            U_ASSERT(FALSE);
-            break;
+            UPRV_UNREACHABLE;
         }
         /*
          * If there are no external levels specified and there
@@ -2803,7 +2827,7 @@
         DirProp dirProp;
         for(i=0; i<pBiDi->paraCount; i++) {
             last=(pBiDi->paras[i].limit)-1;
-            level=pBiDi->paras[i].level;
+            level= static_cast<UBiDiLevel>(pBiDi->paras[i].level);
             if(level==0)
                 continue;           /* LTR paragraph */
             start= i==0 ? 0 : pBiDi->paras[i-1].limit;
@@ -3006,10 +3030,10 @@
     if( pBiDi->fnClassCallback == NULL ||
         (dir = (*pBiDi->fnClassCallback)(pBiDi->coClassCallback, c)) == U_BIDI_CLASS_DEFAULT )
     {
-        dir = ubidi_getClass(pBiDi->bdp, c);
+        dir = ubidi_getClass(c);
     }
     if(dir >= U_CHAR_DIRECTION_COUNT) {
-        dir = ON;
+        dir = (UCharDirection)ON;
     }
     return dir;
 }
diff --git a/src/third_party/icu/source/common/ubidi_props.c b/src/third_party/icu/source/common/ubidi_props.cpp
similarity index 64%
rename from src/third_party/icu/source/common/ubidi_props.c
rename to src/third_party/icu/source/common/ubidi_props.cpp
index 42d05f1..afcc4aa 100644
--- a/src/third_party/icu/source/common/ubidi_props.c
+++ b/src/third_party/icu/source/common/ubidi_props.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  ubidi_props.c
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -42,17 +44,12 @@
 #define INCLUDED_FROM_UBIDI_PROPS_C
 #include "ubidi_props_data.h"
 
-/* UBiDiProps singleton ----------------------------------------------------- */
-
-U_CFUNC const UBiDiProps *
-ubidi_getSingleton() {
-    return &ubidi_props_singleton;
-}
-
 /* set of property starts for UnicodeSet ------------------------------------ */
 
 static UBool U_CALLCONV
 _enumPropertyStartsRange(const void *context, UChar32 start, UChar32 end, uint32_t value) {
+    (void)end;
+    (void)value;
     /* add the start code point to the USet */
     const USetAdder *sa=(const USetAdder *)context;
     sa->add(sa->set, start);
@@ -60,7 +57,7 @@
 }
 
 U_CFUNC void
-ubidi_addPropertyStarts(const UBiDiProps *bdp, const USetAdder *sa, UErrorCode *pErrorCode) {
+ubidi_addPropertyStarts(const USetAdder *sa, UErrorCode *pErrorCode) {
     int32_t i, length;
     UChar32 c, start, limit;
 
@@ -72,19 +69,19 @@
     }
 
     /* add the start code point of each same-value range of the trie */
-    utrie2_enum(&bdp->trie, NULL, _enumPropertyStartsRange, sa);
+    utrie2_enum(&ubidi_props_singleton.trie, NULL, _enumPropertyStartsRange, sa);
 
     /* add the code points from the bidi mirroring table */
-    length=bdp->indexes[UBIDI_IX_MIRROR_LENGTH];
+    length=ubidi_props_singleton.indexes[UBIDI_IX_MIRROR_LENGTH];
     for(i=0; i<length; ++i) {
-        c=UBIDI_GET_MIRROR_CODE_POINT(bdp->mirrors[i]);
+        c=UBIDI_GET_MIRROR_CODE_POINT(ubidi_props_singleton.mirrors[i]);
         sa->addRange(sa->set, c, c+1);
     }
 
     /* add the code points from the Joining_Group array where the value changes */
-    start=bdp->indexes[UBIDI_IX_JG_START];
-    limit=bdp->indexes[UBIDI_IX_JG_LIMIT];
-    jgArray=bdp->jgArray;
+    start=ubidi_props_singleton.indexes[UBIDI_IX_JG_START];
+    limit=ubidi_props_singleton.indexes[UBIDI_IX_JG_LIMIT];
+    jgArray=ubidi_props_singleton.jgArray;
     for(;;) {
         prev=0;
         while(start<limit) {
@@ -99,11 +96,11 @@
             /* add the limit code point if the last value was not 0 (it is now start==limit) */
             sa->add(sa->set, limit);
         }
-        if(limit==bdp->indexes[UBIDI_IX_JG_LIMIT]) {
+        if(limit==ubidi_props_singleton.indexes[UBIDI_IX_JG_LIMIT]) {
             /* switch to the second Joining_Group range */
-            start=bdp->indexes[UBIDI_IX_JG_START2];
-            limit=bdp->indexes[UBIDI_IX_JG_LIMIT2];
-            jgArray=bdp->jgArray2;
+            start=ubidi_props_singleton.indexes[UBIDI_IX_JG_START2];
+            limit=ubidi_props_singleton.indexes[UBIDI_IX_JG_LIMIT2];
+            jgArray=ubidi_props_singleton.jgArray2;
         } else {
             break;
         }
@@ -117,14 +114,8 @@
 /* property access functions ------------------------------------------------ */
 
 U_CFUNC int32_t
-ubidi_getMaxValue(const UBiDiProps *bdp, UProperty which) {
-    int32_t max;
-
-    if(bdp==NULL) {
-        return -1;
-    }
-
-    max=bdp->indexes[UBIDI_MAX_VALUES_INDEX];
+ubidi_getMaxValue(UProperty which) {
+    int32_t max=ubidi_props_singleton.indexes[UBIDI_MAX_VALUES_INDEX];
     switch(which) {
     case UCHAR_BIDI_CLASS:
         return (max&UBIDI_CLASS_MASK);
@@ -140,19 +131,19 @@
 }
 
 U_CAPI UCharDirection
-ubidi_getClass(const UBiDiProps *bdp, UChar32 c) {
-    uint16_t props=UTRIE2_GET16(&bdp->trie, c);
+ubidi_getClass(UChar32 c) {
+    uint16_t props=UTRIE2_GET16(&ubidi_props_singleton.trie, c);
     return (UCharDirection)UBIDI_GET_CLASS(props);
 }
 
 U_CFUNC UBool
-ubidi_isMirrored(const UBiDiProps *bdp, UChar32 c) {
-    uint16_t props=UTRIE2_GET16(&bdp->trie, c);
+ubidi_isMirrored(UChar32 c) {
+    uint16_t props=UTRIE2_GET16(&ubidi_props_singleton.trie, c);
     return (UBool)UBIDI_GET_FLAG(props, UBIDI_IS_MIRRORED_SHIFT);
 }
 
 static UChar32
-getMirror(const UBiDiProps *bdp, UChar32 c, uint16_t props) {
+getMirror(UChar32 c, uint16_t props) {
     int32_t delta=UBIDI_GET_MIRROR_DELTA(props);
     if(delta!=UBIDI_ESC_MIRROR_DELTA) {
         return c+delta;
@@ -163,8 +154,8 @@
         int32_t i, length;
         UChar32 c2;
 
-        mirrors=bdp->mirrors;
-        length=bdp->indexes[UBIDI_IX_MIRROR_LENGTH];
+        mirrors=ubidi_props_singleton.mirrors;
+        length=ubidi_props_singleton.indexes[UBIDI_IX_MIRROR_LENGTH];
 
         /* linear search */
         for(i=0; i<length; ++i) {
@@ -184,80 +175,80 @@
 }
 
 U_CFUNC UChar32
-ubidi_getMirror(const UBiDiProps *bdp, UChar32 c) {
-    uint16_t props=UTRIE2_GET16(&bdp->trie, c);
-    return getMirror(bdp, c, props);
+ubidi_getMirror(UChar32 c) {
+    uint16_t props=UTRIE2_GET16(&ubidi_props_singleton.trie, c);
+    return getMirror(c, props);
 }
 
 U_CFUNC UBool
-ubidi_isBidiControl(const UBiDiProps *bdp, UChar32 c) {
-    uint16_t props=UTRIE2_GET16(&bdp->trie, c);
+ubidi_isBidiControl(UChar32 c) {
+    uint16_t props=UTRIE2_GET16(&ubidi_props_singleton.trie, c);
     return (UBool)UBIDI_GET_FLAG(props, UBIDI_BIDI_CONTROL_SHIFT);
 }
 
 U_CFUNC UBool
-ubidi_isJoinControl(const UBiDiProps *bdp, UChar32 c) {
-    uint16_t props=UTRIE2_GET16(&bdp->trie, c);
+ubidi_isJoinControl(UChar32 c) {
+    uint16_t props=UTRIE2_GET16(&ubidi_props_singleton.trie, c);
     return (UBool)UBIDI_GET_FLAG(props, UBIDI_JOIN_CONTROL_SHIFT);
 }
 
 U_CFUNC UJoiningType
-ubidi_getJoiningType(const UBiDiProps *bdp, UChar32 c) {
-    uint16_t props=UTRIE2_GET16(&bdp->trie, c);
+ubidi_getJoiningType(UChar32 c) {
+    uint16_t props=UTRIE2_GET16(&ubidi_props_singleton.trie, c);
     return (UJoiningType)((props&UBIDI_JT_MASK)>>UBIDI_JT_SHIFT);
 }
 
 U_CFUNC UJoiningGroup
-ubidi_getJoiningGroup(const UBiDiProps *bdp, UChar32 c) {
+ubidi_getJoiningGroup(UChar32 c) {
     UChar32 start, limit;
 
-    start=bdp->indexes[UBIDI_IX_JG_START];
-    limit=bdp->indexes[UBIDI_IX_JG_LIMIT];
+    start=ubidi_props_singleton.indexes[UBIDI_IX_JG_START];
+    limit=ubidi_props_singleton.indexes[UBIDI_IX_JG_LIMIT];
     if(start<=c && c<limit) {
-        return (UJoiningGroup)bdp->jgArray[c-start];
+        return (UJoiningGroup)ubidi_props_singleton.jgArray[c-start];
     }
-    start=bdp->indexes[UBIDI_IX_JG_START2];
-    limit=bdp->indexes[UBIDI_IX_JG_LIMIT2];
+    start=ubidi_props_singleton.indexes[UBIDI_IX_JG_START2];
+    limit=ubidi_props_singleton.indexes[UBIDI_IX_JG_LIMIT2];
     if(start<=c && c<limit) {
-        return (UJoiningGroup)bdp->jgArray2[c-start];
+        return (UJoiningGroup)ubidi_props_singleton.jgArray2[c-start];
     }
     return U_JG_NO_JOINING_GROUP;
 }
 
 U_CFUNC UBidiPairedBracketType
-ubidi_getPairedBracketType(const UBiDiProps *bdp, UChar32 c) {
-    uint16_t props=UTRIE2_GET16(&bdp->trie, c);
+ubidi_getPairedBracketType(UChar32 c) {
+    uint16_t props=UTRIE2_GET16(&ubidi_props_singleton.trie, c);
     return (UBidiPairedBracketType)((props&UBIDI_BPT_MASK)>>UBIDI_BPT_SHIFT);
 }
 
 U_CFUNC UChar32
-ubidi_getPairedBracket(const UBiDiProps *bdp, UChar32 c) {
-    uint16_t props=UTRIE2_GET16(&bdp->trie, c);
+ubidi_getPairedBracket(UChar32 c) {
+    uint16_t props=UTRIE2_GET16(&ubidi_props_singleton.trie, c);
     if((props&UBIDI_BPT_MASK)==0) {
         return c;
     } else {
-        return getMirror(bdp, c, props);
+        return getMirror(c, props);
     }
 }
 
 /* public API (see uchar.h) ------------------------------------------------- */
 
 U_CFUNC UCharDirection
-u_charDirection(UChar32 c) {   
-    return ubidi_getClass(&ubidi_props_singleton, c);
+u_charDirection(UChar32 c) {
+    return ubidi_getClass(c);
 }
 
 U_CFUNC UBool
 u_isMirrored(UChar32 c) {
-    return ubidi_isMirrored(&ubidi_props_singleton, c);
+    return ubidi_isMirrored(c);
 }
 
 U_CFUNC UChar32
 u_charMirror(UChar32 c) {
-    return ubidi_getMirror(&ubidi_props_singleton, c);
+    return ubidi_getMirror(c);
 }
 
-U_STABLE UChar32 U_EXPORT2
+U_CAPI UChar32 U_EXPORT2
 u_getBidiPairedBracket(UChar32 c) {
-    return ubidi_getPairedBracket(&ubidi_props_singleton, c);
+    return ubidi_getPairedBracket(c);
 }
diff --git a/src/third_party/icu/source/common/ubidi_props.h b/src/third_party/icu/source/common/ubidi_props.h
index 0533ed3..698ee9c 100644
--- a/src/third_party/icu/source/common/ubidi_props.h
+++ b/src/third_party/icu/source/common/ubidi_props.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  ubidi_props.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -29,46 +31,40 @@
 
 /* library API -------------------------------------------------------------- */
 
-struct UBiDiProps;
-typedef struct UBiDiProps UBiDiProps;
-
-U_CFUNC const UBiDiProps *
-ubidi_getSingleton(void);
-
 U_CFUNC void
-ubidi_addPropertyStarts(const UBiDiProps *bdp, const USetAdder *sa, UErrorCode *pErrorCode);
+ubidi_addPropertyStarts(const USetAdder *sa, UErrorCode *pErrorCode);
 
 /* property access functions */
 
 U_CFUNC int32_t
-ubidi_getMaxValue(const UBiDiProps *bdp, UProperty which);
+ubidi_getMaxValue(UProperty which);
 
 U_CAPI UCharDirection
-ubidi_getClass(const UBiDiProps *bdp, UChar32 c);
+ubidi_getClass(UChar32 c);
 
 U_CFUNC UBool
-ubidi_isMirrored(const UBiDiProps *bdp, UChar32 c);
+ubidi_isMirrored(UChar32 c);
 
 U_CFUNC UChar32
-ubidi_getMirror(const UBiDiProps *bdp, UChar32 c);
+ubidi_getMirror(UChar32 c);
 
 U_CFUNC UBool
-ubidi_isBidiControl(const UBiDiProps *bdp, UChar32 c);
+ubidi_isBidiControl(UChar32 c);
 
 U_CFUNC UBool
-ubidi_isJoinControl(const UBiDiProps *bdp, UChar32 c);
+ubidi_isJoinControl(UChar32 c);
 
 U_CFUNC UJoiningType
-ubidi_getJoiningType(const UBiDiProps *bdp, UChar32 c);
+ubidi_getJoiningType(UChar32 c);
 
 U_CFUNC UJoiningGroup
-ubidi_getJoiningGroup(const UBiDiProps *bdp, UChar32 c);
+ubidi_getJoiningGroup(UChar32 c);
 
 U_CFUNC UBidiPairedBracketType
-ubidi_getPairedBracketType(const UBiDiProps *bdp, UChar32 c);
+ubidi_getPairedBracketType(UChar32 c);
 
 U_CFUNC UChar32
-ubidi_getPairedBracket(const UBiDiProps *bdp, UChar32 c);
+ubidi_getPairedBracket(UChar32 c);
 
 /* file definitions --------------------------------------------------------- */
 
diff --git a/src/third_party/icu/source/common/ubidi_props_data.h b/src/third_party/icu/source/common/ubidi_props_data.h
index 3699708..7a34870 100644
--- a/src/third_party/icu/source/common/ubidi_props_data.h
+++ b/src/third_party/icu/source/common/ubidi_props_data.h
@@ -1,322 +1,337 @@
-/*
- * Copyright (C) 1999-2016, International Business Machines
- * Corporation and others.  All Rights Reserved.
- *
- * file name: ubidi_props_data.h
- *
- * machine-generated by: icu/tools/unicode/c/genprops/bidipropsbuilder.cpp
- */
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+//
+// Copyright (C) 1999-2016, International Business Machines
+// Corporation and others.  All Rights Reserved.
+//
+// file name: ubidi_props_data.h
+//
+// machine-generated by: icu/tools/unicode/c/genprops/bidipropsbuilder.cpp
 
-#ifndef INCLUDED_FROM_UBIDI_PROPS_C
-#   error This file must be #included from ubidi_props.c only.
-#endif
 
-static const UVersionInfo ubidi_props_dataVersion={8,0,0,0};
+#ifdef INCLUDED_FROM_UBIDI_PROPS_C
 
-static const int32_t ubidi_props_indexes[UBIDI_IX_TOP]={0x10,0x5ae8,0x5778,0x1a,0x620,0x8b8,0x10ac0,0x10af0,0,0,0,0,0,0,0,0x5502b6};
+static const UVersionInfo ubidi_props_dataVersion={0xd,0,0,0};
 
-static const uint16_t ubidi_props_trieIndex[11188]={
-0x34f,0x357,0x35f,0x367,0x37f,0x387,0x38f,0x397,0x36f,0x377,0x36f,0x377,0x36f,0x377,0x36f,0x377,
-0x36f,0x377,0x36f,0x377,0x39d,0x3a5,0x3ad,0x3b5,0x3bd,0x3c5,0x3c1,0x3c9,0x3d1,0x3d9,0x3d4,0x3dc,
-0x36f,0x377,0x36f,0x377,0x3e4,0x3ec,0x36f,0x377,0x36f,0x377,0x36f,0x377,0x3f2,0x3fa,0x402,0x40a,
-0x412,0x41a,0x422,0x42a,0x430,0x438,0x440,0x448,0x450,0x458,0x45e,0x466,0x46e,0x476,0x47e,0x486,
-0x492,0x48e,0x49a,0x404,0x404,0x4aa,0x46e,0x4a2,0x4b2,0x4b4,0x4bc,0x4c4,0x4cc,0x4cd,0x4d5,0x4dd,
-0x4e5,0x4cd,0x4ed,0x4f2,0x4e5,0x4cd,0x4fa,0x502,0x4cc,0x507,0x50f,0x4c4,0x514,0x36f,0x51c,0x520,
-0x528,0x529,0x531,0x539,0x4cc,0x541,0x549,0x4c4,0x4cc,0x36f,0x4d5,0x4c4,0x36f,0x36f,0x54f,0x36f,
-0x36f,0x555,0x55d,0x36f,0x36f,0x561,0x569,0x36f,0x56d,0x574,0x36f,0x57c,0x584,0x58b,0x513,0x36f,
-0x36f,0x593,0x59b,0x5a3,0x5ab,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x5b3,0x36f,0x5bb,0x36f,0x36f,0x36f,
-0x5c3,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x5cb,0x36f,0x36f,0x36f,0x5d3,0x5d3,0x4d9,0x4d9,0x36f,0x5d9,0x5e1,0x5bb,
-0x5f7,0x5e9,0x5e9,0x5ff,0x606,0x5ef,0x36f,0x36f,0x36f,0x60e,0x616,0x36f,0x36f,0x36f,0x618,0x620,
-0x628,0x36f,0x62f,0x637,0x36f,0x63f,0x36f,0x36f,0x647,0x64a,0x514,0x652,0x3e6,0x65a,0x36f,0x661,
-0x36f,0x666,0x36f,0x36f,0x36f,0x36f,0x66c,0x674,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x3bd,0x67c,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x684,0x68c,0x690,
-0x6a8,0x6ae,0x698,0x6a0,0x6b6,0x6be,0x6c2,0x58e,0x6ca,0x6d2,0x6da,0x36f,0x6e2,0x620,0x620,0x620,
-0x6f2,0x6fa,0x702,0x70a,0x70f,0x717,0x71f,0x6ea,0x727,0x72f,0x36f,0x735,0x73c,0x620,0x620,0x742,
-0x620,0x53f,0x746,0x620,0x74e,0x36f,0x36f,0x61d,0x620,0x620,0x620,0x620,0x620,0x620,0x620,0x620,
-0x620,0x620,0x620,0x620,0x620,0x756,0x620,0x620,0x620,0x620,0x620,0x75c,0x620,0x620,0x764,0x76c,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x620,0x620,0x620,0x620,0x77c,0x783,0x78b,0x774,
-0x79b,0x7a3,0x7ab,0x7b2,0x7ba,0x7c2,0x7c9,0x793,0x620,0x620,0x620,0x7d1,0x7d7,0x7dd,0x7e5,0x7ea,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x7f1,0x36f,0x36f,0x36f,0x7f9,0x36f,0x36f,0x36f,0x3bd,
-0x801,0x809,0x540,0x36f,0x80c,0x620,0x620,0x623,0x620,0x620,0x620,0x620,0x620,0x620,0x813,0x819,
-0x829,0x821,0x36f,0x36f,0x831,0x5c3,0x36f,0x396,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x620,0x7f8,
-0x3a4,0x36f,0x839,0x841,0x36f,0x849,0x7ea,0x36f,0x36f,0x36f,0x36f,0x851,0x36f,0x36f,0x618,0x395,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x620,0x620,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x839,0x620,0x53f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x858,0x36f,0x36f,0x85d,0x529,0x36f,0x36f,0x56f,0x620,0x617,0x36f,0x36f,0x865,0x36f,0x36f,0x36f,
-0x86d,0x874,0x5e9,0x87c,0x36f,0x36f,0x527,0x884,0x36f,0x88b,0x892,0x36f,0x4b2,0x897,0x36f,0x4cb,
-0x36f,0x89f,0x8a7,0x4cd,0x36f,0x8ab,0x4cc,0x8b3,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x8ba,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x8ce,0x8c2,0x8c6,0x46e,0x46e,0x46e,0x46e,0x46e,
-0x46e,0x46e,0x46e,0x46e,0x46e,0x46e,0x46e,0x46e,0x46e,0x8d6,0x46e,0x46e,0x46e,0x46e,0x8de,0x8e2,
-0x8ea,0x8f2,0x8f6,0x8fe,0x46e,0x46e,0x46e,0x902,0x90a,0x35f,0x912,0x91a,0x36f,0x36f,0x36f,0x922,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0xdbc,0xdbc,0xdfc,0xe3c,0xdbc,0xdbc,0xdbc,0xdbc,0xdbc,0xdbc,0xe74,0xeb4,0xef4,0xf04,0xf44,0xf50,
-0xdbc,0xdbc,0xf90,0xdbc,0xdbc,0xdbc,0xfc8,0x1008,0x1048,0x1088,0x10c0,0x1100,0x1140,0x1178,0x11b8,0x11f8,
-0xa40,0xa80,0xac0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0xafa,0x1a0,0x1a0,
-0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0xb37,0x1a0,0x1a0,0xb6c,0xbac,0x1a0,0xbec,0xc2c,0xc6c,
+static const int32_t ubidi_props_indexes[UBIDI_IX_TOP]={0x10,0x67ec,0x6200,0x28,0x620,0x8c8,0x10ac0,0x10d24,0,0,0,0,0,0,0,0x6502b6};
+
+static const uint16_t ubidi_props_trieIndex[12536]={
+0x37c,0x384,0x38c,0x394,0x3ac,0x3b4,0x3bc,0x3c4,0x39c,0x3a4,0x39c,0x3a4,0x39c,0x3a4,0x39c,0x3a4,
+0x39c,0x3a4,0x39c,0x3a4,0x3ca,0x3d2,0x3da,0x3e2,0x3ea,0x3f2,0x3ee,0x3f6,0x3fe,0x406,0x401,0x409,
+0x39c,0x3a4,0x39c,0x3a4,0x411,0x419,0x39c,0x3a4,0x39c,0x3a4,0x39c,0x3a4,0x41f,0x427,0x42f,0x437,
+0x43f,0x447,0x44f,0x457,0x45d,0x465,0x46d,0x475,0x47d,0x485,0x48b,0x493,0x49b,0x4a3,0x4ab,0x4b3,
+0x4bf,0x4bb,0x4c7,0x4cf,0x431,0x4df,0x4e6,0x4d7,0x4ee,0x4f0,0x4f8,0x500,0x508,0x509,0x511,0x519,
+0x521,0x509,0x529,0x52e,0x521,0x509,0x536,0x53e,0x508,0x546,0x54e,0x500,0x556,0x39c,0x55e,0x562,
+0x56a,0x56c,0x574,0x57c,0x508,0x584,0x58c,0x500,0x413,0x590,0x511,0x500,0x508,0x39c,0x598,0x39c,
+0x39c,0x59e,0x5a6,0x39c,0x39c,0x5aa,0x5b2,0x39c,0x5b6,0x5bd,0x39c,0x5c5,0x5cd,0x5d4,0x555,0x39c,
+0x39c,0x5dc,0x5e4,0x5ec,0x5f4,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x5fc,0x39c,0x604,0x39c,0x39c,0x39c,
+0x60c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x614,0x39c,0x39c,0x39c,0x61c,0x61c,0x515,0x515,0x39c,0x622,0x62a,0x604,
+0x640,0x632,0x632,0x648,0x64f,0x638,0x39c,0x39c,0x39c,0x657,0x65f,0x39c,0x39c,0x39c,0x661,0x669,
+0x671,0x39c,0x678,0x680,0x39c,0x688,0x56b,0x39c,0x545,0x690,0x556,0x698,0x413,0x6a0,0x39c,0x6a7,
+0x39c,0x6ac,0x39c,0x39c,0x39c,0x39c,0x6b2,0x6ba,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x3ea,0x6c2,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x6ca,0x6d2,0x6d6,
+0x6ee,0x6f4,0x6de,0x6e6,0x6fc,0x704,0x708,0x5d7,0x710,0x718,0x720,0x39c,0x728,0x669,0x669,0x669,
+0x738,0x740,0x748,0x750,0x755,0x75d,0x765,0x730,0x76d,0x775,0x39c,0x77b,0x782,0x669,0x669,0x669,
+0x669,0x582,0x788,0x669,0x790,0x39c,0x39c,0x666,0x669,0x669,0x669,0x669,0x669,0x669,0x669,0x669,
+0x669,0x669,0x669,0x669,0x669,0x798,0x669,0x669,0x669,0x669,0x669,0x79e,0x669,0x669,0x7a6,0x7ae,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x669,0x669,0x669,0x669,0x7be,0x7c6,0x7ce,0x7b6,
+0x7de,0x7e6,0x7ee,0x7f5,0x7fc,0x804,0x808,0x7d6,0x669,0x669,0x669,0x810,0x816,0x669,0x669,0x81c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x824,0x39c,0x39c,0x39c,0x82c,0x39c,0x39c,0x39c,0x3ea,
+0x834,0x83c,0x840,0x39c,0x848,0x669,0x669,0x66c,0x669,0x669,0x669,0x669,0x669,0x669,0x84f,0x855,
+0x865,0x85d,0x39c,0x39c,0x86d,0x60c,0x39c,0x3c3,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x669,0x82b,
+0x3d1,0x39c,0x875,0x87d,0x39c,0x885,0x88d,0x39c,0x39c,0x39c,0x39c,0x891,0x39c,0x39c,0x661,0x3c2,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x669,0x669,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x875,0x669,0x582,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x898,0x39c,0x39c,0x89d,0x56c,0x39c,0x39c,0x5b8,0x669,0x660,0x39c,0x39c,0x8a5,0x39c,0x39c,0x39c,
+0x8ad,0x8b4,0x632,0x8bc,0x39c,0x39c,0x58e,0x8c4,0x39c,0x8cc,0x8d3,0x39c,0x4ee,0x8d8,0x39c,0x507,
+0x39c,0x8e0,0x8e8,0x509,0x39c,0x8ec,0x508,0x8f4,0x39c,0x39c,0x39c,0x8fa,0x39c,0x39c,0x39c,0x901,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x915,0x909,0x90d,0x49b,0x49b,0x49b,0x49b,0x49b,
+0x49b,0x49b,0x49b,0x49b,0x49b,0x49b,0x49b,0x49b,0x49b,0x91d,0x49b,0x49b,0x49b,0x49b,0x925,0x929,
+0x931,0x939,0x93d,0x945,0x49b,0x49b,0x49b,0x949,0x951,0x38c,0x959,0x961,0x39c,0x39c,0x39c,0x969,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0xe70,0xe70,0xeb0,0xef0,0xe70,0xe70,0xe70,0xe70,0xe70,0xe70,0xf28,0xf68,0xfa8,0xfb8,0xff8,0x1004,
+0xe70,0xe70,0x1044,0xe70,0xe70,0xe70,0x107c,0x10bc,0x10fc,0x113c,0x1174,0x11b4,0x11f4,0x122c,0x126c,0x12ac,
+0xa40,0xa80,0xac0,0xaff,0x1a0,0x1a0,0xb3f,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0xb68,0x1a0,0x1a0,
+0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0xba8,0x1a0,0x1a0,0xbdd,0xc1d,0xc5d,0xc9d,0xcdd,0xd1d,
 0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,
-0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0xcac,
+0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0xd5d,
 0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,
-0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0xcac,
+0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0xd5d,
 0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,
-0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0xcac,
+0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0xd5d,
 0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,
-0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0xcac,
+0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0xd5d,
 0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,
-0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0xcac,
+0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0xd5d,
 0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,
-0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0xcac,
+0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0xd5d,
 0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,
-0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0xcac,
+0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0xd5d,
 0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,
-0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0xcac,
+0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0xd5d,
 0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,
-0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0xcac,
+0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0xd5d,
 0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,
-0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0xcac,
+0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0xd5d,
 0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,
-0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0xcac,
+0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0xd5d,
 0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,
-0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0xcac,
-0xcec,0xcfc,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,
-0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0xcac,
+0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0xd5d,
+0xd9d,0xdad,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,
+0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0xd5d,
 0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,
-0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0xcac,
+0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0xd5d,
 0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,
-0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0xcac,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x92a,0x36f,0x620,0x620,0x932,0x5c3,0x36f,0x4c5,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x93a,0x36f,0x36f,0x36f,0x941,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x404,0x404,0x404,0x404,0x404,0x404,0x404,0x404,0x949,0x404,0x404,0x404,0x404,0x404,0x404,0x404,
-0x951,0x955,0x404,0x404,0x404,0x404,0x965,0x95d,0x404,0x96d,0x404,0x404,0x975,0x97b,0x404,0x404,
-0x404,0x404,0x404,0x404,0x404,0x404,0x404,0x404,0x404,0x404,0x404,0x404,0x404,0x404,0x404,0x404,
-0x404,0x404,0x404,0x983,0x404,0x404,0x404,0x404,0x404,0x404,0x404,0x404,0x404,0x404,0x404,0x404,
-0x4cc,0x98b,0x992,0x999,0x3e6,0x99c,0x36f,0x36f,0x4b2,0x9a4,0x36f,0x9aa,0x3e6,0x9af,0x5d5,0x36f,
-0x36f,0x9b7,0x36f,0x36f,0x36f,0x36f,0x7f9,0x9bf,0x3e6,0x4cd,0x528,0x9c6,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x9cc,0x9d4,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x9d8,0x9e0,0x36f,
-0x36f,0x9e8,0x528,0x36f,0x36f,0x9f0,0x36f,0x36f,0x5b3,0x9f8,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x9fc,0x36f,0xa02,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0xa08,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x4e6,0xa10,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0xa17,0xa1f,0xa25,0x36f,0x36f,0x620,0x620,0xa2d,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x620,0x620,0x743,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0xa2f,0x36f,0xa36,0x36f,0xa32,0x36f,0xa39,0x36f,0xa41,0xa45,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x3bd,0xa4d,0x3bd,0xa54,
-0xa5b,0xa63,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x404,0x404,0x404,0x404,
-0x404,0x404,0xa6b,0x404,0x404,0x404,0x404,0x404,0x404,0x404,0x404,0x404,0x404,0x404,0x404,0x404,
-0x404,0x404,0x404,0x404,0x404,0x404,0x404,0x404,0x404,0x404,0x404,0x404,0x404,0x404,0x404,0x404,
-0x404,0x404,0x404,0x404,0x404,0x404,0x404,0x404,0x404,0x404,0x404,0x404,0x46e,0x46e,0x46e,0x46e,
-0x46e,0x46e,0x46e,0xa73,0x404,0x404,0x404,0x404,0x404,0x404,0x404,0x404,0x620,0xa7b,0x620,0x620,
-0x623,0xa80,0xa84,0x813,0xa8c,0x36f,0x36f,0xa92,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x620,0x620,0x620,0x620,0x620,0x620,0x620,0x620,0x620,0x620,0x620,0x620,
-0x620,0x620,0x620,0x620,0x620,0x620,0x620,0x80c,0x620,0xa9a,0x620,0x620,0x620,0x620,0x620,0x620,
-0x620,0x620,0xa9e,0xaa6,0x620,0x620,0x620,0x623,0x620,0x620,0xa9d,0x36f,0xa7b,0x620,0xaae,0x620,
-0xab6,0x815,0x36f,0x36f,0xac6,0x36f,0x36f,0x36f,0xacb,0x36f,0x5c3,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0xabe,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
-0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,0xabe,0xadb,0xad3,0xad3,0xad3,
-0xadc,0xadc,0xadc,0xadc,0x3bd,0x3bd,0x3bd,0x3bd,0x3bd,0x3bd,0x3bd,0xae4,0xadc,0xadc,0xadc,0xadc,
-0xadc,0xadc,0xadc,0xadc,0xadc,0xadc,0xadc,0xadc,0xadc,0xadc,0xadc,0xadc,0xadc,0xadc,0xadc,0xadc,
-0xadc,0xadc,0xadc,0xadc,0xadc,0xadc,0xadc,0xadc,0xadc,0xadc,0xadc,0xadc,0xadc,0xadc,0xadc,0xadc,
-0xadc,0xadc,0xadc,0xadc,0xadc,0xadc,0xadc,0xadc,0xadc,0xadc,0xadc,0xadc,0xadc,0xadc,0xadc,0xadc,
-0xadc,0xadc,0xadc,0xadc,0xadc,0xadc,0xadc,0xadc,0xadc,0xadc,0xadc,0xadc,0x12,0x12,0x12,0x12,
-0x12,0x12,0x12,0x12,0x12,8,7,8,9,7,0x12,0x12,0x12,0x12,0x12,0x12,
-0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,7,7,7,8,9,0xa,0xa,4,
-4,4,0xa,0xa,0x310a,0xf20a,0xa,3,6,3,6,6,2,2,2,2,
-2,2,2,2,2,2,6,0xa,0x500a,0xa,0xd00a,0xa,0xa,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0x510a,0xa,0xd20a,0xa,0xa,0xa,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0x510a,0xa,0xd20a,0xa,0x12,0,0,0,0,
+0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0xd5d,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x971,0x39c,0x669,0x669,0x979,0x60c,0x39c,0x501,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x981,0x39c,0x39c,0x39c,0x988,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x431,0x431,0x431,0x431,0x431,0x431,0x431,0x431,0x990,0x431,0x431,0x431,0x431,0x431,0x431,0x431,
+0x998,0x99c,0x431,0x431,0x431,0x431,0x9ac,0x9a4,0x431,0x9b4,0x431,0x431,0x9bc,0x9c2,0x431,0x431,
+0x431,0x431,0x431,0x431,0x431,0x431,0x431,0x431,0x9d2,0x9ca,0x431,0x431,0x431,0x431,0x431,0x431,
+0x431,0x431,0x431,0x9da,0x431,0x9e2,0x431,0x431,0x431,0x9e6,0x9ed,0x9f3,0x431,0x9f7,0x9ff,0x431,
+0x508,0xa07,0xa0e,0xa15,0x413,0xa18,0x39c,0x39c,0x4ee,0xa1f,0x39c,0xa25,0x413,0xa2a,0xa32,0x39c,
+0x39c,0xa37,0x39c,0x39c,0x39c,0x39c,0x82c,0xa3f,0x413,0x590,0x56b,0xa46,0x39c,0x39c,0x39c,0x39c,
+0x39c,0xa07,0xa4e,0x39c,0x39c,0xa56,0xa5e,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0xa62,0xa6a,0x39c,
+0x39c,0xa72,0x56b,0xa7a,0x39c,0xa80,0x39c,0x39c,0x5fc,0xa88,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0xa8d,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0xa94,0xa9c,0x39c,0x39c,0x39c,0xa9f,0x56b,0xaa7,
+0xaab,0xab3,0x39c,0xaba,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0xac1,0x39c,0x39c,0xacf,0xac9,0x39c,0x39c,0x39c,0xad7,0xadf,0x39c,0xae3,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x592,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0xaf0,0xaeb,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0xaf8,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0xaff,
+0x39c,0xb05,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0xa26,0x39c,0xb0b,0x39c,0x39c,0xb13,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x522,0xb1b,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0xb22,0xb2a,0xb30,0x39c,0x39c,0x669,0x669,0xb38,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x669,0x669,0x83f,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0xb3a,0x39c,0xb41,0x39c,0xb3d,0x39c,0xb44,0x39c,0xb4c,0xb50,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x3ea,0xb58,0x3ea,
+0xb5f,0xb66,0xb6e,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0xb76,0xb7e,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0xb05,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0xb83,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x431,0x431,0x431,
+0x431,0x431,0x431,0xb8b,0x431,0xb93,0xb93,0xb9a,0x431,0x431,0x431,0x431,0x431,0x431,0x431,0x431,
+0x431,0x431,0x431,0x431,0x431,0x431,0x431,0x431,0x431,0x431,0x431,0x431,0x431,0x431,0x431,0x431,
+0x90d,0x49b,0x49b,0x431,0x431,0x49b,0x49b,0x9f3,0x431,0x431,0x431,0x431,0x431,0x49b,0x49b,0x49b,
+0x49b,0x49b,0x49b,0x49b,0xba2,0x431,0x431,0x431,0x431,0x431,0x431,0x431,0x431,0x669,0xbaa,0x669,
+0x669,0x66c,0xbaf,0xbb3,0x84f,0xbbb,0x3be,0x39c,0xbc1,0x39c,0xbc6,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x779,0x39c,0x39c,0x39c,0x39c,0x669,0x669,0x669,0x669,0x669,0x669,0x669,0x669,0x669,0x669,0x669,
+0x669,0x669,0x669,0x669,0x669,0x669,0x669,0x669,0x669,0x669,0x669,0x669,0x669,0x669,0x669,0x669,
+0x669,0x669,0x669,0x66b,0x979,0x669,0x669,0x669,0x66c,0x669,0x669,0xbce,0x66e,0xbaa,0x669,0xbd6,
+0x669,0xbde,0xbe3,0x39c,0x39c,0x669,0x669,0x669,0xbeb,0x669,0x669,0x798,0x669,0x669,0x669,0x66c,
+0xbf2,0xbfa,0xc00,0xc05,0x39c,0x669,0x669,0x669,0x669,0xc0d,0x669,0x788,0xc15,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0xc1c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,
+0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0x39c,0xc1c,0xc2c,0xc24,0xc24,
+0xc24,0xc2d,0xc2d,0xc2d,0xc2d,0x3ea,0x3ea,0x3ea,0x3ea,0x3ea,0x3ea,0x3ea,0xc35,0xc2d,0xc2d,0xc2d,
+0xc2d,0xc2d,0xc2d,0xc2d,0xc2d,0xc2d,0xc2d,0xc2d,0xc2d,0xc2d,0xc2d,0xc2d,0xc2d,0xc2d,0xc2d,0xc2d,
+0xc2d,0xc2d,0xc2d,0xc2d,0xc2d,0xc2d,0xc2d,0xc2d,0xc2d,0xc2d,0xc2d,0xc2d,0xc2d,0xc2d,0xc2d,0xc2d,
+0xc2d,0xc2d,0xc2d,0xc2d,0xc2d,0xc2d,0xc2d,0xc2d,0xc2d,0xc2d,0xc2d,0xc2d,0xc2d,0xc2d,0xc2d,0xc2d,
+0xc2d,0xc2d,0xc2d,0xc2d,0xc2d,0xc2d,0xc2d,0xc2d,0xc2d,0xc2d,0xc2d,0xc2d,0xc2d,0x37b,0x37b,0x37b,
+0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,8,7,8,9,7,0x12,0x12,
+0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,7,7,7,8,
+9,0xa,0xa,4,4,4,0xa,0xa,0x310a,0xf20a,0xa,3,6,3,6,6,
+2,2,2,2,2,2,2,2,2,2,6,0xa,0x500a,0xa,0xd00a,0xa,
+0xa,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0x510a,0xa,0xd20a,0xa,0xa,
+0xa,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0x510a,0xa,0xd20a,0xa,0x12,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0x12,0x12,0x12,0x12,
-0x12,7,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,
-0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,6,0xa,4,4,
-4,4,0xa,0xa,0xa,0xa,0,0x900a,0xa,0xb2,0xa,0xa,4,4,2,2,
-0xa,0,0xa,0xa,0xa,2,0,0x900a,0xa,0xa,0xa,0xa,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0xa,0,0,0,0,0,0,0,0,0,0,0,0,
+0x12,0x12,0x12,0x12,0x12,7,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,
+0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,
+6,0xa,4,4,4,4,0xa,0xa,0xa,0xa,0,0x900a,0xa,0xb2,0xa,0xa,
+4,4,2,2,0xa,0,0xa,0xa,0xa,2,0,0x900a,0xa,0xa,0xa,0xa,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0xa,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0xa,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0xa,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0xa,0xa,0,
-0,0,0,0,0,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
-0xa,0xa,0xa,0xa,0,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
-0xa,0xa,0xa,0xa,0,0,0,0,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
-0xa,0xa,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
-0xa,0xa,0xa,0xa,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0xa,0xa,0,0,0,0,0,0,0,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0,0,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0,0,0,0,0,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
 0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
 0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
 0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
-0xb1,0xb1,0xb1,0xb1,0,0,0,0,0xa,0xa,0,0,0,0,0,0,
-0,0,0xa,0,0,0,0,0,0xa,0xa,0,0xa,0,0,0,0,
+0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0,0,0xa,0xa,0,0,
+0,0,0,0,0,0,0xa,0,0,0,0,0,0xa,0xa,0,0xa,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0xa,0,0,0,0,0,0,0,0,0,
-0,0,0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0xa,0,0,0,0,0,
+0,0,0,0,0,0,0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0xa,0,0,0xa,0xa,4,1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
+0,0,0,0,0,0,0xa,0,0,0xa,0xa,4,1,0xb1,0xb1,0xb1,
 0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
 0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
-0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,1,0xb1,1,0xb1,0xb1,1,0xb1,0xb1,1,0xb1,
+0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,1,0xb1,1,0xb1,0xb1,1,
+0xb1,0xb1,1,0xb1,1,1,1,1,1,1,1,1,1,1,1,1,
 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-1,1,1,1,1,1,1,1,5,5,5,5,5,5,0xa,0xa,
-0xd,4,4,0xd,6,0xd,0xa,0xa,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
-0xb1,0xb1,0xb1,0xd,0x8ad,0xd,0xd,0xd,0x4d,0xd,0x8d,0x8d,0x8d,0x8d,0x4d,0x8d,
-0x4d,0x8d,0x4d,0x4d,0x4d,0x4d,0x4d,0x8d,0x8d,0x8d,0x8d,0x4d,0x4d,0x4d,0x4d,0x4d,
-0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x2d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,
-0x8d,0x4d,0x4d,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
-0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,5,5,5,5,5,5,5,5,
-5,5,4,5,5,0xd,0x4d,0x4d,0xb1,0x8d,0x8d,0x8d,0xd,0x8d,0x8d,0x8d,
-0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,
-0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,
+1,1,1,1,1,1,1,1,1,1,1,1,5,5,5,5,
+5,5,0xa,0xa,0xd,4,4,0xd,6,0xd,0xa,0xa,0xb1,0xb1,0xb1,0xb1,
+0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xd,0x8ad,0xd,0xd,0xd,0x4d,0xd,0x8d,0x8d,
+0x8d,0x8d,0x4d,0x8d,0x4d,0x8d,0x4d,0x4d,0x4d,0x4d,0x4d,0x8d,0x8d,0x8d,0x8d,0x4d,
+0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x2d,0x4d,0x4d,0x4d,
+0x4d,0x4d,0x4d,0x4d,0x8d,0x4d,0x4d,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
+0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,5,5,5,5,
+5,5,5,5,5,5,4,5,5,0xd,0x4d,0x4d,0xb1,0x8d,0x8d,0x8d,
+0xd,0x8d,0x8d,0x8d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x8d,0x8d,0x8d,0x8d,
+0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x4d,0x4d,
 0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,
 0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,
-0x8d,0x4d,0x4d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x4d,0x8d,0x4d,0x8d,
-0x4d,0x4d,0x8d,0x8d,0xd,0x8d,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,5,0xa,0xb1,
-0xb1,0xb1,0xb1,0xb1,0xb1,0xd,0xd,0xb1,0xb1,0xa,0xb1,0xb1,0xb1,0xb1,0x8d,0x8d,
-2,2,2,2,2,2,2,2,2,2,0x4d,0x4d,0x4d,0xd,0xd,0x4d,
-0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xad,
-0x8d,0xb1,0x4d,0x4d,0x4d,0x8d,0x8d,0x8d,0x8d,0x8d,0x4d,0x4d,0x4d,0x4d,0x8d,0x4d,
-0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x8d,0x4d,0x8d,0x4d,0x8d,0x4d,0x4d,0x8d,
-0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
-0xb1,0xb1,0xb1,0xd,0xd,0x8d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,
-0x4d,0x8d,0x8d,0x8d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,
-0x4d,0x4d,0x4d,0x8d,0x8d,0x4d,0x4d,0x4d,0x4d,0x8d,0x4d,0x8d,0x8d,0x4d,0x4d,0x4d,
-0x8d,0x8d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,
+0x4d,0x4d,0x4d,0x4d,0x8d,0x4d,0x4d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,
+0x4d,0x8d,0x4d,0x8d,0x4d,0x4d,0x8d,0x8d,0xd,0x8d,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
+0xb1,5,0xa,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xd,0xd,0xb1,0xb1,0xa,0xb1,0xb1,
+0xb1,0xb1,0x8d,0x8d,2,2,2,2,2,2,2,2,2,2,0x4d,0x4d,
+0x4d,0xd,0xd,0x4d,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,
+0xd,0xd,0xd,0xad,0x8d,0xb1,0x4d,0x4d,0x4d,0x8d,0x8d,0x8d,0x8d,0x8d,0x4d,0x4d,
+0x4d,0x4d,0x8d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x8d,0x4d,0x8d,0x4d,
+0x8d,0x4d,0x4d,0x8d,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
+0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xd,0xd,0x8d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,
+0x4d,0x4d,0x4d,0x4d,0x4d,0x8d,0x8d,0x8d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,
+0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x8d,0x8d,0x4d,0x4d,0x4d,0x4d,0x8d,0x4d,0x8d,
+0x8d,0x4d,0x4d,0x4d,0x8d,0x8d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0xd,0xd,0xd,0xd,
 0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,
-0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xb1,0xb1,
-0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xd,0xd,0xd,0xd,0xd,0xd,0xd,
-0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,1,1,1,1,1,1,1,1,
-1,1,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
+0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,
+0xd,0xd,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xd,0xd,0xd,
+0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,1,1,1,1,
+1,1,1,1,1,1,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
 0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
-0x41,0x41,0x41,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,1,1,0xa,0xa,
-0xa,0xa,0x21,1,1,1,1,1,0xb1,0xb1,0xb1,0xb1,1,0xb1,0xb1,0xb1,
-1,0xb1,0xb1,0xb1,0xb1,0xb1,1,1,1,1,1,1,1,1,1,1,
-1,1,1,1,1,1,1,1,1,1,1,1,1,1,0xb1,0xb1,
-0xb1,0xb1,1,0xb1,0xb1,0xb1,0xb1,0xb1,0x81,0x41,0x41,0x41,0x41,0x41,0x81,0x81,
-0x41,0x81,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x81,0x41,1,1,
-1,0xb1,0xb1,0xb1,1,1,1,1,0xd,0xd,0xd,0xb1,0xb1,0xb1,0xb1,0xb1,
+0x41,0x41,0x41,0x41,0x41,0x41,0x41,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
+1,1,0xa,0xa,0xa,0xa,0x21,1,1,0xb1,1,1,0xb1,0xb1,0xb1,0xb1,
+1,0xb1,0xb1,0xb1,1,0xb1,0xb1,0xb1,0xb1,0xb1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,0xb1,0xb1,0xb1,0xb1,1,0xb1,0xb1,0xb1,0xb1,0xb1,0x81,0x41,0x41,0x41,
+0x41,0x41,0x81,0x81,0x41,0x81,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
+0x81,0x41,0x81,0x81,0x81,0xb1,0xb1,0xb1,1,1,1,1,0x4d,0xd,0x4d,0x4d,
+0x4d,0x4d,0xd,0x8d,0x4d,0x8d,0x8d,0xd,0xd,0xd,0xd,0xd,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,0xb1,0xb1,5,0xb1,
 0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
-0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,
-0x4d,0x4d,0x8d,0x8d,0x8d,0xd,0x8d,0x4d,0x4d,0x8d,0x8d,0x4d,0x4d,0xd,0xd,0xd,
-0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xb1,0xb1,0xb1,0,0,0,0,0,
+0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0x4d,0x4d,0x4d,0x4d,
+0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x8d,0x8d,0x8d,0xd,0x8d,0x4d,0x4d,0x8d,0x8d,0x4d,
+0x4d,0xd,0x4d,0x4d,0x4d,0x8d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,
+0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xb1,0xb1,0xb1,0xb1,0xb1,
+0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0xb1,0,0xb1,0,0,0,
 0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0,0,0xb1,0,0,
@@ -329,7 +344,7 @@
 0,0xb1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0xb1,0xb1,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,4,4,0,0,0,0,0,0,0,4,
-0,0,0,0,0,0xb1,0xb1,0,0,0,0,0,0,0,0,0,
+0,0,0xb1,0,0,0xb1,0xb1,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0xb1,0xb1,0,0,0,0,0xb1,0xb1,0,0,0xb1,
 0xb1,0xb1,0,0,0,0xb1,0,0,0,0,0,0,0,0,0,0,
@@ -338,199 +353,199 @@
 0xb1,0,0,0,0,0xb1,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0xb1,0xb1,0,0,0,0,
 0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,
+0,0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0xb1,0,0,0xb1,0,0xb1,0xb1,0xb1,
-0xb1,0,0,0,0,0,0,0,0,0xb1,0,0,0,0,0,0,
-0,0,0xb1,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0xb1,0,0,0xb1,0,0xb1,0xb1,0xb1,0xb1,0,0,0,
+0,0,0,0,0,0xb1,0,0,0,0,0,0,0,0xb1,0xb1,0,
+0,0,0,0,0,0,0,0,0,0,0xb1,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0xb1,0,0,0,0,0,0,0,0,0,0,0,0,0xb1,0,0,
+0,0,0,0,0,0,0,0,0xb1,0,0,0,0,0,0,0,
+0,0,0,0,0,0xb1,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0xa,0xa,0xa,0xa,0xa,
+0xa,4,0xa,0,0,0,0,0,0xb1,0,0,0,0xb1,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0xa,0xa,0xa,0xa,0xa,0xa,4,0xa,0,0,0,0,0,
-0xb1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0xb1,0xb1,0xb1,0,0,0,0,0,0xb1,0xb1,0xb1,0,0xb1,0xb1,
-0xb1,0xb1,0,0,0,0,0,0,0,0xb1,0xb1,0,0,0,0,0,
-0,0,0,0,0,0,0xb1,0xb1,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0xa,0xa,0xa,0xa,
-0xa,0xa,0xa,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0xb1,0,0,0xa0,0,0,0,0,0,0,0xa0,0,0,0,0,0,
-0xb1,0xb1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0xb1,0,0,0,0,0,0,0,0xb1,0xb1,
-0xb1,0,0xb1,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0xb1,0,0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,
-0,0,0,4,0,0,0,0,0,0,0,0xb1,0xb1,0xb1,0xb1,0xb1,
-0xb1,0xb1,0xb1,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0xb1,0,0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0xb1,
-0xb1,0,0,0,0,0,0,0,0,0,0,0,0xb1,0xb1,0xb1,0xb1,
-0xb1,0xb1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0xb1,0xb1,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0xb1,0,0xb1,0,0xb1,0x310a,0xf20a,0x310a,0xf20a,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,
-0xb1,0xb1,0xb1,0xb1,0xb1,0,0xb1,0xb1,0,0,0,0,0,0xb1,0xb1,0xb1,
-0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
-0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
-0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0xb1,0xb1,0xb1,0xb1,0,0xb1,0xb1,
-0xb1,0xb1,0xb1,0xb1,0,0xb1,0xb1,0,0,0xb1,0xb1,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0xb1,0xb1,0,0,0,0,0xb1,0xb1,0xb1,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0xb1,0xb1,0xb1,
-0xb1,0,0,0,0,0,0,0,0,0,0,0,0,0,0xb1,0,
-0,0xb1,0xb1,0,0,0,0,0,0,0xb1,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0xb1,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0xb1,0xb1,0xb1,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0xa,0xa,0xa,0xa,
-0xa,0xa,0xa,0xa,0xa,0xa,0,0,0,0,0,0,0xa,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0x310a,0xf20a,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xb1,0xb1,
-0xb1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0xb1,0xb1,0,0xb1,0xb1,0xb1,0xb1,0xb1,
-0xb1,0xb1,0,0,0,0,0,0,0,0,0xb1,0,0,0xb1,0xb1,0xb1,
-0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0,0,0,0,0,4,
-0,0xb1,0,0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
-0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
-0x40,0x40,0x40,0x40,0x40,0xb1,0x40,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0xa,0xa,0xa,0xa,
-0xa,0xa,0xa,0x4a,0xa,0xa,0x2a,0xb1,0xb1,0xb1,0x12,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0x40,0x40,0x40,0x40,
-0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
-0x40,0x40,0x40,0x40,0,0,0,0,0,0,0,0,0,0,0,0x40,
-0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
-0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0xb1,0xb1,0xb1,0,0,0,0,0xb1,
-0xb1,0,0,0,0,0,0,0,0,0,0xb1,0,0,0,0,0,
-0,0xb1,0xb1,0xb1,0,0,0,0,0xa,0,0,0,0xa,0xa,0,0,
+0xb1,0,0,0,0,0,0xb1,0xb1,0xb1,0,0xb1,0xb1,0xb1,0xb1,0,0,
+0,0,0,0,0,0xb1,0xb1,0,0,0,0,0,0,0,0,0,
+0,0,0xb1,0xb1,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xa,0xa,
-0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
-0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0,0,0,0,0,0,0,0,0,0,0,0,0xb1,0,0,0xa0,
+0,0,0,0,0,0,0xa0,0,0,0,0,0,0xb1,0xb1,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0xb1,0xb1,0,0,0xb1,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0xb1,0xb1,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0xb1,0,0,0,0,0,
+0,0,0xb1,0xb1,0xb1,0,0xb1,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0xb1,0,0,0xb1,0xb1,0xb1,0xb1,
+0xb1,0xb1,0xb1,0,0,0,0,4,0,0,0,0,0,0,0,0xb1,
+0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0xb1,0,0,0xb1,0xb1,0xb1,0xb1,
+0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0,0,0,0,0,0,0,0,0,
+0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0xb1,0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0xb1,0,0xb1,0,
-0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0,0,0,0,0xb1,
-0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0xb1,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0xb1,0xb1,0xb1,0xb1,
-0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0xb1,0xb1,0xb1,0xb1,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0xb1,0,0xb1,0xb1,
-0xb1,0xb1,0xb1,0,0xb1,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0xb1,0xb1,0xb1,0xb1,0,0,
-0xb1,0xb1,0,0xb1,0xb1,0xb1,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0xb1,0,0xb1,0xb1,0,0,
-0,0xb1,0,0xb1,0xb1,0xb1,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0xb1,0xb1,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0xb1,0xb1,0xb1,0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
-0xb1,0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0,0,0xb1,0,0,
-0,0,0,0,0xb1,0,0,0,0xb1,0xb1,0,0,0,0,0,0,
+0xb1,0xb1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0xb1,0,0xb1,0,0xb1,0x310a,0xf20a,
+0x310a,0xf20a,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
+0xb1,0xb1,0xb1,0,0xb1,0xb1,0xb1,0xb1,0xb1,0,0xb1,0xb1,0,0,0,0,
+0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0xb1,0xb1,0xb1,
 0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
-0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0,0,0,0,0xb1,0xb1,0xb1,0xb1,
+0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0xb1,0xb1,0xb1,
+0xb1,0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0xb1,0xb1,0,0,0xb1,0xb1,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0xa,0,0xa,
-0xa,0xa,0,0,0,0,0,0,0,0,0,0,0,0xa,0xa,0xa,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0xa,0xa,0xa,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0xa,0xa,0,
-0xa,0xa,0xa,0xa,6,0x310a,0xf20a,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
-0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,9,
-0xb2,0xb2,0xb2,0xb2,0xb2,0x12,0x814,0x815,0x813,0x816,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,
-2,0,0,0,2,2,2,2,2,2,3,3,0xa,0x310a,0xf20a,0,
-9,9,9,9,9,9,9,9,9,9,9,0xb2,0x412,0x432,0x8a0,0x8a1,
-0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
-9,7,0x8ab,0x8ae,0x8b0,0x8ac,0x8af,6,4,4,4,4,4,0xa,0xa,0xa,
-0xa,0x300a,0xf00a,0xa,0xa,0xa,0xa,0xa,2,2,2,2,2,2,2,2,
-2,2,3,3,0xa,0x310a,0xf20a,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,
-4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
-4,4,4,4,4,4,4,4,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
-0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xa,0xa,0,0xa,0xa,0xa,0xa,0,
-0xa,0xa,0,0,0,0,0,0,0,0,0,0,0xa,0,0xa,0xa,
-0xa,0,0,0,0,0,0xa,0xa,0xa,0xa,0xa,0xa,0,0xa,0,0xa,
-0,0xa,0,0,0,0,4,0,0,0,0,0,0,0,0,0,
-0,0,0xa,0xa,0,0,0,0,0x100a,0xa,0xa,0xa,0xa,0,0,0,
-0,0,0xa,0xa,0xa,0xa,0,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
-0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0,0,0,0,0,0,0,0,
-0,0xa,0xa,0xa,0,0,0,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
-0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,
-0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0xa,0xa,0x300a,0xf00a,0x900a,0x900a,0x900a,0x100a,0x900a,0x900a,
-0x100a,0x100a,0x900a,0x900a,0x900a,0x900a,0x900a,0x100a,0xa,0x100a,0x100a,0x100a,0x100a,0xa,0xa,0xa,
-0x700a,0x700a,0x700a,0xb00a,0xb00a,0xb00a,0xa,0xa,0xa,0x100a,3,4,0xa,0x900a,0x100a,0xa,
-0xa,0xa,0x100a,0x100a,0x100a,0x100a,0xa,0x100a,0x100a,0x100a,0x100a,0xa,0x100a,0xa,0x100a,0xa,
-0xa,0xa,0xa,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0xa,0xa,0xa,0xa,
-0xa,0x100a,0xa,0x100a,0x300a,0xf00a,0x100a,0x100a,0x100a,0x100a,0x100a,0x900a,0x100a,0x100a,0x100a,0x100a,
-0x100a,0x100a,0x100a,0x100a,0x100a,0xa,0xa,0xa,0xa,0xa,0x300a,0xf00a,0x300a,0xf00a,0xa,0xa,
-0xa,0xa,0xa,0xa,0xa,0xa,0xa,0x100a,0x100a,0xa,0x100a,0xa,0x300a,0xf00a,0x300a,0xf00a,
-0x300a,0xf00a,0x300a,0xf00a,0xa,0xa,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,
-0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x100a,0xa,0xa,0x300a,0xf00a,0x300a,0xf00a,0xa,
-0xa,0xa,0xa,0xa,0x900a,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0x300a,0xf00a,
-0xa,0xa,0x900a,0x100a,0x900a,0x900a,0x100a,0x900a,0x100a,0x100a,0x100a,0x100a,0x300a,0xf00a,0x300a,0xf00a,
-0x300a,0xf00a,0x300a,0xf00a,0x100a,0xa,0xa,0xa,0xa,0xa,0x100a,0x100a,0xa,0xa,0xa,0xa,
-0xa,0xa,0xa,0xa,0xa,0x300a,0xf00a,0x300a,0xf00a,0x900a,0xa,0xa,0x300a,0xf00a,0xa,0xa,
-0xa,0xa,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0xa,0xa,0xa,0xa,
-0xa,0xa,0xa,0xa,0x310a,0xf20a,0x310a,0xf20a,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
-0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0x100a,0x100a,0xa,0xa,
-0xa,0xa,0xa,0xa,0xa,0x310a,0xf20a,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0,0,0,0,0,0,0,0,0xb1,0xb1,0,0,0,0,0xb1,0xb1,
+0xb1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0xb1,0xb1,0xb1,0xb1,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0xb1,0,0,0xb1,0xb1,0,0,0,0,0,0,0xb1,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0xb1,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0xb1,0xb1,0xb1,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0,0,0,0,0,0,
+0xa,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0x310a,0xf20a,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0xb1,0xb1,0xb1,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0xb1,0xb1,0,0xb1,
+0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0,0,0,0,0,0,0xb1,0,
+0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0,0,
+0,0,0,4,0,0xb1,0,0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
+0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
+0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0xb1,0x40,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0x4a,0xa,0xa,0x2a,0xb1,0xb1,0xb1,0x12,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
+0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0,0,0,0,0,0,0,
+0,0xb1,0xb1,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
+0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0xb1,0xb1,0xb1,0,
+0,0,0,0xb1,0xb1,0,0,0,0,0,0,0,0,0,0xb1,0,
+0,0,0,0,0,0xb1,0xb1,0xb1,0,0,0,0,0xa,0,0,0,
 0xa,0xa,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xa,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
 0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
-0xa,0xa,0xa,0xa,0xa,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0xb1,0xb1,0,0,0xb1,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0xb1,0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,
+0xb1,0,0xb1,0,0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0,
+0,0,0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0xb1,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0xb1,0,0xb1,0xb1,0xb1,0xb1,0xb1,0,0xb1,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0xb1,0xb1,0xb1,0xb1,0xb1,
+0xb1,0xb1,0xb1,0xb1,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0xb1,0xb1,0xb1,0xb1,0,0,0xb1,0xb1,0,0xb1,0xb1,0xb1,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0xb1,0,0xb1,0xb1,0,0,0,0xb1,0,0xb1,0xb1,0xb1,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0xb1,0xb1,0xb1,0xb1,
+0xb1,0xb1,0xb1,0xb1,0,0,0xb1,0xb1,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0xb1,0xb1,0xb1,0,0xb1,0xb1,0xb1,0xb1,
+0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
+0xb1,0,0,0,0,0xb1,0,0,0,0,0,0,0xb1,0,0,0,
+0xb1,0xb1,0,0,0,0,0,0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
+0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
+0xb1,0xb1,0,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0xa,0,0xa,0xa,0xa,0,0,0,0,0,0,
+0,0,0,0,0,0xa,0xa,0xa,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0xa,0xa,0xa,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0xa,0xa,0,0xa,0xa,0xa,0xa,6,0x310a,0xf20a,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,9,0xb2,0xb2,0xb2,0xb2,0xb2,0x12,0x814,0x815,
+0x813,0x816,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,2,0,0,0,2,2,2,2,
+2,2,3,3,0xa,0x310a,0xf20a,0,9,9,9,9,9,9,9,9,
+9,9,9,0xb2,0x412,0x432,0x8a0,0x8a1,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,9,7,0x8ab,0x8ae,0x8b0,0x8ac,0x8af,6,
+4,4,4,4,4,0xa,0xa,0xa,0xa,0x300a,0xf00a,0xa,0xa,0xa,0xa,0xa,
+2,2,2,2,2,2,2,2,2,2,3,3,0xa,0x310a,0xf20a,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
+4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
+0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
+0xa,0xa,0,0xa,0xa,0xa,0xa,0,0xa,0xa,0,0,0,0,0,0,
+0,0,0,0,0xa,0,0xa,0xa,0xa,0,0,0,0,0,0xa,0xa,
+0xa,0xa,0xa,0xa,0,0xa,0,0xa,0,0xa,0,0,0,0,4,0,
+0,0,0,0,0,0,0,0,0,0,0xa,0xa,0,0,0,0,
+0x100a,0xa,0xa,0xa,0xa,0,0,0,0,0,0xa,0xa,0xa,0xa,0,0,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0,0,0,0,0,0,0,0,0,0xa,0xa,0xa,0,0,0,0,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0xa,0xa,
+0x300a,0xf00a,0x900a,0x900a,0x900a,0x100a,0x900a,0x900a,0x100a,0x100a,0x900a,0x900a,0x900a,0x900a,0x900a,0x100a,
+0xa,0x100a,0x100a,0x100a,0x100a,0xa,0xa,0xa,0x700a,0x700a,0x700a,0xb00a,0xb00a,0xb00a,0xa,0xa,
+0xa,0x100a,3,4,0xa,0x900a,0x100a,0xa,0xa,0xa,0x100a,0x100a,0x100a,0x100a,0xa,0x900a,
+0x900a,0x900a,0x900a,0xa,0x900a,0xa,0x100a,0xa,0xa,0xa,0xa,0x100a,0x100a,0x100a,0x100a,0x100a,
+0x100a,0x100a,0x100a,0x100a,0xa,0xa,0xa,0xa,0xa,0x100a,0xa,0x100a,0x300a,0xf00a,0x100a,0x100a,
+0x100a,0x100a,0x100a,0x900a,0x100a,0x900a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x900a,0xa,0xa,0xa,
+0xa,0xa,0x300a,0xf00a,0x300a,0xf00a,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0x100a,
+0x100a,0xa,0x100a,0xa,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0xa,0xa,0x300a,0xf00a,
+0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,
+0x100a,0xa,0xa,0x300a,0xf00a,0x300a,0xf00a,0xa,0xa,0xa,0xa,0xa,0x900a,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0x300a,0xf00a,0xa,0xa,0x900a,0x100a,0x900a,0x900a,0x100a,0x900a,
+0x100a,0x100a,0x100a,0x100a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x900a,0xa,0xa,0xa,
+0xa,0xa,0x100a,0x100a,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0x300a,0xf00a,0x300a,
+0xf00a,0x900a,0xa,0xa,0x300a,0xf00a,0xa,0xa,0xa,0xa,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,
+0x300a,0xf00a,0x300a,0xf00a,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0x310a,0xf20a,0x310a,0xf20a,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0x100a,0x100a,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0x310a,0xf20a,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,2,2,2,2,2,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0x310a,0xf20a,0x310a,0xf20a,0x310a,0xf20a,0x310a,0xf20a,0x310a,0xf20a,0x310a,0xf20a,0x310a,0xf20a,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0x100a,0xa,0xa,0x300a,0xf00a,0x310a,0xf20a,0xa,
+0x300a,0xf00a,0xa,0x500a,0x100a,0xd00a,0xa,0xa,0xa,0xa,0xa,0x100a,0x100a,0x300a,0xf00a,0xa,
+0xa,0xa,0xa,0xa,0x900a,0x300a,0xf00a,0xa,0xa,0xa,0x300a,0xf00a,0x300a,0xf00a,0x310a,0xf20a,
+0x310a,0xf20a,0x310a,0xf20a,0x310a,0xf20a,0x310a,0xf20a,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0x100a,0xa,0x100a,0x100a,0x100a,0xa,0xa,
+0x300a,0xf00a,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0x100a,0x900a,0x100a,0x100a,
+0x300a,0xf00a,0xa,0xa,0x310a,0xf20a,0xa,0xa,0xa,0xa,0xa,0x310a,0xf20a,0x310a,0xf20a,0x310a,
+0xf20a,0x310a,0xf20a,0x310a,0xf20a,0x710a,0x320a,0xf10a,0xb20a,0x310a,0xf20a,0x310a,0xf20a,0x310a,0xf20a,0x310a,
+0xf20a,0xa,0xa,0x900a,0x100a,0x100a,0x100a,0x100a,0x900a,0xa,0x100a,0x900a,0x300a,0xf00a,0x100a,0x100a,
+0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0x900a,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0x300a,0xf00a,0x100a,0x100a,0x300a,0xf00a,0xa,0xa,
+0xa,0x100a,0xa,0xa,0xa,0xa,0x100a,0x300a,0xf00a,0x300a,0xf00a,0xa,0x300a,0xf00a,0xa,0xa,
+0x310a,0xf20a,0x310a,0xf20a,0x100a,0xa,0xa,0xa,0xa,0xa,0x100a,0x900a,0x900a,0x900a,0x100a,0xa,
+0xa,0xa,0xa,0xa,0x300a,0xf00a,0x900a,0xa,0xa,0xa,0xa,0x100a,0xa,0xa,0xa,0x300a,
+0xf00a,0x300a,0xf00a,0x100a,0xa,0x100a,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,
+0x100a,0x100a,0x100a,0x100a,0x100a,0xa,0x100a,0x100a,0x100a,0x100a,0xa,0xa,0x100a,0xa,0x100a,0xa,
+0xa,0x100a,0xa,0x300a,0xf00a,0x300a,0xf00a,0xa,0xa,0xa,0xa,0xa,0x300a,0xf00a,0xa,0xa,
+0xa,0xa,0xa,0xa,0x300a,0xf00a,0x100a,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0x100a,
+0x100a,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0x300a,0xf00a,0xa,0xa,0xa,0xa,0x100a,0x100a,
+0x100a,0x100a,0xa,0x100a,0x100a,0xa,0xa,0x100a,0x100a,0xa,0xa,0xa,0xa,0x300a,0xf00a,0x300a,
+0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,
+0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,
+0xf00a,0x300a,0xf00a,0x100a,0xa,0xa,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0xa,0x300a,
+0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,
+0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0xa,0xa,0xa,0xa,0xa,0x100a,0xa,0x900a,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0x900a,0xa,
+0,0,0,0,0,0xa,0xa,0xa,0xa,0xa,0xa,0,0,0,0,0xb1,
+0xb1,0xb1,0,0,0,0,0,0,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xb1,
+0xa,0xa,0x300a,0xf00a,0x300a,0xf00a,0xa,0xa,0xa,0x300a,0xf00a,0xa,0x300a,0xf00a,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0x300a,0xf00a,0xa,0xa,
+0x300a,0xf00a,0x310a,0xf20a,0x310a,0xf20a,0x310a,0xf20a,0x310a,0xf20a,0xa,0xa,0xa,0xa,0xa,0xa,
 0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
 0xa,0xa,0xa,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
-2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
-2,2,2,2,0,0,0,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
-0xa,0xa,0xa,0xa,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
-0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0x310a,0xf20a,0x310a,0xf20a,0x310a,0xf20a,0x310a,0xf20a,
-0x310a,0xf20a,0x310a,0xf20a,0x310a,0xf20a,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
-0x100a,0xa,0xa,0x300a,0xf00a,0x310a,0xf20a,0xa,0x300a,0xf00a,0xa,0x500a,0x100a,0xd00a,0xa,0xa,
-0xa,0xa,0xa,0x100a,0x100a,0x300a,0xf00a,0xa,0xa,0xa,0xa,0xa,0x100a,0x300a,0xf00a,0xa,
-0xa,0xa,0x300a,0xf00a,0x300a,0xf00a,0x310a,0xf20a,0x310a,0xf20a,0x310a,0xf20a,0x310a,0xf20a,0x310a,0xf20a,
-0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
-0xa,0x100a,0xa,0x100a,0x100a,0x100a,0xa,0xa,0x100a,0x100a,0xa,0xa,0xa,0xa,0xa,0xa,
-0xa,0xa,0xa,0xa,0x100a,0x900a,0x100a,0x100a,0x300a,0xf00a,0xa,0xa,0x310a,0xf20a,0xa,0xa,
-0xa,0xa,0xa,0x310a,0xf20a,0x310a,0xf20a,0x310a,0xf20a,0x310a,0xf20a,0x310a,0xf20a,0x710a,0x320a,0xf10a,
-0xb20a,0x310a,0xf20a,0x310a,0xf20a,0x310a,0xf20a,0x310a,0xf20a,0xa,0xa,0x100a,0x100a,0x100a,0x100a,0x100a,
-0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0xa,0xa,0xa,0xa,
-0xa,0xa,0xa,0xa,0x900a,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0x300a,0xf00a,0x100a,0x100a,
-0x300a,0xf00a,0xa,0xa,0xa,0x100a,0xa,0xa,0xa,0xa,0x100a,0x300a,0xf00a,0x300a,0xf00a,0xa,
-0x300a,0xf00a,0xa,0xa,0x310a,0xf20a,0x310a,0xf20a,0x100a,0xa,0xa,0xa,0xa,0xa,0x100a,0x900a,
-0x900a,0x900a,0x100a,0xa,0xa,0xa,0xa,0xa,0x300a,0xf00a,0x100a,0xa,0xa,0xa,0xa,0x100a,
-0xa,0xa,0xa,0x300a,0xf00a,0x300a,0xf00a,0x100a,0xa,0x100a,0xa,0xa,0xa,0xa,0xa,0xa,
-0xa,0xa,0xa,0xa,0xa,0xa,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,
-0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0xa,0x100a,0x100a,0x100a,0x100a,0xa,0xa,
-0x100a,0xa,0x100a,0xa,0xa,0x100a,0xa,0x300a,0xf00a,0x300a,0xf00a,0xa,0xa,0xa,0xa,0xa,
-0x300a,0xf00a,0xa,0xa,0xa,0xa,0xa,0xa,0x300a,0xf00a,0x100a,0xa,0xa,0xa,0xa,0xa,
-0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
-0xa,0xa,0xa,0x100a,0x100a,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0x300a,0xf00a,0xa,0xa,
-0xa,0xa,0x100a,0x100a,0x100a,0x100a,0xa,0x100a,0x100a,0xa,0xa,0x100a,0x100a,0xa,0xa,0xa,
-0xa,0x300a,0xf00a,0x100a,0x100a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x100a,0x100a,0x100a,
-0x100a,0x100a,0x100a,0x300a,0xf00a,0x100a,0x100a,0x100a,0x100a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,
-0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x100a,0x100a,0x100a,0x100a,0x300a,0xf00a,0x100a,0xa,0xa,0x300a,0xf00a,
-0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0xa,0x300a,0xf00a,0x100a,0x100a,0x300a,0xf00a,0x100a,0x100a,0x100a,
-0x100a,0x100a,0x100a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x100a,0x100a,0x100a,0x100a,0x100a,
-0x100a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0xa,0xa,0xa,0xa,0xa,
-0x100a,0xa,0x900a,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
-0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0,0,0xa,0xa,0xa,0xa,0xa,0xa,
-0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
-0xa,0xa,0,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
-0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0,0,
-0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0,0xa,0xa,
-0xa,0xa,0xa,0xa,0xa,0xa,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0xa,0xa,0xa,0xa,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0xa,0xa,0xa,0xa,0xa,0xa,0,
-0,0,0,0xb1,0xb1,0xb1,0,0,0,0,0,0,0,0xa,0xa,0xa,
-0xa,0xa,0xa,0xa,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0xb1,0xa,0xa,0x300a,0xf00a,0x300a,0xf00a,0xa,0xa,0xa,0x300a,0xf00a,0xa,
-0x300a,0xf00a,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
-0x300a,0xf00a,0xa,0xa,0x300a,0xf00a,0x310a,0xf20a,0x310a,0xf20a,0x310a,0xf20a,0x310a,0xf20a,0xa,0xa,
 0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
 0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0,0xa,0xa,0xa,0xa,0xa,
 0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
@@ -549,6 +564,7 @@
 0xa,0xa,0xa,0,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
 0xa,0xa,0xa,0xa,0,0,0,0,0,0,0,0,0,0,0,0,
+0xa,0xa,0xa,0xa,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0xa,0xa,0xa,0xa,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0xa,0xa,0xa,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
@@ -557,173 +573,242 @@
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0xb1,0,0,0,0xb1,0,0,0,0,0xb1,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0xb1,0xb1,0,0xa,0xa,0xa,0xa,0,0,0,0,
+0,0,0,0,0,0xb1,0xb1,0,0xa,0xa,0xa,0xa,0xb1,0,0,0,
 0,0,0,0,0,0,0,0,4,4,0,0,0,0,0,0,
 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
 0x40,0x40,0x60,0,0xa,0xa,0xa,0xa,0,0,0,0,0,0,0,0,
 0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
-0xb1,0xb1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xb1,
-0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xb1,
-0,0,0xb1,0xb1,0xb1,0xb1,0,0,0xb1,0,0,0,0,0,0,0,
-0,0,0,0,0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0xb1,0xb1,0,
-0,0xb1,0xb1,0,0,0,0,0,0,0,0,0,0,0,0,0xb1,
-0,0,0,0,0,0,0,0,0xb1,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0xb1,0,0xb1,0xb1,
-0xb1,0,0,0xb1,0xb1,0,0,0,0,0,0xb1,0xb1,0,0,0,0,
-0,0,0,0,0,0,0,0,0xb1,0xb1,0,0,0,0,0,0,
-0,0,0xb1,0,0,0,0,0,0,0,0,0,0,0xb1,0,0,
-0xb1,0,0,0,0,0xb1,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,
-1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-1,1,1,1,1,1,1,1,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,
-0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0,0,0,0,0,0,0,0,
+0xb1,0xb1,0,0,0,0,0,0,0,0,0,0,0,0,0,0xb1,
+0,0,0,0,0,0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,1,0xb1,1,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,
-0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,
-0xd,0xd,0xd,0xd,0xd,0xd,0xa,0xa,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,
-0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,
-0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,
-0xd,0xd,0xd,0xd,0xd,0xa,0xd,0xd,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
-0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
-0xa,0xa,0,0,0,0,0,0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
-0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
-0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,6,0xa,6,0,0xa,6,0xa,0xa,
-0xa,0x310a,0xf20a,0x310a,0xf20a,0x310a,0xf20a,4,0xa,0xa,3,3,0x300a,0xf00a,0xa,0,
-0xa,4,4,0xa,0,0,0,0,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,
-0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,
-0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xb2,0,0xa,0xa,4,4,4,0xa,0xa,
-0x310a,0xf20a,0xa,3,6,3,6,6,2,2,2,2,2,2,2,2,
-2,2,6,0xa,0x500a,0xa,0xd00a,0xa,0xa,0,0,0,0,0,0,0,
+0,0,0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0x510a,0xa,0xd20a,0xa,0x310a,0xf20a,0xa,0x310a,0xf20a,0xa,0xa,0,0,
+0,0,0,0xb1,0,0,0xb1,0xb1,0xb1,0xb1,0,0,0xb1,0xb1,0,0,
+0,0,0,0,0,0,0,0,0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,
+0,0xb1,0xb1,0,0,0xb1,0xb1,0,0,0,0,0,0,0,0,0,
+0,0,0,0xb1,0,0,0,0,0,0,0,0,0xb1,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,4,4,0xa,0xa,0xa,4,4,0,
-0xa,0xa,0xa,0xa,0xa,0xa,0xa,0,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,
-0x12,0xaa,0xaa,0xaa,0xa,0xa,0x12,0x12,0,0xa,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
-0xa,0xa,0xa,0xa,0xa,0,0,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
-0xa,0xa,0xa,0xa,0,0,0,0,0xb1,2,2,2,2,2,2,2,
-2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
-2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0xb1,0xb1,0xb1,0xb1,0xb1,0,
-0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,
+0xb1,0,0xb1,0xb1,0xb1,0,0,0xb1,0xb1,0,0,0,0,0,0xb1,0xb1,
+0,0,0,0,0,0,0,0,0,0,0,0,0xb1,0xb1,0,0,
+0,0,0,0,0,0,0xb1,0,0,0,0,0,0,0,0,0,
+0,0,0xa,0xa,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0xb1,0,0,0xb1,0,0,0,
+0,0xb1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,1,1,1,1,1,1,1,1,1,3,1,1,
 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-1,1,1,0xa,1,0xb1,0xb1,0xb1,1,0xb1,0xb1,1,1,1,1,1,
-0xb1,0xb1,0xb1,0xb1,1,1,1,1,1,1,1,1,1,1,1,1,
-1,1,1,1,1,1,1,1,1,1,1,1,0xb1,0xb1,0xb1,1,
-1,1,1,0xb1,0x41,0x81,1,1,0x81,0xb1,0xb1,1,1,1,1,0x41,
-0x41,0x41,0x41,0x81,1,1,1,1,1,1,1,1,1,1,1,1,
-1,1,1,1,0x41,0x41,0x41,0x41,0x41,0x81,1,0x81,1,0x81,0x81,1,
-1,0x61,0x81,0x81,0x81,0x81,0x81,0x41,0x41,0x41,0x41,0x61,0x41,0x41,0x41,0x41,
-0x41,0x81,0x41,0x41,1,1,1,1,1,1,1,1,1,1,1,1,
-1,1,1,1,1,1,1,1,1,1,1,1,1,0xa,0xa,0xa,
-0xa,0xa,0xa,0xa,0x41,0x81,0x41,0x81,0x81,0x81,0x41,0x41,0x41,0x81,0x41,0x41,
-0x81,0x41,0x81,0x81,0x41,0x81,1,1,1,1,1,1,1,1,1,1,
-1,1,1,1,1,0x81,0x81,0x81,0x81,0x41,0x41,1,1,1,1,1,
-1,1,1,1,1,1,1,1,1,1,1,1,5,5,5,5,
+1,1,1,1,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,
+0xd,0xd,0xd,0xd,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,1,0xb1,1,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,
+0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,
+0xd,0xd,0xa,0xa,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,
+0xd,0xd,0xd,0xd,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,
+0x12,0x12,0x12,0x12,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,
+0xd,0xa,0xd,0xd,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
+0xb1,0xb1,0xb1,0xb1,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0,0,
+0,0,0,0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
+0xb1,0xb1,0xb1,0xb1,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,6,0xa,6,0,0xa,6,0xa,0xa,0xa,0x310a,0xf20a,0x310a,
+0xf20a,0x310a,0xf20a,4,0xa,0xa,3,3,0x300a,0xf00a,0xa,0,0xa,4,4,0xa,
+0,0,0,0,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,
+0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,
+0xd,0xd,0xd,0xb2,0,0xa,0xa,4,4,4,0xa,0xa,0x310a,0xf20a,0xa,3,
+6,3,6,6,2,2,2,2,2,2,2,2,2,2,6,0xa,
+0x500a,0xa,0xd00a,0xa,0xa,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x510a,
+0xa,0xd20a,0xa,0x310a,0xf20a,0xa,0x310a,0xf20a,0xa,0xa,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,4,4,0xa,0xa,0xa,4,4,0,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0xaa,0xaa,0xaa,
+0xa,0xa,0x12,0x12,0,0xa,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0,0,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0,0,0,0xb1,2,2,2,2,2,2,2,2,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0,0,0,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0xa,
+1,0xb1,0xb1,0xb1,1,0xb1,0xb1,1,1,1,1,1,0xb1,0xb1,0xb1,0xb1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,0xb1,0xb1,0xb1,1,1,1,1,0xb1,
+0x41,0x81,1,1,0x81,0xb1,0xb1,1,1,1,1,0x41,0x41,0x41,0x41,0x81,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+0x41,0x41,0x41,0x41,0x41,0x81,1,0x81,1,0x81,0x81,1,1,0x61,0x81,0x81,
+0x81,0x81,0x81,0x41,0x41,0x41,0x41,0x61,0x41,0x41,0x41,0x41,0x41,0x81,0x41,0x41,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0x41,0x81,0x41,0x81,0x81,0x81,0x41,0x41,0x41,0x81,0x41,0x41,0x81,0x41,0x81,0x81,
+0x41,0x81,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,0x81,0x81,0x81,0x81,0x41,0x41,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,0x4d,0x4d,0x8d,0x4d,0xb1,0xb1,0xb1,0xb1,
+0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,5,5,5,5,5,5,5,5,
+5,5,0xd,0xd,0xd,0xd,0xd,0xd,0x6d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,
+0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,
+0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,5,5,5,5,5,5,5,5,
 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,1,0,0,0,0,
+5,5,5,5,5,5,5,1,1,1,1,1,1,1,1,1,
+1,1,1,0xb1,0xb1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,0x4d,0x4d,0x4d,0x8d,0x4d,0x4d,0x4d,0x4d,
+0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0xd,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
+0xb1,0xb1,0xb1,0xb1,0xb1,0x4d,0x4d,0x4d,0x8d,0xd,0xd,0xd,0xd,0xd,0xd,0xd,
+0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,0x41,1,0x41,0x41,
+0x81,0x81,0x81,1,0x41,0x81,0x81,0x41,0x41,0x81,0x41,0x41,1,0x41,0x81,0x81,
+0x41,1,1,1,1,0x81,0x41,0x61,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,
 0,0,0,0,0,0,0,0,0,0,0xa,0xa,0xa,0xa,0xa,0xa,
 0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0xb1,0xb1,0xb1,0xb1,0,0,0xb1,0xb1,0,0,0xa0,0,0,
-0,0,0,0,0,0,0,0xb1,0xb1,0xb1,0xb1,0xb1,0,0xb1,0xb1,0xb1,
-0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0xb1,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0,0,0,
+0,0,0,0xb1,0xb1,0xb1,0xb1,0,0,0xb1,0xb1,0,0,0,0,0,
+0,0,0,0xb1,0xb1,0xb1,0xb1,0xb1,0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
+0xb1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0xb1,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xb1,0xb1,
+0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0,0,0,0,0,0,0,
+0,0xb1,0xb1,0xb1,0xb1,0,0,0xb1,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0xb1,0xb1,0xb1,0,0,
-0xb1,0,0xb1,0xb1,0,0,0,0,0,0,0,0,0,0,0,0xb1,
+0xb1,0,0xb1,0xb1,0,0,0,0,0,0,0xb1,0,0,0,0,0xb1,
 0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xb1,0xb1,
 0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0xb1,0xb1,0xb1,0,0xb1,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0xb1,0,0,0,0,0xb1,
-0xb1,0,0xb1,0xb1,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0xb1,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0xb1,0xb1,0xb1,0xb1,0xb1,
+0xb1,0,0xb1,0,0,0,0,0xb1,0xb1,0,0xb1,0xb1,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0xb1,0xb1,0xb1,0xb1,0,0,0,0,0,0,0xb1,0xb1,0,0xb1,
-0xb1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0xb1,0xb1,0,0,
+0,0,0,0,0,0,0,0,0,0,0xb1,0xb1,0xb1,0xb1,0,0,
+0,0,0,0,0xb1,0xb1,0,0xb1,0xb1,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0xb1,0,0xb1,
+0,0,0,0,0xb1,0xb1,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0xb1,0xb1,0xb1,0xb1,0xb1,
+0xb1,0xb1,0xb1,0,0,0xb1,0,0xb1,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0xb1,0,0xb1,0,0,
 0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0xb1,0,0,0,0,0,0,0,0,
 0,0,0xb1,0xb1,0xb1,0xb1,0,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,
+0,0,0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0xb1,0xb1,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0xb1,0xb1,0,0xb1,0,
+0,0,0,0xb1,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0xb1,0xb1,0xb1,0xb1,0,0,0xb1,0xb1,0,0,0,0,0,0xb1,0xb1,0xb1,
+0xb1,0xb1,0xb1,0xa0,0xa0,0xb1,0xb1,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xb1,
-0xb1,0xb1,0xb1,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0xb2,0xb2,0xb2,0xb2,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0xb1,0xb1,0xb1,0,0,0,0,0,0,0,0,0,0xb2,
-0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,
-0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xb1,0xb1,
+0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0xb1,0xb1,0xb1,0xb1,0,0,0,0,0,
+0,0,0,0xb1,0,0,0,0,0,0,0,0,0,0xb1,0xb1,0xb1,
+0xb1,0xb1,0xb1,0,0,0xb1,0xb1,0xb1,0,0,0,0,0,0,0,0,
+0,0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,
 0xb1,0xb1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0xa,0xa,0xb1,0xb1,0xb1,0xa,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0x100a,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0x100a,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0x100a,0,0,0,0,0,0,0,0,
-0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
-2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
-2,2,2,2,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
-0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0,0,0xb1,
-0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0,
-0,0,0,0,0,0xb1,0,0,0,0,0,0,0,0,0,0,
-0xb1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0xb1,0xb1,0xb1,0xb1,0xb1,0,0xb1,0xb1,0xb1,
+0,0,0,0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0xb1,0xb1,0xb1,0xb1,
+0xb1,0xb1,0,0xa0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0xb1,0xb1,
+0xb1,0xb1,0xb1,0xb1,0xb1,0,0xb1,0xb1,0,0xb1,0xb1,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xb1,0xb1,
 0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,
-1,1,1,1,1,1,1,1,1,1,1,1,0xb1,0xb1,0xb1,0xb1,
-0xb1,0xb1,0xb1,1,1,1,1,1,1,1,1,1,0xd,0xd,0xd,0xd,
-0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xa,0xa,0xd,0xd,
-0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xa,0xa,0xa,0xa,
-0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0,0,0,0,0xa,0xa,0xa,0xa,
-0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0,
-0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
-0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
-2,2,2,2,2,2,2,2,2,2,2,0xa,0xa,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0xb1,0xb1,0xb1,
+0xb1,0xb1,0xb1,0,0,0,0xb1,0,0xb1,0xb1,0,0xb1,0xb1,0xb1,0xb1,0xb1,
+0xb1,0xb1,0,0xb1,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0xb1,0xb1,0,0,
+0,0xb1,0,0xb1,0,0,0,0,0,0,0,0,4,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0xa,0xa,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0xa,0xa,0xa,0xa,0,0xa,0xa,0xa,
+0,0,0,0,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,4,4,4,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0xb1,0xb1,0xb1,0xb1,
+0xb1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0xb1,0xb1,0xb1,0xb1,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xa,0,
+0xb1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0xb2,0xb2,0xb2,0xb2,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xb1,
+0xb1,0xb1,0,0,0,0,0,0,0,0,0,0xb2,0xb2,0xb2,0xb2,0xb2,
+0xb2,0xb2,0xb2,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0xb1,0xb1,0xb1,
+0xb1,0xb1,0xb1,0xb1,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0xb1,0xb1,0xb1,0xb1,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0xa,0xa,0xb1,0xb1,0xb1,0xa,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0x100a,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0x100a,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0x100a,0,0,0,0,0,0,0,0,0,0,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
+0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0,0,0xb1,0xb1,0xb1,0xb1,0xb1,
+0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0,0,0,0,0,
+0,0xb1,0,0,0,0,0,0,0,0,0,0,0xb1,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0xb1,0xb1,0xb1,0xb1,0xb1,0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
+0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,
+0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
+0xb1,0,0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0xb1,0xb1,0,0xb1,0xb1,
+0xb1,0xb1,0xb1,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0xb1,0xb1,0xb1,0xb1,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,4,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,0xb1,0xb1,0xb1,0xb1,
+0xb1,0xb1,0xb1,1,1,1,1,1,1,1,1,1,0x41,0x41,0x41,0x41,
+0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
+0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0xb1,0xb1,0xb1,0xb1,
+0xb1,0xb1,0xb1,0xa1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,
+0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xa,0xa,0xd,0xd,0xd,0xd,0xd,0xd,
+0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0,0,0,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0,0,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,2,2,2,2,
+2,2,2,2,2,2,2,0xa,0xa,0xa,0xa,0xa,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xa,0xa,
+0xa,0xa,0xa,0xa,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0xa,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
 0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
-0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
-0xa,0xa,0xa,0xa,0xa,0,0,0,0xa,0xa,0xa,0xa,0,0,0,0,
-0,0,0,0,0,0,0,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0,0,0,0,0,0,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
 0,0,0,0,0,0,0,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
 0xa,0xa,0,0,0,0,0,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
 0,0,0,0,0,0,0,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
-0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0x12,0x12,0,0,0,0,0,0,0,0,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0,0,0xa,0xa,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0,0,0xa,0xa,0xa,0xa,0xa,0,0,0,
+0xa,0xa,0xa,0,0,0,0,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0,
 0,0,0,0,0,0,0,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
-0xa,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0xb2,0xb2,0xb2,0xb2,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0,0,0,0,0,0,0,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0,0,0,0,0,
+0,0,0,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,2,2,2,2,2,2,2,2,2,2,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x12,0x12,
 0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,
-0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0x12,0xb2,0x12,0x12,
+0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,
+0x12,0xb2,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,
 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,
-0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,
-0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
-0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,
-0,0,0,0
+0x12,0x12,0x12,0x12,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
+0xb1,0xb1,0xb1,0xb1,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,
+0x12,0x12,0x12,0x12,0,0,0,0
 };
 
-static const uint32_t ubidi_props_mirrors[26]={
-0x2000ab,0xbb,0x2a02215,0x1202243,0x2802298,0x2c022a6,0x30022a8,0x2e022a9,0x32022ab,0x6022cd,0x1e022f2,0x20022f3,0x22022f4,0x24022f6,0x26022f7,0x14022fa,
-0x16022fb,0x18022fc,0x1a022fd,0x1c022fe,0x8029b8,0x4029f5,0xa02ade,0xe02ae3,0xc02ae4,0x1002ae5
+static const uint32_t ubidi_props_mirrors[40]={
+0x2000ab,0xbb,0x4202215,0x4e0221f,0x3e02220,0x3a02221,0x3c02222,0x4c02224,0x2202243,0x1402245,0x120224c,0x4002298,0x44022a6,0x48022a8,0x46022a9,0x4a022ab,
+0x38022b8,0x10022cd,0x2e022f2,0x30022f3,0x32022f4,0x34022f6,0x36022f7,0x24022fa,0x26022fb,0x28022fc,0x2a022fd,0x2c022fe,0x20027dc,0xa0299b,0xc029a0,0x8029a3,
+0x16029b8,0x4029f5,0x1802ade,0x1c02ae3,0x1a02ae4,0x1e02ae5,0xe02aee,0x602bfe
 };
 
-static const uint8_t ubidi_props_jgArray[664]={
+static const uint8_t ubidi_props_jgArray[680]={
 0x2d,0,3,3,0x2c,3,0x2d,3,4,0x2a,4,4,0xd,0xd,0xd,6,
 6,0x1f,0x1f,0x23,0x23,0x21,0x21,0x28,0x28,1,1,0xb,0xb,0x37,0x37,0x37,
 0,9,0x1d,0x13,0x16,0x18,0x1a,0x10,0x2c,0x2d,0x2d,0,0,0,0,0,
@@ -760,18 +845,55 @@
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0x5d,0x5a,0x60,0x63,0x5e,0x5f,0x59,0x61,0x5b,0x5c,0x62,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 4,4,0xd,0x28,9,0x1d,0x16,0x18,0x2d,0x2d,0x1f,0x2c,0x39,0,6,0x21,
-0xb,0x55,0x1f,1,0x13,0,0,0
+0xb,0x55,0x1f,1,0x13,0,4,4,4,0x1f,0x2d,0x56,0x58,0x57,4,4,
+4,0xd,0xb,1,0x58,0xd,0xd,0x16
 };
 
-static const uint8_t ubidi_props_jgArray2[48]={
+static const uint8_t ubidi_props_jgArray2[612]={
 0x3a,0x3c,0x3c,0x40,0x40,0x3d,0,0x52,0,0x54,0x54,0,0,0x41,0x4f,0x53,
 0x43,0x43,0x43,0x44,0x3e,0x50,0x45,0x46,0x4c,0x3b,0x3b,0x48,0x48,0x4b,0x49,0x49,
-0x49,0x4a,0,0,0x4d,0,0,0,0,0,0,0x47,0x3f,0x4e,0x51,0x42
+0x49,0x4a,0,0,0x4d,0,0,0,0,0,0,0x47,0x3f,0x4e,0x51,0x42,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0x65,0,0,0,0,0,0,0x65,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0x64,0,0,0x65,0,0x64,0,
+0x64,0,0,0x64
 };
 
 static const UBiDiProps ubidi_props_singleton={
@@ -782,17 +904,19 @@
   ubidi_props_jgArray2,
   {
     ubidi_props_trieIndex,
-    ubidi_props_trieIndex+3388,
+    ubidi_props_trieIndex+3568,
     NULL,
-    3388,
-    7800,
+    3568,
+    8968,
     0x1a0,
-    0xdbc,
+    0xe70,
     0x0,
     0x0,
     0x110000,
-    0x2bb0,
+    0x30f4,
     NULL, 0, FALSE, FALSE, 0, NULL
   },
   { 2,2,0,0 }
 };
+
+#endif  // INCLUDED_FROM_UBIDI_PROPS_C
diff --git a/src/third_party/icu/source/common/ubidiimp.h b/src/third_party/icu/source/common/ubidiimp.h
index accd177..e48fc6f 100644
--- a/src/third_party/icu/source/common/ubidiimp.h
+++ b/src/third_party/icu/source/common/ubidiimp.h
@@ -1,12 +1,14 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
-*   Copyright (C) 1999-2015, International Business Machines
+*   Copyright (C) 1999-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *
 ******************************************************************************
 *   file name:  ubidiimp.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -18,11 +20,20 @@
 #define UBIDIIMP_H
 
 #include "unicode/utypes.h"
+#include "unicode/ubidi.h"
 #include "unicode/uchar.h"
 #include "ubidi_props.h"
 
 /* miscellaneous definitions ---------------------------------------------- */
 
+// ICU-20853=ICU-20935 Solaris #defines CS and ES in sys/regset.h
+#ifdef CS
+#   undef CS
+#endif
+#ifdef ES
+#   undef ES
+#endif
+
 typedef uint8_t DirProp;
 typedef uint32_t Flags;
 
@@ -195,8 +206,8 @@
 /* in a Run, logicalStart will get this bit set if the run level is odd */
 #define INDEX_ODD_BIT (1UL<<31)
 
-#define MAKE_INDEX_ODD_PAIR(index, level) ((index)|((int32_t)(level)<<31))
-#define ADD_ODD_BIT_FROM_LEVEL(x, level)  ((x)|=((int32_t)(level)<<31))
+#define MAKE_INDEX_ODD_PAIR(index, level) ((index)|((int32_t)((level)&1)<<31))
+#define ADD_ODD_BIT_FROM_LEVEL(x, level)  ((x)|=((int32_t)((level)&1)<<31))
 #define REMOVE_ODD_BIT(x)                 ((x)&=~INDEX_ODD_BIT)
 
 #define GET_INDEX(x)   ((x)&~INDEX_ODD_BIT)
@@ -251,8 +262,6 @@
      */
     const UBiDi * pParaBiDi;
 
-    const UBiDiProps *bdp;
-
     /* alias pointer to the current text */
     const UChar *text;
 
@@ -386,41 +395,49 @@
 } BidiMemoryForAllocation;
 
 /* Macros for initial checks at function entry */
-#define RETURN_IF_NULL_OR_FAILING_ERRCODE(pErrcode, retvalue)   \
-        if((pErrcode)==NULL || U_FAILURE(*pErrcode)) return retvalue
-#define RETURN_IF_NOT_VALID_PARA(bidi, errcode, retvalue)   \
-        if(!IS_VALID_PARA(bidi)) {  \
-            errcode=U_INVALID_STATE_ERROR;  \
-            return retvalue;                \
-        }
-#define RETURN_IF_NOT_VALID_PARA_OR_LINE(bidi, errcode, retvalue)   \
-        if(!IS_VALID_PARA_OR_LINE(bidi)) {  \
-            errcode=U_INVALID_STATE_ERROR;  \
-            return retvalue;                \
-        }
-#define RETURN_IF_BAD_RANGE(arg, start, limit, errcode, retvalue)   \
-        if((arg)<(start) || (arg)>=(limit)) {       \
-            (errcode)=U_ILLEGAL_ARGUMENT_ERROR;     \
-            return retvalue;                        \
-        }
+#define RETURN_IF_NULL_OR_FAILING_ERRCODE(pErrcode, retvalue) UPRV_BLOCK_MACRO_BEGIN { \
+    if((pErrcode)==NULL || U_FAILURE(*pErrcode)) return retvalue; \
+} UPRV_BLOCK_MACRO_END
+#define RETURN_IF_NOT_VALID_PARA(bidi, errcode, retvalue) UPRV_BLOCK_MACRO_BEGIN { \
+    if(!IS_VALID_PARA(bidi)) { \
+        errcode=U_INVALID_STATE_ERROR; \
+        return retvalue; \
+    } \
+} UPRV_BLOCK_MACRO_END
+#define RETURN_IF_NOT_VALID_PARA_OR_LINE(bidi, errcode, retvalue) UPRV_BLOCK_MACRO_BEGIN { \
+    if(!IS_VALID_PARA_OR_LINE(bidi)) { \
+        errcode=U_INVALID_STATE_ERROR; \
+        return retvalue; \
+    } \
+} UPRV_BLOCK_MACRO_END
+#define RETURN_IF_BAD_RANGE(arg, start, limit, errcode, retvalue) UPRV_BLOCK_MACRO_BEGIN { \
+    if((arg)<(start) || (arg)>=(limit)) { \
+        (errcode)=U_ILLEGAL_ARGUMENT_ERROR; \
+        return retvalue; \
+    } \
+} UPRV_BLOCK_MACRO_END
 
-#define RETURN_VOID_IF_NULL_OR_FAILING_ERRCODE(pErrcode)   \
-        if((pErrcode)==NULL || U_FAILURE(*pErrcode)) return
-#define RETURN_VOID_IF_NOT_VALID_PARA(bidi, errcode)   \
-        if(!IS_VALID_PARA(bidi)) {  \
-            errcode=U_INVALID_STATE_ERROR;  \
-            return;                \
-        }
-#define RETURN_VOID_IF_NOT_VALID_PARA_OR_LINE(bidi, errcode)   \
-        if(!IS_VALID_PARA_OR_LINE(bidi)) {  \
-            errcode=U_INVALID_STATE_ERROR;  \
-            return;                \
-        }
-#define RETURN_VOID_IF_BAD_RANGE(arg, start, limit, errcode)   \
-        if((arg)<(start) || (arg)>=(limit)) {       \
-            (errcode)=U_ILLEGAL_ARGUMENT_ERROR;     \
-            return;                        \
-        }
+#define RETURN_VOID_IF_NULL_OR_FAILING_ERRCODE(pErrcode) UPRV_BLOCK_MACRO_BEGIN { \
+    if((pErrcode)==NULL || U_FAILURE(*pErrcode)) return; \
+} UPRV_BLOCK_MACRO_END
+#define RETURN_VOID_IF_NOT_VALID_PARA(bidi, errcode) UPRV_BLOCK_MACRO_BEGIN { \
+    if(!IS_VALID_PARA(bidi)) { \
+        errcode=U_INVALID_STATE_ERROR; \
+        return; \
+    } \
+} UPRV_BLOCK_MACRO_END
+#define RETURN_VOID_IF_NOT_VALID_PARA_OR_LINE(bidi, errcode) UPRV_BLOCK_MACRO_BEGIN { \
+    if(!IS_VALID_PARA_OR_LINE(bidi)) { \
+        errcode=U_INVALID_STATE_ERROR; \
+        return; \
+    } \
+} UPRV_BLOCK_MACRO_END
+#define RETURN_VOID_IF_BAD_RANGE(arg, start, limit, errcode) UPRV_BLOCK_MACRO_BEGIN { \
+    if((arg)<(start) || (arg)>=(limit)) { \
+        (errcode)=U_ILLEGAL_ARGUMENT_ERROR; \
+        return; \
+    } \
+} UPRV_BLOCK_MACRO_END
 
 /* helper function to (re)allocate memory if allowed */
 U_CFUNC UBool
@@ -442,26 +459,26 @@
 /* additional macros used by ubidi_open() - always allow allocation */
 #define getInitialDirPropsMemory(pBiDi, length) \
         ubidi_getMemory((BidiMemoryForAllocation *)&(pBiDi)->dirPropsMemory, &(pBiDi)->dirPropsSize, \
-                        TRUE, (length))
+                        true, (length))
 
 #define getInitialLevelsMemory(pBiDi, length) \
         ubidi_getMemory((BidiMemoryForAllocation *)&(pBiDi)->levelsMemory, &(pBiDi)->levelsSize, \
-                        TRUE, (length))
+                        true, (length))
 
 #define getInitialOpeningsMemory(pBiDi, length) \
         ubidi_getMemory((BidiMemoryForAllocation *)&(pBiDi)->openingsMemory, &(pBiDi)->openingsSize, \
-                        TRUE, (length)*sizeof(Opening))
+                        true, (length)*sizeof(Opening))
 
 #define getInitialParasMemory(pBiDi, length) \
         ubidi_getMemory((BidiMemoryForAllocation *)&(pBiDi)->parasMemory, &(pBiDi)->parasSize, \
-                        TRUE, (length)*sizeof(Para))
+                        true, (length)*sizeof(Para))
 
 #define getInitialRunsMemory(pBiDi, length) \
         ubidi_getMemory((BidiMemoryForAllocation *)&(pBiDi)->runsMemory, &(pBiDi)->runsSize, \
-                        TRUE, (length)*sizeof(Run))
+                        true, (length)*sizeof(Run))
 
 #define getInitialIsolatesMemory(pBiDi, length) \
         ubidi_getMemory((BidiMemoryForAllocation *)&(pBiDi)->isolatesMemory, &(pBiDi)->isolatesSize, \
-                        TRUE, (length)*sizeof(Isolate))
+                        true, (length)*sizeof(Isolate))
 
 #endif
diff --git a/src/third_party/icu/source/common/ubidiln.c b/src/third_party/icu/source/common/ubidiln.cpp
similarity index 98%
rename from src/third_party/icu/source/common/ubidiln.c
rename to src/third_party/icu/source/common/ubidiln.cpp
index 2c54926..188bf89 100644
--- a/src/third_party/icu/source/common/ubidiln.c
+++ b/src/third_party/icu/source/common/ubidiln.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 ******************************************************************************
 *   file name:  ubidiln.c
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -14,8 +16,10 @@
 *   created by: Markus W. Scherer, updated by Matitiahu Allouche
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "cmemory.h"
 #include "unicode/utypes.h"
 #include "unicode/ustring.h"
@@ -517,7 +521,7 @@
 
 /* compute the runs array --------------------------------------------------- */
 
-static int32_t getRunFromLogicalIndex(UBiDi *pBiDi, int32_t logicalIndex, UErrorCode *pErrorCode) {
+static int32_t getRunFromLogicalIndex(UBiDi *pBiDi, int32_t logicalIndex) {
     Run *runs=pBiDi->runs;
     int32_t runCount=pBiDi->runCount, visualStart=0, i, length, logicalStart;
 
@@ -530,9 +534,7 @@
         visualStart+=length;
     }
     /* we should never get here */
-    U_ASSERT(FALSE);
-    *pErrorCode = U_INVALID_STATE_ERROR;
-    return 0;
+    UPRV_UNREACHABLE;
 }
 
 /*
@@ -547,7 +549,7 @@
  * negative number of BiDi control characters within this run.
  */
 U_CFUNC UBool
-ubidi_getRuns(UBiDi *pBiDi, UErrorCode *pErrorCode) {
+ubidi_getRuns(UBiDi *pBiDi, UErrorCode*) {
     /*
      * This method returns immediately if the runs are already set. This
      * includes the case of length==0 (handled in setPara)..
@@ -688,7 +690,7 @@
                       *limit=start+pBiDi->insertPoints.size;
         int32_t runIndex;
         for(point=start; point<limit; point++) {
-            runIndex=getRunFromLogicalIndex(pBiDi, point->pos, pErrorCode);
+            runIndex=getRunFromLogicalIndex(pBiDi, point->pos);
             pBiDi->runs[runIndex].insertRemove|=point->flag;
         }
     }
@@ -699,7 +701,7 @@
         const UChar *start=pBiDi->text, *limit=start+pBiDi->length, *pu;
         for(pu=start; pu<limit; pu++) {
             if(IS_BIDI_CONTROL_CHAR(*pu)) {
-                runIndex=getRunFromLogicalIndex(pBiDi, (int32_t)(pu-start), pErrorCode);
+                runIndex=getRunFromLogicalIndex(pBiDi, (int32_t)(pu-start));
                 pBiDi->runs[runIndex].insertRemove--;
             }
         }
diff --git a/src/third_party/icu/source/common/ubiditransform.cpp b/src/third_party/icu/source/common/ubiditransform.cpp
new file mode 100644
index 0000000..d56bf15
--- /dev/null
+++ b/src/third_party/icu/source/common/ubiditransform.cpp
@@ -0,0 +1,530 @@
+/*
+******************************************************************************
+*
+* © 2016 and later: Unicode, Inc. and others.
+* License & terms of use: http://www.unicode.org/copyright.html
+*
+******************************************************************************
+*   file name:  ubiditransform.c
+*   encoding:   UTF-8
+*   tab size:   8 (not used)
+*   indentation:4
+*
+*   created on: 2016jul24
+*   created by: Lina Kemmel
+*
+*/
+
+#include "cmemory.h"
+#include "unicode/ubidi.h"
+#include "unicode/ustring.h"
+#include "unicode/ushape.h"
+#include "unicode/utf16.h"
+#include "ustr_imp.h"
+#include "unicode/ubiditransform.h"
+
+/* Some convenience defines */
+#define LTR                     UBIDI_LTR
+#define RTL                     UBIDI_RTL
+#define LOGICAL                 UBIDI_LOGICAL
+#define VISUAL                  UBIDI_VISUAL
+#define SHAPE_LOGICAL           U_SHAPE_TEXT_DIRECTION_LOGICAL
+#define SHAPE_VISUAL            U_SHAPE_TEXT_DIRECTION_VISUAL_LTR
+
+#define CHECK_LEN(STR, LEN, ERROR) UPRV_BLOCK_MACRO_BEGIN { \
+    if (LEN == 0) return 0; \
+    if (LEN < -1) { *(ERROR) = U_ILLEGAL_ARGUMENT_ERROR; return 0; } \
+    if (LEN == -1) LEN = u_strlen(STR); \
+} UPRV_BLOCK_MACRO_END
+
+#define MAX_ACTIONS     7
+
+/**
+ * Typedef for a pointer to a function, which performs some operation (such as
+ * reordering, setting "inverse" mode, character mirroring, etc.). Return value
+ * indicates whether the text was changed in the course of this operation or
+ * not.
+ */
+typedef UBool (*UBiDiAction)(UBiDiTransform *, UErrorCode *);
+
+/**
+ * Structure that holds a predefined reordering scheme, including the following
+ * information:
+ * <ul>
+ * <li>an input base direction,</li>
+ * <li>an input order,</li>
+ * <li>an output base direction,</li>
+ * <li>an output order,</li>
+ * <li>a digit shaping direction,</li>
+ * <li>a letter shaping direction,</li>
+ * <li>a base direction that should be applied when the reordering engine is
+ *     invoked (which can not always be derived from the caller-defined
+ *     options),</li>
+ * <li>an array of pointers to functions that accomplish the bidi layout
+ *     transformation.</li>
+ * </ul>
+ */
+typedef struct {
+    UBiDiLevel        inLevel;               /* input level */
+    UBiDiOrder        inOrder;               /* input order */
+    UBiDiLevel        outLevel;              /* output level */
+    UBiDiOrder        outOrder;              /* output order */
+    uint32_t          digitsDir;             /* digit shaping direction */
+    uint32_t          lettersDir;            /* letter shaping direction */
+    UBiDiLevel        baseLevel;             /* paragraph level to be used with setPara */
+    const UBiDiAction actions[MAX_ACTIONS];  /* array of pointers to functions carrying out the transformation */
+} ReorderingScheme;
+
+struct UBiDiTransform {
+    UBiDi                   *pBidi;             /* pointer to a UBiDi object */
+    const ReorderingScheme  *pActiveScheme;     /* effective reordering scheme */
+    UChar                   *src;               /* input text */
+    UChar                   *dest;              /* output text */
+    uint32_t                srcLength;          /* input text length - not really needed as we are zero-terminated and can u_strlen */
+    uint32_t                srcSize;            /* input text capacity excluding the trailing zero */
+    uint32_t                destSize;           /* output text capacity */
+    uint32_t                *pDestLength;       /* number of UChars written to dest */
+    uint32_t                reorderingOptions;  /* reordering options - currently only suppot DO_MIRRORING */
+    uint32_t                digits;             /* digit option for ArabicShaping */
+    uint32_t                letters;            /* letter option for ArabicShaping */
+};
+
+U_CAPI UBiDiTransform* U_EXPORT2
+ubiditransform_open(UErrorCode *pErrorCode)
+{
+    UBiDiTransform *pBiDiTransform = NULL;
+    if (U_SUCCESS(*pErrorCode)) {
+        pBiDiTransform = (UBiDiTransform*) uprv_calloc(1, sizeof(UBiDiTransform));
+        if (pBiDiTransform == NULL) {
+            *pErrorCode = U_MEMORY_ALLOCATION_ERROR;
+        }
+    }
+    return pBiDiTransform;
+}
+
+U_CAPI void U_EXPORT2
+ubiditransform_close(UBiDiTransform *pBiDiTransform)
+{
+    if (pBiDiTransform != NULL) {
+        if (pBiDiTransform->pBidi != NULL) {
+            ubidi_close(pBiDiTransform->pBidi);
+        }
+        if (pBiDiTransform->src != NULL) {
+            uprv_free(pBiDiTransform->src);
+        }
+        uprv_free(pBiDiTransform);
+    }
+}
+
+/**
+ * Performs Bidi resolution of text.
+ * 
+ * @param pTransform Pointer to the <code>UBiDiTransform</code> structure.
+ * @param pErrorCode Pointer to the error code value.
+ *
+ * @return Whether or not this function modifies the text. Besides the return
+ * value, the caller should also check <code>U_SUCCESS(*pErrorCode)</code>.
+ */
+static UBool
+action_resolve(UBiDiTransform *pTransform, UErrorCode *pErrorCode)
+{
+    ubidi_setPara(pTransform->pBidi, pTransform->src, pTransform->srcLength,
+            pTransform->pActiveScheme->baseLevel, NULL, pErrorCode);
+    return FALSE;
+}
+
+/**
+ * Performs basic reordering of text (Logical -> Visual LTR).
+ * 
+ * @param pTransform Pointer to the <code>UBiDiTransform</code> structure.
+ * @param pErrorCode Pointer to the error code value.
+ *
+ * @return Whether or not this function modifies the text. Besides the return
+ * value, the caller should also check <code>U_SUCCESS(*pErrorCode)</code>.
+ */
+static UBool
+action_reorder(UBiDiTransform *pTransform, UErrorCode *pErrorCode)
+{
+    ubidi_writeReordered(pTransform->pBidi, pTransform->dest, pTransform->destSize,
+            static_cast<uint16_t>(pTransform->reorderingOptions), pErrorCode);
+
+    *pTransform->pDestLength = pTransform->srcLength;
+    pTransform->reorderingOptions = UBIDI_REORDER_DEFAULT;
+    return TRUE;
+}
+
+/**
+ * Sets "inverse" mode on the <code>UBiDi</code> object.
+ * 
+ * @param pTransform Pointer to the <code>UBiDiTransform</code> structure.
+ * @param pErrorCode Pointer to the error code value.
+ *
+ * @return Whether or not this function modifies the text. Besides the return
+ * value, the caller should also check <code>U_SUCCESS(*pErrorCode)</code>.
+ */
+static UBool
+action_setInverse(UBiDiTransform *pTransform, UErrorCode *pErrorCode)
+{
+    (void)pErrorCode;
+    ubidi_setInverse(pTransform->pBidi, TRUE);
+    ubidi_setReorderingMode(pTransform->pBidi, UBIDI_REORDER_INVERSE_LIKE_DIRECT);
+    return FALSE;
+}
+
+/**
+ * Sets "runs only" reordering mode indicating a Logical LTR <-> Logical RTL
+ * transformation.
+ * 
+ * @param pTransform Pointer to the <code>UBiDiTransform</code> structure.
+ * @param pErrorCode Pointer to the error code value.
+ *
+ * @return Whether or not this function modifies the text. Besides the return
+ * value, the caller should also check <code>U_SUCCESS(*pErrorCode)</code>.
+ */
+static UBool
+action_setRunsOnly(UBiDiTransform *pTransform, UErrorCode *pErrorCode)
+{
+    (void)pErrorCode;
+    ubidi_setReorderingMode(pTransform->pBidi, UBIDI_REORDER_RUNS_ONLY);
+    return FALSE;
+}
+
+/**
+ * Performs string reverse.
+ * 
+ * @param pTransform Pointer to the <code>UBiDiTransform</code> structure.
+ * @param pErrorCode Pointer to the error code value.
+ *
+ * @return Whether or not this function modifies the text. Besides the return
+ * value, the caller should also check <code>U_SUCCESS(*pErrorCode)</code>.
+ */
+static UBool
+action_reverse(UBiDiTransform *pTransform, UErrorCode *pErrorCode)
+{
+    ubidi_writeReverse(pTransform->src, pTransform->srcLength,
+            pTransform->dest, pTransform->destSize,
+            UBIDI_REORDER_DEFAULT, pErrorCode);
+    *pTransform->pDestLength = pTransform->srcLength;
+    return TRUE;
+}
+
+/**
+ * Applies a new value to the text that serves as input at the current
+ * processing step. This value is identical to the original one when we begin
+ * the processing, but usually changes as the transformation progresses.
+ * 
+ * @param pTransform A pointer to the <code>UBiDiTransform</code> structure.
+ * @param newSrc A pointer whose value is to be used as input text.
+ * @param newLength A length of the new text in <code>UChar</code>s.
+ * @param newSize A new source capacity in <code>UChar</code>s.
+ * @param pErrorCode Pointer to the error code value.
+ */
+static void
+updateSrc(UBiDiTransform *pTransform, const UChar *newSrc, uint32_t newLength,
+        uint32_t newSize, UErrorCode *pErrorCode)
+{
+    if (newSize < newLength) {
+        *pErrorCode = U_BUFFER_OVERFLOW_ERROR;
+        return;
+    }
+    if (newSize > pTransform->srcSize) {
+        newSize += 50; // allocate slightly more than needed right now
+        if (pTransform->src != NULL) {
+            uprv_free(pTransform->src);
+            pTransform->src = NULL;
+        }
+        pTransform->src = (UChar *)uprv_malloc(newSize * sizeof(UChar));
+        if (pTransform->src == NULL) {
+            *pErrorCode = U_MEMORY_ALLOCATION_ERROR;
+            //pTransform->srcLength = pTransform->srcSize = 0;
+            return;
+        }
+        pTransform->srcSize = newSize;
+    }
+    u_strncpy(pTransform->src, newSrc, newLength);
+    pTransform->srcLength = u_terminateUChars(pTransform->src,
+    		pTransform->srcSize, newLength, pErrorCode);
+}
+
+/**
+ * Calls a lower level shaping function.
+ * 
+ * @param pTransform Pointer to the <code>UBiDiTransform</code> structure.
+ * @param options Shaping options.
+ * @param pErrorCode Pointer to the error code value.
+ */
+static void
+doShape(UBiDiTransform *pTransform, uint32_t options, UErrorCode *pErrorCode)
+{
+    *pTransform->pDestLength = u_shapeArabic(pTransform->src,
+            pTransform->srcLength, pTransform->dest, pTransform->destSize,
+            options, pErrorCode);
+}
+
+/**
+ * Performs digit and letter shaping.
+ * 
+ * @param pTransform Pointer to the <code>UBiDiTransform</code> structure.
+ * @param pErrorCode Pointer to the error code value.
+ *
+ * @return Whether or not this function modifies the text. Besides the return
+ * value, the caller should also check <code>U_SUCCESS(*pErrorCode)</code>.
+ */
+static UBool
+action_shapeArabic(UBiDiTransform *pTransform, UErrorCode *pErrorCode)
+{
+    if ((pTransform->letters | pTransform->digits) == 0) {
+        return FALSE;
+    }
+    if (pTransform->pActiveScheme->lettersDir == pTransform->pActiveScheme->digitsDir) {
+        doShape(pTransform, pTransform->letters | pTransform->digits | pTransform->pActiveScheme->lettersDir,
+                pErrorCode);
+    } else {
+        doShape(pTransform, pTransform->digits | pTransform->pActiveScheme->digitsDir, pErrorCode);
+        if (U_SUCCESS(*pErrorCode)) {
+            updateSrc(pTransform, pTransform->dest, *pTransform->pDestLength,
+                    *pTransform->pDestLength, pErrorCode);
+            doShape(pTransform, pTransform->letters | pTransform->pActiveScheme->lettersDir,
+                    pErrorCode);
+        }
+    }
+    return TRUE;
+}
+
+/**
+ * Performs character mirroring.
+ * 
+ * @param pTransform Pointer to the <code>UBiDiTransform</code> structure.
+ * @param pErrorCode Pointer to the error code value.
+ *
+ * @return Whether or not this function modifies the text. Besides the return
+ * value, the caller should also check <code>U_SUCCESS(*pErrorCode)</code>.
+ */
+static UBool
+action_mirror(UBiDiTransform *pTransform, UErrorCode *pErrorCode)
+{
+    UChar32 c;
+    uint32_t i = 0, j = 0;
+    if (0 == (pTransform->reorderingOptions & UBIDI_DO_MIRRORING)) {
+        return FALSE;
+    }
+    if (pTransform->destSize < pTransform->srcLength) {
+        *pErrorCode = U_BUFFER_OVERFLOW_ERROR;
+        return FALSE;
+    }
+    do {
+        UBool isOdd = ubidi_getLevelAt(pTransform->pBidi, i) & 1;
+        U16_NEXT(pTransform->src, i, pTransform->srcLength, c); 
+        U16_APPEND_UNSAFE(pTransform->dest, j, isOdd ? u_charMirror(c) : c);
+    } while (i < pTransform->srcLength);
+    
+    *pTransform->pDestLength = pTransform->srcLength;
+    pTransform->reorderingOptions = UBIDI_REORDER_DEFAULT;
+    return TRUE;
+}
+
+/**
+ * All possible reordering schemes.
+ *
+ */
+static const ReorderingScheme Schemes[] =
+{
+    /* 0: Logical LTR => Visual LTR */
+    {LTR, LOGICAL, LTR, VISUAL, SHAPE_LOGICAL, SHAPE_LOGICAL, LTR,
+            {action_shapeArabic, action_resolve, action_reorder, NULL}},
+    /* 1: Logical RTL => Visual LTR */
+    {RTL, LOGICAL, LTR, VISUAL, SHAPE_LOGICAL, SHAPE_VISUAL, RTL,
+            {action_resolve, action_reorder, action_shapeArabic, NULL}},
+    /* 2: Logical LTR => Visual RTL */
+    {LTR, LOGICAL, RTL, VISUAL, SHAPE_LOGICAL, SHAPE_LOGICAL, LTR,
+            {action_shapeArabic, action_resolve, action_reorder, action_reverse, NULL}},
+    /* 3: Logical RTL => Visual RTL */
+    {RTL, LOGICAL, RTL, VISUAL, SHAPE_LOGICAL, SHAPE_VISUAL, RTL,
+            {action_resolve, action_reorder, action_shapeArabic, action_reverse, NULL}},
+    /* 4: Visual LTR => Logical RTL */
+    {LTR, VISUAL, RTL, LOGICAL, SHAPE_LOGICAL, SHAPE_VISUAL, RTL,
+            {action_shapeArabic, action_setInverse, action_resolve, action_reorder, NULL}},
+    /* 5: Visual RTL => Logical RTL */
+    {RTL, VISUAL, RTL, LOGICAL, SHAPE_LOGICAL, SHAPE_VISUAL, RTL,
+            {action_reverse, action_shapeArabic, action_setInverse, action_resolve, action_reorder, NULL}},
+    /* 6: Visual LTR => Logical LTR */
+    {LTR, VISUAL, LTR, LOGICAL, SHAPE_LOGICAL, SHAPE_LOGICAL, LTR,
+            {action_setInverse, action_resolve, action_reorder, action_shapeArabic, NULL}},
+    /* 7: Visual RTL => Logical LTR */
+    {RTL, VISUAL, LTR, LOGICAL, SHAPE_LOGICAL, SHAPE_LOGICAL, LTR,
+            {action_reverse, action_setInverse, action_resolve, action_reorder, action_shapeArabic, NULL}},
+    /* 8: Logical LTR => Logical RTL */
+    {LTR, LOGICAL, RTL, LOGICAL, SHAPE_LOGICAL, SHAPE_LOGICAL, LTR,
+            {action_shapeArabic, action_resolve, action_mirror, action_setRunsOnly, action_resolve, action_reorder, NULL}},
+    /* 9: Logical RTL => Logical LTR */
+    {RTL, LOGICAL, LTR, LOGICAL, SHAPE_LOGICAL, SHAPE_LOGICAL, RTL,
+            {action_resolve, action_mirror, action_setRunsOnly, action_resolve, action_reorder, action_shapeArabic, NULL}},
+    /* 10: Visual LTR => Visual RTL */
+    {LTR, VISUAL, RTL, VISUAL, SHAPE_LOGICAL, SHAPE_VISUAL, LTR,
+            {action_shapeArabic, action_setInverse, action_resolve, action_mirror, action_reverse, NULL}},
+    /* 11: Visual RTL => Visual LTR */
+    {RTL, VISUAL, LTR, VISUAL, SHAPE_LOGICAL, SHAPE_VISUAL, LTR,
+            {action_reverse, action_shapeArabic, action_setInverse, action_resolve, action_mirror, NULL}},
+    /* 12: Logical LTR => Logical LTR */
+    {LTR, LOGICAL, LTR, LOGICAL, SHAPE_LOGICAL, SHAPE_LOGICAL, LTR,
+            {action_resolve, action_mirror, action_shapeArabic, NULL}},
+    /* 13: Logical RTL => Logical RTL */
+    {RTL, LOGICAL, RTL, LOGICAL, SHAPE_VISUAL, SHAPE_LOGICAL, RTL,
+            {action_resolve, action_mirror, action_shapeArabic, NULL}},
+    /* 14: Visual LTR => Visual LTR */
+    {LTR, VISUAL, LTR, VISUAL, SHAPE_LOGICAL, SHAPE_VISUAL, LTR,
+            {action_resolve, action_mirror, action_shapeArabic, NULL}},
+    /* 15: Visual RTL => Visual RTL */
+    {RTL, VISUAL, RTL, VISUAL, SHAPE_LOGICAL, SHAPE_VISUAL, LTR,
+            {action_reverse, action_resolve, action_mirror, action_shapeArabic, action_reverse, NULL}}
+};
+
+static const uint32_t nSchemes = sizeof(Schemes) / sizeof(*Schemes);
+
+/**
+ * When the direction option is <code>UBIDI_DEFAULT_LTR</code> or
+ * <code>UBIDI_DEFAULT_RTL</code>, resolve the base direction according to that
+ * of the first strong bidi character.
+ */
+static void
+resolveBaseDirection(const UChar *text, uint32_t length,
+        UBiDiLevel *pInLevel, UBiDiLevel *pOutLevel)
+{
+    switch (*pInLevel) {
+        case UBIDI_DEFAULT_LTR:
+        case UBIDI_DEFAULT_RTL: {
+            UBiDiLevel level = static_cast<UBiDiLevel>(ubidi_getBaseDirection(text, length));
+            *pInLevel = static_cast<UBiDiLevel>(level != UBIDI_NEUTRAL) ? level
+                    : *pInLevel == UBIDI_DEFAULT_RTL ? static_cast<UBiDiLevel>(RTL) : static_cast<UBiDiLevel>(LTR);
+            break;
+        }
+        default:
+            *pInLevel &= 1;
+            break;
+    }
+    switch (*pOutLevel) {
+        case UBIDI_DEFAULT_LTR:
+        case UBIDI_DEFAULT_RTL:
+            *pOutLevel = *pInLevel;
+            break;
+        default:
+            *pOutLevel &= 1;
+            break;
+    }
+}
+
+/**
+ * Finds a valid <code>ReorderingScheme</code> matching the
+ * caller-defined scheme.
+ * 
+ * @return A valid <code>ReorderingScheme</code> object or NULL
+ */
+static const ReorderingScheme*
+findMatchingScheme(UBiDiLevel inLevel, UBiDiLevel outLevel,
+        UBiDiOrder inOrder, UBiDiOrder outOrder)
+{
+    uint32_t i;
+    for (i = 0; i < nSchemes; i++) {
+        const ReorderingScheme *pScheme = Schemes + i;
+        if (inLevel == pScheme->inLevel && outLevel == pScheme->outLevel
+                && inOrder == pScheme->inOrder && outOrder == pScheme->outOrder) {
+            return pScheme;
+        }
+    }
+    return NULL;
+}
+
+U_CAPI uint32_t U_EXPORT2
+ubiditransform_transform(UBiDiTransform *pBiDiTransform,
+            const UChar *src, int32_t srcLength,
+            UChar *dest, int32_t destSize,
+            UBiDiLevel inParaLevel, UBiDiOrder inOrder,
+            UBiDiLevel outParaLevel, UBiDiOrder outOrder,
+            UBiDiMirroring doMirroring, uint32_t shapingOptions,
+            UErrorCode *pErrorCode)
+{
+    uint32_t destLength = 0;
+    UBool textChanged = FALSE;
+    const UBiDiTransform *pOrigTransform = pBiDiTransform;
+    const UBiDiAction *action = NULL;
+
+    if (U_FAILURE(*pErrorCode)) {
+        return 0;
+    }
+    if (src == NULL || dest == NULL) {
+        *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR;
+        return 0;
+    }
+    CHECK_LEN(src, srcLength, pErrorCode);
+    CHECK_LEN(dest, destSize, pErrorCode);
+
+    if (pBiDiTransform == NULL) {
+        pBiDiTransform = ubiditransform_open(pErrorCode);
+        if (U_FAILURE(*pErrorCode)) {
+            return 0;
+        }
+    }
+    /* Current limitation: in multiple paragraphs will be resolved according
+       to the 1st paragraph */
+    resolveBaseDirection(src, srcLength, &inParaLevel, &outParaLevel);
+
+    pBiDiTransform->pActiveScheme = findMatchingScheme(inParaLevel, outParaLevel,
+            inOrder, outOrder);
+    if (pBiDiTransform->pActiveScheme == NULL) {
+        goto cleanup;
+    }
+    pBiDiTransform->reorderingOptions = doMirroring ? UBIDI_DO_MIRRORING
+            : UBIDI_REORDER_DEFAULT;
+
+    /* Ignore TEXT_DIRECTION_* flags, as we apply our own depending on the text
+       scheme at the time shaping is invoked. */
+    shapingOptions &= ~U_SHAPE_TEXT_DIRECTION_MASK;
+    pBiDiTransform->digits = shapingOptions & ~U_SHAPE_LETTERS_MASK;
+    pBiDiTransform->letters = shapingOptions & ~U_SHAPE_DIGITS_MASK;
+
+    updateSrc(pBiDiTransform, src, srcLength, destSize > srcLength ? destSize : srcLength, pErrorCode);
+    if (U_FAILURE(*pErrorCode)) {
+        goto cleanup;
+    }
+    if (pBiDiTransform->pBidi == NULL) {
+        pBiDiTransform->pBidi = ubidi_openSized(0, 0, pErrorCode);
+        if (U_FAILURE(*pErrorCode)) {
+            goto cleanup;
+        }
+    }
+    pBiDiTransform->dest = dest;
+    pBiDiTransform->destSize = destSize;
+    pBiDiTransform->pDestLength = &destLength;
+
+    /* Checking for U_SUCCESS() within the loop to bail out on first failure. */
+    for (action = pBiDiTransform->pActiveScheme->actions; *action && U_SUCCESS(*pErrorCode); action++) {
+        if ((*action)(pBiDiTransform, pErrorCode)) {
+            if (action + 1) {
+                updateSrc(pBiDiTransform, pBiDiTransform->dest, *pBiDiTransform->pDestLength,
+                        *pBiDiTransform->pDestLength, pErrorCode);
+            }
+            textChanged = TRUE;
+        }
+    }
+    ubidi_setInverse(pBiDiTransform->pBidi, FALSE);
+
+    if (!textChanged && U_SUCCESS(*pErrorCode)) {
+        /* Text was not changed - just copy src to dest */
+        if (destSize < srcLength) {
+            *pErrorCode = U_BUFFER_OVERFLOW_ERROR;
+        } else {
+            u_strncpy(dest, src, srcLength);
+            destLength = srcLength;
+        }
+    }
+cleanup:
+    if (pOrigTransform != pBiDiTransform) {
+        ubiditransform_close(pBiDiTransform);
+    } else {
+        pBiDiTransform->dest = NULL;
+        pBiDiTransform->pDestLength = NULL;
+        pBiDiTransform->srcLength = 0;
+        pBiDiTransform->destSize = 0;
+    }
+    return U_FAILURE(*pErrorCode) ? 0 : destLength;
+}
diff --git a/src/third_party/icu/source/common/ubidiwrt.c b/src/third_party/icu/source/common/ubidiwrt.cpp
similarity index 96%
rename from src/third_party/icu/source/common/ubidiwrt.c
rename to src/third_party/icu/source/common/ubidiwrt.cpp
index 2c64959..a69c0a4 100644
--- a/src/third_party/icu/source/common/ubidiwrt.c
+++ b/src/third_party/icu/source/common/ubidiwrt.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 ******************************************************************************
 *   file name:  ubidiwrt.c
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -38,7 +40,7 @@
  * Further assumptions for all UTFs:
  * - u_charMirror(c) needs the same number of code units as c
  */
-#if UTF_SIZE==8
+#if defined(UTF_SIZE) && UTF_SIZE==8
 # error reimplement ubidi_writeReordered() for UTF-8, see comment above
 #endif
 
@@ -344,6 +346,13 @@
     return u_terminateUChars(dest, destSize, destLength, pErrorCode);
 }
 
+// Ticket 20907 - The optimizer in MSVC/Visual Studio versions below 16.4 has trouble with this
+// function on Windows ARM64. As a work-around, we disable optimizations for this function.
+// This work-around could/should be removed once the following versions of Visual Studio are no
+// longer supported: All versions of VS2017, and versions of VS2019 below 16.4.
+#if (defined(_MSC_VER) && (defined(_M_ARM64)) && (_MSC_VER < 1924))
+#pragma optimize( "", off )
+#endif
 U_CAPI int32_t U_EXPORT2
 ubidi_writeReordered(UBiDi *pBiDi,
                      UChar *dest, int32_t destSize,
@@ -636,3 +645,6 @@
 
     return u_terminateUChars(saveDest, destCapacity, destCapacity-destSize, pErrorCode);
 }
+#if (defined(_MSC_VER) && (defined(_M_ARM64)) && (_MSC_VER < 1924))
+#pragma optimize( "", on )
+#endif
diff --git a/src/third_party/icu/source/common/ubrk.cpp b/src/third_party/icu/source/common/ubrk.cpp
index d53aa1a..54db6d2 100644
--- a/src/third_party/icu/source/common/ubrk.cpp
+++ b/src/third_party/icu/source/common/ubrk.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ********************************************************************************
 *   Copyright (C) 1996-2015, International Business Machines
@@ -9,7 +11,9 @@
 
 #if !UCONFIG_NO_BREAK_ITERATION
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/ubrk.h"
 
 #include "unicode/brkiter.h"
@@ -19,6 +23,7 @@
 #include "unicode/rbbi.h"
 #include "rbbirb.h"
 #include "uassert.h"
+#include "cmemory.h"
 
 U_NAMESPACE_USE
 
@@ -118,7 +123,28 @@
 }
 
 
-
+U_CAPI UBreakIterator* U_EXPORT2
+ubrk_openBinaryRules(const uint8_t *binaryRules, int32_t rulesLength,
+                     const UChar *  text, int32_t textLength,
+                     UErrorCode *   status)
+{
+    if (U_FAILURE(*status)) {
+        return NULL;
+    }
+    if (rulesLength < 0) {
+        *status = U_ILLEGAL_ARGUMENT_ERROR;
+        return NULL;
+    }
+    LocalPointer<RuleBasedBreakIterator> lpRBBI(new RuleBasedBreakIterator(binaryRules, rulesLength, *status), *status);
+    if (U_FAILURE(*status)) {
+        return NULL;
+    }
+    UBreakIterator *uBI = reinterpret_cast<UBreakIterator *>(lpRBBI.orphan());
+    if (text != NULL) {
+        ubrk_setText(uBI, text, textLength, status);
+    }
+    return uBI;
+}
 
 
 U_CAPI UBreakIterator * U_EXPORT2
@@ -287,7 +313,8 @@
 }
 
 
-void ubrk_refreshUText(UBreakIterator *bi,
+U_CAPI void U_EXPORT2
+ubrk_refreshUText(UBreakIterator *bi,
                        UText          *text,
                        UErrorCode     *status)
 {
@@ -295,6 +322,39 @@
     bii->refreshInputText(text, *status);
 }
 
+U_CAPI int32_t U_EXPORT2
+ubrk_getBinaryRules(UBreakIterator *bi,
+                    uint8_t *       binaryRules, int32_t rulesCapacity,
+                    UErrorCode *    status)
+{
+    if (U_FAILURE(*status)) {
+        return 0;
+    }
+    if ((binaryRules == NULL && rulesCapacity > 0) || rulesCapacity < 0) {
+        *status = U_ILLEGAL_ARGUMENT_ERROR;
+        return 0;
+    }
+    RuleBasedBreakIterator* rbbi;
+    if ((rbbi = dynamic_cast<RuleBasedBreakIterator*>(reinterpret_cast<BreakIterator*>(bi))) == NULL) {
+        *status = U_ILLEGAL_ARGUMENT_ERROR;
+        return 0;
+    }
+    uint32_t rulesLength;
+    const uint8_t * returnedRules = rbbi->getBinaryRules(rulesLength);
+    if (rulesLength > INT32_MAX) {
+        *status = U_INDEX_OUTOFBOUNDS_ERROR;
+        return 0;
+    }
+    if (binaryRules != NULL) { // if not preflighting
+        // Here we know rulesLength <= INT32_MAX and rulesCapacity >= 0, can cast safely
+        if ((int32_t)rulesLength > rulesCapacity) {
+            *status = U_BUFFER_OVERFLOW_ERROR;
+        } else {
+            uprv_memcpy(binaryRules, returnedRules, rulesLength);
+        }
+    }
+    return (int32_t)rulesLength;
+}
 
 
 #endif /* #if !UCONFIG_NO_BREAK_ITERATION */
diff --git a/src/third_party/icu/source/common/ubrkimpl.h b/src/third_party/icu/source/common/ubrkimpl.h
index e490971..8197f66 100644
--- a/src/third_party/icu/source/common/ubrkimpl.h
+++ b/src/third_party/icu/source/common/ubrkimpl.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
 *   Copyright (C) 2006, International Business Machines
diff --git a/src/third_party/icu/source/common/ucase.cpp b/src/third_party/icu/source/common/ucase.cpp
index 0930574..e03e634 100644
--- a/src/third_party/icu/source/common/ucase.cpp
+++ b/src/third_party/icu/source/common/ucase.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  ucase.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -17,7 +19,9 @@
 *   Much code moved here (and modified) from uchar.c.
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/utypes.h"
 #include "unicode/unistr.h"
 #include "unicode/uset.h"
@@ -45,13 +49,6 @@
 #define INCLUDED_FROM_UCASE_CPP
 #include "ucase_props_data.h"
 
-/* UCaseProps singleton ----------------------------------------------------- */
-
-U_CAPI const UCaseProps * U_EXPORT2
-ucase_getSingleton() {
-    return &ucase_props_singleton;
-}
-
 /* set of property starts for UnicodeSet ------------------------------------ */
 
 static UBool U_CALLCONV
@@ -63,13 +60,13 @@
 }
 
 U_CFUNC void U_EXPORT2
-ucase_addPropertyStarts(const UCaseProps *csp, const USetAdder *sa, UErrorCode *pErrorCode) {
+ucase_addPropertyStarts(const USetAdder *sa, UErrorCode *pErrorCode) {
     if(U_FAILURE(*pErrorCode)) {
         return;
     }
 
     /* add the start code point of each same-value range of the trie */
-    utrie2_enum(&csp->trie, NULL, _enumPropertyStartsRange, sa);
+    utrie2_enum(&ucase_props_singleton.trie, NULL, _enumPropertyStartsRange, sa);
 
     /* add code points with hardcoded properties, plus the ones following them */
 
@@ -83,9 +80,12 @@
 
 /* data access primitives --------------------------------------------------- */
 
-#define GET_EXCEPTIONS(csp, props) ((csp)->exceptions+((props)>>UCASE_EXC_SHIFT))
+U_CFUNC const UTrie2 * U_EXPORT2
+ucase_getTrie() {
+    return &ucase_props_singleton.trie;
+}
 
-#define PROPS_HAS_EXCEPTION(props) ((props)&UCASE_EXCEPTION)
+#define GET_EXCEPTIONS(csp, props) ((csp)->exceptions+((props)>>UCASE_EXC_SHIFT))
 
 /* number of bits in an 8-bit integer value */
 static const uint8_t flagsOffset[256]={
@@ -119,7 +119,7 @@
  *               moved to the last uint16_t of the value, use +1 for beginning of next slot
  * @param value (out) int32_t or uint32_t output if hasSlot, otherwise not modified
  */
-#define GET_SLOT_VALUE(excWord, idx, pExc16, value) \
+#define GET_SLOT_VALUE(excWord, idx, pExc16, value) UPRV_BLOCK_MACRO_BEGIN { \
     if(((excWord)&UCASE_EXC_DOUBLE_SLOTS)==0) { \
         (pExc16)+=SLOT_OFFSET(excWord, idx); \
         (value)=*pExc16; \
@@ -127,20 +127,26 @@
         (pExc16)+=2*SLOT_OFFSET(excWord, idx); \
         (value)=*pExc16++; \
         (value)=((value)<<16)|*pExc16; \
-    }
+    } \
+} UPRV_BLOCK_MACRO_END
 
 /* simple case mappings ----------------------------------------------------- */
 
 U_CAPI UChar32 U_EXPORT2
-ucase_tolower(const UCaseProps *csp, UChar32 c) {
-    uint16_t props=UTRIE2_GET16(&csp->trie, c);
-    if(!PROPS_HAS_EXCEPTION(props)) {
-        if(UCASE_GET_TYPE(props)>=UCASE_UPPER) {
+ucase_tolower(UChar32 c) {
+    uint16_t props=UTRIE2_GET16(&ucase_props_singleton.trie, c);
+    if(!UCASE_HAS_EXCEPTION(props)) {
+        if(UCASE_IS_UPPER_OR_TITLE(props)) {
             c+=UCASE_GET_DELTA(props);
         }
     } else {
-        const uint16_t *pe=GET_EXCEPTIONS(csp, props);
+        const uint16_t *pe=GET_EXCEPTIONS(&ucase_props_singleton, props);
         uint16_t excWord=*pe++;
+        if(HAS_SLOT(excWord, UCASE_EXC_DELTA) && UCASE_IS_UPPER_OR_TITLE(props)) {
+            int32_t delta;
+            GET_SLOT_VALUE(excWord, UCASE_EXC_DELTA, pe, delta);
+            return (excWord&UCASE_EXC_DELTA_IS_NEGATIVE)==0 ? c+delta : c-delta;
+        }
         if(HAS_SLOT(excWord, UCASE_EXC_LOWER)) {
             GET_SLOT_VALUE(excWord, UCASE_EXC_LOWER, pe, c);
         }
@@ -149,15 +155,20 @@
 }
 
 U_CAPI UChar32 U_EXPORT2
-ucase_toupper(const UCaseProps *csp, UChar32 c) {
-    uint16_t props=UTRIE2_GET16(&csp->trie, c);
-    if(!PROPS_HAS_EXCEPTION(props)) {
+ucase_toupper(UChar32 c) {
+    uint16_t props=UTRIE2_GET16(&ucase_props_singleton.trie, c);
+    if(!UCASE_HAS_EXCEPTION(props)) {
         if(UCASE_GET_TYPE(props)==UCASE_LOWER) {
             c+=UCASE_GET_DELTA(props);
         }
     } else {
-        const uint16_t *pe=GET_EXCEPTIONS(csp, props);
+        const uint16_t *pe=GET_EXCEPTIONS(&ucase_props_singleton, props);
         uint16_t excWord=*pe++;
+        if(HAS_SLOT(excWord, UCASE_EXC_DELTA) && UCASE_GET_TYPE(props)==UCASE_LOWER) {
+            int32_t delta;
+            GET_SLOT_VALUE(excWord, UCASE_EXC_DELTA, pe, delta);
+            return (excWord&UCASE_EXC_DELTA_IS_NEGATIVE)==0 ? c+delta : c-delta;
+        }
         if(HAS_SLOT(excWord, UCASE_EXC_UPPER)) {
             GET_SLOT_VALUE(excWord, UCASE_EXC_UPPER, pe, c);
         }
@@ -166,15 +177,20 @@
 }
 
 U_CAPI UChar32 U_EXPORT2
-ucase_totitle(const UCaseProps *csp, UChar32 c) {
-    uint16_t props=UTRIE2_GET16(&csp->trie, c);
-    if(!PROPS_HAS_EXCEPTION(props)) {
+ucase_totitle(UChar32 c) {
+    uint16_t props=UTRIE2_GET16(&ucase_props_singleton.trie, c);
+    if(!UCASE_HAS_EXCEPTION(props)) {
         if(UCASE_GET_TYPE(props)==UCASE_LOWER) {
             c+=UCASE_GET_DELTA(props);
         }
     } else {
-        const uint16_t *pe=GET_EXCEPTIONS(csp, props);
+        const uint16_t *pe=GET_EXCEPTIONS(&ucase_props_singleton, props);
         uint16_t excWord=*pe++;
+        if(HAS_SLOT(excWord, UCASE_EXC_DELTA) && UCASE_GET_TYPE(props)==UCASE_LOWER) {
+            int32_t delta;
+            GET_SLOT_VALUE(excWord, UCASE_EXC_DELTA, pe, delta);
+            return (excWord&UCASE_EXC_DELTA_IS_NEGATIVE)==0 ? c+delta : c-delta;
+        }
         int32_t idx;
         if(HAS_SLOT(excWord, UCASE_EXC_TITLE)) {
             idx=UCASE_EXC_TITLE;
@@ -197,7 +213,7 @@
 
 
 U_CFUNC void U_EXPORT2
-ucase_addCaseClosure(const UCaseProps *csp, UChar32 c, const USetAdder *sa) {
+ucase_addCaseClosure(UChar32 c, const USetAdder *sa) {
     uint16_t props;
 
     /*
@@ -228,8 +244,8 @@
         break;
     }
 
-    props=UTRIE2_GET16(&csp->trie, c);
-    if(!PROPS_HAS_EXCEPTION(props)) {
+    props=UTRIE2_GET16(&ucase_props_singleton.trie, c);
+    if(!UCASE_HAS_EXCEPTION(props)) {
         if(UCASE_GET_TYPE(props)!=UCASE_NONE) {
             /* add the one simple case mapping, no matter what type it is */
             int32_t delta=UCASE_GET_DELTA(props);
@@ -242,7 +258,7 @@
          * c has exceptions, so there may be multiple simple and/or
          * full case mappings. Add them all.
          */
-        const uint16_t *pe0, *pe=GET_EXCEPTIONS(csp, props);
+        const uint16_t *pe0, *pe=GET_EXCEPTIONS(&ucase_props_singleton, props);
         const UChar *closure;
         uint16_t excWord=*pe++;
         int32_t idx, closureLength, fullLength, length;
@@ -257,6 +273,12 @@
                 sa->add(sa->set, c);
             }
         }
+        if(HAS_SLOT(excWord, UCASE_EXC_DELTA)) {
+            pe=pe0;
+            int32_t delta;
+            GET_SLOT_VALUE(excWord, UCASE_EXC_DELTA, pe, delta);
+            sa->add(sa->set, (excWord&UCASE_EXC_DELTA_IS_NEGATIVE)==0 ? c+delta : c-delta);
+        }
 
         /* get the closure string pointer & length */
         if(HAS_SLOT(excWord, UCASE_EXC_CLOSURE)) {
@@ -337,10 +359,10 @@
 }
 
 U_CFUNC UBool U_EXPORT2
-ucase_addStringCaseClosure(const UCaseProps *csp, const UChar *s, int32_t length, const USetAdder *sa) {
+ucase_addStringCaseClosure(const UChar *s, int32_t length, const USetAdder *sa) {
     int32_t i, start, limit, result, unfoldRows, unfoldRowWidth, unfoldStringWidth;
 
-    if(csp->unfold==NULL || s==NULL) {
+    if(ucase_props_singleton.unfold==NULL || s==NULL) {
         return FALSE; /* no reverse case folding data, or no string */
     }
     if(length<=1) {
@@ -354,7 +376,7 @@
         return FALSE;
     }
 
-    const uint16_t *unfold=csp->unfold;
+    const uint16_t *unfold=ucase_props_singleton.unfold;
     unfoldRows=unfold[UCASE_UNFOLD_ROWS];
     unfoldRowWidth=unfold[UCASE_UNFOLD_ROW_WIDTH];
     unfoldStringWidth=unfold[UCASE_UNFOLD_STRING_WIDTH];
@@ -380,7 +402,7 @@
             for(i=unfoldStringWidth; i<unfoldRowWidth && p[i]!=0;) {
                 U16_NEXT_UNSAFE(p, i, c);
                 sa->add(sa->set, c);
-                ucase_addCaseClosure(csp, c, sa);
+                ucase_addCaseClosure(c, sa);
             }
             return TRUE;
         } else if(result<0) {
@@ -425,43 +447,180 @@
     return c;
 }
 
+namespace LatinCase {
+
+const int8_t TO_LOWER_NORMAL[LIMIT] = {
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+    0, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, EXC, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+    32, 32, 32, 32, 32, 32, 32, 0, 32, 32, 32, 32, 32, 32, 32, EXC,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+    1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+    1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+    1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+    EXC, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1,
+
+    0, 1, 0, 1, 0, 1, 0, 1, 0, EXC, 1, 0, 1, 0, 1, 0,
+    1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+    1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+    1, 0, 1, 0, 1, 0, 1, 0, -121, 1, 0, 1, 0, 1, 0, EXC
+};
+
+const int8_t TO_LOWER_TR_LT[LIMIT] = {
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+    0, 32, 32, 32, 32, 32, 32, 32, 32, EXC, EXC, 32, 32, 32, 32, 32,
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, EXC, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, EXC, EXC, 32, 32,
+    32, 32, 32, 32, 32, 32, 32, 0, 32, 32, 32, 32, 32, 32, 32, EXC,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+    1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+    1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+    1, 0, 1, 0, 1, 0, 1, 0, EXC, 0, 1, 0, 1, 0, EXC, 0,
+    EXC, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1,
+
+    0, 1, 0, 1, 0, 1, 0, 1, 0, EXC, 1, 0, 1, 0, 1, 0,
+    1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+    1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+    1, 0, 1, 0, 1, 0, 1, 0, -121, 1, 0, 1, 0, 1, 0, EXC
+};
+
+const int8_t TO_UPPER_NORMAL[LIMIT] = {
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32,
+    -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, 0, 0, 0, 0, 0,
+
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, EXC, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, EXC,
+    -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32,
+    -32, -32, -32, -32, -32, -32, -32, 0, -32, -32, -32, -32, -32, -32, -32, 121,
+
+    0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1,
+    0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1,
+    0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1,
+    0, EXC, 0, -1, 0, -1, 0, -1, 0, 0, -1, 0, -1, 0, -1, 0,
+
+    -1, 0, -1, 0, -1, 0, -1, 0, -1, EXC, 0, -1, 0, -1, 0, -1,
+    0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1,
+    0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1,
+    0, -1, 0, -1, 0, -1, 0, -1, 0, 0, -1, 0, -1, 0, -1, EXC
+};
+
+const int8_t TO_UPPER_TR[LIMIT] = {
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, -32, -32, -32, -32, -32, -32, -32, -32, EXC, -32, -32, -32, -32, -32, -32,
+    -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, 0, 0, 0, 0, 0,
+
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, EXC, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, EXC,
+    -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32,
+    -32, -32, -32, -32, -32, -32, -32, 0, -32, -32, -32, -32, -32, -32, -32, 121,
+
+    0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1,
+    0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1,
+    0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1,
+    0, EXC, 0, -1, 0, -1, 0, -1, 0, 0, -1, 0, -1, 0, -1, 0,
+
+    -1, 0, -1, 0, -1, 0, -1, 0, -1, EXC, 0, -1, 0, -1, 0, -1,
+    0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1,
+    0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1,
+    0, -1, 0, -1, 0, -1, 0, -1, 0, 0, -1, 0, -1, 0, -1, EXC
+};
+
+}  // namespace LatinCase
+
 U_NAMESPACE_END
 
 /** @return UCASE_NONE, UCASE_LOWER, UCASE_UPPER, UCASE_TITLE */
 U_CAPI int32_t U_EXPORT2
-ucase_getType(const UCaseProps *csp, UChar32 c) {
-    uint16_t props=UTRIE2_GET16(&csp->trie, c);
+ucase_getType(UChar32 c) {
+    uint16_t props=UTRIE2_GET16(&ucase_props_singleton.trie, c);
     return UCASE_GET_TYPE(props);
 }
 
 /** @return same as ucase_getType() and set bit 2 if c is case-ignorable */
 U_CAPI int32_t U_EXPORT2
-ucase_getTypeOrIgnorable(const UCaseProps *csp, UChar32 c) {
-    uint16_t props=UTRIE2_GET16(&csp->trie, c);
+ucase_getTypeOrIgnorable(UChar32 c) {
+    uint16_t props=UTRIE2_GET16(&ucase_props_singleton.trie, c);
     return UCASE_GET_TYPE_AND_IGNORABLE(props);
 }
 
 /** @return UCASE_NO_DOT, UCASE_SOFT_DOTTED, UCASE_ABOVE, UCASE_OTHER_ACCENT */
 static inline int32_t
-getDotType(const UCaseProps *csp, UChar32 c) {
-    uint16_t props=UTRIE2_GET16(&csp->trie, c);
-    if(!PROPS_HAS_EXCEPTION(props)) {
+getDotType(UChar32 c) {
+    uint16_t props=UTRIE2_GET16(&ucase_props_singleton.trie, c);
+    if(!UCASE_HAS_EXCEPTION(props)) {
         return props&UCASE_DOT_MASK;
     } else {
-        const uint16_t *pe=GET_EXCEPTIONS(csp, props);
+        const uint16_t *pe=GET_EXCEPTIONS(&ucase_props_singleton, props);
         return (*pe>>UCASE_EXC_DOT_SHIFT)&UCASE_DOT_MASK;
     }
 }
 
 U_CAPI UBool U_EXPORT2
-ucase_isSoftDotted(const UCaseProps *csp, UChar32 c) {
-    return (UBool)(getDotType(csp, c)==UCASE_SOFT_DOTTED);
+ucase_isSoftDotted(UChar32 c) {
+    return (UBool)(getDotType(c)==UCASE_SOFT_DOTTED);
 }
 
 U_CAPI UBool U_EXPORT2
-ucase_isCaseSensitive(const UCaseProps *csp, UChar32 c) {
-    uint16_t props=UTRIE2_GET16(&csp->trie, c);
-    return (UBool)((props&UCASE_SENSITIVE)!=0);
+ucase_isCaseSensitive(UChar32 c) {
+    uint16_t props=UTRIE2_GET16(&ucase_props_singleton.trie, c);
+    if(!UCASE_HAS_EXCEPTION(props)) {
+        return (UBool)((props&UCASE_SENSITIVE)!=0);
+    } else {
+        const uint16_t *pe=GET_EXCEPTIONS(&ucase_props_singleton, props);
+        return (UBool)((*pe&UCASE_EXC_SENSITIVE)!=0);
+    }
 }
 
 /* string casing ------------------------------------------------------------ */
@@ -544,15 +703,14 @@
  *     zero or more case-ignorable characters.
  */
 
-#define is_a(c) ((c)=='a' || (c)=='A')
 #define is_d(c) ((c)=='d' || (c)=='D')
 #define is_e(c) ((c)=='e' || (c)=='E')
 #define is_i(c) ((c)=='i' || (c)=='I')
 #define is_l(c) ((c)=='l' || (c)=='L')
-#define is_n(c) ((c)=='n' || (c)=='N')
 #define is_r(c) ((c)=='r' || (c)=='R')
 #define is_t(c) ((c)=='t' || (c)=='T')
 #define is_u(c) ((c)=='u' || (c)=='U')
+#define is_y(c) ((c)=='y' || (c)=='Y')
 #define is_z(c) ((c)=='z' || (c)=='Z')
 
 /* separator? */
@@ -564,16 +722,7 @@
  * Accepts both 2- and 3-letter codes and accepts case variants.
  */
 U_CFUNC int32_t
-ucase_getCaseLocale(const char *locale, int32_t *locCache) {
-    int32_t result;
-    char c;
-
-    if(locCache!=NULL && (result=*locCache)!=UCASE_LOC_UNKNOWN) {
-        return result;
-    }
-
-    result=UCASE_LOC_ROOT;
-
+ucase_getCaseLocale(const char *locale) {
     /*
      * This function used to use uloc_getLanguage(), but the current code
      * removes the dependency of this low-level code on uloc implementation code
@@ -583,44 +732,12 @@
      * Because this code does not want to depend on uloc, the caller must
      * pass in a non-NULL locale, i.e., may need to call uloc_getDefault().
      */
-    c=*locale++;
-    if(is_t(c)) {
-        /* tr or tur? */
-        c=*locale++;
-        if(is_u(c)) {
-            c=*locale++;
-        }
-        if(is_r(c)) {
-            c=*locale;
-            if(is_sep(c)) {
-                result=UCASE_LOC_TURKISH;
-            }
-        }
-    } else if(is_a(c)) {
-        /* az or aze? */
-        c=*locale++;
-        if(is_z(c)) {
-            c=*locale++;
-            if(is_e(c)) {
-                c=*locale;
-            }
-            if(is_sep(c)) {
-                result=UCASE_LOC_TURKISH;
-            }
-        }
-    } else if(is_l(c)) {
-        /* lt or lit? */
-        c=*locale++;
-        if(is_i(c)) {
-            c=*locale++;
-        }
-        if(is_t(c)) {
-            c=*locale;
-            if(is_sep(c)) {
-                result=UCASE_LOC_LITHUANIAN;
-            }
-        }
-    } else if(is_e(c)) {
+    char c=*locale++;
+    // Fastpath for English "en" which is often used for default (=root locale) case mappings,
+    // and for Chinese "zh": Very common but no special case mapping behavior.
+    // Then check lowercase vs. uppercase to reduce the number of comparisons
+    // for other locales without special behavior.
+    if(c=='e') {
         /* el or ell? */
         c=*locale++;
         if(is_l(c)) {
@@ -629,27 +746,159 @@
                 c=*locale;
             }
             if(is_sep(c)) {
-                result=UCASE_LOC_GREEK;
+                return UCASE_LOC_GREEK;
             }
         }
-    } else if(is_n(c)) {
-        /* nl or nld? */
-        c=*locale++;
-        if(is_l(c)) {
+        // en, es, ... -> root
+    } else if(c=='z') {
+        return UCASE_LOC_ROOT;
+#if U_CHARSET_FAMILY==U_ASCII_FAMILY
+    } else if(c>='a') {  // ASCII a-z = 0x61..0x7a, after A-Z
+#elif U_CHARSET_FAMILY==U_EBCDIC_FAMILY
+    } else if(c<='z') {  // EBCDIC a-z = 0x81..0xa9 with two gaps, before A-Z
+#else
+#   error Unknown charset family!
+#endif
+        // lowercase c
+        if(c=='t') {
+            /* tr or tur? */
             c=*locale++;
-            if(is_d(c)) {
-                c=*locale;
+            if(is_u(c)) {
+                c=*locale++;
             }
-            if(is_sep(c)) {
-                result=UCASE_LOC_DUTCH;
+            if(is_r(c)) {
+                c=*locale;
+                if(is_sep(c)) {
+                    return UCASE_LOC_TURKISH;
+                }
+            }
+        } else if(c=='a') {
+            /* az or aze? */
+            c=*locale++;
+            if(is_z(c)) {
+                c=*locale++;
+                if(is_e(c)) {
+                    c=*locale;
+                }
+                if(is_sep(c)) {
+                    return UCASE_LOC_TURKISH;
+                }
+            }
+        } else if(c=='l') {
+            /* lt or lit? */
+            c=*locale++;
+            if(is_i(c)) {
+                c=*locale++;
+            }
+            if(is_t(c)) {
+                c=*locale;
+                if(is_sep(c)) {
+                    return UCASE_LOC_LITHUANIAN;
+                }
+            }
+        } else if(c=='n') {
+            /* nl or nld? */
+            c=*locale++;
+            if(is_l(c)) {
+                c=*locale++;
+                if(is_d(c)) {
+                    c=*locale;
+                }
+                if(is_sep(c)) {
+                    return UCASE_LOC_DUTCH;
+                }
+            }
+        } else if(c=='h') {
+            /* hy or hye? *not* hyw */
+            c=*locale++;
+            if(is_y(c)) {
+                c=*locale++;
+                if(is_e(c)) {
+                    c=*locale;
+                }
+                if(is_sep(c)) {
+                    return UCASE_LOC_ARMENIAN;
+                }
+            }
+        }
+    } else {
+        // uppercase c
+        // Same code as for lowercase c but also check for 'E'.
+        if(c=='T') {
+            /* tr or tur? */
+            c=*locale++;
+            if(is_u(c)) {
+                c=*locale++;
+            }
+            if(is_r(c)) {
+                c=*locale;
+                if(is_sep(c)) {
+                    return UCASE_LOC_TURKISH;
+                }
+            }
+        } else if(c=='A') {
+            /* az or aze? */
+            c=*locale++;
+            if(is_z(c)) {
+                c=*locale++;
+                if(is_e(c)) {
+                    c=*locale;
+                }
+                if(is_sep(c)) {
+                    return UCASE_LOC_TURKISH;
+                }
+            }
+        } else if(c=='L') {
+            /* lt or lit? */
+            c=*locale++;
+            if(is_i(c)) {
+                c=*locale++;
+            }
+            if(is_t(c)) {
+                c=*locale;
+                if(is_sep(c)) {
+                    return UCASE_LOC_LITHUANIAN;
+                }
+            }
+        } else if(c=='E') {
+            /* el or ell? */
+            c=*locale++;
+            if(is_l(c)) {
+                c=*locale++;
+                if(is_l(c)) {
+                    c=*locale;
+                }
+                if(is_sep(c)) {
+                    return UCASE_LOC_GREEK;
+                }
+            }
+        } else if(c=='N') {
+            /* nl or nld? */
+            c=*locale++;
+            if(is_l(c)) {
+                c=*locale++;
+                if(is_d(c)) {
+                    c=*locale;
+                }
+                if(is_sep(c)) {
+                    return UCASE_LOC_DUTCH;
+                }
+            }
+        } else if(c=='H') {
+            /* hy or hye? *not* hyw */
+            c=*locale++;
+            if(is_y(c)) {
+                c=*locale++;
+                if(is_e(c)) {
+                    c=*locale;
+                }
+                if(is_sep(c)) {
+                    return UCASE_LOC_ARMENIAN;
+                }
             }
         }
     }
-
-    if(locCache!=NULL) {
-        *locCache=result;
-    }
-    return result;
+    return UCASE_LOC_ROOT;
 }
 
 /*
@@ -661,7 +910,7 @@
  * it is also cased or not.
  */
 static UBool
-isFollowedByCasedLetter(const UCaseProps *csp, UCaseContextIterator *iter, void *context, int8_t dir) {
+isFollowedByCasedLetter(UCaseContextIterator *iter, void *context, int8_t dir) {
     UChar32 c;
 
     if(iter==NULL) {
@@ -669,7 +918,7 @@
     }
 
     for(/* dir!=0 sets direction */; (c=iter(context, dir))>=0; dir=0) {
-        int32_t type=ucase_getTypeOrIgnorable(csp, c);
+        int32_t type=ucase_getTypeOrIgnorable(c);
         if(type&4) {
             /* case-ignorable, continue with the loop */
         } else if(type!=UCASE_NONE) {
@@ -684,7 +933,7 @@
 
 /* Is preceded by Soft_Dotted character with no intervening cc=230 ? */
 static UBool
-isPrecededBySoftDotted(const UCaseProps *csp, UCaseContextIterator *iter, void *context) {
+isPrecededBySoftDotted(UCaseContextIterator *iter, void *context) {
     UChar32 c;
     int32_t dotType;
     int8_t dir;
@@ -694,7 +943,7 @@
     }
 
     for(dir=-1; (c=iter(context, dir))>=0; dir=0) {
-        dotType=getDotType(csp, c);
+        dotType=getDotType(c);
         if(dotType==UCASE_SOFT_DOTTED) {
             return TRUE; /* preceded by TYPE_i */
         } else if(dotType!=UCASE_OTHER_ACCENT) {
@@ -741,7 +990,7 @@
 
 /* Is preceded by base character 'I' with no intervening cc=230 ? */
 static UBool
-isPrecededBy_I(const UCaseProps *csp, UCaseContextIterator *iter, void *context) {
+isPrecededBy_I(UCaseContextIterator *iter, void *context) {
     UChar32 c;
     int32_t dotType;
     int8_t dir;
@@ -754,7 +1003,7 @@
         if(c==0x49) {
             return TRUE; /* preceded by I */
         }
-        dotType=getDotType(csp, c);
+        dotType=getDotType(c);
         if(dotType!=UCASE_OTHER_ACCENT) {
             return FALSE; /* preceded by different base character (not I), or intervening cc==230 */
         }
@@ -765,7 +1014,7 @@
 
 /* Is followed by one or more cc==230 ? */
 static UBool
-isFollowedByMoreAbove(const UCaseProps *csp, UCaseContextIterator *iter, void *context) {
+isFollowedByMoreAbove(UCaseContextIterator *iter, void *context) {
     UChar32 c;
     int32_t dotType;
     int8_t dir;
@@ -775,7 +1024,7 @@
     }
 
     for(dir=1; (c=iter(context, dir))>=0; dir=0) {
-        dotType=getDotType(csp, c);
+        dotType=getDotType(c);
         if(dotType==UCASE_ABOVE) {
             return TRUE; /* at least one cc==230 following */
         } else if(dotType!=UCASE_OTHER_ACCENT) {
@@ -788,7 +1037,7 @@
 
 /* Is followed by a dot above (without cc==230 in between) ? */
 static UBool
-isFollowedByDotAbove(const UCaseProps *csp, UCaseContextIterator *iter, void *context) {
+isFollowedByDotAbove(UCaseContextIterator *iter, void *context) {
     UChar32 c;
     int32_t dotType;
     int8_t dir;
@@ -801,7 +1050,7 @@
         if(c==0x307) {
             return TRUE;
         }
-        dotType=getDotType(csp, c);
+        dotType=getDotType(c);
         if(dotType!=UCASE_OTHER_ACCENT) {
             return FALSE; /* next base character or cc==230 in between */
         }
@@ -811,19 +1060,20 @@
 }
 
 U_CAPI int32_t U_EXPORT2
-ucase_toFullLower(const UCaseProps *csp, UChar32 c,
+ucase_toFullLower(UChar32 c,
                   UCaseContextIterator *iter, void *context,
                   const UChar **pString,
-                  const char *locale, int32_t *locCache)
-{
+                  int32_t loc) {
+    // The sign of the result has meaning, input must be non-negative so that it can be returned as is.
+    U_ASSERT(c >= 0);
     UChar32 result=c;
-    uint16_t props=UTRIE2_GET16(&csp->trie, c);
-    if(!PROPS_HAS_EXCEPTION(props)) {
-        if(UCASE_GET_TYPE(props)>=UCASE_UPPER) {
+    uint16_t props=UTRIE2_GET16(&ucase_props_singleton.trie, c);
+    if(!UCASE_HAS_EXCEPTION(props)) {
+        if(UCASE_IS_UPPER_OR_TITLE(props)) {
             result=c+UCASE_GET_DELTA(props);
         }
     } else {
-        const uint16_t *pe=GET_EXCEPTIONS(csp, props), *pe2;
+        const uint16_t *pe=GET_EXCEPTIONS(&ucase_props_singleton, props), *pe2;
         uint16_t excWord=*pe++;
         int32_t full;
 
@@ -831,7 +1081,6 @@
 
         if(excWord&UCASE_EXC_CONDITIONAL_SPECIAL) {
             /* use hardcoded conditions and mappings */
-            int32_t loc=ucase_getCaseLocale(locale, locCache);
 
             /*
              * Test for conditional mappings first
@@ -842,7 +1091,7 @@
             if( loc==UCASE_LOC_LITHUANIAN &&
                     /* base characters, find accents above */
                     (((c==0x49 || c==0x4a || c==0x12e) &&
-                        isFollowedByMoreAbove(csp, iter, context)) ||
+                        isFollowedByMoreAbove(iter, context)) ||
                     /* precomposed with accent above, no need to find one */
                     (c==0xcc || c==0xcd || c==0x128))
             ) {
@@ -894,7 +1143,7 @@
                     0130; 0069; 0130; 0130; az # LATIN CAPITAL LETTER I WITH DOT ABOVE
                  */
                 return 0x69;
-            } else if(loc==UCASE_LOC_TURKISH && c==0x307 && isPrecededBy_I(csp, iter, context)) {
+            } else if(loc==UCASE_LOC_TURKISH && c==0x307 && isPrecededBy_I(iter, context)) {
                 /*
                     # When lowercasing, remove dot_above in the sequence I + dot_above, which will turn into i.
                     # This matches the behavior of the canonically equivalent I-dot_above
@@ -902,8 +1151,9 @@
                     0307; ; 0307; 0307; tr After_I; # COMBINING DOT ABOVE
                     0307; ; 0307; 0307; az After_I; # COMBINING DOT ABOVE
                  */
+                *pString=nullptr;
                 return 0; /* remove the dot (continue without output) */
-            } else if(loc==UCASE_LOC_TURKISH && c==0x49 && !isFollowedByDotAbove(csp, iter, context)) {
+            } else if(loc==UCASE_LOC_TURKISH && c==0x49 && !isFollowedByDotAbove(iter, context)) {
                 /*
                     # When lowercasing, unless an I is before a dot_above, it turns into a dotless i.
 
@@ -920,8 +1170,8 @@
                 *pString=iDot;
                 return 2;
             } else if(  c==0x3a3 &&
-                        !isFollowedByCasedLetter(csp, iter, context, 1) &&
-                        isFollowedByCasedLetter(csp, iter, context, -1) /* -1=preceded */
+                        !isFollowedByCasedLetter(iter, context, 1) &&
+                        isFollowedByCasedLetter(iter, context, -1) /* -1=preceded */
             ) {
                 /* greek capital sigma maps depending on surrounding cased letters (see SpecialCasing.txt) */
                 /*
@@ -945,6 +1195,11 @@
             }
         }
 
+        if(HAS_SLOT(excWord, UCASE_EXC_DELTA) && UCASE_IS_UPPER_OR_TITLE(props)) {
+            int32_t delta;
+            GET_SLOT_VALUE(excWord, UCASE_EXC_DELTA, pe2, delta);
+            return (excWord&UCASE_EXC_DELTA_IS_NEGATIVE)==0 ? c+delta : c-delta;
+        }
         if(HAS_SLOT(excWord, UCASE_EXC_LOWER)) {
             GET_SLOT_VALUE(excWord, UCASE_EXC_LOWER, pe2, result);
         }
@@ -955,19 +1210,21 @@
 
 /* internal */
 static int32_t
-toUpperOrTitle(const UCaseProps *csp, UChar32 c,
+toUpperOrTitle(UChar32 c,
                UCaseContextIterator *iter, void *context,
                const UChar **pString,
-               const char *locale, int32_t *locCache,
+               int32_t loc,
                UBool upperNotTitle) {
+    // The sign of the result has meaning, input must be non-negative so that it can be returned as is.
+    U_ASSERT(c >= 0);
     UChar32 result=c;
-    uint16_t props=UTRIE2_GET16(&csp->trie, c);
-    if(!PROPS_HAS_EXCEPTION(props)) {
+    uint16_t props=UTRIE2_GET16(&ucase_props_singleton.trie, c);
+    if(!UCASE_HAS_EXCEPTION(props)) {
         if(UCASE_GET_TYPE(props)==UCASE_LOWER) {
             result=c+UCASE_GET_DELTA(props);
         }
     } else {
-        const uint16_t *pe=GET_EXCEPTIONS(csp, props), *pe2;
+        const uint16_t *pe=GET_EXCEPTIONS(&ucase_props_singleton, props), *pe2;
         uint16_t excWord=*pe++;
         int32_t full, idx;
 
@@ -975,8 +1232,6 @@
 
         if(excWord&UCASE_EXC_CONDITIONAL_SPECIAL) {
             /* use hardcoded conditions and mappings */
-            int32_t loc=ucase_getCaseLocale(locale, locCache);
-
             if(loc==UCASE_LOC_TURKISH && c==0x69) {
                 /*
                     # Turkish and Azeri
@@ -990,7 +1245,7 @@
                     0069; 0069; 0130; 0130; az; # LATIN SMALL LETTER I
                 */
                 return 0x130;
-            } else if(loc==UCASE_LOC_LITHUANIAN && c==0x307 && isPrecededBySoftDotted(csp, iter, context)) {
+            } else if(loc==UCASE_LOC_LITHUANIAN && c==0x307 && isPrecededBySoftDotted(iter, context)) {
                 /*
                     # Lithuanian
 
@@ -1000,7 +1255,19 @@
 
                     0307; 0307; ; ; lt After_Soft_Dotted; # COMBINING DOT ABOVE
                  */
+                *pString=nullptr;
                 return 0; /* remove the dot (continue without output) */
+            } else if(c==0x0587) {
+                // See ICU-13416:
+                // և ligature ech-yiwn
+                // uppercases to ԵՒ=ech+yiwn by default and in Western Armenian,
+                // but to ԵՎ=ech+vew in Eastern Armenian.
+                if(loc==UCASE_LOC_ARMENIAN) {
+                    *pString=upperNotTitle ? u"ԵՎ" : u"Եվ";
+                } else {
+                    *pString=upperNotTitle ? u"ԵՒ" : u"Եւ";
+                }
+                return 2;
             } else {
                 /* no known conditional special case mapping, use a normal mapping */
             }
@@ -1033,6 +1300,11 @@
             }
         }
 
+        if(HAS_SLOT(excWord, UCASE_EXC_DELTA) && UCASE_GET_TYPE(props)==UCASE_LOWER) {
+            int32_t delta;
+            GET_SLOT_VALUE(excWord, UCASE_EXC_DELTA, pe2, delta);
+            return (excWord&UCASE_EXC_DELTA_IS_NEGATIVE)==0 ? c+delta : c-delta;
+        }
         if(!upperNotTitle && HAS_SLOT(excWord, UCASE_EXC_TITLE)) {
             idx=UCASE_EXC_TITLE;
         } else if(HAS_SLOT(excWord, UCASE_EXC_UPPER)) {
@@ -1048,19 +1320,19 @@
 }
 
 U_CAPI int32_t U_EXPORT2
-ucase_toFullUpper(const UCaseProps *csp, UChar32 c,
+ucase_toFullUpper(UChar32 c,
                   UCaseContextIterator *iter, void *context,
                   const UChar **pString,
-                  const char *locale, int32_t *locCache) {
-    return toUpperOrTitle(csp, c, iter, context, pString, locale, locCache, TRUE);
+                  int32_t caseLocale) {
+    return toUpperOrTitle(c, iter, context, pString, caseLocale, TRUE);
 }
 
 U_CAPI int32_t U_EXPORT2
-ucase_toFullTitle(const UCaseProps *csp, UChar32 c,
+ucase_toFullTitle(UChar32 c,
                   UCaseContextIterator *iter, void *context,
                   const UChar **pString,
-                  const char *locale, int32_t *locCache) {
-    return toUpperOrTitle(csp, c, iter, context, pString, locale, locCache, FALSE);
+                  int32_t caseLocale) {
+    return toUpperOrTitle(c, iter, context, pString, caseLocale, FALSE);
 }
 
 /* case folding ------------------------------------------------------------- */
@@ -1106,14 +1378,14 @@
 
 /* return the simple case folding mapping for c */
 U_CAPI UChar32 U_EXPORT2
-ucase_fold(const UCaseProps *csp, UChar32 c, uint32_t options) {
-    uint16_t props=UTRIE2_GET16(&csp->trie, c);
-    if(!PROPS_HAS_EXCEPTION(props)) {
-        if(UCASE_GET_TYPE(props)>=UCASE_UPPER) {
+ucase_fold(UChar32 c, uint32_t options) {
+    uint16_t props=UTRIE2_GET16(&ucase_props_singleton.trie, c);
+    if(!UCASE_HAS_EXCEPTION(props)) {
+        if(UCASE_IS_UPPER_OR_TITLE(props)) {
             c+=UCASE_GET_DELTA(props);
         }
     } else {
-        const uint16_t *pe=GET_EXCEPTIONS(csp, props);
+        const uint16_t *pe=GET_EXCEPTIONS(&ucase_props_singleton, props);
         uint16_t excWord=*pe++;
         int32_t idx;
         if(excWord&UCASE_EXC_CONDITIONAL_FOLD) {
@@ -1138,6 +1410,14 @@
                 }
             }
         }
+        if((excWord&UCASE_EXC_NO_SIMPLE_CASE_FOLDING)!=0) {
+            return c;
+        }
+        if(HAS_SLOT(excWord, UCASE_EXC_DELTA) && UCASE_IS_UPPER_OR_TITLE(props)) {
+            int32_t delta;
+            GET_SLOT_VALUE(excWord, UCASE_EXC_DELTA, pe, delta);
+            return (excWord&UCASE_EXC_DELTA_IS_NEGATIVE)==0 ? c+delta : c-delta;
+        }
         if(HAS_SLOT(excWord, UCASE_EXC_FOLD)) {
             idx=UCASE_EXC_FOLD;
         } else if(HAS_SLOT(excWord, UCASE_EXC_LOWER)) {
@@ -1166,18 +1446,19 @@
  */
 
 U_CAPI int32_t U_EXPORT2
-ucase_toFullFolding(const UCaseProps *csp, UChar32 c,
+ucase_toFullFolding(UChar32 c,
                     const UChar **pString,
-                    uint32_t options)
-{
+                    uint32_t options) {
+    // The sign of the result has meaning, input must be non-negative so that it can be returned as is.
+    U_ASSERT(c >= 0);
     UChar32 result=c;
-    uint16_t props=UTRIE2_GET16(&csp->trie, c);
-    if(!PROPS_HAS_EXCEPTION(props)) {
-        if(UCASE_GET_TYPE(props)>=UCASE_UPPER) {
+    uint16_t props=UTRIE2_GET16(&ucase_props_singleton.trie, c);
+    if(!UCASE_HAS_EXCEPTION(props)) {
+        if(UCASE_IS_UPPER_OR_TITLE(props)) {
             result=c+UCASE_GET_DELTA(props);
         }
     } else {
-        const uint16_t *pe=GET_EXCEPTIONS(csp, props), *pe2;
+        const uint16_t *pe=GET_EXCEPTIONS(&ucase_props_singleton, props), *pe2;
         uint16_t excWord=*pe++;
         int32_t full, idx;
 
@@ -1224,6 +1505,14 @@
             }
         }
 
+        if((excWord&UCASE_EXC_NO_SIMPLE_CASE_FOLDING)!=0) {
+            return ~c;
+        }
+        if(HAS_SLOT(excWord, UCASE_EXC_DELTA) && UCASE_IS_UPPER_OR_TITLE(props)) {
+            int32_t delta;
+            GET_SLOT_VALUE(excWord, UCASE_EXC_DELTA, pe2, delta);
+            return (excWord&UCASE_EXC_DELTA_IS_NEGATIVE)==0 ? c+delta : c-delta;
+        }
         if(HAS_SLOT(excWord, UCASE_EXC_FOLD)) {
             idx=UCASE_EXC_FOLD;
         } else if(HAS_SLOT(excWord, UCASE_EXC_LOWER)) {
@@ -1239,66 +1528,59 @@
 
 /* case mapping properties API ---------------------------------------------- */
 
-#define GET_CASE_PROPS() &ucase_props_singleton
-
 /* public API (see uchar.h) */
 
 U_CAPI UBool U_EXPORT2
 u_isULowercase(UChar32 c) {
-    return (UBool)(UCASE_LOWER==ucase_getType(GET_CASE_PROPS(), c));
+    return (UBool)(UCASE_LOWER==ucase_getType(c));
 }
 
 U_CAPI UBool U_EXPORT2
 u_isUUppercase(UChar32 c) {
-    return (UBool)(UCASE_UPPER==ucase_getType(GET_CASE_PROPS(), c));
+    return (UBool)(UCASE_UPPER==ucase_getType(c));
 }
 
 /* Transforms the Unicode character to its lower case equivalent.*/
 U_CAPI UChar32 U_EXPORT2
 u_tolower(UChar32 c) {
-    return ucase_tolower(GET_CASE_PROPS(), c);
+    return ucase_tolower(c);
 }
     
 /* Transforms the Unicode character to its upper case equivalent.*/
 U_CAPI UChar32 U_EXPORT2
 u_toupper(UChar32 c) {
-    return ucase_toupper(GET_CASE_PROPS(), c);
+    return ucase_toupper(c);
 }
 
 /* Transforms the Unicode character to its title case equivalent.*/
 U_CAPI UChar32 U_EXPORT2
 u_totitle(UChar32 c) {
-    return ucase_totitle(GET_CASE_PROPS(), c);
+    return ucase_totitle(c);
 }
 
 /* return the simple case folding mapping for c */
 U_CAPI UChar32 U_EXPORT2
 u_foldCase(UChar32 c, uint32_t options) {
-    return ucase_fold(GET_CASE_PROPS(), c, options);
+    return ucase_fold(c, options);
 }
 
 U_CFUNC int32_t U_EXPORT2
 ucase_hasBinaryProperty(UChar32 c, UProperty which) {
     /* case mapping properties */
     const UChar *resultString;
-    int32_t locCache;
-    const UCaseProps *csp=GET_CASE_PROPS();
-    if(csp==NULL) {
-        return FALSE;
-    }
     switch(which) {
     case UCHAR_LOWERCASE:
-        return (UBool)(UCASE_LOWER==ucase_getType(csp, c));
+        return (UBool)(UCASE_LOWER==ucase_getType(c));
     case UCHAR_UPPERCASE:
-        return (UBool)(UCASE_UPPER==ucase_getType(csp, c));
+        return (UBool)(UCASE_UPPER==ucase_getType(c));
     case UCHAR_SOFT_DOTTED:
-        return ucase_isSoftDotted(csp, c);
+        return ucase_isSoftDotted(c);
     case UCHAR_CASE_SENSITIVE:
-        return ucase_isCaseSensitive(csp, c);
+        return ucase_isCaseSensitive(c);
     case UCHAR_CASED:
-        return (UBool)(UCASE_NONE!=ucase_getType(csp, c));
+        return (UBool)(UCASE_NONE!=ucase_getType(c));
     case UCHAR_CASE_IGNORABLE:
-        return (UBool)(ucase_getTypeOrIgnorable(csp, c)>>2);
+        return (UBool)(ucase_getTypeOrIgnorable(c)>>2);
     /*
      * Note: The following Changes_When_Xyz are defined as testing whether
      * the NFD form of the input changes when Xyz-case-mapped.
@@ -1312,21 +1594,17 @@
      * start sets for normalization and case mappings.
      */
     case UCHAR_CHANGES_WHEN_LOWERCASED:
-        locCache=UCASE_LOC_ROOT;
-        return (UBool)(ucase_toFullLower(csp, c, NULL, NULL, &resultString, "", &locCache)>=0);
+        return (UBool)(ucase_toFullLower(c, NULL, NULL, &resultString, UCASE_LOC_ROOT)>=0);
     case UCHAR_CHANGES_WHEN_UPPERCASED:
-        locCache=UCASE_LOC_ROOT;
-        return (UBool)(ucase_toFullUpper(csp, c, NULL, NULL, &resultString, "", &locCache)>=0);
+        return (UBool)(ucase_toFullUpper(c, NULL, NULL, &resultString, UCASE_LOC_ROOT)>=0);
     case UCHAR_CHANGES_WHEN_TITLECASED:
-        locCache=UCASE_LOC_ROOT;
-        return (UBool)(ucase_toFullTitle(csp, c, NULL, NULL, &resultString, "", &locCache)>=0);
+        return (UBool)(ucase_toFullTitle(c, NULL, NULL, &resultString, UCASE_LOC_ROOT)>=0);
     /* case UCHAR_CHANGES_WHEN_CASEFOLDED: -- in uprops.c */
     case UCHAR_CHANGES_WHEN_CASEMAPPED:
-        locCache=UCASE_LOC_ROOT;
         return (UBool)(
-            ucase_toFullLower(csp, c, NULL, NULL, &resultString, "", &locCache)>=0 ||
-            ucase_toFullUpper(csp, c, NULL, NULL, &resultString, "", &locCache)>=0 ||
-            ucase_toFullTitle(csp, c, NULL, NULL, &resultString, "", &locCache)>=0);
+            ucase_toFullLower(c, NULL, NULL, &resultString, UCASE_LOC_ROOT)>=0 ||
+            ucase_toFullUpper(c, NULL, NULL, &resultString, UCASE_LOC_ROOT)>=0 ||
+            ucase_toFullTitle(c, NULL, NULL, &resultString, UCASE_LOC_ROOT)>=0);
     default:
         return FALSE;
     }
diff --git a/src/third_party/icu/source/common/ucase.h b/src/third_party/icu/source/common/ucase.h
index 12771a3..a018f82 100644
--- a/src/third_party/icu/source/common/ucase.h
+++ b/src/third_party/icu/source/common/ucase.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  ucase.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -24,6 +26,7 @@
 #include "putilimp.h"
 #include "uset_imp.h"
 #include "udataswp.h"
+#include "utrie2.h"
 
 #ifdef __cplusplus
 U_NAMESPACE_BEGIN
@@ -35,18 +38,8 @@
 
 /* library API -------------------------------------------------------------- */
 
-U_CDECL_BEGIN
-
-struct UCaseProps;
-typedef struct UCaseProps UCaseProps;
-
-U_CDECL_END
-
-U_CAPI const UCaseProps * U_EXPORT2
-ucase_getSingleton(void);
-
 U_CFUNC void U_EXPORT2
-ucase_addPropertyStarts(const UCaseProps *csp, const USetAdder *sa, UErrorCode *pErrorCode);
+ucase_addPropertyStarts(const USetAdder *sa, UErrorCode *pErrorCode);
 
 /**
  * Requires non-NULL locale ID but otherwise does the equivalent of
@@ -54,7 +47,7 @@
  * Accepts both 2- and 3-letter codes and accepts case variants.
  */
 U_CFUNC int32_t
-ucase_getCaseLocale(const char *locale, int32_t *locCache);
+ucase_getCaseLocale(const char *locale);
 
 /* Casing locale types for ucase_getCaseLocale */
 enum {
@@ -63,13 +56,14 @@
     UCASE_LOC_TURKISH,
     UCASE_LOC_LITHUANIAN,
     UCASE_LOC_GREEK,
-    UCASE_LOC_DUTCH
+    UCASE_LOC_DUTCH,
+    UCASE_LOC_ARMENIAN
 };
 
 /**
  * Bit mask for getting just the options from a string compare options word
  * that are relevant for case-insensitive string comparison.
- * See uchar.h. Also include _STRNCMP_STYLE and U_COMPARE_CODE_POINT_ORDER.
+ * See stringoptions.h. Also include _STRNCMP_STYLE and U_COMPARE_CODE_POINT_ORDER.
  * @internal
  */
 #define _STRCASECMP_OPTIONS_MASK 0xffff
@@ -77,24 +71,30 @@
 /**
  * Bit mask for getting just the options from a string compare options word
  * that are relevant for case folding (of a single string or code point).
- * See uchar.h.
+ *
+ * Currently only bit 0 for U_FOLD_CASE_EXCLUDE_SPECIAL_I.
+ * It is conceivable that at some point we might use one more bit for using uppercase sharp s.
+ * It is conceivable that at some point we might want the option to use only simple case foldings
+ * when operating on strings.
+ *
+ * See stringoptions.h.
  * @internal
  */
-#define _FOLD_CASE_OPTIONS_MASK 0xff
+#define _FOLD_CASE_OPTIONS_MASK 7
 
 /* single-code point functions */
 
 U_CAPI UChar32 U_EXPORT2
-ucase_tolower(const UCaseProps *csp, UChar32 c);
+ucase_tolower(UChar32 c);
 
 U_CAPI UChar32 U_EXPORT2
-ucase_toupper(const UCaseProps *csp, UChar32 c);
+ucase_toupper(UChar32 c);
 
 U_CAPI UChar32 U_EXPORT2
-ucase_totitle(const UCaseProps *csp, UChar32 c);
+ucase_totitle(UChar32 c);
 
 U_CAPI UChar32 U_EXPORT2
-ucase_fold(const UCaseProps *csp, UChar32 c, uint32_t options);
+ucase_fold(UChar32 c, uint32_t options);
 
 /**
  * Adds all simple case mappings and the full case folding for c to sa,
@@ -106,7 +106,7 @@
  * - for k include the Kelvin sign
  */
 U_CFUNC void U_EXPORT2
-ucase_addCaseClosure(const UCaseProps *csp, UChar32 c, const USetAdder *sa);
+ucase_addCaseClosure(UChar32 c, const USetAdder *sa);
 
 /**
  * Maps the string to single code points and adds the associated case closure
@@ -118,10 +118,10 @@
  * the string itself is added as well as part of its code points' closure.
  * It must be length>=0.
  *
- * @return TRUE if the string was found
+ * @return true if the string was found
  */
 U_CFUNC UBool U_EXPORT2
-ucase_addStringCaseClosure(const UCaseProps *csp, const UChar *s, int32_t length, const USetAdder *sa);
+ucase_addStringCaseClosure(const UChar *s, int32_t length, const USetAdder *sa);
 
 #ifdef __cplusplus
 U_NAMESPACE_BEGIN
@@ -150,22 +150,49 @@
     int32_t rowCpIndex;
 };
 
+/**
+ * Fast case mapping data for ASCII/Latin.
+ * Linear arrays of delta bytes: 0=no mapping; EXC=exception.
+ * Deltas must not cross the ASCII boundary, or else they cannot be easily used
+ * in simple UTF-8 code.
+ */
+namespace LatinCase {
+
+/** Case mapping/folding data for code points up to U+017F. */
+constexpr UChar LIMIT = 0x180;
+/** U+017F case-folds and uppercases crossing the ASCII boundary. */
+constexpr UChar LONG_S = 0x17f;
+/** Exception: Complex mapping, or too-large delta. */
+constexpr int8_t EXC = -0x80;
+
+/** Deltas for lowercasing for most locales, and default case folding. */
+extern const int8_t TO_LOWER_NORMAL[LIMIT];
+/** Deltas for lowercasing for tr/az/lt, and Turkic case folding. */
+extern const int8_t TO_LOWER_TR_LT[LIMIT];
+
+/** Deltas for uppercasing for most locales. */
+extern const int8_t TO_UPPER_NORMAL[LIMIT];
+/** Deltas for uppercasing for tr/az. */
+extern const int8_t TO_UPPER_TR[LIMIT];
+
+}  // namespace LatinCase
+
 U_NAMESPACE_END
 #endif
 
 /** @return UCASE_NONE, UCASE_LOWER, UCASE_UPPER, UCASE_TITLE */
 U_CAPI int32_t U_EXPORT2
-ucase_getType(const UCaseProps *csp, UChar32 c);
+ucase_getType(UChar32 c);
 
-/** @return same as ucase_getType() and set bit 2 if c is case-ignorable */
+/** @return like ucase_getType() but also sets UCASE_IGNORABLE if c is case-ignorable */
 U_CAPI int32_t U_EXPORT2
-ucase_getTypeOrIgnorable(const UCaseProps *csp, UChar32 c);
+ucase_getTypeOrIgnorable(UChar32 c);
 
 U_CAPI UBool U_EXPORT2
-ucase_isSoftDotted(const UCaseProps *csp, UChar32 c);
+ucase_isSoftDotted(UChar32 c);
 
 U_CAPI UBool U_EXPORT2
-ucase_isCaseSensitive(const UCaseProps *csp, UChar32 c);
+ucase_isCaseSensitive(UChar32 c);
 
 /* string case mapping functions */
 
@@ -238,10 +265,7 @@
  * @param context Pointer to be passed into iter.
  * @param pString If the mapping result is a string, then the pointer is
  *                written to *pString.
- * @param locale Locale ID for locale-dependent mappings.
- * @param locCache Initialize to 0; may be used to cache the result of parsing
- *                 the locale ID for subsequent calls.
- *                 Can be NULL.
+ * @param caseLocale Case locale value from ucase_getCaseLocale().
  * @return Output code point or string length, see UCASE_MAX_STRING_LENGTH.
  *
  * @see UCaseContextIterator
@@ -249,25 +273,25 @@
  * @internal
  */
 U_CAPI int32_t U_EXPORT2
-ucase_toFullLower(const UCaseProps *csp, UChar32 c,
+ucase_toFullLower(UChar32 c,
                   UCaseContextIterator *iter, void *context,
                   const UChar **pString,
-                  const char *locale, int32_t *locCache);
+                  int32_t caseLocale);
 
 U_CAPI int32_t U_EXPORT2
-ucase_toFullUpper(const UCaseProps *csp, UChar32 c,
+ucase_toFullUpper(UChar32 c,
                   UCaseContextIterator *iter, void *context,
                   const UChar **pString,
-                  const char *locale, int32_t *locCache);
+                  int32_t caseLocale);
 
 U_CAPI int32_t U_EXPORT2
-ucase_toFullTitle(const UCaseProps *csp, UChar32 c,
+ucase_toFullTitle(UChar32 c,
                   UCaseContextIterator *iter, void *context,
                   const UChar **pString,
-                  const char *locale, int32_t *locCache);
+                  int32_t caseLocale);
 
 U_CAPI int32_t U_EXPORT2
-ucase_toFullFolding(const UCaseProps *csp, UChar32 c,
+ucase_toFullFolding(UChar32 c,
                     const UChar **pString,
                     uint32_t options);
 
@@ -281,10 +305,10 @@
  * @internal
  */
 typedef int32_t U_CALLCONV
-UCaseMapFull(const UCaseProps *csp, UChar32 c,
+UCaseMapFull(UChar32 c,
              UCaseContextIterator *iter, void *context,
              const UChar **pString,
-             const char *locale, int32_t *locCache);
+             int32_t caseLocale);
 
 U_CDECL_END
 
@@ -313,6 +337,9 @@
 
 /* definitions for 16-bit case properties word ------------------------------ */
 
+U_CFUNC const UTrie2 * U_EXPORT2
+ucase_getTrie();
+
 /* 2-bit constants for types of cased characters */
 #define UCASE_TYPE_MASK     3
 enum {
@@ -325,9 +352,13 @@
 #define UCASE_GET_TYPE(props) ((props)&UCASE_TYPE_MASK)
 #define UCASE_GET_TYPE_AND_IGNORABLE(props) ((props)&7)
 
+#define UCASE_IS_UPPER_OR_TITLE(props) ((props)&2)
+
 #define UCASE_IGNORABLE         4
-#define UCASE_SENSITIVE         8
-#define UCASE_EXCEPTION         0x10
+#define UCASE_EXCEPTION         8
+#define UCASE_SENSITIVE         0x10
+
+#define UCASE_HAS_EXCEPTION(props) ((props)&UCASE_EXCEPTION)
 
 #define UCASE_DOT_MASK      0x60
 enum {
@@ -349,9 +380,9 @@
 #   define UCASE_GET_DELTA(props) (int16_t)(((props)&0x8000) ? (((props)>>UCASE_DELTA_SHIFT)|0xfe00) : ((uint16_t)(props)>>UCASE_DELTA_SHIFT))
 #endif
 
-/* exception: bits 15..5 are an unsigned 11-bit index into the exceptions array */
-#define UCASE_EXC_SHIFT     5
-#define UCASE_EXC_MASK      0xffe0
+/* exception: bits 15..4 are an unsigned 12-bit index into the exceptions array */
+#define UCASE_EXC_SHIFT     4
+#define UCASE_EXC_MASK      0xfff0
 #define UCASE_MAX_EXCEPTIONS ((UCASE_EXC_MASK>>UCASE_EXC_SHIFT)+1)
 
 /* definitions for 16-bit main exceptions word ------------------------------ */
@@ -362,7 +393,7 @@
     UCASE_EXC_FOLD,
     UCASE_EXC_UPPER,
     UCASE_EXC_TITLE,
-    UCASE_EXC_4,            /* reserved */
+    UCASE_EXC_DELTA,
     UCASE_EXC_5,            /* reserved */
     UCASE_EXC_CLOSURE,
     UCASE_EXC_FULL_MAPPINGS,
@@ -372,7 +403,11 @@
 /* each slot is 2 uint16_t instead of 1 */
 #define UCASE_EXC_DOUBLE_SLOTS      0x100
 
-/* reserved: exception bits 11..9 */
+enum {
+    UCASE_EXC_NO_SIMPLE_CASE_FOLDING=0x200,
+    UCASE_EXC_DELTA_IS_NEGATIVE=0x400,
+    UCASE_EXC_SENSITIVE=0x800
+};
 
 /* UCASE_EXC_DOT_MASK=UCASE_DOT_MASK<<UCASE_EXC_DOT_SHIFT */
 #define UCASE_EXC_DOT_SHIFT     7
diff --git a/src/third_party/icu/source/common/ucase_props_data.h b/src/third_party/icu/source/common/ucase_props_data.h
index edfbda0..aead6d5 100644
--- a/src/third_party/icu/source/common/ucase_props_data.h
+++ b/src/third_party/icu/source/common/ucase_props_data.h
@@ -1,155 +1,155 @@
-/*
- * Copyright (C) 1999-2016, International Business Machines
- * Corporation and others.  All Rights Reserved.
- *
- * file name: ucase_props_data.h
- *
- * machine-generated by: icu/tools/unicode/c/genprops/casepropsbuilder.cpp
- */
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+//
+// Copyright (C) 1999-2016, International Business Machines
+// Corporation and others.  All Rights Reserved.
+//
+// file name: ucase_props_data.h
+//
+// machine-generated by: icu/tools/unicode/c/genprops/casepropsbuilder.cpp
 
-#ifndef INCLUDED_FROM_UCASE_CPP
-#   error This file must be #included from ucase.cpp only.
-#endif
 
-static const UVersionInfo ucase_props_dataVersion={8,0,0,0};
+#ifdef INCLUDED_FROM_UCASE_CPP
 
-static const int32_t ucase_props_indexes[UCASE_IX_TOP]={0x10,0x67ea,0x5658,0x737,0x172,0,0,0,0,0,0,0,0,0,0,3};
+static const UVersionInfo ucase_props_dataVersion={0xd,0,0,0};
 
-static const uint16_t ucase_props_trieIndex[11044]={
-0x316,0x31e,0x326,0x32e,0x33c,0x344,0x34c,0x354,0x35c,0x364,0x36b,0x373,0x37b,0x383,0x38b,0x393,
-0x399,0x3a1,0x3a9,0x3b1,0x3b9,0x3c1,0x3c9,0x3d1,0x3d9,0x3e1,0x3e9,0x3f1,0x3f9,0x401,0x409,0x411,
-0x419,0x421,0x425,0x42d,0x435,0x43d,0x445,0x44d,0x449,0x451,0x456,0x45e,0x465,0x46d,0x475,0x47d,
-0x485,0x48d,0x495,0x49d,0x335,0x33d,0x4a2,0x4aa,0x4af,0x4b7,0x4bf,0x4c7,0x4c6,0x4ce,0x4d3,0x4db,
-0x4e2,0x4e9,0x4ed,0x335,0x335,0x316,0x335,0x4f5,0x4fd,0x4ff,0x507,0x50f,0x513,0x514,0x51c,0x524,
-0x52c,0x514,0x534,0x539,0x52c,0x514,0x541,0x524,0x513,0x545,0x54d,0x524,0x552,0x335,0x55a,0x335,
-0x48c,0x4c8,0x562,0x524,0x513,0x545,0x569,0x524,0x513,0x335,0x51c,0x524,0x335,0x335,0x56f,0x335,
-0x335,0x575,0x57c,0x335,0x335,0x580,0x588,0x335,0x58c,0x593,0x335,0x59a,0x5a2,0x5a9,0x5b1,0x335,
-0x335,0x5b6,0x5be,0x5c6,0x5ce,0x5d6,0x5de,0x47b,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x5e2,0x335,0x335,0x5f2,0x5fa,0x5ea,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x602,0x602,0x520,0x520,0x335,0x608,0x610,0x335,
-0x618,0x335,0x620,0x335,0x335,0x626,0x335,0x335,0x335,0x62e,0x335,0x335,0x335,0x335,0x335,0x335,
-0x635,0x335,0x63c,0x644,0x335,0x64c,0x335,0x335,0x654,0x657,0x65f,0x665,0x66d,0x675,0x335,0x67c,
-0x335,0x681,0x335,0x687,0x335,0x335,0x68f,0x697,0x69f,0x6a4,0x6a7,0x6af,0x6bf,0x6b7,0x6cf,0x6c7,
-0x35c,0x6d7,0x35c,0x6df,0x6e2,0x35c,0x6ea,0x35c,0x6f2,0x6fa,0x702,0x70a,0x712,0x71a,0x722,0x72a,
-0x732,0x739,0x335,0x741,0x749,0x335,0x751,0x759,0x761,0x769,0x771,0x779,0x781,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x784,0x78a,0x790,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x798,0x79d,0x7a1,0x7a9,0x35c,0x35c,0x35c,0x7b1,0x7b9,0x7c1,0x335,0x7c6,0x335,0x335,0x335,0x7ce,
-0x335,0x61d,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x512,0x7d6,0x335,0x335,0x7dd,0x335,0x335,0x7e5,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x7ed,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x687,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x7f3,0x335,0x35c,0x7fb,0x803,0x335,0x335,0x80b,0x813,0x81b,0x35c,0x820,0x828,0x82e,0x335,0x834,
-0x83c,0x52b,0x335,0x335,0x335,0x335,0x843,0x84b,0x335,0x852,0x859,0x335,0x4fd,0x85e,0x866,0x52b,
-0x335,0x86c,0x874,0x878,0x335,0x880,0x888,0x890,0x335,0x896,0x89a,0x8a2,0x8b2,0x8aa,0x335,0x8ba,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x8c2,0x335,0x335,0x335,0x335,0x8ca,0x66d,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x8cf,0x8d7,0x8db,0x335,0x335,0x335,0x335,0x318,0x31e,0x8e3,0x8eb,0x8f2,0x4c8,0x335,0x335,0x8fa,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0xcd8,0xcd8,0xcf0,0xd30,0xd70,0xdac,0xdec,0xe2c,0xe64,0xea4,0xee4,0xf24,0xf64,0xfa4,0xfe4,0x1024,
-0x1064,0x1094,0x10d4,0x1114,0x1124,0x1158,0x1194,0x11d4,0x1214,0x1254,0xcd4,0x1288,0x12bc,0x12fc,0x1318,0x134c,
-0x9e1,0xa11,0xa51,0xa8c,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0xab5,0x188,0x188,
-0x188,0x188,0x188,0x188,0x188,0x188,0x188,0xaf2,0x188,0x188,0xb27,0xb66,0x188,0xba0,0xbd7,0x188,
+static const int32_t ucase_props_indexes[UCASE_IX_TOP]={0x10,0x70c2,0x6098,0x683,0x172,0,0,0,0,0,0,0,0,0,0,3};
+
+static const uint16_t ucase_props_trieIndex[12356]={
+0x336,0x33e,0x346,0x34e,0x35c,0x364,0x36c,0x374,0x37c,0x384,0x38b,0x393,0x39b,0x3a3,0x3ab,0x3b3,
+0x3b9,0x3c1,0x3c9,0x3d1,0x3d9,0x3e1,0x3e9,0x3f1,0x3f9,0x401,0x409,0x411,0x419,0x421,0x429,0x431,
+0x439,0x441,0x449,0x451,0x459,0x461,0x469,0x471,0x46d,0x475,0x47a,0x482,0x489,0x491,0x499,0x4a1,
+0x4a9,0x4b1,0x4b9,0x4c1,0x355,0x35d,0x4c6,0x4ce,0x4d3,0x4db,0x4e3,0x4eb,0x4ea,0x4f2,0x4f7,0x4ff,
+0x507,0x50e,0x512,0x355,0x355,0x355,0x519,0x521,0x529,0x52b,0x533,0x53b,0x53f,0x540,0x548,0x550,
+0x558,0x540,0x560,0x565,0x558,0x540,0x56d,0x575,0x53f,0x57d,0x585,0x58d,0x595,0x355,0x59d,0x355,
+0x5a5,0x4ec,0x5ad,0x58d,0x53f,0x57d,0x5b4,0x58d,0x5bc,0x5be,0x548,0x58d,0x53f,0x355,0x5c6,0x355,
+0x355,0x5cc,0x5d3,0x355,0x355,0x5d7,0x5df,0x355,0x5e3,0x5ea,0x355,0x5f1,0x5f9,0x600,0x608,0x355,
+0x355,0x60d,0x615,0x61d,0x625,0x62d,0x634,0x63c,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x644,0x355,0x355,0x654,0x654,0x64c,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x65c,0x65c,0x54c,0x54c,0x355,0x662,0x66a,0x355,
+0x672,0x355,0x67a,0x355,0x681,0x687,0x355,0x355,0x355,0x68f,0x355,0x355,0x355,0x355,0x355,0x355,
+0x696,0x355,0x69d,0x6a5,0x355,0x6ad,0x6b5,0x355,0x57c,0x6b8,0x6c0,0x6c6,0x5bc,0x6ce,0x355,0x6d5,
+0x355,0x6da,0x355,0x6e0,0x6e8,0x6ec,0x6f4,0x6fc,0x704,0x709,0x70c,0x714,0x724,0x71c,0x734,0x72c,
+0x37c,0x73c,0x37c,0x744,0x747,0x37c,0x74f,0x37c,0x757,0x75f,0x767,0x76f,0x777,0x77f,0x787,0x78f,
+0x797,0x79e,0x355,0x7a6,0x7ae,0x355,0x7b6,0x7be,0x7c6,0x7ce,0x7d6,0x7de,0x7e6,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x7e9,0x7ef,0x7f5,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x7fd,0x802,0x806,0x80e,0x37c,0x37c,0x37c,0x816,0x81e,0x825,0x355,0x82a,0x355,0x355,0x355,0x832,
+0x355,0x677,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x53e,0x83a,0x355,0x355,0x841,0x355,0x355,0x849,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x851,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x6e0,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x857,0x355,0x85f,0x864,0x86c,0x355,0x355,0x874,0x87c,0x884,0x37c,0x889,0x891,0x897,0x89f,0x8a2,
+0x8aa,0x8b1,0x355,0x355,0x355,0x355,0x8b8,0x8c0,0x355,0x8c8,0x8cf,0x355,0x529,0x8d4,0x8dc,0x681,
+0x355,0x8e2,0x8ea,0x8ee,0x355,0x8f6,0x8fe,0x906,0x355,0x90c,0x910,0x918,0x928,0x920,0x355,0x930,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x938,0x355,0x355,0x355,0x355,0x940,0x5bc,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x945,0x94d,0x951,0x355,0x355,0x355,0x355,0x338,0x33e,0x959,0x961,0x968,0x4ec,0x355,0x355,0x970,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0xd58,0xd58,0xd70,0xdb0,0xdf0,0xe2c,0xe6c,0xeac,0xee4,0xf24,0xf64,0xfa4,0xfe4,0x1024,0x1064,0x10a4,
+0x10e4,0x1124,0x1164,0x11a4,0x11b4,0x11e8,0x1224,0x1264,0x12a4,0x12e4,0xd54,0x1318,0x134c,0x138c,0x13a8,0x13dc,
+0x9e1,0xa11,0xa51,0xa90,0x188,0x188,0xac8,0x188,0x188,0x188,0x188,0x188,0x188,0xaf1,0x188,0x188,
+0x188,0x188,0x188,0x188,0x188,0x188,0x188,0xb31,0x188,0x188,0xb66,0xba5,0xbe5,0xc1f,0xc56,0x188,
 0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,
 0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,
 0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,
@@ -174,130 +174,139 @@
 0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,
 0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,
 0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,
-0xc17,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x621,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x902,0x335,0x335,0x335,0x905,0x335,0x335,0x335,
-0x335,0x90d,0x913,0x917,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x91f,0x923,0x335,0x335,0x335,0x335,0x335,0x92b,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x933,0x937,0x93f,0x943,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x513,0x948,0x94f,0x951,0x66d,0x959,0x335,0x335,0x961,0x968,0x335,0x954,0x66d,0x96e,0x976,
-0x335,0x335,0x97b,0x335,0x335,0x335,0x335,0x318,0x983,0x66d,0x514,0x98b,0x992,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x998,0x9a0,0x335,0x335,0x335,0x335,0x335,0x335,0x9a4,0x9ac,
-0x335,0x335,0x9b4,0x48c,0x335,0x335,0x9bc,0x335,0x335,0x9c2,0x9ca,0x335,0x335,0x335,0x335,0x335,
-0x335,0x41d,0x9d2,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x9da,0x335,0x9e0,0x654,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x9e6,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x9ee,0x654,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x9f6,0x9fe,0xa04,0x335,0x335,0x335,0x335,0xa0c,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0xa14,0xa1c,0xa21,0xa27,0xa2f,0xa37,0xa3f,0xa18,0xa47,
-0xa4f,0xa57,0xa5e,0xa19,0xa14,0xa1c,0xa17,0xa27,0xa1a,0xa15,0xa66,0xa18,0xa6e,0xa76,0xa7e,0xa85,
-0xa71,0xa79,0xa81,0xa88,0xa74,0xa90,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x813,0xa98,0x813,0xa9f,0xaa6,0xaae,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0xab2,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0xa10,0xaba,0xaba,0xac0,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x963,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x513,0x813,0x813,0x813,0x335,0x335,0x335,0x335,0x813,
-0x813,0x813,0x813,0x813,0x813,0x813,0x9ea,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x335,
-0x335,0x335,0x335,0x335,0x335,0x335,0x335,0x315,0,0,0,0,0,0,0,0,
+0xc96,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x977,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x6b5,0x355,0x355,0x355,0x97f,0x355,0x355,0x355,
+0x355,0x987,0x98d,0x991,0x355,0x355,0x995,0x999,0x99f,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x9a7,0x9ab,0x355,0x355,0x355,0x355,0x355,0x9b3,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x9bb,0x9bf,0x9c7,0x9cb,0x355,0x9d2,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x9d8,0x355,0x355,0x355,0x355,0x9df,0x355,0x355,0x355,0x355,
+0x355,0x53f,0x9e4,0x9eb,0x5bd,0x5bc,0x9ef,0x53c,0x355,0x9f7,0x9fe,0x355,0xa04,0x5bc,0xa09,0xa11,
+0x355,0x355,0xa16,0x355,0x355,0x355,0x355,0x338,0xa1e,0x5bc,0x5be,0xa26,0xa2d,0x355,0x355,0x355,
+0x355,0x355,0x9e4,0xa35,0x355,0x355,0xa3d,0xa45,0x355,0x355,0x355,0x355,0x355,0x355,0xa49,0xa51,
+0x355,0x355,0xa59,0x4b0,0x355,0x355,0xa61,0x355,0x355,0xa67,0xa6f,0x355,0x355,0x355,0x355,0x355,
+0x355,0xa74,0x355,0x355,0x355,0xa7c,0xa84,0x355,0x355,0xa8c,0xa94,0x355,0x355,0x355,0xa97,0x6b5,
+0xa9f,0xaa3,0xaab,0x355,0xab2,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0xab9,0x355,0x355,0x940,0xac1,0x355,0x355,0x355,0xac7,0xacf,0x355,0xad3,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0xad9,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0xadf,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0xae6,0x355,0xaec,0x57c,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0xa7c,0xa84,0x355,0x355,0x355,0x355,0x355,0x355,0x677,0x355,0xaf2,0x355,0x355,
+0xafa,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0xaff,0x57c,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0xb07,0xb0f,0xb15,0x355,0x355,0x355,0x355,0xb1d,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0xb25,0xb2d,0xb32,0xb38,0xb40,0xb48,0xb50,0xb29,0xb58,0xb60,
+0xb68,0xb6f,0xb2a,0xb25,0xb2d,0xb28,0xb38,0xb2b,0xb26,0xb77,0xb29,0xb7f,0xb87,0xb8f,0xb96,0xb82,
+0xb8a,0xb92,0xb99,0xb85,0xba1,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x87c,0xba9,0x87c,0xbb0,0xbb7,0xbbf,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0xbc7,0xbcf,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0xbd3,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x9d0,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0xbdb,0x355,0xbe3,0xbeb,0xbf2,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0xb21,
+0xbfa,0xbfa,0xc00,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x9f9,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x53f,0x87c,0x87c,0x87c,0x355,0x355,0x355,0x355,0x87c,0x87c,
+0x87c,0x87c,0x87c,0x87c,0x87c,0xc08,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,0x355,
+0x355,0x355,0x355,0x355,0x355,0x355,0x335,0x335,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,
 0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,
-0,0,4,0,0,0,0,0,0,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,
-0x100a,0x1a,0xba,0xfa,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x17a,0x100a,0x100a,0x100a,0x100a,
-0x100a,0x100a,0x100a,0,0,0,4,0,4,0xf009,0xf009,0xf009,0xf009,0xf009,0xf009,0xf009,
-0xf009,0x1f9,0xf029,0x299,0xf009,0xf009,0xf009,0xf009,0xf009,0xf009,0xf009,0x319,0xf009,0xf009,0xf009,0xf009,
-0xf009,0xf009,0xf009,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,4,0,0,0,0,0,0,0x1012,0x1012,0x1012,0x1012,0x1012,0x1012,0x1012,
+0x1012,0xa,0x5a,0x7a,0x1012,0x1012,0x1012,0x1012,0x1012,0x1012,0x1012,0xba,0x1012,0x1012,0x1012,0x1012,
+0x1012,0x1012,0x1012,0,0,0,4,0,4,0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,
+0xf011,0xf9,0xf031,0x149,0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,0x189,0xf011,0xf011,0xf011,0xf011,
+0xf011,0xf011,0xf011,0,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,4,0,1,0,0,4,0,4,
-0,0,0,0,4,0x399,0,4,4,0,1,0,0,0,0,0,
-0x100a,0x100a,0x100a,0x100a,0x100a,0x3fa,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x47a,0x4ba,0x100a,0x100a,
-0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x4f9,
-0xf009,0xf009,0xf009,0xf009,0xf009,0x639,0xf009,0xf009,0xf009,0xf009,0xf009,0xf009,0xf009,0xf009,0xf009,0xf009,
-0xf009,0xf009,0xf009,0xf009,0xf009,0xf009,0xf009,0,0xf009,0xf009,0xf009,0xf009,0xf009,0xf009,0xf009,0x3c89,
-0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,
-0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,
-0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x6ba,0xff89,0x8a,0xff89,0x8a,0xff89,0x6fa,0xffa9,
-0x73a,0x7f9,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,1,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,
-0xff89,0x8a,0xff89,0x8a,0xff89,0x899,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,
-0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,
-0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,
-0x8a,0xff89,0x8a,0xff89,0xc38a,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x999,0x6189,0x690a,0x8a,0xff89,
-0x8a,0xff89,0x670a,0x8a,0xff89,0x668a,0x668a,0x8a,0xff89,1,0x278a,0x650a,0x658a,0x8a,0xff89,0x668a,
-0x678a,0x3089,0x698a,0x688a,0x8a,0xff89,0x5189,1,0x698a,0x6a8a,0x4109,0x6b0a,0x8a,0xff89,0x8a,0xff89,
-0x8a,0xff89,0x6d0a,0x8a,0xff89,0x6d0a,1,1,0x8a,0xff89,0x6d0a,0x8a,0xff89,0x6c8a,0x6c8a,0x8a,
-0xff89,0x8a,0xff89,0x6d8a,0x8a,0xff89,1,0,0x8a,0xff89,1,0x1c09,0,0,0,0,
-0x9fa,0xa5b,0xad9,0xb3a,0xb9b,0xc19,0xc7a,0xcdb,0xd59,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,
-0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0xd889,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,
-0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0xdb9,0xeba,0xf1b,0xf99,
-0x8a,0xff89,0xcf8a,0xe40a,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,
-0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,
-0x8a,0xff89,0x8a,0xff89,0xbf0a,1,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,
-0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,1,1,1,1,1,1,0xffa,0x8a,
-0xff89,0xae8a,0x103a,0x1079,0x10b9,0x8a,0xff89,0x9e8a,0x228a,0x238a,0x8a,0xff89,0x8a,0xffa9,0x8a,0xff89,
-0x8a,0xff89,0x8a,0xff89,0x10f9,0x1139,0x1179,0x9709,0x9909,1,0x9989,0x9989,1,0x9b09,1,0x9a89,
-0x11b9,1,1,1,0x9989,0x11f9,1,0x9889,1,0x1239,0x1279,1,0x97a9,0x9689,1,0x12b9,
-0x12f9,1,1,0x9689,1,0x1339,0x9589,1,1,0x9509,1,1,1,1,1,1,
-1,0x1379,1,1,0x9309,1,1,0x9309,1,1,1,0x13b9,0x9309,0xdd89,0x9389,0x9389,
-0xdc89,1,1,1,1,1,0x9289,1,0,1,1,1,1,1,1,1,
-1,0x13f9,0x1439,1,1,1,1,1,1,1,1,1,1,1,1,1,
+0,0,0,0,4,0x1c9,0,4,4,0,1,0,0,0,0,0,
+0x1012,0x1012,0x1012,0x1012,0x1012,0x1fa,0x1012,0x1012,0x1012,0x1012,0x1012,0x1012,0x5a,0x5a,0x1012,0x1012,
+0x1012,0x1012,0x1012,0x1012,0x1012,0x1012,0x1012,0,0x1012,0x1012,0x1012,0x1012,0x1012,0x1012,0x1012,0x239,
+0xf011,0xf011,0xf011,0xf011,0xf011,0x2d9,0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,
+0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,0,0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,0x3c91,
+0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,
+0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,
+0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x31a,0xff91,0x92,0xff91,0x92,0xff91,0x31a,0xffb1,
+0x33a,0x389,0x92,0xff91,0x92,0xff91,0x92,0xff91,1,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,
+0xff91,0x92,0xff91,0x92,0xff91,0x3d9,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,
+0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,
+0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,
+0x92,0xff91,0x92,0xff91,0xc392,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x459,0x6191,0x6912,0x92,0xff91,
+0x92,0xff91,0x6712,0x92,0xff91,0x6692,0x6692,0x92,0xff91,1,0x2792,0x6512,0x6592,0x92,0xff91,0x6692,
+0x6792,0x3091,0x6992,0x6892,0x92,0xff91,0x5191,1,0x6992,0x6a92,0x4111,0x6b12,0x92,0xff91,0x92,0xff91,
+0x92,0xff91,0x6d12,0x92,0xff91,0x6d12,1,1,0x92,0xff91,0x6d12,0x92,0xff91,0x6c92,0x6c92,0x92,
+0xff91,0x92,0xff91,0x6d92,0x92,0xff91,1,0,0x92,0xff91,1,0x1c11,0,0,0,0,
+0x48a,0x4bb,0x4f9,0x52a,0x55b,0x599,0x5ca,0x5fb,0x639,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,
+0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0xd891,0x92,0xff91,0x92,0xff91,0x92,0xff91,
+0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x669,0x6ea,0x71b,0x759,
+0x92,0xff91,0xcf92,0xe412,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,
+0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,
+0x92,0xff91,0x92,0xff91,0xbf12,1,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,
+0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,1,1,1,1,1,1,0x78a,0x92,
+0xff91,0xae92,0x7aa,0x7c9,0x7c9,0x92,0xff91,0x9e92,0x2292,0x2392,0x92,0xff91,0x92,0xffb1,0x92,0xff91,
+0x92,0xff91,0x92,0xff91,0x7e9,0x809,0x829,0x9711,0x9911,1,0x9991,0x9991,1,0x9b11,1,0x9a91,
+0x849,1,1,1,0x9991,0x869,1,0x9891,1,0x889,0x8a9,1,0x97b1,0x9691,0x8a9,0x8c9,
+0x8e9,1,1,0x9691,1,0x909,0x9591,1,1,0x9511,1,1,1,1,1,1,
+1,0x929,1,1,0x9311,1,0x949,0x9311,1,1,1,0x969,0x9311,0xdd91,0x9391,0x9391,
+0xdc91,1,1,1,1,1,0x9291,1,0,1,1,1,1,1,1,1,
+1,0x989,0x9a9,1,1,1,1,1,1,1,1,1,1,1,1,1,
 1,1,1,1,5,5,0x25,5,5,5,5,5,5,4,4,4,
-0xc,4,0xc,4,5,5,4,4,4,4,4,4,4,4,4,4,
+0x14,4,0x14,4,5,5,4,4,4,4,4,4,4,4,4,4,
 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
 4,4,4,4,5,5,5,5,5,4,4,4,4,4,4,4,
 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
-4,4,4,4,0x4c,0x4c,0x44,0x44,0x44,0x44,0x44,0x147c,0x4c,0x44,0x4c,0x44,
-0x4c,0x44,0x44,0x44,0x44,0x44,0x44,0x4c,0x44,0x64,0x64,0x64,0x64,0x64,0x64,0x64,
+4,4,4,4,0x54,0x54,0x44,0x44,0x44,0x44,0x44,0x9cc,0x54,0x44,0x54,0x44,
+0x54,0x44,0x44,0x44,0x44,0x44,0x44,0x54,0x44,0x64,0x64,0x64,0x64,0x64,0x64,0x64,
 0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,
-0x64,0x64,0x64,0x64,0x64,0x6c,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,
-0x64,0x44,0x44,0x44,0x44,0x44,0x4c,0x44,0x44,0x149d,0x44,0x64,0x64,0x64,0x44,0x44,
+0x64,0x64,0x64,0x64,0x64,0x74,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,
+0x64,0x44,0x44,0x44,0x44,0x44,0x54,0x44,0x44,0x9dd,0x44,0x64,0x64,0x64,0x44,0x44,
 0x44,0x64,0x64,4,0x44,0x44,0x44,0x64,0x64,0x64,0x64,0x44,0x64,0x64,0x64,0x44,
 0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,
-0x44,0x44,0x44,0x44,0x8a,0xff89,0x8a,0xff89,4,4,0x8a,0xff89,0,0,5,0x4109,
-0x4109,0x4109,0,0x3a0a,0,0,0,0,4,4,0x130a,4,0x128a,0x128a,0x128a,0,
-0x200a,0,0x1f8a,0x1f8a,0x1539,0x100a,0x16da,0x100a,0x100a,0x175a,0x100a,0x100a,0x17da,0x187a,0x191a,0x100a,
-0x199a,0x100a,0x100a,0x100a,0x1a1a,0x1a9a,0,0x1b1a,0x100a,0x100a,0x1b9a,0x100a,0x100a,0x1c1a,0x100a,0x100a,
-0xed09,0xed89,0xed89,0xed89,0x1c99,0xf009,0x1e39,0xf009,0xf009,0x1eb9,0xf009,0xf009,0x1f39,0x1fd9,0x2079,0xf009,
-0x20f9,0xf009,0xf009,0xf009,0x2179,0x21f9,0x2279,0x22d9,0xf009,0xf009,0x2359,0xf009,0xf009,0x23d9,0xf009,0xf009,
-0xe009,0xe089,0xe089,0x40a,0x2459,0x24b9,2,2,2,0x2559,0x25b9,0xfc09,0x8a,0xff89,0x8a,0xff89,
-0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,
-0x8a,0xff89,0x8a,0xff89,0x2619,0x2679,0x389,0xc629,0x26da,0x2779,0,0x8a,0xff89,0xfc8a,0x8a,0xff89,
-1,0xbf0a,0xbf0a,0xbf0a,0x280a,0x280a,0x280a,0x280a,0x280a,0x280a,0x280a,0x280a,0x280a,0x280a,0x280a,0x280a,
-0x280a,0x280a,0x280a,0x280a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,
-0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,
-0x100a,0x100a,0x100a,0x100a,0xf009,0xf009,0xf009,0xf009,0xf009,0xf009,0xf009,0xf009,0xf009,0xf009,0xf009,0xf009,
-0xf009,0xf009,0xf009,0xf009,0xd809,0xd809,0xd809,0xd809,0xd809,0xd809,0xd829,0xd809,0xd829,0xd809,0xd809,0xd809,
-0xd809,0xd809,0xd809,0xd809,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,
-0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,
-0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0,0x44,0x44,0x44,0x44,0x44,4,4,0x8a,0xff89,
-0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,
-0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,
-0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,
-0x8a,0xff89,0x8a,0xff89,0x78a,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,
-0xff89,0x8a,0xff89,0xf889,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,
-0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,
-0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,
-0x8a,0xff89,0x8a,0xff89,0,0x180a,0x180a,0x180a,0x180a,0x180a,0x180a,0x180a,0x180a,0x180a,0x180a,0x180a,
-0x180a,0x180a,0x180a,0x180a,0x180a,0x180a,0x180a,0x180a,0x180a,0x180a,0x180a,0x180a,0x180a,0x180a,0x180a,0,
-0,4,0,0,0,0,0,0,0,0xe809,0xe809,0xe809,0xe809,0xe809,0xe809,0xe809,
-0xe809,0xe809,0xe809,0xe809,0xe809,0xe809,0xe809,0xe809,0xe809,0xe809,0xe809,0xe809,0xe809,0xe809,0xe809,0xe809,
-0xe809,0xe809,0xe809,0xe809,0xe809,0xe809,0xe809,0xe809,0xe809,0xe809,0xe809,0x27d9,0,0,0,0,
+0x44,0x44,0x44,0x44,0x92,0xff91,0x92,0xff91,4,4,0x92,0xff91,0,0,5,0x4111,
+0x4111,0x4111,0,0x3a12,0,0,0,0,4,4,0x1312,4,0x1292,0x1292,0x1292,0,
+0x2012,0,0x1f92,0x1f92,0xa29,0x1012,0xafa,0x1012,0x1012,0xb3a,0x1012,0x1012,0xb7a,0xbca,0xc1a,0x1012,
+0xc5a,0x1012,0x1012,0x1012,0xc9a,0xcda,0,0xd1a,0x1012,0x1012,0xd5a,0x1012,0x1012,0xd9a,0x1012,0x1012,
+0xed11,0xed91,0xed91,0xed91,0xdd9,0xf011,0xea9,0xf011,0xf011,0xee9,0xf011,0xf011,0xf29,0xf79,0xfc9,0xf011,
+0x1009,0xf011,0xf011,0xf011,0x1049,0x1089,0x10c9,0x10f9,0xf011,0xf011,0x1139,0xf011,0xf011,0x1179,0xf011,0xf011,
+0xe011,0xe091,0xe091,0x412,0x11b9,0x11e9,2,2,2,0x1239,0x1269,0xfc11,0x92,0xff91,0x92,0xff91,
+0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,
+0x92,0xff91,0x92,0xff91,0x1299,0x12c9,0x391,0xc631,0x12fa,0x1349,0,0x92,0xff91,0xfc92,0x92,0xff91,
+1,0xbf12,0xbf12,0xbf12,0x2812,0x2812,0x2812,0x2812,0x2812,0x2812,0x2812,0x2812,0x2812,0x2812,0x2812,0x2812,
+0x2812,0x2812,0x2812,0x2812,0x1012,0x1012,0x137a,0x1012,0x13ba,0x1012,0x1012,0x1012,0x1012,0x1012,0x1012,0x1012,
+0x1012,0x1012,0x13fa,0x1012,0x1012,0x143a,0x147a,0x1012,0x1012,0x1012,0x1012,0x1012,0x1012,0x1012,0x14ca,0x1012,
+0x1012,0x1012,0x1012,0x1012,0xf011,0xf011,0x1509,0xf011,0x1549,0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,
+0xf011,0xf011,0x1589,0xf011,0xf011,0x15c9,0x1609,0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,0x1659,0xf011,
+0xf011,0xf011,0xf011,0xf011,0xd811,0xd811,0xd811,0xd811,0xd811,0xd811,0xd831,0xd811,0xd831,0xd811,0xd811,0xd811,
+0xd811,0xd811,0xd811,0xd811,0x92,0xff91,0x169a,0x16d9,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,
+0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,
+0x92,0xff91,0x92,0xff91,0x92,0xff91,0,0x44,0x44,0x44,0x44,0x44,4,4,0x92,0xff91,
+0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,
+0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,
+0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,
+0x92,0xff91,0x92,0xff91,0x792,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,
+0xff91,0x92,0xff91,0xf891,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,
+0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,
+0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,
+0x92,0xff91,0x92,0xff91,0,0x1812,0x1812,0x1812,0x1812,0x1812,0x1812,0x1812,0x1812,0x1812,0x1812,0x1812,
+0x1812,0x1812,0x1812,0x1812,0x1812,0x1812,0x1812,0x1812,0x1812,0x1812,0x1812,0x1812,0x1812,0x1812,0x1812,0,
+0,4,0,0,0,0,0,4,1,0xe811,0xe811,0xe811,0xe811,0xe811,0xe811,0xe811,
+0xe811,0xe811,0xe811,0xe811,0xe811,0xe811,0xe811,0xe811,0xe811,0xe811,0xe811,0xe811,0xe811,0xe811,0xe811,0xe811,
+0xe811,0xe811,0xe811,0xe811,0xe811,0xe811,0xe811,0xe811,0xe811,0xe811,0xe811,0x1719,1,0,0,0,
 0,0,0,0,0,0x64,0x44,0x44,0x44,0x44,0x64,0x44,0x44,0x44,0x64,0x64,
 0x44,0x44,0x44,0x44,0x44,0x44,0x64,0x64,0x64,0x64,0x64,0x64,0x44,0x44,0x64,0x44,
 0x44,0x64,0x64,0x44,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,
@@ -328,12 +337,14 @@
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x64,0x44,
-4,4,0,0,0,0,4,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x44,0x44,
-0x44,0x44,4,0x44,0x44,0x44,0x44,0x44,4,0x44,0x44,0x44,4,0x44,0x44,0x44,
-0x44,0x44,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0x64,0x64,0x64,
-0,0,0,0,0,0,0,0x64,0x44,0x44,0x64,0x44,0x44,0x64,0x44,0x44,
+4,4,0,0,0,0,4,0,0,0x64,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0x44,0x44,0x44,0x44,4,0x44,0x44,0x44,0x44,0x44,4,0x44,0x44,0x44,
+4,0x44,0x44,0x44,0x44,0x44,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0x64,0x64,0x64,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0x64,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,
+0x44,0x44,0x44,0x44,0x44,0x44,4,0x64,0x44,0x44,0x64,0x44,0x44,0x64,0x44,0x44,
 0x44,0x64,0x64,0x64,0x64,0x64,0x64,0x44,0x44,0x44,0x64,0x44,0x44,0x64,0x64,0x44,
 0x44,0x44,0x44,0x44,4,4,4,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
@@ -346,7 +357,7 @@
 0,4,4,4,4,0,0,0,0,0,0,0,0,0x64,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,4,4,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x44,0,
 0,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 0,4,4,0,0,0,0,4,4,0,0,4,4,0x64,0,0,
@@ -354,166 +365,180 @@
 0,0,0,0,4,4,0,0,0,4,0,0,0,0,0,0,
 0,0,0,0,0,4,4,4,4,4,0,4,4,0,0,0,
 0,0x64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0x64,0,0,4,0,4,4,4,4,0,0,0,0,0,0,0,
-0,0x64,0,0,0,0,0,0,0,0,4,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,
-0,0,0,0,0,0x64,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,4,0,0,0,0,0,4,4,
-4,0,4,4,4,0x64,0,0,0,0,0,0,0,0x64,0x64,0,
-0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,
-4,0x64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0x64,0,0,0,0,0,0,0,4,4,
-4,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,4,0,0,4,4,4,4,0x64,0x64,0x64,0,
-0,0,0,0,0,0,4,4,0x64,0x64,0x64,0x64,4,4,4,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,4,0,0,4,4,4,4,0x64,0x64,0,4,4,0,0,0,
-0,0,0,0,0,0,4,0,0x64,0x64,0x64,0x64,4,4,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0x64,0x64,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0x64,0,0x64,0,0x64,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0x64,0x64,4,0x64,4,4,4,
-4,4,0x64,0x64,0x64,0x64,4,0,0x64,4,0x44,0x44,0x64,0,0x44,0x44,
-0,0,0,0,0,4,4,4,4,4,4,4,4,4,4,4,
-0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
-4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
-4,0,0,0,0,0,0,0,0,0,0x64,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,4,4,4,4,0,4,4,4,4,4,0x64,
-0,0x64,0x64,0,0,4,4,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-4,4,0,0,0,0,4,4,4,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,4,4,4,4,0,0,0,
-0,0,0,0,0,0,0,0,0,0,4,0,0,4,4,0,
-0,0,0,0,0,0x64,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,4,0,0,0x28da,0x291a,0x295a,0x299a,0x29da,0x2a1a,0x2a5a,0x2a9a,
-0x2ada,0x2b1a,0x2b5a,0x2b9a,0x2bda,0x2c1a,0x2c5a,0x2c9a,0x2cda,0x2d1a,0x2d5a,0x2d9a,0x2dda,0x2e1a,0x2e5a,0x2e9a,
-0x2eda,0x2f1a,0x2f5a,0x2f9a,0x2fda,0x301a,0x305a,0x309a,0x30da,0x311a,0x315a,0x319a,0x31da,0x321a,0,0x325a,
-0,0,0,0,0,0x329a,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0x44,0x44,0x44,0x4ada,0x4b3a,0x4b9a,0x4bfa,0x4c5a,0x4cba,0x4d1a,0x4d7a,
-0x4dda,0x4e3a,0x4e9a,0x4efa,0x4f5a,0x4fba,0x501a,0x507a,0x50da,0x513a,0x519a,0x51fa,0x525a,0x52ba,0,0,
-0x5319,0x5379,0x53d9,0x5439,0x5499,0x54f9,0,0,0x32da,0x333a,0x339a,0x33fa,0x345a,0x34ba,0x351a,0x357a,
-0x35da,0x363a,0x369a,0x36fa,0x375a,0x37ba,0x381a,0x387a,0x38da,0x393a,0x399a,0x39fa,0x3a5a,0x3aba,0x3b1a,0x3b7a,
-0x3bda,0x3c3a,0x3c9a,0x3cfa,0x3d5a,0x3dba,0x3e1a,0x3e7a,0x3eda,0x3f3a,0x3f9a,0x3ffa,0x405a,0x40ba,0x411a,0x417a,
-0x41da,0x423a,0x429a,0x42fa,0x435a,0x43ba,0x441a,0x447a,0x44da,0x453a,0x459a,0x45fa,0x465a,0x46ba,0x471a,0x477a,
-0x47da,0x483a,0x489a,0x48fa,0x495a,0x49ba,0x4a1a,0x4a7a,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,4,4,0x64,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,4,4,0,4,4,4,4,4,4,4,0,0,
-0,0,0,0,0,0,4,0,0,4,4,4,4,4,4,4,
-4,4,0x64,4,0,0,0,4,0,0,0,0,0,0x44,0,0,
-0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0x64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,4,4,4,0,0,0,0,4,
-4,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,
-0,0x64,0x44,0x64,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0x44,0x64,0,0,4,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,4,0,4,4,4,4,4,4,4,0,
-0x64,0,4,0,0,4,4,4,4,4,4,4,4,0,0,0,
-0,0,0,4,4,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0,0,0x64,
-0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,
-0x44,0x44,0x44,0x44,0x44,0x64,0x64,0x64,0x64,0x64,0x64,0x44,0x44,0x64,4,0,
+0,0,0,0,0,0,4,4,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,
 4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0x64,0,4,4,4,4,4,0,4,0,0,0,0,0,4,0,
-0x60,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x44,
-0x64,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0,0,0,0,0,0,0,0,
-0,0,0,0,4,4,0,0,0,0,0,0,0,0,0,0,
+0x64,0,0,4,0,4,4,4,4,0,0,0,0,0,0,0,
+0,0x64,0,0,0,0,0,0,0,4,4,0,0,0,0,0,
+0,0,0,0,0,0,4,4,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,4,4,4,4,0,0,4,4,0x60,0x64,
+0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,
+0,0x64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,4,0,0,0,4,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,4,0,0,0,0,0,4,4,4,0,4,4,
+4,0x64,0,0,0,0,0,0,0,0x64,0x64,0,0,0,0,0,
+0,0,0,0,0,0,4,0,0,0,0,0,4,0x64,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0x64,0,4,4,0,0,0,4,0,4,
-4,4,0x60,0x60,0,0,0,0,0,0,0,0,0,0,0,0,
-4,4,4,4,4,4,4,4,0,0,4,0x64,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,4,4,4,4,4,4,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0x44,0x44,0x44,0,
-0x64,0x64,0x64,0x64,0x64,0x64,0x44,0x44,0x64,0x64,0x64,0x64,0x44,0,0x64,0x64,
-0x64,0x64,0x64,0x64,0x64,0,0,0,0,0x64,0,0,0,0,0,0,
-0x44,0,0,0,0x44,0x44,0,0,0,0,0,0,1,1,1,1,
+0,0,0,0x64,0x64,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0x64,0,0,0,0,0,0,0,4,4,4,0,4,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,4,0,0,4,4,4,4,0x64,0x64,0x64,0,0,0,0,0,
+0,0,4,4,0x64,0x64,0x64,0x64,4,4,4,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,
+4,4,4,4,0x64,0x64,0x64,4,4,0,0,0,0,0,0,0,
+0,0,4,0,0x64,0x64,0x64,0x64,4,4,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0x64,0x64,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0x64,0,0x64,
+0,0x64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0x64,0x64,4,0x64,4,4,4,4,4,0x64,0x64,
+0x64,0x64,4,0,0x64,4,0x44,0x44,0x64,0,0x44,0x44,0,0,0,0,
+0,4,4,4,4,4,4,4,4,4,4,4,0,4,4,4,
+4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
+4,4,4,4,4,4,4,4,4,4,4,4,4,0,0,0,
+0,0,0,0,0,0,0x64,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,4,4,4,4,0,4,4,4,4,4,0x64,0,0x64,0x64,0,
+0,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,4,4,0,0,
+0,0,4,4,4,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,4,4,4,4,0,0,0,0,0,0,0,
+0,0,0,0,0,0,4,0,0,4,4,0,0,0,0,0,
+0,0x64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,4,0,0,0x175a,0x175a,0x175a,0x175a,0x175a,0x175a,0x175a,0x175a,0x175a,0x175a,0x175a,0x175a,
+0x175a,0x175a,0x175a,0x175a,0x175a,0x175a,0x175a,0x175a,0x175a,0x175a,0x175a,0x175a,0x175a,0x175a,0x175a,0x175a,
+0x175a,0x175a,0x175a,0x175a,0x175a,0x175a,0,0x175a,0,0,0,0,0,0x175a,0,0,
+0x1779,0x17a9,0x17d9,0x1809,0x1839,0x1869,0x1899,0x18c9,0x18f9,0x1929,0x1959,0x1989,0x19b9,0x19e9,0x1a19,0x1a49,
+0x1a79,0x1aa9,0x1ad9,0x1b09,0x1b39,0x1b69,0x1b99,0x1bc9,0x1bf9,0x1c29,0x1c59,0x1c89,0x1cb9,0x1ce9,0x1d19,0x1d49,
+0x1d79,0x1da9,0x1dd9,0x1e09,0x1e39,0x1e69,0x1e99,0x1ec9,0x1ef9,0x1f29,0x1f59,0,4,0x1f89,0x1fb9,0x1fe9,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0x44,0x44,0x44,
+0x201a,0x201a,0x201a,0x201a,0x201a,0x201a,0x201a,0x201a,0x201a,0x201a,0x201a,0x201a,0x201a,0x201a,0x201a,0x201a,
+0x203a,0x203a,0x203a,0x203a,0x203a,0x203a,0,0,0x2059,0x2089,0x20b9,0x20e9,0x2119,0x2149,0,0,
+0x201a,0x201a,0x201a,0x201a,0x201a,0x201a,0x201a,0x201a,0x201a,0x201a,0x201a,0x201a,0x201a,0x201a,0x201a,0x201a,
+0x201a,0x201a,0x201a,0x201a,0x201a,0x201a,0x201a,0x201a,0x201a,0x201a,0x201a,0x201a,0x201a,0x201a,0x201a,0x201a,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,4,4,0x64,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,4,4,0,4,
+4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,0,
+0,4,4,4,4,4,4,4,4,4,0x64,4,0,0,0,4,
+0,0,0,0,0,0x44,0,0,0,0,0,0,0,0,0,0,
+0,0,0,4,4,4,4,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,4,4,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0x64,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,0,
+0,0,0,4,4,0,0,0,0,0,0,0,0,0,4,0,
+0,0,0,0,0,0x64,0x44,0x64,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x44,
+0x64,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,4,0,4,4,4,4,
+4,4,4,0,0x64,0,4,0,0,4,4,4,4,4,4,4,
+4,0,0,0,0,0,0,4,4,0x44,0x44,0x44,0x44,0x44,0x44,0x44,
+0x44,0,0,0x64,0,0,0,0,0,0,0,4,0,0,0,0,
+0,0,0,0,0x44,0x44,0x44,0x44,0x44,0x64,0x64,0x64,0x64,0x64,0x64,0x44,
+0x44,0x64,4,0x64,0x64,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0x64,0,4,4,4,4,4,0,4,0,0,0,
+0,0,4,0,0x60,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0x44,0x64,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,4,4,4,4,0,0,
+4,4,0x60,0x64,4,4,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0x64,0,4,4,0,0,
+0,4,0,4,4,4,0x60,0x60,0,0,0,0,0,0,0,0,
+0,0,0,0,4,4,4,4,4,4,4,4,0,0,4,0x64,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,4,4,4,4,4,4,0,0,
+0x2179,0x21a9,0x21d9,0x2209,0x2239,0x2289,0x22d9,0x2309,0x2339,0,0,0,0,0,0,0,
+0x236a,0x236a,0x236a,0x236a,0x236a,0x236a,0x236a,0x236a,0x236a,0x236a,0x236a,0x236a,0x236a,0x236a,0x236a,0x236a,
+0x236a,0x236a,0x236a,0x236a,0x236a,0x236a,0x236a,0x236a,0x236a,0x236a,0x236a,0,0,0x236a,0x236a,0x236a,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0x44,0x44,0x44,0,0x64,0x64,0x64,0x64,0x64,0x64,0x44,0x44,0x64,0x64,0x64,0x64,
+0x44,0,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0,0,0,0,0x64,0,0,
+0,0,0,0,0x44,0,0,0,0x44,0x44,0,0,0,0,0,0,
 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-1,1,1,1,1,1,1,1,1,1,1,1,5,5,5,5,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,0x25,5,
-5,5,5,5,5,5,5,1,1,1,1,1,1,1,1,1,
-1,1,1,1,5,0x5559,1,1,1,0x5599,1,1,5,5,5,5,
-0x25,5,5,5,0x25,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,1,1,1,1,
-1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-1,1,0x21,1,1,1,1,5,5,5,5,5,0x44,0x44,0x44,0x44,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,0x25,5,5,5,5,5,5,5,5,1,1,1,1,1,
+1,1,1,1,1,1,1,1,5,0x2389,1,1,1,0x23a9,1,1,
+5,5,5,5,0x25,5,5,5,0x25,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,0x23c9,1,
+1,1,1,1,1,1,0x21,1,1,1,1,5,5,5,5,5,
 0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,
-0x44,0x44,0,0,0,0,0,0,0x64,0x64,0x44,0x64,0x44,0x44,0x64,0x44,
-0x44,0x44,0x44,0x44,0x44,0x44,0x64,0x44,0x44,0x64,0x64,0x64,0x64,0x44,0x44,0x44,
-0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x8a,0xff89,0x8a,0xff89,
-0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xffa9,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,
-0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x55da,0x5659,0x8a,0xff89,
-0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,
-0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x56d9,0x57d9,
-0x58d9,0x59d9,0x5ad9,0x5bd9,1,1,0x5c3a,1,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,
-0x8a,0xff89,0x8a,0xffa9,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,
-0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x409,0x409,0x409,0x409,0x409,0x409,0x409,0x409,
-0xfc0a,0xfc0a,0xfc0a,0xfc0a,0xfc0a,0xfc0a,0xfc0a,0xfc0a,0x409,0x409,0x409,0x409,0x409,0x409,0,0,
-0xfc0a,0xfc0a,0xfc0a,0xfc0a,0xfc0a,0xfc0a,0,0,0x409,0x409,0x409,0x409,0x409,0x409,0x409,0x409,
-0xfc0a,0xfc0a,0xfc0a,0xfc0a,0xfc0a,0xfc0a,0xfc0a,0xfc0a,0x409,0x409,0x409,0x409,0x409,0x409,0x409,0x409,
-0xfc0a,0xfc0a,0xfc0a,0xfc0a,0xfc0a,0xfc0a,0xfc0a,0xfc0a,0x409,0x409,0x409,0x409,0x409,0x409,0,0,
-0xfc0a,0xfc0a,0xfc0a,0xfc0a,0xfc0a,0xfc0a,0,0,0x5cd9,0x409,0x5dd9,0x409,0x5f39,0x409,0x6099,0x409,
-0,0xfc0a,0,0xfc0a,0,0xfc0a,0,0xfc0a,0x409,0x409,0x409,0x409,0x409,0x409,0x409,0x409,
-0xfc0a,0xfc0a,0xfc0a,0xfc0a,0xfc0a,0xfc0a,0xfc0a,0xfc0a,0x2509,0x2509,0x2b09,0x2b09,0x2b09,0x2b09,0x3209,0x3209,
-0x4009,0x4009,0x3809,0x3809,0x3f09,0x3f09,0,0,0x61f9,0x62d9,0x63b9,0x6499,0x6579,0x6659,0x6739,0x6819,
-0x68fb,0x69db,0x6abb,0x6b9b,0x6c7b,0x6d5b,0x6e3b,0x6f1b,0x6ff9,0x70d9,0x71b9,0x7299,0x7379,0x7459,0x7539,0x7619,
-0x76fb,0x77db,0x78bb,0x799b,0x7a7b,0x7b5b,0x7c3b,0x7d1b,0x7df9,0x7ed9,0x7fb9,0x8099,0x8179,0x8259,0x8339,0x8419,
-0x84fb,0x85db,0x86bb,0x879b,0x887b,0x895b,0x8a3b,0x8b1b,0x409,0x409,0x8bf9,0x8cf9,0x8dd9,0,0x8ed9,0x8fd9,
-0xfc0a,0xfc0a,0xdb0a,0xdb0a,0x913b,4,0x9219,4,4,4,0x92b9,0x93b9,0x9499,0,0x9599,0x9699,
-0xd50a,0xd50a,0xd50a,0xd50a,0x97fb,4,4,4,0x409,0x409,0x98d9,0x9a39,0,0,0x9bd9,0x9cd9,
-0xfc0a,0xfc0a,0xce0a,0xce0a,0,4,4,4,0x409,0x409,0x9e39,0x9f99,0xa139,0x389,0xa239,0xa339,
-0xfc0a,0xfc0a,0xc80a,0xc80a,0xfc8a,4,4,4,0,0,0xa499,0xa599,0xa679,0,0xa779,0xa879,
-0xc00a,0xc00a,0xc10a,0xc10a,0xa9db,4,4,0,0,0,0,0,0,0,0,0,
-0,0,0,4,4,4,4,4,0,0,0,0,0,0,0,0,
-4,4,0,0,0,0,0,0,4,0,0,4,0,0,4,4,
-4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,4,4,4,4,4,0,4,4,4,4,4,4,
-4,4,4,4,0,0x25,0,0,0,0,0,0,0,0,0,0,
-0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,
-5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0x44,0x44,0x64,0x64,0x44,0x44,0x44,0x44,0x64,0x64,0x64,0x44,
-0x44,4,4,4,4,0x44,4,4,4,0x64,0x64,0x44,0x64,0x44,0x64,0x64,
-0x64,0x64,0x64,0x64,0x44,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,2,0,0,0,0,2,0,0,1,2,
-2,2,1,1,2,2,2,1,0,2,0,0,0,2,2,2,
-2,2,0,0,0,0,0,0,2,0,0xaaba,0,2,0,0xab3a,0xabba,
-2,2,0,1,2,2,0xe0a,2,1,0,0,0,0,1,0,0,
-1,1,2,2,0,0,0,0,0,2,1,1,0x21,0x21,0,0,
-0,0,0xf209,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0x80a,0x80a,0x80a,0x80a,0x80a,0x80a,0x80a,0x80a,0x80a,0x80a,0x80a,0x80a,
-0x80a,0x80a,0x80a,0x80a,0xf809,0xf809,0xf809,0xf809,0xf809,0xf809,0xf809,0xf809,0xf809,0xf809,0xf809,0xf809,
-0xf809,0xf809,0xf809,0xf809,0,0,0,0x8a,0xff89,0,0,0,0,0,0,0,
+0x44,0x44,0x44,0x44,0x44,0x44,0x64,0x64,0x64,0x64,0,0x44,0x64,0x64,0x44,0x64,
+0x44,0x44,0x64,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x64,0x44,0x44,0x64,0x64,0x64,
+0x64,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,
+0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xffb1,0x92,0xff91,
+0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,
+0x23ea,0x2429,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,
+0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,
+0x92,0xff91,0x2469,0x24e9,0x2569,0x25e9,0x2669,0x26e9,1,1,0x271a,1,0x92,0xff91,0x92,0xff91,
+0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xffb1,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,
+0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x411,0x411,0x411,0x411,
+0x411,0x411,0x411,0x411,0xfc12,0xfc12,0xfc12,0xfc12,0xfc12,0xfc12,0xfc12,0xfc12,0x411,0x411,0x411,0x411,
+0x411,0x411,0,0,0xfc12,0xfc12,0xfc12,0xfc12,0xfc12,0xfc12,0,0,0x411,0x411,0x411,0x411,
+0x411,0x411,0x411,0x411,0xfc12,0xfc12,0xfc12,0xfc12,0xfc12,0xfc12,0xfc12,0xfc12,0x411,0x411,0x411,0x411,
+0x411,0x411,0x411,0x411,0xfc12,0xfc12,0xfc12,0xfc12,0xfc12,0xfc12,0xfc12,0xfc12,0x411,0x411,0x411,0x411,
+0x411,0x411,0,0,0xfc12,0xfc12,0xfc12,0xfc12,0xfc12,0xfc12,0,0,0x2769,0x411,0x27e9,0x411,
+0x2899,0x411,0x2949,0x411,0,0xfc12,0,0xfc12,0,0xfc12,0,0xfc12,0x411,0x411,0x411,0x411,
+0x411,0x411,0x411,0x411,0xfc12,0xfc12,0xfc12,0xfc12,0xfc12,0xfc12,0xfc12,0xfc12,0x2511,0x2511,0x2b11,0x2b11,
+0x2b11,0x2b11,0x3211,0x3211,0x4011,0x4011,0x3811,0x3811,0x3f11,0x3f11,0,0,0x29f9,0x2a69,0x2ad9,0x2b49,
+0x2bb9,0x2c29,0x2c99,0x2d09,0x2d7b,0x2deb,0x2e5b,0x2ecb,0x2f3b,0x2fab,0x301b,0x308b,0x30f9,0x3169,0x31d9,0x3249,
+0x32b9,0x3329,0x3399,0x3409,0x347b,0x34eb,0x355b,0x35cb,0x363b,0x36ab,0x371b,0x378b,0x37f9,0x3869,0x38d9,0x3949,
+0x39b9,0x3a29,0x3a99,0x3b09,0x3b7b,0x3beb,0x3c5b,0x3ccb,0x3d3b,0x3dab,0x3e1b,0x3e8b,0x411,0x411,0x3ef9,0x3f79,
+0x3fe9,0,0x4069,0x40e9,0xfc12,0xfc12,0xdb12,0xdb12,0x419b,4,0x4209,4,4,4,0x4259,0x42d9,
+0x4349,0,0x43c9,0x4449,0xd512,0xd512,0xd512,0xd512,0x44fb,4,4,4,0x411,0x411,0x4569,0x4619,
+0,0,0x46e9,0x4769,0xfc12,0xfc12,0xce12,0xce12,0,4,4,4,0x411,0x411,0x4819,0x48c9,
+0x4999,0x391,0x4a19,0x4a99,0xfc12,0xfc12,0xc812,0xc812,0xfc92,4,4,4,0,0,0x4b49,0x4bc9,
+0x4c39,0,0x4cb9,0x4d39,0xc012,0xc012,0xc112,0xc112,0x4deb,4,4,0,0,0,0,0,
+0,0,0,0,0,0,0,4,4,4,4,4,0,0,0,0,
+0,0,0,0,4,4,0,0,0,0,0,0,4,0,0,4,
+0,0,4,4,4,4,4,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,4,4,4,4,4,0,4,4,
+4,4,4,4,4,4,4,4,0,0x25,0,0,0,0,0,0,
+0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,
+5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0x44,0x44,0x64,0x64,0x44,0x44,0x44,0x44,
+0x64,0x64,0x64,0x44,0x44,4,4,4,4,0x44,4,4,4,0x64,0x64,0x44,
+0x64,0x44,0x64,0x64,0x64,0x64,0x64,0x64,0x44,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,2,
+0,0,1,2,2,2,1,1,2,2,2,1,0,2,0,0,
+0,2,2,2,2,2,0,0,0,0,0,0,2,0,0x4e5a,0,
+2,0,0x4e9a,0x4eda,2,2,0,1,2,2,0xe12,2,1,0,0,0,
+0,1,0,0,1,1,2,2,0,0,0,0,0,2,1,1,
+0x21,0x21,0,0,0,0,0xf211,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0x812,0x812,0x812,0x812,0x812,0x812,0x812,0x812,
+0x812,0x812,0x812,0x812,0x812,0x812,0x812,0x812,0xf811,0xf811,0xf811,0xf811,0xf811,0xf811,0xf811,0xf811,
+0xf811,0xf811,0xf811,0xf811,0xf811,0xf811,0xf811,0xf811,0,0,0,0x92,0xff91,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0xd0a,0xd0a,0xd0a,0xd0a,0xd0a,0xd0a,0xd0a,0xd0a,0xd0a,0xd0a,
-0xd0a,0xd0a,0xd0a,0xd0a,0xd0a,0xd0a,0xd0a,0xd0a,0xf309,0xf309,0xf309,0xf309,0xf309,0xf309,0xf309,0xf309,
-0xf309,0xf309,0xf309,0xf309,0xf309,0xf309,0xf309,0xf309,0xf309,0xf309,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0xd12,0xd12,0xd12,0xd12,0xd12,0xd12,
+0xd12,0xd12,0xd12,0xd12,0xd12,0xd12,0xd12,0xd12,0xd12,0xd12,0xd12,0xd12,0xf311,0xf311,0xf311,0xf311,
+0xf311,0xf311,0xf311,0xf311,0xf311,0xf311,0xf311,0xf311,0xf311,0xf311,0xf311,0xf311,0xf311,0xf311,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0x180a,0x180a,0x180a,0x180a,0x180a,0x180a,0x180a,0x180a,0x180a,0x180a,0x180a,0x180a,0x180a,0x180a,0x180a,0x180a,
-0x180a,0x180a,0x180a,0x180a,0x180a,0x180a,0x180a,0x180a,0x180a,0x180a,0x180a,0x180a,0x180a,0x180a,0x180a,0x180a,
-0x180a,0x180a,0x180a,0,0xe809,0xe809,0xe809,0xe809,0xe809,0xe809,0xe809,0xe809,0xe809,0xe809,0xe809,0xe809,
-0xe809,0xe809,0xe809,0xe809,0xe809,0xe809,0xe809,0xe809,0xe809,0xe809,0xe809,0xe809,0xe809,0xe809,0xe809,0xe809,
-0xe809,0xe809,0xe809,0,0x8a,0xff89,0xac3a,0xac7a,0xacba,0xacf9,0xad39,0x8a,0xff89,0x8a,0xff89,0x8a,
-0xff89,0xad7a,0xadba,0xadfa,0xae3a,1,0x8a,0xff89,1,0x8a,0xff89,1,1,1,1,1,
-0x25,5,0xae7a,0xaeba,0x8a,0xff89,0x8a,0xff89,1,0,0,0,0,0,0,0x8a,
-0xff89,0x8a,0xff89,0x44,0x44,0x44,0x8a,0xff89,0,0,0,0,0,0,0,0,
-0,0,0,0,0xaef9,0xaf39,0xaf79,0xafb9,0xaff9,0xb039,0xb079,0xb0b9,0xb0f9,0xb139,0xb179,0xb1b9,
-0xb1f9,0xb239,0xb279,0xb2b9,0xb2f9,0xb339,0xb379,0xb3b9,0xb3f9,0xb439,0xb479,0xb4b9,0xb4f9,0xb539,0xb579,0xb5b9,
-0xb5f9,0xb639,0xb679,0xb6b9,0xb6f9,0xb739,0xb779,0xb7b9,0xb7f9,0xb839,0,0xb879,0,0,0,0,
-0,0xb8b9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0x1812,0x1812,0x1812,0x1812,0x1812,0x1812,0x1812,0x1812,0x1812,0x1812,0x1812,0x1812,
+0x1812,0x1812,0x1812,0x1812,0x1812,0x1812,0x1812,0x1812,0x1812,0x1812,0x1812,0x1812,0x1812,0x1812,0x1812,0x1812,
+0x1812,0x1812,0x1812,0x1812,0x1812,0x1812,0x1812,0,0xe811,0xe811,0xe811,0xe811,0xe811,0xe811,0xe811,0xe811,
+0xe811,0xe811,0xe811,0xe811,0xe811,0xe811,0xe811,0xe811,0xe811,0xe811,0xe811,0xe811,0xe811,0xe811,0xe811,0xe811,
+0xe811,0xe811,0xe811,0xe811,0xe811,0xe811,0xe811,0,0x92,0xff91,0x4f1a,0x4f3a,0x4f5a,0x4f79,0x4f99,0x92,
+0xff91,0x92,0xff91,0x92,0xff91,0x4fba,0x4fda,0x4ffa,0x501a,1,0x92,0xff91,1,0x92,0xff91,1,
+1,1,1,1,0x25,5,0x503a,0x503a,0x92,0xff91,0x92,0xff91,1,0,0,0,
+0,0,0,0x92,0xff91,0x92,0xff91,0x44,0x44,0x44,0x92,0xff91,0,0,0,0,
+0,0,0,0,0,0,0,0,0x5059,0x5059,0x5059,0x5059,0x5059,0x5059,0x5059,0x5059,
+0x5059,0x5059,0x5059,0x5059,0x5059,0x5059,0x5059,0x5059,0x5059,0x5059,0x5059,0x5059,0x5059,0x5059,0x5059,0x5059,
+0x5059,0x5059,0x5059,0x5059,0x5059,0x5059,0x5059,0x5059,0x5059,0x5059,0,0x5059,0,0,0,0,
+0,0x5059,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0x64,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,
 0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,
@@ -526,306 +551,352 @@
 4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0x8a,0xff89,0x8a,0xff89,
-0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0,0x44,4,4,4,0,
-0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0,4,0x8a,0xff89,0x8a,0xff89,
-0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,
-0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,5,5,0x44,0x44,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0x44,0x44,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,
+0,0,0,0,0,0,0,0,0,0,0,0,0x92,0xff91,0x92,0xff91,
+0x92,0xff91,0x92,0xff91,0x92,0xff91,0x507a,0x50b9,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,
+0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0,0x44,
+4,4,4,0,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0,4,
+0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,
+0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,5,5,0x44,0x44,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0x44,0x44,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
-4,4,4,4,4,4,4,4,4,4,4,4,4,4,0x8a,0xff89,
-0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,1,1,0x8a,0xff89,
-0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,
-5,1,1,1,1,1,1,1,1,0x8a,0xff89,0x8a,0xff89,0xb8fa,0x8a,0xff89,
-0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,4,4,4,0x8a,0xff89,0xb93a,1,0,
-0x8a,0xff89,0x8a,0xff89,1,1,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,0x8a,0xff89,
-0x8a,0xff89,0xb97a,0xb9ba,0xb9fa,0xba3a,0,0,0xba7a,0xbaba,0xbafa,0xbb3a,0x8a,0xff89,0x8a,0xff89,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,5,5,1,0,0,0,0,0,
-0,0,4,0,0,0,0x64,0,0,0,0,4,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
+4,4,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,
+1,1,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,
+0x92,0xff91,0x92,0xff91,5,1,1,1,1,1,1,1,1,0x92,0xff91,0x92,
+0xff91,0x50fa,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,4,4,4,0x92,
+0xff91,0x511a,1,0,0x92,0xff91,0x92,0xff91,0x1811,1,0x92,0xff91,0x92,0xff91,0x92,0xff91,
+0x92,0xff91,0x92,0xff91,0x92,0xff91,0x513a,0x515a,0x517a,0x519a,0x513a,1,0x51ba,0x51da,0x51fa,0x521a,
+0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0x92,0xff91,0,0,0x92,0xff91,
+0xe812,0x523a,0x525a,0x92,0xff91,0x92,0xff91,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0x92,0xff91,0,
+5,5,1,0,0,0,0,0,0,0,4,0,0,0,0x64,0,
+0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,4,4,0,0,0,0,0,
 0x64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0x44,0x44,0x44,0x44,
-0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,
-4,4,4,0x64,0x64,0x64,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,
-4,4,4,4,4,4,0,0x60,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0x64,0,0,4,4,
-4,4,0,0,4,0,0,0,0x60,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,0,
-0,4,4,0,0,4,4,0,0,0,0,0,0,0,0,0,
-0,0,0,4,0,0,0,0,0,0,0,0,4,0,0,0,
+0,0,0,0,0x64,4,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-4,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,
+0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,
+0x44,0x44,0,0,0,0,0,0,0,0,0,0,0,0,0,4,
+0,0,0,0,0,0,4,4,4,4,4,0x64,0x64,0x64,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0x44,0,0x44,0x44,0x64,0,0,0x44,0x44,0,0,0,0,0,0x44,0x44,
-0,0x44,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,4,4,0,0,
-0,0,0,4,4,0,0x64,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,
-1,1,1,1,1,1,1,1,1,1,1,0xbb79,1,1,1,1,
-1,1,1,4,5,5,5,5,1,1,1,1,1,1,0,0,
-0,0,0,0,0,0,0,0,0xbbb9,0xbc19,0xbc79,0xbcd9,0xbd39,0xbd99,0xbdf9,0xbe59,
-0xbeb9,0xbf19,0xbf79,0xbfd9,0xc039,0xc099,0xc0f9,0xc159,0xcdb9,0xce19,0xce79,0xced9,0xcf39,0xcf99,0xcff9,0xd059,
-0xd0b9,0xd119,0xd179,0xd1d9,0xd239,0xd299,0xd2f9,0xd359,0xd3b9,0xd419,0xd479,0xd4d9,0xd539,0xd599,0xd5f9,0xd659,
-0xd6b9,0xd719,0xd779,0xd7d9,0xd839,0xd899,0xd8f9,0xd959,0xc1b9,0xc219,0xc279,0xc2d9,0xc339,0xc399,0xc3f9,0xc459,
-0xc4b9,0xc519,0xc579,0xc5d9,0xc639,0xc699,0xc6f9,0xc759,0xc7b9,0xc819,0xc879,0xc8d9,0xc939,0xc999,0xc9f9,0xca59,
-0xcab9,0xcb19,0xcb79,0xcbd9,0xcc39,0xcc99,0xccf9,0xcd59,0,0,0,0,0,4,0,0,
-4,0,0,0,0,0x64,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0xd9b9,0xdab9,0xdbb9,0xdcb9,0xde19,0xdf79,0xe0b9,0,
-0,0,0,0,0,0,0,0,0,0,0,0xe1f9,0xe2f9,0xe3f9,0xe4f9,0xe5f9,
-0,0,0,0,0,0,0x64,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,
-4,4,4,4,4,4,4,4,4,4,4,4,0,0,0,4,
-0,0,0,0,0,0,0,0,0,0,0,0,0x44,0x44,0x44,0x44,
-0x44,0x44,0x44,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x44,0x44,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,
-0,4,0,0,0,0,0,0,0,0,0,0,0,0x100a,0x100a,0x100a,
-0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,
-0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0,0,0,4,0,4,0xf009,0xf009,0xf009,
-0xf009,0xf009,0xf009,0xf009,0xf009,0xf009,0xf009,0xf009,0xf009,0xf009,0xf009,0xf009,0xf009,0xf009,0xf009,0xf009,
-0xf009,0xf009,0xf009,0xf009,0xf009,0xf009,0xf009,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,
+0,0,0,4,4,4,4,4,4,4,4,4,4,4,0,0x60,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0x64,0,0,4,4,4,4,0,0,4,4,0,0,
+0x60,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,4,4,4,4,4,4,0,0,4,4,0,0,4,4,0,
 0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,
+0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,
+0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0x44,0,0x44,0x44,0x64,0,0,0x44,
+0x44,0,0,0,0,0,0x44,0x44,0,0x44,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,4,4,4,0,0,0,0,0x64,0,0,0,0,0,0,0,
+0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,4,4,0,0,0,0,0,4,4,0,0x64,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0x44,0x44,0x44,0x44,0x44,0,
-0,0,0,0,0x140a,0x140a,0x140a,0x140a,0x140a,0x140a,0x140a,0x140a,0x140a,0x140a,0x140a,0x140a,
-0x140a,0x140a,0x140a,0x140a,0x140a,0x140a,0x140a,0x140a,0x140a,0x140a,0x140a,0x140a,0x140a,0x140a,0x140a,0x140a,
-0x140a,0x140a,0x140a,0x140a,0xec09,0xec09,0xec09,0xec09,0xec09,0xec09,0xec09,0xec09,0xec09,0xec09,0xec09,0xec09,
-0xec09,0xec09,0xec09,0xec09,0xec09,0xec09,0xec09,0xec09,0xec09,0xec09,0xec09,0xec09,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,0x5279,1,1,1,1,1,1,1,4,5,5,5,5,
+1,1,1,1,1,1,1,1,1,4,4,4,0,0,0,0,
+0x5299,0x52c9,0x52f9,0x5329,0x5359,0x5389,0x53b9,0x53e9,0x5419,0x5449,0x5479,0x54a9,0x54d9,0x5509,0x5539,0x5569,
+0x5b99,0x5bc9,0x5bf9,0x5c29,0x5c59,0x5c89,0x5cb9,0x5ce9,0x5d19,0x5d49,0x5d79,0x5da9,0x5dd9,0x5e09,0x5e39,0x5e69,
+0x5e99,0x5ec9,0x5ef9,0x5f29,0x5f59,0x5f89,0x5fb9,0x5fe9,0x6019,0x6049,0x6079,0x60a9,0x60d9,0x6109,0x6139,0x6169,
+0x5599,0x55c9,0x55f9,0x5629,0x5659,0x5689,0x56b9,0x56e9,0x5719,0x5749,0x5779,0x57a9,0x57d9,0x5809,0x5839,0x5869,
+0x5899,0x58c9,0x58f9,0x5929,0x5959,0x5989,0x59b9,0x59e9,0x5a19,0x5a49,0x5a79,0x5aa9,0x5ad9,0x5b09,0x5b39,0x5b69,
+0,0,0,0,0,4,0,0,4,0,0,0,0,0x64,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0x6199,0x6219,0x6299,0x6319,0x63c9,0x6479,0x6519,0,0,0,0,0,0,0,0,0,
+0,0,0,0x65b9,0x6639,0x66b9,0x6739,0x67b9,0,0,0,0,0,0,0x64,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
+4,4,4,4,0,0,0,4,0,0,0,0,0,0,0,0,
+0,0,0,0,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x64,0x64,0x64,0x64,0x64,
+0x64,0x64,0x44,0x44,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,4,0,0,4,0,0,0,0,0,0,
+0,0,0,0,0,0x1012,0x1012,0x1012,0x1012,0x1012,0x1012,0x1012,0x1012,0x1012,0x1012,0x1012,
+0x1012,0x1012,0x1012,0x1012,0x1012,0x1012,0x1012,0x1012,0x1012,0x1012,0x1012,0x1012,0x1012,0x1012,0x1012,0,
+0,0,4,0,4,0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,
+0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,4,4,4,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0x64,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0x44,0x44,0x44,0x44,0x44,0,0,0,0,0,0x1412,0x1412,0x1412,0x1412,
+0x1412,0x1412,0x1412,0x1412,0x1412,0x1412,0x1412,0x1412,0x1412,0x1412,0x1412,0x1412,0x1412,0x1412,0x1412,0x1412,
+0x1412,0x1412,0x1412,0x1412,0x1412,0x1412,0x1412,0x1412,0x1412,0x1412,0x1412,0x1412,0xec11,0xec11,0xec11,0xec11,
+0xec11,0xec11,0xec11,0xec11,0xec11,0xec11,0xec11,0xec11,0xec11,0xec11,0xec11,0xec11,0xec11,0xec11,0xec11,0xec11,
+0xec11,0xec11,0xec11,0xec11,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0x1412,0x1412,0x1412,0x1412,0x1412,0x1412,0x1412,0x1412,0x1412,0x1412,0x1412,0x1412,
+0x1412,0x1412,0x1412,0x1412,0x1412,0x1412,0x1412,0x1412,0,0,0,0,0xec11,0xec11,0xec11,0xec11,
+0xec11,0xec11,0xec11,0xec11,0xec11,0xec11,0xec11,0xec11,0xec11,0xec11,0xec11,0xec11,0xec11,0xec11,0xec11,0xec11,
+0xec11,0xec11,0xec11,0xec11,0xec11,0xec11,0xec11,0xec11,0,0,0,0,0,4,4,4,
 0,4,4,0,0,0,0,0,4,0x64,4,0x44,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0x44,0x64,0x64,0,0,0,0,0x64,0,0,0,0,
 0,0x44,0x64,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0x200a,0x200a,0x200a,0x200a,
-0x200a,0x200a,0x200a,0x200a,0x200a,0x200a,0x200a,0x200a,0x200a,0x200a,0x200a,0x200a,0x200a,0x200a,0x200a,0x200a,
-0x200a,0x200a,0x200a,0x200a,0x200a,0x200a,0x200a,0x200a,0x200a,0x200a,0x200a,0x200a,0x200a,0x200a,0x200a,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0xe009,0xe009,0xe009,0xe009,
-0xe009,0xe009,0xe009,0xe009,0xe009,0xe009,0xe009,0xe009,0xe009,0xe009,0xe009,0xe009,0xe009,0xe009,0xe009,0xe009,
-0xe009,0xe009,0xe009,0xe009,0xe009,0xe009,0xe009,0xe009,0xe009,0xe009,0xe009,0xe009,0xe009,0xe009,0xe009,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0x2012,0x2012,0x2012,0x2012,
+0x2012,0x2012,0x2012,0x2012,0x2012,0x2012,0x2012,0x2012,0x2012,0x2012,0x2012,0x2012,0x2012,0x2012,0x2012,0x2012,
+0x2012,0x2012,0x2012,0x2012,0x2012,0x2012,0x2012,0x2012,0x2012,0x2012,0x2012,0x2012,0x2012,0x2012,0x2012,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0xe011,0xe011,0xe011,0xe011,
+0xe011,0xe011,0xe011,0xe011,0xe011,0xe011,0xe011,0xe011,0xe011,0xe011,0xe011,0xe011,0xe011,0xe011,0xe011,0xe011,
+0xe011,0xe011,0xe011,0xe011,0xe011,0xe011,0xe011,0xe011,0xe011,0xe011,0xe011,0xe011,0xe011,0xe011,0xe011,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0x44,0x44,0x44,0x44,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0x44,0x44,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0x64,0x64,0x44,0x44,0x44,0x64,0x44,0x64,0x64,0x64,0x64,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,
 4,4,0x64,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,
+4,4,4,0,0,0x64,0x64,0,0,4,0,0,0x44,0x44,0x44,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,
+4,4,4,4,0,4,4,4,4,4,4,0x64,0x64,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0x64,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,4,4,4,4,0,0,0x64,0x64,0,
-0,4,0,0,0x44,0x44,0x44,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,
+4,4,4,0,0x60,0,0,0,0,0,0,0,0,4,0x64,4,
+4,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,4,4,4,0,0,4,0x60,0x64,4,
+0,0,0,0,0,0,4,0,0,0,0,4,4,4,4,4,
+4,0x64,0x64,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,
+0,0,0,0,0,0x60,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0x44,0x44,0x44,0x44,0x44,0x44,
+0x44,0,0,0,0x44,0x44,0x44,0x44,0x44,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0x64,4,4,0,0x64,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,4,4,4,4,4,0,4,4,4,
-4,4,4,0x64,0x64,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,
-4,4,4,4,4,4,4,0,0x60,0,0,0,0,0,0,0,
-0,0,0x64,4,4,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,4,4,4,0,0,
-4,0x60,0x64,4,0,0,0,0,0,0,0,0,0,0,0,4,
-4,4,4,4,4,0x64,0x64,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,
-0,0,0,0,0,0,0,0,0,0x60,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x44,0x44,
-0x44,0x44,0x44,0x44,0x44,0,0,0,0x44,0x44,0x44,0x44,0x44,0,0,0,
+0,0,0x44,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,4,4,4,4,4,4,0,4,0,
+0,0,0,4,4,0,0x64,0x64,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,4,4,4,4,4,4,0,4,0,0,0,0,4,
-4,0,0x64,0x64,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,4,4,4,4,0,0,0,0,0,0,
+4,4,0,0x64,0x64,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,4,4,4,4,0,0,0,0,0,0,4,4,0,0x64,
-0x64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,
+0,4,0,0x64,0,0,0,0,0,0,0,0,0,0,0,4,
+0,4,0,0,4,4,4,4,4,4,0x60,0x64,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,4,4,4,0,0,4,4,
+4,4,0,4,4,4,4,0x64,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,
+4,4,4,4,4,4,4,4,0,0x64,0x64,0,0,0,0,0,
+0x1012,0x1012,0x1012,0x1012,0x1012,0x1012,0x1012,0x1012,0x1012,0x1012,0x1012,0x1012,0x1012,0x1012,0x1012,0x1012,
+0x1012,0x1012,0x1012,0x1012,0x1012,0x1012,0x1012,0x1012,0x1012,0x1012,0x1012,0x1012,0x1012,0x1012,0x1012,0x1012,
+0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,
+0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,0xf011,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,4,4,0x60,0x64,0,
+0,0,0,0x64,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+4,4,4,4,0,0,4,4,0,0,0,0,0,4,4,4,
+4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,
+0x64,4,4,4,4,0,0,4,4,4,4,0,0,0,0,0,
+0,0,0,0x64,0,0,0,0,0,0,0,0,0,4,4,4,
+4,4,4,0,0,4,4,4,0,0,0,0,0,0,0,0,
+0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,0,
+4,0x64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,4,4,4,4,4,4,4,0,4,4,4,4,
+4,4,0,0x64,4,4,4,4,4,4,4,4,0,0,4,4,
+4,4,4,4,4,0,4,4,0,4,4,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,
+4,4,4,0,0,0,4,0,4,4,0,4,4,4,0x64,4,
+0x64,0x64,0,4,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,4,4,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,4,4,4,4,4,4,4,4,0,0,4,0,0x64,
-0,0,0,0,0,0,0,0,0,0,0,4,0,4,0,0,
-4,4,4,4,4,4,0x60,0x64,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,4,4,4,0,0,4,4,4,4,0,4,
-4,4,4,0x64,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0xf009,0xf009,0xf009,0xf009,0xf009,0xf009,0xf009,0xf009,
-0xf009,0xf009,0xf009,0xf009,0xf009,0xf009,0xf009,0xf009,0xf009,0xf009,0xf009,0xf009,0xf009,0xf009,0xf009,0xf009,
-0xf009,0xf009,0xf009,0xf009,0xf009,0xf009,0xf009,0xf009,0,0,0,0,0,0,0,0,
+0,4,0,0x64,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,4,4,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,
+4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0x64,0x64,0x64,0x64,0x64,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 0x44,0x44,0x44,0x44,0x44,0x44,0x44,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,4,
-4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,
+4,4,4,4,4,4,4,4,4,4,0,4,4,0,0,0,
+0,0,0,0,0,0,0,0,0x60,0x60,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,4,0x64,0,0,0,0,0,0,0x60,0x60,0x64,
-0x64,0x64,0,0,0,0x60,0x60,0x60,0x60,0x60,0x60,4,4,4,4,4,
-4,4,4,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0,0,0x44,0x44,0x44,
-0x44,0x44,0x64,0x64,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0x44,0x44,0x44,0x44,0,0,
+0,0,0,0,0,0,0,0,0,4,0x64,0,0,0,0,0,
+0,0x60,0x60,0x64,0x64,0x64,0,0,0,0x60,0x60,0x60,0x60,0x60,0x60,4,
+4,4,4,4,4,4,4,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0,
+0,0x44,0x44,0x44,0x44,0x44,0x64,0x64,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x44,0x44,
+0x44,0x44,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0x44,0x44,0x44,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0x44,0x44,0x44,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
-2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,
-1,1,0x21,0x21,1,1,1,1,1,1,1,1,1,1,1,1,
-1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,
-2,2,1,1,1,1,1,1,1,0,0x21,0x21,1,1,1,1,
-1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,
+0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,
 2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,
 1,1,1,1,1,1,0x21,0x21,1,1,1,1,1,1,1,1,
-1,1,1,1,1,1,1,1,2,0,2,2,0,0,2,0,
-0,2,2,0,0,2,2,2,2,0,2,2,2,2,2,2,
-2,2,1,1,1,1,0,1,0,1,0x21,0x21,1,1,1,1,
-0,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,
-2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,
-2,2,0,2,2,2,2,0,0,2,2,2,2,2,2,2,
-2,0,2,2,2,2,2,2,2,0,1,1,1,1,1,1,
-1,1,0x21,0x21,1,1,1,1,1,1,1,1,1,1,1,1,
-1,1,1,1,2,2,0,2,2,2,2,0,2,2,2,2,
-2,0,2,0,0,0,2,2,2,2,2,2,2,0,1,1,
-1,1,1,1,1,1,0x21,0x21,1,1,1,1,1,1,1,1,
-1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,
-2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,
 1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,
-2,2,2,2,2,2,2,2,1,1,1,1,1,1,0,0,
+2,2,2,2,2,2,1,1,1,1,1,1,1,0,0x21,0x21,
+1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,
 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
-2,2,2,2,2,2,2,2,2,0,1,1,1,1,1,1,
+2,2,1,1,1,1,1,1,1,1,0x21,0x21,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,2,0,2,2,
+0,0,2,0,0,2,2,0,0,2,2,2,2,0,2,2,
+2,2,2,2,2,2,1,1,1,1,0,1,0,1,0x21,0x21,
+1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,
+2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+1,1,1,1,2,2,0,2,2,2,2,0,0,2,2,2,
+2,2,2,2,2,0,2,2,2,2,2,2,2,0,1,1,
+1,1,1,1,1,1,0x21,0x21,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,2,2,0,2,2,2,2,0,
+2,2,2,2,2,0,2,0,0,0,2,2,2,2,2,2,
+2,0,1,1,1,1,1,1,1,1,0x21,0x21,1,1,1,1,
+1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,
+1,1,0,0,2,2,2,2,2,2,2,2,2,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,2,0,1,1,
 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-1,1,1,0,1,1,1,1,1,1,2,2,2,2,2,2,
+1,1,1,1,1,1,1,0,1,1,1,1,1,1,2,2,
 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
-2,2,2,0,1,1,1,1,1,1,1,1,1,1,1,1,
-1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,
-2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
-1,1,1,0,1,1,1,1,1,1,2,1,0,0,0,0,
+2,2,2,2,2,2,2,0,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,
+1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,
+2,2,2,2,1,1,1,0,1,1,1,1,1,1,2,1,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
-4,4,4,4,4,4,4,0,0,0,0,4,4,4,4,4,
-4,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,
-0,4,0,0,0,0,0,0,0,0,0,0,4,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,4,4,4,4,4,0,4,4,4,4,4,4,4,
-4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0,
+0,0,0,0,4,4,4,4,4,4,4,4,4,4,4,4,
+4,4,4,4,4,4,4,4,4,4,4,0,0,0,0,4,
+4,4,4,4,4,4,4,4,4,4,4,4,4,0,0,0,
+0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,
+4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,4,4,4,4,4,0,4,4,4,
+4,4,4,4,4,4,4,4,4,4,4,4,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0x44,0x44,0x44,0x44,
+0x44,0x44,0x44,0,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,
+0x44,0x44,0x44,0x44,0x44,0,0,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0,0x44,
+0x44,0,0x44,0x44,0x44,0x44,0x44,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0x44,0x44,0x44,0x44,
+0x44,0x44,0x44,4,4,4,4,4,4,4,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0x64,0x64,0x64,0x64,
+0x64,0x64,0x64,0,0,0,0,0,0,0,0,0,0x1112,0x1112,0x1112,0x1112,
+0x1112,0x1112,0x1112,0x1112,0x1112,0x1112,0x1112,0x1112,0x1112,0x1112,0x1112,0x1112,0x1112,0x1112,0x1112,0x1112,
+0x1112,0x1112,0x1112,0x1112,0x1112,0x1112,0x1112,0x1112,0x1112,0x1112,0x1112,0x1112,0x1112,0x1112,0xef11,0xef11,
+0xef11,0xef11,0xef11,0xef11,0xef11,0xef11,0xef11,0xef11,0xef11,0xef11,0xef11,0xef11,0xef11,0xef11,0xef11,0xef11,
+0xef11,0xef11,0xef11,0xef11,0xef11,0xef11,0xef11,0xef11,0xef11,0xef11,0xef11,0xef11,0x44,0x44,0x44,0x44,
+0x44,0x44,0x64,4,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,
 2,2,0,0,0,0,0,0,2,2,2,2,2,2,2,2,
 2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0
 };
 
-static const uint16_t ucase_props_exceptions[1847]={
-0xc041,0x69,2,0x130,0x131,0x4001,0x6a,0x41,0x6b,1,0x212a,0x41,0x73,1,0x17f,0x5044,
-0x49,2,0x130,0x131,0x44,0x4b,1,0x212a,0x44,0x53,1,0x17f,6,0x3bc,0x39c,0x41,
-0xe5,1,0x212b,0x4001,0xec,0x4001,0xed,0xc0,1,0x2220,0x73,0x73,0x53,0x53,0x53,0x73,
-0x1e9e,0x44,0xc5,1,0x212b,0x4001,0x129,0x4001,0x12f,0xc043,0x69,0x130,2,0x49,0x131,0x44,
-0x49,2,0x69,0x130,0x80,0x2220,0x2bc,0x6e,0x2bc,0x4e,0x2bc,0x4e,6,0x73,0x53,9,
-0x1c6,0x1c5,0xd,0x1c6,0x1c4,0x1c5,0xc,0x1c4,0x1c5,9,0x1c9,0x1c8,0xd,0x1c9,0x1c7,0x1c8,
-0xc,0x1c7,0x1c8,9,0x1cc,0x1cb,0xd,0x1cc,0x1ca,0x1cb,0xc,0x1ca,0x1cb,0x80,0x2220,0x6a,
-0x30c,0x4a,0x30c,0x4a,0x30c,9,0x1f3,0x1f2,0xd,0x1f3,0x1f1,0x1f2,0xc,0x1f1,0x1f2,1,
-0x2c65,1,0x2c66,4,0x2c7e,4,0x2c7f,4,0x2c6f,4,0x2c6d,4,0x2c70,4,0xa7ab,4,
-0xa7ac,4,0xa78d,4,0xa7aa,4,0x2c62,4,0xa7ad,4,0x2c6e,4,0x2c64,4,0xa7b1,0x1004,
-0xa7b2,4,0xa7b0,0x6000,0x3046,0x3b9,0x399,1,0x1fbe,0xc0,1,0x3330,0x3b9,0x308,0x301,0x399,
-0x308,0x301,0x399,0x308,0x301,0x1fd3,0x41,0x3b2,1,0x3d0,0x41,0x3b5,1,0x3f5,0x41,0x3b8,
-2,0x3d1,0x3f4,0x41,0x3b9,2,0x345,0x1fbe,0x41,0x3ba,1,0x3f0,0x41,0x3bc,1,0xb5,
-0x41,0x3c0,1,0x3d6,0x41,0x3c1,1,0x3f1,0x4041,0x3c3,1,0x3c2,0x41,0x3c6,1,0x3d5,
-0x41,0x3c9,1,0x2126,0xc0,1,0x3330,0x3c5,0x308,0x301,0x3a5,0x308,0x301,0x3a5,0x308,0x301,
-0x1fe3,0x44,0x392,1,0x3d0,0x44,0x395,1,0x3f5,0x44,0x398,2,0x3d1,0x3f4,0x44,0x399,
-2,0x345,0x1fbe,0x44,0x39a,1,0x3f0,0x44,0x39c,1,0xb5,0x44,0x3a0,1,0x3d6,0x44,
-0x3a1,1,0x3f1,6,0x3c3,0x3a3,0x44,0x3a3,1,0x3c2,0x44,0x3a6,1,0x3d5,0x44,0x3a9,
-1,0x2126,6,0x3b2,0x392,0x46,0x3b8,0x398,1,0x3f4,6,0x3c6,0x3a6,6,0x3c0,0x3a0,
-6,0x3ba,0x39a,6,0x3c1,0x3a1,0x41,0x3b8,2,0x398,0x3d1,6,0x3b5,0x395,0x80,0x2220,
-0x565,0x582,0x535,0x552,0x535,0x582,1,0x2d00,1,0x2d01,1,0x2d02,1,0x2d03,1,0x2d04,
-1,0x2d05,1,0x2d06,1,0x2d07,1,0x2d08,1,0x2d09,1,0x2d0a,1,0x2d0b,1,0x2d0c,
-1,0x2d0d,1,0x2d0e,1,0x2d0f,1,0x2d10,1,0x2d11,1,0x2d12,1,0x2d13,1,0x2d14,
-1,0x2d15,1,0x2d16,1,0x2d17,1,0x2d18,1,0x2d19,1,0x2d1a,1,0x2d1b,1,0x2d1c,
-1,0x2d1d,1,0x2d1e,1,0x2d1f,1,0x2d20,1,0x2d21,1,0x2d22,1,0x2d23,1,0x2d24,
-1,0x2d25,1,0x2d27,1,0x2d2d,3,0xab70,0x13a0,3,0xab71,0x13a1,3,0xab72,0x13a2,3,
-0xab73,0x13a3,3,0xab74,0x13a4,3,0xab75,0x13a5,3,0xab76,0x13a6,3,0xab77,0x13a7,3,0xab78,
-0x13a8,3,0xab79,0x13a9,3,0xab7a,0x13aa,3,0xab7b,0x13ab,3,0xab7c,0x13ac,3,0xab7d,0x13ad,
-3,0xab7e,0x13ae,3,0xab7f,0x13af,3,0xab80,0x13b0,3,0xab81,0x13b1,3,0xab82,0x13b2,3,
-0xab83,0x13b3,3,0xab84,0x13b4,3,0xab85,0x13b5,3,0xab86,0x13b6,3,0xab87,0x13b7,3,0xab88,
-0x13b8,3,0xab89,0x13b9,3,0xab8a,0x13ba,3,0xab8b,0x13bb,3,0xab8c,0x13bc,3,0xab8d,0x13bd,
-3,0xab8e,0x13be,3,0xab8f,0x13bf,3,0xab90,0x13c0,3,0xab91,0x13c1,3,0xab92,0x13c2,3,
-0xab93,0x13c3,3,0xab94,0x13c4,3,0xab95,0x13c5,3,0xab96,0x13c6,3,0xab97,0x13c7,3,0xab98,
-0x13c8,3,0xab99,0x13c9,3,0xab9a,0x13ca,3,0xab9b,0x13cb,3,0xab9c,0x13cc,3,0xab9d,0x13cd,
-3,0xab9e,0x13ce,3,0xab9f,0x13cf,3,0xaba0,0x13d0,3,0xaba1,0x13d1,3,0xaba2,0x13d2,3,
-0xaba3,0x13d3,3,0xaba4,0x13d4,3,0xaba5,0x13d5,3,0xaba6,0x13d6,3,0xaba7,0x13d7,3,0xaba8,
-0x13d8,3,0xaba9,0x13d9,3,0xabaa,0x13da,3,0xabab,0x13db,3,0xabac,0x13dc,3,0xabad,0x13dd,
-3,0xabae,0x13de,3,0xabaf,0x13df,3,0xabb0,0x13e0,3,0xabb1,0x13e1,3,0xabb2,0x13e2,3,
-0xabb3,0x13e3,3,0xabb4,0x13e4,3,0xabb5,0x13e5,3,0xabb6,0x13e6,3,0xabb7,0x13e7,3,0xabb8,
-0x13e8,3,0xabb9,0x13e9,3,0xabba,0x13ea,3,0xabbb,0x13eb,3,0xabbc,0x13ec,3,0xabbd,0x13ed,
-3,0xabbe,0x13ee,3,0xabbf,0x13ef,3,0x13f8,0x13f0,3,0x13f9,0x13f1,3,0x13fa,0x13f2,3,
-0x13fb,0x13f3,3,0x13fc,0x13f4,3,0x13fd,0x13f5,6,0x13f0,0x13f0,6,0x13f1,0x13f1,6,0x13f2,
-0x13f2,6,0x13f3,0x13f3,6,0x13f4,0x13f4,6,0x13f5,0x13f5,4,0xa77d,4,0x2c63,0x41,0x1e61,
-1,0x1e9b,0x44,0x1e60,1,0x1e9b,0x80,0x2220,0x68,0x331,0x48,0x331,0x48,0x331,0x80,0x2220,
-0x74,0x308,0x54,0x308,0x54,0x308,0x80,0x2220,0x77,0x30a,0x57,0x30a,0x57,0x30a,0x80,0x2220,
-0x79,0x30a,0x59,0x30a,0x59,0x30a,0x80,0x2220,0x61,0x2be,0x41,0x2be,0x41,0x2be,6,0x1e61,
-0x1e60,0x81,0xdf,0x20,0x73,0x73,0x80,0x2220,0x3c5,0x313,0x3a5,0x313,0x3a5,0x313,0x80,0x3330,
-0x3c5,0x313,0x300,0x3a5,0x313,0x300,0x3a5,0x313,0x300,0x80,0x3330,0x3c5,0x313,0x301,0x3a5,0x313,
-0x301,0x3a5,0x313,0x301,0x80,0x3330,0x3c5,0x313,0x342,0x3a5,0x313,0x342,0x3a5,0x313,0x342,0x84,
-0x1f88,0x220,0x1f00,0x3b9,0x1f08,0x399,0x84,0x1f89,0x220,0x1f01,0x3b9,0x1f09,0x399,0x84,0x1f8a,0x220,
-0x1f02,0x3b9,0x1f0a,0x399,0x84,0x1f8b,0x220,0x1f03,0x3b9,0x1f0b,0x399,0x84,0x1f8c,0x220,0x1f04,0x3b9,
-0x1f0c,0x399,0x84,0x1f8d,0x220,0x1f05,0x3b9,0x1f0d,0x399,0x84,0x1f8e,0x220,0x1f06,0x3b9,0x1f0e,0x399,
-0x84,0x1f8f,0x220,0x1f07,0x3b9,0x1f0f,0x399,0x81,0x1f80,0x220,0x1f00,0x3b9,0x1f08,0x399,0x81,0x1f81,
-0x220,0x1f01,0x3b9,0x1f09,0x399,0x81,0x1f82,0x220,0x1f02,0x3b9,0x1f0a,0x399,0x81,0x1f83,0x220,0x1f03,
-0x3b9,0x1f0b,0x399,0x81,0x1f84,0x220,0x1f04,0x3b9,0x1f0c,0x399,0x81,0x1f85,0x220,0x1f05,0x3b9,0x1f0d,
-0x399,0x81,0x1f86,0x220,0x1f06,0x3b9,0x1f0e,0x399,0x81,0x1f87,0x220,0x1f07,0x3b9,0x1f0f,0x399,0x84,
-0x1f98,0x220,0x1f20,0x3b9,0x1f28,0x399,0x84,0x1f99,0x220,0x1f21,0x3b9,0x1f29,0x399,0x84,0x1f9a,0x220,
-0x1f22,0x3b9,0x1f2a,0x399,0x84,0x1f9b,0x220,0x1f23,0x3b9,0x1f2b,0x399,0x84,0x1f9c,0x220,0x1f24,0x3b9,
-0x1f2c,0x399,0x84,0x1f9d,0x220,0x1f25,0x3b9,0x1f2d,0x399,0x84,0x1f9e,0x220,0x1f26,0x3b9,0x1f2e,0x399,
-0x84,0x1f9f,0x220,0x1f27,0x3b9,0x1f2f,0x399,0x81,0x1f90,0x220,0x1f20,0x3b9,0x1f28,0x399,0x81,0x1f91,
-0x220,0x1f21,0x3b9,0x1f29,0x399,0x81,0x1f92,0x220,0x1f22,0x3b9,0x1f2a,0x399,0x81,0x1f93,0x220,0x1f23,
-0x3b9,0x1f2b,0x399,0x81,0x1f94,0x220,0x1f24,0x3b9,0x1f2c,0x399,0x81,0x1f95,0x220,0x1f25,0x3b9,0x1f2d,
-0x399,0x81,0x1f96,0x220,0x1f26,0x3b9,0x1f2e,0x399,0x81,0x1f97,0x220,0x1f27,0x3b9,0x1f2f,0x399,0x84,
-0x1fa8,0x220,0x1f60,0x3b9,0x1f68,0x399,0x84,0x1fa9,0x220,0x1f61,0x3b9,0x1f69,0x399,0x84,0x1faa,0x220,
-0x1f62,0x3b9,0x1f6a,0x399,0x84,0x1fab,0x220,0x1f63,0x3b9,0x1f6b,0x399,0x84,0x1fac,0x220,0x1f64,0x3b9,
-0x1f6c,0x399,0x84,0x1fad,0x220,0x1f65,0x3b9,0x1f6d,0x399,0x84,0x1fae,0x220,0x1f66,0x3b9,0x1f6e,0x399,
-0x84,0x1faf,0x220,0x1f67,0x3b9,0x1f6f,0x399,0x81,0x1fa0,0x220,0x1f60,0x3b9,0x1f68,0x399,0x81,0x1fa1,
-0x220,0x1f61,0x3b9,0x1f69,0x399,0x81,0x1fa2,0x220,0x1f62,0x3b9,0x1f6a,0x399,0x81,0x1fa3,0x220,0x1f63,
-0x3b9,0x1f6b,0x399,0x81,0x1fa4,0x220,0x1f64,0x3b9,0x1f6c,0x399,0x81,0x1fa5,0x220,0x1f65,0x3b9,0x1f6d,
-0x399,0x81,0x1fa6,0x220,0x1f66,0x3b9,0x1f6e,0x399,0x81,0x1fa7,0x220,0x1f67,0x3b9,0x1f6f,0x399,0x80,
-0x2220,0x1f70,0x3b9,0x1fba,0x399,0x1fba,0x345,0x84,0x1fbc,0x220,0x3b1,0x3b9,0x391,0x399,0x80,0x2220,
-0x3ac,0x3b9,0x386,0x399,0x386,0x345,0x80,0x2220,0x3b1,0x342,0x391,0x342,0x391,0x342,0x80,0x3330,
-0x3b1,0x342,0x3b9,0x391,0x342,0x399,0x391,0x342,0x345,0x81,0x1fb3,0x220,0x3b1,0x3b9,0x391,0x399,
-0x46,0x3b9,0x399,1,0x345,0x80,0x2220,0x1f74,0x3b9,0x1fca,0x399,0x1fca,0x345,0x84,0x1fcc,0x220,
-0x3b7,0x3b9,0x397,0x399,0x80,0x2220,0x3ae,0x3b9,0x389,0x399,0x389,0x345,0x80,0x2220,0x3b7,0x342,
-0x397,0x342,0x397,0x342,0x80,0x3330,0x3b7,0x342,0x3b9,0x397,0x342,0x399,0x397,0x342,0x345,0x81,
-0x1fc3,0x220,0x3b7,0x3b9,0x397,0x399,0x80,0x3330,0x3b9,0x308,0x300,0x399,0x308,0x300,0x399,0x308,
-0x300,0xc0,1,0x3330,0x3b9,0x308,0x301,0x399,0x308,0x301,0x399,0x308,0x301,0x390,0x80,0x2220,
-0x3b9,0x342,0x399,0x342,0x399,0x342,0x80,0x3330,0x3b9,0x308,0x342,0x399,0x308,0x342,0x399,0x308,
-0x342,0x80,0x3330,0x3c5,0x308,0x300,0x3a5,0x308,0x300,0x3a5,0x308,0x300,0xc0,1,0x3330,0x3c5,
-0x308,0x301,0x3a5,0x308,0x301,0x3a5,0x308,0x301,0x3b0,0x80,0x2220,0x3c1,0x313,0x3a1,0x313,0x3a1,
-0x313,0x80,0x2220,0x3c5,0x342,0x3a5,0x342,0x3a5,0x342,0x80,0x3330,0x3c5,0x308,0x342,0x3a5,0x308,
-0x342,0x3a5,0x308,0x342,0x80,0x2220,0x1f7c,0x3b9,0x1ffa,0x399,0x1ffa,0x345,0x84,0x1ffc,0x220,0x3c9,
-0x3b9,0x3a9,0x399,0x80,0x2220,0x3ce,0x3b9,0x38f,0x399,0x38f,0x345,0x80,0x2220,0x3c9,0x342,0x3a9,
-0x342,0x3a9,0x342,0x80,0x3330,0x3c9,0x342,0x3b9,0x3a9,0x342,0x399,0x3a9,0x342,0x345,0x81,0x1ff3,
-0x220,0x3c9,0x3b9,0x3a9,0x399,0x41,0x3c9,1,0x3a9,0x41,0x6b,1,0x4b,0x41,0xe5,1,
-0xc5,1,0x26b,1,0x1d7d,1,0x27d,4,0x23a,4,0x23e,1,0x251,1,0x271,1,
-0x250,1,0x252,1,0x23f,1,0x240,4,0x10a0,4,0x10a1,4,0x10a2,4,0x10a3,4,
-0x10a4,4,0x10a5,4,0x10a6,4,0x10a7,4,0x10a8,4,0x10a9,4,0x10aa,4,0x10ab,4,
-0x10ac,4,0x10ad,4,0x10ae,4,0x10af,4,0x10b0,4,0x10b1,4,0x10b2,4,0x10b3,4,
-0x10b4,4,0x10b5,4,0x10b6,4,0x10b7,4,0x10b8,4,0x10b9,4,0x10ba,4,0x10bb,4,
-0x10bc,4,0x10bd,4,0x10be,4,0x10bf,4,0x10c0,4,0x10c1,4,0x10c2,4,0x10c3,4,
-0x10c4,4,0x10c5,4,0x10c7,4,0x10cd,1,0x1d79,1,0x265,1,0x266,1,0x25c,1,
-0x261,1,0x26c,1,0x29e,1,0x287,1,0x29d,1,0xab53,4,0xa7b3,6,0x13a0,0x13a0,
-6,0x13a1,0x13a1,6,0x13a2,0x13a2,6,0x13a3,0x13a3,6,0x13a4,0x13a4,6,0x13a5,0x13a5,6,
-0x13a6,0x13a6,6,0x13a7,0x13a7,6,0x13a8,0x13a8,6,0x13a9,0x13a9,6,0x13aa,0x13aa,6,0x13ab,
-0x13ab,6,0x13ac,0x13ac,6,0x13ad,0x13ad,6,0x13ae,0x13ae,6,0x13af,0x13af,6,0x13b0,0x13b0,
-6,0x13b1,0x13b1,6,0x13b2,0x13b2,6,0x13b3,0x13b3,6,0x13b4,0x13b4,6,0x13b5,0x13b5,6,
-0x13b6,0x13b6,6,0x13b7,0x13b7,6,0x13b8,0x13b8,6,0x13b9,0x13b9,6,0x13ba,0x13ba,6,0x13bb,
-0x13bb,6,0x13bc,0x13bc,6,0x13bd,0x13bd,6,0x13be,0x13be,6,0x13bf,0x13bf,6,0x13c0,0x13c0,
-6,0x13c1,0x13c1,6,0x13c2,0x13c2,6,0x13c3,0x13c3,6,0x13c4,0x13c4,6,0x13c5,0x13c5,6,
-0x13c6,0x13c6,6,0x13c7,0x13c7,6,0x13c8,0x13c8,6,0x13c9,0x13c9,6,0x13ca,0x13ca,6,0x13cb,
-0x13cb,6,0x13cc,0x13cc,6,0x13cd,0x13cd,6,0x13ce,0x13ce,6,0x13cf,0x13cf,6,0x13d0,0x13d0,
-6,0x13d1,0x13d1,6,0x13d2,0x13d2,6,0x13d3,0x13d3,6,0x13d4,0x13d4,6,0x13d5,0x13d5,6,
-0x13d6,0x13d6,6,0x13d7,0x13d7,6,0x13d8,0x13d8,6,0x13d9,0x13d9,6,0x13da,0x13da,6,0x13db,
-0x13db,6,0x13dc,0x13dc,6,0x13dd,0x13dd,6,0x13de,0x13de,6,0x13df,0x13df,6,0x13e0,0x13e0,
-6,0x13e1,0x13e1,6,0x13e2,0x13e2,6,0x13e3,0x13e3,6,0x13e4,0x13e4,6,0x13e5,0x13e5,6,
-0x13e6,0x13e6,6,0x13e7,0x13e7,6,0x13e8,0x13e8,6,0x13e9,0x13e9,6,0x13ea,0x13ea,6,0x13eb,
-0x13eb,6,0x13ec,0x13ec,6,0x13ed,0x13ed,6,0x13ee,0x13ee,6,0x13ef,0x13ef,0x80,0x2220,0x66,
-0x66,0x46,0x46,0x46,0x66,0x80,0x2220,0x66,0x69,0x46,0x49,0x46,0x69,0x80,0x2220,0x66,
-0x6c,0x46,0x4c,0x46,0x6c,0x80,0x3330,0x66,0x66,0x69,0x46,0x46,0x49,0x46,0x66,0x69,
-0x80,0x3330,0x66,0x66,0x6c,0x46,0x46,0x4c,0x46,0x66,0x6c,0xc0,1,0x2220,0x73,0x74,
-0x53,0x54,0x53,0x74,0xfb06,0xc0,1,0x2220,0x73,0x74,0x53,0x54,0x53,0x74,0xfb05,0x80,
-0x2220,0x574,0x576,0x544,0x546,0x544,0x576,0x80,0x2220,0x574,0x565,0x544,0x535,0x544,0x565,0x80,
-0x2220,0x574,0x56b,0x544,0x53b,0x544,0x56b,0x80,0x2220,0x57e,0x576,0x54e,0x546,0x54e,0x576,0x80,
-0x2220,0x574,0x56d,0x544,0x53d,0x544,0x56d
+static const uint16_t ucase_props_exceptions[1667]={
+0xc850,0x20,2,0x130,0x131,0x4810,0x20,0x841,0x6b,1,0x212a,0x841,0x73,1,0x17f,0x5c50,
+0x20,2,0x130,0x131,0x844,0x4b,1,0x212a,0x844,0x53,1,0x17f,0x806,0x3bc,0x39c,0x841,
+0xe5,1,0x212b,0x8c0,1,0x2220,0x73,0x73,0x53,0x53,0x53,0x73,0x1e9e,0x844,0xc5,1,
+0x212b,0x4810,1,0xce50,0xc7,2,0x49,0x131,0x844,0x49,2,0x69,0x130,0x880,0x2220,0x2bc,
+0x6e,0x2bc,0x4e,0x2bc,0x4e,0x806,0x73,0x53,0x809,0x1c6,0x1c5,0x80d,0x1c6,0x1c4,0x1c5,0x80c,
+0x1c4,0x1c5,0x809,0x1c9,0x1c8,0x80d,0x1c9,0x1c7,0x1c8,0x80c,0x1c7,0x1c8,0x809,0x1cc,0x1cb,0x80d,
+0x1cc,0x1ca,0x1cb,0x80c,0x1ca,0x1cb,0x880,0x2220,0x6a,0x30c,0x4a,0x30c,0x4a,0x30c,0x809,0x1f3,
+0x1f2,0x80d,0x1f3,0x1f1,0x1f2,0x80c,0x1f1,0x1f2,0x810,0x2a2b,0x810,0x2a28,0x810,0x2a3f,0x810,0x2a1f,
+0x810,0x2a1c,0x810,0x2a1e,0x810,0xa54f,0x810,0xa54b,0x810,0xa528,0x810,0xa544,0x810,0x29f7,0x810,0xa541,
+0x810,0x29fd,0x810,0x29e7,0x810,0xa543,0x810,0xa52a,0x1810,0xa515,0x810,0xa512,0x6800,0x3846,0x3b9,0x399,
+1,0x1fbe,0x8c0,1,0x3330,0x3b9,0x308,0x301,0x399,0x308,0x301,0x399,0x308,0x301,0x1fd3,0x841,
+0x3b2,1,0x3d0,0x841,0x3b5,1,0x3f5,0x841,0x3b8,2,0x3d1,0x3f4,0x841,0x3b9,2,0x345,
+0x1fbe,0x841,0x3ba,1,0x3f0,0x841,0x3bc,1,0xb5,0x841,0x3c0,1,0x3d6,0x841,0x3c1,1,
+0x3f1,0x4850,0x20,1,0x3c2,0x841,0x3c6,1,0x3d5,0x841,0x3c9,1,0x2126,0x8c0,1,0x3330,
+0x3c5,0x308,0x301,0x3a5,0x308,0x301,0x3a5,0x308,0x301,0x1fe3,0x844,0x392,1,0x3d0,0x844,0x395,
+1,0x3f5,0x844,0x398,2,0x3d1,0x3f4,0x844,0x399,2,0x345,0x1fbe,0x844,0x39a,1,0x3f0,
+0x844,0x39c,1,0xb5,0x844,0x3a0,1,0x3d6,0x844,0x3a1,1,0x3f1,0x806,0x3c3,0x3a3,0x844,
+0x3a3,1,0x3c2,0x844,0x3a6,1,0x3d5,0x844,0x3a9,1,0x2126,0x806,0x3b2,0x392,0x846,0x3b8,
+0x398,1,0x3f4,0x806,0x3c6,0x3a6,0x806,0x3c0,0x3a0,0x806,0x3ba,0x39a,0x806,0x3c1,0x3a1,0x841,
+0x3b8,2,0x398,0x3d1,0x806,0x3b5,0x395,0x841,0x432,1,0x1c80,0x841,0x434,1,0x1c81,0x841,
+0x43e,1,0x1c82,0x841,0x441,1,0x1c83,0x841,0x442,2,0x1c84,0x1c85,0x841,0x44a,1,0x1c86,
+0x844,0x412,1,0x1c80,0x844,0x414,1,0x1c81,0x844,0x41e,1,0x1c82,0x844,0x421,1,0x1c83,
+0x844,0x422,2,0x1c84,0x1c85,0x844,0x42a,1,0x1c86,0x841,0x463,1,0x1c87,0x844,0x462,1,
+0x1c87,0x4880,0x20,0x565,0x582,0x810,0x1c60,0x80c,0x1c90,0x10d0,0x80c,0x1c91,0x10d1,0x80c,0x1c92,0x10d2,
+0x80c,0x1c93,0x10d3,0x80c,0x1c94,0x10d4,0x80c,0x1c95,0x10d5,0x80c,0x1c96,0x10d6,0x80c,0x1c97,0x10d7,0x80c,
+0x1c98,0x10d8,0x80c,0x1c99,0x10d9,0x80c,0x1c9a,0x10da,0x80c,0x1c9b,0x10db,0x80c,0x1c9c,0x10dc,0x80c,0x1c9d,
+0x10dd,0x80c,0x1c9e,0x10de,0x80c,0x1c9f,0x10df,0x80c,0x1ca0,0x10e0,0x80c,0x1ca1,0x10e1,0x80c,0x1ca2,0x10e2,
+0x80c,0x1ca3,0x10e3,0x80c,0x1ca4,0x10e4,0x80c,0x1ca5,0x10e5,0x80c,0x1ca6,0x10e6,0x80c,0x1ca7,0x10e7,0x80c,
+0x1ca8,0x10e8,0x80c,0x1ca9,0x10e9,0x80c,0x1caa,0x10ea,0x80c,0x1cab,0x10eb,0x80c,0x1cac,0x10ec,0x80c,0x1cad,
+0x10ed,0x80c,0x1cae,0x10ee,0x80c,0x1caf,0x10ef,0x80c,0x1cb0,0x10f0,0x80c,0x1cb1,0x10f1,0x80c,0x1cb2,0x10f2,
+0x80c,0x1cb3,0x10f3,0x80c,0x1cb4,0x10f4,0x80c,0x1cb5,0x10f5,0x80c,0x1cb6,0x10f6,0x80c,0x1cb7,0x10f7,0x80c,
+0x1cb8,0x10f8,0x80c,0x1cb9,0x10f9,0x80c,0x1cba,0x10fa,0x80c,0x1cbd,0x10fd,0x80c,0x1cbe,0x10fe,0x80c,0x1cbf,
+0x10ff,0xa10,0x97d0,0xa10,8,0x806,0x13f0,0x13f0,0x806,0x13f1,0x13f1,0x806,0x13f2,0x13f2,0x806,0x13f3,
+0x13f3,0x806,0x13f4,0x13f4,0x806,0x13f5,0x13f5,0x806,0x432,0x412,0x806,0x434,0x414,0x806,0x43e,0x41e,
+0x806,0x441,0x421,0x846,0x442,0x422,1,0x1c85,0x846,0x442,0x422,1,0x1c84,0x806,0x44a,0x42a,
+0x806,0x463,0x462,0x806,0xa64b,0xa64a,0xc10,0xbc0,0x810,0x8a04,0x810,0xee6,0x810,0x8a38,0x841,0x1e61,
+1,0x1e9b,0x844,0x1e60,1,0x1e9b,0x880,0x2220,0x68,0x331,0x48,0x331,0x48,0x331,0x880,0x2220,
+0x74,0x308,0x54,0x308,0x54,0x308,0x880,0x2220,0x77,0x30a,0x57,0x30a,0x57,0x30a,0x880,0x2220,
+0x79,0x30a,0x59,0x30a,0x59,0x30a,0x880,0x2220,0x61,0x2be,0x41,0x2be,0x41,0x2be,0x806,0x1e61,
+0x1e60,0xc90,0x1dbf,0x20,0x73,0x73,0x880,0x2220,0x3c5,0x313,0x3a5,0x313,0x3a5,0x313,0x880,0x3330,
+0x3c5,0x313,0x300,0x3a5,0x313,0x300,0x3a5,0x313,0x300,0x880,0x3330,0x3c5,0x313,0x301,0x3a5,0x313,
+0x301,0x3a5,0x313,0x301,0x880,0x3330,0x3c5,0x313,0x342,0x3a5,0x313,0x342,0x3a5,0x313,0x342,0x890,
+8,0x220,0x1f00,0x3b9,0x1f08,0x399,0x890,8,0x220,0x1f01,0x3b9,0x1f09,0x399,0x890,8,0x220,
+0x1f02,0x3b9,0x1f0a,0x399,0x890,8,0x220,0x1f03,0x3b9,0x1f0b,0x399,0x890,8,0x220,0x1f04,0x3b9,
+0x1f0c,0x399,0x890,8,0x220,0x1f05,0x3b9,0x1f0d,0x399,0x890,8,0x220,0x1f06,0x3b9,0x1f0e,0x399,
+0x890,8,0x220,0x1f07,0x3b9,0x1f0f,0x399,0xc90,8,0x220,0x1f00,0x3b9,0x1f08,0x399,0xc90,8,
+0x220,0x1f01,0x3b9,0x1f09,0x399,0xc90,8,0x220,0x1f02,0x3b9,0x1f0a,0x399,0xc90,8,0x220,0x1f03,
+0x3b9,0x1f0b,0x399,0xc90,8,0x220,0x1f04,0x3b9,0x1f0c,0x399,0xc90,8,0x220,0x1f05,0x3b9,0x1f0d,
+0x399,0xc90,8,0x220,0x1f06,0x3b9,0x1f0e,0x399,0xc90,8,0x220,0x1f07,0x3b9,0x1f0f,0x399,0x890,
+8,0x220,0x1f20,0x3b9,0x1f28,0x399,0x890,8,0x220,0x1f21,0x3b9,0x1f29,0x399,0x890,8,0x220,
+0x1f22,0x3b9,0x1f2a,0x399,0x890,8,0x220,0x1f23,0x3b9,0x1f2b,0x399,0x890,8,0x220,0x1f24,0x3b9,
+0x1f2c,0x399,0x890,8,0x220,0x1f25,0x3b9,0x1f2d,0x399,0x890,8,0x220,0x1f26,0x3b9,0x1f2e,0x399,
+0x890,8,0x220,0x1f27,0x3b9,0x1f2f,0x399,0xc90,8,0x220,0x1f20,0x3b9,0x1f28,0x399,0xc90,8,
+0x220,0x1f21,0x3b9,0x1f29,0x399,0xc90,8,0x220,0x1f22,0x3b9,0x1f2a,0x399,0xc90,8,0x220,0x1f23,
+0x3b9,0x1f2b,0x399,0xc90,8,0x220,0x1f24,0x3b9,0x1f2c,0x399,0xc90,8,0x220,0x1f25,0x3b9,0x1f2d,
+0x399,0xc90,8,0x220,0x1f26,0x3b9,0x1f2e,0x399,0xc90,8,0x220,0x1f27,0x3b9,0x1f2f,0x399,0x890,
+8,0x220,0x1f60,0x3b9,0x1f68,0x399,0x890,8,0x220,0x1f61,0x3b9,0x1f69,0x399,0x890,8,0x220,
+0x1f62,0x3b9,0x1f6a,0x399,0x890,8,0x220,0x1f63,0x3b9,0x1f6b,0x399,0x890,8,0x220,0x1f64,0x3b9,
+0x1f6c,0x399,0x890,8,0x220,0x1f65,0x3b9,0x1f6d,0x399,0x890,8,0x220,0x1f66,0x3b9,0x1f6e,0x399,
+0x890,8,0x220,0x1f67,0x3b9,0x1f6f,0x399,0xc90,8,0x220,0x1f60,0x3b9,0x1f68,0x399,0xc90,8,
+0x220,0x1f61,0x3b9,0x1f69,0x399,0xc90,8,0x220,0x1f62,0x3b9,0x1f6a,0x399,0xc90,8,0x220,0x1f63,
+0x3b9,0x1f6b,0x399,0xc90,8,0x220,0x1f64,0x3b9,0x1f6c,0x399,0xc90,8,0x220,0x1f65,0x3b9,0x1f6d,
+0x399,0xc90,8,0x220,0x1f66,0x3b9,0x1f6e,0x399,0xc90,8,0x220,0x1f67,0x3b9,0x1f6f,0x399,0x880,
+0x2220,0x1f70,0x3b9,0x1fba,0x399,0x1fba,0x345,0x890,9,0x220,0x3b1,0x3b9,0x391,0x399,0x880,0x2220,
+0x3ac,0x3b9,0x386,0x399,0x386,0x345,0x880,0x2220,0x3b1,0x342,0x391,0x342,0x391,0x342,0x880,0x3330,
+0x3b1,0x342,0x3b9,0x391,0x342,0x399,0x391,0x342,0x345,0xc90,9,0x220,0x3b1,0x3b9,0x391,0x399,
+0x846,0x3b9,0x399,1,0x345,0x880,0x2220,0x1f74,0x3b9,0x1fca,0x399,0x1fca,0x345,0x890,9,0x220,
+0x3b7,0x3b9,0x397,0x399,0x880,0x2220,0x3ae,0x3b9,0x389,0x399,0x389,0x345,0x880,0x2220,0x3b7,0x342,
+0x397,0x342,0x397,0x342,0x880,0x3330,0x3b7,0x342,0x3b9,0x397,0x342,0x399,0x397,0x342,0x345,0xc90,
+9,0x220,0x3b7,0x3b9,0x397,0x399,0x880,0x3330,0x3b9,0x308,0x300,0x399,0x308,0x300,0x399,0x308,
+0x300,0x8c0,1,0x3330,0x3b9,0x308,0x301,0x399,0x308,0x301,0x399,0x308,0x301,0x390,0x880,0x2220,
+0x3b9,0x342,0x399,0x342,0x399,0x342,0x880,0x3330,0x3b9,0x308,0x342,0x399,0x308,0x342,0x399,0x308,
+0x342,0x880,0x3330,0x3c5,0x308,0x300,0x3a5,0x308,0x300,0x3a5,0x308,0x300,0x8c0,1,0x3330,0x3c5,
+0x308,0x301,0x3a5,0x308,0x301,0x3a5,0x308,0x301,0x3b0,0x880,0x2220,0x3c1,0x313,0x3a1,0x313,0x3a1,
+0x313,0x880,0x2220,0x3c5,0x342,0x3a5,0x342,0x3a5,0x342,0x880,0x3330,0x3c5,0x308,0x342,0x3a5,0x308,
+0x342,0x3a5,0x308,0x342,0x880,0x2220,0x1f7c,0x3b9,0x1ffa,0x399,0x1ffa,0x345,0x890,9,0x220,0x3c9,
+0x3b9,0x3a9,0x399,0x880,0x2220,0x3ce,0x3b9,0x38f,0x399,0x38f,0x345,0x880,0x2220,0x3c9,0x342,0x3a9,
+0x342,0x3a9,0x342,0x880,0x3330,0x3c9,0x342,0x3b9,0x3a9,0x342,0x399,0x3a9,0x342,0x345,0xc90,9,
+0x220,0x3c9,0x3b9,0x3a9,0x399,0xc50,0x1d5d,1,0x3a9,0xc50,0x20bf,1,0x4b,0xc50,0x2046,1,
+0xc5,0xc10,0x29f7,0xc10,0xee6,0xc10,0x29e7,0xc10,0x2a2b,0xc10,0x2a28,0xc10,0x2a1c,0xc10,0x29fd,0xc10,
+0x2a1f,0xc10,0x2a1e,0xc10,0x2a3f,0xc10,0x1c60,0x841,0xa64b,1,0x1c88,0x844,0xa64a,1,0x1c88,0xc10,
+0x8a04,0xc10,0xa528,0xc10,0xa544,0xc10,0xa54f,0xc10,0xa54b,0xc10,0xa541,0xc10,0xa512,0xc10,0xa52a,0xc10,
+0xa515,0x810,0x3a0,0xc10,0xa543,0xc10,0x8a38,0xc10,0x3a0,0x806,0x13a0,0x13a0,0x806,0x13a1,0x13a1,0x806,
+0x13a2,0x13a2,0x806,0x13a3,0x13a3,0x806,0x13a4,0x13a4,0x806,0x13a5,0x13a5,0x806,0x13a6,0x13a6,0x806,0x13a7,
+0x13a7,0x806,0x13a8,0x13a8,0x806,0x13a9,0x13a9,0x806,0x13aa,0x13aa,0x806,0x13ab,0x13ab,0x806,0x13ac,0x13ac,
+0x806,0x13ad,0x13ad,0x806,0x13ae,0x13ae,0x806,0x13af,0x13af,0x806,0x13b0,0x13b0,0x806,0x13b1,0x13b1,0x806,
+0x13b2,0x13b2,0x806,0x13b3,0x13b3,0x806,0x13b4,0x13b4,0x806,0x13b5,0x13b5,0x806,0x13b6,0x13b6,0x806,0x13b7,
+0x13b7,0x806,0x13b8,0x13b8,0x806,0x13b9,0x13b9,0x806,0x13ba,0x13ba,0x806,0x13bb,0x13bb,0x806,0x13bc,0x13bc,
+0x806,0x13bd,0x13bd,0x806,0x13be,0x13be,0x806,0x13bf,0x13bf,0x806,0x13c0,0x13c0,0x806,0x13c1,0x13c1,0x806,
+0x13c2,0x13c2,0x806,0x13c3,0x13c3,0x806,0x13c4,0x13c4,0x806,0x13c5,0x13c5,0x806,0x13c6,0x13c6,0x806,0x13c7,
+0x13c7,0x806,0x13c8,0x13c8,0x806,0x13c9,0x13c9,0x806,0x13ca,0x13ca,0x806,0x13cb,0x13cb,0x806,0x13cc,0x13cc,
+0x806,0x13cd,0x13cd,0x806,0x13ce,0x13ce,0x806,0x13cf,0x13cf,0x806,0x13d0,0x13d0,0x806,0x13d1,0x13d1,0x806,
+0x13d2,0x13d2,0x806,0x13d3,0x13d3,0x806,0x13d4,0x13d4,0x806,0x13d5,0x13d5,0x806,0x13d6,0x13d6,0x806,0x13d7,
+0x13d7,0x806,0x13d8,0x13d8,0x806,0x13d9,0x13d9,0x806,0x13da,0x13da,0x806,0x13db,0x13db,0x806,0x13dc,0x13dc,
+0x806,0x13dd,0x13dd,0x806,0x13de,0x13de,0x806,0x13df,0x13df,0x806,0x13e0,0x13e0,0x806,0x13e1,0x13e1,0x806,
+0x13e2,0x13e2,0x806,0x13e3,0x13e3,0x806,0x13e4,0x13e4,0x806,0x13e5,0x13e5,0x806,0x13e6,0x13e6,0x806,0x13e7,
+0x13e7,0x806,0x13e8,0x13e8,0x806,0x13e9,0x13e9,0x806,0x13ea,0x13ea,0x806,0x13eb,0x13eb,0x806,0x13ec,0x13ec,
+0x806,0x13ed,0x13ed,0x806,0x13ee,0x13ee,0x806,0x13ef,0x13ef,0x880,0x2220,0x66,0x66,0x46,0x46,0x46,
+0x66,0x880,0x2220,0x66,0x69,0x46,0x49,0x46,0x69,0x880,0x2220,0x66,0x6c,0x46,0x4c,0x46,
+0x6c,0x880,0x3330,0x66,0x66,0x69,0x46,0x46,0x49,0x46,0x66,0x69,0x880,0x3330,0x66,0x66,
+0x6c,0x46,0x46,0x4c,0x46,0x66,0x6c,0x8c0,1,0x2220,0x73,0x74,0x53,0x54,0x53,0x74,
+0xfb06,0x8c0,1,0x2220,0x73,0x74,0x53,0x54,0x53,0x74,0xfb05,0x880,0x2220,0x574,0x576,0x544,
+0x546,0x544,0x576,0x880,0x2220,0x574,0x565,0x544,0x535,0x544,0x565,0x880,0x2220,0x574,0x56b,0x544,
+0x53b,0x544,0x56b,0x880,0x2220,0x57e,0x576,0x54e,0x546,0x54e,0x576,0x880,0x2220,0x574,0x56d,0x544,
+0x53d,0x544,0x56d
 };
 
 static const uint16_t ucase_props_unfold[370]={
@@ -862,17 +933,19 @@
   ucase_props_unfold,
   {
     ucase_props_trieIndex,
-    ucase_props_trieIndex+3160,
+    ucase_props_trieIndex+3288,
     NULL,
-    3160,
-    7884,
+    3288,
+    9068,
     0x188,
-    0xcd4,
+    0xd54,
     0x0,
     0x0,
     0xe0800,
-    0x2b20,
+    0x3040,
     NULL, 0, FALSE, FALSE, 0, NULL
   },
-  { 3,0,0,0 }
+  { 4,0,0,0 }
 };
+
+#endif  // INCLUDED_FROM_UCASE_CPP
diff --git a/src/third_party/icu/source/common/ucasemap.cpp b/src/third_party/icu/source/common/ucasemap.cpp
index 48fd558..80c7ca4 100644
--- a/src/third_party/icu/source/common/ucasemap.cpp
+++ b/src/third_party/icu/source/common/ucasemap.cpp
@@ -1,12 +1,14 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
-*   Copyright (C) 2005-2011, International Business Machines
+*   Copyright (C) 2005-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *
 *******************************************************************************
 *   file name:  ucasemap.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -16,9 +18,16 @@
 *   Case mapping service object and functions using it.
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/utypes.h"
 #include "unicode/brkiter.h"
+#include "unicode/bytestream.h"
+#include "unicode/casemap.h"
+#include "unicode/edits.h"
+#include "unicode/stringoptions.h"
+#include "unicode/stringpiece.h"
 #include "unicode/ubrk.h"
 #include "unicode/uloc.h"
 #include "unicode/ustring.h"
@@ -29,49 +38,51 @@
 #include "unicode/utf.h"
 #include "unicode/utf8.h"
 #include "unicode/utf16.h"
+#include "bytesinkutil.h"
 #include "cmemory.h"
 #include "cstring.h"
+#include "uassert.h"
 #include "ucase.h"
+#include "ucasemap_imp.h"
 #include "ustr_imp.h"
 
 U_NAMESPACE_USE
 
 /* UCaseMap service object -------------------------------------------------- */
 
+UCaseMap::UCaseMap(const char *localeID, uint32_t opts, UErrorCode *pErrorCode) :
+#if !UCONFIG_NO_BREAK_ITERATION
+        iter(NULL),
+#endif
+        caseLocale(UCASE_LOC_UNKNOWN), options(opts) {
+    ucasemap_setLocale(this, localeID, pErrorCode);
+}
+
+UCaseMap::~UCaseMap() {
+#if !UCONFIG_NO_BREAK_ITERATION
+    delete iter;
+#endif
+}
+
 U_CAPI UCaseMap * U_EXPORT2
 ucasemap_open(const char *locale, uint32_t options, UErrorCode *pErrorCode) {
-    UCaseMap *csm;
-
     if(U_FAILURE(*pErrorCode)) {
         return NULL;
     }
-
-    csm=(UCaseMap *)uprv_malloc(sizeof(UCaseMap));
+    UCaseMap *csm = new UCaseMap(locale, options, pErrorCode);
     if(csm==NULL) {
+        *pErrorCode = U_MEMORY_ALLOCATION_ERROR;
+        return NULL;
+    } else if (U_FAILURE(*pErrorCode)) {
+        delete csm;
         return NULL;
     }
-    uprv_memset(csm, 0, sizeof(UCaseMap));
-
-    csm->csp=ucase_getSingleton();
-    ucasemap_setLocale(csm, locale, pErrorCode);
-    if(U_FAILURE(*pErrorCode)) {
-        uprv_free(csm);
-        return NULL;
-    }
-
-    csm->options=options;
     return csm;
 }
 
 U_CAPI void U_EXPORT2
 ucasemap_close(UCaseMap *csm) {
-    if(csm!=NULL) {
-#if !UCONFIG_NO_BREAK_ITERATION
-        // Do not call ubrk_close() so that we do not depend on all of the BreakIterator code.
-        delete reinterpret_cast<BreakIterator *>(csm->iter);
-#endif
-        uprv_free(csm);
-    }
+    delete csm;
 }
 
 U_CAPI const char * U_EXPORT2
@@ -86,13 +97,16 @@
 
 U_CAPI void U_EXPORT2
 ucasemap_setLocale(UCaseMap *csm, const char *locale, UErrorCode *pErrorCode) {
-    int32_t length;
-
     if(U_FAILURE(*pErrorCode)) {
         return;
     }
+    if (locale != NULL && *locale == 0) {
+        csm->locale[0] = 0;
+        csm->caseLocale = UCASE_LOC_ROOT;
+        return;
+    }
 
-    length=uloc_getName(locale, csm->locale, (int32_t)sizeof(csm->locale), pErrorCode);
+    int32_t length=uloc_getName(locale, csm->locale, (int32_t)sizeof(csm->locale), pErrorCode);
     if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR || length==sizeof(csm->locale)) {
         *pErrorCode=U_ZERO_ERROR;
         /* we only really need the language code for case mappings */
@@ -101,90 +115,60 @@
     if(length==sizeof(csm->locale)) {
         *pErrorCode=U_BUFFER_OVERFLOW_ERROR;
     }
-    csm->locCache=0;
     if(U_SUCCESS(*pErrorCode)) {
-        ucase_getCaseLocale(csm->locale, &csm->locCache);
+        csm->caseLocale=UCASE_LOC_UNKNOWN;
+        csm->caseLocale = ucase_getCaseLocale(csm->locale);
     } else {
         csm->locale[0]=0;
+        csm->caseLocale = UCASE_LOC_ROOT;
     }
 }
 
 U_CAPI void U_EXPORT2
-ucasemap_setOptions(UCaseMap *csm, uint32_t options, UErrorCode * /*pErrorCode*/) {
+ucasemap_setOptions(UCaseMap *csm, uint32_t options, UErrorCode *pErrorCode) {
+    if(U_FAILURE(*pErrorCode)) {
+        return;
+    }
     csm->options=options;
 }
 
 /* UTF-8 string case mappings ----------------------------------------------- */
 
-/* TODO(markus): Move to a new, separate utf8case.c file. */
+/* TODO(markus): Move to a new, separate utf8case.cpp file. */
+
+namespace {
 
 /* append a full case mapping result, see UCASE_MAX_STRING_LENGTH */
-static inline int32_t
-appendResult(uint8_t *dest, int32_t destIndex, int32_t destCapacity,
-             int32_t result, const UChar *s) {
-    UChar32 c;
-    int32_t length, destLength;
-    UErrorCode errorCode;
+inline UBool
+appendResult(int32_t cpLength, int32_t result, const UChar *s,
+             ByteSink &sink, uint32_t options, icu::Edits *edits, UErrorCode &errorCode) {
+    U_ASSERT(U_SUCCESS(errorCode));
 
     /* decode the result */
     if(result<0) {
         /* (not) original code point */
-        c=~result;
-        length=-1;
-    } else if(result<=UCASE_MAX_STRING_LENGTH) {
-        c=U_SENTINEL;
-        length=result;
-    } else {
-        c=result;
-        length=-1;
-    }
-
-    if(destIndex<destCapacity) {
-        /* append the result */
-        if(length<0) {
-            /* code point */
-            UBool isError=FALSE;
-            U8_APPEND(dest, destIndex, destCapacity, c, isError);
-            if(isError) {
-                /* overflow, nothing written */
-                destIndex+=U8_LENGTH(c);
-            }
-        } else {
-            /* string */
-            errorCode=U_ZERO_ERROR;
-            u_strToUTF8(
-                (char *)(dest+destIndex), destCapacity-destIndex, &destLength,
-                s, length,
-                &errorCode);
-            destIndex+=destLength;
-            /* we might have an overflow, but we know the actual length */
+        if(edits!=NULL) {
+            edits->addUnchanged(cpLength);
+        }
+        if((options & U_OMIT_UNCHANGED_TEXT) == 0) {
+            ByteSinkUtil::appendCodePoint(cpLength, ~result, sink);
         }
     } else {
-        /* preflight */
-        if(length<0) {
-            destIndex+=U8_LENGTH(c);
+        if(result<=UCASE_MAX_STRING_LENGTH) {
+            // string: "result" is the UTF-16 length
+            return ByteSinkUtil::appendChange(cpLength, s, result, sink, edits, errorCode);
         } else {
-            errorCode=U_ZERO_ERROR;
-            u_strToUTF8(
-                NULL, 0, &destLength,
-                s, length,
-                &errorCode);
-            destIndex+=destLength;
+            ByteSinkUtil::appendCodePoint(cpLength, result, sink, edits);
         }
     }
-    return destIndex;
+    return TRUE;
 }
 
-static inline int32_t
-appendUChar(uint8_t *dest, int32_t destIndex, int32_t destCapacity, UChar c) {
-    int32_t limit=destIndex+U8_LENGTH(c);
-    if(limit<destCapacity) {
-        U8_APPEND_UNSAFE(dest, destIndex, c);
-    }
-    return limit;
-}
+// See unicode/utf8.h U8_APPEND_UNSAFE().
+inline uint8_t getTwoByteLead(UChar32 c) { return (uint8_t)((c >> 6) | 0xc0); }
+inline uint8_t getTwoByteTrail(UChar32 c) { return (uint8_t)((c & 0x3f) | 0x80); }
 
-static UChar32 U_CALLCONV
+UChar32 U_CALLCONV
 utf8_caseContextIterator(void *context, int8_t dir) {
     UCaseContext *csc=(UCaseContext *)context;
     UChar32 c;
@@ -216,182 +200,352 @@
     return U_SENTINEL;
 }
 
-/*
- * Case-maps [srcStart..srcLimit[ but takes
- * context [0..srcLength[ into account.
+/**
+ * caseLocale >= 0: Lowercases [srcStart..srcLimit[ but takes context [0..srcLength[ into account.
+ * caseLocale < 0: Case-folds [srcStart..srcLimit[.
  */
-static int32_t
-_caseMap(const UCaseMap *csm, UCaseMapFull *map,
-         uint8_t *dest, int32_t destCapacity,
-         const uint8_t *src, UCaseContext *csc,
-         int32_t srcStart, int32_t srcLimit,
-         UErrorCode *pErrorCode) {
-    const UChar *s;
-    UChar32 c, c2 = 0;
-    int32_t srcIndex, destIndex;
-    int32_t locCache;
-
-    locCache=csm->locCache;
-
-    /* case mapping loop */
-    srcIndex=srcStart;
-    destIndex=0;
-    while(srcIndex<srcLimit) {
-        csc->cpStart=srcIndex;
-        U8_NEXT(src, srcIndex, srcLimit, c);
-        csc->cpLimit=srcIndex;
-        if(c<0) {
-            int32_t i=csc->cpStart;
-            while(destIndex<destCapacity && i<srcIndex) {
-                dest[destIndex++]=src[i++];
+void toLower(int32_t caseLocale, uint32_t options,
+             const uint8_t *src, UCaseContext *csc, int32_t srcStart, int32_t srcLimit,
+             icu::ByteSink &sink, icu::Edits *edits, UErrorCode &errorCode) {
+    const int8_t *latinToLower;
+    if (caseLocale == UCASE_LOC_ROOT ||
+            (caseLocale >= 0 ?
+                !(caseLocale == UCASE_LOC_TURKISH || caseLocale == UCASE_LOC_LITHUANIAN) :
+                (options & _FOLD_CASE_OPTIONS_MASK) == U_FOLD_CASE_DEFAULT)) {
+        latinToLower = LatinCase::TO_LOWER_NORMAL;
+    } else {
+        latinToLower = LatinCase::TO_LOWER_TR_LT;
+    }
+    const UTrie2 *trie = ucase_getTrie();
+    int32_t prev = srcStart;
+    int32_t srcIndex = srcStart;
+    for (;;) {
+        // fast path for simple cases
+        int32_t cpStart;
+        UChar32 c;
+        for (;;) {
+            if (U_FAILURE(errorCode) || srcIndex >= srcLimit) {
+                c = U_SENTINEL;
+                break;
             }
-            continue;
+            uint8_t lead = src[srcIndex++];
+            if (lead <= 0x7f) {
+                int8_t d = latinToLower[lead];
+                if (d == LatinCase::EXC) {
+                    cpStart = srcIndex - 1;
+                    c = lead;
+                    break;
+                }
+                if (d == 0) { continue; }
+                ByteSinkUtil::appendUnchanged(src + prev, srcIndex - 1 - prev,
+                                              sink, options, edits, errorCode);
+                char ascii = (char)(lead + d);
+                sink.Append(&ascii, 1);
+                if (edits != nullptr) {
+                    edits->addReplace(1, 1);
+                }
+                prev = srcIndex;
+                continue;
+            } else if (lead < 0xe3) {
+                uint8_t t;
+                if (0xc2 <= lead && lead <= 0xc5 && srcIndex < srcLimit &&
+                        (t = src[srcIndex] - 0x80) <= 0x3f) {
+                    // U+0080..U+017F
+                    ++srcIndex;
+                    c = ((lead - 0xc0) << 6) | t;
+                    int8_t d = latinToLower[c];
+                    if (d == LatinCase::EXC) {
+                        cpStart = srcIndex - 2;
+                        break;
+                    }
+                    if (d == 0) { continue; }
+                    ByteSinkUtil::appendUnchanged(src + prev, srcIndex - 2 - prev,
+                                                  sink, options, edits, errorCode);
+                    ByteSinkUtil::appendTwoBytes(c + d, sink);
+                    if (edits != nullptr) {
+                        edits->addReplace(2, 2);
+                    }
+                    prev = srcIndex;
+                    continue;
+                }
+            } else if ((lead <= 0xe9 || lead == 0xeb || lead == 0xec) &&
+                    (srcIndex + 2) <= srcLimit &&
+                    U8_IS_TRAIL(src[srcIndex]) && U8_IS_TRAIL(src[srcIndex + 1])) {
+                // most of CJK: no case mappings
+                srcIndex += 2;
+                continue;
+            }
+            cpStart = --srcIndex;
+            U8_NEXT(src, srcIndex, srcLimit, c);
+            if (c < 0) {
+                // ill-formed UTF-8
+                continue;
+            }
+            uint16_t props = UTRIE2_GET16(trie, c);
+            if (UCASE_HAS_EXCEPTION(props)) { break; }
+            int32_t delta;
+            if (!UCASE_IS_UPPER_OR_TITLE(props) || (delta = UCASE_GET_DELTA(props)) == 0) {
+                continue;
+            }
+            ByteSinkUtil::appendUnchanged(src + prev, cpStart - prev,
+                                          sink, options, edits, errorCode);
+            ByteSinkUtil::appendCodePoint(srcIndex - cpStart, c + delta, sink, edits);
+            prev = srcIndex;
         }
-        c=map(csm->csp, c, utf8_caseContextIterator, csc, &s, csm->locale, &locCache);
-        if((destIndex<destCapacity) && (c<0 ? (c2=~c)<=0x7f : UCASE_MAX_STRING_LENGTH<c && (c2=c)<=0x7f)) {
-            /* fast path version of appendResult() for ASCII results */
-            dest[destIndex++]=(uint8_t)c2;
+        if (c < 0) {
+            break;
+        }
+        // slow path
+        const UChar *s;
+        if (caseLocale >= 0) {
+            csc->cpStart = cpStart;
+            csc->cpLimit = srcIndex;
+            c = ucase_toFullLower(c, utf8_caseContextIterator, csc, &s, caseLocale);
         } else {
-            destIndex=appendResult(dest, destIndex, destCapacity, c, s);
+            c = ucase_toFullFolding(c, &s, options);
+        }
+        if (c >= 0) {
+            ByteSinkUtil::appendUnchanged(src + prev, cpStart - prev,
+                                          sink, options, edits, errorCode);
+            appendResult(srcIndex - cpStart, c, s, sink, options, edits, errorCode);
+            prev = srcIndex;
         }
     }
-
-    if(destIndex>destCapacity) {
-        *pErrorCode=U_BUFFER_OVERFLOW_ERROR;
-    }
-    return destIndex;
+    ByteSinkUtil::appendUnchanged(src + prev, srcIndex - prev,
+                                  sink, options, edits, errorCode);
 }
 
+void toUpper(int32_t caseLocale, uint32_t options,
+             const uint8_t *src, UCaseContext *csc, int32_t srcLength,
+             icu::ByteSink &sink, icu::Edits *edits, UErrorCode &errorCode) {
+    const int8_t *latinToUpper;
+    if (caseLocale == UCASE_LOC_TURKISH) {
+        latinToUpper = LatinCase::TO_UPPER_TR;
+    } else {
+        latinToUpper = LatinCase::TO_UPPER_NORMAL;
+    }
+    const UTrie2 *trie = ucase_getTrie();
+    int32_t prev = 0;
+    int32_t srcIndex = 0;
+    for (;;) {
+        // fast path for simple cases
+        int32_t cpStart;
+        UChar32 c;
+        for (;;) {
+            if (U_FAILURE(errorCode) || srcIndex >= srcLength) {
+                c = U_SENTINEL;
+                break;
+            }
+            uint8_t lead = src[srcIndex++];
+            if (lead <= 0x7f) {
+                int8_t d = latinToUpper[lead];
+                if (d == LatinCase::EXC) {
+                    cpStart = srcIndex - 1;
+                    c = lead;
+                    break;
+                }
+                if (d == 0) { continue; }
+                ByteSinkUtil::appendUnchanged(src + prev, srcIndex - 1 - prev,
+                                              sink, options, edits, errorCode);
+                char ascii = (char)(lead + d);
+                sink.Append(&ascii, 1);
+                if (edits != nullptr) {
+                    edits->addReplace(1, 1);
+                }
+                prev = srcIndex;
+                continue;
+            } else if (lead < 0xe3) {
+                uint8_t t;
+                if (0xc2 <= lead && lead <= 0xc5 && srcIndex < srcLength &&
+                        (t = src[srcIndex] - 0x80) <= 0x3f) {
+                    // U+0080..U+017F
+                    ++srcIndex;
+                    c = ((lead - 0xc0) << 6) | t;
+                    int8_t d = latinToUpper[c];
+                    if (d == LatinCase::EXC) {
+                        cpStart = srcIndex - 2;
+                        break;
+                    }
+                    if (d == 0) { continue; }
+                    ByteSinkUtil::appendUnchanged(src + prev, srcIndex - 2 - prev,
+                                                  sink, options, edits, errorCode);
+                    ByteSinkUtil::appendTwoBytes(c + d, sink);
+                    if (edits != nullptr) {
+                        edits->addReplace(2, 2);
+                    }
+                    prev = srcIndex;
+                    continue;
+                }
+            } else if ((lead <= 0xe9 || lead == 0xeb || lead == 0xec) &&
+                    (srcIndex + 2) <= srcLength &&
+                    U8_IS_TRAIL(src[srcIndex]) && U8_IS_TRAIL(src[srcIndex + 1])) {
+                // most of CJK: no case mappings
+                srcIndex += 2;
+                continue;
+            }
+            cpStart = --srcIndex;
+            U8_NEXT(src, srcIndex, srcLength, c);
+            if (c < 0) {
+                // ill-formed UTF-8
+                continue;
+            }
+            uint16_t props = UTRIE2_GET16(trie, c);
+            if (UCASE_HAS_EXCEPTION(props)) { break; }
+            int32_t delta;
+            if (UCASE_GET_TYPE(props) != UCASE_LOWER || (delta = UCASE_GET_DELTA(props)) == 0) {
+                continue;
+            }
+            ByteSinkUtil::appendUnchanged(src + prev, cpStart - prev,
+                                          sink, options, edits, errorCode);
+            ByteSinkUtil::appendCodePoint(srcIndex - cpStart, c + delta, sink, edits);
+            prev = srcIndex;
+        }
+        if (c < 0) {
+            break;
+        }
+        // slow path
+        csc->cpStart = cpStart;
+        csc->cpLimit = srcIndex;
+        const UChar *s;
+        c = ucase_toFullUpper(c, utf8_caseContextIterator, csc, &s, caseLocale);
+        if (c >= 0) {
+            ByteSinkUtil::appendUnchanged(src + prev, cpStart - prev,
+                                          sink, options, edits, errorCode);
+            appendResult(srcIndex - cpStart, c, s, sink, options, edits, errorCode);
+            prev = srcIndex;
+        }
+    }
+    ByteSinkUtil::appendUnchanged(src + prev, srcIndex - prev,
+                                  sink, options, edits, errorCode);
+}
+
+}  // namespace
+
 #if !UCONFIG_NO_BREAK_ITERATION
 
-U_CFUNC int32_t U_CALLCONV
-ucasemap_internalUTF8ToTitle(const UCaseMap *csm,
-         uint8_t *dest, int32_t destCapacity,
-         const uint8_t *src, int32_t srcLength,
-         UErrorCode *pErrorCode) {
-    const UChar *s;
-    UChar32 c;
-    int32_t prev, titleStart, titleLimit, idx, destIndex, length;
-    UBool isFirstIndex;
-
-    if(U_FAILURE(*pErrorCode)) {
-        return 0;
+U_CFUNC void U_CALLCONV
+ucasemap_internalUTF8ToTitle(
+        int32_t caseLocale, uint32_t options, BreakIterator *iter,
+        const uint8_t *src, int32_t srcLength,
+        ByteSink &sink, icu::Edits *edits,
+        UErrorCode &errorCode) {
+    if (!ustrcase_checkTitleAdjustmentOptions(options, errorCode)) {
+        return;
     }
 
-    // Use the C++ abstract base class to minimize dependencies.
-    // TODO: Change UCaseMap.iter to store a BreakIterator directly.
-    BreakIterator *bi=reinterpret_cast<BreakIterator *>(csm->iter);
-
     /* set up local variables */
-    int32_t locCache=csm->locCache;
     UCaseContext csc=UCASECONTEXT_INITIALIZER;
     csc.p=(void *)src;
     csc.limit=srcLength;
-    destIndex=0;
-    prev=0;
-    isFirstIndex=TRUE;
+    int32_t prev=0;
+    UBool isFirstIndex=TRUE;
 
     /* titlecasing loop */
     while(prev<srcLength) {
         /* find next index where to titlecase */
+        int32_t index;
         if(isFirstIndex) {
             isFirstIndex=FALSE;
-            idx=bi->first();
+            index=iter->first();
         } else {
-            idx=bi->next();
+            index=iter->next();
         }
-        if(idx==UBRK_DONE || idx>srcLength) {
-            idx=srcLength;
+        if(index==UBRK_DONE || index>srcLength) {
+            index=srcLength;
         }
 
         /*
-         * Unicode 4 & 5 section 3.13 Default Case Operations:
-         *
-         * R3  toTitlecase(X): Find the word boundaries based on Unicode Standard Annex
-         * #29, "Text Boundaries." Between each pair of word boundaries, find the first
-         * cased character F. If F exists, map F to default_title(F); then map each
-         * subsequent character C to default_lower(C).
-         *
-         * In this implementation, segment [prev..index[ into 3 parts:
-         * a) uncased characters (copy as-is) [prev..titleStart[
-         * b) first case letter (titlecase)         [titleStart..titleLimit[
+         * Segment [prev..index[ into 3 parts:
+         * a) skipped characters (copy as-is) [prev..titleStart[
+         * b) first letter (titlecase)              [titleStart..titleLimit[
          * c) subsequent characters (lowercase)                 [titleLimit..index[
          */
-        if(prev<idx) {
-            /* find and copy uncased characters [prev..titleStart[ */
-            titleStart=titleLimit=prev;
-            U8_NEXT(src, titleLimit, idx, c);
-            if((csm->options&U_TITLECASE_NO_BREAK_ADJUSTMENT)==0 && UCASE_NONE==ucase_getType(csm->csp, c)) {
-                /* Adjust the titlecasing index (titleStart) to the next cased character. */
-                for(;;) {
+        if(prev<index) {
+            /* find and copy skipped characters [prev..titleStart[ */
+            int32_t titleStart=prev;
+            int32_t titleLimit=prev;
+            UChar32 c;
+            U8_NEXT(src, titleLimit, index, c);
+            if ((options&U_TITLECASE_NO_BREAK_ADJUSTMENT)==0) {
+                // Adjust the titlecasing index to the next cased character,
+                // or to the next letter/number/symbol/private use.
+                // Stop with titleStart<titleLimit<=index
+                // if there is a character to be titlecased,
+                // or else stop with titleStart==titleLimit==index.
+                UBool toCased = (options&U_TITLECASE_ADJUST_TO_CASED) != 0;
+                while (toCased ? UCASE_NONE==ucase_getType(c) : !ustrcase_isLNS(c)) {
                     titleStart=titleLimit;
-                    if(titleLimit==idx) {
-                        /*
-                         * only uncased characters in [prev..index[
-                         * stop with titleStart==titleLimit==index
-                         */
+                    if(titleLimit==index) {
                         break;
                     }
-                    U8_NEXT(src, titleLimit, idx, c);
-                    if(UCASE_NONE!=ucase_getType(csm->csp, c)) {
-                        break; /* cased letter at [titleStart..titleLimit[ */
-                    }
+                    U8_NEXT(src, titleLimit, index, c);
                 }
-                length=titleStart-prev;
-                if(length>0) {
-                    if((destIndex+length)<=destCapacity) {
-                        uprv_memcpy(dest+destIndex, src+prev, length);
+                if (prev < titleStart) {
+                    if (!ByteSinkUtil::appendUnchanged(src+prev, titleStart-prev,
+                                                       sink, options, edits, errorCode)) {
+                        return;
                     }
-                    destIndex+=length;
                 }
             }
 
             if(titleStart<titleLimit) {
                 /* titlecase c which is from [titleStart..titleLimit[ */
-                csc.cpStart=titleStart;
-                csc.cpLimit=titleLimit;
-                c=ucase_toFullTitle(csm->csp, c, utf8_caseContextIterator, &csc, &s, csm->locale, &locCache);
-                destIndex=appendResult(dest, destIndex, destCapacity, c, s);
+                if(c>=0) {
+                    csc.cpStart=titleStart;
+                    csc.cpLimit=titleLimit;
+                    const UChar *s;
+                    c=ucase_toFullTitle(c, utf8_caseContextIterator, &csc, &s, caseLocale);
+                    if (!appendResult(titleLimit-titleStart, c, s, sink, options, edits, errorCode)) {
+                        return;
+                    }
+                } else {
+                    // Malformed UTF-8.
+                    if (!ByteSinkUtil::appendUnchanged(src+titleStart, titleLimit-titleStart,
+                                                       sink, options, edits, errorCode)) {
+                        return;
+                    }
+                }
 
                 /* Special case Dutch IJ titlecasing */
-                if ( titleStart+1 < idx && 
-                     ucase_getCaseLocale(csm->locale, &locCache) == UCASE_LOC_DUTCH &&
-                     ( src[titleStart] == 0x0049 || src[titleStart] == 0x0069 ) &&
-                     ( src[titleStart+1] == 0x004A || src[titleStart+1] == 0x006A )) { 
-                            c=0x004A;
-                            destIndex=appendResult(dest, destIndex, destCapacity, c, s);
-                            titleLimit++;
+                if (titleStart+1 < index &&
+                        caseLocale == UCASE_LOC_DUTCH &&
+                        (src[titleStart] == 0x0049 || src[titleStart] == 0x0069)) {
+                    if (src[titleStart+1] == 0x006A) {
+                        ByteSinkUtil::appendCodePoint(1, 0x004A, sink, edits);
+                        titleLimit++;
+                    } else if (src[titleStart+1] == 0x004A) {
+                        // Keep the capital J from getting lowercased.
+                        if (!ByteSinkUtil::appendUnchanged(src+titleStart+1, 1,
+                                                           sink, options, edits, errorCode)) {
+                            return;
+                        }
+                        titleLimit++;
+                    }
                 }
+
                 /* lowercase [titleLimit..index[ */
-                if(titleLimit<idx) {
-                    if((csm->options&U_TITLECASE_NO_LOWERCASE)==0) {
+                if(titleLimit<index) {
+                    if((options&U_TITLECASE_NO_LOWERCASE)==0) {
                         /* Normal operation: Lowercase the rest of the word. */
-                        destIndex+=
-                            _caseMap(
-                                csm, ucase_toFullLower,
-                                dest+destIndex, destCapacity-destIndex,
-                                src, &csc,
-                                titleLimit, idx,
-                                pErrorCode);
+                        toLower(caseLocale, options,
+                                src, &csc, titleLimit, index,
+                                sink, edits, errorCode);
+                        if(U_FAILURE(errorCode)) {
+                            return;
+                        }
                     } else {
                         /* Optionally just copy the rest of the word unchanged. */
-                        length=idx-titleLimit;
-                        if((destIndex+length)<=destCapacity) {
-                            uprv_memcpy(dest+destIndex, src+titleLimit, length);
+                        if (!ByteSinkUtil::appendUnchanged(src+titleLimit, index-titleLimit,
+                                                           sink, options, edits, errorCode)) {
+                            return;
                         }
-                        destIndex+=length;
                     }
                 }
             }
         }
 
-        prev=idx;
+        prev=index;
     }
-
-    if(destIndex>destCapacity) {
-        *pErrorCode=U_BUFFER_OVERFLOW_ERROR;
-    }
-    return destIndex;
 }
 
 #endif
@@ -399,11 +553,11 @@
 U_NAMESPACE_BEGIN
 namespace GreekUpper {
 
-UBool isFollowedByCasedLetter(const UCaseProps *csp, const uint8_t *s, int32_t i, int32_t length) {
+UBool isFollowedByCasedLetter(const uint8_t *s, int32_t i, int32_t length) {
     while (i < length) {
         UChar32 c;
         U8_NEXT(s, i, length, c);
-        int32_t type = ucase_getTypeOrIgnorable(csp, c);
+        int32_t type = ucase_getTypeOrIgnorable(c);
         if ((type & UCASE_IGNORABLE) != 0) {
             // Case-ignorable, continue with the loop.
         } else if (type != UCASE_NONE) {
@@ -416,19 +570,17 @@
 }
 
 // Keep this consistent with the UTF-16 version in ustrcase.cpp and the Java version in CaseMap.java.
-int32_t toUpper(const UCaseMap *csm,
-                uint8_t *dest, int32_t destCapacity,
-                const uint8_t *src, int32_t srcLength,
-                UErrorCode *pErrorCode) {
-    int32_t locCache = UCASE_LOC_GREEK;
-    int32_t destIndex=0;
+void toUpper(uint32_t options,
+             const uint8_t *src, int32_t srcLength,
+             ByteSink &sink, Edits *edits,
+             UErrorCode &errorCode) {
     uint32_t state = 0;
     for (int32_t i = 0; i < srcLength;) {
         int32_t nextIndex = i;
         UChar32 c;
         U8_NEXT(src, nextIndex, srcLength, c);
         uint32_t nextState = 0;
-        int32_t type = ucase_getTypeOrIgnorable(csm->csp, c);
+        int32_t type = ucase_getTypeOrIgnorable(c);
         if ((type & UCASE_IGNORABLE) != 0) {
             // c is case-ignorable
             nextState |= (state & AFTER_CASED);
@@ -478,7 +630,7 @@
                     (data & HAS_ACCENT) != 0 &&
                     numYpogegrammeni == 0 &&
                     (state & AFTER_CASED) == 0 &&
-                    !isFollowedByCasedLetter(csm->csp, src, nextIndex, srcLength)) {
+                    !isFollowedByCasedLetter(src, nextIndex, srcLength)) {
                 // Keep disjunctive "or" with (only) a tonos.
                 // We use the same "word boundary" conditions as for the Final_Sigma test.
                 if (i == nextIndex) {
@@ -496,139 +648,171 @@
                     data &= ~HAS_EITHER_DIALYTIKA;
                 }
             }
-            destIndex=appendUChar(dest, destIndex, destCapacity, (UChar)upper);
-            if ((data & HAS_EITHER_DIALYTIKA) != 0) {
-                destIndex=appendUChar(dest, destIndex, destCapacity, 0x308);  // restore or add a dialytika
+
+            UBool change;
+            if (edits == nullptr && (options & U_OMIT_UNCHANGED_TEXT) == 0) {
+                change = TRUE;  // common, simple usage
+            } else {
+                // Find out first whether we are changing the text.
+                U_ASSERT(0x370 <= upper && upper <= 0x3ff);  // 2-byte UTF-8, main Greek block
+                change = (i + 2) > nextIndex ||
+                        src[i] != getTwoByteLead(upper) || src[i + 1] != getTwoByteTrail(upper) ||
+                        numYpogegrammeni > 0;
+                int32_t i2 = i + 2;
+                if ((data & HAS_EITHER_DIALYTIKA) != 0) {
+                    change |= (i2 + 2) > nextIndex ||
+                            src[i2] != (uint8_t)u8"\u0308"[0] ||
+                            src[i2 + 1] != (uint8_t)u8"\u0308"[1];
+                    i2 += 2;
+                }
+                if (addTonos) {
+                    change |= (i2 + 2) > nextIndex ||
+                            src[i2] != (uint8_t)u8"\u0301"[0] ||
+                            src[i2 + 1] != (uint8_t)u8"\u0301"[1];
+                    i2 += 2;
+                }
+                int32_t oldLength = nextIndex - i;
+                int32_t newLength = (i2 - i) + numYpogegrammeni * 2;  // 2 bytes per U+0399
+                change |= oldLength != newLength;
+                if (change) {
+                    if (edits != NULL) {
+                        edits->addReplace(oldLength, newLength);
+                    }
+                } else {
+                    if (edits != NULL) {
+                        edits->addUnchanged(oldLength);
+                    }
+                    // Write unchanged text?
+                    change = (options & U_OMIT_UNCHANGED_TEXT) == 0;
+                }
             }
-            if (addTonos) {
-                destIndex=appendUChar(dest, destIndex, destCapacity, 0x301);
+
+            if (change) {
+                ByteSinkUtil::appendTwoBytes(upper, sink);
+                if ((data & HAS_EITHER_DIALYTIKA) != 0) {
+                    sink.AppendU8(u8"\u0308", 2);  // restore or add a dialytika
+                }
+                if (addTonos) {
+                    sink.AppendU8(u8"\u0301", 2);
+                }
+                while (numYpogegrammeni > 0) {
+                    sink.AppendU8(u8"\u0399", 2);
+                    --numYpogegrammeni;
+                }
             }
-            while (numYpogegrammeni > 0) {
-                destIndex=appendUChar(dest, destIndex, destCapacity, 0x399);
-                --numYpogegrammeni;
+        } else if(c>=0) {
+            const UChar *s;
+            c=ucase_toFullUpper(c, NULL, NULL, &s, UCASE_LOC_GREEK);
+            if (!appendResult(nextIndex - i, c, s, sink, options, edits, errorCode)) {
+                return;
             }
         } else {
-            const UChar *s;
-            UChar32 c2 = 0;
-            c=ucase_toFullUpper(csm->csp, c, NULL, NULL, &s, csm->locale, &locCache);
-            if((destIndex<destCapacity) && (c<0 ? (c2=~c)<=0x7f : UCASE_MAX_STRING_LENGTH<c && (c2=c)<=0x7f)) {
-                /* fast path version of appendResult() for ASCII results */
-                dest[destIndex++]=(uint8_t)c2;
-            } else {
-                destIndex=appendResult(dest, destIndex, destCapacity, c, s);
+            // Malformed UTF-8.
+            if (!ByteSinkUtil::appendUnchanged(src+i, nextIndex-i,
+                                               sink, options, edits, errorCode)) {
+                return;
             }
         }
         i = nextIndex;
         state = nextState;
     }
-
-    if(destIndex>destCapacity) {
-        *pErrorCode=U_BUFFER_OVERFLOW_ERROR;
-    }
-    return destIndex;
 }
 
 }  // namespace GreekUpper
 U_NAMESPACE_END
 
-static int32_t U_CALLCONV
-ucasemap_internalUTF8ToLower(const UCaseMap *csm,
-                             uint8_t *dest, int32_t destCapacity,
+static void U_CALLCONV
+ucasemap_internalUTF8ToLower(int32_t caseLocale, uint32_t options, UCASEMAP_BREAK_ITERATOR_UNUSED
                              const uint8_t *src, int32_t srcLength,
-                             UErrorCode *pErrorCode) {
+                             icu::ByteSink &sink, icu::Edits *edits,
+                             UErrorCode &errorCode) {
     UCaseContext csc=UCASECONTEXT_INITIALIZER;
     csc.p=(void *)src;
     csc.limit=srcLength;
-    return _caseMap(
-        csm, ucase_toFullLower,
-        dest, destCapacity,
+    toLower(
+        caseLocale, options,
         src, &csc, 0, srcLength,
-        pErrorCode);
+        sink, edits, errorCode);
 }
 
-static int32_t U_CALLCONV
-ucasemap_internalUTF8ToUpper(const UCaseMap *csm,
-                             uint8_t *dest, int32_t destCapacity,
+static void U_CALLCONV
+ucasemap_internalUTF8ToUpper(int32_t caseLocale, uint32_t options, UCASEMAP_BREAK_ITERATOR_UNUSED
                              const uint8_t *src, int32_t srcLength,
-                             UErrorCode *pErrorCode) {
-    int32_t locCache = csm->locCache;
-    if (ucase_getCaseLocale(csm->locale, &locCache) == UCASE_LOC_GREEK) {
-        return GreekUpper::toUpper(csm, dest, destCapacity, src, srcLength, pErrorCode);
+                             icu::ByteSink &sink, icu::Edits *edits,
+                             UErrorCode &errorCode) {
+    if (caseLocale == UCASE_LOC_GREEK) {
+        GreekUpper::toUpper(options, src, srcLength, sink, edits, errorCode);
+    } else {
+        UCaseContext csc=UCASECONTEXT_INITIALIZER;
+        csc.p=(void *)src;
+        csc.limit=srcLength;
+        toUpper(
+            caseLocale, options,
+            src, &csc, srcLength,
+            sink, edits, errorCode);
     }
-    UCaseContext csc=UCASECONTEXT_INITIALIZER;
-    csc.p=(void *)src;
-    csc.limit=srcLength;
-    return _caseMap(
-        csm, ucase_toFullUpper,
-        dest, destCapacity,
-        src, &csc, 0, srcLength,
-        pErrorCode);
 }
 
-static int32_t
-utf8_foldCase(const UCaseProps *csp,
-              uint8_t *dest, int32_t destCapacity,
-              const uint8_t *src, int32_t srcLength,
-              uint32_t options,
-              UErrorCode *pErrorCode) {
-    int32_t srcIndex, destIndex;
-
-    const UChar *s;
-    UChar32 c, c2;
-    int32_t start;
-
-    /* case mapping loop */
-    srcIndex=destIndex=0;
-    while(srcIndex<srcLength) {
-        start=srcIndex;
-        U8_NEXT(src, srcIndex, srcLength, c);
-        if(c<0) {
-            while(destIndex<destCapacity && start<srcIndex) {
-                dest[destIndex++]=src[start++];
-            }
-            continue;
-        }
-        c=ucase_toFullFolding(csp, c, &s, options);
-        if((destIndex<destCapacity) && (c<0 ? (c2=~c)<=0x7f : UCASE_MAX_STRING_LENGTH<c && (c2=c)<=0x7f)) {
-            /* fast path version of appendResult() for ASCII results */
-            dest[destIndex++]=(uint8_t)c2;
-        } else {
-            destIndex=appendResult(dest, destIndex, destCapacity, c, s);
-        }
-    }
-
-    if(destIndex>destCapacity) {
-        *pErrorCode=U_BUFFER_OVERFLOW_ERROR;
-    }
-    return destIndex;
-}
-
-static int32_t U_CALLCONV
-ucasemap_internalUTF8Fold(const UCaseMap *csm,
-                          uint8_t *dest, int32_t destCapacity,
+static void U_CALLCONV
+ucasemap_internalUTF8Fold(int32_t /* caseLocale */, uint32_t options, UCASEMAP_BREAK_ITERATOR_UNUSED
                           const uint8_t *src, int32_t srcLength,
-                          UErrorCode *pErrorCode) {
-    return utf8_foldCase(csm->csp, dest, destCapacity, src, srcLength, csm->options, pErrorCode);
+                          icu::ByteSink &sink, icu::Edits *edits,
+                          UErrorCode &errorCode) {
+    toLower(
+        -1, options,
+        src, nullptr, 0, srcLength,
+        sink, edits, errorCode);
 }
 
-U_CFUNC int32_t
-ucasemap_mapUTF8(const UCaseMap *csm,
-                 uint8_t *dest, int32_t destCapacity,
-                 const uint8_t *src, int32_t srcLength,
+void
+ucasemap_mapUTF8(int32_t caseLocale, uint32_t options, UCASEMAP_BREAK_ITERATOR_PARAM
+                 const char *src, int32_t srcLength,
                  UTF8CaseMapper *stringCaseMapper,
-                 UErrorCode *pErrorCode) {
-    int32_t destLength;
-
+                 icu::ByteSink &sink, icu::Edits *edits,
+                 UErrorCode &errorCode) {
     /* check argument values */
-    if(U_FAILURE(*pErrorCode)) {
+    if (U_FAILURE(errorCode)) {
+        return;
+    }
+    if ((src == nullptr && srcLength != 0) || srcLength < -1) {
+        errorCode = U_ILLEGAL_ARGUMENT_ERROR;
+        return;
+    }
+
+    // Get the string length.
+    if (srcLength == -1) {
+        srcLength = (int32_t)uprv_strlen((const char *)src);
+    }
+
+    if (edits != nullptr && (options & U_EDITS_NO_RESET) == 0) {
+        edits->reset();
+    }
+    stringCaseMapper(caseLocale, options, UCASEMAP_BREAK_ITERATOR
+                     (const uint8_t *)src, srcLength, sink, edits, errorCode);
+    sink.Flush();
+    if (U_SUCCESS(errorCode)) {
+        if (edits != nullptr) {
+            edits->copyErrorTo(errorCode);
+        }
+    }
+}
+
+int32_t
+ucasemap_mapUTF8(int32_t caseLocale, uint32_t options, UCASEMAP_BREAK_ITERATOR_PARAM
+                 char *dest, int32_t destCapacity,
+                 const char *src, int32_t srcLength,
+                 UTF8CaseMapper *stringCaseMapper,
+                 icu::Edits *edits,
+                 UErrorCode &errorCode) {
+    /* check argument values */
+    if(U_FAILURE(errorCode)) {
         return 0;
     }
     if( destCapacity<0 ||
         (dest==NULL && destCapacity>0) ||
-        src==NULL ||
-        srcLength<-1
+        (src==NULL && srcLength!=0) || srcLength<-1
     ) {
-        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
+        errorCode=U_ILLEGAL_ARGUMENT_ERROR;
         return 0;
     }
 
@@ -642,12 +826,25 @@
         ((src>=dest && src<(dest+destCapacity)) ||
          (dest>=src && dest<(src+srcLength)))
     ) {
-        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
+        errorCode=U_ILLEGAL_ARGUMENT_ERROR;
         return 0;
     }
 
-    destLength=stringCaseMapper(csm, dest, destCapacity, src, srcLength, pErrorCode);
-    return u_terminateChars((char *)dest, destCapacity, destLength, pErrorCode);
+    CheckedArrayByteSink sink(dest, destCapacity);
+    if (edits != nullptr && (options & U_EDITS_NO_RESET) == 0) {
+        edits->reset();
+    }
+    stringCaseMapper(caseLocale, options, UCASEMAP_BREAK_ITERATOR
+                     (const uint8_t *)src, srcLength, sink, edits, errorCode);
+    sink.Flush();
+    if (U_SUCCESS(errorCode)) {
+        if (sink.Overflowed()) {
+            errorCode = U_BUFFER_OVERFLOW_ERROR;
+        } else if (edits != nullptr) {
+            edits->copyErrorTo(errorCode);
+        }
+    }
+    return u_terminateChars(dest, destCapacity, sink.NumberOfBytesAppended(), &errorCode);
 }
 
 /* public API functions */
@@ -657,10 +854,11 @@
                      char *dest, int32_t destCapacity,
                      const char *src, int32_t srcLength,
                      UErrorCode *pErrorCode) {
-    return ucasemap_mapUTF8(csm,
-                   (uint8_t *)dest, destCapacity,
-                   (const uint8_t *)src, srcLength,
-                   ucasemap_internalUTF8ToLower, pErrorCode);
+    return ucasemap_mapUTF8(
+        csm->caseLocale, csm->options, UCASEMAP_BREAK_ITERATOR_NULL
+        dest, destCapacity,
+        src, srcLength,
+        ucasemap_internalUTF8ToLower, NULL, *pErrorCode);
 }
 
 U_CAPI int32_t U_EXPORT2
@@ -668,10 +866,11 @@
                      char *dest, int32_t destCapacity,
                      const char *src, int32_t srcLength,
                      UErrorCode *pErrorCode) {
-    return ucasemap_mapUTF8(csm,
-                   (uint8_t *)dest, destCapacity,
-                   (const uint8_t *)src, srcLength,
-                   ucasemap_internalUTF8ToUpper, pErrorCode);
+    return ucasemap_mapUTF8(
+        csm->caseLocale, csm->options, UCASEMAP_BREAK_ITERATOR_NULL
+        dest, destCapacity,
+        src, srcLength,
+        ucasemap_internalUTF8ToUpper, NULL, *pErrorCode);
 }
 
 U_CAPI int32_t U_EXPORT2
@@ -679,8 +878,79 @@
                       char *dest, int32_t destCapacity,
                       const char *src, int32_t srcLength,
                       UErrorCode *pErrorCode) {
-    return ucasemap_mapUTF8(csm,
-                   (uint8_t *)dest, destCapacity,
-                   (const uint8_t *)src, srcLength,
-                   ucasemap_internalUTF8Fold, pErrorCode);
+    return ucasemap_mapUTF8(
+        UCASE_LOC_ROOT, csm->options, UCASEMAP_BREAK_ITERATOR_NULL
+        dest, destCapacity,
+        src, srcLength,
+        ucasemap_internalUTF8Fold, NULL, *pErrorCode);
 }
+
+U_NAMESPACE_BEGIN
+
+void CaseMap::utf8ToLower(
+        const char *locale, uint32_t options,
+        StringPiece src, ByteSink &sink, Edits *edits,
+        UErrorCode &errorCode) {
+    ucasemap_mapUTF8(
+        ustrcase_getCaseLocale(locale), options, UCASEMAP_BREAK_ITERATOR_NULL
+        src.data(), src.length(),
+        ucasemap_internalUTF8ToLower, sink, edits, errorCode);
+}
+
+void CaseMap::utf8ToUpper(
+        const char *locale, uint32_t options,
+        StringPiece src, ByteSink &sink, Edits *edits,
+        UErrorCode &errorCode) {
+    ucasemap_mapUTF8(
+        ustrcase_getCaseLocale(locale), options, UCASEMAP_BREAK_ITERATOR_NULL
+        src.data(), src.length(),
+        ucasemap_internalUTF8ToUpper, sink, edits, errorCode);
+}
+
+void CaseMap::utf8Fold(
+        uint32_t options,
+        StringPiece src, ByteSink &sink, Edits *edits,
+        UErrorCode &errorCode) {
+    ucasemap_mapUTF8(
+        UCASE_LOC_ROOT, options, UCASEMAP_BREAK_ITERATOR_NULL
+        src.data(), src.length(),
+        ucasemap_internalUTF8Fold, sink, edits, errorCode);
+}
+
+int32_t CaseMap::utf8ToLower(
+        const char *locale, uint32_t options,
+        const char *src, int32_t srcLength,
+        char *dest, int32_t destCapacity, Edits *edits,
+        UErrorCode &errorCode) {
+    return ucasemap_mapUTF8(
+        ustrcase_getCaseLocale(locale), options, UCASEMAP_BREAK_ITERATOR_NULL
+        dest, destCapacity,
+        src, srcLength,
+        ucasemap_internalUTF8ToLower, edits, errorCode);
+}
+
+int32_t CaseMap::utf8ToUpper(
+        const char *locale, uint32_t options,
+        const char *src, int32_t srcLength,
+        char *dest, int32_t destCapacity, Edits *edits,
+        UErrorCode &errorCode) {
+    return ucasemap_mapUTF8(
+        ustrcase_getCaseLocale(locale), options, UCASEMAP_BREAK_ITERATOR_NULL
+        dest, destCapacity,
+        src, srcLength,
+        ucasemap_internalUTF8ToUpper, edits, errorCode);
+}
+
+int32_t CaseMap::utf8Fold(
+        uint32_t options,
+        const char *src, int32_t srcLength,
+        char *dest, int32_t destCapacity, Edits *edits,
+        UErrorCode &errorCode) {
+    return ucasemap_mapUTF8(
+        UCASE_LOC_ROOT, options, UCASEMAP_BREAK_ITERATOR_NULL
+        dest, destCapacity,
+        src, srcLength,
+        ucasemap_internalUTF8Fold, edits, errorCode);
+}
+
+U_NAMESPACE_END
diff --git a/src/third_party/icu/source/common/ucasemap_imp.h b/src/third_party/icu/source/common/ucasemap_imp.h
new file mode 100644
index 0000000..e17a0ae
--- /dev/null
+++ b/src/third_party/icu/source/common/ucasemap_imp.h
@@ -0,0 +1,282 @@
+// © 2017 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+// ucasemap_imp.h
+// created: 2017feb08 Markus W. Scherer
+
+#ifndef __UCASEMAP_IMP_H__
+#define __UCASEMAP_IMP_H__
+
+#include "unicode/utypes.h"
+#include "unicode/ucasemap.h"
+#include "unicode/uchar.h"
+#include "ucase.h"
+
+/**
+ * Bit mask for the titlecasing iterator options bit field.
+ * Currently only 3 out of 8 values are used:
+ * 0 (words), U_TITLECASE_WHOLE_STRING, U_TITLECASE_SENTENCES.
+ * See stringoptions.h.
+ * @internal
+ */
+#define U_TITLECASE_ITERATOR_MASK 0xe0
+
+/**
+ * Bit mask for the titlecasing index adjustment options bit set.
+ * Currently two bits are defined:
+ * U_TITLECASE_NO_BREAK_ADJUSTMENT, U_TITLECASE_ADJUST_TO_CASED.
+ * See stringoptions.h.
+ * @internal
+ */
+#define U_TITLECASE_ADJUSTMENT_MASK 0x600
+
+/**
+ * Internal API, used by u_strcasecmp() etc.
+ * Compare strings case-insensitively,
+ * in code point order or code unit order.
+ */
+U_CFUNC int32_t
+u_strcmpFold(const UChar *s1, int32_t length1,
+             const UChar *s2, int32_t length2,
+             uint32_t options,
+             UErrorCode *pErrorCode);
+
+/**
+ * Internal API, used for detecting length of
+ * shared prefix case-insensitively.
+ * @param s1            input string 1
+ * @param length1       length of string 1, or -1 (NULL terminated)
+ * @param s2            input string 2
+ * @param length2       length of string 2, or -1 (NULL terminated)
+ * @param options       compare options
+ * @param matchLen1     (output) length of partial prefix match in s1
+ * @param matchLen2     (output) length of partial prefix match in s2
+ * @param pErrorCode    receives error status
+ */
+U_CAPI void
+u_caseInsensitivePrefixMatch(const UChar *s1, int32_t length1,
+                             const UChar *s2, int32_t length2,
+                             uint32_t options,
+                             int32_t *matchLen1, int32_t *matchLen2,
+                             UErrorCode *pErrorCode);
+
+#ifdef __cplusplus
+
+U_NAMESPACE_BEGIN
+
+class BreakIterator;        // unicode/brkiter.h
+class ByteSink;
+class Locale;               // unicode/locid.h
+
+/** Returns true if the options are valid. Otherwise false, and sets an error. */
+inline UBool ustrcase_checkTitleAdjustmentOptions(uint32_t options, UErrorCode &errorCode) {
+    if (U_FAILURE(errorCode)) { return false; }
+    if ((options & U_TITLECASE_ADJUSTMENT_MASK) == U_TITLECASE_ADJUSTMENT_MASK) {
+        // Both options together.
+        errorCode = U_ILLEGAL_ARGUMENT_ERROR;
+        return false;
+    }
+    return true;
+}
+
+inline UBool ustrcase_isLNS(UChar32 c) {
+    // Letter, number, symbol,
+    // or a private use code point because those are typically used as letters or numbers.
+    // Consider modifier letters only if they are cased.
+    const uint32_t LNS = (U_GC_L_MASK|U_GC_N_MASK|U_GC_S_MASK|U_GC_CO_MASK) & ~U_GC_LM_MASK;
+    int gc = u_charType(c);
+    return (U_MASK(gc) & LNS) != 0 || (gc == U_MODIFIER_LETTER && ucase_getType(c) != UCASE_NONE);
+}
+
+#if !UCONFIG_NO_BREAK_ITERATION
+
+/** Returns nullptr if error. Pass in either locale or locID, not both. */
+U_CFUNC
+BreakIterator *ustrcase_getTitleBreakIterator(
+        const Locale *locale, const char *locID, uint32_t options, BreakIterator *iter,
+        LocalPointer<BreakIterator> &ownedIter, UErrorCode &errorCode);
+
+#endif
+
+U_NAMESPACE_END
+
+#include "unicode/unistr.h"  // for UStringCaseMapper
+
+/*
+ * Internal string casing functions implementing
+ * ustring.h/ustrcase.cpp and UnicodeString case mapping functions.
+ */
+
+struct UCaseMap : public icu::UMemory {
+    /** Implements most of ucasemap_open(). */
+    UCaseMap(const char *localeID, uint32_t opts, UErrorCode *pErrorCode);
+    ~UCaseMap();
+
+#if !UCONFIG_NO_BREAK_ITERATION
+    icu::BreakIterator *iter;  /* We adopt the iterator, so we own it. */
+#endif
+    char locale[32];
+    int32_t caseLocale;
+    uint32_t options;
+};
+
+#if UCONFIG_NO_BREAK_ITERATION
+#   define UCASEMAP_BREAK_ITERATOR_PARAM
+#   define UCASEMAP_BREAK_ITERATOR_UNUSED
+#   define UCASEMAP_BREAK_ITERATOR
+#   define UCASEMAP_BREAK_ITERATOR_NULL
+#else
+#   define UCASEMAP_BREAK_ITERATOR_PARAM icu::BreakIterator *iter,
+#   define UCASEMAP_BREAK_ITERATOR_UNUSED icu::BreakIterator *,
+#   define UCASEMAP_BREAK_ITERATOR iter,
+#   define UCASEMAP_BREAK_ITERATOR_NULL NULL,
+#endif
+
+U_CFUNC int32_t
+ustrcase_getCaseLocale(const char *locale);
+
+// TODO: swap src / dest if approved for new public api
+/** Implements UStringCaseMapper. */
+U_CFUNC int32_t U_CALLCONV
+ustrcase_internalToLower(int32_t caseLocale, uint32_t options, UCASEMAP_BREAK_ITERATOR_PARAM
+                         UChar *dest, int32_t destCapacity,
+                         const UChar *src, int32_t srcLength,
+                         icu::Edits *edits,
+                         UErrorCode &errorCode);
+
+/** Implements UStringCaseMapper. */
+U_CFUNC int32_t U_CALLCONV
+ustrcase_internalToUpper(int32_t caseLocale, uint32_t options, UCASEMAP_BREAK_ITERATOR_PARAM
+                         UChar *dest, int32_t destCapacity,
+                         const UChar *src, int32_t srcLength,
+                         icu::Edits *edits,
+                         UErrorCode &errorCode);
+
+#if !UCONFIG_NO_BREAK_ITERATION
+
+/** Implements UStringCaseMapper. */
+U_CFUNC int32_t U_CALLCONV
+ustrcase_internalToTitle(int32_t caseLocale, uint32_t options,
+                         icu::BreakIterator *iter,
+                         UChar *dest, int32_t destCapacity,
+                         const UChar *src, int32_t srcLength,
+                         icu::Edits *edits,
+                         UErrorCode &errorCode);
+
+#endif
+
+/** Implements UStringCaseMapper. */
+U_CFUNC int32_t U_CALLCONV
+ustrcase_internalFold(int32_t caseLocale, uint32_t options, UCASEMAP_BREAK_ITERATOR_PARAM
+                      UChar *dest, int32_t destCapacity,
+                      const UChar *src, int32_t srcLength,
+                      icu::Edits *edits,
+                      UErrorCode &errorCode);
+
+/**
+ * Common string case mapping implementation for ucasemap_toXyz() and UnicodeString::toXyz().
+ * Implements argument checking.
+ */
+U_CFUNC int32_t
+ustrcase_map(int32_t caseLocale, uint32_t options, UCASEMAP_BREAK_ITERATOR_PARAM
+             UChar *dest, int32_t destCapacity,
+             const UChar *src, int32_t srcLength,
+             UStringCaseMapper *stringCaseMapper,
+             icu::Edits *edits,
+             UErrorCode &errorCode);
+
+/**
+ * Common string case mapping implementation for old-fashioned u_strToXyz() functions
+ * that allow the source string to overlap the destination buffer.
+ * Implements argument checking and internally works with an intermediate buffer if necessary.
+ */
+U_CFUNC int32_t
+ustrcase_mapWithOverlap(int32_t caseLocale, uint32_t options, UCASEMAP_BREAK_ITERATOR_PARAM
+                        UChar *dest, int32_t destCapacity,
+                        const UChar *src, int32_t srcLength,
+                        UStringCaseMapper *stringCaseMapper,
+                        UErrorCode &errorCode);
+
+/**
+ * UTF-8 string case mapping function type, used by ucasemap_mapUTF8().
+ * UTF-8 version of UStringCaseMapper.
+ * All error checking must be done.
+ * The UCaseMap must be fully initialized, with locale and/or iter set as needed.
+ */
+typedef void U_CALLCONV
+UTF8CaseMapper(int32_t caseLocale, uint32_t options,
+#if !UCONFIG_NO_BREAK_ITERATION
+               icu::BreakIterator *iter,
+#endif
+               const uint8_t *src, int32_t srcLength,
+               icu::ByteSink &sink, icu::Edits *edits,
+               UErrorCode &errorCode);
+
+#if !UCONFIG_NO_BREAK_ITERATION
+
+/** Implements UTF8CaseMapper. */
+U_CFUNC void U_CALLCONV
+ucasemap_internalUTF8ToTitle(int32_t caseLocale, uint32_t options,
+        icu::BreakIterator *iter,
+        const uint8_t *src, int32_t srcLength,
+        icu::ByteSink &sink, icu::Edits *edits,
+        UErrorCode &errorCode);
+
+#endif
+
+void
+ucasemap_mapUTF8(int32_t caseLocale, uint32_t options, UCASEMAP_BREAK_ITERATOR_PARAM
+                 const char *src, int32_t srcLength,
+                 UTF8CaseMapper *stringCaseMapper,
+                 icu::ByteSink &sink, icu::Edits *edits,
+                 UErrorCode &errorCode);
+
+/**
+ * Implements argument checking and buffer handling
+ * for UTF-8 string case mapping as a common function.
+ */
+int32_t
+ucasemap_mapUTF8(int32_t caseLocale, uint32_t options, UCASEMAP_BREAK_ITERATOR_PARAM
+                 char *dest, int32_t destCapacity,
+                 const char *src, int32_t srcLength,
+                 UTF8CaseMapper *stringCaseMapper,
+                 icu::Edits *edits,
+                 UErrorCode &errorCode);
+
+U_NAMESPACE_BEGIN
+namespace GreekUpper {
+
+// Data bits.
+static const uint32_t UPPER_MASK = 0x3ff;
+static const uint32_t HAS_VOWEL = 0x1000;
+static const uint32_t HAS_YPOGEGRAMMENI = 0x2000;
+static const uint32_t HAS_ACCENT = 0x4000;
+static const uint32_t HAS_DIALYTIKA = 0x8000;
+// Further bits during data building and processing, not stored in the data map.
+static const uint32_t HAS_COMBINING_DIALYTIKA = 0x10000;
+static const uint32_t HAS_OTHER_GREEK_DIACRITIC = 0x20000;
+
+static const uint32_t HAS_VOWEL_AND_ACCENT = HAS_VOWEL | HAS_ACCENT;
+static const uint32_t HAS_VOWEL_AND_ACCENT_AND_DIALYTIKA =
+        HAS_VOWEL_AND_ACCENT | HAS_DIALYTIKA;
+static const uint32_t HAS_EITHER_DIALYTIKA = HAS_DIALYTIKA | HAS_COMBINING_DIALYTIKA;
+
+// State bits.
+static const uint32_t AFTER_CASED = 1;
+static const uint32_t AFTER_VOWEL_WITH_ACCENT = 2;
+
+uint32_t getLetterData(UChar32 c);
+
+/**
+ * Returns a non-zero value for each of the Greek combining diacritics
+ * listed in The Unicode Standard, version 8, chapter 7.2 Greek,
+ * plus some perispomeni look-alikes.
+ */
+uint32_t getDiacriticData(UChar32 c);
+
+}  // namespace GreekUpper
+U_NAMESPACE_END
+
+#endif  // __cplusplus
+
+#endif  // __UCASEMAP_IMP_H__
diff --git a/src/third_party/icu/source/common/ucasemap_titlecase_brkiter.cpp b/src/third_party/icu/source/common/ucasemap_titlecase_brkiter.cpp
index 0622da1..d2e42c3 100644
--- a/src/third_party/icu/source/common/ucasemap_titlecase_brkiter.cpp
+++ b/src/third_party/icu/source/common/ucasemap_titlecase_brkiter.cpp
@@ -1,10 +1,12 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *   Copyright (C) 2011, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *******************************************************************************
 *   file name:  ucasemap_titlecase_brkiter.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -19,26 +21,84 @@
 
 #if !UCONFIG_NO_BREAK_ITERATION
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/brkiter.h"
 #include "unicode/ubrk.h"
+#include "unicode/casemap.h"
 #include "unicode/ucasemap.h"
 #include "cmemory.h"
 #include "ucase.h"
-#include "ustr_imp.h"
+#include "ucasemap_imp.h"
+
+U_NAMESPACE_BEGIN
+
+void CaseMap::utf8ToTitle(
+        const char *locale, uint32_t options, BreakIterator *iter,
+        StringPiece src, ByteSink &sink, Edits *edits,
+        UErrorCode &errorCode) {
+    if (U_FAILURE(errorCode)) {
+        return;
+    }
+    UText utext = UTEXT_INITIALIZER;
+    utext_openUTF8(&utext, src.data(), src.length(), &errorCode);
+    LocalPointer<BreakIterator> ownedIter;
+    iter = ustrcase_getTitleBreakIterator(nullptr, locale, options, iter, ownedIter, errorCode);
+    if (iter == nullptr) {
+        utext_close(&utext);
+        return;
+    }
+    iter->setText(&utext, errorCode);
+    ucasemap_mapUTF8(
+        ustrcase_getCaseLocale(locale), options, iter,
+        src.data(), src.length(),
+        ucasemap_internalUTF8ToTitle, sink, edits, errorCode);
+    utext_close(&utext);
+}
+
+int32_t CaseMap::utf8ToTitle(
+        const char *locale, uint32_t options, BreakIterator *iter,
+        const char *src, int32_t srcLength,
+        char *dest, int32_t destCapacity, Edits *edits,
+        UErrorCode &errorCode) {
+    if (U_FAILURE(errorCode)) {
+        return 0;
+    }
+    UText utext=UTEXT_INITIALIZER;
+    utext_openUTF8(&utext, src, srcLength, &errorCode);
+    LocalPointer<BreakIterator> ownedIter;
+    iter = ustrcase_getTitleBreakIterator(nullptr, locale, options, iter, ownedIter, errorCode);
+    if(iter==NULL) {
+        utext_close(&utext);
+        return 0;
+    }
+    iter->setText(&utext, errorCode);
+    int32_t length=ucasemap_mapUTF8(
+        ustrcase_getCaseLocale(locale), options, iter,
+        dest, destCapacity,
+        src, srcLength,
+        ucasemap_internalUTF8ToTitle, edits, errorCode);
+    utext_close(&utext);
+    return length;
+}
+
+U_NAMESPACE_END
 
 U_NAMESPACE_USE
 
 U_CAPI const UBreakIterator * U_EXPORT2
 ucasemap_getBreakIterator(const UCaseMap *csm) {
-    return csm->iter;
+    return reinterpret_cast<UBreakIterator *>(csm->iter);
 }
 
 U_CAPI void U_EXPORT2
-ucasemap_setBreakIterator(UCaseMap *csm, UBreakIterator *iterToAdopt, UErrorCode * /*pErrorCode*/) {
-    // Do not call ubrk_close() so that we do not depend on all of the BreakIterator code.
-    delete reinterpret_cast<BreakIterator *>(csm->iter);
-    csm->iter=iterToAdopt;
+ucasemap_setBreakIterator(UCaseMap *csm, UBreakIterator *iterToAdopt, UErrorCode *pErrorCode) {
+    if(U_FAILURE(*pErrorCode)) {
+        return;
+    }
+    delete csm->iter;
+    csm->iter=reinterpret_cast<BreakIterator *>(iterToAdopt);
 }
 
 U_CAPI int32_t U_EXPORT2
@@ -46,21 +106,30 @@
                      char *dest, int32_t destCapacity,
                      const char *src, int32_t srcLength,
                      UErrorCode *pErrorCode) {
+    if (U_FAILURE(*pErrorCode)) {
+        return 0;
+    }
     UText utext=UTEXT_INITIALIZER;
     utext_openUTF8(&utext, (const char *)src, srcLength, pErrorCode);
-    if(U_FAILURE(*pErrorCode)) {
+    if (U_FAILURE(*pErrorCode)) {
         return 0;
     }
     if(csm->iter==NULL) {
-        csm->iter=ubrk_open(UBRK_WORD, csm->locale,
-                            NULL, 0,
-                            pErrorCode);
+        LocalPointer<BreakIterator> ownedIter;
+        BreakIterator *iter = ustrcase_getTitleBreakIterator(
+            nullptr, csm->locale, csm->options, nullptr, ownedIter, *pErrorCode);
+        if (iter == nullptr) {
+            utext_close(&utext);
+            return 0;
+        }
+        csm->iter = ownedIter.orphan();
     }
-    ubrk_setUText(csm->iter, &utext, pErrorCode);
-    int32_t length=ucasemap_mapUTF8(csm,
-                   (uint8_t *)dest, destCapacity,
-                   (const uint8_t *)src, srcLength,
-                   ucasemap_internalUTF8ToTitle, pErrorCode);
+    csm->iter->setText(&utext, *pErrorCode);
+    int32_t length=ucasemap_mapUTF8(
+            csm->caseLocale, csm->options, csm->iter,
+            dest, destCapacity,
+            src, srcLength,
+            ucasemap_internalUTF8ToTitle, NULL, *pErrorCode);
     utext_close(&utext);
     return length;
 }
diff --git a/src/third_party/icu/source/common/ucat.c b/src/third_party/icu/source/common/ucat.cpp
similarity index 94%
rename from src/third_party/icu/source/common/ucat.c
rename to src/third_party/icu/source/common/ucat.cpp
index 5f6feb9..dac56ee 100644
--- a/src/third_party/icu/source/common/ucat.c
+++ b/src/third_party/icu/source/common/ucat.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
 * Copyright (c) 2003, International Business Machines
diff --git a/src/third_party/icu/source/common/uchar.c b/src/third_party/icu/source/common/uchar.cpp
similarity index 91%
rename from src/third_party/icu/source/common/uchar.c
rename to src/third_party/icu/source/common/uchar.cpp
index e88987d..bb5cf8a 100644
--- a/src/third_party/icu/source/common/uchar.c
+++ b/src/third_party/icu/source/common/uchar.cpp
@@ -1,6 +1,8 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ********************************************************************************
-*   Copyright (C) 1996-2014, International Business Machines
+*   Copyright (C) 1996-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 ********************************************************************************
 *
@@ -19,8 +21,10 @@
 ******************************************************************************
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/utypes.h"
 #include "unicode/uchar.h"
 #include "unicode/uscript.h"
@@ -40,15 +44,7 @@
 /* constants and macros for access to the data ------------------------------ */
 
 /* getting a uint32_t properties word from the data */
-#define GET_PROPS(c, result) ((result)=UTRIE2_GET16(&propsTrie, c));
-
-U_CFUNC UBool
-uprv_haveProperties(UErrorCode *pErrorCode) {
-    if(U_FAILURE(*pErrorCode)) {
-        return FALSE;
-    }
-    return TRUE;
-}
+#define GET_PROPS(c, result) ((result)=UTRIE2_GET16(&propsTrie, c))
 
 /* API functions ------------------------------------------------------------ */
 
@@ -68,6 +64,7 @@
 
 static uint32_t U_CALLCONV
 _enumTypeValue(const void *context, uint32_t value) {
+    (void)context;
     return GET_CATEGORY(value);
 }
 
@@ -436,7 +433,7 @@
         }
 
         return numValue;
-    } else if(ntv<UPROPS_NTV_RESERVED_START) {
+    } else if(ntv<UPROPS_NTV_FRACTION20_START) {
         /* sexagesimal (base 60) integer */
         int32_t numValue=(ntv>>2)-0xbf;
         int32_t exp=(ntv&3)+1;
@@ -460,6 +457,18 @@
         }
 
         return numValue;
+    } else if(ntv<UPROPS_NTV_FRACTION32_START) {
+        // fraction-20 e.g. 3/80
+        int32_t frac20=ntv-UPROPS_NTV_FRACTION20_START;  // 0..0x17
+        int32_t numerator=2*(frac20&3)+1;
+        int32_t denominator=20<<(frac20>>2);
+        return (double)numerator/denominator;
+    } else if(ntv<UPROPS_NTV_RESERVED_START) {
+        // fraction-32 e.g. 3/64
+        int32_t frac32=ntv-UPROPS_NTV_FRACTION32_START;  // 0..15
+        int32_t numerator=2*(frac32&3)+1;
+        int32_t denominator=32<<(frac32>>2);
+        return (double)numerator/denominator;
     } else {
         /* reserved */
         return U_NO_NUMERIC_VALUE;
@@ -551,7 +560,6 @@
 
 U_CAPI UScriptCode U_EXPORT2
 uscript_getScript(UChar32 c, UErrorCode *pErrorCode) {
-    uint32_t scriptX;
     if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
         return USCRIPT_INVALID_CODE;
     }
@@ -559,48 +567,46 @@
         *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
         return USCRIPT_INVALID_CODE;
     }
-    scriptX=u_getUnicodeProperties(c, 0)&UPROPS_SCRIPT_X_MASK;
+    uint32_t scriptX=u_getUnicodeProperties(c, 0)&UPROPS_SCRIPT_X_MASK;
+    uint32_t codeOrIndex=uprops_mergeScriptCodeOrIndex(scriptX);
     if(scriptX<UPROPS_SCRIPT_X_WITH_COMMON) {
-        return (UScriptCode)scriptX;
+        return (UScriptCode)codeOrIndex;
     } else if(scriptX<UPROPS_SCRIPT_X_WITH_INHERITED) {
         return USCRIPT_COMMON;
     } else if(scriptX<UPROPS_SCRIPT_X_WITH_OTHER) {
         return USCRIPT_INHERITED;
     } else {
-        return (UScriptCode)scriptExtensions[scriptX&UPROPS_SCRIPT_MASK];
+        return (UScriptCode)scriptExtensions[codeOrIndex];
     }
 }
 
 U_CAPI UBool U_EXPORT2
 uscript_hasScript(UChar32 c, UScriptCode sc) {
-    const uint16_t *scx;
     uint32_t scriptX=u_getUnicodeProperties(c, 0)&UPROPS_SCRIPT_X_MASK;
+    uint32_t codeOrIndex=uprops_mergeScriptCodeOrIndex(scriptX);
     if(scriptX<UPROPS_SCRIPT_X_WITH_COMMON) {
-        return sc==(UScriptCode)scriptX;
+        return sc==(UScriptCode)codeOrIndex;
     }
 
-    scx=scriptExtensions+(scriptX&UPROPS_SCRIPT_MASK);
+    const uint16_t *scx=scriptExtensions+codeOrIndex;
     if(scriptX>=UPROPS_SCRIPT_X_WITH_OTHER) {
         scx=scriptExtensions+scx[1];
     }
-    if(sc>=USCRIPT_CODE_LIMIT) {
+    uint32_t sc32=sc;
+    if(sc32>0x7fff) {
         /* Guard against bogus input that would make us go past the Script_Extensions terminator. */
         return FALSE;
     }
-    while(sc>*scx) {
+    while(sc32>*scx) {
         ++scx;
     }
-    return sc==(*scx&0x7fff);
+    return sc32==(*scx&0x7fff);
 }
 
 U_CAPI int32_t U_EXPORT2
 uscript_getScriptExtensions(UChar32 c,
                             UScriptCode *scripts, int32_t capacity,
                             UErrorCode *pErrorCode) {
-    uint32_t scriptX;
-    int32_t length;
-    const uint16_t *scx;
-    uint16_t sx;
     if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
         return 0;
     }
@@ -608,21 +614,23 @@
         *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
         return 0;
     }
-    scriptX=u_getUnicodeProperties(c, 0)&UPROPS_SCRIPT_X_MASK;
+    uint32_t scriptX=u_getUnicodeProperties(c, 0)&UPROPS_SCRIPT_X_MASK;
+    uint32_t codeOrIndex=uprops_mergeScriptCodeOrIndex(scriptX);
     if(scriptX<UPROPS_SCRIPT_X_WITH_COMMON) {
         if(capacity==0) {
             *pErrorCode=U_BUFFER_OVERFLOW_ERROR;
         } else {
-            scripts[0]=(UScriptCode)scriptX;
+            scripts[0]=(UScriptCode)codeOrIndex;
         }
         return 1;
     }
 
-    scx=scriptExtensions+(scriptX&UPROPS_SCRIPT_MASK);
+    const uint16_t *scx=scriptExtensions+codeOrIndex;
     if(scriptX>=UPROPS_SCRIPT_X_WITH_OTHER) {
         scx=scriptExtensions+scx[1];
     }
-    length=0;
+    int32_t length=0;
+    uint16_t sx;
     do {
         sx=*scx++;
         if(length<capacity) {
@@ -648,6 +656,8 @@
     /* add the start code point to the USet */
     const USetAdder *sa=(const USetAdder *)context;
     sa->add(sa->set, start);
+    (void)end;
+    (void)value;
     return TRUE;
 }
 
@@ -720,8 +730,5 @@
     }
 
     /* add the start code point of each same-value range of the properties vectors trie */
-    if(propsVectorsColumns>0) {
-        /* if propsVectorsColumns==0 then the properties vectors trie may not be there at all */
-        utrie2_enum(&propsVectorsTrie, NULL, _enumPropertyStartsRange, sa);
-    }
+    utrie2_enum(&propsVectorsTrie, NULL, _enumPropertyStartsRange, sa);
 }
diff --git a/src/third_party/icu/source/common/uchar_props_data.h b/src/third_party/icu/source/common/uchar_props_data.h
index 40e0af2..9a78918 100644
--- a/src/third_party/icu/source/common/uchar_props_data.h
+++ b/src/third_party/icu/source/common/uchar_props_data.h
@@ -1,155 +1,156 @@
-/*
- * Copyright (C) 1999-2016, International Business Machines
- * Corporation and others.  All Rights Reserved.
- *
- * file name: uchar_props_data.h
- *
- * machine-generated by: icu/tools/unicode/c/genprops/corepropsbuilder.cpp
- */
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+//
+// Copyright (C) 1999-2016, International Business Machines
+// Corporation and others.  All Rights Reserved.
+//
+// file name: uchar_props_data.h
+//
+// machine-generated by: icu/tools/unicode/c/genprops/corepropsbuilder.cpp
 
-#ifndef INCLUDED_FROM_UCHAR_C
-#   error This file must be #included from uchar.c only.
-#endif
 
-static const UVersionInfo dataVersion={8,0,0,0};
+#ifdef INCLUDED_FROM_UCHAR_C
 
-static const uint16_t propsTrie_index[19820]={
-0x41e,0x426,0x42e,0x436,0x44e,0x456,0x45e,0x466,0x46e,0x476,0x47c,0x484,0x48c,0x494,0x49c,0x4a4,
-0x4aa,0x4b2,0x4ba,0x4c2,0x4c5,0x4cd,0x4d5,0x4dd,0x4e5,0x4ed,0x4e9,0x4f1,0x4f9,0x501,0x506,0x50e,
-0x516,0x51e,0x522,0x52a,0x532,0x53a,0x542,0x54a,0x546,0x54e,0x553,0x55b,0x561,0x569,0x571,0x579,
-0x581,0x589,0x591,0x599,0x59e,0x5a6,0x5a9,0x5b1,0x5b9,0x5c1,0x5c7,0x5cf,0x5ce,0x5d6,0x5de,0x5e6,
-0x5f6,0x5ee,0x5fe,0x43e,0x43e,0x60e,0x43e,0x606,0x61e,0x620,0x628,0x616,0x638,0x63e,0x646,0x630,
-0x656,0x65c,0x664,0x64e,0x674,0x67a,0x682,0x66c,0x692,0x698,0x6a0,0x68a,0x6b0,0x6b8,0x6c0,0x6a8,
-0x6d0,0x6d6,0x6de,0x6c8,0x6ee,0x6f4,0x6fc,0x6e6,0x6ee,0x70b,0x713,0x704,0x723,0x72a,0x732,0x71b,
-0x5ca,0x73a,0x742,0x43e,0x74a,0x752,0x75a,0x43e,0x762,0x76a,0x772,0x777,0x77f,0x786,0x78e,0x43e,
-0x589,0x796,0x79e,0x7a6,0x7ae,0x516,0x7be,0x7b6,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x7c4,0x589,0x7cc,0x7c2,0x7d4,0x589,0x7d0,0x589,0x7da,0x7e2,0x7ea,0x516,0x516,0x7f2,
-0x7fa,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x7ff,0x807,0x589,0x589,0x80f,0x817,0x81f,0x827,0x82f,0x589,0x837,0x83f,0x847,
-0x857,0x589,0x85f,0x861,0x589,0x84f,0x589,0x869,0x87d,0x871,0x879,0x885,0x589,0x88d,0x893,0x89b,
-0x8a3,0x589,0x8b3,0x8bb,0x8c3,0x8ab,0x43e,0x43e,0x8d3,0x8d6,0x8de,0x8cb,0x8ee,0x8e6,0x589,0x8f5,
-0x589,0x904,0x8fd,0x90c,0x43e,0x43e,0x914,0x91c,0x4be,0x924,0x927,0x92d,0x934,0x927,0x4e5,0x93c,
-0x46e,0x46e,0x46e,0x46e,0x944,0x46e,0x46e,0x46e,0x954,0x95c,0x964,0x96c,0x974,0x978,0x980,0x94c,
-0x998,0x9a0,0x988,0x990,0x9a8,0x9b0,0x9b8,0x9c0,0x9d8,0x9c8,0x9d0,0x9e0,0x9e8,0x9f7,0x9fc,0x9ef,
-0xa04,0xa04,0xa04,0xa04,0xa04,0xa04,0xa04,0xa04,0xa0c,0xa14,0x89b,0xa17,0xa1f,0xa26,0xa2b,0xa33,
-0x89b,0xa38,0xa37,0xa48,0xa4b,0x89b,0x89b,0xa40,0x89b,0x89b,0x89b,0x89b,0x89b,0xa5a,0xa62,0xa52,
-0x89b,0x89b,0x89b,0xa67,0x89b,0x89b,0x89b,0x89b,0x89b,0x89b,0x89b,0xa6d,0xa75,0x89b,0xa7d,0xa84,
-0x89b,0x89b,0x89b,0x89b,0x89b,0x89b,0x89b,0x89b,0xa04,0xa04,0xa04,0xa04,0xa8c,0xa04,0xa93,0xa9a,
-0xa04,0xa04,0xa04,0xa04,0xa04,0xa04,0xa04,0xa04,0x89b,0xaa2,0xaa9,0xaad,0xab3,0xab9,0xac1,0xac6,
-0x516,0xad6,0xace,0xade,0x46e,0x46e,0x46e,0xae6,0x4be,0xaee,0x589,0xaf4,0xb04,0xafc,0xafc,0x4e5,
-0xb0c,0xb14,0xb1c,0x43e,0xb24,0x89b,0x89b,0xb2b,0x89b,0x89b,0x89b,0x89b,0x89b,0x89b,0xb33,0xb39,
-0xb49,0xb41,0x5ca,0x589,0xb51,0x7fa,0x589,0xb59,0xb61,0xb66,0x589,0x589,0xb6b,0x575,0x89b,0xb72,
-0xb7a,0xb82,0xb88,0x89b,0xb82,0xb90,0x89b,0xb7a,0x89b,0x89b,0x89b,0x89b,0x89b,0x89b,0x89b,0x89b,
-0xb98,0x589,0x589,0x589,0xba0,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0xba6,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0xbab,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x869,0x89b,0x89b,
-0xbb3,0x589,0xbb6,0x589,0xbbe,0xbc4,0xbcc,0xbd4,0xbd9,0x589,0x589,0xbdd,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0xbe4,0x589,0xbeb,0xbf1,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0xbf9,0x589,0x589,0x589,0xc01,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0xc03,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0xc0a,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0xc11,0x589,0x589,0x589,0xc18,0xc20,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0xc25,0x589,0x589,0xc2d,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0xc31,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0xc34,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0xc37,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0xc3d,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0xc45,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0xc4a,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0xc4f,0x589,0x589,0x589,0xc54,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0xc5c,0xc63,0xc67,0x589,0x589,0x589,0xc6e,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x869,0x43e,
-0xc7c,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0xc74,0x89b,0xc84,0x90c,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0xc89,0xc91,0x46e,0xca1,0xc99,0x589,0x589,0xca9,0xcb1,0xcc1,0x46e,0xcc6,0xcce,0xcd4,0x43e,0xcb9,
-0xcdc,0xce4,0x589,0xcec,0xcfc,0xcff,0xcf4,0xd07,0x5de,0xd0f,0xd16,0xd1e,0x61e,0xd2e,0xd26,0xd36,
-0x589,0xd3e,0xd46,0xd4e,0x589,0xd56,0xd5e,0xd66,0xd6e,0xd76,0xd7a,0xd82,0x4be,0x4be,0x589,0xd8a,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0xd92,0xd99,0x860,
-0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,
-0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,
-0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,
-0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,
-0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,
-0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,
-0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,
-0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,
-0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,
-0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,
-0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,
-0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,
-0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,
-0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,
-0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,
-0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,
-0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0x589,0x589,0x589,0xdb1,0x589,0xc6f,0xdb8,0xdbd,
-0x589,0x589,0x589,0xdc5,0x589,0x589,0xdc9,0x43e,0xde1,0xdd1,0xdd9,0x589,0x589,0xde9,0xdf1,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0xdf6,0xdfe,0x589,0xe02,0x589,0xe08,0xe0c,
-0xe14,0xe1c,0xe23,0xe2b,0x589,0x589,0x589,0xe31,0xe49,0x42e,0xe51,0xe59,0xe5e,0x87d,0xe39,0xe41,
-0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,
-0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,
-0x10f8,0x10f8,0x1138,0x1178,0x11b8,0x11f0,0x1230,0x1270,0x12a8,0x12e8,0x1314,0x1354,0x1394,0x13a4,0x13e4,0x1418,
-0x1458,0x1488,0x14c8,0x1508,0x1518,0x154c,0x1584,0x15c4,0x1604,0x1644,0x1678,0x16a4,0x16e4,0x171c,0x1738,0x1778,
-0xa80,0xac0,0xb00,0xb3b,0xb7b,0xa40,0xbbb,0xa40,0xbdd,0xa40,0xa40,0xa40,0xa40,0xc1d,0xa40,0xa40,
-0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xc5d,0xc7d,0xa40,0xa40,0xcbd,0xcfd,0xa40,0xd3d,0xd7d,0xdbd,
-0xdfd,0xe34,0x1db,0x1db,0xe58,0xe8c,0x1db,0xeb4,0x1db,0x1db,0x1db,0x1db,0xee1,0x1db,0x1db,0x1db,
-0x1db,0x1db,0x1db,0x1db,0xef5,0x1db,0xf2d,0xf6d,0x1db,0xf78,0xa40,0xa40,0xa40,0xa40,0xa40,0xfb8,
+static const UVersionInfo dataVersion={0xd,0,0,0};
+
+static const uint16_t propsTrie_index[22276]={
+0x46d,0x475,0x47d,0x485,0x49d,0x4a5,0x4ad,0x4b5,0x4bd,0x4c5,0x4cb,0x4d3,0x4db,0x4e3,0x4eb,0x4f3,
+0x4f9,0x501,0x509,0x511,0x514,0x51c,0x524,0x52c,0x534,0x53c,0x538,0x540,0x548,0x550,0x555,0x55d,
+0x565,0x56d,0x571,0x579,0x581,0x589,0x591,0x599,0x595,0x59d,0x5a2,0x5aa,0x5b0,0x5b8,0x5c0,0x5c8,
+0x5d0,0x5d8,0x5e0,0x5e8,0x5ed,0x5f5,0x5f8,0x600,0x608,0x610,0x616,0x61e,0x61d,0x625,0x62d,0x635,
+0x645,0x63d,0x64d,0x655,0x48d,0x665,0x66b,0x65d,0x67b,0x67d,0x685,0x673,0x695,0x69b,0x6a3,0x68d,
+0x6b3,0x6b9,0x6c1,0x6ab,0x6d1,0x6d7,0x6df,0x6c9,0x6ef,0x6f5,0x6fd,0x6e7,0x70d,0x715,0x71d,0x705,
+0x72d,0x733,0x73b,0x725,0x74b,0x751,0x759,0x743,0x769,0x76e,0x776,0x761,0x786,0x78d,0x795,0x77e,
+0x619,0x79d,0x7a5,0x48d,0x7ad,0x7b4,0x7bc,0x48d,0x7c4,0x7cc,0x7d4,0x7d9,0x7e1,0x7e8,0x7f0,0x48d,
+0x5d8,0x7f8,0x800,0x808,0x810,0x565,0x820,0x818,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x828,0x5d8,0x830,0x834,0x83c,0x5d8,0x842,0x5d8,0x848,0x850,0x858,0x565,0x565,0x860,
+0x868,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x86d,0x875,0x5d8,0x5d8,0x87d,0x885,0x88d,0x895,0x89d,0x5d8,0x8a5,0x8ad,0x8b5,
+0x8c5,0x5d8,0x8cd,0x8cf,0x8d7,0x8bd,0x5d8,0x8da,0x8ee,0x8e2,0x8ea,0x8f6,0x5d8,0x8fe,0x904,0x90c,
+0x914,0x5d8,0x924,0x92c,0x934,0x91c,0x944,0x48d,0x94c,0x94f,0x957,0x93c,0x967,0x95f,0x5d8,0x96e,
+0x5d8,0x97d,0x976,0x985,0x98d,0x991,0x999,0x9a1,0x50d,0x9a9,0x9ac,0x9b2,0x9b9,0x9ac,0x534,0x9c1,
+0x4bd,0x4bd,0x4bd,0x4bd,0x9c9,0x4bd,0x4bd,0x4bd,0x9d9,0x9e1,0x9e9,0x9f1,0x9f9,0x9fd,0xa05,0x9d1,
+0xa1d,0xa25,0xa0d,0xa15,0xa2d,0xa35,0xa3d,0xa45,0xa5d,0xa4d,0xa55,0xa65,0xa6d,0xa7c,0xa81,0xa74,
+0xa89,0xa89,0xa89,0xa89,0xa89,0xa89,0xa89,0xa89,0xa91,0xa99,0x90c,0xa9c,0xaa4,0xaab,0xab0,0xab8,
+0x90c,0xabf,0xabe,0xacf,0xad2,0x90c,0x90c,0xac7,0x90c,0x90c,0x90c,0x90c,0x90c,0xae1,0xae9,0xad9,
+0x90c,0x90c,0x90c,0xaee,0x90c,0x90c,0x90c,0x90c,0x90c,0x90c,0x90c,0xaf4,0xafc,0x90c,0xb04,0xb0b,
+0x90c,0x90c,0x90c,0x90c,0x90c,0x90c,0x90c,0x90c,0xa89,0xa89,0xa89,0xa89,0xb13,0xa89,0xb1a,0xb21,
+0xa89,0xa89,0xa89,0xa89,0xa89,0xa89,0xa89,0xa89,0x90c,0xb29,0xb30,0xb34,0xb3a,0x90c,0x90c,0x90c,
+0x565,0xb4a,0xb42,0xb52,0x4bd,0x4bd,0x4bd,0xb5a,0x50d,0xb62,0x5d8,0xb68,0xb78,0xb70,0xb70,0x534,
+0xb80,0xb88,0xb90,0x48d,0xb98,0x90c,0x90c,0xb9f,0x90c,0x90c,0x90c,0x90c,0x90c,0x90c,0xba7,0xbad,
+0xbbd,0xbb5,0x619,0x5d8,0xbc5,0x868,0x5d8,0xbcd,0xbd5,0xbd9,0x5d8,0x5d8,0xbde,0x5d8,0x90c,0xbe5,
+0xab9,0xbed,0xbf3,0x90c,0xbed,0xbfb,0x90c,0x90c,0x90c,0x90c,0x90c,0x90c,0x90c,0x90c,0x90c,0x90c,
+0xc03,0x5d8,0x5d8,0x5d8,0xc0b,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0xc11,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0xc16,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x90c,0x90c,
+0xc1e,0x5d8,0xc21,0x5d8,0xc29,0xc2f,0xc37,0xc3f,0xc44,0x5d8,0x5d8,0xc48,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0xc4f,0x5d8,0xc56,0xc5c,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0xc64,0x5d8,0x5d8,0x5d8,0xc6c,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0xc6e,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0xc75,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0xc7c,0x5d8,0x5d8,0x5d8,0xc83,0xc8b,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0xc90,0x5d8,0x5d8,0xc98,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0xc9c,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0xc9f,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0xca2,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0xca8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0xcb0,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0xcb5,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0xcba,0x5d8,0x5d8,0x5d8,0xcbf,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0xcc7,0xcce,0xcd2,0x5d8,0x5d8,0x5d8,0xcd9,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x8ce,
+0xce7,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0xcdf,0x90c,0xcef,0x985,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0xcf4,0xcfc,0x4bd,0xd0c,0xd04,0x5d8,0x5d8,0xd14,0xd1c,0xd2c,0x4bd,0xd31,0xd39,0xd3f,0xd47,0xd24,
+0xd4f,0xd57,0x5d8,0xd5f,0xd6f,0xd72,0xd67,0xd7a,0x62d,0xd82,0xd89,0x8ce,0x67b,0xd99,0xd91,0xda1,
+0x5d8,0xda9,0xdb1,0xdb9,0x5d8,0xdc1,0xdc9,0xdd1,0xdd9,0xde1,0xde5,0xded,0x50d,0x50d,0x5d8,0xdf5,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0xdfd,0xe09,0xe01,
+0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,
+0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,
+0xe11,0xe11,0xe11,0xe11,0xe11,0xe11,0xe11,0xe11,0xe11,0xe11,0xe11,0xe11,0xe11,0xe11,0xe11,0xe11,
+0xe11,0xe11,0xe11,0xe11,0xe11,0xe11,0xe11,0xe11,0xe11,0xe11,0xe11,0xe11,0xe11,0xe11,0xe11,0xe11,
+0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,
+0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,
+0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,
+0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,
+0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,
+0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,
+0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,
+0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,
+0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,
+0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,
+0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,
+0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,
+0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0x5d8,0x5d8,0x5d8,0xe21,0x5d8,0xcda,0xe28,0xe2d,
+0x5d8,0x5d8,0x5d8,0xe35,0x5d8,0x5d8,0x8d9,0x48d,0xe4b,0xe3b,0xe43,0x5d8,0x5d8,0xe53,0xe5b,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0xe60,0xe68,0x5d8,0xe6c,0x5d8,0xe72,0xe76,
+0xe7e,0xe86,0xe8d,0xe95,0x5d8,0x5d8,0x5d8,0xe9b,0xeb3,0x47d,0xebb,0xec3,0xec8,0x8ee,0xea3,0xeab,
+0xe11,0xe11,0xe11,0xe11,0xe11,0xe11,0xe11,0xe11,0xe11,0xe11,0xe11,0xe11,0xe11,0xe11,0xe11,0xe11,
+0xe11,0xe11,0xe11,0xe11,0xe11,0xe11,0xe11,0xe11,0xe11,0xe11,0xe11,0xe11,0xe11,0xe11,0xe11,0xe11,
+0x1234,0x1234,0x1274,0x12b4,0x12f4,0x132c,0x136c,0x13ac,0x13e4,0x1424,0x1450,0x1490,0x14d0,0x14e0,0x1520,0x1554,
+0x1594,0x15c4,0x1604,0x1644,0x1654,0x1688,0x16c0,0x1700,0x1740,0x1780,0x17b4,0x17e0,0x1820,0x1858,0x1874,0x18b4,
+0xa80,0xac0,0xb00,0xb40,0xb80,0xa40,0xbc0,0xa40,0xbe2,0xa40,0xa40,0xa40,0xa40,0xc22,0x1db,0x1db,
+0xc62,0xca2,0xa40,0xa40,0xa40,0xa40,0xce2,0xd02,0xa40,0xa40,0xd42,0xd82,0xdc2,0xe02,0xe42,0xe82,
+0xec2,0xef9,0x1db,0x1db,0xf1d,0xf51,0x1db,0xf79,0x1db,0x1db,0x1db,0x1db,0xfa6,0x1db,0x1db,0x1db,
+0x1db,0x1db,0x1db,0x1db,0xfba,0x1db,0xff2,0x1032,0x1db,0x103d,0x1db,0x1db,0x1db,0x1073,0xa40,0x10b3,
+0x1db,0x1db,0x10f3,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
 0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
 0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
 0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
@@ -171,541 +172,569 @@
 0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
 0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
 0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
-0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
-0xff8,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
+0x1133,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
 0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
 0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,
-0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x1038,
+0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x1173,
 0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,
-0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x1038,
-0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,
-0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,
-0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,
-0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,
-0xe66,0xe6d,0xe75,0x43e,0x589,0x589,0x589,0x575,0xe85,0xe7d,0xe9c,0xe8d,0xe94,0xea4,0xb20,0xeac,
-0x43e,0x43e,0x43e,0x43e,0xd1e,0x589,0xeb4,0xebc,0x589,0xec4,0xecc,0xed0,0xed8,0x589,0xee0,0x43e,
-0x516,0x520,0xee8,0x589,0xeec,0xef4,0x43e,0x43e,0x589,0x865,0x589,0xefc,0x43e,0x43e,0x43e,0x43e,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0xb04,0x869,0xe08,0x43e,0x43e,0x43e,0x43e,
-0xf0c,0xf04,0xf0f,0xf17,0x87d,0xf1f,0x43e,0xf27,0xf2f,0xf37,0x43e,0x43e,0x589,0xf47,0xf4f,0xf3f,
-0xf5f,0xf66,0xf57,0xf6e,0xf76,0x43e,0xf86,0xf7e,0x589,0xf89,0xf91,0xf99,0xfa1,0xfa9,0x43e,0x43e,
-0x589,0x589,0xfb1,0x43e,0x516,0xfb9,0x4be,0xfc1,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,
-0x43e,0x43e,0x43e,0xfc9,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,
-0xfd9,0x5bf,0xfe1,0xfd1,0x8ee,0xfe9,0xff1,0xff7,0x100f,0xfff,0x1007,0x1013,0x8ee,0x1023,0x101b,0x102b,
-0x103b,0x1033,0x43e,0x43e,0x1042,0x104a,0x5e1,0x1052,0x1062,0x67a,0x106a,0x105a,0x43e,0x43e,0x43e,0x43e,
-0x43e,0x43e,0x43e,0x43e,0x589,0x1072,0x107a,0x43e,0x43e,0x43e,0x43e,0x43e,0x589,0x1082,0x108a,0x43e,
-0x589,0x1092,0x109a,0x43e,0x589,0x10a2,0xef4,0x43e,0x10b2,0x10aa,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,
-0x516,0x4be,0x10ba,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,
-0x43e,0x589,0x10c2,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,
-0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,
-0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0xdc9,0x43e,0x43e,0x43e,0x10d2,0x10da,0x10e2,0x10ca,0x589,
-0x589,0x589,0x589,0x589,0x589,0x10ea,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,
-0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x10f2,0x43e,0x43e,0x43e,
-0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,
-0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x10f4,
-0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x10c2,0x87d,
-0x10fc,0x43e,0x43e,0xdfe,0x1104,0x589,0x1114,0x111c,0x1124,0x110c,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,
-0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,
-0x43e,0x43e,0x43e,0x43e,0x43e,0x589,0x589,0x112c,0x1131,0x1139,0x43e,0x43e,0x43e,0x1141,0x43e,0x43e,
-0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,
-0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,
-0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,
-0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x589,0x589,0x589,
-0x1149,0x114e,0x1156,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,
-0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x89b,0x89b,0x89b,
-0x89b,0x89b,0x89b,0x89b,0xb33,0x89b,0x115e,0x89b,0x1165,0x116d,0x1173,0x89b,0x1179,0x89b,0x89b,0x1181,
-0x43e,0x43e,0x43e,0x43e,0x43e,0x89b,0x89b,0xa34,0x1189,0x43e,0x43e,0x43e,0x43e,0x1199,0x11a0,0x11a5,
-0x11ab,0x11b3,0x11bb,0x11c3,0x119d,0x11cb,0x11d3,0x11db,0x11e0,0x11b2,0x1199,0x11a0,0x119c,0x11ab,0x11e8,0x119a,
-0x11eb,0x119d,0x11f3,0x11fb,0x1203,0x120a,0x11f6,0x11fe,0x1206,0x120d,0x11f9,0x1215,0x1191,0x89b,0x89b,0x89b,
-0x89b,0x89b,0x89b,0x89b,0x89b,0x89b,0x89b,0x89b,0x89b,0x89b,0x89b,0x89b,0x89b,0x4e5,0x1225,0x4e5,
-0x122c,0x1233,0x121d,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,
-0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,
-0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x589,0x589,0x589,
-0x589,0x589,0x589,0x123b,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,
-0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,
-0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x1249,0x1251,0x1259,
-0x1261,0x1269,0x1271,0x43e,0x1241,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x89b,0x1279,0x89b,
-0x89b,0xb2b,0x127e,0x1282,0xb33,0x128a,0x128f,0x89b,0x1279,0x1293,0x43e,0x43e,0x129a,0x12a2,0x1293,0x12a8,
-0x43e,0x43e,0x43e,0x43e,0x43e,0x89b,0x89b,0x89b,0x89b,0x89b,0x89b,0x89b,0x12b0,0x89b,0x89b,0x89b,
-0x89b,0x89b,0x89b,0x89b,0x89b,0x89b,0x89b,0x89b,0xb24,0x89b,0x12b8,0x89b,0x89b,0x89b,0x89b,0x89b,
-0x89b,0x89b,0x89b,0x1177,0x12bd,0x89b,0x89b,0x89b,0xb2b,0x89b,0x89b,0x12c5,0x43e,0x1279,0x89b,0x12cd,
-0x89b,0x12d5,0xb35,0x43e,0x43e,0x12dd,0x43e,0x43e,0x43e,0x12e2,0x43e,0xea4,0x43e,0x43e,0x43e,0x43e,
-0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,
-0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,
-0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x12ea,0x589,0x589,
-0x12f1,0x589,0x589,0x589,0x12f9,0x589,0x1301,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0xc15,0x589,0x589,
-0x1309,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x1311,0x1319,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0xc54,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x1320,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x1327,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x132e,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0xb04,0x43e,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x60e,0x589,0x589,0x589,0x589,0x589,0x589,0xeec,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x1141,0x43e,0x43e,
-0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x589,0x589,0x589,0x589,0x1332,0x589,0x589,0x589,
-0x589,0x589,0x589,0x589,0x589,0x589,0x589,0x589,0xeec,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,
-0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,
-0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,
-0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x1342,0x133a,0x133a,0x133a,0x43e,0x43e,0x43e,0x43e,
-0x4e5,0x4e5,0x4e5,0x4e5,0x4e5,0x4e5,0x4e5,0x134a,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,
-0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,
-0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,
-0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,
-0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,
-0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,
-0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,
-0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0xda9,0x1352,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,
+0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x1173,
+0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,
+0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,
+0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,
+0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,
+0xed0,0xed7,0xedf,0x48d,0x5d8,0x5d8,0x5d8,0xee7,0xef7,0xeef,0xf0e,0xeff,0xf06,0xf16,0xf1a,0xf1e,
+0x48d,0x48d,0x48d,0x48d,0x8ce,0x5d8,0xf26,0xf2e,0x5d8,0xf36,0xf3e,0xf42,0xf4a,0x5d8,0xf52,0x48d,
+0x565,0x56f,0xf5a,0x5d8,0xf5e,0xf66,0xf76,0xf6e,0x5d8,0xf7e,0x5d8,0xf85,0x48d,0x48d,0x48d,0x48d,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0xb78,0x8da,0xe72,0x48d,0x48d,0x48d,0x48d,
+0xf95,0xf8d,0xf98,0xfa0,0x8ee,0xfa8,0x48d,0xfb0,0xfb8,0xfc0,0x48d,0x48d,0x5d8,0xfd0,0xfd8,0xfc8,
+0xfe8,0xfef,0xfe0,0xff7,0xfff,0x48d,0x100f,0x1007,0x5d8,0x1012,0x101a,0x1022,0x102a,0x1032,0x48d,0x48d,
+0x5d8,0x5d8,0x103a,0x48d,0x565,0x1042,0x50d,0x104a,0x5d8,0x1052,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,
+0x48d,0x48d,0x48d,0x105a,0x5d8,0x1062,0x48d,0x48d,0x106a,0x1072,0x1079,0x48d,0x48d,0xe68,0x1081,0xb78,
+0x1091,0x60e,0x1099,0x1089,0x967,0x10a1,0x10a9,0x10af,0x10c7,0x10b7,0x10bf,0x10cb,0x967,0x10db,0x10d3,0x10e3,
+0x10f3,0x10eb,0x48d,0x48d,0x10fa,0x1102,0x630,0x110a,0x111a,0x1120,0x1128,0x1112,0x48d,0x48d,0x48d,0x48d,
+0x5d8,0x1130,0x1138,0x1140,0x5d8,0x1148,0x1150,0x48d,0x48d,0x48d,0x48d,0x48d,0x5d8,0x1158,0x1160,0x48d,
+0x5d8,0x1168,0x1170,0x1178,0x5d8,0x1188,0x1180,0x48d,0x848,0x1190,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,
+0x5d8,0x1198,0x48d,0x48d,0x48d,0x565,0x50d,0x11a0,0x11b0,0x11b6,0x11a8,0x48d,0x48d,0x11c6,0x11ca,0x11be,
+0x11e2,0x11d2,0x11da,0x5d8,0x11f2,0x11ea,0x5d8,0x8cf,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,
+0x1208,0x120d,0x11fa,0x1202,0x121d,0x1215,0x48d,0x48d,0x122c,0x1230,0x1224,0x1240,0x1238,0x1180,0x48d,0x48d,
+0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x1244,0x48d,0x48d,0x48d,0x48d,0x48d,0x124b,0x125b,0x1253,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x8d9,0x48d,0x48d,0x48d,
+0x126b,0x1273,0x127b,0x1263,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x1283,0x48d,0x48d,0x48d,0x48d,0x48d,
+0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x128b,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,
+0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,
+0x48d,0x48d,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x1293,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,
+0x48d,0x48d,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x8cf,0x8ee,0x129b,0x48d,0x48d,0xe68,0x12a3,0x5d8,0x12b3,0x12bb,0x12c3,0x12ab,0x48d,
+0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,
+0x48d,0x48d,0x48d,0x48d,0x565,0x50d,0x12cb,0x48d,0x48d,0x48d,0x5d8,0x5d8,0x12d3,0x12d8,0x12de,0x48d,
+0x48d,0x12e6,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x12ee,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x8da,0x48d,0x103a,0x48d,0x48d,0x48d,0x48d,0x48d,
+0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,
+0x48d,0x48d,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x8ee,0x48d,0x12f4,0x12fb,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0xe01,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,
+0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,
+0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,
+0x48d,0x48d,0x5d8,0x5d8,0x5d8,0x1301,0x1306,0x130e,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,
+0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,
+0x48d,0x48d,0x90c,0x90c,0x90c,0x90c,0x90c,0x90c,0x90c,0xba7,0x90c,0x1316,0x90c,0x131d,0x1325,0x132b,
+0x90c,0x1331,0x90c,0x90c,0x1339,0x48d,0x48d,0x48d,0x48d,0x1341,0x90c,0x90c,0xabb,0x1349,0x48d,0x48d,
+0x48d,0x48d,0x1359,0x1360,0x1365,0x136b,0x1373,0x137b,0x1383,0x135d,0x138b,0x1393,0x139b,0x13a0,0x1372,0x1359,
+0x1360,0x135c,0x136b,0x13a8,0x135a,0x13ab,0x135d,0x13b3,0x13bb,0x13c3,0x13ca,0x13b6,0x13be,0x13c6,0x13cd,0x13b9,
+0x13d5,0x1351,0x90c,0x90c,0x90c,0x90c,0x90c,0x90c,0x90c,0x90c,0x90c,0x90c,0x90c,0x90c,0x90c,0x90c,
+0x90c,0x90c,0x534,0x13e5,0x534,0x13ec,0x13f3,0x13dd,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,
+0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,
+0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,
+0x48d,0x48d,0x13fa,0x1402,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x5d8,0x1412,0x140a,0x48d,0x48d,0x48d,
+0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x5d8,0x141a,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,
+0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,
+0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,
+0x48d,0x48d,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x1422,0x48d,0x565,0x1432,0x142a,0x48d,0x48d,0x48d,
+0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,
+0x48d,0x48d,0x48d,0x48d,0x48d,0x143a,0x144a,0x1442,0x48d,0x48d,0x145a,0x1452,0x48d,0x48d,0x48d,0x48d,
+0x48d,0x48d,0x146a,0x1472,0x147a,0x1482,0x148a,0x1492,0x48d,0x1462,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,
+0x48d,0x48d,0x90c,0x149a,0x90c,0x90c,0xb9f,0x149f,0x14a3,0xba7,0x14ab,0x90c,0x90c,0x90c,0x90c,0xba9,
+0x48d,0x14b3,0x14bb,0x14bf,0x14c7,0x14cf,0x48d,0x48d,0x48d,0x48d,0x90c,0x90c,0x90c,0x90c,0x90c,0x90c,
+0x90c,0x14d7,0x90c,0x90c,0x90c,0x90c,0x90c,0x90c,0x90c,0x90c,0x90c,0x90c,0x90c,0x90c,0x90c,0x90c,
+0x90c,0x90c,0x90c,0x90c,0x90c,0x90c,0x90c,0x90c,0x14df,0x14e7,0x90c,0x90c,0x90c,0xb9f,0x90c,0x90c,
+0x14ef,0x14f7,0x149a,0x90c,0x14ff,0x90c,0x1507,0x150c,0x48d,0x48d,0x90c,0x90c,0x90c,0x1514,0x90c,0x90c,
+0x151b,0x90c,0x90c,0x90c,0xb9f,0x1520,0x1528,0x152e,0x1533,0x48d,0x90c,0x90c,0x90c,0x90c,0x153b,0x90c,
+0xabe,0x117c,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,
+0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,
+0x48d,0x48d,0x1543,0x5d8,0x5d8,0x154a,0x5d8,0x5d8,0x5d8,0x1552,0x5d8,0x155a,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0xc80,0x5d8,0x5d8,0x1562,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x156a,0x1572,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0xcbf,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x1579,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x1580,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x1587,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0xf5e,0x48d,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x158b,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0xf5e,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x1066,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x1590,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,
+0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,
+0x48d,0x48d,0x48d,0x5d8,0x5d8,0x5d8,0x5d8,0x1598,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0xf5e,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,
+0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,
+0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,
+0x48d,0x48d,0x48d,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,
+0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x5d8,0x655,0x48d,0x48d,
+0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,
+0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,
+0x48d,0x48d,0x48d,0x15a8,0x15a0,0x15a0,0x15a0,0x48d,0x48d,0x48d,0x48d,0x534,0x534,0x534,0x534,0x534,
+0x534,0x534,0x15b0,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,
+0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,
+0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,0x48d,
+0x48d,0x48d,0x48d,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,
+0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,
+0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,
+0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,0xe19,
+0xe19,0xe19,0x15b8,0x46c,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,
 0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,
-0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xc,0x17,0x17,0x17,0x19,0x17,0x17,0x17,
-0x14,0x15,0x17,0x18,0x17,0x13,0x17,0x17,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,
-0x249,0x289,0x17,0x17,0x18,0x18,0x18,0x17,0x17,1,1,1,1,1,1,1,
-1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-1,1,1,0x14,0x17,0x15,0x1a,0x16,0x1a,2,2,2,2,2,2,2,
-2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
-2,2,2,0x14,0x18,0x15,0x18,0xf,0,0,0,0,0,0,0,0,
+0xf,0xf,0xf,0xf,0xc,0x17,0x17,0x17,0x19,0x17,0x17,0x17,0x14,0x15,0x17,0x18,
+0x17,0x13,0x17,0x17,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,0x17,0x17,
+0x18,0x18,0x18,0x17,0x17,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0x14,
+0x17,0x15,0x1a,0x16,0x1a,2,2,2,2,2,2,2,2,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0x14,
+0x18,0x15,0x18,0xf,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,
+0,0,0,0,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,
 0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,
-0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xc,0x17,0x19,0x19,0x19,0x19,0x1b,0x17,
-0x1a,0x1b,5,0x1c,0x18,0x10,0x1b,0x1a,0x1b,0x18,0x34b,0x38b,0x1a,2,0x17,0x17,
-0x1a,0x30b,5,0x1d,0x34cb,0x344b,0x3ccb,0x17,1,1,1,1,1,1,1,1,
-1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0x18,
-1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,
-2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0x18,
-2,2,2,2,2,2,2,2,1,2,1,2,1,2,1,2,
+0xf,0xf,0xf,0xf,0xc,0x17,0x19,0x19,0x19,0x19,0x1b,0x17,0x1a,0x1b,5,0x1c,
+0x18,0x10,0x1b,0x1a,0x1b,0x18,0x34b,0x38b,0x1a,2,0x17,0x17,0x1a,0x30b,5,0x1d,
+0x34cb,0x344b,0x3ccb,0x17,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,0x18,1,1,1,1,
+1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,0x18,2,2,2,2,
+2,2,2,2,1,2,1,2,1,2,1,2,1,2,1,2,
 1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,
 1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,
+1,2,1,2,1,2,1,2,1,2,1,2,2,1,2,1,
+2,1,2,1,2,2,1,2,1,2,1,2,1,2,1,2,
 1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,
+1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,
+1,2,1,2,1,1,2,1,2,1,2,2,2,1,1,2,
+1,2,1,1,2,1,1,1,2,2,1,1,1,1,2,1,
+1,2,1,1,1,2,2,2,1,1,2,1,1,2,1,2,
+1,2,1,1,2,1,2,2,1,2,1,1,2,1,1,1,
+2,1,2,1,1,2,2,5,1,2,2,2,5,5,5,5,
+1,3,2,1,3,2,1,3,2,1,2,1,2,1,2,1,
 2,1,2,1,2,1,2,1,2,2,1,2,1,2,1,2,
+1,2,1,2,1,2,1,2,1,2,1,2,2,1,3,2,
+1,2,1,1,1,2,1,2,1,2,1,2,1,2,1,2,
 1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,
 1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,
-1,2,1,2,1,2,1,2,1,1,2,1,2,1,2,2,
-2,1,1,2,1,2,1,1,2,1,1,1,2,2,1,1,
-1,1,2,1,1,2,1,1,1,2,2,2,1,1,2,1,
-1,2,1,2,1,2,1,1,2,1,2,2,1,2,1,1,
-2,1,1,1,2,1,2,1,1,2,2,5,1,2,2,2,
-5,5,5,5,1,3,2,1,3,2,1,3,2,1,2,1,
-2,1,2,1,2,1,2,1,2,1,2,1,2,2,1,2,
-1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,
-2,1,3,2,1,2,1,1,1,2,1,2,1,2,1,2,
-1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,
-1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,
-1,2,1,2,1,2,1,2,1,2,1,2,2,2,2,2,
-2,2,1,1,2,1,1,2,2,1,2,1,1,1,1,2,
-1,2,1,2,1,2,1,2,2,2,2,2,2,2,2,2,
+1,2,1,2,1,2,1,2,2,2,2,2,2,2,1,1,
+2,1,1,2,2,1,2,1,1,1,1,2,1,2,1,2,
+1,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,
 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
-2,2,2,2,2,2,2,2,5,2,2,2,2,2,2,2,
+2,2,2,2,5,2,2,2,2,2,2,2,2,2,2,2,
 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
-2,2,2,2,4,4,4,4,4,4,4,4,4,4,4,4,
-4,4,4,4,4,4,0x1a,0x1a,0x1a,0x1a,4,4,4,4,4,4,
-4,4,4,4,4,4,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,
-0x1a,0x1a,0x1a,0x1a,4,4,4,4,4,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,
-4,0x1a,4,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,
-0x1a,0x1a,0x1a,0x1a,6,6,6,6,6,6,6,6,6,6,6,6,
+4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
+4,4,0x1a,0x1a,0x1a,0x1a,4,4,4,4,4,4,4,4,4,4,
+4,4,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,
+4,4,4,4,4,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,4,0x1a,4,0x1a,
+0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,
 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
-6,6,6,6,1,2,1,2,4,0x1a,1,2,0,0,4,2,
-2,2,0x17,1,0,0,0,0,0x1a,0x1a,1,0x17,1,1,1,0,
-1,0,1,1,2,1,1,1,1,1,1,1,1,1,1,1,
-1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,
+6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+1,2,1,2,4,0x1a,1,2,0,0,4,2,2,2,0x17,1,
+0,0,0,0,0x1a,0x1a,1,0x17,1,1,1,0,1,0,1,1,
+2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,0,1,1,1,1,1,1,1,1,1,2,2,2,2,
 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
-2,2,2,2,2,2,2,1,2,2,1,1,1,2,2,2,
+2,2,2,1,2,2,1,1,1,2,2,2,1,2,1,2,
 1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,
-1,2,1,2,1,2,1,2,2,2,2,2,1,2,0x18,1,
-2,1,1,2,2,1,1,1,1,1,1,1,1,1,1,1,
+1,2,1,2,2,2,2,2,1,2,0x18,1,2,1,1,2,
+2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,
+1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,
 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
-2,2,2,2,2,2,2,2,1,2,1,2,1,2,1,2,
+2,2,2,2,1,2,1,2,1,2,1,2,1,2,1,2,
 1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,
-1,2,1,2,1,2,1,2,1,2,0x1b,6,6,6,6,6,
-7,7,1,2,1,2,1,2,1,2,1,2,1,2,1,2,
+1,2,1,2,1,2,0x1b,6,6,6,6,6,7,7,1,2,
 1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,
 1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,
-1,2,1,2,1,2,1,2,1,1,2,1,2,1,2,1,
-2,1,2,1,2,1,2,2,1,2,1,2,1,2,1,2,
+1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,
+1,2,1,2,1,1,2,1,2,1,2,1,2,1,2,1,
+2,1,2,2,1,2,1,2,1,2,1,2,1,2,1,2,
 1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,
 1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,
-1,2,1,2,1,2,1,2,0,1,1,1,1,1,1,1,
-1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-1,1,1,0,0,4,0x17,0x17,0x17,0x17,0x17,0x17,0,2,2,2,
+1,2,1,2,0,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,
+0,4,0x17,0x17,0x17,0x17,0x17,0x17,2,2,2,2,2,2,2,2,
 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
-2,2,2,2,2,2,2,2,2,2,2,2,0,0x17,0x13,0,
-0,0x1b,0x1b,0x19,0,6,6,6,6,6,6,6,6,6,6,6,
+2,2,2,2,2,2,2,2,2,0x17,0x13,0,0,0x1b,0x1b,0x19,
+0,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+6,6,6,6,6,6,6,6,6,6,6,6,6,6,0x13,6,
+0x17,6,6,0x17,6,6,0x17,6,0,0,0,0,0,0,0,0,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,5,
+5,5,5,0x17,0x17,0,0,0,0,0,0,0,0,0,0,0,
+0x10,0x10,0x10,0x10,0x10,0x10,0x18,0x18,0x18,0x17,0x17,0x19,0x17,0x17,0x1b,0x1b,
+6,6,6,6,6,6,6,6,6,6,6,0x17,0x10,0,0x17,0x17,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+4,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,
 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
-6,6,0x13,6,0x17,6,6,0x17,6,6,0x17,6,0,0,0,0,
-0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,
+0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,0x17,0x17,0x17,0x17,5,5,
+6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,0x17,5,6,6,6,6,6,6,6,0x10,0x1b,6,
+6,6,6,6,6,4,4,6,6,0x1b,6,6,6,6,5,5,
+0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,5,5,5,0x1b,0x1b,5,
+0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0,0x10,
+5,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+6,6,6,0,0,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,
+6,6,6,6,6,5,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,
+6,6,6,6,6,6,6,6,4,4,0x1b,0x17,0x17,0x17,4,0,
+0,6,0x19,0x19,6,6,6,6,4,6,6,6,4,6,6,6,
+6,6,0,0,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
+0x17,0x17,0x17,0,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,6,6,6,6,4,6,
+6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,
+0,0,0x17,0,5,5,5,5,5,5,5,5,5,5,5,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,6,6,0x10,6,6,6,6,6,6,6,6,6,
+6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,0,5,5,5,5,5,5,
+5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,6,
+6,6,6,6,6,6,6,6,6,6,6,6,5,5,6,6,
+0x17,0x17,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,0x17,4,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,8,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,8,
+6,5,8,8,8,6,6,6,6,6,6,6,6,8,8,8,
+8,6,8,8,5,6,6,6,6,6,6,6,5,5,5,5,
+5,5,5,5,5,5,6,6,0,0,0x49,0x89,0xc9,0x109,0x149,0x189,
+0x1c9,0x209,0x249,0x289,5,5,0x19,0x19,0x37cb,0x35cb,0x3fcb,0x34cb,0x3ccb,0x94b,0x1b,0x19,
+5,0x17,6,0,5,6,8,8,0,5,5,5,5,5,5,5,
+5,0,0,5,5,0,0,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,0,5,5,5,5,5,5,5,0,5,0,
+0,0,5,5,5,5,0,0,6,5,8,8,8,6,6,6,
+6,0,0,8,8,0,0,8,8,6,5,0,0,0,0,0,
+0,0,0,8,0,0,0,0,5,5,0,5,0,0,0,0,
+0,0,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,6,6,5,5,
+5,6,0x17,0,0,0,0,0,0,0,0,0,0,6,6,8,
+0,5,5,5,5,5,5,0,0,0,0,5,5,0,0,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,0,5,5,
+5,5,5,5,5,0,5,5,0,5,5,0,5,5,0,0,
+6,0,8,8,8,6,6,0,0,0,0,6,6,0,0,6,
+6,6,0,0,0,6,0,0,0,0,0,0,0,5,5,5,
+5,0,5,0,5,5,6,6,0,0,0x49,0x89,0xc9,0x109,0x149,0x189,
+0x1c9,0x209,0x249,0x289,0x17,0x19,0,0,0,0,0,0,0,5,6,6,
+6,6,6,6,0,6,6,8,0,5,5,5,5,5,5,5,
+5,5,0,5,5,5,0,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,0,5,5,5,5,5,5,5,0,5,5,
+0,5,5,5,5,5,0,0,6,5,8,8,8,6,6,6,
+6,6,0,6,6,8,0,8,8,6,0,0,5,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,5,5,6,6,
+0,0,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,0x1b,5,0x34cb,0x344b,
+0x3ccb,0x37cb,0x35cb,0x3fcb,0,0,0,0,0,0,0,0,0,6,8,8,
+0,5,5,5,5,5,5,5,5,0,0,5,5,0,0,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,0,5,5,
+5,5,5,5,5,0,5,5,0,5,5,5,5,5,0,0,
+6,5,8,6,8,6,6,6,6,0,0,8,8,0,0,8,
+8,6,0,0,0,0,0,0,0,6,6,8,0,0,0,0,
+5,5,0,5,0,0,0,0,0,0,0x49,0x89,0xc9,0x109,0x149,0x189,
+0x1c9,0x209,0x249,0x289,0x7cb,0x1e4b,0x784b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x19,0x1b,0,
+0,0,0,0,0,0,6,5,0,5,5,5,5,5,5,0,
+0,0,5,5,5,0,5,5,5,5,0,0,0,5,5,0,
+5,0,5,5,0,0,0,5,5,0,0,0,5,5,5,0,
+0,0,5,5,5,5,5,5,5,5,5,5,5,5,0,0,
+0,0,8,8,6,8,8,0,0,0,8,8,8,0,8,8,
+8,6,0,0,5,0,0,0,0,0,0,8,0,0,0,0,
+0,0,0,0,5,5,6,6,0,0,0x49,0x89,0xc9,0x109,0x149,0x189,
+0x1c9,0x209,0x249,0x289,0,0,0,0,0,0,0,0x17,0x54b,0x58b,0x5cb,0x60b,
+0x58b,0x5cb,0x60b,0x1b,6,8,8,8,6,5,5,5,5,5,5,5,
+5,0,5,5,5,0,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,0,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,0,0,0,5,6,6,6,8,8,8,
+8,0,6,6,6,0,6,6,6,6,0,0,0,0,0,0,
+0,6,6,0,5,5,5,0,0,0,0,0,5,5,6,6,
+0,0,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,0,5,5,0,
+0,0,0,0,0,0,0,0,0,0,0,0,5,6,8,8,
+0x17,5,5,5,5,5,5,5,5,0,5,5,5,0,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,0,5,5,
+5,5,5,5,5,5,5,5,0,5,5,5,5,5,0,0,
+6,5,8,6,8,8,8,8,8,0,6,8,8,0,8,8,
+6,6,0,0,0,0,0,0,0,8,8,0,0,0,0,0,
+0,0,5,0,5,5,6,6,0,0,0x49,0x89,0xc9,0x109,0x149,0x189,
+0x1c9,0x209,0x249,0x289,0x7cb,0x1e4b,0x784b,0x34cb,0x344b,0x3ccb,0x37cb,0x35cb,0x3fcb,0x1b,5,5,
+5,5,5,5,6,6,8,8,5,5,5,5,5,5,5,5,
+5,0,5,5,5,0,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,6,6,5,8,8,8,6,6,6,6,0,8,8,
+8,0,8,8,8,6,5,0x1b,0,0,0,0,5,5,5,8,
+0xcc0b,0xca0b,0xcb4b,0xc90b,0x364b,0xc94b,0x350b,5,0,0,0,0,0,0,0x49,0x89,
+0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,0,0,8,8,0x17,0,0,0,
+0,0,0,0,0,0,0,0,0,6,8,8,0,5,5,5,
 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,
-0,0,0,0,5,5,5,0x17,0x17,0,0,0,0,0,0,0,
-0,0,0,0,0x10,0x10,0x10,0x10,0x10,0x10,0x18,0x18,0x18,0x17,0x17,0x19,
-0x17,0x17,0x1b,0x1b,6,6,6,6,6,6,6,6,6,6,6,0x17,
-0x10,0,0x17,0x17,5,5,5,5,5,5,5,5,5,5,5,5,
+0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,0,5,5,5,5,5,5,5,5,5,
+0,5,0,0,5,5,5,5,5,5,5,0,0,0,6,0,
+0,0,0,8,8,8,6,6,6,0,6,0,8,8,8,8,
+8,8,8,8,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,6,5,5,6,6,6,6,6,6,6,0,
+0,0,0,0x19,5,5,5,5,5,5,4,6,6,6,6,6,
+6,6,6,0x17,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,0x17,0x17,
+0,0,0,0,0,5,5,0,5,0,5,5,5,5,5,0,
 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,4,5,5,5,5,5,5,5,5,5,5,6,
+5,5,5,5,0,5,0,5,5,5,5,5,5,5,5,5,
+5,6,5,5,6,6,6,6,6,6,6,6,6,5,0,0,
+5,5,5,5,5,0,4,0,6,6,6,6,6,6,0,0,
+0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,0,0,5,5,5,5,
+5,0x1b,0x1b,0x1b,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
+0x17,0x17,0x17,0x1b,0x17,0x1b,0x1b,0x1b,6,6,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,0x344b,0x3c4b,0x444b,0x4c4b,0x544b,0x5c4b,
+0x644b,0x6c4b,0x744b,0x2c4b,0x1b,6,0x1b,6,0x1b,6,0x14,0x15,0x14,0x15,8,8,
+5,5,5,5,5,5,5,5,0,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,0,0,0,0,6,6,6,6,6,6,6,6,6,6,6,
+6,6,6,8,6,6,6,6,6,0x17,6,6,5,5,5,5,
+5,6,6,6,6,6,6,6,6,6,6,6,0,6,6,6,
 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
-6,6,6,6,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,0x17,0x17,
-0x17,0x17,5,5,6,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,0x17,5,6,6,6,6,6,6,
-6,0x10,0x1b,6,6,6,6,6,6,4,4,6,6,0x1b,6,6,
-6,6,5,5,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,5,5,
-5,0x1b,0x1b,5,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
-0x17,0x17,0,0x10,5,6,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,
-6,6,6,6,6,6,6,0,0,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,
-6,6,6,6,6,6,6,6,6,5,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,
-0x249,0x289,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,6,6,6,6,6,6,6,6,6,4,4,0x1b,0x17,
-0x17,0x17,4,0,0,0,0,0,6,6,6,6,4,6,6,6,
-4,6,6,6,6,6,0,0,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
-0x17,0x17,0x17,0x17,0x17,0x17,0x17,0,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,
-6,6,4,6,6,6,6,6,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,6,6,6,0,0,0x17,0,0,0,0,6,6,6,6,6,
-6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
-6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,
-0,0,0,0,0,0,0,0,5,5,6,6,0x17,0x17,0x49,0x89,
-0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,0x17,4,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,6,6,6,8,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,6,8,6,5,8,8,
-8,6,6,6,6,6,6,6,6,8,8,8,8,6,8,8,
-5,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,
-5,5,6,6,0,0,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,
-5,5,0x19,0x19,0x37cb,0x35cb,0x3fcb,0x34cb,0x3ccb,0x94b,0x1b,0x19,0,0,0,0,
-5,6,8,8,0,5,5,5,5,5,5,5,5,0,0,5,
-5,0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,0,5,5,5,5,5,5,5,0,5,0,0,0,5,5,
-5,5,0,0,6,5,8,8,8,6,6,6,6,0,0,8,
-8,0,0,8,8,6,5,0,0,0,0,0,0,0,0,8,
-0,0,0,0,5,5,0,5,0,0,0,0,0,0,0x49,0x89,
-0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,6,6,5,5,5,6,0,0,
-0,0,0,0,0,0,0,0,0,6,6,8,0,5,5,5,
-5,5,5,0,0,0,0,5,5,0,0,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,0,5,5,5,5,5,5,
-5,0,5,5,0,5,5,0,5,5,0,0,6,0,8,8,
-8,6,6,0,0,0,0,6,6,0,0,6,6,6,0,0,
-0,6,0,0,0,0,0,0,0,5,5,5,5,0,5,0,
-5,5,6,6,0,0,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,
-0x17,0x19,0,0,0,0,0,0,0,5,0,0,0,0,0,0,
-0,6,6,8,0,5,5,5,5,5,5,5,5,5,0,5,
-5,5,0,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,0,5,5,5,5,5,5,5,0,5,5,0,5,5,5,
-5,5,0,0,6,5,8,8,8,6,6,6,6,6,0,6,
-6,8,0,8,8,6,0,0,5,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,5,5,6,6,0,0,0x49,0x89,
-0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,0x1b,5,0x34cb,0x344b,0x3ccb,0x37cb,0x35cb,0x3fcb,
-0,0,0,0,0,0,0,0,0,6,8,8,0,5,5,5,
-5,5,5,5,5,0,0,5,5,0,0,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,0,5,5,5,5,5,5,
-5,0,5,5,0,5,5,5,5,5,0,0,6,5,8,6,
-8,6,6,6,6,0,0,8,8,0,0,8,8,6,0,0,
-0,0,0,0,0,0,6,8,0,0,0,0,5,5,0,5,
-0,0,0,0,0,0,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,
-0x7cb,0x1e4b,0x784b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x19,0x1b,0,0,0,0,0,
-0,0,6,5,0,5,5,5,5,5,5,0,0,0,5,5,
-5,0,5,5,5,5,0,0,0,5,5,0,5,0,5,5,
-0,0,0,5,5,0,0,0,5,5,5,0,0,0,5,5,
-5,5,5,5,5,5,5,5,5,5,0,0,0,0,8,8,
-6,8,8,0,0,0,8,8,8,0,8,8,8,6,0,0,
-5,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,
-5,5,6,6,0,0,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,
-0,0,0,0,0,0,0,0,0x54b,0x58b,0x5cb,0x60b,0x58b,0x5cb,0x60b,0x1b,
-6,8,8,8,0,5,5,5,5,5,5,5,5,0,5,5,
-5,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,0,0,0,5,6,6,6,8,8,8,8,0,6,6,
-6,0,6,6,6,6,0,0,0,0,0,0,0,6,6,0,
-5,5,5,0,0,0,0,0,5,5,6,6,0,0,0x49,0x89,
-0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,0,5,5,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,6,8,8,0,5,5,5,
-5,5,5,5,5,0,5,5,5,0,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,0,5,5,5,5,5,5,
-5,5,5,5,0,5,5,5,5,5,0,0,6,5,8,6,
-8,8,8,8,8,0,6,8,8,0,8,8,6,6,0,0,
-0,0,0,0,0,8,8,0,0,0,0,0,0,0,5,0,
-5,5,6,6,0,0,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,
-0x7cb,0x1e4b,0x784b,0x34cb,0x344b,0x3ccb,0,0,0,0x1b,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,0,0,5,8,8,8,6,6,6,
-6,0,8,8,8,0,8,8,8,6,5,0,0,0,0,0,
-0,0,0,8,0,0,0,0,0,0,0,5,0,0,0,0,
-0,0,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,0,0,8,8,
-0x17,0,0,0,0,0,0,0,0,0,0,0,0,0,8,8,
-0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,0,0,0,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,0,5,5,5,5,5,
-5,5,5,5,0,5,0,0,5,5,5,5,5,5,5,0,
-0,0,6,0,0,0,0,8,8,8,6,6,6,0,6,0,
-8,8,8,8,8,8,8,8,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,6,5,5,6,6,6,6,
-6,6,6,0,0,0,0,0x19,5,5,5,5,5,5,4,6,
-6,6,6,6,6,6,6,0x17,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,
-0x249,0x289,0x17,0x17,0,0,0,0,0,5,5,0,5,0,0,5,
-5,0,5,0,0,5,0,0,0,0,0,0,5,5,5,5,
-0,5,5,5,5,5,5,5,0,5,5,5,0,5,0,5,
-0,0,5,5,0,5,5,5,5,6,5,5,6,6,6,6,
-6,6,0,6,6,5,0,0,5,5,5,5,5,0,4,0,
-6,6,6,6,6,6,0,0,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,
-0x249,0x289,0,0,5,5,5,5,5,0x1b,0x1b,0x1b,0x17,0x17,0x17,0x17,
-0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x1b,0x17,0x1b,0x1b,0x1b,
-6,6,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,
-0x249,0x289,0x344b,0x3c4b,0x444b,0x4c4b,0x544b,0x5c4b,0x644b,0x6c4b,0x744b,0x2c4b,0x1b,6,0x1b,6,
-0x1b,6,0x14,0x15,0x14,0x15,8,8,5,5,5,5,5,5,5,5,
-0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,0,0,0,0,6,6,6,
-6,6,6,6,6,6,6,6,6,6,6,8,6,6,6,6,
-6,0x17,6,6,5,5,5,5,5,6,6,6,6,6,6,6,
-6,6,6,6,0,6,6,6,6,6,6,6,6,6,6,6,
-6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
-6,6,6,6,6,0,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,6,0x1b,
-0x1b,0x1b,0x1b,0x1b,0x1b,0,0x1b,0x1b,0x17,0x17,0x17,0x17,0x17,0x1b,0x1b,0x1b,
-0x1b,0x17,0x17,0,0,0,0,0,5,5,5,5,5,5,5,5,
-5,5,5,8,8,6,6,6,6,8,6,6,6,6,6,6,
-8,6,6,8,8,6,6,5,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,
-0x249,0x289,0x17,0x17,0x17,0x17,0x17,0x17,5,5,5,5,5,5,8,8,
-6,6,5,5,5,5,6,6,6,5,8,8,8,5,5,8,
-8,8,8,8,8,8,5,5,5,6,6,6,6,5,5,5,
-5,5,5,5,5,5,5,5,5,5,6,8,8,6,6,8,
-8,8,8,8,8,6,5,8,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,
-0x249,0x289,8,8,8,6,0x1b,0x1b,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,0x17,4,5,5,5,1,1,1,1,1,1,0,1,
-0,0,0,0,0,1,0,0,5,5,5,5,5,5,5,5,
+6,6,6,6,6,6,6,6,6,6,6,6,6,0,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,6,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0x1b,0x1b,
+0x17,0x17,0x17,0x17,0x17,0x1b,0x1b,0x1b,0x1b,0x17,0x17,0,0,0,0,0,
+5,5,5,5,5,5,5,5,5,5,5,8,8,6,6,6,
+6,8,6,6,6,6,6,6,8,6,6,8,8,6,6,5,
+0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,0x17,0x17,0x17,0x17,0x17,0x17,
+5,5,5,5,5,5,8,8,6,6,5,5,5,5,6,6,
+6,5,8,8,8,5,5,8,8,8,8,8,8,8,5,5,
+5,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,
+5,5,6,8,8,6,6,8,8,8,8,8,8,6,5,8,
+0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,8,8,8,6,0x1b,0x1b,
+2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,0x17,4,2,2,2,
+1,1,1,1,1,1,0,1,0,0,0,0,0,1,0,0,
+2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
 5,5,5,5,5,5,5,5,5,0,5,5,5,5,0,0,
 5,5,5,5,5,5,5,0,5,0,5,5,5,5,0,0,
 5,5,5,5,5,5,5,5,5,0,5,5,5,5,0,0,
 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,0,5,5,5,5,0,0,5,5,5,5,5,5,5,0,
 5,0,5,5,5,5,0,0,5,5,5,5,5,5,5,5,
 5,5,5,5,5,5,5,0,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,0,5,5,5,5,0,0,
 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,0,0,6,6,6,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
-0x17,0x30b,0x34b,0x38b,0x3cb,0x40b,0x44b,0x48b,0x4cb,0x50b,0x7cb,0xa4b,0xccb,0xf4b,0x11cb,0x144b,
-0x16cb,0x194b,0x1bcb,0x1e4b,0x788b,0,0,0,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
-0x1b,0x1b,0,0,0,0,0,0,1,1,1,1,1,1,1,1,
-1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,
-2,2,2,2,2,2,0,0,0x13,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,0,0,6,6,6,
+0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x30b,0x34b,0x38b,0x3cb,0x40b,0x44b,0x48b,
+0x4cb,0x50b,0x7cb,0xa4b,0xccb,0xf4b,0x11cb,0x144b,0x16cb,0x194b,0x1bcb,0x1e4b,0x788b,0,0,0,
 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,0x17,0x17,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,0xc,5,5,5,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0,0,0,0,0,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,0,0,2,2,2,2,2,2,0,0,
+0x13,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,0x14,0x15,0,0,0,5,5,5,5,
-5,5,5,5,5,5,5,0x17,0x17,0x17,0x98a,0x9ca,0xa0a,5,5,5,
+5,0x1b,0x17,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,0xc,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0x14,
+0x15,0,0,0,5,5,5,5,5,5,5,5,5,5,5,0x17,
+0x17,0x17,0x98a,0x9ca,0xa0a,5,5,5,5,5,5,5,5,0,0,0,
+0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,
+5,0,5,5,5,5,6,6,6,0,0,0,0,0,0,0,
+0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,6,6,6,0x17,0x17,0,0,0,0,0,
+0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,6,6,0,0,0,0,0,0,0,0,
+0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,
+5,0,5,5,5,0,6,6,0,0,0,0,0,0,0,0,
+0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,6,6,8,6,6,6,6,6,
+6,6,8,8,8,8,8,8,8,8,6,8,8,6,6,6,
+6,6,6,6,6,6,6,6,0x17,0x17,0x17,4,0x17,0x17,0x17,0x19,
+5,6,0,0,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,0,0,
+0,0,0,0,0x54b,0x58b,0x5cb,0x60b,0x64b,0x68b,0x6cb,0x70b,0x74b,0x78b,0,0,
+0,0,0,0,5,5,5,5,5,5,5,5,5,6,5,0,
+0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,0x17,0x17,0x17,0x17,0x17,0x17,0x13,0x17,0x17,0x17,0x17,6,
+6,6,0x10,0,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,0,0,
+0,0,0,0,5,5,5,4,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
 5,5,5,5,5,0,0,0,0,0,0,0,5,5,5,5,
-5,5,5,5,5,5,5,5,5,0,5,5,5,5,6,6,
-6,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,
-6,0x17,0x17,0,0,0,0,0,0,0,0,0,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,
-0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,
-5,5,5,5,5,5,5,5,5,0,5,5,5,0,6,6,
-0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,
+5,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,
+0,0,0,0,0,0,0,0,6,6,6,8,8,8,8,6,
+6,8,8,8,0,0,0,0,8,8,6,8,8,8,8,8,
+8,6,6,6,0,0,0,0,0x1b,0,0,0,0x17,0x17,0x49,0x89,
+0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,5,5,5,5,5,5,5,5,
 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-6,6,8,6,6,6,6,6,6,6,8,8,8,8,8,8,
-8,8,6,8,8,6,6,6,6,6,6,6,6,6,6,6,
-0x17,0x17,0x17,4,0x17,0x17,0x17,0x19,5,6,0,0,0x49,0x89,0xc9,0x109,
-0x149,0x189,0x1c9,0x209,0x249,0x289,0,0,0,0,0,0,0x54b,0x58b,0x5cb,0x60b,
-0x64b,0x68b,0x6cb,0x70b,0x74b,0x78b,0,0,0,0,0,0,5,5,5,5,
-5,5,5,5,5,6,5,0,0,0,0,0,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,0x17,0x17,0x17,0x17,
-0x17,0x17,0x13,0x17,0x17,0x17,0x17,6,6,6,0x10,0,0x49,0x89,0xc9,0x109,
-0x149,0x189,0x1c9,0x209,0x249,0x289,0,0,0,0,0,0,5,5,5,4,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,
-0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,0,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,0,0,5,5,5,5,5,0,0,0,
+0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,
+5,5,5,5,0,0,0,0,5,5,5,5,5,5,5,5,
 5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,
-0,0,0,0,6,6,6,8,8,8,8,6,6,8,8,8,
-0,0,0,0,8,8,6,8,8,8,8,8,8,6,6,6,
-0,0,0,0,0x1b,0,0,0,0x17,0x17,0x49,0x89,0xc9,0x109,0x149,0x189,
-0x1c9,0x209,0x249,0x289,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,0,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,0,0,5,5,5,5,5,0,0,0,0,0,0,0,
-0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,
-0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,0,0,0,0,0,0,0x49,0x89,0xc9,0x109,
-0x149,0x189,0x1c9,0x209,0x249,0x289,0x30b,0,0,0,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,0x30b,0,0,0,0x1b,0x1b,
 0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
-0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,5,5,5,5,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,6,6,8,8,6,0,0,0x17,0x17,0x17,0x17,0x17,0x17,
-0x17,0x17,0x17,4,0x17,0x17,0x17,0x17,0x17,0x17,0,0,6,6,6,6,
-6,6,6,6,6,6,6,6,6,6,7,0,5,5,5,5,
+5,5,5,5,5,5,5,6,6,8,8,6,0,0,0x17,0x17,
+0x17,0x17,0x17,0x17,0x17,0x17,0x17,4,0x17,0x17,0x17,0x17,0x17,0x17,0,0,
+6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,6,
 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,8,6,8,6,6,6,6,6,6,6,0,6,8,6,8,
-8,6,6,6,6,6,6,6,6,8,8,8,8,8,8,6,
-6,6,6,6,6,6,6,6,6,0,0,6,0x49,0x89,0xc9,0x109,
-0x149,0x189,0x1c9,0x209,0x249,0x289,0,0,0,0,0,0,0x49,0x89,0xc9,0x109,
-0x149,0x189,0x1c9,0x209,0x249,0x289,0,0,0,0,0,0,0x17,0x1b,0x1b,0x1b,
-0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,6,6,6,6,6,6,6,6,6,
-0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0,0,6,6,6,6,
-8,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,6,8,6,6,
-6,6,6,8,6,8,8,8,8,8,6,8,8,5,5,5,
-5,5,5,5,0,0,0,0,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,
-0x249,0x289,0x17,0x17,0x17,0x17,0x17,0x17,5,8,6,6,6,6,8,8,
-6,6,8,6,6,6,5,5,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,
-0x249,0x289,5,5,5,5,5,5,6,6,8,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,6,8,6,6,8,8,
-8,6,8,6,6,6,8,8,0,0,0,0,0,0,0,0,
-0x17,0x17,0x17,0x17,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,0,0,
-0,5,5,5,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,5,5,
-5,5,5,5,8,8,8,8,8,8,8,8,6,6,6,6,
-6,6,6,6,8,8,6,6,0,0,0,0x17,0x17,0x17,0x17,0x17,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,4,4,4,4,4,4,0x17,0x17,
-0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0,0,0,0,0,0,0,0,
-6,6,6,0x17,6,6,6,6,6,6,6,6,6,6,6,6,
-6,8,6,6,6,6,6,6,6,5,5,5,5,6,5,5,
-5,5,8,8,6,5,5,0,6,6,0,0,0,0,0,0,
-2,2,2,2,2,2,2,2,2,2,2,2,4,4,4,4,
-4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
-4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,2,
-2,2,2,2,2,2,2,2,2,2,2,2,4,2,2,2,
-2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
-2,2,2,2,2,2,2,2,2,2,2,4,4,4,4,4,
-6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
-6,6,6,6,6,6,0,0,0,0,0,0,6,6,6,6,
-1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,
-1,2,1,2,1,2,2,2,2,2,2,2,2,2,1,2,
-2,2,2,2,2,2,2,2,1,1,1,1,1,0x1a,0x1a,0x1a,
-0,0,2,2,2,0,2,2,1,1,1,1,3,0x1a,0x1a,0,
-2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,
-2,2,2,2,2,2,0,0,1,1,1,1,1,1,0,0,
-2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,
-2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,
-2,2,2,2,2,2,0,0,1,1,1,1,1,1,0,0,
-2,2,2,2,2,2,2,2,0,1,0,1,0,1,0,1,
-2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,
-2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,
-2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,
-2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,
-2,2,2,2,2,0,2,2,1,1,1,1,3,0x1a,2,0x1a,
-0x1a,0x1a,2,2,2,0,2,2,1,1,1,1,3,0x1a,0x1a,0x1a,
-2,2,2,2,0,0,2,2,1,1,1,1,0,0x1a,0x1a,0x1a,
-0x16,0x17,0x17,0x17,0x18,0x14,0x15,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
-0x17,0x17,0x18,0x17,0x16,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0xc,
-0x10,0x10,0x10,0x10,0x10,0,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
-0x2cb,4,0,0,0x3cb,0x40b,0x44b,0x48b,0x4cb,0x50b,0x18,0x18,0x18,0x14,0x15,4,
-0xc,0xc,0xc,0xc,0xc,0xc,0xc,0xc,0xc,0xc,0xc,0x10,0x10,0x10,0x10,0x10,
-0x13,0x13,0x13,0x13,0x13,0x13,0x17,0x17,0x1c,0x1d,0x14,0x1c,0x1c,0x1d,0x14,0x1c,
-0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0xd,0xe,0x10,0x10,0x10,0x10,0x10,0xc,
-0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x1c,0x1d,0x17,0x17,0x17,0x17,0x16,
-0x2cb,0x30b,0x34b,0x38b,0x3cb,0x40b,0x44b,0x48b,0x4cb,0x50b,0x18,0x18,0x18,0x14,0x15,0,
-4,4,4,4,4,4,4,4,4,4,4,4,4,0,0,0,
-0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,
-0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,
-7,6,7,7,7,6,6,6,6,6,6,6,6,6,6,6,
+5,5,5,5,5,8,6,8,6,6,6,6,6,6,6,0,
+6,8,6,8,8,6,6,6,6,6,6,6,6,8,8,8,
+8,8,8,6,6,6,6,6,6,6,6,6,6,0,0,6,
+0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,0,0,0,0,0,0,
+0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,0,0,0,0,0,0,
+0x17,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,6,6,6,6,6,
+6,6,6,6,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0,0,
 6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0x1b,0x1b,0x1b,0x1b,1,0x1b,1,0x1b,1,0x1b,1,1,1,1,0x1b,2,
-1,1,1,1,2,5,5,5,5,2,0x1b,0x1b,2,2,1,1,
-0x18,0x18,0x18,0x18,0x18,1,2,2,2,2,0x1b,0x18,0x1b,0x1b,2,0x1b,
-0x358b,0x360b,0x364b,0x348b,0x388b,0x350b,0x390b,0x3d0b,0x410b,0x354b,0x454b,0x35cb,0x3dcb,0x45cb,0x4dcb,0x58b,
-0x1b,0x1b,1,0x1b,0x1b,0x1b,0x1b,1,0x1b,0x1b,2,1,1,1,2,2,
-1,1,1,2,0x1b,1,0x1b,0x1b,0x18,1,1,1,1,1,0x1b,0x1b,
-0x58a,0x5ca,0x60a,0x64a,0x68a,0x6ca,0x70a,0x74a,0x78a,0x7ca,0x80a,0x84a,0x11ca,0x1e4a,0x980a,0x784a,
-0x58a,0x5ca,0x60a,0x64a,0x68a,0x6ca,0x70a,0x74a,0x78a,0x7ca,0x80a,0x84a,0x11ca,0x1e4a,0x980a,0x784a,
-0x784a,0x984a,0x788a,1,2,0x6ca,0x11ca,0x988a,0x78ca,0x54b,0x1b,0x1b,0,0,0,0,
-0x18,0x18,0x18,0x18,0x18,0x1b,0x1b,0x1b,0x1b,0x1b,0x18,0x18,0x1b,0x1b,0x1b,0x1b,
-0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
-0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1b,0x1b,0x18,
-0x1b,0x1b,0x18,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x18,0x1b,0x1b,0x1b,0x1b,0x1b,
-0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x18,0x18,
-0x1b,0x1b,0x18,0x1b,0x18,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
-0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
-0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
-0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x14,0x15,0x14,0x15,0x1b,0x1b,0x1b,0x1b,
-0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
-0x18,0x18,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x14,0x15,0x1b,0x1b,0x1b,0x1b,0x1b,
-0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
-0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x18,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
-0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
-0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
-0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1b,0x1b,0x1b,0x1b,
-0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
-0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x18,0x18,0x18,0x18,0x18,0x18,0x1b,0x1b,
-0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
-0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x2cb,0x80b,0x84b,0x88b,0x8cb,0x90b,
-0x94b,0x98b,0x9cb,0xa0b,0xa4b,0x30b,0x34b,0x38b,0x3cb,0x40b,0x44b,0x48b,0x4cb,0x50b,0x7cb,0x2cb,
+6,6,6,6,8,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+6,8,6,6,6,6,6,8,6,8,8,8,8,8,6,8,
+8,5,5,5,5,5,5,5,0,0,0,0,0x49,0x89,0xc9,0x109,
+0x149,0x189,0x1c9,0x209,0x249,0x289,0x17,0x17,0x17,0x17,0x17,0x17,5,8,6,6,
+6,6,8,8,6,6,8,6,6,6,5,5,0x49,0x89,0xc9,0x109,
+0x149,0x189,0x1c9,0x209,0x249,0x289,5,5,5,5,5,5,6,6,8,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,8,
+6,6,8,8,8,6,8,6,6,6,8,8,0,0,0,0,
+0,0,0,0,0x17,0x17,0x17,0x17,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,
+0x249,0x289,0,0,0,5,5,5,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,
+0x249,0x289,5,5,5,5,5,5,8,8,8,8,8,8,8,8,
+6,6,6,6,6,6,6,6,8,8,6,6,0,0,0,0x17,
+0x17,0x17,0x17,0x17,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,
+4,4,0x17,0x17,2,2,2,2,2,2,2,2,2,0,0,0,
+0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,
+0,1,1,1,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0,0,0,0,
+0,0,0,0,6,6,6,0x17,6,6,6,6,6,6,6,6,
+6,6,6,6,6,8,6,6,6,6,6,6,6,5,5,5,
+5,6,5,5,5,5,5,5,6,5,5,8,6,6,5,0,
+0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,
+4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
+4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
+4,4,4,2,2,2,2,2,2,2,2,2,2,2,2,2,
+4,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4,
+4,4,4,4,6,6,6,6,6,6,6,6,6,6,6,6,
+6,6,6,6,6,6,6,6,6,6,6,6,6,6,0,6,
+6,6,6,6,1,2,1,2,1,2,1,2,1,2,1,2,
+1,2,1,2,1,2,1,2,1,2,2,2,2,2,2,2,
+2,2,1,2,2,2,2,2,2,2,2,2,1,1,1,1,
+1,0x1a,0x1a,0x1a,0,0,2,2,2,0,2,2,1,1,1,1,
+3,0x1a,0x1a,0,2,2,2,2,2,2,2,2,1,1,1,1,
+1,1,1,1,2,2,2,2,2,2,0,0,1,1,1,1,
+1,1,0,0,2,2,2,2,2,2,2,2,1,1,1,1,
+1,1,1,1,2,2,2,2,2,2,2,2,1,1,1,1,
+1,1,1,1,2,2,2,2,2,2,0,0,1,1,1,1,
+1,1,0,0,2,2,2,2,2,2,2,2,0,1,0,1,
+0,1,0,1,2,2,2,2,2,2,2,2,1,1,1,1,
+1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,
+2,2,0,0,2,2,2,2,2,2,2,2,3,3,3,3,
+3,3,3,3,2,2,2,2,2,2,2,2,3,3,3,3,
+3,3,3,3,2,2,2,2,2,0,2,2,1,1,1,1,
+3,0x1a,2,0x1a,0x1a,0x1a,2,2,2,0,2,2,1,1,1,1,
+3,0x1a,0x1a,0x1a,2,2,2,2,0,0,2,2,1,1,1,1,
+0,0x1a,0x1a,0x1a,0x16,0x17,0x17,0x17,0x18,0x14,0x15,0x17,0x17,0x17,0x17,0x17,
+0x17,0x17,0x17,0x17,0x17,0x17,0x18,0x17,0x16,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
+0x17,0x17,0x17,0xc,0x10,0x10,0x10,0x10,0x10,0,0x10,0x10,0x10,0x10,0x10,0x10,
+0x10,0x10,0x10,0x10,0x2cb,4,0,0,0x3cb,0x40b,0x44b,0x48b,0x4cb,0x50b,0x18,0x18,
+0x18,0x14,0x15,4,0xc,0xc,0xc,0xc,0xc,0xc,0xc,0xc,0xc,0xc,0xc,0x10,
+0x10,0x10,0x10,0x10,0x13,0x13,0x13,0x13,0x13,0x13,0x17,0x17,0x1c,0x1d,0x14,0x1c,
+0x1c,0x1d,0x14,0x1c,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0xd,0xe,0x10,0x10,
+0x10,0x10,0x10,0xc,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x1c,0x1d,0x17,
+0x17,0x17,0x17,0x16,0x2cb,0x30b,0x34b,0x38b,0x3cb,0x40b,0x44b,0x48b,0x4cb,0x50b,0x18,0x18,
+0x18,0x14,0x15,0,4,4,4,4,4,4,4,4,4,4,4,4,
+4,0,0,0,0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,
+0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,
+0x19,0x19,0x19,0x19,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,6,6,6,6,6,6,6,6,6,6,6,6,
+6,7,7,7,7,6,7,7,7,6,6,6,6,6,6,6,
+6,6,6,6,6,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0x1b,0x1b,0x1b,0x1b,1,0x1b,1,0x1b,1,0x1b,1,1,
+1,1,0x1b,2,1,1,1,1,2,5,5,5,5,2,0x1b,0x1b,
+2,2,1,1,0x18,0x18,0x18,0x18,0x18,1,2,2,2,2,0x1b,0x18,
+0x1b,0x1b,2,0x1b,0x358b,0x360b,0x364b,0x348b,0x388b,0x350b,0x390b,0x3d0b,0x410b,0x354b,0x454b,0x35cb,
+0x3dcb,0x45cb,0x4dcb,0x58b,0x1b,0x1b,1,0x1b,0x1b,0x1b,0x1b,1,0x1b,0x1b,2,1,
+1,1,2,2,1,1,1,2,0x1b,1,0x1b,0x1b,0x18,1,1,1,
+1,1,0x1b,0x1b,0x58a,0x5ca,0x60a,0x64a,0x68a,0x6ca,0x70a,0x74a,0x78a,0x7ca,0x80a,0x84a,
+0x11ca,0x1e4a,0x980a,0x784a,0x58a,0x5ca,0x60a,0x64a,0x68a,0x6ca,0x70a,0x74a,0x78a,0x7ca,0x80a,0x84a,
+0x11ca,0x1e4a,0x980a,0x784a,0x784a,0x984a,0x788a,1,2,0x6ca,0x11ca,0x988a,0x78ca,0x54b,0x1b,0x1b,
+0,0,0,0,0x18,0x18,0x18,0x18,0x18,0x1b,0x1b,0x1b,0x1b,0x1b,0x18,0x18,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+0x18,0x1b,0x1b,0x18,0x1b,0x1b,0x18,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x18,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x18,0x18,0x1b,0x1b,0x18,0x1b,0x18,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+0x18,0x18,0x18,0x18,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x14,0x15,0x14,0x15,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x18,0x18,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x14,0x15,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x18,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x18,0x18,0x18,0x18,0x18,
+0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x18,0x18,0x18,0x18,
+0x18,0x18,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x2cb,0x80b,0x84b,0x88b,0x8cb,0x90b,0x94b,0x98b,0x9cb,0xa0b,
+0xa4b,0x30b,0x34b,0x38b,0x3cb,0x40b,0x44b,0x48b,0x4cb,0x50b,0x7cb,0x2cb,0x30b,0x34b,0x38b,0x3cb,
+0x40b,0x44b,0x48b,0x4cb,0x50b,0x7cb,0x80b,0x84b,0x88b,0x8cb,0x90b,0x94b,0x98b,0x9cb,0xa0b,0xa4b,
 0x30b,0x34b,0x38b,0x3cb,0x40b,0x44b,0x48b,0x4cb,0x50b,0x7cb,0x80b,0x84b,0x88b,0x8cb,0x90b,0x94b,
-0x98b,0x9cb,0xa0b,0xa4b,0x30b,0x34b,0x38b,0x3cb,0x40b,0x44b,0x48b,0x4cb,0x50b,0x7cb,0x80b,0x84b,
-0x88b,0x8cb,0x90b,0x94b,0x98b,0x9cb,0xa0b,0xa4b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
-0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
-0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
-0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x18,
-0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x18,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
-0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x98b,0x9cb,0xa0b,0xa4b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x18,0x18,0x18,0x18,
+0x18,0x18,0x18,0x18,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
 0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x18,0x1b,0x1b,0x1b,0x1b,
-0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x14,0x15,0x14,0x15,
-0x14,0x15,0x14,0x15,0x14,0x15,0x14,0x15,0x14,0x15,0x30b,0x34b,0x38b,0x3cb,0x40b,0x44b,
-0x48b,0x4cb,0x50b,0x7cb,0x30b,0x34b,0x38b,0x3cb,0x40b,0x44b,0x48b,0x4cb,0x50b,0x7cb,0x30b,0x34b,
-0x38b,0x3cb,0x40b,0x44b,0x48b,0x4cb,0x50b,0x7cb,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
-0x1b,0x1b,0x1b,0x1b,0x18,0x18,0x18,0x18,0x18,0x14,0x15,0x18,0x18,0x18,0x18,0x18,
-0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
-0x18,0x18,0x18,0x18,0x18,0x18,0x14,0x15,0x14,0x15,0x14,0x15,0x14,0x15,0x14,0x15,
-0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
-0x18,0x18,0x18,0x14,0x15,0x14,0x15,0x14,0x15,0x14,0x15,0x14,0x15,0x14,0x15,0x14,
-0x15,0x14,0x15,0x14,0x15,0x14,0x15,0x14,0x15,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
-0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
-0x18,0x18,0x18,0x18,0x14,0x15,0x14,0x15,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
-0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
-0x18,0x18,0x18,0x18,0x14,0x15,0x18,0x18,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
-0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
-0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1b,0x1b,0x18,0x18,0x18,0x18,0x18,
-0x18,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
-0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x18,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
 0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
-0x1b,0x1b,0,0,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
-0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0,
-0,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0x1b,0x1b,
-0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0x1b,0x1b,0x1b,0x1b,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x18,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x14,0x15,0x14,0x15,0x14,0x15,0x14,0x15,
+0x14,0x15,0x14,0x15,0x14,0x15,0x30b,0x34b,0x38b,0x3cb,0x40b,0x44b,0x48b,0x4cb,0x50b,0x7cb,
+0x30b,0x34b,0x38b,0x3cb,0x40b,0x44b,0x48b,0x4cb,0x50b,0x7cb,0x30b,0x34b,0x38b,0x3cb,0x40b,0x44b,
+0x48b,0x4cb,0x50b,0x7cb,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x18,0x18,0x18,0x18,0x18,0x14,0x15,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+0x18,0x18,0x14,0x15,0x14,0x15,0x14,0x15,0x14,0x15,0x14,0x15,0x18,0x18,0x18,0x18,
+0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x14,
+0x15,0x14,0x15,0x14,0x15,0x14,0x15,0x14,0x15,0x14,0x15,0x14,0x15,0x14,0x15,0x14,
+0x15,0x14,0x15,0x14,0x15,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+0x14,0x15,0x14,0x15,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+0x14,0x15,0x18,0x18,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+0x18,0x18,0x18,0x18,0x18,0x1b,0x1b,0x18,0x18,0x18,0x18,0x18,0x18,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0,0,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,2,2,2,2,2,2,2,2,
 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
 2,2,2,2,2,2,2,0,1,1,1,1,1,1,1,1,
 1,1,1,1,1,1,1,0,2,2,2,2,2,2,2,2,
@@ -725,8 +754,8 @@
 0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x13,0x17,0x17,0x13,0x17,0x1c,0x1d,0x17,0x17,
 0x1c,0x1d,0x14,0x15,0x14,0x15,0x14,0x15,0x14,0x15,0x17,0x17,0x17,0x17,0x17,4,
 0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x13,0x13,0x17,0x17,0x17,0x17,
-0x13,0x17,0x14,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0x13,0x17,0x14,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
+0x1b,0x1b,0x17,0,0,0,0,0,0,0,0,0,0,0,0,0,
 0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
 0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0x1b,0x1b,0x1b,0x1b,0x1b,
 0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
@@ -744,147 +773,146 @@
 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0x17,
 4,4,4,5,0,0,0,0,0,5,5,5,5,5,5,5,
 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,0,0,0,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,0,0x1b,0x1b,0x58b,0x5cb,
-0x60b,0x64b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0,0,0,
-0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+5,5,5,5,0,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,0,0x1b,0x1b,0x58b,0x5cb,0x60b,0x64b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0,0,0,0,0,0,0,
+0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,0x58b,0x5cb,0x60b,0x64b,0x68b,0x6cb,0x70b,0x74b,0x78b,0x7cb,0x1b,0x1b,
 0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
-0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0x58b,0x5cb,0x60b,0x64b,0x68b,0x6cb,0x70b,0x74b,
-0x78b,0x7cb,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
-0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x7cb,0xa4b,0xccb,0xf4b,0x11cb,0x144b,0x16cb,0x194b,
-0x1b,0xa8b,0xacb,0xb0b,0xb4b,0xb8b,0xbcb,0xc0b,0xc4b,0xc8b,0xccb,0xd0b,0xd4b,0xd8b,0xdcb,0xe0b,
-0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
-0x1b,0xe4b,0xe8b,0xecb,0xf0b,0xf4b,0xf8b,0xfcb,0x100b,0x104b,0x108b,0x10cb,0x110b,0x114b,0x118b,0x11cb,
-5,5,5,5,5,0x685,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,0x5c5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,0x685,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,0x705,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,0x585,5,5,0x705,
-5,5,5,0x7885,5,0x605,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,0x785,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,0x5c5,5,5,5,5,5,5,5,0x685,5,0x645,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0x7985,
-0x7c5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0x7845,
-5,5,5,5,5,5,5,5,0x605,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+0x1b,0x1b,0x1b,0x1b,0x7cb,0xa4b,0xccb,0xf4b,0x11cb,0x144b,0x16cb,0x194b,0x1b,0xa8b,0xacb,0xb0b,
+0xb4b,0xb8b,0xbcb,0xc0b,0xc4b,0xc8b,0xccb,0xd0b,0xd4b,0xd8b,0xdcb,0xe0b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0xe4b,0xe8b,0xecb,
+0xf0b,0xf4b,0xf8b,0xfcb,0x100b,0x104b,0x108b,0x10cb,0x110b,0x114b,0x118b,0x11cb,5,5,5,5,
 5,0x685,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0x5c5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,0x685,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,0x705,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,0x585,5,5,0x705,5,5,5,0x7885,
+5,0x605,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,0x785,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+0x5c5,5,5,5,5,5,5,5,0x685,5,0x645,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,0x7985,0x7c5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,0x7845,5,5,5,5,
+5,5,5,5,0x605,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,0x685,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+0x1e45,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+0x7985,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,0x7a85,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,0x5c5,5,0x745,5,0x6c5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,0x7c5,5,0x7845,0xa45,0xcc5,5,5,5,5,5,5,0xf45,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,0x605,0x605,0x605,0x605,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,0x645,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,0x585,5,5,5,5,5,5,5,0x585,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,0x585,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,0x785,0xa45,5,5,5,5,
+5,5,5,5,5,5,5,5,0x585,0x5c5,0x605,5,0x5c5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,0x7c5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,0x745,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,0x705,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,0x785,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,0x1e45,5,
+5,5,5,5,5,5,0x645,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+0x7885,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,0x5c5,5,5,5,5,0x5c5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,0x5c5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,0x7845,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,0x6c5,5,
 5,5,5,5,0x1e45,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,0x7985,5,5,5,5,5,5,5,5,5,5,5,
 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,0x7a85,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,0x5c5,5,0x745,
-5,0x6c5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,0x7c5,5,0x7845,0xa45,0xcc5,5,5,5,5,5,5,
-0xf45,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,0x605,0x605,0x605,0x605,5,5,5,5,5,5,5,
+0x6c5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,0x545,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,0,0,0,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,5,5,5,5,
 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,0x645,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,0x585,5,5,5,5,5,5,
-5,0x585,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,0x585,5,
+5,4,5,5,5,5,5,5,5,5,5,5,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0,0,0,0,0,0,0,0,0,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,4,0x17,0x17,0x17,
 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,0x785,0xa45,
-5,5,5,5,5,5,5,5,5,5,5,5,0x585,0x5c5,0x605,5,
-0x5c5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,0x7c5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-0x745,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,0x705,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,0x785,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,0x1e45,5,5,5,5,5,5,5,0x645,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,0x7885,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,0x5c5,5,5,5,5,0x5c5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-0x5c5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,0x7845,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,0x6c5,5,5,5,5,5,0x1e45,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,0x6c5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,0x545,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,
-0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,4,5,5,5,5,5,5,5,5,5,5,
-0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0,0,0,0,0,0,0,0,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-4,0x17,0x17,0x17,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,5,5,
+0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,5,5,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,1,2,1,2,1,2,1,2,1,2,1,2,
 1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,
-4,4,6,6,1,2,1,2,1,2,1,2,1,2,1,2,
-1,2,5,6,7,7,7,0x17,6,6,6,6,6,6,6,6,
-6,6,0x17,4,5,5,5,5,5,5,0x58a,0x5ca,0x60a,0x64a,0x68a,0x6ca,
-0x70a,0x74a,0x78a,0x54a,6,6,0x17,0x17,0x17,0x17,0x17,0x17,0,0,0,0,
-0,0,0,0,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,
-0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,4,4,4,4,4,
-4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,5,4,4,2,5,
-5,5,5,5,0x1a,0x1a,1,2,1,2,1,2,1,2,1,2,
-1,2,1,2,2,2,1,2,1,2,1,2,1,2,1,2,
-1,2,1,2,1,2,1,2,4,2,2,2,2,2,2,2,
-2,1,2,1,2,1,1,2,1,2,1,2,1,2,1,2,
-4,0x1a,0x1a,1,2,1,2,5,1,2,1,2,2,2,1,2,
-1,2,1,2,1,2,1,2,1,2,1,1,1,1,0,0,
-1,1,1,1,1,2,1,2,0,0,0,0,0,0,0,0,
-5,5,6,5,5,5,6,5,5,5,5,6,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,8,8,6,6,8,0x1b,0x1b,0x1b,0x1b,0,0,0,0,
-0x34cb,0x344b,0x3ccb,0x37cb,0x35cb,0x3fcb,0x1b,0x1b,0x19,0x1b,0,0,0,0,0,0,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,0x17,0x17,0x17,0x17,0,0,0,0,0,0,0,0,
-8,8,8,8,6,0,0,0,0,0,0,0,0,0,0x17,0x17,
-0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,0,0,0,0,0,0,
-8,8,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-8,8,8,8,8,8,8,8,8,8,8,8,6,6,6,6,
-6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,5,
-5,5,5,5,0x17,0x17,0x17,5,0x17,5,0,0,5,5,5,5,
-5,5,6,6,6,6,6,6,6,6,0x17,0x17,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,
-6,6,6,6,6,6,6,6,6,6,8,8,0,0,0,0,
-0,0,0,0,0,0,0,0x17,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,0,0,0,8,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
-0x17,0x17,0x17,0x17,0x17,0x17,0,4,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,
-0x249,0x289,0,0,0,0,0x17,0x17,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,6,8,8,6,6,
-6,6,8,8,6,8,8,8,5,5,5,5,5,6,4,5,
-5,5,5,5,5,5,5,5,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,
-0x249,0x289,5,5,5,5,5,0,5,5,5,5,5,5,5,5,
-5,6,6,6,6,6,6,8,8,6,6,8,8,6,6,0,
-0,0,0,0,0,0,0,0,5,5,5,6,5,5,5,5,
-5,5,5,5,6,8,0,0,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,
-0x249,0x289,0,0,0x17,0x17,0x17,0x17,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,4,5,5,5,5,5,5,0x1b,
-0x1b,0x1b,5,8,6,8,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,6,5,6,6,6,5,5,6,
-6,5,5,5,5,5,6,6,5,6,5,0,0,0,0,0,
+1,2,1,2,1,2,1,2,1,2,1,2,4,4,6,6,
+1,2,1,2,1,2,1,2,1,2,1,2,1,2,5,6,
+7,7,7,0x17,6,6,6,6,6,6,6,6,6,6,0x17,4,
+5,5,5,5,5,5,0x58a,0x5ca,0x60a,0x64a,0x68a,0x6ca,0x70a,0x74a,0x78a,0x54a,
+6,6,0x17,0x17,0x17,0x17,0x17,0x17,0,0,0,0,0,0,0,0,
+0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,
+0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,4,4,4,4,4,4,4,4,4,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,5,5,4,0x17,0x17,5,5,5,5,5,5,5,5,
-5,5,5,8,6,6,8,8,0x17,0x17,5,4,4,8,6,0,
-0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,0,
-0,5,5,5,5,5,5,0,0,5,5,5,5,5,5,0,
-0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,0,
-5,5,5,5,5,5,5,0,2,2,2,2,2,2,2,2,
-2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
-2,2,2,0x1a,4,4,4,4,2,2,2,2,2,2,0,0,
-0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,
-2,2,2,2,2,2,2,2,5,5,5,8,8,6,8,8,
-6,8,8,0x17,8,6,0,0,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,
-0x249,0x289,0,0,0,0,0,0,5,5,5,5,0,0,0,0,
-0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,5,
+0,0,0,0,0,1,2,5,4,4,2,5,5,5,5,5,
+0x1a,0x1a,1,2,1,2,1,2,1,2,1,2,1,2,1,2,
+2,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,
+1,2,1,2,4,2,2,2,2,2,2,2,2,1,2,1,
+2,1,1,2,1,2,1,2,1,2,1,2,4,0x1a,0x1a,1,
+2,1,2,5,1,2,1,2,2,2,1,2,1,2,1,2,
+1,2,1,2,1,2,1,1,1,1,1,2,1,1,1,1,
+1,2,1,2,1,2,1,2,1,2,1,2,0,0,1,2,
+1,1,1,1,2,1,2,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,5,5,6,5,
+5,5,6,5,5,5,5,6,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,8,
+8,6,6,8,0x1b,0x1b,0x1b,0x1b,6,0,0,0,0x34cb,0x344b,0x3ccb,0x37cb,
+0x35cb,0x3fcb,0x1b,0x1b,0x19,0x1b,0,0,0,0,0,0,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+0x17,0x17,0x17,0x17,0,0,0,0,0,0,0,0,8,8,8,8,
+6,6,0,0,0,0,0,0,0,0,0x17,0x17,0x49,0x89,0xc9,0x109,
+0x149,0x189,0x1c9,0x209,0x249,0x289,0,0,0,0,0,0,8,8,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,8,8,8,8,
+8,8,8,8,8,8,8,8,6,6,6,6,6,6,6,6,
+6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,
+0x17,0x17,0x17,5,0x17,5,5,6,5,5,5,5,5,5,6,6,
+6,6,6,6,6,6,0x17,0x17,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,
+6,6,6,6,6,6,8,8,0,0,0,0,0,0,0,0,
+0,0,0,0x17,8,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
+0x17,0x17,0,4,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,0,0,
+0,0,0x17,0x17,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,6,8,8,6,6,6,6,8,8,
+6,6,8,8,5,5,5,5,5,6,4,5,5,5,5,5,
+5,5,5,5,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,5,5,
+5,5,5,0,5,5,5,5,5,5,5,5,5,6,6,6,
+6,6,6,8,8,6,6,8,8,6,6,0,0,0,0,0,
+0,0,0,0,5,5,5,6,5,5,5,5,5,5,5,5,
+6,8,0,0,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,0,0,
+0x17,0x17,0x17,0x17,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,4,5,5,5,5,5,5,0x1b,0x1b,0x1b,5,8,
+6,8,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,6,5,6,6,6,5,5,6,6,5,5,5,
+5,5,6,6,5,6,5,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,
+5,4,0x17,0x17,5,5,5,5,5,5,5,5,5,5,5,8,
+6,6,8,8,0x17,0x17,5,4,4,8,6,0,0,0,0,0,
+0,0,0,0,0,5,5,5,5,5,5,0,0,5,5,5,
+5,5,5,0,0,5,5,5,5,5,5,0,0,0,0,0,
+0,0,0,0,5,5,5,5,5,5,5,0,5,5,5,5,
+5,5,5,0,2,2,2,2,2,2,2,2,2,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0x1a,
+4,4,4,4,2,2,2,2,2,2,2,2,2,4,0x1a,0x1a,
+0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,
+2,2,2,2,5,5,5,8,8,6,8,8,6,8,8,0x17,
+8,6,0,0,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,0,0,
+0,0,0,0,5,5,5,5,0,0,0,0,0,0,0,0,
+0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+0,0,0,0,5,5,5,5,5,5,5,0,0,0,0,5,
 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
 5,5,5,5,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,
 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,
@@ -897,136 +925,154 @@
 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
 5,0x7c5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
 5,5,0,0,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,
-0,0,0,0,5,5,5,5,5,5,5,5,5,0x18,5,5,
-5,5,5,5,5,5,5,5,5,5,5,0,5,5,5,5,
-5,0,5,0,5,5,0,5,5,0,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,2,2,2,2,2,2,2,0,0,0,0,0,
-0,0,0,0,0,0,0,2,2,2,2,2,0,0,0,0,
-0,5,6,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,
-0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,0x15,0x14,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,0,0,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-5,5,5,5,5,5,5,5,5,5,5,5,0x19,0x1b,0,0,
-6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
-0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x14,0x15,0x17,0,0,0,0,0,0,
-6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
-0x17,0x13,0x13,0x16,0x16,0x14,0x15,0x14,0x15,0x14,0x15,0x14,0x15,0x14,0x15,0x14,
-0x15,0x17,0x17,0x14,0x15,0x17,0x17,0x17,0x17,0x16,0x16,0x16,0x17,0x17,0x17,0,
-0x17,0x17,0x17,0x17,0x13,0x14,0x15,0x14,0x15,0x14,0x15,0x17,0x17,0x17,0x18,0x13,
-0x18,0x18,0x18,0,0x17,0x19,0x17,0x17,0,0,0,0,5,5,5,5,
+5,5,5,5,5,0x18,5,5,5,5,5,5,5,5,5,5,
+5,5,5,0,5,5,5,5,5,0,5,0,5,5,0,5,
 5,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,2,2,2,2,
+2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,2,
+2,2,2,2,0,0,0,0,0,5,6,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,0x1a,0x1a,
+0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,
 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,0,0,0x10,0,0,5,5,5,5,5,5,0,0,5,5,
-5,5,5,5,0,0,5,5,5,5,5,5,0,0,5,5,
-5,0,0,0,0x19,0x19,0x18,0x1a,0x1b,0x19,0x19,0,0x1b,0x18,0x18,0x18,
-0x18,0x1b,0x1b,0,0,0,0,0,0,0,0,0,0,0x10,0x10,0x10,
-0x1b,0x1b,0,0,0,0x17,0x17,0x17,0x19,0x17,0x17,0x17,0x14,0x15,0x17,0x18,
-0x17,0x13,0x17,0x17,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,0x17,0x17,
-0x18,0x18,0x18,0x17,0x1a,2,2,2,2,2,2,2,2,2,2,2,
-2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0x14,
-0x18,0x15,0x18,0x14,0x15,0x17,0x14,0x15,0x17,0x17,5,5,5,5,5,5,
-5,5,5,5,4,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,4,4,5,5,5,5,5,5,5,5,
-5,5,5,5,0,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,0,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,
-5,5,0,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,0,0,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,0,0,0xb00b,0xb80b,0x784b,0x804b,0x884b,0x904b,0x984b,0xa04b,0xa84b,0xb04b,0xb84b,0x788b,
-0x808b,0x888b,0x908b,0x988b,0xa08b,0xa88b,0xb08b,0xb88b,0,0,0,0x1b,0x1b,0x1b,0x1b,0x1b,
-0x1b,0x1b,0x1b,0x1b,0x17,0x17,0x17,0,0,0,0,0x58b,0x5cb,0x60b,0x64b,0x68b,
-0x6cb,0x70b,0x74b,0x78b,0x7cb,0xa4b,0xccb,0xf4b,0x11cb,0x144b,0x16cb,0x194b,0x1bcb,0x1e4b,0x800b,0x880b,
-0x900b,0x980b,0xa00b,0xa80b,0x7ca,0x7ca,0x7ca,0x7ca,0x7ca,0xcca,0x11ca,0x11ca,0x11ca,0x11ca,0x1e4a,0x880a,
-0x980a,0x980a,0x980a,0x980a,0x980a,0x784a,0x984a,0x68a,0x11ca,0x344b,0x344b,0x388b,0x3ccb,0x1b,0x1b,0x1b,
-0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x54b,0x34cb,0x1b,0,0,0,
-0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0,0,0,
-0x34ca,0x344a,0x58a,0x68a,0x11ca,0x980a,0x984a,0x988a,0x68a,0x7ca,0x11ca,0x1e4a,0x980a,0x784a,0x984a,0x68a,
-0x7ca,0x11ca,0x1e4a,0x980a,0x784a,0x788a,0x988a,0x7ca,0x58a,0x58a,0x58a,0x5ca,0x5ca,0x5ca,0x5ca,0x68a,
-0x1b,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
-0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,6,0,0,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-6,0x58b,0x5cb,0x60b,0x64b,0x68b,0x6cb,0x70b,0x74b,0x78b,0x7cb,0xa4b,0xccb,0xf4b,0x11cb,0x144b,
-0x16cb,0x194b,0x1bcb,0x1e4b,0x800b,0x880b,0x900b,0x980b,0xa00b,0xa80b,0xb00b,0xb80b,0,0,0,0,
-0x58b,0x68b,0x7cb,0x11cb,0,0,0,0,0,0,0,0,0,0,0,0,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,0x1bca,5,5,5,5,5,5,5,5,0xb80a,0,0,0,0,0,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,6,6,6,6,6,0,0,0,0,0,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0x17,
-5,5,5,5,0,0,0,0,5,5,5,5,5,5,5,5,
-0x17,0x58a,0x5ca,0x7ca,0xa4a,0x1e4a,0,0,0,0,0,0,0,0,0,0,
-2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,
-0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0x17,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,0x15,0x14,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,0,5,5,0,0,0,5,0,0,5,
-5,5,5,5,5,5,0,0,5,0,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,0,0x17,0x58b,0x5cb,0x60b,0x7cb,0xa4b,0x1e4b,0x784b,0x788b,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,0x1b,0x1b,0x58b,0x5cb,0x60b,0x64b,0x68b,0x7cb,0xa4b,0,0,0,0,
-0,0,0,0x58b,0x5cb,0x60b,0x64b,0x64b,0x68b,0x7cb,0xa4b,0x1e4b,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,
-5,5,0,0,0,0,0,0x58b,0x68b,0x7cb,0xa4b,0x1e4b,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,0x58b,0x7cb,0xa4b,0x1e4b,0x5cb,0x60b,0,0,0,0x17,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,0,0,0,0,0,0x17,0xa04b,0xa84b,0xb04b,0xb84b,
-0x788b,0x808b,0x888b,0x908b,0x988b,0xa08b,0xa88b,0xb08b,0xb88b,0x78cb,0x80cb,0x88cb,0x90cb,0x98cb,0xa0cb,0xa8cb,
-0xb0cb,0xb8cb,0x36cb,0x354b,0x34cb,0x348b,0x46cb,0x344b,0x4ecb,0x388b,0x3ccb,0x454b,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,0,0,0,0,0x5ecb,0x344b,5,5,0x58b,0x5cb,0x60b,0x64b,
-0x68b,0x6cb,0x70b,0x74b,0x78b,0x7cb,0xa4b,0xccb,0xf4b,0x11cb,0x144b,0x16cb,0,0,0x1e4b,0x800b,
-0x880b,0x900b,0x980b,0xa00b,0xa80b,0xb00b,0xb80b,0x784b,0x804b,0x884b,0x904b,0x984b,0x30b,0x34b,0x38b,0x3cb,
-0x7cb,0xa4b,0x1e4b,0x784b,0,0,0,0,0,0,0,0,0x17,0x17,0x17,0x17,
-0x17,0x17,0x17,0x17,0x17,0,0,0,0,0,0,0,5,6,6,6,
-0,6,6,0,0,0,0,0,6,6,6,6,5,5,5,5,
-0,5,5,5,0,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,
-6,6,6,0,0,0,0,6,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,0x58b,0x11cb,0x17,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,0x58b,0x7cb,0xa4b,5,5,5,5,5,6,6,0,
-0,0,0,0x58b,0x68b,0x7cb,0xa4b,0x1e4b,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0,
+0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,
-0x1b,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,0,0,0,0x17,0x17,0x17,
-0x17,0x17,0x17,0x17,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,0,0,0x58b,0x5cb,0x60b,0x64b,
-0x7cb,0xa4b,0x1e4b,0x784b,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,0,0,0,0,0,0x58b,0x5cb,0x60b,0x64b,
-0x7cb,0xa4b,0x1e4b,0x784b,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,0,0,0,0,0,0,0,0x17,0x17,0x17,
-0x17,0,0,0,0,0,0,0,0,0,0,0,0,0x58b,0x5cb,0x60b,
-0x64b,0x7cb,0xa4b,0x1e4b,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,5,5,5,5,5,5,5,5,5,0,0,0,
+5,5,5,5,0x19,0x1b,0,0,6,6,6,6,6,6,6,6,
+6,6,6,6,6,6,6,6,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x14,
+0x15,0x17,0,0,0,0,0,0,6,6,6,6,6,6,6,6,
+6,6,6,6,6,6,6,6,0x17,0x13,0x13,0x16,0x16,0x14,0x15,0x14,
+0x15,0x14,0x15,0x14,0x15,0x14,0x15,0x14,0x15,0x17,0x17,0x14,0x15,0x17,0x17,0x17,
+0x17,0x16,0x16,0x16,0x17,0x17,0x17,0,0x17,0x17,0x17,0x17,0x13,0x14,0x15,0x14,
+0x15,0x14,0x15,0x17,0x17,0x17,0x18,0x13,0x18,0x18,0x18,0,0x17,0x19,0x17,0x17,
+0,0,0,0,5,5,5,5,5,0,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,0,0,0x10,0,0,5,5,
+5,5,5,5,0,0,5,5,5,5,5,5,0,0,5,5,
+5,5,5,5,0,0,5,5,5,0,0,0,0x19,0x19,0x18,0x1a,
+0x1b,0x19,0x19,0,0x1b,0x18,0x18,0x18,0x18,0x1b,0x1b,0,0,0,0,0,
+0,0,0,0,0,0x10,0x10,0x10,0x1b,0x1b,0,0,0,0x17,0x17,0x17,
+0x19,0x17,0x17,0x17,0x14,0x15,0x17,0x18,0x17,0x13,0x17,0x17,0x49,0x89,0xc9,0x109,
+0x149,0x189,0x1c9,0x209,0x249,0x289,0x17,0x17,0x18,0x18,0x18,0x17,0x1a,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+2,2,2,2,2,2,2,0x14,0x18,0x15,0x18,0x14,0x15,0x17,0x14,0x15,
+0x17,0x17,5,5,5,5,5,5,5,5,5,5,4,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,
+5,5,5,5,5,5,5,5,5,5,5,5,0,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,0,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,0,5,5,0,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,0,0,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,0,0,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,0,0,0,0,0,0xb00b,0xb80b,0x784b,0x804b,
+0x884b,0x904b,0x984b,0xa04b,0xa84b,0xb04b,0xb84b,0x788b,0x808b,0x888b,0x908b,0x988b,0xa08b,0xa88b,0xb08b,0xb88b,
+0,0,0,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x17,0x17,0x17,0,
+0,0,0,0x58b,0x5cb,0x60b,0x64b,0x68b,0x6cb,0x70b,0x74b,0x78b,0x7cb,0xa4b,0xccb,0xf4b,
+0x11cb,0x144b,0x16cb,0x194b,0x1bcb,0x1e4b,0x800b,0x880b,0x900b,0x980b,0xa00b,0xa80b,0x7ca,0x7ca,0x7ca,0x7ca,
+0x7ca,0xcca,0x11ca,0x11ca,0x11ca,0x11ca,0x1e4a,0x880a,0x980a,0x980a,0x980a,0x980a,0x980a,0x784a,0x984a,0x68a,
+0x11ca,0x344b,0x344b,0x388b,0x3ccb,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x54b,0x34cb,0x1b,0x1b,0x1b,0,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0,0,0,0x34ca,0x344a,0x58a,0x68a,0x11ca,0x980a,0x984a,0x988a,
+0x68a,0x7ca,0x11ca,0x1e4a,0x980a,0x784a,0x984a,0x68a,0x7ca,0x11ca,0x1e4a,0x980a,0x784a,0x788a,0x988a,0x7ca,
+0x58a,0x58a,0x58a,0x5ca,0x5ca,0x5ca,0x5ca,0x68a,0x1b,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,
-1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,
-0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,
-2,2,2,2,2,2,2,0,0,0,0,0,0,0,0x58b,0x68b,
-0x7cb,0x11cb,0x1e4b,0x784b,0x30b,0x34b,0x38b,0x3cb,0x40b,0x44b,0x48b,0x4cb,0x50b,0x7cb,0xa4b,0xccb,
-0xf4b,0x11cb,0x144b,0x16cb,0x194b,0x1bcb,0x1e4b,0x800b,0x880b,0x900b,0x980b,0xa00b,0xa80b,0xb00b,0xb80b,0x344b,
-0x34cb,0x348b,0x388b,0,0x144b,0x16cb,0x194b,0x1bcb,0x1e4b,0x784b,0x49,0x89,0xc9,0x109,0x149,0x189,
+0,0,0,0,0,0,0,0,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,6,0,0,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,6,0x58b,0x5cb,0x60b,0x64b,0x68b,0x6cb,0x70b,
+0x74b,0x78b,0x7cb,0xa4b,0xccb,0xf4b,0x11cb,0x144b,0x16cb,0x194b,0x1bcb,0x1e4b,0x800b,0x880b,0x900b,0x980b,
+0xa00b,0xa80b,0xb00b,0xb80b,0,0,0,0,0x58b,0x68b,0x7cb,0x11cb,0,0,0,0,
+0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,0x1bca,5,5,5,5,5,5,
+5,5,0xb80a,0,0,0,0,0,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,
+6,6,6,0,0,0,0,0,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,0,0x17,5,5,5,5,0,0,0,0,
+5,5,5,5,5,5,5,5,0x17,0x58a,0x5ca,0x7ca,0xa4a,0x1e4a,0,0,
+0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,
+2,2,2,2,2,2,2,2,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,0,0,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,
+0x249,0x289,0,0,0,0,0,0,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+2,2,2,2,0,0,0,0,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,
+2,2,2,2,2,2,2,2,5,5,5,5,5,5,5,5,
+0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,
+0,0,0,0x17,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,0,5,5,0,0,0,
+5,0,0,5,5,5,5,5,5,5,0,0,5,0,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,0,0x17,0x58b,0x5cb,0x60b,0x7cb,0xa4b,0x1e4b,0x784b,0x788b,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,0x1b,0x1b,0x58b,0x5cb,0x60b,0x64b,0x68b,0x7cb,0xa4b,
+0,0,0,0,0,0,0,0x58b,0x5cb,0x60b,0x64b,0x64b,0x68b,0x7cb,0xa4b,0x1e4b,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,0,5,5,0,0,0,0,0,0x58b,0x68b,0x7cb,0xa4b,0x1e4b,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,0x58b,0x7cb,0xa4b,0x1e4b,0x5cb,0x60b,0,0,0,0x17,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0x17,
+0xa04b,0xa84b,0xb04b,0xb84b,0x788b,0x808b,0x888b,0x908b,0x988b,0xa08b,0xa88b,0xb08b,0xb88b,0x78cb,0x80cb,0x88cb,
+0x90cb,0x98cb,0xa0cb,0xa8cb,0xb0cb,0xb8cb,0x36cb,0x354b,0x34cb,0x348b,0x46cb,0x344b,0x4ecb,0x388b,0x3ccb,0x454b,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,0,0,0,0,0x5ecb,0x344b,5,5,
+0x58b,0x5cb,0x60b,0x64b,0x68b,0x6cb,0x70b,0x74b,0x78b,0x7cb,0xa4b,0xccb,0xf4b,0x11cb,0x144b,0x16cb,
+0,0,0x1e4b,0x800b,0x880b,0x900b,0x980b,0xa00b,0xa80b,0xb00b,0xb80b,0x784b,0x804b,0x884b,0x904b,0x984b,
+0x30b,0x34b,0x38b,0x3cb,0x7cb,0xa4b,0x1e4b,0x784b,0x344b,0,0,0,0,0,0,0,
+0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0,0,0,0,0,0,0,
+5,6,6,6,0,6,6,0,0,0,0,0,6,6,6,6,
+5,5,5,5,0,5,5,5,0,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,0,0,6,6,6,0,0,0,0,6,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,0x58b,0x11cb,0x17,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,0x58b,0x7cb,0xa4b,5,5,5,5,
+5,6,6,0,0,0,0,0x58b,0x68b,0x7cb,0xa4b,0x1e4b,0x17,0x17,0x17,0x17,
+0x17,0x17,0x17,0,0,0,0,0,0,0,0,0,5,5,5,5,
+5,5,5,5,0x1b,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,
+0,0x17,0x17,0x17,0x17,0x17,0x17,0x17,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,
+0x58b,0x5cb,0x60b,0x64b,0x7cb,0xa4b,0x1e4b,0x784b,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,
+0x58b,0x5cb,0x60b,0x64b,0x7cb,0xa4b,0x1e4b,0x784b,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,
+0,0x17,0x17,0x17,0x17,0,0,0,0,0,0,0,0,0,0,0,
+0,0x58b,0x5cb,0x60b,0x64b,0x7cb,0xa4b,0x1e4b,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,
+5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,
+0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,
+0,0,0x58b,0x68b,0x7cb,0x11cb,0x1e4b,0x784b,5,5,5,5,6,6,6,6,
+0,0,0,0,0,0,0,0,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,
+0x249,0x289,0,0,0,0,0,0,0x30b,0x34b,0x38b,0x3cb,0x40b,0x44b,0x48b,0x4cb,
+0x50b,0x7cb,0xa4b,0xccb,0xf4b,0x11cb,0x144b,0x16cb,0x194b,0x1bcb,0x1e4b,0x800b,0x880b,0x900b,0x980b,0xa00b,
+0xa80b,0xb00b,0xb80b,0x344b,0x34cb,0x348b,0x388b,0,5,5,5,5,5,5,5,5,
+5,5,0,6,6,0x13,0,0,5,5,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,0x58b,0x5cb,0x60b,0x64b,0x68b,0x7cb,0xa4b,0xccb,0x1e4b,0x344b,5,
+0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,
+6,6,6,6,6,0x58b,0x7cb,0xa4b,0x1e4b,0x17,0x17,0x17,0x17,0x17,0,0,
+0,0,0,0,5,5,5,5,5,0x58b,0x5cb,0x60b,0x64b,0x7cb,0xa4b,0x1e4b,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0x144b,0x16cb,0x194b,0x1bcb,0x1e4b,0x784b,0x49,0x89,0xc9,0x109,0x149,0x189,
 0x1c9,0x209,0x249,0x289,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,6,8,6,8,5,5,5,5,5,5,5,5,5,
 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
@@ -1035,24 +1081,24 @@
 0xa4b,0xccb,0xf4b,0x11cb,5,5,5,5,5,5,5,5,5,5,5,5,
 5,5,5,5,8,8,8,6,6,6,6,8,8,6,6,0x17,
 0x17,0x10,0x17,0x17,0x17,0x17,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,
+0,0x10,0,0,5,5,5,5,5,5,5,5,5,5,5,5,
 5,5,5,5,5,0,0,0,0,0,0,0,0x49,0x89,0xc9,0x109,
 0x149,0x189,0x1c9,0x209,0x249,0x289,0,0,0,0,0,0,5,5,5,5,
 5,5,5,6,6,6,6,6,8,6,6,6,6,6,6,6,
 6,0,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,0x17,0x17,0x17,0x17,
-0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,
+5,8,8,5,0,0,0,0,0,0,0,0,5,5,5,5,
 5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,5,
 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,
 0x17,0x17,5,0,0,0,0,0,0,0,0,0,8,5,5,5,
-5,0x17,0x17,0x17,0x17,0x17,6,6,6,0x17,0,0,0x49,0x89,0xc9,0x109,
+5,0x17,0x17,0x17,0x17,6,6,6,6,0x17,8,6,0x49,0x89,0xc9,0x109,
 0x149,0x189,0x1c9,0x209,0x249,0x289,5,0x17,5,0x17,0x17,0x17,5,5,5,5,
 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,8,
 8,8,6,6,6,6,6,6,6,6,6,8,0,0x58b,0x5cb,0x60b,
 0x64b,0x68b,0x6cb,0x70b,0x74b,0x78b,0x7cb,0xa4b,0xccb,0xf4b,0x11cb,0x144b,0x16cb,0x194b,0x1bcb,0x1e4b,
 0x784b,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,
 5,5,5,5,5,5,5,5,8,8,8,6,6,6,8,8,
-6,8,6,6,0x17,0x17,0x17,0x17,0x17,0x17,0,0,5,5,5,5,
+6,8,6,6,0x17,0x17,0x17,0x17,0x17,0x17,6,0,5,5,5,5,
 5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,5,
 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,
 5,0,5,5,5,5,0,5,5,5,5,5,5,5,5,5,
@@ -1064,63 +1110,127 @@
 6,6,6,6,6,0,0,0,6,6,6,6,6,0,0,0,
 0,0,0,0,0,0,0,0,6,6,8,8,0,5,5,5,
 5,5,5,5,5,0,0,5,5,0,0,5,5,5,5,5,
-5,5,5,5,5,5,5,5,6,8,8,8,8,0,0,8,
-8,0,0,8,8,8,0,0,5,0,0,0,0,0,0,8,
-0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,8,8,8,6,6,6,6,6,
-6,8,6,8,8,8,8,6,6,8,6,6,5,5,0x17,5,
-0,0,0,0,0,0,0,0,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,
-0x249,0x289,0,0,0,0,0,0,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,8,8,8,6,6,6,6,0,0,
-8,8,8,8,6,6,8,6,6,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
-0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
-5,5,5,5,6,6,0,0,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,8,8,8,6,6,6,6,6,
-6,6,6,8,8,6,8,6,6,0x17,0x17,0x17,5,0,0,0,
-0,0,0,0,0,0,0,0,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,
-0x249,0x289,0,0,0,0,0,0,5,5,5,5,5,5,5,5,
-5,5,5,6,8,6,8,8,6,6,6,6,6,6,8,6,
-0,0,0,0,0,0,0,0,8,8,6,6,6,6,8,6,
-6,6,6,6,0,0,0,0,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,
-0x249,0x289,0x7cb,0xa4b,0x17,0x17,0x17,0x1b,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,0,5,5,5,5,5,5,
+5,0,5,5,0,5,5,5,5,5,0,6,6,5,8,8,
+6,8,8,8,8,0,0,8,8,0,0,8,8,8,0,0,
+5,0,0,0,0,0,0,8,0,0,0,0,0,5,5,5,
 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,0,0,0,6,6,6,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,
-0x249,0x289,0x7cb,0xa4b,0xccb,0xf4b,0x11cb,0x144b,0x16cb,0x194b,0x1bcb,0,0,0,0,0,
-0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,8,8,8,6,6,6,6,6,6,6,6,
+8,8,6,6,6,8,6,5,5,5,5,0x17,0x17,0x17,0x17,0x17,
+0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,0x17,0x17,0,0x17,6,5,
+5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,0,0,0,0,0,0,0,0x34ca,0x354a,0x34ca,0x34ca,0x344a,0x348a,0x388a,0xf4a,
-0x11ca,0x64a,0x68a,0x6ca,0x70a,0x74a,0x78a,0,0x17,0x17,0x17,0x17,0x17,0,0,0,
-0,0,0,0,0,0,0,0,0x5ca,0x60a,0x64a,0x68a,0x6ca,0x70a,0x74a,0x78a,
-0x60a,0x64a,0x68a,0x6ca,0x70a,0x74a,0x78a,0x64a,0x68a,0x6ca,0x70a,0x74a,0x78a,0x58a,0x5ca,0x60a,
-0x64a,0x68a,0x6ca,0x70a,0x74a,0x78a,0x58a,0x5ca,0x60a,0x64a,0x68a,0x5ca,0x60a,0x60a,0x64a,0x68a,
-0x6ca,0x70a,0x74a,0x78a,0x58a,0x5ca,0x60a,0x60a,0x64a,0x68a,0xc08a,0xc18a,0x58a,0x5ca,0x60a,0x60a,
-0x64a,0x68a,0x60a,0x60a,0x64a,0x64a,0x64a,0x64a,0x6ca,0x70a,0x70a,0x70a,0x74a,0x74a,0x78a,0x78a,
-0x78a,0x78a,0x5ca,0x60a,0x64a,0x68a,0x6ca,0x58a,0x5ca,0x60a,0x64a,0x64a,0x68a,0x68a,0x5ca,0x60a,
-0x58a,0x5ca,0x348a,0x388a,0x454a,0x348a,0x388a,0x35ca,5,5,5,5,0,0,0,0,
+8,8,8,6,6,6,6,6,6,8,6,8,8,8,8,6,
+6,8,6,6,5,5,0x17,5,0,0,0,0,0,0,0,0,
+0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,0,0,0,0,0,0,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,8,
+8,8,6,6,6,6,0,0,8,8,8,8,6,6,8,6,
+6,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
+0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,5,5,5,5,6,6,0,0,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+8,8,8,6,6,6,6,6,6,6,6,8,8,6,8,6,
+6,0x17,0x17,0x17,5,0,0,0,0,0,0,0,0,0,0,0,
+0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,0,0,0,0,0,0,
+0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+5,5,5,5,5,5,5,5,5,5,5,6,8,6,8,8,
+6,6,6,6,6,6,8,6,5,0,0,0,0,0,0,0,
+8,8,6,6,6,6,8,6,6,6,6,6,0,0,0,0,
+0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,0x7cb,0xa4b,0x17,0x17,0x17,0x1b,
+5,5,5,5,5,5,5,5,5,5,5,5,8,8,8,6,
+6,6,6,6,6,6,6,6,8,6,6,0x17,0,0,0,0,
+0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,0x7cb,0xa4b,0xccb,0xf4b,0x11cb,0x144b,
+0x16cb,0x194b,0x1bcb,0,0,0,0,0,0,0,0,0,0,0,0,5,
+8,5,8,6,0x17,0x17,0x17,0,0,0,0,0,0,0,0,0,
+0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,0,0,0,0,0,0,
+5,5,5,5,5,5,5,0,0,5,0,0,5,5,5,5,
+5,5,5,5,0,5,5,0,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,8,8,8,8,8,8,0,8,
+8,0,0,6,6,8,6,5,6,5,0x17,5,8,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,
+0,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,8,8,8,6,6,6,6,
+0,0,6,6,8,8,8,8,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,
+6,8,5,6,6,6,6,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,6,
+0,0,0,0,0,0,0,0,5,6,6,6,6,6,6,8,
+8,6,6,6,5,5,5,5,5,6,6,6,6,6,6,6,
+6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,0x17,0x17,0x17,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,0,0,0,0,0x17,0x17,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,
-6,6,6,6,6,0x17,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,
+5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,8,
+6,6,0x17,0x17,0x17,5,0x17,0x17,5,0x17,0x17,0x17,0x17,0x17,0,0,
+0,0,0,0,0,0,0,0,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,
+0x249,0x289,0x58b,0x5cb,0x60b,0x64b,0x68b,0x6cb,0x70b,0x74b,0x78b,0x7cb,0xa4b,0xccb,0xf4b,0x11cb,
+0x144b,0x16cb,0x194b,0x1bcb,0x1e4b,0,0,0,0x17,0x17,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,0,5,5,5,5,5,5,
 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+5,5,5,8,6,6,6,6,6,6,6,0,6,6,6,6,
+6,6,8,6,6,6,6,6,6,6,6,6,0,8,6,6,
+6,6,6,6,6,8,6,6,8,6,6,0,0,0,0,0,
+0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,0,0,6,6,6,6,6,6,6,6,6,6,
+6,6,6,6,6,6,5,6,0,0,0,0,0,0,0,0,
+0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,0,0,0,0,0,0,
+5,5,5,5,5,5,5,0,5,5,0,5,5,5,5,5,
 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-6,6,6,6,6,6,6,0x17,0x17,0x17,0x17,0x17,0x1b,0x1b,0x1b,0x1b,
-4,4,4,4,0x17,0x1b,0,0,0,0,0,0,0,0,0,0,
-0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,0,0x7cb,0x1e4b,0x788b,0x790b,0x798b,
-0x7a0b,0x7a8b,0,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,0,0,0,0,0,5,5,5,
-5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,
-5,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+5,6,6,6,6,6,6,0,0,0,6,0,6,6,0,6,
+5,5,5,5,5,5,5,5,5,5,8,8,8,8,8,0,
+6,6,0,8,8,6,8,6,5,0,0,0,0,0,0,0,
+5,5,5,5,5,5,0,5,5,0,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,6,6,8,8,0x17,0x17,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0x19,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0x17,0xcd0b,0xcc0b,0xcb0b,0xd00b,
+0xca0b,0xcf0b,0xcb4b,0xd04b,0xc90b,0x37cb,0x37cb,0x364b,0x35cb,0xc94b,0x3fcb,0x350b,0x34cb,0x344b,0x344b,0x3ccb,
+0xcd0b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x19,0x19,0x19,0x34ca,0x354a,0x34ca,0x34ca,
+0x344a,0x348a,0x388a,0xf4a,0x11ca,0x64a,0x68a,0x6ca,0x70a,0x74a,0x78a,0,0x17,0x17,0x17,0x17,
+0x17,0,0,0,0,0,0,0,0,0,0,0,0x5ca,0x60a,0x64a,0x68a,
+0x6ca,0x70a,0x74a,0x78a,0x60a,0x64a,0x68a,0x6ca,0x70a,0x74a,0x78a,0x64a,0x68a,0x6ca,0x70a,0x74a,
+0x78a,0x58a,0x5ca,0x60a,0x64a,0x68a,0x6ca,0x70a,0x74a,0x78a,0x58a,0x5ca,0x60a,0x64a,0x68a,0x5ca,
+0x60a,0x60a,0x64a,0x68a,0x6ca,0x70a,0x74a,0x78a,0x58a,0x5ca,0x60a,0x60a,0x64a,0x68a,0xc08a,0xc18a,
+0x58a,0x5ca,0x60a,0x60a,0x64a,0x68a,0x60a,0x60a,0x64a,0x64a,0x64a,0x64a,0x6ca,0x70a,0x70a,0x70a,
+0x74a,0x74a,0x78a,0x78a,0x78a,0x78a,0x5ca,0x60a,0x64a,0x68a,0x6ca,0x58a,0x5ca,0x60a,0x64a,0x64a,
+0x68a,0x68a,0x5ca,0x60a,0x58a,0x5ca,0x348a,0x388a,0x454a,0x348a,0x388a,0x35ca,5,5,5,5,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,0,0x10,0x10,0x10,0x10,
+0x10,0x10,0x10,0x10,0x10,0,0,0,0,0,0,0,5,5,5,5,
+5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0x49,0x89,0xc9,0x109,
+0x149,0x189,0x1c9,0x209,0x249,0x289,0,0,0,0,0x17,0x17,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,0,0,6,6,6,6,
+6,0x17,0,0,0,0,0,0,0,0,0,0,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,
+6,6,6,0x17,0x17,0x17,0x17,0x17,0x1b,0x1b,0x1b,0x1b,4,4,4,4,
+0x17,0x1b,0,0,0,0,0,0,0,0,0,0,0x49,0x89,0xc9,0x109,
+0x149,0x189,0x1c9,0x209,0x249,0x289,0,0x7cb,0x1e4b,0x788b,0x790b,0x798b,0x7a0b,0x7a8b,0,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,0,0,0,0,0,5,5,5,0x54b,0x58b,0x5cb,0x60b,
+0x64b,0x68b,0x6cb,0x70b,0x74b,0x78b,0x7cb,0x80b,0x84b,0x88b,0x8cb,0x90b,0x94b,0x98b,0x9cb,0xa0b,
+0x58b,0x5cb,0x60b,0x17,0x17,0x17,0x17,0,0,0,0,0,5,5,5,5,
+5,5,5,5,5,5,5,0,0,0,0,6,5,8,8,8,
 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
-8,8,8,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,6,6,6,6,4,4,4,4,4,4,4,4,4,
-4,4,4,4,5,5,0,0,0,0,0,0,0,0,0,0,
+8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+0,0,0,0,0,0,0,6,6,6,6,4,4,4,4,4,
+4,4,4,4,4,4,4,4,4,4,0x17,4,6,0,0,0,
+0,0,0,0,0,0,0,0,8,8,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,0,
+5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,
+5,5,5,5,0,0,0,0,0,0,0,0,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,
 0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,
 5,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,
 5,5,0,0,0x1b,6,6,0x17,0x10,0x10,0x10,0x10,0,0,0,0,
@@ -1136,8 +1246,10 @@
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0x1b,0x1b,6,6,6,0x1b,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0x54b,0x58b,0x5cb,0x60b,0x64b,0x68b,0x6cb,0x70b,0x74b,0x78b,0x7cb,0x80b,
+0x84b,0x88b,0x8cb,0x90b,0x94b,0x98b,0x9cb,0xa0b,0,0,0,0,0,0,0,0,
 0,0,0,0,0x58b,0x5cb,0x60b,0x64b,0x68b,0x6cb,0x70b,0x74b,0x78b,0x7cb,0xa4b,0xccb,
-0xf4b,0x11cb,0x144b,0x16cb,0x194b,0x1bcb,0,0,0,0,0,0,0,0,0,0,
+0xf4b,0x11cb,0x144b,0x16cb,0x194b,0x1bcb,0x58b,0x5cb,0x60b,0x64b,0x68b,0x58b,0x68b,0,0,0,
 0,0,0,0,0x249,0x289,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,
 0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,0x49,0x89,0xc9,0x109,0x149,0x189,
 0x1c9,0x209,0x249,0x289,1,1,1,1,1,1,1,1,1,1,1,1,
@@ -1180,2217 +1292,2569 @@
 6,6,6,6,6,6,6,6,6,6,6,6,6,0x1b,0x1b,0x1b,
 0x1b,0x1b,0x1b,0x1b,0x1b,6,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
 6,0x1b,0x1b,0x17,0x17,0x17,0x17,0x17,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,6,6,6,6,6,5,5,5,5,
-5,0,0,0x58b,0x5cb,0x60b,0x64b,0x68b,0x6cb,0x70b,0x74b,0x78b,6,6,6,6,
+0,0,0,0,0,0,0,6,6,6,6,6,6,6,6,0,
+6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+6,0,0,6,6,6,6,6,6,6,0,6,6,0,6,6,
 6,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0x18,0x18,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,5,5,5,5,0,5,5,5,5,5,5,5,
+0,0,0,0,0,0,0,0,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,
+0x249,0x289,0,0,0,0,5,0x1b,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,
+5,5,5,5,5,0,0,0,6,6,6,6,6,6,6,4,
+4,4,4,4,4,4,0,0,5,5,5,5,5,5,5,5,
+5,5,5,5,6,6,6,6,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,
+0x249,0x289,0,0,0,0,0,0x19,5,5,5,5,5,0,0,0x58b,
+0x5cb,0x60b,0x64b,0x68b,0x6cb,0x70b,0x74b,0x78b,6,6,6,6,6,6,6,0,
+0,0,0,0,0,0,0,0,2,2,2,2,6,6,6,6,
+6,6,6,4,0,0,0,0,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,
+0x249,0x289,0,0,0,0,0x17,0x17,1,1,2,2,2,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0x58b,0x5cb,0x60b,0x64b,0x68b,0x6cb,0x70b,
+0x74b,0x78b,0x7cb,0xa4b,0xccb,0xf4b,0x11cb,0x144b,0x78cb,0x794b,0x814b,0x58b,0x5cb,0x60b,0x64b,0x68b,
+0x6cb,0x70b,0x74b,0x78b,0x1b,0x34cb,0x344b,0x3ccb,0x19,0x58b,0x5cb,0x788b,0x78cb,0,0,0,
+0,0,0,0,0,0,0,0,0x16cb,0x194b,0x1bcb,0x1e4b,0x800b,0x880b,0x900b,0x980b,
+0xa00b,0xa80b,0xb00b,0xb80b,0x784b,0x804b,0x884b,0x904b,0x984b,0xa04b,0xa84b,0xb04b,0xb84b,0x788b,0x808b,0x888b,
+0x908b,0x988b,0xa08b,0xa88b,0xb08b,0xb88b,0x78cb,0x80cb,0x984b,0xa04b,0xa84b,0xb04b,0xb84b,0x788b,0x808b,0x888b,
+0x908b,0x988b,0xa08b,0xa88b,0xb08b,0xb88b,0x1b,0x5cb,0x60b,0x64b,0x68b,0x6cb,0x70b,0x74b,0x78b,0x7cb,
+0x900b,0xa00b,0x804b,0x788b,0x344b,0x354b,0,0,0,0x58b,0x5cb,0x60b,0x64b,0x68b,0x6cb,0x70b,
+0x74b,0x78b,0x7cb,0xa4b,0xccb,0xf4b,0x11cb,0x144b,0x16cb,0x194b,0x1bcb,0x1e4b,0x800b,0x880b,0x900b,0x980b,
+0xa00b,0xa80b,0xb00b,0xb80b,0x784b,0x804b,0x884b,0x904b,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0x18,0x18,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,5,5,5,5,0,5,5,5,
 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,0,5,5,0,5,0,0,5,0,5,5,5,
-5,5,5,5,5,5,5,0,5,5,5,5,0,5,0,5,
-0,0,0,0,0,0,5,0,0,0,0,5,0,5,0,5,
-0,5,5,5,0,5,5,0,5,0,0,5,0,5,0,5,
-0,5,0,5,0,5,5,0,5,0,0,5,5,5,5,0,
-5,5,5,5,5,5,5,0,5,5,5,5,0,5,5,5,
-5,0,5,0,5,5,5,5,5,5,5,5,5,5,0,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-0,0,0,0,0,5,5,5,0,5,5,5,5,5,0,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-0,0,0,0,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
-0,0,0,0,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
-0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
-0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
-0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x2cb,0x2cb,0x30b,0x34b,0x38b,0x3cb,0x40b,0x44b,
-0x48b,0x4cb,0x50b,0x54b,0x54b,0,0,0,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
-0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0x1b,0x1b,0x1b,0x1b,
+5,5,5,5,5,5,5,5,0,5,5,0,5,0,0,5,
+0,5,5,5,5,5,5,5,5,5,5,0,5,5,5,5,
+0,5,0,5,0,0,0,0,0,0,5,0,0,0,0,5,
+0,5,0,5,0,5,5,5,0,5,5,0,5,0,0,5,
+0,5,0,5,0,5,0,5,0,5,5,0,5,0,0,5,
+5,5,5,0,5,5,5,5,5,5,5,0,5,5,5,5,
+0,5,5,5,5,0,5,0,5,5,5,5,5,5,5,5,
+5,5,0,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,0,0,0,0,0,5,5,5,0,5,5,5,
+5,5,0,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,0,0,0,0,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0,0,0,0,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x2cb,0x2cb,0x30b,0x34b,
+0x38b,0x3cb,0x40b,0x44b,0x48b,0x4cb,0x50b,0x54b,0x54b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0,0,0,
+0,0,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0x1b,0x1b,0x1b,0x1b,
 0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
-0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0,0,0,0,0,0,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0,0,0,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0,0,0,0,0,0,0,0x1b,0x1b,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0x1b,0x1b,0x1b,0x1b,
 0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
-0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
-0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0,0,0,0,0,0,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1a,0x1a,0x1a,0x1a,0x1a,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0,0,0,0,0,0,0,0,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0,0,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0,0,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0,0,0,0,0,0,0,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0,0,0,0,0,0,0,0,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0,0,0,0,0,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0,0,0,0,0,0,0,0,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0,
 0x1b,0x1b,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
-0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1a,0x1a,0x1a,0x1a,0x1a,
-0x1b,0x1b,0x1b,0x1b,0,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0,
+0x1b,0x1b,0x1b,0x1b,0x1b,0,0,0,0x1b,0x1b,0x1b,0,0,0,0,0,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0,0,0,0,0,0,0,0,
 0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
-0x1b,0,0,0,0x1b,0x1b,0x1b,0x1b,0,0,0,0,0,0,0,0,
-0,0,0,0,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
-0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0,0,0,0,0,0,
-0,0,0,0,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0,0,0,
-0,0,0,0,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0,
-0,0,0,0,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0,0,0,
-0,0,0,0,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
-0x1b,0x1b,0x1b,0x1b,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,5,0x705,5,5,5,5,5,5,
+0x1b,0,0,0,0,0,0,0,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0,0,0,0,0,0,0,0,0,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,5,0x705,5,5,
 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,0x645,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,0x645,5,5,5,
 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,0x645,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,0x645,5,5,5,5,5,
 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,0x685,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,0x685,5,5,5,5,5,5,
 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,0xcc5,5,5,5,5,5,5,5,5,
-0xf45,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-0xf45,5,5,5,5,5,5,5,5,5,5,5,5,5,0x6c5,5,
+5,5,5,5,5,5,5,5,5,5,5,0xcc5,5,5,5,5,
+5,5,5,5,0xf45,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,0xf45,5,5,5,5,5,5,5,5,5,5,5,
+5,5,0x6c5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,0x605,5,5,5,5,5,5,5,5,5,5,
 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
 5,0x605,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,5,5,5,5,5,0x605,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,0x605,5,5,5,
 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,0x605,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,0x605,5,5,5,5,
+5,5,5,5,5,5,5,5,5,0x645,5,5,5,5,5,5,
 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,0x605,5,5,5,5,5,5,5,5,
-5,5,5,5,5,0x645,5,5,5,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,0x785,5,5,5,5,5,5,5,
-5,5,5,5,5,5,5,5,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
-0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
-0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0,0x10,0,0,0,0,0,0,
+5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,6,6,6,6,6,6,6,6,
-6,6,6,6,6,6,6,6,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+0x785,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+0,0x10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
-0x11,0x11,0x11,0x11,0x11,0x11,0,0,0,0,0,0
+0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0,0,
+0,0,0,0
 };
 
 static const UTrie2 propsTrie={
     propsTrie_index,
-    propsTrie_index+4216,
+    propsTrie_index+4532,
     NULL,
-    4216,
-    15604,
+    4532,
+    17744,
     0xa40,
-    0x10f8,
+    0x1234,
     0x0,
     0x0,
     0x110000,
-    0x4d68,
+    0x5700,
     NULL, 0, FALSE, FALSE, 0, NULL
 };
 
-static const uint16_t propsVectorsTrie_index[27452]={
-0x488,0x490,0x498,0x4a0,0x4b8,0x4c0,0x4c8,0x4d0,0x4d8,0x4e0,0x4e8,0x4f0,0x4f8,0x500,0x508,0x510,
-0x517,0x51f,0x527,0x52f,0x532,0x53a,0x542,0x54a,0x552,0x55a,0x562,0x56a,0x572,0x57a,0x582,0x58a,
-0x592,0x59a,0x5a1,0x5a9,0x5b1,0x5b9,0x5c1,0x5c9,0x5d1,0x5d9,0x5de,0x5e6,0x5ed,0x5f5,0x5fd,0x605,
-0x60d,0x615,0x61d,0x625,0x62c,0x634,0x63c,0x644,0x64c,0x654,0x65c,0x664,0x66c,0x674,0x67c,0x684,
-0x180c,0xce8,0xdd3,0x4a8,0x4a8,0xe52,0xe58,0xe60,0x10fc,0x1114,0x1104,0x110c,0x71c,0x722,0x72a,0x732,
-0x73a,0x740,0x748,0x750,0x758,0x75e,0x766,0x76e,0x776,0x77c,0x784,0x78c,0x794,0x79c,0x7a4,0x7ab,
-0x7b3,0x7b9,0x7c1,0x7c9,0x7d1,0x7d7,0x7df,0x7e7,0x7ef,0x7f5,0x7fd,0x805,0x80d,0x814,0x81c,0x824,
-0x82c,0x830,0x838,0x83f,0x847,0x84f,0x857,0x85f,0x141c,0x1424,0x867,0x86f,0x877,0x87f,0x887,0x88e,
-0x1482,0x1472,0x147a,0x174f,0x1757,0x1124,0x896,0x111c,0x1366,0x1366,0x1368,0x1138,0x1139,0x112c,0x112e,0x1130,
-0x148a,0x148c,0x89e,0x148c,0x8a6,0x8ab,0x8b3,0x1491,0x8b9,0x148c,0x8bf,0x8c7,0xbc1,0x1499,0x1499,0x8cf,
-0x14a9,0x14aa,0x14aa,0x14aa,0x14aa,0x14aa,0x14aa,0x14aa,0x14aa,0x14aa,0x14aa,0x14aa,0x14aa,0x14aa,0x14aa,0x14aa,
-0x14aa,0x14aa,0x14aa,0x14a1,0x8d7,0x14b2,0x14b2,0x8df,0xad6,0xade,0xae6,0xaee,0x14c2,0x14ba,0x8e7,0x8ef,
-0x8f7,0x14ca,0x14d2,0x8ff,0x14ca,0x907,0x1814,0xcf0,0xaf6,0xafe,0xb06,0xb0b,0x16c5,0xbf4,0xbfb,0x162d,
-0xb91,0x181c,0xcf8,0xd00,0xd08,0xd10,0xf10,0xf10,0x1715,0x171a,0xc2c,0xc34,0x178b,0x1793,0x18b5,0xddb,
-0x179b,0xc7c,0xc84,0x17a3,0x4a8,0x4a8,0xef0,0xd18,0x164d,0x1635,0x1645,0x163d,0x16dd,0x16d5,0x169d,0xba1,
-0x1141,0x1141,0x1141,0x1141,0x1144,0x1141,0x1141,0x114c,0x90f,0x1154,0x913,0x91b,0x1154,0x923,0x92b,0x933,
-0x1164,0x115c,0x116c,0x93b,0x943,0x94b,0x953,0x95b,0x1174,0x117c,0x1184,0x118c,0x963,0x1194,0x119b,0x11a3,
-0x11ab,0x11b3,0x11bb,0x11c3,0x11cb,0x11d2,0x11da,0x11e2,0x11ea,0x11f2,0x11f5,0x11f7,0x14da,0x15c0,0x15c6,0x96b,
-0x11ff,0x973,0x97b,0x1319,0x131e,0x1321,0x1329,0x1207,0x1331,0x1331,0x1217,0x120f,0x121f,0x1227,0x122f,0x1237,
-0x123f,0x1247,0x124f,0x1257,0x15ce,0x1625,0x175f,0x189d,0x1267,0x126e,0x1276,0x127e,0x125f,0x1286,0x15d6,0x15dd,
-0x14e2,0x14e2,0x14e2,0x14e2,0x14e2,0x14e2,0x14e2,0x14e2,0x15e5,0x15e8,0x15e5,0x15e5,0x15f0,0x15f7,0x15f9,0x1600,
-0x1608,0x160c,0x160c,0x160f,0x160c,0x160c,0x1615,0x160c,0x1655,0x170d,0x1767,0xb13,0xb19,0xb1f,0xb27,0xb2c,
-0x16b5,0xbd1,0xbd5,0x1722,0x16a5,0x16a5,0x16a5,0xba9,0x16ad,0xbc9,0x16f5,0xc1c,0xbb1,0xbb9,0xbb9,0x17ab,
-0x16e5,0x176f,0xc0b,0xc0c,0x983,0x14ea,0x14ea,0x98b,0x14f2,0x14f2,0x14f2,0x14f2,0x14f2,0x14f2,0x993,0x68c,
-0x134e,0x1370,0x99b,0x1378,0x9a3,0x1380,0x1388,0x1390,0x9ab,0x9b0,0x1398,0x139f,0x9b5,0x9bd,0x1705,0xb99,
-0x9c5,0x13f6,0x13fd,0x13a7,0x1405,0x140c,0x13af,0x9cd,0x13c8,0x13c8,0x13ca,0x13b7,0x13bf,0x13bf,0x13c0,0x1414,
-0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,
-0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,
-0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,
-0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,
-0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,
-0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,
-0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,
-0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,
-0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,
-0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,
-0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,
-0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,
-0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x10b3,0x165d,0x165d,
-0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,
-0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,
-0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,
-0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,
-0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,
-0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,
-0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,
-0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,
-0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,
-0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,
-0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,
-0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,
-0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,
-0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,
-0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,
-0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,
-0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,
-0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,
-0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,
-0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,
-0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,
-0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,
-0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,
-0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,
-0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,
-0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,
-0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,
-0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,
-0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,
-0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,
-0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,
-0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,
-0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,
-0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,
-0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,
-0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,
-0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,
-0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,
-0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,
-0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,
-0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d2,0x13d9,0x10bb,0x10c1,
-0x1502,0x1508,0x1508,0x1508,0x1508,0x1508,0x1508,0x1508,0x1508,0x1508,0x1508,0x1508,0x1508,0x1508,0x1508,0x1508,
-0x1508,0x1508,0x1508,0x1508,0x1508,0x1508,0x1508,0x1508,0x1508,0x1508,0x1508,0x1508,0x1508,0x1508,0x1508,0x1508,
-0x1508,0x1508,0x1508,0x1508,0x9d5,0x1510,0x9dd,0x1824,0x17b7,0x17b7,0x17b7,0x17b7,0x17b7,0x17b7,0x17b7,0x17b7,
-0x17b3,0xc8c,0x17c7,0x17bf,0x17c9,0x182c,0x182c,0xd20,0x16bd,0x172a,0x177f,0x1783,0x1777,0xc3c,0xc42,0xc45,
-0x16ed,0xc14,0x1732,0xc4d,0x17d1,0x17d4,0xc94,0xd28,0x17e4,0x17dc,0xc9c,0xd30,0x1834,0x1838,0xd38,0xfb6,
-0x17ec,0xca4,0xcac,0x1840,0x1850,0x1848,0xd40,0xeb3,0xde3,0xdeb,0x19e9,0xf6e,0x1a8e,0x1a8e,0x1858,0xd48,
-0x1464,0x1465,0x1466,0x1467,0x1468,0x1469,0x146a,0x1464,0x1465,0x1466,0x1467,0x1468,0x1469,0x146a,0x1464,0x1465,
-0x1466,0x1467,0x1468,0x1469,0x146a,0x1464,0x1465,0x1466,0x1467,0x1468,0x1469,0x146a,0x1464,0x1465,0x1466,0x1467,
-0x1468,0x1469,0x146a,0x1464,0x1465,0x1466,0x1467,0x1468,0x1469,0x146a,0x1464,0x1465,0x1466,0x1467,0x1468,0x1469,
-0x146a,0x1464,0x1465,0x1466,0x1467,0x1468,0x1469,0x146a,0x1464,0x1465,0x1466,0x1467,0x1468,0x1469,0x146a,0x1464,
-0x1465,0x1466,0x1467,0x1468,0x1469,0x146a,0x1464,0x1465,0x1466,0x1467,0x1468,0x1469,0x146a,0x1464,0x1465,0x1466,
-0x1467,0x1468,0x1469,0x146a,0x1464,0x1465,0x1466,0x1467,0x1468,0x1469,0x146a,0x1464,0x1465,0x1466,0x1467,0x1468,
-0x1469,0x146a,0x1464,0x1465,0x1466,0x1467,0x1468,0x1469,0x146a,0x1464,0x1465,0x1466,0x1467,0x1468,0x1469,0x146a,
-0x1464,0x1465,0x1466,0x1467,0x1468,0x1469,0x146a,0x1464,0x1465,0x1466,0x1467,0x1468,0x1469,0x146a,0x1464,0x1465,
-0x1466,0x1467,0x1468,0x1469,0x146a,0x1464,0x1465,0x1466,0x1467,0x1468,0x1469,0x146a,0x1464,0x1465,0x1466,0x1467,
-0x1468,0x1469,0x146a,0x1464,0x1465,0x1466,0x1467,0x1468,0x1469,0x146a,0x1464,0x1465,0x1466,0x1467,0x1468,0x1469,
-0x146a,0x1464,0x1465,0x1466,0x1467,0x1468,0x1469,0x146a,0x1464,0x1465,0x1466,0x1467,0x1468,0x1469,0x146a,0x1464,
-0x1465,0x1466,0x1467,0x1468,0x1469,0x146a,0x1464,0x1465,0x1466,0x1467,0x1468,0x1469,0x146a,0x1464,0x1465,0x1466,
-0x1467,0x1468,0x1469,0x146a,0x1464,0x1465,0x1466,0x1467,0x1468,0x1469,0x146a,0x1464,0x1465,0x1466,0x1467,0x1468,
-0x1469,0x146a,0x1464,0x1465,0x1466,0x1467,0x1468,0x1469,0x146a,0x1464,0x1465,0x1466,0x1467,0x1468,0x1469,0x146a,
-0x1464,0x1465,0x1466,0x1467,0x1468,0x1469,0x146a,0x1464,0x1465,0x1466,0x1467,0x1468,0x1469,0x146a,0x1464,0x1465,
-0x1466,0x1467,0x1468,0x1469,0x146a,0x1464,0x1465,0x1466,0x1467,0x1468,0x1469,0x146a,0x1464,0x1465,0x1466,0x1467,
-0x1468,0x1469,0x146a,0x1464,0x1465,0x1466,0x1467,0x1468,0x1469,0x146a,0x1464,0x1465,0x1466,0x1467,0x1468,0x1469,
-0x146a,0x1464,0x1465,0x1466,0x1467,0x1468,0x1469,0x146a,0x1464,0x1465,0x1466,0x1467,0x1468,0x1469,0x146a,0x1464,
-0x1465,0x1466,0x1467,0x1468,0x1469,0x146a,0x1464,0x1465,0x1466,0x1467,0x1468,0x1469,0x146a,0x1464,0x1465,0x1466,
-0x1467,0x1468,0x1469,0x146a,0x1464,0x1465,0x1466,0x1467,0x1468,0x1469,0x146a,0x1464,0x1465,0x1466,0x1467,0x1468,
-0x1469,0x146a,0x1464,0x1465,0x1466,0x1467,0x1468,0x1469,0x146a,0x1464,0x1465,0x1466,0x1467,0x1468,0x1469,0x146a,
-0x1464,0x1465,0x1466,0x1467,0x1468,0x1469,0x146a,0x1464,0x1465,0x1466,0x1467,0x1468,0x1469,0x9e5,0xd50,0xd53,
-0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,
-0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,
-0x143c,0x143c,0x143c,0x143c,0x143c,0x143c,0x143c,0x143c,0x143c,0x143c,0x143c,0x143c,0x143c,0x143c,0x143c,0x143c,
-0x143c,0x143c,0x143c,0x143c,0x143c,0x143c,0x143c,0x143c,0x143c,0x143c,0x143c,0x143c,0x143c,0x143c,0x143c,0x143c,
-0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,
-0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,
-0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,
-0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,
-0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,
-0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,
-0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,
-0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,
-0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,
-0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,
-0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,
-0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,
-0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x1339,0x13e1,0x13e1,0x13e1,0x13e1,0x13e1,0x13e1,0x13e1,0x13e1,
-0x13e6,0x13ee,0x161d,0x10c9,0x16fd,0x16fd,0x10cd,0x10d4,0x9ed,0x9f5,0x9fd,0x12a6,0x12ad,0x12b5,0xa05,0x12bd,
-0x12ee,0x12ee,0x1296,0x129e,0x12c5,0x12e5,0x12e6,0x12f6,0x12cd,0x128e,0xa0d,0x12d5,0xa15,0x12dd,0xa1d,0xa21,
-0xc24,0x12fe,0xa29,0xa31,0x1306,0x130c,0x1311,0xa39,0xa49,0x1356,0x135e,0x1341,0x1346,0xa51,0xa59,0xa41,
-0x142c,0x142c,0x142c,0x142c,0x142c,0x142c,0x142c,0x142c,0x142c,0x142c,0x142c,0x142c,0x142c,0x142c,0x142c,0x142c,
-0x142c,0x142c,0x142c,0x142c,0x142c,0x142c,0x142c,0x142c,0x142c,0x142c,0x142c,0x142c,0x1434,0x1434,0x1434,0x1434,
-0x12a0,0x12a0,0x12e0,0x1320,0x1360,0x13a0,0x13e0,0x1420,0x145c,0x149c,0x14c8,0x1508,0x1548,0x1588,0x15c8,0x1608,
-0x1648,0x1684,0x16c4,0x1704,0x1744,0x1778,0x17b4,0x17f4,0x1834,0x1874,0x18b0,0x18f0,0x1930,0x1970,0x19b0,0x19f0,
-0xa80,0xac0,0xb00,0xe48,0xb40,0xa40,0xb80,0xa40,0xe68,0xa40,0xa40,0xa40,0xa40,0xbc0,0xa40,0xa40,
-0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xdcd,0xbfd,0xa40,0xa40,0xc3d,0xc7d,0xa40,0xe0d,0xd8d,0xcbd,
-0x115e,0x115e,0x115e,0x115e,0x115e,0x115e,0x115e,0x115e,0x115e,0x115e,0x115e,0x115e,0x115e,0x115e,0x115e,0x115e,
-0x115e,0x115e,0x115e,0x115e,0xea8,0x119e,0xfde,0x101e,0x11de,0xee8,0xf1e,0xf1e,0xf1e,0xf1e,0xf1e,0xf5e,
-0xf1e,0xf1e,0xf1e,0xf1e,0xf1e,0xf1e,0xf1e,0xf1e,0xf1e,0xf1e,0xf1e,0xf1e,0xf1e,0xf1e,0xf1e,0xf1e,
-0xf1e,0xf1e,0xf1e,0xf1e,0xf1e,0xf1e,0xf1e,0xf1e,0xf1e,0xf1e,0xf1e,0xf1e,0xf1e,0xf1e,0xf1e,0xf9e,
+static const uint16_t propsVectorsTrie_index[31228]={
+0x4e8,0x4f0,0x4f8,0x500,0x518,0x520,0x528,0x530,0x538,0x540,0x548,0x550,0x558,0x560,0x568,0x570,
+0x577,0x57f,0x587,0x58f,0x592,0x59a,0x5a2,0x5aa,0x5b2,0x5ba,0x5c2,0x5ca,0x5d2,0x5da,0x5e2,0x5ea,
+0x5f2,0x5fa,0x601,0x609,0x611,0x619,0x621,0x629,0x631,0x639,0x63e,0x646,0x64d,0x655,0x65d,0x665,
+0x66d,0x675,0x67d,0x685,0x68c,0x694,0x69c,0x6a4,0x6ac,0x6b4,0x6bc,0x6c4,0x6cc,0x6d4,0x6dc,0x6e4,
+0x1a38,0xd5e,0xe35,0x6ec,0x508,0xe9c,0xea4,0x1bf2,0x1300,0x1310,0x12f8,0x1308,0x7c5,0x7cb,0x7d3,0x7db,
+0x7e3,0x7e9,0x7f1,0x7f9,0x801,0x807,0x80f,0x817,0x81f,0x825,0x82d,0x835,0x83d,0x845,0x84d,0x854,
+0x85c,0x862,0x86a,0x872,0x87a,0x880,0x888,0x890,0x898,0x1318,0x8a0,0x8a8,0x8b0,0x8b7,0x8bf,0x8c7,
+0x8cf,0x8d3,0x8db,0x8e2,0x8ea,0x8f2,0x8fa,0x902,0x162c,0x1634,0x90a,0x912,0x91a,0x922,0x92a,0x931,
+0x1692,0x1682,0x168a,0x1973,0x197b,0x1328,0x939,0x1320,0x1572,0x1572,0x1574,0x133c,0x133d,0x1330,0x1332,0x1334,
+0x169a,0x169c,0x941,0x169c,0x949,0x94e,0x956,0x16a1,0x95c,0x169c,0x962,0x96a,0xc39,0x16a9,0x16a9,0x972,
+0x16b9,0x16ba,0x16ba,0x16ba,0x16ba,0x16ba,0x16ba,0x16ba,0x16ba,0x16ba,0x16ba,0x16ba,0x16ba,0x16ba,0x16ba,0x16ba,
+0x16ba,0x16ba,0x16ba,0x16b1,0x97a,0x16c2,0x16c2,0x982,0xb59,0xb61,0xb69,0xb71,0x16d2,0x16ca,0x98a,0x992,
+0x99a,0x16dc,0x16e4,0x9a2,0x16da,0x9aa,0x1a40,0xd66,0xb79,0xb81,0xb89,0xb8e,0x18e1,0xc6c,0xc73,0x1849,
+0xc09,0x1a48,0xd6e,0xd76,0xd7e,0xd86,0xf47,0xf48,0x1939,0x193e,0xca8,0xcb0,0x19af,0x19b7,0x1b11,0xe3d,
+0x19bf,0xcf2,0xcfa,0x19c7,0x10f6,0x1196,0xf27,0xd8e,0x1869,0x1851,0x1861,0x1859,0x18f9,0x18f1,0x18b9,0xc19,
+0x1345,0x1345,0x1345,0x1345,0x1348,0x1345,0x1345,0x1350,0x9b2,0x1358,0x9b6,0x9be,0x1358,0x9c6,0x9ce,0x9d6,
+0x1368,0x1360,0x1370,0x9de,0x9e6,0x1378,0x9ee,0x9f6,0x1380,0x1388,0x1390,0x1398,0x9fe,0x13a0,0x13a7,0x13af,
+0x13b7,0x13bf,0x13c7,0x13cf,0x13d7,0x13de,0x13e6,0x13ee,0x13f6,0x13fe,0x1401,0x1403,0x16ec,0x17dc,0x17e2,0x1929,
+0x140b,0xa06,0xa0e,0x1525,0x152a,0x152d,0x1535,0x1413,0x153d,0x153d,0x1423,0x141b,0x142b,0x1433,0x143b,0x1443,
+0x144b,0x1453,0x145b,0x1463,0x17ea,0x1841,0x1983,0x1ad9,0x1473,0x147a,0x1482,0x148a,0x146b,0x1492,0x17f2,0x17f9,
+0x16f4,0x16f4,0x16f4,0x16f4,0x16f4,0x16f4,0x16f4,0x16f4,0x1801,0x1804,0x1801,0x1801,0x180c,0x1813,0x1815,0x181c,
+0x1824,0x1828,0x1828,0x182b,0x1828,0x1828,0x1831,0x1828,0x1871,0x1931,0x198b,0xb96,0xb9c,0x1c36,0x1c3e,0x1d15,
+0x18d1,0xc49,0xc4d,0x1946,0x18c1,0x18c1,0x18c1,0xc21,0x18c9,0xc41,0x1911,0xc98,0xc29,0xc31,0xc31,0x19cf,
+0x1901,0x1993,0xc83,0xc88,0xa16,0x16fc,0x16fc,0xa1e,0x1704,0x1704,0x1704,0x1704,0x1704,0x1704,0xa26,0x6f0,
+0x155a,0x157c,0xa2e,0x1584,0xa36,0x158c,0x1594,0x159c,0xa3e,0xa43,0x15a4,0x15ab,0xa48,0x170c,0x1921,0xc11,
+0xa50,0x1606,0x160d,0x15b3,0x1615,0x161c,0x15bb,0x15bf,0x15d8,0x15d8,0x15da,0x15c7,0x15cf,0x15cf,0x15d0,0x1624,
+0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,
+0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,
+0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,
+0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,
+0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,
+0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,
+0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,
+0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,
+0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,
+0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,
+0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,
+0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,
+0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1714,0x1717,0x1879,0x1879,
+0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,
+0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,
+0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,
+0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,
+0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,
+0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,
+0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,
+0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,
+0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,
+0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,
+0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,
+0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,
+0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,
+0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,
+0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,
+0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,
+0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,
+0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,
+0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,
+0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,
+0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,
+0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,
+0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,
+0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,
+0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,
+0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,
+0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,
+0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,
+0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,
+0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,
+0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,
+0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,
+0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,
+0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,
+0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,
+0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,
+0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,
+0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,
+0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,
+0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,
+0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e2,0x15e9,0x1a30,0x12b5,
+0x171f,0x1725,0x1725,0x1725,0x1725,0x1725,0x1725,0x1725,0x1725,0x1725,0x1725,0x1725,0x1725,0x1725,0x1725,0x1725,
+0x1725,0x1725,0x1725,0x1725,0x1725,0x1725,0x1725,0x1725,0x1725,0x1725,0x1725,0x1725,0x1725,0x1725,0x1725,0x1725,
+0x1725,0x1725,0x1725,0x1725,0xa58,0x172d,0xa60,0x1a50,0x19db,0x19db,0x19db,0x19db,0x19db,0x19db,0x19db,0x19db,
+0x19d7,0xd02,0x19eb,0x19e3,0x19ed,0x1a58,0x1a58,0xd96,0x18d9,0x194e,0x19a3,0x19a7,0x199b,0x1b09,0xcb8,0xcbb,
+0x1909,0xc90,0x1956,0xcc3,0x19f5,0x19f8,0xd0a,0x1a60,0x1a08,0x1a00,0xd12,0xd9e,0x1a68,0x1a6c,0xda6,0xff0,
+0x1a10,0xd1a,0xd22,0x1a74,0x1a84,0x1a7c,0xdae,0xef7,0xe45,0xe4d,0x1c85,0xfa8,0x1d32,0x1d32,0x1a8c,0xdb6,
+0x1674,0x1675,0x1676,0x1677,0x1678,0x1679,0x167a,0x1674,0x1675,0x1676,0x1677,0x1678,0x1679,0x167a,0x1674,0x1675,
+0x1676,0x1677,0x1678,0x1679,0x167a,0x1674,0x1675,0x1676,0x1677,0x1678,0x1679,0x167a,0x1674,0x1675,0x1676,0x1677,
+0x1678,0x1679,0x167a,0x1674,0x1675,0x1676,0x1677,0x1678,0x1679,0x167a,0x1674,0x1675,0x1676,0x1677,0x1678,0x1679,
+0x167a,0x1674,0x1675,0x1676,0x1677,0x1678,0x1679,0x167a,0x1674,0x1675,0x1676,0x1677,0x1678,0x1679,0x167a,0x1674,
+0x1675,0x1676,0x1677,0x1678,0x1679,0x167a,0x1674,0x1675,0x1676,0x1677,0x1678,0x1679,0x167a,0x1674,0x1675,0x1676,
+0x1677,0x1678,0x1679,0x167a,0x1674,0x1675,0x1676,0x1677,0x1678,0x1679,0x167a,0x1674,0x1675,0x1676,0x1677,0x1678,
+0x1679,0x167a,0x1674,0x1675,0x1676,0x1677,0x1678,0x1679,0x167a,0x1674,0x1675,0x1676,0x1677,0x1678,0x1679,0x167a,
+0x1674,0x1675,0x1676,0x1677,0x1678,0x1679,0x167a,0x1674,0x1675,0x1676,0x1677,0x1678,0x1679,0x167a,0x1674,0x1675,
+0x1676,0x1677,0x1678,0x1679,0x167a,0x1674,0x1675,0x1676,0x1677,0x1678,0x1679,0x167a,0x1674,0x1675,0x1676,0x1677,
+0x1678,0x1679,0x167a,0x1674,0x1675,0x1676,0x1677,0x1678,0x1679,0x167a,0x1674,0x1675,0x1676,0x1677,0x1678,0x1679,
+0x167a,0x1674,0x1675,0x1676,0x1677,0x1678,0x1679,0x167a,0x1674,0x1675,0x1676,0x1677,0x1678,0x1679,0x167a,0x1674,
+0x1675,0x1676,0x1677,0x1678,0x1679,0x167a,0x1674,0x1675,0x1676,0x1677,0x1678,0x1679,0x167a,0x1674,0x1675,0x1676,
+0x1677,0x1678,0x1679,0x167a,0x1674,0x1675,0x1676,0x1677,0x1678,0x1679,0x167a,0x1674,0x1675,0x1676,0x1677,0x1678,
+0x1679,0x167a,0x1674,0x1675,0x1676,0x1677,0x1678,0x1679,0x167a,0x1674,0x1675,0x1676,0x1677,0x1678,0x1679,0x167a,
+0x1674,0x1675,0x1676,0x1677,0x1678,0x1679,0x167a,0x1674,0x1675,0x1676,0x1677,0x1678,0x1679,0x167a,0x1674,0x1675,
+0x1676,0x1677,0x1678,0x1679,0x167a,0x1674,0x1675,0x1676,0x1677,0x1678,0x1679,0x167a,0x1674,0x1675,0x1676,0x1677,
+0x1678,0x1679,0x167a,0x1674,0x1675,0x1676,0x1677,0x1678,0x1679,0x167a,0x1674,0x1675,0x1676,0x1677,0x1678,0x1679,
+0x167a,0x1674,0x1675,0x1676,0x1677,0x1678,0x1679,0x167a,0x1674,0x1675,0x1676,0x1677,0x1678,0x1679,0x167a,0x1674,
+0x1675,0x1676,0x1677,0x1678,0x1679,0x167a,0x1674,0x1675,0x1676,0x1677,0x1678,0x1679,0x167a,0x1674,0x1675,0x1676,
+0x1677,0x1678,0x1679,0x167a,0x1674,0x1675,0x1676,0x1677,0x1678,0x1679,0x167a,0x1674,0x1675,0x1676,0x1677,0x1678,
+0x1679,0x167a,0x1674,0x1675,0x1676,0x1677,0x1678,0x1679,0x167a,0x1674,0x1675,0x1676,0x1677,0x1678,0x1679,0x167a,
+0x1674,0x1675,0x1676,0x1677,0x1678,0x1679,0x167a,0x1674,0x1675,0x1676,0x1677,0x1678,0x1679,0xa68,0xdbe,0xdc1,
+0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,
+0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,
+0x164c,0x164c,0x164c,0x164c,0x164c,0x164c,0x164c,0x164c,0x164c,0x164c,0x164c,0x164c,0x164c,0x164c,0x164c,0x164c,
+0x164c,0x164c,0x164c,0x164c,0x164c,0x164c,0x164c,0x164c,0x164c,0x164c,0x164c,0x164c,0x164c,0x164c,0x164c,0x164c,
+0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,
+0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,
+0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,
+0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,
+0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,
+0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,
+0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,
+0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,
+0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,
+0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,
+0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,
+0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,
+0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x15f1,0x15f1,0x15f1,0x15f1,0x15f1,0x15f1,0x15f1,0x15f1,
+0x15f6,0x15fe,0x1839,0x12bd,0x1919,0x1919,0x12c1,0x12c8,0xa70,0xa78,0xa80,0x14b2,0x14b9,0x14c1,0xa88,0x14c9,
+0x14fa,0x14fa,0x14a2,0x14aa,0x14d1,0x14f1,0x14f2,0x1502,0x14d9,0x149a,0xa90,0x14e1,0xa98,0x14e9,0xaa0,0xaa4,
+0xca0,0x150a,0xaac,0xab4,0x1512,0x1518,0x151d,0xabc,0xacc,0x1562,0x156a,0x154d,0x1552,0xad4,0xadc,0xac4,
+0x163c,0x163c,0x163c,0x163c,0x163c,0x163c,0x163c,0x163c,0x163c,0x163c,0x163c,0x163c,0x163c,0x163c,0x163c,0x163c,
+0x163c,0x163c,0x163c,0x163c,0x163c,0x163c,0x163c,0x163c,0x163c,0x163c,0x163c,0x163c,0x1644,0x1644,0x1644,0x1644,
+0x1420,0x1420,0x1460,0x14a0,0x14e0,0x1520,0x1560,0x15a0,0x15dc,0x161c,0x1648,0x1688,0x16c8,0x1708,0x1748,0x1788,
+0x17c8,0x1804,0x1844,0x1884,0x18c4,0x18f8,0x1934,0x1974,0x19b4,0x19f4,0x1a30,0x1a70,0x1ab0,0x1af0,0x1b30,0x1b70,
+0xa80,0xac0,0xb00,0xb40,0xb80,0xa40,0xe75,0xa40,0xe97,0xa40,0xa40,0xa40,0xa40,0xbc0,0x12dd,0x12dd,
+0xed7,0xc00,0xa40,0xa40,0xa40,0xa40,0xf17,0xc2d,0xa40,0xa40,0xc6d,0xcad,0xced,0xd2d,0xe35,0xda5,
+0x121d,0x121d,0x121d,0x121d,0x121d,0x121d,0x121d,0x121d,0x121d,0x121d,0x121d,0x121d,0x121d,0x121d,0x121d,0x121d,
+0x121d,0x121d,0x121d,0x121d,0xf57,0x125d,0x1092,0x10d2,0x129d,0x10dd,0x131d,0x131d,0x131d,0xf97,0xfb7,0xff7,
+0x135d,0x135d,0x1037,0xfb7,0xfb7,0xfb7,0xfb7,0xfb7,0xfb7,0xfb7,0xfb7,0xfb7,0xfb7,0xfb7,0xfb7,0xfb7,
+0xfb7,0xfb7,0xfb7,0xfb7,0xfb7,0xfb7,0xfb7,0xfb7,0xfb7,0xfb7,0xfb7,0xfb7,0xfb7,0xfb7,0xfb7,0x1052,
 0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
-0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xcfd,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xd65,
 0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
-0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xcfd,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xd65,
 0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
-0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xcfd,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xd65,
 0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
-0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xcfd,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xd65,
 0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
-0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xcfd,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xd65,
 0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
-0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xcfd,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xd65,
 0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
-0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xcfd,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xd65,
 0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
-0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xcfd,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xd65,
 0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
-0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xcfd,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xd65,
 0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
-0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xcfd,
-0xd3d,0xd4d,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
-0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xcfd,
-0x10de,0x10de,0x10de,0x10de,0x10de,0x10de,0x10de,0x10de,0x10de,0x10de,0x10de,0x10de,0x10de,0x10de,0x10de,0x10de,
-0x10de,0x10de,0x10de,0x10de,0x10de,0x10de,0x10de,0x10de,0x10de,0x10de,0x10de,0x10de,0x10de,0x10de,0x10de,0x105e,
-0x111e,0x111e,0x111e,0x111e,0x111e,0x111e,0x111e,0x111e,0x111e,0x111e,0x111e,0x111e,0x111e,0x111e,0x111e,0x111e,
-0x111e,0x111e,0x111e,0x111e,0x111e,0x111e,0x111e,0x111e,0x111e,0x111e,0x111e,0x111e,0x111e,0x111e,0x111e,0x109e,
-0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,
-0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,
-0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,
-0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,
-0xb34,0xb3b,0xb43,0xb4b,0x1665,0x1665,0x1665,0xb53,0xb5b,0xb5e,0x1695,0x168d,0xb89,0xcb4,0xcb8,0xcbc,
-0x4a8,0x4a8,0x4a8,0x4a8,0xcc4,0x17f4,0xccc,0xf08,0x1518,0xa61,0xa67,0xfc6,0xb66,0x16cd,0xc03,0x4a8,
-0x152d,0x1520,0x1525,0x166d,0xb6e,0x694,0x4a8,0x4a8,0x19d1,0xf25,0x19c1,0x69c,0x4a8,0x4a8,0x4a8,0x4a8,
-0x19f1,0x19f1,0x19f1,0x19f1,0x19f1,0x19f1,0x19f1,0x19f1,0x19f1,0xf76,0xf7e,0xf86,0x4a8,0x4a8,0x4a8,0x4a8,
-0xb76,0xb79,0xd5b,0x1a39,0xfbe,0x6a4,0x4a8,0x1057,0xc55,0xcd4,0x4a8,0x4a8,0x198d,0xebb,0xec3,0x1a79,
-0xbdd,0xbe4,0xbec,0x1860,0x1a19,0x4a8,0x19f9,0xf96,0x1868,0xd63,0xd6b,0xd73,0xfe6,0x6ac,0x4a8,0x4a8,
-0x1870,0x1870,0x6b4,0x4a8,0x1aa6,0x106f,0x1a9e,0x1077,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,
-0x4a8,0x4a8,0x4a8,0xd7b,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,
-0x18bd,0x18bf,0xdf3,0xdfa,0x1880,0x1878,0xd83,0xee8,0x1985,0xea3,0xeab,0xf8e,0x199d,0x19a1,0xee0,0x1006,
-0xf59,0xf5e,0x6bc,0x4a8,0x105f,0x1067,0x19e1,0xf66,0xf3b,0xf41,0xf49,0xf51,0x4a8,0x4a8,0x4a8,0x4a8,
-0x4a8,0x4a8,0x4a8,0x4a8,0x1a61,0x1a59,0x102d,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x1a49,0xfee,0xff6,0xffe,
-0x1a11,0x1a09,0xfa6,0x4a8,0x19a9,0xef8,0x6c4,0x4a8,0x103d,0x1045,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,
-0x173a,0x173a,0x173a,0x173a,0x173a,0x173a,0x173a,0x173a,0x173a,0x173a,0x173a,0x173a,0x173a,0x173a,0x173a,0x173a,
-0x173a,0x173a,0x173a,0x173a,0x173a,0x173a,0x173a,0x173a,0x173a,0x173a,0x173a,0x173f,0xc5d,0xc64,0xc64,0xc64,
-0x1747,0x1747,0x1747,0xc6c,0x1a96,0x1a96,0x1a96,0x1a96,0x1a96,0x1a96,0x6cc,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,
-0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,
-0x1888,0x1888,0x1888,0x1888,0x1888,0x1888,0x1888,0x1888,0x1888,0x1888,0x1888,0x1888,0x1888,0x1888,0x1888,0x1888,
-0x1888,0x1888,0x188a,0x1888,0x1892,0x1888,0x1888,0x1888,0x1888,0x1888,0x1888,0x1895,0x1888,0x1888,0x1888,0x1888,
-0x1888,0x6d4,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,
-0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,
-0x18c7,0x18c7,0x18c7,0x18c7,0x18c7,0x18c7,0x18c7,0x18c7,0x18c7,0x18c7,0x18c7,0x18c7,0x18c7,0x18c7,0x18c7,0x18c7,
-0x18c7,0xe02,0xfae,0x6dc,0x4a8,0x4a8,0x6e0,0xf00,0x1a31,0x1a29,0xfce,0xfd6,0x6e8,0x4a8,0x4a8,0x4a8,
-0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,
-0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x1995,0x1995,0xecb,0xed0,0xed8,0x4a8,0x4a8,0x4a8,
-0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,
-0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x19c9,0x19c9,0x19c9,
-0xf18,0xf1d,0x6f0,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,
-0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x1535,0x1535,0x1535,
-0x1535,0x1535,0x1535,0x1535,0xa6f,0x1545,0xa77,0x1546,0x153d,0x154e,0x1554,0x155c,0xa7f,0x1685,0x1685,0x6f8,
-0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x1675,0x1675,0xb81,0xc74,0x4a8,0x4a8,0x4a8,0x4a8,0x158d,0x1594,0xa87,
-0x1597,0xa8f,0xa97,0xa9f,0x1591,0xaa7,0xaaf,0xab7,0x1596,0x159e,0x158d,0x1594,0x1590,0x1597,0x159f,0x158e,
-0x1595,0x1591,0xabe,0x1564,0x156c,0x1573,0x157a,0x1567,0x156f,0x1576,0x157d,0xac6,0x1585,0x1abe,0x1abe,0x1abe,
-0x1abe,0x1abe,0x1abe,0x1abe,0x1abe,0x1abe,0x1abe,0x1abe,0x1abe,0x1abe,0x1abe,0x1abe,0x1abe,0x1aae,0x1ab1,0x1aae,
-0x1ab8,0x1097,0x700,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,
-0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,
-0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x100e,0x1a51,0x1014,
-0x1a51,0x101c,0x1021,0x1025,0x1025,0x107f,0x1086,0x1086,0x1086,0x108e,0x1086,0x108f,0x1086,0x4a8,0x4a8,0x4a8,
-0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,
-0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,
-0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x704,0x4a8,0x4a8,0x4a8,
-0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,
-0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,
-0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,
-0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x704,0xace,0x15a7,0x15a7,
-0x15a8,0x70c,0x70c,0x70c,0x70c,0x167d,0x167d,0x167d,0x167d,0x167d,0x167d,0x167d,0x714,0x70c,0x70c,0x70c,
-0x70c,0x70c,0x70c,0x70c,0x70c,0x70c,0x70c,0x70c,0x70c,0x70c,0x70c,0x70c,0x70c,0x70c,0x70c,0x70c,
-0x70c,0x70c,0x70c,0x70c,0x70c,0x70c,0x70c,0x70c,0x70c,0x70c,0x70c,0x70c,0x70c,0x70c,0x70c,0x70c,
-0x70c,0x70c,0x70c,0x70c,0x70c,0x70c,0x70c,0x70c,0x70c,0x70c,0x70c,0x70c,0x70c,0x70c,0x70c,0x70c,
-0x70c,0x70c,0x70c,0x70c,0x70c,0x70c,0x70c,0x70c,0x70c,0x70c,0x70c,0x70c,0x70c,0x17fc,0xcdc,0x1804,
-0x1804,0xce0,0xe13,0xe1b,0xe23,0xd8b,0xd91,0x18a5,0xd99,0xda1,0xda8,0xda8,0xdaf,0xdb7,0xdbe,0xdc6,
-0xdcb,0xdcb,0xdcb,0xdcb,0xdcb,0x18ee,0x18f6,0x18ee,0x18fc,0x1904,0x18cf,0x190c,0x1914,0x18ee,0x191c,0x1924,
-0x192b,0x1933,0x18d7,0x18ee,0x1935,0x18df,0x18e6,0x193d,0xe2b,0x19b9,0xe32,0x19b1,0x1945,0x194d,0x1955,0x195d,
-0x1a21,0x1965,0x196d,0xe3a,0xe42,0x1975,0x1975,0x1975,0xe4a,0x19d9,0x19d9,0xf2d,0xf33,0xe0a,0xe0b,0xe0b,
-0xe0b,0xe0b,0xe0b,0xe0b,0xe0b,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,
-0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,
-0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,
-0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x1a01,0x1a01,0x1a01,
-0x1a01,0x1a01,0x1a01,0xf9e,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,
-0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,
-0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0xe68,0xe70,0xe78,
-0xe80,0xe88,0xe90,0xe97,0xe9b,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x1a71,0x1a69,0x1035,
-0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x1a41,0xfde,
-0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,
-0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,
-0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x1a81,0x1a81,0x1a81,0x1a81,0x1a81,0x1a81,0x1a81,0x1a81,
-0x1a81,0x1a81,0x1a81,0x1a81,0x1a81,0x1a81,0x1a86,0x1a81,0x1a81,0x1a81,0x104d,0x104f,0x4a8,0x4a8,0x4a8,0x4a8,
-0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x4a8,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,
-0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,
-0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,
-0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x10dc,0x109f,
-0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,
-0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,
-0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,
-0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x10a7,0x109f,0x109f,
-0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,
-0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,
-0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,
-0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x15b8,0x15b8,
-0x15b8,0x15b8,0x15b8,0x15b8,0x15b8,0x15b8,0x15b8,0x15b8,0x15b8,0x15b8,0x15b8,0x15b8,0x15b8,0x15b8,0x10e4,0x109f,
-0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,
-0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,
-0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x10ab,0x109f,0x109f,
-0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,
-0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,
-0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,
-0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x109f,0x10ab,0x18ad,0x18ad,
-0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,
-0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,
-0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,
-0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x10ec,0x197d,0x197d,0x197d,0x197d,0x197d,0x197d,0x10f4,0x1ac6,
-0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,
-0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,
-0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,
-0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1454,0x1454,
-0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,
-0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,
-0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,
-0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1444,0x145c,0x145c,
-0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,
-0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,
-0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,
-0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x144c,0x1454,0x1454,
-0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,
-0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,
-0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,
-0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x1454,0x145c,0x145c,
-0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,
-0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,
-0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,
-0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x145c,0x15b0,0x15b0,
-0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,
-0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,
-0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,
-0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x15b0,0x18ad,0x18ad,
-0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,
-0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,
-0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,
-0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x18ad,0x1ac6,0x1ac6,
-0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,
-0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,
-0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,
-0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x1ac6,0x487,0x487,
-0x252,0x252,0x252,0x252,0x252,0x252,0x252,0x252,0x252,0x255,0x25e,0x258,0x258,0x25b,0x252,0x252,
-0x252,0x252,0x252,0x252,0x252,0x252,0x252,0x252,0x252,0x252,0x252,0x252,0x252,0x252,0x252,0x252,
-0x786,0x780,0x765,0x75c,0x753,0x750,0x747,0x762,0x74d,0x759,0x75c,0x777,0x76e,0x75f,0x783,0x756,
-0x744,0x744,0x744,0x744,0x744,0x744,0x744,0x744,0x744,0x744,0x76b,0x768,0x771,0x771,0x771,0x780,
-0x747,0x792,0x792,0x792,0x792,0x792,0x792,0x78c,0x78c,0x78c,0x78c,0x78c,0x78c,0x78c,0x78c,0x78c,
-0x78c,0x78c,0x78c,0x78c,0x78c,0x78c,0x78c,0x78c,0x78c,0x78c,0x78c,0x74d,0x753,0x759,0x77d,0x741,
-0x77a,0x78f,0x78f,0x78f,0x78f,0x78f,0x78f,0x789,0x789,0x789,0x789,0x789,0x789,0x789,0x789,0x789,
-0x789,0x789,0x789,0x789,0x789,0x789,0x789,0x789,0x789,0x789,0x789,0x74d,0x774,0x74a,0x771,0x252,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xd65,
+0xde5,0xdf5,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xd65,
+0x119d,0x119d,0x119d,0x119d,0x119d,0x119d,0x119d,0x119d,0x119d,0x119d,0x119d,0x119d,0x119d,0x119d,0x119d,0x119d,
+0x119d,0x119d,0x119d,0x119d,0x119d,0x119d,0x119d,0x119d,0x119d,0x119d,0x119d,0x119d,0x119d,0x119d,0x119d,0x111d,
+0x11dd,0x11dd,0x11dd,0x11dd,0x11dd,0x11dd,0x11dd,0x11dd,0x11dd,0x11dd,0x11dd,0x11dd,0x11dd,0x11dd,0x11dd,0x11dd,
+0x11dd,0x11dd,0x11dd,0x11dd,0x11dd,0x11dd,0x11dd,0x11dd,0x11dd,0x11dd,0x11dd,0x11dd,0x11dd,0x11dd,0x11dd,0x115d,
+0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,
+0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,
+0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,
+0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,
+0xba4,0xbab,0xbb3,0xbbb,0x1881,0x1881,0x1881,0xbc3,0xbcb,0xbce,0x18b1,0x18a9,0xc01,0xd2a,0xd2e,0xd32,
+0x508,0x508,0x508,0x508,0xd3a,0x1a18,0xd42,0xf3f,0x1735,0xae4,0xaea,0x1000,0xbd6,0x18e9,0xc7b,0x508,
+0x174a,0x173d,0x1742,0x1889,0xbde,0xbe6,0x1134,0x113a,0x1c6d,0xf5d,0x1c5d,0x6f8,0x508,0x508,0x508,0x508,
+0x1c8d,0x1c8d,0x1c8d,0x1c8d,0x1c8d,0x1c8d,0x1c8d,0x1c8d,0x1c8d,0xfb0,0xfb8,0xfc0,0x508,0x508,0x508,0x508,
+0xbee,0xbf1,0xdc9,0x1cd5,0xff8,0x700,0x508,0x1092,0xccb,0xd4a,0x508,0x508,0x1c02,0xeff,0xf07,0x1d1d,
+0xc55,0xc5c,0xc64,0x1a94,0x1cb5,0x508,0x1c95,0xfd0,0x1a9c,0xdd1,0xdd9,0xde1,0x1020,0x708,0x508,0x508,
+0x1aa4,0x1aa4,0x710,0x508,0x1d4a,0x10aa,0x1d42,0x10b2,0x1e0e,0x11ac,0x508,0x508,0x508,0x508,0x508,0x508,
+0x508,0x508,0x508,0xde9,0x1e66,0x1291,0x508,0x508,0x1e2e,0x11d4,0x11db,0x718,0x508,0x71c,0x1248,0x11e3,
+0x1b19,0x1b1b,0xe55,0xe5c,0x1aac,0x1ab4,0xdf1,0xf1f,0x1bfa,0xee7,0xeef,0xfc8,0x1c1a,0x1c1e,0x1c26,0x1040,
+0xf93,0xf98,0x724,0x508,0x109a,0x10a2,0x1c7d,0xfa0,0xf75,0xf7b,0xf83,0xf8b,0x508,0x508,0x508,0x508,
+0x1daa,0x1da2,0x1124,0x112c,0x1cfd,0x1cf5,0x1068,0x508,0x508,0x508,0x508,0x508,0x1ce5,0x1028,0x1030,0x1038,
+0x1cad,0x1ca5,0xfe0,0x111c,0x1c2e,0xf2f,0x72c,0x508,0x1078,0x1080,0x508,0x508,0x508,0x508,0x508,0x508,
+0x1e06,0x118e,0x734,0x508,0x508,0x1d0d,0x1d05,0x1070,0x1250,0x1256,0x125e,0x508,0x508,0x11eb,0x11ef,0x11f7,
+0x1dde,0x1dd6,0x1176,0x1dce,0x1dc6,0x73c,0x1cdd,0x1018,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,
+0x10da,0x10df,0x10e7,0x10ee,0x110e,0x1114,0x508,0x508,0x115a,0x115e,0x1166,0x119e,0x11a4,0x744,0x508,0x508,
+0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x11bc,0x508,0x508,0x508,0x508,0x508,0x748,0x1e4e,0x1238,
+0x195e,0x195e,0x195e,0x195e,0x195e,0x195e,0x195e,0x195e,0x195e,0x195e,0x195e,0x195e,0x195e,0x195e,0x195e,0x195e,
+0x195e,0x195e,0x195e,0x195e,0x195e,0x195e,0x195e,0x195e,0x195e,0x195e,0x195e,0x1963,0xcd3,0xcda,0xcda,0xcda,
+0x196b,0x196b,0x196b,0xce2,0x1d3a,0x1d3a,0x1d3a,0x1d3a,0x1d3a,0x1d3a,0x750,0x508,0x508,0x508,0x508,0x508,
+0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,
+0x1b23,0x1b23,0x1b23,0x1b23,0x1b23,0x1b23,0x1b23,0x1b23,0x1b23,0x1b23,0x1b23,0x1b23,0x1b23,0x1b23,0x1b23,0x1b23,
+0x1b23,0xe64,0xfe8,0x758,0x508,0x508,0x75c,0xf37,0x1ccd,0x1cc5,0x1008,0x1010,0x764,0x508,0x508,0x508,
+0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,
+0x508,0x508,0x1e26,0x1e1e,0x11cc,0x508,0x508,0x508,0x1c12,0x1c12,0xf0f,0x1c0a,0xf17,0x508,0x508,0x1106,
+0x1dba,0x1dba,0x1dba,0x1dba,0x1dba,0x1dba,0x1dba,0x1dba,0x1dba,0x1dba,0x1dba,0x1dba,0x1dba,0x1dba,0x1dba,0x1dba,
+0x1dba,0x1dba,0x1dba,0x1dba,0x1dba,0x1dba,0x1dba,0x1dbe,0x1e76,0x1e76,0x1e76,0x1e76,0x1e76,0x1e76,0x1e76,0x1e76,
+0x1e76,0x1e76,0x1e76,0x1e76,0x1e76,0x1e76,0x1266,0x126c,0x1286,0x1289,0x1289,0x1289,0x76c,0x508,0x508,0x508,
+0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,
+0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x1c65,0x1c65,0x1c65,
+0xf50,0xf55,0x774,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,
+0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x1752,0x1752,0x1752,
+0x1752,0x1752,0x1752,0x1752,0xaf2,0x1762,0xafa,0x1763,0x175a,0x176b,0x1771,0x1779,0xb02,0x18a1,0x18a1,0x77c,
+0x508,0x508,0x508,0x508,0x11c4,0x1891,0x1891,0xbf9,0xcea,0x508,0x508,0x508,0x508,0x17aa,0x17b1,0xb0a,
+0x17b4,0xb12,0xb1a,0xb22,0x17ae,0xb2a,0xb32,0xb3a,0x17b3,0x17bb,0x17aa,0x17b1,0x17ad,0x17b4,0x17bc,0x17ab,
+0x17b2,0x17ae,0xb41,0x1781,0x1789,0x1790,0x1797,0x1784,0x178c,0x1793,0x179a,0xb49,0x17a2,0x1d62,0x1d62,0x1d62,
+0x1d62,0x1d62,0x1d62,0x1d62,0x1d62,0x1d62,0x1d62,0x1d62,0x1d62,0x1d62,0x1d62,0x1d62,0x1d62,0x1d52,0x1d55,0x1d52,
+0x1d5c,0x10ca,0x784,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,
+0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,
+0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x10fe,0x78c,0x508,
+0x508,0x508,0x508,0x508,0x508,0x1e46,0x11ff,0x794,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,
+0x508,0x508,0x508,0x1e56,0x1240,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,
+0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,
+0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x1c9d,0x1c9d,0x1c9d,
+0x1c9d,0x1c9d,0x1c9d,0xfd8,0x508,0x1d9a,0x1d92,0x10d2,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,
+0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,
+0x798,0x1e16,0x11b4,0x508,0x508,0x1207,0x1208,0x7a0,0x508,0x508,0x508,0x508,0x508,0xeac,0xeb4,0xebc,
+0xec4,0xecc,0xed4,0xedb,0xedf,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,
+0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,
+0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,
+0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,
+0x508,0x508,0x508,0x508,0x7a4,0x1048,0x1ced,0x104e,0x1ced,0x1056,0x105b,0x1060,0x1060,0x1d72,0x1d82,0x1d8a,
+0x10ba,0x1d7a,0x1e36,0x10c2,0x1dee,0x1e3e,0x1e3e,0x117e,0x1186,0x121f,0x1225,0x122a,0x1230,0x1e5e,0x1e5e,0x1e5e,
+0x1e5e,0x1274,0x1e5e,0x127a,0x127e,0x7ac,0x7ac,0x7ac,0x7ac,0x7ac,0x7ac,0x7ac,0x7ac,0x7ac,0x7ac,0x7ac,
+0x7ac,0x7ac,0x7ac,0x7ac,0x7ac,0x7ac,0x7ac,0x7ac,0x7ac,0x7ac,0x7ac,0x7ac,0x7ac,0x7ac,0x7ac,0x7ac,
+0x7ac,0x7ac,0x7ac,0x7ac,0x7ad,0xb51,0x17c4,0x17c4,0x17c4,0x7b5,0x7b5,0x7b5,0x7b5,0x1899,0x1899,0x1899,
+0x1899,0x1899,0x1899,0x1899,0x7bd,0x7b5,0x7b5,0x7b5,0x7b5,0x7b5,0x7b5,0x7b5,0x7b5,0x7b5,0x7b5,0x7b5,
+0x7b5,0x7b5,0x7b5,0x7b5,0x7b5,0x7b5,0x7b5,0x7b5,0x7b5,0x7b5,0x7b5,0x7b5,0x7b5,0x7b5,0x7b5,0x7b5,
+0x7b5,0x7b5,0x7b5,0x7b5,0x7b5,0x7b5,0x7b5,0x7b5,0x7b5,0x7b5,0x7b5,0x7b5,0x7b5,0x7b5,0x7b5,0x7b5,
+0x7b5,0x7b5,0x7b5,0x7b5,0x7b5,0x7b5,0x7b5,0x7b5,0x7b5,0x7b5,0x7b5,0x7b5,0x7b5,0x7b5,0x7b5,0x7b5,
+0x7b5,0x7b5,0x7b5,0x7b5,0x7b5,0x1a20,0xd52,0x1a28,0x1a28,0xd56,0xe6c,0xe74,0xe7c,0x1ae9,0x1ad1,0x1af1,
+0x1af9,0x1ae1,0xe01,0xe05,0xe0c,0xe14,0xe1b,0xe23,0xe2b,0xe2d,0xe2d,0xe2d,0xe2d,0x1b5a,0x1b62,0x1b5a,
+0x1b68,0x1b70,0x1b3b,0x1b78,0x1b80,0x1b5a,0x1b88,0x1b90,0x1b97,0x1b9f,0x1b43,0x1b5a,0x1ba4,0x1b4b,0x1b52,0x1bac,
+0x1bb2,0x1c4e,0x1c55,0x1c46,0x1bba,0x1bc2,0x1bca,0x1bd2,0x1cbd,0x1bda,0x1be2,0xe84,0xe8c,0x1b2b,0x1b2b,0x1b2b,
+0xe94,0x1c75,0x1c75,0xf65,0xf6d,0x1abc,0x1abc,0x1abc,0x1abc,0x1abc,0x1abc,0x1abc,0x1abc,0x1abc,0x1abc,0x1abc,
+0x1abc,0x1abc,0x1abc,0x1abc,0x1abc,0x1abc,0x1abc,0x1abe,0x1abc,0x1ac6,0x1abc,0x1abc,0x1abc,0x1abc,0x1abc,0x1abc,
+0x1ac9,0x1abc,0x1abc,0x1abc,0x1abc,0x1abc,0xdf9,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,
+0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,
+0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x1d25,0x1d25,0x1d25,0x1d25,0x1d25,0x1d25,0x1d25,0x1d25,0x1d25,
+0x1d25,0x1d25,0x1d25,0x1d25,0x1d25,0x1d2a,0x1d25,0x1d25,0x1d25,0x1088,0x108a,0x508,0x508,0x508,0x508,0x508,
+0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,
+0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,
+0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,
+0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,
+0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1142,0x1b33,0x1de6,0x1de6,0x1de6,0x1de6,0x1de6,0x1de6,0x1de6,0x114a,
+0x1152,0x1210,0x1217,0x1dfe,0x1dfe,0x1dfe,0x1dfe,0x1dfe,0x1dfe,0x1dfe,0x1dfe,0x1dfe,0x1dfe,0x1dfe,0x116e,0x508,
+0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,
+0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x508,
+0x508,0x508,0x508,0x508,0x508,0x508,0x508,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,
+0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,
+0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,
+0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x12d0,0x1299,0x1b01,
+0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,
+0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,
+0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x12a1,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,
+0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,
+0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,
+0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,
+0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x17d4,0x17d4,0x17d4,0x17d4,0x17d4,0x17d4,0x17d4,0x17d4,0x17d4,
+0x17d4,0x17d4,0x17d4,0x17d4,0x17d4,0x17d4,0x17d4,0x12d8,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,
+0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,
+0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,
+0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x12a5,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,
+0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,
+0x1e6e,0x12ad,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,
+0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,
+0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,
+0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,0x1299,
+0x1299,0x12a5,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,
+0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,
+0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,
+0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x12e0,0x1bea,0x1bea,0x1bea,0x1bea,
+0x1bea,0x1bea,0x12e8,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,
+0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,
+0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,
+0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,
+0x1d6a,0x1d6a,0x12f0,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1664,0x1664,0x1664,
+0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,
+0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,
+0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,
+0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1654,0x166c,0x166c,0x166c,
+0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,
+0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,
+0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,
+0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x165c,0x1664,0x1664,0x1664,
+0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,
+0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,
+0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,
+0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x1664,0x166c,0x166c,0x166c,
+0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,
+0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,
+0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,
+0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x166c,0x17cc,0x17cc,0x17cc,
+0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,
+0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,
+0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,
+0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x17cc,0x1b01,0x1b01,0x1b01,
+0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,
+0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,
+0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,
+0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1b01,0x1d6a,0x1d6a,0x1d6a,
+0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,
+0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,
+0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,
+0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1d6a,0x1db2,0x1db2,0x1db2,
+0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,
+0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,
+0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,
+0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1db2,0x1df6,0x1df6,0x1df6,
+0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,
+0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,
+0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,
+0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1df6,0x1e6e,0x1e6e,0x1e6e,
+0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,
+0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,
+0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,
+0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x1e6e,0x4e7,0x4e7,0x4e7,
+0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2ca,0x2d3,0x2cd,0x2cd,0x2d0,0x2c7,0x2c7,
+0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,0x2c7,
+0x7fb,0x7f5,0x7da,0x7d1,0x7c8,0x7c5,0x7bc,0x7d7,0x7c2,0x7ce,0x7d1,0x7ec,0x7e3,0x7d4,0x7f8,0x7cb,
+0x7b9,0x7b9,0x7b9,0x7b9,0x7b9,0x7b9,0x7b9,0x7b9,0x7b9,0x7b9,0x7e0,0x7dd,0x7e6,0x7e6,0x7e6,0x7f5,
+0x7bc,0x807,0x807,0x807,0x807,0x807,0x807,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,
+0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x7c2,0x7c8,0x7ce,0x7f2,0x7b6,
+0x7ef,0x804,0x804,0x804,0x804,0x804,0x804,0x7fe,0x7fe,0x7fe,0x7fe,0x7fe,0x7fe,0x7fe,0x7fe,0x7fe,
+0x7fe,0x7fe,0x7fe,0x7fe,0x7fe,0x7fe,0x7fe,0x7fe,0x7fe,0x7fe,0x7fe,0x7c2,0x7e9,0x7bf,0x7e6,0x2c7,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0x261,0x261,0x261,0x261,0x261,0x270,0x261,0x261,0x261,0x261,0x261,0x261,0x261,0x261,0x261,0x261,
-0x261,0x261,0x261,0x261,0x261,0x261,0x261,0x261,0x261,0x261,0x261,0x261,0x261,0x261,0x261,0x261,
-0x264,0x5df,0x79b,0x79e,0x5e5,0x79e,0x798,0x5dc,0x5d3,0x26a,0x5f1,0x26d,0x7a1,0x5ca,0x5e8,0x795,
-0x5e2,0x5ee,0x5d0,0x5d0,0x5d6,0x267,0x5dc,0x5d9,0x5d3,0x5d0,0x5f1,0x26d,0x5cd,0x5cd,0x5cd,0x5df,
-0x276,0x276,0x276,0x276,0x276,0x276,0x5fa,0x276,0x276,0x276,0x276,0x276,0x276,0x276,0x276,0x276,
-0x5fa,0x276,0x276,0x276,0x276,0x276,0x276,0x5eb,0x5fa,0x276,0x276,0x276,0x276,0x276,0x5fa,0x5f4,
-0x5f7,0x5f7,0x273,0x273,0x273,0x273,0x5f4,0x273,0x5f7,0x5f7,0x5f7,0x273,0x5f7,0x5f7,0x273,0x273,
-0x5f4,0x273,0x5f7,0x5f7,0x273,0x273,0x273,0x5eb,0x5f4,0x5f7,0x5f7,0x273,0x5f7,0x273,0x5f4,0x273,
-0x282,0x600,0x282,0x279,0x282,0x279,0x282,0x279,0x282,0x279,0x282,0x279,0x282,0x279,0x282,0x279,
-0x27f,0x5fd,0x282,0x600,0x282,0x279,0x282,0x279,0x282,0x279,0x282,0x600,0x282,0x279,0x282,0x279,
-0x282,0x279,0x282,0x279,0x282,0x279,0x606,0x5fd,0x282,0x279,0x282,0x600,0x282,0x279,0x282,0x279,
-0x282,0x5fd,0x609,0x603,0x282,0x279,0x282,0x279,0x5fd,0x282,0x279,0x282,0x279,0x282,0x279,0x609,
-0x603,0x606,0x5fd,0x282,0x600,0x282,0x279,0x282,0x600,0x60c,0x606,0x5fd,0x282,0x600,0x282,0x279,
-0x282,0x279,0x606,0x5fd,0x282,0x279,0x282,0x279,0x282,0x279,0x282,0x279,0x282,0x279,0x282,0x279,
-0x282,0x279,0x282,0x279,0x282,0x279,0x606,0x5fd,0x282,0x279,0x282,0x600,0x282,0x279,0x282,0x279,
-0x282,0x279,0x282,0x279,0x282,0x279,0x282,0x279,0x282,0x282,0x279,0x282,0x279,0x282,0x279,0x27c,
-0x285,0x291,0x291,0x285,0x291,0x285,0x291,0x291,0x285,0x291,0x291,0x291,0x285,0x285,0x291,0x291,
-0x291,0x291,0x285,0x291,0x291,0x285,0x291,0x291,0x291,0x285,0x285,0x285,0x291,0x291,0x285,0x291,
-0x294,0x288,0x291,0x285,0x291,0x285,0x291,0x291,0x285,0x291,0x285,0x285,0x291,0x285,0x291,0x294,
-0x288,0x291,0x291,0x291,0x285,0x291,0x285,0x291,0x291,0x285,0x285,0x28e,0x291,0x285,0x285,0x285,
-0x28e,0x28e,0x28e,0x28e,0x297,0x297,0x28b,0x297,0x297,0x28b,0x297,0x297,0x28b,0x294,0x60f,0x294,
-0x60f,0x294,0x60f,0x294,0x60f,0x294,0x60f,0x294,0x60f,0x294,0x60f,0x294,0x60f,0x285,0x294,0x288,
-0x294,0x288,0x294,0x288,0x291,0x285,0x294,0x288,0x294,0x288,0x294,0x288,0x294,0x288,0x294,0x288,
-0x288,0x297,0x297,0x28b,0x294,0x288,0x969,0x969,0x96c,0x966,0x294,0x288,0x294,0x288,0x294,0x288,
-0x294,0x288,0x294,0x288,0x294,0x288,0x294,0x288,0x294,0x288,0x294,0x288,0x294,0x288,0x294,0x288,
-0x294,0x288,0x294,0x288,0x96c,0x966,0x96c,0x966,0x969,0x963,0x96c,0x966,0xb25,0xc27,0x969,0x963,
-0x969,0x963,0x96c,0x966,0x96c,0x966,0x96c,0x966,0x96c,0x966,0x96c,0x966,0x96c,0x966,0x96c,0x966,
-0xc27,0xc27,0xc27,0xd1d,0xd1d,0xd1d,0xd20,0xd20,0xd1d,0xd20,0xd20,0xd1d,0xd1d,0xd20,0xe61,0xe64,
-0xe64,0xe64,0xe64,0xe61,0xe64,0xe61,0xe64,0xe61,0xe64,0xe61,0xe64,0xe61,0x29a,0x612,0x29a,0x29a,
-0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x612,0x29a,0x29a,
-0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,
-0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29d,0x29a,0x29a,0x29a,
-0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,
-0x29a,0x96f,0x96f,0x96f,0x96f,0x96f,0xc2a,0xc2a,0x2b5,0x2b5,0x2b5,0x2b5,0x2b5,0x2b5,0x2b5,0x2b5,
-0x2b5,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2a9,0x2a9,0x2a0,0x2a0,0x618,0x2a0,0x2ac,0x61b,
-0x2af,0x61b,0x61b,0x61b,0x2af,0x61b,0x2ac,0x2ac,0x61e,0x2b2,0x2a0,0x2a0,0x2a0,0x2a0,0x2a0,0x2a6,
-0x615,0x615,0x615,0x615,0x2a3,0x615,0x2a0,0xa9e,0x2b5,0x2b5,0x2b5,0x2b5,0x2b5,0x2a0,0x2a0,0x2a0,
-0x2a0,0x2a0,0x978,0x978,0x975,0x972,0x975,0xc2d,0xc2d,0xc2d,0xc2d,0xc2d,0xc2d,0xc2d,0xc2d,0xc2d,
-0xc2d,0xc2d,0xc2d,0xc2d,0xc2d,0xc2d,0xc2d,0xc2d,0x621,0x621,0x621,0x621,0x621,0x621,0x621,0x621,
-0x621,0x621,0x621,0x621,0x621,0x621,0x621,0x621,0x621,0x621,0x621,0x621,0x621,0x621,0x621,0x621,
-0x621,0x621,0x621,0x621,0x621,0x621,0x621,0x621,0x621,0x621,0x621,0x621,0x621,0x621,0x621,0x621,
-0x621,0x621,0x621,0x621,0x621,0x621,0x621,0x621,0x621,0x621,0x621,0x621,0x621,0x621,0x621,0x621,
-0x621,0x621,0x621,0x621,0x621,0x621,0x621,0x621,0x624,0x624,0x8d0,0x624,0x624,0x8d3,0xaa1,0xaa1,
-0xaa1,0xaa1,0xaa1,0xaa1,0xaa1,0xaa1,0xaa1,0xbe2,0xcf3,0xcf3,0xcf3,0xcf3,0xcf3,0xcf3,0xcf3,0xcf3,
-0xe2e,0xe2e,0xe2e,0xe2e,0xe31,0xcf6,0xcf6,0xcf6,0x627,0x627,0xaa4,0xc24,0xc24,0xc24,0xc24,0xc24,
-0xc24,0xc24,0xc24,0xc24,0xc24,0xc24,0xc24,0xc24,0xf0f,0xf0c,0xf0f,0xf0c,0x2c1,0x2ca,0xf0f,0xf0c,
-6,6,0x2d0,0xe67,0xe67,0xe67,0x2b8,0x1452,6,6,6,6,0x2cd,0x2bb,0x2df,0x2be,
-0x2df,0x2df,0x2df,6,0x2df,6,0x2df,0x2df,0x2d6,0x62d,0x62d,0x62d,0x62d,0x62d,0x62d,0x62d,
-0x62d,0x62d,0x62d,0x62d,0x62d,0x62d,0x62d,0x62d,0x62d,0x62d,6,0x62d,0x62d,0x62d,0x62d,0x62d,
-0x62d,0x62d,0x2df,0x2df,0x2d6,0x2d6,0x2d6,0x2d6,0x2d6,0x62a,0x62a,0x62a,0x62a,0x62a,0x62a,0x62a,
-0x62a,0x62a,0x62a,0x62a,0x62a,0x62a,0x62a,0x62a,0x62a,0x62a,0x2d3,0x62a,0x62a,0x62a,0x62a,0x62a,
-0x62a,0x62a,0x2d6,0x2d6,0x2d6,0x2d6,0x2d6,0xf0f,0x2e2,0x2e2,0x2e5,0x2df,0x2df,0x2e2,0x2d9,0x97b,
-0xb2e,0xb2b,0x2dc,0x97b,0x2dc,0x97b,0x2dc,0x97b,0x2dc,0x97b,0x2c7,0x2c4,0x2c7,0x2c4,0x2c7,0x2c4,
-0x2c7,0x2c4,0x2c7,0x2c4,0x2c7,0x2c4,0x2c7,0x2c4,0x2e2,0x2e2,0x2d9,0x2d3,0xadd,0xada,0xb28,0xc33,
-0xc30,0xc36,0xc33,0xc30,0xd23,0xd26,0xd26,0xd26,0x98a,0x639,0x2f4,0x2f7,0x2f4,0x2f4,0x2f4,0x2f7,
-0x2f4,0x2f4,0x2f4,0x2f4,0x2f7,0x98a,0x2f7,0x2f4,0x636,0x636,0x636,0x636,0x636,0x636,0x636,0x636,
-0x636,0x639,0x636,0x636,0x636,0x636,0x636,0x636,0x636,0x636,0x636,0x636,0x636,0x636,0x636,0x636,
-0x636,0x636,0x636,0x636,0x636,0x636,0x636,0x636,0x630,0x630,0x630,0x630,0x630,0x630,0x630,0x630,
-0x630,0x633,0x630,0x630,0x630,0x630,0x630,0x630,0x630,0x630,0x630,0x630,0x630,0x630,0x630,0x630,
-0x630,0x630,0x630,0x630,0x984,0x633,0x2ee,0x2f1,0x2ee,0x2ee,0x2ee,0x2f1,0x2ee,0x2ee,0x2ee,0x2ee,
-0x2f1,0x984,0x2f1,0x2ee,0x2f4,0x2ee,0x2f4,0x2ee,0x2f4,0x2ee,0x2f4,0x2ee,0x2f4,0x2ee,0x2f4,0x2ee,
-0x2f4,0x2ee,0x2f4,0x2ee,0x2f4,0x2ee,0x2f4,0x2ee,0x2f4,0x2ee,0x2f7,0x2f1,0x2f4,0x2ee,0x2f4,0x2ee,
-0x2f4,0x2ee,0x2f4,0x2ee,0x2f4,0x2ee,0x2eb,0x8dc,0x2e8,0x8c1,0x8c1,0x10b9,0x97e,0x97e,0xb34,0xb31,
-0x987,0x981,0x987,0x981,0x2f4,0x2ee,0x2f4,0x2ee,0x2f4,0x2ee,0x2f4,0x2ee,0x2f4,0x2ee,0x2f4,0x2ee,
-0x2f4,0x2ee,0x2f4,0x2ee,0x2f4,0x2ee,0x2f4,0x2ee,0x2f4,0x2ee,0x2f4,0x2ee,0x2f4,0x2ee,0x2f4,0x2ee,
-0x2f4,0x2ee,0x2f4,0x2ee,0x2f4,0x2ee,0x2f4,0x2ee,0x2f4,0x2ee,0x2f4,0x2ee,0x2f4,0x2ee,0x2f4,0x2ee,
-0x2f4,0x2ee,0x2f4,0x2ee,0x2f4,0x2f7,0x2f1,0x2f4,0x2ee,0xb34,0xb31,0x2f4,0x2ee,0xb34,0xb31,0x2f4,
-0x2ee,0xb34,0xb31,0xe6a,0x2f7,0x2f1,0x2f7,0x2f1,0x2f4,0x2ee,0x2f7,0x2f1,0x2f4,0x2ee,0x2f7,0x2f1,
-0x2f7,0x2f1,0x2f7,0x2f1,0x2f4,0x2ee,0x2f7,0x2f1,0x2f7,0x2f1,0x2f7,0x2f1,0x2f4,0x2ee,0x2f7,0x2f1,
-0x98a,0x984,0x2f7,0x2f1,0x2f7,0x2f1,0x2f7,0x2f1,0x2f7,0x2f1,0xd2c,0xd29,0x2f7,0x2f1,0xe6d,0xe6a,
-0xe6d,0xe6a,0xe6d,0xe6a,0xba3,0xba0,0xba3,0xba0,0xba3,0xba0,0xba3,0xba0,0xba3,0xba0,0xba3,0xba0,
-0xba3,0xba0,0xba3,0xba0,0xe9a,0xe97,0xe9a,0xe97,0xf8d,0xf8a,0xf8d,0xf8a,0xf8d,0xf8a,0xf8d,0xf8a,
-0xf8d,0xf8a,0xf8d,0xf8a,0xf8d,0xf8a,0xf8d,0xf8a,0x10f5,0x10f2,0x12d5,0x12d2,0x148b,0x1488,0x148b,0x1488,
-0x148b,0x1488,0x148b,0x1488,9,0x306,0x306,0x306,0x306,0x306,0x306,0x306,0x306,0x306,0x306,0x306,
-0x306,0x306,0x306,0x306,0x306,0x306,0x306,0x306,0x306,0x306,0x306,0x306,0x306,0x306,0x306,9,
-9,0x309,0x2fa,0x2fa,0x2fa,0x2fd,0x2fa,0x2fa,9,0x300,0x300,0x300,0x300,0x300,0x300,0x300,
-0x300,0x300,0x300,0x300,0x300,0x300,0x300,0x300,0x300,0x300,0x300,0x300,0x300,0x300,0x300,0x300,
-0x300,0x300,0x300,0x300,0x300,0x300,0x300,0x300,0x300,0x300,0x300,0x303,9,0x849,0x98d,9,
-9,0x1455,0x1455,0x1371,0xc,0x8fd,0x8fd,0x8fd,0x8fd,0x8fd,0x8fd,0x8fd,0x8fd,0x8fd,0x8fd,0x8fd,
-0x8fd,0x8fd,0x8fd,0x8fd,0x8fd,0x8fd,0xd2f,0x8fd,0x8fd,0x8fd,0x8fd,0x8fd,0x8fd,0x8fd,0x8fd,0x8fd,
-0x8fd,0x8fd,0x8fd,0x8fd,0x30c,0x30c,0x30c,0x30c,0x30c,0x30c,0x30c,0x30c,0x30c,0x30c,0xe70,0x30c,
-0x30c,0x30c,0x318,0x30c,0x30f,0x30c,0x30c,0x31b,0x900,0xd32,0xd35,0xd32,0xc,0xc,0xc,0xc,
-0xc,0xc,0xc,0xc,0x31e,0x31e,0x31e,0x31e,0x31e,0x31e,0x31e,0x31e,0x31e,0x31e,0x31e,0x31e,
-0x31e,0x31e,0x31e,0x31e,0x31e,0x31e,0x31e,0x31e,0x31e,0x31e,0x31e,0x31e,0x31e,0x31e,0x31e,0xc,
-0xc,0xc,0xc,0xc,0x31e,0x31e,0x31e,0x315,0x312,0xc,0xc,0xc,0xc,0xc,0xc,0xc,
-0xc,0xc,0xc,0xc,0xc39,0xc39,0xc39,0xc39,0x1374,0x1458,0xf18,0xf18,0xf18,0xf15,0xf15,0xd3e,
-0x84f,0xc48,0xc45,0xc45,0xc3c,0xc3c,0xc3c,0xc3c,0xc3c,0xc3c,0xf12,0xf12,0xf12,0xf12,0xf12,0x84c,
-0x144c,0xf,0xd3b,0x852,0x1290,0x339,0x33c,0x33c,0x33c,0x33c,0x33c,0x339,0x339,0x339,0x339,0x339,
-0x339,0x339,0x339,0x339,0x339,0x339,0x339,0x339,0x339,0x339,0x339,0x339,0x339,0x339,0x339,0xf1b,
-0xf1b,0xf1b,0xf1b,0xf1b,0x855,0x339,0x339,0x339,0x339,0x339,0x339,0x339,0x339,0x339,0x339,0x8c7,
-0x8c7,0x8c7,0x8c7,0x8c7,0x8c7,0x8c7,0x8c7,0xad4,0xad4,0xad4,0xc3c,0xc42,0xc3f,0xd38,0xd38,0xd38,
-0xd38,0xd38,0xd38,0x128d,0x8df,0x8df,0x8df,0x8df,0x8df,0x8df,0x8df,0x8df,0x8df,0x8df,0x333,0x330,
-0x32d,0x32a,0xb37,0xb37,0x8c4,0x339,0x339,0x345,0x339,0x33f,0x33f,0x33f,0x33f,0x339,0x339,0x339,
-0x339,0x339,0x339,0x339,0x339,0x339,0x339,0x339,0x339,0x339,0x339,0x339,0x339,0x339,0x339,0x339,
-0x339,0x339,0x339,0x339,0x339,0x339,0x339,0x339,0x339,0x339,0x339,0x339,0x339,0x339,0x339,0x339,
-0x339,0x339,0x339,0x339,0x339,0x339,0x339,0x339,0x339,0x339,0x339,0x339,0x339,0x339,0x339,0x339,
-0x339,0x339,0x339,0x339,0x339,0x339,0x339,0x339,0x993,0x993,0x339,0x339,0x339,0x339,0x339,0x993,
-0x33c,0x339,0x33c,0x339,0x339,0x339,0x339,0x339,0x339,0x339,0x339,0x339,0x339,0x339,0x339,0x993,
-0x339,0x339,0x339,0x33c,0x348,0x339,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x321,0x32a,0x327,
-0x327,0x324,0x324,0x324,0x324,0x342,0x342,0x324,0x324,0x32a,0x327,0x327,0x327,0x324,0xc4b,0xc4b,
-0x336,0x336,0x336,0x336,0x336,0x336,0x336,0x336,0x336,0x336,0x993,0x993,0x993,0x990,0x990,0xc4b,
-0x9ab,0x9ab,0x9ab,0x9a5,0x9a5,0x9a5,0x9a5,0x9a5,0x9a5,0x9a5,0x9a5,0x9a2,0x9a5,0x9a2,0x12,0x996,
-0x9a8,0x999,0x9a8,0x9a8,0x9a8,0x9a8,0x9a8,0x9a8,0x9a8,0x9a8,0x9a8,0x9a8,0x9a8,0x9a8,0x9a8,0x9a8,
-0x9a8,0x9a8,0x9a8,0x9a8,0x9a8,0x9a8,0x9a8,0x9a8,0x9a8,0x9a8,0x9a8,0x9a8,0x9a8,0xc4e,0xc4e,0xc4e,
-0x99f,0x99f,0x99f,0x99f,0x99f,0x99f,0x99f,0x99f,0x99f,0x99f,0x99f,0x99f,0x99f,0x99f,0x99f,0x99f,
-0x99c,0x99c,0x99c,0x99c,0x99c,0x99c,0x99c,0x99c,0x99c,0x99c,0x99c,0x12,0x12,0xc4e,0xc4e,0xc4e,
-0xda4,0xda4,0xda4,0xda4,0xda4,0xda4,0xda4,0xda4,0xda4,0xda4,0xda4,0xda4,0xda4,0xda4,0xda4,0xda4,
-0xda4,0xda4,0xda4,0xda4,0xda4,0xda4,0xda4,0xda4,0xda4,0xda4,0xda4,0xda4,0xda4,0xda4,0xfa2,0xfa2,
-0xfa2,0xfa2,0xfa2,0xfa2,0xfa2,0xfa2,0xfa2,0xfa2,0xfa2,0xfa2,0xfa2,0xfa2,0xfa2,0xfa2,0xfa2,0xfa2,
-0x9b1,0x9b1,0x9b1,0x9b1,0x9b1,0x9b1,0x9b1,0x9b1,0x9b1,0x9b1,0x9b1,0x9b1,0x9b1,0x9b1,0x9b1,0x9b1,
-0x9b1,0x9b1,0x9b1,0x9b1,0x9b1,0x9b1,0x9b1,0x9b1,0x9b1,0x9b1,0x9b1,0x9b1,0x9b1,0x9b1,0x9b1,0x9b1,
-0x9b1,0x9b1,0x9b1,0x9b1,0x9b1,0x9b1,0x9ae,0x9ae,0x9ae,0x9ae,0x9ae,0x9ae,0x9ae,0x9ae,0x9ae,0x9ae,
-0x9ae,0xb3a,0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
-0xeb2,0xeb2,0xeb2,0xeb2,0xeb2,0xeb2,0xeb2,0xeb2,0xeb2,0xeb2,0xeb5,0xeb5,0xeb5,0xeb5,0xeb5,0xeb5,
-0xeb5,0xeb5,0xeb5,0xeb5,0xeb5,0xeb5,0xeb5,0xeb5,0xeb5,0xeb5,0xeb5,0xeb5,0xeb5,0xeb5,0xeb5,0xeb5,
-0xeb5,0xeb5,0xeb5,0xeb5,0xeb5,0xeb5,0xeb5,0xeb5,0xeb5,0xeb5,0xeb5,0xea9,0xea9,0xea9,0xea9,0xea9,
-0xea9,0xea9,0xea9,0xea9,0xeb8,0xeb8,0xeac,0xeac,0xeaf,0xebe,0xebb,0x10e,0x10e,0x10e,0x10e,0x10e,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0xab0,0xab0,0xab3,0xab3,0xab0,0xab0,0xab0,0xab0,0xab0,0xab0,0xab0,0xab0,0x72,0x72,0x72,0x72,
-0xce7,0xce7,0xce7,0xce7,0xce7,0xce7,0xce7,0xce7,0xce7,0xce7,0xd2,0xd2,0xd2,0xd2,0xd2,0xd2,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0x1518,0x1518,0x1518,0x1518,0x1cb,0x1cb,0x1cb,0x1cb,0x1cb,0x1cb,0x1cb,0x1cb,0x1cb,0x1cb,0x1cb,0x1515,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0x1fe,0x1fe,0x1fe,0x1fe,0x1fe,0x1fe,0x1fe,0x15d2,0x15d2,0x15d2,0x15d2,0x15d2,0x15d2,0x15d2,0x15d2,0x15d2,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0x20a,0x20a,0x20a,0x20a,0x20a,0x20a,0x20a,0x20a,0x20a,0x160b,0x160b,0x160b,0x160b,0x160b,0x160b,0x160b,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0x11e5,0x11e5,0x11e5,0x11e5,0x11e5,0x11e5,0x11e5,0x11e5,0x11e5,0x17a,0x17a,0x17a,0x17a,0x17a,0x17a,0x17a,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0x1e0,0x1e0,0x1e0,0x1e0,0x1e0,0x1e0,0x1e0,0x1e0,0x1e0,0x1e0,0x1e0,0x1e0,0x1e0,0x1e0,0x1e0,0x1e0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0x142b,0x142b,0x142b,0x142b,0x142b,0x142b,0x142b,0x142b,0x142b,0x142b,0x1c5,0x1c5,0x1c5,0x1c5,0x1c5,0x1c5,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0x16fb,0x16fb,0x16fb,0x16fb,0x225,0x225,0x225,0x225,0x225,0x225,0x225,0x225,0x225,0x225,0x225,0x225,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0x1209,0x1209,0x1209,0x1209,0x1209,0x1209,0x1209,0x1209,0x1209,0x1209,0x1209,0x1209,0x1209,0x1209,0x1209,0x183,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0x15bd,0x15bd,0x15bd,0x15bd,0x15bd,0x15bd,0x15bd,0x15bd,0x15bd,0x15bd,0x1f8,0x1f8,0x1f8,0x1f8,0x15c3,0x15c3,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0x150f,0x150f,0x150f,0x150f,0x150f,0x150f,0x150f,0x150f,0x150f,0x150f,0x150f,0x150f,0x150f,0x150f,0x150f,0x150f,
-0x15f9,0x15f9,0x15f9,0x15f9,0x15f9,0x15f9,0x15f9,0x15f9,0x15f9,0x15f9,0x15f9,0x15f9,0x15f9,0x15f9,0x15f9,0x15f9,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0x1662,0x1662,0x1662,0x1662,0x20d,0x20d,0x20d,0x20d,0x20d,0x20d,0x20d,0x20d,0x20d,0x20d,0x20d,0x20d,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0xd9b,0xd9b,0xd98,0xd98,0xd98,0xd9b,0xdb,0xdb,0xdb,0xdb,0xdb,0xdb,0xdb,0xdb,0xdb,0xdb,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0x234,0x1719,0x1719,0x1719,0x1719,0x1719,0x1719,0x1719,0x1719,0x1719,0x1719,0x1719,0x1719,0x1719,0x1719,0x1719,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x8fa,0x8fa,
-3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
-3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
-0xcff,0xcff,0xcff,0xcff,0xcff,0xcff,0xcff,0xcff,0xcff,0xcff,0xcff,0xcff,0xcff,0xcff,0xcff,0xcff,
-3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
-0x145e,0x360,0x36f,0x36f,0x18,0x375,0x375,0x375,0x375,0x375,0x375,0x375,0x375,0x18,0x18,0x375,
-0x375,0x18,0x18,0x375,0x375,0x375,0x375,0x375,0x375,0x375,0x375,0x375,0x375,0x375,0x375,0x375,
-0x375,0x18,0x375,0x375,0x375,0x375,0x375,0x375,0x375,0x18,0x375,0x18,0x18,0x18,0x375,0x375,
-0x375,0x375,0x18,0x18,0x363,0xc54,0x360,0x36f,0x36f,0x360,0x360,0x360,0x360,0x18,0x18,0x36f,
-0x36f,0x18,0x18,0x372,0x372,0x366,0xd44,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x360,
-0x18,0x18,0x18,0x18,0x378,0x378,0x18,0x378,0x375,0x375,0x360,0x360,0x18,0x18,0x8e5,0x8e5,
-0x8e5,0x8e5,0x8e5,0x8e5,0x8e5,0x8e5,0x8e5,0x8e5,0x375,0x375,0x36c,0x36c,0x369,0x369,0x369,0x369,
-0x369,0x36c,0x369,0x10c8,0x18,0x18,0x18,0x18,0x1b,0xc57,0x37b,0xc5a,0x1b,0x387,0x387,0x387,
-0x387,0x387,0x387,0x1b,0x1b,0x1b,0x1b,0x387,0x387,0x1b,0x1b,0x387,0x387,0x387,0x387,0x387,
-0x387,0x387,0x387,0x387,0x387,0x387,0x387,0x387,0x387,0x1b,0x387,0x387,0x387,0x387,0x387,0x387,
-0x387,0x1b,0x387,0x38a,0x1b,0x387,0x38a,0x1b,0x387,0x387,0x1b,0x1b,0x37e,0x1b,0x384,0x384,
-0x384,0x37b,0x37b,0x1b,0x1b,0x1b,0x1b,0x37b,0x37b,0x1b,0x1b,0x37b,0x37b,0x381,0x1b,0x1b,
-0x1b,0xf24,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x38a,0x38a,0x38a,0x387,0x1b,0x38a,0x1b,
-0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x8e8,0x8e8,0x8e8,0x8e8,0x8e8,0x8e8,0x8e8,0x8e8,0x8e8,0x8e8,
-0x37b,0x37b,0x387,0x387,0x387,0xf24,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
-0x1e,0x38d,0x38d,0x396,0x1e,0x399,0x399,0x399,0x399,0x399,0x399,0x399,0xc63,0x399,0x1e,0x399,
-0x399,0x399,0x1e,0x399,0x399,0x399,0x399,0x399,0x399,0x399,0x399,0x399,0x399,0x399,0x399,0x399,
-0x399,0x1e,0x399,0x399,0x399,0x399,0x399,0x399,0x399,0x1e,0x399,0x399,0x1e,0x399,0x399,0x399,
-0x399,0x399,0x1e,0x1e,0x390,0x399,0x396,0x396,0x396,0x38d,0x38d,0x38d,0x38d,0x38d,0x1e,0x38d,
-0x38d,0x396,0x1e,0x396,0x396,0x393,0x1e,0x1e,0x399,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
-0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x399,0xc63,0xc5d,0xc5d,0x1e,0x1e,0x8eb,0x8eb,
-0x8eb,0x8eb,0x8eb,0x8eb,0x8eb,0x8eb,0x8eb,0x8eb,0x1377,0xc60,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
-0x1e,0x166b,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x21,0x39c,0x3ab,0x3ab,0x21,0x3b1,0x3b1,0x3b1,
-0x3b1,0x3b1,0x3b1,0x3b1,0x3b1,0x21,0x21,0x3b1,0x3b1,0x21,0x21,0x3b1,0x3b1,0x3b1,0x3b1,0x3b1,
-0x3b1,0x3b1,0x3b1,0x3b1,0x3b1,0x3b1,0x3b1,0x3b1,0x3b1,0x21,0x3b1,0x3b1,0x3b1,0x3b1,0x3b1,0x3b1,
-0x3b1,0x21,0x3b1,0x3b1,0x21,0xc66,0x3b1,0x3b1,0x3b1,0x3b1,0x21,0x21,0x39f,0x3b1,0x39c,0x39c,
-0x3ab,0x39c,0x39c,0x39c,0xf27,0x21,0x21,0x3ab,0x3ae,0x21,0x21,0x3ae,0x3ae,0x3a2,0x21,0x21,
-0x21,0x21,0x21,0x21,0x21,0x21,0x39c,0x39c,0x21,0x21,0x21,0x21,0x3b4,0x3b4,0x21,0x3b1,
-0x3b1,0x3b1,0xf27,0xf27,0x21,0x21,0x3a8,0x3a8,0x3a8,0x3a8,0x3a8,0x3a8,0x3a8,0x3a8,0x3a8,0x3a8,
-0x3a5,0xc66,0x129c,0x129c,0x129c,0x129c,0x129c,0x129c,0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,
-0x24,0x24,0x3b7,0x3c3,0x24,0x3c3,0x3c3,0x3c3,0x3c3,0x3c3,0x3c3,0x24,0x24,0x24,0x3c3,0x3c3,
-0x3c3,0x24,0x3c3,0x3c3,0x3c6,0x3c3,0x24,0x24,0x24,0x3c3,0x3c3,0x24,0x3c3,0x24,0x3c3,0x3c3,
-0x24,0x24,0x24,0x3c3,0x3c3,0x24,0x24,0x24,0x3c3,0x3c3,0x8f4,0x24,0x24,0x24,0x3c3,0x3c3,
-0x3c3,0x3c3,0x3c3,0x3c3,0x3c3,0x8f4,0xd47,0x3c3,0x3c3,0x3c3,0x24,0x24,0x24,0x24,0x3b7,0x3bd,
-0x3b7,0x3bd,0x3bd,0x24,0x24,0x24,0x3bd,0x3bd,0x3bd,0x24,0x3c0,0x3c0,0x3c0,0x3ba,0x24,0x24,
-0xf2a,0x24,0x24,0x24,0x24,0x24,0x24,0x3b7,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,
-0x24,0x24,0xe5e,0x8f1,0x8f1,0x8f1,0x8f1,0x8f1,0x8f1,0x8f1,0x8f1,0x8f1,0x8ee,0x8ee,0x8ee,0xc69,
-0xc69,0xc69,0xc69,0xc69,0xc69,0xc6c,0xc69,0x24,0x24,0x24,0x24,0x24,0x1461,0x3d5,0x3d5,0x3d5,
-0x27,0x3d8,0x3d8,0x3d8,0x3d8,0x3d8,0x3d8,0x3d8,0x3d8,0x27,0x3d8,0x3d8,0x3d8,0x27,0x3d8,0x3d8,
-0x3d8,0x3d8,0x3d8,0x3d8,0x3d8,0x3d8,0x3d8,0x3d8,0x3d8,0x3d8,0x3d8,0x3d8,0x3d8,0x27,0x3d8,0x3d8,
-0x3d8,0x3d8,0x3d8,0x3d8,0x3d8,0x3d8,0x3d8,0x3d8,0x1464,0x3d8,0x3d8,0x3d8,0x3d8,0x3d8,0x27,0x27,
-0x27,0xf33,0x3c9,0x3c9,0x3c9,0x3d5,0x3d5,0x3d5,0x3d5,0x27,0x3c9,0x3c9,0x3cc,0x27,0x3c9,0x3c9,
-0x3c9,0x3cf,0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x3c9,0x3c9,0x27,0xf33,0xf33,0x166e,0x27,
-0x27,0x27,0x27,0x27,0x3d8,0x3d8,0xf2d,0xf2d,0x27,0x27,0x3d2,0x3d2,0x3d2,0x3d2,0x3d2,0x3d2,
-0x3d2,0x3d2,0x3d2,0x3d2,0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,0xf30,0xf30,0xf30,0xf30,
-0xf30,0xf30,0xf30,0xf30,0x2a,0x1467,0x3e4,0x3e4,0x2a,0x3ea,0x3ea,0x3ea,0x3ea,0x3ea,0x3ea,0x3ea,
-0x3ea,0x2a,0x3ea,0x3ea,0x3ea,0x2a,0x3ea,0x3ea,0x3ea,0x3ea,0x3ea,0x3ea,0x3ea,0x3ea,0x3ea,0x3ea,
-0x3ea,0x3ea,0x3ea,0x3ea,0x3ea,0x2a,0x3ea,0x3ea,0x3ea,0x3ea,0x3ea,0x3ea,0x3ea,0x3ea,0x3ea,0x3ea,
-0x2a,0x3ea,0x3ea,0x3ea,0x3ea,0x3ea,0x2a,0x2a,0xc6f,0xc72,0x3e4,0x3db,0x3e7,0x3e4,0x3db,0x3e4,
-0x3e4,0x2a,0x3db,0x3e7,0x3e7,0x2a,0x3e7,0x3e7,0x3db,0x3de,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,
-0x2a,0x3db,0x3db,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x3ea,0x2a,0x3ea,0x3ea,0xe76,0xe76,
-0x2a,0x2a,0x3e1,0x3e1,0x3e1,0x3e1,0x3e1,0x3e1,0x3e1,0x3e1,0x3e1,0x3e1,0x2a,0xe79,0xe79,0x2a,
-0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2d,0x146a,0x3f6,0x3f6,
-0x2d,0x3fc,0x3fc,0x3fc,0x3fc,0x3fc,0x3fc,0x3fc,0x3fc,0x2d,0x3fc,0x3fc,0x3fc,0x2d,0x3fc,0x3fc,
-0x3fc,0x3fc,0x3fc,0x3fc,0x3fc,0x3fc,0x3fc,0x3fc,0x3fc,0x3fc,0x3fc,0x3fc,0x3fc,0x129f,0x3fc,0x3fc,
-0x3fc,0x3fc,0x3fc,0x3fc,0x3fc,0x3fc,0x3fc,0x3fc,0x3fc,0x3fc,0x3fc,0x3fc,0x3fc,0x3fc,0x129f,0x2d,
-0x2d,0xf3f,0x3ed,0x3f6,0x3f6,0x3ed,0x3ed,0x3ed,0xf36,0x2d,0x3f6,0x3f6,0x3f6,0x2d,0x3f9,0x3f9,
-0x3f9,0x3f0,0x129f,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x3ed,0x2d,0x2d,0x2d,0x2d,
-0x2d,0x2d,0x2d,0x1671,0x3fc,0x3fc,0xf36,0xf36,0x2d,0x2d,0x3f3,0x3f3,0x3f3,0x3f3,0x3f3,0x3f3,
-0x3f3,0x3f3,0x3f3,0x3f3,0xf39,0xf39,0xf39,0xf39,0xf39,0xf39,0x2d,0x2d,0x2d,0xf3c,0xf3f,0xf3f,
-0xf3f,0xf3f,0xf3f,0xf3f,0x30,0x30,0x9bd,0x9bd,0x30,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,
-0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x30,0x30,0x30,0x9c3,0x9c3,
-0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,
-0x9c3,0x9c3,0x30,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x30,0x9c3,0x30,0x30,
-0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x30,0x30,0x30,0x9b7,0x30,0x30,0x30,0x30,0x9b4,
-0x9bd,0x9bd,0x9b4,0x9b4,0x9b4,0x30,0x9b4,0x30,0x9bd,0x9bd,0x9c0,0x9bd,0x9c0,0x9c0,0x9c0,0x9b4,
-0x30,0x30,0x30,0x30,0x30,0x30,0x146d,0x146d,0x146d,0x146d,0x146d,0x146d,0x146d,0x146d,0x146d,0x146d,
-0x30,0x30,0x9bd,0x9bd,0x9ba,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
-0x33,0x417,0x417,0x417,0x417,0x417,0x417,0x417,0x417,0x417,0x417,0x417,0x417,0x417,0x417,0x417,
-0x417,0x417,0x417,0x417,0x417,0x417,0x417,0x417,0x417,0x417,0x417,0x417,0x417,0x417,0x417,0x417,
-0x417,0x402,0x417,0x414,0x402,0x402,0x402,0x402,0x402,0x402,0x408,0x33,0x33,0x33,0x33,0x3ff,
-0x41d,0x41d,0x41d,0x41d,0x41d,0x417,0x41a,0x405,0x405,0x405,0x405,0x405,0x405,0x402,0x405,0x40b,
-0x411,0x411,0x411,0x411,0x411,0x411,0x411,0x411,0x411,0x411,0x40e,0x40e,0x33,0x33,0x33,0x33,
-0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,
-0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x36,0x42c,0x42c,0x36,
-0x42c,0x36,0x36,0x42c,0x42c,0x36,0x42c,0x36,0x36,0x42c,0x36,0x36,0x36,0x36,0x36,0x36,
-0x42c,0x42c,0x42c,0x42c,0x36,0x42c,0x42c,0x42c,0x42c,0x42c,0x42c,0x42c,0x36,0x42c,0x42c,0x42c,
-0x36,0x42c,0x36,0x42c,0x36,0x36,0x42c,0x42c,0x36,0x42c,0x42c,0x42c,0x42c,0x420,0x42c,0x429,
-0x420,0x420,0x420,0x420,0x420,0x420,0x36,0x420,0x420,0x42c,0x36,0x36,0x435,0x435,0x435,0x435,
-0x435,0x36,0x432,0x36,0x423,0x423,0x423,0x423,0x423,0x420,0x36,0x36,0x426,0x426,0x426,0x426,
-0x426,0x426,0x426,0x426,0x426,0x426,0x36,0x36,0x42f,0x42f,0x137a,0x137a,0x36,0x36,0x36,0x36,
-0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
-0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x936,0x936,0x936,0x939,
-0x936,0x936,0x936,0x936,0x39,0x936,0x936,0x936,0x936,0x939,0x936,0x936,0x936,0x936,0x939,0x936,
-0x936,0x936,0x936,0x939,0x936,0x936,0x936,0x936,0x939,0x936,0x936,0x936,0x936,0x936,0x936,0x936,
-0x936,0x936,0x936,0x936,0x936,0x939,0x9d2,0xf4b,0xf4b,0x39,0x39,0x39,0x39,0x903,0x903,0x906,
-0x903,0x906,0x906,0x90f,0x906,0x90f,0x903,0x903,0x903,0x903,0x903,0x930,0x903,0x906,0x909,0x909,
-0x90c,0x915,0x909,0x909,0x936,0x936,0x936,0x936,0x12a8,0x12a2,0x12a2,0x12a2,0x903,0x903,0x903,0x906,
-0x903,0x903,0x9c6,0x903,0x39,0x903,0x903,0x903,0x903,0x906,0x903,0x903,0x903,0x903,0x906,0x903,
-0x903,0x903,0x903,0x906,0x903,0x903,0x903,0x903,0x906,0x903,0x9c6,0x9c6,0x9c6,0x903,0x903,0x903,
-0x903,0x903,0x903,0x903,0x9c6,0x906,0x9c6,0x9c6,0x9c6,0x39,0x9cf,0x9cf,0x9cc,0x9cc,0x9cc,0x9cc,
-0x9cc,0x9cc,0x9c9,0x9cc,0x9cc,0x9cc,0x9cc,0x9cc,0x9cc,0x39,0xf42,0x9cc,0xd4a,0xd4a,0xf45,0xf48,
-0xf42,0x10cb,0x10cb,0x10cb,0x10cb,0x12a5,0x12a5,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,
-0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,
-0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x3c,0x1380,
-0x3c,0x3c,0x3c,0x3c,0x3c,0x1380,0x3c,0x3c,0x43b,0x43b,0x43b,0x43b,0x43b,0x43b,0x43b,0x43b,
-0x43b,0x43b,0x43b,0x43b,0x43b,0x43b,0x43b,0x43b,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0xd59,
-0x9fc,0x3f,0x9fc,0x9fc,0x9fc,0x9fc,0x3f,0x3f,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x3f,
-0x9fc,0x3f,0x9fc,0x9fc,0x9fc,0x9fc,0x3f,0x3f,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0xd59,
-0x9fc,0x3f,0x9fc,0x9fc,0x9fc,0x9fc,0x3f,0x3f,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,
-0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0xd59,0x9fc,0x3f,0x9fc,0x9fc,
-0x9fc,0x9fc,0x3f,0x3f,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x3f,0x9fc,0x3f,0x9fc,0x9fc,
-0x9fc,0x9fc,0x3f,0x3f,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0xd59,0x9fc,0x9fc,0x9fc,0x9fc,
-0x9fc,0x9fc,0x9fc,0x3f,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,
-0x9fc,0x9fc,0x9fc,0xd59,0x9fc,0x3f,0x9fc,0x9fc,0x9fc,0x9fc,0x3f,0x3f,0x9fc,0x9fc,0x9fc,0x9fc,
-0x9fc,0x9fc,0x9fc,0xd59,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,
-0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x3f,0x3f,0x12ab,0x12ab,0xd53,0xd56,0x9f6,0x9ff,0x9f3,
-0x9f3,0x9f3,0x9f3,0x9ff,0x9ff,0x9f9,0x9f9,0x9f9,0x9f9,0x9f9,0x9f9,0x9f9,0x9f9,0x9f9,0x9f0,0x9f0,
-0x9f0,0x9f0,0x9f0,0x9f0,0x9f0,0x9f0,0x9f0,0x9f0,0x9f0,0x3f,0x3f,0x3f,0xa02,0xa02,0xa02,0xa02,
-0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,
-0xa02,0x1677,0x42,0x42,0x1674,0x1674,0x1674,0x1674,0x1674,0x1674,0x42,0x42,0xa14,0xa17,0xa17,0xa17,
-0xa17,0xa17,0xa17,0xa17,0xa17,0xa17,0xa17,0xa17,0xa17,0xa17,0xa17,0xa17,0xa17,0xa17,0xa17,0xa17,
-0xa17,0xa17,0xa17,0xa17,0xa17,0xa17,0xa17,0xa11,0xa0e,0x45,0x45,0x45,0xa1d,0xa1d,0xa1d,0xa1d,
-0xa1d,0xa1d,0xa1d,0xa1d,0xa1d,0xa1d,0xa1d,0xa1a,0xa1a,0xa1a,0xa1d,0xa1d,0xa1d,0x1470,0x1470,0x1470,
-0x1470,0x1470,0x1470,0x1470,0x1470,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0xa3e,0xa3e,0xa3e,0xa3e,
-0xa3e,0xa3e,0xa20,0xa3e,0xa3e,0xa23,0xa23,0xa23,0xa23,0xa23,0xa23,0xa23,0xa23,0xa23,0xa26,0xa23,
-0xa35,0xa35,0xa38,0xa41,0xa2f,0xa2c,0xa35,0xa32,0xa41,0xc75,0x4b,0x4b,0xa3b,0xa3b,0xa3b,0xa3b,
-0xa3b,0xa3b,0xa3b,0xa3b,0xa3b,0xa3b,0x4b,0x4b,0x4b,0x4b,0x4b,0x4b,0xc78,0xc78,0xc78,0xc78,
-0xc78,0xc78,0xc78,0xc78,0xc78,0xc78,0x4b,0x4b,0x4b,0x4b,0x4b,0x4b,0xa4d,0xa4d,0xacb,0xace,
-0xa53,0xac8,0xa50,0xa4d,0xa56,0xa65,0xa59,0xa68,0xa68,0xa68,0xa47,0x4e,0xa5c,0xa5c,0xa5c,0xa5c,
-0xa5c,0xa5c,0xa5c,0xa5c,0xa5c,0xa5c,0x4e,0x4e,0x4e,0x4e,0x4e,0x4e,0xa5f,0xa5f,0xa5f,0xa5f,
-0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,
-0xa5f,0xa5f,0xa5f,0xa5f,0x4e,0x4e,0x4e,0x4e,0x4e,0x4e,0x4e,0x4e,0xa5f,0xa5f,0xa5f,0xa5f,
-0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,0xa4a,0xf6c,0x4e,0x4e,0x4e,0x4e,0x4e,0x1122,0x1122,0x1122,0x1122,
-0x1122,0x1122,0x1122,0x1122,0x1122,0x1122,0x1122,0x1122,0x1122,0x1122,0x1122,0x1122,0x45c,0x45c,0x45c,0x45c,
-0x45c,0x45c,0x45c,0x45c,0x45f,0x45f,0x45f,0x45f,0x45f,0x45f,0x45f,0x45f,0x45c,0x45c,0x45c,0x45c,
-0x45c,0x45c,0x51,0x51,0x45f,0x45f,0x45f,0x45f,0x45f,0x45f,0x51,0x51,0x45c,0x45c,0x45c,0x45c,
-0x45c,0x45c,0x45c,0x45c,0x51,0x45f,0x51,0x45f,0x51,0x45f,0x51,0x45f,0x45c,0x45c,0x45c,0x45c,
-0x45c,0x45c,0x45c,0x45c,0x45f,0x45f,0x45f,0x45f,0x45f,0x45f,0x45f,0x45f,0x45c,0x45c,0x45c,0x45c,
-0x45c,0x45c,0x45c,0x45c,0x45c,0x45c,0x45c,0x45c,0x45c,0x45c,0x51,0x51,0x45c,0x45c,0x45c,0x45c,
-0x45c,0x45c,0x45c,0x45c,0x45f,0x45f,0x45f,0x45f,0x45f,0x45f,0x45f,0x45f,0x45c,0x45c,0x45c,0x45c,
-0x45c,0x51,0x45c,0x45c,0x45f,0x45f,0x45f,0x45f,0x45f,0x456,0x45c,0x456,0x456,0x453,0x45c,0x45c,
-0x45c,0x51,0x45c,0x45c,0x45f,0x45f,0x45f,0x45f,0x45f,0x453,0x453,0x453,0x45c,0x45c,0x45c,0x45c,
-0x51,0x51,0x45c,0x45c,0x45f,0x45f,0x45f,0x45f,0x51,0x453,0x453,0x453,0x45c,0x45c,0x45c,0x45c,
-0x45c,0x45c,0x45c,0x45c,0x45f,0x45f,0x45f,0x45f,0x45f,0x453,0x453,0x453,0x51,0x51,0x45c,0x45c,
-0x45c,0x51,0x45c,0x45c,0x45f,0x45f,0x45f,0x45f,0x45f,0x459,0x456,0x51,0xb40,0xb43,0xb43,0xb43,
-0xf75,0x54,0x144f,0x144f,0x144f,0x144f,0x468,0x468,0x468,0x468,0x468,0x468,0x4b0,0xb55,0x57,0x57,
-0x66f,0x4b0,0x4b0,0x4b0,0x4b0,0x4b0,0x4b6,0x4c8,0x4b6,0x4c2,0x4bc,0x672,0x4ad,0x66c,0x66c,0x66c,
-0x66c,0x4ad,0x4ad,0x4ad,0x4ad,0x4ad,0x4b3,0x4c5,0x4b3,0x4bf,0x4b9,0x57,0xd62,0xd62,0xd62,0xd62,
-0xd62,0x12ae,0x12ae,0x12ae,0x12ae,0x12ae,0x12ae,0x12ae,0x12ae,0x57,0x57,0x57,0x4ce,0x4ce,0x4ce,0x4ce,
-0x4ce,0x4ce,0x4ce,0x4cb,0x4d1,0x6e7,0x4ce,0x93f,0x960,0xa77,0xa77,0xa77,0xb58,0xb58,0xd65,0xd65,
-0xd65,0xd65,0x10e3,0x10e6,0x10e6,0x12b1,0x1449,0x1473,0x1476,0x1476,0x167a,0x5a,0x5a,0x5a,0x5a,0x5a,
-0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x4d7,0x4d7,0x4d7,0x4d7,
-0x4d7,0x4d7,0x4d7,0x4d7,0x4d7,0x4d7,0x4d7,0x4d7,0x4d7,0x4d4,0x4d4,0x4d4,0x4d4,0x4d7,0xa7a,0xa7a,
-0xb5b,0xb61,0xb61,0xb5e,0xb5e,0xb5e,0xb5e,0xd68,0xe7c,0xe7c,0xe7c,0xe7c,0x10b6,0x5d,0x5d,0x5d,
-0x5d,0x5d,0x5d,0x5d,0x5d,0x5d,0x5d,0x5d,0x5d,0x5d,0x5d,0x5d,0x507,0x507,0x507,0xa83,
-0xe85,0xf7b,0xf7b,0xf7b,0xf7b,0x1215,0x167d,0x167d,0x60,0x60,0x60,0x60,0x699,0x699,0x699,0x699,
-0x69c,0x69c,0x69c,0x69c,0x69c,0x69c,0x513,0x513,0x510,0x510,0x510,0x510,0xe8b,0xe8b,0xe8b,0xe88,
-0xe88,0xe88,0xe88,0xe88,0x10ec,0x12ba,0x12ba,0x12ba,0x12ba,0x12b4,0x12b4,0x12b4,0x12bd,0x12b7,0x12b7,0x12bd,
-0x1479,0x1479,0x1479,0x1479,0x147c,0x147c,0x147c,0x63,0x63,0x63,0x63,0x63,0x53d,0x53d,0x53d,0x53d,
-0x53d,0xa8c,0xa8c,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,
-0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x540,0x540,0x540,0x540,
-0x540,0x540,0x540,0x540,0x540,0x540,0x540,0x69,0x69,0x69,0x69,0x69,0x69,0x69,0x69,0x69,
-0x69,0x69,0x69,0x69,0x69,0x69,0x69,0x69,0x69,0x69,0x69,0x69,0xaa7,0xaa7,0xaa7,0xaa7,
-0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,
-0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,0x6c,0xaa7,0xaa7,0xaa7,0xaa7,0xaaa,0xaa7,0xaa7,0xaa7,0xaa7,
-0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,0xaaa,
-0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0xaad,0xaad,0xaad,0xaad,
-0xaad,0xaad,0xaad,0xaad,0xaad,0xaad,0xaad,0xaad,0xaad,0xaad,0xaad,0xaad,0xaad,0xaad,0xaad,0xaad,
-0xaad,0xaad,0x6f,0x6f,0x6f,0x6f,0x6f,0x6f,0x6f,0x6f,0x6f,0x6f,0x75,0x7c8,0x7c2,0x7c8,
-0x7c2,0x7c8,0x7c2,0x7c8,0x7c2,0x7c8,0x7c2,0x7c2,0x7c5,0x7c2,0x7c5,0x7c2,0x7c5,0x7c2,0x7c5,0x7c2,
-0x7c5,0x7c2,0x7c5,0x7c2,0x7c5,0x7c2,0x7c5,0x7c2,0x7c5,0x7c2,0x7c5,0x7c2,0x7c2,0x7c2,0x7c2,0x7c8,
-0x7c2,0x7c8,0x7c2,0x7c8,0x7c2,0x7c2,0x7c2,0x7c2,0x7c2,0x7c2,0x7c8,0x7c2,0x7c2,0x7c2,0x7c2,0x7c2,
-0x7c5,0xc03,0xc03,0x75,0x75,0x8d9,0x8d9,0x8a3,0x8a3,0x7cb,0x7ce,0xc00,0x78,0x78,0x78,0x78,
-0x78,0x7e0,0x7e0,0x7e0,0x7e0,0x7e0,0x7e0,0x7e0,0x7e0,0x7e0,0x7e0,0x7e0,0x7e0,0x7e0,0x7e0,0x7e0,
-0x7e0,0x7e0,0x7e0,0x7e0,0x7e0,0x7e0,0x7e0,0x7e0,0x7e0,0x7e0,0x7e0,0x7e0,0x7e0,0x10aa,0x78,0x78,
-0x7b,0x7e3,0x7e3,0x7e3,0x7e3,0x7e3,0x7e3,0x7e3,0x7e3,0x7e3,0x7e3,0x7e3,0x7e3,0x7e3,0x7e3,0x7e3,
-0x7e3,0x7e3,0x7e3,0x7b,0x8ac,0x8ac,0x8af,0x8af,0x8af,0x8af,0x8af,0x8af,0x8af,0x8af,0x8af,0x8af,
-0x8af,0x8af,0x8af,0x8af,0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,
-0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,0x135c,0x135c,0x135c,0x7e,
-0x7e,0x7e,0x7e,0x7e,0x7ec,0x7ec,0x7ec,0x7ec,0x7ec,0x7ec,0x7ec,0x7ec,0x7ec,0x7ec,0x7ec,0x7ec,
-0x7ec,0x7ec,0x7ec,0x7ec,0x7ec,0x7ec,0x7ec,0x7ec,0x7ec,0x7ec,0x7ec,0x7ec,0x7ec,0x7ec,0x7ec,0x7ec,
-0x7ec,0xd05,0xd05,0x81,0x7f2,0x7f2,0x7f2,0x7f2,0x7f2,0x7f2,0x7f2,0x7f2,0x7f2,0x7f2,0x7f2,0x7f2,
-0x7f2,0x7f2,0x7f2,0x7f2,0x7f2,0x7f2,0x7f2,0x7f2,0x7f2,0x7f2,0x7f2,0x7f2,0x7f2,0x7f2,0x7f2,0x7f2,
-0x7f2,0x7f2,0x7f2,0x81,0xabf,0xabf,0xabf,0xabf,0xabf,0xabf,0xabf,0xabf,0xabf,0xabf,0xabf,0xabf,
-0xabf,0x84,0x84,0x84,0xac5,0xac5,0xac5,0xac5,0xac5,0xac5,0xac5,0xac5,0xac5,0xac5,0xac5,0xac5,
-0xac5,0xac5,0xac5,0xac5,0xac5,0xc0c,0xac5,0xac5,0xac5,0xc0c,0xac5,0x87,0x87,0x87,0x87,0x87,
-0x87,0x87,0x87,0x87,0x1149,0x1149,0x1149,0x1149,0x1149,0x1149,0x1149,0x1149,0x1149,0x1149,0x1149,0x1149,
-0x1149,0x1149,0x1149,0x1149,0x95a,0x95a,0x95a,0x95a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,
-0x8a,0x8a,0x8a,0x8a,0x11be,0x11be,0x11be,0x11be,0x11be,0x11be,0x11be,0x11be,0x11be,0x11be,0x11be,0x11be,
-0x11be,0x11be,0x11be,0x11be,0x59a,0x59a,0x59a,0x59a,0x59a,0x59a,0x59a,0x8d,0x8d,0x8d,0x8d,0x8d,
-0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x588,0x588,0x588,0x588,0x588,0x8d,0x8d,0x8d,0x8d,
-0x8d,0xa98,0x58b,0x591,0x597,0x597,0x597,0x597,0x597,0x597,0x597,0x597,0x597,0x58e,0x591,0x591,
-0x591,0x591,0x591,0x591,0x591,0x591,0x591,0x591,0x591,0x591,0x591,0x8d,0x591,0x591,0x591,0x591,
-0x591,0x8d,0x591,0x8d,0x591,0x591,0x8d,0x591,0x591,0x8d,0x591,0x591,0x591,0x591,0x591,0x591,
-0x591,0x591,0x591,0x594,0x5ac,0x5a6,0x5ac,0x5a6,0x5a9,0x5af,0x5ac,0x5a6,0x5a9,0x5af,0x5ac,0x5a6,
-0x5a9,0x5af,0x5ac,0x5a6,0x12cf,0x12cf,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,
-0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x5ac,0x5a6,0x5a9,0x5af,0x5ac,0x5a6,0x5ac,0x5a6,0x5ac,
-0x5a6,0x5ac,0x5ac,0x5a6,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,
-0x90,0x90,0x90,0x90,0x5a9,0x5a6,0x5a9,0x5a9,0x5a9,0x5a9,0x5a9,0x5a9,0x5a6,0x5a9,0x5a6,0x5a6,
-0x5a9,0x5a9,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a9,0x5a6,0x5a6,0x5a9,0x5a6,0x5a9,0x5a9,0x5a9,0x5a6,
-0x5a9,0x5a9,0x5a9,0x5a9,0x90,0x90,0x5a9,0x5a9,0x5a9,0x5a9,0x5a6,0x5a6,0x5a9,0x5a6,0x5a6,0x5a6,
-0x5a6,0x5a9,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a9,0x5a9,0x5a9,0x5a6,0x5a6,0x90,0x90,0x90,0x90,
-0x90,0x90,0x90,0x90,0xae0,0xae0,0xae0,0xae0,0xae0,0xae0,0xae0,0xae0,0xae0,0xae0,0xae0,0xae0,
-0xae0,0xae0,0xae0,0xae0,0x5ac,0x5ac,0x8f7,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5a3,0x5a3,
-0xb9a,0xd1a,0x90,0x90,0x804,0x816,0x813,0x816,0x813,0xc21,0xc21,0xd11,0xd0e,0x807,0x807,0x807,
-0x807,0x819,0x819,0x819,0x831,0x834,0x843,0x93,0x837,0x83a,0x846,0x846,0x82e,0x825,0x81f,0x825,
-0x81f,0x825,0x81f,0x822,0x822,0x83d,0x83d,0x840,0x83d,0x83d,0x83d,0x93,0x83d,0x82b,0x828,0x822,
-0x93,0x93,0x93,0x93,0x5b8,0x5c4,0x5b8,0xb9d,0x5b8,0x96,0x5b8,0x5c4,0x5b8,0x5c4,0x5b8,0x5c4,
-0x5b8,0x5c4,0x5b8,0x5c4,0x5c4,0x5c1,0x5bb,0x5be,0x5c4,0x5c1,0x5bb,0x5be,0x5c4,0x5c1,0x5bb,0x5be,
-0x5c4,0x5c1,0x5bb,0x5c1,0x5bb,0x5c1,0x5bb,0x5be,0x5c4,0x5c1,0x5bb,0x5c1,0x5bb,0x5c1,0x5bb,0x5c1,
-0x5bb,0x96,0x96,0x5b5,0x708,0x70b,0x720,0x723,0x702,0x70b,0x70b,0x9c,0x6ea,0x6ed,0x6ed,0x6ed,
-0x6ed,0x6ea,0x6ea,0x9c,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0xa9b,0xa9b,0xa9b,
-0x95d,0x6e4,0x5c7,0x5c7,0x9c,0x732,0x711,0x702,0x70b,0x708,0x702,0x714,0x705,0x6ff,0x702,0x720,
-0x717,0x70e,0x72f,0x702,0x72c,0x72c,0x72c,0x72c,0x72c,0x72c,0x72c,0x72c,0x72c,0x72c,0x71d,0x71a,
-0x720,0x720,0x720,0x732,0x6f3,0x6f0,0x6f0,0x6f0,0x6f0,0x6f0,0x6f0,0x6f0,0x6f0,0x6f0,0x6f0,0x6f0,
-0x6f0,0x6f0,0x6f0,0x6f0,0x6f0,0x6f0,0x6f0,0x6f0,0x6f0,0x6f0,0x6f0,0x6f0,0x6f0,0x6f0,0x6f0,0x6f0,
-0x6f0,0x6f0,0x6f0,0x9c,0x9c,0x9c,0x6f0,0x6f0,0x6f0,0x6f0,0x6f0,0x6f0,0x9c,0x9c,0x6f0,0x6f0,
-0x6f0,0x6f0,0x6f0,0x6f0,0x9c,0x9c,0x6f0,0x6f0,0x6f0,0x6f0,0x6f0,0x6f0,0x9c,0x9c,0x6f0,0x6f0,
-0x6f0,0x9c,0x9c,0x9c,0xae3,0xae3,0xae3,0xae3,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,
-0x9f,0x9f,0x9f,0x9f,0xae9,0xae9,0xae9,0xae9,0xae9,0xae9,0xae9,0xae9,0xae9,0xae9,0xae9,0xae9,
-0xae9,0xae9,0xae9,0xae9,0xae9,0xae9,0xae9,0xa2,0xa2,0xa2,0xa2,0xa2,0x15e1,0x15e1,0x15e1,0x15e1,
-0x15e1,0x15e1,0x15e1,0x15e1,0x15e1,0x15e1,0x15e1,0x15e1,0x15e1,0x15e1,0x15e1,0x15e1,0xaf2,0xaf2,0xaf2,0xaf2,
-0xaf2,0xaf2,0xaf2,0xaf2,0xaf2,0xaf2,0xaf2,0xaf2,0xaf2,0xaf2,0xaf2,0xaf2,0xaf2,0xaf2,0xaf2,0xaf2,
-0xaf2,0xaf2,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xafe,0xafe,0xafe,0xafe,
-0xafe,0xafe,0xafe,0xa8,0xa8,0xf87,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,
-0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0x1683,0x1683,0x1683,0x1683,
-0x1683,0x1683,0x1683,0x1683,0x1683,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,
-0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xb16,0xb16,0xb16,0xb16,
-0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,
-0xb13,0xab,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb16,0xb16,0xb13,0xb13,
-0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,
-0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb16,0xab,0xb16,0xb16,0xab,0xab,0xb16,0xab,
-0xab,0xb16,0xb16,0xab,0xab,0xb16,0xb16,0xb16,0xb16,0xab,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,
-0xb16,0xb16,0xb13,0xb13,0xb13,0xb13,0xab,0xb13,0xab,0xb13,0xb13,0xb13,0xb13,0xc99,0xb13,0xb13,
-0xab,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb16,0xb16,0xb16,0xb16,
-0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb13,0xb13,0xb13,0xb13,
-0xb16,0xb16,0xab,0xb16,0xb16,0xb16,0xb16,0xab,0xab,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,
-0xb16,0xab,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xab,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,
-0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,
-0xb13,0xb13,0xb13,0xb13,0xb16,0xb16,0xab,0xb16,0xb16,0xb16,0xb16,0xab,0xb16,0xb16,0xb16,0xb16,
-0xb16,0xab,0xb16,0xab,0xab,0xab,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xab,0xb13,0xb13,
-0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xd83,0xd83,0xab,0xab,
-0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,
-0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb13,0xb13,0xb13,0xb0d,0xb13,0xb13,0xb13,0xb13,
-0xb13,0xb13,0xe94,0xe91,0xab,0xab,0xb10,0xb10,0xb10,0xb10,0xb10,0xb10,0xb10,0xb10,0xb10,0xb10,
-0xb10,0xb10,0xb10,0xb10,0xb10,0xb10,0xb10,0xb10,0xae,0xb1c,0xae,0xae,0xae,0xae,0xae,0xae,
-0xae,0xae,0xae,0xae,0xae,0xae,0xae,0xae,0xae,0xae,0xae,0xae,0xae,0xae,0xae,0xae,
-0xae,0xae,0xae,0xae,0xae,0xae,0xae,0xae,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,
-0xbac,0xbac,0xbac,0xbac,0xbac,0xb1,0xbac,0xbac,0xbac,0xbac,0xba6,0xba6,0xba9,0xb1,0xb1,0xb1,
-0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xbb5,0xbb5,0xbb5,0xbb5,0xbb5,0xbb5,0xbb5,0xbb5,
-0xbb5,0xbb5,0xbb5,0xbb5,0xbb5,0xbb5,0xbb5,0xbb5,0xbb5,0xbb5,0xbaf,0xbaf,0xbb2,0xc15,0xc15,0xb4,
-0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,0xbbb,0xbbb,0xbbb,0xbbb,0xbbb,0xbbb,0xbbb,0xbbb,
-0xbbb,0xbbb,0xbbb,0xbbb,0xbbb,0xbbb,0xbbb,0xbbb,0xbbb,0xbbb,0xbb8,0xbb8,0xb7,0xb7,0xb7,0xb7,
-0xb7,0xb7,0xb7,0xb7,0xb7,0xb7,0xb7,0xb7,0xbc1,0xbc1,0xbc1,0xbc1,0xbc1,0xbc1,0xbc1,0xbc1,
-0xbc1,0xbc1,0xbc1,0xbc1,0xbc1,0xba,0xbc1,0xbc1,0xbc1,0xba,0xbbe,0xbbe,0xba,0xba,0xba,0xba,
-0xba,0xba,0xba,0xba,0xba,0xba,0xba,0xba,0xcab,0xcab,0xcab,0xcab,0xcab,0xcab,0xcab,0xcab,
-0xcab,0xcab,0xcab,0xcab,0xcab,0xcab,0xcab,0xcab,0xcab,0xcab,0xcab,0xcab,0xcab,0xcab,0xcab,0xcab,
-0xcab,0xcab,0xcab,0xcab,0xcab,0x148e,0x148e,0xbd,0xc9c,0xc9c,0xc9c,0xca8,0xca8,0xca8,0xca8,0xc9c,
-0xc9c,0xca8,0xca8,0xca8,0xbd,0xbd,0xbd,0xbd,0xca8,0xca8,0xc9c,0xca8,0xca8,0xca8,0xca8,0xca8,
-0xca8,0xc9f,0xc9f,0xc9f,0xbd,0xbd,0xbd,0xbd,0xca2,0xbd,0xbd,0xbd,0xcae,0xcae,0xca5,0xca5,
-0xca5,0xca5,0xca5,0xca5,0xca5,0xca5,0xca5,0xca5,0xcb1,0xcb1,0xcb1,0xcb1,0xcb1,0xcb1,0xcb1,0xcb1,
-0xcb1,0xcb1,0xcb1,0xcb1,0xcb1,0xcb1,0xcb1,0xcb1,0xcb1,0xcb1,0xc0,0xc0,0xcb1,0xcb1,0xcb1,0xcb1,
-0xcb1,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x1491,0x1491,0x1491,0x1491,
-0x1491,0x1491,0x1491,0x1491,0x1491,0x1491,0x1491,0x1491,0x1491,0x1491,0x1491,0x1491,0x1491,0x1491,0x1491,0x1491,
-0xc3,0xc3,0x1491,0x1491,0x1491,0x1491,0x1491,0x1491,0x1491,0x1491,0x1491,0x1491,0x1491,0x1491,0x1491,0x1491,
-0x1491,0x1491,0x1491,0x1491,0x1491,0x1491,0x1491,0x1491,0x1491,0x1491,0xc3,0xc3,0x1491,0x1491,0x1491,0x1491,
-0x1491,0x1491,0x1491,0x1491,0x1491,0x1491,0x1491,0x1491,0x1491,0x1491,0x1491,0x1491,0x1491,0x1491,0x1491,0x1491,
-0x1491,0x1491,0x1491,0x1491,0x1491,0x1491,0xc3,0xc3,0xc3,0x1491,0x1491,0x1491,0x1491,0x1491,0x1491,0x1491,
-0x1491,0x1491,0x1491,0x1491,0x1491,0xc3,0x1491,0x1491,0x1491,0x1491,0x1491,0x1491,0x1491,0x1491,0xc3,0xc3,
-0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0x1686,0x1686,0x1686,0x1686,
-0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,
-0xcd8,0xcd8,0xcd8,0xcd8,0xcd8,0xcd8,0xcd8,0xcd8,0xcd8,0xcd8,0xcd8,0xcd8,0xc6,0xcd8,0xcd8,0xcd8,
-0xcd8,0xcd8,0xcd8,0xcd8,0xcd8,0xcd8,0xcd8,0xcd8,0xcd8,0xcd8,0xcd8,0xcd8,0xcd8,0xcd8,0xcd8,0xcd8,
-0xcd8,0xcd8,0xcd8,0xc6,0xcd8,0xcd8,0xcd8,0xcd8,0xcd8,0xcd8,0xcd8,0xcd8,0xcd8,0xcd8,0xcd8,0xcd8,
-0xcd8,0xcd8,0xcd8,0xcd8,0xcd8,0xcd8,0xcd8,0xc6,0xcd8,0xcd8,0xc6,0xcd8,0xcd8,0xcd8,0xcd8,0xcd8,
-0xcd8,0xcd8,0xcd8,0xcd8,0xcd8,0xcd8,0xcd8,0xcd8,0xcd8,0xcd8,0xc6,0xc6,0xcd8,0xcd8,0xcd8,0xcd8,
-0xcd8,0xcd8,0xcd8,0xcd8,0xcd8,0xcd8,0xcd8,0xcd8,0xcd8,0xcd8,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,
-0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,
-0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xcdb,0xcdb,0xcdb,0xcdb,
-0xcdb,0xcdb,0xcdb,0xcdb,0xcdb,0xcdb,0xcdb,0xcdb,0xcdb,0xcdb,0xcdb,0xcdb,0xcdb,0xcdb,0xcdb,0xcdb,
-0xcdb,0xcdb,0xcdb,0xcdb,0xcdb,0xcdb,0xcdb,0xc9,0xc9,0xc9,0xc9,0xc9,0xd17,0xd17,0xd17,0xcc,
-0xcc,0xcc,0xcc,0xd14,0xd14,0xd14,0xd14,0xd14,0xd14,0xd14,0xd14,0xd14,0xd14,0xd14,0xd14,0xd14,
-0xd14,0xd14,0xd14,0xd14,0xd14,0xd14,0xd14,0xd14,0xd14,0xd14,0xd14,0xd14,0xcc,0xcc,0xcc,0xd14,
-0xd14,0xd14,0xd14,0xd14,0xd14,0xd14,0xd14,0xd14,0xce1,0xce1,0xce1,0xce1,0xce1,0xce1,0xce1,0xce1,
-0xce1,0xce1,0xce1,0xce1,0xce1,0xce1,0xce1,0xce1,0xce1,0xce1,0xce1,0xce1,0xce1,0xce1,0xce1,0xce1,
-0xce1,0xce1,0xce1,0xce1,0xce1,0xce1,0xcf,0xcde,0xcea,0xcea,0xcea,0xcea,0xcea,0xcea,0xcea,0xcea,
-0xcea,0xcea,0xcea,0xcea,0xcea,0xcea,0xcea,0xcea,0xcea,0xcea,0xcea,0xcea,0xcea,0xcea,0xcea,0xcea,
-0xcea,0xcea,0xcea,0xcea,0xcea,0xcea,0xd2,0xd2,0xced,0xced,0xced,0xced,0xced,0xced,0xd5,0xd5,
-0xced,0xd5,0xced,0xced,0xced,0xced,0xced,0xced,0xced,0xced,0xced,0xced,0xced,0xced,0xced,0xced,
-0xced,0xced,0xced,0xced,0xced,0xced,0xced,0xced,0xced,0xced,0xd5,0xced,0xced,0xd5,0xd5,0xd5,
-0xced,0xd5,0xd5,0xced,0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,
-0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,0xd8,0xd8,0xd8,0xd8,0xd8,
-0xd8,0xd8,0xd8,0xd8,0xd9e,0xd9e,0xd9e,0xd9e,0xd9e,0xd9e,0xd9e,0xd9e,0xd9e,0xd9e,0xd9e,0x1494,
-0x1494,0xde,0xde,0xde,0x1086,0x1086,0x1086,0x1086,0x1086,0x1086,0x1086,0x1086,0x1086,0x1086,0x1086,0x1086,
-0x135,0x135,0x135,0x135,0xdb0,0xdb0,0xdb0,0xdb0,0xdb0,0xdb0,0xdb0,0xdb0,0xdb0,0xdb0,0xdb0,0xdb0,
-0xdb0,0xdb0,0xdb0,0xdb0,0xdb0,0xdb0,0xdb0,0xdb0,0xdb0,0xdb0,0xdb0,0xda7,0xda7,0xdad,0xdad,0xda7,
-0xe1,0xe1,0xdaa,0xdaa,0x10b3,0x10b3,0x10b3,0x10b3,0xe4,0xe4,0xe4,0xe4,0xe4,0xe4,0xe4,0xe4,
-0xe4,0xe4,0xe4,0xe4,0xc12,0xc12,0xc12,0xc12,0xc12,0xc12,0xc12,0xc12,0xc12,0xc12,0xc12,0xc12,
-0xc12,0xc12,0xc12,0xc12,0xfa5,0xfa5,0xfa5,0xfa5,0xfa5,0xfa5,0xfa5,0x1497,0x1497,0x1497,0x1497,0x1497,
-0x1497,0x1497,0x1497,0x1497,0x1497,0x1497,0x1497,0x1497,0x1497,0x149a,0xe7,0xe7,0xe7,0xe7,0xe7,0xe7,
-0x12db,0x10f8,0xea3,0xea3,0xdc2,0xdbf,0xdc2,0xdbf,0xdbf,0xdb6,0xdb6,0xdb6,0xdb6,0xdb6,0xdb6,0x1101,
-0x10fe,0x1101,0x10fe,0x10fb,0x10fb,0x10fb,0x1389,0x1386,0xea,0xea,0xea,0xea,0xea,0xdbc,0xdb9,0xdb9,
-0xdb9,0xdb6,0xdbc,0xdb9,0xdc5,0xdc5,0xdc5,0xdc5,0xdc5,0xdc5,0xdc5,0xdc5,0xdc5,0xdc5,0xdc5,0xdc5,
-0xdc5,0xdc5,0xdc5,0xdc5,0xdc5,0xdc5,0xdc5,0xdc5,0xdc5,0xdc5,0xdc5,0xed,0xed,0xed,0xed,0xed,
-0xed,0xed,0xed,0xed,0xdc5,0xdc5,0xdc5,0xdc5,0xdc5,0xdc5,0xdc5,0xed,0xdc5,0xdc5,0xdc5,0xdc5,
-0xdc5,0xdc5,0xdc5,0xed,0xdc5,0xdc5,0xdc5,0xdc5,0xdc5,0xdc5,0xdc5,0xed,0xdc5,0xdc5,0xdc5,0xdc5,
-0xdc5,0xdc5,0xdc5,0xed,0xdcb,0xdcb,0xdcb,0xdcb,0xdcb,0xdcb,0xdcb,0xdcb,0xdcb,0xdcb,0xdcb,0xdcb,
-0xdcb,0xdcb,0xdcb,0xdcb,0xdc8,0xdc8,0xdc8,0xdc8,0xdc8,0xdc8,0xdc8,0xdc8,0xdc8,0xdc8,0xf0,0xf0,
-0xf0,0xf0,0xf0,0xf0,0xdce,0xdce,0xdce,0xdce,0xdce,0xdce,0xf3,0x138c,0xf3,0xf3,0xf3,0xf3,
-0xf3,0x138c,0xf3,0xf3,0xe28,0xe28,0xe28,0xe28,0xe28,0xe28,0xe28,0xe28,0xe28,0xe28,0xe28,0xe28,
-0xe28,0xe28,0xe28,0xe28,0xdd4,0xdd4,0xdd4,0xdd4,0xdd4,0xdd4,0xdd4,0xdd4,0xdd4,0xdd4,0xdd4,0xdd4,
-0xdd4,0xdd4,0xdd4,0xf6,0xdd1,0xdd1,0xdd1,0xdd1,0xdd1,0xdd1,0xdd1,0xdd1,0xdd1,0xdd1,0xdd1,0xdd1,
-0xdd1,0xdd1,0xdd1,0xdd1,0xdd1,0xdd1,0xdd1,0xdd1,0xdd1,0xdd1,0xdd1,0xdd1,0xdd1,0xdd1,0xdd1,0xdd1,
-0xdd1,0xdd1,0xdd1,0xf6,0xde6,0xdda,0xdda,0xdda,0xf9,0xdda,0xdda,0xf9,0xf9,0xf9,0xf9,0xf9,
-0xdda,0xdda,0xdda,0xdda,0xde6,0xde6,0xde6,0xde6,0xf9,0xde6,0xde6,0xde6,0xf9,0xde6,0xde6,0xde6,
-0xde6,0xde6,0xde6,0xde6,0xde6,0xde6,0xde6,0xde6,0xde6,0xde6,0xde6,0xde6,0xde6,0xde6,0xde6,0xde6,
-0xde6,0xde6,0xde6,0xde6,0xf9,0xf9,0xf9,0xf9,0xdd7,0xdd7,0xdd7,0xf9,0xf9,0xf9,0xf9,0xddd,
-0xde0,0xde0,0xde0,0xde0,0xde0,0xde0,0xde0,0xde0,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,
-0xde3,0xde3,0xde3,0xde3,0xde3,0xde3,0xde9,0xde9,0xde0,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,
-0xdf5,0xdf5,0xdf5,0xdf5,0xdf5,0xdf5,0xdf5,0xdf5,0xdf5,0xdf5,0x1107,0x1107,0xfc,0xfc,0xfc,0xfc,
-0xdf5,0xdf5,0xdf5,0xdf5,0xdf5,0xdf8,0xdf8,0xdf8,0xdf5,0xdf5,0xdf8,0xdf5,0xdf5,0xdf5,0xdf5,0xdf5,
-0xdf5,0xdf5,0xdf5,0xdf5,0xdf5,0xdf5,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xdf2,0xdf2,0xdf2,0xdf2,
-0xdf2,0xdf2,0xdf2,0xdf2,0xdf2,0xdf2,0x1104,0xfc,0xfc,0xfc,0xdef,0xdef,0xdfe,0xdfe,0xdfe,0xdfe,
-0xff,0xff,0xff,0xff,0xdfe,0xdfe,0xdfe,0xdfe,0xdfe,0xdfe,0xdfe,0xdfe,0xdfb,0xdfe,0xdfe,0xdfe,
-0xdfe,0xdfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x14a3,0x14a9,0x14a6,0x102,
-0x102,0x102,0x102,0x102,0x102,0x102,0x102,0x102,0x102,0x102,0x102,0x102,0x102,0x102,0x102,0x102,
-0x102,0x102,0x102,0x102,0x102,0x102,0x102,0x102,0x102,0x102,0x102,0x102,0x102,0x102,0x102,0x102,
-0xe25,0xe25,0xe25,0xe22,0xe22,0xe19,0xe19,0xe22,0xe1f,0xe1f,0xe1f,0xe1f,0x105,0x105,0x105,0x105,
-0x1275,0x1275,0x1275,0x1275,0x1275,0x1275,0x1275,0x1275,0x1278,0x1275,0x159,0x159,0x159,0x159,0x159,0x159,
-0xe28,0xe28,0xe28,0xe28,0xe28,0xe28,0x1398,0x1398,0x108,0x108,0x108,0x108,0x108,0x108,0x108,0xe2b,
-0x12e1,0x108,0x108,0x108,0x108,0x108,0x108,0x108,0x108,0x108,0x108,0x108,0x108,0x108,0x108,0x12de,
-0xbe8,0xbe8,0xbe8,0xbe8,0xbe8,0xbe8,0xbe8,0xbe8,0xbe8,0xbe8,0xbe8,0xbe8,0xbe8,0xbe8,0xbe8,0xbe8,
-0xe52,0xe43,0xe3d,0xe4f,0xe4c,0xe46,0xe46,0xe55,0xe40,0xe49,0x10b,0x10b,0x10b,0x10b,0x10b,0x10b,
-0xed6,0xed6,0xec1,0xed6,0xed9,0xedc,0xedc,0xedc,0xedc,0xedc,0xedc,0xedc,0x111,0x111,0x111,0x111,
-0xed0,0xed0,0xed0,0xed0,0xed0,0xed0,0xed0,0xed0,0xed0,0xed0,0xee2,0xee2,0xec7,0xecd,0xee2,0xee2,
-0xeca,0xec7,0xec7,0xec7,0xec7,0xec7,0xec7,0xec7,0xec7,0xec7,0xec7,0xec4,0xec4,0xec4,0xec4,0xec4,
-0xec4,0xec4,0xec4,0xec4,0xec7,0xec7,0xec7,0xec7,0xec7,0xec7,0xec7,0xec7,0xec7,0x111,0x111,0x111,
-0x12e7,0x12e4,0x12e7,0x12e4,0x12e7,0x12e4,0x12e7,0x12e4,0x12e7,0x12e4,0x139e,0x14b5,0x14b5,0x14b5,0x114,0x114,
-0x14b5,0x14b5,0x168f,0x168f,0x168f,0x1689,0x168f,0x1689,0x114,0x114,0x114,0x114,0x114,0x114,0x114,0x114,
-0x114,0x114,0x114,0x114,0x114,0x114,0x114,0x114,0x114,0x114,0x114,0x114,0x114,0x114,0x114,0x114,
-0x114,0x114,0x114,0x114,0x114,0x114,0x114,0x114,0x114,0x114,0x114,0x14b2,0x13a1,0x13a1,0x12e4,0xfe1,
-0xfe1,0xfe1,0xfe1,0xfe1,0xef1,0xef1,0xef1,0xef1,0xef1,0xef1,0xef1,0xef1,0xef1,0xef1,0xef1,0xef1,
-0xef1,0xef1,0xef1,0xef1,0xef1,0xef1,0xef1,0xef1,0xeee,0xeee,0xef4,0xef4,0x117,0x117,0x117,0x117,
-0x117,0x117,0x117,0x117,0xefd,0xefd,0xefd,0xefd,0xefd,0xefd,0xefd,0xefd,0xefd,0xefd,0xefd,0xefd,
-0xefd,0xefd,0xefd,0xefd,0xefd,0xefd,0xefd,0xefd,0xefd,0xefd,0xef7,0xef7,0xef7,0xef7,0x1110,0x1110,
-0x11a,0x11a,0x11a,0xefa,0x14b8,0x14b8,0x14b8,0x14b8,0x14b8,0x14b8,0x14b8,0x14b8,0x14b8,0x14b8,0x14b8,0x14b8,
-0x14b8,0x14b8,0x14b8,0x14b8,0x14b8,0x14b8,0x14b8,0x14b8,0x14b8,0x14b8,0x14b8,0x14b8,0x14b8,0x1692,0x11d,0x11d,
-0x11d,0x11d,0x11d,0x11d,0x11d,0x11d,0x11d,0x11d,0x11d,0x11d,0x11d,0x11d,0x11d,0x11d,0x11d,0x11d,
-0x11d,0x11d,0x11d,0x11d,0x11d,0x11d,0x11d,0x11d,0x11d,0x11d,0x11d,0x11d,0x11d,0x11d,0x11d,0x11d,
-0xf06,0xf06,0xf06,0x14be,0x14be,0x14be,0x14be,0x14be,0x14be,0x14be,0x14be,0x14be,0x14be,0x14be,0x14be,0x120,
-0xf03,0xf03,0xf03,0xf03,0x14bb,0x120,0x120,0x120,0x120,0x120,0x120,0x120,0x120,0x120,0x120,0x120,
-0xf09,0xf09,0xf09,0xf09,0xf09,0xf09,0xf09,0xf09,0xf09,0xf09,0xf09,0xf09,0xf09,0xf09,0xf09,0xf09,
-0xf09,0xf09,0x123,0x123,0x123,0x123,0x123,0x123,0x123,0x123,0x123,0x123,0x123,0x123,0x123,0x123,
-0x1008,0x1008,0x1008,0x1008,0x1005,0x1005,0x1005,0x1005,0x1005,0x1005,0x1005,0x1005,0xff6,0xff6,0xff6,0xff6,
-0xff6,0xff6,0xff6,0xff6,0x1005,0x1005,0xffc,0xff9,0x126,0x126,0x126,0x100b,0x100b,0xfff,0xfff,0xfff,
-0x1002,0x1002,0x1002,0x1002,0x1002,0x1002,0x1002,0x1002,0x1002,0x1002,0x126,0x126,0x126,0x1008,0x1008,0x1008,
-0x100e,0x100e,0x100e,0x100e,0x100e,0x100e,0x100e,0x100e,0x100e,0x100e,0x1011,0x1011,0x1011,0x1011,0x1011,0x1011,
-0x1023,0x1023,0x1023,0x1023,0x1023,0x1023,0x1023,0x1023,0x1023,0x1023,0x1026,0x1026,0x129,0x129,0x129,0x129,
-0x129,0x129,0x129,0x129,0x129,0x129,0x129,0x129,0x129,0x129,0x129,0x129,0x129,0x129,0x129,0x129,
-0x104d,0x104d,0x104d,0x104d,0x1047,0x12c,0x12c,0x12c,0x12c,0x12c,0x12c,0x12c,0x12c,0x12c,0x1053,0x1053,
-0x104a,0x104a,0x104a,0x104a,0x104a,0x104a,0x104a,0x104a,0x104a,0x104a,0x12c,0x12c,0x12c,0x12c,0x12c,0x12c,
-0x1071,0x1071,0x1071,0x1071,0x1071,0x1071,0x1071,0x1065,0x1065,0x1065,0x1065,0x1065,0x1065,0x1065,0x1065,0x1065,
-0x1065,0x1065,0x106b,0x106e,0x12f,0x12f,0x12f,0x12f,0x12f,0x12f,0x12f,0x12f,0x12f,0x12f,0x12f,0x1068,
-0x1080,0x1080,0x1080,0x1080,0x1080,0x1080,0x1080,0x1080,0x1080,0x1074,0x1074,0x1074,0x1074,0x1074,0x1074,0x107d,
-0x107d,0x1074,0x1074,0x107d,0x107d,0x1074,0x1074,0x132,0x132,0x132,0x132,0x132,0x132,0x132,0x132,0x132,
-0x1080,0x1080,0x1080,0x1074,0x1080,0x1080,0x1080,0x1080,0x1080,0x1080,0x1080,0x1080,0x1074,0x107d,0x132,0x132,
-0x107a,0x107a,0x107a,0x107a,0x107a,0x107a,0x107a,0x107a,0x107a,0x107a,0x132,0x132,0x1077,0x1083,0x1083,0x1083,
-0x14ca,0x135,0x135,0x135,0x135,0x135,0x135,0x135,0x135,0x135,0x135,0x135,0x135,0x135,0x135,0x135,
-0x135,0x135,0x135,0x135,0x135,0x135,0x135,0x135,0x135,0x135,0x135,0x135,0x135,0x135,0x135,0x135,
-0x1089,0x1089,0x1089,0x1089,0x1089,0x1089,0x1089,0x1089,0x1089,0x1089,0x1089,0x1089,0x1089,0x1089,0x1089,0x1089,
-0x1089,0x1089,0x1089,0x1089,0x1089,0x1089,0x1089,0x1089,0x1089,0x1089,0x1089,0x1089,0x1089,0x108c,0x138,0x138,
-0x108f,0x108f,0x108f,0x108f,0x108f,0x108f,0x108f,0x108f,0x108f,0x108f,0x108f,0x108f,0x108f,0x108f,0x108f,0x108f,
-0x108f,0x108f,0x108f,0x108f,0x108f,0x108f,0x108f,0x108f,0x108f,0x108f,0x108f,0x108f,0x108f,0x13b,0x13b,0x13b,
-0x1092,0x1092,0x1092,0x1092,0x1092,0x1092,0x1092,0x1092,0x1092,0x1092,0x1092,0x1092,0x1092,0x1092,0x1092,0x1092,
-0x1092,0x13e,0x13e,0x13e,0x13e,0x13e,0x13e,0x13e,0x13e,0x13e,0x13e,0x13e,0x13e,0x13e,0x13e,0x13e,
-0x1098,0x1098,0x1098,0x1098,0x1098,0x1098,0x1098,0x1098,0x1098,0x1098,0x1098,0x1098,0x1098,0x1098,0x1098,0x1098,
-0x1098,0x1098,0x1098,0x1098,0x1098,0x1098,0x1098,0x1098,0x1098,0x1098,0x141,0x141,0x141,0x141,0x141,0x1095,
-0x109b,0x109b,0x109b,0x109b,0x109b,0x109b,0x109b,0x109b,0x109b,0x109b,0x109b,0x109b,0x144,0x144,0x144,0x144,
-0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,
-0x10a1,0x10a1,0x10a1,0x10a1,0x147,0x147,0x147,0x147,0x147,0x147,0x147,0x147,0x147,0x147,0x147,0x147,
-0x1116,0x1116,0x1116,0x1116,0x111f,0x1116,0x1116,0x1116,0x111f,0x1116,0x1116,0x1116,0x1116,0x1113,0x14a,0x14a,
-0x111c,0x111c,0x111c,0x111c,0x111c,0x111c,0x111c,0x111c,0x111c,0x111c,0x111c,0x111c,0x111c,0x111c,0x111c,0x14a,
-0x1122,0x1122,0x1122,0x1122,0x1122,0x1122,0x1122,0x1122,0x1122,0x1122,0x1122,0x1122,0x1122,0x1122,0x1122,0x1122,
-0x1122,0x1122,0x1122,0x1122,0x1122,0x1122,0x14d,0x14d,0x14d,0x14d,0x14d,0x14d,0x14d,0x14d,0x14d,0x14d,
-0x113d,0x113d,0x113d,0x113d,0x113d,0x113d,0x113d,0x113d,0x113d,0x113d,0x113d,0x113d,0x113d,0x113d,0x113d,0x113d,
-0x113d,0x113d,0x113d,0x113d,0x113d,0x113a,0x1125,0x113a,0x1125,0x1125,0x1125,0x1125,0x1125,0x1125,0x1125,0x150,
-0x112e,0x1137,0x1125,0x1137,0x1137,0x1125,0x1125,0x1125,0x1125,0x1125,0x1125,0x1125,0x1125,0x113a,0x113a,0x113a,
-0x113a,0x113a,0x113a,0x1125,0x1125,0x112b,0x112b,0x112b,0x112b,0x112b,0x112b,0x112b,0x112b,0x150,0x150,0x1128,
-0x1134,0x1134,0x1134,0x1134,0x1134,0x1134,0x1134,0x1134,0x1134,0x1134,0x150,0x150,0x150,0x150,0x150,0x150,
-0x1134,0x1134,0x1134,0x1134,0x1134,0x1134,0x1134,0x1134,0x1134,0x1134,0x150,0x150,0x150,0x150,0x150,0x150,
-0x1131,0x1131,0x1131,0x1131,0x1131,0x1131,0x1131,0x1140,0x1143,0x1143,0x1143,0x1143,0x1131,0x1131,0x150,0x150,
-0x151e,0x151e,0x151e,0x151e,0x151e,0x151e,0x151e,0x151e,0x151e,0x151e,0x151e,0x151e,0x151e,0x151e,0x151b,0x1d1,
-0x1284,0x1269,0x127e,0x127e,0x127e,0x127e,0x127e,0x127e,0x127e,0x126c,0x126c,0x126c,0x126c,0x127e,0x126c,0x126c,
-0x126c,0x126c,0x1272,0x1440,0x1446,0x1443,0x143d,0x153,0x1665,0x1665,0x153,0x153,0x153,0x153,0x153,0x153,
-0x1158,0x1158,0x1158,0x1158,0x1158,0x1158,0x1158,0x1158,0x1158,0x1158,0x1158,0x1158,0x1158,0x1158,0x1158,0x1158,
-0x114f,0x114f,0x1152,0x115b,0x1155,0x1155,0x1155,0x115b,0x156,0x156,0x156,0x156,0x156,0x156,0x156,0x156,
-0x115e,0x115e,0x115e,0x115e,0x115e,0x115e,0x115e,0x115e,0x115e,0x115e,0x115e,0x115e,0x115e,0x115e,0x115e,0x115e,
-0x115e,0x115e,0x1164,0x128a,0x1164,0x1164,0x1164,0x1164,0x1161,0x1161,0x1161,0x1164,0x1698,0x169b,0x15c,0x15c,
-0x1257,0x1257,0x1257,0x1257,0x1257,0x1257,0x1257,0x1257,0x1257,0x1257,0x1257,0x1257,0x1257,0x1257,0x1257,0x1257,
-0x1257,0x1257,0x1257,0x1257,0x1257,0x1257,0x1257,0x1257,0x1257,0x1257,0x1257,0x1257,0x1257,0x15f,0x15f,0x15f,
-0x1179,0x116d,0x116d,0x116d,0x116d,0x116d,0x116d,0x1170,0x117f,0x117f,0x116d,0x116d,0x116d,0x116d,0x162,0x127b,
-0x1173,0x1173,0x1173,0x1173,0x1173,0x1173,0x1173,0x1173,0x1173,0x1173,0x162,0x162,0x162,0x162,0x116d,0x116d,
-0x119d,0x1191,0x119d,0x165,0x165,0x165,0x165,0x165,0x165,0x165,0x165,0x165,0x165,0x165,0x165,0x165,
-0x165,0x165,0x165,0x165,0x165,0x165,0x165,0x165,0x165,0x165,0x165,0x119a,0x119a,0x11a0,0x1194,0x1197,
-0x11b5,0x11b5,0x11b5,0x11af,0x11af,0x11a6,0x11af,0x11af,0x11a6,0x11af,0x11af,0x11b8,0x11b2,0x11a9,0x168,0x168,
-0x11ac,0x11ac,0x11ac,0x11ac,0x11ac,0x11ac,0x11ac,0x11ac,0x11ac,0x11ac,0x168,0x168,0x168,0x168,0x168,0x168,
-0x11be,0x11be,0x11be,0x11be,0x11be,0x11be,0x11be,0x16b,0x16b,0x16b,0x16b,0x11bb,0x11bb,0x11bb,0x11bb,0x11bb,
-0x11bb,0x11bb,0x11bb,0x11bb,0x11bb,0x11bb,0x11bb,0x11bb,0x11bb,0x11bb,0x11bb,0x11bb,0x11bb,0x11bb,0x11bb,0x11bb,
-0x11bb,0x11bb,0x11bb,0x11bb,0x11bb,0x11bb,0x11bb,0x11bb,0x16b,0x16b,0x16b,0x16b,0x11c7,0x11c7,0x11c7,0x11c7,
-0x11c7,0x11c7,0x11c7,0x11c7,0x11c7,0x11c7,0x11c7,0x11c7,0x11c7,0x11c7,0x11c7,0x11c7,0x11c7,0x11c7,0x11c7,0x11c7,
-0x11c7,0x11c7,0x16e,0x11c4,0x11c1,0x11c1,0x11c1,0x11c1,0x11c1,0x11c1,0x11c1,0x11c1,0x11d6,0x11d6,0x11d6,0x11d6,
-0x11d6,0x11d6,0x11d6,0x11d6,0x11d6,0x11d6,0x11d6,0x11d6,0x11d6,0x11d6,0x11d6,0x11d6,0x11d6,0x11d6,0x11d6,0x11d6,
-0x11d6,0x11d6,0x171,0x171,0x171,0x11d0,0x11d3,0x11d3,0x11d3,0x11d3,0x11d3,0x11d3,0x11dc,0x11dc,0x11dc,0x11dc,
-0x11dc,0x11dc,0x11dc,0x11dc,0x11dc,0x11dc,0x11dc,0x11dc,0x11dc,0x11dc,0x11dc,0x11dc,0x11dc,0x11dc,0x11dc,0x11dc,
-0x11dc,0x11dc,0x174,0x174,0x11d9,0x11d9,0x11d9,0x11d9,0x11d9,0x11d9,0x11d9,0x11d9,0x11e2,0x11e2,0x11e2,0x11e2,
-0x11e2,0x11e2,0x11e2,0x11e2,0x11e2,0x11e2,0x11e2,0x11e2,0x11e2,0x11e2,0x11e2,0x11e2,0x11e2,0x11e2,0x11e2,0x177,
-0x177,0x177,0x177,0x177,0x11df,0x11df,0x11df,0x11df,0x11df,0x11df,0x11df,0x11df,0x11e8,0x11e8,0x11e8,0x11e8,
-0x11e8,0x11e8,0x11e8,0x11e8,0x11e8,0x11e8,0x11e8,0x11e8,0x11e8,0x11e8,0x11e8,0x11e8,0x11e8,0x11e8,0x11e8,0x11e8,
-0x11e8,0x11e8,0x11e8,0x11e8,0x11e8,0x11e8,0x11e8,0x11e8,0x11e8,0x11e8,0x11e8,0x17d,0x1206,0x1206,0x180,0x180,
-0x180,0x180,0x180,0x180,0x180,0x180,0x180,0x180,0x180,0x180,0x180,0x180,0x141f,0x141f,0x141f,0x141f,
-0x141f,0x141f,0x141f,0x141f,0x141f,0x141f,0x141f,0x141f,0x141f,0x141f,0x141f,0x141f,0x1239,0x1239,0x1239,0x1239,
-0x1239,0x1239,0x1239,0x1239,0x1239,0x1239,0x1239,0x14d6,0x14d6,0x186,0x186,0x186,0x1239,0x1239,0x1239,0x1239,
-0x1239,0x1239,0x1239,0x1239,0x1239,0x1239,0x1239,0x1239,0x1239,0x1239,0x1239,0x1239,0x1239,0x1239,0x1239,0x123c,
-0x123c,0x123c,0x1212,0x186,0x1356,0x1245,0x1356,0x1356,0x1356,0x1356,0x1356,0x1356,0x1356,0x1356,0x1356,0x1356,
-0x1356,0x1245,0x1356,0x1245,0x1353,0x1353,0x1353,0x1353,0x1353,0x1353,0x1353,0x1353,0x1353,0x1353,0x13b0,0x13b0,
-0x186,0x186,0x186,0x186,0x1359,0x1359,0x1353,0x1353,0x1353,0x1353,0x1353,0x1353,0x1353,0x1242,0x1353,0x1242,
-0x1242,0x1353,0x1359,0x1248,0x1353,0x1353,0x1353,0x1353,0x1353,0x1353,0x1353,0x1353,0x1353,0x1353,0x1236,0x1236,
-0x1236,0x1236,0x1350,0x134a,0x123f,0x1350,0x1350,0x1350,0x1350,0x1350,0x1350,0x1350,0x1350,0x1350,0x1350,0x186,
-0x186,0x186,0x186,0x186,0x186,0x186,0x186,0x186,0x186,0x186,0x186,0x186,0x186,0x186,0x186,0x186,
-0x186,0x186,0x186,0x186,0x186,0x186,0x186,0x186,0x186,0x186,0x186,0x186,0x186,0x186,0x186,0x186,
-0x186,0x186,0x12f0,0x12f0,0x12f0,0x12f0,0x12f0,0x12f0,0x12f0,0x12f0,0x12f0,0x12f0,0x12f0,0x12f0,0x12f0,0x12f0,
-0x12f0,0x12f0,0x12f0,0x12f0,0x12f0,0x12f0,0x12f0,0x12f0,0x12f0,0x12f0,0x12f0,0x12f0,0x1263,0x1365,0x135f,0x189,
-0x189,0x189,0x189,0x189,0x189,0x189,0x189,0x189,0x189,0x189,0x189,0x189,0x125d,0x125d,0x125d,0x125d,
-0x125d,0x125d,0x125d,0x125d,0x125d,0x125d,0x1260,0x125d,0x125d,0x125d,0x125d,0x125d,0x125d,0x125d,0x125d,0x125d,
-0x125d,0x125d,0x125d,0x125d,0x125d,0x125d,0x125d,0x1260,0x125d,0x125d,0x1365,0x1365,0x1365,0x1365,0x1365,0x135f,
-0x1365,0x1365,0x1365,0x189,0x189,0x189,0x189,0x189,0x125a,0x125a,0x125a,0x125a,0x125a,0x125a,0x125a,0x125a,
-0x125a,0x189,0x189,0x189,0x189,0x189,0x189,0x189,0x1362,0x1362,0x189,0x189,0x189,0x189,0x189,0x189,
-0x189,0x189,0x189,0x189,0x189,0x189,0x189,0x189,0x189,0x189,0x189,0x189,0x189,0x189,0x189,0x189,
-0x189,0x189,0x189,0x189,0x189,0x189,0x189,0x189,0x189,0x189,0x189,0x189,0x12f9,0x12f9,0x12f9,0x12f9,
-0x12f9,0x12f9,0x12f9,0x12f9,0x12f9,0x12f9,0x12f9,0x12f9,0x12f9,0x12f9,0x12f9,0x12f9,0x12f9,0x12f9,0x12f9,0x12f9,
-0x12f9,0x12f9,0x12f9,0x12f9,0x12f9,0x12f3,0x12f3,0x12f3,0x18c,0x18c,0x12f6,0x18c,0x130b,0x130b,0x130b,0x130b,
-0x130b,0x130b,0x12fc,0x1305,0x12ff,0x12ff,0x1305,0x1305,0x1305,0x12ff,0x1305,0x12ff,0x12ff,0x12ff,0x1308,0x1308,
-0x18f,0x18f,0x18f,0x18f,0x18f,0x18f,0x18f,0x18f,0x1302,0x1302,0x1302,0x1302,0x192,0x130e,0x130e,0x130e,
-0x130e,0x130e,0x130e,0x192,0x192,0x130e,0x130e,0x130e,0x130e,0x130e,0x130e,0x192,0x192,0x130e,0x130e,0x130e,
-0x130e,0x130e,0x130e,0x192,0x192,0x192,0x192,0x192,0x192,0x192,0x192,0x192,0x130e,0x130e,0x130e,0x130e,
-0x130e,0x130e,0x130e,0x192,0x130e,0x130e,0x130e,0x130e,0x130e,0x130e,0x130e,0x192,0x157b,0x157b,0x157b,0x157b,
-0x157b,0x157b,0x157b,0x157b,0x157b,0x157b,0x157b,0x157b,0x157b,0x157b,0x157b,0x157b,0x1311,0x1311,0x1311,0x1311,
-0x1311,0x1311,0x1314,0x1326,0x1326,0x131a,0x131a,0x131a,0x131a,0x131a,0x195,0x195,0x195,0x195,0x1317,0x1317,
-0x1317,0x1317,0x1317,0x1317,0x1317,0x1317,0x1317,0x1317,0x1317,0x1317,0x1317,0x1317,0x1317,0x1317,0x131d,0x131d,
-0x131d,0x131d,0x131d,0x131d,0x131d,0x131d,0x131d,0x131d,0x195,0x195,0x195,0x195,0x195,0x195,0x195,0x195,
-0x195,0x195,0x195,0x195,0x195,0x195,0x195,0x14d9,0x1329,0x1329,0x1329,0x1329,0x1329,0x1329,0x1329,0x1329,
-0x1329,0x1329,0x1329,0x1329,0x1329,0x1329,0x1329,0x1329,0x1329,0x1329,0x1329,0x1329,0x1329,0x1329,0x1329,0x1329,
-0x1329,0x198,0x198,0x198,0x198,0x198,0x198,0x198,0x136b,0x1368,0x19b,0x19b,0x19b,0x19b,0x19b,0x19b,
-0x19b,0x19b,0x19b,0x19b,0x19b,0x19b,0x19b,0x19b,0x19b,0x19b,0x19b,0x19b,0x19b,0x19b,0x19b,0x19b,
-0x19b,0x19b,0x19b,0x19b,0x19b,0x19b,0x19b,0x19b,0x19b,0x19b,0x19b,0x19b,0x132c,0x132c,0x132c,0x132c,
-0x132c,0x132c,0x132c,0x132c,0x132c,0x132c,0x132c,0x132c,0x132c,0x132c,0x132c,0x19e,0x19e,0x132c,0x132c,0x132c,
-0x132c,0x132c,0x132c,0x132c,0x132c,0x132c,0x132c,0x132c,0x132c,0x132c,0x132c,0x14dc,0x19e,0x132c,0x132c,0x132c,
-0x132c,0x132c,0x132c,0x132c,0x132c,0x132c,0x132c,0x132c,0x132c,0x132c,0x132c,0x132f,0x19e,0x132c,0x132c,0x132c,
-0x132c,0x132c,0x132c,0x132c,0x132c,0x132c,0x132c,0x132c,0x132c,0x132c,0x132c,0x132c,0x14dc,0x14dc,0x14dc,0x14dc,
-0x14dc,0x14dc,0x14dc,0x14dc,0x14dc,0x14dc,0x14dc,0x14dc,0x14dc,0x14dc,0x14dc,0x14dc,0x14dc,0x14dc,0x14dc,0x14dc,
-0x14dc,0x14dc,0x19e,0x19e,0x19e,0x19e,0x19e,0x19e,0x19e,0x19e,0x19e,0x19e,0x1335,0x1335,0x1335,0x1335,
-0x1335,0x1335,0x1335,0x1335,0x14e2,0x14e2,0x14e2,0x14e2,0x14e2,0x14e2,0x14e2,0x14e8,0x14e8,0x14e2,0x14e2,0x14e8,
-0x14e8,0x14ee,0x14e8,0x14e8,0x14e8,0x14e8,0x1a1,0x14e2,0x14e2,0x14e2,0x14e2,0x14e2,0x1a1,0x14e8,0x14e2,0x14e2,
-0x14e8,0x14e2,0x14e2,0x14e2,0x14e2,0x14e2,0x14e2,0x14e2,0x14e2,0x14e8,0x14e8,0x14e2,0x14e2,0x14e2,0x14e2,0x14e2,
-0x14e2,0x14e2,0x14e2,0x14e2,0x14e8,0x14e2,0x14e2,0x14e2,0x1344,0x1341,0x1341,0x1341,0x1341,0x1341,0x14f7,0x14f7,
-0x14f7,0x14f7,0x14f7,0x14fa,0x14fd,0x14fa,0x14fa,0x14fa,0x16aa,0x1a4,0x1a4,0x1a4,0x1a4,0x1a4,0x1a4,0x1a4,
-0x1a4,0x1a4,0x1a4,0x1a4,0x1a4,0x1a4,0x1a4,0x1a4,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14fa,0x14f7,0x14f7,
-0x14f7,0x14fa,0x14f7,0x14fd,0x14fd,0x1a4,0x1a4,0x1a4,0x14fa,0x14f7,0x14f7,0x14fa,0x1a4,0x1a4,0x1a4,0x1a4,
-0x1a4,0x1a4,0x1a4,0x1a4,0x1a4,0x1a4,0x1a4,0x1a4,0x1347,0x1347,0x1347,0x1347,0x1347,0x1347,0x1347,0x1347,
-0x1347,0x1347,0x1347,0x1347,0x1347,0x1347,0x1347,0x1347,0x1347,0x1347,0x1347,0x1347,0x1a7,0x1a7,0x1a7,0x1a7,
-0x1a7,0x1a7,0x1a7,0x1a7,0x1a7,0x1a7,0x1a7,0x1a7,0x13bf,0x1503,0x13bf,0x13bf,0x13bf,0x13bf,0x13bf,0x13bf,
-0x13bf,0x13bf,0x13bf,0x13bf,0x13bf,0x1503,0x1503,0x1503,0x1503,0x1503,0x1503,0x16b0,0x16b0,0x1aa,0x1aa,0x1aa,
-0x1aa,0x1aa,0x1aa,0x1aa,0x1aa,0x1aa,0x1aa,0x1aa,0x1aa,0x1aa,0x1aa,0x1aa,0x1aa,0x1aa,0x1aa,0x1aa,
-0x1aa,0x1aa,0x1aa,0x1aa,0x1aa,0x1aa,0x1aa,0x1aa,0x1aa,0x1aa,0x1aa,0x1aa,0x1aa,0x1aa,0x1aa,0x1aa,
-0x1aa,0x1aa,0x1aa,0x16ad,0x13bc,0x13bc,0x13bc,0x13bc,0x13bc,0x13bc,0x13b9,0x13b9,0x13b9,0x13b9,0x13b9,0x13b9,
-0x13bc,0x13bc,0x13bc,0x13bc,0x13bc,0x13bc,0x13bc,0x13bc,0x13bc,0x13bc,0x13bc,0x13bc,0x13bc,0x13bc,0x13bc,0x1500,
-0x13c5,0x13c5,0x13c5,0x13c5,0x1ad,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,
-0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,
-0x1ad,0x13c5,0x13c5,0x1ad,0x13c5,0x1ad,0x1ad,0x13c5,0x1ad,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,
-0x13c5,0x13c5,0x13c5,0x1ad,0x13c5,0x13c5,0x13c5,0x13c5,0x1ad,0x13c5,0x1ad,0x13c5,0x1ad,0x1ad,0x1ad,0x1ad,
-0x1ad,0x1ad,0x13c5,0x1ad,0x1ad,0x1ad,0x1ad,0x13c5,0x1ad,0x13c5,0x1ad,0x13c5,0x1ad,0x13c5,0x13c5,0x13c5,
-0x1ad,0x13c5,0x13c5,0x1ad,0x13c5,0x1ad,0x1ad,0x13c5,0x1ad,0x13c5,0x1ad,0x13c5,0x1ad,0x13c5,0x1ad,0x13c5,
-0x1ad,0x13c5,0x13c5,0x1ad,0x13c5,0x1ad,0x1ad,0x13c5,0x13c5,0x13c5,0x13c5,0x1ad,0x13c5,0x13c5,0x13c5,0x13c5,
-0x13c5,0x13c5,0x13c5,0x1ad,0x13c5,0x13c5,0x13c5,0x13c5,0x1ad,0x13c5,0x13c5,0x13c5,0x13c5,0x1ad,0x13c5,0x1ad,
-0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x1ad,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,
-0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x1ad,0x1ad,0x1ad,0x1ad,
-0x1ad,0x13c5,0x13c5,0x13c5,0x1ad,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x1ad,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,
-0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x1ad,0x1ad,0x1ad,0x1ad,
-0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,
-0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,0x13c2,0x13c2,0x1ad,0x1ad,
-0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,0x13da,0x13da,0x13da,0x13da,
-0x13da,0x13da,0x13da,0x13c8,0x13c8,0x13c8,0x13c8,0x13c8,0x13d7,0x13c8,0x13cb,0x13cb,0x13c8,0x13c8,0x13c8,0x13ce,
-0x13ce,0x1b0,0x13d4,0x13d4,0x13d4,0x13d4,0x13d4,0x13d4,0x13d4,0x13d4,0x13d4,0x13d4,0x13d1,0x13dd,0x13dd,0x13dd,
-0x1b0,0x1b0,0x1b0,0x1b0,0x1b0,0x1b0,0x1b0,0x1b0,0x1b0,0x1b0,0x1b0,0x1b0,0x158d,0x158d,0x158d,0x158d,
-0x158d,0x158d,0x158d,0x158d,0x158d,0x158d,0x158d,0x158d,0x158d,0x158d,0x158d,0x158d,0x13e9,0x13e9,0x13e9,0x13e9,
-0x13e9,0x13e9,0x13e9,0x13e9,0x13e9,0x13e9,0x13e9,0x13e6,0x13e0,0x13e0,0x13e6,0x13e6,0x13ef,0x13ef,0x13e9,0x13ec,
-0x13ec,0x13e6,0x13e3,0x1b3,0x1b3,0x1b3,0x1b3,0x1b3,0x1b3,0x1b3,0x1b3,0x1b3,0x13f2,0x13f2,0x13f2,0x13f2,
-0x13f2,0x13f2,0x13f2,0x13f2,0x13f2,0x13f2,0x13f2,0x13f2,0x13f2,0x13f2,0x13f2,0x13f2,0x13f2,0x13f2,0x13f2,0x13f2,
-0x13f2,0x13f2,0x13f2,0x13f2,0x1b6,0x1b6,0x1b6,0x1b6,0x16b3,0x16b3,0x13f2,0x13f2,0x16b3,0x16b3,0x16b3,0x16b3,
-0x16b3,0x16b3,0x16b3,0x16b3,0x16b3,0x16b3,0x16b3,0x16b3,0x16b3,0x16b3,0x16b3,0x16b3,0x1b6,0x1b6,0x16b3,0x16b3,
-0x16b3,0x16b3,0x16b3,0x16b3,0x16b3,0x16b3,0x16b3,0x16b3,0x16b3,0x16b3,0x16b3,0x16b3,0x13fe,0x13fe,0x13fe,0x13fe,
-0x13fe,0x1b9,0x1b9,0x1b9,0x1b9,0x1b9,0x1b9,0x1b9,0x1b9,0x1b9,0x1b9,0x1b9,0x13fe,0x13fb,0x13fb,0x13fb,
-0x13fb,0x13fb,0x13fb,0x13fb,0x13fb,0x13fb,0x13fb,0x13fb,0x13fb,0x13fb,0x13fb,0x13fb,0x13fb,0x13fb,0x13fb,0x13fb,
-0x13fb,0x13fb,0x13fb,0x13fb,0x13fb,0x13fb,0x13fb,0x13fb,0x13fb,0x13fb,0x13fb,0x13fb,0x13fb,0x13fb,0x13fb,0x1b9,
-0x1b9,0x1b9,0x1b9,0x1b9,0x1b9,0x1b9,0x1b9,0x1b9,0x1b9,0x1b9,0x1b9,0x1b9,0x1b9,0x1b9,0x1b9,0x13f8,
-0x13f8,0x13f8,0x13f8,0x1401,0x1401,0x1401,0x1401,0x1401,0x1401,0x1401,0x1401,0x1401,0x1401,0x1401,0x1401,0x1401,
-0x1413,0x1416,0x1416,0x1416,0x1416,0x1419,0x1419,0x1407,0x140a,0x16b9,0x16b6,0x16b6,0x16b6,0x1509,0x1bc,0x1bc,
-0x140d,0x140d,0x140d,0x140d,0x140d,0x140d,0x140d,0x140d,0x140d,0x140d,0x1506,0x16bf,0x16c2,0x16bc,0x16c5,0x16c5,
-0x141f,0x141f,0x141f,0x141f,0x141f,0x141f,0x141f,0x141f,0x141f,0x1bf,0x1bf,0x1bf,0x1bf,0x1bf,0x1bf,0x1bf,
-0x141c,0x141c,0x141c,0x141c,0x141c,0x141c,0x141c,0x141c,0x141c,0x141c,0x1bf,0x1bf,0x1bf,0x1bf,0x1bf,0x1bf,
-0x1422,0x1422,0x1422,0x1422,0x1422,0x1422,0x1422,0x1422,0x1c2,0x1c2,0x1c2,0x1c2,0x1c2,0x1c2,0x1c2,0x1c2,
-0x1281,0x127e,0x1281,0x126f,0x127e,0x127e,0x127e,0x1284,0x127e,0x1284,0x1287,0x127e,0x1284,0x1284,0x127e,0x127e,
-0x1434,0x1434,0x1434,0x1434,0x1434,0x1434,0x1434,0x1434,0x1434,0x1434,0x1434,0x1425,0x142e,0x1425,0x142e,0x142e,
-0x1425,0x1425,0x1425,0x1425,0x1425,0x1425,0x1431,0x1428,0x1c5,0x1c5,0x1c5,0x1c5,0x1c5,0x1c5,0x1c5,0x1c5,
-0x150f,0x150f,0x150f,0x150f,0x150f,0x150f,0x150f,0x150f,0x150f,0x150f,0x150f,0x150f,0x150f,0x150f,0x1c8,0x1c8,
-0x150c,0x150c,0x150c,0x150c,0x150c,0x1512,0x1c8,0x1c8,0x1c8,0x1c8,0x1c8,0x1c8,0x1c8,0x1c8,0x1c8,0x1c8,
-0x1668,0x165f,0x165f,0x165f,0x165f,0x165f,0x165f,0x165f,0x165f,0x165f,0x165f,0x165f,0x165f,0x165f,0x165f,0x165f,
-0x165f,0x165f,0x165f,0x165f,0x165f,0x165f,0x165f,0x165f,0x165f,0x165f,0x165f,0x165f,0x1ce,0x1ce,0x1ce,0x1ce,
-0x1d1,0x1d1,0x1d1,0x1d1,0x1d1,0x1d1,0x1d1,0x1d1,0x1d1,0x1d1,0x1d1,0x1d1,0x1d1,0x1d1,0x1d1,0x1d1,
-0x1d1,0x1d1,0x1d1,0x1d1,0x1d1,0x1d1,0x1d1,0x1d1,0x1d1,0x1d1,0x1d1,0x1d1,0x1d1,0x1d1,0x1d1,0x1d1,
-0x152a,0x152a,0x152a,0x152a,0x152a,0x152a,0x152a,0x152a,0x152a,0x152a,0x152a,0x1d4,0x1d4,0x1d4,0x1d4,0x1d4,
-0x152a,0x152a,0x152a,0x152a,0x152a,0x152a,0x152a,0x152a,0x152a,0x152a,0x152a,0x152a,0x152a,0x1d4,0x1d4,0x1d4,
-0x1d4,0x1d4,0x1d4,0x1d4,0x152a,0x152a,0x152a,0x152a,0x152a,0x152a,0x152a,0x152a,0x152a,0x152a,0x1d4,0x1d4,
-0x1527,0x1521,0x1524,0x152d,0x1530,0x1530,0x1530,0x1530,0x1530,0x1530,0x1530,0x1530,0x1d7,0x1d7,0x1d7,0x1d7,
-0x1d7,0x1d7,0x1d7,0x1d7,0x1518,0x1518,0x1518,0x1518,0x1518,0x1518,0x1518,0x1518,0x1518,0x1518,0x1518,0x1518,
-0x1518,0x1518,0x1518,0x1518,0x1533,0x1533,0x1533,0x1533,0x1533,0x1533,0x1533,0x1533,0x1533,0x1533,0x1533,0x1533,
-0x1533,0x1533,0x1533,0x1533,0x1533,0x1533,0x1533,0x1533,0x1533,0x1da,0x1da,0x1da,0x1da,0x1da,0x1da,0x1da,
-0x1da,0x1da,0x1da,0x1da,0x1da,0x1da,0x1da,0x1da,0x1da,0x1da,0x1da,0x1da,0x1da,0x1da,0x1da,0x1da,
-0x1da,0x1da,0x1da,0x1da,0x1da,0x1da,0x1da,0x1da,0x1da,0x1da,0x1da,0x1da,0x16c8,0x1536,0x153c,0x153c,
-0x1dd,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1dd,0x1dd,0x1545,0x1545,0x1dd,0x1dd,0x1545,
-0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1545,0x1dd,0x1545,0x1545,
-0x1545,0x1545,0x1545,0x1545,0x1545,0x1dd,0x1545,0x1545,0x1dd,0x1545,0x1545,0x1545,0x1545,0x1545,0x1dd,0x1dd,
-0x1539,0x1545,0x1536,0x153c,0x1536,0x153c,0x153c,0x153c,0x153c,0x1dd,0x1dd,0x153c,0x153c,0x1dd,0x1dd,0x153f,
-0x153f,0x1542,0x1dd,0x1dd,0x16cb,0x1dd,0x1dd,0x1dd,0x1dd,0x1dd,0x1dd,0x1536,0x1dd,0x1dd,0x1dd,0x1dd,
-0x1dd,0x1548,0x1545,0x1545,0x1545,0x1545,0x153c,0x153c,0x1dd,0x1dd,0x1539,0x1539,0x1539,0x1539,0x1539,0x1539,
-0x1539,0x1dd,0x1dd,0x1dd,0x1539,0x1539,0x1539,0x1539,0x1539,0x1dd,0x1dd,0x1dd,0x1dd,0x1dd,0x1dd,0x1dd,
-0x1dd,0x1dd,0x1dd,0x1dd,0x155d,0x155d,0x155d,0x155d,0x155d,0x155d,0x155d,0x155d,0x155d,0x155d,0x155d,0x155d,
-0x155d,0x155d,0x155d,0x155d,0x155d,0x155d,0x1e0,0x155d,0x155d,0x155d,0x155d,0x155d,0x155d,0x155d,0x155d,0x155d,
-0x155d,0x155d,0x155d,0x155d,0x1557,0x1557,0x1557,0x154b,0x154b,0x154b,0x1557,0x1557,0x154b,0x155a,0x154e,0x154b,
-0x1560,0x1560,0x1554,0x1560,0x1560,0x1551,0x1e0,0x1e0,0x156f,0x156f,0x156f,0x1563,0x1563,0x1563,0x1563,0x1563,
-0x1563,0x1566,0x1569,0x1e3,0x1e3,0x1e3,0x1e3,0x1e3,0x156c,0x156c,0x156c,0x156c,0x156c,0x156c,0x156c,0x156c,
-0x156c,0x156c,0x1e3,0x1e3,0x1e3,0x1e3,0x1e3,0x1e3,0x16ce,0x16ce,0x16ce,0x16ce,0x157b,0x1578,0x1e6,0x1e6,
-0x1e6,0x1e6,0x1e6,0x1e6,0x1e6,0x1e6,0x1e6,0x1e6,0x16f8,0x16f8,0x16f8,0x16f8,0x16f8,0x16f8,0x16f8,0x16f8,
-0x16f8,0x16f8,0x16f8,0x16f8,0x16f8,0x16f8,0x16f8,0x16f8,0x1581,0x1581,0x1581,0x1581,0x1581,0x1581,0x1581,0x1581,
-0x1581,0x1581,0x1581,0x1581,0x1581,0x1581,0x1581,0x1581,0x1581,0x1581,0x1581,0x1581,0x1581,0x1581,0x1581,0x1e9,
-0x1e9,0x1e9,0x1e9,0x1e9,0x1e9,0x1e9,0x1e9,0x1e9,0x1581,0x1581,0x1581,0x1581,0x1581,0x1581,0x1581,0x1581,
-0x1581,0x1581,0x1581,0x1581,0x1581,0x1581,0x1581,0x1581,0x1581,0x1581,0x1581,0x1581,0x1581,0x1581,0x1e9,0x1e9,
-0x1e9,0x1e9,0x1e9,0x1e9,0x1e9,0x1e9,0x1e9,0x1e9,0x1581,0x1581,0x1581,0x1581,0x1581,0x1581,0x1581,0x1581,
-0x1e9,0x1e9,0x1e9,0x1e9,0x1e9,0x1e9,0x1e9,0x1e9,0x1e9,0x1e9,0x1e9,0x1e9,0x1e9,0x1e9,0x1e9,0x1e9,
-0x1e9,0x1e9,0x1e9,0x1e9,0x1e9,0x1e9,0x1e9,0x1e9,0x158d,0x158d,0x158d,0x158d,0x158d,0x158d,0x158d,0x158d,
-0x158d,0x158d,0x158d,0x158d,0x158d,0x158d,0x158d,0x158d,0x158d,0x158d,0x158d,0x1584,0x1587,0x158a,0x158d,0x1ec,
-0x1ec,0x1ec,0x1ec,0x1ec,0x1ec,0x1ec,0x1ec,0x1ec,0x159c,0x159c,0x159c,0x159c,0x159c,0x1590,0x1590,0x1ef,
-0x1ef,0x1ef,0x1ef,0x1593,0x1593,0x1593,0x1593,0x1593,0x1599,0x1599,0x1599,0x1599,0x1599,0x1599,0x1596,0x1ef,
-0x1ef,0x1ef,0x1ef,0x1ef,0x1ef,0x1ef,0x1ef,0x1ef,0x15a5,0x15a5,0x15a5,0x15a5,0x15a5,0x1f2,0x1f2,0x15a2,
-0x15a2,0x15a2,0x15a2,0x15a2,0x15a2,0x15a2,0x15a2,0x15a2,0x159f,0x159f,0x159f,0x159f,0x159f,0x159f,0x159f,0x1f2,
-0x1f2,0x1f2,0x1f2,0x1f2,0x1f2,0x1f2,0x1f2,0x1f2,0x15a8,0x15ba,0x15ba,0x15ae,0x15b7,0x1f5,0x1f5,0x1f5,
-0x1f5,0x1f5,0x1f5,0x1f5,0x1f5,0x1f5,0x1f5,0x1f5,0x15b1,0x15b1,0x15b1,0x15b1,0x15b1,0x15b1,0x15b1,0x15b1,
-0x15b1,0x15b1,0x1f5,0x1f5,0x1f5,0x1f5,0x1f5,0x1f5,0x15c0,0x15c0,0x15c0,0x15c0,0x15c0,0x15c0,0x15c0,0x15c0,
-0x15c0,0x15c0,0x15c0,0x15c0,0x15c0,0x15c0,0x15c0,0x15c0,0x15c0,0x15c0,0x15c0,0x15c0,0x15c0,0x15c0,0x15c0,0x15c0,
-0x15c0,0x15c0,0x15c0,0x15c0,0x15c0,0x15c0,0x15c0,0x1f8,0x15cc,0x15cc,0x15cc,0x15cc,0x15cc,0x15c6,0x15cf,0x15cc,
-0x15cc,0x15cc,0x15cc,0x15cc,0x15cc,0x15cc,0x15cc,0x15cc,0x15c9,0x15c9,0x15c9,0x15c9,0x15c9,0x15c9,0x15c9,0x15c9,
-0x15c9,0x15c9,0x15cc,0x15cc,0x15cc,0x15cc,0x15cc,0x1fb,0x15d5,0x15d5,0x15d5,0x15d5,0x15d5,0x15d5,0x15d5,0x15d5,
-0x15d5,0x15d5,0x15d5,0x15d5,0x15d5,0x15d5,0x15d5,0x15d5,0x15d5,0x15d5,0x15d5,0x15d5,0x15d5,0x15d5,0x15d5,0x15d5,
-0x15d5,0x15d5,0x15d5,0x15d5,0x15d5,0x15d5,0x15d5,0x1fe,0x15e1,0x15e1,0x15e1,0x15e1,0x15e1,0x15e1,0x15e1,0x15e1,
-0x15e1,0x15e1,0x15e1,0x15e1,0x15e1,0x15e1,0x15e1,0x15e1,0x15e1,0x15e1,0x15e1,0x15e1,0x15e1,0x15e1,0x15de,0x15de,
-0x15de,0x15de,0x15de,0x201,0x201,0x201,0x201,0x201,0x15f9,0x15f9,0x15fc,0x15fc,0x15ff,0x15f0,0x204,0x204,
-0x204,0x204,0x204,0x204,0x204,0x204,0x204,0x204,0x15f6,0x15f6,0x15f6,0x15f6,0x15f6,0x15f6,0x15f6,0x15f6,
-0x15f6,0x15f6,0x204,0x15f0,0x15f0,0x15f0,0x15f0,0x15f0,0x15f0,0x15f0,0x204,0x15f9,0x15f9,0x15f9,0x15f9,0x15f9,
-0x15f9,0x15f9,0x15f9,0x15f9,0x15f9,0x15f9,0x15f9,0x15f9,0x15f9,0x15f9,0x15f9,0x15f9,0x15f9,0x15f9,0x15f9,0x15f9,
-0x204,0x204,0x204,0x204,0x204,0x15f9,0x15f9,0x15f9,0x1608,0x1608,0x1608,0x1608,0x1608,0x1608,0x1608,0x1608,
-0x1608,0x1608,0x1608,0x1608,0x1608,0x1608,0x1608,0x1608,0x1608,0x1608,0x1608,0x1608,0x1608,0x1608,0x1608,0x1608,
-0x1608,0x207,0x207,0x207,0x207,0x207,0x207,0x207,0x1611,0x1611,0x1611,0x1611,0x1611,0x1611,0x1611,0x1611,
-0x1611,0x1611,0x1611,0x1611,0x1611,0x1611,0x1611,0x1611,0x1611,0x1611,0x20a,0x20a,0x20a,0x20a,0x20a,0x20a,
-0x20a,0x160e,0x160e,0x160e,0x160e,0x20a,0x20a,0x20a,0x162c,0x162c,0x162c,0x162c,0x162c,0x162c,0x162c,0x162c,
-0x162c,0x162c,0x162c,0x162c,0x162c,0x162c,0x162c,0x1614,0x1626,0x1626,0x1614,0x1614,0x1614,0x1614,0x210,0x210,
-0x1626,0x1626,0x1629,0x1629,0x1614,0x1614,0x1626,0x161a,0x1617,0x161d,0x162f,0x162f,0x1620,0x1620,0x1623,0x1623,
-0x1623,0x162f,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,
-0x16d4,0x16d4,0x16d4,0x16d4,0x16d1,0x16d1,0x210,0x210,0x210,0x210,0x210,0x210,0x210,0x210,0x210,0x210,
-0x210,0x210,0x210,0x210,0x210,0x210,0x210,0x210,0x210,0x210,0x210,0x210,0x210,0x210,0x210,0x210,
-0x210,0x210,0x210,0x210,0x210,0x210,0x210,0x210,0x213,0x1632,0x1632,0x1632,0x1632,0x1632,0x1632,0x1632,
-0x1632,0x1632,0x1632,0x1632,0x1632,0x1632,0x1632,0x1632,0x1632,0x1632,0x1632,0x1632,0x1632,0x213,0x213,0x213,
-0x213,0x213,0x213,0x213,0x213,0x213,0x213,0x213,0x1635,0x1635,0x1635,0x1635,0x1635,0x1635,0x1635,0x1635,
-0x1635,0x1635,0x1635,0x1635,0x216,0x216,0x216,0x216,0x1635,0x1635,0x1635,0x1635,0x1635,0x1635,0x1635,0x1635,
-0x1635,0x1635,0x1635,0x1635,0x1635,0x1635,0x1635,0x1635,0x216,0x216,0x216,0x216,0x216,0x216,0x216,0x216,
-0x1635,0x1635,0x1635,0x1635,0x1635,0x1635,0x1635,0x1635,0x1635,0x1635,0x216,0x216,0x216,0x216,0x216,0x216,
-0x1635,0x1635,0x1635,0x1635,0x1635,0x1635,0x1635,0x1635,0x216,0x216,0x216,0x216,0x216,0x216,0x216,0x216,
-0x1635,0x1635,0x1635,0x1635,0x1635,0x1635,0x1635,0x1635,0x1635,0x1635,0x1635,0x1635,0x1635,0x1635,0x1635,0x1635,
-0x1635,0x1635,0x216,0x216,0x216,0x216,0x216,0x216,0x216,0x216,0x216,0x216,0x216,0x216,0x216,0x216,
-0x216,0x216,0x216,0x216,0x216,0x216,0x216,0x216,0x216,0x216,0x216,0x216,0x216,0x216,0x216,0x216,
-0x216,0x216,0x216,0x216,0x1638,0x1647,0x163e,0x163b,0x164d,0x164d,0x1641,0x164d,0x219,0x219,0x219,0x219,
-0x219,0x219,0x219,0x219,0x1644,0x1644,0x1644,0x1644,0x1644,0x1644,0x1644,0x1644,0x1644,0x1644,0x219,0x219,
-0x219,0x219,0x219,0x219,0x1653,0x1653,0x1653,0x1653,0x1653,0x1653,0x1653,0x1653,0x1653,0x1653,0x1650,0x1650,
-0x1650,0x1650,0x1650,0x1650,0x1650,0x1650,0x1650,0x21c,0x21c,0x21c,0x21c,0x21c,0x21c,0x21c,0x21c,0x21c,
-0x21c,0x21c,0x21c,0x1659,0x16e9,0x16e9,0x16e9,0x16e9,0x16e9,0x16e9,0x16e9,0x16e9,0x16e9,0x16e9,0x16e9,0x16e9,
-0x16e9,0x16e9,0x16e9,0x16e9,0x16e9,0x16e9,0x16e9,0x16e9,0x16e9,0x16e9,0x16e9,0x16e9,0x16e9,0x16e9,0x21f,0x21f,
-0x21f,0x16da,0x16da,0x16da,0x16e6,0x16e6,0x16da,0x16da,0x16da,0x16da,0x16e6,0x16da,0x16da,0x16da,0x16da,0x16dd,
-0x21f,0x21f,0x21f,0x21f,0x16e3,0x16e3,0x16e3,0x16e3,0x16e3,0x16e3,0x16e3,0x16e3,0x16e3,0x16e3,0x16e0,0x16e0,
-0x16ec,0x16ec,0x16ec,0x16e0,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x222,0x222,0x222,0x222,0x222,
-0x222,0x222,0x222,0x222,0x222,0x222,0x222,0x222,0x222,0x222,0x222,0x222,0x222,0x222,0x222,0x222,
-0x222,0x222,0x222,0x222,0x222,0x222,0x222,0x222,0x222,0x222,0x222,0x222,0x1701,0x1701,0x1701,0x1701,
-0x1701,0x1701,0x1701,0x1701,0x1701,0x1701,0x1701,0x1701,0x1701,0x1701,0x1701,0x1701,0x1701,0x1701,0x1701,0x228,
-0x1701,0x1701,0x228,0x228,0x228,0x228,0x228,0x16fe,0x16fe,0x16fe,0x16fe,0x16fe,0x1704,0x1704,0x1704,0x1704,
-0x1704,0x1704,0x1704,0x22b,0x1704,0x22b,0x1704,0x1704,0x1704,0x1704,0x22b,0x1704,0x1704,0x1704,0x1704,0x1704,
-0x1704,0x1704,0x1704,0x1704,0x1704,0x1704,0x1704,0x1704,0x1704,0x1704,0x22b,0x1704,0x1704,0x1704,0x1704,0x1704,
-0x1704,0x1704,0x1704,0x1704,0x1704,0x1707,0x22b,0x22b,0x22b,0x22b,0x22b,0x22b,0x1572,0x1572,0x1572,0x1572,
-0x1572,0x1572,0x1572,0x1572,0x1572,0x1572,0x1572,0x1572,0x1572,0x1572,0x1572,0x1572,0x1710,0x1710,0x1710,0x1710,
-0x1710,0x1710,0x1710,0x1710,0x1710,0x1710,0x1710,0x1710,0x1710,0x1710,0x1710,0x1710,0x1710,0x1710,0x1710,0x22e,
-0x22e,0x22e,0x22e,0x22e,0x22e,0x22e,0x22e,0x22e,0x22e,0x22e,0x22e,0x22e,0x170d,0x170d,0x170d,0x170d,
-0x170d,0x170d,0x170d,0x170d,0x170d,0x170d,0x170d,0x170d,0x170d,0x170d,0x170d,0x170d,0x170d,0x170d,0x170d,0x22e,
-0x22e,0x22e,0x22e,0x22e,0x22e,0x22e,0x170a,0x170a,0x170a,0x170a,0x170a,0x170a,0x231,0x231,0x231,0x231,
-0x231,0x231,0x231,0x231,0x231,0x231,0x231,0x231,0x231,0x231,0x231,0x231,0x1713,0x1713,0x1713,0x1713,
-0x1713,0x1713,0x1713,0x1713,0x1716,0x231,0x231,0x231,0x231,0x231,0x231,0x231,0x231,0x231,0x231,0x231,
-0x231,0x231,0x231,0x231,0x231,0x231,0x231,0x231,0x231,0x231,0x231,0x231,0x231,0x231,0x231,0x231,
-0x231,0x231,0x231,0x231,0x231,0x231,0x231,0x231,0x1713,0x1713,0x1713,0x1713,0x1713,0x231,0x231,0x231,
-0x231,0x231,0x231,0x231,0x231,0x231,0x231,0x231,0x231,0x231,0x231,0x231,0x231,0x231,0x231,0x231,
-0x231,0x231,0x231,0x231,0x231,0x231,0x231,0x231,0x231,0x231,0x231,0x231,0x171c,0x171c,0x171c,0x171c,
-0x1719,0x171c,0x171c,0x171f,0x1722,0x171f,0x171f,0x171c,0x234,0x234,0x234,0x234,0x234,0x234,0x234,0x234,
-0x234,0x234,0x234,0x234,0x234,0x234,0x234,0x1719,0x1719,0x1719,0x1719,0x1719,0x237,0x237,0x237,0x237,
-0x237,0x237,0x237,0x237,0x237,0x237,0x237,0x237,0x237,0x237,0x237,0x237,0x237,0x237,0x237,0x237,
-0x237,0x237,0x237,0x237,0x237,0x237,0x237,0x237,0x237,0x237,0x237,0x237,0x1728,0x1728,0x24f,0x24f,
-0x24f,0x24f,0x24f,0x24f,0x24f,0x24f,0x24f,0x24f,0x24f,0x24f,0x24f,0x24f,0x237,0x237,0x237,0x237,
-0x237,0x237,0x237,0x237,0x237,0x237,0x237,0x237,0x237,0x237,0x237,0x237,0x237,0x237,0x237,0x237,
-0x237,0x237,0x237,0x237,0x237,0x237,0x237,0x237,0x237,0x237,0x8fa,0x8fa,0xabc,0xabc,0xabc,0xabc,
-0xabc,0xabc,0xabc,0xabc,0xabc,0xabc,0xabc,0xabc,0xabc,0xabc,0xabc,0xabc,0xabc,0xabc,0xabc,0xabc,
-0xabc,0xabc,0x23a,0x23a,0x23a,0x23a,0x23a,0x23a,0x23a,0x23a,0x23a,0x23a,0x10ad,0x10ad,0x10ad,0x10ad,
-0x1251,0x1251,0x1251,0x1251,0x1251,0x1251,0x1251,0x1251,0x1437,0x1725,0x1725,0x1725,0x1725,0x1725,0x1725,0x1725,
-0x1725,0x1725,0x23d,0x23d,0x23d,0x23d,0x23d,0x23d,0x23d,0x23d,0x23d,0x23d,0x23d,0x23d,0x23d,0x23d,
-0x23d,0x23d,0x23d,0x23d,0x23d,0x23d,0x23d,0x23d,0x23d,0x23d,0x23d,0x23d,0x23d,0x23d,0x23d,0x23d,
-0x23d,0x23d,0x23d,0x23d,0xc0f,0xc0f,0xc0f,0xc0f,0xc0f,0xc0f,0xc0f,0xc0f,0xc0f,0xc0f,0xc0f,0x1254,
-0x1254,0x1254,0x240,0x240,0xe3a,0xe3a,0xe3a,0xe3a,0xe3a,0xe3a,0xe3a,0xe3a,0xe3a,0xe3a,0xe3a,0xe3a,
-0xe3a,0xe3a,0xe3a,0xe3a,0xe3a,0xe3a,0xe3a,0xe3a,0xe3a,0xe3a,0xe3a,0xe3a,0xe3a,0xe3a,0x240,0x240,
-0x240,0x240,0x240,0x240,0x240,0x240,0x240,0x240,0x240,0x240,0x240,0x240,0x240,0x240,0x240,0x240,
-0x240,0x240,0x240,0x240,0x240,0x240,0x240,0x240,0x240,0x240,0x240,0x240,0x240,0x240,0x240,0x240,
-0xb1f,0xb1f,0xb1f,0xb1f,0xb1f,0xb1f,0xb1f,0xb1f,0xb1f,0xb1f,0xb1f,0xb1f,0xb1f,0xb1f,0xb1f,0xb1f,
-0xb1f,0xb1f,0xb1f,0xb1f,0xb1f,0xb1f,0xb1f,0x243,0x243,0x243,0x243,0x243,0x243,0x243,0x243,0x243,
-0xb22,0xb22,0xb22,0xb22,0xb22,0xb22,0xb22,0xb22,0xb22,0xb22,0xb22,0xb22,0xb22,0xb22,0xb22,0xb22,
-0xb22,0xb22,0xb22,0xb22,0xb22,0xb22,0xb22,0xb22,0xb22,0xb22,0xb22,0xb22,0xb22,0xb22,0x246,0x246,
-0x1266,0x1266,0x1266,0x1266,0x1266,0x1266,0x1266,0x1266,0x1266,0x1266,0x1266,0x1266,0x1266,0x1266,0x1266,0x1266,
-0x1266,0x1266,0x1266,0x1266,0x1266,0x249,0x249,0x249,0x249,0x249,0x249,0x249,0x249,0x249,0x249,0x249,
-0x136e,0x136e,0x136e,0x136e,0x136e,0x136e,0x136e,0x136e,0x136e,0x136e,0x136e,0x136e,0x136e,0x136e,0x136e,0x136e,
-0x136e,0x136e,0x136e,0x136e,0x136e,0x136e,0x136e,0x136e,0x136e,0x136e,0x136e,0x136e,0x136e,0x136e,0x24c,0x24c,
-0x10bf,0x34b,0x34b,0x357,0xc51,0x35a,0x35a,0x35a,0x35a,0x35a,0x35a,0x35a,0x35a,0x35a,0x35a,0x35a,
-0x35a,0x35a,0x35a,0x35a,0x35a,0x35a,0x35a,0x35a,0x35a,0x35a,0x35a,0x35a,0x35a,0x35a,0x35a,0x35a,
-0x357,0x34b,0x34b,0x34b,0x34b,0x34b,0x34b,0x34b,0x34b,0x357,0x357,0x357,0x357,0x351,0x10c2,0x1296,
-0x35a,0x8ca,0x8cd,0x34e,0x34e,0x10bf,0x1293,0x1293,0x35d,0x35d,0x35d,0x35d,0x35d,0x35d,0x35d,0x35d,
-0x35a,0x35a,0x34b,0x34b,0x858,0x85b,0x8e2,0x8e2,0x8e2,0x8e2,0x8e2,0x8e2,0x8e2,0x8e2,0x8e2,0x8e2,
-0x354,0xf21,0xf1e,0x1299,0x1299,0x1299,0x1299,0x1299,0x145b,0x10c5,0x10c5,0xe73,0xe73,0xd41,0xe73,0xe73,
-0x35a,0x35a,0x35a,0x35a,0x35a,0x35a,0x35a,0x35a,0x35a,0x35d,0x35a,0x35a,0x35a,0x35a,0x35a,0x35a,
-0x35a,0x35d,0x35a,0x35a,0x35d,0x35a,0x35a,0x35a,0x35a,0x35a,0x1293,0x1296,0x34e,0x35a,0x357,0x357,
-0x43b,0x43b,0x43b,0x43b,0x43b,0x43b,0x43b,0x43b,0x43b,0x43b,0x43b,0x43b,0x43b,0x43b,0x43b,0x43b,
-0x43b,0x43b,0x43b,0x43b,0x43b,0x43b,0x43b,0xb3d,0xb3d,0xd4d,0xd4d,0x438,0xd50,0x137d,0x137d,0x137d,
-0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,
-0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,0x43e,
-0x444,0x444,0x444,0x10da,0x10da,0x10da,0x10da,0x10da,0x441,0x441,0x441,0x441,0x441,0x441,0x441,0x441,
-0x441,0x441,0x441,0x441,0x441,0x441,0x441,0x441,0x441,0x441,0x441,0x441,0x441,0x441,0x441,0x441,
-0x441,0x441,0x441,0x441,0x441,0x441,0x441,0x441,0x441,0x441,0x10d7,0x10d7,0x10d7,0x10d7,0x10d7,0x10d7,
-0x447,0x444,0x444,0x444,0x444,0x444,0x444,0x444,0x444,0x444,0x444,0x444,0x444,0x444,0x444,0x444,
-0x444,0x444,0x444,0x444,0x444,0x444,0x444,0x444,0x444,0x444,0x444,0x444,0x444,0x444,0x444,0x444,
-0x444,0x444,0x444,0x444,0x450,0x44a,0x450,0x44a,0x450,0x44a,0x450,0x44a,0x450,0x44a,0x450,0x44a,
-0x450,0x44a,0x450,0x44a,0x450,0x44a,0x450,0x44a,0x450,0x44a,0x450,0x44a,0x450,0x44a,0x450,0x44a,
-0x450,0x44a,0x450,0x44a,0x450,0x44a,0x44a,0x44a,0x44a,0x44a,0x44d,0x93c,0xf6f,0xf6f,0xf72,0xf6f,
-0x450,0x44a,0x450,0x44a,0x450,0x44a,0x450,0x44a,0x450,0x44a,0x450,0x44a,0x450,0x44a,0x450,0x44a,
-0x450,0x44a,0x450,0x44a,0x450,0x44a,0x450,0x44a,0x450,0x44a,0xf72,0xf6f,0xf72,0xf6f,0xf72,0xf6f,
-0x45c,0x45c,0x45c,0x45c,0x45c,0x45c,0x45c,0x45c,0x45f,0x45f,0x45f,0x45f,0x45f,0x45f,0x45f,0x45f,
-0x45c,0x45c,0x45c,0x45c,0x45c,0x45c,0x45c,0x45c,0x45f,0x45f,0x45f,0x45f,0x45f,0x45f,0x45f,0x45f,
-0x63c,0x63c,0x63f,0x47a,0x64b,0x648,0x648,0x645,0x4a4,0x4a4,0x462,0x462,0x462,0x462,0x462,0xa6b,
-0x64e,0x486,0x666,0x669,0x49b,0x64e,0x489,0x489,0x47a,0x495,0x495,0x63c,0x4a1,0x49e,0x642,0x474,
-0x46b,0x46b,0x46e,0x46e,0x46e,0x46e,0x46e,0x471,0x46e,0x46e,0x46e,0x465,0x4aa,0x4aa,0x4a7,0x4a7,
-0x65a,0x48f,0x48c,0x657,0x654,0x651,0x663,0x47d,0x660,0x660,0x492,0x495,0x65d,0x65d,0x492,0x495,
-0x477,0x47a,0x47a,0x47a,0x498,0x483,0x480,0xb52,0xa71,0xa74,0xa6e,0xa6e,0xa6e,0xa6e,0xb49,0xb49,
-0xb49,0xb49,0xb4f,0xc7e,0xc7b,0xd5c,0xd5f,0xb4c,0xd5f,0xd5f,0xd5f,0xd5f,0xd5c,0xd5f,0xd5f,0xb46,
-0x4dd,0x4dd,0x4f5,0x678,0x4da,0x675,0x4dd,0x4f2,0x4da,0x678,0x4ec,0x4f5,0x4f5,0x4f5,0x4ec,0x4ec,
-0x4f5,0x4f5,0x4f5,0x681,0x4da,0x4f5,0x67b,0x4da,0x4e9,0x4f5,0x4f5,0x4f5,0x4f5,0x4f5,0x4da,0x4da,
-0x4e0,0x675,0x67e,0x4da,0x4f5,0x4da,0x684,0x4da,0x4f5,0x4e3,0x4fb,0x687,0x4f5,0x4f5,0x4e6,0x4ec,
-0x4f5,0x4f5,0x4f8,0x4f5,0x4ec,0x4ef,0x4ef,0x4ef,0x4ef,0xa80,0xa7d,0xc81,0xd6e,0xb6d,0xb70,0xb70,
-0xb6a,0xb67,0xb67,0xb67,0xb67,0xb70,0xb6d,0xb6d,0xb6d,0xb6d,0xb64,0xb67,0xd6b,0xe7f,0xe82,0xf78,
-0x10e9,0x10e9,0x10e9,0x68d,0x68a,0x4fe,0x501,0x501,0x501,0x501,0x501,0x68a,0x68d,0x68d,0x68a,0x501,
-0x693,0x693,0x693,0x693,0x693,0x693,0x693,0x693,0x693,0x693,0x693,0x693,0x50a,0x50a,0x50a,0x50a,
-0x690,0x690,0x690,0x690,0x690,0x690,0x690,0x690,0x690,0x690,0x504,0x504,0x504,0x504,0x504,0x504,
-0x510,0x510,0x510,0x510,0x510,0x510,0x510,0x510,0x50d,0x516,0x516,0x510,0x510,0x510,0x513,0x50d,
-0x510,0x510,0x50d,0x50d,0x50d,0x50d,0x510,0x510,0x696,0x696,0x50d,0x50d,0x510,0x510,0x510,0x510,
-0x510,0x510,0x510,0x510,0x510,0x510,0x510,0x510,0x510,0x513,0x513,0x513,0x510,0x510,0x699,0x510,
-0x699,0x510,0x510,0x510,0x510,0x510,0x510,0x510,0x50d,0x510,0x50d,0x50d,0x50d,0x50d,0x50d,0x50d,
-0x510,0x510,0x50d,0x696,0x50d,0x50d,0x50d,0xa86,0xa86,0xa86,0xa86,0xa86,0xa86,0xa86,0xa86,0xa86,
-0xb73,0xb73,0xb73,0xb73,0xb73,0xb73,0xb73,0xb73,0xb73,0xb73,0xb73,0xb73,0x69f,0x519,0x69f,0x69f,
-0x51c,0x519,0x519,0x69f,0x69f,0x51c,0x519,0x69f,0x51c,0x519,0x519,0x69f,0x519,0x69f,0x528,0x525,
-0x519,0x69f,0x519,0x519,0x519,0x519,0x69f,0x519,0x519,0x69f,0x69f,0x69f,0x69f,0x519,0x519,0x69f,
-0x51c,0x69f,0x51c,0x69f,0x69f,0x69f,0x69f,0x69f,0x6a5,0x51f,0x69f,0x51f,0x51f,0x519,0x519,0x519,
-0x69f,0x69f,0x69f,0x69f,0x519,0x519,0x519,0x519,0x69f,0x69f,0x519,0x519,0x519,0x51c,0x519,0x519,
-0x51c,0x519,0x519,0x51c,0x69f,0x51c,0x519,0x519,0x69f,0x519,0x519,0x519,0x519,0x519,0x69f,0x519,
-0x519,0x519,0x519,0x519,0x519,0x519,0x519,0x519,0x519,0x519,0x519,0x519,0x6a2,0x69f,0x51c,0x519,
-0x69f,0x69f,0x69f,0x69f,0x519,0x519,0x69f,0x69f,0x519,0x51c,0x6a2,0x6a2,0x51c,0x51c,0x519,0x519,
-0x51c,0x51c,0x519,0x519,0x51c,0x51c,0x519,0x519,0x519,0x519,0x519,0x519,0x51c,0x51c,0x69f,0x69f,
-0x51c,0x51c,0x69f,0x69f,0x51c,0x51c,0x519,0x519,0x519,0x519,0x519,0x519,0x519,0x519,0x519,0x519,
-0x519,0x69f,0x519,0x519,0x519,0x69f,0x519,0x519,0x519,0x519,0x519,0x519,0x519,0x69f,0x519,0x519,
-0x519,0x519,0x519,0x519,0x51c,0x51c,0x51c,0x51c,0x519,0x519,0x519,0x519,0x519,0x519,0x519,0x519,
-0x519,0x519,0x519,0x519,0x519,0x519,0x519,0x69f,0x519,0x519,0x519,0x519,0x519,0x519,0x519,0x519,
-0x519,0x519,0x519,0x519,0x519,0x519,0x519,0x519,0x519,0x519,0x519,0x519,0x519,0x519,0x519,0x519,
-0x519,0x519,0x519,0x519,0x519,0x519,0x519,0x519,0x51c,0x51c,0x51c,0x51c,0x519,0x519,0x519,0x519,
-0x519,0x519,0x51c,0x51c,0x51c,0x51c,0x519,0x522,0x519,0x519,0xb76,0xb76,0xb76,0xb76,0xb76,0xb76,
-0xb76,0xb76,0xb76,0xb76,0xb76,0xb76,0xb76,0xb76,0x52b,0xa89,0x52b,0x52b,0x52b,0x52b,0x52b,0x52b,
-0x53a,0x537,0x53a,0x537,0x52b,0x52b,0x52b,0x52b,0x52b,0x52b,0x6a8,0x52b,0x52b,0x52b,0x52b,0x52b,
-0x52b,0x52b,0x531,0x531,0x52b,0x52b,0x52b,0x52b,0x534,0x534,0x52b,0x52b,0x52b,0x52b,0x52b,0x52b,
-0x52e,0x7ad,0x7aa,0x52b,0x52b,0x52b,0x52b,0x52b,0x52b,0x52b,0x52b,0x52b,0x52b,0x52b,0x52b,0x52b,
-0x52b,0x52b,0x52b,0x52b,0x52b,0x52b,0x52b,0x52b,0x52b,0x52b,0x52b,0x52b,0x52b,0x52b,0x52b,0x52b,
-0x52b,0x52b,0x52b,0x52b,0x52b,0x52b,0x52b,0xa89,0xb7c,0xa89,0xa89,0xa89,0x53d,0x53d,0x53d,0x53d,
-0x53d,0x53d,0x53d,0x53d,0x53d,0x53d,0x53d,0x53d,0x53d,0x53d,0x53d,0x53d,0x53d,0x53d,0x53d,0x53d,
-0x53d,0x53d,0x53d,0x53d,0x53d,0x53d,0x53d,0x53d,0x53d,0x53d,0x53d,0x53d,0x6b1,0x6b1,0x6b1,0x6b1,
-0x6b1,0x6b1,0x6b1,0x6b1,0x6b1,0x6b1,0x543,0xbe5,0xbe5,0xbe5,0xbe5,0xbe5,0xbe5,0xbe5,0xbe5,0xbe5,
-0xbe5,0xbe5,0xbe5,0xbe5,0xbe5,0xbe5,0xbe5,0xbe5,0xbe5,0xbe5,0xbe5,0xcf9,0x6ba,0x6ba,0x6ba,0x6ba,
-0x6ba,0x6ba,0x6ba,0x6ba,0x6ba,0x6ba,0x6ba,0x6ba,0x6ba,0x6ba,0x6ba,0x6ba,0x6ba,0x6ba,0x6ba,0x6ba,
-0x546,0x549,0x549,0x549,0x549,0x549,0x549,0x549,0x549,0x549,0x549,0x549,0x6ba,0x6ba,0x6ba,0x6ba,
-0x6ba,0x6ba,0x6ba,0x6ba,0x6ba,0x6ba,0x6ba,0x6ba,0x549,0x549,0x549,0x549,0x6ba,0x6ba,0x6ba,0x6ba,
-0x6ba,0x6ba,0x6ba,0x6ba,0x6ba,0x6ba,0x6ba,0x6ba,0x6ba,0x6ba,0x6ba,0x6ba,0x6bd,0x6bd,0x6bd,0x6bd,
-0x6bd,0x6bd,0x6bd,0x6bd,0x6bd,0x6bd,0x6bd,0x6bd,0x6bd,0x6bd,0x6bd,0x6bd,0x54c,0x54c,0x6bd,0x6bd,
-0x6bd,0x6bd,0xb7f,0xb7f,0xb7f,0xb7f,0xb7f,0xb7f,0xb7f,0xb7f,0xb7f,0xb7f,0x6c3,0x6c3,0x54f,0x6c0,
-0x6c0,0x6c0,0x6c0,0x6c0,0x6c0,0x6c0,0x552,0x552,0x54f,0x54f,0x555,0x555,0x555,0x555,0x6c3,0x6c3,
-0x555,0x555,0x6c6,0x6c3,0x54f,0x54f,0x54f,0x54f,0x6c3,0x6c3,0x555,0x555,0x6c6,0x6c3,0x54f,0x54f,
-0x54f,0x54f,0x6c3,0x6c3,0x6c0,0x54f,0x555,0x6c3,0x54f,0x54f,0x6c0,0x6c3,0x6c3,0x6c3,0x555,0x555,
-0x54f,0x54f,0x54f,0x54f,0x54f,0x54f,0x54f,0x54f,0x54f,0x54f,0x54f,0x54f,0x54f,0x54f,0x6c3,0x6c0,
-0x6c3,0x6c0,0x54f,0x555,0x555,0x555,0x555,0x555,0x555,0x54f,0x54f,0x6c0,0xa8f,0xa8f,0xa8f,0xa8f,
-0xa8f,0xa8f,0xa8f,0xa8f,0xb82,0xb82,0xb82,0xb85,0xb85,0xb88,0xb88,0xb82,0x561,0x561,0x561,0x561,
-0x55e,0x6d5,0x6d5,0x558,0x558,0x6c9,0x558,0x558,0x558,0x558,0x6cf,0x6c9,0x558,0x55e,0x558,0x558,
-0xcfc,0xcfc,0xb8b,0xb8b,0xd7a,0xa92,0x55b,0x55b,0x6cc,0x567,0x6cc,0x55b,0x55e,0x558,0x55e,0x55e,
-0x558,0x558,0x55e,0x558,0x558,0x558,0x55e,0x558,0x558,0x558,0x55e,0x55e,0x558,0x558,0x558,0x558,
-0x558,0x558,0x558,0x558,0x55e,0x561,0x561,0x55b,0x558,0x558,0x558,0x558,0x6d5,0x558,0x6d5,0x558,
-0x558,0x558,0x558,0x558,0x564,0x564,0x564,0x564,0x564,0x564,0x564,0x564,0x564,0x564,0x564,0x564,
-0x558,0x558,0x558,0x558,0x558,0x558,0x558,0x558,0x558,0x558,0x558,0x558,0x6d8,0x6d5,0x56a,0x6d8,
-0x6c9,0x6cf,0x55e,0x6c9,0x6d2,0x6c9,0x6c9,0x558,0x6c9,0x6d5,0x56a,0x6d5,0xa92,0xa92,0xb8e,0xb8e,
-0xb8e,0xb8e,0xb8e,0xb8e,0xb8e,0xb8e,0xb8e,0xb91,0xb8e,0xb8e,0xd74,0xd80,0x56d,0x56d,0x56d,0x56d,
-0x56d,0x56d,0x56d,0x56d,0x56d,0x56d,0x56d,0x56d,0x56d,0x56d,0x56d,0x56d,0x56d,0x56d,0x56d,0x56d,
-0x570,0x12c9,0x12c9,0x12c9,0x570,0x570,0x570,0x570,0x570,0x570,0x570,0x570,0x147f,0x576,0x582,0x576,
-0x576,0x12c9,0x570,0x570,0x582,0x582,0x12cc,0x12cc,0x585,0x585,0x570,0x57c,0x570,0x570,0x57c,0x570,
-0x57c,0x570,0x57c,0x570,0x570,0x570,0x570,0x570,0x570,0x57c,0x570,0x570,0x570,0x570,0x570,0x570,
-0x12c9,0x570,0x570,0x570,0x570,0x570,0x570,0x570,0x570,0x570,0x570,0x57c,0x57c,0x570,0x570,0x570,
-0x570,0x570,0x570,0x570,0x570,0x6de,0x570,0x570,0x570,0x570,0x570,0x570,0x57c,0x570,0x570,0x57c,
-0x570,0x570,0x570,0x570,0x12c9,0x570,0x12c9,0x570,0x570,0x570,0x570,0x12c9,0x12c9,0x12c9,0x570,0x122a,
-0x570,0x570,0x570,0x579,0x579,0x579,0x579,0x12c6,0x12c6,0x570,0x573,0x57f,0x57c,0x570,0x570,0x570,
-0xb97,0xb94,0xb97,0xb94,0xb97,0xb94,0xb97,0xb94,0xb97,0xb94,0xb97,0xb94,0xb97,0xb94,0x6db,0x6db,
-0x6db,0x6db,0x6db,0x6db,0x6db,0x6db,0x6db,0x6db,0x570,0x57c,0x570,0x570,0x570,0x570,0x570,0x570,
-0x570,0x570,0x570,0x570,0x570,0x570,0x570,0x570,0x12c9,0x570,0x570,0x570,0x570,0x570,0x570,0x570,
-0x570,0x570,0x570,0x570,0x570,0x570,0x570,0x12c9,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,
-0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a9,0x5a9,0x5a9,0x5a9,0x5a9,0x5a9,0x5a9,0x5af,0x5af,0x5af,0x5af,
-0x5af,0x5af,0x5af,0x5af,0x5a6,0x5ac,0x59d,0x5a0,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,
-0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,
-0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5a3,0x5a3,0x5a3,0x5a3,0x5a3,0x5a3,0x5a6,0x5a6,0x5a6,0x5a6,
-0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,
-0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a9,0x5af,0x5ac,0x5a6,0x5a9,0x5af,0x5ac,0x5a6,
-0x5a9,0x5af,0x5ac,0x5a6,0x5a9,0x5af,0x5ac,0x5a6,0x5a9,0x5af,0x5ac,0x5a6,0x5a9,0x5af,0x5ac,0x5a6,
-0x5a9,0x5af,0x5ac,0x5a6,0x5a9,0x5af,0x5ac,0x5a6,0x5ac,0x5a6,0x5ac,0x5a6,0x5ac,0x5a6,0x5ac,0x5a6,
-0x5ac,0x5a6,0x5ac,0x5a6,0x5a9,0x5af,0x5ac,0x5a6,0x5a9,0x5af,0x5ac,0x5a6,0x5a9,0x5af,0x5ac,0x5a6,
-0x5a9,0x5af,0x5ac,0x5a6,0x5ac,0x5a6,0x5a9,0x5af,0x5ac,0x5a6,0x5ac,0x5a6,0x5a9,0x5af,0x5ac,0x5a6,
-0x5a9,0x5af,0x5ac,0x5a6,0x5ac,0x5a6,0x12cf,0x12cf,0x12cf,0x12cf,0x12cf,0x12cf,0x12cf,0x12cf,0x12cf,0x12cf,
-0x12cf,0x12cf,0x12cf,0x12cf,0x5ac,0x5a6,0x5ac,0x5a6,0x5ac,0x5a6,0x5a9,0x5af,0x5a9,0x5af,0x5ac,0x5a6,
-0x5ac,0x5a6,0x5ac,0x5a6,0x5ac,0x5a6,0x5ac,0x5a6,0x5ac,0x5a6,0x5ac,0x5a6,0x5a9,0x5ac,0x5a6,0x5a9,
-0x5ac,0x5a6,0x5a9,0x5af,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,
-0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a9,0x5a9,0x5a9,0x5a9,0x5a9,
-0x5a9,0x5a9,0x5a9,0x5a9,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,
-0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,
-0x5a6,0x5a6,0x5a6,0x5a6,0x5a9,0x5a9,0x5a6,0x5a9,0x5a6,0x5a9,0x5a6,0x5a6,0x5a9,0x5a6,0x5a6,0x5a9,
-0x5a6,0x5a9,0x5a6,0x5a6,0x5a9,0x5a6,0x5a9,0x5a9,0x5a6,0x5a6,0x5a6,0x5a9,0x5a6,0x5a6,0x5a6,0x5a6,
-0x5a6,0x5a9,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,
-0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a9,0x5a9,0x5a6,0x5a6,0x5a9,0x5a6,0x5a9,0x5a6,
-0x5a6,0x5a6,0x5a6,0x5a6,0x5a9,0x5a9,0x5a9,0x5a9,0x5a9,0x5a9,0x5a9,0x5a9,0x5a9,0x5a9,0x5a9,0x5a9,
-0x5a9,0x5a9,0x5a9,0x5a9,0x5a9,0x5a9,0x5a9,0x5a9,0x5a9,0x5a9,0x5a9,0x5a9,0x5a9,0x5a9,0x5a9,0x5a9,
-0x5a9,0x5a9,0x5a9,0x5a9,0x5a9,0x5a9,0x5a9,0x5af,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,
-0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,
-0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5af,0x5af,0x5af,0x5af,0x5af,0x5af,0x5af,0x5af,
-0x5af,0x5af,0x5af,0x5af,0x5af,0x5af,0x5af,0x5af,0x5af,0x5af,0x5af,0x5af,0x5af,0x5ac,0x5ac,0x5ac,
-0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5b2,0x5b2,0x5b2,0x5b2,0xf84,0xf84,0xf84,0x1482,
-0x1482,0x1482,0x1482,0x1482,0x1482,0x1482,0x1680,0x1680,0x80a,0x810,0x810,0x81c,0x81c,0x80d,0x804,0x80d,
-0x804,0x80d,0x804,0x80d,0x804,0x80d,0x804,0x80d,0x5c1,0x5c1,0x5bb,0x5c1,0x5bb,0x5c1,0x5bb,0x5c1,
-0x5bb,0x5c1,0x5bb,0x5be,0x5c4,0x5c1,0x5bb,0x5c1,0x5bb,0x5be,0x5c4,0x5c1,0x5bb,0x5c1,0x5bb,0x5be,
-0x5c4,0x5c1,0x5bb,0x5be,0x5c4,0x5c1,0x5bb,0x5be,0x5c4,0x5c1,0x5bb,0x5c1,0x5bb,0x5c1,0x5bb,0x5c1,
-0x5bb,0x5c1,0x5bb,0x5be,0x5c4,0x5c1,0x5bb,0x5be,0x5c4,0x5c1,0x5bb,0x5be,0x5c4,0x5c1,0x5bb,0x5be,
-0x5c4,0x5c1,0x5bb,0x5be,0x5c4,0x5c1,0x5bb,0x5be,0x5c4,0x5c1,0x5bb,0x5be,0x5c4,0x5c1,0x5bb,0x5be,
-0x5c4,0x5c1,0x5bb,0x5be,0x6ae,0x6ae,0x6ae,0x6ae,0x6ae,0x6ae,0x6ae,0x6ae,0x6ae,0x6ae,0x6ae,0x6ae,
-0x6ae,0x6ae,0x6ae,0x6ae,0x6ae,0x6ae,0x6ae,0x6ae,0x6ab,0x6ab,0x6ab,0x6ab,0x6ab,0x6ab,0x6ab,0x6ab,
-0x6ab,0x6ab,0x6ab,0x6ab,0x6ab,0x6ab,0x6ab,0x6ab,0x6ab,0x6ab,0x6ab,0x6ab,0x6ab,0x6ab,0x6ab,0x6ab,
-0x6ab,0x6ab,0x6ab,0x6ab,0x6ab,0x6ab,0x6ab,0x6ab,0x6ab,0x6ab,0x6b4,0x6b4,0x6b4,0x6b4,0x6b4,0x6b4,
-0x6b4,0x6b4,0x6b4,0x6b4,0x6b4,0x6b4,0x6b7,0x6b4,0x6b4,0x6b4,0x6b4,0x6b4,0x6b4,0x6b4,0x6b4,0x6b4,
-0x6b4,0x6b4,0x6b4,0x6b4,0x6b1,0x6b1,0x6b1,0x6b1,0x6b1,0x6b1,0x6b1,0x6b1,0x6b1,0x6b1,0x6b1,0x6b1,
-0x6b1,0x6b1,0x6b1,0x6b1,0x6ba,0x6ba,0x6ba,0x6ba,0x6ba,0x6ba,0x6ba,0x6ba,0x6ba,0x6ba,0x6ba,0x6ba,
-0x6ba,0x6ba,0x6ba,0x6ba,0x6ba,0x6ba,0x6ba,0x6ba,0x6ba,0x6ba,0x6ba,0x6ba,0x6ba,0x6ba,0x6ba,0x6ba,
-0x6ba,0x6ba,0x6ba,0x6ba,0x6e1,0x6e1,0x6e1,0x6e1,0x6e1,0x6e1,0x6e1,0x6e1,0x6e1,0x6e1,0x6e1,0x6e1,
-0x6e1,0x6e1,0x6e1,0x6e1,0x6e1,0x6e1,0x6e1,0x6e1,0x6e1,0x6e1,0x6e1,0x6e1,0x6e1,0x6e1,0x6e1,0x6e1,
-0x6e1,0x6e1,0x6e1,0x6e1,0xbeb,0x86d,0x867,0x864,0x86a,0x861,0x6f6,0x6f9,0x6f9,0x6f9,0x6f9,0x6f9,
-0x6f9,0x6f9,0x6f9,0x6f9,0x873,0x6f6,0x6f6,0x6f6,0x6f6,0x6f6,0x6f6,0x6f6,0x6f6,0x6f6,0x6f6,0x6f6,
-0x6f6,0x6f6,0x6f6,0x6f6,0x6f6,0x6f6,0x6f6,0x6f6,0x6f6,0x6f6,0x6f6,0x6f6,0x6f6,0x6f6,0x6f6,0x6f6,
-0x6f6,0x6f6,0x6f6,0x6f6,0x6f6,0x6f6,0x870,0x870,0x6fc,0x882,0x885,0x88b,0x7b0,0x7bc,0x8a0,0x7b9,
-0x879,0x876,0x879,0x876,0x87f,0x87c,0x87f,0x87c,0x879,0x876,0x7b6,0x88b,0x879,0x876,0x879,0x876,
-0x879,0x876,0x879,0x876,0x88e,0x897,0x894,0x894,0x702,0x73e,0x73e,0x73e,0x73e,0x73e,0x73e,0x738,
-0x738,0x738,0x738,0x738,0x738,0x738,0x738,0x738,0x738,0x738,0x738,0x738,0x738,0x738,0x738,0x738,
-0x738,0x738,0x738,0x705,0x720,0x6ff,0x726,0x729,0x723,0x73b,0x73b,0x73b,0x73b,0x73b,0x73b,0x735,
-0x735,0x735,0x735,0x735,0x735,0x735,0x735,0x735,0x735,0x735,0x735,0x735,0x735,0x735,0x735,0x735,
-0x735,0x735,0x735,0x705,0x720,0x6ff,0x720,0xbee,0x7a4,0x7a4,0x7a4,0x7a4,0x7a4,0x7a4,0x7a4,0x7a4,
-0x7a4,0x7a4,0x7a4,0x7a4,0x7a4,0x7a4,0x7a4,0x7a4,0x7a4,0x7a4,0x7a4,0x7a4,0x7a4,0x7a4,0x7a4,0x7a4,
-0x7a4,0x7a4,0x7a4,0x7a4,0x7a4,0x7a4,0x7a4,0x7a4,0x7a4,0x7a4,0x124b,0x124b,0x124b,0x124b,0x124b,0x7a7,
-0x7b6,0x7b9,0x7b9,0x7b9,0x7b9,0x7b9,0x7b9,0x7b9,0x7b9,0x7b9,0x8d6,0x8d6,0x8d6,0x8d6,0x7bf,0x7bf,
-0x891,0x89d,0x89d,0x89d,0x89d,0x89a,0x7b3,0x888,0xab6,0xab6,0xab6,0xbfd,0xc1b,0xc18,0xad1,0x85e,
-0x7c5,0x7c2,0x7c5,0x7c8,0x7c2,0x7c5,0x7c2,0x7c5,0x7c2,0x7c5,0x7c2,0x7c2,0x7c2,0x7c2,0x7c2,0x7c2,
-0x7c5,0x7c5,0x7c2,0x7c5,0x7c5,0x7c2,0x7c5,0x7c5,0x7c2,0x7c5,0x7c5,0x7c2,0x7c5,0x7c5,0x7c2,0x7c2,
-0xc1e,0x7d7,0x7d1,0x7d7,0x7d1,0x7d7,0x7d1,0x7d7,0x7d1,0x7d7,0x7d1,0x7d1,0x7d4,0x7d1,0x7d4,0x7d1,
-0x7d4,0x7d1,0x7d4,0x7d1,0x7d4,0x7d1,0x7d4,0x7d1,0x7d4,0x7d1,0x7d4,0x7d1,0x7d4,0x7d1,0x7d4,0x7d1,
-0x7d4,0x7d1,0x7d4,0x7d7,0x7d1,0x7d4,0x7d1,0x7d4,0x7d1,0x7d4,0x7d1,0x7d1,0x7d1,0x7d1,0x7d1,0x7d1,
-0x7d4,0x7d4,0x7d1,0x7d4,0x7d4,0x7d1,0x7d4,0x7d4,0x7d1,0x7d4,0x7d4,0x7d1,0x7d4,0x7d4,0x7d1,0x7d1,
-0x7d1,0x7d1,0x7d1,0x7d7,0x7d1,0x7d7,0x7d1,0x7d7,0x7d1,0x7d1,0x7d1,0x7d1,0x7d1,0x7d1,0x7d7,0x7d1,
-0x7d1,0x7d1,0x7d1,0x7d1,0x7d4,0x7d7,0x7d7,0x7d4,0x7d4,0x7d4,0x7d4,0x8a6,0x8a9,0x7da,0x7dd,0xc06,
-0x7e3,0x7e3,0x7e3,0x7e3,0x7e3,0x7e3,0x7e3,0x7e3,0x7e3,0x7e3,0x7e3,0x7e3,0x7e3,0x7e3,0x7e3,0x7e3,
-0x7e3,0x7e3,0x7e3,0x7e3,0x7e3,0x7e3,0x7e3,0x7e3,0x7e3,0x7e3,0x7e3,0x7e3,0x7e3,0x7e3,0x7e3,0x7e3,
-0x7e6,0x7e3,0x7e3,0x7e3,0x7e3,0x7e3,0x7e3,0x7e3,0x7e3,0x7e3,0x7e3,0x7e3,0x7e3,0x7e3,0x7e3,0x7e3,
-0x7e3,0x7e3,0x7e3,0x7e3,0x7e3,0x7e3,0x7e3,0x7e3,0x7e3,0x7e3,0x7e3,0x7e3,0x7ef,0x7ef,0x7ef,0x7ef,
-0x7ef,0x7ef,0x7ef,0x7ef,0x7ef,0x7ef,0x7ef,0x7ef,0x7ef,0x7ef,0x7ef,0x7ef,0x7ef,0x7ef,0x7ef,0x7ef,
-0x7ef,0x7ef,0x7ef,0x7ef,0x7ef,0x7ef,0x7ef,0x7ef,0xd08,0xd08,0xe34,0x7e9,0x8b2,0x8b2,0x8b2,0x8b2,
-0x8b2,0x8b2,0x8b2,0x8b2,0x8b2,0x8b2,0x8b2,0x8b2,0xd02,0xd02,0xd02,0xd02,0x7f2,0x7f2,0x7f2,0x7f2,
-0x7f2,0x7f2,0x7f2,0x7f2,0x7f2,0x7f2,0x7f2,0x7f2,0x7f2,0x7f2,0x7f2,0x7f2,0x8bb,0x8bb,0x8bb,0x8bb,
-0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x7f5,0x7f5,0x7f5,
-0x7f5,0x7f5,0x7f5,0xd0b,0xd0b,0xd0b,0xd0b,0x8be,0x8be,0x8be,0x8be,0x8be,0x7f5,0x7f5,0x7f5,0x7f5,
-0x7f5,0x7f5,0x7f5,0x7f5,0x7f5,0x7f5,0x7f5,0x7f5,0x7f5,0x7f5,0x7f5,0x7f5,0x7f5,0x7f5,0x7f5,0x7f5,
-0x7f5,0x7f5,0x7f5,0x7f5,0x7f5,0x7f5,0x7f5,0x7f5,0x7f5,0x7f5,0x7f5,0x7f5,0x7f5,0x7f5,0xd0b,0xd0b,
-0x7f8,0x7f8,0x7f8,0x7f8,0x7f8,0x7f8,0x7f8,0x7f8,0x7f8,0x7f8,0x7f8,0x7f8,0x7f8,0x7f8,0x7f8,0x7f8,
-0x7f8,0x7f8,0x7f8,0x7f8,0x7f8,0x7f8,0x7f8,0x7f8,0x7f8,0x7f8,0x7f8,0x7f8,0x7f8,0x7f8,0x7f8,0x7f8,
-0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x7fb,0x7fb,0x7fb,0x7fb,0x7fb,0x7fb,0x7fb,0x7fb,
-0x7fb,0x7fb,0x7fb,0x7fb,0x7fb,0x7fb,0x7fb,0x7fb,0x7fb,0x7fb,0x7fb,0x7fb,0x7fb,0x7fb,0x7fb,0x7fb,
-0x7fb,0x7fb,0x7fb,0x7fb,0x7fb,0x7fb,0x7fb,0x7fb,0x7fb,0x7fb,0xe37,0xe37,0xe37,0xe37,0xe37,0xe37,
-0xe37,0xe37,0xe37,0xe37,0xe37,0xe37,0xe37,0xe37,0xe37,0xe37,0xe37,0xe37,0xe37,0xe37,0xe37,0xe37,
-0x10ad,0x10ad,0x10ad,0x10ad,0x7fe,0x7fe,0x7fe,0x7fe,0x7fe,0x7fe,0x7fe,0x7fe,0x7fe,0x7fe,0x7fe,0x7fe,
-0x7fe,0x7fe,0x7fe,0x7fe,0x7fe,0x7fe,0x7fe,0x7fe,0x7fe,0x7fe,0x7fe,0x7fe,0x7fe,0x7fe,0x7fe,0x7fe,
-0x7fe,0x7fe,0x7fe,0x7fe,0x7fe,0x7fe,0x801,0x801,0x7fe,0x801,0x7fe,0x801,0x801,0x7fe,0x7fe,0x7fe,
-0x7fe,0x7fe,0x7fe,0x7fe,0x7fe,0x7fe,0x7fe,0x801,0x7fe,0x801,0x7fe,0x801,0x801,0x7fe,0x7fe,0x801,
-0x801,0x801,0x7fe,0x7fe,0x7fe,0x7fe,0x143a,0x143a,0xc0f,0xc0f,0xc0f,0xc0f,0xc0f,0xc0f,0xc0f,0xc0f,
-0xc0f,0xc0f,0xc0f,0xc0f,0xc0f,0xc0f,0xc0f,0xc0f,0x8b2,0x8b2,0x8b2,0x8b2,0x8b2,0x8b2,0x8b2,0x8b2,
-0x8b2,0x8b2,0x8b2,0x8b2,0x8b2,0x8b2,0x8b2,0x8b2,0x8b2,0x8b2,0x8b2,0x8b2,0x8b2,0x8b2,0x8b2,0x8b2,
-0x8b2,0x8b2,0x8b2,0x8b2,0x8b2,0x8b2,0x8b2,0x8b2,0x124e,0x124e,0x124e,0x124e,0x122d,0x122d,0x122d,0x122d,
-0x122d,0x122d,0x122d,0x122d,0xd02,0xc09,0xc09,0xc09,0xc09,0xc09,0xc09,0xc09,0xc09,0xc09,0xc09,0xc09,
-0xc09,0xc09,0xc09,0xc09,0x8b5,0x8b5,0x8b5,0x8b5,0x8b5,0x8b5,0x8b5,0x8b5,0x8b5,0x8b5,0x8b5,0x8b5,
-0x8b5,0x8b5,0x8b5,0x8b5,0x8b5,0x8b5,0x8b5,0x8b5,0x8b5,0x8b5,0x8b5,0x8b8,0x8b5,0x8b8,0x8b5,0x8b5,
-0x8b5,0x8b5,0x8b5,0x8b5,0x8b5,0x8b5,0x8b5,0x8b5,0x8b5,0x8b5,0x8b5,0x8b5,0x8b5,0x8b5,0x8b5,0x8b5,
-0x8b5,0xc09,0xc09,0xc09,0xc09,0xc09,0xc09,0xc09,0xc09,0xc09,0xc09,0xc09,0xc09,0xc09,0xc09,0xc09,
-0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,
-0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0xd0b,
-0x936,0x918,0x918,0x918,0x918,0x912,0x918,0x918,0x92a,0x918,0x918,0x915,0x921,0x927,0x927,0x927,
-0x927,0x927,0x92a,0x912,0x91e,0x912,0x912,0x912,0x909,0x909,0x912,0x912,0x912,0x912,0x912,0x912,
-0x92d,0x92d,0x92d,0x92d,0x92d,0x92d,0x92d,0x92d,0x92d,0x92d,0x912,0x912,0x912,0x912,0x912,0x912,
-0x912,0x912,0x912,0x912,0x915,0x909,0x912,0x909,0x912,0x909,0x924,0x91b,0x924,0x91b,0x933,0x933,
-0x942,0x942,0x942,0x942,0x942,0x942,0x942,0x942,0x942,0x942,0x942,0x942,0x942,0x942,0x942,0x942,
-0x942,0x942,0x942,0x942,0x942,0x942,0x942,0x942,0x942,0x942,0x942,0x942,0x942,0x942,0x942,0x942,
-0x945,0x945,0x945,0x945,0x945,0x945,0x945,0x945,0x945,0x945,0x945,0x945,0x945,0x945,0x945,0x945,
-0x945,0x945,0x945,0x945,0x945,0x945,0x945,0x945,0x945,0x945,0x945,0x945,0x945,0x945,0x945,0x945,
-0x948,0x948,0x948,0x948,0x948,0x948,0x948,0x948,0x948,0x948,0x948,0x948,0x948,0x948,0x948,0x948,
-0x948,0x948,0x948,0x948,0x948,0x948,0x948,0x948,0x948,0x948,0x948,0x948,0x948,0x948,0x948,0x948,
-0x951,0x951,0x951,0x951,0x951,0x951,0x951,0x951,0x951,0x951,0x951,0x951,0x951,0x951,0x951,0x951,
-0x951,0x951,0x951,0x951,0x951,0x951,0x951,0x951,0x951,0x951,0x951,0x951,0x951,0x951,0x94b,0x94b,
-0x954,0x954,0x954,0x954,0x954,0x954,0x954,0x954,0x954,0x954,0x954,0x954,0x954,0x954,0x954,0x954,
-0x954,0x954,0x954,0x954,0x954,0x954,0x954,0x954,0x954,0x954,0x954,0x954,0x954,0x954,0x94e,0x94e,
-0x951,0x951,0x951,0x951,0x951,0x951,0x951,0x951,0x951,0x951,0x951,0x951,0x951,0x951,0x951,0x951,
-0x951,0x951,0x951,0x951,0x951,0x951,0x951,0x951,0x951,0x951,0x951,0x951,0x951,0x951,0x951,0x951,
-0x954,0x954,0x954,0x954,0x954,0x954,0x954,0x954,0x954,0x954,0x954,0x954,0x954,0x954,0x954,0x954,
-0x954,0x954,0x954,0x954,0x954,0x954,0x954,0x954,0x954,0x954,0x954,0x954,0x954,0x954,0x954,0x954,
-0x957,0x95a,0x95a,0x95a,0x95a,0x95a,0x95a,0x95a,0x95a,0x95a,0x95a,0x95a,0x95a,0x95a,0x95a,0x95a,
-0x95a,0x95a,0x95a,0x95a,0x95a,0x95a,0x95a,0x95a,0x95a,0x95a,0x95a,0x95a,0x957,0x95a,0x95a,0x95a,
-0x95a,0x95a,0x95a,0x95a,0x95a,0x95a,0x95a,0x95a,0x95a,0x95a,0x95a,0x95a,0x95a,0x95a,0x95a,0x95a,
-0x95a,0x95a,0x95a,0x95a,0x95a,0x95a,0x95a,0x95a,0x9e7,0x9e7,0xf69,0x9e7,0x9e7,0x9e7,0x9ea,0x9e7,
-0xf69,0x9e7,0x9e7,0xf60,0x9e1,0x9d5,0x9d5,0x9d5,0x9d5,0x9e4,0x9d5,0xf4e,0xf4e,0xf4e,0x9d5,0x9d8,
-0x9e1,0x9db,0xf54,0xf63,0xf63,0xf4e,0xf4e,0xf69,0xad7,0xad7,0xad7,0xad7,0xad7,0xad7,0xad7,0xad7,
-0xad7,0xad7,0x9ed,0x9ed,0x9de,0x9de,0x9de,0x9de,0x9e7,0x9e7,0x9e7,0x9e7,0x9e7,0x9e7,0x9e4,0x9e4,
-0x9d5,0x9d5,0xf69,0xf69,0xf69,0xf69,0xf4e,0xf4e,0x9e7,0x9e7,0x9e7,0x9e7,0x9e7,0x9e7,0x9e7,0x9e7,
-0x9e7,0x9e7,0x9e7,0x9e7,0x9e7,0x9e7,0x9e7,0x9e7,0x9e7,0x9e7,0x9e7,0x9e7,0x9e7,0x9e7,0x9e7,0x9e7,
-0x9e7,0x9e7,0x9e7,0x9e7,0x9e7,0x9e7,0x9e7,0x9e7,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0xd59,
-0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,
-0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,
-0x9fc,0x9fc,0x9fc,0xd59,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,
-0x9fc,0x9fc,0x9fc,0x9fc,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,
-0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,
-0xa02,0xa02,0xa02,0xa02,0xa08,0xa08,0xa08,0xa08,0xa08,0xa08,0xa08,0xa08,0xa08,0xa08,0xa08,0xa08,
-0xa08,0xa05,0xa0b,0xa08,0xa08,0xa08,0xa08,0xa08,0xa08,0xa08,0xa08,0x10e0,0x10e0,0x10e0,0x10e0,0x10e0,
-0x10e0,0x10e0,0x10e0,0x10e0,0x10dd,0xa08,0xa08,0xa08,0xa08,0xa08,0xa08,0xa08,0xa08,0xa08,0xa08,0xa08,
-0xa08,0xa08,0xa08,0xa08,0xa08,0xa08,0xa08,0xa08,0xa08,0xa08,0xa08,0xa08,0xa08,0xa08,0xa08,0xa08,
-0xa08,0xa08,0xa08,0xa08,0xa08,0xa08,0xa08,0xa08,0xa1d,0xa1d,0xa1d,0xa1d,0xa1d,0xa1d,0xa1d,0xa1d,
+0x2d6,0x2d6,0x2d6,0x2d6,0x2d6,0x2e5,0x2d6,0x2d6,0x2d6,0x2d6,0x2d6,0x2d6,0x2d6,0x2d6,0x2d6,0x2d6,
+0x2d6,0x2d6,0x2d6,0x2d6,0x2d6,0x2d6,0x2d6,0x2d6,0x2d6,0x2d6,0x2d6,0x2d6,0x2d6,0x2d6,0x2d6,0x2d6,
+0x2d9,0x651,0x810,0x813,0x657,0x813,0x80d,0x64e,0x645,0x2df,0x663,0x2e2,0x816,0x63c,0x65a,0x80a,
+0x654,0x660,0x642,0x642,0x648,0x2dc,0x64e,0x64b,0x645,0x642,0x663,0x2e2,0x63f,0x63f,0x63f,0x651,
+0x2eb,0x2eb,0x2eb,0x2eb,0x2eb,0x2eb,0x66c,0x2eb,0x2eb,0x2eb,0x2eb,0x2eb,0x2eb,0x2eb,0x2eb,0x2eb,
+0x66c,0x2eb,0x2eb,0x2eb,0x2eb,0x2eb,0x2eb,0x65d,0x66c,0x2eb,0x2eb,0x2eb,0x2eb,0x2eb,0x66c,0x666,
+0x669,0x669,0x2e8,0x2e8,0x2e8,0x2e8,0x666,0x2e8,0x669,0x669,0x669,0x2e8,0x669,0x669,0x2e8,0x2e8,
+0x666,0x2e8,0x669,0x669,0x2e8,0x2e8,0x2e8,0x65d,0x666,0x669,0x669,0x2e8,0x669,0x2e8,0x666,0x2e8,
+0x2f7,0x672,0x2f7,0x2ee,0x2f7,0x2ee,0x2f7,0x2ee,0x2f7,0x2ee,0x2f7,0x2ee,0x2f7,0x2ee,0x2f7,0x2ee,
+0x2f4,0x66f,0x2f7,0x672,0x2f7,0x2ee,0x2f7,0x2ee,0x2f7,0x2ee,0x2f7,0x672,0x2f7,0x2ee,0x2f7,0x2ee,
+0x2f7,0x2ee,0x2f7,0x2ee,0x2f7,0x2ee,0x678,0x66f,0x2f7,0x2ee,0x2f7,0x672,0x2f7,0x2ee,0x2f7,0x2ee,
+0x2f7,0x66f,0x67b,0x675,0x2f7,0x2ee,0x2f7,0x2ee,0x66f,0x2f7,0x2ee,0x2f7,0x2ee,0x2f7,0x2ee,0x67b,
+0x675,0x678,0x66f,0x2f7,0x672,0x2f7,0x2ee,0x2f7,0x672,0x67e,0x678,0x66f,0x2f7,0x672,0x2f7,0x2ee,
+0x2f7,0x2ee,0x678,0x66f,0x2f7,0x2ee,0x2f7,0x2ee,0x2f7,0x2ee,0x2f7,0x2ee,0x2f7,0x2ee,0x2f7,0x2ee,
+0x2f7,0x2ee,0x2f7,0x2ee,0x2f7,0x2ee,0x678,0x66f,0x2f7,0x2ee,0x2f7,0x672,0x2f7,0x2ee,0x2f7,0x2ee,
+0x2f7,0x2ee,0x2f7,0x2ee,0x2f7,0x2ee,0x2f7,0x2ee,0x2f7,0x2f7,0x2ee,0x2f7,0x2ee,0x2f7,0x2ee,0x2f1,
+0x2fa,0x306,0x306,0x2fa,0x306,0x2fa,0x306,0x306,0x2fa,0x306,0x306,0x306,0x2fa,0x2fa,0x306,0x306,
+0x306,0x306,0x2fa,0x306,0x306,0x2fa,0x306,0x306,0x306,0x2fa,0x2fa,0x2fa,0x306,0x306,0x2fa,0x306,
+0x309,0x2fd,0x306,0x2fa,0x306,0x2fa,0x306,0x306,0x2fa,0x306,0x2fa,0x2fa,0x306,0x2fa,0x306,0x309,
+0x2fd,0x306,0x306,0x306,0x2fa,0x306,0x2fa,0x306,0x306,0x2fa,0x2fa,0x303,0x306,0x2fa,0x2fa,0x2fa,
+0x303,0x303,0x303,0x303,0x30c,0x30c,0x300,0x30c,0x30c,0x300,0x30c,0x30c,0x300,0x309,0x681,0x309,
+0x681,0x309,0x681,0x309,0x681,0x309,0x681,0x309,0x681,0x309,0x681,0x309,0x681,0x2fa,0x309,0x2fd,
+0x309,0x2fd,0x309,0x2fd,0x306,0x2fa,0x309,0x2fd,0x309,0x2fd,0x309,0x2fd,0x309,0x2fd,0x309,0x2fd,
+0x2fd,0x30c,0x30c,0x300,0x309,0x2fd,0x9ea,0x9ea,0x9ed,0x9e7,0x309,0x2fd,0x309,0x2fd,0x309,0x2fd,
+0x309,0x2fd,0x309,0x2fd,0x309,0x2fd,0x309,0x2fd,0x309,0x2fd,0x309,0x2fd,0x309,0x2fd,0x309,0x2fd,
+0x309,0x2fd,0x309,0x2fd,0x9ed,0x9e7,0x9ed,0x9e7,0x9ea,0x9e4,0x9ed,0x9e7,0xbaf,0xcb7,0x9ea,0x9e4,
+0x9ea,0x9e4,0x9ed,0x9e7,0x9ed,0x9e7,0x9ed,0x9e7,0x9ed,0x9e7,0x9ed,0x9e7,0x9ed,0x9e7,0x9ed,0x9e7,
+0xcb7,0xcb7,0xcb7,0xdb6,0xdb6,0xdb6,0xdb9,0xdb9,0xdb6,0xdb9,0xdb9,0xdb6,0xdb6,0xdb9,0xefa,0xefd,
+0xefd,0xefd,0xefd,0xefa,0xefd,0xefa,0xefd,0xefa,0xefd,0xefa,0xefd,0xefa,0x30f,0x684,0x30f,0x30f,
+0x30f,0x30f,0x30f,0x30f,0x30f,0x30f,0x30f,0x30f,0x30f,0x30f,0x30f,0x30f,0x30f,0x684,0x30f,0x30f,
+0x30f,0x30f,0x30f,0x30f,0x30f,0x30f,0x30f,0x30f,0x30f,0x30f,0x30f,0x30f,0x30f,0x30f,0x30f,0x30f,
+0x30f,0x30f,0x30f,0x30f,0x30f,0x30f,0x30f,0x30f,0x30f,0x30f,0x30f,0x30f,0x312,0x30f,0x30f,0x30f,
+0x30f,0x30f,0x30f,0x30f,0x30f,0x30f,0x30f,0x30f,0x30f,0x30f,0x30f,0x30f,0x30f,0x30f,0x30f,0x30f,
+0x30f,0x9f0,0x9f0,0x9f0,0x9f0,0x9f0,0xcba,0xcba,0x327,0x327,0x327,0x327,0x327,0x327,0x327,0x327,
+0x327,0x31e,0x31e,0x31e,0x31e,0x31e,0x31e,0x31e,0x31b,0x31b,0x318,0x318,0x68a,0x318,0x31e,0x68d,
+0x321,0x68d,0x68d,0x68d,0x321,0x68d,0x31e,0x31e,0x690,0x324,0x318,0x318,0x318,0x318,0x318,0x318,
+0x687,0x687,0x687,0x687,0x315,0x687,0x318,0xb25,0x327,0x327,0x327,0x327,0x327,0x318,0x318,0x318,
+0x318,0x318,0x9f9,0x9f9,0x9f6,0x9f3,0x9f6,0xcbd,0xcbd,0xcbd,0xcbd,0xcbd,0xcbd,0xcbd,0xcbd,0xcbd,
+0xcbd,0xcbd,0xcbd,0xcbd,0xcbd,0xcbd,0xcbd,0xcbd,0x693,0x693,0x693,0x693,0x693,0x693,0x693,0x693,
+0x693,0x693,0x693,0x693,0x693,0x693,0x693,0x693,0x693,0x693,0x693,0x693,0x693,0x693,0x693,0x693,
+0x693,0x693,0x693,0x693,0x693,0x693,0x693,0x693,0x693,0x693,0x693,0x693,0x693,0x693,0x693,0x693,
+0x693,0x693,0x693,0x693,0x693,0x693,0x693,0x693,0x693,0x693,0x693,0x693,0x693,0x693,0x693,0x693,
+0x693,0x693,0x693,0x693,0x693,0x693,0x693,0x693,0x696,0x696,0x94b,0x696,0x696,0x94e,0xb28,0xb28,
+0xb28,0xb28,0xb28,0xb28,0xb28,0xb28,0xb28,0xc6c,0xd83,0xd83,0xd83,0xd83,0xd83,0xd83,0xd83,0xd83,
+0xebe,0xebe,0xebe,0xebe,0xec1,0xd86,0xd86,0xd86,0x699,0x699,0xb2b,0xcb4,0xcb4,0xcb4,0xcb4,0xcb4,
+0xcb4,0xcb4,0xcb4,0xcb4,0xcb4,0xcb4,0xcb4,0xcb4,0xfa8,0xfa5,0xfa8,0xfa5,0x333,0x33c,0xfa8,0xfa5,
+9,9,0x342,0xf00,0xf00,0xf00,0x32a,0x14fd,9,9,9,9,0x33f,0x32d,0x351,0x330,
+0x351,0x351,0x351,9,0x351,9,0x351,0x351,0x348,0x69f,0x69f,0x69f,0x69f,0x69f,0x69f,0x69f,
+0x69f,0x69f,0x69f,0x69f,0x69f,0x69f,0x69f,0x69f,0x69f,0x69f,9,0x69f,0x69f,0x69f,0x69f,0x69f,
+0x69f,0x69f,0x351,0x351,0x348,0x348,0x348,0x348,0x348,0x69c,0x69c,0x69c,0x69c,0x69c,0x69c,0x69c,
+0x69c,0x69c,0x69c,0x69c,0x69c,0x69c,0x69c,0x69c,0x69c,0x69c,0x345,0x69c,0x69c,0x69c,0x69c,0x69c,
+0x69c,0x69c,0x348,0x348,0x348,0x348,0x348,0xfa8,0x354,0x354,0x357,0x351,0x351,0x354,0x34b,0x9fc,
+0xbb8,0xbb5,0x34e,0x9fc,0x34e,0x9fc,0x34e,0x9fc,0x34e,0x9fc,0x339,0x336,0x339,0x336,0x339,0x336,
+0x339,0x336,0x339,0x336,0x339,0x336,0x339,0x336,0x354,0x354,0x34b,0x345,0xb67,0xb64,0xbb2,0xcc3,
+0xcc0,0xcc6,0xcc3,0xcc0,0xdbc,0xdbf,0xdbf,0xdbf,0xa0b,0x6ab,0x363,0x366,0x363,0x363,0x363,0x366,
+0x363,0x363,0x363,0x363,0x366,0xa0b,0x366,0x363,0x6a8,0x6a8,0x6a8,0x6a8,0x6a8,0x6a8,0x6a8,0x6a8,
+0x6a8,0x6ab,0x6a8,0x6a8,0x6a8,0x6a8,0x6a8,0x6a8,0x6a8,0x6a8,0x6a8,0x6a8,0x6a8,0x6a8,0x6a8,0x6a8,
+0x6a8,0x6a8,0x6a8,0x6a8,0x6a8,0x6a8,0x6a8,0x6a8,0x6a2,0x6a2,0x6a2,0x6a2,0x6a2,0x6a2,0x6a2,0x6a2,
+0x6a2,0x6a5,0x6a2,0x6a2,0x6a2,0x6a2,0x6a2,0x6a2,0x6a2,0x6a2,0x6a2,0x6a2,0x6a2,0x6a2,0x6a2,0x6a2,
+0x6a2,0x6a2,0x6a2,0x6a2,0xa05,0x6a5,0x35d,0x360,0x35d,0x35d,0x35d,0x360,0x35d,0x35d,0x35d,0x35d,
+0x360,0xa05,0x360,0x35d,0x363,0x35d,0x363,0x35d,0x363,0x35d,0x363,0x35d,0x363,0x35d,0x363,0x35d,
+0x363,0x35d,0x363,0x35d,0x363,0x35d,0x363,0x35d,0x363,0x35d,0x366,0x360,0x363,0x35d,0x363,0x35d,
+0x363,0x35d,0x363,0x35d,0x363,0x35d,0x35a,0x957,0x95a,0x93c,0x93c,0x114f,0x9ff,0x9ff,0xbbe,0xbbb,
+0xa08,0xa02,0xa08,0xa02,0x363,0x35d,0x363,0x35d,0x363,0x35d,0x363,0x35d,0x363,0x35d,0x363,0x35d,
+0x363,0x35d,0x363,0x35d,0x363,0x35d,0x363,0x35d,0x363,0x35d,0x363,0x35d,0x363,0x35d,0x363,0x35d,
+0x363,0x35d,0x363,0x35d,0x363,0x35d,0x363,0x35d,0x363,0x35d,0x363,0x35d,0x363,0x35d,0x363,0x35d,
+0x363,0x35d,0x363,0x35d,0x363,0x366,0x360,0x363,0x35d,0xbbe,0xbbb,0x363,0x35d,0xbbe,0xbbb,0x363,
+0x35d,0xbbe,0xbbb,0xf03,0x366,0x360,0x366,0x360,0x363,0x35d,0x366,0x360,0x363,0x35d,0x366,0x360,
+0x366,0x360,0x366,0x360,0x363,0x35d,0x366,0x360,0x366,0x360,0x366,0x360,0x363,0x35d,0x366,0x360,
+0xa0b,0xa05,0x366,0x360,0x366,0x360,0x366,0x360,0x366,0x360,0xdc5,0xdc2,0x366,0x360,0xf06,0xf03,
+0xf06,0xf03,0xf06,0xf03,0xc2d,0xc2a,0xc2d,0xc2a,0xc2d,0xc2a,0xc2d,0xc2a,0xc2d,0xc2a,0xc2d,0xc2a,
+0xc2d,0xc2a,0xc2d,0xc2a,0xf33,0xf30,0xf33,0xf30,0x1023,0x1020,0x1023,0x1020,0x1023,0x1020,0x1023,0x1020,
+0x1023,0x1020,0x1023,0x1020,0x1023,0x1020,0x1023,0x1020,0x1188,0x1185,0x1371,0x136e,0x1536,0x1533,0x1536,0x1533,
+0x1536,0x1533,0x1536,0x1533,0xc,0x378,0x378,0x378,0x378,0x378,0x378,0x378,0x378,0x378,0x378,0x378,
+0x378,0x378,0x378,0x378,0x378,0x378,0x378,0x378,0x378,0x378,0x378,0x378,0x378,0x378,0x378,0xc,
+0xc,0x37b,0x369,0x369,0x369,0x36f,0x369,0x36c,0x1941,0x372,0x372,0x372,0x372,0x372,0x372,0x372,
+0x372,0x372,0x372,0x372,0x372,0x372,0x372,0x372,0x372,0x372,0x372,0x372,0x372,0x372,0x372,0x372,
+0x372,0x372,0x372,0x372,0x372,0x372,0x372,0x372,0x372,0x372,0x372,0x375,0x1941,0x37e,0xa0e,0xc,
+0xc,0x1500,0x1500,0x141c,0xf,0x97e,0x97e,0x97e,0x97e,0x97e,0x97e,0x97e,0x97e,0x97e,0x97e,0x97e,
+0x97e,0x97e,0x97e,0x97e,0x97e,0x97e,0xdc8,0x97e,0x97e,0x97e,0x97e,0x97e,0x97e,0x97e,0x97e,0x97e,
+0x97e,0x97e,0x97e,0x97e,0x381,0x381,0x381,0x381,0x381,0x381,0x381,0x381,0x381,0x381,0xf09,0x381,
+0x381,0x381,0x38d,0x381,0x384,0x381,0x381,0x390,0x981,0xdcb,0xdce,0xdcb,0xf,0xf,0xf,0xf,
+0xf,0xf,0xf,0xf,0x393,0x393,0x393,0x393,0x393,0x393,0x393,0x393,0x393,0x393,0x393,0x393,
+0x393,0x393,0x393,0x393,0x393,0x393,0x393,0x393,0x393,0x393,0x393,0x393,0x393,0x393,0x393,0xf,
+0xf,0xf,0xf,0x1944,0x393,0x393,0x393,0x38a,0x387,0xf,0xf,0xf,0xf,0xf,0xf,0xf,
+0xf,0xf,0xf,0xf,0xcdb,0xcdb,0xcdb,0xcdb,0x141f,0x1503,0xfb1,0xfb1,0xfb1,0xfae,0xfae,0xdd4,
+0x8c7,0xcd5,0xcd2,0xcd2,0xcc9,0xcc9,0xcc9,0xcc9,0xcc9,0xcc9,0xfab,0xfab,0xfab,0xfab,0xfab,0x8c4,
+0x14fa,0x12,0xdd7,0x8ca,0x1338,0x3ae,0x3b1,0x3b1,0x3b1,0x3b1,0x3b1,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,
+0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0xfb4,
+0xfb4,0xfb4,0xfb4,0xfb4,0x8cd,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x942,
+0x942,0x942,0x942,0x942,0x942,0x942,0x942,0xb5e,0xb5e,0xb5e,0xcc9,0xccf,0xccc,0xdd1,0xdd1,0xdd1,
+0xdd1,0xdd1,0xdd1,0x1335,0x960,0x960,0x960,0x960,0x960,0x960,0x960,0x960,0x960,0x960,0x3a8,0x3a5,
+0x3a2,0x39f,0xbc1,0xbc1,0x93f,0x3ae,0x3ae,0x3ba,0x3ae,0x3b4,0x3b4,0x3b4,0x3b4,0x3ae,0x3ae,0x3ae,
+0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,
+0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,
+0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,
+0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0xa14,0xa14,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0xa14,
+0x3b1,0x3ae,0x3b1,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0xa14,
+0x3ae,0x3ae,0x3ae,0x3b1,0x95d,0x3ae,0x399,0x399,0x399,0x399,0x399,0x399,0x399,0x396,0x39f,0x39c,
+0x39c,0x399,0x399,0x399,0x399,0x3b7,0x3b7,0x399,0x399,0x39f,0x39c,0x39c,0x39c,0x399,0xcd8,0xcd8,
+0x3ab,0x3ab,0x3ab,0x3ab,0x3ab,0x3ab,0x3ab,0x3ab,0x3ab,0x3ab,0xa14,0xa14,0xa14,0xa11,0xa11,0xcd8,
+0xa29,0xa29,0xa29,0xa23,0xa23,0xa23,0xa23,0xa23,0xa23,0xa23,0xa23,0xa20,0xa23,0xa20,0x15,0xa2c,
+0xa26,0xa17,0xa26,0xa26,0xa26,0xa26,0xa26,0xa26,0xa26,0xa26,0xa26,0xa26,0xa26,0xa26,0xa26,0xa26,
+0xa26,0xa26,0xa26,0xa26,0xa26,0xa26,0xa26,0xa26,0xa26,0xa26,0xa26,0xa26,0xa26,0xcde,0xcde,0xcde,
 0xa1d,0xa1d,0xa1d,0xa1d,0xa1d,0xa1d,0xa1d,0xa1d,0xa1d,0xa1d,0xa1d,0xa1d,0xa1d,0xa1d,0xa1d,0xa1d,
-0xa1d,0xa1d,0xa1d,0xa1d,0xa1d,0xa1d,0xa1d,0xa1d,0xa41,0xa41,0xa41,0xa44,0xa44,0xa41,0xa41,0xa41,
-0xa41,0xa41,0xa41,0xa41,0xa41,0xa41,0xa41,0xa41,0xa41,0xa41,0xa41,0xa41,0xa29,0xa29,0xa3e,0xa20,
-0xa20,0xa20,0xa20,0xa20,0xa20,0xa20,0xa3e,0xa3e,0xa41,0xa41,0xa41,0xa41,0xa41,0xa41,0xa41,0xa41,
-0xa41,0xa41,0xa41,0xa41,0xa41,0xa41,0xa41,0xa41,0xa41,0xa41,0xa41,0xa41,0xa41,0xa41,0xa41,0xa41,
-0xa41,0xa41,0xa41,0xa41,0xa41,0xa41,0xa41,0xa41,0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,
-0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,
-0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,0xa62,0xa5f,0xa5f,0xa5f,0xa5f,
-0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,
-0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,0xa89,0xa89,0xa89,0xa89,0xa89,0xa89,0xa89,0xa89,
-0xa89,0xa89,0xa89,0xa89,0xa89,0xa89,0xa89,0xa89,0xa89,0xa89,0xa89,0xa89,0xa89,0xa89,0xa89,0xa89,
-0xa89,0xa89,0xa89,0xb7c,0xb7c,0xb7c,0xb7c,0xb7c,0xa95,0xa95,0xa95,0xa95,0xa95,0xa95,0xa95,0xa95,
-0xa95,0xa95,0xa95,0xa95,0xa95,0xa95,0xa95,0xa95,0xa95,0xa95,0xa95,0xa95,0xa95,0xa95,0xa95,0xa95,
-0xa95,0xa95,0xa95,0xa95,0xa95,0xa95,0xa95,0xa95,0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,
-0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,
-0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,0xaad,0xaad,0xaad,0xaad,0xaad,0xaad,0xaad,0xaad,
-0xaad,0xaad,0xaad,0xaad,0xaad,0xaad,0xaad,0xaad,0xaad,0xaad,0xaad,0xaad,0xaad,0xaad,0xaad,0xaad,
-0xaad,0xaad,0xaad,0xaad,0xaad,0xaad,0xaad,0xaad,0xabc,0xabc,0xabc,0xabc,0xabc,0xabc,0xabc,0xabc,
-0xabc,0xabc,0xabc,0xabc,0xabc,0xabc,0xabc,0xabc,0xabc,0xabc,0xabc,0xabc,0xabc,0xabc,0xabc,0xabc,
-0xabc,0xabc,0xabc,0xabc,0xabc,0xabc,0xabc,0xabc,0xabf,0xabf,0xabf,0xabf,0xabf,0xabf,0xabf,0xabf,
-0xabf,0xabf,0xabf,0xabf,0xabf,0xabf,0xabf,0xabf,0xabf,0xabf,0xabf,0xabf,0xabf,0xac2,0xabf,0xabf,
-0xabf,0xabf,0xabf,0xabf,0xabf,0xabf,0xabf,0xabf,0xabf,0xabf,0xabf,0xabf,0xabf,0xabf,0xabf,0xabf,
-0xabf,0xabf,0xabf,0xabf,0xabf,0xabf,0xabf,0xabf,0xabf,0xabf,0xabf,0xabf,0xabf,0xabf,0xabf,0xabf,
-0xac5,0xac5,0xc0c,0xc0c,0xac5,0xac5,0xac5,0xac5,0xac5,0xac5,0xac5,0xac5,0xac5,0xac5,0xac5,0xac5,
-0xac5,0xac5,0xac5,0xac5,0xc0c,0xac5,0xac5,0xac5,0xac5,0xac5,0xac5,0xac5,0xac5,0xac5,0xac5,0xac5,
-0xae6,0xae6,0xae6,0xae6,0xae6,0xae6,0xae6,0xae6,0xae6,0xae6,0xae6,0xae6,0xae6,0xae6,0xae6,0xae6,
-0xae6,0xae6,0xae6,0xae6,0xae6,0xae6,0xae6,0xae6,0xae6,0xae6,0xae6,0xae6,0xae6,0xae6,0xae6,0x1485,
-0xaef,0xaef,0xaef,0xaef,0xaef,0xaef,0xc96,0xc96,0xaec,0xaec,0xaec,0xaec,0xaec,0xaec,0xaec,0xaec,
-0xaec,0xaec,0xaec,0xaec,0xaec,0xaec,0xaec,0xaec,0xaec,0xaec,0xaec,0xaec,0xaec,0xaec,0xaec,0xaec,
-0xaec,0xaec,0xc93,0xc93,0xce4,0xce4,0xce4,0xce4,0xce4,0xce4,0xce4,0xce4,0xce4,0xce4,0xce4,0xce4,
-0xce4,0xce4,0xce4,0xce4,0xaef,0xaef,0xaef,0xaef,0xaef,0xaef,0xaef,0xaef,0xaef,0xaef,0xaef,0xaef,
-0xaef,0xaef,0xaef,0xaef,0xaef,0xaef,0xaef,0xaef,0xaef,0xaef,0xaef,0xaef,0xaef,0xaef,0xaef,0xaef,
-0xaef,0xaef,0xaef,0xaef,0xaf2,0xaf2,0xaf2,0xaf2,0xaf2,0xaf2,0xaf2,0xaf2,0xaf2,0xaf2,0xaf2,0xaf2,
-0xaf2,0xaf2,0xaf2,0xaf2,0xaf2,0xaf2,0xaf2,0xaf2,0xaf2,0xaf2,0xaf2,0xaf2,0xaf2,0xaf2,0xaf2,0xaf2,
-0xaf2,0xaf2,0xaf2,0xaf2,0xb01,0xb01,0xb01,0xb01,0xb01,0xaf8,0xb04,0xb0a,0xb0a,0xb0a,0xafe,0xafe,
-0xafe,0xb07,0xafb,0xafb,0xafb,0xafb,0xafb,0xaf5,0xaf5,0xaf5,0xaf5,0xaf5,0xaf5,0xaf5,0xaf5,0xb0a,
-0xb0a,0xb0a,0xb0a,0xb0a,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,
-0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,
-0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xb01,0xb01,0xb0a,0xb0a,0xb0a,0xafe,0xafe,0xb0a,0xb0a,0xb0a,
-0xb0a,0xb0a,0xb0a,0xb0a,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,
-0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xb0a,0xb0a,0xb0a,0xb0a,0xafe,0xafe,
-0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xb01,0xb01,0xb01,0xb01,0xb01,
-0xb01,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,
-0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0xafe,0x1683,0x1683,
-0xb16,0xb0d,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,
-0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb0d,0xb13,0xb13,0xb13,0xb13,
-0xb13,0xb13,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,
-0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb0d,0xb13,0xb13,0xb13,0xb13,
-0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,
-0xb13,0xb0d,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,
-0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb0d,0xb13,0xb13,
-0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,
-0xb13,0xb13,0xb13,0xb13,0xb10,0xb10,0xb10,0xb10,0xb10,0xb10,0xb10,0xb10,0xb10,0xb10,0xb10,0xb10,
-0xb10,0xb10,0xb10,0xb10,0xb10,0xb10,0xb10,0xb10,0xb10,0xb10,0xb10,0xb10,0xb10,0xb10,0xb10,0xb10,
-0xb10,0xb10,0xb10,0xb10,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,
-0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb13,0xb13,
-0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,
-0xb13,0xb13,0xb13,0xb13,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,
-0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb16,0xb13,0xb13,
-0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,
-0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb13,0xb16,0xb16,0xb16,0xb16,0xb19,0xb19,0xb19,0xb19,
-0xb19,0xb19,0xb19,0xb19,0xb19,0xb19,0xb19,0xb19,0xb19,0xb19,0xb19,0xb19,0xb19,0xb19,0xb19,0xb19,
-0xb19,0xb19,0xb19,0xb19,0xb19,0xb19,0xb19,0xb19,0xb19,0xb19,0xb19,0xb19,0xb19,0xb19,0xb19,0xb1c,
-0xb1f,0xb1f,0xb1f,0xb1f,0xb1f,0xb1f,0xb1f,0xb1f,0xb1f,0xb1f,0xb1f,0xb1f,0xb1f,0xb1f,0xb1f,0xb1f,
-0xb1f,0xb1f,0xb1f,0xb1f,0xb1f,0xb1f,0xb1f,0xb1f,0xb1f,0xb1f,0xb1f,0xb1f,0xb1f,0xb1f,0xb1f,0xb1f,
-0xb22,0xb22,0xb22,0xb22,0xb22,0xb22,0xb22,0xb22,0xb22,0xb22,0xb22,0xb22,0xb22,0xb22,0xb22,0xb22,
-0xb22,0xb22,0xb22,0xb22,0xb22,0xb22,0xb22,0xb22,0xb22,0xb22,0xb22,0xb22,0xb22,0xb22,0xb22,0xb22,
-0xb7c,0xb7c,0xb7c,0xb7c,0xb7c,0xb7c,0xb7c,0xb7c,0xb7c,0xb7c,0xb7c,0xb7c,0xb7c,0xb7c,0xb7c,0xb7c,
-0xb7c,0xb7c,0xb7c,0xb7c,0xb7c,0xb7c,0xb79,0xb7c,0xb79,0xb79,0xb79,0xb79,0xb79,0xb79,0xb79,0xb79,
-0xb79,0xb79,0xb79,0xb79,0xb79,0xb79,0xb79,0xc84,0xc87,0xd71,0xd71,0xd71,0xd71,0xd71,0xd71,0xd71,
-0xd71,0xd71,0xd71,0xd71,0xe8b,0xe8b,0xe8b,0xe8b,0xb8e,0xb8e,0xb8e,0xb8e,0xb8e,0xb8e,0xb8e,0xb8e,
-0xb8e,0xb8e,0xc8a,0xc8a,0xc8a,0xc8a,0xc8a,0xc8a,0xc8a,0xc8a,0xd77,0xd7d,0xd77,0xd74,0xd77,0xd77,
-0xd74,0xd77,0xd74,0xd77,0xd77,0xf7e,0x1218,0x1218,0xd86,0xd86,0xd86,0xd86,0xd86,0xd8c,0xd89,0xe9d,
-0xe9d,0xe9d,0xe9d,0x1383,0xf90,0x1383,0x12d8,0x12d8,0xbc4,0xbc4,0xbc4,0xbc4,0xbc4,0xbc4,0xbc4,0xbc4,
-0xbc4,0xbc4,0xbc4,0xbc4,0xbc4,0xbc4,0xbc4,0xbc4,0xbc4,0xbc4,0xbf4,0xbf1,0xbf4,0xbf1,0xbf4,0xbf1,
-0x10a7,0x10a4,0xf96,0xf93,0xbc7,0xbc7,0xbc7,0xbc7,0xbc7,0xbc7,0xbc7,0xbc7,0xbc7,0xbc7,0xbc7,0xbc7,
-0xbc7,0xbc7,0xbc7,0xbc7,0xbca,0xbca,0xbca,0xbca,0xbca,0xbca,0xbca,0xbca,0xbca,0xbca,0xbca,0xbca,
-0xbca,0xbca,0xbca,0xbca,0xbca,0xbca,0xbca,0xbca,0xbca,0xbca,0xbca,0xbca,0xbca,0xbca,0xbca,0xbca,
-0xbca,0xbca,0xbca,0xbca,0xbcd,0xbcd,0xbca,0xbca,0xbca,0xbca,0xbca,0xbca,0xbca,0xbca,0xbca,0xbca,
-0xbd0,0xbd0,0xbd0,0xbd6,0xbd3,0xbfa,0xbf7,0xbd6,0xbd3,0xbd6,0xbd3,0xbd6,0xbd3,0xbd6,0xbd3,0xbd6,
-0xbd3,0xbd6,0xbd3,0xbd6,0xbd3,0xbd6,0xbd3,0xbd6,0xbd3,0xbd0,0xbd0,0xbd0,0xbd0,0xbd0,0xbd0,0xbd0,
-0xbd0,0xbd0,0xbd0,0xbd0,0xbd0,0xbd0,0xbd0,0xbd0,0xbd0,0xbd0,0xbd0,0xbd0,0xbd0,0xbd0,0xbd0,0xbd0,
-0xbd0,0xbd0,0xbd0,0xbd0,0xbd0,0xbd0,0xbd0,0xbd0,0xbd0,0xbd0,0xbd0,0xbd0,0xbd6,0xbd3,0xbd6,0xbd3,
-0xbd0,0xbd0,0xbd0,0xbd0,0xbd0,0xbd0,0xbd0,0xbd0,0xbd0,0xbd0,0xbd0,0xbd0,0xbd0,0xbd0,0xbd0,0xbd0,
-0xbd0,0xbd0,0xbd0,0xbd0,0xbd0,0xbd0,0xbd0,0xbd0,0xbd0,0xbd0,0xbd0,0xbd0,0xbd6,0xbd3,0xbd0,0xbd0,
-0xbd9,0xbd9,0xbd9,0xbd9,0xbd9,0xbd9,0xbd9,0xbd9,0xbd9,0xbd9,0xbd9,0xbd9,0xbdf,0xbd9,0xbd9,0xbd9,
-0xbd9,0xbd9,0xbd9,0xbd9,0xbd9,0xbd9,0xbd9,0xbd9,0xbd9,0xbd9,0xbd9,0xbd9,0xbd9,0xbd9,0xbd9,0xbd9,
-0xbd9,0xbd9,0xbd9,0xbd9,0xbd9,0xbd9,0xbd9,0xbd9,0xbd9,0xbd9,0xbd9,0xbd9,0xbd9,0xbd9,0xbd9,0xbd9,
-0xbdf,0xbdf,0xbdf,0xbd9,0xbd9,0xbd9,0xbd9,0xbd9,0xbd9,0xbd9,0xbd9,0xbd9,0xbd9,0xbd9,0xbd9,0xbd9,
-0xbd9,0xbd9,0xbd9,0xbd9,0xbd9,0xbd9,0xbd9,0xbd9,0xbd9,0xbd9,0xbd9,0xbd9,0xbd9,0xbd9,0xbd9,0xbd9,
-0xbdc,0xbd9,0xbd9,0xbd9,0xc0f,0xc0f,0xc0f,0xc0f,0xc0f,0xc0f,0xc0f,0xc0f,0xc0f,0xc0f,0xc0f,0xc0f,
-0xc0f,0xc0f,0xc0f,0xc0f,0xc0f,0xc0f,0xc0f,0xc0f,0xc0f,0xc0f,0xc0f,0xc0f,0xc0f,0xc0f,0xc0f,0xc0f,
-0xc0f,0xc0f,0xc0f,0xc0f,0xc8d,0xc90,0xd74,0xd74,0xd74,0xd74,0xd74,0xd74,0xd74,0xd74,0xd7d,0xd7d,
-0xd74,0xd74,0xd74,0xd74,0xd77,0xd77,0xe8e,0xf7e,0xf7e,0xf7e,0xf7e,0xf7e,0xf7e,0xf7e,0xf7e,0xf7e,
-0xf7e,0x10ef,0x1224,0x121b,0xcb4,0xcb4,0xcb4,0xcb4,0xcb4,0xcb4,0xcb4,0xcb4,0xcb4,0xcb4,0xcb4,0xcb4,
-0xcb4,0xcb4,0xcb4,0xcb4,0xcb4,0xcb4,0xcb4,0xcb4,0xcb4,0xcb4,0xcb4,0xcb4,0xcb4,0xcb4,0xcb4,0xcb4,
-0xcb4,0xcb4,0xcb4,0xcb4,0xcc3,0xcc3,0xcc3,0xcc3,0xcc3,0xcc3,0xcba,0xcba,0xcba,0xcba,0xcba,0xcb7,
-0xccc,0xccc,0xccc,0xcc6,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xcc6,
-0xccc,0xccc,0xccc,0xccc,0xcc0,0xcc0,0xcc9,0xcc9,0xcc9,0xcc9,0xcbd,0xcbd,0xcbd,0xcbd,0xcbd,0xcc3,
-0xd92,0xd92,0xd92,0xd92,0xd92,0xd92,0xd92,0xd92,0xd92,0xd92,0xd92,0xd92,0xd8f,0xd92,0xd92,0xd92,
-0xd92,0xd92,0xd92,0xd92,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,
-0xccc,0xccc,0xcc6,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,
-0xccc,0xcc0,0xcc0,0xcc0,0xcc3,0xcc3,0xcc3,0xcc3,0xcc3,0xcc3,0xcc3,0xcc3,0xcc3,0xcc3,0xcc3,0xcc3,
-0xcc3,0xcc3,0xcc3,0xcc3,0xcc3,0xcc3,0xcc3,0xcc3,0xcc3,0xcc3,0xcc3,0xcc3,0xcc3,0xcc3,0xcc3,0xcc3,
-0xcc3,0xcc3,0xcc3,0xcc3,0xccf,0xccf,0xccf,0xccf,0xccf,0xcd2,0xcd2,0xcd2,0xccf,0xccf,0xccf,0xccf,
-0xccf,0xccf,0xd95,0xd95,0xd95,0xd95,0xd95,0xd95,0xea0,0xea0,0xea0,0xea0,0xea0,0xea0,0xea0,0xf9c,
-0xf9c,0xf99,0xf99,0xf99,0xcd5,0xcd5,0xcd5,0xcd5,0xcd5,0xcd5,0xcd5,0xcd5,0xcd5,0xcd5,0xcd5,0xcd5,
-0xcd5,0xcd5,0xcd5,0xcd5,0xcd5,0xcd5,0xcd5,0xcd5,0xcd5,0xcd5,0xcd5,0xcd5,0xcd5,0xcd5,0xcd5,0xcd5,
-0xcd5,0xcd5,0xcd5,0xcd5,0xcdb,0xcdb,0xcdb,0xcdb,0xcdb,0xcdb,0xcdb,0xcdb,0xcdb,0xcdb,0xcdb,0xcdb,
-0xcdb,0xcdb,0xcdb,0xcdb,0xcdb,0xcdb,0xcdb,0xcdb,0xcdb,0xcdb,0xcdb,0xcdb,0xcdb,0xcdb,0xcdb,0xcdb,
-0xcdb,0xcdb,0xcdb,0xcdb,0xce4,0xce4,0xce4,0xce4,0xce4,0xce4,0xce4,0xce4,0xce4,0xce4,0xce4,0xce4,
-0xce4,0xce4,0xce4,0xce4,0xce4,0xce4,0xce4,0xce4,0xce4,0xce4,0xce4,0xce4,0xce4,0xce4,0xce4,0xce4,
-0xce4,0xce4,0xce4,0xce4,0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,
-0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,
-0xcf0,0xcf0,0xcf0,0xcf0,0xcff,0xcff,0xcff,0xcff,0xcff,0xcff,0xcff,0xcff,0xcff,0xcff,0xcff,0xcff,
-0xcff,0xcff,0xcff,0xcff,0xcff,0xcff,0xcff,0xcff,0xcff,0xcff,0xcff,0xcff,0xcff,0xcff,0xcff,0xcff,
-0xcff,0xcff,0xcff,0xcff,0xd9b,0xd9b,0xd9b,0xd9b,0xd9b,0xd9b,0xd9b,0xd9b,0xd9b,0xd9b,0xd9b,0xd9b,
-0xd9b,0xd9b,0xd9b,0xd9b,0xd9b,0xd9b,0xd9b,0xd9b,0xd9b,0xd9b,0xd9b,0xd9b,0xd9b,0xd9b,0xd9b,0xd9b,
-0xd9b,0xd9b,0xd9b,0xd9b,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,
-0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xd9e,0xd9e,0xd9e,0xd9e,0xd9e,0xd9e,0xd9e,
-0xd9e,0xd9e,0xd9e,0xd9e,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,
-0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,0xda1,
-0xda1,0xda1,0xda1,0xda1,0xe5b,0xe5b,0xdb3,0xdb3,0xea3,0xea3,0xea3,0xea3,0xea3,0xea3,0xea3,0xfa8,
-0xfa8,0xfa8,0xfa8,0xfa8,0xfa5,0xfa5,0xfa5,0xfa5,0xfa5,0xfa5,0xfa5,0xfa5,0xfa5,0xfa5,0xfa5,0xfa5,
-0xfa5,0xfa5,0xfa5,0xfa5,0xdc2,0xdbf,0xdc2,0xdbf,0xdc2,0xdbf,0xdc2,0xdbf,0xdc2,0xdbf,0xdc2,0xdbf,
-0xdc2,0xdbf,0xdc2,0xdbf,0xdc2,0xdbf,0xdc2,0xdbf,0xdc2,0xdbf,0xdc2,0xdbf,0xdc2,0xdbf,0xdc2,0xdbf,
-0xdc2,0xdbf,0xdc2,0xdbf,0xdce,0xdce,0xdce,0xdce,0xdce,0xdce,0xdce,0xdce,0xdce,0xdce,0xdce,0xdce,
-0xdce,0xdce,0xdce,0xdce,0xdce,0xdce,0xdce,0xdce,0xdce,0xdce,0xdce,0xdce,0xdce,0xdce,0xdce,0xdce,
-0xdce,0xdce,0xdce,0xdce,0xdd4,0xdd4,0xdd4,0xdd4,0xdd4,0xdd4,0xdd4,0xdd4,0xdd4,0xdd4,0xdd4,0xdd4,
-0xdd4,0xdd4,0xdd4,0xdd4,0xdd4,0xdd4,0xdd4,0xdd4,0xdd4,0xdd4,0xdd4,0xdd4,0xdd4,0xdd4,0xdd4,0xdd4,
-0xdd4,0xdd4,0xdd4,0xdd4,0xdec,0xdec,0xdec,0xdec,0xdec,0xdec,0xdec,0xdec,0xdec,0xdec,0xdec,0xdec,
-0xdec,0xdec,0xdec,0xdec,0xdec,0xdec,0xdec,0xdec,0xdec,0xdec,0xdec,0xea6,0xea6,0xea6,0xea6,0xfab,
-0xfab,0xfab,0xfab,0xfab,0xdf5,0xdf5,0xdf5,0xdf5,0xdf5,0xdf5,0xdf5,0xdf5,0xdf5,0xdf5,0xdf5,0xdf5,
-0xdf5,0xdf5,0xdf5,0xdf5,0xdf5,0xdf5,0xdf5,0xdf5,0xdf5,0xdf5,0xdf5,0xdf5,0xdf5,0xdf5,0xdf5,0xdf5,
-0xdf5,0xdf5,0xdf5,0xdf5,0xdfe,0xdfe,0xdfe,0xdfe,0xdfe,0xdfe,0xdfe,0xdfe,0xdfe,0xdfe,0xdfe,0xdfe,
-0xdfe,0xdfe,0xdfe,0xdfe,0xdfe,0xdfe,0xdfe,0xdfe,0xdfe,0xdfe,0xdfe,0xdfe,0xdfe,0xdfe,0xdfe,0xdfe,
-0xdfe,0xdfe,0xdfe,0xdfe,0xe07,0xe07,0xe07,0xe07,0xe07,0xe07,0xe07,0xe07,0xe07,0xe07,0xe07,0xe07,
-0xe07,0xe07,0xe07,0xe07,0xe07,0xe07,0xe07,0xe07,0xe07,0xe07,0xe07,0xe07,0xe07,0xe07,0xe07,0xe07,
-0xe07,0xe07,0xe07,0xe01,0xe04,0xe04,0xe04,0xe04,0xe04,0xe04,0xe04,0xe04,0xe04,0xe04,0xe04,0xe04,
-0xe04,0xe04,0xe04,0xe04,0xe04,0xe04,0xe04,0xe04,0xe04,0xe04,0xe04,0xe04,0xe04,0xe04,0xe04,0xe07,
-0xe07,0xe07,0xe07,0xe07,0xe10,0xe10,0xe10,0xe10,0xe10,0xe10,0xe10,0xe10,0xe10,0xe10,0xe10,0xe10,
-0xe10,0xe10,0xe0d,0xe0d,0xe0d,0xe0d,0xe0d,0xe0d,0xe0d,0xe0d,0xe0a,0xe13,0xfb7,0xfb1,0xfc0,0xfae,
-0xe10,0xe10,0xfae,0xfae,0xe25,0xe25,0xe16,0xe25,0xe25,0xe25,0xe1c,0xe25,0xe25,0xe25,0xe25,0xe16,
-0xe25,0xe25,0xe25,0xe25,0xe25,0xe25,0xe25,0xe25,0xe25,0xe25,0xe25,0xe25,0xe25,0xe25,0xe25,0xe25,
-0xe25,0xe25,0xe25,0xe25,0xe28,0xe28,0xe28,0xe28,0xe28,0xe28,0xe28,0xe28,0xe28,0xe28,0xe28,0xe28,
-0xe28,0xe28,0xe28,0xe28,0xe28,0xe28,0xe28,0xe28,0xe28,0xe28,0xe28,0xe28,0xe28,0xe28,0xe28,0xe28,
-0xe28,0xe28,0xe28,0xe28,0xe3a,0xe3a,0xe3a,0xe3a,0xe3a,0xe3a,0xe3a,0xe3a,0xe3a,0xe3a,0xe3a,0xe3a,
-0xe3a,0xe3a,0xe3a,0xe3a,0xe3a,0xe3a,0xe3a,0xe3a,0xe3a,0xe3a,0xe3a,0xe3a,0xe3a,0xe3a,0xe3a,0xe3a,
-0xe3a,0xe3a,0xe3a,0xe3a,0xe58,0xe58,0xe58,0xe58,0xe58,0xe58,0xe58,0xe58,0xe58,0xe58,0xe58,0xe58,
-0xe58,0xe58,0xe58,0xe58,0x10b3,0x10b3,0x10b3,0x10b3,0x10b3,0x10b3,0x10b3,0x10b3,0x10b3,0x10b3,0x10b3,0x10b3,
-0x10b3,0x10b3,0x10b3,0x10b3,0xea0,0xea0,0xea0,0xea0,0xf99,0xf99,0xf99,0xf99,0xf99,0xf99,0xf99,0xf99,
-0xf99,0xf99,0xf99,0xf99,0xf9f,0xf9f,0xf9f,0xf9f,0xf9f,0xf9f,0xf9f,0xf9f,0xf9f,0xf9f,0xf9f,0xf9f,
-0xf9f,0xf9f,0xf9f,0xf9f,0xec1,0xec1,0xec1,0xec1,0xed3,0xedc,0xedf,0xedc,0xedf,0xedc,0xedf,0xedc,
-0xedf,0xedc,0xedf,0xedc,0xedc,0xedc,0xedf,0xedc,0xedc,0xedc,0xedc,0xedc,0xedc,0xedc,0xedc,0xedc,
-0xedc,0xedc,0xedc,0xedc,0xedc,0xedc,0xedc,0xedc,0xedc,0xedc,0xedc,0xedc,0xec4,0xed3,0xec1,0xec1,
-0xec1,0xec1,0xec1,0xed6,0xec1,0xed6,0xed3,0xed3,0xee8,0xee5,0xee8,0xee8,0xee8,0xee5,0xee5,0xee8,
-0xee5,0xee8,0xee5,0xee8,0xee5,0xfd2,0xfd2,0xfd2,0x110d,0xfc9,0xfd2,0xfc9,0xee5,0xee8,0xee5,0xee5,
-0xfc9,0xfc9,0xfc9,0xfc9,0xfcc,0xfcf,0x110d,0x110d,0xeeb,0xeeb,0xfe4,0xfdb,0xfe4,0xfdb,0xfe4,0xfdb,
-0xfe4,0xfdb,0xfe4,0xfdb,0xfe4,0xfdb,0xfe4,0xfdb,0xfdb,0xfdb,0xfe4,0xfdb,0xfe4,0xfdb,0xfe4,0xfdb,
-0xfe4,0xfdb,0xfe4,0xfdb,0xfe4,0xfdb,0xfe4,0xfdb,0xef1,0xef1,0xef1,0xef1,0xef1,0xef1,0xef1,0xef1,
-0xef1,0xef1,0xef1,0xef1,0xef1,0xef1,0xef1,0xef1,0xef1,0xef1,0xef1,0xef1,0xef1,0xef1,0xef1,0xef1,
-0xef1,0xef1,0xef1,0xef1,0xef1,0xef1,0xef1,0xef1,0xf00,0xf00,0xf00,0xf00,0xf00,0xf00,0xf00,0xf00,
-0xf00,0xf00,0xf00,0xf00,0xf00,0xf00,0xf00,0xf00,0xf00,0xf00,0xf00,0xf00,0xf00,0xf00,0xf00,0xf00,
-0xf00,0xf00,0xf00,0xf00,0xf00,0xf00,0xf00,0xf00,0xf00,0xf00,0xf00,0x14b8,0x14b8,0x14b8,0x14b8,0x14b8,
-0x14b8,0x14b8,0x14b8,0x14b8,0x14b8,0x14b8,0x14b8,0x14b8,0x14b8,0x14b8,0x14b8,0x14b8,0xf06,0xf06,0xf06,0xf06,
-0xf06,0xf06,0xf06,0xf06,0xf06,0xf06,0xf06,0xf06,0xf06,0xf06,0xf06,0xf06,0xf06,0xf06,0xf06,0xf06,
-0xf06,0xf06,0xf06,0xf06,0xf06,0xf06,0xf06,0xf06,0xf06,0xf06,0xf06,0xf06,0xf4e,0xf69,0xf60,0xf5d,
-0xf5d,0xf69,0xf69,0xf60,0xf60,0xf5d,0xf5d,0xf5d,0xf5d,0xf5d,0xf69,0xf69,0xf69,0xf4e,0xf4e,0xf4e,
-0xf4e,0xf69,0xf69,0xf69,0xf69,0xf69,0xf69,0xf69,0xf69,0xf69,0xf69,0xf69,0xf69,0xf69,0xf4e,0xf60,
-0xf63,0xf4e,0xf4e,0xf66,0xf66,0xf66,0xf66,0xf66,0xf66,0xf51,0xf69,0xf66,0xf5a,0xf5a,0xf5a,0xf5a,
-0xf5a,0xf5a,0xf5a,0xf5a,0xf5a,0xf5a,0x10d4,0x10d4,0x10d1,0x10ce,0xf57,0xf57,0xf81,0xf81,0xf81,0xf81,
-0x1224,0x1224,0x121b,0x121b,0x1221,0x1218,0x1218,0x1218,0x1218,0x121b,0x12c3,0x1221,0x121b,0x1221,0x1218,0x1221,
-0x1224,0x1218,0x1218,0x1218,0x121b,0x121b,0x1218,0x1218,0x121b,0x1218,0x1218,0x121b,0xf9f,0xf9f,0xf9f,0xf9f,
-0xf9f,0xf99,0xf99,0xf9f,0xf9f,0xf9f,0xf9f,0xf9f,0xf9f,0x1491,0x1491,0x1491,0xf9c,0xf99,0xf99,0xf99,
-0xf99,0x1233,0x1230,0x1230,0x1230,0x1230,0x1491,0x1491,0x1491,0x1491,0x1491,0x1491,0xfbd,0xfbd,0xfba,0xfb4,
-0xfba,0xfb4,0xfba,0xfb4,0xfba,0xfb4,0xfb1,0xfb1,0xfb1,0xfb1,0xfc6,0xfc3,0xfb1,0x110a,0x138f,0x1392,
-0x1392,0x138f,0x138f,0x138f,0x138f,0x138f,0x1395,0x1395,0x14ac,0x14a0,0x14a0,0x149d,0xfe4,0xfdb,0xfe4,0xfdb,
-0xfe4,0xfdb,0xfe4,0xfdb,0xfd8,0xfd5,0xfd5,0xfe4,0xfdb,0x12e7,0x12e4,0x168c,0x12e7,0x12e4,0x139e,0x139b,
-0x14af,0x14af,0x14b5,0x14af,0x14b5,0x14af,0x14b5,0x14af,0x14b5,0x14af,0x14b5,0x14af,0xfe4,0xfdb,0xfe4,0xfdb,
-0xfe4,0xfdb,0xfe4,0xfdb,0xfe4,0xfdb,0xfe4,0xfdb,0xfe4,0xfdb,0xfe4,0xfdb,0xfe4,0xfdb,0xfe4,0xfdb,
-0xfe4,0xfdb,0xfe4,0xfdb,0xfe4,0xfdb,0xfe4,0xfdb,0xfe4,0xfdb,0xfe4,0xfdb,0xfde,0xfdb,0xfdb,0xfdb,
-0xfdb,0xfdb,0xfdb,0xfdb,0xfdb,0xfe4,0xfdb,0xfe4,0xfdb,0xfe4,0xfe4,0xfdb,0xfe7,0xfe7,0xfed,0xff3,
-0xff3,0xff3,0xff3,0xff3,0xff3,0xff3,0xff3,0xff3,0xff3,0xff3,0xff3,0xff3,0xff3,0xff3,0xff3,0xff3,
-0xff3,0xff3,0xff3,0xff3,0xff3,0xff3,0xff3,0xff3,0xff3,0xff3,0xff3,0xff3,0xff3,0xfed,0xfe7,0xfe7,
-0xfe7,0xfe7,0xfed,0xfed,0xfe7,0xfe7,0xff0,0x13a7,0x13a4,0x13a4,0xff3,0xff3,0xfea,0xfea,0xfea,0xfea,
-0xfea,0xfea,0xfea,0xfea,0xfea,0xfea,0x13aa,0x13aa,0x13aa,0x13aa,0x13aa,0x13aa,0x1008,0x1008,0x1008,0x1008,
-0x1008,0x1008,0x1008,0x1008,0x1008,0x1008,0x1008,0x1008,0x1008,0x1008,0x1008,0x1008,0x1008,0x1008,0x1008,0x1008,
-0x1008,0x1008,0x1008,0x1008,0x1008,0x1008,0x1008,0x1008,0x1008,0x1008,0x1008,0x1008,0x1011,0x1011,0x1011,0x1011,
-0x1011,0x1011,0x1011,0x1011,0x1011,0x1011,0x1011,0x1011,0x1011,0x1011,0x1011,0x1011,0x1011,0x1011,0x1011,0x1011,
-0x1011,0x1011,0x1011,0x1011,0x1014,0x1014,0x1014,0x1017,0x1014,0x1014,0x101a,0x101a,0x101d,0x101d,0x101d,0x101d,
-0x101d,0x101d,0x101d,0x101d,0x101d,0x101d,0x101d,0x101d,0x101d,0x101d,0x101d,0x101d,0x101d,0x101d,0x101d,0x101d,
-0x101d,0x101d,0x101d,0x101d,0x101d,0x101d,0x101d,0x101d,0x101d,0x101d,0x101d,0x101d,0x1026,0x1026,0x1026,0x1026,
-0x1026,0x1026,0x1026,0x1026,0x1026,0x1026,0x1026,0x1026,0x1029,0x1020,0x102f,0x102c,0x1026,0x1026,0x1026,0x1026,
-0x1026,0x1026,0x1026,0x1026,0x1026,0x1026,0x1026,0x1026,0x1026,0x1026,0x1026,0x1026,0x1026,0x1026,0x1026,0x1026,
-0x1026,0x1026,0x1026,0x1026,0x1026,0x1026,0x1026,0x1026,0x1026,0x1026,0x1026,0x1026,0x12ed,0x12ea,0x1041,0x103b,
-0x1041,0x103b,0x1041,0x103b,0x1041,0x103b,0x1041,0x103b,0x1041,0x103b,0x103e,0x10bc,0x1032,0x1032,0x1032,0x1038,
-0x13ad,0x13ad,0x13ad,0x13ad,0x13ad,0x13ad,0x13ad,0x13ad,0x1035,0x1035,0x1038,0x1044,0x1041,0x103b,0x1041,0x103b,
-0x1041,0x103b,0x1041,0x103b,0x1041,0x103b,0x1041,0x103b,0x1041,0x103b,0x1041,0x103b,0x1041,0x103b,0x1041,0x103b,
-0x1041,0x103b,0x1041,0x103b,0x1041,0x103b,0x1041,0x103b,0x1041,0x103b,0x1041,0x103b,0x14c4,0x14c1,0x14c4,0x14c1,
-0x14c7,0x14c7,0x1695,0x13ad,0x104d,0x104d,0x1050,0x1050,0x1050,0x1050,0x1050,0x1050,0x1050,0x1050,0x1050,0x1050,
-0x1050,0x1050,0x1050,0x1050,0x1050,0x1050,0x1050,0x1050,0x1050,0x1050,0x1050,0x1050,0x1050,0x1050,0x1050,0x1050,
-0x1050,0x1050,0x1050,0x1050,0x104d,0x104d,0x104d,0x104d,0x104d,0x104d,0x104d,0x104d,0x104d,0x104d,0x104d,0x104d,
-0x105f,0x105f,0x105f,0x105f,0x105f,0x105f,0x1056,0x1056,0x1056,0x1056,0x1056,0x1059,0x1059,0x1059,0x10b0,0x1062,
-0x1071,0x1071,0x1071,0x1071,0x1071,0x1071,0x1071,0x1071,0x1071,0x1071,0x1071,0x1071,0x1071,0x1071,0x1071,0x1071,
-0x105c,0x105c,0x105c,0x105c,0x105c,0x105c,0x105c,0x105c,0x105c,0x105c,0x105f,0x105f,0x105f,0x105f,0x105f,0x105f,
-0x105f,0x105f,0x105f,0x105f,0x105f,0x105f,0x105f,0x105f,0x105f,0x105f,0x105f,0x105f,0x105f,0x105f,0x105f,0x105f,
-0x1080,0x1080,0x1080,0x1080,0x1080,0x1080,0x1080,0x1080,0x1080,0x1080,0x1080,0x1080,0x1080,0x1080,0x1080,0x1080,
-0x1080,0x1080,0x1080,0x1080,0x1080,0x1080,0x1080,0x1080,0x1080,0x1080,0x1080,0x1080,0x1080,0x1080,0x1080,0x1080,
-0x1092,0x1092,0x1092,0x1092,0x1092,0x1092,0x1092,0x1092,0x1092,0x1092,0x1092,0x1092,0x1092,0x1092,0x1092,0x1092,
-0x1092,0x1092,0x1092,0x1092,0x1092,0x1092,0x1092,0x1092,0x1092,0x1092,0x1092,0x1092,0x1092,0x1092,0x1092,0x1092,
-0x109b,0x109b,0x109b,0x109b,0x109e,0x109b,0x109b,0x109b,0x109b,0x109b,0x109b,0x109b,0x109b,0x109b,0x109b,0x109b,
-0x109b,0x109b,0x109b,0x109b,0x109b,0x109b,0x109b,0x109b,0x109b,0x109b,0x109b,0x109b,0x109b,0x109b,0x109b,0x109b,
-0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,
-0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,
-0x111f,0x111f,0x111f,0x111f,0x111f,0x111f,0x111f,0x111f,0x111f,0x111f,0x111f,0x111f,0x111f,0x111f,0x111f,0x111f,
-0x111f,0x111f,0x111f,0x111f,0x111f,0x111f,0x1116,0x1116,0x1119,0x1119,0x111f,0x1116,0x1116,0x1116,0x1116,0x1116,
+0xa1a,0xa1a,0xa1a,0xa1a,0xa1a,0xa1a,0xa1a,0xa1a,0xa1a,0xa1a,0xa1a,0x15,0x15,0xcde,0xcde,0xcde,
+0xe37,0xe37,0xe37,0xe37,0xe37,0xe37,0xe37,0xe37,0xe37,0xe37,0xe37,0xe37,0xe37,0xe37,0xe37,0xe37,
+0xe37,0xe37,0xe37,0xe37,0xe37,0xe37,0xe37,0xe37,0xe37,0xe37,0xe37,0xe37,0xe37,0xe37,0x1035,0x1035,
+0x1035,0x1035,0x1035,0x1035,0x1035,0x1035,0x1035,0x1035,0x1035,0x1035,0x1035,0x1035,0x1035,0x1035,0x1035,0x1035,
+0xa32,0xa32,0xa32,0xa32,0xa32,0xa32,0xa32,0xa32,0xa32,0xa32,0xa32,0xa32,0xa32,0xa32,0xa32,0xa32,
+0xa32,0xa32,0xa32,0xa32,0xa32,0xa32,0xa32,0xa32,0xa32,0xa32,0xa32,0xa32,0xa32,0xa32,0xa32,0xa32,
+0xa32,0xa32,0xa32,0xa32,0xa32,0xa32,0xa2f,0xa2f,0xa2f,0xa2f,0xa2f,0xa2f,0xa2f,0xa2f,0xa2f,0xa2f,
+0xa2f,0xbc4,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+0xf4b,0xf4b,0xf4b,0xf4b,0xf4b,0xf4b,0xf4b,0xf4b,0xf4b,0xf4b,0xf4e,0xf4e,0xf4e,0xf4e,0xf4e,0xf4e,
+0xf4e,0xf4e,0xf4e,0xf4e,0xf4e,0xf4e,0xf4e,0xf4e,0xf4e,0xf4e,0xf4e,0xf4e,0xf4e,0xf4e,0xf4e,0xf4e,
+0xf4e,0xf4e,0xf4e,0xf4e,0xf4e,0xf4e,0xf4e,0xf4e,0xf4e,0xf4e,0xf4e,0xf42,0xf42,0xf42,0xf42,0xf42,
+0xf42,0xf42,0xf42,0xf42,0xf51,0xf51,0xf45,0xf45,0xf48,0xf57,0xf54,0x10b,0x10b,0x1968,0x196b,0x196b,
+0x18f9,0x18f9,0x18f9,0x18f9,0x18f9,0x18f9,0x18f9,0x18f9,0x18f9,0x18f9,0x18f9,0x252,0x252,0x252,0x252,0x252,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0xb37,0xb37,0xb3a,0xb3a,0xb37,0xb37,0xb37,0xb37,0xb37,0xb37,0xb37,0xb37,0x72,0x72,0x72,0x72,
+0x15ba,0x15ba,0x15ba,0x15ba,0x1bc,0x1bc,0x1bc,0x1bc,0x1bc,0x1bc,0x1bc,0x1bc,0x1bc,0x1bc,0x1bc,0x15b7,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0x1ef,0x1ef,0x1ef,0x1ef,0x1ef,0x1ef,0x1ef,0x1674,0x1674,0x1674,0x1674,0x1674,0x1674,0x1674,0x1674,0x1674,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0x1fb,0x1fb,0x1fb,0x1fb,0x1fb,0x1fb,0x1fb,0x1fb,0x1fb,0x16ad,0x16ad,0x16ad,0x16ad,0x16ad,0x16ad,0x16ad,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0x127b,0x127b,0x127b,0x127b,0x127b,0x127b,0x127b,0x127b,0x127b,0x174,0x174,0x174,0x174,0x174,0x174,0x174,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0x276,0x276,0x276,0x276,0x276,0x276,0x276,0x276,0x276,0x276,0x276,0x276,0x276,0x276,0x276,0x276,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0x1af7,0x1af7,0x1af7,0x1af7,0x1af7,0x1af7,0x1af7,0x1af7,0x1af7,0x1af7,0x1af7,0x1af7,0x1af7,0x1af7,0x1af7,0x1af7,
+0x1d1,0x1d1,0x1d1,0x1d1,0x1d1,0x1d1,0x1d1,0x1d1,0x1d1,0x1d1,0x1d1,0x1d1,0x1d1,0x1d1,0x1d1,0x1d1,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0x14d6,0x14d6,0x14d6,0x14d6,0x14d6,0x14d6,0x14d6,0x14d6,0x14d6,0x14d6,0x1b6,0x1b6,0x1b6,0x1b6,0x1b6,0x1b6,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0x25b,0x25b,0x25b,0x25b,0x25b,0x25b,0x25b,0x25b,0x25b,0x25b,0x25b,0x25b,0x25b,0x25b,0x25b,0x25b,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0x18e7,0x18ea,0x18ea,0x24f,0x24f,0x24f,0x24f,0x24f,0x24f,0x24f,0x24f,0x24f,0x24f,0x24f,0x24f,0x24f,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0x19b6,0x19b6,0x19b6,0x19b6,0x19b6,0x19b6,0x19b6,0x19b6,0x19b6,0x19b6,0x261,0x261,0x261,0x261,0x261,0x261,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0x1b1b,0x29d,0x29d,0x29d,0x29d,0x29d,0x29d,0x29d,0x29d,0x29d,0x29d,0x29d,0x29d,0x29d,0x29d,0x29d,
+0x17a9,0x17a9,0x17a9,0x17a9,0x216,0x216,0x216,0x216,0x216,0x216,0x216,0x216,0x216,0x216,0x216,0x216,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0x165f,0x165f,0x165f,0x165f,0x165f,0x165f,0x165f,0x165f,0x165f,0x165f,0x1e9,0x1e9,0x1e9,0x1e9,0x1665,0x1665,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0x15b1,0x15b1,0x15b1,0x15b1,0x15b1,0x15b1,0x15b1,0x15b1,0x15b1,0x15b1,0x15b1,0x15b1,0x15b1,0x15b1,0x15b1,0x15b1,
+0x169b,0x169b,0x169b,0x169b,0x169b,0x169b,0x169b,0x169b,0x169b,0x169b,0x169b,0x169b,0x169b,0x169b,0x169b,0x169b,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0x2a3,0x2a3,0x2a3,0x2a3,0x2a3,0x2a3,0x2a3,0x2a3,0x2a3,0x2a3,0x2a3,0x2a3,0x2a3,0x2a3,0x2a3,0x2a3,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0x1713,0x1713,0x1713,0x1713,0x1fe,0x1fe,0x1fe,0x1fe,0x1fe,0x1fe,0x1fe,0x1fe,0x1fe,0x1fe,0x1fe,0x1fe,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0xe2e,0xe2e,0xe2b,0xe2b,0xe2b,0xe2e,0xd8,0xd8,0xd8,0xd8,0xd8,0xd8,0xd8,0xd8,0xd8,0xd8,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0x225,0x17c1,0x17c1,0x17c1,0x17c1,0x17c1,0x17c1,0x17c1,0x17c1,0x17c1,0x17c1,0x17c1,0x17c1,0x17c1,0x17c1,0x17c1,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0x1845,0x1845,0x231,0x1845,0x1845,0x231,0x1845,0x1845,0x1845,0x1845,0x1845,0x231,0x231,0x231,0x231,0x231,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0x1a6d,0x1a6d,0x1a6d,0x1a6d,0x1a6d,0x1a6d,0x1a6d,0x1a6d,0x1a6d,0x1a6d,0x282,0x282,0x282,0x282,0x1a70,0x1a6a,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0x267,0x19cb,0x19cb,0x19cb,0x19cb,0x19cb,0x19cb,0x19cb,0x19cb,0x19cb,0x19cb,0x19cb,0x19cb,0x19cb,0x19cb,0x19cb,
+0x285,0x285,0x285,0x285,0x285,0x285,0x285,0x285,0x285,0x285,0x285,0x285,0x285,0x285,0x285,0x285,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x97b,0x97b,
+3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
+3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
+3,3,0x97b,0x97b,6,6,6,6,6,6,6,6,6,6,6,6,
+6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+6,6,6,6,0xd8c,0xd8c,0xd8c,0xd8c,0xd8c,0xd8c,0xd8c,0xd8c,0xd8c,0xd8c,0xd8c,0xd8c,
+0xd8c,0xd8c,0xd8c,0xd8c,6,6,6,6,6,6,6,6,6,6,6,6,
+6,6,6,6,0x1509,0x3d5,0x3e4,0x3e4,0x1b,0x3ea,0x3ea,0x3ea,0x3ea,0x3ea,0x3ea,0x3ea,
+0x3ea,0x1b,0x1b,0x3ea,0x3ea,0x1b,0x1b,0x3ea,0x3ea,0x3ea,0x3ea,0x3ea,0x3ea,0x3ea,0x3ea,0x3ea,
+0x3ea,0x3ea,0x3ea,0x3ea,0x3ea,0x1b,0x3ea,0x3ea,0x3ea,0x3ea,0x3ea,0x3ea,0x3ea,0x1b,0x3ea,0x1b,
+0x1b,0x1b,0x3ea,0x3ea,0x3ea,0x3ea,0x1b,0x1b,0x3d8,0xce4,0x3d5,0x3e4,0x3e4,0x3d5,0x3d5,0x3d5,
+0x3d5,0x1b,0x1b,0x3e4,0x3e4,0x1b,0x1b,0x3e7,0x3e7,0x3db,0xddd,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x3d5,0x1b,0x1b,0x1b,0x1b,0x3ed,0x3ed,0x1b,0x3ed,0x3ea,0x3ea,0x3d5,0x3d5,
+0x1b,0x1b,0x966,0x966,0x966,0x966,0x966,0x966,0x966,0x966,0x966,0x966,0x3ea,0x3ea,0x3e1,0x3e1,
+0x3de,0x3de,0x3de,0x3de,0x3de,0x3e1,0x3de,0x115e,0x18a2,0x189f,0x1947,0x1b,0x1e,0xce7,0x3f0,0xcea,
+0x1e,0x3fc,0x3fc,0x3fc,0x3fc,0x3fc,0x3fc,0x1e,0x1e,0x1e,0x1e,0x3fc,0x3fc,0x1e,0x1e,0x3fc,
+0x3fc,0x3fc,0x3fc,0x3fc,0x3fc,0x3fc,0x3fc,0x3fc,0x3fc,0x3fc,0x3fc,0x3fc,0x3fc,0x1e,0x3fc,0x3fc,
+0x3fc,0x3fc,0x3fc,0x3fc,0x3fc,0x1e,0x3fc,0x3ff,0x1e,0x3fc,0x3ff,0x1e,0x3fc,0x3fc,0x1e,0x1e,
+0x3f3,0x1e,0x3f9,0x3f9,0x3f9,0x3f0,0x3f0,0x1e,0x1e,0x1e,0x1e,0x3f0,0x3f0,0x1e,0x1e,0x3f0,
+0x3f0,0x3f6,0x1e,0x1e,0x1e,0xfbd,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x3ff,0x3ff,0x3ff,
+0x3fc,0x1e,0x3ff,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x969,0x969,0x969,0x969,0x969,0x969,
+0x969,0x969,0x969,0x969,0x3f0,0x3f0,0x3fc,0x3fc,0x3fc,0xfbd,0x194a,0x1e,0x1e,0x1e,0x1e,0x1e,
+0x1e,0x1e,0x1e,0x1e,0x21,0x402,0x402,0x40b,0x21,0x40e,0x40e,0x40e,0x40e,0x40e,0x40e,0x40e,
+0xcf3,0x40e,0x21,0x40e,0x40e,0x40e,0x21,0x40e,0x40e,0x40e,0x40e,0x40e,0x40e,0x40e,0x40e,0x40e,
+0x40e,0x40e,0x40e,0x40e,0x40e,0x21,0x40e,0x40e,0x40e,0x40e,0x40e,0x40e,0x40e,0x21,0x40e,0x40e,
+0x21,0x40e,0x40e,0x40e,0x40e,0x40e,0x21,0x21,0x405,0x40e,0x40b,0x40b,0x40b,0x402,0x402,0x402,
+0x402,0x402,0x21,0x402,0x402,0x40b,0x21,0x40b,0x40b,0x408,0x21,0x21,0x40e,0x21,0x21,0x21,
+0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x40e,0xcf3,0xced,0xced,
+0x21,0x21,0x96c,0x96c,0x96c,0x96c,0x96c,0x96c,0x96c,0x96c,0x96c,0x96c,0x1422,0xcf0,0x21,0x21,
+0x21,0x21,0x21,0x21,0x21,0x1725,0x18a5,0x18a5,0x18a5,0x18a8,0x18a8,0x18a8,0x24,0x411,0x420,0x420,
+0x24,0x426,0x426,0x426,0x426,0x426,0x426,0x426,0x426,0x24,0x24,0x426,0x426,0x24,0x24,0x426,
+0x426,0x426,0x426,0x426,0x426,0x426,0x426,0x426,0x426,0x426,0x426,0x426,0x426,0x24,0x426,0x426,
+0x426,0x426,0x426,0x426,0x426,0x24,0x426,0x426,0x24,0xcf6,0x426,0x426,0x426,0x426,0x24,0x24,
+0x414,0x426,0x411,0x411,0x420,0x411,0x411,0x411,0xfc0,0x24,0x24,0x420,0x423,0x24,0x24,0x423,
+0x423,0x417,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x1ab5,0x411,0x411,0x24,0x24,0x24,0x24,
+0x429,0x429,0x24,0x426,0x426,0x426,0xfc0,0xfc0,0x24,0x24,0x41d,0x41d,0x41d,0x41d,0x41d,0x41d,
+0x41d,0x41d,0x41d,0x41d,0x41a,0xcf6,0x1344,0x1344,0x1344,0x1344,0x1344,0x1344,0x24,0x24,0x24,0x24,
+0x24,0x24,0x24,0x24,0x27,0x27,0x42c,0x438,0x27,0x438,0x438,0x438,0x438,0x438,0x438,0x27,
+0x27,0x27,0x438,0x438,0x438,0x27,0x438,0x438,0x43b,0x438,0x27,0x27,0x27,0x438,0x438,0x27,
+0x438,0x27,0x438,0x438,0x27,0x27,0x27,0x438,0x438,0x27,0x27,0x27,0x438,0x438,0x438,0x27,
+0x27,0x27,0x438,0x438,0x438,0x438,0x438,0x438,0x438,0x438,0xde0,0x438,0x438,0x438,0x27,0x27,
+0x27,0x27,0x42c,0x432,0x42c,0x432,0x432,0x27,0x27,0x27,0x432,0x432,0x432,0x27,0x435,0x435,
+0x435,0x42f,0x27,0x27,0xfc3,0x27,0x27,0x27,0x27,0x27,0x27,0x42c,0x27,0x27,0x27,0x27,
+0x27,0x27,0x27,0x27,0x27,0x27,0xef7,0x972,0x972,0x972,0x972,0x972,0x972,0x972,0x972,0x972,
+0x96f,0x96f,0x96f,0xdb0,0xcf9,0xcf9,0xcf9,0xcf9,0xcf9,0xcfc,0xcf9,0x27,0x27,0x27,0x27,0x27,
+0x150c,0x44a,0x44a,0x44a,0x194d,0x44d,0x44d,0x44d,0x44d,0x44d,0x44d,0x44d,0x44d,0x2a,0x44d,0x44d,
+0x44d,0x2a,0x44d,0x44d,0x44d,0x44d,0x44d,0x44d,0x44d,0x44d,0x44d,0x44d,0x44d,0x44d,0x44d,0x44d,
+0x44d,0x2a,0x44d,0x44d,0x44d,0x44d,0x44d,0x44d,0x44d,0x44d,0x44d,0x44d,0x150f,0x44d,0x44d,0x44d,
+0x44d,0x44d,0x2a,0x2a,0x2a,0xfcc,0x43e,0x43e,0x43e,0x44a,0x44a,0x44a,0x44a,0x2a,0x43e,0x43e,
+0x441,0x2a,0x43e,0x43e,0x43e,0x444,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x43e,0x43e,0x2a,
+0xfcc,0xfcc,0x1728,0x2a,0x2a,0x2a,0x2a,0x2a,0x44d,0x44d,0xfc6,0xfc6,0x2a,0x2a,0x447,0x447,
+0x447,0x447,0x447,0x447,0x447,0x447,0x447,0x447,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x1a19,
+0xfc9,0xfc9,0xfc9,0xfc9,0xfc9,0xfc9,0xfc9,0xfc9,0x17e5,0x1512,0x456,0x456,0x1950,0x45c,0x45c,0x45c,
+0x45c,0x45c,0x45c,0x45c,0x45c,0x2d,0x45c,0x45c,0x45c,0x2d,0x45c,0x45c,0x45c,0x45c,0x45c,0x45c,
+0x45c,0x45c,0x45c,0x45c,0x45c,0x45c,0x45c,0x45c,0x45c,0x2d,0x45c,0x45c,0x45c,0x45c,0x45c,0x45c,
+0x45c,0x45c,0x45c,0x45c,0x2d,0x45c,0x45c,0x45c,0x45c,0x45c,0x2d,0x2d,0xcff,0xd02,0x456,0x450,
+0x459,0x456,0x450,0x456,0x456,0x2d,0x450,0x459,0x459,0x2d,0x459,0x459,0x450,0x453,0x2d,0x2d,
+0x2d,0x2d,0x2d,0x2d,0x2d,0x450,0x450,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x45c,0x2d,
+0x45c,0x45c,0xf0f,0xf0f,0x2d,0x2d,0x975,0x975,0x975,0x975,0x975,0x975,0x975,0x975,0x975,0x975,
+0x2d,0xf12,0xf12,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,
+0x18ab,0x1515,0x468,0x468,0x1ab8,0x46e,0x46e,0x46e,0x46e,0x46e,0x46e,0x46e,0x46e,0x30,0x46e,0x46e,
+0x46e,0x30,0x46e,0x46e,0x46e,0x46e,0x46e,0x46e,0x46e,0x46e,0x46e,0x46e,0x46e,0x46e,0x46e,0x46e,
+0x468,0x45f,0x45f,0x45f,0xfcf,0x30,0x468,0x468,0x468,0x30,0x46b,0x46b,0x46b,0x462,0x134a,0x17e8,
+0x30,0x30,0x30,0x30,0x17eb,0x17eb,0x17eb,0x45f,0x17e8,0x17e8,0x17e8,0x17e8,0x17e8,0x17e8,0x17e8,0x172b,
+0x46e,0x46e,0xfcf,0xfcf,0x30,0x30,0x465,0x465,0x465,0x465,0x465,0x465,0x465,0x465,0x465,0x465,
+0xfd2,0xfd2,0xfd2,0xfd2,0xfd2,0xfd2,0x17e8,0x17e8,0x17e8,0xfd5,0xfd8,0xfd8,0xfd8,0xfd8,0xfd8,0xfd8,
+0x33,0x1abb,0xa3e,0xa3e,0x33,0xa44,0xa44,0xa44,0xa44,0xa44,0xa44,0xa44,0xa44,0xa44,0xa44,0xa44,
+0xa44,0xa44,0xa44,0xa44,0xa44,0xa44,0xa44,0x33,0x33,0x33,0xa44,0xa44,0xa44,0xa44,0xa44,0xa44,
+0xa44,0xa44,0xa44,0xa44,0xa44,0xa44,0xa44,0xa44,0xa44,0xa44,0xa44,0xa44,0xa44,0xa44,0x33,0xa44,
+0xa44,0xa44,0xa44,0xa44,0xa44,0xa44,0xa44,0xa44,0x33,0xa44,0x33,0x33,0xa44,0xa44,0xa44,0xa44,
+0xa44,0xa44,0xa44,0x33,0x33,0x33,0xa38,0x33,0x33,0x33,0x33,0xa35,0xa3e,0xa3e,0xa35,0xa35,
+0xa35,0x33,0xa35,0x33,0xa3e,0xa3e,0xa41,0xa3e,0xa41,0xa41,0xa41,0xa35,0x33,0x33,0x33,0x33,
+0x33,0x33,0x1518,0x1518,0x1518,0x1518,0x1518,0x1518,0x1518,0x1518,0x1518,0x1518,0x33,0x33,0xa3e,0xa3e,
+0xa3b,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x36,0x489,0x489,0x489,
+0x489,0x489,0x489,0x489,0x489,0x489,0x489,0x489,0x489,0x489,0x489,0x489,0x489,0x489,0x489,0x489,
+0x489,0x489,0x489,0x489,0x489,0x489,0x489,0x489,0x489,0x489,0x489,0x489,0x489,0x474,0x489,0x486,
+0x474,0x474,0x474,0x474,0x474,0x474,0x47a,0x36,0x36,0x36,0x36,0x471,0x48f,0x48f,0x48f,0x48f,
+0x48f,0x489,0x48c,0x477,0x477,0x477,0x477,0x477,0x477,0x474,0x477,0x47d,0x483,0x483,0x483,0x483,
+0x483,0x483,0x483,0x483,0x483,0x483,0x480,0x480,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x39,0x49e,0x49e,0x39,0x49e,0x39,0x1a1f,0x49e,
+0x49e,0x1a1f,0x49e,0x39,0x1a1f,0x49e,0x1a1f,0x1a1f,0x1a1f,0x1a1f,0x1a1f,0x1a1f,0x49e,0x49e,0x49e,0x49e,
+0x1a1f,0x49e,0x49e,0x49e,0x49e,0x49e,0x49e,0x49e,0x1a1f,0x49e,0x49e,0x49e,0x39,0x49e,0x39,0x49e,
+0x1a1f,0x1a1f,0x49e,0x49e,0x1a1f,0x49e,0x49e,0x49e,0x49e,0x492,0x49e,0x49b,0x492,0x492,0x492,0x492,
+0x492,0x492,0x1a1c,0x492,0x492,0x49e,0x39,0x39,0x4a7,0x4a7,0x4a7,0x4a7,0x4a7,0x39,0x4a4,0x39,
+0x495,0x495,0x495,0x495,0x495,0x492,0x39,0x39,0x498,0x498,0x498,0x498,0x498,0x498,0x498,0x498,
+0x498,0x498,0x39,0x39,0x4a1,0x4a1,0x1425,0x1425,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,
+0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,
+0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x9b7,0x9b7,0x9b7,0x9ba,0x9b7,0x9b7,0x9b7,0x9b7,
+0x3c,0x9b7,0x9b7,0x9b7,0x9b7,0x9ba,0x9b7,0x9b7,0x9b7,0x9b7,0x9ba,0x9b7,0x9b7,0x9b7,0x9b7,0x9ba,
+0x9b7,0x9b7,0x9b7,0x9b7,0x9ba,0x9b7,0x9b7,0x9b7,0x9b7,0x9b7,0x9b7,0x9b7,0x9b7,0x9b7,0x9b7,0x9b7,
+0x9b7,0x9ba,0xa53,0xfe4,0xfe4,0x3c,0x3c,0x3c,0x3c,0x984,0x984,0x987,0x984,0x987,0x987,0x990,
+0x987,0x990,0x984,0x984,0x984,0x984,0x984,0x9b1,0x984,0x987,0x98a,0x98a,0x98d,0x996,0x98a,0x98a,
+0x9b7,0x9b7,0x9b7,0x9b7,0x1353,0x134d,0x134d,0x134d,0x984,0x984,0x984,0x987,0x984,0x984,0xa47,0x984,
+0x3c,0x984,0x984,0x984,0x984,0x987,0x984,0x984,0x984,0x984,0x987,0x984,0x984,0x984,0x984,0x987,
+0x984,0x984,0x984,0x984,0x987,0x984,0xa47,0xa47,0xa47,0x984,0x984,0x984,0x984,0x984,0x984,0x984,
+0xa47,0x987,0xa47,0xa47,0xa47,0x3c,0xa50,0xa50,0xa4d,0xa4d,0xa4d,0xa4d,0xa4d,0xa4d,0xa4a,0xa4d,
+0xa4d,0xa4d,0xa4d,0xa4d,0xa4d,0x3c,0xfdb,0xa4d,0xde3,0xde3,0xfde,0xfe1,0xfdb,0x1161,0x1161,0x1161,
+0x1161,0x1350,0x1350,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,
+0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,
+0x3c,0x3c,0x3c,0x3c,0x4ad,0x4ad,0x4ad,0x4ad,0x4ad,0x4ad,0x3f,0x142b,0x3f,0x3f,0x3f,0x3f,
+0x3f,0x142b,0x3f,0x3f,0x4aa,0x4aa,0x4aa,0x4aa,0x4aa,0x4aa,0x4aa,0x4aa,0x4aa,0x4aa,0x4aa,0x4aa,
+0x4aa,0x4aa,0x4aa,0x4aa,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xdf2,0xa7d,0x42,0xa7d,0xa7d,
+0xa7d,0xa7d,0x42,0x42,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0x42,0xa7d,0x42,0xa7d,0xa7d,
+0xa7d,0xa7d,0x42,0x42,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xdf2,0xa7d,0x42,0xa7d,0xa7d,
+0xa7d,0xa7d,0x42,0x42,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,
+0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xdf2,0xa7d,0x42,0xa7d,0xa7d,0xa7d,0xa7d,0x42,0x42,
+0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0x42,0xa7d,0x42,0xa7d,0xa7d,0xa7d,0xa7d,0x42,0x42,
+0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xdf2,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0x42,
+0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xdf2,
+0xa7d,0x42,0xa7d,0xa7d,0xa7d,0xa7d,0x42,0x42,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xdf2,
+0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,
+0xa7d,0xa7d,0xa7d,0x42,0x42,0x1356,0x1356,0xdec,0xdef,0xa77,0xa80,0xa74,0xa74,0xa74,0xa74,0xa80,
+0xa80,0xa7a,0xa7a,0xa7a,0xa7a,0xa7a,0xa7a,0xa7a,0xa7a,0xa7a,0xa71,0xa71,0xa71,0xa71,0xa71,0xa71,
+0xa71,0xa71,0xa71,0xa71,0xa71,0x42,0x42,0x42,0xa83,0xa83,0xa83,0xa83,0xa83,0xa83,0xa83,0xa83,
+0xa83,0xa83,0xa83,0xa83,0xa83,0xa83,0xa83,0xa83,0xa83,0xa83,0xa83,0xa83,0xa83,0x1731,0x45,0x45,
+0x172e,0x172e,0x172e,0x172e,0x172e,0x172e,0x45,0x45,0xa95,0xa98,0xa98,0xa98,0xa98,0xa98,0xa98,0xa98,
+0xa98,0xa98,0xa98,0xa98,0xa98,0xa98,0xa98,0xa98,0xa98,0xa98,0xa98,0xa98,0xa98,0xa98,0xa98,0xa98,
+0xa98,0xa98,0xa98,0xa92,0xa8f,0x48,0x48,0x48,0xa9e,0xa9e,0xa9e,0xa9e,0xa9e,0xa9e,0xa9e,0xa9e,
+0xa9e,0xa9e,0xa9e,0xa9b,0xa9b,0xa9b,0xa9e,0xa9e,0xa9e,0x151b,0x151b,0x151b,0x151b,0x151b,0x151b,0x151b,
+0x151b,0x4b,0x4b,0x4b,0x4b,0x4b,0x4b,0x4b,0xabf,0xabf,0xabf,0xabf,0xabf,0xabf,0xaa1,0xabf,
+0xabf,0xaa4,0xaa4,0xaa4,0xaa4,0xaa4,0xaa4,0xaa4,0xaa4,0xaa4,0xaa7,0xaa4,0xab6,0xab6,0xab9,0xac2,
+0xab0,0xaad,0xab6,0xab3,0xac2,0xd05,0x4e,0x4e,0xabc,0xabc,0xabc,0xabc,0xabc,0xabc,0xabc,0xabc,
+0xabc,0xabc,0x4e,0x4e,0x4e,0x4e,0x4e,0x4e,0xd08,0xd08,0xd08,0xd08,0xd08,0xd08,0xd08,0xd08,
+0xd08,0xd08,0x4e,0x4e,0x4e,0x4e,0x4e,0x4e,0xad1,0xad1,0xb52,0xb55,0xad7,0xb4f,0xad4,0xad1,
+0xada,0xae9,0xadd,0xaec,0xaec,0xaec,0xac8,0x51,0xae0,0xae0,0xae0,0xae0,0xae0,0xae0,0xae0,0xae0,
+0xae0,0xae0,0x51,0x51,0x51,0x51,0x51,0x51,0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,
+0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,
+0x1953,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,
+0xae3,0xacb,0x1002,0x51,0x51,0x51,0x51,0x51,0x11b8,0x11b8,0x11b8,0x11b8,0x11b8,0x11b8,0x11b8,0x11b8,
+0x11b8,0x11b8,0x11b8,0x11b8,0x11b8,0x11b8,0x11b8,0x11b8,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,
+0x4ce,0x4ce,0x4ce,0x4ce,0x4ce,0x4ce,0x4ce,0x4ce,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,0x54,0x54,
+0x4ce,0x4ce,0x4ce,0x4ce,0x4ce,0x4ce,0x54,0x54,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,
+0x54,0x4ce,0x54,0x4ce,0x54,0x4ce,0x54,0x4ce,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,
+0x4ce,0x4ce,0x4ce,0x4ce,0x4ce,0x4ce,0x4ce,0x4ce,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,
+0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,0x54,0x54,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,
+0x4ce,0x4ce,0x4ce,0x4ce,0x4ce,0x4ce,0x4ce,0x4ce,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,0x54,0x4cb,0x4cb,
+0x4ce,0x4ce,0x4ce,0x4ce,0x4ce,0x4c5,0x4cb,0x4c5,0x4c5,0x4c2,0x4cb,0x4cb,0x4cb,0x54,0x4cb,0x4cb,
+0x4ce,0x4ce,0x4ce,0x4ce,0x4ce,0x4c2,0x4c2,0x4c2,0x4cb,0x4cb,0x4cb,0x4cb,0x54,0x54,0x4cb,0x4cb,
+0x4ce,0x4ce,0x4ce,0x4ce,0x54,0x4c2,0x4c2,0x4c2,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,
+0x4ce,0x4ce,0x4ce,0x4ce,0x4ce,0x4c2,0x4c2,0x4c2,0x54,0x54,0x4cb,0x4cb,0x4cb,0x54,0x4cb,0x4cb,
+0x4ce,0x4ce,0x4ce,0x4ce,0x4ce,0x4c8,0x4c5,0x54,0xbca,0xbcd,0xbcd,0xbcd,0x100b,0x57,0x14f7,0x14f7,
+0x14f7,0x14f7,0x4d7,0x4d7,0x4d7,0x4d7,0x4d7,0x4d7,0x522,0xbdf,0x5a,0x5a,0x6e1,0x522,0x522,0x522,
+0x522,0x522,0x528,0x53a,0x528,0x534,0x52e,0x6e4,0x51f,0x6de,0x6de,0x6de,0x6de,0x51f,0x51f,0x51f,
+0x51f,0x51f,0x525,0x537,0x525,0x531,0x52b,0x5a,0xdfb,0xdfb,0xdfb,0xdfb,0xdfb,0x1359,0x1359,0x1359,
+0x1359,0x1359,0x1359,0x1359,0x1359,0x5a,0x5a,0x5a,0x5d,0x5d,0x5d,0x5d,0x5d,0x5d,0x5d,0x5d,
+0x5d,0x5d,0x5d,0x5d,0x5d,0x5d,0x5d,0x5d,0x549,0x549,0x549,0x549,0x549,0x549,0x549,0x549,
+0x549,0x549,0x549,0x549,0x549,0x546,0x546,0x546,0x546,0x549,0xafb,0xafe,0xbe5,0xbeb,0xbeb,0xbe8,
+0xbe8,0xbe8,0xbe8,0xe01,0xf15,0xf15,0xf15,0xf15,0x114c,0x60,0x60,0x60,0x60,0x60,0x60,0x60,
+0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x579,0x579,0x579,0xb07,0xf1e,0x1011,0x1011,0x1011,
+0x1011,0x12ab,0x1737,0x1737,0x63,0x63,0x63,0x63,0x70b,0x70b,0x70b,0x70b,0x70e,0x70e,0x70e,0x70e,
+0x70e,0x70e,0x585,0x585,0x582,0x582,0x582,0x582,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0xb13,0xb13,0x66,
+0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,
+0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x5af,0x5af,0x5af,0x5af,0x5af,0x5af,0x5af,0x5af,
+0x5af,0x5af,0x5af,0x69,0x69,0x69,0x69,0x69,0x69,0x69,0x69,0x69,0x69,0x69,0x69,0x69,
+0x69,0x69,0x69,0x69,0x69,0x69,0x69,0x69,0xb2e,0xb2e,0xb2e,0xb2e,0xb2e,0xb2e,0xb2e,0xb2e,
+0xb2e,0xb2e,0xb2e,0xb2e,0xb2e,0xb2e,0xb2e,0xb2e,0xb2e,0xb2e,0xb2e,0xb2e,0xb2e,0xb2e,0xb2e,0xb2e,
+0xb2e,0xb2e,0x6c,0xb2e,0xb2e,0xb2e,0xb2e,0xb31,0xb2e,0xb2e,0xb2e,0xb2e,0xb2e,0xb2e,0xb2e,0xb2e,
+0xb2e,0xb2e,0xb2e,0xb2e,0xb2e,0xb2e,0xb2e,0xb2e,0xb2e,0xb2e,0xb2e,0xb31,0x6c,0x6c,0x6c,0x6c,
+0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0xb34,0xb34,0xb34,0xb34,0xb34,0xb34,0xb34,0xb34,
+0xb34,0xb34,0xb34,0xb34,0xb34,0xb34,0xb34,0xb34,0xb34,0xb34,0xb34,0xb34,0xb34,0xb34,0x6f,0x6f,
+0x6f,0x6f,0x6f,0x6f,0x6f,0x6f,0x6f,0x6f,0x75,0x843,0x83d,0x843,0x83d,0x843,0x83d,0x843,
+0x83d,0x843,0x83d,0x83d,0x840,0x83d,0x840,0x83d,0x840,0x83d,0x840,0x83d,0x840,0x83d,0x840,0x83d,
+0x840,0x83d,0x840,0x83d,0x840,0x83d,0x840,0x83d,0x83d,0x83d,0x83d,0x843,0x83d,0x843,0x83d,0x843,
+0x83d,0x83d,0x83d,0x83d,0x83d,0x83d,0x843,0x83d,0x83d,0x83d,0x83d,0x83d,0x840,0xc93,0xc93,0x75,
+0x75,0x954,0x954,0x91e,0x91e,0x846,0x849,0xc90,0x78,0x78,0x78,0x78,0x78,0x85b,0x85b,0x85b,
+0x85b,0x85b,0x85b,0x85b,0x85b,0x85b,0x85b,0x85b,0x85b,0x85b,0x85b,0x85b,0x85b,0x85b,0x85b,0x85b,
+0x85b,0x85b,0x85b,0x85b,0x85b,0x85b,0x85b,0x85b,0x85b,0x113a,0x191a,0x1a01,0x7b,0x85e,0x85e,0x85e,
+0x85e,0x85e,0x85e,0x85e,0x85e,0x85e,0x85e,0x85e,0x85e,0x85e,0x85e,0x85e,0x85e,0x85e,0x85e,0x7b,
+0x927,0x927,0x92a,0x92a,0x92a,0x92a,0x92a,0x92a,0x92a,0x92a,0x92a,0x92a,0x92a,0x92a,0x92a,0x92a,
+0x867,0x867,0x867,0x867,0x867,0x867,0x867,0x867,0x867,0x867,0x867,0x867,0x867,0x867,0x867,0x867,
+0x867,0x867,0x867,0x867,0x867,0x867,0x867,0x867,0x867,0x867,0x867,0x867,0x867,0xd98,0xd98,0x7e,
+0xb46,0xb46,0xb46,0xb46,0xb46,0xb46,0xb46,0xb46,0xb46,0xb46,0xb46,0xb46,0xb46,0x81,0x81,0x81,
+0xb4c,0xb4c,0xb4c,0xb4c,0xb4c,0xb4c,0xb4c,0xb4c,0xb4c,0xb4c,0xb4c,0xb4c,0xb4c,0xb4c,0xb4c,0xb4c,
+0xb4c,0xc9c,0xb4c,0xb4c,0xb4c,0xc9c,0xb4c,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,
+0x11df,0x11df,0x11df,0x11df,0x11df,0x11df,0x11df,0x11df,0x11df,0x11df,0x11df,0x11df,0x11df,0x11df,0x11df,0x11df,
+0x9db,0x9db,0x9db,0x9db,0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,
+0x1254,0x1254,0x1254,0x1254,0x1254,0x1254,0x1254,0x1254,0x1254,0x1254,0x1254,0x1254,0x1254,0x1254,0x1254,0x1254,
+0x60c,0x60c,0x60c,0x60c,0x60c,0x60c,0x60c,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,
+0x8a,0x8a,0x8a,0x5fa,0x5fa,0x5fa,0x5fa,0x5fa,0x8a,0x8a,0x8a,0x8a,0x8a,0xb1f,0x5fd,0x603,
+0x609,0x609,0x609,0x609,0x609,0x609,0x609,0x609,0x609,0x600,0x603,0x603,0x603,0x603,0x603,0x603,
+0x603,0x603,0x603,0x603,0x603,0x603,0x603,0x8a,0x603,0x603,0x603,0x603,0x603,0x8a,0x603,0x8a,
+0x603,0x603,0x8a,0x603,0x603,0x8a,0x603,0x603,0x603,0x603,0x603,0x603,0x603,0x603,0x603,0x606,
+0x61e,0x618,0x61e,0x618,0x61b,0x621,0x61e,0x618,0x61b,0x621,0x61e,0x618,0x61b,0x621,0x61e,0x618,
+0x136b,0x136b,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,
+0x8d,0x8d,0x8d,0x61e,0x618,0x61b,0x621,0x61e,0x618,0x61e,0x618,0x61e,0x618,0x61e,0x61e,0x618,
+0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,
+0x61b,0x618,0x61b,0x61b,0x61b,0x61b,0x61b,0x61b,0x618,0x61b,0x618,0x618,0x61b,0x61b,0x618,0x618,
+0x618,0x618,0x618,0x61b,0x618,0x618,0x61b,0x618,0x61b,0x61b,0x61b,0x618,0x61b,0x61b,0x61b,0x61b,
+0x8d,0x8d,0x61b,0x61b,0x61b,0x61b,0x618,0x618,0x61b,0x618,0x618,0x618,0x618,0x61b,0x618,0x618,
+0x618,0x618,0x618,0x61b,0x61b,0x61b,0x618,0x618,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,
+0xb6a,0xb6a,0xb6a,0xb6a,0xb6a,0xb6a,0xb6a,0xb6a,0xb6a,0xb6a,0xb6a,0xb6a,0xb6a,0xb6a,0xb6a,0xb6a,
+0x61e,0x61e,0x978,0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,0x615,0x615,0xc24,0xdb3,0x8d,0x8d,
+0x87f,0x891,0x88e,0x891,0x88e,0xcb1,0xcb1,0xda4,0xda1,0x882,0x882,0x882,0x882,0x894,0x894,0x894,
+0x8ac,0x8af,0x8be,0x90,0x8b2,0x8b5,0x8c1,0x8c1,0x8a9,0x8a0,0x89a,0x8a0,0x89a,0x8a0,0x89a,0x89d,
+0x89d,0x8b8,0x8b8,0x8bb,0x8b8,0x8b8,0x8b8,0x90,0x8b8,0x8a6,0x8a3,0x89d,0x90,0x90,0x90,0x90,
+0x62a,0x636,0x62a,0xc27,0x62a,0x93,0x62a,0x636,0x62a,0x636,0x62a,0x636,0x62a,0x636,0x62a,0x636,
+0x636,0x633,0x62d,0x630,0x636,0x633,0x62d,0x630,0x636,0x633,0x62d,0x630,0x636,0x633,0x62d,0x633,
+0x62d,0x633,0x62d,0x630,0x636,0x633,0x62d,0x633,0x62d,0x633,0x62d,0x633,0x62d,0x93,0x93,0x627,
+0x77d,0x780,0x795,0x798,0x777,0x780,0x780,0x99,0x75f,0x762,0x762,0x762,0x762,0x75f,0x75f,0x99,
+0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,0xb22,0xb22,0xb22,0x9de,0x759,0x639,0x639,
+0x99,0x7a7,0x786,0x777,0x780,0x77d,0x777,0x789,0x77a,0x774,0x777,0x795,0x78c,0x783,0x7a4,0x777,
+0x7a1,0x7a1,0x7a1,0x7a1,0x7a1,0x7a1,0x7a1,0x7a1,0x7a1,0x7a1,0x792,0x78f,0x795,0x795,0x795,0x7a7,
+0x768,0x765,0x765,0x765,0x765,0x765,0x765,0x765,0x765,0x765,0x765,0x765,0x765,0x765,0x765,0x765,
+0x765,0x765,0x765,0x765,0x765,0x765,0x765,0x765,0x765,0x765,0x765,0x765,0x765,0x765,0x765,0x99,
+0x99,0x99,0x765,0x765,0x765,0x765,0x765,0x765,0x99,0x99,0x765,0x765,0x765,0x765,0x765,0x765,
+0x99,0x99,0x765,0x765,0x765,0x765,0x765,0x765,0x99,0x99,0x765,0x765,0x765,0x99,0x99,0x99,
+0xb6d,0xb6d,0xb6d,0xb6d,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x18b7,0x18b7,0x18b7,
+0xb73,0xb73,0xb73,0xb73,0xb73,0xb73,0xb73,0xb73,0xb73,0xb73,0xb73,0xb73,0xb73,0xb73,0xb73,0xb73,
+0xb73,0xb73,0xb73,0x9f,0x9f,0x9f,0x9f,0x9f,0x1683,0x1683,0x1683,0x1683,0x1683,0x1683,0x1683,0x1683,
+0x1683,0x1683,0x1683,0x1683,0x1683,0x1683,0x1683,0x1683,0xb7c,0xb7c,0xb7c,0xb7c,0xb7c,0xb7c,0xb7c,0xb7c,
+0xb7c,0xb7c,0xb7c,0xb7c,0xb7c,0xb7c,0xb7c,0xb7c,0xb7c,0xb7c,0xb7c,0xb7c,0xb7c,0xb7c,0xa2,0xa2,
+0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xa5,
+0xa5,0x101d,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,
+0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0x173d,0x173d,0x173d,0x173d,0x173d,0x173d,0x173d,0x173d,
+0x173d,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,
+0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,
+0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xa8,0xb9d,0xb9d,
+0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xba0,0xba0,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,
+0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,
+0xb9d,0xb9d,0xb9d,0xb9d,0xba0,0xa8,0xba0,0xba0,0xa8,0xa8,0xba0,0xa8,0xa8,0xba0,0xba0,0xa8,
+0xa8,0xba0,0xba0,0xba0,0xba0,0xa8,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xb9d,0xb9d,
+0xb9d,0xb9d,0xa8,0xb9d,0xa8,0xb9d,0xb9d,0xb9d,0xb9d,0xd29,0xb9d,0xb9d,0xa8,0xb9d,0xb9d,0xb9d,
+0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,
+0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xb9d,0xb9d,0xb9d,0xb9d,0xba0,0xba0,0xa8,0xba0,
+0xba0,0xba0,0xba0,0xa8,0xa8,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xa8,0xba0,0xba0,
+0xba0,0xba0,0xba0,0xba0,0xba0,0xa8,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,
+0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,
+0xba0,0xba0,0xa8,0xba0,0xba0,0xba0,0xba0,0xa8,0xba0,0xba0,0xba0,0xba0,0xba0,0xa8,0xba0,0xa8,
+0xa8,0xa8,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xa8,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,
+0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xe16,0xe16,0xa8,0xa8,0xba0,0xba0,0xba0,0xba0,
+0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,
+0xba0,0xba0,0xba0,0xba0,0xb9d,0xb9d,0xb9d,0xb97,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xf2d,0xf2a,
+0xa8,0xa8,0xb9a,0xb9a,0xb9a,0xb9a,0xb9a,0xb9a,0xb9a,0xb9a,0xb9a,0xb9a,0xb9a,0xb9a,0xb9a,0xb9a,
+0xb9a,0xb9a,0xb9a,0xb9a,0xab,0xba6,0xab,0xab,0xab,0xab,0xab,0xab,0xab,0xab,0xab,0xab,
+0xab,0xab,0xab,0xab,0xab,0xab,0xab,0xab,0xab,0xab,0xab,0xab,0xab,0xab,0xab,0xab,
+0xab,0xab,0xab,0xab,0xc36,0xc36,0xc36,0xc36,0xc36,0xc36,0xc36,0xc36,0xc36,0xc36,0xc36,0xc36,
+0xc36,0xae,0xc36,0xc36,0xc36,0xc36,0xc30,0xc30,0xc33,0xae,0xae,0xae,0xae,0xae,0xae,0xae,
+0xae,0xae,0xae,0xae,0xc3f,0xc3f,0xc3f,0xc3f,0xc3f,0xc3f,0xc3f,0xc3f,0xc3f,0xc3f,0xc3f,0xc3f,
+0xc3f,0xc3f,0xc3f,0xc3f,0xc3f,0xc3f,0xc39,0xc39,0xc3c,0xca5,0xca5,0xb1,0xb1,0xb1,0xb1,0xb1,
+0xb1,0xb1,0xb1,0xb1,0xc45,0xc45,0xc45,0xc45,0xc45,0xc45,0xc45,0xc45,0xc45,0xc45,0xc45,0xc45,
+0xc45,0xc45,0xc45,0xc45,0xc45,0xc45,0xc42,0xc42,0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,
+0xb4,0xb4,0xb4,0xb4,0xc4b,0xc4b,0xc4b,0xc4b,0xc4b,0xc4b,0xc4b,0xc4b,0xc4b,0xc4b,0xc4b,0xc4b,
+0xc4b,0xb7,0xc4b,0xc4b,0xc4b,0xb7,0xc48,0xc48,0xb7,0xb7,0xb7,0xb7,0xb7,0xb7,0xb7,0xb7,
+0xb7,0xb7,0xb7,0xb7,0xd3b,0xd3b,0xd3b,0xd3b,0xd3b,0xd3b,0xd3b,0xd3b,0xd3b,0xd3b,0xd3b,0xd3b,
+0xd3b,0xd3b,0xd3b,0xd3b,0xd3b,0xd3b,0xd3b,0xd3b,0xd3b,0xd3b,0xd3b,0xd3b,0xd3b,0xd3b,0xd3b,0xd3b,
+0xd3b,0x1539,0x1539,0xba,0xd2c,0xd2c,0xd2c,0xd38,0xd38,0xd38,0xd38,0xd2c,0xd2c,0xd38,0xd38,0xd38,
+0xba,0xba,0xba,0xba,0xd38,0xd38,0xd2c,0xd38,0xd38,0xd38,0xd38,0xd38,0xd38,0xd2f,0xd2f,0xd2f,
+0xba,0xba,0xba,0xba,0xd32,0xba,0xba,0xba,0xd3e,0xd3e,0xd35,0xd35,0xd35,0xd35,0xd35,0xd35,
+0xd35,0xd35,0xd35,0xd35,0xd41,0xd41,0xd41,0xd41,0xd41,0xd41,0xd41,0xd41,0xd41,0xd41,0xd41,0xd41,
+0xd41,0xd41,0xd41,0xd41,0xd41,0xd41,0xbd,0xbd,0xd41,0xd41,0xd41,0xd41,0xd41,0xbd,0xbd,0xbd,
+0xbd,0xbd,0xbd,0xbd,0xbd,0xbd,0xbd,0xbd,0x153c,0x153c,0x153c,0x153c,0x153c,0x153c,0x153c,0x153c,
+0x153c,0x153c,0x153c,0x153c,0x153c,0x153c,0x153c,0x153c,0x153c,0x153c,0x153c,0x153c,0xc0,0xc0,0x153c,0x153c,
+0x153c,0x153c,0x153c,0x153c,0x153c,0x153c,0x153c,0x153c,0x153c,0x153c,0x153c,0x153c,0x153c,0x153c,0x153c,0x153c,
+0x153c,0x153c,0x153c,0x153c,0x153c,0x153c,0xc0,0x1abe,0x153c,0x153c,0x153c,0x153c,0x153c,0x153c,0x153c,0x153c,
+0xd68,0xd68,0xd68,0xd68,0xd68,0xd68,0xd68,0xd68,0xd68,0xd68,0xd68,0xd68,0xc3,0xd68,0xd68,0xd68,
+0xd68,0xd68,0xd68,0xd68,0xd68,0xd68,0xd68,0xd68,0xd68,0xd68,0xd68,0xd68,0xd68,0xd68,0xd68,0xd68,
+0xd68,0xd68,0xd68,0xc3,0xd68,0xd68,0xd68,0xd68,0xd68,0xd68,0xd68,0xd68,0xd68,0xd68,0xd68,0xd68,
+0xd68,0xd68,0xd68,0xd68,0xd68,0xd68,0xd68,0xc3,0xd68,0xd68,0xc3,0xd68,0xd68,0xd68,0xd68,0xd68,
+0xd68,0xd68,0xd68,0xd68,0xd68,0xd68,0xd68,0xd68,0xd68,0xd68,0xc3,0xc3,0xd68,0xd68,0xd68,0xd68,
+0xd68,0xd68,0xd68,0xd68,0xd68,0xd68,0xd68,0xd68,0xd68,0xd68,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,
+0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,
+0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xd6b,0xd6b,0xd6b,0xd6b,
+0xd6b,0xd6b,0xd6b,0xd6b,0xd6b,0xd6b,0xd6b,0xd6b,0xd6b,0xd6b,0xd6b,0xd6b,0xd6b,0xd6b,0xd6b,0xd6b,
+0xd6b,0xd6b,0xd6b,0xd6b,0xd6b,0xd6b,0xd6b,0xc6,0xc6,0xc6,0xc6,0xc6,0xdad,0xdad,0xdad,0xc9,
+0xc9,0xc9,0xc9,0xda7,0xda7,0xda7,0xda7,0xda7,0xda7,0xda7,0xda7,0xda7,0xda7,0xda7,0xda7,0xda7,
+0xda7,0xda7,0xda7,0xda7,0xda7,0xda7,0xda7,0xda7,0xda7,0xda7,0xda7,0xda7,0xc9,0xc9,0xc9,0xdaa,
+0xdaa,0xdaa,0xdaa,0xdaa,0xdaa,0xdaa,0xdaa,0xdaa,0xd71,0xd71,0xd71,0xd71,0xd71,0xd71,0xd71,0xd71,
+0xd71,0xd71,0xd71,0xd71,0xd71,0xd71,0xd71,0xd71,0xd71,0xd71,0xd71,0xd71,0xd71,0xd71,0xd71,0xd71,
+0xd71,0xd71,0xd71,0xd71,0xd71,0xd71,0xcc,0xd6e,0xd7a,0xd7a,0xd7a,0xd7a,0xd7a,0xd7a,0xd7a,0xd7a,
+0xd7a,0xd7a,0xd7a,0xd7a,0xd7a,0xd7a,0xd7a,0xd7a,0xd7a,0xd7a,0xd7a,0xd7a,0xd7a,0xd7a,0xd7a,0xd7a,
+0xd7a,0xd7a,0xd7a,0xd7a,0xd7a,0xd7a,0xcf,0xcf,0xd77,0xd77,0xd77,0xd77,0xd77,0xd77,0xd77,0xd77,
+0xd77,0xd77,0xcf,0xcf,0xcf,0xcf,0xcf,0xcf,0x187b,0x187b,0x187b,0x187b,0x187b,0x187b,0x187b,0x187b,
+0x187b,0x187b,0x187b,0x187b,0x187b,0x187b,0x187b,0x187b,0xd7d,0xd7d,0xd7d,0xd7d,0xd7d,0xd7d,0xd2,0xd2,
+0xd7d,0xd2,0xd7d,0xd7d,0xd7d,0xd7d,0xd7d,0xd7d,0xd7d,0xd7d,0xd7d,0xd7d,0xd7d,0xd7d,0xd7d,0xd7d,
+0xd7d,0xd7d,0xd7d,0xd7d,0xd7d,0xd7d,0xd7d,0xd7d,0xd7d,0xd7d,0xd2,0xd7d,0xd7d,0xd2,0xd2,0xd2,
+0xd7d,0xd2,0xd2,0xd7d,0xd80,0xd80,0xd80,0xd80,0xd80,0xd80,0xd80,0xd80,0xd80,0xd80,0xd80,0xd80,
+0xd80,0xd80,0xd80,0xd80,0xd80,0xd80,0xd80,0xd80,0xd80,0xd80,0xd80,0xd5,0xd5,0xd5,0xd5,0xd5,
+0xd5,0xd5,0xd5,0xd5,0xe31,0xe31,0xe31,0xe31,0xe31,0xe31,0xe31,0xe31,0xe31,0xe31,0xe31,0x153f,
+0x153f,0x17f1,0x17f1,0xdb,0x1119,0x1119,0x1119,0x1119,0x1119,0x1119,0x1119,0x1119,0x1119,0x1119,0x1119,0x1119,
+0x1acd,0x132,0x132,0x132,0xe43,0xe43,0xe43,0xe43,0xe43,0xe43,0xe43,0xe43,0xe43,0xe43,0xe43,0xe43,
+0xe43,0xe43,0xe43,0xe43,0xe43,0xe43,0xe43,0xe43,0xe43,0xe43,0xe43,0xe3a,0xe3a,0xe40,0xe40,0xe3a,
+0xde,0xde,0xe3d,0xe3d,0x1149,0x1149,0x1149,0x1149,0xe1,0xe1,0xe1,0xe1,0xe1,0xe1,0xe1,0xe1,
+0xe1,0xe1,0xe1,0xe1,0xca2,0xca2,0xca2,0xca2,0xca2,0xca2,0xca2,0xca2,0xca2,0xca2,0xca2,0xca2,
+0xca2,0xca2,0xca2,0xca2,0x1038,0x1038,0x1038,0x1038,0x1038,0x1038,0x1038,0x1542,0x1542,0x1542,0x1542,0x1542,
+0x1542,0x1542,0x1542,0x1542,0x1542,0x1542,0x1542,0x1542,0x1542,0x1545,0x18bd,0x18bd,0x193e,0x18bd,0xe4,0x17f4,
+0x1377,0x118b,0xf3c,0xf3c,0xe55,0xe52,0xe55,0xe52,0xe52,0xe49,0xe49,0xe49,0xe49,0xe49,0xe49,0x1194,
+0x1191,0x1194,0x1191,0x118e,0x118e,0x118e,0x1434,0x1431,0xe7,0xe7,0xe7,0xe7,0xe7,0xe4f,0xe4c,0xe4c,
+0xe4c,0xe49,0xe4f,0xe4c,0xe58,0xe58,0xe58,0xe58,0xe58,0xe58,0xe58,0xe58,0xe58,0xe58,0xe58,0xe58,
+0xe58,0xe58,0xe58,0xe58,0xe58,0xe58,0xe58,0xe58,0xe58,0xe58,0xe58,0xea,0xea,0xea,0xea,0xea,
+0xea,0xea,0xea,0xea,0xe58,0xe58,0xe58,0xe58,0xe58,0xe58,0xe58,0xea,0xe58,0xe58,0xe58,0xe58,
+0xe58,0xe58,0xe58,0xea,0xe58,0xe58,0xe58,0xe58,0xe58,0xe58,0xe58,0xea,0xe58,0xe58,0xe58,0xe58,
+0xe58,0xe58,0xe58,0xea,0xe5e,0xe5e,0xe5e,0xe5e,0xe5e,0xe5e,0xe5e,0xe5e,0xe5e,0xe5e,0xe5e,0xe5e,
+0xe5e,0xe5e,0xe5e,0xe5e,0xe5b,0xe5b,0xe5b,0xe5b,0xe5b,0xe5b,0xe5b,0xe5b,0xe5b,0xe5b,0xed,0xed,
+0xed,0xed,0xed,0xed,0xe61,0xe61,0xe61,0xe61,0xe61,0xe61,0xf0,0x1437,0xf0,0xf0,0xf0,0xf0,
+0xf0,0x1437,0xf0,0xf0,0xeb8,0xeb8,0xeb8,0xeb8,0xeb8,0xeb8,0xeb8,0xeb8,0xeb8,0xeb8,0xeb8,0xeb8,
+0xeb8,0xeb8,0xeb8,0xeb8,0xe67,0xe67,0xe67,0xe67,0xe67,0xe67,0xe67,0xe67,0xe67,0xe67,0xe67,0xe67,
+0xe67,0xe67,0xe67,0xf3,0xe64,0xe64,0xe64,0xe64,0xe64,0xe64,0xe64,0xe64,0xe64,0xe64,0xe64,0xe64,
+0xe64,0xe64,0xe64,0xe64,0xe64,0xe64,0xe64,0xe64,0xe64,0xe64,0xe64,0xe64,0xe64,0xe64,0xe64,0xe64,
+0xe64,0xe64,0xe64,0xf3,0xe79,0xe6d,0xe6d,0xe6d,0xf6,0xe6d,0xe6d,0xf6,0xf6,0xf6,0xf6,0xf6,
+0xe6d,0xe6d,0xe6d,0xe6d,0xe79,0xe79,0xe79,0xe79,0xf6,0xe79,0xe79,0xe79,0xf6,0xe79,0xe79,0xe79,
+0xe79,0xe79,0xe79,0xe79,0xe79,0xe79,0xe79,0xe79,0xe79,0xe79,0xe79,0xe79,0xe79,0xe79,0xe79,0xe79,
+0xe79,0xe79,0xe79,0xe79,0x195c,0x195c,0xf6,0xf6,0xe6a,0xe6a,0xe6a,0xf6,0xf6,0xf6,0xf6,0xe70,
+0xe73,0xe73,0xe73,0xe73,0xe73,0xe73,0xe73,0xe73,0x1959,0xf6,0xf6,0xf6,0xf6,0xf6,0xf6,0xf6,
+0xe76,0xe76,0xe76,0xe76,0xe76,0xe76,0xe7c,0xe7c,0xe73,0xf6,0xf6,0xf6,0xf6,0xf6,0xf6,0xf6,
+0xe88,0xe88,0xe88,0xe88,0xe88,0xe88,0xe88,0xe88,0xe88,0xe88,0x119a,0x119a,0xf9,0xf9,0xf9,0xf9,
+0xe88,0xe88,0xe88,0xe88,0xe88,0xe8b,0xe8b,0xe8b,0xe88,0xe88,0xe8b,0xe88,0xe88,0xe88,0xe88,0xe88,
+0xe88,0xe88,0xe88,0xe88,0xe88,0xe88,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xe85,0xe85,0xe85,0xe85,
+0xe85,0xe85,0xe85,0xe85,0xe85,0xe85,0x1197,0xf9,0xf9,0xf9,0xe82,0xe82,0xe91,0xe91,0xe91,0xe91,
+0xfc,0xfc,0xfc,0xfc,0xe91,0xe91,0xe91,0xe91,0xe91,0xe91,0xe91,0xe91,0xe8e,0xe91,0xe91,0xe91,
+0xe91,0xe91,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0x154e,0x1554,0x1551,0x189c,
+0x17f7,0x18c0,0x18c0,0x18c0,0x18c0,0x18c0,0x1962,0x195f,0x1965,0x195f,0x1965,0x1a25,0x1ac1,0x1ac1,0x1ac1,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xeb5,0xeb5,0xeb5,0xeb2,0xeb2,0xea9,0xea9,0xeb2,0xeaf,0xeaf,0xeaf,0xeaf,0x1ac4,0x102,0x102,0x102,
+0x1314,0x1314,0x1314,0x1317,0x1317,0x1317,0x130e,0x130e,0x1311,0x130e,0x156,0x156,0x156,0x156,0x156,0x156,
+0xeb8,0xeb8,0xeb8,0xeb8,0xeb8,0xeb8,0x1443,0x1443,0x105,0x105,0x105,0x105,0x105,0x105,0x105,0xebb,
+0x137d,0x105,0x105,0x105,0x105,0x105,0x105,0x105,0x105,0x105,0x105,0x105,0x105,0x105,0x105,0x137a,
+0xc72,0xc72,0xc72,0xc72,0xc72,0xc72,0xc72,0xc72,0xc72,0xc72,0xc72,0xc72,0xc72,0xc72,0xc72,0xc75,
+0xee8,0xed9,0xed3,0xee5,0xee2,0xedc,0xedc,0xeeb,0xed6,0xedf,0x108,0x108,0x108,0x108,0x108,0x108,
+0xf6f,0xf6f,0xf5a,0xf6f,0xf72,0xf75,0xf75,0xf75,0xf75,0xf75,0xf75,0xf75,0x10e,0x10e,0x10e,0x10e,
+0xf69,0xf69,0xf69,0xf69,0xf69,0xf69,0xf69,0xf69,0xf69,0xf69,0xf7b,0xf7b,0xf60,0xf66,0xf7b,0xf7b,
+0xf63,0xf60,0xf60,0xf60,0xf60,0xf60,0xf60,0xf60,0xf60,0xf60,0xf60,0xf5d,0xf5d,0xf5d,0xf5d,0xf5d,
+0xf5d,0xf5d,0xf5d,0xf5d,0xf60,0xf60,0xf60,0xf60,0xf60,0xf60,0xf60,0xf60,0xf60,0x10e,0x10e,0x10e,
+0x111,0x111,0x1a2b,0x1a28,0x1a2b,0x1a2b,0x1a2b,0x1aca,0x1ac7,0x1aca,0x1ac7,0x111,0x111,0x111,0x111,0x111,
+0x111,0x111,0x111,0x111,0x111,0x111,0x111,0x111,0x111,0x111,0x111,0x111,0x111,0x111,0x111,0x111,
+0x111,0x1aca,0x1ac7,0x155d,0x144c,0x144c,0x1380,0x1074,0x1074,0x1074,0x1074,0x1074,0xf8a,0xf8a,0xf8a,0xf8a,
+0xf8a,0xf8a,0xf8a,0xf8a,0xf8a,0xf8a,0xf8a,0xf8a,0xf8a,0xf8a,0xf8a,0xf8a,0xf8a,0xf8a,0xf8a,0xf8a,
+0xf87,0xf87,0xf8d,0xf8d,0x114,0x114,0x114,0x114,0x114,0x114,0x114,0x114,0xf96,0xf96,0xf96,0xf96,
+0xf96,0xf96,0xf96,0xf96,0xf96,0xf96,0xf96,0xf96,0xf96,0xf96,0xf96,0xf96,0xf96,0xf96,0xf96,0xf96,
+0xf96,0xf96,0xf90,0xf90,0xf90,0xf90,0x11a3,0x11a3,0x117,0x117,0x117,0xf93,0x1563,0x1563,0x1563,0x1563,
+0x1563,0x1563,0x1563,0x1563,0x1563,0x1563,0x1563,0x1563,0x1563,0x1563,0x1563,0x1563,0x1563,0x1563,0x1563,0x1563,
+0x1563,0x1563,0x1563,0x1563,0x1563,0x174c,0x11a,0x11a,0x11a,0x11a,0x11a,0x11a,0x11a,0x11a,0x11a,0x11a,
+0x11a,0x11a,0x11a,0x11a,0x11a,0x11a,0x11a,0x11a,0x11a,0x11a,0x11a,0x11a,0x11a,0x11a,0x11a,0x11a,
+0x11a,0x11a,0x11a,0x11a,0x11a,0x11a,0x11a,0x11a,0xf9f,0xf9f,0xf9f,0x1569,0x1569,0x1569,0x1569,0x1569,
+0x1569,0x1569,0x1569,0x1569,0x1569,0x1569,0x1569,0x11d,0xf9c,0xf9c,0xf9c,0xf9c,0x1566,0x11d,0x11d,0x11d,
+0x11d,0x11d,0x11d,0x11d,0x11d,0x11d,0x11d,0x11d,0xfa2,0xfa2,0xfa2,0xfa2,0xfa2,0xfa2,0xfa2,0xfa2,
+0xfa2,0xfa2,0xfa2,0xfa2,0xfa2,0xfa2,0xfa2,0xfa2,0xfa2,0xfa2,0x1974,0x1974,0x1974,0x1974,0x1974,0x1974,
+0x1974,0x120,0x120,0x120,0x120,0x120,0x120,0x120,0x109b,0x109b,0x109b,0x109b,0x1098,0x1098,0x1098,0x1098,
+0x1098,0x1098,0x1098,0x1098,0x1089,0x1089,0x1089,0x1089,0x1089,0x1089,0x1089,0x1089,0x1098,0x1098,0x108f,0x108c,
+0x123,0x123,0x123,0x109e,0x109e,0x1092,0x1092,0x1092,0x1095,0x1095,0x1095,0x1095,0x1095,0x1095,0x1095,0x1095,
+0x1095,0x1095,0x123,0x123,0x123,0x109b,0x109b,0x109b,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,
+0x10a1,0x10a1,0x10a4,0x10a4,0x10a4,0x10a4,0x10a4,0x10a4,0x10b6,0x10b6,0x10b6,0x10b6,0x10b6,0x10b6,0x10b6,0x10b6,
+0x10b6,0x10b6,0x10b9,0x10b9,0x126,0x126,0x126,0x126,0x126,0x126,0x126,0x126,0x126,0x126,0x126,0x126,
+0x126,0x126,0x126,0x126,0x126,0x126,0x126,0x126,0x10e0,0x10e0,0x10e0,0x10e0,0x10da,0x17fd,0x129,0x129,
+0x129,0x129,0x129,0x129,0x129,0x129,0x10e6,0x10e6,0x10dd,0x10dd,0x10dd,0x10dd,0x10dd,0x10dd,0x10dd,0x10dd,
+0x10dd,0x10dd,0x129,0x129,0x129,0x129,0x129,0x129,0x1104,0x1104,0x1104,0x1104,0x1104,0x1104,0x1104,0x10f8,
+0x10f8,0x10f8,0x10f8,0x10f8,0x10f8,0x10f8,0x10f8,0x10f8,0x10f8,0x10f8,0x10fe,0x1101,0x12c,0x12c,0x12c,0x12c,
+0x12c,0x12c,0x12c,0x12c,0x12c,0x12c,0x12c,0x10fb,0x1113,0x1113,0x1113,0x1113,0x1113,0x1113,0x1113,0x1113,
+0x1113,0x1107,0x1107,0x1107,0x1107,0x1107,0x1107,0x1110,0x1110,0x1107,0x1107,0x1110,0x1110,0x1107,0x1107,0x12f,
+0x12f,0x12f,0x12f,0x12f,0x12f,0x12f,0x12f,0x12f,0x1113,0x1113,0x1113,0x1107,0x1113,0x1113,0x1113,0x1113,
+0x1113,0x1113,0x1113,0x1113,0x1107,0x1110,0x12f,0x12f,0x110d,0x110d,0x110d,0x110d,0x110d,0x110d,0x110d,0x110d,
+0x110d,0x110d,0x12f,0x12f,0x110a,0x1116,0x1116,0x1116,0x1575,0x132,0x132,0x132,0x132,0x132,0x132,0x132,
+0x132,0x132,0x132,0x132,0x132,0x132,0x132,0x132,0x132,0x132,0x132,0x132,0x132,0x132,0x132,0x132,
+0x132,0x132,0x132,0x132,0x132,0x132,0x132,0x132,0x111c,0x111c,0x111c,0x111c,0x111c,0x111c,0x111c,0x111c,
+0x111c,0x111c,0x111c,0x111c,0x111c,0x111c,0x111c,0x111c,0x111c,0x111c,0x111c,0x111c,0x111c,0x111c,0x111c,0x111c,
+0x111c,0x111c,0x111c,0x111c,0x111c,0x111f,0x135,0x135,0x1122,0x1122,0x1122,0x1122,0x1122,0x1122,0x1122,0x1122,
 0x1122,0x1122,0x1122,0x1122,0x1122,0x1122,0x1122,0x1122,0x1122,0x1122,0x1122,0x1122,0x1122,0x1122,0x1122,0x1122,
-0x1122,0x1122,0x1122,0x1122,0x1122,0x1122,0x1122,0x1122,0x1122,0x1122,0x1122,0x1122,0x1122,0x1122,0x1122,0x1122,
-0x113d,0x113d,0x113d,0x113d,0x113d,0x113d,0x113d,0x113d,0x113d,0x113d,0x113d,0x113d,0x113d,0x113d,0x113d,0x113d,
-0x113d,0x113d,0x113d,0x113d,0x113d,0x113d,0x113d,0x113d,0x113d,0x113d,0x113d,0x113d,0x113d,0x113d,0x113d,0x113d,
-0x1149,0x1149,0x1149,0x1149,0x1149,0x1149,0x1149,0x1149,0x1149,0x1149,0x1149,0x1149,0x1149,0x1149,0x1149,0x1149,
-0x1149,0x1149,0x1149,0x1149,0x1149,0x1149,0x1149,0x1149,0x1149,0x1149,0x1149,0x1149,0x1149,0x1149,0x1146,0x114c,
-0x1158,0x1158,0x1158,0x1158,0x1158,0x1158,0x1158,0x1158,0x1158,0x1158,0x1158,0x1158,0x1158,0x1158,0x1158,0x1158,
-0x1158,0x1158,0x1158,0x1158,0x1158,0x1158,0x1158,0x1158,0x1158,0x1158,0x1158,0x1158,0x1158,0x1158,0x1158,0x1158,
-0x1167,0x1167,0x1167,0x1176,0x117c,0x117c,0x117c,0x117c,0x117c,0x117c,0x117c,0x117c,0x117c,0x117c,0x117c,0x117c,
-0x117c,0x117c,0x117c,0x117c,0x117c,0x117c,0x117c,0x117c,0x117c,0x117c,0x117c,0x117c,0x117c,0x117c,0x117c,0x117c,
-0x117c,0x117c,0x117c,0x116a,0x1176,0x1176,0x1167,0x1167,0x1167,0x1167,0x1176,0x1176,0x1167,0x1176,0x1176,0x1176,
-0x1188,0x1188,0x1188,0x1188,0x1188,0x1188,0x1188,0x1188,0x1188,0x1188,0x1188,0x1188,0x1188,0x1188,0x1188,0x1188,
-0x118b,0x1188,0x1188,0x1188,0x1188,0x1188,0x1188,0x1182,0x1182,0x1182,0x1188,0x1185,0x14cd,0x14d0,0x14d3,0x14d3,
-0x119a,0x119a,0x119a,0x119a,0x119a,0x119a,0x119a,0x119a,0x119a,0x119a,0x119a,0x119a,0x119a,0x119a,0x119a,0x119a,
-0x118e,0x119a,0x118e,0x118e,0x118e,0x11a3,0x11a3,0x118e,0x118e,0x11a3,0x119a,0x11a3,0x11a3,0x119a,0x118e,0x1191,
-0x119a,0x119a,0x119a,0x119a,0x119a,0x119a,0x119a,0x119a,0x119a,0x119a,0x119a,0x119a,0x119a,0x119a,0x119a,0x119a,
-0x119a,0x119a,0x119a,0x119a,0x119a,0x119a,0x119a,0x119a,0x119a,0x119a,0x119a,0x119a,0x119a,0x119a,0x119a,0x119a,
-0x11b5,0x11b5,0x11b5,0x11b5,0x11b5,0x11b5,0x11b5,0x11b5,0x11b5,0x11b5,0x11b5,0x11b5,0x11b5,0x11b5,0x11b5,0x11b5,
-0x11b5,0x11b5,0x11b5,0x11b5,0x11b5,0x11b5,0x11b5,0x11b5,0x11b5,0x11b5,0x11b5,0x11b5,0x11b5,0x11b5,0x11b5,0x11b5,
-0x11cd,0x11cd,0x11cd,0x11cd,0x11cd,0x11cd,0x11cd,0x11cd,0x11cd,0x11cd,0x11cd,0x11cd,0x11cd,0x11cd,0x11cd,0x11cd,
-0x11cd,0x11cd,0x11cd,0x11cd,0x11cd,0x11cd,0x11cd,0x11cd,0x11cd,0x11cd,0x11cd,0x11cd,0x11cd,0x11ca,0x11ca,0x11ca,
-0x11d6,0x11d6,0x11d6,0x11d6,0x11d6,0x11d6,0x11d6,0x11d6,0x11d6,0x11d6,0x11d6,0x11d6,0x11d6,0x11d6,0x11d6,0x11d6,
-0x11d6,0x11d6,0x11d6,0x11d6,0x11d6,0x11d6,0x11d6,0x11d6,0x11d6,0x11d6,0x11d6,0x11d6,0x11d6,0x11d6,0x11d6,0x11d6,
-0x11e5,0x11e5,0x11e5,0x11e5,0x11e5,0x11e5,0x11e5,0x11e5,0x11e5,0x11e5,0x11e5,0x11e5,0x11e5,0x11e5,0x11e5,0x11e5,
-0x11e5,0x11e5,0x11e5,0x11e5,0x11e5,0x11e5,0x11e5,0x11e5,0x11e5,0x11e5,0x11e5,0x11e5,0x11e5,0x11e5,0x11e5,0x11e5,
-0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1203,0x1200,0x1200,0x1200,0x1200,
-0x11fd,0x11fd,0x11fd,0x11f1,0x11f1,0x11f1,0x11f1,0x11fd,0x11fd,0x11f7,0x11f4,0x11fa,0x11fa,0x11eb,0x1206,0x1206,
-0x11ee,0x11ee,0x11fd,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,
-0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1203,0x1200,0x1203,0x1200,0x1200,0x1200,
-0x1209,0x1209,0x1209,0x1209,0x1209,0x1209,0x1209,0x1209,0x1209,0x1209,0x1209,0x1209,0x1209,0x1209,0x1209,0x1209,
-0x1209,0x1209,0x1209,0x1209,0x1209,0x1209,0x1209,0x1209,0x1209,0x1209,0x1209,0x1209,0x1209,0x1209,0x1209,0x1209,
-0x120f,0x120f,0x120f,0x120c,0x120c,0x120c,0x1209,0x1209,0x1209,0x1209,0x120c,0x1209,0x1209,0x1209,0x120f,0x120c,
-0x120f,0x120c,0x1209,0x1209,0x1209,0x1209,0x1209,0x1209,0x1209,0x1209,0x1209,0x1209,0x1209,0x1209,0x1209,0x1209,
-0x1209,0x1209,0x1209,0x1209,0x1209,0x1209,0x1209,0x1209,0x1209,0x1209,0x1209,0x1209,0x1209,0x120f,0x120c,0x120c,
-0x1209,0x1209,0x1209,0x1209,0x121b,0x121b,0x12c0,0x1218,0x12c0,0x12c0,0x12c0,0x12c0,0x1218,0x121e,0x1224,0x1218,
-0x1218,0x1218,0x1218,0x1218,0x121e,0x1221,0x1224,0x1224,0x1221,0x1224,0x1218,0x1221,0x1221,0x1227,0x1224,0x1218,
-0x1218,0x1224,0x121b,0x121b,0x1356,0x1356,0x1245,0x1356,0x1356,0x1356,0x1245,0x1356,0x1356,0x1356,0x123f,0x123f,
-0x123f,0x123f,0x123f,0x134d,0x1353,0x1353,0x1353,0x1353,0x1353,0x1353,0x1353,0x1242,0x1353,0x1353,0x1353,0x1353,
-0x1353,0x1353,0x1353,0x1242,0x1266,0x1266,0x1266,0x1266,0x1266,0x1266,0x1266,0x1266,0x1266,0x1266,0x1266,0x1266,
-0x1266,0x1266,0x1266,0x1266,0x1266,0x1266,0x1266,0x1266,0x1266,0x1266,0x1266,0x1266,0x1266,0x1266,0x1266,0x1266,
-0x1266,0x1266,0x1266,0x1266,0x130b,0x130b,0x130b,0x130b,0x130b,0x130b,0x130b,0x130b,0x130b,0x130b,0x130b,0x130b,
-0x130b,0x130b,0x130b,0x130b,0x130b,0x130b,0x130b,0x130b,0x130b,0x130b,0x130b,0x130b,0x130b,0x130b,0x130b,0x130b,
-0x130b,0x130b,0x130b,0x130b,0x1320,0x1311,0x1320,0x1323,0x1323,0x1323,0x1323,0x1323,0x1323,0x1323,0x1323,0x1323,
-0x1323,0x1323,0x1323,0x1323,0x1323,0x1323,0x1323,0x1323,0x1323,0x1323,0x1323,0x1323,0x1323,0x1323,0x1323,0x1323,
-0x1323,0x1323,0x1323,0x1323,0x1311,0x1311,0x1311,0x1311,0x1311,0x1311,0x1311,0x1311,0x1329,0x1329,0x1329,0x1329,
-0x1329,0x1329,0x1329,0x1329,0x1329,0x1329,0x1329,0x1329,0x1329,0x1329,0x1329,0x1329,0x1329,0x1329,0x1329,0x1329,
-0x1329,0x1329,0x1329,0x1329,0x1329,0x1329,0x1329,0x1329,0x1329,0x1329,0x1329,0x1329,0x1335,0x1335,0x1335,0x1335,
-0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,
-0x1335,0x1332,0x1332,0x1335,0x1335,0x1335,0x1335,0x1335,0x1332,0x1335,0x1335,0x1335,0x1332,0x1335,0x1332,0x1335,
-0x1332,0x1335,0x1335,0x1335,0x1335,0x1335,0x1338,0x1335,0x1335,0x1335,0x1335,0x1332,0x1335,0x1332,0x1332,0x1335,
-0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1332,0x1332,0x1332,0x1332,
-0x1332,0x1332,0x1332,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,
-0x1335,0x1335,0x1335,0x1332,0x1332,0x1332,0x1332,0x1332,0x1332,0x1332,0x1332,0x1332,0x1332,0x1335,0x1335,0x1335,
-0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1332,0x1332,0x1332,0x1332,0x1332,0x1332,
-0x1332,0x1332,0x1332,0x1332,0x1332,0x1332,0x14df,0x14df,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,
-0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,
-0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x14e8,0x14e2,0x14e2,0x14e8,0x14e8,0x14e8,0x14e8,
-0x14e8,0x14e8,0x14e8,0x14e8,0x14e8,0x16a1,0x16a1,0x16a1,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x14e8,0x1335,
-0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,
-0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x14e8,0x16a1,0x16a1,
-0x1335,0x1335,0x1335,0x1335,0x1335,0x1338,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,
-0x1335,0x1335,0x1335,0x1335,0x14e2,0x14e2,0x14e8,0x14e8,0x14e2,0x14e8,0x14e8,0x14e8,0x14df,0x14df,0x14e8,0x14e8,
-0x1335,0x1335,0x1335,0x1338,0x1338,0x14eb,0x1335,0x1335,0x1335,0x1335,0x1338,0x14ee,0x14e8,0x14e8,0x14e8,0x16a1,
-0x16a1,0x16a1,0x16a1,0x16a1,0x14e8,0x14e8,0x14e8,0x14e8,0x14e8,0x14e8,0x14e8,0x14e8,0x14e8,0x14e8,0x14e8,0x14e8,
-0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,
-0x1335,0x14e2,0x14e2,0x14e8,0x14eb,0x14e8,0x14e2,0x14e8,0x16a1,0x16a1,0x16a1,0x16a4,0x16a4,0x16a4,0x16a4,0x16a4,
-0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,
-0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x14e8,
-0x1335,0x14e8,0x1338,0x1338,0x1335,0x1335,0x1338,0x1338,0x1338,0x1338,0x1338,0x1338,0x1338,0x1338,0x1338,0x1338,
-0x1338,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,
-0x1335,0x1335,0x1338,0x1338,0x1338,0x1338,0x1335,0x1335,0x1335,0x1335,0x1338,0x1335,0x1338,0x1338,0x1338,0x1338,
-0x1338,0x1338,0x1338,0x1338,0x1338,0x1335,0x1335,0x1335,0x1338,0x1335,0x1335,0x1335,0x1335,0x1338,0x1338,0x1338,
-0x1335,0x1338,0x1338,0x1338,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,
-0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x14eb,0x1335,0x1335,0x1335,
-0x1335,0x14e8,0x14e2,0x16a1,0x13b3,0x13b3,0x13b3,0x13b3,0x14df,0x14df,0x14df,0x14df,0x14df,0x14e5,0x14e8,0x16a1,
-0x16a1,0x16a1,0x16a1,0x169e,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,0x1335,
-0x1335,0x1335,0x1335,0x1335,0x14e2,0x14e8,0x14e2,0x14e8,0x14e2,0x14e2,0x14e2,0x14e2,0x14e8,0x14e2,0x14e2,0x14e2,
-0x14e2,0x14e2,0x14e2,0x14e8,0x14e2,0x14e2,0x14e2,0x14e8,0x14df,0x14df,0x14df,0x14df,0x14df,0x14df,0x14e8,0x1335,
-0x1335,0x1335,0x1335,0x1335,0x13b6,0x133b,0x133b,0x133b,0x133b,0x133b,0x133b,0x133b,0x133b,0x133b,0x133b,0x133b,
-0x133b,0x133b,0x133b,0x133b,0x133b,0x13b6,0x133b,0x133b,0x133b,0x13b6,0x133b,0x13b6,0x133b,0x13b6,0x133b,0x13b6,
-0x133b,0x133b,0x133b,0x13b6,0x133b,0x133b,0x133b,0x133b,0x133b,0x133b,0x13b6,0x13b6,0x133b,0x133b,0x133b,0x133b,
-0x13b6,0x133b,0x13b6,0x13b6,0x133b,0x133b,0x133b,0x133b,0x13b6,0x133b,0x133b,0x133b,0x133b,0x133b,0x133b,0x133b,
-0x133b,0x133b,0x133b,0x133b,0x133b,0x14f4,0x14f4,0x16a7,0x16a7,0x133e,0x133e,0x133e,0x133b,0x133b,0x133b,0x133e,
-0x133e,0x133e,0x133e,0x133e,0x15e4,0x15e4,0x15e4,0x15e4,0x15e4,0x15e4,0x15e4,0x15e4,0x15e4,0x15e4,0x15e4,0x15e4,
-0x15e4,0x15e4,0x15e4,0x15e4,0x1341,0x1341,0x1341,0x1341,0x1341,0x1341,0x1341,0x1341,0x1341,0x1341,0x1341,0x1341,
-0x1341,0x1341,0x1341,0x1341,0x1341,0x1341,0x1341,0x1341,0x1341,0x1341,0x1341,0x1341,0x1341,0x1341,0x1341,0x1341,
-0x1341,0x1341,0x1341,0x1341,0x1341,0x1341,0x1341,0x1344,0x1341,0x1341,0x1341,0x1341,0x1341,0x1341,0x1341,0x1341,
-0x1341,0x1341,0x1341,0x1341,0x1341,0x1341,0x1341,0x1341,0x1344,0x1344,0x1344,0x1341,0x1341,0x1341,0x1341,0x1341,
-0x1341,0x1341,0x1341,0x1341,0x1347,0x1347,0x1347,0x1347,0x1347,0x1347,0x1347,0x1347,0x1347,0x1347,0x1347,0x1347,
-0x1347,0x1347,0x1347,0x1347,0x1347,0x1347,0x1347,0x1347,0x1347,0x1347,0x1347,0x1347,0x1347,0x1347,0x1347,0x1347,
-0x1347,0x1347,0x1347,0x1347,0x136e,0x136e,0x136e,0x136e,0x136e,0x136e,0x136e,0x136e,0x136e,0x136e,0x136e,0x136e,
-0x136e,0x136e,0x136e,0x136e,0x136e,0x136e,0x136e,0x136e,0x136e,0x136e,0x136e,0x136e,0x136e,0x136e,0x136e,0x136e,
-0x136e,0x136e,0x136e,0x136e,0x13c8,0x13c8,0x13c8,0x13da,0x13da,0x13da,0x13da,0x13da,0x13da,0x13da,0x13da,0x13da,
-0x13da,0x13da,0x13da,0x13da,0x13da,0x13da,0x13da,0x13da,0x13da,0x13da,0x13da,0x13da,0x13da,0x13da,0x13da,0x13da,
-0x13da,0x13da,0x13da,0x13da,0x13f5,0x13f5,0x13f5,0x13f5,0x13f5,0x13f5,0x13f5,0x13f5,0x13f5,0x13f5,0x13f5,0x13f5,
-0x13f5,0x13f5,0x13f5,0x13f5,0x13f5,0x13f5,0x13f5,0x13f5,0x13f5,0x13f5,0x13f5,0x13f5,0x13f5,0x13f5,0x13f5,0x13f5,
-0x13f5,0x13f5,0x13f5,0x13f5,0x13fe,0x13fe,0x13fe,0x13fe,0x13fe,0x13fe,0x13fe,0x13fe,0x13fe,0x13fe,0x13fe,0x13fe,
-0x13fe,0x13fe,0x13fe,0x13fe,0x13fe,0x13fe,0x13fe,0x13fe,0x13fe,0x13fe,0x13fe,0x13fe,0x13fe,0x13fe,0x13fe,0x13fe,
-0x13fe,0x13fe,0x13fe,0x13fe,0x1404,0x1404,0x1410,0x1416,0x1416,0x1416,0x1416,0x1416,0x1416,0x1416,0x1416,0x1416,
-0x1416,0x1416,0x1416,0x1416,0x1416,0x1416,0x1416,0x1416,0x1416,0x1416,0x1416,0x1416,0x1416,0x1416,0x1416,0x1416,
-0x1416,0x1416,0x1416,0x1416,0x1416,0x1416,0x1416,0x1410,0x1410,0x1410,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,
-0x1404,0x1404,0x1404,0x1410,0x1434,0x1434,0x1434,0x1434,0x1434,0x1434,0x1434,0x1434,0x1434,0x1434,0x1434,0x1434,
-0x1434,0x1434,0x1434,0x1434,0x1434,0x1434,0x1434,0x1434,0x1434,0x1434,0x1434,0x1434,0x1434,0x1434,0x1434,0x1434,
-0x1434,0x1434,0x1434,0x1434,0x14e2,0x14e2,0x14e8,0x14e8,0x14e8,0x14e2,0x14e2,0x14e2,0x14e2,0x14e2,0x14e2,0x14e2,
-0x14e2,0x14e2,0x14e2,0x14e2,0x14e2,0x14e8,0x14e8,0x14e8,0x14df,0x14df,0x14df,0x14df,0x14df,0x14df,0x14df,0x14df,
-0x14e8,0x14e8,0x14e8,0x14e2,0x14e2,0x14e2,0x14e2,0x14e2,0x14e2,0x14e2,0x14e2,0x14e8,0x14e2,0x14e2,0x14e8,0x14e8,
-0x14e8,0x14e8,0x14e2,0x14e2,0x14ee,0x14e2,0x14e2,0x14e2,0x14e2,0x14f1,0x14f1,0x14e2,0x14e2,0x14e2,0x14e2,0x14e2,
-0x14e2,0x14e2,0x14e2,0x14e2,0x1518,0x1518,0x1518,0x1518,0x1518,0x1518,0x1518,0x1518,0x1518,0x1518,0x1518,0x1518,
-0x1518,0x1518,0x1518,0x1518,0x1518,0x1518,0x1518,0x1518,0x1518,0x1518,0x1518,0x1518,0x1518,0x1518,0x1518,0x1518,
-0x1518,0x1518,0x1518,0x1518,0x152a,0x152a,0x152a,0x152a,0x152a,0x152a,0x152a,0x152a,0x152a,0x152a,0x152a,0x152a,
-0x152a,0x152a,0x152a,0x152a,0x152a,0x152a,0x152a,0x152a,0x152a,0x152a,0x152a,0x152a,0x152a,0x152a,0x152a,0x152a,
-0x152a,0x152a,0x152a,0x152a,0x1530,0x1530,0x1530,0x1530,0x1530,0x1530,0x1530,0x1530,0x1530,0x1530,0x1530,0x1530,
-0x1530,0x1530,0x1530,0x1530,0x1530,0x1530,0x1530,0x1530,0x1530,0x1530,0x1530,0x1530,0x1530,0x1530,0x1530,0x1530,
-0x1530,0x1530,0x1530,0x1530,0x1533,0x1533,0x1533,0x1533,0x1533,0x1533,0x1533,0x1533,0x1533,0x1533,0x1533,0x1533,
-0x1533,0x1533,0x1533,0x1533,0x1533,0x1533,0x1533,0x1533,0x1533,0x1533,0x1533,0x1533,0x1533,0x1533,0x1533,0x1533,
-0x1533,0x1533,0x1533,0x1533,0x1572,0x1572,0x1572,0x1572,0x1572,0x1572,0x1572,0x1572,0x1572,0x1572,0x1572,0x1572,
-0x1572,0x1572,0x1572,0x1572,0x1572,0x1572,0x1572,0x1572,0x1572,0x1572,0x1572,0x1572,0x1572,0x1572,0x1572,0x1572,
-0x1572,0x1572,0x1572,0x1563,0x157b,0x157b,0x157b,0x157b,0x157b,0x157b,0x157b,0x157b,0x157b,0x157b,0x157b,0x157b,
-0x157b,0x157b,0x157b,0x157b,0x157b,0x157b,0x157b,0x157b,0x157b,0x157b,0x157b,0x157b,0x157b,0x157b,0x157b,0x1575,
-0x157e,0x157e,0x157e,0x157e,0x1581,0x1581,0x1581,0x1581,0x1581,0x1581,0x1581,0x1581,0x1581,0x1581,0x1581,0x1581,
-0x1581,0x1581,0x1581,0x1581,0x1581,0x1581,0x1581,0x1581,0x1581,0x1581,0x1581,0x1581,0x1581,0x1581,0x1581,0x1581,
-0x1581,0x1581,0x1581,0x1581,0x159c,0x159c,0x159c,0x159c,0x159c,0x159c,0x159c,0x159c,0x1593,0x159c,0x159c,0x159c,
-0x159c,0x159c,0x159c,0x159c,0x159c,0x159c,0x159c,0x159c,0x159c,0x159c,0x159c,0x159c,0x159c,0x159c,0x159c,0x159c,
-0x159c,0x159c,0x159c,0x159c,0x15a5,0x15a5,0x15a5,0x15a5,0x15a5,0x15a5,0x15a5,0x15a5,0x15a5,0x15a5,0x15a5,0x15a5,
-0x15a5,0x15a5,0x15a5,0x15a5,0x15a5,0x15a5,0x15a5,0x15a5,0x15a5,0x15a5,0x15a5,0x15a5,0x15a5,0x15a5,0x15a5,0x15a5,
-0x15a5,0x15a5,0x15a5,0x15a5,0x15b7,0x15b7,0x15b7,0x15b7,0x15b7,0x15b7,0x15b7,0x15b7,0x15b7,0x15b7,0x15b7,0x15b7,
-0x15b7,0x15b7,0x15b7,0x15b7,0x15b4,0x15b4,0x15b4,0x15a8,0x15a8,0x15a8,0x15a8,0x15a8,0x15a8,0x15a8,0x15a8,0x15b4,
-0x15b4,0x15a8,0x15b4,0x15ab,0x15b7,0x15b7,0x15b7,0x15b7,0x15b7,0x15b7,0x15b7,0x15b7,0x15b7,0x15b7,0x15b7,0x15b7,
-0x15b7,0x15b7,0x15b7,0x15b7,0x15b7,0x15b7,0x15b7,0x15b7,0x15b7,0x15b7,0x15b7,0x15b7,0x15b7,0x15b7,0x15b7,0x15b7,
-0x15b7,0x15b7,0x15b7,0x15b7,0x15db,0x15db,0x15db,0x15db,0x15db,0x15db,0x15db,0x15db,0x15db,0x15db,0x15db,0x15db,
-0x15db,0x15db,0x15db,0x15db,0x15db,0x15db,0x15db,0x15db,0x15db,0x15db,0x15db,0x15db,0x15db,0x15db,0x15db,0x15db,
-0x15db,0x15d8,0x15d8,0x15d8,0x15e4,0x15e4,0x15e4,0x15e4,0x15e4,0x15e4,0x15e4,0x15e4,0x15e4,0x15e4,0x15e4,0x15e4,
-0x15e4,0x15e4,0x15e4,0x15e4,0x15e4,0x15e4,0x15e4,0x15e4,0x15e4,0x15e4,0x15ea,0x15ea,0x15ea,0x15e7,0x15e7,0x15e7,
-0x15e4,0x15e4,0x15e4,0x15e4,0x15f9,0x15f9,0x15f9,0x15f9,0x15f9,0x15f9,0x15f9,0x15f9,0x15f9,0x15f9,0x15f9,0x15f9,
-0x15f9,0x15f9,0x15f9,0x15f9,0x15ed,0x15ed,0x15ed,0x15ed,0x15ed,0x15ed,0x15ed,0x15ff,0x15ff,0x15f3,0x15f0,0x15f0,
-0x15f0,0x15f0,0x15f0,0x15f0,0x15f9,0x15f9,0x15f9,0x15f9,0x15f9,0x15f9,0x15f9,0x15f9,0x15f9,0x15f9,0x15f9,0x15f9,
-0x15f9,0x15f9,0x15f9,0x15f9,0x15f9,0x15f9,0x15f9,0x15f9,0x15f9,0x15f9,0x15f9,0x15f9,0x15f9,0x15f9,0x15f9,0x15f9,
-0x15f9,0x15f9,0x15f9,0x15f9,0x1605,0x1605,0x1605,0x1605,0x1605,0x1605,0x1605,0x1605,0x1605,0x1605,0x1605,0x1605,
-0x1605,0x1605,0x1605,0x1605,0x1605,0x1605,0x1605,0x1605,0x1605,0x1605,0x1605,0x1602,0x1602,0x1602,0x1602,0x1602,
-0x1602,0x1602,0x1602,0x1602,0x1608,0x1608,0x1608,0x1608,0x1608,0x1608,0x1608,0x1608,0x1608,0x1608,0x1608,0x1608,
-0x1608,0x1608,0x1608,0x1608,0x1608,0x1608,0x1608,0x1608,0x1608,0x1608,0x1608,0x1608,0x1608,0x1608,0x1608,0x1608,
-0x1608,0x1608,0x1608,0x1608,0x162c,0x162c,0x162c,0x162c,0x162c,0x162c,0x162c,0x162c,0x162c,0x162c,0x162c,0x162c,
-0x162c,0x162c,0x162c,0x162c,0x162c,0x162c,0x162c,0x162c,0x162c,0x162c,0x162c,0x162c,0x162c,0x162c,0x162c,0x162c,
-0x162c,0x162c,0x162c,0x162c,0x1635,0x1635,0x1635,0x1635,0x1635,0x1635,0x1635,0x1635,0x1635,0x1635,0x1635,0x1635,
-0x1635,0x1635,0x1635,0x1635,0x1635,0x1635,0x1635,0x1635,0x1635,0x1635,0x1635,0x1635,0x1635,0x1635,0x1635,0x1635,
-0x1635,0x1635,0x1635,0x1635,0x164d,0x164d,0x164d,0x164d,0x164d,0x164d,0x164d,0x164d,0x164d,0x164d,0x164d,0x164d,
-0x164d,0x164d,0x164d,0x164d,0x1638,0x1647,0x1647,0x1638,0x1638,0x1638,0x1638,0x1638,0x1638,0x1647,0x1638,0x164a,
-0x164a,0x1638,0x164a,0x1638,0x164d,0x164d,0x164d,0x164d,0x164d,0x164d,0x164d,0x164d,0x164d,0x164d,0x164d,0x164d,
-0x164d,0x164d,0x164d,0x164d,0x164d,0x164d,0x164d,0x164d,0x164d,0x164d,0x164d,0x164d,0x164d,0x164d,0x164d,0x164d,
-0x164d,0x164d,0x164d,0x164d,0x1656,0x1656,0x1656,0x1656,0x1656,0x1656,0x1656,0x1656,0x1656,0x1656,0x1656,0x1656,
-0x1656,0x1656,0x1656,0x1656,0x1656,0x1656,0x1656,0x1656,0x1656,0x1656,0x1656,0x1656,0x1656,0x1656,0x1656,0x1656,
-0x1656,0x1656,0x1656,0x1656,0x165c,0x165c,0x165c,0x165c,0x165c,0x165c,0x165c,0x165c,0x165c,0x165c,0x165c,0x165c,
-0x165c,0x165c,0x165c,0x165c,0x165c,0x165c,0x165c,0x165c,0x165c,0x165c,0x165c,0x165c,0x165c,0x165c,0x165c,0x165c,
-0x165c,0x165c,0x165c,0x165c,0x16b3,0x16b3,0x16b3,0x16b3,0x16b3,0x16b3,0x16b3,0x16b3,0x16b3,0x16b3,0x16b3,0x16b3,
-0x16b3,0x16b3,0x16b3,0x16b3,0x16b3,0x16b3,0x16b3,0x16b3,0x16b3,0x16b3,0x16b3,0x16b3,0x16b3,0x16b3,0x16b3,0x16b3,
-0x16b3,0x16b3,0x16b3,0x16b3,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,
-0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,
-0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x16f5,0x16f2,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,
-0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x16f8,0x16f8,0x16f8,0x16f8,0x16f8,0x16f8,0x16f8,0x16f8,
-0x16f8,0x16f8,0x16f8,0x16f8,0x16f8,0x16f8,0x16f8,0x16f8,0x16f8,0x16f8,0x16f8,0x16f8,0x16f8,0x16f8,0x16f8,0x16f8,
-0x16f8,0x16f8,0x16f8,0x16f8,0x16f8,0x16f8,0x16f8,0x16f8,0x16fb,0x16fb,0x16fb,0x16fb,0x16fb,0x16fb,0x16fb,0x16fb,
-0x16fb,0x16fb,0x16fb,0x16fb,0x16fb,0x16fb,0x16fb,0x16fb,0x16fb,0x16fb,0x16fb,0x16fb,0x16fb,0x16fb,0x16fb,0x16fb,
-0x16fb,0x16fb,0x16fb,0x16fb,0x16fb,0x16fb,0x16fb,0x16fb,0x170d,0x170d,0x170d,0x170d,0x170d,0x170d,0x170d,0x170d,
-0x170d,0x170d,0x170d,0x170d,0x170d,0x170d,0x170d,0x170d,0x170d,0x170d,0x170d,0x170d,0x170d,0x170d,0x170d,0x170d,
-0x170d,0x170d,0x170d,0x170d,0x170d,0x170d,0x170d,0x170d,0x1710,0x1710,0x1710,0x1710,0x1710,0x1710,0x1710,0x1710,
+0x1122,0x1122,0x1122,0x1122,0x1122,0x138,0x138,0x138,0x1125,0x1125,0x1125,0x1125,0x1125,0x1125,0x1125,0x1125,
+0x1125,0x1125,0x1125,0x1125,0x1125,0x1125,0x1125,0x1125,0x1125,0x13b,0x13b,0x13b,0x13b,0x13b,0x13b,0x13b,
+0x13b,0x13b,0x13b,0x13b,0x13b,0x13b,0x13b,0x13b,0x112b,0x112b,0x112b,0x112b,0x112b,0x112b,0x112b,0x112b,
+0x112b,0x112b,0x112b,0x112b,0x112b,0x112b,0x112b,0x112b,0x112b,0x112b,0x112b,0x112b,0x112b,0x112b,0x112b,0x112b,
+0x112b,0x112b,0x13e,0x13e,0x13e,0x13e,0x13e,0x1128,0x112e,0x112e,0x112e,0x112e,0x112e,0x112e,0x112e,0x112e,
+0x112e,0x112e,0x112e,0x112e,0x141,0x141,0x141,0x141,0x1131,0x1131,0x1131,0x1131,0x1131,0x1131,0x1131,0x1131,
+0x1131,0x1131,0x1131,0x1131,0x1131,0x1131,0x1131,0x1131,0x1131,0x1131,0x1131,0x1131,0x144,0x144,0x144,0x144,
+0x144,0x144,0x144,0x144,0x144,0x144,0x144,0x144,0x11a9,0x11a9,0x11a9,0x11a9,0x11b2,0x11a9,0x11a9,0x11a9,
+0x11b2,0x11a9,0x11a9,0x11a9,0x11a9,0x11a6,0x147,0x147,0x11af,0x11af,0x11af,0x11af,0x11af,0x11af,0x11af,0x11b5,
+0x11af,0x11b5,0x11af,0x11af,0x11af,0x11b5,0x11b5,0x147,0x11b8,0x11b8,0x11b8,0x11b8,0x11b8,0x11b8,0x11b8,0x11b8,
+0x11b8,0x11b8,0x11b8,0x11b8,0x11b8,0x11b8,0x11b8,0x11b8,0x11b8,0x11b8,0x11b8,0x11b8,0x11b8,0x11b8,0x14a,0x14a,
+0x14a,0x14a,0x14a,0x14a,0x14a,0x14a,0x14a,0x14a,0x11d3,0x11d3,0x11d3,0x11d3,0x11d3,0x11d3,0x11d3,0x11d3,
+0x11d3,0x11d3,0x11d3,0x11d3,0x11d3,0x11d3,0x11d3,0x11d3,0x11d3,0x11d3,0x11d3,0x11d3,0x11d3,0x11d0,0x11bb,0x11d0,
+0x11bb,0x11bb,0x11bb,0x11bb,0x11bb,0x11bb,0x11bb,0x14d,0x11c4,0x11cd,0x11bb,0x11cd,0x11cd,0x11bb,0x11bb,0x11bb,
+0x11bb,0x11bb,0x11bb,0x11bb,0x11bb,0x11d0,0x11d0,0x11d0,0x11d0,0x11d0,0x11d0,0x11bb,0x11bb,0x11c1,0x11c1,0x11c1,
+0x11c1,0x11c1,0x11c1,0x11c1,0x11c1,0x14d,0x14d,0x11be,0x11ca,0x11ca,0x11ca,0x11ca,0x11ca,0x11ca,0x11ca,0x11ca,
+0x11ca,0x11ca,0x14d,0x14d,0x14d,0x14d,0x14d,0x14d,0x11ca,0x11ca,0x11ca,0x11ca,0x11ca,0x11ca,0x11ca,0x11ca,
+0x11ca,0x11ca,0x14d,0x14d,0x14d,0x14d,0x14d,0x14d,0x11c7,0x11c7,0x11c7,0x11c7,0x11c7,0x11c7,0x11c7,0x11d6,
+0x11d9,0x11d9,0x11d9,0x11d9,0x11c7,0x11c7,0x14d,0x14d,0x15c0,0x15c0,0x15c0,0x15c0,0x15c0,0x15c0,0x15c0,0x15c0,
+0x15c0,0x15c0,0x15c0,0x15c0,0x15c0,0x15c0,0x15bd,0x1adf,0x1329,0x1302,0x1320,0x1320,0x1320,0x1320,0x1320,0x1320,
+0x1320,0x1308,0x1305,0x12fc,0x12fc,0x1326,0x12fc,0x12fc,0x12fc,0x12fc,0x130b,0x14eb,0x14f1,0x14ee,0x14ee,0x193b,
+0x1716,0x1716,0x1aac,0x150,0x150,0x150,0x150,0x150,0x11ee,0x11ee,0x11ee,0x11ee,0x11ee,0x11ee,0x11ee,0x11ee,
+0x11ee,0x11ee,0x11ee,0x11ee,0x11ee,0x11ee,0x11ee,0x11ee,0x11e5,0x11e5,0x11e8,0x11f1,0x11eb,0x11eb,0x11eb,0x11f1,
+0x153,0x153,0x153,0x153,0x153,0x153,0x153,0x153,0x12ea,0x12ea,0x12ea,0x12ea,0x12ea,0x12ea,0x12ea,0x12ea,
+0x12ea,0x12ea,0x12ea,0x12ea,0x12ea,0x12ea,0x12ea,0x12ea,0x12ea,0x12ea,0x12ea,0x12ea,0x12ea,0x12ea,0x12ea,0x12ea,
+0x12ea,0x12ea,0x12ea,0x12ea,0x12ea,0x159,0x159,0x159,0x120f,0x1203,0x1203,0x1203,0x1203,0x1203,0x1203,0x1206,
+0x1215,0x1215,0x1203,0x1203,0x1203,0x1203,0x15c,0x131a,0x1209,0x1209,0x1209,0x1209,0x1209,0x1209,0x1209,0x1209,
+0x1209,0x1209,0x15c,0x15c,0x15c,0x15c,0x1203,0x1203,0x1233,0x1227,0x1233,0x15f,0x15f,0x15f,0x15f,0x15f,
+0x15f,0x15f,0x15f,0x15f,0x15f,0x15f,0x15f,0x15f,0x15f,0x15f,0x15f,0x15f,0x15f,0x15f,0x15f,0x15f,
+0x15f,0x15f,0x15f,0x1230,0x1230,0x1236,0x122a,0x122d,0x124b,0x124b,0x124b,0x1245,0x1245,0x123c,0x1245,0x1245,
+0x123c,0x1245,0x1245,0x124e,0x1248,0x123f,0x162,0x162,0x1242,0x1242,0x1242,0x1242,0x1242,0x1242,0x1242,0x1242,
+0x1242,0x1242,0x162,0x162,0x162,0x162,0x162,0x162,0x1254,0x1254,0x1254,0x1254,0x1254,0x1254,0x1254,0x165,
+0x165,0x165,0x165,0x1251,0x1251,0x1251,0x1251,0x1251,0x1251,0x1251,0x1251,0x1251,0x1251,0x1251,0x1251,0x1251,
+0x1251,0x1251,0x1251,0x1251,0x1251,0x1251,0x1251,0x1251,0x1251,0x1251,0x1251,0x1251,0x1251,0x1251,0x1251,0x1251,
+0x165,0x165,0x165,0x165,0x125d,0x125d,0x125d,0x125d,0x125d,0x125d,0x125d,0x125d,0x125d,0x125d,0x125d,0x125d,
+0x125d,0x125d,0x125d,0x125d,0x125d,0x125d,0x125d,0x125d,0x125d,0x125d,0x168,0x125a,0x1257,0x1257,0x1257,0x1257,
+0x1257,0x1257,0x1257,0x1257,0x126c,0x126c,0x126c,0x126c,0x126c,0x126c,0x126c,0x126c,0x126c,0x126c,0x126c,0x126c,
+0x126c,0x126c,0x126c,0x126c,0x126c,0x126c,0x126c,0x126c,0x126c,0x126c,0x16b,0x16b,0x16b,0x1266,0x1269,0x1269,
+0x1269,0x1269,0x1269,0x1269,0x1272,0x1272,0x1272,0x1272,0x1272,0x1272,0x1272,0x1272,0x1272,0x1272,0x1272,0x1272,
+0x1272,0x1272,0x1272,0x1272,0x1272,0x1272,0x1272,0x1272,0x1272,0x1272,0x16e,0x16e,0x126f,0x126f,0x126f,0x126f,
+0x126f,0x126f,0x126f,0x126f,0x1278,0x1278,0x1278,0x1278,0x1278,0x1278,0x1278,0x1278,0x1278,0x1278,0x1278,0x1278,
+0x1278,0x1278,0x1278,0x1278,0x1278,0x1278,0x1278,0x171,0x171,0x171,0x171,0x171,0x1275,0x1275,0x1275,0x1275,
+0x1275,0x1275,0x1275,0x1275,0x127e,0x127e,0x127e,0x127e,0x127e,0x127e,0x127e,0x127e,0x127e,0x127e,0x127e,0x127e,
+0x127e,0x127e,0x127e,0x127e,0x127e,0x127e,0x127e,0x127e,0x127e,0x127e,0x127e,0x127e,0x127e,0x127e,0x127e,0x127e,
+0x127e,0x127e,0x127e,0x177,0x1299,0x1299,0x17a,0x17a,0x17a,0x17a,0x17a,0x17a,0x17a,0x17a,0x17a,0x17a,
+0x17a,0x197d,0x17a,0x17a,0x14ca,0x14ca,0x14ca,0x14ca,0x14ca,0x14ca,0x14ca,0x14ca,0x14ca,0x14ca,0x14ca,0x14ca,
+0x14ca,0x14ca,0x14ca,0x14ca,0x129f,0x129f,0x129f,0x129f,0x129f,0x129f,0x129f,0x129f,0x129f,0x129f,0x129f,0x129f,
+0x129f,0x129f,0x129f,0x17d,0x1a4f,0x1a4f,0x1a4f,0x1a4f,0x1a4f,0x1a4f,0x1a4f,0x1a52,0x1a4c,0x279,0x279,0x279,
+0x279,0x279,0x279,0x279,0x187e,0x187e,0x187e,0x187e,0x187e,0x187e,0x187e,0x187e,0x187e,0x187e,0x187e,0x187e,
+0x187e,0x1ad0,0x180,0x180,0x180,0x180,0x180,0x180,0x180,0x180,0x180,0x180,0x180,0x180,0x180,0x180,
+0x180,0x180,0x180,0x180,0x180,0x180,0x180,0x180,0x180,0x180,0x180,0x180,0x180,0x180,0x180,0x180,
+0x180,0x180,0x180,0x180,0x180,0x180,0x138c,0x138c,0x138c,0x138c,0x138c,0x138c,0x138c,0x138c,0x138c,0x138c,
+0x138c,0x138c,0x138c,0x138c,0x138c,0x138c,0x138c,0x138c,0x138c,0x138c,0x138c,0x138c,0x138c,0x138c,0x138c,0x138c,
+0x12f6,0x13f5,0x13f2,0x183,0x183,0x183,0x183,0x183,0x183,0x183,0x183,0x183,0x183,0x183,0x183,0x183,
+0x12f0,0x12f0,0x12f0,0x12f0,0x12f0,0x12f0,0x12f0,0x12f0,0x12f0,0x12f0,0x12f3,0x12f0,0x12f0,0x12f0,0x12f0,0x12f0,
+0x12f0,0x12f0,0x12f0,0x12f0,0x12f0,0x12f0,0x12f0,0x12f0,0x12f0,0x12f0,0x12f0,0x12f3,0x12f0,0x12f0,0x13f5,0x13f5,
+0x13f5,0x13f5,0x13f5,0x13f2,0x13f5,0x13f5,0x13f5,0x1881,0x183,0x183,0x183,0x183,0x12ed,0x12ed,0x12ed,0x12ed,
+0x12ed,0x12ed,0x12ed,0x12ed,0x12ed,0x183,0x183,0x183,0x183,0x183,0x183,0x183,0x1419,0x1419,0x183,0x183,
+0x183,0x183,0x183,0x183,0x183,0x183,0x183,0x183,0x183,0x183,0x183,0x183,0x1920,0x1920,0x1920,0x1920,
+0x1920,0x1920,0x183,0x183,0x183,0x183,0x183,0x183,0x183,0x183,0x183,0x183,0x183,0x183,0x183,0x183,
+0x183,0x183,0x183,0x183,0x183,0x183,0x183,0x183,0x183,0x183,0x183,0x183,0x183,0x183,0x183,0x183,
+0x183,0x183,0x183,0x183,0x1395,0x1395,0x1395,0x1395,0x1395,0x1395,0x1395,0x1395,0x1395,0x1395,0x1395,0x1395,
+0x1395,0x1395,0x1395,0x1395,0x1395,0x1395,0x1395,0x1395,0x1395,0x1395,0x1395,0x1395,0x1395,0x138f,0x138f,0x138f,
+0x186,0x186,0x1392,0x186,0x13a7,0x13a7,0x13a7,0x13a7,0x13a7,0x13a7,0x1398,0x13a1,0x139b,0x139b,0x13a1,0x13a1,
+0x13a1,0x139b,0x13a1,0x139b,0x139b,0x139b,0x13a4,0x13a4,0x189,0x189,0x189,0x189,0x189,0x189,0x189,0x189,
+0x139e,0x139e,0x139e,0x139e,0x18c,0x13aa,0x13aa,0x13aa,0x13aa,0x13aa,0x13aa,0x18c,0x18c,0x13aa,0x13aa,0x13aa,
+0x13aa,0x13aa,0x13aa,0x18c,0x18c,0x13aa,0x13aa,0x13aa,0x13aa,0x13aa,0x13aa,0x18c,0x18c,0x18c,0x18c,0x18c,
+0x18c,0x18c,0x18c,0x18c,0x13aa,0x13aa,0x13aa,0x13aa,0x13aa,0x13aa,0x13aa,0x18c,0x13aa,0x13aa,0x13aa,0x13aa,
+0x13aa,0x13aa,0x13aa,0x18c,0x161d,0x161d,0x161d,0x161d,0x161d,0x161d,0x161d,0x161d,0x161d,0x161d,0x161d,0x161d,
+0x161d,0x161d,0x161d,0x161d,0x13ad,0x13ad,0x13ad,0x13ad,0x13ad,0x13ad,0x13b0,0x13c2,0x13c2,0x13b6,0x13b6,0x13b6,
+0x13b6,0x13b6,0x18f,0x18f,0x18f,0x18f,0x13b3,0x13b3,0x13b3,0x13b3,0x13b3,0x13b3,0x13b3,0x13b3,0x13b3,0x13b3,
+0x13b3,0x13b3,0x13b3,0x13b3,0x13b3,0x13b3,0x13b9,0x13b9,0x13b9,0x13b9,0x13b9,0x13b9,0x13b9,0x13b9,0x13b9,0x13b9,
+0x18f,0x18f,0x18f,0x18f,0x18f,0x18f,0x18f,0x18f,0x18f,0x18f,0x18f,0x18f,0x18f,0x18f,0x18f,0x1584,
+0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,
+0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x192,0x192,0x192,0x192,0x192,0x192,0x192,
+0x13c8,0x13c8,0x13c8,0x13c8,0x13c8,0x13c8,0x13c8,0x13c8,0x13c8,0x13c8,0x13c8,0x13c8,0x13c8,0x13c8,0x13c8,0x195,
+0x195,0x13c8,0x13c8,0x13c8,0x13c8,0x13c8,0x13c8,0x13c8,0x13c8,0x13c8,0x13c8,0x13c8,0x13c8,0x13c8,0x13c8,0x1587,
+0x195,0x13c8,0x13c8,0x13c8,0x13c8,0x13c8,0x13c8,0x13c8,0x13c8,0x13c8,0x13c8,0x13c8,0x13c8,0x13c8,0x13c8,0x13fe,
+0x195,0x13c8,0x13c8,0x13c8,0x13c8,0x13c8,0x13c8,0x13c8,0x13c8,0x13c8,0x13c8,0x13c8,0x13c8,0x13c8,0x13c8,0x13c8,
+0x1587,0x1587,0x1587,0x1587,0x1587,0x1587,0x1587,0x1587,0x1587,0x1587,0x1587,0x1587,0x1587,0x1587,0x1587,0x1587,
+0x1587,0x1587,0x1587,0x1587,0x1587,0x1587,0x195,0x195,0x195,0x195,0x195,0x195,0x195,0x195,0x195,0x195,
+0x1413,0x1410,0x1410,0x1410,0x1410,0x1410,0x159c,0x159c,0x159c,0x159c,0x159c,0x159f,0x170d,0x159f,0x159f,0x159f,
+0x17d9,0x188a,0x188a,0x18c3,0x18c3,0x1a8e,0x1b39,0x1b39,0x198,0x198,0x198,0x198,0x198,0x198,0x198,0x198,
+0x159f,0x159f,0x159f,0x159f,0x159f,0x159f,0x159c,0x159c,0x159c,0x159f,0x159c,0x170a,0x170a,0x198,0x198,0x198,
+0x159f,0x159c,0x159c,0x159f,0x188a,0x188a,0x188a,0x1926,0x1926,0x1a07,0x1a8e,0x1b39,0x1b39,0x198,0x198,0x198,
+0x13cb,0x13cb,0x13cb,0x13cb,0x13cb,0x13cb,0x13cb,0x13cb,0x13cb,0x13cb,0x13cb,0x13cb,0x13cb,0x13cb,0x13cb,0x13cb,
+0x13cb,0x13cb,0x13cb,0x13cb,0x19b,0x19b,0x19b,0x19b,0x19b,0x19b,0x19b,0x19b,0x19b,0x19b,0x19b,0x19b,
+0x1467,0x15a5,0x1467,0x1467,0x1467,0x1467,0x1467,0x1467,0x1467,0x1467,0x1467,0x1467,0x1467,0x15a5,0x15a5,0x15a5,
+0x15a5,0x15a5,0x15a5,0x175e,0x175e,0x19e,0x1809,0x1809,0x1809,0x1809,0x1809,0x1809,0x1809,0x1809,0x1ad3,0x1ad3,
+0x1ad3,0x1ad3,0x1ad3,0x1ad3,0x1ad3,0x1ad3,0x1ad3,0x1ad3,0x19e,0x19e,0x19e,0x19e,0x19e,0x19e,0x19e,0x19e,
+0x19e,0x19e,0x19e,0x1983,0x1806,0x1806,0x1806,0x1806,0x1806,0x1806,0x1806,0x1806,0x1806,0x1806,0x1806,0x1806,
+0x146d,0x146d,0x146d,0x146d,0x1a1,0x146d,0x146d,0x146d,0x146d,0x146d,0x146d,0x146d,0x146d,0x146d,0x146d,0x146d,
+0x146d,0x146d,0x146d,0x146d,0x146d,0x146d,0x146d,0x146d,0x146d,0x146d,0x146d,0x146d,0x146d,0x146d,0x146d,0x146d,
+0x1a1,0x146d,0x146d,0x1a1,0x146d,0x1a1,0x1a1,0x146d,0x1a1,0x146d,0x146d,0x146d,0x146d,0x146d,0x146d,0x146d,
+0x146d,0x146d,0x146d,0x1a1,0x146d,0x146d,0x146d,0x146d,0x1a1,0x146d,0x1a1,0x146d,0x1a1,0x1a1,0x1a1,0x1a1,
+0x1a1,0x1a1,0x146d,0x1a1,0x1a1,0x1a1,0x1a1,0x146d,0x1a1,0x146d,0x1a1,0x146d,0x1a1,0x146d,0x146d,0x146d,
+0x1a1,0x146d,0x146d,0x1a1,0x146d,0x1a1,0x1a1,0x146d,0x1a1,0x146d,0x1a1,0x146d,0x1a1,0x146d,0x1a1,0x146d,
+0x1a1,0x146d,0x146d,0x1a1,0x146d,0x1a1,0x1a1,0x146d,0x146d,0x146d,0x146d,0x1a1,0x146d,0x146d,0x146d,0x146d,
+0x146d,0x146d,0x146d,0x1a1,0x146d,0x146d,0x146d,0x146d,0x1a1,0x146d,0x146d,0x146d,0x146d,0x1a1,0x146d,0x1a1,
+0x146d,0x146d,0x146d,0x146d,0x146d,0x146d,0x146d,0x146d,0x146d,0x146d,0x1a1,0x146d,0x146d,0x146d,0x146d,0x146d,
+0x146d,0x146d,0x146d,0x146d,0x146d,0x146d,0x146d,0x146d,0x146d,0x146d,0x146d,0x146d,0x1a1,0x1a1,0x1a1,0x1a1,
+0x1a1,0x146d,0x146d,0x146d,0x1a1,0x146d,0x146d,0x146d,0x146d,0x146d,0x1a1,0x146d,0x146d,0x146d,0x146d,0x146d,
+0x146d,0x146d,0x146d,0x146d,0x146d,0x146d,0x146d,0x146d,0x146d,0x146d,0x146d,0x146d,0x1a1,0x1a1,0x1a1,0x1a1,
+0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,
+0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x146a,0x146a,0x1a1,0x1a1,
+0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1482,0x1482,0x1482,0x1482,
+0x1482,0x1482,0x1482,0x1470,0x1470,0x1470,0x1470,0x1470,0x147f,0x1470,0x1473,0x1473,0x1470,0x1470,0x1470,0x1476,
+0x1476,0x1a4,0x147c,0x147c,0x147c,0x147c,0x147c,0x147c,0x147c,0x147c,0x147c,0x147c,0x1479,0x1485,0x1485,0x1485,
+0x1989,0x1986,0x1986,0x1ad6,0x1a4,0x1a4,0x1a4,0x1a4,0x1a4,0x1a4,0x1a4,0x1a4,0x162f,0x162f,0x162f,0x162f,
+0x162f,0x162f,0x162f,0x162f,0x162f,0x162f,0x162f,0x162f,0x162f,0x162f,0x162f,0x162f,0x1491,0x1491,0x1491,0x1491,
+0x1491,0x1491,0x1491,0x1491,0x1491,0x1491,0x1491,0x148e,0x1488,0x1488,0x148e,0x148e,0x1497,0x1497,0x1491,0x1494,
+0x1494,0x148e,0x148b,0x1a7,0x1a7,0x1a7,0x1a7,0x1a7,0x1a7,0x1a7,0x1a7,0x1a7,0x149a,0x149a,0x149a,0x149a,
+0x149a,0x149a,0x149a,0x149a,0x149a,0x149a,0x149a,0x149a,0x149a,0x149a,0x149a,0x149a,0x149a,0x149a,0x149a,0x149a,
+0x149a,0x149a,0x149a,0x149a,0x1aa,0x1aa,0x1aa,0x1aa,0x1761,0x1761,0x149a,0x149a,0x1761,0x1761,0x1761,0x1761,
+0x1761,0x1761,0x1761,0x1761,0x1761,0x1761,0x1761,0x1761,0x1761,0x1761,0x1761,0x1761,0x1aa,0x1aa,0x1761,0x1761,
+0x1761,0x1761,0x1761,0x1761,0x1761,0x1761,0x1761,0x1761,0x1761,0x1761,0x1761,0x1761,0x14a6,0x14a6,0x14a6,0x14a6,
+0x14a6,0x1a37,0x1a37,0x1a37,0x1a37,0x1a37,0x1a37,0x1ad,0x1ad,0x1ad,0x1ad,0x1a31,0x14a6,0x14a3,0x14a3,0x14a3,
+0x14a3,0x14a3,0x14a3,0x14a3,0x14a3,0x14a3,0x14a3,0x14a3,0x14a3,0x14a3,0x14a3,0x14a3,0x1a34,0x1a34,0x1a34,0x1a34,
+0x1a34,0x1a34,0x1a34,0x1a34,0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,0x14a0,0x14a0,0x14a0,0x14a0,0x14a9,
+0x14a9,0x14a9,0x14a9,0x14a9,0x14a9,0x14a9,0x14a9,0x14a9,0x14a9,0x14a9,0x14a9,0x14a9,0x14ca,0x14ca,0x14ca,0x14ca,
+0x14ca,0x14ca,0x14ca,0x14ca,0x14ca,0x1b0,0x1b0,0x1b0,0x1b0,0x1b0,0x1b0,0x1b0,0x14c7,0x14c7,0x14c7,0x14c7,
+0x14c7,0x14c7,0x14c7,0x14c7,0x14c7,0x14c7,0x1b0,0x1b0,0x1b0,0x1b0,0x1b0,0x1b0,0x14cd,0x14cd,0x14cd,0x14cd,
+0x14cd,0x14cd,0x14cd,0x14cd,0x1b3,0x1b3,0x1b3,0x1b3,0x1b3,0x1b3,0x1b3,0x1b3,0x1323,0x1320,0x1323,0x12ff,
+0x1320,0x1326,0x1326,0x1329,0x1326,0x1329,0x132c,0x1320,0x1329,0x1329,0x1320,0x1320,0x14df,0x14df,0x14df,0x14df,
+0x14df,0x14df,0x14df,0x14df,0x14df,0x14df,0x14df,0x14d0,0x14d9,0x14d0,0x14d9,0x14d9,0x14d0,0x14d0,0x14d0,0x14d0,
+0x14d0,0x14d0,0x14dc,0x14d3,0x1a3a,0x1b6,0x1b6,0x1b6,0x1b6,0x1b6,0x1b6,0x1b6,0x15b1,0x15b1,0x15b1,0x15b1,
+0x15b1,0x15b1,0x15b1,0x15b1,0x15b1,0x15b1,0x15b1,0x15b1,0x15b1,0x15b1,0x1b9,0x1b9,0x15ae,0x15ae,0x15ae,0x15ae,
+0x15ae,0x15b4,0x1b9,0x1b9,0x1b9,0x1b9,0x1b9,0x1b9,0x1b9,0x1b9,0x1b9,0x1b9,0x1719,0x1710,0x1710,0x1710,
 0x1710,0x1710,0x1710,0x1710,0x1710,0x1710,0x1710,0x1710,0x1710,0x1710,0x1710,0x1710,0x1710,0x1710,0x1710,0x1710,
-0x1710,0x1710,0x1710,0x1710,0x1710,0x1710,0x1710,0x1710,0x1719,0x1719,0x1719,0x1719,0x1719,0x1719,0x1719,0x1719,
-0x1719,0x1719,0x1719,0x1719,0x1719,0x1719,0x1719,0x1719,0x1719,0x1719,0x1719,0x1719,0x1719,0x1719,0x1719,0x1719,
-0x1719,0x1719,0x1719,0x1719,0x1719,0x1719,0x1719,0x1719,0x1719,0x1719,0x1719,0x171c,0x171c,0x171c,0x171c,0x1719,
-0x1719,0x1719,0x1719,0x1719,0x1719,0x1719,0x1719,0x1719,0x1719,0x1719,0x1719,0x1719,0x1719,0x171c,0x171c,0x171c,
-0x171c,0x171c,0x171c,0x171c,0x171c,0x1719,0x171c,0x171c,0x171c,0x171c,0x171c,0x171c,0x171c,0x171c,0x171c,0x171c,
-0x171c,0x171c,0x171c,0x171c,0x171c,0x171c,0x171c,0x171c,0x171c,0x171c,0x171c,0x171c,0x171c,0x171c,0x171c,0x171c,
-0x171c,0x171c,0x171c,0x171c,0x171c,0x171c,0x171c,0x171c,0x1728,0x1728,0x1728,0x1728,0x1728,0x1728,0x1728,0x1728,
-0x1728,0x1728,0x1728,0x1728,0x1728,0x1728,0x1728,0x1728,0x1728,0x1728,0x1728,0x1728,0x1728,0x1728,0x1728,0x1728,
-0x1728,0x1728,0x1728,0x1728,0x1728,0x1728,0x1728,0x1728,0,0,0,0
+0x1710,0x1710,0x1710,0x1710,0x1710,0x1710,0x1710,0x1710,0x1bf,0x1bf,0x1bf,0x1bf,0x1adf,0x1c2,0x1c2,0x1c2,
+0x1c2,0x1c2,0x1c2,0x1c2,0x1c2,0x1c2,0x1c2,0x1c2,0x1c2,0x1c2,0x1c2,0x1c2,0x1c2,0x1c2,0x1c2,0x1c2,
+0x1c2,0x1c2,0x1c2,0x1c2,0x1c2,0x1c2,0x1c2,0x1c2,0x1c2,0x1c2,0x1c2,0x1c2,0x1c2,0x1c2,0x1c2,0x1c2,
+0x15cc,0x15cc,0x15cc,0x15cc,0x15cc,0x15cc,0x15cc,0x15cc,0x15cc,0x15cc,0x15cc,0x1c5,0x1c5,0x1c5,0x1c5,0x1c5,
+0x15cc,0x15cc,0x15cc,0x15cc,0x15cc,0x15cc,0x15cc,0x15cc,0x15cc,0x15cc,0x15cc,0x15cc,0x15cc,0x1c5,0x1c5,0x1c5,
+0x1c5,0x1c5,0x1c5,0x1c5,0x15cc,0x15cc,0x15cc,0x15cc,0x15cc,0x15cc,0x15cc,0x15cc,0x15cc,0x15cc,0x1c5,0x1c5,
+0x15c9,0x15c3,0x15c6,0x15cf,0x15d2,0x15d2,0x15d2,0x15d2,0x15d2,0x15d2,0x15d2,0x15d2,0x1c8,0x1c8,0x1c8,0x1c8,
+0x1c8,0x1c8,0x1c8,0x1c8,0x15ba,0x15ba,0x15ba,0x15ba,0x15ba,0x15ba,0x15ba,0x15ba,0x15ba,0x15ba,0x15ba,0x15ba,
+0x15ba,0x15ba,0x15ba,0x15ba,0x15d5,0x15d5,0x15d5,0x15d5,0x15d5,0x15d5,0x15d5,0x15d5,0x15d5,0x15d5,0x15d5,0x15d5,
+0x15d5,0x15d5,0x15d5,0x15d5,0x15d5,0x15d5,0x15d5,0x15d5,0x15d5,0x198c,0x198c,0x198c,0x198c,0x1cb,0x1cb,0x1cb,
+0x1cb,0x1cb,0x1cb,0x1cb,0x1a91,0x1a91,0x1a91,0x1a91,0x1a91,0x1a91,0x1a91,0x1a91,0x1a91,0x1a91,0x1a91,0x1a91,
+0x1cb,0x1cb,0x1cb,0x1cb,0x1cb,0x1cb,0x1cb,0x1cb,0x1cb,0x1cb,0x1cb,0x1cb,0x1cb,0x1cb,0x1cb,0x1cb,
+0x1cb,0x1cb,0x1cb,0x1cb,0x1776,0x171c,0x15de,0x1722,0x1ce,0x15e7,0x15e7,0x15e7,0x15e7,0x15e7,0x15e7,0x15e7,
+0x15e7,0x1ce,0x1ce,0x15e7,0x15e7,0x1ce,0x1ce,0x15e7,0x15e7,0x15e7,0x15e7,0x15e7,0x15e7,0x15e7,0x15e7,0x15e7,
+0x15e7,0x15e7,0x15e7,0x15e7,0x15e7,0x1ce,0x15e7,0x15e7,0x15e7,0x15e7,0x15e7,0x15e7,0x15e7,0x1ce,0x15e7,0x15e7,
+0x1ce,0x15e7,0x15e7,0x15e7,0x15e7,0x15e7,0x1ce,0x1a16,0x171f,0x15e7,0x15d8,0x15de,0x15d8,0x15de,0x15de,0x15de,
+0x15de,0x1ce,0x1ce,0x15de,0x15de,0x1ce,0x1ce,0x15e1,0x15e1,0x15e4,0x1ce,0x1ce,0x1779,0x1ce,0x1ce,0x1ce,
+0x1ce,0x1ce,0x1ce,0x15d8,0x1ce,0x1ce,0x1ce,0x1ce,0x1ce,0x15ea,0x15e7,0x15e7,0x15e7,0x15e7,0x15de,0x15de,
+0x1ce,0x1ce,0x15db,0x15db,0x15db,0x15db,0x15db,0x15db,0x15db,0x1ce,0x1ce,0x1ce,0x15db,0x15db,0x15db,0x15db,
+0x15db,0x1ce,0x1ce,0x1ce,0x1ce,0x1ce,0x1ce,0x1ce,0x1ce,0x1ce,0x1ce,0x1ce,0x15ff,0x15ff,0x15ff,0x15ff,
+0x15ff,0x15ff,0x15ff,0x15ff,0x15ff,0x15ff,0x15ff,0x15ff,0x15ff,0x15ff,0x15ff,0x15ff,0x15ff,0x15ff,0x1d1,0x15ff,
+0x15ff,0x15ff,0x15ff,0x15ff,0x15ff,0x15ff,0x15ff,0x15ff,0x15ff,0x15ff,0x15ff,0x15ff,0x15f9,0x15f9,0x15f9,0x15ed,
+0x15ed,0x15ed,0x15f9,0x15f9,0x15ed,0x15fc,0x15f0,0x15ed,0x1602,0x1602,0x15f6,0x1602,0x1602,0x15f3,0x180c,0x1d1,
+0x1611,0x1611,0x1611,0x1605,0x1605,0x1605,0x1605,0x1605,0x1605,0x1608,0x160b,0x1d4,0x1d4,0x1d4,0x1d4,0x1d4,
+0x160e,0x160e,0x160e,0x160e,0x160e,0x160e,0x160e,0x160e,0x160e,0x160e,0x1d4,0x1d4,0x1d4,0x1d4,0x1d4,0x1d4,
+0x177c,0x177c,0x177c,0x177c,0x161d,0x161a,0x1a3d,0x1a3d,0x1ae5,0x1ae8,0x1ae2,0x1ae2,0x1d7,0x1d7,0x1d7,0x1d7,
+0x17a6,0x17a6,0x17a6,0x17a6,0x17a6,0x17a6,0x17a6,0x17a6,0x17a6,0x17a6,0x17a6,0x17a6,0x17a6,0x17a6,0x17a6,0x17a6,
+0x1623,0x1623,0x1623,0x1623,0x1623,0x1623,0x1623,0x1623,0x1623,0x1623,0x1623,0x1623,0x1623,0x1623,0x1623,0x1623,
+0x1623,0x1623,0x1623,0x1623,0x1623,0x1623,0x1623,0x1da,0x1da,0x1da,0x1da,0x1da,0x1da,0x1da,0x1da,0x1da,
+0x1623,0x1623,0x1623,0x1623,0x1623,0x1623,0x1623,0x1623,0x1623,0x1623,0x1623,0x1623,0x1623,0x1623,0x1623,0x1623,
+0x1623,0x1623,0x1623,0x1623,0x1623,0x1623,0x1da,0x1da,0x1da,0x1da,0x1da,0x1da,0x1da,0x1da,0x1da,0x1da,
+0x1623,0x1623,0x1623,0x1623,0x1623,0x1623,0x1623,0x1623,0x1da,0x1da,0x1da,0x1da,0x1da,0x1da,0x1da,0x1da,
+0x1da,0x1da,0x1da,0x1da,0x1da,0x1da,0x1da,0x1da,0x1da,0x1da,0x1da,0x1da,0x1da,0x1da,0x1da,0x1da,
+0x162f,0x162f,0x162f,0x162f,0x162f,0x162f,0x162f,0x162f,0x162f,0x162f,0x162f,0x162f,0x162f,0x162f,0x162f,0x162f,
+0x162f,0x162f,0x162f,0x1626,0x1629,0x162c,0x162f,0x1dd,0x1dd,0x1dd,0x1dd,0x1dd,0x1dd,0x1dd,0x1dd,0x1dd,
+0x163e,0x163e,0x163e,0x163e,0x163e,0x1632,0x1632,0x1e0,0x1e0,0x1e0,0x1e0,0x1635,0x1635,0x1635,0x1635,0x1635,
+0x163b,0x163b,0x163b,0x163b,0x163b,0x163b,0x1638,0x1e0,0x1e0,0x1e0,0x1e0,0x1e0,0x1e0,0x1e0,0x1e0,0x1e0,
+0x1647,0x1647,0x1647,0x1647,0x1647,0x1e3,0x1e3,0x1644,0x1644,0x1644,0x1644,0x1644,0x1644,0x1644,0x1644,0x1644,
+0x1641,0x1641,0x1641,0x1641,0x1641,0x1641,0x1641,0x1e3,0x1e3,0x1e3,0x1e3,0x1e3,0x1e3,0x1e3,0x1e3,0x1e3,
+0x164a,0x165c,0x165c,0x1650,0x1659,0x1e6,0x1e6,0x1e6,0x1e6,0x1e6,0x1e6,0x1e6,0x1e6,0x1e6,0x1e6,0x1e6,
+0x1653,0x1653,0x1653,0x1653,0x1653,0x1653,0x1653,0x1653,0x1653,0x1653,0x1e6,0x1e6,0x1e6,0x1e6,0x1e6,0x1e6,
+0x1662,0x1662,0x1662,0x1662,0x1662,0x1662,0x1662,0x1662,0x1662,0x1662,0x1662,0x1662,0x1662,0x1662,0x1662,0x1662,
+0x1662,0x1662,0x1662,0x1662,0x1662,0x1662,0x1662,0x1662,0x1662,0x1662,0x1662,0x1662,0x1662,0x1662,0x1662,0x1e9,
+0x166e,0x166e,0x166e,0x166e,0x166e,0x1668,0x1671,0x166e,0x166e,0x166e,0x166e,0x166e,0x166e,0x166e,0x166e,0x166e,
+0x166b,0x166b,0x166b,0x166b,0x166b,0x166b,0x166b,0x166b,0x166b,0x166b,0x166e,0x166e,0x166e,0x166e,0x166e,0x1ec,
+0x1677,0x1677,0x1677,0x1677,0x1677,0x1677,0x1677,0x1677,0x1677,0x1677,0x1677,0x1677,0x1677,0x1677,0x1677,0x1677,
+0x1677,0x1677,0x1677,0x1677,0x1677,0x1677,0x1677,0x1677,0x1677,0x1677,0x1677,0x1677,0x1677,0x1677,0x1677,0x1ef,
+0x1683,0x1683,0x1683,0x1683,0x1683,0x1683,0x1683,0x1683,0x1683,0x1683,0x1683,0x1683,0x1683,0x1683,0x1683,0x1683,
+0x1683,0x1683,0x1683,0x1683,0x1683,0x1683,0x1680,0x1680,0x1680,0x1680,0x1680,0x1f2,0x1f2,0x1f2,0x1f2,0x1f2,
+0x169b,0x169b,0x169e,0x169e,0x16a1,0x1692,0x1f5,0x1f5,0x1f5,0x1f5,0x1f5,0x1f5,0x1f5,0x1f5,0x1f5,0x1f5,
+0x1698,0x1698,0x1698,0x1698,0x1698,0x1698,0x1698,0x1698,0x1698,0x1698,0x1f5,0x1692,0x1692,0x1692,0x1692,0x1692,
+0x1692,0x1692,0x1f5,0x169b,0x169b,0x169b,0x169b,0x169b,0x169b,0x169b,0x169b,0x169b,0x169b,0x169b,0x169b,0x169b,
+0x169b,0x169b,0x169b,0x169b,0x169b,0x169b,0x169b,0x169b,0x1f5,0x1f5,0x1f5,0x1f5,0x1f5,0x169b,0x169b,0x169b,
+0x16aa,0x16aa,0x16aa,0x16aa,0x16aa,0x16aa,0x16aa,0x16aa,0x16aa,0x16aa,0x16aa,0x16aa,0x16aa,0x16aa,0x16aa,0x16aa,
+0x16aa,0x16aa,0x16aa,0x16aa,0x16aa,0x16aa,0x16aa,0x16aa,0x16aa,0x1f8,0x1f8,0x1f8,0x1f8,0x1f8,0x1f8,0x1f8,
+0x16b3,0x16b3,0x16b3,0x16b3,0x16b3,0x16b3,0x16b3,0x16b3,0x16b3,0x16b3,0x16b3,0x16b3,0x16b3,0x16b3,0x16b3,0x16b3,
+0x16b3,0x16b3,0x1fb,0x1fb,0x1fb,0x1fb,0x1fb,0x1fb,0x1fb,0x16b0,0x16b0,0x16b0,0x16b0,0x1fb,0x1fb,0x1fb,
+0x16ce,0x16ce,0x16ce,0x16ce,0x16ce,0x16ce,0x16ce,0x16ce,0x16ce,0x16ce,0x16ce,0x16ce,0x16ce,0x16ce,0x16ce,0x16b6,
+0x16c8,0x16c8,0x16b6,0x16b6,0x16b6,0x16b6,0x201,0x201,0x16c8,0x16c8,0x16cb,0x16cb,0x16b6,0x16b6,0x16c8,0x16bc,
+0x16b9,0x16bf,0x16d1,0x16d1,0x16c2,0x16c2,0x16c5,0x16c5,0x16c5,0x16d1,0x1785,0x1785,0x1785,0x1785,0x1785,0x1785,
+0x1785,0x1785,0x1785,0x1785,0x1785,0x1785,0x1785,0x1785,0x1782,0x1782,0x1782,0x1782,0x177f,0x177f,0x201,0x201,
+0x201,0x201,0x201,0x201,0x201,0x201,0x201,0x201,0x201,0x201,0x201,0x201,0x201,0x201,0x201,0x201,
+0x201,0x201,0x201,0x201,0x201,0x201,0x201,0x201,0x201,0x201,0x201,0x201,0x201,0x201,0x201,0x201,
+0x204,0x16d4,0x16d4,0x16d4,0x16d4,0x16d4,0x16d4,0x16d4,0x16d4,0x16d4,0x16d4,0x16d4,0x16d4,0x16d4,0x16d4,0x16d4,
+0x16d4,0x16d4,0x16d4,0x16d4,0x16d4,0x204,0x204,0x204,0x204,0x204,0x204,0x204,0x204,0x204,0x204,0x204,
+0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x207,0x207,0x207,0x207,
+0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,
+0x207,0x207,0x207,0x207,0x207,0x207,0x207,0x207,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,
+0x16d7,0x16d7,0x207,0x207,0x207,0x207,0x207,0x207,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,
+0x207,0x207,0x207,0x207,0x207,0x207,0x207,0x207,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,
+0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x207,0x207,0x1aeb,0x1aeb,0x207,0x207,
+0x207,0x207,0x207,0x207,0x207,0x207,0x207,0x207,0x207,0x207,0x207,0x207,0x207,0x207,0x207,0x207,
+0x207,0x207,0x207,0x207,0x207,0x207,0x207,0x207,0x207,0x207,0x207,0x207,0x207,0x207,0x207,0x207,
+0x16da,0x16e9,0x16e0,0x16dd,0x16ef,0x16ef,0x16e3,0x16ef,0x20a,0x20a,0x20a,0x20a,0x20a,0x20a,0x20a,0x20a,
+0x16e6,0x16e6,0x16e6,0x16e6,0x16e6,0x16e6,0x16e6,0x16e6,0x16e6,0x16e6,0x20a,0x20a,0x20a,0x20a,0x20a,0x20a,
+0x16f5,0x16f5,0x16f5,0x16f5,0x16f5,0x16f5,0x16f5,0x16f5,0x16f5,0x16f5,0x16f2,0x16f2,0x16f2,0x16f2,0x16f2,0x16f2,
+0x16f2,0x16f2,0x16f2,0x20d,0x20d,0x20d,0x20d,0x20d,0x20d,0x20d,0x20d,0x20d,0x20d,0x20d,0x20d,0x16fb,
+0x1797,0x1797,0x1797,0x1797,0x1797,0x1797,0x1797,0x1797,0x1797,0x1797,0x1797,0x1797,0x1797,0x1797,0x1797,0x1797,
+0x1797,0x1797,0x1797,0x1797,0x1797,0x1797,0x1797,0x1797,0x1797,0x1797,0x198f,0x210,0x210,0x1788,0x1788,0x1788,
+0x1794,0x1794,0x1788,0x1788,0x1788,0x1788,0x1794,0x1788,0x1788,0x1788,0x1788,0x178b,0x210,0x210,0x210,0x210,
+0x1791,0x1791,0x1791,0x1791,0x1791,0x1791,0x1791,0x1791,0x1791,0x1791,0x178e,0x178e,0x179a,0x179a,0x179a,0x178e,
+0x179d,0x179d,0x179d,0x179d,0x179d,0x179d,0x179d,0x213,0x213,0x213,0x213,0x213,0x213,0x213,0x213,0x213,
+0x213,0x213,0x213,0x213,0x213,0x213,0x213,0x213,0x213,0x213,0x213,0x213,0x213,0x213,0x213,0x213,
+0x213,0x213,0x213,0x213,0x213,0x213,0x213,0x213,0x17af,0x17af,0x17af,0x17af,0x17af,0x17af,0x17af,0x17af,
+0x17af,0x17af,0x17af,0x17af,0x17af,0x17af,0x17af,0x17af,0x17af,0x17af,0x17af,0x219,0x17af,0x17af,0x219,0x219,
+0x219,0x219,0x219,0x17ac,0x17ac,0x17ac,0x17ac,0x17ac,0x17b2,0x17b2,0x17b2,0x17b2,0x17b2,0x17b2,0x17b2,0x21c,
+0x17b2,0x21c,0x17b2,0x17b2,0x17b2,0x17b2,0x21c,0x17b2,0x17b2,0x17b2,0x17b2,0x17b2,0x17b2,0x17b2,0x17b2,0x17b2,
+0x17b2,0x17b2,0x17b2,0x17b2,0x17b2,0x17b2,0x21c,0x17b2,0x17b2,0x17b2,0x17b2,0x17b2,0x17b2,0x17b2,0x17b2,0x17b2,
+0x17b2,0x17b5,0x21c,0x21c,0x21c,0x21c,0x21c,0x21c,0x1614,0x1614,0x1614,0x1614,0x1614,0x1614,0x1614,0x1614,
+0x1614,0x1614,0x1614,0x1614,0x1614,0x1614,0x1614,0x1614,0x17be,0x17be,0x17be,0x17be,0x17be,0x17be,0x17be,0x17be,
+0x17be,0x17be,0x17be,0x17be,0x17be,0x17be,0x17be,0x17be,0x17be,0x17be,0x17be,0x21f,0x21f,0x21f,0x21f,0x21f,
+0x21f,0x21f,0x21f,0x21f,0x21f,0x21f,0x21f,0x21f,0x17bb,0x17bb,0x17bb,0x17bb,0x17bb,0x17bb,0x17bb,0x17bb,
+0x17bb,0x17bb,0x17bb,0x17bb,0x17bb,0x17bb,0x17bb,0x17bb,0x17bb,0x17bb,0x17bb,0x21f,0x21f,0x21f,0x21f,0x21f,
+0x21f,0x21f,0x17b8,0x17b8,0x17b8,0x17b8,0x17b8,0x17b8,0x1929,0x1929,0x1929,0x1929,0x1929,0x1929,0x1929,0x1929,
+0x1929,0x1929,0x1929,0x1929,0x1a0a,0x1a0a,0x1a0a,0x1a0a,0x1a0a,0x1a94,0x1b3c,0x1a0a,0x1a0a,0x1a0a,0x1a0a,0x1b3f,
+0x1b3c,0x222,0x1a0a,0x1a94,0x1a0a,0x1a0a,0x1a0a,0x1a0a,0x17df,0x1a0a,0x1a0a,0x1a94,0x1a94,0x1a94,0x1a94,0x1a94,
+0x1a94,0x1a94,0x1a94,0x1b3c,0x222,0x1a97,0x1a97,0x1a97,0x1929,0x192c,0x192c,0x192c,0x192c,0x192c,0x192c,0x192c,
+0x192c,0x192c,0x192c,0x192c,0x192c,0x192c,0x1929,0x1929,0x17c4,0x17c4,0x17c4,0x17c4,0x17c1,0x17c4,0x17c4,0x17c7,
+0x17ca,0x17c7,0x17c7,0x17c4,0x225,0x225,0x225,0x225,0x225,0x225,0x225,0x225,0x225,0x225,0x225,0x225,
+0x225,0x225,0x225,0x17c1,0x17c1,0x17c1,0x17c1,0x17c1,0x1821,0x1821,0x1821,0x1821,0x1818,0x1818,0x1818,0x1812,
+0x1815,0x1815,0x1815,0x1a40,0x228,0x228,0x228,0x228,0x181e,0x181e,0x181e,0x181e,0x181e,0x181e,0x181e,0x181e,
+0x181e,0x181e,0x228,0x228,0x228,0x228,0x181b,0x181b,0x183c,0x183c,0x183c,0x183c,0x183c,0x183c,0x183c,0x183c,
+0x183c,0x22b,0x183c,0x183c,0x183c,0x183c,0x183c,0x183c,0x183c,0x183c,0x183c,0x183c,0x183c,0x183c,0x183c,0x183c,
+0x183c,0x183c,0x183c,0x183c,0x183c,0x183c,0x183c,0x183c,0x183c,0x183c,0x183c,0x1839,0x1827,0x1827,0x1827,0x1827,
+0x1827,0x1827,0x1827,0x22b,0x1827,0x1827,0x1827,0x1827,0x1827,0x1827,0x1839,0x182a,0x183c,0x183f,0x183f,0x1833,
+0x1830,0x1830,0x22b,0x22b,0x22b,0x22b,0x22b,0x22b,0x22b,0x22b,0x22b,0x22b,0x1836,0x1836,0x1836,0x1836,
+0x1836,0x1836,0x1836,0x1836,0x1836,0x1836,0x182d,0x182d,0x182d,0x182d,0x182d,0x182d,0x182d,0x182d,0x182d,0x182d,
+0x182d,0x182d,0x182d,0x182d,0x182d,0x22b,0x22b,0x22b,0x184b,0x184e,0x1854,0x1854,0x1854,0x1854,0x1854,0x1854,
+0x1854,0x1854,0x1854,0x1854,0x1854,0x1854,0x1854,0x1854,0x1842,0x1842,0x1842,0x1842,0x1842,0x1842,0x1842,0x1842,
+0x1842,0x22e,0x22e,0x22e,0x22e,0x22e,0x22e,0x22e,0x19ad,0x19ad,0x19ad,0x19ad,0x19ad,0x19ad,0x19ad,0x19ad,
+0x19ad,0x19ad,0x19ad,0x19ad,0x19ad,0x19ad,0x19ad,0x19ad,0x1845,0x1845,0x1845,0x1845,0x1845,0x1845,0x1845,0x231,
+0x1845,0x1845,0x1845,0x1845,0x1845,0x1845,0x1845,0x1845,0x1845,0x1845,0x1845,0x1845,0x1845,0x1845,0x1845,0x1845,
+0x1845,0x231,0x231,0x1845,0x1845,0x1845,0x1845,0x1845,0x1893,0x192f,0x1a9a,0x1a9d,0x1b45,0x234,0x234,0x234,
+0x234,0x234,0x234,0x234,0x234,0x234,0x234,0x234,0x1b42,0x1b42,0x234,0x234,0x234,0x234,0x234,0x234,
+0x234,0x234,0x234,0x234,0x234,0x234,0x234,0x234,0x1854,0x1854,0x1854,0x1854,0x1854,0x1854,0x1854,0x1854,
+0x1854,0x1854,0x1854,0x1854,0x1854,0x1854,0x1854,0x1854,0x237,0x237,0x1848,0x1848,0x1848,0x1848,0x1848,0x1848,
+0x1848,0x1848,0x1848,0x1848,0x1848,0x1848,0x1848,0x1848,0x237,0x1851,0x1848,0x1848,0x1848,0x1848,0x1848,0x1848,
+0x1848,0x1851,0x1848,0x1848,0x1851,0x1848,0x1848,0x237,0x237,0x237,0x237,0x237,0x237,0x237,0x237,0x237,
+0x1857,0x1857,0x1857,0x1857,0x1857,0x1857,0x1857,0x1857,0x1857,0x1857,0x1857,0x1857,0x1857,0x23a,0x23a,0x23a,
+0x23a,0x23a,0x23a,0x23a,0x23a,0x23a,0x23a,0x23a,0x23a,0x23a,0x23a,0x23a,0x23a,0x23a,0x23a,0x23a,
+0x186f,0x186f,0x1860,0x185a,0x185a,0x186f,0x185d,0x1872,0x1872,0x1872,0x1872,0x1875,0x1875,0x1869,0x1866,0x1863,
+0x186c,0x186c,0x186c,0x186c,0x186c,0x186c,0x186c,0x186c,0x186c,0x186c,0x1aee,0x1869,0x23d,0x1863,0x1992,0x1a43,
+0x1af1,0x1af1,0x23d,0x23d,0x23d,0x23d,0x23d,0x23d,0x23d,0x23d,0x23d,0x23d,0x23d,0x23d,0x23d,0x23d,
+0x23d,0x23d,0x23d,0x23d,0x23d,0x23d,0x23d,0x23d,0x23d,0x23d,0x23d,0x23d,0x23d,0x23d,0x23d,0x23d,
+0x187b,0x187b,0x187b,0x187b,0x187b,0x187b,0x187b,0x187b,0x187b,0x187b,0x187b,0x187b,0x187b,0x187b,0x187b,0x187b,
+0x187b,0x187b,0x187b,0x187b,0x240,0x240,0x240,0x240,0x1878,0x1878,0x1878,0x1878,0x1878,0x1878,0x1878,0x1878,
+0x1878,0x1878,0x1878,0x1878,0x1878,0x1878,0x1878,0x1878,0x1878,0x1878,0x1878,0x1878,0x1878,0x1878,0x1878,0x1878,
+0x1878,0x1878,0x1878,0x1878,0x240,0x240,0x240,0x240,0x1896,0x1896,0x1896,0x1896,0x1896,0x1896,0x1896,0x1896,
+0x1896,0x1896,0x1896,0x1896,0x1896,0x1a13,0x1a13,0x1a13,0x1a13,0x1a13,0x1aa0,0x1aa0,0x1aa0,0x1aa0,0x1aa0,0x1aa0,
+0x243,0x243,0x243,0x243,0x243,0x243,0x243,0x243,0x1935,0x1935,0x1935,0x1935,0x1935,0x1935,0x1935,0x1935,
+0x1935,0x1935,0x1935,0x1935,0x1935,0x1935,0x1935,0x1935,0x1935,0x1935,0x1935,0x1935,0x1935,0x1935,0x1935,0x1935,
+0x1935,0x1935,0x1935,0x1935,0x1935,0x1935,0x1935,0x246,0x246,0x246,0x246,0x246,0x246,0x246,0x246,0x246,
+0x246,0x246,0x246,0x246,0x246,0x246,0x246,0x246,0x288,0x288,0x288,0x288,0x288,0x288,0x288,0x288,
+0x288,0x288,0x288,0x288,0x288,0x288,0x288,0x288,0x18d5,0x18d5,0x18d5,0x18d5,0x18d5,0x18d5,0x18d5,0x249,
+0x18d5,0x18d5,0x249,0x18d5,0x18d5,0x18d5,0x18d5,0x18d5,0x18d5,0x18d5,0x18d5,0x18d5,0x18d5,0x18d5,0x18d5,0x18d5,
+0x18d5,0x18d5,0x18d5,0x18d5,0x18d5,0x18d5,0x18d5,0x18d5,0x18d5,0x18c9,0x18c9,0x18c9,0x18c9,0x18c9,0x18c9,0x249,
+0x249,0x249,0x18c9,0x249,0x18c9,0x18c9,0x249,0x18c9,0x18c9,0x18c9,0x18cc,0x18c9,0x18cf,0x18cf,0x18d8,0x18c9,
+0x249,0x249,0x249,0x249,0x249,0x249,0x249,0x249,0x18d2,0x18d2,0x18d2,0x18d2,0x18d2,0x18d2,0x18d2,0x18d2,
+0x18d2,0x18d2,0x249,0x249,0x249,0x249,0x249,0x249,0x1938,0x1938,0x1938,0x1938,0x1938,0x1938,0x1938,0x1938,
+0x1938,0x1938,0x1938,0x1938,0x1938,0x1938,0x1938,0x1938,0x1938,0x1938,0x1938,0x1938,0x1938,0x1938,0x1938,0x1938,
+0x1938,0x1938,0x1938,0x1938,0x24c,0x24c,0x24c,0x24c,0x1905,0x1908,0x1917,0x1917,0x1908,0x190b,0x1905,0x1902,
+0x255,0x255,0x255,0x255,0x255,0x255,0x255,0x255,0x18f0,0x18db,0x18db,0x18db,0x18db,0x18db,0x18db,0x18ed,
+0x18ed,0x18db,0x18db,0x18db,0x18f0,0x18f0,0x18f0,0x18f0,0x1a49,0x1a49,0x1a49,0x1a49,0x1a49,0x1a49,0x1a49,0x1a49,
+0x1a49,0x1a49,0x1a49,0x1a49,0x1a49,0x1a49,0x1a49,0x1a49,0x1a49,0x1a49,0x1a49,0x1a49,0x258,0x258,0x258,0x258,
+0x258,0x258,0x258,0x258,0x258,0x258,0x258,0x258,0x1998,0x1998,0x1998,0x1998,0x1998,0x1998,0x1998,0x1998,
+0x1998,0x1998,0x1998,0x1998,0x1998,0x1998,0x258,0x258,0x1aa9,0x1aa9,0x1aa9,0x1aa9,0x1b4b,0x28b,0x28b,0x28b,
+0x1aa9,0x1aa9,0x1aa9,0x28b,0x28b,0x28b,0x28b,0x28b,0x19aa,0x19aa,0x19aa,0x19aa,0x19aa,0x19aa,0x19aa,0x19aa,
+0x19aa,0x19aa,0x19aa,0x19aa,0x19a7,0x19a7,0x19a7,0x199b,0x199b,0x199b,0x199b,0x199b,0x199b,0x199b,0x199b,0x199b,
+0x19a7,0x19a1,0x199e,0x19a4,0x25b,0x25b,0x25b,0x25b,0x19ad,0x19ad,0x19ad,0x19ad,0x19ad,0x19ad,0x19ad,0x19ad,
+0x19ad,0x19ad,0x19ad,0x19ad,0x19ad,0x19ad,0x19ad,0x19ad,0x19ad,0x19ad,0x19ad,0x19ad,0x19ad,0x19ad,0x19ad,0x19ad,
+0x19ad,0x19ad,0x19ad,0x25e,0x25e,0x19ad,0x19ad,0x19ad,0x19bc,0x19bc,0x19bc,0x19bc,0x19bc,0x19bc,0x261,0x19bc,
+0x19bc,0x261,0x19bc,0x19bc,0x19bc,0x19bc,0x19bc,0x19bc,0x19bc,0x19bc,0x19bc,0x19bc,0x19bc,0x19bc,0x19bc,0x19bc,
+0x19bc,0x19bc,0x19bc,0x19bc,0x19bc,0x19bc,0x19bc,0x19bc,0x19bc,0x19bc,0x19b9,0x19b9,0x19b9,0x19b9,0x19b9,0x261,
+0x19b0,0x19b0,0x261,0x19b9,0x19b9,0x19b0,0x19b9,0x19b3,0x19bc,0x261,0x261,0x261,0x261,0x261,0x261,0x261,
+0x19c5,0x19c5,0x19c8,0x19c8,0x19bf,0x19bf,0x19bf,0x19bf,0x264,0x264,0x264,0x264,0x264,0x264,0x264,0x264,
+0x19c2,0x19c2,0x19c2,0x19c2,0x19c2,0x19c2,0x19c2,0x19c2,0x19c2,0x19c2,0x264,0x264,0x264,0x264,0x264,0x264,
+0x19cb,0x19cb,0x19cb,0x19cb,0x19cb,0x19cb,0x19cb,0x19cb,0x19cb,0x19cb,0x19cb,0x19cb,0x19ce,0x19cb,0x19cb,0x19cb,
+0x19ce,0x19cb,0x19cb,0x19cb,0x19cb,0x267,0x267,0x267,0x267,0x267,0x267,0x267,0x267,0x267,0x267,0x267,
+0x19d7,0x19d7,0x19d7,0x19d7,0x19d7,0x19d7,0x19d7,0x19d7,0x19d7,0x19d7,0x19d7,0x19d7,0x19d7,0x19d7,0x19d7,0x19d7,
+0x19d7,0x19d7,0x19d7,0x19d1,0x19d1,0x19d4,0x19d4,0x19da,0x19da,0x26a,0x26a,0x26a,0x26a,0x26a,0x26a,0x26a,
+0x19dd,0x19dd,0x19dd,0x19dd,0x19dd,0x19dd,0x19dd,0x19dd,0x19dd,0x19dd,0x19dd,0x19dd,0x19dd,0x19dd,0x19dd,0x19dd,
+0x19dd,0x19dd,0x19dd,0x19dd,0x26d,0x26d,0x26d,0x26d,0x26d,0x26d,0x26d,0x26d,0x26d,0x26d,0x26d,0x26d,
+0x19e0,0x19e0,0x19e0,0x19e0,0x19e0,0x19e0,0x19e0,0x19e0,0x19e0,0x19e0,0x19e0,0x19e0,0x19e0,0x19e0,0x19e0,0x19e0,
+0x19e0,0x19e0,0x19e0,0x19e0,0x19e0,0x19e0,0x19e0,0x19e3,0x19ec,0x19e0,0x19e0,0x270,0x270,0x270,0x270,0x270,
+0x19ef,0x19ef,0x19ef,0x19ef,0x19ef,0x19ef,0x19ef,0x19f2,0x273,0x273,0x273,0x273,0x273,0x273,0x273,0x273,
+0x19fb,0x19fb,0x19fb,0x19fb,0x19fb,0x19fb,0x19fb,0x19fb,0x19fb,0x19fb,0x19fb,0x19fb,0x19fb,0x19fb,0x19fb,0x19fb,
+0x19fb,0x19fb,0x19f5,0x19f5,0x19f5,0x19f5,0x19f5,0x19f5,0x19f5,0x19f5,0x19f5,0x19f5,0x19f5,0x19f8,0x19f8,0x19f8,
+0x19f8,0x19fe,0x19fe,0x19fe,0x19fe,0x19fe,0x276,0x276,0x276,0x276,0x276,0x276,0x1a55,0x1a55,0x1a55,0x1a55,
+0x1a55,0x1a55,0x1a55,0x1a55,0x1a55,0x1a55,0x1a55,0x1a55,0x1a55,0x1a55,0x1a55,0x1a55,0x1a55,0x1a55,0x1a55,0x1a55,
+0x1a55,0x1a55,0x1a55,0x27c,0x27c,0x27c,0x27c,0x27c,0x27c,0x27c,0x27c,0x27c,0x1a64,0x1a64,0x1a64,0x1a64,
+0x1a64,0x1a64,0x1a64,0x1a64,0x27f,0x27f,0x1a64,0x1a64,0x1a64,0x1a64,0x1a64,0x1a64,0x1a64,0x1a64,0x1a64,0x1a64,
+0x1a64,0x1a64,0x1a64,0x1a64,0x1a64,0x1a64,0x1a64,0x1a64,0x1a64,0x1a64,0x1a64,0x1a64,0x1a64,0x1a61,0x1a61,0x1a61,
+0x1a58,0x1a58,0x1a58,0x1a58,0x27f,0x27f,0x1a58,0x1a58,0x1a61,0x1a61,0x1a61,0x1a61,0x1a5b,0x1a64,0x1a5e,0x1a64,
+0x1a61,0x27f,0x27f,0x27f,0x27f,0x27f,0x27f,0x27f,0x27f,0x27f,0x27f,0x27f,0x27f,0x27f,0x27f,0x27f,
+0x27f,0x27f,0x27f,0x27f,0x27f,0x27f,0x27f,0x27f,0x27f,0x27f,0x27f,0x27f,0x1a70,0x1a70,0x1a70,0x1a70,
+0x1a70,0x1a70,0x1a70,0x1a70,0x1a70,0x1a70,0x1a70,0x1a70,0x1a70,0x282,0x282,0x282,0x1a67,0x1a67,0x1a67,0x1a67,
+0x1a67,0x1a67,0x1a67,0x1a70,0x1a70,0x1a70,0x1a70,0x1a70,0x1a73,0x1a73,0x282,0x282,0x285,0x1a76,0x1a76,0x1a76,
+0x1a76,0x1a76,0x1a76,0x1a76,0x1a76,0x1a76,0x1a76,0x1a76,0x1a76,0x1a76,0x1a76,0x1a76,0x1a76,0x1a76,0x1a76,0x1a76,
+0x1a76,0x1a76,0x1a76,0x1a76,0x1a76,0x1a76,0x1a76,0x1a76,0x1a76,0x1a76,0x1a76,0x1a76,0x1a76,0x1a76,0x285,0x285,
+0x288,0x288,0x288,0x288,0x288,0x288,0x288,0x288,0x288,0x288,0x288,0x288,0x288,0x288,0x288,0x288,
+0x1aa3,0x1aa3,0x1aa3,0x288,0x288,0x288,0x288,0x288,0x288,0x288,0x288,0x288,0x288,0x288,0x288,0x288,
+0x1aa6,0x1aa6,0x1aa6,0x1aa6,0x288,0x288,0x288,0x288,0x288,0x288,0x288,0x288,0x1938,0x1938,0x1938,0x1938,
+0x1938,0x1938,0x1938,0x1938,0x1938,0x1938,0x1938,0x1938,0x1938,0x1938,0x1938,0x1938,0x1aa9,0x1aa9,0x1aa9,0x1b4b,
+0x1b4b,0x1b4b,0x1b4b,0x28b,0x28b,0x28b,0x28b,0x28b,0x28b,0x28b,0x28b,0x28b,0x1aa9,0x1aa9,0x1aa9,0x1aa9,
+0x1aa9,0x1aa9,0x1b4b,0x1b4b,0x1b4b,0x1b4b,0x1b4b,0x1b4b,0x1b4b,0x1b4b,0x1b4b,0x1b4b,0x1b4b,0x28b,0x28b,0x28b,
+0x28b,0x28b,0x28b,0x28b,0x1b4b,0x1b4b,0x1b4b,0x1b4b,0x1b4b,0x1b4b,0x1b4b,0x28b,0x28b,0x28b,0x28b,0x28b,
+0x28b,0x28b,0x28b,0x28b,0x28b,0x28b,0x28b,0x28b,0x1b4b,0x1b4b,0x1b4b,0x1b4b,0x1b4b,0x1b4b,0x1b4b,0x28b,
+0x28b,0x28b,0x28b,0x28b,0x28b,0x28b,0x28b,0x28b,0x28b,0x28b,0x28b,0x28b,0x28b,0x28b,0x28b,0x28b,
+0x28b,0x28b,0x28b,0x28b,0x28b,0x28b,0x28b,0x28b,0x28b,0x28b,0x28b,0x28b,0x28b,0x28b,0x28b,0x28b,
+0x1a7f,0x1a79,0x1a79,0x1a79,0x1a79,0x1a79,0x1a79,0x1a79,0x1a79,0x1a79,0x1a79,0x1a79,0x1a79,0x1a79,0x1a79,0x1a79,
+0x1a79,0x1a79,0x28e,0x28e,0x28e,0x28e,0x28e,0x28e,0x28e,0x28e,0x28e,0x28e,0x28e,0x28e,0x28e,0x1a7c,
+0x1a8b,0x1a8b,0x1a8b,0x1a8b,0x1a8b,0x1a8b,0x1a8b,0x1a8b,0x1a8b,0x1a8b,0x1a8b,0x1a8b,0x1a82,0x1a82,0x1a82,0x1a82,
+0x1a88,0x1a88,0x1a88,0x1a88,0x1a88,0x1a88,0x1a88,0x1a88,0x1a88,0x1a88,0x291,0x291,0x291,0x291,0x291,0x1a85,
+0x1af7,0x1af7,0x1af7,0x1af7,0x1af7,0x1af4,0x1af4,0x1af4,0x1af4,0x1af4,0x1af4,0x1af4,0x294,0x294,0x294,0x294,
+0x294,0x294,0x294,0x294,0x294,0x294,0x294,0x294,0x294,0x294,0x294,0x294,0x294,0x294,0x294,0x294,
+0x1b12,0x1b12,0x1b12,0x1b12,0x1b12,0x1b12,0x1b12,0x297,0x297,0x1b12,0x297,0x297,0x1b12,0x1b12,0x1b12,0x1b12,
+0x1b12,0x1b12,0x1b12,0x1b12,0x297,0x1b12,0x1b12,0x297,0x1b12,0x1b12,0x1b12,0x1b12,0x1b12,0x1b12,0x1b12,0x1b12,
+0x1b12,0x1b12,0x1b12,0x1b12,0x1b12,0x1b12,0x1b12,0x1b12,0x1afa,0x1b09,0x1b09,0x1b09,0x1b09,0x1b09,0x297,0x1b09,
+0x1b0c,0x297,0x297,0x1afa,0x1afa,0x1b0f,0x1b00,0x1b15,0x1b09,0x1b15,0x1b09,0x1afd,0x1b18,0x1b03,0x1b18,0x297,
+0x297,0x297,0x297,0x297,0x297,0x297,0x297,0x297,0x1b06,0x1b06,0x1b06,0x1b06,0x1b06,0x1b06,0x1b06,0x1b06,
+0x1b06,0x1b06,0x297,0x297,0x297,0x297,0x297,0x297,0x1b51,0x1b51,0x1b51,0x1b51,0x1b51,0x1b51,0x1b51,0x1b51,
+0x1b51,0x1b51,0x1b51,0x1b51,0x1b51,0x1b51,0x1b51,0x1b51,0x1b51,0x1b51,0x1b51,0x1b51,0x1b51,0x1b51,0x29a,0x29a,
+0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,
+0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,
+0x1b1e,0x1b1e,0x1b1e,0x1b1e,0x1b1e,0x1b1e,0x1b1e,0x1b1e,0x1b1e,0x1b1e,0x1b1e,0x1b1e,0x1b1e,0x1b1e,0x1b1e,0x1b1e,
+0x1b1e,0x1b1e,0x1b1e,0x2a0,0x1b1e,0x1b1e,0x1b1e,0x1b1e,0x1b1e,0x1b1e,0x1b1e,0x1b1e,0x1b1e,0x1b1e,0x1b1e,0x1b1e,
+0x1b1e,0x1b1e,0x1b1e,0x2a0,0x2a0,0x2a0,0x2a0,0x2a0,0x2a0,0x2a0,0x2a0,0x2a0,0x2a0,0x2a0,0x2a0,0x2a0,
+0x2a0,0x2a0,0x2a0,0x2a0,0x2a0,0x2a0,0x2a0,0x2a0,0x1b21,0x1b21,0x1b21,0x1b21,0x1b21,0x1b21,0x1b21,0x1b21,
+0x1b21,0x1b21,0x2a0,0x2a0,0x2a0,0x2a0,0x2a0,0x2a0,0x1b54,0x1b54,0x1b54,0x1b54,0x1b54,0x1b54,0x1b54,0x1b54,
+0x1b54,0x2a3,0x2a3,0x2a3,0x2a3,0x2a3,0x2a3,0x2a3,0x2a3,0x2a3,0x2a3,0x2a3,0x2a3,0x2a3,0x2a3,0x2a3,
+0x2a3,0x2a3,0x2a3,0x2a3,0x2a3,0x2a3,0x2a3,0x2a3,0x2a3,0x2a3,0x2a3,0x2a3,0x2a3,0x2a3,0x2a3,0x2a3,
+0x2a3,0x2a3,0x2a3,0x2a3,0x1b2a,0x1b2a,0x1b2a,0x1b2a,0x1b2a,0x1b2a,0x1b2a,0x1b2a,0x1b2a,0x1b2a,0x2a6,0x1b24,
+0x1b24,0x1b27,0x2a6,0x2a6,0x1b2a,0x1b2a,0x2a6,0x2a6,0x2a6,0x2a6,0x2a6,0x2a6,0x2a6,0x2a6,0x2a6,0x2a6,
+0x2a6,0x2a6,0x2a6,0x2a6,0x2a9,0x2a9,0x2a9,0x2a9,0x2a9,0x2a9,0x2a9,0x2a9,0x2a9,0x2a9,0x2a9,0x2a9,
+0x2a9,0x2a9,0x2a9,0x2a9,0x2a9,0x2a9,0x2a9,0x2a9,0x2a9,0x2a9,0x2a9,0x2a9,0x2a9,0x2a9,0x2a9,0x2a9,
+0x2a9,0x2a9,0x2a9,0x2a9,0x1932,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,
+0x2c1,0x2c1,0x2c1,0x2c1,0x2a9,0x2a9,0x2a9,0x2a9,0x2a9,0x2a9,0x2a9,0x2a9,0x2a9,0x2a9,0x2a9,0x2a9,
+0x2a9,0x2a9,0x2a9,0x2a9,0x2a9,0x2a9,0x2a9,0x2a9,0x2a9,0x2a9,0x2a9,0x2a9,0x2a9,0x2a9,0x2a9,0x2a9,
+0x2a9,0x2a9,0x97b,0x97b,0x1b4e,0x1b4e,0x1b4e,0x1b4e,0x1b4e,0x1b4e,0x1b4e,0x1b4e,0x1b4e,0x1b4e,0x1b4e,0x2c4,
+0x2c4,0x2c4,0x2c4,0x2c4,0x2a9,0x2a9,0x2a9,0x2a9,0x2a9,0x2a9,0x2a9,0x2a9,0x2a9,0x2a9,0x2a9,0x2a9,
+0x2a9,0x2a9,0x2a9,0x2a9,0x191d,0x191d,0x191d,0x191d,0x191d,0x191d,0x191d,0x191d,0x191d,0x191d,0x191d,0x1a04,
+0x1a04,0x1a04,0x1a04,0x1a04,0x1b33,0x1b33,0x1b33,0x1b33,0x1b33,0x1b33,0x1b33,0x1b33,0x1b33,0x1b33,0x1b33,0x1b33,
+0x1b33,0x2ac,0x2ac,0x2ac,0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,0x12e4,
+0x12e4,0x12e4,0x2af,0x2af,0xed0,0xed0,0xed0,0xed0,0xed0,0xed0,0xed0,0xed0,0xed0,0xed0,0xed0,0xed0,
+0xed0,0xed0,0xed0,0xed0,0xed0,0xed0,0xed0,0xed0,0xed0,0xed0,0xed0,0xed0,0xed0,0xed0,0x2af,0x2af,
+0x2af,0x2af,0x2af,0x2af,0x2af,0x2af,0x2af,0x2af,0x2af,0x2af,0x2af,0x2af,0x2af,0x2af,0x2af,0x2af,
+0x2af,0x2af,0x2af,0x2af,0x2af,0x2af,0x2af,0x2af,0x2af,0x2af,0x2af,0x2af,0x2af,0x2af,0x2af,0x2af,
+0xba9,0xba9,0xba9,0xba9,0xba9,0xba9,0xba9,0xba9,0xba9,0xba9,0xba9,0xba9,0xba9,0xba9,0xba9,0xba9,
+0xba9,0xba9,0xba9,0xba9,0xba9,0xba9,0xba9,0x1b36,0x1b36,0x1b36,0x1b36,0x1b36,0x1b36,0x1b36,0x2b2,0x2b2,
+0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,
+0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0x2b5,0x2b5,
+0x12f9,0x12f9,0x12f9,0x12f9,0x12f9,0x12f9,0x12f9,0x12f9,0x12f9,0x12f9,0x12f9,0x12f9,0x12f9,0x12f9,0x12f9,0x12f9,
+0x12f9,0x12f9,0x12f9,0x12f9,0x12f9,0x2b8,0x2b8,0x2b8,0x2b8,0x2b8,0x2b8,0x2b8,0x2b8,0x2b8,0x2b8,0x2b8,
+0x1416,0x1416,0x1416,0x1416,0x1416,0x1416,0x1416,0x1416,0x1416,0x1416,0x1416,0x1416,0x1416,0x1416,0x1416,0x1416,
+0x1416,0x1416,0x1416,0x1416,0x1416,0x1416,0x1416,0x1416,0x1416,0x1416,0x1416,0x1416,0x1416,0x1416,0x2bb,0x2bb,
+0x17dc,0x17dc,0x2be,0x2be,0x2be,0x2be,0x2be,0x2be,0x2be,0x2be,0x2be,0x2be,0x2be,0x2be,0x2be,0x2be,
+0x1932,0x1932,0x1932,0x1932,0x1932,0x1932,0x1932,0x1932,0x1932,0x1932,0x1932,0x1932,0x1932,0x1932,0x1932,0x1932,
+0x3cc,0x3c0,0x3c0,0x3c0,0x3c0,0x3c0,0x3c0,0x3c0,0x3c0,0x3cc,0x3cc,0x3cc,0x3cc,0x3c6,0x1158,0x133e,
+0x3cf,0x945,0x948,0x3bd,0x3bd,0x1155,0x133b,0x133b,0x3d2,0x3d2,0x3d2,0x3d2,0x3d2,0x3d2,0x3d2,0x3d2,
+0x1155,0x3c0,0x3c0,0x3cc,0xce1,0x3cf,0x3cf,0x3cf,0x3cf,0x3cf,0x3cf,0x3cf,0x3cf,0x3cf,0x3cf,0x3cf,
+0x3cf,0x3cf,0x3cf,0x3cf,0x3cf,0x3cf,0x3cf,0x3cf,0x3cf,0x3cf,0x3cf,0x3cf,0x3cf,0x3cf,0x3cf,0x3cf,
+0x3cf,0x3cf,0x3c0,0x3c0,0x8d0,0x8d3,0x963,0x963,0x963,0x963,0x963,0x963,0x963,0x963,0x963,0x963,
+0x3c9,0xfba,0xfb7,0x1341,0x1341,0x1341,0x1341,0x1341,0x1506,0x115b,0x115b,0xf0c,0xf0c,0xdda,0xf0c,0xf0c,
+0x3cf,0x3cf,0x3cf,0x3cf,0x3cf,0x3cf,0x3cf,0x3cf,0x3cf,0x3d2,0x3cf,0x3cf,0x3cf,0x3cf,0x3cf,0x3cf,
+0x3cf,0x3d2,0x3cf,0x3cf,0x3d2,0x3cf,0x3cf,0x3cf,0x3cf,0x3cf,0x133b,0x133e,0x3c3,0x3cf,0x3cc,0x3cc,
+0x46e,0x46e,0x46e,0x46e,0x46e,0x46e,0x46e,0x46e,0x46e,0x1347,0x46e,0x46e,0x46e,0x46e,0x46e,0x46e,
+0x46e,0x46e,0x46e,0x46e,0x46e,0x46e,0x46e,0x46e,0x46e,0x46e,0x1347,0x18ae,0x18ae,0xfd8,0x45f,0x468,
+0x4aa,0x4aa,0x4aa,0x4aa,0x4aa,0x4aa,0x4aa,0x4aa,0x4aa,0x4aa,0x4aa,0x4aa,0x4aa,0x4aa,0x4aa,0x4aa,
+0x4aa,0x4aa,0x4aa,0x4aa,0x4aa,0x4aa,0x4aa,0xbc7,0xbc7,0xde6,0xde6,0x8d6,0xde9,0x1428,0x1428,0x1428,
+0x4ad,0x4ad,0x4ad,0x4ad,0x4ad,0x4ad,0x4ad,0x4ad,0x4ad,0x4ad,0x4ad,0x4ad,0x4ad,0x4ad,0x4ad,0x4ad,
+0x4ad,0x4ad,0x4ad,0x4ad,0x4ad,0x4ad,0x4ad,0x4ad,0x4ad,0x4ad,0x4ad,0x4ad,0x4ad,0x4ad,0x4ad,0x4ad,
+0x4b3,0x4b3,0x4b3,0x1170,0x1170,0x1170,0x1170,0x1170,0x4b0,0x4b0,0x4b0,0x4b0,0x4b0,0x4b0,0x4b0,0x4b0,
+0x4b0,0x4b0,0x4b0,0x4b0,0x4b0,0x4b0,0x4b0,0x4b0,0x4b0,0x4b0,0x4b0,0x4b0,0x4b0,0x4b0,0x4b0,0x4b0,
+0x4b0,0x4b0,0x4b0,0x4b0,0x4b0,0x4b0,0x4b0,0x4b0,0x4b0,0x4b0,0x116d,0x116d,0x116d,0x116d,0x116d,0x116d,
+0x4b6,0x4b3,0x4b3,0x4b3,0x4b3,0x4b3,0x4b3,0x4b3,0x4b3,0x4b3,0x4b3,0x4b3,0x4b3,0x4b3,0x4b3,0x4b3,
+0x4b3,0x4b3,0x4b3,0x4b3,0x4b3,0x4b3,0x4b3,0x4b3,0x4b3,0x4b3,0x4b3,0x4b3,0x4b3,0x4b3,0x4b3,0x4b3,
+0x4b3,0x4b3,0x4b3,0x4b3,0x4bf,0x4b9,0x4bf,0x4b9,0x4bf,0x4b9,0x4bf,0x4b9,0x4bf,0x4b9,0x4bf,0x4b9,
+0x4bf,0x4b9,0x4bf,0x4b9,0x4bf,0x4b9,0x4bf,0x4b9,0x4bf,0x4b9,0x4bf,0x4b9,0x4bf,0x4b9,0x4bf,0x4b9,
+0x4bf,0x4b9,0x4bf,0x4b9,0x4bf,0x4b9,0x4b9,0x4b9,0x4b9,0x4b9,0x4bc,0x9bd,0x1005,0x1005,0x1008,0x1005,
+0x4bf,0x4b9,0x4bf,0x4b9,0x4bf,0x4b9,0x4bf,0x4b9,0x4bf,0x4b9,0x4bf,0x4b9,0x4bf,0x4b9,0x4bf,0x4b9,
+0x4bf,0x4b9,0x4bf,0x4b9,0x4bf,0x4b9,0x4bf,0x4b9,0x4bf,0x4b9,0x1008,0x1005,0x1008,0x1005,0x1008,0x1005,
+0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,0x4ce,0x4ce,0x4ce,0x4ce,0x4ce,0x4ce,0x4ce,0x4ce,
+0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,0x4ce,0x4ce,0x4ce,0x4ce,0x4ce,0x4ce,0x4ce,0x4ce,
+0x6ae,0x6ae,0x6b1,0x4e9,0x6bd,0x6ba,0x6ba,0x6b7,0x513,0x513,0x4d1,0x4d1,0x4d1,0x4d1,0x4d1,0xb58,
+0x6c0,0x4f5,0x6d8,0x6db,0x50a,0x6c0,0x4f8,0x4f8,0x4e9,0x504,0x504,0x6ae,0x510,0x50d,0x6b4,0x4e3,
+0x4da,0x4da,0x4dd,0x4dd,0x4dd,0x4dd,0x4dd,0x4e0,0x4dd,0x4dd,0x4dd,0x4d4,0x51c,0x519,0x516,0x516,
+0x6cc,0x4fe,0x4fb,0x6c9,0x6c6,0x6c3,0x6d5,0x4ec,0x6d2,0x6d2,0x501,0x504,0x6cf,0x6cf,0x501,0x504,
+0x4e6,0x4e9,0x4e9,0x4e9,0x507,0x4f2,0x4ef,0xbdc,0xaf2,0xaf5,0xaef,0xaef,0xaef,0xaef,0xbd3,0xbd3,
+0xbd3,0xbd3,0xbd9,0xd0e,0xd0b,0xdf5,0xdf8,0xbd6,0xdf8,0xdf8,0xdf8,0xdf8,0xdf5,0xdf8,0xdf8,0xbd0,
+0x540,0x540,0x540,0x540,0x540,0x540,0x540,0x53d,0x543,0x75c,0x540,0x9c0,0x9e1,0xaf8,0xaf8,0xaf8,
+0xbe2,0xbe2,0xdfe,0xdfe,0xdfe,0xdfe,0x1179,0x117c,0x117c,0x135c,0x14f4,0x151e,0x1521,0x1521,0x1734,0x18b1,
+0x54f,0x54f,0x567,0x6ea,0x54c,0x6e7,0x54f,0x564,0x54c,0x6ea,0x55e,0x567,0x567,0x567,0x55e,0x55e,
+0x567,0x567,0x567,0x6f3,0x54c,0x567,0x6ed,0x54c,0x55b,0x567,0x567,0x567,0x567,0x567,0x54c,0x54c,
+0x552,0x6e7,0x6f0,0x54c,0x567,0x54c,0x6f6,0x54c,0x567,0x555,0x56d,0x6f9,0x567,0x567,0x558,0x55e,
+0x567,0x567,0x56a,0x567,0x55e,0x561,0x561,0x561,0x561,0xb04,0xb01,0xd11,0xe07,0xbf7,0xbfa,0xbfa,
+0xbf4,0xbf1,0xbf1,0xbf1,0xbf1,0xbfa,0xbf7,0xbf7,0xbf7,0xbf7,0xbee,0xbf1,0xe04,0xf18,0xf1b,0x100e,
+0x117f,0x117f,0x117f,0x6ff,0x6fc,0x570,0x573,0x573,0x573,0x573,0x573,0x6fc,0x6ff,0x6ff,0x6fc,0x573,
+0x705,0x705,0x705,0x705,0x705,0x705,0x705,0x705,0x705,0x705,0x705,0x705,0x57c,0x57c,0x57c,0x57c,
+0x702,0x702,0x702,0x702,0x702,0x702,0x702,0x702,0x702,0x702,0x576,0x576,0x576,0x576,0x576,0x576,
+0x582,0x582,0x582,0x582,0x582,0x582,0x582,0x582,0x57f,0x588,0x588,0x582,0x582,0x582,0x585,0x57f,
+0x582,0x582,0x57f,0x57f,0x57f,0x57f,0x582,0x582,0x708,0x708,0x57f,0x57f,0x582,0x582,0x582,0x582,
+0x582,0x582,0x582,0x582,0x582,0x582,0x582,0x582,0x582,0x585,0x585,0x585,0x582,0x582,0x70b,0x582,
+0x70b,0x582,0x582,0x582,0x582,0x582,0x582,0x582,0x57f,0x582,0x57f,0x57f,0x57f,0x57f,0x57f,0x57f,
+0x582,0x582,0x57f,0x708,0x57f,0x57f,0x57f,0xb0a,0xb0a,0xb0a,0xb0a,0xb0a,0xb0a,0xb0a,0xb0a,0xb0a,
+0xbfd,0xbfd,0xbfd,0xbfd,0xbfd,0xbfd,0xbfd,0xbfd,0xbfd,0xbfd,0xbfd,0xbfd,0x711,0x58b,0x711,0x711,
+0x58e,0x58b,0x58b,0x711,0x711,0x58e,0x58b,0x711,0x58e,0x58b,0x58b,0x711,0x58b,0x711,0x59a,0x597,
+0x58b,0x711,0x58b,0x58b,0x58b,0x58b,0x711,0x58b,0x58b,0x711,0x711,0x711,0x711,0x58b,0x58b,0x711,
+0x58e,0x711,0x58e,0x711,0x711,0x711,0x711,0x711,0x717,0x591,0x711,0x591,0x591,0x58b,0x58b,0x58b,
+0x711,0x711,0x711,0x711,0x58b,0x58b,0x58b,0x58b,0x711,0x711,0x58b,0x58b,0x58b,0x58e,0x58b,0x58b,
+0x58e,0x58b,0x58b,0x58e,0x711,0x58e,0x58b,0x58b,0x711,0x58b,0x58b,0x58b,0x58b,0x58b,0x711,0x58b,
+0x58b,0x58b,0x58b,0x58b,0x58b,0x58b,0x58b,0x58b,0x58b,0x58b,0x58b,0x58b,0x714,0x711,0x58e,0x58b,
+0x711,0x711,0x711,0x711,0x58b,0x58b,0x711,0x711,0x58b,0x58e,0x714,0x714,0x58e,0x58e,0x58b,0x58b,
+0x58e,0x58e,0x58b,0x58b,0x58e,0x58e,0x58b,0x58b,0x58b,0x58b,0x58b,0x58b,0x58e,0x58e,0x711,0x711,
+0x58e,0x58e,0x711,0x711,0x58e,0x58e,0x58b,0x58b,0x58b,0x58b,0x58b,0x58b,0x58b,0x58b,0x58b,0x58b,
+0x58b,0x711,0x58b,0x58b,0x58b,0x711,0x58b,0x58b,0x58b,0x58b,0x58b,0x58b,0x58b,0x711,0x58b,0x58b,
+0x58b,0x58b,0x58b,0x58b,0x58e,0x58e,0x58e,0x58e,0x58b,0x58b,0x58b,0x58b,0x58b,0x58b,0x58b,0x58b,
+0x58b,0x58b,0x58b,0x58b,0x58b,0x58b,0x58b,0x711,0x58b,0x58b,0x58b,0x58b,0x58b,0x58b,0x58b,0x58b,
+0x58b,0x58b,0x58b,0x58b,0x58b,0x58b,0x58b,0x58b,0x58b,0x58b,0x58b,0x58b,0x58b,0x58b,0x58b,0x58b,
+0x58b,0x58b,0x58b,0x58b,0x58b,0x58b,0x58b,0x58b,0x58e,0x58e,0x58e,0x58e,0x58b,0x58b,0x58b,0x58b,
+0x58b,0x58b,0x58e,0x58e,0x58e,0x58e,0x58b,0x594,0x58b,0x58b,0xc00,0xc00,0xc00,0xc00,0xc00,0xc00,
+0xc00,0xc00,0xc00,0xc00,0xc00,0xc00,0xc00,0xc00,0x59d,0xb0d,0x59d,0x59d,0x59d,0x59d,0x59d,0x59d,
+0x5a9,0x5a6,0x5a9,0x5a6,0x59d,0x59d,0x59d,0x59d,0x59d,0x59d,0x71a,0x59d,0x59d,0x59d,0x59d,0x59d,
+0x59d,0x59d,0x81f,0x81f,0x59d,0x59d,0x59d,0x59d,0x5a3,0x5a3,0x59d,0x59d,0x59d,0x59d,0x59d,0x59d,
+0x5a0,0x825,0x822,0x59d,0x59d,0x59d,0x59d,0x59d,0x59d,0x59d,0x59d,0x59d,0x59d,0x59d,0x59d,0x59d,
+0x59d,0x59d,0x59d,0x59d,0x59d,0x59d,0x59d,0x59d,0x59d,0x59d,0x59d,0x59d,0x59d,0x59d,0x59d,0x59d,
+0x59d,0x59d,0x59d,0x59d,0x59d,0x59d,0x59d,0xb0d,0xc06,0xb0d,0xb0d,0xb0d,0x5ac,0x5ac,0x5ac,0x5ac,
+0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,
+0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x5ac,0x723,0x723,0x723,0x723,
+0x723,0x723,0x723,0x723,0x723,0x723,0x5b2,0xc6f,0xc6f,0xc6f,0xc6f,0xc6f,0xc6f,0xc6f,0xc6f,0xc6f,
+0xc6f,0xc6f,0xc6f,0xc6f,0xc6f,0xc6f,0xc6f,0xc6f,0xc6f,0xc6f,0xc6f,0xd89,0x72c,0x72c,0x72c,0x72c,
+0x72c,0x72c,0x72c,0x72c,0x72c,0x72c,0x72c,0x72c,0x72c,0x72c,0x72c,0x72c,0x72c,0x72c,0x72c,0x72c,
+0x5b5,0x5b8,0x5b8,0x5b8,0x5b8,0x5b8,0x5b8,0x5b8,0x5b8,0x5b8,0x5b8,0x5b8,0x72c,0x72c,0x72c,0x72c,
+0x72c,0x72c,0x72c,0x72c,0x72c,0x72c,0x72c,0x72c,0x5b8,0x5b8,0x5b8,0x5b8,0x72c,0x72c,0x72c,0x72c,
+0x72c,0x72c,0x72c,0x72c,0x72c,0x72c,0x72c,0x72c,0x72c,0x72c,0x72c,0x72c,0x72f,0x72f,0x72f,0x72f,
+0x72f,0x72f,0x72f,0x72f,0x72f,0x72f,0x72f,0x72f,0x72f,0x72f,0x72f,0x72f,0x5bb,0x5bb,0x72f,0x72f,
+0x72f,0x72f,0xc09,0xc09,0xc09,0xc09,0xc09,0xc09,0xc09,0xc09,0xc09,0xc09,0x735,0x735,0x5be,0x732,
+0x732,0x732,0x732,0x732,0x732,0x732,0x5c1,0x5c1,0x5be,0x5be,0x5c4,0x5c4,0x5c4,0x5c4,0x735,0x735,
+0x5c4,0x5c4,0x738,0x735,0x5be,0x5be,0x5be,0x5be,0x735,0x735,0x5c4,0x5c4,0x738,0x735,0x5be,0x5be,
+0x5be,0x5be,0x735,0x735,0x732,0x5be,0x5c4,0x735,0x5be,0x5be,0x732,0x735,0x735,0x735,0x5c4,0x5c4,
+0x5be,0x5be,0x5be,0x5be,0x5be,0x5be,0x5be,0x5be,0x5be,0x5be,0x5be,0x5be,0x5be,0x5be,0x735,0x732,
+0x735,0x732,0x5be,0x5c4,0x5c4,0x5c4,0x5c4,0x5c4,0x5c4,0x5be,0x5be,0x732,0xb16,0xb16,0xb16,0xb16,
+0xb16,0xb16,0xb16,0xb16,0xc0c,0xc0c,0xc0c,0xc0f,0xc0f,0xc8a,0xc8a,0xc0c,0x5d3,0x5d3,0x5d3,0x5d3,
+0x5d0,0x74a,0x747,0x5ca,0x5ca,0x73b,0x5ca,0x5ca,0x5ca,0x5ca,0x741,0x73b,0x5ca,0x5d0,0x5ca,0x5c7,
+0xd92,0xd92,0xc15,0xc15,0xe13,0xb19,0x5cd,0x5cd,0x73e,0x5d6,0x73e,0x5cd,0x5d0,0x5ca,0x5d0,0x5d0,
+0x5ca,0x5ca,0x5d0,0x5ca,0x5ca,0x5ca,0x5d0,0x5ca,0x5ca,0x5ca,0x5d0,0x5d0,0x5ca,0x5ca,0x5ca,0x5ca,
+0x5ca,0x5ca,0x5ca,0x5ca,0x5d0,0x5d3,0x5d3,0x5cd,0x5ca,0x5ca,0x5ca,0x5ca,0x74d,0x5ca,0x74d,0x5ca,
+0x5ca,0x5ca,0x5ca,0x5ca,0x828,0x828,0x828,0x828,0x828,0x828,0x828,0x828,0x828,0x828,0x828,0x828,
+0x5ca,0x5ca,0x5ca,0x5ca,0x5ca,0x5ca,0x5ca,0x5ca,0x5ca,0x5ca,0x5ca,0x5d0,0x74d,0x74a,0x5d9,0x74d,
+0x73b,0x741,0x5d0,0x73b,0x744,0x73b,0x73b,0x5ca,0x73b,0x74a,0x5d9,0x74a,0xb19,0xb19,0xc18,0xc18,
+0xc18,0xc18,0xc18,0xc18,0xc18,0xc18,0xc18,0xc1b,0xc18,0xc18,0xe10,0xec7,0x5dc,0x5dc,0x5dc,0x5dc,
+0x5dc,0x5dc,0x5dc,0x5dc,0x5dc,0x5dc,0x5dc,0x5dc,0x5dc,0x5dc,0x5dc,0x5dc,0x5dc,0x5dc,0x5dc,0x5dc,
+0x5df,0x13e6,0x13e6,0x13e6,0x5df,0x5df,0x5df,0x5df,0x5df,0x5df,0x5df,0x5df,0x152a,0x5eb,0x5f4,0x5eb,
+0x5eb,0x13e6,0x5df,0x5df,0x5f4,0x5f4,0x13e9,0x13e9,0x5f7,0x5f7,0x5e8,0x5ee,0x5e8,0x5e8,0x5ee,0x5df,
+0x5ee,0x5df,0x5ee,0x5df,0x5df,0x5df,0x5df,0x5df,0x5df,0x5ee,0x5df,0x5df,0x5df,0x5df,0x5df,0x5df,
+0x13e6,0x5df,0x5df,0x5df,0x5df,0x5df,0x5df,0x5df,0x5df,0x5df,0x5df,0x5ee,0x5ee,0x5df,0x5df,0x5df,
+0x5df,0x5df,0x5df,0x5df,0x5df,0x753,0x5df,0x5df,0x5df,0x5df,0x5df,0x5df,0x5ee,0x5df,0x5df,0x5ee,
+0x5df,0x5df,0x5df,0x5df,0x13e6,0x5df,0x13e6,0x5df,0x5df,0x5df,0x5df,0x13e6,0x13e6,0x13e6,0x5df,0x12de,
+0x5df,0x5df,0x5df,0x5e5,0x5e5,0x5e5,0x5e5,0x1368,0x1368,0x5df,0x5e2,0x5f1,0x5f4,0x5e8,0x5e8,0x5e8,
+0xc21,0xc1e,0xc21,0xc1e,0xc21,0xc1e,0xc21,0xc1e,0xc21,0xc1e,0xc21,0xc1e,0xc21,0xc1e,0x750,0x750,
+0x750,0x750,0x750,0x750,0x750,0x750,0x750,0x750,0x5df,0x5ee,0x5df,0x5df,0x5df,0x5df,0x5df,0x5df,
+0x5df,0x5df,0x5df,0x5df,0x5df,0x5df,0x5df,0x5df,0x13e6,0x5df,0x5df,0x5df,0x5df,0x5df,0x5df,0x5df,
+0x5df,0x5df,0x5df,0x5df,0x5df,0x5df,0x5df,0x13e6,0x618,0x618,0x618,0x618,0x618,0x618,0x618,0x618,
+0x618,0x618,0x618,0x618,0x618,0x61b,0x61b,0x61b,0x61b,0x61b,0x61b,0x61b,0x621,0x621,0x621,0x621,
+0x621,0x621,0x621,0x621,0x618,0x61e,0x60f,0x612,0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,
+0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,
+0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,0x615,0x615,0x615,0x615,0x615,0x615,0x618,0x618,0x618,0x618,
+0x618,0x618,0x618,0x618,0x618,0x618,0x618,0x618,0x618,0x618,0x618,0x618,0x618,0x618,0x618,0x618,
+0x618,0x618,0x618,0x618,0x618,0x618,0x618,0x618,0x61b,0x621,0x61e,0x618,0x61b,0x621,0x61e,0x618,
+0x61b,0x621,0x61e,0x618,0x61b,0x621,0x61e,0x618,0x61b,0x621,0x61e,0x618,0x61b,0x621,0x61e,0x618,
+0x61b,0x621,0x61e,0x618,0x61b,0x621,0x61e,0x618,0x61e,0x618,0x61e,0x618,0x61e,0x618,0x61e,0x618,
+0x61e,0x618,0x61e,0x618,0x61b,0x621,0x61e,0x618,0x61b,0x621,0x61e,0x618,0x61b,0x621,0x61e,0x618,
+0x61b,0x621,0x61e,0x618,0x61e,0x618,0x61b,0x621,0x61e,0x618,0x61e,0x618,0x61b,0x621,0x61e,0x618,
+0x61b,0x621,0x61e,0x618,0x61e,0x618,0x136b,0x136b,0x136b,0x136b,0x136b,0x136b,0x136b,0x136b,0x136b,0x136b,
+0x136b,0x136b,0x136b,0x136b,0x61e,0x618,0x61e,0x618,0x61e,0x618,0x61b,0x621,0x61b,0x621,0x61e,0x618,
+0x61e,0x618,0x61e,0x618,0x61e,0x618,0x61e,0x618,0x61e,0x618,0x61e,0x618,0x61b,0x61e,0x618,0x61b,
+0x61e,0x618,0x61b,0x621,0x618,0x618,0x618,0x618,0x618,0x618,0x618,0x618,0x618,0x618,0x618,0x618,
+0x618,0x618,0x618,0x618,0x618,0x618,0x618,0x618,0x618,0x618,0x618,0x61b,0x61b,0x61b,0x61b,0x61b,
+0x61b,0x61b,0x61b,0x61b,0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,
+0x61e,0x61e,0x61e,0x61e,0x61e,0x618,0x618,0x618,0x618,0x618,0x618,0x618,0x618,0x618,0x618,0x618,
+0x618,0x618,0x618,0x618,0x61b,0x61b,0x618,0x61b,0x618,0x61b,0x618,0x618,0x61b,0x618,0x618,0x61b,
+0x618,0x61b,0x618,0x618,0x61b,0x618,0x61b,0x61b,0x618,0x618,0x618,0x61b,0x618,0x618,0x618,0x618,
+0x618,0x61b,0x618,0x618,0x618,0x618,0x618,0x618,0x618,0x618,0x618,0x618,0x618,0x618,0x618,0x618,
+0x618,0x618,0x618,0x618,0x618,0x618,0x618,0x618,0x61b,0x61b,0x618,0x618,0x61b,0x618,0x61b,0x618,
+0x618,0x618,0x618,0x618,0x61b,0x61b,0x61b,0x61b,0x61b,0x61b,0x61b,0x61b,0x61b,0x61b,0x61b,0x61b,
+0x61b,0x61b,0x61b,0x61b,0x61b,0x61b,0x61b,0x61b,0x61b,0x61b,0x61b,0x61b,0x61b,0x61b,0x61b,0x61b,
+0x61b,0x61b,0x61b,0x61b,0x61b,0x61b,0x61b,0x621,0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,
+0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,
+0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,0x621,0x621,0x621,0x621,0x621,0x621,0x621,0x621,
+0x621,0x621,0x621,0x621,0x621,0x621,0x621,0x621,0x621,0x621,0x621,0x621,0x621,0x61e,0x61e,0x61e,
+0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,0x624,0x624,0x624,0x624,0x101a,0x101a,0x101a,0x152d,
+0x152d,0x152d,0x152d,0x152d,0x152d,0x152d,0x173a,0x173a,0x885,0x88b,0x88b,0x897,0x897,0x888,0x87f,0x888,
+0x87f,0x888,0x87f,0x888,0x87f,0x888,0x87f,0x888,0x633,0x633,0x62d,0x633,0x62d,0x633,0x62d,0x633,
+0x62d,0x633,0x62d,0x630,0x636,0x633,0x62d,0x633,0x62d,0x630,0x636,0x633,0x62d,0x633,0x62d,0x630,
+0x636,0x633,0x62d,0x630,0x636,0x633,0x62d,0x630,0x636,0x633,0x62d,0x633,0x62d,0x633,0x62d,0x633,
+0x62d,0x633,0x62d,0x630,0x636,0x633,0x62d,0x630,0x636,0x633,0x62d,0x630,0x636,0x633,0x62d,0x630,
+0x636,0x633,0x62d,0x630,0x636,0x633,0x62d,0x630,0x636,0x633,0x62d,0x630,0x636,0x633,0x62d,0x630,
+0x636,0x633,0x62d,0x630,0x720,0x720,0x720,0x720,0x720,0x720,0x720,0x720,0x720,0x720,0x720,0x720,
+0x720,0x720,0x720,0x720,0x720,0x720,0x720,0x720,0x71d,0x71d,0x71d,0x71d,0x71d,0x71d,0x71d,0x71d,
+0x71d,0x71d,0x71d,0x71d,0x71d,0x71d,0x71d,0x71d,0x71d,0x71d,0x71d,0x71d,0x71d,0x71d,0x71d,0x71d,
+0x71d,0x71d,0x71d,0x71d,0x71d,0x71d,0x71d,0x71d,0x71d,0x71d,0x726,0x726,0x726,0x726,0x726,0x726,
+0x726,0x726,0x726,0x726,0x726,0x726,0x729,0x726,0x726,0x726,0x726,0x726,0x726,0x726,0x726,0x726,
+0x726,0x726,0x726,0x726,0x723,0x723,0x723,0x723,0x723,0x723,0x723,0x723,0x723,0x723,0x723,0x723,
+0x723,0x723,0x723,0x723,0x72c,0x72c,0x72c,0x72c,0x72c,0x72c,0x72c,0x72c,0x72c,0x72c,0x72c,0x72c,
+0x72c,0x72c,0x72c,0x72c,0x72c,0x72c,0x72c,0x72c,0x72c,0x72c,0x72c,0x72c,0x72c,0x72c,0x72c,0x72c,
+0x72c,0x72c,0x72c,0x72c,0x756,0x756,0x756,0x756,0x756,0x756,0x756,0x756,0x756,0x756,0x756,0x756,
+0x756,0x756,0x756,0x756,0x756,0x756,0x756,0x756,0x756,0x756,0x756,0x756,0x756,0x756,0x756,0x756,
+0x756,0x756,0x756,0x756,0xc78,0x8e8,0x8e2,0x8df,0x8e5,0x8dc,0x76b,0x76e,0x76e,0x76e,0x76e,0x76e,
+0x76e,0x76e,0x76e,0x76e,0x8ee,0x76b,0x76b,0x76b,0x76b,0x76b,0x76b,0x76b,0x76b,0x76b,0x76b,0x76b,
+0x76b,0x76b,0x76b,0x76b,0x76b,0x76b,0x76b,0x76b,0x76b,0x76b,0x76b,0x76b,0x76b,0x76b,0x76b,0x76b,
+0x76b,0x76b,0x76b,0x76b,0x76b,0x76b,0x8eb,0x8eb,0x771,0x8fd,0x900,0x906,0x82b,0x837,0x91b,0x834,
+0x8f4,0x8f1,0x8f4,0x8f1,0x8fa,0x8f7,0x8fa,0x8f7,0x8f4,0x8f1,0x831,0x906,0x8f4,0x8f1,0x8f4,0x8f1,
+0x8f4,0x8f1,0x8f4,0x8f1,0x909,0x912,0x90f,0x90f,0x777,0x7b3,0x7b3,0x7b3,0x7b3,0x7b3,0x7b3,0x7ad,
+0x7ad,0x7ad,0x7ad,0x7ad,0x7ad,0x7ad,0x7ad,0x7ad,0x7ad,0x7ad,0x7ad,0x7ad,0x7ad,0x7ad,0x7ad,0x7ad,
+0x7ad,0x7ad,0x7ad,0x77a,0x795,0x774,0x79b,0x79e,0x798,0x7b0,0x7b0,0x7b0,0x7b0,0x7b0,0x7b0,0x7aa,
+0x7aa,0x7aa,0x7aa,0x7aa,0x7aa,0x7aa,0x7aa,0x7aa,0x7aa,0x7aa,0x7aa,0x7aa,0x7aa,0x7aa,0x7aa,0x7aa,
+0x7aa,0x7aa,0x7aa,0x77a,0x795,0x774,0x795,0xc7b,0x819,0x819,0x819,0x819,0x819,0x819,0x819,0x819,
+0x819,0x819,0x819,0x819,0x819,0x819,0x819,0x819,0x819,0x819,0x819,0x819,0x819,0x819,0x819,0x819,
+0x819,0x819,0x819,0x819,0x819,0x819,0x819,0x819,0x819,0x819,0x12d8,0x12d8,0x12d8,0x12d8,0x12d8,0x81c,
+0x831,0x834,0x834,0x834,0x834,0x834,0x834,0x834,0x834,0x834,0x951,0x951,0x951,0x951,0x83a,0x83a,
+0x90c,0x918,0x918,0x918,0x918,0x915,0x82e,0x903,0xb3d,0xb3d,0xb3d,0xc8d,0xcab,0xca8,0xb5b,0x8d9,
+0x840,0x83d,0x840,0x843,0x83d,0x840,0x83d,0x840,0x83d,0x840,0x83d,0x83d,0x83d,0x83d,0x83d,0x83d,
+0x840,0x840,0x83d,0x840,0x840,0x83d,0x840,0x840,0x83d,0x840,0x840,0x83d,0x840,0x840,0x83d,0x83d,
+0xcae,0x852,0x84c,0x852,0x84c,0x852,0x84c,0x852,0x84c,0x852,0x84c,0x84c,0x84f,0x84c,0x84f,0x84c,
+0x84f,0x84c,0x84f,0x84c,0x84f,0x84c,0x84f,0x84c,0x84f,0x84c,0x84f,0x84c,0x84f,0x84c,0x84f,0x84c,
+0x84f,0x84c,0x84f,0x852,0x84c,0x84f,0x84c,0x84f,0x84c,0x84f,0x84c,0x84c,0x84c,0x84c,0x84c,0x84c,
+0x84f,0x84f,0x84c,0x84f,0x84f,0x84c,0x84f,0x84f,0x84c,0x84f,0x84f,0x84c,0x84f,0x84f,0x84c,0x84c,
+0x84c,0x84c,0x84c,0x852,0x84c,0x852,0x84c,0x852,0x84c,0x84c,0x84c,0x84c,0x84c,0x84c,0x852,0x84c,
+0x84c,0x84c,0x84c,0x84c,0x84f,0x852,0x852,0x84f,0x84f,0x84f,0x84f,0x921,0x924,0x855,0x858,0xc96,
+0x85e,0x85e,0x85e,0x85e,0x85e,0x85e,0x85e,0x85e,0x85e,0x85e,0x85e,0x85e,0x85e,0x85e,0x85e,0x85e,
+0x85e,0x85e,0x85e,0x85e,0x85e,0x85e,0x85e,0x85e,0x85e,0x85e,0x85e,0x85e,0x85e,0x85e,0x85e,0x85e,
+0x861,0x85e,0x85e,0x85e,0x85e,0x85e,0x85e,0x85e,0x85e,0x85e,0x85e,0x85e,0x85e,0x85e,0x85e,0x85e,
+0x85e,0x85e,0x85e,0x85e,0x85e,0x85e,0x85e,0x85e,0x85e,0x85e,0x85e,0x85e,0x86a,0x86a,0x86a,0x86a,
+0x86a,0x86a,0x86a,0x86a,0x86a,0x86a,0x86a,0x86a,0x86a,0x86a,0x86a,0x86a,0x86a,0x86a,0x86a,0x86a,
+0x86a,0x86a,0x86a,0x86a,0x86a,0x86a,0x86a,0x86a,0xd9b,0xd9b,0xeca,0x864,0x92d,0x92d,0x92d,0x92d,
+0x92d,0x92d,0x92d,0x92d,0x92d,0x92d,0x92d,0x92d,0xd95,0xd95,0xd95,0xd95,0x86d,0x86d,0x86d,0x86d,
+0x86d,0x86d,0x86d,0x86d,0x86d,0x86d,0x86d,0x86d,0x86d,0x86d,0x86d,0x86d,0x86d,0x86d,0x86d,0x86d,
+0x86d,0x86d,0x86d,0x86d,0x86d,0x86d,0x86d,0x86d,0x86d,0x86d,0x86d,0x1ab2,0x936,0x936,0x936,0x936,
+0x936,0x936,0x936,0x936,0x936,0x936,0x936,0x936,0x936,0x936,0x936,0x936,0x936,0x870,0x870,0x870,
+0x870,0x870,0x870,0xd9e,0xd9e,0xd9e,0xd9e,0x939,0x939,0x939,0x939,0x939,0x870,0x870,0x870,0x870,
+0x870,0x870,0x870,0x870,0x870,0x870,0x870,0x870,0x870,0x870,0x870,0x870,0x870,0x870,0x870,0x870,
+0x870,0x870,0x870,0x870,0x870,0x870,0x870,0x870,0x870,0x870,0x870,0x870,0x870,0x870,0xd9e,0xd9e,
+0x873,0x873,0x873,0x873,0x873,0x873,0x873,0x873,0x873,0x873,0x873,0x873,0x873,0x873,0x873,0x873,
+0x873,0x873,0x873,0x873,0x873,0x873,0x873,0x873,0x873,0x873,0x873,0x873,0x873,0x873,0x873,0x873,
+0x936,0x936,0x936,0x936,0x936,0x936,0x936,0x936,0x876,0x876,0x876,0x876,0x876,0x876,0x876,0x876,
+0x876,0x876,0x876,0x876,0x876,0x876,0x876,0x876,0x876,0x876,0x876,0x876,0x876,0x876,0x876,0x876,
+0x876,0x876,0x876,0x876,0x876,0x876,0x876,0x876,0x876,0x876,0xecd,0xecd,0xecd,0xecd,0xecd,0xecd,
+0xecd,0xecd,0xecd,0xecd,0xecd,0xecd,0xecd,0xecd,0xecd,0xecd,0xecd,0xecd,0xecd,0xecd,0xecd,0xecd,
+0x113d,0x113d,0x113d,0x113d,0x879,0x879,0x879,0x879,0x879,0x879,0x879,0x879,0x879,0x879,0x879,0x879,
+0x879,0x879,0x879,0x879,0x879,0x879,0x879,0x879,0x879,0x879,0x879,0x879,0x879,0x879,0x879,0x879,
+0x879,0x879,0x879,0x879,0x879,0x879,0x87c,0x87c,0x879,0x87c,0x879,0x87c,0x87c,0x879,0x879,0x879,
+0x879,0x879,0x879,0x879,0x879,0x879,0x879,0x87c,0x879,0x87c,0x879,0x87c,0x87c,0x879,0x879,0x87c,
+0x87c,0x87c,0x879,0x879,0x879,0x879,0x14e5,0x14e5,0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,
+0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,0x92d,0x92d,0x92d,0x92d,0x92d,0x92d,0x92d,0x92d,
+0x92d,0x92d,0x92d,0x92d,0x92d,0x92d,0x92d,0x92d,0x92d,0x92d,0x92d,0x92d,0x92d,0x92d,0x92d,0x92d,
+0x92d,0x92d,0x92d,0x92d,0x92d,0x92d,0x92d,0x92d,0x131d,0x131d,0x131d,0x131d,0x12bd,0x12bd,0x12bd,0x12bd,
+0x12bd,0x12bd,0x12bd,0x12bd,0xd95,0xc99,0xc99,0xc99,0xc99,0xc99,0xc99,0xc99,0xc99,0xc99,0xc99,0xc99,
+0xc99,0xc99,0xc99,0xc99,0x930,0x930,0x930,0x930,0x930,0x930,0x930,0x930,0x930,0x930,0x930,0x930,
+0x930,0x930,0x930,0x930,0x930,0x930,0x930,0x930,0x930,0x930,0x930,0x933,0x930,0x933,0x930,0x930,
+0x930,0x930,0x930,0x930,0x930,0x930,0x930,0x930,0x930,0x930,0x930,0x930,0x930,0x930,0x930,0x930,
+0x930,0xc99,0xc99,0xc99,0xc99,0xc99,0xc99,0xc99,0xc99,0xc99,0xc99,0xc99,0xc99,0xc99,0xc99,0xc99,
+0x936,0x936,0x936,0x936,0x936,0x936,0x936,0x936,0x936,0x936,0x936,0x936,0x936,0x936,0x936,0x936,
+0x936,0x936,0x936,0x936,0x936,0x936,0x936,0x936,0x936,0x936,0x936,0x936,0x936,0x936,0x936,0xd9e,
+0x9b7,0x999,0x999,0x999,0x999,0x993,0x999,0x999,0x9ab,0x999,0x999,0x996,0x9a2,0x9a8,0x9a8,0x9a8,
+0x9a8,0x9a8,0x9ab,0x993,0x99f,0x993,0x993,0x993,0x98a,0x98a,0x993,0x993,0x993,0x993,0x993,0x993,
+0x9ae,0x9ae,0x9ae,0x9ae,0x9ae,0x9ae,0x9ae,0x9ae,0x9ae,0x9ae,0x993,0x993,0x993,0x993,0x993,0x993,
+0x993,0x993,0x993,0x993,0x996,0x98a,0x993,0x98a,0x993,0x98a,0x9a5,0x99c,0x9a5,0x99c,0x9b4,0x9b4,
+0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,
+0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,
+0x9c6,0x9c6,0x9c6,0x9c6,0x9c6,0x9c6,0x9c6,0x9c6,0x9c6,0x9c6,0x9c6,0x9c6,0x9c6,0x9c6,0x9c6,0x9c6,
+0x9c6,0x9c6,0x9c6,0x9c6,0x9c6,0x9c6,0x9c6,0x9c6,0x9c6,0x9c6,0x9c6,0x9c6,0x9c6,0x9c6,0x9c6,0x9c6,
+0x9c9,0x9c9,0x9c9,0x9c9,0x9c9,0x9c9,0x9c9,0x9c9,0x9c9,0x9c9,0x9c9,0x9c9,0x9c9,0x9c9,0x9c9,0x9c9,
+0x9c9,0x9c9,0x9c9,0x9c9,0x9c9,0x9c9,0x9c9,0x9c9,0x9c9,0x9c9,0x9c9,0x9c9,0x9c9,0x9c9,0x9c9,0x9c9,
+0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,
+0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9cc,0x9cc,
+0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,
+0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,0x9cf,0x9cf,
+0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,
+0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,
+0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,
+0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,
+0x9d8,0x9db,0x9db,0x9db,0x9db,0x9db,0x9db,0x9db,0x9db,0x9db,0x9db,0x9db,0x9db,0x9db,0x9db,0x9db,
+0x9db,0x9db,0x9db,0x9db,0x9db,0x9db,0x9db,0x9db,0x9db,0x9db,0x9db,0x9db,0x9d8,0x9db,0x9db,0x9db,
+0x9db,0x9db,0x9db,0x9db,0x9db,0x9db,0x9db,0x9db,0x9db,0x9db,0x9db,0x9db,0x9db,0x9db,0x9db,0x9db,
+0x9db,0x9db,0x9db,0x9db,0x9db,0x9db,0x9db,0x9db,0xa68,0xa68,0xfff,0xa68,0xa68,0xa68,0xa6b,0xa68,
+0xfff,0xa68,0xa68,0xff6,0xa62,0xa56,0xa56,0xa56,0xa56,0xa65,0xa56,0xfe7,0xfe7,0xfe7,0xa56,0xa59,
+0xa62,0xa5c,0xfed,0xff9,0xff9,0xfe7,0xfe7,0xfff,0xb61,0xb61,0xb61,0xb61,0xb61,0xb61,0xb61,0xb61,
+0xb61,0xb61,0xa6e,0xa6e,0xa5f,0xa5f,0xa5f,0xa5f,0xa68,0xa68,0xa68,0xa68,0xa68,0xa68,0xa65,0xa65,
+0xa56,0xa56,0xfff,0xfff,0xfff,0xfff,0xfe7,0xfe7,0xa68,0xa68,0xa68,0xa68,0xa68,0xa68,0xa68,0xa68,
+0xa68,0xa68,0xa68,0xa68,0xa68,0xa68,0xa68,0xa68,0xa68,0xa68,0xa68,0xa68,0xa68,0xa68,0xa68,0xa68,
+0xa68,0xa68,0xa68,0xa68,0xa68,0xa68,0xa68,0xa68,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xdf2,
+0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,
+0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,
+0xa7d,0xa7d,0xa7d,0xdf2,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,0xa7d,
+0xa7d,0xa7d,0xa7d,0xa7d,0xa83,0xa83,0xa83,0xa83,0xa83,0xa83,0xa83,0xa83,0xa83,0xa83,0xa83,0xa83,
+0xa83,0xa83,0xa83,0xa83,0xa83,0xa83,0xa83,0xa83,0xa83,0xa83,0xa83,0xa83,0xa83,0xa83,0xa83,0xa83,
+0xa83,0xa83,0xa83,0xa83,0xa89,0xa89,0xa89,0xa89,0xa89,0xa89,0xa89,0xa89,0xa89,0xa89,0xa89,0xa89,
+0xa89,0xa86,0xa8c,0xa89,0xa89,0xa89,0xa89,0xa89,0xa89,0xa89,0xa89,0x1176,0x1176,0x1176,0x1176,0x1176,
+0x1176,0x1176,0x1176,0x1176,0x1173,0xa89,0xa89,0xa89,0xa89,0xa89,0xa89,0xa89,0xa89,0xa89,0xa89,0xa89,
+0xa89,0xa89,0xa89,0xa89,0xa89,0xa89,0xa89,0xa89,0xa89,0xa89,0xa89,0xa89,0xa89,0xa89,0xa89,0xa89,
+0xa89,0xa89,0xa89,0xa89,0xa89,0xa89,0xa89,0xa89,0xa9e,0xa9e,0xa9e,0xa9e,0xa9e,0xa9e,0xa9e,0xa9e,
+0xa9e,0xa9e,0xa9e,0xa9e,0xa9e,0xa9e,0xa9e,0xa9e,0xa9e,0xa9e,0xa9e,0xa9e,0xa9e,0xa9e,0xa9e,0xa9e,
+0xa9e,0xa9e,0xa9e,0xa9e,0xa9e,0xa9e,0xa9e,0xa9e,0xac2,0xac2,0xac2,0xac5,0xac5,0xac2,0xac2,0xac2,
+0xac2,0xac2,0xac2,0xac2,0xac2,0xac2,0xac2,0xac2,0xac2,0xac2,0xac2,0xac2,0xaaa,0xaaa,0xabf,0xaa1,
+0xaa1,0xaa1,0xaa1,0xaa1,0xaa1,0xaa1,0xabf,0xabf,0xac2,0xac2,0xac2,0xac2,0xac2,0xac2,0xac2,0xac2,
+0xac2,0xac2,0xac2,0xac2,0xac2,0xac2,0xac2,0xac2,0xac2,0xac2,0xac2,0xac2,0xac2,0xac2,0xac2,0xac2,
+0xac2,0xac2,0xac2,0xac2,0xac2,0xac2,0xac2,0xac2,0xae3,0xae3,0xae3,0xae3,0xae3,0xace,0xace,0xae3,
+0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,
+0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,
+0xae3,0xae3,0xae3,0xae6,0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,
+0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,0xae3,
+0xb0d,0xb0d,0xb0d,0xb0d,0xb0d,0xb0d,0xb0d,0xb0d,0xb10,0xb0d,0xb0d,0xb0d,0xb0d,0xb0d,0xb0d,0xb0d,
+0xb0d,0xb0d,0xb0d,0xb0d,0xb0d,0xb0d,0xb0d,0xb0d,0xb0d,0xb0d,0xb0d,0xc06,0xc06,0xc06,0xc06,0xc06,
+0xb1c,0xb1c,0xb1c,0xb1c,0xb1c,0xb1c,0xb1c,0xb1c,0xb1c,0xb1c,0xb1c,0xb1c,0xb1c,0xb1c,0xb1c,0xb1c,
+0xb1c,0xb1c,0xb1c,0xb1c,0xb1c,0xb1c,0xb1c,0xb1c,0xb1c,0xb1c,0xb1c,0xb1c,0xb1c,0xb1c,0xb1c,0xb1c,
+0xb2e,0xb2e,0xb2e,0xb2e,0xb2e,0xb2e,0xb2e,0xb2e,0xb2e,0xb2e,0xb2e,0xb2e,0xb2e,0xb2e,0xb2e,0xb2e,
+0xb2e,0xb2e,0xb2e,0xb2e,0xb2e,0xb2e,0xb2e,0xb2e,0xb2e,0xb2e,0xb2e,0xb2e,0xb2e,0xb2e,0xb2e,0xb2e,
+0xb34,0xb34,0xb34,0xb34,0xb34,0xb34,0xb34,0xb34,0xb34,0xb34,0xb34,0xb34,0xb34,0xb34,0xb34,0xb34,
+0xb34,0xb34,0xb34,0xb34,0xb34,0xb34,0xb34,0xb34,0xb34,0xb34,0xb34,0xb34,0xb34,0xb34,0xb34,0xb34,
+0xb40,0xb40,0xb40,0xb40,0xb40,0xb40,0xb40,0xb40,0xb40,0xb40,0xb40,0xb40,0xb40,0xb40,0xb40,0xb40,
+0xb40,0xb40,0xb40,0xb40,0xb40,0xb40,0xb40,0xb40,0x13ec,0x13ec,0x13ec,0x1b2d,0x1b2d,0x1b2d,0x1b2d,0x1b2d,
+0xb43,0xb43,0xb43,0xb43,0xb43,0xb43,0xb43,0xb43,0xb43,0xb43,0xb43,0xb43,0xb43,0xb43,0xb43,0xb43,
+0xb43,0xb43,0xb43,0xb43,0xb43,0xb43,0xb43,0xb43,0xb43,0xb43,0xb43,0xb43,0xb43,0xb43,0xb43,0xb43,
+0xb43,0xb43,0x1b30,0x1b30,0x1b30,0x1b30,0x1b30,0x1b30,0x1b30,0x1b30,0x1b30,0x1b30,0xb46,0xb46,0xb46,0xb46,
+0xb46,0xb46,0xb46,0xb46,0xb46,0xb46,0xb46,0xb46,0xb46,0xb46,0xb46,0xb46,0xb46,0xb46,0xb46,0xb46,
+0xb46,0xb49,0xb46,0xb46,0xb46,0xb46,0xb46,0xb46,0xb46,0xb46,0xb46,0xb46,0xb46,0xb46,0xb46,0xb46,
+0xb46,0xb46,0xb46,0xb46,0xb46,0xb46,0xb46,0xb46,0xb46,0xb46,0xb46,0xb46,0xb46,0xb46,0xb46,0xb46,
+0xb46,0xb46,0xb46,0xb46,0xb4c,0xb4c,0xc9c,0xc9c,0xb4c,0xb4c,0xb4c,0xb4c,0xb4c,0xb4c,0xb4c,0xb4c,
+0xb4c,0xb4c,0xb4c,0xb4c,0xb4c,0xb4c,0xb4c,0xb4c,0xc9c,0xb4c,0xb4c,0xb4c,0xb4c,0xb4c,0xb4c,0xb4c,
+0xb4c,0xb4c,0xb4c,0xb4c,0xb70,0xb70,0xb70,0xb70,0xb70,0xb70,0xb70,0xb70,0xb70,0xb70,0xb70,0xb70,
+0xb70,0xb70,0xb70,0xb70,0xb70,0xb70,0xb70,0xb70,0xb70,0xb70,0xb70,0xb70,0xb70,0xb70,0xb70,0xb70,
+0xb70,0xb70,0xb70,0x1530,0xb79,0xb79,0xb79,0xb79,0xb79,0xb79,0xd26,0xd26,0xb76,0xb76,0xb76,0xb76,
+0xb76,0xb76,0xb76,0xb76,0xb76,0xb76,0xb76,0xb76,0xb76,0xb76,0xb76,0xb76,0xb76,0xb76,0xb76,0xb76,
+0xb76,0xb76,0xb76,0xb76,0xb76,0xb76,0xd23,0xd23,0xd74,0xd74,0xd74,0xd74,0xd74,0xd74,0xd74,0xd74,
+0xd74,0xd74,0xd74,0xd74,0xd74,0xd74,0xd74,0xd74,0xb79,0xb79,0xb79,0xb79,0xb79,0xb79,0xb79,0xb79,
+0xb79,0xb79,0xb79,0xb79,0xb79,0xb79,0xb79,0xb79,0xb79,0xb79,0xb79,0xb79,0xb79,0xb79,0xb79,0xb79,
+0xb79,0xb79,0xb79,0xb79,0xb79,0xb79,0xb79,0xb79,0xb7c,0xb7c,0xb7c,0xb7c,0xb7c,0xb7c,0xb7c,0xb7c,
+0xb7c,0xb7c,0xb7c,0xb7c,0xb7c,0xb7c,0xb7c,0xb7c,0xb7c,0xb7c,0xb7c,0xb7c,0xb7c,0xb7c,0xb7c,0xb7c,
+0xb7c,0xb7c,0xb7c,0xb7c,0xb7c,0xb7c,0xb7c,0xb7c,0xb8b,0xb8b,0xb8b,0xb8b,0xb8b,0xb82,0xb8e,0xb94,
+0xb94,0xb94,0xb88,0xb88,0xb88,0xb91,0xb85,0xb85,0xb85,0xb85,0xb85,0xb7f,0xb7f,0xb7f,0xb7f,0xb7f,
+0xb7f,0xb7f,0xb7f,0xb94,0xb94,0xb94,0xb94,0xb94,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,
+0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,
+0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb8b,0xb8b,0xb94,0xb94,0xb94,0xb88,
+0xb88,0xb94,0xb94,0xb94,0xb94,0xb94,0xb94,0xb94,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,
+0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb94,0xb94,
+0xb94,0xb94,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb8b,
+0xb8b,0xb8b,0xb8b,0xb8b,0xb8b,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,
+0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,0xb88,
+0xb88,0xb88,0x173d,0x173d,0xba0,0xb97,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,
+0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb97,
+0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,
+0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xb97,
+0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,
+0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb97,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xba0,0xba0,0xba0,0xba0,
+0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,
+0xba0,0xb97,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,
+0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9a,0xb9a,0xb9a,0xb9a,0xb9a,0xb9a,0xb9a,0xb9a,
+0xb9a,0xb9a,0xb9a,0xb9a,0xb9a,0xb9a,0xb9a,0xb9a,0xb9a,0xb9a,0xb9a,0xb9a,0xb9a,0xb9a,0xb9a,0xb9a,
+0xb9a,0xb9a,0xb9a,0xb9a,0xb9a,0xb9a,0xb9a,0xb9a,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,
+0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,
+0xba0,0xba0,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,
+0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,
+0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,0xba0,
+0xba0,0xba0,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,
+0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xba0,0xba0,0xba0,0xba0,
+0xba3,0xba3,0xba3,0xba3,0xba3,0xba3,0xba3,0xba3,0xba3,0xba3,0xba3,0xba3,0xba3,0xba3,0xba3,0xba3,
+0xba3,0xba3,0xba3,0xba3,0xba3,0xba3,0xba3,0xba3,0xba3,0xba3,0xba3,0xba3,0xba3,0xba3,0xba3,0xba3,
+0xba9,0xba9,0xba9,0xba9,0xba9,0xba9,0xba9,0xba9,0xba9,0xba9,0xba9,0xba9,0xba9,0xba9,0xba9,0xba9,
+0xba9,0xba9,0xba9,0xba9,0xba9,0xba9,0xba9,0xba9,0xba9,0xba9,0xba9,0xba9,0xba9,0xba9,0xba9,0xba9,
+0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,
+0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,
+0xc06,0xc06,0xc06,0xc06,0xc06,0xc06,0xc06,0xc06,0xc06,0xc06,0xc06,0xc06,0xc06,0xc06,0xc06,0xc06,
+0xc06,0xc06,0xc06,0xc06,0xc06,0xc06,0xc03,0xc06,0xc03,0xc03,0xc03,0xc03,0xc03,0xc03,0xc03,0xc03,
+0xc03,0xc03,0xc03,0xc03,0xc03,0xc03,0xc03,0xd14,0xd17,0xe0a,0xe0a,0xe0a,0xe0a,0xe0a,0xe0a,0xe0a,
+0xe0a,0xe0a,0xe0a,0xe0a,0xf24,0xf24,0xf24,0xf24,0xc18,0xc18,0xc18,0xc18,0xc18,0xc18,0xc12,0xc12,
+0xc12,0xc12,0xd1a,0xd1a,0xd1a,0xd1a,0xd1a,0xd1a,0xd1d,0xd1d,0xe10,0xec4,0xe10,0xe10,0xe10,0xe10,
+0xe0d,0xe10,0xe0d,0xe10,0xe10,0x1014,0x12ae,0x12ae,0xe19,0xe19,0xe19,0xe19,0xe19,0xe1f,0xe1c,0xf36,
+0xf36,0xf36,0xf36,0x142e,0x1026,0x142e,0x1374,0x1374,0xc4e,0xc4e,0xc4e,0xc4e,0xc4e,0xc4e,0xc4e,0xc4e,
+0xc4e,0xc4e,0xc4e,0xc4e,0xc4e,0xc4e,0xc4e,0xc4e,0xc4e,0xc4e,0xc81,0xc7e,0xc81,0xc7e,0xc81,0xc7e,
+0x1137,0x1134,0x102c,0x1029,0xc51,0xc51,0xc51,0xc51,0xc51,0xc51,0xc51,0xc51,0xc51,0xc51,0xc51,0xc51,
+0xc51,0xc51,0xc51,0xc51,0xc54,0xc54,0xc54,0xc54,0xc54,0xc54,0xc54,0xc54,0xc54,0xc54,0xc54,0xc54,
+0xc54,0xc54,0xc54,0xc54,0xc54,0xc54,0xc54,0xc54,0xc54,0xc54,0xc54,0xc54,0xc54,0xc54,0xc54,0xc54,
+0xc54,0xc54,0xc54,0xc54,0xc57,0xc57,0xc54,0xc54,0xc54,0xc54,0xc54,0xc54,0xc54,0xc54,0xc54,0xc54,
+0xc5a,0xc5a,0xc5a,0xc60,0xc5d,0xc87,0xc84,0xc60,0xc5d,0xc60,0xc5d,0xc60,0xc5d,0xc60,0xc5d,0xc60,
+0xc5d,0xc60,0xc5d,0xc60,0xc5d,0xc60,0xc5d,0xc60,0xc5d,0xc5a,0xc5a,0xc5a,0xc5a,0xc5a,0xc5a,0xc5a,
+0xc5a,0xc5a,0xc5a,0xc5a,0xc5a,0xc5a,0xc5a,0xc5a,0xc5a,0xc5a,0xc5a,0xc5a,0xc5a,0xc5a,0xc5a,0xc5a,
+0xc5a,0xc5a,0xc5a,0xc5a,0xc5a,0xc5a,0xc5a,0xc5a,0xc5a,0xc5a,0xc5a,0xc5a,0xc60,0xc5d,0xc60,0xc5d,
+0xc5a,0xc5a,0xc5a,0xc5a,0xc5a,0xc5a,0xc5a,0xc5a,0xc5a,0xc5a,0xc5a,0xc5a,0xc5a,0xc5a,0xc5a,0xc5a,
+0xc5a,0xc5a,0xc5a,0xc5a,0xc5a,0xc5a,0xc5a,0xc5a,0xc5a,0xc5a,0xc5a,0xc5a,0xc60,0xc5d,0xc5a,0xc5a,
+0xc63,0xc63,0xc63,0xc63,0xc63,0xc63,0xc63,0xc63,0xc63,0xc63,0xc63,0xc63,0xc69,0xc63,0xc63,0xc63,
+0xc63,0xc63,0xc63,0xc63,0xc63,0xc63,0xc63,0xc63,0xc63,0xc63,0xc63,0xc63,0xc63,0xc63,0xc63,0xc63,
+0xc63,0xc63,0xc63,0xc63,0xc63,0xc63,0xc63,0xc63,0xc63,0xc63,0xc63,0xc63,0xc63,0xc63,0xc63,0xc63,
+0xc69,0xc69,0xc69,0xc63,0xc63,0xc63,0xc63,0xc63,0xc63,0xc63,0xc63,0xc63,0xc63,0xc63,0xc63,0xc63,
+0xc63,0xc63,0xc63,0xc63,0xc63,0xc63,0xc63,0xc63,0xc63,0xc63,0xc63,0xc63,0xc63,0xc63,0xc63,0xc63,
+0xc66,0xc63,0xc63,0xc63,0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,
+0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,
+0xc9f,0xc9f,0xc9f,0xc9f,0xd20,0xd8f,0xe0d,0xe0d,0xe0d,0xe0d,0xe0d,0xe10,0xe0d,0xe0d,0xec4,0xec4,
+0xe0d,0xe0d,0xe0d,0xe0d,0xe10,0xe10,0xf27,0x1014,0x1014,0x1014,0x1014,0x1014,0x1014,0x1014,0x1014,0x1014,
+0x1014,0x12db,0x12db,0x12b1,0xd44,0xd44,0xd44,0xd44,0xd44,0xd44,0xd44,0xd44,0xd44,0xd44,0xd44,0xd44,
+0xd44,0xd44,0xd44,0xd44,0xd44,0xd44,0xd44,0xd44,0xd44,0xd44,0xd44,0xd44,0xd44,0xd44,0xd44,0xd44,
+0xd44,0xd44,0xd44,0xd44,0xd53,0xd53,0xd53,0xd53,0xd53,0xd53,0xd4a,0xd4a,0xd4a,0xd4a,0xd4a,0xd47,
+0xd5c,0xd5c,0xd5c,0xd56,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd56,
+0xd5c,0xd5c,0xd5c,0xd5c,0xd50,0xd50,0xd59,0xd59,0xd59,0xd59,0xd4d,0xd4d,0xd4d,0xd4d,0xd4d,0xd53,
+0xe25,0xe25,0xe25,0xe25,0xe25,0xe25,0xe25,0xe25,0xe25,0xe25,0xe25,0xe25,0xe22,0xe25,0xe25,0xe25,
+0xe25,0xe25,0xe25,0xe25,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,
+0xd5c,0xd5c,0xd56,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,
+0xd5c,0xd50,0xd50,0xd50,0xd53,0xd53,0xd53,0xd53,0xd53,0xd53,0xd53,0xd53,0xd53,0xd53,0xd53,0xd53,
+0xd53,0xd53,0xd53,0xd53,0xd53,0xd53,0xd53,0xd53,0xd53,0xd53,0xd53,0xd53,0xd53,0xd53,0xd53,0xd53,
+0xd53,0xd53,0xd53,0xd53,0xd5f,0xd5f,0xd5f,0xd5f,0xd5f,0xd62,0xd62,0xd62,0xd5f,0xd5f,0xd5f,0xd5f,
+0xd5f,0xd5f,0xe28,0xe28,0xe28,0xe28,0xe28,0xe28,0xf39,0xf39,0xf39,0xf39,0xf39,0xf39,0xf39,0x1140,
+0x1140,0x102f,0x102f,0x102f,0xd65,0xd65,0xd65,0xd65,0xd65,0xd65,0xd65,0xd65,0xd65,0xd65,0xd65,0xd65,
+0xd65,0xd65,0xd65,0xd65,0xd65,0xd65,0xd65,0xd65,0xd65,0xd65,0xd65,0xd65,0xd65,0xd65,0xd65,0xd65,
+0xd65,0xd65,0xd65,0xd65,0xd6b,0xd6b,0xd6b,0xd6b,0xd6b,0xd6b,0xd6b,0xd6b,0xd6b,0xd6b,0xd6b,0xd6b,
+0xd6b,0xd6b,0xd6b,0xd6b,0xd6b,0xd6b,0xd6b,0xd6b,0xd6b,0xd6b,0xd6b,0xd6b,0xd6b,0xd6b,0xd6b,0xd6b,
+0xd6b,0xd6b,0xd6b,0xd6b,0xd74,0xd74,0xd74,0xd74,0xd74,0xd74,0xd74,0xd74,0xd74,0xd74,0xd74,0xd74,
+0xd74,0xd74,0xd74,0xd74,0xd74,0xd74,0xd74,0xd74,0xd74,0xd74,0xd74,0xd74,0xd74,0xd74,0xd74,0xd74,
+0xd74,0xd74,0xd74,0xd74,0xd80,0xd80,0xd80,0xd80,0xd80,0xd80,0xd80,0xd80,0xd80,0xd80,0xd80,0xd80,
+0xd80,0xd80,0xd80,0xd80,0xd80,0xd80,0xd80,0xd80,0xd80,0xd80,0xd80,0xd80,0xd80,0xd80,0xd80,0xd80,
+0xd80,0xd80,0xd80,0xd80,0xd8c,0xd8c,0xd8c,0xd8c,0xd8c,0xd8c,0xd8c,0xd8c,0xd8c,0xd8c,0xd8c,0xd8c,
+0xd8c,0xd8c,0xd8c,0xd8c,0xd8c,0xd8c,0xd8c,0xd8c,0xd8c,0xd8c,0xd8c,0xd8c,0xd8c,0xd8c,0xd8c,0xd8c,
+0xd8c,0xd8c,0xd8c,0xd8c,0xe2e,0xe2e,0xe2e,0xe2e,0xe2e,0xe2e,0xe2e,0xe2e,0xe2e,0xe2e,0xe2e,0xe2e,
+0xe2e,0xe2e,0xe2e,0xe2e,0xe2e,0xe2e,0xe2e,0xe2e,0xe2e,0xe2e,0xe2e,0xe2e,0xe2e,0xe2e,0xe2e,0xe2e,
+0xe2e,0xe2e,0xe2e,0xe2e,0xe34,0xe34,0xe34,0xe34,0xe34,0xe34,0xe34,0xe34,0xe34,0xe34,0xe34,0xe34,
+0xe34,0xe34,0xe34,0xe34,0xe34,0xe34,0xe34,0xe34,0xe34,0xe31,0xe31,0xe31,0xe31,0xe31,0xe31,0xe31,
+0xe31,0xe31,0xe31,0xe31,0xe34,0xe34,0xe34,0xe34,0xe34,0xe34,0xe34,0xe34,0xe34,0xe34,0xe34,0xe34,
+0xe34,0xe34,0xe34,0xe34,0xe34,0xe34,0xe34,0xe34,0xe34,0xe34,0xe34,0xe34,0xe34,0xe34,0xe34,0xe34,
+0xe34,0xe34,0xe34,0xe34,0xef4,0xef4,0xe46,0xe46,0xf3c,0xf3c,0xf3c,0xf3c,0xf3c,0xf3c,0xf3c,0x103b,
+0x103b,0x103b,0x103b,0x103b,0x1038,0x1038,0x1038,0x1038,0x1038,0x1038,0x1038,0x1038,0x1038,0x1038,0x1038,0x1038,
+0x1038,0x1038,0x1038,0x1038,0xe55,0xe52,0xe55,0xe52,0xe55,0xe52,0xe55,0xe52,0xe55,0xe52,0xe55,0xe52,
+0xe55,0xe52,0xe55,0xe52,0xe55,0xe52,0xe55,0xe52,0xe55,0xe52,0xe55,0xe52,0xe55,0xe52,0xe55,0xe52,
+0xe55,0xe52,0xe55,0xe52,0xe61,0xe61,0xe61,0xe61,0xe61,0xe61,0xe61,0xe61,0xe61,0xe61,0xe61,0xe61,
+0xe61,0xe61,0xe61,0xe61,0xe61,0xe61,0xe61,0xe61,0xe61,0xe61,0xe61,0xe61,0xe61,0xe61,0xe61,0xe61,
+0xe61,0xe61,0xe61,0xe61,0xe67,0xe67,0xe67,0xe67,0xe67,0xe67,0xe67,0xe67,0xe67,0xe67,0xe67,0xe67,
+0xe67,0xe67,0xe67,0xe67,0xe67,0xe67,0xe67,0xe67,0xe67,0xe67,0xe67,0xe67,0xe67,0xe67,0xe67,0xe67,
+0xe67,0xe67,0xe67,0xe67,0xeee,0xeee,0xeee,0xeee,0xeee,0xeee,0xeee,0xeee,0xe7f,0xe7f,0xe7f,0xe7f,
+0xe7f,0xe7f,0xe7f,0xe7f,0xe7f,0xe7f,0xe7f,0xe7f,0xe7f,0xe7f,0xe7f,0xf3f,0xf3f,0xf3f,0xf3f,0x103e,
+0x103e,0x103e,0x103e,0x103e,0xe88,0xe88,0xe88,0xe88,0xe88,0xe88,0xe88,0xe88,0xe88,0xe88,0xe88,0xe88,
+0xe88,0xe88,0xe88,0xe88,0xe88,0xe88,0xe88,0xe88,0xe88,0xe88,0xe88,0xe88,0xe88,0xe88,0xe88,0xe88,
+0xe88,0xe88,0xe88,0xe88,0xe91,0xe91,0xe91,0xe91,0xe91,0xe91,0xe91,0xe91,0xe91,0xe91,0xe91,0xe91,
+0xe91,0xe91,0xe91,0xe91,0xe91,0xe91,0xe91,0xe91,0xe91,0xe91,0xe91,0xe91,0xe91,0xe91,0xe91,0xe91,
+0xe91,0xe91,0xe91,0xe91,0xe9a,0xe9a,0xe9a,0xe9a,0xe9a,0xe9a,0xe9a,0xe9a,0xe9a,0xe9a,0xe9a,0xe9a,
+0xe9a,0xe9a,0xe9a,0xe9a,0xe9a,0xe9a,0xe9a,0xe9a,0xe9a,0xe9a,0xe9a,0xe9a,0xe9a,0xe9a,0xe9a,0xe9a,
+0xe9a,0xe9a,0xe9a,0xe94,0xe97,0xe97,0xe97,0xe97,0xe97,0xe97,0xe97,0xe97,0xe97,0xe97,0xe97,0xe97,
+0xe97,0xe97,0xe97,0xe97,0xe97,0xe97,0xe97,0xe97,0xe97,0xe97,0xe97,0xe97,0xe97,0xe97,0xe97,0xe9a,
+0xe9a,0xe9a,0xe9a,0xe9a,0xea3,0xea3,0xea3,0xea3,0xea3,0xea3,0xea3,0xea3,0xea3,0xea3,0xea3,0xea3,
+0xea3,0xea3,0xea0,0xea0,0xea0,0xea0,0xea0,0xea0,0xea0,0xea0,0xe9d,0xea6,0x104a,0x1044,0x1053,0x1041,
+0xea3,0xea3,0x1041,0x1041,0xeb5,0xeb5,0xea9,0xeb5,0xeb5,0xeb5,0xeac,0xeb5,0xeb5,0xeb5,0xeb5,0xea9,
+0xeb5,0xeb5,0xeb5,0xeb5,0xeb5,0xeb5,0xeb5,0xeb5,0xeb5,0xeb5,0xeb5,0xeb5,0xeb5,0xeb5,0xeb5,0xeb5,
+0xeb5,0xeb5,0xeb5,0xeb5,0xeb8,0xeb8,0xeb8,0xeb8,0xeb8,0xeb8,0xeb8,0xeb8,0xeb8,0xeb8,0xeb8,0xeb8,
+0xeb8,0xeb8,0xeb8,0xeb8,0xeb8,0xeb8,0xeb8,0xeb8,0xeb8,0xeb8,0xeb8,0xeb8,0xeb8,0xeb8,0xeb8,0xeb8,
+0xeb8,0xeb8,0xeb8,0xeb8,0xed0,0xed0,0xed0,0xed0,0xed0,0xed0,0xed0,0xed0,0xed0,0xed0,0xed0,0xed0,
+0xed0,0xed0,0xed0,0xed0,0xed0,0xed0,0xed0,0xed0,0xed0,0xed0,0xed0,0xed0,0xed0,0xed0,0xed0,0xed0,
+0xed0,0xed0,0xed0,0xed0,0xef1,0xef1,0xef1,0xef1,0xef1,0xef1,0xef1,0xef1,0xef1,0xef1,0xef1,0xef1,
+0xef1,0xef1,0xef1,0xef1,0x1149,0x1149,0x1149,0x1149,0x1149,0x1149,0x1149,0x1149,0x1149,0x1149,0x1149,0x1149,
+0x1149,0x1149,0x1149,0x1149,0xf24,0xf24,0xf24,0xf21,0xf21,0xf21,0xf21,0xf21,0x1182,0x13dd,0x13dd,0x13dd,
+0x13dd,0x135f,0x135f,0x135f,0x13e0,0x1362,0x1362,0x13e0,0x1524,0x1524,0x1524,0x1524,0x1527,0x1527,0x1527,0x17ee,
+0x17ee,0x17ee,0x17ee,0x18b4,0xf39,0xf39,0xf39,0xf39,0x102f,0x102f,0x102f,0x102f,0x102f,0x102f,0x102f,0x102f,
+0x102f,0x102f,0x102f,0x102f,0x1032,0x1032,0x1032,0x1032,0x1032,0x1032,0x1032,0x1032,0x1032,0x1032,0x1032,0x1032,
+0x1032,0x1032,0x1032,0x1032,0xf5a,0xf5a,0xf5a,0xf5a,0xf6c,0xf75,0xf78,0xf75,0xf78,0xf75,0xf78,0xf75,
+0xf78,0xf75,0xf78,0xf75,0xf75,0xf75,0xf78,0xf75,0xf75,0xf75,0xf75,0xf75,0xf75,0xf75,0xf75,0xf75,
+0xf75,0xf75,0xf75,0xf75,0xf75,0xf75,0xf75,0xf75,0xf75,0xf75,0xf75,0xf75,0xf5d,0xf5a,0xf5a,0xf5a,
+0xf5a,0xf5a,0xf5a,0xf6f,0xf5a,0xf6f,0xf6c,0xf6c,0xf81,0xf7e,0xf81,0xf81,0xf81,0xf7e,0xf7e,0xf81,
+0xf7e,0xf81,0xf7e,0xf81,0xf7e,0x1065,0x1065,0x1065,0x11a0,0x105c,0x1065,0x105c,0xf7e,0xf81,0xf7e,0xf7e,
+0x105c,0x105c,0x105c,0x105c,0x105f,0x1062,0x11a0,0x11a0,0xf84,0xf84,0x1077,0x106e,0x1077,0x106e,0x1077,0x106e,
+0x1077,0x106e,0x1077,0x106e,0x1077,0x106e,0x1077,0x106e,0x106e,0x106e,0x1077,0x106e,0x1077,0x106e,0x1077,0x106e,
+0x1077,0x106e,0x1077,0x106e,0x1077,0x106e,0x1077,0x106e,0xf8a,0xf8a,0xf8a,0xf8a,0xf8a,0xf8a,0xf8a,0xf8a,
+0xf8a,0xf8a,0xf8a,0xf8a,0xf8a,0xf8a,0xf8a,0xf8a,0xf8a,0xf8a,0xf8a,0xf8a,0xf8a,0xf8a,0xf8a,0xf8a,
+0xf8a,0xf8a,0xf8a,0xf8a,0xf8a,0xf8a,0xf8a,0xf8a,0xf99,0xf99,0xf99,0xf99,0xf99,0xf99,0xf99,0xf99,
+0xf99,0xf99,0xf99,0xf99,0xf99,0xf99,0xf99,0xf99,0xf99,0xf99,0xf99,0xf99,0xf99,0xf99,0xf99,0xf99,
+0xf99,0xf99,0xf99,0xf99,0xf99,0xf99,0xf99,0xf99,0xf99,0xf99,0xf99,0x1563,0x1563,0x1563,0x1563,0x1563,
+0x1563,0x1563,0x1563,0x1563,0x1563,0x1563,0x1563,0x1563,0x1563,0x1563,0x1563,0x1563,0xf9f,0xf9f,0xf9f,0xf9f,
+0xf9f,0xf9f,0xf9f,0xf9f,0xf9f,0xf9f,0xf9f,0xf9f,0xf9f,0xf9f,0xf9f,0xf9f,0xf9f,0xf9f,0xf9f,0xf9f,
+0xf9f,0xf9f,0xf9f,0xf9f,0xf9f,0xf9f,0xf9f,0xf9f,0xf9f,0xf9f,0xf9f,0xf9f,0xfe7,0xfff,0xff6,0xffc,
+0xffc,0xfff,0xfff,0xff6,0xff6,0xffc,0xffc,0xffc,0xffc,0xffc,0xfff,0xfff,0xfff,0xfe7,0xfe7,0xfe7,
+0xfe7,0xfff,0xfff,0xfff,0xfff,0xfff,0xfff,0xfff,0xfff,0xfff,0xfff,0xfff,0xfff,0xfff,0xfe7,0xff6,
+0xff9,0xfe7,0xfe7,0xffc,0xffc,0xffc,0xffc,0xffc,0xffc,0xfea,0xfff,0xffc,0xff3,0xff3,0xff3,0xff3,
+0xff3,0xff3,0xff3,0xff3,0xff3,0xff3,0x116a,0x116a,0x1167,0x1164,0xff0,0xff0,0x1017,0x1017,0x1017,0x1017,
+0x12db,0x12db,0x12b1,0x12b1,0x12b7,0x12ae,0x12ae,0x12ae,0x12ae,0x12b1,0x13e3,0x12b7,0x12b1,0x12b7,0x12ae,0x12b7,
+0x12db,0x12ae,0x12ae,0x12ae,0x12b1,0x12b1,0x12ae,0x12ae,0x12b1,0x12ae,0x12ae,0x12b1,0x1032,0x1032,0x1032,0x1032,
+0x1032,0x102f,0x102f,0x1032,0x1032,0x1032,0x1032,0x1032,0x1032,0x153c,0x153c,0x153c,0x1140,0x102f,0x102f,0x102f,
+0x102f,0x12e7,0x12c0,0x12c0,0x12c0,0x12c0,0x153c,0x153c,0x153c,0x153c,0x153c,0x153c,0x1050,0x1050,0x104d,0x1047,
+0x104d,0x1047,0x104d,0x1047,0x104d,0x1047,0x1044,0x1044,0x1044,0x1044,0x1059,0x1056,0x1044,0x119d,0x143a,0x143d,
+0x143d,0x143a,0x143a,0x143a,0x143a,0x143a,0x1440,0x1440,0x1557,0x154b,0x154b,0x1548,0x1077,0x106e,0x1077,0x106e,
+0x1077,0x106e,0x1077,0x106e,0x106b,0x1068,0x1068,0x1077,0x106e,0x1383,0x1380,0x1746,0x1383,0x1380,0x1449,0x1446,
+0x155a,0x155a,0x1560,0x155a,0x1560,0x155a,0x1560,0x155a,0x1560,0x155a,0x1560,0x155a,0x1077,0x106e,0x1077,0x106e,
+0x1077,0x106e,0x1077,0x106e,0x1077,0x106e,0x1077,0x106e,0x1077,0x106e,0x1077,0x106e,0x1077,0x106e,0x1077,0x106e,
+0x1077,0x106e,0x1077,0x106e,0x1077,0x106e,0x1077,0x106e,0x1077,0x106e,0x1077,0x106e,0x1071,0x106e,0x106e,0x106e,
+0x106e,0x106e,0x106e,0x106e,0x106e,0x1077,0x106e,0x1077,0x106e,0x1077,0x1077,0x106e,0x107a,0x107a,0x1080,0x1086,
+0x1086,0x1086,0x1086,0x1086,0x1086,0x1086,0x1086,0x1086,0x1086,0x1086,0x1086,0x1086,0x1086,0x1086,0x1086,0x1086,
+0x1086,0x1086,0x1086,0x1086,0x1086,0x1086,0x1086,0x1086,0x1086,0x1086,0x1086,0x1086,0x1086,0x1080,0x107a,0x107a,
+0x107a,0x107a,0x1080,0x1080,0x107a,0x107a,0x1083,0x1452,0x144f,0x144f,0x1086,0x1086,0x107d,0x107d,0x107d,0x107d,
+0x107d,0x107d,0x107d,0x107d,0x107d,0x107d,0x1455,0x1455,0x1455,0x1455,0x1455,0x1455,0x109b,0x109b,0x109b,0x109b,
+0x109b,0x109b,0x109b,0x109b,0x109b,0x109b,0x109b,0x109b,0x109b,0x109b,0x109b,0x109b,0x109b,0x109b,0x109b,0x109b,
+0x109b,0x109b,0x109b,0x109b,0x109b,0x109b,0x109b,0x109b,0x109b,0x109b,0x109b,0x109b,0x10a4,0x10a4,0x10a4,0x10a4,
+0x10a4,0x10a4,0x10a4,0x10a4,0x10a4,0x10a4,0x10a4,0x10a4,0x10a4,0x10a4,0x10a4,0x10a4,0x10a4,0x10a4,0x10a4,0x10a4,
+0x10a4,0x10a4,0x10a4,0x10a4,0x10a7,0x10a7,0x10a7,0x10aa,0x10a7,0x10a7,0x10ad,0x10ad,0x10b0,0x10b0,0x10b0,0x10b0,
+0x10b0,0x10b0,0x10b0,0x10b0,0x10b0,0x10b0,0x10b0,0x10b0,0x10b0,0x10b0,0x10b0,0x10b0,0x10b0,0x10b0,0x10b0,0x10b0,
+0x10b0,0x10b0,0x10b0,0x10b0,0x10b0,0x10b0,0x10b0,0x10b0,0x10b0,0x10b0,0x10b0,0x10b0,0x10b9,0x10b9,0x10b9,0x10b9,
+0x10b9,0x10b9,0x10b9,0x10b9,0x10b9,0x10b9,0x10b9,0x10b9,0x10bc,0x10b3,0x10c2,0x10bf,0x10b9,0x10b9,0x10b9,0x10b9,
+0x10b9,0x10b9,0x10b9,0x10b9,0x10b9,0x10b9,0x10b9,0x10b9,0x10b9,0x10b9,0x10b9,0x10b9,0x10b9,0x10b9,0x10b9,0x10b9,
+0x10b9,0x10b9,0x10b9,0x10b9,0x10b9,0x10b9,0x10b9,0x10b9,0x10b9,0x10b9,0x10b9,0x10b9,0x1389,0x1386,0x10d4,0x10ce,
+0x10d4,0x10ce,0x10d4,0x10ce,0x10d4,0x10ce,0x10d4,0x10ce,0x10d4,0x10ce,0x10d1,0x1152,0x10c5,0x10c5,0x10c5,0x10cb,
+0x1458,0x1458,0x1458,0x1458,0x1458,0x1458,0x1458,0x1458,0x10c8,0x10c8,0x10cb,0x10d7,0x10d4,0x10ce,0x10d4,0x10ce,
+0x10d4,0x10ce,0x10d4,0x10ce,0x10d4,0x10ce,0x10d4,0x10ce,0x10d4,0x10ce,0x10d4,0x10ce,0x10d4,0x10ce,0x10d4,0x10ce,
+0x10d4,0x10ce,0x10d4,0x10ce,0x10d4,0x10ce,0x10d4,0x10ce,0x10d4,0x10ce,0x10d4,0x10ce,0x156f,0x156c,0x156f,0x156c,
+0x1572,0x1572,0x174f,0x1458,0x10e0,0x10e0,0x10e3,0x10e3,0x10e3,0x10e3,0x10e3,0x10e3,0x10e3,0x10e3,0x10e3,0x10e3,
+0x10e3,0x10e3,0x10e3,0x10e3,0x10e3,0x10e3,0x10e3,0x10e3,0x10e3,0x10e3,0x10e3,0x10e3,0x10e3,0x10e3,0x10e3,0x10e3,
+0x10e3,0x10e3,0x10e3,0x10e3,0x10e0,0x10e0,0x10e0,0x10e0,0x10e0,0x10e0,0x10e0,0x10e0,0x10e0,0x10e0,0x10e0,0x10e0,
+0x10f2,0x10f2,0x10f2,0x10f2,0x10f2,0x10f2,0x10e9,0x10e9,0x10e9,0x10e9,0x10e9,0x10ec,0x10ec,0x10ec,0x1146,0x10f5,
+0x1104,0x1104,0x1104,0x1104,0x1104,0x1104,0x1104,0x1104,0x1104,0x1104,0x1104,0x1104,0x1104,0x1104,0x1104,0x1104,
+0x10ef,0x10ef,0x10ef,0x10ef,0x10ef,0x10ef,0x10ef,0x10ef,0x10ef,0x10ef,0x10f2,0x10f2,0x10f2,0x10f2,0x10f2,0x10f2,
+0x10f2,0x10f2,0x10f2,0x10f2,0x10f2,0x10f2,0x10f2,0x10f2,0x10f2,0x10f2,0x10f2,0x10f2,0x10f2,0x10f2,0x10f2,0x10f2,
+0x1113,0x1113,0x1113,0x1113,0x1113,0x1113,0x1113,0x1113,0x1113,0x1113,0x1113,0x1113,0x1113,0x1113,0x1113,0x1113,
+0x1113,0x1113,0x1113,0x1113,0x1113,0x1113,0x1113,0x1113,0x1113,0x1113,0x1113,0x1113,0x1113,0x1113,0x1113,0x1113,
+0x1125,0x1125,0x1125,0x1125,0x1125,0x1125,0x1125,0x1125,0x1125,0x1125,0x1125,0x1125,0x1125,0x1125,0x1125,0x1125,
+0x1125,0x1125,0x1125,0x1125,0x1125,0x1125,0x1125,0x1125,0x1125,0x1125,0x1125,0x1125,0x1125,0x1125,0x1125,0x1125,
+0x112e,0x112e,0x112e,0x112e,0x1143,0x112e,0x112e,0x112e,0x112e,0x112e,0x112e,0x112e,0x112e,0x112e,0x112e,0x112e,
+0x112e,0x112e,0x112e,0x112e,0x112e,0x112e,0x112e,0x112e,0x112e,0x112e,0x112e,0x112e,0x112e,0x112e,0x112e,0x112e,
+0x1131,0x1131,0x1131,0x1131,0x1131,0x1131,0x1131,0x1131,0x1131,0x1131,0x1131,0x1131,0x1131,0x1131,0x1131,0x1131,
+0x1131,0x1131,0x1131,0x1131,0x1131,0x1131,0x1131,0x1131,0x1131,0x1131,0x1131,0x1131,0x1131,0x1131,0x1131,0x1131,
+0x113d,0x113d,0x113d,0x113d,0x12e1,0x12e1,0x12e1,0x12e1,0x12e1,0x12e1,0x12e1,0x12e1,0x14e2,0x17cd,0x17cd,0x17cd,
+0x17cd,0x17cd,0x17cd,0x17cd,0x17cd,0x17cd,0x191d,0x191d,0x191d,0x191d,0x191d,0x191d,0x191d,0x191d,0x191d,0x191d,
+0x11b2,0x11b2,0x11b2,0x11b2,0x11b2,0x11b2,0x11b2,0x11b2,0x11b2,0x11b2,0x11b2,0x11b2,0x11b2,0x11b2,0x11b2,0x11b2,
+0x11b2,0x11b2,0x11b2,0x11b2,0x11b2,0x11b2,0x11a9,0x11a9,0x11ac,0x11ac,0x11b2,0x11a9,0x11a9,0x11a9,0x11a9,0x11a9,
+0x11b8,0x11b8,0x11b8,0x11b8,0x11b8,0x11b8,0x11b8,0x11b8,0x11b8,0x11b8,0x11b8,0x11b8,0x11b8,0x11b8,0x11b8,0x11b8,
+0x11b8,0x11b8,0x11b8,0x11b8,0x11b8,0x11b8,0x11b8,0x11b8,0x11b8,0x11b8,0x11b8,0x11b8,0x11b8,0x11b8,0x11b8,0x11b8,
+0x11d3,0x11d3,0x11d3,0x11d3,0x11d3,0x11d3,0x11d3,0x11d3,0x11d3,0x11d3,0x11d3,0x11d3,0x11d3,0x11d3,0x11d3,0x11d3,
+0x11d3,0x11d3,0x11d3,0x11d3,0x11d3,0x11d3,0x11d3,0x11d3,0x11d3,0x11d3,0x11d3,0x11d3,0x11d3,0x11d3,0x11d3,0x11d3,
+0x11df,0x11df,0x11df,0x11df,0x11df,0x11df,0x11df,0x11df,0x11df,0x11df,0x11df,0x11df,0x11df,0x11df,0x11df,0x11df,
+0x11df,0x11df,0x11df,0x11df,0x11df,0x11df,0x11df,0x11df,0x11df,0x11df,0x11df,0x11df,0x11df,0x11df,0x11dc,0x11e2,
+0x11ee,0x11ee,0x11ee,0x11ee,0x11ee,0x11ee,0x11ee,0x11ee,0x11ee,0x11ee,0x11ee,0x11ee,0x11ee,0x11ee,0x11ee,0x11ee,
+0x11ee,0x11ee,0x11ee,0x11ee,0x11ee,0x11ee,0x11ee,0x11ee,0x11ee,0x11ee,0x11ee,0x11ee,0x11ee,0x11ee,0x11ee,0x11ee,
+0x11f4,0x11f4,0x11f4,0x11f4,0x11f4,0x11f4,0x11f4,0x11f4,0x11f4,0x11f4,0x11f4,0x11f4,0x11f4,0x11f4,0x11f4,0x11f4,
+0x11f4,0x132f,0x11fa,0x1332,0x11fa,0x11fa,0x11fa,0x11fa,0x11f7,0x11f7,0x11f7,0x11fa,0x1752,0x1755,0x197a,0x1977,
+0x11fd,0x11fd,0x11fd,0x120c,0x1212,0x1212,0x1212,0x1212,0x1212,0x1212,0x1212,0x1212,0x1212,0x1212,0x1212,0x1212,
+0x1212,0x1212,0x1212,0x1212,0x1212,0x1212,0x1212,0x1212,0x1212,0x1212,0x1212,0x1212,0x1212,0x1212,0x1212,0x1212,
+0x1212,0x1212,0x1212,0x1200,0x120c,0x120c,0x11fd,0x11fd,0x11fd,0x11fd,0x120c,0x120c,0x11fd,0x11fd,0x120c,0x120c,
+0x121e,0x121e,0x121e,0x121e,0x121e,0x121e,0x121e,0x121e,0x121e,0x121e,0x121e,0x121e,0x121e,0x121e,0x121e,0x121e,
+0x1221,0x121e,0x121e,0x121e,0x121e,0x121e,0x121e,0x1218,0x1218,0x1218,0x121e,0x121b,0x1578,0x157b,0x157e,0x157e,
+0x1230,0x1230,0x1230,0x1230,0x1230,0x1230,0x1230,0x1230,0x1230,0x1230,0x1230,0x1230,0x1230,0x1230,0x1230,0x1230,
+0x1224,0x1230,0x1224,0x1224,0x1224,0x1239,0x1239,0x1224,0x1224,0x1239,0x1230,0x1239,0x1239,0x1230,0x1224,0x1227,
+0x1230,0x1230,0x1230,0x1230,0x1230,0x1230,0x1230,0x1230,0x1230,0x1230,0x1230,0x1230,0x1230,0x1230,0x1230,0x1230,
+0x1230,0x1230,0x1230,0x1230,0x1230,0x1230,0x1230,0x1230,0x1230,0x1230,0x1230,0x1230,0x1230,0x1230,0x1230,0x1230,
+0x124b,0x124b,0x124b,0x124b,0x124b,0x124b,0x124b,0x124b,0x124b,0x124b,0x124b,0x124b,0x124b,0x124b,0x124b,0x124b,
+0x124b,0x124b,0x124b,0x124b,0x124b,0x124b,0x124b,0x124b,0x124b,0x124b,0x124b,0x124b,0x124b,0x124b,0x124b,0x124b,
+0x1263,0x1263,0x1263,0x1263,0x1263,0x1263,0x1263,0x1263,0x1263,0x1263,0x1263,0x1263,0x1263,0x1263,0x1263,0x1263,
+0x1263,0x1263,0x1263,0x1263,0x1263,0x1263,0x1263,0x1263,0x1263,0x1263,0x1263,0x1263,0x1263,0x1260,0x1260,0x1260,
+0x126c,0x126c,0x126c,0x126c,0x126c,0x126c,0x126c,0x126c,0x126c,0x126c,0x126c,0x126c,0x126c,0x126c,0x126c,0x126c,
+0x126c,0x126c,0x126c,0x126c,0x126c,0x126c,0x126c,0x126c,0x126c,0x126c,0x126c,0x126c,0x126c,0x126c,0x126c,0x126c,
+0x127b,0x127b,0x127b,0x127b,0x127b,0x127b,0x127b,0x127b,0x127b,0x127b,0x127b,0x127b,0x127b,0x127b,0x127b,0x127b,
+0x127b,0x127b,0x127b,0x127b,0x127b,0x127b,0x127b,0x127b,0x127b,0x127b,0x127b,0x127b,0x127b,0x127b,0x127b,0x127b,
+0x1281,0x1281,0x1290,0x1293,0x1293,0x1293,0x1293,0x1293,0x1293,0x1293,0x1293,0x1293,0x1293,0x1293,0x1293,0x1293,
+0x1293,0x1293,0x1293,0x1293,0x1293,0x1293,0x1293,0x1293,0x1293,0x1293,0x1296,0x1293,0x1296,0x1293,0x1293,0x1293,
+0x1293,0x1293,0x1293,0x1293,0x1293,0x1293,0x1293,0x1293,0x1293,0x1293,0x1293,0x1296,0x1293,0x1293,0x1293,0x1293,
+0x1290,0x1290,0x1290,0x1284,0x1284,0x1284,0x1284,0x1290,0x1290,0x128a,0x1287,0x128d,0x128d,0x129c,0x1299,0x1299,
+0x129f,0x129f,0x129f,0x129f,0x129f,0x129f,0x129f,0x129f,0x129f,0x129f,0x129f,0x129f,0x129f,0x129f,0x129f,0x129f,
+0x129f,0x129f,0x129f,0x129f,0x129f,0x129f,0x129f,0x129f,0x129f,0x129f,0x129f,0x129f,0x129f,0x129f,0x129f,0x129f,
+0x12a5,0x12a5,0x12a5,0x12a2,0x12a2,0x12a2,0x129f,0x129f,0x129f,0x129f,0x12a2,0x129f,0x129f,0x129f,0x12a5,0x12a2,
+0x12a5,0x12a2,0x129f,0x129f,0x129f,0x129f,0x129f,0x129f,0x129f,0x129f,0x129f,0x129f,0x129f,0x129f,0x129f,0x129f,
+0x129f,0x129f,0x129f,0x129f,0x129f,0x129f,0x129f,0x129f,0x129f,0x129f,0x129f,0x129f,0x129f,0x12a5,0x12a2,0x12a2,
+0x129f,0x129f,0x129f,0x129f,0x12c6,0x12c6,0x12c6,0x12c6,0x12c6,0x12c6,0x12c6,0x12c6,0x12c6,0x12c6,0x12c6,0x12c9,
+0x12c9,0x12c9,0x12a8,0x1980,0x13d7,0x12d2,0x13d7,0x13d7,0x13d7,0x13d7,0x13d7,0x13d7,0x13d7,0x13d7,0x13d7,0x13d7,
+0x13d7,0x12d2,0x13d7,0x12d2,0x12b1,0x12b1,0x1365,0x12ae,0x1365,0x1365,0x1365,0x1365,0x12ae,0x12b4,0x12db,0x12ae,
+0x12ae,0x12ae,0x12ae,0x12ae,0x12b4,0x12b7,0x12db,0x12db,0x12b7,0x12db,0x12ae,0x12b7,0x12b7,0x12ba,0x12db,0x12ae,
+0x12ae,0x12db,0x12b1,0x12b1,0x13d4,0x13d4,0x13d4,0x13d4,0x13d4,0x13d4,0x13d4,0x13d4,0x13d4,0x13d4,0x12c3,0x12c3,
+0x12c3,0x12c3,0x13ef,0x13ce,0x12cc,0x13ef,0x13ef,0x13ef,0x13ef,0x13ef,0x13ef,0x13ef,0x13ef,0x13ef,0x13ef,0x187e,
+0x187e,0x187e,0x187e,0x187e,0x12c6,0x12c6,0x12c6,0x12c6,0x12c6,0x12c6,0x12c6,0x12c6,0x12c6,0x12c6,0x12c6,0x1581,
+0x1581,0x1ad0,0x1ad0,0x1ad0,0x12c6,0x12c6,0x12c6,0x12c6,0x12c6,0x12c6,0x12c6,0x12c6,0x12c6,0x12c6,0x12c6,0x12c6,
+0x12c6,0x12c6,0x12c6,0x12c6,0x13d7,0x13d7,0x12d2,0x13d7,0x13d7,0x13d7,0x12d2,0x13d7,0x13d7,0x13d7,0x12cc,0x12cc,
+0x12cc,0x12cc,0x12cc,0x13d1,0x13d4,0x13d4,0x13d4,0x13d4,0x13d4,0x13d4,0x13d4,0x12cf,0x13d4,0x13d4,0x13d4,0x13d4,
+0x13d4,0x13d4,0x13d4,0x12cf,0x13d4,0x13d4,0x13d4,0x13d4,0x13d4,0x13d4,0x13d4,0x13d4,0x13d4,0x13d4,0x145b,0x145b,
+0x1a2e,0x1ad0,0x1ad0,0x1ad0,0x13da,0x13da,0x13d4,0x13d4,0x13d4,0x13d4,0x13d4,0x13d4,0x13d4,0x12cf,0x13d4,0x12cf,
+0x12cf,0x13d4,0x13da,0x12d5,0x12f9,0x12f9,0x12f9,0x12f9,0x12f9,0x12f9,0x12f9,0x12f9,0x12f9,0x12f9,0x12f9,0x12f9,
+0x12f9,0x12f9,0x12f9,0x12f9,0x12f9,0x12f9,0x12f9,0x12f9,0x12f9,0x12f9,0x12f9,0x12f9,0x12f9,0x12f9,0x12f9,0x12f9,
+0x12f9,0x12f9,0x12f9,0x12f9,0x1383,0x1380,0x1383,0x1380,0x1383,0x1380,0x1383,0x1380,0x1383,0x1380,0x1449,0x1560,
+0x1560,0x1560,0x17fa,0x196e,0x1560,0x1560,0x1749,0x1749,0x1749,0x1743,0x1749,0x1743,0x1971,0x196e,0x1a2b,0x1a28,
+0x1a2b,0x1a28,0x1a2b,0x1a28,0x13a7,0x13a7,0x13a7,0x13a7,0x13a7,0x13a7,0x13a7,0x13a7,0x13a7,0x13a7,0x13a7,0x13a7,
+0x13a7,0x13a7,0x13a7,0x13a7,0x13a7,0x13a7,0x13a7,0x13a7,0x13a7,0x13a7,0x13a7,0x13a7,0x13a7,0x13a7,0x13a7,0x13a7,
+0x13a7,0x13a7,0x13a7,0x13a7,0x13bc,0x13ad,0x13bc,0x13bf,0x13bf,0x13bf,0x13bf,0x13bf,0x13bf,0x13bf,0x13bf,0x13bf,
+0x13bf,0x13bf,0x13bf,0x13bf,0x13bf,0x13bf,0x13bf,0x13bf,0x13bf,0x13bf,0x13bf,0x13bf,0x13bf,0x13bf,0x13bf,0x13bf,
+0x13bf,0x13bf,0x13bf,0x13bf,0x13ad,0x13ad,0x13ad,0x13ad,0x13ad,0x13ad,0x13ad,0x13ad,0x13c5,0x13c5,0x13c5,0x13c5,
+0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,
+0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13c5,0x13cb,0x13cb,0x13cb,0x13cb,
+0x13cb,0x13cb,0x13cb,0x13cb,0x13cb,0x13cb,0x13cb,0x13cb,0x13cb,0x13cb,0x13cb,0x13cb,0x13cb,0x13cb,0x13cb,0x13cb,
+0x13cb,0x13cb,0x13cb,0x13cb,0x13cb,0x13cb,0x13cb,0x13cb,0x13cb,0x13cb,0x13cb,0x13cb,0x13fb,0x13f8,0x1923,0x1923,
+0x1923,0x1923,0x1923,0x1923,0x1923,0x1923,0x1923,0x1923,0x1923,0x1923,0x1923,0x1923,0x1923,0x1923,0x1923,0x1923,
+0x1923,0x1923,0x1923,0x1923,0x1923,0x1923,0x1923,0x1923,0x1923,0x1923,0x1923,0x1923,0x1404,0x1404,0x1404,0x1404,
+0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,
+0x1404,0x1401,0x1401,0x1404,0x1404,0x1404,0x1404,0x1404,0x1401,0x1404,0x1404,0x1404,0x1401,0x1404,0x1401,0x1404,
+0x1401,0x1404,0x1404,0x1404,0x1404,0x1404,0x1407,0x1404,0x1404,0x1404,0x1404,0x1401,0x1404,0x1401,0x1401,0x1404,
+0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1401,0x1401,0x1401,0x1401,
+0x1401,0x1401,0x1401,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,
+0x1404,0x1404,0x1404,0x1401,0x1401,0x1401,0x1401,0x1401,0x1401,0x1401,0x1401,0x1401,0x1401,0x1404,0x1404,0x1404,
+0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1401,0x1401,0x1401,0x1401,0x1401,0x1401,
+0x1401,0x1401,0x1401,0x1401,0x1401,0x1401,0x158a,0x158a,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,
+0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,
+0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1596,0x1590,0x1590,0x1596,0x1596,0x1596,0x1596,
+0x1596,0x1596,0x1596,0x1596,0x1596,0x17d0,0x17d0,0x17d0,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1596,0x1404,
+0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,
+0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1596,0x17d0,0x17d0,
+0x1404,0x1404,0x1404,0x1404,0x1404,0x1407,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,
+0x1404,0x1404,0x1404,0x1404,0x1590,0x1590,0x1596,0x1596,0x1590,0x1596,0x1596,0x1596,0x158d,0x158d,0x1596,0x1596,
+0x1404,0x1404,0x1407,0x1407,0x1407,0x1701,0x1404,0x1407,0x1404,0x1404,0x1407,0x1599,0x1599,0x1596,0x1596,0x17d0,
+0x17d0,0x17d0,0x17d0,0x17d0,0x1596,0x1596,0x1596,0x1596,0x1596,0x1596,0x1596,0x1596,0x1596,0x1596,0x1596,0x1596,
+0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,
+0x1404,0x1590,0x1590,0x1596,0x1701,0x1596,0x1590,0x1596,0x17d0,0x17d0,0x17d0,0x17d3,0x17d3,0x17d3,0x17d3,0x17d3,
+0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,
+0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1596,
+0x1404,0x1596,0x1407,0x1407,0x1404,0x1404,0x1407,0x1407,0x1407,0x1407,0x1407,0x1407,0x1407,0x1407,0x1407,0x1407,
+0x1407,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,
+0x1404,0x1404,0x1407,0x1407,0x1407,0x1407,0x1407,0x1407,0x1407,0x1407,0x1407,0x1407,0x1407,0x1407,0x1407,0x1407,
+0x1407,0x1407,0x1407,0x1407,0x1407,0x1404,0x1404,0x1404,0x1407,0x1404,0x1404,0x1404,0x1404,0x1407,0x1407,0x1407,
+0x1404,0x1407,0x1407,0x1407,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1407,0x1404,0x1407,0x1404,0x1404,
+0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,
+0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1701,0x1404,0x1404,0x1404,0x1404,0x1596,0x1590,0x17d0,
+0x145e,0x145e,0x145e,0x145e,0x158a,0x158a,0x158d,0x158d,0x158d,0x1593,0x1596,0x17d0,0x17d0,0x17d0,0x17d0,0x1758,
+0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,0x1404,
+0x1590,0x1590,0x1590,0x1590,0x1590,0x1590,0x1590,0x1596,0x1596,0x1590,0x1590,0x1596,0x1599,0x1599,0x1596,0x1596,
+0x1596,0x1596,0x1887,0x1590,0x1590,0x1590,0x1590,0x1590,0x1590,0x1596,0x1590,0x1596,0x1590,0x1590,0x1590,0x1590,
+0x1596,0x1590,0x1590,0x1590,0x1590,0x1590,0x1590,0x1596,0x1590,0x1590,0x1590,0x1596,0x158d,0x158d,0x158d,0x158d,
+0x158d,0x158d,0x1596,0x1404,0x1404,0x1404,0x1404,0x1404,0x14e8,0x140a,0x140a,0x140a,0x140a,0x140a,0x140a,0x140a,
+0x140a,0x140a,0x140a,0x140a,0x140a,0x140a,0x140a,0x140a,0x140a,0x14e8,0x140a,0x140a,0x140a,0x14e8,0x140a,0x14e8,
+0x140a,0x14e8,0x140a,0x14e8,0x140a,0x140a,0x140a,0x14e8,0x140a,0x140a,0x140a,0x140a,0x140a,0x140a,0x14e8,0x14e8,
+0x140a,0x140a,0x140a,0x140a,0x14e8,0x140a,0x14e8,0x14e8,0x140a,0x140a,0x140a,0x140a,0x14e8,0x140a,0x140a,0x140a,
+0x140a,0x140a,0x140a,0x140a,0x140a,0x140a,0x140a,0x140a,0x140a,0x1707,0x1707,0x17d6,0x17d6,0x140d,0x140d,0x140d,
+0x140a,0x140a,0x140a,0x140d,0x140d,0x140d,0x140d,0x140d,0x1686,0x1686,0x1686,0x1686,0x1686,0x1686,0x1686,0x1686,
+0x1686,0x1686,0x1686,0x1686,0x1686,0x1686,0x1686,0x1686,0x1410,0x1410,0x1410,0x1410,0x1410,0x1410,0x1410,0x1410,
+0x1410,0x1410,0x1410,0x1410,0x1410,0x1410,0x1410,0x1410,0x1410,0x1410,0x1410,0x1410,0x1410,0x1410,0x1410,0x1410,
+0x1410,0x1410,0x1410,0x1410,0x1410,0x1410,0x1410,0x1410,0x1410,0x1410,0x1410,0x1413,0x1410,0x1410,0x1410,0x1410,
+0x1410,0x1410,0x1410,0x1410,0x1410,0x1410,0x1410,0x1410,0x1410,0x1410,0x1410,0x1410,0x1413,0x1413,0x1413,0x1410,
+0x1410,0x1410,0x1410,0x1410,0x1410,0x1410,0x1410,0x1410,0x1416,0x1416,0x1416,0x1416,0x1416,0x1416,0x1416,0x1416,
+0x1416,0x1416,0x1416,0x1416,0x1416,0x1416,0x1416,0x1416,0x1416,0x1416,0x1416,0x1416,0x1416,0x1416,0x1416,0x1416,
+0x1416,0x1416,0x1416,0x1416,0x1416,0x1416,0x1416,0x1416,0x1803,0x1803,0x1800,0x175b,0x1464,0x1464,0x1464,0x1464,
+0x1464,0x1464,0x1461,0x1461,0x1461,0x1461,0x1461,0x1461,0x1464,0x1464,0x1464,0x1464,0x1464,0x1464,0x1464,0x1464,
+0x1464,0x1464,0x1464,0x1464,0x1464,0x1464,0x1464,0x15a2,0x1470,0x1470,0x1470,0x1482,0x1482,0x1482,0x1482,0x1482,
+0x1482,0x1482,0x1482,0x1482,0x1482,0x1482,0x1482,0x1482,0x1482,0x1482,0x1482,0x1482,0x1482,0x1482,0x1482,0x1482,
+0x1482,0x1482,0x1482,0x1482,0x1482,0x1482,0x1482,0x1482,0x149d,0x149d,0x149d,0x149d,0x149d,0x149d,0x149d,0x149d,
+0x149d,0x149d,0x149d,0x149d,0x149d,0x149d,0x149d,0x149d,0x149d,0x149d,0x149d,0x149d,0x149d,0x149d,0x149d,0x149d,
+0x149d,0x149d,0x149d,0x149d,0x149d,0x149d,0x149d,0x149d,0x14a3,0x14a3,0x14a3,0x14a3,0x14a3,0x14a3,0x14a3,0x14a3,
+0x14a3,0x14a3,0x14a3,0x14a3,0x14a3,0x14a3,0x14a3,0x14a3,0x14a3,0x14a3,0x14a3,0x14a3,0x14a3,0x14a3,0x14a3,0x14a3,
+0x14a3,0x14a3,0x14a3,0x14a3,0x14a3,0x14a3,0x14a3,0x1a34,0x14a6,0x14a6,0x14a6,0x14a6,0x14a6,0x14a6,0x14a6,0x14a6,
+0x14a6,0x14a6,0x14a6,0x14a6,0x14a6,0x14a6,0x14a6,0x14a6,0x14a6,0x14a6,0x14a6,0x14a6,0x14a6,0x14a6,0x14a6,0x14a6,
+0x14a6,0x14a6,0x14a6,0x14a6,0x14a6,0x14a6,0x14a6,0x14a6,0x14ac,0x14ac,0x14b8,0x14be,0x14be,0x14be,0x14be,0x14be,
+0x14be,0x14be,0x14be,0x14be,0x14be,0x14be,0x14be,0x14be,0x14be,0x14be,0x14be,0x14be,0x14be,0x14be,0x14be,0x14be,
+0x14be,0x14be,0x14be,0x14be,0x14be,0x14be,0x14be,0x14be,0x14be,0x14be,0x14be,0x14b8,0x14b8,0x14b8,0x14ac,0x14ac,
+0x14ac,0x14ac,0x14ac,0x14ac,0x14ac,0x14ac,0x14ac,0x14b8,0x14bb,0x14be,0x14c1,0x14c1,0x14be,0x14c4,0x14c4,0x14af,
+0x14b2,0x1764,0x1767,0x1767,0x1767,0x15ab,0x1adc,0x1ad9,0x14b5,0x14b5,0x14b5,0x14b5,0x14b5,0x14b5,0x14b5,0x14b5,
+0x14b5,0x14b5,0x15a8,0x176d,0x1770,0x176a,0x1773,0x1773,0x14df,0x14df,0x14df,0x14df,0x14df,0x14df,0x14df,0x14df,
+0x14df,0x14df,0x14df,0x14df,0x14df,0x14df,0x14df,0x14df,0x14df,0x14df,0x14df,0x14df,0x14df,0x14df,0x14df,0x14df,
+0x14df,0x14df,0x14df,0x14df,0x14df,0x14df,0x14df,0x14df,0x153c,0x153c,0x153c,0x153c,0x153c,0x153c,0x153c,0x153c,
+0x153c,0x153c,0x153c,0x153c,0x153c,0x153c,0x153c,0x153c,0x153c,0x153c,0x153c,0x153c,0x153c,0x153c,0x153c,0x153c,
+0x153c,0x153c,0x1956,0x1956,0x1956,0x153c,0x153c,0x153c,0x153c,0x153c,0x153c,0x153c,0x153c,0x153c,0x153c,0x153c,
+0x153c,0x1a22,0x153c,0x153c,0x153c,0x153c,0x153c,0x153c,0x153c,0x153c,0x18ba,0x1956,0x1956,0x1956,0x1956,0x1956,
+0x1956,0x1956,0x1956,0x1956,0x1956,0x1956,0x1956,0x1956,0x1590,0x1590,0x1596,0x1596,0x1596,0x1590,0x1590,0x1590,
+0x1590,0x1590,0x1590,0x1590,0x1590,0x1590,0x1590,0x1590,0x1590,0x1596,0x1596,0x1596,0x158d,0x158d,0x158d,0x158d,
+0x158d,0x158d,0x158d,0x158d,0x1596,0x1596,0x1596,0x1590,0x1590,0x1590,0x1590,0x1590,0x1590,0x1590,0x1590,0x1596,
+0x1590,0x1590,0x1596,0x1596,0x1596,0x1596,0x1590,0x1590,0x1599,0x1590,0x1590,0x1590,0x1590,0x1704,0x1704,0x1590,
+0x1590,0x1590,0x1590,0x1590,0x1590,0x1590,0x1590,0x1590,0x1884,0x1596,0x1590,0x1590,0x1596,0x1590,0x1590,0x1590,
+0x1590,0x1590,0x1590,0x1590,0x1590,0x1596,0x1596,0x1590,0x1590,0x1590,0x1590,0x1590,0x1590,0x1590,0x1590,0x1590,
+0x1596,0x1590,0x1590,0x1590,0x15ba,0x15ba,0x15ba,0x15ba,0x15ba,0x15ba,0x15ba,0x15ba,0x15ba,0x15ba,0x15ba,0x15ba,
+0x15ba,0x15ba,0x15ba,0x15ba,0x15ba,0x15ba,0x15ba,0x15ba,0x15ba,0x15ba,0x15ba,0x15ba,0x15ba,0x15ba,0x15ba,0x15ba,
+0x15ba,0x15ba,0x15ba,0x15ba,0x15cc,0x15cc,0x15cc,0x15cc,0x15cc,0x15cc,0x15cc,0x15cc,0x15cc,0x15cc,0x15cc,0x15cc,
+0x15cc,0x15cc,0x15cc,0x15cc,0x15cc,0x15cc,0x15cc,0x15cc,0x15cc,0x15cc,0x15cc,0x15cc,0x15cc,0x15cc,0x15cc,0x15cc,
+0x15cc,0x15cc,0x15cc,0x15cc,0x15d2,0x15d2,0x15d2,0x15d2,0x15d2,0x15d2,0x15d2,0x15d2,0x15d2,0x15d2,0x15d2,0x15d2,
+0x15d2,0x15d2,0x15d2,0x15d2,0x15d2,0x15d2,0x15d2,0x15d2,0x15d2,0x15d2,0x15d2,0x15d2,0x15d2,0x15d2,0x15d2,0x15d2,
+0x15d2,0x15d2,0x15d2,0x15d2,0x15d5,0x15d5,0x15d5,0x15d5,0x15d5,0x15d5,0x15d5,0x15d5,0x15d5,0x15d5,0x15d5,0x15d5,
+0x15d5,0x15d5,0x15d5,0x15d5,0x15d5,0x15d5,0x15d5,0x15d5,0x15d5,0x15d5,0x15d5,0x15d5,0x15d5,0x15d5,0x15d5,0x15d5,
+0x15d5,0x15d5,0x15d5,0x15d5,0x1614,0x1614,0x1614,0x1614,0x1614,0x1614,0x1614,0x1614,0x1614,0x1614,0x1614,0x1614,
+0x1614,0x1614,0x1614,0x1614,0x1614,0x1614,0x1614,0x1614,0x1614,0x1614,0x1614,0x1614,0x1614,0x1614,0x1614,0x1614,
+0x1614,0x1614,0x1614,0x1605,0x161d,0x161d,0x161d,0x161d,0x161d,0x161d,0x161d,0x161d,0x161d,0x161d,0x161d,0x161d,
+0x161d,0x161d,0x161d,0x161d,0x161d,0x161d,0x161d,0x161d,0x161d,0x161d,0x161d,0x161d,0x161d,0x161d,0x161d,0x1617,
+0x1620,0x1620,0x1620,0x1620,0x1623,0x1623,0x1623,0x1623,0x1623,0x1623,0x1623,0x1623,0x1623,0x1623,0x1623,0x1623,
+0x1623,0x1623,0x1623,0x1623,0x1623,0x1623,0x1623,0x1623,0x1623,0x1623,0x1623,0x1623,0x1623,0x1623,0x1623,0x1623,
+0x1623,0x1623,0x1623,0x1623,0x163e,0x163e,0x163e,0x163e,0x163e,0x163e,0x163e,0x163e,0x1635,0x163e,0x163e,0x163e,
+0x163e,0x163e,0x163e,0x163e,0x163e,0x163e,0x163e,0x163e,0x163e,0x163e,0x163e,0x163e,0x163e,0x163e,0x163e,0x163e,
+0x163e,0x163e,0x163e,0x163e,0x1647,0x1647,0x1647,0x1647,0x1647,0x1647,0x1647,0x1647,0x1647,0x1647,0x1647,0x1647,
+0x1647,0x1647,0x1647,0x1647,0x1647,0x1647,0x1647,0x1647,0x1647,0x1647,0x1647,0x1647,0x1647,0x1647,0x1647,0x1647,
+0x1647,0x1647,0x1647,0x1647,0x1659,0x1659,0x1659,0x1659,0x1659,0x1659,0x1659,0x1659,0x1659,0x1659,0x1659,0x1659,
+0x1659,0x1659,0x1659,0x1659,0x1656,0x1656,0x1656,0x164a,0x164a,0x164a,0x164a,0x164a,0x164a,0x164a,0x164a,0x1656,
+0x1656,0x164a,0x1656,0x164d,0x1659,0x1659,0x1659,0x1659,0x1659,0x1659,0x1659,0x1659,0x1659,0x1659,0x1659,0x1659,
+0x1659,0x1659,0x1659,0x1659,0x1659,0x1659,0x1659,0x1659,0x1659,0x1659,0x1659,0x1659,0x1659,0x1659,0x1659,0x1659,
+0x1659,0x1659,0x1659,0x1659,0x167d,0x167d,0x167d,0x167d,0x167d,0x167d,0x167d,0x167d,0x167d,0x167d,0x167d,0x167d,
+0x167d,0x167d,0x167d,0x167d,0x167d,0x167d,0x167d,0x167d,0x167d,0x167d,0x167d,0x167d,0x167d,0x167d,0x167d,0x167d,
+0x167d,0x167a,0x167a,0x167a,0x1686,0x1686,0x1686,0x1686,0x1686,0x1686,0x1686,0x1686,0x1686,0x1686,0x1686,0x1686,
+0x1686,0x1686,0x1686,0x1686,0x1686,0x1686,0x1686,0x1686,0x1686,0x1686,0x168c,0x168c,0x168c,0x1689,0x1689,0x1689,
+0x1686,0x1686,0x1686,0x1686,0x169b,0x169b,0x169b,0x169b,0x169b,0x169b,0x169b,0x169b,0x169b,0x169b,0x169b,0x169b,
+0x169b,0x169b,0x169b,0x169b,0x168f,0x168f,0x168f,0x168f,0x168f,0x168f,0x168f,0x16a1,0x16a1,0x1695,0x1692,0x1692,
+0x1692,0x1692,0x1692,0x1692,0x169b,0x169b,0x169b,0x169b,0x169b,0x169b,0x169b,0x169b,0x169b,0x169b,0x169b,0x169b,
+0x169b,0x169b,0x169b,0x169b,0x169b,0x169b,0x169b,0x169b,0x169b,0x169b,0x169b,0x169b,0x169b,0x169b,0x169b,0x169b,
+0x169b,0x169b,0x169b,0x169b,0x16a7,0x16a7,0x16a7,0x16a7,0x16a7,0x16a7,0x16a7,0x16a7,0x16a7,0x16a7,0x16a7,0x16a7,
+0x16a7,0x16a7,0x16a7,0x16a7,0x16a7,0x16a7,0x16a7,0x16a7,0x16a7,0x16a7,0x16a7,0x16a4,0x16a4,0x16a4,0x16a4,0x16a4,
+0x16a4,0x16a4,0x16a4,0x16a4,0x16aa,0x16aa,0x16aa,0x16aa,0x16aa,0x16aa,0x16aa,0x16aa,0x16aa,0x16aa,0x16aa,0x16aa,
+0x16aa,0x16aa,0x16aa,0x16aa,0x16aa,0x16aa,0x16aa,0x16aa,0x16aa,0x16aa,0x16aa,0x16aa,0x16aa,0x16aa,0x16aa,0x16aa,
+0x16aa,0x16aa,0x16aa,0x16aa,0x16ce,0x16ce,0x16ce,0x16ce,0x16ce,0x16ce,0x16ce,0x16ce,0x16ce,0x16ce,0x16ce,0x16ce,
+0x16ce,0x16ce,0x16ce,0x16ce,0x16ce,0x16ce,0x16ce,0x16ce,0x16ce,0x16ce,0x16ce,0x16ce,0x16ce,0x16ce,0x16ce,0x16ce,
+0x16ce,0x16ce,0x16ce,0x16ce,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,
+0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,0x16d7,
+0x16d7,0x16d7,0x16d7,0x16d7,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,
+0x16ef,0x16ef,0x16ef,0x16ef,0x16da,0x16e9,0x16e9,0x16da,0x16da,0x16da,0x16da,0x16da,0x16da,0x16e9,0x16da,0x16ec,
+0x16ec,0x16da,0x16ec,0x16da,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,
+0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,0x16ef,
+0x16ef,0x16ef,0x16ef,0x16ef,0x16f8,0x16f8,0x16f8,0x16f8,0x16f8,0x16f8,0x16f8,0x16f8,0x16f8,0x16f8,0x16f8,0x16f8,
+0x16f8,0x16f8,0x16f8,0x16f8,0x16f8,0x16f8,0x16f8,0x16f8,0x16f8,0x16f8,0x16f8,0x16f8,0x16f8,0x16f8,0x16f8,0x16f8,
+0x16f8,0x16f8,0x16f8,0x16f8,0x16fe,0x16fe,0x16fe,0x16fe,0x16fe,0x16fe,0x16fe,0x16fe,0x16fe,0x16fe,0x16fe,0x16fe,
+0x16fe,0x16fe,0x16fe,0x16fe,0x16fe,0x16fe,0x16fe,0x16fe,0x16fe,0x16fe,0x16fe,0x16fe,0x16fe,0x16fe,0x16fe,0x16fe,
+0x16fe,0x16fe,0x16fe,0x16fe,0x1956,0x1956,0x1956,0x1956,0x1956,0x1956,0x1956,0x1956,0x1956,0x1956,0x1956,0x1956,
+0x1740,0x1740,0x1740,0x1740,0x1956,0x1956,0x1956,0x1956,0x1956,0x1956,0x1956,0x1956,0x1956,0x1956,0x1956,0x1956,
+0x1956,0x1956,0x1956,0x1a22,0x1761,0x1761,0x1761,0x1761,0x1761,0x1761,0x1761,0x1761,0x1761,0x1761,0x1761,0x1761,
+0x1761,0x1761,0x1761,0x1761,0x1761,0x1761,0x1761,0x1761,0x1761,0x1761,0x1761,0x1761,0x1761,0x1761,0x1761,0x1761,
+0x1761,0x1761,0x1761,0x1761,0x179d,0x179d,0x179d,0x179d,0x179d,0x179d,0x179d,0x179d,0x179d,0x179d,0x179d,0x179d,
+0x179d,0x179d,0x179d,0x179d,0x179d,0x179d,0x179d,0x179d,0x179d,0x179d,0x179d,0x179d,0x179d,0x179d,0x179d,0x179d,
+0x179d,0x179d,0x179d,0x179d,0x179d,0x179d,0x17a3,0x17a0,0x179d,0x179d,0x179d,0x179d,0x179d,0x179d,0x179d,0x179d,
+0x179d,0x179d,0x179d,0x179d,0x179d,0x179d,0x179d,0x179d,0x17a6,0x17a6,0x17a6,0x17a6,0x17a6,0x17a6,0x17a6,0x17a6,
+0x17a6,0x17a6,0x17a6,0x17a6,0x17a6,0x17a6,0x17a6,0x17a6,0x17a6,0x17a6,0x17a6,0x17a6,0x17a6,0x17a6,0x17a6,0x17a6,
+0x17a6,0x17a6,0x17a6,0x17a6,0x17a6,0x17a6,0x17a6,0x17a6,0x17a9,0x17a9,0x17a9,0x17a9,0x17a9,0x17a9,0x17a9,0x17a9,
+0x17a9,0x17a9,0x17a9,0x17a9,0x17a9,0x17a9,0x17a9,0x17a9,0x17a9,0x17a9,0x17a9,0x17a9,0x17a9,0x17a9,0x17a9,0x17a9,
+0x17a9,0x17a9,0x17a9,0x17a9,0x17a9,0x17a9,0x17a9,0x17a9,0x17bb,0x17bb,0x17bb,0x17bb,0x17bb,0x17bb,0x17bb,0x17bb,
+0x17bb,0x17bb,0x17bb,0x17bb,0x17bb,0x17bb,0x17bb,0x17bb,0x17bb,0x17bb,0x17bb,0x17bb,0x17bb,0x17bb,0x17bb,0x17bb,
+0x17bb,0x17bb,0x17bb,0x17bb,0x17bb,0x17bb,0x17bb,0x17bb,0x17be,0x17be,0x17be,0x17be,0x17be,0x17be,0x17be,0x17be,
+0x17be,0x17be,0x17be,0x17be,0x17be,0x17be,0x17be,0x17be,0x17be,0x17be,0x17be,0x17be,0x17be,0x17be,0x17be,0x17be,
+0x17be,0x17be,0x17be,0x17be,0x17be,0x17be,0x17be,0x17be,0x17c1,0x17c1,0x17c1,0x17c1,0x17c1,0x17c1,0x17c1,0x17c1,
+0x17c1,0x17c1,0x17c1,0x17c1,0x17c1,0x17c1,0x17c1,0x17c1,0x17c1,0x17c1,0x17c1,0x17c1,0x17c1,0x17c1,0x17c1,0x17c1,
+0x17c1,0x17c1,0x17c1,0x17c1,0x17c1,0x17c1,0x17c1,0x17c1,0x17c1,0x17c1,0x17c1,0x17c4,0x17c4,0x17c4,0x17c4,0x17c1,
+0x17c1,0x17c1,0x17c1,0x17c1,0x17c1,0x17c1,0x17c1,0x17c1,0x17c1,0x17c1,0x17c1,0x17c1,0x17c1,0x17c4,0x17c4,0x17c4,
+0x17c4,0x17c4,0x17c4,0x17c4,0x17c4,0x17c1,0x17c4,0x17c4,0x17c4,0x17c4,0x17c4,0x17c4,0x17c4,0x17c4,0x17c4,0x17c4,
+0x17c4,0x17c4,0x17c4,0x17c4,0x17c4,0x17c4,0x17c4,0x17c4,0x17c4,0x17c4,0x17c4,0x17c4,0x17c4,0x17c4,0x17c4,0x17c4,
+0x17c4,0x17c4,0x17c4,0x17c4,0x17c4,0x17c4,0x17c4,0x17c4,0x17dc,0x17dc,0x17dc,0x17dc,0x17dc,0x17dc,0x17dc,0x17dc,
+0x17dc,0x17dc,0x17dc,0x17dc,0x17dc,0x17dc,0x17dc,0x17dc,0x17dc,0x17dc,0x17dc,0x17dc,0x17dc,0x17dc,0x17dc,0x17dc,
+0x17dc,0x17dc,0x17dc,0x17dc,0x17dc,0x17dc,0x17dc,0x17dc,0x18c6,0x18c6,0x18c6,0x18c6,0x18c6,0x18c6,0x18c6,0x18c6,
+0x18c6,0x18c6,0x18c6,0x18c6,0x1b3f,0x1a94,0x1a94,0x1a97,0x17df,0x17df,0x17df,0x17df,0x17df,0x17df,0x17df,0x17df,
+0x17e2,0x1890,0x1890,0x1890,0x1890,0x1890,0x1890,0x192c,0x17df,0x17df,0x17df,0x17df,0x17df,0x188d,0x188d,0x188d,
+0x188d,0x188d,0x188d,0x188d,0x188d,0x188d,0x188d,0x188d,0x188d,0x188d,0x1929,0x1929,0x1929,0x1929,0x1929,0x1929,
+0x1a0a,0x1a0a,0x1a0a,0x1a0a,0x1a0a,0x1a0a,0x1a0a,0x1a0a,0x188d,0x188d,0x188d,0x188d,0x188d,0x188d,0x1890,0x188d,
+0x1929,0x1929,0x1929,0x1929,0x1929,0x1929,0x1929,0x1929,0x1890,0x192c,0x192c,0x1890,0x1890,0x1890,0x1890,0x1890,
+0x1890,0x1890,0x188d,0x180f,0x1890,0x1890,0x1890,0x1a94,0x188d,0x188d,0x188d,0x188d,0x188d,0x188d,0x180f,0x188d,
+0x188d,0x188d,0x188d,0x188d,0x1929,0x1a0a,0x1a0a,0x1a0a,0x188d,0x188d,0x188d,0x188d,0x188d,0x188d,0x188d,0x188d,
+0x188d,0x188d,0x188d,0x188d,0x188d,0x188d,0x188d,0x1929,0x1824,0x1824,0x1821,0x1821,0x1821,0x1821,0x1821,0x1821,
+0x1821,0x1821,0x1821,0x1821,0x1821,0x1821,0x1821,0x1821,0x1821,0x1821,0x1821,0x1821,0x1821,0x1821,0x1821,0x1821,
+0x1821,0x1821,0x1821,0x1821,0x1821,0x1821,0x1821,0x1821,0x1824,0x1824,0x1824,0x1824,0x1824,0x1824,0x1824,0x1824,
+0x1824,0x1824,0x1824,0x1824,0x1824,0x1824,0x1824,0x1824,0x1824,0x1824,0x1824,0x1824,0x1824,0x1824,0x1824,0x1824,
+0x1824,0x1824,0x1824,0x1824,0x1824,0x1824,0x1824,0x1824,0x1872,0x1872,0x1872,0x1872,0x1872,0x1872,0x1872,0x1872,
+0x1872,0x1872,0x1872,0x1872,0x1872,0x1872,0x1872,0x1872,0x1872,0x1872,0x1872,0x1872,0x1872,0x186f,0x186f,0x186f,
+0x185a,0x185a,0x185a,0x185a,0x185a,0x185a,0x185a,0x185a,0x1872,0x1872,0x1872,0x1872,0x1872,0x1872,0x1872,0x1872,
+0x1872,0x1872,0x1872,0x1872,0x1872,0x1872,0x1872,0x1872,0x1872,0x1872,0x1872,0x1872,0x1872,0x1872,0x1872,0x1872,
+0x1872,0x1872,0x1872,0x1872,0x1872,0x1872,0x1872,0x1872,0x1896,0x1896,0x1896,0x1896,0x1896,0x1896,0x1896,0x1896,
+0x1896,0x1896,0x1896,0x1896,0x1896,0x1896,0x1896,0x1896,0x1896,0x1896,0x1896,0x1896,0x1896,0x1896,0x1896,0x1896,
+0x1896,0x1896,0x1896,0x1896,0x1896,0x1896,0x1896,0x1896,0x1899,0x1899,0x1899,0x1899,0x1899,0x1899,0x1899,0x1899,
+0x1899,0x1899,0x1899,0x1899,0x1899,0x1899,0x1899,0x1899,0x1899,0x1899,0x1899,0x1899,0x1899,0x1899,0x1899,0x1899,
+0x1899,0x1899,0x1899,0x1899,0x1899,0x1899,0x1899,0x1899,0x1899,0x1899,0x1899,0x1b48,0x1b48,0x1b48,0x1b48,0x1b48,
+0x1b48,0x1b48,0x1b48,0x1b48,0x1b48,0x1b48,0x1b48,0x1b48,0x18f0,0x18f0,0x18f0,0x18f0,0x1a46,0x1a46,0x18f3,0x18f3,
+0x18f3,0x18f3,0x18db,0x18db,0x18db,0x18db,0x18db,0x18db,0x18db,0x18db,0x18db,0x18db,0x18db,0x18db,0x18db,0x18ed,
+0x18de,0x18e1,0x18e4,0x18f6,0x18f6,0x1995,0x18e7,0x18e7,0x18f0,0x18f0,0x18f0,0x18f0,0x18f0,0x18f0,0x18f0,0x18f0,
+0x18f0,0x18f0,0x18f0,0x18f0,0x18f0,0x18f0,0x18f0,0x18f0,0x18f0,0x18f0,0x18f0,0x18f0,0x18f0,0x18f0,0x18f0,0x18f0,
+0x18f0,0x18f0,0x18f0,0x18f0,0x18f0,0x18f0,0x18f0,0x18f0,0x1911,0x1911,0x1911,0x1911,0x1911,0x1911,0x1911,0x1911,
+0x1911,0x1911,0x1911,0x1911,0x1911,0x1911,0x1911,0x1911,0x1911,0x1911,0x1911,0x18fc,0x1902,0x18ff,0x18ff,0x18ff,
+0x18ff,0x190e,0x1914,0x18ff,0x18ff,0x18ff,0x18ff,0x190b,0x1911,0x18ff,0x18ff,0x18ff,0x18ff,0x18ff,0x18ff,0x18ff,
+0x18ff,0x18ff,0x18ff,0x1911,0x1911,0x1911,0x1911,0x1911,0x1911,0x1911,0x1911,0x1911,0x1911,0x1911,0x1911,0x1911,
+0x1911,0x1911,0x1911,0x1911,0x1911,0x1911,0x1911,0x1911,0x1923,0x1923,0x1923,0x1923,0x1923,0x1923,0x1923,0x1923,
+0x1923,0x1923,0x1923,0x1923,0x1923,0x1923,0x1923,0x1923,0x1923,0x1923,0x1923,0x1923,0x1923,0x1923,0x1923,0x1923,
+0x1923,0x1923,0x1923,0x1923,0x1923,0x1923,0x1923,0x1923,0x1929,0x1929,0x1929,0x1929,0x1929,0x1929,0x1929,0x1a0a,
+0x1a0a,0x1a0a,0x1a0a,0x1a0a,0x1a0a,0x1a0a,0x1a0a,0x1a0a,0x1a0a,0x1a0a,0x1a0a,0x1a0a,0x1a0a,0x1a0a,0x1a0a,0x1a0a,
+0x1a0a,0x1a0a,0x1a0a,0x1a0a,0x1a0a,0x1a0a,0x1a0a,0x1a0a,0x1932,0x1932,0x1932,0x1932,0x1932,0x1932,0x1932,0x1932,
+0x1932,0x1932,0x1932,0x1932,0x1932,0x1932,0x1932,0x1932,0x1932,0x1932,0x1932,0x1932,0x1932,0x1932,0x1932,0x1932,
+0x1932,0x1932,0x1932,0x1932,0x1932,0x1932,0x1932,0x1932,0x1938,0x1938,0x1938,0x1938,0x1938,0x1938,0x1938,0x1938,
+0x1938,0x1938,0x1938,0x1938,0x1938,0x1938,0x1938,0x1938,0x1938,0x1938,0x1938,0x1938,0x1938,0x1938,0x1938,0x1938,
+0x1938,0x1938,0x1938,0x1938,0x1938,0x1938,0x1938,0x1938,0x19aa,0x19aa,0x19aa,0x19aa,0x19aa,0x19aa,0x19aa,0x19aa,
+0x19aa,0x19aa,0x19aa,0x19aa,0x19aa,0x19aa,0x19aa,0x19aa,0x19aa,0x19aa,0x19aa,0x19aa,0x19aa,0x19aa,0x19aa,0x19aa,
+0x19aa,0x19aa,0x19aa,0x19aa,0x19aa,0x19aa,0x19aa,0x19aa,0x19c5,0x19c5,0x19c5,0x19c5,0x19c5,0x19c5,0x19c5,0x19c5,
+0x19c5,0x19c5,0x19c5,0x19c5,0x19c5,0x19c5,0x19c5,0x19c5,0x19c5,0x19c5,0x19c5,0x19c5,0x19c5,0x19c5,0x19c5,0x19c5,
+0x19c5,0x19c5,0x19c5,0x19c5,0x19c5,0x19c5,0x19c5,0x19c5,0x19cb,0x19cb,0x19cb,0x19cb,0x19cb,0x19cb,0x19cb,0x19cb,
+0x19cb,0x19cb,0x19cb,0x19cb,0x19cb,0x19cb,0x19cb,0x19cb,0x19cb,0x19cb,0x19cb,0x19cb,0x19cb,0x19cb,0x19cb,0x19cb,
+0x19cb,0x19cb,0x19cb,0x19cb,0x19cb,0x19cb,0x19cb,0x19cb,0x19e6,0x19e6,0x19e6,0x19e6,0x19e6,0x19e6,0x19e6,0x19e6,
+0x19e6,0x19e6,0x19e6,0x19e6,0x19e6,0x19e6,0x19e6,0x19e6,0x19e6,0x19e6,0x19e6,0x19e6,0x19e6,0x19e6,0x19e6,0x19e6,
+0x19e6,0x19e6,0x19e6,0x19e6,0x19e6,0x19e6,0x19e6,0x19e6,0x19e9,0x19e9,0x19e9,0x19e9,0x19e9,0x19e9,0x19e9,0x19e9,
+0x19e9,0x19e9,0x19e9,0x19e9,0x19e9,0x19e9,0x19e9,0x19e9,0x19e9,0x19e9,0x19e9,0x19e9,0x19e9,0x19e9,0x19e9,0x19e9,
+0x19e9,0x19e9,0x19e9,0x19e9,0x19e9,0x19e9,0x19e9,0x19e9,0x19f2,0x19f2,0x19f2,0x19f2,0x19f2,0x19f2,0x19f2,0x19f2,
+0x19f2,0x19f2,0x19f2,0x19f2,0x19f2,0x19f2,0x19f2,0x19f2,0x19f2,0x19f2,0x19f2,0x19f2,0x19f2,0x19f2,0x19f2,0x19f2,
+0x19f2,0x19f2,0x19f2,0x19f2,0x19f2,0x19ef,0x19ef,0x19ef,0x1a0a,0x1a0a,0x1a0a,0x1b3c,0x1b3c,0x1a94,0x1a94,0x1a94,
+0x1a94,0x1a94,0x1a94,0x1b3c,0x1b3c,0x1b3c,0x1a94,0x1a94,0x1a0d,0x1a0d,0x1a0d,0x1a0d,0x1a0a,0x1a10,0x1a10,0x1a0a,
+0x1a10,0x1a10,0x1a94,0x1a97,0x1a94,0x1a94,0x1a94,0x1a94,0x1a49,0x1a49,0x1a49,0x1a49,0x1a49,0x1a49,0x1a49,0x1a49,
+0x1a49,0x1a49,0x1a49,0x1a49,0x1a49,0x1a49,0x1a49,0x1a49,0x1a49,0x1a49,0x1a49,0x1a49,0x1a49,0x1a49,0x1a49,0x1a49,
+0x1a49,0x1a49,0x1a49,0x1a49,0x1a49,0x1a49,0x1a49,0x1a49,0x1a70,0x1a70,0x1a70,0x1a70,0x1a70,0x1a70,0x1a70,0x1a70,
+0x1a70,0x1a70,0x1a70,0x1a70,0x1a70,0x1a70,0x1a70,0x1a70,0x1a70,0x1a70,0x1a70,0x1a70,0x1a70,0x1a70,0x1a70,0x1a70,
+0x1a70,0x1a70,0x1a70,0x1a70,0x1a70,0x1a70,0x1a70,0x1a70,0x1a79,0x1a79,0x1a79,0x1a79,0x1a79,0x1a79,0x1a79,0x1a79,
+0x1a79,0x1a79,0x1a79,0x1a79,0x1a79,0x1a79,0x1a79,0x1a79,0x1aaf,0x1aaf,0x1a79,0x1aaf,0x1a79,0x1a79,0x1a79,0x1a79,
+0x1a79,0x1a79,0x1a79,0x1a79,0x1a79,0x1a7f,0x1a7f,0x1a7f,0x1a8b,0x1a8b,0x1a8b,0x1a8b,0x1a8b,0x1a8b,0x1a8b,0x1a8b,
+0x1a8b,0x1a8b,0x1a8b,0x1a8b,0x1a8b,0x1a8b,0x1a8b,0x1a8b,0x1a8b,0x1a8b,0x1a8b,0x1a8b,0x1a8b,0x1a8b,0x1a8b,0x1a8b,
+0x1a8b,0x1a8b,0x1a8b,0x1a8b,0x1a8b,0x1a8b,0x1a8b,0x1a8b,0x1b1e,0x1b1e,0x1b1e,0x1b1e,0x1b1e,0x1b1e,0x1b1e,0x1b1e,
+0x1b1e,0x1b1e,0x1b1e,0x1b1e,0x1b1e,0x1b1e,0x1b1e,0x1b1e,0x1b1e,0x1b1e,0x1b1e,0x1b1e,0x1b1e,0x1b1e,0x1b1e,0x1b1e,
+0x1b1e,0x1b1e,0x1b1e,0x1b1e,0x1b1e,0x1b1e,0x1b1e,0x1b1e,0x1b2a,0x1b2a,0x1b2a,0x1b2a,0x1b2a,0x1b2a,0x1b2a,0x1b2a,
+0x1b2a,0x1b2a,0x1b2a,0x1b2a,0x1b2a,0x1b2a,0x1b2a,0x1b2a,0x1b2a,0x1b2a,0x1b2a,0x1b2a,0x1b2a,0x1b2a,0x1b2a,0x1b2a,
+0x1b2a,0x1b2a,0x1b2a,0x1b2a,0x1b2a,0x1b2a,0x1b2a,0x1b2a,0x1b4e,0x1b4e,0x1b4e,0x1b4e,0x1b4e,0x1b4e,0x1b4e,0x1b4e,
+0x1b4e,0x1b4e,0x1b4e,0x1b4e,0x1b4e,0x1b4e,0x1b4e,0x1b4e,0x1b4e,0x1b4e,0x1b4e,0x1b4e,0x1b4e,0x1b4e,0x1b4e,0x1b4e,
+0x1b4e,0x1b4e,0x1b4e,0x1b4e,0x1b4e,0x1b4e,0x1b4e,0x1b4e,0x1b51,0x1b51,0x1b51,0x1b51,0x1b51,0x1b51,0x1b51,0x1b51,
+0x1b51,0x1b51,0x1b51,0x1b51,0x1b51,0x1b51,0x1b51,0x1b51,0x1b51,0x1b51,0x1b51,0x1b51,0x1b51,0x1b51,0x1b51,0x1b51,
+0x1b51,0x1b51,0x1b51,0x1b51,0x1b51,0x1b51,0x1b51,0x1b51,0,0,0,0
 };
 
 static const UTrie2 propsVectorsTrie={
     propsVectorsTrie_index,
-    propsVectorsTrie_index+4640,
+    propsVectorsTrie_index+5024,
     NULL,
-    4640,
-    22812,
+    5024,
+    26204,
     0xa40,
-    0x12a0,
+    0x1420,
     0x0,
     0x0,
     0x110000,
-    0x6b38,
+    0x79f8,
     NULL, 0, FALSE, FALSE, 0, NULL
 };
 
-static const uint32_t propsVectors[5931]={
-0x67,0,0,0x67,0x80000,0x20,0x867,0,0,0xa67,0,0,0xb67,0,0,0xc67,
-0,0,0xd67,0,0,0xe67,0,0,0x1067,0,0,0x1167,0,0,0x1267,0,
-0,0x1367,0,0,0x1467,0,0,0x1567,0,0,0x1667,0,0,0x1767,0,0,
-0x1867,0,0,0x1967,0,0,0x1a67,0,0,0x1b67,0,0,0x1d67,0,0,0x1f67,
-0,0,0x2067,0,0,0x2267,0,0,0x2367,0,0,0x2467,0,0,0x2567,0,
-0,0x2767,0,0,0x2867,0x80000,0x20,0x2967,0,0,0x2a67,0,0x1600000,0x2b67,0,0,
-0x2d67,0,0,0x3067,0x20000000,0,0x3167,0x20000000,0,0x3267,0x20000000,0,0x3a67,0,0,0x3b67,
-0,0,0x3c67,0,0,0x3e67,0,0,0x4067,0,0,0x4167,0,0,0x4367,0,
-0,0x4467,0,0,0x4867,0,0,0x4967,0,0,0x4a67,0,0,0x5067,0,0,
-0x5167,0,0,0x5467,0,0,0x5567,0,0,0x5667,0x80000,0x20,0x5767,0,0,0x5867,
-0,0,0x5967,0,0,0x5b67,0,0,0x5c67,0,0,0x5d67,0,0,0x6067,0x80000,
-0x20,0x6267,0,0,0x6367,0,0,0x6467,0,0,0x6567,0,0,0x6f67,0,0,
-0x7067,0,0,0x7367,0x20000000,0,0x7567,0,0,0x7667,0,0,0x7767,0,0,0x7867,
-0,0,0x7a67,0,0,0x7b67,0,0,0x7c67,0,0,0x7e67,0,0,0x7f67,0,
-0,0x8167,0,0,0x8267,0,0,0x8367,0,0,0x8467,0,0,0x8567,0,0,
-0x8667,0,0,0x8767,0,0,0x8867,0,0,0x8967,0,0,0x8b67,0,0,0x8c67,
-0,0,0x8e67,0x20000000,0,0x8f67,0,0,0x9067,0,0,0x9167,0,0,0x9267,0,
-0,0x9367,0,0,0x9567,0,0,0x9667,0,0,0x9767,0,0,0x9867,0,0,
-0x9967,0,0,0x9a67,0,0,0x9c67,0,0,0x9f67,0,0,0xa167,0,0,0xa367,
-0,0,0xa467,0,0,0xa567,0,0,0xa667,0,0,0xa767,0,0,0xa867,0,
-0,0xa967,0,0,0xaa67,0,0,0xab67,0,0,0xac67,0,0,0xad67,0,0,
-0xae67,0,0,0xaf67,0,0,0xb167,0,0,0xb267,0,0,0xb367,0,0,0xb467,
-0,0,0xb567,0,0,0xb767,0,0,0xb867,0,0,0xb967,0,0,0xba67,0,
-0,0xbc67,0,0,0xbd67,0,0,0xbe67,0,0,0xbf67,0,0,0xc067,0,0,
-0xc167,0,0,0xc267,0,0,0xc367,0,0,0xc467,0,0,0xc667,0,0,0xc767,
-0,0,0xc867,0,0,0xc967,0,0,0xca67,0,0,0xcb67,0,0,0xcc67,0,
-0,0xcd67,0,0,0xcf67,0,0,0xd067,0,0,0xd267,0,0,0xd367,0,0,
-0xd467,0,0,0xd567,0,0,0xd667,0,0,0xd867,0,0,0xd967,0,0,0xda67,
-0,0,0xdb67,0,0,0xdc67,0,0,0xdd67,0,0,0xde67,0,0,0xdf67,0,
-0,0xe067,0,0,0xe167,0,0,0xe267,0,0,0xe367,0,0,0xe467,0,0,
-0xe567,0,0,0xe667,0,0,0xe767,0,0,0xe867,0,0,0xe967,0,0,0xea67,
-0,0,0xeb67,0,0,0xec67,0,0,0xed67,0,0,0xee67,0,0,0xef67,0,
-0,0xf167,0,0,0xf367,0,0,0xf567,0,0,0xf667,0,0,0xf767,0,0,
-0xf867,0,0,0xf967,0,0,0xfa67,0,0,0xfb67,0,0,0xfc67,0,0,0xfd67,
-0,0,0xfe67,0,0,0x10167,0,0,0x10267,0,0,0x10367,0,0,0x10467,0,
-0,0x10567,0,0,0x10667,0,0,0xa0067,0,0xe00000,0xa4667,0,0xe00000,0xa4767,0,0xe00000,
-0xa4f67,0,0xe00000,0xa5e67,0,0xe00000,0xa5f67,0,0xe00000,0xac567,0,0xe00000,0xad167,0,0xe00000,0xb0067,
-0,0xe00000,0x11000100,0,0x900020,0x11000100,0x40000001,0x440020,0x11000100,0x40000001,0x643020,0x11000100,0x40000001,0xa5a040,0x11000100,0x40000001,
-0x116a8a0,0x11000200,0,0x900020,0x11000200,0x4000001,0xc4000b,0x11000200,0x7c00100,0x220402,0x11000200,0x24000000,0x10200000,0x11000200,0x24000008,0x1710000,
-0x11000200,0x40000001,0x1d3b020,0x11000219,0x7c00100,0x220401,0x11000219,0x7c00100,0x250401,0x11000319,0x7c00100,0x220401,0x11000319,0x7c00100,0x220402,0x11000319,
-0x7c00100,0x250400,0x11000319,0x7c00100,0x250401,0x11000419,0x7c00100,0x220400,0x11000419,0x7c00100,0x220401,0x11000419,0x7c00100,0x220402,0x11000419,0x7c00100,
-0x230400,0x11000419,0x7c00100,0x250400,0x11000419,0x7c00100,0x250401,0x11000419,0x7c00100,0x250402,0x11000519,0x7c00100,0x220400,0x11000519,0x7c00100,0x230400,
-0x11000600,0x4000400,0x200000,0x11000600,0x4000400,0x200002,0x11000600,0x4000400,0x201000,0x11000600,0x7c00500,0x220400,0x11000600,0x7c00500,0x230400,0x11000600,
-0x7c00500,0x530400,0x11000600,0x7c00d00,0x230400,0x11000619,0x7c00500,0x22040f,0x11000800,0x4000010,0x1001401,0x11000800,0x4000400,0x200001,0x11000800,0x6800010,
-0x201001,0x11000800,0x7c00500,0x230401,0x11000807,0x7c00100,0x220400,0x11000807,0x7c00100,0x250400,0x1100080e,0x4000400,0x200000,0x1100080e,0x4000400,0x200002,
-0x1100080e,0x7000500,0x220402,0x1100080e,0x7c00100,0x220400,0x1100080e,0x7c00100,0x220401,0x1100080e,0x7c00100,0x220402,0x1100080e,0x7c00100,0x250400,0x1100080e,
-0x7c00100,0x250401,0x1100080e,0x7c00120,0x220402,0x1100080e,0x7c00120,0x250402,0x11000908,0x2802400,0x962460,0x11000908,0x4000000,0x200000,0x11000908,0x7c00100,
-0x220400,0x11000908,0x7c00100,0x220401,0x11000908,0x7c00100,0x250400,0x11000908,0x7c00100,0x250401,0x11000a03,0x4000000,0x200000,0x11000a03,0x4000000,0x270000,
-0x11000a03,0x7c00100,0x220400,0x11000a03,0x7c00100,0x220402,0x11000a03,0x7c00100,0x250400,0x11000a03,0x7c00500,0x230400,0x11000b13,0x2802500,0x962460,0x11000b13,
-0x4000000,0x200000,0x11000b13,0x4000000,0x201000,0x11000b13,0x4000000,0x230400,0x11000b13,0x4000002,0x400000,0x11000b13,0x4000010,0x200000,0x11000b13,0x7c00100,
-0x2633800,0x11000c00,0,0x218820,0x11000c02,0x2802100,0x962460,0x11000c02,0x2802400,0x962460,0x11000c02,0x4000000,0x200000,0x11000c02,0x4000000,0x1329400,
-0x11000c02,0x4000000,0x1329800,0x11000c02,0x4000000,0x1500000,0x11000c02,0x6800000,0x1329800,0x11000c02,0x7c00100,0x230400,0x11000c02,0x7c00100,0x230401,0x11000c02,
-0x7c00100,0x230402,0x11000c02,0x7c00500,0x230400,0x11000c02,0x7d00100,0x230400,0x11000c02,0xc000010,0xb48000,0x11000f0a,0x2802100,0x962460,0x11000f0a,0x2802400,
-0x962460,0x11000f0a,0x2806400,0x962460,0x11000f0a,0x4000000,0x200000,0x11000f0a,0x6800100,0x962540,0x11000f0a,0x7c00100,0x230400,0x11000f0a,0x7c00100,0x230401,
-0x11001004,0x2802100,0x962460,0x11001004,0x2802400,0x962460,0x11001004,0x2806400,0x962460,0x11001004,0x4000000,0x200000,0x11001004,0x4000000,0x1500000,0x11001004,
-0x6800100,0x962540,0x11001004,0x6800100,0x962541,0x11001004,0x7c00100,0x230400,0x11001004,0x7c00100,0x230401,0x11001110,0x2802100,0x962460,0x11001110,0x2802400,
-0x962460,0x11001110,0x2806400,0x962460,0x11001110,0x6800100,0x962540,0x11001110,0x7c00100,0x230400,0x11001110,0x7c00100,0x230401,0x1100120f,0x2802100,0x962460,
-0x1100120f,0x2802400,0x962460,0x1100120f,0x2806400,0x962460,0x1100120f,0x6800100,0x962540,0x1100120f,0x7c00100,0x230400,0x1100131f,0x2802100,0x962460,0x1100131f,
-0x2802400,0x962460,0x1100131f,0x2806400,0x962460,0x1100131f,0x4000000,0x200000,0x1100131f,0x6800000,0x1329800,0x1100131f,0x6800100,0x962540,0x1100131f,0x6800100,
-0x962541,0x1100131f,0x7c00100,0x230400,0x1100131f,0x7c00100,0x230401,0x11001423,0x2802100,0x962460,0x11001423,0x2806400,0x962460,0x11001423,0x6800100,0x962540,
-0x11001423,0x6800100,0x962541,0x11001423,0x7c00100,0x230400,0x11001423,0x7c00100,0x230401,0x11001524,0x2802100,0x962460,0x11001524,0x2802100,0x962461,0x11001524,
-0x2806400,0x962460,0x11001524,0x6800000,0x1329800,0x11001524,0x6800100,0x962540,0x11001524,0x7c00100,0x230400,0x11001615,0x2802100,0x962460,0x11001615,0x2806400,
-0x962460,0x11001615,0x6800000,0x1329800,0x11001615,0x6800100,0x962540,0x11001615,0x6800100,0x962541,0x11001615,0x7c00100,0x230400,0x1100171a,0x2802100,0x962460,
-0x1100171a,0x2806400,0x962460,0x1100171a,0x6800000,0x1329800,0x1100171a,0x6800100,0x962540,0x1100171a,0x6800100,0x962541,0x1100171a,0x7c00100,0x230400,0x11001900,
-0x4000000,0x1600000,0x11001926,0x2802100,0x1862460,0x11001926,0x2802400,0x1862460,0x11001926,0x2806100,0x1862460,0x11001926,0x4000000,0x200000,0x11001926,0x4000010,
-0x400000,0x11001926,0x6800000,0x1329800,0x11001926,0x7800100,0x1830142,0x11001926,0x7c00100,0x1830000,0x11001926,0x7c00900,0x1830000,0x11001926,0x7e00100,0x1830000,
-0x11001a18,0x2802100,0x1862460,0x11001a18,0x2802400,0x1862460,0x11001a18,0x6800000,0x1329800,0x11001a18,0x7800100,0x1830142,0x11001a18,0x7c00100,0x1830000,0x11001a18,
-0x7c00100,0x1830002,0x11001a18,0x7c00900,0x1830000,0x11001a18,0x7e00100,0x1830000,0x11001d00,0x4000000,0x200000,0x11001d0c,0x7c00100,0x230400,0x11001d0c,0x7c00100,
-0x250400,0x11001e12,0x7c00100,0x2230500,0x11001e12,0x7c00100,0x2330520,0x11001e12,0x7c80100,0x2330520,0x11002619,0x7c00100,0x220401,0x11002619,0x7c00100,0x220402,
-0x11002619,0x7c00100,0x250401,0x1100270e,0x4000400,0x200001,0x1100270e,0x4000400,0x200002,0x1100270e,0x4000400,0x500001,0x1100270e,0x7c00100,0x220401,0x1100270e,
-0x7c00100,0x250401,0x11002800,0x80000,0x918820,0x11002800,0x80000,0x1c18020,0x11002800,0x180000,0x918820,0x11002800,0x4000001,0x440001,0x11002800,0x4000001,
-0x440002,0x11002800,0x4000001,0xc4000b,0x11002800,0x6800000,0x201c00,0x11002800,0x6800020,0x201c00,0x11002800,0x24000000,0x200000,0x11002800,0x24000000,0x200002,
-0x11002800,0x24000000,0x810000,0x11002800,0x24000000,0x1410000,0x11002800,0x24000000,0x1500000,0x11002800,0x24000000,0x1500002,0x11002800,0x24000002,0x400000,0x11002800,
-0x24000006,0xc0000b,0x11002800,0x24000008,0x1410000,0x11002800,0x24000008,0x1710000,0x11002800,0x24000020,0x1001400,0x11002800,0x24000020,0x1500002,0x11002800,0x2c000010,
-0x1248000,0x11002800,0x2c000010,0x11248002,0x11002800,0x40000001,0x63b020,0x11002800,0x40080000,0x918820,0x11002801,0x82000,0x962460,0x11002900,0x4000000,0x20000e,
-0x11002900,0x4000000,0x20000f,0x11002900,0x4000020,0x20000e,0x11002900,0x4000020,0x20000f,0x11002900,0x4000020,0x81000e,0x11002900,0x4000020,0x81000f,0x11002900,
-0x4000020,0x141000e,0x11002900,0x4000020,0x141000f,0x11002900,0x4000022,0x20000e,0x11002900,0x4000022,0x20000f,0x11002a00,0x4000000,0x1500000,0x11002a00,0x4000000,
-0x1600000,0x11002a00,0x4000000,0x1600002,0x11002b01,0x2000,0x962460,0x11002b01,0x2802020,0x962460,0x11002c00,0x4000000,0x200000,0x11002c00,0x4000000,0x200002,
-0x11002c00,0x4000000,0x20000f,0x11002c00,0x4000020,0x200000,0x11002c00,0x7c00000,0x200000,0x11002c00,0x7c00020,0x200000,0x11002c00,0x7c00120,0x220405,0x11002c00,
-0x7c00120,0x230402,0x11002c00,0x7c00120,0x250402,0x11002c00,0x7c00120,0x250405,0x11002c19,0x7c00100,0x250400,0x11002c19,0x7c00100,0x250401,0x11002d00,0x4000000,
-0x100006,0x11002d00,0x4000000,0x200006,0x11002d19,0x7c00100,0x220402,0x11002d19,0x7c00100,0x230400,0x11002d19,0x7c00100,0x250402,0x11002e00,0x24000000,0x200000,
-0x11002e00,0x24000020,0x200000,0x11002e00,0x24000020,0x200001,0x11002e00,0x24000020,0x10200000,0x11002f00,0x24000020,0x200000,0x11002f00,0x24000020,0x200001,0x11002f00,
-0x24000020,0x200002,0x11002f00,0x24000020,0xf00000,0x11002f00,0x24000020,0x1600000,0x11002f00,0x24000022,0x1600000,0x11003000,0x24000000,0x200000,0x11003000,0x24000000,
-0x10200000,0x11003000,0x24000000,0x30e00000,0x11003000,0x24000020,0x200000,0x11003000,0x24000020,0x810000,0x11003000,0x24000020,0x1410000,0x11003100,0x24000000,0x200000,
-0x11003200,0x24000000,0x200000,0x11003300,0x4000000,0x100003,0x11003400,0x24000000,0x100000,0x11003400,0x24000000,0x200000,0x11003500,0x24000000,0x200000,0x11003600,
-0x24000000,0x200000,0x11003600,0x24000000,0x10200000,0x11003600,0x24000020,0x200000,0x11003700,0x24000000,0x200000,0x11003700,0x24000000,0xe00000,0x11003700,0x24000000,
-0x10200000,0x11003700,0x24000000,0x10e00000,0x11003700,0x24000000,0x30200000,0x11003700,0x24000000,0x90e00000,0x11003700,0x24000020,0x200000,0x11003800,0x4000000,0x100000,
-0x11003800,0x24000000,0x200000,0x11003800,0x24000000,0xb00000,0x11003800,0x24000000,0xe00000,0x11003800,0x24000000,0x1710000,0x11003800,0x24000000,0x10200000,0x11003800,
-0x24000000,0x10b00000,0x11003800,0x24000000,0x10e00000,0x11003800,0x24000000,0x90e00000,0x11005003,0x7c00100,0x220402,0x11005013,0x2802500,0x962460,0x11005013,0x4000020,
-0x200005,0x11005013,0x7c00100,0x2633801,0x11005013,0x7c00100,0x2633802,0x11005013,0x7c00100,0x2633805,0x11005019,0x7c00100,0x220402,0x11005100,0x24000000,0x810000,
-0x11005100,0x24000000,0x1410000,0x11005102,0x7000100,0x230408,0x11005102,0x7c00100,0x230404,0x11005102,0x7c00100,0x230407,0x11005102,0x7c00100,0x230408,0x11005102,
-0x7c00100,0x230409,0x11005201,0x2802400,0x962460,0x11005500,0x80000,0x1e18820,0x11005502,0x7000100,0x230408,0x11005502,0x7c00100,0x230404,0x11005502,0x7c00100,
-0x230407,0x11005502,0x7c00100,0x230408,0x11005502,0x7c00100,0x230409,0x11005667,0x1000,0,0x11020200,0x80004,0x418820,0x11020200,0x4000000,0x100006,
-0x11020200,0x4000000,0x10000f,0x11020200,0x4000400,0x100002,0x11020200,0x4000400,0x500002,0x11020200,0x6800c00,0x101000,0x11020200,0x24000000,0x100000,0x11020200,
-0x24000000,0x1400000,0x11020200,0x24000000,0x1500000,0x11020200,0x24000000,0x1600000,0x11020200,0x24000000,0x10200000,0x11020200,0x24000020,0x100000,0x11020200,0x24000020,
-0x1600000,0x11020219,0x7c00100,0x12040f,0x11020219,0x7c00100,0x220400,0x11020219,0x7c00100,0x220401,0x11020219,0x7c00100,0x250400,0x11020319,0x7c00100,0x220400,
-0x11020319,0x7c00100,0x220401,0x11020319,0x7c00100,0x220402,0x11020319,0x7c00100,0x250400,0x11020319,0x7c00100,0x250402,0x11020319,0x7d00100,0x220402,0x11020419,
-0x7c00100,0x220401,0x11020519,0x7c00100,0x220400,0x11020600,0x4000400,0x100002,0x11020600,0x4000400,0x200000,0x11020600,0x7c00500,0x130400,0x11020600,0x7c00d00,
-0x130400,0x11020701,0x2802400,0x962460,0x11020701,0x2802400,0x962461,0x11020701,0x2802400,0xc62460,0x1102080e,0x7c00100,0x220400,0x1102080e,0x7c00100,0x250400,
-0x11020908,0x7c00100,0x220400,0x11020908,0x7c00100,0x220401,0x11020908,0x7c00100,0x250400,0x11020908,0x7c00100,0x250401,0x11022800,0x24000000,0x100000,0x11022800,
-0x24000000,0x200000,0x11022800,0x24000000,0x200002,0x11022800,0x24000000,0x401000,0x11022800,0x24000000,0xf00002,0x11022800,0x24000000,0xf0ac02,0x11022800,0x24000000,
-0x1500000,0x11022800,0x24000002,0x100000,0x11022800,0x24000002,0x370000,0x11022800,0x24000002,0x470000,0x11022800,0x24000006,0x400000,0x11022800,0x24000008,0x1710000,
-0x11022800,0x24000008,0x1712c00,0x11022800,0x24000020,0x100000,0x11022800,0x24000020,0x1500000,0x11022800,0x24000020,0x1500002,0x11022900,0x4000000,0x10000e,0x11022900,
-0x4000000,0x10000f,0x11022919,0x7c00100,0x12040f,0x11022c00,0x4000000,0x100002,0x11022c00,0x4000000,0x1500002,0x11022c00,0x4000000,0x1600002,0x11022c00,0x4000000,
-0x1010000f,0x11022c00,0x7c00120,0x120405,0x11022c0e,0x7c00100,0x250401,0x11022c19,0x7c00100,0x150401,0x11022d00,0x4000000,0x100006,0x11022d00,0x4000000,0x200006,
-0x11022d19,0x7c00100,0x120402,0x11022d19,0x7c00100,0x150402,0x11022e00,0x24000000,0x200000,0x11022e00,0x24000020,0x100000,0x11022e00,0x24000020,0x10100000,0x11022f00,
-0x24000020,0x100000,0x11022f00,0x24000020,0x100001,0x11022f00,0x24000020,0x100002,0x11023000,0x24000000,0x100000,0x11023300,0x4000000,0x100002,0x11023300,0x4000000,
-0x100003,0x11023300,0x4000100,0x120403,0x11023300,0x4000100,0x150403,0x11023300,0x4000100,0x10150403,0x11023400,0x24000000,0x100000,0x11023500,0x24000000,0x100000,
-0x11023600,0x24000000,0x100000,0x11023600,0x24000020,0x100000,0x11023600,0x24000020,0x10100000,0x11023700,0x24000000,0x100000,0x11023700,0x24000000,0xe00000,0x11023700,
-0x24000000,0x10100000,0x11023700,0x24000000,0x10e00000,0x11023700,0x24000020,0x100000,0x11023700,0x24000020,0x10100000,0x11023800,0x4000000,0x100000,0x11023800,0x24000000,
-0x200000,0x11024e67,0,0,0x11025600,0x4000000,0x100000,0x11042a00,0x4000000,0x1600000,0x11045700,0x4000000,0x20000a,0x11045700,0x4000020,0x20000a,
-0x11045712,0x7c00100,0x23040a,0x11045712,0x7c80100,0x23040a,0x11045716,0x7c00100,0x230c0a,0x11045716,0x7c00100,0x2530c0a,0x11063d00,0x4000001,0x440011,0x11065700,
-0x4000000,0x810011,0x11065700,0x4000000,0xe00011,0x11065700,0x4000000,0x1410011,0x11065700,0x4000000,0x1500011,0x11065700,0x4000000,0x1600011,0x11065700,0x4000006,
-0xe70011,0x11065700,0x4000008,0xe00011,0x11065700,0x4000008,0xe02c11,0x11065700,0x4000010,0x871411,0x11065700,0x4000010,0x1201411,0x11065700,0x4000010,0x1271011,
-0x11065700,0x4000020,0xe00011,0x11065700,0x4000400,0xe00011,0x11065700,0x4000420,0xe00011,0x11065700,0x6800000,0xe01c11,0x11065700,0x6800040,0xe00011,0x11065700,
-0xc000010,0x80ac11,0x11065700,0xc000010,0xb48011,0x11065719,0x7c00100,0xe20411,0x11065719,0x7c00100,0xe50411,0x11065719,0x7c00140,0xe20411,0x11065719,0x7c00140,
-0xe50411,0x11080100,0x6800000,0x201c00,0x11080100,0x68000c0,0x11329800,0x11080100,0x24000000,0x200000,0x11080100,0x24000000,0x810000,0x11080100,0x24000000,0x1410000,
-0x11080100,0x24000000,0x1500000,0x11080100,0x24000000,0x1600000,0x11080100,0x24000000,0x1b00000,0x11080100,0x24000000,0x2410000,0x11080100,0x24000000,0x10200000,0x11080100,
-0x24000006,0xd70000,0x11080100,0x24000008,0x1713c00,0x11080100,0x24000008,0x1714000,0x11080100,0x24000010,0x1001400,0x11080100,0x24000010,0x1071000,0x11080100,0x24000010,
-0x1071400,0x11080100,0x24000020,0x200000,0x11080100,0x24000020,0x400000,0x11080100,0x24000020,0x1600000,0x11080100,0x24000400,0x200000,0x11080100,0x24000420,0x200000,
-0x11080100,0x2c000010,0xb48000,0x11080100,0x2c000010,0x100ac00,0x11080100,0x44000001,0x1a40000,0x11080119,0x7c00100,0x220400,0x11080119,0x7c00100,0x250400,0x11080119,
-0x7c001c0,0x220400,0x11080119,0x7c001c0,0x250400,0x11080200,0x4000400,0x200002,0x11080200,0x24000000,0x200000,0x11080200,0x24000000,0x1500000,0x11080200,0x24000000,
-0x1600000,0x11080200,0x24000020,0x200000,0x110a1e12,0x7c00100,0x2130480,0x110a1e12,0x7c80100,0x2130480,0x110a3000,0x24100000,0x810001,0x110a3000,0x24100000,0x1410001,
-0x110a3d00,0x4000000,0xe00000,0x110a3d00,0x4000000,0xe00002,0x110a3d00,0x24000000,0xe00000,0x110a3d11,0x7c00300,0xe30000,0x110a3d11,0x7c00900,0x1230400,0x110a3d12,
-0x2802400,0x962460,0x110a3e14,0x7c00100,0xe30000,0x110a3e14,0x7c00100,0xe30001,0x110a3e14,0x7c00100,0x2530000,0x110a3e14,0x7c00900,0x1230000,0x110a3e14,0x7c00900,
-0x1230001,0x110a3f16,0x7c00100,0xe30c00,0x110a3f16,0x7c00100,0xe30c01,0x110a3f16,0x7c00100,0x2530c00,0x110a3f16,0x7c00900,0x1230c00,0x110a3f16,0x7c00900,0x1230c01,
-0x110a4005,0x7c00100,0xe30400,0x110a4112,0x7c00100,0xe30402,0x110a4112,0x7c80100,0xe30402,0x110a4400,0x4000000,0xe00000,0x110a4412,0x4000000,0xe00002,0x110a4412,
-0x4000000,0xe00003,0x110a4416,0x4000000,0xe00c03,0x110a4500,0x4000000,0xe0000d,0x110a4516,0x4000000,0xe00c0d,0x110a4711,0x7c40300,0xe30000,0x110a4f11,0x7c00300,
-0xe30001,0x110a4f11,0x7c40300,0xe30000,0x110a5300,0x4000000,0x810010,0x110a5300,0x4000000,0xe00002,0x110a5300,0x4000000,0xe00010,0x110a5300,0x4000000,0x1410010,
-0x110a5300,0x4000002,0xe70010,0x110a5300,0x4000008,0x810010,0x110a5300,0x4000008,0x1410010,0x110a5300,0x6800000,0xe01c02,0x110a5300,0x6800000,0xe01c10,0x110a5400,
-0x4000000,0x81000c,0x110a5400,0x4000000,0xe0000c,0x110a5400,0x4000000,0x141000c,0x110a5400,0x4000000,0x150000c,0x110a5400,0x4000000,0x160000c,0x110a5400,0x4000002,
-0xe7000c,0x110a5400,0x4000010,0x87140c,0x110a5400,0x4000010,0xe7000c,0x110a5400,0x4000010,0x120140c,0x110a5400,0x4000010,0x127100c,0x110a5400,0x4000020,0xe0000c,
-0x110a5400,0x4000026,0xe7000c,0x110a5400,0xc000010,0x80ac0c,0x110a5400,0xc000010,0xb4800c,0x11400a0c,0xc000010,0x1049400,0x11400c0e,0x4000010,0xb00000,0x11400c0e,
-0x4000010,0x1071400,0x11400c0e,0xc000010,0xb48000,0x11400c11,0x7c00900,0x230400,0x11400f33,0xc000010,0x448000,0x11400f43,0xc000010,0x448000,0x11403d8a,0x4000000,
-0xe00000,0x11445784,0x4000004,0x120000a,0x11445784,0x4000008,0x81000a,0x11445784,0x4000008,0x141000a,0x11445784,0x4000010,0x87000a,0x11445784,0xc000010,0x84800a,
-0x1144578d,0x3802500,0x126246a,0x1144578d,0x7c00d00,0x2530c0a,0x114a3d84,0x24000000,0x810000,0x114a3d84,0x24000000,0x1410000,0x114a3d84,0x24000008,0x810000,0x114a3d84,
-0x24000008,0x1410000,0x114a3d84,0x24000010,0x870000,0x114a3d84,0x2c000010,0x848000,0x114a3d8a,0x4000000,0xe00000,0x114a3d8a,0x24000000,0xe00000,0x114a3d8a,0x24000002,
-0x1200000,0x114a3d8a,0x24000002,0x10e00000,0x114a3d8a,0x24000008,0x810000,0x114a3d8a,0x24000008,0x1410000,0x114a3d8d,0x7c00900,0x930c00,0x114a3d8d,0x7c00900,0xe30c00,
-0x114a3d8f,0x7c00300,0xe30000,0x114a3e8d,0x7000400,0x1200c02,0x114a3f84,0x4000004,0x1200000,0x114a3f8d,0x7c00d00,0x2530c00,0x114a428f,0x4000000,0xe00000,0x114a428f,
-0x4000000,0xe0000f,0x114a448a,0x4000000,0xe00002,0x114a448a,0x4000000,0xe00003,0x114a448a,0x4000000,0x10e00003,0x114a458a,0x4000000,0xe00002,0x114a458a,0x4000000,
-0xe0000d,0x11800906,0x2802400,0x962460,0x11800c16,0x2802100,0x962460,0x11800c16,0x2802500,0x962460,0x11800f1c,0x2802400,0x962460,0x11800f28,0x2802400,0x962460,
-0x11820700,0x2802400,0x962460,0x11820700,0x2802500,0x962460,0x118a3d92,0x2802400,0x962460,0x118a3e8d,0x2802400,0x962460,0x11c00904,0x2802400,0x962460,0x11c00c1a,
-0x6800000,0x1329800,0x11c00f57,0x6800000,0x1329800,0x11c0105c,0x6800000,0x1329800,0x11c01160,0x6800000,0x1329800,0x11c01264,0x6800000,0x1329800,0x11c01468,0x4000000,
-0x200000,0x11c01468,0x6800000,0x1329800,0x11c01468,0x7c00100,0x230400,0x11c0511a,0x7c00100,0x230408,0x20000067,0x1000,0,0x20000b13,0x2802400,0x962460,
-0x20000b13,0x2802500,0x962460,0x20001b27,0x2802100,0x962460,0x20001b27,0x2802100,0x962461,0x20001b27,0x2802400,0x962460,0x20001b27,0x2806400,0x962460,0x20001b27,
-0x2902100,0x962462,0x20001b27,0x4000000,0x200000,0x20001b27,0x4000000,0x400000,0x20001b27,0x4000000,0x500000,0x20001b27,0x4000000,0x810000,0x20001b27,0x4000000,
-0xb00000,0x20001b27,0x4000000,0xc0000b,0x20001b27,0x4000000,0x1410000,0x20001b27,0x4000010,0xb00000,0x20001b27,0x4000010,0xc00000,0x20001b27,0x6800000,0x1329800,
-0x20001b27,0x6800100,0x462540,0x20001b27,0x6800400,0x962540,0x20001b27,0x7c00100,0x230400,0x20001b27,0x7c00100,0x230401,0x20002619,0x7c00100,0x220401,0x20002a00,
-0x4000000,0x1600000,0x20004b67,0,0x1900020,0x20004c67,0,0x1900020,0x20004d67,0,0x1900020,0x20006d67,0x1000,0,0x20006e67,0x1000,
-0,0x20026d67,0,0,0x20026e67,0,0,0x200a4a12,0x7c00100,0x1f304c1,0x200a4a12,0x7c00100,0x20304e1,0x21005600,0x4000000,0x700000,
-0x21022a00,0x4000000,0x1600000,0x30000419,0x7c00100,0x220400,0x30000419,0x7c00100,0x220401,0x30000419,0x7c00100,0x250400,0x30000419,0x7c00100,0x250401,0x30000519,
-0x7c00100,0x220400,0x30000600,0x4000400,0x200000,0x30000600,0x7c00500,0x230400,0x30000605,0x4000400,0x200000,0x3000080e,0x7c00100,0x220400,0x30000908,0x2000,
-0x962460,0x30000908,0x7c00100,0x220400,0x30000908,0x7c00100,0x220401,0x30000908,0x7c00100,0x250400,0x30000908,0x7c00100,0x250401,0x30000a03,0x4000006,0x400000,
-0x30000c02,0x4000000,0x200000,0x30000c02,0x7c00100,0x230400,0x30000d22,0,0x218820,0x30000d22,0x2802100,0x962460,0x30000d22,0x2802400,0x962460,0x30000d22,
-0x2802500,0x962460,0x30000d22,0x4000000,0x200000,0x30000d22,0x4000010,0x200000,0x30000d22,0x7c00100,0x230400,0x30000d22,0xc000010,0x248000,0x30000e25,0x2802500,
-0x962460,0x30000e25,0x7c00100,0x230400,0x30001821,0x2802100,0x962460,0x30001821,0x2806400,0x962460,0x30001821,0x4000000,0x200000,0x30001821,0x6800100,0x962540,
-0x30001821,0x6800100,0x962541,0x30001821,0x7c00100,0x230400,0x30001b27,0x2802100,0x962460,0x30001b27,0x2802400,0x962460,0x30001b27,0x4000000,0x200000,0x30001b27,
-0x4000000,0x400000,0x30001b27,0x7c00100,0x230400,0x30001c1c,0x2802100,0x1862460,0x30001c1c,0x2802400,0x1862460,0x30001c1c,0x2806400,0x1862460,0x30001c1c,0x4000000,
-0x200000,0x30001c1c,0x6800100,0x1862400,0x30001c1c,0x6800100,0x1862540,0x30001c1c,0x7c00100,0x1830000,0x30001c1c,0x7c00100,0x1830001,0x30001c1c,0xc000010,0x448000,
-0x30001f0b,0x4000000,0x200000,0x30001f0b,0x4000010,0x200000,0x30001f0b,0x4000010,0x400000,0x30001f0b,0x6800000,0x200000,0x30001f0b,0x7c00100,0x230400,0x30001f0b,
-0xc000010,0x248000,0x30002006,0x7c00100,0x250400,0x30002128,0x4000010,0x200000,0x30002128,0x7c00100,0x230400,0x30002128,0xc000010,0x248000,0x3000221d,0x4000000,
-0x810000,0x3000221d,0x4000000,0x1410000,0x3000221d,0x4000001,0x440000,0x3000221d,0x7c00100,0x230400,0x30002300,0x4000010,0x400000,0x30002320,0x7c00100,0x230400,
-0x30002417,0x2802100,0x1862460,0x30002417,0x2802400,0x1862460,0x30002417,0x2806400,0x1862460,0x30002417,0x2882000,0x1862460,0x30002417,0x4000000,0x200000,0x30002417,
-0x4000000,0x400000,0x30002417,0x4000000,0x1600000,0x30002417,0x4000010,0x400000,0x30002417,0x4000010,0x1200000,0x30002417,0x6800000,0x1329800,0x30002417,0x6800100,
-0x1862540,0x30002417,0x7c00100,0x1830000,0x30002417,0x7d00100,0x1830000,0x3000251b,0x80000,0xc18820,0x3000251b,0x2802100,0x962460,0x3000251b,0x4000000,0x200000,
-0x3000251b,0x4000006,0x500000,0x3000251b,0x4000010,0x400000,0x3000251b,0x4000010,0xb70000,0x3000251b,0x4000800,0x200000,0x3000251b,0x6800000,0x1329800,0x3000251b,
-0x7c00100,0x230400,0x3000251b,0x7c00900,0x230400,0x3000251b,0xc000010,0xb48000,0x3000251b,0x12882000,0x962460,0x30002800,0x4000001,0xc4000b,0x30002800,0x24000000,
-0x200000,0x30002800,0x2c000010,0x1248002,0x30002800,0x2c000010,0x11248002,0x30002a00,0x4000000,0x1600000,0x30002b01,0x2000,0x962460,0x30002c00,0x4000000,0x200000,
-0x30002c00,0x7c00100,0x10220405,0x30002d19,0x7c00100,0x250400,0x30002e00,0x24000000,0x200000,0x30003000,0x24000000,0x200000,0x30003100,0x24000000,0x200000,0x30003600,
-0x24000000,0x200000,0x30003700,0x24000000,0x200000,0x3000392e,0x24000000,0x200000,0x30005013,0x7c00100,0x2633801,0x30005600,0,0x918820,0x30020600,0x4000400,
-0x500000,0x30020701,0x2802400,0x962460,0x30020701,0x2802400,0xc62460,0x300a3a11,0x4020000,0xe00000,0x300a3a11,0x4020000,0xe00002,0x300a3b11,0x4020000,0xe00002,
-0x300a3c00,0x4008000,0xe00000,0x300a3c00,0x4010000,0xe00000,0x300a3d11,0x7c00300,0xe30002,0x300a4305,0x7c00100,0xe30400,0x300a4611,0x7c40300,0xe30000,0x300a4829,
-0x7c00100,0xe30400,0x300a4829,0x7c00900,0x1230400,0x300a4929,0x4000000,0xe00000,0x30402573,0x4000010,0x400000,0x30402573,0x4000010,0xb70000,0x30402573,0xc000010,
-0xb48000,0x304a3d8a,0x4000000,0xe00000,0x30800c16,0x2802100,0x962460,0x30c01c6d,0x6800000,0x1329800,0x3100080e,0x7c00120,0x220402,0x3100080e,0x7c00120,0x250402,
-0x31005167,0x1000,0,0x3100581e,0x4000000,0x200000,0x3100581e,0x7c00100,0x230400,0x3100590d,0x7c00100,0x230400,0x31005a09,0x7c00100,0x220400,0x31005a09,
-0x7c00100,0x250400,0x31005b00,0x4000000,0x200000,0x31005c00,0x80000,0x918820,0x31005c00,0x2802000,0x962460,0x31005c00,0x2802400,0x962460,0x31005c00,0x4000000,
-0x200000,0x31005c00,0x4000000,0x200001,0x31005c00,0x6800000,0x962540,0x31005c00,0x6800400,0x962540,0x31005c01,0x2802400,0x962460,0x31005d00,0x4000020,0x200005,
-0x31005d00,0x6800020,0x1329805,0x31005d00,0x7c00120,0x220405,0x31005d00,0x7c00120,0x250405,0x31006000,0x80000,0x918820,0x31006000,0x180000,0x918820,0x310a5e11,
-0x7c40300,0xe30000,0x310a5f11,0x7c00300,0xe30001,0x32000419,0x7c00100,0x250400,0x3200080e,0x4000020,0x200000,0x3200080e,0x7c00100,0x220400,0x3200080e,0x7c00100,
-0x250400,0x32000908,0x7c00100,0x220400,0x32000908,0x7c00100,0x250400,0x32000c02,0x7c00100,0x230400,0x32000e25,0x7c00100,0x230400,0x32001d0c,0x7c00100,0x230400,
-0x32002800,0x80000,0x1e18820,0x32002800,0x80020,0x218820,0x32002800,0x4000001,0x440002,0x32002800,0x24000000,0x200000,0x32002800,0x24000000,0x200002,0x32002800,
-0x24000020,0x200000,0x32002800,0x2c000010,0x1248002,0x32002919,0x7c00100,0x22040f,0x32002a00,0x4000000,0x1600000,0x32002b01,0x2000,0x962460,0x32002b01,0x2802000,
-0x962460,0x32002b01,0x2802020,0x962460,0x32002c00,0x4000000,0x200000,0x32002c00,0x4000020,0x200000,0x32002c00,0x4000020,0x200005,0x32002c00,0x7c00120,0x220405,
-0x32002c00,0x7c00120,0x250405,0x32002e00,0x24000020,0x200000,0x32002f00,0x24000020,0x200000,0x32003000,0x24000000,0x200000,0x32003000,0x24000020,0x200000,0x32003500,
-0x24000000,0x200000,0x32003600,0x24000020,0x200000,0x32003600,0x24000020,0x10200000,0x32003600,0x24000020,0x30200000,0x32003700,0x24000000,0x100000,0x32003700,0x24000000,
-0x200000,0x32003700,0x24000000,0x10200000,0x32003800,0x24000000,0x810000,0x32003800,0x24000000,0x1410000,0x32005102,0x4000000,0x1500008,0x32005502,0x7c00100,0x230400,
-0x32006108,0x7c00100,0x220400,0x32006108,0x7c00100,0x250400,0x3200622a,0x2802100,0x962460,0x3200622a,0x2806000,0x962460,0x3200622a,0x7c00100,0x230400,0x3200632b,
-0x2802100,0x962460,0x3200632b,0x2806000,0x962460,0x3200632b,0x7c00100,0x230400,0x3200642c,0x2802100,0x962460,0x3200642c,0x7c00100,0x230400,0x3200652d,0x2802100,
-0x962460,0x3200652d,0x7c00100,0x230400,0x32006600,0x24000020,0x200000,0x32006700,0x24000020,0x200000,0x32006800,0x24000020,0x200000,0x32006800,0x24000020,0x10200000,
-0x32006900,0x24000020,0x200000,0x32006900,0x24000020,0x810000,0x32006900,0x24000020,0x1410000,0x32006a00,0x24000020,0x200000,0x32006a00,0x24000020,0x200001,0x32006a00,
-0x24000020,0x200002,0x32020701,0x2882000,0xc62460,0x32023300,0x4000000,0x100000,0x32026c01,0x12882000,0x962460,0x32065700,0x4000000,0x810011,0x32065700,0x4000000,
-0x1410011,0x32086600,0x24000020,0x810000,0x32086600,0x24000020,0x1410000,0x32086900,0x24000020,0x810000,0x32086900,0x24000020,0x1410000,0x320a3d11,0x7c00100,0x1230400,
+static const uint32_t propsVectors[6999]={
+0x67,0,0,0x67,0,0x4e00000,0x67,0x80000,0x20,0x867,0,0,0xa67,0,0,0xb67,
+0,0,0xc67,0,0,0xd67,0,0,0xe67,0,0,0x1067,0,0,0x1167,0,
+0,0x1267,0,0,0x1367,0,0,0x1467,0,0,0x1567,0,0,0x1667,0,0,
+0x1767,0,0,0x1867,0,0,0x1967,0,0,0x1a67,0,0,0x1b67,0,0,0x1d67,
+0,0,0x1f67,0,0,0x2067,0,0,0x2267,0,0,0x2367,0,0,0x2467,0,
+0,0x2567,0,0,0x2767,0,0,0x2867,0x80000,0x20,0x2967,0,0,0x2a67,0,0x1600000,
+0x2b67,0,0,0x2d67,0,0,0x3167,0x20000000,0,0x3267,0x20000000,0,0x3a67,0,0,0x3b67,
+0,0,0x3c67,0,0,0x3e67,0,0,0x4067,0,0,0x4167,0,0,0x4467,0,
+0,0x4867,0,0,0x4967,0,0,0x4a67,0,0,0x5067,0,0,0x5167,0,0,
+0x5467,0,0,0x5567,0,0,0x5667,0x80000,0x20,0x5767,0,0,0x5867,0,0,0x5967,
+0,0,0x5b67,0,0,0x5c67,0,0,0x5d67,0,0,0x6067,0x80000,0x20,0x6267,0,
+0,0x6367,0,0,0x6467,0,0,0x6567,0,0,0x6f67,0,0,0x7067,0,0,
+0x7367,0x20000000,0,0x7567,0,0,0x7667,0,0,0x7767,0,0,0x7867,0,0,0x7a67,
+0,0,0x7b67,0,0,0x7c67,0,0,0x7e67,0,0,0x7f67,0,0,0x8167,0,
+0,0x8267,0,0,0x8367,0,0,0x8467,0,0,0x8567,0,0,0x8667,0,0,
+0x8767,0,0,0x8867,0,0,0x8967,0,0,0x8b67,0,0,0x8c67,0,0,0x8e67,
+0x20000000,0,0x8f67,0,0,0x9067,0,0,0x9167,0,0,0x9267,0,0,0x9367,0,
+0,0x9567,0,0,0x9667,0,0,0x9767,0,0,0x9867,0,0,0x9967,0,0,
+0x9a67,0,0,0x9c67,0,0,0x9f67,0,0,0xa167,0,0,0xa367,0,0,0xa467,
+0,0,0xa567,0,0,0xa667,0,0,0xa767,0,0,0xa867,0,0,0xa967,0,
+0,0xaa67,0,0x4e00000,0xab67,0,0x4e00000,0xac67,0,0,0xad67,0,0,0xae67,0,0,
+0xaf67,0,0,0xb167,0,0,0xb267,0,0,0xb467,0,0,0xb567,0,0,0xb767,
+0,0,0xb867,0,0,0xb967,0,0,0xba67,0,0,0xbc67,0,0,0xbd67,0,
+0,0xbe67,0,0,0xbf67,0,0,0xc067,0,0,0xc167,0,0,0xc267,0,0,
+0xc367,0,0x4e00000,0xc467,0,0x4e00000,0xc667,0,0,0xc767,0,0,0xc867,0,0,0xc967,
+0,0,0xca67,0,0,0xcc67,0,0x4e00000,0xcf67,0,0x4e00000,0xd067,0,0x4e00000,0xd267,0,
+0,0xd367,0,0,0xd467,0,0,0xd567,0,0,0xd667,0,0,0xd867,0,0,
+0xda67,0,0,0xdb67,0,0,0xdc67,0,0,0xdd67,0,0,0xde67,0,0,0xdf67,
+0,0,0xe067,0,0,0xe167,0,0,0xe267,0,0,0xe367,0,0x4e00000,0xe467,0,
+0,0xe567,0,0,0xe667,0,0,0xe767,0,0,0xe867,0,0,0xe967,0,0,
+0xea67,0,0,0xeb67,0,0,0xec67,0,0,0xed67,0,0,0xee67,0,0,0xef67,
+0,0,0xf167,0,0,0xf367,0,0,0xf567,0,0,0xf667,0,0,0xf767,0,
+0,0xf867,0,0,0xf967,0,0,0xfa67,0,0x4e00000,0xfb67,0,0,0xfc67,0,0,
+0xfd67,0,0,0xfe67,0,0,0x10167,0,0,0x10267,0,0,0x10367,0,0,0x10467,
+0,0,0x10567,0,0x4e00000,0x10667,0,0,0x10767,0,0,0x10867,0,0,0x10967,0,
+0,0x10a67,0,0,0x10b67,0,0,0x10c67,0,0,0x10d67,0,0,0x10e67,0,0,
+0x10f67,0,0,0x11067,0,0,0x11367,0,0,0x11467,0,0,0x11567,0,0,0x11667,
+0,0,0x11767,0,0,0x11867,0,0,0x11967,0,0x4e00000,0x11a67,0,0,0x11b67,0,
+0,0x11c67,0,0,0x11d67,0,0,0x11e67,0,0,0x11f67,0,0,0x12067,0,0,
+0x12167,0,0,0x12267,0,0,0x12367,0,0,0x12467,0,0,0x12567,0,0,0x12667,
+0,0,0x12767,0,0,0x12867,0,0,0x12967,0,0,0x12a67,0,0x4e00000,0x12b67,0,
+0,0x12c67,0,0,0x12d67,0,0,0x12f67,0,0,0x13067,0,0,0x13167,0,0,
+0x13267,0,0,0x13367,0,0,0x13467,0,0,0xa0067,0,0xe00000,0xa4767,0,0xe00000,0xa4f67,
+0,0xe00000,0xa5e67,0,0xe00000,0xa5f67,0,0xe00000,0xac567,0,0xe00000,0xad167,0,0xe00000,0xb0067,0,
+0xe00000,0xb1267,0,0xe00000,0xb2e67,0,0xe00000,0x11000100,0,0x900020,0x11000100,0x40000001,0x440020,0x11000100,0x40000001,0x643020,
+0x11000100,0x40000001,0xa5a040,0x11000100,0x40000001,0x116a8a0,0x11000200,0,0x900020,0x11000200,0x4000001,0xc4000b,0x11000200,0x7c00100,0x220402,0x11000200,
+0x24000000,0x14200000,0x11000200,0x24000008,0x1710000,0x11000200,0x40000001,0x1d3b020,0x11000219,0x7c00100,0x220401,0x11000219,0x7c00100,0x250401,0x11000319,0x7c00100,
+0x220401,0x11000319,0x7c00100,0x220402,0x11000319,0x7c00100,0x250400,0x11000319,0x7c00100,0x250401,0x11000419,0x7c00100,0x220400,0x11000419,0x7c00100,0x220401,
+0x11000419,0x7c00100,0x220402,0x11000419,0x7c00100,0x230400,0x11000419,0x7c00100,0x250400,0x11000419,0x7c00100,0x250401,0x11000419,0x7c00100,0x250402,0x11000519,
+0x7c00100,0x220400,0x11000519,0x7c00100,0x230400,0x11000600,0x4000400,0x200002,0x11000600,0x4000400,0x200400,0x11000600,0x7c00500,0x220400,0x11000600,0x7c00500,
+0x230400,0x11000600,0x7c00500,0x530400,0x11000600,0x7c00d00,0x230400,0x11000619,0x7c00500,0x22040f,0x11000800,0x4000010,0x1001401,0x11000800,0x4000400,0x200001,
+0x11000800,0x6800010,0x201001,0x11000800,0x7c00500,0x230401,0x11000807,0x7c00100,0x220400,0x11000807,0x7c00100,0x250400,0x1100080e,0x4000400,0x200000,0x1100080e,
+0x4000400,0x200002,0x1100080e,0x7000500,0x220402,0x1100080e,0x7c00100,0x220400,0x1100080e,0x7c00100,0x220401,0x1100080e,0x7c00100,0x220402,0x1100080e,0x7c00100,
+0x250400,0x1100080e,0x7c00100,0x250401,0x1100080e,0x7c00120,0x220402,0x1100080e,0x7c00120,0x250402,0x11000908,0x4000000,0x200000,0x11000908,0x7c00100,0x220400,
+0x11000908,0x7c00100,0x220401,0x11000908,0x7c00100,0x250400,0x11000908,0x7c00100,0x250401,0x11000a03,0x4000000,0x200400,0x11000a03,0x4000000,0x201000,0x11000a03,
+0x4000000,0x270000,0x11000a03,0x7c00100,0x220400,0x11000a03,0x7c00100,0x220402,0x11000a03,0x7c00100,0x250400,0x11000a03,0x7c00500,0x230400,0x11000a03,0xc000010,
+0x1049400,0x11000b13,0x2802500,0x962460,0x11000b13,0x4000000,0x200000,0x11000b13,0x4000000,0x201000,0x11000b13,0x4000000,0x230400,0x11000b13,0x4000002,0x400000,
+0x11000b13,0x4000010,0x200000,0x11000b13,0x7c00100,0x2633800,0x11000c00,0x80000000,0x218960,0x11000c02,0x2802100,0x962460,0x11000c02,0x2802400,0x962460,0x11000c02,
+0x4000000,0x200000,0x11000c02,0x4000000,0x1329400,0x11000c02,0x4000000,0x1329800,0x11000c02,0x4000000,0x1500000,0x11000c02,0x6800000,0x1329800,0x11000c02,0x7c00100,
+0x230400,0x11000c02,0x7c00100,0x230401,0x11000c02,0x7c00100,0x230402,0x11000c02,0x7c00500,0x230400,0x11000c02,0x7d00100,0x230400,0x11000f01,0x2802400,0x962460,
+0x11000f0a,0x2802100,0x962460,0x11000f0a,0x2802400,0x962460,0x11000f0a,0x2806400,0x962460,0x11000f0a,0x4000000,0x200000,0x11000f0a,0x6800100,0x962540,0x11000f0a,
+0x7c00100,0x230400,0x11000f0a,0x7c00100,0x230401,0x11001004,0x2802100,0x962460,0x11001004,0x2802400,0x962460,0x11001004,0x2806400,0x962460,0x11001004,0x4000000,
+0x200000,0x11001004,0x4000000,0x1500000,0x11001004,0x6800100,0x962540,0x11001004,0x6800100,0x962541,0x11001004,0x7c00100,0x230400,0x11001004,0x7c00100,0x230401,
+0x11001110,0x2802100,0x962460,0x11001110,0x2802400,0x962460,0x11001110,0x2806400,0x962460,0x11001110,0x6800100,0x962540,0x11001110,0x7c00100,0x230400,0x11001110,
+0x7c00100,0x230401,0x1100120f,0x2802100,0x962460,0x1100120f,0x2802400,0x962460,0x1100120f,0x2806400,0x962460,0x1100120f,0x6800100,0x962540,0x1100120f,0x7c00100,
+0x230400,0x1100131f,0x2802100,0x962460,0x1100131f,0x2802400,0x962460,0x1100131f,0x2806400,0x962460,0x1100131f,0x4000000,0x200000,0x1100131f,0x6800000,0x1329800,
+0x1100131f,0x6800100,0x962540,0x1100131f,0x6800100,0x962541,0x1100131f,0x7c00100,0x230400,0x1100131f,0x7c00100,0x230401,0x11001423,0x2802100,0x962460,0x11001423,
+0x2806400,0x962460,0x11001423,0x6800100,0x962540,0x11001423,0x6800100,0x962541,0x11001423,0x7c00100,0x230400,0x11001423,0x7c00100,0x230401,0x11001524,0x2802100,
+0x962460,0x11001524,0x2802100,0x962461,0x11001524,0x2806400,0x962460,0x11001524,0x6800000,0x1329800,0x11001524,0x6800100,0x962540,0x11001524,0x7c00100,0x230400,
+0x11001615,0x2802100,0x962460,0x11001615,0x2806400,0x962460,0x11001615,0x6800100,0x962540,0x11001615,0x6800100,0x962541,0x11001615,0x7c00100,0x230400,0x1100171a,
+0x2802100,0x962460,0x1100171a,0x2806400,0x962460,0x1100171a,0x6800000,0x1329800,0x1100171a,0x6800100,0x962540,0x1100171a,0x6800100,0x962541,0x1100171a,0x7c00100,
+0x230400,0x11001900,0x4000000,0x1600000,0x11001926,0x2802100,0x1862460,0x11001926,0x2802400,0x1862460,0x11001926,0x2806100,0x1862460,0x11001926,0x4000000,0x200000,
+0x11001926,0x4000010,0x400000,0x11001926,0x6800000,0x1329800,0x11001926,0x7800100,0x1830142,0x11001926,0x7c00100,0x1830000,0x11001926,0x7c00900,0x1830000,0x11001926,
+0x7e00100,0x1830000,0x11001a18,0x2802100,0x1862460,0x11001a18,0x2802400,0x1862460,0x11001a18,0x6800000,0x1329800,0x11001a18,0x7800100,0x1830142,0x11001a18,0x7c00100,
+0x1830000,0x11001a18,0x7c00100,0x1830002,0x11001a18,0x7c00900,0x1830000,0x11001a18,0x7e00100,0x1830000,0x11001d0c,0x7c00100,0x230400,0x11001d0c,0x7c00100,0x250400,
+0x11001e12,0x7c00100,0x2230500,0x11001e12,0x7c00100,0x2330520,0x11001e12,0x7c80100,0x2330520,0x11002619,0x7c00100,0x220401,0x11002619,0x7c00100,0x220402,0x11002619,
+0x7c00100,0x250401,0x1100270e,0x4000400,0x200001,0x1100270e,0x4000400,0x200002,0x1100270e,0x4000400,0x500001,0x1100270e,0x7c00100,0x220401,0x1100270e,0x7c00100,
+0x250401,0x11002800,0x80000,0x918820,0x11002800,0x80000,0x1c18020,0x11002800,0x180000,0x918820,0x11002800,0x4000001,0x445801,0x11002800,0x4000001,0x445802,
+0x11002800,0x4000001,0xc4000b,0x11002800,0x6800000,0x201c00,0x11002800,0x6800020,0x201c00,0x11002800,0x24000000,0x200000,0x11002800,0x24000000,0x200002,0x11002800,
+0x24000000,0x810000,0x11002800,0x24000000,0x1410000,0x11002800,0x24000000,0x1500000,0x11002800,0x24000000,0x1500002,0x11002800,0x24000002,0x400000,0x11002800,0x24000006,
+0xc0000b,0x11002800,0x24000008,0x1410000,0x11002800,0x24000008,0x1710000,0x11002800,0x24000020,0x1001400,0x11002800,0x24000020,0x1500002,0x11002800,0x2c000010,0x1248000,
+0x11002800,0x2c000010,0x15248002,0x11002800,0x40000001,0x63b020,0x11002800,0x40080000,0x918820,0x11002801,0x80000,0xaa65620,0x11002801,0x82000,0x962460,0x11002900,
+0x4000000,0x20000e,0x11002900,0x4000000,0x20000f,0x11002900,0x4000020,0x20000e,0x11002900,0x4000020,0x20000f,0x11002900,0x4000020,0x81000e,0x11002900,0x4000020,
+0x81000f,0x11002900,0x4000020,0x141000e,0x11002900,0x4000020,0x141000f,0x11002900,0x4000022,0x20000e,0x11002900,0x4000022,0x20000f,0x11002a00,0x4000000,0x1500000,
+0x11002a00,0x4000000,0x1600000,0x11002a00,0x4000000,0x1600002,0x11002b01,0x2000,0x962460,0x11002b01,0x2802020,0x962460,0x11002c00,0x4000000,0x200000,0x11002c00,
+0x4000000,0x200002,0x11002c00,0x4000000,0x20000f,0x11002c00,0x4000020,0x200000,0x11002c00,0x7c00000,0x200000,0x11002c00,0x7c00020,0x200000,0x11002c00,0x7c00120,
+0x220405,0x11002c00,0x7c00120,0x230402,0x11002c00,0x7c00120,0x250402,0x11002c00,0x7c00120,0x250405,0x11002c19,0x7c00100,0x250400,0x11002c19,0x7c00100,0x250401,
+0x11002d00,0x4000000,0x100006,0x11002d00,0x4000000,0x200006,0x11002d19,0x7c00100,0x220402,0x11002d19,0x7c00100,0x230400,0x11002d19,0x7c00100,0x250402,0x11002e00,
+0x24000000,0x200000,0x11002e00,0x24000020,0x200000,0x11002e00,0x24000020,0x200001,0x11002e00,0x24000020,0x14200000,0x11002f00,0x24000020,0x200000,0x11002f00,0x24000020,
+0x200001,0x11002f00,0x24000020,0x200002,0x11002f00,0x24000020,0xf00000,0x11002f00,0x24000020,0x1600000,0x11002f00,0x24000022,0x1600000,0x11003000,0x24000000,0x200000,
+0x11003000,0x24000000,0x14200000,0x11003000,0x24000020,0x200000,0x11003000,0x24000020,0x810000,0x11003000,0x24000020,0x1410000,0x11003100,0x24000000,0x200000,0x11003200,
+0x24000000,0x200000,0x11003300,0x4000000,0x100003,0x11003400,0x24000000,0x100000,0x11003400,0x24000000,0x200000,0x11003500,0x24000000,0x200000,0x11003600,0x24000000,
+0x200000,0x11003600,0x24000000,0x14200000,0x11003600,0x24000020,0x200000,0x11003700,0x24000000,0x200000,0x11003700,0x24000000,0x4200000,0x11003700,0x24000000,0x4e00000,
+0x11003700,0x24000000,0x14200000,0x11003700,0x24000000,0x14e00000,0x11003700,0x24000000,0x96800000,0x11003700,0x24000020,0x4200000,0x11003800,0x4000000,0x100000,0x11003800,
+0x24000000,0x200000,0x11003800,0x24000000,0xb00000,0x11003800,0x24000000,0x1710000,0x11003800,0x24000000,0x4200000,0x11003800,0x24000000,0x4e00000,0x11003800,0x24000000,
+0x14200000,0x11003800,0x24000000,0x14b00000,0x11003800,0x24000000,0x14e00000,0x11003800,0x24000000,0x96800000,0x11005003,0x7c00100,0x220402,0x11005013,0x2802500,0x962460,
+0x11005013,0x4000020,0x200005,0x11005013,0x7c00100,0x2633801,0x11005013,0x7c00100,0x2633802,0x11005013,0x7c00100,0x2633805,0x11005019,0x7c00100,0x220402,0x11005100,
+0x24000000,0x810000,0x11005100,0x24000000,0x1410000,0x11005102,0x7000100,0x230408,0x11005102,0x7c00100,0x230404,0x11005102,0x7c00100,0x230407,0x11005102,0x7c00100,
+0x230408,0x11005102,0x7c00100,0x230409,0x11005201,0x2802400,0x962460,0x11005500,0x80000,0x1e18820,0x11005502,0x7000100,0x230408,0x11005502,0x7c00100,0x230404,
+0x11005502,0x7c00100,0x230407,0x11005502,0x7c00100,0x230408,0x11005502,0x7c00100,0x230409,0x11005667,0x1000,0,0x11020200,0x80004,0x418820,0x11020200,
+0x4000000,0x100006,0x11020200,0x4000000,0x10000f,0x11020200,0x4000400,0x100002,0x11020200,0x4000400,0x500002,0x11020200,0x6800c00,0x101000,0x11020200,0x24000000,
+0x100000,0x11020200,0x24000000,0x1400000,0x11020200,0x24000000,0x1500000,0x11020200,0x24000000,0x1600000,0x11020200,0x24000000,0x14200000,0x11020200,0x24000020,0x100000,
+0x11020200,0x24000020,0x1600000,0x11020219,0x7c00100,0x12040f,0x11020219,0x7c00100,0x220400,0x11020219,0x7c00100,0x220401,0x11020219,0x7c00100,0x250400,0x11020319,
+0x7c00100,0x220400,0x11020319,0x7c00100,0x220401,0x11020319,0x7c00100,0x220402,0x11020319,0x7c00100,0x250400,0x11020319,0x7c00100,0x250402,0x11020319,0x7d00100,
+0x220402,0x11020419,0x7c00100,0x220401,0x11020519,0x7c00100,0x220400,0x11020600,0x4000400,0x100002,0x11020600,0x4000400,0x200400,0x11020600,0x7c00500,0x130400,
+0x11020600,0x7c00d00,0x130400,0x11020701,0x2802400,0x962460,0x11020701,0x2802400,0x962461,0x11020701,0x2802400,0xc62460,0x1102080e,0x7c00100,0x220400,0x1102080e,
+0x7c00100,0x250400,0x11020908,0x7c00100,0x220400,0x11020908,0x7c00100,0x220401,0x11020908,0x7c00100,0x250400,0x11020908,0x7c00100,0x250401,0x11022800,0x24000000,
+0x100000,0x11022800,0x24000000,0x200000,0x11022800,0x24000000,0x200002,0x11022800,0x24000000,0x401000,0x11022800,0x24000000,0xf00002,0x11022800,0x24000000,0xf0ac02,
+0x11022800,0x24000000,0x1500000,0x11022800,0x24000002,0x100000,0x11022800,0x24000002,0x370000,0x11022800,0x24000002,0x470000,0x11022800,0x24000006,0x400000,0x11022800,
+0x24000008,0x1710000,0x11022800,0x24000008,0x1712c00,0x11022800,0x24000020,0x100000,0x11022800,0x24000020,0x1500000,0x11022800,0x24000020,0x1500002,0x11022900,0x4000000,
+0x10000e,0x11022900,0x4000000,0x10000f,0x11022919,0x7c00100,0x12040f,0x11022c00,0x4000000,0x100002,0x11022c00,0x4000000,0x1500002,0x11022c00,0x4000000,0x1600002,
+0x11022c00,0x4000000,0x1410000f,0x11022c00,0x7c00120,0x120405,0x11022c0e,0x7c00100,0x250401,0x11022c19,0x7c00100,0x150401,0x11022d00,0x4000000,0x100006,0x11022d00,
+0x4000000,0x200006,0x11022d19,0x7c00100,0x120402,0x11022d19,0x7c00100,0x150402,0x11022e00,0x24000000,0x200000,0x11022e00,0x24000020,0x100000,0x11022e00,0x24000020,
+0x14100000,0x11022f00,0x24000020,0x100000,0x11022f00,0x24000020,0x100001,0x11022f00,0x24000020,0x100002,0x11023000,0x24000000,0x100000,0x11023300,0x4000000,0x100002,
+0x11023300,0x4000000,0x100003,0x11023300,0x4000100,0x120403,0x11023300,0x4000100,0x150403,0x11023300,0x4000100,0x14150403,0x11023400,0x24000000,0x100000,0x11023500,
+0x24000000,0x100000,0x11023600,0x24000000,0x100000,0x11023600,0x24000020,0x100000,0x11023600,0x24000020,0x14100000,0x11023700,0x24000000,0x4100000,0x11023700,0x24000000,
+0x4e00000,0x11023700,0x24000000,0x14100000,0x11023700,0x24000000,0x14e00000,0x11023700,0x24000020,0x100000,0x11023700,0x24000020,0x4100000,0x11023700,0x24000020,0x14100000,
+0x11023800,0x4000000,0x100000,0x11023800,0x24000000,0x200000,0x11024e67,0,0,0x11025600,0x4000000,0x100000,0x11042a00,0x4000000,0x1600000,0x11045700,
+0x4000000,0x20000a,0x11045700,0x4000020,0x20000a,0x11045712,0x7c00100,0xe3040a,0x11045712,0x7c80100,0xe3040a,0x11045716,0x7c00100,0xe30c0a,0x11045716,0x7c00100,
+0x2530c0a,0x11063d00,0x4000001,0x445811,0x11065700,0x4000000,0x810011,0x11065700,0x4000000,0xe00011,0x11065700,0x4000000,0x1410011,0x11065700,0x4000000,0x1500011,
+0x11065700,0x4000000,0x1600011,0x11065700,0x4000006,0xe70011,0x11065700,0x4000008,0xe00011,0x11065700,0x4000008,0xe02c11,0x11065700,0x4000010,0x871411,0x11065700,
+0x4000010,0x1201411,0x11065700,0x4000010,0x1271011,0x11065700,0x4000020,0xe00011,0x11065700,0x4000400,0xe00011,0x11065700,0x4000420,0xe00011,0x11065700,0x6800000,
+0xe01c11,0x11065700,0x6800040,0xe29811,0x11065700,0xc000010,0x80ac11,0x11065700,0xc000010,0xb48011,0x11065719,0x7c00100,0xe20411,0x11065719,0x7c00100,0xe50411,
+0x11065719,0x7c00140,0xe20411,0x11065719,0x7c00140,0xe50411,0x11080100,0x6800000,0x201c00,0x11080100,0x68000c0,0x19329800,0x11080100,0x24000000,0x200000,0x11080100,
+0x24000000,0x810000,0x11080100,0x24000000,0x1410000,0x11080100,0x24000000,0x1500000,0x11080100,0x24000000,0x1600000,0x11080100,0x24000000,0x1b00000,0x11080100,0x24000000,
+0x2410000,0x11080100,0x24000000,0x18200000,0x11080100,0x24000006,0xd70000,0x11080100,0x24000008,0x1713c00,0x11080100,0x24000008,0x1714000,0x11080100,0x24000010,0x1001400,
+0x11080100,0x24000010,0x1071000,0x11080100,0x24000010,0x1071400,0x11080100,0x24000020,0x200000,0x11080100,0x24000020,0x400000,0x11080100,0x24000020,0x1600000,0x11080100,
+0x24000400,0x200000,0x11080100,0x24000420,0x200000,0x11080100,0x2c000010,0xb48000,0x11080100,0x2c000010,0x100ac00,0x11080100,0x44000001,0x1a45800,0x11080119,0x7c00100,
+0x220400,0x11080119,0x7c00100,0x250400,0x11080119,0x7c001c0,0x220400,0x11080119,0x7c001c0,0x250400,0x11080200,0x4000400,0x200002,0x11080200,0x24000000,0x200000,
+0x11080200,0x24000000,0x1500000,0x11080200,0x24000000,0x1600000,0x11080200,0x24000020,0x200000,0x110a1e12,0x7c00100,0x2130480,0x110a1e12,0x7c80100,0x2130480,0x110a3000,
+0x24000000,0x34e00000,0x110a3000,0x24100000,0x810001,0x110a3000,0x24100000,0x1410001,0x110a3700,0x24000000,0x34200000,0x110a3d00,0x4000000,0xe00000,0x110a3d00,0x4000000,
+0xe00002,0x110a3d00,0x24000000,0xe00000,0x110a3d11,0x7c00300,0xe30000,0x110a3d11,0x7c00900,0x1230400,0x110a3d12,0x2802400,0x962460,0x110a3e14,0x7c00100,0xe30000,
+0x110a3e14,0x7c00100,0xe30001,0x110a3e14,0x7c00100,0x2530000,0x110a3e14,0x7c00900,0x1230000,0x110a3e14,0x7c00900,0x1230001,0x110a3f16,0x7c00100,0xe30c00,0x110a3f16,
+0x7c00100,0xe30c01,0x110a3f16,0x7c00100,0x2530c00,0x110a3f16,0x7c00900,0x1230c00,0x110a3f16,0x7c00900,0x1230c01,0x110a4005,0x7c00100,0xe30400,0x110a4112,0x7c00100,
+0xe30402,0x110a4112,0x7c80100,0xe30402,0x110a4400,0x4000000,0xe00000,0x110a4412,0x4000000,0xe00002,0x110a4412,0x4000000,0xe00003,0x110a4416,0x4000000,0xe00c03,
+0x110a4500,0x4000000,0xe0000d,0x110a4516,0x4000000,0xe00c0d,0x110a4711,0x7c40300,0xe30000,0x110a4f11,0x7c00300,0xe30001,0x110a4f11,0x7c40300,0xe30000,0x110a5300,
+0x4000000,0x810010,0x110a5300,0x4000000,0xe00002,0x110a5300,0x4000000,0xe00010,0x110a5300,0x4000000,0x1410010,0x110a5300,0x4000002,0xe70010,0x110a5300,0x4000008,
+0x810010,0x110a5300,0x4000008,0x1410010,0x110a5300,0x6800000,0xe01c02,0x110a5300,0x6800000,0xe01c10,0x110a5400,0x4000000,0x81000c,0x110a5400,0x4000000,0xe0000c,
+0x110a5400,0x4000000,0x141000c,0x110a5400,0x4000000,0x150000c,0x110a5400,0x4000000,0x160000c,0x110a5400,0x4000002,0xe7000c,0x110a5400,0x4000010,0x87140c,0x110a5400,
+0x4000010,0xe7000c,0x110a5400,0x4000010,0x120140c,0x110a5400,0x4000010,0x127100c,0x110a5400,0x4000020,0xe0000c,0x110a5400,0x4000026,0xe7000c,0x110a5400,0xc000010,
+0x80ac0c,0x110a5400,0xc000010,0xb4800c,0x11400c0c,0x4000010,0xb00000,0x11400c0c,0x4000010,0x1071400,0x11400c0c,0xc000010,0xb48000,0x11400c16,0x7c00900,0x230400,
+0x11400f40,0xc000010,0x448000,0x11400f54,0xc000010,0x448000,0x11401d89,0x4000000,0x200000,0x11403dbf,0x4000000,0xe00000,0x114457b4,0x4000004,0x120000a,0x114457b4,
+0x4000008,0x81000a,0x114457b4,0x4000008,0x141000a,0x114457b4,0x4000010,0x87000a,0x114457b4,0xc000010,0x84800a,0x114457bd,0x3802500,0x126246a,0x114457bd,0x7c00d00,
+0x2530c0a,0x114a3db4,0x24000000,0x810000,0x114a3db4,0x24000000,0x1410000,0x114a3db4,0x24000008,0x810000,0x114a3db4,0x24000008,0x1410000,0x114a3db4,0x24000010,0x870000,
+0x114a3db4,0x2c000010,0x848000,0x114a3dba,0x4000000,0xe00000,0x114a3dba,0x24000000,0xe00000,0x114a3dba,0x24000002,0x1200000,0x114a3dba,0x24000002,0x14e00000,0x114a3dba,
+0x24000008,0x810000,0x114a3dba,0x24000008,0x1410000,0x114a3dbd,0x7c00900,0x930c00,0x114a3dbd,0x7c00900,0xe30c00,0x114a3dbf,0x7c00300,0xe30000,0x114a3ebd,0x7000400,
+0x1200c02,0x114a3fb4,0x4000004,0x1200000,0x114a3fbd,0x7c00d00,0x2530c00,0x114a42bf,0x4000000,0xe00000,0x114a42bf,0x4000000,0xe0000f,0x114a44bf,0x4000000,0xe00002,
+0x114a44bf,0x4000000,0xe00003,0x114a44bf,0x4000000,0x14e00003,0x114a45bf,0x4000000,0xe00002,0x114a45bf,0x4000000,0xe0000d,0x1180090a,0x2802400,0x962460,0x11800c1e,
+0x2802100,0x962460,0x11800c1e,0x2802500,0x962460,0x11800f27,0x2802400,0x962460,0x11800f34,0x2802400,0x962460,0x11820700,0x2802400,0x962460,0x11820700,0x2802500,
+0x962460,0x118a3dc0,0x2802400,0x962460,0x118a3ebd,0x2802400,0x962460,0x11c00904,0x2802400,0x962460,0x11c00908,0x2802400,0x962460,0x11c00c20,0xc000010,0xb48000,
+0x11c00c23,0x6800000,0x1329800,0x11c00f6d,0x6800000,0x1329800,0x11c01072,0x6800000,0x1329800,0x11c01176,0x6800000,0x1329800,0x11c0127a,0x6800000,0x1329800,0x11c0147e,
+0x4000000,0x200000,0x11c0147e,0x6800000,0x1329800,0x11c01682,0x6800000,0x1329800,0x11c051fa,0x7c00100,0x230408,0x20000067,0x1000,0,0x20000b13,0x2802400,
+0x962460,0x20000b13,0x2802500,0x962460,0x20001b27,0x2802100,0x962460,0x20001b27,0x2802100,0x962461,0x20001b27,0x2802400,0x962460,0x20001b27,0x2806400,0x962460,
+0x20001b27,0x2902100,0x962462,0x20001b27,0x4000000,0x200000,0x20001b27,0x4000000,0x400000,0x20001b27,0x4000000,0x500000,0x20001b27,0x4000000,0x810000,0x20001b27,
+0x4000000,0xb00000,0x20001b27,0x4000000,0xc0000b,0x20001b27,0x4000000,0x1410000,0x20001b27,0x4000010,0xb00000,0x20001b27,0x4000010,0xc00000,0x20001b27,0x6800000,
+0x1329800,0x20001b27,0x6800100,0x462540,0x20001b27,0x6800400,0x962540,0x20001b27,0x7c00100,0x230400,0x20001b27,0x7c00100,0x230401,0x20002619,0x7c00100,0x220401,
+0x20002a00,0x4000000,0x1600000,0x20004b67,0,0x1900000,0x20004c67,0,0x1900000,0x20004d67,0,0x1900000,0x20006d67,0x1000,0,0x20006e67,
+0x1000,0,0x20026d67,0,0,0x20026e67,0,0,0x200a4a12,0x7c00100,0x1f304c1,0x200a4a12,0x7c00100,0x20304e1,0x21005600,0x4000000,
+0x700000,0x21022a00,0x4000000,0x1600000,0x30000419,0x7c00100,0x220400,0x30000419,0x7c00100,0x220401,0x30000419,0x7c00100,0x250400,0x30000419,0x7c00100,0x250401,
+0x30000519,0x7c00100,0x220400,0x30000600,0x4000400,0x200400,0x30000600,0x7c00500,0x230400,0x30000605,0x4000400,0x200400,0x3000080e,0x7c00100,0x220400,0x30000908,
+0x2000,0x962460,0x30000908,0x7c00100,0x220400,0x30000908,0x7c00100,0x220401,0x30000908,0x7c00100,0x250400,0x30000908,0x7c00100,0x250401,0x30000a03,0x4000006,
+0x400400,0x30000c02,0x4000000,0x200000,0x30000c02,0x7c00100,0x230400,0x30000d22,0x2802100,0x962460,0x30000d22,0x2802400,0x962460,0x30000d22,0x2802500,0x962460,
+0x30000d22,0x4000000,0x200000,0x30000d22,0x4000010,0x200000,0x30000d22,0x7c00100,0x230400,0x30000d22,0xc000010,0x248000,0x30000d22,0x80000000,0x218960,0x30000e25,
+0x2802500,0x962460,0x30000e25,0x7c00100,0x230400,0x30001821,0x2802100,0x962460,0x30001821,0x2806400,0x962460,0x30001821,0x4000000,0x200000,0x30001821,0x6800100,
+0x962540,0x30001821,0x6800100,0x962541,0x30001821,0x7c00100,0x230400,0x30001b27,0x2802100,0x962460,0x30001b27,0x2802400,0x962460,0x30001b27,0x4000000,0x200000,
+0x30001b27,0x4000000,0x400000,0x30001b27,0x7c00100,0x230400,0x30001c1c,0x2802100,0x1862460,0x30001c1c,0x2802400,0x1862460,0x30001c1c,0x2806400,0x1862460,0x30001c1c,
+0x4000000,0x200000,0x30001c1c,0x6800100,0x1862400,0x30001c1c,0x6800100,0x1862540,0x30001c1c,0x7c00100,0x1830000,0x30001c1c,0x7c00100,0x1830001,0x30001c1c,0xc000010,
+0x448000,0x30001f0b,0x4000000,0x200000,0x30001f0b,0x4000010,0x200000,0x30001f0b,0x4000010,0x400000,0x30001f0b,0x6800000,0x200000,0x30001f0b,0x7c00100,0x230400,
+0x30001f0b,0xc000010,0x248000,0x30002006,0x7c00100,0x250400,0x30002128,0x4000000,0x200000,0x30002128,0x7c00100,0x230400,0x30002128,0xc000010,0x248000,0x3000221d,
+0x4000000,0x810000,0x3000221d,0x4000000,0x1410000,0x3000221d,0x4000001,0x445800,0x3000221d,0x7c00100,0x230400,0x30002300,0x4000010,0x400000,0x30002320,0x7c00100,
+0x230400,0x30002417,0x2802100,0x1862460,0x30002417,0x2802400,0x1862460,0x30002417,0x2806400,0x1862460,0x30002417,0x2882000,0x1862460,0x30002417,0x4000000,0x200000,
+0x30002417,0x4000000,0x400000,0x30002417,0x4000000,0x1600000,0x30002417,0x4000010,0x400000,0x30002417,0x4000010,0x1200000,0x30002417,0x6800000,0x1329800,0x30002417,
+0x6800100,0x1862540,0x30002417,0x7c00100,0x1830000,0x30002417,0x7d00100,0x1830000,0x3000251b,0x80000,0xc18820,0x3000251b,0x2802100,0x962460,0x3000251b,0x3c02100,
+0x962460,0x3000251b,0x4000000,0x200000,0x3000251b,0x4000006,0x500000,0x3000251b,0x4000010,0x400000,0x3000251b,0x4000010,0xb70000,0x3000251b,0x4000800,0x200000,
+0x3000251b,0x6800000,0x1329800,0x3000251b,0x7c00100,0x230400,0x3000251b,0x7c00900,0x230400,0x3000251b,0xc000010,0xb48000,0x3000251b,0x12882000,0x962460,0x30002800,
+0x24000000,0x200000,0x30002800,0x2c000010,0x1248002,0x30002800,0x2c000010,0x15248002,0x30002a00,0x4000000,0x1600000,0x30002b01,0x2000,0x962460,0x30002b01,0x2000,
+0x8962460,0x30002c00,0x4000000,0x200000,0x30002c00,0x7c00100,0x14220405,0x30002d19,0x7c00100,0x250400,0x30002e00,0x24000000,0x200000,0x30003000,0x24000000,0x200000,
+0x30003000,0x24000000,0x4200000,0x30003100,0x24000000,0x200000,0x30003600,0x24000000,0x200000,0x30003700,0x24000000,0x4200000,0x3000392e,0x24000000,0x200000,0x30005013,
+0x7c00100,0x2633801,0x30005600,0,0x918820,0x30020600,0x4000400,0x500400,0x30020701,0x2802400,0x962460,0x30020701,0x2802400,0xc62460,0x300a3a11,0x4020000,
+0xe00000,0x300a3a11,0x4020000,0xe00002,0x300a3b11,0x4020000,0xe00002,0x300a3c00,0x4008000,0xe00000,0x300a3c00,0x4010000,0xe00000,0x300a3d11,0x7c00300,0xe30002,
+0x300a4305,0x7c00100,0xe30400,0x300a4611,0x7c40300,0xe30000,0x300a4829,0x7c00100,0xe30400,0x300a4829,0x7c00900,0x1230400,0x300a4929,0x4000000,0xe00000,0x3040258f,
+0x4000010,0x400000,0x3040258f,0x4000010,0xb70000,0x3040258f,0xc000010,0xb48000,0x304028af,0x4000001,0xc41c0b,0x304a3dbf,0x4000000,0xe00000,0x30800c1e,0x2802100,
+0x962460,0x30c01c87,0x6800000,0x1329800,0x3100080e,0x7c00120,0x220402,0x3100080e,0x7c00120,0x250402,0x31005167,0x1000,0,0x3100581e,0x4000000,0x200000,
+0x3100581e,0x7c00100,0x230400,0x3100590d,0x7c00100,0x230400,0x31005a09,0x7c00100,0x220400,0x31005a09,0x7c00100,0x250400,0x31005b00,0x4000000,0x200000,0x31005c00,
+0x80000,0x918820,0x31005c00,0x2802000,0x962460,0x31005c00,0x2802400,0x962460,0x31005c00,0x4000000,0x200000,0x31005c00,0x4000000,0x200001,0x31005c00,0x6800000,
+0x962540,0x31005c00,0x6800400,0x962540,0x31005c01,0x2802400,0x962460,0x31005d00,0x4000020,0x200005,0x31005d00,0x6800020,0x1329805,0x31005d00,0x7c00120,0x220405,
+0x31005d00,0x7c00120,0x250405,0x31006000,0x82000,0x8962460,0x31006000,0x180000,0x918820,0x310a5e11,0x7c40300,0xe30000,0x310a5f11,0x7c00300,0xe30001,0x32000419,
+0x7c00100,0x250400,0x3200080e,0x4000020,0x200000,0x3200080e,0x7c00100,0x220400,0x3200080e,0x7c00100,0x250400,0x32000908,0x7c00100,0x220400,0x32000908,0x7c00100,
+0x250400,0x32000c02,0x7c00100,0x230400,0x32000e25,0x7c00100,0x230400,0x32001d0c,0x7c00100,0x230400,0x32002800,0x80000,0x1e18820,0x32002800,0x80020,0x218820,
+0x32002800,0x4000001,0x445802,0x32002800,0x24000000,0x200000,0x32002800,0x24000000,0x200002,0x32002800,0x24000020,0x200000,0x32002800,0x2c000010,0x1248002,0x32002919,
+0x7c00100,0x22040f,0x32002a00,0x4000000,0x1600000,0x32002b01,0x2000,0x962460,0x32002b01,0x2802000,0x962460,0x32002b01,0x2802020,0x962460,0x32002c00,0x4000000,
+0x200000,0x32002c00,0x4000020,0x200000,0x32002c00,0x4000020,0x200005,0x32002c00,0x7c00120,0x220405,0x32002c00,0x7c00120,0x250405,0x32002e00,0x24000020,0x200000,
+0x32002f00,0x24000020,0x200000,0x32003000,0x24000000,0x200000,0x32003000,0x24000020,0x200000,0x32003500,0x24000000,0x200000,0x32003600,0x24000020,0x200000,0x32003600,
+0x24000020,0x14200000,0x32003700,0x24000000,0x200000,0x32003700,0x24000000,0x4100000,0x32003700,0x24000000,0x4200000,0x32003700,0x24000000,0x14200000,0x32003800,0x24000000,
+0x810000,0x32003800,0x24000000,0x1410000,0x32005102,0x4000000,0x1500008,0x32005502,0x7c00100,0x230400,0x32006108,0x7c00100,0x220400,0x32006108,0x7c00100,0x250400,
+0x3200622a,0x2802100,0x962460,0x3200622a,0x2806000,0x962460,0x3200622a,0x7c00100,0x230400,0x3200632b,0x2802100,0x962460,0x3200632b,0x2806000,0x962460,0x3200632b,
+0x7c00100,0x230400,0x3200642c,0x2802100,0x962460,0x3200642c,0x7c00100,0x230400,0x3200652d,0x2802100,0x962460,0x3200652d,0x7c00100,0x230400,0x32006600,0x24000020,
+0x200000,0x32006700,0x24000020,0x200000,0x32006800,0x24000020,0x200000,0x32006800,0x24000020,0x14200000,0x32006900,0x24000020,0x200000,0x32006900,0x24000020,0x810000,
+0x32006900,0x24000020,0x1410000,0x32006a00,0x24000020,0x200000,0x32006a00,0x24000020,0x200001,0x32006a00,0x24000020,0x200002,0x32020701,0x2882000,0xc62460,0x32023300,
+0x4000000,0x100000,0x32026c01,0x12882000,0x962460,0x32026c01,0x12882000,0x8962460,0x32065700,0x4000000,0x810011,0x32065700,0x4000000,0x1410011,0x32086600,0x24000020,
+0x810000,0x32086600,0x24000020,0x1410000,0x32086900,0x24000020,0x810000,0x32086900,0x24000020,0x1410000,0x320a3600,0x24000020,0x34200000,0x320a3d11,0x7c00100,0x1230400,
 0x320a3e14,0x7c00100,0xe30010,0x320a3e14,0x7c00100,0x2530000,0x320a3f16,0x7c00100,0xe30c10,0x320a4400,0x4000000,0xe00003,0x320a4929,0x4000000,0xe00000,0x320a4f11,
-0x7c00300,0xe30001,0x320a6b16,0x7c00100,0x2530c00,0x3240636f,0xc000010,0x448000,0x324a3d8f,0x4000000,0x10e00000,0x324a3d8f,0x7c00100,0x1230400,0x324a3f8d,0x4000002,
-0x1200c00,0x324a538a,0x24000000,0xe00000,0x32820701,0x2802000,0x962460,0x40000419,0x7c00100,0x220400,0x40000519,0x7c00100,0x220400,0x40000600,0x4000400,0x200000,
-0x4000080e,0x7c00100,0x220400,0x4000080e,0x7c00100,0x250400,0x4000080e,0x7c00100,0x250402,0x40000c02,0,0x218820,0x40000c02,0x2802100,0x962460,0x40000c02,
-0x2802400,0x962460,0x40000c02,0x2802500,0x962460,0x40000c02,0x4000000,0x200000,0x40000c02,0x4000000,0x1071400,0x40000c02,0x7c00100,0x230400,0x40000d22,0x7c00100,
+0x7c00300,0xe30001,0x320a6b16,0x7c00100,0x2530c00,0x3240638b,0xc000010,0x448000,0x324a3dc2,0x4000000,0x14e00000,0x324a3dc2,0x7c00100,0x1230400,0x324a3fbd,0x4000002,
+0x1200c00,0x324a53ba,0x24000000,0xe00000,0x32820701,0x2802000,0x962460,0x40000419,0x7c00100,0x220400,0x40000519,0x7c00100,0x220400,0x40000600,0x4000400,0x200400,
+0x4000080e,0x7c00100,0x220400,0x4000080e,0x7c00100,0x250400,0x4000080e,0x7c00100,0x250402,0x40000c02,0x2802100,0x962460,0x40000c02,0x2802400,0x962460,0x40000c02,
+0x2802500,0x962460,0x40000c02,0x4000000,0x200000,0x40000c02,0x4000000,0x1071400,0x40000c02,0x7c00100,0x230400,0x40000c02,0x80000000,0x218960,0x40000d22,0x7c00100,
 0x230400,0x40000f0a,0x7c00100,0x230400,0x40001004,0x7c00100,0x230400,0x40001110,0x2802100,0x962460,0x40001110,0x6800100,0x962540,0x4000120f,0x2802100,0x962460,
 0x4000120f,0x4000000,0x1600000,0x4000120f,0x7c00100,0x230400,0x4000131f,0x7c00100,0x230400,0x40001423,0x4000000,0x200000,0x40001423,0x4000000,0x1600000,0x40001615,
 0x2802400,0x962460,0x40001615,0x7c00100,0x230400,0x40002417,0x2802400,0x1862460,0x40002417,0x4000000,0x200000,0x40002800,0x6800000,0x201c00,0x40002800,0x24000002,
-0x200000,0x40002c00,0x4000000,0x200002,0x40003000,0x24000000,0x10200000,0x40003000,0x24000020,0x200000,0x40003700,0x24000000,0x200000,0x40003700,0x24000000,0x10200000,
-0x40003700,0x24000000,0x30200000,0x40005a09,0x7c00100,0x220400,0x40005a09,0x7c00100,0x250400,0x40005d00,0x7c00120,0x220405,0x40006f30,0x2802100,0x962460,0x40006f30,
+0x200000,0x40002c00,0x4000000,0x200002,0x40003000,0x24000000,0x14200000,0x40003000,0x24000020,0x200000,0x40003700,0x24000000,0x200000,0x40003700,0x24000000,0x4200000,
+0x40003700,0x24000000,0x14200000,0x40005a09,0x7c00100,0x220400,0x40005a09,0x7c00100,0x250400,0x40005d00,0x7c00120,0x220405,0x40006f30,0x2802100,0x962460,0x40006f30,
 0x2802400,0x962460,0x40006f30,0x4000000,0x200000,0x40006f30,0x6800000,0x1329800,0x40006f30,0x6800100,0x962540,0x40006f30,0x7c00100,0x230400,0x40006f30,0xc000010,
 0xb48000,0x40007034,0x7c00100,0x1830000,0x40007117,0x4000000,0x200000,0x40007208,0x7c00100,0x220400,0x4000720e,0x7c00100,0x220400,0x4000720e,0x7c00500,0x22040e,
 0x4000720e,0x7c00500,0x22040f,0x40007219,0x7c00100,0x220400,0x40007219,0x7c00500,0x220400,0x40007219,0x7c00500,0x22040e,0x40007219,0x7c00500,0x22040f,0x40007300,
-0x24000000,0x200000,0x40007300,0x24000000,0x10200000,0x40007400,0x4000000,0x200000,0x40007531,0x7c00100,0x230400,0x40007631,0x7c00100,0x230400,0x40007835,0x4000010,
+0x24000000,0x200000,0x40007300,0x24000000,0x14200000,0x40007400,0x4000000,0x200000,0x40007531,0x7c00100,0x230400,0x40007631,0x7c00100,0x230400,0x40007835,0x4000010,
 0x400000,0x40007835,0x7c00100,0x230400,0x40007933,0x7c00100,0x230400,0x40007a32,0x6800000,0x1329800,0x40007a32,0x7c00100,0x230400,0x40007b2f,0x7c00100,0x230400,
-0x40007c00,0x4000000,0x200000,0x40020701,0x2802400,0x962460,0x40020701,0x2802400,0xc62460,0x40023300,0x4000000,0x200000,0x40023700,0x24000000,0x30e00000,0x40027d01,
-0x12882000,0x962460,0x400a4400,0x4000000,0xe0000d,0x400a4412,0x4000000,0xe00002,0x400a4412,0x4000000,0xe00003,0x400a4500,0x4000000,0xe0000d,0x400a5300,0x4000000,
-0x810010,0x400a5300,0x4000000,0x1410010,0x404077a6,0x4000000,0x200000,0x404077a6,0x4000000,0x400000,0x40c0511a,0x4000000,0x200000,0x41000419,0x7c00100,0x220400,
-0x41000419,0x7c00100,0x250400,0x4100080e,0x7c00100,0x220400,0x4100080e,0x7c00100,0x250400,0x41000908,0x7c00100,0x220400,0x41000908,0x7c00100,0x250400,0x41000b13,
-0x2802000,0x962460,0x41000b13,0x2802100,0x962460,0x41000b13,0x4000000,0xb00000,0x41000c02,0x2802100,0x962460,0x41000c02,0x4000000,0xb00000,0x41000c02,0x4000000,
-0x1500000,0x41000f0a,0x7c00100,0x230400,0x41001004,0x7c00100,0x230400,0x41001423,0x7c00100,0x230400,0x41001b27,0x4000000,0x500000,0x41001d0c,0x7c00100,0x230400,
-0x41001d0c,0x7c00100,0x23040f,0x41001f0b,0x2802100,0x962460,0x41001f0b,0x4000000,0x200000,0x41001f0b,0x7c00100,0x230400,0x41002800,0x24000000,0x200000,0x41002800,
-0x24000000,0x400000,0x41002919,0x7c00100,0x22040e,0x41002a00,0x4000000,0x1600000,0x41002b01,0x2802020,0x962460,0x41002c00,0x4000000,0x200000,0x41002c00,0x7c00120,
-0x220405,0x41003000,0x24000000,0x200000,0x41003700,0x24000000,0x200000,0x41003700,0x24000000,0x10200000,0x41003700,0x24000000,0x10e00000,0x41003700,0x24000000,0x30200000,
-0x41003700,0x24000000,0x30e00000,0x41005d00,0x7c00120,0x220405,0x41006600,0x24000020,0x200000,0x41006600,0x24000020,0x810000,0x41006600,0x24000020,0x1410000,0x41007208,
-0x7c00100,0x22040f,0x41007219,0x7c00100,0x220400,0x41007300,0x24000000,0x200000,0x41007e0e,0x2802000,0x962460,0x41007e0e,0x4000000,0x200000,0x41007f0e,0x4000000,
-0x200000,0x41007f0e,0x7c00100,0x230400,0x41008002,0x7c00100,0x230400,0x41008137,0x2802100,0x962460,0x41008137,0x4000000,0x200000,0x41008137,0x6800100,0x962540,
-0x41008137,0x7c00100,0x230400,0x41008301,0x2802000,0x962460,0x41008407,0x4000000,0x200000,0x41008407,0x4000000,0x400000,0x41008407,0x4000000,0xb00000,0x41008407,
-0x7c00100,0x220400,0x41008407,0x7c00100,0x250400,0x4100850b,0x7c00100,0x230400,0x4100860b,0x4000000,0x200000,0x4100860b,0x7c00100,0x230400,0x4100870c,0x7c00100,
-0x220400,0x41008838,0x7c00100,0x220400,0x41008838,0x7c00100,0x250400,0x41008939,0x2802000,0x962460,0x41008939,0x2802100,0x962460,0x41008939,0x2806000,0x962460,
-0x41008939,0x4000000,0x200000,0x41008939,0x4000000,0x400000,0x41008939,0x7c00100,0x230400,0x41008939,0xc000010,0x448000,0x41008a00,0x4000000,0x200000,0x41008b3b,
-0x4000000,0x1800000,0x41008b3b,0x6800000,0x1329800,0x41008b3b,0x7c00100,0x1830000,0x41008b3b,0x7e00100,0x1830000,0x41008c3d,0x4000010,0x400000,0x41008c3d,0x7c00100,
-0x230400,0x41008d0e,0x7c00100,0x22040f,0x41008d19,0x7c00100,0x220400,0x41008d19,0x7c00100,0x22040f,0x41008e00,0x24000000,0x200000,0x41008e00,0x24000000,0x400000,
-0x41008e00,0x24000000,0x1710000,0x41008e00,0x24000006,0x400000,0x41008f3a,0x2802000,0x962460,0x41008f3a,0x2802100,0x962460,0x41008f3a,0x2806000,0x962460,0x41008f3a,
+0x40007c00,0x4000000,0x200000,0x40020701,0x2802400,0x962460,0x40020701,0x2802400,0xc62460,0x40023300,0x4000000,0x200000,0x40027d01,0x12882000,0x962460,0x400a3700,
+0x24000000,0x34200000,0x400a3700,0x24000000,0x34e00000,0x400a4400,0x4000000,0xe0000d,0x400a4412,0x4000000,0xe00002,0x400a4412,0x4000000,0xe00003,0x400a4500,0x4000000,
+0xe0000d,0x400a5300,0x4000000,0x810010,0x400a5300,0x4000000,0x1410010,0x404077fc,0x4000000,0x200000,0x404077ff,0x4000000,0x200000,0x404077ff,0x4000000,0x400000,
+0x40c0147e,0x4000000,0x200000,0x40c051fa,0x4000000,0x200000,0x41000419,0x7c00100,0x220400,0x41000419,0x7c00100,0x250400,0x4100080e,0x7c00100,0x220400,0x4100080e,
+0x7c00100,0x250400,0x41000908,0x7c00100,0x220400,0x41000908,0x7c00100,0x250400,0x41000b13,0x2802000,0x962460,0x41000b13,0x2802100,0x962460,0x41000b13,0x4000000,
+0xb00000,0x41000c02,0x2802100,0x962460,0x41000c02,0x4000000,0x1500000,0x41000c02,0xc000010,0xb48000,0x41000f0a,0x7c00100,0x230400,0x41001004,0x7c00100,0x230400,
+0x41001423,0x7c00100,0x230400,0x41001b27,0x4000000,0x500000,0x41001d0c,0x7c00100,0x230400,0x41001d0c,0x7c00100,0x23040f,0x41001f0b,0x2802400,0x962460,0x41001f0b,
+0x4000000,0x200000,0x41001f0b,0x7c00100,0x230400,0x41002800,0x24000000,0x200000,0x41002800,0x24000000,0x400000,0x41002919,0x7c00100,0x22040e,0x41002a00,0x4000000,
+0x1600000,0x41002b01,0x2802020,0x962460,0x41002c00,0x4000000,0x200000,0x41002c00,0x7c00120,0x220405,0x41003000,0x24000000,0x200000,0x41003700,0x24000000,0x4200000,
+0x41003700,0x24000000,0x14200000,0x41003700,0x24000000,0x14e00000,0x41005d00,0x7c00120,0x220405,0x41006600,0x24000020,0x200000,0x41006600,0x24000020,0x810000,0x41006600,
+0x24000020,0x1410000,0x41007208,0x7c00100,0x22040f,0x41007219,0x7c00100,0x220400,0x41007300,0x24000000,0x200000,0x41007e0e,0x2802000,0x962460,0x41007e0e,0x4000000,
+0x200000,0x41007f0e,0x4000000,0x200000,0x41007f0e,0x7c00100,0x230400,0x41008002,0x7c00100,0x230400,0x41008137,0x2802100,0x962460,0x41008137,0x4000000,0x200000,
+0x41008137,0x6800100,0x962540,0x41008137,0x7c00100,0x230400,0x41008301,0x2802000,0x962460,0x41008407,0x4000000,0x200000,0x41008407,0x4000000,0x400000,0x41008407,
+0x4000000,0xb00000,0x41008407,0x7c00100,0x220400,0x41008407,0x7c00100,0x250400,0x4100850b,0x7c00100,0x230400,0x4100860b,0x4000000,0x200000,0x4100860b,0x7c00100,
+0x230400,0x4100870c,0x7c00100,0x220400,0x41008838,0x7c00100,0x220400,0x41008838,0x7c00100,0x250400,0x41008939,0x2802000,0x962460,0x41008939,0x2802100,0x962460,
+0x41008939,0x2806000,0x962460,0x41008939,0x4000000,0x200000,0x41008939,0x4000000,0x400000,0x41008939,0x7c00100,0x230400,0x41008939,0xc000010,0x448000,0x41008a00,
+0x4000400,0x200400,0x41008b3b,0x4000000,0x1800000,0x41008b3b,0x6800000,0x1329800,0x41008b3b,0x7c00100,0x1830000,0x41008b3b,0x7e00100,0x1830000,0x41008c3d,0x4000010,
+0x400000,0x41008c3d,0x7c00100,0x230400,0x41008d0e,0x7c00100,0x22040f,0x41008d19,0x7c00100,0x220400,0x41008d19,0x7c00100,0x22040f,0x41008e00,0x24000000,0x200000,
+0x41008e00,0x24000000,0x400000,0x41008e00,0x24000000,0x1710000,0x41008e00,0x24000006,0x400000,0x41008f3a,0x2802100,0x962460,0x41008f3a,0x2806000,0x962460,0x41008f3a,
 0x4000000,0x200000,0x41008f3a,0x6800100,0x962540,0x41008f3a,0x7c00100,0x230400,0x4100903c,0x7c00100,0x230400,0x4100903c,0x7c00100,0x23040f,0x41020701,0x2802000,
-0x962460,0x41020701,0x2802000,0xc62460,0x410a4412,0x4000000,0xe00003,0x410a4711,0x7c40300,0xe30000,0x410a4f11,0x7c00300,0xe30001,0x410a9100,0x4000000,0x800010,
-0x410a9100,0x4000000,0x810010,0x410a9100,0x4000000,0x870010,0x410a9100,0x4000000,0xb00010,0x410a9100,0x4000000,0xf00010,0x410a9100,0x4000000,0x1001410,0x410a9100,
-0x4000000,0x1071010,0x410a9100,0x4000000,0x1071410,0x410a9100,0x4000000,0x1410010,0x414a828a,0x4000000,0xe00000,0x41808300,0x2802000,0x962460,0x41c01468,0x6800000,
-0x1329800,0x50000419,0x7c00100,0x220400,0x50000419,0x7c00100,0x250400,0x5000080e,0x7c00100,0x220400,0x50000908,0x7c00100,0x220400,0x50000908,0x7c00100,0x250400,
-0x50000b13,0x2802500,0x962460,0x50000f0a,0x7c00100,0x230400,0x50001615,0x2802100,0x962460,0x50001615,0x7c00100,0x230400,0x50002b01,0x2802020,0x962460,0x50002c00,
-0x4000000,0x200000,0x50002c19,0x7c00100,0x220400,0x50002d19,0x7c00100,0x220400,0x50003000,0x24000000,0x200000,0x50003000,0x24000020,0x200000,0x50003700,0x24000000,
-0x200000,0x50005d00,0x7c00120,0x220405,0x50005d00,0x7c00120,0x250405,0x50006108,0x7c00100,0x220400,0x50006108,0x7c00100,0x250400,0x50006600,0x24000020,0x200000,
-0x50007300,0x24000000,0x200000,0x50008301,0x2802400,0x962460,0x50008a00,0x7c00500,0x230400,0x50009257,0x2802400,0x962460,0x50009257,0x4000000,0x200000,0x50009257,
-0x4000010,0x1071400,0x50009257,0x6800000,0x1329800,0x50009257,0x7c00100,0x230400,0x50009257,0x7c00500,0x230400,0x50009257,0x7c00900,0x230400,0x50009257,0xc000010,
-0xb48000,0x5000933e,0x2802100,0x962460,0x5000933e,0x2802400,0x962460,0x5000933e,0x4000000,0x200000,0x5000933e,0x4000000,0x400000,0x5000933e,0x4000010,0x400000,
-0x5000933e,0x6800000,0x1329800,0x5000933e,0x6800100,0x962540,0x5000933e,0x6800100,0x962541,0x5000933e,0x6804400,0x962540,0x5000933e,0x7c00100,0x230400,0x5000933e,
-0x7c00100,0x230401,0x5000933e,0xc000010,0x448000,0x50009419,0x7c00100,0x220400,0x50009419,0x7c00100,0x250400,0x50009500,0x4000400,0x200000,0x5000965a,0x4000000,
-0x500000,0x5000965a,0x7c00100,0x230400,0x5000965a,0xc000010,0xb48000,0x5000975b,0x4000000,0x200000,0x5000975b,0x4000010,0x400000,0x5000975b,0x7c00100,0x230400,
-0x50009865,0x7c00100,0x230400,0x50009965,0x4000010,0x400000,0x50009965,0x7c00100,0x230400,0x50409a93,0x4000000,0x200000,0x5100080e,0x7c00100,0x220400,0x5100080e,
-0x7c00100,0x250400,0x51000c02,0x2802100,0x962460,0x51000c02,0x4000000,0x1500000,0x51000c02,0x4000020,0x200000,0x51000c02,0x7c00100,0x230400,0x51000f0a,0x7c00100,
-0x230400,0x51000f0a,0x7c00500,0x230400,0x51001110,0x2802100,0x962460,0x5100131f,0x2802100,0x962460,0x51001423,0x7c00100,0x230400,0x51001524,0x2802100,0x962460,
-0x51001524,0x4000000,0x200000,0x51001524,0x7c00100,0x230400,0x5100171a,0x2802100,0x962460,0x5100171a,0x4000000,0x200000,0x5100171a,0x4000000,0x1500000,0x5100171a,
-0x7c00100,0x230400,0x51001b27,0x4000000,0x200000,0x51001b27,0x4000000,0x400000,0x51001b27,0x4000000,0x500000,0x51001b27,0x7c00100,0x230400,0x51001c1c,0x2802100,
-0x1862460,0x51001c1c,0x2802400,0x1862460,0x51001c1c,0x2806400,0x1862460,0x51001c1c,0x4000000,0x1800000,0x51001c1c,0x6800000,0x1329800,0x51001c1c,0x6800000,0x1862400,
-0x51001c1c,0x6800100,0x1862400,0x51001c1c,0x6800100,0x1862540,0x51001c1c,0x6800400,0x1862400,0x51001c1c,0x7c00100,0x1830000,0x5100251b,0x7c00100,0x230400,0x51002619,
-0x7c00100,0x220400,0x51002619,0x7c00100,0x250400,0x51002800,0x80020,0x218820,0x51002c00,0x4000000,0x200000,0x51002d19,0x7c00100,0x230400,0x51003700,0x24000000,
-0x200000,0x51003700,0x24000000,0xe00000,0x51005201,0x2802400,0x962460,0x51005c00,0x4000000,0x200000,0x51006108,0x7c00100,0x220400,0x51006108,0x7c00100,0x250400,
-0x51006600,0x24000020,0x200000,0x51006600,0x24000020,0x810000,0x51006600,0x24000020,0x1410000,0x51007300,0x24000000,0x200000,0x51007300,0x24000000,0x30200000,0x51007300,
-0x24000020,0x200000,0x51008002,0x7c00100,0x230400,0x51008301,0x2802000,0x962460,0x51008301,0x2802400,0x962460,0x51008a00,0x7c00500,0x230400,0x51008e00,0x24000000,
-0x200000,0x51008e00,0x24000000,0x400000,0x51008e00,0x24000000,0x810000,0x51008e00,0x24000000,0x1400000,0x51008e00,0x24000000,0x1410000,0x51008e00,0x24000000,0x1710000,
-0x51008e00,0x24000002,0x200000,0x51008e00,0x24000500,0x230400,0x51008e00,0x2c000010,0xb48000,0x51009419,0x7c00100,0x220400,0x51009419,0x7c00100,0x22040e,0x51009419,
-0x7c00100,0x22040f,0x51009419,0x7c00100,0x250400,0x51009500,0x4000000,0x200000,0x51009500,0x7c00500,0x230400,0x51009519,0x7c00100,0x220400,0x51009519,0x7c00100,
-0x22040f,0x51009519,0x7c00100,0x230400,0x51009519,0x7c00100,0x250400,0x51009b71,0x2802100,0x962460,0x51009b71,0x6800000,0x1329800,0x51009b71,0x6800100,0x962540,
-0x51009b71,0x6804400,0x962540,0x51009b71,0x7c00100,0x230400,0x51009c52,0x2802100,0x962460,0x51009c52,0x2802400,0x962460,0x51009c52,0x2802c00,0x962460,0x51009c52,
-0x4000010,0x400000,0x51009c52,0x6800000,0x1329800,0x51009c52,0x6800100,0x962540,0x51009c52,0x7c00100,0x230400,0x51009c52,0xc000010,0x448000,0x51009d6d,0x6800000,
-0x1329800,0x51009d6d,0x7c00100,0x230400,0x51009d6d,0x7c00500,0x230400,0x51009d6d,0x7c00d00,0x230400,0x51009d6d,0xc000010,0x448000,0x51009e08,0x2802100,0x962460,
-0x51009f63,0x4000010,0x400000,0x51009f63,0x6800000,0x1329800,0x51009f63,0x7c00100,0x230400,0x51009f63,0x7c00900,0x230400,0x51009f63,0xc000010,0x448000,0x51009f63,
-0xc000010,0xb48000,0x5100a008,0x2000,0x962460,0x5100a008,0x2802400,0x962460,0x5100a008,0x4000000,0x200000,0x5100a008,0x7c00100,0x220400,0x5100a008,0x7c00100,
-0x230400,0x5100a008,0x7c00100,0x250400,0x5100a008,0x7c00500,0x230400,0x5100a16f,0x2806400,0x962460,0x5100a16f,0x6800000,0x1329800,0x5100a16f,0x6800100,0x962540,
-0x5100a16f,0x7c00100,0x230400,0x5100a16f,0xc000010,0x448000,0x5100a24f,0x2802100,0x962460,0x5100a24f,0x2802400,0x962460,0x5100a24f,0x6800000,0x1329800,0x5100a24f,
-0x7c00100,0x230400,0x5100a24f,0xc000010,0x448000,0x5100a36e,0x2802100,0x962460,0x5100a36e,0x4000000,0x200000,0x5100a36e,0x6800100,0x962540,0x5100a36e,0x6804400,
-0x962540,0x5100a36e,0x7c00100,0x230400,0x5100a442,0x2802100,0x962460,0x5100a442,0x4000000,0x200000,0x5100a442,0x6800000,0x1329800,0x5100a442,0x6800100,0x962540,
-0x5100a442,0x7c00100,0x230400,0x5100a442,0xc000010,0x448000,0x5100a500,0x4000000,0x200000,0x5100a600,0x4000000,0x200000,0x5100a601,0x2802000,0x962460,0x5100a76b,
-0x7c00100,0x230400,0x5100a868,0x7c00100,0x230400,0x5100a96c,0x4000000,0x200000,0x5100a96c,0x7c00100,0x230400,0x5100aa00,0x4000000,0xe00000,0x5100aa00,0x4000000,
-0x30e00000,0x5100ab00,0x4000000,0xe00000,0x51086600,0x24000020,0x810000,0x51086600,0x24000020,0x1410000,0x510a4005,0x7c00100,0xe30400,0x510a4711,0x7c40300,0xe30000,
-0x5140a2a1,0x4000400,0x400000,0x514a828a,0x4000000,0xe00000,0x51802b81,0x2802000,0x962460,0x51c0090a,0x2802400,0x962460,0x51c0a00a,0x2802400,0x962460,0x52000f0a,
-0x2802100,0x962460,0x52000f0a,0x6800100,0x962540,0x52000f0a,0x7c00100,0x230400,0x52001004,0x4000000,0x1600000,0x52001b00,0x4000000,0x200000,0x52001c1c,0x2802100,
-0x1862460,0x52001c1c,0x6800100,0x1862400,0x52001c1c,0x6800400,0x1862400,0x52001e12,0x7c00100,0x2230500,0x52001e12,0x7c00100,0x2330520,0x52002128,0x4000002,0x400000,
-0x52002128,0x7c00100,0x230400,0x52002a00,0x4000000,0x1500000,0x52002a00,0x4000000,0x1600000,0x52002d00,0x4000000,0x200006,0x52003000,0x24000000,0x200000,0x52003700,
-0x24000000,0x30e00000,0x52006108,0x7c00100,0x220400,0x52006108,0x7c00100,0x250400,0x52008301,0x2802400,0x962460,0x52008407,0x2802400,0x962460,0x52008407,0x7c00100,
-0x220400,0x52008407,0x7c00100,0x250400,0x52008b3b,0x6800000,0x1800000,0x52008b3b,0x7c00100,0x1830000,0x52008e00,0x24000000,0x400000,0x52009419,0x7c00100,0x250400,
-0x5200975b,0x4000000,0x200000,0x5200ac7e,0x2802000,0x962460,0x5200ac7e,0x2802100,0x962460,0x5200ac7e,0x2802400,0x962460,0x5200ac7e,0x4000010,0x200000,0x5200ac7e,
-0x7c00100,0x230400,0x5200ad28,0x7c00100,0x230400,0x5200ae6a,0x2802100,0x1862460,0x5200ae6a,0x2802400,0x962460,0x5200ae6a,0x2802400,0x1862460,0x5200ae6a,0x2806000,
-0x1862460,0x5200ae6a,0x4000000,0x1800000,0x5200ae6a,0x6800000,0x1329800,0x5200ae6a,0x6800100,0x1862400,0x5200ae6a,0x6800100,0x1862540,0x5200ae6a,0x7c00100,0x1830000,
-0x5200ae6a,0x7c00900,0x1830000,0x5200ae6a,0xc000010,0x1848000,0x5200b083,0x4000010,0x400000,0x5200b083,0x7c00100,0x230400,0x5200b083,0xc000010,0x448000,0x5200b182,
-0x2802400,0x962460,0x5200b182,0x4000000,0x200000,0x5200b182,0x4000010,0x400000,0x5200b182,0x7c00100,0x230400,0x5200b182,0xc000010,0x448000,0x5200b30a,0x2802400,
-0x962460,0x5200b30a,0x4000000,0x200000,0x5200b30a,0x7c00100,0x230400,0x5200b54e,0x2802100,0x962460,0x5200b54e,0x2802400,0x962460,0x5200b54e,0x4000000,0x200000,
-0x5200b54e,0x4000010,0x400000,0x5200b54e,0x6800000,0x1329800,0x5200b54e,0x6800100,0x962540,0x5200b54e,0x6804400,0x962540,0x5200b54e,0x7c00100,0x230400,0x5200b54e,
-0xc000010,0x448000,0x5200b61c,0x4000000,0x1800000,0x5200b61c,0x6800400,0x1862400,0x5200b61c,0x7c00100,0x1830000,0x5200b61c,0x7c00900,0x1830000,0x5200b77f,0x2802100,
-0x1862460,0x5200b77f,0x2802400,0x1862460,0x5200b77f,0x4000000,0x1800000,0x5200b77f,0x4000010,0x1800000,0x5200b77f,0x7c00100,0x1830000,0x5200b77f,0x7c00500,0x1830000,
-0x5200b77f,0x7c00900,0x1830000,0x5200b77f,0x7e00100,0x1830000,0x5200b873,0x2802100,0x962460,0x5200b873,0x2806400,0x962460,0x5200b873,0x6800000,0x1329800,0x5200b873,
-0x6800100,0x962540,0x5200b873,0x6800400,0x962540,0x5200b873,0x7c00100,0x230400,0x5200b873,0xc000010,0x448000,0x5200b912,0x7c00100,0x2230500,0x5200b912,0x7c00100,
-0x2330520,0x5200ba74,0x4000000,0x200000,0x5200ba74,0x4000010,0x400000,0x5200ba74,0x7c00100,0x230400,0x5200bb85,0x4000000,0x200000,0x5200bb85,0x7c00100,0x230400,
-0x5200bc75,0x4000000,0x400000,0x5200bc75,0x4000010,0x400000,0x5200bc75,0x7c00100,0x230400,0x5200bd7d,0x4000000,0x200000,0x5200bd7d,0x7c00100,0x230400,0x5200be7a,
-0x4000000,0x200000,0x5200be7a,0x7c00100,0x230400,0x5200bf58,0x7c00100,0x230400,0x5200c002,0x4000000,0x200000,0x5200c178,0,0x218820,0x5200c178,0x2802000,
-0x962460,0x5200c178,0x2802100,0x962460,0x5200c178,0x2802400,0x962460,0x5200c178,0x2806400,0x962460,0x5200c178,0x4000000,0x200000,0x5200c178,0x6800100,0x962540,
-0x5200c178,0x7c00100,0x230400,0x5200c178,0x7c00100,0x230401,0x5200c178,0xc000010,0x448000,0x5200c247,0x7c00100,0x230400,0x5200c247,0x7c00100,0x830400,0x5200c247,
-0x7c00100,0x1430400,0x5200c300,0x4000000,0x200003,0x52022d00,0x4000000,0x100006,0x52023700,0x24000000,0x100000,0x52023700,0x24000000,0xe00000,0x52023700,0x24000000,
-0x10100000,0x52023700,0x24000000,0x10e00000,0x52023700,0x24000000,0x30e00000,0x52023700,0x24000000,0x90e00000,0x52023800,0x24000000,0x30100000,0x52024400,0x4000000,0x100000,
-0x52027300,0x24000000,0x100000,0x52027300,0x24000000,0x30100000,0x5202c300,0x4000000,0x100000,0x5202c300,0x4000000,0x100002,0x5202c300,0x4000000,0x100003,0x5202c300,
-0x4000000,0x10000d,0x5202c300,0x4000100,0x150400,0x5202c300,0x4000100,0x15040d,0x5202c300,0x4000100,0x10150400,0x520a1e12,0x7c00100,0x2130480,0x520a4400,0x4000000,
-0xe00003,0x520a4711,0x7c40300,0xe30000,0x520a4f11,0x7c00300,0xe30001,0x520ab412,0x7c00100,0x2130480,0x520ac400,0x4000000,0xe00002,0x520ac400,0x4000000,0xe0000d,
-0x520ac400,0x4000000,0x30e0000d,0x520ac414,0x4000000,0xe0000d,0x520ac511,0x7c40300,0xe30000,0x5240af75,0x6800400,0x962540,0x5240af75,0x7c00100,0x230400,0x5240af76,
-0x4000400,0x200000,0x5240af76,0x6800100,0x962540,0x5240b294,0x4000000,0x200000,0x5240b294,0x4000000,0x1500000,0x5240b5a4,0x7c00900,0x230400,0x5280af75,0x2802400,
-0x962460,0x5280af76,0x2802400,0x962460,0x5280af78,0x2802400,0x962460,0x5280af7a,0x2802400,0x962460,0x52c0b39f,0x7c00100,0x230400,0x60000c02,0x2802100,0x962460,
-0x60000c02,0x7c00100,0x230400,0x60000f0a,0x2802100,0x962460,0x60000f0a,0x6800100,0x962540,0x60000f0a,0x7c00100,0x230400,0x6000131f,0x4000000,0x200000,0x6000171a,
-0x7c00100,0x230400,0x60001b27,0x2802100,0x962460,0x60001b27,0x4000000,0xc00000,0x60001b27,0x7c00100,0x230400,0x60001f0b,0x2802000,0x962460,0x60002919,0x7c00100,
-0x22040e,0x60002a00,0x4000000,0x1600000,0x60003000,0x24000000,0x10200000,0x60003000,0x24000000,0x10e00000,0x60003000,0x24000000,0x30200000,0x60003000,0x24000000,0x30e00000,
-0x60003700,0x24000000,0x200000,0x60003700,0x24000000,0x30200000,0x60003800,0x24000000,0x1710000,0x60003800,0x24000000,0x30200000,0x60003800,0x24000000,0xb0e00000,0x60005102,
-0x4000000,0x200000,0x60006108,0x7c00100,0x220400,0x60006108,0x7c00100,0x250400,0x60006600,0x24000020,0x200000,0x60008301,0x2802000,0x962460,0x6000903c,0x2806000,
-0x962460,0x6000903c,0x4000000,0x400000,0x60009519,0x7c00100,0x220400,0x60009519,0x7c00100,0x250400,0x6000a008,0x7c00100,0x220400,0x6000a008,0x7c00100,0x250400,
-0x6000c300,0x4000000,0x32703580,0x6000c654,0x2802000,0x962460,0x6000c654,0x4000010,0x200000,0x6000c654,0x7c00100,0x230400,0x6000c73f,0x2802000,0x962460,0x6000c73f,
-0x2802100,0x962460,0x6000c73f,0x4000000,0x200000,0x6000c73f,0x6800100,0x962540,0x6000c73f,0x6804000,0x962540,0x6000c73f,0x7c00100,0x230400,0x6000c80b,0x7c00100,
-0x230400,0x6000c941,0x2802100,0x962460,0x6000c941,0x2806000,0x962460,0x6000c941,0x4000000,0x200000,0x6000c941,0x4000010,0x200000,0x6000c941,0x6800000,0x1329800,
-0x6000c941,0x6800100,0x962540,0x6000c941,0x7c00100,0x230400,0x6000c941,0xc000010,0x448000,0x6000ca82,0x7c00100,0x230400,0x6000cc00,0x4000000,0xe00000,0x6000cc00,
-0x4000000,0x30e00000,0x6000cd00,0x4000000,0x30200000,0x6000cd00,0x4000000,0x30e00000,0x6000cd00,0x4000000,0xb0e00000,0x6000ce00,0x4000000,0x30e00000,0x6000ce00,0x4000000,
-0xb0e00000,0x6000cf00,0x4000000,0x30e00000,0x6000cf00,0x4000000,0xb0e00000,0x6000d000,0x4000000,0x200000,0x6002c300,0x4000000,0x100000,0x6002c300,0x4000000,0x10000d,
-0x6002c300,0x4000000,0x30100000,0x6002c300,0x4000100,0x150400,0x6002c300,0x4000100,0x15040d,0x6002c300,0x4000100,0x10150400,0x600a4305,0x7c00100,0xe30400,0x600ac400,
-0x4000000,0x10e0000d,0x600ac400,0x4000000,0x30e00003,0x600ac400,0x4000000,0x30e0000d,0x600acb14,0x7c00100,0xe30000,0x600acb16,0x7c00100,0xe30c00,0x600ad111,0x7c40300,
-0xe30000,0x61000a03,0x4000000,0x1600000,0x61000c02,0,0x218820,0x6100120f,0x4000000,0x200000,0x61001a18,0x7c00100,0x1830000,0x61001d0c,0x7c00100,0x230400,
-0x61001d0c,0x7c00100,0x250400,0x61006600,0x24000020,0x200000,0x61008407,0x7c00100,0x220400,0x61008407,0x7c00100,0x250400,0x6100870c,0x7c00100,0x220400,0x61008e00,
-0x24000000,0x200000,0x61008e00,0x24000000,0x400000,0x61008e00,0x24000002,0x300000,0x6100903c,0x7c00100,0x230400,0x61009519,0x7c00100,0x220400,0x61009519,0x7c00100,
-0x250400,0x61009519,0x7c00500,0x22040f,0x61009b71,0x2802100,0x962460,0x61009b71,0x2806400,0x962460,0x61009b71,0x7c00100,0x230400,0x6100a008,0x2802100,0x962460,
-0x6100c300,0x4000000,0x20000f,0x6100cd00,0x4000000,0x200000,0x6100ce00,0x4000000,0x30e00000,0x6100d202,0x2802400,0x962460,0x6100d202,0x2802500,0x962460,0x6100d202,
-0x7c00100,0x230400,0x6100d302,0x4000020,0x200000,0x6100d302,0x7c00120,0x230405,0x6100d476,0x2802100,0x962460,0x6100d476,0x2802100,0x962461,0x6100d476,0x2806400,
-0x962460,0x6100d476,0x4000000,0x400000,0x6100d476,0x6800000,0x1329800,0x6100d476,0x6800100,0x962540,0x6100d476,0x7c00100,0x230400,0x6100d476,0xc000010,0x448000,
-0x6100d573,0x2802100,0x962460,0x6100d573,0x2806400,0x962460,0x6100d573,0x6800100,0x962540,0x6100d573,0x7c00100,0x230400,0x6100d573,0x7c00900,0x230400,0x6100d573,
-0xc000010,0x448000,0x6100d68d,0x7c00100,0x230400,0x6100d756,0x7c00100,0x230400,0x6100d85c,0x2802400,0x962460,0x6100d85c,0x6800100,0x962540,0x6100d85c,0x7c00100,
-0x230400,0x6100d85c,0x7c00500,0x230400,0x6100d997,0x2802100,0x962460,0x6100d997,0x4000000,0x200000,0x6100d997,0x4000000,0x400000,0x6100d997,0x6800000,0x1329800,
-0x6100d997,0x6800100,0x962540,0x6100d997,0x6804400,0x962540,0x6100d997,0x7c00100,0x230400,0x6100d997,0xc000010,0x448000,0x6100da98,0x6800000,0x1329800,0x6100da98,
-0x7c00100,0x230400,0x6100db71,0x4000000,0x200000,0x6100dc99,0x2802100,0x962460,0x6100dc99,0x2802400,0x962460,0x6100dc99,0x6800000,0x1329800,0x6100dc99,0x6800100,
-0x962540,0x6100dc99,0x6804400,0x962540,0x6100dc99,0x7c00100,0x230400,0x610a4711,0x7c40300,0xe30000,0x610a4f11,0x7c00300,0xe30001,0x6140af75,0x7c00100,0x230400,
-0x6140af76,0x6800100,0x962540,0x6140af7f,0x7c00100,0x230400,0x6180af76,0x2802400,0x962460,0x62002a00,0x4000000,0x1600000,0x63000c00,0x80000,0x918820,0x63002800,
-0x80000,0x918820,0x7000080e,0x7c00100,0x250400,0x70000a03,0x4000000,0x200000,0x70000c00,0,0x218820,0x70000f0a,0x7c00100,0x230400,0x70001004,0x7c00100,
-0x230400,0x70001524,0x2802100,0x962460,0x70001524,0x7c00100,0x230400,0x70001615,0x2802100,0x962460,0x7000171a,0x2802100,0x962460,0x70001821,0x6800000,0x1329800,
-0x70002320,0x7c00100,0x230400,0x70002a00,0x4000000,0x1500000,0x70002a00,0x4000000,0x1600000,0x70003000,0x24000000,0x200000,0x70003000,0x24000000,0x10200000,0x70003800,
-0x24000000,0xe00000,0x70005201,0x2802400,0x962460,0x7000581e,0x7c00100,0x230400,0x70006108,0x7c00100,0x220400,0x70006108,0x7c00100,0x250400,0x70006f30,0x7c00100,
-0x230400,0x70007300,0x24000000,0x200000,0x70007f0e,0x4000000,0x200000,0x70008301,0x2802100,0x962460,0x70008301,0x2802400,0x962460,0x70008e00,0x24000000,0x200000,
-0x70008e00,0x24000000,0x400000,0x70008e00,0x24000002,0x400000,0x70008e00,0x24000008,0x1410000,0x70008e00,0x24000010,0x400000,0x70008e00,0x2c000010,0x448000,0x70009519,
-0x7c00100,0x220400,0x70009519,0x7c00100,0x230400,0x70009519,0x7c00100,0x250400,0x70009865,0x7c00100,0x230400,0x70009965,0x4000010,0x400000,0x70009965,0x7c00100,
-0x230400,0x7000a008,0x7c00100,0x220400,0x7000a008,0x7c00100,0x250400,0x7000a008,0x7c00500,0x22040f,0x7000a50e,0x4000000,0x200000,0x7000b61c,0x2802400,0x1862460,
-0x7000b61c,0x6800400,0x1862400,0x7000b61c,0x7c00100,0x1830000,0x7000c300,0x4000000,0x100000,0x7000c941,0x2806000,0x962460,0x7000cc00,0x4000000,0xe00000,0x7000cd00,
-0x4000000,0x200000,0x7000cd00,0x4000000,0xe00000,0x7000cd00,0x4000000,0x10200000,0x7000cd00,0x4000000,0x10e00000,0x7000cd00,0x4000000,0x30e00000,0x7000cd00,0x4000000,
-0x90e00000,0x7000cd00,0x4000000,0xb0e00000,0x7000ce00,0x4000000,0x30e00000,0x7000cf00,0x4000000,0xe00000,0x7000cf00,0x4000000,0x10e00000,0x7000cf00,0x4000000,0x30e00000,
-0x7000d202,0x2802100,0x962460,0x7000d202,0x7c00100,0x230400,0x7000d997,0x7c00100,0x230400,0x7000d997,0xc000010,0x248000,0x7000dd86,0x2802400,0x962460,0x7000dd86,
-0x7c00100,0x230400,0x7000dd86,0xc000010,0x448000,0x7000de9f,0x4000000,0x200000,0x7000de9f,0x7c00100,0x230400,0x7000e001,0x2000,0x962460,0x7000e001,0x2802400,
-0x962460,0x7000e187,0x2802000,0x962460,0x7000e187,0x2802100,0x962460,0x7000e187,0x4000000,0x200000,0x7000e187,0x7c00100,0x230400,0x7000e187,0xc000010,0x448000,
-0x7000e288,0x7c00100,0x230400,0x7000e300,0x4000000,0x200000,0x7000e489,0x2802100,0x962460,0x7000e489,0x2802400,0x962460,0x7000e489,0x6800100,0x962540,0x7000e489,
-0x6800100,0x962541,0x7000e489,0x6804400,0x962540,0x7000e489,0x7c00100,0x230400,0x7000e489,0x7c00900,0x230400,0x7000e59d,0x2802100,0x962460,0x7000e59d,0x2802400,
-0x962460,0x7000e59d,0x4000000,0x200000,0x7000e59d,0x4000010,0x200000,0x7000e59d,0x6800100,0x962540,0x7000e59d,0x6804400,0x962540,0x7000e59d,0x7c00100,0x230400,
-0x7000e59d,0xc000010,0x448000,0x7000e691,0x2802100,0x962460,0x7000e691,0x2802400,0x962460,0x7000e691,0x2806400,0x962460,0x7000e691,0x6800000,0x1329800,0x7000e691,
-0x6800100,0x962540,0x7000e691,0x7c00100,0x230400,0x7000e700,0x4000400,0x200000,0x7000e70e,0x7c00100,0x220400,0x7000e719,0x7c00100,0x220400,0x7000e719,0x7c00500,
-0x22040f,0x7000e853,0x7c00100,0x230400,0x7000e9a0,0x2802400,0x962460,0x7000e9a0,0x4000000,0x200000,0x7000e9a0,0x4000000,0x500000,0x7000e9a0,0x7c00100,0x230400,
-0x7000ea79,0x2802400,0x962460,0x7000ea79,0x4000000,0x200000,0x7000ea79,0x4000000,0xf00000,0x7000ea79,0x4000010,0x400000,0x7000ea79,0x7c00100,0x230400,0x7000eb8c,
-0x2802400,0x962460,0x7000eb8c,0x4000000,0x200000,0x7000eb8c,0x7c00100,0x230400,0x7000eca3,0x2802100,0x962460,0x7000eca3,0x2806400,0x962460,0x7000eca3,0x4000000,
-0x200000,0x7000eca3,0x6800000,0x1329800,0x7000eca3,0x6800100,0x962540,0x7000eca3,0x7c00100,0x230400,0x7000eca3,0xc000010,0x448000,0x7000ed95,0x6800000,0x1329800,
-0x7000ed95,0x7c00100,0x230400,0x7000ed95,0xc000010,0x448000,0x7000ee1c,0x2802400,0x1862460,0x7000ee1c,0x6800000,0x1329800,0x7000ee1c,0x7c00100,0x1830000,0x7000ee1c,
-0x7c00900,0x1830000,0x7000ef8f,0x4000000,0x200000,0x7000ef8f,0x7c00100,0x230400,0x7000f08e,0x4000000,0x200000,0x7000f08e,0x7c00100,0x230400,0x7000f159,0x2802100,
-0x962460,0x7000f159,0x7c00100,0x230400,0x7000f200,0x4000000,0x200000,0x7000f200,0x4000000,0x1200000,0x7000f200,0x4000000,0x1710000,0x7000f34b,0x2802100,0x962460,
-0x7000f34b,0x4000000,0x200000,0x7000f34b,0x4000010,0x400000,0x7000f34b,0x6800000,0x1329800,0x7000f34b,0x7c00100,0x230400,0x7000f34b,0x7c00900,0x230400,0x7000f34b,
-0xc000010,0x448000,0x7000f490,0x4000000,0x200000,0x7000f490,0x7c00100,0x230400,0x7000f5a5,0x7c00100,0x230400,0x7000f67b,0x4000000,0x200000,0x7000f67b,0x4000010,
-0x200000,0x7000f67b,0x7c00100,0x230400,0x7000f8a6,0x2802100,0x962460,0x7000f8a6,0x2802400,0x962460,0x7000f8a6,0x2806400,0x962460,0x7000f8a6,0x4000000,0x500000,
-0x7000f8a6,0x4000010,0xb00000,0x7000f8a6,0x4000800,0x200000,0x7000f8a6,0x6800100,0x962540,0x7000f8a6,0x6800100,0x962541,0x7000f8a6,0x7c00100,0x230400,0x7000f8a6,
-0xc000010,0x448000,0x7000f921,0x4000000,0x200000,0x7000fa00,0x4000000,0x200000,0x7000fb9e,0x2802100,0x962460,0x7000fb9e,0x2802400,0x962460,0x7000fb9e,0x2806400,
-0x962460,0x7000fb9e,0x4000000,0x200000,0x7000fb9e,0x6800000,0x1329800,0x7000fb9e,0x6800100,0x962540,0x7000fb9e,0x6800100,0x962541,0x7000fb9e,0x7c00100,0x230400,
-0x7000fc92,0x4000000,0x200000,0x7000fc92,0x6800000,0x1329800,0x7000fc92,0x7c00100,0x220400,0x7000fc92,0x7c00100,0x230400,0x7000fc92,0x7c00100,0x250400,0x7040dfa8,
-0x4000000,0x200000,0x7040f7aa,0x80000,0x918820,0x7080af76,0x2802400,0x962460,0x7080dfa8,0x2802400,0x962460,0x8000120f,0x7c00100,0x230400,0x80001524,0x7c00100,
-0x230400,0x8000171a,0x7c00100,0x230400,0x80002006,0x7c00100,0x220400,0x80002006,0x7c00100,0x250400,0x80002a00,0x4000000,0x1500000,0x80002d00,0x4000000,0x200000,
-0x80005208,0x2802400,0x962460,0x80005c00,0x4000000,0x200000,0x80007300,0x24000000,0x200000,0x80009519,0x7c00100,0x220400,0x80009519,0x7c00100,0x230400,0x80009519,
-0x7c00100,0x250400,0x80009865,0x7c00100,0x230400,0x8000a008,0x2802100,0x962460,0x8000b30a,0x4000000,0x500000,0x8000b30a,0x7c00100,0x230400,0x8000cd00,0x4000000,
-0xe00000,0x8000cd00,0x4000000,0x30e00000,0x8000cd00,0x4000000,0x70200000,0x8000ce00,0x4000000,0x30e00000,0x8000cf00,0x4000000,0x30e00000,0x8000d202,0x2802500,0x962460,
-0x8000d202,0x7c00100,0x230400,0x8000d68d,0x4000000,0x200000,0x8000d997,0x2802400,0x962460,0x8000d997,0x4000000,0x200000,0x8000d997,0x4000000,0x400000,0x8000d997,
-0x4000000,0x500000,0x8000d997,0x7c00100,0x230400,0x8000d997,0xc000010,0x448000,0x8000e489,0x2802100,0x962460,0x8000e489,0x7c00100,0x230400,0x8000e719,0x7c00100,
-0x220400,0x8000f8a6,0x2802100,0x962460,0x8000f8a6,0x7c00100,0x230400,0x8000f8a6,0xc000010,0x448000,0x8000fda1,0x2802100,0x1862460,0x8000fda1,0x2806400,0x1862460,
-0x8000fda1,0x4000000,0x1800000,0x8000fda1,0x6800000,0x1329800,0x8000fda1,0x6800100,0x1862540,0x8000fda1,0x7c00100,0x1830000,0x8000fda1,0xc000010,0x448000,0x8000fe9c,
-0x7c00100,0x230400,0x8000fe9c,0x7c00100,0x830400,0x8000fe9c,0x7c00100,0x1430400,0x8000ff06,0x7c00100,0x220400,0x80010165,0x7c00100,0x230400,0x800102a2,0x4000000,
-0x200000,0x800102a2,0x7c00100,0x230400,0x800103a4,0x7c00100,0x230400,0x800103a4,0xc000010,0x448000,0x8001044c,0x4000000,0x200000,0x8001044c,0x7c00100,0x220400,
-0x8001044c,0x7c00100,0x250400,0x80010500,0x4000000,0x30e00000,0x80010500,0x4000000,0xb0e00000,0x80010670,0x2802000,0x962460,0x80010670,0x4000000,0x200000,0x80010670,
-0x4000010,0x400000,0x80010670,0xc000010,0x448000,0x800a4711,0x7c40300,0xe30000,0x800b0011,0x7c40300,0xe30000};
+0x962460,0x41020701,0x2802000,0xc62460,0x410a3700,0x24000000,0x34200000,0x410a3700,0x24000000,0x34e00000,0x410a4412,0x4000000,0xe00003,0x410a4711,0x7c40300,0xe30000,
+0x410a4f11,0x7c00300,0xe30001,0x410a9100,0x4000000,0x800010,0x410a9100,0x4000000,0x810010,0x410a9100,0x4000000,0x870010,0x410a9100,0x4000000,0xb00010,0x410a9100,
+0x4000000,0xf00010,0x410a9100,0x4000000,0x1001410,0x410a9100,0x4000000,0x1071010,0x410a9100,0x4000000,0x1071410,0x410a9100,0x4000000,0x1410010,0x41408ac5,0x4000400,
+0x200000,0x414a82bf,0x4000000,0xe00000,0x41808300,0x2802000,0x962460,0x41c0147e,0x6800000,0x1329800,0x50000419,0x7c00100,0x220400,0x50000419,0x7c00100,0x250400,
+0x5000080e,0x7c00100,0x220400,0x50000908,0x7c00100,0x220400,0x50000908,0x7c00100,0x250400,0x50000b13,0x2802500,0x962460,0x50000f0a,0x7c00100,0x230400,0x50001615,
+0x2802100,0x962460,0x50001615,0x7c00100,0x230400,0x50002b01,0x2802020,0x962460,0x50002c00,0x4000000,0x200000,0x50002c19,0x7c00100,0x220400,0x50002d19,0x7c00100,
+0x220400,0x50003000,0x24000000,0x200000,0x50003000,0x24000020,0x200000,0x50003700,0x24000000,0x4200000,0x50005d00,0x7c00120,0x220405,0x50005d00,0x7c00120,0x250405,
+0x50006108,0x7c00100,0x220400,0x50006108,0x7c00100,0x250400,0x50006600,0x24000020,0x200000,0x50007300,0x24000000,0x200000,0x50008301,0x2802400,0x962460,0x50008a00,
+0x7c00500,0x230400,0x50009257,0x2802400,0x962460,0x50009257,0x4000000,0x200000,0x50009257,0x4000010,0x1071400,0x50009257,0x6800000,0x1329800,0x50009257,0x7c00100,
+0x230400,0x50009257,0x7c00500,0x230400,0x50009257,0x7c00900,0x230400,0x50009257,0xc000010,0xb48000,0x5000933e,0x2802100,0x962460,0x5000933e,0x2802400,0x962460,
+0x5000933e,0x4000000,0x200000,0x5000933e,0x4000000,0x400000,0x5000933e,0x4000010,0x400000,0x5000933e,0x6800000,0x1329800,0x5000933e,0x6800100,0x962540,0x5000933e,
+0x6800100,0x962541,0x5000933e,0x6804400,0x962540,0x5000933e,0x7c00100,0x230400,0x5000933e,0x7c00100,0x230401,0x5000933e,0xc000010,0x448000,0x50009419,0x7c00100,
+0x220400,0x50009419,0x7c00100,0x250400,0x50009500,0x4000400,0x200400,0x5000965a,0x4000000,0x500000,0x5000965a,0x7c00100,0x230400,0x5000965a,0xc000010,0xb48000,
+0x5000975b,0x4000000,0x200000,0x5000975b,0x4000010,0x400000,0x5000975b,0x7c00100,0x230400,0x50009865,0x7c00100,0x230400,0x50009965,0x4000010,0x400000,0x50009965,
+0x7c00100,0x230400,0x50409abf,0x4000000,0x200000,0x5100080e,0x7c00100,0x220400,0x5100080e,0x7c00100,0x250400,0x51000c02,0x2802100,0x962460,0x51000c02,0x4000000,
+0x1500000,0x51000c02,0x4000020,0x200000,0x51000c02,0x7c00100,0x230400,0x51000f0a,0x7c00100,0x230400,0x51000f0a,0x7c00500,0x230400,0x51001110,0x2802100,0x962460,
+0x5100131f,0x2802100,0x962460,0x51001423,0x7c00100,0x230400,0x51001524,0x2802100,0x962460,0x51001524,0x4000000,0x200000,0x51001524,0x7c00100,0x230400,0x5100171a,
+0x2802100,0x962460,0x5100171a,0x4000000,0x200000,0x5100171a,0x4000000,0x1500000,0x5100171a,0x7c00100,0x230400,0x51001b27,0x4000000,0x200000,0x51001b27,0x4000000,
+0x400000,0x51001b27,0x4000000,0x500000,0x51001b27,0x7c00100,0x230400,0x51001c1c,0x2802100,0x1862460,0x51001c1c,0x2802500,0x1862460,0x51001c1c,0x2806400,0x1862460,
+0x51001c1c,0x4000000,0x1800000,0x51001c1c,0x6800000,0x1329800,0x51001c1c,0x6800100,0x1862400,0x51001c1c,0x6800100,0x1862540,0x51001c1c,0x6800500,0x1862400,0x51001c1c,
+0x7c00100,0x1830000,0x5100251b,0x7c00100,0x230400,0x51002619,0x7c00100,0x220400,0x51002619,0x7c00100,0x250400,0x51002800,0x80020,0x218820,0x51002c00,0x4000000,
+0x200000,0x51002d19,0x7c00100,0x230400,0x51003700,0x24000000,0x4200000,0x51003700,0x24000000,0x4e00000,0x51005201,0x2802400,0x962460,0x51005c00,0x4000000,0x200000,
+0x51006108,0x7c00100,0x220400,0x51006108,0x7c00100,0x250400,0x51006600,0x24000020,0x200000,0x51006600,0x24000020,0x810000,0x51006600,0x24000020,0x1410000,0x51007300,
+0x24000000,0x200000,0x51007300,0x24000020,0x200000,0x51008002,0x7c00100,0x230400,0x51008301,0x2802000,0x962460,0x51008301,0x2802400,0x962460,0x51008a00,0x7c00500,
+0x230400,0x51008e00,0x24000000,0x200000,0x51008e00,0x24000000,0x400000,0x51008e00,0x24000000,0x810000,0x51008e00,0x24000000,0x1400000,0x51008e00,0x24000000,0x1410000,
+0x51008e00,0x24000000,0x1710000,0x51008e00,0x24000002,0x200000,0x51008e00,0x24000500,0x230400,0x51008e00,0x2c000010,0xb48000,0x51009419,0x7c00100,0x220400,0x51009419,
+0x7c00100,0x22040e,0x51009419,0x7c00100,0x22040f,0x51009419,0x7c00100,0x250400,0x51009500,0x4000400,0x200400,0x51009500,0x7c00500,0x230400,0x51009519,0x7c00100,
+0x220400,0x51009519,0x7c00100,0x22040f,0x51009519,0x7c00100,0x230400,0x51009519,0x7c00100,0x250400,0x51009b71,0x2802100,0x962460,0x51009b71,0x6800000,0x1329800,
+0x51009b71,0x6800100,0x962540,0x51009b71,0x6804400,0x962540,0x51009b71,0x7c00100,0x230400,0x51009c52,0x2802100,0x962460,0x51009c52,0x2802400,0x962460,0x51009c52,
+0x2802d00,0x962460,0x51009c52,0x4000010,0x400000,0x51009c52,0x6800000,0x1329800,0x51009c52,0x6800100,0x962540,0x51009c52,0x7c00100,0x230400,0x51009c52,0xc000010,
+0x448000,0x51009d6d,0x6800000,0x1329800,0x51009d6d,0x7c00100,0x230400,0x51009d6d,0x7c00500,0x230400,0x51009d6d,0x7c00d00,0x230400,0x51009d6d,0xc000010,0x448000,
+0x51009e08,0x2802100,0x962460,0x51009f63,0x4000010,0x400000,0x51009f63,0x6800000,0x1329800,0x51009f63,0x7c00100,0x230400,0x51009f63,0x7c00900,0x230400,0x51009f63,
+0xc000010,0x448000,0x51009f63,0xc000010,0xb48000,0x5100a008,0x2000,0x962460,0x5100a008,0x2802400,0x962460,0x5100a008,0x4000000,0x200000,0x5100a008,0x7c00100,
+0x220400,0x5100a008,0x7c00100,0x230400,0x5100a008,0x7c00100,0x250400,0x5100a008,0x7c00500,0x230400,0x5100a16f,0x2806400,0x962460,0x5100a16f,0x6800000,0x1329800,
+0x5100a16f,0x6800100,0x962540,0x5100a16f,0x7c00100,0x230400,0x5100a16f,0xc000010,0x448000,0x5100a24f,0x2802100,0x962460,0x5100a24f,0x2802400,0x962460,0x5100a24f,
+0x6800000,0x1329800,0x5100a24f,0x7c00100,0x230400,0x5100a24f,0xc000010,0x448000,0x5100a36e,0x2802100,0x962460,0x5100a36e,0x4000000,0x200000,0x5100a36e,0x6800100,
+0x962540,0x5100a36e,0x6804400,0x962540,0x5100a36e,0x7c00100,0x230400,0x5100a442,0x2802100,0x962460,0x5100a442,0x4000000,0x200000,0x5100a442,0x6800000,0x1329800,
+0x5100a442,0x6800100,0x962540,0x5100a442,0x7c00100,0x230400,0x5100a442,0xc000010,0x448000,0x5100a500,0x4000000,0x200000,0x5100a600,0x4000000,0x200000,0x5100a601,
+0x2802000,0x962460,0x5100a76b,0x7c00100,0x230400,0x5100a868,0x7c00100,0x230400,0x5100a96c,0x4000000,0x200000,0x5100a96c,0x7c00100,0x230400,0x5100aa00,0x4000000,
+0x4e00000,0x5100ab00,0x4000000,0x4e00000,0x51086600,0x24000020,0x810000,0x51086600,0x24000020,0x1410000,0x510a4005,0x7c00100,0xe30400,0x510a4711,0x7c40300,0xe30000,
+0x510a7300,0x24000000,0x34200000,0x510aaa00,0x4000000,0x34e00000,0x5140a2f3,0x4000400,0x400000,0x514a82bf,0x4000000,0xe00000,0x51802bb1,0x2802000,0x962460,0x51c00908,
+0x2802400,0x962460,0x51c0a008,0x2802400,0x962460,0x52000f0a,0x2802100,0x962460,0x52000f0a,0x6800100,0x962540,0x52000f0a,0x7c00100,0x230400,0x52001004,0x4000000,
+0x1600000,0x52001b00,0x4000000,0x200000,0x52001c1c,0x2802100,0x1862460,0x52001c1c,0x6800100,0x1862400,0x52001c1c,0x6800500,0x1862400,0x52001e12,0x7c00100,0x2230500,
+0x52001e12,0x7c00100,0x2330520,0x52002128,0x4000002,0x400000,0x52002128,0x7c00100,0x230400,0x52002a00,0x4000000,0x1500000,0x52002a00,0x4000000,0x1600000,0x52002d00,
+0x4000000,0x200006,0x52003000,0x24000000,0x200000,0x52006108,0x7c00100,0x220400,0x52006108,0x7c00100,0x250400,0x52008301,0x2802400,0x962460,0x52008407,0x2802400,
+0x962460,0x52008407,0x7c00100,0x220400,0x52008407,0x7c00100,0x250400,0x52008b3b,0x6800000,0x1800000,0x52008b3b,0x7c00100,0x1830000,0x52008e00,0x24000000,0x400000,
+0x52009419,0x7c00100,0x250400,0x5200975b,0x4000000,0x200000,0x5200ac7e,0x2802000,0x962460,0x5200ac7e,0x2802100,0x962460,0x5200ac7e,0x2802400,0x962460,0x5200ac7e,
+0x4000010,0x200000,0x5200ac7e,0x7c00100,0x230400,0x5200ac7e,0xc000010,0x248000,0x5200ad28,0x7c00100,0x230400,0x5200ae6a,0x2802100,0x1862460,0x5200ae6a,0x2802400,
+0x962460,0x5200ae6a,0x2802400,0x1862460,0x5200ae6a,0x2806000,0x1862460,0x5200ae6a,0x4000000,0x1800000,0x5200ae6a,0x6800000,0x1329800,0x5200ae6a,0x6800100,0x1862400,
+0x5200ae6a,0x6800100,0x1862540,0x5200ae6a,0x7c00100,0x1830000,0x5200ae6a,0x7c00900,0x1830000,0x5200ae6a,0xc000010,0x1848000,0x5200b083,0x4000010,0x400000,0x5200b083,
+0x7c00100,0x230400,0x5200b083,0xc000010,0x448000,0x5200b182,0x2802400,0x962460,0x5200b182,0x4000000,0x200000,0x5200b182,0x4000010,0x400000,0x5200b182,0x7c00100,
+0x230400,0x5200b182,0xc000010,0x448000,0x5200b30a,0x2802400,0x962460,0x5200b30a,0x4000000,0x200000,0x5200b30a,0x7c00100,0x230400,0x5200b54e,0x2802100,0x962460,
+0x5200b54e,0x2802400,0x962460,0x5200b54e,0x4000000,0x200000,0x5200b54e,0x4000010,0x400000,0x5200b54e,0x6800000,0x1329800,0x5200b54e,0x6800100,0x962540,0x5200b54e,
+0x6804400,0x962540,0x5200b54e,0x7c00100,0x230400,0x5200b54e,0xc000010,0x448000,0x5200b61c,0x4000000,0x1800000,0x5200b61c,0x6800500,0x1862400,0x5200b61c,0x7c00100,
+0x1830000,0x5200b61c,0x7c00900,0x1830000,0x5200b77f,0x2802100,0x1862460,0x5200b77f,0x2802400,0x1862460,0x5200b77f,0x4000000,0x1800000,0x5200b77f,0x4000010,0x1800000,
+0x5200b77f,0x7c00100,0x1830000,0x5200b77f,0x7c00500,0x1830000,0x5200b77f,0x7c00900,0x1830000,0x5200b77f,0x7e00100,0x1830000,0x5200b873,0x2802100,0x962460,0x5200b873,
+0x2806400,0x962460,0x5200b873,0x6800000,0x1329800,0x5200b873,0x6800100,0x962540,0x5200b873,0x6800400,0x962540,0x5200b873,0x7c00100,0x230400,0x5200b873,0xc000010,
+0x448000,0x5200b912,0x7c00100,0x2230500,0x5200b912,0x7c00100,0x2330520,0x5200ba74,0x4000000,0x200000,0x5200ba74,0x4000010,0x400000,0x5200ba74,0x7c00100,0x230400,
+0x5200bb85,0x4000000,0x200000,0x5200bb85,0x7c00100,0x230400,0x5200bc75,0x4000000,0x400000,0x5200bc75,0x4000010,0x400000,0x5200bc75,0x7c00100,0x230400,0x5200bd7d,
+0x4000000,0x200000,0x5200bd7d,0x7c00100,0x230400,0x5200be7a,0x4000000,0x200000,0x5200be7a,0x7c00100,0x230400,0x5200bf58,0x7c00100,0x230400,0x5200c002,0x4000000,
+0x200000,0x5200c178,0x2802000,0x962460,0x5200c178,0x2802100,0x962460,0x5200c178,0x2802400,0x962460,0x5200c178,0x2806400,0x962460,0x5200c178,0x4000000,0x200000,
+0x5200c178,0x6800100,0x962540,0x5200c178,0x7c00100,0x230400,0x5200c178,0x7c00100,0x230401,0x5200c178,0xc000010,0x448000,0x5200c178,0x80000000,0x218960,0x5200c247,
+0x7c00100,0x230400,0x5200c247,0x7c00100,0x830400,0x5200c247,0x7c00100,0x1430400,0x5200c300,0x4000000,0x200003,0x52022d00,0x4000000,0x100006,0x52023700,0x24000000,
+0x4100000,0x52023700,0x24000000,0x4e00000,0x52023700,0x24000000,0x14100000,0x52023700,0x24000000,0x14e00000,0x52023700,0x24000000,0x96800000,0x52024400,0x4000000,0x100000,
+0x52027300,0x24000000,0x100000,0x5202c300,0x4000000,0x100000,0x5202c300,0x4000000,0x100002,0x5202c300,0x4000000,0x100003,0x5202c300,0x4000000,0x10000d,0x5202c300,
+0x4000100,0x150400,0x5202c300,0x4000100,0x15040d,0x5202c300,0x4000100,0x14150400,0x520a1e12,0x7c00100,0x2130480,0x520a3700,0x24000000,0x34e00000,0x520a3800,0x24000000,
+0x34100000,0x520a4711,0x7c40300,0xe30000,0x520a4f11,0x7c00300,0xe30001,0x520a7300,0x24000000,0x34100000,0x520ab412,0x7c00100,0x2130480,0x520ac400,0x4000000,0xe00002,
+0x520ac400,0x4000000,0xe0000d,0x520ac400,0x4000000,0x34e0000d,0x520ac414,0x4000000,0xe0000d,0x520ac511,0x7c40300,0xe30000,0x5240af91,0x7c00100,0x230400,0x5240af96,
+0x4000400,0x200000,0x5240af98,0x6800400,0x962540,0x5240af98,0x7c00100,0x230400,0x5240afa2,0x7c00100,0x230400,0x5240afa4,0x7c00100,0x230400,0x5240b2c7,0x4000000,
+0x200000,0x5240b2c7,0x4000000,0x1500000,0x5240b2d2,0x4000000,0x200000,0x5240b2e0,0x4000000,0x200000,0x5240b5f6,0x7c00900,0x230400,0x524a44bf,0x4000000,0xe00003,
+0x5280af91,0x2802400,0x962460,0x5280af92,0x2802400,0x962460,0x5280af98,0x2802400,0x962460,0x5280af9a,0x2802400,0x962460,0x5280af9c,0x2802400,0x962460,0x52c0b3ed,
+0x2802400,0x962460,0x52c0b3f1,0x7c00100,0x230400,0x60000c02,0x2802100,0x962460,0x60000c02,0x7c00100,0x230400,0x60000f0a,0x2802100,0x962460,0x60000f0a,0x6800100,
+0x962540,0x60000f0a,0x7c00100,0x230400,0x6000131f,0x4000000,0x200000,0x6000171a,0x7c00100,0x230400,0x6000171a,0x7c00100,0x230560,0x60001b27,0x2802100,0x962460,
+0x60001b27,0x4000000,0xc00000,0x60001b27,0x7c00100,0x230400,0x60001f0b,0x2802400,0x962460,0x60002919,0x7c00100,0x22040e,0x60002a00,0x4000000,0x1600000,0x60003000,
+0x24000000,0x14200000,0x60003000,0x24000000,0x14e00000,0x60003700,0x24000000,0x4200000,0x60003800,0x24000000,0x1710000,0x60005102,0x4000000,0x200000,0x60006108,0x7c00100,
+0x220400,0x60006108,0x7c00100,0x250400,0x60006600,0x24000020,0x200000,0x60008301,0x2802000,0x962460,0x6000903c,0x2806000,0x962460,0x6000903c,0x4000000,0x400000,
+0x60009519,0x7c00100,0x220400,0x60009519,0x7c00100,0x250400,0x6000a008,0x7c00100,0x220400,0x6000a008,0x7c00100,0x250400,0x6000c300,0x4000000,0x3a703580,0x6000c654,
+0x2802000,0x962460,0x6000c654,0x4000010,0x200000,0x6000c654,0x7c00100,0x230400,0x6000c73f,0x2802000,0x962460,0x6000c73f,0x2802100,0x962460,0x6000c73f,0x4000000,
+0x200000,0x6000c73f,0x6800100,0x962540,0x6000c73f,0x6804000,0x962540,0x6000c73f,0x7c00100,0x230400,0x6000c80b,0x7c00100,0x230400,0x6000c941,0x2802100,0x962460,
+0x6000c941,0x2806000,0x962460,0x6000c941,0x4000000,0x200000,0x6000c941,0x4000010,0x200000,0x6000c941,0x6800000,0x1329800,0x6000c941,0x6800100,0x962540,0x6000c941,
+0x7c00100,0x230400,0x6000c941,0xc000010,0x448000,0x6000ca82,0x7c00100,0x230400,0x6000cc00,0x4000000,0x4e00000,0x6000d000,0x4000000,0x200000,0x6002c300,0x4000000,
+0x100000,0x6002c300,0x4000000,0x10000d,0x6002c300,0x4000100,0x150400,0x6002c300,0x4000100,0x15040d,0x6002c300,0x4000100,0x14150400,0x600a3000,0x24000000,0x34200000,
+0x600a3000,0x24000000,0x34e00000,0x600a3700,0x24000000,0x34200000,0x600a3800,0x24000000,0x34200000,0x600a3800,0x24000000,0xb6800000,0x600a4305,0x7c00100,0xe30400,0x600ac300,
+0x4000000,0x34100000,0x600ac400,0x4000000,0x14e0000d,0x600ac400,0x4000000,0x34e0000d,0x600acb14,0x7c00100,0xe30000,0x600acb16,0x7c00100,0xe30c00,0x600acc00,0x4000000,
+0x34e00000,0x600acd00,0x4000000,0x34200000,0x600acd00,0x4000000,0x34e00000,0x600acd00,0x4000000,0xb6800000,0x600ace00,0x4000000,0x34e00000,0x600ace00,0x4000000,0xb6800000,
+0x600acf00,0x4000000,0x34e00000,0x600acf00,0x4000000,0xb6800000,0x600ad111,0x7c40300,0xe30000,0x604ac4bf,0x4000000,0x34e00003,0x61000a03,0x4000000,0x1600000,0x61000c02,
+0x80000000,0x218960,0x6100120f,0x4000000,0x200000,0x61001a18,0x7c00100,0x1830000,0x61001d0c,0x7c00100,0x230400,0x61001d0c,0x7c00100,0x250400,0x61006600,0x24000020,
+0x200000,0x61008407,0x7c00100,0x220400,0x61008407,0x7c00100,0x250400,0x6100870c,0x7c00100,0x220400,0x61008e00,0x24000000,0x200000,0x61008e00,0x24000000,0x400000,
+0x61008e00,0x24000002,0x300000,0x6100903c,0x7c00100,0x230400,0x61009519,0x7c00100,0x220400,0x61009519,0x7c00100,0x250400,0x61009519,0x7c00500,0x22040f,0x61009b71,
+0x2802100,0x962460,0x61009b71,0x2806400,0x962460,0x61009b71,0x7c00100,0x230400,0x6100a008,0x2802100,0x962460,0x6100c300,0x4000000,0x20000f,0x6100cd00,0x4000000,
+0x200000,0x6100d202,0x2802400,0x962460,0x6100d202,0x2802500,0x962460,0x6100d202,0x7c00100,0x230400,0x6100d302,0x4000020,0x200000,0x6100d302,0x7c00120,0x230405,
+0x6100d476,0x2802100,0x962460,0x6100d476,0x2802100,0x962461,0x6100d476,0x2806400,0x962460,0x6100d476,0x4000000,0x400000,0x6100d476,0x6800000,0x1329800,0x6100d476,
+0x6800100,0x962540,0x6100d476,0x7c00100,0x230400,0x6100d476,0xc000010,0x448000,0x6100d573,0x2802100,0x962460,0x6100d573,0x2806400,0x962460,0x6100d573,0x6800100,
+0x962540,0x6100d573,0x7c00100,0x230400,0x6100d573,0x7c00900,0x230400,0x6100d573,0xc000010,0x448000,0x6100d68d,0x7c00100,0x230400,0x6100d756,0x7c00100,0x230400,
+0x6100d85c,0x2802500,0x962460,0x6100d85c,0x6800100,0x962540,0x6100d85c,0x7c00100,0x230400,0x6100d85c,0x7c00500,0x230400,0x6100d997,0x2802100,0x962460,0x6100d997,
+0x4000000,0x200000,0x6100d997,0x4000000,0x400000,0x6100d997,0x6800000,0x1329800,0x6100d997,0x6800100,0x962540,0x6100d997,0x6804400,0x962540,0x6100d997,0x7c00100,
+0x230400,0x6100d997,0x7c00100,0x230560,0x6100d997,0xc000010,0x448000,0x6100da98,0x6800000,0x1329800,0x6100da98,0x7c00100,0x230400,0x6100db71,0x4000000,0x200000,
+0x6100dc99,0x2802100,0x962460,0x6100dc99,0x2802400,0x962460,0x6100dc99,0x6800000,0x1329800,0x6100dc99,0x6800100,0x962540,0x6100dc99,0x6804400,0x962540,0x6100dc99,
+0x7c00100,0x230400,0x610a4711,0x7c40300,0xe30000,0x610a4f11,0x7c00300,0xe30001,0x610ace00,0x4000000,0x34e00000,0x6140af96,0x7c00100,0x230400,0x6140af98,0x7c00100,
+0x230400,0x6180af93,0x2802400,0x962460,0x62002a00,0x4000000,0x1600000,0x63002800,0x80000,0x918820,0x63c00c14,0x80000,0x918820,0x7000080e,0x7c00100,0x250400,
+0x70000a03,0x4000000,0x200000,0x70000c00,0x80000000,0x218960,0x70000f0a,0x7c00100,0x230400,0x70001004,0x7c00100,0x230400,0x70001524,0x2802100,0x962460,0x70001524,
+0x7c00100,0x230400,0x70001615,0x2802100,0x962460,0x7000171a,0x2802100,0x962460,0x70001821,0x6800000,0x1329800,0x70002320,0x7c00100,0x230400,0x70002a00,0x4000000,
+0x1500000,0x70002a00,0x4000000,0x1600000,0x70003000,0x24000000,0x200000,0x70003000,0x24000000,0x14200000,0x70003800,0x24000000,0x4e00000,0x70005201,0x2802400,0x962460,
+0x7000581e,0x7c00100,0x230400,0x70006108,0x7c00100,0x220400,0x70006108,0x7c00100,0x250400,0x70006f30,0x7c00100,0x230400,0x70007300,0x24000000,0x200000,0x70007f0e,
+0x4000000,0x200000,0x70008301,0x2802100,0x962460,0x70008301,0x2802400,0x962460,0x70008e00,0x24000000,0x200000,0x70008e00,0x24000000,0x400000,0x70008e00,0x24000002,
+0x400000,0x70008e00,0x24000008,0x1410000,0x70008e00,0x24000010,0x400000,0x70008e00,0x2c000010,0x448000,0x70009519,0x7c00100,0x220400,0x70009519,0x7c00100,0x230400,
+0x70009519,0x7c00100,0x250400,0x70009865,0x7c00100,0x230400,0x70009965,0x4000010,0x400000,0x70009965,0x7c00100,0x230400,0x7000a008,0x7c00100,0x220400,0x7000a008,
+0x7c00100,0x250400,0x7000a008,0x7c00500,0x22040f,0x7000a50e,0x4000000,0x200000,0x7000b61c,0x2802500,0x1862460,0x7000b61c,0x6800500,0x1862400,0x7000b61c,0x7c00100,
+0x1830000,0x7000c300,0x4000000,0x100000,0x7000c941,0x2806000,0x962460,0x7000cc00,0x4000000,0x4e00000,0x7000cd00,0x4000000,0x200000,0x7000cd00,0x4000000,0x4200000,
+0x7000cd00,0x4000000,0x4e00000,0x7000cd00,0x4000000,0x14200000,0x7000cd00,0x4000000,0x14e00000,0x7000cd00,0x4000000,0x96800000,0x7000cf00,0x4000000,0x4e00000,0x7000cf00,
+0x4000000,0x14e00000,0x7000d202,0x2802100,0x962460,0x7000d202,0x7c00100,0x230400,0x7000d997,0x7c00100,0x230400,0x7000d997,0xc000010,0x248000,0x7000dd86,0x2802400,
+0x962460,0x7000dd86,0x7c00100,0x230400,0x7000dd86,0xc000010,0x448000,0x7000de9f,0x4000000,0x200000,0x7000de9f,0x7c00100,0x230400,0x7000e001,0x2000,0x962460,
+0x7000e001,0x2802400,0x962460,0x7000e187,0x2802000,0x962460,0x7000e187,0x2802100,0x962460,0x7000e187,0x4000000,0x200000,0x7000e187,0x7c00100,0x230400,0x7000e187,
+0xc000010,0x448000,0x7000e288,0x7c00100,0x230400,0x7000e300,0x4000000,0x200000,0x7000e489,0x2802100,0x962460,0x7000e489,0x2802400,0x962460,0x7000e489,0x6800100,
+0x962540,0x7000e489,0x6800100,0x962541,0x7000e489,0x6804400,0x962540,0x7000e489,0x7c00100,0x230400,0x7000e489,0x7c00900,0x230400,0x7000e59d,0x2802100,0x962460,
+0x7000e59d,0x2802400,0x962460,0x7000e59d,0x4000000,0x200000,0x7000e59d,0x4000010,0x200000,0x7000e59d,0x6800100,0x962540,0x7000e59d,0x6804400,0x962540,0x7000e59d,
+0x7c00100,0x230400,0x7000e59d,0xc000010,0x448000,0x7000e691,0x2802100,0x962460,0x7000e691,0x2802400,0x962460,0x7000e691,0x2806400,0x962460,0x7000e691,0x6800000,
+0x1329800,0x7000e691,0x6800100,0x962540,0x7000e691,0x7c00100,0x230400,0x7000e700,0x4000400,0x200400,0x7000e70e,0x7c00100,0x220400,0x7000e719,0x7c00100,0x220400,
+0x7000e719,0x7c00500,0x22040f,0x7000e853,0x7c00100,0x230400,0x7000e9a0,0x2802400,0x962460,0x7000e9a0,0x4000000,0x200000,0x7000e9a0,0x4000000,0x500000,0x7000e9a0,
+0x7c00100,0x230400,0x7000ea79,0x2802400,0x962460,0x7000ea79,0x4000000,0x200000,0x7000ea79,0x4000000,0xf00000,0x7000ea79,0x4000010,0x400000,0x7000ea79,0x7c00100,
+0x230400,0x7000eb8c,0x2802400,0x962460,0x7000eb8c,0x4000000,0x200000,0x7000eb8c,0x7c00100,0x230400,0x7000eca3,0x2802100,0x962460,0x7000eca3,0x2806400,0x962460,
+0x7000eca3,0x4000000,0x200000,0x7000eca3,0x6800000,0x1329800,0x7000eca3,0x6800100,0x962540,0x7000eca3,0x7c00100,0x230400,0x7000eca3,0xc000010,0x448000,0x7000ed95,
+0x6800000,0x1329800,0x7000ed95,0x7c00100,0x230400,0x7000ed95,0xc000010,0x448000,0x7000ee1c,0x2802500,0x1862460,0x7000ee1c,0x6800000,0x1329800,0x7000ee1c,0x7c00100,
+0x1830000,0x7000ee1c,0x7c00900,0x1830000,0x7000ef8f,0x4000000,0x200000,0x7000ef8f,0x7c00100,0x230400,0x7000f08e,0x4000000,0x200000,0x7000f08e,0x7c00100,0x230400,
+0x7000f159,0x2802100,0x962460,0x7000f159,0x7c00100,0x230400,0x7000f200,0x4000000,0x200000,0x7000f200,0x4000000,0x1200000,0x7000f200,0x4000000,0x1710000,0x7000f34b,
+0x2802400,0x962460,0x7000f34b,0x4000000,0x200000,0x7000f34b,0x4000010,0x400000,0x7000f34b,0x6800000,0x1329800,0x7000f34b,0x7c00100,0x230400,0x7000f34b,0x7c00900,
+0x230400,0x7000f34b,0xc000010,0x448000,0x7000f490,0x4000000,0x200000,0x7000f490,0x7c00100,0x230400,0x7000f5a5,0x7c00100,0x230400,0x7000f67b,0x4000000,0x200000,
+0x7000f67b,0x4000010,0x200000,0x7000f67b,0x7c00100,0x230400,0x7000f8a6,0x2802100,0x962460,0x7000f8a6,0x2802400,0x962460,0x7000f8a6,0x2806400,0x962460,0x7000f8a6,
+0x4000000,0x500000,0x7000f8a6,0x4000010,0xb00000,0x7000f8a6,0x4000800,0x200000,0x7000f8a6,0x6800100,0x962540,0x7000f8a6,0x6800100,0x962541,0x7000f8a6,0x7c00100,
+0x230400,0x7000f8a6,0xc000010,0x448000,0x7000f921,0x4000000,0x200000,0x7000fa00,0x4000000,0x200000,0x7000fb9e,0x2802100,0x962460,0x7000fb9e,0x2802400,0x962460,
+0x7000fb9e,0x2806400,0x962460,0x7000fb9e,0x4000000,0x200000,0x7000fb9e,0x6800000,0x1329800,0x7000fb9e,0x6800100,0x962540,0x7000fb9e,0x6800100,0x962541,0x7000fb9e,
+0x7c00100,0x230400,0x7000fc92,0x4000000,0x200000,0x7000fc92,0x6800000,0x1329800,0x7000fc92,0x7c00100,0x220400,0x7000fc92,0x7c00100,0x230400,0x7000fc92,0x7c00100,
+0x250400,0x700acd00,0x4000000,0x34e00000,0x700acd00,0x4000000,0xb6800000,0x700ace00,0x4000000,0x34e00000,0x700acf00,0x4000000,0x34e00000,0x700acf00,0x4000000,0xb6800000,
+0x7050df01,0x4000000,0x200000,0x7050f705,0x80000,0x918820,0x7080af96,0x2802400,0x962460,0x7090df01,0x2802400,0x962460,0x70d0e403,0x2802100,0x962460,0x70d0e403,
+0x2802400,0x962460,0x70d0e403,0x6800100,0x962540,0x8000120f,0x7c00100,0x230400,0x80001524,0x7c00100,0x230400,0x8000171a,0x7c00100,0x230400,0x80002006,0x7c00100,
+0x220400,0x80002006,0x7c00100,0x250400,0x80002a00,0x4000000,0x1500000,0x80002d00,0x4000000,0x200000,0x80005208,0x2802400,0x962460,0x80005c00,0x4000000,0x200000,
+0x80007300,0x24000000,0x200000,0x80009519,0x7c00100,0x220400,0x80009519,0x7c00100,0x230400,0x80009519,0x7c00100,0x250400,0x80009865,0x7c00100,0x230400,0x8000a008,
+0x2802100,0x962460,0x8000b30a,0x4000000,0x500000,0x8000b30a,0x7c00100,0x230400,0x8000cd00,0x4000000,0x4e00000,0x8000d202,0x2802500,0x962460,0x8000d202,0x7c00100,
+0x230400,0x8000d68d,0x4000000,0x200000,0x8000d997,0x2802000,0x962460,0x8000d997,0x2802400,0x962460,0x8000d997,0x4000000,0x400000,0x8000d997,0x4000000,0x500000,
+0x8000d997,0x7c00100,0x230400,0x8000d997,0xc000010,0x448000,0x8000e489,0x2802100,0x962460,0x8000e489,0x7c00100,0x230400,0x8000e719,0x7c00100,0x220400,0x8000f8a6,
+0x2802100,0x962460,0x8000f8a6,0x7c00100,0x230400,0x8000f8a6,0xc000010,0x448000,0x8000fda1,0x2802100,0x1862460,0x8000fda1,0x2806400,0x1862460,0x8000fda1,0x4000000,
+0x1800000,0x8000fda1,0x6800000,0x1329800,0x8000fda1,0x6800100,0x1862540,0x8000fda1,0x7c00100,0x1830000,0x8000fda1,0xc000010,0x448000,0x8000fe9c,0x7c00100,0x230400,
+0x8000fe9c,0x7c00100,0x830400,0x8000fe9c,0x7c00100,0x1430400,0x8000ff06,0x7c00100,0x220400,0x80010165,0x7c00100,0x230400,0x800102a2,0x4000000,0x200000,0x800102a2,
+0x7c00100,0x230400,0x800103a4,0x7c00100,0x230400,0x800103a4,0xc000010,0x448000,0x8001044c,0x4000000,0x200000,0x8001044c,0x7c00100,0x220400,0x8001044c,0x7c00100,
+0x250400,0x80010670,0x2802000,0x962460,0x80010670,0x4000000,0x200000,0x80010670,0x4000010,0x400000,0x80010670,0xc000010,0x448000,0x800a4711,0x7c40300,0xe30000,
+0x800acd00,0x4000000,0x34e00000,0x800acd00,0x4000000,0x7a902460,0x800ace00,0x4000000,0x34e00000,0x800acf00,0x4000000,0x34e00000,0x800b0011,0x7c40300,0xe30000,0x800b0500,
+0x4000000,0x34e00000,0x800b0500,0x4000000,0xb6800000,0x90001615,0x7c00100,0x230400,0x9000171a,0x4000000,0x200000,0x9000171a,0x7c00100,0x230400,0x90003000,0x24000000,
+0x200000,0x90007f0e,0x4000000,0x200000,0x90008301,0x2802000,0x962460,0x90008e00,0x24000000,0x400000,0x90009519,0x7c00100,0x250400,0x9000a16f,0x2802100,0x962460,
+0x9000d200,0x80000000,0x218960,0x9000d202,0x2802000,0x962460,0x9000d202,0x2802100,0x962460,0x9000d202,0x7c00100,0x230400,0x9000e59d,0x2802100,0x962460,0x90010500,
+0x4000000,0xe00000,0x900107a7,0x2802100,0x962460,0x900107a7,0x2802400,0x962460,0x900107a7,0x2802c00,0x962460,0x900107a7,0x4000000,0x1400000,0x900107a7,0x6800000,
+0x1329800,0x900107a7,0x7c00100,0x220400,0x900107a7,0x7c00100,0x250400,0x900108a8,0x2802100,0x962460,0x900108a8,0x2806400,0x962460,0x900108a8,0x4000000,0x200000,
+0x900108a8,0x4000000,0x400000,0x900108a8,0x4000010,0x400000,0x900108a8,0x6800000,0x1329800,0x900108a8,0x6800100,0x962540,0x900108a8,0x7c00100,0x230400,0x900108a8,
+0xc000010,0x448000,0x90010908,0x7c00100,0x220400,0x90010a38,0x2802100,0x962460,0x90010ca9,0x2802100,0x962460,0x90010ca9,0x4000000,0x500000,0x90010ca9,0x4000010,
+0xb00000,0x90010ca9,0x6800100,0x962540,0x90010ca9,0x7c00100,0x230400,0x90010d1b,0x4000000,0x500000,0x90010eaa,0x2802100,0x962460,0x90010eaa,0x2802400,0x962460,
+0x90010eaa,0x2806400,0x962460,0x90010eaa,0x4000000,0x200000,0x90010eaa,0x4000000,0x400000,0x90010eaa,0x4000010,0x400000,0x90010eaa,0x6800000,0x1329800,0x90010eaa,
+0x6800100,0x962540,0x90010eaa,0x7c00100,0x230400,0x90010eaa,0xc000010,0x448000,0x90010fab,0x7c00100,0x220400,0x90010fab,0x7c00100,0x250400,0x9002c300,0x4000000,
+0x100000,0x900ac400,0x4000000,0xe0000d,0x900acd00,0x4000000,0x34e00000,0x900acd00,0x4000000,0xb6800000,0x900acf00,0x4000000,0x34e00000,0x900b0500,0x4000000,0x34e00000,
+0x900b0500,0x4000000,0xb6800000,0x900b0b9a,0x7c00900,0x1230400,0x900b109a,0x7c00300,0xe30000,0x900b119a,0x7c00300,0xe30000,0x90408e06,0x24000000,0x400000,0xa0001004,
+0x4000000,0x200000,0xa0001004,0x7c00100,0x230400,0xa000120f,0x2802100,0x962460,0xa000120f,0x2802400,0x962460,0xa000171a,0x2802100,0x962460,0xa000171a,0x2806400,
+0x962460,0xa0002a00,0x4000000,0x1600000,0xa0003000,0x24000000,0x200000,0xa000581e,0x7c00100,0x230400,0xa0007300,0x24000000,0x200000,0xa0008301,0x2802400,0x962460,
+0xa0008e00,0x24000000,0x400000,0xa000cf00,0x4000000,0x4e00000,0xa0010500,0x4000000,0x200000,0xa00114af,0x2802100,0x962460,0xa00114af,0x2802400,0x962460,0xa00114af,
+0x2806400,0x962460,0xa00114af,0x6800000,0x1329800,0xa00114af,0x7c00100,0x230400,0xa00114af,0x7c00100,0x230560,0xa00116b0,0x2802100,0x962460,0xa00116b0,0x2802800,
+0x962460,0xa00116b0,0x2806400,0x962460,0xa00116b0,0x4000000,0x400000,0xa00116b0,0x4000000,0x500000,0xa00116b0,0x4000010,0x400000,0xa00116b0,0x6800100,0x962540,
+0xa00116b0,0x7c00100,0x230400,0xa00116b0,0x7c00100,0x230560,0xa00116b0,0xc000010,0x448000,0xa0011722,0x7c00100,0x230400,0xa00118b1,0x2802000,0x962460,0xa00118b1,
+0x2802100,0x962460,0xa00118b1,0x2806400,0x962460,0xa00118b1,0x4000000,0x200000,0xa00118b1,0x4000000,0x400000,0xa00118b1,0x4000000,0x500000,0xa00118b1,0x6800100,
+0x962540,0xa00118b1,0x7c00100,0x230400,0xa00118b1,0x7c00100,0x230560,0xa00118b1,0xc000010,0x448000,0xa00a4005,0x7c00100,0xe30400,0xa00a4711,0x7c40300,0xe30000,
+0xa00ac400,0x4000000,0x4e00000,0xa00acb14,0x7c00100,0xe30000,0xa00acf00,0x4000000,0x34e00000,0xa00b0500,0x4000000,0x34e00000,0xa00b0500,0x4000000,0xb6800000,0xa00b0b96,
+0x7c00900,0x1230400,0xa00b1211,0x7c40300,0xe30000,0xa00b1314,0x7c00100,0xe30000,0xa00b1596,0x7c00300,0xe30000,0xa040afac,0x6800400,0x962540,0xa08083ad,0x2802400,
+0x962460,0xb0000a03,0x7c00100,0x220400,0xb0000b13,0x7c00100,0x2633800,0xb0001004,0x2802000,0x962460,0xb0001110,0x4000000,0x200000,0xb0001524,0x2802000,0x962460,
+0xb0001615,0x4000000,0x500000,0xb000251b,0x7c00100,0x230400,0xb0007300,0x24000000,0x200000,0xb0008939,0x4000000,0x200000,0xb0008939,0x7c00100,0x230400,0xb0008e00,
+0x24000000,0x200000,0xb0008e00,0x24000000,0x400000,0xb0008e00,0x24000010,0x400000,0xb0009257,0x2802000,0x962460,0xb0009257,0x4000000,0x1600000,0xb0009519,0x7c00100,
+0x220400,0xb0009519,0x7c00100,0x250400,0xb0009a00,0x4000000,0x200000,0xb000b30a,0x2802100,0x962460,0xb000b30a,0x7c00100,0x230400,0xb000c178,0x80000000,0x218960,
+0xb000c300,0x4000000,0x4200000,0xb000d202,0x2802000,0x962460,0xb000d476,0x6800100,0x962540,0xb000d476,0x7c00100,0x230400,0xb000e300,0x4000000,0x4e00000,0xb000fda1,
+0x7c00100,0x1830000,0xb0010eaa,0x2802000,0x962460,0xb00116b0,0x7c00100,0x230400,0xb0011900,0x4000000,0x4e00000,0xb0011ab2,0x2802100,0x962460,0xb0011ab2,0x2802400,
+0x962460,0xb0011ab2,0x2806400,0x962460,0xb0011ab2,0x4000000,0x200000,0xb0011ab2,0x6800100,0x962540,0xb0011ab2,0x7c00100,0x230400,0xb0011b0c,0x7c00100,0x230400,
+0xb0011cb3,0x2802100,0x962460,0xb0011cb3,0x2806400,0x962460,0xb0011cb3,0x6800000,0x1329800,0xb0011cb3,0x6800100,0x962540,0xb0011cb3,0x7c00100,0x230400,0xb0011db6,
+0x2802500,0x962460,0xb0011db6,0x6800000,0x1329800,0xb0011db6,0x7c00100,0x230400,0xb0011db6,0x7c00500,0x230400,0xb0011e00,0x4000000,0x200000,0xb0011e00,0x4000000,
+0x1500000,0xb0011fb4,0x2802100,0x962460,0xb0011fb4,0x6800100,0x962540,0xb0011fb4,0x7c00100,0x230400,0xb0011fb4,0xc000010,0x248000,0xb0012000,0x4000000,0x200000,
+0xb00121b5,0x4000000,0x200000,0xb00121b5,0x4000010,0x400000,0xb00121b5,0x7c00100,0x220400,0xb00121b5,0x7c00100,0x250400,0xb00121b5,0xc000010,0x448000,0xb00122b8,
+0x4000000,0x200000,0xb00122b8,0x7c00100,0x230400,0xb00123b7,0x2802400,0x962460,0xb00123b7,0x4000000,0x200000,0xb00123b7,0x7c00100,0x230400,0xb00123b7,0xc000010,
+0x248000,0xb00a4005,0x7c00100,0xe30400,0xb00a4711,0x7c40300,0xe30000,0xb00acf00,0x4000000,0x34e00000,0xb00b0500,0x4000000,0x34e00000,0xb00b0500,0x4000000,0x3ce00000,
+0xb00b0500,0x4000000,0xb6800000,0xb00b109a,0x7c00300,0xe30000,0xb080e47c,0x2802000,0x962460,0xc0001524,0x4000000,0x500000,0xc0001a18,0x2806400,0x1862460,0xc0001a18,
+0x7c00100,0x1830000,0xc0007300,0x24000000,0x200000,0xc0008e00,0x24000010,0x400000,0xc0009519,0x7c00100,0x220400,0xc0009519,0x7c00100,0x250400,0xc000c300,0x4000000,
+0x420000f,0xc000d85c,0x2802100,0x962460,0xc000d85c,0x6800100,0x962540,0xc000d85c,0x7c00100,0x230400,0xc000dc99,0x7c00100,0x230400,0xc000e719,0x7c00100,0x220400,
+0xc00107a7,0x7c00100,0x230400,0xc0010eaa,0x7c00100,0x230400,0xc00116b0,0x7c00100,0x230560,0xc0011900,0x4000000,0x4200000,0xc0012447,0,0x818820,0xc0012447,
+0,0xc18820,0xc0012447,0,0x1418820,0xc00125b9,0x7c00100,0x230400,0xc00126bb,0x2802100,0x962460,0xc00126bb,0x2806400,0x962460,0xc00126bb,0x4000000,
+0x500000,0xc00126bb,0x6800100,0x962540,0xc00126bb,0x7c00100,0x230400,0xc00127ba,0x2802400,0x962460,0xc00127ba,0x4000000,0x200000,0xc00127ba,0x6800000,0x1329800,
+0xc00127ba,0x7c00100,0x230400,0xc00127ba,0x7c00900,0x230400,0xc0012800,0x4000000,0x200000,0xc0012b23,0x4000000,0x200000,0xc0012b23,0x4000000,0x400000,0xc0012b23,
+0x4000000,0x1500000,0xc0012cbc,0x2802400,0x962460,0xc0012cbc,0x4000000,0x1600000,0xc0012cbc,0x6800000,0x1329800,0xc0012cbc,0x7c00100,0x230400,0xc00acf00,0x4000000,
+0x34e00000,0xc00ae300,0x4000000,0x34e00000,0xc00b0500,0x4000000,0x34e00000,0xc00b0500,0x4000000,0xb6800000,0xc00b0b00,0x4000000,0x1200000,0xc00b0b00,0x7c00900,0x1230400,
+0xc00b109a,0x7c00300,0xe30000,0xc00b2914,0x7c00100,0x2530000,0xc00b2916,0x7c00100,0x2530c00,0xc00b2a00,0x4000000,0x34e00000,0xc040af53,0x7c00100,0x230400,0xc0c12b7e,
+0x4000000,0x200000,0xc14a44bf,0x4000000,0xe0000d,0xd000131f,0x2802c00,0x962460,0xd000171a,0x7c00100,0x230400,0xd0001821,0x2802100,0x962460,0xd0007300,0x24000000,
+0x200000,0xd0008e00,0x24000000,0x200000,0xd0008f3a,0x2806000,0x962460,0xd0009519,0x7c00100,0x220400,0xd0009519,0x7c00100,0x250400,0xd000a500,0x4000000,0x200000,
+0xd000c300,0x4000000,0x4e00000,0xd000d202,0x7c00100,0x230400,0xd000d476,0x7c00100,0x230400,0xd000d997,0x2802100,0x962460,0xd000d997,0x6800100,0x962540,0xd000e001,
+0x2802100,0x962460,0xd000e700,0x4000400,0x200000,0xd000e719,0x7c00100,0x220400,0xd000e719,0x7c00500,0x23040f,0xd000fa00,0x4000000,0x4e00000,0xd0010eaa,0x4000010,
+0x400000,0xd0010eaa,0x7c00100,0x230400,0xd0012dbd,0x4000000,0x200000,0xd0012dbd,0x7c00100,0x230400,0xd0012fbe,0x2802100,0x962460,0xd0012fbe,0x2802400,0x962460,
+0xd0012fbe,0x2806400,0x962460,0xd0012fbe,0x4000000,0x400000,0xd0012fbe,0x6800000,0x1329800,0xd0012fbe,0x6800100,0x962540,0xd0012fbe,0x6800100,0x962541,0xd0012fbe,
+0x6804400,0x962540,0xd0012fbe,0x7c00100,0x230400,0xd0012fbe,0x7c00100,0x230560,0xd0012fbe,0xc000010,0x448000,0xd0013183,0x7c00100,0x230400,0xd0013200,0x4000000,
+0x200000,0xd0013200,0x6800000,0x1329805,0xd00134c0,0x2802100,0x962460,0xd00134c0,0x4000002,0x400000,0xd00134c0,0x7c00100,0x230400,0xd00a4305,0x7c00100,0xe30400,
+0xd00a4611,0x7c40300,0xe30000,0xd00a4711,0x7c40300,0xe30000,0xd00a5e11,0x7c40300,0xe30000,0xd00acf00,0x4000000,0x34e00000,0xd00b0500,0x4000000,0x34e00000,0xd00b0500,
+0x4000000,0xb6800000,0xd00b0b11,0x6800500,0x962540,0xd00b0bbf,0x2802200,0xc62460,0xd00b119a,0x7c00300,0xe30000,0xd00b2a00,0x4000000,0x34e00000,0xd00b2e11,0x7c40300,
+0xe30000,0xd00b30bf,0x7c00300,0x230000,0xd00b339a,0x7c00300,0xe30000};
 
-static const int32_t countPropsVectors=5931;
+static const int32_t countPropsVectors=6999;
 static const int32_t propsVectorsColumns=3;
-static const uint16_t scriptExtensions[172]={
-0x800e,0x8019,8,0x8059,8,2,8,0x8019,8,0x8038,8,8,3,0x800c,2,0x22,
-0x8025,2,0x22,0x54,0x79,0x807b,2,0x8022,2,0x8025,2,0x18,4,0xa,0xf,0x10,
-0x15,0x19,0x1a,0x1f,0x23,0x24,0x89,0x8097,4,0xa,0xf,0x10,0x15,0x19,0x1a,0x1f,
-0x23,0x24,0x8089,4,0xa,0xf,0x10,0x15,0x1a,0x1f,0x21,0x23,0x24,0x3a,0x89,0x91,
-0x99,0x9e,0x80a0,4,0xa,0xf,0x10,0x15,0x1a,0x1f,0x21,0x23,0x24,0x30,0x3a,0x89,
-0x91,0x99,0x9e,0x80a0,0xa,0x78,0x80a0,0xa,0x54,4,0x3a,0x8076,4,0x59,0x10,0x80a4,
-0x10,0x5e,0xf,0x809d,0xf,0x62,0x23,0x8089,0x23,0x66,0x1c,0x34,0x8076,0x1c,0x6a,0x2a,
-0x2b,0x2c,0x802d,0x1b,0x805a,0x800a,0xa,0x8089,0xa,0x8097,0xa,0x15,0x1a,0x23,0x8024,0xa,
-0x8015,0xa,0x19,0x8089,5,0x11,0x12,0x14,0x16,0x8029,5,0x11,0x12,0x14,0x8016,0x11,
-0x14,0x8016,5,0x8011,0xa,0xf,0x10,0x78,0x91,0x99,0x9e,0xa0,0x80a3,0xa,0x8023,0xa,
-0x9d,0x19,0x1c,0x804f,0x37,0x804e,0x2f,0x8031,2,0x8007,0x8087,0};
+static const uint16_t scriptExtensions[262]={
+0x800e,0x8019,8,0x8059,8,2,8,0x8038,8,6,8,0x8019,2,0x22,0x25,0xb6,
+0x80c0,2,0x22,0x8025,2,0x11,2,0x22,0x54,0x79,0x7b,0xa7,0xb6,0x80b7,2,0x8022,
+2,0x25,0x80c0,2,0x20,2,0x80b6,4,0xa,0xf,0x10,0x15,0x19,0x1a,0x1f,0x23,
+0x24,0x89,0x97,0x809e,4,0xa,0xf,0x10,0x15,0x19,0x1a,0x1f,0x23,0x24,0x89,0x809e,
+4,0xa,0xf,0x10,0x15,0x1a,0x1f,0x21,0x23,0x24,0x3a,0x89,0x91,0x99,0x9e,0xa0,
+0xaf,0xb2,0xb3,0x80bb,4,0xa,0xf,0x10,0x15,0x1a,0x1f,0x21,0x23,0x24,0x30,0x3a,
+0x89,0x91,0x99,0x9e,0xa0,0xaf,0xb2,0xb3,0x80bb,0xa,0x78,0xa0,0x80b2,0xa,0x69,4,
+0x3a,0x8076,4,0x6f,0x10,0x80a4,0x10,0x74,0xf,0x809d,0xf,0x78,0x23,0x8089,0x23,0x7c,
+0x15,0x80bb,0x15,0x80,0x1c,0x34,0x8076,0x1c,0x84,0xc,0x8019,0x2a,0x2b,0x2c,0x802d,0x1b,
+0x805a,0x800a,4,0xa,0x15,0x8089,0xa,0x8089,4,0x800a,0xa,0x8097,0xa,0x15,0x1a,0x1f,
+0x23,0x8024,0xa,0x80bb,4,0xa,0x15,0x1f,0x24,0x89,0x9e,0x80bb,0x8004,8,0x8022,0x19,
+0x801b,0xa,0x19,0x8089,5,0x11,0x12,0x14,0x16,0x8029,5,0x11,0x12,0x14,0x8016,0x8011,
+5,0x8011,0x11,0x14,0x8016,0x11,0x8019,0xa,0xf,0x10,0x78,0x91,0x99,0x9d,0x9e,0xa0,
+0xa3,0x80b2,0xa,0xf,0x10,0x15,0x1a,0x78,0x91,0x99,0x9d,0x9e,0xa0,0xa3,0xb2,0x80bb,
+0xa,0xf,0x10,0x15,0x78,0x91,0x99,0x9d,0x9e,0xa0,0xa3,0xb2,0x80bb,0xa,0x98,0xa,
+0x8023,0xa,0xef,0x19,0x1c,0x804f,0x37,0x804e,2,0x8025,2,0xf8,0x2f,0x31,0x8053,0x2f,
+0x8031,2,0x8007,0x89,0x7c,0x8087};
 
-static const int32_t indexes[UPROPS_INDEX_COUNT]={0x26ca,0x26ca,0x26ca,0x26ca,0x5c6c,3,0x7397,0x73ed,0x73ed,0x73ed,0xb06a6,0x2774191,0,0,0,0};
+static const int32_t indexes[UPROPS_INDEX_COUNT]={0x2b96,0x2b96,0x2b96,0x2b96,0x6898,3,0x83ef,0x8472,0x8472,0x8472,0xb34c0,0x2a75a31,0,0,0,0};
 
+#endif  // INCLUDED_FROM_UCHAR_C
diff --git a/src/third_party/icu/source/common/ucharstrie.cpp b/src/third_party/icu/source/common/ucharstrie.cpp
index 03732c7..011075e 100644
--- a/src/third_party/icu/source/common/ucharstrie.cpp
+++ b/src/third_party/icu/source/common/ucharstrie.cpp
@@ -1,10 +1,12 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *   Copyright (C) 2010-2011, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *******************************************************************************
 *   file name:  ucharstrie.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -12,7 +14,9 @@
 *   created by: Markus W. Scherer
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/utypes.h"
 #include "unicode/appendable.h"
 #include "unicode/ucharstrie.h"
@@ -174,7 +178,8 @@
 }
 
 UStringTrieResult
-UCharsTrie::next(const UChar *s, int32_t sLength) {
+UCharsTrie::next(ConstChar16Ptr ptr, int32_t sLength) {
+    const UChar *s=ptr;
     if(sLength<0 ? *s==0 : sLength==0) {
         // Empty input.
         return current();
diff --git a/src/third_party/icu/source/common/ucharstriebuilder.cpp b/src/third_party/icu/source/common/ucharstriebuilder.cpp
index 4e59684..104d48a 100644
--- a/src/third_party/icu/source/common/ucharstriebuilder.cpp
+++ b/src/third_party/icu/source/common/ucharstriebuilder.cpp
@@ -1,10 +1,12 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *   Copyright (C) 2010-2012, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *******************************************************************************
 *   file name:  ucharstriebuilder.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -12,8 +14,10 @@
 *   created by: Markus W. Scherer
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/utypes.h"
 #include "unicode/ucharstrie.h"
 #include "unicode/ucharstriebuilder.h"
@@ -117,7 +121,7 @@
             return *this;
         }
         if(elementsLength>0) {
-            uprv_memcpy(newElements, elements, elementsLength*sizeof(UCharsTrieElement));
+            uprv_memcpy(newElements, elements, (size_t)elementsLength*sizeof(UCharsTrieElement));
         }
         delete[] elements;
         elements=newElements;
@@ -287,7 +291,7 @@
 
 UCharsTrieBuilder::UCTLinearMatchNode::UCTLinearMatchNode(const UChar *units, int32_t len, Node *nextNode)
         : LinearMatchNode(len, nextNode), s(units) {
-    hash=hash*37+ustr_hashUCharsN(units, len);
+    hash=hash*37u+ustr_hashUCharsN(units, len);
 }
 
 UBool
diff --git a/src/third_party/icu/source/common/ucharstrieiterator.cpp b/src/third_party/icu/source/common/ucharstrieiterator.cpp
index 748fff2..3ccc68f 100644
--- a/src/third_party/icu/source/common/ucharstrieiterator.cpp
+++ b/src/third_party/icu/source/common/ucharstrieiterator.cpp
@@ -1,10 +1,12 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *   Copyright (C) 2010-2011, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *******************************************************************************
 *   file name:  ucharstrieiterator.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -12,8 +14,10 @@
 *   created by: Markus W. Scherer
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/utypes.h"
 #include "unicode/ucharstrie.h"
 #include "unicode/unistr.h"
@@ -21,7 +25,7 @@
 
 U_NAMESPACE_BEGIN
 
-UCharsTrie::Iterator::Iterator(const UChar *trieUChars, int32_t maxStringLength,
+UCharsTrie::Iterator::Iterator(ConstChar16Ptr trieUChars, int32_t maxStringLength,
                                UErrorCode &errorCode)
         : uchars_(trieUChars),
           pos_(uchars_), initialPos_(uchars_),
diff --git a/src/third_party/icu/source/common/uchriter.cpp b/src/third_party/icu/source/common/uchriter.cpp
index 40b06ce..bedbabc 100644
--- a/src/third_party/icu/source/common/uchriter.cpp
+++ b/src/third_party/icu/source/common/uchriter.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 * Copyright (C) 1998-2012, International Business Machines Corporation and
@@ -23,14 +25,14 @@
     // never default construct!
 }
 
-UCharCharacterIterator::UCharCharacterIterator(const UChar* textPtr,
+UCharCharacterIterator::UCharCharacterIterator(ConstChar16Ptr textPtr,
                                                int32_t length)
   : CharacterIterator(textPtr != 0 ? (length>=0 ? length : u_strlen(textPtr)) : 0),
   text(textPtr)
 {
 }
 
-UCharCharacterIterator::UCharCharacterIterator(const UChar* textPtr,
+UCharCharacterIterator::UCharCharacterIterator(ConstChar16Ptr textPtr,
                                                int32_t length,
                                                int32_t position)
   : CharacterIterator(textPtr != 0 ? (length>=0 ? length : u_strlen(textPtr)) : 0, position),
@@ -38,7 +40,7 @@
 {
 }
 
-UCharCharacterIterator::UCharCharacterIterator(const UChar* textPtr,
+UCharCharacterIterator::UCharCharacterIterator(ConstChar16Ptr textPtr,
                                                int32_t length,
                                                int32_t textBegin,
                                                int32_t textEnd,
@@ -87,7 +89,7 @@
     return ustr_hashUCharsN(text, textLength) ^ pos ^ begin ^ end;
 }
 
-CharacterIterator*
+UCharCharacterIterator*
 UCharCharacterIterator::clone() const {
     return new UCharCharacterIterator(*this);
 }
@@ -347,7 +349,7 @@
     return pos;
 }
 
-void UCharCharacterIterator::setText(const UChar* newText,
+void UCharCharacterIterator::setText(ConstChar16Ptr newText,
                                      int32_t      newTextLength) {
     text = newText;
     if(newText == 0 || newTextLength < 0) {
diff --git a/src/third_party/icu/source/common/ucln.h b/src/third_party/icu/source/common/ucln.h
index cd2630a..fe6666e 100644
--- a/src/third_party/icu/source/common/ucln.h
+++ b/src/third_party/icu/source/common/ucln.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 ******************************************************************************
 *   file name:  ucln.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
diff --git a/src/third_party/icu/source/common/ucln_cmn.cpp b/src/third_party/icu/source/common/ucln_cmn.cpp
index fe73d41..56e7fff 100644
--- a/src/third_party/icu/source/common/ucln_cmn.cpp
+++ b/src/third_party/icu/source/common/ucln_cmn.cpp
@@ -1,10 +1,12 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 * Copyright (C) 2001-2014, International Business Machines
 *                Corporation and others. All Rights Reserved.
 ******************************************************************************
 *   file name:  ucln_cmn.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -12,8 +14,10 @@
 *   created by: George Rhoten
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/utypes.h"
 #include "unicode/uclean.h"
 #include "cmemory.h"
@@ -40,8 +44,8 @@
 u_cleanup(void)
 {
     UTRACE_ENTRY_OC(UTRACE_U_CLEANUP);
-    umtx_lock(NULL);     /* Force a memory barrier, so that we are sure to see   */
-    umtx_unlock(NULL);   /*   all state left around by any other threads.        */
+    icu::umtx_lock(NULL);     /* Force a memory barrier, so that we are sure to see   */
+    icu::umtx_unlock(NULL);   /*   all state left around by any other threads.        */
 
     ucln_lib_cleanup();
 
@@ -65,9 +69,20 @@
 ucln_common_registerCleanup(ECleanupCommonType type,
                             cleanupFunc *func)
 {
+    // Thread safety messiness: From ticket 10295, calls to registerCleanup() may occur
+    // concurrently. Although such cases should be storing the same value, they raise errors
+    // from the thread sanity checker. Doing the store within a mutex avoids those.
+    // BUT that can trigger a recursive entry into std::call_once() in umutex.cpp when this code,
+    // running from the call_once function, tries to grab the ICU global mutex, which
+    // re-enters the mutex init path. So, work-around by special casing UCLN_COMMON_MUTEX, not
+    // using the ICU global mutex for it.
+    //
+    // No other point in ICU uses std::call_once().
+
     U_ASSERT(UCLN_COMMON_START < type && type < UCLN_COMMON_COUNT);
-    if (UCLN_COMMON_START < type && type < UCLN_COMMON_COUNT)
-    {
+    if (type == UCLN_COMMON_MUTEX) {
+        gCommonCleanupFunctions[type] = func;
+    } else if (UCLN_COMMON_START < type && type < UCLN_COMMON_COUNT)  {
         icu::Mutex m;     // See ticket 10295 for discussion.
         gCommonCleanupFunctions[type] = func;
     }
diff --git a/src/third_party/icu/source/common/ucln_cmn.h b/src/third_party/icu/source/common/ucln_cmn.h
index 3517ca7..44b73e9 100644
--- a/src/third_party/icu/source/common/ucln_cmn.h
+++ b/src/third_party/icu/source/common/ucln_cmn.h
@@ -1,12 +1,12 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
-*                                                                            *
-* Copyright (C) 2001-2014, International Business Machines                   *
-*                Corporation and others. All Rights Reserved.                *
-*                                                                            *
+* Copyright (C) 2001-2016, International Business Machines
+*                Corporation and others. All Rights Reserved.
 ******************************************************************************
 *   file name:  ucln_cmn.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -22,8 +22,6 @@
 
 /* These are the cleanup functions for various APIs. */
 /* @return true if cleanup complete successfully.*/
-U_CFUNC UBool umtx_cleanup(void);
-
 U_CFUNC UBool utrace_cleanup(void);
 
 U_CFUNC UBool ucln_lib_cleanup(void);
@@ -33,16 +31,23 @@
 as the cleanup functions are suppose to be called. */
 typedef enum ECleanupCommonType {
     UCLN_COMMON_START = -1,
+    UCLN_COMMON_NUMPARSE_UNISETS,
     UCLN_COMMON_USPREP,
     UCLN_COMMON_BREAKITERATOR,
-    UCLN_COMMON_BREAKITERATOR_DICT,
+    UCLN_COMMON_RBBI,
     UCLN_COMMON_SERVICE,
     UCLN_COMMON_LOCALE_KEY_TYPE,
     UCLN_COMMON_LOCALE,
+    UCLN_COMMON_LOCALE_ALIAS,
+    UCLN_COMMON_LOCALE_KNOWN_CANONICALIZED,
     UCLN_COMMON_LOCALE_AVAILABLE,
+    UCLN_COMMON_LIKELY_SUBTAGS,
+    UCLN_COMMON_LOCALE_DISTANCE,
     UCLN_COMMON_ULOC,
+    UCLN_COMMON_CURRENCY,
     UCLN_COMMON_LOADED_NORMALIZER2,
     UCLN_COMMON_NORMALIZER2,
+    UCLN_COMMON_CHARACTERPROPERTIES,
     UCLN_COMMON_USET,
     UCLN_COMMON_UNAMES,
     UCLN_COMMON_UPROPS,
@@ -50,7 +55,6 @@
     UCLN_COMMON_UCNV_IO,
     UCLN_COMMON_UDATA,
     UCLN_COMMON_PUTIL,
-    UCLN_COMMON_LIST_FORMATTER,
     UCLN_COMMON_UINIT,
 
     /*
@@ -60,6 +64,7 @@
     */
     UCLN_COMMON_UNIFIED_CACHE,
     UCLN_COMMON_URES,
+    UCLN_COMMON_MUTEX,    // Mutexes should be the last to be cleaned up.
     UCLN_COMMON_COUNT /* This must be last */
 } ECleanupCommonType;
 
diff --git a/src/third_party/icu/source/common/ucln_imp.h b/src/third_party/icu/source/common/ucln_imp.h
index d5a77cd..72231f4 100644
--- a/src/third_party/icu/source/common/ucln_imp.h
+++ b/src/third_party/icu/source/common/ucln_imp.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 ******************************************************************************
 *   file name:  ucln_imp.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -78,7 +80,7 @@
  * Use the ANSI C 'atexit' function. Note that this mechanism does not
  * guarantee the order of cleanup relative to other users of ICU!
  */
-static UBool gAutoCleanRegistered = FALSE;
+static UBool gAutoCleanRegistered = false;
 
 static void ucln_atexit_handler()
 {
@@ -88,7 +90,7 @@
 static void ucln_registerAutomaticCleanup()
 {
     if(!gAutoCleanRegistered) {
-        gAutoCleanRegistered = TRUE;
+        gAutoCleanRegistered = true;
         atexit(&ucln_atexit_handler);
     }
 }
@@ -121,7 +123,9 @@
 /* READ READ READ READ!    Are you getting compilation errors from windows.h?
           Any source file which includes this (ucln_imp.h) header MUST 
           be defined with language extensions ON. */
+#ifndef WIN32_LEAN_AND_MEAN
 #   define WIN32_LEAN_AND_MEAN
+#endif
 #   define VC_EXTRALEAN
 #   define NOUSER
 #   define NOSERVICE
@@ -133,7 +137,7 @@
  */
 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
 {
-    BOOL status = TRUE;
+    BOOL status = true;
 
     switch(fdwReason) {
         case DLL_PROCESS_ATTACH:
diff --git a/src/third_party/icu/source/common/ucmndata.c b/src/third_party/icu/source/common/ucmndata.cpp
similarity index 94%
rename from src/third_party/icu/source/common/ucmndata.c
rename to src/third_party/icu/source/common/ucmndata.cpp
index b9a11eb..ba2310b 100644
--- a/src/third_party/icu/source/common/ucmndata.c
+++ b/src/third_party/icu/source/common/ucmndata.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
@@ -75,7 +77,11 @@
 typedef struct  {
     uint32_t          count;
     uint32_t          reserved;
-    PointerTOCEntry   entry[2];   /* Actual size is from count. */
+    /**
+     * Variable-length array declared with length 1 to disable bounds checkers.
+     * The actual array length is in the count field.
+     */
+    PointerTOCEntry   entry[1];
 }  PointerTOC;
 
 
@@ -205,7 +211,9 @@
     return -1;
 }
 
-static uint32_t offsetTOCEntryCount(const UDataMemory *pData) {
+U_CDECL_BEGIN
+static uint32_t U_CALLCONV
+offsetTOCEntryCount(const UDataMemory *pData) {
     int32_t          retVal=0;
     const UDataOffsetTOC *toc = (UDataOffsetTOC *)pData->toc;
     if (toc != NULL) {
@@ -214,11 +222,12 @@
     return retVal;
 }
 
-static const DataHeader *
+static const DataHeader * U_CALLCONV
 offsetTOCLookupFn(const UDataMemory *pData,
                   const char *tocEntryName,
                   int32_t *pLength,
                   UErrorCode *pErrorCode) {
+    (void)pErrorCode;
     const UDataOffsetTOC  *toc = (UDataOffsetTOC *)pData->toc;
     if(toc!=NULL) {
         const char *base=(const char *)toc;
@@ -260,16 +269,16 @@
 }
 
 
-static uint32_t pointerTOCEntryCount(const UDataMemory *pData) {
+static uint32_t U_CALLCONV pointerTOCEntryCount(const UDataMemory *pData) {
     const PointerTOC *toc = (PointerTOC *)pData->toc;
     return (uint32_t)((toc != NULL) ? (toc->count) : 0);
 }
 
-
-static const DataHeader *pointerTOCLookupFn(const UDataMemory *pData,
+static const DataHeader * U_CALLCONV pointerTOCLookupFn(const UDataMemory *pData,
                    const char *name,
                    int32_t *pLength,
                    UErrorCode *pErrorCode) {
+    (void)pErrorCode;
     if(pData->toc!=NULL) {
         const PointerTOC *toc = (PointerTOC *)pData->toc;
         int32_t number, count=(int32_t)toc->count;
@@ -298,6 +307,8 @@
         return pData->pHeader;
     }
 }
+U_CDECL_END
+
 
 static const commonDataFuncs CmnDFuncs = {offsetTOCLookupFn,  offsetTOCEntryCount};
 static const commonDataFuncs ToCPFuncs = {pointerTOCLookupFn, pointerTOCEntryCount};
diff --git a/src/third_party/icu/source/common/ucmndata.h b/src/third_party/icu/source/common/ucmndata.h
index 413a2f8..15c1a6c 100644
--- a/src/third_party/icu/source/common/ucmndata.h
+++ b/src/third_party/icu/source/common/ucmndata.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
@@ -64,7 +66,11 @@
 
 typedef struct {
     uint32_t count;
-    UDataOffsetTOCEntry entry[2];    /* Actual size of array is from count. */
+    /**
+     * Variable-length array declared with length 1 to disable bounds checkers.
+     * The actual array length is in the count field.
+     */
+    UDataOffsetTOCEntry entry[1];
 } UDataOffsetTOC;
 
 /**
diff --git a/src/third_party/icu/source/common/ucnv.c b/src/third_party/icu/source/common/ucnv.cpp
similarity index 98%
rename from src/third_party/icu/source/common/ucnv.c
rename to src/third_party/icu/source/common/ucnv.cpp
index e442001..aba2301 100644
--- a/src/third_party/icu/source/common/ucnv.c
+++ b/src/third_party/icu/source/common/ucnv.cpp
@@ -1,7 +1,9 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
-*   Copyright (C) 1998-2015, International Business Machines
+*   Copyright (C) 1998-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *
 ******************************************************************************
@@ -21,11 +23,15 @@
 
 #include <stdlib.h>
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/utypes.h"
 
 #if !UCONFIG_NO_CONVERSION
 
+#include <memory>
+
 #include "unicode/ustring.h"
 #include "unicode/ucnv.h"
 #include "unicode/ucnv_err.h"
@@ -159,7 +165,6 @@
     UConverter *localConverter, *allocatedConverter;
     int32_t stackBufferSize;
     int32_t bufferSizeNeeded;
-    char *stackBufferChars = (char *)stackBuffer;
     UErrorCode cbErr;
     UConverterToUnicodeArgs toUArgs = {
         sizeof(UConverterToUnicodeArgs),
@@ -225,23 +230,22 @@
         }
     }
 
-
-    /* Pointers on 64-bit platforms need to be aligned
-     * on a 64-bit boundary in memory.
+    /* Adjust (if necessary) the stackBuffer pointer to be aligned correctly for a UConverter.
+     * TODO(Jira ICU-20736) Redo this using std::align() once g++4.9 compatibility is no longer needed.
      */
-    if (U_ALIGNMENT_OFFSET(stackBuffer) != 0) {
-        int32_t offsetUp = (int32_t)U_ALIGNMENT_OFFSET_UP(stackBufferChars);
-        if(stackBufferSize > offsetUp) {
-            stackBufferSize -= offsetUp;
-            stackBufferChars += offsetUp;
+    if (stackBuffer) {
+        uintptr_t p = reinterpret_cast<uintptr_t>(stackBuffer);
+        uintptr_t aligned_p = (p + alignof(UConverter) - 1) & ~(alignof(UConverter) - 1);
+        ptrdiff_t pointerAdjustment = aligned_p - p;
+        if (bufferSizeNeeded + pointerAdjustment <= stackBufferSize) {
+            stackBuffer = reinterpret_cast<void *>(aligned_p);
+            stackBufferSize -= static_cast<int32_t>(pointerAdjustment);
         } else {
             /* prevent using the stack buffer but keep the size > 0 so that we do not just preflight */
             stackBufferSize = 1;
         }
     }
 
-    stackBuffer = (void *)stackBufferChars;
-    
     /* Now, see if we must allocate any memory */
     if (stackBufferSize < bufferSizeNeeded || stackBuffer == NULL)
     {
@@ -476,7 +480,7 @@
                     const UChar *s,
                     int32_t length,
                     UErrorCode *err) {
-    UAlignedMemory cloneBuffer[U_CNV_SAFECLONE_BUFFERSIZE / sizeof(UAlignedMemory) + 1];
+    alignas(UConverter) char cloneBuffer[U_CNV_SAFECLONE_BUFFERSIZE];
     char chars[UCNV_ERROR_BUFFER_LENGTH];
 
     UConverter *clone;
@@ -1064,7 +1068,7 @@
 
                         length=(int32_t)(pArgs->sourceLimit-pArgs->source);
                         if(length>0) {
-                            uprv_memcpy(cnv->preFromU, pArgs->source, length*U_SIZEOF_UCHAR);
+                            u_memcpy(cnv->preFromU, pArgs->source, length);
                             cnv->preFromULength=(int8_t)-length;
                         }
 
@@ -1744,13 +1748,9 @@
     }
     if(srcLength>0) {
         srcLimit=src+srcLength;
+        destCapacity=pinCapacity(dest, destCapacity);
         destLimit=dest+destCapacity;
 
-        /* pin the destination limit to U_MAX_PTR; NULL check is for OS/400 */
-        if(destLimit<dest || (destLimit==NULL && dest!=NULL)) {
-            destLimit=(char *)U_MAX_PTR(dest);
-        }
-
         /* perform the conversion */
         ucnv_fromUnicode(cnv, &dest, destLimit, &src, srcLimit, 0, TRUE, pErrorCode);
         destLength=(int32_t)(dest-originalDest);
@@ -1804,13 +1804,9 @@
     }
     if(srcLength>0) {
         srcLimit=src+srcLength;
+        destCapacity=pinCapacity(dest, destCapacity);
         destLimit=dest+destCapacity;
 
-        /* pin the destination limit to U_MAX_PTR; NULL check is for OS/400 */
-        if(destLimit<dest || (destLimit==NULL && dest!=NULL)) {
-            destLimit=(UChar *)U_MAX_PTR(dest);
-        }
-
         /* perform the conversion */
         ucnv_toUnicode(cnv, &dest, destLimit, &src, srcLimit, 0, TRUE, pErrorCode);
         destLength=(int32_t)(dest-originalDest);
@@ -1820,7 +1816,7 @@
         {
             UChar buffer[1024];
 
-            destLimit=buffer+sizeof(buffer)/U_SIZEOF_UCHAR;
+            destLimit=buffer+UPRV_LENGTHOF(buffer);
             do {
                 dest=buffer;
                 *pErrorCode=U_ZERO_ERROR;
@@ -2649,7 +2645,7 @@
         return NULL;
     }
 
-    for(i=0; i<(int32_t)(sizeof(ambiguousConverters)/sizeof(UAmbiguousConverter)); ++i)
+    for(i=0; i<UPRV_LENGTHOF(ambiguousConverters); ++i)
     {
         if(0==uprv_strcmp(name, ambiguousConverters[i].name))
         {
@@ -2746,7 +2742,7 @@
     }
     if ((*len = converter->invalidUCharLength) > 0)
     {
-        uprv_memcpy (errChars, converter->invalidUCharBuffer, sizeof(UChar) * (*len));
+        u_memcpy (errChars, converter->invalidUCharBuffer, *len);
     }
 }
 
diff --git a/src/third_party/icu/source/common/ucnv2022.cpp b/src/third_party/icu/source/common/ucnv2022.cpp
index 0c12dd0..a211df7 100644
--- a/src/third_party/icu/source/common/ucnv2022.cpp
+++ b/src/third_party/icu/source/common/ucnv2022.cpp
@@ -1,10 +1,12 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
-*   Copyright (C) 2000-2015, International Business Machines
+*   Copyright (C) 2000-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 **********************************************************************
 *   file name:  ucnv2022.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -223,10 +225,10 @@
 /* ISO-2022 ----------------------------------------------------------------- */
 
 /*Forward declaration */
-U_CFUNC void
+U_CFUNC void U_CALLCONV
 ucnv_fromUnicode_UTF8(UConverterFromUnicodeArgs * args,
                       UErrorCode * err);
-U_CFUNC void
+U_CFUNC void U_CALLCONV
 ucnv_fromUnicode_UTF8_OFFSETS_LOGIC(UConverterFromUnicodeArgs * args,
                                     UErrorCode * err);
 
@@ -383,26 +385,31 @@
 } Variant2022;
 
 /*********** ISO 2022 Converter Protos ***********/
-static void
+static void U_CALLCONV
 _ISO2022Open(UConverter *cnv, UConverterLoadArgs *pArgs, UErrorCode *errorCode);
 
-static void
+static void U_CALLCONV
  _ISO2022Close(UConverter *converter);
 
-static void
+static void U_CALLCONV
 _ISO2022Reset(UConverter *converter, UConverterResetChoice choice);
 
-static const char*
+U_CDECL_BEGIN
+static const char * U_CALLCONV
 _ISO2022getName(const UConverter* cnv);
+U_CDECL_END
 
-static void
+static void  U_CALLCONV
 _ISO_2022_WriteSub(UConverterFromUnicodeArgs *args, int32_t offsetIndex, UErrorCode *err);
 
-static UConverter *
+U_CDECL_BEGIN
+static UConverter * U_CALLCONV
 _ISO_2022_SafeClone(const UConverter *cnv, void *stackBuffer, int32_t *pBufferSize, UErrorCode *status);
 
+U_CDECL_END
+
 #ifdef U_ENABLE_GENERIC_ISO_2022
-static void
+static void U_CALLCONV
 T_UConverter_toUnicode_ISO_2022_OFFSETS_LOGIC(UConverterToUnicodeArgs* args, UErrorCode* err);
 #endif
 
@@ -468,10 +475,10 @@
     }
 }
 
-static void
+static void U_CALLCONV
 _ISO2022Open(UConverter *cnv, UConverterLoadArgs *pArgs, UErrorCode *errorCode){
 
-    char myLocale[6]={' ',' ',' ',' ',' ',' '};
+    char myLocale[7]={' ',' ',' ',' ',' ',' ', '\0'};
 
     cnv->extraInfo = uprv_malloc (sizeof (UConverterDataISO2022));
     if(cnv->extraInfo != NULL) {
@@ -486,7 +493,7 @@
         myConverterData->currentType = ASCII1;
         cnv->fromUnicodeStatus =FALSE;
         if(pArgs->locale){
-            uprv_strncpy(myLocale, pArgs->locale, sizeof(myLocale));
+            uprv_strncpy(myLocale, pArgs->locale, sizeof(myLocale)-1);
         }
         version = pArgs->options & UCNV_OPTIONS_VERSION_MASK;
         myConverterData->version = version;
@@ -506,7 +513,7 @@
                     ucnv_loadSharedData("ISO8859_7", &stackPieces, &stackArgs, errorCode);
             }
             myConverterData->myConverterArray[JISX208] =
-                ucnv_loadSharedData("Shift-JIS", &stackPieces, &stackArgs, errorCode);
+                ucnv_loadSharedData("EUC-JP", &stackPieces, &stackArgs, errorCode);
             if(jpCharsetMasks[version]&CSM(JISX212)) {
                 myConverterData->myConverterArray[JISX212] =
                     ucnv_loadSharedData("jisx-212", &stackPieces, &stackArgs, errorCode);
@@ -646,7 +653,7 @@
 }
 
 
-static void
+static void U_CALLCONV
 _ISO2022Close(UConverter *converter) {
     UConverterDataISO2022* myData =(UConverterDataISO2022 *) (converter->extraInfo);
     UConverterSharedData **array = myData->myConverterArray;
@@ -669,7 +676,7 @@
     }
 }
 
-static void
+static void U_CALLCONV
 _ISO2022Reset(UConverter *converter, UConverterResetChoice choice) {
     UConverterDataISO2022 *myConverterData=(UConverterDataISO2022 *) (converter->extraInfo);
     if(choice<=UCNV_RESET_TO_UNICODE) {
@@ -714,7 +721,9 @@
     }
 }
 
-static const char*
+U_CDECL_BEGIN
+
+static const char * U_CALLCONV
 _ISO2022getName(const UConverter* cnv){
     if(cnv->extraInfo){
         UConverterDataISO2022* myData= (UConverterDataISO2022*)cnv->extraInfo;
@@ -723,6 +732,8 @@
     return NULL;
 }
 
+U_CDECL_END
+
 
 /*************** to unicode *******************/
 /****************************************************************************
@@ -971,9 +982,9 @@
                         *err = U_UNSUPPORTED_ESCAPE_SEQUENCE;
                         break;
                     }
-                    /*fall through*/
+                    U_FALLTHROUGH;
                 case GB2312_1:
-                    /*fall through*/
+                    U_FALLTHROUGH;
                 case CNS_11643_1:
                     myData2022->toU2022State.cs[1]=(int8_t)tempState;
                     break;
@@ -1243,7 +1254,7 @@
 *
 */
 
-static void
+static void U_CALLCONV
 T_UConverter_toUnicode_ISO_2022_OFFSETS_LOGIC(UConverterToUnicodeArgs* args,
                                                            UErrorCode* err){
     const char* mySourceLimit, *realSourceLimit;
@@ -1504,79 +1515,6 @@
 }
 
 /*
- * Take a valid Shift-JIS byte pair, check that it is in the range corresponding
- * to JIS X 0208, and convert it to a pair of 21..7E bytes.
- * Return 0 if the byte pair is out of range.
- */
-static inline uint32_t
-_2022FromSJIS(uint32_t value) {
-    uint8_t trail;
-
-    if(value > 0xEFFC) {
-        return 0;  /* beyond JIS X 0208 */
-    }
-
-    trail = (uint8_t)value;
-
-    value &= 0xff00;  /* lead byte */
-    if(value <= 0x9f00) {
-        value -= 0x7000;
-    } else /* 0xe000 <= value <= 0xef00 */ {
-        value -= 0xb000;
-    }
-    value <<= 1;
-
-    if(trail <= 0x9e) {
-        value -= 0x100;
-        if(trail <= 0x7e) {
-            value |= trail - 0x1f;
-        } else {
-            value |= trail - 0x20;
-        }
-    } else /* trail <= 0xfc */ {
-        value |= trail - 0x7e;
-    }
-    return value;
-}
-
-/*
- * Convert a pair of JIS X 0208 21..7E bytes to Shift-JIS.
- * If either byte is outside 21..7E make sure that the result is not valid
- * for Shift-JIS so that the converter catches it.
- * Some invalid byte values already turn into equally invalid Shift-JIS
- * byte values and need not be tested explicitly.
- */
-static inline void
-_2022ToSJIS(uint8_t c1, uint8_t c2, char bytes[2]) {
-    if(c1&1) {
-        ++c1;
-        if(c2 <= 0x5f) {
-            c2 += 0x1f;
-        } else if(c2 <= 0x7e) {
-            c2 += 0x20;
-        } else {
-            c2 = 0;  /* invalid */
-        }
-    } else {
-        if((uint8_t)(c2-0x21) <= ((0x7e)-0x21)) {
-            c2 += 0x7e;
-        } else {
-            c2 = 0;  /* invalid */
-        }
-    }
-    c1 >>= 1;
-    if(c1 <= 0x2f) {
-        c1 += 0x70;
-    } else if(c1 <= 0x3f) {
-        c1 += 0xb0;
-    } else {
-        c1 = 0;  /* invalid */
-    }
-    bytes[0] = (char)c1;
-    bytes[1] = (char)c2;
-}
-
-/*
  * JIS X 0208 has fallbacks from Unicode half-width Katakana to full-width (DBCS)
  * Katakana.
  * Now that we use a Shift-JIS table for JIS X 0208 we need to hardcode these fallbacks
@@ -1649,7 +1587,7 @@
     0x212C   /* U+FF9F */
 };
 
-static void
+static void U_CALLCONV
 UConverter_fromUnicode_ISO_2022_JP_OFFSETS_LOGIC(UConverterFromUnicodeArgs* args, UErrorCode* err) {
     UConverter *cnv = args->converter;
     UConverterDataISO2022 *converterData;
@@ -1846,8 +1784,13 @@
                                 converterData->myConverterArray[cs0],
                                 sourceChar, &value,
                                 useFallback, MBCS_OUTPUT_2);
-                    if(len2 == 2 || (len2 == -2 && len == 0)) {  /* only accept DBCS: abs(len)==2 */
-                        value = _2022FromSJIS(value);
+                    // Only accept DBCS char (abs(len2) == 2).
+                    // With EUC-JP table for JIS X 208, half-width Kana
+                    // represented with DBCS starting with 0x8E has to be
+                    // filtered out so that they can be converted with
+                    // hwkana_fb table.
+                    if((len2 == 2 && ((value & 0xFF00) != 0x8E00)) || (len2 == -2 && len == 0)) {
+                        value &= 0x7F7F;
                         if(value != 0) {
                             targetValue = value;
                             len = len2;
@@ -2066,7 +2009,7 @@
 
 /*************** to unicode *******************/
 
-static void
+static void U_CALLCONV
 UConverter_toUnicode_ISO_2022_JP_OFFSETS_LOGIC(UConverterToUnicodeArgs *args,
                                                UErrorCode* err){
     char tempBuf[2];
@@ -2160,7 +2103,6 @@
             /* ISO-2022-JP does not use single-byte (C1) SS2 and SS3 */
 
             case CR:
-                /*falls through*/
             case LF:
                 /* automatically reset to single-byte mode */
                 if((StateEnum)pToU2022State->cs[0] != ASCII && (StateEnum)pToU2022State->cs[0] != JISX201) {
@@ -2168,7 +2110,7 @@
                 }
                 pToU2022State->cs[2] = 0;
                 pToU2022State->g = 0;
-                /* falls through */
+                U_FALLTHROUGH;
             default:
                 /* convert one or two bytes */
                 myData->isEmptySegment = FALSE;
@@ -2240,18 +2182,13 @@
                         if (leadIsOk && trailIsOk) {
                             ++mySource;
                             tmpSourceChar = (mySourceChar << 8) | trailByte;
-                            if(cs == JISX208) {
-                                _2022ToSJIS((uint8_t)mySourceChar, trailByte, tempBuf);
-                                mySourceChar = tmpSourceChar;
-                            } else {
-                                /* Copy before we modify tmpSourceChar so toUnicodeCallback() sees the correct bytes. */
-                                mySourceChar = tmpSourceChar;
-                                if (cs == KSC5601) {
-                                    tmpSourceChar += 0x8080;  /* = _2022ToGR94DBCS(tmpSourceChar) */
-                                }
-                                tempBuf[0] = (char)(tmpSourceChar >> 8);
-                                tempBuf[1] = (char)(tmpSourceChar);
+                            /* Copy before we modify tmpSourceChar so toUnicodeCallback() sees the correct bytes. */
+                            mySourceChar = tmpSourceChar;
+                            if (cs == JISX208 || cs == KSC5601) {
+                                tmpSourceChar += 0x8080;  /* = _2022ToGR94DBCS(tmpSourceChar) */
                             }
+                            tempBuf[0] = (char)(tmpSourceChar >> 8);
+                            tempBuf[1] = (char)(tmpSourceChar);
                             targetUniChar = ucnv_MBCSSimpleGetNextUChar(myData->myConverterArray[cs], tempBuf, 2, FALSE);
                         } else if (!(trailIsOk || IS_2022_CONTROL(trailByte))) {
                             /* report a pair of illegal bytes if the second byte is not a DBCS starter */
@@ -2319,7 +2256,7 @@
 *  ii) There are only 2 shifting sequences SO to shift into double byte mode
 *      and SI to shift into single byte mode
 */
-static void
+static void U_CALLCONV
 UConverter_fromUnicode_ISO_2022_KR_OFFSETS_LOGIC_IBM(UConverterFromUnicodeArgs* args, UErrorCode* err){
 
     UConverter* saveConv = args->converter;
@@ -2343,7 +2280,7 @@
     args->converter=saveConv;
 }
 
-static void
+static void U_CALLCONV
 UConverter_fromUnicode_ISO_2022_KR_OFFSETS_LOGIC(UConverterFromUnicodeArgs* args, UErrorCode* err){
 
     const UChar *source = args->source;
@@ -2562,7 +2499,7 @@
 
 /************************ To Unicode ***************************************/
 
-static void
+static void U_CALLCONV
 UConverter_toUnicode_ISO_2022_KR_OFFSETS_LOGIC_IBM(UConverterToUnicodeArgs *args,
                                                             UErrorCode* err){
     char const* sourceStart;
@@ -2660,7 +2597,7 @@
     }
 }
 
-static void
+static void U_CALLCONV
 UConverter_toUnicode_ISO_2022_KR_OFFSETS_LOGIC(UConverterToUnicodeArgs *args,
                                                             UErrorCode* err){
     char tempBuf[2];
@@ -2762,7 +2699,7 @@
                         /* report a pair of illegal bytes if the second byte is not a DBCS starter */
                         ++mySource;
                         /* add another bit so that the code below writes 2 bytes in case of error */
-                        mySourceChar = 0x10000 | (mySourceChar << 8) | trailByte;
+                        mySourceChar = static_cast<UChar>(0x10000 | (mySourceChar << 8) | trailByte);
                     }
                 } else {
                     args->converter->toUBytes[0] = (uint8_t)mySourceChar;
@@ -2902,7 +2839,7 @@
         CNS_11643_1992_Plane_7_STR
 };
 
-static void
+static void U_CALLCONV
 UConverter_fromUnicode_ISO_2022_CN_OFFSETS_LOGIC(UConverterFromUnicodeArgs* args, UErrorCode* err){
     UConverter *cnv = args->converter;
     UConverterDataISO2022 *converterData;
@@ -3253,7 +3190,7 @@
 }
 
 
-static void
+static void U_CALLCONV
 UConverter_toUnicode_ISO_2022_CN_OFFSETS_LOGIC(UConverterToUnicodeArgs *args,
                                                UErrorCode* err){
     char tempBuf[3];
@@ -3294,7 +3231,7 @@
                     myData->isEmptySegment = FALSE;	/* we are handling it, reset to avoid future spurious errors */
                     *err = U_ILLEGAL_ESCAPE_SEQUENCE;
                     args->converter->toUCallbackReason = UCNV_IRREGULAR;
-                    args->converter->toUBytes[0] = mySourceChar;
+                    args->converter->toUBytes[0] = static_cast<uint8_t>(mySourceChar);
                     args->converter->toULength = 1;
                     args->target = myTarget;
                     args->source = mySource;
@@ -3343,10 +3280,9 @@
             /* ISO-2022-CN does not use single-byte (C1) SS2 and SS3 */
 
             case CR:
-                /*falls through*/
             case LF:
                 uprv_memset(pToU2022State, 0, sizeof(ISO2022State));
-                /* falls through */
+                U_FALLTHROUGH;
             default:
                 /* convert one or two bytes */
                 myData->isEmptySegment = FALSE;
@@ -3456,7 +3392,7 @@
 }
 #endif /* #if !UCONFIG_ONLY_HTML_CONVERSION */
 
-static void
+static void U_CALLCONV
 _ISO_2022_WriteSub(UConverterFromUnicodeArgs *args, int32_t offsetIndex, UErrorCode *err) {
     UConverter *cnv = args->converter;
     UConverterDataISO2022 *myConverterData=(UConverterDataISO2022 *) cnv->extraInfo;
@@ -3503,14 +3439,14 @@
     case 'k':
         if(myConverterData->version == 0) {
             if(length == 1) {
-                if((UBool)args->converter->fromUnicodeStatus) {
+                if(args->converter->fromUnicodeStatus) {
                     /* in DBCS mode: switch to SBCS */
                     args->converter->fromUnicodeStatus = 0;
                     *p++ = UCNV_SI;
                 }
                 *p++ = subchar[0];
             } else /* length == 2*/ {
-                if(!(UBool)args->converter->fromUnicodeStatus) {
+                if(!args->converter->fromUnicodeStatus) {
                     /* in SBCS mode: switch to DBCS */
                     args->converter->fromUnicodeStatus = 1;
                     *p++ = UCNV_SO;
@@ -3562,25 +3498,18 @@
 
 /*
  * Structure for cloning an ISO 2022 converter into a single memory block.
- * ucnv_safeClone() of the converter will align the entire cloneStruct,
- * and then ucnv_safeClone() of the sub-converter may additionally align
- * currentConverter inside the cloneStruct, for which we need the deadSpace
- * after currentConverter.
- * This is because UAlignedMemory may be larger than the actually
- * necessary alignment size for the platform.
- * The other cloneStruct fields will not be moved around,
- * and are aligned properly with cloneStruct's alignment.
  */
 struct cloneStruct
 {
     UConverter cnv;
     UConverter currentConverter;
-    UAlignedMemory deadSpace;
     UConverterDataISO2022 mydata;
 };
 
 
-static UConverter *
+U_CDECL_BEGIN
+
+static UConverter * U_CALLCONV
 _ISO_2022_SafeClone(
             const UConverter *cnv,
             void *stackBuffer,
@@ -3591,6 +3520,10 @@
     UConverterDataISO2022 *cnvData;
     int32_t i, size;
 
+    if (U_FAILURE(*status)){
+        return nullptr;
+    }
+
     if (*pBufferSize == 0) { /* 'preflighting' request - set needed size into *pBufferSize */
         *pBufferSize = (int32_t)sizeof(struct cloneStruct);
         return NULL;
@@ -3608,7 +3541,7 @@
     /* share the subconverters */
 
     if(cnvData->currentConverter != NULL) {
-        size = (int32_t)(sizeof(UConverter) + sizeof(UAlignedMemory)); /* include size of padding */
+        size = (int32_t)sizeof(UConverter);
         localClone->mydata.currentConverter =
             ucnv_safeClone(cnvData->currentConverter,
                             &localClone->currentConverter,
@@ -3627,7 +3560,9 @@
     return &localClone->cnv;
 }
 
-static void
+U_CDECL_END
+
+static void U_CALLCONV
 _ISO_2022_GetUnicodeSet(const UConverter *cnv,
                     const USetAdder *sa,
                     UConverterUnicodeSet which,
@@ -3893,7 +3828,7 @@
     UCNV_IBM,
     UCNV_ISO_2022,
     1,
-    3, /* max 3 bytes per UChar: SO+DBCS */
+    8, /* max 8 bytes per UChar */
     { 0x1a, 0, 0, 0 },
     1,
     FALSE,
diff --git a/src/third_party/icu/source/common/ucnv_bld.cpp b/src/third_party/icu/source/common/ucnv_bld.cpp
index d8d3097..04c9471 100644
--- a/src/third_party/icu/source/common/ucnv_bld.cpp
+++ b/src/third_party/icu/source/common/ucnv_bld.cpp
@@ -1,7 +1,9 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
  ********************************************************************
  * COPYRIGHT:
- * Copyright (c) 1996-2015, International Business Machines Corporation and
+ * Copyright (c) 1996-2016, International Business Machines Corporation and
  * others. All Rights Reserved.
  ********************************************************************
  *
@@ -23,8 +25,10 @@
 
 #if !UCONFIG_NO_CONVERSION
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/putil.h"
 #include "unicode/udata.h"
 #include "unicode/ucnv.h"
@@ -67,7 +71,11 @@
 
     &_Latin1Data,
     &_UTF8Data, &_UTF16BEData, &_UTF16LEData,
+#if UCONFIG_ONLY_HTML_CONVERSION
+    NULL, NULL,
+#else
     &_UTF32BEData, &_UTF32LEData,
+#endif
     NULL,
 
 #if UCONFIG_NO_LEGACY_CONVERSION
@@ -101,7 +109,7 @@
 
     &_ASCIIData,
 #if UCONFIG_ONLY_HTML_CONVERSION
-    NULL, NULL, &_UTF16Data, &_UTF32Data, NULL, NULL,
+    NULL, NULL, &_UTF16Data, NULL, NULL, NULL,
 #else
     &_UTF7Data, &_Bocu1Data, &_UTF16Data, &_UTF32Data, &_CESU8Data, &_IMAPData,
 #endif
@@ -166,6 +174,7 @@
   { "utf16oppositeendian", UCNV_UTF16_BigEndian},
   { "utf16platformendian", UCNV_UTF16_LittleEndian },
 #endif
+#if !UCONFIG_ONLY_HTML_CONVERSION
   { "utf32", UCNV_UTF32 },
   { "utf32be", UCNV_UTF32_BigEndian },
   { "utf32le", UCNV_UTF32_LittleEndian },
@@ -176,6 +185,7 @@
   { "utf32oppositeendian", UCNV_UTF32_BigEndian },
   { "utf32platformendian", UCNV_UTF32_LittleEndian },
 #endif
+#endif
 #if !UCONFIG_ONLY_HTML_CONVERSION
   { "utf7", UCNV_UTF7 },
 #endif
@@ -188,9 +198,9 @@
 
 /*initializes some global variables */
 static UHashtable *SHARED_DATA_HASHTABLE = NULL;
-static UMutex cnvCacheMutex = U_MUTEX_INITIALIZER;  /* Mutex for synchronizing cnv cache access. */
-                                                    /*  Note:  the global mutex is used for      */
-                                                    /*         reference count updates.          */
+static icu::UMutex cnvCacheMutex;
+/*  Note:  the global mutex is used for      */
+/*         reference count updates.          */
 
 static const char **gAvailableConverters = NULL;
 static uint16_t gAvailableConverterCount = 0;
@@ -218,7 +228,7 @@
 static const char DATA_TYPE[] = "cnv";
 
 /* ucnv_flushAvailableConverterCache. This is only called from ucnv_cleanup().
- *                       If it is ever to be called from elsewhere, synchronization 
+ *                       If it is ever to be called from elsewhere, synchronization
  *                       will need to be considered.
  */
 static void
@@ -255,6 +265,11 @@
     return (SHARED_DATA_HASHTABLE == NULL);
 }
 
+U_CAPI void U_EXPORT2
+ucnv_enableCleanup(void) {
+    ucln_common_registerCleanup(UCLN_COMMON_UCNV, ucnv_cleanup);
+}
+
 static UBool U_CALLCONV
 isCnvAcceptable(void * /*context*/,
                 const char * /*type*/, const char * /*name*/,
@@ -381,7 +396,7 @@
 
     /* do a binary search for the alias */
     start = 0;
-    limit = sizeof(cnvNameType)/sizeof(cnvNameType[0]);
+    limit = UPRV_LENGTHOF(cnvNameType);
     mid = limit;
     lastMid = UINT32_MAX;
 
@@ -433,7 +448,7 @@
         SHARED_DATA_HASHTABLE = uhash_openSize(uhash_hashChars, uhash_compareChars, NULL,
                             ucnv_io_countKnownConverters(&err)*UCNV_CACHE_LOAD_FACTOR,
                             &err);
-        ucln_common_registerCleanup(UCLN_COMMON_UCNV, ucnv_cleanup);
+        ucnv_enableCleanup();
 
         if (U_FAILURE(err))
             return;
@@ -1093,7 +1108,7 @@
     U_ASSERT(gAvailableConverterCount == 0);
     U_ASSERT(gAvailableConverters == NULL);
 
-    ucln_common_registerCleanup(UCLN_COMMON_UCNV, ucnv_cleanup);
+    ucnv_enableCleanup();
     UEnumeration *allConvEnum = ucnv_openAllNames(&errCode);
     int32_t allConverterCount = uenum_count(allConvEnum, &errCode);
     if (U_FAILURE(errCode)) {
@@ -1199,7 +1214,7 @@
     //             -- Andy
     gDefaultConverterName = gDefaultConverterNameBuffer;
 
-    ucln_common_registerCleanup(UCLN_COMMON_UCNV, ucnv_cleanup);
+    ucnv_enableCleanup();
 
     umtx_unlock(&cnvCacheMutex);
 }
@@ -1298,7 +1313,7 @@
 
         /* The close may make the current name go away. */
         ucnv_close(cnv);
-  
+
         /* reset the converter cache */
         u_flushDefaultConverter();
     }
diff --git a/src/third_party/icu/source/common/ucnv_bld.h b/src/third_party/icu/source/common/ucnv_bld.h
index 2fbba14..43e6c09 100644
--- a/src/third_party/icu/source/common/ucnv_bld.h
+++ b/src/third_party/icu/source/common/ucnv_bld.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
 *   Copyright (C) 1999-2015 International Business Machines
@@ -64,8 +66,8 @@
 
 typedef struct UConverterStaticData {   /* +offset: size */
     uint32_t structSize;                /* +0: 4 Size of this structure */
-    
-    char name 
+
+    char name
       [UCNV_MAX_CONVERTER_NAME_LENGTH]; /* +4: 60  internal name of the converter- invariant chars */
 
     int32_t codepage;               /* +64: 4 codepage # (now IBM-$codepage) */
@@ -78,7 +80,7 @@
 
     uint8_t subChar[UCNV_MAX_SUBCHAR_LEN]; /* +72: 4  [note:  4 and 8 byte boundary] */
     int8_t subCharLen;              /* +76: 1 */
-    
+
     uint8_t hasToUnicodeFallback;   /* +77: 1 UBool needs to be changed to UBool to be consistent across platform */
     uint8_t hasFromUnicodeFallback; /* +78: 1 */
     uint8_t unicodeMask;            /* +79: 1  bit 0: has supplementary  bit 1: has single surrogates */
@@ -99,8 +101,8 @@
 
     const UConverterStaticData *staticData; /* pointer to the static (non changing) data. */
 
-    UBool                sharedDataCached;   /* TRUE:  shared data is in cache, don't destroy on ucnv_close() if 0 ref.  FALSE: shared data isn't in the cache, do attempt to clean it up if the ref is 0 */
-    /** If FALSE, then referenceCounter is not used. Must not change after initialization. */
+    UBool                sharedDataCached;   /* true:  shared data is in cache, don't destroy on ucnv_close() if 0 ref.  false: shared data isn't in the cache, do attempt to clean it up if the ref is 0 */
+    /** If false, then referenceCounter is not used. Must not change after initialization. */
     UBool isReferenceCounted;
 
     const UConverterImpl *impl;     /* vtable-style struct of mostly function pointers */
@@ -126,7 +128,7 @@
 #define UCNV_IMMUTABLE_SHARED_DATA_INITIALIZER(pStaticData, pImpl) \
     { \
         sizeof(UConverterSharedData), ~((uint32_t)0), \
-        NULL, pStaticData, FALSE, FALSE, pImpl, \
+        NULL, pStaticData, false, false, pImpl, \
         0, UCNV_MBCS_TABLE_INITIALIZER \
     }
 
@@ -179,9 +181,9 @@
 
     uint32_t options; /* options flags from UConverterOpen, may contain additional bits */
 
-    UBool sharedDataIsCached;  /* TRUE:  shared data is in cache, don't destroy on ucnv_close() if 0 ref.  FALSE: shared data isn't in the cache, do attempt to clean it up if the ref is 0 */
-    UBool isCopyLocal;  /* TRUE if UConverter is not owned and not released in ucnv_close() (stack-allocated, safeClone(), etc.) */
-    UBool isExtraLocal; /* TRUE if extraInfo is not owned and not released in ucnv_close() (stack-allocated, safeClone(), etc.) */
+    UBool sharedDataIsCached;  /* true:  shared data is in cache, don't destroy on ucnv_close() if 0 ref.  false: shared data isn't in the cache, do attempt to clean it up if the ref is 0 */
+    UBool isCopyLocal;  /* true if UConverter is not owned and not released in ucnv_close() (stack-allocated, safeClone(), etc.) */
+    UBool isExtraLocal; /* true if extraInfo is not owned and not released in ucnv_close() (stack-allocated, safeClone(), etc.) */
 
     UBool  useFallback;
     int8_t toULength;                   /* number of bytes in toUBytes */
@@ -286,6 +288,9 @@
           const void *inData, int32_t length, void *outData,
           UErrorCode *pErrorCode);
 
+U_CAPI void U_EXPORT2
+ucnv_enableCleanup(void);
+
 #endif
 
 #endif /* _UCNV_BLD */
diff --git a/src/third_party/icu/source/common/ucnv_cb.c b/src/third_party/icu/source/common/ucnv_cb.cpp
similarity index 98%
rename from src/third_party/icu/source/common/ucnv_cb.c
rename to src/third_party/icu/source/common/ucnv_cb.cpp
index fa34b65..1bb0012 100644
--- a/src/third_party/icu/source/common/ucnv_cb.c
+++ b/src/third_party/icu/source/common/ucnv_cb.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
 *   Copyright (C) 2000-2006, International Business Machines
diff --git a/src/third_party/icu/source/common/ucnv_cnv.c b/src/third_party/icu/source/common/ucnv_cnv.cpp
similarity index 94%
rename from src/third_party/icu/source/common/ucnv_cnv.c
rename to src/third_party/icu/source/common/ucnv_cnv.cpp
index f8e2f83..ea71acf 100644
--- a/src/third_party/icu/source/common/ucnv_cnv.c
+++ b/src/third_party/icu/source/common/ucnv_cnv.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
@@ -31,6 +33,9 @@
                    const USetAdder *sa,
                    UConverterUnicodeSet which,
                    UErrorCode *pErrorCode) {
+    (void)cnv;
+    (void)which;
+    (void)pErrorCode;
     sa->addRange(sa->set, 0, 0x10ffff);
 }
 
@@ -39,6 +44,9 @@
                                const USetAdder *sa,
                                UConverterUnicodeSet which,
                                UErrorCode *pErrorCode) {
+    (void)cnv;
+    (void)which;
+    (void)pErrorCode;
     sa->addRange(sa->set, 0, 0xd7ff);
     sa->addRange(sa->set, 0xe000, 0x10ffff);
 }
diff --git a/src/third_party/icu/source/common/ucnv_cnv.h b/src/third_party/icu/source/common/ucnv_cnv.h
index 402e2c9..59be8bd 100644
--- a/src/third_party/icu/source/common/ucnv_cnv.h
+++ b/src/third_party/icu/source/common/ucnv_cnv.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
 *   Copyright (C) 1999-2011, International Business Machines
@@ -57,7 +59,7 @@
 } UConverterLoadArgs;
 
 #define UCNV_LOAD_ARGS_INITIALIZER \
-    { (int32_t)sizeof(UConverterLoadArgs), 0, FALSE, FALSE, 0, 0, NULL, NULL, NULL }
+    { (int32_t)sizeof(UConverterLoadArgs), 0, false, false, 0, 0, NULL, NULL, NULL }
 
 typedef void (*UConverterLoad) (UConverterSharedData *sharedData,
                                 UConverterLoadArgs *pArgs,
@@ -265,8 +267,8 @@
 U_CDECL_END
 
 /** Always use fallbacks from codepage to Unicode */
-#define TO_U_USE_FALLBACK(useFallback) TRUE
-#define UCNV_TO_U_USE_FALLBACK(cnv) TRUE
+#define TO_U_USE_FALLBACK(useFallback) true
+#define UCNV_TO_U_USE_FALLBACK(cnv) true
 
 /** Use fallbacks from Unicode to codepage when cnv->useFallback or for private-use code points */
 #define IS_PRIVATE_USE(c) ((uint32_t)((c)-0xe000)<0x1900 || (uint32_t)((c)-0xf0000)<0x20000)
diff --git a/src/third_party/icu/source/common/ucnv_ct.c b/src/third_party/icu/source/common/ucnv_ct.cpp
similarity index 96%
rename from src/third_party/icu/source/common/ucnv_ct.c
rename to src/third_party/icu/source/common/ucnv_ct.cpp
index 91d66e1..b40e1b2 100644
--- a/src/third_party/icu/source/common/ucnv_ct.c
+++ b/src/third_party/icu/source/common/ucnv_ct.cpp
@@ -1,10 +1,12 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
 *   Copyright (C) 2010-2015, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 **********************************************************************
 *   file name:  ucnv_ct.c
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -163,21 +165,22 @@
 } UConverterDataCompoundText;
 
 /*********** Compound Text Converter Protos ***********/
-static void
+U_CDECL_BEGIN
+static void U_CALLCONV
 _CompoundTextOpen(UConverter *cnv, UConverterLoadArgs *pArgs, UErrorCode *errorCode);
 
-static void
+static void U_CALLCONV
  _CompoundTextClose(UConverter *converter);
 
-static void
+static void U_CALLCONV
 _CompoundTextReset(UConverter *converter, UConverterResetChoice choice);
 
-static const char*
+static const char* U_CALLCONV
 _CompoundTextgetName(const UConverter* cnv);
 
 
 static int32_t findNextEsc(const char *source, const char *sourceLimit) {
-    int32_t length = sourceLimit - source;
+    int32_t length = static_cast<int32_t>(sourceLimit - source);
     int32_t i;
     for (i = 1; i < length; i++) {
         if (*(source + i) == 0x1B) {
@@ -255,14 +258,14 @@
     return state;
 }
 
-static void
+static void U_CALLCONV
 _CompoundTextOpen(UConverter *cnv, UConverterLoadArgs *pArgs, UErrorCode *errorCode){
     cnv->extraInfo = uprv_malloc (sizeof (UConverterDataCompoundText));
     if (cnv->extraInfo != NULL) {
         UConverterDataCompoundText *myConverterData = (UConverterDataCompoundText *) cnv->extraInfo;
 
         UConverterNamePieces stackPieces;
-        UConverterLoadArgs stackArgs={ (int32_t)sizeof(UConverterLoadArgs) };
+        UConverterLoadArgs stackArgs=UCNV_LOAD_ARGS_INITIALIZER;
 
         myConverterData->myConverterArray[COMPOUND_TEXT_SINGLE_0] = NULL;
         myConverterData->myConverterArray[COMPOUND_TEXT_SINGLE_1] = ucnv_loadSharedData("icu-internal-compound-s1", &stackPieces, &stackArgs, errorCode);
@@ -298,7 +301,7 @@
 }
 
 
-static void
+static void U_CALLCONV
 _CompoundTextClose(UConverter *converter) {
     UConverterDataCompoundText* myConverterData = (UConverterDataCompoundText*)(converter->extraInfo);
     int32_t i;
@@ -312,19 +315,23 @@
         }
 
         uprv_free(converter->extraInfo);
+        converter->extraInfo = NULL;
     }
 }
 
-static void
+static void U_CALLCONV
 _CompoundTextReset(UConverter *converter, UConverterResetChoice choice) {
+    (void)converter;
+    (void)choice;
 }
 
-static const char*
+static const char* U_CALLCONV
 _CompoundTextgetName(const UConverter* cnv){
+    (void)cnv;
     return "x11-compound-text";
 }
 
-static void
+static void U_CALLCONV
 UConverter_fromUnicode_CompoundText_OFFSETS(UConverterFromUnicodeArgs* args, UErrorCode* err){
     UConverter *cnv = args->converter;
     uint8_t *target = (uint8_t *) args->target;
@@ -456,7 +463,7 @@
 }
 
 
-static void
+static void U_CALLCONV
 UConverter_toUnicode_CompoundText_OFFSETS(UConverterToUnicodeArgs *args,
                                                UErrorCode* err){
     const char *mySource = (char *) args->source;
@@ -513,7 +520,7 @@
                     currentState = tmpState;
                 }
 
-                sourceOffset = uprv_strlen((char*)escSeqCompoundText[currentState]) - args->converter->toULength;
+                sourceOffset = static_cast<int32_t>(uprv_strlen((char*)escSeqCompoundText[currentState]) - args->converter->toULength);
 
                 mySource += sourceOffset;
 
@@ -572,7 +579,7 @@
     args->source = mySource;
 }
 
-static void
+static void U_CALLCONV
 _CompoundText_GetUnicodeSet(const UConverter *cnv,
                     const USetAdder *sa,
                     UConverterUnicodeSet which,
@@ -589,6 +596,7 @@
     sa->addRange(sa->set, 0x0020, 0x007F);
     sa->addRange(sa->set, 0x00A0, 0x00FF);
 }
+U_CDECL_END
 
 static const UConverterImpl _CompoundTextImpl = {
 
@@ -611,8 +619,11 @@
     _CompoundTextgetName,
     NULL,
     NULL,
-    _CompoundText_GetUnicodeSet
+    _CompoundText_GetUnicodeSet,
+    NULL,
+    NULL
 };
+
 static const UConverterStaticData _CompoundTextStaticData = {
     sizeof(UConverterStaticData),
     "COMPOUND_TEXT",
diff --git a/src/third_party/icu/source/common/ucnv_err.c b/src/third_party/icu/source/common/ucnv_err.cpp
similarity index 94%
rename from src/third_party/icu/source/common/ucnv_err.c
rename to src/third_party/icu/source/common/ucnv_err.cpp
index 0fb14f0..6b738fa 100644
--- a/src/third_party/icu/source/common/ucnv_err.c
+++ b/src/third_party/icu/source/common/ucnv_err.cpp
@@ -1,7 +1,9 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
  *****************************************************************************
  *
- *   Copyright (C) 1998-2014, International Business Machines
+ *   Copyright (C) 1998-2016, International Business Machines
  *   Corporation and others.  All Rights Reserved.
  *
  *****************************************************************************
@@ -26,7 +28,7 @@
 #include "unicode/ucnv.h"
 #include "ustrfmt.h"
 
-#define VALUE_STRING_LENGTH 32
+#define VALUE_STRING_LENGTH 48
 /*Magic # 32 = 4(number of char in value string) * 8(max number of bytes per char for any converter) */
 #define UNICODE_PERCENT_SIGN_CODEPOINT  0x0025
 #define UNICODE_U_CODEPOINT             0x0055
@@ -58,11 +60,12 @@
  * To avoid dependency on other code, this list is hard coded here.
  * When an ignorable code point is found and is unmappable, the default callbacks
  * will ignore them.
- * For a list of the default ignorable code points, use this link: http://unicode.org/cldr/utility/list-unicodeset.jsp?a=[%3ADI%3A]&g=
+ * For a list of the default ignorable code points, use this link:
+ * https://unicode.org/cldr/utility/list-unicodeset.jsp?a=%5B%3ADI%3A%5D&abb=on&g=&i=
  *
  * This list should be sync with the one in CharsetCallback.java
  */
-#define IS_DEFAULT_IGNORABLE_CODE_POINT(c) (\
+#define IS_DEFAULT_IGNORABLE_CODE_POINT(c) ( \
     (c == 0x00AD) || \
     (c == 0x034F) || \
     (c == 0x061C) || \
@@ -72,26 +75,15 @@
     (0x180B <= c && c <= 0x180E) || \
     (0x200B <= c && c <= 0x200F) || \
     (0x202A <= c && c <= 0x202E) || \
-    (c == 0x2060) || \
-    (0x2066 <= c && c <= 0x2069) || \
-    (0x2061 <= c && c <= 0x2064) || \
-    (0x206A <= c && c <= 0x206F) || \
+    (0x2060 <= c && c <= 0x206F) || \
     (c == 0x3164) || \
-    (0x0FE00 <= c && c <= 0x0FE0F) || \
-    (c == 0x0FEFF) || \
-    (c == 0x0FFA0) || \
-    (0x01BCA0  <= c && c <= 0x01BCA3) || \
-    (0x01D173 <= c && c <= 0x01D17A) || \
-    (c == 0x0E0001) || \
-    (0x0E0020 <= c && c <= 0x0E007F) || \
-    (0x0E0100 <= c && c <= 0x0E01EF) || \
-    (c == 0x2065) || \
-    (0x0FFF0 <= c && c <= 0x0FFF8) || \
-    (c == 0x0E0000) || \
-    (0x0E0002 <= c && c <= 0x0E001F) || \
-    (0x0E0080 <= c && c <= 0x0E00FF) || \
-    (0x0E01F0 <= c && c <= 0x0E0FFF) \
-    )
+    (0xFE00 <= c && c <= 0xFE0F) || \
+    (c == 0xFEFF) || \
+    (c == 0xFFA0) || \
+    (0xFFF0 <= c && c <= 0xFFF8) || \
+    (0x1BCA0 <= c && c <= 0x1BCA3) || \
+    (0x1D173 <= c && c <= 0x1D17A) || \
+    (0xE0000 <= c && c <= 0xE0FFF))
 
 
 /*Function Pointer STOPS at the ILLEGAL_SEQUENCE */
@@ -105,6 +97,10 @@
                   UConverterCallbackReason reason,
                   UErrorCode * err)
 {
+    (void)context;
+    (void)fromUArgs;
+    (void)codeUnits;
+    (void)length;
     if (reason == UCNV_UNASSIGNED && IS_DEFAULT_IGNORABLE_CODE_POINT(codePoint))
     {
         /*
@@ -128,6 +124,7 @@
                    UErrorCode * err)
 {
     /* the caller must have set the error code accordingly */
+    (void)context; (void)toUArgs; (void)codePoints; (void)length; (void)reason; (void)err;
     return;
 }
 
@@ -141,6 +138,9 @@
                   UConverterCallbackReason reason,
                   UErrorCode * err)
 {
+    (void)fromUArgs;
+    (void)codeUnits;
+    (void)length;
     if (reason <= UCNV_IRREGULAR)
     {
         if (reason == UCNV_UNASSIGNED && IS_DEFAULT_IGNORABLE_CODE_POINT(codePoint))
@@ -169,6 +169,8 @@
                   UConverterCallbackReason reason,
                   UErrorCode * err)
 {
+    (void)codeUnits;
+    (void)length;
     if (reason <= UCNV_IRREGULAR)
     {
         if (reason == UCNV_UNASSIGNED && IS_DEFAULT_IGNORABLE_CODE_POINT(codePoint))
@@ -366,6 +368,9 @@
                  UConverterCallbackReason reason,
                  UErrorCode * err)
 {
+    (void)toArgs;
+    (void)codeUnits;
+    (void)length;
     if (reason <= UCNV_IRREGULAR)
     {
         if (context == NULL || (*((char*)context) == UCNV_PRV_STOP_ON_ILLEGAL && reason == UCNV_UNASSIGNED))
@@ -386,6 +391,8 @@
                  UConverterCallbackReason reason,
                  UErrorCode * err)
 {
+    (void)codeUnits;
+    (void)length;
     if (reason <= UCNV_IRREGULAR)
     {
         if (context == NULL || (*((char*)context) == UCNV_PRV_STOP_ON_ILLEGAL && reason == UCNV_UNASSIGNED))
diff --git a/src/third_party/icu/source/common/ucnv_ext.cpp b/src/third_party/icu/source/common/ucnv_ext.cpp
index 419310e..ee89db4 100644
--- a/src/third_party/icu/source/common/ucnv_ext.cpp
+++ b/src/third_party/icu/source/common/ucnv_ext.cpp
@@ -1,12 +1,14 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
-*   Copyright (C) 2003-2013, International Business Machines
+*   Copyright (C) 2003-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *
 ******************************************************************************
 *   file name:  ucnv_ext.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -20,9 +22,12 @@
 
 #if !UCONFIG_NO_CONVERSION && !UCONFIG_NO_LEGACY_CONVERSION
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/uset.h"
+#include "unicode/ustring.h"
 #include "ucnv_bld.h"
 #include "ucnv_cnv.h"
 #include "ucnv_ext.h"
@@ -692,10 +697,13 @@
         switch(length) {
         case 3:
             *p++=(uint8_t)(value>>16);
-        case 2: /*fall through*/
+            U_FALLTHROUGH;
+        case 2:
             *p++=(uint8_t)(value>>8);
-        case 1: /*fall through*/
+            U_FALLTHROUGH;
+        case 1:
             *p++=(uint8_t)value;
+            U_FALLTHROUGH;
         default:
             break; /* will never occur */
         }
@@ -882,7 +890,7 @@
         } else {
             /* the match did not use all of preFromU[] - keep the rest for replay */
             int32_t length=cnv->preFromULength-match;
-            uprv_memmove(cnv->preFromU, cnv->preFromU+match, length*U_SIZEOF_UCHAR);
+            u_memmove(cnv->preFromU, cnv->preFromU+match, length);
             cnv->preFromULength=(int8_t)-length;
         }
 
diff --git a/src/third_party/icu/source/common/ucnv_ext.h b/src/third_party/icu/source/common/ucnv_ext.h
index 1ec4bdf..dceea7e 100644
--- a/src/third_party/icu/source/common/ucnv_ext.h
+++ b/src/third_party/icu/source/common/ucnv_ext.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 ******************************************************************************
 *   file name:  ucnv_ext.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
diff --git a/src/third_party/icu/source/common/ucnv_imp.h b/src/third_party/icu/source/common/ucnv_imp.h
index 27c373a..c5e6aeb 100644
--- a/src/third_party/icu/source/common/ucnv_imp.h
+++ b/src/third_party/icu/source/common/ucnv_imp.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
 *   Copyright (C) 1999-2011, International Business Machines
diff --git a/src/third_party/icu/source/common/ucnv_io.cpp b/src/third_party/icu/source/common/ucnv_io.cpp
index c51cb39..2d9741f 100644
--- a/src/third_party/icu/source/common/ucnv_io.cpp
+++ b/src/third_party/icu/source/common/ucnv_io.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
@@ -27,7 +29,9 @@
 *******************************************************************************
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/utypes.h"
 
 #if !UCONFIG_NO_CONVERSION
@@ -380,8 +384,9 @@
 #   error U_CHARSET_FAMILY is not valid
 #endif
 
+
 /* @see ucnv_compareNames */
-U_CFUNC char * U_EXPORT2
+U_CAPI char * U_CALLCONV
 ucnv_io_stripASCIIForCompare(char *dst, const char *name) {
     char *dstItr = dst;
     uint8_t type, nextType;
@@ -416,7 +421,7 @@
     return dst;
 }
 
-U_CFUNC char * U_EXPORT2
+U_CAPI char * U_CALLCONV
 ucnv_io_stripEBCDICForCompare(char *dst, const char *name) {
     char *dstItr = dst;
     uint8_t type, nextType;
@@ -732,9 +737,7 @@
     return UINT32_MAX;
 }
 
-
-
-U_CFUNC const char *
+U_CAPI const char *
 ucnv_io_getConverterName(const char *alias, UBool *containsOption, UErrorCode *pErrorCode) {
     const char *aliasTmp = alias;
     int32_t i = 0;
@@ -765,6 +768,9 @@
     return NULL;
 }
 
+U_CDECL_BEGIN
+
+
 static int32_t U_CALLCONV
 ucnv_io_countStandardAliases(UEnumeration *enumerator, UErrorCode * /*pErrorCode*/) {
     int32_t value = 0;
@@ -777,7 +783,7 @@
     return value;
 }
 
-static const char* U_CALLCONV
+static const char * U_CALLCONV
 ucnv_io_nextStandardAliases(UEnumeration *enumerator,
                             int32_t* resultLength,
                             UErrorCode * /*pErrorCode*/)
@@ -815,6 +821,8 @@
     uprv_free(enumerator);
 }
 
+U_CDECL_END
+
 /* Enumerate the aliases for the specified converter and standard tag */
 static const UEnumeration gEnumAliases = {
     NULL,
@@ -1011,12 +1019,15 @@
     return NULL;
 }
 
+U_CDECL_BEGIN
+
+
 static int32_t U_CALLCONV
 ucnv_io_countAllConverters(UEnumeration * /*enumerator*/, UErrorCode * /*pErrorCode*/) {
     return gMainTable.converterListSize;
 }
 
-static const char* U_CALLCONV
+static const char * U_CALLCONV
 ucnv_io_nextAllConverters(UEnumeration *enumerator,
                             int32_t* resultLength,
                             UErrorCode * /*pErrorCode*/)
@@ -1041,7 +1052,7 @@
 ucnv_io_resetAllConverters(UEnumeration *enumerator, UErrorCode * /*pErrorCode*/) {
     *((uint16_t *)(enumerator->context)) = 0;
 }
-
+U_CDECL_END
 static const UEnumeration gEnumAllConverters = {
     NULL,
     NULL,
@@ -1076,7 +1087,7 @@
     return myEnum;
 }
 
-U_CFUNC uint16_t
+U_CAPI uint16_t
 ucnv_io_countKnownConverters(UErrorCode *pErrorCode) {
     if (haveAliasData(pErrorCode)) {
         return (uint16_t)gMainTable.converterListSize;
@@ -1086,7 +1097,11 @@
 
 /* alias table swapping ----------------------------------------------------- */
 
+U_CDECL_BEGIN
+
 typedef char * U_CALLCONV StripForCompareFn(char *dst, const char *name);
+U_CDECL_END
+
 
 /*
  * row of a temporary array
@@ -1110,7 +1125,7 @@
     STACK_ROW_CAPACITY=500
 };
 
-static int32_t
+static int32_t U_CALLCONV
 io_compareRows(const void *context, const void *left, const void *right) {
     char strippedLeft[UCNV_MAX_CONVERTER_NAME_LENGTH],
          strippedRight[UCNV_MAX_CONVERTER_NAME_LENGTH];
@@ -1298,13 +1313,13 @@
                         oldIndex=tempTable.rows[i].sortIndex;
                         ds->swapArray16(ds, p+oldIndex, 2, r+i, pErrorCode);
                     }
-                    uprv_memcpy(q, r, 2*count);
+                    uprv_memcpy(q, r, 2*(size_t)count);
 
                     for(i=0; i<count; ++i) {
                         oldIndex=tempTable.rows[i].sortIndex;
                         ds->swapArray16(ds, p2+oldIndex, 2, r+i, pErrorCode);
                     }
-                    uprv_memcpy(q2, r, 2*count);
+                    uprv_memcpy(q2, r, 2*(size_t)count);
                 }
             }
 
diff --git a/src/third_party/icu/source/common/ucnv_io.h b/src/third_party/icu/source/common/ucnv_io.h
index 060ffd0..8f2d7b5 100644
--- a/src/third_party/icu/source/common/ucnv_io.h
+++ b/src/third_party/icu/source/common/ucnv_io.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
  **********************************************************************
  *   Copyright (C) 1999-2006, International Business Machines
@@ -75,10 +77,10 @@
 #   error U_CHARSET_FAMILY is not valid
 #endif
 
-U_CAPI char * U_EXPORT2
+U_CAPI char * U_CALLCONV
 ucnv_io_stripASCIIForCompare(char *dst, const char *name);
 
-U_CAPI char * U_EXPORT2
+U_CAPI char * U_CALLCONV
 ucnv_io_stripEBCDICForCompare(char *dst, const char *name);
 
 /**
@@ -91,7 +93,7 @@
  * @param pErrorCode The error code
  * @return the converter name in mixed-case, return NULL if the alias is not found.
  */
-U_CFUNC const char *
+U_CAPI const char *
 ucnv_io_getConverterName(const char *alias, UBool *containsOption, UErrorCode *pErrorCode);
 
 /**
@@ -99,7 +101,7 @@
  * @param pErrorCode The error code
  * @return the number of all aliases
  */
-U_CFUNC uint16_t
+U_CAPI uint16_t
 ucnv_io_countKnownConverters(UErrorCode *pErrorCode);
 
 /**
diff --git a/src/third_party/icu/source/common/ucnv_lmb.c b/src/third_party/icu/source/common/ucnv_lmb.cpp
similarity index 96%
rename from src/third_party/icu/source/common/ucnv_lmb.c
rename to src/third_party/icu/source/common/ucnv_lmb.cpp
index 01d0aa1..1683928 100644
--- a/src/third_party/icu/source/common/ucnv_lmb.c
+++ b/src/third_party/icu/source/common/ucnv_lmb.cpp
@@ -1,10 +1,12 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*  
 **********************************************************************
-*   Copyright (C) 2000-2015, International Business Machines
+*   Copyright (C) 2000-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 **********************************************************************
 *   file name:  ucnv_lmb.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   4 (not used)
 *   indentation:4
 *
@@ -580,7 +582,9 @@
   }
 UConverterDataLMBCS;
 
-static void _LMBCSClose(UConverter * _this);
+U_CDECL_BEGIN
+static void  U_CALLCONV _LMBCSClose(UConverter * _this);
+U_CDECL_END
 
 #define DECLARE_LMBCS_DATA(n) \
 static const UConverterImpl _LMBCSImpl##n={\
@@ -598,7 +602,9 @@
     NULL,\
     NULL,\
     _LMBCSSafeClone,\
-    ucnv_getCompleteUnicodeSet\
+    ucnv_getCompleteUnicodeSet,\
+    NULL,\
+    NULL\
 };\
 static const UConverterStaticData _LMBCSStaticData##n={\
   sizeof(UConverterStaticData),\
@@ -614,7 +620,7 @@
 optimization group. So, we put the common stuff into a worker function, 
 and set up another macro to stamp out the 12 open functions:*/
 #define DEFINE_LMBCS_OPEN(n) \
-static void \
+static void U_CALLCONV \
    _LMBCSOpen##n(UConverter* _this, UConverterLoadArgs* pArgs, UErrorCode* err) \
 { _LMBCSOpenWorker(_this, pArgs, err, n); }
 
@@ -627,12 +633,12 @@
                  UErrorCode*  err,
                  ulmbcs_byte_t OptGroup)
 {
-    UConverterDataLMBCS * extraInfo = _this->extraInfo =
-        (UConverterDataLMBCS*)uprv_malloc (sizeof (UConverterDataLMBCS));
+    UConverterDataLMBCS * extraInfo = (UConverterDataLMBCS*)uprv_malloc (sizeof (UConverterDataLMBCS));
+    _this->extraInfo = extraInfo;
     if(extraInfo != NULL)
     {
         UConverterNamePieces stackPieces;
-        UConverterLoadArgs stackArgs={ (int32_t)sizeof(UConverterLoadArgs) };
+        UConverterLoadArgs stackArgs= UCNV_LOAD_ARGS_INITIALIZER;
         ulmbcs_byte_t i;
 
         uprv_memset(extraInfo, 0, sizeof(UConverterDataLMBCS));
@@ -659,7 +665,8 @@
     }
 }
 
-static void 
+U_CDECL_BEGIN
+static void  U_CALLCONV
 _LMBCSClose(UConverter *   _this) 
 {
     if (_this->extraInfo != NULL)
@@ -684,11 +691,12 @@
     UConverterDataLMBCS lmbcs;
 } LMBCSClone;
 
-static UConverter * 
+static UConverter *  U_CALLCONV
 _LMBCSSafeClone(const UConverter *cnv, 
                 void *stackBuffer, 
                 int32_t *pBufferSize, 
                 UErrorCode *status) {
+    (void)status;
     LMBCSClone *newLMBCS;
     UConverterDataLMBCS *extraInfo;
     int32_t i;
@@ -793,12 +801,16 @@
    {
    case 4:
       *pLMBCS++ = (ulmbcs_byte_t)(value >> 24);
-   case 3: /*fall through*/
+      U_FALLTHROUGH;
+   case 3:
       *pLMBCS++ = (ulmbcs_byte_t)(value >> 16);
-   case 2: /*fall through*/
+      U_FALLTHROUGH;
+   case 2:
       *pLMBCS++ = (ulmbcs_byte_t)(value >> 8);
-   case 1: /*fall through*/
+      U_FALLTHROUGH;
+   case 1:
       *pLMBCS++ = (ulmbcs_byte_t)value;
+      U_FALLTHROUGH;
    default:
       /* will never occur */
       break;
@@ -836,7 +848,7 @@
 
 
 /* The main Unicode to LMBCS conversion function */
-static void 
+static void  U_CALLCONV
 _LMBCSFromUnicode(UConverterFromUnicodeArgs*     args,
                   UErrorCode*     err)
 {
@@ -954,26 +966,26 @@
 
                 if(extraInfo->localeConverterIndex < ULMBCS_DOUBLEOPTGROUP_START)
                 {
-                  bytes_written = LMBCSConversionWorker (extraInfo,
+                  bytes_written = (int32_t)LMBCSConversionWorker (extraInfo,
                      ULMBCS_GRP_L1, pLMBCS, &uniChar,
                      &lastConverterIndex, groups_tried);
 
                   if(!bytes_written)
                   {
-                     bytes_written = LMBCSConversionWorker (extraInfo,
+                     bytes_written = (int32_t)LMBCSConversionWorker (extraInfo,
                          ULMBCS_GRP_EXCEPT, pLMBCS, &uniChar,
                          &lastConverterIndex, groups_tried);
                   }
                   if(!bytes_written)
                   {
-                      bytes_written = LMBCSConversionWorker (extraInfo,
+                      bytes_written = (int32_t)LMBCSConversionWorker (extraInfo,
                           extraInfo->localeConverterIndex, pLMBCS, &uniChar,
                           &lastConverterIndex, groups_tried);
                   }
                 }
                 else
                 {
-                     bytes_written = LMBCSConversionWorker (extraInfo,
+                     bytes_written = (int32_t)LMBCSConversionWorker (extraInfo,
                          extraInfo->localeConverterIndex, pLMBCS, &uniChar,
                          &lastConverterIndex, groups_tried);
                 }
@@ -1095,15 +1107,17 @@
    all input as required by ICU converter semantics.
 */
 
-#define CHECK_SOURCE_LIMIT(index) \
-     if (args->source+index > args->sourceLimit){\
-         *err = U_TRUNCATED_CHAR_FOUND;\
-         args->source = args->sourceLimit;\
-         return 0xffff;}
+#define CHECK_SOURCE_LIMIT(index) UPRV_BLOCK_MACRO_BEGIN { \
+    if (args->source+index > args->sourceLimit) { \
+        *err = U_TRUNCATED_CHAR_FOUND; \
+        args->source = args->sourceLimit; \
+        return 0xffff; \
+    } \
+} UPRV_BLOCK_MACRO_END
 
 /* Return the Unicode representation for the current LMBCS character */
 
-static UChar32 
+static UChar32  U_CALLCONV
 _LMBCSGetNextUCharWorker(UConverterToUnicodeArgs*   args,
                          UErrorCode*   err)
 {
@@ -1245,7 +1259,7 @@
 /* The exported function that converts lmbcs to one or more
    UChars - currently UTF-16
 */
-static void 
+static void  U_CALLCONV
 _LMBCSToUnicodeWithOffsets(UConverterToUnicodeArgs*    args,
                      UErrorCode*    err)
 {
@@ -1369,4 +1383,6 @@
 DECLARE_LMBCS_DATA(18)
 DECLARE_LMBCS_DATA(19)
 
+U_CDECL_END
+
 #endif /* #if !UCONFIG_NO_LEGACY_CONVERSION */
diff --git a/src/third_party/icu/source/common/ucnv_set.c b/src/third_party/icu/source/common/ucnv_set.cpp
similarity index 92%
rename from src/third_party/icu/source/common/ucnv_set.c
rename to src/third_party/icu/source/common/ucnv_set.cpp
index 3d8d392..926cee0 100644
--- a/src/third_party/icu/source/common/ucnv_set.c
+++ b/src/third_party/icu/source/common/ucnv_set.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  ucnv_set.c
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
diff --git a/src/third_party/icu/source/common/ucnv_u16.c b/src/third_party/icu/source/common/ucnv_u16.cpp
similarity index 96%
rename from src/third_party/icu/source/common/ucnv_u16.c
rename to src/third_party/icu/source/common/ucnv_u16.cpp
index eac3a9d..63bed57 100644
--- a/src/third_party/icu/source/common/ucnv_u16.c
+++ b/src/third_party/icu/source/common/ucnv_u16.cpp
@@ -1,10 +1,12 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*  
 **********************************************************************
 *   Copyright (C) 2002-2015, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 **********************************************************************
 *   file name:  ucnv_u16.c
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -14,12 +16,15 @@
 *   UTF-16 converter implementation. Used to be in ucnv_utf.c.
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/utypes.h"
 
 #if !UCONFIG_NO_CONVERSION
 
 #include "unicode/ucnv.h"
+#include "unicode/uversion.h"
 #include "ucnv_bld.h"
 #include "ucnv_cnv.h"
 #include "cmemory.h"
@@ -28,11 +33,12 @@
     UCNV_NEED_TO_WRITE_BOM=1
 };
 
+U_CDECL_BEGIN
 /*
  * The UTF-16 toUnicode implementation is also used for the Java-specific
  * "with BOM" variants of UTF-16BE and UTF-16LE.
  */
-static void
+static void  U_CALLCONV
 _UTF16ToUnicodeWithOffsets(UConverterToUnicodeArgs *pArgs,
                            UErrorCode *pErrorCode);
 
@@ -45,7 +51,7 @@
 #endif
 
 
-static void
+static void  U_CALLCONV
 _UTF16BEFromUnicodeWithOffsets(UConverterFromUnicodeArgs *pArgs,
                                UErrorCode *pErrorCode) {
     UConverter *cnv;
@@ -68,7 +74,7 @@
 
     /* write the BOM if necessary */
     if(cnv->fromUnicodeStatus==UCNV_NEED_TO_WRITE_BOM) {
-        static const char bom[]={ (char)0xfe, (char)0xff };
+        static const char bom[]={ (char)0xfeu, (char)0xffu };
         ucnv_fromUWriteBytes(cnv,
                              bom, 2,
                              &pArgs->target, pArgs->targetLimit,
@@ -249,7 +255,7 @@
     pArgs->offsets=offsets;
 }
 
-static void
+static void  U_CALLCONV
 _UTF16BEToUnicodeWithOffsets(UConverterToUnicodeArgs *pArgs,
                              UErrorCode *pErrorCode) {
     UConverter *cnv;
@@ -487,7 +493,7 @@
     pArgs->offsets=offsets;
 }
 
-static UChar32
+static UChar32  U_CALLCONV
 _UTF16BEGetNextUChar(UConverterToUnicodeArgs *pArgs, UErrorCode *err) {
     const uint8_t *s, *sourceLimit;
     UChar32 c;
@@ -566,7 +572,7 @@
     return c;
 } 
 
-static void
+static void  U_CALLCONV
 _UTF16BEReset(UConverter *cnv, UConverterResetChoice choice) {
     if(choice<=UCNV_RESET_TO_UNICODE) {
         /* reset toUnicode state */
@@ -582,10 +588,11 @@
     }
 }
 
-static void
+static void  U_CALLCONV
 _UTF16BEOpen(UConverter *cnv,
              UConverterLoadArgs *pArgs,
              UErrorCode *pErrorCode) {
+    (void)pArgs;
     if(UCNV_GET_VERSION(cnv)<=1) {
         _UTF16BEReset(cnv, UCNV_RESET_BOTH);
     } else {
@@ -593,7 +600,7 @@
     }
 }
 
-static const char *
+static const char *  U_CALLCONV
 _UTF16BEGetName(const UConverter *cnv) {
     if(UCNV_GET_VERSION(cnv)==0) {
         return "UTF-16BE";
@@ -601,6 +608,7 @@
         return "UTF-16BE,version=1";
     }
 }
+U_CDECL_END
 
 static const UConverterImpl _UTF16BEImpl={
     UCNV_UTF16_BigEndian,
@@ -622,7 +630,10 @@
     _UTF16BEGetName,
     NULL,
     NULL,
-    ucnv_getNonSurrogateUnicodeSet
+    ucnv_getNonSurrogateUnicodeSet,
+
+    NULL,
+    NULL
 };
 
 static const UConverterStaticData _UTF16BEStaticData={
@@ -640,8 +651,8 @@
         UCNV_IMMUTABLE_SHARED_DATA_INITIALIZER(&_UTF16BEStaticData, &_UTF16BEImpl);
 
 /* UTF-16LE ----------------------------------------------------------------- */
-
-static void
+U_CDECL_BEGIN
+static void  U_CALLCONV
 _UTF16LEFromUnicodeWithOffsets(UConverterFromUnicodeArgs *pArgs,
                                UErrorCode *pErrorCode) {
     UConverter *cnv;
@@ -664,7 +675,7 @@
 
     /* write the BOM if necessary */
     if(cnv->fromUnicodeStatus==UCNV_NEED_TO_WRITE_BOM) {
-        static const char bom[]={ (char)0xff, (char)0xfe };
+        static const char bom[]={ (char)0xffu, (char)0xfeu };
         ucnv_fromUWriteBytes(cnv,
                              bom, 2,
                              &pArgs->target, pArgs->targetLimit,
@@ -845,7 +856,7 @@
     pArgs->offsets=offsets;
 }
 
-static void
+static void  U_CALLCONV
 _UTF16LEToUnicodeWithOffsets(UConverterToUnicodeArgs *pArgs,
                              UErrorCode *pErrorCode) {
     UConverter *cnv;
@@ -1083,7 +1094,7 @@
     pArgs->offsets=offsets;
 }
 
-static UChar32
+static UChar32  U_CALLCONV
 _UTF16LEGetNextUChar(UConverterToUnicodeArgs *pArgs, UErrorCode *err) {
     const uint8_t *s, *sourceLimit;
     UChar32 c;
@@ -1162,7 +1173,7 @@
     return c;
 } 
 
-static void
+static void  U_CALLCONV
 _UTF16LEReset(UConverter *cnv, UConverterResetChoice choice) {
     if(choice<=UCNV_RESET_TO_UNICODE) {
         /* reset toUnicode state */
@@ -1178,10 +1189,11 @@
     }
 }
 
-static void
+static void  U_CALLCONV
 _UTF16LEOpen(UConverter *cnv,
              UConverterLoadArgs *pArgs,
              UErrorCode *pErrorCode) {
+    (void)pArgs;
     if(UCNV_GET_VERSION(cnv)<=1) {
         _UTF16LEReset(cnv, UCNV_RESET_BOTH);
     } else {
@@ -1189,7 +1201,7 @@
     }
 }
 
-static const char *
+static const char *  U_CALLCONV
 _UTF16LEGetName(const UConverter *cnv) {
     if(UCNV_GET_VERSION(cnv)==0) {
         return "UTF-16LE";
@@ -1197,6 +1209,7 @@
         return "UTF-16LE,version=1";
     }
 }
+U_CDECL_END
 
 static const UConverterImpl _UTF16LEImpl={
     UCNV_UTF16_LittleEndian,
@@ -1218,7 +1231,10 @@
     _UTF16LEGetName,
     NULL,
     NULL,
-    ucnv_getNonSurrogateUnicodeSet
+    ucnv_getNonSurrogateUnicodeSet,
+
+    NULL,
+    NULL
 };
 
 
@@ -1261,8 +1277,8 @@
  * - UTF-16BE,version=1 (Java "UnicodeBig" encoding) and
  *   UTF-16LE,version=1 (Java "UnicodeLittle" encoding) treat a reverse BOM as an error.
  */
-
-static void
+U_CDECL_BEGIN
+static void  U_CALLCONV
 _UTF16Reset(UConverter *cnv, UConverterResetChoice choice) {
     if(choice<=UCNV_RESET_TO_UNICODE) {
         /* reset toUnicode: state=0 */
@@ -1273,10 +1289,10 @@
         cnv->fromUnicodeStatus=UCNV_NEED_TO_WRITE_BOM;
     }
 }
-
-static const UConverterSharedData _UTF16v2Data;
-
-static void
+U_CDECL_END
+extern const UConverterSharedData _UTF16v2Data;
+U_CDECL_BEGIN
+static void U_CALLCONV
 _UTF16Open(UConverter *cnv,
            UConverterLoadArgs *pArgs,
            UErrorCode *pErrorCode) {
@@ -1297,7 +1313,7 @@
     }
 }
 
-static const char *
+static const char *  U_CALLCONV
 _UTF16GetName(const UConverter *cnv) {
     if(UCNV_GET_VERSION(cnv)==0) {
         return "UTF-16";
@@ -1307,14 +1323,23 @@
         return "UTF-16,version=2";
     }
 }
+U_CDECL_END
+extern const UConverterSharedData _UTF16Data;
 
-const UConverterSharedData _UTF16Data;
+static inline bool IS_UTF16BE(const UConverter *cnv) {
+    return ((cnv)->sharedData == &_UTF16BEData);
+}
 
-#define IS_UTF16BE(cnv) ((cnv)->sharedData==&_UTF16BEData)
-#define IS_UTF16LE(cnv) ((cnv)->sharedData==&_UTF16LEData)
-#define IS_UTF16(cnv) ((cnv)->sharedData==&_UTF16Data || (cnv)->sharedData==&_UTF16v2Data)
+static inline bool IS_UTF16LE(const UConverter *cnv) {
+    return ((cnv)->sharedData == &_UTF16LEData);
+}
 
-static void
+static inline bool IS_UTF16(const UConverter *cnv) {
+    return ((cnv)->sharedData==&_UTF16Data) || ((cnv)->sharedData == &_UTF16v2Data);
+}
+
+U_CDECL_BEGIN
+static void U_CALLCONV
 _UTF16ToUnicodeWithOffsets(UConverterToUnicodeArgs *pArgs,
                            UErrorCode *pErrorCode) {
     UConverter *cnv=pArgs->converter;
@@ -1454,7 +1479,7 @@
     cnv->mode=state;
 }
 
-static UChar32
+static UChar32 U_CALLCONV
 _UTF16GetNextUChar(UConverterToUnicodeArgs *pArgs,
                    UErrorCode *pErrorCode) {
     switch(pArgs->converter->mode) {
@@ -1466,6 +1491,7 @@
         return UCNV_GET_NEXT_UCHAR_USE_TO_U;
     }
 }
+U_CDECL_END
 
 static const UConverterImpl _UTF16Impl = {
     UCNV_UTF16,
@@ -1487,7 +1513,10 @@
     _UTF16GetName,
     NULL,
     NULL,
-    ucnv_getNonSurrogateUnicodeSet
+    ucnv_getNonSurrogateUnicodeSet,
+
+    NULL,
+    NULL
 };
 
 static const UConverterStaticData _UTF16StaticData = {
@@ -1529,7 +1558,10 @@
     _UTF16GetName,
     NULL,
     NULL,
-    ucnv_getNonSurrogateUnicodeSet
+    ucnv_getNonSurrogateUnicodeSet,
+
+    NULL,
+    NULL
 };
 
 static const UConverterStaticData _UTF16v2StaticData = {
@@ -1544,7 +1576,7 @@
     { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } /* reserved */
 };
 
-static const UConverterSharedData _UTF16v2Data =
+const UConverterSharedData _UTF16v2Data =
         UCNV_IMMUTABLE_SHARED_DATA_INITIALIZER(&_UTF16v2StaticData, &_UTF16v2Impl);
 
 #endif
diff --git a/src/third_party/icu/source/common/ucnv_u32.c b/src/third_party/icu/source/common/ucnv_u32.cpp
similarity index 95%
rename from src/third_party/icu/source/common/ucnv_u32.c
rename to src/third_party/icu/source/common/ucnv_u32.cpp
index 15bafe3..55c9798 100644
--- a/src/third_party/icu/source/common/ucnv_u32.c
+++ b/src/third_party/icu/source/common/ucnv_u32.cpp
@@ -1,10 +1,12 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*  
 **********************************************************************
 *   Copyright (C) 2002-2015, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 **********************************************************************
 *   file name:  ucnv_u32.c
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -14,10 +16,12 @@
 *   UTF-32 converter implementation. Used to be in ucnv_utf.c.
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/utypes.h"
 
-#if !UCONFIG_NO_CONVERSION
+#if !UCONFIG_NO_CONVERSION && !UCONFIG_ONLY_HTML_CONVERSION
 
 #include "unicode/ucnv.h"
 #include "unicode/utf.h"
@@ -41,8 +45,8 @@
 };
 
 /* UTF-32BE ----------------------------------------------------------------- */
-
-static void
+U_CDECL_BEGIN
+static void U_CALLCONV
 T_UConverter_toUnicode_UTF32_BE(UConverterToUnicodeArgs * args,
                                 UErrorCode * err)
 {
@@ -54,7 +58,7 @@
     uint32_t ch, i;
 
     /* Restore state of current sequence */
-    if (args->converter->toUnicodeStatus && myTarget < targetLimit) {
+    if (args->converter->toULength > 0 && myTarget < targetLimit) {
         i = args->converter->toULength;       /* restore # of bytes consumed */
         args->converter->toULength = 0;
 
@@ -121,7 +125,7 @@
     args->source = (const char *) mySource;
 }
 
-static void
+static void U_CALLCONV
 T_UConverter_toUnicode_UTF32_BE_OFFSET_LOGIC(UConverterToUnicodeArgs * args,
                                              UErrorCode * err)
 {
@@ -135,7 +139,7 @@
     int32_t offsetNum = 0;
 
     /* Restore state of current sequence */
-    if (args->converter->toUnicodeStatus && myTarget < targetLimit) {
+    if (args->converter->toULength > 0 && myTarget < targetLimit) {
         i = args->converter->toULength;       /* restore # of bytes consumed */
         args->converter->toULength = 0;
 
@@ -208,7 +212,7 @@
     args->offsets = myOffsets;
 }
 
-static void
+static void U_CALLCONV
 T_UConverter_fromUnicode_UTF32_BE(UConverterFromUnicodeArgs * args,
                                   UErrorCode * err)
 {
@@ -227,7 +231,7 @@
 
     /* write the BOM if necessary */
     if(args->converter->fromUnicodeStatus==UCNV_NEED_TO_WRITE_BOM) {
-        static const char bom[]={ 0, 0, (char)0xfe, (char)0xff };
+        static const char bom[]={ 0, 0, (char)0xfeu, (char)0xffu };
         ucnv_fromUWriteBytes(args->converter,
                              bom, 4,
                              &args->target, args->targetLimit,
@@ -309,7 +313,7 @@
     args->source = mySource;
 }
 
-static void
+static void U_CALLCONV
 T_UConverter_fromUnicode_UTF32_BE_OFFSET_LOGIC(UConverterFromUnicodeArgs * args,
                                                UErrorCode * err)
 {
@@ -330,7 +334,7 @@
 
     /* write the BOM if necessary */
     if(args->converter->fromUnicodeStatus==UCNV_NEED_TO_WRITE_BOM) {
-        static const char bom[]={ 0, 0, (char)0xfe, (char)0xff };
+        static const char bom[]={ 0, 0, (char)0xfeu, (char)0xffu };
         ucnv_fromUWriteBytes(args->converter,
                              bom, 4,
                              &args->target, args->targetLimit,
@@ -416,7 +420,7 @@
     args->offsets = myOffsets;
 }
 
-static UChar32
+static UChar32 U_CALLCONV
 T_UConverter_getNextUChar_UTF32_BE(UConverterToUnicodeArgs* args,
                                    UErrorCode* err)
 {
@@ -460,7 +464,7 @@
     *err = U_ILLEGAL_CHAR_FOUND;
     return 0xffff;
 }
-
+U_CDECL_END
 static const UConverterImpl _UTF32BEImpl = {
     UCNV_UTF32_BigEndian,
 
@@ -481,7 +485,10 @@
     NULL,
     NULL,
     NULL,
-    ucnv_getNonSurrogateUnicodeSet
+    ucnv_getNonSurrogateUnicodeSet,
+
+    NULL,
+    NULL
 };
 
 /* The 1232 CCSID refers to any version of Unicode with any endianess of UTF-32 */
@@ -500,8 +507,8 @@
         UCNV_IMMUTABLE_SHARED_DATA_INITIALIZER(&_UTF32BEStaticData, &_UTF32BEImpl);
 
 /* UTF-32LE ---------------------------------------------------------- */
-
-static void
+U_CDECL_BEGIN
+static void U_CALLCONV
 T_UConverter_toUnicode_UTF32_LE(UConverterToUnicodeArgs * args,
                                 UErrorCode * err)
 {
@@ -513,7 +520,7 @@
     uint32_t ch, i;
 
     /* Restore state of current sequence */
-    if (args->converter->toUnicodeStatus && myTarget < targetLimit)
+    if (args->converter->toULength > 0 && myTarget < targetLimit)
     {
         i = args->converter->toULength;       /* restore # of bytes consumed */
         args->converter->toULength = 0;
@@ -586,7 +593,7 @@
     args->source = (const char *) mySource;
 }
 
-static void
+static void U_CALLCONV
 T_UConverter_toUnicode_UTF32_LE_OFFSET_LOGIC(UConverterToUnicodeArgs * args,
                                              UErrorCode * err)
 {
@@ -600,7 +607,7 @@
     int32_t offsetNum = 0;
 
     /* Restore state of current sequence */
-    if (args->converter->toUnicodeStatus && myTarget < targetLimit)
+    if (args->converter->toULength > 0 && myTarget < targetLimit)
     {
         i = args->converter->toULength;       /* restore # of bytes consumed */
         args->converter->toULength = 0;
@@ -683,7 +690,7 @@
     args->offsets = myOffsets;
 }
 
-static void
+static void U_CALLCONV
 T_UConverter_fromUnicode_UTF32_LE(UConverterFromUnicodeArgs * args,
                                   UErrorCode * err)
 {
@@ -702,7 +709,7 @@
 
     /* write the BOM if necessary */
     if(args->converter->fromUnicodeStatus==UCNV_NEED_TO_WRITE_BOM) {
-        static const char bom[]={ (char)0xff, (char)0xfe, 0, 0 };
+        static const char bom[]={ (char)0xffu, (char)0xfeu, 0, 0 };
         ucnv_fromUWriteBytes(args->converter,
                              bom, 4,
                              &args->target, args->targetLimit,
@@ -792,7 +799,7 @@
     args->source = mySource;
 }
 
-static void
+static void U_CALLCONV
 T_UConverter_fromUnicode_UTF32_LE_OFFSET_LOGIC(UConverterFromUnicodeArgs * args,
                                                UErrorCode * err)
 {
@@ -813,7 +820,7 @@
 
     /* write the BOM if necessary */
     if(args->converter->fromUnicodeStatus==UCNV_NEED_TO_WRITE_BOM) {
-        static const char bom[]={ (char)0xff, (char)0xfe, 0, 0 };
+        static const char bom[]={ (char)0xffu, (char)0xfeu, 0, 0 };
         ucnv_fromUWriteBytes(args->converter,
                              bom, 4,
                              &args->target, args->targetLimit,
@@ -908,7 +915,7 @@
     args->offsets = myOffsets;
 }
 
-static UChar32
+static UChar32 U_CALLCONV
 T_UConverter_getNextUChar_UTF32_LE(UConverterToUnicodeArgs* args,
                                    UErrorCode* err)
 {
@@ -952,7 +959,7 @@
     *err = U_ILLEGAL_CHAR_FOUND;
     return 0xffff;
 }
-
+U_CDECL_END
 static const UConverterImpl _UTF32LEImpl = {
     UCNV_UTF32_LittleEndian,
 
@@ -973,7 +980,10 @@
     NULL,
     NULL,
     NULL,
-    ucnv_getNonSurrogateUnicodeSet
+    ucnv_getNonSurrogateUnicodeSet,
+
+    NULL,
+    NULL
 };
 
 /* The 1232 CCSID refers to any version of Unicode with any endianess of UTF-32 */
@@ -1014,8 +1024,8 @@
  *
  * On output, emit U+FEFF as the first code point.
  */
-
-static void
+U_CDECL_BEGIN
+static void U_CALLCONV
 _UTF32Reset(UConverter *cnv, UConverterResetChoice choice) {
     if(choice<=UCNV_RESET_TO_UNICODE) {
         /* reset toUnicode: state=0 */
@@ -1027,16 +1037,18 @@
     }
 }
 
-static void
+static void U_CALLCONV
 _UTF32Open(UConverter *cnv,
            UConverterLoadArgs *pArgs,
            UErrorCode *pErrorCode) {
+    (void)pArgs;
+    (void)pErrorCode;
     _UTF32Reset(cnv, UCNV_RESET_BOTH);
 }
 
-static const char utf32BOM[8]={ 0, 0, (char)0xfe, (char)0xff,    (char)0xff, (char)0xfe, 0, 0 };
+static const char utf32BOM[8]={ 0, 0, (char)0xfeu, (char)0xffu, (char)0xffu, (char)0xfeu, 0, 0 };
 
-static void
+static void U_CALLCONV
 _UTF32ToUnicodeWithOffsets(UConverterToUnicodeArgs *pArgs,
                            UErrorCode *pErrorCode) {
     UConverter *cnv=pArgs->converter;
@@ -1062,7 +1074,7 @@
             b=*source;
             if(b==0) {
                 state=1; /* could be 00 00 FE FF */
-            } else if(b==(char)0xff) {
+            } else if(b==(char)0xffu) {
                 state=5; /* could be FF FE 00 00 */
             } else {
                 state=8; /* default to UTF-32BE */
@@ -1177,7 +1189,7 @@
     cnv->mode=state;
 }
 
-static UChar32
+static UChar32 U_CALLCONV
 _UTF32GetNextUChar(UConverterToUnicodeArgs *pArgs,
                    UErrorCode *pErrorCode) {
     switch(pArgs->converter->mode) {
@@ -1189,7 +1201,7 @@
         return UCNV_GET_NEXT_UCHAR_USE_TO_U;
     }
 }
-
+U_CDECL_END
 static const UConverterImpl _UTF32Impl = {
     UCNV_UTF32,
 
@@ -1215,7 +1227,10 @@
     NULL,
     NULL,
     NULL,
-    ucnv_getNonSurrogateUnicodeSet
+    ucnv_getNonSurrogateUnicodeSet,
+
+    NULL,
+    NULL
 };
 
 /* The 1236 CCSID refers to any version of Unicode with a BOM sensitive endianess of UTF-32 */
diff --git a/src/third_party/icu/source/common/ucnv_u7.c b/src/third_party/icu/source/common/ucnv_u7.cpp
similarity index 98%
rename from src/third_party/icu/source/common/ucnv_u7.c
rename to src/third_party/icu/source/common/ucnv_u7.cpp
index d35bae2..87ba8cf 100644
--- a/src/third_party/icu/source/common/ucnv_u7.c
+++ b/src/third_party/icu/source/common/ucnv_u7.cpp
@@ -1,10 +1,12 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*  
 **********************************************************************
-*   Copyright (C) 2002-2015, International Business Machines
+*   Copyright (C) 2002-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 **********************************************************************
 *   file name:  ucnv_u7.c
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -18,6 +20,7 @@
 
 #if !UCONFIG_NO_CONVERSION && !UCONFIG_ONLY_HTML_CONVERSION
 
+#include "cmemory.h"
 #include "unicode/ucnv.h"
 #include "ucnv_bld.h"
 #include "ucnv_cnv.h"
@@ -176,7 +179,8 @@
  *
  */
 
-static void
+U_CDECL_BEGIN
+static void U_CALLCONV
 _UTF7Reset(UConverter *cnv, UConverterResetChoice choice) {
     if(choice<=UCNV_RESET_TO_UNICODE) {
         /* reset toUnicode */
@@ -189,10 +193,11 @@
     }
 }
 
-static void
+static void U_CALLCONV
 _UTF7Open(UConverter *cnv,
           UConverterLoadArgs *pArgs,
           UErrorCode *pErrorCode) {
+    (void)pArgs;
     if(UCNV_GET_VERSION(cnv)<=1) {
         /* TODO(markus): Should just use cnv->options rather than copying the version number. */
         cnv->fromUnicodeStatus=UCNV_GET_VERSION(cnv)<<28;
@@ -202,7 +207,7 @@
     }
 }
 
-static void
+static void U_CALLCONV
 _UTF7ToUnicodeWithOffsets(UConverterToUnicodeArgs *pArgs,
                           UErrorCode *pErrorCode) {
     UConverter *cnv;
@@ -453,7 +458,7 @@
     return;
 }
 
-static void
+static void U_CALLCONV
 _UTF7FromUnicodeWithOffsets(UConverterFromUnicodeArgs *pArgs,
                             UErrorCode *pErrorCode) {
     UConverter *cnv;
@@ -487,7 +492,7 @@
         inDirectMode=(UBool)((status>>24)&1);
         base64Counter=(int8_t)(status>>16);
         bits=(uint8_t)status;
-        U_ASSERT(bits<=sizeof(toBase64)/sizeof(toBase64[0]));
+        U_ASSERT(bits<=UPRV_LENGTHOF(toBase64));
     }
 
     /* UTF-7 always encodes UTF-16 code units, therefore we need only a simple sourceIndex */
@@ -729,7 +734,7 @@
     return;
 }
 
-static const char *
+static const char * U_CALLCONV
 _UTF7GetName(const UConverter *cnv) {
     switch(cnv->fromUnicodeStatus>>28) {
     case 1:
@@ -738,6 +743,7 @@
         return "UTF-7";
     }
 }
+U_CDECL_END
 
 static const UConverterImpl _UTF7Impl={
     UCNV_UTF7,
@@ -759,7 +765,10 @@
     _UTF7GetName,
     NULL, /* we don't need writeSub() because we never call a callback at fromUnicode() */
     NULL,
-    ucnv_getCompleteUnicodeSet
+    ucnv_getCompleteUnicodeSet,
+
+    NULL,
+    NULL
 };
 
 static const UConverterStaticData _UTF7StaticData={
@@ -881,7 +890,8 @@
  * ignore bits 31..25
  */
 
-static void
+U_CDECL_BEGIN
+static void U_CALLCONV
 _IMAPToUnicodeWithOffsets(UConverterToUnicodeArgs *pArgs,
                           UErrorCode *pErrorCode) {
     UConverter *cnv;
@@ -1149,7 +1159,7 @@
     return;
 }
 
-static void
+static void U_CALLCONV
 _IMAPFromUnicodeWithOffsets(UConverterFromUnicodeArgs *pArgs,
                             UErrorCode *pErrorCode) {
     UConverter *cnv;
@@ -1435,6 +1445,7 @@
     pArgs->offsets=offsets;
     return;
 }
+U_CDECL_END
 
 static const UConverterImpl _IMAPImpl={
     UCNV_IMAP_MAILBOX,
@@ -1456,7 +1467,9 @@
     NULL,
     NULL, /* we don't need writeSub() because we never call a callback at fromUnicode() */
     NULL,
-    ucnv_getCompleteUnicodeSet
+    ucnv_getCompleteUnicodeSet,
+    NULL,
+    NULL
 };
 
 static const UConverterStaticData _IMAPStaticData={
diff --git a/src/third_party/icu/source/common/ucnv_u8.c b/src/third_party/icu/source/common/ucnv_u8.cpp
similarity index 70%
rename from src/third_party/icu/source/common/ucnv_u8.c
rename to src/third_party/icu/source/common/ucnv_u8.cpp
index b785873..1ef7fa2 100644
--- a/src/third_party/icu/source/common/ucnv_u8.c
+++ b/src/third_party/icu/source/common/ucnv_u8.cpp
@@ -1,10 +1,12 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*  
 **********************************************************************
-*   Copyright (C) 2002-2015, International Business Machines
+*   Copyright (C) 2002-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 **********************************************************************
 *   file name:  ucnv_u8.c
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -26,9 +28,11 @@
 #include "unicode/utf.h"
 #include "unicode/utf8.h"
 #include "unicode/utf16.h"
+#include "uassert.h"
 #include "ucnv_bld.h"
 #include "ucnv_cnv.h"
 #include "cmemory.h"
+#include "ustr_imp.h"
 
 /* Prototypes --------------------------------------------------------------- */
 
@@ -42,51 +46,13 @@
 
 /* UTF-8 -------------------------------------------------------------------- */
 
-/* UTF-8 Conversion DATA
- *   for more information see Unicode Standard 2.0, Transformation Formats Appendix A-9
- */
-/*static const uint32_t REPLACEMENT_CHARACTER = 0x0000FFFD;*/
 #define MAXIMUM_UCS2            0x0000FFFF
-#define MAXIMUM_UTF             0x0010FFFF
-#define MAXIMUM_UCS4            0x7FFFFFFF
-#define HALF_SHIFT              10
-#define HALF_BASE               0x0010000
-#define HALF_MASK               0x3FF
-#define SURROGATE_HIGH_START    0xD800
-#define SURROGATE_HIGH_END      0xDBFF
-#define SURROGATE_LOW_START     0xDC00
-#define SURROGATE_LOW_END       0xDFFF
 
-/* -SURROGATE_LOW_START + HALF_BASE */
-#define SURROGATE_LOW_BASE      9216
-
-static const uint32_t offsetsFromUTF8[7] = {0,
+static const uint32_t offsetsFromUTF8[5] = {0,
   (uint32_t) 0x00000000, (uint32_t) 0x00003080, (uint32_t) 0x000E2080,
-  (uint32_t) 0x03C82080, (uint32_t) 0xFA082080, (uint32_t) 0x82082080
+  (uint32_t) 0x03C82080
 };
 
-/* END OF UTF-8 Conversion DATA */
-
-static const int8_t bytesFromUTF8[256] = {
-  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 0, 0
-};
-
-/*
- * Starting with Unicode 3.0.1:
- * UTF-8 byte sequences of length N _must_ encode code points of or above utf8_minChar32[N];
- * byte sequences with more than 4 bytes are illegal in UTF-8,
- * which is tested with impossible values for them
- */
-static const uint32_t
-utf8_minChar32[7]={ 0, 0, 0x80, 0x800, 0x10000, 0xffffffff, 0xffffffff };
-
 static UBool hasCESU8Data(const UConverter *cnv)
 {
 #if UCONFIG_ONLY_HTML_CONVERSION
@@ -95,8 +61,8 @@
     return (UBool)(cnv->sharedData == &_CESU8Data);
 #endif
 }
-
-static void ucnv_toUnicode_UTF8 (UConverterToUnicodeArgs * args,
+U_CDECL_BEGIN
+static void  U_CALLCONV ucnv_toUnicode_UTF8 (UConverterToUnicodeArgs * args,
                                   UErrorCode * err)
 {
     UConverter *cnv = args->converter;
@@ -110,7 +76,7 @@
     int32_t i, inBytes;
 
     /* Restore size of current sequence */
-    if (cnv->toUnicodeStatus && myTarget < targetLimit)
+    if (cnv->toULength > 0 && myTarget < targetLimit)
     {
         inBytes = cnv->mode;            /* restore # of bytes to consume */
         i = cnv->toULength;             /* restore # of bytes consumed */
@@ -125,7 +91,7 @@
     while (mySource < sourceLimit && myTarget < targetLimit)
     {
         ch = *(mySource++);
-        if (ch < 0x80)        /* Simple case */
+        if (U8_IS_SINGLE(ch))        /* Simple case */
         {
             *(myTarget++) = (UChar) ch;
         }
@@ -133,7 +99,7 @@
         {
             /* store the first char */
             toUBytes[0] = (char)ch;
-            inBytes = bytesFromUTF8[ch]; /* lookup current sequence length */
+            inBytes = U8_COUNT_BYTES_NON_ASCII(ch); /* lookup current sequence length */
             i = 1;
 
 morebytes:
@@ -142,7 +108,8 @@
                 if (mySource < sourceLimit)
                 {
                     toUBytes[i] = (char) (ch2 = *mySource);
-                    if (!U8_IS_TRAIL(ch2))
+                    if (!icu::UTF8::isValidTrail(ch, static_cast<uint8_t>(ch2), i, inBytes) &&
+                            !(isCESU8 && i == 1 && ch == 0xed && U8_IS_TRAIL(ch2)))
                     {
                         break; /* i < inBytes */
                     }
@@ -160,24 +127,12 @@
                 }
             }
 
-            /* Remove the accumulated high bits */
-            ch -= offsetsFromUTF8[inBytes];
-
-            /*
-             * Legal UTF-8 byte sequences in Unicode 3.0.1 and up:
-             * - use only trail bytes after a lead byte (checked above)
-             * - use the right number of trail bytes for a given lead byte
-             * - encode a code point <= U+10ffff
-             * - use the fewest possible number of bytes for their code points
-             * - use at most 4 bytes (for i>=5 it is 0x10ffff<utf8_minChar32[])
-             *
-             * Starting with Unicode 3.2, surrogate code points must not be encoded in UTF-8.
-             * There are no irregular sequences any more.
-             * In CESU-8, only surrogates, not supplementary code points, are encoded directly.
-             */
-            if (i == inBytes && ch <= MAXIMUM_UTF && ch >= utf8_minChar32[i] &&
-                (isCESU8 ? i <= 3 : !U_IS_SURROGATE(ch)))
+            // In CESU-8, only surrogates, not supplementary code points, are encoded directly.
+            if (i == inBytes && (!isCESU8 || i <= 3))
             {
+                /* Remove the accumulated high bits */
+                ch -= offsetsFromUTF8[inBytes];
+
                 /* Normal valid byte when the loop has not prematurely terminated (i < inBytes) */
                 if (ch <= MAXIMUM_UCS2) 
                 {
@@ -187,9 +142,8 @@
                 else
                 {
                     /* write out the surrogates */
-                    ch -= HALF_BASE;
-                    *(myTarget++) = (UChar) ((ch >> HALF_SHIFT) + SURROGATE_HIGH_START);
-                    ch = (ch & HALF_MASK) + SURROGATE_LOW_START;
+                    *(myTarget++) = U16_LEAD(ch);
+                    ch = U16_TRAIL(ch);
                     if (myTarget < targetLimit)
                     {
                         *(myTarget++) = (UChar)ch;
@@ -224,7 +178,7 @@
     args->source = (const char *) mySource;
 }
 
-static void ucnv_toUnicode_UTF8_OFFSETS_LOGIC (UConverterToUnicodeArgs * args,
+static void  U_CALLCONV ucnv_toUnicode_UTF8_OFFSETS_LOGIC (UConverterToUnicodeArgs * args,
                                                 UErrorCode * err)
 {
     UConverter *cnv = args->converter;
@@ -240,7 +194,7 @@
     int32_t i, inBytes;
 
     /* Restore size of current sequence */
-    if (cnv->toUnicodeStatus && myTarget < targetLimit)
+    if (cnv->toULength > 0 && myTarget < targetLimit)
     {
         inBytes = cnv->mode;            /* restore # of bytes to consume */
         i = cnv->toULength;             /* restore # of bytes consumed */
@@ -254,7 +208,7 @@
     while (mySource < sourceLimit && myTarget < targetLimit)
     {
         ch = *(mySource++);
-        if (ch < 0x80)        /* Simple case */
+        if (U8_IS_SINGLE(ch))        /* Simple case */
         {
             *(myTarget++) = (UChar) ch;
             *(myOffsets++) = offsetNum++;
@@ -262,7 +216,7 @@
         else
         {
             toUBytes[0] = (char)ch;
-            inBytes = bytesFromUTF8[ch];
+            inBytes = U8_COUNT_BYTES_NON_ASCII(ch);
             i = 1;
 
 morebytes:
@@ -271,7 +225,8 @@
                 if (mySource < sourceLimit)
                 {
                     toUBytes[i] = (char) (ch2 = *mySource);
-                    if (!U8_IS_TRAIL(ch2))
+                    if (!icu::UTF8::isValidTrail(ch, static_cast<uint8_t>(ch2), i, inBytes) &&
+                            !(isCESU8 && i == 1 && ch == 0xed && U8_IS_TRAIL(ch2)))
                     {
                         break; /* i < inBytes */
                     }
@@ -288,24 +243,12 @@
                 }
             }
 
-            /* Remove the accumulated high bits */
-            ch -= offsetsFromUTF8[inBytes];
-
-            /*
-             * Legal UTF-8 byte sequences in Unicode 3.0.1 and up:
-             * - use only trail bytes after a lead byte (checked above)
-             * - use the right number of trail bytes for a given lead byte
-             * - encode a code point <= U+10ffff
-             * - use the fewest possible number of bytes for their code points
-             * - use at most 4 bytes (for i>=5 it is 0x10ffff<utf8_minChar32[])
-             *
-             * Starting with Unicode 3.2, surrogate code points must not be encoded in UTF-8.
-             * There are no irregular sequences any more.
-             * In CESU-8, only surrogates, not supplementary code points, are encoded directly.
-             */
-            if (i == inBytes && ch <= MAXIMUM_UTF && ch >= utf8_minChar32[i] &&
-                (isCESU8 ? i <= 3 : !U_IS_SURROGATE(ch)))
+            // In CESU-8, only surrogates, not supplementary code points, are encoded directly.
+            if (i == inBytes && (!isCESU8 || i <= 3))
             {
+                /* Remove the accumulated high bits */
+                ch -= offsetsFromUTF8[inBytes];
+
                 /* Normal valid byte when the loop has not prematurely terminated (i < inBytes) */
                 if (ch <= MAXIMUM_UCS2) 
                 {
@@ -316,10 +259,9 @@
                 else
                 {
                     /* write out the surrogates */
-                    ch -= HALF_BASE;
-                    *(myTarget++) = (UChar) ((ch >> HALF_SHIFT) + SURROGATE_HIGH_START);
+                    *(myTarget++) = U16_LEAD(ch);
                     *(myOffsets++) = offsetNum;
-                    ch = (ch & HALF_MASK) + SURROGATE_LOW_START;
+                    ch = U16_TRAIL(ch);
                     if (myTarget < targetLimit)
                     {
                         *(myTarget++) = (UChar)ch;
@@ -353,8 +295,9 @@
     args->source = (const char *) mySource;
     args->offsets = myOffsets;
 }
+U_CDECL_END
 
-U_CFUNC void ucnv_fromUnicode_UTF8 (UConverterFromUnicodeArgs * args,
+U_CFUNC void  U_CALLCONV ucnv_fromUnicode_UTF8 (UConverterFromUnicodeArgs * args,
                                     UErrorCode * err)
 {
     UConverter *cnv = args->converter;
@@ -468,7 +411,7 @@
     args->source = mySource;
 }
 
-U_CFUNC void ucnv_fromUnicode_UTF8_OFFSETS_LOGIC (UConverterFromUnicodeArgs * args,
+U_CFUNC void  U_CALLCONV ucnv_fromUnicode_UTF8_OFFSETS_LOGIC (UConverterFromUnicodeArgs * args,
                                                   UErrorCode * err)
 {
     UConverter *cnv = args->converter;
@@ -607,15 +550,15 @@
     args->offsets = myOffsets;
 }
 
-static UChar32 ucnv_getNextUChar_UTF8(UConverterToUnicodeArgs *args,
+U_CDECL_BEGIN
+static UChar32 U_CALLCONV ucnv_getNextUChar_UTF8(UConverterToUnicodeArgs *args,
                                                UErrorCode *err) {
     UConverter *cnv;
     const uint8_t *sourceInitial;
     const uint8_t *source;
-    uint16_t extraBytesToWrite;
     uint8_t myByte;
     UChar32 ch;
-    int8_t i, isLegalSequence;
+    int8_t i;
 
     /* UTF-8 only here, the framework handles CESU-8 to combine surrogate pairs */
 
@@ -629,14 +572,14 @@
     }
 
     myByte = (uint8_t)*(source++);
-    if (myByte < 0x80)
+    if (U8_IS_SINGLE(myByte))
     {
         args->source = (const char *)source;
         return (UChar32)myByte;
     }
 
-    extraBytesToWrite = (uint16_t)bytesFromUTF8[myByte];
-    if (extraBytesToWrite == 0) {
+    uint16_t countTrailBytes = U8_COUNT_TRAIL_BYTES(myByte);
+    if (countTrailBytes == 0) {
         cnv->toUBytes[0] = myByte;
         cnv->toULength = 1;
         *err = U_ILLEGAL_CHAR_FOUND;
@@ -645,15 +588,17 @@
     }
 
     /*The byte sequence is longer than the buffer area passed*/
-    if (((const char *)source + extraBytesToWrite - 1) > args->sourceLimit)
+    if (((const char *)source + countTrailBytes) > args->sourceLimit)
     {
         /* check if all of the remaining bytes are trail bytes */
+        uint16_t extraBytesToWrite = countTrailBytes + 1;
         cnv->toUBytes[0] = myByte;
         i = 1;
         *err = U_TRUNCATED_CHAR_FOUND;
         while(source < (const uint8_t *)args->sourceLimit) {
-            if(U8_IS_TRAIL(myByte = *source)) {
-                cnv->toUBytes[i++] = myByte;
+            uint8_t b = *source;
+            if(icu::UTF8::isValidTrail(myByte, b, i, extraBytesToWrite)) {
+                cnv->toUBytes[i++] = b;
                 ++source;
             } else {
                 /* error even before we run out of input */
@@ -666,77 +611,28 @@
         return 0xffff;
     }
 
-    isLegalSequence = 1;
     ch = myByte << 6;
-    switch(extraBytesToWrite)
-    {     
-      /* note: code falls through cases! (sic)*/ 
-    case 6:
-        ch += (myByte = *source);
-        ch <<= 6;
-        if (!U8_IS_TRAIL(myByte))
-        {
-            isLegalSequence = 0;
-            break;
+    if(countTrailBytes == 2) {
+        uint8_t t1 = *source, t2;
+        if(U8_IS_VALID_LEAD3_AND_T1(myByte, t1) && U8_IS_TRAIL(t2 = *++source)) {
+            args->source = (const char *)(source + 1);
+            return (((ch + t1) << 6) + t2) - offsetsFromUTF8[3];
         }
-        ++source;
-    case 5: /*fall through*/
-        ch += (myByte = *source);
-        ch <<= 6;
-        if (!U8_IS_TRAIL(myByte))
-        {
-            isLegalSequence = 0;
-            break;
+    } else if(countTrailBytes == 1) {
+        uint8_t t1 = *source;
+        if(U8_IS_TRAIL(t1)) {
+            args->source = (const char *)(source + 1);
+            return (ch + t1) - offsetsFromUTF8[2];
         }
-        ++source;
-    case 4: /*fall through*/
-        ch += (myByte = *source);
-        ch <<= 6;
-        if (!U8_IS_TRAIL(myByte))
-        {
-            isLegalSequence = 0;
-            break;
+    } else {  // countTrailBytes == 3
+        uint8_t t1 = *source, t2, t3;
+        if(U8_IS_VALID_LEAD4_AND_T1(myByte, t1) && U8_IS_TRAIL(t2 = *++source) &&
+                U8_IS_TRAIL(t3 = *++source)) {
+            args->source = (const char *)(source + 1);
+            return (((((ch + t1) << 6) + t2) << 6) + t3) - offsetsFromUTF8[4];
         }
-        ++source;
-    case 3: /*fall through*/
-        ch += (myByte = *source);
-        ch <<= 6;
-        if (!U8_IS_TRAIL(myByte))
-        {
-            isLegalSequence = 0;
-            break;
-        }
-        ++source;
-    case 2: /*fall through*/
-        ch += (myByte = *source);
-        if (!U8_IS_TRAIL(myByte))
-        {
-            isLegalSequence = 0;
-            break;
-        }
-        ++source;
-    };
-    ch -= offsetsFromUTF8[extraBytesToWrite];
-    args->source = (const char *)source;
-
-    /*
-     * Legal UTF-8 byte sequences in Unicode 3.0.1 and up:
-     * - use only trail bytes after a lead byte (checked above)
-     * - use the right number of trail bytes for a given lead byte
-     * - encode a code point <= U+10ffff
-     * - use the fewest possible number of bytes for their code points
-     * - use at most 4 bytes (for i>=5 it is 0x10ffff<utf8_minChar32[])
-     *
-     * Starting with Unicode 3.2, surrogate code points must not be encoded in UTF-8.
-     * There are no irregular sequences any more.
-     */
-    if (isLegalSequence &&
-        (uint32_t)ch <= MAXIMUM_UTF &&
-        (uint32_t)ch >= utf8_minChar32[extraBytesToWrite] &&
-        !U_IS_SURROGATE(ch)
-    ) {
-        return ch; /* return the code point */
     }
+    args->source = (const char *)source;
 
     for(i = 0; sourceInitial < source; ++i) {
         cnv->toUBytes[i] = *sourceInitial++;
@@ -745,19 +641,13 @@
     *err = U_ILLEGAL_CHAR_FOUND;
     return 0xffff;
 } 
+U_CDECL_END
 
 /* UTF-8-from-UTF-8 conversion functions ------------------------------------ */
 
-/* minimum code point values for n-byte UTF-8 sequences, n=0..4 */
-static const UChar32
-utf8_minLegal[5]={ 0, 0, 0x80, 0x800, 0x10000 };
-
-/* offsets for n-byte UTF-8 sequences that were calculated with ((lead<<6)+trail)<<6+trail... */
-static const UChar32
-utf8_offsets[7]={ 0, 0, 0x3080, 0xE2080, 0x3C82080 };
-
+U_CDECL_BEGIN
 /* "Convert" UTF-8 to UTF-8: Validate and copy. Modified from ucnv_DBCSFromUTF8(). */
-static void
+static void U_CALLCONV
 ucnv_UTF8FromUTF8(UConverterFromUnicodeArgs *pFromUArgs,
                   UConverterToUnicodeArgs *pToUArgs,
                   UErrorCode *pErrorCode) {
@@ -780,12 +670,13 @@
     targetCapacity=(int32_t)(pFromUArgs->targetLimit-pFromUArgs->target);
 
     /* get the converter state from the UTF-8 UConverter */
-    c=(UChar32)utf8->toUnicodeStatus;
-    if(c!=0) {
+    if(utf8->toULength > 0) {
         toULength=oldToULength=utf8->toULength;
         toULimit=(int8_t)utf8->mode;
+        c=(UChar32)utf8->toUnicodeStatus;
     } else {
         toULength=oldToULength=toULimit=0;
+        c = 0;
     }
 
     count=(int32_t)(sourceLimit-source)+oldToULength;
@@ -802,41 +693,23 @@
         *pErrorCode=U_USING_DEFAULT_WARNING;
         return;
     } else {
-        /*
-         * Use a single counter for source and target, counting the minimum of
-         * the source length and the target capacity.
-         * As a result, the source length is checked only once per multi-byte
-         * character instead of twice.
-         *
-         * Make sure that the last byte sequence is complete, or else
-         * stop just before it.
-         * (The longest legal byte sequence has 3 trail bytes.)
-         * Count oldToULength (number of source bytes from a previous buffer)
-         * into the source length but reduce the source index by toULimit
-         * while going back over trail bytes in order to not go back into
-         * the bytes that will be read for finishing a partial
-         * sequence from the previous buffer.
-         * Let the standard converter handle edge cases.
-         */
-        int32_t i;
-
+        // Use a single counter for source and target, counting the minimum of
+        // the source length and the target capacity.
+        // Let the standard converter handle edge cases.
         if(count>targetCapacity) {
             count=targetCapacity;
         }
 
-        i=0;
-        while(i<3 && i<(count-toULimit)) {
-            b=source[count-oldToULength-i-1];
-            if(U8_IS_TRAIL(b)) {
-                ++i;
-            } else {
-                if(i<U8_COUNT_TRAIL_BYTES(b)) {
-                    /* stop converting before the lead byte if there are not enough trail bytes for it */
-                    count-=i+1;
-                }
-                break;
-            }
-        }
+        // The conversion loop checks count>0 only once per character.
+        // If the buffer ends with a truncated sequence,
+        // then we reduce the count to stop before that,
+        // and collect the remaining bytes after the conversion loop.
+
+        // Do not go back into the bytes that will be read for finishing a partial
+        // sequence from the previous buffer.
+        int32_t length=count-toULength;
+        U8_TRUNCATE_IF_INCOMPLETE(source, 0, length);
+        count=toULength+length;
     }
 
     if(c!=0) {
@@ -849,17 +722,17 @@
     /* conversion loop */
     while(count>0) {
         b=*source++;
-        if((int8_t)b>=0) {
+        if(U8_IS_SINGLE(b)) {
             /* convert ASCII */
             *target++=b;
             --count;
             continue;
         } else {
-            if(b>0xe0) {
-                if( /* handle U+1000..U+D7FF inline */
-                    (t1=source[0]) >= 0x80 && ((b<0xed && (t1 <= 0xbf)) ||
-                                               (b==0xed && (t1 <= 0x9f))) &&
-                    (t2=source[1]) >= 0x80 && t2 <= 0xbf
+            if(b>=0xe0) {
+                if( /* handle U+0800..U+FFFF inline */
+                    b<0xf0 &&
+                    U8_IS_VALID_LEAD3_AND_T1(b, t1=source[0]) &&
+                    U8_IS_TRAIL(t2=source[1])
                 ) {
                     source+=2;
                     *target++=b;
@@ -868,10 +741,10 @@
                     count-=3;
                     continue;
                 }
-            } else if(b<0xe0) {
+            } else {
                 if( /* handle U+0080..U+07FF inline */
                     b>=0xc2 &&
-                    (t1=*source) >= 0x80 && t1 <= 0xbf
+                    U8_IS_TRAIL(t1=*source)
                 ) {
                     ++source;
                     *target++=b;
@@ -879,30 +752,18 @@
                     count-=2;
                     continue;
                 }
-            } else if(b==0xe0) {
-                if( /* handle U+0800..U+0FFF inline */
-                    (t1=source[0]) >= 0xa0 && t1 <= 0xbf &&
-                    (t2=source[1]) >= 0x80 && t2 <= 0xbf
-                ) {
-                    source+=2;
-                    *target++=b;
-                    *target++=t1;
-                    *target++=t2;
-                    count-=3;
-                    continue;
-                }
             }
 
             /* handle "complicated" and error cases, and continuing partial characters */
             oldToULength=0;
             toULength=1;
-            toULimit=U8_COUNT_TRAIL_BYTES(b)+1;
+            toULimit=U8_COUNT_BYTES_NON_ASCII(b);
             c=b;
 moreBytes:
             while(toULength<toULimit) {
                 if(source<sourceLimit) {
                     b=*source;
-                    if(U8_IS_TRAIL(b)) {
+                    if(icu::UTF8::isValidTrail(c, b, toULength, toULimit)) {
                         ++source;
                         ++toULength;
                         c=(c<<6)+b;
@@ -924,18 +785,7 @@
                 }
             }
 
-            if( toULength==toULimit &&      /* consumed all trail bytes */
-                (toULength==3 || toULength==2) &&             /* BMP */
-                (c-=utf8_offsets[toULength])>=utf8_minLegal[toULength] &&
-                (c<=0xd7ff || 0xe000<=c)    /* not a surrogate */
-            ) {
-                /* legal byte sequence for BMP code point */
-            } else if(
-                toULength==toULimit && toULength==4 &&
-                (0x10000<=(c-=utf8_offsets[4]) && c<=0x10ffff)
-            ) {
-                /* legal byte sequence for supplementary code point */
-            } else {
+            if(toULength!=toULimit) {
                 /* error handling: illegal UTF-8 byte sequence */
                 source-=(toULength-oldToULength);
                 while(oldToULength<toULength) {
@@ -963,13 +813,14 @@
             }
         }
     }
+    U_ASSERT(count>=0);
 
     if(U_SUCCESS(*pErrorCode) && source<sourceLimit) {
         if(target==(const uint8_t *)pFromUArgs->targetLimit) {
             *pErrorCode=U_BUFFER_OVERFLOW_ERROR;
         } else {
             b=*source;
-            toULimit=U8_COUNT_TRAIL_BYTES(b)+1;
+            toULimit=U8_COUNT_BYTES(b);
             if(toULimit>(sourceLimit-source)) {
                 /* collect a truncated byte sequence */
                 toULength=0;
@@ -982,8 +833,7 @@
                         utf8->toULength=toULength;
                         utf8->mode=toULimit;
                         break;
-                    } else if(!U8_IS_TRAIL(b=*source)) {
-                        /* lead byte in trail byte position */
+                    } else if(!icu::UTF8::isValidTrail(c, b=*source, toULength, toULimit)) {
                         utf8->toULength=toULength;
                         *pErrorCode=U_ILLEGAL_CHAR_FOUND;
                         break;
@@ -1002,6 +852,8 @@
     pFromUArgs->target=(char *)target;
 }
 
+U_CDECL_END
+
 /* UTF-8 converter data ----------------------------------------------------- */
 
 static const UConverterImpl _UTF8Impl={
@@ -1068,7 +920,10 @@
     NULL,
     NULL,
     NULL,
-    ucnv_getCompleteUnicodeSet
+    ucnv_getCompleteUnicodeSet,
+
+    NULL,
+    NULL
 };
 
 static const UConverterStaticData _CESU8StaticData={
diff --git a/src/third_party/icu/source/common/ucnvbocu.cpp b/src/third_party/icu/source/common/ucnvbocu.cpp
index 6b0552e..7c2aab5 100644
--- a/src/third_party/icu/source/common/ucnvbocu.cpp
+++ b/src/third_party/icu/source/common/ucnvbocu.cpp
@@ -1,12 +1,14 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
-*   Copyright (C) 2002-2015, International Business Machines
+*   Copyright (C) 2002-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *
 ******************************************************************************
 *   file name:  ucnvbocu.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -200,14 +202,14 @@
  * @param d Divisor.
  * @param m Output variable for the rest (modulo result).
  */
-#define NEGDIVMOD(n, d, m) { \
+#define NEGDIVMOD(n, d, m) UPRV_BLOCK_MACRO_BEGIN { \
     (m)=(n)%(d); \
     (n)/=(d); \
     if((m)<0) { \
         --(n); \
         (m)+=(d); \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /* Faster versions of packDiff() for single-byte-encoded diff values. */
 
@@ -386,7 +388,7 @@
 }
 
 
-static void
+static void U_CALLCONV
 _Bocu1FromUnicodeWithOffsets(UConverterFromUnicodeArgs *pArgs,
                              UErrorCode *pErrorCode) {
     UConverter *cnv;
@@ -549,15 +551,18 @@
                     case 4:
                         *target++=(uint8_t)(diff>>24);
                         *offsets++=sourceIndex;
-                    case 3: /*fall through*/
+                        U_FALLTHROUGH;
+                    case 3:
                         *target++=(uint8_t)(diff>>16);
                         *offsets++=sourceIndex;
-                    case 2: /*fall through*/
+                        U_FALLTHROUGH;
+                    case 2:
                         *target++=(uint8_t)(diff>>8);
                         *offsets++=sourceIndex;
                     /* case 1: handled above */
                         *target++=(uint8_t)diff;
                         *offsets++=sourceIndex;
+                        U_FALLTHROUGH;
                     default:
                         /* will never occur */
                         break;
@@ -580,10 +585,13 @@
                         /* each branch falls through to the next one */
                     case 3:
                         *charErrorBuffer++=(uint8_t)(diff>>16);
-                    case 2: /*fall through*/
+                        U_FALLTHROUGH;
+                    case 2:
                         *charErrorBuffer++=(uint8_t)(diff>>8);
-                    case 1: /*fall through*/
+                        U_FALLTHROUGH;
+                    case 1:
                         *charErrorBuffer=(uint8_t)diff;
+                        U_FALLTHROUGH;
                     default:
                         /* will never occur */
                         break;
@@ -597,12 +605,15 @@
                     case 3:
                         *target++=(uint8_t)(diff>>16);
                         *offsets++=sourceIndex;
-                    case 2: /*fall through*/
+                        U_FALLTHROUGH;
+                    case 2:
                         *target++=(uint8_t)(diff>>8);
                         *offsets++=sourceIndex;
-                    case 1: /*fall through*/
+                        U_FALLTHROUGH;
+                    case 1:
                         *target++=(uint8_t)diff;
                         *offsets++=sourceIndex;
+                        U_FALLTHROUGH;
                     default:
                         /* will never occur */
                         break;
@@ -638,7 +649,7 @@
  * re-copy the original function and remove the variables
  * offsets, sourceIndex, and nextSourceIndex.
  */
-static void
+static void U_CALLCONV
 _Bocu1FromUnicode(UConverterFromUnicodeArgs *pArgs,
                   UErrorCode *pErrorCode) {
     UConverter *cnv;
@@ -777,12 +788,14 @@
                         /* each branch falls through to the next one */
                     case 4:
                         *target++=(uint8_t)(diff>>24);
-                    case 3: /*fall through*/
+                        U_FALLTHROUGH;
+                    case 3:
                         *target++=(uint8_t)(diff>>16);
                     /* case 2: handled above */
                         *target++=(uint8_t)(diff>>8);
                     /* case 1: handled above */
                         *target++=(uint8_t)diff;
+                        U_FALLTHROUGH;
                     default:
                         /* will never occur */
                         break;
@@ -804,10 +817,13 @@
                         /* each branch falls through to the next one */
                     case 3:
                         *charErrorBuffer++=(uint8_t)(diff>>16);
-                    case 2: /*fall through*/
+                        U_FALLTHROUGH;
+                    case 2:
                         *charErrorBuffer++=(uint8_t)(diff>>8);
-                    case 1: /*fall through*/
+                        U_FALLTHROUGH;
+                    case 1:
                         *charErrorBuffer=(uint8_t)diff;
+                        U_FALLTHROUGH;
                     default:
                         /* will never occur */
                         break;
@@ -820,10 +836,13 @@
                         /* each branch falls through to the next one */
                     case 3:
                         *target++=(uint8_t)(diff>>16);
-                    case 2: /*fall through*/
+                        U_FALLTHROUGH;
+                    case 2:
                         *target++=(uint8_t)(diff>>8);
-                    case 1: /*fall through*/
+                        U_FALLTHROUGH;
+                    case 1:
                         *target++=(uint8_t)diff;
+                        U_FALLTHROUGH;
                     default:
                         /* will never occur */
                         break;
@@ -933,7 +952,7 @@
     }
 }
 
-static void
+static void U_CALLCONV
 _Bocu1ToUnicodeWithOffsets(UConverterToUnicodeArgs *pArgs,
                            UErrorCode *pErrorCode) {
     UConverter *cnv;
@@ -1156,7 +1175,7 @@
  * re-copy the original function and remove the variables
  * offsets, sourceIndex, and nextSourceIndex.
  */
-static void
+static void U_CALLCONV
 _Bocu1ToUnicode(UConverterToUnicodeArgs *pArgs,
                 UErrorCode *pErrorCode) {
     UConverter *cnv;
diff --git a/src/third_party/icu/source/common/ucnvdisp.c b/src/third_party/icu/source/common/ucnvdisp.cpp
similarity index 95%
rename from src/third_party/icu/source/common/ucnvdisp.c
rename to src/third_party/icu/source/common/ucnvdisp.cpp
index 4075be6..ac86b98 100644
--- a/src/third_party/icu/source/common/ucnvdisp.c
+++ b/src/third_party/icu/source/common/ucnvdisp.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
diff --git a/src/third_party/icu/source/common/ucnvhz.c b/src/third_party/icu/source/common/ucnvhz.cpp
similarity index 95%
rename from src/third_party/icu/source/common/ucnvhz.c
rename to src/third_party/icu/source/common/ucnvhz.cpp
index 4ca2e78..6b2f5fa 100644
--- a/src/third_party/icu/source/common/ucnvhz.c
+++ b/src/third_party/icu/source/common/ucnvhz.cpp
@@ -1,10 +1,12 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*  
 **********************************************************************
 *   Copyright (C) 2000-2015, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 **********************************************************************
 *   file name:  ucnvhz.c
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -36,7 +38,7 @@
 #define ESC_LEN       2
 
 
-#define CONCAT_ESCAPE_MACRO( args, targetIndex,targetLength,strToAppend, err, len,sourceIndex){                             \
+#define CONCAT_ESCAPE_MACRO(args, targetIndex,targetLength,strToAppend, err, len,sourceIndex) UPRV_BLOCK_MACRO_BEGIN {      \
     while(len-->0){                                                                                                         \
         if(targetIndex < targetLength){                                                                                     \
             args->target[targetIndex] = (unsigned char) *strToAppend;                                                       \
@@ -51,7 +53,7 @@
         }                                                                                                                   \
         strToAppend++;                                                                                                      \
     }                                                                                                                       \
-}
+} UPRV_BLOCK_MACRO_END
 
 
 typedef struct{
@@ -65,8 +67,8 @@
 }UConverterDataHZ;
 
 
-
-static void 
+U_CDECL_BEGIN
+static void  U_CALLCONV
 _HZOpen(UConverter *cnv, UConverterLoadArgs *pArgs, UErrorCode *errorCode){
     UConverter *gbConverter;
     if(pArgs->onlyTestIsLoadable) {
@@ -92,7 +94,7 @@
     }
 }
 
-static void 
+static void  U_CALLCONV
 _HZClose(UConverter *cnv){
     if(cnv->extraInfo != NULL) {
         ucnv_close (((UConverterDataHZ *) (cnv->extraInfo))->gbConverter);
@@ -103,7 +105,7 @@
     }
 }
 
-static void 
+static void  U_CALLCONV
 _HZReset(UConverter *cnv, UConverterResetChoice choice){
     if(choice<=UCNV_RESET_TO_UNICODE) {
         cnv->toUnicodeStatus = 0;
@@ -150,7 +152,7 @@
 */
 
 
-static void 
+static void  U_CALLCONV
 UConverter_toUnicode_HZ_OFFSETS_LOGIC(UConverterToUnicodeArgs *args,
                                                             UErrorCode* err){
     char tempBuf[2];
@@ -197,7 +199,7 @@
                         *err = U_ILLEGAL_ESCAPE_SEQUENCE;
                         args->converter->toUCallbackReason = UCNV_IRREGULAR;
                         args->converter->toUBytes[0] = UCNV_TILDE;
-                        args->converter->toUBytes[1] = mySourceChar;
+                        args->converter->toUBytes[1] = static_cast<uint8_t>(mySourceChar);
                         args->converter->toULength = 2;
                         args->target = myTarget;
                         args->source = mySource;
@@ -227,7 +229,7 @@
                         --mySource;
                     } else {
                         /* Include the current byte in the illegal sequence. */
-                        args->converter->toUBytes[1] = mySourceChar;
+                        args->converter->toUBytes[1] = static_cast<uint8_t>(mySourceChar);
                         args->converter->toULength = 2;
                     }
                     args->target = myTarget;
@@ -330,7 +332,7 @@
 }
 
 
-static void 
+static void  U_CALLCONV
 UConverter_fromUnicode_HZ_OFFSETS_LOGIC (UConverterFromUnicodeArgs * args,
                                                       UErrorCode * err){
     const UChar *mySource = args->source;
@@ -494,7 +496,7 @@
     myConverterData->isTargetUCharDBCS = isTargetUCharDBCS;
 }
 
-static void
+static void U_CALLCONV
 _HZ_WriteSub(UConverterFromUnicodeArgs *args, int32_t offsetIndex, UErrorCode *err) {
     UConverter *cnv = args->converter;
     UConverterDataHZ *convData=(UConverterDataHZ *) cnv->extraInfo;
@@ -516,24 +518,16 @@
 
 /*
  * Structure for cloning an HZ converter into a single memory block.
- * ucnv_safeClone() of the HZ converter will align the entire cloneHZStruct,
- * and then ucnv_safeClone() of the sub-converter may additionally align
- * subCnv inside the cloneHZStruct, for which we need the deadSpace after
- * subCnv. This is because UAlignedMemory may be larger than the actually
- * necessary alignment size for the platform.
- * The other cloneHZStruct fields will not be moved around,
- * and are aligned properly with cloneHZStruct's alignment.
  */
 struct cloneHZStruct
 {
     UConverter cnv;
     UConverter subCnv;
-    UAlignedMemory deadSpace;
     UConverterDataHZ mydata;
 };
 
 
-static UConverter * 
+static UConverter *  U_CALLCONV
 _HZ_SafeClone(const UConverter *cnv, 
               void *stackBuffer, 
               int32_t *pBufferSize, 
@@ -543,12 +537,12 @@
     int32_t size, bufferSizeNeeded = sizeof(struct cloneHZStruct);
 
     if (U_FAILURE(*status)){
-        return 0;
+        return nullptr;
     }
 
     if (*pBufferSize == 0){ /* 'preflighting' request - set needed size into *pBufferSize */
         *pBufferSize = bufferSizeNeeded;
-        return 0;
+        return nullptr;
     }
 
     localClone = (struct cloneHZStruct *)stackBuffer;
@@ -559,14 +553,14 @@
     localClone->cnv.isExtraLocal = TRUE;
 
     /* deep-clone the sub-converter */
-    size = (int32_t)(sizeof(UConverter) + sizeof(UAlignedMemory)); /* include size of padding */
+    size = (int32_t)sizeof(UConverter);
     ((UConverterDataHZ*)localClone->cnv.extraInfo)->gbConverter =
         ucnv_safeClone(((UConverterDataHZ*)cnv->extraInfo)->gbConverter, &localClone->subCnv, &size, status);
 
     return &localClone->cnv;
 }
 
-static void
+static void U_CALLCONV
 _HZ_GetUnicodeSet(const UConverter *cnv,
                   const USetAdder *sa,
                   UConverterUnicodeSet which,
@@ -580,7 +574,7 @@
         sa, which, UCNV_SET_FILTER_HZ,
         pErrorCode);
 }
-
+U_CDECL_END
 static const UConverterImpl _HZImpl={
 
     UCNV_HZ,
@@ -602,7 +596,9 @@
     NULL,
     _HZ_WriteSub,
     _HZ_SafeClone,
-    _HZ_GetUnicodeSet
+    _HZ_GetUnicodeSet,
+    NULL,
+    NULL
 };
 
 static const UConverterStaticData _HZStaticData={
diff --git a/src/third_party/icu/source/common/ucnvisci.c b/src/third_party/icu/source/common/ucnvisci.cpp
similarity index 97%
rename from src/third_party/icu/source/common/ucnvisci.c
rename to src/third_party/icu/source/common/ucnvisci.cpp
index d34d088..44a7c05 100644
--- a/src/third_party/icu/source/common/ucnvisci.c
+++ b/src/third_party/icu/source/common/ucnvisci.cpp
@@ -1,10 +1,12 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
-*   Copyright (C) 2000-2015, International Business Machines
+*   Copyright (C) 2000-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 **********************************************************************
 *   file name:  ucnvisci.c
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -184,8 +186,9 @@
         return (UBool)(pnjMap[c - 0xa00] >> 1);
     }
 }
-
-static void _ISCIIOpen(UConverter *cnv, UConverterLoadArgs *pArgs, UErrorCode *errorCode) {
+U_CDECL_BEGIN
+static void  U_CALLCONV
+_ISCIIOpen(UConverter *cnv, UConverterLoadArgs *pArgs, UErrorCode *errorCode) {
     if(pArgs->onlyTestIsLoadable) {
         return;
     }
@@ -229,7 +232,8 @@
     }
 }
 
-static void _ISCIIClose(UConverter *cnv) {
+static void U_CALLCONV
+_ISCIIClose(UConverter *cnv) {
     if (cnv->extraInfo!=NULL) {
         if (!cnv->isExtraLocal) {
             uprv_free(cnv->extraInfo);
@@ -238,7 +242,8 @@
     }
 }
 
-static const char* _ISCIIgetName(const UConverter* cnv) {
+static const char*  U_CALLCONV
+_ISCIIgetName(const UConverter* cnv) {
     if (cnv->extraInfo) {
         UConverterDataISCII* myData= (UConverterDataISCII*)cnv->extraInfo;
         return myData->name;
@@ -246,7 +251,8 @@
     return NULL;
 }
 
-static void _ISCIIReset(UConverter *cnv, UConverterResetChoice choice) {
+static void U_CALLCONV
+_ISCIIReset(UConverter *cnv, UConverterResetChoice choice) {
     UConverterDataISCII* data =(UConverterDataISCII *) (cnv->extraInfo);
     if (choice<=UCNV_RESET_TO_UNICODE) {
         cnv->toUnicodeStatus = missingCharMarker;
@@ -825,7 +831,7 @@
 };
 
 
-#define WRITE_TO_TARGET_FROM_U(args,offsets,source,target,targetLimit,targetByteUnit,err){      \
+#define WRITE_TO_TARGET_FROM_U(args,offsets,source,target,targetLimit,targetByteUnit,err) UPRV_BLOCK_MACRO_BEGIN { \
     int32_t offset = (int32_t)(source - args->source-1);                                        \
       /* write the targetUniChar  to target */                                                  \
     if(target < targetLimit){                                                                   \
@@ -878,7 +884,7 @@
                         (uint8_t) (targetByteUnit);                                             \
         *err = U_BUFFER_OVERFLOW_ERROR;                                                         \
     }                                                                                           \
-}
+} UPRV_BLOCK_MACRO_END
 
 /* Rules:
  *    Explicit Halant :
@@ -886,8 +892,8 @@
  *    Soft Halant :
  *                      <HALANT> + <ZWJ>
  */
-
-static void UConverter_fromUnicode_ISCII_OFFSETS_LOGIC(
+static void U_CALLCONV
+UConverter_fromUnicode_ISCII_OFFSETS_LOGIC(
         UConverterFromUnicodeArgs * args, UErrorCode * err) {
     const UChar *source = args->source;
     const UChar *sourceLimit = args->sourceLimit;
@@ -1113,7 +1119,7 @@
     { GURMUKHI,   PNJ_MASK }
 };
 
-#define WRITE_TO_TARGET_TO_U(args,source,target,offsets,offset,targetUniChar,delta, err){\
+#define WRITE_TO_TARGET_TO_U(args,source,target,offsets,offset,targetUniChar,delta, err) UPRV_BLOCK_MACRO_BEGIN { \
     /* add offset to current Indic Block */                                              \
     if(targetUniChar>ASCII_END &&                                                        \
            targetUniChar != ZWJ &&                                                       \
@@ -1134,9 +1140,9 @@
             (UChar)targetUniChar;                                                        \
         *err = U_BUFFER_OVERFLOW_ERROR;                                                  \
     }                                                                                    \
-}
+} UPRV_BLOCK_MACRO_END
 
-#define GET_MAPPING(sourceChar,targetUniChar,data){                                      \
+#define GET_MAPPING(sourceChar,targetUniChar,data) UPRV_BLOCK_MACRO_BEGIN {              \
     targetUniChar = toUnicodeTable[(sourceChar)] ;                                       \
     /* is the code point valid in current script? */                                     \
     if(sourceChar> ASCII_END &&                                                          \
@@ -1147,7 +1153,7 @@
             targetUniChar=missingCharMarker;                                             \
         }                                                                                \
     }                                                                                    \
-}
+} UPRV_BLOCK_MACRO_END
 
 /***********
  *  Rules for ISCII to Unicode converter
@@ -1170,7 +1176,8 @@
  *
  */
 
-static void UConverter_toUnicode_ISCII_OFFSETS_LOGIC(UConverterToUnicodeArgs *args, UErrorCode* err) {
+static void U_CALLCONV
+UConverter_toUnicode_ISCII_OFFSETS_LOGIC(UConverterToUnicodeArgs *args, UErrorCode* err) {
     const char *source = ( char *) args->source;
     UChar *target = args->target;
     const char *sourceLimit = args->sourceLimit;
@@ -1284,7 +1291,7 @@
             /* look at the pre-context and perform special processing */
             switch (sourceChar) {
             case ISCII_INV:
-            case EXT: /*falls through*/
+            case EXT:
             case ATR:
                 *contextCharToUnicode = (UChar)sourceChar;
 
@@ -1322,7 +1329,6 @@
                 }
                 break;
             case 0x0A:
-                /* fall through */
             case 0x0D:
                 data->resetToDefaultToUnicode = TRUE;
                 GET_MAPPING(sourceChar,targetUniChar,data)
@@ -1334,7 +1340,7 @@
                 i=1;
                 found=FALSE;
                 for (; i<vowelSignESpecialCases[0][0]; i++) {
-                    U_ASSERT(i<sizeof(vowelSignESpecialCases)/sizeof(vowelSignESpecialCases[0]));
+                    U_ASSERT(i<UPRV_LENGTHOF(vowelSignESpecialCases));
                     if (vowelSignESpecialCases[i][0]==(uint8_t)*contextCharToUnicode) {
                         targetUniChar=vowelSignESpecialCases[i][1];
                         found=TRUE;
@@ -1420,6 +1426,7 @@
                         /* else fall through to default */
                     }
                     /* else fall through to default */
+                    U_FALLTHROUGH;
                 }
             default:GET_MAPPING(sourceChar,targetUniChar,data)
                 ;
@@ -1430,7 +1437,7 @@
             if (*toUnicodeStatus != missingCharMarker) {
                 /* Check to make sure that consonant clusters are handled correct for Gurmukhi script. */
                 if (data->currentDeltaToUnicode == PNJ_DELTA && data->prevToUnicodeStatus != 0 && isPNJConsonant(data->prevToUnicodeStatus) &&
-                        (*toUnicodeStatus + PNJ_DELTA) == PNJ_SIGN_VIRAMA && (targetUniChar + PNJ_DELTA) == data->prevToUnicodeStatus) {
+                        (*toUnicodeStatus + PNJ_DELTA) == PNJ_SIGN_VIRAMA && ((UChar32)(targetUniChar + PNJ_DELTA) == data->prevToUnicodeStatus)) {
                     /* Consonant clusters C + HALANT + C should be encoded as ADHAK + C */
                     offset = (int)(source-args->source - 3);
                     tempTargetUniChar = PNJ_ADHAK; /* This is necessary to avoid some compiler warnings. */
@@ -1520,7 +1527,7 @@
     UConverterDataISCII mydata;
 };
 
-static UConverter *
+static UConverter * U_CALLCONV
 _ISCII_SafeClone(const UConverter *cnv,
               void *stackBuffer,
               int32_t *pBufferSize,
@@ -1548,12 +1555,15 @@
     return &localClone->cnv;
 }
 
-static void
+static void U_CALLCONV
 _ISCIIGetUnicodeSet(const UConverter *cnv,
                     const USetAdder *sa,
                     UConverterUnicodeSet which,
                     UErrorCode *pErrorCode)
 {
+    (void)cnv;
+    (void)which;
+    (void)pErrorCode;
     int32_t idx, script;
     uint8_t mask;
 
@@ -1574,7 +1584,7 @@
     sa->add(sa->set, ZWNJ);
     sa->add(sa->set, ZWJ);
 }
-
+U_CDECL_END
 static const UConverterImpl _ISCIIImpl={
 
     UCNV_ISCII,
@@ -1596,7 +1606,9 @@
     _ISCIIgetName,
     NULL,
     _ISCII_SafeClone,
-    _ISCIIGetUnicodeSet
+    _ISCIIGetUnicodeSet,
+    NULL,
+    NULL
 };
 
 static const UConverterStaticData _ISCIIStaticData={
diff --git a/src/third_party/icu/source/common/ucnvlat1.c b/src/third_party/icu/source/common/ucnvlat1.cpp
similarity index 96%
rename from src/third_party/icu/source/common/ucnvlat1.c
rename to src/third_party/icu/source/common/ucnvlat1.cpp
index 95e0495..358bc0c 100644
--- a/src/third_party/icu/source/common/ucnvlat1.c
+++ b/src/third_party/icu/source/common/ucnvlat1.cpp
@@ -1,10 +1,12 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /* 
 **********************************************************************
 *   Copyright (C) 2000-2015, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 **********************************************************************
 *   file name:  ucnvlat1.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -21,6 +23,7 @@
 #include "unicode/utf8.h"
 #include "ucnv_bld.h"
 #include "ucnv_cnv.h"
+#include "ustr_imp.h"
 
 /* control optimizations according to the platform */
 #define LATIN1_UNROLL_FROM_UNICODE 1
@@ -28,7 +31,8 @@
 /* ISO 8859-1 --------------------------------------------------------------- */
 
 /* This is a table-less and callback-less version of ucnv_MBCSSingleToBMPWithOffsets(). */
-static void
+U_CDECL_BEGIN
+static void U_CALLCONV
 _Latin1ToUnicodeWithOffsets(UConverterToUnicodeArgs *pArgs,
                             UErrorCode *pErrorCode) {
     const uint8_t *source;
@@ -114,7 +118,7 @@
 }
 
 /* This is a table-less and callback-less version of ucnv_MBCSSingleGetNextUChar(). */
-static UChar32
+static UChar32 U_CALLCONV
 _Latin1GetNextUChar(UConverterToUnicodeArgs *pArgs,
                     UErrorCode *pErrorCode) {
     const uint8_t *source=(const uint8_t *)pArgs->source;
@@ -129,7 +133,7 @@
 }
 
 /* This is a table-less version of ucnv_MBCSSingleFromBMPWithOffsets(). */
-static void
+static void U_CALLCONV
 _Latin1FromUnicodeWithOffsets(UConverterFromUnicodeArgs *pArgs,
                               UErrorCode *pErrorCode) {
     UConverter *cnv;
@@ -316,7 +320,7 @@
 }
 
 /* Convert UTF-8 to Latin-1. Adapted from ucnv_SBCSFromUTF8(). */
-static void
+static void U_CALLCONV
 ucnv_Latin1FromUTF8(UConverterFromUnicodeArgs *pFromUArgs,
                     UConverterToUnicodeArgs *pToUArgs,
                     UErrorCode *pErrorCode) {
@@ -336,7 +340,11 @@
     targetCapacity=(int32_t)(pFromUArgs->targetLimit-pFromUArgs->target);
 
     /* get the converter state from the UTF-8 UConverter */
-    c=(UChar32)utf8->toUnicodeStatus;
+    if (utf8->toULength > 0) {
+        c=(UChar32)utf8->toUnicodeStatus;
+    } else {
+        c = 0;
+    }
     if(c!=0 && source<sourceLimit) {
         if(targetCapacity==0) {
             *pErrorCode=U_BUFFER_OVERFLOW_ERROR;
@@ -371,7 +379,7 @@
     while(source<sourceLimit) {
         if(targetCapacity>0) {
             b=*source++;
-            if((int8_t)b>=0) {
+            if(U8_IS_SINGLE(b)) {
                 /* convert ASCII */
                 *target++=(uint8_t)b;
                 --targetCapacity;
@@ -406,7 +414,7 @@
     if(U_SUCCESS(*pErrorCode) && source<(sourceLimit=(uint8_t *)pToUArgs->sourceLimit)) {
         utf8->toUnicodeStatus=utf8->toUBytes[0]=b=*source++;
         utf8->toULength=1;
-        utf8->mode=U8_COUNT_TRAIL_BYTES(b)+1;
+        utf8->mode=U8_COUNT_BYTES(b);
     }
 
     /* write back the updated pointers */
@@ -414,13 +422,18 @@
     pFromUArgs->target=(char *)target;
 }
 
-static void
+static void U_CALLCONV
 _Latin1GetUnicodeSet(const UConverter *cnv,
                      const USetAdder *sa,
                      UConverterUnicodeSet which,
                      UErrorCode *pErrorCode) {
+    (void)cnv;
+    (void)which;
+    (void)pErrorCode;
     sa->addRange(sa->set, 0, 0xff);
 }
+U_CDECL_END
+
 
 static const UConverterImpl _Latin1Impl={
     UCNV_LATIN_1,
@@ -463,8 +476,9 @@
 
 /* US-ASCII ----------------------------------------------------------------- */
 
+U_CDECL_BEGIN
 /* This is a table-less version of ucnv_MBCSSingleToBMPWithOffsets(). */
-static void
+static void U_CALLCONV
 _ASCIIToUnicodeWithOffsets(UConverterToUnicodeArgs *pArgs,
                            UErrorCode *pErrorCode) {
     const uint8_t *source, *sourceLimit;
@@ -573,7 +587,7 @@
 }
 
 /* This is a table-less version of ucnv_MBCSSingleGetNextUChar(). */
-static UChar32
+static UChar32 U_CALLCONV
 _ASCIIGetNextUChar(UConverterToUnicodeArgs *pArgs,
                    UErrorCode *pErrorCode) {
     const uint8_t *source;
@@ -600,7 +614,7 @@
 }
 
 /* "Convert" UTF-8 to US-ASCII: Validate and copy. */
-static void
+static void U_CALLCONV
 ucnv_ASCIIFromUTF8(UConverterFromUnicodeArgs *pFromUArgs,
                    UConverterToUnicodeArgs *pToUArgs,
                    UErrorCode *pErrorCode) {
@@ -610,7 +624,7 @@
 
     uint8_t c;
 
-    if(pToUArgs->converter->toUnicodeStatus!=0) {
+    if(pToUArgs->converter->toULength > 0) {
         /* no handling of partial UTF-8 characters here, fall back to pivoting */
         *pErrorCode=U_USING_DEFAULT_WARNING;
         return;
@@ -688,13 +702,17 @@
     pFromUArgs->target=(char *)target;
 }
 
-static void
+static void U_CALLCONV
 _ASCIIGetUnicodeSet(const UConverter *cnv,
                     const USetAdder *sa,
                     UConverterUnicodeSet which,
                     UErrorCode *pErrorCode) {
+    (void)cnv;
+    (void)which;
+    (void)pErrorCode;
     sa->addRange(sa->set, 0, 0x7f);
 }
+U_CDECL_END
 
 static const UConverterImpl _ASCIIImpl={
     UCNV_US_ASCII,
diff --git a/src/third_party/icu/source/common/ucnvmbcs.cpp b/src/third_party/icu/source/common/ucnvmbcs.cpp
index 4cec42e..4a56c2a 100644
--- a/src/third_party/icu/source/common/ucnvmbcs.cpp
+++ b/src/third_party/icu/source/common/ucnvmbcs.cpp
@@ -1,12 +1,14 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
-*   Copyright (C) 2000-2015, International Business Machines
+*   Copyright (C) 2000-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *
 ******************************************************************************
 *   file name:  ucnvmbcs.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -44,7 +46,9 @@
 
 #if !UCONFIG_NO_CONVERSION && !UCONFIG_NO_LEGACY_CONVERSION
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/ucnv.h"
 #include "unicode/ucnv_cb.h"
 #include "unicode/udata.h"
@@ -58,6 +62,7 @@
 #include "cmemory.h"
 #include "cstring.h"
 #include "umutex.h"
+#include "ustr_imp.h"
 
 /* control optimizations according to the platform */
 #define MBCS_UNROLL_SINGLE_TO_BMP 1
@@ -376,53 +381,55 @@
 typedef UBool U_CALLCONV
 UConverterEnumToUCallback(const void *context, uint32_t value, UChar32 codePoints[32]);
 
-static void
+static void U_CALLCONV
 ucnv_MBCSLoad(UConverterSharedData *sharedData,
           UConverterLoadArgs *pArgs,
           const uint8_t *raw,
           UErrorCode *pErrorCode);
 
-static void
+static void U_CALLCONV
 ucnv_MBCSUnload(UConverterSharedData *sharedData);
 
-static void
+static void U_CALLCONV
 ucnv_MBCSOpen(UConverter *cnv,
               UConverterLoadArgs *pArgs,
               UErrorCode *pErrorCode);
 
-static UChar32
+static UChar32 U_CALLCONV
 ucnv_MBCSGetNextUChar(UConverterToUnicodeArgs *pArgs,
                   UErrorCode *pErrorCode);
 
-static void
+static void U_CALLCONV
 ucnv_MBCSGetStarters(const UConverter* cnv,
                  UBool starters[256],
                  UErrorCode *pErrorCode);
 
-static const char *
+U_CDECL_BEGIN
+static const char* U_CALLCONV
 ucnv_MBCSGetName(const UConverter *cnv);
+U_CDECL_END
 
-static void
+static void U_CALLCONV
 ucnv_MBCSWriteSub(UConverterFromUnicodeArgs *pArgs,
               int32_t offsetIndex,
               UErrorCode *pErrorCode);
 
-static UChar32
+static UChar32 U_CALLCONV
 ucnv_MBCSGetNextUChar(UConverterToUnicodeArgs *pArgs,
                   UErrorCode *pErrorCode);
 
-static void
+static void U_CALLCONV
 ucnv_SBCSFromUTF8(UConverterFromUnicodeArgs *pFromUArgs,
                   UConverterToUnicodeArgs *pToUArgs,
                   UErrorCode *pErrorCode);
 
-static void
+static void U_CALLCONV
 ucnv_MBCSGetUnicodeSet(const UConverter *cnv,
                    const USetAdder *sa,
                    UConverterUnicodeSet which,
                    UErrorCode *pErrorCode);
 
-static void
+static void U_CALLCONV
 ucnv_DBCSFromUTF8(UConverterFromUnicodeArgs *pFromUArgs,
                   UConverterToUnicodeArgs *pToUArgs,
                   UErrorCode *pErrorCode);
@@ -504,7 +511,6 @@
     NULL
 };
 
-
 /* Static data is in tools/makeconv/ucnvstat.c for data-based
  * converters. Be sure to update it as well.
  */
@@ -846,7 +852,7 @@
     }
 }
 
-U_CFUNC void
+U_CFUNC void 
 ucnv_MBCSGetFilteredUnicodeSetForUnicode(const UConverterSharedData *sharedData,
                                          const USetAdder *sa,
                                          UConverterUnicodeSet which,
@@ -964,11 +970,14 @@
                                     switch(st3Multiplier) {
                                     case 4:
                                         b|=*stage3++;
-                                    case 3: /*fall through*/
+                                        U_FALLTHROUGH;
+                                    case 3:
                                         b|=*stage3++;
-                                    case 2: /*fall through*/
+                                        U_FALLTHROUGH;
+                                    case 2:
                                         b|=stage3[0]|stage3[1];
                                         stage3+=2;
+                                        U_FALLTHROUGH;
                                     default:
                                         break;
                                     }
@@ -1065,7 +1074,7 @@
         pErrorCode);
 }
 
-static void
+static void U_CALLCONV
 ucnv_MBCSGetUnicodeSet(const UConverter *cnv,
                    const USetAdder *sa,
                    UConverterUnicodeSet which,
@@ -1377,7 +1386,7 @@
     uprv_strcat(name, UCNV_SWAP_LFNL_OPTION_STRING);
 
     /* set the pointers */
-    umtx_lock(NULL);
+    icu::umtx_lock(NULL);
     if(mbcsTable->swapLFNLStateTable==NULL) {
         mbcsTable->swapLFNLStateTable=newStateTable;
         mbcsTable->swapLFNLFromUnicodeBytes=(uint8_t *)newResults;
@@ -1385,7 +1394,7 @@
 
         newStateTable=NULL;
     }
-    umtx_unlock(NULL);
+    icu::umtx_unlock(NULL);
 
     /* release the allocated memory if another thread beat us to it */
     if(newStateTable!=NULL) {
@@ -1545,7 +1554,7 @@
 
 /* MBCS setup functions ----------------------------------------------------- */
 
-static void
+static void U_CALLCONV
 ucnv_MBCSLoad(UConverterSharedData *sharedData,
           UConverterLoadArgs *pArgs,
           const uint8_t *raw,
@@ -1870,7 +1879,7 @@
     }
 }
 
-static void
+static void U_CALLCONV
 ucnv_MBCSUnload(UConverterSharedData *sharedData) {
     UConverterMBCSTable *mbcsTable=&sharedData->mbcs;
 
@@ -1888,7 +1897,7 @@
     }
 }
 
-static void
+static void U_CALLCONV
 ucnv_MBCSOpen(UConverter *cnv,
               UConverterLoadArgs *pArgs,
               UErrorCode *pErrorCode) {
@@ -1913,9 +1922,9 @@
         /* do this because double-checked locking is broken */
         UBool isCached;
 
-        umtx_lock(NULL);
+        icu::umtx_lock(NULL);
         isCached=mbcsTable->swapLFNLStateTable!=NULL;
-        umtx_unlock(NULL);
+        icu::umtx_unlock(NULL);
 
         if(!isCached) {
             if(!_EBCDICSwapLFNL(cnv->sharedData, pErrorCode)) {
@@ -1979,7 +1988,9 @@
 #endif
 }
 
-static const char *
+U_CDECL_BEGIN
+
+static const char* U_CALLCONV
 ucnv_MBCSGetName(const UConverter *cnv) {
     if((cnv->options&UCNV_OPTION_SWAP_LFNL)!=0 && cnv->sharedData->mbcs.swapLFNLName!=NULL) {
         return cnv->sharedData->mbcs.swapLFNLName;
@@ -1987,10 +1998,12 @@
         return cnv->sharedData->staticData->name;
     }
 }
+U_CDECL_END
+
 
 /* MBCS-to-Unicode conversion functions ------------------------------------- */
 
-static UChar32
+static UChar32 U_CALLCONV
 ucnv_MBCSGetFallback(UConverterMBCSTable *mbcsTable, uint32_t offset) {
     const _MBCSToUFallback *toUFallbacks;
     uint32_t i, start, limit;
@@ -2953,7 +2966,7 @@
  *
  * All normal mappings and errors are handled here.
  */
-static UChar32
+static UChar32 U_CALLCONV
 ucnv_MBCSGetNextUChar(UConverterToUnicodeArgs *pArgs,
                   UErrorCode *pErrorCode) {
     UConverter *cnv;
@@ -4154,8 +4167,8 @@
     nextSourceIndex=0;
 
     /* Get the SI/SO character for the converter */
-    siLength = getSISOBytes(SI, cnv->options, siBytes);
-    soLength = getSISOBytes(SO, cnv->options, soBytes);
+    siLength = static_cast<uint8_t>(getSISOBytes(SI, cnv->options, siBytes));
+    soLength = static_cast<uint8_t>(getSISOBytes(SO, cnv->options, soBytes));
 
     /* conversion loop */
     /*
@@ -4635,12 +4648,16 @@
                         /* each branch falls through to the next one */
                     case 4:
                         *target++=(uint8_t)(value>>24);
-                    case 3: /*fall through*/
+                        U_FALLTHROUGH;
+                    case 3:
                         *target++=(uint8_t)(value>>16);
-                    case 2: /*fall through*/
+                        U_FALLTHROUGH;
+                    case 2:
                         *target++=(uint8_t)(value>>8);
-                    case 1: /*fall through*/
+                        U_FALLTHROUGH;
+                    case 1:
                         *target++=(uint8_t)value;
+                        U_FALLTHROUGH;
                     default:
                         /* will never occur */
                         break;
@@ -4651,15 +4668,19 @@
                     case 4:
                         *target++=(uint8_t)(value>>24);
                         *offsets++=sourceIndex;
-                    case 3: /*fall through*/
+                        U_FALLTHROUGH;
+                    case 3:
                         *target++=(uint8_t)(value>>16);
                         *offsets++=sourceIndex;
-                    case 2: /*fall through*/
+                        U_FALLTHROUGH;
+                    case 2:
                         *target++=(uint8_t)(value>>8);
                         *offsets++=sourceIndex;
-                    case 1: /*fall through*/
+                        U_FALLTHROUGH;
+                    case 1:
                         *target++=(uint8_t)value;
                         *offsets++=sourceIndex;
+                        U_FALLTHROUGH;
                     default:
                         /* will never occur */
                         break;
@@ -4682,10 +4703,13 @@
                     /* each branch falls through to the next one */
                 case 3:
                     *charErrorBuffer++=(uint8_t)(value>>16);
-                case 2: /*fall through*/
+                    U_FALLTHROUGH;
+                case 2:
                     *charErrorBuffer++=(uint8_t)(value>>8);
-                case 1: /*fall through*/
+                    U_FALLTHROUGH;
+                case 1:
                     *charErrorBuffer=(uint8_t)value;
+                    U_FALLTHROUGH;
                 default:
                     /* will never occur */
                     break;
@@ -4701,16 +4725,19 @@
                     if(offsets!=NULL) {
                         *offsets++=sourceIndex;
                     }
-                case 2: /*fall through*/
+                    U_FALLTHROUGH;
+                case 2:
                     *target++=(uint8_t)(value>>8);
                     if(offsets!=NULL) {
                         *offsets++=sourceIndex;
                     }
-                case 1: /*fall through*/
+                    U_FALLTHROUGH;
+                case 1:
                     *target++=(uint8_t)value;
                     if(offsets!=NULL) {
                         *offsets++=sourceIndex;
                     }
+                    U_FALLTHROUGH;
                 default:
                     /* will never occur */
                     break;
@@ -4988,15 +5015,11 @@
 
 /* MBCS-from-UTF-8 conversion functions ------------------------------------- */
 
-/* minimum code point values for n-byte UTF-8 sequences, n=0..4 */
-static const UChar32
-utf8_minLegal[5]={ 0, 0, 0x80, 0x800, 0x10000 };
-
 /* offsets for n-byte UTF-8 sequences that were calculated with ((lead<<6)+trail)<<6+trail... */
 static const UChar32
-utf8_offsets[7]={ 0, 0, 0x3080, 0xE2080, 0x3C82080 };
+utf8_offsets[5]={ 0, 0, 0x3080, 0xE2080, 0x3C82080 };
 
-static void
+static void U_CALLCONV
 ucnv_SBCSFromUTF8(UConverterFromUnicodeArgs *pFromUArgs,
                   UConverterToUnicodeArgs *pToUArgs,
                   UErrorCode *pErrorCode) {
@@ -5014,7 +5037,7 @@
     uint8_t b, t1, t2;
 
     uint32_t asciiRoundtrips;
-    uint16_t value, minValue;
+    uint16_t value, minValue = 0;
     UBool hasSupplementary;
 
     /* set up the local pointers */
@@ -5044,36 +5067,36 @@
     hasSupplementary=(UBool)(cnv->sharedData->mbcs.unicodeMask&UCNV_HAS_SUPPLEMENTARY);
 
     /* get the converter state from the UTF-8 UConverter */
-    c=(UChar32)utf8->toUnicodeStatus;
-    if(c!=0) {
+    if(utf8->toULength > 0) {
         toULength=oldToULength=utf8->toULength;
         toULimit=(int8_t)utf8->mode;
+        c=(UChar32)utf8->toUnicodeStatus;
     } else {
         toULength=oldToULength=toULimit=0;
+        c = 0;
     }
 
-    /*
-     * Make sure that the last byte sequence before sourceLimit is complete
-     * or runs into a lead byte.
-     * Do not go back into the bytes that will be read for finishing a partial
-     * sequence from the previous buffer.
-     * In the conversion loop compare source with sourceLimit only once
-     * per multi-byte character.
-     */
+    // The conversion loop checks source<sourceLimit only once per 1/2/3-byte character.
+    // If the buffer ends with a truncated 2- or 3-byte sequence,
+    // then we reduce the sourceLimit to before that,
+    // and collect the remaining bytes after the conversion loop.
     {
-        int32_t i, length;
-
-        length=(int32_t)(sourceLimit-source) - (toULimit-oldToULength);
-        for(i=0; i<3 && i<length;) {
-            b=*(sourceLimit-i-1);
-            if(U8_IS_TRAIL(b)) {
-                ++i;
-            } else {
-                if(i<U8_COUNT_TRAIL_BYTES(b)) {
-                    /* exit the conversion loop before the lead byte if there are not enough trail bytes for it */
-                    sourceLimit-=i+1;
+        // Do not go back into the bytes that will be read for finishing a partial
+        // sequence from the previous buffer.
+        int32_t length=(int32_t)(sourceLimit-source) - (toULimit-oldToULength);
+        if(length>0) {
+            uint8_t b1=*(sourceLimit-1);
+            if(U8_IS_SINGLE(b1)) {
+                // common ASCII character
+            } else if(U8_IS_TRAIL(b1) && length>=2) {
+                uint8_t b2=*(sourceLimit-2);
+                if(0xe0<=b2 && b2<0xf0 && U8_IS_VALID_LEAD3_AND_T1(b2, b1)) {
+                    // truncated 3-byte sequence
+                    sourceLimit-=2;
                 }
-                break;
+            } else if(0xc2<=b1 && b1<0xf0) {
+                // truncated 2- or 3-byte sequence
+                --sourceLimit;
             }
         }
     }
@@ -5107,7 +5130,7 @@
     while(source<sourceLimit) {
         if(targetCapacity>0) {
             b=*source++;
-            if((int8_t)b>=0) {
+            if(U8_IS_SINGLE(b)) {
                 /* convert ASCII */
                 if(IS_ASCII_ROUNDTRIP(b, asciiRoundtrips)) {
                     *target++=(uint8_t)b;
@@ -5162,7 +5185,7 @@
                     /* handle "complicated" and error cases, and continuing partial characters */
                     oldToULength=0;
                     toULength=1;
-                    toULimit=U8_COUNT_TRAIL_BYTES(b)+1;
+                    toULimit=U8_COUNT_BYTES_NON_ASCII(b);
                     c=b;
 moreBytes:
                     while(toULength<toULimit) {
@@ -5175,7 +5198,7 @@
                          */
                         if(source<(uint8_t *)pToUArgs->sourceLimit) {
                             b=*source;
-                            if(U8_IS_TRAIL(b)) {
+                            if(icu::UTF8::isValidTrail(c, b, toULength, toULimit)) {
                                 ++source;
                                 ++toULength;
                                 c=(c<<6)+b;
@@ -5197,22 +5220,18 @@
                         }
                     }
 
-                    if( toULength==toULimit &&      /* consumed all trail bytes */
-                        (toULength==3 || toULength==2) &&             /* BMP */
-                        (c-=utf8_offsets[toULength])>=utf8_minLegal[toULength] &&
-                        (c<=0xd7ff || 0xe000<=c)    /* not a surrogate */
-                    ) {
-                        value=MBCS_SINGLE_RESULT_FROM_U(table, results, c);
-                    } else if(
-                        toULength==toULimit && toULength==4 &&
-                        (0x10000<=(c-=utf8_offsets[4]) && c<=0x10ffff)
-                    ) {
-                        /* supplementary code point */
-                        if(!hasSupplementary) {
-                            /* BMP-only codepages are stored without stage 1 entries for supplementary code points */
-                            value=0;
-                        } else {
+                    if(toULength==toULimit) {
+                        c-=utf8_offsets[toULength];
+                        if(toULength<=3) {  /* BMP */
                             value=MBCS_SINGLE_RESULT_FROM_U(table, results, c);
+                        } else {
+                            /* supplementary code point */
+                            if(!hasSupplementary) {
+                                /* BMP-only codepages are stored without stage 1 entries for supplementary code points */
+                                value=0;
+                            } else {
+                                value=MBCS_SINGLE_RESULT_FROM_U(table, results, c);
+                            }
                         }
                     } else {
                         /* error handling: illegal UTF-8 byte sequence */
@@ -5287,7 +5306,7 @@
             source<(sourceLimit=(uint8_t *)pToUArgs->sourceLimit)) {
         c=utf8->toUBytes[0]=b=*source++;
         toULength=1;
-        toULimit=U8_COUNT_TRAIL_BYTES(b)+1;
+        toULimit=U8_COUNT_BYTES(b);
         while(source<sourceLimit) {
             utf8->toUBytes[toULength++]=b=*source++;
             c=(c<<6)+b;
@@ -5302,7 +5321,7 @@
     pFromUArgs->target=(char *)target;
 }
 
-static void
+static void U_CALLCONV
 ucnv_DBCSFromUTF8(UConverterFromUnicodeArgs *pFromUArgs,
                   UConverterToUnicodeArgs *pToUArgs,
                   UErrorCode *pErrorCode) {
@@ -5321,7 +5340,7 @@
 
     uint32_t stage2Entry;
     uint32_t asciiRoundtrips;
-    uint16_t value;
+    uint16_t value = 0;
     UBool hasSupplementary;
 
     /* set up the local pointers */
@@ -5344,36 +5363,36 @@
     hasSupplementary=(UBool)(cnv->sharedData->mbcs.unicodeMask&UCNV_HAS_SUPPLEMENTARY);
 
     /* get the converter state from the UTF-8 UConverter */
-    c=(UChar32)utf8->toUnicodeStatus;
-    if(c!=0) {
+    if(utf8->toULength > 0) {
         toULength=oldToULength=utf8->toULength;
         toULimit=(int8_t)utf8->mode;
+        c=(UChar32)utf8->toUnicodeStatus;
     } else {
         toULength=oldToULength=toULimit=0;
+        c = 0;
     }
 
-    /*
-     * Make sure that the last byte sequence before sourceLimit is complete
-     * or runs into a lead byte.
-     * Do not go back into the bytes that will be read for finishing a partial
-     * sequence from the previous buffer.
-     * In the conversion loop compare source with sourceLimit only once
-     * per multi-byte character.
-     */
+    // The conversion loop checks source<sourceLimit only once per 1/2/3-byte character.
+    // If the buffer ends with a truncated 2- or 3-byte sequence,
+    // then we reduce the sourceLimit to before that,
+    // and collect the remaining bytes after the conversion loop.
     {
-        int32_t i, length;
-
-        length=(int32_t)(sourceLimit-source) - (toULimit-oldToULength);
-        for(i=0; i<3 && i<length;) {
-            b=*(sourceLimit-i-1);
-            if(U8_IS_TRAIL(b)) {
-                ++i;
-            } else {
-                if(i<U8_COUNT_TRAIL_BYTES(b)) {
-                    /* exit the conversion loop before the lead byte if there are not enough trail bytes for it */
-                    sourceLimit-=i+1;
+        // Do not go back into the bytes that will be read for finishing a partial
+        // sequence from the previous buffer.
+        int32_t length=(int32_t)(sourceLimit-source) - (toULimit-oldToULength);
+        if(length>0) {
+            uint8_t b1=*(sourceLimit-1);
+            if(U8_IS_SINGLE(b1)) {
+                // common ASCII character
+            } else if(U8_IS_TRAIL(b1) && length>=2) {
+                uint8_t b2=*(sourceLimit-2);
+                if(0xe0<=b2 && b2<0xf0 && U8_IS_VALID_LEAD3_AND_T1(b2, b1)) {
+                    // truncated 3-byte sequence
+                    sourceLimit-=2;
                 }
-                break;
+            } else if(0xc2<=b1 && b1<0xf0) {
+                // truncated 2- or 3-byte sequence
+                --sourceLimit;
             }
         }
     }
@@ -5389,7 +5408,7 @@
     while(source<sourceLimit) {
         if(targetCapacity>0) {
             b=*source++;
-            if((int8_t)b>=0) {
+            if(U8_IS_SINGLE(b)) {
                 /* convert ASCII */
                 if(IS_ASCII_ROUNDTRIP(b, asciiRoundtrips)) {
                     *target++=b;
@@ -5403,13 +5422,13 @@
                     }
                 }
             } else {
-                if(b>0xe0) {
-                    if( /* handle U+1000..U+D7FF inline */
-                        (((t1=(uint8_t)(source[0]-0x80), b<0xed) && (t1 <= 0x3f)) ||
-                                                        (b==0xed && (t1 <= 0x1f))) &&
+                if(b>=0xe0) {
+                    if( /* handle U+0800..U+D7FF inline */
+                        b<=0xed &&  // do not assume maxFastUChar>0xd7ff
+                        U8_IS_VALID_LEAD3_AND_T1(b, t1=source[0]) &&
                         (t2=(uint8_t)(source[1]-0x80)) <= 0x3f
                     ) {
-                        c=((b&0xf)<<6)|t1;
+                        c=((b&0xf)<<6)|(t1&0x3f);
                         source+=2;
                         value=DBCS_RESULT_FROM_UTF8(mbcsIndex, results, c, t2);
                         if(value==0) {
@@ -5419,7 +5438,7 @@
                     } else {
                         c=-1;
                     }
-                } else if(b<0xe0) {
+                } else {
                     if( /* handle U+0080..U+07FF inline */
                         b>=0xc2 &&
                         (t1=(uint8_t)(*source-0x80)) <= 0x3f
@@ -5434,15 +5453,13 @@
                     } else {
                         c=-1;
                     }
-                } else {
-                    c=-1;
                 }
 
                 if(c<0) {
                     /* handle "complicated" and error cases, and continuing partial characters */
                     oldToULength=0;
                     toULength=1;
-                    toULimit=U8_COUNT_TRAIL_BYTES(b)+1;
+                    toULimit=U8_COUNT_BYTES_NON_ASCII(b);
                     c=b;
 moreBytes:
                     while(toULength<toULimit) {
@@ -5455,7 +5472,7 @@
                          */
                         if(source<(uint8_t *)pToUArgs->sourceLimit) {
                             b=*source;
-                            if(U8_IS_TRAIL(b)) {
+                            if(icu::UTF8::isValidTrail(c, b, toULength, toULimit)) {
                                 ++source;
                                 ++toULength;
                                 c=(c<<6)+b;
@@ -5477,22 +5494,18 @@
                         }
                     }
 
-                    if( toULength==toULimit &&      /* consumed all trail bytes */
-                        (toULength==3 || toULength==2) &&             /* BMP */
-                        (c-=utf8_offsets[toULength])>=utf8_minLegal[toULength] &&
-                        (c<=0xd7ff || 0xe000<=c)    /* not a surrogate */
-                    ) {
-                        stage2Entry=MBCS_STAGE_2_FROM_U(table, c);
-                    } else if(
-                        toULength==toULimit && toULength==4 &&
-                        (0x10000<=(c-=utf8_offsets[4]) && c<=0x10ffff)
-                    ) {
-                        /* supplementary code point */
-                        if(!hasSupplementary) {
-                            /* BMP-only codepages are stored without stage 1 entries for supplementary code points */
-                            stage2Entry=0;
-                        } else {
+                    if(toULength==toULimit) {
+                        c-=utf8_offsets[toULength];
+                        if(toULength<=3) {  /* BMP */
                             stage2Entry=MBCS_STAGE_2_FROM_U(table, c);
+                        } else {
+                            /* supplementary code point */
+                            if(!hasSupplementary) {
+                                /* BMP-only codepages are stored without stage 1 entries for supplementary code points */
+                                stage2Entry=0;
+                            } else {
+                                stage2Entry=MBCS_STAGE_2_FROM_U(table, c);
+                            }
                         }
                     } else {
                         /* error handling: illegal UTF-8 byte sequence */
@@ -5597,7 +5610,7 @@
             source<(sourceLimit=(uint8_t *)pToUArgs->sourceLimit)) {
         c=utf8->toUBytes[0]=b=*source++;
         toULength=1;
-        toULimit=U8_COUNT_TRAIL_BYTES(b)+1;
+        toULimit=U8_COUNT_BYTES(b);
         while(source<sourceLimit) {
             utf8->toUBytes[toULength++]=b=*source++;
             c=(c<<6)+b;
@@ -5614,7 +5627,7 @@
 
 /* miscellaneous ------------------------------------------------------------ */
 
-static void
+static void U_CALLCONV
 ucnv_MBCSGetStarters(const UConverter* cnv,
                  UBool starters[256],
                  UErrorCode *) {
@@ -5637,7 +5650,7 @@
     return (UBool)MBCS_ENTRY_IS_TRANSITION(sharedData->mbcs.stateTable[0][(uint8_t)byte]);
 }
 
-static void
+static void U_CALLCONV
 ucnv_MBCSWriteSub(UConverterFromUnicodeArgs *pArgs,
               int32_t offsetIndex,
               UErrorCode *pErrorCode) {
diff --git a/src/third_party/icu/source/common/ucnvmbcs.h b/src/third_party/icu/source/common/ucnvmbcs.h
index c248c3d..c8f3b89 100644
--- a/src/third_party/icu/source/common/ucnvmbcs.h
+++ b/src/third_party/icu/source/common/ucnvmbcs.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 ******************************************************************************
 *   file name:  ucnvmbcs.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -418,7 +420,7 @@
     NULL, \
     0, \
     0, 0, \
-    FALSE, \
+    false, \
     0, \
      \
     /* roundtrips */ \
diff --git a/src/third_party/icu/source/common/ucnvscsu.c b/src/third_party/icu/source/common/ucnvscsu.cpp
similarity index 97%
rename from src/third_party/icu/source/common/ucnvscsu.c
rename to src/third_party/icu/source/common/ucnvscsu.cpp
index 1aacd81..74b5722 100644
--- a/src/third_party/icu/source/common/ucnvscsu.c
+++ b/src/third_party/icu/source/common/ucnvscsu.cpp
@@ -1,12 +1,14 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
-*   Copyright (C) 2000-2015, International Business Machines
+*   Copyright (C) 2000-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *
 ******************************************************************************
 *   file name:  ucnvscsu.c
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -152,8 +154,8 @@
 };
 
 /* SCSU setup functions ----------------------------------------------------- */
-
-static void
+U_CDECL_BEGIN
+static void U_CALLCONV
 _SCSUReset(UConverter *cnv, UConverterResetChoice choice) {
     SCSUData *scsu=(SCSUData *)cnv->extraInfo;
 
@@ -189,7 +191,7 @@
     }
 }
 
-static void
+static void U_CALLCONV
 _SCSUOpen(UConverter *cnv,
           UConverterLoadArgs *pArgs,
           UErrorCode *pErrorCode) {
@@ -214,7 +216,7 @@
     cnv->subCharLen=-1;
 }
 
-static void
+static void U_CALLCONV
 _SCSUClose(UConverter *cnv) {
     if(cnv->extraInfo!=NULL) {
         if(!cnv->isExtraLocal) {
@@ -226,7 +228,7 @@
 
 /* SCSU-to-Unicode conversion functions ------------------------------------- */
 
-static void
+static void U_CALLCONV
 _SCSUToUnicodeWithOffsets(UConverterToUnicodeArgs *pArgs,
                           UErrorCode *pErrorCode) {
     UConverter *cnv;
@@ -580,7 +582,7 @@
  * re-copy the original function and remove the variables
  * offsets, sourceIndex, and nextSourceIndex.
  */
-static void
+static void U_CALLCONV
 _SCSUToUnicode(UConverterToUnicodeArgs *pArgs,
                UErrorCode *pErrorCode) {
     UConverter *cnv;
@@ -864,7 +866,7 @@
     pArgs->target=target;
     return;
 }
-
+U_CDECL_END
 /* SCSU-from-Unicode conversion functions ----------------------------------- */
 
 /*
@@ -987,7 +989,7 @@
         return -1;
     }
 }
-
+U_CDECL_BEGIN
 /*
  * Idea for compression:
  *  - save SCSUData and other state before really starting work
@@ -1005,7 +1007,7 @@
  *  - Only replace the result after an SDX or SCU?
  */
 
-static void
+static void U_CALLCONV
 _SCSUFromUnicodeWithOffsets(UConverterFromUnicodeArgs *pArgs,
                             UErrorCode *pErrorCode) {
     UConverter *cnv;
@@ -1395,12 +1397,16 @@
                 /* each branch falls through to the next one */
             case 4:
                 *target++=(uint8_t)(c>>24);
-            case 3: /*fall through*/
+                U_FALLTHROUGH;
+            case 3:
                 *target++=(uint8_t)(c>>16);
-            case 2: /*fall through*/
+                U_FALLTHROUGH;
+            case 2:
                 *target++=(uint8_t)(c>>8);
-            case 1: /*fall through*/
+                U_FALLTHROUGH;
+            case 1:
                 *target++=(uint8_t)c;
+                U_FALLTHROUGH;
             default:
                 /* will never occur */
                 break;
@@ -1411,15 +1417,19 @@
             case 4:
                 *target++=(uint8_t)(c>>24);
                 *offsets++=sourceIndex;
-            case 3: /*fall through*/
+                U_FALLTHROUGH;
+            case 3:
                 *target++=(uint8_t)(c>>16);
                 *offsets++=sourceIndex;
-            case 2: /*fall through*/
+                U_FALLTHROUGH;
+            case 2:
                 *target++=(uint8_t)(c>>8);
                 *offsets++=sourceIndex;
-            case 1: /*fall through*/
+                U_FALLTHROUGH;
+            case 1:
                 *target++=(uint8_t)c;
                 *offsets++=sourceIndex;
+                U_FALLTHROUGH;
             default:
                 /* will never occur */
                 break;
@@ -1448,12 +1458,16 @@
             /* each branch falls through to the next one */
         case 4:
             *p++=(uint8_t)(c>>24);
-        case 3: /*fall through*/
+            U_FALLTHROUGH;
+        case 3:
             *p++=(uint8_t)(c>>16);
-        case 2: /*fall through*/
+            U_FALLTHROUGH;
+        case 2:
             *p++=(uint8_t)(c>>8);
-        case 1: /*fall through*/
+            U_FALLTHROUGH;
+        case 1:
             *p=(uint8_t)c;
+            U_FALLTHROUGH;
         default:
             /* will never occur */
             break;
@@ -1469,16 +1483,19 @@
             if(offsets!=NULL) {
                 *offsets++=sourceIndex;
             }
-        case 2: /*fall through*/
+            U_FALLTHROUGH;
+        case 2:
             *target++=(uint8_t)(c>>8);
             if(offsets!=NULL) {
                 *offsets++=sourceIndex;
             }
-        case 1: /*fall through*/
+            U_FALLTHROUGH;
+        case 1:
             *target++=(uint8_t)c;
             if(offsets!=NULL) {
                 *offsets++=sourceIndex;
             }
+            U_FALLTHROUGH;
         default:
             break;
         }
@@ -1498,7 +1515,7 @@
  * re-copy the original function and remove the variables
  * offsets, sourceIndex, and nextSourceIndex.
  */
-static void
+static void U_CALLCONV
 _SCSUFromUnicode(UConverterFromUnicodeArgs *pArgs,
                  UErrorCode *pErrorCode) {
     UConverter *cnv;
@@ -1853,12 +1870,16 @@
             /* each branch falls through to the next one */
         case 4:
             *target++=(uint8_t)(c>>24);
-        case 3: /*fall through*/
+            U_FALLTHROUGH;
+        case 3:
             *target++=(uint8_t)(c>>16);
-        case 2: /*fall through*/
+            U_FALLTHROUGH;
+        case 2:
             *target++=(uint8_t)(c>>8);
-        case 1: /*fall through*/
+            U_FALLTHROUGH;
+        case 1:
             *target++=(uint8_t)c;
+            U_FALLTHROUGH;
         default:
             /* will never occur */
             break;
@@ -1885,12 +1906,16 @@
             /* each branch falls through to the next one */
         case 4:
             *p++=(uint8_t)(c>>24);
-        case 3: /*fall through*/
+            U_FALLTHROUGH;
+        case 3:
             *p++=(uint8_t)(c>>16);
-        case 2: /*fall through*/
+            U_FALLTHROUGH;
+        case 2:
             *p++=(uint8_t)(c>>8);
-        case 1: /*fall through*/
+            U_FALLTHROUGH;
+        case 1:
             *p=(uint8_t)c;
+            U_FALLTHROUGH;
         default:
             /* will never occur */
             break;
@@ -1903,10 +1928,13 @@
             /* each branch falls through to the next one */
         case 3:
             *target++=(uint8_t)(c>>16);
-        case 2: /*fall through*/
+            U_FALLTHROUGH;
+        case 2:
             *target++=(uint8_t)(c>>8);
-        case 1: /*fall through*/
+            U_FALLTHROUGH;
+        case 1:
             *target++=(uint8_t)c;
+            U_FALLTHROUGH;
         default:
             break;
         }
@@ -1921,7 +1949,7 @@
 
 /* miscellaneous ------------------------------------------------------------ */
 
-static const char *
+static const char *  U_CALLCONV
 _SCSUGetName(const UConverter *cnv) {
     SCSUData *scsu=(SCSUData *)cnv->extraInfo;
 
@@ -1940,7 +1968,7 @@
     SCSUData mydata;
 };
 
-static UConverter * 
+static UConverter *  U_CALLCONV
 _SCSUSafeClone(const UConverter *cnv, 
                void *stackBuffer, 
                int32_t *pBufferSize, 
@@ -1967,7 +1995,7 @@
 
     return &localClone->cnv;
 }
-
+U_CDECL_END
 
 static const UConverterImpl _SCSUImpl={
     UCNV_SCSU,
@@ -1989,7 +2017,9 @@
     _SCSUGetName,
     NULL,
     _SCSUSafeClone,
-    ucnv_getCompleteUnicodeSet
+    ucnv_getCompleteUnicodeSet,
+    NULL,
+    NULL
 };
 
 static const UConverterStaticData _SCSUStaticData={
diff --git a/src/third_party/icu/source/common/ucnvsel.cpp b/src/third_party/icu/source/common/ucnvsel.cpp
index 3d1a1fa..411db50 100644
--- a/src/third_party/icu/source/common/ucnvsel.cpp
+++ b/src/third_party/icu/source/common/ucnvsel.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -28,11 +30,12 @@
 
 #if !UCONFIG_NO_CONVERSION
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
 #include "starboard/client_porting/poem/string_poem.h"
-#if !defined(STARBOARD)
+#else
 #include <string.h>
-#endif
+#endif  // defined(STARBOARD)
 
 #include "unicode/uchar.h"
 #include "unicode/uniset.h"
@@ -43,6 +46,7 @@
 #include "propsvec.h"
 #include "uassert.h"
 #include "ucmndata.h"
+#include "udataswp.h"
 #include "uenumimp.h"
 #include "cmemory.h"
 #include "cstring.h"
@@ -74,7 +78,7 @@
   // set errorValue to all-ones
   for (int32_t col = 0; col < columns; col++) {
     upvec_setValue(upvec, UPVEC_ERROR_VALUE_CP, UPVEC_ERROR_VALUE_CP,
-                   col, ~0, ~0, status);
+                   col, static_cast<uint32_t>(~0), static_cast<uint32_t>(~0), status);
   }
 
   for (int32_t i = 0; i < result->encodingsCount; ++i) {
@@ -111,7 +115,7 @@
         // this will be reached for the converters that fill the set with
         // strings. Those should be ignored by our system
       } else {
-        upvec_setValue(upvec, start_char, end_char, column, ~0, mask,
+        upvec_setValue(upvec, start_char, end_char, column, static_cast<uint32_t>(~0), mask,
                        status);
       }
     }
@@ -132,7 +136,7 @@
       uset_getItem(excludedCodePoints, j, &start_char, &end_char, NULL, 0,
                    status);
       for (int32_t col = 0; col < columns; col++) {
-        upvec_setValue(upvec, start_char, end_char, col, ~0, ~0,
+        upvec_setValue(upvec, start_char, end_char, col, static_cast<uint32_t>(~0), static_cast<uint32_t>(~0),
                       status);
       }
     }
@@ -686,42 +690,42 @@
       ent &= ent - 1; // clear the least significant bit set
     }
   }
-  return totalOnes;
+  return static_cast<int16_t>(totalOnes);
 }
 
 
 /* internal function! */
 static UEnumeration *selectForMask(const UConverterSelector* sel,
-                                   uint32_t *mask, UErrorCode *status) {
+                                   uint32_t *theMask, UErrorCode *status) {
+  LocalMemory<uint32_t> mask(theMask);
   // this is the context we will use. Store a table of indices to which
   // encodings are legit.
-  struct Enumerator* result = (Enumerator*)uprv_malloc(sizeof(Enumerator));
-  if (result == NULL) {
-    uprv_free(mask);
+  LocalMemory<Enumerator> result(static_cast<Enumerator *>(uprv_malloc(sizeof(Enumerator))));
+  if (result.isNull()) {
     *status = U_MEMORY_ALLOCATION_ERROR;
-    return NULL;
+    return nullptr;
   }
-  result->index = NULL;  // this will be allocated later!
+  result->index = nullptr;  // this will be allocated later!
   result->length = result->cur = 0;
   result->sel = sel;
 
-  UEnumeration *en = (UEnumeration *)uprv_malloc(sizeof(UEnumeration));
-  if (en == NULL) {
+  LocalMemory<UEnumeration> en(static_cast<UEnumeration *>(uprv_malloc(sizeof(UEnumeration))));
+  if (en.isNull()) {
     // TODO(markus): Combine Enumerator and UEnumeration into one struct.
-    uprv_free(mask);
-    uprv_free(result);
     *status = U_MEMORY_ALLOCATION_ERROR;
-    return NULL;
+    return nullptr;
   }
-  memcpy(en, &defaultEncodings, sizeof(UEnumeration));
-  en->context = result;
-
+  memcpy(en.getAlias(), &defaultEncodings, sizeof(UEnumeration));
+  
   int32_t columns = (sel->encodingsCount+31)/32;
-  int16_t numOnes = countOnes(mask, columns);
+  int16_t numOnes = countOnes(mask.getAlias(), columns);
   // now, we know the exact space we need for index
   if (numOnes > 0) {
-    result->index = (int16_t*) uprv_malloc(numOnes * sizeof(int16_t));
-
+    result->index = static_cast<int16_t*>(uprv_malloc(numOnes * sizeof(int16_t)));
+    if (result->index == nullptr) {
+      *status = U_MEMORY_ALLOCATION_ERROR;
+      return nullptr;
+    }
     int32_t i, j;
     int16_t k = 0;
     for (j = 0 ; j < columns; j++) {
@@ -735,8 +739,8 @@
     }
   } //otherwise, index will remain NULL (and will never be touched by
     //the enumerator code anyway)
-  uprv_free(mask);
-  return en;
+  en->context = result.orphan();
+  return en.orphan();
 }
 
 /* check a string against the selector - UTF16 version */
diff --git a/src/third_party/icu/source/common/ucol_data.h b/src/third_party/icu/source/common/ucol_data.h
index 0230646..83f54ab 100644
--- a/src/third_party/icu/source/common/ucol_data.h
+++ b/src/third_party/icu/source/common/ucol_data.h
@@ -1,10 +1,12 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *   Copyright (C) 2000-2011, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *******************************************************************************
 *   file name:  ucol_data.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
diff --git a/src/third_party/icu/source/common/ucol_swp.cpp b/src/third_party/icu/source/common/ucol_swp.cpp
index 13b0d2a..bbd8820 100644
--- a/src/third_party/icu/source/common/ucol_swp.cpp
+++ b/src/third_party/icu/source/common/ucol_swp.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  ucol_swp.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -16,7 +18,9 @@
 *   Swap collation binaries.
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/udata.h" /* UDataInfo */
 #include "utrie.h"
 #include "utrie2.h"
@@ -27,81 +31,6 @@
 
 /* swapping ----------------------------------------------------------------- */
 
-/*
- * This performs data swapping for a folded trie (see utrie.c for details).
- */
-
-U_CAPI int32_t U_EXPORT2
-utrie_swap(const UDataSwapper *ds,
-           const void *inData, int32_t length, void *outData,
-           UErrorCode *pErrorCode) {
-    const UTrieHeader *inTrie;
-    UTrieHeader trie;
-    int32_t size;
-    UBool dataIs32;
-
-    if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
-        return 0;
-    }
-    if(ds==NULL || inData==NULL || (length>=0 && outData==NULL)) {
-        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
-        return 0;
-    }
-
-    /* setup and swapping */
-    if(length>=0 && (uint32_t)length<sizeof(UTrieHeader)) {
-        *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
-        return 0;
-    }
-
-    inTrie=(const UTrieHeader *)inData;
-    trie.signature=ds->readUInt32(inTrie->signature);
-    trie.options=ds->readUInt32(inTrie->options);
-    trie.indexLength=udata_readInt32(ds, inTrie->indexLength);
-    trie.dataLength=udata_readInt32(ds, inTrie->dataLength);
-
-    if( trie.signature!=0x54726965 ||
-        (trie.options&UTRIE_OPTIONS_SHIFT_MASK)!=UTRIE_SHIFT ||
-        ((trie.options>>UTRIE_OPTIONS_INDEX_SHIFT)&UTRIE_OPTIONS_SHIFT_MASK)!=UTRIE_INDEX_SHIFT ||
-        trie.indexLength<UTRIE_BMP_INDEX_LENGTH ||
-        (trie.indexLength&(UTRIE_SURROGATE_BLOCK_COUNT-1))!=0 ||
-        trie.dataLength<UTRIE_DATA_BLOCK_LENGTH ||
-        (trie.dataLength&(UTRIE_DATA_GRANULARITY-1))!=0 ||
-        ((trie.options&UTRIE_OPTIONS_LATIN1_IS_LINEAR)!=0 && trie.dataLength<(UTRIE_DATA_BLOCK_LENGTH+0x100))
-    ) {
-        *pErrorCode=U_INVALID_FORMAT_ERROR; /* not a UTrie */
-        return 0;
-    }
-
-    dataIs32=(UBool)((trie.options&UTRIE_OPTIONS_DATA_IS_32_BIT)!=0);
-    size=sizeof(UTrieHeader)+trie.indexLength*2+trie.dataLength*(dataIs32?4:2);
-
-    if(length>=0) {
-        UTrieHeader *outTrie;
-
-        if(length<size) {
-            *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
-            return 0;
-        }
-
-        outTrie=(UTrieHeader *)outData;
-
-        /* swap the header */
-        ds->swapArray32(ds, inTrie, sizeof(UTrieHeader), outTrie, pErrorCode);
-
-        /* swap the index and the data */
-        if(dataIs32) {
-            ds->swapArray16(ds, inTrie+1, trie.indexLength*2, outTrie+1, pErrorCode);
-            ds->swapArray32(ds, (const uint16_t *)(inTrie+1)+trie.indexLength, trie.dataLength*4,
-                                     (uint16_t *)(outTrie+1)+trie.indexLength, pErrorCode);
-        } else {
-            ds->swapArray16(ds, inTrie+1, (trie.indexLength+trie.dataLength)*2, outTrie+1, pErrorCode);
-        }
-    }
-
-    return size;
-}
-
 #if !UCONFIG_NO_COLLATION
 
 U_CAPI UBool U_EXPORT2
diff --git a/src/third_party/icu/source/common/ucol_swp.h b/src/third_party/icu/source/common/ucol_swp.h
index 855b404..0c2990a 100644
--- a/src/third_party/icu/source/common/ucol_swp.h
+++ b/src/third_party/icu/source/common/ucol_swp.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  ucol_swp.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -29,7 +31,7 @@
  * Does the data look like a collation binary?
  * @internal
  */
-U_INTERNAL UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 ucol_looksLikeCollationBinary(const UDataSwapper *ds,
                               const void *inData, int32_t length);
 
diff --git a/src/third_party/icu/source/common/ucptrie.cpp b/src/third_party/icu/source/common/ucptrie.cpp
new file mode 100644
index 0000000..0004160
--- /dev/null
+++ b/src/third_party/icu/source/common/ucptrie.cpp
@@ -0,0 +1,601 @@
+// © 2017 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+// ucptrie.cpp (modified from utrie2.cpp)
+// created: 2017dec29 Markus W. Scherer
+
+// #define UCPTRIE_DEBUG
+#ifdef UCPTRIE_DEBUG
+#   include <stdio.h>
+#endif
+
+#include "unicode/utypes.h"
+#include "unicode/ucptrie.h"
+#include "unicode/utf.h"
+#include "unicode/utf8.h"
+#include "unicode/utf16.h"
+#include "cmemory.h"
+#include "uassert.h"
+#include "ucptrie_impl.h"
+
+U_CAPI UCPTrie * U_EXPORT2
+ucptrie_openFromBinary(UCPTrieType type, UCPTrieValueWidth valueWidth,
+                       const void *data, int32_t length, int32_t *pActualLength,
+                       UErrorCode *pErrorCode) {
+    if (U_FAILURE(*pErrorCode)) {
+        return nullptr;
+    }
+
+    if (length <= 0 || (U_POINTER_MASK_LSB(data, 3) != 0) ||
+            type < UCPTRIE_TYPE_ANY || UCPTRIE_TYPE_SMALL < type ||
+            valueWidth < UCPTRIE_VALUE_BITS_ANY || UCPTRIE_VALUE_BITS_8 < valueWidth) {
+        *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR;
+        return nullptr;
+    }
+
+    // Enough data for a trie header?
+    if (length < (int32_t)sizeof(UCPTrieHeader)) {
+        *pErrorCode = U_INVALID_FORMAT_ERROR;
+        return nullptr;
+    }
+
+    // Check the signature.
+    const UCPTrieHeader *header = (const UCPTrieHeader *)data;
+    if (header->signature != UCPTRIE_SIG) {
+        *pErrorCode = U_INVALID_FORMAT_ERROR;
+        return nullptr;
+    }
+
+    int32_t options = header->options;
+    int32_t typeInt = (options >> 6) & 3;
+    int32_t valueWidthInt = options & UCPTRIE_OPTIONS_VALUE_BITS_MASK;
+    if (typeInt > UCPTRIE_TYPE_SMALL || valueWidthInt > UCPTRIE_VALUE_BITS_8 ||
+            (options & UCPTRIE_OPTIONS_RESERVED_MASK) != 0) {
+        *pErrorCode = U_INVALID_FORMAT_ERROR;
+        return nullptr;
+    }
+    UCPTrieType actualType = (UCPTrieType)typeInt;
+    UCPTrieValueWidth actualValueWidth = (UCPTrieValueWidth)valueWidthInt;
+    if (type < 0) {
+        type = actualType;
+    }
+    if (valueWidth < 0) {
+        valueWidth = actualValueWidth;
+    }
+    if (type != actualType || valueWidth != actualValueWidth) {
+        *pErrorCode = U_INVALID_FORMAT_ERROR;
+        return nullptr;
+    }
+
+    // Get the length values and offsets.
+    UCPTrie tempTrie;
+    uprv_memset(&tempTrie, 0, sizeof(tempTrie));
+    tempTrie.indexLength = header->indexLength;
+    tempTrie.dataLength =
+        ((options & UCPTRIE_OPTIONS_DATA_LENGTH_MASK) << 4) | header->dataLength;
+    tempTrie.index3NullOffset = header->index3NullOffset;
+    tempTrie.dataNullOffset =
+        ((options & UCPTRIE_OPTIONS_DATA_NULL_OFFSET_MASK) << 8) | header->dataNullOffset;
+
+    tempTrie.highStart = header->shiftedHighStart << UCPTRIE_SHIFT_2;
+    tempTrie.shifted12HighStart = (tempTrie.highStart + 0xfff) >> 12;
+    tempTrie.type = type;
+    tempTrie.valueWidth = valueWidth;
+
+    // Calculate the actual length.
+    int32_t actualLength = (int32_t)sizeof(UCPTrieHeader) + tempTrie.indexLength * 2;
+    if (valueWidth == UCPTRIE_VALUE_BITS_16) {
+        actualLength += tempTrie.dataLength * 2;
+    } else if (valueWidth == UCPTRIE_VALUE_BITS_32) {
+        actualLength += tempTrie.dataLength * 4;
+    } else {
+        actualLength += tempTrie.dataLength;
+    }
+    if (length < actualLength) {
+        *pErrorCode = U_INVALID_FORMAT_ERROR;  // Not enough bytes.
+        return nullptr;
+    }
+
+    // Allocate the trie.
+    UCPTrie *trie = (UCPTrie *)uprv_malloc(sizeof(UCPTrie));
+    if (trie == nullptr) {
+        *pErrorCode = U_MEMORY_ALLOCATION_ERROR;
+        return nullptr;
+    }
+    uprv_memcpy(trie, &tempTrie, sizeof(tempTrie));
+#ifdef UCPTRIE_DEBUG
+    trie->name = "fromSerialized";
+#endif
+
+    // Set the pointers to its index and data arrays.
+    const uint16_t *p16 = (const uint16_t *)(header + 1);
+    trie->index = p16;
+    p16 += trie->indexLength;
+
+    // Get the data.
+    int32_t nullValueOffset = trie->dataNullOffset;
+    if (nullValueOffset >= trie->dataLength) {
+        nullValueOffset = trie->dataLength - UCPTRIE_HIGH_VALUE_NEG_DATA_OFFSET;
+    }
+    switch (valueWidth) {
+    case UCPTRIE_VALUE_BITS_16:
+        trie->data.ptr16 = p16;
+        trie->nullValue = trie->data.ptr16[nullValueOffset];
+        break;
+    case UCPTRIE_VALUE_BITS_32:
+        trie->data.ptr32 = (const uint32_t *)p16;
+        trie->nullValue = trie->data.ptr32[nullValueOffset];
+        break;
+    case UCPTRIE_VALUE_BITS_8:
+        trie->data.ptr8 = (const uint8_t *)p16;
+        trie->nullValue = trie->data.ptr8[nullValueOffset];
+        break;
+    default:
+        // Unreachable because valueWidth was checked above.
+        *pErrorCode = U_INVALID_FORMAT_ERROR;
+        return nullptr;
+    }
+
+    if (pActualLength != nullptr) {
+        *pActualLength = actualLength;
+    }
+    return trie;
+}
+
+U_CAPI void U_EXPORT2
+ucptrie_close(UCPTrie *trie) {
+    uprv_free(trie);
+}
+
+U_CAPI UCPTrieType U_EXPORT2
+ucptrie_getType(const UCPTrie *trie) {
+    return (UCPTrieType)trie->type;
+}
+
+U_CAPI UCPTrieValueWidth U_EXPORT2
+ucptrie_getValueWidth(const UCPTrie *trie) {
+    return (UCPTrieValueWidth)trie->valueWidth;
+}
+
+U_CAPI int32_t U_EXPORT2
+ucptrie_internalSmallIndex(const UCPTrie *trie, UChar32 c) {
+    int32_t i1 = c >> UCPTRIE_SHIFT_1;
+    if (trie->type == UCPTRIE_TYPE_FAST) {
+        U_ASSERT(0xffff < c && c < trie->highStart);
+        i1 += UCPTRIE_BMP_INDEX_LENGTH - UCPTRIE_OMITTED_BMP_INDEX_1_LENGTH;
+    } else {
+        U_ASSERT((uint32_t)c < (uint32_t)trie->highStart && trie->highStart > UCPTRIE_SMALL_LIMIT);
+        i1 += UCPTRIE_SMALL_INDEX_LENGTH;
+    }
+    int32_t i3Block = trie->index[
+        (int32_t)trie->index[i1] + ((c >> UCPTRIE_SHIFT_2) & UCPTRIE_INDEX_2_MASK)];
+    int32_t i3 = (c >> UCPTRIE_SHIFT_3) & UCPTRIE_INDEX_3_MASK;
+    int32_t dataBlock;
+    if ((i3Block & 0x8000) == 0) {
+        // 16-bit indexes
+        dataBlock = trie->index[i3Block + i3];
+    } else {
+        // 18-bit indexes stored in groups of 9 entries per 8 indexes.
+        i3Block = (i3Block & 0x7fff) + (i3 & ~7) + (i3 >> 3);
+        i3 &= 7;
+        dataBlock = ((int32_t)trie->index[i3Block++] << (2 + (2 * i3))) & 0x30000;
+        dataBlock |= trie->index[i3Block + i3];
+    }
+    return dataBlock + (c & UCPTRIE_SMALL_DATA_MASK);
+}
+
+U_CAPI int32_t U_EXPORT2
+ucptrie_internalSmallU8Index(const UCPTrie *trie, int32_t lt1, uint8_t t2, uint8_t t3) {
+    UChar32 c = (lt1 << 12) | (t2 << 6) | t3;
+    if (c >= trie->highStart) {
+        // Possible because the UTF-8 macro compares with shifted12HighStart which may be higher.
+        return trie->dataLength - UCPTRIE_HIGH_VALUE_NEG_DATA_OFFSET;
+    }
+    return ucptrie_internalSmallIndex(trie, c);
+}
+
+U_CAPI int32_t U_EXPORT2
+ucptrie_internalU8PrevIndex(const UCPTrie *trie, UChar32 c,
+                            const uint8_t *start, const uint8_t *src) {
+    int32_t i, length;
+    // Support 64-bit pointers by avoiding cast of arbitrary difference.
+    if ((src - start) <= 7) {
+        i = length = (int32_t)(src - start);
+    } else {
+        i = length = 7;
+        start = src - 7;
+    }
+    c = utf8_prevCharSafeBody(start, 0, &i, c, -1);
+    i = length - i;  // Number of bytes read backward from src.
+    int32_t idx = _UCPTRIE_CP_INDEX(trie, 0xffff, c);
+    return (idx << 3) | i;
+}
+
+namespace {
+
+inline uint32_t getValue(UCPTrieData data, UCPTrieValueWidth valueWidth, int32_t dataIndex) {
+    switch (valueWidth) {
+    case UCPTRIE_VALUE_BITS_16:
+        return data.ptr16[dataIndex];
+    case UCPTRIE_VALUE_BITS_32:
+        return data.ptr32[dataIndex];
+    case UCPTRIE_VALUE_BITS_8:
+        return data.ptr8[dataIndex];
+    default:
+        // Unreachable if the trie is properly initialized.
+        return 0xffffffff;
+    }
+}
+
+}  // namespace
+
+U_CAPI uint32_t U_EXPORT2
+ucptrie_get(const UCPTrie *trie, UChar32 c) {
+    int32_t dataIndex;
+    if ((uint32_t)c <= 0x7f) {
+        // linear ASCII
+        dataIndex = c;
+    } else {
+        UChar32 fastMax = trie->type == UCPTRIE_TYPE_FAST ? 0xffff : UCPTRIE_SMALL_MAX;
+        dataIndex = _UCPTRIE_CP_INDEX(trie, fastMax, c);
+    }
+    return getValue(trie->data, (UCPTrieValueWidth)trie->valueWidth, dataIndex);
+}
+
+namespace {
+
+constexpr int32_t MAX_UNICODE = 0x10ffff;
+
+inline uint32_t maybeFilterValue(uint32_t value, uint32_t trieNullValue, uint32_t nullValue,
+                                 UCPMapValueFilter *filter, const void *context) {
+    if (value == trieNullValue) {
+        value = nullValue;
+    } else if (filter != nullptr) {
+        value = filter(context, value);
+    }
+    return value;
+}
+
+UChar32 getRange(const void *t, UChar32 start,
+                 UCPMapValueFilter *filter, const void *context, uint32_t *pValue) {
+    if ((uint32_t)start > MAX_UNICODE) {
+        return U_SENTINEL;
+    }
+    const UCPTrie *trie = reinterpret_cast<const UCPTrie *>(t);
+    UCPTrieValueWidth valueWidth = (UCPTrieValueWidth)trie->valueWidth;
+    if (start >= trie->highStart) {
+        if (pValue != nullptr) {
+            int32_t di = trie->dataLength - UCPTRIE_HIGH_VALUE_NEG_DATA_OFFSET;
+            uint32_t value = getValue(trie->data, valueWidth, di);
+            if (filter != nullptr) { value = filter(context, value); }
+            *pValue = value;
+        }
+        return MAX_UNICODE;
+    }
+
+    uint32_t nullValue = trie->nullValue;
+    if (filter != nullptr) { nullValue = filter(context, nullValue); }
+    const uint16_t *index = trie->index;
+
+    int32_t prevI3Block = -1;
+    int32_t prevBlock = -1;
+    UChar32 c = start;
+    uint32_t trieValue, value = nullValue;
+    bool haveValue = false;
+    do {
+        int32_t i3Block;
+        int32_t i3;
+        int32_t i3BlockLength;
+        int32_t dataBlockLength;
+        if (c <= 0xffff && (trie->type == UCPTRIE_TYPE_FAST || c <= UCPTRIE_SMALL_MAX)) {
+            i3Block = 0;
+            i3 = c >> UCPTRIE_FAST_SHIFT;
+            i3BlockLength = trie->type == UCPTRIE_TYPE_FAST ?
+                UCPTRIE_BMP_INDEX_LENGTH : UCPTRIE_SMALL_INDEX_LENGTH;
+            dataBlockLength = UCPTRIE_FAST_DATA_BLOCK_LENGTH;
+        } else {
+            // Use the multi-stage index.
+            int32_t i1 = c >> UCPTRIE_SHIFT_1;
+            if (trie->type == UCPTRIE_TYPE_FAST) {
+                U_ASSERT(0xffff < c && c < trie->highStart);
+                i1 += UCPTRIE_BMP_INDEX_LENGTH - UCPTRIE_OMITTED_BMP_INDEX_1_LENGTH;
+            } else {
+                U_ASSERT(c < trie->highStart && trie->highStart > UCPTRIE_SMALL_LIMIT);
+                i1 += UCPTRIE_SMALL_INDEX_LENGTH;
+            }
+            i3Block = trie->index[
+                (int32_t)trie->index[i1] + ((c >> UCPTRIE_SHIFT_2) & UCPTRIE_INDEX_2_MASK)];
+            if (i3Block == prevI3Block && (c - start) >= UCPTRIE_CP_PER_INDEX_2_ENTRY) {
+                // The index-3 block is the same as the previous one, and filled with value.
+                U_ASSERT((c & (UCPTRIE_CP_PER_INDEX_2_ENTRY - 1)) == 0);
+                c += UCPTRIE_CP_PER_INDEX_2_ENTRY;
+                continue;
+            }
+            prevI3Block = i3Block;
+            if (i3Block == trie->index3NullOffset) {
+                // This is the index-3 null block.
+                if (haveValue) {
+                    if (nullValue != value) {
+                        return c - 1;
+                    }
+                } else {
+                    trieValue = trie->nullValue;
+                    value = nullValue;
+                    if (pValue != nullptr) { *pValue = nullValue; }
+                    haveValue = true;
+                }
+                prevBlock = trie->dataNullOffset;
+                c = (c + UCPTRIE_CP_PER_INDEX_2_ENTRY) & ~(UCPTRIE_CP_PER_INDEX_2_ENTRY - 1);
+                continue;
+            }
+            i3 = (c >> UCPTRIE_SHIFT_3) & UCPTRIE_INDEX_3_MASK;
+            i3BlockLength = UCPTRIE_INDEX_3_BLOCK_LENGTH;
+            dataBlockLength = UCPTRIE_SMALL_DATA_BLOCK_LENGTH;
+        }
+        // Enumerate data blocks for one index-3 block.
+        do {
+            int32_t block;
+            if ((i3Block & 0x8000) == 0) {
+                block = index[i3Block + i3];
+            } else {
+                // 18-bit indexes stored in groups of 9 entries per 8 indexes.
+                int32_t group = (i3Block & 0x7fff) + (i3 & ~7) + (i3 >> 3);
+                int32_t gi = i3 & 7;
+                block = ((int32_t)index[group++] << (2 + (2 * gi))) & 0x30000;
+                block |= index[group + gi];
+            }
+            if (block == prevBlock && (c - start) >= dataBlockLength) {
+                // The block is the same as the previous one, and filled with value.
+                U_ASSERT((c & (dataBlockLength - 1)) == 0);
+                c += dataBlockLength;
+            } else {
+                int32_t dataMask = dataBlockLength - 1;
+                prevBlock = block;
+                if (block == trie->dataNullOffset) {
+                    // This is the data null block.
+                    if (haveValue) {
+                        if (nullValue != value) {
+                            return c - 1;
+                        }
+                    } else {
+                        trieValue = trie->nullValue;
+                        value = nullValue;
+                        if (pValue != nullptr) { *pValue = nullValue; }
+                        haveValue = true;
+                    }
+                    c = (c + dataBlockLength) & ~dataMask;
+                } else {
+                    int32_t di = block + (c & dataMask);
+                    uint32_t trieValue2 = getValue(trie->data, valueWidth, di);
+                    if (haveValue) {
+                        if (trieValue2 != trieValue) {
+                            if (filter == nullptr ||
+                                    maybeFilterValue(trieValue2, trie->nullValue, nullValue,
+                                                     filter, context) != value) {
+                                return c - 1;
+                            }
+                            trieValue = trieValue2;  // may or may not help
+                        }
+                    } else {
+                        trieValue = trieValue2;
+                        value = maybeFilterValue(trieValue2, trie->nullValue, nullValue,
+                                                 filter, context);
+                        if (pValue != nullptr) { *pValue = value; }
+                        haveValue = true;
+                    }
+                    while ((++c & dataMask) != 0) {
+                        trieValue2 = getValue(trie->data, valueWidth, ++di);
+                        if (trieValue2 != trieValue) {
+                            if (filter == nullptr ||
+                                    maybeFilterValue(trieValue2, trie->nullValue, nullValue,
+                                                     filter, context) != value) {
+                                return c - 1;
+                            }
+                            trieValue = trieValue2;  // may or may not help
+                        }
+                    }
+                }
+            }
+        } while (++i3 < i3BlockLength);
+    } while (c < trie->highStart);
+    U_ASSERT(haveValue);
+    int32_t di = trie->dataLength - UCPTRIE_HIGH_VALUE_NEG_DATA_OFFSET;
+    uint32_t highValue = getValue(trie->data, valueWidth, di);
+    if (maybeFilterValue(highValue, trie->nullValue, nullValue,
+                         filter, context) != value) {
+        return c - 1;
+    } else {
+        return MAX_UNICODE;
+    }
+}
+
+}  // namespace
+
+U_CFUNC UChar32
+ucptrie_internalGetRange(UCPTrieGetRange *getRange,
+                         const void *trie, UChar32 start,
+                         UCPMapRangeOption option, uint32_t surrogateValue,
+                         UCPMapValueFilter *filter, const void *context, uint32_t *pValue) {
+    if (option == UCPMAP_RANGE_NORMAL) {
+        return getRange(trie, start, filter, context, pValue);
+    }
+    uint32_t value;
+    if (pValue == nullptr) {
+        // We need to examine the range value even if the caller does not want it.
+        pValue = &value;
+    }
+    UChar32 surrEnd = option == UCPMAP_RANGE_FIXED_ALL_SURROGATES ? 0xdfff : 0xdbff;
+    UChar32 end = getRange(trie, start, filter, context, pValue);
+    if (end < 0xd7ff || start > surrEnd) {
+        return end;
+    }
+    // The range overlaps with surrogates, or ends just before the first one.
+    if (*pValue == surrogateValue) {
+        if (end >= surrEnd) {
+            // Surrogates followed by a non-surrogateValue range,
+            // or surrogates are part of a larger surrogateValue range.
+            return end;
+        }
+    } else {
+        if (start <= 0xd7ff) {
+            return 0xd7ff;  // Non-surrogateValue range ends before surrogateValue surrogates.
+        }
+        // Start is a surrogate with a non-surrogateValue code *unit* value.
+        // Return a surrogateValue code *point* range.
+        *pValue = surrogateValue;
+        if (end > surrEnd) {
+            return surrEnd;  // Surrogate range ends before non-surrogateValue rest of range.
+        }
+    }
+    // See if the surrogateValue surrogate range can be merged with
+    // an immediately following range.
+    uint32_t value2;
+    UChar32 end2 = getRange(trie, surrEnd + 1, filter, context, &value2);
+    if (value2 == surrogateValue) {
+        return end2;
+    }
+    return surrEnd;
+}
+
+U_CAPI UChar32 U_EXPORT2
+ucptrie_getRange(const UCPTrie *trie, UChar32 start,
+                 UCPMapRangeOption option, uint32_t surrogateValue,
+                 UCPMapValueFilter *filter, const void *context, uint32_t *pValue) {
+    return ucptrie_internalGetRange(getRange, trie, start,
+                                    option, surrogateValue,
+                                    filter, context, pValue);
+}
+
+U_CAPI int32_t U_EXPORT2
+ucptrie_toBinary(const UCPTrie *trie,
+                 void *data, int32_t capacity,
+                 UErrorCode *pErrorCode) {
+    if (U_FAILURE(*pErrorCode)) {
+        return 0;
+    }
+
+    UCPTrieType type = (UCPTrieType)trie->type;
+    UCPTrieValueWidth valueWidth = (UCPTrieValueWidth)trie->valueWidth;
+    if (type < UCPTRIE_TYPE_FAST || UCPTRIE_TYPE_SMALL < type ||
+            valueWidth < UCPTRIE_VALUE_BITS_16 || UCPTRIE_VALUE_BITS_8 < valueWidth ||
+            capacity < 0 ||
+            (capacity > 0 && (data == nullptr || (U_POINTER_MASK_LSB(data, 3) != 0)))) {
+        *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR;
+        return 0;
+    }
+
+    int32_t length = (int32_t)sizeof(UCPTrieHeader) + trie->indexLength * 2;
+    switch (valueWidth) {
+    case UCPTRIE_VALUE_BITS_16:
+        length += trie->dataLength * 2;
+        break;
+    case UCPTRIE_VALUE_BITS_32:
+        length += trie->dataLength * 4;
+        break;
+    case UCPTRIE_VALUE_BITS_8:
+        length += trie->dataLength;
+        break;
+    default:
+        // unreachable
+        break;
+    }
+    if (capacity < length) {
+        *pErrorCode = U_BUFFER_OVERFLOW_ERROR;
+        return length;
+    }
+
+    char *bytes = (char *)data;
+    UCPTrieHeader *header = (UCPTrieHeader *)bytes;
+    header->signature = UCPTRIE_SIG;  // "Tri3"
+    header->options = (uint16_t)(
+        ((trie->dataLength & 0xf0000) >> 4) |
+        ((trie->dataNullOffset & 0xf0000) >> 8) |
+        (trie->type << 6) |
+        valueWidth);
+    header->indexLength = (uint16_t)trie->indexLength;
+    header->dataLength = (uint16_t)trie->dataLength;
+    header->index3NullOffset = trie->index3NullOffset;
+    header->dataNullOffset = (uint16_t)trie->dataNullOffset;
+    header->shiftedHighStart = trie->highStart >> UCPTRIE_SHIFT_2;
+    bytes += sizeof(UCPTrieHeader);
+
+    uprv_memcpy(bytes, trie->index, trie->indexLength * 2);
+    bytes += trie->indexLength * 2;
+
+    switch (valueWidth) {
+    case UCPTRIE_VALUE_BITS_16:
+        uprv_memcpy(bytes, trie->data.ptr16, trie->dataLength * 2);
+        break;
+    case UCPTRIE_VALUE_BITS_32:
+        uprv_memcpy(bytes, trie->data.ptr32, trie->dataLength * 4);
+        break;
+    case UCPTRIE_VALUE_BITS_8:
+        uprv_memcpy(bytes, trie->data.ptr8, trie->dataLength);
+        break;
+    default:
+        // unreachable
+        break;
+    }
+    return length;
+}
+
+namespace {
+
+#ifdef UCPTRIE_DEBUG
+long countNull(const UCPTrie *trie) {
+    uint32_t nullValue=trie->nullValue;
+    int32_t length=trie->dataLength;
+    long count=0;
+    switch (trie->valueWidth) {
+    case UCPTRIE_VALUE_BITS_16:
+        for(int32_t i=0; i<length; ++i) {
+            if(trie->data.ptr16[i]==nullValue) { ++count; }
+        }
+        break;
+    case UCPTRIE_VALUE_BITS_32:
+        for(int32_t i=0; i<length; ++i) {
+            if(trie->data.ptr32[i]==nullValue) { ++count; }
+        }
+        break;
+    case UCPTRIE_VALUE_BITS_8:
+        for(int32_t i=0; i<length; ++i) {
+            if(trie->data.ptr8[i]==nullValue) { ++count; }
+        }
+        break;
+    default:
+        // unreachable
+        break;
+    }
+    return count;
+}
+
+U_CFUNC void
+ucptrie_printLengths(const UCPTrie *trie, const char *which) {
+    long indexLength=trie->indexLength;
+    long dataLength=(long)trie->dataLength;
+    long totalLength=(long)sizeof(UCPTrieHeader)+indexLength*2+
+            dataLength*(trie->valueWidth==UCPTRIE_VALUE_BITS_16 ? 2 :
+                        trie->valueWidth==UCPTRIE_VALUE_BITS_32 ? 4 : 1);
+    printf("**UCPTrieLengths(%s %s)** index:%6ld  data:%6ld  countNull:%6ld  serialized:%6ld\n",
+           which, trie->name, indexLength, dataLength, countNull(trie), totalLength);
+}
+#endif
+
+}  // namespace
+
+// UCPMap ----
+// Initially, this is the same as UCPTrie. This may well change.
+
+U_CAPI uint32_t U_EXPORT2
+ucpmap_get(const UCPMap *map, UChar32 c) {
+    return ucptrie_get(reinterpret_cast<const UCPTrie *>(map), c);
+}
+
+U_CAPI UChar32 U_EXPORT2
+ucpmap_getRange(const UCPMap *map, UChar32 start,
+                UCPMapRangeOption option, uint32_t surrogateValue,
+                UCPMapValueFilter *filter, const void *context, uint32_t *pValue) {
+    return ucptrie_getRange(reinterpret_cast<const UCPTrie *>(map), start,
+                            option, surrogateValue,
+                            filter, context, pValue);
+}
diff --git a/src/third_party/icu/source/common/ucptrie_impl.h b/src/third_party/icu/source/common/ucptrie_impl.h
new file mode 100644
index 0000000..1fe6a18
--- /dev/null
+++ b/src/third_party/icu/source/common/ucptrie_impl.h
@@ -0,0 +1,289 @@
+// © 2017 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+// ucptrie_impl.h (modified from utrie2_impl.h)
+// created: 2017dec29 Markus W. Scherer
+
+#ifndef __UCPTRIE_IMPL_H__
+#define __UCPTRIE_IMPL_H__
+
+#include "unicode/ucptrie.h"
+#ifdef UCPTRIE_DEBUG
+#include "unicode/umutablecptrie.h"
+#endif
+
+// UCPTrie signature values, in platform endianness and opposite endianness.
+// The UCPTrie signature ASCII byte values spell "Tri3".
+#define UCPTRIE_SIG     0x54726933
+#define UCPTRIE_OE_SIG  0x33697254
+
+/**
+ * Header data for the binary, memory-mappable representation of a UCPTrie/CodePointTrie.
+ * @internal
+ */
+struct UCPTrieHeader {
+    /** "Tri3" in big-endian US-ASCII (0x54726933) */
+    uint32_t signature;
+
+    /**
+     * Options bit field:
+     * Bits 15..12: Data length bits 19..16.
+     * Bits 11..8: Data null block offset bits 19..16.
+     * Bits 7..6: UCPTrieType
+     * Bits 5..3: Reserved (0).
+     * Bits 2..0: UCPTrieValueWidth
+     */
+    uint16_t options;
+
+    /** Total length of the index tables. */
+    uint16_t indexLength;
+
+    /** Data length bits 15..0. */
+    uint16_t dataLength;
+
+    /** Index-3 null block offset, 0x7fff or 0xffff if none. */
+    uint16_t index3NullOffset;
+
+    /** Data null block offset bits 15..0, 0xfffff if none. */
+    uint16_t dataNullOffset;
+
+    /**
+     * First code point of the single-value range ending with U+10ffff,
+     * rounded up and then shifted right by UCPTRIE_SHIFT_2.
+     */
+    uint16_t shiftedHighStart;
+};
+
+/**
+ * Constants for use with UCPTrieHeader.options.
+ * @internal
+ */
+enum {
+    UCPTRIE_OPTIONS_DATA_LENGTH_MASK = 0xf000,
+    UCPTRIE_OPTIONS_DATA_NULL_OFFSET_MASK = 0xf00,
+    UCPTRIE_OPTIONS_RESERVED_MASK = 0x38,
+    UCPTRIE_OPTIONS_VALUE_BITS_MASK = 7,
+    /**
+     * Value for index3NullOffset which indicates that there is no index-3 null block.
+     * Bit 15 is unused for this value because this bit is used if the index-3 contains
+     * 18-bit indexes.
+     */
+    UCPTRIE_NO_INDEX3_NULL_OFFSET = 0x7fff,
+    UCPTRIE_NO_DATA_NULL_OFFSET = 0xfffff
+};
+
+// Internal constants.
+enum {
+    /** The length of the BMP index table. 1024=0x400 */
+    UCPTRIE_BMP_INDEX_LENGTH = 0x10000 >> UCPTRIE_FAST_SHIFT,
+
+    UCPTRIE_SMALL_LIMIT = 0x1000,
+    UCPTRIE_SMALL_INDEX_LENGTH = UCPTRIE_SMALL_LIMIT >> UCPTRIE_FAST_SHIFT,
+
+    /** Shift size for getting the index-3 table offset. */
+    UCPTRIE_SHIFT_3 = 4,
+
+    /** Shift size for getting the index-2 table offset. */
+    UCPTRIE_SHIFT_2 = 5 + UCPTRIE_SHIFT_3,
+
+    /** Shift size for getting the index-1 table offset. */
+    UCPTRIE_SHIFT_1 = 5 + UCPTRIE_SHIFT_2,
+
+    /**
+     * Difference between two shift sizes,
+     * for getting an index-2 offset from an index-3 offset. 5=9-4
+     */
+    UCPTRIE_SHIFT_2_3 = UCPTRIE_SHIFT_2 - UCPTRIE_SHIFT_3,
+
+    /**
+     * Difference between two shift sizes,
+     * for getting an index-1 offset from an index-2 offset. 5=14-9
+     */
+    UCPTRIE_SHIFT_1_2 = UCPTRIE_SHIFT_1 - UCPTRIE_SHIFT_2,
+
+    /**
+     * Number of index-1 entries for the BMP. (4)
+     * This part of the index-1 table is omitted from the serialized form.
+     */
+    UCPTRIE_OMITTED_BMP_INDEX_1_LENGTH = 0x10000 >> UCPTRIE_SHIFT_1,
+
+    /** Number of entries in an index-2 block. 32=0x20 */
+    UCPTRIE_INDEX_2_BLOCK_LENGTH = 1 << UCPTRIE_SHIFT_1_2,
+
+    /** Mask for getting the lower bits for the in-index-2-block offset. */
+    UCPTRIE_INDEX_2_MASK = UCPTRIE_INDEX_2_BLOCK_LENGTH - 1,
+
+    /** Number of code points per index-2 table entry. 512=0x200 */
+    UCPTRIE_CP_PER_INDEX_2_ENTRY = 1 << UCPTRIE_SHIFT_2,
+
+    /** Number of entries in an index-3 block. 32=0x20 */
+    UCPTRIE_INDEX_3_BLOCK_LENGTH = 1 << UCPTRIE_SHIFT_2_3,
+
+    /** Mask for getting the lower bits for the in-index-3-block offset. */
+    UCPTRIE_INDEX_3_MASK = UCPTRIE_INDEX_3_BLOCK_LENGTH - 1,
+
+    /** Number of entries in a small data block. 16=0x10 */
+    UCPTRIE_SMALL_DATA_BLOCK_LENGTH = 1 << UCPTRIE_SHIFT_3,
+
+    /** Mask for getting the lower bits for the in-small-data-block offset. */
+    UCPTRIE_SMALL_DATA_MASK = UCPTRIE_SMALL_DATA_BLOCK_LENGTH - 1
+};
+
+typedef UChar32
+UCPTrieGetRange(const void *trie, UChar32 start,
+                UCPMapValueFilter *filter, const void *context, uint32_t *pValue);
+
+U_CFUNC UChar32
+ucptrie_internalGetRange(UCPTrieGetRange *getRange,
+                         const void *trie, UChar32 start,
+                         UCPMapRangeOption option, uint32_t surrogateValue,
+                         UCPMapValueFilter *filter, const void *context, uint32_t *pValue);
+
+#ifdef UCPTRIE_DEBUG
+U_CFUNC void
+ucptrie_printLengths(const UCPTrie *trie, const char *which);
+
+U_CFUNC void umutablecptrie_setName(UMutableCPTrie *builder, const char *name);
+#endif
+
+/*
+ * Format of the binary, memory-mappable representation of a UCPTrie/CodePointTrie.
+ * For overview information see http://site.icu-project.org/design/struct/utrie
+ *
+ * The binary trie data should be 32-bit-aligned.
+ * The overall layout is:
+ *
+ * UCPTrieHeader header; -- 16 bytes, see struct definition above
+ * uint16_t index[header.indexLength];
+ * uintXY_t data[header.dataLength];
+ *
+ * The trie data array is an array of uint16_t, uint32_t, or uint8_t,
+ * specified via the UCPTrieValueWidth when building the trie.
+ * The data array is 32-bit-aligned for uint32_t, otherwise 16-bit-aligned.
+ * The overall length of the trie data is a multiple of 4 bytes.
+ * (Padding is added at the end of the index array and/or near the end of the data array as needed.)
+ *
+ * The length of the data array (dataLength) is stored as an integer split across two fields
+ * of the header struct (high bits in header.options).
+ *
+ * The trie type can be "fast" or "small" which determines the index structure,
+ * specified via the UCPTrieType when building the trie.
+ *
+ * The type and valueWidth are stored in the header.options.
+ * There are reserved type and valueWidth values, and reserved header.options bits.
+ * They could be used in future format extensions.
+ * Code reading the trie structure must fail with an error when unknown values or options are set.
+ *
+ * Values for ASCII character (U+0000..U+007F) can always be found at the start of the data array.
+ *
+ * Values for code points below a type-specific fast-indexing limit are found via two-stage lookup.
+ * For a "fast" trie, the limit is the BMP/supplementary boundary at U+10000.
+ * For a "small" trie, the limit is UCPTRIE_SMALL_MAX+1=U+1000.
+ *
+ * All code points in the range highStart..U+10FFFF map to a single highValue
+ * which is stored at the second-to-last position of the data array.
+ * (See UCPTRIE_HIGH_VALUE_NEG_DATA_OFFSET.)
+ * The highStart value is header.shiftedHighStart<<UCPTRIE_SHIFT_2.
+ * (UCPTRIE_SHIFT_2=9)
+ *
+ * Values for code points fast_limit..highStart-1 are found via four-stage lookup.
+ * The data block size is smaller for this range than for the fast range.
+ * This together with more index stages with small blocks makes this range
+ * more easily compactable.
+ *
+ * There is also a trie error value stored at the last position of the data array.
+ * (See UCPTRIE_ERROR_VALUE_NEG_DATA_OFFSET.)
+ * It is intended to be returned for inputs that are not Unicode code points
+ * (outside U+0000..U+10FFFF), or in string processing for ill-formed input
+ * (unpaired surrogate in UTF-16, ill-formed UTF-8 subsequence).
+ *
+ * For a "fast" trie:
+ *
+ * The index array starts with the BMP index table for BMP code point lookup.
+ * Its length is 1024=0x400.
+ *
+ * The supplementary index-1 table follows the BMP index table.
+ * Variable length, for code points up to highStart-1.
+ * Maximum length 64=0x40=0x100000>>UCPTRIE_SHIFT_1.
+ * (For 0x100000 supplementary code points U+10000..U+10ffff.)
+ *
+ * After this index-1 table follow the variable-length index-3 and index-2 tables.
+ *
+ * The supplementary index tables are omitted completely
+ * if there is only BMP data (highStart<=U+10000).
+ *
+ * For a "small" trie:
+ *
+ * The index array starts with a fast-index table for lookup of code points U+0000..U+0FFF.
+ *
+ * The "supplementary" index tables are always stored.
+ * The index-1 table starts from U+0000, its maximum length is 68=0x44=0x110000>>UCPTRIE_SHIFT_1.
+ *
+ * For both trie types:
+ *
+ * The last index-2 block may be a partial block, storing indexes only for code points
+ * below highStart.
+ *
+ * Lookup for ASCII code point c:
+ *
+ * Linear access from the start of the data array.
+ *
+ * value = data[c];
+ *
+ * Lookup for fast-range code point c:
+ *
+ * Shift the code point right by UCPTRIE_FAST_SHIFT=6 bits,
+ * fetch the index array value at that offset,
+ * add the lower code point bits, index into the data array.
+ *
+ * value = data[index[c>>6] + (c&0x3f)];
+ *
+ * (This works for ASCII as well.)
+ *
+ * Lookup for small-range code point c below highStart:
+ *
+ * Split the code point into four bit fields using several sets of shifts & masks
+ * to read consecutive values from the index-1, index-2, index-3 and data tables.
+ *
+ * If all of the data block offsets in an index-3 block fit within 16 bits (up to 0xffff),
+ * then the data block offsets are stored directly as uint16_t.
+ *
+ * Otherwise (this is very unusual but possible), the index-2 entry for the index-3 block
+ * has bit 15 (0x8000) set, and each set of 8 index-3 entries is preceded by
+ * an additional uint16_t word. Data block offsets are 18 bits wide, with the top 2 bits stored
+ * in the additional word.
+ *
+ * See ucptrie_internalSmallIndex() for details.
+ *
+ * (In a "small" trie, this works for ASCII and below-fast_limit code points as well.)
+ *
+ * Compaction:
+ *
+ * Multiple code point ranges ("blocks") that are aligned on certain boundaries
+ * (determined by the shifting/bit fields of code points) and
+ * map to the same data values normally share a single subsequence of the data array.
+ * Data blocks can also overlap partially.
+ * (Depending on the builder code finding duplicate and overlapping blocks.)
+ *
+ * Iteration over same-value ranges:
+ *
+ * Range iteration (ucptrie_getRange()) walks the structure from a start code point
+ * until some code point is found that maps to a different value;
+ * the end of the returned range is just before that.
+ *
+ * The header.dataNullOffset (split across two header fields, high bits in header.options)
+ * is the offset of a widely shared data block filled with one single value.
+ * It helps quickly skip over large ranges of data with that value.
+ * The builder must ensure that if the start of any data block (fast or small)
+ * matches the dataNullOffset, then the whole block must be filled with the null value.
+ * Special care must be taken if there is no fast null data block
+ * but a small one, which is shorter, and it matches the *start* of some fast data block.
+ *
+ * Similarly, the header.index3NullOffset is the index-array offset of an index-3 block
+ * where all index entries point to the dataNullOffset.
+ * If there is no such data or index-3 block, then these offsets are set to
+ * values that cannot be reached (data offset out of range/reserved index offset),
+ * normally UCPTRIE_NO_DATA_NULL_OFFSET or UCPTRIE_NO_INDEX3_NULL_OFFSET respectively.
+ */
+
+#endif
diff --git a/src/third_party/icu/source/common/ucurr.cpp b/src/third_party/icu/source/common/ucurr.cpp
new file mode 100644
index 0000000..0e14cdd
--- /dev/null
+++ b/src/third_party/icu/source/common/ucurr.cpp
@@ -0,0 +1,2701 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+/*
+**********************************************************************
+* Copyright (c) 2002-2016, International Business Machines
+* Corporation and others.  All Rights Reserved.
+**********************************************************************
+*/
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_FORMATTING
+
+#include "unicode/ucurr.h"
+#include "unicode/locid.h"
+#include "unicode/ures.h"
+#include "unicode/ustring.h"
+#include "unicode/parsepos.h"
+#include "unicode/uniset.h"
+#include "unicode/usetiter.h"
+#include "unicode/utf16.h"
+#include "ustr_imp.h"
+#include "charstr.h"
+#include "cmemory.h"
+#include "cstring.h"
+#include "static_unicode_sets.h"
+#include "uassert.h"
+#include "umutex.h"
+#include "ucln_cmn.h"
+#include "uenumimp.h"
+#include "uhash.h"
+#include "hash.h"
+#include "uinvchar.h"
+#include "uresimp.h"
+#include "ulist.h"
+#include "uresimp.h"
+#include "ureslocs.h"
+#include "ulocimp.h"
+
+using namespace icu;
+
+//#define UCURR_DEBUG_EQUIV 1
+#ifdef UCURR_DEBUG_EQUIV
+#include "stdio.h"
+#endif
+//#define UCURR_DEBUG 1
+#ifdef UCURR_DEBUG
+#include "stdio.h"
+#endif
+
+typedef struct IsoCodeEntry {
+    const UChar *isoCode; /* const because it's a reference to a resource bundle string. */
+    UDate from;
+    UDate to;
+} IsoCodeEntry;
+
+//------------------------------------------------------------
+// Constants
+
+// Default currency meta data of last resort.  We try to use the
+// defaults encoded in the meta data resource bundle.  If there is a
+// configuration/build error and these are not available, we use these
+// hard-coded defaults (which should be identical).
+static const int32_t LAST_RESORT_DATA[] = { 2, 0, 2, 0 };
+
+// POW10[i] = 10^i, i=0..MAX_POW10
+static const int32_t POW10[] = { 1, 10, 100, 1000, 10000, 100000,
+                                 1000000, 10000000, 100000000, 1000000000 };
+
+static const int32_t MAX_POW10 = UPRV_LENGTHOF(POW10) - 1;
+
+#define ISO_CURRENCY_CODE_LENGTH 3
+
+//------------------------------------------------------------
+// Resource tags
+//
+
+static const char CURRENCY_DATA[] = "supplementalData";
+// Tag for meta-data, in root.
+static const char CURRENCY_META[] = "CurrencyMeta";
+
+// Tag for map from countries to currencies, in root.
+static const char CURRENCY_MAP[] = "CurrencyMap";
+
+// Tag for default meta-data, in CURRENCY_META
+static const char DEFAULT_META[] = "DEFAULT";
+
+// Variant delimiter
+static const char VAR_DELIM = '_';
+
+// Tag for localized display names (symbols) of currencies
+static const char CURRENCIES[] = "Currencies";
+static const char CURRENCIES_NARROW[] = "Currencies%narrow";
+static const char CURRENCIES_FORMAL[] = "Currencies%formal";
+static const char CURRENCIES_VARIANT[] = "Currencies%variant";
+static const char CURRENCYPLURALS[] = "CurrencyPlurals";
+
+// ISO codes mapping table
+static const UHashtable* gIsoCodes = NULL;
+static icu::UInitOnce gIsoCodesInitOnce = U_INITONCE_INITIALIZER;
+
+// Currency symbol equivalances
+static const icu::Hashtable* gCurrSymbolsEquiv = NULL;
+static icu::UInitOnce gCurrSymbolsEquivInitOnce = U_INITONCE_INITIALIZER;
+
+U_NAMESPACE_BEGIN
+
+// EquivIterator iterates over all strings that are equivalent to a given
+// string, s. Note that EquivIterator will never yield s itself.
+class EquivIterator : public icu::UMemory {
+public:
+    // Constructor. hash stores the equivalence relationships; s is the string
+    // for which we find equivalent strings.
+    inline EquivIterator(const icu::Hashtable& hash, const icu::UnicodeString& s)
+        : _hash(hash) { 
+        _start = _current = &s;
+    }
+    inline ~EquivIterator() { }
+
+    // next returns the next equivalent string or NULL if there are no more.
+    // If s has no equivalent strings, next returns NULL on the first call.
+    const icu::UnicodeString *next();
+private:
+    const icu::Hashtable& _hash;
+    const icu::UnicodeString* _start;
+    const icu::UnicodeString* _current;
+};
+
+const icu::UnicodeString *
+EquivIterator::next() {
+    const icu::UnicodeString* _next = (const icu::UnicodeString*) _hash.get(*_current);
+    if (_next == NULL) {
+        U_ASSERT(_current == _start);
+        return NULL;
+    }
+    if (*_next == *_start) {
+        return NULL;
+    }
+    _current = _next;
+    return _next;
+}
+
+U_NAMESPACE_END
+
+// makeEquivalent makes lhs and rhs equivalent by updating the equivalence
+// relations in hash accordingly.
+static void makeEquivalent(
+    const icu::UnicodeString &lhs,
+    const icu::UnicodeString &rhs,
+    icu::Hashtable* hash, UErrorCode &status) {
+    if (U_FAILURE(status)) {
+        return;
+    }
+    if (lhs == rhs) {
+        // already equivalent
+        return;
+    }
+    icu::EquivIterator leftIter(*hash, lhs);
+    icu::EquivIterator rightIter(*hash, rhs);
+    const icu::UnicodeString *firstLeft = leftIter.next();
+    const icu::UnicodeString *firstRight = rightIter.next();
+    const icu::UnicodeString *nextLeft = firstLeft;
+    const icu::UnicodeString *nextRight = firstRight;
+    while (nextLeft != NULL && nextRight != NULL) {
+        if (*nextLeft == rhs || *nextRight == lhs) {
+            // Already equivalent
+            return;
+        }
+        nextLeft = leftIter.next();
+        nextRight = rightIter.next();
+    }
+    // Not equivalent. Must join.
+    icu::UnicodeString *newFirstLeft;
+    icu::UnicodeString *newFirstRight;
+    if (firstRight == NULL && firstLeft == NULL) {
+        // Neither lhs or rhs belong to an equivalence circle, so we form
+        // a new equivalnce circle of just lhs and rhs.
+        newFirstLeft = new icu::UnicodeString(rhs);
+        newFirstRight = new icu::UnicodeString(lhs);
+    } else if (firstRight == NULL) {
+        // lhs belongs to an equivalence circle, but rhs does not, so we link
+        // rhs into lhs' circle.
+        newFirstLeft = new icu::UnicodeString(rhs);
+        newFirstRight = new icu::UnicodeString(*firstLeft);
+    } else if (firstLeft == NULL) {
+        // rhs belongs to an equivlance circle, but lhs does not, so we link
+        // lhs into rhs' circle.
+        newFirstLeft = new icu::UnicodeString(*firstRight);
+        newFirstRight = new icu::UnicodeString(lhs);
+    } else {
+        // Both lhs and rhs belong to different equivalnce circles. We link
+        // them together to form one single, larger equivalnce circle.
+        newFirstLeft = new icu::UnicodeString(*firstRight);
+        newFirstRight = new icu::UnicodeString(*firstLeft);
+    }
+    if (newFirstLeft == NULL || newFirstRight == NULL) {
+        delete newFirstLeft;
+        delete newFirstRight;
+        status = U_MEMORY_ALLOCATION_ERROR;
+        return;
+    }
+    hash->put(lhs, (void *) newFirstLeft, status);
+    hash->put(rhs, (void *) newFirstRight, status);
+}
+
+// countEquivalent counts how many strings are equivalent to s.
+// hash stores all the equivalnce relations.
+// countEquivalent does not include s itself in the count.
+static int32_t countEquivalent(const icu::Hashtable &hash, const icu::UnicodeString &s) {
+    int32_t result = 0;
+    icu::EquivIterator iter(hash, s);
+    while (iter.next() != NULL) {
+        ++result;
+    }
+#ifdef UCURR_DEBUG_EQUIV
+ {
+   char tmp[200];
+   s.extract(0,s.length(),tmp, "UTF-8");
+   printf("CountEquivalent('%s') = %d\n", tmp, result);
+ }
+#endif
+    return result;
+}
+
+static const icu::Hashtable* getCurrSymbolsEquiv();
+
+//------------------------------------------------------------
+// Code
+
+/**
+ * Cleanup callback func
+ */
+static UBool U_CALLCONV 
+isoCodes_cleanup(void)
+{
+    if (gIsoCodes != NULL) {
+        uhash_close(const_cast<UHashtable *>(gIsoCodes));
+        gIsoCodes = NULL;
+    }
+    gIsoCodesInitOnce.reset();
+    return TRUE;
+}
+
+/**
+ * Cleanup callback func
+ */
+static UBool U_CALLCONV 
+currSymbolsEquiv_cleanup(void)
+{
+    delete const_cast<icu::Hashtable *>(gCurrSymbolsEquiv);
+    gCurrSymbolsEquiv = NULL;
+    gCurrSymbolsEquivInitOnce.reset();
+    return TRUE;
+}
+
+/**
+ * Deleter for OlsonToMetaMappingEntry
+ */
+static void U_CALLCONV
+deleteIsoCodeEntry(void *obj) {
+    IsoCodeEntry *entry = (IsoCodeEntry*)obj;
+    uprv_free(entry);
+}
+
+/**
+ * Deleter for gCurrSymbolsEquiv.
+ */
+static void U_CALLCONV
+deleteUnicode(void *obj) {
+    icu::UnicodeString *entry = (icu::UnicodeString*)obj;
+    delete entry;
+}
+
+/**
+ * Unfortunately, we have to convert the UChar* currency code to char*
+ * to use it as a resource key.
+ */
+static inline char*
+myUCharsToChars(char* resultOfLen4, const UChar* currency) {
+    u_UCharsToChars(currency, resultOfLen4, ISO_CURRENCY_CODE_LENGTH);
+    resultOfLen4[ISO_CURRENCY_CODE_LENGTH] = 0;
+    return resultOfLen4;
+}
+
+/**
+ * Internal function to look up currency data.  Result is an array of
+ * four integers.  The first is the fraction digits.  The second is the
+ * rounding increment, or 0 if none.  The rounding increment is in
+ * units of 10^(-fraction_digits).  The third and fourth are the same
+ * except that they are those used in cash transations ( cashDigits
+ * and cashRounding ).
+ */
+static const int32_t*
+_findMetaData(const UChar* currency, UErrorCode& ec) {
+
+    if (currency == 0 || *currency == 0) {
+        if (U_SUCCESS(ec)) {
+            ec = U_ILLEGAL_ARGUMENT_ERROR;
+        }
+        return LAST_RESORT_DATA;
+    }
+
+    // Get CurrencyMeta resource out of root locale file.  [This may
+    // move out of the root locale file later; if it does, update this
+    // code.]
+    UResourceBundle* currencyData = ures_openDirect(U_ICUDATA_CURR, CURRENCY_DATA, &ec);
+    UResourceBundle* currencyMeta = ures_getByKey(currencyData, CURRENCY_META, currencyData, &ec);
+
+    if (U_FAILURE(ec)) {
+        ures_close(currencyMeta);
+        // Config/build error; return hard-coded defaults
+        return LAST_RESORT_DATA;
+    }
+
+    // Look up our currency, or if that's not available, then DEFAULT
+    char buf[ISO_CURRENCY_CODE_LENGTH+1];
+    UErrorCode ec2 = U_ZERO_ERROR; // local error code: soft failure
+    UResourceBundle* rb = ures_getByKey(currencyMeta, myUCharsToChars(buf, currency), NULL, &ec2);
+      if (U_FAILURE(ec2)) {
+        ures_close(rb);
+        rb = ures_getByKey(currencyMeta,DEFAULT_META, NULL, &ec);
+        if (U_FAILURE(ec)) {
+            ures_close(currencyMeta);
+            ures_close(rb);
+            // Config/build error; return hard-coded defaults
+            return LAST_RESORT_DATA;
+        }
+    }
+
+    int32_t len;
+    const int32_t *data = ures_getIntVector(rb, &len, &ec);
+    if (U_FAILURE(ec) || len != 4) {
+        // Config/build error; return hard-coded defaults
+        if (U_SUCCESS(ec)) {
+            ec = U_INVALID_FORMAT_ERROR;
+        }
+        ures_close(currencyMeta);
+        ures_close(rb);
+        return LAST_RESORT_DATA;
+    }
+
+    ures_close(currencyMeta);
+    ures_close(rb);
+    return data;
+}
+
+// -------------------------------------
+
+static void
+idForLocale(const char* locale, char* countryAndVariant, int capacity, UErrorCode* ec)
+{
+    ulocimp_getRegionForSupplementalData(locale, FALSE, countryAndVariant, capacity, ec);
+}
+
+// ------------------------------------------
+//
+// Registration
+//
+//-------------------------------------------
+
+// don't use ICUService since we don't need fallback
+
+U_CDECL_BEGIN
+static UBool U_CALLCONV currency_cleanup(void);
+U_CDECL_END
+
+#if !UCONFIG_NO_SERVICE
+struct CReg;
+
+static UMutex gCRegLock;
+static CReg* gCRegHead = 0;
+
+struct CReg : public icu::UMemory {
+    CReg *next;
+    UChar iso[ISO_CURRENCY_CODE_LENGTH+1];
+    char  id[ULOC_FULLNAME_CAPACITY];
+
+    CReg(const UChar* _iso, const char* _id)
+        : next(0)
+    {
+        int32_t len = (int32_t)uprv_strlen(_id);
+        if (len > (int32_t)(sizeof(id)-1)) {
+            len = (sizeof(id)-1);
+        }
+        uprv_strncpy(id, _id, len);
+        id[len] = 0;
+        u_memcpy(iso, _iso, ISO_CURRENCY_CODE_LENGTH);
+        iso[ISO_CURRENCY_CODE_LENGTH] = 0;
+    }
+
+    static UCurrRegistryKey reg(const UChar* _iso, const char* _id, UErrorCode* status)
+    {
+        if (status && U_SUCCESS(*status) && _iso && _id) {
+            CReg* n = new CReg(_iso, _id);
+            if (n) {
+                umtx_lock(&gCRegLock);
+                if (!gCRegHead) {
+                    /* register for the first time */
+                    ucln_common_registerCleanup(UCLN_COMMON_CURRENCY, currency_cleanup);
+                }
+                n->next = gCRegHead;
+                gCRegHead = n;
+                umtx_unlock(&gCRegLock);
+                return n;
+            }
+            *status = U_MEMORY_ALLOCATION_ERROR;
+        }
+        return 0;
+    }
+
+    static UBool unreg(UCurrRegistryKey key) {
+        UBool found = FALSE;
+        umtx_lock(&gCRegLock);
+
+        CReg** p = &gCRegHead;
+        while (*p) {
+            if (*p == key) {
+                *p = ((CReg*)key)->next;
+                delete (CReg*)key;
+                found = TRUE;
+                break;
+            }
+            p = &((*p)->next);
+        }
+
+        umtx_unlock(&gCRegLock);
+        return found;
+    }
+
+    static const UChar* get(const char* id) {
+        const UChar* result = NULL;
+        umtx_lock(&gCRegLock);
+        CReg* p = gCRegHead;
+
+        /* register cleanup of the mutex */
+        ucln_common_registerCleanup(UCLN_COMMON_CURRENCY, currency_cleanup);
+        while (p) {
+            if (uprv_strcmp(id, p->id) == 0) {
+                result = p->iso;
+                break;
+            }
+            p = p->next;
+        }
+        umtx_unlock(&gCRegLock);
+        return result;
+    }
+
+    /* This doesn't need to be thread safe. It's for u_cleanup only. */
+    static void cleanup(void) {
+        while (gCRegHead) {
+            CReg* n = gCRegHead;
+            gCRegHead = gCRegHead->next;
+            delete n;
+        }
+    }
+};
+
+// -------------------------------------
+
+U_CAPI UCurrRegistryKey U_EXPORT2
+ucurr_register(const UChar* isoCode, const char* locale, UErrorCode *status)
+{
+    if (status && U_SUCCESS(*status)) {
+        char id[ULOC_FULLNAME_CAPACITY];
+        idForLocale(locale, id, sizeof(id), status);
+        return CReg::reg(isoCode, id, status);
+    }
+    return NULL;
+}
+
+// -------------------------------------
+
+U_CAPI UBool U_EXPORT2
+ucurr_unregister(UCurrRegistryKey key, UErrorCode* status)
+{
+    if (status && U_SUCCESS(*status)) {
+        return CReg::unreg(key);
+    }
+    return FALSE;
+}
+#endif /* UCONFIG_NO_SERVICE */
+
+// -------------------------------------
+
+/**
+ * Release all static memory held by currency.
+ */
+/*The declaration here is needed so currency_cleanup(void)
+ * can call this function.
+ */
+static UBool U_CALLCONV
+currency_cache_cleanup(void);
+
+U_CDECL_BEGIN
+static UBool U_CALLCONV currency_cleanup(void) {
+#if !UCONFIG_NO_SERVICE
+    CReg::cleanup();
+#endif
+    /*
+     * There might be some cached currency data or isoCodes data.
+     */
+    currency_cache_cleanup();
+    isoCodes_cleanup();
+    currSymbolsEquiv_cleanup();
+
+    return TRUE;
+}
+U_CDECL_END
+
+// -------------------------------------
+
+U_CAPI int32_t U_EXPORT2
+ucurr_forLocale(const char* locale,
+                UChar* buff,
+                int32_t buffCapacity,
+                UErrorCode* ec) {
+    if (U_FAILURE(*ec)) { return 0; }
+    if (buffCapacity < 0 || (buff == nullptr && buffCapacity > 0)) {
+        *ec = U_ILLEGAL_ARGUMENT_ERROR;
+        return 0;
+    }
+
+    char currency[4];  // ISO currency codes are alpha3 codes.
+    UErrorCode localStatus = U_ZERO_ERROR;
+    int32_t resLen = uloc_getKeywordValue(locale, "currency",
+                                          currency, UPRV_LENGTHOF(currency), &localStatus);
+    if (U_SUCCESS(localStatus) && resLen == 3 && uprv_isInvariantString(currency, resLen)) {
+        if (resLen < buffCapacity) {
+            T_CString_toUpperCase(currency);
+            u_charsToUChars(currency, buff, resLen);
+        }
+        return u_terminateUChars(buff, buffCapacity, resLen, ec);
+    }
+
+    // get country or country_variant in `id'
+    char id[ULOC_FULLNAME_CAPACITY];
+    idForLocale(locale, id, UPRV_LENGTHOF(id), ec);
+    if (U_FAILURE(*ec)) {
+        return 0;
+    }
+
+#if !UCONFIG_NO_SERVICE
+    const UChar* result = CReg::get(id);
+    if (result) {
+        if(buffCapacity > u_strlen(result)) {
+            u_strcpy(buff, result);
+        }
+        resLen = u_strlen(result);
+        return u_terminateUChars(buff, buffCapacity, resLen, ec);
+    }
+#endif
+    // Remove variants, which is only needed for registration.
+    char *idDelim = uprv_strchr(id, VAR_DELIM);
+    if (idDelim) {
+        idDelim[0] = 0;
+    }
+
+    const UChar* s = NULL;  // Currency code from data file.
+    if (id[0] == 0) {
+        // No point looking in the data for an empty string.
+        // This is what we would get.
+        localStatus = U_MISSING_RESOURCE_ERROR;
+    } else {
+        // Look up the CurrencyMap element in the root bundle.
+        localStatus = U_ZERO_ERROR;
+        UResourceBundle *rb = ures_openDirect(U_ICUDATA_CURR, CURRENCY_DATA, &localStatus);
+        UResourceBundle *cm = ures_getByKey(rb, CURRENCY_MAP, rb, &localStatus);
+        UResourceBundle *countryArray = ures_getByKey(rb, id, cm, &localStatus);
+        UResourceBundle *currencyReq = ures_getByIndex(countryArray, 0, NULL, &localStatus);
+        s = ures_getStringByKey(currencyReq, "id", &resLen, &localStatus);
+        ures_close(currencyReq);
+        ures_close(countryArray);
+    }
+
+    if ((U_FAILURE(localStatus)) && strchr(id, '_') != 0) {
+        // We don't know about it.  Check to see if we support the variant.
+        uloc_getParent(locale, id, UPRV_LENGTHOF(id), ec);
+        *ec = U_USING_FALLBACK_WARNING;
+        // TODO: Loop over the shortened id rather than recursing and
+        // looking again for a currency keyword.
+        return ucurr_forLocale(id, buff, buffCapacity, ec);
+    }
+    if (*ec == U_ZERO_ERROR || localStatus != U_ZERO_ERROR) {
+        // There is nothing to fallback to. Report the failure/warning if possible.
+        *ec = localStatus;
+    }
+    if (U_SUCCESS(*ec)) {
+        if(buffCapacity > resLen) {
+            u_strcpy(buff, s);
+        }
+    }
+    return u_terminateUChars(buff, buffCapacity, resLen, ec);
+}
+
+// end registration
+
+/**
+ * Modify the given locale name by removing the rightmost _-delimited
+ * element.  If there is none, empty the string ("" == root).
+ * NOTE: The string "root" is not recognized; do not use it.
+ * @return TRUE if the fallback happened; FALSE if locale is already
+ * root ("").
+ */
+static UBool fallback(char *loc) {
+    if (!*loc) {
+        return FALSE;
+    }
+    UErrorCode status = U_ZERO_ERROR;
+    if (uprv_strcmp(loc, "en_GB") == 0) {
+        // HACK: See #13368.  We need "en_GB" to fall back to "en_001" instead of "en"
+        // in order to consume the correct data strings.  This hack will be removed
+        // when proper data sink loading is implemented here.
+        // NOTE: "001" adds 1 char over "GB".  However, both call sites allocate
+        // arrays with length ULOC_FULLNAME_CAPACITY (plenty of room for en_001).
+        uprv_strcpy(loc + 3, "001");
+    } else {
+        uloc_getParent(loc, loc, (int32_t)uprv_strlen(loc), &status);
+    }
+ /*
+    char *i = uprv_strrchr(loc, '_');
+    if (i == NULL) {
+        i = loc;
+    }
+    *i = 0;
+ */
+    return TRUE;
+}
+
+
+U_CAPI const UChar* U_EXPORT2
+ucurr_getName(const UChar* currency,
+              const char* locale,
+              UCurrNameStyle nameStyle,
+              UBool* isChoiceFormat, // fillin
+              int32_t* len, // fillin
+              UErrorCode* ec) {
+
+    // Look up the Currencies resource for the given locale.  The
+    // Currencies locale data looks like this:
+    //|en {
+    //|  Currencies {
+    //|    USD { "US$", "US Dollar" }
+    //|    CHF { "Sw F", "Swiss Franc" }
+    //|    INR { "=0#Rs|1#Re|1<Rs", "=0#Rupees|1#Rupee|1<Rupees" }
+    //|    //...
+    //|  }
+    //|}
+
+    if (U_FAILURE(*ec)) {
+        return 0;
+    }
+
+    int32_t choice = (int32_t) nameStyle;
+    if (choice < 0 || choice > 4) {
+        *ec = U_ILLEGAL_ARGUMENT_ERROR;
+        return 0;
+    }
+
+    // In the future, resource bundles may implement multi-level
+    // fallback.  That is, if a currency is not found in the en_US
+    // Currencies data, then the en Currencies data will be searched.
+    // Currently, if a Currencies datum exists in en_US and en, the
+    // en_US entry hides that in en.
+
+    // We want multi-level fallback for this resource, so we implement
+    // it manually.
+
+    // Use a separate UErrorCode here that does not propagate out of
+    // this function.
+    UErrorCode ec2 = U_ZERO_ERROR;
+
+    char loc[ULOC_FULLNAME_CAPACITY];
+    uloc_getName(locale, loc, sizeof(loc), &ec2);
+    if (U_FAILURE(ec2) || ec2 == U_STRING_NOT_TERMINATED_WARNING) {
+        *ec = U_ILLEGAL_ARGUMENT_ERROR;
+        return 0;
+    }
+
+    char buf[ISO_CURRENCY_CODE_LENGTH+1];
+    myUCharsToChars(buf, currency);
+    
+    /* Normalize the keyword value to uppercase */
+    T_CString_toUpperCase(buf);
+    
+    const UChar* s = NULL;
+    ec2 = U_ZERO_ERROR;
+    LocalUResourceBundlePointer rb(ures_open(U_ICUDATA_CURR, loc, &ec2));
+
+    if (nameStyle == UCURR_NARROW_SYMBOL_NAME || nameStyle == UCURR_FORMAL_SYMBOL_NAME || nameStyle == UCURR_VARIANT_SYMBOL_NAME) {
+        CharString key;
+        switch (nameStyle) {
+        case UCURR_NARROW_SYMBOL_NAME:
+            key.append(CURRENCIES_NARROW, ec2);
+            break;
+        case UCURR_FORMAL_SYMBOL_NAME:
+            key.append(CURRENCIES_FORMAL, ec2);
+            break;
+        case UCURR_VARIANT_SYMBOL_NAME:
+            key.append(CURRENCIES_VARIANT, ec2);
+            break;
+        default:
+            *ec = U_UNSUPPORTED_ERROR;
+            return 0;
+        }
+        key.append("/", ec2);
+        key.append(buf, ec2);
+        s = ures_getStringByKeyWithFallback(rb.getAlias(), key.data(), len, &ec2);
+        if (ec2 == U_MISSING_RESOURCE_ERROR) {
+            *ec = U_USING_FALLBACK_WARNING;
+            ec2 = U_ZERO_ERROR;
+            choice = UCURR_SYMBOL_NAME;
+        }
+    }
+    if (s == NULL) {
+        ures_getByKey(rb.getAlias(), CURRENCIES, rb.getAlias(), &ec2);
+        ures_getByKeyWithFallback(rb.getAlias(), buf, rb.getAlias(), &ec2);
+        s = ures_getStringByIndex(rb.getAlias(), choice, len, &ec2);
+    }
+
+    // If we've succeeded we're done.  Otherwise, try to fallback.
+    // If that fails (because we are already at root) then exit.
+    if (U_SUCCESS(ec2)) {
+        if (ec2 == U_USING_DEFAULT_WARNING
+            || (ec2 == U_USING_FALLBACK_WARNING && *ec != U_USING_DEFAULT_WARNING)) {
+            *ec = ec2;
+        }
+    }
+
+    // We no longer support choice format data in names.  Data should not contain
+    // choice patterns.
+    if (isChoiceFormat != NULL) {
+        *isChoiceFormat = FALSE;
+    }
+    if (U_SUCCESS(ec2)) {
+        U_ASSERT(s != NULL);
+        return s;
+    }
+
+    // If we fail to find a match, use the ISO 4217 code
+    *len = u_strlen(currency); // Should == ISO_CURRENCY_CODE_LENGTH, but maybe not...?
+    *ec = U_USING_DEFAULT_WARNING;
+    return currency;
+}
+
+U_CAPI const UChar* U_EXPORT2
+ucurr_getPluralName(const UChar* currency,
+                    const char* locale,
+                    UBool* isChoiceFormat,
+                    const char* pluralCount,
+                    int32_t* len, // fillin
+                    UErrorCode* ec) {
+    // Look up the Currencies resource for the given locale.  The
+    // Currencies locale data looks like this:
+    //|en {
+    //|  CurrencyPlurals {
+    //|    USD{
+    //|      one{"US dollar"}
+    //|      other{"US dollars"}
+    //|    }
+    //|  }
+    //|}
+
+    if (U_FAILURE(*ec)) {
+        return 0;
+    }
+
+    // Use a separate UErrorCode here that does not propagate out of
+    // this function.
+    UErrorCode ec2 = U_ZERO_ERROR;
+
+    char loc[ULOC_FULLNAME_CAPACITY];
+    uloc_getName(locale, loc, sizeof(loc), &ec2);
+    if (U_FAILURE(ec2) || ec2 == U_STRING_NOT_TERMINATED_WARNING) {
+        *ec = U_ILLEGAL_ARGUMENT_ERROR;
+        return 0;
+    }
+
+    char buf[ISO_CURRENCY_CODE_LENGTH+1];
+    myUCharsToChars(buf, currency);
+
+    const UChar* s = NULL;
+    ec2 = U_ZERO_ERROR;
+    UResourceBundle* rb = ures_open(U_ICUDATA_CURR, loc, &ec2);
+
+    rb = ures_getByKey(rb, CURRENCYPLURALS, rb, &ec2);
+
+    // Fetch resource with multi-level resource inheritance fallback
+    rb = ures_getByKeyWithFallback(rb, buf, rb, &ec2);
+
+    s = ures_getStringByKeyWithFallback(rb, pluralCount, len, &ec2);
+    if (U_FAILURE(ec2)) {
+        //  fall back to "other"
+        ec2 = U_ZERO_ERROR;
+        s = ures_getStringByKeyWithFallback(rb, "other", len, &ec2);     
+        if (U_FAILURE(ec2)) {
+            ures_close(rb);
+            // fall back to long name in Currencies
+            return ucurr_getName(currency, locale, UCURR_LONG_NAME, 
+                                 isChoiceFormat, len, ec);
+        }
+    }
+    ures_close(rb);
+
+    // If we've succeeded we're done.  Otherwise, try to fallback.
+    // If that fails (because we are already at root) then exit.
+    if (U_SUCCESS(ec2)) {
+        if (ec2 == U_USING_DEFAULT_WARNING
+            || (ec2 == U_USING_FALLBACK_WARNING && *ec != U_USING_DEFAULT_WARNING)) {
+            *ec = ec2;
+        }
+        U_ASSERT(s != NULL);
+        return s;
+    }
+
+    // If we fail to find a match, use the ISO 4217 code
+    *len = u_strlen(currency); // Should == ISO_CURRENCY_CODE_LENGTH, but maybe not...?
+    *ec = U_USING_DEFAULT_WARNING;
+    return currency;
+}
+
+
+//========================================================================
+// Following are structure and function for parsing currency names
+
+#define NEED_TO_BE_DELETED 0x1
+
+// TODO: a better way to define this?
+#define MAX_CURRENCY_NAME_LEN 100
+
+typedef struct {
+    const char* IsoCode;  // key
+    UChar* currencyName;  // value
+    int32_t currencyNameLen;  // value length
+    int32_t flag;  // flags
+} CurrencyNameStruct;
+
+
+#ifndef MIN
+#define MIN(a,b) (((a)<(b)) ? (a) : (b))
+#endif
+
+#ifndef MAX
+#define MAX(a,b) (((a)<(b)) ? (b) : (a))
+#endif
+
+
+// Comparason function used in quick sort.
+static int U_CALLCONV currencyNameComparator(const void* a, const void* b) {
+    const CurrencyNameStruct* currName_1 = (const CurrencyNameStruct*)a;
+    const CurrencyNameStruct* currName_2 = (const CurrencyNameStruct*)b;
+    for (int32_t i = 0; 
+         i < MIN(currName_1->currencyNameLen, currName_2->currencyNameLen);
+         ++i) {
+        if (currName_1->currencyName[i] < currName_2->currencyName[i]) {
+            return -1;
+        }
+        if (currName_1->currencyName[i] > currName_2->currencyName[i]) {
+            return 1;
+        }
+    }
+    if (currName_1->currencyNameLen < currName_2->currencyNameLen) {
+        return -1;
+    } else if (currName_1->currencyNameLen > currName_2->currencyNameLen) {
+        return 1;
+    }
+    return 0;
+}
+
+
+// Give a locale, return the maximum number of currency names associated with
+// this locale.
+// It gets currency names from resource bundles using fallback.
+// It is the maximum number because in the fallback chain, some of the 
+// currency names are duplicated.
+// For example, given locale as "en_US", the currency names get from resource
+// bundle in "en_US" and "en" are duplicated. The fallback mechanism will count
+// all currency names in "en_US" and "en".
+static void
+getCurrencyNameCount(const char* loc, int32_t* total_currency_name_count, int32_t* total_currency_symbol_count) {
+    U_NAMESPACE_USE
+    *total_currency_name_count = 0;
+    *total_currency_symbol_count = 0;
+    const UChar* s = NULL;
+    char locale[ULOC_FULLNAME_CAPACITY] = "";
+    uprv_strcpy(locale, loc);
+    const icu::Hashtable *currencySymbolsEquiv = getCurrSymbolsEquiv();
+    for (;;) {
+        UErrorCode ec2 = U_ZERO_ERROR;
+        // TODO: ures_openDirect?
+        UResourceBundle* rb = ures_open(U_ICUDATA_CURR, locale, &ec2);
+        UResourceBundle* curr = ures_getByKey(rb, CURRENCIES, NULL, &ec2);
+        int32_t n = ures_getSize(curr);
+        for (int32_t i=0; i<n; ++i) {
+            UResourceBundle* names = ures_getByIndex(curr, i, NULL, &ec2);
+            int32_t len;
+            s = ures_getStringByIndex(names, UCURR_SYMBOL_NAME, &len, &ec2);
+            ++(*total_currency_symbol_count);  // currency symbol
+            if (currencySymbolsEquiv != NULL) {
+                *total_currency_symbol_count += countEquivalent(*currencySymbolsEquiv, UnicodeString(TRUE, s, len));
+            }
+            ++(*total_currency_symbol_count); // iso code
+            ++(*total_currency_name_count); // long name
+            ures_close(names);
+        }
+
+        // currency plurals
+        UErrorCode ec3 = U_ZERO_ERROR;
+        UResourceBundle* curr_p = ures_getByKey(rb, CURRENCYPLURALS, NULL, &ec3);
+        n = ures_getSize(curr_p);
+        for (int32_t i=0; i<n; ++i) {
+            UResourceBundle* names = ures_getByIndex(curr_p, i, NULL, &ec3);
+            *total_currency_name_count += ures_getSize(names);
+            ures_close(names);
+        }
+        ures_close(curr_p);
+        ures_close(curr);
+        ures_close(rb);
+
+        if (!fallback(locale)) {
+            break;
+        }
+    }
+}
+
+static UChar* 
+toUpperCase(const UChar* source, int32_t len, const char* locale) {
+    UChar* dest = NULL;
+    UErrorCode ec = U_ZERO_ERROR;
+    int32_t destLen = u_strToUpper(dest, 0, source, len, locale, &ec);
+
+    ec = U_ZERO_ERROR;
+    dest = (UChar*)uprv_malloc(sizeof(UChar) * MAX(destLen, len));
+    u_strToUpper(dest, destLen, source, len, locale, &ec);
+    if (U_FAILURE(ec)) {
+        u_memcpy(dest, source, len);
+    } 
+    return dest;
+}
+
+
+// Collect all available currency names associated with the given locale
+// (enable fallback chain).
+// Read currenc names defined in resource bundle "Currencies" and
+// "CurrencyPlural", enable fallback chain.
+// return the malloc-ed currency name arrays and the total number of currency
+// names in the array.
+static void
+collectCurrencyNames(const char* locale, 
+                     CurrencyNameStruct** currencyNames, 
+                     int32_t* total_currency_name_count, 
+                     CurrencyNameStruct** currencySymbols, 
+                     int32_t* total_currency_symbol_count, 
+                     UErrorCode& ec) {
+    U_NAMESPACE_USE
+    const icu::Hashtable *currencySymbolsEquiv = getCurrSymbolsEquiv();
+    // Look up the Currencies resource for the given locale.
+    UErrorCode ec2 = U_ZERO_ERROR;
+
+    char loc[ULOC_FULLNAME_CAPACITY] = "";
+    uloc_getName(locale, loc, sizeof(loc), &ec2);
+    if (U_FAILURE(ec2) || ec2 == U_STRING_NOT_TERMINATED_WARNING) {
+        ec = U_ILLEGAL_ARGUMENT_ERROR;
+    }
+
+    // Get maximum currency name count first.
+    getCurrencyNameCount(loc, total_currency_name_count, total_currency_symbol_count);
+
+    *currencyNames = (CurrencyNameStruct*)uprv_malloc
+        (sizeof(CurrencyNameStruct) * (*total_currency_name_count));
+    *currencySymbols = (CurrencyNameStruct*)uprv_malloc
+        (sizeof(CurrencyNameStruct) * (*total_currency_symbol_count));
+
+    if(currencyNames == NULL || currencySymbols == NULL) {
+      ec = U_MEMORY_ALLOCATION_ERROR;
+    }
+
+    if (U_FAILURE(ec)) return;
+
+    const UChar* s = NULL;  // currency name
+    char* iso = NULL;  // currency ISO code
+
+    *total_currency_name_count = 0;
+    *total_currency_symbol_count = 0;
+
+    UErrorCode ec3 = U_ZERO_ERROR;
+    UErrorCode ec4 = U_ZERO_ERROR;
+
+    // Using hash to remove duplicates caused by locale fallback
+    UHashtable* currencyIsoCodes = uhash_open(uhash_hashChars, uhash_compareChars, NULL, &ec3);
+    UHashtable* currencyPluralIsoCodes = uhash_open(uhash_hashChars, uhash_compareChars, NULL, &ec4);
+    for (int32_t localeLevel = 0; ; ++localeLevel) {
+        ec2 = U_ZERO_ERROR;
+        // TODO: ures_openDirect
+        UResourceBundle* rb = ures_open(U_ICUDATA_CURR, loc, &ec2);
+        UResourceBundle* curr = ures_getByKey(rb, CURRENCIES, NULL, &ec2);
+        int32_t n = ures_getSize(curr);
+        for (int32_t i=0; i<n; ++i) {
+            UResourceBundle* names = ures_getByIndex(curr, i, NULL, &ec2);
+            int32_t len;
+            s = ures_getStringByIndex(names, UCURR_SYMBOL_NAME, &len, &ec2);
+            // TODO: uhash_put wont change key/value?
+            iso = (char*)ures_getKey(names);
+            if (localeLevel == 0) {
+                uhash_put(currencyIsoCodes, iso, iso, &ec3); 
+            } else {
+                if (uhash_get(currencyIsoCodes, iso) != NULL) {
+                    ures_close(names);
+                    continue;
+                } else {
+                    uhash_put(currencyIsoCodes, iso, iso, &ec3); 
+                }
+            }
+            // Add currency symbol.
+            (*currencySymbols)[*total_currency_symbol_count].IsoCode = iso;
+            (*currencySymbols)[*total_currency_symbol_count].currencyName = (UChar*)s;
+            (*currencySymbols)[*total_currency_symbol_count].flag = 0;
+            (*currencySymbols)[(*total_currency_symbol_count)++].currencyNameLen = len;
+            // Add equivalent symbols
+            if (currencySymbolsEquiv != NULL) {
+                UnicodeString str(TRUE, s, len);
+                icu::EquivIterator iter(*currencySymbolsEquiv, str);
+                const UnicodeString *symbol;
+                while ((symbol = iter.next()) != NULL) {
+                    (*currencySymbols)[*total_currency_symbol_count].IsoCode = iso;
+                    (*currencySymbols)[*total_currency_symbol_count].currencyName =
+                        const_cast<UChar*>(symbol->getBuffer());
+                    (*currencySymbols)[*total_currency_symbol_count].flag = 0;
+                    (*currencySymbols)[(*total_currency_symbol_count)++].currencyNameLen = symbol->length();
+                }
+            }
+
+            // Add currency long name.
+            s = ures_getStringByIndex(names, UCURR_LONG_NAME, &len, &ec2);
+            (*currencyNames)[*total_currency_name_count].IsoCode = iso;
+            UChar* upperName = toUpperCase(s, len, locale);
+            (*currencyNames)[*total_currency_name_count].currencyName = upperName;
+            (*currencyNames)[*total_currency_name_count].flag = NEED_TO_BE_DELETED;
+            (*currencyNames)[(*total_currency_name_count)++].currencyNameLen = len;
+
+            // put (iso, 3, and iso) in to array
+            // Add currency ISO code.
+            (*currencySymbols)[*total_currency_symbol_count].IsoCode = iso;
+            (*currencySymbols)[*total_currency_symbol_count].currencyName = (UChar*)uprv_malloc(sizeof(UChar)*3);
+            // Must convert iso[] into Unicode
+            u_charsToUChars(iso, (*currencySymbols)[*total_currency_symbol_count].currencyName, 3);
+            (*currencySymbols)[*total_currency_symbol_count].flag = NEED_TO_BE_DELETED;
+            (*currencySymbols)[(*total_currency_symbol_count)++].currencyNameLen = 3;
+
+            ures_close(names);
+        }
+
+        // currency plurals
+        UErrorCode ec5 = U_ZERO_ERROR;
+        UResourceBundle* curr_p = ures_getByKey(rb, CURRENCYPLURALS, NULL, &ec5);
+        n = ures_getSize(curr_p);
+        for (int32_t i=0; i<n; ++i) {
+            UResourceBundle* names = ures_getByIndex(curr_p, i, NULL, &ec5);
+            iso = (char*)ures_getKey(names);
+            // Using hash to remove duplicated ISO codes in fallback chain.
+            if (localeLevel == 0) {
+                uhash_put(currencyPluralIsoCodes, iso, iso, &ec4); 
+            } else {
+                if (uhash_get(currencyPluralIsoCodes, iso) != NULL) {
+                    ures_close(names);
+                    continue;
+                } else {
+                    uhash_put(currencyPluralIsoCodes, iso, iso, &ec4); 
+                }
+            }
+            int32_t num = ures_getSize(names);
+            int32_t len;
+            for (int32_t j = 0; j < num; ++j) {
+                // TODO: remove duplicates between singular name and 
+                // currency long name?
+                s = ures_getStringByIndex(names, j, &len, &ec5);
+                (*currencyNames)[*total_currency_name_count].IsoCode = iso;
+                UChar* upperName = toUpperCase(s, len, locale);
+                (*currencyNames)[*total_currency_name_count].currencyName = upperName;
+                (*currencyNames)[*total_currency_name_count].flag = NEED_TO_BE_DELETED;
+                (*currencyNames)[(*total_currency_name_count)++].currencyNameLen = len;
+            }
+            ures_close(names);
+        }
+        ures_close(curr_p);
+        ures_close(curr);
+        ures_close(rb);
+
+        if (!fallback(loc)) {
+            break;
+        }
+    }
+
+    uhash_close(currencyIsoCodes);
+    uhash_close(currencyPluralIsoCodes);
+
+    // quick sort the struct
+    qsort(*currencyNames, *total_currency_name_count, 
+          sizeof(CurrencyNameStruct), currencyNameComparator);
+    qsort(*currencySymbols, *total_currency_symbol_count, 
+          sizeof(CurrencyNameStruct), currencyNameComparator);
+
+#ifdef UCURR_DEBUG
+    printf("currency name count: %d\n", *total_currency_name_count);
+    for (int32_t index = 0; index < *total_currency_name_count; ++index) {
+        printf("index: %d\n", index);
+        printf("iso: %s\n", (*currencyNames)[index].IsoCode);
+        char curNameBuf[1024];
+        memset(curNameBuf, 0, 1024);
+        u_austrncpy(curNameBuf, (*currencyNames)[index].currencyName, (*currencyNames)[index].currencyNameLen);
+        printf("currencyName: %s\n", curNameBuf);
+        printf("len: %d\n", (*currencyNames)[index].currencyNameLen);
+    }
+    printf("currency symbol count: %d\n", *total_currency_symbol_count);
+    for (int32_t index = 0; index < *total_currency_symbol_count; ++index) {
+        printf("index: %d\n", index);
+        printf("iso: %s\n", (*currencySymbols)[index].IsoCode);
+        char curNameBuf[1024];
+        memset(curNameBuf, 0, 1024);
+        u_austrncpy(curNameBuf, (*currencySymbols)[index].currencyName, (*currencySymbols)[index].currencyNameLen);
+        printf("currencySymbol: %s\n", curNameBuf);
+        printf("len: %d\n", (*currencySymbols)[index].currencyNameLen);
+    }
+#endif
+    // fail on hashtable errors
+    if (U_FAILURE(ec3)) {
+      ec = ec3;
+      return;
+    }
+    if (U_FAILURE(ec4)) {
+      ec = ec4;
+      return;
+    }
+}
+
+// @param  currencyNames: currency names array
+// @param  indexInCurrencyNames: the index of the character in currency names 
+//         array against which the comparison is done
+// @param  key: input text char to compare against
+// @param  begin(IN/OUT): the begin index of matching range in currency names array
+// @param  end(IN/OUT): the end index of matching range in currency names array.
+static int32_t
+binarySearch(const CurrencyNameStruct* currencyNames, 
+             int32_t indexInCurrencyNames,
+             const UChar key,
+             int32_t* begin, int32_t* end) {
+#ifdef UCURR_DEBUG
+    printf("key = %x\n", key);
+#endif
+   int32_t first = *begin;
+   int32_t last = *end;
+   while (first <= last) {
+       int32_t mid = (first + last) / 2;  // compute mid point.
+       if (indexInCurrencyNames >= currencyNames[mid].currencyNameLen) {
+           first = mid + 1;
+       } else {
+           if (key > currencyNames[mid].currencyName[indexInCurrencyNames]) {
+               first = mid + 1;
+           }
+           else if (key < currencyNames[mid].currencyName[indexInCurrencyNames]) {
+               last = mid - 1;
+           }
+           else {
+                // Find a match, and looking for ranges
+                // Now do two more binary searches. First, on the left side for
+                // the greatest L such that CurrencyNameStruct[L] < key.
+                int32_t L = *begin;
+                int32_t R = mid;
+
+#ifdef UCURR_DEBUG
+                printf("mid = %d\n", mid);
+#endif
+                while (L < R) {
+                    int32_t M = (L + R) / 2;
+#ifdef UCURR_DEBUG
+                    printf("L = %d, R = %d, M = %d\n", L, R, M);
+#endif
+                    if (indexInCurrencyNames >= currencyNames[M].currencyNameLen) {
+                        L = M + 1;
+                    } else {
+                        if (currencyNames[M].currencyName[indexInCurrencyNames] < key) {
+                            L = M + 1;
+                        } else {
+#ifdef UCURR_DEBUG
+                            U_ASSERT(currencyNames[M].currencyName[indexInCurrencyNames] == key);
+#endif
+                            R = M;
+                        }
+                    }
+                }
+#ifdef UCURR_DEBUG
+                U_ASSERT(L == R);
+#endif
+                *begin = L;
+#ifdef UCURR_DEBUG
+                printf("begin = %d\n", *begin);
+                U_ASSERT(currencyNames[*begin].currencyName[indexInCurrencyNames] == key);
+#endif
+
+                // Now for the second search, finding the least R such that
+                // key < CurrencyNameStruct[R].
+                L = mid;
+                R = *end;
+                while (L < R) {
+                    int32_t M = (L + R) / 2;
+#ifdef UCURR_DEBUG
+                    printf("L = %d, R = %d, M = %d\n", L, R, M);
+#endif
+                    if (currencyNames[M].currencyNameLen < indexInCurrencyNames) {
+                        L = M + 1;
+                    } else {
+                        if (currencyNames[M].currencyName[indexInCurrencyNames] > key) {
+                            R = M;
+                        } else {
+#ifdef UCURR_DEBUG
+                            U_ASSERT(currencyNames[M].currencyName[indexInCurrencyNames] == key);
+#endif
+                            L = M + 1;
+                        }
+                    }
+                }
+#ifdef UCURR_DEBUG
+                U_ASSERT(L == R);
+#endif
+                if (currencyNames[R].currencyName[indexInCurrencyNames] > key) {
+                    *end = R - 1;
+                } else {
+                    *end = R;
+                }
+#ifdef UCURR_DEBUG
+                printf("end = %d\n", *end);
+#endif
+
+                // now, found the range. check whether there is exact match
+                if (currencyNames[*begin].currencyNameLen == indexInCurrencyNames + 1) {
+                    return *begin;  // find range and exact match.
+                }
+                return -1;  // find range, but no exact match.
+           }
+       }
+   }
+   *begin = -1;
+   *end = -1;
+   return -1;    // failed to find range.
+}
+
+
+// Linear search "text" in "currencyNames".
+// @param  begin, end: the begin and end index in currencyNames, within which
+//         range should the search be performed.
+// @param  textLen: the length of the text to be compared
+// @param  maxMatchLen(IN/OUT): passing in the computed max matching length
+//                              pass out the new max  matching length
+// @param  maxMatchIndex: the index in currencyName which has the longest
+//                        match with input text.
+static void
+linearSearch(const CurrencyNameStruct* currencyNames, 
+             int32_t begin, int32_t end,
+             const UChar* text, int32_t textLen,
+             int32_t *partialMatchLen,
+             int32_t *maxMatchLen, int32_t* maxMatchIndex) {
+    int32_t initialPartialMatchLen = *partialMatchLen;
+    for (int32_t index = begin; index <= end; ++index) {
+        int32_t len = currencyNames[index].currencyNameLen;
+        if (len > *maxMatchLen && len <= textLen &&
+            uprv_memcmp(currencyNames[index].currencyName, text, len * sizeof(UChar)) == 0) {
+            *partialMatchLen = MAX(*partialMatchLen, len);
+            *maxMatchIndex = index;
+            *maxMatchLen = len;
+#ifdef UCURR_DEBUG
+            printf("maxMatchIndex = %d, maxMatchLen = %d\n",
+                   *maxMatchIndex, *maxMatchLen);
+#endif
+        } else {
+            // Check for partial matches.
+            for (int32_t i=initialPartialMatchLen; i<MIN(len, textLen); i++) {
+                if (currencyNames[index].currencyName[i] != text[i]) {
+                    break;
+                }
+                *partialMatchLen = MAX(*partialMatchLen, i + 1);
+            }
+        }
+    }
+}
+
+#define LINEAR_SEARCH_THRESHOLD 10
+
+// Find longest match between "text" and currency names in "currencyNames".
+// @param  total_currency_count: total number of currency names in CurrencyNames.
+// @param  textLen: the length of the text to be compared
+// @param  maxMatchLen: passing in the computed max matching length
+//                              pass out the new max  matching length
+// @param  maxMatchIndex: the index in currencyName which has the longest
+//                        match with input text.
+static void
+searchCurrencyName(const CurrencyNameStruct* currencyNames, 
+                   int32_t total_currency_count,
+                   const UChar* text, int32_t textLen,
+                   int32_t *partialMatchLen,
+                   int32_t* maxMatchLen, int32_t* maxMatchIndex) {
+    *maxMatchIndex = -1;
+    *maxMatchLen = 0;
+    int32_t matchIndex = -1;
+    int32_t binarySearchBegin = 0;
+    int32_t binarySearchEnd = total_currency_count - 1;
+    // It is a variant of binary search.
+    // For example, given the currency names in currencyNames array are:
+    // A AB ABC AD AZ B BB BBEX BBEXYZ BS C D E....
+    // and the input text is BBEXST
+    // The first round binary search search "B" in the text against
+    // the first char in currency names, and find the first char matching range
+    // to be "B BB BBEX BBEXYZ BS" (and the maximum matching "B").
+    // The 2nd round binary search search the second "B" in the text against
+    // the 2nd char in currency names, and narrow the matching range to
+    // "BB BBEX BBEXYZ" (and the maximum matching "BB").
+    // The 3rd round returnes the range as "BBEX BBEXYZ" (without changing
+    // maximum matching).
+    // The 4th round returns the same range (the maximum matching is "BBEX").
+    // The 5th round returns no matching range.
+    for (int32_t index = 0; index < textLen; ++index) {
+        // matchIndex saves the one with exact match till the current point.
+        // [binarySearchBegin, binarySearchEnd] saves the matching range.
+        matchIndex = binarySearch(currencyNames, index,
+                                  text[index],
+                                  &binarySearchBegin, &binarySearchEnd);
+        if (binarySearchBegin == -1) { // did not find the range
+            break;
+        }
+        *partialMatchLen = MAX(*partialMatchLen, index + 1);
+        if (matchIndex != -1) { 
+            // find an exact match for text from text[0] to text[index] 
+            // in currencyNames array.
+            *maxMatchLen = index + 1;
+            *maxMatchIndex = matchIndex;
+        }
+        if (binarySearchEnd - binarySearchBegin < LINEAR_SEARCH_THRESHOLD) {
+            // linear search if within threshold.
+            linearSearch(currencyNames, binarySearchBegin, binarySearchEnd,
+                         text, textLen,
+                         partialMatchLen,
+                         maxMatchLen, maxMatchIndex);
+            break;
+        }
+    }
+    return;
+}
+
+//========================= currency name cache =====================
+typedef struct {
+    char locale[ULOC_FULLNAME_CAPACITY];  //key
+    // currency names, case insensitive
+    CurrencyNameStruct* currencyNames;  // value
+    int32_t totalCurrencyNameCount;  // currency name count
+    // currency symbols and ISO code, case sensitive
+    CurrencyNameStruct* currencySymbols; // value
+    int32_t totalCurrencySymbolCount;  // count
+    // reference count.
+    // reference count is set to 1 when an entry is put to cache.
+    // it increases by 1 before accessing, and decreased by 1 after accessing.
+    // The entry is deleted when ref count is zero, which means 
+    // the entry is replaced out of cache and no process is accessing it.
+    int32_t refCount;
+} CurrencyNameCacheEntry;
+
+
+#define CURRENCY_NAME_CACHE_NUM 10
+
+// Reserve 10 cache entries.
+static CurrencyNameCacheEntry* currCache[CURRENCY_NAME_CACHE_NUM] = {NULL};
+// Using an index to indicate which entry to be replaced when cache is full.
+// It is a simple round-robin replacement strategy.
+static int8_t currentCacheEntryIndex = 0;
+
+static UMutex gCurrencyCacheMutex;
+
+// Cache deletion
+static void
+deleteCurrencyNames(CurrencyNameStruct* currencyNames, int32_t count) {
+    for (int32_t index = 0; index < count; ++index) {
+        if ( (currencyNames[index].flag & NEED_TO_BE_DELETED) ) {
+            uprv_free(currencyNames[index].currencyName);
+        }
+    }
+    uprv_free(currencyNames);
+}
+
+
+static void
+deleteCacheEntry(CurrencyNameCacheEntry* entry) {
+    deleteCurrencyNames(entry->currencyNames, entry->totalCurrencyNameCount);
+    deleteCurrencyNames(entry->currencySymbols, entry->totalCurrencySymbolCount);
+    uprv_free(entry);
+}
+
+
+// Cache clean up
+static UBool U_CALLCONV
+currency_cache_cleanup(void) {
+    for (int32_t i = 0; i < CURRENCY_NAME_CACHE_NUM; ++i) {
+        if (currCache[i]) {
+            deleteCacheEntry(currCache[i]);
+            currCache[i] = 0;
+        }
+    }
+    return TRUE;
+}
+
+
+/**
+ * Loads the currency name data from the cache, or from resource bundles if necessary.
+ * The refCount is automatically incremented.  It is the caller's responsibility
+ * to decrement it when done!
+ */
+static CurrencyNameCacheEntry*
+getCacheEntry(const char* locale, UErrorCode& ec) {
+
+    int32_t total_currency_name_count = 0;
+    CurrencyNameStruct* currencyNames = NULL;
+    int32_t total_currency_symbol_count = 0;
+    CurrencyNameStruct* currencySymbols = NULL;
+    CurrencyNameCacheEntry* cacheEntry = NULL;
+
+    umtx_lock(&gCurrencyCacheMutex);
+    // in order to handle racing correctly,
+    // not putting 'search' in a separate function.
+    int8_t found = -1;
+    for (int8_t i = 0; i < CURRENCY_NAME_CACHE_NUM; ++i) {
+        if (currCache[i]!= NULL &&
+            uprv_strcmp(locale, currCache[i]->locale) == 0) {
+            found = i;
+            break;
+        }
+    }
+    if (found != -1) {
+        cacheEntry = currCache[found];
+        ++(cacheEntry->refCount);
+    }
+    umtx_unlock(&gCurrencyCacheMutex);
+    if (found == -1) {
+        collectCurrencyNames(locale, &currencyNames, &total_currency_name_count, &currencySymbols, &total_currency_symbol_count, ec);
+        if (U_FAILURE(ec)) {
+            return NULL;
+        }
+        umtx_lock(&gCurrencyCacheMutex);
+        // check again.
+        for (int8_t i = 0; i < CURRENCY_NAME_CACHE_NUM; ++i) {
+            if (currCache[i]!= NULL &&
+                uprv_strcmp(locale, currCache[i]->locale) == 0) {
+                found = i;
+                break;
+            }
+        }
+        if (found == -1) {
+            // insert new entry to 
+            // currentCacheEntryIndex % CURRENCY_NAME_CACHE_NUM
+            // and remove the existing entry 
+            // currentCacheEntryIndex % CURRENCY_NAME_CACHE_NUM
+            // from cache.
+            cacheEntry = currCache[currentCacheEntryIndex];
+            if (cacheEntry) {
+                --(cacheEntry->refCount);
+                // delete if the ref count is zero
+                if (cacheEntry->refCount == 0) {
+                    deleteCacheEntry(cacheEntry);
+                }
+            }
+            cacheEntry = (CurrencyNameCacheEntry*)uprv_malloc(sizeof(CurrencyNameCacheEntry));
+            currCache[currentCacheEntryIndex] = cacheEntry;
+            uprv_strcpy(cacheEntry->locale, locale);
+            cacheEntry->currencyNames = currencyNames;
+            cacheEntry->totalCurrencyNameCount = total_currency_name_count;
+            cacheEntry->currencySymbols = currencySymbols;
+            cacheEntry->totalCurrencySymbolCount = total_currency_symbol_count;
+            cacheEntry->refCount = 2; // one for cache, one for reference
+            currentCacheEntryIndex = (currentCacheEntryIndex + 1) % CURRENCY_NAME_CACHE_NUM;
+            ucln_common_registerCleanup(UCLN_COMMON_CURRENCY, currency_cleanup);
+        } else {
+            deleteCurrencyNames(currencyNames, total_currency_name_count);
+            deleteCurrencyNames(currencySymbols, total_currency_symbol_count);
+            cacheEntry = currCache[found];
+            ++(cacheEntry->refCount);
+        }
+        umtx_unlock(&gCurrencyCacheMutex);
+    }
+
+    return cacheEntry;
+}
+
+static void releaseCacheEntry(CurrencyNameCacheEntry* cacheEntry) {
+    umtx_lock(&gCurrencyCacheMutex);
+    --(cacheEntry->refCount);
+    if (cacheEntry->refCount == 0) {  // remove
+        deleteCacheEntry(cacheEntry);
+    }
+    umtx_unlock(&gCurrencyCacheMutex);
+}
+
+U_CAPI void
+uprv_parseCurrency(const char* locale,
+                   const icu::UnicodeString& text,
+                   icu::ParsePosition& pos,
+                   int8_t type,
+                   int32_t* partialMatchLen,
+                   UChar* result,
+                   UErrorCode& ec) {
+    U_NAMESPACE_USE
+    if (U_FAILURE(ec)) {
+        return;
+    }
+    CurrencyNameCacheEntry* cacheEntry = getCacheEntry(locale, ec);
+    if (U_FAILURE(ec)) {
+        return;
+    }
+
+    int32_t total_currency_name_count = cacheEntry->totalCurrencyNameCount;
+    CurrencyNameStruct* currencyNames = cacheEntry->currencyNames;
+    int32_t total_currency_symbol_count = cacheEntry->totalCurrencySymbolCount;
+    CurrencyNameStruct* currencySymbols = cacheEntry->currencySymbols;
+
+    int32_t start = pos.getIndex();
+
+    UChar inputText[MAX_CURRENCY_NAME_LEN];  
+    UChar upperText[MAX_CURRENCY_NAME_LEN];  
+    int32_t textLen = MIN(MAX_CURRENCY_NAME_LEN, text.length() - start);
+    text.extract(start, textLen, inputText);
+    UErrorCode ec1 = U_ZERO_ERROR;
+    textLen = u_strToUpper(upperText, MAX_CURRENCY_NAME_LEN, inputText, textLen, locale, &ec1);
+
+    // Make sure partialMatchLen is initialized
+    *partialMatchLen = 0;
+
+    int32_t max = 0;
+    int32_t matchIndex = -1;
+    // case in-sensitive comparision against currency names
+    searchCurrencyName(currencyNames, total_currency_name_count, 
+                       upperText, textLen, partialMatchLen, &max, &matchIndex);
+
+#ifdef UCURR_DEBUG
+    printf("search in names, max = %d, matchIndex = %d\n", max, matchIndex);
+#endif
+
+    int32_t maxInSymbol = 0;
+    int32_t matchIndexInSymbol = -1;
+    if (type != UCURR_LONG_NAME) {  // not name only
+        // case sensitive comparison against currency symbols and ISO code.
+        searchCurrencyName(currencySymbols, total_currency_symbol_count, 
+                           inputText, textLen,
+                           partialMatchLen,
+                           &maxInSymbol, &matchIndexInSymbol);
+    }
+
+#ifdef UCURR_DEBUG
+    printf("search in symbols, maxInSymbol = %d, matchIndexInSymbol = %d\n", maxInSymbol, matchIndexInSymbol);
+    if(matchIndexInSymbol != -1) {
+      printf("== ISO=%s\n", currencySymbols[matchIndexInSymbol].IsoCode);
+    }
+#endif
+
+    if (max >= maxInSymbol && matchIndex != -1) {
+        u_charsToUChars(currencyNames[matchIndex].IsoCode, result, 4);
+        pos.setIndex(start + max);
+    } else if (maxInSymbol >= max && matchIndexInSymbol != -1) {
+        u_charsToUChars(currencySymbols[matchIndexInSymbol].IsoCode, result, 4);
+        pos.setIndex(start + maxInSymbol);
+    }
+
+    // decrease reference count
+    releaseCacheEntry(cacheEntry);
+}
+
+void uprv_currencyLeads(const char* locale, icu::UnicodeSet& result, UErrorCode& ec) {
+    U_NAMESPACE_USE
+    if (U_FAILURE(ec)) {
+        return;
+    }
+    CurrencyNameCacheEntry* cacheEntry = getCacheEntry(locale, ec);
+    if (U_FAILURE(ec)) {
+        return;
+    }
+
+    for (int32_t i=0; i<cacheEntry->totalCurrencySymbolCount; i++) {
+        const CurrencyNameStruct& info = cacheEntry->currencySymbols[i];
+        UChar32 cp;
+        U16_GET(info.currencyName, 0, 0, info.currencyNameLen, cp);
+        result.add(cp);
+    }
+
+    for (int32_t i=0; i<cacheEntry->totalCurrencyNameCount; i++) {
+        const CurrencyNameStruct& info = cacheEntry->currencyNames[i];
+        UChar32 cp;
+        U16_GET(info.currencyName, 0, 0, info.currencyNameLen, cp);
+        result.add(cp);
+    }
+
+    // decrease reference count
+    releaseCacheEntry(cacheEntry);
+}
+
+
+/**
+ * Internal method.  Given a currency ISO code and a locale, return
+ * the "static" currency name.  This is usually the same as the
+ * UCURR_SYMBOL_NAME, but if the latter is a choice format, then the
+ * format is applied to the number 2.0 (to yield the more common
+ * plural) to return a static name.
+ *
+ * This is used for backward compatibility with old currency logic in
+ * DecimalFormat and DecimalFormatSymbols.
+ */
+U_CAPI void
+uprv_getStaticCurrencyName(const UChar* iso, const char* loc,
+                           icu::UnicodeString& result, UErrorCode& ec)
+{
+    U_NAMESPACE_USE
+
+    int32_t len;
+    const UChar* currname = ucurr_getName(iso, loc, UCURR_SYMBOL_NAME,
+                                          nullptr /* isChoiceFormat */, &len, &ec);
+    if (U_SUCCESS(ec)) {
+        result.setTo(currname, len);
+    }
+}
+
+U_CAPI int32_t U_EXPORT2
+ucurr_getDefaultFractionDigits(const UChar* currency, UErrorCode* ec) {
+    return ucurr_getDefaultFractionDigitsForUsage(currency,UCURR_USAGE_STANDARD,ec);
+}
+
+U_CAPI int32_t U_EXPORT2
+ucurr_getDefaultFractionDigitsForUsage(const UChar* currency, const UCurrencyUsage usage, UErrorCode* ec) {
+    int32_t fracDigits = 0;
+    if (U_SUCCESS(*ec)) {
+        switch (usage) {
+            case UCURR_USAGE_STANDARD:
+                fracDigits = (_findMetaData(currency, *ec))[0];
+                break;
+            case UCURR_USAGE_CASH:
+                fracDigits = (_findMetaData(currency, *ec))[2];
+                break;
+            default:
+                *ec = U_UNSUPPORTED_ERROR;
+        }
+    }
+    return fracDigits;
+}
+
+U_CAPI double U_EXPORT2
+ucurr_getRoundingIncrement(const UChar* currency, UErrorCode* ec) {
+    return ucurr_getRoundingIncrementForUsage(currency, UCURR_USAGE_STANDARD, ec);
+}
+
+U_CAPI double U_EXPORT2
+ucurr_getRoundingIncrementForUsage(const UChar* currency, const UCurrencyUsage usage, UErrorCode* ec) {
+    double result = 0.0;
+
+    const int32_t *data = _findMetaData(currency, *ec);
+    if (U_SUCCESS(*ec)) {
+        int32_t fracDigits;
+        int32_t increment;
+        switch (usage) {
+            case UCURR_USAGE_STANDARD:
+                fracDigits = data[0];
+                increment = data[1];
+                break;
+            case UCURR_USAGE_CASH:
+                fracDigits = data[2];
+                increment = data[3];
+                break;
+            default:
+                *ec = U_UNSUPPORTED_ERROR;
+                return result;
+        }
+
+        // If the meta data is invalid, return 0.0
+        if (fracDigits < 0 || fracDigits > MAX_POW10) {
+            *ec = U_INVALID_FORMAT_ERROR;
+        } else {
+            // A rounding value of 0 or 1 indicates no rounding.
+            if (increment >= 2) {
+                // Return (increment) / 10^(fracDigits).  The only actual rounding data,
+                // as of this writing, is CHF { 2, 5 }.
+                result = double(increment) / POW10[fracDigits];
+            }
+        }
+    }
+
+    return result;
+}
+
+U_CDECL_BEGIN
+
+typedef struct UCurrencyContext {
+    uint32_t currType; /* UCurrCurrencyType */
+    uint32_t listIdx;
+} UCurrencyContext;
+
+/*
+Please keep this list in alphabetical order.
+You can look at the CLDR supplemental data or ISO-4217 for the meaning of some
+of these items.
+ISO-4217: http://www.iso.org/iso/en/prods-services/popstds/currencycodeslist.html
+*/
+static const struct CurrencyList {
+    const char *currency;
+    uint32_t currType;
+} gCurrencyList[] = {
+    {"ADP", UCURR_COMMON|UCURR_DEPRECATED},
+    {"AED", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"AFA", UCURR_COMMON|UCURR_DEPRECATED},
+    {"AFN", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"ALK", UCURR_COMMON|UCURR_DEPRECATED},
+    {"ALL", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"AMD", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"ANG", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"AOA", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"AOK", UCURR_COMMON|UCURR_DEPRECATED},
+    {"AON", UCURR_COMMON|UCURR_DEPRECATED},
+    {"AOR", UCURR_COMMON|UCURR_DEPRECATED},
+    {"ARA", UCURR_COMMON|UCURR_DEPRECATED},
+    {"ARL", UCURR_COMMON|UCURR_DEPRECATED},
+    {"ARM", UCURR_COMMON|UCURR_DEPRECATED},
+    {"ARP", UCURR_COMMON|UCURR_DEPRECATED},
+    {"ARS", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"ATS", UCURR_COMMON|UCURR_DEPRECATED},
+    {"AUD", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"AWG", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"AZM", UCURR_COMMON|UCURR_DEPRECATED},
+    {"AZN", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"BAD", UCURR_COMMON|UCURR_DEPRECATED},
+    {"BAM", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"BAN", UCURR_COMMON|UCURR_DEPRECATED},
+    {"BBD", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"BDT", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"BEC", UCURR_UNCOMMON|UCURR_DEPRECATED},
+    {"BEF", UCURR_COMMON|UCURR_DEPRECATED},
+    {"BEL", UCURR_UNCOMMON|UCURR_DEPRECATED},
+    {"BGL", UCURR_COMMON|UCURR_DEPRECATED},
+    {"BGM", UCURR_COMMON|UCURR_DEPRECATED},
+    {"BGN", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"BGO", UCURR_COMMON|UCURR_DEPRECATED},
+    {"BHD", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"BIF", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"BMD", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"BND", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"BOB", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"BOL", UCURR_COMMON|UCURR_DEPRECATED},
+    {"BOP", UCURR_COMMON|UCURR_DEPRECATED},
+    {"BOV", UCURR_UNCOMMON|UCURR_NON_DEPRECATED},
+    {"BRB", UCURR_COMMON|UCURR_DEPRECATED},
+    {"BRC", UCURR_COMMON|UCURR_DEPRECATED},
+    {"BRE", UCURR_COMMON|UCURR_DEPRECATED},
+    {"BRL", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"BRN", UCURR_COMMON|UCURR_DEPRECATED},
+    {"BRR", UCURR_COMMON|UCURR_DEPRECATED},
+    {"BRZ", UCURR_COMMON|UCURR_DEPRECATED},
+    {"BSD", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"BTN", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"BUK", UCURR_COMMON|UCURR_DEPRECATED},
+    {"BWP", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"BYB", UCURR_COMMON|UCURR_DEPRECATED},
+    {"BYN", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"BYR", UCURR_COMMON|UCURR_DEPRECATED},
+    {"BZD", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"CAD", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"CDF", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"CHE", UCURR_UNCOMMON|UCURR_NON_DEPRECATED},
+    {"CHF", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"CHW", UCURR_UNCOMMON|UCURR_NON_DEPRECATED},
+    {"CLE", UCURR_COMMON|UCURR_DEPRECATED},
+    {"CLF", UCURR_UNCOMMON|UCURR_NON_DEPRECATED},
+    {"CLP", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"CNH", UCURR_UNCOMMON|UCURR_NON_DEPRECATED},
+    {"CNX", UCURR_UNCOMMON|UCURR_DEPRECATED},
+    {"CNY", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"COP", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"COU", UCURR_UNCOMMON|UCURR_NON_DEPRECATED},
+    {"CRC", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"CSD", UCURR_COMMON|UCURR_DEPRECATED},
+    {"CSK", UCURR_COMMON|UCURR_DEPRECATED},
+    {"CUC", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"CUP", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"CVE", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"CYP", UCURR_COMMON|UCURR_DEPRECATED},
+    {"CZK", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"DDM", UCURR_COMMON|UCURR_DEPRECATED},
+    {"DEM", UCURR_COMMON|UCURR_DEPRECATED},
+    {"DJF", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"DKK", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"DOP", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"DZD", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"ECS", UCURR_COMMON|UCURR_DEPRECATED},
+    {"ECV", UCURR_UNCOMMON|UCURR_DEPRECATED},
+    {"EEK", UCURR_COMMON|UCURR_DEPRECATED},
+    {"EGP", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"EQE", UCURR_COMMON|UCURR_DEPRECATED}, // questionable, remove?
+    {"ERN", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"ESA", UCURR_UNCOMMON|UCURR_DEPRECATED},
+    {"ESB", UCURR_UNCOMMON|UCURR_DEPRECATED},
+    {"ESP", UCURR_COMMON|UCURR_DEPRECATED},
+    {"ETB", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"EUR", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"FIM", UCURR_COMMON|UCURR_DEPRECATED},
+    {"FJD", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"FKP", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"FRF", UCURR_COMMON|UCURR_DEPRECATED},
+    {"GBP", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"GEK", UCURR_COMMON|UCURR_DEPRECATED},
+    {"GEL", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"GHC", UCURR_COMMON|UCURR_DEPRECATED},
+    {"GHS", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"GIP", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"GMD", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"GNF", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"GNS", UCURR_COMMON|UCURR_DEPRECATED},
+    {"GQE", UCURR_COMMON|UCURR_DEPRECATED},
+    {"GRD", UCURR_COMMON|UCURR_DEPRECATED},
+    {"GTQ", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"GWE", UCURR_COMMON|UCURR_DEPRECATED},
+    {"GWP", UCURR_COMMON|UCURR_DEPRECATED},
+    {"GYD", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"HKD", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"HNL", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"HRD", UCURR_COMMON|UCURR_DEPRECATED},
+    {"HRK", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"HTG", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"HUF", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"IDR", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"IEP", UCURR_COMMON|UCURR_DEPRECATED},
+    {"ILP", UCURR_COMMON|UCURR_DEPRECATED},
+    {"ILR", UCURR_COMMON|UCURR_DEPRECATED},
+    {"ILS", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"INR", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"IQD", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"IRR", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"ISJ", UCURR_COMMON|UCURR_DEPRECATED},
+    {"ISK", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"ITL", UCURR_COMMON|UCURR_DEPRECATED},
+    {"JMD", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"JOD", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"JPY", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"KES", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"KGS", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"KHR", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"KMF", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"KPW", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"KRH", UCURR_COMMON|UCURR_DEPRECATED},
+    {"KRO", UCURR_COMMON|UCURR_DEPRECATED},
+    {"KRW", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"KWD", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"KYD", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"KZT", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"LAK", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"LBP", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"LKR", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"LRD", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"LSL", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"LSM", UCURR_COMMON|UCURR_DEPRECATED}, // questionable, remove?
+    {"LTL", UCURR_COMMON|UCURR_DEPRECATED},
+    {"LTT", UCURR_COMMON|UCURR_DEPRECATED},
+    {"LUC", UCURR_UNCOMMON|UCURR_DEPRECATED},
+    {"LUF", UCURR_COMMON|UCURR_DEPRECATED},
+    {"LUL", UCURR_UNCOMMON|UCURR_DEPRECATED},
+    {"LVL", UCURR_COMMON|UCURR_DEPRECATED},
+    {"LVR", UCURR_COMMON|UCURR_DEPRECATED},
+    {"LYD", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"MAD", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"MAF", UCURR_COMMON|UCURR_DEPRECATED},
+    {"MCF", UCURR_COMMON|UCURR_DEPRECATED},
+    {"MDC", UCURR_COMMON|UCURR_DEPRECATED},
+    {"MDL", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"MGA", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"MGF", UCURR_COMMON|UCURR_DEPRECATED},
+    {"MKD", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"MKN", UCURR_COMMON|UCURR_DEPRECATED},
+    {"MLF", UCURR_COMMON|UCURR_DEPRECATED},
+    {"MMK", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"MNT", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"MOP", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"MRO", UCURR_COMMON|UCURR_DEPRECATED},
+    {"MRU", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"MTL", UCURR_COMMON|UCURR_DEPRECATED},
+    {"MTP", UCURR_COMMON|UCURR_DEPRECATED},
+    {"MUR", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"MVP", UCURR_COMMON|UCURR_DEPRECATED}, // questionable, remove?
+    {"MVR", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"MWK", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"MXN", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"MXP", UCURR_COMMON|UCURR_DEPRECATED},
+    {"MXV", UCURR_UNCOMMON|UCURR_NON_DEPRECATED},
+    {"MYR", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"MZE", UCURR_COMMON|UCURR_DEPRECATED},
+    {"MZM", UCURR_COMMON|UCURR_DEPRECATED},
+    {"MZN", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"NAD", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"NGN", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"NIC", UCURR_COMMON|UCURR_DEPRECATED},
+    {"NIO", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"NLG", UCURR_COMMON|UCURR_DEPRECATED},
+    {"NOK", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"NPR", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"NZD", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"OMR", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"PAB", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"PEI", UCURR_COMMON|UCURR_DEPRECATED},
+    {"PEN", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"PES", UCURR_COMMON|UCURR_DEPRECATED},
+    {"PGK", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"PHP", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"PKR", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"PLN", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"PLZ", UCURR_COMMON|UCURR_DEPRECATED},
+    {"PTE", UCURR_COMMON|UCURR_DEPRECATED},
+    {"PYG", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"QAR", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"RHD", UCURR_COMMON|UCURR_DEPRECATED},
+    {"ROL", UCURR_COMMON|UCURR_DEPRECATED},
+    {"RON", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"RSD", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"RUB", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"RUR", UCURR_COMMON|UCURR_DEPRECATED},
+    {"RWF", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"SAR", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"SBD", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"SCR", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"SDD", UCURR_COMMON|UCURR_DEPRECATED},
+    {"SDG", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"SDP", UCURR_COMMON|UCURR_DEPRECATED},
+    {"SEK", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"SGD", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"SHP", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"SIT", UCURR_COMMON|UCURR_DEPRECATED},
+    {"SKK", UCURR_COMMON|UCURR_DEPRECATED},
+    {"SLL", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"SOS", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"SRD", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"SRG", UCURR_COMMON|UCURR_DEPRECATED},
+    {"SSP", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"STD", UCURR_COMMON|UCURR_DEPRECATED},
+    {"STN", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"SUR", UCURR_COMMON|UCURR_DEPRECATED},
+    {"SVC", UCURR_COMMON|UCURR_DEPRECATED},
+    {"SYP", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"SZL", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"THB", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"TJR", UCURR_COMMON|UCURR_DEPRECATED},
+    {"TJS", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"TMM", UCURR_COMMON|UCURR_DEPRECATED},
+    {"TMT", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"TND", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"TOP", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"TPE", UCURR_COMMON|UCURR_DEPRECATED},
+    {"TRL", UCURR_COMMON|UCURR_DEPRECATED},
+    {"TRY", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"TTD", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"TWD", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"TZS", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"UAH", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"UAK", UCURR_COMMON|UCURR_DEPRECATED},
+    {"UGS", UCURR_COMMON|UCURR_DEPRECATED},
+    {"UGX", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"USD", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"USN", UCURR_UNCOMMON|UCURR_NON_DEPRECATED},
+    {"USS", UCURR_UNCOMMON|UCURR_NON_DEPRECATED},
+    {"UYI", UCURR_UNCOMMON|UCURR_NON_DEPRECATED},
+    {"UYP", UCURR_COMMON|UCURR_DEPRECATED},
+    {"UYU", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"UZS", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"VEB", UCURR_COMMON|UCURR_DEPRECATED},
+    {"VEF", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"VND", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"VNN", UCURR_COMMON|UCURR_DEPRECATED},
+    {"VUV", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"WST", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"XAF", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"XAG", UCURR_UNCOMMON|UCURR_NON_DEPRECATED},
+    {"XAU", UCURR_UNCOMMON|UCURR_NON_DEPRECATED},
+    {"XBA", UCURR_UNCOMMON|UCURR_NON_DEPRECATED},
+    {"XBB", UCURR_UNCOMMON|UCURR_NON_DEPRECATED},
+    {"XBC", UCURR_UNCOMMON|UCURR_NON_DEPRECATED},
+    {"XBD", UCURR_UNCOMMON|UCURR_NON_DEPRECATED},
+    {"XCD", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"XDR", UCURR_UNCOMMON|UCURR_NON_DEPRECATED},
+    {"XEU", UCURR_UNCOMMON|UCURR_DEPRECATED},
+    {"XFO", UCURR_UNCOMMON|UCURR_NON_DEPRECATED},
+    {"XFU", UCURR_UNCOMMON|UCURR_NON_DEPRECATED},
+    {"XOF", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"XPD", UCURR_UNCOMMON|UCURR_NON_DEPRECATED},
+    {"XPF", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"XPT", UCURR_UNCOMMON|UCURR_NON_DEPRECATED},
+    {"XRE", UCURR_UNCOMMON|UCURR_DEPRECATED},
+    {"XSU", UCURR_UNCOMMON|UCURR_NON_DEPRECATED},
+    {"XTS", UCURR_UNCOMMON|UCURR_NON_DEPRECATED},
+    {"XUA", UCURR_UNCOMMON|UCURR_NON_DEPRECATED},
+    {"XXX", UCURR_UNCOMMON|UCURR_NON_DEPRECATED},
+    {"YDD", UCURR_COMMON|UCURR_DEPRECATED},
+    {"YER", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"YUD", UCURR_COMMON|UCURR_DEPRECATED},
+    {"YUM", UCURR_COMMON|UCURR_DEPRECATED},
+    {"YUN", UCURR_COMMON|UCURR_DEPRECATED},
+    {"YUR", UCURR_COMMON|UCURR_DEPRECATED},
+    {"ZAL", UCURR_UNCOMMON|UCURR_DEPRECATED},
+    {"ZAR", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"ZMK", UCURR_COMMON|UCURR_DEPRECATED},
+    {"ZMW", UCURR_COMMON|UCURR_NON_DEPRECATED},
+    {"ZRN", UCURR_COMMON|UCURR_DEPRECATED},
+    {"ZRZ", UCURR_COMMON|UCURR_DEPRECATED},
+    {"ZWD", UCURR_COMMON|UCURR_DEPRECATED},
+    {"ZWL", UCURR_COMMON|UCURR_DEPRECATED},
+    {"ZWR", UCURR_COMMON|UCURR_DEPRECATED},
+    { NULL, 0 } // Leave here to denote the end of the list.
+};
+
+#define UCURR_MATCHES_BITMASK(variable, typeToMatch) \
+    ((typeToMatch) == UCURR_ALL || ((variable) & (typeToMatch)) == (typeToMatch))
+
+static int32_t U_CALLCONV
+ucurr_countCurrencyList(UEnumeration *enumerator, UErrorCode * /*pErrorCode*/) {
+    UCurrencyContext *myContext = (UCurrencyContext *)(enumerator->context);
+    uint32_t currType = myContext->currType;
+    int32_t count = 0;
+
+    /* Count the number of items matching the type we are looking for. */
+    for (int32_t idx = 0; gCurrencyList[idx].currency != NULL; idx++) {
+        if (UCURR_MATCHES_BITMASK(gCurrencyList[idx].currType, currType)) {
+            count++;
+        }
+    }
+    return count;
+}
+
+static const char* U_CALLCONV
+ucurr_nextCurrencyList(UEnumeration *enumerator,
+                        int32_t* resultLength,
+                        UErrorCode * /*pErrorCode*/)
+{
+    UCurrencyContext *myContext = (UCurrencyContext *)(enumerator->context);
+
+    /* Find the next in the list that matches the type we are looking for. */
+    while (myContext->listIdx < UPRV_LENGTHOF(gCurrencyList)-1) {
+        const struct CurrencyList *currItem = &gCurrencyList[myContext->listIdx++];
+        if (UCURR_MATCHES_BITMASK(currItem->currType, myContext->currType))
+        {
+            if (resultLength) {
+                *resultLength = 3; /* Currency codes are only 3 chars long */
+            }
+            return currItem->currency;
+        }
+    }
+    /* We enumerated too far. */
+    if (resultLength) {
+        *resultLength = 0;
+    }
+    return NULL;
+}
+
+static void U_CALLCONV
+ucurr_resetCurrencyList(UEnumeration *enumerator, UErrorCode * /*pErrorCode*/) {
+    ((UCurrencyContext *)(enumerator->context))->listIdx = 0;
+}
+
+static void U_CALLCONV
+ucurr_closeCurrencyList(UEnumeration *enumerator) {
+    uprv_free(enumerator->context);
+    uprv_free(enumerator);
+}
+
+static void U_CALLCONV
+ucurr_createCurrencyList(UHashtable *isoCodes, UErrorCode* status){
+    UErrorCode localStatus = U_ZERO_ERROR;
+
+    // Look up the CurrencyMap element in the root bundle.
+    UResourceBundle *rb = ures_openDirect(U_ICUDATA_CURR, CURRENCY_DATA, &localStatus);
+    UResourceBundle *currencyMapArray = ures_getByKey(rb, CURRENCY_MAP, rb, &localStatus);
+
+    if (U_SUCCESS(localStatus)) {
+        // process each entry in currency map 
+        for (int32_t i=0; i<ures_getSize(currencyMapArray); i++) {
+            // get the currency resource
+            UResourceBundle *currencyArray = ures_getByIndex(currencyMapArray, i, NULL, &localStatus);
+            // process each currency 
+            if (U_SUCCESS(localStatus)) {
+                for (int32_t j=0; j<ures_getSize(currencyArray); j++) {
+                    // get the currency resource
+                    UResourceBundle *currencyRes = ures_getByIndex(currencyArray, j, NULL, &localStatus);
+                    IsoCodeEntry *entry = (IsoCodeEntry*)uprv_malloc(sizeof(IsoCodeEntry));
+                    if (entry == NULL) {
+                        *status = U_MEMORY_ALLOCATION_ERROR;
+                        return;
+                    }
+
+                    // get the ISO code
+                    int32_t isoLength = 0;
+                    UResourceBundle *idRes = ures_getByKey(currencyRes, "id", NULL, &localStatus);
+                    if (idRes == NULL) {
+                        continue;
+                    }
+                    const UChar *isoCode = ures_getString(idRes, &isoLength, &localStatus);
+
+                    // get from date
+                    UDate fromDate = U_DATE_MIN;
+                    UResourceBundle *fromRes = ures_getByKey(currencyRes, "from", NULL, &localStatus);
+
+                    if (U_SUCCESS(localStatus)) {
+                        int32_t fromLength = 0;
+                        const int32_t *fromArray = ures_getIntVector(fromRes, &fromLength, &localStatus);
+                        int64_t currDate64 = (int64_t)fromArray[0] << 32;
+                        currDate64 |= ((int64_t)fromArray[1] & (int64_t)INT64_C(0x00000000FFFFFFFF));
+                        fromDate = (UDate)currDate64;
+                    }
+                    ures_close(fromRes);
+
+                    // get to date
+                    UDate toDate = U_DATE_MAX;
+                    localStatus = U_ZERO_ERROR;
+                    UResourceBundle *toRes = ures_getByKey(currencyRes, "to", NULL, &localStatus);
+
+                    if (U_SUCCESS(localStatus)) {
+                        int32_t toLength = 0;
+                        const int32_t *toArray = ures_getIntVector(toRes, &toLength, &localStatus);
+                        int64_t currDate64 = (int64_t)toArray[0] << 32;
+                        currDate64 |= ((int64_t)toArray[1] & (int64_t)INT64_C(0x00000000FFFFFFFF));
+                        toDate = (UDate)currDate64;
+                    }
+                    ures_close(toRes);
+
+                    ures_close(idRes);
+                    ures_close(currencyRes);
+
+                    entry->isoCode = isoCode;
+                    entry->from = fromDate;
+                    entry->to = toDate;
+
+                    localStatus = U_ZERO_ERROR;
+                    uhash_put(isoCodes, (UChar *)isoCode, entry, &localStatus);
+                }
+            } else {
+                *status = localStatus;
+            }
+            ures_close(currencyArray);
+        }
+    } else {
+        *status = localStatus;
+    }
+
+    ures_close(currencyMapArray);
+}
+
+static const UEnumeration gEnumCurrencyList = {
+    NULL,
+    NULL,
+    ucurr_closeCurrencyList,
+    ucurr_countCurrencyList,
+    uenum_unextDefault,
+    ucurr_nextCurrencyList,
+    ucurr_resetCurrencyList
+};
+U_CDECL_END
+
+
+static void U_CALLCONV initIsoCodes(UErrorCode &status) {
+    U_ASSERT(gIsoCodes == NULL);
+    ucln_common_registerCleanup(UCLN_COMMON_CURRENCY, currency_cleanup);
+
+    UHashtable *isoCodes = uhash_open(uhash_hashUChars, uhash_compareUChars, NULL, &status);
+    if (U_FAILURE(status)) {
+        return;
+    }
+    uhash_setValueDeleter(isoCodes, deleteIsoCodeEntry);
+
+    ucurr_createCurrencyList(isoCodes, &status);
+    if (U_FAILURE(status)) {
+        uhash_close(isoCodes);
+        return;
+    }
+    gIsoCodes = isoCodes;  // Note: gIsoCodes is const. Once set up here it is never altered,
+                           //       and read only access is safe without synchronization.
+}
+
+static void populateCurrSymbolsEquiv(icu::Hashtable *hash, UErrorCode &status) {
+    if (U_FAILURE(status)) { return; }
+    for (auto& entry : unisets::kCurrencyEntries) {
+        UnicodeString exemplar(entry.exemplar);
+        const UnicodeSet* set = unisets::get(entry.key);
+        if (set == nullptr) { return; }
+        UnicodeSetIterator it(*set);
+        while (it.next()) {
+            UnicodeString value = it.getString();
+            if (value == exemplar) {
+                // No need to mark the exemplar character as an equivalent
+                continue;
+            }
+            makeEquivalent(exemplar, value, hash, status);
+            if (U_FAILURE(status)) { return; }
+        }
+    }
+}
+
+static void U_CALLCONV initCurrSymbolsEquiv() {
+    U_ASSERT(gCurrSymbolsEquiv == NULL);
+    UErrorCode status = U_ZERO_ERROR;
+    ucln_common_registerCleanup(UCLN_COMMON_CURRENCY, currency_cleanup);
+    icu::Hashtable *temp = new icu::Hashtable(status);
+    if (temp == NULL) {
+        return;
+    }
+    if (U_FAILURE(status)) {
+        delete temp;
+        return;
+    }
+    temp->setValueDeleter(deleteUnicode);
+    populateCurrSymbolsEquiv(temp, status);
+    if (U_FAILURE(status)) {
+        delete temp;
+        return;
+    }
+    gCurrSymbolsEquiv = temp;
+}
+
+U_CAPI UBool U_EXPORT2
+ucurr_isAvailable(const UChar* isoCode, UDate from, UDate to, UErrorCode* eErrorCode) {
+    umtx_initOnce(gIsoCodesInitOnce, &initIsoCodes, *eErrorCode);
+    if (U_FAILURE(*eErrorCode)) {
+        return FALSE;
+    }
+
+    IsoCodeEntry* result = (IsoCodeEntry *) uhash_get(gIsoCodes, isoCode);
+    if (result == NULL) {
+        return FALSE;
+    } else if (from > to) {
+        *eErrorCode = U_ILLEGAL_ARGUMENT_ERROR;
+        return FALSE;
+    } else if  ((from > result->to) || (to < result->from)) {
+        return FALSE;
+    }
+    return TRUE;
+}
+
+static const icu::Hashtable* getCurrSymbolsEquiv() {
+    umtx_initOnce(gCurrSymbolsEquivInitOnce, &initCurrSymbolsEquiv);
+    return gCurrSymbolsEquiv;
+}
+
+U_CAPI UEnumeration * U_EXPORT2
+ucurr_openISOCurrencies(uint32_t currType, UErrorCode *pErrorCode) {
+    UEnumeration *myEnum = NULL;
+    UCurrencyContext *myContext;
+
+    myEnum = (UEnumeration*)uprv_malloc(sizeof(UEnumeration));
+    if (myEnum == NULL) {
+        *pErrorCode = U_MEMORY_ALLOCATION_ERROR;
+        return NULL;
+    }
+    uprv_memcpy(myEnum, &gEnumCurrencyList, sizeof(UEnumeration));
+    myContext = (UCurrencyContext*)uprv_malloc(sizeof(UCurrencyContext));
+    if (myContext == NULL) {
+        *pErrorCode = U_MEMORY_ALLOCATION_ERROR;
+        uprv_free(myEnum);
+        return NULL;
+    }
+    myContext->currType = currType;
+    myContext->listIdx = 0;
+    myEnum->context = myContext;
+    return myEnum;
+}
+
+U_CAPI int32_t U_EXPORT2
+ucurr_countCurrencies(const char* locale, 
+                 UDate date, 
+                 UErrorCode* ec)
+{
+    int32_t currCount = 0;
+
+    if (ec != NULL && U_SUCCESS(*ec)) 
+    {
+        // local variables
+        UErrorCode localStatus = U_ZERO_ERROR;
+        char id[ULOC_FULLNAME_CAPACITY];
+
+        // get country or country_variant in `id'
+        idForLocale(locale, id, sizeof(id), ec);
+
+        if (U_FAILURE(*ec))
+        {
+            return 0;
+        }
+
+        // Remove variants, which is only needed for registration.
+        char *idDelim = strchr(id, VAR_DELIM);
+        if (idDelim)
+        {
+            idDelim[0] = 0;
+        }
+
+        // Look up the CurrencyMap element in the root bundle.
+        UResourceBundle *rb = ures_openDirect(U_ICUDATA_CURR, CURRENCY_DATA, &localStatus);
+        UResourceBundle *cm = ures_getByKey(rb, CURRENCY_MAP, rb, &localStatus);
+
+        // Using the id derived from the local, get the currency data
+        UResourceBundle *countryArray = ures_getByKey(rb, id, cm, &localStatus);
+
+        // process each currency to see which one is valid for the given date
+        if (U_SUCCESS(localStatus))
+        {
+            for (int32_t i=0; i<ures_getSize(countryArray); i++)
+            {
+                // get the currency resource
+                UResourceBundle *currencyRes = ures_getByIndex(countryArray, i, NULL, &localStatus);
+
+                // get the from date
+                int32_t fromLength = 0;
+                UResourceBundle *fromRes = ures_getByKey(currencyRes, "from", NULL, &localStatus);
+                const int32_t *fromArray = ures_getIntVector(fromRes, &fromLength, &localStatus);
+
+                int64_t currDate64 = (int64_t)fromArray[0] << 32;
+                currDate64 |= ((int64_t)fromArray[1] & (int64_t)INT64_C(0x00000000FFFFFFFF));
+                UDate fromDate = (UDate)currDate64;
+
+                if (ures_getSize(currencyRes)> 2)
+                {
+                    int32_t toLength = 0;
+                    UResourceBundle *toRes = ures_getByKey(currencyRes, "to", NULL, &localStatus);
+                    const int32_t *toArray = ures_getIntVector(toRes, &toLength, &localStatus);
+
+                    currDate64 = (int64_t)toArray[0] << 32;
+                    currDate64 |= ((int64_t)toArray[1] & (int64_t)INT64_C(0x00000000FFFFFFFF));
+                    UDate toDate = (UDate)currDate64;
+
+                    if ((fromDate <= date) && (date < toDate))
+                    {
+                        currCount++;
+                    }
+
+                    ures_close(toRes);
+                }
+                else
+                {
+                    if (fromDate <= date)
+                    {
+                        currCount++;
+                    }
+                }
+
+                // close open resources
+                ures_close(currencyRes);
+                ures_close(fromRes);
+
+            } // end For loop
+        } // end if (U_SUCCESS(localStatus))
+
+        ures_close(countryArray);
+
+        // Check for errors
+        if (*ec == U_ZERO_ERROR || localStatus != U_ZERO_ERROR)
+        {
+            // There is nothing to fallback to. 
+            // Report the failure/warning if possible.
+            *ec = localStatus;
+        }
+
+        if (U_SUCCESS(*ec))
+        {
+            // no errors
+            return currCount;
+        }
+
+    }
+
+    // If we got here, either error code is invalid or
+    // some argument passed is no good.
+    return 0;
+}
+
+U_CAPI int32_t U_EXPORT2 
+ucurr_forLocaleAndDate(const char* locale, 
+                UDate date, 
+                int32_t index,
+                UChar* buff, 
+                int32_t buffCapacity, 
+                UErrorCode* ec)
+{
+    int32_t resLen = 0;
+	int32_t currIndex = 0;
+    const UChar* s = NULL;
+
+    if (ec != NULL && U_SUCCESS(*ec))
+    {
+        // check the arguments passed
+        if ((buff && buffCapacity) || !buffCapacity )
+        {
+            // local variables
+            UErrorCode localStatus = U_ZERO_ERROR;
+            char id[ULOC_FULLNAME_CAPACITY];
+
+            // get country or country_variant in `id'
+            idForLocale(locale, id, sizeof(id), ec);
+            if (U_FAILURE(*ec))
+            {
+                return 0;
+            }
+
+            // Remove variants, which is only needed for registration.
+            char *idDelim = strchr(id, VAR_DELIM);
+            if (idDelim)
+            {
+                idDelim[0] = 0;
+            }
+
+            // Look up the CurrencyMap element in the root bundle.
+            UResourceBundle *rb = ures_openDirect(U_ICUDATA_CURR, CURRENCY_DATA, &localStatus);
+            UResourceBundle *cm = ures_getByKey(rb, CURRENCY_MAP, rb, &localStatus);
+
+            // Using the id derived from the local, get the currency data
+            UResourceBundle *countryArray = ures_getByKey(rb, id, cm, &localStatus);
+
+            // process each currency to see which one is valid for the given date
+            bool matchFound = false;
+            if (U_SUCCESS(localStatus))
+            {
+                if ((index <= 0) || (index> ures_getSize(countryArray)))
+                {
+                    // requested index is out of bounds
+                    ures_close(countryArray);
+                    return 0;
+                }
+
+                for (int32_t i=0; i<ures_getSize(countryArray); i++)
+                {
+                    // get the currency resource
+                    UResourceBundle *currencyRes = ures_getByIndex(countryArray, i, NULL, &localStatus);
+                    s = ures_getStringByKey(currencyRes, "id", &resLen, &localStatus);
+
+                    // get the from date
+                    int32_t fromLength = 0;
+                    UResourceBundle *fromRes = ures_getByKey(currencyRes, "from", NULL, &localStatus);
+                    const int32_t *fromArray = ures_getIntVector(fromRes, &fromLength, &localStatus);
+
+                    int64_t currDate64 = (int64_t)fromArray[0] << 32;
+                    currDate64 |= ((int64_t)fromArray[1] & (int64_t)INT64_C(0x00000000FFFFFFFF));
+                    UDate fromDate = (UDate)currDate64;
+
+                    if (ures_getSize(currencyRes)> 2)
+                    {
+                        int32_t toLength = 0;
+                        UResourceBundle *toRes = ures_getByKey(currencyRes, "to", NULL, &localStatus);
+                        const int32_t *toArray = ures_getIntVector(toRes, &toLength, &localStatus);
+
+                        currDate64 = (int64_t)toArray[0] << 32;
+                        currDate64 |= ((int64_t)toArray[1] & (int64_t)INT64_C(0x00000000FFFFFFFF));
+                        UDate toDate = (UDate)currDate64;
+
+                        if ((fromDate <= date) && (date < toDate))
+                        {
+                            currIndex++;
+                            if (currIndex == index)
+                            {
+                                matchFound = true;
+                            }
+                        }
+
+                        ures_close(toRes);
+                    }
+                    else
+                    {
+                        if (fromDate <= date)
+                        {
+                            currIndex++;
+                            if (currIndex == index)
+                            {
+                                matchFound = true;
+                            }
+                        }
+                    }
+
+                    // close open resources
+                    ures_close(currencyRes);
+                    ures_close(fromRes);
+
+                    // check for loop exit
+                    if (matchFound)
+                    {
+                        break;
+                    }
+
+                } // end For loop
+            }
+
+            ures_close(countryArray);
+
+            // Check for errors
+            if (*ec == U_ZERO_ERROR || localStatus != U_ZERO_ERROR)
+            {
+                // There is nothing to fallback to. 
+                // Report the failure/warning if possible.
+                *ec = localStatus;
+            }
+
+            if (U_SUCCESS(*ec))
+            {
+                // no errors
+                if((buffCapacity> resLen) && matchFound)
+                {
+                    // write out the currency value
+                    u_strcpy(buff, s);
+                }
+                else
+                {
+                    return 0;
+                }
+            }
+
+            // return null terminated currency string
+            return u_terminateUChars(buff, buffCapacity, resLen, ec);
+        }
+        else
+        {
+            // illegal argument encountered
+            *ec = U_ILLEGAL_ARGUMENT_ERROR;
+        }
+
+    }
+
+    // If we got here, either error code is invalid or
+    // some argument passed is no good.
+    return resLen;
+}
+
+static const UEnumeration defaultKeywordValues = {
+    NULL,
+    NULL,
+    ulist_close_keyword_values_iterator,
+    ulist_count_keyword_values,
+    uenum_unextDefault,
+    ulist_next_keyword_value, 
+    ulist_reset_keyword_values_iterator
+};
+
+U_CAPI UEnumeration *U_EXPORT2 ucurr_getKeywordValuesForLocale(const char *key, const char *locale, UBool commonlyUsed, UErrorCode* status) {
+    // Resolve region
+    char prefRegion[ULOC_COUNTRY_CAPACITY];
+    ulocimp_getRegionForSupplementalData(locale, TRUE, prefRegion, sizeof(prefRegion), status);
+    
+    // Read value from supplementalData
+    UList *values = ulist_createEmptyList(status);
+    UList *otherValues = ulist_createEmptyList(status);
+    UEnumeration *en = (UEnumeration *)uprv_malloc(sizeof(UEnumeration));
+    if (U_FAILURE(*status) || en == NULL) {
+        if (en == NULL) {
+            *status = U_MEMORY_ALLOCATION_ERROR;
+        } else {
+            uprv_free(en);
+        }
+        ulist_deleteList(values);
+        ulist_deleteList(otherValues);
+        return NULL;
+    }
+    memcpy(en, &defaultKeywordValues, sizeof(UEnumeration));
+    en->context = values;
+    
+    UResourceBundle *bundle = ures_openDirect(U_ICUDATA_CURR, "supplementalData", status);
+    ures_getByKey(bundle, "CurrencyMap", bundle, status);
+    UResourceBundle bundlekey, regbndl, curbndl, to;
+    ures_initStackObject(&bundlekey);
+    ures_initStackObject(&regbndl);
+    ures_initStackObject(&curbndl);
+    ures_initStackObject(&to);
+    
+    while (U_SUCCESS(*status) && ures_hasNext(bundle)) {
+        ures_getNextResource(bundle, &bundlekey, status);
+        if (U_FAILURE(*status)) {
+            break;
+        }
+        const char *region = ures_getKey(&bundlekey);
+        UBool isPrefRegion = uprv_strcmp(region, prefRegion) == 0 ? TRUE : FALSE;
+        if (!isPrefRegion && commonlyUsed) {
+            // With commonlyUsed=true, we do not put
+            // currencies for other regions in the
+            // result list.
+            continue;
+        }
+        ures_getByKey(bundle, region, &regbndl, status);
+        if (U_FAILURE(*status)) {
+            break;
+        }
+        while (U_SUCCESS(*status) && ures_hasNext(&regbndl)) {
+            ures_getNextResource(&regbndl, &curbndl, status);
+            if (ures_getType(&curbndl) != URES_TABLE) {
+                // Currently, an empty ARRAY is mixed in.
+                continue;
+            }
+            char *curID = (char *)uprv_malloc(sizeof(char) * ULOC_KEYWORDS_CAPACITY);
+            int32_t curIDLength = ULOC_KEYWORDS_CAPACITY;
+            if (curID == NULL) {
+                *status = U_MEMORY_ALLOCATION_ERROR;
+                break;
+            }
+
+#if U_CHARSET_FAMILY==U_ASCII_FAMILY
+            ures_getUTF8StringByKey(&curbndl, "id", curID, &curIDLength, TRUE, status);
+            /* optimize - use the utf-8 string */
+#else
+            {
+                       const UChar* defString = ures_getStringByKey(&curbndl, "id", &curIDLength, status);
+                       if(U_SUCCESS(*status)) {
+			   if(curIDLength+1 > ULOC_KEYWORDS_CAPACITY) {
+				*status = U_BUFFER_OVERFLOW_ERROR;
+			   } else {
+                           	u_UCharsToChars(defString, curID, curIDLength+1);
+			   }
+                       }
+            }
+#endif	
+
+            if (U_FAILURE(*status)) {
+                break;
+            }
+            UBool hasTo = FALSE;
+            ures_getByKey(&curbndl, "to", &to, status);
+            if (U_FAILURE(*status)) {
+                // Do nothing here...
+                *status = U_ZERO_ERROR;
+            } else {
+                hasTo = TRUE;
+            }
+            if (isPrefRegion && !hasTo && !ulist_containsString(values, curID, (int32_t)uprv_strlen(curID))) {
+                // Currently active currency for the target country
+                ulist_addItemEndList(values, curID, TRUE, status);
+            } else if (!ulist_containsString(otherValues, curID, (int32_t)uprv_strlen(curID)) && !commonlyUsed) {
+                ulist_addItemEndList(otherValues, curID, TRUE, status);
+            } else {
+                uprv_free(curID);
+            }
+        }
+        
+    }
+    if (U_SUCCESS(*status)) {
+        if (commonlyUsed) {
+            if (ulist_getListSize(values) == 0) {
+                // This could happen if no valid region is supplied in the input
+                // locale. In this case, we use the CLDR's default.
+                uenum_close(en);
+                en = ucurr_getKeywordValuesForLocale(key, "und", TRUE, status);
+            }
+        } else {
+            // Consolidate the list
+            char *value = NULL;
+            ulist_resetList(otherValues);
+            while ((value = (char *)ulist_getNext(otherValues)) != NULL) {
+                if (!ulist_containsString(values, value, (int32_t)uprv_strlen(value))) {
+                    char *tmpValue = (char *)uprv_malloc(sizeof(char) * ULOC_KEYWORDS_CAPACITY);
+                    uprv_memcpy(tmpValue, value, uprv_strlen(value) + 1);
+                    ulist_addItemEndList(values, tmpValue, TRUE, status);
+                    if (U_FAILURE(*status)) {
+                        break;
+                    }
+                }
+            }
+        }
+        
+        ulist_resetList((UList *)(en->context));
+    } else {
+        ulist_deleteList(values);
+        uprv_free(en);
+        values = NULL;
+        en = NULL;
+    }
+    ures_close(&to);
+    ures_close(&curbndl);
+    ures_close(&regbndl);
+    ures_close(&bundlekey);
+    ures_close(bundle);
+    
+    ulist_deleteList(otherValues);
+    
+    return en;
+}
+
+
+U_CAPI int32_t U_EXPORT2
+ucurr_getNumericCode(const UChar* currency) {
+    int32_t code = 0;
+    if (currency && u_strlen(currency) == ISO_CURRENCY_CODE_LENGTH) {
+        UErrorCode status = U_ZERO_ERROR;
+
+        UResourceBundle *bundle = ures_openDirect(0, "currencyNumericCodes", &status);
+        ures_getByKey(bundle, "codeMap", bundle, &status);
+        if (U_SUCCESS(status)) {
+            char alphaCode[ISO_CURRENCY_CODE_LENGTH+1];
+            myUCharsToChars(alphaCode, currency);
+            T_CString_toUpperCase(alphaCode);
+            ures_getByKey(bundle, alphaCode, bundle, &status);
+            int tmpCode = ures_getInt(bundle, &status);
+            if (U_SUCCESS(status)) {
+                code = tmpCode;
+            }
+        }
+        ures_close(bundle);
+    }
+    return code;
+}
+#endif /* #if !UCONFIG_NO_FORMATTING */
+
+//eof
diff --git a/src/third_party/icu/source/common/ucurrimp.h b/src/third_party/icu/source/common/ucurrimp.h
new file mode 100644
index 0000000..6d95882
--- /dev/null
+++ b/src/third_party/icu/source/common/ucurrimp.h
@@ -0,0 +1,78 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+/*
+**********************************************************************
+* Copyright (c) 2002-2016, International Business Machines
+* Corporation and others.  All Rights Reserved.
+**********************************************************************
+*/
+
+#ifndef _UCURR_IMP_H_
+#define _UCURR_IMP_H_
+
+#include "unicode/utypes.h"
+#include "unicode/unistr.h"
+#include "unicode/parsepos.h"
+#include "unicode/uniset.h"
+
+/**
+ * Internal method.  Given a currency ISO code and a locale, return
+ * the "static" currency name.  This is usually the same as the
+ * UCURR_SYMBOL_NAME, but if the latter is a choice format, then the
+ * format is applied to the number 2.0 (to yield the more common
+ * plural) to return a static name.
+ *
+ * This is used for backward compatibility with old currency logic in
+ * DecimalFormat and DecimalFormatSymbols.
+ */
+U_CAPI void
+uprv_getStaticCurrencyName(const UChar* iso, const char* loc,
+                           icu::UnicodeString& result, UErrorCode& ec);
+
+/**
+ * Attempt to parse the given string as a currency, either as a
+ * display name in the given locale, or as a 3-letter ISO 4217
+ * code.  If multiple display names match, then the longest one is
+ * selected.  If both a display name and a 3-letter ISO code
+ * match, then the display name is preferred, unless it's length
+ * is less than 3.
+ *
+ * The parameters must not be NULL.
+ *
+ * @param locale the locale of the display names to match
+ * @param text the text to parse
+ * @param pos input-output position; on input, the position within
+ * text to match; must have 0 <= pos.getIndex() < text.length();
+ * on output, the position after the last matched character. If
+ * the parse fails, the position in unchanged upon output.
+ * @param type currency type to parse against, LONG_NAME only or not
+ * @param partialMatchLen The length of the longest matching prefix;
+ * this may be nonzero even if no full currency was matched.
+ * @return the ISO 4217 code, as a string, of the best match, or
+ * null if there is no match
+ *
+ * @internal
+ */
+U_CAPI void
+uprv_parseCurrency(const char* locale,
+                   const icu::UnicodeString& text,
+                   icu::ParsePosition& pos,
+                   int8_t type,
+                   int32_t* partialMatchLen,
+                   UChar* result,
+                   UErrorCode& ec);
+
+/**
+ * Puts all possible first-characters of a currency into the
+ * specified UnicodeSet.
+ *
+ * @param locale the locale of the display names of interest
+ * @param result the UnicodeSet to which to add the starting characters
+ */
+void uprv_currencyLeads(const char* locale, icu::UnicodeSet& result, UErrorCode& ec);
+
+
+
+#endif /* #ifndef _UCURR_IMP_H_ */
+
+//eof
diff --git a/src/third_party/icu/source/common/udata.cpp b/src/third_party/icu/source/common/udata.cpp
index 006e3b2..622e64d 100644
--- a/src/third_party/icu/source/common/udata.cpp
+++ b/src/third_party/icu/source/common/udata.cpp
@@ -1,12 +1,14 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
-*   Copyright (C) 1999-2015, International Business Machines
+*   Copyright (C) 1999-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *
 ******************************************************************************
 *   file name:  udata.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -14,8 +16,11 @@
 *   created by: Markus W. Scherer
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
+
 #include "unicode/utypes.h"  /* U_PLATFORM etc. */
 
 #ifdef __GNUC__
@@ -33,6 +38,7 @@
 #include "cstring.h"
 #include "mutex.h"
 #include "putilimp.h"
+#include "restrace.h"
 #include "uassert.h"
 #include "ucln_cmn.h"
 #include "ucmndata.h"
@@ -72,19 +78,18 @@
 
 #if defined(STARBOARD)
 #include "starboard/client_porting/poem/stdio_poem.h"
-#include "starboard/client_porting/poem/string_poem.h"
 #else
 #if defined(UDATA_DEBUG)
 #   include <stdio.h>
 #endif
-#endif
+#endif  // defined(STARBOARD)
 
 U_NAMESPACE_USE
 
 /*
  *  Forward declarations
  */
-static UDataMemory *udata_findCachedData(const char *path);
+static UDataMemory *udata_findCachedData(const char *path, UErrorCode &err);
 
 /***********************************************************************
 *
@@ -115,8 +120,13 @@
 static UHashtable  *gCommonDataCache = NULL;  /* Global hash table of opened ICU data files.  */
 static icu::UInitOnce gCommonDataCacheInitOnce = U_INITONCE_INITIALIZER;
 
+#if !defined(ICU_DATA_DIR_WINDOWS)
 static UDataFileAccess  gDataFileAccess = UDATA_DEFAULT_ACCESS;  // Access not synchronized.
                                                                  // Modifying is documented as thread-unsafe.
+#else
+// If we are using the Windows data directory, then look in one spot only.
+static UDataFileAccess  gDataFileAccess = UDATA_NO_FILES;
+#endif
 
 static UBool U_CALLCONV
 udata_cleanup(void)
@@ -139,13 +149,13 @@
 }
 
 static UBool U_CALLCONV
-findCommonICUDataByName(const char *inBasename)
+findCommonICUDataByName(const char *inBasename, UErrorCode &err)
 {
     UBool found = FALSE;
     int32_t i;
 
-    UDataMemory  *pData = udata_findCachedData(inBasename);
-    if (pData == NULL)
+    UDataMemory  *pData = udata_findCachedData(inBasename, err);
+    if (U_FAILURE(err) || pData == NULL)
         return FALSE;
 
     {
@@ -207,6 +217,8 @@
     return didUpdate;
 }
 
+#if !defined(ICU_DATA_DIR_WINDOWS)
+
 static UBool
 setCommonICUDataPointer(const void *pData, UBool /*warn*/, UErrorCode *pErrorCode) {
     UDataMemory tData;
@@ -216,6 +228,8 @@
     return setCommonICUData(&tData, FALSE, pErrorCode);
 }
 
+#endif
+
 static const char *
 findBasename(const char *path) {
     const char *basename=uprv_strrchr(path, U_FILE_SEP_CHAR);
@@ -275,40 +289,41 @@
     uprv_free(pDCEl);                  /* delete 'this'          */
 }
 
-static void udata_initHashTable() {
-    UErrorCode err = U_ZERO_ERROR;
+static void U_CALLCONV udata_initHashTable(UErrorCode &err) {
     U_ASSERT(gCommonDataCache == NULL);
     gCommonDataCache = uhash_open(uhash_hashChars, uhash_compareChars, NULL, &err);
     if (U_FAILURE(err)) {
-        // TODO: handle errors better.
-        gCommonDataCache = NULL;
+       return;
     }
-    if (gCommonDataCache != NULL) {
-        uhash_setValueDeleter(gCommonDataCache, DataCacheElement_deleter);
-        ucln_common_registerCleanup(UCLN_COMMON_UDATA, udata_cleanup);
-    }
+    U_ASSERT(gCommonDataCache != NULL);
+    uhash_setValueDeleter(gCommonDataCache, DataCacheElement_deleter);
+    ucln_common_registerCleanup(UCLN_COMMON_UDATA, udata_cleanup);
 }
 
  /*   udata_getCacheHashTable()
   *     Get the hash table used to store the data cache entries.
   *     Lazy create it if it doesn't yet exist.
   */
-static UHashtable *udata_getHashTable() {
-    umtx_initOnce(gCommonDataCacheInitOnce, &udata_initHashTable);
+static UHashtable *udata_getHashTable(UErrorCode &err) {
+    umtx_initOnce(gCommonDataCacheInitOnce, &udata_initHashTable, err);
     return gCommonDataCache;
 }
 
 
 
-static UDataMemory *udata_findCachedData(const char *path)
+static UDataMemory *udata_findCachedData(const char *path, UErrorCode &err)
 {
     UHashtable        *htable;
     UDataMemory       *retVal = NULL;
     DataCacheElement  *el;
     const char        *baseName;
 
+    htable = udata_getHashTable(err);
+    if (U_FAILURE(err)) {
+        return NULL;
+    }
+
     baseName = findBasename(path);   /* Cache remembers only the base name, not the full path. */
-    htable = udata_getHashTable();
     umtx_lock(NULL);
     el = (DataCacheElement *)uhash_get(htable, baseName);
     umtx_unlock(NULL);
@@ -316,7 +331,7 @@
         retVal = el->item;
     }
 #ifdef UDATA_DEBUG
-    fprintf(stderr, "Cache: [%s] -> %p\n", baseName, retVal);
+    fprintf(stderr, "Cache: [%s] -> %p\n", baseName, (void*) retVal);
 #endif
     return retVal;
 }
@@ -330,6 +345,7 @@
     DataCacheElement *oldValue = NULL;
     UErrorCode        subErr = U_ZERO_ERROR;
 
+    htable = udata_getHashTable(*pErr);
     if (U_FAILURE(*pErr)) {
         return NULL;
     }
@@ -362,7 +378,6 @@
 
     /* Stick the new DataCacheElement into the hash table.
     */
-    htable = udata_getHashTable();
     umtx_lock(NULL);
     oldValue = (DataCacheElement *)uhash_get(htable, path);
     if (oldValue != NULL) {
@@ -379,7 +394,7 @@
 
 #ifdef UDATA_DEBUG
     fprintf(stderr, "Cache: [%s] <<< %p : %s. vFunc=%p\n", newElement->name, 
-    newElement->item, u_errorName(subErr), newElement->item->vFuncs);
+    (void*) newElement->item, u_errorName(subErr), (void*) newElement->item->vFuncs);
 #endif
 
     if (subErr == U_USING_DEFAULT_WARNING || U_FAILURE(subErr)) {
@@ -400,9 +415,6 @@
  *                                                                      *
  *----------------------------------------------------------------------*/
 
-#define U_DATA_PATHITER_BUFSIZ  128        /* Size of local buffer for paths         */
-                                           /*   Overflow causes malloc of larger buf */
-
 U_NAMESPACE_BEGIN
 
 class UDataPathIterator
@@ -417,7 +429,8 @@
     const char *path;                              /* working path (u_icudata_Dir) */
     const char *nextPath;                          /* path following this one */
     const char *basename;                          /* item's basename (icudt22e_mt.res)*/
-    const char *suffix;                            /* item suffix (can be null) */
+
+    StringPiece suffix;                            /* item suffix (can be null) */
 
     uint32_t    basenameLen;                       /* length of basename */
 
@@ -431,13 +444,15 @@
 };
 
 /**
- * @param iter  The iterator to be initialized. Its current state does not matter. 
- * @param path  The full pathname to be iterated over.  If NULL, defaults to U_ICUDATA_NAME 
- * @param pkg   Package which is being searched for, ex "icudt28l".  Will ignore leave directories such as /icudt28l 
- * @param item  Item to be searched for.  Can include full path, such as /a/b/foo.dat 
- * @param suffix  Optional item suffix, if not-null (ex. ".dat") then 'path' can contain 'item' explicitly.
- *               Ex:   'stuff.dat' would be found in '/a/foo:/tmp/stuff.dat:/bar/baz' as item #2.   
- *                     '/blarg/stuff.dat' would also be found.
+ * @param iter    The iterator to be initialized. Its current state does not matter.
+ * @param inPath  The full pathname to be iterated over.  If NULL, defaults to U_ICUDATA_NAME 
+ * @param pkg     Package which is being searched for, ex "icudt28l".  Will ignore leaf directories such as /icudt28l 
+ * @param item    Item to be searched for.  Can include full path, such as /a/b/foo.dat 
+ * @param inSuffix  Optional item suffix, if not-null (ex. ".dat") then 'path' can contain 'item' explicitly.
+ *             Ex:   'stuff.dat' would be found in '/a/foo:/tmp/stuff.dat:/bar/baz' as item #2.   
+ *                   '/blarg/stuff.dat' would also be found.
+ *  Note: inSuffix may also be the 'item' being searched for as well, (ex: "ibm-5348_P100-1997.cnv"), in which case 
+ *        the 'item' parameter is often the same as pkg. (Though sometimes might have a tree part as well, ex: "icudt62l-curr").
  */
 UDataPathIterator::UDataPathIterator(const char *inPath, const char *pkg,
                                      const char *item, const char *inSuffix, UBool doCheckLastFour,
@@ -473,7 +488,7 @@
         nextPath = itemPath.data();
     }
 #ifdef UDATA_DEBUG
-    fprintf(stderr, "SUFFIX=%s [%p]\n", inSuffix, inSuffix);
+    fprintf(stderr, "SUFFIX=%s [%p]\n", inSuffix, (void*) inSuffix);
 #endif
 
     /** Suffix  **/
@@ -488,12 +503,11 @@
     /* pathBuffer will hold the output path strings returned by this iterator */
 
 #ifdef UDATA_DEBUG
-    fprintf(stderr, "%p: init %s -> [path=%s], [base=%s], [suff=%s], [itempath=%s], [nextpath=%s], [checklast4=%s]\n",
-            iter,
+    fprintf(stderr, "0: init %s -> [path=%s], [base=%s], [suff=%s], [itempath=%s], [nextpath=%s], [checklast4=%s]\n",
             item,
             path,
             basename,
-            suffix,
+            suffix.data(),
             itemPath.data(),
             nextPath,
             checkLastFour?"TRUE":"false");
@@ -549,7 +563,7 @@
         fprintf(stderr, "rest of path (IDD) = %s\n", currentPath);
         fprintf(stderr, "                     ");
         { 
-            uint32_t qqq;
+            int32_t qqq;
             for(qqq=0;qqq<pathLen;qqq++)
             {
                 fprintf(stderr, " ");
@@ -565,12 +579,12 @@
 
         if(checkLastFour == TRUE && 
            (pathLen>=4) &&
-           uprv_strncmp(pathBuffer.data() +(pathLen-4), suffix, 4)==0 && /* suffix matches */
+           uprv_strncmp(pathBuffer.data() +(pathLen-4), suffix.data(), 4)==0 && /* suffix matches */
            uprv_strncmp(findBasename(pathBuffer.data()), basename, basenameLen)==0  && /* base matches */
            uprv_strlen(pathBasename)==(basenameLen+4)) { /* base+suffix = full len */
 
 #ifdef UDATA_DEBUG
-            fprintf(stderr, "Have %s file on the path: %s\n", suffix, pathBuffer.data());
+            fprintf(stderr, "Have %s file on the path: %s\n", suffix.data(), pathBuffer.data());
 #endif
             /* do nothing */
         }
@@ -601,8 +615,13 @@
             /* + basename */
             pathBuffer.append(packageStub.data()+1, packageStub.length()-1, *pErrorCode);
 
-            if(*suffix)  /* tack on suffix */
+            if (!suffix.empty())  /* tack on suffix */
             {
+                if (suffix.length() > 4) {
+                    // If the suffix is actually an item ("ibm-5348_P100-1997.cnv") and not an extension (".res")
+                    // then we need to ensure that the path ends with a separator.
+                    pathBuffer.ensureEndsWithFileSeparator(*pErrorCode);
+                }
                 pathBuffer.append(suffix, *pErrorCode);
             }
         }
@@ -626,12 +645,15 @@
 
 /*----------------------------------------------------------------------*
  *                                                                      *
- *  Add a static reference to the common data  library                  *
+ *  Add a static reference to the common data library                   *
  *   Unless overridden by an explicit udata_setCommonData, this will be *
  *      our common data.                                                *
  *                                                                      *
  *----------------------------------------------------------------------*/
+#if !defined(ICU_DATA_DIR_WINDOWS)
+// When using the Windows system data, we expect only a single data file.
 extern "C" const ICU_Data_Header U_DATA_API U_ICUDATA_ENTRY_POINT;
+#endif
 
 /*
  * This would be a good place for weak-linkage declarations of
@@ -679,6 +701,8 @@
             if(gCommonICUDataArray[commonDataIndex] != NULL) {
                 return gCommonICUDataArray[commonDataIndex];
             }
+#if !defined(ICU_DATA_DIR_WINDOWS)
+// When using the Windows system data, we expect only a single data file.
             int32_t i;
             for(i = 0; i < commonDataIndex; ++i) {
                 if(gCommonICUDataArray[i]->pHeader == &U_ICUDATA_ENTRY_POINT.hdr) {
@@ -686,6 +710,7 @@
                     return NULL;
                 }
             }
+#endif
         }
 
         /* Add the linked-in data to the list. */
@@ -701,11 +726,14 @@
             setCommonICUDataPointer(uprv_getICUData_conversion(), FALSE, pErrorCode);
         }
         */
+#if !defined(ICU_DATA_DIR_WINDOWS)
+// When using the Windows system data, we expect only a single data file.
         setCommonICUDataPointer(&U_ICUDATA_ENTRY_POINT.hdr, FALSE, pErrorCode);
         {
             Mutex lock;
             return gCommonICUDataArray[commonDataIndex];
         }
+#endif
     }
 
 
@@ -724,18 +752,18 @@
 #ifdef UDATA_DEBUG
         fprintf(stderr, "ocd: no basename in %s, bailing.\n", path);
 #endif
-        *pErrorCode=U_FILE_ACCESS_ERROR;
+        if (U_SUCCESS(*pErrorCode)) {
+            *pErrorCode=U_FILE_ACCESS_ERROR;
+        }
         return NULL;
     }
 
    /* Is the requested common data file already open and cached?                     */
    /*   Note that the cache is keyed by the base name only.  The rest of the path,   */
    /*     if any, is not considered.                                                 */
-   {
-        UDataMemory  *dataToReturn = udata_findCachedData(inBasename);
-        if (dataToReturn != NULL) {
-            return dataToReturn;
-        }
+    UDataMemory  *dataToReturn = udata_findCachedData(inBasename, *pErrorCode);
+    if (dataToReturn != NULL || U_FAILURE(*pErrorCode)) {
+        return dataToReturn;
     }
 
     /* Requested item is not in the cache.
@@ -744,16 +772,19 @@
 
     UDataPathIterator iter(u_getDataDirectory(), inBasename, path, ".dat", TRUE, pErrorCode);
 
-    while((UDataMemory_isLoaded(&tData)==FALSE) && (pathBuffer = iter.next(pErrorCode)) != NULL)
+    while ((UDataMemory_isLoaded(&tData)==FALSE) && (pathBuffer = iter.next(pErrorCode)) != NULL)
     {
 #ifdef UDATA_DEBUG
         fprintf(stderr, "ocd: trying path %s - ", pathBuffer);
 #endif
-        uprv_mapFile(&tData, pathBuffer);
+        uprv_mapFile(&tData, pathBuffer, pErrorCode);
 #ifdef UDATA_DEBUG
         fprintf(stderr, "%s\n", UDataMemory_isLoaded(&tData)?"LOADED":"not loaded");
 #endif
     }
+    if (U_FAILURE(*pErrorCode)) {
+        return NULL;
+    }
 
 #if defined(OS390_STUBDATA) && defined(OS390BATCH)
     if (!UDataMemory_isLoaded(&tData)) {
@@ -762,10 +793,13 @@
         uprv_strncpy(ourPathBuffer, path, 1019);
         ourPathBuffer[1019]=0;
         uprv_strcat(ourPathBuffer, ".dat");
-        uprv_mapFile(&tData, ourPathBuffer);
+        uprv_mapFile(&tData, ourPathBuffer, pErrorCode);
     }
 #endif
 
+    if (U_FAILURE(*pErrorCode)) {
+        return NULL;
+    }
     if (!UDataMemory_isLoaded(&tData)) {
         /* no common data */
         *pErrorCode=U_FILE_ACCESS_ERROR;
@@ -810,7 +844,7 @@
      * Use a specific mutex to avoid nested locks of the global mutex.
      */
 #if MAP_IMPLEMENTATION==MAP_STDIO
-    static UMutex extendICUDataMutex = U_MUTEX_INITIALIZER;
+    static UMutex extendICUDataMutex;
     umtx_lock(&extendICUDataMutex);
 #endif
     if(!umtx_loadAcquire(gHaveTriedToLoadCommonData)) {
@@ -841,7 +875,7 @@
         umtx_storeRelease(gHaveTriedToLoadCommonData, 1);
     }
 
-    didUpdate = findCommonICUDataByName(U_ICUDATA_NAME);  /* Return 'true' when a racing writes out the extended                        */
+    didUpdate = findCommonICUDataByName(U_ICUDATA_NAME, *pErr);  /* Return 'true' when a racing writes out the extended                 */
                                                           /* data after another thread has failed to see it (in openCommonData), so     */
                                                           /* extended data can be examined.                                             */
                                                           /* Also handles a race through here before gHaveTriedToLoadCommonData is set. */
@@ -850,7 +884,7 @@
     umtx_unlock(&extendICUDataMutex);
 #endif
     return didUpdate;               /* Return true if ICUData pointer was updated.   */
-                                    /*   (Could potentialy have been done by another thread racing */
+                                    /*   (Could potentially have been done by another thread racing */
                                     /*   us through here, but that's fine, we still return true    */
                                     /*   so that current thread will also examine extended data.   */
 }
@@ -976,12 +1010,12 @@
     /* init path iterator for individual files */
     UDataPathIterator iter(dataPath, pkgName, path, tocEntryPathSuffix, FALSE, pErrorCode);
 
-    while((pathBuffer = iter.next(pErrorCode)))
+    while ((pathBuffer = iter.next(pErrorCode)) != NULL)
     {
 #ifdef UDATA_DEBUG
         fprintf(stderr, "UDATA: trying individual file %s\n", pathBuffer);
 #endif
-        if(uprv_mapFile(&dataMemory, pathBuffer))
+        if (uprv_mapFile(&dataMemory, pathBuffer, pErrorCode))
         {
             pEntryData = checkDataItem(dataMemory.pHeader, isAcceptable, context, type, name, subErrorCode, pErrorCode);
             if (pEntryData != NULL) {
@@ -997,7 +1031,7 @@
                 return pEntryData;
             }
 
-            /* the data is not acceptable, or some error occured.  Either way, unmap the memory */
+            /* the data is not acceptable, or some error occurred.  Either way, unmap the memory */
             udata_close(&dataMemory);
 
             /* If we had a nasty error, bail out completely.  */
@@ -1049,13 +1083,13 @@
             /* look up the data piece in the common data */
             pHeader=pCommonData->vFuncs->Lookup(pCommonData, tocEntryName, &length, subErrorCode);
 #ifdef UDATA_DEBUG
-            fprintf(stderr, "%s: pHeader=%p - %s\n", tocEntryName, pHeader, u_errorName(*subErrorCode));
+            fprintf(stderr, "%s: pHeader=%p - %s\n", tocEntryName, (void*) pHeader, u_errorName(*subErrorCode));
 #endif
 
             if(pHeader!=NULL) {
                 pEntryData = checkDataItem(pHeader, isAcceptable, context, type, name, subErrorCode, pErrorCode);
 #ifdef UDATA_DEBUG
-                fprintf(stderr, "pEntryData=%p\n", pEntryData);
+                fprintf(stderr, "pEntryData=%p\n", (void*) pEntryData);
 #endif
                 if (U_FAILURE(*pErrorCode)) {
                     return NULL;
@@ -1066,6 +1100,11 @@
                 }
             }
         }
+        // If we failed due to being out-of-memory, then stop early and report the error.
+        if (*subErrorCode == U_MEMORY_ALLOCATION_ERROR) {
+            *pErrorCode = *subErrorCode;
+            return NULL;
+        }
         /* Data wasn't found.  If we were looking for an ICUData item and there is
          * more data available, load it and try again,
          * otherwise break out of this loop. */
@@ -1142,6 +1181,9 @@
     UBool               isICUData = FALSE;
 
 
+    FileTracer::traceOpen(path, type, name);
+
+
     /* Is this path ICU data? */
     if(path == NULL ||
        !strcmp(path, U_ICUDATA_ALIAS) ||  /* "ICUDATA" */
@@ -1155,21 +1197,20 @@
     /* Windows:  try "foo\bar" and "foo/bar" */
     /* remap from alternate path char to the main one */
     if (U_FILE_SEP_CHAR != U_FILE_ALT_SEP_CHAR) {
-      CharString altSepPath;
-      if (path) {
-        if (uprv_strchr(path, U_FILE_ALT_SEP_CHAR) != NULL) {
-          altSepPath.append(path, *pErrorCode);
-          char* p;
-          while ((p = uprv_strchr(altSepPath.data(), U_FILE_ALT_SEP_CHAR))) {
-            *p = U_FILE_SEP_CHAR;
-          }
-#if defined(UDATA_DEBUG)
-          fprintf(stderr, "Changed path from [%s] to [%s]\n", path,
-                  altSepPath.s);
+        CharString altSepPath;
+        if(path) {
+            if(uprv_strchr(path,U_FILE_ALT_SEP_CHAR) != NULL) {
+                altSepPath.append(path, *pErrorCode);
+                char *p;
+                while ((p = uprv_strchr(altSepPath.data(), U_FILE_ALT_SEP_CHAR)) != NULL) {
+                    *p = U_FILE_SEP_CHAR;
+                }
+#if defined (UDATA_DEBUG)
+                fprintf(stderr, "Changed path from [%s] to [%s]\n", path, altSepPath.s);
 #endif
-          path = altSepPath.data();
+              path = altSepPath.data();
+            }
         }
-      }
     }
 
     CharString tocEntryName; /* entry name in tree format. ex:  'icudt28b/coll/ar.res' */
@@ -1244,16 +1285,22 @@
         tocEntryName.append(".", *pErrorCode).append(type, *pErrorCode);
         tocEntryPath.append(".", *pErrorCode).append(type, *pErrorCode);
     }
-    tocEntryPathSuffix = tocEntryPath.data()+tocEntrySuffixIndex; /* suffix starts here */
+    // The +1 is for the U_FILE_SEP_CHAR that is always appended above.
+    tocEntryPathSuffix = tocEntryPath.data() + tocEntrySuffixIndex + 1; /* suffix starts here */
 
 #ifdef UDATA_DEBUG
     fprintf(stderr, " tocEntryName = %s\n", tocEntryName.data());
     fprintf(stderr, " tocEntryPath = %s\n", tocEntryName.data());
 #endif
 
+#if !defined(ICU_DATA_DIR_WINDOWS)
     if(path == NULL) {
         path = COMMON_DATA_NAME; /* "icudt26e" */
     }
+#else
+    // When using the Windows system data, we expects only a single data file.
+    path = COMMON_DATA_NAME; /* "icudt26e" */
+#endif
 
     /************************ Begin loop looking for ind. files ***************/
 #ifdef UDATA_DEBUG
@@ -1264,7 +1311,7 @@
     dataPath = u_getDataDirectory();
 
     /****    Time zone individual files override  */
-    if (isTimeZoneFile(name, type) && isICUData) {
+    if (isICUData && isTimeZoneFile(name, type)) {
         const char *tzFilesDir = u_getTimeZoneFilesDirectory(pErrorCode);
         if (tzFilesDir[0] != 0) {
 #ifdef UDATA_DEBUG
diff --git a/src/third_party/icu/source/common/udatamem.c b/src/third_party/icu/source/common/udatamem.cpp
similarity index 95%
rename from src/third_party/icu/source/common/udatamem.c
rename to src/third_party/icu/source/common/udatamem.cpp
index 84076e9..9a3565d 100644
--- a/src/third_party/icu/source/common/udatamem.c
+++ b/src/third_party/icu/source/common/udatamem.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
@@ -17,7 +19,9 @@
  *
  *----------------------------------------------------------------------------------*/
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/utypes.h"
 #include "cmemory.h"
 #include "unicode/udata.h"
@@ -43,7 +47,7 @@
     if (U_FAILURE(*pErr)) {
         return NULL;
     }
-    This = uprv_malloc(sizeof(UDataMemory));
+    This = (UDataMemory *)uprv_malloc(sizeof(UDataMemory));
     if (This == NULL) {
         *pErr = U_MEMORY_ALLOCATION_ERROR; }
     else {
diff --git a/src/third_party/icu/source/common/udatamem.h b/src/third_party/icu/source/common/udatamem.h
index 5137285..a05dd69 100644
--- a/src/third_party/icu/source/common/udatamem.h
+++ b/src/third_party/icu/source/common/udatamem.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
diff --git a/src/third_party/icu/source/common/udataswp.c b/src/third_party/icu/source/common/udataswp.cpp
similarity index 96%
rename from src/third_party/icu/source/common/udataswp.c
rename to src/third_party/icu/source/common/udataswp.cpp
index a7bfb05..5d40d11 100644
--- a/src/third_party/icu/source/common/udataswp.c
+++ b/src/third_party/icu/source/common/udataswp.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  udataswp.c
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -18,7 +20,9 @@
 *   charset families (ASCII<->EBCDIC).
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include <stdarg.h>
 #include "unicode/utypes.h"
 #include "unicode/udata.h" /* UDataInfo */
@@ -299,7 +303,7 @@
 
     /* check minimum length and magic bytes */
     pHeader=(const DataHeader *)inData;
-    if( (length>=0 && length<sizeof(DataHeader)) ||
+    if( (length>=0 && length<(int32_t)sizeof(DataHeader)) ||
         pHeader->dataHeader.magic1!=0xda ||
         pHeader->dataHeader.magic2!=0x27 ||
         pHeader->info.sizeofUChar!=2
@@ -373,7 +377,7 @@
     }
 
     /* allocate the swapper */
-    swapper=uprv_malloc(sizeof(UDataSwapper));
+    swapper=(UDataSwapper *)uprv_malloc(sizeof(UDataSwapper));
     if(swapper==NULL) {
         *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
         return NULL;
@@ -426,7 +430,7 @@
         return NULL;
     }
     if( data==NULL ||
-        (length>=0 && length<sizeof(DataHeader)) ||
+        (length>=0 && length<(int32_t)sizeof(DataHeader)) ||
         outCharset>U_EBCDIC_FAMILY
     ) {
         *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
@@ -434,7 +438,7 @@
     }
 
     pHeader=(const DataHeader *)data;
-    if( (length>=0 && length<sizeof(DataHeader)) ||
+    if( (length>=0 && length<(int32_t)sizeof(DataHeader)) ||
         pHeader->dataHeader.magic1!=0xda ||
         pHeader->dataHeader.magic2!=0x27 ||
         pHeader->info.sizeofUChar!=2
diff --git a/src/third_party/icu/source/common/udataswp.h b/src/third_party/icu/source/common/udataswp.h
index 66c8495..5e7b043 100644
--- a/src/third_party/icu/source/common/udataswp.h
+++ b/src/third_party/icu/source/common/udataswp.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  udataswp.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -318,6 +320,57 @@
                       const char *outString, int32_t outLength,
                       const UChar *localString, int32_t localLength);
 
+/**
+ * \def uprv_compareInvWithUChar
+ * Compare an invariant-character strings with a UChar string
+ * @internal
+ */
+#if U_CHARSET_FAMILY==U_ASCII_FAMILY
+#   define uprv_compareInvWithUChar uprv_compareInvAscii
+#elif U_CHARSET_FAMILY==U_EBCDIC_FAMILY
+#   define uprv_compareInvWithUChar uprv_compareInvEbcdic
+#else
+#   error Unknown charset family!
+#endif
+
+// utrie_swap.cpp -----------------------------------------------------------***
+
+/**
+ * Swaps a serialized UTrie.
+ * @internal
+ */
+U_CAPI int32_t U_EXPORT2
+utrie_swap(const UDataSwapper *ds,
+           const void *inData, int32_t length, void *outData,
+           UErrorCode *pErrorCode);
+
+/**
+ * Swaps a serialized UTrie2.
+ * @internal
+ */
+U_CAPI int32_t U_EXPORT2
+utrie2_swap(const UDataSwapper *ds,
+            const void *inData, int32_t length, void *outData,
+            UErrorCode *pErrorCode);
+
+/**
+ * Swaps a serialized UCPTrie.
+ * @internal
+ */
+U_CAPI int32_t U_EXPORT2
+ucptrie_swap(const UDataSwapper *ds,
+             const void *inData, int32_t length, void *outData,
+             UErrorCode *pErrorCode);
+
+/**
+ * Swaps a serialized UTrie, UTrie2, or UCPTrie.
+ * @internal
+ */
+U_CAPI int32_t U_EXPORT2
+utrie_swapAnyVersion(const UDataSwapper *ds,
+                     const void *inData, int32_t length, void *outData,
+                     UErrorCode *pErrorCode);
+
 /* material... -------------------------------------------------------------- */
 
 #if 0
diff --git a/src/third_party/icu/source/common/uelement.h b/src/third_party/icu/source/common/uelement.h
index 4eaddd9..88dd4d6 100644
--- a/src/third_party/icu/source/common/uelement.h
+++ b/src/third_party/icu/source/common/uelement.h
@@ -1,10 +1,12 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *   Copyright (C) 1997-2011, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *******************************************************************************
 *   file name:  uelement.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -44,7 +46,7 @@
  * An element-equality (boolean) comparison function.
  * @param e1 An element (object or integer)
  * @param e2 An element (object or integer)
- * @return TRUE if the two elements are equal.
+ * @return true if the two elements are equal.
  */
 typedef UBool U_CALLCONV UElementsAreEqual(const UElement e1, const UElement e2);
 
diff --git a/src/third_party/icu/source/common/uenum.c b/src/third_party/icu/source/common/uenum.cpp
similarity index 96%
rename from src/third_party/icu/source/common/uenum.c
rename to src/third_party/icu/source/common/uenum.cpp
index 9a3d9e1..11d895e 100644
--- a/src/third_party/icu/source/common/uenum.c
+++ b/src/third_party/icu/source/common/uenum.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  uenum.c
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:2
 *
diff --git a/src/third_party/icu/source/common/uenumimp.h b/src/third_party/icu/source/common/uenumimp.h
index 664bc68..9c9df75 100644
--- a/src/third_party/icu/source/common/uenumimp.h
+++ b/src/third_party/icu/source/common/uenumimp.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  uenumimp.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:2
 *
diff --git a/src/third_party/icu/source/common/uhash.c b/src/third_party/icu/source/common/uhash.cpp
similarity index 94%
rename from src/third_party/icu/source/common/uhash.c
rename to src/third_party/icu/source/common/uhash.cpp
index ebab433..358cb97 100644
--- a/src/third_party/icu/source/common/uhash.c
+++ b/src/third_party/icu/source/common/uhash.cpp
@@ -1,6 +1,8 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
-*   Copyright (C) 1997-2014, International Business Machines
+*   Copyright (C) 1997-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 ******************************************************************************
 *   Date        Name        Description
@@ -10,7 +12,9 @@
 ******************************************************************************
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
+#endif  // defined(STARBOARD)
 #include "uhash.h"
 #include "unicode/ustring.h"
 #include "cstring.h"
@@ -78,14 +82,14 @@
  * prime number while being less than a power of two.
  */
 static const int32_t PRIMES[] = {
-    13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381, 32749,
+    7, 13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381, 32749,
     65521, 131071, 262139, 524287, 1048573, 2097143, 4194301, 8388593,
     16777213, 33554393, 67108859, 134217689, 268435399, 536870909,
     1073741789, 2147483647 /*, 4294967291 */
 };
 
-#define PRIMES_LENGTH (sizeof(PRIMES) / sizeof(PRIMES[0]))
-#define DEFAULT_PRIME_INDEX 3
+#define PRIMES_LENGTH UPRV_LENGTHOF(PRIMES)
+#define DEFAULT_PRIME_INDEX 4
 
 /* These ratios are tuned to the PRIMES array such that a resize
  * places the table back into the zone of non-resizing.  That is,
@@ -118,13 +122,14 @@
 
 /* This macro expects a UHashTok.pointer as its keypointer and
    valuepointer parameters */
-#define HASH_DELETE_KEY_VALUE(hash, keypointer, valuepointer) \
-            if (hash->keyDeleter != NULL && keypointer != NULL) { \
-                (*hash->keyDeleter)(keypointer); \
-            } \
-            if (hash->valueDeleter != NULL && valuepointer != NULL) { \
-                (*hash->valueDeleter)(valuepointer); \
-            }
+#define HASH_DELETE_KEY_VALUE(hash, keypointer, valuepointer) UPRV_BLOCK_MACRO_BEGIN { \
+    if (hash->keyDeleter != NULL && keypointer != NULL) { \
+        (*hash->keyDeleter)(keypointer); \
+    } \
+    if (hash->valueDeleter != NULL && valuepointer != NULL) { \
+        (*hash->valueDeleter)(valuepointer); \
+    } \
+} UPRV_BLOCK_MACRO_END
 
 /*
  * Constants for hinting whether a key or value is an integer
@@ -217,7 +222,7 @@
 
     U_ASSERT(primeIndex >= 0 && primeIndex < PRIMES_LENGTH);
 
-    hash->primeIndex = primeIndex;
+    hash->primeIndex = static_cast<int8_t>(primeIndex);
     hash->length = PRIMES[primeIndex];
 
     p = hash->elements = (UHashElement*)
@@ -230,7 +235,7 @@
 
     emptytok.pointer = NULL; /* Only one of these two is needed */
     emptytok.integer = 0;    /* but we don't know which one. */
-    
+
     limit = p + hash->length;
     while (p < limit) {
         p->key = emptytok;
@@ -246,7 +251,7 @@
 
 static UHashtable*
 _uhash_init(UHashtable *result,
-              UHashFunction *keyHash, 
+              UHashFunction *keyHash,
               UKeyComparator *keyComp,
               UValueComparator *valueComp,
               int32_t primeIndex,
@@ -274,7 +279,7 @@
 }
 
 static UHashtable*
-_uhash_create(UHashFunction *keyHash, 
+_uhash_create(UHashFunction *keyHash,
               UKeyComparator *keyComp,
               UValueComparator *valueComp,
               int32_t primeIndex,
@@ -375,8 +380,7 @@
          * WILL NEVER HAPPEN as long as uhash_put() makes sure that
          * count is always < length.
          */
-        U_ASSERT(FALSE);
-        return NULL; /* Never happens if uhash_put() behaves */
+        UPRV_UNREACHABLE;
     }
     return &(elements[theIndex]);
 }
@@ -414,7 +418,7 @@
 
     if (U_FAILURE(*status)) {
         hash->elements = old;
-        hash->length = oldLength;       
+        hash->length = oldLength;
         return;
     }
 
@@ -535,7 +539,7 @@
  ********************************************************************/
 
 U_CAPI UHashtable* U_EXPORT2
-uhash_open(UHashFunction *keyHash, 
+uhash_open(UHashFunction *keyHash,
            UKeyComparator *keyComp,
            UValueComparator *valueComp,
            UErrorCode *status) {
@@ -544,7 +548,7 @@
 }
 
 U_CAPI UHashtable* U_EXPORT2
-uhash_openSize(UHashFunction *keyHash, 
+uhash_openSize(UHashFunction *keyHash,
                UKeyComparator *keyComp,
                UValueComparator *valueComp,
                int32_t size,
@@ -561,7 +565,7 @@
 
 U_CAPI UHashtable* U_EXPORT2
 uhash_init(UHashtable *fillinResult,
-           UHashFunction *keyHash, 
+           UHashFunction *keyHash,
            UKeyComparator *keyComp,
            UValueComparator *valueComp,
            UErrorCode *status) {
@@ -569,6 +573,22 @@
     return _uhash_init(fillinResult, keyHash, keyComp, valueComp, DEFAULT_PRIME_INDEX, status);
 }
 
+U_CAPI UHashtable* U_EXPORT2
+uhash_initSize(UHashtable *fillinResult,
+               UHashFunction *keyHash,
+               UKeyComparator *keyComp,
+               UValueComparator *valueComp,
+               int32_t size,
+               UErrorCode *status) {
+
+    // Find the smallest index i for which PRIMES[i] >= size.
+    int32_t i = 0;
+    while (i<(PRIMES_LENGTH-1) && PRIMES[i]<size) {
+        ++i;
+    }
+    return _uhash_init(fillinResult, keyHash, keyComp, valueComp, i, status);
+}
+
 U_CAPI void U_EXPORT2
 uhash_close(UHashtable *hash) {
     if (hash == NULL) {
@@ -603,7 +623,7 @@
     hash->keyComparator = fn;
     return result;
 }
-U_CAPI UValueComparator *U_EXPORT2 
+U_CAPI UValueComparator *U_EXPORT2
 uhash_setValueComparator(UHashtable *hash, UValueComparator *fn){
     UValueComparator *result = hash->valueComparator;
     hash->valueComparator = fn;
@@ -629,7 +649,7 @@
     UErrorCode status = U_ZERO_ERROR;
     _uhash_internalSetResizePolicy(hash, policy);
     hash->lowWaterMark  = (int32_t)(hash->length * hash->lowWaterRatio);
-    hash->highWaterMark = (int32_t)(hash->length * hash->highWaterRatio);    
+    hash->highWaterMark = (int32_t)(hash->length * hash->highWaterRatio);
     _uhash_rehash(hash, &status);
 }
 
@@ -843,16 +863,16 @@
 U_CAPI int32_t U_EXPORT2
 uhash_hashChars(const UHashTok key) {
     const char *s = (const char *)key.pointer;
-    return s == NULL ? 0 : ustr_hashCharsN(s, uprv_strlen(s));
+    return s == NULL ? 0 : static_cast<int32_t>(ustr_hashCharsN(s, static_cast<int32_t>(uprv_strlen(s))));
 }
 
 U_CAPI int32_t U_EXPORT2
 uhash_hashIChars(const UHashTok key) {
     const char *s = (const char *)key.pointer;
-    return s == NULL ? 0 : ustr_hashICharsN(s, uprv_strlen(s));
+    return s == NULL ? 0 : ustr_hashICharsN(s, static_cast<int32_t>(uprv_strlen(s)));
 }
 
-U_CAPI UBool U_EXPORT2 
+U_CAPI UBool U_EXPORT2
 uhash_equals(const UHashtable* hash1, const UHashtable* hash2){
     int32_t count1, count2, pos, i;
 
@@ -885,14 +905,14 @@
     if(count1!=count2){
         return FALSE;
     }
-    
+
     pos=UHASH_FIRST;
     for(i=0; i<count1; i++){
         const UHashElement* elem1 = uhash_nextElement(hash1, &pos);
         const UHashTok key1 = elem1->key;
         const UHashTok val1 = elem1->value;
         /* here the keys are not compared, instead the key form hash1 is used to fetch
-         * value from hash2. If the hashes are equal then then both hashes should 
+         * value from hash2. If the hashes are equal then then both hashes should
          * contain equal values for the same key!
          */
         const UHashElement* elem2 = _uhash_find(hash2, key1, hash2->keyHasher(key1));
diff --git a/src/third_party/icu/source/common/uhash.h b/src/third_party/icu/source/common/uhash.h
index 1761dd0..b59d271 100644
--- a/src/third_party/icu/source/common/uhash.h
+++ b/src/third_party/icu/source/common/uhash.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *   Copyright (C) 1997-2015, International Business Machines
@@ -152,7 +154,7 @@
                                    * If NULL won't do anything */
 
     /* Size parameters */
-  
+
     int32_t     count;      /* The number of key-value pairs in this table.
                              * 0 <= count <= length.  In practice we
                              * never let count == length (see code). */
@@ -160,12 +162,12 @@
                              * and values.  Must be prime. */
 
     /* Rehashing thresholds */
-    
+
     int32_t     highWaterMark;  /* If count > highWaterMark, rehash */
     int32_t     lowWaterMark;   /* If count < lowWaterMark, rehash */
     float       highWaterRatio; /* 0..1; high water as a fraction of length */
     float       lowWaterRatio;  /* 0..1; low water as a fraction of length */
-    
+
     int8_t      primeIndex;     /* Index into our prime table for length.
                                  * length == PRIMES[primeIndex] */
     UBool       allocated; /* Was this UHashtable allocated? */
@@ -188,7 +190,7 @@
  * @return A pointer to a UHashtable, or 0 if an error occurred.
  * @see uhash_openSize
  */
-U_CAPI UHashtable* U_EXPORT2 
+U_CAPI UHashtable* U_EXPORT2
 uhash_open(UHashFunction *keyHash,
            UKeyComparator *keyComp,
            UValueComparator *valueComp,
@@ -205,7 +207,7 @@
  * @return A pointer to a UHashtable, or 0 if an error occurred.
  * @see uhash_open
  */
-U_CAPI UHashtable* U_EXPORT2 
+U_CAPI UHashtable* U_EXPORT2
 uhash_openSize(UHashFunction *keyHash,
                UKeyComparator *keyComp,
                UValueComparator *valueComp,
@@ -222,7 +224,7 @@
  * @return A pointer to a UHashtable, or 0 if an error occurred.
  * @see uhash_openSize
  */
-U_CAPI UHashtable* U_EXPORT2 
+U_CAPI UHashtable* U_EXPORT2
 uhash_init(UHashtable *hash,
            UHashFunction *keyHash,
            UKeyComparator *keyComp,
@@ -230,10 +232,29 @@
            UErrorCode *status);
 
 /**
+ * Initialize an existing UHashtable.
+ * @param keyHash A pointer to the key hashing function.  Must not be
+ * NULL.
+ * @param keyComp A pointer to the function that compares keys.  Must
+ * not be NULL.
+ * @param size The initial capacity of this hash table.
+ * @param status A pointer to an UErrorCode to receive any errors.
+ * @return A pointer to a UHashtable, or 0 if an error occurred.
+ * @see uhash_openSize
+ */
+U_CAPI UHashtable* U_EXPORT2
+uhash_initSize(UHashtable *hash,
+               UHashFunction *keyHash,
+               UKeyComparator *keyComp,
+               UValueComparator *valueComp,
+               int32_t size,
+               UErrorCode *status);
+
+/**
  * Close a UHashtable, releasing the memory used.
  * @param hash The UHashtable to close. If hash is NULL no operation is performed.
  */
-U_CAPI void U_EXPORT2 
+U_CAPI void U_EXPORT2
 uhash_close(UHashtable *hash);
 
 
@@ -244,7 +265,7 @@
  * @param fn the function to be used hash keys; must not be NULL
  * @return the previous key hasher; non-NULL
  */
-U_CAPI UHashFunction *U_EXPORT2 
+U_CAPI UHashFunction *U_EXPORT2
 uhash_setKeyHasher(UHashtable *hash, UHashFunction *fn);
 
 /**
@@ -254,7 +275,7 @@
  * @param fn the function to be used compare keys; must not be NULL
  * @return the previous key comparator; non-NULL
  */
-U_CAPI UKeyComparator *U_EXPORT2 
+U_CAPI UKeyComparator *U_EXPORT2
 uhash_setKeyComparator(UHashtable *hash, UKeyComparator *fn);
 
 /**
@@ -264,7 +285,7 @@
  * @param fn the function to be used compare keys; must not be NULL
  * @return the previous key comparator; non-NULL
  */
-U_CAPI UValueComparator *U_EXPORT2 
+U_CAPI UValueComparator *U_EXPORT2
 uhash_setValueComparator(UHashtable *hash, UValueComparator *fn);
 
 /**
@@ -277,7 +298,7 @@
  * @param fn the function to be used delete keys, or NULL
  * @return the previous key deleter; may be NULL
  */
-U_CAPI UObjectDeleter *U_EXPORT2 
+U_CAPI UObjectDeleter *U_EXPORT2
 uhash_setKeyDeleter(UHashtable *hash, UObjectDeleter *fn);
 
 /**
@@ -290,7 +311,7 @@
  * @param fn the function to be used delete values, or NULL
  * @return the previous value deleter; may be NULL
  */
-U_CAPI UObjectDeleter *U_EXPORT2 
+U_CAPI UObjectDeleter *U_EXPORT2
 uhash_setValueDeleter(UHashtable *hash, UObjectDeleter *fn);
 
 /**
@@ -300,7 +321,7 @@
  * @param hash The UHashtable to set
  * @param policy The way the hashtable resizes itself, {U_GROW, U_GROW_AND_SHRINK, U_FIXED}
  */
-U_CAPI void U_EXPORT2 
+U_CAPI void U_EXPORT2
 uhash_setResizePolicy(UHashtable *hash, enum UHashResizePolicy policy);
 
 /**
@@ -308,7 +329,7 @@
  * @param hash The UHashtable to query.
  * @return The number of key-value pairs stored in hash.
  */
-U_CAPI int32_t U_EXPORT2 
+U_CAPI int32_t U_EXPORT2
 uhash_count(const UHashtable *hash);
 
 /**
@@ -324,7 +345,7 @@
  * @return The previous value, or NULL if none.
  * @see uhash_get
  */
-U_CAPI void* U_EXPORT2 
+U_CAPI void* U_EXPORT2
 uhash_put(UHashtable *hash,
           void *key,
           void *value,
@@ -342,7 +363,7 @@
  * @return The previous value, or NULL if none.
  * @see uhash_get
  */
-U_CAPI void* U_EXPORT2 
+U_CAPI void* U_EXPORT2
 uhash_iput(UHashtable *hash,
            int32_t key,
            void* value,
@@ -360,7 +381,7 @@
  * @return The previous value, or 0 if none.
  * @see uhash_get
  */
-U_CAPI int32_t U_EXPORT2 
+U_CAPI int32_t U_EXPORT2
 uhash_puti(UHashtable *hash,
            void* key,
            int32_t value,
@@ -378,7 +399,7 @@
  * @return The previous value, or 0 if none.
  * @see uhash_get
  */
-U_CAPI int32_t U_EXPORT2 
+U_CAPI int32_t U_EXPORT2
 uhash_iputi(UHashtable *hash,
            int32_t key,
            int32_t value,
@@ -391,8 +412,8 @@
  * @param key A pointer key stored in a hashtable
  * @return The requested item, or NULL if not found.
  */
-U_CAPI void* U_EXPORT2 
-uhash_get(const UHashtable *hash, 
+U_CAPI void* U_EXPORT2
+uhash_get(const UHashtable *hash,
           const void *key);
 
 /**
@@ -402,7 +423,7 @@
  * @param key An integer key stored in a hashtable
  * @return The requested item, or NULL if not found.
  */
-U_CAPI void* U_EXPORT2 
+U_CAPI void* U_EXPORT2
 uhash_iget(const UHashtable *hash,
            int32_t key);
 
@@ -413,7 +434,7 @@
  * @param key A pointer key stored in a hashtable
  * @return The requested item, or 0 if not found.
  */
-U_CAPI int32_t U_EXPORT2 
+U_CAPI int32_t U_EXPORT2
 uhash_geti(const UHashtable *hash,
            const void* key);
 /**
@@ -423,7 +444,7 @@
  * @param key An integer key stored in a hashtable
  * @return The requested item, or 0 if not found.
  */
-U_CAPI int32_t U_EXPORT2 
+U_CAPI int32_t U_EXPORT2
 uhash_igeti(const UHashtable *hash,
            int32_t key);
 
@@ -433,7 +454,7 @@
  * @param key A key stored in a hashtable
  * @return The item removed, or NULL if not found.
  */
-U_CAPI void* U_EXPORT2 
+U_CAPI void* U_EXPORT2
 uhash_remove(UHashtable *hash,
              const void *key);
 
@@ -443,7 +464,7 @@
  * @param key An integer key stored in a hashtable
  * @return The item removed, or NULL if not found.
  */
-U_CAPI void* U_EXPORT2 
+U_CAPI void* U_EXPORT2
 uhash_iremove(UHashtable *hash,
               int32_t key);
 
@@ -453,7 +474,7 @@
  * @param key An key stored in a hashtable
  * @return The item removed, or 0 if not found.
  */
-U_CAPI int32_t U_EXPORT2 
+U_CAPI int32_t U_EXPORT2
 uhash_removei(UHashtable *hash,
               const void* key);
 
@@ -463,7 +484,7 @@
  * @param key An integer key stored in a hashtable
  * @return The item removed, or 0 if not found.
  */
-U_CAPI int32_t U_EXPORT2 
+U_CAPI int32_t U_EXPORT2
 uhash_iremovei(UHashtable *hash,
                int32_t key);
 
@@ -471,7 +492,7 @@
  * Remove all items from a UHashtable.
  * @param hash The target UHashtable.
  */
-U_CAPI void U_EXPORT2 
+U_CAPI void U_EXPORT2
 uhash_removeAll(UHashtable *hash);
 
 /**
@@ -485,7 +506,7 @@
  * @param key A key stored in a hashtable
  * @return a hash element, or NULL if the key is not found.
  */
-U_CAPI const UHashElement* U_EXPORT2 
+U_CAPI const UHashElement* U_EXPORT2
 uhash_find(const UHashtable *hash, const void* key);
 
 /**
@@ -508,7 +529,7 @@
  * @return a hash element, or NULL if no further key-value pairs
  * exist in the table.
  */
-U_CAPI const UHashElement* U_EXPORT2 
+U_CAPI const UHashElement* U_EXPORT2
 uhash_nextElement(const UHashtable *hash,
                   int32_t *pos);
 
@@ -523,7 +544,7 @@
  * modified.
  * @return the value that was removed.
  */
-U_CAPI void* U_EXPORT2 
+U_CAPI void* U_EXPORT2
 uhash_removeElement(UHashtable *hash, const UHashElement* e);
 
 /********************************************************************
@@ -535,7 +556,7 @@
  * @param i The given integer
  * @return a UHashTok for an integer.
  */
-/*U_CAPI UHashTok U_EXPORT2 
+/*U_CAPI UHashTok U_EXPORT2
 uhash_toki(int32_t i);*/
 
 /**
@@ -543,7 +564,7 @@
  * @param p The given pointer
  * @return a UHashTok for a pointer.
  */
-/*U_CAPI UHashTok U_EXPORT2 
+/*U_CAPI UHashTok U_EXPORT2
 uhash_tokp(void* p);*/
 
 /********************************************************************
@@ -557,7 +578,7 @@
  * @param key The string (const UChar*) to hash.
  * @return A hash code for the key.
  */
-U_CAPI int32_t U_EXPORT2 
+U_CAPI int32_t U_EXPORT2
 uhash_hashUChars(const UHashTok key);
 
 /**
@@ -567,7 +588,7 @@
  * @param key The string (const char*) to hash.
  * @return A hash code for the key.
  */
-U_CAPI int32_t U_EXPORT2 
+U_CAPI int32_t U_EXPORT2
 uhash_hashChars(const UHashTok key);
 
 /**
@@ -587,7 +608,7 @@
  * @param key2 The string for comparison
  * @return true if key1 and key2 are equal, return false otherwise.
  */
-U_CAPI UBool U_EXPORT2 
+U_CAPI UBool U_EXPORT2
 uhash_compareUChars(const UHashTok key1, const UHashTok key2);
 
 /**
@@ -597,7 +618,7 @@
  * @param key2 The string for comparison
  * @return true if key1 and key2 are equal, return false otherwise.
  */
-U_CAPI UBool U_EXPORT2 
+U_CAPI UBool U_EXPORT2
 uhash_compareChars(const UHashTok key1, const UHashTok key2);
 
 /**
@@ -607,7 +628,7 @@
  * @param key2 The string for comparison
  * @return true if key1 and key2 are equal, return false otherwise.
  */
-U_CAPI UBool U_EXPORT2 
+U_CAPI UBool U_EXPORT2
 uhash_compareIChars(const UHashTok key1, const UHashTok key2);
 
 /********************************************************************
@@ -619,7 +640,7 @@
  * @param key The string (const char*) to hash.
  * @return A hash code for the key.
  */
-U_CAPI int32_t U_EXPORT2 
+U_CAPI int32_t U_EXPORT2
 uhash_hashUnicodeString(const UElement key);
 
 /**
@@ -628,7 +649,7 @@
  * @param key The string (const char*) to hash.
  * @return A hash code for the key.
  */
-U_CAPI int32_t U_EXPORT2 
+U_CAPI int32_t U_EXPORT2
 uhash_hashCaselessUnicodeString(const UElement key);
 
 /********************************************************************
@@ -640,7 +661,7 @@
  * @param key The string (const char*) to hash.
  * @return A hash code for the key.
  */
-U_CAPI int32_t U_EXPORT2 
+U_CAPI int32_t U_EXPORT2
 uhash_hashLong(const UHashTok key);
 
 /**
@@ -649,7 +670,7 @@
  * @param Key2 The integer for comparison
  * @return true if key1 and key2 are equal, return false otherwise
  */
-U_CAPI UBool U_EXPORT2 
+U_CAPI UBool U_EXPORT2
 uhash_compareLong(const UHashTok key1, const UHashTok key2);
 
 /********************************************************************
@@ -660,7 +681,7 @@
  * Deleter for Hashtable objects.
  * @param obj The object to be deleted
  */
-U_CAPI void U_EXPORT2 
+U_CAPI void U_EXPORT2
 uhash_deleteHashtable(void *obj);
 
 /* Use uprv_free() itself as a deleter for any key or value allocated using uprv_malloc. */
@@ -671,7 +692,7 @@
  * @param hash2
  * @return true if the hashtables are equal and false if not.
  */
-U_CAPI UBool U_EXPORT2 
+U_CAPI UBool U_EXPORT2
 uhash_equals(const UHashtable* hash1, const UHashtable* hash2);
 
 
@@ -680,8 +701,8 @@
 U_NAMESPACE_BEGIN
 
 /**
- * \class LocalUResourceBundlePointer
- * "Smart pointer" class, closes a UResourceBundle via ures_close().
+ * \class LocalUHashtablePointer
+ * "Smart pointer" class, closes a UHashtable via uhash_close().
  * For most methods see the LocalPointerBase base class.
  *
  * @see LocalPointerBase
diff --git a/src/third_party/icu/source/common/uhash_us.cpp b/src/third_party/icu/source/common/uhash_us.cpp
index 85a33cb..cd88dbd 100644
--- a/src/third_party/icu/source/common/uhash_us.cpp
+++ b/src/third_party/icu/source/common/uhash_us.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *   Copyright (C) 1997-2011, International Business Machines
@@ -10,7 +12,9 @@
 ******************************************************************************
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "hash.h"
 
 /**
diff --git a/src/third_party/icu/source/common/uidna.cpp b/src/third_party/icu/source/common/uidna.cpp
index 4460e37..f3c891b 100644
--- a/src/third_party/icu/source/common/uidna.cpp
+++ b/src/third_party/icu/source/common/uidna.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
  *******************************************************************************
  *
@@ -6,7 +8,7 @@
  *
  *******************************************************************************
  *   file name:  uidna.cpp
- *   encoding:   US-ASCII
+ *   encoding:   UTF-8
  *   tab size:   8 (not used)
  *   indentation:4
  *
@@ -18,8 +20,10 @@
 
 #if !UCONFIG_NO_IDNA
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/uidna.h"
 #include "unicode/ustring.h"
 #include "unicode/usprep.h"
@@ -57,18 +61,16 @@
 
 inline static UBool 
 startsWithPrefix(const UChar* src , int32_t srcLength){
-    UBool startsWithPrefix = TRUE;
-
     if(srcLength < ACE_PREFIX_LENGTH){
         return FALSE;
     }
 
     for(int8_t i=0; i< ACE_PREFIX_LENGTH; i++){
         if(toASCIILower(src[i]) != ACE_PREFIX[i]){
-            startsWithPrefix = FALSE;
+            return FALSE;
         }
     }
-    return startsWithPrefix;
+    return TRUE;
 }
 
 
@@ -318,7 +320,7 @@
     // Step 4: if the source is ASCII then proceed to step 8
     if(srcIsASCII){
         if(b1Len <= destCapacity){
-            uprv_memmove(dest, b1, b1Len * U_SIZEOF_UCHAR);
+            u_memmove(dest, b1, b1Len);
             reqLength = b1Len;
         }else{
             reqLength = b1Len;
@@ -364,9 +366,9 @@
                 goto CLEANUP;
             }
             //Step 7: prepend the ACE prefix
-            uprv_memcpy(dest,ACE_PREFIX,ACE_PREFIX_LENGTH * U_SIZEOF_UCHAR);
+            u_memcpy(dest, ACE_PREFIX, ACE_PREFIX_LENGTH);
             //Step 6: copy the contents in b2 into dest
-            uprv_memcpy(dest+ACE_PREFIX_LENGTH, b2, b2Len * U_SIZEOF_UCHAR);
+            u_memcpy(dest+ACE_PREFIX_LENGTH, b2, b2Len);
 
         }else{
             *status = U_IDNA_ACE_PREFIX_ERROR; 
@@ -441,6 +443,7 @@
         for(int32_t j=0; j<srcLength; j++){
             if(src[j]> 0x7f){
                 srcIsASCII = FALSE;
+                break;
             }/*else if(isLDHChar(src[j])==FALSE){
                 // here we do not assemble surrogates
                 // since we know that LDH code points
@@ -543,7 +546,7 @@
         //step 8: return output of step 5
         reqLength = b2Len;
         if(b2Len <= destCapacity) {
-            uprv_memmove(dest, b2, b2Len * U_SIZEOF_UCHAR);
+            u_memmove(dest, b2, b2Len);
         }
     }
     else{
@@ -572,7 +575,7 @@
         // just return the source
         //copy the source to destination
         if(srcLength <= destCapacity){
-            uprv_memmove(dest,src,srcLength * U_SIZEOF_UCHAR);
+            u_memmove(dest, src, srcLength);
         }
         reqLength = srcLength;
     }
@@ -599,7 +602,7 @@
         if(dest && srcLength <= destCapacity){
             // srcLength should have already been set earlier.
             U_ASSERT(srcLength >= 0);
-            uprv_memmove(dest,src,srcLength * U_SIZEOF_UCHAR);
+            u_memmove(dest, src, srcLength);
         }
         reqLength = srcLength;
         *status = U_ZERO_ERROR;
diff --git a/src/third_party/icu/source/common/uinit.cpp b/src/third_party/icu/source/common/uinit.cpp
index 1dacd2d..e369333 100644
--- a/src/third_party/icu/source/common/uinit.cpp
+++ b/src/third_party/icu/source/common/uinit.cpp
@@ -1,10 +1,12 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 * Copyright (C) 2001-2015, International Business Machines
 *                Corporation and others. All Rights Reserved.
 ******************************************************************************
 *   file name:  uinit.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -12,7 +14,9 @@
 *   created by: George Rhoten
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/utypes.h"
 #include "unicode/icuplug.h"
 #include "unicode/uclean.h"
diff --git a/src/third_party/icu/source/common/uinvchar.c b/src/third_party/icu/source/common/uinvchar.cpp
similarity index 95%
rename from src/third_party/icu/source/common/uinvchar.c
rename to src/third_party/icu/source/common/uinvchar.cpp
index e0c895f..613efed 100644
--- a/src/third_party/icu/source/common/uinvchar.c
+++ b/src/third_party/icu/source/common/uinvchar.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  uinvchar.c
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:2
 *
@@ -17,7 +19,9 @@
 *   for better modularization.
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/utypes.h"
 #include "unicode/ustring.h"
 #include "udataswp.h"
@@ -445,11 +449,19 @@
     return length;
 }
 
+U_CFUNC UBool
+uprv_isEbcdicAtSign(char c) {
+    static const uint8_t ebcdicAtSigns[] = {
+        0x7C, 0x44, 0x66, 0x80, 0xAC, 0xAE, 0xAF, 0xB5, 0xEC, 0xEF, 0x00 };
+    return c != 0 && uprv_strchr((const char *)ebcdicAtSigns, c) != nullptr;
+}
+
 /* compare invariant strings; variant characters compare less than others and unlike each other */
 U_CFUNC int32_t
 uprv_compareInvAscii(const UDataSwapper *ds,
                      const char *outString, int32_t outLength,
                      const UChar *localString, int32_t localLength) {
+    (void)ds;
     int32_t minLength;
     UChar32 c1, c2;
     uint8_t c;
@@ -495,6 +507,7 @@
 uprv_compareInvEbcdic(const UDataSwapper *ds,
                       const char *outString, int32_t outLength,
                       const UChar *localString, int32_t localLength) {
+    (void)ds;
     int32_t minLength;
     UChar32 c1, c2;
     uint8_t c;
@@ -560,17 +573,22 @@
 }
 
 U_CAPI char U_EXPORT2
+uprv_ebcdicToAscii(char c) {
+    return (char)asciiFromEbcdic[(uint8_t)c];
+}
+
+U_CAPI char U_EXPORT2
 uprv_ebcdicToLowercaseAscii(char c) {
     return (char)lowercaseAsciiFromEbcdic[(uint8_t)c];
 }
 
-U_INTERNAL uint8_t* U_EXPORT2
+U_CAPI uint8_t* U_EXPORT2
 uprv_aestrncpy(uint8_t *dst, const uint8_t *src, int32_t n)
 {
   uint8_t *orig_dst = dst;
 
   if(n==-1) { 
-    n = uprv_strlen((const char*)src)+1; /* copy NUL */
+    n = static_cast<int32_t>(uprv_strlen((const char*)src)+1); /* copy NUL */
   }
   /* copy non-null */
   while(*src && n>0) {
@@ -585,13 +603,13 @@
   return orig_dst;
 }
 
-U_INTERNAL uint8_t* U_EXPORT2
+U_CAPI uint8_t* U_EXPORT2
 uprv_eastrncpy(uint8_t *dst, const uint8_t *src, int32_t n)
 {
   uint8_t *orig_dst = dst;
 
   if(n==-1) { 
-    n = uprv_strlen((const char*)src)+1; /* copy NUL */
+    n = static_cast<int32_t>(uprv_strlen((const char*)src)+1); /* copy NUL */
   }
   /* copy non-null */
   while(*src && n>0) {
diff --git a/src/third_party/icu/source/common/uinvchar.h b/src/third_party/icu/source/common/uinvchar.h
index 1a9aa78..9b7a9bd 100644
--- a/src/third_party/icu/source/common/uinvchar.h
+++ b/src/third_party/icu/source/common/uinvchar.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  uinvchar.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:2
 *
@@ -31,11 +33,11 @@
  *
  * @param s Input string pointer.
  * @param length Length of the string, can be -1 if NUL-terminated.
- * @return TRUE if s contains only invariant characters.
+ * @return true if s contains only invariant characters.
  *
  * @internal (ICU 2.8)
  */
-U_INTERNAL UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 uprv_isInvariantString(const char *s, int32_t length);
 
 /**
@@ -44,29 +46,13 @@
  *
  * @param s Input string pointer.
  * @param length Length of the string, can be -1 if NUL-terminated.
- * @return TRUE if s contains only invariant characters.
+ * @return true if s contains only invariant characters.
  *
  * @internal (ICU 2.8)
  */
-U_INTERNAL UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 uprv_isInvariantUString(const UChar *s, int32_t length);
 
-#ifdef __cplusplus
-
-/**
- * Check if a UnicodeString only contains invariant characters.
- * See utypes.h for details.
- *
- * @param s Input string.
- * @return TRUE if s contains only invariant characters.
- */
-U_INTERNAL inline UBool U_EXPORT2
-uprv_isInvariantUnicodeString(const icu::UnicodeString &s) {
-    return uprv_isInvariantUString(s.getBuffer(), s.length());
-}
-
-#endif  /* __cplusplus */
-
 /**
  * \def U_UPPER_ORDINAL
  * Get the ordinal number of an uppercase invariant character
@@ -82,11 +68,80 @@
 #   error Unknown charset family!
 #endif
 
+#ifdef __cplusplus
+
+U_NAMESPACE_BEGIN
+
+/**
+ * Like U_UPPER_ORDINAL(x) but with validation.
+ * Returns 0..25 for A..Z else a value outside 0..25.
+ */
+inline int32_t uprv_upperOrdinal(int32_t c) {
+#if U_CHARSET_FAMILY==U_ASCII_FAMILY
+    return c - 'A';
+#elif U_CHARSET_FAMILY==U_EBCDIC_FAMILY
+    // EBCDIC: A-Z (26 letters) is split into three ranges A-I (9 letters), J-R (9), S-Z (8).
+    // https://en.wikipedia.org/wiki/EBCDIC_037#Codepage_layout
+    if (c <= 'I') { return c - 'A'; }  // A-I --> 0-8
+    if (c < 'J') { return -1; }
+    if (c <= 'R') { return c - 'J' + 9; }  // J-R --> 9..17
+    if (c < 'S') { return -1; }
+    return c - 'S' + 18;  // S-Z --> 18..25
+#else
+#   error Unknown charset family!
+#endif
+}
+
+// Like U_UPPER_ORDINAL(x) but for lowercase and with validation.
+// Returns 0..25 for a..z else a value outside 0..25.
+inline int32_t uprv_lowerOrdinal(int32_t c) {
+#if U_CHARSET_FAMILY==U_ASCII_FAMILY
+    return c - 'a';
+#elif U_CHARSET_FAMILY==U_EBCDIC_FAMILY
+    // EBCDIC: a-z (26 letters) is split into three ranges a-i (9 letters), j-r (9), s-z (8).
+    // https://en.wikipedia.org/wiki/EBCDIC_037#Codepage_layout
+    if (c <= 'i') { return c - 'a'; }  // a-i --> 0-8
+    if (c < 'j') { return -1; }
+    if (c <= 'r') { return c - 'j' + 9; }  // j-r --> 9..17
+    if (c < 's') { return -1; }
+    return c - 's' + 18;  // s-z --> 18..25
+#else
+#   error Unknown charset family!
+#endif
+}
+
+U_NAMESPACE_END
+
+#endif
+
+/**
+ * Returns true if c == '@' is possible.
+ * The @ sign is variant, and the @ sign used on one
+ * EBCDIC machine won't be compiled the same way on other EBCDIC based machines.
+ * @internal
+ */
+U_CFUNC UBool
+uprv_isEbcdicAtSign(char c);
+
+/**
+ * \def uprv_isAtSign
+ * Returns true if c == '@' is possible.
+ * For ASCII, checks for exactly '@'. For EBCDIC, calls uprv_isEbcdicAtSign().
+ * @internal
+ */
+#if U_CHARSET_FAMILY==U_ASCII_FAMILY
+#   define uprv_isAtSign(c) ((c)=='@')
+#elif U_CHARSET_FAMILY==U_EBCDIC_FAMILY
+#   define uprv_isAtSign(c) uprv_isEbcdicAtSign(c)
+#else
+#   error Unknown charset family!
+#endif
+
 /**
  * Compare two EBCDIC invariant-character strings in ASCII order.
  * @internal
  */
-U_INTERNAL int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 uprv_compareInvEbcdicAsAscii(const char *s1, const char *s2);
 
 /**
@@ -103,10 +158,30 @@
 #endif
 
 /**
+ * Converts an EBCDIC invariant character to ASCII.
+ * @internal
+ */
+U_CAPI char U_EXPORT2
+uprv_ebcdicToAscii(char c);
+
+/**
+ * \def uprv_invCharToAscii
+ * Converts an invariant character to ASCII.
+ * @internal
+ */
+#if U_CHARSET_FAMILY==U_ASCII_FAMILY
+#   define uprv_invCharToAscii(c) (c)
+#elif U_CHARSET_FAMILY==U_EBCDIC_FAMILY
+#   define uprv_invCharToAscii(c) uprv_ebcdicToAscii(c)
+#else
+#   error Unknown charset family!
+#endif
+
+/**
  * Converts an EBCDIC invariant character to lowercase ASCII.
  * @internal
  */
-U_INTERNAL char U_EXPORT2
+U_CAPI char U_EXPORT2
 uprv_ebcdicToLowercaseAscii(char c);
 
 /**
@@ -127,7 +202,7 @@
  * @internal
  * @see uprv_strncpy
  */
-U_INTERNAL uint8_t* U_EXPORT2
+U_CAPI uint8_t* U_EXPORT2
 uprv_aestrncpy(uint8_t *dst, const uint8_t *src, int32_t n);
 
 
@@ -136,7 +211,7 @@
  * @internal
  * @see uprv_strncpy
  */
-U_INTERNAL uint8_t* U_EXPORT2
+U_CAPI uint8_t* U_EXPORT2
 uprv_eastrncpy(uint8_t *dst, const uint8_t *src, int32_t n);
 
 
diff --git a/src/third_party/icu/source/common/uiter.cpp b/src/third_party/icu/source/common/uiter.cpp
index 2cc76a9..b9252d8 100644
--- a/src/third_party/icu/source/common/uiter.cpp
+++ b/src/third_party/icu/source/common/uiter.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  uiter.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
diff --git a/src/third_party/icu/source/common/ulayout_props.h b/src/third_party/icu/source/common/ulayout_props.h
new file mode 100644
index 0000000..c0f028c
--- /dev/null
+++ b/src/third_party/icu/source/common/ulayout_props.h
@@ -0,0 +1,46 @@
+// © 2019 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+// ulayout_props.h
+// created: 2019feb12 Markus W. Scherer
+
+#ifndef __ULAYOUT_PROPS_H__
+#define __ULAYOUT_PROPS_H__
+
+#include "unicode/utypes.h"
+
+// file definitions ------------------------------------------------------------
+
+#define ULAYOUT_DATA_NAME "ulayout"
+#define ULAYOUT_DATA_TYPE "icu"
+
+// data format "Layo"
+#define ULAYOUT_FMT_0 0x4c
+#define ULAYOUT_FMT_1 0x61
+#define ULAYOUT_FMT_2 0x79
+#define ULAYOUT_FMT_3 0x6f
+
+// indexes into indexes[]
+enum {
+    // Element 0 stores the length of the indexes[] array.
+    ULAYOUT_IX_INDEXES_LENGTH,
+    // Elements 1..7 store the tops of consecutive code point tries.
+    // No trie is stored if the difference between two of these is less than 16.
+    ULAYOUT_IX_INPC_TRIE_TOP,
+    ULAYOUT_IX_INSC_TRIE_TOP,
+    ULAYOUT_IX_VO_TRIE_TOP,
+    ULAYOUT_IX_RESERVED_TOP,
+
+    ULAYOUT_IX_TRIES_TOP = 7,
+
+    ULAYOUT_IX_MAX_VALUES = 9,
+
+    // Length of indexes[]. Multiple of 4 to 16-align the tries.
+    ULAYOUT_IX_COUNT = 12
+};
+
+constexpr int32_t ULAYOUT_MAX_INPC_SHIFT = 24;
+constexpr int32_t ULAYOUT_MAX_INSC_SHIFT = 16;
+constexpr int32_t ULAYOUT_MAX_VO_SHIFT = 8;
+
+#endif  // __ULAYOUT_PROPS_H__
diff --git a/src/third_party/icu/source/common/ulist.c b/src/third_party/icu/source/common/ulist.cpp
similarity index 73%
rename from src/third_party/icu/source/common/ulist.c
rename to src/third_party/icu/source/common/ulist.cpp
index 6b5013b..c518043 100644
--- a/src/third_party/icu/source/common/ulist.c
+++ b/src/third_party/icu/source/common/ulist.cpp
@@ -1,6 +1,8 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
-*   Copyright (C) 2009-2014, International Business Machines
+*   Copyright (C) 2009-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 ******************************************************************************
 */
@@ -27,7 +29,6 @@
     UListNode *tail;
     
     int32_t size;
-    int32_t currentIndex;
 };
 
 static void ulist_addFirstItem(UList *list, UListNode *newItem);
@@ -49,7 +50,6 @@
     newList->head = NULL;
     newList->tail = NULL;
     newList->size = 0;
-    newList->currentIndex = -1;
     
     return newList;
 }
@@ -63,18 +63,46 @@
     newItem->previous = NULL;
     list->head = newItem;
     list->tail = newItem;
-    list->currentIndex = 0;
+}
+
+static void ulist_removeItem(UList *list, UListNode *p) {
+    if (p->previous == NULL) {
+        // p is the list head.
+        list->head = p->next;
+    } else {
+        p->previous->next = p->next;
+    }
+    if (p->next == NULL) {
+        // p is the list tail.
+        list->tail = p->previous;
+    } else {
+        p->next->previous = p->previous;
+    }
+    if (p == list->curr) {
+        list->curr = p->next;
+    }
+    --list->size;
+    if (p->forceDelete) {
+        uprv_free(p->data);
+    }
+    uprv_free(p);
 }
 
 U_CAPI void U_EXPORT2 ulist_addItemEndList(UList *list, const void *data, UBool forceDelete, UErrorCode *status) {
     UListNode *newItem = NULL;
     
     if (U_FAILURE(*status) || list == NULL || data == NULL) {
+        if (forceDelete) {
+            uprv_free((void *)data);
+        }
         return;
     }
     
     newItem = (UListNode *)uprv_malloc(sizeof(UListNode));
     if (newItem == NULL) {
+        if (forceDelete) {
+            uprv_free((void *)data);
+        }
         *status = U_MEMORY_ALLOCATION_ERROR;
         return;
     }
@@ -97,11 +125,17 @@
     UListNode *newItem = NULL;
     
     if (U_FAILURE(*status) || list == NULL || data == NULL) {
+        if (forceDelete) {
+            uprv_free((void *)data);
+        }
         return;
     }
     
     newItem = (UListNode *)uprv_malloc(sizeof(UListNode));
     if (newItem == NULL) {
+        if (forceDelete) {
+            uprv_free((void *)data);
+        }
         *status = U_MEMORY_ALLOCATION_ERROR;
         return;
     }
@@ -115,32 +149,37 @@
         newItem->next = list->head;
         list->head->previous = newItem;
         list->head = newItem;
-        list->currentIndex++;
     }
     
     list->size++;
 }
 
 U_CAPI UBool U_EXPORT2 ulist_containsString(const UList *list, const char *data, int32_t length) {
-    UBool result = FALSE;
-    const UListNode *pointer = NULL;
-    
-    if (list != NULL && list->size != 0) {
-        pointer = list->head;
-        
-        while (pointer != NULL) {
-            if (length == uprv_strlen(pointer->data)) {
+    if (list != NULL) {
+        const UListNode *pointer;
+        for (pointer = list->head; pointer != NULL; pointer = pointer->next) {
+            if (length == (int32_t)uprv_strlen((const char *)pointer->data)) {
                 if (uprv_memcmp(data, pointer->data, length) == 0) {
-                    result = TRUE;
-                    break;
+                    return TRUE;
                 }
             }
-            
-            pointer = pointer->next;
         }
     }
-    
-    return result;
+    return FALSE;
+}
+
+U_CAPI UBool U_EXPORT2 ulist_removeString(UList *list, const char *data) {
+    if (list != NULL) {
+        UListNode *pointer;
+        for (pointer = list->head; pointer != NULL; pointer = pointer->next) {
+            if (uprv_strcmp(data, (const char *)pointer->data) == 0) {
+                ulist_removeItem(list, pointer);
+                // Remove only the first occurrence, like Java LinkedList.remove(Object).
+                return TRUE;
+            }
+        }
+    }
+    return FALSE;
 }
 
 U_CAPI void *U_EXPORT2 ulist_getNext(UList *list) {
@@ -152,7 +191,6 @@
     
     curr = list->curr;
     list->curr = curr->next;
-    list->currentIndex++;
     
     return curr->data;
 }
@@ -168,7 +206,6 @@
 U_CAPI void U_EXPORT2 ulist_resetList(UList *list) {
     if (list != NULL) {
         list->curr = list->head;
-        list->currentIndex = 0;
     }
 }
 
@@ -215,7 +252,7 @@
 
     s = (const char *)ulist_getNext((UList *)(en->context));
     if (s != NULL && resultLength != NULL) {
-        *resultLength = uprv_strlen(s);
+        *resultLength = static_cast<int32_t>(uprv_strlen(s));
     }
     return s;
 }
@@ -231,4 +268,3 @@
 U_CAPI UList * U_EXPORT2 ulist_getListFromEnum(UEnumeration *en) {
     return (UList *)(en->context);
 }
-
diff --git a/src/third_party/icu/source/common/ulist.h b/src/third_party/icu/source/common/ulist.h
index 4789247..de58a4a 100644
--- a/src/third_party/icu/source/common/ulist.h
+++ b/src/third_party/icu/source/common/ulist.h
@@ -1,6 +1,8 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
-*   Copyright (C) 2009, International Business Machines
+*   Copyright (C) 2009-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 ******************************************************************************
 */
@@ -22,6 +24,8 @@
 
 U_CAPI UBool U_EXPORT2 ulist_containsString(const UList *list, const char *data, int32_t length);
 
+U_CAPI UBool U_EXPORT2 ulist_removeString(UList *list, const char *data);
+
 U_CAPI void *U_EXPORT2 ulist_getNext(UList *list);
 
 U_CAPI int32_t U_EXPORT2 ulist_getListSize(const UList *list);
diff --git a/src/third_party/icu/source/common/ulistformatter.cpp b/src/third_party/icu/source/common/ulistformatter.cpp
index 7fb1e94..b2e01d0 100644
--- a/src/third_party/icu/source/common/ulistformatter.cpp
+++ b/src/third_party/icu/source/common/ulistformatter.cpp
@@ -9,7 +9,9 @@
 
 #if !UCONFIG_NO_FORMATTING
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/ulistformatter.h"
 #include "unicode/listformatter.h"
 #include "unicode/localpointer.h"
diff --git a/src/third_party/icu/source/common/uloc.cpp b/src/third_party/icu/source/common/uloc.cpp
index 05ef513..298ff3b 100644
--- a/src/third_party/icu/source/common/uloc.cpp
+++ b/src/third_party/icu/source/common/uloc.cpp
@@ -1,6 +1,8 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
-*   Copyright (C) 1997-2015, International Business Machines
+*   Copyright (C) 1997-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 **********************************************************************
 *
@@ -28,13 +30,19 @@
      l = lang, C = ctry, M = charmap, V = variant
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
 #include "starboard/client_porting/poem/stdio_poem.h"
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
+#include "unicode/bytestream.h"
+#include "unicode/errorcode.h"
+#include "unicode/stringpiece.h"
 #include "unicode/utypes.h"
 #include "unicode/ustring.h"
 #include "unicode/uloc.h"
 
+#include "bytesinkutil.h"
 #include "putilimp.h"
 #include "ustr_imp.h"
 #include "ulocimp.h"
@@ -45,23 +53,15 @@
 #include "uarrsort.h"
 #include "uenumimp.h"
 #include "uassert.h"
+#include "charstr.h"
 
-#if !defined(STARBOARD)
-#include <stdio.h> /* for sprintf */
-#endif
+U_NAMESPACE_USE
 
 /* ### Declarations **************************************************/
 
 /* Locale stuff from locid.cpp */
 U_CFUNC void locale_set_default(const char *id);
 U_CFUNC const char *locale_get_default(void);
-U_CFUNC int32_t
-locale_getKeywords(const char *localeID,
-            char prev,
-            char *keywords, int32_t keywordCapacity,
-            char *values, int32_t valuesCapacity, int32_t *valLen,
-            UBool valuesToo,
-            UErrorCode *status);
 
 /* ### Data tables **************************************************/
 
@@ -98,91 +98,93 @@
  */
 /* Generated using org.unicode.cldr.icu.GenerateISO639LanguageTables */
 /* ISO639 table version is 20150505 */
+/* Subsequent hand addition of selected languages */
 static const char * const LANGUAGES[] = {
-    "aa",  "ab",  "ace", "ach", "ada", "ady", "ae",  "aeb", 
-    "af",  "afh", "agq", "ain", "ak",  "akk", "akz", "ale", 
-    "aln", "alt", "am",  "an",  "ang", "anp", "ar",  "arc", 
-    "arn", "aro", "arp", "arq", "arw", "ary", "arz", "as",  
-    "asa", "ase", "ast", "av",  "avk", "awa", "ay",  "az",  
-    "ba",  "bal", "ban", "bar", "bas", "bax", "bbc", "bbj", 
-    "be",  "bej", "bem", "bew", "bez", "bfd", "bfq", "bg",  
-    "bgn", "bho", "bi",  "bik", "bin", "bjn", "bkm", "bla", 
-    "bm",  "bn",  "bo",  "bpy", "bqi", "br",  "bra", "brh", 
-    "brx", "bs",  "bss", "bua", "bug", "bum", "byn", "byv", 
-    "ca",  "cad", "car", "cay", "cch", "ce",  "ceb", "cgg", 
-    "ch",  "chb", "chg", "chk", "chm", "chn", "cho", "chp", 
-    "chr", "chy", "ckb", "co",  "cop", "cps", "cr",  "crh", 
-    "cs",  "csb", "cu",  "cv",  "cy",  
-    "da",  "dak", "dar", "dav", "de",  "del", "den", "dgr", 
-    "din", "dje", "doi", "dsb", "dtp", "dua", "dum", "dv",  
-    "dyo", "dyu", "dz",  "dzg", 
-    "ebu", "ee",  "efi", "egl", "egy", "eka", "el",  "elx", 
-    "en",  "enm", "eo",  "es",  "esu", "et",  "eu",  "ewo", 
-    "ext", 
-    "fa",  "fan", "fat", "ff",  "fi",  "fil", "fit", "fj",  
-    "fo",  "fon", "fr",  "frc", "frm", "fro", "frp", "frr", 
-    "frs", "fur", "fy",  
-    "ga",  "gaa", "gag", "gan", "gay", "gba", "gbz", "gd",  
-    "gez", "gil", "gl",  "glk", "gmh", "gn",  "goh", "gom", 
-    "gon", "gor", "got", "grb", "grc", "gsw", "gu",  "guc", 
-    "gur", "guz", "gv",  "gwi", 
-    "ha",  "hai", "hak", "haw", "he",  "hi",  "hif", "hil", 
-    "hit", "hmn", "ho",  "hr",  "hsb", "hsn", "ht",  "hu",  
-    "hup", "hy",  "hz",  
-    "ia",  "iba", "ibb", "id",  "ie",  "ig",  "ii",  "ik",  
-    "ilo", "inh", "io",  "is",  "it",  "iu",  "izh", 
-    "ja",  "jam", "jbo", "jgo", "jmc", "jpr", "jrb", "jut", 
-    "jv",  
-    "ka",  "kaa", "kab", "kac", "kaj", "kam", "kaw", "kbd", 
-    "kbl", "kcg", "kde", "kea", "ken", "kfo", "kg",  "kgp", 
-    "kha", "kho", "khq", "khw", "ki",  "kiu", "kj",  "kk",  
-    "kkj", "kl",  "kln", "km",  "kmb", "kn",  "ko",  "koi", 
-    "kok", "kos", "kpe", "kr",  "krc", "kri", "krj", "krl", 
-    "kru", "ks",  "ksb", "ksf", "ksh", "ku",  "kum", "kut", 
-    "kv",  "kw",  "ky",  
-    "la",  "lad", "lag", "lah", "lam", "lb",  "lez", "lfn", 
-    "lg",  "li",  "lij", "liv", "lkt", "lmo", "ln",  "lo",  
-    "lol", "loz", "lrc", "lt",  "ltg", "lu",  "lua", "lui", 
-    "lun", "luo", "lus", "luy", "lv",  "lzh", "lzz", 
-    "mad", "maf", "mag", "mai", "mak", "man", "mas", "mde", 
-    "mdf", "mdh", "mdr", "men", "mer", "mfe", "mg",  "mga", 
-    "mgh", "mgo", "mh",  "mi",  "mic", "min", "mis", "mk",  
-    "ml",  "mn",  "mnc", "mni", "moh", "mos", "mr",  "mrj", 
-    "ms",  "mt",  "mua", "mul", "mus", "mwl", "mwr", "mwv", 
-    "my",  "mye", "myv", "mzn", 
-    "na",  "nan", "nap", "naq", "nb",  "nd",  "nds", "ne",  
-    "new", "ng",  "nia", "niu", "njo", "nl",  "nmg", "nn",  
-    "nnh", "no",  "nog", "non", "nov", "nqo", "nr",  "nso", 
-    "nus", "nv",  "nwc", "ny",  "nym", "nyn", "nyo", "nzi", 
-    "oc",  "oj",  "om",  "or",  "os",  "osa", "ota", 
-    "pa",  "pag", "pal", "pam", "pap", "pau", "pcd", "pdc", 
-    "pdt", "peo", "pfl", "phn", "pi",  "pl",  "pms", "pnt", 
-    "pon", "prg", "pro", "ps",  "pt",  
-    "qu",  "quc", "qug", 
-    "raj", "rap", "rar", "rgn", "rif", "rm",  "rn",  "ro",  
-    "rof", "rom", "rtm", "ru",  "rue", "rug", "rup", 
-    "rw",  "rwk", 
-    "sa",  "sad", "sah", "sam", "saq", "sas", "sat", "saz", 
-    "sba", "sbp", "sc",  "scn", "sco", "sd",  "sdc", "sdh", 
-    "se",  "see", "seh", "sei", "sel", "ses", "sg",  "sga", 
-    "sgs", "shi", "shn", "shu", "si",  "sid", "sk",  
-    "sl",  "sli", "sly", "sm",  "sma", "smj", "smn", "sms", 
-    "sn",  "snk", "so",  "sog", "sq",  "sr",  "srn", "srr", 
-    "ss",  "ssy", "st",  "stq", "su",  "suk", "sus", "sux", 
-    "sv",  "sw",  "swb", "swc", "syc", "syr", "szl", 
-    "ta",  "tcy", "te",  "tem", "teo", "ter", "tet", "tg",  
-    "th",  "ti",  "tig", "tiv", "tk",  "tkl", "tkr", "tl",  
-    "tlh", "tli", "tly", "tmh", "tn",  "to",  "tog", "tpi", 
-    "tr",  "tru", "trv", "ts",  "tsd", "tsi", "tt",  "ttt", 
-    "tum", "tvl", "tw",  "twq", "ty",  "tyv", "tzm", 
-    "udm", "ug",  "uga", "uk",  "umb", "und", "ur",  "uz",  
-    "vai", "ve",  "vec", "vep", "vi",  "vls", "vmf", "vo",  
-    "vot", "vro", "vun", 
-    "wa",  "wae", "wal", "war", "was", "wbp", "wo",  "wuu", 
-    "xal", "xh",  "xmf", "xog", 
-    "yao", "yap", "yav", "ybb", "yi",  "yo",  "yrl", "yue", 
-    "za",  "zap", "zbl", "zea", "zen", "zgh", "zh",  "zu",  
-    "zun", "zxx", "zza", 
+    "aa",  "ab",  "ace", "ach", "ada", "ady", "ae",  "aeb",
+    "af",  "afh", "agq", "ain", "ak",  "akk", "akz", "ale",
+    "aln", "alt", "am",  "an",  "ang", "anp", "ar",  "arc",
+    "arn", "aro", "arp", "arq", "ars", "arw", "ary", "arz", "as",
+    "asa", "ase", "ast", "av",  "avk", "awa", "ay",  "az",
+    "ba",  "bal", "ban", "bar", "bas", "bax", "bbc", "bbj",
+    "be",  "bej", "bem", "bew", "bez", "bfd", "bfq", "bg",
+    "bgn", "bho", "bi",  "bik", "bin", "bjn", "bkm", "bla",
+    "bm",  "bn",  "bo",  "bpy", "bqi", "br",  "bra", "brh",
+    "brx", "bs",  "bss", "bua", "bug", "bum", "byn", "byv",
+    "ca",  "cad", "car", "cay", "cch", "ccp", "ce",  "ceb", "cgg",
+    "ch",  "chb", "chg", "chk", "chm", "chn", "cho", "chp",
+    "chr", "chy", "ckb", "co",  "cop", "cps", "cr",  "crh",
+    "cs",  "csb", "cu",  "cv",  "cy",
+    "da",  "dak", "dar", "dav", "de",  "del", "den", "dgr",
+    "din", "dje", "doi", "dsb", "dtp", "dua", "dum", "dv",
+    "dyo", "dyu", "dz",  "dzg",
+    "ebu", "ee",  "efi", "egl", "egy", "eka", "el",  "elx",
+    "en",  "enm", "eo",  "es",  "esu", "et",  "eu",  "ewo",
+    "ext",
+    "fa",  "fan", "fat", "ff",  "fi",  "fil", "fit", "fj",
+    "fo",  "fon", "fr",  "frc", "frm", "fro", "frp", "frr",
+    "frs", "fur", "fy",
+    "ga",  "gaa", "gag", "gan", "gay", "gba", "gbz", "gd",
+    "gez", "gil", "gl",  "glk", "gmh", "gn",  "goh", "gom",
+    "gon", "gor", "got", "grb", "grc", "gsw", "gu",  "guc",
+    "gur", "guz", "gv",  "gwi",
+    "ha",  "hai", "hak", "haw", "he",  "hi",  "hif", "hil",
+    "hit", "hmn", "ho",  "hr",  "hsb", "hsn", "ht",  "hu",
+    "hup", "hy",  "hz",
+    "ia",  "iba", "ibb", "id",  "ie",  "ig",  "ii",  "ik",
+    "ilo", "inh", "io",  "is",  "it",  "iu",  "izh",
+    "ja",  "jam", "jbo", "jgo", "jmc", "jpr", "jrb", "jut",
+    "jv",
+    "ka",  "kaa", "kab", "kac", "kaj", "kam", "kaw", "kbd",
+    "kbl", "kcg", "kde", "kea", "ken", "kfo", "kg",  "kgp",
+    "kha", "kho", "khq", "khw", "ki",  "kiu", "kj",  "kk",
+    "kkj", "kl",  "kln", "km",  "kmb", "kn",  "ko",  "koi",
+    "kok", "kos", "kpe", "kr",  "krc", "kri", "krj", "krl",
+    "kru", "ks",  "ksb", "ksf", "ksh", "ku",  "kum", "kut",
+    "kv",  "kw",  "ky",
+    "la",  "lad", "lag", "lah", "lam", "lb",  "lez", "lfn",
+    "lg",  "li",  "lij", "liv", "lkt", "lmo", "ln",  "lo",
+    "lol", "loz", "lrc", "lt",  "ltg", "lu",  "lua", "lui",
+    "lun", "luo", "lus", "luy", "lv",  "lzh", "lzz",
+    "mad", "maf", "mag", "mai", "mak", "man", "mas", "mde",
+    "mdf", "mdh", "mdr", "men", "mer", "mfe", "mg",  "mga",
+    "mgh", "mgo", "mh",  "mi",  "mic", "min", "mis", "mk",
+    "ml",  "mn",  "mnc", "mni", "mo",
+    "moh", "mos", "mr",  "mrj",
+    "ms",  "mt",  "mua", "mul", "mus", "mwl", "mwr", "mwv",
+    "my",  "mye", "myv", "mzn",
+    "na",  "nan", "nap", "naq", "nb",  "nd",  "nds", "ne",
+    "new", "ng",  "nia", "niu", "njo", "nl",  "nmg", "nn",
+    "nnh", "no",  "nog", "non", "nov", "nqo", "nr",  "nso",
+    "nus", "nv",  "nwc", "ny",  "nym", "nyn", "nyo", "nzi",
+    "oc",  "oj",  "om",  "or",  "os",  "osa", "ota",
+    "pa",  "pag", "pal", "pam", "pap", "pau", "pcd", "pcm", "pdc",
+    "pdt", "peo", "pfl", "phn", "pi",  "pl",  "pms", "pnt",
+    "pon", "prg", "pro", "ps",  "pt",
+    "qu",  "quc", "qug",
+    "raj", "rap", "rar", "rgn", "rif", "rm",  "rn",  "ro",
+    "rof", "rom", "rtm", "ru",  "rue", "rug", "rup",
+    "rw",  "rwk",
+    "sa",  "sad", "sah", "sam", "saq", "sas", "sat", "saz",
+    "sba", "sbp", "sc",  "scn", "sco", "sd",  "sdc", "sdh",
+    "se",  "see", "seh", "sei", "sel", "ses", "sg",  "sga",
+    "sgs", "shi", "shn", "shu", "si",  "sid", "sk",
+    "sl",  "sli", "sly", "sm",  "sma", "smj", "smn", "sms",
+    "sn",  "snk", "so",  "sog", "sq",  "sr",  "srn", "srr",
+    "ss",  "ssy", "st",  "stq", "su",  "suk", "sus", "sux",
+    "sv",  "sw",  "swb", "swc", "syc", "syr", "szl",
+    "ta",  "tcy", "te",  "tem", "teo", "ter", "tet", "tg",
+    "th",  "ti",  "tig", "tiv", "tk",  "tkl", "tkr", "tl",
+    "tlh", "tli", "tly", "tmh", "tn",  "to",  "tog", "tpi",
+    "tr",  "tru", "trv", "ts",  "tsd", "tsi", "tt",  "ttt",
+    "tum", "tvl", "tw",  "twq", "ty",  "tyv", "tzm",
+    "udm", "ug",  "uga", "uk",  "umb", "und", "ur",  "uz",
+    "vai", "ve",  "vec", "vep", "vi",  "vls", "vmf", "vo",
+    "vot", "vro", "vun",
+    "wa",  "wae", "wal", "war", "was", "wbp", "wo",  "wuu",
+    "xal", "xh",  "xmf", "xog",
+    "yao", "yap", "yav", "ybb", "yi",  "yo",  "yrl", "yue",
+    "za",  "zap", "zbl", "zea", "zen", "zgh", "zh",  "zu",
+    "zun", "zxx", "zza",
 NULL,
     "in",  "iw",  "ji",  "jw",  "sh",    /* obsolete language codes */
 NULL
@@ -213,91 +215,93 @@
  */
 /* Generated using org.unicode.cldr.icu.GenerateISO639LanguageTables */
 /* ISO639 table version is 20150505 */
+/* Subsequent hand addition of selected languages */
 static const char * const LANGUAGES_3[] = {
-    "aar", "abk", "ace", "ach", "ada", "ady", "ave", "aeb", 
-    "afr", "afh", "agq", "ain", "aka", "akk", "akz", "ale", 
-    "aln", "alt", "amh", "arg", "ang", "anp", "ara", "arc", 
-    "arn", "aro", "arp", "arq", "arw", "ary", "arz", "asm", 
-    "asa", "ase", "ast", "ava", "avk", "awa", "aym", "aze", 
-    "bak", "bal", "ban", "bar", "bas", "bax", "bbc", "bbj", 
-    "bel", "bej", "bem", "bew", "bez", "bfd", "bfq", "bul", 
-    "bgn", "bho", "bis", "bik", "bin", "bjn", "bkm", "bla", 
-    "bam", "ben", "bod", "bpy", "bqi", "bre", "bra", "brh", 
-    "brx", "bos", "bss", "bua", "bug", "bum", "byn", "byv", 
-    "cat", "cad", "car", "cay", "cch", "che", "ceb", "cgg", 
-    "cha", "chb", "chg", "chk", "chm", "chn", "cho", "chp", 
-    "chr", "chy", "ckb", "cos", "cop", "cps", "cre", "crh", 
-    "ces", "csb", "chu", "chv", "cym", 
-    "dan", "dak", "dar", "dav", "deu", "del", "den", "dgr", 
-    "din", "dje", "doi", "dsb", "dtp", "dua", "dum", "div", 
-    "dyo", "dyu", "dzo", "dzg", 
-    "ebu", "ewe", "efi", "egl", "egy", "eka", "ell", "elx", 
-    "eng", "enm", "epo", "spa", "esu", "est", "eus", "ewo", 
-    "ext", 
-    "fas", "fan", "fat", "ful", "fin", "fil", "fit", "fij", 
-    "fao", "fon", "fra", "frc", "frm", "fro", "frp", "frr", 
-    "frs", "fur", "fry", 
-    "gle", "gaa", "gag", "gan", "gay", "gba", "gbz", "gla", 
-    "gez", "gil", "glg", "glk", "gmh", "grn", "goh", "gom", 
-    "gon", "gor", "got", "grb", "grc", "gsw", "guj", "guc", 
-    "gur", "guz", "glv", "gwi", 
-    "hau", "hai", "hak", "haw", "heb", "hin", "hif", "hil", 
-    "hit", "hmn", "hmo", "hrv", "hsb", "hsn", "hat", "hun", 
-    "hup", "hye", "her", 
-    "ina", "iba", "ibb", "ind", "ile", "ibo", "iii", "ipk", 
-    "ilo", "inh", "ido", "isl", "ita", "iku", "izh", 
-    "jpn", "jam", "jbo", "jgo", "jmc", "jpr", "jrb", "jut", 
-    "jav", 
-    "kat", "kaa", "kab", "kac", "kaj", "kam", "kaw", "kbd", 
-    "kbl", "kcg", "kde", "kea", "ken", "kfo", "kon", "kgp", 
-    "kha", "kho", "khq", "khw", "kik", "kiu", "kua", "kaz", 
-    "kkj", "kal", "kln", "khm", "kmb", "kan", "kor", "koi", 
-    "kok", "kos", "kpe", "kau", "krc", "kri", "krj", "krl", 
-    "kru", "kas", "ksb", "ksf", "ksh", "kur", "kum", "kut", 
-    "kom", "cor", "kir", 
-    "lat", "lad", "lag", "lah", "lam", "ltz", "lez", "lfn", 
-    "lug", "lim", "lij", "liv", "lkt", "lmo", "lin", "lao", 
-    "lol", "loz", "lrc", "lit", "ltg", "lub", "lua", "lui", 
-    "lun", "luo", "lus", "luy", "lav", "lzh", "lzz", 
-    "mad", "maf", "mag", "mai", "mak", "man", "mas", "mde", 
-    "mdf", "mdh", "mdr", "men", "mer", "mfe", "mlg", "mga", 
-    "mgh", "mgo", "mah", "mri", "mic", "min", "mis", "mkd", 
-    "mal", "mon", "mnc", "mni", "moh", "mos", "mar", "mrj", 
-    "msa", "mlt", "mua", "mul", "mus", "mwl", "mwr", "mwv", 
-    "mya", "mye", "myv", "mzn", 
-    "nau", "nan", "nap", "naq", "nob", "nde", "nds", "nep", 
-    "new", "ndo", "nia", "niu", "njo", "nld", "nmg", "nno", 
-    "nnh", "nor", "nog", "non", "nov", "nqo", "nbl", "nso", 
-    "nus", "nav", "nwc", "nya", "nym", "nyn", "nyo", "nzi", 
-    "oci", "oji", "orm", "ori", "oss", "osa", "ota", 
-    "pan", "pag", "pal", "pam", "pap", "pau", "pcd", "pdc", 
-    "pdt", "peo", "pfl", "phn", "pli", "pol", "pms", "pnt", 
-    "pon", "prg", "pro", "pus", "por", 
-    "que", "quc", "qug", 
-    "raj", "rap", "rar", "rgn", "rif", "roh", "run", "ron", 
-    "rof", "rom", "rtm", "rus", "rue", "rug", "rup", 
-    "kin", "rwk", 
-    "san", "sad", "sah", "sam", "saq", "sas", "sat", "saz", 
-    "sba", "sbp", "srd", "scn", "sco", "snd", "sdc", "sdh", 
-    "sme", "see", "seh", "sei", "sel", "ses", "sag", "sga", 
-    "sgs", "shi", "shn", "shu", "sin", "sid", "slk", 
-    "slv", "sli", "sly", "smo", "sma", "smj", "smn", "sms", 
-    "sna", "snk", "som", "sog", "sqi", "srp", "srn", "srr", 
-    "ssw", "ssy", "sot", "stq", "sun", "suk", "sus", "sux", 
-    "swe", "swa", "swb", "swc", "syc", "syr", "szl", 
-    "tam", "tcy", "tel", "tem", "teo", "ter", "tet", "tgk", 
-    "tha", "tir", "tig", "tiv", "tuk", "tkl", "tkr", "tgl", 
-    "tlh", "tli", "tly", "tmh", "tsn", "ton", "tog", "tpi", 
-    "tur", "tru", "trv", "tso", "tsd", "tsi", "tat", "ttt", 
-    "tum", "tvl", "twi", "twq", "tah", "tyv", "tzm", 
-    "udm", "uig", "uga", "ukr", "umb", "und", "urd", "uzb", 
-    "vai", "ven", "vec", "vep", "vie", "vls", "vmf", "vol", 
-    "vot", "vro", "vun", 
-    "wln", "wae", "wal", "war", "was", "wbp", "wol", "wuu", 
-    "xal", "xho", "xmf", "xog", 
-    "yao", "yap", "yav", "ybb", "yid", "yor", "yrl", "yue", 
-    "zha", "zap", "zbl", "zea", "zen", "zgh", "zho", "zul", 
-    "zun", "zxx", "zza", 
+    "aar", "abk", "ace", "ach", "ada", "ady", "ave", "aeb",
+    "afr", "afh", "agq", "ain", "aka", "akk", "akz", "ale",
+    "aln", "alt", "amh", "arg", "ang", "anp", "ara", "arc",
+    "arn", "aro", "arp", "arq", "ars", "arw", "ary", "arz", "asm",
+    "asa", "ase", "ast", "ava", "avk", "awa", "aym", "aze",
+    "bak", "bal", "ban", "bar", "bas", "bax", "bbc", "bbj",
+    "bel", "bej", "bem", "bew", "bez", "bfd", "bfq", "bul",
+    "bgn", "bho", "bis", "bik", "bin", "bjn", "bkm", "bla",
+    "bam", "ben", "bod", "bpy", "bqi", "bre", "bra", "brh",
+    "brx", "bos", "bss", "bua", "bug", "bum", "byn", "byv",
+    "cat", "cad", "car", "cay", "cch", "ccp", "che", "ceb", "cgg",
+    "cha", "chb", "chg", "chk", "chm", "chn", "cho", "chp",
+    "chr", "chy", "ckb", "cos", "cop", "cps", "cre", "crh",
+    "ces", "csb", "chu", "chv", "cym",
+    "dan", "dak", "dar", "dav", "deu", "del", "den", "dgr",
+    "din", "dje", "doi", "dsb", "dtp", "dua", "dum", "div",
+    "dyo", "dyu", "dzo", "dzg",
+    "ebu", "ewe", "efi", "egl", "egy", "eka", "ell", "elx",
+    "eng", "enm", "epo", "spa", "esu", "est", "eus", "ewo",
+    "ext",
+    "fas", "fan", "fat", "ful", "fin", "fil", "fit", "fij",
+    "fao", "fon", "fra", "frc", "frm", "fro", "frp", "frr",
+    "frs", "fur", "fry",
+    "gle", "gaa", "gag", "gan", "gay", "gba", "gbz", "gla",
+    "gez", "gil", "glg", "glk", "gmh", "grn", "goh", "gom",
+    "gon", "gor", "got", "grb", "grc", "gsw", "guj", "guc",
+    "gur", "guz", "glv", "gwi",
+    "hau", "hai", "hak", "haw", "heb", "hin", "hif", "hil",
+    "hit", "hmn", "hmo", "hrv", "hsb", "hsn", "hat", "hun",
+    "hup", "hye", "her",
+    "ina", "iba", "ibb", "ind", "ile", "ibo", "iii", "ipk",
+    "ilo", "inh", "ido", "isl", "ita", "iku", "izh",
+    "jpn", "jam", "jbo", "jgo", "jmc", "jpr", "jrb", "jut",
+    "jav",
+    "kat", "kaa", "kab", "kac", "kaj", "kam", "kaw", "kbd",
+    "kbl", "kcg", "kde", "kea", "ken", "kfo", "kon", "kgp",
+    "kha", "kho", "khq", "khw", "kik", "kiu", "kua", "kaz",
+    "kkj", "kal", "kln", "khm", "kmb", "kan", "kor", "koi",
+    "kok", "kos", "kpe", "kau", "krc", "kri", "krj", "krl",
+    "kru", "kas", "ksb", "ksf", "ksh", "kur", "kum", "kut",
+    "kom", "cor", "kir",
+    "lat", "lad", "lag", "lah", "lam", "ltz", "lez", "lfn",
+    "lug", "lim", "lij", "liv", "lkt", "lmo", "lin", "lao",
+    "lol", "loz", "lrc", "lit", "ltg", "lub", "lua", "lui",
+    "lun", "luo", "lus", "luy", "lav", "lzh", "lzz",
+    "mad", "maf", "mag", "mai", "mak", "man", "mas", "mde",
+    "mdf", "mdh", "mdr", "men", "mer", "mfe", "mlg", "mga",
+    "mgh", "mgo", "mah", "mri", "mic", "min", "mis", "mkd",
+    "mal", "mon", "mnc", "mni", "mol",
+    "moh", "mos", "mar", "mrj",
+    "msa", "mlt", "mua", "mul", "mus", "mwl", "mwr", "mwv",
+    "mya", "mye", "myv", "mzn",
+    "nau", "nan", "nap", "naq", "nob", "nde", "nds", "nep",
+    "new", "ndo", "nia", "niu", "njo", "nld", "nmg", "nno",
+    "nnh", "nor", "nog", "non", "nov", "nqo", "nbl", "nso",
+    "nus", "nav", "nwc", "nya", "nym", "nyn", "nyo", "nzi",
+    "oci", "oji", "orm", "ori", "oss", "osa", "ota",
+    "pan", "pag", "pal", "pam", "pap", "pau", "pcd", "pcm", "pdc",
+    "pdt", "peo", "pfl", "phn", "pli", "pol", "pms", "pnt",
+    "pon", "prg", "pro", "pus", "por",
+    "que", "quc", "qug",
+    "raj", "rap", "rar", "rgn", "rif", "roh", "run", "ron",
+    "rof", "rom", "rtm", "rus", "rue", "rug", "rup",
+    "kin", "rwk",
+    "san", "sad", "sah", "sam", "saq", "sas", "sat", "saz",
+    "sba", "sbp", "srd", "scn", "sco", "snd", "sdc", "sdh",
+    "sme", "see", "seh", "sei", "sel", "ses", "sag", "sga",
+    "sgs", "shi", "shn", "shu", "sin", "sid", "slk",
+    "slv", "sli", "sly", "smo", "sma", "smj", "smn", "sms",
+    "sna", "snk", "som", "sog", "sqi", "srp", "srn", "srr",
+    "ssw", "ssy", "sot", "stq", "sun", "suk", "sus", "sux",
+    "swe", "swa", "swb", "swc", "syc", "syr", "szl",
+    "tam", "tcy", "tel", "tem", "teo", "ter", "tet", "tgk",
+    "tha", "tir", "tig", "tiv", "tuk", "tkl", "tkr", "tgl",
+    "tlh", "tli", "tly", "tmh", "tsn", "ton", "tog", "tpi",
+    "tur", "tru", "trv", "tso", "tsd", "tsi", "tat", "ttt",
+    "tum", "tvl", "twi", "twq", "tah", "tyv", "tzm",
+    "udm", "uig", "uga", "ukr", "umb", "und", "urd", "uzb",
+    "vai", "ven", "vec", "vep", "vie", "vls", "vmf", "vol",
+    "vot", "vro", "vun",
+    "wln", "wae", "wal", "war", "was", "wbp", "wol", "wuu",
+    "xal", "xho", "xmf", "xog",
+    "yao", "yap", "yav", "ybb", "yid", "yor", "yrl", "yue",
+    "zha", "zap", "zbl", "zea", "zen", "zgh", "zho", "zul",
+    "zun", "zxx", "zza",
 NULL,
 /*  "in",  "iw",  "ji",  "jw",  "sh",                          */
     "ind", "heb", "yid", "jaw", "srp",
@@ -369,9 +373,9 @@
 };
 static const char* const REPLACEMENT_COUNTRIES[] = {
 /*  "AN", "BU", "CS", "DD", "DY", "FX", "HV", "NH", "RH", "SU", "TP", "UK", "VD", "YD", "YU", "ZR" */
-    "CW", "MM", "RS", "DE", "BJ", "FR", "BF", "VU", "ZW", "RU", "TL", "GB", "VN", "YE", "RS", "CD", NULL, NULL  /* replacement country codes */      
+    "CW", "MM", "RS", "DE", "BJ", "FR", "BF", "VU", "ZW", "RU", "TL", "GB", "VN", "YE", "RS", "CD", NULL, NULL  /* replacement country codes */
 };
-    
+
 /**
  * Table of 3-letter country codes.
  *
@@ -455,8 +459,6 @@
 typedef struct CanonicalizationMap {
     const char *id;          /* input ID */
     const char *canonicalID; /* canonicalized output ID */
-    const char *keyword;     /* keyword, or NULL if none */
-    const char *value;       /* keyword value, or NULL if kw==NULL */
 } CanonicalizationMap;
 
 /**
@@ -464,79 +466,35 @@
  * different semantic kinds of transformations.
  */
 static const CanonicalizationMap CANONICALIZE_MAP[] = {
-    { "",               "en_US_POSIX", NULL, NULL }, /* .NET name */
-    { "c",              "en_US_POSIX", NULL, NULL }, /* POSIX name */
-    { "posix",          "en_US_POSIX", NULL, NULL }, /* POSIX name (alias of C) */
-    { "art_LOJBAN",     "jbo", NULL, NULL }, /* registered name */
-    { "az_AZ_CYRL",     "az_Cyrl_AZ", NULL, NULL }, /* .NET name */
-    { "az_AZ_LATN",     "az_Latn_AZ", NULL, NULL }, /* .NET name */
-    { "ca_ES_PREEURO",  "ca_ES", "currency", "ESP" },
-    { "de__PHONEBOOK",  "de", "collation", "phonebook" }, /* Old ICU name */
-    { "de_AT_PREEURO",  "de_AT", "currency", "ATS" },
-    { "de_DE_PREEURO",  "de_DE", "currency", "DEM" },
-    { "de_LU_PREEURO",  "de_LU", "currency", "LUF" },
-    { "el_GR_PREEURO",  "el_GR", "currency", "GRD" },
-    { "en_BE_PREEURO",  "en_BE", "currency", "BEF" },
-    { "en_IE_PREEURO",  "en_IE", "currency", "IEP" },
-    { "es__TRADITIONAL", "es", "collation", "traditional" }, /* Old ICU name */
-    { "es_ES_PREEURO",  "es_ES", "currency", "ESP" },
-    { "eu_ES_PREEURO",  "eu_ES", "currency", "ESP" },
-    { "fi_FI_PREEURO",  "fi_FI", "currency", "FIM" },
-    { "fr_BE_PREEURO",  "fr_BE", "currency", "BEF" },
-    { "fr_FR_PREEURO",  "fr_FR", "currency", "FRF" },
-    { "fr_LU_PREEURO",  "fr_LU", "currency", "LUF" },
-    { "ga_IE_PREEURO",  "ga_IE", "currency", "IEP" },
-    { "gl_ES_PREEURO",  "gl_ES", "currency", "ESP" },
-    { "hi__DIRECT",     "hi", "collation", "direct" }, /* Old ICU name */
-    { "it_IT_PREEURO",  "it_IT", "currency", "ITL" },
-    { "ja_JP_TRADITIONAL", "ja_JP", "calendar", "japanese" }, /* Old ICU name */
-    { "nb_NO_NY",       "nn_NO", NULL, NULL },  /* "markus said this was ok" :-) */
-    { "nl_BE_PREEURO",  "nl_BE", "currency", "BEF" },
-    { "nl_NL_PREEURO",  "nl_NL", "currency", "NLG" },
-    { "pt_PT_PREEURO",  "pt_PT", "currency", "PTE" },
-    { "sr_SP_CYRL",     "sr_Cyrl_RS", NULL, NULL }, /* .NET name */
-    { "sr_SP_LATN",     "sr_Latn_RS", NULL, NULL }, /* .NET name */
-    { "sr_YU_CYRILLIC", "sr_Cyrl_RS", NULL, NULL }, /* Linux name */
-    { "th_TH_TRADITIONAL", "th_TH", "calendar", "buddhist" }, /* Old ICU name */
-    { "uz_UZ_CYRILLIC", "uz_Cyrl_UZ", NULL, NULL }, /* Linux name */
-    { "uz_UZ_CYRL",     "uz_Cyrl_UZ", NULL, NULL }, /* .NET name */
-    { "uz_UZ_LATN",     "uz_Latn_UZ", NULL, NULL }, /* .NET name */
-    { "zh_CHS",         "zh_Hans", NULL, NULL }, /* .NET name */
-    { "zh_CHT",         "zh_Hant", NULL, NULL }, /* .NET name */
-    { "zh_GAN",         "gan", NULL, NULL }, /* registered name */
-    { "zh_GUOYU",       "zh", NULL, NULL }, /* registered name */
-    { "zh_HAKKA",       "hak", NULL, NULL }, /* registered name */
-    { "zh_MIN_NAN",     "nan", NULL, NULL }, /* registered name */
-    { "zh_WUU",         "wuu", NULL, NULL }, /* registered name */
-    { "zh_XIANG",       "hsn", NULL, NULL }, /* registered name */
-    { "zh_YUE",         "yue", NULL, NULL }, /* registered name */
-};
-
-typedef struct VariantMap {
-    const char *variant;          /* input ID */
-    const char *keyword;     /* keyword, or NULL if none */
-    const char *value;       /* keyword value, or NULL if kw==NULL */
-} VariantMap;
-
-static const VariantMap VARIANT_MAP[] = {
-    { "EURO",   "currency", "EUR" },
-    { "PINYIN", "collation", "pinyin" }, /* Solaris variant */
-    { "STROKE", "collation", "stroke" }  /* Solaris variant */
+    { "art__LOJBAN",    "jbo" }, /* registered name */
+    { "hy__AREVELA",    "hy" }, /* Registered IANA variant */
+    { "hy__AREVMDA",    "hyw" }, /* Registered IANA variant */
+    { "zh__GUOYU",      "zh" }, /* registered name */
+    { "zh__HAKKA",      "hak" }, /* registered name */
+    { "zh__XIANG",      "hsn" }, /* registered name */
+    // subtags with 3 chars won't be treated as variants.
+    { "zh_GAN",         "gan" }, /* registered name */
+    { "zh_MIN_NAN",     "nan" }, /* registered name */
+    { "zh_WUU",         "wuu" }, /* registered name */
+    { "zh_YUE",         "yue" }, /* registered name */
 };
 
 /* ### BCP47 Conversion *******************************************/
 /* Test if the locale id has BCP47 u extension and does not have '@' */
 #define _hasBCP47Extension(id) (id && uprv_strstr(id, "@") == NULL && getShortestSubtagLength(localeID) == 1)
 /* Converts the BCP47 id to Unicode id. Does nothing to id if conversion fails */
-#define _ConvertBCP47(finalID, id, buffer, length,err) \
-        if (uloc_forLanguageTag(id, buffer, length, NULL, err) <= 0 || U_FAILURE(*err)) { \
-            finalID=id; \
-        } else { \
-            finalID=buffer; \
-        }
+#define _ConvertBCP47(finalID, id, buffer, length,err) UPRV_BLOCK_MACRO_BEGIN { \
+    if (uloc_forLanguageTag(id, buffer, length, NULL, err) <= 0 || \
+            U_FAILURE(*err) || *err == U_STRING_NOT_TERMINATED_WARNING) { \
+        finalID=id; \
+        if (*err == U_STRING_NOT_TERMINATED_WARNING) { *err = U_BUFFER_OVERFLOW_ERROR; } \
+    } else { \
+        finalID=buffer; \
+    } \
+} UPRV_BLOCK_MACRO_END
 /* Gets the size of the shortest subtag in the given localeID. */
 static int32_t getShortestSubtagLength(const char *localeID) {
-    int32_t localeIDLength = uprv_strlen(localeID);
+    int32_t localeIDLength = static_cast<int32_t>(uprv_strlen(localeID));
     int32_t length = localeIDLength;
     int32_t tmpLength = 0;
     int32_t i;
@@ -561,6 +519,10 @@
 }
 
 /* ### Keywords **************************************************/
+#define UPRV_ISDIGIT(c) (((c) >= '0') && ((c) <= '9'))
+#define UPRV_ISALPHANUM(c) (uprv_isASCIILetter(c) || UPRV_ISDIGIT(c) )
+/* Punctuation/symbols allowed in legacy key values */
+#define UPRV_OK_VALUE_PUNCTUATION(c) ((c) == '_' || (c) == '-' || (c) == '+' || (c) == '/')
 
 #define ULOC_KEYWORD_BUFFER_LEN 25
 #define ULOC_MAX_NO_KEYWORDS 25
@@ -597,21 +559,27 @@
  */
 static int32_t locale_canonKeywordName(char *buf, const char *keywordName, UErrorCode *status)
 {
-  int32_t i;
-  int32_t keywordNameLen = (int32_t)uprv_strlen(keywordName);
-  
-  if(keywordNameLen >= ULOC_KEYWORD_BUFFER_LEN) {
-    /* keyword name too long for internal buffer */
-    *status = U_INTERNAL_PROGRAM_ERROR;
-          return 0;
+  int32_t keywordNameLen = 0;
+
+  for (; *keywordName != 0; keywordName++) {
+    if (!UPRV_ISALPHANUM(*keywordName)) {
+      *status = U_ILLEGAL_ARGUMENT_ERROR; /* malformed keyword name */
+      return 0;
+    }
+    if (keywordNameLen < ULOC_KEYWORD_BUFFER_LEN - 1) {
+      buf[keywordNameLen++] = uprv_tolower(*keywordName);
+    } else {
+      /* keyword name too long for internal buffer */
+      *status = U_INTERNAL_PROGRAM_ERROR;
+      return 0;
+    }
   }
-  
-  /* normalize the keyword name */
-  for(i = 0; i < keywordNameLen; i++) {
-    buf[i] = uprv_tolower(keywordName[i]);
+  if (keywordNameLen == 0) {
+    *status = U_ILLEGAL_ARGUMENT_ERROR; /* empty keyword name */
+    return 0;
   }
-  buf[i] = 0;
-    
+  buf[keywordNameLen] = 0; /* terminate */
+
   return keywordNameLen;
 }
 
@@ -629,32 +597,21 @@
     return uprv_strcmp(leftString, rightString);
 }
 
-/**
- * Both addKeyword and addValue must already be in canonical form.
- * Either both addKeyword and addValue are NULL, or neither is NULL.
- * If they are not NULL they must be zero terminated.
- * If addKeyword is not NULL is must have length small enough to fit in KeywordStruct.keyword.
- */
-static int32_t
-_getKeywords(const char *localeID,
-             char prev,
-             char *keywords, int32_t keywordCapacity,
-             char *values, int32_t valuesCapacity, int32_t *valLen,
-             UBool valuesToo,
-             const char* addKeyword,
-             const char* addValue,
-             UErrorCode *status)
+U_CFUNC void
+ulocimp_getKeywords(const char *localeID,
+                    char prev,
+                    ByteSink& sink,
+                    UBool valuesToo,
+                    UErrorCode *status)
 {
     KeywordStruct keywordList[ULOC_MAX_NO_KEYWORDS];
-    
+
     int32_t maxKeywords = ULOC_MAX_NO_KEYWORDS;
     int32_t numKeywords = 0;
     const char* pos = localeID;
     const char* equalSign = NULL;
     const char* semicolon = NULL;
     int32_t i = 0, j, n;
-    int32_t keywordsLen = 0;
-    int32_t valuesLen = 0;
 
     if(prev == '@') { /* start of keyword definition */
         /* we will grab pairs, trim spaces, lowercase keywords, sort and return */
@@ -669,7 +626,7 @@
             }
             if(numKeywords == maxKeywords) {
                 *status = U_INTERNAL_PROGRAM_ERROR;
-                return 0;
+                return;
             }
             equalSign = uprv_strchr(pos, '=');
             semicolon = uprv_strchr(pos, ';');
@@ -677,13 +634,13 @@
             /* ';' before '=' [foo@currency;collation=pinyin] is illegal */
             if(!equalSign || (semicolon && semicolon<equalSign)) {
                 *status = U_INVALID_FORMAT_ERROR;
-                return 0;
+                return;
             }
             /* need to normalize both keyword and keyword name */
             if(equalSign - pos >= ULOC_KEYWORD_BUFFER_LEN) {
                 /* keyword name too long for internal buffer */
                 *status = U_INTERNAL_PROGRAM_ERROR;
-                return 0;
+                return;
             }
             for(i = 0, n = 0; i < equalSign - pos; ++i) {
                 if (pos[i] != ' ') {
@@ -694,7 +651,7 @@
             /* zero-length keyword is an error. */
             if (n == 0) {
                 *status = U_INVALID_FORMAT_ERROR;
-                return 0;
+                return;
             }
 
             keywordList[numKeywords].keyword[n] = 0;
@@ -709,7 +666,7 @@
             /* Premature end or zero-length value */
             if (!*equalSign || equalSign == semicolon) {
                 *status = U_INVALID_FORMAT_ERROR;
-                return 0;
+                return;
             }
 
             keywordList[numKeywords].valueStart = equalSign;
@@ -741,189 +698,162 @@
             }
         } while(pos);
 
-        /* Handle addKeyword/addValue. */
-        if (addKeyword != NULL) {
-            UBool duplicate = FALSE;
-            U_ASSERT(addValue != NULL);
-            /* Search for duplicate; if found, do nothing. Explicit keyword
-               overrides addKeyword. */
-            for (j=0; j<numKeywords; ++j) {
-                if (uprv_strcmp(keywordList[j].keyword, addKeyword) == 0) {
-                    duplicate = TRUE;
-                    break;
-                }
-            }
-            if (!duplicate) {
-                if (numKeywords == maxKeywords) {
-                    *status = U_INTERNAL_PROGRAM_ERROR;
-                    return 0;
-                }
-                uprv_strcpy(keywordList[numKeywords].keyword, addKeyword);
-                keywordList[numKeywords].keywordLen = (int32_t)uprv_strlen(addKeyword);
-                keywordList[numKeywords].valueStart = addValue;
-                keywordList[numKeywords].valueLen = (int32_t)uprv_strlen(addValue);
-                ++numKeywords;
-            }
-        } else {
-            U_ASSERT(addValue == NULL);
-        }
-
         /* now we have a list of keywords */
         /* we need to sort it */
         uprv_sortArray(keywordList, numKeywords, sizeof(KeywordStruct), compareKeywordStructs, NULL, FALSE, status);
-        
+
         /* Now construct the keyword part */
         for(i = 0; i < numKeywords; i++) {
-            if(keywordsLen + keywordList[i].keywordLen + 1< keywordCapacity) {
-                uprv_strcpy(keywords+keywordsLen, keywordList[i].keyword);
-                if(valuesToo) {
-                    keywords[keywordsLen + keywordList[i].keywordLen] = '=';
-                } else {
-                    keywords[keywordsLen + keywordList[i].keywordLen] = 0;
-                }
-            }
-            keywordsLen += keywordList[i].keywordLen + 1;
+            sink.Append(keywordList[i].keyword, keywordList[i].keywordLen);
             if(valuesToo) {
-                if(keywordsLen + keywordList[i].valueLen < keywordCapacity) {
-                    uprv_strncpy(keywords+keywordsLen, keywordList[i].valueStart, keywordList[i].valueLen);
-                }
-                keywordsLen += keywordList[i].valueLen;
-                
+                sink.Append("=", 1);
+                sink.Append(keywordList[i].valueStart, keywordList[i].valueLen);
                 if(i < numKeywords - 1) {
-                    if(keywordsLen < keywordCapacity) {       
-                        keywords[keywordsLen] = ';';
-                    }
-                    keywordsLen++;
+                    sink.Append(";", 1);
                 }
-            }
-            if(values) {
-                if(valuesLen + keywordList[i].valueLen + 1< valuesCapacity) {
-                    uprv_strcpy(values+valuesLen, keywordList[i].valueStart);
-                    values[valuesLen + keywordList[i].valueLen] = 0;
-                }
-                valuesLen += keywordList[i].valueLen + 1;
+            } else {
+                sink.Append("\0", 1);
             }
         }
-        if(values) {
-            values[valuesLen] = 0;
-            if(valLen) {
-                *valLen = valuesLen;
-            }
-        }
-        return u_terminateChars(keywords, keywordCapacity, keywordsLen, status);   
-    } else {
-        return 0;
     }
 }
 
-U_CFUNC int32_t
-locale_getKeywords(const char *localeID,
-                   char prev,
-                   char *keywords, int32_t keywordCapacity,
-                   char *values, int32_t valuesCapacity, int32_t *valLen,
-                   UBool valuesToo,
-                   UErrorCode *status) {
-    return _getKeywords(localeID, prev, keywords, keywordCapacity,
-                        values, valuesCapacity, valLen, valuesToo,
-                        NULL, NULL, status);
-}
-
 U_CAPI int32_t U_EXPORT2
 uloc_getKeywordValue(const char* localeID,
                      const char* keywordName,
                      char* buffer, int32_t bufferCapacity,
                      UErrorCode* status)
-{ 
+{
+    if (U_FAILURE(*status)) {
+        return 0;
+    }
+
+    CheckedArrayByteSink sink(buffer, bufferCapacity);
+    ulocimp_getKeywordValue(localeID, keywordName, sink, status);
+
+    int32_t reslen = sink.NumberOfBytesAppended();
+
+    if (U_FAILURE(*status)) {
+        return reslen;
+    }
+
+    if (sink.Overflowed()) {
+        *status = U_BUFFER_OVERFLOW_ERROR;
+    } else {
+        u_terminateChars(buffer, bufferCapacity, reslen, status);
+    }
+
+    return reslen;
+}
+
+U_CAPI void U_EXPORT2
+ulocimp_getKeywordValue(const char* localeID,
+                        const char* keywordName,
+                        icu::ByteSink& sink,
+                        UErrorCode* status)
+{
     const char* startSearchHere = NULL;
     const char* nextSeparator = NULL;
     char keywordNameBuffer[ULOC_KEYWORD_BUFFER_LEN];
     char localeKeywordNameBuffer[ULOC_KEYWORD_BUFFER_LEN];
-    int32_t i = 0;
-    int32_t result = 0;
 
     if(status && U_SUCCESS(*status) && localeID) {
       char tempBuffer[ULOC_FULLNAME_CAPACITY];
       const char* tmpLocaleID;
 
+      if (keywordName == NULL || keywordName[0] == 0) {
+        *status = U_ILLEGAL_ARGUMENT_ERROR;
+        return;
+      }
+
+      locale_canonKeywordName(keywordNameBuffer, keywordName, status);
+      if(U_FAILURE(*status)) {
+        return;
+      }
+
       if (_hasBCP47Extension(localeID)) {
           _ConvertBCP47(tmpLocaleID, localeID, tempBuffer, sizeof(tempBuffer), status);
       } else {
           tmpLocaleID=localeID;
       }
-    
-      startSearchHere = uprv_strchr(tmpLocaleID, '@'); /* TODO: REVISIT: shouldn't this be locale_getKeywordsStart ? */
+
+      startSearchHere = locale_getKeywordsStart(tmpLocaleID);
       if(startSearchHere == NULL) {
           /* no keywords, return at once */
-          return 0;
+          return;
       }
 
-      locale_canonKeywordName(keywordNameBuffer, keywordName, status);
-      if(U_FAILURE(*status)) {
-        return 0;
-      }
-    
       /* find the first keyword */
       while(startSearchHere) {
-          startSearchHere++;
-          /* skip leading spaces (allowed?) */
+          const char* keyValueTail;
+          int32_t keyValueLen;
+
+          startSearchHere++; /* skip @ or ; */
+          nextSeparator = uprv_strchr(startSearchHere, '=');
+          if(!nextSeparator) {
+              *status = U_ILLEGAL_ARGUMENT_ERROR; /* key must have =value */
+              return;
+          }
+          /* strip leading & trailing spaces (TC decided to tolerate these) */
           while(*startSearchHere == ' ') {
               startSearchHere++;
           }
-          nextSeparator = uprv_strchr(startSearchHere, '=');
-          /* need to normalize both keyword and keyword name */
-          if(!nextSeparator) {
-              break;
+          keyValueTail = nextSeparator;
+          while (keyValueTail > startSearchHere && *(keyValueTail-1) == ' ') {
+              keyValueTail--;
           }
-          if(nextSeparator - startSearchHere >= ULOC_KEYWORD_BUFFER_LEN) {
+          /* now keyValueTail points to first char after the keyName */
+          /* copy & normalize keyName from locale */
+          if (startSearchHere == keyValueTail) {
+              *status = U_ILLEGAL_ARGUMENT_ERROR; /* empty keyword name in passed-in locale */
+              return;
+          }
+          keyValueLen = 0;
+          while (startSearchHere < keyValueTail) {
+            if (!UPRV_ISALPHANUM(*startSearchHere)) {
+              *status = U_ILLEGAL_ARGUMENT_ERROR; /* malformed keyword name */
+              return;
+            }
+            if (keyValueLen < ULOC_KEYWORD_BUFFER_LEN - 1) {
+              localeKeywordNameBuffer[keyValueLen++] = uprv_tolower(*startSearchHere++);
+            } else {
               /* keyword name too long for internal buffer */
               *status = U_INTERNAL_PROGRAM_ERROR;
-              return 0;
+              return;
+            }
           }
-          for(i = 0; i < nextSeparator - startSearchHere; i++) {
-              localeKeywordNameBuffer[i] = uprv_tolower(startSearchHere[i]);
-          }
-          /* trim trailing spaces */
-          while(startSearchHere[i-1] == ' ') {
-              i--;
-              U_ASSERT(i>=0);
-          }
-          localeKeywordNameBuffer[i] = 0;
-        
+          localeKeywordNameBuffer[keyValueLen] = 0; /* terminate */
+
           startSearchHere = uprv_strchr(nextSeparator, ';');
-        
+
           if(uprv_strcmp(keywordNameBuffer, localeKeywordNameBuffer) == 0) {
-              nextSeparator++;
+               /* current entry matches the keyword. */
+             nextSeparator++; /* skip '=' */
+              /* First strip leading & trailing spaces (TC decided to tolerate these) */
               while(*nextSeparator == ' ') {
-                  nextSeparator++;
+                nextSeparator++;
               }
-              /* we actually found the keyword. Copy the value */
-              if(startSearchHere && startSearchHere - nextSeparator < bufferCapacity) {
-                  while(*(startSearchHere-1) == ' ') {
-                      startSearchHere--;
-                  }
-                  uprv_strncpy(buffer, nextSeparator, startSearchHere - nextSeparator);
-                  result = u_terminateChars(buffer, bufferCapacity, (int32_t)(startSearchHere - nextSeparator), status);
-              } else if(!startSearchHere && (int32_t)uprv_strlen(nextSeparator) < bufferCapacity) { /* last item in string */
-                  i = (int32_t)uprv_strlen(nextSeparator);
-                  while(nextSeparator[i - 1] == ' ') {
-                      i--;
-                  }
-                  uprv_strncpy(buffer, nextSeparator, i);
-                  result = u_terminateChars(buffer, bufferCapacity, i, status);
-              } else {
-                  /* give a bigger buffer, please */
-                  *status = U_BUFFER_OVERFLOW_ERROR;
-                  if(startSearchHere) {
-                      result = (int32_t)(startSearchHere - nextSeparator);
-                  } else {
-                      result = (int32_t)uprv_strlen(nextSeparator); 
-                  }
+              keyValueTail = (startSearchHere)? startSearchHere: nextSeparator + uprv_strlen(nextSeparator);
+              while(keyValueTail > nextSeparator && *(keyValueTail-1) == ' ') {
+                keyValueTail--;
               }
-              return result;
+              /* Now copy the value, but check well-formedness */
+              if (nextSeparator == keyValueTail) {
+                *status = U_ILLEGAL_ARGUMENT_ERROR; /* empty key value name in passed-in locale */
+                return;
+              }
+              while (nextSeparator < keyValueTail) {
+                if (!UPRV_ISALPHANUM(*nextSeparator) && !UPRV_OK_VALUE_PUNCTUATION(*nextSeparator)) {
+                  *status = U_ILLEGAL_ARGUMENT_ERROR; /* malformed key value */
+                  return;
+                }
+                /* Should we lowercase value to return here? Tests expect as-is. */
+                sink.Append(nextSeparator++, 1);
+              }
+              return;
           }
       }
     }
-    return 0;
 }
 
 U_CAPI int32_t U_EXPORT2
@@ -937,51 +867,67 @@
     int32_t keywordValueLen;
     int32_t bufLen;
     int32_t needLen = 0;
-    int32_t foundValueLen;
-    int32_t keywordAtEnd = 0; /* is the keyword at the end of the string? */
     char keywordNameBuffer[ULOC_KEYWORD_BUFFER_LEN];
+    char keywordValueBuffer[ULOC_KEYWORDS_CAPACITY+1];
     char localeKeywordNameBuffer[ULOC_KEYWORD_BUFFER_LEN];
-    int32_t i = 0;
     int32_t rc;
     char* nextSeparator = NULL;
     char* nextEqualsign = NULL;
     char* startSearchHere = NULL;
     char* keywordStart = NULL;
-    char *insertHere = NULL;
-    if(U_FAILURE(*status)) { 
-        return -1; 
+    CharString updatedKeysAndValues;
+    UBool handledInputKeyAndValue = FALSE;
+    char keyValuePrefix = '@';
+
+    if(U_FAILURE(*status)) {
+        return -1;
     }
-    if(bufferCapacity>1) {
-        bufLen = (int32_t)uprv_strlen(buffer);
-    } else {
+    if (*status == U_STRING_NOT_TERMINATED_WARNING) {
+        *status = U_ZERO_ERROR;
+    }
+    if (keywordName == NULL || keywordName[0] == 0 || bufferCapacity <= 1) {
         *status = U_ILLEGAL_ARGUMENT_ERROR;
         return 0;
     }
+    bufLen = (int32_t)uprv_strlen(buffer);
     if(bufferCapacity<bufLen) {
         /* The capacity is less than the length?! Is this NULL terminated? */
         *status = U_ILLEGAL_ARGUMENT_ERROR;
         return 0;
     }
-    if(keywordValue && !*keywordValue) { 
-        keywordValue = NULL;
-    }
-    if(keywordValue) {
-        keywordValueLen = (int32_t)uprv_strlen(keywordValue);
-    } else { 
-        keywordValueLen = 0;
-    }
     keywordNameLen = locale_canonKeywordName(keywordNameBuffer, keywordName, status);
     if(U_FAILURE(*status)) {
         return 0;
     }
+
+    keywordValueLen = 0;
+    if(keywordValue) {
+        while (*keywordValue != 0) {
+            if (!UPRV_ISALPHANUM(*keywordValue) && !UPRV_OK_VALUE_PUNCTUATION(*keywordValue)) {
+                *status = U_ILLEGAL_ARGUMENT_ERROR; /* malformed key value */
+                return 0;
+            }
+            if (keywordValueLen < ULOC_KEYWORDS_CAPACITY) {
+                /* Should we force lowercase in value to set? */
+                keywordValueBuffer[keywordValueLen++] = *keywordValue++;
+            } else {
+                /* keywordValue too long for internal buffer */
+                *status = U_INTERNAL_PROGRAM_ERROR;
+                return 0;
+            }
+        }
+    }
+    keywordValueBuffer[keywordValueLen] = 0; /* terminate */
+
     startSearchHere = (char*)locale_getKeywordsStart(buffer);
     if(startSearchHere == NULL || (startSearchHere[1]==0)) {
-        if(!keywordValue) { /* no keywords = nothing to remove */
-            return bufLen; 
+        if(keywordValueLen == 0) { /* no keywords = nothing to remove */
+            U_ASSERT(*status != U_STRING_NOT_TERMINATED_WARNING);
+            return bufLen;
         }
 
         needLen = bufLen+1+keywordNameLen+1+keywordValueLen;
-        if(startSearchHere) { /* had a single @ */ 
+        if(startSearchHere) { /* had a single @ */
             needLen--; /* already had the @ */
             /* startSearchHere points at the @ */
         } else {
@@ -991,135 +937,146 @@
             *status = U_BUFFER_OVERFLOW_ERROR;
             return needLen; /* no change */
         }
-        *startSearchHere = '@';
-        startSearchHere++;
+        *startSearchHere++ = '@';
         uprv_strcpy(startSearchHere, keywordNameBuffer);
         startSearchHere += keywordNameLen;
-        *startSearchHere = '=';
-        startSearchHere++;
-        uprv_strcpy(startSearchHere, keywordValue);
-        startSearchHere+=keywordValueLen;
+        *startSearchHere++ = '=';
+        uprv_strcpy(startSearchHere, keywordValueBuffer);
+        U_ASSERT(*status != U_STRING_NOT_TERMINATED_WARNING);
         return needLen;
     } /* end shortcut - no @ */
-    
+
     keywordStart = startSearchHere;
     /* search for keyword */
     while(keywordStart) {
-        keywordStart++;
-        /* skip leading spaces (allowed?) */
+        const char* keyValueTail;
+        int32_t keyValueLen;
+
+        keywordStart++; /* skip @ or ; */
+        nextEqualsign = uprv_strchr(keywordStart, '=');
+        if (!nextEqualsign) {
+            *status = U_ILLEGAL_ARGUMENT_ERROR; /* key must have =value */
+            return 0;
+        }
+        /* strip leading & trailing spaces (TC decided to tolerate these) */
         while(*keywordStart == ' ') {
             keywordStart++;
         }
-        nextEqualsign = uprv_strchr(keywordStart, '=');
-        /* need to normalize both keyword and keyword name */
-        if(!nextEqualsign) {
-            break;
+        keyValueTail = nextEqualsign;
+        while (keyValueTail > keywordStart && *(keyValueTail-1) == ' ') {
+            keyValueTail--;
         }
-        if(nextEqualsign - keywordStart >= ULOC_KEYWORD_BUFFER_LEN) {
-            /* keyword name too long for internal buffer */
-            *status = U_INTERNAL_PROGRAM_ERROR;
+        /* now keyValueTail points to first char after the keyName */
+        /* copy & normalize keyName from locale */
+        if (keywordStart == keyValueTail) {
+            *status = U_ILLEGAL_ARGUMENT_ERROR; /* empty keyword name in passed-in locale */
             return 0;
         }
-        for(i = 0; i < nextEqualsign - keywordStart; i++) {
-            localeKeywordNameBuffer[i] = uprv_tolower(keywordStart[i]);
+        keyValueLen = 0;
+        while (keywordStart < keyValueTail) {
+            if (!UPRV_ISALPHANUM(*keywordStart)) {
+                *status = U_ILLEGAL_ARGUMENT_ERROR; /* malformed keyword name */
+                return 0;
+            }
+            if (keyValueLen < ULOC_KEYWORD_BUFFER_LEN - 1) {
+                localeKeywordNameBuffer[keyValueLen++] = uprv_tolower(*keywordStart++);
+            } else {
+                /* keyword name too long for internal buffer */
+                *status = U_INTERNAL_PROGRAM_ERROR;
+                return 0;
+            }
         }
-        /* trim trailing spaces */
-        while(keywordStart[i-1] == ' ') {
-            i--;
-        }
-        U_ASSERT(i>=0 && i<ULOC_KEYWORD_BUFFER_LEN);
-        localeKeywordNameBuffer[i] = 0;
+        localeKeywordNameBuffer[keyValueLen] = 0; /* terminate */
 
         nextSeparator = uprv_strchr(nextEqualsign, ';');
+
+        /* start processing the value part */
+        nextEqualsign++; /* skip '=' */
+        /* First strip leading & trailing spaces (TC decided to tolerate these) */
+        while(*nextEqualsign == ' ') {
+            nextEqualsign++;
+        }
+        keyValueTail = (nextSeparator)? nextSeparator: nextEqualsign + uprv_strlen(nextEqualsign);
+        while(keyValueTail > nextEqualsign && *(keyValueTail-1) == ' ') {
+            keyValueTail--;
+        }
+        if (nextEqualsign == keyValueTail) {
+            *status = U_ILLEGAL_ARGUMENT_ERROR; /* empty key value in passed-in locale */
+            return 0;
+        }
+
         rc = uprv_strcmp(keywordNameBuffer, localeKeywordNameBuffer);
         if(rc == 0) {
-            nextEqualsign++;
-            while(*nextEqualsign == ' ') {
-                nextEqualsign++;
+            /* Current entry matches the input keyword. Update the entry */
+            if(keywordValueLen > 0) { /* updating a value */
+                updatedKeysAndValues.append(keyValuePrefix, *status);
+                keyValuePrefix = ';'; /* for any subsequent key-value pair */
+                updatedKeysAndValues.append(keywordNameBuffer, keywordNameLen, *status);
+                updatedKeysAndValues.append('=', *status);
+                updatedKeysAndValues.append(keywordValueBuffer, keywordValueLen, *status);
+            } /* else removing this entry, don't emit anything */
+            handledInputKeyAndValue = TRUE;
+        } else {
+           /* input keyword sorts earlier than current entry, add before current entry */
+            if (rc < 0 && keywordValueLen > 0 && !handledInputKeyAndValue) {
+                /* insert new entry at this location */
+                updatedKeysAndValues.append(keyValuePrefix, *status);
+                keyValuePrefix = ';'; /* for any subsequent key-value pair */
+                updatedKeysAndValues.append(keywordNameBuffer, keywordNameLen, *status);
+                updatedKeysAndValues.append('=', *status);
+                updatedKeysAndValues.append(keywordValueBuffer, keywordValueLen, *status);
+                handledInputKeyAndValue = TRUE;
             }
-            /* we actually found the keyword. Change the value */
-            if (nextSeparator) {
-                keywordAtEnd = 0;
-                foundValueLen = (int32_t)(nextSeparator - nextEqualsign);
-            } else {
-                keywordAtEnd = 1;
-                foundValueLen = (int32_t)uprv_strlen(nextEqualsign);
-            }
-            if(keywordValue) { /* adding a value - not removing */
-              if(foundValueLen == keywordValueLen) {
-                uprv_strncpy(nextEqualsign, keywordValue, keywordValueLen);
-                return bufLen; /* no change in size */
-              } else if(foundValueLen > keywordValueLen) {
-                int32_t delta = foundValueLen - keywordValueLen;
-                if(nextSeparator) { /* RH side */
-                  uprv_memmove(nextSeparator - delta, nextSeparator, bufLen-(nextSeparator-buffer));
-                }
-                uprv_strncpy(nextEqualsign, keywordValue, keywordValueLen);
-                bufLen -= delta;
-                buffer[bufLen]=0;
-                return bufLen;
-              } else { /* FVL < KVL */
-                int32_t delta = keywordValueLen - foundValueLen;
-                if((bufLen+delta) >= bufferCapacity) {
-                  *status = U_BUFFER_OVERFLOW_ERROR;
-                  return bufLen+delta;
-                }
-                if(nextSeparator) { /* RH side */
-                  uprv_memmove(nextSeparator+delta,nextSeparator, bufLen-(nextSeparator-buffer));
-                }
-                uprv_strncpy(nextEqualsign, keywordValue, keywordValueLen);
-                bufLen += delta;
-                buffer[bufLen]=0;
-                return bufLen;
-              }
-            } else { /* removing a keyword */
-              if(keywordAtEnd) {
-                /* zero out the ';' or '@' just before startSearchhere */
-                keywordStart[-1] = 0;
-                return (int32_t)((keywordStart-buffer)-1); /* (string length without keyword) minus separator */
-              } else {
-                uprv_memmove(keywordStart, nextSeparator+1, bufLen-((nextSeparator+1)-buffer));
-                keywordStart[bufLen-((nextSeparator+1)-buffer)]=0;
-                return (int32_t)(bufLen-((nextSeparator+1)-keywordStart));
-              }
-            }
-        } else if(rc<0){ /* end match keyword */
-          /* could insert at this location. */
-          insertHere = keywordStart;
+            /* copy the current entry */
+            updatedKeysAndValues.append(keyValuePrefix, *status);
+            keyValuePrefix = ';'; /* for any subsequent key-value pair */
+            updatedKeysAndValues.append(localeKeywordNameBuffer, keyValueLen, *status);
+            updatedKeysAndValues.append('=', *status);
+            updatedKeysAndValues.append(nextEqualsign, static_cast<int32_t>(keyValueTail-nextEqualsign), *status);
+        }
+        if (!nextSeparator && keywordValueLen > 0 && !handledInputKeyAndValue) {
+            /* append new entry at the end, it sorts later than existing entries */
+            updatedKeysAndValues.append(keyValuePrefix, *status);
+            /* skip keyValuePrefix update, no subsequent key-value pair */
+            updatedKeysAndValues.append(keywordNameBuffer, keywordNameLen, *status);
+            updatedKeysAndValues.append('=', *status);
+            updatedKeysAndValues.append(keywordValueBuffer, keywordValueLen, *status);
+            handledInputKeyAndValue = TRUE;
         }
         keywordStart = nextSeparator;
     } /* end loop searching */
-    
-    if(!keywordValue) {
-      return bufLen; /* removal of non-extant keyword - no change */
+
+    /* Any error from updatedKeysAndValues.append above would be internal and not due to
+     * problems with the passed-in locale. So if we did encounter problems with the
+     * passed-in locale above, those errors took precedence and overrode any error
+     * status from updatedKeysAndValues.append, and also caused a return of 0. If there
+     * are errors here they are from updatedKeysAndValues.append; they do cause an
+     * error return but the passed-in locale is unmodified and the original bufLen is
+     * returned.
+     */
+    if (!handledInputKeyAndValue || U_FAILURE(*status)) {
+        /* if input key/value specified removal of a keyword not present in locale, or
+         * there was an error in CharString.append, leave original locale alone. */
+        U_ASSERT(*status != U_STRING_NOT_TERMINATED_WARNING);
+        return bufLen;
     }
 
-    /* we know there is at least one keyword. */
-    needLen = bufLen+1+keywordNameLen+1+keywordValueLen;
-    if(needLen >= bufferCapacity) {
+    // needLen = length of the part before '@'
+    needLen = (int32_t)(startSearchHere - buffer);
+    // Check to see can we fit the startSearchHere, if not, return
+    // U_BUFFER_OVERFLOW_ERROR without copy updatedKeysAndValues into it.
+    // We do this because this API function does not behave like most others:
+    // It promises never to set a U_STRING_NOT_TERMINATED_WARNING.
+    // When the contents fits but without the terminating NUL, in this case we need to not change
+    // the buffer contents and return with a buffer overflow error.
+    int32_t appendLength = updatedKeysAndValues.length();
+    if (appendLength >= bufferCapacity - needLen) {
         *status = U_BUFFER_OVERFLOW_ERROR;
-        return needLen; /* no change */
+        return needLen + appendLength;
     }
-    
-    if(insertHere) {
-      uprv_memmove(insertHere+(1+keywordNameLen+1+keywordValueLen), insertHere, bufLen-(insertHere-buffer));
-      keywordStart = insertHere;
-    } else {
-      keywordStart = buffer+bufLen;
-      *keywordStart = ';';
-      keywordStart++;
-    }
-    uprv_strncpy(keywordStart, keywordNameBuffer, keywordNameLen);
-    keywordStart += keywordNameLen;
-    *keywordStart = '=';
-    keywordStart++;
-    uprv_strncpy(keywordStart, keywordValue, keywordValueLen); /* terminates. */
-    keywordStart+=keywordValueLen;
-    if(insertHere) {
-      *keywordStart = ';';
-      keywordStart++;
-    }
-    buffer[needLen]=0;
+    needLen += updatedKeysAndValues.extract(
+                         startSearchHere, bufferCapacity - needLen, *status);
+    U_ASSERT(*status != U_STRING_NOT_TERMINATED_WARNING);
     return needLen;
 }
 
@@ -1136,20 +1093,6 @@
  */
 #define _isTerminator(a)  ((a==0)||(a=='.')||(a=='@'))
 
-static char* _strnchr(const char* str, int32_t len, char c) {
-    U_ASSERT(str != 0 && len >= 0);
-    while (len-- != 0) {
-        char d = *str;
-        if (d == c) {
-            return (char*) str;
-        } else if (d == 0) {
-            break;
-        }
-        ++str;
-    }
-    return NULL;
-}
-
 /**
  * Lookup 'key' in the array 'list'.  The array 'list' should contain
  * a NULL entry, followed by more entries, and a second NULL entry.
@@ -1175,27 +1118,7 @@
     return -1;
 }
 
-/* count the length of src while copying it to dest; return strlen(src) */
-static inline int32_t
-_copyCount(char *dest, int32_t destCapacity, const char *src) {
-    const char *anchor;
-    char c;
-
-    anchor=src;
-    for(;;) {
-        if((c=*src)==0) {
-            return (int32_t)(src-anchor);
-        }
-        if(destCapacity<=0) {
-            return (int32_t)((src-anchor)+uprv_strlen(src));
-        }
-        ++src;
-        *dest++=c;
-        --destCapacity;
-    }
-}
-
-U_CFUNC const char* 
+U_CFUNC const char*
 uloc_getCurrentCountryID(const char* oldID){
     int32_t offset = _findIndex(DEPRECATED_COUNTRIES, oldID);
     if (offset >= 0) {
@@ -1203,13 +1126,13 @@
     }
     return oldID;
 }
-U_CFUNC const char* 
+U_CFUNC const char*
 uloc_getCurrentLanguageID(const char* oldID){
     int32_t offset = _findIndex(DEPRECATED_LANGUAGES, oldID);
     if (offset >= 0) {
         return REPLACEMENT_LANGUAGES[offset];
     }
-    return oldID;        
+    return oldID;
 }
 /*
  * the internal functions _getLanguage(), _getCountry(), _getVariant()
@@ -1219,58 +1142,56 @@
  *
  * TODO try to use this in Locale
  */
-U_CFUNC int32_t
+CharString U_EXPORT2
 ulocimp_getLanguage(const char *localeID,
-                    char *language, int32_t languageCapacity,
-                    const char **pEnd) {
-    int32_t i=0;
-    int32_t offset;
-    char lang[4]={ 0, 0, 0, 0 }; /* temporary buffer to hold language code for searching */
+                    const char **pEnd,
+                    UErrorCode &status) {
+    CharString result;
+
+    if (uprv_stricmp(localeID, "root") == 0) {
+        localeID += 4;
+    } else if (uprv_strnicmp(localeID, "und", 3) == 0 &&
+               (localeID[3] == '\0' ||
+                localeID[3] == '-' ||
+                localeID[3] == '_' ||
+                localeID[3] == '@')) {
+        localeID += 3;
+    }
 
     /* if it starts with i- or x- then copy that prefix */
     if(_isIDPrefix(localeID)) {
-        if(i<languageCapacity) {
-            language[i]=(char)uprv_tolower(*localeID);
-        }
-        if(i<languageCapacity) {
-            language[i+1]='-';
-        }
-        i+=2;
+        result.append((char)uprv_tolower(*localeID), status);
+        result.append('-', status);
         localeID+=2;
     }
-    
+
     /* copy the language as far as possible and count its length */
     while(!_isTerminator(*localeID) && !_isIDSeparator(*localeID)) {
-        if(i<languageCapacity) {
-            language[i]=(char)uprv_tolower(*localeID);
-        }
-        if(i<3) {
-            U_ASSERT(i>=0);
-            lang[i]=(char)uprv_tolower(*localeID);
-        }
-        i++;
+        result.append((char)uprv_tolower(*localeID), status);
         localeID++;
     }
 
-    if(i==3) {
+    if(result.length()==3) {
         /* convert 3 character code to 2 character code if possible *CWB*/
-        offset=_findIndex(LANGUAGES_3, lang);
+        int32_t offset = _findIndex(LANGUAGES_3, result.data());
         if(offset>=0) {
-            i=_copyCount(language, languageCapacity, LANGUAGES[offset]);
+            result.clear();
+            result.append(LANGUAGES[offset], status);
         }
     }
 
     if(pEnd!=NULL) {
         *pEnd=localeID;
     }
-    return i;
+
+    return result;
 }
 
-U_CFUNC int32_t
+CharString U_EXPORT2
 ulocimp_getScript(const char *localeID,
-                  char *script, int32_t scriptCapacity,
-                  const char **pEnd)
-{
+                  const char **pEnd,
+                  UErrorCode &status) {
+    CharString result;
     int32_t idLen = 0;
 
     if (pEnd != NULL) {
@@ -1289,183 +1210,99 @@
         if (pEnd != NULL) {
             *pEnd = localeID+idLen;
         }
-        if(idLen > scriptCapacity) {
-            idLen = scriptCapacity;
-        }
         if (idLen >= 1) {
-            script[0]=(char)uprv_toupper(*(localeID++));
+            result.append((char)uprv_toupper(*(localeID++)), status);
         }
         for (i = 1; i < idLen; i++) {
-            script[i]=(char)uprv_tolower(*(localeID++));
+            result.append((char)uprv_tolower(*(localeID++)), status);
         }
     }
-    else {
-        idLen = 0;
-    }
-    return idLen;
+
+    return result;
 }
 
-U_CFUNC int32_t
+CharString U_EXPORT2
 ulocimp_getCountry(const char *localeID,
-                   char *country, int32_t countryCapacity,
-                   const char **pEnd)
-{
+                   const char **pEnd,
+                   UErrorCode &status) {
+    CharString result;
     int32_t idLen=0;
-    char cnty[ULOC_COUNTRY_CAPACITY]={ 0, 0, 0, 0 };
-    int32_t offset;
 
     /* copy the country as far as possible and count its length */
     while(!_isTerminator(localeID[idLen]) && !_isIDSeparator(localeID[idLen])) {
-        if(idLen<(ULOC_COUNTRY_CAPACITY-1)) {   /*CWB*/
-            cnty[idLen]=(char)uprv_toupper(localeID[idLen]);
-        }
+        result.append((char)uprv_toupper(localeID[idLen]), status);
         idLen++;
     }
 
     /* the country should be either length 2 or 3 */
     if (idLen == 2 || idLen == 3) {
-        UBool gotCountry = FALSE;
         /* convert 3 character code to 2 character code if possible *CWB*/
         if(idLen==3) {
-            offset=_findIndex(COUNTRIES_3, cnty);
+            int32_t offset = _findIndex(COUNTRIES_3, result.data());
             if(offset>=0) {
-                idLen=_copyCount(country, countryCapacity, COUNTRIES[offset]);
-                gotCountry = TRUE;
-            }
-        }
-        if (!gotCountry) {
-            int32_t i = 0;
-            for (i = 0; i < idLen; i++) {
-                if (i < countryCapacity) {
-                    country[i]=(char)uprv_toupper(localeID[i]);
-                }
+                result.clear();
+                result.append(COUNTRIES[offset], status);
             }
         }
         localeID+=idLen;
     } else {
-        idLen = 0;
+        result.clear();
     }
 
     if(pEnd!=NULL) {
         *pEnd=localeID;
     }
 
-    return idLen;
+    return result;
 }
 
 /**
  * @param needSeparator if true, then add leading '_' if any variants
  * are added to 'variant'
  */
-static int32_t
-_getVariantEx(const char *localeID,
-              char prev,
-              char *variant, int32_t variantCapacity,
-              UBool needSeparator) {
-    int32_t i=0;
+static void
+_getVariant(const char *localeID,
+            char prev,
+            ByteSink& sink,
+            UBool needSeparator) {
+    UBool hasVariant = FALSE;
 
     /* get one or more variant tags and separate them with '_' */
     if(_isIDSeparator(prev)) {
         /* get a variant string after a '-' or '_' */
         while(!_isTerminator(*localeID)) {
             if (needSeparator) {
-                if (i<variantCapacity) {
-                    variant[i] = '_';
-                }
-                ++i;
+                sink.Append("_", 1);
                 needSeparator = FALSE;
             }
-            if(i<variantCapacity) {
-                variant[i]=(char)uprv_toupper(*localeID);
-                if(variant[i]=='-') {
-                    variant[i]='_';
-                }
-            }
-            i++;
+            char c = (char)uprv_toupper(*localeID);
+            if (c == '-') c = '_';
+            sink.Append(&c, 1);
+            hasVariant = TRUE;
             localeID++;
         }
     }
 
     /* if there is no variant tag after a '-' or '_' then look for '@' */
-    if(i==0) {
+    if(!hasVariant) {
         if(prev=='@') {
             /* keep localeID */
         } else if((localeID=locale_getKeywordsStart(localeID))!=NULL) {
             ++localeID; /* point after the '@' */
         } else {
-            return 0;
+            return;
         }
         while(!_isTerminator(*localeID)) {
             if (needSeparator) {
-                if (i<variantCapacity) {
-                    variant[i] = '_';
-                }
-                ++i;
+                sink.Append("_", 1);
                 needSeparator = FALSE;
             }
-            if(i<variantCapacity) {
-                variant[i]=(char)uprv_toupper(*localeID);
-                if(variant[i]=='-' || variant[i]==',') {
-                    variant[i]='_';
-                }
-            }
-            i++;
+            char c = (char)uprv_toupper(*localeID);
+            if (c == '-' || c == ',') c = '_';
+            sink.Append(&c, 1);
             localeID++;
         }
     }
-    
-    return i;
-}
-
-static int32_t
-_getVariant(const char *localeID,
-            char prev,
-            char *variant, int32_t variantCapacity) {
-    return _getVariantEx(localeID, prev, variant, variantCapacity, FALSE);
-}
-
-/**
- * Delete ALL instances of a variant from the given list of one or
- * more variants.  Example: "FOO_EURO_BAR_EURO" => "FOO_BAR".
- * @param variants the source string of one or more variants,
- * separated by '_'.  This will be MODIFIED IN PLACE.  Not zero
- * terminated; if it is, trailing zero will NOT be maintained.
- * @param variantsLen length of variants
- * @param toDelete variant to delete, without separators, e.g.  "EURO"
- * or "PREEURO"; not zero terminated
- * @param toDeleteLen length of toDelete
- * @return number of characters deleted from variants
- */
-static int32_t
-_deleteVariant(char* variants, int32_t variantsLen,
-               const char* toDelete, int32_t toDeleteLen)
-{
-    int32_t delta = 0; /* number of chars deleted */
-    for (;;) {
-        UBool flag = FALSE;
-        if (variantsLen < toDeleteLen) {
-            return delta;
-        }
-        if (uprv_strncmp(variants, toDelete, toDeleteLen) == 0 &&
-            (variantsLen == toDeleteLen ||
-             (flag=(variants[toDeleteLen] == '_'))))
-        {
-            int32_t d = toDeleteLen + (flag?1:0);
-            variantsLen -= d;
-            delta += d;
-            if (variantsLen > 0) {
-                uprv_memmove(variants, variants+d, variantsLen);
-            }
-        } else {
-            char* p = _strnchr(variants, variantsLen, '_');
-            if (p == NULL) {
-                return delta;
-            }
-            ++p;
-            variantsLen -= (int32_t)(p - variants);
-            variants = p;
-        }
-    }
 }
 
 /* Keyword enumeration */
@@ -1475,6 +1312,8 @@
     char* current;
 } UKeywordsContext;
 
+U_CDECL_BEGIN
+
 static void U_CALLCONV
 uloc_kw_closeKeywords(UEnumeration *enumerator) {
     uprv_free(((UKeywordsContext *)enumerator->context)->keywords);
@@ -1493,7 +1332,7 @@
     return result;
 }
 
-static const char* U_CALLCONV 
+static const char * U_CALLCONV
 uloc_kw_nextKeyword(UEnumeration* en,
                     int32_t* resultLength,
                     UErrorCode* /*status*/) {
@@ -1511,12 +1350,15 @@
     return result;
 }
 
-static void U_CALLCONV 
-uloc_kw_resetKeywords(UEnumeration* en, 
+static void U_CALLCONV
+uloc_kw_resetKeywords(UEnumeration* en,
                       UErrorCode* /*status*/) {
     ((UKeywordsContext *)en->context)->current = ((UKeywordsContext *)en->context)->keywords;
 }
 
+U_CDECL_END
+
+
 static const UEnumeration gKeywordsEnum = {
     NULL,
     NULL,
@@ -1530,47 +1372,42 @@
 U_CAPI UEnumeration* U_EXPORT2
 uloc_openKeywordList(const char *keywordList, int32_t keywordListSize, UErrorCode* status)
 {
-    UKeywordsContext *myContext = NULL;
-    UEnumeration *result = NULL;
+    LocalMemory<UKeywordsContext> myContext;
+    LocalMemory<UEnumeration> result;
 
-    if(U_FAILURE(*status)) {
-        return NULL;
+    if (U_FAILURE(*status)) {
+        return nullptr;
     }
-    result = (UEnumeration *)uprv_malloc(sizeof(UEnumeration));
-    /* Null pointer test */
-    if (result == NULL) {
+    myContext.adoptInstead(static_cast<UKeywordsContext *>(uprv_malloc(sizeof(UKeywordsContext))));
+    result.adoptInstead(static_cast<UEnumeration *>(uprv_malloc(sizeof(UEnumeration))));
+    if (myContext.isNull() || result.isNull()) {
         *status = U_MEMORY_ALLOCATION_ERROR;
-        return NULL;
+        return nullptr;
     }
-    uprv_memcpy(result, &gKeywordsEnum, sizeof(UEnumeration));
-    myContext = static_cast<UKeywordsContext *>(uprv_malloc(sizeof(UKeywordsContext)));
-    if (myContext == NULL) {
+    uprv_memcpy(result.getAlias(), &gKeywordsEnum, sizeof(UEnumeration));
+    myContext->keywords = static_cast<char *>(uprv_malloc(keywordListSize+1));
+    if (myContext->keywords == nullptr) {
         *status = U_MEMORY_ALLOCATION_ERROR;
-        uprv_free(result);
-        return NULL;
+        return nullptr;
     }
-    myContext->keywords = (char *)uprv_malloc(keywordListSize+1);
     uprv_memcpy(myContext->keywords, keywordList, keywordListSize);
     myContext->keywords[keywordListSize] = 0;
     myContext->current = myContext->keywords;
-    result->context = myContext;
-    return result;
+    result->context = myContext.orphan();
+    return result.orphan();
 }
 
 U_CAPI UEnumeration* U_EXPORT2
 uloc_openKeywords(const char* localeID,
-                        UErrorCode* status) 
+                        UErrorCode* status)
 {
-    int32_t i=0;
-    char keywords[256];
-    int32_t keywordsCapacity = 256;
     char tempBuffer[ULOC_FULLNAME_CAPACITY];
     const char* tmpLocaleID;
 
     if(status==NULL || U_FAILURE(*status)) {
         return 0;
     }
-    
+
     if (_hasBCP47Extension(localeID)) {
         _ConvertBCP47(tmpLocaleID, localeID, tempBuffer, sizeof(tempBuffer), status);
     } else {
@@ -1581,34 +1418,42 @@
     }
 
     /* Skip the language */
-    ulocimp_getLanguage(tmpLocaleID, NULL, 0, &tmpLocaleID);
+    ulocimp_getLanguage(tmpLocaleID, &tmpLocaleID, *status);
+    if (U_FAILURE(*status)) {
+        return 0;
+    }
+
     if(_isIDSeparator(*tmpLocaleID)) {
         const char *scriptID;
         /* Skip the script if available */
-        ulocimp_getScript(tmpLocaleID+1, NULL, 0, &scriptID);
+        ulocimp_getScript(tmpLocaleID+1, &scriptID, *status);
+        if (U_FAILURE(*status)) {
+            return 0;
+        }
         if(scriptID != tmpLocaleID+1) {
             /* Found optional script */
             tmpLocaleID = scriptID;
         }
         /* Skip the Country */
         if (_isIDSeparator(*tmpLocaleID)) {
-            ulocimp_getCountry(tmpLocaleID+1, NULL, 0, &tmpLocaleID);
-            if(_isIDSeparator(*tmpLocaleID)) {
-                _getVariant(tmpLocaleID+1, *tmpLocaleID, NULL, 0);
+            ulocimp_getCountry(tmpLocaleID+1, &tmpLocaleID, *status);
+            if (U_FAILURE(*status)) {
+                return 0;
             }
         }
     }
 
     /* keywords are located after '@' */
     if((tmpLocaleID = locale_getKeywordsStart(tmpLocaleID)) != NULL) {
-        i=locale_getKeywords(tmpLocaleID+1, '@', keywords, keywordsCapacity, NULL, 0, NULL, FALSE, status);
+        CharString keywords;
+        CharStringByteSink sink(&keywords);
+        ulocimp_getKeywords(tmpLocaleID+1, '@', sink, FALSE, status);
+        if (U_FAILURE(*status)) {
+            return NULL;
+        }
+        return uloc_openKeywordList(keywords.data(), keywords.length(), status);
     }
-
-    if(i) {
-        return uloc_openKeywordList(keywords, i, status);
-    } else {
-        return NULL;
-    }
+    return NULL;
 }
 
 
@@ -1619,7 +1464,7 @@
 #define OPTION_SET(options, mask) ((options & mask) != 0)
 
 static const char i_default[] = {'i', '-', 'd', 'e', 'f', 'a', 'u', 'l', 't'};
-#define I_DEFAULT_LENGTH (sizeof i_default / sizeof i_default[0])
+#define I_DEFAULT_LENGTH UPRV_LENGTHOF(i_default)
 
 /**
  * Canonicalize the given localeID, to level 1 or to level 2,
@@ -1628,28 +1473,22 @@
  *
  * This is the code underlying uloc_getName and uloc_canonicalize.
  */
-static int32_t
+static void
 _canonicalize(const char* localeID,
-              char* result,
-              int32_t resultCapacity,
+              ByteSink& sink,
               uint32_t options,
               UErrorCode* err) {
-    int32_t j, len, fieldCount=0, scriptSize=0, variantSize=0, nameCapacity;
-    char localeBuffer[ULOC_FULLNAME_CAPACITY];
+    int32_t j, fieldCount=0, scriptSize=0, variantSize=0;
     char tempBuffer[ULOC_FULLNAME_CAPACITY];
     const char* origLocaleID;
     const char* tmpLocaleID;
     const char* keywordAssign = NULL;
     const char* separatorIndicator = NULL;
-    const char* addKeyword = NULL;
-    const char* addValue = NULL;
-    char* name;
-    char* variant = NULL; /* pointer into name, or NULL */
 
     if (U_FAILURE(*err)) {
-        return 0;
+        return;
     }
-    
+
     if (_hasBCP47Extension(localeID)) {
         _ConvertBCP47(tmpLocaleID, localeID, tempBuffer, sizeof(tempBuffer), err);
     } else {
@@ -1661,77 +1500,55 @@
 
     origLocaleID=tmpLocaleID;
 
-    /* if we are doing a full canonicalization, then put results in
-       localeBuffer, if necessary; otherwise send them to result. */
-    if (/*OPTION_SET(options, _ULOC_CANONICALIZE) &&*/
-        (result == NULL || resultCapacity < (int32_t)sizeof(localeBuffer))) {
-        name = localeBuffer;
-        nameCapacity = (int32_t)sizeof(localeBuffer);
-    } else {
-        name = result;
-        nameCapacity = resultCapacity;
-    }
-
     /* get all pieces, one after another, and separate with '_' */
-    len=ulocimp_getLanguage(tmpLocaleID, name, nameCapacity, &tmpLocaleID);
+    CharString tag = ulocimp_getLanguage(tmpLocaleID, &tmpLocaleID, *err);
 
-    if(len == I_DEFAULT_LENGTH && uprv_strncmp(origLocaleID, i_default, len) == 0) {
-        const char *d = uloc_getDefault();
-        
-        len = (int32_t)uprv_strlen(d);
-
-        if (name != NULL) {
-            uprv_strncpy(name, d, len);
-        }
+    if (tag.length() == I_DEFAULT_LENGTH &&
+            uprv_strncmp(origLocaleID, i_default, I_DEFAULT_LENGTH) == 0) {
+        tag.clear();
+        tag.append(uloc_getDefault(), *err);
     } else if(_isIDSeparator(*tmpLocaleID)) {
         const char *scriptID;
 
         ++fieldCount;
-        if(len<nameCapacity) {
-            name[len]='_';
-        }
-        ++len;
+        tag.append('_', *err);
 
-        scriptSize=ulocimp_getScript(tmpLocaleID+1,
-            (len<nameCapacity ? name+len : NULL), nameCapacity-len, &scriptID);
+        CharString script = ulocimp_getScript(tmpLocaleID+1, &scriptID, *err);
+        tag.append(script, *err);
+        scriptSize = script.length();
         if(scriptSize > 0) {
             /* Found optional script */
             tmpLocaleID = scriptID;
             ++fieldCount;
-            len+=scriptSize;
             if (_isIDSeparator(*tmpLocaleID)) {
                 /* If there is something else, then we add the _ */
-                if(len<nameCapacity) {
-                    name[len]='_';
-                }
-                ++len;
+                tag.append('_', *err);
             }
         }
 
         if (_isIDSeparator(*tmpLocaleID)) {
             const char *cntryID;
-            int32_t cntrySize = ulocimp_getCountry(tmpLocaleID+1,
-                (len<nameCapacity ? name+len : NULL), nameCapacity-len, &cntryID);
-            if (cntrySize > 0) {
+
+            CharString country = ulocimp_getCountry(tmpLocaleID+1, &cntryID, *err);
+            tag.append(country, *err);
+            if (!country.isEmpty()) {
                 /* Found optional country */
                 tmpLocaleID = cntryID;
-                len+=cntrySize;
             }
             if(_isIDSeparator(*tmpLocaleID)) {
                 /* If there is something else, then we add the _  if we found country before. */
-                if (cntrySize >= 0 && ! _isIDSeparator(*(tmpLocaleID+1)) ) {
+                if (!_isIDSeparator(*(tmpLocaleID+1))) {
                     ++fieldCount;
-                    if(len<nameCapacity) {
-                        name[len]='_';
-                    }
-                    ++len;
+                    tag.append('_', *err);
                 }
 
-                variantSize = _getVariant(tmpLocaleID+1, *tmpLocaleID,
-                    (len<nameCapacity ? name+len : NULL), nameCapacity-len);
+                variantSize = -tag.length();
+                {
+                    CharStringByteSink s(&tag);
+                    _getVariant(tmpLocaleID+1, *tmpLocaleID, s, FALSE);
+                }
+                variantSize += tag.length();
                 if (variantSize > 0) {
-                    variant = len<nameCapacity ? name+len : NULL;
-                    len += variantSize;
                     tmpLocaleID += variantSize + 1; /* skip '_' and variant */
                 }
             }
@@ -1749,10 +1566,7 @@
                 done = TRUE;
                 break;
             default:
-                if (len<nameCapacity) {
-                    name[len] = c;
-                }
-                ++len;
+                tag.append(c, *err);
                 ++tmpLocaleID;
                 break;
             }
@@ -1774,10 +1588,7 @@
             if (c == 0) {
                 break;
             }
-            if (len<nameCapacity) {
-                name[len] = c;
-            }
-            ++len;
+            tag.append(c, *err);
             ++tmpLocaleID;
         }
     }
@@ -1785,92 +1596,49 @@
     if (OPTION_SET(options, _ULOC_CANONICALIZE)) {
         /* Handle @FOO variant if @ is present and not followed by = */
         if (tmpLocaleID!=NULL && keywordAssign==NULL) {
-            int32_t posixVariantSize;
             /* Add missing '_' if needed */
             if (fieldCount < 2 || (fieldCount < 3 && scriptSize > 0)) {
                 do {
-                    if(len<nameCapacity) {
-                        name[len]='_';
-                    }
-                    ++len;
+                    tag.append('_', *err);
                     ++fieldCount;
                 } while(fieldCount<2);
             }
-            posixVariantSize = _getVariantEx(tmpLocaleID+1, '@', name+len, nameCapacity-len,
-                                             (UBool)(variantSize > 0));
+
+            int32_t posixVariantSize = -tag.length();
+            {
+                CharStringByteSink s(&tag);
+                _getVariant(tmpLocaleID+1, '@', s, (UBool)(variantSize > 0));
+            }
+            posixVariantSize += tag.length();
             if (posixVariantSize > 0) {
-                if (variant == NULL) {
-                    variant = name+len;
-                }
-                len += posixVariantSize;
                 variantSize += posixVariantSize;
             }
         }
 
-        /* Handle generic variants first */
-        if (variant) {
-            for (j=0; j<(int32_t)(sizeof(VARIANT_MAP)/sizeof(VARIANT_MAP[0])); j++) {
-                const char* variantToCompare = VARIANT_MAP[j].variant;
-                int32_t n = (int32_t)uprv_strlen(variantToCompare);
-                int32_t variantLen = _deleteVariant(variant, uprv_min(variantSize, (nameCapacity-len)), variantToCompare, n);
-                len -= variantLen;
-                if (variantLen > 0) {
-                    if (len > 0 && name[len-1] == '_') { /* delete trailing '_' */
-                        --len;
-                    }
-                    addKeyword = VARIANT_MAP[j].keyword;
-                    addValue = VARIANT_MAP[j].value;
-                    break;
-                }
-            }
-            if (len > 0 && len <= nameCapacity && name[len-1] == '_') { /* delete trailing '_' */
-                --len;
-            }
-        }
-
         /* Look up the ID in the canonicalization map */
-        for (j=0; j<(int32_t)(sizeof(CANONICALIZE_MAP)/sizeof(CANONICALIZE_MAP[0])); j++) {
-            const char* id = CANONICALIZE_MAP[j].id;
-            int32_t n = (int32_t)uprv_strlen(id);
-            if (len == n && uprv_strncmp(name, id, n) == 0) {
-                if (n == 0 && tmpLocaleID != NULL) {
+        for (j=0; j<UPRV_LENGTHOF(CANONICALIZE_MAP); j++) {
+            StringPiece id(CANONICALIZE_MAP[j].id);
+            if (tag == id) {
+                if (id.empty() && tmpLocaleID != NULL) {
                     break; /* Don't remap "" if keywords present */
                 }
-                len = _copyCount(name, nameCapacity, CANONICALIZE_MAP[j].canonicalID);
-                if (CANONICALIZE_MAP[j].keyword) {
-                    addKeyword = CANONICALIZE_MAP[j].keyword;
-                    addValue = CANONICALIZE_MAP[j].value;
-                }
+                tag.clear();
+                tag.append(CANONICALIZE_MAP[j].canonicalID, *err);
                 break;
             }
         }
     }
 
+    sink.Append(tag.data(), tag.length());
+
     if (!OPTION_SET(options, _ULOC_STRIP_KEYWORDS)) {
         if (tmpLocaleID!=NULL && keywordAssign!=NULL &&
             (!separatorIndicator || separatorIndicator > keywordAssign)) {
-            if(len<nameCapacity) {
-                name[len]='@';
-            }
-            ++len;
+            sink.Append("@", 1);
             ++fieldCount;
-            len += _getKeywords(tmpLocaleID+1, '@', (len<nameCapacity ? name+len : NULL), nameCapacity-len,
-                                NULL, 0, NULL, TRUE, addKeyword, addValue, err);
-        } else if (addKeyword != NULL) {
-            U_ASSERT(addValue != NULL && len < nameCapacity);
-            /* inelegant but works -- later make _getKeywords do this? */
-            len += _copyCount(name+len, nameCapacity-len, "@");
-            len += _copyCount(name+len, nameCapacity-len, addKeyword);
-            len += _copyCount(name+len, nameCapacity-len, "=");
-            len += _copyCount(name+len, nameCapacity-len, addValue);
+            ulocimp_getKeywords(tmpLocaleID+1, '@', sink, TRUE, err);
         }
     }
-
-    if (U_SUCCESS(*err) && result != NULL && name == localeBuffer) {
-        uprv_strncpy(result, localeBuffer, (len > resultCapacity) ? resultCapacity : len);
-    }
-
-    return u_terminateChars(result, resultCapacity, len, err);
 }
 
 /* ### ID parsing API **************************************************/
@@ -1883,10 +1651,10 @@
 {
     const char *lastUnderscore;
     int32_t i;
-    
+
     if (U_FAILURE(*err))
         return 0;
-    
+
     if (localeID == NULL)
         localeID = uloc_getDefault();
 
@@ -1897,9 +1665,16 @@
         i=0;
     }
 
-    if(i>0 && parent != localeID) {
-        uprv_memcpy(parent, localeID, uprv_min(i, parentCapacity));
+    if (i > 0) {
+        if (uprv_strnicmp(localeID, "und_", 4) == 0) {
+            localeID += 3;
+            i -= 3;
+            uprv_memmove(parent, localeID, uprv_min(i, parentCapacity));
+        } else if (parent != localeID) {
+            uprv_memcpy(parent, localeID, uprv_min(i, parentCapacity));
+        }
     }
+
     return u_terminateChars(parent, parentCapacity, i, err);
 }
 
@@ -1910,18 +1685,16 @@
          UErrorCode* err)
 {
     /* uloc_getLanguage will return a 2 character iso-639 code if one exists. *CWB*/
-    int32_t i=0;
 
     if (err==NULL || U_FAILURE(*err)) {
         return 0;
     }
-    
+
     if(localeID==NULL) {
         localeID=uloc_getDefault();
     }
 
-    i=ulocimp_getLanguage(localeID, language, languageCapacity, NULL);
-    return u_terminateChars(language, languageCapacity, i, err);
+    return ulocimp_getLanguage(localeID, NULL, *err).extract(language, languageCapacity, *err);
 }
 
 U_CAPI int32_t U_EXPORT2
@@ -1930,8 +1703,6 @@
          int32_t scriptCapacity,
          UErrorCode* err)
 {
-    int32_t i=0;
-
     if(err==NULL || U_FAILURE(*err)) {
         return 0;
     }
@@ -1941,21 +1712,23 @@
     }
 
     /* skip the language */
-    ulocimp_getLanguage(localeID, NULL, 0, &localeID);
-    if(_isIDSeparator(*localeID)) {
-        i=ulocimp_getScript(localeID+1, script, scriptCapacity, NULL);
+    ulocimp_getLanguage(localeID, &localeID, *err);
+    if (U_FAILURE(*err)) {
+        return 0;
     }
-    return u_terminateChars(script, scriptCapacity, i, err);
+
+    if(_isIDSeparator(*localeID)) {
+        return ulocimp_getScript(localeID+1, NULL, *err).extract(script, scriptCapacity, *err);
+    }
+    return u_terminateChars(script, scriptCapacity, 0, err);
 }
 
 U_CAPI int32_t  U_EXPORT2
 uloc_getCountry(const char* localeID,
             char* country,
             int32_t countryCapacity,
-            UErrorCode* err) 
+            UErrorCode* err)
 {
-    int32_t i=0;
-
     if(err==NULL || U_FAILURE(*err)) {
         return 0;
     }
@@ -1965,36 +1738,43 @@
     }
 
     /* Skip the language */
-    ulocimp_getLanguage(localeID, NULL, 0, &localeID);
+    ulocimp_getLanguage(localeID, &localeID, *err);
+    if (U_FAILURE(*err)) {
+        return 0;
+    }
+
     if(_isIDSeparator(*localeID)) {
         const char *scriptID;
         /* Skip the script if available */
-        ulocimp_getScript(localeID+1, NULL, 0, &scriptID);
+        ulocimp_getScript(localeID+1, &scriptID, *err);
+        if (U_FAILURE(*err)) {
+            return 0;
+        }
         if(scriptID != localeID+1) {
             /* Found optional script */
             localeID = scriptID;
         }
         if(_isIDSeparator(*localeID)) {
-            i=ulocimp_getCountry(localeID+1, country, countryCapacity, NULL);
+            return ulocimp_getCountry(localeID+1, NULL, *err).extract(country, countryCapacity, *err);
         }
     }
-    return u_terminateChars(country, countryCapacity, i, err);
+    return u_terminateChars(country, countryCapacity, 0, err);
 }
 
 U_CAPI int32_t  U_EXPORT2
 uloc_getVariant(const char* localeID,
                 char* variant,
                 int32_t variantCapacity,
-                UErrorCode* err) 
+                UErrorCode* err)
 {
     char tempBuffer[ULOC_FULLNAME_CAPACITY];
     const char* tmpLocaleID;
     int32_t i=0;
-    
+
     if(err==NULL || U_FAILURE(*err)) {
         return 0;
     }
-    
+
     if (_hasBCP47Extension(localeID)) {
         _ConvertBCP47(tmpLocaleID, localeID, tempBuffer, sizeof(tempBuffer), err);
     } else {
@@ -2003,13 +1783,20 @@
         }
         tmpLocaleID=localeID;
     }
-    
+
     /* Skip the language */
-    ulocimp_getLanguage(tmpLocaleID, NULL, 0, &tmpLocaleID);
+    ulocimp_getLanguage(tmpLocaleID, &tmpLocaleID, *err);
+    if (U_FAILURE(*err)) {
+        return 0;
+    }
+
     if(_isIDSeparator(*tmpLocaleID)) {
         const char *scriptID;
         /* Skip the script if available */
-        ulocimp_getScript(tmpLocaleID+1, NULL, 0, &scriptID);
+        ulocimp_getScript(tmpLocaleID+1, &scriptID, *err);
+        if (U_FAILURE(*err)) {
+            return 0;
+        }
         if(scriptID != tmpLocaleID+1) {
             /* Found optional script */
             tmpLocaleID = scriptID;
@@ -2017,7 +1804,10 @@
         /* Skip the Country */
         if (_isIDSeparator(*tmpLocaleID)) {
             const char *cntryID;
-            ulocimp_getCountry(tmpLocaleID+1, NULL, 0, &cntryID);
+            ulocimp_getCountry(tmpLocaleID+1, &cntryID, *err);
+            if (U_FAILURE(*err)) {
+                return 0;
+            }
             if (cntryID != tmpLocaleID+1) {
                 /* Found optional country */
                 tmpLocaleID = cntryID;
@@ -2027,18 +1817,24 @@
                 if (tmpLocaleID != cntryID && _isIDSeparator(tmpLocaleID[1])) {
                     tmpLocaleID++;
                 }
-                i=_getVariant(tmpLocaleID+1, *tmpLocaleID, variant, variantCapacity);
+
+                CheckedArrayByteSink sink(variant, variantCapacity);
+                _getVariant(tmpLocaleID+1, *tmpLocaleID, sink, FALSE);
+
+                i = sink.NumberOfBytesAppended();
+
+                if (U_FAILURE(*err)) {
+                    return i;
+                }
+
+                if (sink.Overflowed()) {
+                    *err = U_BUFFER_OVERFLOW_ERROR;
+                    return i;
+                }
             }
         }
     }
-    
-    /* removed by weiv. We don't want to handle POSIX variants anymore. Use canonicalization function */
-    /* if we do not have a variant tag yet then try a POSIX variant after '@' */
-/*
-    if(!haveVariant && (localeID=uprv_strrchr(localeID, '@'))!=NULL) {
-        i=_getVariant(localeID+1, '@', variant, variantCapacity);
-    }
-*/
+
     return u_terminateChars(variant, variantCapacity, i, err);
 }
 
@@ -2046,36 +1842,117 @@
 uloc_getName(const char* localeID,
              char* name,
              int32_t nameCapacity,
-             UErrorCode* err)  
+             UErrorCode* err)
 {
-    return _canonicalize(localeID, name, nameCapacity, 0, err);
+    if (U_FAILURE(*err)) {
+        return 0;
+    }
+
+    CheckedArrayByteSink sink(name, nameCapacity);
+    ulocimp_getName(localeID, sink, err);
+
+    int32_t reslen = sink.NumberOfBytesAppended();
+
+    if (U_FAILURE(*err)) {
+        return reslen;
+    }
+
+    if (sink.Overflowed()) {
+        *err = U_BUFFER_OVERFLOW_ERROR;
+    } else {
+        u_terminateChars(name, nameCapacity, reslen, err);
+    }
+
+    return reslen;
+}
+
+U_CAPI void U_EXPORT2
+ulocimp_getName(const char* localeID,
+                ByteSink& sink,
+                UErrorCode* err)
+{
+    _canonicalize(localeID, sink, 0, err);
 }
 
 U_CAPI int32_t  U_EXPORT2
 uloc_getBaseName(const char* localeID,
                  char* name,
                  int32_t nameCapacity,
-                 UErrorCode* err)  
+                 UErrorCode* err)
 {
-    return _canonicalize(localeID, name, nameCapacity, _ULOC_STRIP_KEYWORDS, err);
+    if (U_FAILURE(*err)) {
+        return 0;
+    }
+
+    CheckedArrayByteSink sink(name, nameCapacity);
+    ulocimp_getBaseName(localeID, sink, err);
+
+    int32_t reslen = sink.NumberOfBytesAppended();
+
+    if (U_FAILURE(*err)) {
+        return reslen;
+    }
+
+    if (sink.Overflowed()) {
+        *err = U_BUFFER_OVERFLOW_ERROR;
+    } else {
+        u_terminateChars(name, nameCapacity, reslen, err);
+    }
+
+    return reslen;
+}
+
+U_CAPI void U_EXPORT2
+ulocimp_getBaseName(const char* localeID,
+                    ByteSink& sink,
+                    UErrorCode* err)
+{
+    _canonicalize(localeID, sink, _ULOC_STRIP_KEYWORDS, err);
 }
 
 U_CAPI int32_t  U_EXPORT2
 uloc_canonicalize(const char* localeID,
                   char* name,
                   int32_t nameCapacity,
-                  UErrorCode* err)  
+                  UErrorCode* err)
 {
-    return _canonicalize(localeID, name, nameCapacity, _ULOC_CANONICALIZE, err);
+    if (U_FAILURE(*err)) {
+        return 0;
+    }
+
+    CheckedArrayByteSink sink(name, nameCapacity);
+    ulocimp_canonicalize(localeID, sink, err);
+
+    int32_t reslen = sink.NumberOfBytesAppended();
+
+    if (U_FAILURE(*err)) {
+        return reslen;
+    }
+
+    if (sink.Overflowed()) {
+        *err = U_BUFFER_OVERFLOW_ERROR;
+    } else {
+        u_terminateChars(name, nameCapacity, reslen, err);
+    }
+
+    return reslen;
 }
-  
+
+U_CAPI void U_EXPORT2
+ulocimp_canonicalize(const char* localeID,
+                     ByteSink& sink,
+                     UErrorCode* err)
+{
+    _canonicalize(localeID, sink, _ULOC_CANONICALIZE, err);
+}
+
 U_CAPI const char*  U_EXPORT2
-uloc_getISO3Language(const char* localeID) 
+uloc_getISO3Language(const char* localeID)
 {
     int16_t offset;
     char lang[ULOC_LANG_CAPACITY];
     UErrorCode err = U_ZERO_ERROR;
-    
+
     if (localeID == NULL)
     {
         localeID = uloc_getDefault();
@@ -2090,12 +1967,12 @@
 }
 
 U_CAPI const char*  U_EXPORT2
-uloc_getISO3Country(const char* localeID) 
+uloc_getISO3Country(const char* localeID)
 {
     int16_t offset;
     char cntry[ULOC_LANG_CAPACITY];
     UErrorCode err = U_ZERO_ERROR;
-    
+
     if (localeID == NULL)
     {
         localeID = uloc_getDefault();
@@ -2106,18 +1983,35 @@
     offset = _findIndex(COUNTRIES, cntry);
     if (offset < 0)
         return "";
-    
+
     return COUNTRIES_3[offset];
 }
 
 U_CAPI uint32_t  U_EXPORT2
-uloc_getLCID(const char* localeID) 
+uloc_getLCID(const char* localeID)
 {
     UErrorCode status = U_ZERO_ERROR;
     char       langID[ULOC_FULLNAME_CAPACITY];
+    uint32_t   lcid = 0;
+
+    /* Check for incomplete id. */
+    if (!localeID || uprv_strlen(localeID) < 2) {
+        return 0;
+    }
+
+    // First, attempt Windows platform lookup if available, but fall
+    // through to catch any special cases (ICU vs Windows name differences).
+    lcid = uprv_convertToLCIDPlatform(localeID, &status);
+    if (U_FAILURE(status)) {
+        return 0;
+    }
+    if (lcid > 0) {
+        // Windows found an LCID, return that
+        return lcid;
+    }
 
     uloc_getLanguage(localeID, langID, sizeof(langID), &status);
-    if (U_FAILURE(status)) {
+    if (U_FAILURE(status) || status == U_STRING_NOT_TERMINATED_WARNING) {
         return 0;
     }
 
@@ -2125,25 +2019,25 @@
         // uprv_convertToLCID does not support keywords other than collation.
         // Remove all keywords except collation.
         int32_t len;
-        char collVal[ULOC_KEYWORDS_CAPACITY];
         char tmpLocaleID[ULOC_FULLNAME_CAPACITY];
 
-        len = uloc_getKeywordValue(localeID, "collation", collVal,
-            sizeof(collVal)/sizeof(collVal[0]) - 1, &status);
+        CharString collVal;
+        {
+            CharStringByteSink sink(&collVal);
+            ulocimp_getKeywordValue(localeID, "collation", sink, &status);
+        }
 
-        if (U_SUCCESS(status) && len > 0) {
-            collVal[len] = 0;
-
+        if (U_SUCCESS(status) && !collVal.isEmpty()) {
             len = uloc_getBaseName(localeID, tmpLocaleID,
-                sizeof(tmpLocaleID)/sizeof(tmpLocaleID[0]) - 1, &status);
+                UPRV_LENGTHOF(tmpLocaleID) - 1, &status);
 
-            if (U_SUCCESS(status)) {
+            if (U_SUCCESS(status) && len > 0) {
                 tmpLocaleID[len] = 0;
 
-                len = uloc_setKeywordValue("collation", collVal, tmpLocaleID,
-                    sizeof(tmpLocaleID)/sizeof(tmpLocaleID[0]) - len - 1, &status);
+                len = uloc_setKeywordValue("collation", collVal.data(), tmpLocaleID,
+                    UPRV_LENGTHOF(tmpLocaleID) - len - 1, &status);
 
-                if (U_SUCCESS(status)) {
+                if (U_SUCCESS(status) && len > 0) {
                     tmpLocaleID[len] = 0;
                     return uprv_convertToLCID(langID, tmpLocaleID, &status);
                 }
@@ -2174,12 +2068,12 @@
 
 U_CAPI void  U_EXPORT2
 uloc_setDefault(const char*   newDefaultLocale,
-             UErrorCode* err) 
+             UErrorCode* err)
 {
     if (U_FAILURE(*err))
         return;
     /* the error code isn't currently used for anything by this function*/
-    
+
     /* propagate change to C++ */
     locale_set_default(newDefaultLocale);
 }
@@ -2191,7 +2085,7 @@
  * terminated with a null pointer.
  */
 U_CAPI const char* const*  U_EXPORT2
-uloc_getISOLanguages() 
+uloc_getISOLanguages()
 {
     return LANGUAGES;
 }
@@ -2203,340 +2097,11 @@
  * terminated with a null pointer.
  */
 U_CAPI const char* const*  U_EXPORT2
-uloc_getISOCountries() 
+uloc_getISOCountries()
 {
     return COUNTRIES;
 }
 
-
-/* this function to be moved into cstring.c later */
-static char gDecimal = 0;
-
-static /* U_CAPI */
-double
-/* U_EXPORT2 */
-_uloc_strtod(const char *start, char **end) {
-    char *decimal;
-    char *myEnd;
-    char buf[30];
-    double rv;
-    if (!gDecimal) {
-        char rep[5];
-        /* For machines that decide to change the decimal on you,
-        and try to be too smart with localization.
-        This normally should be just a '.'. */
-        sprintf(rep, "%+1.1f", 1.0);
-        gDecimal = rep[2];
-    }
-
-    if(gDecimal == '.') {
-        return uprv_strtod(start, end); /* fall through to OS */
-    } else {
-        uprv_strncpy(buf, start, 29);
-        buf[29]=0;
-        decimal = uprv_strchr(buf, '.');
-        if(decimal) {
-            *decimal = gDecimal;
-        } else {
-            return uprv_strtod(start, end); /* no decimal point */
-        }
-        rv = uprv_strtod(buf, &myEnd);
-        if(end) {
-            *end = (char*)(start+(myEnd-buf)); /* cast away const (to follow uprv_strtod API.) */
-        }
-        return rv;
-    }
-}
-
-typedef struct { 
-    float q;
-    int32_t dummy;  /* to avoid uninitialized memory copy from qsort */
-    char *locale;
-} _acceptLangItem;
-
-static int32_t U_CALLCONV
-uloc_acceptLanguageCompare(const void * /*context*/, const void *a, const void *b)
-{
-    const _acceptLangItem *aa = (const _acceptLangItem*)a;
-    const _acceptLangItem *bb = (const _acceptLangItem*)b;
-
-    int32_t rc = 0;
-    if(bb->q < aa->q) {
-        rc = -1;  /* A > B */
-    } else if(bb->q > aa->q) {
-        rc = 1;   /* A < B */
-    } else {
-        rc = 0;   /* A = B */
-    }
-
-    if(rc==0) {
-        rc = uprv_stricmp(aa->locale, bb->locale);
-    }
-
-#if defined(ULOC_DEBUG)
-    /*  fprintf(stderr, "a:[%s:%g], b:[%s:%g] -> %d\n", 
-    aa->locale, aa->q, 
-    bb->locale, bb->q,
-    rc);*/
-#endif
-
-    return rc;
-}
-
-/* 
-mt-mt, ja;q=0.76, en-us;q=0.95, en;q=0.92, en-gb;q=0.89, fr;q=0.87, iu-ca;q=0.84, iu;q=0.82, ja-jp;q=0.79, mt;q=0.97, de-de;q=0.74, de;q=0.71, es;q=0.68, it-it;q=0.66, it;q=0.63, vi-vn;q=0.61, vi;q=0.58, nl-nl;q=0.55, nl;q=0.53
-*/
-
-U_CAPI int32_t U_EXPORT2
-uloc_acceptLanguageFromHTTP(char *result, int32_t resultAvailable, UAcceptResult *outResult,
-                            const char *httpAcceptLanguage,
-                            UEnumeration* availableLocales,
-                            UErrorCode *status)
-{
-    _acceptLangItem *j;
-    _acceptLangItem smallBuffer[30];
-    char **strs;
-    char tmp[ULOC_FULLNAME_CAPACITY +1];
-    int32_t n = 0;
-    const char *itemEnd;
-    const char *paramEnd;
-    const char *s;
-    const char *t;
-    int32_t res;
-    int32_t i;
-    int32_t l = (int32_t)uprv_strlen(httpAcceptLanguage);
-    int32_t jSize;
-    char *tempstr; /* Use for null pointer check */
-
-    j = smallBuffer;
-    jSize = sizeof(smallBuffer)/sizeof(smallBuffer[0]);
-    if(U_FAILURE(*status)) {
-        return -1;
-    }
-
-    for(s=httpAcceptLanguage;s&&*s;) {
-        while(isspace(*s)) /* eat space at the beginning */
-            s++;
-        itemEnd=uprv_strchr(s,',');
-        paramEnd=uprv_strchr(s,';');
-        if(!itemEnd) {
-            itemEnd = httpAcceptLanguage+l; /* end of string */
-        }
-        if(paramEnd && paramEnd<itemEnd) { 
-            /* semicolon (;) is closer than end (,) */
-            t = paramEnd+1;
-            if(*t=='q') {
-                t++;
-            }
-            while(isspace(*t)) {
-                t++;
-            }
-            if(*t=='=') {
-                t++;
-            }
-            while(isspace(*t)) {
-                t++;
-            }
-            j[n].q = (float)_uloc_strtod(t,NULL);
-        } else {
-            /* no semicolon - it's 1.0 */
-            j[n].q = 1.0f;
-            paramEnd = itemEnd;
-        }
-        j[n].dummy=0;
-        /* eat spaces prior to semi */
-        for(t=(paramEnd-1);(paramEnd>s)&&isspace(*t);t--)
-            ;
-        /* Check for null pointer from uprv_strndup */
-        tempstr = uprv_strndup(s,(int32_t)((t+1)-s));
-        if (tempstr == NULL) {
-            *status = U_MEMORY_ALLOCATION_ERROR;
-            return -1;
-        }
-        j[n].locale = tempstr;
-        uloc_canonicalize(j[n].locale,tmp,sizeof(tmp)/sizeof(tmp[0]),status);
-        if(strcmp(j[n].locale,tmp)) {
-            uprv_free(j[n].locale);
-            j[n].locale=uprv_strdup(tmp);
-        }
-#if defined(ULOC_DEBUG)
-        /*fprintf(stderr,"%d: s <%s> q <%g>\n", n, j[n].locale, j[n].q);*/
-#endif
-        n++;
-        s = itemEnd;
-        while(*s==',') { /* eat duplicate commas */
-            s++;
-        }
-        if(n>=jSize) {
-            if(j==smallBuffer) {  /* overflowed the small buffer. */
-                j = static_cast<_acceptLangItem *>(uprv_malloc(sizeof(j[0])*(jSize*2)));
-                if(j!=NULL) {
-                    uprv_memcpy(j,smallBuffer,sizeof(j[0])*jSize);
-                }
-#if defined(ULOC_DEBUG)
-                fprintf(stderr,"malloced at size %d\n", jSize);
-#endif
-            } else {
-                j = static_cast<_acceptLangItem *>(uprv_realloc(j, sizeof(j[0])*jSize*2));
-#if defined(ULOC_DEBUG)
-                fprintf(stderr,"re-alloced at size %d\n", jSize);
-#endif
-            }
-            jSize *= 2;
-            if(j==NULL) {
-                *status = U_MEMORY_ALLOCATION_ERROR;
-                return -1;
-            }
-        }
-    }
-    uprv_sortArray(j, n, sizeof(j[0]), uloc_acceptLanguageCompare, NULL, TRUE, status);
-    if(U_FAILURE(*status)) {
-        if(j != smallBuffer) {
-#if defined(ULOC_DEBUG)
-            fprintf(stderr,"freeing j %p\n", j);
-#endif
-            uprv_free(j);
-        }
-        return -1;
-    }
-    strs = static_cast<char **>(uprv_malloc((size_t)(sizeof(strs[0])*n)));
-    /* Check for null pointer */
-    if (strs == NULL) {
-        uprv_free(j); /* Free to avoid memory leak */
-        *status = U_MEMORY_ALLOCATION_ERROR;
-        return -1;
-    }
-    for(i=0;i<n;i++) {
-#if defined(ULOC_DEBUG)
-        /*fprintf(stderr,"%d: s <%s> q <%g>\n", i, j[i].locale, j[i].q);*/
-#endif
-        strs[i]=j[i].locale;
-    }
-    res =  uloc_acceptLanguage(result, resultAvailable, outResult, 
-        (const char**)strs, n, availableLocales, status);
-    for(i=0;i<n;i++) {
-        uprv_free(strs[i]);
-    }
-    uprv_free(strs);
-    if(j != smallBuffer) {
-#if defined(ULOC_DEBUG)
-        fprintf(stderr,"freeing j %p\n", j);
-#endif
-        uprv_free(j);
-    }
-    return res;
-}
-
-
-U_CAPI int32_t U_EXPORT2
-uloc_acceptLanguage(char *result, int32_t resultAvailable, 
-                    UAcceptResult *outResult, const char **acceptList,
-                    int32_t acceptListCount,
-                    UEnumeration* availableLocales,
-                    UErrorCode *status)
-{
-    int32_t i,j;
-    int32_t len;
-    int32_t maxLen=0;
-    char tmp[ULOC_FULLNAME_CAPACITY+1];
-    const char *l;
-    char **fallbackList;
-    if(U_FAILURE(*status)) {
-        return -1;
-    }
-    fallbackList = static_cast<char **>(uprv_malloc((size_t)(sizeof(fallbackList[0])*acceptListCount)));
-    if(fallbackList==NULL) {
-        *status = U_MEMORY_ALLOCATION_ERROR;
-        return -1;
-    }
-    for(i=0;i<acceptListCount;i++) {
-#if defined(ULOC_DEBUG)
-        fprintf(stderr,"%02d: %s\n", i, acceptList[i]);
-#endif
-        while((l=uenum_next(availableLocales, NULL, status))) {
-#if defined(ULOC_DEBUG)
-            fprintf(stderr,"  %s\n", l);
-#endif
-            len = (int32_t)uprv_strlen(l);
-            if(!uprv_strcmp(acceptList[i], l)) {
-                if(outResult) { 
-                    *outResult = ULOC_ACCEPT_VALID;
-                }
-#if defined(ULOC_DEBUG)
-                fprintf(stderr, "MATCH! %s\n", l);
-#endif
-                if(len>0) {
-                    uprv_strncpy(result, l, uprv_min(len, resultAvailable));
-                }
-                for(j=0;j<i;j++) {
-                    uprv_free(fallbackList[j]);
-                }
-                uprv_free(fallbackList);
-                return u_terminateChars(result, resultAvailable, len, status);   
-            }
-            if(len>maxLen) {
-                maxLen = len;
-            }
-        }
-        uenum_reset(availableLocales, status);    
-        /* save off parent info */
-        if(uloc_getParent(acceptList[i], tmp, sizeof(tmp)/sizeof(tmp[0]), status)!=0) {
-            fallbackList[i] = uprv_strdup(tmp);
-        } else {
-            fallbackList[i]=0;
-        }
-    }
-
-    for(maxLen--;maxLen>0;maxLen--) {
-        for(i=0;i<acceptListCount;i++) {
-            if(fallbackList[i] && ((int32_t)uprv_strlen(fallbackList[i])==maxLen)) {
-#if defined(ULOC_DEBUG)
-                fprintf(stderr,"Try: [%s]", fallbackList[i]);
-#endif
-                while((l=uenum_next(availableLocales, NULL, status))) {
-#if defined(ULOC_DEBUG)
-                    fprintf(stderr,"  %s\n", l);
-#endif
-                    len = (int32_t)uprv_strlen(l);
-                    if(!uprv_strcmp(fallbackList[i], l)) {
-                        if(outResult) { 
-                            *outResult = ULOC_ACCEPT_FALLBACK;
-                        }
-#if defined(ULOC_DEBUG)
-                        fprintf(stderr, "fallback MATCH! %s\n", l);
-#endif
-                        if(len>0) {
-                            uprv_strncpy(result, l, uprv_min(len, resultAvailable));
-                        }
-                        for(j=0;j<acceptListCount;j++) {
-                            uprv_free(fallbackList[j]);
-                        }
-                        uprv_free(fallbackList);
-                        return u_terminateChars(result, resultAvailable, len, status);
-                    }
-                }
-                uenum_reset(availableLocales, status);    
-
-                if(uloc_getParent(fallbackList[i], tmp, sizeof(tmp)/sizeof(tmp[0]), status)!=0) {
-                    uprv_free(fallbackList[i]);
-                    fallbackList[i] = uprv_strdup(tmp);
-                } else {
-                    uprv_free(fallbackList[i]);
-                    fallbackList[i]=0;
-                }
-            }
-        }
-        if(outResult) { 
-            *outResult = ULOC_ACCEPT_FAILED;
-        }
-    }
-    for(i=0;i<acceptListCount;i++) {
-        uprv_free(fallbackList[i]);
-    }
-    uprv_free(fallbackList);
-    return -1;
-}
-
 U_CAPI const char* U_EXPORT2
 uloc_toUnicodeLocaleKey(const char* keyword)
 {
@@ -2559,9 +2124,6 @@
     return bcpType;
 }
 
-#define UPRV_ISDIGIT(c) (((c) >= '0') && ((c) <= '9'))
-#define UPRV_ISALPHANUM(c) (uprv_isASCIILetter(c) || UPRV_ISDIGIT(c) )
-
 static UBool
 isWellFormedLegacyKey(const char* legacyKey)
 {
@@ -2604,11 +2166,10 @@
         // Checks if the specified locale key is well-formed with the legacy locale syntax.
         //
         // Note:
-        //  Neither ICU nor LDML/CLDR provides the definition of keyword syntax.
-        //  However, a key should not contain '=' obviously. For now, all existing
-        //  keys are using ASCII alphabetic letters only. We won't add any new key
-        //  that is not compatible with the BCP 47 syntax. Therefore, we assume
-        //  a valid key consist from [0-9a-zA-Z], no symbols.
+        //  LDML/CLDR provides some definition of keyword syntax in
+        //  * http://www.unicode.org/reports/tr35/#Unicode_locale_identifier and
+        //  * http://www.unicode.org/reports/tr35/#Old_Locale_Extension_Syntax
+        //  Keys can only consist of [0-9a-zA-Z].
         if (isWellFormedLegacyKey(keyword)) {
             return keyword;
         }
@@ -2624,12 +2185,11 @@
         // Checks if the specified locale type is well-formed with the legacy locale syntax.
         //
         // Note:
-        //  Neither ICU nor LDML/CLDR provides the definition of keyword syntax.
-        //  However, a type should not contain '=' obviously. For now, all existing
-        //  types are using ASCII alphabetic letters with a few symbol letters. We won't
-        //  add any new type that is not compatible with the BCP 47 syntax except timezone
-        //  IDs. For now, we assume a valid type start with [0-9a-zA-Z], but may contain
-        //  '-' '_' '/' in the middle.
+        //  LDML/CLDR provides some definition of keyword syntax in
+        //  * http://www.unicode.org/reports/tr35/#Unicode_locale_identifier and
+        //  * http://www.unicode.org/reports/tr35/#Old_Locale_Extension_Syntax
+        //  Values (types) can only consist of [0-9a-zA-Z], plus for legacy values
+        //  we allow [/_-+] in the middle (e.g. "Etc/GMT+1", "Asia/Tel_Aviv")
         if (isWellFormedLegacyType(value)) {
             return value;
         }
diff --git a/src/third_party/icu/source/common/uloc_keytype.cpp b/src/third_party/icu/source/common/uloc_keytype.cpp
index 0cc422f..d259ec6 100644
--- a/src/third_party/icu/source/common/uloc_keytype.cpp
+++ b/src/third_party/icu/source/common/uloc_keytype.cpp
@@ -1,12 +1,23 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
-*   Copyright (C) 2014, International Business Machines
+*   Copyright (C) 2014-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 **********************************************************************
 */
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
-#include "unicode/utypes.h"
+#endif  // defined(STARBOARD)
 
+#include <algorithm>
+
+#include "unicode/utypes.h"
+#include "unicode/unistr.h"
+#include "unicode/uobject.h"
+
+#include "charstr.h"
+#include "cmemory.h"
 #include "cstring.h"
 #include "uassert.h"
 #include "ucln_cmn.h"
@@ -14,31 +25,34 @@
 #include "umutex.h"
 #include "uresimp.h"
 #include "uvector.h"
+#include "udataswp.h" /* for InvChar functions */
 
 static UHashtable* gLocExtKeyMap = NULL;
 static icu::UInitOnce gLocExtKeyMapInitOnce = U_INITONCE_INITIALIZER;
-static icu::UVector* gKeyTypeStringPool = NULL;
-static icu::UVector* gLocExtKeyDataEntries = NULL;
-static icu::UVector* gLocExtTypeEntries = NULL;
 
 // bit flags for special types
 typedef enum {
     SPECIALTYPE_NONE = 0,
     SPECIALTYPE_CODEPOINTS = 1,
-    SPECIALTYPE_REORDER_CODE = 2
+    SPECIALTYPE_REORDER_CODE = 2,
+    SPECIALTYPE_RG_KEY_VALUE = 4
 } SpecialType;
 
-typedef struct LocExtKeyData {
+struct LocExtKeyData : public icu::UMemory {
     const char*     legacyId;
     const char*     bcpId;
-    UHashtable*     typeMap;
+    icu::LocalUHashtablePointer typeMap;
     uint32_t        specialTypes;
-} LocExtKeyData;
+};
 
-typedef struct LocExtType {
+struct LocExtType : public icu::UMemory {
     const char*     legacyId;
     const char*     bcpId;
-} LocExtType;
+};
+
+static icu::MemoryPool<icu::CharString>* gKeyTypeStringPool = NULL;
+static icu::MemoryPool<LocExtKeyData>* gLocExtKeyDataEntries = NULL;
+static icu::MemoryPool<LocExtType>* gLocExtTypeEntries = NULL;
 
 U_CDECL_BEGIN
 
@@ -62,25 +76,6 @@
     return TRUE;
 }
 
-static void U_CALLCONV
-uloc_deleteKeyTypeStringPoolEntry(void* obj) {
-    uprv_free(obj);
-}
-
-static void U_CALLCONV
-uloc_deleteKeyDataEntry(void* obj) {
-    LocExtKeyData* keyData = (LocExtKeyData*)obj;
-    if (keyData->typeMap != NULL) {
-        uhash_close(keyData->typeMap);
-    }
-    uprv_free(keyData);
-}
-
-static void U_CALLCONV
-uloc_deleteTypeEntry(void* obj) {
-    uprv_free(obj);
-}
-
 U_CDECL_END
 
 
@@ -104,32 +99,20 @@
     tmpSts = U_ZERO_ERROR;
     LocalUResourceBundlePointer bcpTypeAliasRes(ures_getByKey(keyTypeDataRes.getAlias(), "bcpTypeAlias", NULL, &tmpSts));
 
-    // initialize vectors storing dynamically allocated objects
-    gKeyTypeStringPool = new UVector(uloc_deleteKeyTypeStringPoolEntry, NULL, sts);
+    // initialize pools storing dynamically allocated objects
+    gKeyTypeStringPool = new icu::MemoryPool<icu::CharString>;
     if (gKeyTypeStringPool == NULL) {
-        if (U_SUCCESS(sts)) {
-            sts = U_MEMORY_ALLOCATION_ERROR;
-        }
-    }
-    if (U_FAILURE(sts)) {
+        sts = U_MEMORY_ALLOCATION_ERROR;
         return;
     }
-    gLocExtKeyDataEntries = new UVector(uloc_deleteKeyDataEntry, NULL, sts);
+    gLocExtKeyDataEntries = new icu::MemoryPool<LocExtKeyData>;
     if (gLocExtKeyDataEntries == NULL) {
-        if (U_SUCCESS(sts)) {
-            sts = U_MEMORY_ALLOCATION_ERROR;
-        }
-    }
-    if (U_FAILURE(sts)) {
+        sts = U_MEMORY_ALLOCATION_ERROR;
         return;
     }
-    gLocExtTypeEntries = new UVector(uloc_deleteTypeEntry, NULL, sts);
+    gLocExtTypeEntries = new icu::MemoryPool<LocExtType>;
     if (gLocExtTypeEntries == NULL) {
-        if (U_SUCCESS(sts)) {
-            sts = U_MEMORY_ALLOCATION_ERROR;
-        }
-    }
-    if (U_FAILURE(sts)) {
+        sts = U_MEMORY_ALLOCATION_ERROR;
         return;
     }
 
@@ -142,27 +125,24 @@
             break;
         }
         const char* legacyKeyId = ures_getKey(keyMapEntry.getAlias());
-        int32_t bcpKeyIdLen = 0;
-        const UChar* uBcpKeyId = ures_getString(keyMapEntry.getAlias(), &bcpKeyIdLen, &sts);
+        UnicodeString uBcpKeyId = ures_getUnicodeString(keyMapEntry.getAlias(), &sts);
         if (U_FAILURE(sts)) {
             break;
         }
 
         // empty value indicates that BCP key is same with the legacy key.
         const char* bcpKeyId = legacyKeyId;
-        if (bcpKeyIdLen > 0) {
-            char* bcpKeyIdBuf = (char*)uprv_malloc(bcpKeyIdLen + 1);
+        if (!uBcpKeyId.isEmpty()) {
+            icu::CharString* bcpKeyIdBuf = gKeyTypeStringPool->create();
             if (bcpKeyIdBuf == NULL) {
                 sts = U_MEMORY_ALLOCATION_ERROR;
                 break;
             }
-            u_UCharsToChars(uBcpKeyId, bcpKeyIdBuf, bcpKeyIdLen);
-            bcpKeyIdBuf[bcpKeyIdLen] = 0;
-            gKeyTypeStringPool->addElement(bcpKeyIdBuf, sts);
+            bcpKeyIdBuf->appendInvariantChars(uBcpKeyId, sts);
             if (U_FAILURE(sts)) {
                 break;
             }
-            bcpKeyId = bcpKeyIdBuf;
+            bcpKeyId = bcpKeyIdBuf->data();
         }
 
         UBool isTZ = uprv_strcmp(legacyKeyId, "timezone") == 0;
@@ -196,7 +176,7 @@
         LocalUResourceBundlePointer typeMapResByKey(ures_getByKey(typeMapRes.getAlias(), legacyKeyId, NULL, &tmpSts));
         if (U_FAILURE(tmpSts)) {
             // type map for each key must exist
-            U_ASSERT(FALSE);
+            UPRV_UNREACHABLE;
         } else {
             LocalUResourceBundlePointer typeMapEntry;
 
@@ -216,75 +196,63 @@
                     specialTypes |= SPECIALTYPE_REORDER_CODE;
                     continue;
                 }
+                if (uprv_strcmp(legacyTypeId, "RG_KEY_VALUE") == 0) {
+                    specialTypes |= SPECIALTYPE_RG_KEY_VALUE;
+                    continue;
+                }
 
                 if (isTZ) {
                     // a timezone key uses a colon instead of a slash in the resource.
                     // e.g. America:Los_Angeles
                     if (uprv_strchr(legacyTypeId, ':') != NULL) {
-                        int32_t legacyTypeIdLen = uprv_strlen(legacyTypeId);
-                        char* legacyTypeIdBuf = (char*)uprv_malloc(legacyTypeIdLen + 1);
+                        icu::CharString* legacyTypeIdBuf =
+                                gKeyTypeStringPool->create(legacyTypeId, sts);
                         if (legacyTypeIdBuf == NULL) {
                             sts = U_MEMORY_ALLOCATION_ERROR;
                             break;
                         }
-                        const char* p = legacyTypeId;
-                        char* q = legacyTypeIdBuf;
-                        while (*p) {
-                            if (*p == ':') {
-                                *q++ = '/';
-                            } else {
-                                *q++ = *p;
-                            }
-                            p++;
-                        }
-                        *q = 0;
-
-                        gKeyTypeStringPool->addElement(legacyTypeIdBuf, sts);
                         if (U_FAILURE(sts)) {
                             break;
                         }
-                        legacyTypeId = legacyTypeIdBuf;
+                        std::replace(
+                                legacyTypeIdBuf->data(),
+                                legacyTypeIdBuf->data() + legacyTypeIdBuf->length(),
+                                ':', '/');
+                        legacyTypeId = legacyTypeIdBuf->data();
                     }
                 }
 
-                int32_t bcpTypeIdLen = 0;
-                const UChar* uBcpTypeId = ures_getString(typeMapEntry.getAlias(), &bcpTypeIdLen, &sts);
+                UnicodeString uBcpTypeId = ures_getUnicodeString(typeMapEntry.getAlias(), &sts);
                 if (U_FAILURE(sts)) {
                     break;
                 }
 
                 // empty value indicates that BCP type is same with the legacy type.
                 const char* bcpTypeId = legacyTypeId;
-                if (bcpTypeIdLen > 0) {
-                    char* bcpTypeIdBuf = (char*)uprv_malloc(bcpTypeIdLen + 1);
+                if (!uBcpTypeId.isEmpty()) {
+                    icu::CharString* bcpTypeIdBuf = gKeyTypeStringPool->create();
                     if (bcpTypeIdBuf == NULL) {
                         sts = U_MEMORY_ALLOCATION_ERROR;
                         break;
                     }
-                    u_UCharsToChars(uBcpTypeId, bcpTypeIdBuf, bcpTypeIdLen);
-                    bcpTypeIdBuf[bcpTypeIdLen] = 0;
-                    gKeyTypeStringPool->addElement(bcpTypeIdBuf, sts);
+                    bcpTypeIdBuf->appendInvariantChars(uBcpTypeId, sts);
                     if (U_FAILURE(sts)) {
                         break;
                     }
-                    bcpTypeId = bcpTypeIdBuf;
+                    bcpTypeId = bcpTypeIdBuf->data();
                 }
 
                 // Note: legacy type value should never be
                 // equivalent to bcp type value of a different
                 // type under the same key. So we use a single
                 // map for lookup.
-                LocExtType* t = (LocExtType*)uprv_malloc(sizeof(LocExtType));
+                LocExtType* t = gLocExtTypeEntries->create();
                 if (t == NULL) {
                     sts = U_MEMORY_ALLOCATION_ERROR;
                     break;
                 }
                 t->bcpId = bcpTypeId;
                 t->legacyId = legacyTypeId;
-                gLocExtTypeEntries->addElement((void*)t, sts);
-                if (U_FAILURE(sts)) {
-                    break;
-                }
 
                 uhash_put(typeDataMap, (void*)legacyTypeId, t, &sts);
                 if (bcpTypeId != legacyTypeId) {
@@ -308,34 +276,25 @@
                             break;
                         }
                         // check if this is an alias of canoncal legacy type
-                        if (uprv_compareInvAscii(NULL, legacyTypeId, -1, to, toLen) == 0) {
+                        if (uprv_compareInvWithUChar(NULL, legacyTypeId, -1, to, toLen) == 0) {
                             const char* from = ures_getKey(typeAliasDataEntry.getAlias());
                             if (isTZ) {
                                 // replace colon with slash if necessary
                                 if (uprv_strchr(from, ':') != NULL) {
-                                    int32_t fromLen = uprv_strlen(from);
-                                    char* fromBuf = (char*)uprv_malloc(fromLen + 1);
+                                    icu::CharString* fromBuf =
+                                            gKeyTypeStringPool->create(from, sts);
                                     if (fromBuf == NULL) {
                                         sts = U_MEMORY_ALLOCATION_ERROR;
                                         break;
                                     }
-                                    const char* p = from;
-                                    char* q = fromBuf;
-                                    while (*p) {
-                                        if (*p == ':') {
-                                            *q++ = '/';
-                                        } else {
-                                            *q++ = *p;
-                                        }
-                                        p++;
-                                    }
-                                    *q = 0;
-
-                                    gKeyTypeStringPool->addElement(fromBuf, sts);
                                     if (U_FAILURE(sts)) {
                                         break;
                                     }
-                                    from = fromBuf;
+                                    std::replace(
+                                            fromBuf->data(),
+                                            fromBuf->data() + fromBuf->length(),
+                                            ':', '/');
+                                    from = fromBuf->data();
                                 }
                             }
                             uhash_put(typeDataMap, (void*)from, t, &sts);
@@ -358,7 +317,7 @@
                             break;
                         }
                         // check if this is an alias of bcp type
-                        if (uprv_compareInvAscii(NULL, bcpTypeId, -1, to, toLen) == 0) {
+                        if (uprv_compareInvWithUChar(NULL, bcpTypeId, -1, to, toLen) == 0) {
                             const char* from = ures_getKey(bcpTypeAliasDataEntry.getAlias());
                             uhash_put(typeDataMap, (void*)from, t, &sts);
                         }
@@ -373,7 +332,7 @@
             break;
         }
 
-        LocExtKeyData* keyData = (LocExtKeyData*)uprv_malloc(sizeof(LocExtKeyData));
+        LocExtKeyData* keyData = gLocExtKeyDataEntries->create();
         if (keyData == NULL) {
             sts = U_MEMORY_ALLOCATION_ERROR;
             break;
@@ -381,12 +340,7 @@
         keyData->bcpId = bcpKeyId;
         keyData->legacyId = legacyKeyId;
         keyData->specialTypes = specialTypes;
-        keyData->typeMap = typeDataMap;
-
-        gLocExtKeyDataEntries->addElement((void*)keyData, sts);
-        if (U_FAILURE(sts)) {
-            break;
-        }
+        keyData->typeMap.adoptInstead(typeDataMap);
 
         uhash_put(gLocExtKeyMap, (void*)legacyKeyId, keyData, &sts);
         if (legacyKeyId != bcpKeyId) {
@@ -451,6 +405,22 @@
     return (subtagLen >=3 && subtagLen <=8);
 }
 
+static UBool
+isSpecialTypeRgKeyValue(const char* val) {
+    int32_t subtagLen = 0;
+    const char* p = val;
+    while (*p) {
+        if ( (subtagLen < 2 && uprv_isASCIILetter(*p)) ||
+                    (subtagLen >= 2 && (*p == 'Z' || *p == 'z')) ) {
+            subtagLen++;
+        } else {
+            return FALSE;
+        }
+        p++;
+    }
+    return (subtagLen == 6);
+}
+
 U_CFUNC const char*
 ulocimp_toBcpKey(const char* key) {
     if (!init()) {
@@ -495,7 +465,7 @@
         if (isKnownKey != NULL) {
             *isKnownKey = TRUE;
         }
-        LocExtType* t = (LocExtType*)uhash_get(keyData->typeMap, type);
+        LocExtType* t = (LocExtType*)uhash_get(keyData->typeMap.getAlias(), type);
         if (t != NULL) {
             return t->bcpId;
         }
@@ -507,6 +477,9 @@
             if (!matched && keyData->specialTypes & SPECIALTYPE_REORDER_CODE) {
                 matched = isSpecialTypeReorderCode(type);
             }
+            if (!matched && keyData->specialTypes & SPECIALTYPE_RG_KEY_VALUE) {
+                matched = isSpecialTypeRgKeyValue(type);
+            }
             if (matched) {
                 if (isSpecialType != NULL) {
                     *isSpecialType = TRUE;
@@ -537,7 +510,7 @@
         if (isKnownKey != NULL) {
             *isKnownKey = TRUE;
         }
-        LocExtType* t = (LocExtType*)uhash_get(keyData->typeMap, type);
+        LocExtType* t = (LocExtType*)uhash_get(keyData->typeMap.getAlias(), type);
         if (t != NULL) {
             return t->legacyId;
         }
@@ -549,6 +522,9 @@
             if (!matched && keyData->specialTypes & SPECIALTYPE_REORDER_CODE) {
                 matched = isSpecialTypeReorderCode(type);
             }
+            if (!matched && keyData->specialTypes & SPECIALTYPE_RG_KEY_VALUE) {
+                matched = isSpecialTypeRgKeyValue(type);
+            }
             if (matched) {
                 if (isSpecialType != NULL) {
                     *isSpecialType = TRUE;
diff --git a/src/third_party/icu/source/common/uloc_tag.c b/src/third_party/icu/source/common/uloc_tag.cpp
similarity index 60%
rename from src/third_party/icu/source/common/uloc_tag.c
rename to src/third_party/icu/source/common/uloc_tag.cpp
index 1f11169..e687436 100644
--- a/src/third_party/icu/source/common/uloc_tag.c
+++ b/src/third_party/icu/source/common/uloc_tag.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
 *   Copyright (C) 2009-2015, International Business Machines
@@ -5,12 +7,19 @@
 **********************************************************************
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
+#endif  // defined(STARBOARD)
+#include "unicode/bytestream.h"
 #include "unicode/utypes.h"
 #include "unicode/ures.h"
+#include "unicode/localpointer.h"
 #include "unicode/putil.h"
+#include "unicode/uenum.h"
 #include "unicode/uloc.h"
 #include "ustr_imp.h"
+#include "bytesinkutil.h"
+#include "charstr.h"
 #include "cmemory.h"
 #include "cstring.h"
 #include "putilimp.h"
@@ -18,6 +27,7 @@
 #include "ulocimp.h"
 #include "uassert.h"
 
+
 /* struct holding a single variant */
 typedef struct VariantListEntry {
     const char              *variant;
@@ -25,17 +35,17 @@
 } VariantListEntry;
 
 /* struct holding a single attribute value */
-typedef struct AttributeListEntry {
+struct AttributeListEntry : public icu::UMemory {
     const char              *attribute;
     struct AttributeListEntry *next;
-} AttributeListEntry;
+};
 
 /* struct holding a single extension */
-typedef struct ExtensionListEntry {
+struct ExtensionListEntry : public icu::UMemory {
     const char                  *key;
     const char                  *value;
     struct ExtensionListEntry   *next;
-} ExtensionListEntry;
+};
 
 #define MAXEXTLANG 3
 typedef struct ULanguageTag {
@@ -47,7 +57,7 @@
     VariantListEntry    *variants;
     ExtensionListEntry  *extensions;
     const char          *privateuse;
-    const char          *grandfathered;
+    const char          *legacy;
 } ULanguageTag;
 
 #define MINLEN 2
@@ -75,19 +85,35 @@
 
 #define LANG_UND_LEN 3
 
-static const char* const GRANDFATHERED[] = {
-/*  grandfathered   preferred */
+/*
+ Updated on 2018-09-12 from
+ https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry .
+
+ This table has 2 parts. The part for
+ legacy language tags (marked as “Type: grandfathered” in BCP 47)
+ is generated by the following scripts from the IANA language tag registry.
+
+ curl  https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry |\
+ egrep -A 7 'Type: grandfathered' | \
+ egrep 'Tag|Prefe' | grep -B1 'Preferred' | grep -v '^--' | \
+ awk -n '/Tag/ {printf("    \"%s\", ", $2);} /Preferred/ {printf("\"%s\",\n", $2);}' |\
+ tr 'A-Z' 'a-z'
+
+
+ The 2nd part is made of five ICU-specific entries. They're kept for
+ the backward compatibility for now, even though there are no preferred
+ values. They may have to be removed for the strict BCP 47 compliance.
+
+*/
+static const char* const LEGACY[] = {
+/*  legacy          preferred */
     "art-lojban",   "jbo",
-    "cel-gaulish",  "xtg-x-cel-gaulish",
-    "en-GB-oed",    "en-GB-x-oed",
+    "en-gb-oed",    "en-gb-oxendict",
     "i-ami",        "ami",
     "i-bnn",        "bnn",
-    "i-default",    "en-x-i-default",
-    "i-enochian",   "und-x-i-enochian",
     "i-hak",        "hak",
     "i-klingon",    "tlh",
     "i-lux",        "lb",
-    "i-mingo",      "see-x-i-mingo",
     "i-navajo",     "nv",
     "i-pwn",        "pwn",
     "i-tao",        "tao",
@@ -100,17 +126,175 @@
     "sgn-ch-de",    "sgg",
     "zh-guoyu",     "cmn",
     "zh-hakka",     "hak",
-    "zh-min",       "nan-x-zh-min",
     "zh-min-nan",   "nan",
     "zh-xiang",     "hsn",
-    NULL,           NULL
+
+    // Legacy tags with no preferred value in the IANA
+    // registry. Kept for now for the backward compatibility
+    // because ICU has mapped them this way.
+    "cel-gaulish",  "xtg-x-cel-gaulish",
+    "i-default",    "en-x-i-default",
+    "i-enochian",   "und-x-i-enochian",
+    "i-mingo",      "see-x-i-mingo",
+    "zh-min",       "nan-x-zh-min",
 };
 
+/*
+ Updated on 2018-09-12 from
+ https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry .
+
+ The table lists redundant tags with preferred value in the IANA languate tag registry.
+ It's generated with the following command:
+
+ curl  https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry |\
+ grep 'Type: redundant' -A 5 | egrep '^(Tag:|Prefer)' | grep -B1 'Preferred' | \
+ awk -n '/Tag/ {printf("    \"%s\",       ", $2);} /Preferred/ {printf("\"%s\",\n", $2);}' | \
+ tr 'A-Z' 'a-z'
+
+ In addition, ja-latn-hepburn-heploc is mapped to ja-latn-alalc97 because
+ a variant tag 'hepburn-heploc' has the preferred subtag, 'alaic97'.
+*/
+
+static const char* const REDUNDANT[] = {
+//  redundant       preferred
+    "sgn-br",       "bzs",
+    "sgn-co",       "csn",
+    "sgn-de",       "gsg",
+    "sgn-dk",       "dsl",
+    "sgn-es",       "ssp",
+    "sgn-fr",       "fsl",
+    "sgn-gb",       "bfi",
+    "sgn-gr",       "gss",
+    "sgn-ie",       "isg",
+    "sgn-it",       "ise",
+    "sgn-jp",       "jsl",
+    "sgn-mx",       "mfs",
+    "sgn-ni",       "ncs",
+    "sgn-nl",       "dse",
+    "sgn-no",       "nsl",
+    "sgn-pt",       "psr",
+    "sgn-se",       "swl",
+    "sgn-us",       "ase",
+    "sgn-za",       "sfs",
+    "zh-cmn",       "cmn",
+    "zh-cmn-hans",  "cmn-hans",
+    "zh-cmn-hant",  "cmn-hant",
+    "zh-gan",       "gan",
+    "zh-wuu",       "wuu",
+    "zh-yue",       "yue",
+
+    // variant tag with preferred value
+    "ja-latn-hepburn-heploc", "ja-latn-alalc97",
+};
+
+/*
+  Updated on 2018-09-12 from
+  https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry .
+
+  grep 'Type: language' -A 7 language-subtag-registry  | egrep 'Subtag|Prefe' | \
+  grep -B1 'Preferred' | grep -v '^--' | \
+  awk -n '/Subtag/ {printf("    \"%s\",       ", $2);} /Preferred/ {printf("\"%s\",\n", $2);}'
+
+  Make sure that 2-letter language subtags come before 3-letter subtags.
+*/
 static const char DEPRECATEDLANGS[][4] = {
 /*  deprecated  new */
+    "in",       "id",
     "iw",       "he",
     "ji",       "yi",
-    "in",       "id"
+    "jw",       "jv",
+    "mo",       "ro",
+    "aam",       "aas",
+    "adp",       "dz",
+    "aue",       "ktz",
+    "ayx",       "nun",
+    "bgm",       "bcg",
+    "bjd",       "drl",
+    "ccq",       "rki",
+    "cjr",       "mom",
+    "cka",       "cmr",
+    "cmk",       "xch",
+    "coy",       "pij",
+    "cqu",       "quh",
+    "drh",       "khk",
+    "drw",       "prs",
+    "gav",       "dev",
+    "gfx",       "vaj",
+    "ggn",       "gvr",
+    "gti",       "nyc",
+    "guv",       "duz",
+    "hrr",       "jal",
+    "ibi",       "opa",
+    "ilw",       "gal",
+    "jeg",       "oyb",
+    "kgc",       "tdf",
+    "kgh",       "kml",
+    "koj",       "kwv",
+    "krm",       "bmf",
+    "ktr",       "dtp",
+    "kvs",       "gdj",
+    "kwq",       "yam",
+    "kxe",       "tvd",
+    "kzj",       "dtp",
+    "kzt",       "dtp",
+    "lii",       "raq",
+    "lmm",       "rmx",
+    "meg",       "cir",
+    "mst",       "mry",
+    "mwj",       "vaj",
+    "myt",       "mry",
+    "nad",       "xny",
+    "ncp",       "kdz",
+    "nnx",       "ngv",
+    "nts",       "pij",
+    "oun",       "vaj",
+    "pcr",       "adx",
+    "pmc",       "huw",
+    "pmu",       "phr",
+    "ppa",       "bfy",
+    "ppr",       "lcq",
+    "pry",       "prt",
+    "puz",       "pub",
+    "sca",       "hle",
+    "skk",       "oyb",
+    "tdu",       "dtp",
+    "thc",       "tpo",
+    "thx",       "oyb",
+    "tie",       "ras",
+    "tkk",       "twm",
+    "tlw",       "weo",
+    "tmp",       "tyj",
+    "tne",       "kak",
+    "tnf",       "prs",
+    "tsf",       "taj",
+    "uok",       "ema",
+    "xba",       "cax",
+    "xia",       "acn",
+    "xkh",       "waw",
+    "xsj",       "suj",
+    "ybd",       "rki",
+    "yma",       "lrr",
+    "ymt",       "mtm",
+    "yos",       "zom",
+    "yuu",       "yug",
+};
+
+/*
+  Updated on 2018-04-24 from
+
+  curl  https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry | \
+  grep 'Type: region' -A 7 | egrep 'Subtag|Prefe' | \
+  grep -B1 'Preferred' | \
+  awk -n '/Subtag/ {printf("    \"%s\",       ", $2);} /Preferred/ {printf("\"%s\",\n", $2);}'
+*/
+static const char DEPRECATEDREGIONS[][3] = {
+/*  deprecated  new */
+    "BU",       "MM",
+    "DD",       "DE",
+    "FX",       "FR",
+    "TP",       "TL",
+    "YD",       "YE",
+    "ZR",       "CD",
 };
 
 /*
@@ -167,9 +351,24 @@
 
 #if 0
 static const char*
-ultag_getGrandfathered(const ULanguageTag* langtag);
+ultag_getLegacy(const ULanguageTag* langtag);
 #endif
 
+U_NAMESPACE_BEGIN
+
+/**
+ * \class LocalULanguageTagPointer
+ * "Smart pointer" class, closes a ULanguageTag via ultag_close().
+ * For most methods see the LocalPointerBase base class.
+ *
+ * @see LocalPointerBase
+ * @see LocalPointer
+ * @internal
+ */
+U_DEFINE_LOCAL_OPEN_POINTER(LocalULanguageTagPointer, ULanguageTag, ultag_close);
+
+U_NAMESPACE_END
+
 /*
 * -------------------------------------------------
 *
@@ -212,13 +411,22 @@
 }
 
 static UBool
-_isLanguageSubtag(const char* s, int32_t len) {
+_isAlphaNumericStringLimitedLength(const char* s, int32_t len, int32_t min, int32_t max) {
+    if (len < 0) {
+        len = (int32_t)uprv_strlen(s);
+    }
+    if (len >= min && len <= max && _isAlphaNumericString(s, len)) {
+        return TRUE;
+    }
+    return FALSE;
+}
+
+U_CFUNC UBool
+ultag_isLanguageSubtag(const char* s, int32_t len) {
     /*
-     * language      = 2*3ALPHA            ; shortest ISO 639 code
-     *                 ["-" extlang]       ; sometimes followed by
-     *                                     ;   extended language subtags
-     *               / 4ALPHA              ; or reserved for future use
-     *               / 5*8ALPHA            ; or registered language subtag
+     * unicode_language_subtag = alpha{2,3} | alpha{5,8};
+     * NOTE: Per ICUTC 2019/01/23- accepting alpha 4
+     * See ICU-20372
      */
     if (len < 0) {
         len = (int32_t)uprv_strlen(s);
@@ -244,8 +452,8 @@
     return FALSE;
 }
 
-static UBool
-_isScriptSubtag(const char* s, int32_t len) {
+U_CFUNC UBool
+ultag_isScriptSubtag(const char* s, int32_t len) {
     /*
      * script        = 4ALPHA              ; ISO 15924 code
      */
@@ -258,8 +466,8 @@
     return FALSE;
 }
 
-static UBool
-_isRegionSubtag(const char* s, int32_t len) {
+U_CFUNC UBool
+ultag_isRegionSubtag(const char* s, int32_t len) {
     /*
      * region        = 2ALPHA              ; ISO 3166-1 code
      *               / 3DIGIT              ; UN M.49 code
@@ -285,7 +493,7 @@
     if (len < 0) {
         len = (int32_t)uprv_strlen(s);
     }
-    if (len >= 5 && len <= 8 && _isAlphaNumericString(s, len)) {
+    if (_isAlphaNumericStringLimitedLength(s, len, 5, 8)) {
         return TRUE;
     }
     if (len == 4 && ISNUMERIC(*s) && _isAlphaNumericString(s + 1, 3)) {
@@ -295,29 +503,64 @@
 }
 
 static UBool
+_isSepListOf(UBool (*test)(const char*, int32_t), const char* s, int32_t len) {
+    const char *p = s;
+    const char *pSubtag = NULL;
+
+    if (len < 0) {
+        len = (int32_t)uprv_strlen(s);
+    }
+
+    while ((p - s) < len) {
+        if (*p == SEP) {
+            if (pSubtag == NULL) {
+                return FALSE;
+            }
+            if (!test(pSubtag, (int32_t)(p - pSubtag))) {
+                return FALSE;
+            }
+            pSubtag = NULL;
+        } else if (pSubtag == NULL) {
+            pSubtag = p;
+        }
+        p++;
+    }
+    if (pSubtag == NULL) {
+        return FALSE;
+    }
+    return test(pSubtag, (int32_t)(p - pSubtag));
+}
+
+U_CFUNC UBool
+ultag_isVariantSubtags(const char* s, int32_t len) {
+    return _isSepListOf(&_isVariantSubtag, s, len);
+}
+
+// This is for the ICU-specific "lvariant" handling.
+static UBool
 _isPrivateuseVariantSubtag(const char* s, int32_t len) {
     /*
      * variant       = 1*8alphanum         ; registered variants
      *               / (DIGIT 3alphanum)
      */
-    if (len < 0) {
-        len = (int32_t)uprv_strlen(s);
-    }
-    if (len >= 1 && len <= 8 && _isAlphaNumericString(s, len)) {
-        return TRUE;
-    }
-    return FALSE;
+    return _isAlphaNumericStringLimitedLength(s, len , 1, 8);
 }
 
 static UBool
 _isExtensionSingleton(const char* s, int32_t len) {
     /*
      * extension     = singleton 1*("-" (2*8alphanum))
+     *
+     * singleton     = DIGIT               ; 0 - 9
+     *               / %x41-57             ; A - W
+     *               / %x59-5A             ; Y - Z
+     *               / %x61-77             ; a - w
+     *               / %x79-7A             ; y - z
      */
     if (len < 0) {
         len = (int32_t)uprv_strlen(s);
     }
-    if (len == 1 && ISALPHA(*s) && (uprv_tolower(*s) != PRIVATEUSE)) {
+    if (len == 1 && (ISALPHA(*s) || ISNUMERIC(*s)) && (uprv_tolower(*s) != PRIVATEUSE)) {
         return TRUE;
     }
     return FALSE;
@@ -328,42 +571,12 @@
     /*
      * extension     = singleton 1*("-" (2*8alphanum))
      */
-    if (len < 0) {
-        len = (int32_t)uprv_strlen(s);
-    }
-    if (len >= 2 && len <= 8 && _isAlphaNumericString(s, len)) {
-        return TRUE;
-    }
-    return FALSE;
+    return _isAlphaNumericStringLimitedLength(s, len, 2, 8);
 }
 
-static UBool
-_isExtensionSubtags(const char* s, int32_t len) {
-    const char *p = s;
-    const char *pSubtag = NULL;
-
-    if (len < 0) {
-        len = (int32_t)uprv_strlen(s);
-    }
-
-    while ((p - s) < len) {
-        if (*p == SEP) {
-            if (pSubtag == NULL) {
-                return FALSE;
-            }
-            if (!_isExtensionSubtag(pSubtag, (int32_t)(p - pSubtag))) {
-                return FALSE;
-            }
-            pSubtag = NULL;
-        } else if (pSubtag == NULL) {
-            pSubtag = p;
-        }
-        p++;
-    }
-    if (pSubtag == NULL) {
-        return FALSE;
-    }
-    return _isExtensionSubtag(pSubtag, (int32_t)(p - pSubtag));
+U_CFUNC UBool
+ultag_isExtensionSubtags(const char* s, int32_t len) {
+    return _isSepListOf(&_isExtensionSubtag, s, len);
 }
 
 static UBool
@@ -371,58 +584,195 @@
     /*
      * privateuse    = "x" 1*("-" (1*8alphanum))
      */
+    return _isAlphaNumericStringLimitedLength(s, len, 1, 8);
+}
+
+U_CFUNC UBool
+ultag_isPrivateuseValueSubtags(const char* s, int32_t len) {
+    return _isSepListOf(&_isPrivateuseValueSubtag, s, len);
+}
+
+U_CFUNC UBool
+ultag_isUnicodeLocaleAttribute(const char* s, int32_t len) {
+    /*
+     * attribute = alphanum{3,8} ;
+     */
+    return _isAlphaNumericStringLimitedLength(s, len , 3, 8);
+}
+
+U_CFUNC UBool
+ultag_isUnicodeLocaleAttributes(const char* s, int32_t len) {
+    return _isSepListOf(&ultag_isUnicodeLocaleAttribute, s, len);
+}
+
+U_CFUNC UBool
+ultag_isUnicodeLocaleKey(const char* s, int32_t len) {
+    /*
+     * key = alphanum alpha ;
+     */
     if (len < 0) {
         len = (int32_t)uprv_strlen(s);
     }
-    if (len >= 1 && len <= 8 && _isAlphaNumericString(s, len)) {
+    if (len == 2 && (ISALPHA(*s) || ISNUMERIC(*s)) && ISALPHA(s[1])) {
+        return TRUE;
+    }
+    return FALSE;
+}
+
+U_CFUNC UBool
+_isUnicodeLocaleTypeSubtag(const char*s, int32_t len) {
+    /*
+     * alphanum{3,8}
+     */
+    return _isAlphaNumericStringLimitedLength(s, len , 3, 8);
+}
+
+U_CFUNC UBool
+ultag_isUnicodeLocaleType(const char*s, int32_t len) {
+    /*
+     * type = alphanum{3,8} (sep alphanum{3,8})* ;
+     */
+    return _isSepListOf(&_isUnicodeLocaleTypeSubtag, s, len);
+}
+
+static UBool
+_isTKey(const char* s, int32_t len)
+{
+    /*
+     * tkey = alpha digit ;
+     */
+    if (len < 0) {
+        len = (int32_t)uprv_strlen(s);
+    }
+    if (len == 2 && ISALPHA(*s) && ISNUMERIC(*(s + 1))) {
         return TRUE;
     }
     return FALSE;
 }
 
 static UBool
-_isPrivateuseValueSubtags(const char* s, int32_t len) {
-    const char *p = s;
-    const char *pSubtag = NULL;
-
-    if (len < 0) {
-        len = (int32_t)uprv_strlen(s);
-    }
-
-    while ((p - s) < len) {
-        if (*p == SEP) {
-            if (pSubtag == NULL) {
-                return FALSE;
-            }
-            if (!_isPrivateuseValueSubtag(pSubtag, (int32_t)(p - pSubtag))) {
-                return FALSE;
-            }
-            pSubtag = NULL;
-        } else if (pSubtag == NULL) {
-            pSubtag = p;
-        }
-        p++;
-    }
-    if (pSubtag == NULL) {
-        return FALSE;
-    }
-    return _isPrivateuseValueSubtag(pSubtag, (int32_t)(p - pSubtag));
+_isTValue(const char* s, int32_t len)
+{
+    /*
+     * tvalue = (sep alphanum{3,8})+ ;
+     */
+    return _isAlphaNumericStringLimitedLength(s, len , 3, 8);
 }
 
-U_CFUNC UBool
-ultag_isUnicodeLocaleKey(const char* s, int32_t len) {
-    if (len < 0) {
-        len = (int32_t)uprv_strlen(s);
-    }
-    if (len == 2 && _isAlphaNumericString(s, len)) {
-        return TRUE;
+static UBool
+_isTransformedExtensionSubtag(int32_t& state, const char* s, int32_t len)
+{
+    const int32_t kStart = 0;       // Start, wait for unicode_language_subtag, tkey or end
+    const int32_t kGotLanguage = 1; // Got unicode_language_subtag, wait for unicode_script_subtag,
+                                    // unicode_region_subtag, unicode_variant_subtag, tkey or end
+    const int32_t kGotScript = 2;   // Got unicode_script_subtag, wait for unicode_region_subtag,
+                                    // unicode_variant_subtag, tkey, or end
+    const int32_t kGotRegion = 3;   // Got unicode_region_subtag, wait for unicode_variant_subtag,
+                                    // tkey, or end.
+    const int32_t kGotVariant = 4;  // Got unicode_variant_subtag, wait for unicode_variant_subtag
+                                    // tkey or end.
+    const int32_t kGotTKey = -1;    // Got tkey, wait for tvalue. ERROR if stop here.
+    const int32_t kGotTValue = 6;   // Got tvalue, wait for tkey, tvalue or end
+
+    switch (state) {
+        case kStart:
+            if (ultag_isLanguageSubtag(s, len)) {
+                state = kGotLanguage;
+                return TRUE;
+            }
+            if (_isTKey(s, len)) {
+                state = kGotTKey;
+                return TRUE;
+            }
+            return FALSE;
+        case kGotLanguage:
+            if (ultag_isScriptSubtag(s, len)) {
+                state = kGotScript;
+                return TRUE;
+            }
+            U_FALLTHROUGH;
+        case kGotScript:
+            if (ultag_isRegionSubtag(s, len)) {
+                state = kGotRegion;
+                return TRUE;
+            }
+            U_FALLTHROUGH;
+        case kGotRegion:
+            U_FALLTHROUGH;
+        case kGotVariant:
+            if (_isVariantSubtag(s, len)) {
+                state = kGotVariant;
+                return TRUE;
+            }
+            if (_isTKey(s, len)) {
+                state = kGotTKey;
+                return TRUE;
+            }
+            return FALSE;
+        case kGotTKey:
+            if (_isTValue(s, len)) {
+                state = kGotTValue;
+                return TRUE;
+            }
+            return FALSE;
+        case kGotTValue:
+            if (_isTKey(s, len)) {
+                state = kGotTKey;
+                return TRUE;
+            }
+            if (_isTValue(s, len)) {
+                return TRUE;
+            }
+            return FALSE;
     }
     return FALSE;
 }
 
-U_CFUNC UBool
-ultag_isUnicodeLocaleType(const char*s, int32_t len) {
+static UBool
+_isUnicodeExtensionSubtag(int32_t& state, const char* s, int32_t len)
+{
+    const int32_t kStart = 0;         // Start, wait for a key or attribute or end
+    const int32_t kGotKey = 1;        // Got a key, wait for type or key or end
+    const int32_t kGotType = 2;       // Got a type, wait for key or end
+
+    switch (state) {
+        case kStart:
+            if (ultag_isUnicodeLocaleKey(s, len)) {
+                state = kGotKey;
+                return TRUE;
+            }
+            if (ultag_isUnicodeLocaleAttribute(s, len)) {
+                return TRUE;
+            }
+            return FALSE;
+        case kGotKey:
+            if (ultag_isUnicodeLocaleKey(s, len)) {
+                return TRUE;
+            }
+            if (_isUnicodeLocaleTypeSubtag(s, len)) {
+                state = kGotType;
+                return TRUE;
+            }
+            return FALSE;
+        case kGotType:
+            if (ultag_isUnicodeLocaleKey(s, len)) {
+                state = kGotKey;
+                return TRUE;
+            }
+            if (_isUnicodeLocaleTypeSubtag(s, len)) {
+                return TRUE;
+            }
+            return FALSE;
+    }
+    return FALSE;
+}
+
+static UBool
+_isStatefulSepListOf(UBool (*test)(int32_t&, const char*, int32_t), const char* s, int32_t len)
+{
+    int32_t state = 0;
     const char* p;
+    const char* start = s;
     int32_t subtagLen = 0;
 
     if (len < 0) {
@@ -431,22 +781,34 @@
 
     for (p = s; len > 0; p++, len--) {
         if (*p == SEP) {
-            if (subtagLen < 3) {
+            if (!test(state, start, subtagLen)) {
                 return FALSE;
             }
             subtagLen = 0;
-        } else if (ISALPHA(*p) || ISNUMERIC(*p)) {
-            subtagLen++;
-            if (subtagLen > 8) {
-                return FALSE;
-            }
+            start = p + 1;
         } else {
-            return FALSE;
+            subtagLen++;
         }
     }
 
-    return (subtagLen >= 3);
+    if (test(state, start, subtagLen) && state >= 0) {
+        return TRUE;
+    }
+    return FALSE;
 }
+
+U_CFUNC UBool
+ultag_isTransformedExtensionSubtags(const char* s, int32_t len)
+{
+    return _isStatefulSepListOf(&_isTransformedExtensionSubtag, s, len);
+}
+
+U_CFUNC UBool
+ultag_isUnicodeExtensionSubtags(const char* s, int32_t len) {
+    return _isStatefulSepListOf(&_isUnicodeExtensionSubtag, s, len);
+}
+
+
 /*
 * -------------------------------------------------
 *
@@ -578,6 +940,14 @@
                     cmp = LDMLEXT - *(cur->key);
                 } else {
                     cmp = uprv_compareInvCharsAsAscii(ext->key, cur->key);
+                    /* Both are u extension keys - we need special handling for 'attribute' */
+                    if (cmp != 0) {
+                        if (uprv_strcmp(cur->key, LOCALE_ATTRIBUTE_KEY) == 0) {
+                            cmp = 1;
+                        } else if (uprv_strcmp(ext->key, LOCALE_ATTRIBUTE_KEY) == 0) {
+                            cmp = -1;
+                        }
+                    }
                 }
             } else {
                 cmp = uprv_compareInvCharsAsAscii(ext->key, cur->key);
@@ -621,26 +991,25 @@
     langtag->variants = NULL;
     langtag->extensions = NULL;
 
-    langtag->grandfathered = EMPTY;
+    langtag->legacy = EMPTY;
     langtag->privateuse = EMPTY;
 }
 
-static int32_t
-_appendLanguageToLanguageTag(const char* localeID, char* appendAt, int32_t capacity, UBool strict, UErrorCode* status) {
+static void
+_appendLanguageToLanguageTag(const char* localeID, icu::ByteSink& sink, UBool strict, UErrorCode* status) {
     char buf[ULOC_LANG_CAPACITY];
     UErrorCode tmpStatus = U_ZERO_ERROR;
     int32_t len, i;
-    int32_t reslen = 0;
 
     if (U_FAILURE(*status)) {
-        return 0;
+        return;
     }
 
     len = uloc_getLanguage(localeID, buf, sizeof(buf), &tmpStatus);
     if (U_FAILURE(tmpStatus) || tmpStatus == U_STRING_NOT_TERMINATED_WARNING) {
         if (strict) {
             *status = U_ILLEGAL_ARGUMENT_ERROR;
-            return 0;
+            return;
         }
         len = 0;
     }
@@ -648,47 +1017,40 @@
     /* Note: returned language code is in lower case letters */
 
     if (len == 0) {
-        if (reslen < capacity) {
-            uprv_memcpy(appendAt + reslen, LANG_UND, uprv_min(LANG_UND_LEN, capacity - reslen));
-        }
-        reslen += LANG_UND_LEN;
-    } else if (!_isLanguageSubtag(buf, len)) {
+        sink.Append(LANG_UND, LANG_UND_LEN);
+    } else if (!ultag_isLanguageSubtag(buf, len)) {
             /* invalid language code */
         if (strict) {
             *status = U_ILLEGAL_ARGUMENT_ERROR;
-            return 0;
+            return;
         }
-        if (reslen < capacity) {
-            uprv_memcpy(appendAt + reslen, LANG_UND, uprv_min(LANG_UND_LEN, capacity - reslen));
-        }
-        reslen += LANG_UND_LEN;
+        sink.Append(LANG_UND, LANG_UND_LEN);
     } else {
         /* resolve deprecated */
         for (i = 0; i < UPRV_LENGTHOF(DEPRECATEDLANGS); i += 2) {
+            // 2-letter deprecated subtags are listede before 3-letter
+            // ones in DEPRECATEDLANGS[]. Get out of loop on coming
+            // across the 1st 3-letter subtag, if the input is a 2-letter code.
+            // to avoid continuing to try when there's no match.
+            if (uprv_strlen(buf) < uprv_strlen(DEPRECATEDLANGS[i])) break;
             if (uprv_compareInvCharsAsAscii(buf, DEPRECATEDLANGS[i]) == 0) {
                 uprv_strcpy(buf, DEPRECATEDLANGS[i + 1]);
                 len = (int32_t)uprv_strlen(buf);
                 break;
             }
         }
-        if (reslen < capacity) {
-            uprv_memcpy(appendAt + reslen, buf, uprv_min(len, capacity - reslen));
-        }
-        reslen += len;
+        sink.Append(buf, len);
     }
-    u_terminateChars(appendAt, capacity, reslen, status);
-    return reslen;
 }
 
-static int32_t
-_appendScriptToLanguageTag(const char* localeID, char* appendAt, int32_t capacity, UBool strict, UErrorCode* status) {
+static void
+_appendScriptToLanguageTag(const char* localeID, icu::ByteSink& sink, UBool strict, UErrorCode* status) {
     char buf[ULOC_SCRIPT_CAPACITY];
     UErrorCode tmpStatus = U_ZERO_ERROR;
     int32_t len;
-    int32_t reslen = 0;
 
     if (U_FAILURE(*status)) {
-        return 0;
+        return;
     }
 
     len = uloc_getScript(localeID, buf, sizeof(buf), &tmpStatus);
@@ -696,41 +1058,31 @@
         if (strict) {
             *status = U_ILLEGAL_ARGUMENT_ERROR;
         }
-        return 0;
+        return;
     }
 
     if (len > 0) {
-        if (!_isScriptSubtag(buf, len)) {
+        if (!ultag_isScriptSubtag(buf, len)) {
             /* invalid script code */
             if (strict) {
                 *status = U_ILLEGAL_ARGUMENT_ERROR;
             }
-            return 0;
+            return;
         } else {
-            if (reslen < capacity) {
-                *(appendAt + reslen) = SEP;
-            }
-            reslen++;
-
-            if (reslen < capacity) {
-                uprv_memcpy(appendAt + reslen, buf, uprv_min(len, capacity - reslen));
-            }
-            reslen += len;
+            sink.Append("-", 1);
+            sink.Append(buf, len);
         }
     }
-    u_terminateChars(appendAt, capacity, reslen, status);
-    return reslen;
 }
 
-static int32_t
-_appendRegionToLanguageTag(const char* localeID, char* appendAt, int32_t capacity, UBool strict, UErrorCode* status) {
+static void
+_appendRegionToLanguageTag(const char* localeID, icu::ByteSink& sink, UBool strict, UErrorCode* status) {
     char buf[ULOC_COUNTRY_CAPACITY];
     UErrorCode tmpStatus = U_ZERO_ERROR;
     int32_t len;
-    int32_t reslen = 0;
 
     if (U_FAILURE(*status)) {
-        return 0;
+        return;
     }
 
     len = uloc_getCountry(localeID, buf, sizeof(buf), &tmpStatus);
@@ -738,41 +1090,52 @@
         if (strict) {
             *status = U_ILLEGAL_ARGUMENT_ERROR;
         }
-        return 0;
+        return;
     }
 
     if (len > 0) {
-        if (!_isRegionSubtag(buf, len)) {
+        if (!ultag_isRegionSubtag(buf, len)) {
             /* invalid region code */
             if (strict) {
                 *status = U_ILLEGAL_ARGUMENT_ERROR;
             }
-            return 0;
+            return;
         } else {
-            if (reslen < capacity) {
-                *(appendAt + reslen) = SEP;
+            sink.Append("-", 1);
+            /* resolve deprecated */
+            for (int i = 0; i < UPRV_LENGTHOF(DEPRECATEDREGIONS); i += 2) {
+                if (uprv_compareInvCharsAsAscii(buf, DEPRECATEDREGIONS[i]) == 0) {
+                    uprv_strcpy(buf, DEPRECATEDREGIONS[i + 1]);
+                    len = (int32_t)uprv_strlen(buf);
+                    break;
+                }
             }
-            reslen++;
-
-            if (reslen < capacity) {
-                uprv_memcpy(appendAt + reslen, buf, uprv_min(len, capacity - reslen));
-            }
-            reslen += len;
+            sink.Append(buf, len);
         }
     }
-    u_terminateChars(appendAt, capacity, reslen, status);
-    return reslen;
 }
 
-static int32_t
-_appendVariantsToLanguageTag(const char* localeID, char* appendAt, int32_t capacity, UBool strict, UBool *hadPosix, UErrorCode* status) {
+static void _sortVariants(VariantListEntry* first) {
+    for (VariantListEntry* var1 = first; var1 != NULL; var1 = var1->next) {
+        for (VariantListEntry* var2 = var1->next; var2 != NULL; var2 = var2->next) {
+            // Swap var1->variant and var2->variant.
+            if (uprv_compareInvCharsAsAscii(var1->variant, var2->variant) > 0) {
+                const char* temp = var1->variant;
+                var1->variant = var2->variant;
+                var2->variant = temp;
+            }
+        }
+    }
+}
+
+static void
+_appendVariantsToLanguageTag(const char* localeID, icu::ByteSink& sink, UBool strict, UBool *hadPosix, UErrorCode* status) {
     char buf[ULOC_FULLNAME_CAPACITY];
     UErrorCode tmpStatus = U_ZERO_ERROR;
     int32_t len, i;
-    int32_t reslen = 0;
 
     if (U_FAILURE(*status)) {
-        return 0;
+        return;
     }
 
     len = uloc_getVariant(localeID, buf, sizeof(buf), &tmpStatus);
@@ -780,7 +1143,7 @@
         if (strict) {
             *status = U_ILLEGAL_ARGUMENT_ERROR;
         }
-        return 0;
+        return;
     }
 
     if (len > 0) {
@@ -813,7 +1176,7 @@
 
                     /* validate */
                     if (_isVariantSubtag(pVar, -1)) {
-                        if (uprv_strcmp(pVar,POSIX_VALUE) || len != uprv_strlen(POSIX_VALUE)) {
+                        if (uprv_strcmp(pVar,POSIX_VALUE) || len != (int32_t)uprv_strlen(POSIX_VALUE)) {
                             /* emit the variant to the list */
                             var = (VariantListEntry*)uprv_malloc(sizeof(VariantListEntry));
                             if (var == NULL) {
@@ -854,18 +1217,15 @@
             if (varFirst != NULL) {
                 int32_t varLen;
 
+                /* per UTS35, we should sort the variants */
+                _sortVariants(varFirst);
+
                 /* write out validated/normalized variants to the target */
                 var = varFirst;
                 while (var != NULL) {
-                    if (reslen < capacity) {
-                        *(appendAt + reslen) = SEP;
-                    }
-                    reslen++;
+                    sink.Append("-", 1);
                     varLen = (int32_t)uprv_strlen(var->variant);
-                    if (reslen < capacity) {
-                        uprv_memcpy(appendAt + reslen, var->variant, uprv_min(varLen, capacity - reslen));
-                    }
-                    reslen += varLen;
+                    sink.Append(var->variant, varLen);
                     var = var->next;
                 }
             }
@@ -880,29 +1240,25 @@
         }
 
         if (U_FAILURE(*status)) {
-            return 0;
+            return;
         }
     }
-
-    u_terminateChars(appendAt, capacity, reslen, status);
-    return reslen;
 }
 
-static int32_t
-_appendKeywordsToLanguageTag(const char* localeID, char* appendAt, int32_t capacity, UBool strict, UBool hadPosix, UErrorCode* status) {
-    char buf[ULOC_KEYWORD_AND_VALUES_CAPACITY];
+static void
+_appendKeywordsToLanguageTag(const char* localeID, icu::ByteSink& sink, UBool strict, UBool hadPosix, UErrorCode* status) {
     char attrBuf[ULOC_KEYWORD_AND_VALUES_CAPACITY] = { 0 };
     int32_t attrBufLength = 0;
-    UBool isAttribute = FALSE;
-    UEnumeration *keywordEnum = NULL;
-    int32_t reslen = 0;
 
-    keywordEnum = uloc_openKeywords(localeID, status);
+    icu::MemoryPool<AttributeListEntry> attrPool;
+    icu::MemoryPool<ExtensionListEntry> extPool;
+    icu::MemoryPool<icu::CharString> strPool;
+
+    icu::LocalUEnumerationPointer keywordEnum(uloc_openKeywords(localeID, status));
     if (U_FAILURE(*status) && !hadPosix) {
-        uenum_close(keywordEnum);
-        return 0;
+        return;
     }
-    if (keywordEnum != NULL || hadPosix) {
+    if (keywordEnum.isValid() || hadPosix) {
         /* reorder extensions */
         int32_t len;
         const char *key;
@@ -910,24 +1266,30 @@
         ExtensionListEntry *ext;
         AttributeListEntry *firstAttr = NULL;
         AttributeListEntry *attr;
-        char *attrValue;
-        char extBuf[ULOC_KEYWORD_AND_VALUES_CAPACITY];
-        char *pExtBuf = extBuf;
-        int32_t extBufCapacity = sizeof(extBuf);
-        const char *bcpKey, *bcpValue;
+        icu::MemoryPool<icu::CharString> extBufPool;
+        const char *bcpKey=nullptr, *bcpValue=nullptr;
         UErrorCode tmpStatus = U_ZERO_ERROR;
         int32_t keylen;
         UBool isBcpUExt;
 
         while (TRUE) {
-            isAttribute = FALSE;
-            key = uenum_next(keywordEnum, NULL, status);
+            key = uenum_next(keywordEnum.getAlias(), NULL, status);
             if (key == NULL) {
                 break;
             }
-            len = uloc_getKeywordValue(localeID, key, buf, sizeof(buf), &tmpStatus);
-            /* buf must be null-terminated */
-            if (U_FAILURE(tmpStatus) || tmpStatus == U_STRING_NOT_TERMINATED_WARNING) {
+
+            icu::CharString buf;
+            {
+                icu::CharStringByteSink sink(&buf);
+                ulocimp_getKeywordValue(localeID, key, sink, &tmpStatus);
+            }
+            len = buf.length();
+
+            if (U_FAILURE(tmpStatus)) {
+                if (tmpStatus == U_MEMORY_ALLOCATION_ERROR) {
+                    *status = U_MEMORY_ALLOCATION_ERROR;
+                    break;
+                }
                 if (strict) {
                     *status = U_ILLEGAL_ARGUMENT_ERROR;
                     break;
@@ -942,7 +1304,6 @@
 
             /* special keyword used for representing Unicode locale attributes */
             if (uprv_strcmp(key, LOCALE_ATTRIBUTE_KEY) == 0) {
-                isAttribute = TRUE;
                 if (len > 0) {
                     int32_t i = 0;
                     while (TRUE) {
@@ -963,28 +1324,32 @@
                         }
 
                         /* create AttributeListEntry */
-                        attr = (AttributeListEntry*)uprv_malloc(sizeof(AttributeListEntry));
+                        attr = attrPool.create();
                         if (attr == NULL) {
                             *status = U_MEMORY_ALLOCATION_ERROR;
                             break;
                         }
-                        attrValue = (char*)uprv_malloc(attrBufLength + 1);
+                        icu::CharString* attrValue =
+                                strPool.create(attrBuf, attrBufLength, *status);
                         if (attrValue == NULL) {
                             *status = U_MEMORY_ALLOCATION_ERROR;
                             break;
                         }
-                        uprv_strcpy(attrValue, attrBuf);
-                        attr->attribute = attrValue;
+                        if (U_FAILURE(*status)) {
+                            break;
+                        }
+                        attr->attribute = attrValue->data();
 
                         if (!_addAttributeToList(&firstAttr, attr)) {
-                            uprv_free(attr);
-                            uprv_free(attrValue);
                             if (strict) {
                                 *status = U_ILLEGAL_ARGUMENT_ERROR;
                                 break;
                             }
                         }
                     }
+                    /* for a place holder ExtensionListEntry */
+                    bcpKey = LOCALE_ATTRIBUTE_KEY;
+                    bcpValue = NULL;
                 }
             } else if (isBcpUExt) {
                 bcpKey = uloc_toUnicodeLocaleKey(key);
@@ -997,7 +1362,7 @@
                 }
 
                 /* we've checked buf is null-terminated above */
-                bcpValue = uloc_toUnicodeLocaleType(key, buf);
+                bcpValue = uloc_toUnicodeLocaleType(key, buf.data());
                 if (bcpValue == NULL) {
                     if (strict) {
                         *status = U_ILLEGAL_ARGUMENT_ERROR;
@@ -1005,33 +1370,30 @@
                     }
                     continue;
                 }
-                if (bcpValue == buf) {
-                    /* 
+                if (bcpValue == buf.data()) {
+                    /*
                     When uloc_toUnicodeLocaleType(key, buf) returns the
                     input value as is, the value is well-formed, but has
                     no known mapping. This implementation normalizes the
-                    the value to lower case
+                    value to lower case
                     */
-                    int32_t bcpValueLen = uprv_strlen(bcpValue);
-                    if (bcpValueLen < extBufCapacity) {
-                        uprv_strcpy(pExtBuf, bcpValue);
-                        T_CString_toLowerCase(pExtBuf);
+                    icu::CharString* extBuf = extBufPool.create(buf, tmpStatus);
 
-                        bcpValue = pExtBuf;
-
-                        pExtBuf += (bcpValueLen + 1);
-                        extBufCapacity -= (bcpValueLen + 1);
-                    } else {
-                        if (strict) {
-                            *status = U_ILLEGAL_ARGUMENT_ERROR;
-                            break;
-                        }
-                        continue;
+                    if (extBuf == nullptr) {
+                        *status = U_MEMORY_ALLOCATION_ERROR;
+                        break;
                     }
+                    if (U_FAILURE(tmpStatus)) {
+                        *status = tmpStatus;
+                        break;
+                    }
+
+                    T_CString_toLowerCase(extBuf->data());
+                    bcpValue = extBuf->data();
                 }
             } else {
                 if (*key == PRIVATEUSE) {
-                    if (!_isPrivateuseValueSubtags(buf, len)) {
+                    if (!ultag_isPrivateuseValueSubtags(buf.data(), len)) {
                         if (strict) {
                             *status = U_ILLEGAL_ARGUMENT_ERROR;
                             break;
@@ -1039,7 +1401,7 @@
                         continue;
                     }
                 } else {
-                    if (!_isExtensionSingleton(key, keylen) || !_isExtensionSubtags(buf, len)) {
+                    if (!_isExtensionSingleton(key, keylen) || !ultag_isExtensionSubtags(buf.data(), len)) {
                         if (strict) {
                             *status = U_ILLEGAL_ARGUMENT_ERROR;
                             break;
@@ -1048,38 +1410,32 @@
                     }
                 }
                 bcpKey = key;
-                if ((len + 1) < extBufCapacity) {
-                    uprv_memcpy(pExtBuf, buf, len);
-                    bcpValue = pExtBuf;
-
-                    pExtBuf += len;
-
-                    *pExtBuf = 0;
-                    pExtBuf++;
-
-                    extBufCapacity -= (len + 1);
-                } else {
-                    *status = U_ILLEGAL_ARGUMENT_ERROR;
-                    break;
-                }
-            }
-
-            if (!isAttribute) {
-                /* create ExtensionListEntry */
-                ext = (ExtensionListEntry*)uprv_malloc(sizeof(ExtensionListEntry));
-                if (ext == NULL) {
+                icu::CharString* extBuf =
+                    extBufPool.create(buf.data(), len, tmpStatus);
+                if (extBuf == nullptr) {
                     *status = U_MEMORY_ALLOCATION_ERROR;
                     break;
                 }
-                ext->key = bcpKey;
-                ext->value = bcpValue;
+                if (U_FAILURE(tmpStatus)) {
+                    *status = tmpStatus;
+                    break;
+                }
+                bcpValue = extBuf->data();
+            }
 
-                if (!_addExtensionToList(&firstExt, ext, TRUE)) {
-                    uprv_free(ext);
-                    if (strict) {
-                        *status = U_ILLEGAL_ARGUMENT_ERROR;
-                        break;
-                    }
+            /* create ExtensionListEntry */
+            ext = extPool.create();
+            if (ext == NULL) {
+                *status = U_MEMORY_ALLOCATION_ERROR;
+                break;
+            }
+            ext->key = bcpKey;
+            ext->value = bcpValue;
+
+            if (!_addExtensionToList(&firstExt, ext, TRUE)) {
+                if (strict) {
+                    *status = U_ILLEGAL_ARGUMENT_ERROR;
+                    break;
                 }
             }
         }
@@ -1087,103 +1443,48 @@
         /* Special handling for POSIX variant - add the keywords for POSIX */
         if (hadPosix) {
             /* create ExtensionListEntry for POSIX */
-            ext = (ExtensionListEntry*)uprv_malloc(sizeof(ExtensionListEntry));
+            ext = extPool.create();
             if (ext == NULL) {
                 *status = U_MEMORY_ALLOCATION_ERROR;
-                goto cleanup;
+                return;
             }
             ext->key = POSIX_KEY;
             ext->value = POSIX_VALUE;
 
             if (!_addExtensionToList(&firstExt, ext, TRUE)) {
-                uprv_free(ext);
+                // Silently ignore errors.
             }
         }
 
         if (U_SUCCESS(*status) && (firstExt != NULL || firstAttr != NULL)) {
             UBool startLDMLExtension = FALSE;
-
-            attr = firstAttr;
-            ext = firstExt;
-            do {
-                if (!startLDMLExtension && (ext && uprv_strlen(ext->key) > 1)) {
-                   /* write LDML singleton extension */
-                   if (reslen < capacity) {
-                       *(appendAt + reslen) = SEP;
-                   }
-                   reslen++;
-                   if (reslen < capacity) {
-                       *(appendAt + reslen) = LDMLEXT;
-                   }
-                   reslen++;
-
+            for (ext = firstExt; ext; ext = ext->next) {
+                if (!startLDMLExtension && uprv_strlen(ext->key) > 1) {
+                    /* first LDML u singlton extension */
+                   sink.Append("-u", 2);
                    startLDMLExtension = TRUE;
                 }
 
                 /* write out the sorted BCP47 attributes, extensions and private use */
-                if (ext && (uprv_strlen(ext->key) == 1 || attr == NULL)) {
-                    if (reslen < capacity) {
-                        *(appendAt + reslen) = SEP;
-                    }
-                    reslen++;
-                    len = (int32_t)uprv_strlen(ext->key);
-                    if (reslen < capacity) {
-                        uprv_memcpy(appendAt + reslen, ext->key, uprv_min(len, capacity - reslen));
-                    }
-                    reslen += len;
-                    if (reslen < capacity) {
-                        *(appendAt + reslen) = SEP;
-                    }
-                    reslen++;
-                    len = (int32_t)uprv_strlen(ext->value);
-                    if (reslen < capacity) {
-                        uprv_memcpy(appendAt + reslen, ext->value, uprv_min(len, capacity - reslen));
-                    }
-                    reslen += len;
-
-                    ext = ext->next;
-                } else if (attr) {
+                if (uprv_strcmp(ext->key, LOCALE_ATTRIBUTE_KEY) == 0) {
                     /* write the value for the attributes */
-                    if (reslen < capacity) {
-                        *(appendAt + reslen) = SEP;
+                    for (attr = firstAttr; attr; attr = attr->next) {
+                        sink.Append("-", 1);
+                        sink.Append(
+                                attr->attribute, static_cast<int32_t>(uprv_strlen(attr->attribute)));
                     }
-                    reslen++;
-                    len = (int32_t)uprv_strlen(attr->attribute);
-                    if (reslen < capacity) {
-                        uprv_memcpy(appendAt + reslen, attr->attribute, uprv_min(len, capacity - reslen));
+                } else {
+                    sink.Append("-", 1);
+                    sink.Append(ext->key, static_cast<int32_t>(uprv_strlen(ext->key)));
+                    if (uprv_strcmp(ext->value, "true") != 0 &&
+                        uprv_strcmp(ext->value, "yes") != 0) {
+                      sink.Append("-", 1);
+                      sink.Append(ext->value, static_cast<int32_t>(uprv_strlen(ext->value)));
                     }
-                    reslen += len;
-
-                    attr = attr->next;
                 }
-            } while (attr != NULL || ext != NULL);
-        }
-cleanup:
-        /* clean up */
-        ext = firstExt;
-        while (ext != NULL) {
-            ExtensionListEntry *tmpExt = ext->next;
-            uprv_free(ext);
-            ext = tmpExt;
-        }
-
-        attr = firstAttr;
-        while (attr != NULL) {
-            AttributeListEntry *tmpAttr = attr->next;
-            char *pValue = (char *)attr->attribute;
-            uprv_free(pValue);
-            uprv_free(attr);
-            attr = tmpAttr;
-        }
-
-        uenum_close(keywordEnum);
-
-        if (U_FAILURE(*status)) {
-            return 0;
+            }
         }
     }
-
-    return u_terminateChars(appendAt, capacity, reslen, status);
 }
 
 /**
@@ -1192,7 +1493,7 @@
  * Note: char* buf is used for storing keywords
  */
 static void
-_appendLDMLExtensionAsKeywords(const char* ldmlext, ExtensionListEntry** appendTo, char* buf, int32_t bufSize, UBool *posixVariant, UErrorCode *status) {
+_appendLDMLExtensionAsKeywords(const char* ldmlext, ExtensionListEntry** appendTo, icu::MemoryPool<ExtensionListEntry>& extPool, icu::MemoryPool<icu::CharString>& kwdBuf, UBool *posixVariant, UErrorCode *status) {
     const char *pTag;   /* beginning of current subtag */
     const char *pKwds;  /* beginning of key-type pairs */
     UBool variantExists = *posixVariant;
@@ -1200,14 +1501,7 @@
     ExtensionListEntry *kwdFirst = NULL;    /* first LDML keyword */
     ExtensionListEntry *kwd, *nextKwd;
 
-    AttributeListEntry *attrFirst = NULL;   /* first attribute */
-    AttributeListEntry *attr, *nextAttr;
-
     int32_t len;
-    int32_t bufIdx = 0;
-
-    char attrBuf[ULOC_KEYWORD_AND_VALUES_CAPACITY];
-    int32_t attrBufIdx = 0;
 
     /* Reset the posixVariant value */
     *posixVariant = FALSE;
@@ -1215,99 +1509,90 @@
     pTag = ldmlext;
     pKwds = NULL;
 
-    /* Iterate through u extension attributes */
-    while (*pTag) {
-        /* locate next separator char */
-        for (len = 0; *(pTag + len) && *(pTag + len) != SEP; len++);
+    {
+        AttributeListEntry *attrFirst = NULL;   /* first attribute */
+        AttributeListEntry *attr, *nextAttr;
 
-        if (ultag_isUnicodeLocaleKey(pTag, len)) {
-            pKwds = pTag;
-            break;
-        }
+        char attrBuf[ULOC_KEYWORD_AND_VALUES_CAPACITY];
+        int32_t attrBufIdx = 0;
 
-        /* add this attribute to the list */
-        attr = (AttributeListEntry*)uprv_malloc(sizeof(AttributeListEntry));
-        if (attr == NULL) {
-            *status = U_MEMORY_ALLOCATION_ERROR;
-            goto cleanup;
-        }
+        icu::MemoryPool<AttributeListEntry> attrPool;
 
-        if (len < (int32_t)sizeof(attrBuf) - attrBufIdx) {
-            uprv_memcpy(&attrBuf[attrBufIdx], pTag, len);
-            attrBuf[attrBufIdx + len] = 0;
-            attr->attribute = &attrBuf[attrBufIdx];
-            attrBufIdx += (len + 1);
-        } else {
-            *status = U_ILLEGAL_ARGUMENT_ERROR;
-            goto cleanup;
-        }
+        /* Iterate through u extension attributes */
+        while (*pTag) {
+            /* locate next separator char */
+            for (len = 0; *(pTag + len) && *(pTag + len) != SEP; len++);
 
-        if (!_addAttributeToList(&attrFirst, attr)) {
-            *status = U_ILLEGAL_ARGUMENT_ERROR;
-            uprv_free(attr);
-            goto cleanup;
-        }
-
-        /* next tag */
-        pTag += len;
-        if (*pTag) {
-            /* next to the separator */
-            pTag++;
-        }
-    }
-
-    if (attrFirst) {
-        /* emit attributes as an LDML keyword, e.g. attribute=attr1-attr2 */
-
-        if (attrBufIdx > bufSize) {
-            /* attrBufIdx == <total length of attribute subtag> + 1 */
-            *status = U_ILLEGAL_ARGUMENT_ERROR;
-            goto cleanup;
-        }
-
-        kwd = (ExtensionListEntry*)uprv_malloc(sizeof(ExtensionListEntry));
-        if (kwd == NULL) {
-            *status = U_MEMORY_ALLOCATION_ERROR;
-            goto cleanup;
-        }
-
-        kwd->key = LOCALE_ATTRIBUTE_KEY;
-        kwd->value = buf;
-
-        /* attribute subtags sorted in alphabetical order as type */
-        attr = attrFirst;
-        while (attr != NULL) {
-            nextAttr = attr->next;
-
-            /* buffer size check is done above */
-            if (attr != attrFirst) {
-                *(buf + bufIdx) = SEP;
-                bufIdx++;
+            if (ultag_isUnicodeLocaleKey(pTag, len)) {
+                pKwds = pTag;
+                break;
             }
 
-            len = uprv_strlen(attr->attribute);
-            uprv_memcpy(buf + bufIdx, attr->attribute, len);
-            bufIdx += len;
+            /* add this attribute to the list */
+            attr = attrPool.create();
+            if (attr == NULL) {
+                *status = U_MEMORY_ALLOCATION_ERROR;
+                return;
+            }
 
-            attr = nextAttr;
-        }
-        *(buf + bufIdx) = 0;
-        bufIdx++;
+            if (len < (int32_t)sizeof(attrBuf) - attrBufIdx) {
+                uprv_memcpy(&attrBuf[attrBufIdx], pTag, len);
+                attrBuf[attrBufIdx + len] = 0;
+                attr->attribute = &attrBuf[attrBufIdx];
+                attrBufIdx += (len + 1);
+            } else {
+                *status = U_ILLEGAL_ARGUMENT_ERROR;
+                return;
+            }
 
-        if (!_addExtensionToList(&kwdFirst, kwd, FALSE)) {
-            *status = U_ILLEGAL_ARGUMENT_ERROR;
-            uprv_free(kwd);
-            goto cleanup;
+            // duplicate attribute is ignored, causes no error.
+            _addAttributeToList(&attrFirst, attr);
+
+            /* next tag */
+            pTag += len;
+            if (*pTag) {
+                /* next to the separator */
+                pTag++;
+            }
         }
 
-        /* once keyword entry is created, delete the attribute list */
-        attr = attrFirst;
-        while (attr != NULL) {
-            nextAttr = attr->next;
-            uprv_free(attr);
-            attr = nextAttr;
+        if (attrFirst) {
+            /* emit attributes as an LDML keyword, e.g. attribute=attr1-attr2 */
+
+            kwd = extPool.create();
+            if (kwd == NULL) {
+                *status = U_MEMORY_ALLOCATION_ERROR;
+                return;
+            }
+
+            icu::CharString* value = kwdBuf.create();
+            if (value == NULL) {
+                *status = U_MEMORY_ALLOCATION_ERROR;
+                return;
+            }
+
+            /* attribute subtags sorted in alphabetical order as type */
+            attr = attrFirst;
+            while (attr != NULL) {
+                nextAttr = attr->next;
+                if (attr != attrFirst) {
+                    value->append('-', *status);
+                }
+                value->append(attr->attribute, *status);
+                attr = nextAttr;
+            }
+            if (U_FAILURE(*status)) {
+                return;
+            }
+
+            kwd->key = LOCALE_ATTRIBUTE_KEY;
+            kwd->value = value->data();
+
+            if (!_addExtensionToList(&kwdFirst, kwd, FALSE)) {
+                *status = U_ILLEGAL_ARGUMENT_ERROR;
+                return;
+            }
         }
-        attrFirst = NULL;
     }
 
     if (pKwds) {
@@ -1364,15 +1649,16 @@
                 const char *pKey = NULL;    /* LDML key */
                 const char *pType = NULL;   /* LDML type */
 
-                char bcpKeyBuf[9];          /* BCP key length is always 2 for now */
+                char bcpKeyBuf[3];          /* BCP key length is always 2 for now */
 
                 U_ASSERT(pBcpKey != NULL);
 
-                if (bcpKeyLen >= sizeof(bcpKeyBuf)) {
+                if (bcpKeyLen >= (int32_t)sizeof(bcpKeyBuf)) {
                     /* the BCP key is invalid */
                     *status = U_ILLEGAL_ARGUMENT_ERROR;
-                    goto cleanup;
+                    return;
                 }
+                U_ASSERT(bcpKeyLen <= 2);
 
                 uprv_strncpy(bcpKeyBuf, pBcpKey, bcpKeyLen);
                 bcpKeyBuf[bcpKeyLen] = 0;
@@ -1381,7 +1667,7 @@
                 pKey = uloc_toLegacyKey(bcpKeyBuf);
                 if (pKey == NULL) {
                     *status = U_ILLEGAL_ARGUMENT_ERROR;
-                    goto cleanup;
+                    return;
                 }
                 if (pKey == bcpKeyBuf) {
                     /*
@@ -1389,24 +1675,23 @@
                     We normalize the result key to lower case.
                     */
                     T_CString_toLowerCase(bcpKeyBuf);
-                    if (bufSize - bufIdx - 1 >= bcpKeyLen) {
-                        uprv_memcpy(buf + bufIdx, bcpKeyBuf, bcpKeyLen);
-                        pKey = buf + bufIdx;
-                        bufIdx += bcpKeyLen;
-                        *(buf + bufIdx) = 0;
-                        bufIdx++;
-                    } else {
-                        *status = U_BUFFER_OVERFLOW_ERROR;
-                        goto cleanup;
+                    icu::CharString* key = kwdBuf.create(bcpKeyBuf, bcpKeyLen, *status);
+                    if (key == NULL) {
+                        *status = U_MEMORY_ALLOCATION_ERROR;
+                        return;
                     }
+                    if (U_FAILURE(*status)) {
+                        return;
+                    }
+                    pKey = key->data();
                 }
 
                 if (pBcpType) {
                     char bcpTypeBuf[128];       /* practically long enough even considering multiple subtag type */
-                    if (bcpTypeLen >= sizeof(bcpTypeBuf)) {
+                    if (bcpTypeLen >= (int32_t)sizeof(bcpTypeBuf)) {
                         /* the BCP type is too long */
                         *status = U_ILLEGAL_ARGUMENT_ERROR;
-                        goto cleanup;
+                        return;
                     }
 
                     uprv_strncpy(bcpTypeBuf, pBcpType, bcpTypeLen);
@@ -1416,7 +1701,7 @@
                     pType = uloc_toLegacyType(pKey, bcpTypeBuf);
                     if (pType == NULL) {
                         *status = U_ILLEGAL_ARGUMENT_ERROR;
-                        goto cleanup;
+                        return;
                     }
                     if (pType == bcpTypeBuf) {
                         /*
@@ -1425,16 +1710,15 @@
                         */
                         /* normalize to lower case */
                         T_CString_toLowerCase(bcpTypeBuf);
-                        if (bufSize - bufIdx - 1 >= bcpTypeLen) {
-                            uprv_memcpy(buf + bufIdx, bcpTypeBuf, bcpTypeLen);
-                            pType = buf + bufIdx;
-                            bufIdx += bcpTypeLen;
-                            *(buf + bufIdx) = 0;
-                            bufIdx++;
-                        } else {
-                            *status = U_BUFFER_OVERFLOW_ERROR;
-                            goto cleanup;
+                        icu::CharString* type = kwdBuf.create(bcpTypeBuf, bcpTypeLen, *status);
+                        if (type == NULL) {
+                            *status = U_MEMORY_ALLOCATION_ERROR;
+                            return;
                         }
+                        if (U_FAILURE(*status)) {
+                            return;
+                        }
+                        pType = type->data();
                     }
                 } else {
                     /* typeless - default type value is "yes" */
@@ -1447,19 +1731,18 @@
                     *posixVariant = TRUE;
                 } else {
                     /* create an ExtensionListEntry for this keyword */
-                    kwd = (ExtensionListEntry*)uprv_malloc(sizeof(ExtensionListEntry));
+                    kwd = extPool.create();
                     if (kwd == NULL) {
                         *status = U_MEMORY_ALLOCATION_ERROR;
-                        goto cleanup;
+                        return;
                     }
 
                     kwd->key = pKey;
                     kwd->value = pType;
 
                     if (!_addExtensionToList(&kwdFirst, kwd, FALSE)) {
-                        *status = U_ILLEGAL_ARGUMENT_ERROR;
-                        uprv_free(kwd);
-                        goto cleanup;
+                        // duplicate keyword is allowed, Only the first
+                        // is honored.
                     }
                 }
 
@@ -1477,46 +1760,22 @@
         _addExtensionToList(appendTo, kwd, FALSE);
         kwd = nextKwd;
     }
-
-    return;
-
-cleanup:
-    attr = attrFirst;
-    while (attr != NULL) {
-        nextAttr = attr->next;
-        uprv_free(attr);
-        attr = nextAttr;
-    }
-
-    kwd = kwdFirst;
-    while (kwd != NULL) {
-        nextKwd = kwd->next;
-        uprv_free(kwd);
-        kwd = nextKwd;
-    }
 }
 
 
-static int32_t
-_appendKeywords(ULanguageTag* langtag, char* appendAt, int32_t capacity, UErrorCode* status) {
-    int32_t reslen = 0;
+static void
+_appendKeywords(ULanguageTag* langtag, icu::ByteSink& sink, UErrorCode* status) {
     int32_t i, n;
     int32_t len;
     ExtensionListEntry *kwdFirst = NULL;
     ExtensionListEntry *kwd;
     const char *key, *type;
-    char *kwdBuf = NULL;
-    int32_t kwdBufLength = capacity;
+    icu::MemoryPool<ExtensionListEntry> extPool;
+    icu::MemoryPool<icu::CharString> kwdBuf;
     UBool posixVariant = FALSE;
 
     if (U_FAILURE(*status)) {
-        return 0;
-    }
-
-    kwdBuf = (char*)uprv_malloc(kwdBufLength);
-    if (kwdBuf == NULL) {
-        *status = U_MEMORY_ALLOCATION_ERROR;
-        return 0;
+        return;
     }
 
     /* Determine if variants already exists */
@@ -1531,12 +1790,12 @@
         key = ultag_getExtensionKey(langtag, i);
         type = ultag_getExtensionValue(langtag, i);
         if (*key == LDMLEXT) {
-            _appendLDMLExtensionAsKeywords(type, &kwdFirst, kwdBuf, kwdBufLength, &posixVariant, status);
+            _appendLDMLExtensionAsKeywords(type, &kwdFirst, extPool, kwdBuf, &posixVariant, status);
             if (U_FAILURE(*status)) {
                 break;
             }
         } else {
-            kwd = (ExtensionListEntry*)uprv_malloc(sizeof(ExtensionListEntry));
+            kwd = extPool.create();
             if (kwd == NULL) {
                 *status = U_MEMORY_ALLOCATION_ERROR;
                 break;
@@ -1544,7 +1803,6 @@
             kwd->key = key;
             kwd->value = type;
             if (!_addExtensionToList(&kwdFirst, kwd, FALSE)) {
-                uprv_free(kwd);
                 *status = U_ILLEGAL_ARGUMENT_ERROR;
                 break;
             }
@@ -1555,14 +1813,13 @@
         type = ultag_getPrivateUse(langtag);
         if ((int32_t)uprv_strlen(type) > 0) {
             /* add private use as a keyword */
-            kwd = (ExtensionListEntry*)uprv_malloc(sizeof(ExtensionListEntry));
+            kwd = extPool.create();
             if (kwd == NULL) {
                 *status = U_MEMORY_ALLOCATION_ERROR;
             } else {
                 kwd->key = PRIVATEUSE_KEY;
                 kwd->value = type;
                 if (!_addExtensionToList(&kwdFirst, kwd, FALSE)) {
-                    uprv_free(kwd);
                     *status = U_ILLEGAL_ARGUMENT_ERROR;
                 }
             }
@@ -1573,10 +1830,7 @@
 
     if (U_SUCCESS(*status) && posixVariant) {
         len = (int32_t) uprv_strlen(_POSIX);
-        if (reslen < capacity) {
-            uprv_memcpy(appendAt + reslen, _POSIX, uprv_min(len, capacity - reslen));
-        }
-        reslen += len;
+        sink.Append(_POSIX, len);
     }
 
     if (U_SUCCESS(*status) && kwdFirst != NULL) {
@@ -1584,69 +1838,39 @@
         UBool firstValue = TRUE;
         kwd = kwdFirst;
         do {
-            if (reslen < capacity) {
-                if (firstValue) {
-                    /* '@' */
-                    *(appendAt + reslen) = LOCALE_EXT_SEP;
-                    firstValue = FALSE;
-                } else {
-                    /* ';' */
-                    *(appendAt + reslen) = LOCALE_KEYWORD_SEP;
-                }
+            if (firstValue) {
+                sink.Append("@", 1);
+                firstValue = FALSE;
+            } else {
+                sink.Append(";", 1);
             }
-            reslen++;
 
             /* key */
             len = (int32_t)uprv_strlen(kwd->key);
-            if (reslen < capacity) {
-                uprv_memcpy(appendAt + reslen, kwd->key, uprv_min(len, capacity - reslen));
-            }
-            reslen += len;
-
-            /* '=' */
-            if (reslen < capacity) {
-                *(appendAt + reslen) = LOCALE_KEY_TYPE_SEP;
-            }
-            reslen++;
+            sink.Append(kwd->key, len);
+            sink.Append("=", 1);
 
             /* type */
             len = (int32_t)uprv_strlen(kwd->value);
-            if (reslen < capacity) {
-                uprv_memcpy(appendAt + reslen, kwd->value, uprv_min(len, capacity - reslen));
-            }
-            reslen += len;
+            sink.Append(kwd->value, len);
 
             kwd = kwd->next;
         } while (kwd);
     }
-
-    /* clean up */
-    kwd = kwdFirst;
-    while (kwd != NULL) {
-        ExtensionListEntry *tmpKwd = kwd->next;
-        uprv_free(kwd);
-        kwd = tmpKwd;
-    }
-
-    uprv_free(kwdBuf);
-
-    if (U_FAILURE(*status)) {
-        return 0;
-    }
-
-    return u_terminateChars(appendAt, capacity, reslen, status);
 }
 
-static int32_t
-_appendPrivateuseToLanguageTag(const char* localeID, char* appendAt, int32_t capacity, UBool strict, UBool hadPosix, UErrorCode* status) {
+static void
+_appendPrivateuseToLanguageTag(const char* localeID, icu::ByteSink& sink, UBool strict, UBool hadPosix, UErrorCode* status) {
+    (void)hadPosix;
     char buf[ULOC_FULLNAME_CAPACITY];
     char tmpAppend[ULOC_FULLNAME_CAPACITY];
     UErrorCode tmpStatus = U_ZERO_ERROR;
     int32_t len, i;
     int32_t reslen = 0;
+    int32_t capacity = sizeof tmpAppend;
 
     if (U_FAILURE(*status)) {
-        return 0;
+        return;
     }
 
     len = uloc_getVariant(localeID, buf, sizeof(buf), &tmpStatus);
@@ -1654,7 +1878,7 @@
         if (strict) {
             *status = U_ILLEGAL_ARGUMENT_ERROR;
         }
-        return 0;
+        return;
     }
 
     if (len > 0) {
@@ -1738,20 +1962,14 @@
         }
 
         if (U_FAILURE(*status)) {
-            return 0;
+            return;
         }
     }
 
     if (U_SUCCESS(*status)) {
         len = reslen;
-        if (reslen < capacity) {
-            uprv_memcpy(appendAt, tmpAppend, uprv_min(len, capacity - reslen));
-        }
+        sink.Append(tmpAppend, len);
     }
-
-    u_terminateChars(appendAt, capacity, reslen, status);
-
-    return reslen;
 }
 
 /*
@@ -1772,9 +1990,18 @@
 #define EXTV 0x0040
 #define PRIV 0x0080
 
+/**
+ * Ticket #12705 - The optimizer in Visual Studio 2015 Update 3 has problems optimizing this function.
+ * As a work-around, optimization is disabled for this function on VS2015 and VS2017.
+ * This work-around should be removed once the following versions of Visual Studio are no
+ * longer supported: All versions of VS2015/VS2017, and versions of VS2019 below 16.4.
+ */
+#if defined(_MSC_VER) && (_MSC_VER >= 1900) && (_MSC_VER < 1924)
+#pragma optimize( "", off )
+#endif
+
 static ULanguageTag*
 ultag_parse(const char* tag, int32_t tagLen, int32_t* parsedLen, UErrorCode* status) {
-    ULanguageTag *t;
     char *tagBuf;
     int16_t next;
     char *pSubtag, *pNext, *pLastGoodPosition;
@@ -1784,7 +2011,7 @@
     char *pExtValueSubtag, *pExtValueSubtagEnd;
     int32_t i;
     UBool privateuseVar = FALSE;
-    int32_t grandfatheredLen = 0;
+    int32_t legacyLen = 0;
 
     if (parsedLen != NULL) {
         *parsedLen = 0;
@@ -1808,43 +2035,90 @@
     *(tagBuf + tagLen) = 0;
 
     /* create a ULanguageTag */
-    t = (ULanguageTag*)uprv_malloc(sizeof(ULanguageTag));
-    if (t == NULL) {
+    icu::LocalULanguageTagPointer t(
+            (ULanguageTag*)uprv_malloc(sizeof(ULanguageTag)));
+    if (t.isNull()) {
         uprv_free(tagBuf);
         *status = U_MEMORY_ALLOCATION_ERROR;
         return NULL;
     }
-    _initializeULanguageTag(t);
+    _initializeULanguageTag(t.getAlias());
     t->buf = tagBuf;
 
     if (tagLen < MINLEN) {
         /* the input tag is too short - return empty ULanguageTag */
-        return t;
+        return t.orphan();
     }
 
-    /* check if the tag is grandfathered */
-    for (i = 0; GRANDFATHERED[i] != NULL; i += 2) {
-        if (uprv_stricmp(GRANDFATHERED[i], tagBuf) == 0) {
+    size_t parsedLenDelta = 0;
+    // Legacy tag will be consider together. Legacy tag with intervening
+    // script and region such as art-DE-lojban or art-Latn-lojban won't be
+    // matched.
+    /* check if the tag is legacy */
+    for (i = 0; i < UPRV_LENGTHOF(LEGACY); i += 2) {
+        int32_t checkLegacyLen = static_cast<int32_t>(uprv_strlen(LEGACY[i]));
+        if (tagLen < checkLegacyLen) {
+            continue;
+        }
+        if (tagLen > checkLegacyLen && tagBuf[checkLegacyLen] != '-') {
+            // make sure next char is '-'.
+            continue;
+        }
+        if (uprv_strnicmp(LEGACY[i], tagBuf, checkLegacyLen) == 0) {
             int32_t newTagLength;
 
-            grandfatheredLen = tagLen;  /* back up for output parsedLen */
-            newTagLength = uprv_strlen(GRANDFATHERED[i+1]);
+            legacyLen = checkLegacyLen;  /* back up for output parsedLen */
+            int32_t replacementLen = static_cast<int32_t>(uprv_strlen(LEGACY[i+1]));
+            newTagLength = replacementLen + tagLen - checkLegacyLen;
             if (tagLen < newTagLength) {
                 uprv_free(tagBuf);
                 tagBuf = (char*)uprv_malloc(newTagLength + 1);
                 if (tagBuf == NULL) {
                     *status = U_MEMORY_ALLOCATION_ERROR;
-                    ultag_close(t);
                     return NULL;
                 }
                 t->buf = tagBuf;
                 tagLen = newTagLength;
             }
-            uprv_strcpy(t->buf, GRANDFATHERED[i + 1]);
+            parsedLenDelta = checkLegacyLen - replacementLen;
+            uprv_strcpy(t->buf, LEGACY[i + 1]);
+            if (checkLegacyLen != tagLen) {
+                uprv_strcpy(t->buf + replacementLen, tag + checkLegacyLen);
+            }
             break;
         }
     }
 
+    if (legacyLen == 0) {
+        for (i = 0; i < UPRV_LENGTHOF(REDUNDANT); i += 2) {
+            const char* redundantTag = REDUNDANT[i];
+            size_t redundantTagLen = uprv_strlen(redundantTag);
+            // The preferred tag for a redundant tag is always shorter than redundant
+            // tag. A redundant tag may or may not be followed by other subtags.
+            // (i.e. "zh-yue" or "zh-yue-u-co-pinyin").
+            if (uprv_strnicmp(redundantTag, tagBuf, static_cast<uint32_t>(redundantTagLen)) == 0) {
+                const char* redundantTagEnd = tagBuf + redundantTagLen;
+                if (*redundantTagEnd  == '\0' || *redundantTagEnd == SEP) {
+                    const char* preferredTag = REDUNDANT[i + 1];
+                    size_t preferredTagLen = uprv_strlen(preferredTag);
+                    uprv_strncpy(t->buf, preferredTag, preferredTagLen);
+                    if (*redundantTagEnd == SEP) {
+                        uprv_memmove(tagBuf + preferredTagLen,
+                                     redundantTagEnd,
+                                     tagLen - redundantTagLen + 1);
+                    } else {
+                        tagBuf[preferredTagLen] = '\0';
+                    }
+                    // parsedLen should be the length of the input
+                    // before redundantTag is replaced by preferredTag.
+                    // Save the delta to add it back later.
+                    parsedLenDelta = redundantTagLen - preferredTagLen;
+                    break;
+                }
+            }
+        }
+    }
+
     /*
      * langtag      =   language
      *                  ["-" script]
@@ -1883,12 +2157,15 @@
         subtagLen = (int32_t)(pSep - pSubtag);
 
         if (next & LANG) {
-            if (_isLanguageSubtag(pSubtag, subtagLen)) {
+            if (ultag_isLanguageSubtag(pSubtag, subtagLen)) {
                 *pSep = 0;  /* terminate */
+                // TODO: move deprecated language code handling here.
                 t->language = T_CString_toLowerCase(pSubtag);
 
                 pLastGoodPosition = pSep;
-                next = EXTL | SCRT | REGN | VART | EXTS | PRIV;
+                next = SCRT | REGN | VART | EXTS | PRIV;
+                if (subtagLen <= 3)
+                  next |= EXTL;
                 continue;
             }
         }
@@ -1907,7 +2184,7 @@
             }
         }
         if (next & SCRT) {
-            if (_isScriptSubtag(pSubtag, subtagLen)) {
+            if (ultag_isScriptSubtag(pSubtag, subtagLen)) {
                 char *p = pSubtag;
 
                 *pSep = 0;
@@ -1927,8 +2204,9 @@
             }
         }
         if (next & REGN) {
-            if (_isRegionSubtag(pSubtag, subtagLen)) {
+            if (ultag_isRegionSubtag(pSubtag, subtagLen)) {
                 *pSep = 0;
+                // TODO: move deprecated region code handling here.
                 t->region = T_CString_toUpperCase(pSubtag);
 
                 pLastGoodPosition = pSep;
@@ -1945,7 +2223,7 @@
                 var = (VariantListEntry*)uprv_malloc(sizeof(VariantListEntry));
                 if (var == NULL) {
                     *status = U_MEMORY_ALLOCATION_ERROR;
-                    goto error;
+                    return NULL;
                 }
                 *pSep = 0;
                 var->variant = T_CString_toUpperCase(pSubtag);
@@ -1989,7 +2267,7 @@
                 pExtension = (ExtensionListEntry*)uprv_malloc(sizeof(ExtensionListEntry));
                 if (pExtension == NULL) {
                     *status = U_MEMORY_ALLOCATION_ERROR;
-                    goto error;
+                    return NULL;
                 }
                 *pSep = 0;
                 pExtension->key = T_CString_toLowerCase(pSubtag);
@@ -2022,7 +2300,7 @@
             }
         }
         if (next & PRIV) {
-            if (uprv_tolower(*pSubtag) == PRIVATEUSE) {
+            if (uprv_tolower(*pSubtag) == PRIVATEUSE && subtagLen == 1) {
                 char *pPrivuseVal;
 
                 if (pExtension != NULL) {
@@ -2125,16 +2403,17 @@
     }
 
     if (parsedLen != NULL) {
-        *parsedLen = (grandfatheredLen > 0) ? grandfatheredLen : (int32_t)(pLastGoodPosition - t->buf);
+        *parsedLen = (int32_t)(pLastGoodPosition - t->buf + parsedLenDelta);
     }
 
-    return t;
-
-error:
-    ultag_close(t);
-    return NULL;
+    return t.orphan();
 }
 
+// Ticket #12705 - Turn optimization back on.
+#if defined(_MSC_VER) && (_MSC_VER >= 1900) && (_MSC_VER < 1924)
+#pragma optimize( "", on )
+#endif
+
 static void
 ultag_close(ULanguageTag* langtag) {
 
@@ -2296,8 +2575,8 @@
 
 #if 0
 static const char*
-ultag_getGrandfathered(const ULanguageTag* langtag) {
-    return langtag->grandfathered;
+ultag_getLegacy(const ULanguageTag* langtag) {
+    return langtag->legacy;
 }
 #endif
 
@@ -2315,49 +2594,110 @@
                    int32_t langtagCapacity,
                    UBool strict,
                    UErrorCode* status) {
-    /* char canonical[ULOC_FULLNAME_CAPACITY]; */ /* See #6822 */
-    char canonical[256];
-    int32_t reslen = 0;
+    if (U_FAILURE(*status)) {
+        return 0;
+    }
+
+    icu::CheckedArrayByteSink sink(langtag, langtagCapacity);
+    ulocimp_toLanguageTag(localeID, sink, strict, status);
+
+    int32_t reslen = sink.NumberOfBytesAppended();
+
+    if (U_FAILURE(*status)) {
+        return reslen;
+    }
+
+    if (sink.Overflowed()) {
+        *status = U_BUFFER_OVERFLOW_ERROR;
+    } else {
+        u_terminateChars(langtag, langtagCapacity, reslen, status);
+    }
+
+    return reslen;
+}
+
+
+U_CAPI void U_EXPORT2
+ulocimp_toLanguageTag(const char* localeID,
+                      icu::ByteSink& sink,
+                      UBool strict,
+                      UErrorCode* status) {
+    icu::CharString canonical;
+    int32_t reslen;
     UErrorCode tmpStatus = U_ZERO_ERROR;
     UBool hadPosix = FALSE;
     const char* pKeywordStart;
 
     /* Note: uloc_canonicalize returns "en_US_POSIX" for input locale ID "".  See #6835 */
-    canonical[0] = 0;
-    if (uprv_strlen(localeID) > 0) {
-        uloc_canonicalize(localeID, canonical, sizeof(canonical), &tmpStatus);
-        if (tmpStatus != U_ZERO_ERROR) {
+    int32_t resultCapacity = static_cast<int32_t>(uprv_strlen(localeID));
+    if (resultCapacity > 0) {
+        char* buffer;
+
+        for (;;) {
+            buffer = canonical.getAppendBuffer(
+                    /*minCapacity=*/resultCapacity,
+                    /*desiredCapacityHint=*/resultCapacity,
+                    resultCapacity,
+                    tmpStatus);
+
+            if (U_FAILURE(tmpStatus)) {
+                *status = tmpStatus;
+                return;
+            }
+
+            reslen =
+                uloc_canonicalize(localeID, buffer, resultCapacity, &tmpStatus);
+
+            if (tmpStatus != U_BUFFER_OVERFLOW_ERROR) {
+                break;
+            }
+
+            resultCapacity = reslen;
+            tmpStatus = U_ZERO_ERROR;
+        }
+
+        if (U_FAILURE(tmpStatus)) {
             *status = U_ILLEGAL_ARGUMENT_ERROR;
-            return 0;
+            return;
+        }
+
+        canonical.append(buffer, reslen, tmpStatus);
+        if (tmpStatus == U_STRING_NOT_TERMINATED_WARNING) {
+            tmpStatus = U_ZERO_ERROR;  // Terminators provided by CharString.
+        }
+
+        if (U_FAILURE(tmpStatus)) {
+            *status = tmpStatus;
+            return;
         }
     }
 
     /* For handling special case - private use only tag */
-    pKeywordStart = locale_getKeywordsStart(canonical);
-    if (pKeywordStart == canonical) {
-        UEnumeration *kwdEnum;
+    pKeywordStart = locale_getKeywordsStart(canonical.data());
+    if (pKeywordStart == canonical.data()) {
         int kwdCnt = 0;
         UBool done = FALSE;
 
-        kwdEnum = uloc_openKeywords((const char*)canonical, &tmpStatus);
-        if (kwdEnum != NULL) {
-            kwdCnt = uenum_count(kwdEnum, &tmpStatus);
+        icu::LocalUEnumerationPointer kwdEnum(uloc_openKeywords(canonical.data(), &tmpStatus));
+        if (U_SUCCESS(tmpStatus)) {
+            kwdCnt = uenum_count(kwdEnum.getAlias(), &tmpStatus);
             if (kwdCnt == 1) {
                 const char *key;
                 int32_t len = 0;
 
-                key = uenum_next(kwdEnum, &len, &tmpStatus);
+                key = uenum_next(kwdEnum.getAlias(), &len, &tmpStatus);
                 if (len == 1 && *key == PRIVATEUSE) {
-                    char buf[ULOC_KEYWORD_AND_VALUES_CAPACITY];
-                    buf[0] = PRIVATEUSE;
-                    buf[1] = SEP;
-                    len = uloc_getKeywordValue(localeID, key, &buf[2], sizeof(buf) - 2, &tmpStatus);
+                    icu::CharString buf;
+                    {
+                        icu::CharStringByteSink sink(&buf);
+                        ulocimp_getKeywordValue(localeID, key, sink, &tmpStatus);
+                    }
                     if (U_SUCCESS(tmpStatus)) {
-                        if (_isPrivateuseValueSubtags(&buf[2], len)) {
+                        if (ultag_isPrivateuseValueSubtags(buf.data(), buf.length())) {
                             /* return private use only tag */
-                            reslen = len + 2;
-                            uprv_memcpy(langtag, buf, uprv_min(reslen, langtagCapacity));
-                            u_terminateChars(langtag, langtagCapacity, reslen, status);
+                            static const char PREFIX[] = { PRIVATEUSE, SEP };
+                            sink.Append(PREFIX, sizeof(PREFIX));
+                            sink.Append(buf.data(), buf.length());
                             done = TRUE;
                         } else if (strict) {
                             *status = U_ILLEGAL_ARGUMENT_ERROR;
@@ -2370,21 +2710,18 @@
                     }
                 }
             }
-            uenum_close(kwdEnum);
             if (done) {
-                return reslen;
+                return;
             }
         }
     }
 
-    reslen += _appendLanguageToLanguageTag(canonical, langtag, langtagCapacity, strict, status);
-    reslen += _appendScriptToLanguageTag(canonical, langtag + reslen, langtagCapacity - reslen, strict, status);
-    reslen += _appendRegionToLanguageTag(canonical, langtag + reslen, langtagCapacity - reslen, strict, status);
-    reslen += _appendVariantsToLanguageTag(canonical, langtag + reslen, langtagCapacity - reslen, strict, &hadPosix, status);
-    reslen += _appendKeywordsToLanguageTag(canonical, langtag + reslen, langtagCapacity - reslen, strict, hadPosix, status);
-    reslen += _appendPrivateuseToLanguageTag(canonical, langtag + reslen, langtagCapacity - reslen, strict, hadPosix, status);
-
-    return reslen;
+    _appendLanguageToLanguageTag(canonical.data(), sink, strict, status);
+    _appendScriptToLanguageTag(canonical.data(), sink, strict, status);
+    _appendRegionToLanguageTag(canonical.data(), sink, strict, status);
+    _appendVariantsToLanguageTag(canonical.data(), sink, strict, &hadPosix, status);
+    _appendKeywordsToLanguageTag(canonical.data(), sink, strict, hadPosix, status);
+    _appendPrivateuseToLanguageTag(canonical.data(), sink, strict, hadPosix, status);
 }
 
 
@@ -2394,119 +2731,117 @@
                     int32_t localeIDCapacity,
                     int32_t* parsedLength,
                     UErrorCode* status) {
-    ULanguageTag *lt;
-    int32_t reslen = 0;
+    if (U_FAILURE(*status)) {
+        return 0;
+    }
+
+    icu::CheckedArrayByteSink sink(localeID, localeIDCapacity);
+    ulocimp_forLanguageTag(langtag, -1, sink, parsedLength, status);
+
+    int32_t reslen = sink.NumberOfBytesAppended();
+
+    if (U_FAILURE(*status)) {
+        return reslen;
+    }
+
+    if (sink.Overflowed()) {
+        *status = U_BUFFER_OVERFLOW_ERROR;
+    } else {
+        u_terminateChars(localeID, localeIDCapacity, reslen, status);
+    }
+
+    return reslen;
+}
+
+
+U_CAPI void U_EXPORT2
+ulocimp_forLanguageTag(const char* langtag,
+                       int32_t tagLen,
+                       icu::ByteSink& sink,
+                       int32_t* parsedLength,
+                       UErrorCode* status) {
+    UBool isEmpty = TRUE;
     const char *subtag, *p;
     int32_t len;
     int32_t i, n;
     UBool noRegion = TRUE;
 
-    lt = ultag_parse(langtag, -1, parsedLength, status);
+    icu::LocalULanguageTagPointer lt(ultag_parse(langtag, tagLen, parsedLength, status));
     if (U_FAILURE(*status)) {
-        return 0;
+        return;
     }
 
     /* language */
-    subtag = ultag_getExtlangSize(lt) > 0 ? ultag_getExtlang(lt, 0) : ultag_getLanguage(lt);
+    subtag = ultag_getExtlangSize(lt.getAlias()) > 0 ? ultag_getExtlang(lt.getAlias(), 0) : ultag_getLanguage(lt.getAlias());
     if (uprv_compareInvCharsAsAscii(subtag, LANG_UND) != 0) {
         len = (int32_t)uprv_strlen(subtag);
         if (len > 0) {
-            if (reslen < localeIDCapacity) {
-                uprv_memcpy(localeID, subtag, uprv_min(len, localeIDCapacity - reslen));
-            }
-            reslen += len;
+            sink.Append(subtag, len);
+            isEmpty = FALSE;
         }
     }
 
     /* script */
-    subtag = ultag_getScript(lt);
+    subtag = ultag_getScript(lt.getAlias());
     len = (int32_t)uprv_strlen(subtag);
     if (len > 0) {
-        if (reslen < localeIDCapacity) {
-            *(localeID + reslen) = LOCALE_SEP;
-        }
-        reslen++;
+        sink.Append("_", 1);
+        isEmpty = FALSE;
 
         /* write out the script in title case */
-        p = subtag;
-        while (*p) {
-            if (reslen < localeIDCapacity) {
-                if (p == subtag) {
-                    *(localeID + reslen) = uprv_toupper(*p);
-                } else {
-                    *(localeID + reslen) = *p;
-                }
-            }
-            reslen++;
-            p++;
-        }
+        char c = uprv_toupper(*subtag);
+        sink.Append(&c, 1);
+        sink.Append(subtag + 1, len - 1);
     }
 
     /* region */
-    subtag = ultag_getRegion(lt);
+    subtag = ultag_getRegion(lt.getAlias());
     len = (int32_t)uprv_strlen(subtag);
     if (len > 0) {
-        if (reslen < localeIDCapacity) {
-            *(localeID + reslen) = LOCALE_SEP;
-        }
-        reslen++;
-        /* write out the retion in upper case */
+        sink.Append("_", 1);
+        isEmpty = FALSE;
+
+        /* write out the region in upper case */
         p = subtag;
         while (*p) {
-            if (reslen < localeIDCapacity) {
-                *(localeID + reslen) = uprv_toupper(*p);
-            }
-            reslen++;
+            char c = uprv_toupper(*p);
+            sink.Append(&c, 1);
             p++;
         }
         noRegion = FALSE;
     }
 
     /* variants */
-    n = ultag_getVariantsSize(lt);
+    _sortVariants(lt.getAlias()->variants);
+    n = ultag_getVariantsSize(lt.getAlias());
     if (n > 0) {
         if (noRegion) {
-            if (reslen < localeIDCapacity) {
-                *(localeID + reslen) = LOCALE_SEP;
-            }
-            reslen++;
+            sink.Append("_", 1);
+            isEmpty = FALSE;
         }
 
         for (i = 0; i < n; i++) {
-            subtag = ultag_getVariant(lt, i);
-            if (reslen < localeIDCapacity) {
-                *(localeID + reslen) = LOCALE_SEP;
-            }
-            reslen++;
+            subtag = ultag_getVariant(lt.getAlias(), i);
+            sink.Append("_", 1);
+
             /* write out the variant in upper case */
             p = subtag;
             while (*p) {
-                if (reslen < localeIDCapacity) {
-                    *(localeID + reslen) = uprv_toupper(*p);
-                }
-                reslen++;
+                char c = uprv_toupper(*p);
+                sink.Append(&c, 1);
                 p++;
             }
         }
     }
 
     /* keywords */
-    n = ultag_getExtensionsSize(lt);
-    subtag = ultag_getPrivateUse(lt);
+    n = ultag_getExtensionsSize(lt.getAlias());
+    subtag = ultag_getPrivateUse(lt.getAlias());
     if (n > 0 || uprv_strlen(subtag) > 0) {
-        if (reslen == 0 && n > 0) {
+        if (isEmpty && n > 0) {
             /* need a language */
-            if (reslen < localeIDCapacity) {
-                uprv_memcpy(localeID + reslen, LANG_UND, uprv_min(LANG_UND_LEN, localeIDCapacity - reslen));
-            }
-            reslen += LANG_UND_LEN;
+            sink.Append(LANG_UND, LANG_UND_LEN);
         }
-        len = _appendKeywords(lt, localeID + reslen, localeIDCapacity - reslen, status);
-        reslen += len;
+        _appendKeywords(lt.getAlias(), sink, status);
     }
-
-    ultag_close(lt);
-    return u_terminateChars(localeID, localeIDCapacity, reslen, status);
 }
-
-
diff --git a/src/third_party/icu/source/common/ulocimp.h b/src/third_party/icu/source/common/ulocimp.h
index 164a730..5691fe9 100644
--- a/src/third_party/icu/source/common/ulocimp.h
+++ b/src/third_party/icu/source/common/ulocimp.h
@@ -1,6 +1,8 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
-*   Copyright (C) 2004-2014, International Business Machines
+*   Copyright (C) 2004-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 **********************************************************************
 */
@@ -8,8 +10,11 @@
 #ifndef ULOCIMP_H
 #define ULOCIMP_H
 
+#include "unicode/bytestream.h"
 #include "unicode/uloc.h"
 
+#include "charstr.h"
+
 /**
  * Create an iterator over the specified keywords list
  * @param keywordList double-null terminated list. Will be copied.
@@ -35,7 +40,7 @@
     int32_t *pLength,
     UErrorCode *pErrorCode);
 
-/*returns TRUE if a is an ID separator FALSE otherwise*/
+/*returns true if a is an ID separator false otherwise*/
 #define _isIDSeparator(a) (a == '_' || a == '-')
 
 U_CFUNC const char* 
@@ -44,24 +49,233 @@
 U_CFUNC const char* 
 uloc_getCurrentLanguageID(const char* oldID);
 
-U_CFUNC int32_t
+U_CFUNC void
+ulocimp_getKeywords(const char *localeID,
+             char prev,
+             icu::ByteSink& sink,
+             UBool valuesToo,
+             UErrorCode *status);
+
+icu::CharString U_EXPORT2
 ulocimp_getLanguage(const char *localeID,
-                    char *language, int32_t languageCapacity,
-                    const char **pEnd);
+                    const char **pEnd,
+                    UErrorCode &status);
 
-U_CFUNC int32_t
+icu::CharString U_EXPORT2
 ulocimp_getScript(const char *localeID,
-                   char *script, int32_t scriptCapacity,
-                   const char **pEnd);
+                  const char **pEnd,
+                  UErrorCode &status);
 
-U_CFUNC int32_t
+icu::CharString U_EXPORT2
 ulocimp_getCountry(const char *localeID,
-                   char *country, int32_t countryCapacity,
-                   const char **pEnd);
+                   const char **pEnd,
+                   UErrorCode &status);
+
+U_CAPI void U_EXPORT2
+ulocimp_getName(const char* localeID,
+                icu::ByteSink& sink,
+                UErrorCode* err);
+
+U_CAPI void U_EXPORT2
+ulocimp_getBaseName(const char* localeID,
+                    icu::ByteSink& sink,
+                    UErrorCode* err);
+
+U_CAPI void U_EXPORT2
+ulocimp_canonicalize(const char* localeID,
+                     icu::ByteSink& sink,
+                     UErrorCode* err);
+
+U_CAPI void U_EXPORT2
+ulocimp_getKeywordValue(const char* localeID,
+                        const char* keywordName,
+                        icu::ByteSink& sink,
+                        UErrorCode* status);
+
+/**
+ * Writes a well-formed language tag for this locale ID.
+ *
+ * **Note**: When `strict` is false, any locale fields which do not satisfy the
+ * BCP47 syntax requirement will be omitted from the result.  When `strict` is
+ * true, this function sets U_ILLEGAL_ARGUMENT_ERROR to the `err` if any locale
+ * fields do not satisfy the BCP47 syntax requirement.
+ *
+ * @param localeID  the input locale ID
+ * @param sink      the output sink receiving the BCP47 language
+ *                  tag for this Locale.
+ * @param strict    boolean value indicating if the function returns
+ *                  an error for an ill-formed input locale ID.
+ * @param err       error information if receiving the language
+ *                  tag failed.
+ * @return          The length of the BCP47 language tag.
+ *
+ * @internal ICU 64
+ */
+U_CAPI void U_EXPORT2
+ulocimp_toLanguageTag(const char* localeID,
+                      icu::ByteSink& sink,
+                      UBool strict,
+                      UErrorCode* err);
+
+/**
+ * Returns a locale ID for the specified BCP47 language tag string.
+ * If the specified language tag contains any ill-formed subtags,
+ * the first such subtag and all following subtags are ignored.
+ * <p>
+ * This implements the 'Language-Tag' production of BCP 47, and so
+ * supports legacy language tags (marked as “Type: grandfathered” in BCP 47)
+ * (regular and irregular) as well as private use language tags.
+ *
+ * Private use tags are represented as 'x-whatever',
+ * and legacy tags are converted to their canonical replacements where they exist.
+ *
+ * Note that a few legacy tags have no modern replacement;
+ * these will be converted using the fallback described in
+ * the first paragraph, so some information might be lost.
+ *
+ * @param langtag   the input BCP47 language tag.
+ * @param tagLen    the length of langtag, or -1 to call uprv_strlen().
+ * @param sink      the output sink receiving a locale ID for the
+ *                  specified BCP47 language tag.
+ * @param parsedLength  if not NULL, successfully parsed length
+ *                      for the input language tag is set.
+ * @param err       error information if receiving the locald ID
+ *                  failed.
+ * @internal ICU 63
+ */
+U_CAPI void U_EXPORT2
+ulocimp_forLanguageTag(const char* langtag,
+                       int32_t tagLen,
+                       icu::ByteSink& sink,
+                       int32_t* parsedLength,
+                       UErrorCode* err);
+
+/**
+ * Get the region to use for supplemental data lookup. Uses
+ * (1) any region specified by locale tag "rg"; if none then
+ * (2) any unicode_region_tag in the locale ID; if none then
+ * (3) if inferRegion is true, the region suggested by
+ * getLikelySubtags on the localeID.
+ * If no region is found, returns length 0.
+ * 
+ * @param localeID
+ *     The complete locale ID (with keywords) from which
+ *     to get the region to use for supplemental data.
+ * @param inferRegion
+ *     If true, will try to infer region from localeID if
+ *     no other region is found.
+ * @param region
+ *     Buffer in which to put the region ID found; should
+ *     have a capacity at least ULOC_COUNTRY_CAPACITY. 
+ * @param regionCapacity
+ *     The actual capacity of the region buffer.
+ * @param status
+ *     Pointer to in/out UErrorCode value for latest status.
+ * @return
+ *     The length of any region code found, or 0 if none.
+ * @internal ICU 57
+ */
+U_CAPI int32_t U_EXPORT2
+ulocimp_getRegionForSupplementalData(const char *localeID, UBool inferRegion,
+                                     char *region, int32_t regionCapacity, UErrorCode* status);
+
+/**
+ * Add the likely subtags for a provided locale ID, per the algorithm described
+ * in the following CLDR technical report:
+ *
+ *   http://www.unicode.org/reports/tr35/#Likely_Subtags
+ *
+ * If localeID is already in the maximal form, or there is no data available
+ * for maximization, it will be copied to the output buffer.  For example,
+ * "und-Zzzz" cannot be maximized, since there is no reasonable maximization.
+ *
+ * Examples:
+ *
+ * "en" maximizes to "en_Latn_US"
+ *
+ * "de" maximizes to "de_Latn_US"
+ *
+ * "sr" maximizes to "sr_Cyrl_RS"
+ *
+ * "sh" maximizes to "sr_Latn_RS" (Note this will not reverse.)
+ *
+ * "zh_Hani" maximizes to "zh_Hans_CN" (Note this will not reverse.)
+ *
+ * @param localeID The locale to maximize
+ * @param sink The output sink receiving the maximized locale
+ * @param err Error information if maximizing the locale failed.  If the length
+ * of the localeID and the null-terminator is greater than the maximum allowed size,
+ * or the localeId is not well-formed, the error code is U_ILLEGAL_ARGUMENT_ERROR.
+ * @internal ICU 64
+ */
+U_CAPI void U_EXPORT2
+ulocimp_addLikelySubtags(const char* localeID,
+                         icu::ByteSink& sink,
+                         UErrorCode* err);
+
+/**
+ * Minimize the subtags for a provided locale ID, per the algorithm described
+ * in the following CLDR technical report:
+ *
+ *   http://www.unicode.org/reports/tr35/#Likely_Subtags
+ *
+ * If localeID is already in the minimal form, or there is no data available
+ * for minimization, it will be copied to the output buffer.  Since the
+ * minimization algorithm relies on proper maximization, see the comments
+ * for ulocimp_addLikelySubtags for reasons why there might not be any data.
+ *
+ * Examples:
+ *
+ * "en_Latn_US" minimizes to "en"
+ *
+ * "de_Latn_US" minimizes to "de"
+ *
+ * "sr_Cyrl_RS" minimizes to "sr"
+ *
+ * "zh_Hant_TW" minimizes to "zh_TW" (The region is preferred to the
+ * script, and minimizing to "zh" would imply "zh_Hans_CN".)
+ *
+ * @param localeID The locale to minimize
+ * @param sink The output sink receiving the maximized locale
+ * @param err Error information if minimizing the locale failed.  If the length
+ * of the localeID and the null-terminator is greater than the maximum allowed size,
+ * or the localeId is not well-formed, the error code is U_ILLEGAL_ARGUMENT_ERROR.
+ * @internal ICU 64
+ */
+U_CAPI void U_EXPORT2
+ulocimp_minimizeSubtags(const char* localeID,
+                        icu::ByteSink& sink,
+                        UErrorCode* err);
 
 U_CAPI const char * U_EXPORT2
 locale_getKeywordsStart(const char *localeID);
 
+U_CFUNC UBool
+ultag_isExtensionSubtags(const char* s, int32_t len);
+
+U_CFUNC UBool
+ultag_isLanguageSubtag(const char* s, int32_t len);
+
+U_CFUNC UBool
+ultag_isPrivateuseValueSubtags(const char* s, int32_t len);
+
+U_CFUNC UBool
+ultag_isRegionSubtag(const char* s, int32_t len);
+
+U_CFUNC UBool
+ultag_isScriptSubtag(const char* s, int32_t len);
+
+U_CFUNC UBool
+ultag_isTransformedExtensionSubtags(const char* s, int32_t len);
+
+U_CFUNC UBool
+ultag_isUnicodeExtensionSubtags(const char* s, int32_t len);
+
+U_CFUNC UBool
+ultag_isUnicodeLocaleAttribute(const char* s, int32_t len);
+
+U_CFUNC UBool
+ultag_isUnicodeLocaleAttributes(const char* s, int32_t len);
 
 U_CFUNC UBool
 ultag_isUnicodeLocaleKey(const char* s, int32_t len);
@@ -69,6 +283,9 @@
 U_CFUNC UBool
 ultag_isUnicodeLocaleType(const char* s, int32_t len);
 
+U_CFUNC UBool
+ultag_isVariantSubtags(const char* s, int32_t len);
+
 U_CFUNC const char*
 ulocimp_toBcpKey(const char* key);
 
@@ -81,4 +298,10 @@
 U_CFUNC const char*
 ulocimp_toLegacyType(const char* key, const char* type, UBool* isKnownKey, UBool* isSpecialType);
 
+/* Function for testing purpose */
+U_CAPI const char* const* ulocimp_getKnownCanonicalizedLocaleForTest(int32_t* length);
+
+// Return true if the value is already canonicalized.
+U_CAPI bool ulocimp_isCanonicalizedLocaleForTest(const char* localeName);
+
 #endif
diff --git a/src/third_party/icu/source/common/umapfile.c b/src/third_party/icu/source/common/umapfile.cpp
similarity index 71%
rename from src/third_party/icu/source/common/umapfile.c
rename to src/third_party/icu/source/common/umapfile.cpp
index b40dd6c..b2aad14 100644
--- a/src/third_party/icu/source/common/umapfile.c
+++ b/src/third_party/icu/source/common/umapfile.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
@@ -20,24 +22,47 @@
 #include "uposixdefs.h"
 
 #include "unicode/putil.h"
+#include "unicode/ustring.h"
 #include "udatamem.h"
 #include "umapfile.h"
 
 /* memory-mapping base definitions ------------------------------------------ */
 
 #if MAP_IMPLEMENTATION==MAP_WIN32
+#ifndef WIN32_LEAN_AND_MEAN
 #   define WIN32_LEAN_AND_MEAN
+#endif
 #   define VC_EXTRALEAN
 #   define NOUSER
 #   define NOSERVICE
 #   define NOIME
 #   define NOMCX
+
+#   if U_PLATFORM_HAS_WINUWP_API == 1
+        // Some previous versions of the Windows 10 SDK don't expose various APIs for UWP applications
+        // to use, even though UWP apps are allowed to call and use them.  Temporarily change the
+        // WINAPI family partition below to Desktop, so that function declarations are visible for UWP.
+#       include <winapifamily.h>
+#       if !(WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM))
+#           pragma push_macro("WINAPI_PARTITION_DESKTOP")
+#           undef WINAPI_PARTITION_DESKTOP
+#           define WINAPI_PARTITION_DESKTOP 1
+#           define CHANGED_WINAPI_PARTITION_DESKTOP_VALUE
+#       endif
+#   endif
+
 #   include <windows.h>
+
+#   if U_PLATFORM_HAS_WINUWP_API == 1 && defined(CHANGED_WINAPI_PARTITION_DESKTOP_VALUE)
+#       pragma pop_macro("WINAPI_PARTITION_DESKTOP")
+#   endif
+
 #   include "cmemory.h"
 
-    typedef HANDLE MemoryMap;
+typedef HANDLE MemoryMap;
 
-#   define IS_MAP(map) ((map)!=NULL)
+#   define IS_MAP(map) ((map)!=nullptr)
+
 #elif MAP_IMPLEMENTATION==MAP_POSIX || MAP_IMPLEMENTATION==MAP_390DLL
     typedef size_t MemoryMap;
 
@@ -60,7 +85,7 @@
 #       include "unicode/udata.h"
 #       define LIB_PREFIX "lib"
 #       define LIB_SUFFIX ".dll"
-        /* This is inconvienient until we figure out what to do with U_ICUDATA_NAME in utypes.h */
+        /* This is inconvenient until we figure out what to do with U_ICUDATA_NAME in utypes.h */
 #       define U_ICUDATA_ENTRY_NAME "icudt" U_ICU_VERSION_SHORT U_LIB_SUFFIX_C_NAME_STRING "_dat"
 #   endif
 #elif MAP_IMPLEMENTATION==MAP_STDIO
@@ -69,7 +94,7 @@
 
     typedef void *MemoryMap;
 
-#   define IS_MAP(map) ((map)!=NULL)
+#   define IS_MAP(map) ((map)!=nullptr)
 #elif MAP_IMPLEMENTATION==MAP_STARBOARD
 #   include "starboard/file.h"
 #   include "cmemory.h"
@@ -78,6 +103,7 @@
 
 #   define IS_MAP(map) ((map)!=NULL)
 #endif
+
 /*----------------------------------------------------------------------------*
  *                                                                            *
  *   Memory Mapped File support.  Platform dependent implementation of        *
@@ -86,7 +112,10 @@
  *----------------------------------------------------------------------------*/
 #if MAP_IMPLEMENTATION==MAP_NONE
     U_CFUNC UBool
-    uprv_mapFile(UDataMemory *pData, const char *path) {
+    uprv_mapFile(UDataMemory *pData, const char *path, UErrorCode *status) {
+        if (U_FAILURE(*status)) {
+            return FALSE;
+        }
         UDataMemory_init(pData); /* Clear the output struct. */
         return FALSE;            /* no file access */
     }
@@ -94,70 +123,94 @@
     U_CFUNC void uprv_unmapFile(UDataMemory *pData) {
         /* nothing to do */
     }
+
 #elif MAP_IMPLEMENTATION==MAP_WIN32
     U_CFUNC UBool
     uprv_mapFile(
          UDataMemory *pData,    /* Fill in with info on the result doing the mapping. */
                                 /*   Output only; any original contents are cleared.  */
-         const char *path       /* File path to be opened/mapped                      */
+         const char *path,      /* File path to be opened/mapped.                     */
+         UErrorCode *status     /* Error status, used to report out-of-memory errors. */
          )
     {
-        HANDLE map;
-        HANDLE file;
-        SECURITY_ATTRIBUTES mappingAttributes;
-        SECURITY_ATTRIBUTES *mappingAttributesPtr = NULL;
-        SECURITY_DESCRIPTOR securityDesc;
+        if (U_FAILURE(*status)) {
+            return FALSE;
+        }
+
+        HANDLE map = nullptr;
+        HANDLE file = INVALID_HANDLE_VALUE;
 
         UDataMemory_init(pData); /* Clear the output struct.        */
 
         /* open the input file */
-        file=CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, NULL,
+#if U_PLATFORM_HAS_WINUWP_API == 0
+        // Note: In the non-UWP code-path (ie: Win32), the value of the path variable might have come from 
+        // the CRT 'getenv' function, and would be therefore be encoded in the default ANSI code page.
+        // This means that we can't call the *W version of API below, whereas in the UWP code-path
+        // there is no 'getenv' call, and thus the string will be only UTF-8/Invariant characters.
+        file=CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, nullptr,
             OPEN_EXISTING,
-            FILE_ATTRIBUTE_NORMAL|FILE_FLAG_RANDOM_ACCESS, NULL);
-        if(file==INVALID_HANDLE_VALUE) {
+            FILE_ATTRIBUTE_NORMAL|FILE_FLAG_RANDOM_ACCESS, nullptr);
+#else
+        // Convert from UTF-8 string to UTF-16 string.
+        wchar_t utf16Path[MAX_PATH];
+        int32_t pathUtf16Len = 0;
+        u_strFromUTF8(reinterpret_cast<UChar*>(utf16Path), static_cast<int32_t>(UPRV_LENGTHOF(utf16Path)), &pathUtf16Len, path, -1, status);
+
+        if (U_FAILURE(*status)) {
+            return FALSE;
+        }
+        if (*status == U_STRING_NOT_TERMINATED_WARNING) {
+            // Report back an error instead of a warning.
+            *status = U_BUFFER_OVERFLOW_ERROR;
             return FALSE;
         }
 
-        /* Declare and initialize a security descriptor.
-           This is required for multiuser systems on Windows 2000 SP4 and beyond */
-        if (InitializeSecurityDescriptor(&securityDesc, SECURITY_DESCRIPTOR_REVISION)) {
-            /* give the security descriptor a Null Dacl done using the  "TRUE, (PACL)NULL" here	*/
-            if (SetSecurityDescriptorDacl(&securityDesc, TRUE, (PACL)NULL, FALSE)) {
-                /* Make the security attributes point to the security descriptor */
-                uprv_memset(&mappingAttributes, 0, sizeof(mappingAttributes));
-                mappingAttributes.nLength = sizeof(mappingAttributes);
-                mappingAttributes.lpSecurityDescriptor = &securityDesc;
-                mappingAttributes.bInheritHandle = FALSE; /* object uninheritable */
-                mappingAttributesPtr = &mappingAttributes;
+        file = CreateFileW(utf16Path, GENERIC_READ, FILE_SHARE_READ, nullptr,
+            OPEN_EXISTING,
+            FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, nullptr);
+#endif
+        if (file == INVALID_HANDLE_VALUE) {
+            // If we failed to open the file due to an out-of-memory error, then we want
+            // to report that error back to the caller.
+            if (HRESULT_FROM_WIN32(GetLastError()) == E_OUTOFMEMORY) {
+                *status = U_MEMORY_ALLOCATION_ERROR;
             }
+            return FALSE;
         }
-        /* else creating security descriptors can fail when we are on Windows 98,
-           and mappingAttributesPtr == NULL for that case. */
 
+        // Note: We use NULL/nullptr for lpAttributes parameter below.
+        // This means our handle cannot be inherited and we will get the default security descriptor.
         /* create an unnamed Windows file-mapping object for the specified file */
-        map=CreateFileMapping(file, mappingAttributesPtr, PAGE_READONLY, 0, 0, NULL);
+        map = CreateFileMappingW(file, nullptr, PAGE_READONLY, 0, 0, nullptr);
+
         CloseHandle(file);
-        if(map==NULL) {
+        if (map == nullptr) {
+            // If we failed to create the mapping due to an out-of-memory error, then 
+            // we want to report that error back to the caller.
+            if (HRESULT_FROM_WIN32(GetLastError()) == E_OUTOFMEMORY) {
+                *status = U_MEMORY_ALLOCATION_ERROR;
+            }
             return FALSE;
         }
 
         /* map a view of the file into our address space */
-        pData->pHeader=(const DataHeader *)MapViewOfFile(map, FILE_MAP_READ, 0, 0, 0);
-        if(pData->pHeader==NULL) {
+        pData->pHeader = reinterpret_cast<const DataHeader *>(MapViewOfFile(map, FILE_MAP_READ, 0, 0, 0));
+        if (pData->pHeader == nullptr) {
             CloseHandle(map);
             return FALSE;
         }
-        pData->map=map;
+        pData->map = map;
         return TRUE;
     }
 
     U_CFUNC void
     uprv_unmapFile(UDataMemory *pData) {
-        if(pData!=NULL && pData->map!=NULL) {
+        if (pData != nullptr && pData->map != nullptr) {
             UnmapViewOfFile(pData->pHeader);
             CloseHandle(pData->map);
-            pData->pHeader=NULL;
-            pData->map=NULL;
+            pData->pHeader = nullptr;
+            pData->map = nullptr;
         }
     }
 
@@ -165,12 +218,16 @@
 
 #elif MAP_IMPLEMENTATION==MAP_POSIX
     U_CFUNC UBool
-    uprv_mapFile(UDataMemory *pData, const char *path) {
+    uprv_mapFile(UDataMemory *pData, const char *path, UErrorCode *status) {
         int fd;
         int length;
         struct stat mystat;
         void *data;
 
+        if (U_FAILURE(*status)) {
+            return FALSE;
+        }
+
         UDataMemory_init(pData); /* Clear the output struct.        */
 
         /* determine the length of the file */
@@ -193,6 +250,7 @@
 #endif
         close(fd); /* no longer needed */
         if(data==MAP_FAILED) {
+            // Possibly check the errno value for ENOMEM, and report U_MEMORY_ALLOCATION_ERROR?
             return FALSE;
         }
 
@@ -207,13 +265,13 @@
 
     U_CFUNC void
     uprv_unmapFile(UDataMemory *pData) {
-        if(pData!=NULL && pData->map!=NULL) {
+        if(pData!=nullptr && pData->map!=nullptr) {
             size_t dataLen = (char *)pData->map - (char *)pData->mapAddr;
             if(munmap(pData->mapAddr, dataLen)==-1) {
             }
-            pData->pHeader=NULL;
+            pData->pHeader=nullptr;
             pData->map=0;
-            pData->mapAddr=NULL;
+            pData->mapAddr=nullptr;
         }
     }
 
@@ -235,15 +293,19 @@
     }
 
     U_CFUNC UBool
-    uprv_mapFile(UDataMemory *pData, const char *path) {
+    uprv_mapFile(UDataMemory *pData, const char *path, UErrorCode *status) {
         FILE *file;
         int32_t fileLength;
         void *p;
 
+        if (U_FAILURE(*status)) {
+            return FALSE;
+        }
+
         UDataMemory_init(pData); /* Clear the output struct.        */
         /* open the input file */
         file=fopen(path, "rb");
-        if(file==NULL) {
+        if(file==nullptr) {
             return FALSE;
         }
 
@@ -256,8 +318,9 @@
 
         /* allocate the memory to hold the file data */
         p=uprv_malloc(fileLength);
-        if(p==NULL) {
+        if(p==nullptr) {
             fclose(file);
+            *status = U_MEMORY_ALLOCATION_ERROR;
             return FALSE;
         }
 
@@ -277,18 +340,17 @@
 
     U_CFUNC void
     uprv_unmapFile(UDataMemory *pData) {
-        if(pData!=NULL && pData->map!=NULL) {
+        if(pData!=nullptr && pData->map!=nullptr) {
             uprv_free(pData->map);
-            pData->map     = NULL;
-            pData->mapAddr = NULL;
-            pData->pHeader = NULL;
+            pData->map     = nullptr;
+            pData->mapAddr = nullptr;
+            pData->pHeader = nullptr;
         }
     }
 
-
 #elif MAP_IMPLEMENTATION==MAP_STARBOARD
     U_CFUNC UBool
-    uprv_mapFile(UDataMemory *pData, const char *path) {
+    uprv_mapFile(UDataMemory *pData, const char *path, UErrorCode *status) {
         UDataMemory_init(pData); /* Clear the output struct.        */
 
         /* open the input file */
@@ -318,7 +380,7 @@
         }
 
         /* read the file */
-        if (fileLength != SbFileReadAll(file, p, fileLength)) {
+        if (fileLength != SbFileReadAll(file, static_cast<char *>(p), fileLength)) {
             uprv_free(p);
             SbFileClose(file);
             return FALSE;
@@ -378,7 +440,7 @@
      *
      *                    TODO:  This works the way ICU historically has, but the
      *                           whole data fallback search path is so complicated that
-     *                           proabably almost no one will ever really understand it,
+     *                           probably almost no one will ever really understand it,
      *                           the potential for confusion is large.  (It's not just 
      *                           this one function, but the whole scheme.)
      *                            
@@ -399,7 +461,7 @@
             * Copy the ICU_DATA path to the path buffer and return that*/
             const char *icuDataDir;
             icuDataDir=u_getDataDirectory();
-            if(icuDataDir!=NULL && *icuDataDir!=0) {
+            if(icuDataDir!=nullptr && *icuDataDir!=0) {
                 return strcpy_returnEnd(pathBuffer, icuDataDir);
             } else {
                 /* there is no icuDataDir either.  Just return the empty pathBuffer. */
@@ -418,7 +480,7 @@
 
 #   define DATA_TYPE "dat"
 
-    U_CFUNC UBool uprv_mapFile(UDataMemory *pData, const char *path) {
+    U_CFUNC UBool uprv_mapFile(UDataMemory *pData, const char *path, UErrorCode *status) {
         const char *inBasename;
         char *basename;
         char pathBuffer[1024];
@@ -426,8 +488,12 @@
         dllhandle *handle;
         void *val=0;
 
+        if (U_FAILURE(*status)) {
+            return FALSE;
+        }
+
         inBasename=uprv_strrchr(path, U_FILE_SEP_CHAR);
-        if(inBasename==NULL) {
+        if(inBasename==nullptr) {
             inBasename = path;
         } else {
             inBasename++;
@@ -457,6 +523,7 @@
             data=mmap(0, length, PROT_READ, MAP_PRIVATE, fd, 0);
             close(fd); /* no longer needed */
             if(data==MAP_FAILED) {
+                // Possibly check the errorno value for ENOMEM, and report U_MEMORY_ALLOCATION_ERROR?
                 return FALSE;
             }
             pData->map = (char *)data + length;
@@ -491,7 +558,7 @@
                fprintf(stderr, " -> %08X\n", handle );
 #       endif
 
-        if(handle != NULL) {
+        if(handle != nullptr) {
                /* we have a data DLL - what kind of lookup do we need here? */
                /* try to find the Table of Contents */
                UDataMemory_init(pData); /* Clear the output struct.        */
@@ -512,11 +579,11 @@
     }
 
     U_CFUNC void uprv_unmapFile(UDataMemory *pData) {
-        if(pData!=NULL && pData->map!=NULL) {
+        if(pData!=nullptr && pData->map!=nullptr) {
             uprv_free(pData->map);
-            pData->map     = NULL;
-            pData->mapAddr = NULL;
-            pData->pHeader = NULL;
+            pData->map     = nullptr;
+            pData->mapAddr = nullptr;
+            pData->pHeader = nullptr;
         }   
     }
 
diff --git a/src/third_party/icu/source/common/umapfile.h b/src/third_party/icu/source/common/umapfile.h
index 8aeba17..c7cf2af 100644
--- a/src/third_party/icu/source/common/umapfile.h
+++ b/src/third_party/icu/source/common/umapfile.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
@@ -27,7 +29,7 @@
 #include "unicode/udata.h"
 #include "putilimp.h"
 
-U_CFUNC UBool uprv_mapFile(UDataMemory *pdm, const char *path);
+U_CFUNC UBool uprv_mapFile(UDataMemory *pdm, const char *path, UErrorCode *status);
 U_CFUNC void  uprv_unmapFile(UDataMemory *pData);
 
 /* MAP_NONE: no memory mapping, no file access at all */
diff --git a/src/third_party/icu/source/common/umath.c b/src/third_party/icu/source/common/umath.cpp
similarity index 82%
rename from src/third_party/icu/source/common/umath.c
rename to src/third_party/icu/source/common/umath.cpp
index 4a57114..7cf4b31 100644
--- a/src/third_party/icu/source/common/umath.c
+++ b/src/third_party/icu/source/common/umath.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
diff --git a/src/third_party/icu/source/common/umutablecptrie.cpp b/src/third_party/icu/source/common/umutablecptrie.cpp
new file mode 100644
index 0000000..cdbe270
--- /dev/null
+++ b/src/third_party/icu/source/common/umutablecptrie.cpp
@@ -0,0 +1,1852 @@
+// © 2017 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+// umutablecptrie.cpp (inspired by utrie2_builder.cpp)
+// created: 2017dec29 Markus W. Scherer
+
+// #define UCPTRIE_DEBUG
+#ifdef UCPTRIE_DEBUG
+#   include <stdio.h>
+#endif
+
+#include "unicode/utypes.h"
+#include "unicode/ucptrie.h"
+#include "unicode/umutablecptrie.h"
+#include "unicode/uobject.h"
+#include "unicode/utf16.h"
+#include "cmemory.h"
+#include "uassert.h"
+#include "ucptrie_impl.h"
+
+// ICU-20235 In case Microsoft math.h has defined this, undefine it.
+#ifdef OVERFLOW
+#undef OVERFLOW
+#endif
+
+U_NAMESPACE_BEGIN
+
+namespace {
+
+constexpr int32_t MAX_UNICODE = 0x10ffff;
+
+constexpr int32_t UNICODE_LIMIT = 0x110000;
+constexpr int32_t BMP_LIMIT = 0x10000;
+constexpr int32_t ASCII_LIMIT = 0x80;
+
+constexpr int32_t I_LIMIT = UNICODE_LIMIT >> UCPTRIE_SHIFT_3;
+constexpr int32_t BMP_I_LIMIT = BMP_LIMIT >> UCPTRIE_SHIFT_3;
+constexpr int32_t ASCII_I_LIMIT = ASCII_LIMIT >> UCPTRIE_SHIFT_3;
+
+constexpr int32_t SMALL_DATA_BLOCKS_PER_BMP_BLOCK = (1 << (UCPTRIE_FAST_SHIFT - UCPTRIE_SHIFT_3));
+
+// Flag values for data blocks.
+constexpr uint8_t ALL_SAME = 0;
+constexpr uint8_t MIXED = 1;
+constexpr uint8_t SAME_AS = 2;
+
+/** Start with allocation of 16k data entries. */
+constexpr int32_t INITIAL_DATA_LENGTH = ((int32_t)1 << 14);
+
+/** Grow about 8x each time. */
+constexpr int32_t MEDIUM_DATA_LENGTH = ((int32_t)1 << 17);
+
+/**
+ * Maximum length of the build-time data array.
+ * One entry per 0x110000 code points.
+ */
+constexpr int32_t MAX_DATA_LENGTH = UNICODE_LIMIT;
+
+// Flag values for index-3 blocks while compacting/building.
+constexpr uint8_t I3_NULL = 0;
+constexpr uint8_t I3_BMP = 1;
+constexpr uint8_t I3_16 = 2;
+constexpr uint8_t I3_18 = 3;
+
+constexpr int32_t INDEX_3_18BIT_BLOCK_LENGTH = UCPTRIE_INDEX_3_BLOCK_LENGTH + UCPTRIE_INDEX_3_BLOCK_LENGTH / 8;
+
+class AllSameBlocks;
+class MixedBlocks;
+
+class MutableCodePointTrie : public UMemory {
+public:
+    MutableCodePointTrie(uint32_t initialValue, uint32_t errorValue, UErrorCode &errorCode);
+    MutableCodePointTrie(const MutableCodePointTrie &other, UErrorCode &errorCode);
+    MutableCodePointTrie(const MutableCodePointTrie &other) = delete;
+    ~MutableCodePointTrie();
+
+    MutableCodePointTrie &operator=(const MutableCodePointTrie &other) = delete;
+
+    static MutableCodePointTrie *fromUCPMap(const UCPMap *map, UErrorCode &errorCode);
+    static MutableCodePointTrie *fromUCPTrie(const UCPTrie *trie, UErrorCode &errorCode);
+
+    uint32_t get(UChar32 c) const;
+    int32_t getRange(UChar32 start, UCPMapValueFilter *filter, const void *context,
+                     uint32_t *pValue) const;
+
+    void set(UChar32 c, uint32_t value, UErrorCode &errorCode);
+    void setRange(UChar32 start, UChar32 end, uint32_t value, UErrorCode &errorCode);
+
+    UCPTrie *build(UCPTrieType type, UCPTrieValueWidth valueWidth, UErrorCode &errorCode);
+
+private:
+    void clear();
+
+    bool ensureHighStart(UChar32 c);
+    int32_t allocDataBlock(int32_t blockLength);
+    int32_t getDataBlock(int32_t i);
+
+    void maskValues(uint32_t mask);
+    UChar32 findHighStart() const;
+    int32_t compactWholeDataBlocks(int32_t fastILimit, AllSameBlocks &allSameBlocks);
+    int32_t compactData(
+            int32_t fastILimit, uint32_t *newData, int32_t newDataCapacity,
+            int32_t dataNullIndex, MixedBlocks &mixedBlocks, UErrorCode &errorCode);
+    int32_t compactIndex(int32_t fastILimit, MixedBlocks &mixedBlocks, UErrorCode &errorCode);
+    int32_t compactTrie(int32_t fastILimit, UErrorCode &errorCode);
+
+    uint32_t *index = nullptr;
+    int32_t indexCapacity = 0;
+    int32_t index3NullOffset = -1;
+    uint32_t *data = nullptr;
+    int32_t dataCapacity = 0;
+    int32_t dataLength = 0;
+    int32_t dataNullOffset = -1;
+
+    uint32_t origInitialValue;
+    uint32_t initialValue;
+    uint32_t errorValue;
+    UChar32 highStart;
+    uint32_t highValue;
+#ifdef UCPTRIE_DEBUG
+public:
+    const char *name;
+#endif
+private:
+    /** Temporary array while building the final data. */
+    uint16_t *index16 = nullptr;
+    uint8_t flags[UNICODE_LIMIT >> UCPTRIE_SHIFT_3];
+};
+
+MutableCodePointTrie::MutableCodePointTrie(uint32_t iniValue, uint32_t errValue, UErrorCode &errorCode) :
+        origInitialValue(iniValue), initialValue(iniValue), errorValue(errValue),
+        highStart(0), highValue(initialValue)
+#ifdef UCPTRIE_DEBUG
+        , name("open")
+#endif
+        {
+    if (U_FAILURE(errorCode)) { return; }
+    index = (uint32_t *)uprv_malloc(BMP_I_LIMIT * 4);
+    data = (uint32_t *)uprv_malloc(INITIAL_DATA_LENGTH * 4);
+    if (index == nullptr || data == nullptr) {
+        errorCode = U_MEMORY_ALLOCATION_ERROR;
+        return;
+    }
+    indexCapacity = BMP_I_LIMIT;
+    dataCapacity = INITIAL_DATA_LENGTH;
+}
+
+MutableCodePointTrie::MutableCodePointTrie(const MutableCodePointTrie &other, UErrorCode &errorCode) :
+        index3NullOffset(other.index3NullOffset),
+        dataNullOffset(other.dataNullOffset),
+        origInitialValue(other.origInitialValue), initialValue(other.initialValue),
+        errorValue(other.errorValue),
+        highStart(other.highStart), highValue(other.highValue)
+#ifdef UCPTRIE_DEBUG
+        , name("mutable clone")
+#endif
+        {
+    if (U_FAILURE(errorCode)) { return; }
+    int32_t iCapacity = highStart <= BMP_LIMIT ? BMP_I_LIMIT : I_LIMIT;
+    index = (uint32_t *)uprv_malloc(iCapacity * 4);
+    data = (uint32_t *)uprv_malloc(other.dataCapacity * 4);
+    if (index == nullptr || data == nullptr) {
+        errorCode = U_MEMORY_ALLOCATION_ERROR;
+        return;
+    }
+    indexCapacity = iCapacity;
+    dataCapacity = other.dataCapacity;
+
+    int32_t iLimit = highStart >> UCPTRIE_SHIFT_3;
+    uprv_memcpy(flags, other.flags, iLimit);
+    uprv_memcpy(index, other.index, iLimit * 4);
+    uprv_memcpy(data, other.data, (size_t)other.dataLength * 4);
+    dataLength = other.dataLength;
+    U_ASSERT(other.index16 == nullptr);
+}
+
+MutableCodePointTrie::~MutableCodePointTrie() {
+    uprv_free(index);
+    uprv_free(data);
+    uprv_free(index16);
+}
+
+MutableCodePointTrie *MutableCodePointTrie::fromUCPMap(const UCPMap *map, UErrorCode &errorCode) {
+    // Use the highValue as the initialValue to reduce the highStart.
+    uint32_t errorValue = ucpmap_get(map, -1);
+    uint32_t initialValue = ucpmap_get(map, 0x10ffff);
+    LocalPointer<MutableCodePointTrie> mutableTrie(
+        new MutableCodePointTrie(initialValue, errorValue, errorCode),
+        errorCode);
+    if (U_FAILURE(errorCode)) {
+        return nullptr;
+    }
+    UChar32 start = 0, end;
+    uint32_t value;
+    while ((end = ucpmap_getRange(map, start, UCPMAP_RANGE_NORMAL, 0,
+                                  nullptr, nullptr, &value)) >= 0) {
+        if (value != initialValue) {
+            if (start == end) {
+                mutableTrie->set(start, value, errorCode);
+            } else {
+                mutableTrie->setRange(start, end, value, errorCode);
+            }
+        }
+        start = end + 1;
+    }
+    if (U_SUCCESS(errorCode)) {
+        return mutableTrie.orphan();
+    } else {
+        return nullptr;
+    }
+}
+
+MutableCodePointTrie *MutableCodePointTrie::fromUCPTrie(const UCPTrie *trie, UErrorCode &errorCode) {
+    // Use the highValue as the initialValue to reduce the highStart.
+    uint32_t errorValue;
+    uint32_t initialValue;
+    switch (trie->valueWidth) {
+    case UCPTRIE_VALUE_BITS_16:
+        errorValue = trie->data.ptr16[trie->dataLength - UCPTRIE_ERROR_VALUE_NEG_DATA_OFFSET];
+        initialValue = trie->data.ptr16[trie->dataLength - UCPTRIE_HIGH_VALUE_NEG_DATA_OFFSET];
+        break;
+    case UCPTRIE_VALUE_BITS_32:
+        errorValue = trie->data.ptr32[trie->dataLength - UCPTRIE_ERROR_VALUE_NEG_DATA_OFFSET];
+        initialValue = trie->data.ptr32[trie->dataLength - UCPTRIE_HIGH_VALUE_NEG_DATA_OFFSET];
+        break;
+    case UCPTRIE_VALUE_BITS_8:
+        errorValue = trie->data.ptr8[trie->dataLength - UCPTRIE_ERROR_VALUE_NEG_DATA_OFFSET];
+        initialValue = trie->data.ptr8[trie->dataLength - UCPTRIE_HIGH_VALUE_NEG_DATA_OFFSET];
+        break;
+    default:
+        // Unreachable if the trie is properly initialized.
+        errorCode = U_ILLEGAL_ARGUMENT_ERROR;
+        return nullptr;
+    }
+    LocalPointer<MutableCodePointTrie> mutableTrie(
+        new MutableCodePointTrie(initialValue, errorValue, errorCode),
+        errorCode);
+    if (U_FAILURE(errorCode)) {
+        return nullptr;
+    }
+    UChar32 start = 0, end;
+    uint32_t value;
+    while ((end = ucptrie_getRange(trie, start, UCPMAP_RANGE_NORMAL, 0,
+                                   nullptr, nullptr, &value)) >= 0) {
+        if (value != initialValue) {
+            if (start == end) {
+                mutableTrie->set(start, value, errorCode);
+            } else {
+                mutableTrie->setRange(start, end, value, errorCode);
+            }
+        }
+        start = end + 1;
+    }
+    if (U_SUCCESS(errorCode)) {
+        return mutableTrie.orphan();
+    } else {
+        return nullptr;
+    }
+}
+
+void MutableCodePointTrie::clear() {
+    index3NullOffset = dataNullOffset = -1;
+    dataLength = 0;
+    highValue = initialValue = origInitialValue;
+    highStart = 0;
+    uprv_free(index16);
+    index16 = nullptr;
+}
+
+uint32_t MutableCodePointTrie::get(UChar32 c) const {
+    if ((uint32_t)c > MAX_UNICODE) {
+        return errorValue;
+    }
+    if (c >= highStart) {
+        return highValue;
+    }
+    int32_t i = c >> UCPTRIE_SHIFT_3;
+    if (flags[i] == ALL_SAME) {
+        return index[i];
+    } else {
+        return data[index[i] + (c & UCPTRIE_SMALL_DATA_MASK)];
+    }
+}
+
+inline uint32_t maybeFilterValue(uint32_t value, uint32_t initialValue, uint32_t nullValue,
+                                 UCPMapValueFilter *filter, const void *context) {
+    if (value == initialValue) {
+        value = nullValue;
+    } else if (filter != nullptr) {
+        value = filter(context, value);
+    }
+    return value;
+}
+
+UChar32 MutableCodePointTrie::getRange(
+        UChar32 start, UCPMapValueFilter *filter, const void *context,
+        uint32_t *pValue) const {
+    if ((uint32_t)start > MAX_UNICODE) {
+        return U_SENTINEL;
+    }
+    if (start >= highStart) {
+        if (pValue != nullptr) {
+            uint32_t value = highValue;
+            if (filter != nullptr) { value = filter(context, value); }
+            *pValue = value;
+        }
+        return MAX_UNICODE;
+    }
+    uint32_t nullValue = initialValue;
+    if (filter != nullptr) { nullValue = filter(context, nullValue); }
+    UChar32 c = start;
+    uint32_t trieValue, value;
+    bool haveValue = false;
+    int32_t i = c >> UCPTRIE_SHIFT_3;
+    do {
+        if (flags[i] == ALL_SAME) {
+            uint32_t trieValue2 = index[i];
+            if (haveValue) {
+                if (trieValue2 != trieValue) {
+                    if (filter == nullptr ||
+                            maybeFilterValue(trieValue2, initialValue, nullValue,
+                                             filter, context) != value) {
+                        return c - 1;
+                    }
+                    trieValue = trieValue2;  // may or may not help
+                }
+            } else {
+                trieValue = trieValue2;
+                value = maybeFilterValue(trieValue2, initialValue, nullValue, filter, context);
+                if (pValue != nullptr) { *pValue = value; }
+                haveValue = true;
+            }
+            c = (c + UCPTRIE_SMALL_DATA_BLOCK_LENGTH) & ~UCPTRIE_SMALL_DATA_MASK;
+        } else /* MIXED */ {
+            int32_t di = index[i] + (c & UCPTRIE_SMALL_DATA_MASK);
+            uint32_t trieValue2 = data[di];
+            if (haveValue) {
+                if (trieValue2 != trieValue) {
+                    if (filter == nullptr ||
+                            maybeFilterValue(trieValue2, initialValue, nullValue,
+                                             filter, context) != value) {
+                        return c - 1;
+                    }
+                    trieValue = trieValue2;  // may or may not help
+                }
+            } else {
+                trieValue = trieValue2;
+                value = maybeFilterValue(trieValue2, initialValue, nullValue, filter, context);
+                if (pValue != nullptr) { *pValue = value; }
+                haveValue = true;
+            }
+            while ((++c & UCPTRIE_SMALL_DATA_MASK) != 0) {
+                trieValue2 = data[++di];
+                if (trieValue2 != trieValue) {
+                    if (filter == nullptr ||
+                            maybeFilterValue(trieValue2, initialValue, nullValue,
+                                             filter, context) != value) {
+                        return c - 1;
+                    }
+                }
+                trieValue = trieValue2;  // may or may not help
+            }
+        }
+        ++i;
+    } while (c < highStart);
+    U_ASSERT(haveValue);
+    if (maybeFilterValue(highValue, initialValue, nullValue,
+                         filter, context) != value) {
+        return c - 1;
+    } else {
+        return MAX_UNICODE;
+    }
+}
+
+void
+writeBlock(uint32_t *block, uint32_t value) {
+    uint32_t *limit = block + UCPTRIE_SMALL_DATA_BLOCK_LENGTH;
+    while (block < limit) {
+        *block++ = value;
+    }
+}
+
+bool MutableCodePointTrie::ensureHighStart(UChar32 c) {
+    if (c >= highStart) {
+        // Round up to a UCPTRIE_CP_PER_INDEX_2_ENTRY boundary to simplify compaction.
+        c = (c + UCPTRIE_CP_PER_INDEX_2_ENTRY) & ~(UCPTRIE_CP_PER_INDEX_2_ENTRY - 1);
+        int32_t i = highStart >> UCPTRIE_SHIFT_3;
+        int32_t iLimit = c >> UCPTRIE_SHIFT_3;
+        if (iLimit > indexCapacity) {
+            uint32_t *newIndex = (uint32_t *)uprv_malloc(I_LIMIT * 4);
+            if (newIndex == nullptr) { return false; }
+            uprv_memcpy(newIndex, index, i * 4);
+            uprv_free(index);
+            index = newIndex;
+            indexCapacity = I_LIMIT;
+        }
+        do {
+            flags[i] = ALL_SAME;
+            index[i] = initialValue;
+        } while(++i < iLimit);
+        highStart = c;
+    }
+    return true;
+}
+
+int32_t MutableCodePointTrie::allocDataBlock(int32_t blockLength) {
+    int32_t newBlock = dataLength;
+    int32_t newTop = newBlock + blockLength;
+    if (newTop > dataCapacity) {
+        int32_t capacity;
+        if (dataCapacity < MEDIUM_DATA_LENGTH) {
+            capacity = MEDIUM_DATA_LENGTH;
+        } else if (dataCapacity < MAX_DATA_LENGTH) {
+            capacity = MAX_DATA_LENGTH;
+        } else {
+            // Should never occur.
+            // Either MAX_DATA_LENGTH is incorrect,
+            // or the code writes more values than should be possible.
+            return -1;
+        }
+        uint32_t *newData = (uint32_t *)uprv_malloc(capacity * 4);
+        if (newData == nullptr) {
+            return -1;
+        }
+        uprv_memcpy(newData, data, (size_t)dataLength * 4);
+        uprv_free(data);
+        data = newData;
+        dataCapacity = capacity;
+    }
+    dataLength = newTop;
+    return newBlock;
+}
+
+/**
+ * No error checking for illegal arguments.
+ *
+ * @return -1 if no new data block available (out of memory in data array)
+ * @internal
+ */
+int32_t MutableCodePointTrie::getDataBlock(int32_t i) {
+    if (flags[i] == MIXED) {
+        return index[i];
+    }
+    if (i < BMP_I_LIMIT) {
+        int32_t newBlock = allocDataBlock(UCPTRIE_FAST_DATA_BLOCK_LENGTH);
+        if (newBlock < 0) { return newBlock; }
+        int32_t iStart = i & ~(SMALL_DATA_BLOCKS_PER_BMP_BLOCK -1);
+        int32_t iLimit = iStart + SMALL_DATA_BLOCKS_PER_BMP_BLOCK;
+        do {
+            U_ASSERT(flags[iStart] == ALL_SAME);
+            writeBlock(data + newBlock, index[iStart]);
+            flags[iStart] = MIXED;
+            index[iStart++] = newBlock;
+            newBlock += UCPTRIE_SMALL_DATA_BLOCK_LENGTH;
+        } while (iStart < iLimit);
+        return index[i];
+    } else {
+        int32_t newBlock = allocDataBlock(UCPTRIE_SMALL_DATA_BLOCK_LENGTH);
+        if (newBlock < 0) { return newBlock; }
+        writeBlock(data + newBlock, index[i]);
+        flags[i] = MIXED;
+        index[i] = newBlock;
+        return newBlock;
+    }
+}
+
+void MutableCodePointTrie::set(UChar32 c, uint32_t value, UErrorCode &errorCode) {
+    if (U_FAILURE(errorCode)) {
+        return;
+    }
+    if ((uint32_t)c > MAX_UNICODE) {
+        errorCode = U_ILLEGAL_ARGUMENT_ERROR;
+        return;
+    }
+
+    int32_t block;
+    if (!ensureHighStart(c) || (block = getDataBlock(c >> UCPTRIE_SHIFT_3)) < 0) {
+        errorCode = U_MEMORY_ALLOCATION_ERROR;
+        return;
+    }
+
+    data[block + (c & UCPTRIE_SMALL_DATA_MASK)] = value;
+}
+
+void
+fillBlock(uint32_t *block, UChar32 start, UChar32 limit, uint32_t value) {
+    uint32_t *pLimit = block + limit;
+    block += start;
+    while (block < pLimit) {
+        *block++ = value;
+    }
+}
+
+void MutableCodePointTrie::setRange(UChar32 start, UChar32 end, uint32_t value, UErrorCode &errorCode) {
+    if (U_FAILURE(errorCode)) {
+        return;
+    }
+    if ((uint32_t)start > MAX_UNICODE || (uint32_t)end > MAX_UNICODE || start > end) {
+        errorCode = U_ILLEGAL_ARGUMENT_ERROR;
+        return;
+    }
+    if (!ensureHighStart(end)) {
+        errorCode = U_MEMORY_ALLOCATION_ERROR;
+        return;
+    }
+
+    UChar32 limit = end + 1;
+    if (start & UCPTRIE_SMALL_DATA_MASK) {
+        // Set partial block at [start..following block boundary[.
+        int32_t block = getDataBlock(start >> UCPTRIE_SHIFT_3);
+        if (block < 0) {
+            errorCode = U_MEMORY_ALLOCATION_ERROR;
+            return;
+        }
+
+        UChar32 nextStart = (start + UCPTRIE_SMALL_DATA_MASK) & ~UCPTRIE_SMALL_DATA_MASK;
+        if (nextStart <= limit) {
+            fillBlock(data + block, start & UCPTRIE_SMALL_DATA_MASK, UCPTRIE_SMALL_DATA_BLOCK_LENGTH,
+                      value);
+            start = nextStart;
+        } else {
+            fillBlock(data + block, start & UCPTRIE_SMALL_DATA_MASK, limit & UCPTRIE_SMALL_DATA_MASK,
+                      value);
+            return;
+        }
+    }
+
+    // Number of positions in the last, partial block.
+    int32_t rest = limit & UCPTRIE_SMALL_DATA_MASK;
+
+    // Round down limit to a block boundary.
+    limit &= ~UCPTRIE_SMALL_DATA_MASK;
+
+    // Iterate over all-value blocks.
+    while (start < limit) {
+        int32_t i = start >> UCPTRIE_SHIFT_3;
+        if (flags[i] == ALL_SAME) {
+            index[i] = value;
+        } else /* MIXED */ {
+            fillBlock(data + index[i], 0, UCPTRIE_SMALL_DATA_BLOCK_LENGTH, value);
+        }
+        start += UCPTRIE_SMALL_DATA_BLOCK_LENGTH;
+    }
+
+    if (rest > 0) {
+        // Set partial block at [last block boundary..limit[.
+        int32_t block = getDataBlock(start >> UCPTRIE_SHIFT_3);
+        if (block < 0) {
+            errorCode = U_MEMORY_ALLOCATION_ERROR;
+            return;
+        }
+
+        fillBlock(data + block, 0, rest, value);
+    }
+}
+
+/* compaction --------------------------------------------------------------- */
+
+void MutableCodePointTrie::maskValues(uint32_t mask) {
+    initialValue &= mask;
+    errorValue &= mask;
+    highValue &= mask;
+    int32_t iLimit = highStart >> UCPTRIE_SHIFT_3;
+    for (int32_t i = 0; i < iLimit; ++i) {
+        if (flags[i] == ALL_SAME) {
+            index[i] &= mask;
+        }
+    }
+    for (int32_t i = 0; i < dataLength; ++i) {
+        data[i] &= mask;
+    }
+}
+
+template<typename UIntA, typename UIntB>
+bool equalBlocks(const UIntA *s, const UIntB *t, int32_t length) {
+    while (length > 0 && *s == *t) {
+        ++s;
+        ++t;
+        --length;
+    }
+    return length == 0;
+}
+
+bool allValuesSameAs(const uint32_t *p, int32_t length, uint32_t value) {
+    const uint32_t *pLimit = p + length;
+    while (p < pLimit && *p == value) { ++p; }
+    return p == pLimit;
+}
+
+/** Search for an identical block. */
+int32_t findSameBlock(const uint16_t *p, int32_t pStart, int32_t length,
+                      const uint16_t *q, int32_t qStart, int32_t blockLength) {
+    // Ensure that we do not even partially get past length.
+    length -= blockLength;
+
+    q += qStart;
+    while (pStart <= length) {
+        if (equalBlocks(p + pStart, q, blockLength)) {
+            return pStart;
+        }
+        ++pStart;
+    }
+    return -1;
+}
+
+int32_t findAllSameBlock(const uint32_t *p, int32_t start, int32_t limit,
+                         uint32_t value, int32_t blockLength) {
+    // Ensure that we do not even partially get past limit.
+    limit -= blockLength;
+
+    for (int32_t block = start; block <= limit; ++block) {
+        if (p[block] == value) {
+            for (int32_t i = 1;; ++i) {
+                if (i == blockLength) {
+                    return block;
+                }
+                if (p[block + i] != value) {
+                    block += i;
+                    break;
+                }
+            }
+        }
+    }
+    return -1;
+}
+
+/**
+ * Look for maximum overlap of the beginning of the other block
+ * with the previous, adjacent block.
+ */
+template<typename UIntA, typename UIntB>
+int32_t getOverlap(const UIntA *p, int32_t length,
+                   const UIntB *q, int32_t qStart, int32_t blockLength) {
+    int32_t overlap = blockLength - 1;
+    U_ASSERT(overlap <= length);
+    q += qStart;
+    while (overlap > 0 && !equalBlocks(p + (length - overlap), q, overlap)) {
+        --overlap;
+    }
+    return overlap;
+}
+
+int32_t getAllSameOverlap(const uint32_t *p, int32_t length, uint32_t value,
+                          int32_t blockLength) {
+    int32_t min = length - (blockLength - 1);
+    int32_t i = length;
+    while (min < i && p[i - 1] == value) { --i; }
+    return length - i;
+}
+
+bool isStartOfSomeFastBlock(uint32_t dataOffset, const uint32_t index[], int32_t fastILimit) {
+    for (int32_t i = 0; i < fastILimit; i += SMALL_DATA_BLOCKS_PER_BMP_BLOCK) {
+        if (index[i] == dataOffset) {
+            return true;
+        }
+    }
+    return false;
+}
+
+/**
+ * Finds the start of the last range in the trie by enumerating backward.
+ * Indexes for code points higher than this will be omitted.
+ */
+UChar32 MutableCodePointTrie::findHighStart() const {
+    int32_t i = highStart >> UCPTRIE_SHIFT_3;
+    while (i > 0) {
+        bool match;
+        if (flags[--i] == ALL_SAME) {
+            match = index[i] == highValue;
+        } else /* MIXED */ {
+            const uint32_t *p = data + index[i];
+            for (int32_t j = 0;; ++j) {
+                if (j == UCPTRIE_SMALL_DATA_BLOCK_LENGTH) {
+                    match = true;
+                    break;
+                }
+                if (p[j] != highValue) {
+                    match = false;
+                    break;
+                }
+            }
+        }
+        if (!match) {
+            return (i + 1) << UCPTRIE_SHIFT_3;
+        }
+    }
+    return 0;
+}
+
+class AllSameBlocks {
+public:
+    static constexpr int32_t NEW_UNIQUE = -1;
+    static constexpr int32_t OVERFLOW = -2;
+
+    AllSameBlocks() : length(0), mostRecent(-1) {}
+
+    int32_t findOrAdd(int32_t index, int32_t count, uint32_t value) {
+        if (mostRecent >= 0 && values[mostRecent] == value) {
+            refCounts[mostRecent] += count;
+            return indexes[mostRecent];
+        }
+        for (int32_t i = 0; i < length; ++i) {
+            if (values[i] == value) {
+                mostRecent = i;
+                refCounts[i] += count;
+                return indexes[i];
+            }
+        }
+        if (length == CAPACITY) {
+            return OVERFLOW;
+        }
+        mostRecent = length;
+        indexes[length] = index;
+        values[length] = value;
+        refCounts[length++] = count;
+        return NEW_UNIQUE;
+    }
+
+    /** Replaces the block which has the lowest reference count. */
+    void add(int32_t index, int32_t count, uint32_t value) {
+        U_ASSERT(length == CAPACITY);
+        int32_t least = -1;
+        int32_t leastCount = I_LIMIT;
+        for (int32_t i = 0; i < length; ++i) {
+            U_ASSERT(values[i] != value);
+            if (refCounts[i] < leastCount) {
+                least = i;
+                leastCount = refCounts[i];
+            }
+        }
+        U_ASSERT(least >= 0);
+        mostRecent = least;
+        indexes[least] = index;
+        values[least] = value;
+        refCounts[least] = count;
+    }
+
+    int32_t findMostUsed() const {
+        if (length == 0) { return -1; }
+        int32_t max = -1;
+        int32_t maxCount = 0;
+        for (int32_t i = 0; i < length; ++i) {
+            if (refCounts[i] > maxCount) {
+                max = i;
+                maxCount = refCounts[i];
+            }
+        }
+        return indexes[max];
+    }
+
+private:
+    static constexpr int32_t CAPACITY = 32;
+
+    int32_t length;
+    int32_t mostRecent;
+
+    int32_t indexes[CAPACITY];
+    uint32_t values[CAPACITY];
+    int32_t refCounts[CAPACITY];
+};
+
+// Custom hash table for mixed-value blocks to be found anywhere in the
+// compacted data or index so far.
+class MixedBlocks {
+public:
+    MixedBlocks() {}
+    ~MixedBlocks() {
+        uprv_free(table);
+    }
+
+    bool init(int32_t maxLength, int32_t newBlockLength) {
+        // We store actual data indexes + 1 to reserve 0 for empty entries.
+        int32_t maxDataIndex = maxLength - newBlockLength + 1;
+        int32_t newLength;
+        if (maxDataIndex <= 0xfff) {  // 4k
+            newLength = 6007;
+            shift = 12;
+            mask = 0xfff;
+        } else if (maxDataIndex <= 0x7fff) {  // 32k
+            newLength = 50021;
+            shift = 15;
+            mask = 0x7fff;
+        } else if (maxDataIndex <= 0x1ffff) {  // 128k
+            newLength = 200003;
+            shift = 17;
+            mask = 0x1ffff;
+        } else {
+            // maxDataIndex up to around MAX_DATA_LENGTH, ca. 1.1M
+            newLength = 1500007;
+            shift = 21;
+            mask = 0x1fffff;
+        }
+        if (newLength > capacity) {
+            uprv_free(table);
+            table = (uint32_t *)uprv_malloc(newLength * 4);
+            if (table == nullptr) {
+                return false;
+            }
+            capacity = newLength;
+        }
+        length = newLength;
+        uprv_memset(table, 0, length * 4);
+
+        blockLength = newBlockLength;
+        return true;
+    }
+
+    template<typename UInt>
+    void extend(const UInt *data, int32_t minStart, int32_t prevDataLength, int32_t newDataLength) {
+        int32_t start = prevDataLength - blockLength;
+        if (start >= minStart) {
+            ++start;  // Skip the last block that we added last time.
+        } else {
+            start = minStart;  // Begin with the first full block.
+        }
+        for (int32_t end = newDataLength - blockLength; start <= end; ++start) {
+            uint32_t hashCode = makeHashCode(data, start);
+            addEntry(data, start, hashCode, start);
+        }
+    }
+
+    template<typename UIntA, typename UIntB>
+    int32_t findBlock(const UIntA *data, const UIntB *blockData, int32_t blockStart) const {
+        uint32_t hashCode = makeHashCode(blockData, blockStart);
+        int32_t entryIndex = findEntry(data, blockData, blockStart, hashCode);
+        if (entryIndex >= 0) {
+            return (table[entryIndex] & mask) - 1;
+        } else {
+            return -1;
+        }
+    }
+
+    int32_t findAllSameBlock(const uint32_t *data, uint32_t blockValue) const {
+        uint32_t hashCode = makeHashCode(blockValue);
+        int32_t entryIndex = findEntry(data, blockValue, hashCode);
+        if (entryIndex >= 0) {
+            return (table[entryIndex] & mask) - 1;
+        } else {
+            return -1;
+        }
+    }
+
+private:
+    template<typename UInt>
+    uint32_t makeHashCode(const UInt *blockData, int32_t blockStart) const {
+        int32_t blockLimit = blockStart + blockLength;
+        uint32_t hashCode = blockData[blockStart++];
+        do {
+            hashCode = 37 * hashCode + blockData[blockStart++];
+        } while (blockStart < blockLimit);
+        return hashCode;
+    }
+
+    uint32_t makeHashCode(uint32_t blockValue) const {
+        uint32_t hashCode = blockValue;
+        for (int32_t i = 1; i < blockLength; ++i) {
+            hashCode = 37 * hashCode + blockValue;
+        }
+        return hashCode;
+    }
+
+    template<typename UInt>
+    void addEntry(const UInt *data, int32_t blockStart, uint32_t hashCode, int32_t dataIndex) {
+        U_ASSERT(0 <= dataIndex && dataIndex < (int32_t)mask);
+        int32_t entryIndex = findEntry(data, data, blockStart, hashCode);
+        if (entryIndex < 0) {
+            table[~entryIndex] = (hashCode << shift) | (dataIndex + 1);
+        }
+    }
+
+    template<typename UIntA, typename UIntB>
+    int32_t findEntry(const UIntA *data, const UIntB *blockData, int32_t blockStart,
+                      uint32_t hashCode) const {
+        uint32_t shiftedHashCode = hashCode << shift;
+        int32_t initialEntryIndex = (hashCode % (length - 1)) + 1;  // 1..length-1
+        for (int32_t entryIndex = initialEntryIndex;;) {
+            uint32_t entry = table[entryIndex];
+            if (entry == 0) {
+                return ~entryIndex;
+            }
+            if ((entry & ~mask) == shiftedHashCode) {
+                int32_t dataIndex = (entry & mask) - 1;
+                if (equalBlocks(data + dataIndex, blockData + blockStart, blockLength)) {
+                    return entryIndex;
+                }
+            }
+            entryIndex = nextIndex(initialEntryIndex, entryIndex);
+        }
+    }
+
+    int32_t findEntry(const uint32_t *data, uint32_t blockValue, uint32_t hashCode) const {
+        uint32_t shiftedHashCode = hashCode << shift;
+        int32_t initialEntryIndex = (hashCode % (length - 1)) + 1;  // 1..length-1
+        for (int32_t entryIndex = initialEntryIndex;;) {
+            uint32_t entry = table[entryIndex];
+            if (entry == 0) {
+                return ~entryIndex;
+            }
+            if ((entry & ~mask) == shiftedHashCode) {
+                int32_t dataIndex = (entry & mask) - 1;
+                if (allValuesSameAs(data + dataIndex, blockLength, blockValue)) {
+                    return entryIndex;
+                }
+            }
+            entryIndex = nextIndex(initialEntryIndex, entryIndex);
+        }
+    }
+
+    inline int32_t nextIndex(int32_t initialEntryIndex, int32_t entryIndex) const {
+        // U_ASSERT(0 < initialEntryIndex && initialEntryIndex < length);
+        return (entryIndex + initialEntryIndex) % length;
+    }
+
+    // Hash table.
+    // The length is a prime number, larger than the maximum data length.
+    // The "shift" lower bits store a data index + 1.
+    // The remaining upper bits store a partial hashCode of the block data values.
+    uint32_t *table = nullptr;
+    int32_t capacity = 0;
+    int32_t length = 0;
+    int32_t shift = 0;
+    uint32_t mask = 0;
+
+    int32_t blockLength = 0;
+};
+
+int32_t MutableCodePointTrie::compactWholeDataBlocks(int32_t fastILimit, AllSameBlocks &allSameBlocks) {
+#ifdef UCPTRIE_DEBUG
+    bool overflow = false;
+#endif
+
+    // ASCII data will be stored as a linear table, even if the following code
+    // does not yet count it that way.
+    int32_t newDataCapacity = ASCII_LIMIT;
+    // Add room for a small data null block in case it would match the start of
+    // a fast data block where dataNullOffset must not be set in that case.
+    newDataCapacity += UCPTRIE_SMALL_DATA_BLOCK_LENGTH;
+    // Add room for special values (errorValue, highValue) and padding.
+    newDataCapacity += 4;
+    int32_t iLimit = highStart >> UCPTRIE_SHIFT_3;
+    int32_t blockLength = UCPTRIE_FAST_DATA_BLOCK_LENGTH;
+    int32_t inc = SMALL_DATA_BLOCKS_PER_BMP_BLOCK;
+    for (int32_t i = 0; i < iLimit; i += inc) {
+        if (i == fastILimit) {
+            blockLength = UCPTRIE_SMALL_DATA_BLOCK_LENGTH;
+            inc = 1;
+        }
+        uint32_t value = index[i];
+        if (flags[i] == MIXED) {
+            // Really mixed?
+            const uint32_t *p = data + value;
+            value = *p;
+            if (allValuesSameAs(p + 1, blockLength - 1, value)) {
+                flags[i] = ALL_SAME;
+                index[i] = value;
+                // Fall through to ALL_SAME handling.
+            } else {
+                newDataCapacity += blockLength;
+                continue;
+            }
+        } else {
+            U_ASSERT(flags[i] == ALL_SAME);
+            if (inc > 1) {
+                // Do all of the fast-range data block's ALL_SAME parts have the same value?
+                bool allSame = true;
+                int32_t next_i = i + inc;
+                for (int32_t j = i + 1; j < next_i; ++j) {
+                    U_ASSERT(flags[j] == ALL_SAME);
+                    if (index[j] != value) {
+                        allSame = false;
+                        break;
+                    }
+                }
+                if (!allSame) {
+                    // Turn it into a MIXED block.
+                    if (getDataBlock(i) < 0) {
+                        return -1;
+                    }
+                    newDataCapacity += blockLength;
+                    continue;
+                }
+            }
+        }
+        // Is there another ALL_SAME block with the same value?
+        int32_t other = allSameBlocks.findOrAdd(i, inc, value);
+        if (other == AllSameBlocks::OVERFLOW) {
+            // The fixed-size array overflowed. Slow check for a duplicate block.
+#ifdef UCPTRIE_DEBUG
+            if (!overflow) {
+                puts("UCPTrie AllSameBlocks overflow");
+                overflow = true;
+            }
+#endif
+            int32_t jInc = SMALL_DATA_BLOCKS_PER_BMP_BLOCK;
+            for (int32_t j = 0;; j += jInc) {
+                if (j == i) {
+                    allSameBlocks.add(i, inc, value);
+                    break;
+                }
+                if (j == fastILimit) {
+                    jInc = 1;
+                }
+                if (flags[j] == ALL_SAME && index[j] == value) {
+                    allSameBlocks.add(j, jInc + inc, value);
+                    other = j;
+                    break;
+                    // We could keep counting blocks with the same value
+                    // before we add the first one, which may improve compaction in rare cases,
+                    // but it would make it slower.
+                }
+            }
+        }
+        if (other >= 0) {
+            flags[i] = SAME_AS;
+            index[i] = other;
+        } else {
+            // New unique same-value block.
+            newDataCapacity += blockLength;
+        }
+    }
+    return newDataCapacity;
+}
+
+#ifdef UCPTRIE_DEBUG
+#   define DEBUG_DO(expr) expr
+#else
+#   define DEBUG_DO(expr)
+#endif
+
+#ifdef UCPTRIE_DEBUG
+// Braille symbols: U+28xx = UTF-8 E2 A0 80..E2 A3 BF
+int32_t appendValue(char s[], int32_t length, uint32_t value) {
+    value ^= value >> 16;
+    value ^= value >> 8;
+    s[length] = 0xE2;
+    s[length + 1] = (char)(0xA0 + ((value >> 6) & 3));
+    s[length + 2] = (char)(0x80 + (value & 0x3F));
+    return length + 3;
+}
+
+void printBlock(const uint32_t *block, int32_t blockLength, uint32_t value,
+                UChar32 start, int32_t overlap, uint32_t initialValue) {
+    char s[UCPTRIE_FAST_DATA_BLOCK_LENGTH * 3 + 3];
+    int32_t length = 0;
+    int32_t i;
+    for (i = 0; i < overlap; ++i) {
+        length = appendValue(s, length, 0);  // Braille blank
+    }
+    s[length++] = '|';
+    for (; i < blockLength; ++i) {
+        if (block != nullptr) {
+            value = block[i];
+        }
+        if (value == initialValue) {
+            value = 0x40;  // Braille lower left dot
+        }
+        length = appendValue(s, length, value);
+    }
+    s[length] = 0;
+    start += overlap;
+    if (start <= 0xffff) {
+        printf("    %04lX  %s|\n", (long)start, s);
+    } else if (start <= 0xfffff) {
+        printf("   %5lX  %s|\n", (long)start, s);
+    } else {
+        printf("  %6lX  %s|\n", (long)start, s);
+    }
+}
+#endif
+
+/**
+ * Compacts a build-time trie.
+ *
+ * The compaction
+ * - removes blocks that are identical with earlier ones
+ * - overlaps each new non-duplicate block as much as possible with the previously-written one
+ * - works with fast-range data blocks whose length is a multiple of that of
+ *   higher-code-point data blocks
+ *
+ * It does not try to find an optimal order of writing, deduplicating, and overlapping blocks.
+ */
+int32_t MutableCodePointTrie::compactData(
+        int32_t fastILimit, uint32_t *newData, int32_t newDataCapacity,
+        int32_t dataNullIndex, MixedBlocks &mixedBlocks, UErrorCode &errorCode) {
+#ifdef UCPTRIE_DEBUG
+    int32_t countSame=0, sumOverlaps=0;
+    bool printData = dataLength == 29088 /* line.brk */ ||
+        // dataLength == 30048 /* CanonIterData */ ||
+        dataLength == 50400 /* zh.txt~stroke */;
+#endif
+
+    // The linear ASCII data has been copied into newData already.
+    int32_t newDataLength = 0;
+    for (int32_t i = 0; newDataLength < ASCII_LIMIT;
+            newDataLength += UCPTRIE_FAST_DATA_BLOCK_LENGTH, i += SMALL_DATA_BLOCKS_PER_BMP_BLOCK) {
+        index[i] = newDataLength;
+#ifdef UCPTRIE_DEBUG
+        if (printData) {
+            printBlock(newData + newDataLength, UCPTRIE_FAST_DATA_BLOCK_LENGTH, 0, newDataLength, 0, initialValue);
+        }
+#endif
+    }
+
+    int32_t blockLength = UCPTRIE_FAST_DATA_BLOCK_LENGTH;
+    if (!mixedBlocks.init(newDataCapacity, blockLength)) {
+        errorCode = U_MEMORY_ALLOCATION_ERROR;
+        return 0;
+    }
+    mixedBlocks.extend(newData, 0, 0, newDataLength);
+
+    int32_t iLimit = highStart >> UCPTRIE_SHIFT_3;
+    int32_t inc = SMALL_DATA_BLOCKS_PER_BMP_BLOCK;
+    int32_t fastLength = 0;
+    for (int32_t i = ASCII_I_LIMIT; i < iLimit; i += inc) {
+        if (i == fastILimit) {
+            blockLength = UCPTRIE_SMALL_DATA_BLOCK_LENGTH;
+            inc = 1;
+            fastLength = newDataLength;
+            if (!mixedBlocks.init(newDataCapacity, blockLength)) {
+                errorCode = U_MEMORY_ALLOCATION_ERROR;
+                return 0;
+            }
+            mixedBlocks.extend(newData, 0, 0, newDataLength);
+        }
+        if (flags[i] == ALL_SAME) {
+            uint32_t value = index[i];
+            // Find an earlier part of the data array of length blockLength
+            // that is filled with this value.
+            int32_t n = mixedBlocks.findAllSameBlock(newData, value);
+            // If we find a match, and the current block is the data null block,
+            // and it is not a fast block but matches the start of a fast block,
+            // then we need to continue looking.
+            // This is because this small block is shorter than the fast block,
+            // and not all of the rest of the fast block is filled with this value.
+            // Otherwise trie.getRange() would detect that the fast block starts at
+            // dataNullOffset and assume incorrectly that it is filled with the null value.
+            while (n >= 0 && i == dataNullIndex && i >= fastILimit && n < fastLength &&
+                    isStartOfSomeFastBlock(n, index, fastILimit)) {
+                n = findAllSameBlock(newData, n + 1, newDataLength, value, blockLength);
+            }
+            if (n >= 0) {
+                DEBUG_DO(++countSame);
+                index[i] = n;
+            } else {
+                n = getAllSameOverlap(newData, newDataLength, value, blockLength);
+                DEBUG_DO(sumOverlaps += n);
+#ifdef UCPTRIE_DEBUG
+                if (printData) {
+                    printBlock(nullptr, blockLength, value, i << UCPTRIE_SHIFT_3, n, initialValue);
+                }
+#endif
+                index[i] = newDataLength - n;
+                int32_t prevDataLength = newDataLength;
+                while (n < blockLength) {
+                    newData[newDataLength++] = value;
+                    ++n;
+                }
+                mixedBlocks.extend(newData, 0, prevDataLength, newDataLength);
+            }
+        } else if (flags[i] == MIXED) {
+            const uint32_t *block = data + index[i];
+            int32_t n = mixedBlocks.findBlock(newData, block, 0);
+            if (n >= 0) {
+                DEBUG_DO(++countSame);
+                index[i] = n;
+            } else {
+                n = getOverlap(newData, newDataLength, block, 0, blockLength);
+                DEBUG_DO(sumOverlaps += n);
+#ifdef UCPTRIE_DEBUG
+                if (printData) {
+                    printBlock(block, blockLength, 0, i << UCPTRIE_SHIFT_3, n, initialValue);
+                }
+#endif
+                index[i] = newDataLength - n;
+                int32_t prevDataLength = newDataLength;
+                while (n < blockLength) {
+                    newData[newDataLength++] = block[n++];
+                }
+                mixedBlocks.extend(newData, 0, prevDataLength, newDataLength);
+            }
+        } else /* SAME_AS */ {
+            uint32_t j = index[i];
+            index[i] = index[j];
+        }
+    }
+
+#ifdef UCPTRIE_DEBUG
+    /* we saved some space */
+    printf("compacting UCPTrie: count of 32-bit data words %lu->%lu  countSame=%ld  sumOverlaps=%ld\n",
+            (long)dataLength, (long)newDataLength, (long)countSame, (long)sumOverlaps);
+#endif
+    return newDataLength;
+}
+
+int32_t MutableCodePointTrie::compactIndex(int32_t fastILimit, MixedBlocks &mixedBlocks,
+                                           UErrorCode &errorCode) {
+    int32_t fastIndexLength = fastILimit >> (UCPTRIE_FAST_SHIFT - UCPTRIE_SHIFT_3);
+    if ((highStart >> UCPTRIE_FAST_SHIFT) <= fastIndexLength) {
+        // Only the linear fast index, no multi-stage index tables.
+        index3NullOffset = UCPTRIE_NO_INDEX3_NULL_OFFSET;
+        return fastIndexLength;
+    }
+
+    // Condense the fast index table.
+    // Also, does it contain an index-3 block with all dataNullOffset?
+    uint16_t fastIndex[UCPTRIE_BMP_INDEX_LENGTH];  // fastIndexLength
+    int32_t i3FirstNull = -1;
+    for (int32_t i = 0, j = 0; i < fastILimit; ++j) {
+        uint32_t i3 = index[i];
+        fastIndex[j] = (uint16_t)i3;
+        if (i3 == (uint32_t)dataNullOffset) {
+            if (i3FirstNull < 0) {
+                i3FirstNull = j;
+            } else if (index3NullOffset < 0 &&
+                    (j - i3FirstNull + 1) == UCPTRIE_INDEX_3_BLOCK_LENGTH) {
+                index3NullOffset = i3FirstNull;
+            }
+        } else {
+            i3FirstNull = -1;
+        }
+        // Set the index entries that compactData() skipped.
+        // Needed when the multi-stage index covers the fast index range as well.
+        int32_t iNext = i + SMALL_DATA_BLOCKS_PER_BMP_BLOCK;
+        while (++i < iNext) {
+            i3 += UCPTRIE_SMALL_DATA_BLOCK_LENGTH;
+            index[i] = i3;
+        }
+    }
+
+    if (!mixedBlocks.init(fastIndexLength, UCPTRIE_INDEX_3_BLOCK_LENGTH)) {
+        errorCode = U_MEMORY_ALLOCATION_ERROR;
+        return 0;
+    }
+    mixedBlocks.extend(fastIndex, 0, 0, fastIndexLength);
+
+    // Examine index-3 blocks. For each determine one of:
+    // - same as the index-3 null block
+    // - same as a fast-index block
+    // - 16-bit indexes
+    // - 18-bit indexes
+    // We store this in the first flags entry for the index-3 block.
+    //
+    // Also determine an upper limit for the index-3 table length.
+    int32_t index3Capacity = 0;
+    i3FirstNull = index3NullOffset;
+    bool hasLongI3Blocks = false;
+    // If the fast index covers the whole BMP, then
+    // the multi-stage index is only for supplementary code points.
+    // Otherwise, the multi-stage index covers all of Unicode.
+    int32_t iStart = fastILimit < BMP_I_LIMIT ? 0 : BMP_I_LIMIT;
+    int32_t iLimit = highStart >> UCPTRIE_SHIFT_3;
+    for (int32_t i = iStart; i < iLimit;) {
+        int32_t j = i;
+        int32_t jLimit = i + UCPTRIE_INDEX_3_BLOCK_LENGTH;
+        uint32_t oredI3 = 0;
+        bool isNull = true;
+        do {
+            uint32_t i3 = index[j];
+            oredI3 |= i3;
+            if (i3 != (uint32_t)dataNullOffset) {
+                isNull = false;
+            }
+        } while (++j < jLimit);
+        if (isNull) {
+            flags[i] = I3_NULL;
+            if (i3FirstNull < 0) {
+                if (oredI3 <= 0xffff) {
+                    index3Capacity += UCPTRIE_INDEX_3_BLOCK_LENGTH;
+                } else {
+                    index3Capacity += INDEX_3_18BIT_BLOCK_LENGTH;
+                    hasLongI3Blocks = true;
+                }
+                i3FirstNull = 0;
+            }
+        } else {
+            if (oredI3 <= 0xffff) {
+                int32_t n = mixedBlocks.findBlock(fastIndex, index, i);
+                if (n >= 0) {
+                    flags[i] = I3_BMP;
+                    index[i] = n;
+                } else {
+                    flags[i] = I3_16;
+                    index3Capacity += UCPTRIE_INDEX_3_BLOCK_LENGTH;
+                }
+            } else {
+                flags[i] = I3_18;
+                index3Capacity += INDEX_3_18BIT_BLOCK_LENGTH;
+                hasLongI3Blocks = true;
+            }
+        }
+        i = j;
+    }
+
+    int32_t index2Capacity = (iLimit - iStart) >> UCPTRIE_SHIFT_2_3;
+
+    // Length of the index-1 table, rounded up.
+    int32_t index1Length = (index2Capacity + UCPTRIE_INDEX_2_MASK) >> UCPTRIE_SHIFT_1_2;
+
+    // Index table: Fast index, index-1, index-3, index-2.
+    // +1 for possible index table padding.
+    int32_t index16Capacity = fastIndexLength + index1Length + index3Capacity + index2Capacity + 1;
+    index16 = (uint16_t *)uprv_malloc(index16Capacity * 2);
+    if (index16 == nullptr) {
+        errorCode = U_MEMORY_ALLOCATION_ERROR;
+        return 0;
+    }
+    uprv_memcpy(index16, fastIndex, fastIndexLength * 2);
+
+    if (!mixedBlocks.init(index16Capacity, UCPTRIE_INDEX_3_BLOCK_LENGTH)) {
+        errorCode = U_MEMORY_ALLOCATION_ERROR;
+        return 0;
+    }
+    MixedBlocks longI3Blocks;
+    if (hasLongI3Blocks) {
+        if (!longI3Blocks.init(index16Capacity, INDEX_3_18BIT_BLOCK_LENGTH)) {
+            errorCode = U_MEMORY_ALLOCATION_ERROR;
+            return 0;
+        }
+    }
+
+    // Compact the index-3 table and write an uncompacted version of the index-2 table.
+    uint16_t index2[UNICODE_LIMIT >> UCPTRIE_SHIFT_2];  // index2Capacity
+    int32_t i2Length = 0;
+    i3FirstNull = index3NullOffset;
+    int32_t index3Start = fastIndexLength + index1Length;
+    int32_t indexLength = index3Start;
+    for (int32_t i = iStart; i < iLimit; i += UCPTRIE_INDEX_3_BLOCK_LENGTH) {
+        int32_t i3;
+        uint8_t f = flags[i];
+        if (f == I3_NULL && i3FirstNull < 0) {
+            // First index-3 null block. Write & overlap it like a normal block, then remember it.
+            f = dataNullOffset <= 0xffff ? I3_16 : I3_18;
+            i3FirstNull = 0;
+        }
+        if (f == I3_NULL) {
+            i3 = index3NullOffset;
+        } else if (f == I3_BMP) {
+            i3 = index[i];
+        } else if (f == I3_16) {
+            int32_t n = mixedBlocks.findBlock(index16, index, i);
+            if (n >= 0) {
+                i3 = n;
+            } else {
+                if (indexLength == index3Start) {
+                    // No overlap at the boundary between the index-1 and index-3 tables.
+                    n = 0;
+                } else {
+                    n = getOverlap(index16, indexLength,
+                                   index, i, UCPTRIE_INDEX_3_BLOCK_LENGTH);
+                }
+                i3 = indexLength - n;
+                int32_t prevIndexLength = indexLength;
+                while (n < UCPTRIE_INDEX_3_BLOCK_LENGTH) {
+                    index16[indexLength++] = index[i + n++];
+                }
+                mixedBlocks.extend(index16, index3Start, prevIndexLength, indexLength);
+                if (hasLongI3Blocks) {
+                    longI3Blocks.extend(index16, index3Start, prevIndexLength, indexLength);
+                }
+            }
+        } else {
+            U_ASSERT(f == I3_18);
+            U_ASSERT(hasLongI3Blocks);
+            // Encode an index-3 block that contains one or more data indexes exceeding 16 bits.
+            int32_t j = i;
+            int32_t jLimit = i + UCPTRIE_INDEX_3_BLOCK_LENGTH;
+            int32_t k = indexLength;
+            do {
+                ++k;
+                uint32_t v = index[j++];
+                uint32_t upperBits = (v & 0x30000) >> 2;
+                index16[k++] = v;
+                v = index[j++];
+                upperBits |= (v & 0x30000) >> 4;
+                index16[k++] = v;
+                v = index[j++];
+                upperBits |= (v & 0x30000) >> 6;
+                index16[k++] = v;
+                v = index[j++];
+                upperBits |= (v & 0x30000) >> 8;
+                index16[k++] = v;
+                v = index[j++];
+                upperBits |= (v & 0x30000) >> 10;
+                index16[k++] = v;
+                v = index[j++];
+                upperBits |= (v & 0x30000) >> 12;
+                index16[k++] = v;
+                v = index[j++];
+                upperBits |= (v & 0x30000) >> 14;
+                index16[k++] = v;
+                v = index[j++];
+                upperBits |= (v & 0x30000) >> 16;
+                index16[k++] = v;
+                index16[k - 9] = upperBits;
+            } while (j < jLimit);
+            int32_t n = longI3Blocks.findBlock(index16, index16, indexLength);
+            if (n >= 0) {
+                i3 = n | 0x8000;
+            } else {
+                if (indexLength == index3Start) {
+                    // No overlap at the boundary between the index-1 and index-3 tables.
+                    n = 0;
+                } else {
+                    n = getOverlap(index16, indexLength,
+                                   index16, indexLength, INDEX_3_18BIT_BLOCK_LENGTH);
+                }
+                i3 = (indexLength - n) | 0x8000;
+                int32_t prevIndexLength = indexLength;
+                if (n > 0) {
+                    int32_t start = indexLength;
+                    while (n < INDEX_3_18BIT_BLOCK_LENGTH) {
+                        index16[indexLength++] = index16[start + n++];
+                    }
+                } else {
+                    indexLength += INDEX_3_18BIT_BLOCK_LENGTH;
+                }
+                mixedBlocks.extend(index16, index3Start, prevIndexLength, indexLength);
+                if (hasLongI3Blocks) {
+                    longI3Blocks.extend(index16, index3Start, prevIndexLength, indexLength);
+                }
+            }
+        }
+        if (index3NullOffset < 0 && i3FirstNull >= 0) {
+            index3NullOffset = i3;
+        }
+        // Set the index-2 table entry.
+        index2[i2Length++] = i3;
+    }
+    U_ASSERT(i2Length == index2Capacity);
+    U_ASSERT(indexLength <= index3Start + index3Capacity);
+
+    if (index3NullOffset < 0) {
+        index3NullOffset = UCPTRIE_NO_INDEX3_NULL_OFFSET;
+    }
+    if (indexLength >= (UCPTRIE_NO_INDEX3_NULL_OFFSET + UCPTRIE_INDEX_3_BLOCK_LENGTH)) {
+        // The index-3 offsets exceed 15 bits, or
+        // the last one cannot be distinguished from the no-null-block value.
+        errorCode = U_INDEX_OUTOFBOUNDS_ERROR;
+        return 0;
+    }
+
+    // Compact the index-2 table and write the index-1 table.
+    static_assert(UCPTRIE_INDEX_2_BLOCK_LENGTH == UCPTRIE_INDEX_3_BLOCK_LENGTH,
+                  "must re-init mixedBlocks");
+    int32_t blockLength = UCPTRIE_INDEX_2_BLOCK_LENGTH;
+    int32_t i1 = fastIndexLength;
+    for (int32_t i = 0; i < i2Length; i += blockLength) {
+        int32_t n;
+        if ((i2Length - i) >= blockLength) {
+            // normal block
+            U_ASSERT(blockLength == UCPTRIE_INDEX_2_BLOCK_LENGTH);
+            n = mixedBlocks.findBlock(index16, index2, i);
+        } else {
+            // highStart is inside the last index-2 block. Shorten it.
+            blockLength = i2Length - i;
+            n = findSameBlock(index16, index3Start, indexLength,
+                              index2, i, blockLength);
+        }
+        int32_t i2;
+        if (n >= 0) {
+            i2 = n;
+        } else {
+            if (indexLength == index3Start) {
+                // No overlap at the boundary between the index-1 and index-3/2 tables.
+                n = 0;
+            } else {
+                n = getOverlap(index16, indexLength, index2, i, blockLength);
+            }
+            i2 = indexLength - n;
+            int32_t prevIndexLength = indexLength;
+            while (n < blockLength) {
+                index16[indexLength++] = index2[i + n++];
+            }
+            mixedBlocks.extend(index16, index3Start, prevIndexLength, indexLength);
+        }
+        // Set the index-1 table entry.
+        index16[i1++] = i2;
+    }
+    U_ASSERT(i1 == index3Start);
+    U_ASSERT(indexLength <= index16Capacity);
+
+#ifdef UCPTRIE_DEBUG
+    /* we saved some space */
+    printf("compacting UCPTrie: count of 16-bit index words %lu->%lu\n",
+            (long)iLimit, (long)indexLength);
+#endif
+
+    return indexLength;
+}
+
+int32_t MutableCodePointTrie::compactTrie(int32_t fastILimit, UErrorCode &errorCode) {
+    // Find the real highStart and round it up.
+    U_ASSERT((highStart & (UCPTRIE_CP_PER_INDEX_2_ENTRY - 1)) == 0);
+    highValue = get(MAX_UNICODE);
+    int32_t realHighStart = findHighStart();
+    realHighStart = (realHighStart + (UCPTRIE_CP_PER_INDEX_2_ENTRY - 1)) &
+        ~(UCPTRIE_CP_PER_INDEX_2_ENTRY - 1);
+    if (realHighStart == UNICODE_LIMIT) {
+        highValue = initialValue;
+    }
+
+#ifdef UCPTRIE_DEBUG
+    printf("UCPTrie: highStart U+%06lx  highValue 0x%lx  initialValue 0x%lx\n",
+            (long)realHighStart, (long)highValue, (long)initialValue);
+#endif
+
+    // We always store indexes and data values for the fast range.
+    // Pin highStart to the top of that range while building.
+    UChar32 fastLimit = fastILimit << UCPTRIE_SHIFT_3;
+    if (realHighStart < fastLimit) {
+        for (int32_t i = (realHighStart >> UCPTRIE_SHIFT_3); i < fastILimit; ++i) {
+            flags[i] = ALL_SAME;
+            index[i] = highValue;
+        }
+        highStart = fastLimit;
+    } else {
+        highStart = realHighStart;
+    }
+
+    uint32_t asciiData[ASCII_LIMIT];
+    for (int32_t i = 0; i < ASCII_LIMIT; ++i) {
+        asciiData[i] = get(i);
+    }
+
+    // First we look for which data blocks have the same value repeated over the whole block,
+    // deduplicate such blocks, find a good null data block (for faster enumeration),
+    // and get an upper bound for the necessary data array length.
+    AllSameBlocks allSameBlocks;
+    int32_t newDataCapacity = compactWholeDataBlocks(fastILimit, allSameBlocks);
+    if (newDataCapacity < 0) {
+        errorCode = U_MEMORY_ALLOCATION_ERROR;
+        return 0;
+    }
+    uint32_t *newData = (uint32_t *)uprv_malloc(newDataCapacity * 4);
+    if (newData == nullptr) {
+        errorCode = U_MEMORY_ALLOCATION_ERROR;
+        return 0;
+    }
+    uprv_memcpy(newData, asciiData, sizeof(asciiData));
+
+    int32_t dataNullIndex = allSameBlocks.findMostUsed();
+
+    MixedBlocks mixedBlocks;
+    int32_t newDataLength = compactData(fastILimit, newData, newDataCapacity,
+                                        dataNullIndex, mixedBlocks, errorCode);
+    if (U_FAILURE(errorCode)) { return 0; }
+    U_ASSERT(newDataLength <= newDataCapacity);
+    uprv_free(data);
+    data = newData;
+    dataCapacity = newDataCapacity;
+    dataLength = newDataLength;
+    if (dataLength > (0x3ffff + UCPTRIE_SMALL_DATA_BLOCK_LENGTH)) {
+        // The offset of the last data block is too high to be stored in the index table.
+        errorCode = U_INDEX_OUTOFBOUNDS_ERROR;
+        return 0;
+    }
+
+    if (dataNullIndex >= 0) {
+        dataNullOffset = index[dataNullIndex];
+#ifdef UCPTRIE_DEBUG
+        if (data[dataNullOffset] != initialValue) {
+            printf("UCPTrie initialValue %lx -> more common nullValue %lx\n",
+                   (long)initialValue, (long)data[dataNullOffset]);
+        }
+#endif
+        initialValue = data[dataNullOffset];
+    } else {
+        dataNullOffset = UCPTRIE_NO_DATA_NULL_OFFSET;
+    }
+
+    int32_t indexLength = compactIndex(fastILimit, mixedBlocks, errorCode);
+    highStart = realHighStart;
+    return indexLength;
+}
+
+UCPTrie *MutableCodePointTrie::build(UCPTrieType type, UCPTrieValueWidth valueWidth, UErrorCode &errorCode) {
+    if (U_FAILURE(errorCode)) {
+        return nullptr;
+    }
+    if (type < UCPTRIE_TYPE_FAST || UCPTRIE_TYPE_SMALL < type ||
+            valueWidth < UCPTRIE_VALUE_BITS_16 || UCPTRIE_VALUE_BITS_8 < valueWidth) {
+        errorCode = U_ILLEGAL_ARGUMENT_ERROR;
+        return nullptr;
+    }
+
+    // The mutable trie always stores 32-bit values.
+    // When we build a UCPTrie for a smaller value width, we first mask off unused bits
+    // before compacting the data.
+    switch (valueWidth) {
+    case UCPTRIE_VALUE_BITS_32:
+        break;
+    case UCPTRIE_VALUE_BITS_16:
+        maskValues(0xffff);
+        break;
+    case UCPTRIE_VALUE_BITS_8:
+        maskValues(0xff);
+        break;
+    default:
+        break;
+    }
+
+    UChar32 fastLimit = type == UCPTRIE_TYPE_FAST ? BMP_LIMIT : UCPTRIE_SMALL_LIMIT;
+    int32_t indexLength = compactTrie(fastLimit >> UCPTRIE_SHIFT_3, errorCode);
+    if (U_FAILURE(errorCode)) {
+        clear();
+        return nullptr;
+    }
+
+    // Ensure data table alignment: The index length must be even for uint32_t data.
+    if (valueWidth == UCPTRIE_VALUE_BITS_32 && (indexLength & 1) != 0) {
+        index16[indexLength++] = 0xffee;  // arbitrary value
+    }
+
+    // Make the total trie structure length a multiple of 4 bytes by padding the data table,
+    // and store special values as the last two data values.
+    int32_t length = indexLength * 2;
+    if (valueWidth == UCPTRIE_VALUE_BITS_16) {
+        if (((indexLength ^ dataLength) & 1) != 0) {
+            // padding
+            data[dataLength++] = errorValue;
+        }
+        if (data[dataLength - 1] != errorValue || data[dataLength - 2] != highValue) {
+            data[dataLength++] = highValue;
+            data[dataLength++] = errorValue;
+        }
+        length += dataLength * 2;
+    } else if (valueWidth == UCPTRIE_VALUE_BITS_32) {
+        // 32-bit data words never need padding to a multiple of 4 bytes.
+        if (data[dataLength - 1] != errorValue || data[dataLength - 2] != highValue) {
+            if (data[dataLength - 1] != highValue) {
+                data[dataLength++] = highValue;
+            }
+            data[dataLength++] = errorValue;
+        }
+        length += dataLength * 4;
+    } else {
+        int32_t and3 = (length + dataLength) & 3;
+        if (and3 == 0 && data[dataLength - 1] == errorValue && data[dataLength - 2] == highValue) {
+            // all set
+        } else if(and3 == 3 && data[dataLength - 1] == highValue) {
+            data[dataLength++] = errorValue;
+        } else {
+            while (and3 != 2) {
+                data[dataLength++] = highValue;
+                and3 = (and3 + 1) & 3;
+            }
+            data[dataLength++] = highValue;
+            data[dataLength++] = errorValue;
+        }
+        length += dataLength;
+    }
+
+    // Calculate the total length of the UCPTrie as a single memory block.
+    length += sizeof(UCPTrie);
+    U_ASSERT((length & 3) == 0);
+
+    uint8_t *bytes = (uint8_t *)uprv_malloc(length);
+    if (bytes == nullptr) {
+        errorCode = U_MEMORY_ALLOCATION_ERROR;
+        clear();
+        return nullptr;
+    }
+    UCPTrie *trie = reinterpret_cast<UCPTrie *>(bytes);
+    uprv_memset(trie, 0, sizeof(UCPTrie));
+    trie->indexLength = indexLength;
+    trie->dataLength = dataLength;
+
+    trie->highStart = highStart;
+    // Round up shifted12HighStart to a multiple of 0x1000 for easy testing from UTF-8 lead bytes.
+    // Runtime code needs to then test for the real highStart as well.
+    trie->shifted12HighStart = (highStart + 0xfff) >> 12;
+    trie->type = type;
+    trie->valueWidth = valueWidth;
+
+    trie->index3NullOffset = index3NullOffset;
+    trie->dataNullOffset = dataNullOffset;
+    trie->nullValue = initialValue;
+
+    bytes += sizeof(UCPTrie);
+
+    // Fill the index and data arrays.
+    uint16_t *dest16 = (uint16_t *)bytes;
+    trie->index = dest16;
+
+    if (highStart <= fastLimit) {
+        // Condense only the fast index from the mutable-trie index.
+        for (int32_t i = 0, j = 0; j < indexLength; i += SMALL_DATA_BLOCKS_PER_BMP_BLOCK, ++j) {
+            *dest16++ = (uint16_t)index[i];  // dest16[j]
+        }
+    } else {
+        uprv_memcpy(dest16, index16, indexLength * 2);
+        dest16 += indexLength;
+    }
+    bytes += indexLength * 2;
+
+    // Write the data array.
+    const uint32_t *p = data;
+    switch (valueWidth) {
+    case UCPTRIE_VALUE_BITS_16:
+        // Write 16-bit data values.
+        trie->data.ptr16 = dest16;
+        for (int32_t i = dataLength; i > 0; --i) {
+            *dest16++ = (uint16_t)*p++;
+        }
+        break;
+    case UCPTRIE_VALUE_BITS_32:
+        // Write 32-bit data values.
+        trie->data.ptr32 = (uint32_t *)bytes;
+        uprv_memcpy(bytes, p, (size_t)dataLength * 4);
+        break;
+    case UCPTRIE_VALUE_BITS_8:
+        // Write 8-bit data values.
+        trie->data.ptr8 = bytes;
+        for (int32_t i = dataLength; i > 0; --i) {
+            *bytes++ = (uint8_t)*p++;
+        }
+        break;
+    default:
+        // Will not occur, valueWidth checked at the beginning.
+        break;
+    }
+
+#ifdef UCPTRIE_DEBUG
+    trie->name = name;
+
+    ucptrie_printLengths(trie, "");
+#endif
+
+    clear();
+    return trie;
+}
+
+}  // namespace
+
+U_NAMESPACE_END
+
+U_NAMESPACE_USE
+
+U_CAPI UMutableCPTrie * U_EXPORT2
+umutablecptrie_open(uint32_t initialValue, uint32_t errorValue, UErrorCode *pErrorCode) {
+    if (U_FAILURE(*pErrorCode)) {
+        return nullptr;
+    }
+    LocalPointer<MutableCodePointTrie> trie(
+        new MutableCodePointTrie(initialValue, errorValue, *pErrorCode), *pErrorCode);
+    if (U_FAILURE(*pErrorCode)) {
+        return nullptr;
+    }
+    return reinterpret_cast<UMutableCPTrie *>(trie.orphan());
+}
+
+U_CAPI UMutableCPTrie * U_EXPORT2
+umutablecptrie_clone(const UMutableCPTrie *other, UErrorCode *pErrorCode) {
+    if (U_FAILURE(*pErrorCode)) {
+        return nullptr;
+    }
+    if (other == nullptr) {
+        return nullptr;
+    }
+    LocalPointer<MutableCodePointTrie> clone(
+        new MutableCodePointTrie(*reinterpret_cast<const MutableCodePointTrie *>(other), *pErrorCode), *pErrorCode);
+    if (U_FAILURE(*pErrorCode)) {
+        return nullptr;
+    }
+    return reinterpret_cast<UMutableCPTrie *>(clone.orphan());
+}
+
+U_CAPI void U_EXPORT2
+umutablecptrie_close(UMutableCPTrie *trie) {
+    delete reinterpret_cast<MutableCodePointTrie *>(trie);
+}
+
+U_CAPI UMutableCPTrie * U_EXPORT2
+umutablecptrie_fromUCPMap(const UCPMap *map, UErrorCode *pErrorCode) {
+    if (U_FAILURE(*pErrorCode)) {
+        return nullptr;
+    }
+    if (map == nullptr) {
+        *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR;
+        return nullptr;
+    }
+    return reinterpret_cast<UMutableCPTrie *>(MutableCodePointTrie::fromUCPMap(map, *pErrorCode));
+}
+
+U_CAPI UMutableCPTrie * U_EXPORT2
+umutablecptrie_fromUCPTrie(const UCPTrie *trie, UErrorCode *pErrorCode) {
+    if (U_FAILURE(*pErrorCode)) {
+        return nullptr;
+    }
+    if (trie == nullptr) {
+        *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR;
+        return nullptr;
+    }
+    return reinterpret_cast<UMutableCPTrie *>(MutableCodePointTrie::fromUCPTrie(trie, *pErrorCode));
+}
+
+U_CAPI uint32_t U_EXPORT2
+umutablecptrie_get(const UMutableCPTrie *trie, UChar32 c) {
+    return reinterpret_cast<const MutableCodePointTrie *>(trie)->get(c);
+}
+
+namespace {
+
+UChar32 getRange(const void *trie, UChar32 start,
+                 UCPMapValueFilter *filter, const void *context, uint32_t *pValue) {
+    return reinterpret_cast<const MutableCodePointTrie *>(trie)->
+        getRange(start, filter, context, pValue);
+}
+
+}  // namespace
+
+U_CAPI UChar32 U_EXPORT2
+umutablecptrie_getRange(const UMutableCPTrie *trie, UChar32 start,
+                        UCPMapRangeOption option, uint32_t surrogateValue,
+                        UCPMapValueFilter *filter, const void *context, uint32_t *pValue) {
+    return ucptrie_internalGetRange(getRange, trie, start,
+                                    option, surrogateValue,
+                                    filter, context, pValue);
+}
+
+U_CAPI void U_EXPORT2
+umutablecptrie_set(UMutableCPTrie *trie, UChar32 c, uint32_t value, UErrorCode *pErrorCode) {
+    if (U_FAILURE(*pErrorCode)) {
+        return;
+    }
+    reinterpret_cast<MutableCodePointTrie *>(trie)->set(c, value, *pErrorCode);
+}
+
+U_CAPI void U_EXPORT2
+umutablecptrie_setRange(UMutableCPTrie *trie, UChar32 start, UChar32 end,
+                   uint32_t value, UErrorCode *pErrorCode) {
+    if (U_FAILURE(*pErrorCode)) {
+        return;
+    }
+    reinterpret_cast<MutableCodePointTrie *>(trie)->setRange(start, end, value, *pErrorCode);
+}
+
+/* Compact and internally serialize the trie. */
+U_CAPI UCPTrie * U_EXPORT2
+umutablecptrie_buildImmutable(UMutableCPTrie *trie, UCPTrieType type, UCPTrieValueWidth valueWidth,
+                              UErrorCode *pErrorCode) {
+    if (U_FAILURE(*pErrorCode)) {
+        return nullptr;
+    }
+    return reinterpret_cast<MutableCodePointTrie *>(trie)->build(type, valueWidth, *pErrorCode);
+}
+
+#ifdef UCPTRIE_DEBUG
+U_CFUNC void umutablecptrie_setName(UMutableCPTrie *trie, const char *name) {
+    reinterpret_cast<MutableCodePointTrie *>(trie)->name = name;
+}
+#endif
diff --git a/src/third_party/icu/source/common/umutex.cpp b/src/third_party/icu/source/common/umutex.cpp
index c7c6c47..04203eb 100644
--- a/src/third_party/icu/source/common/umutex.cpp
+++ b/src/third_party/icu/source/common/umutex.cpp
@@ -1,7 +1,9 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
-*   Copyright (C) 1997-2015, International Business Machines
+*   Copyright (C) 1997-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *
 ******************************************************************************
@@ -18,273 +20,150 @@
 ******************************************************************************
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "umutex.h"
 
 #include "unicode/utypes.h"
 #include "uassert.h"
+#include "ucln_cmn.h"
 #include "cmemory.h"
 
+U_NAMESPACE_BEGIN
 
-// The ICU global mutex. Used when ICU implementation code passes NULL for the mutex pointer.
-static UMutex   globalMutex = U_MUTEX_INITIALIZER;
-
-/*
- * ICU Mutex wrappers.  Wrap operating system mutexes, giving the rest of ICU a
- * platform independent set of mutex operations.  For internal ICU use only.
- */
 
 #if defined(U_USER_MUTEX_CPP)
-// Build time user mutex hook: #include "U_USER_MUTEX_CPP"
-#include U_MUTEX_XSTR(U_USER_MUTEX_CPP)
-
-#elif U_PLATFORM_HAS_WIN32_API
-
-//-------------------------------------------------------------------------------------------
-//
-//    Windows Specific Definitions
-//
-//        Note: Cygwin (and possibly others) have both WIN32 and POSIX.
-//              Prefer Win32 in these cases.  (Win32 comes ahead in the #if chain)
-//
-//-------------------------------------------------------------------------------------------
-
-#if defined U_NO_PLATFORM_ATOMICS
-#error ICU on Win32 requires support for low level atomic operations.
-// Visual Studio, gcc, clang are OK. Shouldn't get here.
+// Support for including an alternate implementation of mutexes has been withdrawn.
+// See issue ICU-20185.
+#error U_USER_MUTEX_CPP not supported
 #endif
 
 
-// This function is called when a test of a UInitOnce::fState reveals that
-//   initialization has not completed, that we either need to call the
-//   function on this thread, or wait for some other thread to complete.
-//
-// The actual call to the init function is made inline by template code
-//   that knows the C++ types involved. This function returns TRUE if
-//   the caller needs to call the Init function.
-//
+/*************************************************************************************************
+ *
+ *  ICU Mutex wrappers.
+ *
+ *************************************************************************************************/
 
-U_NAMESPACE_BEGIN
+namespace {
+std::mutex *initMutex;
+std::condition_variable *initCondition;
 
-U_COMMON_API UBool U_EXPORT2 umtx_initImplPreInit(UInitOnce &uio) {
-    for (;;) {
-        int32_t previousState = InterlockedCompareExchange(
-#if (U_PLATFORM == U_PF_MINGW) || (U_PLATFORM == U_PF_CYGWIN) || defined(__clang__)
-           (LONG volatile *) // this is the type given in the API doc for this function.
-#endif
-            &uio.fState,  //  Destination
-            1,            //  Exchange Value
-            0);           //  Compare value
+// The ICU global mutex.
+// Used when ICU implementation code passes nullptr for the mutex pointer.
+UMutex globalMutex;
 
-        if (previousState == 0) {
-            return true;   // Caller will next call the init function.
-                           // Current state == 1.
-        } else if (previousState == 2) {
-            // Another thread already completed the initialization.
-            //   We can simply return FALSE, indicating no
-            //   further action is needed by the caller.
-            return FALSE;
-        } else {
-            // Another thread is currently running the initialization.
-            // Wait until it completes.
-            do {
-                Sleep(1);
-                previousState = umtx_loadAcquire(uio.fState);
-            } while (previousState == 1);
+std::once_flag initFlag;
+std::once_flag *pInitFlag = &initFlag;
+
+}  // Anonymous namespace
+
+U_CDECL_BEGIN
+static UBool U_CALLCONV umtx_cleanup() {
+    initMutex->~mutex();
+    initCondition->~condition_variable();
+    UMutex::cleanup();
+
+    // Reset the once_flag, by destructing it and creating a fresh one in its place.
+    // Do not use this trick anywhere else in ICU; use umtx_initOnce, not std::call_once().
+    pInitFlag->~once_flag();
+    pInitFlag = new(&initFlag) std::once_flag();
+    return true;
+}
+
+static void U_CALLCONV umtx_init() {
+    initMutex = STATIC_NEW(std::mutex);
+    initCondition = STATIC_NEW(std::condition_variable);
+    ucln_common_registerCleanup(UCLN_COMMON_MUTEX, umtx_cleanup);
+}
+U_CDECL_END
+
+
+std::mutex *UMutex::getMutex() {
+    std::mutex *retPtr = fMutex.load(std::memory_order_acquire);
+    if (retPtr == nullptr) {
+        std::call_once(*pInitFlag, umtx_init);
+        std::lock_guard<std::mutex> guard(*initMutex);
+        retPtr = fMutex.load(std::memory_order_acquire);
+        if (retPtr == nullptr) {
+            fMutex = new(fStorage) std::mutex();
+            retPtr = fMutex;
+            fListLink = gListHead;
+            gListHead = this;
         }
     }
+    U_ASSERT(retPtr != nullptr);
+    return retPtr;
 }
 
-// This function is called by the thread that ran an initialization function,
-// just after completing the function.
+UMutex *UMutex::gListHead = nullptr;
 
-U_COMMON_API void U_EXPORT2 umtx_initImplPostInit(UInitOnce &uio) {
-    umtx_storeRelease(uio.fState, 2);
+void UMutex::cleanup() {
+    UMutex *next = nullptr;
+    for (UMutex *m = gListHead; m != nullptr; m = next) {
+        (*m->fMutex).~mutex();
+        m->fMutex = nullptr;
+        next = m->fListLink;
+        m->fListLink = nullptr;
+    }
+    gListHead = nullptr;
 }
 
-U_NAMESPACE_END
-
-static void winMutexInit(CRITICAL_SECTION *cs) {
-    InitializeCriticalSection(cs);
-    return;
-}
 
 U_CAPI void  U_EXPORT2
 umtx_lock(UMutex *mutex) {
-    if (mutex == NULL) {
+    if (mutex == nullptr) {
         mutex = &globalMutex;
     }
-    CRITICAL_SECTION *cs = &mutex->fCS;
-    umtx_initOnce(mutex->fInitOnce, winMutexInit, cs);
-    EnterCriticalSection(cs);
-}
-
-U_CAPI void  U_EXPORT2
-umtx_unlock(UMutex* mutex)
-{
-    if (mutex == NULL) {
-        mutex = &globalMutex;
-    }
-    LeaveCriticalSection(&mutex->fCS);
-}
-
-
-U_CAPI void U_EXPORT2
-umtx_condBroadcast(UConditionVar *condition) {
-    // We require that the associated mutex be held by the caller,
-    //  so access to fWaitCount is protected and safe. No other thread can
-    //  call condWait() while we are here.
-    if (condition->fWaitCount == 0) {
-        return;
-    }
-    ResetEvent(condition->fExitGate);
-    SetEvent(condition->fEntryGate);
-}
-
-U_CAPI void U_EXPORT2
-umtx_condSignal(UConditionVar *condition) {
-    // Function not implemented. There is no immediate requirement from ICU to have it.
-    // Once ICU drops support for Windows XP and Server 2003, ICU Condition Variables will be
-    // changed to be thin wrappers on native Windows CONDITION_VARIABLEs, and this function
-    // becomes trivial to provide.
-    U_ASSERT(FALSE);
-}
-
-U_CAPI void U_EXPORT2
-umtx_condWait(UConditionVar *condition, UMutex *mutex) {
-    if (condition->fEntryGate == NULL) {
-        // Note: because the associated mutex must be locked when calling
-        //       wait, we know that there can not be multiple threads
-        //       running here with the same condition variable.
-        //       Meaning that lazy initialization is safe.
-        U_ASSERT(condition->fExitGate == NULL);
-        condition->fEntryGate = CreateEvent(NULL,   // Security Attributes
-                                            TRUE,   // Manual Reset
-                                            FALSE,  // Initially reset
-                                            NULL);  // Name.
-        U_ASSERT(condition->fEntryGate != NULL);
-        condition->fExitGate = CreateEvent(NULL, TRUE, TRUE, NULL);
-        U_ASSERT(condition->fExitGate != NULL);
-    }
-
-    condition->fWaitCount++;
-    umtx_unlock(mutex);
-    WaitForSingleObject(condition->fEntryGate, INFINITE); 
-    umtx_lock(mutex);
-    condition->fWaitCount--;
-    if (condition->fWaitCount == 0) {
-        // All threads that were waiting at the entry gate have woken up
-        // and moved through. Shut the entry gate and open the exit gate.
-        ResetEvent(condition->fEntryGate);
-        SetEvent(condition->fExitGate);
-    } else {
-        umtx_unlock(mutex);
-        WaitForSingleObject(condition->fExitGate, INFINITE);
-        umtx_lock(mutex);
-    }
-}
-
-
-#elif U_PLATFORM_IMPLEMENTS_POSIX
-
-//-------------------------------------------------------------------------------------------
-//
-//  POSIX specific definitions
-//
-//-------------------------------------------------------------------------------------------
-
-# include <pthread.h>
-
-// Each UMutex consists of a pthread_mutex_t.
-// All are statically initialized and ready for use.
-// There is no runtime mutex initialization code needed.
-
-U_CAPI void  U_EXPORT2
-umtx_lock(UMutex *mutex) {
-    if (mutex == NULL) {
-        mutex = &globalMutex;
-    }
-    int sysErr = pthread_mutex_lock(&mutex->fMutex);
-    (void)sysErr;   // Suppress unused variable warnings.
-    U_ASSERT(sysErr == 0);
+    mutex->lock();
 }
 
 
 U_CAPI void  U_EXPORT2
 umtx_unlock(UMutex* mutex)
 {
-    if (mutex == NULL) {
+    if (mutex == nullptr) {
         mutex = &globalMutex;
     }
-    int sysErr = pthread_mutex_unlock(&mutex->fMutex);
-    (void)sysErr;   // Suppress unused variable warnings.
-    U_ASSERT(sysErr == 0);
+    mutex->unlock();
 }
 
 
-U_CAPI void U_EXPORT2
-umtx_condWait(UConditionVar *cond, UMutex *mutex) {
-    if (mutex == NULL) {
-        mutex = &globalMutex;
-    }
-    int sysErr = pthread_cond_wait(&cond->fCondition, &mutex->fMutex);
-    (void)sysErr;
-    U_ASSERT(sysErr == 0);
-}
-
-U_CAPI void U_EXPORT2
-umtx_condBroadcast(UConditionVar *cond) {
-    int sysErr = pthread_cond_broadcast(&cond->fCondition);
-    (void)sysErr;
-    U_ASSERT(sysErr == 0);
-}
-
-U_CAPI void U_EXPORT2
-umtx_condSignal(UConditionVar *cond) {
-    int sysErr = pthread_cond_signal(&cond->fCondition);
-    (void)sysErr;
-    U_ASSERT(sysErr == 0);
-}
-
-
-
-U_NAMESPACE_BEGIN
-
-static pthread_mutex_t initMutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_cond_t initCondition = PTHREAD_COND_INITIALIZER;
-
+/*************************************************************************************************
+ *
+ *  UInitOnce Implementation
+ *
+ *************************************************************************************************/
 
 // This function is called when a test of a UInitOnce::fState reveals that
-//   initialization has not completed, that we either need to call the
+//   initialization has not completed, that we either need to call the init
 //   function on this thread, or wait for some other thread to complete.
 //
 // The actual call to the init function is made inline by template code
-//   that knows the C++ types involved. This function returns TRUE if
+//   that knows the C++ types involved. This function returns true if
 //   the caller needs to call the Init function.
 //
 U_COMMON_API UBool U_EXPORT2
 umtx_initImplPreInit(UInitOnce &uio) {
-    pthread_mutex_lock(&initMutex);
-    int32_t state = uio.fState;
-    if (state == 0) {
+    std::call_once(*pInitFlag, umtx_init);
+    std::unique_lock<std::mutex> lock(*initMutex);
+    if (umtx_loadAcquire(uio.fState) == 0) {
         umtx_storeRelease(uio.fState, 1);
-        pthread_mutex_unlock(&initMutex);
-        return TRUE;   // Caller will next call the init function.
+        return true;      // Caller will next call the init function.
     } else {
-        while (uio.fState == 1) {
+        while (umtx_loadAcquire(uio.fState) == 1) {
             // Another thread is currently running the initialization.
             // Wait until it completes.
-            pthread_cond_wait(&initCondition, &initMutex);
+            initCondition->wait(lock);
         }
-        pthread_mutex_unlock(&initMutex);
         U_ASSERT(uio.fState == 2);
-        return FALSE;
+        return false;
     }
 }
 
 
-
 // This function is called by the thread that ran an initialization function,
 // just after completing the function.
 //   Some threads may be waiting on the condition, requiring the broadcast wakeup.
@@ -293,80 +172,20 @@
 
 U_COMMON_API void U_EXPORT2
 umtx_initImplPostInit(UInitOnce &uio) {
-    pthread_mutex_lock(&initMutex);
-    umtx_storeRelease(uio.fState, 2);
-    pthread_cond_broadcast(&initCondition);
-    pthread_mutex_unlock(&initMutex);
+    {
+        std::unique_lock<std::mutex> lock(*initMutex);
+        umtx_storeRelease(uio.fState, 2);
+    }
+    initCondition->notify_all();
 }
 
 U_NAMESPACE_END
 
-// End of POSIX specific umutex implementation.
-
-#else  // Platform #define chain.
-
-#error Unknown Platform
-
-#endif  // Platform #define chain.
-
-
-//-------------------------------------------------------------------------------
-//
-//   Atomic Operations, out-of-line versions.
-//                      These are conditional, only defined if better versions
-//                      were not available for the platform.
-//
-//                      These versions are platform neutral.
-//
-//--------------------------------------------------------------------------------
-
-#if defined U_NO_PLATFORM_ATOMICS
-static UMutex   gIncDecMutex = U_MUTEX_INITIALIZER;
-
-U_NAMESPACE_BEGIN
-
-U_COMMON_API int32_t U_EXPORT2
-umtx_atomic_inc(u_atomic_int32_t *p)  {
-    int32_t retVal;
-    umtx_lock(&gIncDecMutex);
-    retVal = ++(*p);
-    umtx_unlock(&gIncDecMutex);
-    return retVal;
-}
-
-
-U_COMMON_API int32_t U_EXPORT2
-umtx_atomic_dec(u_atomic_int32_t *p) {
-    int32_t retVal;
-    umtx_lock(&gIncDecMutex);
-    retVal = --(*p);
-    umtx_unlock(&gIncDecMutex);
-    return retVal;
-}
-
-U_COMMON_API int32_t U_EXPORT2
-umtx_loadAcquire(u_atomic_int32_t &var) {
-    umtx_lock(&gIncDecMutex);
-    int32_t val = var;
-    umtx_unlock(&gIncDecMutex);
-    return val;
-}
-
-U_COMMON_API void U_EXPORT2
-umtx_storeRelease(u_atomic_int32_t &var, int32_t val) {
-    umtx_lock(&gIncDecMutex);
-    var = val;
-    umtx_unlock(&gIncDecMutex);
-}
-
-U_NAMESPACE_END
-#endif
-
-//--------------------------------------------------------------------------
-//
-//  Deprecated functions for setting user mutexes.
-//
-//--------------------------------------------------------------------------
+/*************************************************************************************************
+ *
+ *  Deprecated functions for setting user mutexes.
+ *
+ *************************************************************************************************/
 
 U_DEPRECATED void U_EXPORT2
 u_setMutexFunctions(const void * /*context */, UMtxInitFn *, UMtxFn *,
diff --git a/src/third_party/icu/source/common/umutex.h b/src/third_party/icu/source/common/umutex.h
index 2f12dca..8d76b3f 100644
--- a/src/third_party/icu/source/common/umutex.h
+++ b/src/third_party/icu/source/common/umutex.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
 *   Copyright (C) 1997-2015, International Business Machines
@@ -18,49 +20,55 @@
 #ifndef UMUTEX_H
 #define UMUTEX_H
 
+#include <atomic>
+#include <condition_variable>
+#include <mutex>
+#include <type_traits>
+
 #include "unicode/utypes.h"
 #include "unicode/uclean.h"
+#include "unicode/uobject.h"
+
 #include "putilimp.h"
 
-
-
-// Forward Declarations. UMutex is not in the ICU namespace (yet) because
-//                       there are some remaining references from plain C.
-#if !defined(U_USER_ATOMICS_H)
-// Postponing the defines gives the user flexibility.  E.g. UMutex and
-// UConditionVar can now be typedefs.
-struct UMutex;
-struct UConditionVar;
+#if defined(U_USER_ATOMICS_H) || defined(U_USER_MUTEX_H)
+// Support for including an alternate implementation of atomic & mutex operations has been withdrawn.
+// See issue ICU-20185.
+#error U_USER_ATOMICS and U_USER_MUTEX_H are not supported
 #endif
 
-U_NAMESPACE_BEGIN
-struct UInitOnce;
-U_NAMESPACE_END
+// Export an explicit template instantiation of std::atomic<int32_t>. 
+// When building DLLs for Windows this is required as it is used as a data member of the exported SharedObject class.
+// See digitlst.h, pluralaffix.h, datefmt.h, and others for similar examples.
+//
+// Similar story for std::atomic<std::mutex *>, and the exported UMutex class.
+#if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN && !defined(U_IN_DOXYGEN)
+#if defined(__clang__) || defined(_MSC_VER)
+  #if defined(__clang__)
+    // Suppress the warning that the explicit instantiation after explicit specialization has no effect.
+    #pragma clang diagnostic push
+    #pragma clang diagnostic ignored "-Winstantiation-after-specialization"
+  #endif
+template struct U_COMMON_API std::atomic<int32_t>;
+template struct U_COMMON_API std::atomic<std::mutex *>;
+  #if defined(__clang__)
+    #pragma clang diagnostic pop
+  #endif
+#elif defined(__GNUC__)
+// For GCC this class is already exported/visible, so no need for U_COMMON_API.
+template struct std::atomic<int32_t>;
+template struct std::atomic<std::mutex *>;
+#endif
+#endif
 
-// Stringify macros, to allow #include of user supplied atomic & mutex files.
-#define U_MUTEX_STR(s) #s
-#define U_MUTEX_XSTR(s) U_MUTEX_STR(s)
+
+U_NAMESPACE_BEGIN
 
 /****************************************************************************
  *
- *   Low Level Atomic Operations.
- *      Compiler dependent. Not operating system dependent.
+ *   Low Level Atomic Operations, ICU wrappers for.
  *
  ****************************************************************************/
-#if defined (U_USER_ATOMICS_H)
-#include U_MUTEX_XSTR(U_USER_ATOMICS_H)
-
-#if defined(STARBOARD)
-#define ATOMIC_INT32_T_INITIALIZER(val) (val)
-#endif
-
-#elif U_HAVE_STD_ATOMICS
-
-//  C++11 atomics are available.
-
-#include <atomic>
-
-U_NAMESPACE_BEGIN
 
 typedef std::atomic<int32_t> u_atomic_int32_t;
 #define ATOMIC_INT32_T_INITIALIZER(val) ATOMIC_VAR_INIT(val)
@@ -80,153 +88,19 @@
 inline int32_t umtx_atomic_dec(u_atomic_int32_t *var) {
     return var->fetch_sub(1) - 1;
 }
-U_NAMESPACE_END
-
-#elif U_PLATFORM_HAS_WIN32_API
-
-// MSVC compiler. Reads and writes of volatile variables have
-//                acquire and release memory semantics, respectively.
-//                This is a Microsoft extension, not standard C++ behavior.
-//
-//   Update:      can't use this because of MinGW, built with gcc.
-//                Original plan was to use gcc atomics for MinGW, but they
-//                aren't supported, so we fold MinGW into this path.
-
-# define WIN32_LEAN_AND_MEAN
-# define VC_EXTRALEAN
-# define NOUSER
-# define NOSERVICE
-# define NOIME
-# define NOMCX
-# ifndef NOMINMAX
-# define NOMINMAX
-# endif
-# include <windows.h>
-
-U_NAMESPACE_BEGIN
-typedef volatile LONG u_atomic_int32_t;
-#define ATOMIC_INT32_T_INITIALIZER(val) val
-
-inline int32_t umtx_loadAcquire(u_atomic_int32_t &var) {
-    return InterlockedCompareExchange(&var, 0, 0);
-}
-
-inline void umtx_storeRelease(u_atomic_int32_t &var, int32_t val) {
-    InterlockedExchange(&var, val);
-}
-
-
-inline int32_t umtx_atomic_inc(u_atomic_int32_t *var) {
-    return InterlockedIncrement(var);
-}
-
-inline int32_t umtx_atomic_dec(u_atomic_int32_t *var) {
-    return InterlockedDecrement(var);
-}
-U_NAMESPACE_END
-
-
-#elif U_HAVE_CLANG_ATOMICS
-/*
- *  Clang __c11 atomic built-ins
- */
-
-U_NAMESPACE_BEGIN
-typedef _Atomic(int32_t) u_atomic_int32_t;
-#define ATOMIC_INT32_T_INITIALIZER(val) val
-
-inline int32_t umtx_loadAcquire(u_atomic_int32_t &var) {
-     return __c11_atomic_load(&var, __ATOMIC_ACQUIRE);
-}
-
-inline void umtx_storeRelease(u_atomic_int32_t &var, int32_t val) {
-   return __c11_atomic_store(&var, val, __ATOMIC_RELEASE);
-}
-
-inline int32_t umtx_atomic_inc(u_atomic_int32_t *var) {
-    return __c11_atomic_fetch_add(var, 1, __ATOMIC_SEQ_CST) + 1;
-}
-
-inline int32_t umtx_atomic_dec(u_atomic_int32_t *var) {
-    return __c11_atomic_fetch_sub(var, 1, __ATOMIC_SEQ_CST) - 1;
-}
-U_NAMESPACE_END
-
-
-#elif U_HAVE_GCC_ATOMICS
-/*
- * gcc atomic ops. These are available on several other compilers as well.
- */
-
-U_NAMESPACE_BEGIN
-typedef int32_t u_atomic_int32_t;
-#define ATOMIC_INT32_T_INITIALIZER(val) val
-
-inline int32_t umtx_loadAcquire(u_atomic_int32_t &var) {
-    int32_t val = var;
-    __sync_synchronize();
-    return val;
-}
-
-inline void umtx_storeRelease(u_atomic_int32_t &var, int32_t val) {
-    __sync_synchronize();
-    var = val;
-}
-
-inline int32_t umtx_atomic_inc(u_atomic_int32_t *p)  {
-   return __sync_add_and_fetch(p, 1);
-}
-
-inline int32_t umtx_atomic_dec(u_atomic_int32_t *p)  {
-   return __sync_sub_and_fetch(p, 1);
-}
-U_NAMESPACE_END
-
-#else
-
-/*
- * Unknown Platform. Use out-of-line functions, which in turn use mutexes.
- *                   Slow but correct.
- */
-
-#define U_NO_PLATFORM_ATOMICS
-
-U_NAMESPACE_BEGIN
-typedef int32_t u_atomic_int32_t;
-#define ATOMIC_INT32_T_INITIALIZER(val) val
-
-U_COMMON_API int32_t U_EXPORT2 
-umtx_loadAcquire(u_atomic_int32_t &var);
-
-U_COMMON_API void U_EXPORT2 
-umtx_storeRelease(u_atomic_int32_t &var, int32_t val);
-
-U_COMMON_API int32_t U_EXPORT2 
-umtx_atomic_inc(u_atomic_int32_t *p);
-
-U_COMMON_API int32_t U_EXPORT2 
-umtx_atomic_dec(u_atomic_int32_t *p);
-
-U_NAMESPACE_END
-
-#endif  /* Low Level Atomic Ops Platfrom Chain */
-
 
 
 /*************************************************************************************************
  *
  *  UInitOnce Definitions.
- *     These are platform neutral.
  *
  *************************************************************************************************/
 
-U_NAMESPACE_BEGIN
-
 struct UInitOnce {
     u_atomic_int32_t   fState;
     UErrorCode       fErrCode;
-    void reset() {fState = 0;};
-    UBool isReset() {return umtx_loadAcquire(fState) == 0;};
+    void reset() {fState = 0;}
+    UBool isReset() {return umtx_loadAcquire(fState) == 0;}
 // Note: isReset() is used by service registration code.
 //                 Thread safety of this usage needs review.
 };
@@ -237,8 +111,7 @@
 U_COMMON_API UBool U_EXPORT2 umtx_initImplPreInit(UInitOnce &);
 U_COMMON_API void  U_EXPORT2 umtx_initImplPostInit(UInitOnce &);
 
-
-template<class T> void umtx_initOnce(UInitOnce &uio, T *obj, void (T::*fp)()) {
+template<class T> void umtx_initOnce(UInitOnce &uio, T *obj, void (U_CALLCONV T::*fp)()) {
     if (umtx_loadAcquire(uio.fState) == 2) {
         return;
     }
@@ -251,7 +124,7 @@
 
 // umtx_initOnce variant for plain functions, or static class functions.
 //               No context parameter.
-inline void umtx_initOnce(UInitOnce &uio, void (*fp)()) {
+inline void umtx_initOnce(UInitOnce &uio, void (U_CALLCONV *fp)()) {
     if (umtx_loadAcquire(uio.fState) == 2) {
         return;
     }
@@ -263,7 +136,7 @@
 
 // umtx_initOnce variant for plain functions, or static class functions.
 //               With ErrorCode, No context parameter.
-inline void umtx_initOnce(UInitOnce &uio, void (*fp)(UErrorCode &), UErrorCode &errCode) {
+inline void umtx_initOnce(UInitOnce &uio, void (U_CALLCONV *fp)(UErrorCode &), UErrorCode &errCode) {
     if (U_FAILURE(errCode)) {
         return;
     }
@@ -282,7 +155,7 @@
 
 // umtx_initOnce variant for plain functions, or static class functions,
 //               with a context parameter.
-template<class T> void umtx_initOnce(UInitOnce &uio, void (*fp)(T), T context) {
+template<class T> void umtx_initOnce(UInitOnce &uio, void (U_CALLCONV *fp)(T), T context) {
     if (umtx_loadAcquire(uio.fState) == 2) {
         return;
     }
@@ -294,7 +167,7 @@
 
 // umtx_initOnce variant for plain functions, or static class functions,
 //               with a context parameter and an error code.
-template<class T> void umtx_initOnce(UInitOnce &uio, void (*fp)(T, UErrorCode &), T context, UErrorCode &errCode) {
+template<class T> void umtx_initOnce(UInitOnce &uio, void (U_CALLCONV *fp)(T, UErrorCode &), T context, UErrorCode &errCode) {
     if (U_FAILURE(errCode)) {
         return;
     }
@@ -311,150 +184,94 @@
     }
 }
 
-U_NAMESPACE_END
-
-
-
-/*************************************************************************************************
- *
- *  Mutex Definitions. Platform Dependent, #if platform chain follows.
- *         TODO:  Add a C++11 version.
- *                Need to convert all mutex using files to C++ first.
- *
- *************************************************************************************************/
-
-#if defined(U_USER_MUTEX_H)
-// #inlcude "U_USER_MUTEX_H"
-#include U_MUTEX_XSTR(U_USER_MUTEX_H)
-
-#elif U_PLATFORM_HAS_WIN32_API
-
-/* Windows Definitions.
- *    Windows comes first in the platform chain.
- *    Cygwin (and possibly others) have both WIN32 and POSIX APIs. Prefer Win32 in this case.
- */
-
-
-/* For CRITICAL_SECTION */
-
-/*
- *   Note: there is an earlier include of windows.h in this file, but it is in
- *         different conditionals.
- *         This one is needed if we are using C++11 for atomic ops, but
- *         win32 APIs for Critical Sections.
- */
-
-# define WIN32_LEAN_AND_MEAN
-# define VC_EXTRALEAN
-# define NOUSER
-# define NOSERVICE
-# define NOIME
-# define NOMCX
-# ifndef NOMINMAX
-# define NOMINMAX
-# endif
-# include <windows.h>
-
-
-typedef struct UMutex {
-    icu::UInitOnce    fInitOnce;
-    CRITICAL_SECTION  fCS;
-} UMutex;
-
-/* Initializer for a static UMUTEX. Deliberately contains no value for the
- *  CRITICAL_SECTION.
- */
-#define U_MUTEX_INITIALIZER {U_INITONCE_INITIALIZER}
-
-struct UConditionVar {
-    HANDLE           fEntryGate;
-    HANDLE           fExitGate;
-    int32_t          fWaitCount;
-};
-
-#define U_CONDITION_INITIALIZER {NULL, NULL, 0}
-    
-
-
-#elif U_PLATFORM_IMPLEMENTS_POSIX
-
-/*
- *  POSIX platform
- */
-
-#include <pthread.h>
-
-struct UMutex {
-    pthread_mutex_t  fMutex;
-};
-typedef struct UMutex UMutex;
-#define U_MUTEX_INITIALIZER  {PTHREAD_MUTEX_INITIALIZER}
-
-struct UConditionVar {
-    pthread_cond_t   fCondition;
-};
-#define U_CONDITION_INITIALIZER {PTHREAD_COND_INITIALIZER}
-
+// UMutex should be constexpr-constructible, so that no initialization code
+// is run during startup.
+// This works on all C++ libraries except MS VS before VS2019.
+#if (defined(_CPPLIB_VER) && !defined(_MSVC_STL_VERSION)) || \
+    (defined(_MSVC_STL_VERSION) && _MSVC_STL_VERSION < 142)
+    // (VS std lib older than VS2017) || (VS std lib version < VS2019)
+#   define UMUTEX_CONSTEXPR
 #else
-
-/*
- *  Unknow platform type.
- *      This is an error condition. ICU requires mutexes.
- */
-
-#error Unknown Platform.
-
+#   define UMUTEX_CONSTEXPR constexpr
 #endif
 
-
-
-/**************************************************************************************
+/**
+ * UMutex - ICU Mutex class.
  *
- *  Mutex Implementation function declaratations.
- *     Declarations are platform neutral.
- *     Implementations, in umutex.cpp, are platform specific.
+ * This is the preferred Mutex class for use within ICU implementation code.
+ * It is a thin wrapper over C++ std::mutex, with these additions:
+ *    - Static instances are safe, not triggering static construction or destruction,
+ *      and the associated order of construction or destruction issues.
+ *    - Plumbed into u_cleanup() for destructing the underlying std::mutex,
+ *      which frees any OS level resources they may be holding.
  *
- ************************************************************************************/
+ * Limitations:
+ *    - Static or global instances only. Cannot be heap allocated. Cannot appear as a
+ *      member of another class.
+ *    - No condition variables or other advanced features. If needed, you will need to use
+ *      std::mutex and std::condition_variable directly. For an example, see unifiedcache.cpp
+ *
+ * Typical Usage:
+ *    static UMutex myMutex;
+ *
+ *    {
+ *       Mutex lock(myMutex);
+ *       ...    // Do stuff that is protected by myMutex;
+ *    }         // myMutex is released when lock goes out of scope.
+ */
+
+class U_COMMON_API UMutex {
+public:
+    UMUTEX_CONSTEXPR UMutex() {}
+    ~UMutex() = default;
+
+    UMutex(const UMutex &other) = delete;
+    UMutex &operator =(const UMutex &other) = delete;
+    void *operator new(size_t) = delete;
+
+    // requirements for C++ BasicLockable, allows UMutex to work with std::lock_guard
+    void lock() {
+        std::mutex *m = fMutex.load(std::memory_order_acquire);
+        if (m == nullptr) { m = getMutex(); }
+        m->lock();
+    }
+    void unlock() { fMutex.load(std::memory_order_relaxed)->unlock(); }
+
+    static void cleanup();
+
+private:
+    alignas(std::mutex) char fStorage[sizeof(std::mutex)] {};
+    std::atomic<std::mutex *> fMutex { nullptr };
+
+    /** All initialized UMutexes are kept in a linked list, so that they can be found,
+     * and the underlying std::mutex destructed, by u_cleanup().
+     */
+    UMutex *fListLink { nullptr };
+    static UMutex *gListHead;
+
+    /** Out-of-line function to lazily initialize a UMutex on first use.
+     * Initial fast check is inline, in lock().  The returned value may never
+     * be nullptr.
+     */
+    std::mutex *getMutex();
+};
+
 
 /* Lock a mutex.
  * @param mutex The given mutex to be locked.  Pass NULL to specify
  *              the global ICU mutex.  Recursive locks are an error
  *              and may cause a deadlock on some platforms.
  */
-U_INTERNAL void U_EXPORT2 umtx_lock(UMutex* mutex);
+U_CAPI void U_EXPORT2 umtx_lock(UMutex* mutex);
 
 /* Unlock a mutex.
  * @param mutex The given mutex to be unlocked.  Pass NULL to specify
  *              the global ICU mutex.
  */
-U_INTERNAL void U_EXPORT2 umtx_unlock (UMutex* mutex);
-
-/*
- * Wait on a condition variable.
- * The calling thread will unlock the mutex and wait on the condition variable.
- * The mutex must be locked by the calling thread when invoking this function.
- *
- * @param cond the condition variable to wait on.
- * @param mutex the associated mutex.
- */
-
-U_INTERNAL void U_EXPORT2 umtx_condWait(UConditionVar *cond, UMutex *mutex);
+U_CAPI void U_EXPORT2 umtx_unlock (UMutex* mutex);
 
 
-/*
- * Broadcast wakeup of all threads waiting on a Condition.
- * The associated mutex must be locked by the calling thread when calling
- * this function; this is a temporary ICU restriction.
- * 
- * @param cond the condition variable.
- */
-U_INTERNAL void U_EXPORT2 umtx_condBroadcast(UConditionVar *cond);
-
-/*
- * Signal a condition variable, waking up one waiting thread.
- * CAUTION: Do not use. Place holder only. Not implemented for Windows.
- */
-U_INTERNAL void U_EXPORT2 umtx_condSignal(UConditionVar *cond);
+U_NAMESPACE_END
 
 #endif /* UMUTEX_H */
 /*eof*/
diff --git a/src/third_party/icu/source/common/unames.cpp b/src/third_party/icu/source/common/unames.cpp
index c1f66a5..cc75bfd 100644
--- a/src/third_party/icu/source/common/unames.cpp
+++ b/src/third_party/icu/source/common/unames.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 ******************************************************************************
 *   file name:  unames.c
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -14,8 +16,10 @@
 *   created by: Markus W. Scherer
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/utypes.h"
 #include "unicode/putil.h"
 #include "unicode/uchar.h"
@@ -212,13 +216,13 @@
     return U_SUCCESS(*pErrorCode);
 }
 
-#define WRITE_CHAR(buffer, bufferLength, bufferPos, c) { \
+#define WRITE_CHAR(buffer, bufferLength, bufferPos, c) UPRV_BLOCK_MACRO_BEGIN { \
     if((bufferLength)>0) { \
         *(buffer)++=c; \
         --(bufferLength); \
     } \
     ++(bufferPos); \
-}
+} UPRV_BLOCK_MACRO_END
 
 #define U_ISO_COMMENT U_CHAR_NAME_CHOICE_COUNT
 
@@ -466,7 +470,7 @@
         buffer[--i] = (v < 10 ? '0' + v : 'A' + v - 10);
     }
     buffer += ndigits;
-    length += ndigits;
+    length += static_cast<uint16_t>(ndigits);
     WRITE_CHAR(buffer, bufferLength, length, '>');
 
     return length;
@@ -1519,14 +1523,15 @@
 u_charFromName(UCharNameChoice nameChoice,
                const char *name,
                UErrorCode *pErrorCode) {
-    char upper[120], lower[120];
+    char upper[120] = {0};
+    char lower[120] = {0};
     FindName findName;
     AlgorithmicRange *algRange;
     uint32_t *p;
     uint32_t i;
     UChar32 cp = 0;
     char c0;
-    UChar32 error = 0xffff;     /* Undefined, but use this for backwards compatibility. */
+    static constexpr UChar32 error = 0xffff;     /* Undefined, but use this for backwards compatibility. */
 
     if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
         return error;
@@ -1560,39 +1565,45 @@
 
     /* try extended names first */
     if (lower[0] == '<') {
-        if (nameChoice == U_EXTENDED_CHAR_NAME) {
+        if (nameChoice == U_EXTENDED_CHAR_NAME && lower[--i] == '>') {
             // Parse a string like "<category-HHHH>" where HHHH is a hex code point.
-            if (lower[--i] == '>' && i >= 3 && lower[--i] != '-') {
-                while (i >= 3 && lower[--i] != '-') {}
+            uint32_t limit = i;
+            while (i >= 3 && lower[--i] != '-') {}
 
-                if (i >= 2 && lower[i] == '-') {
-                    uint32_t cIdx;
+            // There should be 1 to 8 hex digits.
+            int32_t hexLength = limit - (i + 1);
+            if (i >= 2 && lower[i] == '-' && 1 <= hexLength && hexLength <= 8) {
+                uint32_t cIdx;
 
-                    lower[i] = 0;
+                lower[i] = 0;
 
-                    for (++i; lower[i] != '>'; ++i) {
-                        if (lower[i] >= '0' && lower[i] <= '9') {
-                            cp = (cp << 4) + lower[i] - '0';
-                        } else if (lower[i] >= 'a' && lower[i] <= 'f') {
-                            cp = (cp << 4) + lower[i] - 'a' + 10;
-                        } else {
-                            *pErrorCode = U_ILLEGAL_CHAR_FOUND;
-                            return error;
-                        }
+                for (++i; i < limit; ++i) {
+                    if (lower[i] >= '0' && lower[i] <= '9') {
+                        cp = (cp << 4) + lower[i] - '0';
+                    } else if (lower[i] >= 'a' && lower[i] <= 'f') {
+                        cp = (cp << 4) + lower[i] - 'a' + 10;
+                    } else {
+                        *pErrorCode = U_ILLEGAL_CHAR_FOUND;
+                        return error;
                     }
+                    // Prevent signed-integer overflow and out-of-range code points.
+                    if (cp > UCHAR_MAX_VALUE) {
+                        *pErrorCode = U_ILLEGAL_CHAR_FOUND;
+                        return error;
+                    }
+                }
 
-                    /* Now validate the category name.
-                       We could use a binary search, or a trie, if
-                       we really wanted to. */
+                /* Now validate the category name.
+                   We could use a binary search, or a trie, if
+                   we really wanted to. */
+                uint8_t cat = getCharCat(cp);
+                for (lower[i] = 0, cIdx = 0; cIdx < UPRV_LENGTHOF(charCatNames); ++cIdx) {
 
-                    for (lower[i] = 0, cIdx = 0; cIdx < UPRV_LENGTHOF(charCatNames); ++cIdx) {
-
-                        if (!uprv_strcmp(lower + 1, charCatNames[cIdx])) {
-                            if (getCharCat(cp) == cIdx) {
-                                return cp;
-                            }
-                            break;
+                    if (!uprv_strcmp(lower + 1, charCatNames[cIdx])) {
+                        if (cat == cIdx) {
+                            return cp;
                         }
+                        break;
                     }
                 }
             }
diff --git a/src/third_party/icu/source/common/unicode/appendable.h b/src/third_party/icu/source/common/unicode/appendable.h
index a6a83b1..fc99254 100644
--- a/src/third_party/icu/source/common/unicode/appendable.h
+++ b/src/third_party/icu/source/common/unicode/appendable.h
@@ -1,10 +1,12 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *   Copyright (C) 2011-2012, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *******************************************************************************
 *   file name:  appendable.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -17,10 +19,13 @@
 
 /**
  * \file
- * \brief C++ API: Appendable class: Sink for Unicode code points and 16-bit code units (UChars).
+ * \brief C++ API: Appendable class: Sink for Unicode code points and 16-bit code units (char16_ts).
  */
 
 #include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
 #include "unicode/uobject.h"
 
 U_NAMESPACE_BEGIN
@@ -32,15 +37,15 @@
  * Combines elements of Java Appendable and ICU4C ByteSink.
  *
  * This class can be used in APIs where it does not matter whether the actual destination is
- * a UnicodeString, a UChar[] array, a UnicodeSet, or any other object
+ * a UnicodeString, a char16_t[] array, a UnicodeSet, or any other object
  * that receives and processes characters and/or strings.
  *
- * Implementation classes must implement at least appendCodeUnit(UChar).
+ * Implementation classes must implement at least appendCodeUnit(char16_t).
  * The base class provides default implementations for the other methods.
  *
  * The methods do not take UErrorCode parameters.
  * If an error occurs (e.g., out-of-memory),
- * in addition to returning FALSE from failing operations,
+ * in addition to returning false from failing operations,
  * the implementation must prevent unexpected behavior (e.g., crashes)
  * from further calls and should make the error condition available separately
  * (e.g., store a UErrorCode, make/keep a UnicodeString bogus).
@@ -57,37 +62,37 @@
     /**
      * Appends a 16-bit code unit.
      * @param c code unit
-     * @return TRUE if the operation succeeded
+     * @return true if the operation succeeded
      * @stable ICU 4.8
      */
-    virtual UBool appendCodeUnit(UChar c) = 0;
+    virtual UBool appendCodeUnit(char16_t c) = 0;
 
     /**
      * Appends a code point.
-     * The default implementation calls appendCodeUnit(UChar) once or twice.
+     * The default implementation calls appendCodeUnit(char16_t) once or twice.
      * @param c code point 0..0x10ffff
-     * @return TRUE if the operation succeeded
+     * @return true if the operation succeeded
      * @stable ICU 4.8
      */
     virtual UBool appendCodePoint(UChar32 c);
 
     /**
      * Appends a string.
-     * The default implementation calls appendCodeUnit(UChar) for each code unit.
+     * The default implementation calls appendCodeUnit(char16_t) for each code unit.
      * @param s string, must not be NULL if length!=0
      * @param length string length, or -1 if NUL-terminated
-     * @return TRUE if the operation succeeded
+     * @return true if the operation succeeded
      * @stable ICU 4.8
      */
-    virtual UBool appendString(const UChar *s, int32_t length);
+    virtual UBool appendString(const char16_t *s, int32_t length);
 
     /**
      * Tells the object that the caller is going to append roughly
-     * appendCapacity UChars. A subclass might use this to pre-allocate
+     * appendCapacity char16_ts. A subclass might use this to pre-allocate
      * a larger buffer if necessary.
-     * The default implementation does nothing. (It always returns TRUE.)
-     * @param appendCapacity estimated number of UChars that will be appended
-     * @return TRUE if the operation succeeded
+     * The default implementation does nothing. (It always returns true.)
+     * @param appendCapacity estimated number of char16_ts that will be appended
+     * @return true if the operation succeeded
      * @stable ICU 4.8
      */
     virtual UBool reserveAppendCapacity(int32_t appendCapacity);
@@ -100,19 +105,19 @@
      * The returned buffer is only valid until the next operation
      * on this Appendable.
      *
-     * After writing at most *resultCapacity UChars, call appendString() with the
-     * pointer returned from this function and the number of UChars written.
-     * Many appendString() implementations will avoid copying UChars if this function
+     * After writing at most *resultCapacity char16_ts, call appendString() with the
+     * pointer returned from this function and the number of char16_ts written.
+     * Many appendString() implementations will avoid copying char16_ts if this function
      * returned an internal buffer.
      *
      * Partial usage example:
      * \code
      *  int32_t capacity;
-     *  UChar* buffer = app.getAppendBuffer(..., &capacity);
-     *  ... Write n UChars into buffer, with n <= capacity.
+     *  char16_t* buffer = app.getAppendBuffer(..., &capacity);
+     *  ... Write n char16_ts into buffer, with n <= capacity.
      *  app.appendString(buffer, n);
      * \endcode
-     * In many implementations, that call to append will avoid copying UChars.
+     * In many implementations, that call to append will avoid copying char16_ts.
      *
      * If the Appendable allocates or reallocates an internal buffer, it should use
      * the desiredCapacityHint if appropriate.
@@ -136,9 +141,9 @@
      * @return a buffer with *resultCapacity>=minCapacity
      * @stable ICU 4.8
      */
-    virtual UChar *getAppendBuffer(int32_t minCapacity,
+    virtual char16_t *getAppendBuffer(int32_t minCapacity,
                                    int32_t desiredCapacityHint,
-                                   UChar *scratch, int32_t scratchCapacity,
+                                   char16_t *scratch, int32_t scratchCapacity,
                                    int32_t *resultCapacity);
 };
 
@@ -166,15 +171,15 @@
     /**
      * Appends a 16-bit code unit to the string.
      * @param c code unit
-     * @return TRUE if the operation succeeded
+     * @return true if the operation succeeded
      * @stable ICU 4.8
      */
-    virtual UBool appendCodeUnit(UChar c);
+    virtual UBool appendCodeUnit(char16_t c);
 
     /**
      * Appends a code point to the string.
      * @param c code point 0..0x10ffff
-     * @return TRUE if the operation succeeded
+     * @return true if the operation succeeded
      * @stable ICU 4.8
      */
     virtual UBool appendCodePoint(UChar32 c);
@@ -183,16 +188,16 @@
      * Appends a string to the UnicodeString.
      * @param s string, must not be NULL if length!=0
      * @param length string length, or -1 if NUL-terminated
-     * @return TRUE if the operation succeeded
+     * @return true if the operation succeeded
      * @stable ICU 4.8
      */
-    virtual UBool appendString(const UChar *s, int32_t length);
+    virtual UBool appendString(const char16_t *s, int32_t length);
 
     /**
      * Tells the UnicodeString that the caller is going to append roughly
-     * appendCapacity UChars.
-     * @param appendCapacity estimated number of UChars that will be appended
-     * @return TRUE if the operation succeeded
+     * appendCapacity char16_ts.
+     * @param appendCapacity estimated number of char16_ts that will be appended
+     * @return true if the operation succeeded
      * @stable ICU 4.8
      */
     virtual UBool reserveAppendCapacity(int32_t appendCapacity);
@@ -218,9 +223,9 @@
      * @return a buffer with *resultCapacity>=minCapacity
      * @stable ICU 4.8
      */
-    virtual UChar *getAppendBuffer(int32_t minCapacity,
+    virtual char16_t *getAppendBuffer(int32_t minCapacity,
                                    int32_t desiredCapacityHint,
-                                   UChar *scratch, int32_t scratchCapacity,
+                                   char16_t *scratch, int32_t scratchCapacity,
                                    int32_t *resultCapacity);
 
 private:
@@ -229,4 +234,6 @@
 
 U_NAMESPACE_END
 
+#endif /* U_SHOW_CPLUSPLUS_API */
+
 #endif  // __APPENDABLE_H__
diff --git a/src/third_party/icu/source/common/unicode/brkiter.h b/src/third_party/icu/source/common/unicode/brkiter.h
index 4aa5e55..9bba5fc 100644
--- a/src/third_party/icu/source/common/unicode/brkiter.h
+++ b/src/third_party/icu/source/common/unicode/brkiter.h
@@ -1,6 +1,8 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ********************************************************************************
-*   Copyright (C) 1997-2014, International Business Machines
+*   Copyright (C) 1997-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 ********************************************************************************
 *
@@ -27,6 +29,10 @@
  * \brief C++ API: Break Iterator.
  */
 
+#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
 #if UCONFIG_NO_BREAK_ITERATION
 
 U_NAMESPACE_BEGIN
@@ -133,7 +139,7 @@
      * method which subclasses implement.
      * @stable ICU 2.0
      */
-    virtual BreakIterator* clone(void) const = 0;
+    virtual BreakIterator* clone() const = 0;
 
     /**
      * Return a polymorphic class ID for this object. Different subclasses
@@ -168,6 +174,11 @@
     /**
      * Change the text over which this operates. The text boundary is
      * reset to the start.
+     *
+     * The BreakIterator will retain a reference to the supplied string.
+     * The caller must not modify or delete the text while the BreakIterator
+     * retains the reference.
+     *
      * @param text The UnicodeString used to change the text.
      * @stable ICU 2.0
      */
@@ -243,7 +254,7 @@
     virtual int32_t next(void) = 0;
 
     /**
-     * Return character index of the current interator position within the text.
+     * Return character index of the current iterator position within the text.
      * @return The boundary most recently returned.
      * @stable ICU 2.0
      */
@@ -270,7 +281,7 @@
     virtual int32_t preceding(int32_t offset) = 0;
 
     /**
-     * Return true if the specfied position is a boundary position.
+     * Return true if the specified position is a boundary position.
      * As a side effect, the current position of the iterator is set
      * to the first boundary position at or following the specified offset.
      * @param offset the offset to check.
@@ -285,21 +296,20 @@
      * does nothing.  Negative values move to previous boundaries
      * and positive values move to later boundaries.
      * @return The new iterator position, or
-     * DONE if there are fewer than |n| boundaries in the specfied direction.
+     * DONE if there are fewer than |n| boundaries in the specified direction.
      * @stable ICU 2.0
      */
     virtual int32_t next(int32_t n) = 0;
 
    /**
-     * For RuleBasedBreakIterators, return the status tag from the 
-     * break rule that determined the most recently
-     * returned break position.
+     * For RuleBasedBreakIterators, return the status tag from the break rule
+     * that determined the boundary at the current iteration position.
      * <p>
      * For break iterator types that do not support a rule status,
      * a default value of 0 is returned.
      * <p>
-     * @return the status from the break rule that determined the most recently
-     *         returned break position.
+     * @return the status from the break rule that determined the boundary at
+     *         the current iteration position.
      * @see RuleBaseBreakIterator::getRuleStatus()
      * @see UWordBreak
      * @stable ICU 52
@@ -307,8 +317,8 @@
     virtual int32_t getRuleStatus() const;
 
    /**
-    * For RuleBasedBreakIterators, get the status (tag) values from the break rule(s) 
-    * that determined the most recently returned break position.
+    * For RuleBasedBreakIterators, get the status (tag) values from the break rule(s)
+    * that determined the boundary at the current iteration position.
     * <p>
     * For break iterator types that do not support rule status,
     * no values are returned.
@@ -324,10 +334,10 @@
     * @param fillInVec an array to be filled in with the status values.
     * @param capacity  the length of the supplied vector.  A length of zero causes
     *                  the function to return the number of status values, in the
-    *                  normal way, without attemtping to store any values.
+    *                  normal way, without attempting to store any values.
     * @param status    receives error codes.
     * @return          The number of rule status values from rules that determined
-    *                  the most recent boundary returned by the break iterator.
+    *                  the boundary at the current iteration position.
     *                  In the event of a U_BUFFER_OVERFLOW_ERROR, the return value
     *                  is the total number of status values that were available,
     *                  not the reduced number that were actually returned.
@@ -425,12 +435,13 @@
     static BreakIterator* U_EXPORT2
     createSentenceInstance(const Locale& where, UErrorCode& status);
 
+#ifndef U_HIDE_DEPRECATED_API
     /**
      * Create BreakIterator for title-casing breaks using the specified locale
      * Returns an instance of a BreakIterator implementing title breaks.
      * The iterator returned locates title boundaries as described for
      * Unicode 3.2 only. For Unicode 4.0 and above title boundary iteration,
-     * please use Word Boundary iterator.{@link #createWordInstance }
+     * please use a word boundary iterator. See {@link #createWordInstance }.
      *
      * @param where the locale.
      * @param status The error code.
@@ -445,10 +456,11 @@
      * used; neither the requested locale nor any of its fall back locales
      * could be found.
      * The caller owns the returned object and is responsible for deleting it.
-     * @stable ICU 2.1
+     * @deprecated ICU 64 Use createWordInstance instead.
      */
     static BreakIterator* U_EXPORT2
     createTitleInstance(const Locale& where, UErrorCode& status);
+#endif /* U_HIDE_DEPRECATED_API */
 
     /**
      * Get the set of Locales for which TextBoundaries are installed.
@@ -462,7 +474,7 @@
     static const Locale* U_EXPORT2 getAvailableLocales(int32_t& count);
 
     /**
-     * Get name of the object for the desired Locale, in the desired langauge.
+     * Get name of the object for the desired Locale, in the desired language.
      * @param objectLocale must be from getAvailableLocales.
      * @param displayLocale specifies the desired locale for output.
      * @param name the fill-in parameter of the return value
@@ -475,7 +487,7 @@
                                          UnicodeString& name);
 
     /**
-     * Get name of the object for the desired Locale, in the langauge of the
+     * Get name of the object for the desired Locale, in the language of the
      * default locale.
      * @param objectLocale must be from getMatchingLocales
      * @param name the fill-in parameter of the return value
@@ -485,6 +497,7 @@
     static UnicodeString& U_EXPORT2 getDisplayName(const Locale& objectLocale,
                                          UnicodeString& name);
 
+#ifndef U_FORCE_HIDE_DEPRECATED_API
     /**
      * Deprecated functionality. Use clone() instead.
      *
@@ -507,6 +520,7 @@
     virtual BreakIterator *  createBufferClone(void *stackBuffer,
                                                int32_t &BufferSize,
                                                UErrorCode &status) = 0;
+#endif  // U_FORCE_HIDE_DEPRECATED_API
 
 #ifndef U_HIDE_DEPRECATED_API
 
@@ -550,7 +564,7 @@
      * BreakIterator::createXXXInstance to avoid undefined behavior.
      * @param key the registry key returned by a previous call to registerInstance
      * @param status the in/out status code, no special meanings are assigned
-     * @return TRUE if the iterator for the key was successfully unregistered
+     * @return true if the iterator for the key was successfully unregistered
      * @stable ICU 2.4
      */
     static UBool U_EXPORT2 unregister(URegistryKey key, UErrorCode& status);
@@ -609,7 +623,7 @@
     virtual BreakIterator &refreshInputText(UText *input, UErrorCode &status) = 0;
 
  private:
-    static BreakIterator* buildInstance(const Locale& loc, const char *type, int32_t kind, UErrorCode& status);
+    static BreakIterator* buildInstance(const Locale& loc, const char *type, UErrorCode& status);
     static BreakIterator* createInstance(const Locale& loc, int32_t kind, UErrorCode& status);
     static BreakIterator* makeInstance(const Locale& loc, int32_t kind, UErrorCode& status);
 
@@ -622,27 +636,26 @@
     /** @internal */
     BreakIterator();
     /** @internal */
-    BreakIterator (const BreakIterator &other) : UObject(other) {}
+    BreakIterator (const BreakIterator &other);
+#ifndef U_HIDE_INTERNAL_API
     /** @internal */
-    BreakIterator (const Locale& valid, const Locale& actual);
+    BreakIterator (const Locale& valid, const Locale &actual);
+    /** @internal. Assignment Operator, used by RuleBasedBreakIterator. */
+    BreakIterator &operator = (const BreakIterator &other);
+#endif  /* U_HIDE_INTERNAL_API */
+
 private:
 
-    /** @internal */
+    /** @internal (private) */
     char actualLocale[ULOC_FULLNAME_CAPACITY];
     char validLocale[ULOC_FULLNAME_CAPACITY];
-
-    /**
-     * The assignment operator has no real implementation.
-     * It's provided to make the compiler happy. Do not call.
-     */
-    BreakIterator& operator=(const BreakIterator&);
 };
 
 #ifndef U_HIDE_DEPRECATED_API
 
 inline UBool BreakIterator::isBufferClone()
 {
-    return FALSE;
+    return false;
 }
 
 #endif /* U_HIDE_DEPRECATED_API */
@@ -651,5 +664,7 @@
 
 #endif /* #if !UCONFIG_NO_BREAK_ITERATION */
 
-#endif // _BRKITER
+#endif /* U_SHOW_CPLUSPLUS_API */
+
+#endif // BRKITER_H
 //eof
diff --git a/src/third_party/icu/source/common/unicode/bytestream.h b/src/third_party/icu/source/common/unicode/bytestream.h
index 129629c..d030704 100644
--- a/src/third_party/icu/source/common/unicode/bytestream.h
+++ b/src/third_party/icu/source/common/unicode/bytestream.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 // Copyright (C) 2009-2012, International Business Machines
 // Corporation and others. All Rights Reserved.
 //
@@ -36,6 +38,9 @@
  */
 
 #include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
 #include "unicode/uobject.h"
 #include "unicode/std_string.h"
 
@@ -66,6 +71,40 @@
    */
   virtual void Append(const char* bytes, int32_t n) = 0;
 
+#ifndef U_HIDE_DRAFT_API
+  /**
+   * Appends n bytes to this. Same as Append().
+   * Call AppendU8() with u8"string literals" which are const char * in C++11
+   * but const char8_t * in C++20.
+   * If the compiler does support char8_t as a distinct type,
+   * then an AppendU8() overload for that is defined and will be chosen.
+   *
+   * @param bytes the pointer to the bytes
+   * @param n the number of bytes; must be non-negative
+   * @draft ICU 67
+   */
+  inline void AppendU8(const char* bytes, int32_t n) {
+    Append(bytes, n);
+  }
+
+#if defined(__cpp_char8_t) || defined(U_IN_DOXYGEN)
+  /**
+   * Appends n bytes to this. Same as Append() but for a const char8_t * pointer.
+   * Call AppendU8() with u8"string literals" which are const char * in C++11
+   * but const char8_t * in C++20.
+   * If the compiler does support char8_t as a distinct type,
+   * then this AppendU8() overload for that is defined and will be chosen.
+   *
+   * @param bytes the pointer to the bytes
+   * @param n the number of bytes; must be non-negative
+   * @draft ICU 67
+   */
+  inline void AppendU8(const char8_t* bytes, int32_t n) {
+    Append(reinterpret_cast<const char*>(bytes), n);
+  }
+#endif
+#endif  // U_HIDE_DRAFT_API
+
   /**
    * Returns a writable buffer for appending and writes the buffer's capacity to
    * *result_capacity. Guarantees *result_capacity>=min_capacity.
@@ -124,8 +163,8 @@
   virtual void Flush();
 
 private:
-  ByteSink(const ByteSink &); // copy constructor not implemented
-  ByteSink &operator=(const ByteSink &); // assignment operator not implemented
+  ByteSink(const ByteSink &) = delete;
+  ByteSink &operator=(const ByteSink &) = delete;
 };
 
 // -------------------------------------------------------------
@@ -158,7 +197,7 @@
    * Returns the sink to its original state, without modifying the buffer.
    * Useful for reusing both the buffer and the sink for multiple streams.
    * Resets the state to NumberOfBytesWritten()=NumberOfBytesAppended()=0
-   * and Overflowed()=FALSE.
+   * and Overflowed()=false.
    * @return *this
    * @stable ICU 4.6
    */
@@ -197,7 +236,7 @@
   /**
    * Returns true if any bytes were discarded, i.e., if there was an
    * attempt to write more than 'capacity' bytes.
-   * @return TRUE if more than 'capacity' bytes were Append()ed
+   * @return true if more than 'capacity' bytes were Append()ed
    * @stable ICU 4.2
    */
   UBool Overflowed() const { return overflowed_; }
@@ -215,12 +254,11 @@
   int32_t size_;
   int32_t appended_;
   UBool overflowed_;
-  CheckedArrayByteSink(); ///< default constructor not implemented 
-  CheckedArrayByteSink(const CheckedArrayByteSink &); ///< copy constructor not implemented
-  CheckedArrayByteSink &operator=(const CheckedArrayByteSink &); ///< assignment operator not implemented
-};
 
-#if U_HAVE_STD_STRING
+  CheckedArrayByteSink() = delete;
+  CheckedArrayByteSink(const CheckedArrayByteSink &) = delete;
+  CheckedArrayByteSink &operator=(const CheckedArrayByteSink &) = delete;
+};
 
 /** 
  * Implementation of ByteSink that writes to a "string".
@@ -237,6 +275,19 @@
    */
   StringByteSink(StringClass* dest) : dest_(dest) { }
   /**
+   * Constructs a ByteSink that reserves append capacity and will append bytes to the dest string.
+   * 
+   * @param dest pointer to string object to append to
+   * @param initialAppendCapacity capacity beyond dest->length() to be reserve()d
+   * @stable ICU 60
+   */
+  StringByteSink(StringClass* dest, int32_t initialAppendCapacity) : dest_(dest) {
+    if (initialAppendCapacity > 0 &&
+        (uint32_t)initialAppendCapacity > (dest->capacity() - dest->length())) {
+      dest->reserve(dest->length() + initialAppendCapacity);
+    }
+  }
+  /**
    * Append "bytes[0,n-1]" to this.
    * @param data the pointer to the bytes
    * @param n the number of bytes; must be non-negative
@@ -247,13 +298,14 @@
   }
  private:
   StringClass* dest_;
-  StringByteSink(); ///< default constructor not implemented 
-  StringByteSink(const StringByteSink &); ///< copy constructor not implemented
-  StringByteSink &operator=(const StringByteSink &); ///< assignment operator not implemented
+
+  StringByteSink() = delete;
+  StringByteSink(const StringByteSink &) = delete;
+  StringByteSink &operator=(const StringByteSink &) = delete;
 };
 
-#endif
-
 U_NAMESPACE_END
 
+#endif /* U_SHOW_CPLUSPLUS_API */
+
 #endif  // __BYTESTREAM_H__
diff --git a/src/third_party/icu/source/common/unicode/bytestrie.h b/src/third_party/icu/source/common/unicode/bytestrie.h
index 9c77827..85f802d 100644
--- a/src/third_party/icu/source/common/unicode/bytestrie.h
+++ b/src/third_party/icu/source/common/unicode/bytestrie.h
@@ -1,10 +1,12 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *   Copyright (C) 2010-2012, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *******************************************************************************
 *   file name:  bytestrie.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -21,6 +23,9 @@
  */
 
 #include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
 #include "unicode/stringpiece.h"
 #include "unicode/uobject.h"
 #include "unicode/ustringtrie.h"
@@ -93,6 +98,39 @@
     }
 
     /**
+     * Returns the state of this trie as a 64-bit integer.
+     * The state value is never 0.
+     *
+     * @return opaque state value
+     * @see resetToState64
+     * @stable ICU 65
+     */
+    uint64_t getState64() const {
+        return (static_cast<uint64_t>(remainingMatchLength_ + 2) << kState64RemainingShift) |
+            (uint64_t)(pos_ - bytes_);
+    }
+
+    /**
+     * Resets this trie to the saved state.
+     * Unlike resetToState(State), the 64-bit state value
+     * must be from getState64() from the same trie object or
+     * from one initialized the exact same way.
+     * Because of no validation, this method is faster.
+     *
+     * @param state The opaque trie state value from getState64().
+     * @return *this
+     * @see getState64
+     * @see resetToState
+     * @see reset
+     * @stable ICU 65
+     */
+    BytesTrie &resetToState64(uint64_t state) {
+        remainingMatchLength_ = static_cast<int32_t>(state >> kState64RemainingShift) - 2;
+        pos_ = bytes_ + (state & kState64PosMask);
+        return *this;
+    }
+
+    /**
      * BytesTrie state object, for saving a trie's current state
      * and resetting the trie back to this state later.
      * @stable ICU 4.8
@@ -213,16 +251,16 @@
     /**
      * Determines whether all byte sequences reachable from the current state
      * map to the same value.
-     * @param uniqueValue Receives the unique value, if this function returns TRUE.
+     * @param uniqueValue Receives the unique value, if this function returns true.
      *                    (output-only)
-     * @return TRUE if all byte sequences reachable from the current state
+     * @return true if all byte sequences reachable from the current state
      *         map to the same value.
      * @stable ICU 4.8
      */
     inline UBool hasUniqueValue(int32_t &uniqueValue) const {
         const uint8_t *pos=pos_;
         // Skip the rest of a pending linear-match node.
-        return pos!=NULL && findUniqueValue(pos+remainingMatchLength_+1, FALSE, uniqueValue);
+        return pos!=NULL && findUniqueValue(pos+remainingMatchLength_+1, false, uniqueValue);
     }
 
     /**
@@ -281,7 +319,7 @@
         Iterator &reset();
 
         /**
-         * @return TRUE if there are more elements.
+         * @return true if there are more elements.
          * @stable ICU 4.8
          */
         UBool hasNext() const;
@@ -297,7 +335,7 @@
          *                  pass the U_SUCCESS() test, or else the function returns
          *                  immediately. Check for U_FAILURE() on output or use with
          *                  function chaining. (See User Guide for details.)
-         * @return TRUE if there is another element.
+         * @return true if there is another element.
          * @stable ICU 4.8
          */
         UBool next(UErrorCode &errorCode);
@@ -306,7 +344,7 @@
          * @return The NUL-terminated byte sequence for the last successful next().
          * @stable ICU 4.8
          */
-        const StringPiece &getString() const { return sp_; }
+        StringPiece getString() const;
         /**
          * @return The value for the last successful next().
          * @stable ICU 4.8
@@ -325,7 +363,6 @@
         int32_t initialRemainingMatchLength_;
 
         CharString *str_;
-        StringPiece sp_;
         int32_t maxLength_;
         int32_t value_;
 
@@ -501,6 +538,13 @@
     static const int32_t kMaxTwoByteDelta=((kMinThreeByteDeltaLead-kMinTwoByteDeltaLead)<<8)-1;  // 0x2fff
     static const int32_t kMaxThreeByteDelta=((kFourByteDeltaLead-kMinThreeByteDeltaLead)<<16)-1;  // 0xdffff
 
+    // For getState64():
+    // The remainingMatchLength_ is -1..14=(kMaxLinearMatchLength=0x10)-2
+    // so we need at least 5 bits for that.
+    // We add 2 to store it as a positive value 1..16=kMaxLinearMatchLength.
+    static constexpr int32_t kState64RemainingShift = 59;
+    static constexpr uint64_t kState64PosMask = (UINT64_C(1) << kState64RemainingShift) - 1;
+
     uint8_t *ownedArray_;
 
     // Fixed value referencing the BytesTrie bytes.
@@ -516,4 +560,6 @@
 
 U_NAMESPACE_END
 
+#endif /* U_SHOW_CPLUSPLUS_API */
+
 #endif  // __BYTESTRIE_H__
diff --git a/src/third_party/icu/source/common/unicode/bytestriebuilder.h b/src/third_party/icu/source/common/unicode/bytestriebuilder.h
index d00ab9b..cae16e4 100644
--- a/src/third_party/icu/source/common/unicode/bytestriebuilder.h
+++ b/src/third_party/icu/source/common/unicode/bytestriebuilder.h
@@ -1,10 +1,12 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
-*   Copyright (C) 2010-2014, International Business Machines
+*   Copyright (C) 2010-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *******************************************************************************
 *   file name:  bytestriebuilder.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -21,6 +23,9 @@
 #define __BYTESTRIEBUILDER_H__
 
 #include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
 #include "unicode/bytestrie.h"
 #include "unicode/stringpiece.h"
 #include "unicode/stringtriebuilder.h"
@@ -29,7 +34,6 @@
 
 class BytesTrieElement;
 class CharString;
-
 /**
  * Builder class for BytesTrie.
  *
@@ -65,7 +69,7 @@
      * @return *this
      * @stable ICU 4.8
      */
-    BytesTrieBuilder &add(const StringPiece &s, int32_t value, UErrorCode &errorCode);
+    BytesTrieBuilder &add(StringPiece s, int32_t value, UErrorCode &errorCode);
 
     /**
      * Builds a BytesTrie for the add()ed data.
@@ -97,9 +101,10 @@
      * Multiple calls to buildStringPiece() return StringPieces referring to the
      * builder's same byte array, without rebuilding.
      * If buildStringPiece() is called after build(), the trie will be
-     * re-serialized into a new array.
-     * If build() is called after buildStringPiece(), the trie object will become
-     * the owner of the previously returned array.
+     * re-serialized into a new array (because build() passes on ownership).
+     * If build() is called after buildStringPiece(), the trie object returned
+     * by build() will become the owner of the underlying string for the
+     * previously returned StringPiece.
      * After clear() has been called, a new array will be used as well.
      * @param buildOption Build option, see UStringTrieBuildOption.
      * @param errorCode Standard ICU error code. Its input value must
@@ -126,23 +131,23 @@
     void buildBytes(UStringTrieBuildOption buildOption, UErrorCode &errorCode);
 
     virtual int32_t getElementStringLength(int32_t i) const;
-    virtual UChar getElementUnit(int32_t i, int32_t byteIndex) const;
+    virtual char16_t getElementUnit(int32_t i, int32_t byteIndex) const;
     virtual int32_t getElementValue(int32_t i) const;
 
     virtual int32_t getLimitOfLinearMatch(int32_t first, int32_t last, int32_t byteIndex) const;
 
     virtual int32_t countElementUnits(int32_t start, int32_t limit, int32_t byteIndex) const;
     virtual int32_t skipElementsBySomeUnits(int32_t i, int32_t byteIndex, int32_t count) const;
-    virtual int32_t indexOfElementWithNextUnit(int32_t i, int32_t byteIndex, UChar byte) const;
+    virtual int32_t indexOfElementWithNextUnit(int32_t i, int32_t byteIndex, char16_t byte) const;
 
-    virtual UBool matchNodesCanHaveValues() const { return FALSE; }
+    virtual UBool matchNodesCanHaveValues() const { return false; }
 
     virtual int32_t getMaxBranchLinearSubNodeLength() const { return BytesTrie::kMaxBranchLinearSubNodeLength; }
     virtual int32_t getMinLinearMatch() const { return BytesTrie::kMinLinearMatch; }
     virtual int32_t getMaxLinearMatchLength() const { return BytesTrie::kMaxLinearMatchLength; }
 
     /**
-     * @internal
+     * @internal (private)
      */
     class BTLinearMatchNode : public LinearMatchNode {
     public:
@@ -152,7 +157,7 @@
     private:
         const char *s;
     };
-
+    
     virtual Node *createLinearMatchNode(int32_t i, int32_t byteIndex, int32_t length,
                                         Node *nextNode) const;
 
@@ -178,4 +183,6 @@
 
 U_NAMESPACE_END
 
+#endif /* U_SHOW_CPLUSPLUS_API */
+
 #endif  // __BYTESTRIEBUILDER_H__
diff --git a/src/third_party/icu/source/common/unicode/caniter.h b/src/third_party/icu/source/common/unicode/caniter.h
index 3bd79f7..4ed2b74 100644
--- a/src/third_party/icu/source/common/unicode/caniter.h
+++ b/src/third_party/icu/source/common/unicode/caniter.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
  *******************************************************************************
  * Copyright (C) 1996-2014, International Business Machines Corporation and
@@ -10,6 +12,8 @@
 
 #include "unicode/utypes.h"
 
+#if U_SHOW_CPLUSPLUS_API
+
 #if !UCONFIG_NO_NORMALIZATION
 
 #include "unicode/uobject.h"
@@ -21,11 +25,11 @@
  */
  
 /** Should permutation skip characters with combining class zero
- *  Should be either TRUE or FALSE. This is a compile time option
+ *  Should be either true or false. This is a compile time option
  *  @stable ICU 2.4
  */
 #ifndef CANITER_SKIP_ZEROES
-#define CANITER_SKIP_ZEROES TRUE
+#define CANITER_SKIP_ZEROES true
 #endif
 
 U_NAMESPACE_BEGIN
@@ -151,13 +155,13 @@
 
     /**
      * Copy constructor. Private for now.
-     * @internal
+     * @internal (private)
      */
     CanonicalIterator(const CanonicalIterator& other);
 
     /**
      * Assignment operator. Private for now.
-     * @internal
+     * @internal (private)
      */
     CanonicalIterator& operator=(const CanonicalIterator& other);
 
@@ -185,7 +189,7 @@
     UnicodeString *getEquivalents(const UnicodeString &segment, int32_t &result_len, UErrorCode &status); //private String[] getEquivalents(String segment)
 
     //Set getEquivalents2(String segment);
-    Hashtable *getEquivalents2(Hashtable *fillinResult, const UChar *segment, int32_t segLen, UErrorCode &status);
+    Hashtable *getEquivalents2(Hashtable *fillinResult, const char16_t *segment, int32_t segLen, UErrorCode &status);
     //Hashtable *getEquivalents2(const UnicodeString &segment, int32_t segLen, UErrorCode &status);
 
     /**
@@ -194,7 +198,7 @@
      * If so, take the remainder, and return the equivalents
      */
     //Set extract(int comp, String segment, int segmentPos, StringBuffer buffer);
-    Hashtable *extract(Hashtable *fillinResult, UChar32 comp, const UChar *segment, int32_t segLen, int32_t segmentPos, UErrorCode &status);
+    Hashtable *extract(Hashtable *fillinResult, UChar32 comp, const char16_t *segment, int32_t segLen, int32_t segmentPos, UErrorCode &status);
     //Hashtable *extract(UChar32 comp, const UnicodeString &segment, int32_t segLen, int32_t segmentPos, UErrorCode &status);
 
     void cleanPieces();
@@ -205,4 +209,6 @@
 
 #endif /* #if !UCONFIG_NO_NORMALIZATION */
 
+#endif /* U_SHOW_CPLUSPLUS_API */
+
 #endif
diff --git a/src/third_party/icu/source/common/unicode/casemap.h b/src/third_party/icu/source/common/unicode/casemap.h
new file mode 100644
index 0000000..53af84f
--- /dev/null
+++ b/src/third_party/icu/source/common/unicode/casemap.h
@@ -0,0 +1,497 @@
+// © 2017 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+// casemap.h
+// created: 2017jan12 Markus W. Scherer
+
+#ifndef __CASEMAP_H__
+#define __CASEMAP_H__
+
+#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
+#include "unicode/stringpiece.h"
+#include "unicode/uobject.h"
+
+/**
+ * \file
+ * \brief C++ API: Low-level C++ case mapping functions.
+ */
+
+U_NAMESPACE_BEGIN
+
+class BreakIterator;
+class ByteSink;
+class Edits;
+
+/**
+ * Low-level C++ case mapping functions.
+ *
+ * @stable ICU 59
+ */
+class U_COMMON_API CaseMap U_FINAL : public UMemory {
+public:
+    /**
+     * Lowercases a UTF-16 string and optionally records edits.
+     * Casing is locale-dependent and context-sensitive.
+     * The result may be longer or shorter than the original.
+     * The source string and the destination buffer must not overlap.
+     *
+     * @param locale    The locale ID. ("" = root locale, NULL = default locale.)
+     * @param options   Options bit set, usually 0. See U_OMIT_UNCHANGED_TEXT and U_EDITS_NO_RESET.
+     * @param src       The original string.
+     * @param srcLength The length of the original string. If -1, then src must be NUL-terminated.
+     * @param dest      A buffer for the result string. The result will be NUL-terminated if
+     *                  the buffer is large enough.
+     *                  The contents is undefined in case of failure.
+     * @param destCapacity The size of the buffer (number of char16_ts). If it is 0, then
+     *                  dest may be NULL and the function will only return the length of the result
+     *                  without writing any of the result string.
+     * @param edits     Records edits for index mapping, working with styled text,
+     *                  and getting only changes (if any).
+     *                  The Edits contents is undefined if any error occurs.
+     *                  This function calls edits->reset() first unless
+     *                  options includes U_EDITS_NO_RESET. edits can be NULL.
+     * @param errorCode Reference to an in/out error code value
+     *                  which must not indicate a failure before the function call.
+     * @return The length of the result string, if successful.
+     *         When the result would be longer than destCapacity,
+     *         the full length is returned and a U_BUFFER_OVERFLOW_ERROR is set.
+     *
+     * @see u_strToLower
+     * @stable ICU 59
+     */
+     static int32_t toLower(
+            const char *locale, uint32_t options,
+            const char16_t *src, int32_t srcLength,
+            char16_t *dest, int32_t destCapacity, Edits *edits,
+            UErrorCode &errorCode);
+
+    /**
+     * Uppercases a UTF-16 string and optionally records edits.
+     * Casing is locale-dependent and context-sensitive.
+     * The result may be longer or shorter than the original.
+     * The source string and the destination buffer must not overlap.
+     *
+     * @param locale    The locale ID. ("" = root locale, NULL = default locale.)
+     * @param options   Options bit set, usually 0. See U_OMIT_UNCHANGED_TEXT and U_EDITS_NO_RESET.
+     * @param src       The original string.
+     * @param srcLength The length of the original string. If -1, then src must be NUL-terminated.
+     * @param dest      A buffer for the result string. The result will be NUL-terminated if
+     *                  the buffer is large enough.
+     *                  The contents is undefined in case of failure.
+     * @param destCapacity The size of the buffer (number of char16_ts). If it is 0, then
+     *                  dest may be NULL and the function will only return the length of the result
+     *                  without writing any of the result string.
+     * @param edits     Records edits for index mapping, working with styled text,
+     *                  and getting only changes (if any).
+     *                  The Edits contents is undefined if any error occurs.
+     *                  This function calls edits->reset() first unless
+     *                  options includes U_EDITS_NO_RESET. edits can be NULL.
+     * @param errorCode Reference to an in/out error code value
+     *                  which must not indicate a failure before the function call.
+     * @return The length of the result string, if successful.
+     *         When the result would be longer than destCapacity,
+     *         the full length is returned and a U_BUFFER_OVERFLOW_ERROR is set.
+     *
+     * @see u_strToUpper
+     * @stable ICU 59
+     */
+    static int32_t toUpper(
+            const char *locale, uint32_t options,
+            const char16_t *src, int32_t srcLength,
+            char16_t *dest, int32_t destCapacity, Edits *edits,
+            UErrorCode &errorCode);
+
+#if !UCONFIG_NO_BREAK_ITERATION
+
+    /**
+     * Titlecases a UTF-16 string and optionally records edits.
+     * Casing is locale-dependent and context-sensitive.
+     * The result may be longer or shorter than the original.
+     * The source string and the destination buffer must not overlap.
+     *
+     * Titlecasing uses a break iterator to find the first characters of words
+     * that are to be titlecased. It titlecases those characters and lowercases
+     * all others. (This can be modified with options bits.)
+     *
+     * @param locale    The locale ID. ("" = root locale, NULL = default locale.)
+     * @param options   Options bit set, usually 0. See U_OMIT_UNCHANGED_TEXT, U_EDITS_NO_RESET,
+     *                  U_TITLECASE_NO_LOWERCASE,
+     *                  U_TITLECASE_NO_BREAK_ADJUSTMENT, U_TITLECASE_ADJUST_TO_CASED,
+     *                  U_TITLECASE_WHOLE_STRING, U_TITLECASE_SENTENCES.
+     * @param iter      A break iterator to find the first characters of words that are to be titlecased.
+     *                  It is set to the source string (setText())
+     *                  and used one or more times for iteration (first() and next()).
+     *                  If NULL, then a word break iterator for the locale is used
+     *                  (or something equivalent).
+     * @param src       The original string.
+     * @param srcLength The length of the original string. If -1, then src must be NUL-terminated.
+     * @param dest      A buffer for the result string. The result will be NUL-terminated if
+     *                  the buffer is large enough.
+     *                  The contents is undefined in case of failure.
+     * @param destCapacity The size of the buffer (number of char16_ts). If it is 0, then
+     *                  dest may be NULL and the function will only return the length of the result
+     *                  without writing any of the result string.
+     * @param edits     Records edits for index mapping, working with styled text,
+     *                  and getting only changes (if any).
+     *                  The Edits contents is undefined if any error occurs.
+     *                  This function calls edits->reset() first unless
+     *                  options includes U_EDITS_NO_RESET. edits can be NULL.
+     * @param errorCode Reference to an in/out error code value
+     *                  which must not indicate a failure before the function call.
+     * @return The length of the result string, if successful.
+     *         When the result would be longer than destCapacity,
+     *         the full length is returned and a U_BUFFER_OVERFLOW_ERROR is set.
+     *
+     * @see u_strToTitle
+     * @see ucasemap_toTitle
+     * @stable ICU 59
+     */
+    static int32_t toTitle(
+            const char *locale, uint32_t options, BreakIterator *iter,
+            const char16_t *src, int32_t srcLength,
+            char16_t *dest, int32_t destCapacity, Edits *edits,
+            UErrorCode &errorCode);
+
+#endif  // UCONFIG_NO_BREAK_ITERATION
+
+    /**
+     * Case-folds a UTF-16 string and optionally records edits.
+     *
+     * Case folding is locale-independent and not context-sensitive,
+     * but there is an option for whether to include or exclude mappings for dotted I
+     * and dotless i that are marked with 'T' in CaseFolding.txt.
+     *
+     * The result may be longer or shorter than the original.
+     * The source string and the destination buffer must not overlap.
+     *
+     * @param options   Options bit set, usually 0. See U_OMIT_UNCHANGED_TEXT, U_EDITS_NO_RESET,
+     *                  U_FOLD_CASE_DEFAULT, U_FOLD_CASE_EXCLUDE_SPECIAL_I.
+     * @param src       The original string.
+     * @param srcLength The length of the original string. If -1, then src must be NUL-terminated.
+     * @param dest      A buffer for the result string. The result will be NUL-terminated if
+     *                  the buffer is large enough.
+     *                  The contents is undefined in case of failure.
+     * @param destCapacity The size of the buffer (number of char16_ts). If it is 0, then
+     *                  dest may be NULL and the function will only return the length of the result
+     *                  without writing any of the result string.
+     * @param edits     Records edits for index mapping, working with styled text,
+     *                  and getting only changes (if any).
+     *                  The Edits contents is undefined if any error occurs.
+     *                  This function calls edits->reset() first unless
+     *                  options includes U_EDITS_NO_RESET. edits can be NULL.
+     * @param errorCode Reference to an in/out error code value
+     *                  which must not indicate a failure before the function call.
+     * @return The length of the result string, if successful.
+     *         When the result would be longer than destCapacity,
+     *         the full length is returned and a U_BUFFER_OVERFLOW_ERROR is set.
+     *
+     * @see u_strFoldCase
+     * @stable ICU 59
+     */
+    static int32_t fold(
+            uint32_t options,
+            const char16_t *src, int32_t srcLength,
+            char16_t *dest, int32_t destCapacity, Edits *edits,
+            UErrorCode &errorCode);
+
+    /**
+     * Lowercases a UTF-8 string and optionally records edits.
+     * Casing is locale-dependent and context-sensitive.
+     * The result may be longer or shorter than the original.
+     *
+     * @param locale    The locale ID. ("" = root locale, NULL = default locale.)
+     * @param options   Options bit set, usually 0. See U_OMIT_UNCHANGED_TEXT and U_EDITS_NO_RESET.
+     * @param src       The original string.
+     * @param sink      A ByteSink to which the result string is written.
+     *                  sink.Flush() is called at the end.
+     * @param edits     Records edits for index mapping, working with styled text,
+     *                  and getting only changes (if any).
+     *                  The Edits contents is undefined if any error occurs.
+     *                  This function calls edits->reset() first unless
+     *                  options includes U_EDITS_NO_RESET. edits can be NULL.
+     * @param errorCode Reference to an in/out error code value
+     *                  which must not indicate a failure before the function call.
+     *
+     * @see ucasemap_utf8ToLower
+     * @stable ICU 60
+     */
+    static void utf8ToLower(
+            const char *locale, uint32_t options,
+            StringPiece src, ByteSink &sink, Edits *edits,
+            UErrorCode &errorCode);
+
+    /**
+     * Uppercases a UTF-8 string and optionally records edits.
+     * Casing is locale-dependent and context-sensitive.
+     * The result may be longer or shorter than the original.
+     *
+     * @param locale    The locale ID. ("" = root locale, NULL = default locale.)
+     * @param options   Options bit set, usually 0. See U_OMIT_UNCHANGED_TEXT and U_EDITS_NO_RESET.
+     * @param src       The original string.
+     * @param sink      A ByteSink to which the result string is written.
+     *                  sink.Flush() is called at the end.
+     * @param edits     Records edits for index mapping, working with styled text,
+     *                  and getting only changes (if any).
+     *                  The Edits contents is undefined if any error occurs.
+     *                  This function calls edits->reset() first unless
+     *                  options includes U_EDITS_NO_RESET. edits can be NULL.
+     * @param errorCode Reference to an in/out error code value
+     *                  which must not indicate a failure before the function call.
+     *
+     * @see ucasemap_utf8ToUpper
+     * @stable ICU 60
+     */
+    static void utf8ToUpper(
+            const char *locale, uint32_t options,
+            StringPiece src, ByteSink &sink, Edits *edits,
+            UErrorCode &errorCode);
+
+#if !UCONFIG_NO_BREAK_ITERATION
+
+    /**
+     * Titlecases a UTF-8 string and optionally records edits.
+     * Casing is locale-dependent and context-sensitive.
+     * The result may be longer or shorter than the original.
+     *
+     * Titlecasing uses a break iterator to find the first characters of words
+     * that are to be titlecased. It titlecases those characters and lowercases
+     * all others. (This can be modified with options bits.)
+     *
+     * @param locale    The locale ID. ("" = root locale, NULL = default locale.)
+     * @param options   Options bit set, usually 0. See U_OMIT_UNCHANGED_TEXT, U_EDITS_NO_RESET,
+     *                  U_TITLECASE_NO_LOWERCASE,
+     *                  U_TITLECASE_NO_BREAK_ADJUSTMENT, U_TITLECASE_ADJUST_TO_CASED,
+     *                  U_TITLECASE_WHOLE_STRING, U_TITLECASE_SENTENCES.
+     * @param iter      A break iterator to find the first characters of words that are to be titlecased.
+     *                  It is set to the source string (setUText())
+     *                  and used one or more times for iteration (first() and next()).
+     *                  If NULL, then a word break iterator for the locale is used
+     *                  (or something equivalent).
+     * @param src       The original string.
+     * @param sink      A ByteSink to which the result string is written.
+     *                  sink.Flush() is called at the end.
+     * @param edits     Records edits for index mapping, working with styled text,
+     *                  and getting only changes (if any).
+     *                  The Edits contents is undefined if any error occurs.
+     *                  This function calls edits->reset() first unless
+     *                  options includes U_EDITS_NO_RESET. edits can be NULL.
+     * @param errorCode Reference to an in/out error code value
+     *                  which must not indicate a failure before the function call.
+     *
+     * @see ucasemap_utf8ToTitle
+     * @stable ICU 60
+     */
+    static void utf8ToTitle(
+            const char *locale, uint32_t options, BreakIterator *iter,
+            StringPiece src, ByteSink &sink, Edits *edits,
+            UErrorCode &errorCode);
+
+#endif  // UCONFIG_NO_BREAK_ITERATION
+
+    /**
+     * Case-folds a UTF-8 string and optionally records edits.
+     *
+     * Case folding is locale-independent and not context-sensitive,
+     * but there is an option for whether to include or exclude mappings for dotted I
+     * and dotless i that are marked with 'T' in CaseFolding.txt.
+     *
+     * The result may be longer or shorter than the original.
+     *
+     * @param options   Options bit set, usually 0. See U_OMIT_UNCHANGED_TEXT and U_EDITS_NO_RESET.
+     * @param src       The original string.
+     * @param sink      A ByteSink to which the result string is written.
+     *                  sink.Flush() is called at the end.
+     * @param edits     Records edits for index mapping, working with styled text,
+     *                  and getting only changes (if any).
+     *                  The Edits contents is undefined if any error occurs.
+     *                  This function calls edits->reset() first unless
+     *                  options includes U_EDITS_NO_RESET. edits can be NULL.
+     * @param errorCode Reference to an in/out error code value
+     *                  which must not indicate a failure before the function call.
+     *
+     * @see ucasemap_utf8FoldCase
+     * @stable ICU 60
+     */
+    static void utf8Fold(
+            uint32_t options,
+            StringPiece src, ByteSink &sink, Edits *edits,
+            UErrorCode &errorCode);
+
+    /**
+     * Lowercases a UTF-8 string and optionally records edits.
+     * Casing is locale-dependent and context-sensitive.
+     * The result may be longer or shorter than the original.
+     * The source string and the destination buffer must not overlap.
+     *
+     * @param locale    The locale ID. ("" = root locale, NULL = default locale.)
+     * @param options   Options bit set, usually 0. See U_OMIT_UNCHANGED_TEXT and U_EDITS_NO_RESET.
+     * @param src       The original string.
+     * @param srcLength The length of the original string. If -1, then src must be NUL-terminated.
+     * @param dest      A buffer for the result string. The result will be NUL-terminated if
+     *                  the buffer is large enough.
+     *                  The contents is undefined in case of failure.
+     * @param destCapacity The size of the buffer (number of bytes). If it is 0, then
+     *                  dest may be NULL and the function will only return the length of the result
+     *                  without writing any of the result string.
+     * @param edits     Records edits for index mapping, working with styled text,
+     *                  and getting only changes (if any).
+     *                  The Edits contents is undefined if any error occurs.
+     *                  This function calls edits->reset() first unless
+     *                  options includes U_EDITS_NO_RESET. edits can be NULL.
+     * @param errorCode Reference to an in/out error code value
+     *                  which must not indicate a failure before the function call.
+     * @return The length of the result string, if successful.
+     *         When the result would be longer than destCapacity,
+     *         the full length is returned and a U_BUFFER_OVERFLOW_ERROR is set.
+     *
+     * @see ucasemap_utf8ToLower
+     * @stable ICU 59
+     */
+    static int32_t utf8ToLower(
+            const char *locale, uint32_t options,
+            const char *src, int32_t srcLength,
+            char *dest, int32_t destCapacity, Edits *edits,
+            UErrorCode &errorCode);
+
+    /**
+     * Uppercases a UTF-8 string and optionally records edits.
+     * Casing is locale-dependent and context-sensitive.
+     * The result may be longer or shorter than the original.
+     * The source string and the destination buffer must not overlap.
+     *
+     * @param locale    The locale ID. ("" = root locale, NULL = default locale.)
+     * @param options   Options bit set, usually 0. See U_OMIT_UNCHANGED_TEXT and U_EDITS_NO_RESET.
+     * @param src       The original string.
+     * @param srcLength The length of the original string. If -1, then src must be NUL-terminated.
+     * @param dest      A buffer for the result string. The result will be NUL-terminated if
+     *                  the buffer is large enough.
+     *                  The contents is undefined in case of failure.
+     * @param destCapacity The size of the buffer (number of bytes). If it is 0, then
+     *                  dest may be NULL and the function will only return the length of the result
+     *                  without writing any of the result string.
+     * @param edits     Records edits for index mapping, working with styled text,
+     *                  and getting only changes (if any).
+     *                  The Edits contents is undefined if any error occurs.
+     *                  This function calls edits->reset() first unless
+     *                  options includes U_EDITS_NO_RESET. edits can be NULL.
+     * @param errorCode Reference to an in/out error code value
+     *                  which must not indicate a failure before the function call.
+     * @return The length of the result string, if successful.
+     *         When the result would be longer than destCapacity,
+     *         the full length is returned and a U_BUFFER_OVERFLOW_ERROR is set.
+     *
+     * @see ucasemap_utf8ToUpper
+     * @stable ICU 59
+     */
+    static int32_t utf8ToUpper(
+            const char *locale, uint32_t options,
+            const char *src, int32_t srcLength,
+            char *dest, int32_t destCapacity, Edits *edits,
+            UErrorCode &errorCode);
+
+#if !UCONFIG_NO_BREAK_ITERATION
+
+    /**
+     * Titlecases a UTF-8 string and optionally records edits.
+     * Casing is locale-dependent and context-sensitive.
+     * The result may be longer or shorter than the original.
+     * The source string and the destination buffer must not overlap.
+     *
+     * Titlecasing uses a break iterator to find the first characters of words
+     * that are to be titlecased. It titlecases those characters and lowercases
+     * all others. (This can be modified with options bits.)
+     *
+     * @param locale    The locale ID. ("" = root locale, NULL = default locale.)
+     * @param options   Options bit set, usually 0. See U_OMIT_UNCHANGED_TEXT, U_EDITS_NO_RESET,
+     *                  U_TITLECASE_NO_LOWERCASE,
+     *                  U_TITLECASE_NO_BREAK_ADJUSTMENT, U_TITLECASE_ADJUST_TO_CASED,
+     *                  U_TITLECASE_WHOLE_STRING, U_TITLECASE_SENTENCES.
+     * @param iter      A break iterator to find the first characters of words that are to be titlecased.
+     *                  It is set to the source string (setUText())
+     *                  and used one or more times for iteration (first() and next()).
+     *                  If NULL, then a word break iterator for the locale is used
+     *                  (or something equivalent).
+     * @param src       The original string.
+     * @param srcLength The length of the original string. If -1, then src must be NUL-terminated.
+     * @param dest      A buffer for the result string. The result will be NUL-terminated if
+     *                  the buffer is large enough.
+     *                  The contents is undefined in case of failure.
+     * @param destCapacity The size of the buffer (number of bytes). If it is 0, then
+     *                  dest may be NULL and the function will only return the length of the result
+     *                  without writing any of the result string.
+     * @param edits     Records edits for index mapping, working with styled text,
+     *                  and getting only changes (if any).
+     *                  The Edits contents is undefined if any error occurs.
+     *                  This function calls edits->reset() first unless
+     *                  options includes U_EDITS_NO_RESET. edits can be NULL.
+     * @param errorCode Reference to an in/out error code value
+     *                  which must not indicate a failure before the function call.
+     * @return The length of the result string, if successful.
+     *         When the result would be longer than destCapacity,
+     *         the full length is returned and a U_BUFFER_OVERFLOW_ERROR is set.
+     *
+     * @see ucasemap_utf8ToTitle
+     * @stable ICU 59
+     */
+    static int32_t utf8ToTitle(
+            const char *locale, uint32_t options, BreakIterator *iter,
+            const char *src, int32_t srcLength,
+            char *dest, int32_t destCapacity, Edits *edits,
+            UErrorCode &errorCode);
+
+#endif  // UCONFIG_NO_BREAK_ITERATION
+
+    /**
+     * Case-folds a UTF-8 string and optionally records edits.
+     *
+     * Case folding is locale-independent and not context-sensitive,
+     * but there is an option for whether to include or exclude mappings for dotted I
+     * and dotless i that are marked with 'T' in CaseFolding.txt.
+     *
+     * The result may be longer or shorter than the original.
+     * The source string and the destination buffer must not overlap.
+     *
+     * @param options   Options bit set, usually 0. See U_OMIT_UNCHANGED_TEXT, U_EDITS_NO_RESET,
+     *                  U_FOLD_CASE_DEFAULT, U_FOLD_CASE_EXCLUDE_SPECIAL_I.
+     * @param src       The original string.
+     * @param srcLength The length of the original string. If -1, then src must be NUL-terminated.
+     * @param dest      A buffer for the result string. The result will be NUL-terminated if
+     *                  the buffer is large enough.
+     *                  The contents is undefined in case of failure.
+     * @param destCapacity The size of the buffer (number of bytes). If it is 0, then
+     *                  dest may be NULL and the function will only return the length of the result
+     *                  without writing any of the result string.
+     * @param edits     Records edits for index mapping, working with styled text,
+     *                  and getting only changes (if any).
+     *                  The Edits contents is undefined if any error occurs.
+     *                  This function calls edits->reset() first unless
+     *                  options includes U_EDITS_NO_RESET. edits can be NULL.
+     * @param errorCode Reference to an in/out error code value
+     *                  which must not indicate a failure before the function call.
+     * @return The length of the result string, if successful.
+     *         When the result would be longer than destCapacity,
+     *         the full length is returned and a U_BUFFER_OVERFLOW_ERROR is set.
+     *
+     * @see ucasemap_utf8FoldCase
+     * @stable ICU 59
+     */
+    static int32_t utf8Fold(
+            uint32_t options,
+            const char *src, int32_t srcLength,
+            char *dest, int32_t destCapacity, Edits *edits,
+            UErrorCode &errorCode);
+
+private:
+    CaseMap() = delete;
+    CaseMap(const CaseMap &other) = delete;
+    CaseMap &operator=(const CaseMap &other) = delete;
+};
+
+U_NAMESPACE_END
+
+#endif /* U_SHOW_CPLUSPLUS_API */
+
+#endif  // __CASEMAP_H__
diff --git a/src/third_party/icu/source/common/unicode/char16ptr.h b/src/third_party/icu/source/common/unicode/char16ptr.h
new file mode 100644
index 0000000..c8a9ae6
--- /dev/null
+++ b/src/third_party/icu/source/common/unicode/char16ptr.h
@@ -0,0 +1,313 @@
+// © 2017 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+// char16ptr.h
+// created: 2017feb28 Markus W. Scherer
+
+#ifndef __CHAR16PTR_H__
+#define __CHAR16PTR_H__
+
+#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
+#include <cstddef>
+
+/**
+ * \file
+ * \brief C++ API: char16_t pointer wrappers with
+ *        implicit conversion from bit-compatible raw pointer types.
+ *        Also conversion functions from char16_t * to UChar * and OldUChar *.
+ */
+
+U_NAMESPACE_BEGIN
+
+/**
+ * \def U_ALIASING_BARRIER
+ * Barrier for pointer anti-aliasing optimizations even across function boundaries.
+ * @internal
+ */
+#ifdef U_ALIASING_BARRIER
+    // Use the predefined value.
+#elif (defined(__clang__) || defined(__GNUC__)) && U_PLATFORM != U_PF_BROWSER_NATIVE_CLIENT
+#   define U_ALIASING_BARRIER(ptr) asm volatile("" : : "rm"(ptr) : "memory")
+#elif defined(U_IN_DOXYGEN)
+#   define U_ALIASING_BARRIER(ptr)
+#endif
+
+/**
+ * char16_t * wrapper with implicit conversion from distinct but bit-compatible pointer types.
+ * @stable ICU 59
+ */
+class U_COMMON_API Char16Ptr U_FINAL {
+public:
+    /**
+     * Copies the pointer.
+     * @param p pointer
+     * @stable ICU 59
+     */
+    inline Char16Ptr(char16_t *p);
+#if !U_CHAR16_IS_TYPEDEF
+    /**
+     * Converts the pointer to char16_t *.
+     * @param p pointer to be converted
+     * @stable ICU 59
+     */
+    inline Char16Ptr(uint16_t *p);
+#endif
+#if U_SIZEOF_WCHAR_T==2 || defined(U_IN_DOXYGEN)
+    /**
+     * Converts the pointer to char16_t *.
+     * (Only defined if U_SIZEOF_WCHAR_T==2.)
+     * @param p pointer to be converted
+     * @stable ICU 59
+     */
+    inline Char16Ptr(wchar_t *p);
+#endif
+    /**
+     * nullptr constructor.
+     * @param p nullptr
+     * @stable ICU 59
+     */
+    inline Char16Ptr(std::nullptr_t p);
+    /**
+     * Destructor.
+     * @stable ICU 59
+     */
+    inline ~Char16Ptr();
+
+    /**
+     * Pointer access.
+     * @return the wrapped pointer
+     * @stable ICU 59
+     */
+    inline char16_t *get() const;
+    /**
+     * char16_t pointer access via type conversion (e.g., static_cast).
+     * @return the wrapped pointer
+     * @stable ICU 59
+     */
+    inline operator char16_t *() const { return get(); }
+
+private:
+    Char16Ptr() = delete;
+
+#ifdef U_ALIASING_BARRIER
+    template<typename T> static char16_t *cast(T *t) {
+        U_ALIASING_BARRIER(t);
+        return reinterpret_cast<char16_t *>(t);
+    }
+
+    char16_t *p_;
+#else
+    union {
+        char16_t *cp;
+        uint16_t *up;
+        wchar_t *wp;
+    } u_;
+#endif
+};
+
+/// \cond
+#ifdef U_ALIASING_BARRIER
+
+Char16Ptr::Char16Ptr(char16_t *p) : p_(p) {}
+#if !U_CHAR16_IS_TYPEDEF
+Char16Ptr::Char16Ptr(uint16_t *p) : p_(cast(p)) {}
+#endif
+#if U_SIZEOF_WCHAR_T==2
+Char16Ptr::Char16Ptr(wchar_t *p) : p_(cast(p)) {}
+#endif
+Char16Ptr::Char16Ptr(std::nullptr_t p) : p_(p) {}
+Char16Ptr::~Char16Ptr() {
+    U_ALIASING_BARRIER(p_);
+}
+
+char16_t *Char16Ptr::get() const { return p_; }
+
+#else
+
+Char16Ptr::Char16Ptr(char16_t *p) { u_.cp = p; }
+#if !U_CHAR16_IS_TYPEDEF
+Char16Ptr::Char16Ptr(uint16_t *p) { u_.up = p; }
+#endif
+#if U_SIZEOF_WCHAR_T==2
+Char16Ptr::Char16Ptr(wchar_t *p) { u_.wp = p; }
+#endif
+Char16Ptr::Char16Ptr(std::nullptr_t p) { u_.cp = p; }
+Char16Ptr::~Char16Ptr() {}
+
+char16_t *Char16Ptr::get() const { return u_.cp; }
+
+#endif
+/// \endcond
+
+/**
+ * const char16_t * wrapper with implicit conversion from distinct but bit-compatible pointer types.
+ * @stable ICU 59
+ */
+class U_COMMON_API ConstChar16Ptr U_FINAL {
+public:
+    /**
+     * Copies the pointer.
+     * @param p pointer
+     * @stable ICU 59
+     */
+    inline ConstChar16Ptr(const char16_t *p);
+#if !U_CHAR16_IS_TYPEDEF
+    /**
+     * Converts the pointer to char16_t *.
+     * @param p pointer to be converted
+     * @stable ICU 59
+     */
+    inline ConstChar16Ptr(const uint16_t *p);
+#endif
+#if U_SIZEOF_WCHAR_T==2 || defined(U_IN_DOXYGEN)
+    /**
+     * Converts the pointer to char16_t *.
+     * (Only defined if U_SIZEOF_WCHAR_T==2.)
+     * @param p pointer to be converted
+     * @stable ICU 59
+     */
+    inline ConstChar16Ptr(const wchar_t *p);
+#endif
+    /**
+     * nullptr constructor.
+     * @param p nullptr
+     * @stable ICU 59
+     */
+    inline ConstChar16Ptr(const std::nullptr_t p);
+
+    /**
+     * Destructor.
+     * @stable ICU 59
+     */
+    inline ~ConstChar16Ptr();
+
+    /**
+     * Pointer access.
+     * @return the wrapped pointer
+     * @stable ICU 59
+     */
+    inline const char16_t *get() const;
+    /**
+     * char16_t pointer access via type conversion (e.g., static_cast).
+     * @return the wrapped pointer
+     * @stable ICU 59
+     */
+    inline operator const char16_t *() const { return get(); }
+
+private:
+    ConstChar16Ptr() = delete;
+
+#ifdef U_ALIASING_BARRIER
+    template<typename T> static const char16_t *cast(const T *t) {
+        U_ALIASING_BARRIER(t);
+        return reinterpret_cast<const char16_t *>(t);
+    }
+
+    const char16_t *p_;
+#else
+    union {
+        const char16_t *cp;
+        const uint16_t *up;
+        const wchar_t *wp;
+    } u_;
+#endif
+};
+
+/// \cond
+#ifdef U_ALIASING_BARRIER
+
+ConstChar16Ptr::ConstChar16Ptr(const char16_t *p) : p_(p) {}
+#if !U_CHAR16_IS_TYPEDEF
+ConstChar16Ptr::ConstChar16Ptr(const uint16_t *p) : p_(cast(p)) {}
+#endif
+#if U_SIZEOF_WCHAR_T==2
+ConstChar16Ptr::ConstChar16Ptr(const wchar_t *p) : p_(cast(p)) {}
+#endif
+ConstChar16Ptr::ConstChar16Ptr(const std::nullptr_t p) : p_(p) {}
+ConstChar16Ptr::~ConstChar16Ptr() {
+    U_ALIASING_BARRIER(p_);
+}
+
+const char16_t *ConstChar16Ptr::get() const { return p_; }
+
+#else
+
+ConstChar16Ptr::ConstChar16Ptr(const char16_t *p) { u_.cp = p; }
+#if !U_CHAR16_IS_TYPEDEF
+ConstChar16Ptr::ConstChar16Ptr(const uint16_t *p) { u_.up = p; }
+#endif
+#if U_SIZEOF_WCHAR_T==2
+ConstChar16Ptr::ConstChar16Ptr(const wchar_t *p) { u_.wp = p; }
+#endif
+ConstChar16Ptr::ConstChar16Ptr(const std::nullptr_t p) { u_.cp = p; }
+ConstChar16Ptr::~ConstChar16Ptr() {}
+
+const char16_t *ConstChar16Ptr::get() const { return u_.cp; }
+
+#endif
+/// \endcond
+
+/**
+ * Converts from const char16_t * to const UChar *.
+ * Includes an aliasing barrier if available.
+ * @param p pointer
+ * @return p as const UChar *
+ * @stable ICU 59
+ */
+inline const UChar *toUCharPtr(const char16_t *p) {
+#ifdef U_ALIASING_BARRIER
+    U_ALIASING_BARRIER(p);
+#endif
+    return reinterpret_cast<const UChar *>(p);
+}
+
+/**
+ * Converts from char16_t * to UChar *.
+ * Includes an aliasing barrier if available.
+ * @param p pointer
+ * @return p as UChar *
+ * @stable ICU 59
+ */
+inline UChar *toUCharPtr(char16_t *p) {
+#ifdef U_ALIASING_BARRIER
+    U_ALIASING_BARRIER(p);
+#endif
+    return reinterpret_cast<UChar *>(p);
+}
+
+/**
+ * Converts from const char16_t * to const OldUChar *.
+ * Includes an aliasing barrier if available.
+ * @param p pointer
+ * @return p as const OldUChar *
+ * @stable ICU 59
+ */
+inline const OldUChar *toOldUCharPtr(const char16_t *p) {
+#ifdef U_ALIASING_BARRIER
+    U_ALIASING_BARRIER(p);
+#endif
+    return reinterpret_cast<const OldUChar *>(p);
+}
+
+/**
+ * Converts from char16_t * to OldUChar *.
+ * Includes an aliasing barrier if available.
+ * @param p pointer
+ * @return p as OldUChar *
+ * @stable ICU 59
+ */
+inline OldUChar *toOldUCharPtr(char16_t *p) {
+#ifdef U_ALIASING_BARRIER
+    U_ALIASING_BARRIER(p);
+#endif
+    return reinterpret_cast<OldUChar *>(p);
+}
+
+U_NAMESPACE_END
+
+#endif /* U_SHOW_CPLUSPLUS_API */
+
+#endif  // __CHAR16PTR_H__
diff --git a/src/third_party/icu/source/common/unicode/chariter.h b/src/third_party/icu/source/common/unicode/chariter.h
index e8d6509..96dc5db 100644
--- a/src/third_party/icu/source/common/unicode/chariter.h
+++ b/src/third_party/icu/source/common/unicode/chariter.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ********************************************************************
 *
@@ -11,6 +13,9 @@
 #define CHARITER_H
 
 #include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
 #include "unicode/uobject.h"
 #include "unicode/unistr.h"
 /**
@@ -60,7 +65,7 @@
  * check for the end of the iteration. When there are no more
  * characters in the text object:
  * <ul>
- * <li>The hasNext() function returns FALSE.</li>
+ * <li>The hasNext() function returns false.</li>
  * <li>nextPostInc() and next32PostInc() return DONE
  *     when one attempts to read beyond the end of the text object.</li>
  * </ul>
@@ -76,7 +81,7 @@
  * }
  *
  * void function1(ForwardCharacterIterator &it) {
- *     UChar c;
+ *     char16_t c;
  *     while((c=it.nextPostInc())!=ForwardCharacterIterator::DONE) {
  *         // use c
  *      }
@@ -147,7 +152,7 @@
      * @return the current code unit.
      * @stable ICU 2.0
      */
-    virtual UChar         nextPostInc(void) = 0;
+    virtual char16_t         nextPostInc(void) = 0;
     
     /**
      * Gets the current code point for returning and advances to the next code point
@@ -160,11 +165,11 @@
     virtual UChar32       next32PostInc(void) = 0;
     
     /**
-     * Returns FALSE if there are no more code units or code points
+     * Returns false if there are no more code units or code points
      * at or after the current position in the iteration range.
      * This is used with nextPostInc() or next32PostInc() in forward
      * iteration.
-     * @returns FALSE if there are no more code units or code points
+     * @returns false if there are no more code units or code points
      * at or after the current position in the iteration range.
      * @stable ICU 2.0
      */
@@ -228,7 +233,7 @@
  * showing a way to convert simple for() loops:
  * \code
  * void forward2(CharacterIterator &it) {
- *     UChar c;
+ *     char16_t c;
  *     for(c=it.firstPostInc(); c!=CharacterIterator::DONE; c=it.nextPostInc()) {
  *          // use c
  *      }
@@ -247,7 +252,7 @@
  * Backward iteration with a more traditional for() loop:
  * \code
  * void backward2(CharacterIterator &it) {
- *     UChar c;
+ *     char16_t c;
  *     for(c=it.last(); c!=CharacterIterator::DONE; c=it.previous()) {
  *         // use c
  *      }
@@ -264,7 +269,7 @@
  *      // get the position
  *      int32_t pos=it.getIndex();
  *      // get the previous code unit
- *      UChar u=it.previous();
+ *      char16_t u=it.previous();
  *      // move back one more code unit
  *      it.move(-1, CharacterIterator::kCurrent);
  *      // set the position back to where it was
@@ -281,7 +286,7 @@
  * Function processing characters, in this example simple output
  * <pre>
  * \code
- *  void processChar( UChar c )
+ *  void processChar( char16_t c )
  *  {
  *      cout << " " << c;
  *  }
@@ -292,7 +297,7 @@
  * \code
  *  void traverseForward(CharacterIterator& iter)
  *  {
- *      for(UChar c = iter.first(); c != CharacterIterator.DONE; c = iter.next()) {
+ *      for(char16_t c = iter.first(); c != CharacterIterator.DONE; c = iter.next()) {
  *          processChar(c);
  *      }
  *  }
@@ -303,7 +308,7 @@
  * \code
  *  void traverseBackward(CharacterIterator& iter)
  *  {
- *      for(UChar c = iter.last(); c != CharacterIterator.DONE; c = iter.previous()) {
+ *      for(char16_t c = iter.last(); c != CharacterIterator.DONE; c = iter.previous()) {
  *          processChar(c);
  *      }
  *  }
@@ -315,7 +320,7 @@
  * \code
  * void traverseOut(CharacterIterator& iter, int32_t pos)
  * {
- *      UChar c;
+ *      char16_t c;
  *      for (c = iter.setIndex(pos);
  *      c != CharacterIterator.DONE && (Unicode::isLetter(c) || Unicode::isDigit(c));
  *          c = iter.next()) {}
@@ -375,7 +380,7 @@
      * @return a pointer to a new CharacterIterator
      * @stable ICU 2.0
      */
-    virtual CharacterIterator* clone(void) const = 0;
+    virtual CharacterIterator* clone() const = 0;
 
     /**
      * Sets the iterator to refer to the first code unit in its
@@ -384,7 +389,7 @@
      * @return the first code unit in its iteration range.
      * @stable ICU 2.0
      */
-    virtual UChar         first(void) = 0;
+    virtual char16_t         first(void) = 0;
 
     /**
      * Sets the iterator to refer to the first code unit in its
@@ -394,7 +399,7 @@
      * @return the first code unit in its iteration range.
      * @stable ICU 2.0
      */
-    virtual UChar         firstPostInc(void);
+    virtual char16_t         firstPostInc(void);
 
     /**
      * Sets the iterator to refer to the first code point in its
@@ -433,7 +438,7 @@
      * @return the last code unit.
      * @stable ICU 2.0
      */
-    virtual UChar         last(void) = 0;
+    virtual char16_t         last(void) = 0;
         
     /**
      * Sets the iterator to refer to the last code point in its
@@ -461,7 +466,7 @@
      * @return the "position"-th code unit.
      * @stable ICU 2.0
      */
-    virtual UChar         setIndex(int32_t position) = 0;
+    virtual char16_t         setIndex(int32_t position) = 0;
 
     /**
      * Sets the iterator to refer to the beginning of the code point
@@ -481,7 +486,7 @@
      * @return the current code unit. 
      * @stable ICU 2.0
      */
-    virtual UChar         current(void) const = 0;
+    virtual char16_t         current(void) const = 0;
         
     /**
      * Returns the code point the iterator currently refers to.  
@@ -497,7 +502,7 @@
      * @return the next code unit.
      * @stable ICU 2.0
      */
-    virtual UChar         next(void) = 0;
+    virtual char16_t         next(void) = 0;
         
     /**
      * Advances to the next code point in the iteration range
@@ -518,7 +523,7 @@
      * @return the previous code unit.
      * @stable ICU 2.0
      */
-    virtual UChar         previous(void) = 0;
+    virtual char16_t         previous(void) = 0;
 
     /**
      * Advances to the previous code point in the iteration range
@@ -530,12 +535,12 @@
     virtual UChar32       previous32(void) = 0;
 
     /**
-     * Returns FALSE if there are no more code units or code points
+     * Returns false if there are no more code units or code points
      * before the current position in the iteration range.
      * This is used with previous() or previous32() in backward
      * iteration.
-     * @return FALSE if there are no more code units or code points
-     * before the current position in the iteration range, return TRUE otherwise.
+     * @return false if there are no more code units or code points
+     * before the current position in the iteration range, return true otherwise.
      * @stable ICU 2.0
      */
     virtual UBool        hasPrevious() = 0;
@@ -567,7 +572,7 @@
      * Returns the numeric index in the underlying text-storage
      * object of the character the iterator currently refers to
      * (i.e., the character returned by current()).  
-     * @return the numberic index in the text-storage object of 
+     * @return the numeric index in the text-storage object of 
      * the character the iterator currently refers to
      * @stable ICU 2.0
      */
@@ -605,6 +610,10 @@
      * @return the new position
      * @stable ICU 2.0
      */
+#ifdef move32
+     // One of the system headers right now is sometimes defining a conflicting macro we don't use
+#undef move32
+#endif
     virtual int32_t      move32(int32_t delta, EOrigin origin) = 0;
 
     /**
@@ -719,4 +728,7 @@
 }
 
 U_NAMESPACE_END
+
+#endif /* U_SHOW_CPLUSPLUS_API */
+
 #endif
diff --git a/src/third_party/icu/source/common/unicode/dbbi.h b/src/third_party/icu/source/common/unicode/dbbi.h
index 7187c3c..3de9cc3 100644
--- a/src/third_party/icu/source/common/unicode/dbbi.h
+++ b/src/third_party/icu/source/common/unicode/dbbi.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
 *   Copyright (C) 1999-2006,2013 IBM Corp. All rights reserved.
@@ -11,6 +13,10 @@
 #ifndef DBBI_H
 #define DBBI_H
 
+#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
 #include "unicode/rbbi.h"
 
 #if !UCONFIG_NO_BREAK_ITERATION
@@ -37,4 +43,6 @@
 
 #endif /* #if !UCONFIG_NO_BREAK_ITERATION */
 
+#endif /* U_SHOW_CPLUSPLUS_API */
+
 #endif
diff --git a/src/third_party/icu/source/common/unicode/docmain.h b/src/third_party/icu/source/common/unicode/docmain.h
index df3fe84..edcb5d4 100644
--- a/src/third_party/icu/source/common/unicode/docmain.h
+++ b/src/third_party/icu/source/common/unicode/docmain.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /********************************************************************
  * COPYRIGHT: 
  * Copyright (c) 1997-2012, International Business Machines Corporation and
@@ -31,7 +33,7 @@
  * then detailed member descriptions.</p>
  * 
  * <h3>C Programmers:</h3>
- * <p>Use <a href="#Module">Module List</a> or <a href="globals.html">File Members</a>
+ * <p>Use <a href="#Module">Module List</a> or <a href="globals_u.html">File Members</a>
  * to find a list of all the functions and constants.
  * For example, to find BreakIterator functions you would click on
  * <a href="files.html"> File List</a>,
@@ -51,10 +53,10 @@
  *
  * <h2>Architecture (User's Guide)</h2>
  * <ul>
- *   <li><a href="http://userguide.icu-project.org/">Introduction</a></li>
- *   <li><a href="http://userguide.icu-project.org/i18n">Internationalization</a></li>
- *   <li><a href="http://userguide.icu-project.org/design">Locale Model, Multithreading, Error Handling, etc.</a></li>
- *   <li><a href="http://userguide.icu-project.org/conversion">Conversion</a></li>
+ *   <li><a href="https://unicode-org.github.io/icu/userguide/">Introduction</a></li>
+ *   <li><a href="https://unicode-org.github.io/icu/userguide/i18n">Internationalization</a></li>
+ *   <li><a href="https://unicode-org.github.io/icu/userguide/design">Locale Model, Multithreading, Error Handling, etc.</a></li>
+ *   <li><a href="https://unicode-org.github.io/icu/userguide/conversion">Conversion</a></li>
  * </ul>
  *
  * <hr>
@@ -86,13 +88,23 @@
  *     <td>icu::UnicodeSet</td>
  *   </tr>
  *   <tr>
+ *     <td>Maps from Unicode Code Points to Integer Values</td>
+ *     <td>ucptrie.h, umutablecptrie.h</td>
+ *     <td>C API</td>
+ *   </tr>
+ *   <tr>
  *     <td>Maps from Strings to Integer Values</td>
  *     <td>(no C API)</td>
  *     <td>icu::BytesTrie, icu::UCharsTrie</td>
  *   </tr>
  *   <tr>
  *     <td>Codepage Conversion</td>
- *     <td>ucnv.h, ucnvsel.hb</td>
+ *     <td>ucnv.h, ucnvsel.h</td>
+ *     <td>C API</td>
+ *   </tr>
+ *   <tr>
+ *     <td>Codepage Detection</td>
+ *     <td>ucsdet.h</td>
  *     <td>C API</td>
  *   </tr>
  *   <tr>
@@ -103,7 +115,7 @@
  *   <tr>
  *     <td>Locales </td>
  *     <td>uloc.h</a></td>
- *     <td>icu::Locale</td>
+ *     <td>icu::Locale, icu::LocaleBuilder, icu::LocaleMatcher</td>
  *   </tr>
  *   <tr>
  *     <td>Resource Bundles</td>
@@ -131,9 +143,19 @@
  *     <td>icu::MessageFormat</td>
  *   </tr>
  *   <tr>
- *     <td>Number Formatting</td>
- *     <td>unum.h</td>
- *     <td>icu::NumberFormat</td>
+ *     <td>List Formatting</td>
+ *     <td>ulistformatter.h</td>
+ *     <td>icu::ListFormatter</td>
+ *   </tr>
+ *   <tr>
+ *     <td>Number Formatting<br/>(includes currency and unit formatting)</td>
+ *     <td>unumberformatter.h, unum.h</td>
+ *     <td>icu::number::NumberFormatter (ICU 60+) or icu::NumberFormat (older versions)</td>
+ *   </tr>
+ *   <tr>
+ *     <td>Number Range Formatting<br />(includes currency and unit ranges)</td>
+ *     <td>unumberrangeformatter.h</td>
+ *     <td>icu::number::NumberRangeFormatter</td>
  *   </tr>
  *   <tr>
  *     <td>Number Spellout<br/>(Rule Based Number Formatting)</td>
@@ -147,7 +169,7 @@
  *   </tr>
  *   <tr>
  *     <td>Bidirectional Algorithm</td>
- *     <td>ubidi.h</td>
+ *     <td>ubidi.h, ubiditransform.h</td>
  *     <td>C API</td>
  *   </tr>
  *   <tr>
@@ -201,9 +223,9 @@
  *     <td>C API</td>
  *   </tr>
  *   <tr>
- *     <td>Layout Engine/Complex Text Layout</td>
- *     <td>loengine.h</td>
- *     <td>icu::LayoutEngine,icu::ParagraphLayout</td>
+ *     <td>Paragraph Layout / Complex Text Layout</td>
+ *     <td>playout.h</td>
+ *     <td>icu::ParagraphLayout</td>
  *   </tr>
  *   <tr>
  *     <td>ICU I/O</td>
diff --git a/src/third_party/icu/source/common/unicode/dtintrv.h b/src/third_party/icu/source/common/unicode/dtintrv.h
index 5bacce8..4f4b6bf 100644
--- a/src/third_party/icu/source/common/unicode/dtintrv.h
+++ b/src/third_party/icu/source/common/unicode/dtintrv.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 * Copyright (C) 2008-2009, International Business Machines Corporation and
@@ -13,6 +15,9 @@
 #define __DTINTRV_H__
 
 #include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
 #include "unicode/uobject.h"
 
 /**
@@ -20,7 +25,6 @@
  * \brief C++ API: Date Interval data type
  */
 
-
 U_NAMESPACE_BEGIN
 
 
@@ -51,14 +55,14 @@
      * @return  the from date in dateInterval.
      * @stable ICU 4.0
      */
-    UDate getFromDate() const;
+    inline UDate getFromDate() const;
 
     /** 
      * Get the to date.
      * @return  the to date in dateInterval.
      * @stable ICU 4.0
      */
-    UDate getToDate() const;
+    inline UDate getToDate() const;
 
 
     /**
@@ -67,7 +71,7 @@
      * <pre>
      * .   Base* polymorphic_pointer = createPolymorphicObject();
      * .   if (polymorphic_pointer->getDynamicClassID() ==
-     * .       erived::getStaticClassID()) ...
+     * .       derived::getStaticClassID()) ...
      * </pre>
      * @return          The class ID for all objects of this class.
      * @stable ICU 4.0
@@ -102,17 +106,17 @@
 
     /**
      * Equality operator.
-     * @return TRUE if the two DateIntervals are the same
+     * @return true if the two DateIntervals are the same
      * @stable ICU 4.0
      */
     virtual UBool operator==(const DateInterval& other) const;
 
     /**
      * Non-equality operator
-     * @return TRUE if the two DateIntervals are not the same
+     * @return true if the two DateIntervals are not the same
      * @stable ICU 4.0
      */
-    UBool operator!=(const DateInterval& other) const;
+    inline UBool operator!=(const DateInterval& other) const;
 
 
     /**
@@ -155,4 +159,6 @@
 
 U_NAMESPACE_END
 
+#endif /* U_SHOW_CPLUSPLUS_API */
+
 #endif
diff --git a/src/third_party/icu/source/common/unicode/edits.h b/src/third_party/icu/source/common/unicode/edits.h
new file mode 100644
index 0000000..bfa07fa
--- /dev/null
+++ b/src/third_party/icu/source/common/unicode/edits.h
@@ -0,0 +1,531 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+// edits.h
+// created: 2016dec30 Markus W. Scherer
+
+#ifndef __EDITS_H__
+#define __EDITS_H__
+
+#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
+#include "unicode/uobject.h"
+
+/**
+ * \file
+ * \brief C++ API: C++ class Edits for low-level string transformations on styled text.
+ */
+
+U_NAMESPACE_BEGIN
+
+class UnicodeString;
+
+/**
+ * Records lengths of string edits but not replacement text. Supports replacements, insertions, deletions
+ * in linear progression. Does not support moving/reordering of text.
+ *
+ * There are two types of edits: <em>change edits</em> and <em>no-change edits</em>. Add edits to
+ * instances of this class using {@link #addReplace(int32_t, int32_t)} (for change edits) and
+ * {@link #addUnchanged(int32_t)} (for no-change edits). Change edits are retained with full granularity,
+ * whereas adjacent no-change edits are always merged together. In no-change edits, there is a one-to-one
+ * mapping between code points in the source and destination strings.
+ *
+ * After all edits have been added, instances of this class should be considered immutable, and an
+ * {@link Edits::Iterator} can be used for queries.
+ *
+ * There are four flavors of Edits::Iterator:
+ *
+ * <ul>
+ * <li>{@link #getFineIterator()} retains full granularity of change edits.
+ * <li>{@link #getFineChangesIterator()} retains full granularity of change edits, and when calling
+ * next() on the iterator, skips over no-change edits (unchanged regions).
+ * <li>{@link #getCoarseIterator()} treats adjacent change edits as a single edit. (Adjacent no-change
+ * edits are automatically merged during the construction phase.)
+ * <li>{@link #getCoarseChangesIterator()} treats adjacent change edits as a single edit, and when
+ * calling next() on the iterator, skips over no-change edits (unchanged regions).
+ * </ul>
+ *
+ * For example, consider the string "abcßDeF", which case-folds to "abcssdef". This string has the
+ * following fine edits:
+ * <ul>
+ * <li>abc ⇨ abc (no-change)
+ * <li>ß ⇨ ss (change)
+ * <li>D ⇨ d (change)
+ * <li>e ⇨ e (no-change)
+ * <li>F ⇨ f (change)
+ * </ul>
+ * and the following coarse edits (note how adjacent change edits get merged together):
+ * <ul>
+ * <li>abc ⇨ abc (no-change)
+ * <li>ßD ⇨ ssd (change)
+ * <li>e ⇨ e (no-change)
+ * <li>F ⇨ f (change)
+ * </ul>
+ *
+ * The "fine changes" and "coarse changes" iterators will step through only the change edits when their
+ * `Edits::Iterator::next()` methods are called. They are identical to the non-change iterators when
+ * their `Edits::Iterator::findSourceIndex()` or `Edits::Iterator::findDestinationIndex()`
+ * methods are used to walk through the string.
+ *
+ * For examples of how to use this class, see the test `TestCaseMapEditsIteratorDocs` in
+ * UCharacterCaseTest.java.
+ *
+ * An Edits object tracks a separate UErrorCode, but ICU string transformation functions
+ * (e.g., case mapping functions) merge any such errors into their API's UErrorCode.
+ *
+ * @stable ICU 59
+ */
+class U_COMMON_API Edits U_FINAL : public UMemory {
+public:
+    /**
+     * Constructs an empty object.
+     * @stable ICU 59
+     */
+    Edits() :
+            array(stackArray), capacity(STACK_CAPACITY), length(0), delta(0), numChanges(0),
+            errorCode_(U_ZERO_ERROR) {}
+    /**
+     * Copy constructor.
+     * @param other source edits
+     * @stable ICU 60
+     */
+    Edits(const Edits &other) :
+            array(stackArray), capacity(STACK_CAPACITY), length(other.length),
+            delta(other.delta), numChanges(other.numChanges),
+            errorCode_(other.errorCode_) {
+        copyArray(other);
+    }
+    /**
+     * Move constructor, might leave src empty.
+     * This object will have the same contents that the source object had.
+     * @param src source edits
+     * @stable ICU 60
+     */
+    Edits(Edits &&src) U_NOEXCEPT :
+            array(stackArray), capacity(STACK_CAPACITY), length(src.length),
+            delta(src.delta), numChanges(src.numChanges),
+            errorCode_(src.errorCode_) {
+        moveArray(src);
+    }
+
+    /**
+     * Destructor.
+     * @stable ICU 59
+     */
+    ~Edits();
+
+    /**
+     * Assignment operator.
+     * @param other source edits
+     * @return *this
+     * @stable ICU 60
+     */
+    Edits &operator=(const Edits &other);
+
+    /**
+     * Move assignment operator, might leave src empty.
+     * This object will have the same contents that the source object had.
+     * The behavior is undefined if *this and src are the same object.
+     * @param src source edits
+     * @return *this
+     * @stable ICU 60
+     */
+    Edits &operator=(Edits &&src) U_NOEXCEPT;
+
+    /**
+     * Resets the data but may not release memory.
+     * @stable ICU 59
+     */
+    void reset() U_NOEXCEPT;
+
+    /**
+     * Adds a no-change edit: a record for an unchanged segment of text.
+     * Normally called from inside ICU string transformation functions, not user code.
+     * @stable ICU 59
+     */
+    void addUnchanged(int32_t unchangedLength);
+    /**
+     * Adds a change edit: a record for a text replacement/insertion/deletion.
+     * Normally called from inside ICU string transformation functions, not user code.
+     * @stable ICU 59
+     */
+    void addReplace(int32_t oldLength, int32_t newLength);
+    /**
+     * Sets the UErrorCode if an error occurred while recording edits.
+     * Preserves older error codes in the outErrorCode.
+     * Normally called from inside ICU string transformation functions, not user code.
+     * @param outErrorCode Set to an error code if it does not contain one already
+     *                  and an error occurred while recording edits.
+     *                  Otherwise unchanged.
+     * @return true if U_FAILURE(outErrorCode)
+     * @stable ICU 59
+     */
+    UBool copyErrorTo(UErrorCode &outErrorCode) const;
+
+    /**
+     * How much longer is the new text compared with the old text?
+     * @return new length minus old length
+     * @stable ICU 59
+     */
+    int32_t lengthDelta() const { return delta; }
+    /**
+     * @return true if there are any change edits
+     * @stable ICU 59
+     */
+    UBool hasChanges() const { return numChanges != 0; }
+
+    /**
+     * @return the number of change edits
+     * @stable ICU 60
+     */
+    int32_t numberOfChanges() const { return numChanges; }
+
+    /**
+     * Access to the list of edits.
+     *
+     * At any moment in time, an instance of this class points to a single edit: a "window" into a span
+     * of the source string and the corresponding span of the destination string. The source string span
+     * starts at {@link #sourceIndex()} and runs for {@link #oldLength()} chars; the destination string
+     * span starts at {@link #destinationIndex()} and runs for {@link #newLength()} chars.
+     *
+     * The iterator can be moved between edits using the `next()`, `findSourceIndex(int32_t, UErrorCode &)`,
+     * and `findDestinationIndex(int32_t, UErrorCode &)` methods.
+     * Calling any of these methods mutates the iterator to make it point to the corresponding edit.
+     *
+     * For more information, see the documentation for {@link Edits}.
+     *
+     * @see getCoarseIterator
+     * @see getFineIterator
+     * @stable ICU 59
+     */
+    struct U_COMMON_API Iterator U_FINAL : public UMemory {
+        /**
+         * Default constructor, empty iterator.
+         * @stable ICU 60
+         */
+        Iterator() :
+                array(nullptr), index(0), length(0),
+                remaining(0), onlyChanges_(false), coarse(false),
+                dir(0), changed(false), oldLength_(0), newLength_(0),
+                srcIndex(0), replIndex(0), destIndex(0) {}
+        /**
+         * Copy constructor.
+         * @stable ICU 59
+         */
+        Iterator(const Iterator &other) = default;
+        /**
+         * Assignment operator.
+         * @stable ICU 59
+         */
+        Iterator &operator=(const Iterator &other) = default;
+
+        /**
+         * Advances the iterator to the next edit.
+         * @param errorCode ICU error code. Its input value must pass the U_SUCCESS() test,
+         *                  or else the function returns immediately. Check for U_FAILURE()
+         *                  on output or use with function chaining. (See User Guide for details.)
+         * @return true if there is another edit
+         * @stable ICU 59
+         */
+        UBool next(UErrorCode &errorCode) { return next(onlyChanges_, errorCode); }
+
+        /**
+         * Moves the iterator to the edit that contains the source index.
+         * The source index may be found in a no-change edit
+         * even if normal iteration would skip no-change edits.
+         * Normal iteration can continue from a found edit.
+         *
+         * The iterator state before this search logically does not matter.
+         * (It may affect the performance of the search.)
+         *
+         * The iterator state after this search is undefined
+         * if the source index is out of bounds for the source string.
+         *
+         * @param i source index
+         * @param errorCode ICU error code. Its input value must pass the U_SUCCESS() test,
+         *                  or else the function returns immediately. Check for U_FAILURE()
+         *                  on output or use with function chaining. (See User Guide for details.)
+         * @return true if the edit for the source index was found
+         * @stable ICU 59
+         */
+        UBool findSourceIndex(int32_t i, UErrorCode &errorCode) {
+            return findIndex(i, true, errorCode) == 0;
+        }
+
+        /**
+         * Moves the iterator to the edit that contains the destination index.
+         * The destination index may be found in a no-change edit
+         * even if normal iteration would skip no-change edits.
+         * Normal iteration can continue from a found edit.
+         *
+         * The iterator state before this search logically does not matter.
+         * (It may affect the performance of the search.)
+         *
+         * The iterator state after this search is undefined
+         * if the source index is out of bounds for the source string.
+         *
+         * @param i destination index
+         * @param errorCode ICU error code. Its input value must pass the U_SUCCESS() test,
+         *                  or else the function returns immediately. Check for U_FAILURE()
+         *                  on output or use with function chaining. (See User Guide for details.)
+         * @return true if the edit for the destination index was found
+         * @stable ICU 60
+         */
+        UBool findDestinationIndex(int32_t i, UErrorCode &errorCode) {
+            return findIndex(i, false, errorCode) == 0;
+        }
+
+        /**
+         * Computes the destination index corresponding to the given source index.
+         * If the source index is inside a change edit (not at its start),
+         * then the destination index at the end of that edit is returned,
+         * since there is no information about index mapping inside a change edit.
+         *
+         * (This means that indexes to the start and middle of an edit,
+         * for example around a grapheme cluster, are mapped to indexes
+         * encompassing the entire edit.
+         * The alternative, mapping an interior index to the start,
+         * would map such an interval to an empty one.)
+         *
+         * This operation will usually but not always modify this object.
+         * The iterator state after this search is undefined.
+         *
+         * @param i source index
+         * @param errorCode ICU error code. Its input value must pass the U_SUCCESS() test,
+         *                  or else the function returns immediately. Check for U_FAILURE()
+         *                  on output or use with function chaining. (See User Guide for details.)
+         * @return destination index; undefined if i is not 0..string length
+         * @stable ICU 60
+         */
+        int32_t destinationIndexFromSourceIndex(int32_t i, UErrorCode &errorCode);
+
+        /**
+         * Computes the source index corresponding to the given destination index.
+         * If the destination index is inside a change edit (not at its start),
+         * then the source index at the end of that edit is returned,
+         * since there is no information about index mapping inside a change edit.
+         *
+         * (This means that indexes to the start and middle of an edit,
+         * for example around a grapheme cluster, are mapped to indexes
+         * encompassing the entire edit.
+         * The alternative, mapping an interior index to the start,
+         * would map such an interval to an empty one.)
+         *
+         * This operation will usually but not always modify this object.
+         * The iterator state after this search is undefined.
+         *
+         * @param i destination index
+         * @param errorCode ICU error code. Its input value must pass the U_SUCCESS() test,
+         *                  or else the function returns immediately. Check for U_FAILURE()
+         *                  on output or use with function chaining. (See User Guide for details.)
+         * @return source index; undefined if i is not 0..string length
+         * @stable ICU 60
+         */
+        int32_t sourceIndexFromDestinationIndex(int32_t i, UErrorCode &errorCode);
+
+        /**
+         * Returns whether the edit currently represented by the iterator is a change edit.
+         *
+         * @return true if this edit replaces oldLength() units with newLength() different ones.
+         *         false if oldLength units remain unchanged.
+         * @stable ICU 59
+         */
+        UBool hasChange() const { return changed; }
+
+        /**
+         * The length of the current span in the source string, which starts at {@link #sourceIndex}.
+         *
+         * @return the number of units in the original string which are replaced or remain unchanged.
+         * @stable ICU 59
+         */
+        int32_t oldLength() const { return oldLength_; }
+
+        /**
+         * The length of the current span in the destination string, which starts at
+         * {@link #destinationIndex}, or in the replacement string, which starts at
+         * {@link #replacementIndex}.
+         *
+         * @return the number of units in the modified string, if hasChange() is true.
+         *         Same as oldLength if hasChange() is false.
+         * @stable ICU 59
+         */
+        int32_t newLength() const { return newLength_; }
+
+        /**
+         * The start index of the current span in the source string; the span has length
+         * {@link #oldLength}.
+         *
+         * @return the current index into the source string
+         * @stable ICU 59
+         */
+        int32_t sourceIndex() const { return srcIndex; }
+
+        /**
+         * The start index of the current span in the replacement string; the span has length
+         * {@link #newLength}. Well-defined only if the current edit is a change edit.
+         *
+         * The *replacement string* is the concatenation of all substrings of the destination
+         * string corresponding to change edits.
+         *
+         * This method is intended to be used together with operations that write only replacement
+         * characters (e.g. operations specifying the \ref U_OMIT_UNCHANGED_TEXT option).
+         * The source string can then be modified in-place.
+         *
+         * @return the current index into the replacement-characters-only string,
+         *         not counting unchanged spans
+         * @stable ICU 59
+         */
+        int32_t replacementIndex() const {
+            // TODO: Throw an exception if we aren't in a change edit?
+            return replIndex;
+        }
+
+        /**
+         * The start index of the current span in the destination string; the span has length
+         * {@link #newLength}.
+         *
+         * @return the current index into the full destination string
+         * @stable ICU 59
+         */
+        int32_t destinationIndex() const { return destIndex; }
+
+#ifndef U_HIDE_INTERNAL_API
+        /**
+         * A string representation of the current edit represented by the iterator for debugging. You
+         * should not depend on the contents of the return string.
+         * @internal
+         */
+        UnicodeString& toString(UnicodeString& appendTo) const;
+#endif  // U_HIDE_INTERNAL_API
+
+    private:
+        friend class Edits;
+
+        Iterator(const uint16_t *a, int32_t len, UBool oc, UBool crs);
+
+        int32_t readLength(int32_t head);
+        void updateNextIndexes();
+        void updatePreviousIndexes();
+        UBool noNext();
+        UBool next(UBool onlyChanges, UErrorCode &errorCode);
+        UBool previous(UErrorCode &errorCode);
+        /** @return -1: error or i<0; 0: found; 1: i>=string length */
+        int32_t findIndex(int32_t i, UBool findSource, UErrorCode &errorCode);
+
+        const uint16_t *array;
+        int32_t index, length;
+        // 0 if we are not within compressed equal-length changes.
+        // Otherwise the number of remaining changes, including the current one.
+        int32_t remaining;
+        UBool onlyChanges_, coarse;
+
+        int8_t dir;  // iteration direction: back(<0), initial(0), forward(>0)
+        UBool changed;
+        int32_t oldLength_, newLength_;
+        int32_t srcIndex, replIndex, destIndex;
+    };
+
+    /**
+     * Returns an Iterator for coarse-grained change edits
+     * (adjacent change edits are treated as one).
+     * Can be used to perform simple string updates.
+     * Skips no-change edits.
+     * @return an Iterator that merges adjacent changes.
+     * @stable ICU 59
+     */
+    Iterator getCoarseChangesIterator() const {
+        return Iterator(array, length, true, true);
+    }
+
+    /**
+     * Returns an Iterator for coarse-grained change and no-change edits
+     * (adjacent change edits are treated as one).
+     * Can be used to perform simple string updates.
+     * Adjacent change edits are treated as one edit.
+     * @return an Iterator that merges adjacent changes.
+     * @stable ICU 59
+     */
+    Iterator getCoarseIterator() const {
+        return Iterator(array, length, false, true);
+    }
+
+    /**
+     * Returns an Iterator for fine-grained change edits
+     * (full granularity of change edits is retained).
+     * Can be used for modifying styled text.
+     * Skips no-change edits.
+     * @return an Iterator that separates adjacent changes.
+     * @stable ICU 59
+     */
+    Iterator getFineChangesIterator() const {
+        return Iterator(array, length, true, false);
+    }
+
+    /**
+     * Returns an Iterator for fine-grained change and no-change edits
+     * (full granularity of change edits is retained).
+     * Can be used for modifying styled text.
+     * @return an Iterator that separates adjacent changes.
+     * @stable ICU 59
+     */
+    Iterator getFineIterator() const {
+        return Iterator(array, length, false, false);
+    }
+
+    /**
+     * Merges the two input Edits and appends the result to this object.
+     *
+     * Consider two string transformations (for example, normalization and case mapping)
+     * where each records Edits in addition to writing an output string.<br>
+     * Edits ab reflect how substrings of input string a
+     * map to substrings of intermediate string b.<br>
+     * Edits bc reflect how substrings of intermediate string b
+     * map to substrings of output string c.<br>
+     * This function merges ab and bc such that the additional edits
+     * recorded in this object reflect how substrings of input string a
+     * map to substrings of output string c.
+     *
+     * If unrelated Edits are passed in where the output string of the first
+     * has a different length than the input string of the second,
+     * then a U_ILLEGAL_ARGUMENT_ERROR is reported.
+     *
+     * @param ab reflects how substrings of input string a
+     *     map to substrings of intermediate string b.
+     * @param bc reflects how substrings of intermediate string b
+     *     map to substrings of output string c.
+     * @param errorCode ICU error code. Its input value must pass the U_SUCCESS() test,
+     *                  or else the function returns immediately. Check for U_FAILURE()
+     *                  on output or use with function chaining. (See User Guide for details.)
+     * @return *this, with the merged edits appended
+     * @stable ICU 60
+     */
+    Edits &mergeAndAppend(const Edits &ab, const Edits &bc, UErrorCode &errorCode);
+
+private:
+    void releaseArray() U_NOEXCEPT;
+    Edits &copyArray(const Edits &other);
+    Edits &moveArray(Edits &src) U_NOEXCEPT;
+
+    void setLastUnit(int32_t last) { array[length - 1] = (uint16_t)last; }
+    int32_t lastUnit() const { return length > 0 ? array[length - 1] : 0xffff; }
+
+    void append(int32_t r);
+    UBool growArray();
+
+    static const int32_t STACK_CAPACITY = 100;
+    uint16_t *array;
+    int32_t capacity;
+    int32_t length;
+    int32_t delta;
+    int32_t numChanges;
+    UErrorCode errorCode_;
+    uint16_t stackArray[STACK_CAPACITY];
+};
+
+U_NAMESPACE_END
+
+#endif /* U_SHOW_CPLUSPLUS_API */
+
+#endif  // __EDITS_H__
diff --git a/src/third_party/icu/source/common/unicode/enumset.h b/src/third_party/icu/source/common/unicode/enumset.h
index 5106c37..6d7fa72 100644
--- a/src/third_party/icu/source/common/unicode/enumset.h
+++ b/src/third_party/icu/source/common/unicode/enumset.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
@@ -26,6 +28,7 @@
  * enum bitset for boolean fields. Similar to Java EnumSet<>. 
  * Needs to range check. Used for private instance variables.
  * @internal
+ * \cond
  */
 template<typename T, uint32_t minValue, uint32_t limitValue>
 class EnumSet {
@@ -40,7 +43,7 @@
     inline int32_t contains(T toCheck) const { return get(toCheck); }
     inline void set(T toSet, int32_t v) { fBools=(fBools&(~flag(toSet)))|(v?(flag(toSet)):0); }
     inline int32_t get(T toCheck) const { return (fBools & flag(toCheck))?1:0; }
-    inline UBool isValidEnum(T toCheck) const {  return (toCheck>=minValue&&toCheck<limitValue); }
+    inline UBool isValidEnum(T toCheck) const {  return ((uint32_t)toCheck>=minValue&&(uint32_t)toCheck<limitValue); }
     inline UBool isValidValue(int32_t v) const { return (v==0||v==1); }
     inline const EnumSet<T,minValue,limitValue>& operator=(const EnumSet<T,minValue,limitValue>& other) {
         fBools = other.fBools;
@@ -58,6 +61,8 @@
     uint32_t fBools;
 };
 
+/** \endcond */
+
 U_NAMESPACE_END
 
 #endif /* U_SHOW_CPLUSPLUS_API */
diff --git a/src/third_party/icu/source/common/unicode/errorcode.h b/src/third_party/icu/source/common/unicode/errorcode.h
index 3b60181..fe7b518 100644
--- a/src/third_party/icu/source/common/unicode/errorcode.h
+++ b/src/third_party/icu/source/common/unicode/errorcode.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  errorcode.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -24,6 +26,9 @@
  */
 
 #include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
 #include "unicode/uobject.h"
 
 U_NAMESPACE_BEGIN
@@ -134,4 +139,6 @@
 
 U_NAMESPACE_END
 
+#endif /* U_SHOW_CPLUSPLUS_API */
+
 #endif  // __ERRORCODE_H__
diff --git a/src/third_party/icu/source/common/unicode/filteredbrk.h b/src/third_party/icu/source/common/unicode/filteredbrk.h
index fff9bb5..8b07e39 100644
--- a/src/third_party/icu/source/common/unicode/filteredbrk.h
+++ b/src/third_party/icu/source/common/unicode/filteredbrk.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ********************************************************************************
 *   Copyright (C) 1997-2015, International Business Machines
@@ -9,12 +11,13 @@
 #define FILTEREDBRK_H
 
 #include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
 #include "unicode/brkiter.h"
 
 #if !UCONFIG_NO_BREAK_ITERATION && !UCONFIG_NO_FILTERED_BREAK_ITERATION
 
-#ifndef U_HIDE_DRAFT_API
-
 U_NAMESPACE_BEGIN
 
 /**
@@ -31,13 +34,13 @@
  *  but with "Mr." as an exception, a filtered break iterator
  *  would consider the string "Mr. Smith" to be a single segment.
  *
- * @draft ICU 56
+ * @stable ICU 56
  */
 class U_COMMON_API FilteredBreakIteratorBuilder : public UObject {
  public:
   /**
    *  destructor.
-   * @draft ICU 56
+   * @stable ICU 56
    */
   virtual ~FilteredBreakIteratorBuilder();
 
@@ -51,18 +54,30 @@
    * @param where the locale.
    * @param status The error code.
    * @return the new builder
-   * @draft ICU 56
+   * @stable ICU 56
    */
   static FilteredBreakIteratorBuilder *createInstance(const Locale& where, UErrorCode& status);
 
+#ifndef U_HIDE_DEPRECATED_API
+  /**
+   * This function has been deprecated in favor of createEmptyInstance, which has
+   * identical behavior.
+   * @param status The error code.
+   * @return the new builder
+   * @deprecated ICU 60 use createEmptyInstance instead
+   * @see createEmptyInstance()
+   */
+  static FilteredBreakIteratorBuilder *createInstance(UErrorCode &status);
+#endif  /* U_HIDE_DEPRECATED_API */
+
   /**
    * Construct an empty FilteredBreakIteratorBuilder.
    * In this state, it will not suppress any segment boundaries.
    * @param status The error code.
    * @return the new builder
-   * @draft ICU 56
+   * @stable ICU 60
    */
-  static FilteredBreakIteratorBuilder *createInstance(UErrorCode &status);
+  static FilteredBreakIteratorBuilder *createEmptyInstance(UErrorCode &status);
 
   /**
    * Suppress a certain string from being the end of a segment.
@@ -70,9 +85,9 @@
    * by the iterator.
    * @param string the string to suppress, such as "Mr."
    * @param status error code
-   * @return returns TRUE if the string was not present and now added,
-   * FALSE if the call was a no-op because the string was already being suppressed.
-   * @draft ICU 56
+   * @return returns true if the string was not present and now added,
+   * false if the call was a no-op because the string was already being suppressed.
+   * @stable ICU 56
    */
   virtual UBool suppressBreakAfter(const UnicodeString& string, UErrorCode& status) = 0;
 
@@ -81,14 +96,27 @@
    * This function does not create any new segment boundaries, but only serves to un-do
    * the effect of earlier calls to suppressBreakAfter, or to un-do the effect of
    * locale data which may be suppressing certain strings.
-   * @param exception the exception to remove
+   * @param string the exception to remove
    * @param status error code
-   * @return returns TRUE if the string was present and now removed,
-   * FALSE if the call was a no-op because the string was not being suppressed.
-   * @draft ICU 56
+   * @return returns true if the string was present and now removed,
+   * false if the call was a no-op because the string was not being suppressed.
+   * @stable ICU 56
    */
   virtual UBool unsuppressBreakAfter(const UnicodeString& string, UErrorCode& status) = 0;
 
+#ifndef U_FORCE_HIDE_DEPRECATED_API
+  /**
+   * This function has been deprecated in favor of wrapIteratorWithFilter()
+   * The behavior is identical.
+   * @param adoptBreakIterator the break iterator to adopt
+   * @param status error code
+   * @return the new BreakIterator, owned by the caller.
+   * @deprecated ICU 60 use wrapIteratorWithFilter() instead
+   * @see wrapBreakIteratorWithFilter()
+   */
+  virtual BreakIterator *build(BreakIterator* adoptBreakIterator, UErrorCode& status) = 0;
+#endif  // U_FORCE_HIDE_DEPRECATED_API
+
   /**
    * Wrap (adopt) an existing break iterator in a new filtered instance.
    * The resulting BreakIterator is owned by the caller.
@@ -96,17 +124,20 @@
    * Note that the adoptBreakIterator is adopted by the new BreakIterator
    * and should no longer be used by the caller.
    * The FilteredBreakIteratorBuilder may be reused.
+   * This function is an alias for build()
    * @param adoptBreakIterator the break iterator to adopt
    * @param status error code
    * @return the new BreakIterator, owned by the caller.
-   * @draft ICU 56
+   * @stable ICU 60
    */
-  virtual BreakIterator *build(BreakIterator* adoptBreakIterator, UErrorCode& status) = 0;
+  inline BreakIterator *wrapIteratorWithFilter(BreakIterator* adoptBreakIterator, UErrorCode& status) {
+    return build(adoptBreakIterator, status);
+  }
 
  protected:
   /**
    * For subclass use
-   * @draft ICU 56
+   * @stable ICU 56
    */
   FilteredBreakIteratorBuilder();
 };
@@ -114,8 +145,8 @@
 
 U_NAMESPACE_END
 
-#endif  /* U_HIDE_DRAFT_API */
-
 #endif // #if !UCONFIG_NO_BREAK_ITERATION && !UCONFIG_NO_FILTERED_BREAK_ITERATION
 
+#endif /* U_SHOW_CPLUSPLUS_API */
+
 #endif // #ifndef FILTEREDBRK_H
diff --git a/src/third_party/icu/source/common/unicode/icudataver.h b/src/third_party/icu/source/common/unicode/icudataver.h
index 609f580..f218ed8 100644
--- a/src/third_party/icu/source/common/unicode/icudataver.h
+++ b/src/third_party/icu/source/common/unicode/icudataver.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
@@ -36,6 +38,6 @@
  * 
  * @stable ICU 49
  */
-U_STABLE void U_EXPORT2 u_getDataVersion(UVersionInfo dataVersionFillin, UErrorCode *status);
+U_CAPI void U_EXPORT2 u_getDataVersion(UVersionInfo dataVersionFillin, UErrorCode *status);
 
 #endif
diff --git a/src/third_party/icu/source/common/unicode/icuplug.h b/src/third_party/icu/source/common/unicode/icuplug.h
index 3a600f7..52f810d 100644
--- a/src/third_party/icu/source/common/unicode/icuplug.h
+++ b/src/third_party/icu/source/common/unicode/icuplug.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
@@ -108,7 +110,7 @@
 #include "unicode/utypes.h"
 
 
-#if UCONFIG_ENABLE_PLUGINS
+#if UCONFIG_ENABLE_PLUGINS || defined(U_IN_DOXYGEN)
 
 
 
@@ -157,7 +159,11 @@
     UPLUG_REASON_QUERY = 0,     /**< The plugin is being queried for info. **/
     UPLUG_REASON_LOAD = 1,     /**< The plugin is being loaded. **/
     UPLUG_REASON_UNLOAD = 2,   /**< The plugin is being unloaded. **/
-    UPLUG_REASON_COUNT         /**< count of known reasons **/
+    /**
+     * Number of known reasons.
+     * @internal The numeric value may change over time, see ICU ticket #12420.
+     */
+    UPLUG_REASON_COUNT
 } UPlugReason;
 
 
@@ -173,7 +179,11 @@
     UPLUG_LEVEL_UNKNOWN = 1,     /**< The plugin is waiting to be installed. **/
     UPLUG_LEVEL_LOW     = 2,     /**< The plugin must be called before u_init completes **/
     UPLUG_LEVEL_HIGH    = 3,     /**< The plugin can run at any time. **/
-    UPLUG_LEVEL_COUNT         /**< count of known reasons **/
+    /**
+     * Number of known levels.
+     * @internal The numeric value may change over time, see ICU ticket #12420.
+     */
+    UPLUG_LEVEL_COUNT
 } UPlugLevel;
 
 /**
@@ -198,7 +208,7 @@
  * @param dontUnload  set true if this plugin can't be unloaded
  * @internal ICU 4.4 Technology Preview
  */
-U_INTERNAL void U_EXPORT2 
+U_CAPI void U_EXPORT2 
 uplug_setPlugNoUnload(UPlugData *plug, UBool dontUnload);
 
 /**
@@ -207,7 +217,7 @@
  * @param level the level of this plugin
  * @internal ICU 4.4 Technology Preview
  */
-U_INTERNAL void U_EXPORT2
+U_CAPI void U_EXPORT2
 uplug_setPlugLevel(UPlugData *plug, UPlugLevel level);
 
 /**
@@ -216,7 +226,7 @@
  * @return the level of this plugin
  * @internal ICU 4.4 Technology Preview
  */
-U_INTERNAL UPlugLevel U_EXPORT2
+U_CAPI UPlugLevel U_EXPORT2
 uplug_getPlugLevel(UPlugData *plug);
 
 /**
@@ -226,7 +236,7 @@
  * @return the lowest level of plug which can currently load
  * @internal ICU 4.4 Technology Preview
  */
-U_INTERNAL UPlugLevel U_EXPORT2
+U_CAPI UPlugLevel U_EXPORT2
 uplug_getCurrentLevel(void);
 
 
@@ -235,7 +245,7 @@
  * @return The error code of this plugin's load attempt.
  * @internal ICU 4.4 Technology Preview
  */
-U_INTERNAL UErrorCode U_EXPORT2
+U_CAPI UErrorCode U_EXPORT2
 uplug_getPlugLoadStatus(UPlugData *plug); 
 
 /**
@@ -244,7 +254,7 @@
  * @param name the name of this plugin. The first UPLUG_NAME_MAX characters willi be copied into a new buffer.
  * @internal ICU 4.4 Technology Preview
  */
-U_INTERNAL void U_EXPORT2
+U_CAPI void U_EXPORT2
 uplug_setPlugName(UPlugData *plug, const char *name);
 
 /**
@@ -253,7 +263,7 @@
  * @return the name of this plugin
  * @internal ICU 4.4 Technology Preview
  */
-U_INTERNAL const char * U_EXPORT2
+U_CAPI const char * U_EXPORT2
 uplug_getPlugName(UPlugData *plug);
 
 /**
@@ -262,7 +272,7 @@
  * @return the symbol name, or NULL
  * @internal ICU 4.4 Technology Preview
  */
-U_INTERNAL const char * U_EXPORT2
+U_CAPI const char * U_EXPORT2
 uplug_getSymbolName(UPlugData *plug);
 
 /**
@@ -272,7 +282,7 @@
  * @return the library name, or NULL
  * @internal ICU 4.4 Technology Preview
  */
-U_INTERNAL const char * U_EXPORT2
+U_CAPI const char * U_EXPORT2
 uplug_getLibraryName(UPlugData *plug, UErrorCode *status);
 
 /**
@@ -282,7 +292,7 @@
  * @return the library, or NULL
  * @internal ICU 4.4 Technology Preview
  */
-U_INTERNAL void * U_EXPORT2
+U_CAPI void * U_EXPORT2
 uplug_getLibrary(UPlugData *plug);
 
 /**
@@ -291,7 +301,7 @@
  * @return the context, or NULL if not set
  * @internal ICU 4.4 Technology Preview
  */
-U_INTERNAL void * U_EXPORT2
+U_CAPI void * U_EXPORT2
 uplug_getContext(UPlugData *plug);
 
 /**
@@ -300,7 +310,7 @@
  * @param context new context to set
  * @internal ICU 4.4 Technology Preview
  */
-U_INTERNAL void U_EXPORT2
+U_CAPI void U_EXPORT2
 uplug_setContext(UPlugData *plug, void *context);
 
 
@@ -311,7 +321,7 @@
  * @return configuration string, or else null.
  * @internal ICU 4.4 Technology Preview
  */
-U_INTERNAL const char * U_EXPORT2
+U_CAPI const char * U_EXPORT2
 uplug_getConfiguration(UPlugData *plug);
 
 /**
@@ -329,7 +339,7 @@
  * @return the next oldest plugin, or NULL if no more.
  * @internal ICU 4.4 Technology Preview
  */
-U_INTERNAL UPlugData* U_EXPORT2
+U_CAPI UPlugData* U_EXPORT2
 uplug_nextPlug(UPlugData *prior);
 
 /**
@@ -344,7 +354,7 @@
  * @return the new UPlugData associated with this plugin, or NULL if error.
  * @internal ICU 4.4 Technology Preview
  */
-U_INTERNAL UPlugData* U_EXPORT2
+U_CAPI UPlugData* U_EXPORT2
 uplug_loadPlugFromEntrypoint(UPlugEntrypoint *entrypoint, const char *config, UErrorCode *status);
 
 
@@ -358,7 +368,7 @@
  * @return the new UPlugData associated with this plugin, or NULL if error.
  * @internal ICU 4.4 Technology Preview
  */
-U_INTERNAL UPlugData* U_EXPORT2
+U_CAPI UPlugData* U_EXPORT2
 uplug_loadPlugFromLibrary(const char *libName, const char *sym, const char *config, UErrorCode *status);
 
 /**
@@ -368,7 +378,7 @@
  * @param status error result
  * @internal ICU 4.4 Technology Preview
  */
-U_INTERNAL void U_EXPORT2
+U_CAPI void U_EXPORT2
 uplug_removePlug(UPlugData *plug, UErrorCode *status);
 #endif  /* U_HIDE_INTERNAL_API */
 
diff --git a/src/third_party/icu/source/common/unicode/idna.h b/src/third_party/icu/source/common/unicode/idna.h
index 90194a3..1305dc6 100644
--- a/src/third_party/icu/source/common/unicode/idna.h
+++ b/src/third_party/icu/source/common/unicode/idna.h
@@ -1,10 +1,12 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *   Copyright (C) 2010-2012, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *******************************************************************************
 *   file name:  idna.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -22,6 +24,8 @@
 
 #include "unicode/utypes.h"
 
+#if U_SHOW_CPLUSPLUS_API
+
 #if !UCONFIG_NO_IDNA
 
 #include "unicode/bytestream.h"
@@ -91,7 +95,7 @@
 
     /**
      * Converts a single domain name label into its ASCII form for DNS lookup.
-     * If any processing step fails, then info.hasErrors() will be TRUE and
+     * If any processing step fails, then info.hasErrors() will be true and
      * the result might not be an ASCII string.
      * The label might be modified according to the types of errors.
      * Labels with severe errors will be left in (or turned into) their Unicode form.
@@ -115,7 +119,7 @@
 
     /**
      * Converts a single domain name label into its Unicode form for human-readable display.
-     * If any processing step fails, then info.hasErrors() will be TRUE.
+     * If any processing step fails, then info.hasErrors() will be true.
      * The label might be modified according to the types of errors.
      *
      * The UErrorCode indicates an error only in exceptional cases,
@@ -137,7 +141,7 @@
 
     /**
      * Converts a whole domain name into its ASCII form for DNS lookup.
-     * If any processing step fails, then info.hasErrors() will be TRUE and
+     * If any processing step fails, then info.hasErrors() will be true and
      * the result might not be an ASCII string.
      * The domain name might be modified according to the types of errors.
      * Labels with severe errors will be left in (or turned into) their Unicode form.
@@ -161,7 +165,7 @@
 
     /**
      * Converts a whole domain name into its Unicode form for human-readable display.
-     * If any processing step fails, then info.hasErrors() will be TRUE.
+     * If any processing step fails, then info.hasErrors() will be true.
      * The domain name might be modified according to the types of errors.
      *
      * The UErrorCode indicates an error only in exceptional cases,
@@ -198,7 +202,7 @@
      * @stable ICU 4.6
      */
     virtual void
-    labelToASCII_UTF8(const StringPiece &label, ByteSink &dest,
+    labelToASCII_UTF8(StringPiece label, ByteSink &dest,
                       IDNAInfo &info, UErrorCode &errorCode) const;
 
     /**
@@ -216,7 +220,7 @@
      * @stable ICU 4.6
      */
     virtual void
-    labelToUnicodeUTF8(const StringPiece &label, ByteSink &dest,
+    labelToUnicodeUTF8(StringPiece label, ByteSink &dest,
                        IDNAInfo &info, UErrorCode &errorCode) const;
 
     /**
@@ -234,7 +238,7 @@
      * @stable ICU 4.6
      */
     virtual void
-    nameToASCII_UTF8(const StringPiece &name, ByteSink &dest,
+    nameToASCII_UTF8(StringPiece name, ByteSink &dest,
                      IDNAInfo &info, UErrorCode &errorCode) const;
 
     /**
@@ -252,7 +256,7 @@
      * @stable ICU 4.6
      */
     virtual void
-    nameToUnicodeUTF8(const StringPiece &name, ByteSink &dest,
+    nameToUnicodeUTF8(StringPiece name, ByteSink &dest,
                       IDNAInfo &info, UErrorCode &errorCode) const;
 };
 
@@ -269,10 +273,10 @@
      * Constructor for stack allocation.
      * @stable ICU 4.6
      */
-    IDNAInfo() : errors(0), labelErrors(0), isTransDiff(FALSE), isBiDi(FALSE), isOkBiDi(TRUE) {}
+    IDNAInfo() : errors(0), labelErrors(0), isTransDiff(false), isBiDi(false), isOkBiDi(true) {}
     /**
      * Were there IDNA processing errors?
-     * @return TRUE if there were processing errors
+     * @return true if there were processing errors
      * @stable ICU 4.6
      */
     UBool hasErrors() const { return errors!=0; }
@@ -284,7 +288,7 @@
      */
     uint32_t getErrors() const { return errors; }
     /**
-     * Returns TRUE if transitional and nontransitional processing produce different results.
+     * Returns true if transitional and nontransitional processing produce different results.
      * This is the case when the input label or domain name contains
      * one or more deviation characters outside a Punycode label (see UTS #46).
      * <ul>
@@ -293,7 +297,7 @@
      * <li>With transitional processing, such characters are
      * mapped (sharp s/sigma) or removed (joiner/nonjoiner).
      * </ul>
-     * @return TRUE if transitional and nontransitional processing produce different results
+     * @return true if transitional and nontransitional processing produce different results
      * @stable ICU 4.6
      */
     UBool isTransitionalDifferent() const { return isTransDiff; }
@@ -306,9 +310,9 @@
 
     void reset() {
         errors=labelErrors=0;
-        isTransDiff=FALSE;
-        isBiDi=FALSE;
-        isOkBiDi=TRUE;
+        isTransDiff=false;
+        isBiDi=false;
+        isOkBiDi=true;
     }
 
     uint32_t errors, labelErrors;
@@ -320,4 +324,7 @@
 U_NAMESPACE_END
 
 #endif  // UCONFIG_NO_IDNA
+
+#endif /* U_SHOW_CPLUSPLUS_API */
+
 #endif  // __IDNA_H__
diff --git a/src/third_party/icu/source/common/unicode/listformatter.h b/src/third_party/icu/source/common/unicode/listformatter.h
deleted file mode 100644
index e48faaa..0000000
--- a/src/third_party/icu/source/common/unicode/listformatter.h
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
-*******************************************************************************
-*
-*   Copyright (C) 2012-2014, International Business Machines
-*   Corporation and others.  All Rights Reserved.
-*
-*******************************************************************************
-*   file name:  listformatter.h
-*   encoding:   US-ASCII
-*   tab size:   8 (not used)
-*   indentation:4
-*
-*   created on: 20120426
-*   created by: Umesh P. Nair
-*/
-
-#ifndef __LISTFORMATTER_H__
-#define __LISTFORMATTER_H__
-
-#include "unicode/utypes.h"
-
-#include "unicode/unistr.h"
-#include "unicode/locid.h"
-
-U_NAMESPACE_BEGIN
-
-/** @internal */
-class Hashtable;
-
-/** @internal */
-struct ListFormatInternal;
-
-/* The following can't be #ifndef U_HIDE_INTERNAL_API, needed for other .h file declarations */
-/** @internal */
-struct ListFormatData : public UMemory {
-    UnicodeString twoPattern;
-    UnicodeString startPattern;
-    UnicodeString middlePattern;
-    UnicodeString endPattern;
-
-  ListFormatData(const UnicodeString& two, const UnicodeString& start, const UnicodeString& middle, const UnicodeString& end) :
-      twoPattern(two), startPattern(start), middlePattern(middle), endPattern(end) {}
-};
-
-
-/**
- * \file
- * \brief C++ API: API for formatting a list.
- */
-
-
-/**
- * An immutable class for formatting a list, using data from CLDR (or supplied
- * separately).
- *
- * Example: Input data ["Alice", "Bob", "Charlie", "Delta"] will be formatted
- * as "Alice, Bob, Charlie and Delta" in English.
- *
- * The ListFormatter class is not intended for public subclassing.
- * @stable ICU 50
- */
-class U_COMMON_API ListFormatter : public UObject{
-
-  public:
-
-    /**
-     * Copy constructor.
-     * @stable ICU 52
-     */
-    ListFormatter(const ListFormatter&);
-
-    /**
-     * Assignment operator.
-     * @stable ICU 52
-     */
-    ListFormatter& operator=(const ListFormatter& other);
-
-    /**
-     * Creates a ListFormatter appropriate for the default locale.
-     *
-     * @param errorCode ICU error code, set if no data available for default locale.
-     * @return Pointer to a ListFormatter object for the default locale,
-     *     created from internal data derived from CLDR data.
-     * @stable ICU 50
-     */
-    static ListFormatter* createInstance(UErrorCode& errorCode);
-
-    /**
-     * Creates a ListFormatter appropriate for a locale.
-     *
-     * @param locale The locale.
-     * @param errorCode ICU error code, set if no data available for the given locale.
-     * @return A ListFormatter object created from internal data derived from
-     *     CLDR data.
-     * @stable ICU 50
-     */
-    static ListFormatter* createInstance(const Locale& locale, UErrorCode& errorCode);
-
-#ifndef U_HIDE_INTERNAL_API
-    /**
-     * Creates a ListFormatter appropriate for a locale and style.
-     *
-     * @param locale The locale.
-     * @param style the style, either "standard", "duration", or "duration-short"
-     * @param errorCode ICU error code, set if no data available for the given locale.
-     * @return A ListFormatter object created from internal data derived from
-     *     CLDR data.
-     * @internal
-     */
-    static ListFormatter* createInstance(const Locale& locale, const char* style, UErrorCode& errorCode);
-#endif  /* U_HIDE_INTERNAL_API */
-
-    /**
-     * Destructor.
-     *
-     * @stable ICU 50
-     */
-    virtual ~ListFormatter();
-
-
-    /**
-     * Formats a list of strings.
-     *
-     * @param items An array of strings to be combined and formatted.
-     * @param n_items Length of the array items.
-     * @param appendTo The string to which the result should be appended to.
-     * @param errorCode ICU error code, set if there is an error.
-     * @return Formatted string combining the elements of items, appended to appendTo.
-     * @stable ICU 50
-     */
-    UnicodeString& format(const UnicodeString items[], int32_t n_items,
-        UnicodeString& appendTo, UErrorCode& errorCode) const;
-
-#ifndef U_HIDE_INTERNAL_API
-    /**
-      @internal for MeasureFormat
-    */
-    UnicodeString& format(
-            const UnicodeString items[],
-            int32_t n_items,
-            UnicodeString& appendTo,
-            int32_t index,
-            int32_t &offset,
-            UErrorCode& errorCode) const;
-    /**
-     * @internal constructor made public for testing.
-     */
-    ListFormatter(const ListFormatData &data);
-    /**
-     * @internal constructor made public for testing.
-     */
-    ListFormatter(const ListFormatInternal* listFormatterInternal);
-#endif  /* U_HIDE_INTERNAL_API */
-
-  private:
-    static void initializeHash(UErrorCode& errorCode);
-    static const ListFormatInternal* getListFormatInternal(const Locale& locale, const char *style, UErrorCode& errorCode);
-
-    ListFormatter();
-
-    ListFormatInternal* owned;
-    const ListFormatInternal* data;
-};
-
-U_NAMESPACE_END
-
-#endif
diff --git a/src/third_party/icu/source/common/unicode/localebuilder.h b/src/third_party/icu/source/common/unicode/localebuilder.h
new file mode 100644
index 0000000..27a894d
--- /dev/null
+++ b/src/third_party/icu/source/common/unicode/localebuilder.h
@@ -0,0 +1,311 @@
+// © 2018 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+#ifndef __LOCALEBUILDER_H__
+#define __LOCALEBUILDER_H__
+
+#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
+#include "unicode/locid.h"
+#include "unicode/localematcher.h"
+#include "unicode/stringpiece.h"
+#include "unicode/uobject.h"
+
+/**
+ * \file
+ * \brief C++ API: Builder API for Locale
+ */
+
+U_NAMESPACE_BEGIN
+class CharString;
+
+/**
+ * <code>LocaleBuilder</code> is used to build instances of <code>Locale</code>
+ * from values configured by the setters.  Unlike the <code>Locale</code>
+ * constructors, the <code>LocaleBuilder</code> checks if a value configured by a
+ * setter satisfies the syntax requirements defined by the <code>Locale</code>
+ * class.  A <code>Locale</code> object created by a <code>LocaleBuilder</code> is
+ * well-formed and can be transformed to a well-formed IETF BCP 47 language tag
+ * without losing information.
+ *
+ * <p>The following example shows how to create a <code>Locale</code> object
+ * with the <code>LocaleBuilder</code>.
+ * <blockquote>
+ * <pre>
+ *     UErrorCode status = U_ZERO_ERROR;
+ *     Locale aLocale = LocaleBuilder()
+ *                          .setLanguage("sr")
+ *                          .setScript("Latn")
+ *                          .setRegion("RS")
+ *                          .build(status);
+ *     if (U_SUCCESS(status)) {
+ *       // ...
+ *     }
+ * </pre>
+ * </blockquote>
+ *
+ * <p>LocaleBuilders can be reused; <code>clear()</code> resets all
+ * fields to their default values.
+ *
+ * <p>LocaleBuilder tracks errors in an internal UErrorCode. For all setters,
+ * except setLanguageTag and setLocale, LocaleBuilder will return immediately
+ * if the internal UErrorCode is in error state.
+ * To reset internal state and error code, call clear method.
+ * The setLanguageTag and setLocale method will first clear the internal
+ * UErrorCode, then track the error of the validation of the input parameter
+ * into the internal UErrorCode.
+ *
+ * @stable ICU 64
+ */
+class U_COMMON_API LocaleBuilder : public UObject {
+public:
+    /**
+     * Constructs an empty LocaleBuilder. The default value of all
+     * fields, extensions, and private use information is the
+     * empty string.
+     *
+     * @stable ICU 64
+     */
+    LocaleBuilder();
+
+    /**
+     * Destructor
+     * @stable ICU 64
+     */
+    virtual ~LocaleBuilder();
+
+    /**
+     * Resets the <code>LocaleBuilder</code> to match the provided
+     * <code>locale</code>.  Existing state is discarded.
+     *
+     * <p>All fields of the locale must be well-formed.
+     * <p>This method clears the internal UErrorCode.
+     *
+     * @param locale the locale
+     * @return This builder.
+     *
+     * @stable ICU 64
+     */
+    LocaleBuilder& setLocale(const Locale& locale);
+
+    /**
+     * Resets the LocaleBuilder to match the provided
+     * [Unicode Locale Identifier](http://www.unicode.org/reports/tr35/tr35.html#unicode_locale_id) .
+     * Discards the existing state.
+     * The empty string causes the builder to be reset, like {@link #clear}.
+     * Legacy language tags (marked as “Type: grandfathered” in BCP 47)
+     * are converted to their canonical form before being processed.
+     * Otherwise, the <code>language tag</code> must be well-formed,
+     * or else the build() method will later report an U_ILLEGAL_ARGUMENT_ERROR.
+     *
+     * <p>This method clears the internal UErrorCode.
+     *
+     * @param tag the language tag, defined as
+     *   [unicode_locale_id](http://www.unicode.org/reports/tr35/tr35.html#unicode_locale_id).
+     * @return This builder.
+     * @stable ICU 64
+     */
+    LocaleBuilder& setLanguageTag(StringPiece tag);
+
+    /**
+     * Sets the language.  If <code>language</code> is the empty string, the
+     * language in this <code>LocaleBuilder</code> is removed. Otherwise, the
+     * <code>language</code> must be well-formed, or else the build() method will
+     * later report an U_ILLEGAL_ARGUMENT_ERROR.
+     *
+     * <p>The syntax of language value is defined as
+     * [unicode_language_subtag](http://www.unicode.org/reports/tr35/tr35.html#unicode_language_subtag).
+     *
+     * @param language the language
+     * @return This builder.
+     * @stable ICU 64
+     */
+    LocaleBuilder& setLanguage(StringPiece language);
+
+    /**
+     * Sets the script. If <code>script</code> is the empty string, the script in
+     * this <code>LocaleBuilder</code> is removed.
+     * Otherwise, the <code>script</code> must be well-formed, or else the build()
+     * method will later report an U_ILLEGAL_ARGUMENT_ERROR.
+     *
+     * <p>The script value is a four-letter script code as
+     * [unicode_script_subtag](http://www.unicode.org/reports/tr35/tr35.html#unicode_script_subtag)
+     * defined by ISO 15924
+     *
+     * @param script the script
+     * @return This builder.
+     * @stable ICU 64
+     */
+    LocaleBuilder& setScript(StringPiece script);
+
+    /**
+     * Sets the region.  If region is the empty string, the region in this
+     * <code>LocaleBuilder</code> is removed. Otherwise, the <code>region</code>
+     * must be well-formed, or else the build() method will later report an
+     * U_ILLEGAL_ARGUMENT_ERROR.
+     *
+     * <p>The region value is defined by
+     *  [unicode_region_subtag](http://www.unicode.org/reports/tr35/tr35.html#unicode_region_subtag)
+     * as a two-letter ISO 3166 code or a three-digit UN M.49 area code.
+     *
+     * <p>The region value in the <code>Locale</code> created by the
+     * <code>LocaleBuilder</code> is always normalized to upper case.
+     *
+     * @param region the region
+     * @return This builder.
+     * @stable ICU 64
+     */
+    LocaleBuilder& setRegion(StringPiece region);
+
+    /**
+     * Sets the variant.  If variant is the empty string, the variant in this
+     * <code>LocaleBuilder</code> is removed.  Otherwise, the <code>variant</code>
+     * must be well-formed, or else the build() method will later report an
+     * U_ILLEGAL_ARGUMENT_ERROR.
+     *
+     * <p><b>Note:</b> This method checks if <code>variant</code>
+     * satisfies the
+     * [unicode_variant_subtag](http://www.unicode.org/reports/tr35/tr35.html#unicode_variant_subtag)
+     * syntax requirements, and normalizes the value to lowercase letters. However,
+     * the <code>Locale</code> class does not impose any syntactic
+     * restriction on variant. To set an ill-formed variant, use a Locale constructor.
+     * If there are multiple unicode_variant_subtag, the caller must concatenate
+     * them with '-' as separator (ex: "foobar-fibar").
+     *
+     * @param variant the variant
+     * @return This builder.
+     * @stable ICU 64
+     */
+    LocaleBuilder& setVariant(StringPiece variant);
+
+    /**
+     * Sets the extension for the given key. If the value is the empty string,
+     * the extension is removed.  Otherwise, the <code>key</code> and
+     * <code>value</code> must be well-formed, or else the build() method will
+     * later report an U_ILLEGAL_ARGUMENT_ERROR.
+     *
+     * <p><b>Note:</b> The key ('u') is used for the Unicode locale extension.
+     * Setting a value for this key replaces any existing Unicode locale key/type
+     * pairs with those defined in the extension.
+     *
+     * <p><b>Note:</b> The key ('x') is used for the private use code. To be
+     * well-formed, the value for this key needs only to have subtags of one to
+     * eight alphanumeric characters, not two to eight as in the general case.
+     *
+     * @param key the extension key
+     * @param value the extension value
+     * @return This builder.
+     * @stable ICU 64
+     */
+    LocaleBuilder& setExtension(char key, StringPiece value);
+
+    /**
+     * Sets the Unicode locale keyword type for the given key. If the type
+     * StringPiece is constructed with a nullptr, the keyword is removed.
+     * If the type is the empty string, the keyword is set without type subtags.
+     * Otherwise, the key and type must be well-formed, or else the build()
+     * method will later report an U_ILLEGAL_ARGUMENT_ERROR.
+     *
+     * <p>Keys and types are converted to lower case.
+     *
+     * <p><b>Note</b>:Setting the 'u' extension via {@link #setExtension}
+     * replaces all Unicode locale keywords with those defined in the
+     * extension.
+     *
+     * @param key the Unicode locale key
+     * @param type the Unicode locale type
+     * @return This builder.
+     * @stable ICU 64
+     */
+    LocaleBuilder& setUnicodeLocaleKeyword(
+        StringPiece key, StringPiece type);
+
+    /**
+     * Adds a unicode locale attribute, if not already present, otherwise
+     * has no effect.  The attribute must not be empty string and must be
+     * well-formed or U_ILLEGAL_ARGUMENT_ERROR will be set to status
+     * during the build() call.
+     *
+     * @param attribute the attribute
+     * @return This builder.
+     * @stable ICU 64
+     */
+    LocaleBuilder& addUnicodeLocaleAttribute(StringPiece attribute);
+
+    /**
+     * Removes a unicode locale attribute, if present, otherwise has no
+     * effect.  The attribute must not be empty string and must be well-formed
+     * or U_ILLEGAL_ARGUMENT_ERROR will be set to status during the build() call.
+     *
+     * <p>Attribute comparison for removal is case-insensitive.
+     *
+     * @param attribute the attribute
+     * @return This builder.
+     * @stable ICU 64
+     */
+    LocaleBuilder& removeUnicodeLocaleAttribute(StringPiece attribute);
+
+    /**
+     * Resets the builder to its initial, empty state.
+     * <p>This method clears the internal UErrorCode.
+     *
+     * @return this builder
+     * @stable ICU 64
+     */
+    LocaleBuilder& clear();
+
+    /**
+     * Resets the extensions to their initial, empty state.
+     * Language, script, region and variant are unchanged.
+     *
+     * @return this builder
+     * @stable ICU 64
+     */
+    LocaleBuilder& clearExtensions();
+
+    /**
+     * Returns an instance of <code>Locale</code> created from the fields set
+     * on this builder.
+     * If any set methods or during the build() call require memory allocation
+     * but fail U_MEMORY_ALLOCATION_ERROR will be set to status.
+     * If any of the fields set by the setters are not well-formed, the status
+     * will be set to U_ILLEGAL_ARGUMENT_ERROR. The state of the builder will
+     * not change after the build() call and the caller is free to keep using
+     * the same builder to build more locales.
+     *
+     * @return a new Locale
+     * @stable ICU 64
+     */
+    Locale build(UErrorCode& status);
+
+    /**
+     * Sets the UErrorCode if an error occurred while recording sets.
+     * Preserves older error codes in the outErrorCode.
+     * @param outErrorCode Set to an error code that occurred while setting subtags.
+     *                  Unchanged if there is no such error or if outErrorCode
+     *                  already contained an error.
+     * @return true if U_FAILURE(outErrorCode)
+     * @stable ICU 65
+     */
+    UBool copyErrorTo(UErrorCode &outErrorCode) const;
+
+private:
+    friend class LocaleMatcher::Result;
+
+    void copyExtensionsFrom(const Locale& src, UErrorCode& errorCode);
+
+    UErrorCode status_;
+    char language_[9];
+    char script_[5];
+    char region_[4];
+    CharString *variant_;  // Pointer not object so we need not #include internal charstr.h.
+    icu::Locale *extensions_;  // Pointer not object. Storage for all other fields.
+
+};
+
+U_NAMESPACE_END
+
+#endif /* U_SHOW_CPLUSPLUS_API */
+
+#endif  // __LOCALEBUILDER_H__
diff --git a/src/third_party/icu/source/common/unicode/localematcher.h b/src/third_party/icu/source/common/unicode/localematcher.h
new file mode 100644
index 0000000..63a68b0
--- /dev/null
+++ b/src/third_party/icu/source/common/unicode/localematcher.h
@@ -0,0 +1,720 @@
+// © 2019 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+// localematcher.h
+// created: 2019may08 Markus W. Scherer
+
+#ifndef __LOCALEMATCHER_H__
+#define __LOCALEMATCHER_H__
+
+#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
+#include "unicode/locid.h"
+#include "unicode/stringpiece.h"
+#include "unicode/uobject.h"
+
+/**
+ * \file
+ * \brief C++ API: Locale matcher: User's desired locales vs. application's supported locales.
+ */
+
+/**
+ * Builder option for whether the language subtag or the script subtag is most important.
+ *
+ * @see LocaleMatcher::Builder#setFavorSubtag(ULocMatchFavorSubtag)
+ * @stable ICU 65
+ */
+enum ULocMatchFavorSubtag {
+    /**
+     * Language differences are most important, then script differences, then region differences.
+     * (This is the default behavior.)
+     *
+     * @stable ICU 65
+     */
+    ULOCMATCH_FAVOR_LANGUAGE,
+    /**
+     * Makes script differences matter relatively more than language differences.
+     *
+     * @stable ICU 65
+     */
+    ULOCMATCH_FAVOR_SCRIPT
+};
+#ifndef U_IN_DOXYGEN
+typedef enum ULocMatchFavorSubtag ULocMatchFavorSubtag;
+#endif
+
+/**
+ * Builder option for whether all desired locales are treated equally or
+ * earlier ones are preferred.
+ *
+ * @see LocaleMatcher::Builder#setDemotionPerDesiredLocale(ULocMatchDemotion)
+ * @stable ICU 65
+ */
+enum ULocMatchDemotion {
+    /**
+     * All desired locales are treated equally.
+     *
+     * @stable ICU 65
+     */
+    ULOCMATCH_DEMOTION_NONE,
+    /**
+     * Earlier desired locales are preferred.
+     *
+     * <p>From each desired locale to the next,
+     * the distance to any supported locale is increased by an additional amount
+     * which is at least as large as most region mismatches.
+     * A later desired locale has to have a better match with some supported locale
+     * due to more than merely having the same region subtag.
+     *
+     * <p>For example: <code>Supported={en, sv}  desired=[en-GB, sv]</code>
+     * yields <code>Result(en-GB, en)</code> because
+     * with the demotion of sv its perfect match is no better than
+     * the region distance between the earlier desired locale en-GB and en=en-US.
+     *
+     * <p>Notes:
+     * <ul>
+     *   <li>In some cases, language and/or script differences can be as small as
+     *       the typical region difference. (Example: sr-Latn vs. sr-Cyrl)
+     *   <li>It is possible for certain region differences to be larger than usual,
+     *       and larger than the demotion.
+     *       (As of CLDR 35 there is no such case, but
+     *        this is possible in future versions of the data.)
+     * </ul>
+     *
+     * @stable ICU 65
+     */
+    ULOCMATCH_DEMOTION_REGION
+};
+#ifndef U_IN_DOXYGEN
+typedef enum ULocMatchDemotion ULocMatchDemotion;
+#endif
+
+#ifndef U_FORCE_HIDE_DRAFT_API
+
+/**
+ * Builder option for whether to include or ignore one-way (fallback) match data.
+ * The LocaleMatcher uses CLDR languageMatch data which includes fallback (oneway=true) entries.
+ * Sometimes it is desirable to ignore those.
+ *
+ * <p>For example, consider a web application with the UI in a given language,
+ * with a link to another, related web app.
+ * The link should include the UI language, and the target server may also use
+ * the client’s Accept-Language header data.
+ * The target server has its own list of supported languages.
+ * One may want to favor UI language consistency, that is,
+ * if there is a decent match for the original UI language, we want to use it,
+ * but not if it is merely a fallback.
+ *
+ * @see LocaleMatcher::Builder#setDirection(ULocMatchDirection)
+ * @draft ICU 67
+ */
+enum ULocMatchDirection {
+    /**
+     * Locale matching includes one-way matches such as Breton→French. (default)
+     *
+     * @draft ICU 67
+     */
+    ULOCMATCH_DIRECTION_WITH_ONE_WAY,
+    /**
+     * Locale matching limited to two-way matches including e.g. Danish↔Norwegian
+     * but ignoring one-way matches.
+     *
+     * @draft ICU 67
+     */
+    ULOCMATCH_DIRECTION_ONLY_TWO_WAY
+};
+#ifndef U_IN_DOXYGEN
+typedef enum ULocMatchDirection ULocMatchDirection;
+#endif
+
+#endif  // U_FORCE_HIDE_DRAFT_API
+
+struct UHashtable;
+
+U_NAMESPACE_BEGIN
+
+struct LSR;
+
+class LocaleDistance;
+class LocaleLsrIterator;
+class UVector;
+class XLikelySubtags;
+
+/**
+ * Immutable class that picks the best match between a user's desired locales and
+ * an application's supported locales.
+ * Movable but not copyable.
+ *
+ * <p>Example:
+ * <pre>
+ * UErrorCode errorCode = U_ZERO_ERROR;
+ * LocaleMatcher matcher = LocaleMatcher::Builder().setSupportedLocales("fr, en-GB, en").build(errorCode);
+ * Locale *bestSupported = matcher.getBestLocale(Locale.US, errorCode);  // "en"
+ * </pre>
+ *
+ * <p>A matcher takes into account when languages are close to one another,
+ * such as Danish and Norwegian,
+ * and when regional variants are close, like en-GB and en-AU as opposed to en-US.
+ *
+ * <p>If there are multiple supported locales with the same (language, script, region)
+ * likely subtags, then the current implementation returns the first of those locales.
+ * It ignores variant subtags (except for pseudolocale variants) and extensions.
+ * This may change in future versions.
+ *
+ * <p>For example, the current implementation does not distinguish between
+ * de, de-DE, de-Latn, de-1901, de-u-co-phonebk.
+ *
+ * <p>If you prefer one equivalent locale over another, then provide only the preferred one,
+ * or place it earlier in the list of supported locales.
+ *
+ * <p>Otherwise, the order of supported locales may have no effect on the best-match results.
+ * The current implementation compares each desired locale with supported locales
+ * in the following order:
+ * 1. Default locale, if supported;
+ * 2. CLDR "paradigm locales" like en-GB and es-419;
+ * 3. other supported locales.
+ * This may change in future versions.
+ *
+ * <p>Often a product will just need one matcher instance, built with the languages
+ * that it supports. However, it may want multiple instances with different
+ * default languages based on additional information, such as the domain.
+ *
+ * <p>This class is not intended for public subclassing.
+ *
+ * @stable ICU 65
+ */
+class U_COMMON_API LocaleMatcher : public UMemory {
+public:
+    /**
+     * Data for the best-matching pair of a desired and a supported locale.
+     * Movable but not copyable.
+     *
+     * @stable ICU 65
+     */
+    class U_COMMON_API Result : public UMemory {
+    public:
+        /**
+         * Move constructor; might modify the source.
+         * This object will have the same contents that the source object had.
+         *
+         * @param src Result to move contents from.
+         * @stable ICU 65
+         */
+        Result(Result &&src) U_NOEXCEPT;
+
+        /**
+         * Destructor.
+         *
+         * @stable ICU 65
+         */
+        ~Result();
+
+        /**
+         * Move assignment; might modify the source.
+         * This object will have the same contents that the source object had.
+         *
+         * @param src Result to move contents from.
+         * @stable ICU 65
+         */
+        Result &operator=(Result &&src) U_NOEXCEPT;
+
+        /**
+         * Returns the best-matching desired locale.
+         * nullptr if the list of desired locales is empty or if none matched well enough.
+         *
+         * @return the best-matching desired locale, or nullptr.
+         * @stable ICU 65
+         */
+        inline const Locale *getDesiredLocale() const { return desiredLocale; }
+
+        /**
+         * Returns the best-matching supported locale.
+         * If none matched well enough, this is the default locale.
+         * The default locale is nullptr if Builder::setNoDefaultLocale() was called,
+         * or if the list of supported locales is empty and no explicit default locale is set.
+         *
+         * @return the best-matching supported locale, or nullptr.
+         * @stable ICU 65
+         */
+        inline const Locale *getSupportedLocale() const { return supportedLocale; }
+
+        /**
+         * Returns the index of the best-matching desired locale in the input Iterable order.
+         * -1 if the list of desired locales is empty or if none matched well enough.
+         *
+         * @return the index of the best-matching desired locale, or -1.
+         * @stable ICU 65
+         */
+        inline int32_t getDesiredIndex() const { return desiredIndex; }
+
+        /**
+         * Returns the index of the best-matching supported locale in the
+         * constructor’s or builder’s input order (“set” Collection plus “added” locales).
+         * If the matcher was built from a locale list string, then the iteration order is that
+         * of a LocalePriorityList built from the same string.
+         * -1 if the list of supported locales is empty or if none matched well enough.
+         *
+         * @return the index of the best-matching supported locale, or -1.
+         * @stable ICU 65
+         */
+        inline int32_t getSupportedIndex() const { return supportedIndex; }
+
+        /**
+         * Takes the best-matching supported locale and adds relevant fields of the
+         * best-matching desired locale, such as the -t- and -u- extensions.
+         * May replace some fields of the supported locale.
+         * The result is the locale that should be used for date and number formatting, collation, etc.
+         * Returns the root locale if getSupportedLocale() returns nullptr.
+         *
+         * <p>Example: desired=ar-SA-u-nu-latn, supported=ar-EG, resolved locale=ar-SA-u-nu-latn
+         *
+         * @return a locale combining the best-matching desired and supported locales.
+         * @stable ICU 65
+         */
+        Locale makeResolvedLocale(UErrorCode &errorCode) const;
+
+    private:
+        Result(const Locale *desired, const Locale *supported,
+               int32_t desIndex, int32_t suppIndex, UBool owned) :
+                desiredLocale(desired), supportedLocale(supported),
+                desiredIndex(desIndex), supportedIndex(suppIndex),
+                desiredIsOwned(owned) {}
+
+        Result(const Result &other) = delete;
+        Result &operator=(const Result &other) = delete;
+
+        const Locale *desiredLocale;
+        const Locale *supportedLocale;
+        int32_t desiredIndex;
+        int32_t supportedIndex;
+        UBool desiredIsOwned;
+
+        friend class LocaleMatcher;
+    };
+
+    /**
+     * LocaleMatcher builder.
+     * Movable but not copyable.
+     *
+     * @stable ICU 65
+     */
+    class U_COMMON_API Builder : public UMemory {
+    public:
+        /**
+         * Constructs a builder used in chaining parameters for building a LocaleMatcher.
+         *
+         * @return a new Builder object
+         * @stable ICU 65
+         */
+        Builder() {}
+
+        /**
+         * Move constructor; might modify the source.
+         * This builder will have the same contents that the source builder had.
+         *
+         * @param src Builder to move contents from.
+         * @stable ICU 65
+         */
+        Builder(Builder &&src) U_NOEXCEPT;
+
+        /**
+         * Destructor.
+         *
+         * @stable ICU 65
+         */
+        ~Builder();
+
+        /**
+         * Move assignment; might modify the source.
+         * This builder will have the same contents that the source builder had.
+         *
+         * @param src Builder to move contents from.
+         * @stable ICU 65
+         */
+        Builder &operator=(Builder &&src) U_NOEXCEPT;
+
+        /**
+         * Parses an Accept-Language string
+         * (<a href="https://tools.ietf.org/html/rfc2616#section-14.4">RFC 2616 Section 14.4</a>),
+         * such as "af, en, fr;q=0.9", and sets the supported locales accordingly.
+         * Allows whitespace in more places but does not allow "*".
+         * Clears any previously set/added supported locales first.
+         *
+         * @param locales the Accept-Language string of locales to set
+         * @return this Builder object
+         * @stable ICU 65
+         */
+        Builder &setSupportedLocalesFromListString(StringPiece locales);
+
+        /**
+         * Copies the supported locales, preserving iteration order.
+         * Clears any previously set/added supported locales first.
+         * Duplicates are allowed, and are not removed.
+         *
+         * @param locales the list of locale
+         * @return this Builder object
+         * @stable ICU 65
+         */
+        Builder &setSupportedLocales(Locale::Iterator &locales);
+
+        /**
+         * Copies the supported locales from the begin/end range, preserving iteration order.
+         * Clears any previously set/added supported locales first.
+         * Duplicates are allowed, and are not removed.
+         *
+         * Each of the iterator parameter values must be an
+         * input iterator whose value is convertible to const Locale &.
+         *
+         * @param begin Start of range.
+         * @param end Exclusive end of range.
+         * @return this Builder object
+         * @stable ICU 65
+         */
+        template<typename Iter>
+        Builder &setSupportedLocales(Iter begin, Iter end) {
+            if (U_FAILURE(errorCode_)) { return *this; }
+            clearSupportedLocales();
+            while (begin != end) {
+                addSupportedLocale(*begin++);
+            }
+            return *this;
+        }
+
+        /**
+         * Copies the supported locales from the begin/end range, preserving iteration order.
+         * Calls the converter to convert each *begin to a Locale or const Locale &.
+         * Clears any previously set/added supported locales first.
+         * Duplicates are allowed, and are not removed.
+         *
+         * Each of the iterator parameter values must be an
+         * input iterator whose value is convertible to const Locale &.
+         *
+         * @param begin Start of range.
+         * @param end Exclusive end of range.
+         * @param converter Converter from *begin to const Locale & or compatible.
+         * @return this Builder object
+         * @stable ICU 65
+         */
+        template<typename Iter, typename Conv>
+        Builder &setSupportedLocalesViaConverter(Iter begin, Iter end, Conv converter) {
+            if (U_FAILURE(errorCode_)) { return *this; }
+            clearSupportedLocales();
+            while (begin != end) {
+                addSupportedLocale(converter(*begin++));
+            }
+            return *this;
+        }
+
+        /**
+         * Adds another supported locale.
+         * Duplicates are allowed, and are not removed.
+         *
+         * @param locale another locale
+         * @return this Builder object
+         * @stable ICU 65
+         */
+        Builder &addSupportedLocale(const Locale &locale);
+
+#ifndef U_HIDE_DRAFT_API
+        /**
+         * Sets no default locale.
+         * There will be no explicit or implicit default locale.
+         * If there is no good match, then the matcher will return nullptr for the
+         * best supported locale.
+         *
+         * @draft ICU 68
+         */
+        Builder &setNoDefaultLocale();
+#endif  // U_HIDE_DRAFT_API
+
+        /**
+         * Sets the default locale; if nullptr, or if it is not set explicitly,
+         * then the first supported locale is used as the default locale.
+         * There is no default locale at all (nullptr will be returned instead)
+         * if setNoDefaultLocale() is called.
+         *
+         * @param defaultLocale the default locale (will be copied)
+         * @return this Builder object
+         * @stable ICU 65
+         */
+        Builder &setDefaultLocale(const Locale *defaultLocale);
+
+        /**
+         * If ULOCMATCH_FAVOR_SCRIPT, then the language differences are smaller than script
+         * differences.
+         * This is used in situations (such as maps) where
+         * it is better to fall back to the same script than a similar language.
+         *
+         * @param subtag the subtag to favor
+         * @return this Builder object
+         * @stable ICU 65
+         */
+        Builder &setFavorSubtag(ULocMatchFavorSubtag subtag);
+
+        /**
+         * Option for whether all desired locales are treated equally or
+         * earlier ones are preferred (this is the default).
+         *
+         * @param demotion the demotion per desired locale to set.
+         * @return this Builder object
+         * @stable ICU 65
+         */
+        Builder &setDemotionPerDesiredLocale(ULocMatchDemotion demotion);
+
+#ifndef U_HIDE_DRAFT_API
+        /**
+         * Option for whether to include or ignore one-way (fallback) match data.
+         * By default, they are included.
+         *
+         * @param direction the match direction to set.
+         * @return this Builder object
+         * @draft ICU 67
+         */
+        Builder &setDirection(ULocMatchDirection direction) {
+            if (U_SUCCESS(errorCode_)) {
+                direction_ = direction;
+            }
+            return *this;
+        }
+#endif  // U_HIDE_DRAFT_API
+
+#ifndef U_HIDE_DRAFT_API
+        /**
+         * Sets the maximum distance for an acceptable match.
+         * The matcher will return a match for a pair of locales only if
+         * they match at least as well as the pair given here.
+         *
+         * For example, setMaxDistance(en-US, en-GB) limits matches to ones where the
+         * (desired, support) locales have a distance no greater than a region subtag difference.
+         * This is much stricter than the CLDR default.
+         *
+         * The details of locale matching are subject to changes in
+         * CLDR data and in the algorithm.
+         * Specifying a maximum distance in relative terms via a sample pair of locales
+         * insulates from changes that affect all distance metrics similarly,
+         * but some changes will necessarily affect relative distances between
+         * different pairs of locales.
+         *
+         * @param desired the desired locale for distance comparison.
+         * @param supported the supported locale for distance comparison.
+         * @return this Builder object
+         * @draft ICU 68
+         */
+        Builder &setMaxDistance(const Locale &desired, const Locale &supported);
+#endif  // U_HIDE_DRAFT_API
+
+        /**
+         * Sets the UErrorCode if an error occurred while setting parameters.
+         * Preserves older error codes in the outErrorCode.
+         *
+         * @param outErrorCode Set to an error code if it does not contain one already
+         *                  and an error occurred while setting parameters.
+         *                  Otherwise unchanged.
+         * @return true if U_FAILURE(outErrorCode)
+         * @stable ICU 65
+         */
+        UBool copyErrorTo(UErrorCode &outErrorCode) const;
+
+        /**
+         * Builds and returns a new locale matcher.
+         * This builder can continue to be used.
+         *
+         * @param errorCode ICU error code. Its input value must pass the U_SUCCESS() test,
+         *                  or else the function returns immediately. Check for U_FAILURE()
+         *                  on output or use with function chaining. (See User Guide for details.)
+         * @return LocaleMatcher
+         * @stable ICU 65
+         */
+        LocaleMatcher build(UErrorCode &errorCode) const;
+
+    private:
+        friend class LocaleMatcher;
+
+        Builder(const Builder &other) = delete;
+        Builder &operator=(const Builder &other) = delete;
+
+        void clearSupportedLocales();
+        bool ensureSupportedLocaleVector();
+
+        UErrorCode errorCode_ = U_ZERO_ERROR;
+        UVector *supportedLocales_ = nullptr;
+        int32_t thresholdDistance_ = -1;
+        ULocMatchDemotion demotion_ = ULOCMATCH_DEMOTION_REGION;
+        Locale *defaultLocale_ = nullptr;
+        bool withDefault_ = true;
+        ULocMatchFavorSubtag favor_ = ULOCMATCH_FAVOR_LANGUAGE;
+        ULocMatchDirection direction_ = ULOCMATCH_DIRECTION_WITH_ONE_WAY;
+        Locale *maxDistanceDesired_ = nullptr;
+        Locale *maxDistanceSupported_ = nullptr;
+    };
+
+    // FYI No public LocaleMatcher constructors in C++; use the Builder.
+
+    /**
+     * Move copy constructor; might modify the source.
+     * This matcher will have the same settings that the source matcher had.
+     * @param src source matcher
+     * @stable ICU 65
+     */
+    LocaleMatcher(LocaleMatcher &&src) U_NOEXCEPT;
+
+    /**
+     * Destructor.
+     * @stable ICU 65
+     */
+    ~LocaleMatcher();
+
+    /**
+     * Move assignment operator; might modify the source.
+     * This matcher will have the same settings that the source matcher had.
+     * The behavior is undefined if *this and src are the same object.
+     * @param src source matcher
+     * @return *this
+     * @stable ICU 65
+     */
+    LocaleMatcher &operator=(LocaleMatcher &&src) U_NOEXCEPT;
+
+    /**
+     * Returns the supported locale which best matches the desired locale.
+     *
+     * @param desiredLocale Typically a user's language.
+     * @param errorCode ICU error code. Its input value must pass the U_SUCCESS() test,
+     *                  or else the function returns immediately. Check for U_FAILURE()
+     *                  on output or use with function chaining. (See User Guide for details.)
+     * @return the best-matching supported locale.
+     * @stable ICU 65
+     */
+    const Locale *getBestMatch(const Locale &desiredLocale, UErrorCode &errorCode) const;
+
+    /**
+     * Returns the supported locale which best matches one of the desired locales.
+     *
+     * @param desiredLocales Typically a user's languages, in order of preference (descending).
+     * @param errorCode ICU error code. Its input value must pass the U_SUCCESS() test,
+     *                  or else the function returns immediately. Check for U_FAILURE()
+     *                  on output or use with function chaining. (See User Guide for details.)
+     * @return the best-matching supported locale.
+     * @stable ICU 65
+     */
+    const Locale *getBestMatch(Locale::Iterator &desiredLocales, UErrorCode &errorCode) const;
+
+    /**
+     * Parses an Accept-Language string
+     * (<a href="https://tools.ietf.org/html/rfc2616#section-14.4">RFC 2616 Section 14.4</a>),
+     * such as "af, en, fr;q=0.9",
+     * and returns the supported locale which best matches one of the desired locales.
+     * Allows whitespace in more places but does not allow "*".
+     *
+     * @param desiredLocaleList Typically a user's languages, as an Accept-Language string.
+     * @param errorCode ICU error code. Its input value must pass the U_SUCCESS() test,
+     *                  or else the function returns immediately. Check for U_FAILURE()
+     *                  on output or use with function chaining. (See User Guide for details.)
+     * @return the best-matching supported locale.
+     * @stable ICU 65
+     */
+    const Locale *getBestMatchForListString(StringPiece desiredLocaleList, UErrorCode &errorCode) const;
+
+    /**
+     * Returns the best match between the desired locale and the supported locales.
+     * If the result's desired locale is not nullptr, then it is the address of the input locale.
+     * It has not been cloned.
+     *
+     * @param desiredLocale Typically a user's language.
+     * @param errorCode ICU error code. Its input value must pass the U_SUCCESS() test,
+     *                  or else the function returns immediately. Check for U_FAILURE()
+     *                  on output or use with function chaining. (See User Guide for details.)
+     * @return the best-matching pair of the desired and a supported locale.
+     * @stable ICU 65
+     */
+    Result getBestMatchResult(const Locale &desiredLocale, UErrorCode &errorCode) const;
+
+    /**
+     * Returns the best match between the desired and supported locales.
+     * If the result's desired locale is not nullptr, then it is a clone of
+     * the best-matching desired locale. The Result object owns the clone.
+     *
+     * @param desiredLocales Typically a user's languages, in order of preference (descending).
+     * @param errorCode ICU error code. Its input value must pass the U_SUCCESS() test,
+     *                  or else the function returns immediately. Check for U_FAILURE()
+     *                  on output or use with function chaining. (See User Guide for details.)
+     * @return the best-matching pair of a desired and a supported locale.
+     * @stable ICU 65
+     */
+    Result getBestMatchResult(Locale::Iterator &desiredLocales, UErrorCode &errorCode) const;
+
+#ifndef U_HIDE_DRAFT_API
+    /**
+     * Returns true if the pair of locales matches acceptably.
+     * This is influenced by Builder options such as setDirection(), setFavorSubtag(),
+     * and setMaxDistance().
+     *
+     * @param desired The desired locale.
+     * @param supported The supported locale.
+     * @param errorCode ICU error code. Its input value must pass the U_SUCCESS() test,
+     *                  or else the function returns immediately. Check for U_FAILURE()
+     *                  on output or use with function chaining. (See User Guide for details.)
+     * @return true if the pair of locales matches acceptably.
+     * @draft ICU 68
+     */
+    UBool isMatch(const Locale &desired, const Locale &supported, UErrorCode &errorCode) const;
+#endif  // U_HIDE_DRAFT_API
+
+#ifndef U_HIDE_INTERNAL_API
+    /**
+     * Returns a fraction between 0 and 1, where 1 means that the languages are a
+     * perfect match, and 0 means that they are completely different.
+     *
+     * <p>This is mostly an implementation detail, and the precise values may change over time.
+     * The implementation may use either the maximized forms or the others ones, or both.
+     * The implementation may or may not rely on the forms to be consistent with each other.
+     *
+     * <p>Callers should construct and use a matcher rather than match pairs of locales directly.
+     *
+     * @param desired Desired locale.
+     * @param supported Supported locale.
+     * @param errorCode ICU error code. Its input value must pass the U_SUCCESS() test,
+     *                  or else the function returns immediately. Check for U_FAILURE()
+     *                  on output or use with function chaining. (See User Guide for details.)
+     * @return value between 0 and 1, inclusive.
+     * @internal (has a known user)
+     */
+    double internalMatch(const Locale &desired, const Locale &supported, UErrorCode &errorCode) const;
+#endif  // U_HIDE_INTERNAL_API
+
+private:
+    LocaleMatcher(const Builder &builder, UErrorCode &errorCode);
+    LocaleMatcher(const LocaleMatcher &other) = delete;
+    LocaleMatcher &operator=(const LocaleMatcher &other) = delete;
+
+    int32_t putIfAbsent(const LSR &lsr, int32_t i, int32_t suppLength, UErrorCode &errorCode);
+
+    int32_t getBestSuppIndex(LSR desiredLSR, LocaleLsrIterator *remainingIter, UErrorCode &errorCode) const;
+
+    const XLikelySubtags &likelySubtags;
+    const LocaleDistance &localeDistance;
+    int32_t thresholdDistance;
+    int32_t demotionPerDesiredLocale;
+    ULocMatchFavorSubtag favorSubtag;
+    ULocMatchDirection direction;
+
+    // These are in input order.
+    const Locale ** supportedLocales;
+    LSR *lsrs;
+    int32_t supportedLocalesLength;
+    // These are in preference order: 1. Default locale 2. paradigm locales 3. others.
+    UHashtable *supportedLsrToIndex;  // Map<LSR, Integer> stores index+1 because 0 is "not found"
+    // Array versions of the supportedLsrToIndex keys and values.
+    // The distance lookup loops over the supportedLSRs and returns the index of the best match.
+    const LSR **supportedLSRs;
+    int32_t *supportedIndexes;
+    int32_t supportedLSRsLength;
+    Locale *ownedDefaultLocale;
+    const Locale *defaultLocale;
+};
+
+U_NAMESPACE_END
+
+#endif  // U_SHOW_CPLUSPLUS_API
+#endif  // __LOCALEMATCHER_H__
diff --git a/src/third_party/icu/source/common/unicode/localpointer.h b/src/third_party/icu/source/common/unicode/localpointer.h
index 210125c..2a65f2d 100644
--- a/src/third_party/icu/source/common/unicode/localpointer.h
+++ b/src/third_party/icu/source/common/unicode/localpointer.h
@@ -1,12 +1,14 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
-*   Copyright (C) 2009-2015, International Business Machines
+*   Copyright (C) 2009-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *
 *******************************************************************************
 *   file name:  localpointer.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -18,7 +20,7 @@
 #define __LOCALPOINTER_H__
 
 /**
- * \file 
+ * \file
  * \brief C++ API: "Smart pointers" for use with and in ICU4C C++ code.
  *
  * These classes are inspired by
@@ -40,16 +42,9 @@
 
 #if U_SHOW_CPLUSPLUS_API
 
-U_NAMESPACE_BEGIN
+#include <memory>
 
-// The operator new is declared but not defined to prevent custom functions that
-// heap allocate the object.
-#if defined(__ghs__)
-// Linker requires an implementation.
-#define IGNORE_DECLARATION { ASSERT(0); return NULL; }
-#else
-#define IGNORE_DECLARATION
-#endif
+U_NAMESPACE_BEGIN
 
 /**
  * "Smart pointer" base class; do not use directly: use LocalPointer etc.
@@ -61,7 +56,7 @@
  * Destructor and adoptInstead().
  *
  * There is no operator T *() provided because the programmer must decide
- * whether to use getAlias() (without transfer of ownership) or orpan()
+ * whether to use getAlias() (without transfer of ownership) or orphan()
  * (with transfer of ownership and NULLing of the pointer).
  *
  * @see LocalPointer
@@ -72,6 +67,13 @@
 template<typename T>
 class LocalPointerBase {
 public:
+    // No heap allocation. Use only on the stack.
+    static void* U_EXPORT2 operator new(size_t) = delete;
+    static void* U_EXPORT2 operator new[](size_t) = delete;
+#if U_HAVE_PLACEMENT_NEW
+    static void* U_EXPORT2 operator new(size_t, void*) = delete;
+#endif
+
     /**
      * Constructor takes ownership.
      * @param p simple pointer to an object that is adopted
@@ -86,13 +88,13 @@
     ~LocalPointerBase() { /* delete ptr; */ }
     /**
      * NULL check.
-     * @return TRUE if ==NULL
+     * @return true if ==NULL
      * @stable ICU 4.4
      */
     UBool isNull() const { return ptr==NULL; }
     /**
      * NULL check.
-     * @return TRUE if !=NULL
+     * @return true if !=NULL
      * @stable ICU 4.4
      */
     UBool isValid() const { return ptr!=NULL; }
@@ -165,12 +167,6 @@
     // No ownership sharing: No copy constructor, no assignment operator.
     LocalPointerBase(const LocalPointerBase<T> &other);
     void operator=(const LocalPointerBase<T> &other);
-    // No heap allocation. Use only on the stack.
-    static void * U_EXPORT2 operator new(size_t size) IGNORE_DECLARATION;
-    static void * U_EXPORT2 operator new[](size_t size) IGNORE_DECLARATION;
-#if U_HAVE_PLACEMENT_NEW
-    static void * U_EXPORT2 operator new(size_t, void *ptr);
-#endif
 };
 
 /**
@@ -181,9 +177,9 @@
  * \code
  * LocalPointer<UnicodeString> s(new UnicodeString((UChar32)0x50005));
  * int32_t length=s->length();  // 2
- * UChar lead=s->charAt(0);  // 0xd900
+ * char16_t lead=s->charAt(0);  // 0xd900
  * if(some condition) { return; }  // no need to explicitly delete the pointer
- * s.adoptInstead(new UnicodeString((UChar)0xfffc));
+ * s.adoptInstead(new UnicodeString((char16_t)0xfffc));
  * length=s->length();  // 1
  * // no need to explicitly delete the pointer
  * \endcode
@@ -194,13 +190,14 @@
 template<typename T>
 class LocalPointer : public LocalPointerBase<T> {
 public:
+    using LocalPointerBase<T>::operator*;
+    using LocalPointerBase<T>::operator->;
     /**
      * Constructor takes ownership.
      * @param p simple pointer to an object that is adopted
      * @stable ICU 4.4
      */
     explicit LocalPointer(T *p=NULL) : LocalPointerBase<T>(p) {}
-#ifndef U_HIDE_DRAFT_API
     /**
      * Constructor takes ownership and reports an error if NULL.
      *
@@ -212,24 +209,35 @@
      * @param p simple pointer to an object that is adopted
      * @param errorCode in/out UErrorCode, set to U_MEMORY_ALLOCATION_ERROR
      *     if p==NULL and no other failure code had been set
-     * @draft ICU 55
+     * @stable ICU 55
      */
     LocalPointer(T *p, UErrorCode &errorCode) : LocalPointerBase<T>(p) {
         if(p==NULL && U_SUCCESS(errorCode)) {
             errorCode=U_MEMORY_ALLOCATION_ERROR;
         }
     }
-#if U_HAVE_RVALUE_REFERENCES
     /**
      * Move constructor, leaves src with isNull().
      * @param src source smart pointer
-     * @draft ICU 56
+     * @stable ICU 56
      */
     LocalPointer(LocalPointer<T> &&src) U_NOEXCEPT : LocalPointerBase<T>(src.ptr) {
         src.ptr=NULL;
     }
-#endif
-#endif  /* U_HIDE_DRAFT_API */
+
+    /**
+     * Constructs a LocalPointer from a C++11 std::unique_ptr.
+     * The LocalPointer steals the object owned by the std::unique_ptr.
+     *
+     * This constructor works via move semantics. If your std::unique_ptr is
+     * in a local variable, you must use std::move.
+     *
+     * @param p The std::unique_ptr from which the pointer will be stolen.
+     * @stable ICU 64
+     */
+    explicit LocalPointer(std::unique_ptr<T> &&p)
+        : LocalPointerBase<T>(p.release()) {}
+
     /**
      * Destructor deletes the object it owns.
      * @stable ICU 4.4
@@ -237,38 +245,37 @@
     ~LocalPointer() {
         delete LocalPointerBase<T>::ptr;
     }
-#ifndef U_HIDE_DRAFT_API
-#if U_HAVE_RVALUE_REFERENCES
     /**
      * Move assignment operator, leaves src with isNull().
      * The behavior is undefined if *this and src are the same object.
      * @param src source smart pointer
      * @return *this
-     * @draft ICU 56
+     * @stable ICU 56
      */
     LocalPointer<T> &operator=(LocalPointer<T> &&src) U_NOEXCEPT {
-        return moveFrom(src);
-    }
-#endif
-    /**
-     * Move assignment, leaves src with isNull().
-     * The behavior is undefined if *this and src are the same object.
-     *
-     * Can be called explicitly, does not need C++11 support.
-     * @param src source smart pointer
-     * @return *this
-     * @draft ICU 56
-     */
-    LocalPointer<T> &moveFrom(LocalPointer<T> &src) U_NOEXCEPT {
         delete LocalPointerBase<T>::ptr;
         LocalPointerBase<T>::ptr=src.ptr;
         src.ptr=NULL;
         return *this;
     }
+
+    /**
+     * Move-assign from an std::unique_ptr to this LocalPointer.
+     * Steals the pointer from the std::unique_ptr.
+     *
+     * @param p The std::unique_ptr from which the pointer will be stolen.
+     * @return *this
+     * @stable ICU 64
+     */
+    LocalPointer<T> &operator=(std::unique_ptr<T> &&p) U_NOEXCEPT {
+        adoptInstead(p.release());
+        return *this;
+    }
+
     /**
      * Swap pointers.
      * @param other other smart pointer
-     * @draft ICU 56
+     * @stable ICU 56
      */
     void swap(LocalPointer<T> &other) U_NOEXCEPT {
         T *temp=LocalPointerBase<T>::ptr;
@@ -279,12 +286,11 @@
      * Non-member LocalPointer swap function.
      * @param p1 will get p2's pointer
      * @param p2 will get p1's pointer
-     * @draft ICU 56
+     * @stable ICU 56
      */
     friend inline void swap(LocalPointer<T> &p1, LocalPointer<T> &p2) U_NOEXCEPT {
         p1.swap(p2);
     }
-#endif  /* U_HIDE_DRAFT_API */
     /**
      * Deletes the object it owns,
      * and adopts (takes ownership of) the one passed in.
@@ -295,7 +301,6 @@
         delete LocalPointerBase<T>::ptr;
         LocalPointerBase<T>::ptr=p;
     }
-#ifndef U_HIDE_DRAFT_API
     /**
      * Deletes the object it owns,
      * and adopts (takes ownership of) the one passed in.
@@ -309,7 +314,7 @@
      * @param p simple pointer to an object that is adopted
      * @param errorCode in/out UErrorCode, set to U_MEMORY_ALLOCATION_ERROR
      *     if p==NULL and no other failure code had been set
-     * @draft ICU 55
+     * @stable ICU 55
      */
     void adoptInsteadAndCheckErrorCode(T *p, UErrorCode &errorCode) {
         if(U_SUCCESS(errorCode)) {
@@ -322,7 +327,21 @@
             delete p;
         }
     }
-#endif  /* U_HIDE_DRAFT_API */
+
+    /**
+     * Conversion operator to a C++11 std::unique_ptr.
+     * Disowns the object and gives it to the returned std::unique_ptr.
+     *
+     * This operator works via move semantics. If your LocalPointer is
+     * in a local variable, you must use std::move.
+     *
+     * @return An std::unique_ptr owning the pointer previously owned by this
+     *         icu::LocalPointer.
+     * @stable ICU 64
+     */
+    operator std::unique_ptr<T> () && {
+        return std::unique_ptr<T>(LocalPointerBase<T>::orphan());
+    }
 };
 
 /**
@@ -333,10 +352,10 @@
  * Usage example:
  * \code
  * LocalArray<UnicodeString> a(new UnicodeString[2]);
- * a[0].append((UChar)0x61);
+ * a[0].append((char16_t)0x61);
  * if(some condition) { return; }  // no need to explicitly delete the array
  * a.adoptInstead(new UnicodeString[4]);
- * a[3].append((UChar)0x62).append((UChar)0x63).reverse();
+ * a[3].append((char16_t)0x62).append((char16_t)0x63).reverse();
  * // no need to explicitly delete the array
  * \endcode
  *
@@ -346,13 +365,14 @@
 template<typename T>
 class LocalArray : public LocalPointerBase<T> {
 public:
+    using LocalPointerBase<T>::operator*;
+    using LocalPointerBase<T>::operator->;
     /**
      * Constructor takes ownership.
      * @param p simple pointer to an array of T objects that is adopted
      * @stable ICU 4.4
      */
     explicit LocalArray(T *p=NULL) : LocalPointerBase<T>(p) {}
-#ifndef U_HIDE_DRAFT_API
     /**
      * Constructor takes ownership and reports an error if NULL.
      *
@@ -364,24 +384,35 @@
      * @param p simple pointer to an array of T objects that is adopted
      * @param errorCode in/out UErrorCode, set to U_MEMORY_ALLOCATION_ERROR
      *     if p==NULL and no other failure code had been set
-     * @draft ICU 56
+     * @stable ICU 56
      */
     LocalArray(T *p, UErrorCode &errorCode) : LocalPointerBase<T>(p) {
         if(p==NULL && U_SUCCESS(errorCode)) {
             errorCode=U_MEMORY_ALLOCATION_ERROR;
         }
     }
-#if U_HAVE_RVALUE_REFERENCES
     /**
      * Move constructor, leaves src with isNull().
      * @param src source smart pointer
-     * @draft ICU 56
+     * @stable ICU 56
      */
     LocalArray(LocalArray<T> &&src) U_NOEXCEPT : LocalPointerBase<T>(src.ptr) {
         src.ptr=NULL;
     }
-#endif
-#endif  /* U_HIDE_DRAFT_API */
+
+    /**
+     * Constructs a LocalArray from a C++11 std::unique_ptr of an array type.
+     * The LocalPointer steals the array owned by the std::unique_ptr.
+     *
+     * This constructor works via move semantics. If your std::unique_ptr is
+     * in a local variable, you must use std::move.
+     *
+     * @param p The std::unique_ptr from which the array will be stolen.
+     * @stable ICU 64
+     */
+    explicit LocalArray(std::unique_ptr<T[]> &&p)
+        : LocalPointerBase<T>(p.release()) {}
+
     /**
      * Destructor deletes the array it owns.
      * @stable ICU 4.4
@@ -389,38 +420,37 @@
     ~LocalArray() {
         delete[] LocalPointerBase<T>::ptr;
     }
-#ifndef U_HIDE_DRAFT_API
-#if U_HAVE_RVALUE_REFERENCES
     /**
      * Move assignment operator, leaves src with isNull().
      * The behavior is undefined if *this and src are the same object.
      * @param src source smart pointer
      * @return *this
-     * @draft ICU 56
+     * @stable ICU 56
      */
     LocalArray<T> &operator=(LocalArray<T> &&src) U_NOEXCEPT {
-        return moveFrom(src);
-    }
-#endif
-    /**
-     * Move assignment, leaves src with isNull().
-     * The behavior is undefined if *this and src are the same object.
-     *
-     * Can be called explicitly, does not need C++11 support.
-     * @param src source smart pointer
-     * @return *this
-     * @draft ICU 56
-     */
-    LocalArray<T> &moveFrom(LocalArray<T> &src) U_NOEXCEPT {
         delete[] LocalPointerBase<T>::ptr;
         LocalPointerBase<T>::ptr=src.ptr;
         src.ptr=NULL;
         return *this;
     }
+
+    /**
+     * Move-assign from an std::unique_ptr to this LocalPointer.
+     * Steals the array from the std::unique_ptr.
+     *
+     * @param p The std::unique_ptr from which the array will be stolen.
+     * @return *this
+     * @stable ICU 64
+     */
+    LocalArray<T> &operator=(std::unique_ptr<T[]> &&p) U_NOEXCEPT {
+        adoptInstead(p.release());
+        return *this;
+    }
+
     /**
      * Swap pointers.
      * @param other other smart pointer
-     * @draft ICU 56
+     * @stable ICU 56
      */
     void swap(LocalArray<T> &other) U_NOEXCEPT {
         T *temp=LocalPointerBase<T>::ptr;
@@ -431,12 +461,11 @@
      * Non-member LocalArray swap function.
      * @param p1 will get p2's pointer
      * @param p2 will get p1's pointer
-     * @draft ICU 56
+     * @stable ICU 56
      */
     friend inline void swap(LocalArray<T> &p1, LocalArray<T> &p2) U_NOEXCEPT {
         p1.swap(p2);
     }
-#endif  /* U_HIDE_DRAFT_API */
     /**
      * Deletes the array it owns,
      * and adopts (takes ownership of) the one passed in.
@@ -447,7 +476,6 @@
         delete[] LocalPointerBase<T>::ptr;
         LocalPointerBase<T>::ptr=p;
     }
-#ifndef U_HIDE_DRAFT_API
     /**
      * Deletes the array it owns,
      * and adopts (takes ownership of) the one passed in.
@@ -461,7 +489,7 @@
      * @param p simple pointer to an array of T objects that is adopted
      * @param errorCode in/out UErrorCode, set to U_MEMORY_ALLOCATION_ERROR
      *     if p==NULL and no other failure code had been set
-     * @draft ICU 56
+     * @stable ICU 56
      */
     void adoptInsteadAndCheckErrorCode(T *p, UErrorCode &errorCode) {
         if(U_SUCCESS(errorCode)) {
@@ -474,7 +502,6 @@
             delete[] p;
         }
     }
-#endif  /* U_HIDE_DRAFT_API */
     /**
      * Array item access (writable).
      * No index bounds check.
@@ -483,6 +510,21 @@
      * @stable ICU 4.4
      */
     T &operator[](ptrdiff_t i) const { return LocalPointerBase<T>::ptr[i]; }
+
+    /**
+     * Conversion operator to a C++11 std::unique_ptr.
+     * Disowns the object and gives it to the returned std::unique_ptr.
+     *
+     * This operator works via move semantics. If your LocalPointer is
+     * in a local variable, you must use std::move.
+     *
+     * @return An std::unique_ptr owning the pointer previously owned by this
+     *         icu::LocalPointer.
+     * @stable ICU 64
+     */
+    operator std::unique_ptr<T[]> () && {
+        return std::unique_ptr<T[]>(LocalPointerBase<T>::orphan());
+    }
 };
 
 /**
@@ -492,9 +534,6 @@
  * like LocalPointer<Type> except that this subclass will use the closeFunction
  * rather than the C++ delete operator.
  *
- * Requirement: The closeFunction must tolerate a NULL pointer.
- * (We could add a NULL check here but it is normally redundant.)
- *
  * Usage example:
  * \code
  * LocalUCaseMapPointer csm(ucasemap_open(localeID, options, &errorCode));
@@ -508,25 +547,31 @@
  * @see LocalPointer
  * @stable ICU 4.4
  */
-#if U_HAVE_RVALUE_REFERENCES
 #define U_DEFINE_LOCAL_OPEN_POINTER(LocalPointerClassName, Type, closeFunction) \
     class LocalPointerClassName : public LocalPointerBase<Type> { \
     public: \
+        using LocalPointerBase<Type>::operator*; \
+        using LocalPointerBase<Type>::operator->; \
         explicit LocalPointerClassName(Type *p=NULL) : LocalPointerBase<Type>(p) {} \
         LocalPointerClassName(LocalPointerClassName &&src) U_NOEXCEPT \
                 : LocalPointerBase<Type>(src.ptr) { \
             src.ptr=NULL; \
         } \
-        ~LocalPointerClassName() { closeFunction(ptr); } \
+        /* TODO: Be agnostic of the deleter function signature from the user-provided std::unique_ptr? */ \
+        explicit LocalPointerClassName(std::unique_ptr<Type, decltype(&closeFunction)> &&p) \
+                : LocalPointerBase<Type>(p.release()) {} \
+        ~LocalPointerClassName() { if (ptr != NULL) { closeFunction(ptr); } } \
         LocalPointerClassName &operator=(LocalPointerClassName &&src) U_NOEXCEPT { \
-            return moveFrom(src); \
-        } \
-        LocalPointerClassName &moveFrom(LocalPointerClassName &src) U_NOEXCEPT { \
-            closeFunction(ptr); \
+            if (ptr != NULL) { closeFunction(ptr); } \
             LocalPointerBase<Type>::ptr=src.ptr; \
             src.ptr=NULL; \
             return *this; \
         } \
+        /* TODO: Be agnostic of the deleter function signature from the user-provided std::unique_ptr? */ \
+        LocalPointerClassName &operator=(std::unique_ptr<Type, decltype(&closeFunction)> &&p) { \
+            adoptInstead(p.release()); \
+            return *this; \
+        } \
         void swap(LocalPointerClassName &other) U_NOEXCEPT { \
             Type *temp=LocalPointerBase<Type>::ptr; \
             LocalPointerBase<Type>::ptr=other.ptr; \
@@ -536,36 +581,13 @@
             p1.swap(p2); \
         } \
         void adoptInstead(Type *p) { \
-            closeFunction(ptr); \
+            if (ptr != NULL) { closeFunction(ptr); } \
             ptr=p; \
         } \
-    }
-#else
-#define U_DEFINE_LOCAL_OPEN_POINTER(LocalPointerClassName, Type, closeFunction) \
-    class LocalPointerClassName : public LocalPointerBase<Type> { \
-    public: \
-        explicit LocalPointerClassName(Type *p=NULL) : LocalPointerBase<Type>(p) {} \
-        ~LocalPointerClassName() { closeFunction(ptr); } \
-        LocalPointerClassName &moveFrom(LocalPointerClassName &src) U_NOEXCEPT { \
-            closeFunction(ptr); \
-            LocalPointerBase<Type>::ptr=src.ptr; \
-            src.ptr=NULL; \
-            return *this; \
-        } \
-        void swap(LocalPointerClassName &other) U_NOEXCEPT { \
-            Type *temp=LocalPointerBase<Type>::ptr; \
-            LocalPointerBase<Type>::ptr=other.ptr; \
-            other.ptr=temp; \
-        } \
-        friend inline void swap(LocalPointerClassName &p1, LocalPointerClassName &p2) U_NOEXCEPT { \
-            p1.swap(p2); \
-        } \
-        void adoptInstead(Type *p) { \
-            closeFunction(ptr); \
-            ptr=p; \
+        operator std::unique_ptr<Type, decltype(&closeFunction)> () && { \
+            return std::unique_ptr<Type, decltype(&closeFunction)>(LocalPointerBase<Type>::orphan(), closeFunction); \
         } \
     }
-#endif
 
 U_NAMESPACE_END
 
diff --git a/src/third_party/icu/source/common/unicode/locdspnm.h b/src/third_party/icu/source/common/unicode/locdspnm.h
new file mode 100644
index 0000000..4f06f85
--- /dev/null
+++ b/src/third_party/icu/source/common/unicode/locdspnm.h
@@ -0,0 +1,211 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+/*
+******************************************************************************
+* Copyright (C) 2010-2016, International Business Machines Corporation and
+* others. All Rights Reserved.
+******************************************************************************
+*/
+
+#ifndef LOCDSPNM_H
+#define LOCDSPNM_H
+
+#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
+/**
+ * \file
+ * \brief C++ API: Provides display names of Locale and its components.
+ */
+
+#if !UCONFIG_NO_FORMATTING
+
+#include "unicode/locid.h"
+#include "unicode/strenum.h"
+#include "unicode/uscript.h"
+#include "unicode/uldnames.h"
+#include "unicode/udisplaycontext.h"
+
+U_NAMESPACE_BEGIN
+
+/**
+ * Returns display names of Locales and components of Locales. For
+ * more information on language, script, region, variant, key, and
+ * values, see Locale.
+ * @stable ICU 4.4
+ */
+class U_COMMON_API LocaleDisplayNames : public UObject {
+public:
+    /**
+     * Destructor.
+     * @stable ICU 4.4
+     */
+    virtual ~LocaleDisplayNames();
+
+    /**
+     * Convenience overload of
+     * {@link #createInstance(const Locale& locale, UDialectHandling dialectHandling)}
+     * that specifies STANDARD dialect handling.
+     * @param locale the display locale
+     * @return a LocaleDisplayNames instance
+     * @stable ICU 4.4
+     */
+    inline static LocaleDisplayNames* U_EXPORT2 createInstance(const Locale& locale);
+
+    /**
+     * Returns an instance of LocaleDisplayNames that returns names
+     * formatted for the provided locale, using the provided
+     * dialectHandling.
+     *
+     * @param locale the display locale
+     * @param dialectHandling how to select names for locales
+     * @return a LocaleDisplayNames instance
+     * @stable ICU 4.4
+     */
+    static LocaleDisplayNames* U_EXPORT2 createInstance(const Locale& locale,
+                            UDialectHandling dialectHandling);
+
+    /**
+     * Returns an instance of LocaleDisplayNames that returns names formatted
+     * for the provided locale, using the provided UDisplayContext settings.
+     *
+     * @param locale the display locale
+     * @param contexts List of one or more context settings (e.g. for dialect
+     *               handling, capitalization, etc.
+     * @param length Number of items in the contexts list
+     * @return a LocaleDisplayNames instance
+     * @stable ICU 51
+     */
+    static LocaleDisplayNames* U_EXPORT2 createInstance(const Locale& locale,
+                            UDisplayContext *contexts, int32_t length);
+
+    // getters for state
+    /**
+     * Returns the locale used to determine the display names. This is
+     * not necessarily the same locale passed to {@link #createInstance}.
+     * @return the display locale
+     * @stable ICU 4.4
+     */
+    virtual const Locale& getLocale() const = 0;
+
+    /**
+     * Returns the dialect handling used in the display names.
+     * @return the dialect handling enum
+     * @stable ICU 4.4
+     */
+    virtual UDialectHandling getDialectHandling() const = 0;
+
+    /**
+     * Returns the UDisplayContext value for the specified UDisplayContextType.
+     * @param type the UDisplayContextType whose value to return
+     * @return the UDisplayContext for the specified type.
+     * @stable ICU 51
+     */
+    virtual UDisplayContext getContext(UDisplayContextType type) const = 0;
+
+    // names for entire locales
+    /**
+     * Returns the display name of the provided locale.
+     * @param locale the locale whose display name to return
+     * @param result receives the locale's display name
+     * @return the display name of the provided locale
+     * @stable ICU 4.4
+     */
+    virtual UnicodeString& localeDisplayName(const Locale& locale,
+                         UnicodeString& result) const = 0;
+
+    /**
+     * Returns the display name of the provided locale id.
+     * @param localeId the id of the locale whose display name to return
+     * @param result receives the locale's display name
+     * @return the display name of the provided locale
+     * @stable ICU 4.4
+     */
+    virtual UnicodeString& localeDisplayName(const char* localeId,
+                         UnicodeString& result) const = 0;
+
+    // names for components of a locale id
+    /**
+     * Returns the display name of the provided language code.
+     * @param lang the language code
+     * @param result receives the language code's display name
+     * @return the display name of the provided language code
+     * @stable ICU 4.4
+     */
+    virtual UnicodeString& languageDisplayName(const char* lang,
+                           UnicodeString& result) const = 0;
+
+    /**
+     * Returns the display name of the provided script code.
+     * @param script the script code
+     * @param result receives the script code's display name
+     * @return the display name of the provided script code
+     * @stable ICU 4.4
+     */
+    virtual UnicodeString& scriptDisplayName(const char* script,
+                         UnicodeString& result) const = 0;
+
+    /**
+     * Returns the display name of the provided script code.
+     * @param scriptCode the script code number
+     * @param result receives the script code's display name
+     * @return the display name of the provided script code
+     * @stable ICU 4.4
+     */
+    virtual UnicodeString& scriptDisplayName(UScriptCode scriptCode,
+                         UnicodeString& result) const = 0;
+
+    /**
+     * Returns the display name of the provided region code.
+     * @param region the region code
+     * @param result receives the region code's display name
+     * @return the display name of the provided region code
+     * @stable ICU 4.4
+     */
+    virtual UnicodeString& regionDisplayName(const char* region,
+                         UnicodeString& result) const = 0;
+
+    /**
+     * Returns the display name of the provided variant.
+     * @param variant the variant string
+     * @param result receives the variant's display name
+     * @return the display name of the provided variant
+     * @stable ICU 4.4
+     */
+    virtual UnicodeString& variantDisplayName(const char* variant,
+                          UnicodeString& result) const = 0;
+
+    /**
+     * Returns the display name of the provided locale key.
+     * @param key the locale key name
+     * @param result receives the locale key's display name
+     * @return the display name of the provided locale key
+     * @stable ICU 4.4
+     */
+    virtual UnicodeString& keyDisplayName(const char* key,
+                      UnicodeString& result) const = 0;
+
+    /**
+     * Returns the display name of the provided value (used with the provided key).
+     * @param key the locale key name
+     * @param value the locale key's value
+     * @param result receives the value's display name
+     * @return the display name of the provided value
+     * @stable ICU 4.4
+     */
+    virtual UnicodeString& keyValueDisplayName(const char* key, const char* value,
+                           UnicodeString& result) const = 0;
+};
+
+inline LocaleDisplayNames* LocaleDisplayNames::createInstance(const Locale& locale) {
+  return LocaleDisplayNames::createInstance(locale, ULDN_STANDARD_NAMES);
+}
+
+U_NAMESPACE_END
+
+#endif
+
+#endif /* U_SHOW_CPLUSPLUS_API */
+
+#endif
diff --git a/src/third_party/icu/source/common/unicode/locid.h b/src/third_party/icu/source/common/unicode/locid.h
index 232ddf2..ba858d7 100644
--- a/src/third_party/icu/source/common/unicode/locid.h
+++ b/src/third_party/icu/source/common/unicode/locid.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
@@ -30,11 +32,16 @@
 #define LOCID_H
 
 #include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
+#include "unicode/bytestream.h"
+#include "unicode/localpointer.h"
+#include "unicode/strenum.h"
+#include "unicode/stringpiece.h"
 #include "unicode/uobject.h"
-#include "unicode/unistr.h"
 #include "unicode/putil.h"
 #include "unicode/uloc.h"
-#include "unicode/strenum.h"
 
 /**
  * \file
@@ -46,6 +53,9 @@
 // Forward Declarations
 void U_CALLCONV locale_available_init(); /**< @internal */
 
+class StringEnumeration;
+class UnicodeString;
+
 /**
  * A <code>Locale</code> object represents a specific geographical, political,
  * or cultural region. An operation that requires a <code>Locale</code> to perform
@@ -85,7 +95,7 @@
  * <P>
  * The third constructor requires a third argument--the <STRONG>Variant.</STRONG>
  * The Variant codes are vendor and browser-specific.
- * For example, use REVISED for a langauge's revised script orthography, and POSIX for POSIX.
+ * For example, use REVISED for a language's revised script orthography, and POSIX for POSIX.
  * Where there are two variants, separate them with an underscore, and
  * put the most important one first. For
  * example, a Traditional Spanish collation might be referenced, with
@@ -243,7 +253,7 @@
     /**
      * Construct a locale from language, country, variant.
      * If an error occurs, then the constructed object will be "bogus"
-     * (isBogus() will return TRUE).
+     * (isBogus() will return true).
      *
      * @param language Lowercase two-letter or three-letter ISO-639 code.
      *  This parameter can instead be an ICU style C locale (e.g. "en_US"),
@@ -277,6 +287,14 @@
      */
     Locale(const    Locale& other);
 
+    /**
+     * Move constructor; might leave source in bogus state.
+     * This locale will have the same contents that the source locale had.
+     *
+     * @param other The Locale object being moved in.
+     * @stable ICU 63
+     */
+    Locale(Locale&& other) U_NOEXCEPT;
 
     /**
      * Destructor
@@ -294,6 +312,17 @@
     Locale& operator=(const Locale& other);
 
     /**
+     * Move assignment operator; might leave source in bogus state.
+     * This locale will have the same contents that the source locale had.
+     * The behavior is undefined if *this and the source are the same object.
+     *
+     * @param other The Locale object being moved in.
+     * @return      *this
+     * @stable ICU 63
+     */
+    Locale& operator=(Locale&& other) U_NOEXCEPT;
+
+    /**
      * Checks if two locale keys are the same.
      *
      * @param other The locale key object to be compared with this.
@@ -310,7 +339,7 @@
      *              otherwise.
      * @stable ICU 2.0
      */
-    UBool   operator!=(const    Locale&     other) const;
+    inline UBool   operator!=(const    Locale&     other) const;
 
     /**
      * Clone this object.
@@ -350,7 +379,7 @@
      * the default locale ID of the runtime environment.
      *
      * @param newLocale Locale to set to.  If NULL, set to the value obtained
-     *                  from the runtime environement.
+     *                  from the runtime environment.
      * @param success The error code.
      * @system
      * @stable ICU 2.0
@@ -360,6 +389,57 @@
 #endif  /* U_HIDE_SYSTEM_API */
 
     /**
+     * Returns a Locale for the specified BCP47 language tag string.
+     * If the specified language tag contains any ill-formed subtags,
+     * the first such subtag and all following subtags are ignored.
+     * <p>
+     * This implements the 'Language-Tag' production of BCP 47, and so
+     * supports legacy language tags (marked as “Type: grandfathered” in BCP 47)
+     * (regular and irregular) as well as private use language tags.
+     *
+     * Private use tags are represented as 'x-whatever',
+     * and legacy tags are converted to their canonical replacements where they exist.
+     *
+     * Note that a few legacy tags have no modern replacement;
+     * these will be converted using the fallback described in
+     * the first paragraph, so some information might be lost.
+     *
+     * @param tag     the input BCP47 language tag.
+     * @param status  error information if creating the Locale failed.
+     * @return        the Locale for the specified BCP47 language tag.
+     * @stable ICU 63
+     */
+    static Locale U_EXPORT2 forLanguageTag(StringPiece tag, UErrorCode& status);
+
+    /**
+     * Returns a well-formed language tag for this Locale.
+     * <p>
+     * <b>Note</b>: Any locale fields which do not satisfy the BCP47 syntax
+     * requirement will be silently omitted from the result.
+     *
+     * If this function fails, partial output may have been written to the sink.
+     *
+     * @param sink    the output sink receiving the BCP47 language
+     *                tag for this Locale.
+     * @param status  error information if creating the language tag failed.
+     * @stable ICU 63
+     */
+    void toLanguageTag(ByteSink& sink, UErrorCode& status) const;
+
+    /**
+     * Returns a well-formed language tag for this Locale.
+     * <p>
+     * <b>Note</b>: Any locale fields which do not satisfy the BCP47 syntax
+     * requirement will be silently omitted from the result.
+     *
+     * @param status  error information if creating the language tag failed.
+     * @return        the BCP47 language tag for this Locale.
+     * @stable ICU 63
+     */
+    template<typename StringClass>
+    inline StringClass toLanguageTag(UErrorCode& status) const;
+
+    /**
      * Creates a locale which has had minimal canonicalization
      * as per uloc_getName().
      * @param name The name to create from.  If name is null,
@@ -372,7 +452,7 @@
 
     /**
      * Creates a locale from the given string after canonicalizing
-     * the string by calling uloc_canonicalize().
+     * the string according to CLDR by calling uloc_canonicalize().
      * @param name the locale ID to create from.  Must not be NULL.
      * @return a new locale object corresponding to the given name
      * @stable ICU 3.0
@@ -429,6 +509,77 @@
      */
     const char * getBaseName() const;
 
+    /**
+     * Add the likely subtags for this Locale, per the algorithm described
+     * in the following CLDR technical report:
+     *
+     *   http://www.unicode.org/reports/tr35/#Likely_Subtags
+     *
+     * If this Locale is already in the maximal form, or not valid, or there is
+     * no data available for maximization, the Locale will be unchanged.
+     *
+     * For example, "und-Zzzz" cannot be maximized, since there is no
+     * reasonable maximization.
+     *
+     * Examples:
+     *
+     * "en" maximizes to "en_Latn_US"
+     *
+     * "de" maximizes to "de_Latn_US"
+     *
+     * "sr" maximizes to "sr_Cyrl_RS"
+     *
+     * "sh" maximizes to "sr_Latn_RS" (Note this will not reverse.)
+     *
+     * "zh_Hani" maximizes to "zh_Hans_CN" (Note this will not reverse.)
+     *
+     * @param status  error information if maximizing this Locale failed.
+     *                If this Locale is not well-formed, the error code is
+     *                U_ILLEGAL_ARGUMENT_ERROR.
+     * @stable ICU 63
+     */
+    void addLikelySubtags(UErrorCode& status);
+
+    /**
+     * Minimize the subtags for this Locale, per the algorithm described
+     * in the following CLDR technical report:
+     *
+     *   http://www.unicode.org/reports/tr35/#Likely_Subtags
+     *
+     * If this Locale is already in the minimal form, or not valid, or there is
+     * no data available for minimization, the Locale will be unchanged.
+     *
+     * Since the minimization algorithm relies on proper maximization, see the
+     * comments for addLikelySubtags for reasons why there might not be any
+     * data.
+     *
+     * Examples:
+     *
+     * "en_Latn_US" minimizes to "en"
+     *
+     * "de_Latn_US" minimizes to "de"
+     *
+     * "sr_Cyrl_RS" minimizes to "sr"
+     *
+     * "zh_Hant_TW" minimizes to "zh_TW" (The region is preferred to the
+     * script, and minimizing to "zh" would imply "zh_Hans_CN".)
+     *
+     * @param status  error information if maximizing this Locale failed.
+     *                If this Locale is not well-formed, the error code is
+     *                U_ILLEGAL_ARGUMENT_ERROR.
+     * @stable ICU 63
+     */
+    void minimizeSubtags(UErrorCode& status);
+
+#ifndef U_HIDE_DRAFT_API
+    /**
+     * Canonicalize the locale ID of this object according to CLDR.
+     * @param status the status code
+     * @draft ICU 67
+     * @see createCanonical
+     */
+    void canonicalize(UErrorCode& status);
+#endif  // U_HIDE_DRAFT_API
 
     /**
      * Gets the list of keywords for the specified locale.
@@ -436,13 +587,58 @@
      * @param status the status code
      * @return pointer to StringEnumeration class, or NULL if there are no keywords. 
      * Client must dispose of it by calling delete.
+     * @see getKeywords
      * @stable ICU 2.8
      */
     StringEnumeration * createKeywords(UErrorCode &status) const;
 
     /**
+     * Gets the list of Unicode keywords for the specified locale.
+     *
+     * @param status the status code
+     * @return pointer to StringEnumeration class, or NULL if there are no keywords.
+     * Client must dispose of it by calling delete.
+     * @see getUnicodeKeywords
+     * @stable ICU 63
+     */
+    StringEnumeration * createUnicodeKeywords(UErrorCode &status) const;
+
+    /**
+     * Gets the set of keywords for this Locale.
+     *
+     * A wrapper to call createKeywords() and write the resulting
+     * keywords as standard strings (or compatible objects) into any kind of
+     * container that can be written to by an STL style output iterator.
+     *
+     * @param iterator  an STL style output iterator to write the keywords to.
+     * @param status    error information if creating set of keywords failed.
+     * @stable ICU 63
+     */
+    template<typename StringClass, typename OutputIterator>
+    inline void getKeywords(OutputIterator iterator, UErrorCode& status) const;
+
+    /**
+     * Gets the set of Unicode keywords for this Locale.
+     *
+     * A wrapper to call createUnicodeKeywords() and write the resulting
+     * keywords as standard strings (or compatible objects) into any kind of
+     * container that can be written to by an STL style output iterator.
+     *
+     * @param iterator  an STL style output iterator to write the keywords to.
+     * @param status    error information if creating set of keywords failed.
+     * @stable ICU 63
+     */
+    template<typename StringClass, typename OutputIterator>
+    inline void getUnicodeKeywords(OutputIterator iterator, UErrorCode& status) const;
+
+    /**
      * Gets the value for a keyword.
      *
+     * This uses legacy keyword=value pairs, like "collation=phonebook".
+     *
+     * ICU4C doesn't do automatic conversion between legacy and Unicode
+     * keywords and values in getters and setters (as opposed to ICU4J).
+     *
      * @param keywordName name of the keyword for which we want the value. Case insensitive.
      * @param buffer The buffer to receive the keyword value.
      * @param bufferCapacity The capacity of receiving buffer
@@ -454,11 +650,78 @@
     int32_t getKeywordValue(const char* keywordName, char *buffer, int32_t bufferCapacity, UErrorCode &status) const;
 
     /**
+     * Gets the value for a keyword.
+     *
+     * This uses legacy keyword=value pairs, like "collation=phonebook".
+     *
+     * ICU4C doesn't do automatic conversion between legacy and Unicode
+     * keywords and values in getters and setters (as opposed to ICU4J).
+     *
+     * @param keywordName  name of the keyword for which we want the value.
+     * @param sink         the sink to receive the keyword value.
+     * @param status       error information if getting the value failed.
+     * @stable ICU 63
+     */
+    void getKeywordValue(StringPiece keywordName, ByteSink& sink, UErrorCode& status) const;
+
+    /**
+     * Gets the value for a keyword.
+     *
+     * This uses legacy keyword=value pairs, like "collation=phonebook".
+     *
+     * ICU4C doesn't do automatic conversion between legacy and Unicode
+     * keywords and values in getters and setters (as opposed to ICU4J).
+     *
+     * @param keywordName  name of the keyword for which we want the value.
+     * @param status       error information if getting the value failed.
+     * @return             the keyword value.
+     * @stable ICU 63
+     */
+    template<typename StringClass>
+    inline StringClass getKeywordValue(StringPiece keywordName, UErrorCode& status) const;
+
+    /**
+     * Gets the Unicode value for a Unicode keyword.
+     *
+     * This uses Unicode key-value pairs, like "co-phonebk".
+     *
+     * ICU4C doesn't do automatic conversion between legacy and Unicode
+     * keywords and values in getters and setters (as opposed to ICU4J).
+     *
+     * @param keywordName  name of the keyword for which we want the value.
+     * @param sink         the sink to receive the keyword value.
+     * @param status       error information if getting the value failed.
+     * @stable ICU 63
+     */
+    void getUnicodeKeywordValue(StringPiece keywordName, ByteSink& sink, UErrorCode& status) const;
+
+    /**
+     * Gets the Unicode value for a Unicode keyword.
+     *
+     * This uses Unicode key-value pairs, like "co-phonebk".
+     *
+     * ICU4C doesn't do automatic conversion between legacy and Unicode
+     * keywords and values in getters and setters (as opposed to ICU4J).
+     *
+     * @param keywordName  name of the keyword for which we want the value.
+     * @param status       error information if getting the value failed.
+     * @return             the keyword value.
+     * @stable ICU 63
+     */
+    template<typename StringClass>
+    inline StringClass getUnicodeKeywordValue(StringPiece keywordName, UErrorCode& status) const;
+
+    /**
      * Sets or removes the value for a keyword.
      *
      * For removing all keywords, use getBaseName(),
      * and construct a new Locale if it differs from getName().
      *
+     * This uses legacy keyword=value pairs, like "collation=phonebook".
+     *
+     * ICU4C doesn't do automatic conversion between legacy and Unicode
+     * keywords and values in getters and setters (as opposed to ICU4J).
+     *
      * @param keywordName name of the keyword to be set. Case insensitive.
      * @param keywordValue value of the keyword to be set. If 0-length or
      *  NULL, will result in the keyword being removed. No error is given if
@@ -470,6 +733,46 @@
     void setKeywordValue(const char* keywordName, const char* keywordValue, UErrorCode &status);
 
     /**
+     * Sets or removes the value for a keyword.
+     *
+     * For removing all keywords, use getBaseName(),
+     * and construct a new Locale if it differs from getName().
+     *
+     * This uses legacy keyword=value pairs, like "collation=phonebook".
+     *
+     * ICU4C doesn't do automatic conversion between legacy and Unicode
+     * keywords and values in getters and setters (as opposed to ICU4J).
+     *
+     * @param keywordName name of the keyword to be set.
+     * @param keywordValue value of the keyword to be set. If 0-length or
+     *  NULL, will result in the keyword being removed. No error is given if
+     *  that keyword does not exist.
+     * @param status Returns any error information while performing this operation.
+     * @stable ICU 63
+     */
+    void setKeywordValue(StringPiece keywordName, StringPiece keywordValue, UErrorCode& status);
+
+    /**
+     * Sets or removes the Unicode value for a Unicode keyword.
+     *
+     * For removing all keywords, use getBaseName(),
+     * and construct a new Locale if it differs from getName().
+     *
+     * This uses Unicode key-value pairs, like "co-phonebk".
+     *
+     * ICU4C doesn't do automatic conversion between legacy and Unicode
+     * keywords and values in getters and setters (as opposed to ICU4J).
+     *
+     * @param keywordName name of the keyword to be set.
+     * @param keywordValue value of the keyword to be set. If 0-length or
+     *  NULL, will result in the keyword being removed. No error is given if
+     *  that keyword does not exist.
+     * @param status Returns any error information while performing this operation.
+     * @stable ICU 63
+     */
+    void setUnicodeKeywordValue(StringPiece keywordName, StringPiece keywordValue, UErrorCode& status);
+
+    /**
      * returns the locale's three-letter language code, as specified
      * in ISO draft standard ISO-639-2.
      * @return      An alias to the code, or an empty string
@@ -496,14 +799,14 @@
     /**
      * Returns whether this locale's script is written right-to-left.
      * If there is no script subtag, then the likely script is used, see uloc_addLikelySubtags().
-     * If no likely script is known, then FALSE is returned.
+     * If no likely script is known, then false is returned.
      *
      * A script is right-to-left according to the CLDR script metadata
      * which corresponds to whether the script's letters have Bidi_Class=R or AL.
      *
-     * Returns TRUE for "ar" and "en-Hebr", FALSE for "zh" and "fa-Cyrl".
+     * Returns true for "ar" and "en-Hebr", false for "zh" and "fa-Cyrl".
      *
-     * @return TRUE if the locale's script is written right-to-left
+     * @return true if the locale's script is written right-to-left
      * @stable ICU 54
      */
     UBool isRightToLeft() const;
@@ -626,7 +929,7 @@
 
     /**
      * Fills in "name" with the name of this locale in a format suitable for user display
-     * in the locale specfied by "displayLocale".  This function uses getDisplayLanguage(),
+     * in the locale specified by "displayLocale".  This function uses getDisplayLanguage(),
      * getDisplayCountry(), and getDisplayVariant() to do its work, and outputs the display
      * name in the format "language (country[,variant])".  For example, if displayLocale is
      * fr_FR, then en_US's display name would be "Anglais (&Eacute;tats-Unis)", and no_NO_NY's
@@ -657,10 +960,10 @@
 
     /**
      * Gets the bogus state. Locale object can be bogus if it doesn't exist
-     * @return FALSE if it is a real locale, TRUE if it is a bogus locale
+     * @return false if it is a real locale, true if it is a bogus locale
      * @stable ICU 2.1
      */
-    UBool isBogus(void) const;
+    inline UBool isBogus(void) const;
 
     /**
      * Returns a list of all installed locales.
@@ -706,6 +1009,102 @@
      */
     virtual UClassID getDynamicClassID() const;
 
+    /**
+     * A Locale iterator interface similar to a Java Iterator<Locale>.
+     * @stable ICU 65
+     */
+    class U_COMMON_API Iterator /* not : public UObject because this is an interface/mixin class */ {
+    public:
+        /** @stable ICU 65 */
+        virtual ~Iterator();
+
+        /**
+         * @return true if next() can be called again.
+         * @stable ICU 65
+         */
+        virtual UBool hasNext() const = 0;
+
+        /**
+         * @return the next locale.
+         * @stable ICU 65
+         */
+        virtual const Locale &next() = 0;
+    };
+
+    /**
+     * A generic Locale iterator implementation over Locale input iterators.
+     * @stable ICU 65
+     */
+    template<typename Iter>
+    class RangeIterator : public Iterator, public UMemory {
+    public:
+        /**
+         * Constructs an iterator from a begin/end range.
+         * Each of the iterator parameter values must be an
+         * input iterator whose value is convertible to const Locale &.
+         *
+         * @param begin Start of range.
+         * @param end Exclusive end of range.
+         * @stable ICU 65
+         */
+        RangeIterator(Iter begin, Iter end) : it_(begin), end_(end) {}
+
+        /**
+         * @return true if next() can be called again.
+         * @stable ICU 65
+         */
+        UBool hasNext() const override { return it_ != end_; }
+
+        /**
+         * @return the next locale.
+         * @stable ICU 65
+         */
+        const Locale &next() override { return *it_++; }
+
+    private:
+        Iter it_;
+        const Iter end_;
+    };
+
+    /**
+     * A generic Locale iterator implementation over Locale input iterators.
+     * Calls the converter to convert each *begin to a const Locale &.
+     * @stable ICU 65
+     */
+    template<typename Iter, typename Conv>
+    class ConvertingIterator : public Iterator, public UMemory {
+    public:
+        /**
+         * Constructs an iterator from a begin/end range.
+         * Each of the iterator parameter values must be an
+         * input iterator whose value the converter converts to const Locale &.
+         *
+         * @param begin Start of range.
+         * @param end Exclusive end of range.
+         * @param converter Converter from *begin to const Locale & or compatible.
+         * @stable ICU 65
+         */
+        ConvertingIterator(Iter begin, Iter end, Conv converter) :
+                it_(begin), end_(end), converter_(converter) {}
+
+        /**
+         * @return true if next() can be called again.
+         * @stable ICU 65
+         */
+        UBool hasNext() const override { return it_ != end_; }
+
+        /**
+         * @return the next locale.
+         * @stable ICU 65
+         */
+        const Locale &next() override { return converter_(*it_++); }
+
+    private:
+        Iter it_;
+        const Iter end_;
+        Conv converter_;
+    };
+
 protected: /* only protected for testing purposes. DO NOT USE. */
 #ifndef U_HIDE_INTERNAL_API
     /**
@@ -756,12 +1155,12 @@
 
     /**
      * A friend to allow the default locale to be set by either the C or C++ API.
-     * @internal
+     * @internal (private)
      */
     friend Locale *locale_set_default_internal(const char *, UErrorCode& status);
 
     /**
-     * @internal
+     * @internal (private)
      */
     friend void U_CALLCONV locale_available_init();
 };
@@ -772,6 +1171,15 @@
     return !operator==(other);
 }
 
+template<typename StringClass> inline StringClass
+Locale::toLanguageTag(UErrorCode& status) const
+{
+    StringClass result;
+    StringByteSink<StringClass> sink(&result);
+    toLanguageTag(sink, status);
+    return result;
+}
+
 inline const char *
 Locale::getCountry() const
 {
@@ -802,6 +1210,58 @@
     return fullName;
 }
 
+template<typename StringClass, typename OutputIterator> inline void
+Locale::getKeywords(OutputIterator iterator, UErrorCode& status) const
+{
+    LocalPointer<StringEnumeration> keys(createKeywords(status));
+    if (U_FAILURE(status) || keys.isNull()) {
+        return;
+    }
+    for (;;) {
+        int32_t resultLength;
+        const char* buffer = keys->next(&resultLength, status);
+        if (U_FAILURE(status) || buffer == nullptr) {
+            return;
+        }
+        *iterator++ = StringClass(buffer, resultLength);
+    }
+}
+
+template<typename StringClass, typename OutputIterator> inline void
+Locale::getUnicodeKeywords(OutputIterator iterator, UErrorCode& status) const
+{
+    LocalPointer<StringEnumeration> keys(createUnicodeKeywords(status));
+    if (U_FAILURE(status) || keys.isNull()) {
+        return;
+    }
+    for (;;) {
+        int32_t resultLength;
+        const char* buffer = keys->next(&resultLength, status);
+        if (U_FAILURE(status) || buffer == nullptr) {
+            return;
+        }
+        *iterator++ = StringClass(buffer, resultLength);
+    }
+}
+
+template<typename StringClass> inline StringClass
+Locale::getKeywordValue(StringPiece keywordName, UErrorCode& status) const
+{
+    StringClass result;
+    StringByteSink<StringClass> sink(&result);
+    getKeywordValue(keywordName, sink, status);
+    return result;
+}
+
+template<typename StringClass> inline StringClass
+Locale::getUnicodeKeywordValue(StringPiece keywordName, UErrorCode& status) const
+{
+    StringClass result;
+    StringByteSink<StringClass> sink(&result);
+    getUnicodeKeywordValue(keywordName, sink, status);
+    return result;
+}
+
 inline UBool
 Locale::isBogus(void) const {
     return fIsBogus;
@@ -809,4 +1269,6 @@
 
 U_NAMESPACE_END
 
+#endif /* U_SHOW_CPLUSPLUS_API */
+
 #endif
diff --git a/src/third_party/icu/source/common/unicode/messagepattern.h b/src/third_party/icu/source/common/unicode/messagepattern.h
index f8b8dfb..98e7b70 100644
--- a/src/third_party/icu/source/common/unicode/messagepattern.h
+++ b/src/third_party/icu/source/common/unicode/messagepattern.h
@@ -1,10 +1,12 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *   Copyright (C) 2011-2013, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *******************************************************************************
 *   file name:  messagepattern.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -22,6 +24,8 @@
 
 #include "unicode/utypes.h"
 
+#if U_SHOW_CPLUSPLUS_API
+
 #if !UCONFIG_NO_FORMATTING
 
 #include "unicode/parseerr.h"
@@ -261,7 +265,7 @@
 
 /**
  * \def UMSGPAT_ARG_TYPE_HAS_PLURAL_STYLE
- * Returns TRUE if the argument type has a plural style part sequence and semantics,
+ * Returns true if the argument type has a plural style part sequence and semantics,
  * for example UMSGPAT_ARG_TYPE_PLURAL and UMSGPAT_ARG_TYPE_SELECTORDINAL.
  * @stable ICU 50
  */
@@ -519,14 +523,14 @@
 
     /**
      * @param other another object to compare with.
-     * @return TRUE if this object is equivalent to the other one.
+     * @return true if this object is equivalent to the other one.
      * @stable ICU 4.8
      */
     UBool operator==(const MessagePattern &other) const;
 
     /**
      * @param other another object to compare with.
-     * @return FALSE if this object is equivalent to the other one.
+     * @return false if this object is equivalent to the other one.
      * @stable ICU 4.8
      */
     inline UBool operator!=(const MessagePattern &other) const {
@@ -560,7 +564,7 @@
 
     /**
      * Does the parsed pattern have named arguments like {first_name}?
-     * @return TRUE if the parsed pattern has at least one named argument.
+     * @return true if the parsed pattern has at least one named argument.
      * @stable ICU 4.8
      */
     UBool hasNamedArguments() const {
@@ -569,7 +573,7 @@
 
     /**
      * Does the parsed pattern have numbered arguments like {2}?
-     * @return TRUE if the parsed pattern has at least one numbered argument.
+     * @return true if the parsed pattern has at least one numbered argument.
      * @stable ICU 4.8
      */
     UBool hasNumberedArguments() const {
@@ -660,7 +664,7 @@
      * Compares the part's substring with the input string s.
      * @param part a part of this MessagePattern.
      * @param s a string.
-     * @return TRUE if getSubstring(part).equals(s).
+     * @return true if getSubstring(part).equals(s).
      * @stable ICU 4.8
      */
     UBool partSubstringMatches(const Part &part, const UnicodeString &s) const {
@@ -769,8 +773,8 @@
          * @stable ICU 4.8
          */
         UMessagePatternArgType getArgType() const {
-            UMessagePatternPartType type=getType();
-            if(type==UMSGPAT_PART_TYPE_ARG_START || type==UMSGPAT_PART_TYPE_ARG_LIMIT) {
+            UMessagePatternPartType msgType=getType();
+            if(msgType ==UMSGPAT_PART_TYPE_ARG_START || msgType ==UMSGPAT_PART_TYPE_ARG_LIMIT) {
                 return (UMessagePatternArgType)value;
             } else {
                 return UMSGPAT_ARG_TYPE_NONE;
@@ -781,7 +785,7 @@
          * Indicates whether the Part type has a numeric value.
          * If so, then that numeric value can be retrieved via MessagePattern.getNumericValue().
          * @param type The Part type to be tested.
-         * @return TRUE if the Part type has a numeric value.
+         * @return true if the Part type has a numeric value.
          * @stable ICU 4.8
          */
         static UBool hasNumericValue(UMessagePatternPartType type) {
@@ -790,14 +794,14 @@
 
         /**
          * @param other another object to compare with.
-         * @return TRUE if this object is equivalent to the other one.
+         * @return true if this object is equivalent to the other one.
          * @stable ICU 4.8
          */
         UBool operator==(const Part &other) const;
 
         /**
          * @param other another object to compare with.
-         * @return FALSE if this object is equivalent to the other one.
+         * @return false if this object is equivalent to the other one.
          * @stable ICU 4.8
          */
         inline UBool operator!=(const Part &other) const {
@@ -865,7 +869,7 @@
      * Parses a number from the specified message substring.
      * @param start start index into the message string
      * @param limit limit index into the message string, must be start<limit
-     * @param allowInfinity TRUE if U+221E is allowed (for ChoiceFormat)
+     * @param allowInfinity true if U+221E is allowed (for ChoiceFormat)
      * @param parseError
      * @param errorCode
      */
@@ -896,13 +900,13 @@
     UBool isOrdinal(int32_t index);
 
     /**
-     * @return TRUE if we are inside a MessageFormat (sub-)pattern,
+     * @return true if we are inside a MessageFormat (sub-)pattern,
      *         as opposed to inside a top-level choice/plural/select pattern.
      */
     UBool inMessageFormatPattern(int32_t nestingLevel);
 
     /**
-     * @return TRUE if we are in a MessageFormat sub-pattern
+     * @return true if we are in a MessageFormat sub-pattern
      *         of a top-level ChoiceFormat pattern.
      */
     UBool inTopLevelChoiceMessage(int32_t nestingLevel, UMessagePatternArgType parentType);
@@ -940,4 +944,6 @@
 
 #endif  // !UCONFIG_NO_FORMATTING
 
+#endif /* U_SHOW_CPLUSPLUS_API */
+
 #endif  // __MESSAGEPATTERN_H__
diff --git a/src/third_party/icu/source/common/unicode/normalizer2.h b/src/third_party/icu/source/common/unicode/normalizer2.h
index c03cba3..5eb1d95 100644
--- a/src/third_party/icu/source/common/unicode/normalizer2.h
+++ b/src/third_party/icu/source/common/unicode/normalizer2.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  normalizer2.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -24,14 +26,19 @@
 
 #include "unicode/utypes.h"
 
+#if U_SHOW_CPLUSPLUS_API
+
 #if !UCONFIG_NO_NORMALIZATION
 
+#include "unicode/stringpiece.h"
 #include "unicode/uniset.h"
 #include "unicode/unistr.h"
 #include "unicode/unorm2.h"
 
 U_NAMESPACE_BEGIN
 
+class ByteSink;
+
 /**
  * Unicode normalization functionality for standard Unicode normalization or
  * for using custom mapping tables.
@@ -213,6 +220,35 @@
     normalize(const UnicodeString &src,
               UnicodeString &dest,
               UErrorCode &errorCode) const = 0;
+
+    /**
+     * Normalizes a UTF-8 string and optionally records how source substrings
+     * relate to changed and unchanged result substrings.
+     *
+     * Currently implemented completely only for "compose" modes,
+     * such as for NFC, NFKC, and NFKC_Casefold
+     * (UNORM2_COMPOSE and UNORM2_COMPOSE_CONTIGUOUS).
+     * Otherwise currently converts to & from UTF-16 and does not support edits.
+     *
+     * @param options   Options bit set, usually 0. See U_OMIT_UNCHANGED_TEXT and U_EDITS_NO_RESET.
+     * @param src       Source UTF-8 string.
+     * @param sink      A ByteSink to which the normalized UTF-8 result string is written.
+     *                  sink.Flush() is called at the end.
+     * @param edits     Records edits for index mapping, working with styled text,
+     *                  and getting only changes (if any).
+     *                  The Edits contents is undefined if any error occurs.
+     *                  This function calls edits->reset() first unless
+     *                  options includes U_EDITS_NO_RESET. edits can be nullptr.
+     * @param errorCode Standard ICU error code. Its input value must
+     *                  pass the U_SUCCESS() test, or else the function returns
+     *                  immediately. Check for U_FAILURE() on output or use with
+     *                  function chaining. (See User Guide for details.)
+     * @stable ICU 60
+     */
+    virtual void
+    normalizeUTF8(uint32_t options, StringPiece src, ByteSink &sink,
+                  Edits *edits, UErrorCode &errorCode) const;
+
     /**
      * Appends the normalized form of the second string to the first string
      * (merging them at the boundary) and returns the first string.
@@ -254,13 +290,13 @@
      * Gets the decomposition mapping of c.
      * Roughly equivalent to normalizing the String form of c
      * on a UNORM2_DECOMPOSE Normalizer2 instance, but much faster, and except that this function
-     * returns FALSE and does not write a string
+     * returns false and does not write a string
      * if c does not have a decomposition mapping in this instance's data.
      * This function is independent of the mode of the Normalizer2.
      * @param c code point
      * @param decomposition String object which will be set to c's
      *                      decomposition mapping, if there is one.
-     * @return TRUE if c has a decomposition, otherwise FALSE
+     * @return true if c has a decomposition, otherwise false
      * @stable ICU 4.6
      */
     virtual UBool
@@ -280,14 +316,14 @@
      *
      * When used on a standard NFC Normalizer2 instance,
      * it returns the Decomposition_Mapping only if the Decomposition_Type (dt) is Canonical (Can);
-     * in this case, the result contains either one or two code points (=1..4 UChars).
+     * in this case, the result contains either one or two code points (=1..4 char16_ts).
      *
      * This function is independent of the mode of the Normalizer2.
-     * The default implementation returns FALSE.
+     * The default implementation returns false.
      * @param c code point
      * @param decomposition String object which will be set to c's
      *                      raw decomposition mapping, if there is one.
-     * @return TRUE if c has a decomposition, otherwise FALSE
+     * @return true if c has a decomposition, otherwise false
      * @stable ICU 49
      */
     virtual UBool
@@ -333,11 +369,35 @@
      *                  pass the U_SUCCESS() test, or else the function returns
      *                  immediately. Check for U_FAILURE() on output or use with
      *                  function chaining. (See User Guide for details.)
-     * @return TRUE if s is normalized
+     * @return true if s is normalized
      * @stable ICU 4.4
      */
     virtual UBool
     isNormalized(const UnicodeString &s, UErrorCode &errorCode) const = 0;
+    /**
+     * Tests if the UTF-8 string is normalized.
+     * Internally, in cases where the quickCheck() method would return "maybe"
+     * (which is only possible for the two COMPOSE modes) this method
+     * resolves to "yes" or "no" to provide a definitive result,
+     * at the cost of doing more work in those cases.
+     *
+     * This works for all normalization modes,
+     * but it is currently optimized for UTF-8 only for "compose" modes,
+     * such as for NFC, NFKC, and NFKC_Casefold
+     * (UNORM2_COMPOSE and UNORM2_COMPOSE_CONTIGUOUS).
+     * For other modes it currently converts to UTF-16 and calls isNormalized().
+     *
+     * @param s UTF-8 input string
+     * @param errorCode Standard ICU error code. Its input value must
+     *                  pass the U_SUCCESS() test, or else the function returns
+     *                  immediately. Check for U_FAILURE() on output or use with
+     *                  function chaining. (See User Guide for details.)
+     * @return true if s is normalized
+     * @stable ICU 60
+     */
+    virtual UBool
+    isNormalizedUTF8(StringPiece s, UErrorCode &errorCode) const;
+
 
     /**
      * Tests if the string is normalized.
@@ -392,7 +452,7 @@
      * character independently.
      * This is used for iterative normalization. See the class documentation for details.
      * @param c character to test
-     * @return TRUE if c has a normalization boundary before it
+     * @return true if c has a normalization boundary before it
      * @stable ICU 4.4
      */
     virtual UBool hasBoundaryBefore(UChar32 c) const = 0;
@@ -408,7 +468,7 @@
      * This is used for iterative normalization. See the class documentation for details.
      * Note that this operation may be significantly slower than hasBoundaryBefore().
      * @param c character to test
-     * @return TRUE if c has a normalization boundary after it
+     * @return true if c has a normalization boundary after it
      * @stable ICU 4.4
      */
     virtual UBool hasBoundaryAfter(UChar32 c) const = 0;
@@ -423,7 +483,7 @@
      * This is used for iterative normalization. See the class documentation for details.
      * Note that this operation may be significantly slower than hasBoundaryBefore().
      * @param c character to test
-     * @return TRUE if c is normalization-inert
+     * @return true if c is normalization-inert
      * @stable ICU 4.4
      */
     virtual UBool isInert(UChar32 c) const = 0;
@@ -477,7 +537,36 @@
     virtual UnicodeString &
     normalize(const UnicodeString &src,
               UnicodeString &dest,
-              UErrorCode &errorCode) const;
+              UErrorCode &errorCode) const U_OVERRIDE;
+
+    /**
+     * Normalizes a UTF-8 string and optionally records how source substrings
+     * relate to changed and unchanged result substrings.
+     *
+     * Currently implemented completely only for "compose" modes,
+     * such as for NFC, NFKC, and NFKC_Casefold
+     * (UNORM2_COMPOSE and UNORM2_COMPOSE_CONTIGUOUS).
+     * Otherwise currently converts to & from UTF-16 and does not support edits.
+     *
+     * @param options   Options bit set, usually 0. See U_OMIT_UNCHANGED_TEXT and U_EDITS_NO_RESET.
+     * @param src       Source UTF-8 string.
+     * @param sink      A ByteSink to which the normalized UTF-8 result string is written.
+     *                  sink.Flush() is called at the end.
+     * @param edits     Records edits for index mapping, working with styled text,
+     *                  and getting only changes (if any).
+     *                  The Edits contents is undefined if any error occurs.
+     *                  This function calls edits->reset() first unless
+     *                  options includes U_EDITS_NO_RESET. edits can be nullptr.
+     * @param errorCode Standard ICU error code. Its input value must
+     *                  pass the U_SUCCESS() test, or else the function returns
+     *                  immediately. Check for U_FAILURE() on output or use with
+     *                  function chaining. (See User Guide for details.)
+     * @stable ICU 60
+     */
+    virtual void
+    normalizeUTF8(uint32_t options, StringPiece src, ByteSink &sink,
+                  Edits *edits, UErrorCode &errorCode) const U_OVERRIDE;
+
     /**
      * Appends the normalized form of the second string to the first string
      * (merging them at the boundary) and returns the first string.
@@ -495,7 +584,7 @@
     virtual UnicodeString &
     normalizeSecondAndAppend(UnicodeString &first,
                              const UnicodeString &second,
-                             UErrorCode &errorCode) const;
+                             UErrorCode &errorCode) const U_OVERRIDE;
     /**
      * Appends the second string to the first string
      * (merging them at the boundary) and returns the first string.
@@ -513,7 +602,7 @@
     virtual UnicodeString &
     append(UnicodeString &first,
            const UnicodeString &second,
-           UErrorCode &errorCode) const;
+           UErrorCode &errorCode) const U_OVERRIDE;
 
     /**
      * Gets the decomposition mapping of c.
@@ -523,11 +612,11 @@
      * @param c code point
      * @param decomposition String object which will be set to c's
      *                      decomposition mapping, if there is one.
-     * @return TRUE if c has a decomposition, otherwise FALSE
+     * @return true if c has a decomposition, otherwise false
      * @stable ICU 4.6
      */
     virtual UBool
-    getDecomposition(UChar32 c, UnicodeString &decomposition) const;
+    getDecomposition(UChar32 c, UnicodeString &decomposition) const U_OVERRIDE;
 
     /**
      * Gets the raw decomposition mapping of c.
@@ -537,11 +626,11 @@
      * @param c code point
      * @param decomposition String object which will be set to c's
      *                      raw decomposition mapping, if there is one.
-     * @return TRUE if c has a decomposition, otherwise FALSE
+     * @return true if c has a decomposition, otherwise false
      * @stable ICU 49
      */
     virtual UBool
-    getRawDecomposition(UChar32 c, UnicodeString &decomposition) const;
+    getRawDecomposition(UChar32 c, UnicodeString &decomposition) const U_OVERRIDE;
 
     /**
      * Performs pairwise composition of a & b and returns the composite if there is one.
@@ -554,7 +643,7 @@
      * @stable ICU 49
      */
     virtual UChar32
-    composePair(UChar32 a, UChar32 b) const;
+    composePair(UChar32 a, UChar32 b) const U_OVERRIDE;
 
     /**
      * Gets the combining class of c.
@@ -565,7 +654,7 @@
      * @stable ICU 49
      */
     virtual uint8_t
-    getCombiningClass(UChar32 c) const;
+    getCombiningClass(UChar32 c) const U_OVERRIDE;
 
     /**
      * Tests if the string is normalized.
@@ -575,11 +664,34 @@
      *                  pass the U_SUCCESS() test, or else the function returns
      *                  immediately. Check for U_FAILURE() on output or use with
      *                  function chaining. (See User Guide for details.)
-     * @return TRUE if s is normalized
+     * @return true if s is normalized
      * @stable ICU 4.4
      */
     virtual UBool
-    isNormalized(const UnicodeString &s, UErrorCode &errorCode) const;
+    isNormalized(const UnicodeString &s, UErrorCode &errorCode) const U_OVERRIDE;
+    /**
+     * Tests if the UTF-8 string is normalized.
+     * Internally, in cases where the quickCheck() method would return "maybe"
+     * (which is only possible for the two COMPOSE modes) this method
+     * resolves to "yes" or "no" to provide a definitive result,
+     * at the cost of doing more work in those cases.
+     *
+     * This works for all normalization modes,
+     * but it is currently optimized for UTF-8 only for "compose" modes,
+     * such as for NFC, NFKC, and NFKC_Casefold
+     * (UNORM2_COMPOSE and UNORM2_COMPOSE_CONTIGUOUS).
+     * For other modes it currently converts to UTF-16 and calls isNormalized().
+     *
+     * @param s UTF-8 input string
+     * @param errorCode Standard ICU error code. Its input value must
+     *                  pass the U_SUCCESS() test, or else the function returns
+     *                  immediately. Check for U_FAILURE() on output or use with
+     *                  function chaining. (See User Guide for details.)
+     * @return true if s is normalized
+     * @stable ICU 60
+     */
+    virtual UBool
+    isNormalizedUTF8(StringPiece s, UErrorCode &errorCode) const U_OVERRIDE;
     /**
      * Tests if the string is normalized.
      * For details see the Normalizer2 base class documentation.
@@ -592,7 +704,7 @@
      * @stable ICU 4.4
      */
     virtual UNormalizationCheckResult
-    quickCheck(const UnicodeString &s, UErrorCode &errorCode) const;
+    quickCheck(const UnicodeString &s, UErrorCode &errorCode) const U_OVERRIDE;
     /**
      * Returns the end of the normalized substring of the input string.
      * For details see the Normalizer2 base class documentation.
@@ -605,36 +717,36 @@
      * @stable ICU 4.4
      */
     virtual int32_t
-    spanQuickCheckYes(const UnicodeString &s, UErrorCode &errorCode) const;
+    spanQuickCheckYes(const UnicodeString &s, UErrorCode &errorCode) const U_OVERRIDE;
 
     /**
      * Tests if the character always has a normalization boundary before it,
      * regardless of context.
      * For details see the Normalizer2 base class documentation.
      * @param c character to test
-     * @return TRUE if c has a normalization boundary before it
+     * @return true if c has a normalization boundary before it
      * @stable ICU 4.4
      */
-    virtual UBool hasBoundaryBefore(UChar32 c) const;
+    virtual UBool hasBoundaryBefore(UChar32 c) const U_OVERRIDE;
 
     /**
      * Tests if the character always has a normalization boundary after it,
      * regardless of context.
      * For details see the Normalizer2 base class documentation.
      * @param c character to test
-     * @return TRUE if c has a normalization boundary after it
+     * @return true if c has a normalization boundary after it
      * @stable ICU 4.4
      */
-    virtual UBool hasBoundaryAfter(UChar32 c) const;
+    virtual UBool hasBoundaryAfter(UChar32 c) const U_OVERRIDE;
 
     /**
      * Tests if the character is normalization-inert.
      * For details see the Normalizer2 base class documentation.
      * @param c character to test
-     * @return TRUE if c is normalization-inert
+     * @return true if c is normalization-inert
      * @stable ICU 4.4
      */
-    virtual UBool isInert(UChar32 c) const;
+    virtual UBool isInert(UChar32 c) const U_OVERRIDE;
 private:
     UnicodeString &
     normalize(const UnicodeString &src,
@@ -642,6 +754,12 @@
               USetSpanCondition spanCondition,
               UErrorCode &errorCode) const;
 
+    void
+    normalizeUTF8(uint32_t options, const char *src, int32_t length,
+                  ByteSink &sink, Edits *edits,
+                  USetSpanCondition spanCondition,
+                  UErrorCode &errorCode) const;
+
     UnicodeString &
     normalizeSecondAndAppend(UnicodeString &first,
                              const UnicodeString &second,
@@ -655,4 +773,7 @@
 U_NAMESPACE_END
 
 #endif  // !UCONFIG_NO_NORMALIZATION
+
+#endif /* U_SHOW_CPLUSPLUS_API */
+
 #endif  // __NORMALIZER2_H__
diff --git a/src/third_party/icu/source/common/unicode/normlzr.h b/src/third_party/icu/source/common/unicode/normlzr.h
index 7be0a7d..3352983 100644
--- a/src/third_party/icu/source/common/unicode/normlzr.h
+++ b/src/third_party/icu/source/common/unicode/normlzr.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
  ********************************************************************
  * COPYRIGHT:
@@ -11,6 +13,8 @@
 
 #include "unicode/utypes.h"
 
+#if U_SHOW_CPLUSPLUS_API
+
 /**
  * \file 
  * \brief C++ API: Unicode Normalization
@@ -166,7 +170,7 @@
    * @param mode  The normalization mode.
    * @deprecated ICU 56 Use Normalizer2 instead.
    */
-  Normalizer(const UChar* str, int32_t length, UNormalizationMode mode);
+  Normalizer(ConstChar16Ptr str, int32_t length, UNormalizationMode mode);
 
   /**
    * Creates a new <code>Normalizer</code> object for iterating over the
@@ -179,21 +183,22 @@
    * @deprecated ICU 56 Use Normalizer2 instead.
    */
   Normalizer(const CharacterIterator& iter, UNormalizationMode mode);
+#endif  /* U_HIDE_DEPRECATED_API */
 
+#ifndef U_FORCE_HIDE_DEPRECATED_API
   /**
    * Copy constructor.
    * @param copy The object to be copied.
    * @deprecated ICU 56 Use Normalizer2 instead.
    */
   Normalizer(const Normalizer& copy);
-#endif  /* U_HIDE_DEPRECATED_API */
 
   /**
    * Destructor
    * @deprecated ICU 56 Use Normalizer2 instead.
    */
   virtual ~Normalizer();
-
+#endif  // U_FORCE_HIDE_DEPRECATED_API
 
   //-------------------------------------------------------------------------
   // Static utility methods
@@ -229,7 +234,7 @@
    *
    * @param source    the string to be composed.
    * @param compat    Perform compatibility decomposition before composition.
-   *                  If this argument is <code>FALSE</code>, only canonical
+   *                  If this argument is <code>false</code>, only canonical
    *                  decomposition will be performed.
    * @param options   the optional features to be enabled (0 for no options)
    * @param result    The composed string (on output).
@@ -251,7 +256,7 @@
    *
    * @param source    the string to be decomposed.
    * @param compat    Perform compatibility decomposition.
-   *                  If this argument is <code>FALSE</code>, only canonical
+   *                  If this argument is <code>false</code>, only canonical
    *                  decomposition will be performed.
    * @param options   the optional features to be enabled (0 for no options)
    * @param result    The decomposed string (on output).
@@ -310,7 +315,7 @@
    * never a "maybe".
    * For NFD, NFKD, and FCD, both functions work exactly the same.
    * For NFC and NFKC where quickCheck may return "maybe", this function will
-   * perform further tests to arrive at a TRUE/FALSE result.
+   * perform further tests to arrive at a true/false result.
    *
    * @param src        String that is to be tested if it is in a normalization format.
    * @param mode       Which normalization form to test for.
@@ -572,7 +577,7 @@
   int32_t            endIndex(void) const;
 
   /**
-   * Returns TRUE when both iterators refer to the same character in the same
+   * Returns true when both iterators refer to the same character in the same
    * input text.
    *
    * @param that a Normalizer object to compare this one to
@@ -582,7 +587,7 @@
   UBool        operator==(const Normalizer& that) const;
 
   /**
-   * Returns FALSE when both iterators refer to the same character in the same
+   * Returns false when both iterators refer to the same character in the same
    * input text.
    *
    * @param that a Normalizer object to compare this one to
@@ -597,7 +602,7 @@
    * @return a pointer to a new Normalizer
    * @deprecated ICU 56 Use Normalizer2 instead.
    */
-  Normalizer*        clone(void) const;
+  Normalizer*        clone() const;
 
   /**
    * Generates a hash code for this iterator.
@@ -650,8 +655,8 @@
    * It is possible to specify multiple options that are all turned on or off.
    *
    * @param   option  the option(s) whose value is/are to be set.
-   * @param   value   the new setting for the option.  Use <code>TRUE</code> to
-   *                  turn the option(s) on and <code>FALSE</code> to turn it/them off.
+   * @param   value   the new setting for the option.  Use <code>true</code> to
+   *                  turn the option(s) on and <code>false</code> to turn it/them off.
    *
    * @see #getOption
    * @deprecated ICU 56 Use Normalizer2 instead.
@@ -661,11 +666,11 @@
 
   /**
    * Determine whether an option is turned on or off.
-   * If multiple options are specified, then the result is TRUE if any
+   * If multiple options are specified, then the result is true if any
    * of them are set.
    * <p>
    * @param option the option(s) that are to be checked
-   * @return TRUE if any of the option(s) are set
+   * @return true if any of the option(s) are set
    * @see #setOption
    * @deprecated ICU 56 Use Normalizer2 instead.
    */
@@ -702,7 +707,7 @@
    * @param status a UErrorCode
    * @deprecated ICU 56 Use Normalizer2 instead.
    */
-  void setText(const UChar* newText,
+  void setText(ConstChar16Ptr newText,
                     int32_t length,
             UErrorCode &status);
   /**
@@ -721,12 +726,14 @@
   static UClassID U_EXPORT2 getStaticClassID();
 #endif  /* U_HIDE_DEPRECATED_API */
 
+#ifndef U_FORCE_HIDE_DEPRECATED_API
   /**
    * ICU "poor man's RTTI", returns a UClassID for the actual class.
    * @return a UClassID for the actual class.
    * @deprecated ICU 56 Use Normalizer2 instead.
    */
   virtual UClassID getDynamicClassID() const;
+#endif  // U_FORCE_HIDE_DEPRECATED_API
 
 private:
   //-------------------------------------------------------------------------
@@ -750,9 +757,7 @@
 
   FilteredNormalizer2*fFilteredNorm2;  // owned if not NULL
   const Normalizer2  *fNorm2;  // not owned; may be equal to fFilteredNorm2
-#ifndef U_HIDE_DEPRECATED_API
-  UNormalizationMode  fUMode;
-#endif  /* U_HIDE_DEPRECATED_API */
+  UNormalizationMode  fUMode;  // deprecated
   int32_t             fOptions;
 
   // The input text and our position in it
@@ -796,8 +801,8 @@
                     uint32_t options,
                     UErrorCode &errorCode) {
   // all argument checking is done in unorm_compare
-  return unorm_compare(s1.getBuffer(), s1.length(),
-                       s2.getBuffer(), s2.length(),
+  return unorm_compare(toUCharPtr(s1.getBuffer()), s1.length(),
+                       toUCharPtr(s2.getBuffer()), s2.length(),
                        options,
                        &errorCode);
 }
@@ -807,3 +812,5 @@
 #endif /* #if !UCONFIG_NO_NORMALIZATION */
 
 #endif // NORMLZR_H
+
+#endif /* U_SHOW_CPLUSPLUS_API */
diff --git a/src/third_party/icu/source/common/unicode/parseerr.h b/src/third_party/icu/source/common/unicode/parseerr.h
index 44ff008..c23cc27 100644
--- a/src/third_party/icu/source/common/unicode/parseerr.h
+++ b/src/third_party/icu/source/common/unicode/parseerr.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
 *   Copyright (C) 1999-2005, International Business Machines
@@ -56,9 +58,9 @@
 typedef struct UParseError {
 
     /**
-     * The line on which the error occured.  If the parser uses this
+     * The line on which the error occurred.  If the parser uses this
      * field, it sets it to the line number of the source text line on
-     * which the error appears, which will be be a value >= 1.  If the
+     * which the error appears, which will be a value >= 1.  If the
      * parse does not support line numbers, the value will be <= 0.
      * @stable ICU 2.0
      */
diff --git a/src/third_party/icu/source/common/unicode/parsepos.h b/src/third_party/icu/source/common/unicode/parsepos.h
index cdf49e0..260ed4c 100644
--- a/src/third_party/icu/source/common/unicode/parsepos.h
+++ b/src/third_party/icu/source/common/unicode/parsepos.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 * Copyright (C) 1997-2005, International Business Machines Corporation and others. All Rights Reserved.
 *******************************************************************************
@@ -17,6 +19,9 @@
 #define PARSEPOS_H
 
 #include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
 #include "unicode/uobject.h"
 
  
@@ -88,21 +93,21 @@
      * Assignment operator
      * @stable ICU 2.0
      */
-    ParsePosition&      operator=(const ParsePosition& copy);
+    inline ParsePosition&      operator=(const ParsePosition& copy);
 
     /**
      * Equality operator.
-     * @return TRUE if the two parse positions are equal, FALSE otherwise.
+     * @return true if the two parse positions are equal, false otherwise.
      * @stable ICU 2.0
      */
-    UBool              operator==(const ParsePosition& that) const;
+    inline UBool              operator==(const ParsePosition& that) const;
 
     /**
      * Equality operator.
-     * @return TRUE if the two parse positions are not equal, FALSE otherwise.
+     * @return true if the two parse positions are not equal, false otherwise.
      * @stable ICU 2.0
      */
-    UBool              operator!=(const ParsePosition& that) const;
+    inline UBool              operator!=(const ParsePosition& that) const;
 
     /**
      * Clone this object.
@@ -124,14 +129,14 @@
      * @return the current index.
      * @stable ICU 2.0
      */
-    int32_t getIndex(void) const;
+    inline int32_t getIndex(void) const;
 
     /**
      * Set the current parse position.
      * @param index the new index.
      * @stable ICU 2.0
      */
-    void setIndex(int32_t index);
+    inline void setIndex(int32_t index);
 
     /**
      * Set the index at which a parse error occurred.  Formatters
@@ -140,14 +145,14 @@
      * set.
      * @stable ICU 2.0
      */
-    void setErrorIndex(int32_t ei);
+    inline void setErrorIndex(int32_t ei);
 
     /**
      * Retrieve the index at which an error occurred, or -1 if the
      * error index has not been set.
      * @stable ICU 2.0
      */
-    int32_t getErrorIndex(void) const;
+    inline int32_t getErrorIndex(void) const;
 
     /**
      * ICU "poor man's RTTI", returns a UClassID for this class.
@@ -191,9 +196,9 @@
 ParsePosition::operator==(const ParsePosition& copy) const
 {
   if(index != copy.index || errorIndex != copy.errorIndex)
-  return FALSE;
+  return false;
   else
-  return TRUE;
+  return true;
 }
 
 inline UBool
@@ -227,4 +232,6 @@
 }
 U_NAMESPACE_END
 
+#endif /* U_SHOW_CPLUSPLUS_API */
+
 #endif
diff --git a/src/third_party/icu/source/common/unicode/platform.h b/src/third_party/icu/source/common/unicode/platform.h
index a390138..a27f315 100644
--- a/src/third_party/icu/source/common/unicode/platform.h
+++ b/src/third_party/icu/source/common/unicode/platform.h
@@ -1,7 +1,9 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
-*   Copyright (C) 1997-2015, International Business Machines
+*   Copyright (C) 1997-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *
 ******************************************************************************
@@ -39,7 +41,7 @@
  * and/or from other macros that are predefined by the compiler
  * or defined in standard (POSIX or platform or compiler) headers.
  *
- * As a temporary workaround, you can add an explicit <code>#define</code> for some macros
+ * As a temporary workaround, you can add an explicit \#define for some macros
  * before it is first tested, or add an equivalent -D macro definition
  * to the compiler's command line.
  *
@@ -133,7 +135,17 @@
 #define U_PF_BROWSER_NATIVE_CLIENT 4020
 /** Android is based on Linux. @internal */
 #define U_PF_ANDROID 4050
+/** Fuchsia is a POSIX-ish platform. @internal */
+#define U_PF_FUCHSIA 4100
 /* Maximum value for Linux-based platform is 4499 */
+/**
+ * Emscripten is a C++ transpiler for the Web that can target asm.js or
+ * WebAssembly. It provides some POSIX-compatible wrappers and stubs and
+ * some Linux-like functionality, but is not fully compatible with
+ * either.
+ * @internal
+ */
+#define U_PF_EMSCRIPTEN 5010
 /** z/OS is the successor to OS/390 which was the successor to MVS. @internal */
 #define U_PF_OS390 9000
 /** "IBM i" is the current name of what used to be i5/OS and earlier OS/400. @internal */
@@ -157,8 +169,10 @@
 #   define U_PLATFORM U_PF_ANDROID
     /* Android wchar_t support depends on the API level. */
 #   include <android/api-level.h>
-#elif defined(__native_client__)
+#elif defined(__pnacl__) || defined(__native_client__)
 #   define U_PLATFORM U_PF_BROWSER_NATIVE_CLIENT
+#elif defined(__Fuchsia__)
+#   define U_PLATFORM U_PF_FUCHSIA
 #elif defined(linux) || defined(__linux__) || defined(__linux)
 #   define U_PLATFORM U_PF_LINUX
 #elif defined(__APPLE__) && defined(__MACH__)
@@ -195,6 +209,8 @@
 #   define U_PLATFORM U_PF_OS390
 #elif defined(__OS400__) || defined(__TOS_OS400__)
 #   define U_PLATFORM U_PF_OS400
+#elif defined(__EMSCRIPTEN__)
+#   define U_PLATFORM U_PF_EMSCRIPTEN
 #else
 #   define U_PLATFORM U_PF_UNKNOWN
 #endif
@@ -210,6 +226,9 @@
 #   define CYGWINMSVC
 #endif
 */
+#ifdef U_IN_DOXYGEN
+#   define CYGWINMSVC
+#endif
 
 /**
  * \def U_PLATFORM_USES_ONLY_WIN32_API
@@ -243,6 +262,18 @@
 #endif
 
 /**
+ * \def U_PLATFORM_HAS_WINUWP_API
+ * Defines whether target is intended for Universal Windows Platform API
+ * Set to 1 for Windows10 Release Solution Configuration
+ * @internal
+ */
+#ifdef U_PLATFORM_HAS_WINUWP_API
+    /* Use the predefined value. */
+#else
+#   define U_PLATFORM_HAS_WINUWP_API 0
+#endif
+
+/**
  * \def U_PLATFORM_IMPLEMENTS_POSIX
  * Defines whether the platform implements (most of) the POSIX API.
  * Set to 1 for Cygwin and most other platforms.
@@ -329,42 +360,6 @@
 #   define U_HAVE_INTTYPES_H U_HAVE_STDINT_H
 #endif
 
-/**
- * \def U_IOSTREAM_SOURCE
- * Defines what support for C++ streams is available.
- *
- * If U_IOSTREAM_SOURCE is set to 199711, then &lt;iostream&gt; is available
- * (the ISO/IEC C++ FDIS was published in November 1997), and then
- * one should qualify streams using the std namespace in ICU header
- * files.
- * Starting with ICU 49, this is the only supported version.
- *
- * If U_IOSTREAM_SOURCE is set to 198506, then &lt;iostream.h&gt; is
- * available instead (in June 1985 Stroustrup published
- * "An Extensible I/O Facility for C++" at the summer USENIX conference).
- * Starting with ICU 49, this version is not supported any more.
- *
- * If U_IOSTREAM_SOURCE is 0 (or any value less than 199711),
- * then C++ streams are not available and
- * support for them will be silently suppressed in ICU.
- *
- * @internal
- */
-#ifndef U_IOSTREAM_SOURCE
-#define U_IOSTREAM_SOURCE 199711
-#endif
-
-/**
- * \def U_HAVE_STD_STRING
- * Defines whether the standard C++ (STL) &lt;string&gt; header is available.
- * @internal
- */
-#ifdef U_HAVE_STD_STRING
-    /* Use the predefined value. */
-#else
-#   define U_HAVE_STD_STRING 1
-#endif
-
 /*===========================================================================*/
 /** @{ Compiler and environment features                                     */
 /*===========================================================================*/
@@ -451,23 +446,41 @@
 #   define U_HAVE_DEBUG_LOCATION_NEW 0
 #endif
 
-/* Compatibility with non clang compilers */
-#ifndef __has_attribute
-#    define __has_attribute(x) 0
+/* Compatibility with compilers other than clang: http://clang.llvm.org/docs/LanguageExtensions.html */
+#ifdef __has_attribute
+#   define UPRV_HAS_ATTRIBUTE(x) __has_attribute(x)
+#else
+#   define UPRV_HAS_ATTRIBUTE(x) 0
 #endif
-
-#ifndef __has_feature
-#    undef __has_feature
+#ifdef __has_cpp_attribute
+#   define UPRV_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
+#else
+#   define UPRV_HAS_CPP_ATTRIBUTE(x) 0
 #endif
-
-#ifndef __has_builtin
-#    define __has_builtin(x) 0
-#endif

-#ifndef __has_feature
-#    define __has_feature(x) 0
+#ifdef __has_declspec_attribute
+#   define UPRV_HAS_DECLSPEC_ATTRIBUTE(x) __has_declspec_attribute(x)
+#else
+#   define UPRV_HAS_DECLSPEC_ATTRIBUTE(x) 0
 #endif
-#ifndef __has_extension
-#    define __has_extension(x) 0
+#ifdef __has_builtin
+#   define UPRV_HAS_BUILTIN(x) __has_builtin(x)
+#else
+#   define UPRV_HAS_BUILTIN(x) 0
+#endif
+#ifdef __has_feature
+#   define UPRV_HAS_FEATURE(x) __has_feature(x)
+#else
+#   define UPRV_HAS_FEATURE(x) 0
+#endif
+#ifdef __has_extension
+#   define UPRV_HAS_EXTENSION(x) __has_extension(x)
+#else
+#   define UPRV_HAS_EXTENSION(x) 0
+#endif
+#ifdef __has_warning
+#   define UPRV_HAS_WARNING(x) __has_warning(x)
+#else
+#   define UPRV_HAS_WARNING(x) 0
 #endif
 
 /**
@@ -486,7 +499,9 @@
  * Attribute to specify the size of the allocated buffer for malloc-like functions
  * @internal
  */
-#if (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) || __has_attribute(alloc_size)
+#if (defined(__GNUC__) &&                                            \
+        (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) || \
+        UPRV_HAS_ATTRIBUTE(alloc_size)
 #   define U_ALLOC_SIZE_ATTR(X) __attribute__ ((alloc_size(X)))
 #   define U_ALLOC_SIZE_ATTR2(X,Y) __attribute__ ((alloc_size(X,Y)))
 #else
@@ -508,29 +523,20 @@
     /* Otherwise use the predefined value. */
 #elif !defined(__cplusplus)
 #   define U_CPLUSPLUS_VERSION 0
-#elif __cplusplus >= 201402L
+#elif __cplusplus >= 201402L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
 #   define U_CPLUSPLUS_VERSION 14
-#elif __cplusplus >= 201103L
+#elif __cplusplus >= 201103L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201103L)
 #   define U_CPLUSPLUS_VERSION 11
 #else
     // C++98 or C++03
 #   define U_CPLUSPLUS_VERSION 1
 #endif
 
-/**
- * \def U_HAVE_RVALUE_REFERENCES
- * Set to 1 if the compiler supports rvalue references.
- * C++11 feature, necessary for move constructor & move assignment.
- * @internal
- */
-#ifdef U_HAVE_RVALUE_REFERENCES
-    /* Use the predefined value. */
-#elif U_CPLUSPLUS_VERSION >= 11 || __has_feature(cxx_rvalue_references) \
-        || defined(__GXX_EXPERIMENTAL_CXX0X__) \
-        || (defined(_MSC_VER) && _MSC_VER >= 1600)  /* Visual Studio 2010 */
-#   define U_HAVE_RVALUE_REFERENCES 1
-#else
-#   define U_HAVE_RVALUE_REFERENCES 0
+#if (U_PLATFORM == U_PF_AIX || U_PLATFORM == U_PF_OS390) && defined(__cplusplus) &&(U_CPLUSPLUS_VERSION < 11)
+// add in std::nullptr_t
+namespace std {
+  typedef decltype(nullptr) nullptr_t;
+};
 #endif
 
 /**
@@ -542,11 +548,34 @@
  */
 #ifdef U_NOEXCEPT
     /* Use the predefined value. */
-#elif U_CPLUSPLUS_VERSION >= 11 || __has_feature(cxx_noexcept) || __has_extension(cxx_noexcept) \
-        || (defined(_MSC_VER) && _MSC_VER >= 1900)  /* Visual Studio 2015 */
-#   define U_NOEXCEPT noexcept
 #else
-#   define U_NOEXCEPT
+#   define U_NOEXCEPT noexcept
+#endif
+
+/**
+ * \def U_FALLTHROUGH
+ * Annotate intentional fall-through between switch labels.
+ * http://clang.llvm.org/docs/AttributeReference.html#fallthrough-clang-fallthrough
+ * @internal
+ */
+#ifndef __cplusplus
+    // Not for C.
+#elif defined(U_FALLTHROUGH)
+    // Use the predefined value.
+#elif defined(__clang__)
+    // Test for compiler vs. feature separately.
+    // Other compilers might choke on the feature test.
+#    if UPRV_HAS_CPP_ATTRIBUTE(clang::fallthrough) || \
+             (UPRV_HAS_FEATURE(cxx_attributes) &&     \
+             UPRV_HAS_WARNING("-Wimplicit-fallthrough"))
+#       define U_FALLTHROUGH [[clang::fallthrough]]
+#   endif
+#elif defined(__GNUC__) && (__GNUC__ >= 7)
+#   define U_FALLTHROUGH __attribute__((fallthrough))
+#endif
+
+#ifndef U_FALLTHROUGH
+#   define U_FALLTHROUGH
 #endif
 
 /** @} */
@@ -641,7 +670,8 @@
  */
 #ifdef U_CHARSET_IS_UTF8
     /* Use the predefined value. */
-#elif U_PLATFORM == U_PF_ANDROID || U_PLATFORM_IS_DARWIN_BASED
+#elif U_PLATFORM_IS_LINUX_BASED || U_PLATFORM_IS_DARWIN_BASED || \
+        U_PLATFORM == U_PF_EMSCRIPTEN
 #   define U_CHARSET_IS_UTF8 1
 #else
 #   define U_CHARSET_IS_UTF8 0
@@ -738,7 +768,7 @@
          * narrow-character strings are in EBCDIC.
          */
 #       define U_SIZEOF_WCHAR_T 2
-#else
+#   else
         /*
          * LOCALETYPE(*CLD) or LOCALETYPE(*LOCALE) is specified.
          * Wide-character strings are in 16-bit EBCDIC,
@@ -769,11 +799,14 @@
 #else
     /*
      * Notes:
-     * Visual Studio 10 (_MSC_VER>=1600) defines char16_t but
-     * does not support u"abc" string literals.
+     * Visual Studio 2010 (_MSC_VER==1600) defines char16_t as a typedef
+     * and does not support u"abc" string literals.
+     * Visual Studio 2015 (_MSC_VER>=1900) and above adds support for
+     * both char16_t and u"abc" string literals.
      * gcc 4.4 defines the __CHAR16_TYPE__ macro to a usable type but
      * does not support u"abc" string literals.
      * C++11 and C11 require support for UTF-16 literals
+     * TODO: Fix for plain C. Doesn't work on Mac.
      */
 #   if U_CPLUSPLUS_VERSION >= 11 || (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L)
 #       define U_HAVE_CHAR16_T 1
@@ -796,7 +829,8 @@
 #elif U_HAVE_CHAR16_T \
     || (defined(__xlC__) && defined(__IBM_UTF_LITERAL) && U_SIZEOF_WCHAR_T != 2) \
     || (defined(__HP_aCC) && __HP_aCC >= 035000) \
-    || (defined(__HP_cc) && __HP_cc >= 111106)
+    || (defined(__HP_cc) && __HP_cc >= 111106) \
+    || (defined(U_IN_DOXYGEN))
 #   define U_DECLARE_UTF16(string) u ## string
 #elif U_SIZEOF_WCHAR_T == 2 \
     && (U_CHARSET_FAMILY == 0 || (U_PF_OS390 <= U_PLATFORM && U_PLATFORM <= U_PF_OS400 && defined(__UCS2__)))
@@ -823,6 +857,9 @@
 #   define U_EXPORT
 #elif defined(STARBOARD)
 #   define U_EXPORT SB_EXPORT_PLATFORM
+#elif defined(_MSC_VER) || (UPRV_HAS_DECLSPEC_ATTRIBUTE(dllexport) && \
+                            UPRV_HAS_DECLSPEC_ATTRIBUTE(dllimport))
+#   define U_EXPORT __declspec(dllexport)
 #elif defined(__GNUC__)
 #   define U_EXPORT __attribute__((visibility("default")))
 #elif (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x550) \
@@ -830,13 +867,11 @@
 #   define U_EXPORT __global
 /*#elif defined(__HP_aCC) || defined(__HP_cc)
 #   define U_EXPORT __declspec(dllexport)*/
-#elif defined(_MSC_VER)
-#   define U_EXPORT __declspec(dllexport)
 #else
 #   define U_EXPORT
 #endif
 
-/* U_CALLCONV is releated to U_EXPORT2 */
+/* U_CALLCONV is related to U_EXPORT2 */
 #ifdef U_EXPORT2
     /* Use the predefined value. */
 #elif defined(_MSC_VER)
@@ -849,7 +884,8 @@
     /* Use the predefined value. */
 #elif U_PLATFORM == U_STARBOARD
 #   define U_IMPORT SB_IMPORT_PLATFORM
-#elif defined(_MSC_VER)
+#elif defined(_MSC_VER) || (UPRV_HAS_DECLSPEC_ATTRIBUTE(dllexport) && \
+                            UPRV_HAS_DECLSPEC_ATTRIBUTE(dllimport))
     /* Windows needs to export/import data. */
 #   define U_IMPORT __declspec(dllimport)
 #else
@@ -865,6 +901,12 @@
  * This is only used for non-ICU-API functions.
  * When a function is a public ICU API,
  * you must use the U_CAPI and U_EXPORT2 qualifiers.
+ *
+ * Please note, you need to use U_CALLCONV after the *.
+ *
+ * NO : "static const char U_CALLCONV *func( . . . )"
+ * YES: "static const char* U_CALLCONV func( . . . )"
+ *
  * @stable ICU 2.0
  */
 #if U_PLATFORM == U_PF_OS390 && defined(__cplusplus)
@@ -873,6 +915,16 @@
 #    define U_CALLCONV U_EXPORT2
 #endif
 
+/**
+ * \def U_CALLCONV_FPTR
+ * Similar to U_CALLCONV, but only used on function pointers.
+ * @internal
+ */
+#if U_PLATFORM == U_PF_OS390 && defined(__cplusplus)
+#    define U_CALLCONV_FPTR U_CALLCONV
+#else
+#    define U_CALLCONV_FPTR
+#endif
 /* @} */
 
-#endif
+#endif  // _PLATFORM_H
diff --git a/src/third_party/icu/source/common/unicode/ptypes.h b/src/third_party/icu/source/common/unicode/ptypes.h
index fb88f21..ba7bfd8 100644
--- a/src/third_party/icu/source/common/unicode/ptypes.h
+++ b/src/third_party/icu/source/common/unicode/ptypes.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
@@ -85,6 +87,7 @@
 
 #else /* neither U_HAVE_STDINT_H nor U_HAVE_INTTYPES_H */
 
+/// \cond
 #if ! U_HAVE_INT8_T
 typedef signed char int8_t;
 #endif
@@ -124,6 +127,7 @@
     typedef unsigned long long uint64_t;
 #endif
 #endif
+/// \endcond
 
 #endif /* U_HAVE_STDINT_H / U_HAVE_INTTYPES_H */
 
diff --git a/src/third_party/icu/source/common/unicode/putil.h b/src/third_party/icu/source/common/unicode/putil.h
index fe786af..0747005 100644
--- a/src/third_party/icu/source/common/unicode/putil.h
+++ b/src/third_party/icu/source/common/unicode/putil.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
@@ -24,7 +26,9 @@
 #ifndef PUTIL_H
 #define PUTIL_H
 
+#if defined(STARBOARD)
 #include "starboard/configuration_constants.h"
+#endif  // defined(STARBOARD)
 #include "unicode/utypes.h"
  /**
   * \file
@@ -37,7 +41,7 @@
 
 /**
  * Platform utilities isolates the platform dependencies of the
- * libarary.  For each platform which this code is ported to, these
+ * library.  For each platform which this code is ported to, these
  * functions may have to be re-implemented.
  */
 
@@ -52,7 +56,7 @@
  * The data directory is determined as follows:
  *    If u_setDataDirectory() has been called, that is it, otherwise
  *    if the ICU_DATA environment variable is set, use that, otherwise
- *    If a data directory was specifed at ICU build time
+ *    If a data directory was specified at ICU build time
  *      <code>
  * \code
  *        #define ICU_DATA_DIR "path" 
@@ -65,7 +69,7 @@
  *   
  * @stable ICU 2.0
  */
-U_STABLE const char* U_EXPORT2 u_getDataDirectory(void);
+U_CAPI const char* U_EXPORT2 u_getDataDirectory(void);
 
 
 /** 
@@ -87,18 +91,18 @@
  * @see u_init
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2 u_setDataDirectory(const char *directory);
+U_CAPI void U_EXPORT2 u_setDataDirectory(const char *directory);
 
 #ifndef U_HIDE_INTERNAL_API
 /**
   * Return the time zone files override directory, or an empty string if
-  * no directory was specified. Certain time zone resources will be preferrentially
+  * no directory was specified. Certain time zone resources will be preferentially
   * loaded from individual files in this directory.
   *
   * @return the time zone data override directory.
   * @internal
   */ 
-U_INTERNAL const char * U_EXPORT2 u_getTimeZoneFilesDirectory(UErrorCode *status);
+U_CAPI const char * U_EXPORT2 u_getTimeZoneFilesDirectory(UErrorCode *status);
 
 /**
   * Set the time zone files override directory.
@@ -108,7 +112,7 @@
   *   will access the time zone data.
   * @internal
   */
-U_INTERNAL void U_EXPORT2 u_setTimeZoneFilesDirectory(const char *path, UErrorCode *status);
+U_CAPI void U_EXPORT2 u_setTimeZoneFilesDirectory(const char *path, UErrorCode *status);
 #endif  /* U_HIDE_INTERNAL_API */
 
 
@@ -161,7 +165,7 @@
  * @see U_CHARSET_FAMILY
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 u_charsToUChars(const char *cs, UChar *us, int32_t length);
 
 /**
@@ -183,7 +187,7 @@
  * @see U_CHARSET_FAMILY
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 u_UCharsToChars(const UChar *us, char *cs, int32_t length);
 
 #endif
diff --git a/src/third_party/icu/source/common/unicode/rbbi.h b/src/third_party/icu/source/common/unicode/rbbi.h
index d47598a..65117f6 100644
--- a/src/third_party/icu/source/common/unicode/rbbi.h
+++ b/src/third_party/icu/source/common/unicode/rbbi.h
@@ -1,6 +1,8 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ***************************************************************************
-*   Copyright (C) 1999-2014 International Business Machines Corporation   *
+*   Copyright (C) 1999-2016 International Business Machines Corporation   *
 *   and others. All rights reserved.                                      *
 ***************************************************************************
 
@@ -16,6 +18,8 @@
 
 #include "unicode/utypes.h"
 
+#if U_SHOW_CPLUSPLUS_API
+
 /**
  * \file
  * \brief C++ API: Rule Based Break Iterator
@@ -27,25 +31,17 @@
 #include "unicode/udata.h"
 #include "unicode/parseerr.h"
 #include "unicode/schriter.h"
-#include "unicode/uchriter.h"
 
-
-struct UTrie;
+struct UCPTrie;
 
 U_NAMESPACE_BEGIN
 
 /** @internal */
-struct RBBIDataHeader;
-class  RuleBasedBreakIteratorTables;
-class  BreakIterator;
-class  RBBIDataWrapper;
-class  UStack;
 class  LanguageBreakEngine;
+struct RBBIDataHeader;
+class  RBBIDataWrapper;
 class  UnhandledEngine;
-struct RBBIStateTable;
-
-
-
+class  UStack;
 
 /**
  *
@@ -56,20 +52,76 @@
  *
  * <p>See the ICU User Guide for information on Break Iterator Rules.</p>
  *
- * <p>This class is not intended to be subclassed.  (Class DictionaryBasedBreakIterator
- *    is a subclass, but that relationship is effectively internal to the ICU
- *    implementation.  The subclassing interface to RulesBasedBreakIterator is
- *    not part of the ICU API, and may not remain stable.</p>
- *
+ * <p>This class is not intended to be subclassed.</p>
  */
 class U_COMMON_API RuleBasedBreakIterator /*U_FINAL*/ : public BreakIterator {
 
-protected:
+private:
     /**
      * The UText through which this BreakIterator accesses the text
+     * @internal (private)
+     */
+    UText  fText;
+
+#ifndef U_HIDE_INTERNAL_API
+public:
+#endif /* U_HIDE_INTERNAL_API */
+    /**
+     * The rule data for this BreakIterator instance.
+     * Not for general use; Public only for testing purposes.
      * @internal
      */
-    UText  *fText;
+    RBBIDataWrapper    *fData;
+private:
+
+    /**
+      * The current  position of the iterator. Pinned, 0 < fPosition <= text.length.
+      * Never has the value UBRK_DONE (-1).
+      */
+    int32_t         fPosition;
+
+    /**
+      * TODO:
+      */
+    int32_t         fRuleStatusIndex;
+
+    /**
+     *   Cache of previously determined boundary positions.
+     */
+    class BreakCache;
+    BreakCache         *fBreakCache;
+
+    /**
+     *  Cache of boundary positions within a region of text that has been
+     *  sub-divided by dictionary based breaking.
+     */
+    class DictionaryCache;
+    DictionaryCache *fDictionaryCache;
+
+    /**
+     *
+     * If present, UStack of LanguageBreakEngine objects that might handle
+     * dictionary characters. Searched from top to bottom to find an object to
+     * handle a given character.
+     * @internal (private)
+     */
+    UStack              *fLanguageBreakEngines;
+
+    /**
+     *
+     * If present, the special LanguageBreakEngine used for handling
+     * characters that are in the dictionary set, but not handled by any
+     * LanguageBreakEngine.
+     * @internal (private)
+     */
+    UnhandledEngine     *fUnhandledBreakEngine;
+
+    /**
+     * Counter for the number of characters encountered with the "dictionary"
+     *   flag set.
+     * @internal (private)
+     */
+    uint32_t            fDictionaryCharCount;
 
     /**
      *   A character iterator that refers to the same text as the UText, above.
@@ -83,106 +135,22 @@
      *    a characterIterator that wraps that data.  Needed only for the
      *    implementation of getText(), a backwards compatibility issue.
      */
-    StringCharacterIterator *fSCharIter;
+    StringCharacterIterator fSCharIter;
 
     /**
-     *  When the input text is provided by a UText, this
-     *    dummy CharacterIterator over an empty string will
-     *    be returned from getText()
-     */
-    UCharCharacterIterator *fDCharIter;
+      * True when iteration has run off the end, and iterator functions should return UBRK_DONE.
+      */
+    UBool           fDone;
 
     /**
-     * The rule data for this BreakIterator instance
-     * @internal
+     *  Array of look-ahead tentative results.
      */
-    RBBIDataWrapper    *fData;
+    int32_t *fLookAheadMatches;
 
-    /** Index of the Rule {tag} values for the most recent match.
-     *  @internal
-    */
-    int32_t             fLastRuleStatusIndex;
-
-    /**
-     * Rule tag value valid flag.
-     * Some iterator operations don't intrinsically set the correct tag value.
-     * This flag lets us lazily compute the value if we are ever asked for it.
-     * @internal
-     */
-    UBool               fLastStatusIndexValid;
-
-    /**
-     * Counter for the number of characters encountered with the "dictionary"
-     *   flag set.
-     * @internal
-     */
-    uint32_t            fDictionaryCharCount;
-
-    /**
-     * When a range of characters is divided up using the dictionary, the break
-     * positions that are discovered are stored here, preventing us from having
-     * to use either the dictionary or the state table again until the iterator
-     * leaves this range of text. Has the most impact for line breaking.
-     * @internal
-     */
-    int32_t*            fCachedBreakPositions;
-
-    /**
-     * The number of elements in fCachedBreakPositions
-     * @internal
-     */
-    int32_t             fNumCachedBreakPositions;
-
-    /**
-     * if fCachedBreakPositions is not null, this indicates which item in the
-     * cache the current iteration position refers to
-     * @internal
-     */
-    int32_t             fPositionInCache;
-    
-    /**
-     *
-     * If present, UStack of LanguageBreakEngine objects that might handle
-     * dictionary characters. Searched from top to bottom to find an object to
-     * handle a given character.
-     * @internal
-     */
-    UStack              *fLanguageBreakEngines;
-    
-    /**
-     *
-     * If present, the special LanguageBreakEngine used for handling
-     * characters that are in the dictionary set, but not handled by any
-     * LangugageBreakEngine.
-     * @internal
-     */
-    UnhandledEngine     *fUnhandledBreakEngine;
-    
-    /**
-     *
-     * The type of the break iterator, or -1 if it has not been set.
-     * @internal
-     */
-    int32_t             fBreakType;
-    
-protected:
     //=======================================================================
     // constructors
     //=======================================================================
 
-#ifndef U_HIDE_INTERNAL_API
-    /**
-     * Constant to be used in the constructor
-     * RuleBasedBreakIterator(RBBIDataHeader*, EDontAdopt, UErrorCode &);
-     * which does not adopt the memory indicated by the RBBIDataHeader*
-     * parameter.
-     *
-     * @internal
-     */
-    enum EDontAdopt {
-        kDontAdopt
-    };
-
     /**
      * Constructor from a flattened set of RBBI data in malloced memory.
      *             RulesBasedBreakIterators built from a custom set of rules
@@ -191,28 +159,15 @@
      *
      *             The break iterator adopts the memory, and will
      *             free it when done.
-     * @internal
+     * @internal (private)
      */
     RuleBasedBreakIterator(RBBIDataHeader* data, UErrorCode &status);
 
-    /**
-     * Constructor from a flattened set of RBBI data in memory which need not
-     *             be malloced (e.g. it may be a memory-mapped file, etc.).
-     *
-     *             This version does not adopt the memory, and does not
-     *             free it when done.
-     * @internal
-     */
-    RuleBasedBreakIterator(const RBBIDataHeader* data, enum EDontAdopt dontAdopt, UErrorCode &status);
-#endif  /* U_HIDE_INTERNAL_API */
-
-
+    /** @internal */
     friend class RBBIRuleBuilder;
     /** @internal */
     friend class BreakIterator;
 
-
-
 public:
 
     /** Default constructor.  Creates an empty shell of an iterator, with no
@@ -242,17 +197,17 @@
                              UErrorCode            &status);
 
     /**
-     * Contruct a RuleBasedBreakIterator from a set of precompiled binary rules.
+     * Construct a RuleBasedBreakIterator from a set of precompiled binary rules.
      * Binary rules are obtained from RulesBasedBreakIterator::getBinaryRules().
      * Construction of a break iterator in this way is substantially faster than
-     * constuction from source rules.
+     * construction from source rules.
      *
      * Ownership of the storage containing the compiled rules remains with the
-     * caller of this function.  The compiled rules must not be  modified or 
+     * caller of this function.  The compiled rules must not be  modified or
      * deleted during the life of the break iterator.
      *
      * The compiled rules are not compatible across different major versions of ICU.
-     * The compiled rules are comaptible only between machines with the same
+     * The compiled rules are compatible only between machines with the same
      * byte ordering (little or big endian) and the same base character set family
      * (ASCII or EBCDIC).
      *
@@ -298,35 +253,35 @@
     RuleBasedBreakIterator& operator=(const RuleBasedBreakIterator& that);
 
     /**
-     * Equality operator.  Returns TRUE if both BreakIterators are of the
+     * Equality operator.  Returns true if both BreakIterators are of the
      * same class, have the same behavior, and iterate over the same text.
      * @param that The BreakIterator to be compared for equality
-     * @return TRUE if both BreakIterators are of the
+     * @return true if both BreakIterators are of the
      * same class, have the same behavior, and iterate over the same text.
      *  @stable ICU 2.0
      */
     virtual UBool operator==(const BreakIterator& that) const;
 
     /**
-     * Not-equal operator.  If operator== returns TRUE, this returns FALSE,
+     * Not-equal operator.  If operator== returns true, this returns false,
      * and vice versa.
      * @param that The BreakIterator to be compared for inequality
-     * @return TRUE if both BreakIterators are not same.
+     * @return true if both BreakIterators are not same.
      *  @stable ICU 2.0
      */
-    UBool operator!=(const BreakIterator& that) const;
+    inline UBool operator!=(const BreakIterator& that) const;
 
     /**
      * Returns a newly-constructed RuleBasedBreakIterator with the same
      * behavior, and iterating over the same text, as this one.
      * Differs from the copy constructor in that it is polymorphic, and
      * will correctly clone (copy) a derived class.
-     * clone() is thread safe.  Multiple threads may simultaeneously
+     * clone() is thread safe.  Multiple threads may simultaneously
      * clone the same source break iterator.
      * @return a newly-constructed RuleBasedBreakIterator
      * @stable ICU 2.0
      */
-    virtual BreakIterator* clone() const;
+    virtual RuleBasedBreakIterator* clone() const;
 
     /**
      * Compute a hash code for this BreakIterator
@@ -402,6 +357,11 @@
     /**
      * Set the iterator to analyze a new piece of text.  This function resets
      * the current iteration position to the beginning of the text.
+     *
+     * The BreakIterator will retain a reference to the supplied string.
+     * The caller must not modify or delete the text while the BreakIterator
+     * retains the reference.
+     *
      * @param newText The text to analyze.
      *  @stable ICU 2.0
      */
@@ -481,7 +441,7 @@
     virtual int32_t preceding(int32_t offset);
 
     /**
-     * Returns true if the specfied position is a boundary position.  As a side
+     * Returns true if the specified position is a boundary position.  As a side
      * effect, leaves the iterator pointing to the first boundary position at
      * or after "offset".
      * @param offset the offset to check.
@@ -491,7 +451,10 @@
     virtual UBool isBoundary(int32_t offset);
 
     /**
-     * Returns the current iteration position.
+     * Returns the current iteration position. Note that UBRK_DONE is never
+     * returned from this function; if iteration has run to the end of a
+     * string, current() will return the length of the string while
+     * next() will return UBRK_DONE).
      * @return The current iteration position.
      * @stable ICU 2.0
      */
@@ -499,8 +462,8 @@
 
 
     /**
-     * Return the status tag from the break rule that determined the most recently
-     * returned break position.  For break rules that do not specify a
+     * Return the status tag from the break rule that determined the boundary at
+     * the current iteration position.  For break rules that do not specify a
      * status, a default value of 0 is returned.  If more than one break rule
      * would cause a boundary to be located at some position in the text,
      * the numerically largest of the applicable status values is returned.
@@ -517,15 +480,14 @@
      * position from <code>next()</code>, <code>previous()</code>, or
      * any other break iterator functions that returns a boundary position.
      * <p>
+     * Note that <code>getRuleStatus()</code> returns the value corresponding to
+     * <code>current()</code> index even after <code>next()</code> has returned DONE.
+     * <p>
      * When creating custom break rules, one is free to define whatever
      * status values may be convenient for the application.
      * <p>
-     * Note: this function is not thread safe.  It should not have been
-     *       declared const, and the const remains only for compatibility
-     *       reasons.  (The function is logically const, but not bit-wise const).
-     * <p>
-     * @return the status from the break rule that determined the most recently
-     * returned break position.
+     * @return the status from the break rule that determined the boundary
+     * at the current iteration position.
      *
      * @see UWordBreak
      * @stable ICU 2.2
@@ -533,8 +495,8 @@
     virtual int32_t getRuleStatus() const;
 
    /**
-    * Get the status (tag) values from the break rule(s) that determined the most
-    * recently returned break position.
+    * Get the status (tag) values from the break rule(s) that determined the boundary
+    * at the current iteration position.
     * <p>
     * The returned status value(s) are stored into an array provided by the caller.
     * The values are stored in sorted (ascending) order.
@@ -545,10 +507,10 @@
     * @param fillInVec an array to be filled in with the status values.
     * @param capacity  the length of the supplied vector.  A length of zero causes
     *                  the function to return the number of status values, in the
-    *                  normal way, without attemtping to store any values.
+    *                  normal way, without attempting to store any values.
     * @param status    receives error codes.
-    * @return          The number of rule status values from rules that determined
-    *                  the most recent boundary returned by the break iterator.
+    * @return          The number of rule status values from the rules that determined
+    *                  the boundary at the current iteration position.
     *                  In the event of a U_BUFFER_OVERFLOW_ERROR, the return value
     *                  is the total number of status values that were available,
     *                  not the reduced number that were actually returned.
@@ -583,12 +545,13 @@
      */
     static UClassID U_EXPORT2 getStaticClassID(void);
 
+#ifndef U_FORCE_HIDE_DEPRECATED_API
     /**
      * Deprecated functionality. Use clone() instead.
      *
      * Create a clone (copy) of this break iterator in memory provided
      *  by the caller.  The idea is to increase performance by avoiding
-     *  a storage allocation.  Use of this functoin is NOT RECOMMENDED.
+     *  a storage allocation.  Use of this function is NOT RECOMMENDED.
      *  Performance gains are minimal, and correct buffer management is
      *  tricky.  Use clone() instead.
      *
@@ -601,7 +564,7 @@
      *                     storage for the cloned object.
      *
      * @param status       Error status.  U_SAFECLONE_ALLOCATED_WARNING will be
-     *                     returned if the the provided buffer was too small, and
+     *                     returned if the provided buffer was too small, and
      *                     the clone was therefore put on the heap.
      *
      * @return  Pointer to the clone object.  This may differ from the stackBuffer
@@ -609,10 +572,10 @@
      *          or if the stackBuffer was too small to hold the clone.
      * @deprecated ICU 52. Use clone() instead.
      */
-    virtual BreakIterator *  createBufferClone(void *stackBuffer,
-                                               int32_t &BufferSize,
-                                               UErrorCode &status);
-
+    virtual RuleBasedBreakIterator *createBufferClone(void *stackBuffer,
+                                                      int32_t &BufferSize,
+                                                      UErrorCode &status);
+#endif  // U_FORCE_HIDE_DEPRECATED_API
 
     /**
      * Return the binary form of compiled break rules,
@@ -624,7 +587,7 @@
      * The binary data can only be used with the same version of ICU
      *  and on the same platform type (processor endian-ness)
      *
-     * @param length Returns the length of the binary data.  (Out paramter.)
+     * @param length Returns the length of the binary data.  (Out parameter.)
      *
      * @return   A pointer to the binary (compiled) rule data.  The storage
      *           belongs to the RulesBasedBreakIterator object, not the
@@ -661,108 +624,93 @@
     virtual RuleBasedBreakIterator &refreshInputText(UText *input, UErrorCode &status);
 
 
-protected:
+private:
     //=======================================================================
     // implementation
     //=======================================================================
     /**
      * Dumps caches and performs other actions associated with a complete change
      * in text or iteration position.
-     * @internal
+     * @internal (private)
      */
-    virtual void reset(void);
+    void reset(void);
 
-#if 0
-    /**
-      * Return true if the category lookup for this char
-      * indicates that it is in the set of dictionary lookup chars.
-      * This function is intended for use by dictionary based break iterators.
-      * @return true if the category lookup for this char
-      * indicates that it is in the set of dictionary lookup chars.
-      * @internal
-      */
-    virtual UBool isDictionaryChar(UChar32);
-
-    /**
-      * Get the type of the break iterator.
-      * @internal
-      */
-    virtual int32_t getBreakType() const;
-#endif
-
-    /**
-      * Set the type of the break iterator.
-      * @internal
-      */
-    virtual void setBreakType(int32_t type);
-
-#ifndef U_HIDE_INTERNAL_API
     /**
       * Common initialization function, used by constructors and bufferClone.
-      * @internal
+      * @internal (private)
       */
-    void init();
-#endif  /* U_HIDE_INTERNAL_API */
-
-private:
+    void init(UErrorCode &status);
 
     /**
-     * This method backs the iterator back up to a "safe position" in the text.
-     * This is a position that we know, without any context, must be a break position.
-     * The various calling methods then iterate forward from this safe position to
-     * the appropriate position to return.  (For more information, see the description
-     * of buildBackwardsStateTable() in RuleBasedBreakIterator.Builder.)
-     * @param statetable state table used of moving backwards
-     * @internal
+     * Iterate backwards from an arbitrary position in the input text using the
+     * synthesized Safe Reverse rules.
+     * This locates a "Safe Position" from which the forward break rules
+     * will operate correctly. A Safe Position is not necessarily a boundary itself.
+     *
+     * @param fromPosition the position in the input text to begin the iteration.
+     * @internal (private)
      */
-    int32_t handlePrevious(const RBBIStateTable *statetable);
+    int32_t handleSafePrevious(int32_t fromPosition);
 
     /**
-     * This method is the actual implementation of the next() method.  All iteration
-     * vectors through here.  This method initializes the state machine to state 1
-     * and advances through the text character by character until we reach the end
-     * of the text or the state machine transitions to state 0.  We update our return
-     * value every time the state machine passes through a possible end state.
-     * @param statetable state table used of moving forwards
-     * @internal
+     * Find a rule-based boundary by running the state machine.
+     * Input
+     *    fPosition, the position in the text to begin from.
+     * Output
+     *    fPosition:           the boundary following the starting position.
+     *    fDictionaryCharCount the number of dictionary characters encountered.
+     *                         If > 0, the segment will be further subdivided
+     *    fRuleStatusIndex     Info from the state table indicating which rules caused the boundary.
+     *
+     * @internal (private)
      */
-    int32_t handleNext(const RBBIStateTable *statetable);
+    int32_t handleNext();
 
-protected:
-
-#ifndef U_HIDE_INTERNAL_API
-    /**
-     * This is the function that actually implements dictionary-based
-     * breaking.  Covering at least the range from startPos to endPos,
-     * it checks for dictionary characters, and if it finds them determines
-     * the appropriate object to deal with them. It may cache found breaks in
-     * fCachedBreakPositions as it goes. It may well also look at text outside
-     * the range startPos to endPos.
-     * If going forward, endPos is the normal Unicode break result, and
-     * if goind in reverse, startPos is the normal Unicode break result
-     * @param startPos  The start position of a range of text
-     * @param endPos    The end position of a range of text
-     * @param reverse   The call is for the reverse direction
-     * @internal
+    /*
+     * Templatized version of handleNext() and handleSafePrevious().
+     *
+     * There will be exactly four instantiations, two each for 8 and 16 bit tables,
+     * two each for 8 and 16 bit trie.
+     * Having separate instantiations for the table types keeps conditional tests of
+     * the table type out of the inner loops, at the expense of replicated code.
+     *
+     * The template parameter for the Trie access function is a value, not a type.
+     * Doing it this way, the compiler will inline the Trie function in the
+     * expanded functions. (Both the 8 and 16 bit access functions have the same type
+     * signature)
      */
-    int32_t checkDictionary(int32_t startPos, int32_t endPos, UBool reverse);
-#endif  /* U_HIDE_INTERNAL_API */
 
-private:
+    typedef uint16_t (*PTrieFunc)(const UCPTrie *, UChar32);
+
+    template<typename RowType, PTrieFunc trieFunc>
+    int32_t handleSafePrevious(int32_t fromPosition);
+
+    template<typename RowType, PTrieFunc trieFunc>
+    int32_t handleNext();
+
 
     /**
      * This function returns the appropriate LanguageBreakEngine for a
      * given character c.
      * @param c         A character in the dictionary set
-     * @internal
+     * @internal (private)
      */
     const LanguageBreakEngine *getLanguageBreakEngine(UChar32 c);
 
+  public:
+#ifndef U_HIDE_INTERNAL_API
     /**
-     *  @internal
+     *   Debugging function only.
+     *   @internal
      */
-    void makeRuleStatusValid();
+     void dumpCache();
 
+    /**
+     * Debugging function only.
+     * @internal
+     */
+    void dumpTables();
+#endif  /* U_HIDE_INTERNAL_API */
 };
 
 //------------------------------------------------------------------------------
@@ -779,4 +727,6 @@
 
 #endif /* #if !UCONFIG_NO_BREAK_ITERATION */
 
+#endif /* U_SHOW_CPLUSPLUS_API */
+
 #endif
diff --git a/src/third_party/icu/source/common/unicode/rep.h b/src/third_party/icu/source/common/unicode/rep.h
index 4c7eae1..6dd4530 100644
--- a/src/third_party/icu/source/common/unicode/rep.h
+++ b/src/third_party/icu/source/common/unicode/rep.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **************************************************************************
 * Copyright (C) 1999-2012, International Business Machines Corporation and
@@ -14,6 +16,10 @@
 #ifndef REP_H
 #define REP_H
 
+#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
 #include "unicode/uobject.h"
 
 /**
@@ -91,7 +97,7 @@
      * @return 16-bit code unit of text at given offset
      * @stable ICU 1.8
      */
-    inline UChar charAt(int32_t offset) const;
+    inline char16_t charAt(int32_t offset) const;
 
     /**
      * Returns the 32-bit code point at the given 16-bit offset into
@@ -187,9 +193,6 @@
      * Clones can be used concurrently in multiple threads.
      * If a subclass does not implement clone(), or if an error occurs,
      * then NULL is returned.
-     * The clone functions in all subclasses return a pointer to a Replaceable
-     * because some compilers do not support covariant (same-as-this)
-     * return types; cast to the appropriate subclass if necessary.
      * The caller must delete the clone.
      *
      * @return a clone of this object
@@ -228,7 +231,7 @@
      * Virtual version of charAt().
      * @stable ICU 2.4
      */
-    virtual UChar getCharAt(int32_t offset) const = 0;
+    virtual char16_t getCharAt(int32_t offset) const = 0;
 
     /**
      * Virtual version of char32At().
@@ -244,7 +247,7 @@
     return getLength();
 }
 
-inline UChar
+inline char16_t
 Replaceable::charAt(int32_t offset) const {
     return getCharAt(offset);
 }
@@ -258,4 +261,6 @@
 
 U_NAMESPACE_END
 
+#endif /* U_SHOW_CPLUSPLUS_API */
+
 #endif
diff --git a/src/third_party/icu/source/common/unicode/resbund.h b/src/third_party/icu/source/common/unicode/resbund.h
index 6e3c1b2..37738e2 100644
--- a/src/third_party/icu/source/common/unicode/resbund.h
+++ b/src/third_party/icu/source/common/unicode/resbund.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
@@ -47,6 +49,9 @@
 #define RESBUND_H
 
 #include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
 #include "unicode/uobject.h"
 #include "unicode/ures.h"
 #include "unicode/unistr.h"
@@ -130,7 +135,7 @@
     ResourceBundle(UErrorCode &err);
 
     /**
-     * Standard constructor, onstructs a resource bundle for the locale-specific
+     * Standard constructor, constructs a resource bundle for the locale-specific
      * bundle in the specified package.
      *
      * @param packageName   The packageName and locale together point to an ICU udata object, 
@@ -214,7 +219,7 @@
      *                could be <TT>U_MISSING_RESOURCE_ERROR</TT> if the key is not found
      *                could be a warning
      *                e.g.: <TT>U_USING_FALLBACK_WARNING</TT>,<TT>U_USING_DEFAULT_WARNING </TT>
-     * @return a pointer to a zero-terminated UChar array which lives in a memory mapped/DLL file.
+     * @return a pointer to a zero-terminated char16_t array which lives in a memory mapped/DLL file.
      * @stable ICU 2.0
      */
     UnicodeString
@@ -281,7 +286,7 @@
     /**
      * Checks whether the resource has another element to iterate over.
      *
-     * @return TRUE if there are more elements, FALSE if there is no more elements
+     * @return true if there are more elements, false if there is no more elements
      * @stable ICU 2.0
      */
     UBool
@@ -487,4 +492,7 @@
 };
 
 U_NAMESPACE_END
+
+#endif /* U_SHOW_CPLUSPLUS_API */
+
 #endif
diff --git a/src/third_party/icu/source/common/unicode/schriter.h b/src/third_party/icu/source/common/unicode/schriter.h
index d0b5e22..1ca5b70 100644
--- a/src/third_party/icu/source/common/unicode/schriter.h
+++ b/src/third_party/icu/source/common/unicode/schriter.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
@@ -19,6 +21,9 @@
 #define SCHRITER_H
 
 #include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
 #include "unicode/chariter.h"
 #include "unicode/uchriter.h"
 
@@ -67,7 +72,7 @@
    * Create an iterator over the UnicodeString referred to by "textStr".
    * The UnicodeString object is copied.
    * The iteration range begins with the code unit specified by
-   * "textBegin" and ends with the code unit BEFORE the code unit specfied
+   * "textBegin" and ends with the code unit BEFORE the code unit specified
    * by "textEnd".  The starting position is specified by "textPos".  If
    * "textBegin" and "textEnd" don't form a valid range on "text" (i.e.,
    * textBegin >= textEnd or either is negative or greater than text.size()),
@@ -128,7 +133,7 @@
    * @return the newly cloned object.
    * @stable ICU 2.0
    */
-  virtual CharacterIterator* clone(void) const;
+  virtual StringCharacterIterator* clone() const;
 
   /**
    * Sets the iterator to iterate over the provided string.
@@ -173,7 +178,7 @@
    * @param newTextLength The length of the String
    * @stable ICU 2.0
    */
-  void setText(const UChar* newText, int32_t newTextLength);
+  void setText(const char16_t* newText, int32_t newTextLength);
 
   /**
    * Copy of the iterated string object.
@@ -184,4 +189,7 @@
 };
 
 U_NAMESPACE_END
+
+#endif /* U_SHOW_CPLUSPLUS_API */
+
 #endif
diff --git a/src/third_party/icu/source/common/unicode/simpleformatter.h b/src/third_party/icu/source/common/unicode/simpleformatter.h
new file mode 100644
index 0000000..6d9c04a
--- /dev/null
+++ b/src/third_party/icu/source/common/unicode/simpleformatter.h
@@ -0,0 +1,341 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+/*
+******************************************************************************
+* Copyright (C) 2014-2016, International Business Machines
+* Corporation and others.  All Rights Reserved.
+******************************************************************************
+* simpleformatter.h
+*/
+
+#ifndef __SIMPLEFORMATTER_H__
+#define __SIMPLEFORMATTER_H__
+
+/**
+ * \file
+ * \brief C++ API: Simple formatter, minimal subset of MessageFormat.
+ */
+
+#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
+#include "unicode/unistr.h"
+
+U_NAMESPACE_BEGIN
+
+// Forward declaration:
+namespace number {
+namespace impl {
+class SimpleModifier;
+}
+}
+
+/**
+ * Formats simple patterns like "{1} was born in {0}".
+ * Minimal subset of MessageFormat; fast, simple, minimal dependencies.
+ * Supports only numbered arguments with no type nor style parameters,
+ * and formats only string values.
+ * Quoting via ASCII apostrophe compatible with ICU MessageFormat default behavior.
+ *
+ * Factory methods set error codes for syntax errors
+ * and for too few or too many arguments/placeholders.
+ *
+ * SimpleFormatter objects are thread-safe except for assignment and applying new patterns.
+ *
+ * Example:
+ * <pre>
+ * UErrorCode errorCode = U_ZERO_ERROR;
+ * SimpleFormatter fmt("{1} '{born}' in {0}", errorCode);
+ * UnicodeString result;
+ *
+ * // Output: "paul {born} in england"
+ * fmt.format("england", "paul", result, errorCode);
+ * </pre>
+ *
+ * This class is not intended for public subclassing.
+ *
+ * @see MessageFormat
+ * @see UMessagePatternApostropheMode
+ * @stable ICU 57
+ */
+class U_COMMON_API SimpleFormatter U_FINAL : public UMemory {
+public:
+    /**
+     * Default constructor.
+     * @stable ICU 57
+     */
+    SimpleFormatter() : compiledPattern((char16_t)0) {}
+
+    /**
+     * Constructs a formatter from the pattern string.
+     *
+     * @param pattern The pattern string.
+     * @param errorCode ICU error code in/out parameter.
+     *                  Must fulfill U_SUCCESS before the function call.
+     *                  Set to U_ILLEGAL_ARGUMENT_ERROR for bad argument syntax.
+     * @stable ICU 57
+     */
+    SimpleFormatter(const UnicodeString& pattern, UErrorCode &errorCode) {
+        applyPattern(pattern, errorCode);
+    }
+
+    /**
+     * Constructs a formatter from the pattern string.
+     * The number of arguments checked against the given limits is the
+     * highest argument number plus one, not the number of occurrences of arguments.
+     *
+     * @param pattern The pattern string.
+     * @param min The pattern must have at least this many arguments.
+     * @param max The pattern must have at most this many arguments.
+     * @param errorCode ICU error code in/out parameter.
+     *                  Must fulfill U_SUCCESS before the function call.
+     *                  Set to U_ILLEGAL_ARGUMENT_ERROR for bad argument syntax and
+     *                  too few or too many arguments.
+     * @stable ICU 57
+     */
+    SimpleFormatter(const UnicodeString& pattern, int32_t min, int32_t max,
+                    UErrorCode &errorCode) {
+        applyPatternMinMaxArguments(pattern, min, max, errorCode);
+    }
+
+    /**
+     * Copy constructor.
+     * @stable ICU 57
+     */
+    SimpleFormatter(const SimpleFormatter& other)
+            : compiledPattern(other.compiledPattern) {}
+
+    /**
+     * Assignment operator.
+     * @stable ICU 57
+     */
+    SimpleFormatter &operator=(const SimpleFormatter& other);
+
+    /**
+     * Destructor.
+     * @stable ICU 57
+     */
+    ~SimpleFormatter();
+
+    /**
+     * Changes this object according to the new pattern.
+     *
+     * @param pattern The pattern string.
+     * @param errorCode ICU error code in/out parameter.
+     *                  Must fulfill U_SUCCESS before the function call.
+     *                  Set to U_ILLEGAL_ARGUMENT_ERROR for bad argument syntax.
+     * @return true if U_SUCCESS(errorCode).
+     * @stable ICU 57
+     */
+    UBool applyPattern(const UnicodeString &pattern, UErrorCode &errorCode) {
+        return applyPatternMinMaxArguments(pattern, 0, INT32_MAX, errorCode);
+    }
+
+    /**
+     * Changes this object according to the new pattern.
+     * The number of arguments checked against the given limits is the
+     * highest argument number plus one, not the number of occurrences of arguments.
+     *
+     * @param pattern The pattern string.
+     * @param min The pattern must have at least this many arguments.
+     * @param max The pattern must have at most this many arguments.
+     * @param errorCode ICU error code in/out parameter.
+     *                  Must fulfill U_SUCCESS before the function call.
+     *                  Set to U_ILLEGAL_ARGUMENT_ERROR for bad argument syntax and
+     *                  too few or too many arguments.
+     * @return true if U_SUCCESS(errorCode).
+     * @stable ICU 57
+     */
+    UBool applyPatternMinMaxArguments(const UnicodeString &pattern,
+                                      int32_t min, int32_t max, UErrorCode &errorCode);
+
+    /**
+     * @return The max argument number + 1.
+     * @stable ICU 57
+     */
+    int32_t getArgumentLimit() const {
+        return getArgumentLimit(compiledPattern.getBuffer(), compiledPattern.length());
+    }
+
+    /**
+     * Formats the given value, appending to the appendTo builder.
+     * The argument value must not be the same object as appendTo.
+     * getArgumentLimit() must be at most 1.
+     *
+     * @param value0 Value for argument {0}.
+     * @param appendTo Gets the formatted pattern and value appended.
+     * @param errorCode ICU error code in/out parameter.
+     *                  Must fulfill U_SUCCESS before the function call.
+     * @return appendTo
+     * @stable ICU 57
+     */
+    UnicodeString &format(
+            const UnicodeString &value0,
+            UnicodeString &appendTo, UErrorCode &errorCode) const;
+
+    /**
+     * Formats the given values, appending to the appendTo builder.
+     * An argument value must not be the same object as appendTo.
+     * getArgumentLimit() must be at most 2.
+     *
+     * @param value0 Value for argument {0}.
+     * @param value1 Value for argument {1}.
+     * @param appendTo Gets the formatted pattern and values appended.
+     * @param errorCode ICU error code in/out parameter.
+     *                  Must fulfill U_SUCCESS before the function call.
+     * @return appendTo
+     * @stable ICU 57
+     */
+    UnicodeString &format(
+            const UnicodeString &value0,
+            const UnicodeString &value1,
+            UnicodeString &appendTo, UErrorCode &errorCode) const;
+
+    /**
+     * Formats the given values, appending to the appendTo builder.
+     * An argument value must not be the same object as appendTo.
+     * getArgumentLimit() must be at most 3.
+     *
+     * @param value0 Value for argument {0}.
+     * @param value1 Value for argument {1}.
+     * @param value2 Value for argument {2}.
+     * @param appendTo Gets the formatted pattern and values appended.
+     * @param errorCode ICU error code in/out parameter.
+     *                  Must fulfill U_SUCCESS before the function call.
+     * @return appendTo
+     * @stable ICU 57
+     */
+    UnicodeString &format(
+            const UnicodeString &value0,
+            const UnicodeString &value1,
+            const UnicodeString &value2,
+            UnicodeString &appendTo, UErrorCode &errorCode) const;
+
+    /**
+     * Formats the given values, appending to the appendTo string.
+     *
+     * @param values The argument values.
+     *               An argument value must not be the same object as appendTo.
+     *               Can be NULL if valuesLength==getArgumentLimit()==0.
+     * @param valuesLength The length of the values array.
+     *                     Must be at least getArgumentLimit().
+     * @param appendTo Gets the formatted pattern and values appended.
+     * @param offsets offsets[i] receives the offset of where
+     *                values[i] replaced pattern argument {i}.
+     *                Can be shorter or longer than values. Can be NULL if offsetsLength==0.
+     *                If there is no {i} in the pattern, then offsets[i] is set to -1.
+     * @param offsetsLength The length of the offsets array.
+     * @param errorCode ICU error code in/out parameter.
+     *                  Must fulfill U_SUCCESS before the function call.
+     * @return appendTo
+     * @stable ICU 57
+     */
+    UnicodeString &formatAndAppend(
+            const UnicodeString *const *values, int32_t valuesLength,
+            UnicodeString &appendTo,
+            int32_t *offsets, int32_t offsetsLength, UErrorCode &errorCode) const;
+
+    /**
+     * Formats the given values, replacing the contents of the result string.
+     * May optimize by actually appending to the result if it is the same object
+     * as the value corresponding to the initial argument in the pattern.
+     *
+     * @param values The argument values.
+     *               An argument value may be the same object as result.
+     *               Can be NULL if valuesLength==getArgumentLimit()==0.
+     * @param valuesLength The length of the values array.
+     *                     Must be at least getArgumentLimit().
+     * @param result Gets its contents replaced by the formatted pattern and values.
+     * @param offsets offsets[i] receives the offset of where
+     *                values[i] replaced pattern argument {i}.
+     *                Can be shorter or longer than values. Can be NULL if offsetsLength==0.
+     *                If there is no {i} in the pattern, then offsets[i] is set to -1.
+     * @param offsetsLength The length of the offsets array.
+     * @param errorCode ICU error code in/out parameter.
+     *                  Must fulfill U_SUCCESS before the function call.
+     * @return result
+     * @stable ICU 57
+     */
+    UnicodeString &formatAndReplace(
+            const UnicodeString *const *values, int32_t valuesLength,
+            UnicodeString &result,
+            int32_t *offsets, int32_t offsetsLength, UErrorCode &errorCode) const;
+
+    /**
+     * Returns the pattern text with none of the arguments.
+     * Like formatting with all-empty string values.
+     * @stable ICU 57
+     */
+    UnicodeString getTextWithNoArguments() const {
+        return getTextWithNoArguments(
+            compiledPattern.getBuffer(),
+            compiledPattern.length(),
+            nullptr,
+            0);
+    }
+
+#ifndef U_HIDE_INTERNAL_API
+    /**
+     * Returns the pattern text with none of the arguments.
+     * Like formatting with all-empty string values.
+     *
+     * TODO(ICU-20406): Replace this with an Iterator interface.
+     *
+     * @param offsets offsets[i] receives the offset of where {i} was located
+     *                before it was replaced by an empty string.
+     *                For example, "a{0}b{1}" produces offset 1 for i=0 and 2 for i=1.
+     *                Can be nullptr if offsetsLength==0.
+     *                If there is no {i} in the pattern, then offsets[i] is set to -1.
+     * @param offsetsLength The length of the offsets array.
+     *
+     * @internal
+     */
+    UnicodeString getTextWithNoArguments(int32_t *offsets, int32_t offsetsLength) const {
+        return getTextWithNoArguments(
+            compiledPattern.getBuffer(),
+            compiledPattern.length(),
+            offsets,
+            offsetsLength);
+    }
+#endif // U_HIDE_INTERNAL_API
+
+private:
+    /**
+     * Binary representation of the compiled pattern.
+     * Index 0: One more than the highest argument number.
+     * Followed by zero or more arguments or literal-text segments.
+     *
+     * An argument is stored as its number, less than ARG_NUM_LIMIT.
+     * A literal-text segment is stored as its length (at least 1) offset by ARG_NUM_LIMIT,
+     * followed by that many chars.
+     */
+    UnicodeString compiledPattern;
+
+    static inline int32_t getArgumentLimit(const char16_t *compiledPattern,
+                                              int32_t compiledPatternLength) {
+        return compiledPatternLength == 0 ? 0 : compiledPattern[0];
+    }
+
+    static UnicodeString getTextWithNoArguments(
+        const char16_t *compiledPattern,
+        int32_t compiledPatternLength,
+        int32_t *offsets,
+        int32_t offsetsLength);
+
+    static UnicodeString &format(
+            const char16_t *compiledPattern, int32_t compiledPatternLength,
+            const UnicodeString *const *values,
+            UnicodeString &result, const UnicodeString *resultCopy, UBool forbidResultAsValue,
+            int32_t *offsets, int32_t offsetsLength,
+            UErrorCode &errorCode);
+
+    // Give access to internals to SimpleModifier for number formatting
+    friend class number::impl::SimpleModifier;
+};
+
+U_NAMESPACE_END
+
+#endif /* U_SHOW_CPLUSPLUS_API */
+
+#endif  // __SIMPLEFORMATTER_H__
diff --git a/src/third_party/icu/source/common/unicode/std_string.h b/src/third_party/icu/source/common/unicode/std_string.h
index 05955c5..bf87230 100644
--- a/src/third_party/icu/source/common/unicode/std_string.h
+++ b/src/third_party/icu/source/common/unicode/std_string.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  std_string.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -25,13 +27,15 @@
 
 #include "unicode/utypes.h"
 
-#if U_HAVE_STD_STRING
+#if U_SHOW_CPLUSPLUS_API
 
-#if !defined(_MSC_VER)
-namespace std { class type_info; } // WORKAROUND: http://llvm.org/bugs/show_bug.cgi?id=13364
+// Workaround for a libstdc++ bug before libstdc++4.6 (2011).
+// https://bugs.llvm.org/show_bug.cgi?id=13364
+#if defined(__GLIBCXX__)
+namespace std { class type_info; }
 #endif
 #include <string>
 
-#endif  // U_HAVE_STD_STRING
+#endif /* U_SHOW_CPLUSPLUS_API */
 
 #endif  // __STD_STRING_H__
diff --git a/src/third_party/icu/source/common/unicode/strenum.h b/src/third_party/icu/source/common/unicode/strenum.h
index 3dbe21c..df72b4b 100644
--- a/src/third_party/icu/source/common/unicode/strenum.h
+++ b/src/third_party/icu/source/common/unicode/strenum.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -10,6 +12,10 @@
 #ifndef STRENUM_H
 #define STRENUM_H
 
+#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
 #include "unicode/uobject.h"
 #include "unicode/unistr.h"
 
@@ -33,7 +39,7 @@
  * call, so the returned string still might not be 'valid' on
  * subsequent use.</p>
  *
- * <p>Strings may take the form of const char*, const UChar*, or const
+ * <p>Strings may take the form of const char*, const char16_t*, or const
  * UnicodeString*.  The type you get is determine by the variant of
  * 'next' that you call.  In general the StringEnumeration is
  * optimized for one of these types, but all StringEnumerations can
@@ -65,9 +71,6 @@
      * Clones can be used concurrently in multiple threads.
      * If a subclass does not implement clone(), or if an error occurs,
      * then NULL is returned.
-     * The clone functions in all subclasses return a base class pointer
-     * because some compilers do not support covariant (same-as-this)
-     * return types; cast to the appropriate subclass if necessary.
      * The caller must delete the clone.
      *
      * @return a clone of this object
@@ -110,7 +113,7 @@
      * <p>If the iterator is out of sync with its service, status is set
      * to U_ENUM_OUT_OF_SYNC_ERROR and NULL is returned.</p>
      *
-     * <p>If the native service string is a UChar* string, it is
+     * <p>If the native service string is a char16_t* string, it is
      * converted to char* with the invariant converter.  If the
      * conversion fails (because a character cannot be converted) then
      * status is set to U_INVARIANT_CONVERSION_ERROR and the return
@@ -129,7 +132,7 @@
     virtual const char* next(int32_t *resultLength, UErrorCode& status);
 
     /**
-     * <p>Returns the next element as a NUL-terminated UChar*.  If there
+     * <p>Returns the next element as a NUL-terminated char16_t*.  If there
      * are no more elements, returns NULL.  If the resultLength pointer
      * is not NULL, the length of the string (not counting the
      * terminating NUL) is returned at that address.  If an error
@@ -151,7 +154,7 @@
      *
      * @stable ICU 2.4 
      */
-    virtual const UChar* unext(int32_t *resultLength, UErrorCode& status);
+    virtual const char16_t* unext(int32_t *resultLength, UErrorCode& status);
 
     /**
      * <p>Returns the next element a UnicodeString*.  If there are no
@@ -193,7 +196,7 @@
      * Compares this enumeration to other to check if both are equal
      *
      * @param that The other string enumeration to compare this object to
-     * @return TRUE if the enumerations are equal. FALSE if not.
+     * @return true if the enumerations are equal. false if not.
      * @stable ICU 3.6 
      */
     virtual UBool operator==(const StringEnumeration& that)const;
@@ -201,7 +204,7 @@
      * Compares this enumeration to other to check if both are not equal
      *
      * @param that The other string enumeration to compare this object to
-     * @return TRUE if the enumerations are equal. FALSE if not.
+     * @return true if the enumerations are equal. false if not.
      * @stable ICU 3.6 
      */
     virtual UBool operator!=(const StringEnumeration& that)const;
@@ -272,5 +275,7 @@
 
 U_NAMESPACE_END
 
+#endif /* U_SHOW_CPLUSPLUS_API */
+
 /* STRENUM_H */
 #endif
diff --git a/src/third_party/icu/source/common/unicode/stringoptions.h b/src/third_party/icu/source/common/unicode/stringoptions.h
new file mode 100644
index 0000000..7b9f709
--- /dev/null
+++ b/src/third_party/icu/source/common/unicode/stringoptions.h
@@ -0,0 +1,190 @@
+// © 2017 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+// stringoptions.h
+// created: 2017jun08 Markus W. Scherer
+
+#ifndef __STRINGOPTIONS_H__
+#define __STRINGOPTIONS_H__
+
+#include "unicode/utypes.h"
+
+/**
+ * \file
+ * \brief C API: Bit set option bit constants for various string and character processing functions.
+ */
+
+/**
+ * Option value for case folding: Use default mappings defined in CaseFolding.txt.
+ *
+ * @stable ICU 2.0
+ */
+#define U_FOLD_CASE_DEFAULT 0
+
+/**
+ * Option value for case folding:
+ *
+ * Use the modified set of mappings provided in CaseFolding.txt to handle dotted I
+ * and dotless i appropriately for Turkic languages (tr, az).
+ *
+ * Before Unicode 3.2, CaseFolding.txt contains mappings marked with 'I' that
+ * are to be included for default mappings and
+ * excluded for the Turkic-specific mappings.
+ *
+ * Unicode 3.2 CaseFolding.txt instead contains mappings marked with 'T' that
+ * are to be excluded for default mappings and
+ * included for the Turkic-specific mappings.
+ *
+ * @stable ICU 2.0
+ */
+#define U_FOLD_CASE_EXCLUDE_SPECIAL_I 1
+
+/**
+ * Titlecase the string as a whole rather than each word.
+ * (Titlecase only the character at index 0, possibly adjusted.)
+ * Option bits value for titlecasing APIs that take an options bit set.
+ *
+ * It is an error to specify multiple titlecasing iterator options together,
+ * including both an options bit and an explicit BreakIterator.
+ *
+ * @see U_TITLECASE_ADJUST_TO_CASED
+ * @stable ICU 60
+ */
+#define U_TITLECASE_WHOLE_STRING 0x20
+
+/**
+ * Titlecase sentences rather than words.
+ * (Titlecase only the first character of each sentence, possibly adjusted.)
+ * Option bits value for titlecasing APIs that take an options bit set.
+ *
+ * It is an error to specify multiple titlecasing iterator options together,
+ * including both an options bit and an explicit BreakIterator.
+ *
+ * @see U_TITLECASE_ADJUST_TO_CASED
+ * @stable ICU 60
+ */
+#define U_TITLECASE_SENTENCES 0x40
+
+/**
+ * Do not lowercase non-initial parts of words when titlecasing.
+ * Option bit for titlecasing APIs that take an options bit set.
+ *
+ * By default, titlecasing will titlecase the character at each
+ * (possibly adjusted) BreakIterator index and
+ * lowercase all other characters up to the next iterator index.
+ * With this option, the other characters will not be modified.
+ *
+ * @see U_TITLECASE_ADJUST_TO_CASED
+ * @see UnicodeString::toTitle
+ * @see CaseMap::toTitle
+ * @see ucasemap_setOptions
+ * @see ucasemap_toTitle
+ * @see ucasemap_utf8ToTitle
+ * @stable ICU 3.8
+ */
+#define U_TITLECASE_NO_LOWERCASE 0x100
+
+/**
+ * Do not adjust the titlecasing BreakIterator indexes;
+ * titlecase exactly the characters at breaks from the iterator.
+ * Option bit for titlecasing APIs that take an options bit set.
+ *
+ * By default, titlecasing will take each break iterator index,
+ * adjust it to the next relevant character (see U_TITLECASE_ADJUST_TO_CASED),
+ * and titlecase that one.
+ *
+ * Other characters are lowercased.
+ *
+ * It is an error to specify multiple titlecasing adjustment options together.
+ *
+ * @see U_TITLECASE_ADJUST_TO_CASED
+ * @see U_TITLECASE_NO_LOWERCASE
+ * @see UnicodeString::toTitle
+ * @see CaseMap::toTitle
+ * @see ucasemap_setOptions
+ * @see ucasemap_toTitle
+ * @see ucasemap_utf8ToTitle
+ * @stable ICU 3.8
+ */
+#define U_TITLECASE_NO_BREAK_ADJUSTMENT 0x200
+
+/**
+ * Adjust each titlecasing BreakIterator index to the next cased character.
+ * (See the Unicode Standard, chapter 3, Default Case Conversion, R3 toTitlecase(X).)
+ * Option bit for titlecasing APIs that take an options bit set.
+ *
+ * This used to be the default index adjustment in ICU.
+ * Since ICU 60, the default index adjustment is to the next character that is
+ * a letter, number, symbol, or private use code point.
+ * (Uncased modifier letters are skipped.)
+ * The difference in behavior is small for word titlecasing,
+ * but the new adjustment is much better for whole-string and sentence titlecasing:
+ * It yields "49ers" and "«丰(abc)»" instead of "49Ers" and "«丰(Abc)»".
+ *
+ * It is an error to specify multiple titlecasing adjustment options together.
+ *
+ * @see U_TITLECASE_NO_BREAK_ADJUSTMENT
+ * @stable ICU 60
+ */
+#define U_TITLECASE_ADJUST_TO_CASED 0x400
+
+/**
+ * Option for string transformation functions to not first reset the Edits object.
+ * Used for example in some case-mapping and normalization functions.
+ *
+ * @see CaseMap
+ * @see Edits
+ * @see Normalizer2
+ * @stable ICU 60
+ */
+#define U_EDITS_NO_RESET 0x2000
+
+/**
+ * Omit unchanged text when recording how source substrings
+ * relate to changed and unchanged result substrings.
+ * Used for example in some case-mapping and normalization functions.
+ *
+ * @see CaseMap
+ * @see Edits
+ * @see Normalizer2
+ * @stable ICU 60
+ */
+#define U_OMIT_UNCHANGED_TEXT 0x4000
+
+/**
+ * Option bit for u_strCaseCompare, u_strcasecmp, unorm_compare, etc:
+ * Compare strings in code point order instead of code unit order.
+ * @stable ICU 2.2
+ */
+#define U_COMPARE_CODE_POINT_ORDER  0x8000
+
+/**
+ * Option bit for unorm_compare:
+ * Perform case-insensitive comparison.
+ * @stable ICU 2.2
+ */
+#define U_COMPARE_IGNORE_CASE       0x10000
+
+/**
+ * Option bit for unorm_compare:
+ * Both input strings are assumed to fulfill FCD conditions.
+ * @stable ICU 2.2
+ */
+#define UNORM_INPUT_IS_FCD          0x20000
+
+// Related definitions elsewhere.
+// Options that are not meaningful in the same functions
+// can share the same bits.
+//
+// Public:
+// unicode/unorm.h #define UNORM_COMPARE_NORM_OPTIONS_SHIFT 20
+//
+// Internal: (may change or be removed)
+// ucase.h #define _STRCASECMP_OPTIONS_MASK 0xffff
+// ucase.h #define _FOLD_CASE_OPTIONS_MASK 7
+// ucasemap_imp.h #define U_TITLECASE_ITERATOR_MASK 0xe0
+// ucasemap_imp.h #define U_TITLECASE_ADJUSTMENT_MASK 0x600
+// ustr_imp.h #define _STRNCMP_STYLE 0x1000
+// unormcmp.cpp #define _COMPARE_EQUIV 0x80000
+
+#endif  // __STRINGOPTIONS_H__
diff --git a/src/third_party/icu/source/common/unicode/stringpiece.h b/src/third_party/icu/source/common/unicode/stringpiece.h
index b29571d..7d7d871 100644
--- a/src/third_party/icu/source/common/unicode/stringpiece.h
+++ b/src/third_party/icu/source/common/unicode/stringpiece.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 // Copyright (C) 2009-2013, International Business Machines
 // Corporation and others. All Rights Reserved.
 //
@@ -26,6 +28,12 @@
  */
 
 #include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
+#include <cstddef>
+#include <type_traits>
+
 #include "unicode/uobject.h"
 #include "unicode/std_string.h"
 
@@ -40,9 +48,9 @@
  * in a "const char*" or a "string" wherever a "StringPiece" is
  * expected.
  *
- * Functions or methods may use const StringPiece& parameters to accept either
- * a "const char*" or a "string" value that will be implicitly converted to
- * a StringPiece.
+ * Functions or methods may use StringPiece parameters to accept either a
+ * "const char*" or a "string" value that will be implicitly converted to a
+ * StringPiece.
  *
  * Systematic usage of StringPiece is encouraged as it will reduce unnecessary
  * conversions from "const char*" to "string" and back again.
@@ -59,21 +67,84 @@
    * Default constructor, creates an empty StringPiece.
    * @stable ICU 4.2
    */
-  StringPiece() : ptr_(NULL), length_(0) { }
+  StringPiece() : ptr_(nullptr), length_(0) { }
+
   /**
    * Constructs from a NUL-terminated const char * pointer.
    * @param str a NUL-terminated const char * pointer
    * @stable ICU 4.2
    */
   StringPiece(const char* str);
-#if U_HAVE_STD_STRING
+#ifndef U_HIDE_DRAFT_API
+#if defined(__cpp_char8_t) || defined(U_IN_DOXYGEN)
+  /**
+   * Constructs from a NUL-terminated const char8_t * pointer.
+   * @param str a NUL-terminated const char8_t * pointer
+   * @draft ICU 67
+   */
+  StringPiece(const char8_t* str) : StringPiece(reinterpret_cast<const char*>(str)) {}
+#endif
+  /**
+   * Constructs an empty StringPiece.
+   * Needed for type disambiguation from multiple other overloads.
+   * @param p nullptr
+   * @draft ICU 67
+   */
+  StringPiece(std::nullptr_t p) : ptr_(p), length_(0) {}
+#endif  // U_HIDE_DRAFT_API
+
   /**
    * Constructs from a std::string.
    * @stable ICU 4.2
    */
   StringPiece(const std::string& str)
     : ptr_(str.data()), length_(static_cast<int32_t>(str.size())) { }
+#ifndef U_HIDE_DRAFT_API
+#if defined(__cpp_lib_char8_t) || defined(U_IN_DOXYGEN)
+  /**
+   * Constructs from a std::u8string.
+   * @draft ICU 67
+   */
+  StringPiece(const std::u8string& str)
+    : ptr_(reinterpret_cast<const char*>(str.data())),
+      length_(static_cast<int32_t>(str.size())) { }
 #endif
+#endif  // U_HIDE_DRAFT_API
+
+  /**
+   * Constructs from some other implementation of a string piece class, from any
+   * C++ record type that has these two methods:
+   *
+   * \code{.cpp}
+   *
+   *   struct OtherStringPieceClass {
+   *     const char* data();  // or const char8_t*
+   *     size_t size();
+   *   };
+   *
+   * \endcode
+   *
+   * The other string piece class will typically be std::string_view from C++17
+   * or absl::string_view from Abseil.
+   *
+   * Starting with C++20, data() may also return a const char8_t* pointer,
+   * as from std::u8string_view.
+   *
+   * @param str the other string piece
+   * @stable ICU 65
+   */
+  template <typename T,
+            typename = typename std::enable_if<
+                (std::is_same<decltype(T().data()), const char*>::value
+#if defined(__cpp_char8_t)
+                    || std::is_same<decltype(T().data()), const char8_t*>::value
+#endif
+                ) &&
+                std::is_same<decltype(T().size()), size_t>::value>::type>
+  StringPiece(T str)
+      : ptr_(reinterpret_cast<const char*>(str.data())),
+        length_(static_cast<int32_t>(str.size())) {}
+
   /**
    * Constructs from a const char * pointer and a specified length.
    * @param offset a const char * pointer (need not be terminated)
@@ -81,6 +152,19 @@
    * @stable ICU 4.2
    */
   StringPiece(const char* offset, int32_t len) : ptr_(offset), length_(len) { }
+#ifndef U_HIDE_DRAFT_API
+#if defined(__cpp_char8_t) || defined(U_IN_DOXYGEN)
+  /**
+   * Constructs from a const char8_t * pointer and a specified length.
+   * @param str a const char8_t * pointer (need not be terminated)
+   * @param len the length of the string; must be non-negative
+   * @draft ICU 67
+   */
+  StringPiece(const char8_t* str, int32_t len) :
+      StringPiece(reinterpret_cast<const char*>(str), len) {}
+#endif
+#endif  // U_HIDE_DRAFT_API
+
   /**
    * Substring of another StringPiece.
    * @param x the other StringPiece
@@ -99,7 +183,7 @@
   StringPiece(const StringPiece& x, int32_t pos, int32_t len);
 
   /**
-   * Returns the string pointer. May be NULL if it is empty.
+   * Returns the string pointer. May be nullptr if it is empty.
    *
    * data() may return a pointer to a buffer with embedded NULs, and the
    * returned buffer may or may not be null terminated.  Therefore it is
@@ -123,7 +207,7 @@
   int32_t length() const { return length_; }
   /**
    * Returns whether the string is empty.
-   * @return TRUE if the string is empty
+   * @return true if the string is empty
    * @stable ICU 4.2
    */
   UBool empty() const { return length_ == 0; }
@@ -132,7 +216,7 @@
    * Sets to an empty string.
    * @stable ICU 4.2
    */
-  void clear() { ptr_ = NULL; length_ = 0; }
+  void clear() { ptr_ = nullptr; length_ = 0; }
 
   /**
    * Reset the stringpiece to refer to new data.
@@ -149,6 +233,29 @@
    */
   void set(const char* str);
 
+#ifndef U_HIDE_DRAFT_API
+#if defined(__cpp_char8_t) || defined(U_IN_DOXYGEN)
+  /**
+   * Resets the stringpiece to refer to new data.
+   * @param xdata pointer the new string data. Need not be NUL-terminated.
+   * @param len the length of the new data
+   * @draft ICU 67
+   */
+  inline void set(const char8_t* xdata, int32_t len) {
+      set(reinterpret_cast<const char*>(xdata), len);
+  }
+
+  /**
+   * Resets the stringpiece to refer to new data.
+   * @param str a pointer to a NUL-terminated string.
+   * @draft ICU 67
+   */
+  inline void set(const char8_t* str) {
+      set(reinterpret_cast<const char*>(str));
+  }
+#endif
+#endif  // U_HIDE_DRAFT_API
+
   /**
    * Removes the first n string units.
    * @param n prefix length, must be non-negative and <=length()
@@ -179,6 +286,26 @@
     }
   }
 
+#ifndef U_HIDE_DRAFT_API
+  /**
+   * Searches the StringPiece for the given search string (needle);
+   * @param needle The string for which to search.
+   * @param offset Where to start searching within this string (haystack).
+   * @return The offset of needle in haystack, or -1 if not found.
+   * @draft ICU 67
+   */
+  int32_t find(StringPiece needle, int32_t offset);
+
+  /**
+   * Compares this StringPiece with the other StringPiece, with semantics
+   * similar to std::string::compare().
+   * @param other The string to compare to.
+   * @return below zero if this < other; above zero if this > other; 0 if this == other.
+   * @draft ICU 67
+   */
+  int32_t compare(StringPiece other);
+#endif  // U_HIDE_DRAFT_API
+
   /**
    * Maximum integer, used as a default value for substring methods.
    * @stable ICU 4.2
@@ -202,7 +329,7 @@
  * Global operator == for StringPiece
  * @param x The first StringPiece to compare.
  * @param y The second StringPiece to compare.
- * @return TRUE if the string data is equal
+ * @return true if the string data is equal
  * @stable ICU 4.8
  */
 U_EXPORT UBool U_EXPORT2 
@@ -212,7 +339,7 @@
  * Global operator != for StringPiece
  * @param x The first StringPiece to compare.
  * @param y The second StringPiece to compare.
- * @return TRUE if the string data is not equal
+ * @return true if the string data is not equal
  * @stable ICU 4.8
  */
 inline UBool operator!=(const StringPiece& x, const StringPiece& y) {
@@ -221,4 +348,6 @@
 
 U_NAMESPACE_END
 
+#endif /* U_SHOW_CPLUSPLUS_API */
+
 #endif  // __STRINGPIECE_H__
diff --git a/src/third_party/icu/source/common/unicode/stringtriebuilder.h b/src/third_party/icu/source/common/unicode/stringtriebuilder.h
index 04447e5..fe471bb 100644
--- a/src/third_party/icu/source/common/unicode/stringtriebuilder.h
+++ b/src/third_party/icu/source/common/unicode/stringtriebuilder.h
@@ -1,10 +1,12 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *   Copyright (C) 2010-2012,2014, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *******************************************************************************
 *   file name:  stringtriebuilder.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -16,6 +18,9 @@
 #define __STRINGTRIEBUILDER_H__
 
 #include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
 #include "unicode/uobject.h"
 
 /**
@@ -24,8 +29,10 @@
  */
 
 // Forward declaration.
+/// \cond
 struct UHashtable;
 typedef struct UHashtable UHashtable;
+/// \endcond
 
 /**
  * Build options for BytesTrieBuilder and CharsTrieBuilder.
@@ -62,7 +69,7 @@
 public:
 #ifndef U_HIDE_INTERNAL_API
     /** @internal */
-    static UBool hashNode(const void *node);
+    static int32_t hashNode(const void *node);
     /** @internal */
     static UBool equalNodes(const void *left, const void *right);
 #endif  /* U_HIDE_INTERNAL_API */
@@ -103,7 +110,7 @@
     /** @internal */
     virtual int32_t getElementStringLength(int32_t i) const = 0;
     /** @internal */
-    virtual UChar getElementUnit(int32_t i, int32_t unitIndex) const = 0;
+    virtual char16_t getElementUnit(int32_t i, int32_t unitIndex) const = 0;
     /** @internal */
     virtual int32_t getElementValue(int32_t i) const = 0;
 
@@ -118,7 +125,7 @@
     /** @internal */
     virtual int32_t skipElementsBySomeUnits(int32_t i, int32_t unitIndex, int32_t count) const = 0;
     /** @internal */
-    virtual int32_t indexOfElementWithNextUnit(int32_t i, int32_t unitIndex, UChar unit) const = 0;
+    virtual int32_t indexOfElementWithNextUnit(int32_t i, int32_t unitIndex, char16_t unit) const = 0;
 
     /** @internal */
     virtual UBool matchNodesCanHaveValues() const = 0;
@@ -135,7 +142,7 @@
     /** @internal */
     static const int32_t kMaxBranchLinearSubNodeLength=5;
 
-    // Maximum number of nested split-branch levels for a branch on all 2^16 possible UChar units.
+    // Maximum number of nested split-branch levels for a branch on all 2^16 possible char16_t units.
     // log2(2^16/kMaxBranchLinearSubNodeLength) rounded up.
     /** @internal */
     static const int32_t kMaxSplitBranchLevels=14;
@@ -184,8 +191,12 @@
     /** @internal */
     UHashtable *nodes;
 
-#ifndef U_HIDE_INTERNAL_API
-    /** @internal */
+    // Do not conditionalize the following with #ifndef U_HIDE_INTERNAL_API,
+    // it is needed for layout of other objects.
+    /**
+     * @internal
+     * \cond
+     */
     class Node : public UObject {
     public:
         Node(int32_t initialHash) : hash(initialHash), offset(0) {}
@@ -243,6 +254,7 @@
         int32_t offset;
     };
 
+#ifndef U_HIDE_INTERNAL_API
     // This class should not be overridden because
     // registerFinalValue() compares a stack-allocated FinalValueNode
     // (stack-allocated so that we don't unnecessarily create lots of duplicate nodes)
@@ -252,51 +264,58 @@
     /** @internal */
     class FinalValueNode : public Node {
     public:
-        FinalValueNode(int32_t v) : Node(0x111111*37+v), value(v) {}
+        FinalValueNode(int32_t v) : Node(0x111111u*37u+v), value(v) {}
         virtual UBool operator==(const Node &other) const;
         virtual void write(StringTrieBuilder &builder);
     protected:
         int32_t value;
     };
+#endif  /* U_HIDE_INTERNAL_API */
 
+    // Do not conditionalize the following with #ifndef U_HIDE_INTERNAL_API,
+    // it is needed for layout of other objects.
     /**
      * @internal 
      */
     class ValueNode : public Node {
     public:
-        ValueNode(int32_t initialHash) : Node(initialHash), hasValue(FALSE), value(0) {}
+        ValueNode(int32_t initialHash) : Node(initialHash), hasValue(false), value(0) {}
         virtual UBool operator==(const Node &other) const;
         void setValue(int32_t v) {
-            hasValue=TRUE;
+            hasValue=true;
             value=v;
-            hash=hash*37+v;
+            hash=hash*37u+v;
         }
     protected:
         UBool hasValue;
         int32_t value;
     };
 
+#ifndef U_HIDE_INTERNAL_API
     /** 
      * @internal 
      */
     class IntermediateValueNode : public ValueNode {
     public:
         IntermediateValueNode(int32_t v, Node *nextNode)
-                : ValueNode(0x222222*37+hashCode(nextNode)), next(nextNode) { setValue(v); }
+                : ValueNode(0x222222u*37u+hashCode(nextNode)), next(nextNode) { setValue(v); }
         virtual UBool operator==(const Node &other) const;
         virtual int32_t markRightEdgesFirst(int32_t edgeNumber);
         virtual void write(StringTrieBuilder &builder);
     protected:
         Node *next;
     };
+#endif  /* U_HIDE_INTERNAL_API */
 
+    // Do not conditionalize the following with #ifndef U_HIDE_INTERNAL_API,
+    // it is needed for layout of other objects.
     /**
      * @internal 
      */
     class LinearMatchNode : public ValueNode {
     public:
         LinearMatchNode(int32_t len, Node *nextNode)
-                : ValueNode((0x333333*37+len)*37+hashCode(nextNode)),
+                : ValueNode((0x333333u*37u+len)*37u+hashCode(nextNode)),
                   length(len), next(nextNode) {}
         virtual UBool operator==(const Node &other) const;
         virtual int32_t markRightEdgesFirst(int32_t edgeNumber);
@@ -305,6 +324,7 @@
         Node *next;
     };
 
+#ifndef U_HIDE_INTERNAL_API
     /**
      * @internal 
      */
@@ -326,25 +346,25 @@
         virtual void write(StringTrieBuilder &builder);
         // Adds a unit with a final value.
         void add(int32_t c, int32_t value) {
-            units[length]=(UChar)c;
+            units[length]=(char16_t)c;
             equal[length]=NULL;
             values[length]=value;
             ++length;
-            hash=(hash*37+c)*37+value;
+            hash=(hash*37u+c)*37u+value;
         }
         // Adds a unit which leads to another match node.
         void add(int32_t c, Node *node) {
-            units[length]=(UChar)c;
+            units[length]=(char16_t)c;
             equal[length]=node;
             values[length]=0;
             ++length;
-            hash=(hash*37+c)*37+hashCode(node);
+            hash=(hash*37u+c)*37u+hashCode(node);
         }
     protected:
         Node *equal[kMaxBranchLinearSubNodeLength];  // NULL means "has final value".
         int32_t length;
         int32_t values[kMaxBranchLinearSubNodeLength];
-        UChar units[kMaxBranchLinearSubNodeLength];
+        char16_t units[kMaxBranchLinearSubNodeLength];
     };
 
     /**
@@ -352,15 +372,15 @@
      */
     class SplitBranchNode : public BranchNode {
     public:
-        SplitBranchNode(UChar middleUnit, Node *lessThanNode, Node *greaterOrEqualNode)
-                : BranchNode(((0x555555*37+middleUnit)*37+
-                              hashCode(lessThanNode))*37+hashCode(greaterOrEqualNode)),
+        SplitBranchNode(char16_t middleUnit, Node *lessThanNode, Node *greaterOrEqualNode)
+                : BranchNode(((0x555555u*37u+middleUnit)*37u+
+                              hashCode(lessThanNode))*37u+hashCode(greaterOrEqualNode)),
                   unit(middleUnit), lessThan(lessThanNode), greaterOrEqual(greaterOrEqualNode) {}
         virtual UBool operator==(const Node &other) const;
         virtual int32_t markRightEdgesFirst(int32_t edgeNumber);
         virtual void write(StringTrieBuilder &builder);
     protected:
-        UChar unit;
+        char16_t unit;
         Node *lessThan;
         Node *greaterOrEqual;
     };
@@ -370,7 +390,7 @@
     class BranchHeadNode : public ValueNode {
     public:
         BranchHeadNode(int32_t len, Node *subNode)
-                : ValueNode((0x666666*37+len)*37+hashCode(subNode)),
+                : ValueNode((0x666666u*37u+len)*37u+hashCode(subNode)),
                   length(len), next(subNode) {}
         virtual UBool operator==(const Node &other) const;
         virtual int32_t markRightEdgesFirst(int32_t edgeNumber);
@@ -379,7 +399,9 @@
         int32_t length;
         Node *next;  // A branch sub-node.
     };
+
 #endif  /* U_HIDE_INTERNAL_API */
+    /// \endcond
 
     /** @internal */
     virtual Node *createLinearMatchNode(int32_t i, int32_t unitIndex, int32_t length,
@@ -399,4 +421,6 @@
 
 U_NAMESPACE_END
 
+#endif /* U_SHOW_CPLUSPLUS_API */
+
 #endif  // __STRINGTRIEBUILDER_H__
diff --git a/src/third_party/icu/source/common/unicode/symtable.h b/src/third_party/icu/source/common/unicode/symtable.h
index 428f8bf..b64d877 100644
--- a/src/third_party/icu/source/common/unicode/symtable.h
+++ b/src/third_party/icu/source/common/unicode/symtable.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
 *   Copyright (c) 2000-2005, International Business Machines
@@ -11,6 +13,9 @@
 #define SYMTABLE_H
 
 #include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
 #include "unicode/uobject.h"
 
 /**
@@ -109,4 +114,6 @@
 };
 U_NAMESPACE_END
 
+#endif /* U_SHOW_CPLUSPLUS_API */
+
 #endif
diff --git a/src/third_party/icu/source/common/unicode/ubidi.h b/src/third_party/icu/source/common/unicode/ubidi.h
index 27042ed..63d0e45 100644
--- a/src/third_party/icu/source/common/unicode/ubidi.h
+++ b/src/third_party/icu/source/common/unicode/ubidi.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 ******************************************************************************
 *   file name:  ubidi.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -19,7 +21,10 @@
 
 #include "unicode/utypes.h"
 #include "unicode/uchar.h"
+
+#if U_SHOW_CPLUSPLUS_API
 #include "unicode/localpointer.h"
+#endif   // U_SHOW_CPLUSPLUS_API
 
 /**
  *\file
@@ -321,6 +326,10 @@
  * these special values are designed that way. Also, the implementation
  * assumes that UBIDI_MAX_EXPLICIT_LEVEL is odd.
  *
+ * Note: The numeric values of the related constants will not change:
+ * They are tied to the use of 7-bit byte values (plus the override bit)
+ * and of the UBiDiLevel=uint8_t data type in this API.
+ *
  * @see UBIDI_DEFAULT_LTR
  * @see UBIDI_DEFAULT_RTL
  * @see UBIDI_LEVEL_OVERRIDE
@@ -384,6 +393,8 @@
 
 /**
  * Maximum explicit embedding level.
+ * Same as the max_depth value in the
+ * <a href="http://www.unicode.org/reports/tr9/#BD2">Unicode Bidirectional Algorithm</a>.
  * (The maximum resolved level can be up to <code>UBIDI_MAX_EXPLICIT_LEVEL+1</code>).
  * @stable ICU 2.0
  */
@@ -488,7 +499,7 @@
  * @return An empty <code>UBiDi</code> object.
  * @stable ICU 2.0
  */
-U_STABLE UBiDi * U_EXPORT2
+U_CAPI UBiDi * U_EXPORT2
 ubidi_open(void);
 
 /**
@@ -525,7 +536,7 @@
  * @return An empty <code>UBiDi</code> object with preallocated memory.
  * @stable ICU 2.0
  */
-U_STABLE UBiDi * U_EXPORT2
+U_CAPI UBiDi * U_EXPORT2
 ubidi_openSized(int32_t maxLength, int32_t maxRunCount, UErrorCode *pErrorCode);
 
 /**
@@ -548,7 +559,7 @@
  * @see ubidi_setLine
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 ubidi_close(UBiDi *pBiDi);
 
 #if U_SHOW_CPLUSPLUS_API
@@ -586,7 +597,7 @@
  * this "inverse Bidi" and that the current implementation provides only an
  * approximation of "inverse Bidi".</p>
  *
- * <p>With <code>isInverse</code> set to <code>TRUE</code>,
+ * <p>With <code>isInverse</code> set to <code>true</code>,
  * this function changes the behavior of some of the subsequent functions
  * in a way that they can be used for the inverse Bidi algorithm.
  * Specifically, runs of text with numeric characters will be treated in a
@@ -599,12 +610,12 @@
  * the runs of the logically ordered output.</p>
  *
  * <p>Calling this function with argument <code>isInverse</code> set to
- * <code>TRUE</code> is equivalent to calling
+ * <code>true</code> is equivalent to calling
  * <code>ubidi_setReorderingMode</code> with argument
  * <code>reorderingMode</code>
  * set to <code>#UBIDI_REORDER_INVERSE_NUMBERS_AS_L</code>.<br>
  * Calling this function with argument <code>isInverse</code> set to
- * <code>FALSE</code> is equivalent to calling
+ * <code>false</code> is equivalent to calling
  * <code>ubidi_setReorderingMode</code> with argument
  * <code>reorderingMode</code>
  * set to <code>#UBIDI_REORDER_DEFAULT</code>.
@@ -618,18 +629,18 @@
  * @see ubidi_setReorderingMode
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 ubidi_setInverse(UBiDi *pBiDi, UBool isInverse);
 
 /**
  * Is this Bidi object set to perform the inverse Bidi algorithm?
  * <p>Note: calling this function after setting the reordering mode with
- * <code>ubidi_setReorderingMode</code> will return <code>TRUE</code> if the
+ * <code>ubidi_setReorderingMode</code> will return <code>true</code> if the
  * reordering mode was set to <code>#UBIDI_REORDER_INVERSE_NUMBERS_AS_L</code>,
- * <code>FALSE</code> for all other values.</p>
+ * <code>false</code> for all other values.</p>
  *
  * @param pBiDi is a <code>UBiDi</code> object.
- * @return TRUE if the Bidi object is set to perform the inverse Bidi algorithm
+ * @return true if the Bidi object is set to perform the inverse Bidi algorithm
  * by handling numbers as L.
  *
  * @see ubidi_setInverse
@@ -637,7 +648,7 @@
  * @stable ICU 2.0
  */
 
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 ubidi_isInverse(UBiDi *pBiDi);
 
 /**
@@ -660,7 +671,7 @@
  * @see ubidi_setPara
  * @stable ICU 3.4
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 ubidi_orderParagraphsLTR(UBiDi *pBiDi, UBool orderParagraphsLTR);
 
 /**
@@ -668,13 +679,13 @@
  * successive paragraphs progress from left to right?
  *
  * @param pBiDi is a <code>UBiDi</code> object.
- * @return TRUE if the Bidi object is set to allocate level 0 to block
+ * @return true if the Bidi object is set to allocate level 0 to block
  *         separators.
  *
  * @see ubidi_orderParagraphsLTR
  * @stable ICU 3.4
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 ubidi_isOrderParagraphsLTR(UBiDi *pBiDi);
 
 /**
@@ -690,7 +701,7 @@
       * @stable ICU 3.6 */
     UBIDI_REORDER_DEFAULT = 0,
     /** Logical to Visual algorithm which handles numbers in a way which
-      * mimicks the behavior of Windows XP.
+      * mimics the behavior of Windows XP.
       * @stable ICU 3.6 */
     UBIDI_REORDER_NUMBERS_SPECIAL,
     /** Logical to Visual algorithm grouping numbers with adjacent R characters
@@ -706,7 +717,7 @@
       * @stable ICU 3.6 */
     UBIDI_REORDER_RUNS_ONLY,
     /** Visual to Logical algorithm which handles numbers like L
-      * (same algorithm as selected by <code>ubidi_setInverse(TRUE)</code>.
+      * (same algorithm as selected by <code>ubidi_setInverse(true)</code>.
       * @see ubidi_setInverse
       * @stable ICU 3.6 */
     UBIDI_REORDER_INVERSE_NUMBERS_AS_L,
@@ -718,9 +729,13 @@
       * <code>UBIDI_REORDER_NUMBERS_SPECIAL</code> Bidi algorithm.
       * @stable ICU 3.6 */
     UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL,
-    /** Number of values for reordering mode.
-      * @stable ICU 3.6 */
+#ifndef U_HIDE_DEPRECATED_API
+    /**
+     * Number of values for reordering mode.
+     * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
+     */
     UBIDI_REORDER_COUNT
+#endif  // U_HIDE_DEPRECATED_API
 } UBiDiReorderingMode;
 
 /**
@@ -821,7 +836,7 @@
  * reordered sequence (the option <code>#UBIDI_INSERT_LRM_FOR_NUMERIC</code> can
  * be used with function <code>ubidi_writeReordered</code> to this end. This
  * mode is equivalent to calling <code>ubidi_setInverse()</code> with
- * argument <code>isInverse</code> set to <code>TRUE</code>.</li>
+ * argument <code>isInverse</code> set to <code>true</code>.</li>
  *
  * <li>When the reordering mode is set to
  * <code>#UBIDI_REORDER_INVERSE_LIKE_DIRECT</code>, the "direct" Logical to Visual
@@ -874,7 +889,7 @@
  * @see ubidi_writeReordered
  * @stable ICU 3.6
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 ubidi_setReorderingMode(UBiDi *pBiDi, UBiDiReorderingMode reorderingMode);
 
 /**
@@ -885,7 +900,7 @@
  * @see ubidi_setReorderingMode
  * @stable ICU 3.6
  */
-U_STABLE UBiDiReorderingMode U_EXPORT2
+U_CAPI UBiDiReorderingMode U_EXPORT2
 ubidi_getReorderingMode(UBiDi *pBiDi);
 
 /**
@@ -923,7 +938,7 @@
      *
      * <p>If this option is set in conjunction with reordering mode
      * <code>#UBIDI_REORDER_INVERSE_NUMBERS_AS_L</code> or with calling
-     * <code>ubidi_setInverse(TRUE)</code>, it implies
+     * <code>ubidi_setInverse(true)</code>, it implies
      * option <code>#UBIDI_INSERT_LRM_FOR_NUMERIC</code>
      * in calls to function <code>ubidi_writeReordered()</code>.</p>
      *
@@ -1004,7 +1019,7 @@
      *
      * <p>When the <code>UBIDI_OPTION_STREAMING</code> option is used,
      * it is recommended to call <code>ubidi_orderParagraphsLTR()</code> with
-     * argument <code>orderParagraphsLTR</code> set to <code>TRUE</code> before
+     * argument <code>orderParagraphsLTR</code> set to <code>true</code> before
      * calling <code>ubidi_setPara</code> so that later paragraphs may be
      * concatenated to previous paragraphs on the right.</p>
      *
@@ -1030,7 +1045,7 @@
  * @see ubidi_getReorderingOptions
  * @stable ICU 3.6
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 ubidi_setReorderingOptions(UBiDi *pBiDi, uint32_t reorderingOptions);
 
 /**
@@ -1041,7 +1056,7 @@
  * @see ubidi_setReorderingOptions
  * @stable ICU 3.6
  */
-U_STABLE uint32_t U_EXPORT2
+U_CAPI uint32_t U_EXPORT2
 ubidi_getReorderingOptions(UBiDi *pBiDi);
 
 /**
@@ -1128,7 +1143,7 @@
  * @see ubidi_setPara
  * @stable ICU 4.8
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 ubidi_setContext(UBiDi *pBiDi,
                  const UChar *prologue, int32_t proLength,
                  const UChar *epilogue, int32_t epiLength,
@@ -1136,7 +1151,7 @@
 
 /**
  * Perform the Unicode Bidi algorithm. It is defined in the
- * <a href="http://www.unicode.org/unicode/reports/tr9/">Unicode Standard Anned #9</a>,
+ * <a href="http://www.unicode.org/unicode/reports/tr9/">Unicode Standard Annex #9</a>,
  * version 13,
  * also described in The Unicode Standard, Version 4.0 .<p>
  *
@@ -1190,11 +1205,14 @@
  *        A level overrides the directional property of its corresponding
  *        (same index) character if the level has the
  *        <code>#UBIDI_LEVEL_OVERRIDE</code> bit set.<br><br>
- *        Except for that bit, it must be
+ *        Aside from that bit, it must be
  *        <code>paraLevel<=embeddingLevels[]<=UBIDI_MAX_EXPLICIT_LEVEL</code>,
- *        with one exception: a level of zero may be specified for a paragraph
- *        separator even if <code>paraLevel>0</code> when multiple paragraphs
- *        are submitted in the same call to <code>ubidi_setPara()</code>.<br><br>
+ *        except that level 0 is always allowed.
+ *        Level 0 for a paragraph separator prevents reordering of paragraphs;
+ *        this only works reliably if <code>#UBIDI_LEVEL_OVERRIDE</code>
+ *        is also set for paragraph separators.
+ *        Level 0 for other characters is treated as a wildcard
+ *        and is lifted up to the resolved level of the surrounding paragraph.<br><br>
  *        <strong>Caution: </strong>A copy of this pointer, not of the levels,
  *        will be stored in the <code>UBiDi</code> object;
  *        the <code>embeddingLevels</code> array must not be
@@ -1213,7 +1231,7 @@
  * @param pErrorCode must be a valid pointer to an error code value.
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 ubidi_setPara(UBiDi *pBiDi, const UChar *text, int32_t length,
               UBiDiLevel paraLevel, UBiDiLevel *embeddingLevels,
               UErrorCode *pErrorCode);
@@ -1264,7 +1282,7 @@
  * @see ubidi_getProcessedLength
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 ubidi_setLine(const UBiDi *pParaBiDi,
               int32_t start, int32_t limit,
               UBiDi *pLineBiDi,
@@ -1285,7 +1303,7 @@
  * @see UBiDiDirection
  * @stable ICU 2.0
  */
-U_STABLE UBiDiDirection U_EXPORT2
+U_CAPI UBiDiDirection U_EXPORT2
 ubidi_getDirection(const UBiDi *pBiDi);
 
 /**
@@ -1315,7 +1333,7 @@
  * @see UBiDiDirection
  * @stable ICU 4.6
  */
-U_STABLE UBiDiDirection U_EXPORT2
+U_CAPI UBiDiDirection U_EXPORT2
 ubidi_getBaseDirection(const UChar *text,  int32_t length );
 
 /**
@@ -1329,7 +1347,7 @@
  * @see ubidi_setLine
  * @stable ICU 2.0
  */
-U_STABLE const UChar * U_EXPORT2
+U_CAPI const UChar * U_EXPORT2
 ubidi_getText(const UBiDi *pBiDi);
 
 /**
@@ -1340,7 +1358,7 @@
  * @return The length of the text that the UBiDi object was created for.
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 ubidi_getLength(const UBiDi *pBiDi);
 
 /**
@@ -1358,7 +1376,7 @@
  * @see ubidi_getParagraphByIndex
  * @stable ICU 2.0
  */
-U_STABLE UBiDiLevel U_EXPORT2
+U_CAPI UBiDiLevel U_EXPORT2
 ubidi_getParaLevel(const UBiDi *pBiDi);
 
 /**
@@ -1369,7 +1387,7 @@
  * @return The number of paragraphs.
  * @stable ICU 3.4
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 ubidi_countParagraphs(UBiDi *pBiDi);
 
 /**
@@ -1406,7 +1424,7 @@
  * @see ubidi_getProcessedLength
  * @stable ICU 3.4
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 ubidi_getParagraph(const UBiDi *pBiDi, int32_t charIndex, int32_t *pParaStart,
                    int32_t *pParaLimit, UBiDiLevel *pParaLevel,
                    UErrorCode *pErrorCode);
@@ -1438,7 +1456,7 @@
  *
  * @stable ICU 3.4
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 ubidi_getParagraphByIndex(const UBiDi *pBiDi, int32_t paraIndex,
                           int32_t *pParaStart, int32_t *pParaLimit,
                           UBiDiLevel *pParaLevel, UErrorCode *pErrorCode);
@@ -1458,7 +1476,7 @@
  * @see ubidi_getProcessedLength
  * @stable ICU 2.0
  */
-U_STABLE UBiDiLevel U_EXPORT2
+U_CAPI UBiDiLevel U_EXPORT2
 ubidi_getLevelAt(const UBiDi *pBiDi, int32_t charIndex);
 
 /**
@@ -1479,7 +1497,7 @@
  * @see ubidi_getProcessedLength
  * @stable ICU 2.0
  */
-U_STABLE const UBiDiLevel * U_EXPORT2
+U_CAPI const UBiDiLevel * U_EXPORT2
 ubidi_getLevels(UBiDi *pBiDi, UErrorCode *pErrorCode);
 
 /**
@@ -1506,7 +1524,7 @@
  * @see ubidi_getProcessedLength
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 ubidi_getLogicalRun(const UBiDi *pBiDi, int32_t logicalPosition,
                     int32_t *pLogicalLimit, UBiDiLevel *pLevel);
 
@@ -1525,7 +1543,7 @@
  * @return The number of runs.
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 ubidi_countRuns(UBiDi *pBiDi, UErrorCode *pErrorCode);
 
 /**
@@ -1584,7 +1602,7 @@
  * to avoid these issues.
  * @stable ICU 2.0
  */
-U_STABLE UBiDiDirection U_EXPORT2
+U_CAPI UBiDiDirection U_EXPORT2
 ubidi_getVisualRun(UBiDi *pBiDi, int32_t runIndex,
                    int32_t *pLogicalStart, int32_t *pLength);
 
@@ -1625,7 +1643,7 @@
  * @see ubidi_getProcessedLength
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 ubidi_getVisualIndex(UBiDi *pBiDi, int32_t logicalIndex, UErrorCode *pErrorCode);
 
 /**
@@ -1660,7 +1678,7 @@
  * @see ubidi_getResultLength
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 ubidi_getLogicalIndex(UBiDi *pBiDi, int32_t visualIndex, UErrorCode *pErrorCode);
 
 /**
@@ -1703,7 +1721,7 @@
  * @see ubidi_getResultLength
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 ubidi_getLogicalMap(UBiDi *pBiDi, int32_t *indexMap, UErrorCode *pErrorCode);
 
 /**
@@ -1739,7 +1757,7 @@
  * @see ubidi_getResultLength
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 ubidi_getVisualMap(UBiDi *pBiDi, int32_t *indexMap, UErrorCode *pErrorCode);
 
 /**
@@ -1762,7 +1780,7 @@
  *        The index map will result in <code>indexMap[logicalIndex]==visualIndex</code>.
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 ubidi_reorderLogical(const UBiDiLevel *levels, int32_t length, int32_t *indexMap);
 
 /**
@@ -1785,7 +1803,7 @@
  *        The index map will result in <code>indexMap[visualIndex]==logicalIndex</code>.
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 ubidi_reorderVisual(const UBiDiLevel *levels, int32_t length, int32_t *indexMap);
 
 /**
@@ -1820,7 +1838,7 @@
  * @see UBIDI_MAP_NOWHERE
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 ubidi_invertMap(const int32_t *srcMap, int32_t *destMap, int32_t length);
 
 /** option flags for ubidi_writeReordered() */
@@ -1925,7 +1943,7 @@
  * @see UBIDI_OPTION_STREAMING
  * @stable ICU 3.6
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 ubidi_getProcessedLength(const UBiDi *pBiDi);
 
 /**
@@ -1955,17 +1973,23 @@
  * @see UBIDI_OPTION_REMOVE_CONTROLS
  * @stable ICU 3.6
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 ubidi_getResultLength(const UBiDi *pBiDi);
 
 U_CDECL_BEGIN
+
+#ifndef U_HIDE_DEPRECATED_API
 /**
- * value returned by <code>UBiDiClassCallback</code> callbacks when
+ * Value returned by <code>UBiDiClassCallback</code> callbacks when
  * there is no need to override the standard Bidi class for a given code point.
+ *
+ * This constant is deprecated; use u_getIntPropertyMaxValue(UCHAR_BIDI_CLASS)+1 instead.
+ *
  * @see UBiDiClassCallback
- * @stable ICU 3.6
+ * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
  */
 #define U_BIDI_CLASS_DEFAULT  U_CHAR_DIRECTION_COUNT
+#endif  // U_HIDE_DEPRECATED_API
 
 /**
  * Callback type declaration for overriding default Bidi class values with
@@ -1981,8 +2005,8 @@
  *
  * @return The directional property / Bidi class for the given code point
  *         <code>c</code> if the default class has been overridden, or
- *         <code>#U_BIDI_CLASS_DEFAULT</code> if the standard Bidi class value
- *         for <code>c</code> is to be used.
+ *         <code>u_getIntPropertyMaxValue(UCHAR_BIDI_CLASS)+1</code>
+ *         if the standard Bidi class value for <code>c</code> is to be used.
  * @see ubidi_setClassCallback
  * @see ubidi_getClassCallback
  * @stable ICU 3.6
@@ -1995,8 +2019,8 @@
 /**
  * Retrieve the Bidi class for a given code point.
  * <p>If a <code>#UBiDiClassCallback</code> callback is defined and returns a
- * value other than <code>#U_BIDI_CLASS_DEFAULT</code>, that value is used;
- * otherwise the default class determination mechanism is invoked.</p>
+ * value other than <code>u_getIntPropertyMaxValue(UCHAR_BIDI_CLASS)+1</code>,
+ * that value is used; otherwise the default class determination mechanism is invoked.</p>
  *
  * @param pBiDi is the paragraph <code>UBiDi</code> object.
  *
@@ -2007,7 +2031,7 @@
  * @see UBiDiClassCallback
  * @stable ICU 3.6
  */
-U_STABLE UCharDirection U_EXPORT2
+U_CAPI UCharDirection U_EXPORT2
 ubidi_getCustomizedClass(UBiDi *pBiDi, UChar32 c);
 
 /**
@@ -2037,7 +2061,7 @@
  * @see ubidi_getClassCallback
  * @stable ICU 3.6
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 ubidi_setClassCallback(UBiDi *pBiDi, UBiDiClassCallback *newFn,
                        const void *newContext, UBiDiClassCallback **oldFn,
                        const void **oldContext, UErrorCode *pErrorCode);
@@ -2054,7 +2078,7 @@
  * @see ubidi_setClassCallback
  * @stable ICU 3.6
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 ubidi_getClassCallback(UBiDi *pBiDi, UBiDiClassCallback **fn, const void **context);
 
 /**
@@ -2122,7 +2146,7 @@
  * @see ubidi_getProcessedLength
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 ubidi_writeReordered(UBiDi *pBiDi,
                      UChar *dest, int32_t destSize,
                      uint16_t options,
@@ -2174,7 +2198,7 @@
  * @return The length of the output string.
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 ubidi_writeReverse(const UChar *src, int32_t srcLength,
                    UChar *dest, int32_t destSize,
                    uint16_t options,
diff --git a/src/third_party/icu/source/common/unicode/ubiditransform.h b/src/third_party/icu/source/common/unicode/ubiditransform.h
new file mode 100644
index 0000000..2dd7564
--- /dev/null
+++ b/src/third_party/icu/source/common/unicode/ubiditransform.h
@@ -0,0 +1,326 @@
+/*
+******************************************************************************
+*
+* © 2016 and later: Unicode, Inc. and others.
+* License & terms of use: http://www.unicode.org/copyright.html
+*
+******************************************************************************
+*   file name:  ubiditransform.h
+*   encoding:   UTF-8
+*   tab size:   8 (not used)
+*   indentation:4
+*
+*   created on: 2016jul24
+*   created by: Lina Kemmel
+*
+*/
+
+#ifndef UBIDITRANSFORM_H
+#define UBIDITRANSFORM_H
+
+#include "unicode/utypes.h"
+#include "unicode/ubidi.h"
+#include "unicode/uchar.h"
+
+#if U_SHOW_CPLUSPLUS_API
+#include "unicode/localpointer.h"
+#endif   // U_SHOW_CPLUSPLUS_API
+
+/**
+ * \file
+ * \brief Bidi Transformations
+ */
+
+/**
+ * `UBiDiOrder` indicates the order of text.
+ *
+ * This bidi transformation engine supports all possible combinations (4 in
+ * total) of input and output text order:
+ *
+ *   - <logical input, visual output>: unless the output direction is RTL, this
+ *     corresponds to a normal operation of the Bidi algorithm as described in the
+ *     Unicode Technical Report and implemented by `UBiDi` when the
+ *     reordering mode is set to `UBIDI_REORDER_DEFAULT`. Visual RTL
+ *     mode is not supported by `UBiDi` and is accomplished through
+ *     reversing a visual LTR string,
+ *
+ *   - <visual input, logical output>: unless the input direction is RTL, this
+ *     corresponds to an "inverse bidi algorithm" in `UBiDi` with the
+ *     reordering mode set to `UBIDI_REORDER_INVERSE_LIKE_DIRECT`.
+ *     Visual RTL mode is not not supported by `UBiDi` and is
+ *     accomplished through reversing a visual LTR string,
+ *
+ *   - <logical input, logical output>: if the input and output base directions
+ *     mismatch, this corresponds to the `UBiDi` implementation with the
+ *     reordering mode set to `UBIDI_REORDER_RUNS_ONLY`; and if the
+ *     input and output base directions are identical, the transformation engine
+ *     will only handle character mirroring and Arabic shaping operations without
+ *     reordering,
+ *
+ *   - <visual input, visual output>: this reordering mode is not supported by
+ *     the `UBiDi` engine; it implies character mirroring, Arabic
+ *     shaping, and - if the input/output base directions mismatch -  string
+ *     reverse operations.
+ * @see ubidi_setInverse
+ * @see ubidi_setReorderingMode
+ * @see UBIDI_REORDER_DEFAULT
+ * @see UBIDI_REORDER_INVERSE_LIKE_DIRECT
+ * @see UBIDI_REORDER_RUNS_ONLY
+ * @stable ICU 58
+ */
+typedef enum {
+    /** 0: Constant indicating a logical order.
+      * This is the default for input text.
+      * @stable ICU 58
+      */
+    UBIDI_LOGICAL = 0,
+    /** 1: Constant indicating a visual order.
+      * This is a default for output text.
+      * @stable ICU 58
+      */
+    UBIDI_VISUAL
+} UBiDiOrder;
+
+/**
+ * <code>UBiDiMirroring</code> indicates whether or not characters with the
+ * "mirrored" property in RTL runs should be replaced with their mirror-image
+ * counterparts.
+ * @see UBIDI_DO_MIRRORING
+ * @see ubidi_setReorderingOptions
+ * @see ubidi_writeReordered
+ * @see ubidi_writeReverse
+ * @stable ICU 58
+ */
+typedef enum {
+    /** 0: Constant indicating that character mirroring should not be
+      * performed.
+      * This is the default.
+      * @stable ICU 58
+      */
+    UBIDI_MIRRORING_OFF = 0,
+    /** 1: Constant indicating that character mirroring should be performed.
+      * This corresponds to calling <code>ubidi_writeReordered</code> or
+      * <code>ubidi_writeReverse</code> with the
+      * <code>UBIDI_DO_MIRRORING</code> option bit set.
+      * @stable ICU 58
+      */
+    UBIDI_MIRRORING_ON
+} UBiDiMirroring;
+
+/**
+ * Forward declaration of the <code>UBiDiTransform</code> structure that stores
+ * information used by the layout transformation engine.
+ * @stable ICU 58
+ */
+typedef struct UBiDiTransform UBiDiTransform;
+
+/**
+ * Performs transformation of text from the bidi layout defined by the input
+ * ordering scheme to the bidi layout defined by the output ordering scheme,
+ * and applies character mirroring and Arabic shaping operations.<p>
+ * In terms of <code>UBiDi</code>, such a transformation implies:
+ * <ul>
+ * <li>calling <code>ubidi_setReorderingMode</code> as needed (when the
+ * reordering mode is other than normal),</li>
+ * <li>calling <code>ubidi_setInverse</code> as needed (when text should be
+ * transformed from a visual to a logical form),</li>
+ * <li>resolving embedding levels of each character in the input text by
+ * calling <code>ubidi_setPara</code>,</li>
+ * <li>reordering the characters based on the computed embedding levels, also
+ * performing character mirroring as needed, and streaming the result to the
+ * output, by calling <code>ubidi_writeReordered</code>,</li>
+ * <li>performing Arabic digit and letter shaping on the output text by calling
+ * <code>u_shapeArabic</code>.</li>
+ * </ul>
+ * An "ordering scheme" encompasses the base direction and the order of text,
+ * and these characteristics must be defined by the caller for both input and
+ * output explicitly .<p>
+ * There are 36 possible combinations of <input, output> ordering schemes,
+ * which are partially supported by <code>UBiDi</code> already. Examples of the
+ * currently supported combinations:
+ * <ul>
+ * <li><Logical LTR, Visual LTR>: this is equivalent to calling
+ * <code>ubidi_setPara</code> with <code>paraLevel == UBIDI_LTR</code>,</li>
+ * <li><Logical RTL, Visual LTR>: this is equivalent to calling
+ * <code>ubidi_setPara</code> with <code>paraLevel == UBIDI_RTL</code>,</li>
+ * <li><Logical Default ("Auto") LTR, Visual LTR>: this is equivalent to
+ * calling <code>ubidi_setPara</code> with
+ * <code>paraLevel == UBIDI_DEFAULT_LTR</code>,</li>
+ * <li><Logical Default ("Auto") RTL, Visual LTR>: this is equivalent to
+ * calling <code>ubidi_setPara</code> with
+ * <code>paraLevel == UBIDI_DEFAULT_RTL</code>,</li>
+ * <li><Visual LTR, Logical LTR>: this is equivalent to
+ * calling <code>ubidi_setInverse(UBiDi*, true)</code> and then
+ * <code>ubidi_setPara</code> with <code>paraLevel == UBIDI_LTR</code>,</li>
+ * <li><Visual LTR, Logical RTL>: this is equivalent to
+ * calling <code>ubidi_setInverse(UBiDi*, true)</code> and then
+ * <code>ubidi_setPara</code> with <code>paraLevel == UBIDI_RTL</code>.</li>
+ * </ul>
+ * All combinations that involve the Visual RTL scheme are unsupported by
+ * <code>UBiDi</code>, for instance:
+ * <ul>
+ * <li><Logical LTR, Visual RTL>,</li>
+ * <li><Visual RTL, Logical RTL>.</li>
+ * </ul>
+ * <p>Example of usage of the transformation engine:<br>
+ * <pre>
+ * \code
+ * UChar text1[] = {'a', 'b', 'c', 0x0625, '1', 0};
+ * UChar text2[] = {'a', 'b', 'c', 0x0625, '1', 0};
+ * UErrorCode errorCode = U_ZERO_ERROR;
+ * // Run a transformation.
+ * ubiditransform_transform(pBidiTransform,
+ *          text1, -1, text2, -1,
+ *          UBIDI_LTR, UBIDI_VISUAL,
+ *          UBIDI_RTL, UBIDI_LOGICAL,
+ *          UBIDI_MIRRORING_OFF,
+ *          U_SHAPE_DIGITS_AN2EN | U_SHAPE_DIGIT_TYPE_AN_EXTENDED,
+ *          &errorCode);
+ * // Do something with text2.
+ *  text2[4] = '2';
+ * // Run a reverse transformation.
+ * ubiditransform_transform(pBidiTransform,
+ *          text2, -1, text1, -1,
+ *          UBIDI_RTL, UBIDI_LOGICAL,
+ *          UBIDI_LTR, UBIDI_VISUAL,
+ *          UBIDI_MIRRORING_OFF,
+ *          U_SHAPE_DIGITS_EN2AN | U_SHAPE_DIGIT_TYPE_AN_EXTENDED,
+ *          &errorCode);
+ *\endcode
+ * </pre>
+ * </p>
+ *
+ * @param pBiDiTransform A pointer to a <code>UBiDiTransform</code> object
+ *        allocated with <code>ubiditransform_open()</code> or
+ *        <code>NULL</code>.<p>
+ *        This object serves for one-time setup to amortize initialization
+ *        overheads. Use of this object is not thread-safe. All other threads
+ *        should allocate a new <code>UBiDiTransform</code> object by calling
+ *        <code>ubiditransform_open()</code> before using it. Alternatively,
+ *        a caller can set this parameter to <code>NULL</code>, in which case
+ *        the object will be allocated by the engine on the fly.</p>
+ * @param src A pointer to the text that the Bidi layout transformations will
+ *        be performed on.
+ *        <p><strong>Note:</strong> the text must be (at least)
+ *        <code>srcLength</code> long.</p>
+ * @param srcLength The length of the text, in number of UChars. If
+ *        <code>length == -1</code> then the text must be zero-terminated.
+ * @param dest A pointer to where the processed text is to be copied.
+ * @param destSize The size of the <code>dest</code> buffer, in number of
+ *        UChars. If the <code>U_SHAPE_LETTERS_UNSHAPE</code> option is set,
+ *        then the destination length could be as large as
+ *        <code>srcLength * 2</code>. Otherwise, the destination length will
+ *        not exceed <code>srcLength</code>. If the caller reserves the last
+ *        position for zero-termination, it should be excluded from
+ *        <code>destSize</code>.
+ *        <p><code>destSize == -1</code> is allowed and makes sense when
+ *        <code>dest</code> was holds some meaningful value, e.g. that of
+ *        <code>src</code>. In this case <code>dest</code> must be
+ *        zero-terminated.</p>
+ * @param inParaLevel A base embedding level of the input as defined in
+ *        <code>ubidi_setPara</code> documentation for the
+ *        <code>paraLevel</code> parameter.
+ * @param inOrder An order of the input, which can be one of the
+ *        <code>UBiDiOrder</code> values.
+ * @param outParaLevel A base embedding level of the output as defined in
+ *        <code>ubidi_setPara</code> documentation for the
+ *        <code>paraLevel</code> parameter.
+ * @param outOrder An order of the output, which can be one of the
+ *        <code>UBiDiOrder</code> values.
+ * @param doMirroring Indicates whether or not to perform character mirroring,
+ *        and can accept one of the <code>UBiDiMirroring</code> values.
+ * @param shapingOptions Arabic digit and letter shaping options defined in the
+ *        ushape.h documentation.
+ *        <p><strong>Note:</strong> Direction indicator options are computed by
+ *        the transformation engine based on the effective ordering schemes, so
+ *        user-defined direction indicators will be ignored.</p>
+ * @param pErrorCode A pointer to an error code value.
+ *
+ * @return The destination length, i.e. the number of UChars written to
+ *         <code>dest</code>. If the transformation fails, the return value
+ *         will be 0 (and the error code will be written to
+ *         <code>pErrorCode</code>).
+ *
+ * @see UBiDiLevel
+ * @see UBiDiOrder
+ * @see UBiDiMirroring
+ * @see ubidi_setPara
+ * @see u_shapeArabic
+ * @stable ICU 58
+ */
+U_CAPI uint32_t U_EXPORT2
+ubiditransform_transform(UBiDiTransform *pBiDiTransform,
+            const UChar *src, int32_t srcLength,
+            UChar *dest, int32_t destSize,
+            UBiDiLevel inParaLevel, UBiDiOrder inOrder,
+            UBiDiLevel outParaLevel, UBiDiOrder outOrder,
+            UBiDiMirroring doMirroring, uint32_t shapingOptions,
+            UErrorCode *pErrorCode);
+
+/**
+ * Allocates a <code>UBiDiTransform</code> object. This object can be reused,
+ * e.g. with different ordering schemes, mirroring or shaping options.<p>
+ * <strong>Note:</strong>The object can only be reused in the same thread.
+ * All other threads should allocate a new <code>UBiDiTransform</code> object
+ * before using it.<p>
+ * Example of usage:<p>
+ * <pre>
+ * \code
+ * UErrorCode errorCode = U_ZERO_ERROR;
+ * // Open a new UBiDiTransform.
+ * UBiDiTransform* transform = ubiditransform_open(&errorCode);
+ * // Run a transformation.
+ * ubiditransform_transform(transform,
+ *          text1, -1, text2, -1,
+ *          UBIDI_RTL, UBIDI_LOGICAL,
+ *          UBIDI_LTR, UBIDI_VISUAL,
+ *          UBIDI_MIRRORING_ON,
+ *          U_SHAPE_DIGITS_EN2AN,
+ *          &errorCode);
+ * // Do something with the output text and invoke another transformation using
+ * //   that text as input.
+ * ubiditransform_transform(transform,
+ *          text2, -1, text3, -1,
+ *          UBIDI_LTR, UBIDI_VISUAL,
+ *          UBIDI_RTL, UBIDI_VISUAL,
+ *          UBIDI_MIRRORING_ON,
+ *          0, &errorCode);
+ *\endcode
+ * </pre>
+ * <p>
+ * The <code>UBiDiTransform</code> object must be deallocated by calling
+ * <code>ubiditransform_close()</code>.
+ *
+ * @return An empty <code>UBiDiTransform</code> object.
+ * @stable ICU 58
+ */
+U_CAPI UBiDiTransform* U_EXPORT2
+ubiditransform_open(UErrorCode *pErrorCode);
+
+/**
+ * Deallocates the given <code>UBiDiTransform</code> object.
+ * @stable ICU 58
+ */
+U_CAPI void U_EXPORT2
+ubiditransform_close(UBiDiTransform *pBidiTransform);
+
+#if U_SHOW_CPLUSPLUS_API
+
+U_NAMESPACE_BEGIN
+
+/**
+ * \class LocalUBiDiTransformPointer
+ * "Smart pointer" class, closes a UBiDiTransform via ubiditransform_close().
+ * For most methods see the LocalPointerBase base class.
+ *
+ * @see LocalPointerBase
+ * @see LocalPointer
+ * @stable ICU 58
+ */
+U_DEFINE_LOCAL_OPEN_POINTER(LocalUBiDiTransformPointer, UBiDiTransform, ubiditransform_close);
+
+U_NAMESPACE_END
+
+#endif
+
+#endif
diff --git a/src/third_party/icu/source/common/unicode/ubrk.h b/src/third_party/icu/source/common/unicode/ubrk.h
index 3c26663..37189a8 100644
--- a/src/third_party/icu/source/common/unicode/ubrk.h
+++ b/src/third_party/icu/source/common/unicode/ubrk.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 * Copyright (C) 1996-2015, International Business Machines Corporation and others.
@@ -11,7 +13,10 @@
 #include "unicode/utypes.h"
 #include "unicode/uloc.h"
 #include "unicode/utext.h"
+
+#if U_SHOW_CPLUSPLUS_API
 #include "unicode/localpointer.h"
+#endif   // U_SHOW_CPLUSPLUS_API
 
 /**
  * A text-break iterator.
@@ -70,7 +75,7 @@
  * "Extended Grapheme Clusters", which are groupings of codepoints
  * that should be treated as character-like units for many text operations.
  * Please see Unicode Standard Annex #29, Unicode Text Segmentation,
- * http://www.unicode.org/reports/tr29/ for additional information 
+ * http://www.unicode.org/reports/tr29/ for additional information
  * on grapheme clusters and guidelines on their use.
  * <p>
  * Title boundary analysis locates all positions,
@@ -114,8 +119,12 @@
    * @deprecated ICU 2.8 Use the word break iterator for titlecasing for Unicode 4 and later.
    */
   UBRK_TITLE = 4,
-#endif /* U_HIDE_DEPRECATED_API */
-  UBRK_COUNT = 5
+    /**
+     * One more than the highest normal UBreakIteratorType value.
+     * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
+     */
+    UBRK_COUNT = 5
+#endif  // U_HIDE_DEPRECATED_API
 } UBreakIteratorType;
 
 /** Value indicating all text boundaries have been returned.
@@ -130,7 +139,10 @@
  *  word, to allow for further subdivisions of a category in future releases.
  *  Applications should check for tag values falling within the range, rather
  *  than for single individual values.
- *  @stable ICU 2.2
+ *
+ * The numeric values of all of these constants are stable (will not change).
+ *
+ * @stable ICU 2.2
 */
 typedef enum UWordBreak {
     /** Tag value for "words" that do not fit into any of other categories.
@@ -163,7 +175,10 @@
  *  word, to allow for further subdivisions of a category in future releases.
  *  Applications should check for tag values falling within the range, rather
  *  than for single individual values.
- *  @stable ICU 2.8
+ *
+ * The numeric values of all of these constants are stable (will not change).
+ *
+ * @stable ICU 2.8
 */
 typedef enum ULineBreakTag {
     /** Tag value for soft line breaks, positions at which a line break
@@ -185,7 +200,10 @@
  *  sentence, to allow for further subdivisions of a category in future releases.
  *  Applications should check for tag values falling within the range, rather
  *  than for single individual values.
- *  @stable ICU 2.8
+ *
+ * The numeric values of all of these constants are stable (will not change).
+ *
+ * @stable ICU 2.8
 */
 typedef enum USentenceBreakTag {
     /** Tag value for for sentences  ending with a sentence terminator
@@ -215,14 +233,15 @@
  * @param locale The locale specifying the text-breaking conventions. Note that
  * locale keys such as "lb" and "ss" may be used to modify text break behavior,
  * see general discussion of BreakIterator C API.
- * @param text The text to be iterated over.
+ * @param text The text to be iterated over. May be null, in which case ubrk_setText() is
+ *        used to specify the text to be iterated.
  * @param textLength The number of characters in text, or -1 if null-terminated.
  * @param status A UErrorCode to receive any errors.
  * @return A UBreakIterator for the specified locale.
  * @see ubrk_openRules
  * @stable ICU 2.0
  */
-U_STABLE UBreakIterator* U_EXPORT2
+U_CAPI UBreakIterator* U_EXPORT2
 ubrk_open(UBreakIteratorType type,
       const char *locale,
       const UChar *text,
@@ -244,7 +263,7 @@
  * @see ubrk_open
  * @stable ICU 2.2
  */
-U_STABLE UBreakIterator* U_EXPORT2
+U_CAPI UBreakIterator* U_EXPORT2
 ubrk_openRules(const UChar     *rules,
                int32_t         rulesLength,
                const UChar     *text,
@@ -253,6 +272,31 @@
                UErrorCode      *status);
 
 /**
+ * Open a new UBreakIterator for locating text boundaries using precompiled binary rules.
+ * Opening a UBreakIterator this way is substantially faster than using ubrk_openRules.
+ * Binary rules may be obtained using ubrk_getBinaryRules. The compiled rules are not
+ * compatible across different major versions of ICU, nor across platforms of different
+ * endianness or different base character set family (ASCII vs EBCDIC).
+ * @param binaryRules A set of compiled binary rules specifying the text breaking
+ *                    conventions. Ownership of the storage containing the compiled
+ *                    rules remains with the caller of this function. The compiled
+ *                    rules must not be modified or deleted during the life of the
+ *                    break iterator.
+ * @param rulesLength The length of binaryRules in bytes; must be >= 0.
+ * @param text        The text to be iterated over.  May be null, in which case
+ *                    ubrk_setText() is used to specify the text to be iterated.
+ * @param textLength  The number of characters in text, or -1 if null-terminated.
+ * @param status      Pointer to UErrorCode to receive any errors.
+ * @return            UBreakIterator for the specified rules.
+ * @see ubrk_getBinaryRules
+ * @stable ICU 59
+ */
+U_CAPI UBreakIterator* U_EXPORT2
+ubrk_openBinaryRules(const uint8_t *binaryRules, int32_t rulesLength,
+                     const UChar *  text, int32_t textLength,
+                     UErrorCode *   status);
+
+/**
  * Thread safe cloning operation
  * @param bi iterator to be cloned
  * @param stackBuffer <em>Deprecated functionality as of ICU 52, use NULL.</em><br>
@@ -270,7 +314,7 @@
  * @return pointer to the new clone
  * @stable ICU 2.0
  */
-U_STABLE UBreakIterator * U_EXPORT2
+U_CAPI UBreakIterator * U_EXPORT2
 ubrk_safeClone(
           const UBreakIterator *bi,
           void *stackBuffer,
@@ -293,7 +337,7 @@
 * @param bi The break iterator to close.
  * @stable ICU 2.0
 */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 ubrk_close(UBreakIterator *bi);
 
 #if U_SHOW_CPLUSPLUS_API
@@ -316,14 +360,18 @@
 #endif
 
 /**
- * Sets an existing iterator to point to a new piece of text
+ * Sets an existing iterator to point to a new piece of text.
+ * The break iterator retains a pointer to the supplied text.
+ * The caller must not modify or delete the text while the BreakIterator
+ * retains the reference.
+ *
  * @param bi The iterator to use
  * @param text The text to be set
  * @param textLength The length of the text
  * @param status The error code
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 ubrk_setText(UBreakIterator* bi,
              const UChar*    text,
              int32_t         textLength,
@@ -347,7 +395,7 @@
  * @param status The error code
  * @stable ICU 3.4
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 ubrk_setUText(UBreakIterator* bi,
              UText*          text,
              UErrorCode*     status);
@@ -362,7 +410,7 @@
  * \ref ubrk_first, or \ref ubrk_last.
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 ubrk_current(const UBreakIterator *bi);
 
 /**
@@ -374,7 +422,7 @@
  * @see ubrk_previous
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 ubrk_next(UBreakIterator *bi);
 
 /**
@@ -386,7 +434,7 @@
  * @see ubrk_next
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 ubrk_previous(UBreakIterator *bi);
 
 /**
@@ -396,7 +444,7 @@
  * @see ubrk_last
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 ubrk_first(UBreakIterator *bi);
 
 /**
@@ -408,7 +456,7 @@
  * @see ubrk_first
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 ubrk_last(UBreakIterator *bi);
 
 /**
@@ -420,7 +468,7 @@
  * @see ubrk_following
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 ubrk_preceding(UBreakIterator *bi,
            int32_t offset);
 
@@ -433,7 +481,7 @@
  * @see ubrk_preceding
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 ubrk_following(UBreakIterator *bi,
            int32_t offset);
 
@@ -446,7 +494,7 @@
 * @see ubrk_countAvailable
 * @stable ICU 2.0
 */
-U_STABLE const char* U_EXPORT2
+U_CAPI const char* U_EXPORT2
 ubrk_getAvailable(int32_t index);
 
 /**
@@ -457,12 +505,12 @@
 * @see ubrk_getAvailable
 * @stable ICU 2.0
 */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 ubrk_countAvailable(void);
 
 
 /**
-* Returns true if the specfied position is a boundary position.  As a side
+* Returns true if the specified position is a boundary position.  As a side
 * effect, leaves the iterator pointing to the first boundary position at
 * or after "offset".
 * @param bi The break iterator to use.
@@ -470,7 +518,7 @@
 * @return True if "offset" is a boundary position.
 * @stable ICU 2.0
 */
-U_STABLE  UBool U_EXPORT2
+U_CAPI  UBool U_EXPORT2
 ubrk_isBoundary(UBreakIterator *bi, int32_t offset);
 
 /**
@@ -482,7 +530,7 @@
  * For word break iterators, the possible values are defined in enum UWordBreak.
  * @stable ICU 2.2
  */
-U_STABLE  int32_t U_EXPORT2
+U_CAPI  int32_t U_EXPORT2
 ubrk_getRuleStatus(UBreakIterator *bi);
 
 /**
@@ -496,13 +544,13 @@
  * @param fillInVec an array to be filled in with the status values.
  * @param capacity  the length of the supplied vector.  A length of zero causes
  *                  the function to return the number of status values, in the
- *                  normal way, without attemtping to store any values.
+ *                  normal way, without attempting to store any values.
  * @param status    receives error codes.
  * @return          The number of rule status values from rules that determined
  *                  the most recent boundary returned by the break iterator.
  * @stable ICU 3.0
  */
-U_STABLE  int32_t U_EXPORT2
+U_CAPI  int32_t U_EXPORT2
 ubrk_getRuleStatusVec(UBreakIterator *bi, int32_t *fillInVec, int32_t capacity, UErrorCode *status);
 
 /**
@@ -514,7 +562,7 @@
  * @return locale string
  * @stable ICU 2.8
  */
-U_STABLE const char* U_EXPORT2
+U_CAPI const char* U_EXPORT2
 ubrk_getLocaleByType(const UBreakIterator *bi, ULocDataLocaleType type, UErrorCode* status);
 
 /**
@@ -542,11 +590,42 @@
   *
   * @stable ICU 49
   */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 ubrk_refreshUText(UBreakIterator *bi,
                        UText          *text,
                        UErrorCode     *status);
 
+
+/**
+ * Get a compiled binary version of the rules specifying the behavior of a UBreakIterator.
+ * The binary rules may be used with ubrk_openBinaryRules to open a new UBreakIterator
+ * more quickly than using ubrk_openRules. The compiled rules are not compatible across
+ * different major versions of ICU, nor across platforms of different endianness or
+ * different base character set family (ASCII vs EBCDIC). Supports preflighting (with
+ * binaryRules=NULL and rulesCapacity=0) to get the rules length without copying them to
+ * the binaryRules buffer. However, whether preflighting or not, if the actual length
+ * is greater than INT32_MAX, then the function returns 0 and sets *status to
+ * U_INDEX_OUTOFBOUNDS_ERROR.
+
+ * @param bi            The break iterator to use.
+ * @param binaryRules   Buffer to receive the compiled binary rules; set to NULL for
+ *                      preflighting.
+ * @param rulesCapacity Capacity (in bytes) of the binaryRules buffer; set to 0 for
+ *                      preflighting. Must be >= 0.
+ * @param status        Pointer to UErrorCode to receive any errors, such as
+ *                      U_BUFFER_OVERFLOW_ERROR, U_INDEX_OUTOFBOUNDS_ERROR, or
+ *                      U_ILLEGAL_ARGUMENT_ERROR.
+ * @return              The actual byte length of the binary rules, if <= INT32_MAX;
+ *                      otherwise 0. If not preflighting and this is larger than
+ *                      rulesCapacity, *status will be set to an error.
+ * @see ubrk_openBinaryRules
+ * @stable ICU 59
+ */
+U_CAPI int32_t U_EXPORT2
+ubrk_getBinaryRules(UBreakIterator *bi,
+                    uint8_t *       binaryRules, int32_t rulesCapacity,
+                    UErrorCode *    status);
+
 #endif /* #if !UCONFIG_NO_BREAK_ITERATION */
 
 #endif
diff --git a/src/third_party/icu/source/common/unicode/ucasemap.h b/src/third_party/icu/source/common/unicode/ucasemap.h
index b37e165..d1c1b48 100644
--- a/src/third_party/icu/source/common/unicode/ucasemap.h
+++ b/src/third_party/icu/source/common/unicode/ucasemap.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  ucasemap.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -20,8 +22,12 @@
 #define __UCASEMAP_H__
 
 #include "unicode/utypes.h"
+#include "unicode/stringoptions.h"
 #include "unicode/ustring.h"
+
+#if U_SHOW_CPLUSPLUS_API
 #include "unicode/localpointer.h"
+#endif   // U_SHOW_CPLUSPLUS_API
 
 /**
  * \file
@@ -66,7 +72,7 @@
  * @see U_TITLECASE_NO_BREAK_ADJUSTMENT
  * @stable ICU 3.4
  */
-U_STABLE UCaseMap * U_EXPORT2
+U_CAPI UCaseMap * U_EXPORT2
 ucasemap_open(const char *locale, uint32_t options, UErrorCode *pErrorCode);
 
 /**
@@ -74,7 +80,7 @@
  * @param csm Object to be closed.
  * @stable ICU 3.4
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 ucasemap_close(UCaseMap *csm);
 
 #if U_SHOW_CPLUSPLUS_API
@@ -102,7 +108,7 @@
  * @return locale ID
  * @stable ICU 3.4
  */
-U_STABLE const char * U_EXPORT2
+U_CAPI const char * U_EXPORT2
 ucasemap_getLocale(const UCaseMap *csm);
 
 /**
@@ -111,7 +117,7 @@
  * @return options bit set
  * @stable ICU 3.4
  */
-U_STABLE uint32_t U_EXPORT2
+U_CAPI uint32_t U_EXPORT2
 ucasemap_getOptions(const UCaseMap *csm);
 
 /**
@@ -125,7 +131,7 @@
  * @see ucasemap_open
  * @stable ICU 3.4
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 ucasemap_setLocale(UCaseMap *csm, const char *locale, UErrorCode *pErrorCode);
 
 /**
@@ -139,50 +145,9 @@
  * @see ucasemap_open
  * @stable ICU 3.4
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 ucasemap_setOptions(UCaseMap *csm, uint32_t options, UErrorCode *pErrorCode);
 
-/**
- * Do not lowercase non-initial parts of words when titlecasing.
- * Option bit for titlecasing APIs that take an options bit set.
- *
- * By default, titlecasing will titlecase the first cased character
- * of a word and lowercase all other characters.
- * With this option, the other characters will not be modified.
- *
- * @see ucasemap_setOptions
- * @see ucasemap_toTitle
- * @see ucasemap_utf8ToTitle
- * @see UnicodeString::toTitle
- * @stable ICU 3.8
- */
-#define U_TITLECASE_NO_LOWERCASE 0x100
-
-/**
- * Do not adjust the titlecasing indexes from BreakIterator::next() indexes;
- * titlecase exactly the characters at breaks from the iterator.
- * Option bit for titlecasing APIs that take an options bit set.
- *
- * By default, titlecasing will take each break iterator index,
- * adjust it by looking for the next cased character, and titlecase that one.
- * Other characters are lowercased.
- *
- * This follows Unicode 4 & 5 section 3.13 Default Case Operations:
- *
- * R3  toTitlecase(X): Find the word boundaries based on Unicode Standard Annex
- * #29, "Text Boundaries." Between each pair of word boundaries, find the first
- * cased character F. If F exists, map F to default_title(F); then map each
- * subsequent character C to default_lower(C).
- *
- * @see ucasemap_setOptions
- * @see ucasemap_toTitle
- * @see ucasemap_utf8ToTitle
- * @see UnicodeString::toTitle
- * @see U_TITLECASE_NO_LOWERCASE
- * @stable ICU 3.8
- */
-#define U_TITLECASE_NO_BREAK_ADJUSTMENT 0x200
-
 #if !UCONFIG_NO_BREAK_ITERATION
 
 /**
@@ -192,7 +157,7 @@
  * @return titlecasing break iterator
  * @stable ICU 3.8
  */
-U_STABLE const UBreakIterator * U_EXPORT2
+U_CAPI const UBreakIterator * U_EXPORT2
 ucasemap_getBreakIterator(const UCaseMap *csm);
 
 /**
@@ -215,7 +180,7 @@
  * @see ucasemap_utf8ToTitle
  * @stable ICU 3.8
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 ucasemap_setBreakIterator(UCaseMap *csm, UBreakIterator *iterToAdopt, UErrorCode *pErrorCode);
 
 /**
@@ -240,7 +205,7 @@
  * The standard titlecase iterator for the root locale implements the
  * algorithm of Unicode TR 21.
  *
- * This function uses only the setUText(), first(), next() and close() methods of the
+ * This function uses only the setText(), first() and next() methods of the
  * provided break iterator.
  *
  * The result may be longer or shorter than the original.
@@ -251,7 +216,7 @@
  * @param dest      A buffer for the result string. The result will be NUL-terminated if
  *                  the buffer is large enough.
  *                  The contents is undefined in case of failure.
- * @param destCapacity The size of the buffer (number of bytes). If it is 0, then
+ * @param destCapacity The size of the buffer (number of UChars). If it is 0, then
  *                  dest may be NULL and the function will only return the length of the result
  *                  without writing any of the result string.
  * @param src       The original string.
@@ -264,13 +229,13 @@
  * @see u_strToTitle
  * @stable ICU 3.8
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 ucasemap_toTitle(UCaseMap *csm,
                  UChar *dest, int32_t destCapacity,
                  const UChar *src, int32_t srcLength,
                  UErrorCode *pErrorCode);
 
-#endif
+#endif  // UCONFIG_NO_BREAK_ITERATION
 
 /**
  * Lowercase the characters in a UTF-8 string.
@@ -295,7 +260,7 @@
  * @see u_strToLower
  * @stable ICU 3.4
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 ucasemap_utf8ToLower(const UCaseMap *csm,
                      char *dest, int32_t destCapacity,
                      const char *src, int32_t srcLength,
@@ -324,7 +289,7 @@
  * @see u_strToUpper
  * @stable ICU 3.4
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 ucasemap_utf8ToUpper(const UCaseMap *csm,
                      char *dest, int32_t destCapacity,
                      const char *src, int32_t srcLength,
@@ -376,7 +341,7 @@
  * @see U_TITLECASE_NO_BREAK_ADJUSTMENT
  * @stable ICU 3.8
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 ucasemap_utf8ToTitle(UCaseMap *csm,
                     char *dest, int32_t destCapacity,
                     const char *src, int32_t srcLength,
@@ -414,7 +379,7 @@
  * @see U_FOLD_CASE_EXCLUDE_SPECIAL_I
  * @stable ICU 3.8
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 ucasemap_utf8FoldCase(const UCaseMap *csm,
                       char *dest, int32_t destCapacity,
                       const char *src, int32_t srcLength,
diff --git a/src/third_party/icu/source/common/unicode/ucat.h b/src/third_party/icu/source/common/unicode/ucat.h
index ad9f037..9385034 100644
--- a/src/third_party/icu/source/common/unicode/ucat.h
+++ b/src/third_party/icu/source/common/unicode/ucat.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
 * Copyright (c) 2003-2004, International Business Machines
@@ -101,7 +103,7 @@
  * 
  * @stable ICU 2.6
  */
-U_STABLE u_nl_catd U_EXPORT2
+U_CAPI u_nl_catd U_EXPORT2
 u_catopen(const char* name, const char* locale, UErrorCode* ec);
 
 /**
@@ -112,7 +114,7 @@
  * 
  * @stable ICU 2.6
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 u_catclose(u_nl_catd catd);
 
 /**
@@ -147,7 +149,7 @@
  * 
  * @stable ICU 2.6
  */
-U_STABLE const UChar* U_EXPORT2
+U_CAPI const UChar* U_EXPORT2
 u_catgets(u_nl_catd catd, int32_t set_num, int32_t msg_num,
           const UChar* s,
           int32_t* len, UErrorCode* ec);
diff --git a/src/third_party/icu/source/common/unicode/uchar.h b/src/third_party/icu/source/common/unicode/uchar.h
index 1836f92..1e0f82e 100644
--- a/src/third_party/icu/source/common/unicode/uchar.h
+++ b/src/third_party/icu/source/common/unicode/uchar.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
 *   Copyright (C) 1997-2016, International Business Machines
@@ -24,6 +26,25 @@
 #define UCHAR_H
 
 #include "unicode/utypes.h"
+#include "unicode/stringoptions.h"
+#include "unicode/ucpmap.h"
+
+#if !defined(USET_DEFINED) && !defined(U_IN_DOXYGEN)
+
+#define USET_DEFINED
+
+/**
+ * USet is the C API type corresponding to C++ class UnicodeSet.
+ * It is forward-declared here to avoid including unicode/uset.h file if related
+ * APIs are not used.
+ *
+ * @see ucnv_getUnicodeSet
+ * @stable ICU 2.4
+ */
+typedef struct USet USet;
+
+#endif
+
 
 U_CDECL_BEGIN
 
@@ -39,7 +60,7 @@
  * @see u_getUnicodeVersion
  * @stable ICU 2.0
  */
-#define U_UNICODE_VERSION "8.0"
+#define U_UNICODE_VERSION "13.0"
 
 /**
  * \file
@@ -58,6 +79,18 @@
  * "About the Unicode Character Database" (http://www.unicode.org/ucd/)
  * and the ICU User Guide chapter on Properties (http://icu-project.org/userguide/properties.html).
  *
+ * Many properties are accessible via generic functions that take a UProperty selector.
+ * - u_hasBinaryProperty() returns a binary value (true/false) per property and code point.
+ * - u_getIntPropertyValue() returns an integer value per property and code point.
+ *   For each supported enumerated or catalog property, there is
+ *   an enum type for all of the property's values, and
+ *   u_getIntPropertyValue() returns the numeric values of those constants.
+ * - u_getBinaryPropertySet() returns a set for each ICU-supported binary property with
+ *   all code points for which the property is true.
+ * - u_getIntPropertyMap() returns a map for each
+ *   ICU-supported enumerated/catalog/int-valued property which
+ *   maps all Unicode code points to their values for that property.
+ *
  * Many functions are designed to match java.lang.Character functions.
  * See the individual function documentation,
  * and see the JDK 1.4 java.lang.Character documentation
@@ -109,11 +142,11 @@
  * Comparison:
  * - u_isUWhiteSpace=UCHAR_WHITE_SPACE: Unicode White_Space property;
  *       most of general categories "Z" (separators) + most whitespace ISO controls
- *       (including no-break spaces, but excluding IS1..IS4 and ZWSP)
+ *       (including no-break spaces, but excluding IS1..IS4)
  * - u_isWhitespace: Java isWhitespace; Z + whitespace ISO controls but excluding no-break spaces
  * - u_isJavaSpaceChar: Java isSpaceChar; just Z (including no-break spaces)
  * - u_isspace: Z + whitespace ISO controls (including no-break spaces)
- * - u_isblank: "horizontal spaces" = TAB + Zs - ZWSP
+ * - u_isblank: "horizontal spaces" = TAB + Zs
  */
 
 /**
@@ -146,8 +179,9 @@
  *
  * The properties APIs are intended to reflect Unicode properties as defined
  * in the Unicode Character Database (UCD) and Unicode Technical Reports (UTR).
- * For details about the properties see http://www.unicode.org/ucd/ .
- * For names of Unicode properties see the UCD file PropertyAliases.txt.
+ *
+ * For details about the properties see
+ * UAX #44: Unicode Character Database (http://www.unicode.org/reports/tr44/).
  *
  * Important: If ICU is built with UCD files from Unicode versions below, e.g., 3.2,
  * then properties marked with "new in Unicode 3.2" are not or not fully available.
@@ -401,32 +435,61 @@
      * Binary property Emoji.
      * See http://www.unicode.org/reports/tr51/#Emoji_Properties
      *
-     * @draft ICU 57
+     * @stable ICU 57
      */
     UCHAR_EMOJI=57,
     /**
      * Binary property Emoji_Presentation.
      * See http://www.unicode.org/reports/tr51/#Emoji_Properties
      *
-     * @draft ICU 57
+     * @stable ICU 57
      */
     UCHAR_EMOJI_PRESENTATION=58,
     /**
      * Binary property Emoji_Modifier.
      * See http://www.unicode.org/reports/tr51/#Emoji_Properties
      *
-     * @draft ICU 57
+     * @stable ICU 57
      */
     UCHAR_EMOJI_MODIFIER=59,
     /**
      * Binary property Emoji_Modifier_Base.
      * See http://www.unicode.org/reports/tr51/#Emoji_Properties
      *
-     * @draft ICU 57
+     * @stable ICU 57
      */
     UCHAR_EMOJI_MODIFIER_BASE=60,
-    /** One more than the last constant for binary Unicode properties. @stable ICU 2.1 */
-    UCHAR_BINARY_LIMIT=61,
+    /**
+     * Binary property Emoji_Component.
+     * See http://www.unicode.org/reports/tr51/#Emoji_Properties
+     *
+     * @stable ICU 60
+     */
+    UCHAR_EMOJI_COMPONENT=61,
+    /**
+     * Binary property Regional_Indicator.
+     * @stable ICU 60
+     */
+    UCHAR_REGIONAL_INDICATOR=62,
+    /**
+     * Binary property Prepended_Concatenation_Mark.
+     * @stable ICU 60
+     */
+    UCHAR_PREPENDED_CONCATENATION_MARK=63,
+    /**
+     * Binary property Extended_Pictographic.
+     * See http://www.unicode.org/reports/tr51/#Emoji_Properties
+     *
+     * @stable ICU 62
+     */
+    UCHAR_EXTENDED_PICTOGRAPHIC=64,
+#ifndef U_HIDE_DEPRECATED_API
+    /**
+     * One more than the last constant for binary Unicode properties.
+     * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
+     */
+    UCHAR_BINARY_LIMIT,
+#endif  // U_HIDE_DEPRECATED_API
 
     /** Enumerated property Bidi_Class.
         Same as u_charDirection, returns UCharDirection values. @stable ICU 2.2 */
@@ -513,8 +576,35 @@
         (http://www.unicode.org/reports/tr9/)
         Returns UBidiPairedBracketType values. @stable ICU 52 */
     UCHAR_BIDI_PAIRED_BRACKET_TYPE=0x1015,
-    /** One more than the last constant for enumerated/integer Unicode properties. @stable ICU 2.2 */
-    UCHAR_INT_LIMIT=0x1016,
+    /**
+     * Enumerated property Indic_Positional_Category.
+     * New in Unicode 6.0 as provisional property Indic_Matra_Category;
+     * renamed and changed to informative in Unicode 8.0.
+     * See http://www.unicode.org/reports/tr44/#IndicPositionalCategory.txt
+     * @stable ICU 63
+     */
+    UCHAR_INDIC_POSITIONAL_CATEGORY=0x1016,
+    /**
+     * Enumerated property Indic_Syllabic_Category.
+     * New in Unicode 6.0 as provisional; informative since Unicode 8.0.
+     * See http://www.unicode.org/reports/tr44/#IndicSyllabicCategory.txt
+     * @stable ICU 63
+     */
+    UCHAR_INDIC_SYLLABIC_CATEGORY=0x1017,
+    /**
+     * Enumerated property Vertical_Orientation.
+     * Used for UAX #50 Unicode Vertical Text Layout (https://www.unicode.org/reports/tr50/).
+     * New as a UCD property in Unicode 10.0.
+     * @stable ICU 63
+     */
+    UCHAR_VERTICAL_ORIENTATION=0x1018,
+#ifndef U_HIDE_DEPRECATED_API
+    /**
+     * One more than the last constant for enumerated/integer Unicode properties.
+     * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
+     */
+    UCHAR_INT_LIMIT=0x1019,
+#endif  // U_HIDE_DEPRECATED_API
 
     /** Bitmask property General_Category_Mask.
         This is the General_Category property returned as a bit mask.
@@ -527,16 +617,26 @@
     UCHAR_GENERAL_CATEGORY_MASK=0x2000,
     /** First constant for bit-mask Unicode properties. @stable ICU 2.4 */
     UCHAR_MASK_START=UCHAR_GENERAL_CATEGORY_MASK,
-    /** One more than the last constant for bit-mask Unicode properties. @stable ICU 2.4 */
+#ifndef U_HIDE_DEPRECATED_API
+    /**
+     * One more than the last constant for bit-mask Unicode properties.
+     * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
+     */
     UCHAR_MASK_LIMIT=0x2001,
+#endif  // U_HIDE_DEPRECATED_API
 
     /** Double property Numeric_Value.
         Corresponds to u_getNumericValue. @stable ICU 2.4 */
     UCHAR_NUMERIC_VALUE=0x3000,
     /** First constant for double Unicode properties. @stable ICU 2.4 */
     UCHAR_DOUBLE_START=UCHAR_NUMERIC_VALUE,
-    /** One more than the last constant for double Unicode properties. @stable ICU 2.4 */
+#ifndef U_HIDE_DEPRECATED_API
+    /**
+     * One more than the last constant for double Unicode properties.
+     * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
+     */
     UCHAR_DOUBLE_LIMIT=0x3001,
+#endif  // U_HIDE_DEPRECATED_API
 
     /** String property Age.
         Corresponds to u_charAge. @stable ICU 2.4 */
@@ -588,8 +688,13 @@
     /** String property Bidi_Paired_Bracket (new in Unicode 6.3).
         Corresponds to u_getBidiPairedBracket. @stable ICU 52 */
     UCHAR_BIDI_PAIRED_BRACKET=0x400D,
-    /** One more than the last constant for string Unicode properties. @stable ICU 2.4 */
+#ifndef U_HIDE_DEPRECATED_API
+    /**
+     * One more than the last constant for string Unicode properties.
+     * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
+     */
     UCHAR_STRING_LIMIT=0x400E,
+#endif  // U_HIDE_DEPRECATED_API
 
     /** Miscellaneous property Script_Extensions (new in Unicode 6.0).
         Some characters are commonly used in multiple scripts.
@@ -599,9 +704,14 @@
     UCHAR_SCRIPT_EXTENSIONS=0x7000,
     /** First constant for Unicode properties with unusual value types. @stable ICU 4.6 */
     UCHAR_OTHER_PROPERTY_START=UCHAR_SCRIPT_EXTENSIONS,
-    /** One more than the last constant for Unicode properties with unusual value types.
-     * @stable ICU 4.6 */
+#ifndef U_HIDE_DEPRECATED_API
+    /**
+     * One more than the last constant for Unicode properties with unusual value types.
+     * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
+     */
     UCHAR_OTHER_PROPERTY_LIMIT=0x7001,
+#endif  // U_HIDE_DEPRECATED_API
+
     /** Represents a nonexistent or invalid property or property value. @stable ICU 2.4 */
     UCHAR_INVALID_CODE = -1
 } UProperty;
@@ -682,7 +792,13 @@
     U_INITIAL_PUNCTUATION     = 28,
     /** Pf @stable ICU 2.0 */
     U_FINAL_PUNCTUATION       = 29,
-    /** One higher than the last enum UCharCategory constant. @stable ICU 2.0 */
+    /**
+     * One higher than the last enum UCharCategory constant.
+     * This numeric value is stable (will not change), see
+     * http://www.unicode.org/policies/stability_policy.html#Property_Value
+     *
+     * @stable ICU 2.0
+     */
     U_CHAR_CATEGORY_COUNT
 } UCharCategory;
 
@@ -856,8 +972,15 @@
     U_RIGHT_TO_LEFT_ISOLATE       = 21,
     /** PDI @stable ICU 52 */
     U_POP_DIRECTIONAL_ISOLATE     = 22,
-    /** @stable ICU 2.0 */
+#ifndef U_HIDE_DEPRECATED_API
+    /**
+     * One more than the highest UCharDirection value.
+     * The highest value is available via u_getIntPropertyMaxValue(UCHAR_BIDI_CLASS).
+     *
+     * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
+     */
     U_CHAR_DIRECTION_COUNT
+#endif  // U_HIDE_DEPRECATED_API
 } UCharDirection;
 
 /**
@@ -879,8 +1002,15 @@
     U_BPT_OPEN,
     /** Close paired bracket. @stable ICU 52 */
     U_BPT_CLOSE,
-    /** @stable ICU 52 */
+#ifndef U_HIDE_DEPRECATED_API
+    /**
+     * One more than the highest normal UBidiPairedBracketType value.
+     * The highest value is available via u_getIntPropertyMaxValue(UCHAR_BIDI_PAIRED_BRACKET_TYPE).
+     *
+     * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
+     */
     U_BPT_COUNT /* 3 */
+#endif  // U_HIDE_DEPRECATED_API
 } UBidiPairedBracketType;
 
 /**
@@ -1211,7 +1341,7 @@
      * Unicode 4.0.1 renames the "Cyrillic Supplementary" block to "Cyrillic Supplement".
      * @stable ICU 2.2
      */
-    UBLOCK_CYRILLIC_SUPPLEMENTARY = UBLOCK_CYRILLIC_SUPPLEMENT, 
+    UBLOCK_CYRILLIC_SUPPLEMENTARY = UBLOCK_CYRILLIC_SUPPLEMENT,
     /** @stable ICU 2.2 */
     UBLOCK_TAGALOG = 98, /*[1700]*/
     /** @stable ICU 2.2 */
@@ -1570,8 +1700,122 @@
     /** @stable ICU 56 */
     UBLOCK_SUTTON_SIGNWRITING = 262, /*[1D800]*/
 
-    /** @stable ICU 2.0 */
-    UBLOCK_COUNT = 263,
+    /* New blocks in Unicode 9.0 */
+
+    /** @stable ICU 58 */
+    UBLOCK_ADLAM = 263, /*[1E900]*/
+    /** @stable ICU 58 */
+    UBLOCK_BHAIKSUKI = 264, /*[11C00]*/
+    /** @stable ICU 58 */
+    UBLOCK_CYRILLIC_EXTENDED_C = 265, /*[1C80]*/
+    /** @stable ICU 58 */
+    UBLOCK_GLAGOLITIC_SUPPLEMENT = 266, /*[1E000]*/
+    /** @stable ICU 58 */
+    UBLOCK_IDEOGRAPHIC_SYMBOLS_AND_PUNCTUATION = 267, /*[16FE0]*/
+    /** @stable ICU 58 */
+    UBLOCK_MARCHEN = 268, /*[11C70]*/
+    /** @stable ICU 58 */
+    UBLOCK_MONGOLIAN_SUPPLEMENT = 269, /*[11660]*/
+    /** @stable ICU 58 */
+    UBLOCK_NEWA = 270, /*[11400]*/
+    /** @stable ICU 58 */
+    UBLOCK_OSAGE = 271, /*[104B0]*/
+    /** @stable ICU 58 */
+    UBLOCK_TANGUT = 272, /*[17000]*/
+    /** @stable ICU 58 */
+    UBLOCK_TANGUT_COMPONENTS = 273, /*[18800]*/
+
+    // New blocks in Unicode 10.0
+
+    /** @stable ICU 60 */
+    UBLOCK_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_F = 274, /*[2CEB0]*/
+    /** @stable ICU 60 */
+    UBLOCK_KANA_EXTENDED_A = 275, /*[1B100]*/
+    /** @stable ICU 60 */
+    UBLOCK_MASARAM_GONDI = 276, /*[11D00]*/
+    /** @stable ICU 60 */
+    UBLOCK_NUSHU = 277, /*[1B170]*/
+    /** @stable ICU 60 */
+    UBLOCK_SOYOMBO = 278, /*[11A50]*/
+    /** @stable ICU 60 */
+    UBLOCK_SYRIAC_SUPPLEMENT = 279, /*[0860]*/
+    /** @stable ICU 60 */
+    UBLOCK_ZANABAZAR_SQUARE = 280, /*[11A00]*/
+
+    // New blocks in Unicode 11.0
+
+    /** @stable ICU 62 */
+    UBLOCK_CHESS_SYMBOLS = 281, /*[1FA00]*/
+    /** @stable ICU 62 */
+    UBLOCK_DOGRA = 282, /*[11800]*/
+    /** @stable ICU 62 */
+    UBLOCK_GEORGIAN_EXTENDED = 283, /*[1C90]*/
+    /** @stable ICU 62 */
+    UBLOCK_GUNJALA_GONDI = 284, /*[11D60]*/
+    /** @stable ICU 62 */
+    UBLOCK_HANIFI_ROHINGYA = 285, /*[10D00]*/
+    /** @stable ICU 62 */
+    UBLOCK_INDIC_SIYAQ_NUMBERS = 286, /*[1EC70]*/
+    /** @stable ICU 62 */
+    UBLOCK_MAKASAR = 287, /*[11EE0]*/
+    /** @stable ICU 62 */
+    UBLOCK_MAYAN_NUMERALS = 288, /*[1D2E0]*/
+    /** @stable ICU 62 */
+    UBLOCK_MEDEFAIDRIN = 289, /*[16E40]*/
+    /** @stable ICU 62 */
+    UBLOCK_OLD_SOGDIAN = 290, /*[10F00]*/
+    /** @stable ICU 62 */
+    UBLOCK_SOGDIAN = 291, /*[10F30]*/
+
+    // New blocks in Unicode 12.0
+
+    /** @stable ICU 64 */
+    UBLOCK_EGYPTIAN_HIEROGLYPH_FORMAT_CONTROLS = 292, /*[13430]*/
+    /** @stable ICU 64 */
+    UBLOCK_ELYMAIC = 293, /*[10FE0]*/
+    /** @stable ICU 64 */
+    UBLOCK_NANDINAGARI = 294, /*[119A0]*/
+    /** @stable ICU 64 */
+    UBLOCK_NYIAKENG_PUACHUE_HMONG = 295, /*[1E100]*/
+    /** @stable ICU 64 */
+    UBLOCK_OTTOMAN_SIYAQ_NUMBERS = 296, /*[1ED00]*/
+    /** @stable ICU 64 */
+    UBLOCK_SMALL_KANA_EXTENSION = 297, /*[1B130]*/
+    /** @stable ICU 64 */
+    UBLOCK_SYMBOLS_AND_PICTOGRAPHS_EXTENDED_A = 298, /*[1FA70]*/
+    /** @stable ICU 64 */
+    UBLOCK_TAMIL_SUPPLEMENT = 299, /*[11FC0]*/
+    /** @stable ICU 64 */
+    UBLOCK_WANCHO = 300, /*[1E2C0]*/
+
+    // New blocks in Unicode 13.0
+
+    /** @stable ICU 66 */
+    UBLOCK_CHORASMIAN = 301, /*[10FB0]*/
+    /** @stable ICU 66 */
+    UBLOCK_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_G = 302, /*[30000]*/
+    /** @stable ICU 66 */
+    UBLOCK_DIVES_AKURU = 303, /*[11900]*/
+    /** @stable ICU 66 */
+    UBLOCK_KHITAN_SMALL_SCRIPT = 304, /*[18B00]*/
+    /** @stable ICU 66 */
+    UBLOCK_LISU_SUPPLEMENT = 305, /*[11FB0]*/
+    /** @stable ICU 66 */
+    UBLOCK_SYMBOLS_FOR_LEGACY_COMPUTING = 306, /*[1FB00]*/
+    /** @stable ICU 66 */
+    UBLOCK_TANGUT_SUPPLEMENT = 307, /*[18D00]*/
+    /** @stable ICU 66 */
+    UBLOCK_YEZIDI = 308, /*[10E80]*/
+
+#ifndef U_HIDE_DEPRECATED_API
+    /**
+     * One more than the highest normal UBlockCode value.
+     * The highest value is available via u_getIntPropertyMaxValue(UCHAR_BLOCK).
+     *
+     * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
+     */
+    UBLOCK_COUNT = 309,
+#endif  // U_HIDE_DEPRECATED_API
 
     /** @stable ICU 2.0 */
     UBLOCK_INVALID_CODE=-1
@@ -1600,7 +1844,15 @@
     U_EA_FULLWIDTH, /*[F]*/
     U_EA_NARROW,    /*[Na]*/
     U_EA_WIDE,      /*[W]*/
+#ifndef U_HIDE_DEPRECATED_API
+    /**
+     * One more than the highest normal UEastAsianWidth value.
+     * The highest value is available via u_getIntPropertyMaxValue(UCHAR_EAST_ASIAN_WIDTH).
+     *
+     * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
+     */
     U_EA_COUNT
+#endif  // U_HIDE_DEPRECATED_API
 } UEastAsianWidth;
 
 /**
@@ -1617,7 +1869,7 @@
 typedef enum UCharNameChoice {
     /** Unicode character name (Name property). @stable ICU 2.0 */
     U_UNICODE_CHAR_NAME,
-#ifndef U_HIDE_DEPRECATED_API 
+#ifndef U_HIDE_DEPRECATED_API
     /**
      * The Unicode_1_Name property value which is of little practical value.
      * Beginning with ICU 49, ICU APIs return an empty string for this name choice.
@@ -1629,8 +1881,13 @@
     U_EXTENDED_CHAR_NAME = U_UNICODE_CHAR_NAME+2,
     /** Corrected name from NameAliases.txt. @stable ICU 4.4 */
     U_CHAR_NAME_ALIAS,
-    /** @stable ICU 2.0 */
+#ifndef U_HIDE_DEPRECATED_API
+    /**
+     * One more than the highest normal UCharNameChoice value.
+     * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
+     */
     U_CHAR_NAME_CHOICE_COUNT
+#endif  // U_HIDE_DEPRECATED_API
 } UCharNameChoice;
 
 /**
@@ -1649,7 +1906,13 @@
 typedef enum UPropertyNameChoice {
     U_SHORT_PROPERTY_NAME,
     U_LONG_PROPERTY_NAME,
+#ifndef U_HIDE_DEPRECATED_API
+    /**
+     * One more than the highest normal UPropertyNameChoice value.
+     * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
+     */
     U_PROPERTY_NAME_CHOICE_COUNT
+#endif  // U_HIDE_DEPRECATED_API
 } UPropertyNameChoice;
 
 /**
@@ -1683,7 +1946,15 @@
     U_DT_SUPER,             /*[sup]*/
     U_DT_VERTICAL,          /*[vert]*/
     U_DT_WIDE,              /*[wide]*/
+#ifndef U_HIDE_DEPRECATED_API
+    /**
+     * One more than the highest normal UDecompositionType value.
+     * The highest value is available via u_getIntPropertyMaxValue(UCHAR_DECOMPOSITION_TYPE).
+     *
+     * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
+     */
     U_DT_COUNT /* 18 */
+#endif  // U_HIDE_DEPRECATED_API
 } UDecompositionType;
 
 /**
@@ -1705,7 +1976,15 @@
     U_JT_LEFT_JOINING,      /*[L]*/
     U_JT_RIGHT_JOINING,     /*[R]*/
     U_JT_TRANSPARENT,       /*[T]*/
+#ifndef U_HIDE_DEPRECATED_API
+    /**
+     * One more than the highest normal UJoiningType value.
+     * The highest value is available via u_getIntPropertyMaxValue(UCHAR_JOINING_TYPE).
+     *
+     * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
+     */
     U_JT_COUNT /* 6 */
+#endif  // U_HIDE_DEPRECATED_API
 } UJoiningType;
 
 /**
@@ -1808,7 +2087,34 @@
     U_JG_MANICHAEAN_YODH,  /**< @stable ICU 54 */
     U_JG_MANICHAEAN_ZAYIN,  /**< @stable ICU 54 */
     U_JG_STRAIGHT_WAW,  /**< @stable ICU 54 */
+    U_JG_AFRICAN_FEH,  /**< @stable ICU 58 */
+    U_JG_AFRICAN_NOON,  /**< @stable ICU 58 */
+    U_JG_AFRICAN_QAF,  /**< @stable ICU 58 */
+
+    U_JG_MALAYALAM_BHA,  /**< @stable ICU 60 */
+    U_JG_MALAYALAM_JA,  /**< @stable ICU 60 */
+    U_JG_MALAYALAM_LLA,  /**< @stable ICU 60 */
+    U_JG_MALAYALAM_LLLA,  /**< @stable ICU 60 */
+    U_JG_MALAYALAM_NGA,  /**< @stable ICU 60 */
+    U_JG_MALAYALAM_NNA,  /**< @stable ICU 60 */
+    U_JG_MALAYALAM_NNNA,  /**< @stable ICU 60 */
+    U_JG_MALAYALAM_NYA,  /**< @stable ICU 60 */
+    U_JG_MALAYALAM_RA,  /**< @stable ICU 60 */
+    U_JG_MALAYALAM_SSA,  /**< @stable ICU 60 */
+    U_JG_MALAYALAM_TTA,  /**< @stable ICU 60 */
+
+    U_JG_HANIFI_ROHINGYA_KINNA_YA,  /**< @stable ICU 62 */
+    U_JG_HANIFI_ROHINGYA_PA,  /**< @stable ICU 62 */
+
+#ifndef U_HIDE_DEPRECATED_API
+    /**
+     * One more than the highest normal UJoiningGroup value.
+     * The highest value is available via u_getIntPropertyMaxValue(UCHAR_JOINING_GROUP).
+     *
+     * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
+     */
     U_JG_COUNT
+#endif  // U_HIDE_DEPRECATED_API
 } UJoiningGroup;
 
 /**
@@ -1834,10 +2140,32 @@
     U_GCB_LVT = 7,              /*[LVT]*/
     U_GCB_T = 8,                /*[T]*/
     U_GCB_V = 9,                /*[V]*/
+    /** @stable ICU 4.0 */
     U_GCB_SPACING_MARK = 10,    /*[SM]*/ /* from here on: new in Unicode 5.1/ICU 4.0 */
+    /** @stable ICU 4.0 */
     U_GCB_PREPEND = 11,         /*[PP]*/
+    /** @stable ICU 50 */
     U_GCB_REGIONAL_INDICATOR = 12,  /*[RI]*/ /* new in Unicode 6.2/ICU 50 */
-    U_GCB_COUNT = 13
+    /** @stable ICU 58 */
+    U_GCB_E_BASE = 13,          /*[EB]*/ /* from here on: new in Unicode 9.0/ICU 58 */
+    /** @stable ICU 58 */
+    U_GCB_E_BASE_GAZ = 14,      /*[EBG]*/
+    /** @stable ICU 58 */
+    U_GCB_E_MODIFIER = 15,      /*[EM]*/
+    /** @stable ICU 58 */
+    U_GCB_GLUE_AFTER_ZWJ = 16,  /*[GAZ]*/
+    /** @stable ICU 58 */
+    U_GCB_ZWJ = 17,             /*[ZWJ]*/
+
+#ifndef U_HIDE_DEPRECATED_API
+    /**
+     * One more than the highest normal UGraphemeClusterBreak value.
+     * The highest value is available via u_getIntPropertyMaxValue(UCHAR_GRAPHEME_CLUSTER_BREAK).
+     *
+     * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
+     */
+    U_GCB_COUNT = 18
+#endif  // U_HIDE_DEPRECATED_API
 } UGraphemeClusterBreak;
 
 /**
@@ -1862,16 +2190,46 @@
     U_WB_MIDNUM = 5,            /*[MN]*/
     U_WB_NUMERIC = 6,           /*[NU]*/
     U_WB_EXTENDNUMLET = 7,      /*[EX]*/
+    /** @stable ICU 4.0 */
     U_WB_CR = 8,                /*[CR]*/ /* from here on: new in Unicode 5.1/ICU 4.0 */
+    /** @stable ICU 4.0 */
     U_WB_EXTEND = 9,            /*[Extend]*/
+    /** @stable ICU 4.0 */
     U_WB_LF = 10,               /*[LF]*/
+    /** @stable ICU 4.0 */
     U_WB_MIDNUMLET =11,         /*[MB]*/
+    /** @stable ICU 4.0 */
     U_WB_NEWLINE =12,           /*[NL]*/
+    /** @stable ICU 50 */
     U_WB_REGIONAL_INDICATOR = 13,   /*[RI]*/ /* new in Unicode 6.2/ICU 50 */
+    /** @stable ICU 52 */
     U_WB_HEBREW_LETTER = 14,    /*[HL]*/ /* from here on: new in Unicode 6.3/ICU 52 */
+    /** @stable ICU 52 */
     U_WB_SINGLE_QUOTE = 15,     /*[SQ]*/
+    /** @stable ICU 52 */
     U_WB_DOUBLE_QUOTE = 16,     /*[DQ]*/
-    U_WB_COUNT = 17
+    /** @stable ICU 58 */
+    U_WB_E_BASE = 17,           /*[EB]*/ /* from here on: new in Unicode 9.0/ICU 58 */
+    /** @stable ICU 58 */
+    U_WB_E_BASE_GAZ = 18,       /*[EBG]*/
+    /** @stable ICU 58 */
+    U_WB_E_MODIFIER = 19,       /*[EM]*/
+    /** @stable ICU 58 */
+    U_WB_GLUE_AFTER_ZWJ = 20,   /*[GAZ]*/
+    /** @stable ICU 58 */
+    U_WB_ZWJ = 21,              /*[ZWJ]*/
+    /** @stable ICU 62 */
+    U_WB_WSEGSPACE = 22,        /*[WSEGSPACE]*/
+
+#ifndef U_HIDE_DEPRECATED_API
+    /**
+     * One more than the highest normal UWordBreakValues value.
+     * The highest value is available via u_getIntPropertyMaxValue(UCHAR_WORD_BREAK).
+     *
+     * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
+     */
+    U_WB_COUNT = 23
+#endif  // U_HIDE_DEPRECATED_API
 } UWordBreakValues;
 
 /**
@@ -1902,7 +2260,15 @@
     U_SB_EXTEND = 12,           /*[EX]*/
     U_SB_LF = 13,               /*[LF]*/
     U_SB_SCONTINUE = 14,        /*[SC]*/
+#ifndef U_HIDE_DEPRECATED_API
+    /**
+     * One more than the highest normal USentenceBreak value.
+     * The highest value is available via u_getIntPropertyMaxValue(UCHAR_SENTENCE_BREAK).
+     *
+     * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
+     */
     U_SB_COUNT = 15
+#endif  // U_HIDE_DEPRECATED_API
 } USentenceBreak;
 
 /**
@@ -1949,18 +2315,43 @@
     U_LB_SPACE = 26,             /*[SP]*/
     U_LB_BREAK_SYMBOLS = 27,     /*[SY]*/
     U_LB_ZWSPACE = 28,           /*[ZW]*/
+    /** @stable ICU 2.6 */
     U_LB_NEXT_LINE = 29,         /*[NL]*/ /* from here on: new in Unicode 4/ICU 2.6 */
+    /** @stable ICU 2.6 */
     U_LB_WORD_JOINER = 30,       /*[WJ]*/
+    /** @stable ICU 3.4 */
     U_LB_H2 = 31,                /*[H2]*/ /* from here on: new in Unicode 4.1/ICU 3.4 */
+    /** @stable ICU 3.4 */
     U_LB_H3 = 32,                /*[H3]*/
+    /** @stable ICU 3.4 */
     U_LB_JL = 33,                /*[JL]*/
+    /** @stable ICU 3.4 */
     U_LB_JT = 34,                /*[JT]*/
+    /** @stable ICU 3.4 */
     U_LB_JV = 35,                /*[JV]*/
+    /** @stable ICU 4.4 */
     U_LB_CLOSE_PARENTHESIS = 36, /*[CP]*/ /* new in Unicode 5.2/ICU 4.4 */
+    /** @stable ICU 49 */
     U_LB_CONDITIONAL_JAPANESE_STARTER = 37,/*[CJ]*/ /* new in Unicode 6.1/ICU 49 */
+    /** @stable ICU 49 */
     U_LB_HEBREW_LETTER = 38,     /*[HL]*/ /* new in Unicode 6.1/ICU 49 */
+    /** @stable ICU 50 */
     U_LB_REGIONAL_INDICATOR = 39,/*[RI]*/ /* new in Unicode 6.2/ICU 50 */
-    U_LB_COUNT = 40
+    /** @stable ICU 58 */
+    U_LB_E_BASE = 40,            /*[EB]*/ /* from here on: new in Unicode 9.0/ICU 58 */
+    /** @stable ICU 58 */
+    U_LB_E_MODIFIER = 41,        /*[EM]*/
+    /** @stable ICU 58 */
+    U_LB_ZWJ = 42,               /*[ZWJ]*/
+#ifndef U_HIDE_DEPRECATED_API
+    /**
+     * One more than the highest normal ULineBreak value.
+     * The highest value is available via u_getIntPropertyMaxValue(UCHAR_LINE_BREAK).
+     *
+     * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
+     */
+    U_LB_COUNT = 43
+#endif  // U_HIDE_DEPRECATED_API
 } ULineBreak;
 
 /**
@@ -1980,7 +2371,15 @@
     U_NT_DECIMAL,           /*[de]*/
     U_NT_DIGIT,             /*[di]*/
     U_NT_NUMERIC,           /*[nu]*/
+#ifndef U_HIDE_DEPRECATED_API
+    /**
+     * One more than the highest normal UNumericType value.
+     * The highest value is available via u_getIntPropertyMaxValue(UCHAR_NUMERIC_TYPE).
+     *
+     * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
+     */
     U_NT_COUNT
+#endif  // U_HIDE_DEPRECATED_API
 } UNumericType;
 
 /**
@@ -2002,10 +2401,175 @@
     U_HST_TRAILING_JAMO,    /*[T]*/
     U_HST_LV_SYLLABLE,      /*[LV]*/
     U_HST_LVT_SYLLABLE,     /*[LVT]*/
+#ifndef U_HIDE_DEPRECATED_API
+    /**
+     * One more than the highest normal UHangulSyllableType value.
+     * The highest value is available via u_getIntPropertyMaxValue(UCHAR_HANGUL_SYLLABLE_TYPE).
+     *
+     * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
+     */
     U_HST_COUNT
+#endif  // U_HIDE_DEPRECATED_API
 } UHangulSyllableType;
 
 /**
+ * Indic Positional Category constants.
+ *
+ * @see UCHAR_INDIC_POSITIONAL_CATEGORY
+ * @stable ICU 63
+ */
+typedef enum UIndicPositionalCategory {
+    /*
+     * Note: UIndicPositionalCategory constants are parsed by preparseucd.py.
+     * It matches lines like
+     *     U_INPC_<Unicode Indic_Positional_Category value name>
+     */
+
+    /** @stable ICU 63 */
+    U_INPC_NA,
+    /** @stable ICU 63 */
+    U_INPC_BOTTOM,
+    /** @stable ICU 63 */
+    U_INPC_BOTTOM_AND_LEFT,
+    /** @stable ICU 63 */
+    U_INPC_BOTTOM_AND_RIGHT,
+    /** @stable ICU 63 */
+    U_INPC_LEFT,
+    /** @stable ICU 63 */
+    U_INPC_LEFT_AND_RIGHT,
+    /** @stable ICU 63 */
+    U_INPC_OVERSTRUCK,
+    /** @stable ICU 63 */
+    U_INPC_RIGHT,
+    /** @stable ICU 63 */
+    U_INPC_TOP,
+    /** @stable ICU 63 */
+    U_INPC_TOP_AND_BOTTOM,
+    /** @stable ICU 63 */
+    U_INPC_TOP_AND_BOTTOM_AND_RIGHT,
+    /** @stable ICU 63 */
+    U_INPC_TOP_AND_LEFT,
+    /** @stable ICU 63 */
+    U_INPC_TOP_AND_LEFT_AND_RIGHT,
+    /** @stable ICU 63 */
+    U_INPC_TOP_AND_RIGHT,
+    /** @stable ICU 63 */
+    U_INPC_VISUAL_ORDER_LEFT,
+    /** @stable ICU 66 */
+    U_INPC_TOP_AND_BOTTOM_AND_LEFT,
+} UIndicPositionalCategory;
+
+/**
+ * Indic Syllabic Category constants.
+ *
+ * @see UCHAR_INDIC_SYLLABIC_CATEGORY
+ * @stable ICU 63
+ */
+typedef enum UIndicSyllabicCategory {
+    /*
+     * Note: UIndicSyllabicCategory constants are parsed by preparseucd.py.
+     * It matches lines like
+     *     U_INSC_<Unicode Indic_Syllabic_Category value name>
+     */
+
+    /** @stable ICU 63 */
+    U_INSC_OTHER,
+    /** @stable ICU 63 */
+    U_INSC_AVAGRAHA,
+    /** @stable ICU 63 */
+    U_INSC_BINDU,
+    /** @stable ICU 63 */
+    U_INSC_BRAHMI_JOINING_NUMBER,
+    /** @stable ICU 63 */
+    U_INSC_CANTILLATION_MARK,
+    /** @stable ICU 63 */
+    U_INSC_CONSONANT,
+    /** @stable ICU 63 */
+    U_INSC_CONSONANT_DEAD,
+    /** @stable ICU 63 */
+    U_INSC_CONSONANT_FINAL,
+    /** @stable ICU 63 */
+    U_INSC_CONSONANT_HEAD_LETTER,
+    /** @stable ICU 63 */
+    U_INSC_CONSONANT_INITIAL_POSTFIXED,
+    /** @stable ICU 63 */
+    U_INSC_CONSONANT_KILLER,
+    /** @stable ICU 63 */
+    U_INSC_CONSONANT_MEDIAL,
+    /** @stable ICU 63 */
+    U_INSC_CONSONANT_PLACEHOLDER,
+    /** @stable ICU 63 */
+    U_INSC_CONSONANT_PRECEDING_REPHA,
+    /** @stable ICU 63 */
+    U_INSC_CONSONANT_PREFIXED,
+    /** @stable ICU 63 */
+    U_INSC_CONSONANT_SUBJOINED,
+    /** @stable ICU 63 */
+    U_INSC_CONSONANT_SUCCEEDING_REPHA,
+    /** @stable ICU 63 */
+    U_INSC_CONSONANT_WITH_STACKER,
+    /** @stable ICU 63 */
+    U_INSC_GEMINATION_MARK,
+    /** @stable ICU 63 */
+    U_INSC_INVISIBLE_STACKER,
+    /** @stable ICU 63 */
+    U_INSC_JOINER,
+    /** @stable ICU 63 */
+    U_INSC_MODIFYING_LETTER,
+    /** @stable ICU 63 */
+    U_INSC_NON_JOINER,
+    /** @stable ICU 63 */
+    U_INSC_NUKTA,
+    /** @stable ICU 63 */
+    U_INSC_NUMBER,
+    /** @stable ICU 63 */
+    U_INSC_NUMBER_JOINER,
+    /** @stable ICU 63 */
+    U_INSC_PURE_KILLER,
+    /** @stable ICU 63 */
+    U_INSC_REGISTER_SHIFTER,
+    /** @stable ICU 63 */
+    U_INSC_SYLLABLE_MODIFIER,
+    /** @stable ICU 63 */
+    U_INSC_TONE_LETTER,
+    /** @stable ICU 63 */
+    U_INSC_TONE_MARK,
+    /** @stable ICU 63 */
+    U_INSC_VIRAMA,
+    /** @stable ICU 63 */
+    U_INSC_VISARGA,
+    /** @stable ICU 63 */
+    U_INSC_VOWEL,
+    /** @stable ICU 63 */
+    U_INSC_VOWEL_DEPENDENT,
+    /** @stable ICU 63 */
+    U_INSC_VOWEL_INDEPENDENT,
+} UIndicSyllabicCategory;
+
+/**
+ * Vertical Orientation constants.
+ *
+ * @see UCHAR_VERTICAL_ORIENTATION
+ * @stable ICU 63
+ */
+typedef enum UVerticalOrientation {
+    /*
+     * Note: UVerticalOrientation constants are parsed by preparseucd.py.
+     * It matches lines like
+     *     U_VO_<Unicode Vertical_Orientation value name>
+     */
+
+    /** @stable ICU 63 */
+    U_VO_ROTATED,
+    /** @stable ICU 63 */
+    U_VO_TRANSFORMED_ROTATED,
+    /** @stable ICU 63 */
+    U_VO_TRANSFORMED_UPRIGHT,
+    /** @stable ICU 63 */
+    U_VO_UPRIGHT,
+} UVerticalOrientation;
+
+/**
  * Check a binary Unicode property for a code point.
  *
  * Unicode, especially in version 3.2, defines many more properties than the
@@ -2022,19 +2586,38 @@
  * @param c Code point to test.
  * @param which UProperty selector constant, identifies which binary property to check.
  *        Must be UCHAR_BINARY_START<=which<UCHAR_BINARY_LIMIT.
- * @return TRUE or FALSE according to the binary Unicode property value for c.
- *         Also FALSE if 'which' is out of bounds or if the Unicode version
+ * @return true or false according to the binary Unicode property value for c.
+ *         Also false if 'which' is out of bounds or if the Unicode version
  *         does not have data for the property at all, or not for this code point.
  *
  * @see UProperty
+ * @see u_getBinaryPropertySet
  * @see u_getIntPropertyValue
  * @see u_getUnicodeVersion
  * @stable ICU 2.1
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 u_hasBinaryProperty(UChar32 c, UProperty which);
 
 /**
+ * Returns a frozen USet for a binary property.
+ * The library retains ownership over the returned object.
+ * Sets an error code if the property number is not one for a binary property.
+ *
+ * The returned set contains all code points for which the property is true.
+ *
+ * @param property UCHAR_BINARY_START..UCHAR_BINARY_LIMIT-1
+ * @param pErrorCode an in/out ICU UErrorCode
+ * @return the property as a set
+ * @see UProperty
+ * @see u_hasBinaryProperty
+ * @see Unicode::fromUSet
+ * @stable ICU 63
+ */
+U_CAPI const USet * U_EXPORT2
+u_getBinaryPropertySet(UProperty property, UErrorCode *pErrorCode);
+
+/**
  * Check if a code point has the Alphabetic Unicode property.
  * Same as u_hasBinaryProperty(c, UCHAR_ALPHABETIC).
  * This is different from u_isalpha!
@@ -2046,7 +2629,7 @@
  * @see u_hasBinaryProperty
  * @stable ICU 2.1
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 u_isUAlphabetic(UChar32 c);
 
 /**
@@ -2061,7 +2644,7 @@
  * @see u_hasBinaryProperty
  * @stable ICU 2.1
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 u_isULowercase(UChar32 c);
 
 /**
@@ -2076,7 +2659,7 @@
  * @see u_hasBinaryProperty
  * @stable ICU 2.1
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 u_isUUppercase(UChar32 c);
 
 /**
@@ -2097,7 +2680,7 @@
  * @see u_hasBinaryProperty
  * @stable ICU 2.1
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 u_isUWhiteSpace(UChar32 c);
 
 /**
@@ -2125,7 +2708,7 @@
  *         for enumerated properties, corresponds to the numeric value of the enumerated
  *         constant of the respective property value enumeration type
  *         (cast to enum type if necessary).
- *         Returns 0 or 1 (for FALSE/TRUE) for binary Unicode properties.
+ *         Returns 0 or 1 (for false/true) for binary Unicode properties.
  *         Returns a bit-mask for mask properties.
  *         Returns 0 if 'which' is out of bounds or if the Unicode version
  *         does not have data for the property at all, or not for this code point.
@@ -2134,10 +2717,11 @@
  * @see u_hasBinaryProperty
  * @see u_getIntPropertyMinValue
  * @see u_getIntPropertyMaxValue
+ * @see u_getIntPropertyMap
  * @see u_getUnicodeVersion
  * @stable ICU 2.2
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 u_getIntPropertyValue(UChar32 c, UProperty which);
 
 /**
@@ -2158,7 +2742,7 @@
  * @see u_getIntPropertyValue
  * @stable ICU 2.2
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 u_getIntPropertyMinValue(UProperty which);
 
 /**
@@ -2170,7 +2754,7 @@
  *
  * - UCHAR_BIDI_CLASS:    0/18 (U_LEFT_TO_RIGHT/U_BOUNDARY_NEUTRAL)
  * - UCHAR_SCRIPT:        0/45 (USCRIPT_COMMON/USCRIPT_TAGBANWA)
- * - UCHAR_IDEOGRAPHIC:   0/1  (FALSE/TRUE)
+ * - UCHAR_IDEOGRAPHIC:   0/1  (false/true)
  *
  * For undefined UProperty constant values, min/max values will be 0/-1.
  *
@@ -2187,10 +2771,28 @@
  * @see u_getIntPropertyValue
  * @stable ICU 2.2
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 u_getIntPropertyMaxValue(UProperty which);
 
 /**
+ * Returns an immutable UCPMap for an enumerated/catalog/int-valued property.
+ * The library retains ownership over the returned object.
+ * Sets an error code if the property number is not one for an "int property".
+ *
+ * The returned object maps all Unicode code points to their values for that property.
+ * For documentation of the integer values see u_getIntPropertyValue().
+ *
+ * @param property UCHAR_INT_START..UCHAR_INT_LIMIT-1
+ * @param pErrorCode an in/out ICU UErrorCode
+ * @return the property as a map
+ * @see UProperty
+ * @see u_getIntPropertyValue
+ * @stable ICU 63
+ */
+U_CAPI const UCPMap * U_EXPORT2
+u_getIntPropertyMap(UProperty property, UErrorCode *pErrorCode);
+
+/**
  * Get the numeric value for a Unicode code point as defined in the
  * Unicode Character Database.
  *
@@ -2212,7 +2814,7 @@
  * @see U_NO_NUMERIC_VALUE
  * @stable ICU 2.2
  */
-U_STABLE double U_EXPORT2
+U_CAPI double U_EXPORT2
 u_getNumericValue(UChar32 c);
 
 /**
@@ -2240,14 +2842,14 @@
  * documentation at the top of this header file.
  *
  * @param c the code point to be tested
- * @return TRUE if the code point is an Ll lowercase letter
+ * @return true if the code point is an Ll lowercase letter
  *
  * @see UCHAR_LOWERCASE
  * @see u_isupper
  * @see u_istitle
  * @stable ICU 2.0
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 u_islower(UChar32 c);
 
 /**
@@ -2266,7 +2868,7 @@
  * documentation at the top of this header file.
  *
  * @param c the code point to be tested
- * @return TRUE if the code point is an Lu uppercase letter
+ * @return true if the code point is an Lu uppercase letter
  *
  * @see UCHAR_UPPERCASE
  * @see u_islower
@@ -2274,7 +2876,7 @@
  * @see u_tolower
  * @stable ICU 2.0
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 u_isupper(UChar32 c);
 
 /**
@@ -2284,14 +2886,14 @@
  * Same as java.lang.Character.isTitleCase().
  *
  * @param c the code point to be tested
- * @return TRUE if the code point is an Lt titlecase letter
+ * @return true if the code point is an Lt titlecase letter
  *
  * @see u_isupper
  * @see u_islower
  * @see u_totitle
  * @stable ICU 2.0
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 u_istitle(UChar32 c);
 
 /**
@@ -2308,11 +2910,11 @@
  * documentation at the top of this header file.
  *
  * @param c the code point to be tested
- * @return TRUE if the code point is a digit character according to Character.isDigit()
+ * @return true if the code point is a digit character according to Character.isDigit()
  *
  * @stable ICU 2.0
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 u_isdigit(UChar32 c);
 
 /**
@@ -2327,13 +2929,13 @@
  * documentation at the top of this header file.
  *
  * @param c the code point to be tested
- * @return TRUE if the code point is a letter character
+ * @return true if the code point is a letter character
  *
  * @see u_isdigit
  * @see u_isalnum
  * @stable ICU 2.0
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 u_isalpha(UChar32 c);
 
 /**
@@ -2350,11 +2952,11 @@
  * documentation at the top of this header file.
  *
  * @param c the code point to be tested
- * @return TRUE if the code point is an alphanumeric character according to Character.isLetterOrDigit()
+ * @return true if the code point is an alphanumeric character according to Character.isLetterOrDigit()
  *
  * @stable ICU 2.0
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 u_isalnum(UChar32 c);
 
 /**
@@ -2373,11 +2975,11 @@
  * documentation at the top of this header file.
  *
  * @param c the code point to be tested
- * @return TRUE if the code point is a hexadecimal digit
+ * @return true if the code point is a hexadecimal digit
  *
  * @stable ICU 2.6
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 u_isxdigit(UChar32 c);
 
 /**
@@ -2389,17 +2991,17 @@
  * documentation at the top of this header file.
  *
  * @param c the code point to be tested
- * @return TRUE if the code point is a punctuation character
+ * @return true if the code point is a punctuation character
  *
  * @stable ICU 2.6
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 u_ispunct(UChar32 c);
 
 /**
  * Determines whether the specified code point is a "graphic" character
  * (printable, excluding spaces).
- * TRUE for all characters except those with general categories
+ * true for all characters except those with general categories
  * "Cc" (control codes), "Cf" (format controls), "Cs" (surrogates),
  * "Cn" (unassigned), and "Z" (separators).
  *
@@ -2408,11 +3010,11 @@
  * documentation at the top of this header file.
  *
  * @param c the code point to be tested
- * @return TRUE if the code point is a "graphic" character
+ * @return true if the code point is a "graphic" character
  *
  * @stable ICU 2.6
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 u_isgraph(UChar32 c);
 
 /**
@@ -2420,14 +3022,13 @@
  * a character that visibly separates words on a line.
  * The following are equivalent definitions:
  *
- * TRUE for Unicode White_Space characters except for "vertical space controls"
+ * true for Unicode White_Space characters except for "vertical space controls"
  * where "vertical space controls" are the following characters:
  * U+000A (LF) U+000B (VT) U+000C (FF) U+000D (CR) U+0085 (NEL) U+2028 (LS) U+2029 (PS)
  *
  * same as
  *
- * TRUE for U+0009 (TAB) and characters with general category "Zs" (space separators)
- * except Zero Width Space (ZWSP, U+200B).
+ * true for U+0009 (TAB) and characters with general category "Zs" (space separators).
  *
  * Note: There are several ICU whitespace functions; please see the uchar.h
  * file documentation for a detailed comparison.
@@ -2437,11 +3038,11 @@
  * documentation at the top of this header file.
  *
  * @param c the code point to be tested
- * @return TRUE if the code point is a "blank"
+ * @return true if the code point is a "blank"
  *
  * @stable ICU 2.6
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 u_isblank(UChar32 c);
 
 /**
@@ -2456,7 +3057,7 @@
  * Same as java.lang.Character.isDefined().
  *
  * @param c the code point to be tested
- * @return TRUE if the code point is assigned a character
+ * @return true if the code point is assigned a character
  *
  * @see u_isdigit
  * @see u_isalpha
@@ -2466,7 +3067,7 @@
  * @see u_istitle
  * @stable ICU 2.0
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 u_isdefined(UChar32 c);
 
 /**
@@ -2487,7 +3088,7 @@
  * @see u_isUWhiteSpace
  * @stable ICU 2.0
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 u_isspace(UChar32 c);
 
 /**
@@ -2501,14 +3102,14 @@
  * file documentation for a detailed comparison.
  *
  * @param c the code point to be tested
- * @return TRUE if the code point is a space character according to Character.isSpaceChar()
+ * @return true if the code point is a space character according to Character.isSpaceChar()
  *
  * @see u_isspace
  * @see u_isWhitespace
  * @see u_isUWhiteSpace
  * @stable ICU 2.6
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 u_isJavaSpaceChar(UChar32 c);
 
 /**
@@ -2541,14 +3142,14 @@
  * file documentation for a detailed comparison.
  *
  * @param c the code point to be tested
- * @return TRUE if the code point is a whitespace character according to Java/ICU
+ * @return true if the code point is a whitespace character according to Java/ICU
  *
  * @see u_isspace
  * @see u_isJavaSpaceChar
  * @see u_isUWhiteSpace
  * @stable ICU 2.0
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 u_isWhitespace(UChar32 c);
 
 /**
@@ -2566,13 +3167,13 @@
  * documentation at the top of this header file.
  *
  * @param c the code point to be tested
- * @return TRUE if the code point is a control character
+ * @return true if the code point is a control character
  *
  * @see UCHAR_DEFAULT_IGNORABLE_CODE_POINT
  * @see u_isprint
  * @stable ICU 2.0
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 u_iscntrl(UChar32 c);
 
 /**
@@ -2582,12 +3183,12 @@
  * Same as java.lang.Character.isISOControl().
  *
  * @param c the code point to be tested
- * @return TRUE if the code point is an ISO control code
+ * @return true if the code point is an ISO control code
  *
  * @see u_iscntrl
  * @stable ICU 2.6
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 u_isISOControl(UChar32 c);
 
 /**
@@ -2599,34 +3200,33 @@
  * documentation at the top of this header file.
  *
  * @param c the code point to be tested
- * @return TRUE if the code point is a printable character
+ * @return true if the code point is a printable character
  *
  * @see UCHAR_DEFAULT_IGNORABLE_CODE_POINT
  * @see u_iscntrl
  * @stable ICU 2.0
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 u_isprint(UChar32 c);
 
 /**
- * Determines whether the specified code point is a base character.
+ * Non-standard: Determines whether the specified code point is a base character.
  * True for general categories "L" (letters), "N" (numbers),
  * "Mc" (spacing combining marks), and "Me" (enclosing marks).
  *
- * Note that this is different from the Unicode definition in
- * chapter 3.5, conformance clause D13,
- * which defines base characters to be all characters (not Cn)
- * that do not graphically combine with preceding characters (M)
- * and that are neither control (Cc) or format (Cf) characters.
+ * Note that this is different from the Unicode Standard definition in
+ * chapter 3.6, conformance clause D51 “Base character”,
+ * which defines base characters as the code points with general categories
+ * Letter (L), Number (N), Punctuation (P), Symbol (S), or Space Separator (Zs).
  *
  * @param c the code point to be tested
- * @return TRUE if the code point is a base character according to this function
+ * @return true if the code point is a base character according to this function
  *
  * @see u_isalpha
  * @see u_isdigit
  * @stable ICU 2.0
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 u_isbase(UChar32 c);
 
 /**
@@ -2645,7 +3245,7 @@
  * @see UCharDirection
  * @stable ICU 2.0
  */
-U_STABLE UCharDirection U_EXPORT2
+U_CAPI UCharDirection U_EXPORT2
 u_charDirection(UChar32 c);
 
 /**
@@ -2658,12 +3258,12 @@
  * Same as UCHAR_BIDI_MIRRORED
  *
  * @param c the code point to be tested
- * @return TRUE if the character has the Bidi_Mirrored property
+ * @return true if the character has the Bidi_Mirrored property
  *
  * @see UCHAR_BIDI_MIRRORED
  * @stable ICU 2.0
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 u_isMirrored(UChar32 c);
 
 /**
@@ -2685,7 +3285,7 @@
  * @see u_isMirrored
  * @stable ICU 2.0
  */
-U_STABLE UChar32 U_EXPORT2
+U_CAPI UChar32 U_EXPORT2
 u_charMirror(UChar32 c);
 
 /**
@@ -2704,7 +3304,7 @@
  * @see u_charMirror
  * @stable ICU 52
  */
-U_STABLE UChar32 U_EXPORT2
+U_CAPI UChar32 U_EXPORT2
 u_getBidiPairedBracket(UChar32 c);
 
 /**
@@ -2718,7 +3318,7 @@
  * @see UCharCategory
  * @stable ICU 2.0
  */
-U_STABLE int8_t U_EXPORT2
+U_CAPI int8_t U_EXPORT2
 u_charType(UChar32 c);
 
 /**
@@ -2741,13 +3341,13 @@
  * of code points c (where start<=c<limit)
  * with the same Unicode general category ("character type").
  *
- * The callback function can stop the enumeration by returning FALSE.
+ * The callback function can stop the enumeration by returning false.
  *
  * @param context an opaque pointer, as passed into utrie_enum()
  * @param start the first code point in a contiguous range with value
  * @param limit one past the last code point in a contiguous range with value
  * @param type the general category for all code points in [start..limit[
- * @return FALSE to stop the enumeration
+ * @return false to stop the enumeration
  *
  * @stable ICU 2.1
  * @see UCharCategory
@@ -2775,7 +3375,7 @@
  * @see UCharCategory
  * @see UCharEnumTypeRange
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 u_enumCharTypes(UCharEnumTypeRange *enumRange, const void *context);
 
 #if !UCONFIG_NO_NORMALIZATION
@@ -2787,7 +3387,7 @@
  * @return the combining class of the character
  * @stable ICU 2.0
  */
-U_STABLE uint8_t U_EXPORT2
+U_CAPI uint8_t U_EXPORT2
 u_getCombiningClass(UChar32 c);
 
 #endif
@@ -2815,7 +3415,7 @@
  * @see u_getNumericValue
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 u_charDigitValue(UChar32 c);
 
 /**
@@ -2827,7 +3427,7 @@
  * @see UBlockCode
  * @stable ICU 2.0
  */
-U_STABLE UBlockCode U_EXPORT2
+U_CAPI UBlockCode U_EXPORT2
 ublock_getCode(UChar32 c);
 
 /**
@@ -2862,12 +3462,12 @@
  * @see u_enumCharNames
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 u_charName(UChar32 code, UCharNameChoice nameChoice,
            char *buffer, int32_t bufferLength,
            UErrorCode *pErrorCode);
 
-#ifndef U_HIDE_DEPRECATED_API 
+#ifndef U_HIDE_DEPRECATED_API
 /**
  * Returns an empty string.
  * Used to return the ISO 10646 comment for a character.
@@ -2912,7 +3512,7 @@
  * @see u_enumCharNames
  * @stable ICU 1.7
  */
-U_STABLE UChar32 U_EXPORT2
+U_CAPI UChar32 U_EXPORT2
 u_charFromName(UCharNameChoice nameChoice,
                const char *name,
                UErrorCode *pErrorCode);
@@ -2921,14 +3521,14 @@
  * Type of a callback function for u_enumCharNames() that gets called
  * for each Unicode character with the code point value and
  * the character name.
- * If such a function returns FALSE, then the enumeration is stopped.
+ * If such a function returns false, then the enumeration is stopped.
  *
  * @param context The context pointer that was passed to u_enumCharNames().
  * @param code The Unicode code point for the character with this name.
  * @param nameChoice Selector for which kind of names is enumerated.
  * @param name The character's name, zero-terminated.
  * @param length The length of the name.
- * @return TRUE if the enumeration should continue, FALSE to stop it.
+ * @return true if the enumeration should continue, false to stop it.
  *
  * @see UCharNameChoice
  * @see u_enumCharNames
@@ -2961,7 +3561,7 @@
  * @see u_charFromName
  * @stable ICU 1.7
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 u_enumCharNames(UChar32 start, UChar32 limit,
                 UEnumCharNamesFn *fn,
                 void *context,
@@ -2999,7 +3599,7 @@
  * @see UPropertyNameChoice
  * @stable ICU 2.4
  */
-U_STABLE const char* U_EXPORT2
+U_CAPI const char* U_EXPORT2
 u_getPropertyName(UProperty property,
                   UPropertyNameChoice nameChoice);
 
@@ -3022,7 +3622,7 @@
  * @see UProperty
  * @stable ICU 2.4
  */
-U_STABLE UProperty U_EXPORT2
+U_CAPI UProperty U_EXPORT2
 u_getPropertyEnum(const char* alias);
 
 /**
@@ -3072,7 +3672,7 @@
  * @see UPropertyNameChoice
  * @stable ICU 2.4
  */
-U_STABLE const char* U_EXPORT2
+U_CAPI const char* U_EXPORT2
 u_getPropertyValueName(UProperty property,
                        int32_t value,
                        UPropertyNameChoice nameChoice);
@@ -3108,7 +3708,7 @@
  * @see UProperty
  * @stable ICU 2.4
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 u_getPropertyValueEnum(UProperty property,
                        const char* alias);
 
@@ -3122,14 +3722,14 @@
  * Same as UCHAR_ID_START
  *
  * @param c the code point to be tested
- * @return TRUE if the code point may start an identifier
+ * @return true if the code point may start an identifier
  *
  * @see UCHAR_ID_START
  * @see u_isalpha
  * @see u_isIDPart
  * @stable ICU 2.0
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 u_isIDStart(UChar32 c);
 
 /**
@@ -3146,14 +3746,14 @@
  * u_isIDIgnorable(c).
  *
  * @param c the code point to be tested
- * @return TRUE if the code point may occur in an identifier according to Java
+ * @return true if the code point may occur in an identifier according to Java
  *
  * @see UCHAR_ID_CONTINUE
  * @see u_isIDStart
  * @see u_isIDIgnorable
  * @stable ICU 2.0
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 u_isIDPart(UChar32 c);
 
 /**
@@ -3169,14 +3769,14 @@
  * Note that Unicode just recommends to ignore Cf (format controls).
  *
  * @param c the code point to be tested
- * @return TRUE if the code point is ignorable in identifiers according to Java
+ * @return true if the code point is ignorable in identifiers according to Java
  *
  * @see UCHAR_DEFAULT_IGNORABLE_CODE_POINT
  * @see u_isIDStart
  * @see u_isIDPart
  * @stable ICU 2.0
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 u_isIDIgnorable(UChar32 c);
 
 /**
@@ -3188,14 +3788,14 @@
  * Same as java.lang.Character.isJavaIdentifierStart().
  *
  * @param c the code point to be tested
- * @return TRUE if the code point may start a Java identifier
+ * @return true if the code point may start a Java identifier
  *
  * @see     u_isJavaIDPart
  * @see     u_isalpha
  * @see     u_isIDStart
  * @stable ICU 2.0
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 u_isJavaIDStart(UChar32 c);
 
 /**
@@ -3207,7 +3807,7 @@
  * Same as java.lang.Character.isJavaIdentifierPart().
  *
  * @param c the code point to be tested
- * @return TRUE if the code point may occur in a Java identifier
+ * @return true if the code point may occur in a Java identifier
  *
  * @see     u_isIDIgnorable
  * @see     u_isJavaIDStart
@@ -3216,7 +3816,7 @@
  * @see     u_isIDPart
  * @stable ICU 2.0
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 u_isJavaIDPart(UChar32 c);
 
 /**
@@ -3241,7 +3841,7 @@
  *         otherwise the code point itself.
  * @stable ICU 2.0
  */
-U_STABLE UChar32 U_EXPORT2
+U_CAPI UChar32 U_EXPORT2
 u_tolower(UChar32 c);
 
 /**
@@ -3266,7 +3866,7 @@
  *         otherwise the code point itself.
  * @stable ICU 2.0
  */
-U_STABLE UChar32 U_EXPORT2
+U_CAPI UChar32 U_EXPORT2
 u_toupper(UChar32 c);
 
 /**
@@ -3291,30 +3891,9 @@
  *         otherwise the code point itself.
  * @stable ICU 2.0
  */
-U_STABLE UChar32 U_EXPORT2
+U_CAPI UChar32 U_EXPORT2
 u_totitle(UChar32 c);
 
-/** Option value for case folding: use default mappings defined in CaseFolding.txt. @stable ICU 2.0 */
-#define U_FOLD_CASE_DEFAULT 0
-
-/**
- * Option value for case folding:
- *
- * Use the modified set of mappings provided in CaseFolding.txt to handle dotted I
- * and dotless i appropriately for Turkic languages (tr, az).
- *
- * Before Unicode 3.2, CaseFolding.txt contains mappings marked with 'I' that
- * are to be included for default mappings and
- * excluded for the Turkic-specific mappings.
- *
- * Unicode 3.2 CaseFolding.txt instead contains mappings marked with 'T' that
- * are to be excluded for default mappings and
- * included for the Turkic-specific mappings.
- *
- * @stable ICU 2.0
- */
-#define U_FOLD_CASE_EXCLUDE_SPECIAL_I 1
-
 /**
  * The given character is mapped to its case folding equivalent according to
  * UnicodeData.txt and CaseFolding.txt;
@@ -3337,7 +3916,7 @@
  *         otherwise the code point itself.
  * @stable ICU 2.0
  */
-U_STABLE UChar32 U_EXPORT2
+U_CAPI UChar32 U_EXPORT2
 u_foldCase(UChar32 c, uint32_t options);
 
 /**
@@ -3378,7 +3957,7 @@
  * @see     u_isdigit
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 u_digit(UChar32 ch, int8_t radix);
 
 /**
@@ -3409,7 +3988,7 @@
  * @see     u_isdigit
  * @stable ICU 2.0
  */
-U_STABLE UChar32 U_EXPORT2
+U_CAPI UChar32 U_EXPORT2
 u_forDigit(int32_t digit, int8_t radix);
 
 /**
@@ -3426,7 +4005,7 @@
  *
  * @stable ICU 2.1
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 u_charAge(UChar32 c, UVersionInfo versionArray);
 
 /**
@@ -3440,7 +4019,7 @@
  *                     the Unicode version number
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 u_getUnicodeVersion(UVersionInfo versionArray);
 
 #if !UCONFIG_NO_NORMALIZATION
@@ -3465,7 +4044,7 @@
  *
  * @stable ICU 2.2
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 u_getFC_NFKC_Closure(UChar32 c, UChar *dest, int32_t destCapacity, UErrorCode *pErrorCode);
 
 #endif
diff --git a/src/third_party/icu/source/common/unicode/ucharstrie.h b/src/third_party/icu/source/common/unicode/ucharstrie.h
index 0575a97..b6f9e3e 100644
--- a/src/third_party/icu/source/common/unicode/ucharstrie.h
+++ b/src/third_party/icu/source/common/unicode/ucharstrie.h
@@ -1,10 +1,12 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *   Copyright (C) 2010-2012, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *******************************************************************************
 *   file name:  ucharstrie.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -22,6 +24,9 @@
  */
 
 #include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
 #include "unicode/unistr.h"
 #include "unicode/uobject.h"
 #include "unicode/ustringtrie.h"
@@ -34,7 +39,7 @@
 
 /**
  * Light-weight, non-const reader class for a UCharsTrie.
- * Traverses a UChar-serialized data structure with minimal state,
+ * Traverses a char16_t-serialized data structure with minimal state,
  * for mapping strings (16-bit-unit sequences) to non-negative integer values.
  *
  * This class owns the serialized trie data only if it was constructed by
@@ -50,18 +55,18 @@
     /**
      * Constructs a UCharsTrie reader instance.
      *
-     * The trieUChars must contain a copy of a UChar sequence from the UCharsTrieBuilder,
-     * starting with the first UChar of that sequence.
-     * The UCharsTrie object will not read more UChars than
+     * The trieUChars must contain a copy of a char16_t sequence from the UCharsTrieBuilder,
+     * starting with the first char16_t of that sequence.
+     * The UCharsTrie object will not read more char16_ts than
      * the UCharsTrieBuilder generated in the corresponding build() call.
      *
      * The array is not copied/cloned and must not be modified while
      * the UCharsTrie object is in use.
      *
-     * @param trieUChars The UChar array that contains the serialized trie.
+     * @param trieUChars The char16_t array that contains the serialized trie.
      * @stable ICU 4.8
      */
-    UCharsTrie(const UChar *trieUChars)
+    UCharsTrie(ConstChar16Ptr trieUChars)
             : ownedArray_(NULL), uchars_(trieUChars),
               pos_(uchars_), remainingMatchLength_(-1) {}
 
@@ -73,7 +78,7 @@
 
     /**
      * Copy constructor, copies the other trie reader object and its state,
-     * but not the UChar array which will be shared. (Shallow copy.)
+     * but not the char16_t array which will be shared. (Shallow copy.)
      * @param other Another UCharsTrie object.
      * @stable ICU 4.8
      */
@@ -93,6 +98,39 @@
     }
 
     /**
+     * Returns the state of this trie as a 64-bit integer.
+     * The state value is never 0.
+     *
+     * @return opaque state value
+     * @see resetToState64
+     * @stable ICU 65
+     */
+    uint64_t getState64() const {
+        return (static_cast<uint64_t>(remainingMatchLength_ + 2) << kState64RemainingShift) |
+            (uint64_t)(pos_ - uchars_);
+    }
+
+    /**
+     * Resets this trie to the saved state.
+     * Unlike resetToState(State), the 64-bit state value
+     * must be from getState64() from the same trie object or
+     * from one initialized the exact same way.
+     * Because of no validation, this method is faster.
+     *
+     * @param state The opaque trie state value from getState64().
+     * @return *this
+     * @see getState64
+     * @see resetToState
+     * @see reset
+     * @stable ICU 65
+     */
+    UCharsTrie &resetToState64(uint64_t state) {
+        remainingMatchLength_ = static_cast<int32_t>(state >> kState64RemainingShift) - 2;
+        pos_ = uchars_ + (state & kState64PosMask);
+        return *this;
+    }
+
+    /**
      * UCharsTrie state object, for saving a trie's current state
      * and resetting the trie back to this state later.
      * @stable ICU 4.8
@@ -107,8 +145,8 @@
     private:
         friend class UCharsTrie;
 
-        const UChar *uchars;
-        const UChar *pos;
+        const char16_t *uchars;
+        const char16_t *pos;
         int32_t remainingMatchLength;
     };
 
@@ -146,14 +184,14 @@
 
     /**
      * Determines whether the string so far matches, whether it has a value,
-     * and whether another input UChar can continue a matching string.
+     * and whether another input char16_t can continue a matching string.
      * @return The match/value Result.
      * @stable ICU 4.8
      */
     UStringTrieResult current() const;
 
     /**
-     * Traverses the trie from the initial state for this input UChar.
+     * Traverses the trie from the initial state for this input char16_t.
      * Equivalent to reset().next(uchar).
      * @param uchar Input char value. Values below 0 and above 0xffff will never match.
      * @return The match/value Result.
@@ -175,7 +213,7 @@
     UStringTrieResult firstForCodePoint(UChar32 cp);
 
     /**
-     * Traverses the trie from the current state for this input UChar.
+     * Traverses the trie from the current state for this input char16_t.
      * @param uchar Input char value. Values below 0 and above 0xffff will never match.
      * @return The match/value Result.
      * @stable ICU 4.8
@@ -206,7 +244,7 @@
      * @return The match/value Result.
      * @stable ICU 4.8
      */
-    UStringTrieResult next(const UChar *s, int32_t length);
+    UStringTrieResult next(ConstChar16Ptr s, int32_t length);
 
     /**
      * Returns a matching string's value if called immediately after
@@ -218,7 +256,7 @@
      * @stable ICU 4.8
      */
     inline int32_t getValue() const {
-        const UChar *pos=pos_;
+        const char16_t *pos=pos_;
         int32_t leadUnit=*pos++;
         // U_ASSERT(leadUnit>=kMinValueLead);
         return leadUnit&kValueIsFinal ?
@@ -228,23 +266,23 @@
     /**
      * Determines whether all strings reachable from the current state
      * map to the same value.
-     * @param uniqueValue Receives the unique value, if this function returns TRUE.
+     * @param uniqueValue Receives the unique value, if this function returns true.
      *                    (output-only)
-     * @return TRUE if all strings reachable from the current state
+     * @return true if all strings reachable from the current state
      *         map to the same value.
      * @stable ICU 4.8
      */
     inline UBool hasUniqueValue(int32_t &uniqueValue) const {
-        const UChar *pos=pos_;
+        const char16_t *pos=pos_;
         // Skip the rest of a pending linear-match node.
-        return pos!=NULL && findUniqueValue(pos+remainingMatchLength_+1, FALSE, uniqueValue);
+        return pos!=NULL && findUniqueValue(pos+remainingMatchLength_+1, false, uniqueValue);
     }
 
     /**
-     * Finds each UChar which continues the string from the current state.
-     * That is, each UChar c for which it would be next(c)!=USTRINGTRIE_NO_MATCH now.
-     * @param out Each next UChar is appended to this object.
-     * @return the number of UChars which continue the string from here
+     * Finds each char16_t which continues the string from the current state.
+     * That is, each char16_t c for which it would be next(c)!=USTRINGTRIE_NO_MATCH now.
+     * @param out Each next char16_t is appended to this object.
+     * @return the number of char16_ts which continue the string from here
      * @stable ICU 4.8
      */
     int32_t getNextUChars(Appendable &out) const;
@@ -256,8 +294,8 @@
     class U_COMMON_API Iterator : public UMemory {
     public:
         /**
-         * Iterates from the root of a UChar-serialized UCharsTrie.
-         * @param trieUChars The trie UChars.
+         * Iterates from the root of a char16_t-serialized UCharsTrie.
+         * @param trieUChars The trie char16_ts.
          * @param maxStringLength If 0, the iterator returns full strings.
          *                        Otherwise, the iterator returns strings with this maximum length.
          * @param errorCode Standard ICU error code. Its input value must
@@ -266,7 +304,7 @@
          *                  function chaining. (See User Guide for details.)
          * @stable ICU 4.8
          */
-        Iterator(const UChar *trieUChars, int32_t maxStringLength, UErrorCode &errorCode);
+        Iterator(ConstChar16Ptr trieUChars, int32_t maxStringLength, UErrorCode &errorCode);
 
         /**
          * Iterates from the current state of the specified UCharsTrie.
@@ -295,7 +333,7 @@
         Iterator &reset();
 
         /**
-         * @return TRUE if there are more elements.
+         * @return true if there are more elements.
          * @stable ICU 4.8
          */
         UBool hasNext() const;
@@ -311,7 +349,7 @@
          *                  pass the U_SUCCESS() test, or else the function returns
          *                  immediately. Check for U_FAILURE() on output or use with
          *                  function chaining. (See User Guide for details.)
-         * @return TRUE if there is another element.
+         * @return true if there is another element.
          * @stable ICU 4.8
          */
         UBool next(UErrorCode &errorCode);
@@ -331,14 +369,14 @@
         UBool truncateAndStop() {
             pos_=NULL;
             value_=-1;  // no real value for str
-            return TRUE;
+            return true;
         }
 
-        const UChar *branchNext(const UChar *pos, int32_t length, UErrorCode &errorCode);
+        const char16_t *branchNext(const char16_t *pos, int32_t length, UErrorCode &errorCode);
 
-        const UChar *uchars_;
-        const UChar *pos_;
-        const UChar *initialPos_;
+        const char16_t *uchars_;
+        const char16_t *pos_;
+        const char16_t *initialPos_;
         int32_t remainingMatchLength_;
         int32_t initialRemainingMatchLength_;
         UBool skipValue_;  // Skip intermediate value which was already delivered.
@@ -366,7 +404,7 @@
      * this constructor adopts the builder's array.
      * This constructor is only called by the builder.
      */
-    UCharsTrie(UChar *adoptUChars, const UChar *trieUChars)
+    UCharsTrie(char16_t *adoptUChars, const char16_t *trieUChars)
             : ownedArray_(adoptUChars), uchars_(trieUChars),
               pos_(uchars_), remainingMatchLength_(-1) {}
 
@@ -379,7 +417,7 @@
 
     // Reads a compact 32-bit integer.
     // pos is already after the leadUnit, and the lead unit has bit 15 reset.
-    static inline int32_t readValue(const UChar *pos, int32_t leadUnit) {
+    static inline int32_t readValue(const char16_t *pos, int32_t leadUnit) {
         int32_t value;
         if(leadUnit<kMinTwoUnitValueLead) {
             value=leadUnit;
@@ -390,7 +428,7 @@
         }
         return value;
     }
-    static inline const UChar *skipValue(const UChar *pos, int32_t leadUnit) {
+    static inline const char16_t *skipValue(const char16_t *pos, int32_t leadUnit) {
         if(leadUnit>=kMinTwoUnitValueLead) {
             if(leadUnit<kThreeUnitValueLead) {
                 ++pos;
@@ -400,12 +438,12 @@
         }
         return pos;
     }
-    static inline const UChar *skipValue(const UChar *pos) {
+    static inline const char16_t *skipValue(const char16_t *pos) {
         int32_t leadUnit=*pos++;
         return skipValue(pos, leadUnit&0x7fff);
     }
 
-    static inline int32_t readNodeValue(const UChar *pos, int32_t leadUnit) {
+    static inline int32_t readNodeValue(const char16_t *pos, int32_t leadUnit) {
         // U_ASSERT(kMinValueLead<=leadUnit && leadUnit<kValueIsFinal);
         int32_t value;
         if(leadUnit<kMinTwoUnitNodeValueLead) {
@@ -417,7 +455,7 @@
         }
         return value;
     }
-    static inline const UChar *skipNodeValue(const UChar *pos, int32_t leadUnit) {
+    static inline const char16_t *skipNodeValue(const char16_t *pos, int32_t leadUnit) {
         // U_ASSERT(kMinValueLead<=leadUnit && leadUnit<kValueIsFinal);
         if(leadUnit>=kMinTwoUnitNodeValueLead) {
             if(leadUnit<kThreeUnitNodeValueLead) {
@@ -429,7 +467,7 @@
         return pos;
     }
 
-    static inline const UChar *jumpByDelta(const UChar *pos) {
+    static inline const char16_t *jumpByDelta(const char16_t *pos) {
         int32_t delta=*pos++;
         if(delta>=kMinTwoUnitDeltaLead) {
             if(delta==kThreeUnitDeltaLead) {
@@ -442,7 +480,7 @@
         return pos+delta;
     }
 
-    static const UChar *skipDelta(const UChar *pos) {
+    static const char16_t *skipDelta(const char16_t *pos) {
         int32_t delta=*pos++;
         if(delta>=kMinTwoUnitDeltaLead) {
             if(delta==kThreeUnitDeltaLead) {
@@ -459,28 +497,28 @@
     }
 
     // Handles a branch node for both next(uchar) and next(string).
-    UStringTrieResult branchNext(const UChar *pos, int32_t length, int32_t uchar);
+    UStringTrieResult branchNext(const char16_t *pos, int32_t length, int32_t uchar);
 
     // Requires remainingLength_<0.
-    UStringTrieResult nextImpl(const UChar *pos, int32_t uchar);
+    UStringTrieResult nextImpl(const char16_t *pos, int32_t uchar);
 
     // Helper functions for hasUniqueValue().
     // Recursively finds a unique value (or whether there is not a unique one)
     // from a branch.
-    static const UChar *findUniqueValueFromBranch(const UChar *pos, int32_t length,
+    static const char16_t *findUniqueValueFromBranch(const char16_t *pos, int32_t length,
                                                   UBool haveUniqueValue, int32_t &uniqueValue);
     // Recursively finds a unique value (or whether there is not a unique one)
     // starting from a position on a node lead unit.
-    static UBool findUniqueValue(const UChar *pos, UBool haveUniqueValue, int32_t &uniqueValue);
+    static UBool findUniqueValue(const char16_t *pos, UBool haveUniqueValue, int32_t &uniqueValue);
 
     // Helper functions for getNextUChars().
     // getNextUChars() when pos is on a branch node.
-    static void getNextBranchUChars(const UChar *pos, int32_t length, Appendable &out);
+    static void getNextBranchUChars(const char16_t *pos, int32_t length, Appendable &out);
 
     // UCharsTrie data structure
     //
-    // The trie consists of a series of UChar-serialized nodes for incremental
-    // Unicode string/UChar sequence matching. (UChar=16-bit unsigned integer)
+    // The trie consists of a series of char16_t-serialized nodes for incremental
+    // Unicode string/char16_t sequence matching. (char16_t=16-bit unsigned integer)
     // The root node is at the beginning of the trie data.
     //
     // Types of nodes are distinguished by their node lead unit ranges.
@@ -489,9 +527,9 @@
     //
     // Node types:
     //  - Final-value node: Stores a 32-bit integer in a compact, variable-length format.
-    //    The value is for the string/UChar sequence so far.
+    //    The value is for the string/char16_t sequence so far.
     //  - Match node, optionally with an intermediate value in a different compact format.
-    //    The value, if present, is for the string/UChar sequence so far.
+    //    The value, if present, is for the string/char16_t sequence so far.
     //
     //  Aside from the value, which uses the node lead unit's high bits:
     //
@@ -558,19 +596,28 @@
 
     static const int32_t kMaxTwoUnitDelta=((kThreeUnitDeltaLead-kMinTwoUnitDeltaLead)<<16)-1;  // 0x03feffff
 
-    UChar *ownedArray_;
+    // For getState64():
+    // The remainingMatchLength_ is -1..14=(kMaxLinearMatchLength=0x10)-2
+    // so we need at least 5 bits for that.
+    // We add 2 to store it as a positive value 1..16=kMaxLinearMatchLength.
+    static constexpr int32_t kState64RemainingShift = 59;
+    static constexpr uint64_t kState64PosMask = (UINT64_C(1) << kState64RemainingShift) - 1;
+
+    char16_t *ownedArray_;
 
     // Fixed value referencing the UCharsTrie words.
-    const UChar *uchars_;
+    const char16_t *uchars_;
 
     // Iterator variables.
 
     // Pointer to next trie unit to read. NULL if no more matches.
-    const UChar *pos_;
+    const char16_t *pos_;
     // Remaining length of a linear-match node, minus 1. Negative if not in such a node.
     int32_t remainingMatchLength_;
 };
 
 U_NAMESPACE_END
 
+#endif /* U_SHOW_CPLUSPLUS_API */
+
 #endif  // __UCHARSTRIE_H__
diff --git a/src/third_party/icu/source/common/unicode/ucharstriebuilder.h b/src/third_party/icu/source/common/unicode/ucharstriebuilder.h
index 35e353d..1565770 100644
--- a/src/third_party/icu/source/common/unicode/ucharstriebuilder.h
+++ b/src/third_party/icu/source/common/unicode/ucharstriebuilder.h
@@ -1,10 +1,12 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
-*   Copyright (C) 2010-2014, International Business Machines
+*   Copyright (C) 2010-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *******************************************************************************
 *   file name:  ucharstriebuilder.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -16,6 +18,9 @@
 #define __UCHARSTRIEBUILDER_H__
 
 #include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
 #include "unicode/stringtriebuilder.h"
 #include "unicode/ucharstrie.h"
 #include "unicode/unistr.h"
@@ -87,21 +92,22 @@
     UCharsTrie *build(UStringTrieBuildOption buildOption, UErrorCode &errorCode);
 
     /**
-     * Builds a UCharsTrie for the add()ed data and UChar-serializes it.
+     * Builds a UCharsTrie for the add()ed data and char16_t-serializes it.
      * Once built, no further data can be add()ed until clear() is called.
      *
      * A UCharsTrie cannot be empty. At least one (string, value) pair
      * must have been add()ed.
      *
      * Multiple calls to buildUnicodeString() set the UnicodeStrings to the
-     * builder's same UChar array, without rebuilding.
+     * builder's same char16_t array, without rebuilding.
      * If buildUnicodeString() is called after build(), the trie will be
-     * re-serialized into a new array.
-     * If build() is called after buildUnicodeString(), the trie object will become
-     * the owner of the previously returned array.
+     * re-serialized into a new array (because build() passes on ownership).
+     * If build() is called after buildUnicodeString(), the trie object returned
+     * by build() will become the owner of the underlying data for the
+     * previously returned UnicodeString.
      * After clear() has been called, a new array will be used as well.
      * @param buildOption Build option, see UStringTrieBuildOption.
-     * @param result A UnicodeString which will be set to the UChar-serialized
+     * @param result A UnicodeString which will be set to the char16_t-serialized
      *               UCharsTrie for the add()ed data.
      * @param errorCode Standard ICU error code. Its input value must
      *                  pass the U_SUCCESS() test, or else the function returns
@@ -133,16 +139,16 @@
     void buildUChars(UStringTrieBuildOption buildOption, UErrorCode &errorCode);
 
     virtual int32_t getElementStringLength(int32_t i) const;
-    virtual UChar getElementUnit(int32_t i, int32_t unitIndex) const;
+    virtual char16_t getElementUnit(int32_t i, int32_t unitIndex) const;
     virtual int32_t getElementValue(int32_t i) const;
 
     virtual int32_t getLimitOfLinearMatch(int32_t first, int32_t last, int32_t unitIndex) const;
 
     virtual int32_t countElementUnits(int32_t start, int32_t limit, int32_t unitIndex) const;
     virtual int32_t skipElementsBySomeUnits(int32_t i, int32_t unitIndex, int32_t count) const;
-    virtual int32_t indexOfElementWithNextUnit(int32_t i, int32_t unitIndex, UChar unit) const;
+    virtual int32_t indexOfElementWithNextUnit(int32_t i, int32_t unitIndex, char16_t unit) const;
 
-    virtual UBool matchNodesCanHaveValues() const { return TRUE; }
+    virtual UBool matchNodesCanHaveValues() const { return true; }
 
     virtual int32_t getMaxBranchLinearSubNodeLength() const { return UCharsTrie::kMaxBranchLinearSubNodeLength; }
     virtual int32_t getMinLinearMatch() const { return UCharsTrie::kMinLinearMatch; }
@@ -150,11 +156,11 @@
 
     class UCTLinearMatchNode : public LinearMatchNode {
     public:
-        UCTLinearMatchNode(const UChar *units, int32_t len, Node *nextNode);
+        UCTLinearMatchNode(const char16_t *units, int32_t len, Node *nextNode);
         virtual UBool operator==(const Node &other) const;
         virtual void write(StringTrieBuilder &builder);
     private:
-        const UChar *s;
+        const char16_t *s;
     };
 
     virtual Node *createLinearMatchNode(int32_t i, int32_t unitIndex, int32_t length,
@@ -162,7 +168,7 @@
 
     UBool ensureCapacity(int32_t length);
     virtual int32_t write(int32_t unit);
-    int32_t write(const UChar *s, int32_t length);
+    int32_t write(const char16_t *s, int32_t length);
     virtual int32_t writeElementUnits(int32_t i, int32_t unitIndex, int32_t length);
     virtual int32_t writeValueAndFinal(int32_t i, UBool isFinal);
     virtual int32_t writeValueAndType(UBool hasValue, int32_t value, int32_t node);
@@ -173,13 +179,15 @@
     int32_t elementsCapacity;
     int32_t elementsLength;
 
-    // UChar serialization of the trie.
+    // char16_t serialization of the trie.
     // Grows from the back: ucharsLength measures from the end of the buffer!
-    UChar *uchars;
+    char16_t *uchars;
     int32_t ucharsCapacity;
     int32_t ucharsLength;
 };
 
 U_NAMESPACE_END
 
+#endif /* U_SHOW_CPLUSPLUS_API */
+
 #endif  // __UCHARSTRIEBUILDER_H__
diff --git a/src/third_party/icu/source/common/unicode/uchriter.h b/src/third_party/icu/source/common/unicode/uchriter.h
index 6d5a990..f508356 100644
--- a/src/third_party/icu/source/common/unicode/uchriter.h
+++ b/src/third_party/icu/source/common/unicode/uchriter.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
 *   Copyright (C) 1998-2005, International Business Machines
@@ -9,22 +11,25 @@
 #define UCHRITER_H
 
 #include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
 #include "unicode/chariter.h"
 
 /**
  * \file 
- * \brief C++ API: UChar Character Iterator
+ * \brief C++ API: char16_t Character Iterator
  */
  
 U_NAMESPACE_BEGIN
 
 /**
  * A concrete subclass of CharacterIterator that iterates over the
- * characters (code units or code points) in a UChar array.
+ * characters (code units or code points) in a char16_t array.
  * It's possible not only to create an
- * iterator that iterates over an entire UChar array, but also to
- * create one that iterates over only a subrange of a UChar array
- * (iterators over different subranges of the same UChar array don't
+ * iterator that iterates over an entire char16_t array, but also to
+ * create one that iterates over only a subrange of a char16_t array
+ * (iterators over different subranges of the same char16_t array don't
  * compare equal).
  * @see CharacterIterator
  * @see ForwardCharacterIterator
@@ -33,34 +38,34 @@
 class U_COMMON_API UCharCharacterIterator : public CharacterIterator {
 public:
   /**
-   * Create an iterator over the UChar array referred to by "textPtr".
+   * Create an iterator over the char16_t array referred to by "textPtr".
    * The iteration range is 0 to <code>length-1</code>.
    * text is only aliased, not adopted (the
    * destructor will not delete it).
-   * @param textPtr The UChar array to be iterated over
-   * @param length The length of the UChar array
+   * @param textPtr The char16_t array to be iterated over
+   * @param length The length of the char16_t array
    * @stable ICU 2.0
    */
-  UCharCharacterIterator(const UChar* textPtr, int32_t length);
+  UCharCharacterIterator(ConstChar16Ptr textPtr, int32_t length);
 
   /**
-   * Create an iterator over the UChar array referred to by "textPtr".
+   * Create an iterator over the char16_t array referred to by "textPtr".
    * The iteration range is 0 to <code>length-1</code>.
    * text is only aliased, not adopted (the
    * destructor will not delete it).
    * The starting
    * position is specified by "position". If "position" is outside the valid
    * iteration range, the behavior of this object is undefined.
-   * @param textPtr The UChar array to be iteratd over
-   * @param length The length of the UChar array
+   * @param textPtr The char16_t array to be iteratd over
+   * @param length The length of the char16_t array
    * @param position The starting position of the iteration
    * @stable ICU 2.0
    */
-  UCharCharacterIterator(const UChar* textPtr, int32_t length,
+  UCharCharacterIterator(ConstChar16Ptr textPtr, int32_t length,
                          int32_t position);
 
   /**
-   * Create an iterator over the UChar array referred to by "textPtr".
+   * Create an iterator over the char16_t array referred to by "textPtr".
    * The iteration range is 0 to <code>end-1</code>.
    * text is only aliased, not adopted (the
    * destructor will not delete it).
@@ -68,14 +73,14 @@
    * position is specified by "position". If begin and end do not
    * form a valid iteration range or "position" is outside the valid
    * iteration range, the behavior of this object is undefined.
-   * @param textPtr The UChar array to be iterated over
-   * @param length The length of the UChar array
+   * @param textPtr The char16_t array to be iterated over
+   * @param length The length of the char16_t array
    * @param textBegin  The begin position of the iteration range
    * @param textEnd    The end position of the iteration range
    * @param position    The starting position of the iteration
    * @stable ICU 2.0
    */
-  UCharCharacterIterator(const UChar* textPtr, int32_t length,
+  UCharCharacterIterator(ConstChar16Ptr textPtr, int32_t length,
                          int32_t textBegin,
                          int32_t textEnd,
                          int32_t position);
@@ -130,7 +135,7 @@
    * @return the CharacterIterator newly created
    * @stable ICU 2.0
    */
-  virtual CharacterIterator* clone(void) const;
+  virtual UCharCharacterIterator* clone() const;
 
   /**
    * Sets the iterator to refer to the first code unit in its
@@ -139,7 +144,7 @@
    * @return the first code unit in its iteration range.
    * @stable ICU 2.0
    */
-  virtual UChar         first(void);
+  virtual char16_t         first(void);
 
   /**
    * Sets the iterator to refer to the first code unit in its
@@ -149,7 +154,7 @@
    * @return the first code unit in its iteration range
    * @stable ICU 2.0
    */
-  virtual UChar         firstPostInc(void);
+  virtual char16_t         firstPostInc(void);
 
   /**
    * Sets the iterator to refer to the first code point in its
@@ -179,7 +184,7 @@
    * @return the last code unit in its iteration range.
    * @stable ICU 2.0
    */
-  virtual UChar         last(void);
+  virtual char16_t         last(void);
 
   /**
    * Sets the iterator to refer to the last code point in its
@@ -198,7 +203,7 @@
    * @return the code unit
    * @stable ICU 2.0
    */
-  virtual UChar         setIndex(int32_t position);
+  virtual char16_t         setIndex(int32_t position);
 
   /**
    * Sets the iterator to refer to the beginning of the code point
@@ -218,7 +223,7 @@
    * @return the code unit the iterator currently refers to.
    * @stable ICU 2.0
    */
-  virtual UChar         current(void) const;
+  virtual char16_t         current(void) const;
 
   /**
    * Returns the code point the iterator currently refers to.
@@ -234,7 +239,7 @@
    * @return the next code unit in the iteration range.
    * @stable ICU 2.0
    */
-  virtual UChar         next(void);
+  virtual char16_t         next(void);
 
   /**
    * Gets the current code unit for returning and advances to the next code unit
@@ -244,7 +249,7 @@
    * @return the current code unit.
    * @stable ICU 2.0
    */
-  virtual UChar         nextPostInc(void);
+  virtual char16_t         nextPostInc(void);
 
   /**
    * Advances to the next code point in the iteration range (toward
@@ -269,11 +274,11 @@
   virtual UChar32       next32PostInc(void);
 
   /**
-   * Returns FALSE if there are no more code units or code points
+   * Returns false if there are no more code units or code points
    * at or after the current position in the iteration range.
    * This is used with nextPostInc() or next32PostInc() in forward
    * iteration.
-   * @return FALSE if there are no more code units or code points
+   * @return false if there are no more code units or code points
    * at or after the current position in the iteration range.
    * @stable ICU 2.0
    */
@@ -286,7 +291,7 @@
    * @return the previous code unit in the iteration range.
    * @stable ICU 2.0
    */
-  virtual UChar         previous(void);
+  virtual char16_t         previous(void);
 
   /**
    * Advances to the previous code point in the iteration range (toward
@@ -298,11 +303,11 @@
   virtual UChar32       previous32(void);
 
   /**
-   * Returns FALSE if there are no more code units or code points
+   * Returns false if there are no more code units or code points
    * before the current position in the iteration range.
    * This is used with previous() or previous32() in backward
    * iteration.
-   * @return FALSE if there are no more code units or code points
+   * @return false if there are no more code units or code points
    * before the current position in the iteration range.
    * @stable ICU 2.0
    */
@@ -332,16 +337,20 @@
    * @return the new position
    * @stable ICU 2.0
    */
+#ifdef move32
+   // One of the system headers right now is sometimes defining a conflicting macro we don't use
+#undef move32
+#endif
   virtual int32_t      move32(int32_t delta, EOrigin origin);
 
   /**
    * Sets the iterator to iterate over a new range of text
    * @stable ICU 2.0
    */
-  void setText(const UChar* newText, int32_t newTextLength);
+  void setText(ConstChar16Ptr newText, int32_t newTextLength);
 
   /**
-   * Copies the UChar array under iteration into the UnicodeString
+   * Copies the char16_t array under iteration into the UnicodeString
    * referred to by "result".  Even if this iterator iterates across
    * only a part of this string, the whole string is copied.
    * @param result Receives a copy of the text under iteration.
@@ -373,9 +382,12 @@
    * Protected member text
    * @stable ICU 2.0
    */
-  const UChar*            text;
+  const char16_t*            text;
 
 };
 
 U_NAMESPACE_END
+
+#endif /* U_SHOW_CPLUSPLUS_API */
+
 #endif
diff --git a/src/third_party/icu/source/common/unicode/uclean.h b/src/third_party/icu/source/common/unicode/uclean.h
index d9a1e53..c2d920a 100644
--- a/src/third_party/icu/source/common/unicode/uclean.h
+++ b/src/third_party/icu/source/common/unicode/uclean.h
@@ -1,10 +1,12 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 * Copyright (C) 2001-2014, International Business Machines
 *                Corporation and others. All Rights Reserved.
 ******************************************************************************
 *   file name:  uclean.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -47,7 +49,7 @@
  *
  * @stable ICU 2.6
  */  
-U_STABLE void U_EXPORT2 
+U_CAPI void U_EXPORT2 
 u_init(UErrorCode *status);
 
 #ifndef U_HIDE_SYSTEM_API
@@ -68,7 +70,7 @@
  * This has the effect of restoring ICU to its initial condition, before
  * any of these override functions were installed.  Refer to
  * u_setMemoryFunctions(), u_setMutexFunctions and 
- * utrace_setFunctions().  If ICU is to be reinitialized after after
+ * utrace_setFunctions().  If ICU is to be reinitialized after
  * calling u_cleanup(), these runtime override functions will need to
  * be set up again if they are still required.
  * <p>
@@ -96,13 +98,13 @@
  * @stable ICU 2.0
  * @system
  */
-U_STABLE void U_EXPORT2 
+U_CAPI void U_EXPORT2 
 u_cleanup(void);
 
-
+U_CDECL_BEGIN
 /**
   *  Pointer type for a user supplied memory allocation function.
-  *  @param context user supplied value, obtained from from u_setMemoryFunctions().
+  *  @param context user supplied value, obtained from u_setMemoryFunctions().
   *  @param size    The number of bytes to be allocated
   *  @return        Pointer to the newly allocated memory, or NULL if the allocation failed.
   *  @stable ICU 2.8
@@ -111,7 +113,7 @@
 typedef void *U_CALLCONV UMemAllocFn(const void *context, size_t size);
 /**
   *  Pointer type for a user supplied memory re-allocation function.
-  *  @param context user supplied value, obtained from from u_setMemoryFunctions().
+  *  @param context user supplied value, obtained from u_setMemoryFunctions().
   *  @param size    The number of bytes to be allocated
   *  @return        Pointer to the newly allocated memory, or NULL if the allocation failed.
   *  @stable ICU 2.8
@@ -121,7 +123,7 @@
 /**
   *  Pointer type for a user supplied memory free  function.  Behavior should be
   *  similar the standard C library free().
-  *  @param context user supplied value, obtained from from u_setMemoryFunctions().
+  *  @param context user supplied value, obtained from u_setMemoryFunctions().
   *  @param mem     Pointer to the memory block to be resized
   *  @param size    The new size for the block
   *  @return        Pointer to the resized memory block, or NULL if the resizing failed.
@@ -146,10 +148,11 @@
  *  @stable ICU 2.8
  *  @system
  */  
-U_STABLE void U_EXPORT2 
-u_setMemoryFunctions(const void *context, UMemAllocFn *a, UMemReallocFn *r, UMemFreeFn *f, 
+U_CAPI void U_EXPORT2 
+u_setMemoryFunctions(const void *context, UMemAllocFn * U_CALLCONV_FPTR a, UMemReallocFn * U_CALLCONV_FPTR r, UMemFreeFn * U_CALLCONV_FPTR f, 
                     UErrorCode *status);
 
+U_CDECL_END
 
 #ifndef U_HIDE_DEPRECATED_API
 /*********************************************************************************
@@ -170,13 +173,14 @@
   */
 typedef void *UMTX;
 
+U_CDECL_BEGIN
 /**
   *  Function Pointer type for a user supplied mutex initialization function.
   *  The user-supplied function will be called by ICU whenever ICU needs to create a
   *  new mutex.  The function implementation should create a mutex, and store a pointer
   *  to something that uniquely identifies the mutex into the UMTX that is supplied
-  *  as a paramter.
-  *  @param context user supplied value, obtained from from u_setMutexFunctions().
+  *  as a parameter.
+  *  @param context user supplied value, obtained from u_setMutexFunctions().
   *  @param mutex   Receives a pointer that identifies the new mutex.
   *                 The mutex init function must set the UMTX to a non-null value.   
   *                 Subsequent calls by ICU to lock, unlock, or destroy a mutex will 
@@ -193,13 +197,13 @@
   *  Function Pointer type for a user supplied mutex functions.
   *  One of the  user-supplied functions with this signature will be called by ICU
   *  whenever ICU needs to lock, unlock, or destroy a mutex.
-  *  @param context user supplied value, obtained from from u_setMutexFunctions().
+  *  @param context user supplied value, obtained from u_setMutexFunctions().
   *  @param mutex   specify the mutex on which to operate.
   *  @deprecated ICU 52. This function is no longer supported.
   *  @system
   */
 typedef void U_CALLCONV UMtxFn   (const void *context, UMTX  *mutex);
-
+U_CDECL_END
 
 /**
   *  Set the functions that ICU will use for mutex operations
@@ -225,7 +229,7 @@
 
 /**
   *  Pointer type for a user supplied atomic increment or decrement function.
-  *  @param context user supplied value, obtained from from u_setAtomicIncDecFunctions().
+  *  @param context user supplied value, obtained from u_setAtomicIncDecFunctions().
   *  @param p   Pointer to a 32 bit int to be incremented or decremented
   *  @return    The value of the variable after the inc or dec operation.
   *  @deprecated ICU 52. This function is no longer supported.
diff --git a/src/third_party/icu/source/common/unicode/ucnv.h b/src/third_party/icu/source/common/unicode/ucnv.h
index 564656c..58f271c 100644
--- a/src/third_party/icu/source/common/unicode/ucnv.h
+++ b/src/third_party/icu/source/common/unicode/ucnv.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
 *   Copyright (C) 1999-2014, International Business Machines
@@ -27,7 +29,7 @@
  * converter, you can get its properties, set options, convert your data and
  * close the converter.</p>
  *
- * <p>Since many software programs recogize different converter names for
+ * <p>Since many software programs recognize different converter names for
  * different types of converters, there are other functions in this API to
  * iterate over the converter aliases. The functions {@link ucnv_getAvailableName() },
  * {@link ucnv_getAlias() } and {@link ucnv_getStandardName() } are some of the
@@ -49,21 +51,23 @@
 
 #include "unicode/ucnv_err.h"
 #include "unicode/uenum.h"
-#include "unicode/localpointer.h"
 
-#ifndef __USET_H__
+#if U_SHOW_CPLUSPLUS_API
+#include "unicode/localpointer.h"
+#endif   // U_SHOW_CPLUSPLUS_API
+
+#if !defined(USET_DEFINED) && !defined(U_IN_DOXYGEN)
+
+#define USET_DEFINED
 
 /**
- * USet is the C API type for Unicode sets.
- * It is forward-declared here to avoid including the header file if related
+ * USet is the C API type corresponding to C++ class UnicodeSet.
+ * It is forward-declared here to avoid including unicode/uset.h file if related
  * conversion APIs are not used.
- * See unicode/uset.h
  *
  * @see ucnv_getUnicodeSet
- * @stable ICU 2.6
+ * @stable ICU 2.4
  */
-struct USet;
-/** @stable ICU 2.6 */
 typedef struct USet USet;
 
 #endif
@@ -182,7 +186,7 @@
 
 /**
  * Function pointer for error callback in the codepage to unicode direction.
- * Called when an error has occured in conversion to unicode, or on open/close of the callback (see reason).
+ * Called when an error has occurred in conversion to unicode, or on open/close of the callback (see reason).
  * @param context Pointer to the callback's private data
  * @param args Information about the conversion in progress
  * @param codeUnits Points to 'length' bytes of the concerned codepage sequence
@@ -205,7 +209,7 @@
 
 /**
  * Function pointer for error callback in the unicode to codepage direction.
- * Called when an error has occured in conversion from unicode, or on open/close of the callback (see reason).
+ * Called when an error has occurred in conversion from unicode, or on open/close of the callback (see reason).
  * @param context Pointer to the callback's private data
  * @param args Information about the conversion in progress
  * @param codeUnits Points to 'length' UChars of the concerned Unicode sequence
@@ -307,7 +311,7 @@
  * lexically follows name2.
  * @stable ICU 2.0
  */
-U_STABLE int U_EXPORT2
+U_CAPI int U_EXPORT2
 ucnv_compareNames(const char *name1, const char *name2);
 
 
@@ -351,7 +355,7 @@
  *          ucnv_getAlias for a complete list that is available.
  *          If this parameter is NULL, the default converter will be used.
  * @param err outgoing error status <TT>U_MEMORY_ALLOCATION_ERROR, U_FILE_ACCESS_ERROR</TT>
- * @return the created Unicode converter object, or <TT>NULL</TT> if an error occured
+ * @return the created Unicode converter object, or <TT>NULL</TT> if an error occurred
  * @see ucnv_openU
  * @see ucnv_openCCSID
  * @see ucnv_getAvailableName
@@ -361,7 +365,7 @@
  * @see ucnv_compareNames
  * @stable ICU 2.0
  */
-U_STABLE UConverter* U_EXPORT2
+U_CAPI UConverter* U_EXPORT2
 ucnv_open(const char *converterName, UErrorCode *err);
 
 
@@ -384,14 +388,14 @@
  * @param err outgoing error status <TT>U_MEMORY_ALLOCATION_ERROR,
  *        U_FILE_ACCESS_ERROR</TT>
  * @return the created Unicode converter object, or <TT>NULL</TT> if an
- *        error occured
+ *        error occurred
  * @see ucnv_open
  * @see ucnv_openCCSID
  * @see ucnv_close
  * @see ucnv_compareNames
  * @stable ICU 2.0
  */
-U_STABLE UConverter* U_EXPORT2
+U_CAPI UConverter* U_EXPORT2
 ucnv_openU(const UChar *name,
            UErrorCode *err);
 
@@ -450,7 +454,7 @@
  * @param platform the platform in which the codepage number exists
  * @param err error status <TT>U_MEMORY_ALLOCATION_ERROR, U_FILE_ACCESS_ERROR</TT>
  * @return the created Unicode converter object, or <TT>NULL</TT> if an error
- *   occured.
+ *   occurred.
  * @see ucnv_open
  * @see ucnv_openU
  * @see ucnv_close
@@ -459,7 +463,7 @@
  * @see UConverterPlatform
  * @stable ICU 2.0
  */
-U_STABLE UConverter* U_EXPORT2
+U_CAPI UConverter* U_EXPORT2
 ucnv_openCCSID(int32_t codepage,
                UConverterPlatform platform,
                UErrorCode * err);
@@ -475,7 +479,7 @@
  * <p>The name will NOT be looked up in the alias mechanism, nor will the converter be
  * stored in the converter cache or the alias table. The only way to open further converters
  * is call this function multiple times, or use the ucnv_safeClone() function to clone a
- * 'master' converter.</p>
+ * 'primary' converter.</p>
  *
  * <p>A future version of ICU may add alias table lookups and/or caching
  * to this function.</p>
@@ -487,14 +491,14 @@
  * @param packageName name of the package (equivalent to 'path' in udata_open() call)
  * @param converterName name of the data item to be used, without suffix.
  * @param err outgoing error status <TT>U_MEMORY_ALLOCATION_ERROR, U_FILE_ACCESS_ERROR</TT>
- * @return the created Unicode converter object, or <TT>NULL</TT> if an error occured
+ * @return the created Unicode converter object, or <TT>NULL</TT> if an error occurred
  * @see udata_open
  * @see ucnv_open
  * @see ucnv_safeClone
  * @see ucnv_close
  * @stable ICU 2.2
  */
-U_STABLE UConverter* U_EXPORT2
+U_CAPI UConverter* U_EXPORT2
 ucnv_openPackage(const char *packageName, const char *converterName, UErrorCode *err);
 
 /**
@@ -536,7 +540,7 @@
  * @return pointer to the new clone
  * @stable ICU 2.0
  */
-U_STABLE UConverter * U_EXPORT2
+U_CAPI UConverter * U_EXPORT2
 ucnv_safeClone(const UConverter *cnv,
                void             *stackBuffer,
                int32_t          *pBufferSize,
@@ -565,7 +569,7 @@
  * @see ucnv_openCCSID
  * @stable ICU 2.0
  */
-U_STABLE void  U_EXPORT2
+U_CAPI void  U_EXPORT2
 ucnv_close(UConverter * converter);
 
 #if U_SHOW_CPLUSPLUS_API
@@ -594,7 +598,7 @@
  * stateful, then subChars will be an empty string.
  *
  * @param converter the Unicode converter
- * @param subChars the subsitution characters
+ * @param subChars the substitution characters
  * @param len on input the capacity of subChars, on output the number
  * of bytes copied to it
  * @param  err the outgoing error status code.
@@ -604,7 +608,7 @@
  * @see ucnv_setSubstChars
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 ucnv_getSubstChars(const UConverter *converter,
                    char *subChars,
                    int8_t *len,
@@ -629,7 +633,7 @@
  * @see ucnv_getSubstChars
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 ucnv_setSubstChars(UConverter *converter,
                    const char *subChars,
                    int8_t len,
@@ -662,7 +666,7 @@
  * @see ucnv_getSubstChars
  * @stable ICU 3.6
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 ucnv_setSubstString(UConverter *cnv,
                     const UChar *s,
                     int32_t length,
@@ -681,7 +685,7 @@
  * <TT>U_INDEX_OUTOFBOUNDS_ERROR</TT> will be returned.
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 ucnv_getInvalidChars(const UConverter *converter,
                      char *errBytes,
                      int8_t *len,
@@ -700,7 +704,7 @@
  * <TT>U_INDEX_OUTOFBOUNDS_ERROR</TT> will be returned.
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 ucnv_getInvalidUChars(const UConverter *converter,
                       UChar *errUChars,
                       int8_t *len,
@@ -713,7 +717,7 @@
  * @param converter the Unicode converter
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 ucnv_reset(UConverter *converter);
 
 /**
@@ -724,7 +728,7 @@
  * @param converter the Unicode converter
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 ucnv_resetToUnicode(UConverter *converter);
 
 /**
@@ -735,7 +739,7 @@
  * @param converter the Unicode converter
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 ucnv_resetFromUnicode(UConverter *converter);
 
 /**
@@ -788,7 +792,7 @@
  * @see ucnv_getMinCharSize
  * @stable ICU 2.0
  */
-U_STABLE int8_t U_EXPORT2
+U_CAPI int8_t U_EXPORT2
 ucnv_getMaxCharSize(const UConverter *converter);
 
 /**
@@ -821,7 +825,7 @@
  * @see ucnv_getMaxCharSize
  * @stable ICU 2.0
  */
-U_STABLE int8_t U_EXPORT2
+U_CAPI int8_t U_EXPORT2
 ucnv_getMinCharSize(const UConverter *converter);
 
 /**
@@ -830,7 +834,7 @@
  * name will be filled in.
  *
  * @param converter the Unicode converter.
- * @param displayLocale is the specific Locale we want to localised for
+ * @param displayLocale is the specific Locale we want to localized for
  * @param displayName user provided buffer to be filled in
  * @param displayNameCapacity size of displayName Buffer
  * @param err error status code
@@ -838,7 +842,7 @@
  * @see ucnv_getName
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 ucnv_getDisplayName(const UConverter *converter,
                     const char *displayLocale,
                     UChar *displayName,
@@ -855,7 +859,7 @@
  * @see ucnv_getDisplayName
  * @stable ICU 2.0
  */
-U_STABLE const char * U_EXPORT2
+U_CAPI const char * U_EXPORT2
 ucnv_getName(const UConverter *converter, UErrorCode *err);
 
 /**
@@ -875,13 +879,13 @@
  *
  * @param converter the Unicode converter
  * @param err the error status code.
- * @return If any error occurrs, -1 will be returned otherwise, the codepage number
+ * @return If any error occurs, -1 will be returned otherwise, the codepage number
  * will be returned
  * @see ucnv_openCCSID
  * @see ucnv_getPlatform
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 ucnv_getCCSID(const UConverter *converter,
               UErrorCode *err);
 
@@ -895,7 +899,7 @@
  * @return The codepage platform
  * @stable ICU 2.0
  */
-U_STABLE UConverterPlatform U_EXPORT2
+U_CAPI UConverterPlatform U_EXPORT2
 ucnv_getPlatform(const UConverter *converter,
                  UErrorCode *err);
 
@@ -907,14 +911,14 @@
  * @return the type of the converter
  * @stable ICU 2.0
  */
-U_STABLE UConverterType U_EXPORT2
+U_CAPI UConverterType U_EXPORT2
 ucnv_getType(const UConverter * converter);
 
 /**
  * Gets the "starter" (lead) bytes for converters of type MBCS.
  * Will fill in an <TT>U_ILLEGAL_ARGUMENT_ERROR</TT> if converter passed in
  * is not MBCS. Fills in an array of type UBool, with the value of the byte
- * as offset to the array. For example, if (starters[0x20] == TRUE) at return,
+ * as offset to the array. For example, if (starters[0x20] == true) at return,
  * it means that the byte 0x20 is a starter byte in this converter.
  * Context pointers are always owned by the caller.
  *
@@ -925,7 +929,7 @@
  * @see ucnv_getType
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 ucnv_getStarters(const UConverter* converter,
                  UBool starters[256],
                  UErrorCode* err);
@@ -941,8 +945,13 @@
     UCNV_ROUNDTRIP_SET,
     /** Select the set of Unicode code points with roundtrip or fallback mappings. @stable ICU 4.0 */
     UCNV_ROUNDTRIP_AND_FALLBACK_SET,
-    /** Number of UConverterUnicodeSet selectors. @stable ICU 2.6 */
+#ifndef U_HIDE_DEPRECATED_API
+    /**
+     * Number of UConverterUnicodeSet selectors.
+     * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
+     */
     UCNV_SET_COUNT
+#endif  // U_HIDE_DEPRECATED_API
 } UConverterUnicodeSet;
 
 
@@ -991,7 +1000,7 @@
  * @see uset_close
  * @stable ICU 2.6
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 ucnv_getUnicodeSet(const UConverter *cnv,
                    USet *setFillIn,
                    UConverterUnicodeSet whichSet,
@@ -1008,7 +1017,7 @@
  * @see ucnv_setToUCallBack
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 ucnv_getToUCallBack (const UConverter * converter,
                      UConverterToUCallback *action,
                      const void **context);
@@ -1024,7 +1033,7 @@
  * @see ucnv_setFromUCallBack
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 ucnv_getFromUCallBack (const UConverter * converter,
                        UConverterFromUCallback *action,
                        const void **context);
@@ -1044,7 +1053,7 @@
  * @see ucnv_getToUCallBack
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 ucnv_setToUCallBack (UConverter * converter,
                      UConverterToUCallback newAction,
                      const void* newContext,
@@ -1067,7 +1076,7 @@
  * @see ucnv_getFromUCallBack
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 ucnv_setFromUCallBack (UConverter * converter,
                        UConverterFromUCallback newAction,
                        const void *newContext,
@@ -1094,7 +1103,7 @@
  *  consumed. At that point, the caller should reset the source and
  *  sourceLimit pointers to point to the next chunk.
  *
- * At the end of the stream (flush==TRUE), the input is completely consumed
+ * At the end of the stream (flush==true), the input is completely consumed
  * when *source==sourceLimit and no error code is set.
  * The converter object is then automatically reset by this function.
  * (This means that a converter need not be reset explicitly between data
@@ -1119,9 +1128,9 @@
  * e.g: <TT>offsets[3]</TT> is equal to 6, it means that the <TT>target[3]</TT> was a result of transcoding <TT>source[6]</TT>
  * For output data carried across calls, and other data without a specific source character
  * (such as from escape sequences or callbacks)  -1 will be placed for offsets.
- * @param flush set to <TT>TRUE</TT> if the current source buffer is the last available
- * chunk of the source, <TT>FALSE</TT> otherwise. Note that if a failing status is returned,
- * this function may have to be called multiple times with flush set to <TT>TRUE</TT> until
+ * @param flush set to <TT>true</TT> if the current source buffer is the last available
+ * chunk of the source, <TT>false</TT> otherwise. Note that if a failing status is returned,
+ * this function may have to be called multiple times with flush set to <TT>true</TT> until
  * the source buffer is consumed.
  * @param err the error status.  <TT>U_ILLEGAL_ARGUMENT_ERROR</TT> will be set if the
  * converter is <TT>NULL</TT>.
@@ -1133,7 +1142,7 @@
  * @see ucnv_setToUCallBack
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 ucnv_fromUnicode (UConverter * converter,
                   char **target,
                   const char *targetLimit,
@@ -1163,7 +1172,7 @@
  *  consumed. At that point, the caller should reset the source and
  *  sourceLimit pointers to point to the next chunk.
  *
- * At the end of the stream (flush==TRUE), the input is completely consumed
+ * At the end of the stream (flush==true), the input is completely consumed
  * when *source==sourceLimit and no error code is set
  * The converter object is then automatically reset by this function.
  * (This means that a converter need not be reset explicitly between data
@@ -1187,9 +1196,9 @@
  * e.g: <TT>offsets[3]</TT> is equal to 6, it means that the <TT>target[3]</TT> was a result of transcoding <TT>source[6]</TT>
  * For output data carried across calls, and other data without a specific source character
  * (such as from escape sequences or callbacks)  -1 will be placed for offsets.
- * @param flush set to <TT>TRUE</TT> if the current source buffer is the last available
- * chunk of the source, <TT>FALSE</TT> otherwise. Note that if a failing status is returned,
- * this function may have to be called multiple times with flush set to <TT>TRUE</TT> until
+ * @param flush set to <TT>true</TT> if the current source buffer is the last available
+ * chunk of the source, <TT>false</TT> otherwise. Note that if a failing status is returned,
+ * this function may have to be called multiple times with flush set to <TT>true</TT> until
  * the source buffer is consumed.
  * @param err the error status.  <TT>U_ILLEGAL_ARGUMENT_ERROR</TT> will be set if the
  * converter is <TT>NULL</TT>.
@@ -1202,7 +1211,7 @@
  * @see ucnv_getNextUChar
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 ucnv_toUnicode(UConverter *converter,
                UChar **target,
                const UChar *targetLimit,
@@ -1239,7 +1248,7 @@
  * @see UCNV_GET_MAX_BYTES_FOR_STRING
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 ucnv_fromUChars(UConverter *cnv,
                 char *dest, int32_t destCapacity,
                 const UChar *src, int32_t srcLength,
@@ -1271,7 +1280,7 @@
  * @see ucnv_convert
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 ucnv_toUChars(UConverter *cnv,
               UChar *dest, int32_t destCapacity,
               const char *src, int32_t srcLength,
@@ -1289,7 +1298,7 @@
  * - Convenient.
  *
  * Limitations compared to ucnv_toUnicode():
- * - Always assumes flush=TRUE.
+ * - Always assumes flush=true.
  *   This makes ucnv_getNextUChar() unsuitable for "streaming" conversion,
  *   that is, for where the input is supplied in multiple buffers,
  *   because ucnv_getNextUChar() will assume the end of the input at the end
@@ -1300,7 +1309,7 @@
  * ucnv_getNextUChar() uses the current state of the converter
  * (unlike ucnv_toUChars() which always resets first).
  * However, if ucnv_getNextUChar() is called after ucnv_toUnicode()
- * stopped in the middle of a character sequence (with flush=FALSE),
+ * stopped in the middle of a character sequence (with flush=false),
  * then ucnv_getNextUChar() will always use the slower ucnv_toUnicode()
  * internally until the next character boundary.
  * (This is new in ICU 2.6. In earlier releases, ucnv_getNextUChar() had to
@@ -1347,7 +1356,7 @@
  * @see ucnv_convert
  * @stable ICU 2.0
  */
-U_STABLE UChar32 U_EXPORT2
+U_CAPI UChar32 U_EXPORT2
 ucnv_getNextUChar(UConverter * converter,
                   const char **source,
                   const char * sourceLimit,
@@ -1379,7 +1388,7 @@
  *
  * ucnv_convertEx() also provides further convenience:
  * - an option to reset the converters at the beginning
- *   (if reset==TRUE, see parameters;
+ *   (if reset==true, see parameters;
  *    also sets *pivotTarget=*pivotSource=pivotStart)
  * - allow NUL-terminated input
  *   (only a single NUL byte, will not work for charsets with multi-byte NULs)
@@ -1436,7 +1445,7 @@
  *                    &target, u8+capacity,
  *                    &s, s+length,
  *                    NULL, NULL, NULL, NULL,
- *                    TRUE, TRUE,
+ *                    true, true,
  *                    pErrorCode);
  *
  *     myReleaseCachedUTF8Converter(utf8Cnv);
@@ -1468,7 +1477,7 @@
  *                      It must be pivotStart<=*pivotSource<=*pivotTarget<=pivotLimit
  *                      and pivotStart<pivotLimit (unless pivotStart==NULL).
  * @param pivotLimit    Pointer to the first unit after the pivot buffer.
- * @param reset         If TRUE, then ucnv_resetToUnicode(sourceCnv) and
+ * @param reset         If true, then ucnv_resetToUnicode(sourceCnv) and
  *                      ucnv_resetFromUnicode(targetCnv) are called, and the
  *                      pivot pointers are reset (*pivotTarget=*pivotSource=pivotStart).
  * @param flush         If true, indicates the end of the input.
@@ -1491,7 +1500,7 @@
  * @see ucnv_toUChars
  * @stable ICU 2.6
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 ucnv_convertEx(UConverter *targetCnv, UConverter *sourceCnv,
                char **target, const char *targetLimit,
                const char **source, const char *sourceLimit,
@@ -1555,7 +1564,7 @@
  * @see ucnv_getNextUChar
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 ucnv_convert(const char *toConverterName,
              const char *fromConverterName,
              char *target,
@@ -1609,7 +1618,7 @@
  * @see ucnv_toUChars
  * @stable ICU 2.6
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 ucnv_toAlgorithmic(UConverterType algorithmicType,
                    UConverter *cnv,
                    char *target, int32_t targetCapacity,
@@ -1661,7 +1670,7 @@
  * @see ucnv_toUChars
  * @stable ICU 2.6
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 ucnv_fromAlgorithmic(UConverter *cnv,
                      UConverterType algorithmicType,
                      char *target, int32_t targetCapacity,
@@ -1675,7 +1684,7 @@
  * @see ucnv_close
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 ucnv_flushCache(void);
 
 /**
@@ -1685,7 +1694,7 @@
  * @see ucnv_getAvailableName
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 ucnv_countAvailable(void);
 
 /**
@@ -1698,7 +1707,7 @@
  * @see ucnv_countAvailable
  * @stable ICU 2.0
  */
-U_STABLE const char* U_EXPORT2
+U_CAPI const char* U_EXPORT2
 ucnv_getAvailableName(int32_t n);
 
 /**
@@ -1713,7 +1722,7 @@
  * @see uenum_next
  * @stable ICU 2.4
  */
-U_STABLE UEnumeration * U_EXPORT2
+U_CAPI UEnumeration * U_EXPORT2
 ucnv_openAllNames(UErrorCode *pErrorCode);
 
 /**
@@ -1726,7 +1735,7 @@
  * @return number of names on alias list for given alias
  * @stable ICU 2.0
  */
-U_STABLE uint16_t U_EXPORT2
+U_CAPI uint16_t U_EXPORT2
 ucnv_countAliases(const char *alias, UErrorCode *pErrorCode);
 
 /**
@@ -1741,7 +1750,7 @@
  * @see ucnv_countAliases
  * @stable ICU 2.0
  */
-U_STABLE const char * U_EXPORT2
+U_CAPI const char * U_EXPORT2
 ucnv_getAlias(const char *alias, uint16_t n, UErrorCode *pErrorCode);
 
 /**
@@ -1757,7 +1766,7 @@
  * @param pErrorCode result of operation
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 ucnv_getAliases(const char *alias, const char **aliases, UErrorCode *pErrorCode);
 
 /**
@@ -1783,7 +1792,7 @@
  * @see uenum_next
  * @stable ICU 2.2
  */
-U_STABLE UEnumeration * U_EXPORT2
+U_CAPI UEnumeration * U_EXPORT2
 ucnv_openStandardNames(const char *convName,
                        const char *standard,
                        UErrorCode *pErrorCode);
@@ -1793,7 +1802,7 @@
  * @return number of standards
  * @stable ICU 2.0
  */
-U_STABLE uint16_t U_EXPORT2
+U_CAPI uint16_t U_EXPORT2
 ucnv_countStandards(void);
 
 /**
@@ -1803,7 +1812,7 @@
  * @return returns the name of the standard at given index. Owned by the library.
  * @stable ICU 2.0
  */
-U_STABLE const char * U_EXPORT2
+U_CAPI const char * U_EXPORT2
 ucnv_getStandard(uint16_t n, UErrorCode *pErrorCode);
 
 /**
@@ -1825,7 +1834,7 @@
  *         then <code>NULL</code> is returned. Owned by the library.
  * @stable ICU 2.0
  */
-U_STABLE const char * U_EXPORT2
+U_CAPI const char * U_EXPORT2
 ucnv_getStandardName(const char *name, const char *standard, UErrorCode *pErrorCode);
 
 /**
@@ -1847,7 +1856,7 @@
  * @see ucnv_getStandardName
  * @stable ICU 2.4
  */
-U_STABLE const char * U_EXPORT2
+U_CAPI const char * U_EXPORT2
 ucnv_getCanonicalName(const char *alias, const char *standard, UErrorCode *pErrorCode);
 
 /**
@@ -1864,7 +1873,7 @@
  * @see ucnv_setDefaultName
  * @stable ICU 2.0
  */
-U_STABLE const char * U_EXPORT2
+U_CAPI const char * U_EXPORT2
 ucnv_getDefaultName(void);
 
 #ifndef U_HIDE_SYSTEM_API
@@ -1884,7 +1893,7 @@
  * @system
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 ucnv_setDefaultName(const char *name);
 #endif  /* U_HIDE_SYSTEM_API */
 
@@ -1905,18 +1914,18 @@
  * @see ucnv_isAmbiguous
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 ucnv_fixFileSeparator(const UConverter *cnv, UChar *source, int32_t sourceLen);
 
 /**
  * Determines if the converter contains ambiguous mappings of the same
  * character or not.
  * @param cnv the converter to be tested
- * @return TRUE if the converter contains ambiguous mapping of the same
- * character, FALSE otherwise.
+ * @return true if the converter contains ambiguous mapping of the same
+ * character, false otherwise.
  * @stable ICU 2.0
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 ucnv_isAmbiguous(const UConverter *cnv);
 
 /**
@@ -1929,12 +1938,12 @@
  * http://www.icu-project.org/userguide/conversion-data.html#ucmformat
  *
  * @param cnv The converter to set the fallback mapping usage on.
- * @param usesFallback TRUE if the user wants the converter to take advantage of the fallback
- * mapping, FALSE otherwise.
+ * @param usesFallback true if the user wants the converter to take advantage of the fallback
+ * mapping, false otherwise.
  * @stable ICU 2.0
  * @see ucnv_usesFallback
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 ucnv_setFallback(UConverter *cnv, UBool usesFallback);
 
 /**
@@ -1942,11 +1951,11 @@
  * This flag has restrictions, see ucnv_setFallback().
  *
  * @param cnv The converter to be tested
- * @return TRUE if the converter uses fallback, FALSE otherwise.
+ * @return true if the converter uses fallback, false otherwise.
  * @stable ICU 2.0
  * @see ucnv_setFallback
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 ucnv_usesFallback(const UConverter *cnv);
 
 /**
@@ -1978,7 +1987,7 @@
  * @return The name of the encoding detected. NULL if encoding is not detected.
  * @stable ICU 2.4
  */
-U_STABLE const char* U_EXPORT2
+U_CAPI const char* U_EXPORT2
 ucnv_detectUnicodeSignature(const char* source,
                             int32_t sourceLength,
                             int32_t *signatureLength,
@@ -1995,7 +2004,7 @@
  * @return The number of UChars in the state. -1 if an error is encountered.
  * @stable ICU 3.4
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 ucnv_fromUCountPending(const UConverter* cnv, UErrorCode* status);
 
 /**
@@ -2009,7 +2018,7 @@
  * @return The number of chars in the state. -1 if an error is encountered.
  * @stable ICU 3.4
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 ucnv_toUCountPending(const UConverter* cnv, UErrorCode* status);
 
 /**
@@ -2021,13 +2030,13 @@
  * but a UTF-32 converter encodes each code point with 4 bytes.
  * Note: This method is not intended to be used to determine whether the charset has a
  * fixed ratio of bytes to Unicode codes <i>units</i> for any particular Unicode encoding form.
- * FALSE is returned with the UErrorCode if error occurs or cnv is NULL.
+ * false is returned with the UErrorCode if error occurs or cnv is NULL.
  * @param cnv       The converter to be tested
  * @param status    ICU error code in/out paramter
- * @return TRUE if the converter is fixed-width
+ * @return true if the converter is fixed-width
  * @stable ICU 4.8
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 ucnv_isFixedWidth(UConverter *cnv, UErrorCode *status);
 
 #endif
diff --git a/src/third_party/icu/source/common/unicode/ucnv_cb.h b/src/third_party/icu/source/common/unicode/ucnv_cb.h
index f0e67ba..41845d1 100644
--- a/src/third_party/icu/source/common/unicode/ucnv_cb.h
+++ b/src/third_party/icu/source/common/unicode/ucnv_cb.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
 *   Copyright (C) 2000-2004, International Business Machines
@@ -82,7 +84,7 @@
  * @see ucnv_cbFromUWriteSub
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 ucnv_cbFromUWriteBytes (UConverterFromUnicodeArgs *args,
                         const char* source,
                         int32_t length,
@@ -102,7 +104,7 @@
  * @see ucnv_cbFromUWriteBytes
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2 
+U_CAPI void U_EXPORT2 
 ucnv_cbFromUWriteSub (UConverterFromUnicodeArgs *args,
                       int32_t offsetIndex,
                       UErrorCode * err);
@@ -119,7 +121,7 @@
  * @see ucnv_cbToUWriteSub
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2 ucnv_cbFromUWriteUChars(UConverterFromUnicodeArgs *args,
+U_CAPI void U_EXPORT2 ucnv_cbFromUWriteUChars(UConverterFromUnicodeArgs *args,
                              const UChar** source,
                              const UChar*  sourceLimit,
                              int32_t offsetIndex,
@@ -138,7 +140,7 @@
  * @see ucnv_cbToUWriteSub
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2 ucnv_cbToUWriteUChars (UConverterToUnicodeArgs *args,
+U_CAPI void U_EXPORT2 ucnv_cbToUWriteUChars (UConverterToUnicodeArgs *args,
                                              const UChar* source,
                                              int32_t length,
                                              int32_t offsetIndex,
@@ -154,7 +156,7 @@
  * @see ucnv_cbToUWriteUChars
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2 ucnv_cbToUWriteSub (UConverterToUnicodeArgs *args,
+U_CAPI void U_EXPORT2 ucnv_cbToUWriteSub (UConverterToUnicodeArgs *args,
                        int32_t offsetIndex,
                        UErrorCode * err);
 #endif
diff --git a/src/third_party/icu/source/common/unicode/ucnv_err.h b/src/third_party/icu/source/common/unicode/ucnv_err.h
index e092e95..7209ba5 100644
--- a/src/third_party/icu/source/common/unicode/ucnv_err.h
+++ b/src/third_party/icu/source/common/unicode/ucnv_err.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
 *   Copyright (C) 1999-2009, International Business Machines
@@ -117,19 +119,19 @@
 #define UCNV_ESCAPE_JAVA      "J"
 /**
  * FROM_U_CALLBACK_ESCAPE context option to escape the code unit according to C (\\uXXXX \\UXXXXXXXX)
- * TO_U_CALLBACK_ESCAPE option to escape the character value accoding to C (\\xXXXX)
+ * TO_U_CALLBACK_ESCAPE option to escape the character value according to C (\\xXXXX)
  * @stable ICU 2.0
  */
 #define UCNV_ESCAPE_C         "C"
 /**
  * FROM_U_CALLBACK_ESCAPE context option to escape the code unit according to XML Decimal escape \htmlonly(&amp;#DDDD;)\endhtmlonly
- * TO_U_CALLBACK_ESCAPE context option to escape the character value accoding to XML Decimal escape \htmlonly(&amp;#DDDD;)\endhtmlonly
+ * TO_U_CALLBACK_ESCAPE context option to escape the character value according to XML Decimal escape \htmlonly(&amp;#DDDD;)\endhtmlonly
  * @stable ICU 2.0
  */
 #define UCNV_ESCAPE_XML_DEC   "D"
 /**
  * FROM_U_CALLBACK_ESCAPE context option to escape the code unit according to XML Hex escape \htmlonly(&amp;#xXXXX;)\endhtmlonly
- * TO_U_CALLBACK_ESCAPE context option to escape the character value accoding to XML Hex escape \htmlonly(&amp;#xXXXX;)\endhtmlonly
+ * TO_U_CALLBACK_ESCAPE context option to escape the character value according to XML Hex escape \htmlonly(&amp;#xXXXX;)\endhtmlonly
  * @stable ICU 2.0
  */
 #define UCNV_ESCAPE_XML_HEX   "X"
@@ -169,7 +171,7 @@
                              code points.
                              The error code U_INVALID_CHAR_FOUND will be set. */
     UCNV_RESET = 3,       /**< The callback is called with this reason when a
-                             'reset' has occured. Callback should reset all
+                             'reset' has occurred. Callback should reset all
                              state. */
     UCNV_CLOSE = 4,        /**< Called when the converter is closed. The
                              callback should release any allocated memory.*/
@@ -191,13 +193,13 @@
  */
 typedef struct {
     uint16_t size;              /**< The size of this struct. @stable ICU 2.0 */
-    UBool flush;                /**< The internal state of converter will be reset and data flushed if set to TRUE. @stable ICU 2.0    */
+    UBool flush;                /**< The internal state of converter will be reset and data flushed if set to true. @stable ICU 2.0    */
     UConverter *converter;      /**< Pointer to the converter that is opened and to which this struct is passed as an argument. @stable ICU 2.0  */
     const UChar *source;        /**< Pointer to the source source buffer. @stable ICU 2.0    */
     const UChar *sourceLimit;   /**< Pointer to the limit (end + 1) of source buffer. @stable ICU 2.0    */
     char *target;               /**< Pointer to the target buffer. @stable ICU 2.0    */
     const char *targetLimit;    /**< Pointer to the limit (end + 1) of target buffer. @stable ICU 2.0     */
-    int32_t *offsets;           /**< Pointer to the buffer that recieves the offsets. *offset = blah ; offset++;. @stable ICU 2.0  */
+    int32_t *offsets;           /**< Pointer to the buffer that receives the offsets. *offset = blah ; offset++;. @stable ICU 2.0  */
 } UConverterFromUnicodeArgs;
 
 
@@ -207,13 +209,13 @@
  */
 typedef struct {
     uint16_t size;              /**< The size of this struct   @stable ICU 2.0 */
-    UBool flush;                /**< The internal state of converter will be reset and data flushed if set to TRUE. @stable ICU 2.0   */
+    UBool flush;                /**< The internal state of converter will be reset and data flushed if set to true. @stable ICU 2.0   */
     UConverter *converter;      /**< Pointer to the converter that is opened and to which this struct is passed as an argument. @stable ICU 2.0 */
     const char *source;         /**< Pointer to the source source buffer. @stable ICU 2.0    */
     const char *sourceLimit;    /**< Pointer to the limit (end + 1) of source buffer. @stable ICU 2.0    */
     UChar *target;              /**< Pointer to the target buffer. @stable ICU 2.0    */
     const UChar *targetLimit;   /**< Pointer to the limit (end + 1) of target buffer. @stable ICU 2.0     */
-    int32_t *offsets;           /**< Pointer to the buffer that recieves the offsets. *offset = blah ; offset++;. @stable ICU 2.0  */
+    int32_t *offsets;           /**< Pointer to the buffer that receives the offsets. *offset = blah ; offset++;. @stable ICU 2.0  */
 } UConverterToUnicodeArgs;
 
 
@@ -231,7 +233,7 @@
  * @param err This should always be set to a failure status prior to calling.
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2 UCNV_FROM_U_CALLBACK_STOP (
+U_CAPI void U_EXPORT2 UCNV_FROM_U_CALLBACK_STOP (
                   const void *context,
                   UConverterFromUnicodeArgs *fromUArgs,
                   const UChar* codeUnits,
@@ -255,7 +257,7 @@
  * @param err This should always be set to a failure status prior to calling.
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2 UCNV_TO_U_CALLBACK_STOP (
+U_CAPI void U_EXPORT2 UCNV_TO_U_CALLBACK_STOP (
                   const void *context,
                   UConverterToUnicodeArgs *toUArgs,
                   const char* codeUnits,
@@ -282,7 +284,7 @@
  *      otherwise this value will be set to a failure status.
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2 UCNV_FROM_U_CALLBACK_SKIP (
+U_CAPI void U_EXPORT2 UCNV_FROM_U_CALLBACK_SKIP (
                   const void *context,
                   UConverterFromUnicodeArgs *fromUArgs,
                   const UChar* codeUnits,
@@ -312,7 +314,7 @@
  * @see ucnv_setSubstChars
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2 UCNV_FROM_U_CALLBACK_SUBSTITUTE (
+U_CAPI void U_EXPORT2 UCNV_FROM_U_CALLBACK_SUBSTITUTE (
                   const void *context,
                   UConverterFromUnicodeArgs *fromUArgs,
                   const UChar* codeUnits,
@@ -368,7 +370,7 @@
  *      otherwise this value will be set to a failure status.
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2 UCNV_FROM_U_CALLBACK_ESCAPE (
+U_CAPI void U_EXPORT2 UCNV_FROM_U_CALLBACK_ESCAPE (
                   const void *context,
                   UConverterFromUnicodeArgs *fromUArgs,
                   const UChar* codeUnits,
@@ -396,7 +398,7 @@
  *      otherwise this value will be set to a failure status.
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2 UCNV_TO_U_CALLBACK_SKIP (
+U_CAPI void U_EXPORT2 UCNV_TO_U_CALLBACK_SKIP (
                   const void *context,
                   UConverterToUnicodeArgs *toUArgs,
                   const char* codeUnits,
@@ -422,7 +424,7 @@
  *      otherwise this value will be set to a failure status.
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2 UCNV_TO_U_CALLBACK_SUBSTITUTE (
+U_CAPI void U_EXPORT2 UCNV_TO_U_CALLBACK_SUBSTITUTE (
                   const void *context,
                   UConverterToUnicodeArgs *toUArgs,
                   const char* codeUnits,
@@ -448,7 +450,7 @@
  * @stable ICU 2.0
  */
 
-U_STABLE void U_EXPORT2 UCNV_TO_U_CALLBACK_ESCAPE (
+U_CAPI void U_EXPORT2 UCNV_TO_U_CALLBACK_ESCAPE (
                   const void *context,
                   UConverterToUnicodeArgs *toUArgs,
                   const char* codeUnits,
diff --git a/src/third_party/icu/source/common/unicode/ucnvsel.h b/src/third_party/icu/source/common/unicode/ucnvsel.h
index eb9588e..5e0a71c 100644
--- a/src/third_party/icu/source/common/unicode/ucnvsel.h
+++ b/src/third_party/icu/source/common/unicode/ucnvsel.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -27,7 +29,10 @@
 #include "unicode/utf16.h"
 #include "unicode/uenum.h"
 #include "unicode/ucnv.h"
+
+#if U_SHOW_CPLUSPLUS_API
 #include "unicode/localpointer.h"
+#endif   // U_SHOW_CPLUSPLUS_API
 
 /**
  * \file
@@ -70,7 +75,7 @@
  *
  * @stable ICU 4.2
  */
-U_STABLE UConverterSelector* U_EXPORT2
+U_CAPI UConverterSelector* U_EXPORT2
 ucnvsel_open(const char* const*  converterList, int32_t converterListSize,
              const USet* excludedCodePoints,
              const UConverterUnicodeSet whichSet, UErrorCode* status);
@@ -88,7 +93,7 @@
  *
  * @stable ICU 4.2
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 ucnvsel_close(UConverterSelector *sel);
 
 #if U_SHOW_CPLUSPLUS_API
@@ -125,7 +130,7 @@
  *
  * @stable ICU 4.2
  */
-U_STABLE UConverterSelector* U_EXPORT2
+U_CAPI UConverterSelector* U_EXPORT2
 ucnvsel_openFromSerialized(const void* buffer, int32_t length, UErrorCode* status);
 
 /**
@@ -142,7 +147,7 @@
  *
  * @stable ICU 4.2
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 ucnvsel_serialize(const UConverterSelector* sel,
                   void* buffer, int32_t bufferCapacity, UErrorCode* status);
 
@@ -160,7 +165,7 @@
  *
  * @stable ICU 4.2
  */
-U_STABLE UEnumeration * U_EXPORT2
+U_CAPI UEnumeration * U_EXPORT2
 ucnvsel_selectForString(const UConverterSelector* sel,
                         const UChar *s, int32_t length, UErrorCode *status);
 
@@ -178,7 +183,7 @@
  *
  * @stable ICU 4.2
  */
-U_STABLE UEnumeration * U_EXPORT2
+U_CAPI UEnumeration * U_EXPORT2
 ucnvsel_selectForUTF8(const UConverterSelector* sel,
                       const char *s, int32_t length, UErrorCode *status);
 
diff --git a/src/third_party/icu/source/common/unicode/uconfig.h b/src/third_party/icu/source/common/unicode/uconfig.h
index 592eaae..53ecdcc 100644
--- a/src/third_party/icu/source/common/unicode/uconfig.h
+++ b/src/third_party/icu/source/common/unicode/uconfig.h
@@ -1,10 +1,12 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*  
 **********************************************************************
-*   Copyright (C) 2002-2015, International Business Machines
+*   Copyright (C) 2002-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 **********************************************************************
 *   file name:  uconfig.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -74,7 +76,7 @@
 #endif
 
 /**
- * Determines wheter to enable auto cleanup of libraries. 
+ * Determines whether to enable auto cleanup of libraries. 
  * @internal
  */
 #ifndef UCLN_NO_AUTO_CLEANUP
@@ -188,7 +190,7 @@
 
 #ifdef U_HAVE_LIB_SUFFIX
     /* Use the predefined value. */
-#elif defined(U_LIB_SUFFIX_C_NAME)
+#elif defined(U_LIB_SUFFIX_C_NAME) || defined(U_IN_DOXYGEN)
 #   define U_HAVE_LIB_SUFFIX 1
 #endif
 
@@ -267,7 +269,8 @@
 
 /**
  * \def UCONFIG_NO_CONVERSION
- * ICU will not completely build with this switch turned on.
+ * ICU will not completely build (compiling the tools fails) with this
+ * switch turned on.
  * This switch turns off all converters.
  *
  * You may want to use this together with U_CHARSET_IS_UTF8 defined to 1
@@ -293,7 +296,7 @@
  * This is not possible on EBCDIC platforms
  * because they need ibm-37 or ibm-1047 default converters.
  *
- * @draft ICU 55
+ * @stable ICU 55
  */
 #ifndef UCONFIG_ONLY_HTML_CONVERSION
 #   define UCONFIG_ONLY_HTML_CONVERSION 0
@@ -325,7 +328,9 @@
  */
 #ifndef UCONFIG_NO_NORMALIZATION
 #   define UCONFIG_NO_NORMALIZATION 0
-#elif UCONFIG_NO_NORMALIZATION
+#endif
+
+#if UCONFIG_NO_NORMALIZATION
     /* common library */
     /* ICU 50 CJK dictionary BreakIterator uses normalization */
 #   define UCONFIG_NO_BREAK_ITERATION 1
@@ -371,6 +376,18 @@
 #   define UCONFIG_MSGPAT_DEFAULT_APOSTROPHE_MODE UMSGPAT_APOS_DOUBLE_OPTIONAL
 #endif
 
+/**
+ * \def UCONFIG_USE_WINDOWS_LCID_MAPPING_API
+ * On platforms where U_PLATFORM_HAS_WIN32_API is true, this switch determines
+ * if the Windows platform APIs are used for LCID<->Locale Name conversions.
+ * Otherwise, only the built-in ICU tables are used.
+ * 
+ * @internal ICU 64
+ */
+#ifndef UCONFIG_USE_WINDOWS_LCID_MAPPING_API
+#   define UCONFIG_USE_WINDOWS_LCID_MAPPING_API 1
+#endif
+
 /* i18n library switches ---------------------------------------------------- */
 
 /**
@@ -433,17 +450,6 @@
 #   define UCONFIG_HAVE_PARSEALLINPUT 1
 #endif
 
-
-/**
- * \def UCONFIG_FORMAT_FASTPATHS_49
- * This switch turns on other formatting fastpaths. Binary incompatible in object DecimalFormat and DecimalFormatSymbols
- *
- * @internal
- */
-#ifndef UCONFIG_FORMAT_FASTPATHS_49
-#   define UCONFIG_FORMAT_FASTPATHS_49 1
-#endif
-
 /**
  * \def UCONFIG_NO_FILTERED_BREAK_ITERATION
  * This switch turns off filtered break iteration code.
@@ -454,4 +460,4 @@
 #   define UCONFIG_NO_FILTERED_BREAK_ITERATION 0
 #endif
 
-#endif
+#endif  // __UCONFIG_H__
diff --git a/src/third_party/icu/source/common/unicode/ucpmap.h b/src/third_party/icu/source/common/unicode/ucpmap.h
new file mode 100644
index 0000000..31e1365
--- /dev/null
+++ b/src/third_party/icu/source/common/unicode/ucpmap.h
@@ -0,0 +1,159 @@
+// © 2018 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+// ucpmap.h
+// created: 2018sep03 Markus W. Scherer
+
+#ifndef __UCPMAP_H__
+#define __UCPMAP_H__
+
+#include "unicode/utypes.h"
+
+U_CDECL_BEGIN
+
+/**
+ * \file
+ *
+ * This file defines an abstract map from Unicode code points to integer values.
+ *
+ * @see UCPMap
+ * @see UCPTrie
+ * @see UMutableCPTrie
+ */
+
+/**
+ * Abstract map from Unicode code points (U+0000..U+10FFFF) to integer values.
+ *
+ * @see UCPTrie
+ * @see UMutableCPTrie
+ * @stable ICU 63
+ */
+typedef struct UCPMap UCPMap;
+
+/**
+ * Selectors for how ucpmap_getRange() etc. should report value ranges overlapping with surrogates.
+ * Most users should use UCPMAP_RANGE_NORMAL.
+ *
+ * @see ucpmap_getRange
+ * @see ucptrie_getRange
+ * @see umutablecptrie_getRange
+ * @stable ICU 63
+ */
+enum UCPMapRangeOption {
+    /**
+     * ucpmap_getRange() enumerates all same-value ranges as stored in the map.
+     * Most users should use this option.
+     * @stable ICU 63
+     */
+    UCPMAP_RANGE_NORMAL,
+    /**
+     * ucpmap_getRange() enumerates all same-value ranges as stored in the map,
+     * except that lead surrogates (U+D800..U+DBFF) are treated as having the
+     * surrogateValue, which is passed to getRange() as a separate parameter.
+     * The surrogateValue is not transformed via filter().
+     * See U_IS_LEAD(c).
+     *
+     * Most users should use UCPMAP_RANGE_NORMAL instead.
+     *
+     * This option is useful for maps that map surrogate code *units* to
+     * special values optimized for UTF-16 string processing
+     * or for special error behavior for unpaired surrogates,
+     * but those values are not to be associated with the lead surrogate code *points*.
+     * @stable ICU 63
+     */
+    UCPMAP_RANGE_FIXED_LEAD_SURROGATES,
+    /**
+     * ucpmap_getRange() enumerates all same-value ranges as stored in the map,
+     * except that all surrogates (U+D800..U+DFFF) are treated as having the
+     * surrogateValue, which is passed to getRange() as a separate parameter.
+     * The surrogateValue is not transformed via filter().
+     * See U_IS_SURROGATE(c).
+     *
+     * Most users should use UCPMAP_RANGE_NORMAL instead.
+     *
+     * This option is useful for maps that map surrogate code *units* to
+     * special values optimized for UTF-16 string processing
+     * or for special error behavior for unpaired surrogates,
+     * but those values are not to be associated with the lead surrogate code *points*.
+     * @stable ICU 63
+     */
+    UCPMAP_RANGE_FIXED_ALL_SURROGATES
+};
+#ifndef U_IN_DOXYGEN
+typedef enum UCPMapRangeOption UCPMapRangeOption;
+#endif
+
+/**
+ * Returns the value for a code point as stored in the map, with range checking.
+ * Returns an implementation-defined error value if c is not in the range 0..U+10FFFF.
+ *
+ * @param map the map
+ * @param c the code point
+ * @return the map value,
+ *         or an implementation-defined error value if the code point is not in the range 0..U+10FFFF
+ * @stable ICU 63
+ */
+U_CAPI uint32_t U_EXPORT2
+ucpmap_get(const UCPMap *map, UChar32 c);
+
+/**
+ * Callback function type: Modifies a map value.
+ * Optionally called by ucpmap_getRange()/ucptrie_getRange()/umutablecptrie_getRange().
+ * The modified value will be returned by the getRange function.
+ *
+ * Can be used to ignore some of the value bits,
+ * make a filter for one of several values,
+ * return a value index computed from the map value, etc.
+ *
+ * @param context an opaque pointer, as passed into the getRange function
+ * @param value a value from the map
+ * @return the modified value
+ * @stable ICU 63
+ */
+typedef uint32_t U_CALLCONV
+UCPMapValueFilter(const void *context, uint32_t value);
+
+/**
+ * Returns the last code point such that all those from start to there have the same value.
+ * Can be used to efficiently iterate over all same-value ranges in a map.
+ * (This is normally faster than iterating over code points and get()ting each value,
+ * but much slower than a data structure that stores ranges directly.)
+ *
+ * If the UCPMapValueFilter function pointer is not NULL, then
+ * the value to be delivered is passed through that function, and the return value is the end
+ * of the range where all values are modified to the same actual value.
+ * The value is unchanged if that function pointer is NULL.
+ *
+ * Example:
+ * \code
+ * UChar32 start = 0, end;
+ * uint32_t value;
+ * while ((end = ucpmap_getRange(map, start, UCPMAP_RANGE_NORMAL, 0,
+ *                               NULL, NULL, &value)) >= 0) {
+ *     // Work with the range start..end and its value.
+ *     start = end + 1;
+ * }
+ * \endcode
+ *
+ * @param map the map
+ * @param start range start
+ * @param option defines whether surrogates are treated normally,
+ *               or as having the surrogateValue; usually UCPMAP_RANGE_NORMAL
+ * @param surrogateValue value for surrogates; ignored if option==UCPMAP_RANGE_NORMAL
+ * @param filter a pointer to a function that may modify the map data value,
+ *     or NULL if the values from the map are to be used unmodified
+ * @param context an opaque pointer that is passed on to the filter function
+ * @param pValue if not NULL, receives the value that every code point start..end has;
+ *     may have been modified by filter(context, map value)
+ *     if that function pointer is not NULL
+ * @return the range end code point, or -1 if start is not a valid code point
+ * @stable ICU 63
+ */
+U_CAPI UChar32 U_EXPORT2
+ucpmap_getRange(const UCPMap *map, UChar32 start,
+                UCPMapRangeOption option, uint32_t surrogateValue,
+                UCPMapValueFilter *filter, const void *context, uint32_t *pValue);
+
+U_CDECL_END
+
+#endif
diff --git a/src/third_party/icu/source/common/unicode/ucptrie.h b/src/third_party/icu/source/common/unicode/ucptrie.h
new file mode 100644
index 0000000..b95491b
--- /dev/null
+++ b/src/third_party/icu/source/common/unicode/ucptrie.h
@@ -0,0 +1,646 @@
+// © 2017 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+// ucptrie.h (modified from utrie2.h)
+// created: 2017dec29 Markus W. Scherer
+
+#ifndef __UCPTRIE_H__
+#define __UCPTRIE_H__
+
+#include "unicode/utypes.h"
+#include "unicode/ucpmap.h"
+#include "unicode/utf8.h"
+
+#if U_SHOW_CPLUSPLUS_API
+#include "unicode/localpointer.h"
+#endif   // U_SHOW_CPLUSPLUS_API
+
+U_CDECL_BEGIN
+
+/**
+ * \file
+ *
+ * This file defines an immutable Unicode code point trie.
+ *
+ * @see UCPTrie
+ * @see UMutableCPTrie
+ */
+
+#ifndef U_IN_DOXYGEN
+/** @internal */
+typedef union UCPTrieData {
+    /** @internal */
+    const void *ptr0;
+    /** @internal */
+    const uint16_t *ptr16;
+    /** @internal */
+    const uint32_t *ptr32;
+    /** @internal */
+    const uint8_t *ptr8;
+} UCPTrieData;
+#endif
+
+/**
+ * Immutable Unicode code point trie structure.
+ * Fast, reasonably compact, map from Unicode code points (U+0000..U+10FFFF) to integer values.
+ * For details see http://site.icu-project.org/design/struct/utrie
+ *
+ * Do not access UCPTrie fields directly; use public functions and macros.
+ * Functions are easy to use: They support all trie types and value widths.
+ *
+ * When performance is really important, macros provide faster access.
+ * Most macros are specific to either "fast" or "small" tries, see UCPTrieType.
+ * There are "fast" macros for special optimized use cases.
+ *
+ * The macros will return bogus values, or may crash, if used on the wrong type or value width.
+ *
+ * @see UMutableCPTrie
+ * @stable ICU 63
+ */
+struct UCPTrie {
+#ifndef U_IN_DOXYGEN
+    /** @internal */
+    const uint16_t *index;
+    /** @internal */
+    UCPTrieData data;
+
+    /** @internal */
+    int32_t indexLength;
+    /** @internal */
+    int32_t dataLength;
+    /** Start of the last range which ends at U+10FFFF. @internal */
+    UChar32 highStart;
+    /** highStart>>12 @internal */
+    uint16_t shifted12HighStart;
+
+    /** @internal */
+    int8_t type;  // UCPTrieType
+    /** @internal */
+    int8_t valueWidth;  // UCPTrieValueWidth
+
+    /** padding/reserved @internal */
+    uint32_t reserved32;
+    /** padding/reserved @internal */
+    uint16_t reserved16;
+
+    /**
+     * Internal index-3 null block offset.
+     * Set to an impossibly high value (e.g., 0xffff) if there is no dedicated index-3 null block.
+     * @internal
+     */
+    uint16_t index3NullOffset;
+    /**
+     * Internal data null block offset, not shifted.
+     * Set to an impossibly high value (e.g., 0xfffff) if there is no dedicated data null block.
+     * @internal
+     */
+    int32_t dataNullOffset;
+    /** @internal */
+    uint32_t nullValue;
+
+#ifdef UCPTRIE_DEBUG
+    /** @internal */
+    const char *name;
+#endif
+#endif
+};
+#ifndef U_IN_DOXYGEN
+typedef struct UCPTrie UCPTrie;
+#endif
+
+/**
+ * Selectors for the type of a UCPTrie.
+ * Different trade-offs for size vs. speed.
+ *
+ * @see umutablecptrie_buildImmutable
+ * @see ucptrie_openFromBinary
+ * @see ucptrie_getType
+ * @stable ICU 63
+ */
+enum UCPTrieType {
+    /**
+     * For ucptrie_openFromBinary() to accept any type.
+     * ucptrie_getType() will return the actual type.
+     * @stable ICU 63
+     */
+    UCPTRIE_TYPE_ANY = -1,
+    /**
+     * Fast/simple/larger BMP data structure. Use functions and "fast" macros.
+     * @stable ICU 63
+     */
+    UCPTRIE_TYPE_FAST,
+    /**
+     * Small/slower BMP data structure. Use functions and "small" macros.
+     * @stable ICU 63
+     */
+    UCPTRIE_TYPE_SMALL
+};
+#ifndef U_IN_DOXYGEN
+typedef enum UCPTrieType UCPTrieType;
+#endif
+
+/**
+ * Selectors for the number of bits in a UCPTrie data value.
+ *
+ * @see umutablecptrie_buildImmutable
+ * @see ucptrie_openFromBinary
+ * @see ucptrie_getValueWidth
+ * @stable ICU 63
+ */
+enum UCPTrieValueWidth {
+    /**
+     * For ucptrie_openFromBinary() to accept any data value width.
+     * ucptrie_getValueWidth() will return the actual data value width.
+     * @stable ICU 63
+     */
+    UCPTRIE_VALUE_BITS_ANY = -1,
+    /**
+     * The trie stores 16 bits per data value.
+     * It returns them as unsigned values 0..0xffff=65535.
+     * @stable ICU 63
+     */
+    UCPTRIE_VALUE_BITS_16,
+    /**
+     * The trie stores 32 bits per data value.
+     * @stable ICU 63
+     */
+    UCPTRIE_VALUE_BITS_32,
+    /**
+     * The trie stores 8 bits per data value.
+     * It returns them as unsigned values 0..0xff=255.
+     * @stable ICU 63
+     */
+    UCPTRIE_VALUE_BITS_8
+};
+#ifndef U_IN_DOXYGEN
+typedef enum UCPTrieValueWidth UCPTrieValueWidth;
+#endif
+
+/**
+ * Opens a trie from its binary form, stored in 32-bit-aligned memory.
+ * Inverse of ucptrie_toBinary().
+ *
+ * The memory must remain valid and unchanged as long as the trie is used.
+ * You must ucptrie_close() the trie once you are done using it.
+ *
+ * @param type selects the trie type; results in an
+ *             U_INVALID_FORMAT_ERROR if it does not match the binary data;
+ *             use UCPTRIE_TYPE_ANY to accept any type
+ * @param valueWidth selects the number of bits in a data value; results in an
+ *                  U_INVALID_FORMAT_ERROR if it does not match the binary data;
+ *                  use UCPTRIE_VALUE_BITS_ANY to accept any data value width
+ * @param data a pointer to 32-bit-aligned memory containing the binary data of a UCPTrie
+ * @param length the number of bytes available at data;
+ *               can be more than necessary
+ * @param pActualLength receives the actual number of bytes at data taken up by the trie data;
+ *                      can be NULL
+ * @param pErrorCode an in/out ICU UErrorCode
+ * @return the trie
+ *
+ * @see umutablecptrie_open
+ * @see umutablecptrie_buildImmutable
+ * @see ucptrie_toBinary
+ * @stable ICU 63
+ */
+U_CAPI UCPTrie * U_EXPORT2
+ucptrie_openFromBinary(UCPTrieType type, UCPTrieValueWidth valueWidth,
+                       const void *data, int32_t length, int32_t *pActualLength,
+                       UErrorCode *pErrorCode);
+
+/**
+ * Closes a trie and releases associated memory.
+ *
+ * @param trie the trie
+ * @stable ICU 63
+ */
+U_CAPI void U_EXPORT2
+ucptrie_close(UCPTrie *trie);
+
+/**
+ * Returns the trie type.
+ *
+ * @param trie the trie
+ * @return the trie type
+ * @see ucptrie_openFromBinary
+ * @see UCPTRIE_TYPE_ANY
+ * @stable ICU 63
+ */
+U_CAPI UCPTrieType U_EXPORT2
+ucptrie_getType(const UCPTrie *trie);
+
+/**
+ * Returns the number of bits in a trie data value.
+ *
+ * @param trie the trie
+ * @return the number of bits in a trie data value
+ * @see ucptrie_openFromBinary
+ * @see UCPTRIE_VALUE_BITS_ANY
+ * @stable ICU 63
+ */
+U_CAPI UCPTrieValueWidth U_EXPORT2
+ucptrie_getValueWidth(const UCPTrie *trie);
+
+/**
+ * Returns the value for a code point as stored in the trie, with range checking.
+ * Returns the trie error value if c is not in the range 0..U+10FFFF.
+ *
+ * Easier to use than UCPTRIE_FAST_GET() and similar macros but slower.
+ * Easier to use because, unlike the macros, this function works on all UCPTrie
+ * objects, for all types and value widths.
+ *
+ * @param trie the trie
+ * @param c the code point
+ * @return the trie value,
+ *         or the trie error value if the code point is not in the range 0..U+10FFFF
+ * @stable ICU 63
+ */
+U_CAPI uint32_t U_EXPORT2
+ucptrie_get(const UCPTrie *trie, UChar32 c);
+
+/**
+ * Returns the last code point such that all those from start to there have the same value.
+ * Can be used to efficiently iterate over all same-value ranges in a trie.
+ * (This is normally faster than iterating over code points and get()ting each value,
+ * but much slower than a data structure that stores ranges directly.)
+ *
+ * If the UCPMapValueFilter function pointer is not NULL, then
+ * the value to be delivered is passed through that function, and the return value is the end
+ * of the range where all values are modified to the same actual value.
+ * The value is unchanged if that function pointer is NULL.
+ *
+ * Example:
+ * \code
+ * UChar32 start = 0, end;
+ * uint32_t value;
+ * while ((end = ucptrie_getRange(trie, start, UCPMAP_RANGE_NORMAL, 0,
+ *                                NULL, NULL, &value)) >= 0) {
+ *     // Work with the range start..end and its value.
+ *     start = end + 1;
+ * }
+ * \endcode
+ *
+ * @param trie the trie
+ * @param start range start
+ * @param option defines whether surrogates are treated normally,
+ *               or as having the surrogateValue; usually UCPMAP_RANGE_NORMAL
+ * @param surrogateValue value for surrogates; ignored if option==UCPMAP_RANGE_NORMAL
+ * @param filter a pointer to a function that may modify the trie data value,
+ *     or NULL if the values from the trie are to be used unmodified
+ * @param context an opaque pointer that is passed on to the filter function
+ * @param pValue if not NULL, receives the value that every code point start..end has;
+ *     may have been modified by filter(context, trie value)
+ *     if that function pointer is not NULL
+ * @return the range end code point, or -1 if start is not a valid code point
+ * @stable ICU 63
+ */
+U_CAPI UChar32 U_EXPORT2
+ucptrie_getRange(const UCPTrie *trie, UChar32 start,
+                 UCPMapRangeOption option, uint32_t surrogateValue,
+                 UCPMapValueFilter *filter, const void *context, uint32_t *pValue);
+
+/**
+ * Writes a memory-mappable form of the trie into 32-bit aligned memory.
+ * Inverse of ucptrie_openFromBinary().
+ *
+ * @param trie the trie
+ * @param data a pointer to 32-bit-aligned memory to be filled with the trie data;
+ *             can be NULL if capacity==0
+ * @param capacity the number of bytes available at data, or 0 for pure preflighting
+ * @param pErrorCode an in/out ICU UErrorCode;
+ *                   U_BUFFER_OVERFLOW_ERROR if the capacity is too small
+ * @return the number of bytes written or (if buffer overflow) needed for the trie
+ *
+ * @see ucptrie_openFromBinary()
+ * @stable ICU 63
+ */
+U_CAPI int32_t U_EXPORT2
+ucptrie_toBinary(const UCPTrie *trie, void *data, int32_t capacity, UErrorCode *pErrorCode);
+
+/**
+ * Macro parameter value for a trie with 16-bit data values.
+ * Use the name of this macro as a "dataAccess" parameter in other macros.
+ * Do not use this macro in any other way.
+ *
+ * @see UCPTRIE_VALUE_BITS_16
+ * @stable ICU 63
+ */
+#define UCPTRIE_16(trie, i) ((trie)->data.ptr16[i])
+
+/**
+ * Macro parameter value for a trie with 32-bit data values.
+ * Use the name of this macro as a "dataAccess" parameter in other macros.
+ * Do not use this macro in any other way.
+ *
+ * @see UCPTRIE_VALUE_BITS_32
+ * @stable ICU 63
+ */
+#define UCPTRIE_32(trie, i) ((trie)->data.ptr32[i])
+
+/**
+ * Macro parameter value for a trie with 8-bit data values.
+ * Use the name of this macro as a "dataAccess" parameter in other macros.
+ * Do not use this macro in any other way.
+ *
+ * @see UCPTRIE_VALUE_BITS_8
+ * @stable ICU 63
+ */
+#define UCPTRIE_8(trie, i) ((trie)->data.ptr8[i])
+
+/**
+ * Returns a trie value for a code point, with range checking.
+ * Returns the trie error value if c is not in the range 0..U+10FFFF.
+ *
+ * @param trie (const UCPTrie *, in) the trie; must have type UCPTRIE_TYPE_FAST
+ * @param dataAccess UCPTRIE_16, UCPTRIE_32, or UCPTRIE_8 according to the trie’s value width
+ * @param c (UChar32, in) the input code point
+ * @return The code point's trie value.
+ * @stable ICU 63
+ */
+#define UCPTRIE_FAST_GET(trie, dataAccess, c) dataAccess(trie, _UCPTRIE_CP_INDEX(trie, 0xffff, c))
+
+/**
+ * Returns a 16-bit trie value for a code point, with range checking.
+ * Returns the trie error value if c is not in the range U+0000..U+10FFFF.
+ *
+ * @param trie (const UCPTrie *, in) the trie; must have type UCPTRIE_TYPE_SMALL
+ * @param dataAccess UCPTRIE_16, UCPTRIE_32, or UCPTRIE_8 according to the trie’s value width
+ * @param c (UChar32, in) the input code point
+ * @return The code point's trie value.
+ * @stable ICU 63
+ */
+#define UCPTRIE_SMALL_GET(trie, dataAccess, c) \
+    dataAccess(trie, _UCPTRIE_CP_INDEX(trie, UCPTRIE_SMALL_MAX, c))
+
+/**
+ * UTF-16: Reads the next code point (UChar32 c, out), post-increments src,
+ * and gets a value from the trie.
+ * Sets the trie error value if c is an unpaired surrogate.
+ *
+ * @param trie (const UCPTrie *, in) the trie; must have type UCPTRIE_TYPE_FAST
+ * @param dataAccess UCPTRIE_16, UCPTRIE_32, or UCPTRIE_8 according to the trie’s value width
+ * @param src (const UChar *, in/out) the source text pointer
+ * @param limit (const UChar *, in) the limit pointer for the text, or NULL if NUL-terminated
+ * @param c (UChar32, out) variable for the code point
+ * @param result (out) variable for the trie lookup result
+ * @stable ICU 63
+ */
+#define UCPTRIE_FAST_U16_NEXT(trie, dataAccess, src, limit, c, result) UPRV_BLOCK_MACRO_BEGIN { \
+    (c) = *(src)++; \
+    int32_t __index; \
+    if (!U16_IS_SURROGATE(c)) { \
+        __index = _UCPTRIE_FAST_INDEX(trie, c); \
+    } else { \
+        uint16_t __c2; \
+        if (U16_IS_SURROGATE_LEAD(c) && (src) != (limit) && U16_IS_TRAIL(__c2 = *(src))) { \
+            ++(src); \
+            (c) = U16_GET_SUPPLEMENTARY((c), __c2); \
+            __index = _UCPTRIE_SMALL_INDEX(trie, c); \
+        } else { \
+            __index = (trie)->dataLength - UCPTRIE_ERROR_VALUE_NEG_DATA_OFFSET; \
+        } \
+    } \
+    (result) = dataAccess(trie, __index); \
+} UPRV_BLOCK_MACRO_END
+
+/**
+ * UTF-16: Reads the previous code point (UChar32 c, out), pre-decrements src,
+ * and gets a value from the trie.
+ * Sets the trie error value if c is an unpaired surrogate.
+ *
+ * @param trie (const UCPTrie *, in) the trie; must have type UCPTRIE_TYPE_FAST
+ * @param dataAccess UCPTRIE_16, UCPTRIE_32, or UCPTRIE_8 according to the trie’s value width
+ * @param start (const UChar *, in) the start pointer for the text
+ * @param src (const UChar *, in/out) the source text pointer
+ * @param c (UChar32, out) variable for the code point
+ * @param result (out) variable for the trie lookup result
+ * @stable ICU 63
+ */
+#define UCPTRIE_FAST_U16_PREV(trie, dataAccess, start, src, c, result) UPRV_BLOCK_MACRO_BEGIN { \
+    (c) = *--(src); \
+    int32_t __index; \
+    if (!U16_IS_SURROGATE(c)) { \
+        __index = _UCPTRIE_FAST_INDEX(trie, c); \
+    } else { \
+        uint16_t __c2; \
+        if (U16_IS_SURROGATE_TRAIL(c) && (src) != (start) && U16_IS_LEAD(__c2 = *((src) - 1))) { \
+            --(src); \
+            (c) = U16_GET_SUPPLEMENTARY(__c2, (c)); \
+            __index = _UCPTRIE_SMALL_INDEX(trie, c); \
+        } else { \
+            __index = (trie)->dataLength - UCPTRIE_ERROR_VALUE_NEG_DATA_OFFSET; \
+        } \
+    } \
+    (result) = dataAccess(trie, __index); \
+} UPRV_BLOCK_MACRO_END
+
+/**
+ * UTF-8: Post-increments src and gets a value from the trie.
+ * Sets the trie error value for an ill-formed byte sequence.
+ *
+ * Unlike UCPTRIE_FAST_U16_NEXT() this UTF-8 macro does not provide the code point
+ * because it would be more work to do so and is often not needed.
+ * If the trie value differs from the error value, then the byte sequence is well-formed,
+ * and the code point can be assembled without revalidation.
+ *
+ * @param trie (const UCPTrie *, in) the trie; must have type UCPTRIE_TYPE_FAST
+ * @param dataAccess UCPTRIE_16, UCPTRIE_32, or UCPTRIE_8 according to the trie’s value width
+ * @param src (const char *, in/out) the source text pointer
+ * @param limit (const char *, in) the limit pointer for the text (must not be NULL)
+ * @param result (out) variable for the trie lookup result
+ * @stable ICU 63
+ */
+#define UCPTRIE_FAST_U8_NEXT(trie, dataAccess, src, limit, result) UPRV_BLOCK_MACRO_BEGIN { \
+    int32_t __lead = (uint8_t)*(src)++; \
+    if (!U8_IS_SINGLE(__lead)) { \
+        uint8_t __t1, __t2, __t3; \
+        if ((src) != (limit) && \
+            (__lead >= 0xe0 ? \
+                __lead < 0xf0 ?  /* U+0800..U+FFFF except surrogates */ \
+                    U8_LEAD3_T1_BITS[__lead &= 0xf] & (1 << ((__t1 = *(src)) >> 5)) && \
+                    ++(src) != (limit) && (__t2 = *(src) - 0x80) <= 0x3f && \
+                    (__lead = ((int32_t)(trie)->index[(__lead << 6) + (__t1 & 0x3f)]) + __t2, 1) \
+                :  /* U+10000..U+10FFFF */ \
+                    (__lead -= 0xf0) <= 4 && \
+                    U8_LEAD4_T1_BITS[(__t1 = *(src)) >> 4] & (1 << __lead) && \
+                    (__lead = (__lead << 6) | (__t1 & 0x3f), ++(src) != (limit)) && \
+                    (__t2 = *(src) - 0x80) <= 0x3f && \
+                    ++(src) != (limit) && (__t3 = *(src) - 0x80) <= 0x3f && \
+                    (__lead = __lead >= (trie)->shifted12HighStart ? \
+                        (trie)->dataLength - UCPTRIE_HIGH_VALUE_NEG_DATA_OFFSET : \
+                        ucptrie_internalSmallU8Index((trie), __lead, __t2, __t3), 1) \
+            :  /* U+0080..U+07FF */ \
+                __lead >= 0xc2 && (__t1 = *(src) - 0x80) <= 0x3f && \
+                (__lead = (int32_t)(trie)->index[__lead & 0x1f] + __t1, 1))) { \
+            ++(src); \
+        } else { \
+            __lead = (trie)->dataLength - UCPTRIE_ERROR_VALUE_NEG_DATA_OFFSET;  /* ill-formed*/ \
+        } \
+    } \
+    (result) = dataAccess(trie, __lead); \
+} UPRV_BLOCK_MACRO_END
+
+/**
+ * UTF-8: Pre-decrements src and gets a value from the trie.
+ * Sets the trie error value for an ill-formed byte sequence.
+ *
+ * Unlike UCPTRIE_FAST_U16_PREV() this UTF-8 macro does not provide the code point
+ * because it would be more work to do so and is often not needed.
+ * If the trie value differs from the error value, then the byte sequence is well-formed,
+ * and the code point can be assembled without revalidation.
+ *
+ * @param trie (const UCPTrie *, in) the trie; must have type UCPTRIE_TYPE_FAST
+ * @param dataAccess UCPTRIE_16, UCPTRIE_32, or UCPTRIE_8 according to the trie’s value width
+ * @param start (const char *, in) the start pointer for the text
+ * @param src (const char *, in/out) the source text pointer
+ * @param result (out) variable for the trie lookup result
+ * @stable ICU 63
+ */
+#define UCPTRIE_FAST_U8_PREV(trie, dataAccess, start, src, result) UPRV_BLOCK_MACRO_BEGIN { \
+    int32_t __index = (uint8_t)*--(src); \
+    if (!U8_IS_SINGLE(__index)) { \
+        __index = ucptrie_internalU8PrevIndex((trie), __index, (const uint8_t *)(start), \
+                                              (const uint8_t *)(src)); \
+        (src) -= __index & 7; \
+        __index >>= 3; \
+    } \
+    (result) = dataAccess(trie, __index); \
+} UPRV_BLOCK_MACRO_END
+
+/**
+ * Returns a trie value for an ASCII code point, without range checking.
+ *
+ * @param trie (const UCPTrie *, in) the trie (of either fast or small type)
+ * @param dataAccess UCPTRIE_16, UCPTRIE_32, or UCPTRIE_8 according to the trie’s value width
+ * @param c (UChar32, in) the input code point; must be U+0000..U+007F
+ * @return The ASCII code point's trie value.
+ * @stable ICU 63
+ */
+#define UCPTRIE_ASCII_GET(trie, dataAccess, c) dataAccess(trie, c)
+
+/**
+ * Returns a trie value for a BMP code point (U+0000..U+FFFF), without range checking.
+ * Can be used to look up a value for a UTF-16 code unit if other parts of
+ * the string processing check for surrogates.
+ *
+ * @param trie (const UCPTrie *, in) the trie; must have type UCPTRIE_TYPE_FAST
+ * @param dataAccess UCPTRIE_16, UCPTRIE_32, or UCPTRIE_8 according to the trie’s value width
+ * @param c (UChar32, in) the input code point, must be U+0000..U+FFFF
+ * @return The BMP code point's trie value.
+ * @stable ICU 63
+ */
+#define UCPTRIE_FAST_BMP_GET(trie, dataAccess, c) dataAccess(trie, _UCPTRIE_FAST_INDEX(trie, c))
+
+/**
+ * Returns a trie value for a supplementary code point (U+10000..U+10FFFF),
+ * without range checking.
+ *
+ * @param trie (const UCPTrie *, in) the trie; must have type UCPTRIE_TYPE_FAST
+ * @param dataAccess UCPTRIE_16, UCPTRIE_32, or UCPTRIE_8 according to the trie’s value width
+ * @param c (UChar32, in) the input code point, must be U+10000..U+10FFFF
+ * @return The supplementary code point's trie value.
+ * @stable ICU 63
+ */
+#define UCPTRIE_FAST_SUPP_GET(trie, dataAccess, c) dataAccess(trie, _UCPTRIE_SMALL_INDEX(trie, c))
+
+/* Internal definitions ----------------------------------------------------- */
+
+#ifndef U_IN_DOXYGEN
+
+/**
+ * Internal implementation constants.
+ * These are needed for the API macros, but users should not use these directly.
+ * @internal
+ */
+enum {
+    /** @internal */
+    UCPTRIE_FAST_SHIFT = 6,
+
+    /** Number of entries in a data block for code points below the fast limit. 64=0x40 @internal */
+    UCPTRIE_FAST_DATA_BLOCK_LENGTH = 1 << UCPTRIE_FAST_SHIFT,
+
+    /** Mask for getting the lower bits for the in-fast-data-block offset. @internal */
+    UCPTRIE_FAST_DATA_MASK = UCPTRIE_FAST_DATA_BLOCK_LENGTH - 1,
+
+    /** @internal */
+    UCPTRIE_SMALL_MAX = 0xfff,
+
+    /**
+     * Offset from dataLength (to be subtracted) for fetching the
+     * value returned for out-of-range code points and ill-formed UTF-8/16.
+     * @internal
+     */
+    UCPTRIE_ERROR_VALUE_NEG_DATA_OFFSET = 1,
+    /**
+     * Offset from dataLength (to be subtracted) for fetching the
+     * value returned for code points highStart..U+10FFFF.
+     * @internal
+     */
+    UCPTRIE_HIGH_VALUE_NEG_DATA_OFFSET = 2
+};
+
+/* Internal functions and macros -------------------------------------------- */
+// Do not conditionalize with #ifndef U_HIDE_INTERNAL_API, needed for public API
+
+/** @internal */
+U_CAPI int32_t U_EXPORT2
+ucptrie_internalSmallIndex(const UCPTrie *trie, UChar32 c);
+
+/** @internal */
+U_CAPI int32_t U_EXPORT2
+ucptrie_internalSmallU8Index(const UCPTrie *trie, int32_t lt1, uint8_t t2, uint8_t t3);
+
+/**
+ * Internal function for part of the UCPTRIE_FAST_U8_PREVxx() macro implementations.
+ * Do not call directly.
+ * @internal
+ */
+U_CAPI int32_t U_EXPORT2
+ucptrie_internalU8PrevIndex(const UCPTrie *trie, UChar32 c,
+                            const uint8_t *start, const uint8_t *src);
+
+/** Internal trie getter for a code point below the fast limit. Returns the data index. @internal */
+#define _UCPTRIE_FAST_INDEX(trie, c) \
+    ((int32_t)(trie)->index[(c) >> UCPTRIE_FAST_SHIFT] + ((c) & UCPTRIE_FAST_DATA_MASK))
+
+/** Internal trie getter for a code point at or above the fast limit. Returns the data index. @internal */
+#define _UCPTRIE_SMALL_INDEX(trie, c) \
+    ((c) >= (trie)->highStart ? \
+        (trie)->dataLength - UCPTRIE_HIGH_VALUE_NEG_DATA_OFFSET : \
+        ucptrie_internalSmallIndex(trie, c))
+
+/**
+ * Internal trie getter for a code point, with checking that c is in U+0000..10FFFF.
+ * Returns the data index.
+ * @internal
+ */
+#define _UCPTRIE_CP_INDEX(trie, fastMax, c) \
+    ((uint32_t)(c) <= (uint32_t)(fastMax) ? \
+        _UCPTRIE_FAST_INDEX(trie, c) : \
+        (uint32_t)(c) <= 0x10ffff ? \
+            _UCPTRIE_SMALL_INDEX(trie, c) : \
+            (trie)->dataLength - UCPTRIE_ERROR_VALUE_NEG_DATA_OFFSET)
+
+U_CDECL_END
+
+#endif  // U_IN_DOXYGEN
+
+#if U_SHOW_CPLUSPLUS_API
+
+U_NAMESPACE_BEGIN
+
+/**
+ * \class LocalUCPTriePointer
+ * "Smart pointer" class, closes a UCPTrie via ucptrie_close().
+ * For most methods see the LocalPointerBase base class.
+ *
+ * @see LocalPointerBase
+ * @see LocalPointer
+ * @stable ICU 63
+ */
+U_DEFINE_LOCAL_OPEN_POINTER(LocalUCPTriePointer, UCPTrie, ucptrie_close);
+
+U_NAMESPACE_END
+
+#endif  // U_SHOW_CPLUSPLUS_API
+
+#endif
diff --git a/src/third_party/icu/source/common/unicode/ucurr.h b/src/third_party/icu/source/common/unicode/ucurr.h
new file mode 100644
index 0000000..35c2a39
--- /dev/null
+++ b/src/third_party/icu/source/common/unicode/ucurr.h
@@ -0,0 +1,468 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+/*
+**********************************************************************
+* Copyright (c) 2002-2016, International Business Machines
+* Corporation and others.  All Rights Reserved.
+**********************************************************************
+*/
+#ifndef _UCURR_H_
+#define _UCURR_H_
+
+#include "unicode/utypes.h"
+#include "unicode/uenum.h"
+
+/**
+ * \file 
+ * \brief C API: Encapsulates information about a currency.
+ *
+ * The ucurr API encapsulates information about a currency, as defined by
+ * ISO 4217.  A currency is represented by a 3-character string
+ * containing its ISO 4217 code.  This API can return various data
+ * necessary the proper display of a currency:
+ *
+ * <ul><li>A display symbol, for a specific locale
+ * <li>The number of fraction digits to display
+ * <li>A rounding increment
+ * </ul>
+ *
+ * The <tt>DecimalFormat</tt> class uses these data to display
+ * currencies.
+ * @author Alan Liu
+ * @since ICU 2.2
+ */
+
+#if !UCONFIG_NO_FORMATTING
+
+/**
+ * Currency Usage used for Decimal Format
+ * @stable ICU 54
+ */
+enum UCurrencyUsage {
+    /**
+     * a setting to specify currency usage which determines currency digit
+     * and rounding for standard usage, for example: "50.00 NT$"
+     * used as DEFAULT value
+     * @stable ICU 54
+     */
+    UCURR_USAGE_STANDARD=0,
+    /**
+     * a setting to specify currency usage which determines currency digit
+     * and rounding for cash usage, for example: "50 NT$"
+     * @stable ICU 54
+     */
+    UCURR_USAGE_CASH=1,
+#ifndef U_HIDE_DEPRECATED_API
+    /**
+     * One higher than the last enum UCurrencyUsage constant.
+     * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
+     */
+    UCURR_USAGE_COUNT=2
+#endif  // U_HIDE_DEPRECATED_API
+};
+/** Currency Usage used for Decimal Format */
+typedef enum UCurrencyUsage UCurrencyUsage; 
+
+/**
+ * Finds a currency code for the given locale.
+ * @param locale the locale for which to retrieve a currency code. 
+ *               Currency can be specified by the "currency" keyword
+ *               in which case it overrides the default currency code
+ * @param buff   fill in buffer. Can be NULL for preflighting.
+ * @param buffCapacity capacity of the fill in buffer. Can be 0 for
+ *               preflighting. If it is non-zero, the buff parameter
+ *               must not be NULL.
+ * @param ec error code
+ * @return length of the currency string. It should always be 3. If 0,
+ *                currency couldn't be found or the input values are 
+ *                invalid. 
+ * @stable ICU 2.8
+ */
+U_CAPI int32_t U_EXPORT2
+ucurr_forLocale(const char* locale,
+                UChar* buff,
+                int32_t buffCapacity,
+                UErrorCode* ec);
+
+/**
+ * Selector constants for ucurr_getName().
+ *
+ * @see ucurr_getName
+ * @stable ICU 2.6
+ */
+typedef enum UCurrNameStyle {
+    /**
+     * Selector for ucurr_getName indicating a symbolic name for a
+     * currency, such as "$" for USD.
+     * @stable ICU 2.6
+     */
+    UCURR_SYMBOL_NAME,
+
+    /**
+     * Selector for ucurr_getName indicating the long name for a
+     * currency, such as "US Dollar" for USD.
+     * @stable ICU 2.6
+     */
+    UCURR_LONG_NAME,
+
+    /**
+     * Selector for getName() indicating the narrow currency symbol.
+     * The narrow currency symbol is similar to the regular currency
+     * symbol, but it always takes the shortest form: for example,
+     * "$" instead of "US$" for USD in en-CA.
+     *
+     * @stable ICU 61
+     */
+    UCURR_NARROW_SYMBOL_NAME,
+
+#ifndef U_HIDE_DRAFT_API
+    /**
+     * Selector for getName() indicating the formal currency symbol.
+     * The formal currency symbol is similar to the regular currency
+     * symbol, but it always takes the form used in formal settings
+     * such as banking; for example, "NT$" instead of "$" for TWD in zh-TW.
+     *
+     * @draft ICU 68
+     */
+    UCURR_FORMAL_SYMBOL_NAME,
+
+    /**
+     * Selector for getName() indicating the variant currency symbol.
+     * The variant symbol for a currency is an alternative symbol
+     * that is not necessarily as widely used as the regular symbol.
+     *
+     * @draft ICU 68
+     */
+    UCURR_VARIANT_SYMBOL_NAME
+#endif  // U_HIDE_DRAFT_API
+    
+} UCurrNameStyle;
+
+#if !UCONFIG_NO_SERVICE
+/**
+ * @stable ICU 2.6
+ */
+typedef const void* UCurrRegistryKey;
+
+/**
+ * Register an (existing) ISO 4217 currency code for the given locale.
+ * Only the country code and the two variants EURO and PRE_EURO are
+ * recognized.
+ * @param isoCode the three-letter ISO 4217 currency code
+ * @param locale  the locale for which to register this currency code
+ * @param status the in/out status code
+ * @return a registry key that can be used to unregister this currency code, or NULL
+ * if there was an error.
+ * @stable ICU 2.6
+ */
+U_CAPI UCurrRegistryKey U_EXPORT2
+ucurr_register(const UChar* isoCode, 
+                   const char* locale,  
+                   UErrorCode* status);
+/**
+ * Unregister the previously-registered currency definitions using the
+ * URegistryKey returned from ucurr_register.  Key becomes invalid after
+ * a successful call and should not be used again.  Any currency 
+ * that might have been hidden by the original ucurr_register call is 
+ * restored.
+ * @param key the registry key returned by a previous call to ucurr_register
+ * @param status the in/out status code, no special meanings are assigned
+ * @return true if the currency for this key was successfully unregistered
+ * @stable ICU 2.6
+ */
+U_CAPI UBool U_EXPORT2
+ucurr_unregister(UCurrRegistryKey key, UErrorCode* status);
+#endif /* UCONFIG_NO_SERVICE */
+
+/**
+ * Returns the display name for the given currency in the
+ * given locale.  For example, the display name for the USD
+ * currency object in the en_US locale is "$".
+ * @param currency null-terminated 3-letter ISO 4217 code
+ * @param locale locale in which to display currency
+ * @param nameStyle selector for which kind of name to return
+ * @param isChoiceFormat always set to false, or can be NULL;
+ *     display names are static strings;
+ *     since ICU 4.4, ChoiceFormat patterns are no longer supported
+ * @param len fill-in parameter to receive length of result
+ * @param ec error code
+ * @return pointer to display string of 'len' UChars.  If the resource
+ * data contains no entry for 'currency', then 'currency' itself is
+ * returned.
+ * @stable ICU 2.6
+ */
+U_CAPI const UChar* U_EXPORT2
+ucurr_getName(const UChar* currency,
+              const char* locale,
+              UCurrNameStyle nameStyle,
+              UBool* isChoiceFormat,
+              int32_t* len,
+              UErrorCode* ec);
+
+/**
+ * Returns the plural name for the given currency in the
+ * given locale.  For example, the plural name for the USD
+ * currency object in the en_US locale is "US dollar" or "US dollars".
+ * @param currency null-terminated 3-letter ISO 4217 code
+ * @param locale locale in which to display currency
+ * @param isChoiceFormat always set to false, or can be NULL;
+ *     display names are static strings;
+ *     since ICU 4.4, ChoiceFormat patterns are no longer supported
+ * @param pluralCount plural count
+ * @param len fill-in parameter to receive length of result
+ * @param ec error code
+ * @return pointer to display string of 'len' UChars.  If the resource
+ * data contains no entry for 'currency', then 'currency' itself is
+ * returned.
+ * @stable ICU 4.2
+ */
+U_CAPI const UChar* U_EXPORT2
+ucurr_getPluralName(const UChar* currency,
+                    const char* locale,
+                    UBool* isChoiceFormat,
+                    const char* pluralCount,
+                    int32_t* len,
+                    UErrorCode* ec);
+
+/**
+ * Returns the number of the number of fraction digits that should
+ * be displayed for the given currency.
+ * This is equivalent to ucurr_getDefaultFractionDigitsForUsage(currency,UCURR_USAGE_STANDARD,ec);
+ *
+ * Important: The number of fraction digits for a given currency is NOT
+ * guaranteed to be constant across versions of ICU or CLDR. For example,
+ * do NOT use this value as a mechanism for deciding the magnitude used
+ * to store currency values in a database. You should use this value for
+ * display purposes only.
+ *
+ * @param currency null-terminated 3-letter ISO 4217 code
+ * @param ec input-output error code
+ * @return a non-negative number of fraction digits to be
+ * displayed, or 0 if there is an error
+ * @stable ICU 3.0
+ */
+U_CAPI int32_t U_EXPORT2
+ucurr_getDefaultFractionDigits(const UChar* currency,
+                               UErrorCode* ec);
+
+/**
+ * Returns the number of the number of fraction digits that should
+ * be displayed for the given currency with usage.
+ *
+ * Important: The number of fraction digits for a given currency is NOT
+ * guaranteed to be constant across versions of ICU or CLDR. For example,
+ * do NOT use this value as a mechanism for deciding the magnitude used
+ * to store currency values in a database. You should use this value for
+ * display purposes only.
+ *
+ * @param currency null-terminated 3-letter ISO 4217 code
+ * @param usage enum usage for the currency
+ * @param ec input-output error code
+ * @return a non-negative number of fraction digits to be
+ * displayed, or 0 if there is an error
+ * @stable ICU 54
+ */
+U_CAPI int32_t U_EXPORT2
+ucurr_getDefaultFractionDigitsForUsage(const UChar* currency, 
+                                       const UCurrencyUsage usage,
+                                       UErrorCode* ec);
+
+/**
+ * Returns the rounding increment for the given currency, or 0.0 if no
+ * rounding is done by the currency.
+ * This is equivalent to ucurr_getRoundingIncrementForUsage(currency,UCURR_USAGE_STANDARD,ec);
+ * @param currency null-terminated 3-letter ISO 4217 code
+ * @param ec input-output error code
+ * @return the non-negative rounding increment, or 0.0 if none,
+ * or 0.0 if there is an error
+ * @stable ICU 3.0
+ */
+U_CAPI double U_EXPORT2
+ucurr_getRoundingIncrement(const UChar* currency,
+                           UErrorCode* ec);
+
+/**
+ * Returns the rounding increment for the given currency, or 0.0 if no
+ * rounding is done by the currency given usage.
+ * @param currency null-terminated 3-letter ISO 4217 code
+ * @param usage enum usage for the currency
+ * @param ec input-output error code
+ * @return the non-negative rounding increment, or 0.0 if none,
+ * or 0.0 if there is an error
+ * @stable ICU 54
+ */
+U_CAPI double U_EXPORT2
+ucurr_getRoundingIncrementForUsage(const UChar* currency,
+                                   const UCurrencyUsage usage,
+                                   UErrorCode* ec);
+
+/**
+ * Selector constants for ucurr_openCurrencies().
+ *
+ * @see ucurr_openCurrencies
+ * @stable ICU 3.2
+ */
+typedef enum UCurrCurrencyType {
+    /**
+     * Select all ISO-4217 currency codes.
+     * @stable ICU 3.2
+     */
+    UCURR_ALL = INT32_MAX,
+    /**
+     * Select only ISO-4217 commonly used currency codes.
+     * These currencies can be found in common use, and they usually have
+     * bank notes or coins associated with the currency code.
+     * This does not include fund codes, precious metals and other
+     * various ISO-4217 codes limited to special financial products.
+     * @stable ICU 3.2
+     */
+    UCURR_COMMON = 1,
+    /**
+     * Select ISO-4217 uncommon currency codes.
+     * These codes respresent fund codes, precious metals and other
+     * various ISO-4217 codes limited to special financial products.
+     * A fund code is a monetary resource associated with a currency.
+     * @stable ICU 3.2
+     */
+    UCURR_UNCOMMON = 2,
+    /**
+     * Select only deprecated ISO-4217 codes.
+     * These codes are no longer in general public use.
+     * @stable ICU 3.2
+     */
+    UCURR_DEPRECATED = 4,
+    /**
+     * Select only non-deprecated ISO-4217 codes.
+     * These codes are in general public use.
+     * @stable ICU 3.2
+     */
+    UCURR_NON_DEPRECATED = 8
+} UCurrCurrencyType;
+
+/**
+ * Provides a UEnumeration object for listing ISO-4217 codes.
+ * @param currType You can use one of several UCurrCurrencyType values for this
+ *      variable. You can also | (or) them together to get a specific list of
+ *      currencies. Most people will want to use the (UCURR_COMMON|UCURR_NON_DEPRECATED) value to
+ *      get a list of current currencies.
+ * @param pErrorCode Error code
+ * @stable ICU 3.2
+ */
+U_CAPI UEnumeration * U_EXPORT2
+ucurr_openISOCurrencies(uint32_t currType, UErrorCode *pErrorCode);
+
+/**
+  * Queries if the given ISO 4217 3-letter code is available on the specified date range. 
+  * 
+  * Note: For checking availability of a currency on a specific date, specify the date on both 'from' and 'to' 
+  * 
+  * When 'from' is U_DATE_MIN and 'to' is U_DATE_MAX, this method checks if the specified currency is available any time. 
+  * If 'from' and 'to' are same UDate value, this method checks if the specified currency is available on that date.
+  * 
+  * @param isoCode 
+  *            The ISO 4217 3-letter code. 
+  * 
+  * @param from 
+  *            The lower bound of the date range, inclusive. When 'from' is U_DATE_MIN, check the availability 
+  *            of the currency any date before 'to' 
+  * 
+  * @param to 
+  *            The upper bound of the date range, inclusive. When 'to' is U_DATE_MAX, check the availability of 
+  *            the currency any date after 'from' 
+  * 
+  * @param errorCode 
+  *            ICU error code 
+   * 
+  * @return true if the given ISO 4217 3-letter code is supported on the specified date range. 
+  * 
+  * @stable ICU 4.8 
+  */ 
+U_CAPI UBool U_EXPORT2
+ucurr_isAvailable(const UChar* isoCode, 
+             UDate from, 
+             UDate to, 
+             UErrorCode* errorCode);
+
+/** 
+ * Finds the number of valid currency codes for the
+ * given locale and date.
+ * @param locale the locale for which to retrieve the
+ *               currency count.
+ * @param date   the date for which to retrieve the
+ *               currency count for the given locale.
+ * @param ec     error code
+ * @return       the number of currency codes for the
+ *               given locale and date.  If 0, currency
+ *               codes couldn't be found for the input
+ *               values are invalid.
+ * @stable ICU 4.0
+ */
+U_CAPI int32_t U_EXPORT2
+ucurr_countCurrencies(const char* locale, 
+                 UDate date, 
+                 UErrorCode* ec); 
+
+/** 
+ * Finds a currency code for the given locale and date 
+ * @param locale the locale for which to retrieve a currency code.  
+ *               Currency can be specified by the "currency" keyword 
+ *               in which case it overrides the default currency code 
+ * @param date   the date for which to retrieve a currency code for 
+ *               the given locale. 
+ * @param index  the index within the available list of currency codes
+ *               for the given locale on the given date.
+ * @param buff   fill in buffer. Can be NULL for preflighting. 
+ * @param buffCapacity capacity of the fill in buffer. Can be 0 for 
+ *               preflighting. If it is non-zero, the buff parameter 
+ *               must not be NULL. 
+ * @param ec     error code 
+ * @return       length of the currency string. It should always be 3. 
+ *               If 0, currency couldn't be found or the input values are  
+ *               invalid.  
+ * @stable ICU 4.0 
+ */ 
+U_CAPI int32_t U_EXPORT2 
+ucurr_forLocaleAndDate(const char* locale, 
+                UDate date, 
+                int32_t index,
+                UChar* buff, 
+                int32_t buffCapacity, 
+                UErrorCode* ec); 
+
+/**
+ * Given a key and a locale, returns an array of string values in a preferred
+ * order that would make a difference. These are all and only those values where
+ * the open (creation) of the service with the locale formed from the input locale
+ * plus input keyword and that value has different behavior than creation with the
+ * input locale alone.
+ * @param key           one of the keys supported by this service.  For now, only
+ *                      "currency" is supported.
+ * @param locale        the locale
+ * @param commonlyUsed  if set to true it will return only commonly used values
+ *                      with the given locale in preferred order.  Otherwise,
+ *                      it will return all the available values for the locale.
+ * @param status error status
+ * @return a string enumeration over keyword values for the given key and the locale.
+ * @stable ICU 4.2
+ */
+U_CAPI UEnumeration* U_EXPORT2
+ucurr_getKeywordValuesForLocale(const char* key,
+                                const char* locale,
+                                UBool commonlyUsed,
+                                UErrorCode* status);
+
+/**
+ * Returns the ISO 4217 numeric code for the currency.
+ * <p>Note: If the ISO 4217 numeric code is not assigned for the currency or
+ * the currency is unknown, this function returns 0.
+ *
+ * @param currency null-terminated 3-letter ISO 4217 code
+ * @return The ISO 4217 numeric code of the currency
+ * @stable ICU 49
+ */
+U_CAPI int32_t U_EXPORT2
+ucurr_getNumericCode(const UChar* currency);
+
+#endif /* #if !UCONFIG_NO_FORMATTING */
+
+#endif
diff --git a/src/third_party/icu/source/common/unicode/udata.h b/src/third_party/icu/source/common/unicode/udata.h
index 29e4663..6caa849 100644
--- a/src/third_party/icu/source/common/unicode/udata.h
+++ b/src/third_party/icu/source/common/unicode/udata.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 ******************************************************************************
 *   file name:  udata.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -18,7 +20,10 @@
 #define __UDATA_H__
 
 #include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
 #include "unicode/localpointer.h"
+#endif   // U_SHOW_CPLUSPLUS_API
 
 U_CDECL_BEGIN
 
@@ -164,8 +169,8 @@
  * @param pInfo A pointer to the <code>UDataInfo</code> structure
  *              of data that has been loaded and will be returned
  *              by <code>udata_openChoice()</code> if this function
- *              returns <code>TRUE</code>.
- * @return TRUE if the current data memory is acceptable
+ *              returns <code>true</code>.
+ * @return true if the current data memory is acceptable
  * @stable ICU 2.0
  */
 typedef UBool U_CALLCONV
@@ -195,7 +200,7 @@
  * @see udata_openChoice
  * @stable ICU 2.0
  */
-U_STABLE UDataMemory * U_EXPORT2
+U_CAPI UDataMemory * U_EXPORT2
 udata_open(const char *path, const char *type, const char *name,
            UErrorCode *pErrorCode);
 
@@ -237,7 +242,7 @@
  *             This may be <code>NULL</code> or empty.
  * @param name A string that specifies the name of the data.
  * @param isAcceptable This function is called to verify that loaded data
- *                     is useful for the client code. If it returns FALSE
+ *                     is useful for the client code. If it returns false
  *                     for all data items, then <code>udata_openChoice()</code>
  *                     will return with an error.
  * @param context Arbitrary parameter to be passed into isAcceptable.
@@ -247,7 +252,7 @@
  *         to get a pointer to the actual data.
  * @stable ICU 2.0
  */
-U_STABLE UDataMemory * U_EXPORT2
+U_CAPI UDataMemory * U_EXPORT2
 udata_openChoice(const char *path, const char *type, const char *name,
                  UDataMemoryIsAcceptable *isAcceptable, void *context,
                  UErrorCode *pErrorCode);
@@ -259,28 +264,9 @@
  * @param pData The pointer to data memory object
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 udata_close(UDataMemory *pData);
 
-#if U_SHOW_CPLUSPLUS_API
-
-U_NAMESPACE_BEGIN
-
-/**
- * \class LocalUDataMemoryPointer
- * "Smart pointer" class, closes a UDataMemory via udata_close().
- * For most methods see the LocalPointerBase base class.
- *
- * @see LocalPointerBase
- * @see LocalPointer
- * @stable ICU 4.4
- */
-U_DEFINE_LOCAL_OPEN_POINTER(LocalUDataMemoryPointer, UDataMemory, udata_close);
-
-U_NAMESPACE_END
-
-#endif
-
 /**
  * Get the pointer to the actual data inside the data memory.
  * The data is read-only.
@@ -290,7 +276,7 @@
  * @param pData The pointer to data memory object
  * @stable ICU 2.0
  */
-U_STABLE const void * U_EXPORT2
+U_CAPI const void * U_EXPORT2
 udata_getMemory(UDataMemory *pData);
 
 /**
@@ -311,7 +297,7 @@
  * adjusted and only part of the structure will be filled.
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 udata_getInfo(UDataMemory *pData, UDataInfo *pInfo);
 
 /**
@@ -320,7 +306,7 @@
  * area in memory.
  *
  * ICU data must be at least 8-aligned, and should be 16-aligned.
- * See http://userguide.icu-project.org/icudata
+ * See https://unicode-org.github.io/icu/userguide/icudata
  *
  * The format of this data is that of the icu common data file, as is
  * generated by the pkgdata tool with mode=common or mode=dll.
@@ -357,7 +343,7 @@
  * @param err outgoing error status <code>U_USING_DEFAULT_WARNING, U_UNSUPPORTED_ERROR</code>
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 udata_setCommonData(const void *data, UErrorCode *err);
 
 
@@ -367,7 +353,7 @@
  * pointer.
  *
  * ICU data must be at least 8-aligned, and should be 16-aligned.
- * See http://userguide.icu-project.org/icudata
+ * See https://unicode-org.github.io/icu/userguide/icudata
  *
  * The format of this data is that of the icu common data file, like 'icudt26l.dat'
  * or the corresponding shared library (DLL) file.
@@ -388,7 +374,7 @@
  * @see udata_setCommonData
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 udata_setAppData(const char *packageName, const void *data, UErrorCode *err);
 
 /**
@@ -408,8 +394,13 @@
     UDATA_PACKAGES_FIRST,
     /** ICU does not access the file system for data loading. @stable ICU 3.4 */
     UDATA_NO_FILES,
-    /** Number of real UDataFileAccess values. @stable ICU 3.4 */
+#ifndef U_HIDE_DEPRECATED_API
+    /**
+     * Number of real UDataFileAccess values.
+     * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
+     */
     UDATA_FILE_ACCESS_COUNT
+#endif  // U_HIDE_DEPRECATED_API
 } UDataFileAccess;
 
 /**
@@ -422,9 +413,28 @@
  * @see UDataFileAccess
  * @stable ICU 3.4 
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 udata_setFileAccess(UDataFileAccess access, UErrorCode *status);
 
 U_CDECL_END
 
+#if U_SHOW_CPLUSPLUS_API
+
+U_NAMESPACE_BEGIN
+
+/**
+ * \class LocalUDataMemoryPointer
+ * "Smart pointer" class, closes a UDataMemory via udata_close().
+ * For most methods see the LocalPointerBase base class.
+ *
+ * @see LocalPointerBase
+ * @see LocalPointer
+ * @stable ICU 4.4
+ */
+U_DEFINE_LOCAL_OPEN_POINTER(LocalUDataMemoryPointer, UDataMemory, udata_close);
+
+U_NAMESPACE_END
+
+#endif  // U_SHOW_CPLUSPLUS_API
+
 #endif
diff --git a/src/third_party/icu/source/common/unicode/udisplaycontext.h b/src/third_party/icu/source/common/unicode/udisplaycontext.h
new file mode 100644
index 0000000..6e14217
--- /dev/null
+++ b/src/third_party/icu/source/common/unicode/udisplaycontext.h
@@ -0,0 +1,173 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+/*
+*****************************************************************************************
+* Copyright (C) 2014-2016, International Business Machines
+* Corporation and others. All Rights Reserved.
+*****************************************************************************************
+*/
+
+#ifndef UDISPLAYCONTEXT_H
+#define UDISPLAYCONTEXT_H
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_FORMATTING
+
+/**
+ * \file
+ * \brief C API: Display context types (enum values)
+ */
+
+/**
+ * Display context types, for getting values of a particular setting.
+ * Note, the specific numeric values are internal and may change.
+ * @stable ICU 51
+ */
+enum UDisplayContextType {
+    /**
+     * Type to retrieve the dialect handling setting, e.g.
+     * UDISPCTX_STANDARD_NAMES or UDISPCTX_DIALECT_NAMES.
+     * @stable ICU 51
+     */
+    UDISPCTX_TYPE_DIALECT_HANDLING = 0,
+    /**
+     * Type to retrieve the capitalization context setting, e.g.
+     * UDISPCTX_CAPITALIZATION_NONE, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE,
+     * UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, etc.
+     * @stable ICU 51
+     */
+    UDISPCTX_TYPE_CAPITALIZATION = 1,
+    /**
+     * Type to retrieve the display length setting, e.g.
+     * UDISPCTX_LENGTH_FULL, UDISPCTX_LENGTH_SHORT.
+     * @stable ICU 54
+     */
+    UDISPCTX_TYPE_DISPLAY_LENGTH = 2,
+    /**
+     * Type to retrieve the substitute handling setting, e.g.
+     * UDISPCTX_SUBSTITUTE, UDISPCTX_NO_SUBSTITUTE.
+     * @stable ICU 58
+     */
+    UDISPCTX_TYPE_SUBSTITUTE_HANDLING = 3
+};
+/**
+*  @stable ICU 51
+*/
+typedef enum UDisplayContextType UDisplayContextType;
+
+/**
+ * Display context settings.
+ * Note, the specific numeric values are internal and may change.
+ * @stable ICU 51
+ */
+enum UDisplayContext {
+    /**
+     * ================================
+     * DIALECT_HANDLING can be set to one of UDISPCTX_STANDARD_NAMES or
+     * UDISPCTX_DIALECT_NAMES. Use UDisplayContextType UDISPCTX_TYPE_DIALECT_HANDLING
+     * to get the value.
+     */
+    /**
+     * A possible setting for DIALECT_HANDLING:
+     * use standard names when generating a locale name,
+     * e.g. en_GB displays as 'English (United Kingdom)'.
+     * @stable ICU 51
+     */
+    UDISPCTX_STANDARD_NAMES = (UDISPCTX_TYPE_DIALECT_HANDLING<<8) + 0,
+    /**
+     * A possible setting for DIALECT_HANDLING:
+     * use dialect names, when generating a locale name,
+     * e.g. en_GB displays as 'British English'.
+     * @stable ICU 51
+     */
+    UDISPCTX_DIALECT_NAMES = (UDISPCTX_TYPE_DIALECT_HANDLING<<8) + 1,
+    /**
+     * ================================
+     * CAPITALIZATION can be set to one of UDISPCTX_CAPITALIZATION_NONE,
+     * UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE,
+     * UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE,
+     * UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU, or
+     * UDISPCTX_CAPITALIZATION_FOR_STANDALONE.
+     * Use UDisplayContextType UDISPCTX_TYPE_CAPITALIZATION to get the value.
+     */
+    /**
+     * The capitalization context to be used is unknown (this is the default value).
+     * @stable ICU 51
+     */
+    UDISPCTX_CAPITALIZATION_NONE = (UDISPCTX_TYPE_CAPITALIZATION<<8) + 0,
+    /**
+     * The capitalization context if a date, date symbol or display name is to be
+     * formatted with capitalization appropriate for the middle of a sentence.
+     * @stable ICU 51
+     */
+    UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE = (UDISPCTX_TYPE_CAPITALIZATION<<8) + 1,
+    /**
+     * The capitalization context if a date, date symbol or display name is to be
+     * formatted with capitalization appropriate for the beginning of a sentence.
+     * @stable ICU 51
+     */
+    UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE = (UDISPCTX_TYPE_CAPITALIZATION<<8) + 2,
+    /**
+     * The capitalization context if a date, date symbol or display name is to be
+     * formatted with capitalization appropriate for a user-interface list or menu item.
+     * @stable ICU 51
+     */
+    UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU = (UDISPCTX_TYPE_CAPITALIZATION<<8) + 3,
+    /**
+     * The capitalization context if a date, date symbol or display name is to be
+     * formatted with capitalization appropriate for stand-alone usage such as an
+     * isolated name on a calendar page.
+     * @stable ICU 51
+     */
+    UDISPCTX_CAPITALIZATION_FOR_STANDALONE = (UDISPCTX_TYPE_CAPITALIZATION<<8) + 4,
+    /**
+     * ================================
+     * DISPLAY_LENGTH can be set to one of UDISPCTX_LENGTH_FULL or
+     * UDISPCTX_LENGTH_SHORT. Use UDisplayContextType UDISPCTX_TYPE_DISPLAY_LENGTH
+     * to get the value.
+     */
+    /**
+     * A possible setting for DISPLAY_LENGTH:
+     * use full names when generating a locale name,
+     * e.g. "United States" for US.
+     * @stable ICU 54
+     */
+    UDISPCTX_LENGTH_FULL = (UDISPCTX_TYPE_DISPLAY_LENGTH<<8) + 0,
+    /**
+     * A possible setting for DISPLAY_LENGTH:
+     * use short names when generating a locale name,
+     * e.g. "U.S." for US.
+     * @stable ICU 54
+     */
+    UDISPCTX_LENGTH_SHORT = (UDISPCTX_TYPE_DISPLAY_LENGTH<<8) + 1,
+    /**
+     * ================================
+     * SUBSTITUTE_HANDLING can be set to one of UDISPCTX_SUBSTITUTE or
+     * UDISPCTX_NO_SUBSTITUTE. Use UDisplayContextType UDISPCTX_TYPE_SUBSTITUTE_HANDLING
+     * to get the value.
+     */
+    /**
+     * A possible setting for SUBSTITUTE_HANDLING:
+     * Returns a fallback value (e.g., the input code) when no data is available.
+     * This is the default value.
+     * @stable ICU 58
+     */
+    UDISPCTX_SUBSTITUTE = (UDISPCTX_TYPE_SUBSTITUTE_HANDLING<<8) + 0,
+    /**
+     * A possible setting for SUBSTITUTE_HANDLING:
+     * Returns a null value with error code set to U_ILLEGAL_ARGUMENT_ERROR when no
+     * data is available.
+     * @stable ICU 58
+     */
+    UDISPCTX_NO_SUBSTITUTE = (UDISPCTX_TYPE_SUBSTITUTE_HANDLING<<8) + 1
+
+};
+/**
+*  @stable ICU 51
+*/
+typedef enum UDisplayContext UDisplayContext;
+
+#endif /* #if !UCONFIG_NO_FORMATTING */
+
+#endif
diff --git a/src/third_party/icu/source/common/unicode/uenum.h b/src/third_party/icu/source/common/unicode/uenum.h
index 5408ec5..d9c893e 100644
--- a/src/third_party/icu/source/common/unicode/uenum.h
+++ b/src/third_party/icu/source/common/unicode/uenum.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  uenum.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:2
 *
@@ -18,11 +20,14 @@
 #define __UENUM_H
 
 #include "unicode/utypes.h"
-#include "unicode/localpointer.h"
 
 #if U_SHOW_CPLUSPLUS_API
-#include "unicode/strenum.h"
-#endif
+#include "unicode/localpointer.h"
+
+U_NAMESPACE_BEGIN
+class StringEnumeration;
+U_NAMESPACE_END
+#endif   // U_SHOW_CPLUSPLUS_API
 
 /**
  * \file
@@ -45,7 +50,7 @@
  * @param en UEnumeration structure pointer
  * @stable ICU 2.2
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 uenum_close(UEnumeration* en);
 
 #if U_SHOW_CPLUSPLUS_API
@@ -81,7 +86,7 @@
  * @return number of elements in the iterator
  * @stable ICU 2.2
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 uenum_count(UEnumeration* en, UErrorCode* status);
 
 /**
@@ -105,7 +110,7 @@
  *         traversed, returns NULL.
  * @stable ICU 2.2
  */
-U_STABLE const UChar* U_EXPORT2
+U_CAPI const UChar* U_EXPORT2
 uenum_unext(UEnumeration* en,
             int32_t* resultLength,
             UErrorCode* status);
@@ -138,7 +143,7 @@
  *         traversed, returns NULL.
  * @stable ICU 2.2
  */
-U_STABLE const char* U_EXPORT2
+U_CAPI const char* U_EXPORT2
 uenum_next(UEnumeration* en,
            int32_t* resultLength,
            UErrorCode* status);
@@ -152,7 +157,7 @@
  *               the iterator is out of sync with its service.  
  * @stable ICU 2.2
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 uenum_reset(UEnumeration* en, UErrorCode* status);
 
 #if U_SHOW_CPLUSPLUS_API
@@ -166,7 +171,7 @@
  * @return a UEnumeration wrapping the adopted StringEnumeration.
  * @stable ICU 4.2
  */
-U_STABLE UEnumeration* U_EXPORT2
+U_CAPI UEnumeration* U_EXPORT2
 uenum_openFromStringEnumeration(icu::StringEnumeration* adopted, UErrorCode* ec);
 
 #endif
@@ -182,12 +187,10 @@
  * @see uenum_close
  * @stable ICU 50
  */
-U_STABLE UEnumeration* U_EXPORT2
+U_CAPI UEnumeration* U_EXPORT2
 uenum_openUCharStringsEnumeration(const UChar* const strings[], int32_t count,
                                  UErrorCode* ec);
 
-/* Note:  next function is not hidden as draft, as it is used internally (it was formerly an internal function). */
-
 /**
  * Given an array of const char* strings (invariant chars only), return a UEnumeration.  String pointers from 0..count-1 must not be null.
  * Do not free or modify either the string array or the characters it points to until this object has been destroyed with uenum_close.
@@ -199,7 +202,7 @@
  * @see uenum_close
  * @stable ICU 50
  */
-U_STABLE UEnumeration* U_EXPORT2
+U_CAPI UEnumeration* U_EXPORT2
 uenum_openCharStringsEnumeration(const char* const strings[], int32_t count,
                                  UErrorCode* ec);
 
diff --git a/src/third_party/icu/source/common/unicode/uidna.h b/src/third_party/icu/source/common/unicode/uidna.h
index decece1..24a81ce 100644
--- a/src/third_party/icu/source/common/unicode/uidna.h
+++ b/src/third_party/icu/source/common/unicode/uidna.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
  *******************************************************************************
  *
@@ -6,7 +8,7 @@
  *
  *******************************************************************************
  *   file name:  uidna.h
- *   encoding:   US-ASCII
+ *   encoding:   UTF-8
  *   tab size:   8 (not used)
  *   indentation:4
  *
@@ -21,9 +23,13 @@
 
 #if !UCONFIG_NO_IDNA
 
-#include "unicode/localpointer.h"
+#include <stdbool.h>
 #include "unicode/parseerr.h"
 
+#if U_SHOW_CPLUSPLUS_API
+#include "unicode/localpointer.h"
+#endif   // U_SHOW_CPLUSPLUS_API
+
 /**
  * \file
  * \brief C API: Internationalizing Domain Names in Applications (IDNA)
@@ -136,7 +142,7 @@
  * @return the UTS #46 UIDNA instance, if successful
  * @stable ICU 4.6
  */
-U_STABLE UIDNA * U_EXPORT2
+U_CAPI UIDNA * U_EXPORT2
 uidna_openUTS46(uint32_t options, UErrorCode *pErrorCode);
 
 /**
@@ -144,7 +150,7 @@
  * @param idna UIDNA instance to be closed
  * @stable ICU 4.6
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 uidna_close(UIDNA *idna);
 
 #if U_SHOW_CPLUSPLUS_API
@@ -180,7 +186,7 @@
     /** sizeof(UIDNAInfo) @stable ICU 4.6 */
     int16_t size;
     /**
-     * Set to TRUE if transitional and nontransitional processing produce different results.
+     * Set to true if transitional and nontransitional processing produce different results.
      * For details see C++ IDNAInfo::isTransitionalDifferent().
      * @stable ICU 4.6
      */
@@ -202,7 +208,7 @@
  */
 #define UIDNA_INFO_INITIALIZER { \
     (int16_t)sizeof(UIDNAInfo), \
-    FALSE, FALSE, \
+    false, false, \
     0, 0, 0 }
 
 /**
@@ -228,7 +234,7 @@
  * @return destination string length
  * @stable ICU 4.6
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 uidna_labelToASCII(const UIDNA *idna,
                    const UChar *label, int32_t length,
                    UChar *dest, int32_t capacity,
@@ -255,7 +261,7 @@
  * @return destination string length
  * @stable ICU 4.6
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 uidna_labelToUnicode(const UIDNA *idna,
                      const UChar *label, int32_t length,
                      UChar *dest, int32_t capacity,
@@ -284,7 +290,7 @@
  * @return destination string length
  * @stable ICU 4.6
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 uidna_nameToASCII(const UIDNA *idna,
                   const UChar *name, int32_t length,
                   UChar *dest, int32_t capacity,
@@ -311,7 +317,7 @@
  * @return destination string length
  * @stable ICU 4.6
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 uidna_nameToUnicode(const UIDNA *idna,
                     const UChar *name, int32_t length,
                     UChar *dest, int32_t capacity,
@@ -336,7 +342,7 @@
  * @return destination string length
  * @stable ICU 4.6
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 uidna_labelToASCII_UTF8(const UIDNA *idna,
                         const char *label, int32_t length,
                         char *dest, int32_t capacity,
@@ -359,7 +365,7 @@
  * @return destination string length
  * @stable ICU 4.6
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 uidna_labelToUnicodeUTF8(const UIDNA *idna,
                          const char *label, int32_t length,
                          char *dest, int32_t capacity,
@@ -382,7 +388,7 @@
  * @return destination string length
  * @stable ICU 4.6
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 uidna_nameToASCII_UTF8(const UIDNA *idna,
                        const char *name, int32_t length,
                        char *dest, int32_t capacity,
@@ -405,7 +411,7 @@
  * @return destination string length
  * @stable ICU 4.6
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 uidna_nameToUnicodeUTF8(const UIDNA *idna,
                         const char *name, int32_t length,
                         char *dest, int32_t capacity,
diff --git a/src/third_party/icu/source/common/unicode/uiter.h b/src/third_party/icu/source/common/unicode/uiter.h
index 0cdb8ff..be232c7 100644
--- a/src/third_party/icu/source/common/unicode/uiter.h
+++ b/src/third_party/icu/source/common/unicode/uiter.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  uiter.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -490,7 +492,7 @@
  * @see UnicodeString::char32At()
  * @stable ICU 2.1
  */
-U_STABLE UChar32 U_EXPORT2
+U_CAPI UChar32 U_EXPORT2
 uiter_current32(UCharIterator *iter);
 
 /**
@@ -507,7 +509,7 @@
  * @see U16_NEXT
  * @stable ICU 2.1
  */
-U_STABLE UChar32 U_EXPORT2
+U_CAPI UChar32 U_EXPORT2
 uiter_next32(UCharIterator *iter);
 
 /**
@@ -524,7 +526,7 @@
  * @see U16_PREV
  * @stable ICU 2.1
  */
-U_STABLE UChar32 U_EXPORT2
+U_CAPI UChar32 U_EXPORT2
 uiter_previous32(UCharIterator *iter);
 
 /**
@@ -545,7 +547,7 @@
  * @see UITER_NO_STATE
  * @stable ICU 2.6
  */
-U_STABLE uint32_t U_EXPORT2
+U_CAPI uint32_t U_EXPORT2
 uiter_getState(const UCharIterator *iter);
 
 /**
@@ -563,7 +565,7 @@
  * @see UCharIteratorSetState
  * @stable ICU 2.6
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 uiter_setState(UCharIterator *iter, uint32_t state, UErrorCode *pErrorCode);
 
 /**
@@ -588,7 +590,7 @@
  * @see UCharIterator
  * @stable ICU 2.1
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 uiter_setString(UCharIterator *iter, const UChar *s, int32_t length);
 
 /**
@@ -611,7 +613,7 @@
  * @see uiter_setString
  * @stable ICU 2.6
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 uiter_setUTF16BE(UCharIterator *iter, const char *s, int32_t length);
 
 /**
@@ -647,7 +649,7 @@
  * @see UCharIterator
  * @stable ICU 2.6
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 uiter_setUTF8(UCharIterator *iter, const char *s, int32_t length);
 
 #if U_SHOW_CPLUSPLUS_API
@@ -672,7 +674,7 @@
  * @see UCharIterator
  * @stable ICU 2.1
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 uiter_setCharacterIterator(UCharIterator *iter, icu::CharacterIterator *charIter);
 
 /**
@@ -697,7 +699,7 @@
  * @see UCharIterator
  * @stable ICU 2.1
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 uiter_setReplaceable(UCharIterator *iter, const icu::Replaceable *rep);
 
 #endif
diff --git a/src/third_party/icu/source/common/unicode/uldnames.h b/src/third_party/icu/source/common/unicode/uldnames.h
new file mode 100644
index 0000000..47b047e
--- /dev/null
+++ b/src/third_party/icu/source/common/unicode/uldnames.h
@@ -0,0 +1,307 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+/*
+*******************************************************************************
+*   Copyright (C) 2010-2016, International Business Machines Corporation and
+*   others.  All Rights Reserved.
+*******************************************************************************
+*/
+
+#ifndef __ULDNAMES_H__
+#define __ULDNAMES_H__
+
+/**
+ * \file
+ * \brief C API: Provides display names of Locale ids and their components.
+ */
+
+#include "unicode/utypes.h"
+#include "unicode/uscript.h"
+#include "unicode/udisplaycontext.h"
+
+#if U_SHOW_CPLUSPLUS_API
+#include "unicode/localpointer.h"
+#endif   // U_SHOW_CPLUSPLUS_API
+
+/**
+ * Enum used in LocaleDisplayNames::createInstance.
+ * @stable ICU 4.4
+ */
+typedef enum {
+    /**
+     * Use standard names when generating a locale name,
+     * e.g. en_GB displays as 'English (United Kingdom)'.
+     * @stable ICU 4.4
+     */
+    ULDN_STANDARD_NAMES = 0,
+    /**
+     * Use dialect names, when generating a locale name,
+     * e.g. en_GB displays as 'British English'.
+     * @stable ICU 4.4
+     */
+    ULDN_DIALECT_NAMES
+} UDialectHandling;
+
+/**
+ * Opaque C service object type for the locale display names API
+ * @stable ICU 4.4
+ */
+struct ULocaleDisplayNames;
+
+/** 
+ * C typedef for struct ULocaleDisplayNames. 
+ * @stable ICU 4.4 
+ */
+typedef struct ULocaleDisplayNames ULocaleDisplayNames;  
+
+#if !UCONFIG_NO_FORMATTING
+
+/**
+ * Returns an instance of LocaleDisplayNames that returns names
+ * formatted for the provided locale, using the provided
+ * dialectHandling.  The usual value for dialectHandling is
+ * ULOC_STANDARD_NAMES.
+ *
+ * @param locale the display locale 
+ * @param dialectHandling how to select names for locales 
+ * @return a ULocaleDisplayNames instance 
+ * @param pErrorCode the status code
+ * @stable ICU 4.4
+ */
+U_CAPI ULocaleDisplayNames * U_EXPORT2
+uldn_open(const char * locale,
+          UDialectHandling dialectHandling,
+          UErrorCode *pErrorCode);
+
+/**
+ * Closes a ULocaleDisplayNames instance obtained from uldn_open().
+ * @param ldn the ULocaleDisplayNames instance to be closed
+ * @stable ICU 4.4
+ */
+U_CAPI void U_EXPORT2
+uldn_close(ULocaleDisplayNames *ldn);
+
+#if U_SHOW_CPLUSPLUS_API
+
+U_NAMESPACE_BEGIN
+
+/**
+ * \class LocalULocaleDisplayNamesPointer
+ * "Smart pointer" class, closes a ULocaleDisplayNames via uldn_close().
+ * For most methods see the LocalPointerBase base class.
+ *
+ * @see LocalPointerBase
+ * @see LocalPointer
+ * @stable ICU 4.4
+ */
+U_DEFINE_LOCAL_OPEN_POINTER(LocalULocaleDisplayNamesPointer, ULocaleDisplayNames, uldn_close);
+
+U_NAMESPACE_END
+
+#endif
+
+/* getters for state */
+
+/**
+ * Returns the locale used to determine the display names. This is
+ * not necessarily the same locale passed to {@link #uldn_open}.
+ * @param ldn the LocaleDisplayNames instance
+ * @return the display locale 
+ * @stable ICU 4.4
+ */
+U_CAPI const char * U_EXPORT2
+uldn_getLocale(const ULocaleDisplayNames *ldn);
+
+/**
+ * Returns the dialect handling used in the display names.
+ * @param ldn the LocaleDisplayNames instance
+ * @return the dialect handling enum
+ * @stable ICU 4.4
+ */
+U_CAPI UDialectHandling U_EXPORT2
+uldn_getDialectHandling(const ULocaleDisplayNames *ldn);
+
+/* names for entire locales */
+
+/**
+ * Returns the display name of the provided locale.
+ * @param ldn the LocaleDisplayNames instance
+ * @param locale the locale whose display name to return
+ * @param result receives the display name
+ * @param maxResultSize the size of the result buffer
+ * @param pErrorCode the status code
+ * @return the actual buffer size needed for the display name.  If it's
+ * greater than maxResultSize, the returned name will be truncated.
+ * @stable ICU 4.4
+ */
+U_CAPI int32_t U_EXPORT2
+uldn_localeDisplayName(const ULocaleDisplayNames *ldn,
+                       const char *locale,
+                       UChar *result,
+                       int32_t maxResultSize,
+                       UErrorCode *pErrorCode);
+
+/* names for components of a locale */
+
+/**
+ * Returns the display name of the provided language code.
+ * @param ldn the LocaleDisplayNames instance
+ * @param lang the language code whose display name to return
+ * @param result receives the display name
+ * @param maxResultSize the size of the result buffer
+ * @param pErrorCode the status code
+ * @return the actual buffer size needed for the display name.  If it's
+ * greater than maxResultSize, the returned name will be truncated.
+ * @stable ICU 4.4
+ */
+U_CAPI int32_t U_EXPORT2
+uldn_languageDisplayName(const ULocaleDisplayNames *ldn,
+                         const char *lang,
+                         UChar *result,
+                         int32_t maxResultSize,
+                         UErrorCode *pErrorCode);
+
+/**
+ * Returns the display name of the provided script.
+ * @param ldn the LocaleDisplayNames instance
+ * @param script the script whose display name to return
+ * @param result receives the display name
+ * @param maxResultSize the size of the result buffer
+ * @param pErrorCode the status code
+ * @return the actual buffer size needed for the display name.  If it's
+ * greater than maxResultSize, the returned name will be truncated.
+ * @stable ICU 4.4
+ */
+U_CAPI int32_t U_EXPORT2
+uldn_scriptDisplayName(const ULocaleDisplayNames *ldn,
+                       const char *script,
+                       UChar *result,
+                       int32_t maxResultSize,
+                       UErrorCode *pErrorCode);
+
+/**
+ * Returns the display name of the provided script code.
+ * @param ldn the LocaleDisplayNames instance
+ * @param scriptCode the script code whose display name to return
+ * @param result receives the display name
+ * @param maxResultSize the size of the result buffer
+ * @param pErrorCode the status code
+ * @return the actual buffer size needed for the display name.  If it's
+ * greater than maxResultSize, the returned name will be truncated.
+ * @stable ICU 4.4
+ */
+U_CAPI int32_t U_EXPORT2
+uldn_scriptCodeDisplayName(const ULocaleDisplayNames *ldn,
+                           UScriptCode scriptCode,
+                           UChar *result,
+                           int32_t maxResultSize,
+                           UErrorCode *pErrorCode);
+
+/**
+ * Returns the display name of the provided region code.
+ * @param ldn the LocaleDisplayNames instance
+ * @param region the region code whose display name to return
+ * @param result receives the display name
+ * @param maxResultSize the size of the result buffer
+ * @param pErrorCode the status code
+ * @return the actual buffer size needed for the display name.  If it's
+ * greater than maxResultSize, the returned name will be truncated.
+ * @stable ICU 4.4
+ */
+U_CAPI int32_t U_EXPORT2
+uldn_regionDisplayName(const ULocaleDisplayNames *ldn,
+                       const char *region,
+                       UChar *result,
+                       int32_t maxResultSize,
+                       UErrorCode *pErrorCode);
+
+/**
+ * Returns the display name of the provided variant
+ * @param ldn the LocaleDisplayNames instance
+ * @param variant the variant whose display name to return
+ * @param result receives the display name
+ * @param maxResultSize the size of the result buffer
+ * @param pErrorCode the status code
+ * @return the actual buffer size needed for the display name.  If it's
+ * greater than maxResultSize, the returned name will be truncated.
+ * @stable ICU 4.4
+ */
+U_CAPI int32_t U_EXPORT2
+uldn_variantDisplayName(const ULocaleDisplayNames *ldn,
+                        const char *variant,
+                        UChar *result,
+                        int32_t maxResultSize,
+                        UErrorCode *pErrorCode);
+
+/**
+ * Returns the display name of the provided locale key
+ * @param ldn the LocaleDisplayNames instance
+ * @param key the locale key whose display name to return
+ * @param result receives the display name
+ * @param maxResultSize the size of the result buffer
+ * @param pErrorCode the status code
+ * @return the actual buffer size needed for the display name.  If it's
+ * greater than maxResultSize, the returned name will be truncated.
+ * @stable ICU 4.4
+ */
+U_CAPI int32_t U_EXPORT2
+uldn_keyDisplayName(const ULocaleDisplayNames *ldn,
+                    const char *key,
+                    UChar *result,
+                    int32_t maxResultSize,
+                    UErrorCode *pErrorCode);
+
+/**
+ * Returns the display name of the provided value (used with the provided key).
+ * @param ldn the LocaleDisplayNames instance
+ * @param key the locale key
+ * @param value the locale key's value
+ * @param result receives the display name
+ * @param maxResultSize the size of the result buffer
+ * @param pErrorCode the status code
+ * @return the actual buffer size needed for the display name.  If it's
+ * greater than maxResultSize, the returned name will be truncated.
+ * @stable ICU 4.4
+ */
+U_CAPI int32_t U_EXPORT2
+uldn_keyValueDisplayName(const ULocaleDisplayNames *ldn,
+                         const char *key,
+                         const char *value,
+                         UChar *result,
+                         int32_t maxResultSize,
+                         UErrorCode *pErrorCode);
+
+/**
+* Returns an instance of LocaleDisplayNames that returns names formatted
+* for the provided locale, using the provided UDisplayContext settings.
+*
+* @param locale The display locale 
+* @param contexts List of one or more context settings (e.g. for dialect
+*               handling, capitalization, etc.
+* @param length Number of items in the contexts list
+* @param pErrorCode Pointer to UErrorCode input/output status. If at entry this indicates
+*               a failure status, the function will do nothing; otherwise this will be
+*               updated with any new status from the function. 
+* @return a ULocaleDisplayNames instance 
+* @stable ICU 51
+*/
+U_CAPI ULocaleDisplayNames * U_EXPORT2
+uldn_openForContext(const char * locale, UDisplayContext *contexts,
+                    int32_t length, UErrorCode *pErrorCode);
+
+/**
+* Returns the UDisplayContext value for the specified UDisplayContextType.
+* @param ldn the ULocaleDisplayNames instance
+* @param type the UDisplayContextType whose value to return
+* @param pErrorCode Pointer to UErrorCode input/output status. If at entry this indicates
+*               a failure status, the function will do nothing; otherwise this will be
+*               updated with any new status from the function. 
+* @return the UDisplayContextValue for the specified type.
+* @stable ICU 51
+*/
+U_CAPI UDisplayContext U_EXPORT2
+uldn_getContext(const ULocaleDisplayNames *ldn, UDisplayContextType type,
+                UErrorCode *pErrorCode);
+
+#endif  /* !UCONFIG_NO_FORMATTING */
+#endif  /* __ULDNAMES_H__ */
diff --git a/src/third_party/icu/source/common/unicode/ulistformatter.h b/src/third_party/icu/source/common/unicode/ulistformatter.h
deleted file mode 100644
index 1c6cb2d..0000000
--- a/src/third_party/icu/source/common/unicode/ulistformatter.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
-*****************************************************************************************
-* Copyright (C) 2015, International Business Machines
-* Corporation and others. All Rights Reserved.
-*****************************************************************************************
-*/
-
-#ifndef ULISTFORMATTER_H
-#define ULISTFORMATTER_H
-
-#include "unicode/utypes.h"
-
-#if !UCONFIG_NO_FORMATTING
-#ifndef U_HIDE_DRAFT_API
-
-#include "unicode/localpointer.h"
-
-/**
- * \file
- * \brief C API: Format a list in a locale-appropriate way.
- *
- * A UListFormatter is used to format a list of items in a locale-appropriate way, 
- * using data from CLDR.
- * Example: Input data ["Alice", "Bob", "Charlie", "Delta"] will be formatted
- * as "Alice, Bob, Charlie, and Delta" in English.
- */
-
-/**
- * Opaque UListFormatter object for use in C
- * @draft ICU 55
- */
-struct UListFormatter;
-typedef struct UListFormatter UListFormatter;  /**< C typedef for struct UListFormatter. @draft ICU 55 */
-
-/**
- * Open a new UListFormatter object using the rules for a given locale.
- * @param locale
- *            The locale whose rules should be used; may be NULL for
- *            default locale.
- * @param status
- *            A pointer to a standard ICU UErrorCode (input/output parameter).
- *            Its input value must pass the U_SUCCESS() test, or else the
- *            function returns immediately. The caller should check its output
- *            value with U_FAILURE(), or use with function chaining (see User
- *            Guide for details).
- * @return
- *            A pointer to a UListFormatter object for the specified locale,
- *            or NULL if an error occurred.
- * @draft ICU 55
- */
-U_DRAFT UListFormatter* U_EXPORT2
-ulistfmt_open(const char*  locale,
-              UErrorCode*  status);
-
-/**
- * Close a UListFormatter object. Once closed it may no longer be used.
- * @param listfmt
- *            The UListFormatter object to close.
- * @draft ICU 55
- */
-U_DRAFT void U_EXPORT2
-ulistfmt_close(UListFormatter *listfmt);
-
-
-#if U_SHOW_CPLUSPLUS_API
-
-U_NAMESPACE_BEGIN
-
-/**
- * \class LocalUListFormatterPointer
- * "Smart pointer" class, closes a UListFormatter via ulistfmt_close().
- * For most methods see the LocalPointerBase base class.
- *
- * @see LocalPointerBase
- * @see LocalPointer
- * @draft ICU 55
- */
-U_DEFINE_LOCAL_OPEN_POINTER(LocalUListFormatterPointer, UListFormatter, ulistfmt_close);
-
-U_NAMESPACE_END
-
-#endif
-
-/**
- * Formats a list of strings using the conventions established for the
- * UListFormatter object.
- * @param listfmt
- *            The UListFormatter object specifying the list conventions.
- * @param strings
- *            An array of pointers to UChar strings; the array length is
- *            specified by stringCount. Must be non-NULL if stringCount > 0.
- * @param stringLengths
- *            An array of string lengths corresponding to the strings[]
- *            parameter; any individual length value may be negative to indicate
- *            that the corresponding strings[] entry is 0-terminated, or
- *            stringLengths itself may be NULL if all of the strings are
- *            0-terminated. If non-NULL, the stringLengths array must have
- *            stringCount entries.
- * @param stringCount
- *            the number of entries in strings[], and the number of entries
- *            in the stringLengths array if it is not NULL. Must be >= 0.
- * @param result
- *            A pointer to a buffer to receive the formatted list.
- * @param resultCapacity
- *            The maximum size of result.
- * @param status
- *            A pointer to a standard ICU UErrorCode (input/output parameter).
- *            Its input value must pass the U_SUCCESS() test, or else the
- *            function returns immediately. The caller should check its output
- *            value with U_FAILURE(), or use with function chaining (see User
- *            Guide for details).
- * @return
- *            The total buffer size needed; if greater than resultLength, the
- *            output was truncated. May be <=0 if unable to determine the
- *            total buffer size needed (e.g. for illegal arguments).
- * @draft ICU 55
- */
-U_DRAFT int32_t U_EXPORT2
-ulistfmt_format(const UListFormatter* listfmt,
-                const UChar* const strings[],
-                const int32_t *    stringLengths,
-                int32_t            stringCount,
-                UChar*             result,
-                int32_t            resultCapacity,
-                UErrorCode*        status);
-
-#endif /* U_HIDE_DRAFT_API */
-#endif /* #if !UCONFIG_NO_FORMATTING */
-
-#endif
diff --git a/src/third_party/icu/source/common/unicode/uloc.h b/src/third_party/icu/source/common/unicode/uloc.h
index 2da74e7..3addb84 100644
--- a/src/third_party/icu/source/common/unicode/uloc.h
+++ b/src/third_party/icu/source/common/unicode/uloc.h
@@ -1,6 +1,8 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
-*   Copyright (C) 1997-2015, International Business Machines
+*   Copyright (C) 1997-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 **********************************************************************
 *
@@ -59,7 +61,7 @@
  * http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt</a>
  *
  * <P>
- * The second option includes an additonal <STRONG>ISO Country
+ * The second option includes an additional <STRONG>ISO Country
  * Code.</STRONG> These codes are the upper-case two-letter codes
  * as defined by ISO-3166.
  * You can find a full list of these codes at a number of sites, such as:
@@ -67,7 +69,7 @@
  * http://www.chemie.fu-berlin.de/diverse/doc/ISO_3166.html</a>
  *
  * <P>
- * The third option requires another additonal information--the 
+ * The third option requires another additional information--the 
  * <STRONG>Variant.</STRONG>
  * The Variant codes are vendor and browser-specific.
  * For example, use WIN for Windows, MAC for Macintosh, and POSIX for POSIX.
@@ -155,7 +157,7 @@
  * <STRONG>just</STRONG> a mechanism for identifying these services.
  *
  * <P>
- * Each international serivce that performs locale-sensitive operations 
+ * Each international service that performs locale-sensitive operations 
  * allows you
  * to get all the available objects of that type. You can sift
  * through these objects by language, country, or variant,
@@ -348,10 +350,14 @@
    *  @deprecated ICU 2.8 
    */
   ULOC_REQUESTED_LOCALE = 2,
-#endif /* U_HIDE_DEPRECATED_API */
 
-  ULOC_DATA_LOCALE_TYPE_LIMIT = 3
-} ULocDataLocaleType ;
+    /**
+     * One more than the highest normal ULocDataLocaleType value.
+     * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
+     */
+    ULOC_DATA_LOCALE_TYPE_LIMIT = 3
+#endif  // U_HIDE_DEPRECATED_API
+} ULocDataLocaleType;
 
 #ifndef U_HIDE_SYSTEM_API
 /**
@@ -365,7 +371,7 @@
  * @system
  * @stable ICU 2.0
  */
-U_STABLE const char* U_EXPORT2
+U_CAPI const char* U_EXPORT2
 uloc_getDefault(void);
 
 /**
@@ -385,7 +391,7 @@
  * @system
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 uloc_setDefault(const char* localeID,
         UErrorCode*       status);
 #endif  /* U_HIDE_SYSTEM_API */
@@ -402,7 +408,7 @@
  * than languageCapacity, the returned language code will be truncated.  
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 uloc_getLanguage(const char*    localeID,
          char* language,
          int32_t languageCapacity,
@@ -420,7 +426,7 @@
  * than scriptCapacity, the returned language code will be truncated.  
  * @stable ICU 2.8
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 uloc_getScript(const char*    localeID,
          char* script,
          int32_t scriptCapacity,
@@ -438,7 +444,7 @@
  * than countryCapacity, the returned country code will be truncated.  
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 uloc_getCountry(const char*    localeID,
         char* country,
         int32_t countryCapacity,
@@ -456,7 +462,7 @@
  * than variantCapacity, the returned variant code will be truncated.  
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 uloc_getVariant(const char*    localeID,
         char* variant,
         int32_t variantCapacity,
@@ -479,7 +485,7 @@
  * than nameCapacity, the returned full name will be truncated.  
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 uloc_getName(const char*    localeID,
          char* name,
          int32_t nameCapacity,
@@ -502,7 +508,7 @@
  * than nameCapacity, the returned full name will be truncated.  
  * @stable ICU 2.8
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 uloc_canonicalize(const char*    localeID,
          char* name,
          int32_t nameCapacity,
@@ -515,7 +521,7 @@
  * @return language the ISO language code for localeID
  * @stable ICU 2.0
  */
-U_STABLE const char* U_EXPORT2
+U_CAPI const char* U_EXPORT2
 uloc_getISO3Language(const char* localeID);
 
 
@@ -526,37 +532,45 @@
  * @return country the ISO country code for localeID
  * @stable ICU 2.0
  */
-U_STABLE const char* U_EXPORT2
+U_CAPI const char* U_EXPORT2
 uloc_getISO3Country(const char* localeID);
 
 /**
  * Gets the Win32 LCID value for the specified locale.
  * If the ICU locale is not recognized by Windows, 0 will be returned.
  *
+ * LCIDs were deprecated with Windows Vista and Microsoft recommends
+ * that developers use BCP47 style tags instead (uloc_toLanguageTag).
+ *
  * @param localeID the locale to get the Win32 LCID value with
  * @return country the Win32 LCID for localeID
  * @stable ICU 2.0
  */
-U_STABLE uint32_t U_EXPORT2
+U_CAPI uint32_t U_EXPORT2
 uloc_getLCID(const char* localeID);
 
 /**
  * Gets the language name suitable for display for the specified locale.
  *
  * @param locale the locale to get the ISO language code with
- * @param displayLocale Specifies the locale to be used to display the name.  In other words,
- *                 if the locale's language code is "en", passing Locale::getFrench() for
- *                 inLocale would result in "Anglais", while passing Locale::getGerman()
- *                 for inLocale would result in "Englisch".
+ * @param displayLocale Specifies the locale to be used to display the name. In
+ *                 other words, if the locale's language code is "en", passing
+ *                 Locale::getFrench() for inLocale would result in "Anglais",
+ *                 while passing Locale::getGerman() for inLocale would result
+ *                 in "Englisch".
  * @param language the displayable language code for localeID
- * @param languageCapacity the size of the language buffer to store the  
- * displayable language code with
- * @param status error information if retrieving the displayable language code failed
- * @return the actual buffer size needed for the displayable language code.  If it's greater 
- * than languageCapacity, the returned language code will be truncated.  
+ * @param languageCapacity the size of the language buffer to store the
+ *                 displayable language code with.
+ * @param status error information if retrieving the displayable language code
+ *                 failed. U_USING_DEFAULT_WARNING indicates that no data was
+ *                 found from the locale resources and a case canonicalized
+ *                 language code is placed into language as fallback.
+ * @return the actual buffer size needed for the displayable language code. If
+ *                 it's greater than languageCapacity, the returned language
+ *                 code will be truncated.
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 uloc_getDisplayLanguage(const char* locale,
             const char* displayLocale,
             UChar* language,
@@ -566,20 +580,26 @@
 /**
  * Gets the script name suitable for display for the specified locale.
  *
- * @param locale the locale to get the displayable script code with. NULL may be used to specify the default.
- * @param displayLocale Specifies the locale to be used to display the name.  In other words,
- *                 if the locale's language code is "en", passing Locale::getFrench() for
- *                 inLocale would result in "", while passing Locale::getGerman()
- *                 for inLocale would result in "". NULL may be used to specify the default.
- * @param script the displayable country code for localeID
- * @param scriptCapacity the size of the script buffer to store the  
- * displayable script code with
- * @param status error information if retrieving the displayable script code failed
- * @return the actual buffer size needed for the displayable script code.  If it's greater 
- * than scriptCapacity, the returned displayable script code will be truncated.  
+ * @param locale the locale to get the displayable script code with. NULL may be
+ *                 used to specify the default.
+ * @param displayLocale Specifies the locale to be used to display the name. In
+ *                 other words, if the locale's language code is "en", passing
+ *                 Locale::getFrench() for inLocale would result in "", while
+ *                 passing Locale::getGerman() for inLocale would result in "".
+ *                 NULL may be used to specify the default.
+ * @param script the displayable script for the localeID.
+ * @param scriptCapacity the size of the script buffer to store the displayable
+ *                 script code with.
+ * @param status error information if retrieving the displayable script code
+ *                 failed. U_USING_DEFAULT_WARNING indicates that no data was
+ *                 found from the locale resources and a case canonicalized
+ *                 script code is placed into script as fallback.
+ * @return the actual buffer size needed for the displayable script code. If
+ *                 it's greater than scriptCapacity, the returned displayable
+ *                 script code will be truncated.
  * @stable ICU 2.8
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 uloc_getDisplayScript(const char* locale,
             const char* displayLocale,
             UChar* script,
@@ -588,21 +608,30 @@
 
 /**
  * Gets the country name suitable for display for the specified locale.
+ * Warning: this is for the region part of a valid locale ID; it cannot just be
+ * the region code (like "FR"). To get the display name for a region alone, or
+ * for other options, use ULocaleDisplayNames instead.
  *
- * @param locale the locale to get the displayable country code with. NULL may be used to specify the default.
- * @param displayLocale Specifies the locale to be used to display the name.  In other words,
- *                 if the locale's language code is "en", passing Locale::getFrench() for
- *                 inLocale would result in "Anglais", while passing Locale::getGerman()
- *                 for inLocale would result in "Englisch". NULL may be used to specify the default.
- * @param country the displayable country code for localeID
- * @param countryCapacity the size of the country buffer to store the  
- * displayable country code with
- * @param status error information if retrieving the displayable country code failed
- * @return the actual buffer size needed for the displayable country code.  If it's greater 
- * than countryCapacity, the returned displayable country code will be truncated.  
+ * @param locale the locale to get the displayable country code with. NULL may
+ *                 be used to specify the default.
+ * @param displayLocale Specifies the locale to be used to display the name. In
+ *                 other words, if the locale's language code is "en", passing
+ *                 Locale::getFrench() for inLocale would result in "Anglais",
+ *                 while passing Locale::getGerman() for inLocale would result
+ *                 in "Englisch". NULL may be used to specify the default.
+ * @param country the displayable country code for localeID.
+ * @param countryCapacity the size of the country buffer to store the
+ *                 displayable country code with.
+ * @param status error information if retrieving the displayable country code
+ *                 failed. U_USING_DEFAULT_WARNING indicates that no data was
+ *                 found from the locale resources and a case canonicalized
+ *                 country code is placed into country as fallback.
+ * @return the actual buffer size needed for the displayable country code. If
+ *                 it's greater than countryCapacity, the returned displayable
+ *                 country code will be truncated.
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 uloc_getDisplayCountry(const char* locale,
                        const char* displayLocale,
                        UChar* country,
@@ -613,20 +642,26 @@
 /**
  * Gets the variant name suitable for display for the specified locale.
  *
- * @param locale the locale to get the displayable variant code with. NULL may be used to specify the default.
- * @param displayLocale Specifies the locale to be used to display the name.  In other words,
- *                 if the locale's language code is "en", passing Locale::getFrench() for
- *                 inLocale would result in "Anglais", while passing Locale::getGerman()
- *                 for inLocale would result in "Englisch". NULL may be used to specify the default.
- * @param variant the displayable variant code for localeID
- * @param variantCapacity the size of the variant buffer to store the 
- * displayable variant code with
- * @param status error information if retrieving the displayable variant code failed
- * @return the actual buffer size needed for the displayable variant code.  If it's greater 
- * than variantCapacity, the returned displayable variant code will be truncated.  
+ * @param locale the locale to get the displayable variant code with. NULL may
+ *                 be used to specify the default.
+ * @param displayLocale Specifies the locale to be used to display the name. In
+ *                 other words, if the locale's language code is "en", passing
+ *                 Locale::getFrench() for inLocale would result in "Anglais",
+ *                 while passing Locale::getGerman() for inLocale would result
+ *                 in "Englisch". NULL may be used to specify the default.
+ * @param variant the displayable variant code for localeID.
+ * @param variantCapacity the size of the variant buffer to store the
+ *                 displayable variant code with.
+ * @param status error information if retrieving the displayable variant code
+ *                 failed. U_USING_DEFAULT_WARNING indicates that no data was
+ *                 found from the locale resources and a case canonicalized
+ *                 variant code is placed into variant as fallback.
+ * @return the actual buffer size needed for the displayable variant code. If
+ *                 it's greater than variantCapacity, the returned displayable
+ *                 variant code will be truncated.
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 uloc_getDisplayVariant(const char* locale,
                        const char* displayLocale,
                        UChar* variant,
@@ -634,9 +669,9 @@
                        UErrorCode* status);
 
 /**
- * Gets the keyword name suitable for display for the specified locale.
- * E.g: for the locale string de_DE\@collation=PHONEBOOK, this API gets the display 
- * string for the keyword collation. 
+ * Gets the keyword name suitable for display for the specified locale. E.g:
+ * for the locale string de_DE\@collation=PHONEBOOK, this API gets the display
+ * string for the keyword collation.
  * Usage:
  * <code>
  *    UErrorCode status = U_ZERO_ERROR;
@@ -665,15 +700,17 @@
  *                          for inLocale would result in "Englisch". NULL may be used to specify the default.
  * @param dest              the buffer to which the displayable keyword should be written.
  * @param destCapacity      The size of the buffer (number of UChars). If it is 0, then
- *                          dest may be NULL and the function will only return the length of the 
+ *                          dest may be NULL and the function will only return the length of the
  *                          result without writing any of the result string (pre-flighting).
- * @param status            error information if retrieving the displayable string failed. 
+ * @param status            error information if retrieving the displayable string failed.
  *                          Should not be NULL and should not indicate failure on entry.
- * @return the actual buffer size needed for the displayable variant code.  
+ *                          U_USING_DEFAULT_WARNING indicates that no data was found from the locale
+ *                          resources and the keyword is placed into dest as fallback.
+ * @return the actual buffer size needed for the displayable variant code.
  * @see #uloc_openKeywords
  * @stable ICU 2.8
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 uloc_getDisplayKeyword(const char* keyword,
                        const char* displayLocale,
                        UChar* dest,
@@ -681,7 +718,7 @@
                        UErrorCode* status);
 /**
  * Gets the value of the keyword suitable for display for the specified locale.
- * E.g: for the locale string de_DE\@collation=PHONEBOOK, this API gets the display 
+ * E.g: for the locale string de_DE\@collation=PHONEBOOK, this API gets the display
  * string for PHONEBOOK, in the display locale, when "collation" is specified as the keyword.
  *
  * @param locale            The locale to get the displayable variant code with. NULL may be used to specify the default.
@@ -692,14 +729,16 @@
  *                          for inLocale would result in "Englisch". NULL may be used to specify the default.
  * @param dest              the buffer to which the displayable keyword should be written.
  * @param destCapacity      The size of the buffer (number of UChars). If it is 0, then
- *                          dest may be NULL and the function will only return the length of the 
+ *                          dest may be NULL and the function will only return the length of the
  *                          result without writing any of the result string (pre-flighting).
- * @param status            error information if retrieving the displayable string failed. 
+ * @param status            error information if retrieving the displayable string failed.
  *                          Should not be NULL and must not indicate failure on entry.
- * @return the actual buffer size needed for the displayable variant code.  
+ *                          U_USING_DEFAULT_WARNING indicates that no data was found from the locale
+ *                          resources and the value of the keyword is placed into dest as fallback.
+ * @return the actual buffer size needed for the displayable variant code.
  * @stable ICU 2.8
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 uloc_getDisplayKeywordValue(   const char* locale,
                                const char* keyword,
                                const char* displayLocale,
@@ -722,7 +761,7 @@
  * than maxResultSize, the returned displayable name will be truncated.  
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 uloc_getDisplayName(const char* localeID,
             const char* inLocaleID,
             UChar* result,
@@ -731,16 +770,22 @@
 
 
 /**
- * Gets the specified locale from a list of all available locales.  
- * The return value is a pointer to an item of 
- * a locale name array.  Both this array and the pointers
- * it contains are owned by ICU and should not be deleted or written through
- * by the caller.  The locale name is terminated by a null pointer.
- * @param n the specific locale name index of the available locale list
+ * Gets the specified locale from a list of available locales.
+ *
+ * This method corresponds to uloc_openAvailableByType called with the
+ * ULOC_AVAILABLE_DEFAULT type argument.
+ *
+ * The return value is a pointer to an item of a locale name array. Both this
+ * array and the pointers it contains are owned by ICU and should not be
+ * deleted or written through by the caller. The locale name is terminated by
+ * a null pointer.
+ *
+ * @param n the specific locale name index of the available locale list;
+ *     should not exceed the number returned by uloc_countAvailable.
  * @return a specified locale name of all available locales
  * @stable ICU 2.0
  */
-U_STABLE const char* U_EXPORT2
+U_CAPI const char* U_EXPORT2
 uloc_getAvailable(int32_t n);
 
 /**
@@ -749,7 +794,69 @@
  * @return the size of the locale list
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2 uloc_countAvailable(void);
+U_CAPI int32_t U_EXPORT2 uloc_countAvailable(void);
+
+/**
+ * Types for uloc_getAvailableByType and uloc_countAvailableByType.
+ *
+ * @stable ICU 65
+ */
+typedef enum ULocAvailableType {
+  /**
+   * Locales that return data when passed to ICU APIs,
+   * but not including legacy or alias locales.
+   *
+   * @stable ICU 65
+   */
+  ULOC_AVAILABLE_DEFAULT,
+
+  /**
+   * Legacy or alias locales that return data when passed to ICU APIs.
+   * Examples of supported legacy or alias locales:
+   *
+   * - iw (alias to he)
+   * - mo (alias to ro)
+   * - zh_CN (alias to zh_Hans_CN)
+   * - sr_BA (alias to sr_Cyrl_BA)
+   * - ars (alias to ar_SA)
+   *
+   * The locales in this set are disjoint from the ones in
+   * ULOC_AVAILABLE_DEFAULT. To get both sets at the same time, use
+   * ULOC_AVAILABLE_WITH_LEGACY_ALIASES.
+   *
+   * @stable ICU 65
+   */
+  ULOC_AVAILABLE_ONLY_LEGACY_ALIASES,
+
+  /**
+   * The union of the locales in ULOC_AVAILABLE_DEFAULT and
+   * ULOC_AVAILABLE_ONLY_LEGACY_ALIAS.
+   *
+   * @stable ICU 65
+   */
+  ULOC_AVAILABLE_WITH_LEGACY_ALIASES,
+
+#ifndef U_HIDE_INTERNAL_API
+  /**
+   * @internal
+   */
+  ULOC_AVAILABLE_COUNT
+#endif
+} ULocAvailableType;
+
+/**
+ * Gets a list of available locales according to the type argument, allowing
+ * the user to access different sets of supported locales in ICU.
+ *
+ * The returned UEnumeration must be closed by the caller.
+ *
+ * @param type Type choice from ULocAvailableType.
+ * @param status Set if an error occurred.
+ * @return a UEnumeration owned by the caller, or nullptr on failure.
+ * @stable ICU 65
+ */
+U_CAPI UEnumeration* U_EXPORT2
+uloc_openAvailableByType(ULocAvailableType type, UErrorCode* status);
 
 /**
  *
@@ -762,7 +869,7 @@
  * @return a list of all available language codes
  * @stable ICU 2.0
  */
-U_STABLE const char* const* U_EXPORT2
+U_CAPI const char* const* U_EXPORT2
 uloc_getISOLanguages(void);
 
 /**
@@ -774,7 +881,7 @@
  * @return a list of all available country codes
  * @stable ICU 2.0
  */
-U_STABLE const char* const* U_EXPORT2
+U_CAPI const char* const* U_EXPORT2
 uloc_getISOCountries(void);
 
 /**
@@ -790,7 +897,7 @@
  * @return The length of the parent locale ID.
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 uloc_getParent(const char*    localeID,
                  char* parent,
                  int32_t parentCapacity,
@@ -821,7 +928,7 @@
  * than nameCapacity, the returned full name will be truncated.  
  * @stable ICU 2.8
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 uloc_getBaseName(const char*    localeID,
          char* name,
          int32_t nameCapacity,
@@ -836,7 +943,7 @@
  * @return enumeration of keywords or NULL if there are no keywords.
  * @stable ICU 2.8
  */
-U_STABLE UEnumeration* U_EXPORT2
+U_CAPI UEnumeration* U_EXPORT2
 uloc_openKeywords(const char* localeID,
                         UErrorCode* status);
 
@@ -844,14 +951,16 @@
  * Get the value for a keyword. Locale name does not need to be normalized.
  * 
  * @param localeID locale name containing the keyword ("de_DE@currency=EURO;collation=PHONEBOOK")
- * @param keywordName name of the keyword for which we want the value. Case insensitive.
+ * @param keywordName name of the keyword for which we want the value; must not be
+ *  NULL or empty, and must consist only of [A-Za-z0-9]. Case insensitive.
  * @param buffer receiving buffer
  * @param bufferCapacity capacity of receiving buffer
- * @param status containing error code - buffer not big enough.
+ * @param status containing error code: e.g. buffer not big enough or ill-formed localeID
+ *  or keywordName parameters.
  * @return the length of keyword value
  * @stable ICU 2.8
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 uloc_getKeywordValue(const char* localeID,
                      const char* keywordName,
                      char* buffer, int32_t bufferCapacity,
@@ -864,23 +973,31 @@
  * For removing all keywords, use uloc_getBaseName().
  *
  * NOTE: Unlike almost every other ICU function which takes a
- * buffer, this function will NOT truncate the output text. If a
- * BUFFER_OVERFLOW_ERROR is received, it means that the original
- * buffer is untouched. This is done to prevent incorrect or possibly
- * even malformed locales from being generated and used.
+ * buffer, this function will NOT truncate the output text, and will
+ * not update the buffer with unterminated text setting a status of
+ * U_STRING_NOT_TERMINATED_WARNING. If a BUFFER_OVERFLOW_ERROR is received,
+ * it means a terminated version of the updated locale ID would not fit
+ * in the buffer, and the original buffer is untouched. This is done to
+ * prevent incorrect or possibly even malformed locales from being generated
+ * and used.
  *
- * @param keywordName name of the keyword to be set. Case insensitive.
+ * @param keywordName name of the keyword to be set; must not be
+ *  NULL or empty, and must consist only of [A-Za-z0-9]. Case insensitive.
  * @param keywordValue value of the keyword to be set. If 0-length or
- *  NULL, will result in the keyword being removed. No error is given if 
- *  that keyword does not exist.
- * @param buffer input buffer containing locale to be modified.
+ *  NULL, will result in the keyword being removed; no error is given if 
+ *  that keyword does not exist. Otherwise, must consist only of
+ *  [A-Za-z0-9] and [/_+-].
+ * @param buffer input buffer containing well-formed locale ID to be
+ *  modified.
  * @param bufferCapacity capacity of receiving buffer
- * @param status containing error code - buffer not big enough.
+ * @param status containing error code: e.g. buffer not big enough
+ *  or ill-formed keywordName or keywordValue parameters, or ill-formed
+ *  locale ID in buffer on input.
  * @return the length needed for the buffer
  * @see uloc_getKeywordValue
  * @stable ICU 3.2
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 uloc_setKeywordValue(const char* keywordName,
                      const char* keywordValue,
                      char* buffer, int32_t bufferCapacity,
@@ -889,18 +1006,18 @@
 /**
  * Returns whether the locale's script is written right-to-left.
  * If there is no script subtag, then the likely script is used, see uloc_addLikelySubtags().
- * If no likely script is known, then FALSE is returned.
+ * If no likely script is known, then false is returned.
  *
  * A script is right-to-left according to the CLDR script metadata
  * which corresponds to whether the script's letters have Bidi_Class=R or AL.
  *
- * Returns TRUE for "ar" and "en-Hebr", FALSE for "zh" and "fa-Cyrl".
+ * Returns true for "ar" and "en-Hebr", false for "zh" and "fa-Cyrl".
  *
  * @param locale input locale ID
- * @return TRUE if the locale's script is written right-to-left
+ * @return true if the locale's script is written right-to-left
  * @stable ICU 54
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 uloc_isRightToLeft(const char *locale);
 
 /**
@@ -924,7 +1041,7 @@
  * @return an enum indicating the layout orientation for characters.
  * @stable ICU 4.0
  */
-U_STABLE ULayoutType U_EXPORT2
+U_CAPI ULayoutType U_EXPORT2
 uloc_getCharacterOrientation(const char* localeId,
                              UErrorCode *status);
 
@@ -936,38 +1053,54 @@
  * @return an enum indicating the layout orientation for lines.
  * @stable ICU 4.0
  */
-U_STABLE ULayoutType U_EXPORT2
+U_CAPI ULayoutType U_EXPORT2
 uloc_getLineOrientation(const char* localeId,
                         UErrorCode *status);
 
 /**
- * enums for the 'outResult' parameter return value
+ * Output values which uloc_acceptLanguage() writes to the 'outResult' parameter.
+ *
  * @see uloc_acceptLanguageFromHTTP
  * @see uloc_acceptLanguage
  * @stable ICU 3.2
  */
 typedef enum {
-  ULOC_ACCEPT_FAILED   = 0,  /* No exact match was found. */
-  ULOC_ACCEPT_VALID    = 1,  /* An exact match was found. */
-  ULOC_ACCEPT_FALLBACK = 2   /* A fallback was found, for example, 
-                                Accept list contained 'ja_JP'
-                                which matched available locale 'ja'. */
+    /**
+     * No exact match was found.
+     * @stable ICU 3.2
+     */
+    ULOC_ACCEPT_FAILED   = 0,
+    /**
+     * An exact match was found.
+     * @stable ICU 3.2
+     */
+    ULOC_ACCEPT_VALID    = 1,
+    /**
+     * A fallback was found. For example, the Accept-Language list includes 'ja_JP'
+     * and is matched with available locale 'ja'.
+     * @stable ICU 3.2
+     */
+    ULOC_ACCEPT_FALLBACK = 2   /*  */
 } UAcceptResult;
 
-
 /**
  * Based on a HTTP header from a web browser and a list of available locales,
  * determine an acceptable locale for the user.
+ *
+ * This is a thin wrapper over C++ class LocaleMatcher.
+ *
  * @param result - buffer to accept the result locale
  * @param resultAvailable the size of the result buffer.
  * @param outResult - An out parameter that contains the fallback status
  * @param httpAcceptLanguage - "Accept-Language:" header as per HTTP.
  * @param availableLocales - list of available locales to match
- * @param status Error status, may be BUFFER_OVERFLOW_ERROR
+ * @param status ICU error code. Its input value must pass the U_SUCCESS() test,
+ *               or else the function returns immediately. Check for U_FAILURE()
+ *               on output or use with function chaining. (See User Guide for details.)
  * @return length needed for the locale.
  * @stable ICU 3.2
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 uloc_acceptLanguageFromHTTP(char *result, int32_t resultAvailable,
                             UAcceptResult *outResult,
                             const char *httpAcceptLanguage,
@@ -977,17 +1110,22 @@
 /**
  * Based on a list of available locales,
  * determine an acceptable locale for the user.
+ *
+ * This is a thin wrapper over C++ class LocaleMatcher.
+ *
  * @param result - buffer to accept the result locale
  * @param resultAvailable the size of the result buffer.
  * @param outResult - An out parameter that contains the fallback status
  * @param acceptList - list of acceptable languages
  * @param acceptListCount - count of acceptList items
  * @param availableLocales - list of available locales to match
- * @param status Error status, may be BUFFER_OVERFLOW_ERROR
+ * @param status ICU error code. Its input value must pass the U_SUCCESS() test,
+ *               or else the function returns immediately. Check for U_FAILURE()
+ *               on output or use with function chaining. (See User Guide for details.)
  * @return length needed for the locale.
  * @stable ICU 3.2
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 uloc_acceptLanguage(char *result, int32_t resultAvailable, 
                     UAcceptResult *outResult, const char **acceptList,
                     int32_t acceptListCount,
@@ -1007,7 +1145,7 @@
  * @return actual the actual size of the locale ID, not including NUL-termination 
  * @stable ICU 3.8
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 uloc_getLocaleForLCID(uint32_t hostID, char *locale, int32_t localeCapacity,
                     UErrorCode *status);
 
@@ -1045,7 +1183,7 @@
  * On error, the return value is -1.
  * @stable ICU 4.0
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 uloc_addLikelySubtags(const char*    localeID,
          char* maximizedLocaleID,
          int32_t maximizedLocaleIDCapacity,
@@ -1085,7 +1223,7 @@
  * On error, the return value is -1.
  * @stable ICU 4.0
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 uloc_minimizeSubtags(const char*    localeID,
          char* minimizedLocaleID,
          int32_t minimizedLocaleIDCapacity,
@@ -1095,14 +1233,18 @@
  * Returns a locale ID for the specified BCP47 language tag string.
  * If the specified language tag contains any ill-formed subtags,
  * the first such subtag and all following subtags are ignored.
- * <p> 
- * This implements the 'Language-Tag' production of BCP47, and so
- * supports grandfathered (regular and irregular) as well as private
- * use language tags.  Private use tags are represented as 'x-whatever',
- * and grandfathered tags are converted to their canonical replacements
- * where they exist.  Note that a few grandfathered tags have no modern
- * replacement, these will be converted using the fallback described in
+ * <p>
+ * This implements the 'Language-Tag' production of BCP 47, and so
+ * supports legacy language tags (marked as “Type: grandfathered” in BCP 47)
+ * (regular and irregular) as well as private use language tags.
+ *
+ * Private use tags are represented as 'x-whatever',
+ * and legacy tags are converted to their canonical replacements where they exist.
+ *
+ * Note that a few legacy tags have no modern replacement;
+ * these will be converted using the fallback described in
  * the first paragraph, so some information might be lost.
+ *
  * @param langtag   the input BCP47 language tag.
  * @param localeID  the output buffer receiving a locale ID for the
  *                  specified BCP47 language tag.
@@ -1114,7 +1256,7 @@
  * @return          the length of the locale ID.
  * @stable ICU 4.2
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 uloc_forLanguageTag(const char* langtag,
                     char* localeID,
                     int32_t localeIDCapacity,
@@ -1124,10 +1266,10 @@
 /**
  * Returns a well-formed language tag for this locale ID. 
  * <p> 
- * <b>Note</b>: When <code>strict</code> is FALSE, any locale
+ * <b>Note</b>: When <code>strict</code> is false, any locale
  * fields which do not satisfy the BCP47 syntax requirement will
  * be omitted from the result.  When <code>strict</code> is
- * TRUE, this function sets U_ILLEGAL_ARGUMENT_ERROR to the
+ * true, this function sets U_ILLEGAL_ARGUMENT_ERROR to the
  * <code>err</code> if any locale fields do not satisfy the
  * BCP47 syntax requirement.
  * @param localeID  the input locale ID
@@ -1142,7 +1284,7 @@
  * @return          The length of the BCP47 language tag.
  * @stable ICU 4.2
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 uloc_toLanguageTag(const char* localeID,
                    char* langtag,
                    int32_t langtagCapacity,
@@ -1170,7 +1312,7 @@
  * @see uloc_toLegacyKey
  * @stable ICU 54
  */
-U_STABLE const char* U_EXPORT2
+U_CAPI const char* U_EXPORT2
 uloc_toUnicodeLocaleKey(const char* keyword);
 
 /**
@@ -1201,7 +1343,7 @@
  * @see uloc_toLegacyType
  * @stable ICU 54
  */
-U_STABLE const char* U_EXPORT2
+U_CAPI const char* U_EXPORT2
 uloc_toUnicodeLocaleType(const char* keyword, const char* value);
 
 /**
@@ -1216,7 +1358,7 @@
  * @see toUnicodeLocaleKey
  * @stable ICU 54
  */
-U_STABLE const char* U_EXPORT2
+U_CAPI const char* U_EXPORT2
 uloc_toLegacyKey(const char* keyword);
 
 /**
@@ -1245,7 +1387,7 @@
  * @see toUnicodeLocaleType
  * @stable ICU 54
  */
-U_STABLE const char* U_EXPORT2
+U_CAPI const char* U_EXPORT2
 uloc_toLegacyType(const char* keyword, const char* value);
 
 #endif /*_ULOC*/
diff --git a/src/third_party/icu/source/common/unicode/umachine.h b/src/third_party/icu/source/common/unicode/umachine.h
index 1b7ea61..7e09828 100644
--- a/src/third_party/icu/source/common/unicode/umachine.h
+++ b/src/third_party/icu/source/common/unicode/umachine.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 ******************************************************************************
 *   file name:  umachine.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -47,14 +49,15 @@
  * ANSI C headers:
  * stddef.h defines wchar_t
  */
+#include <stdbool.h>
 #if !defined(STARBOARD)
 #include <stddef.h>
 #endif
 
 /*==========================================================================*/
-/* For C wrappers, we use the symbol U_STABLE.                                */
+/* For C wrappers, we use the symbol U_CAPI.                                */
 /* This works properly if the includer is C or C++.                         */
-/* Functions are declared   U_STABLE return-type U_EXPORT2 function-name()... */
+/* Functions are declared   U_CAPI return-type U_EXPORT2 function-name()... */
 /*==========================================================================*/
 
 /**
@@ -107,15 +110,15 @@
 
 /** This is used to declare a function as a public ICU C API @stable ICU 2.0*/
 #define U_CAPI U_CFUNC U_EXPORT
-/** This is used to declare a function as a stable public ICU C API*/
+/** Obsolete/same as U_CAPI; was used to declare a function as a stable public ICU C API*/
 #define U_STABLE U_CAPI
-/** This is used to declare a function as a draft public ICU C API  */
+/** Obsolete/same as U_CAPI; was used to declare a function as a draft public ICU C API  */
 #define U_DRAFT  U_CAPI
 /** This is used to declare a function as a deprecated public ICU C API  */
 #define U_DEPRECATED U_CAPI U_ATTRIBUTE_DEPRECATED
-/** This is used to declare a function as an obsolete public ICU C API  */
+/** Obsolete/same as U_CAPI; was used to declare a function as an obsolete public ICU C API  */
 #define U_OBSOLETE U_CAPI
-/** This is used to declare a function as an internal ICU C API  */
+/** Obsolete/same as U_CAPI; was used to declare a function as an internal ICU C API  */
 #define U_INTERNAL U_CAPI
 
 /**
@@ -125,6 +128,9 @@
  * May result in an error if it applied to something not an override.
  * @internal
  */
+#ifndef U_OVERRIDE
+#define U_OVERRIDE override
+#endif
 
 /**
  * \def U_FINAL
@@ -133,23 +139,45 @@
  * May result in an error if subclasses attempt to override.
  * @internal
  */
-
-#if U_CPLUSPLUS_VERSION >= 11
-/* C++11 */
-#ifndef U_OVERRIDE
-#define U_OVERRIDE override
-#endif
-#ifndef U_FINAL
+#if !defined(U_FINAL) || defined(U_IN_DOXYGEN)
 #define U_FINAL final
 #endif
-#else
-/* not C++11 - define to nothing */
-#ifndef U_OVERRIDE
-#define U_OVERRIDE
+
+// Before ICU 65, function-like, multi-statement ICU macros were just defined as
+// series of statements wrapped in { } blocks and the caller could choose to
+// either treat them as if they were actual functions and end the invocation
+// with a trailing ; creating an empty statement after the block or else omit
+// this trailing ; using the knowledge that the macro would expand to { }.
+//
+// But doing so doesn't work well with macros that look like functions and
+// compiler warnings about empty statements (ICU-20601) and ICU 65 therefore
+// switches to the standard solution of wrapping such macros in do { } while.
+//
+// This will however break existing code that depends on being able to invoke
+// these macros without a trailing ; so to be able to remain compatible with
+// such code the wrapper is itself defined as macros so that it's possible to
+// build ICU 65 and later with the old macro behaviour, like this:
+//
+// export CPPFLAGS='-DUPRV_BLOCK_MACRO_BEGIN="" -DUPRV_BLOCK_MACRO_END=""'
+// runConfigureICU ...
+//
+
+/**
+ * \def UPRV_BLOCK_MACRO_BEGIN
+ * Defined as the "do" keyword by default.
+ * @internal
+ */
+#ifndef UPRV_BLOCK_MACRO_BEGIN
+#define UPRV_BLOCK_MACRO_BEGIN do
 #endif
-#ifndef U_FINAL
-#define U_FINAL
-#endif
+
+/**
+ * \def UPRV_BLOCK_MACRO_END
+ * Defined as "while (false)" by default.
+ * @internal
+ */
+#ifndef UPRV_BLOCK_MACRO_END
+#define UPRV_BLOCK_MACRO_END while (false)
 #endif
 
 /*==========================================================================*/
@@ -232,18 +260,59 @@
 /* Boolean data type                                                        */
 /*==========================================================================*/
 
-/** The ICU boolean type @stable ICU 2.0 */
+/**
+ * The ICU boolean type, a signed-byte integer.
+ * ICU-specific for historical reasons: The C and C++ standards used to not define type bool.
+ * Also provides a fixed type definition, as opposed to
+ * type bool whose details (e.g., sizeof) may vary by compiler and between C and C++.
+ *
+ * @stable ICU 2.0
+ */
 typedef int8_t UBool;
 
+/**
+ * \def U_DEFINE_FALSE_AND_TRUE
+ * Normally turns off defining macros FALSE=0 & TRUE=1 in public ICU headers.
+ * These obsolete macros sometimes break compilation of other code that
+ * defines enum constants or similar with these names.
+ * C++ has long defined bool/false/true.
+ * C99 also added definitions for these, although as macros; see stdbool.h.
+ *
+ * You may transitionally define U_DEFINE_FALSE_AND_TRUE=1 if you need time to migrate code.
+ *
+ * @internal ICU 68
+ */
+#ifdef U_DEFINE_FALSE_AND_TRUE
+    // Use the predefined value.
+#elif defined(U_COMBINED_IMPLEMENTATION) || \
+        defined(U_COMMON_IMPLEMENTATION) || defined(U_I18N_IMPLEMENTATION) || \
+        defined(U_IO_IMPLEMENTATION) || defined(U_LAYOUTEX_IMPLEMENTATION) || \
+        defined(U_TOOLUTIL_IMPLEMENTATION)
+    // Inside ICU: Keep FALSE & TRUE available.
+#   define U_DEFINE_FALSE_AND_TRUE 1
+#else
+    // Outside ICU: Avoid collision with non-macro definitions of FALSE & TRUE.
+#   define U_DEFINE_FALSE_AND_TRUE 0
+#endif
+
+#if U_DEFINE_FALSE_AND_TRUE || defined(U_IN_DOXYGEN)
 #ifndef TRUE
-/** The TRUE value of a UBool @stable ICU 2.0 */
+/**
+ * The TRUE value of a UBool.
+ *
+ * @deprecated ICU 68 Use standard "true" instead.
+ */
 #   define TRUE  1
 #endif
 #ifndef FALSE
-/** The FALSE value of a UBool @stable ICU 2.0 */
+/**
+ * The FALSE value of a UBool.
+ *
+ * @deprecated ICU 68 Use standard "false" instead.
+ */
 #   define FALSE 0
 #endif
-
+#endif  // U_DEFINE_FALSE_AND_TRUE
 
 /*==========================================================================*/
 /* Unicode data types                                                       */
@@ -291,30 +360,100 @@
 #define U_SIZEOF_UCHAR 2
 
 /**
+ * \def U_CHAR16_IS_TYPEDEF
+ * If 1, then char16_t is a typedef and not a real type (yet)
+ * @internal
+ */
+#if (U_PLATFORM == U_PF_AIX) && defined(__cplusplus) &&(U_CPLUSPLUS_VERSION < 11)
+// for AIX, uchar.h needs to be included
+# include <uchar.h>
+# define U_CHAR16_IS_TYPEDEF 1
+#elif defined(_MSC_VER) && (_MSC_VER < 1900)
+// Versions of Visual Studio/MSVC below 2015 do not support char16_t as a real type,
+// and instead use a typedef.  https://msdn.microsoft.com/library/bb531344.aspx
+# define U_CHAR16_IS_TYPEDEF 1
+#else
+# define U_CHAR16_IS_TYPEDEF 0
+#endif
+
+
+/**
  * \var UChar
- * Define UChar to be UCHAR_TYPE, if that is #defined (for example, to char16_t),
- * or wchar_t if that is 16 bits wide; always assumed to be unsigned.
- * If neither is available, then define UChar to be uint16_t.
  *
- * This makes the definition of UChar platform-dependent
- * but allows direct string type compatibility with platforms with
- * 16-bit wchar_t types.
+ * The base type for UTF-16 code units and pointers.
+ * Unsigned 16-bit integer.
+ * Starting with ICU 59, C++ API uses char16_t directly, while C API continues to use UChar.
+ *
+ * UChar is configurable by defining the macro UCHAR_TYPE
+ * on the preprocessor or compiler command line:
+ * -DUCHAR_TYPE=uint16_t or -DUCHAR_TYPE=wchar_t (if U_SIZEOF_WCHAR_T==2) etc.
+ * (The UCHAR_TYPE can also be \#defined earlier in this file, for outside the ICU library code.)
+ * This is for transitional use from application code that uses uint16_t or wchar_t for UTF-16.
+ *
+ * The default is UChar=char16_t.
+ *
+ * C++11 defines char16_t as bit-compatible with uint16_t, but as a distinct type.
+ *
+ * In C, char16_t is a simple typedef of uint_least16_t.
+ * ICU requires uint_least16_t=uint16_t for data memory mapping.
+ * On macOS, char16_t is not available because the uchar.h standard header is missing.
  *
  * @stable ICU 4.4
  */
-#if defined(UCHAR_TYPE)
-    typedef UCHAR_TYPE UChar;
-/* Not #elif U_HAVE_CHAR16_T -- because that is type-incompatible with pre-C++11 callers
-    typedef char16_t UChar;  */
-#elif U_SIZEOF_WCHAR_T==2
+
+#if 1
+    // #if 1 is normal. UChar defaults to char16_t in C++.
+    // For configuration testing of UChar=uint16_t temporarily change this to #if 0.
+    // The intltest Makefile #defines UCHAR_TYPE=char16_t,
+    // so we only #define it to uint16_t if it is undefined so far.
+#elif !defined(UCHAR_TYPE)
+#   define UCHAR_TYPE uint16_t
+#endif
+
+#if defined(U_COMBINED_IMPLEMENTATION) || defined(U_COMMON_IMPLEMENTATION) || \
+        defined(U_I18N_IMPLEMENTATION) || defined(U_IO_IMPLEMENTATION)
+    // Inside the ICU library code, never configurable.
+    typedef char16_t UChar;
+#elif defined(STARBOARD) && U_SIZEOF_WCHAR_T==2
     typedef wchar_t UChar;
-#elif defined(__CHAR16_TYPE__)
-    typedef __CHAR16_TYPE__ UChar;
+#elif defined(STARBOARD) && U_SIZEOF_WCHAR_T==4
+    typedef uint16_t UChar;
+#elif defined(UCHAR_TYPE)
+    typedef UCHAR_TYPE UChar;
+#elif (U_CPLUSPLUS_VERSION >= 11)
+    typedef char16_t UChar;
 #else
     typedef uint16_t UChar;
 #endif
 
 /**
+ * \var OldUChar
+ * Default ICU 58 definition of UChar.
+ * A base type for UTF-16 code units and pointers.
+ * Unsigned 16-bit integer.
+ *
+ * Define OldUChar to be wchar_t if that is 16 bits wide.
+ * If wchar_t is not 16 bits wide, then define UChar to be uint16_t.
+ *
+ * This makes the definition of OldUChar platform-dependent
+ * but allows direct string type compatibility with platforms with
+ * 16-bit wchar_t types.
+ *
+ * This is how UChar was defined in ICU 58, for transition convenience.
+ * Exception: ICU 58 UChar was defined to UCHAR_TYPE if that macro was defined.
+ * The current UChar responds to UCHAR_TYPE but OldUChar does not.
+ *
+ * @stable ICU 59
+ */
+#if U_SIZEOF_WCHAR_T==2
+    typedef wchar_t OldUChar;
+#elif defined(__CHAR16_TYPE__)
+    typedef __CHAR16_TYPE__ OldUChar;
+#else
+    typedef uint16_t OldUChar;
+#endif
+
+/**
  * Define UChar32 as a type for single Unicode code points.
  * UChar32 is a signed 32-bit integer (same as int32_t).
  *
diff --git a/src/third_party/icu/source/common/unicode/umisc.h b/src/third_party/icu/source/common/unicode/umisc.h
index d85451f..213290b 100644
--- a/src/third_party/icu/source/common/unicode/umisc.h
+++ b/src/third_party/icu/source/common/unicode/umisc.h
@@ -1,10 +1,12 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
 *   Copyright (C) 1999-2006, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 **********************************************************************
 *   file name:  umisc.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
diff --git a/src/third_party/icu/source/common/unicode/umutablecptrie.h b/src/third_party/icu/source/common/unicode/umutablecptrie.h
new file mode 100644
index 0000000..5325d58
--- /dev/null
+++ b/src/third_party/icu/source/common/unicode/umutablecptrie.h
@@ -0,0 +1,241 @@
+// © 2017 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+// umutablecptrie.h (split out of ucptrie.h)
+// created: 2018jan24 Markus W. Scherer
+
+#ifndef __UMUTABLECPTRIE_H__
+#define __UMUTABLECPTRIE_H__
+
+#include "unicode/utypes.h"
+
+#include "unicode/ucpmap.h"
+#include "unicode/ucptrie.h"
+#include "unicode/utf8.h"
+
+#if U_SHOW_CPLUSPLUS_API
+#include "unicode/localpointer.h"
+#endif   // U_SHOW_CPLUSPLUS_API
+
+U_CDECL_BEGIN
+
+/**
+ * \file
+ *
+ * This file defines a mutable Unicode code point trie.
+ *
+ * @see UCPTrie
+ * @see UMutableCPTrie
+ */
+
+/**
+ * Mutable Unicode code point trie.
+ * Fast map from Unicode code points (U+0000..U+10FFFF) to 32-bit integer values.
+ * For details see http://site.icu-project.org/design/struct/utrie
+ *
+ * Setting values (especially ranges) and lookup is fast.
+ * The mutable trie is only somewhat space-efficient.
+ * It builds a compacted, immutable UCPTrie.
+ *
+ * This trie can be modified while iterating over its contents.
+ * For example, it is possible to merge its values with those from another
+ * set of ranges (e.g., another mutable or immutable trie):
+ * Iterate over those source ranges; for each of them iterate over this trie;
+ * add the source value into the value of each trie range.
+ *
+ * @see UCPTrie
+ * @see umutablecptrie_buildImmutable
+ * @stable ICU 63
+ */
+typedef struct UMutableCPTrie UMutableCPTrie;
+
+/**
+ * Creates a mutable trie that initially maps each Unicode code point to the same value.
+ * It uses 32-bit data values until umutablecptrie_buildImmutable() is called.
+ * umutablecptrie_buildImmutable() takes a valueWidth parameter which
+ * determines the number of bits in the data value in the resulting UCPTrie.
+ * You must umutablecptrie_close() the trie once you are done using it.
+ *
+ * @param initialValue the initial value that is set for all code points
+ * @param errorValue the value for out-of-range code points and ill-formed UTF-8/16
+ * @param pErrorCode an in/out ICU UErrorCode
+ * @return the trie
+ * @stable ICU 63
+ */
+U_CAPI UMutableCPTrie * U_EXPORT2
+umutablecptrie_open(uint32_t initialValue, uint32_t errorValue, UErrorCode *pErrorCode);
+
+/**
+ * Clones a mutable trie.
+ * You must umutablecptrie_close() the clone once you are done using it.
+ *
+ * @param other the trie to clone
+ * @param pErrorCode an in/out ICU UErrorCode
+ * @return the trie clone
+ * @stable ICU 63
+ */
+U_CAPI UMutableCPTrie * U_EXPORT2
+umutablecptrie_clone(const UMutableCPTrie *other, UErrorCode *pErrorCode);
+
+/**
+ * Closes a mutable trie and releases associated memory.
+ *
+ * @param trie the trie
+ * @stable ICU 63
+ */
+U_CAPI void U_EXPORT2
+umutablecptrie_close(UMutableCPTrie *trie);
+
+/**
+ * Creates a mutable trie with the same contents as the UCPMap.
+ * You must umutablecptrie_close() the mutable trie once you are done using it.
+ *
+ * @param map the source map
+ * @param pErrorCode an in/out ICU UErrorCode
+ * @return the mutable trie
+ * @stable ICU 63
+ */
+U_CAPI UMutableCPTrie * U_EXPORT2
+umutablecptrie_fromUCPMap(const UCPMap *map, UErrorCode *pErrorCode);
+
+/**
+ * Creates a mutable trie with the same contents as the immutable one.
+ * You must umutablecptrie_close() the mutable trie once you are done using it.
+ *
+ * @param trie the immutable trie
+ * @param pErrorCode an in/out ICU UErrorCode
+ * @return the mutable trie
+ * @stable ICU 63
+ */
+U_CAPI UMutableCPTrie * U_EXPORT2
+umutablecptrie_fromUCPTrie(const UCPTrie *trie, UErrorCode *pErrorCode);
+
+/**
+ * Returns the value for a code point as stored in the trie.
+ *
+ * @param trie the trie
+ * @param c the code point
+ * @return the value
+ * @stable ICU 63
+ */
+U_CAPI uint32_t U_EXPORT2
+umutablecptrie_get(const UMutableCPTrie *trie, UChar32 c);
+
+/**
+ * Returns the last code point such that all those from start to there have the same value.
+ * Can be used to efficiently iterate over all same-value ranges in a trie.
+ * (This is normally faster than iterating over code points and get()ting each value,
+ * but much slower than a data structure that stores ranges directly.)
+ *
+ * The trie can be modified between calls to this function.
+ *
+ * If the UCPMapValueFilter function pointer is not NULL, then
+ * the value to be delivered is passed through that function, and the return value is the end
+ * of the range where all values are modified to the same actual value.
+ * The value is unchanged if that function pointer is NULL.
+ *
+ * See the same-signature ucptrie_getRange() for a code sample.
+ *
+ * @param trie the trie
+ * @param start range start
+ * @param option defines whether surrogates are treated normally,
+ *               or as having the surrogateValue; usually UCPMAP_RANGE_NORMAL
+ * @param surrogateValue value for surrogates; ignored if option==UCPMAP_RANGE_NORMAL
+ * @param filter a pointer to a function that may modify the trie data value,
+ *     or NULL if the values from the trie are to be used unmodified
+ * @param context an opaque pointer that is passed on to the filter function
+ * @param pValue if not NULL, receives the value that every code point start..end has;
+ *     may have been modified by filter(context, trie value)
+ *     if that function pointer is not NULL
+ * @return the range end code point, or -1 if start is not a valid code point
+ * @stable ICU 63
+ */
+U_CAPI UChar32 U_EXPORT2
+umutablecptrie_getRange(const UMutableCPTrie *trie, UChar32 start,
+                        UCPMapRangeOption option, uint32_t surrogateValue,
+                        UCPMapValueFilter *filter, const void *context, uint32_t *pValue);
+
+/**
+ * Sets a value for a code point.
+ *
+ * @param trie the trie
+ * @param c the code point
+ * @param value the value
+ * @param pErrorCode an in/out ICU UErrorCode
+ * @stable ICU 63
+ */
+U_CAPI void U_EXPORT2
+umutablecptrie_set(UMutableCPTrie *trie, UChar32 c, uint32_t value, UErrorCode *pErrorCode);
+
+/**
+ * Sets a value for each code point [start..end].
+ * Faster and more space-efficient than setting the value for each code point separately.
+ *
+ * @param trie the trie
+ * @param start the first code point to get the value
+ * @param end the last code point to get the value (inclusive)
+ * @param value the value
+ * @param pErrorCode an in/out ICU UErrorCode
+ * @stable ICU 63
+ */
+U_CAPI void U_EXPORT2
+umutablecptrie_setRange(UMutableCPTrie *trie,
+                        UChar32 start, UChar32 end,
+                        uint32_t value, UErrorCode *pErrorCode);
+
+/**
+ * Compacts the data and builds an immutable UCPTrie according to the parameters.
+ * After this, the mutable trie will be empty.
+ *
+ * The mutable trie stores 32-bit values until buildImmutable() is called.
+ * If values shorter than 32 bits are to be stored in the immutable trie,
+ * then the upper bits are discarded.
+ * For example, when the mutable trie contains values 0x81, -0x7f, and 0xa581,
+ * and the value width is 8 bits, then each of these is stored as 0x81
+ * and the immutable trie will return that as an unsigned value.
+ * (Some implementations may want to make productive temporary use of the upper bits
+ * until buildImmutable() discards them.)
+ *
+ * Not every possible set of mappings can be built into a UCPTrie,
+ * because of limitations resulting from speed and space optimizations.
+ * Every Unicode assigned character can be mapped to a unique value.
+ * Typical data yields data structures far smaller than the limitations.
+ *
+ * It is possible to construct extremely unusual mappings that exceed the data structure limits.
+ * In such a case this function will fail with a U_INDEX_OUTOFBOUNDS_ERROR.
+ *
+ * @param trie the trie trie
+ * @param type selects the trie type
+ * @param valueWidth selects the number of bits in a trie data value; if smaller than 32 bits,
+ *                   then the values stored in the trie will be truncated first
+ * @param pErrorCode an in/out ICU UErrorCode
+ *
+ * @see umutablecptrie_fromUCPTrie
+ * @stable ICU 63
+ */
+U_CAPI UCPTrie * U_EXPORT2
+umutablecptrie_buildImmutable(UMutableCPTrie *trie, UCPTrieType type, UCPTrieValueWidth valueWidth,
+                              UErrorCode *pErrorCode);
+
+U_CDECL_END
+
+#if U_SHOW_CPLUSPLUS_API
+
+U_NAMESPACE_BEGIN
+
+/**
+ * \class LocalUMutableCPTriePointer
+ * "Smart pointer" class, closes a UMutableCPTrie via umutablecptrie_close().
+ * For most methods see the LocalPointerBase base class.
+ *
+ * @see LocalPointerBase
+ * @see LocalPointer
+ * @stable ICU 63
+ */
+U_DEFINE_LOCAL_OPEN_POINTER(LocalUMutableCPTriePointer, UMutableCPTrie, umutablecptrie_close);
+
+U_NAMESPACE_END
+
+#endif
+
+#endif
diff --git a/src/third_party/icu/source/common/unicode/unifilt.h b/src/third_party/icu/source/common/unicode/unifilt.h
index ce952af..420e1a1 100644
--- a/src/third_party/icu/source/common/unicode/unifilt.h
+++ b/src/third_party/icu/source/common/unicode/unifilt.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
 * Copyright (C) 1999-2010, International Business Machines Corporation and others.
@@ -10,6 +12,10 @@
 #ifndef UNIFILT_H
 #define UNIFILT_H
 
+#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
 #include "unicode/unifunct.h"
 #include "unicode/unimatch.h"
 
@@ -28,7 +34,7 @@
  * defined range.
  * @stable ICU 3.0
  */
-#define U_ETHER ((UChar)0xFFFF)
+#define U_ETHER ((char16_t)0xFFFF)
 
 /**
  *
@@ -66,6 +72,14 @@
     virtual ~UnicodeFilter();
 
     /**
+     * Clones this object polymorphically.
+     * The caller owns the result and should delete it when done.
+     * @return clone, or nullptr if an error occurred
+     * @stable ICU 2.4
+     */
+    virtual UnicodeFilter* clone() const = 0;
+
+    /**
      * Returns <tt>true</tt> for characters that are in the selected
      * subset.  In other words, if a character is <b>to be
      * filtered</b>, then <tt>contains()</tt> returns
@@ -117,4 +131,6 @@
 
 U_NAMESPACE_END
 
+#endif /* U_SHOW_CPLUSPLUS_API */
+
 #endif
diff --git a/src/third_party/icu/source/common/unicode/unifunct.h b/src/third_party/icu/source/common/unicode/unifunct.h
index 3aa7b03..7d31af7 100644
--- a/src/third_party/icu/source/common/unicode/unifunct.h
+++ b/src/third_party/icu/source/common/unicode/unifunct.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
 *   Copyright (c) 2002-2005, International Business Machines Corporation
@@ -11,6 +13,9 @@
 #define UNIFUNCT_H
 
 #include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
 #include "unicode/uobject.h"
 
 /**
@@ -122,4 +127,6 @@
 
 U_NAMESPACE_END
 
+#endif /* U_SHOW_CPLUSPLUS_API */
+
 #endif
diff --git a/src/third_party/icu/source/common/unicode/unimatch.h b/src/third_party/icu/source/common/unicode/unimatch.h
index 0dbb14e..302332f 100644
--- a/src/third_party/icu/source/common/unicode/unimatch.h
+++ b/src/third_party/icu/source/common/unicode/unimatch.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 * Copyright (C) 2001-2005, International Business Machines Corporation and others. All Rights Reserved.
 **********************************************************************
@@ -15,6 +17,7 @@
  * \brief C++ API: Unicode Matcher
  */
 
+#if U_SHOW_CPLUSPLUS_API
 
 U_NAMESPACE_BEGIN
 
@@ -112,11 +115,11 @@
      * considered for matching will be text.charAt(limit-1) in the
      * forward direction or text.charAt(limit+1) in the backward
      * direction.
-     * @param incremental if TRUE, then assume further characters may
+     * @param incremental if true, then assume further characters may
      * be inserted at limit and check for partial matching.  Otherwise
      * assume the text as given is complete.
      * @return a match degree value indicating a full match, a partial
-     * match, or a mismatch.  If incremental is FALSE then
+     * match, or a mismatch.  If incremental is false then
      * U_PARTIAL_MATCH should never be returned.
      * @stable ICU 2.4
      */
@@ -131,17 +134,17 @@
      * will produce another matcher that is equal to this one.
      * @param result the string to receive the pattern.  Previous
      * contents will be deleted.
-     * @param escapeUnprintable if TRUE then convert unprintable
+     * @param escapeUnprintable if true then convert unprintable
      * character to their hex escape representations, \\uxxxx or
      * \\Uxxxxxxxx.  Unprintable characters are those other than
      * U+000A, U+0020..U+007E.
      * @stable ICU 2.4
      */
     virtual UnicodeString& toPattern(UnicodeString& result,
-                                     UBool escapeUnprintable = FALSE) const = 0;
+                                     UBool escapeUnprintable = false) const = 0;
 
     /**
-     * Returns TRUE if this matcher will match a character c, where c
+     * Returns true if this matcher will match a character c, where c
      * & 0xFF == v, at offset, in the forward direction (with limit >
      * offset).  This is used by <tt>RuleBasedTransliterator</tt> for
      * indexing.
@@ -160,4 +163,6 @@
 
 U_NAMESPACE_END
 
+#endif /* U_SHOW_CPLUSPLUS_API */
+
 #endif
diff --git a/src/third_party/icu/source/common/unicode/uniset.h b/src/third_party/icu/source/common/unicode/uniset.h
index 0456f2b..50b6360 100644
--- a/src/third_party/icu/source/common/unicode/uniset.h
+++ b/src/third_party/icu/source/common/unicode/uniset.h
@@ -1,6 +1,8 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ***************************************************************************
-* Copyright (C) 1999-2015, International Business Machines Corporation
+* Copyright (C) 1999-2016, International Business Machines Corporation
 * and others. All Rights Reserved.
 ***************************************************************************
 *   Date        Name        Description
@@ -11,6 +13,11 @@
 #ifndef UNICODESET_H
 #define UNICODESET_H
 
+#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
+#include "unicode/ucpmap.h"
 #include "unicode/unifilt.h"
 #include "unicode/unistr.h"
 #include "unicode/uset.h"
@@ -23,8 +30,6 @@
 U_NAMESPACE_BEGIN
 
 // Forward Declarations.
-void U_CALLCONV UnicodeSet_initInclusion(int32_t src, UErrorCode &status); /**< @internal */
-
 class BMPSet;
 class ParsePosition;
 class RBBIRuleScanner;
@@ -274,14 +279,23 @@
  * @stable ICU 2.0
  */
 class U_COMMON_API UnicodeSet U_FINAL : public UnicodeFilter {
+private:
+    /**
+     * Enough for sets with few ranges.
+     * For example, White_Space has 10 ranges, list length 21.
+     */
+    static constexpr int32_t INITIAL_CAPACITY = 25;
+    // fFlags constant
+    static constexpr uint8_t kIsBogus = 1;  // This set is bogus (i.e. not valid)
 
-    int32_t len; // length of list used; 0 <= len <= capacity
-    int32_t capacity; // capacity of list
-    UChar32* list; // MUST be terminated with HIGH
-    BMPSet *bmpSet; // The set is frozen iff either bmpSet or stringSpan is not NULL.
-    UChar32* buffer; // internal buffer, may be NULL
-    int32_t bufferCapacity; // capacity of buffer
-    int32_t patLen;
+    UChar32* list = stackList; // MUST be terminated with HIGH
+    int32_t capacity = INITIAL_CAPACITY; // capacity of list
+    int32_t len = 1; // length of list used; 1 <= len <= capacity
+    uint8_t fFlags = 0;         // Bit flag (see constants above)
+
+    BMPSet *bmpSet = nullptr; // The set is frozen iff either bmpSet or stringSpan is not NULL.
+    UChar32* buffer = nullptr; // internal buffer, may be NULL
+    int32_t bufferCapacity = 0; // capacity of buffer
 
     /**
      * The pattern representation of this set.  This may not be the
@@ -292,30 +306,34 @@
      * indicating that toPattern() must generate a pattern
      * representation from the inversion list.
      */
-    UChar *pat;
-    UVector* strings; // maintained in sorted order
-    UnicodeSetStringSpan *stringSpan;
+    char16_t *pat = nullptr;
+    int32_t patLen = 0;
 
-private:
-    enum { // constants
-        kIsBogus = 1       // This set is bogus (i.e. not valid)
-    };
-    uint8_t fFlags;         // Bit flag (see constants above)
+    UVector* strings = nullptr; // maintained in sorted order
+    UnicodeSetStringSpan *stringSpan = nullptr;
+
+    /**
+     * Initial list array.
+     * Avoids some heap allocations, and list is never nullptr.
+     * Increases the object size a bit.
+     */
+    UChar32 stackList[INITIAL_CAPACITY];
+
 public:
     /**
      * Determine if this object contains a valid set.
      * A bogus set has no value. It is different from an empty set.
      * It can be used to indicate that no set value is available.
      *
-     * @return TRUE if the set is valid, FALSE otherwise
+     * @return true if the set is bogus/invalid, false otherwise
      * @see setToBogus()
      * @stable ICU 4.0
      */
     inline UBool isBogus(void) const;
-    
+
     /**
      * Make this UnicodeSet object invalid.
-     * The string will test TRUE with isBogus().
+     * The string will test true with isBogus().
      *
      * A bogus set has no value. It is different from an empty set.
      * It can be used to indicate that no set value is available.
@@ -360,7 +378,7 @@
     UnicodeSet();
 
     /**
-     * Constructs a set containing the given range. If <code>end >
+     * Constructs a set containing the given range. If <code>end <
      * start</code> then an empty set is created.
      *
      * @param start first character, inclusive, of range
@@ -476,7 +494,7 @@
      * <tt>true</tt> if the specified set is not equal to this set.
      * @stable ICU 2.0
      */
-    UBool operator!=(const UnicodeSet& o) const;
+    inline UBool operator!=(const UnicodeSet& o) const;
 
     /**
      * Returns a copy of this object.  All UnicodeFunctor objects have
@@ -487,7 +505,7 @@
      * @see cloneAsThawed
      * @stable ICU 2.0
      */
-    virtual UnicodeFunctor* clone() const;
+    virtual UnicodeSet* clone() const;
 
     /**
      * Returns the hash code value for this set.
@@ -545,7 +563,7 @@
     /**
      * Determines whether the set has been frozen (made immutable) or not.
      * See the ICU4J Freezable interface for details.
-     * @return TRUE/FALSE for whether the set has been frozen
+     * @return true/false for whether the set has been frozen
      * @see freeze
      * @see cloneAsThawed
      * @stable ICU 3.8
@@ -565,7 +583,7 @@
      * @see cloneAsThawed
      * @stable ICU 3.8
      */
-    UnicodeFunctor *freeze();
+    UnicodeSet *freeze();
 
     /**
      * Clone the set and make the clone mutable.
@@ -575,16 +593,15 @@
      * @see isFrozen
      * @stable ICU 3.8
      */
-    UnicodeFunctor *cloneAsThawed() const;
+    UnicodeSet *cloneAsThawed() const;
 
     //----------------------------------------------------------------
     // Public API
     //----------------------------------------------------------------
 
     /**
-     * Make this object represent the range <code>start - end</code>.
-     * If <code>end > start</code> then this object is set to an
-     * an empty range.
+     * Make this object represent the range `start - end`.
+     * If `end > start` then this object is set to an empty range.
      * A frozen set will not be modified.
      *
      * @param start first character in the set, inclusive
@@ -683,14 +700,14 @@
      * A frozen set will not be modified.
      * @param result the string to receive the rules.  Previous
      * contents will be deleted.
-     * @param escapeUnprintable if TRUE then convert unprintable
+     * @param escapeUnprintable if true then convert unprintable
      * character to their hex escape representations, \\uxxxx or
      * \\Uxxxxxxxx.  Unprintable characters are those other than
      * U+000A, U+0020..U+007E.
      * @stable ICU 2.0
      */
     virtual UnicodeString& toPattern(UnicodeString& result,
-                             UBool escapeUnprintable = FALSE) const;
+                                     UBool escapeUnprintable = false) const;
 
     /**
      * Modifies this set to contain those code points which have the given value
@@ -889,7 +906,7 @@
      * @stable ICU 3.8
      * @see USetSpanCondition
      */
-    int32_t span(const UChar *s, int32_t length, USetSpanCondition spanCondition) const;
+    int32_t span(const char16_t *s, int32_t length, USetSpanCondition spanCondition) const;
 
     /**
      * Returns the end of the substring of the input string according to the USetSpanCondition.
@@ -922,7 +939,7 @@
      * @stable ICU 3.8
      * @see USetSpanCondition
      */
-    int32_t spanBack(const UChar *s, int32_t length, USetSpanCondition spanCondition) const;
+    int32_t spanBack(const char16_t *s, int32_t length, USetSpanCondition spanCondition) const;
 
     /**
      * Returns the start of the substring of the input string according to the USetSpanCondition.
@@ -1479,8 +1496,6 @@
 
     friend class USetAccess;
 
-    int32_t getStringCount() const;
-
     const UnicodeString* getString(int32_t index) const;
 
     //----------------------------------------------------------------
@@ -1504,6 +1519,7 @@
     //----------------------------------------------------------------
 
     UnicodeSet(const UnicodeSet& o, UBool /* asThawed */);
+    UnicodeSet& copyFrom(const UnicodeSet& o, UBool asThawed);
 
     //----------------------------------------------------------------
     // Implementation: Pattern parsing
@@ -1519,19 +1535,25 @@
                       UnicodeString& rebuiltPat,
                       uint32_t options,
                       UnicodeSet& (UnicodeSet::*caseClosure)(int32_t attribute),
+                      int32_t depth,
                       UErrorCode& ec);
 
     //----------------------------------------------------------------
     // Implementation: Utility methods
     //----------------------------------------------------------------
 
-    void ensureCapacity(int32_t newLen, UErrorCode& ec);
+    static int32_t nextCapacity(int32_t minCapacity);
 
-    void ensureBufferCapacity(int32_t newLen, UErrorCode& ec);
+    bool ensureCapacity(int32_t newLen);
+
+    bool ensureBufferCapacity(int32_t newLen);
 
     void swapBuffers(void);
 
     UBool allocateStrings(UErrorCode &status);
+    UBool hasStrings() const;
+    int32_t stringsSize() const;
+    UBool stringsContains(const UnicodeString &s) const;
 
     UnicodeString& _toPattern(UnicodeString& result,
                               UBool escapeUnprintable) const;
@@ -1611,11 +1633,10 @@
                               UnicodeString& rebuiltPat,
                               UErrorCode& ec);
 
-    friend void U_CALLCONV UnicodeSet_initInclusion(int32_t src, UErrorCode &status);
     static const UnicodeSet* getInclusions(int32_t src, UErrorCode &status);
 
     /**
-     * A filter that returns TRUE if the given code point should be
+     * A filter that returns true if the given code point should be
      * included in the UnicodeSet being constructed.
      */
     typedef UBool (*Filter)(UChar32 codePoint, void* context);
@@ -1631,13 +1652,21 @@
      */
     void applyFilter(Filter filter,
                      void* context,
-                     int32_t src,
+                     const UnicodeSet* inclusions,
                      UErrorCode &status);
 
+    // UCPMap is now stable ICU 63
+    void applyIntPropertyValue(const UCPMap *map,
+                               UCPMapValueFilter *filter, const void *context,
+                               UErrorCode &errorCode);
+
     /**
      * Set the new pattern to cache.
      */
-    void setPattern(const UnicodeString& newPat);
+    void setPattern(const UnicodeString& newPat) {
+        setPattern(newPat.getBuffer(), newPat.length());
+    }
+    void setPattern(const char16_t *newPat, int32_t newPatLen);
     /**
      * Release existing cached pattern.
      */
@@ -1710,4 +1739,6 @@
 
 U_NAMESPACE_END
 
+#endif /* U_SHOW_CPLUSPLUS_API */
+
 #endif
diff --git a/src/third_party/icu/source/common/unicode/unistr.h b/src/third_party/icu/source/common/unicode/unistr.h
index 63f1933..456389f 100644
--- a/src/third_party/icu/source/common/unicode/unistr.h
+++ b/src/third_party/icu/source/common/unicode/unistr.h
@@ -1,6 +1,8 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
-*   Copyright (C) 1998-2015, International Business Machines
+*   Copyright (C) 1998-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 **********************************************************************
 *
@@ -22,59 +24,59 @@
 #define UNISTR_H
 
 /**
- * \file 
- * \brief C++ API: Unicode String 
+ * \file
+ * \brief C++ API: Unicode String
  */
 
 #include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
+#include <cstddef>
+#include "unicode/char16ptr.h"
 #include "unicode/rep.h"
 #include "unicode/std_string.h"
 #include "unicode/stringpiece.h"
 #include "unicode/bytestream.h"
-#include "unicode/ucasemap.h"
 
 struct UConverter;          // unicode/ucnv.h
 
-#ifndef U_COMPARE_CODE_POINT_ORDER
-/* see also ustring.h and unorm.h */
-/**
- * Option bit for u_strCaseCompare, u_strcasecmp, unorm_compare, etc:
- * Compare strings in code point order instead of code unit order.
- * @stable ICU 2.2
- */
-#define U_COMPARE_CODE_POINT_ORDER  0x8000
-#endif
-
 #ifndef USTRING_H
 /**
  * \ingroup ustring_ustrlen
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 u_strlen(const UChar *s);
 #endif
 
-/**
- * \def U_STRING_CASE_MAPPER_DEFINED
- * @internal
- */
-#ifndef U_STRING_CASE_MAPPER_DEFINED
-#define U_STRING_CASE_MAPPER_DEFINED
-
-/**
- * Internal string case mapping function type.
- * @internal
- */
-typedef int32_t U_CALLCONV
-UStringCaseMapper(const UCaseMap *csm,
-                  UChar *dest, int32_t destCapacity,
-                  const UChar *src, int32_t srcLength,
-                  UErrorCode *pErrorCode);
-
-#endif
-
 U_NAMESPACE_BEGIN
 
+#if !UCONFIG_NO_BREAK_ITERATION
 class BreakIterator;        // unicode/brkiter.h
+#endif
+class Edits;
+
+U_NAMESPACE_END
+
+// Not #ifndef U_HIDE_INTERNAL_API because UnicodeString needs the UStringCaseMapper.
+/**
+ * Internal string case mapping function type.
+ * All error checking must be done.
+ * src and dest must not overlap.
+ * @internal
+ */
+typedef int32_t U_CALLCONV
+UStringCaseMapper(int32_t caseLocale, uint32_t options,
+#if !UCONFIG_NO_BREAK_ITERATION
+                  icu::BreakIterator *iter,
+#endif
+                  char16_t *dest, int32_t destCapacity,
+                  const char16_t *src, int32_t srcLength,
+                  icu::Edits *edits,
+                  UErrorCode &errorCode);
+
+U_NAMESPACE_BEGIN
+
 class Locale;               // unicode/locid.h
 class StringCharacterIterator;
 class UnicodeStringAppendable;  // unicode/appendable.h
@@ -95,29 +97,25 @@
 
 /**
  * Unicode String literals in C++.
- * Dependent on the platform properties, different UnicodeString
- * constructors should be used to create a UnicodeString object from
- * a string literal.
- * The macros are defined for maximum performance.
+ *
+ * Note: these macros are not recommended for new code.
+ * Prior to the availability of C++11 and u"unicode string literals",
+ * these macros were provided for portability and efficiency when
+ * initializing UnicodeStrings from literals.
+ *
  * They work only for strings that contain "invariant characters", i.e.,
  * only latin letters, digits, and some punctuation.
  * See utypes.h for details.
  *
  * The string parameter must be a C string literal.
  * The length of the string, not including the terminating
- * <code>NUL</code>, must be specified as a constant.
- * The U_STRING_DECL macro should be invoked exactly once for one
- * such string variable before it is used.
+ * `NUL`, must be specified as a constant.
  * @stable ICU 2.0
  */
-#if defined(U_DECLARE_UTF16)
-#   define UNICODE_STRING(cs, _length) icu::UnicodeString(TRUE, (const UChar *)U_DECLARE_UTF16(cs), _length)
-#elif U_SIZEOF_WCHAR_T==U_SIZEOF_UCHAR && (U_CHARSET_FAMILY==U_ASCII_FAMILY || (U_SIZEOF_UCHAR == 2 && defined(U_WCHAR_IS_UTF16)))
-#   define UNICODE_STRING(cs, _length) icu::UnicodeString(TRUE, (const UChar *)L ## cs, _length)
-#elif U_SIZEOF_UCHAR==1 && U_CHARSET_FAMILY==U_ASCII_FAMILY
-#   define UNICODE_STRING(cs, _length) icu::UnicodeString(TRUE, (const UChar *)cs, _length)
+#if !U_CHAR16_IS_TYPEDEF
+# define UNICODE_STRING(cs, _length) icu::UnicodeString(true, u ## cs, _length)
 #else
-#   define UNICODE_STRING(cs, _length) icu::UnicodeString(cs, _length, US_INV)
+# define UNICODE_STRING(cs, _length) icu::UnicodeString(true, (const char16_t*)u ## cs, _length)
 #endif
 
 /**
@@ -138,7 +136,7 @@
 /**
  * \def UNISTR_FROM_CHAR_EXPLICIT
  * This can be defined to be empty or "explicit".
- * If explicit, then the UnicodeString(UChar) and UnicodeString(UChar32)
+ * If explicit, then the UnicodeString(char16_t) and UnicodeString(UChar32)
  * constructors are marked as explicit, preventing their inadvertent use.
  * @stable ICU 49
  */
@@ -155,7 +153,7 @@
 /**
  * \def UNISTR_FROM_STRING_EXPLICIT
  * This can be defined to be empty or "explicit".
- * If explicit, then the UnicodeString(const char *) and UnicodeString(const UChar *)
+ * If explicit, then the UnicodeString(const char *) and UnicodeString(const char16_t *)
  * constructors are marked as explicit, preventing their inadvertent use.
  *
  * In particular, this helps prevent accidentally depending on ICU conversion code
@@ -172,8 +170,6 @@
 # endif
 #endif
 
-/* Cannot make the following #ifndef U_HIDE_INTERNAL_API,
-   it is used to construct other non-internal constants */
 /**
  * \def UNISTR_OBJECT_SIZE
  * Desired sizeof(UnicodeString) in bytes.
@@ -191,21 +187,21 @@
  * to 4 * sizeof(pointer) (or 3 * sizeof(pointer) for P128 data models),
  * to hold the fields for heap-allocated strings.
  * Such a minimum size also ensures that the object is easily large enough
- * to hold at least 2 UChars, for one supplementary code point (U16_MAX_LENGTH).
+ * to hold at least 2 char16_ts, for one supplementary code point (U16_MAX_LENGTH).
  *
  * sizeof(UnicodeString) >= 48 should work for all known platforms.
  *
  * For example, on a 64-bit machine where sizeof(vtable pointer) is 8,
  * sizeof(UnicodeString) = 64 would leave space for
  * (64 - sizeof(vtable pointer) - 2) / U_SIZEOF_UCHAR = (64 - 8 - 2) / 2 = 27
- * UChars stored inside the object.
+ * char16_ts stored inside the object.
  *
  * The minimum object size on a 64-bit machine would be
  * 4 * sizeof(pointer) = 4 * 8 = 32 bytes,
- * and the internal buffer would hold up to 11 UChars in that case.
+ * and the internal buffer would hold up to 11 char16_ts in that case.
  *
  * @see U16_MAX_LENGTH
- * @draft ICU 56
+ * @stable ICU 56
  */
 #ifndef UNISTR_OBJECT_SIZE
 # define UNISTR_OBJECT_SIZE 64
@@ -216,7 +212,9 @@
  * similar functionality as the Java String and StringBuffer/StringBuilder classes.
  * It is a concrete implementation of the abstract class Replaceable (for transliteration).
  *
- * A UnicodeString may also "alias" an external array of characters
+ * The UnicodeString equivalent of std::string’s clear() is remove().
+ *
+ * A UnicodeString may "alias" an external array of characters
  * (that is, point to it, rather than own the array)
  * whose lifetime must then at least match the lifetime of the aliasing object.
  * This aliasing may be preserved when returning a UnicodeString by value,
@@ -228,32 +226,35 @@
  *
  * The UnicodeString class is not suitable for subclassing.
  *
- * <p>For an overview of Unicode strings in C and C++ see the
- * <a href="http://userguide.icu-project.org/strings#TOC-Strings-in-C-C-">User Guide Strings chapter</a>.</p>
+ * For an overview of Unicode strings in C and C++ see the
+ * [User Guide Strings chapter](https://unicode-org.github.io/icu/userguide/strings#strings-in-cc).
  *
- * <p>In ICU, a Unicode string consists of 16-bit Unicode <em>code units</em>.
+ * In ICU, a Unicode string consists of 16-bit Unicode *code units*.
  * A Unicode character may be stored with either one code unit
  * (the most common case) or with a matched pair of special code units
- * ("surrogates"). The data type for code units is UChar. 
- * For single-character handling, a Unicode character code <em>point</em> is a value
- * in the range 0..0x10ffff. ICU uses the UChar32 type for code points.</p>
+ * ("surrogates"). The data type for code units is char16_t.
+ * For single-character handling, a Unicode character code *point* is a value
+ * in the range 0..0x10ffff. ICU uses the UChar32 type for code points.
  *
- * <p>Indexes and offsets into and lengths of strings always count code units, not code points.
+ * Indexes and offsets into and lengths of strings always count code units, not code points.
  * This is the same as with multi-byte char* strings in traditional string handling.
  * Operations on partial strings typically do not test for code point boundaries.
  * If necessary, the user needs to take care of such boundaries by testing for the code unit
  * values or by using functions like
  * UnicodeString::getChar32Start() and UnicodeString::getChar32Limit()
- * (or, in C, the equivalent macros U16_SET_CP_START() and U16_SET_CP_LIMIT(), see utf.h).</p>
+ * (or, in C, the equivalent macros U16_SET_CP_START() and U16_SET_CP_LIMIT(), see utf.h).
  *
  * UnicodeString methods are more lenient with regard to input parameter values
  * than other ICU APIs. In particular:
  * - If indexes are out of bounds for a UnicodeString object
- *   (<0 or >length()) then they are "pinned" to the nearest boundary.
- * - If primitive string pointer values (e.g., const UChar * or char *)
+ *   (< 0 or > length()) then they are "pinned" to the nearest boundary.
+ * - If the buffer passed to an insert/append/replace operation is owned by the
+ *   target object, e.g., calling str.append(str), an extra copy may take place
+ *   to ensure safety.
+ * - If primitive string pointer values (e.g., const char16_t * or char *)
  *   for input strings are NULL, then those input string parameters are treated
  *   as if they pointed to an empty string.
- *   However, this is <em>not</em> the case for char * parameters for charset names
+ *   However, this is *not* the case for char * parameters for charset names
  *   or other IDs.
  * - Most UnicodeString methods do not take a UErrorCode parameter because
  *   there are usually very few opportunities for failure other than a shortage
@@ -277,14 +278,14 @@
  * This includes the const UnicodeString & parameters for
  * copy construction, assignment, and cloning.
  *
- * <p>UnicodeString uses several storage methods.
+ * UnicodeString uses several storage methods.
  * String contents can be stored inside the UnicodeString object itself,
  * in an allocated and shared buffer, or in an outside buffer that is "aliased".
  * Most of this is done transparently, but careful aliasing in particular provides
  * significant performance improvements.
  * Also, the internal buffer is accessible via special functions.
  * For details see the
- * <a href="http://userguide.icu-project.org/strings#TOC-Maximizing-Performance-with-the-UnicodeString-Storage-Model">User Guide Strings chapter</a>.</p>
+ * [User Guide Strings chapter](https://unicode-org.github.io/icu/userguide/strings#maximizing-performance-with-the-unicodestring-storage-model).
  *
  * @see utf.h
  * @see CharacterIterator
@@ -319,8 +320,8 @@
   /**
    * Equality operator. Performs only bitwise comparison.
    * @param text The UnicodeString to compare to this one.
-   * @return TRUE if <TT>text</TT> contains the same characters as this one,
-   * FALSE otherwise.
+   * @return true if `text` contains the same characters as this one,
+   * false otherwise.
    * @stable ICU 2.0
    */
   inline UBool operator== (const UnicodeString& text) const;
@@ -328,8 +329,8 @@
   /**
    * Inequality operator. Performs only bitwise comparison.
    * @param text The UnicodeString to compare to this one.
-   * @return FALSE if <TT>text</TT> contains the same characters as this one,
-   * TRUE otherwise.
+   * @return false if `text` contains the same characters as this one,
+   * true otherwise.
    * @stable ICU 2.0
    */
   inline UBool operator!= (const UnicodeString& text) const;
@@ -337,8 +338,8 @@
   /**
    * Greater than operator. Performs only bitwise comparison.
    * @param text The UnicodeString to compare to this one.
-   * @return TRUE if the characters in this are bitwise
-   * greater than the characters in <code>text</code>, FALSE otherwise
+   * @return true if the characters in this are bitwise
+   * greater than the characters in `text`, false otherwise
    * @stable ICU 2.0
    */
   inline UBool operator> (const UnicodeString& text) const;
@@ -346,8 +347,8 @@
   /**
    * Less than operator. Performs only bitwise comparison.
    * @param text The UnicodeString to compare to this one.
-   * @return TRUE if the characters in this are bitwise
-   * less than the characters in <code>text</code>, FALSE otherwise
+   * @return true if the characters in this are bitwise
+   * less than the characters in `text`, false otherwise
    * @stable ICU 2.0
    */
   inline UBool operator< (const UnicodeString& text) const;
@@ -355,8 +356,8 @@
   /**
    * Greater than or equal operator. Performs only bitwise comparison.
    * @param text The UnicodeString to compare to this one.
-   * @return TRUE if the characters in this are bitwise
-   * greater than or equal to the characters in <code>text</code>, FALSE otherwise
+   * @return true if the characters in this are bitwise
+   * greater than or equal to the characters in `text`, false otherwise
    * @stable ICU 2.0
    */
   inline UBool operator>= (const UnicodeString& text) const;
@@ -364,38 +365,38 @@
   /**
    * Less than or equal operator. Performs only bitwise comparison.
    * @param text The UnicodeString to compare to this one.
-   * @return TRUE if the characters in this are bitwise
-   * less than or equal to the characters in <code>text</code>, FALSE otherwise
+   * @return true if the characters in this are bitwise
+   * less than or equal to the characters in `text`, false otherwise
    * @stable ICU 2.0
    */
   inline UBool operator<= (const UnicodeString& text) const;
 
   /**
    * Compare the characters bitwise in this UnicodeString to
-   * the characters in <code>text</code>.
+   * the characters in `text`.
    * @param text The UnicodeString to compare to this one.
    * @return The result of bitwise character comparison: 0 if this
-   * contains the same characters as <code>text</code>, -1 if the characters in
-   * this are bitwise less than the characters in <code>text</code>, +1 if the
+   * contains the same characters as `text`, -1 if the characters in
+   * this are bitwise less than the characters in `text`, +1 if the
    * characters in this are bitwise greater than the characters
-   * in <code>text</code>.
+   * in `text`.
    * @stable ICU 2.0
    */
   inline int8_t compare(const UnicodeString& text) const;
 
   /**
    * Compare the characters bitwise in the range
-   * [<TT>start</TT>, <TT>start + length</TT>) with the characters
-   * in the <b>entire string</b> <TT>text</TT>.
+   * [`start`, `start + length`) with the characters
+   * in the **entire string** `text`.
    * (The parameters "start" and "length" are not applied to the other text "text".)
    * @param start the offset at which the compare operation begins
    * @param length the number of characters of text to compare.
    * @param text the other text to be compared against this string.
    * @return The result of bitwise character comparison: 0 if this
-   * contains the same characters as <code>text</code>, -1 if the characters in
-   * this are bitwise less than the characters in <code>text</code>, +1 if the
+   * contains the same characters as `text`, -1 if the characters in
+   * this are bitwise less than the characters in `text`, +1 if the
    * characters in this are bitwise greater than the characters
-   * in <code>text</code>.
+   * in `text`.
    * @stable ICU 2.0
    */
   inline int8_t compare(int32_t start,
@@ -404,19 +405,19 @@
 
   /**
    * Compare the characters bitwise in the range
-   * [<TT>start</TT>, <TT>start + length</TT>) with the characters
-   * in <TT>srcText</TT> in the range
-   * [<TT>srcStart</TT>, <TT>srcStart + srcLength</TT>).
+   * [`start`, `start + length`) with the characters
+   * in `srcText` in the range
+   * [`srcStart`, `srcStart + srcLength`).
    * @param start the offset at which the compare operation begins
    * @param length the number of characters in this to compare.
    * @param srcText the text to be compared
-   * @param srcStart the offset into <TT>srcText</TT> to start comparison
-   * @param srcLength the number of characters in <TT>src</TT> to compare
+   * @param srcStart the offset into `srcText` to start comparison
+   * @param srcLength the number of characters in `src` to compare
    * @return The result of bitwise character comparison: 0 if this
-   * contains the same characters as <code>srcText</code>, -1 if the characters in
-   * this are bitwise less than the characters in <code>srcText</code>, +1 if the
+   * contains the same characters as `srcText`, -1 if the characters in
+   * this are bitwise less than the characters in `srcText`, +1 if the
    * characters in this are bitwise greater than the characters
-   * in <code>srcText</code>.
+   * in `srcText`.
    * @stable ICU 2.0
    */
    inline int8_t compare(int32_t start,
@@ -427,75 +428,75 @@
 
   /**
    * Compare the characters bitwise in this UnicodeString with the first
-   * <TT>srcLength</TT> characters in <TT>srcChars</TT>.
+   * `srcLength` characters in `srcChars`.
    * @param srcChars The characters to compare to this UnicodeString.
-   * @param srcLength the number of characters in <TT>srcChars</TT> to compare
+   * @param srcLength the number of characters in `srcChars` to compare
    * @return The result of bitwise character comparison: 0 if this
-   * contains the same characters as <code>srcChars</code>, -1 if the characters in
-   * this are bitwise less than the characters in <code>srcChars</code>, +1 if the
+   * contains the same characters as `srcChars`, -1 if the characters in
+   * this are bitwise less than the characters in `srcChars`, +1 if the
    * characters in this are bitwise greater than the characters
-   * in <code>srcChars</code>.
+   * in `srcChars`.
    * @stable ICU 2.0
    */
-  inline int8_t compare(const UChar *srcChars,
+  inline int8_t compare(ConstChar16Ptr srcChars,
          int32_t srcLength) const;
 
   /**
    * Compare the characters bitwise in the range
-   * [<TT>start</TT>, <TT>start + length</TT>) with the first
-   * <TT>length</TT> characters in <TT>srcChars</TT>
+   * [`start`, `start + length`) with the first
+   * `length` characters in `srcChars`
    * @param start the offset at which the compare operation begins
    * @param length the number of characters to compare.
    * @param srcChars the characters to be compared
    * @return The result of bitwise character comparison: 0 if this
-   * contains the same characters as <code>srcChars</code>, -1 if the characters in
-   * this are bitwise less than the characters in <code>srcChars</code>, +1 if the
+   * contains the same characters as `srcChars`, -1 if the characters in
+   * this are bitwise less than the characters in `srcChars`, +1 if the
    * characters in this are bitwise greater than the characters
-   * in <code>srcChars</code>.
+   * in `srcChars`.
    * @stable ICU 2.0
    */
   inline int8_t compare(int32_t start,
          int32_t length,
-         const UChar *srcChars) const;
+         const char16_t *srcChars) const;
 
   /**
    * Compare the characters bitwise in the range
-   * [<TT>start</TT>, <TT>start + length</TT>) with the characters
-   * in <TT>srcChars</TT> in the range
-   * [<TT>srcStart</TT>, <TT>srcStart + srcLength</TT>).
+   * [`start`, `start + length`) with the characters
+   * in `srcChars` in the range
+   * [`srcStart`, `srcStart + srcLength`).
    * @param start the offset at which the compare operation begins
    * @param length the number of characters in this to compare
    * @param srcChars the characters to be compared
-   * @param srcStart the offset into <TT>srcChars</TT> to start comparison
-   * @param srcLength the number of characters in <TT>srcChars</TT> to compare
+   * @param srcStart the offset into `srcChars` to start comparison
+   * @param srcLength the number of characters in `srcChars` to compare
    * @return The result of bitwise character comparison: 0 if this
-   * contains the same characters as <code>srcChars</code>, -1 if the characters in
-   * this are bitwise less than the characters in <code>srcChars</code>, +1 if the
+   * contains the same characters as `srcChars`, -1 if the characters in
+   * this are bitwise less than the characters in `srcChars`, +1 if the
    * characters in this are bitwise greater than the characters
-   * in <code>srcChars</code>.
+   * in `srcChars`.
    * @stable ICU 2.0
    */
   inline int8_t compare(int32_t start,
          int32_t length,
-         const UChar *srcChars,
+         const char16_t *srcChars,
          int32_t srcStart,
          int32_t srcLength) const;
 
   /**
    * Compare the characters bitwise in the range
-   * [<TT>start</TT>, <TT>limit</TT>) with the characters
-   * in <TT>srcText</TT> in the range
-   * [<TT>srcStart</TT>, <TT>srcLimit</TT>).
+   * [`start`, `limit`) with the characters
+   * in `srcText` in the range
+   * [`srcStart`, `srcLimit`).
    * @param start the offset at which the compare operation begins
    * @param limit the offset immediately following the compare operation
    * @param srcText the text to be compared
-   * @param srcStart the offset into <TT>srcText</TT> to start comparison
-   * @param srcLimit the offset into <TT>srcText</TT> to limit comparison
+   * @param srcStart the offset into `srcText` to start comparison
+   * @param srcLimit the offset into `srcText` to limit comparison
    * @return The result of bitwise character comparison: 0 if this
-   * contains the same characters as <code>srcText</code>, -1 if the characters in
-   * this are bitwise less than the characters in <code>srcText</code>, +1 if the
+   * contains the same characters as `srcText`, -1 if the characters in
+   * this are bitwise less than the characters in `srcText`, +1 if the
    * characters in this are bitwise greater than the characters
-   * in <code>srcText</code>.
+   * in `srcText`.
    * @stable ICU 2.0
    */
   inline int8_t compareBetween(int32_t start,
@@ -591,7 +592,7 @@
    * in code point order
    * @stable ICU 2.0
    */
-  inline int8_t compareCodePointOrder(const UChar *srcChars,
+  inline int8_t compareCodePointOrder(ConstChar16Ptr srcChars,
                                       int32_t srcLength) const;
 
   /**
@@ -615,7 +616,7 @@
    */
   inline int8_t compareCodePointOrder(int32_t start,
                                       int32_t length,
-                                      const UChar *srcChars) const;
+                                      const char16_t *srcChars) const;
 
   /**
    * Compare two Unicode strings in code point order.
@@ -640,7 +641,7 @@
    */
   inline int8_t compareCodePointOrder(int32_t start,
                                       int32_t length,
-                                      const UChar *srcChars,
+                                      const char16_t *srcChars,
                                       int32_t srcStart,
                                       int32_t srcLength) const;
 
@@ -764,7 +765,7 @@
    * @return A negative, zero, or positive integer indicating the comparison result.
    * @stable ICU 2.0
    */
-  inline int8_t caseCompare(const UChar *srcChars,
+  inline int8_t caseCompare(ConstChar16Ptr srcChars,
          int32_t srcLength,
          uint32_t options) const;
 
@@ -790,7 +791,7 @@
    */
   inline int8_t caseCompare(int32_t start,
          int32_t length,
-         const UChar *srcChars,
+         const char16_t *srcChars,
          uint32_t options) const;
 
   /**
@@ -817,7 +818,7 @@
    */
   inline int8_t caseCompare(int32_t start,
          int32_t length,
-         const UChar *srcChars,
+         const char16_t *srcChars,
          int32_t srcStart,
          int32_t srcLength,
          uint32_t options) const;
@@ -852,22 +853,22 @@
             uint32_t options) const;
 
   /**
-   * Determine if this starts with the characters in <TT>text</TT>
+   * Determine if this starts with the characters in `text`
    * @param text The text to match.
-   * @return TRUE if this starts with the characters in <TT>text</TT>,
-   * FALSE otherwise
+   * @return true if this starts with the characters in `text`,
+   * false otherwise
    * @stable ICU 2.0
    */
   inline UBool startsWith(const UnicodeString& text) const;
 
   /**
-   * Determine if this starts with the characters in <TT>srcText</TT>
-   * in the range [<TT>srcStart</TT>, <TT>srcStart + srcLength</TT>).
+   * Determine if this starts with the characters in `srcText`
+   * in the range [`srcStart`, `srcStart + srcLength`).
    * @param srcText The text to match.
-   * @param srcStart the offset into <TT>srcText</TT> to start matching
-   * @param srcLength the number of characters in <TT>srcText</TT> to match
-   * @return TRUE if this starts with the characters in <TT>text</TT>,
-   * FALSE otherwise
+   * @param srcStart the offset into `srcText` to start matching
+   * @param srcLength the number of characters in `srcText` to match
+   * @return true if this starts with the characters in `text`,
+   * false otherwise
    * @stable ICU 2.0
    */
   inline UBool startsWith(const UnicodeString& srcText,
@@ -875,46 +876,46 @@
             int32_t srcLength) const;
 
   /**
-   * Determine if this starts with the characters in <TT>srcChars</TT>
+   * Determine if this starts with the characters in `srcChars`
    * @param srcChars The characters to match.
-   * @param srcLength the number of characters in <TT>srcChars</TT>
-   * @return TRUE if this starts with the characters in <TT>srcChars</TT>,
-   * FALSE otherwise
+   * @param srcLength the number of characters in `srcChars`
+   * @return true if this starts with the characters in `srcChars`,
+   * false otherwise
    * @stable ICU 2.0
    */
-  inline UBool startsWith(const UChar *srcChars,
+  inline UBool startsWith(ConstChar16Ptr srcChars,
             int32_t srcLength) const;
 
   /**
-   * Determine if this ends with the characters in <TT>srcChars</TT>
-   * in the range  [<TT>srcStart</TT>, <TT>srcStart + srcLength</TT>).
+   * Determine if this ends with the characters in `srcChars`
+   * in the range  [`srcStart`, `srcStart + srcLength`).
    * @param srcChars The characters to match.
-   * @param srcStart the offset into <TT>srcText</TT> to start matching
-   * @param srcLength the number of characters in <TT>srcChars</TT> to match
-   * @return TRUE if this ends with the characters in <TT>srcChars</TT>, FALSE otherwise
+   * @param srcStart the offset into `srcText` to start matching
+   * @param srcLength the number of characters in `srcChars` to match
+   * @return true if this ends with the characters in `srcChars`, false otherwise
    * @stable ICU 2.0
    */
-  inline UBool startsWith(const UChar *srcChars,
+  inline UBool startsWith(const char16_t *srcChars,
             int32_t srcStart,
             int32_t srcLength) const;
 
   /**
-   * Determine if this ends with the characters in <TT>text</TT>
+   * Determine if this ends with the characters in `text`
    * @param text The text to match.
-   * @return TRUE if this ends with the characters in <TT>text</TT>,
-   * FALSE otherwise
+   * @return true if this ends with the characters in `text`,
+   * false otherwise
    * @stable ICU 2.0
    */
   inline UBool endsWith(const UnicodeString& text) const;
 
   /**
-   * Determine if this ends with the characters in <TT>srcText</TT>
-   * in the range [<TT>srcStart</TT>, <TT>srcStart + srcLength</TT>).
+   * Determine if this ends with the characters in `srcText`
+   * in the range [`srcStart`, `srcStart + srcLength`).
    * @param srcText The text to match.
-   * @param srcStart the offset into <TT>srcText</TT> to start matching
-   * @param srcLength the number of characters in <TT>srcText</TT> to match
-   * @return TRUE if this ends with the characters in <TT>text</TT>,
-   * FALSE otherwise
+   * @param srcStart the offset into `srcText` to start matching
+   * @param srcLength the number of characters in `srcText` to match
+   * @return true if this ends with the characters in `text`,
+   * false otherwise
    * @stable ICU 2.0
    */
   inline UBool endsWith(const UnicodeString& srcText,
@@ -922,27 +923,27 @@
           int32_t srcLength) const;
 
   /**
-   * Determine if this ends with the characters in <TT>srcChars</TT>
+   * Determine if this ends with the characters in `srcChars`
    * @param srcChars The characters to match.
-   * @param srcLength the number of characters in <TT>srcChars</TT>
-   * @return TRUE if this ends with the characters in <TT>srcChars</TT>,
-   * FALSE otherwise
+   * @param srcLength the number of characters in `srcChars`
+   * @return true if this ends with the characters in `srcChars`,
+   * false otherwise
    * @stable ICU 2.0
    */
-  inline UBool endsWith(const UChar *srcChars,
+  inline UBool endsWith(ConstChar16Ptr srcChars,
           int32_t srcLength) const;
 
   /**
-   * Determine if this ends with the characters in <TT>srcChars</TT>
-   * in the range  [<TT>srcStart</TT>, <TT>srcStart + srcLength</TT>).
+   * Determine if this ends with the characters in `srcChars`
+   * in the range  [`srcStart`, `srcStart + srcLength`).
    * @param srcChars The characters to match.
-   * @param srcStart the offset into <TT>srcText</TT> to start matching
-   * @param srcLength the number of characters in <TT>srcChars</TT> to match
-   * @return TRUE if this ends with the characters in <TT>srcChars</TT>,
-   * FALSE otherwise
+   * @param srcStart the offset into `srcText` to start matching
+   * @param srcLength the number of characters in `srcChars` to match
+   * @return true if this ends with the characters in `srcChars`,
+   * false otherwise
    * @stable ICU 2.0
    */
-  inline UBool endsWith(const UChar *srcChars,
+  inline UBool endsWith(const char16_t *srcChars,
           int32_t srcStart,
           int32_t srcLength) const;
 
@@ -950,21 +951,21 @@
   /* Searching - bitwise only */
 
   /**
-   * Locate in this the first occurrence of the characters in <TT>text</TT>,
+   * Locate in this the first occurrence of the characters in `text`,
    * using bitwise comparison.
    * @param text The text to search for.
-   * @return The offset into this of the start of <TT>text</TT>,
+   * @return The offset into this of the start of `text`,
    * or -1 if not found.
    * @stable ICU 2.0
    */
   inline int32_t indexOf(const UnicodeString& text) const;
 
   /**
-   * Locate in this the first occurrence of the characters in <TT>text</TT>
-   * starting at offset <TT>start</TT>, using bitwise comparison.
+   * Locate in this the first occurrence of the characters in `text`
+   * starting at offset `start`, using bitwise comparison.
    * @param text The text to search for.
    * @param start The offset at which searching will start.
-   * @return The offset into this of the start of <TT>text</TT>,
+   * @return The offset into this of the start of `text`,
    * or -1 if not found.
    * @stable ICU 2.0
    */
@@ -973,12 +974,12 @@
 
   /**
    * Locate in this the first occurrence in the range
-   * [<TT>start</TT>, <TT>start + length</TT>) of the characters
-   * in <TT>text</TT>, using bitwise comparison.
+   * [`start`, `start + length`) of the characters
+   * in `text`, using bitwise comparison.
    * @param text The text to search for.
    * @param start The offset at which searching will start.
    * @param length The number of characters to search
-   * @return The offset into this of the start of <TT>text</TT>,
+   * @return The offset into this of the start of `text`,
    * or -1 if not found.
    * @stable ICU 2.0
    */
@@ -988,17 +989,17 @@
 
   /**
    * Locate in this the first occurrence in the range
-   * [<TT>start</TT>, <TT>start + length</TT>) of the characters
-   *  in <TT>srcText</TT> in the range
-   * [<TT>srcStart</TT>, <TT>srcStart + srcLength</TT>),
+   * [`start`, `start + length`) of the characters
+   *  in `srcText` in the range
+   * [`srcStart`, `srcStart + srcLength`),
    * using bitwise comparison.
    * @param srcText The text to search for.
-   * @param srcStart the offset into <TT>srcText</TT> at which
+   * @param srcStart the offset into `srcText` at which
    * to start matching
-   * @param srcLength the number of characters in <TT>srcText</TT> to match
+   * @param srcLength the number of characters in `srcText` to match
    * @param start the offset into this at which to start matching
    * @param length the number of characters in this to search
-   * @return The offset into this of the start of <TT>text</TT>,
+   * @return The offset into this of the start of `text`,
    * or -1 if not found.
    * @stable ICU 2.0
    */
@@ -1010,123 +1011,123 @@
 
   /**
    * Locate in this the first occurrence of the characters in
-   * <TT>srcChars</TT>
-   * starting at offset <TT>start</TT>, using bitwise comparison.
+   * `srcChars`
+   * starting at offset `start`, using bitwise comparison.
    * @param srcChars The text to search for.
-   * @param srcLength the number of characters in <TT>srcChars</TT> to match
+   * @param srcLength the number of characters in `srcChars` to match
    * @param start the offset into this at which to start matching
-   * @return The offset into this of the start of <TT>text</TT>,
+   * @return The offset into this of the start of `text`,
    * or -1 if not found.
    * @stable ICU 2.0
    */
-  inline int32_t indexOf(const UChar *srcChars,
+  inline int32_t indexOf(const char16_t *srcChars,
               int32_t srcLength,
               int32_t start) const;
 
   /**
    * Locate in this the first occurrence in the range
-   * [<TT>start</TT>, <TT>start + length</TT>) of the characters
-   * in <TT>srcChars</TT>, using bitwise comparison.
+   * [`start`, `start + length`) of the characters
+   * in `srcChars`, using bitwise comparison.
    * @param srcChars The text to search for.
-   * @param srcLength the number of characters in <TT>srcChars</TT>
+   * @param srcLength the number of characters in `srcChars`
    * @param start The offset at which searching will start.
    * @param length The number of characters to search
-   * @return The offset into this of the start of <TT>srcChars</TT>,
+   * @return The offset into this of the start of `srcChars`,
    * or -1 if not found.
    * @stable ICU 2.0
    */
-  inline int32_t indexOf(const UChar *srcChars,
+  inline int32_t indexOf(ConstChar16Ptr srcChars,
               int32_t srcLength,
               int32_t start,
               int32_t length) const;
 
   /**
    * Locate in this the first occurrence in the range
-   * [<TT>start</TT>, <TT>start + length</TT>) of the characters
-   * in <TT>srcChars</TT> in the range
-   * [<TT>srcStart</TT>, <TT>srcStart + srcLength</TT>),
+   * [`start`, `start + length`) of the characters
+   * in `srcChars` in the range
+   * [`srcStart`, `srcStart + srcLength`),
    * using bitwise comparison.
    * @param srcChars The text to search for.
-   * @param srcStart the offset into <TT>srcChars</TT> at which
+   * @param srcStart the offset into `srcChars` at which
    * to start matching
-   * @param srcLength the number of characters in <TT>srcChars</TT> to match
+   * @param srcLength the number of characters in `srcChars` to match
    * @param start the offset into this at which to start matching
    * @param length the number of characters in this to search
-   * @return The offset into this of the start of <TT>text</TT>,
+   * @return The offset into this of the start of `text`,
    * or -1 if not found.
    * @stable ICU 2.0
    */
-  int32_t indexOf(const UChar *srcChars,
+  int32_t indexOf(const char16_t *srcChars,
               int32_t srcStart,
               int32_t srcLength,
               int32_t start,
               int32_t length) const;
 
   /**
-   * Locate in this the first occurrence of the BMP code point <code>c</code>,
+   * Locate in this the first occurrence of the BMP code point `c`,
    * using bitwise comparison.
    * @param c The code unit to search for.
-   * @return The offset into this of <TT>c</TT>, or -1 if not found.
+   * @return The offset into this of `c`, or -1 if not found.
    * @stable ICU 2.0
    */
-  inline int32_t indexOf(UChar c) const;
+  inline int32_t indexOf(char16_t c) const;
 
   /**
-   * Locate in this the first occurrence of the code point <TT>c</TT>,
+   * Locate in this the first occurrence of the code point `c`,
    * using bitwise comparison.
    *
    * @param c The code point to search for.
-   * @return The offset into this of <TT>c</TT>, or -1 if not found.
+   * @return The offset into this of `c`, or -1 if not found.
    * @stable ICU 2.0
    */
   inline int32_t indexOf(UChar32 c) const;
 
   /**
-   * Locate in this the first occurrence of the BMP code point <code>c</code>,
-   * starting at offset <TT>start</TT>, using bitwise comparison.
+   * Locate in this the first occurrence of the BMP code point `c`,
+   * starting at offset `start`, using bitwise comparison.
    * @param c The code unit to search for.
    * @param start The offset at which searching will start.
-   * @return The offset into this of <TT>c</TT>, or -1 if not found.
+   * @return The offset into this of `c`, or -1 if not found.
    * @stable ICU 2.0
    */
-  inline int32_t indexOf(UChar c,
+  inline int32_t indexOf(char16_t c,
               int32_t start) const;
 
   /**
-   * Locate in this the first occurrence of the code point <TT>c</TT>
-   * starting at offset <TT>start</TT>, using bitwise comparison.
+   * Locate in this the first occurrence of the code point `c`
+   * starting at offset `start`, using bitwise comparison.
    *
    * @param c The code point to search for.
    * @param start The offset at which searching will start.
-   * @return The offset into this of <TT>c</TT>, or -1 if not found.
+   * @return The offset into this of `c`, or -1 if not found.
    * @stable ICU 2.0
    */
   inline int32_t indexOf(UChar32 c,
               int32_t start) const;
 
   /**
-   * Locate in this the first occurrence of the BMP code point <code>c</code>
-   * in the range [<TT>start</TT>, <TT>start + length</TT>),
+   * Locate in this the first occurrence of the BMP code point `c`
+   * in the range [`start`, `start + length`),
    * using bitwise comparison.
    * @param c The code unit to search for.
    * @param start the offset into this at which to start matching
    * @param length the number of characters in this to search
-   * @return The offset into this of <TT>c</TT>, or -1 if not found.
+   * @return The offset into this of `c`, or -1 if not found.
    * @stable ICU 2.0
    */
-  inline int32_t indexOf(UChar c,
+  inline int32_t indexOf(char16_t c,
               int32_t start,
               int32_t length) const;
 
   /**
-   * Locate in this the first occurrence of the code point <TT>c</TT>
-   * in the range [<TT>start</TT>, <TT>start + length</TT>),
+   * Locate in this the first occurrence of the code point `c`
+   * in the range [`start`, `start + length`),
    * using bitwise comparison.
    *
    * @param c The code point to search for.
    * @param start the offset into this at which to start matching
    * @param length the number of characters in this to search
-   * @return The offset into this of <TT>c</TT>, or -1 if not found.
+   * @return The offset into this of `c`, or -1 if not found.
    * @stable ICU 2.0
    */
   inline int32_t indexOf(UChar32 c,
@@ -1134,21 +1135,21 @@
               int32_t length) const;
 
   /**
-   * Locate in this the last occurrence of the characters in <TT>text</TT>,
+   * Locate in this the last occurrence of the characters in `text`,
    * using bitwise comparison.
    * @param text The text to search for.
-   * @return The offset into this of the start of <TT>text</TT>,
+   * @return The offset into this of the start of `text`,
    * or -1 if not found.
    * @stable ICU 2.0
    */
   inline int32_t lastIndexOf(const UnicodeString& text) const;
 
   /**
-   * Locate in this the last occurrence of the characters in <TT>text</TT>
-   * starting at offset <TT>start</TT>, using bitwise comparison.
+   * Locate in this the last occurrence of the characters in `text`
+   * starting at offset `start`, using bitwise comparison.
    * @param text The text to search for.
    * @param start The offset at which searching will start.
-   * @return The offset into this of the start of <TT>text</TT>,
+   * @return The offset into this of the start of `text`,
    * or -1 if not found.
    * @stable ICU 2.0
    */
@@ -1157,12 +1158,12 @@
 
   /**
    * Locate in this the last occurrence in the range
-   * [<TT>start</TT>, <TT>start + length</TT>) of the characters
-   * in <TT>text</TT>, using bitwise comparison.
+   * [`start`, `start + length`) of the characters
+   * in `text`, using bitwise comparison.
    * @param text The text to search for.
    * @param start The offset at which searching will start.
    * @param length The number of characters to search
-   * @return The offset into this of the start of <TT>text</TT>,
+   * @return The offset into this of the start of `text`,
    * or -1 if not found.
    * @stable ICU 2.0
    */
@@ -1172,17 +1173,17 @@
 
   /**
    * Locate in this the last occurrence in the range
-   * [<TT>start</TT>, <TT>start + length</TT>) of the characters
-   * in <TT>srcText</TT> in the range
-   * [<TT>srcStart</TT>, <TT>srcStart + srcLength</TT>),
+   * [`start`, `start + length`) of the characters
+   * in `srcText` in the range
+   * [`srcStart`, `srcStart + srcLength`),
    * using bitwise comparison.
    * @param srcText The text to search for.
-   * @param srcStart the offset into <TT>srcText</TT> at which
+   * @param srcStart the offset into `srcText` at which
    * to start matching
-   * @param srcLength the number of characters in <TT>srcText</TT> to match
+   * @param srcLength the number of characters in `srcText` to match
    * @param start the offset into this at which to start matching
    * @param length the number of characters in this to search
-   * @return The offset into this of the start of <TT>text</TT>,
+   * @return The offset into this of the start of `text`,
    * or -1 if not found.
    * @stable ICU 2.0
    */
@@ -1193,123 +1194,123 @@
               int32_t length) const;
 
   /**
-   * Locate in this the last occurrence of the characters in <TT>srcChars</TT>
-   * starting at offset <TT>start</TT>, using bitwise comparison.
+   * Locate in this the last occurrence of the characters in `srcChars`
+   * starting at offset `start`, using bitwise comparison.
    * @param srcChars The text to search for.
-   * @param srcLength the number of characters in <TT>srcChars</TT> to match
+   * @param srcLength the number of characters in `srcChars` to match
    * @param start the offset into this at which to start matching
-   * @return The offset into this of the start of <TT>text</TT>,
+   * @return The offset into this of the start of `text`,
    * or -1 if not found.
    * @stable ICU 2.0
    */
-  inline int32_t lastIndexOf(const UChar *srcChars,
+  inline int32_t lastIndexOf(const char16_t *srcChars,
               int32_t srcLength,
               int32_t start) const;
 
   /**
    * Locate in this the last occurrence in the range
-   * [<TT>start</TT>, <TT>start + length</TT>) of the characters
-   * in <TT>srcChars</TT>, using bitwise comparison.
+   * [`start`, `start + length`) of the characters
+   * in `srcChars`, using bitwise comparison.
    * @param srcChars The text to search for.
-   * @param srcLength the number of characters in <TT>srcChars</TT>
+   * @param srcLength the number of characters in `srcChars`
    * @param start The offset at which searching will start.
    * @param length The number of characters to search
-   * @return The offset into this of the start of <TT>srcChars</TT>,
+   * @return The offset into this of the start of `srcChars`,
    * or -1 if not found.
    * @stable ICU 2.0
    */
-  inline int32_t lastIndexOf(const UChar *srcChars,
+  inline int32_t lastIndexOf(ConstChar16Ptr srcChars,
               int32_t srcLength,
               int32_t start,
               int32_t length) const;
 
   /**
    * Locate in this the last occurrence in the range
-   * [<TT>start</TT>, <TT>start + length</TT>) of the characters
-   * in <TT>srcChars</TT> in the range
-   * [<TT>srcStart</TT>, <TT>srcStart + srcLength</TT>),
+   * [`start`, `start + length`) of the characters
+   * in `srcChars` in the range
+   * [`srcStart`, `srcStart + srcLength`),
    * using bitwise comparison.
    * @param srcChars The text to search for.
-   * @param srcStart the offset into <TT>srcChars</TT> at which
+   * @param srcStart the offset into `srcChars` at which
    * to start matching
-   * @param srcLength the number of characters in <TT>srcChars</TT> to match
+   * @param srcLength the number of characters in `srcChars` to match
    * @param start the offset into this at which to start matching
    * @param length the number of characters in this to search
-   * @return The offset into this of the start of <TT>text</TT>,
+   * @return The offset into this of the start of `text`,
    * or -1 if not found.
    * @stable ICU 2.0
    */
-  int32_t lastIndexOf(const UChar *srcChars,
+  int32_t lastIndexOf(const char16_t *srcChars,
               int32_t srcStart,
               int32_t srcLength,
               int32_t start,
               int32_t length) const;
 
   /**
-   * Locate in this the last occurrence of the BMP code point <code>c</code>,
+   * Locate in this the last occurrence of the BMP code point `c`,
    * using bitwise comparison.
    * @param c The code unit to search for.
-   * @return The offset into this of <TT>c</TT>, or -1 if not found.
+   * @return The offset into this of `c`, or -1 if not found.
    * @stable ICU 2.0
    */
-  inline int32_t lastIndexOf(UChar c) const;
+  inline int32_t lastIndexOf(char16_t c) const;
 
   /**
-   * Locate in this the last occurrence of the code point <TT>c</TT>,
+   * Locate in this the last occurrence of the code point `c`,
    * using bitwise comparison.
    *
    * @param c The code point to search for.
-   * @return The offset into this of <TT>c</TT>, or -1 if not found.
+   * @return The offset into this of `c`, or -1 if not found.
    * @stable ICU 2.0
    */
   inline int32_t lastIndexOf(UChar32 c) const;
 
   /**
-   * Locate in this the last occurrence of the BMP code point <code>c</code>
-   * starting at offset <TT>start</TT>, using bitwise comparison.
+   * Locate in this the last occurrence of the BMP code point `c`
+   * starting at offset `start`, using bitwise comparison.
    * @param c The code unit to search for.
    * @param start The offset at which searching will start.
-   * @return The offset into this of <TT>c</TT>, or -1 if not found.
+   * @return The offset into this of `c`, or -1 if not found.
    * @stable ICU 2.0
    */
-  inline int32_t lastIndexOf(UChar c,
+  inline int32_t lastIndexOf(char16_t c,
               int32_t start) const;
 
   /**
-   * Locate in this the last occurrence of the code point <TT>c</TT>
-   * starting at offset <TT>start</TT>, using bitwise comparison.
+   * Locate in this the last occurrence of the code point `c`
+   * starting at offset `start`, using bitwise comparison.
    *
    * @param c The code point to search for.
    * @param start The offset at which searching will start.
-   * @return The offset into this of <TT>c</TT>, or -1 if not found.
+   * @return The offset into this of `c`, or -1 if not found.
    * @stable ICU 2.0
    */
   inline int32_t lastIndexOf(UChar32 c,
               int32_t start) const;
 
   /**
-   * Locate in this the last occurrence of the BMP code point <code>c</code>
-   * in the range [<TT>start</TT>, <TT>start + length</TT>),
+   * Locate in this the last occurrence of the BMP code point `c`
+   * in the range [`start`, `start + length`),
    * using bitwise comparison.
    * @param c The code unit to search for.
    * @param start the offset into this at which to start matching
    * @param length the number of characters in this to search
-   * @return The offset into this of <TT>c</TT>, or -1 if not found.
+   * @return The offset into this of `c`, or -1 if not found.
    * @stable ICU 2.0
    */
-  inline int32_t lastIndexOf(UChar c,
+  inline int32_t lastIndexOf(char16_t c,
               int32_t start,
               int32_t length) const;
 
   /**
-   * Locate in this the last occurrence of the code point <TT>c</TT>
-   * in the range [<TT>start</TT>, <TT>start + length</TT>),
+   * Locate in this the last occurrence of the code point `c`
+   * in the range [`start`, `start + length`),
    * using bitwise comparison.
    *
    * @param c The code point to search for.
    * @param start the offset into this at which to start matching
    * @param length the number of characters in this to search
-   * @return The offset into this of <TT>c</TT>, or -1 if not found.
+   * @return The offset into this of `c`, or -1 if not found.
    * @stable ICU 2.0
    */
   inline int32_t lastIndexOf(UChar32 c,
@@ -1320,32 +1321,32 @@
   /* Character access */
 
   /**
-   * Return the code unit at offset <tt>offset</tt>.
+   * Return the code unit at offset `offset`.
    * If the offset is not valid (0..length()-1) then U+ffff is returned.
    * @param offset a valid offset into the text
-   * @return the code unit at offset <tt>offset</tt>
+   * @return the code unit at offset `offset`
    *         or 0xffff if the offset is not valid for this string
    * @stable ICU 2.0
    */
-  inline UChar charAt(int32_t offset) const;
+  inline char16_t charAt(int32_t offset) const;
 
   /**
-   * Return the code unit at offset <tt>offset</tt>.
+   * Return the code unit at offset `offset`.
    * If the offset is not valid (0..length()-1) then U+ffff is returned.
    * @param offset a valid offset into the text
-   * @return the code unit at offset <tt>offset</tt>
+   * @return the code unit at offset `offset`
    * @stable ICU 2.0
    */
-  inline UChar operator[] (int32_t offset) const;
+  inline char16_t operator[] (int32_t offset) const;
 
   /**
    * Return the code point that contains the code unit
-   * at offset <tt>offset</tt>.
+   * at offset `offset`.
    * If the offset is not valid (0..length()-1) then U+ffff is returned.
    * @param offset a valid offset into the text
    * that indicates the text offset of any of the code units
    * that will be assembled into a code point (21-bit value) and returned
-   * @return the code point of text at <tt>offset</tt>
+   * @return the code point of text at `offset`
    *         or 0xffff if the offset is not valid for this string
    * @stable ICU 2.0
    */
@@ -1402,33 +1403,33 @@
    * This behaves like CharacterIterator::move32(delta, kCurrent).
    *
    * Behavior for out-of-bounds indexes:
-   * <code>moveIndex32</code> pins the input index to 0..length(), i.e.,
+   * `moveIndex32` pins the input index to 0..length(), i.e.,
    * if the input index<0 then it is pinned to 0;
    * if it is index>length() then it is pinned to length().
-   * Afterwards, the index is moved by <code>delta</code> code points
+   * Afterwards, the index is moved by `delta` code points
    * forward or backward,
    * but no further backward than to 0 and no further forward than to length().
    * The resulting index return value will be in between 0 and length(), inclusively.
    *
    * Examples:
-   * <pre>
-   * // s has code points 'a' U+10000 'b' U+10ffff U+2029
-   * UnicodeString s=UNICODE_STRING("a\\U00010000b\\U0010ffff\\u2029", 31).unescape();
+   * \code
+   *     // s has code points 'a' U+10000 'b' U+10ffff U+2029
+   *     UnicodeString s(u"a\U00010000b\U0010ffff\u2029");
    *
-   * // initial index: position of U+10000
-   * int32_t index=1;
+   *     // initial index: position of U+10000
+   *     int32_t index=1;
    *
-   * // the following examples will all result in index==4, position of U+10ffff
+   *     // the following examples will all result in index==4, position of U+10ffff
    *
-   * // skip 2 code points from some position in the string
-   * index=s.moveIndex32(index, 2); // skips U+10000 and 'b'
+   *     // skip 2 code points from some position in the string
+   *     index=s.moveIndex32(index, 2); // skips U+10000 and 'b'
    *
-   * // go to the 3rd code point from the start of s (0-based)
-   * index=s.moveIndex32(0, 3); // skips 'a', U+10000, and 'b'
+   *     // go to the 3rd code point from the start of s (0-based)
+   *     index=s.moveIndex32(0, 3); // skips 'a', U+10000, and 'b'
    *
-   * // go to the next-to-last code point of s
-   * index=s.moveIndex32(s.length(), -2); // backward-skips U+2029 and U+10ffff
-   * </pre>
+   *     // go to the next-to-last code point of s
+   *     index=s.moveIndex32(s.length(), -2); // backward-skips U+2029 and U+10ffff
+   * \endcode
    *
    * @param index input code unit index
    * @param delta (signed) code point count to move the index forward or backward
@@ -1442,22 +1443,22 @@
 
   /**
    * Copy the characters in the range
-   * [<tt>start</tt>, <tt>start + length</tt>) into the array <tt>dst</tt>,
-   * beginning at <tt>dstStart</tt>.
-   * If the string aliases to <code>dst</code> itself as an external buffer,
+   * [`start`, `start + length`) into the array `dst`,
+   * beginning at `dstStart`.
+   * If the string aliases to `dst` itself as an external buffer,
    * then extract() will not copy the contents.
    *
    * @param start offset of first character which will be copied into the array
    * @param length the number of characters to extract
-   * @param dst array in which to copy characters.  The length of <tt>dst</tt>
-   * must be at least (<tt>dstStart + length</tt>).
-   * @param dstStart the offset in <TT>dst</TT> where the first character
+   * @param dst array in which to copy characters.  The length of `dst`
+   * must be at least (`dstStart + length`).
+   * @param dstStart the offset in `dst` where the first character
    * will be extracted
    * @stable ICU 2.0
    */
   inline void extract(int32_t start,
            int32_t length,
-           UChar *dst,
+           Char16Ptr dst,
            int32_t dstStart = 0) const;
 
   /**
@@ -1472,27 +1473,26 @@
    * If the string itself does not fit into dest
    * (length()>destCapacity) then the error code is set to U_BUFFER_OVERFLOW_ERROR.
    *
-   * If the string aliases to <code>dest</code> itself as an external buffer,
+   * If the string aliases to `dest` itself as an external buffer,
    * then extract() will not copy the contents.
    *
    * @param dest Destination string buffer.
-   * @param destCapacity Number of UChars available at dest.
+   * @param destCapacity Number of char16_ts available at dest.
    * @param errorCode ICU error code.
    * @return length()
    * @stable ICU 2.0
    */
   int32_t
-  extract(UChar *dest, int32_t destCapacity,
+  extract(Char16Ptr dest, int32_t destCapacity,
           UErrorCode &errorCode) const;
 
   /**
    * Copy the characters in the range
-   * [<tt>start</tt>, <tt>start + length</tt>) into the  UnicodeString
-   * <tt>target</tt>.
+   * [`start`, `start + length`) into the  UnicodeString
+   * `target`.
    * @param start offset of first character which will be copied
    * @param length the number of characters to extract
    * @param target UnicodeString into which to copy characters.
-   * @return A reference to <TT>target</TT>
    * @stable ICU 2.0
    */
   inline void extract(int32_t start,
@@ -1500,28 +1500,27 @@
            UnicodeString& target) const;
 
   /**
-   * Copy the characters in the range [<tt>start</tt>, <tt>limit</tt>)
-   * into the array <tt>dst</tt>, beginning at <tt>dstStart</tt>.
+   * Copy the characters in the range [`start`, `limit`)
+   * into the array `dst`, beginning at `dstStart`.
    * @param start offset of first character which will be copied into the array
    * @param limit offset immediately following the last character to be copied
-   * @param dst array in which to copy characters.  The length of <tt>dst</tt>
-   * must be at least (<tt>dstStart + (limit - start)</tt>).
-   * @param dstStart the offset in <TT>dst</TT> where the first character
+   * @param dst array in which to copy characters.  The length of `dst`
+   * must be at least (`dstStart + (limit - start)`).
+   * @param dstStart the offset in `dst` where the first character
    * will be extracted
    * @stable ICU 2.0
    */
   inline void extractBetween(int32_t start,
               int32_t limit,
-              UChar *dst,
+              char16_t *dst,
               int32_t dstStart = 0) const;
 
   /**
-   * Copy the characters in the range [<tt>start</tt>, <tt>limit</tt>)
-   * into the UnicodeString <tt>target</tt>.  Replaceable API.
+   * Copy the characters in the range [`start`, `limit`)
+   * into the UnicodeString `target`.  Replaceable API.
    * @param start offset of first character which will be copied
    * @param limit offset immediately following the last character to be copied
    * @param target UnicodeString into which to copy characters.
-   * @return A reference to <TT>target</TT>
    * @stable ICU 2.0
    */
   virtual void extractBetween(int32_t start,
@@ -1529,12 +1528,12 @@
               UnicodeString& target) const;
 
   /**
-   * Copy the characters in the range 
-   * [<tt>start</TT>, <tt>start + startLength</TT>) into an array of characters.
+   * Copy the characters in the range
+   * [`start`, `start + startLength`) into an array of characters.
    * All characters must be invariant (see utypes.h).
    * Use US_INV as the last, signature-distinguishing parameter.
    *
-   * This function does not write any more than <code>targetCapacity</code>
+   * This function does not write any more than `targetCapacity`
    * characters but returns the length of the entire output string
    * so that one can allocate a larger buffer and call the function again
    * if necessary.
@@ -1559,9 +1558,9 @@
 
   /**
    * Copy the characters in the range
-   * [<tt>start</TT>, <tt>start + length</TT>) into an array of characters
+   * [`start`, `start + length`) into an array of characters
    * in the platform's default codepage.
-   * This function does not write any more than <code>targetLength</code>
+   * This function does not write any more than `targetLength`
    * characters but returns the length of the entire output string
    * so that one can allocate a larger buffer and call the function again
    * if necessary.
@@ -1571,8 +1570,8 @@
    * @param startLength the number of characters to extract
    * @param target the target buffer for extraction
    * @param targetLength the length of the target buffer
-   * If <TT>target</TT> is NULL, then the number of bytes required for
-   * <TT>target</TT> is returned.
+   * If `target` is NULL, then the number of bytes required for
+   * `target` is returned.
    * @return the output string length, not including the terminating NUL
    * @stable ICU 2.0
    */
@@ -1587,7 +1586,7 @@
 
   /**
    * Copy the characters in the range
-   * [<tt>start</TT>, <tt>start + length</TT>) into an array of characters
+   * [`start`, `start + length`) into an array of characters
    * in a specified codepage.
    * The output string is NUL-terminated.
    *
@@ -1601,11 +1600,11 @@
    * @param target the target buffer for extraction
    * @param codepage the desired codepage for the characters.  0 has
    * the special meaning of the default codepage
-   * If <code>codepage</code> is an empty string (<code>""</code>),
+   * If `codepage` is an empty string (`""`),
    * then a simple conversion is performed on the codepage-invariant
    * subset ("invariant characters") of the platform encoding. See utypes.h.
-   * If <TT>target</TT> is NULL, then the number of bytes required for
-   * <TT>target</TT> is returned. It is assumed that the target is big enough
+   * If `target` is NULL, then the number of bytes required for
+   * `target` is returned. It is assumed that the target is big enough
    * to fit all of the characters.
    * @return the output string length, not including the terminating NUL
    * @stable ICU 2.0
@@ -1617,9 +1616,9 @@
 
   /**
    * Copy the characters in the range
-   * [<tt>start</TT>, <tt>start + length</TT>) into an array of characters
+   * [`start`, `start + length`) into an array of characters
    * in a specified codepage.
-   * This function does not write any more than <code>targetLength</code>
+   * This function does not write any more than `targetLength`
    * characters but returns the length of the entire output string
    * so that one can allocate a larger buffer and call the function again
    * if necessary.
@@ -1636,11 +1635,11 @@
    * @param targetLength the length of the target buffer
    * @param codepage the desired codepage for the characters.  0 has
    * the special meaning of the default codepage
-   * If <code>codepage</code> is an empty string (<code>""</code>),
+   * If `codepage` is an empty string (`""`),
    * then a simple conversion is performed on the codepage-invariant
    * subset ("invariant characters") of the platform encoding. See utypes.h.
-   * If <TT>target</TT> is NULL, then the number of bytes required for
-   * <TT>target</TT> is returned.
+   * If `target` is NULL, then the number of bytes required for
+   * `target` is returned.
    * @return the output string length, not including the terminating NUL
    * @stable ICU 2.0
    */
@@ -1713,8 +1712,6 @@
    */
   void toUTF8(ByteSink &sink) const;
 
-#if U_HAVE_STD_STRING
-
   /**
    * Convert the UnicodeString to UTF-8 and append the result
    * to a standard string.
@@ -1729,13 +1726,11 @@
    */
   template<typename StringClass>
   StringClass &toUTF8String(StringClass &result) const {
-    StringByteSink<StringClass> sbs(&result);
+    StringByteSink<StringClass> sbs(&result, length());
     toUTF8(sbs);
     return result;
   }
 
-#endif
-
   /**
    * Convert the UnicodeString to UTF-32.
    * Unpaired surrogates are replaced with U+FFFD.
@@ -1757,7 +1752,7 @@
 
   /**
    * Return the length of the UnicodeString object.
-   * The length is the number of UChar code units are in the UnicodeString.
+   * The length is the number of char16_t code units are in the UnicodeString.
    * If you want the number of code points, please use countChar32().
    * @return the length of the UnicodeString object
    * @see countChar32
@@ -1766,14 +1761,14 @@
   inline int32_t length(void) const;
 
   /**
-   * Count Unicode code points in the length UChar code units of the string.
-   * A code point may occupy either one or two UChar code units.
+   * Count Unicode code points in the length char16_t code units of the string.
+   * A code point may occupy either one or two char16_t code units.
    * Counting code points involves reading all code units.
    *
    * This functions is basically the inverse of moveIndex32().
    *
    * @param start the index of the first code unit to check
-   * @param length the number of UChar code units to check
+   * @param length the number of char16_t code units to check
    * @return the number of code points in the specified code units
    * @see length
    * @stable ICU 2.0
@@ -1782,7 +1777,7 @@
   countChar32(int32_t start=0, int32_t length=INT32_MAX) const;
 
   /**
-   * Check if the length UChar code units of the string
+   * Check if the length char16_t code units of the string
    * contain more Unicode code points than a certain number.
    * This is more efficient than counting all code points in this part of the string
    * and comparing that number with a threshold.
@@ -1790,10 +1785,10 @@
    * falls within a certain range, and
    * never needs to count more than 'number+1' code points.
    * Logically equivalent to (countChar32(start, length)>number).
-   * A Unicode code point may occupy either one or two UChar code units.
+   * A Unicode code point may occupy either one or two char16_t code units.
    *
    * @param start the index of the first code unit to check (0 for the entire string)
-   * @param length the number of UChar code units to check
+   * @param length the number of char16_t code units to check
    *               (use INT32_MAX for the entire string; remember that start/length
    *                values are pinned)
    * @param number The number of code points in the (sub)string is compared against
@@ -1809,7 +1804,7 @@
 
   /**
    * Determine if this string is empty.
-   * @return TRUE if this string contains 0 characters, FALSE otherwise.
+   * @return true if this string contains 0 characters, false otherwise.
    * @stable ICU 2.0
    */
   inline UBool isEmpty(void) const;
@@ -1819,7 +1814,7 @@
    * This is useful together with the getBuffer functions.
    * See there for details.
    *
-   * @return the number of UChars available in the internal buffer
+   * @return the number of char16_ts available in the internal buffer
    * @see getBuffer
    * @stable ICU 2.0
    */
@@ -1837,12 +1832,12 @@
   /**
    * Determine if this object contains a valid string.
    * A bogus string has no value. It is different from an empty string,
-   * although in both cases isEmpty() returns TRUE and length() returns 0.
+   * although in both cases isEmpty() returns true and length() returns 0.
    * setToBogus() and isBogus() can be used to indicate that no string value is available.
    * For a bogus string, getBuffer() and getTerminatedBuffer() return NULL, and
    * length() returns 0.
    *
-   * @return TRUE if the string is bogus/invalid, FALSE otherwise
+   * @return true if the string is bogus/invalid, false otherwise
    * @see setToBogus()
    * @stable ICU 2.0
    */
@@ -1857,7 +1852,7 @@
 
   /**
    * Assignment operator.  Replace the characters in this UnicodeString
-   * with the characters from <TT>srcText</TT>.
+   * with the characters from `srcText`.
    *
    * Starting with ICU 2.4, the assignment operator and the copy constructor
    * allocate a new buffer and copy the buffer contents even for readonly aliases.
@@ -1878,7 +1873,7 @@
   /**
    * Almost the same as the assignment operator.
    * Replace the characters in this UnicodeString
-   * with the characters from <code>srcText</code>.
+   * with the characters from `srcText`.
    *
    * This function works the same as the assignment operator
    * for all strings except for ones that are readonly aliases.
@@ -1902,36 +1897,20 @@
    */
   UnicodeString &fastCopyFrom(const UnicodeString &src);
 
-#ifndef U_HIDE_DRAFT_API
-#if U_HAVE_RVALUE_REFERENCES
   /**
-   * Move assignment operator, might leave src in bogus state.
+   * Move assignment operator; might leave src in bogus state.
    * This string will have the same contents and state that the source string had.
    * The behavior is undefined if *this and src are the same object.
    * @param src source string
    * @return *this
-   * @draft ICU 56
+   * @stable ICU 56
    */
-  UnicodeString &operator=(UnicodeString &&src) U_NOEXCEPT {
-    return moveFrom(src);
-  }
-#endif
-  /**
-   * Move assignment, might leave src in bogus state.
-   * This string will have the same contents and state that the source string had.
-   * The behavior is undefined if *this and src are the same object.
-   *
-   * Can be called explicitly, does not need C++11 support.
-   * @param src source string
-   * @return *this
-   * @draft ICU 56
-   */
-  UnicodeString &moveFrom(UnicodeString &src) U_NOEXCEPT;
+  UnicodeString &operator=(UnicodeString &&src) U_NOEXCEPT;
 
   /**
    * Swap strings.
    * @param other other string
-   * @draft ICU 56
+   * @stable ICU 56
    */
   void swap(UnicodeString &other) U_NOEXCEPT;
 
@@ -1939,26 +1918,25 @@
    * Non-member UnicodeString swap function.
    * @param s1 will get s2's contents and state
    * @param s2 will get s1's contents and state
-   * @draft ICU 56
+   * @stable ICU 56
    */
-  friend U_COMMON_API inline void U_EXPORT2
+  friend inline void U_EXPORT2
   swap(UnicodeString &s1, UnicodeString &s2) U_NOEXCEPT {
     s1.swap(s2);
   }
-#endif  /* U_HIDE_DRAFT_API */
 
   /**
    * Assignment operator.  Replace the characters in this UnicodeString
-   * with the code unit <TT>ch</TT>.
+   * with the code unit `ch`.
    * @param ch the code unit to replace
    * @return a reference to this
    * @stable ICU 2.0
    */
-  inline UnicodeString& operator= (UChar ch);
+  inline UnicodeString& operator= (char16_t ch);
 
   /**
    * Assignment operator.  Replace the characters in this UnicodeString
-   * with the code point <TT>ch</TT>.
+   * with the code point `ch`.
    * @param ch the code point to replace
    * @return a reference to this
    * @stable ICU 2.0
@@ -1967,11 +1945,11 @@
 
   /**
    * Set the text in the UnicodeString object to the characters
-   * in <TT>srcText</TT> in the range
-   * [<TT>srcStart</TT>, <TT>srcText.length()</TT>).
-   * <TT>srcText</TT> is not modified.
+   * in `srcText` in the range
+   * [`srcStart`, `srcText.length()`).
+   * `srcText` is not modified.
    * @param srcText the source for the new characters
-   * @param srcStart the offset into <TT>srcText</TT> where new characters
+   * @param srcStart the offset into `srcText` where new characters
    * will be obtained
    * @return a reference to this
    * @stable ICU 2.2
@@ -1981,13 +1959,13 @@
 
   /**
    * Set the text in the UnicodeString object to the characters
-   * in <TT>srcText</TT> in the range
-   * [<TT>srcStart</TT>, <TT>srcStart + srcLength</TT>).
-   * <TT>srcText</TT> is not modified.
+   * in `srcText` in the range
+   * [`srcStart`, `srcStart + srcLength`).
+   * `srcText` is not modified.
    * @param srcText the source for the new characters
-   * @param srcStart the offset into <TT>srcText</TT> where new characters
+   * @param srcStart the offset into `srcText` where new characters
    * will be obtained
-   * @param srcLength the number of characters in <TT>srcText</TT> in the
+   * @param srcLength the number of characters in `srcText` in the
    * replace string.
    * @return a reference to this
    * @stable ICU 2.0
@@ -1998,8 +1976,8 @@
 
   /**
    * Set the text in the UnicodeString object to the characters in
-   * <TT>srcText</TT>.
-   * <TT>srcText</TT> is not modified.
+   * `srcText`.
+   * `srcText` is not modified.
    * @param srcText the source for the new characters
    * @return a reference to this
    * @stable ICU 2.0
@@ -2008,37 +1986,37 @@
 
   /**
    * Set the characters in the UnicodeString object to the characters
-   * in <TT>srcChars</TT>. <TT>srcChars</TT> is not modified.
+   * in `srcChars`. `srcChars` is not modified.
    * @param srcChars the source for the new characters
    * @param srcLength the number of Unicode characters in srcChars.
    * @return a reference to this
    * @stable ICU 2.0
    */
-  inline UnicodeString& setTo(const UChar *srcChars,
+  inline UnicodeString& setTo(const char16_t *srcChars,
                int32_t srcLength);
 
   /**
    * Set the characters in the UnicodeString object to the code unit
-   * <TT>srcChar</TT>.
+   * `srcChar`.
    * @param srcChar the code unit which becomes the UnicodeString's character
    * content
    * @return a reference to this
    * @stable ICU 2.0
    */
-  UnicodeString& setTo(UChar srcChar);
+  inline UnicodeString& setTo(char16_t srcChar);
 
   /**
    * Set the characters in the UnicodeString object to the code point
-   * <TT>srcChar</TT>.
+   * `srcChar`.
    * @param srcChar the code point which becomes the UnicodeString's character
    * content
    * @return a reference to this
    * @stable ICU 2.0
    */
-  UnicodeString& setTo(UChar32 srcChar);
+  inline UnicodeString& setTo(UChar32 srcChar);
 
   /**
-   * Aliasing setTo() function, analogous to the readonly-aliasing UChar* constructor.
+   * Aliasing setTo() function, analogous to the readonly-aliasing char16_t* constructor.
    * The text will be used for the UnicodeString object, but
    * it will not be released when the UnicodeString is destroyed.
    * This has copy-on-write semantics:
@@ -2051,21 +2029,21 @@
    * When using fastCopyFrom(), the text will be aliased again,
    * so that both strings then alias the same readonly-text.
    *
-   * @param isTerminated specifies if <code>text</code> is <code>NUL</code>-terminated.
-   *                     This must be true if <code>textLength==-1</code>.
+   * @param isTerminated specifies if `text` is `NUL`-terminated.
+   *                     This must be true if `textLength==-1`.
    * @param text The characters to alias for the UnicodeString.
-   * @param textLength The number of Unicode characters in <code>text</code> to alias.
+   * @param textLength The number of Unicode characters in `text` to alias.
    *                   If -1, then this constructor will determine the length
-   *                   by calling <code>u_strlen()</code>.
+   *                   by calling `u_strlen()`.
    * @return a reference to this
    * @stable ICU 2.0
    */
   UnicodeString &setTo(UBool isTerminated,
-                       const UChar *text,
+                       ConstChar16Ptr text,
                        int32_t textLength);
 
   /**
-   * Aliasing setTo() function, analogous to the writable-aliasing UChar* constructor.
+   * Aliasing setTo() function, analogous to the writable-aliasing char16_t* constructor.
    * The text will be used for the UnicodeString object, but
    * it will not be released when the UnicodeString is destroyed.
    * This has write-through semantics:
@@ -2074,22 +2052,22 @@
    * a new buffer will be allocated and the contents copied as with regularly
    * constructed strings.
    * In an assignment to another UnicodeString, the buffer will be copied.
-   * The extract(UChar *dst) function detects whether the dst pointer is the same
+   * The extract(Char16Ptr dst) function detects whether the dst pointer is the same
    * as the string buffer itself and will in this case not copy the contents.
    *
    * @param buffer The characters to alias for the UnicodeString.
-   * @param buffLength The number of Unicode characters in <code>buffer</code> to alias.
-   * @param buffCapacity The size of <code>buffer</code> in UChars.
+   * @param buffLength The number of Unicode characters in `buffer` to alias.
+   * @param buffCapacity The size of `buffer` in char16_ts.
    * @return a reference to this
    * @stable ICU 2.0
    */
-  UnicodeString &setTo(UChar *buffer,
+  UnicodeString &setTo(char16_t *buffer,
                        int32_t buffLength,
                        int32_t buffCapacity);
 
   /**
    * Make this UnicodeString object invalid.
-   * The string will test TRUE with isBogus().
+   * The string will test true with isBogus().
    *
    * A bogus string has no value. It is different from an empty string.
    * It can be used to indicate that no string value is available.
@@ -2119,8 +2097,7 @@
    *   s.truncate(0);        // set to an empty string (complete truncation), or
    *   s=UnicodeString();    // assign an empty string, or
    *   s.setTo((UChar32)-1); // set to a pseudo code point that is out of range, or
-   *   static const UChar nul=0;
-   *   s.setTo(&nul, 0);     // set to an empty C Unicode string
+   *   s.setTo(u"", 0);      // set to an empty C Unicode string
    * }
    * \endcode
    *
@@ -2137,22 +2114,22 @@
    * @stable ICU 2.0
    */
   UnicodeString& setCharAt(int32_t offset,
-               UChar ch);
+               char16_t ch);
 
 
   /* Append operations */
 
   /**
-   * Append operator. Append the code unit <TT>ch</TT> to the UnicodeString
+   * Append operator. Append the code unit `ch` to the UnicodeString
    * object.
    * @param ch the code unit to be appended
    * @return a reference to this
    * @stable ICU 2.0
    */
- inline  UnicodeString& operator+= (UChar ch);
+ inline  UnicodeString& operator+= (char16_t ch);
 
   /**
-   * Append operator. Append the code point <TT>ch</TT> to the UnicodeString
+   * Append operator. Append the code point `ch` to the UnicodeString
    * object.
    * @param ch the code point to be appended
    * @return a reference to this
@@ -2161,8 +2138,8 @@
  inline  UnicodeString& operator+= (UChar32 ch);
 
   /**
-   * Append operator. Append the characters in <TT>srcText</TT> to the
-   * UnicodeString object. <TT>srcText</TT> is not modified.
+   * Append operator. Append the characters in `srcText` to the
+   * UnicodeString object. `srcText` is not modified.
    * @param srcText the source for the new characters
    * @return a reference to this
    * @stable ICU 2.0
@@ -2171,14 +2148,14 @@
 
   /**
    * Append the characters
-   * in <TT>srcText</TT> in the range
-   * [<TT>srcStart</TT>, <TT>srcStart + srcLength</TT>) to the
-   * UnicodeString object at offset <TT>start</TT>. <TT>srcText</TT>
+   * in `srcText` in the range
+   * [`srcStart`, `srcStart + srcLength`) to the
+   * UnicodeString object at offset `start`. `srcText`
    * is not modified.
    * @param srcText the source for the new characters
-   * @param srcStart the offset into <TT>srcText</TT> where new characters
+   * @param srcStart the offset into `srcText` where new characters
    * will be obtained
-   * @param srcLength the number of characters in <TT>srcText</TT> in
+   * @param srcLength the number of characters in `srcText` in
    * the append string
    * @return a reference to this
    * @stable ICU 2.0
@@ -2188,8 +2165,8 @@
             int32_t srcLength);
 
   /**
-   * Append the characters in <TT>srcText</TT> to the UnicodeString object.
-   * <TT>srcText</TT> is not modified.
+   * Append the characters in `srcText` to the UnicodeString object.
+   * `srcText` is not modified.
    * @param srcText the source for the new characters
    * @return a reference to this
    * @stable ICU 2.0
@@ -2197,44 +2174,44 @@
   inline UnicodeString& append(const UnicodeString& srcText);
 
   /**
-   * Append the characters in <TT>srcChars</TT> in the range
-   * [<TT>srcStart</TT>, <TT>srcStart + srcLength</TT>) to the UnicodeString
+   * Append the characters in `srcChars` in the range
+   * [`srcStart`, `srcStart + srcLength`) to the UnicodeString
    * object at offset
-   * <TT>start</TT>. <TT>srcChars</TT> is not modified.
+   * `start`. `srcChars` is not modified.
    * @param srcChars the source for the new characters
-   * @param srcStart the offset into <TT>srcChars</TT> where new characters
+   * @param srcStart the offset into `srcChars` where new characters
    * will be obtained
-   * @param srcLength the number of characters in <TT>srcChars</TT> in
-   *                  the append string; can be -1 if <TT>srcChars</TT> is NUL-terminated
+   * @param srcLength the number of characters in `srcChars` in
+   *                  the append string; can be -1 if `srcChars` is NUL-terminated
    * @return a reference to this
    * @stable ICU 2.0
    */
-  inline UnicodeString& append(const UChar *srcChars,
+  inline UnicodeString& append(const char16_t *srcChars,
             int32_t srcStart,
             int32_t srcLength);
 
   /**
-   * Append the characters in <TT>srcChars</TT> to the UnicodeString object
-   * at offset <TT>start</TT>. <TT>srcChars</TT> is not modified.
+   * Append the characters in `srcChars` to the UnicodeString object
+   * at offset `start`. `srcChars` is not modified.
    * @param srcChars the source for the new characters
-   * @param srcLength the number of Unicode characters in <TT>srcChars</TT>;
-   *                  can be -1 if <TT>srcChars</TT> is NUL-terminated
+   * @param srcLength the number of Unicode characters in `srcChars`;
+   *                  can be -1 if `srcChars` is NUL-terminated
    * @return a reference to this
    * @stable ICU 2.0
    */
-  inline UnicodeString& append(const UChar *srcChars,
+  inline UnicodeString& append(ConstChar16Ptr srcChars,
             int32_t srcLength);
 
   /**
-   * Append the code unit <TT>srcChar</TT> to the UnicodeString object.
+   * Append the code unit `srcChar` to the UnicodeString object.
    * @param srcChar the code unit to append
    * @return a reference to this
    * @stable ICU 2.0
    */
-  inline UnicodeString& append(UChar srcChar);
+  inline UnicodeString& append(char16_t srcChar);
 
   /**
-   * Append the code point <TT>srcChar</TT> to the UnicodeString object.
+   * Append the code point `srcChar` to the UnicodeString object.
    * @param srcChar the code point to append
    * @return a reference to this
    * @stable ICU 2.0
@@ -2245,14 +2222,14 @@
   /* Insert operations */
 
   /**
-   * Insert the characters in <TT>srcText</TT> in the range
-   * [<TT>srcStart</TT>, <TT>srcStart + srcLength</TT>) into the UnicodeString
-   * object at offset <TT>start</TT>. <TT>srcText</TT> is not modified.
+   * Insert the characters in `srcText` in the range
+   * [`srcStart`, `srcStart + srcLength`) into the UnicodeString
+   * object at offset `start`. `srcText` is not modified.
    * @param start the offset where the insertion begins
    * @param srcText the source for the new characters
-   * @param srcStart the offset into <TT>srcText</TT> where new characters
+   * @param srcStart the offset into `srcText` where new characters
    * will be obtained
-   * @param srcLength the number of characters in <TT>srcText</TT> in
+   * @param srcLength the number of characters in `srcText` in
    * the insert string
    * @return a reference to this
    * @stable ICU 2.0
@@ -2263,8 +2240,8 @@
             int32_t srcLength);
 
   /**
-   * Insert the characters in <TT>srcText</TT> into the UnicodeString object
-   * at offset <TT>start</TT>. <TT>srcText</TT> is not modified.
+   * Insert the characters in `srcText` into the UnicodeString object
+   * at offset `start`. `srcText` is not modified.
    * @param start the offset where the insertion begins
    * @param srcText the source for the new characters
    * @return a reference to this
@@ -2274,26 +2251,26 @@
             const UnicodeString& srcText);
 
   /**
-   * Insert the characters in <TT>srcChars</TT> in the range
-   * [<TT>srcStart</TT>, <TT>srcStart + srcLength</TT>) into the UnicodeString
-   *  object at offset <TT>start</TT>. <TT>srcChars</TT> is not modified.
+   * Insert the characters in `srcChars` in the range
+   * [`srcStart`, `srcStart + srcLength`) into the UnicodeString
+   *  object at offset `start`. `srcChars` is not modified.
    * @param start the offset at which the insertion begins
    * @param srcChars the source for the new characters
-   * @param srcStart the offset into <TT>srcChars</TT> where new characters
+   * @param srcStart the offset into `srcChars` where new characters
    * will be obtained
-   * @param srcLength the number of characters in <TT>srcChars</TT>
+   * @param srcLength the number of characters in `srcChars`
    * in the insert string
    * @return a reference to this
    * @stable ICU 2.0
    */
   inline UnicodeString& insert(int32_t start,
-            const UChar *srcChars,
+            const char16_t *srcChars,
             int32_t srcStart,
             int32_t srcLength);
 
   /**
-   * Insert the characters in <TT>srcChars</TT> into the UnicodeString object
-   * at offset <TT>start</TT>. <TT>srcChars</TT> is not modified.
+   * Insert the characters in `srcChars` into the UnicodeString object
+   * at offset `start`. `srcChars` is not modified.
    * @param start the offset where the insertion begins
    * @param srcChars the source for the new characters
    * @param srcLength the number of Unicode characters in srcChars.
@@ -2301,23 +2278,23 @@
    * @stable ICU 2.0
    */
   inline UnicodeString& insert(int32_t start,
-            const UChar *srcChars,
+            ConstChar16Ptr srcChars,
             int32_t srcLength);
 
   /**
-   * Insert the code unit <TT>srcChar</TT> into the UnicodeString object at
-   * offset <TT>start</TT>.
+   * Insert the code unit `srcChar` into the UnicodeString object at
+   * offset `start`.
    * @param start the offset at which the insertion occurs
    * @param srcChar the code unit to insert
    * @return a reference to this
    * @stable ICU 2.0
    */
   inline UnicodeString& insert(int32_t start,
-            UChar srcChar);
+            char16_t srcChar);
 
   /**
-   * Insert the code point <TT>srcChar</TT> into the UnicodeString object at
-   * offset <TT>start</TT>.
+   * Insert the code point `srcChar` into the UnicodeString object at
+   * offset `start`.
    * @param start the offset at which the insertion occurs
    * @param srcChar the code point to insert
    * @return a reference to this
@@ -2331,22 +2308,22 @@
 
   /**
    * Replace the characters in the range
-   * [<TT>start</TT>, <TT>start + length</TT>) with the characters in
-   * <TT>srcText</TT> in the range
-   * [<TT>srcStart</TT>, <TT>srcStart + srcLength</TT>).
-   * <TT>srcText</TT> is not modified.
+   * [`start`, `start + length`) with the characters in
+   * `srcText` in the range
+   * [`srcStart`, `srcStart + srcLength`).
+   * `srcText` is not modified.
    * @param start the offset at which the replace operation begins
    * @param length the number of characters to replace. The character at
-   * <TT>start + length</TT> is not modified.
+   * `start + length` is not modified.
    * @param srcText the source for the new characters
-   * @param srcStart the offset into <TT>srcText</TT> where new characters
+   * @param srcStart the offset into `srcText` where new characters
    * will be obtained
-   * @param srcLength the number of characters in <TT>srcText</TT> in
+   * @param srcLength the number of characters in `srcText` in
    * the replace string
    * @return a reference to this
    * @stable ICU 2.0
    */
-  UnicodeString& replace(int32_t start,
+  inline UnicodeString& replace(int32_t start,
              int32_t length,
              const UnicodeString& srcText,
              int32_t srcStart,
@@ -2354,50 +2331,50 @@
 
   /**
    * Replace the characters in the range
-   * [<TT>start</TT>, <TT>start + length</TT>)
-   * with the characters in <TT>srcText</TT>.  <TT>srcText</TT> is
+   * [`start`, `start + length`)
+   * with the characters in `srcText`.  `srcText` is
    *  not modified.
    * @param start the offset at which the replace operation begins
    * @param length the number of characters to replace. The character at
-   * <TT>start + length</TT> is not modified.
+   * `start + length` is not modified.
    * @param srcText the source for the new characters
    * @return a reference to this
    * @stable ICU 2.0
    */
-  UnicodeString& replace(int32_t start,
+  inline UnicodeString& replace(int32_t start,
              int32_t length,
              const UnicodeString& srcText);
 
   /**
    * Replace the characters in the range
-   * [<TT>start</TT>, <TT>start + length</TT>) with the characters in
-   * <TT>srcChars</TT> in the range
-   * [<TT>srcStart</TT>, <TT>srcStart + srcLength</TT>). <TT>srcChars</TT>
+   * [`start`, `start + length`) with the characters in
+   * `srcChars` in the range
+   * [`srcStart`, `srcStart + srcLength`). `srcChars`
    * is not modified.
    * @param start the offset at which the replace operation begins
    * @param length the number of characters to replace.  The character at
-   * <TT>start + length</TT> is not modified.
+   * `start + length` is not modified.
    * @param srcChars the source for the new characters
-   * @param srcStart the offset into <TT>srcChars</TT> where new characters
+   * @param srcStart the offset into `srcChars` where new characters
    * will be obtained
-   * @param srcLength the number of characters in <TT>srcChars</TT>
+   * @param srcLength the number of characters in `srcChars`
    * in the replace string
    * @return a reference to this
    * @stable ICU 2.0
    */
-  UnicodeString& replace(int32_t start,
+  inline UnicodeString& replace(int32_t start,
              int32_t length,
-             const UChar *srcChars,
+             const char16_t *srcChars,
              int32_t srcStart,
              int32_t srcLength);
 
   /**
    * Replace the characters in the range
-   * [<TT>start</TT>, <TT>start + length</TT>) with the characters in
-   * <TT>srcChars</TT>.  <TT>srcChars</TT> is not modified.
+   * [`start`, `start + length`) with the characters in
+   * `srcChars`.  `srcChars` is not modified.
    * @param start the offset at which the replace operation begins
    * @param length number of characters to replace.  The character at
-   * <TT>start + length</TT> is not modified.
+   * `start + length` is not modified.
    * @param srcChars the source for the new characters
    * @param srcLength the number of Unicode characters in srcChars
    * @return a reference to this
@@ -2405,31 +2382,31 @@
    */
   inline UnicodeString& replace(int32_t start,
              int32_t length,
-             const UChar *srcChars,
+             ConstChar16Ptr srcChars,
              int32_t srcLength);
 
   /**
    * Replace the characters in the range
-   * [<TT>start</TT>, <TT>start + length</TT>) with the code unit
-   * <TT>srcChar</TT>.
+   * [`start`, `start + length`) with the code unit
+   * `srcChar`.
    * @param start the offset at which the replace operation begins
    * @param length the number of characters to replace.  The character at
-   * <TT>start + length</TT> is not modified.
+   * `start + length` is not modified.
    * @param srcChar the new code unit
    * @return a reference to this
    * @stable ICU 2.0
    */
   inline UnicodeString& replace(int32_t start,
              int32_t length,
-             UChar srcChar);
+             char16_t srcChar);
 
   /**
    * Replace the characters in the range
-   * [<TT>start</TT>, <TT>start + length</TT>) with the code point
-   * <TT>srcChar</TT>.
+   * [`start`, `start + length`) with the code point
+   * `srcChar`.
    * @param start the offset at which the replace operation begins
    * @param length the number of characters to replace.  The character at
-   * <TT>start + length</TT> is not modified.
+   * `start + length` is not modified.
    * @param srcChar the new code point
    * @return a reference to this
    * @stable ICU 2.0
@@ -2437,8 +2414,8 @@
   UnicodeString& replace(int32_t start, int32_t length, UChar32 srcChar);
 
   /**
-   * Replace the characters in the range [<TT>start</TT>, <TT>limit</TT>)
-   * with the characters in <TT>srcText</TT>. <TT>srcText</TT> is not modified.
+   * Replace the characters in the range [`start`, `limit`)
+   * with the characters in `srcText`. `srcText` is not modified.
    * @param start the offset at which the replace operation begins
    * @param limit the offset immediately following the replace range
    * @param srcText the source for the new characters
@@ -2450,16 +2427,16 @@
                 const UnicodeString& srcText);
 
   /**
-   * Replace the characters in the range [<TT>start</TT>, <TT>limit</TT>)
-   * with the characters in <TT>srcText</TT> in the range
-   * [<TT>srcStart</TT>, <TT>srcLimit</TT>). <TT>srcText</TT> is not modified.
+   * Replace the characters in the range [`start`, `limit`)
+   * with the characters in `srcText` in the range
+   * [`srcStart`, `srcLimit`). `srcText` is not modified.
    * @param start the offset at which the replace operation begins
    * @param limit the offset immediately following the replace range
    * @param srcText the source for the new characters
-   * @param srcStart the offset into <TT>srcChars</TT> where new characters
+   * @param srcStart the offset into `srcChars` where new characters
    * will be obtained
    * @param srcLimit the offset immediately following the range to copy
-   * in <TT>srcText</TT>
+   * in `srcText`
    * @return a reference to this
    * @stable ICU 2.0
    */
@@ -2471,12 +2448,9 @@
 
   /**
    * Replace a substring of this object with the given text.
-   * @param start the beginning index, inclusive; <code>0 <= start
-   * <= limit</code>.
-   * @param limit the ending index, exclusive; <code>start <= limit
-   * <= length()</code>.
-   * @param text the text to replace characters <code>start</code>
-   * to <code>limit - 1</code>
+   * @param start the beginning index, inclusive; `0 <= start <= limit`.
+   * @param limit the ending index, exclusive; `start <= limit <= length()`.
+   * @param text the text to replace characters `start` to `limit - 1`
    * @stable ICU 2.0
    */
   virtual void handleReplaceBetween(int32_t start,
@@ -2485,7 +2459,7 @@
 
   /**
    * Replaceable API
-   * @return TRUE if it has MetaData
+   * @return true if it has MetaData
    * @stable ICU 2.4
    */
   virtual UBool hasMetaData() const;
@@ -2495,14 +2469,12 @@
    * information.  This method is used to duplicate or reorder substrings.
    * The destination index must not overlap the source range.
    *
-   * @param start the beginning index, inclusive; <code>0 <= start <=
-   * limit</code>.
-   * @param limit the ending index, exclusive; <code>start <= limit <=
-   * length()</code>.
+   * @param start the beginning index, inclusive; `0 <= start <= limit`.
+   * @param limit the ending index, exclusive; `start <= limit <= length()`.
    * @param dest the destination index.  The characters from
-   * <code>start..limit-1</code> will be copied to <code>dest</code>.
-   * Implementations of this method may assume that <code>dest <= start ||
-   * dest >= limit</code>.
+   *             `start..limit-1` will be copied to `dest`.
+   * Implementations of this method may assume that `dest <= start ||
+   * dest >= limit`.
    * @stable ICU 2.0
    */
   virtual void copy(int32_t start, int32_t limit, int32_t dest);
@@ -2523,7 +2495,7 @@
   /**
    * Replace all occurrences of characters in oldText with characters
    * in newText
-   * in the range [<TT>start</TT>, <TT>start + length</TT>).
+   * in the range [`start`, `start + length`).
    * @param start the start of the range in which replace will performed
    * @param length the length of the range in which replace will be performed
    * @param oldText the text containing the search text
@@ -2538,18 +2510,18 @@
 
   /**
    * Replace all occurrences of characters in oldText in the range
-   * [<TT>oldStart</TT>, <TT>oldStart + oldLength</TT>) with the characters
+   * [`oldStart`, `oldStart + oldLength`) with the characters
    * in newText in the range
-   * [<TT>newStart</TT>, <TT>newStart + newLength</TT>)
-   * in the range [<TT>start</TT>, <TT>start + length</TT>).
+   * [`newStart`, `newStart + newLength`)
+   * in the range [`start`, `start + length`).
    * @param start the start of the range in which replace will performed
    * @param length the length of the range in which replace will be performed
    * @param oldText the text containing the search text
-   * @param oldStart the start of the search range in <TT>oldText</TT>
-   * @param oldLength the length of the search range in <TT>oldText</TT>
+   * @param oldStart the start of the search range in `oldText`
+   * @param oldLength the length of the search range in `oldText`
    * @param newText the text containing the replacement text
-   * @param newStart the start of the replacement range in <TT>newText</TT>
-   * @param newLength the length of the replacement range in <TT>newText</TT>
+   * @param newStart the start of the replacement range in `newText`
+   * @param newLength the length of the replacement range in `newText`
    * @return a reference to this
    * @stable ICU 2.0
    */
@@ -2566,15 +2538,18 @@
   /* Remove operations */
 
   /**
-   * Remove all characters from the UnicodeString object.
+   * Removes all characters from the UnicodeString object and clears the bogus flag.
+   * This is the UnicodeString equivalent of std::string’s clear().
+   *
    * @return a reference to this
+   * @see setToBogus
    * @stable ICU 2.0
    */
-  inline UnicodeString& remove(void);
+  inline UnicodeString& remove();
 
   /**
    * Remove the characters in the range
-   * [<TT>start</TT>, <TT>start + length</TT>) from the UnicodeString object.
+   * [`start`, `start + length`) from the UnicodeString object.
    * @param start the offset of the first character to remove
    * @param length the number of characters to remove
    * @return a reference to this
@@ -2585,7 +2560,7 @@
 
   /**
    * Remove the characters in the range
-   * [<TT>start</TT>, <TT>limit</TT>) from the UnicodeString object.
+   * [`start`, `limit`) from the UnicodeString object.
    * @param start the offset of the first character to remove
    * @param limit the offset immediately following the range to remove
    * @return a reference to this
@@ -2596,8 +2571,8 @@
 
   /**
    * Retain only the characters in the range
-   * [<code>start</code>, <code>limit</code>) from the UnicodeString object.
-   * Removes characters before <code>start</code> and at and after <code>limit</code>.
+   * [`start`, `limit`) from the UnicodeString object.
+   * Removes characters before `start` and at and after `limit`.
    * @param start the offset of the first character to retain
    * @param limit the offset immediately following the range to retain
    * @return a reference to this
@@ -2608,37 +2583,37 @@
   /* Length operations */
 
   /**
-   * Pad the start of this UnicodeString with the character <TT>padChar</TT>.
+   * Pad the start of this UnicodeString with the character `padChar`.
    * If the length of this UnicodeString is less than targetLength,
    * length() - targetLength copies of padChar will be added to the
    * beginning of this UnicodeString.
    * @param targetLength the desired length of the string
    * @param padChar the character to use for padding. Defaults to
    * space (U+0020)
-   * @return TRUE if the text was padded, FALSE otherwise.
+   * @return true if the text was padded, false otherwise.
    * @stable ICU 2.0
    */
   UBool padLeading(int32_t targetLength,
-                    UChar padChar = 0x0020);
+                    char16_t padChar = 0x0020);
 
   /**
-   * Pad the end of this UnicodeString with the character <TT>padChar</TT>.
+   * Pad the end of this UnicodeString with the character `padChar`.
    * If the length of this UnicodeString is less than targetLength,
    * length() - targetLength copies of padChar will be added to the
    * end of this UnicodeString.
    * @param targetLength the desired length of the string
    * @param padChar the character to use for padding. Defaults to
    * space (U+0020)
-   * @return TRUE if the text was padded, FALSE otherwise.
+   * @return true if the text was padded, false otherwise.
    * @stable ICU 2.0
    */
   UBool padTrailing(int32_t targetLength,
-                     UChar padChar = 0x0020);
+                     char16_t padChar = 0x0020);
 
   /**
-   * Truncate this UnicodeString to the <TT>targetLength</TT>.
+   * Truncate this UnicodeString to the `targetLength`.
    * @param targetLength the desired length of this UnicodeString.
-   * @return TRUE if the text was truncated, FALSE otherwise
+   * @return true if the text was truncated, false otherwise
    * @stable ICU 2.0
    */
   inline UBool truncate(int32_t targetLength);
@@ -2661,7 +2636,7 @@
   inline UnicodeString& reverse(void);
 
   /**
-   * Reverse the range [<TT>start</TT>, <TT>start + length</TT>) in
+   * Reverse the range [`start`, `start + length`) in
    * this UnicodeString.
    * @param start the start of the range to reverse
    * @param length the number of characters to to reverse
@@ -2788,11 +2763,11 @@
    *                  break iterator is opened.
    *                  Otherwise the provided iterator is set to the string's text.
    * @param locale    The locale to consider.
+   * @param options   Options bit set, usually 0. See U_TITLECASE_NO_LOWERCASE,
+   *                  U_TITLECASE_NO_BREAK_ADJUSTMENT, U_TITLECASE_ADJUST_TO_CASED,
+   *                  U_TITLECASE_WHOLE_STRING, U_TITLECASE_SENTENCES.
    * @param options Options bit set, see ucasemap_open().
    * @return A reference to this.
-   * @see U_TITLECASE_NO_LOWERCASE
-   * @see U_TITLECASE_NO_BREAK_ADJUSTMENT
-   * @see ucasemap_open
    * @stable ICU 3.8
    */
   UnicodeString &toTitle(BreakIterator *titleIter, const Locale &locale, uint32_t options);
@@ -2820,7 +2795,7 @@
 
   /**
    * Get a read/write pointer to the internal buffer.
-   * The buffer is guaranteed to be large enough for at least minCapacity UChars,
+   * The buffer is guaranteed to be large enough for at least minCapacity char16_ts,
    * writable, and is still owned by the UnicodeString object.
    * Calls to getBuffer(minCapacity) must not be nested, and
    * must be matched with calls to releaseBuffer(newLength).
@@ -2846,22 +2821,22 @@
    *   If the length() was greater than minCapacity, then any contents after minCapacity
    *   may be lost.
    *   The buffer contents is not NUL-terminated by getBuffer().
-   *   If length()<getCapacity() then you can terminate it by writing a NUL
+   *   If length() < getCapacity() then you can terminate it by writing a NUL
    *   at index length().
    * - You must call releaseBuffer(newLength) before and in order to
    *   return to normal UnicodeString operation.
    *
-   * @param minCapacity the minimum number of UChars that are to be available
+   * @param minCapacity the minimum number of char16_ts that are to be available
    *        in the buffer, starting at the returned pointer;
    *        default to the current string capacity if minCapacity==-1
    * @return a writable pointer to the internal string buffer,
-   *         or 0 if an error occurs (nested calls, out of memory)
+   *         or nullptr if an error occurs (nested calls, out of memory)
    *
    * @see releaseBuffer
    * @see getTerminatedBuffer()
    * @stable ICU 2.0
    */
-  UChar *getBuffer(int32_t minCapacity);
+  char16_t *getBuffer(int32_t minCapacity);
 
   /**
    * Release a read/write buffer on a UnicodeString object with an
@@ -2902,20 +2877,20 @@
    *
    * The buffer contents is (probably) not NUL-terminated.
    * You can check if it is with
-   * <code>(s.length()<s.getCapacity() && buffer[s.length()]==0)</code>.
+   * `(s.length() < s.getCapacity() && buffer[s.length()]==0)`.
    * (See getTerminatedBuffer().)
    *
    * The buffer may reside in read-only memory. Its contents must not
    * be modified.
    *
    * @return a read-only pointer to the internal string buffer,
-   *         or 0 if the string is empty or bogus
+   *         or nullptr if the string is empty or bogus
    *
    * @see getBuffer(int32_t minCapacity)
    * @see getTerminatedBuffer()
    * @stable ICU 2.0
    */
-  inline const UChar *getBuffer() const;
+  inline const char16_t *getBuffer() const;
 
   /**
    * Get a read-only pointer to the internal buffer,
@@ -2950,7 +2925,7 @@
    * @see getBuffer()
    * @stable ICU 2.2
    */
-  const UChar *getTerminatedBuffer();
+  const char16_t *getTerminatedBuffer();
 
   //========================================
   // Constructors
@@ -2962,8 +2937,8 @@
   inline UnicodeString();
 
   /**
-   * Construct a UnicodeString with capacity to hold <TT>capacity</TT> UChars
-   * @param capacity the number of UChars this UnicodeString should hold
+   * Construct a UnicodeString with capacity to hold `capacity` char16_ts
+   * @param capacity the number of char16_ts this UnicodeString should hold
    * before a resize is necessary; if count is greater than 0 and count
    * code points c take up more space than capacity, then capacity is adjusted
    * accordingly.
@@ -2975,21 +2950,21 @@
   UnicodeString(int32_t capacity, UChar32 c, int32_t count);
 
   /**
-   * Single UChar (code unit) constructor.
+   * Single char16_t (code unit) constructor.
    *
    * It is recommended to mark this constructor "explicit" by
-   * <code>-DUNISTR_FROM_CHAR_EXPLICIT=explicit</code>
+   * `-DUNISTR_FROM_CHAR_EXPLICIT=explicit`
    * on the compiler command line or similar.
    * @param ch the character to place in the UnicodeString
    * @stable ICU 2.0
    */
-  UNISTR_FROM_CHAR_EXPLICIT UnicodeString(UChar ch);
+  UNISTR_FROM_CHAR_EXPLICIT UnicodeString(char16_t ch);
 
   /**
    * Single UChar32 (code point) constructor.
    *
    * It is recommended to mark this constructor "explicit" by
-   * <code>-DUNISTR_FROM_CHAR_EXPLICIT=explicit</code>
+   * `-DUNISTR_FROM_CHAR_EXPLICIT=explicit`
    * on the compiler command line or similar.
    * @param ch the character to place in the UnicodeString
    * @stable ICU 2.0
@@ -2997,29 +2972,106 @@
   UNISTR_FROM_CHAR_EXPLICIT UnicodeString(UChar32 ch);
 
   /**
-   * UChar* constructor.
+   * char16_t* constructor.
    *
    * It is recommended to mark this constructor "explicit" by
-   * <code>-DUNISTR_FROM_STRING_EXPLICIT=explicit</code>
+   * `-DUNISTR_FROM_STRING_EXPLICIT=explicit`
    * on the compiler command line or similar.
-   * @param text The characters to place in the UnicodeString.  <TT>text</TT>
+   * @param text The characters to place in the UnicodeString.  `text`
    * must be NULL (U+0000) terminated.
    * @stable ICU 2.0
    */
-  UNISTR_FROM_STRING_EXPLICIT UnicodeString(const UChar *text);
+  UNISTR_FROM_STRING_EXPLICIT UnicodeString(const char16_t *text);
+
+#if !U_CHAR16_IS_TYPEDEF
+  /**
+   * uint16_t * constructor.
+   * Delegates to UnicodeString(const char16_t *).
+   *
+   * It is recommended to mark this constructor "explicit" by
+   * `-DUNISTR_FROM_STRING_EXPLICIT=explicit`
+   * on the compiler command line or similar.
+   * @param text NUL-terminated UTF-16 string
+   * @stable ICU 59
+   */
+  UNISTR_FROM_STRING_EXPLICIT UnicodeString(const uint16_t *text) :
+      UnicodeString(ConstChar16Ptr(text)) {}
+#endif
+
+#if U_SIZEOF_WCHAR_T==2 || defined(U_IN_DOXYGEN)
+  /**
+   * wchar_t * constructor.
+   * (Only defined if U_SIZEOF_WCHAR_T==2.)
+   * Delegates to UnicodeString(const char16_t *).
+   *
+   * It is recommended to mark this constructor "explicit" by
+   * `-DUNISTR_FROM_STRING_EXPLICIT=explicit`
+   * on the compiler command line or similar.
+   * @param text NUL-terminated UTF-16 string
+   * @stable ICU 59
+   */
+  UNISTR_FROM_STRING_EXPLICIT UnicodeString(const wchar_t *text) :
+      UnicodeString(ConstChar16Ptr(text)) {}
+#endif
 
   /**
-   * UChar* constructor.
+   * nullptr_t constructor.
+   * Effectively the same as the default constructor, makes an empty string object.
+   *
+   * It is recommended to mark this constructor "explicit" by
+   * `-DUNISTR_FROM_STRING_EXPLICIT=explicit`
+   * on the compiler command line or similar.
+   * @param text nullptr
+   * @stable ICU 59
+   */
+  UNISTR_FROM_STRING_EXPLICIT inline UnicodeString(const std::nullptr_t text);
+
+  /**
+   * char16_t* constructor.
    * @param text The characters to place in the UnicodeString.
-   * @param textLength The number of Unicode characters in <TT>text</TT>
+   * @param textLength The number of Unicode characters in `text`
    * to copy.
    * @stable ICU 2.0
    */
-  UnicodeString(const UChar *text,
+  UnicodeString(const char16_t *text,
         int32_t textLength);
 
+#if !U_CHAR16_IS_TYPEDEF
   /**
-   * Readonly-aliasing UChar* constructor.
+   * uint16_t * constructor.
+   * Delegates to UnicodeString(const char16_t *, int32_t).
+   * @param text UTF-16 string
+   * @param textLength string length
+   * @stable ICU 59
+   */
+  UnicodeString(const uint16_t *text, int32_t textLength) :
+      UnicodeString(ConstChar16Ptr(text), textLength) {}
+#endif
+
+#if U_SIZEOF_WCHAR_T==2 || defined(U_IN_DOXYGEN)
+  /**
+   * wchar_t * constructor.
+   * (Only defined if U_SIZEOF_WCHAR_T==2.)
+   * Delegates to UnicodeString(const char16_t *, int32_t).
+   * @param text NUL-terminated UTF-16 string
+   * @param textLength string length
+   * @stable ICU 59
+   */
+  UnicodeString(const wchar_t *text, int32_t textLength) :
+      UnicodeString(ConstChar16Ptr(text), textLength) {}
+#endif
+
+  /**
+   * nullptr_t constructor.
+   * Effectively the same as the default constructor, makes an empty string object.
+   * @param text nullptr
+   * @param textLength ignored
+   * @stable ICU 59
+   */
+  inline UnicodeString(const std::nullptr_t text, int32_t textLength);
+
+  /**
+   * Readonly-aliasing char16_t* constructor.
    * The text will be used for the UnicodeString object, but
    * it will not be released when the UnicodeString is destroyed.
    * This has copy-on-write semantics:
@@ -3032,20 +3084,20 @@
    * When using fastCopyFrom(), the text will be aliased again,
    * so that both strings then alias the same readonly-text.
    *
-   * @param isTerminated specifies if <code>text</code> is <code>NUL</code>-terminated.
-   *                     This must be true if <code>textLength==-1</code>.
+   * @param isTerminated specifies if `text` is `NUL`-terminated.
+   *                     This must be true if `textLength==-1`.
    * @param text The characters to alias for the UnicodeString.
-   * @param textLength The number of Unicode characters in <code>text</code> to alias.
+   * @param textLength The number of Unicode characters in `text` to alias.
    *                   If -1, then this constructor will determine the length
-   *                   by calling <code>u_strlen()</code>.
+   *                   by calling `u_strlen()`.
    * @stable ICU 2.0
    */
   UnicodeString(UBool isTerminated,
-                const UChar *text,
+                ConstChar16Ptr text,
                 int32_t textLength);
 
   /**
-   * Writable-aliasing UChar* constructor.
+   * Writable-aliasing char16_t* constructor.
    * The text will be used for the UnicodeString object, but
    * it will not be released when the UnicodeString is destroyed.
    * This has write-through semantics:
@@ -3054,15 +3106,52 @@
    * a new buffer will be allocated and the contents copied as with regularly
    * constructed strings.
    * In an assignment to another UnicodeString, the buffer will be copied.
-   * The extract(UChar *dst) function detects whether the dst pointer is the same
+   * The extract(Char16Ptr dst) function detects whether the dst pointer is the same
    * as the string buffer itself and will in this case not copy the contents.
    *
    * @param buffer The characters to alias for the UnicodeString.
-   * @param buffLength The number of Unicode characters in <code>buffer</code> to alias.
-   * @param buffCapacity The size of <code>buffer</code> in UChars.
+   * @param buffLength The number of Unicode characters in `buffer` to alias.
+   * @param buffCapacity The size of `buffer` in char16_ts.
    * @stable ICU 2.0
    */
-  UnicodeString(UChar *buffer, int32_t buffLength, int32_t buffCapacity);
+  UnicodeString(char16_t *buffer, int32_t buffLength, int32_t buffCapacity);
+
+#if !U_CHAR16_IS_TYPEDEF
+  /**
+   * Writable-aliasing uint16_t * constructor.
+   * Delegates to UnicodeString(const char16_t *, int32_t, int32_t).
+   * @param buffer writable buffer of/for UTF-16 text
+   * @param buffLength length of the current buffer contents
+   * @param buffCapacity buffer capacity
+   * @stable ICU 59
+   */
+  UnicodeString(uint16_t *buffer, int32_t buffLength, int32_t buffCapacity) :
+      UnicodeString(Char16Ptr(buffer), buffLength, buffCapacity) {}
+#endif
+
+#if U_SIZEOF_WCHAR_T==2 || defined(U_IN_DOXYGEN)
+  /**
+   * Writable-aliasing wchar_t * constructor.
+   * (Only defined if U_SIZEOF_WCHAR_T==2.)
+   * Delegates to UnicodeString(const char16_t *, int32_t, int32_t).
+   * @param buffer writable buffer of/for UTF-16 text
+   * @param buffLength length of the current buffer contents
+   * @param buffCapacity buffer capacity
+   * @stable ICU 59
+   */
+  UnicodeString(wchar_t *buffer, int32_t buffLength, int32_t buffCapacity) :
+      UnicodeString(Char16Ptr(buffer), buffLength, buffCapacity) {}
+#endif
+
+  /**
+   * Writable-aliasing nullptr_t constructor.
+   * Effectively the same as the default constructor, makes an empty string object.
+   * @param buffer nullptr
+   * @param buffLength ignored
+   * @param buffCapacity ignored
+   * @stable ICU 59
+   */
+  inline UnicodeString(std::nullptr_t buffer, int32_t buffLength, int32_t buffCapacity);
 
 #if U_CHARSET_IS_UTF8 || !UCONFIG_NO_CONVERSION
 
@@ -3077,7 +3166,7 @@
    * UNICODE_STRING_SIMPLE.
    *
    * It is recommended to mark this constructor "explicit" by
-   * <code>-DUNISTR_FROM_STRING_EXPLICIT=explicit</code>
+   * `-DUNISTR_FROM_STRING_EXPLICIT=explicit`
    * on the compiler command line or similar.
    * @param codepageData an array of bytes, null-terminated,
    *                     in the platform's default codepage.
@@ -3092,7 +3181,7 @@
    * Uses the default converter (and thus depends on the ICU conversion code)
    * unless U_CHARSET_IS_UTF8 is set to 1.
    * @param codepageData an array of bytes in the platform's default codepage.
-   * @param dataLength The number of bytes in <TT>codepageData</TT>.
+   * @param dataLength The number of bytes in `codepageData`.
    * @stable ICU 2.0
    */
   UnicodeString(const char *codepageData, int32_t dataLength);
@@ -3104,11 +3193,11 @@
   /**
    * char* constructor.
    * @param codepageData an array of bytes, null-terminated
-   * @param codepage the encoding of <TT>codepageData</TT>.  The special
-   * value 0 for <TT>codepage</TT> indicates that the text is in the
+   * @param codepage the encoding of `codepageData`.  The special
+   * value 0 for `codepage` indicates that the text is in the
    * platform's default codepage.
    *
-   * If <code>codepage</code> is an empty string (<code>""</code>),
+   * If `codepage` is an empty string (`""`),
    * then a simple conversion is performed on the codepage-invariant
    * subset ("invariant characters") of the platform encoding. See utypes.h.
    * Recommendation: For invariant-character strings use the constructor
@@ -3123,11 +3212,11 @@
   /**
    * char* constructor.
    * @param codepageData an array of bytes.
-   * @param dataLength The number of bytes in <TT>codepageData</TT>.
-   * @param codepage the encoding of <TT>codepageData</TT>.  The special
-   * value 0 for <TT>codepage</TT> indicates that the text is in the
+   * @param dataLength The number of bytes in `codepageData`.
+   * @param codepage the encoding of `codepageData`.  The special
+   * value 0 for `codepage` indicates that the text is in the
    * platform's default codepage.
-   * If <code>codepage</code> is an empty string (<code>""</code>),
+   * If `codepage` is an empty string (`""`),
    * then a simple conversion is performed on the codepage-invariant
    * subset ("invariant characters") of the platform encoding. See utypes.h.
    * Recommendation: For invariant-character strings use the constructor
@@ -3178,20 +3267,19 @@
    *
    * For example:
    * \code
-   * void fn(const char *s) {
-   *   UnicodeString ustr(s, -1, US_INV);
-   *   // use ustr ...
-   * }
+   *     void fn(const char *s) {
+   *       UnicodeString ustr(s, -1, US_INV);
+   *       // use ustr ...
+   *     }
    * \endcode
-   *
    * @param src String using only invariant characters.
-   * @param length Length of src, or -1 if NUL-terminated.
+   * @param textLength Length of src, or -1 if NUL-terminated.
    * @param inv Signature-distinguishing paramater, use US_INV.
    *
    * @see US_INV
    * @stable ICU 3.2
    */
-  UnicodeString(const char *src, int32_t length, enum EInvariant inv);
+  UnicodeString(const char *src, int32_t textLength, enum EInvariant inv);
 
 
   /**
@@ -3212,22 +3300,18 @@
    */
   UnicodeString(const UnicodeString& that);
 
-#ifndef U_HIDE_DRAFT_API
-#if U_HAVE_RVALUE_REFERENCES
   /**
-   * Move constructor, might leave src in bogus state.
+   * Move constructor; might leave src in bogus state.
    * This string will have the same contents and state that the source string had.
    * @param src source string
-   * @draft ICU 56
+   * @stable ICU 56
    */
   UnicodeString(UnicodeString &&src) U_NOEXCEPT;
-#endif
-#endif  /* U_HIDE_DRAFT_API */
 
   /**
    * 'Substring' constructor from tail of source string.
    * @param src The UnicodeString object to copy.
-   * @param srcStart The offset into <tt>src</tt> at which to start copying.
+   * @param srcStart The offset into `src` at which to start copying.
    * @stable ICU 2.2
    */
   UnicodeString(const UnicodeString& src, int32_t srcStart);
@@ -3235,8 +3319,8 @@
   /**
    * 'Substring' constructor from subrange of source string.
    * @param src The UnicodeString object to copy.
-   * @param srcStart The offset into <tt>src</tt> at which to start copying.
-   * @param srcLength The number of characters from <tt>src</tt> to copy.
+   * @param srcStart The offset into `src` at which to start copying.
+   * @param srcLength The number of characters from `src` to copy.
    * @stable ICU 2.2
    */
   UnicodeString(const UnicodeString& src, int32_t srcStart, int32_t srcLength);
@@ -3246,9 +3330,6 @@
    * Clones can be used concurrently in multiple threads.
    * If a subclass does not implement clone(), or if an error occurs,
    * then NULL is returned.
-   * The clone functions in all subclasses return a pointer to a Replaceable
-   * because some compilers do not support covariant (same-as-this)
-   * return types; cast to the appropriate subclass if necessary.
    * The caller must delete the clone.
    *
    * @return a clone of this object
@@ -3257,7 +3338,7 @@
    * @see getDynamicClassID
    * @stable ICU 2.6
    */
-  virtual Replaceable *clone() const;
+  virtual UnicodeString *clone() const;
 
   /** Destructor.
    * @stable ICU 2.0
@@ -3277,7 +3358,7 @@
    * @see toUTF8String
    * @stable ICU 4.2
    */
-  static UnicodeString fromUTF8(const StringPiece &utf8);
+  static UnicodeString fromUTF8(StringPiece utf8);
 
   /**
    * Create a UnicodeString from a UTF-32 string.
@@ -3308,7 +3389,7 @@
    *
    * \\a => U+0007, \\b => U+0008, \\t => U+0009, \\n => U+000A,
    * \\v => U+000B, \\f => U+000C, \\r => U+000D, \\e => U+001B,
-   * \\&quot; => U+0022, \\' => U+0027, \\? => U+003F, \\\\ => U+005C
+   * \\" => U+0022, \\' => U+0027, \\? => U+003F, \\\\ => U+005C
    *
    * Anything else following a backslash is generically escaped.  For
    * example, "[a\\-z]" returns "[a-z]".
@@ -3381,7 +3462,7 @@
    * UnicodeString::charAt() to be inline again (see jitterbug 709).
    * @stable ICU 2.4
    */
-  virtual UChar getCharAt(int32_t offset) const;
+  virtual char16_t getCharAt(int32_t offset) const;
 
   /**
    * The change in Replaceable to use virtual getChar32At() allows
@@ -3392,7 +3473,7 @@
 
 private:
   // For char* constructors. Could be made public.
-  UnicodeString &setToUTF8(const StringPiece &utf8);
+  UnicodeString &setToUTF8(StringPiece utf8);
   // For extract(char*).
   // We could make a toUTF8(target, capacity, errorCode) public but not
   // this version: New API will be cleaner if we make callers create substrings
@@ -3417,7 +3498,7 @@
 
   int8_t doCompare(int32_t start,
            int32_t length,
-           const UChar *srcChars,
+           const char16_t *srcChars,
            int32_t srcStart,
            int32_t srcLength) const;
 
@@ -3430,7 +3511,7 @@
 
   int8_t doCompareCodePointOrder(int32_t start,
                                  int32_t length,
-                                 const UChar *srcChars,
+                                 const char16_t *srcChars,
                                  int32_t srcStart,
                                  int32_t srcLength) const;
 
@@ -3445,12 +3526,12 @@
   int8_t
   doCaseCompare(int32_t start,
                 int32_t length,
-                const UChar *srcChars,
+                const char16_t *srcChars,
                 int32_t srcStart,
                 int32_t srcLength,
                 uint32_t options) const;
 
-  int32_t doIndexOf(UChar c,
+  int32_t doIndexOf(char16_t c,
             int32_t start,
             int32_t length) const;
 
@@ -3458,7 +3539,7 @@
                         int32_t start,
                         int32_t length) const;
 
-  int32_t doLastIndexOf(UChar c,
+  int32_t doLastIndexOf(char16_t c,
                 int32_t start,
                 int32_t length) const;
 
@@ -3468,14 +3549,14 @@
 
   void doExtract(int32_t start,
          int32_t length,
-         UChar *dst,
+         char16_t *dst,
          int32_t dstStart) const;
 
   inline void doExtract(int32_t start,
          int32_t length,
          UnicodeString& target) const;
 
-  inline UChar doCharAt(int32_t offset)  const;
+  inline char16_t doCharAt(int32_t offset)  const;
 
   UnicodeString& doReplace(int32_t start,
                int32_t length,
@@ -3485,12 +3566,12 @@
 
   UnicodeString& doReplace(int32_t start,
                int32_t length,
-               const UChar *srcChars,
+               const char16_t *srcChars,
                int32_t srcStart,
                int32_t srcLength);
 
   UnicodeString& doAppend(const UnicodeString& src, int32_t srcStart, int32_t srcLength);
-  UnicodeString& doAppend(const UChar *srcChars, int32_t srcStart, int32_t srcLength);
+  UnicodeString& doAppend(const char16_t *srcChars, int32_t srcStart, int32_t srcLength);
 
   UnicodeString& doReverse(int32_t start,
                int32_t length);
@@ -3500,8 +3581,8 @@
 
   // get pointer to start of array
   // these do not check for kOpenGetBuffer, unlike the public getBuffer() function
-  inline UChar* getArrayStart(void);
-  inline const UChar* getArrayStart(void) const;
+  inline char16_t* getArrayStart(void);
+  inline const char16_t* getArrayStart(void) const;
 
   inline UBool hasShortLength() const;
   inline int32_t getShortLength() const;
@@ -3518,7 +3599,7 @@
   inline void setShortLength(int32_t len);
   inline void setLength(int32_t len);
   inline void setToEmpty();
-  inline void setArray(UChar *array, int32_t len, int32_t capacity); // sets length but not flags
+  inline void setArray(char16_t *array, int32_t len, int32_t capacity); // sets length but not flags
 
   // allocate the array; result may be the stack buffer
   // sets refCount to 1 if appropriate
@@ -3534,7 +3615,7 @@
   void unBogus();
 
   // implements assigment operator, copy constructor, and fastCopyFrom()
-  UnicodeString &copyFrom(const UnicodeString &src, UBool fastCopy=FALSE);
+  UnicodeString &copyFrom(const UnicodeString &src, UBool fastCopy=false);
 
   // Copies just the fields without memory management.
   void copyFieldsFrom(UnicodeString &src, UBool setSrcToBogus) U_NOEXCEPT;
@@ -3556,9 +3637,9 @@
    * Real constructor for converting from codepage data.
    * It assumes that it is called with !fRefCounted.
    *
-   * If <code>codepage==0</code>, then the default converter
+   * If `codepage==0`, then the default converter
    * is used for the platform encoding.
-   * If <code>codepage</code> is an empty string (<code>""</code>),
+   * If `codepage` is an empty string (`""`),
    * then a simple conversion is performed on the codepage-invariant
    * subset ("invariant characters") of the platform encoding. See utypes.h.
    */
@@ -3587,13 +3668,13 @@
    * the buffer is refCounted (shared), and refCount>1, or
    * the buffer is too small.
    *
-   * Return FALSE if memory could not be allocated.
+   * Return false if memory could not be allocated.
    */
   UBool cloneArrayIfNeeded(int32_t newCapacity = -1,
                             int32_t growCapacity = -1,
-                            UBool doCopyArray = TRUE,
+                            UBool doCopyArray = true,
                             int32_t **pBufferToDelete = 0,
-                            UBool forceClone = FALSE);
+                            UBool forceClone = false);
 
   /**
    * Common function for UnicodeString case mappings.
@@ -3601,7 +3682,11 @@
    * as in ustr_imp.h for ustrcase_map().
    */
   UnicodeString &
-  caseMap(const UCaseMap *csm, UStringCaseMapper *stringCaseMapper);
+  caseMap(int32_t caseLocale, uint32_t options,
+#if !UCONFIG_NO_BREAK_ITERATION
+          BreakIterator *iter,
+#endif
+          UStringCaseMapper *stringCaseMapper);
 
   // ref counting
   void addRef(void);
@@ -3617,7 +3702,6 @@
      */
     US_STACKBUF_SIZE=(int32_t)(UNISTR_OBJECT_SIZE-sizeof(void *)-2)/U_SIZEOF_UCHAR,
     kInvalidUChar=0xffff, // U+FFFF returned by charAt(invalid index)
-    kGrowSize=128, // grow size for this buffer
     kInvalidHashCode=0, // invalid hash code
     kEmptyHashCode=1, // hash code for empty string
 
@@ -3693,15 +3777,15 @@
     // Each struct of the union must begin with fLengthAndFlags.
     struct {
       int16_t fLengthAndFlags;          // bit fields: see constants above
-      UChar fBuffer[US_STACKBUF_SIZE];  // buffer for short strings
+      char16_t fBuffer[US_STACKBUF_SIZE];  // buffer for short strings
     } fStackFields;
     struct {
       int16_t fLengthAndFlags;          // bit fields: see constants above
       int32_t fLength;    // number of characters in fArray if >127; else undefined
-      int32_t fCapacity;  // capacity of fArray (in UChars)
+      int32_t fCapacity;  // capacity of fArray (in char16_ts)
       // array pointer last to minimize padding for machines with P128 data model
       // or pointer sizes that are not a power of 2
-      UChar   *fArray;    // the Unicode data
+      char16_t   *fArray;    // the Unicode data
     } fFields;
   } fUnion;
 };
@@ -3754,13 +3838,13 @@
   }
 }
 
-inline UChar*
+inline char16_t*
 UnicodeString::getArrayStart() {
   return (fUnion.fFields.fLengthAndFlags&kUsingStackBuffer) ?
     fUnion.fStackFields.fBuffer : fUnion.fFields.fArray;
 }
 
-inline const UChar*
+inline const char16_t*
 UnicodeString::getArrayStart() const {
   return (fUnion.fFields.fLengthAndFlags&kUsingStackBuffer) ?
     fUnion.fStackFields.fBuffer : fUnion.fFields.fArray;
@@ -3775,6 +3859,18 @@
   fUnion.fStackFields.fLengthAndFlags=kShortString;
 }
 
+inline UnicodeString::UnicodeString(const std::nullptr_t /*text*/) {
+  fUnion.fStackFields.fLengthAndFlags=kShortString;
+}
+
+inline UnicodeString::UnicodeString(const std::nullptr_t /*text*/, int32_t /*length*/) {
+  fUnion.fStackFields.fLengthAndFlags=kShortString;
+}
+
+inline UnicodeString::UnicodeString(std::nullptr_t /*buffer*/, int32_t /*buffLength*/, int32_t /*buffCapacity*/) {
+  fUnion.fStackFields.fLengthAndFlags=kShortString;
+}
+
 //========================================
 // Read-only implementation methods
 //========================================
@@ -3821,10 +3917,10 @@
       (!(fUnion.fFields.fLengthAndFlags&kRefCounted) || refCount()==1));
 }
 
-inline const UChar *
+inline const char16_t *
 UnicodeString::getBuffer() const {
   if(fUnion.fFields.fLengthAndFlags&(kIsBogus|kOpenGetBuffer)) {
-    return 0;
+    return nullptr;
   } else if(fUnion.fFields.fLengthAndFlags&kUsingStackBuffer) {
     return fUnion.fStackFields.fBuffer;
   } else {
@@ -3892,7 +3988,7 @@
 { return doCompare(start, _length, srcText, 0, srcText.length()); }
 
 inline int8_t
-UnicodeString::compare(const UChar *srcChars,
+UnicodeString::compare(ConstChar16Ptr srcChars,
                int32_t srcLength) const
 { return doCompare(0, length(), srcChars, 0, srcLength); }
 
@@ -3907,13 +4003,13 @@
 inline int8_t
 UnicodeString::compare(int32_t start,
                int32_t _length,
-               const UChar *srcChars) const
+               const char16_t *srcChars) const
 { return doCompare(start, _length, srcChars, 0, _length); }
 
 inline int8_t
 UnicodeString::compare(int32_t start,
                int32_t _length,
-               const UChar *srcChars,
+               const char16_t *srcChars,
                int32_t srcStart,
                int32_t srcLength) const
 { return doCompare(start, _length, srcChars, srcStart, srcLength); }
@@ -3953,7 +4049,7 @@
 { return doCompareCodePointOrder(start, _length, srcText, 0, srcText.length()); }
 
 inline int8_t
-UnicodeString::compareCodePointOrder(const UChar *srcChars,
+UnicodeString::compareCodePointOrder(ConstChar16Ptr srcChars,
                                      int32_t srcLength) const
 { return doCompareCodePointOrder(0, length(), srcChars, 0, srcLength); }
 
@@ -3968,13 +4064,13 @@
 inline int8_t
 UnicodeString::compareCodePointOrder(int32_t start,
                                      int32_t _length,
-                                     const UChar *srcChars) const
+                                     const char16_t *srcChars) const
 { return doCompareCodePointOrder(start, _length, srcChars, 0, _length); }
 
 inline int8_t
 UnicodeString::compareCodePointOrder(int32_t start,
                                      int32_t _length,
-                                     const UChar *srcChars,
+                                     const char16_t *srcChars,
                                      int32_t srcStart,
                                      int32_t srcLength) const
 { return doCompareCodePointOrder(start, _length, srcChars, srcStart, srcLength); }
@@ -4018,7 +4114,7 @@
 }
 
 inline int8_t
-UnicodeString::caseCompare(const UChar *srcChars,
+UnicodeString::caseCompare(ConstChar16Ptr srcChars,
                            int32_t srcLength,
                            uint32_t options) const {
   return doCaseCompare(0, length(), srcChars, 0, srcLength, options);
@@ -4037,7 +4133,7 @@
 inline int8_t
 UnicodeString::caseCompare(int32_t start,
                            int32_t _length,
-                           const UChar *srcChars,
+                           const char16_t *srcChars,
                            uint32_t options) const {
   return doCaseCompare(start, _length, srcChars, 0, _length, options);
 }
@@ -4045,7 +4141,7 @@
 inline int8_t
 UnicodeString::caseCompare(int32_t start,
                            int32_t _length,
-                           const UChar *srcChars,
+                           const char16_t *srcChars,
                            int32_t srcStart,
                            int32_t srcLength,
                            uint32_t options) const {
@@ -4096,7 +4192,7 @@
 { return indexOf(text, 0, text.length(), start, _length); }
 
 inline int32_t
-UnicodeString::indexOf(const UChar *srcChars,
+UnicodeString::indexOf(const char16_t *srcChars,
                int32_t srcLength,
                int32_t start) const {
   pinIndex(start);
@@ -4104,14 +4200,14 @@
 }
 
 inline int32_t
-UnicodeString::indexOf(const UChar *srcChars,
+UnicodeString::indexOf(ConstChar16Ptr srcChars,
                int32_t srcLength,
                int32_t start,
                int32_t _length) const
 { return indexOf(srcChars, 0, srcLength, start, _length); }
 
 inline int32_t
-UnicodeString::indexOf(UChar c,
+UnicodeString::indexOf(char16_t c,
                int32_t start,
                int32_t _length) const
 { return doIndexOf(c, start, _length); }
@@ -4123,7 +4219,7 @@
 { return doIndexOf(c, start, _length); }
 
 inline int32_t
-UnicodeString::indexOf(UChar c) const
+UnicodeString::indexOf(char16_t c) const
 { return doIndexOf(c, 0, length()); }
 
 inline int32_t
@@ -4131,7 +4227,7 @@
 { return indexOf(c, 0, length()); }
 
 inline int32_t
-UnicodeString::indexOf(UChar c,
+UnicodeString::indexOf(char16_t c,
                int32_t start) const {
   pinIndex(start);
   return doIndexOf(c, start, length() - start);
@@ -4145,14 +4241,14 @@
 }
 
 inline int32_t
-UnicodeString::lastIndexOf(const UChar *srcChars,
+UnicodeString::lastIndexOf(ConstChar16Ptr srcChars,
                int32_t srcLength,
                int32_t start,
                int32_t _length) const
 { return lastIndexOf(srcChars, 0, srcLength, start, _length); }
 
 inline int32_t
-UnicodeString::lastIndexOf(const UChar *srcChars,
+UnicodeString::lastIndexOf(const char16_t *srcChars,
                int32_t srcLength,
                int32_t start) const {
   pinIndex(start);
@@ -4193,7 +4289,7 @@
 { return lastIndexOf(text, 0, text.length(), 0, length()); }
 
 inline int32_t
-UnicodeString::lastIndexOf(UChar c,
+UnicodeString::lastIndexOf(char16_t c,
                int32_t start,
                int32_t _length) const
 { return doLastIndexOf(c, start, _length); }
@@ -4206,7 +4302,7 @@
 }
 
 inline int32_t
-UnicodeString::lastIndexOf(UChar c) const
+UnicodeString::lastIndexOf(char16_t c) const
 { return doLastIndexOf(c, 0, length()); }
 
 inline int32_t
@@ -4215,7 +4311,7 @@
 }
 
 inline int32_t
-UnicodeString::lastIndexOf(UChar c,
+UnicodeString::lastIndexOf(char16_t c,
                int32_t start) const {
   pinIndex(start);
   return doLastIndexOf(c, start, length() - start);
@@ -4239,17 +4335,17 @@
 { return doCompare(0, srcLength, srcText, srcStart, srcLength) == 0; }
 
 inline UBool
-UnicodeString::startsWith(const UChar *srcChars, int32_t srcLength) const {
+UnicodeString::startsWith(ConstChar16Ptr srcChars, int32_t srcLength) const {
   if(srcLength < 0) {
-    srcLength = u_strlen(srcChars);
+    srcLength = u_strlen(toUCharPtr(srcChars));
   }
   return doCompare(0, srcLength, srcChars, 0, srcLength) == 0;
 }
 
 inline UBool
-UnicodeString::startsWith(const UChar *srcChars, int32_t srcStart, int32_t srcLength) const {
+UnicodeString::startsWith(const char16_t *srcChars, int32_t srcStart, int32_t srcLength) const {
   if(srcLength < 0) {
-    srcLength = u_strlen(srcChars);
+    srcLength = u_strlen(toUCharPtr(srcChars));
   }
   return doCompare(0, srcLength, srcChars, srcStart, srcLength) == 0;
 }
@@ -4269,21 +4365,21 @@
 }
 
 inline UBool
-UnicodeString::endsWith(const UChar *srcChars,
+UnicodeString::endsWith(ConstChar16Ptr srcChars,
             int32_t srcLength) const {
   if(srcLength < 0) {
-    srcLength = u_strlen(srcChars);
+    srcLength = u_strlen(toUCharPtr(srcChars));
   }
   return doCompare(length() - srcLength, srcLength,
                    srcChars, 0, srcLength) == 0;
 }
 
 inline UBool
-UnicodeString::endsWith(const UChar *srcChars,
+UnicodeString::endsWith(const char16_t *srcChars,
             int32_t srcStart,
             int32_t srcLength) const {
   if(srcLength < 0) {
-    srcLength = u_strlen(srcChars + srcStart);
+    srcLength = u_strlen(toUCharPtr(srcChars + srcStart));
   }
   return doCompare(length() - srcLength, srcLength,
                    srcChars, srcStart, srcLength) == 0;
@@ -4309,14 +4405,14 @@
 inline UnicodeString&
 UnicodeString::replace(int32_t start,
                int32_t _length,
-               const UChar *srcChars,
+               ConstChar16Ptr srcChars,
                int32_t srcLength)
 { return doReplace(start, _length, srcChars, 0, srcLength); }
 
 inline UnicodeString&
 UnicodeString::replace(int32_t start,
                int32_t _length,
-               const UChar *srcChars,
+               const char16_t *srcChars,
                int32_t srcStart,
                int32_t srcLength)
 { return doReplace(start, _length, srcChars, srcStart, srcLength); }
@@ -4324,7 +4420,7 @@
 inline UnicodeString&
 UnicodeString::replace(int32_t start,
                int32_t _length,
-               UChar srcChar)
+               char16_t srcChar)
 { return doReplace(start, _length, &srcChar, 0, 1); }
 
 inline UnicodeString&
@@ -4367,7 +4463,7 @@
 inline void
 UnicodeString::extract(int32_t start,
                int32_t _length,
-               UChar *target,
+               Char16Ptr target,
                int32_t targetStart) const
 { doExtract(start, _length, target, targetStart); }
 
@@ -4395,7 +4491,7 @@
 inline void
 UnicodeString::extractBetween(int32_t start,
                   int32_t limit,
-                  UChar *dst,
+                  char16_t *dst,
                   int32_t dstStart) const {
   pinIndex(start);
   pinIndex(limit);
@@ -4407,7 +4503,7 @@
     return tempSubString(start, limit - start);
 }
 
-inline UChar
+inline char16_t
 UnicodeString::doCharAt(int32_t offset) const
 {
   if((uint32_t)offset < (uint32_t)length()) {
@@ -4417,11 +4513,11 @@
   }
 }
 
-inline UChar
+inline char16_t
 UnicodeString::charAt(int32_t offset) const
 { return doCharAt(offset); }
 
-inline UChar
+inline char16_t
 UnicodeString::operator[] (int32_t offset) const
 { return doCharAt(offset); }
 
@@ -4462,14 +4558,14 @@
 }
 
 inline void
-UnicodeString::setArray(UChar *array, int32_t len, int32_t capacity) {
+UnicodeString::setArray(char16_t *array, int32_t len, int32_t capacity) {
   setLength(len);
   fUnion.fFields.fArray = array;
   fUnion.fFields.fCapacity = capacity;
 }
 
 inline UnicodeString&
-UnicodeString::operator= (UChar ch)
+UnicodeString::operator= (char16_t ch)
 { return doReplace(0, length(), &ch, 0, 1); }
 
 inline UnicodeString&
@@ -4501,7 +4597,7 @@
 }
 
 inline UnicodeString&
-UnicodeString::setTo(const UChar *srcChars,
+UnicodeString::setTo(const char16_t *srcChars,
              int32_t srcLength)
 {
   unBogus();
@@ -4509,7 +4605,7 @@
 }
 
 inline UnicodeString&
-UnicodeString::setTo(UChar srcChar)
+UnicodeString::setTo(char16_t srcChar)
 {
   unBogus();
   return doReplace(0, length(), &srcChar, 0, 1);
@@ -4533,22 +4629,22 @@
 { return doAppend(srcText, 0, srcText.length()); }
 
 inline UnicodeString&
-UnicodeString::append(const UChar *srcChars,
+UnicodeString::append(const char16_t *srcChars,
               int32_t srcStart,
               int32_t srcLength)
 { return doAppend(srcChars, srcStart, srcLength); }
 
 inline UnicodeString&
-UnicodeString::append(const UChar *srcChars,
+UnicodeString::append(ConstChar16Ptr srcChars,
               int32_t srcLength)
 { return doAppend(srcChars, 0, srcLength); }
 
 inline UnicodeString&
-UnicodeString::append(UChar srcChar)
+UnicodeString::append(char16_t srcChar)
 { return doAppend(&srcChar, 0, 1); }
 
 inline UnicodeString&
-UnicodeString::operator+= (UChar ch)
+UnicodeString::operator+= (char16_t ch)
 { return doAppend(&ch, 0, 1); }
 
 inline UnicodeString&
@@ -4574,20 +4670,20 @@
 
 inline UnicodeString&
 UnicodeString::insert(int32_t start,
-              const UChar *srcChars,
+              const char16_t *srcChars,
               int32_t srcStart,
               int32_t srcLength)
 { return doReplace(start, 0, srcChars, srcStart, srcLength); }
 
 inline UnicodeString&
 UnicodeString::insert(int32_t start,
-              const UChar *srcChars,
+              ConstChar16Ptr srcChars,
               int32_t srcLength)
 { return doReplace(start, 0, srcChars, 0, srcLength); }
 
 inline UnicodeString&
 UnicodeString::insert(int32_t start,
-              UChar srcChar)
+              char16_t srcChar)
 { return doReplace(start, 0, &srcChar, 0, 1); }
 
 inline UnicodeString&
@@ -4636,12 +4732,12 @@
   if(isBogus() && targetLength == 0) {
     // truncate(0) of a bogus string makes the string empty and non-bogus
     unBogus();
-    return FALSE;
+    return false;
   } else if((uint32_t)targetLength < (uint32_t)length()) {
     setLength(targetLength);
-    return TRUE;
+    return true;
   } else {
-    return FALSE;
+    return false;
   }
 }
 
@@ -4656,4 +4752,6 @@
 
 U_NAMESPACE_END
 
+#endif /* U_SHOW_CPLUSPLUS_API */
+
 #endif
diff --git a/src/third_party/icu/source/common/unicode/unorm.h b/src/third_party/icu/source/common/unicode/unorm.h
index 4852538..c3c5758 100644
--- a/src/third_party/icu/source/common/unicode/unorm.h
+++ b/src/third_party/icu/source/common/unicode/unorm.h
@@ -1,6 +1,8 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
-* Copyright (c) 1996-2015, International Business Machines Corporation
+* Copyright (c) 1996-2016, International Business Machines Corporation
 *               and others. All Rights Reserved.
 *******************************************************************************
 * File unorm.h
@@ -22,11 +24,9 @@
 #include "unicode/uiter.h"
 #include "unicode/unorm2.h"
 
-#ifndef U_HIDE_DEPRECATED_API
-
 /**
  * \file
- * \brief C API: Unicode Normalization 
+ * \brief C API: Unicode Normalization
  *
  * Old Unicode normalization API.
  *
@@ -60,7 +60,7 @@
  *
  * To a user of your program, however, both of these sequences should be
  * treated as the same "user-level" character "A with acute accent".  When you are searching or
- * comparing text, you must ensure that these two sequences are treated 
+ * comparing text, you must ensure that these two sequences are treated
  * equivalently.  In addition, you must handle characters with more than one
  * accent.  Sometimes the order of a character's combining accents is
  * significant, while in other cases accent sequences in different orders are
@@ -88,8 +88,8 @@
  * will often want to use these mappings.
  *
  * <code>unorm_normalize</code> helps solve these problems by transforming text into the
- * canonical composed and decomposed forms as shown in the first example above.  
- * In addition, you can have it perform compatibility decompositions so that 
+ * canonical composed and decomposed forms as shown in the first example above.
+ * In addition, you can have it perform compatibility decompositions so that
  * you can treat compatibility characters the same as their equivalents.
  * Finally, <code>unorm_normalize</code> rearranges accents into the proper canonical
  * order, so that you do not have to worry about accent rearrangement on your
@@ -129,14 +129,17 @@
  * For more usage examples, see the Unicode Standard Annex.
  */
 
-#ifndef U_HIDE_DEPRECATED_API
+// Do not conditionalize the following enum with #ifndef U_HIDE_DEPRECATED_API,
+// it is needed for layout of Normalizer object.
+#ifndef U_FORCE_HIDE_DEPRECATED_API
+
 /**
  * Constants for normalization modes.
  * @deprecated ICU 56 Use unorm2.h instead.
  */
 typedef enum {
   /** No decomposition/composition. @deprecated ICU 56 Use unorm2.h instead. */
-  UNORM_NONE = 1, 
+  UNORM_NONE = 1,
   /** Canonical decomposition. @deprecated ICU 56 Use unorm2.h instead. */
   UNORM_NFD = 2,
   /** Compatibility decomposition. @deprecated ICU 56 Use unorm2.h instead. */
@@ -144,7 +147,7 @@
   /** Canonical decomposition followed by canonical composition. @deprecated ICU 56 Use unorm2.h instead. */
   UNORM_NFC = 4,
   /** Default normalization. @deprecated ICU 56 Use unorm2.h instead. */
-  UNORM_DEFAULT = UNORM_NFC, 
+  UNORM_DEFAULT = UNORM_NFC,
   /** Compatibility decomposition followed by canonical composition. @deprecated ICU 56 Use unorm2.h instead. */
   UNORM_NFKC =5,
   /** "Fast C or D" form. @deprecated ICU 56 Use unorm2.h instead. */
@@ -153,7 +156,10 @@
   /** One more than the highest normalization mode constant. @deprecated ICU 56 Use unorm2.h instead. */
   UNORM_MODE_COUNT
 } UNormalizationMode;
-#endif  /* U_HIDE_DEPRECATED_API */
+
+#endif  // U_FORCE_HIDE_DEPRECATED_API
+
+#ifndef U_HIDE_DEPRECATED_API
 
 /**
  * Constants for options flags for normalization.
@@ -197,7 +203,7 @@
  *
  * @param source The string to normalize.
  * @param sourceLength The length of source, or -1 if NUL-terminated.
- * @param mode The normalization mode; one of UNORM_NONE, 
+ * @param mode The normalization mode; one of UNORM_NONE,
  *             UNORM_NFD, UNORM_NFC, UNORM_NFKC, UNORM_NFKD, UNORM_DEFAULT.
  * @param options The normalization options, ORed together (0 for no options).
  * @param result A pointer to a buffer to receive the result string.
@@ -208,21 +214,21 @@
  *         the output was truncated, and the error code is set to U_BUFFER_OVERFLOW_ERROR.
  * @deprecated ICU 56 Use unorm2.h instead.
  */
-U_STABLE int32_t U_EXPORT2 
+U_DEPRECATED int32_t U_EXPORT2
 unorm_normalize(const UChar *source, int32_t sourceLength,
                 UNormalizationMode mode, int32_t options,
                 UChar *result, int32_t resultLength,
                 UErrorCode *status);
 
 /**
- * Performing quick check on a string, to quickly determine if the string is 
+ * Performing quick check on a string, to quickly determine if the string is
  * in a particular normalization format.
  * Three types of result can be returned UNORM_YES, UNORM_NO or
  * UNORM_MAYBE. Result UNORM_YES indicates that the argument
  * string is in the desired normalized format, UNORM_NO determines that
- * argument string is not in the desired normalized format. A 
- * UNORM_MAYBE result indicates that a more thorough check is required, 
- * the user may have to put the string in its normalized form and compare the 
+ * argument string is not in the desired normalized format. A
+ * UNORM_MAYBE result indicates that a more thorough check is required,
+ * the user may have to put the string in its normalized form and compare the
  * results.
  *
  * @param source       string for determining if it is in a normalized format
@@ -234,7 +240,7 @@
  * @see unorm_isNormalized
  * @deprecated ICU 56 Use unorm2.h instead.
  */
-U_STABLE UNormalizationCheckResult U_EXPORT2
+U_DEPRECATED UNormalizationCheckResult U_EXPORT2
 unorm_quickCheck(const UChar *source, int32_t sourcelength,
                  UNormalizationMode mode,
                  UErrorCode *status);
@@ -255,8 +261,8 @@
  * @see unorm_isNormalized
  * @deprecated ICU 56 Use unorm2.h instead.
  */
-U_STABLE UNormalizationCheckResult U_EXPORT2
-unorm_quickCheckWithOptions(const UChar *src, int32_t srcLength, 
+U_DEPRECATED UNormalizationCheckResult U_EXPORT2
+unorm_quickCheckWithOptions(const UChar *src, int32_t srcLength,
                             UNormalizationMode mode, int32_t options,
                             UErrorCode *pErrorCode);
 
@@ -268,7 +274,7 @@
  * never a "maybe".
  * For NFD, NFKD, and FCD, both functions work exactly the same.
  * For NFC and NFKC where quickCheck may return "maybe", this function will
- * perform further tests to arrive at a TRUE/FALSE result.
+ * perform further tests to arrive at a true/false result.
  *
  * @param src        String that is to be tested if it is in a normalization format.
  * @param srcLength  Length of source to test, or -1 if NUL-terminated.
@@ -281,7 +287,7 @@
  * @see unorm_quickCheck
  * @deprecated ICU 56 Use unorm2.h instead.
  */
-U_STABLE UBool U_EXPORT2
+U_DEPRECATED UBool U_EXPORT2
 unorm_isNormalized(const UChar *src, int32_t srcLength,
                    UNormalizationMode mode,
                    UErrorCode *pErrorCode);
@@ -303,7 +309,7 @@
  * @see unorm_isNormalized
  * @deprecated ICU 56 Use unorm2.h instead.
  */
-U_STABLE UBool U_EXPORT2
+U_DEPRECATED UBool U_EXPORT2
 unorm_isNormalizedWithOptions(const UChar *src, int32_t srcLength,
                               UNormalizationMode mode, int32_t options,
                               UErrorCode *pErrorCode);
@@ -352,10 +358,10 @@
  * It is useful for operations like a normalizing transliterator, where one would
  * not want to replace a piece of text if it is not modified.
  *
- * If doNormalize==TRUE and pNeededToNormalize!=NULL then *pNeeded... is set TRUE
+ * If doNormalize==true and pNeededToNormalize!=NULL then *pNeeded... is set true
  * if the normalization was necessary.
  *
- * If doNormalize==FALSE then *pNeededToNormalize will be set to FALSE.
+ * If doNormalize==false then *pNeededToNormalize will be set to false.
  *
  * If the buffer overflows, then *pNeededToNormalize will be undefined;
  * essentially, whenever U_FAILURE is true (like in buffer overflows), this result
@@ -367,11 +373,11 @@
  * @param mode The normalization mode.
  * @param options The normalization options, ORed together (0 for no options).
  * @param doNormalize Indicates if the source text up to the next boundary
- *                    is to be normalized (TRUE) or just copied (FALSE).
+ *                    is to be normalized (true) or just copied (false).
  * @param pNeededToNormalize Output flag indicating if the normalization resulted in
  *                           different text from the input.
  *                           Not defined if an error occurs including buffer overflow.
- *                           Always FALSE if !doNormalize.
+ *                           Always false if !doNormalize.
  * @param pErrorCode ICU error code in/out parameter.
  *                   Must fulfill U_SUCCESS before the function call.
  * @return Length of output (number of UChars) when successful or buffer overflow.
@@ -381,7 +387,7 @@
  *
  * @deprecated ICU 56 Use unorm2.h instead.
  */
-U_STABLE int32_t U_EXPORT2
+U_DEPRECATED int32_t U_EXPORT2
 unorm_next(UCharIterator *src,
            UChar *dest, int32_t destCapacity,
            UNormalizationMode mode, int32_t options,
@@ -400,11 +406,11 @@
  * @param mode The normalization mode.
  * @param options The normalization options, ORed together (0 for no options).
  * @param doNormalize Indicates if the source text up to the next boundary
- *                    is to be normalized (TRUE) or just copied (FALSE).
+ *                    is to be normalized (true) or just copied (false).
  * @param pNeededToNormalize Output flag indicating if the normalization resulted in
  *                           different text from the input.
  *                           Not defined if an error occurs including buffer overflow.
- *                           Always FALSE if !doNormalize.
+ *                           Always false if !doNormalize.
  * @param pErrorCode ICU error code in/out parameter.
  *                   Must fulfill U_SUCCESS before the function call.
  * @return Length of output (number of UChars) when successful or buffer overflow.
@@ -414,7 +420,7 @@
  *
  * @deprecated ICU 56 Use unorm2.h instead.
  */
-U_STABLE int32_t U_EXPORT2
+U_DEPRECATED int32_t U_EXPORT2
 unorm_previous(UCharIterator *src,
                UChar *dest, int32_t destCapacity,
                UNormalizationMode mode, int32_t options,
@@ -458,7 +464,7 @@
  *
  * @deprecated ICU 56 Use unorm2.h instead.
  */
-U_STABLE int32_t U_EXPORT2
+U_DEPRECATED int32_t U_EXPORT2
 unorm_concatenate(const UChar *left, int32_t leftLength,
                   const UChar *right, int32_t rightLength,
                   UChar *dest, int32_t destCapacity,
diff --git a/src/third_party/icu/source/common/unicode/unorm2.h b/src/third_party/icu/source/common/unicode/unorm2.h
index b557d6a..24417b7 100644
--- a/src/third_party/icu/source/common/unicode/unorm2.h
+++ b/src/third_party/icu/source/common/unicode/unorm2.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  unorm2.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -29,9 +31,13 @@
  */
 
 #include "unicode/utypes.h"
-#include "unicode/localpointer.h"
+#include "unicode/stringoptions.h"
 #include "unicode/uset.h"
 
+#if U_SHOW_CPLUSPLUS_API
+#include "unicode/localpointer.h"
+#endif   // U_SHOW_CPLUSPLUS_API
+
 /**
  * Constants for normalization modes.
  * For details about standard Unicode normalization forms
@@ -129,7 +135,7 @@
  * @return the requested Normalizer2, if successful
  * @stable ICU 49
  */
-U_STABLE const UNormalizer2 * U_EXPORT2
+U_CAPI const UNormalizer2 * U_EXPORT2
 unorm2_getNFCInstance(UErrorCode *pErrorCode);
 
 /**
@@ -143,7 +149,7 @@
  * @return the requested Normalizer2, if successful
  * @stable ICU 49
  */
-U_STABLE const UNormalizer2 * U_EXPORT2
+U_CAPI const UNormalizer2 * U_EXPORT2
 unorm2_getNFDInstance(UErrorCode *pErrorCode);
 
 /**
@@ -157,7 +163,7 @@
  * @return the requested Normalizer2, if successful
  * @stable ICU 49
  */
-U_STABLE const UNormalizer2 * U_EXPORT2
+U_CAPI const UNormalizer2 * U_EXPORT2
 unorm2_getNFKCInstance(UErrorCode *pErrorCode);
 
 /**
@@ -171,7 +177,7 @@
  * @return the requested Normalizer2, if successful
  * @stable ICU 49
  */
-U_STABLE const UNormalizer2 * U_EXPORT2
+U_CAPI const UNormalizer2 * U_EXPORT2
 unorm2_getNFKDInstance(UErrorCode *pErrorCode);
 
 /**
@@ -185,7 +191,7 @@
  * @return the requested Normalizer2, if successful
  * @stable ICU 49
  */
-U_STABLE const UNormalizer2 * U_EXPORT2
+U_CAPI const UNormalizer2 * U_EXPORT2
 unorm2_getNFKCCasefoldInstance(UErrorCode *pErrorCode);
 
 /**
@@ -209,7 +215,7 @@
  * @return the requested UNormalizer2, if successful
  * @stable ICU 4.4
  */
-U_STABLE const UNormalizer2 * U_EXPORT2
+U_CAPI const UNormalizer2 * U_EXPORT2
 unorm2_getInstance(const char *packageName,
                    const char *name,
                    UNormalization2Mode mode,
@@ -230,7 +236,7 @@
  * @return the requested UNormalizer2, if successful
  * @stable ICU 4.4
  */
-U_STABLE UNormalizer2 * U_EXPORT2
+U_CAPI UNormalizer2 * U_EXPORT2
 unorm2_openFiltered(const UNormalizer2 *norm2, const USet *filterSet, UErrorCode *pErrorCode);
 
 /**
@@ -239,7 +245,7 @@
  * @param norm2 UNormalizer2 instance to be closed
  * @stable ICU 4.4
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 unorm2_close(UNormalizer2 *norm2);
 
 #if U_SHOW_CPLUSPLUS_API
@@ -277,7 +283,7 @@
  * @return dest
  * @stable ICU 4.4
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 unorm2_normalize(const UNormalizer2 *norm2,
                  const UChar *src, int32_t length,
                  UChar *dest, int32_t capacity,
@@ -300,7 +306,7 @@
  * @return first
  * @stable ICU 4.4
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 unorm2_normalizeSecondAndAppend(const UNormalizer2 *norm2,
                                 UChar *first, int32_t firstLength, int32_t firstCapacity,
                                 const UChar *second, int32_t secondLength,
@@ -323,7 +329,7 @@
  * @return first
  * @stable ICU 4.4
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 unorm2_append(const UNormalizer2 *norm2,
               UChar *first, int32_t firstLength, int32_t firstCapacity,
               const UChar *second, int32_t secondLength,
@@ -348,7 +354,7 @@
  * @return the non-negative length of c's decomposition, if there is one; otherwise a negative value
  * @stable ICU 4.6
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 unorm2_getDecomposition(const UNormalizer2 *norm2,
                         UChar32 c, UChar *decomposition, int32_t capacity,
                         UErrorCode *pErrorCode);
@@ -382,7 +388,7 @@
  * @return the non-negative length of c's raw decomposition, if there is one; otherwise a negative value
  * @stable ICU 49
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 unorm2_getRawDecomposition(const UNormalizer2 *norm2,
                            UChar32 c, UChar *decomposition, int32_t capacity,
                            UErrorCode *pErrorCode);
@@ -402,7 +408,7 @@
  * @return The non-negative composite code point if there is one; otherwise a negative value.
  * @stable ICU 49
  */
-U_STABLE UChar32 U_EXPORT2
+U_CAPI UChar32 U_EXPORT2
 unorm2_composePair(const UNormalizer2 *norm2, UChar32 a, UChar32 b);
 
 /**
@@ -414,7 +420,7 @@
  * @return c's combining class
  * @stable ICU 49
  */
-U_STABLE uint8_t U_EXPORT2
+U_CAPI uint8_t U_EXPORT2
 unorm2_getCombiningClass(const UNormalizer2 *norm2, UChar32 c);
 
 /**
@@ -430,10 +436,10 @@
  *                   pass the U_SUCCESS() test, or else the function returns
  *                   immediately. Check for U_FAILURE() on output or use with
  *                   function chaining. (See User Guide for details.)
- * @return TRUE if s is normalized
+ * @return true if s is normalized
  * @stable ICU 4.4
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 unorm2_isNormalized(const UNormalizer2 *norm2,
                     const UChar *s, int32_t length,
                     UErrorCode *pErrorCode);
@@ -455,7 +461,7 @@
  * @return UNormalizationCheckResult
  * @stable ICU 4.4
  */
-U_STABLE UNormalizationCheckResult U_EXPORT2
+U_CAPI UNormalizationCheckResult U_EXPORT2
 unorm2_quickCheck(const UNormalizer2 *norm2,
                   const UChar *s, int32_t length,
                   UErrorCode *pErrorCode);
@@ -484,7 +490,7 @@
  * @return "yes" span end index
  * @stable ICU 4.4
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 unorm2_spanQuickCheckYes(const UNormalizer2 *norm2,
                          const UChar *s, int32_t length,
                          UErrorCode *pErrorCode);
@@ -495,10 +501,10 @@
  * For details see the Normalizer2 base class documentation.
  * @param norm2 UNormalizer2 instance
  * @param c character to test
- * @return TRUE if c has a normalization boundary before it
+ * @return true if c has a normalization boundary before it
  * @stable ICU 4.4
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 unorm2_hasBoundaryBefore(const UNormalizer2 *norm2, UChar32 c);
 
 /**
@@ -507,10 +513,10 @@
  * For details see the Normalizer2 base class documentation.
  * @param norm2 UNormalizer2 instance
  * @param c character to test
- * @return TRUE if c has a normalization boundary after it
+ * @return true if c has a normalization boundary after it
  * @stable ICU 4.4
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 unorm2_hasBoundaryAfter(const UNormalizer2 *norm2, UChar32 c);
 
 /**
@@ -518,37 +524,13 @@
  * For details see the Normalizer2 base class documentation.
  * @param norm2 UNormalizer2 instance
  * @param c character to test
- * @return TRUE if c is normalization-inert
+ * @return true if c is normalization-inert
  * @stable ICU 4.4
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 unorm2_isInert(const UNormalizer2 *norm2, UChar32 c);
 
 /**
- * Option bit for unorm_compare:
- * Both input strings are assumed to fulfill FCD conditions.
- * @stable ICU 2.2
- */
-#define UNORM_INPUT_IS_FCD          0x20000
-
-/**
- * Option bit for unorm_compare:
- * Perform case-insensitive comparison.
- * @stable ICU 2.2
- */
-#define U_COMPARE_IGNORE_CASE       0x10000
-
-#ifndef U_COMPARE_CODE_POINT_ORDER
-/* see also unistr.h and ustring.h */
-/**
- * Option bit for u_strCaseCompare, u_strcasecmp, unorm_compare, etc:
- * Compare strings in code point order instead of code unit order.
- * @stable ICU 2.2
- */
-#define U_COMPARE_CODE_POINT_ORDER  0x8000
-#endif
-
-/**
  * Compares two strings for canonical equivalence.
  * Further options include case-insensitive comparison and
  * code point order (as opposed to code unit order).
@@ -614,7 +596,7 @@
  *
  * @stable ICU 2.2
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 unorm_compare(const UChar *s1, int32_t length1,
               const UChar *s2, int32_t length2,
               uint32_t options,
diff --git a/src/third_party/icu/source/common/unicode/uobject.h b/src/third_party/icu/source/common/unicode/uobject.h
index 54ceace..eeb331c 100644
--- a/src/third_party/icu/source/common/unicode/uobject.h
+++ b/src/third_party/icu/source/common/unicode/uobject.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 ******************************************************************************
 *   file name:  uobject.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -19,15 +21,20 @@
 
 #include "unicode/utypes.h"
 
+#if U_SHOW_CPLUSPLUS_API
+
+#include "unicode/platform.h"
+
 /**
  * \file
  * \brief C++ API: Common ICU base class UObject.
  */
 
 /**
- * @{
  * \def U_NO_THROW
- *         Define this to define the throw() specification so
+ *         Since ICU 64, use U_NOEXCEPT instead.
+ *
+ *         Previously, define this to define the throw() specification so
  *                 certain functions do not throw any exceptions
  *
  *         UMemory operator new methods should have the throw() specification 
@@ -36,14 +43,12 @@
  *         constructor is still called, and if the constructor references member 
  *         data, (which it typically does), the result is a segmentation violation.
  *
- * @stable ICU 4.2
+ * @stable ICU 4.2. Since ICU 64, Use U_NOEXCEPT instead. See ICU-20422.
  */
 #ifndef U_NO_THROW
-#define U_NO_THROW throw()
+#define U_NO_THROW U_NOEXCEPT
 #endif
 
-/** @} */
-
 /*===========================================================================*/
 /* UClassID-based RTTI */
 /*===========================================================================*/
@@ -126,14 +131,14 @@
      * for ICU4C C++ classes
      * @stable ICU 2.4
      */
-    static void * U_EXPORT2 operator new(size_t size) U_NO_THROW;
+    static void * U_EXPORT2 operator new(size_t size) U_NOEXCEPT;
 
     /**
      * Override for ICU4C C++ memory management.
      * See new().
      * @stable ICU 2.4
      */
-    static void * U_EXPORT2 operator new[](size_t size) U_NO_THROW;
+    static void * U_EXPORT2 operator new[](size_t size) U_NOEXCEPT;
 
     /**
      * Override for ICU4C C++ memory management.
@@ -143,14 +148,14 @@
      * for ICU4C C++ classes
      * @stable ICU 2.4
      */
-    static void U_EXPORT2 operator delete(void *p) U_NO_THROW;
+    static void U_EXPORT2 operator delete(void *p) U_NOEXCEPT;
 
     /**
      * Override for ICU4C C++ memory management.
      * See delete().
      * @stable ICU 2.4
      */
-    static void U_EXPORT2 operator delete[](void *p) U_NO_THROW;
+    static void U_EXPORT2 operator delete[](void *p) U_NOEXCEPT;
 
 #if U_HAVE_PLACEMENT_NEW
     /**
@@ -158,14 +163,14 @@
      * See new().
      * @stable ICU 2.6
      */
-    static inline void * U_EXPORT2 operator new(size_t, void *ptr) U_NO_THROW { return ptr; }
+    static inline void * U_EXPORT2 operator new(size_t, void *ptr) U_NOEXCEPT { return ptr; }
 
     /**
      * Override for ICU4C C++ memory management for STL.
      * See delete().
      * @stable ICU 2.6
      */
-    static inline void U_EXPORT2 operator delete(void *, void *) U_NO_THROW {}
+    static inline void U_EXPORT2 operator delete(void *, void *) U_NOEXCEPT {}
 #endif /* U_HAVE_PLACEMENT_NEW */
 #if U_HAVE_DEBUG_LOCATION_NEW
     /**
@@ -175,7 +180,7 @@
       * @param file   The file where the allocation was requested
       * @param line   The line where the allocation was requested 
       */ 
-    static void * U_EXPORT2 operator new(size_t size, const char* file, int line) U_NO_THROW;
+    static void * U_EXPORT2 operator new(size_t size, const char* file, int line) U_NOEXCEPT;
     /**
       * This method provides a matching delete for the MFC debug new
       * 
@@ -183,7 +188,7 @@
       * @param file   The file where the allocation was requested
       * @param line   The line where the allocation was requested 
       */ 
-    static void U_EXPORT2 operator delete(void* p, const char* file, int line) U_NO_THROW;
+    static void U_EXPORT2 operator delete(void* p, const char* file, int line) U_NOEXCEPT;
 #endif /* U_HAVE_DEBUG_LOCATION_NEW */
 #endif /* U_OVERRIDE_CXX_ALLOCATION */
 
@@ -210,11 +215,8 @@
  * The clone() function is not available in UObject because it is not
  * implemented by all ICU classes.
  * Many ICU services provide a clone() function for their class trees,
- * defined on the service's C++ base class, and all subclasses within that
- * service class tree return a pointer to the service base class
+ * defined on the service's C++ base class
  * (which itself is a subclass of UObject).
- * This is because some compilers do not support covariant (same-as-this)
- * return types; cast to the appropriate subclass if necessary.
  *
  * @stable ICU 2.2
  */
@@ -317,4 +319,6 @@
 
 U_NAMESPACE_END
 
+#endif /* U_SHOW_CPLUSPLUS_API */
+
 #endif
diff --git a/src/third_party/icu/source/common/unicode/urename.h b/src/third_party/icu/source/common/unicode/urename.h
index 4a68f94..20232cd 100644
--- a/src/third_party/icu/source/common/unicode/urename.h
+++ b/src/third_party/icu/source/common/unicode/urename.h
@@ -1,11 +1,13 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
-*   Copyright (C) 2002-2015, International Business Machines
+*   Copyright (C) 2002-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *******************************************************************************
 *
 *   file name:  urename.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -31,6 +33,9 @@
 
 #if !U_DISABLE_RENAMING
 
+// Disable Renaming for Visual Studio's IntelliSense feature, so that 'Go-to-Definition' (F12) will work.
+#if !(defined(_MSC_VER) && defined(__INTELLISENSE__))
+
 /* We need the U_ICU_ENTRY_POINT_RENAME definition. There's a default one in unicode/uvernum.h we can use, but we will give
    the platform a chance to define it first.
    Normally (if utypes.h or umachine.h was included first) this will not be necessary as it will already be defined.
@@ -98,13 +103,19 @@
 #define _UTF16BEData U_ICU_ENTRY_POINT_RENAME(_UTF16BEData)
 #define _UTF16Data U_ICU_ENTRY_POINT_RENAME(_UTF16Data)
 #define _UTF16LEData U_ICU_ENTRY_POINT_RENAME(_UTF16LEData)
+#define _UTF16v2Data U_ICU_ENTRY_POINT_RENAME(_UTF16v2Data)
 #define _UTF32BEData U_ICU_ENTRY_POINT_RENAME(_UTF32BEData)
 #define _UTF32Data U_ICU_ENTRY_POINT_RENAME(_UTF32Data)
 #define _UTF32LEData U_ICU_ENTRY_POINT_RENAME(_UTF32LEData)
 #define _UTF7Data U_ICU_ENTRY_POINT_RENAME(_UTF7Data)
 #define _UTF8Data U_ICU_ENTRY_POINT_RENAME(_UTF8Data)
+#define _isUnicodeLocaleTypeSubtag U_ICU_ENTRY_POINT_RENAME(_isUnicodeLocaleTypeSubtag)
+#define allowedHourFormatsCleanup U_ICU_ENTRY_POINT_RENAME(allowedHourFormatsCleanup)
 #define cmemory_cleanup U_ICU_ENTRY_POINT_RENAME(cmemory_cleanup)
+#define dayPeriodRulesCleanup U_ICU_ENTRY_POINT_RENAME(dayPeriodRulesCleanup)
+#define deleteAllowedHourFormats U_ICU_ENTRY_POINT_RENAME(deleteAllowedHourFormats)
 #define gTimeZoneFilesInitOnce U_ICU_ENTRY_POINT_RENAME(gTimeZoneFilesInitOnce)
+#define initNumsysNames U_ICU_ENTRY_POINT_RENAME(initNumsysNames)
 #define izrule_clone U_ICU_ENTRY_POINT_RENAME(izrule_clone)
 #define izrule_close U_ICU_ENTRY_POINT_RENAME(izrule_close)
 #define izrule_equals U_ICU_ENTRY_POINT_RENAME(izrule_equals)
@@ -119,20 +130,11 @@
 #define izrule_getStaticClassID U_ICU_ENTRY_POINT_RENAME(izrule_getStaticClassID)
 #define izrule_isEquivalentTo U_ICU_ENTRY_POINT_RENAME(izrule_isEquivalentTo)
 #define izrule_open U_ICU_ENTRY_POINT_RENAME(izrule_open)
-#define le_close U_ICU_ENTRY_POINT_RENAME(le_close)
-#define le_create U_ICU_ENTRY_POINT_RENAME(le_create)
-#define le_getCharIndices U_ICU_ENTRY_POINT_RENAME(le_getCharIndices)
-#define le_getCharIndicesWithBase U_ICU_ENTRY_POINT_RENAME(le_getCharIndicesWithBase)
-#define le_getGlyphCount U_ICU_ENTRY_POINT_RENAME(le_getGlyphCount)
-#define le_getGlyphPosition U_ICU_ENTRY_POINT_RENAME(le_getGlyphPosition)
-#define le_getGlyphPositions U_ICU_ENTRY_POINT_RENAME(le_getGlyphPositions)
-#define le_getGlyphs U_ICU_ENTRY_POINT_RENAME(le_getGlyphs)
-#define le_layoutChars U_ICU_ENTRY_POINT_RENAME(le_layoutChars)
-#define le_reset U_ICU_ENTRY_POINT_RENAME(le_reset)
-#define locale_getKeywords U_ICU_ENTRY_POINT_RENAME(locale_getKeywords)
 #define locale_getKeywordsStart U_ICU_ENTRY_POINT_RENAME(locale_getKeywordsStart)
 #define locale_get_default U_ICU_ENTRY_POINT_RENAME(locale_get_default)
 #define locale_set_default U_ICU_ENTRY_POINT_RENAME(locale_set_default)
+#define numSysCleanup U_ICU_ENTRY_POINT_RENAME(numSysCleanup)
+#define rbbi_cleanup U_ICU_ENTRY_POINT_RENAME(rbbi_cleanup)
 #define pl_addFontRun U_ICU_ENTRY_POINT_RENAME(pl_addFontRun)
 #define pl_addLocaleRun U_ICU_ENTRY_POINT_RENAME(pl_addLocaleRun)
 #define pl_addValueRun U_ICU_ENTRY_POINT_RENAME(pl_addValueRun)
@@ -190,17 +192,18 @@
 #define res_findResource U_ICU_ENTRY_POINT_RENAME(res_findResource)
 #define res_getAlias U_ICU_ENTRY_POINT_RENAME(res_getAlias)
 #define res_getArrayItem U_ICU_ENTRY_POINT_RENAME(res_getArrayItem)
-#define res_getBinary U_ICU_ENTRY_POINT_RENAME(res_getBinary)
-#define res_getIntVector U_ICU_ENTRY_POINT_RENAME(res_getIntVector)
+#define res_getBinaryNoTrace U_ICU_ENTRY_POINT_RENAME(res_getBinaryNoTrace)
+#define res_getIntVectorNoTrace U_ICU_ENTRY_POINT_RENAME(res_getIntVectorNoTrace)
 #define res_getPublicType U_ICU_ENTRY_POINT_RENAME(res_getPublicType)
 #define res_getResource U_ICU_ENTRY_POINT_RENAME(res_getResource)
-#define res_getString U_ICU_ENTRY_POINT_RENAME(res_getString)
+#define res_getStringNoTrace U_ICU_ENTRY_POINT_RENAME(res_getStringNoTrace)
 #define res_getTableItemByIndex U_ICU_ENTRY_POINT_RENAME(res_getTableItemByIndex)
 #define res_getTableItemByKey U_ICU_ENTRY_POINT_RENAME(res_getTableItemByKey)
 #define res_load U_ICU_ENTRY_POINT_RENAME(res_load)
 #define res_read U_ICU_ENTRY_POINT_RENAME(res_read)
 #define res_unload U_ICU_ENTRY_POINT_RENAME(res_unload)
 #define u_UCharsToChars U_ICU_ENTRY_POINT_RENAME(u_UCharsToChars)
+#define u_asciiToUpper U_ICU_ENTRY_POINT_RENAME(u_asciiToUpper)
 #define u_austrcpy U_ICU_ENTRY_POINT_RENAME(u_austrcpy)
 #define u_austrncpy U_ICU_ENTRY_POINT_RENAME(u_austrncpy)
 #define u_caseInsensitivePrefixMatch U_ICU_ENTRY_POINT_RENAME(u_caseInsensitivePrefixMatch)
@@ -257,12 +260,14 @@
 #define u_fstropen U_ICU_ENTRY_POINT_RENAME(u_fstropen)
 #define u_fungetc U_ICU_ENTRY_POINT_RENAME(u_fungetc)
 #define u_getBidiPairedBracket U_ICU_ENTRY_POINT_RENAME(u_getBidiPairedBracket)
+#define u_getBinaryPropertySet U_ICU_ENTRY_POINT_RENAME(u_getBinaryPropertySet)
 #define u_getCombiningClass U_ICU_ENTRY_POINT_RENAME(u_getCombiningClass)
 #define u_getDataDirectory U_ICU_ENTRY_POINT_RENAME(u_getDataDirectory)
 #define u_getDataVersion U_ICU_ENTRY_POINT_RENAME(u_getDataVersion)
 #define u_getDefaultConverter U_ICU_ENTRY_POINT_RENAME(u_getDefaultConverter)
 #define u_getFC_NFKC_Closure U_ICU_ENTRY_POINT_RENAME(u_getFC_NFKC_Closure)
 #define u_getISOComment U_ICU_ENTRY_POINT_RENAME(u_getISOComment)
+#define u_getIntPropertyMap U_ICU_ENTRY_POINT_RENAME(u_getIntPropertyMap)
 #define u_getIntPropertyMaxValue U_ICU_ENTRY_POINT_RENAME(u_getIntPropertyMaxValue)
 #define u_getIntPropertyMinValue U_ICU_ENTRY_POINT_RENAME(u_getIntPropertyMinValue)
 #define u_getIntPropertyValue U_ICU_ENTRY_POINT_RENAME(u_getIntPropertyValue)
@@ -449,7 +454,6 @@
 #define ubidi_getReorderingOptions U_ICU_ENTRY_POINT_RENAME(ubidi_getReorderingOptions)
 #define ubidi_getResultLength U_ICU_ENTRY_POINT_RENAME(ubidi_getResultLength)
 #define ubidi_getRuns U_ICU_ENTRY_POINT_RENAME(ubidi_getRuns)
-#define ubidi_getSingleton U_ICU_ENTRY_POINT_RENAME(ubidi_getSingleton)
 #define ubidi_getText U_ICU_ENTRY_POINT_RENAME(ubidi_getText)
 #define ubidi_getVisualIndex U_ICU_ENTRY_POINT_RENAME(ubidi_getVisualIndex)
 #define ubidi_getVisualMap U_ICU_ENTRY_POINT_RENAME(ubidi_getVisualMap)
@@ -474,6 +478,9 @@
 #define ubidi_setReorderingOptions U_ICU_ENTRY_POINT_RENAME(ubidi_setReorderingOptions)
 #define ubidi_writeReordered U_ICU_ENTRY_POINT_RENAME(ubidi_writeReordered)
 #define ubidi_writeReverse U_ICU_ENTRY_POINT_RENAME(ubidi_writeReverse)
+#define ubiditransform_close U_ICU_ENTRY_POINT_RENAME(ubiditransform_close)
+#define ubiditransform_open U_ICU_ENTRY_POINT_RENAME(ubiditransform_open)
+#define ubiditransform_transform U_ICU_ENTRY_POINT_RENAME(ubiditransform_transform)
 #define ublock_getCode U_ICU_ENTRY_POINT_RENAME(ublock_getCode)
 #define ubrk_close U_ICU_ENTRY_POINT_RENAME(ubrk_close)
 #define ubrk_countAvailable U_ICU_ENTRY_POINT_RENAME(ubrk_countAvailable)
@@ -481,6 +488,7 @@
 #define ubrk_first U_ICU_ENTRY_POINT_RENAME(ubrk_first)
 #define ubrk_following U_ICU_ENTRY_POINT_RENAME(ubrk_following)
 #define ubrk_getAvailable U_ICU_ENTRY_POINT_RENAME(ubrk_getAvailable)
+#define ubrk_getBinaryRules U_ICU_ENTRY_POINT_RENAME(ubrk_getBinaryRules)
 #define ubrk_getLocaleByType U_ICU_ENTRY_POINT_RENAME(ubrk_getLocaleByType)
 #define ubrk_getRuleStatus U_ICU_ENTRY_POINT_RENAME(ubrk_getRuleStatus)
 #define ubrk_getRuleStatusVec U_ICU_ENTRY_POINT_RENAME(ubrk_getRuleStatusVec)
@@ -488,6 +496,7 @@
 #define ubrk_last U_ICU_ENTRY_POINT_RENAME(ubrk_last)
 #define ubrk_next U_ICU_ENTRY_POINT_RENAME(ubrk_next)
 #define ubrk_open U_ICU_ENTRY_POINT_RENAME(ubrk_open)
+#define ubrk_openBinaryRules U_ICU_ENTRY_POINT_RENAME(ubrk_openBinaryRules)
 #define ubrk_openRules U_ICU_ENTRY_POINT_RENAME(ubrk_openRules)
 #define ubrk_preceding U_ICU_ENTRY_POINT_RENAME(ubrk_preceding)
 #define ubrk_previous U_ICU_ENTRY_POINT_RENAME(ubrk_previous)
@@ -515,6 +524,7 @@
 #define ucal_getDefaultTimeZone U_ICU_ENTRY_POINT_RENAME(ucal_getDefaultTimeZone)
 #define ucal_getFieldDifference U_ICU_ENTRY_POINT_RENAME(ucal_getFieldDifference)
 #define ucal_getGregorianChange U_ICU_ENTRY_POINT_RENAME(ucal_getGregorianChange)
+#define ucal_getHostTimeZone U_ICU_ENTRY_POINT_RENAME(ucal_getHostTimeZone)
 #define ucal_getKeywordValuesForLocale U_ICU_ENTRY_POINT_RENAME(ucal_getKeywordValuesForLocale)
 #define ucal_getLimit U_ICU_ENTRY_POINT_RENAME(ucal_getLimit)
 #define ucal_getLocaleByType U_ICU_ENTRY_POINT_RENAME(ucal_getLocaleByType)
@@ -549,7 +559,7 @@
 #define ucase_addStringCaseClosure U_ICU_ENTRY_POINT_RENAME(ucase_addStringCaseClosure)
 #define ucase_fold U_ICU_ENTRY_POINT_RENAME(ucase_fold)
 #define ucase_getCaseLocale U_ICU_ENTRY_POINT_RENAME(ucase_getCaseLocale)
-#define ucase_getSingleton U_ICU_ENTRY_POINT_RENAME(ucase_getSingleton)
+#define ucase_getTrie U_ICU_ENTRY_POINT_RENAME(ucase_getTrie)
 #define ucase_getType U_ICU_ENTRY_POINT_RENAME(ucase_getType)
 #define ucase_getTypeOrIgnorable U_ICU_ENTRY_POINT_RENAME(ucase_getTypeOrIgnorable)
 #define ucase_hasBinaryProperty U_ICU_ENTRY_POINT_RENAME(ucase_hasBinaryProperty)
@@ -567,7 +577,6 @@
 #define ucasemap_getLocale U_ICU_ENTRY_POINT_RENAME(ucasemap_getLocale)
 #define ucasemap_getOptions U_ICU_ENTRY_POINT_RENAME(ucasemap_getOptions)
 #define ucasemap_internalUTF8ToTitle U_ICU_ENTRY_POINT_RENAME(ucasemap_internalUTF8ToTitle)
-#define ucasemap_mapUTF8 U_ICU_ENTRY_POINT_RENAME(ucasemap_mapUTF8)
 #define ucasemap_open U_ICU_ENTRY_POINT_RENAME(ucasemap_open)
 #define ucasemap_setBreakIterator U_ICU_ENTRY_POINT_RENAME(ucasemap_setBreakIterator)
 #define ucasemap_setLocale U_ICU_ENTRY_POINT_RENAME(ucasemap_setLocale)
@@ -577,6 +586,18 @@
 #define ucasemap_utf8ToLower U_ICU_ENTRY_POINT_RENAME(ucasemap_utf8ToLower)
 #define ucasemap_utf8ToTitle U_ICU_ENTRY_POINT_RENAME(ucasemap_utf8ToTitle)
 #define ucasemap_utf8ToUpper U_ICU_ENTRY_POINT_RENAME(ucasemap_utf8ToUpper)
+#define ucfpos_close U_ICU_ENTRY_POINT_RENAME(ucfpos_close)
+#define ucfpos_constrainCategory U_ICU_ENTRY_POINT_RENAME(ucfpos_constrainCategory)
+#define ucfpos_constrainField U_ICU_ENTRY_POINT_RENAME(ucfpos_constrainField)
+#define ucfpos_getCategory U_ICU_ENTRY_POINT_RENAME(ucfpos_getCategory)
+#define ucfpos_getField U_ICU_ENTRY_POINT_RENAME(ucfpos_getField)
+#define ucfpos_getIndexes U_ICU_ENTRY_POINT_RENAME(ucfpos_getIndexes)
+#define ucfpos_getInt64IterationContext U_ICU_ENTRY_POINT_RENAME(ucfpos_getInt64IterationContext)
+#define ucfpos_matchesField U_ICU_ENTRY_POINT_RENAME(ucfpos_matchesField)
+#define ucfpos_open U_ICU_ENTRY_POINT_RENAME(ucfpos_open)
+#define ucfpos_reset U_ICU_ENTRY_POINT_RENAME(ucfpos_reset)
+#define ucfpos_setInt64IterationContext U_ICU_ENTRY_POINT_RENAME(ucfpos_setInt64IterationContext)
+#define ucfpos_setState U_ICU_ENTRY_POINT_RENAME(ucfpos_setState)
 #define uchar_addPropertyStarts U_ICU_ENTRY_POINT_RENAME(uchar_addPropertyStarts)
 #define uchar_swapNames U_ICU_ENTRY_POINT_RENAME(uchar_swapNames)
 #define ucln_cleanupOne U_ICU_ENTRY_POINT_RENAME(ucln_cleanupOne)
@@ -613,6 +634,7 @@
 #define ucnv_createConverterFromPackage U_ICU_ENTRY_POINT_RENAME(ucnv_createConverterFromPackage)
 #define ucnv_createConverterFromSharedData U_ICU_ENTRY_POINT_RENAME(ucnv_createConverterFromSharedData)
 #define ucnv_detectUnicodeSignature U_ICU_ENTRY_POINT_RENAME(ucnv_detectUnicodeSignature)
+#define ucnv_enableCleanup U_ICU_ENTRY_POINT_RENAME(ucnv_enableCleanup)
 #define ucnv_extContinueMatchFromU U_ICU_ENTRY_POINT_RENAME(ucnv_extContinueMatchFromU)
 #define ucnv_extContinueMatchToU U_ICU_ENTRY_POINT_RENAME(ucnv_extContinueMatchToU)
 #define ucnv_extGetUnicodeSet U_ICU_ENTRY_POINT_RENAME(ucnv_extGetUnicodeSet)
@@ -762,6 +784,20 @@
 #define ucol_swap U_ICU_ENTRY_POINT_RENAME(ucol_swap)
 #define ucol_swapInverseUCA U_ICU_ENTRY_POINT_RENAME(ucol_swapInverseUCA)
 #define ucol_tertiaryOrder U_ICU_ENTRY_POINT_RENAME(ucol_tertiaryOrder)
+#define ucpmap_get U_ICU_ENTRY_POINT_RENAME(ucpmap_get)
+#define ucpmap_getRange U_ICU_ENTRY_POINT_RENAME(ucpmap_getRange)
+#define ucptrie_close U_ICU_ENTRY_POINT_RENAME(ucptrie_close)
+#define ucptrie_get U_ICU_ENTRY_POINT_RENAME(ucptrie_get)
+#define ucptrie_getRange U_ICU_ENTRY_POINT_RENAME(ucptrie_getRange)
+#define ucptrie_getType U_ICU_ENTRY_POINT_RENAME(ucptrie_getType)
+#define ucptrie_getValueWidth U_ICU_ENTRY_POINT_RENAME(ucptrie_getValueWidth)
+#define ucptrie_internalGetRange U_ICU_ENTRY_POINT_RENAME(ucptrie_internalGetRange)
+#define ucptrie_internalSmallIndex U_ICU_ENTRY_POINT_RENAME(ucptrie_internalSmallIndex)
+#define ucptrie_internalSmallU8Index U_ICU_ENTRY_POINT_RENAME(ucptrie_internalSmallU8Index)
+#define ucptrie_internalU8PrevIndex U_ICU_ENTRY_POINT_RENAME(ucptrie_internalU8PrevIndex)
+#define ucptrie_openFromBinary U_ICU_ENTRY_POINT_RENAME(ucptrie_openFromBinary)
+#define ucptrie_swap U_ICU_ENTRY_POINT_RENAME(ucptrie_swap)
+#define ucptrie_toBinary U_ICU_ENTRY_POINT_RENAME(ucptrie_toBinary)
 #define ucsdet_close U_ICU_ENTRY_POINT_RENAME(ucsdet_close)
 #define ucsdet_detect U_ICU_ENTRY_POINT_RENAME(ucsdet_detect)
 #define ucsdet_detectAll U_ICU_ENTRY_POINT_RENAME(ucsdet_detectAll)
@@ -861,6 +897,8 @@
 #define udatpg_getBestPatternWithOptions U_ICU_ENTRY_POINT_RENAME(udatpg_getBestPatternWithOptions)
 #define udatpg_getDateTimeFormat U_ICU_ENTRY_POINT_RENAME(udatpg_getDateTimeFormat)
 #define udatpg_getDecimal U_ICU_ENTRY_POINT_RENAME(udatpg_getDecimal)
+#define udatpg_getDefaultHourCycle U_ICU_ENTRY_POINT_RENAME(udatpg_getDefaultHourCycle)
+#define udatpg_getFieldDisplayName U_ICU_ENTRY_POINT_RENAME(udatpg_getFieldDisplayName)
 #define udatpg_getPatternForSkeleton U_ICU_ENTRY_POINT_RENAME(udatpg_getPatternForSkeleton)
 #define udatpg_getSkeleton U_ICU_ENTRY_POINT_RENAME(udatpg_getSkeleton)
 #define udatpg_open U_ICU_ENTRY_POINT_RENAME(udatpg_open)
@@ -875,8 +913,15 @@
 #define udatpg_setDecimal U_ICU_ENTRY_POINT_RENAME(udatpg_setDecimal)
 #define udict_swap U_ICU_ENTRY_POINT_RENAME(udict_swap)
 #define udtitvfmt_close U_ICU_ENTRY_POINT_RENAME(udtitvfmt_close)
+#define udtitvfmt_closeResult U_ICU_ENTRY_POINT_RENAME(udtitvfmt_closeResult)
 #define udtitvfmt_format U_ICU_ENTRY_POINT_RENAME(udtitvfmt_format)
+#define udtitvfmt_formatCalendarToResult U_ICU_ENTRY_POINT_RENAME(udtitvfmt_formatCalendarToResult)
+#define udtitvfmt_formatToResult U_ICU_ENTRY_POINT_RENAME(udtitvfmt_formatToResult)
+#define udtitvfmt_getContext U_ICU_ENTRY_POINT_RENAME(udtitvfmt_getContext)
 #define udtitvfmt_open U_ICU_ENTRY_POINT_RENAME(udtitvfmt_open)
+#define udtitvfmt_openResult U_ICU_ENTRY_POINT_RENAME(udtitvfmt_openResult)
+#define udtitvfmt_resultAsValue U_ICU_ENTRY_POINT_RENAME(udtitvfmt_resultAsValue)
+#define udtitvfmt_setContext U_ICU_ENTRY_POINT_RENAME(udtitvfmt_setContext)
 #define uenum_close U_ICU_ENTRY_POINT_RENAME(uenum_close)
 #define uenum_count U_ICU_ENTRY_POINT_RENAME(uenum_count)
 #define uenum_next U_ICU_ENTRY_POINT_RENAME(uenum_next)
@@ -890,16 +935,9 @@
 #define ufieldpositer_close U_ICU_ENTRY_POINT_RENAME(ufieldpositer_close)
 #define ufieldpositer_next U_ICU_ENTRY_POINT_RENAME(ufieldpositer_next)
 #define ufieldpositer_open U_ICU_ENTRY_POINT_RENAME(ufieldpositer_open)
-#define ufile_close_translit U_ICU_ENTRY_POINT_RENAME(ufile_close_translit)
-#define ufile_fill_uchar_buffer U_ICU_ENTRY_POINT_RENAME(ufile_fill_uchar_buffer)
-#define ufile_flush_io U_ICU_ENTRY_POINT_RENAME(ufile_flush_io)
-#define ufile_flush_translit U_ICU_ENTRY_POINT_RENAME(ufile_flush_translit)
 #define ufile_getch U_ICU_ENTRY_POINT_RENAME(ufile_getch)
 #define ufile_getch32 U_ICU_ENTRY_POINT_RENAME(ufile_getch32)
-#define ufmt_64tou U_ICU_ENTRY_POINT_RENAME(ufmt_64tou)
 #define ufmt_close U_ICU_ENTRY_POINT_RENAME(ufmt_close)
-#define ufmt_defaultCPToUnicode U_ICU_ENTRY_POINT_RENAME(ufmt_defaultCPToUnicode)
-#define ufmt_digitvalue U_ICU_ENTRY_POINT_RENAME(ufmt_digitvalue)
 #define ufmt_getArrayItemByIndex U_ICU_ENTRY_POINT_RENAME(ufmt_getArrayItemByIndex)
 #define ufmt_getArrayLength U_ICU_ENTRY_POINT_RENAME(ufmt_getArrayLength)
 #define ufmt_getDate U_ICU_ENTRY_POINT_RENAME(ufmt_getDate)
@@ -911,11 +949,9 @@
 #define ufmt_getType U_ICU_ENTRY_POINT_RENAME(ufmt_getType)
 #define ufmt_getUChars U_ICU_ENTRY_POINT_RENAME(ufmt_getUChars)
 #define ufmt_isNumeric U_ICU_ENTRY_POINT_RENAME(ufmt_isNumeric)
-#define ufmt_isdigit U_ICU_ENTRY_POINT_RENAME(ufmt_isdigit)
 #define ufmt_open U_ICU_ENTRY_POINT_RENAME(ufmt_open)
-#define ufmt_ptou U_ICU_ENTRY_POINT_RENAME(ufmt_ptou)
-#define ufmt_uto64 U_ICU_ENTRY_POINT_RENAME(ufmt_uto64)
-#define ufmt_utop U_ICU_ENTRY_POINT_RENAME(ufmt_utop)
+#define ufmtval_getString U_ICU_ENTRY_POINT_RENAME(ufmtval_getString)
+#define ufmtval_nextPosition U_ICU_ENTRY_POINT_RENAME(ufmtval_nextPosition)
 #define ugender_getInstance U_ICU_ENTRY_POINT_RENAME(ugender_getInstance)
 #define ugender_getListGender U_ICU_ENTRY_POINT_RENAME(ugender_getListGender)
 #define uhash_close U_ICU_ENTRY_POINT_RENAME(uhash_close)
@@ -944,6 +980,7 @@
 #define uhash_iget U_ICU_ENTRY_POINT_RENAME(uhash_iget)
 #define uhash_igeti U_ICU_ENTRY_POINT_RENAME(uhash_igeti)
 #define uhash_init U_ICU_ENTRY_POINT_RENAME(uhash_init)
+#define uhash_initSize U_ICU_ENTRY_POINT_RENAME(uhash_initSize)
 #define uhash_iput U_ICU_ENTRY_POINT_RENAME(uhash_iput)
 #define uhash_iputi U_ICU_ENTRY_POINT_RENAME(uhash_iputi)
 #define uhash_iremove U_ICU_ENTRY_POINT_RENAME(uhash_iremove)
@@ -1013,11 +1050,17 @@
 #define ulist_getListSize U_ICU_ENTRY_POINT_RENAME(ulist_getListSize)
 #define ulist_getNext U_ICU_ENTRY_POINT_RENAME(ulist_getNext)
 #define ulist_next_keyword_value U_ICU_ENTRY_POINT_RENAME(ulist_next_keyword_value)
+#define ulist_removeString U_ICU_ENTRY_POINT_RENAME(ulist_removeString)
 #define ulist_resetList U_ICU_ENTRY_POINT_RENAME(ulist_resetList)
 #define ulist_reset_keyword_values_iterator U_ICU_ENTRY_POINT_RENAME(ulist_reset_keyword_values_iterator)
 #define ulistfmt_close U_ICU_ENTRY_POINT_RENAME(ulistfmt_close)
+#define ulistfmt_closeResult U_ICU_ENTRY_POINT_RENAME(ulistfmt_closeResult)
 #define ulistfmt_format U_ICU_ENTRY_POINT_RENAME(ulistfmt_format)
+#define ulistfmt_formatStringsToResult U_ICU_ENTRY_POINT_RENAME(ulistfmt_formatStringsToResult)
 #define ulistfmt_open U_ICU_ENTRY_POINT_RENAME(ulistfmt_open)
+#define ulistfmt_openForType U_ICU_ENTRY_POINT_RENAME(ulistfmt_openForType)
+#define ulistfmt_openResult U_ICU_ENTRY_POINT_RENAME(ulistfmt_openResult)
+#define ulistfmt_resultAsValue U_ICU_ENTRY_POINT_RENAME(ulistfmt_resultAsValue)
 #define uloc_acceptLanguage U_ICU_ENTRY_POINT_RENAME(uloc_acceptLanguage)
 #define uloc_acceptLanguageFromHTTP U_ICU_ENTRY_POINT_RENAME(uloc_acceptLanguageFromHTTP)
 #define uloc_addLikelySubtags U_ICU_ENTRY_POINT_RENAME(uloc_addLikelySubtags)
@@ -1037,7 +1080,6 @@
 #define uloc_getDisplayLanguage U_ICU_ENTRY_POINT_RENAME(uloc_getDisplayLanguage)
 #define uloc_getDisplayName U_ICU_ENTRY_POINT_RENAME(uloc_getDisplayName)
 #define uloc_getDisplayScript U_ICU_ENTRY_POINT_RENAME(uloc_getDisplayScript)
-#define uloc_getDisplayScriptInContext U_ICU_ENTRY_POINT_RENAME(uloc_getDisplayScriptInContext)
 #define uloc_getDisplayVariant U_ICU_ENTRY_POINT_RENAME(uloc_getDisplayVariant)
 #define uloc_getISO3Country U_ICU_ENTRY_POINT_RENAME(uloc_getISO3Country)
 #define uloc_getISO3Language U_ICU_ENTRY_POINT_RENAME(uloc_getISO3Language)
@@ -1055,6 +1097,7 @@
 #define uloc_getVariant U_ICU_ENTRY_POINT_RENAME(uloc_getVariant)
 #define uloc_isRightToLeft U_ICU_ENTRY_POINT_RENAME(uloc_isRightToLeft)
 #define uloc_minimizeSubtags U_ICU_ENTRY_POINT_RENAME(uloc_minimizeSubtags)
+#define uloc_openAvailableByType U_ICU_ENTRY_POINT_RENAME(uloc_openAvailableByType)
 #define uloc_openKeywordList U_ICU_ENTRY_POINT_RENAME(uloc_openKeywordList)
 #define uloc_openKeywords U_ICU_ENTRY_POINT_RENAME(uloc_openKeywords)
 #define uloc_setDefault U_ICU_ENTRY_POINT_RENAME(uloc_setDefault)
@@ -1075,15 +1118,37 @@
 #define ulocdata_getPaperSize U_ICU_ENTRY_POINT_RENAME(ulocdata_getPaperSize)
 #define ulocdata_open U_ICU_ENTRY_POINT_RENAME(ulocdata_open)
 #define ulocdata_setNoSubstitute U_ICU_ENTRY_POINT_RENAME(ulocdata_setNoSubstitute)
+#define ulocimp_addLikelySubtags U_ICU_ENTRY_POINT_RENAME(ulocimp_addLikelySubtags)
+#define ulocimp_canonicalize U_ICU_ENTRY_POINT_RENAME(ulocimp_canonicalize)
+#define ulocimp_forLanguageTag U_ICU_ENTRY_POINT_RENAME(ulocimp_forLanguageTag)
+#define ulocimp_getBaseName U_ICU_ENTRY_POINT_RENAME(ulocimp_getBaseName)
 #define ulocimp_getCountry U_ICU_ENTRY_POINT_RENAME(ulocimp_getCountry)
+#define ulocimp_getKeywordValue U_ICU_ENTRY_POINT_RENAME(ulocimp_getKeywordValue)
+#define ulocimp_getKeywords U_ICU_ENTRY_POINT_RENAME(ulocimp_getKeywords)
+#define ulocimp_getKnownCanonicalizedLocaleForTest U_ICU_ENTRY_POINT_RENAME(ulocimp_getKnownCanonicalizedLocaleForTest)
 #define ulocimp_getLanguage U_ICU_ENTRY_POINT_RENAME(ulocimp_getLanguage)
+#define ulocimp_getName U_ICU_ENTRY_POINT_RENAME(ulocimp_getName)
+#define ulocimp_getRegionForSupplementalData U_ICU_ENTRY_POINT_RENAME(ulocimp_getRegionForSupplementalData)
 #define ulocimp_getScript U_ICU_ENTRY_POINT_RENAME(ulocimp_getScript)
+#define ulocimp_isCanonicalizedLocaleForTest U_ICU_ENTRY_POINT_RENAME(ulocimp_isCanonicalizedLocaleForTest)
+#define ulocimp_minimizeSubtags U_ICU_ENTRY_POINT_RENAME(ulocimp_minimizeSubtags)
 #define ulocimp_toBcpKey U_ICU_ENTRY_POINT_RENAME(ulocimp_toBcpKey)
 #define ulocimp_toBcpType U_ICU_ENTRY_POINT_RENAME(ulocimp_toBcpType)
+#define ulocimp_toLanguageTag U_ICU_ENTRY_POINT_RENAME(ulocimp_toLanguageTag)
 #define ulocimp_toLegacyKey U_ICU_ENTRY_POINT_RENAME(ulocimp_toLegacyKey)
 #define ulocimp_toLegacyType U_ICU_ENTRY_POINT_RENAME(ulocimp_toLegacyType)
+#define ultag_isExtensionSubtags U_ICU_ENTRY_POINT_RENAME(ultag_isExtensionSubtags)
+#define ultag_isLanguageSubtag U_ICU_ENTRY_POINT_RENAME(ultag_isLanguageSubtag)
+#define ultag_isPrivateuseValueSubtags U_ICU_ENTRY_POINT_RENAME(ultag_isPrivateuseValueSubtags)
+#define ultag_isRegionSubtag U_ICU_ENTRY_POINT_RENAME(ultag_isRegionSubtag)
+#define ultag_isScriptSubtag U_ICU_ENTRY_POINT_RENAME(ultag_isScriptSubtag)
+#define ultag_isTransformedExtensionSubtags U_ICU_ENTRY_POINT_RENAME(ultag_isTransformedExtensionSubtags)
+#define ultag_isUnicodeExtensionSubtags U_ICU_ENTRY_POINT_RENAME(ultag_isUnicodeExtensionSubtags)
+#define ultag_isUnicodeLocaleAttribute U_ICU_ENTRY_POINT_RENAME(ultag_isUnicodeLocaleAttribute)
+#define ultag_isUnicodeLocaleAttributes U_ICU_ENTRY_POINT_RENAME(ultag_isUnicodeLocaleAttributes)
 #define ultag_isUnicodeLocaleKey U_ICU_ENTRY_POINT_RENAME(ultag_isUnicodeLocaleKey)
 #define ultag_isUnicodeLocaleType U_ICU_ENTRY_POINT_RENAME(ultag_isUnicodeLocaleType)
+#define ultag_isVariantSubtags U_ICU_ENTRY_POINT_RENAME(ultag_isVariantSubtags)
 #define umsg_applyPattern U_ICU_ENTRY_POINT_RENAME(umsg_applyPattern)
 #define umsg_autoQuoteApostrophe U_ICU_ENTRY_POINT_RENAME(umsg_autoQuoteApostrophe)
 #define umsg_clone U_ICU_ENTRY_POINT_RENAME(umsg_clone)
@@ -1096,11 +1161,18 @@
 #define umsg_toPattern U_ICU_ENTRY_POINT_RENAME(umsg_toPattern)
 #define umsg_vformat U_ICU_ENTRY_POINT_RENAME(umsg_vformat)
 #define umsg_vparse U_ICU_ENTRY_POINT_RENAME(umsg_vparse)
-#define umtx_condBroadcast U_ICU_ENTRY_POINT_RENAME(umtx_condBroadcast)
-#define umtx_condSignal U_ICU_ENTRY_POINT_RENAME(umtx_condSignal)
-#define umtx_condWait U_ICU_ENTRY_POINT_RENAME(umtx_condWait)
 #define umtx_lock U_ICU_ENTRY_POINT_RENAME(umtx_lock)
 #define umtx_unlock U_ICU_ENTRY_POINT_RENAME(umtx_unlock)
+#define umutablecptrie_buildImmutable U_ICU_ENTRY_POINT_RENAME(umutablecptrie_buildImmutable)
+#define umutablecptrie_clone U_ICU_ENTRY_POINT_RENAME(umutablecptrie_clone)
+#define umutablecptrie_close U_ICU_ENTRY_POINT_RENAME(umutablecptrie_close)
+#define umutablecptrie_fromUCPMap U_ICU_ENTRY_POINT_RENAME(umutablecptrie_fromUCPMap)
+#define umutablecptrie_fromUCPTrie U_ICU_ENTRY_POINT_RENAME(umutablecptrie_fromUCPTrie)
+#define umutablecptrie_get U_ICU_ENTRY_POINT_RENAME(umutablecptrie_get)
+#define umutablecptrie_getRange U_ICU_ENTRY_POINT_RENAME(umutablecptrie_getRange)
+#define umutablecptrie_open U_ICU_ENTRY_POINT_RENAME(umutablecptrie_open)
+#define umutablecptrie_set U_ICU_ENTRY_POINT_RENAME(umutablecptrie_set)
+#define umutablecptrie_setRange U_ICU_ENTRY_POINT_RENAME(umutablecptrie_setRange)
 #define uniset_getUnicode32Instance U_ICU_ENTRY_POINT_RENAME(uniset_getUnicode32Instance)
 #define unorm2_append U_ICU_ENTRY_POINT_RENAME(unorm2_append)
 #define unorm2_close U_ICU_ENTRY_POINT_RENAME(unorm2_close)
@@ -1143,6 +1215,7 @@
 #define unum_formatDecimal U_ICU_ENTRY_POINT_RENAME(unum_formatDecimal)
 #define unum_formatDouble U_ICU_ENTRY_POINT_RENAME(unum_formatDouble)
 #define unum_formatDoubleCurrency U_ICU_ENTRY_POINT_RENAME(unum_formatDoubleCurrency)
+#define unum_formatDoubleForFields U_ICU_ENTRY_POINT_RENAME(unum_formatDoubleForFields)
 #define unum_formatInt64 U_ICU_ENTRY_POINT_RENAME(unum_formatInt64)
 #define unum_formatUFormattable U_ICU_ENTRY_POINT_RENAME(unum_formatUFormattable)
 #define unum_getAttribute U_ICU_ENTRY_POINT_RENAME(unum_getAttribute)
@@ -1165,6 +1238,29 @@
 #define unum_setSymbol U_ICU_ENTRY_POINT_RENAME(unum_setSymbol)
 #define unum_setTextAttribute U_ICU_ENTRY_POINT_RENAME(unum_setTextAttribute)
 #define unum_toPattern U_ICU_ENTRY_POINT_RENAME(unum_toPattern)
+#define unumf_close U_ICU_ENTRY_POINT_RENAME(unumf_close)
+#define unumf_closeResult U_ICU_ENTRY_POINT_RENAME(unumf_closeResult)
+#define unumf_formatDecimal U_ICU_ENTRY_POINT_RENAME(unumf_formatDecimal)
+#define unumf_formatDouble U_ICU_ENTRY_POINT_RENAME(unumf_formatDouble)
+#define unumf_formatInt U_ICU_ENTRY_POINT_RENAME(unumf_formatInt)
+#define unumf_openForSkeletonAndLocale U_ICU_ENTRY_POINT_RENAME(unumf_openForSkeletonAndLocale)
+#define unumf_openForSkeletonAndLocaleWithError U_ICU_ENTRY_POINT_RENAME(unumf_openForSkeletonAndLocaleWithError)
+#define unumf_openResult U_ICU_ENTRY_POINT_RENAME(unumf_openResult)
+#define unumf_resultAsValue U_ICU_ENTRY_POINT_RENAME(unumf_resultAsValue)
+#define unumf_resultGetAllFieldPositions U_ICU_ENTRY_POINT_RENAME(unumf_resultGetAllFieldPositions)
+#define unumf_resultNextFieldPosition U_ICU_ENTRY_POINT_RENAME(unumf_resultNextFieldPosition)
+#define unumf_resultToDecimalNumber U_ICU_ENTRY_POINT_RENAME(unumf_resultToDecimalNumber)
+#define unumf_resultToString U_ICU_ENTRY_POINT_RENAME(unumf_resultToString)
+#define unumrf_close U_ICU_ENTRY_POINT_RENAME(unumrf_close)
+#define unumrf_closeResult U_ICU_ENTRY_POINT_RENAME(unumrf_closeResult)
+#define unumrf_formatDecimalRange U_ICU_ENTRY_POINT_RENAME(unumrf_formatDecimalRange)
+#define unumrf_formatDoubleRange U_ICU_ENTRY_POINT_RENAME(unumrf_formatDoubleRange)
+#define unumrf_openForSkeletonWithCollapseAndIdentityFallback U_ICU_ENTRY_POINT_RENAME(unumrf_openForSkeletonWithCollapseAndIdentityFallback)
+#define unumrf_openResult U_ICU_ENTRY_POINT_RENAME(unumrf_openResult)
+#define unumrf_resultAsValue U_ICU_ENTRY_POINT_RENAME(unumrf_resultAsValue)
+#define unumrf_resultGetFirstDecimalNumber U_ICU_ENTRY_POINT_RENAME(unumrf_resultGetFirstDecimalNumber)
+#define unumrf_resultGetIdentityResult U_ICU_ENTRY_POINT_RENAME(unumrf_resultGetIdentityResult)
+#define unumrf_resultGetSecondDecimalNumber U_ICU_ENTRY_POINT_RENAME(unumrf_resultGetSecondDecimalNumber)
 #define unumsys_close U_ICU_ENTRY_POINT_RENAME(unumsys_close)
 #define unumsys_getDescription U_ICU_ENTRY_POINT_RENAME(unumsys_getDescription)
 #define unumsys_getName U_ICU_ENTRY_POINT_RENAME(unumsys_getName)
@@ -1174,9 +1270,13 @@
 #define unumsys_openAvailableNames U_ICU_ENTRY_POINT_RENAME(unumsys_openAvailableNames)
 #define unumsys_openByName U_ICU_ENTRY_POINT_RENAME(unumsys_openByName)
 #define uplrules_close U_ICU_ENTRY_POINT_RENAME(uplrules_close)
+#define uplrules_getKeywords U_ICU_ENTRY_POINT_RENAME(uplrules_getKeywords)
 #define uplrules_open U_ICU_ENTRY_POINT_RENAME(uplrules_open)
 #define uplrules_openForType U_ICU_ENTRY_POINT_RENAME(uplrules_openForType)
 #define uplrules_select U_ICU_ENTRY_POINT_RENAME(uplrules_select)
+#define uplrules_selectForRange U_ICU_ENTRY_POINT_RENAME(uplrules_selectForRange)
+#define uplrules_selectFormatted U_ICU_ENTRY_POINT_RENAME(uplrules_selectFormatted)
+#define uplrules_selectWithFormat U_ICU_ENTRY_POINT_RENAME(uplrules_selectWithFormat)
 #define uplug_closeLibrary U_ICU_ENTRY_POINT_RENAME(uplug_closeLibrary)
 #define uplug_findLibrary U_ICU_ENTRY_POINT_RENAME(uplug_findLibrary)
 #define uplug_getConfiguration U_ICU_ENTRY_POINT_RENAME(uplug_getConfiguration)
@@ -1200,8 +1300,10 @@
 #define uplug_setPlugLevel U_ICU_ENTRY_POINT_RENAME(uplug_setPlugLevel)
 #define uplug_setPlugName U_ICU_ENTRY_POINT_RENAME(uplug_setPlugName)
 #define uplug_setPlugNoUnload U_ICU_ENTRY_POINT_RENAME(uplug_setPlugNoUnload)
+#define uprops_addPropertyStarts U_ICU_ENTRY_POINT_RENAME(uprops_addPropertyStarts)
 #define uprops_getSource U_ICU_ENTRY_POINT_RENAME(uprops_getSource)
 #define upropsvec_addPropertyStarts U_ICU_ENTRY_POINT_RENAME(upropsvec_addPropertyStarts)
+#define uprv_add32_overflow U_ICU_ENTRY_POINT_RENAME(uprv_add32_overflow)
 #define uprv_aestrncpy U_ICU_ENTRY_POINT_RENAME(uprv_aestrncpy)
 #define uprv_asciiFromEbcdic U_ICU_ENTRY_POINT_RENAME(uprv_asciiFromEbcdic)
 #define uprv_asciitolower U_ICU_ENTRY_POINT_RENAME(uprv_asciitolower)
@@ -1213,6 +1315,7 @@
 #define uprv_compareInvEbcdic U_ICU_ENTRY_POINT_RENAME(uprv_compareInvEbcdic)
 #define uprv_compareInvEbcdicAsAscii U_ICU_ENTRY_POINT_RENAME(uprv_compareInvEbcdicAsAscii)
 #define uprv_convertToLCID U_ICU_ENTRY_POINT_RENAME(uprv_convertToLCID)
+#define uprv_convertToLCIDPlatform U_ICU_ENTRY_POINT_RENAME(uprv_convertToLCIDPlatform)
 #define uprv_convertToPosix U_ICU_ENTRY_POINT_RENAME(uprv_convertToPosix)
 #define uprv_copyAscii U_ICU_ENTRY_POINT_RENAME(uprv_copyAscii)
 #define uprv_copyEbcdic U_ICU_ENTRY_POINT_RENAME(uprv_copyEbcdic)
@@ -1234,7 +1337,6 @@
 #define uprv_decNumberAbs U_ICU_ENTRY_POINT_RENAME(uprv_decNumberAbs)
 #define uprv_decNumberAdd U_ICU_ENTRY_POINT_RENAME(uprv_decNumberAdd)
 #define uprv_decNumberAnd U_ICU_ENTRY_POINT_RENAME(uprv_decNumberAnd)
-#define uprv_decNumberClass U_ICU_ENTRY_POINT_RENAME(uprv_decNumberClass)
 #define uprv_decNumberClassToString U_ICU_ENTRY_POINT_RENAME(uprv_decNumberClassToString)
 #define uprv_decNumberCompare U_ICU_ENTRY_POINT_RENAME(uprv_decNumberCompare)
 #define uprv_decNumberCompareSignal U_ICU_ENTRY_POINT_RENAME(uprv_decNumberCompareSignal)
@@ -1300,6 +1402,7 @@
 #define uprv_dlsym_func U_ICU_ENTRY_POINT_RENAME(uprv_dlsym_func)
 #define uprv_eastrncpy U_ICU_ENTRY_POINT_RENAME(uprv_eastrncpy)
 #define uprv_ebcdicFromAscii U_ICU_ENTRY_POINT_RENAME(uprv_ebcdicFromAscii)
+#define uprv_ebcdicToAscii U_ICU_ENTRY_POINT_RENAME(uprv_ebcdicToAscii)
 #define uprv_ebcdicToLowercaseAscii U_ICU_ENTRY_POINT_RENAME(uprv_ebcdicToLowercaseAscii)
 #define uprv_ebcdictolower U_ICU_ENTRY_POINT_RENAME(uprv_ebcdictolower)
 #define uprv_fabs U_ICU_ENTRY_POINT_RENAME(uprv_fabs)
@@ -1309,7 +1412,6 @@
 #define uprv_fmod U_ICU_ENTRY_POINT_RENAME(uprv_fmod)
 #define uprv_free U_ICU_ENTRY_POINT_RENAME(uprv_free)
 #define uprv_getCharNameCharacters U_ICU_ENTRY_POINT_RENAME(uprv_getCharNameCharacters)
-#define uprv_getDefaultCodepage U_ICU_ENTRY_POINT_RENAME(uprv_getDefaultCodepage)
 #define uprv_getDefaultLocaleID U_ICU_ENTRY_POINT_RENAME(uprv_getDefaultLocaleID)
 #define uprv_getInfinity U_ICU_ENTRY_POINT_RENAME(uprv_getInfinity)
 #define uprv_getMaxCharNameLength U_ICU_ENTRY_POINT_RENAME(uprv_getMaxCharNameLength)
@@ -1318,9 +1420,9 @@
 #define uprv_getRawUTCtime U_ICU_ENTRY_POINT_RENAME(uprv_getRawUTCtime)
 #define uprv_getStaticCurrencyName U_ICU_ENTRY_POINT_RENAME(uprv_getStaticCurrencyName)
 #define uprv_getUTCtime U_ICU_ENTRY_POINT_RENAME(uprv_getUTCtime)
-#define uprv_haveProperties U_ICU_ENTRY_POINT_RENAME(uprv_haveProperties)
 #define uprv_int32Comparator U_ICU_ENTRY_POINT_RENAME(uprv_int32Comparator)
 #define uprv_isASCIILetter U_ICU_ENTRY_POINT_RENAME(uprv_isASCIILetter)
+#define uprv_isEbcdicAtSign U_ICU_ENTRY_POINT_RENAME(uprv_isEbcdicAtSign)
 #define uprv_isInfinite U_ICU_ENTRY_POINT_RENAME(uprv_isInfinite)
 #define uprv_isInvariantString U_ICU_ENTRY_POINT_RENAME(uprv_isInvariantString)
 #define uprv_isInvariantUString U_ICU_ENTRY_POINT_RENAME(uprv_isInvariantUString)
@@ -1336,6 +1438,7 @@
 #define uprv_maximumPtr U_ICU_ENTRY_POINT_RENAME(uprv_maximumPtr)
 #define uprv_min U_ICU_ENTRY_POINT_RENAME(uprv_min)
 #define uprv_modf U_ICU_ENTRY_POINT_RENAME(uprv_modf)
+#define uprv_mul32_overflow U_ICU_ENTRY_POINT_RENAME(uprv_mul32_overflow)
 #define uprv_parseCurrency U_ICU_ENTRY_POINT_RENAME(uprv_parseCurrency)
 #define uprv_pathIsAbsolute U_ICU_ENTRY_POINT_RENAME(uprv_pathIsAbsolute)
 #define uprv_pow U_ICU_ENTRY_POINT_RENAME(uprv_pow)
@@ -1354,6 +1457,7 @@
 #define uprv_toupper U_ICU_ENTRY_POINT_RENAME(uprv_toupper)
 #define uprv_trunc U_ICU_ENTRY_POINT_RENAME(uprv_trunc)
 #define uprv_tzname U_ICU_ENTRY_POINT_RENAME(uprv_tzname)
+#define uprv_tzname_clear_cache U_ICU_ENTRY_POINT_RENAME(uprv_tzname_clear_cache)
 #define uprv_tzset U_ICU_ENTRY_POINT_RENAME(uprv_tzset)
 #define uprv_uint16Comparator U_ICU_ENTRY_POINT_RENAME(uprv_uint16Comparator)
 #define uprv_uint32Comparator U_ICU_ENTRY_POINT_RENAME(uprv_uint32Comparator)
@@ -1445,11 +1549,22 @@
 #define uregion_getRegionFromCode U_ICU_ENTRY_POINT_RENAME(uregion_getRegionFromCode)
 #define uregion_getRegionFromNumericCode U_ICU_ENTRY_POINT_RENAME(uregion_getRegionFromNumericCode)
 #define uregion_getType U_ICU_ENTRY_POINT_RENAME(uregion_getType)
+#define ureldatefmt_close U_ICU_ENTRY_POINT_RENAME(ureldatefmt_close)
+#define ureldatefmt_closeResult U_ICU_ENTRY_POINT_RENAME(ureldatefmt_closeResult)
+#define ureldatefmt_combineDateAndTime U_ICU_ENTRY_POINT_RENAME(ureldatefmt_combineDateAndTime)
+#define ureldatefmt_format U_ICU_ENTRY_POINT_RENAME(ureldatefmt_format)
+#define ureldatefmt_formatNumeric U_ICU_ENTRY_POINT_RENAME(ureldatefmt_formatNumeric)
+#define ureldatefmt_formatNumericToResult U_ICU_ENTRY_POINT_RENAME(ureldatefmt_formatNumericToResult)
+#define ureldatefmt_formatToResult U_ICU_ENTRY_POINT_RENAME(ureldatefmt_formatToResult)
+#define ureldatefmt_open U_ICU_ENTRY_POINT_RENAME(ureldatefmt_open)
+#define ureldatefmt_openResult U_ICU_ENTRY_POINT_RENAME(ureldatefmt_openResult)
+#define ureldatefmt_resultAsValue U_ICU_ENTRY_POINT_RENAME(ureldatefmt_resultAsValue)
 #define ures_close U_ICU_ENTRY_POINT_RENAME(ures_close)
 #define ures_copyResb U_ICU_ENTRY_POINT_RENAME(ures_copyResb)
 #define ures_countArrayItems U_ICU_ENTRY_POINT_RENAME(ures_countArrayItems)
 #define ures_findResource U_ICU_ENTRY_POINT_RENAME(ures_findResource)
 #define ures_findSubResource U_ICU_ENTRY_POINT_RENAME(ures_findSubResource)
+#define ures_getAllItemsWithFallback U_ICU_ENTRY_POINT_RENAME(ures_getAllItemsWithFallback)
 #define ures_getBinary U_ICU_ENTRY_POINT_RENAME(ures_getBinary)
 #define ures_getByIndex U_ICU_ENTRY_POINT_RENAME(ures_getByIndex)
 #define ures_getByKey U_ICU_ENTRY_POINT_RENAME(ures_getByKey)
@@ -1475,6 +1590,7 @@
 #define ures_getUTF8String U_ICU_ENTRY_POINT_RENAME(ures_getUTF8String)
 #define ures_getUTF8StringByIndex U_ICU_ENTRY_POINT_RENAME(ures_getUTF8StringByIndex)
 #define ures_getUTF8StringByKey U_ICU_ENTRY_POINT_RENAME(ures_getUTF8StringByKey)
+#define ures_getValueWithFallback U_ICU_ENTRY_POINT_RENAME(ures_getValueWithFallback)
 #define ures_getVersion U_ICU_ENTRY_POINT_RENAME(ures_getVersion)
 #define ures_getVersionByKey U_ICU_ENTRY_POINT_RENAME(ures_getVersionByKey)
 #define ures_getVersionNumber U_ICU_ENTRY_POINT_RENAME(ures_getVersionNumber)
@@ -1484,6 +1600,7 @@
 #define ures_open U_ICU_ENTRY_POINT_RENAME(ures_open)
 #define ures_openAvailableLocales U_ICU_ENTRY_POINT_RENAME(ures_openAvailableLocales)
 #define ures_openDirect U_ICU_ENTRY_POINT_RENAME(ures_openDirect)
+#define ures_openDirectFillIn U_ICU_ENTRY_POINT_RENAME(ures_openDirectFillIn)
 #define ures_openFillIn U_ICU_ENTRY_POINT_RENAME(ures_openFillIn)
 #define ures_openNoDefault U_ICU_ENTRY_POINT_RENAME(ures_openNoDefault)
 #define ures_openU U_ICU_ENTRY_POINT_RENAME(ures_openU)
@@ -1597,13 +1714,20 @@
 #define uspoof_areConfusableUTF8 U_ICU_ENTRY_POINT_RENAME(uspoof_areConfusableUTF8)
 #define uspoof_areConfusableUnicodeString U_ICU_ENTRY_POINT_RENAME(uspoof_areConfusableUnicodeString)
 #define uspoof_check U_ICU_ENTRY_POINT_RENAME(uspoof_check)
+#define uspoof_check2 U_ICU_ENTRY_POINT_RENAME(uspoof_check2)
+#define uspoof_check2UTF8 U_ICU_ENTRY_POINT_RENAME(uspoof_check2UTF8)
+#define uspoof_check2UnicodeString U_ICU_ENTRY_POINT_RENAME(uspoof_check2UnicodeString)
 #define uspoof_checkUTF8 U_ICU_ENTRY_POINT_RENAME(uspoof_checkUTF8)
 #define uspoof_checkUnicodeString U_ICU_ENTRY_POINT_RENAME(uspoof_checkUnicodeString)
 #define uspoof_clone U_ICU_ENTRY_POINT_RENAME(uspoof_clone)
 #define uspoof_close U_ICU_ENTRY_POINT_RENAME(uspoof_close)
+#define uspoof_closeCheckResult U_ICU_ENTRY_POINT_RENAME(uspoof_closeCheckResult)
 #define uspoof_getAllowedChars U_ICU_ENTRY_POINT_RENAME(uspoof_getAllowedChars)
 #define uspoof_getAllowedLocales U_ICU_ENTRY_POINT_RENAME(uspoof_getAllowedLocales)
 #define uspoof_getAllowedUnicodeSet U_ICU_ENTRY_POINT_RENAME(uspoof_getAllowedUnicodeSet)
+#define uspoof_getCheckResultChecks U_ICU_ENTRY_POINT_RENAME(uspoof_getCheckResultChecks)
+#define uspoof_getCheckResultNumerics U_ICU_ENTRY_POINT_RENAME(uspoof_getCheckResultNumerics)
+#define uspoof_getCheckResultRestrictionLevel U_ICU_ENTRY_POINT_RENAME(uspoof_getCheckResultRestrictionLevel)
 #define uspoof_getChecks U_ICU_ENTRY_POINT_RENAME(uspoof_getChecks)
 #define uspoof_getInclusionSet U_ICU_ENTRY_POINT_RENAME(uspoof_getInclusionSet)
 #define uspoof_getInclusionUnicodeSet U_ICU_ENTRY_POINT_RENAME(uspoof_getInclusionUnicodeSet)
@@ -1615,6 +1739,7 @@
 #define uspoof_getSkeletonUnicodeString U_ICU_ENTRY_POINT_RENAME(uspoof_getSkeletonUnicodeString)
 #define uspoof_internalInitStatics U_ICU_ENTRY_POINT_RENAME(uspoof_internalInitStatics)
 #define uspoof_open U_ICU_ENTRY_POINT_RENAME(uspoof_open)
+#define uspoof_openCheckResult U_ICU_ENTRY_POINT_RENAME(uspoof_openCheckResult)
 #define uspoof_openFromSerialized U_ICU_ENTRY_POINT_RENAME(uspoof_openFromSerialized)
 #define uspoof_openFromSource U_ICU_ENTRY_POINT_RENAME(uspoof_openFromSource)
 #define uspoof_serialize U_ICU_ENTRY_POINT_RENAME(uspoof_serialize)
@@ -1632,12 +1757,14 @@
 #define ustr_hashCharsN U_ICU_ENTRY_POINT_RENAME(ustr_hashCharsN)
 #define ustr_hashICharsN U_ICU_ENTRY_POINT_RENAME(ustr_hashICharsN)
 #define ustr_hashUCharsN U_ICU_ENTRY_POINT_RENAME(ustr_hashUCharsN)
+#define ustrcase_getCaseLocale U_ICU_ENTRY_POINT_RENAME(ustrcase_getCaseLocale)
+#define ustrcase_getTitleBreakIterator U_ICU_ENTRY_POINT_RENAME(ustrcase_getTitleBreakIterator)
 #define ustrcase_internalFold U_ICU_ENTRY_POINT_RENAME(ustrcase_internalFold)
 #define ustrcase_internalToLower U_ICU_ENTRY_POINT_RENAME(ustrcase_internalToLower)
 #define ustrcase_internalToTitle U_ICU_ENTRY_POINT_RENAME(ustrcase_internalToTitle)
 #define ustrcase_internalToUpper U_ICU_ENTRY_POINT_RENAME(ustrcase_internalToUpper)
 #define ustrcase_map U_ICU_ENTRY_POINT_RENAME(ustrcase_map)
-#define ustrcase_setTempCaseMapLocale U_ICU_ENTRY_POINT_RENAME(ustrcase_setTempCaseMapLocale)
+#define ustrcase_mapWithOverlap U_ICU_ENTRY_POINT_RENAME(ustrcase_mapWithOverlap)
 #define utext_char32At U_ICU_ENTRY_POINT_RENAME(utext_char32At)
 #define utext_clone U_ICU_ENTRY_POINT_RENAME(utext_clone)
 #define utext_close U_ICU_ENTRY_POINT_RENAME(utext_close)
@@ -1682,7 +1809,6 @@
 #define utrace_functionName U_ICU_ENTRY_POINT_RENAME(utrace_functionName)
 #define utrace_getFunctions U_ICU_ENTRY_POINT_RENAME(utrace_getFunctions)
 #define utrace_getLevel U_ICU_ENTRY_POINT_RENAME(utrace_getLevel)
-#define utrace_level U_ICU_ENTRY_POINT_RENAME(utrace_level)
 #define utrace_setFunctions U_ICU_ENTRY_POINT_RENAME(utrace_setFunctions)
 #define utrace_setLevel U_ICU_ENTRY_POINT_RENAME(utrace_setLevel)
 #define utrace_vformat U_ICU_ENTRY_POINT_RENAME(utrace_vformat)
@@ -1718,7 +1844,6 @@
 #define utrie2_fromUTrie U_ICU_ENTRY_POINT_RENAME(utrie2_fromUTrie)
 #define utrie2_get32 U_ICU_ENTRY_POINT_RENAME(utrie2_get32)
 #define utrie2_get32FromLeadSurrogateCodeUnit U_ICU_ENTRY_POINT_RENAME(utrie2_get32FromLeadSurrogateCodeUnit)
-#define utrie2_getVersion U_ICU_ENTRY_POINT_RENAME(utrie2_getVersion)
 #define utrie2_internalU8NextIndex U_ICU_ENTRY_POINT_RENAME(utrie2_internalU8NextIndex)
 #define utrie2_internalU8PrevIndex U_ICU_ENTRY_POINT_RENAME(utrie2_internalU8PrevIndex)
 #define utrie2_isFrozen U_ICU_ENTRY_POINT_RENAME(utrie2_isFrozen)
@@ -1730,7 +1855,6 @@
 #define utrie2_set32ForLeadSurrogateCodeUnit U_ICU_ENTRY_POINT_RENAME(utrie2_set32ForLeadSurrogateCodeUnit)
 #define utrie2_setRange32 U_ICU_ENTRY_POINT_RENAME(utrie2_setRange32)
 #define utrie2_swap U_ICU_ENTRY_POINT_RENAME(utrie2_swap)
-#define utrie2_swapAnyVersion U_ICU_ENTRY_POINT_RENAME(utrie2_swapAnyVersion)
 #define utrie_clone U_ICU_ENTRY_POINT_RENAME(utrie_clone)
 #define utrie_close U_ICU_ENTRY_POINT_RENAME(utrie_close)
 #define utrie_defaultGetFoldingOffset U_ICU_ENTRY_POINT_RENAME(utrie_defaultGetFoldingOffset)
@@ -1742,6 +1866,7 @@
 #define utrie_set32 U_ICU_ENTRY_POINT_RENAME(utrie_set32)
 #define utrie_setRange32 U_ICU_ENTRY_POINT_RENAME(utrie_setRange32)
 #define utrie_swap U_ICU_ENTRY_POINT_RENAME(utrie_swap)
+#define utrie_swapAnyVersion U_ICU_ENTRY_POINT_RENAME(utrie_swapAnyVersion)
 #define utrie_unserialize U_ICU_ENTRY_POINT_RENAME(utrie_unserialize)
 #define utrie_unserializeDummy U_ICU_ENTRY_POINT_RENAME(utrie_unserializeDummy)
 #define vzone_clone U_ICU_ENTRY_POINT_RENAME(vzone_clone)
@@ -1791,6 +1916,7 @@
 #define ztrans_setTime U_ICU_ENTRY_POINT_RENAME(ztrans_setTime)
 #define ztrans_setTo U_ICU_ENTRY_POINT_RENAME(ztrans_setTo)
 
-#endif
+#endif /* !(defined(_MSC_VER) && defined(__INTELLISENSE__)) */
+#endif /* U_DISABLE_RENAMING */
+#endif /* URENAME_H */
 
-#endif
diff --git a/src/third_party/icu/source/common/unicode/urep.h b/src/third_party/icu/source/common/unicode/urep.h
index c7b9947..932202d 100644
--- a/src/third_party/icu/source/common/unicode/urep.h
+++ b/src/third_party/icu/source/common/unicode/urep.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *   Copyright (C) 1997-2010, International Business Machines
diff --git a/src/third_party/icu/source/common/unicode/ures.h b/src/third_party/icu/source/common/unicode/ures.h
index c91f030..fff8404 100644
--- a/src/third_party/icu/source/common/unicode/ures.h
+++ b/src/third_party/icu/source/common/unicode/ures.h
@@ -1,6 +1,8 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
-*   Copyright (C) 1997-2012,2014, International Business Machines
+*   Copyright (C) 1997-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 **********************************************************************
 *
@@ -12,9 +14,9 @@
 *   04/01/97    aliu        Creation.
 *   02/22/99    damiba      overhaul.
 *   04/04/99    helena      Fixed internal header inclusion.
-*   04/15/99    Madhu       Updated Javadoc  
+*   04/15/99    Madhu       Updated Javadoc
 *   06/14/99    stephen     Removed functions taking a filename suffix.
-*   07/20/99    stephen     Language-independent ypedef to void*
+*   07/20/99    stephen     Language-independent typedef to void*
 *   11/09/99    weiv        Added ures_getLocale()
 *   06/24/02    weiv        Added support for resource sharing
 ******************************************************************************
@@ -25,11 +27,14 @@
 
 #include "unicode/utypes.h"
 #include "unicode/uloc.h"
+
+#if U_SHOW_CPLUSPLUS_API
 #include "unicode/localpointer.h"
+#endif   // U_SHOW_CPLUSPLUS_API
 
 /**
  * \file
- * \brief C API: Resource Bundle 
+ * \brief C API: Resource Bundle
  *
  * <h2>C API: Resource Bundle</h2>
  *
@@ -40,7 +45,7 @@
  * <P>
  * Resource bundles in ICU4C are currently defined using text files which conform to the following
  * <a href="http://source.icu-project.org/repos/icu/icuhtml/trunk/design/bnf_rb.txt">BNF definition</a>.
- * More on resource bundle concepts and syntax can be found in the 
+ * More on resource bundle concepts and syntax can be found in the
  * <a href="http://icu-project.org/userguide/ResourceManagement.html">Users Guide</a>.
  * <P>
  */
@@ -119,10 +124,14 @@
     /** @deprecated ICU 2.6 Use the URES_ constant instead. */
     RES_INT_VECTOR=URES_INT_VECTOR,
     /** @deprecated ICU 2.6 Not used. */
-    RES_RESERVED=15, 
-#endif /* U_HIDE_DEPRECATED_API */
+    RES_RESERVED=15,
 
+    /**
+     * One more than the highest normal UResType value.
+     * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
+     */
     URES_LIMIT = 16
+#endif  // U_HIDE_DEPRECATED_API
 } UResType;
 
 /*
@@ -132,17 +141,17 @@
 /**
  * Opens a UResourceBundle, from which users can extract strings by using
  * their corresponding keys.
- * Note that the caller is responsible of calling <TT>ures_close</TT> on each succesfully
+ * Note that the caller is responsible of calling <TT>ures_close</TT> on each successfully
  * opened resource bundle.
- * @param packageName   The packageName and locale together point to an ICU udata object, 
- *                      as defined by <code> udata_open( packageName, "res", locale, err) </code> 
+ * @param packageName   The packageName and locale together point to an ICU udata object,
+ *                      as defined by <code> udata_open( packageName, "res", locale, err) </code>
  *                      or equivalent.  Typically, packageName will refer to a (.dat) file, or to
  *                      a package registered with udata_setAppData(). Using a full file or directory
  *                      pathname for packageName is deprecated. If NULL, ICU data will be used.
  * @param locale  specifies the locale for which we want to open the resource
  *                if NULL, the default locale will be used. If strlen(locale) == 0
  *                root locale will be used.
- *                
+ *
  * @param status  fills in the outgoing error code.
  * The UErrorCode err parameter is used to return status information to the user. To
  * check whether the construction succeeded or not, you should check the value of
@@ -150,39 +159,39 @@
  * informational status results which still indicate success. U_USING_FALLBACK_WARNING
  * indicates that a fall back locale was used. For example, 'de_CH' was requested,
  * but nothing was found there, so 'de' was used. U_USING_DEFAULT_WARNING indicates that
- * the default locale data or root locale data was used; neither the requested locale 
- * nor any of its fall back locales could be found. Please see the users guide for more 
+ * the default locale data or root locale data was used; neither the requested locale
+ * nor any of its fall back locales could be found. Please see the users guide for more
  * information on this topic.
  * @return      a newly allocated resource bundle.
  * @see ures_close
  * @stable ICU 2.0
  */
-U_STABLE UResourceBundle*  U_EXPORT2 
+U_CAPI UResourceBundle*  U_EXPORT2
 ures_open(const char*    packageName,
-          const char*  locale, 
+          const char*  locale,
           UErrorCode*     status);
 
 
-/** This function does not care what kind of localeID is passed in. It simply opens a bundle with 
+/** This function does not care what kind of localeID is passed in. It simply opens a bundle with
  *  that name. Fallback mechanism is disabled for the new bundle. If the requested bundle contains
  *  an %%ALIAS directive, the results are undefined.
- * @param packageName   The packageName and locale together point to an ICU udata object, 
- *                      as defined by <code> udata_open( packageName, "res", locale, err) </code> 
+ * @param packageName   The packageName and locale together point to an ICU udata object,
+ *                      as defined by <code> udata_open( packageName, "res", locale, err) </code>
  *                      or equivalent.  Typically, packageName will refer to a (.dat) file, or to
  *                      a package registered with udata_setAppData(). Using a full file or directory
  *                      pathname for packageName is deprecated. If NULL, ICU data will be used.
  * @param locale  specifies the locale for which we want to open the resource
  *                if NULL, the default locale will be used. If strlen(locale) == 0
  *                root locale will be used.
- *                
+ *
  * @param status fills in the outgoing error code. Either U_ZERO_ERROR or U_MISSING_RESOURCE_ERROR
  * @return      a newly allocated resource bundle or NULL if it doesn't exist.
  * @see ures_close
  * @stable ICU 2.0
  */
-U_STABLE UResourceBundle* U_EXPORT2 
-ures_openDirect(const char* packageName, 
-                const char* locale, 
+U_CAPI UResourceBundle* U_EXPORT2
+ures_openDirect(const char* packageName,
+                const char* locale,
                 UErrorCode* status);
 
 /**
@@ -190,8 +199,8 @@
  * This path will be converted to char * using the default converter,
  * then ures_open() is called.
  *
- * @param packageName   The packageName and locale together point to an ICU udata object, 
- *                      as defined by <code> udata_open( packageName, "res", locale, err) </code> 
+ * @param packageName   The packageName and locale together point to an ICU udata object,
+ *                      as defined by <code> udata_open( packageName, "res", locale, err) </code>
  *                      or equivalent.  Typically, packageName will refer to a (.dat) file, or to
  *                      a package registered with udata_setAppData(). Using a full file or directory
  *                      pathname for packageName is deprecated. If NULL, ICU data will be used.
@@ -203,21 +212,21 @@
  * @see ures_open
  * @stable ICU 2.0
  */
-U_STABLE UResourceBundle* U_EXPORT2 
-ures_openU(const UChar* packageName, 
-           const char* locale, 
+U_CAPI UResourceBundle* U_EXPORT2
+ures_openU(const UChar* packageName,
+           const char* locale,
            UErrorCode* status);
 
 #ifndef U_HIDE_DEPRECATED_API
 /**
  * Returns the number of strings/arrays in resource bundles.
- * Better to use ures_getSize, as this function will be deprecated. 
+ * Better to use ures_getSize, as this function will be deprecated.
  *
  *@param resourceBundle resource bundle containing the desired strings
  *@param resourceKey key tagging the resource
  *@param err fills in the outgoing error code
  *                could be <TT>U_MISSING_RESOURCE_ERROR</TT> if the key is not found
- *                could be a non-failing error 
+ *                could be a non-failing error
  *                e.g.: <TT>U_USING_FALLBACK_WARNING</TT>,<TT>U_USING_FALLBACK_WARNING </TT>
  *@return: for    <STRONG>Arrays</STRONG>: returns the number of resources in the array
  *                <STRONG>Tables</STRONG>: returns the number of resources in the table
@@ -225,7 +234,7 @@
  *@see ures_getSize
  * @deprecated ICU 2.8 User ures_getSize instead
  */
-U_DEPRECATED int32_t U_EXPORT2 
+U_DEPRECATED int32_t U_EXPORT2
 ures_countArrayItems(const UResourceBundle* resourceBundle,
                      const char* resourceKey,
                      UErrorCode* err);
@@ -239,7 +248,7 @@
  * @see ures_open
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2 
+U_CAPI void U_EXPORT2
 ures_close(UResourceBundle* resourceBundle);
 
 #if U_SHOW_CPLUSPLUS_API
@@ -272,12 +281,12 @@
  * @see ures_getVersion
  * @deprecated ICU 2.8 Use ures_getVersion instead.
  */
-U_DEPRECATED const char* U_EXPORT2 
+U_DEPRECATED const char* U_EXPORT2
 ures_getVersionNumber(const UResourceBundle*   resourceBundle);
 #endif  /* U_HIDE_DEPRECATED_API */
 
 /**
- * Return the version number associated with this ResourceBundle as an 
+ * Return the version number associated with this ResourceBundle as an
  * UVersionInfo array.
  *
  * @param resB The resource bundle for which the version is checked.
@@ -285,30 +294,30 @@
  *                    as specified in the resource bundle or its parent.
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2 
-ures_getVersion(const UResourceBundle* resB, 
+U_CAPI void U_EXPORT2
+ures_getVersion(const UResourceBundle* resB,
                 UVersionInfo versionInfo);
 
 #ifndef U_HIDE_DEPRECATED_API
 /**
  * Return the name of the Locale associated with this ResourceBundle. This API allows
- * you to query for the real locale of the resource. For example, if you requested 
- * "en_US_CALIFORNIA" and only "en_US" bundle exists, "en_US" will be returned. 
+ * you to query for the real locale of the resource. For example, if you requested
+ * "en_US_CALIFORNIA" and only "en_US" bundle exists, "en_US" will be returned.
  * For subresources, the locale where this resource comes from will be returned.
- * If fallback has occured, getLocale will reflect this.
+ * If fallback has occurred, getLocale will reflect this.
  *
  * @param resourceBundle resource bundle in question
  * @param status just for catching illegal arguments
  * @return  A Locale name
  * @deprecated ICU 2.8 Use ures_getLocaleByType instead.
  */
-U_DEPRECATED const char* U_EXPORT2 
-ures_getLocale(const UResourceBundle* resourceBundle, 
+U_DEPRECATED const char* U_EXPORT2
+ures_getLocale(const UResourceBundle* resourceBundle,
                UErrorCode* status);
 #endif  /* U_HIDE_DEPRECATED_API */
 
 /**
- * Return the name of the Locale associated with this ResourceBundle. 
+ * Return the name of the Locale associated with this ResourceBundle.
  * You can choose between requested, valid and real locale.
  *
  * @param resourceBundle resource bundle in question
@@ -319,33 +328,33 @@
  * @return  A Locale name
  * @stable ICU 2.8
  */
-U_STABLE const char* U_EXPORT2 
-ures_getLocaleByType(const UResourceBundle* resourceBundle, 
-                     ULocDataLocaleType type, 
+U_CAPI const char* U_EXPORT2
+ures_getLocaleByType(const UResourceBundle* resourceBundle,
+                     ULocDataLocaleType type,
                      UErrorCode* status);
 
 
 #ifndef U_HIDE_INTERNAL_API
 /**
- * Same as ures_open() but uses the fill-in parameter instead of allocating
- * a bundle, if r!=NULL.
+ * Same as ures_open() but uses the fill-in parameter instead of allocating a new bundle.
+ *
  * TODO need to revisit usefulness of this function
  *      and usage model for fillIn parameters without knowing sizeof(UResourceBundle)
- * @param r The resourcebundle to open
- * @param packageName   The packageName and locale together point to an ICU udata object, 
- *                      as defined by <code> udata_open( packageName, "res", locale, err) </code> 
+ * @param r The existing UResourceBundle to fill in. If NULL then status will be
+ *               set to U_ILLEGAL_ARGUMENT_ERROR.
+ * @param packageName   The packageName and locale together point to an ICU udata object,
+ *                      as defined by <code> udata_open( packageName, "res", locale, err) </code>
  *                      or equivalent.  Typically, packageName will refer to a (.dat) file, or to
  *                      a package registered with udata_setAppData(). Using a full file or directory
  *                      pathname for packageName is deprecated. If NULL, ICU data will be used.
  * @param localeID specifies the locale for which we want to open the resource
- * @param status The error code
- * @return a newly allocated resource bundle or NULL if it doesn't exist.
+ * @param status The error code.
  * @internal
  */
-U_INTERNAL void U_EXPORT2 
-ures_openFillIn(UResourceBundle *r, 
+U_CAPI void U_EXPORT2
+ures_openFillIn(UResourceBundle *r,
                 const char* packageName,
-                const char* localeID, 
+                const char* localeID,
                 UErrorCode* status);
 #endif  /* U_HIDE_INTERNAL_API */
 
@@ -357,7 +366,7 @@
  * @param status fills in the outgoing error code
  *                could be <TT>U_MISSING_RESOURCE_ERROR</TT> if the key is not found
  *                Always check the value of status. Don't count on returning NULL.
- *                could be a non-failing error 
+ *                could be a non-failing error
  *                e.g.: <TT>U_USING_FALLBACK_WARNING</TT>,<TT>U_USING_DEFAULT_WARNING </TT>
  * @return a pointer to a zero-terminated UChar array which lives in a memory mapped/DLL file.
  * @see ures_getBinary
@@ -366,9 +375,9 @@
  * @see ures_getUInt
  * @stable ICU 2.0
  */
-U_STABLE const UChar* U_EXPORT2 
-ures_getString(const UResourceBundle* resourceBundle, 
-               int32_t* len, 
+U_CAPI const UChar* U_EXPORT2
+ures_getString(const UResourceBundle* resourceBundle,
+               int32_t* len,
                UErrorCode* status);
 
 /**
@@ -377,10 +386,10 @@
  * it may need to be copied, or transformed from UTF-16 using u_strToUTF8()
  * or equivalent.
  *
- * If forceCopy==TRUE, then the string is always written to the dest buffer
+ * If forceCopy==true, then the string is always written to the dest buffer
  * and dest is returned.
  *
- * If forceCopy==FALSE, then the string is returned as a pointer if possible,
+ * If forceCopy==false, then the string is returned as a pointer if possible,
  * without needing a dest buffer (it can be NULL). If the string needs to be
  * copied or transformed, then it may be placed into dest at an arbitrary offset.
  *
@@ -398,10 +407,10 @@
  *               terminating NUL, even in case of U_BUFFER_OVERFLOW_ERROR.
  *               Can be NULL, meaning capacity=0 and the string length is not
  *               returned to the caller.
- * @param forceCopy If TRUE, then the output string will always be written to
+ * @param forceCopy If true, then the output string will always be written to
  *                  dest, with U_BUFFER_OVERFLOW_ERROR and
  *                  U_STRING_NOT_TERMINATED_WARNING set if appropriate.
- *                  If FALSE, then the dest buffer may or may not contain a
+ *                  If false, then the dest buffer may or may not contain a
  *                  copy of the string. dest may or may not be modified.
  *                  If a copy needs to be written, then the UErrorCode parameter
  *                  indicates overflow etc. as usual.
@@ -418,21 +427,21 @@
  * @see u_strToUTF8
  * @stable ICU 3.6
  */
-U_STABLE const char * U_EXPORT2
+U_CAPI const char * U_EXPORT2
 ures_getUTF8String(const UResourceBundle *resB,
                    char *dest, int32_t *length,
                    UBool forceCopy,
                    UErrorCode *status);
 
 /**
- * Returns a binary data from a binary resource. 
+ * Returns a binary data from a binary resource.
  *
  * @param resourceBundle a string resource
  * @param len    fills in the length of resulting byte chunk
  * @param status fills in the outgoing error code
  *                could be <TT>U_MISSING_RESOURCE_ERROR</TT> if the key is not found
  *                Always check the value of status. Don't count on returning NULL.
- *                could be a non-failing error 
+ *                could be a non-failing error
  *                e.g.: <TT>U_USING_FALLBACK_WARNING</TT>,<TT>U_USING_DEFAULT_WARNING </TT>
  * @return a pointer to a chunk of unsigned bytes which live in a memory mapped/DLL file.
  * @see ures_getString
@@ -441,20 +450,20 @@
  * @see ures_getUInt
  * @stable ICU 2.0
  */
-U_STABLE const uint8_t* U_EXPORT2 
-ures_getBinary(const UResourceBundle* resourceBundle, 
-               int32_t* len, 
+U_CAPI const uint8_t* U_EXPORT2
+ures_getBinary(const UResourceBundle* resourceBundle,
+               int32_t* len,
                UErrorCode* status);
 
 /**
- * Returns a 32 bit integer array from a resource. 
+ * Returns a 32 bit integer array from a resource.
  *
  * @param resourceBundle an int vector resource
  * @param len    fills in the length of resulting byte chunk
  * @param status fills in the outgoing error code
  *                could be <TT>U_MISSING_RESOURCE_ERROR</TT> if the key is not found
  *                Always check the value of status. Don't count on returning NULL.
- *                could be a non-failing error 
+ *                could be a non-failing error
  *                e.g.: <TT>U_USING_FALLBACK_WARNING</TT>,<TT>U_USING_DEFAULT_WARNING </TT>
  * @return a pointer to a chunk of integers which live in a memory mapped/DLL file.
  * @see ures_getBinary
@@ -463,19 +472,19 @@
  * @see ures_getUInt
  * @stable ICU 2.0
  */
-U_STABLE const int32_t* U_EXPORT2 
-ures_getIntVector(const UResourceBundle* resourceBundle, 
-                  int32_t* len, 
+U_CAPI const int32_t* U_EXPORT2
+ures_getIntVector(const UResourceBundle* resourceBundle,
+                  int32_t* len,
                   UErrorCode* status);
 
 /**
- * Returns an unsigned integer from a resource. 
+ * Returns an unsigned integer from a resource.
  * This integer is originally 28 bits.
  *
  * @param resourceBundle a string resource
  * @param status fills in the outgoing error code
  *                could be <TT>U_MISSING_RESOURCE_ERROR</TT> if the key is not found
- *                could be a non-failing error 
+ *                could be a non-failing error
  *                e.g.: <TT>U_USING_FALLBACK_WARNING</TT>,<TT>U_USING_DEFAULT_WARNING </TT>
  * @return an integer value
  * @see ures_getInt
@@ -484,18 +493,18 @@
  * @see ures_getString
  * @stable ICU 2.0
  */
-U_STABLE uint32_t U_EXPORT2 
-ures_getUInt(const UResourceBundle* resourceBundle, 
+U_CAPI uint32_t U_EXPORT2
+ures_getUInt(const UResourceBundle* resourceBundle,
              UErrorCode *status);
 
 /**
- * Returns a signed integer from a resource. 
+ * Returns a signed integer from a resource.
  * This integer is originally 28 bit and the sign gets propagated.
  *
  * @param resourceBundle a string resource
  * @param status  fills in the outgoing error code
  *                could be <TT>U_MISSING_RESOURCE_ERROR</TT> if the key is not found
- *                could be a non-failing error 
+ *                could be a non-failing error
  *                e.g.: <TT>U_USING_FALLBACK_WARNING</TT>,<TT>U_USING_DEFAULT_WARNING </TT>
  * @return an integer value
  * @see ures_getUInt
@@ -504,21 +513,21 @@
  * @see ures_getString
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2 
-ures_getInt(const UResourceBundle* resourceBundle, 
+U_CAPI int32_t U_EXPORT2
+ures_getInt(const UResourceBundle* resourceBundle,
             UErrorCode *status);
 
 /**
- * Returns the size of a resource. Size for scalar types is always 1, 
+ * Returns the size of a resource. Size for scalar types is always 1,
  * and for vector/table types is the number of child resources.
- * @warning Integer array is treated as a scalar type. There are no 
+ * @warning Integer array is treated as a scalar type. There are no
  *          APIs to access individual members of an integer array. It
  *          is always returned as a whole.
  * @param resourceBundle a resource
  * @return number of resources in a given resource.
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2 
+U_CAPI int32_t U_EXPORT2
 ures_getSize(const UResourceBundle *resourceBundle);
 
 /**
@@ -529,21 +538,21 @@
  * @see UResType
  * @stable ICU 2.0
  */
-U_STABLE UResType U_EXPORT2 
+U_CAPI UResType U_EXPORT2
 ures_getType(const UResourceBundle *resourceBundle);
 
 /**
- * Returns the key associated with a given resource. Not all the resources have a key - only 
+ * Returns the key associated with a given resource. Not all the resources have a key - only
  * those that are members of a table.
  *
  * @param resourceBundle a resource
  * @return a key associated to this resource, or NULL if it doesn't have a key
  * @stable ICU 2.0
  */
-U_STABLE const char * U_EXPORT2 
+U_CAPI const char * U_EXPORT2
 ures_getKey(const UResourceBundle *resourceBundle);
 
-/* ITERATION API 
+/* ITERATION API
     This API provides means for iterating through a resource
 */
 
@@ -553,70 +562,70 @@
  * @param resourceBundle a resource
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2 
+U_CAPI void U_EXPORT2
 ures_resetIterator(UResourceBundle *resourceBundle);
 
 /**
  * Checks whether the given resource has another element to iterate over.
  *
  * @param resourceBundle a resource
- * @return TRUE if there are more elements, FALSE if there is no more elements
+ * @return true if there are more elements, false if there is no more elements
  * @stable ICU 2.0
  */
-U_STABLE UBool U_EXPORT2 
+U_CAPI UBool U_EXPORT2
 ures_hasNext(const UResourceBundle *resourceBundle);
 
 /**
- * Returns the next resource in a given resource or NULL if there are no more resources 
- * to iterate over. Features a fill-in parameter. 
+ * Returns the next resource in a given resource or NULL if there are no more resources
+ * to iterate over. Features a fill-in parameter.
  *
  * @param resourceBundle    a resource
  * @param fillIn            if NULL a new UResourceBundle struct is allocated and must be closed by the caller.
  *                          Alternatively, you can supply a struct to be filled by this function.
  * @param status            fills in the outgoing error code. You may still get a non NULL result even if an
- *                          error occured. Check status instead.
+ *                          error occurred. Check status instead.
  * @return                  a pointer to a UResourceBundle struct. If fill in param was NULL, caller must close it
  * @stable ICU 2.0
  */
-U_STABLE UResourceBundle* U_EXPORT2 
-ures_getNextResource(UResourceBundle *resourceBundle, 
-                     UResourceBundle *fillIn, 
+U_CAPI UResourceBundle* U_EXPORT2
+ures_getNextResource(UResourceBundle *resourceBundle,
+                     UResourceBundle *fillIn,
                      UErrorCode *status);
 
 /**
- * Returns the next string in a given resource or NULL if there are no more resources 
- * to iterate over. 
+ * Returns the next string in a given resource or NULL if there are no more resources
+ * to iterate over.
  *
  * @param resourceBundle    a resource
  * @param len               fill in length of the string
  * @param key               fill in for key associated with this string. NULL if no key
- * @param status            fills in the outgoing error code. If an error occured, we may return NULL, but don't
+ * @param status            fills in the outgoing error code. If an error occurred, we may return NULL, but don't
  *                          count on it. Check status instead!
  * @return a pointer to a zero-terminated UChar array which lives in a memory mapped/DLL file.
  * @stable ICU 2.0
  */
-U_STABLE const UChar* U_EXPORT2 
-ures_getNextString(UResourceBundle *resourceBundle, 
-                   int32_t* len, 
-                   const char ** key, 
+U_CAPI const UChar* U_EXPORT2
+ures_getNextString(UResourceBundle *resourceBundle,
+                   int32_t* len,
+                   const char ** key,
                    UErrorCode *status);
 
 /**
- * Returns the resource in a given resource at the specified index. Features a fill-in parameter. 
+ * Returns the resource in a given resource at the specified index. Features a fill-in parameter.
  *
  * @param resourceBundle    the resource bundle from which to get a sub-resource
  * @param indexR            an index to the wanted resource.
  * @param fillIn            if NULL a new UResourceBundle struct is allocated and must be closed by the caller.
  *                          Alternatively, you can supply a struct to be filled by this function.
  * @param status            fills in the outgoing error code. Don't count on NULL being returned if an error has
- *                          occured. Check status instead.
+ *                          occurred. Check status instead.
  * @return                  a pointer to a UResourceBundle struct. If fill in param was NULL, caller must close it
  * @stable ICU 2.0
  */
-U_STABLE UResourceBundle* U_EXPORT2 
-ures_getByIndex(const UResourceBundle *resourceBundle, 
-                int32_t indexR, 
-                UResourceBundle *fillIn, 
+U_CAPI UResourceBundle* U_EXPORT2
+ures_getByIndex(const UResourceBundle *resourceBundle,
+                int32_t indexR,
+                UResourceBundle *fillIn,
                 UErrorCode *status);
 
 /**
@@ -625,15 +634,15 @@
  * @param resourceBundle    a resource
  * @param indexS            an index to the wanted string.
  * @param len               fill in length of the string
- * @param status            fills in the outgoing error code. If an error occured, we may return NULL, but don't
+ * @param status            fills in the outgoing error code. If an error occurred, we may return NULL, but don't
  *                          count on it. Check status instead!
  * @return                  a pointer to a zero-terminated UChar array which lives in a memory mapped/DLL file.
  * @stable ICU 2.0
  */
-U_STABLE const UChar* U_EXPORT2 
-ures_getStringByIndex(const UResourceBundle *resourceBundle, 
-                      int32_t indexS, 
-                      int32_t* len, 
+U_CAPI const UChar* U_EXPORT2
+ures_getStringByIndex(const UResourceBundle *resourceBundle,
+                      int32_t indexS,
+                      int32_t* len,
                       UErrorCode *status);
 
 /**
@@ -642,10 +651,10 @@
  * it may need to be copied, or transformed from UTF-16 using u_strToUTF8()
  * or equivalent.
  *
- * If forceCopy==TRUE, then the string is always written to the dest buffer
+ * If forceCopy==true, then the string is always written to the dest buffer
  * and dest is returned.
  *
- * If forceCopy==FALSE, then the string is returned as a pointer if possible,
+ * If forceCopy==false, then the string is returned as a pointer if possible,
  * without needing a dest buffer (it can be NULL). If the string needs to be
  * copied or transformed, then it may be placed into dest at an arbitrary offset.
  *
@@ -664,10 +673,10 @@
  *               terminating NUL, even in case of U_BUFFER_OVERFLOW_ERROR.
  *               Can be NULL, meaning capacity=0 and the string length is not
  *               returned to the caller.
- * @param forceCopy If TRUE, then the output string will always be written to
+ * @param forceCopy If true, then the output string will always be written to
  *                  dest, with U_BUFFER_OVERFLOW_ERROR and
  *                  U_STRING_NOT_TERMINATED_WARNING set if appropriate.
- *                  If FALSE, then the dest buffer may or may not contain a
+ *                  If false, then the dest buffer may or may not contain a
  *                  copy of the string. dest may or may not be modified.
  *                  If a copy needs to be written, then the UErrorCode parameter
  *                  indicates overflow etc. as usual.
@@ -684,7 +693,7 @@
  * @see u_strToUTF8
  * @stable ICU 3.6
  */
-U_STABLE const char * U_EXPORT2
+U_CAPI const char * U_EXPORT2
 ures_getUTF8StringByIndex(const UResourceBundle *resB,
                           int32_t stringIndex,
                           char *dest, int32_t *pLength,
@@ -693,7 +702,7 @@
 
 /**
  * Returns a resource in a given resource that has a given key. This procedure works only with table
- * resources. Features a fill-in parameter. 
+ * resources. Features a fill-in parameter.
  *
  * @param resourceBundle    a resource
  * @param key               a key associated with the wanted resource
@@ -703,28 +712,28 @@
  * @return                  a pointer to a UResourceBundle struct. If fill in param was NULL, caller must close it
  * @stable ICU 2.0
  */
-U_STABLE UResourceBundle* U_EXPORT2 
-ures_getByKey(const UResourceBundle *resourceBundle, 
-              const char* key, 
-              UResourceBundle *fillIn, 
+U_CAPI UResourceBundle* U_EXPORT2
+ures_getByKey(const UResourceBundle *resourceBundle,
+              const char* key,
+              UResourceBundle *fillIn,
               UErrorCode *status);
 
 /**
  * Returns a string in a given resource that has a given key. This procedure works only with table
- * resources. 
+ * resources.
  *
  * @param resB              a resource
  * @param key               a key associated with the wanted string
  * @param len               fill in length of the string
- * @param status            fills in the outgoing error code. If an error occured, we may return NULL, but don't
+ * @param status            fills in the outgoing error code. If an error occurred, we may return NULL, but don't
  *                          count on it. Check status instead!
  * @return                  a pointer to a zero-terminated UChar array which lives in a memory mapped/DLL file.
  * @stable ICU 2.0
  */
-U_STABLE const UChar* U_EXPORT2 
-ures_getStringByKey(const UResourceBundle *resB, 
-                    const char* key, 
-                    int32_t* len, 
+U_CAPI const UChar* U_EXPORT2
+ures_getStringByKey(const UResourceBundle *resB,
+                    const char* key,
+                    int32_t* len,
                     UErrorCode *status);
 
 /**
@@ -735,10 +744,10 @@
  * it may need to be copied, or transformed from UTF-16 using u_strToUTF8()
  * or equivalent.
  *
- * If forceCopy==TRUE, then the string is always written to the dest buffer
+ * If forceCopy==true, then the string is always written to the dest buffer
  * and dest is returned.
  *
- * If forceCopy==FALSE, then the string is returned as a pointer if possible,
+ * If forceCopy==false, then the string is returned as a pointer if possible,
  * without needing a dest buffer (it can be NULL). If the string needs to be
  * copied or transformed, then it may be placed into dest at an arbitrary offset.
  *
@@ -757,10 +766,10 @@
  *               terminating NUL, even in case of U_BUFFER_OVERFLOW_ERROR.
  *               Can be NULL, meaning capacity=0 and the string length is not
  *               returned to the caller.
- * @param forceCopy If TRUE, then the output string will always be written to
+ * @param forceCopy If true, then the output string will always be written to
  *                  dest, with U_BUFFER_OVERFLOW_ERROR and
  *                  U_STRING_NOT_TERMINATED_WARNING set if appropriate.
- *                  If FALSE, then the dest buffer may or may not contain a
+ *                  If false, then the dest buffer may or may not contain a
  *                  copy of the string. dest may or may not be modified.
  *                  If a copy needs to be written, then the UErrorCode parameter
  *                  indicates overflow etc. as usual.
@@ -777,7 +786,7 @@
  * @see u_strToUTF8
  * @stable ICU 3.6
  */
-U_STABLE const char * U_EXPORT2
+U_CAPI const char * U_EXPORT2
 ures_getUTF8StringByKey(const UResourceBundle *resB,
                         const char *key,
                         char *dest, int32_t *pLength,
@@ -789,82 +798,97 @@
 
 U_NAMESPACE_BEGIN
 /**
- * returns a string from a string resource type
+ * Returns the string value from a string resource bundle.
  *
- * @param resB    a resource
+ * @param resB    a resource, should have type URES_STRING
  * @param status: fills in the outgoing error code
  *                could be <TT>U_MISSING_RESOURCE_ERROR</TT> if the key is not found
- *                could be a non-failing error 
+ *                could be a non-failing error
  *                e.g.: <TT>U_USING_FALLBACK_WARNING</TT>,<TT>U_USING_DEFAULT_WARNING </TT>
- * @return        a UnicodeString object. If there is an error, string is bogus
+ * @return The string value, or a bogus string if there is a failure UErrorCode.
  * @stable ICU 2.0
  */
-inline UnicodeString 
-ures_getUnicodeString(const UResourceBundle *resB, 
-                      UErrorCode* status) 
-{
+inline UnicodeString
+ures_getUnicodeString(const UResourceBundle *resB, UErrorCode* status) {
+    UnicodeString result;
     int32_t len = 0;
     const UChar *r = ures_getString(resB, &len, status);
-    return UnicodeString(TRUE, r, len);
+    if(U_SUCCESS(*status)) {
+        result.setTo(true, r, len);
+    } else {
+        result.setToBogus();
+    }
+    return result;
 }
 
 /**
- * Returns the next string in a resource or NULL if there are no more resources 
- * to iterate over. 
+ * Returns the next string in a resource, or an empty string if there are no more resources
+ * to iterate over.
+ * Use ures_getNextString() instead to distinguish between
+ * the end of the iteration and a real empty string value.
  *
  * @param resB              a resource
  * @param key               fill in for key associated with this string
  * @param status            fills in the outgoing error code
- * @return an UnicodeString object.
+ * @return The string value, or a bogus string if there is a failure UErrorCode.
  * @stable ICU 2.0
  */
-inline UnicodeString 
-ures_getNextUnicodeString(UResourceBundle *resB, 
-                          const char ** key, 
-                          UErrorCode* status) 
-{
+inline UnicodeString
+ures_getNextUnicodeString(UResourceBundle *resB, const char ** key, UErrorCode* status) {
+    UnicodeString result;
     int32_t len = 0;
     const UChar* r = ures_getNextString(resB, &len, key, status);
-    return UnicodeString(TRUE, r, len);
+    if(U_SUCCESS(*status)) {
+        result.setTo(true, r, len);
+    } else {
+        result.setToBogus();
+    }
+    return result;
 }
 
 /**
- * Returns the string in a given resource at the specified index.
+ * Returns the string in a given resource array or table at the specified index.
  *
  * @param resB              a resource
  * @param indexS            an index to the wanted string.
  * @param status            fills in the outgoing error code
- * @return                  an UnicodeString object. If there is an error, string is bogus
+ * @return The string value, or a bogus string if there is a failure UErrorCode.
  * @stable ICU 2.0
  */
-inline UnicodeString 
-ures_getUnicodeStringByIndex(const UResourceBundle *resB, 
-                             int32_t indexS, 
-                             UErrorCode* status) 
-{
+inline UnicodeString
+ures_getUnicodeStringByIndex(const UResourceBundle *resB, int32_t indexS, UErrorCode* status) {
+    UnicodeString result;
     int32_t len = 0;
     const UChar* r = ures_getStringByIndex(resB, indexS, &len, status);
-    return UnicodeString(TRUE, r, len);
+    if(U_SUCCESS(*status)) {
+        result.setTo(true, r, len);
+    } else {
+        result.setToBogus();
+    }
+    return result;
 }
 
 /**
- * Returns a string in a resource that has a given key. This procedure works only with table
- * resources. 
+ * Returns a string in a resource that has a given key.
+ * This procedure works only with table resources.
  *
  * @param resB              a resource
  * @param key               a key associated with the wanted string
  * @param status            fills in the outgoing error code
- * @return                  an UnicodeString object. If there is an error, string is bogus
+ * @return The string value, or a bogus string if there is a failure UErrorCode.
  * @stable ICU 2.0
  */
-inline UnicodeString 
-ures_getUnicodeStringByKey(const UResourceBundle *resB, 
-                           const char* key, 
-                           UErrorCode* status) 
-{
+inline UnicodeString
+ures_getUnicodeStringByKey(const UResourceBundle *resB, const char* key, UErrorCode* status) {
+    UnicodeString result;
     int32_t len = 0;
     const UChar* r = ures_getStringByKey(resB, key, &len, status);
-    return UnicodeString(TRUE, r, len);
+    if(U_SUCCESS(*status)) {
+        result.setTo(true, r, len);
+    } else {
+        result.setToBogus();
+    }
+    return result;
 }
 
 U_NAMESPACE_END
@@ -872,14 +896,14 @@
 #endif
 
 /**
- * Create a string enumerator, owned by the caller, of all locales located within 
+ * Create a string enumerator, owned by the caller, of all locales located within
  * the specified resource tree.
  * @param packageName name of the tree, such as (NULL) or U_ICUDATA_ALIAS or  or "ICUDATA-coll"
  * This call is similar to uloc_getAvailable().
  * @param status error code
  * @stable ICU 3.2
  */
-U_STABLE UEnumeration* U_EXPORT2
+U_CAPI UEnumeration* U_EXPORT2
 ures_openAvailableLocales(const char *packageName, UErrorCode *status);
 
 
diff --git a/src/third_party/icu/source/common/unicode/uscript.h b/src/third_party/icu/source/common/unicode/uscript.h
index a5fb167..8448afd 100644
--- a/src/third_party/icu/source/common/unicode/uscript.h
+++ b/src/third_party/icu/source/common/unicode/uscript.h
@@ -1,6 +1,8 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
  **********************************************************************
- *   Copyright (C) 1997-2015, International Business Machines
+ *   Copyright (C) 1997-2016, International Business Machines
  *   Corporation and others.  All Rights Reserved.
  **********************************************************************
  *
@@ -32,13 +34,13 @@
  * See UAX #24 Unicode Script Property (http://www.unicode.org/reports/tr24/)
  * and http://www.unicode.org/Public/UCD/latest/ucd/PropertyValueAliases.txt .
  *
- * Starting with ICU 3.6, constants for most ISO 15924 script codes
+ * In addition, constants for many ISO 15924 script codes
  * are included, for use with language tags, CLDR data, and similar.
  * Some of those codes are not used in the Unicode Character Database (UCD).
  * For example, there are no characters that have a UCD script property value of
  * Hans or Hant. All Han ideographs have the Hani script property value in Unicode.
  *
- * Private-use codes Qaaa..Qabx are not included.
+ * Private-use codes Qaaa..Qabx are not included, except as used in the UCD or in CLDR.
  *
  * Starting with ICU 55, script codes are only added when their scripts
  * have been or will certainly be encoded in Unicode,
@@ -424,24 +426,79 @@
       /** @stable ICU 54 */
       USCRIPT_SIDDHAM                       = 166,/* Sidd */
 
-      /**
-       * One higher than the last script code constant.
-       * This value increases as constants for script codes are added.
-       *
-       * There are constants for Unicode 7 script property values.
-       * There are constants for ISO 15924 script codes assigned on or before 2013-10-12.
-       * There are no constants for private use codes from Qaaa - Qabx
-       * except as used in the UCD.
-       *
-       * @stable ICU 2.2
-       */
-      USCRIPT_CODE_LIMIT    = 167
+      /** @stable ICU 58 */
+      USCRIPT_ADLAM                         = 167,/* Adlm */
+      /** @stable ICU 58 */
+      USCRIPT_BHAIKSUKI                     = 168,/* Bhks */
+      /** @stable ICU 58 */
+      USCRIPT_MARCHEN                       = 169,/* Marc */
+      /** @stable ICU 58 */
+      USCRIPT_NEWA                          = 170,/* Newa */
+      /** @stable ICU 58 */
+      USCRIPT_OSAGE                         = 171,/* Osge */
+
+      /** @stable ICU 58 */
+      USCRIPT_HAN_WITH_BOPOMOFO             = 172,/* Hanb */
+      /** @stable ICU 58 */
+      USCRIPT_JAMO                          = 173,/* Jamo */
+      /** @stable ICU 58 */
+      USCRIPT_SYMBOLS_EMOJI                 = 174,/* Zsye */
+
+      /** @stable ICU 60 */
+      USCRIPT_MASARAM_GONDI                 = 175,/* Gonm */
+      /** @stable ICU 60 */
+      USCRIPT_SOYOMBO                       = 176,/* Soyo */
+      /** @stable ICU 60 */
+      USCRIPT_ZANABAZAR_SQUARE              = 177,/* Zanb */
+
+      /** @stable ICU 62 */
+      USCRIPT_DOGRA                         = 178,/* Dogr */
+      /** @stable ICU 62 */
+      USCRIPT_GUNJALA_GONDI                 = 179,/* Gong */
+      /** @stable ICU 62 */
+      USCRIPT_MAKASAR                       = 180,/* Maka */
+      /** @stable ICU 62 */
+      USCRIPT_MEDEFAIDRIN                   = 181,/* Medf */
+      /** @stable ICU 62 */
+      USCRIPT_HANIFI_ROHINGYA               = 182,/* Rohg */
+      /** @stable ICU 62 */
+      USCRIPT_SOGDIAN                       = 183,/* Sogd */
+      /** @stable ICU 62 */
+      USCRIPT_OLD_SOGDIAN                   = 184,/* Sogo */
+
+      /** @stable ICU 64 */
+      USCRIPT_ELYMAIC                       = 185,/* Elym */
+      /** @stable ICU 64 */
+      USCRIPT_NYIAKENG_PUACHUE_HMONG        = 186,/* Hmnp */
+      /** @stable ICU 64 */
+      USCRIPT_NANDINAGARI                   = 187,/* Nand */
+      /** @stable ICU 64 */
+      USCRIPT_WANCHO                        = 188,/* Wcho */
+
+      /** @stable ICU 66 */
+      USCRIPT_CHORASMIAN                    = 189,/* Chrs */
+      /** @stable ICU 66 */
+      USCRIPT_DIVES_AKURU                   = 190,/* Diak */
+      /** @stable ICU 66 */
+      USCRIPT_KHITAN_SMALL_SCRIPT           = 191,/* Kits */
+      /** @stable ICU 66 */
+      USCRIPT_YEZIDI                        = 192,/* Yezi */
+
+#ifndef U_HIDE_DEPRECATED_API
+    /**
+     * One more than the highest normal UScriptCode value.
+     * The highest value is available via u_getIntPropertyMaxValue(UCHAR_SCRIPT).
+     *
+     * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
+     */
+    USCRIPT_CODE_LIMIT    = 193
+#endif  // U_HIDE_DEPRECATED_API
 } UScriptCode;
 
 /**
- * Gets the script codes associated with the given locale or ISO 15924 abbreviation or name. 
+ * Gets the script codes associated with the given locale or ISO 15924 abbreviation or name.
  * Fills in USCRIPT_MALAYALAM given "Malayam" OR "Mlym".
- * Fills in USCRIPT_LATIN given "en" OR "en_US" 
+ * Fills in USCRIPT_LATIN given "en" OR "en_US"
  * If the required capacity is greater than the capacity of the destination buffer,
  * then the error code is set to U_BUFFER_OVERFLOW_ERROR and the required capacity is returned.
  *
@@ -452,12 +509,12 @@
  * @param nameOrAbbrOrLocale name of the script, as given in
  * PropertyValueAliases.txt, or ISO 15924 code or locale
  * @param fillIn the UScriptCode buffer to fill in the script code
- * @param capacity the capacity (size) fo UScriptCode buffer passed in.
+ * @param capacity the capacity (size) of UScriptCode buffer passed in.
  * @param err the error status code.
- * @return The number of script codes filled in the buffer passed in 
+ * @return The number of script codes filled in the buffer passed in
  * @stable ICU 2.4
  */
-U_STABLE int32_t  U_EXPORT2 
+U_CAPI int32_t  U_EXPORT2
 uscript_getCode(const char* nameOrAbbrOrLocale,UScriptCode* fillIn,int32_t capacity,UErrorCode *err);
 
 /**
@@ -470,7 +527,7 @@
  * or NULL if scriptCode is invalid
  * @stable ICU 2.4
  */
-U_STABLE const char*  U_EXPORT2 
+U_CAPI const char*  U_EXPORT2
 uscript_getName(UScriptCode scriptCode);
 
 /**
@@ -482,18 +539,18 @@
  * @return short script name (4-letter code), or NULL if scriptCode is invalid
  * @stable ICU 2.4
  */
-U_STABLE const char*  U_EXPORT2 
+U_CAPI const char*  U_EXPORT2
 uscript_getShortName(UScriptCode scriptCode);
 
 /**
  * Gets the script code associated with the given codepoint.
- * Returns USCRIPT_MALAYALAM given 0x0D02 
+ * Returns USCRIPT_MALAYALAM given 0x0D02
  * @param codepoint UChar32 codepoint
  * @param err the error status code.
- * @return The UScriptCode, or 0 if codepoint is invalid 
+ * @return The UScriptCode, or 0 if codepoint is invalid
  * @stable ICU 2.4
  */
-U_STABLE UScriptCode  U_EXPORT2 
+U_CAPI UScriptCode  U_EXPORT2
 uscript_getScript(UChar32 codepoint, UErrorCode *err);
 
 /**
@@ -503,15 +560,12 @@
  *
  * Some characters are commonly used in multiple scripts.
  * For more information, see UAX #24: http://www.unicode.org/reports/tr24/.
- *
- * The Script_Extensions property is provisional. It may be modified or removed
- * in future versions of the Unicode Standard, and thus in ICU.
  * @param c code point
  * @param sc script code
- * @return TRUE if sc is in Script_Extensions(c)
+ * @return true if sc is in Script_Extensions(c)
  * @stable ICU 49
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 uscript_hasScript(UChar32 c, UScriptCode sc);
 
 /**
@@ -532,8 +586,6 @@
  * U_BUFFER_OVERFLOW_ERROR is set and the number of Script_Extensions is returned.
  * (Usual ICU buffer handling behavior.)
  *
- * The Script_Extensions property is provisional. It may be modified or removed
- * in future versions of the Unicode Standard, and thus in ICU.
  * @param c code point
  * @param scripts output script code array
  * @param capacity capacity of the scripts array
@@ -545,7 +597,7 @@
  *         written to scripts unless U_BUFFER_OVERFLOW_ERROR indicates insufficient capacity
  * @stable ICU 49
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 uscript_getScriptExtensions(UChar32 c,
                             UScriptCode *scripts, int32_t capacity,
                             UErrorCode *errorCode);
@@ -584,7 +636,7 @@
  * @return the string length, even if U_BUFFER_OVERFLOW_ERROR
  * @stable ICU 51
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 uscript_getSampleString(UScriptCode script, UChar *dest, int32_t capacity, UErrorCode *pErrorCode);
 
 #if U_SHOW_CPLUSPLUS_API
@@ -616,41 +668,41 @@
  * @see UScriptUsage
  * @stable ICU 51
  */
-U_STABLE UScriptUsage U_EXPORT2
+U_CAPI UScriptUsage U_EXPORT2
 uscript_getUsage(UScriptCode script);
 
 /**
- * Returns TRUE if the script is written right-to-left.
+ * Returns true if the script is written right-to-left.
  * For example, Arab and Hebr.
  *
  * @param script script code
- * @return TRUE if the script is right-to-left
+ * @return true if the script is right-to-left
  * @stable ICU 51
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 uscript_isRightToLeft(UScriptCode script);
 
 /**
- * Returns TRUE if the script allows line breaks between letters (excluding hyphenation).
+ * Returns true if the script allows line breaks between letters (excluding hyphenation).
  * Such a script typically requires dictionary-based line breaking.
  * For example, Hani and Thai.
  *
  * @param script script code
- * @return TRUE if the script allows line breaks between letters
+ * @return true if the script allows line breaks between letters
  * @stable ICU 51
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 uscript_breaksBetweenLetters(UScriptCode script);
 
 /**
- * Returns TRUE if in modern (or most recent) usage of the script case distinctions are customary.
+ * Returns true if in modern (or most recent) usage of the script case distinctions are customary.
  * For example, Latn and Cyrl.
  *
  * @param script script code
- * @return TRUE if the script is cased
+ * @return true if the script is cased
  * @stable ICU 51
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 uscript_isCased(UScriptCode script);
 
 #endif
diff --git a/src/third_party/icu/source/common/unicode/uset.h b/src/third_party/icu/source/common/unicode/uset.h
index eb3c9e6..502ea8d 100644
--- a/src/third_party/icu/source/common/unicode/uset.h
+++ b/src/third_party/icu/source/common/unicode/uset.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  uset.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -29,12 +31,19 @@
 
 #include "unicode/utypes.h"
 #include "unicode/uchar.h"
-#include "unicode/localpointer.h"
 
-#ifndef UCNV_H
-struct USet;
+#if U_SHOW_CPLUSPLUS_API
+#include "unicode/localpointer.h"
+#endif   // U_SHOW_CPLUSPLUS_API
+
+#ifndef USET_DEFINED
+
+#ifndef U_IN_DOXYGEN
+#define USET_DEFINED
+#endif
 /**
- * A UnicodeSet.  Use the uset_* API to manipulate.  Create with
+ * USet is the C API type corresponding to C++ class UnicodeSet.
+ * Use the uset_* API to manipulate.  Create with
  * uset_open*, and destroy with uset_close.
  * @stable ICU 2.4
  */
@@ -152,7 +161,7 @@
      * Continues a span() while there is no set element at the current position.
      * Increments by one code point at a time.
      * Stops before the first set element (character or string).
-     * (For code points only, this is like while contains(current)==FALSE).
+     * (For code points only, this is like while contains(current)==false).
      *
      * When span() returns, the substring between where it started and the position
      * it returned consists only of characters that are not in the set,
@@ -163,7 +172,7 @@
     USET_SPAN_NOT_CONTAINED = 0,
     /**
      * Spans the longest substring that is a concatenation of set elements (characters or strings).
-     * (For characters only, this is like while contains(current)==TRUE).
+     * (For characters only, this is like while contains(current)==true).
      *
      * When span() returns, the substring between where it started and the position
      * it returned consists only of set elements (characters or strings) that are in the set.
@@ -179,7 +188,7 @@
     /**
      * Continues a span() while there is a set element at the current position.
      * Increments by the longest matching element at each position.
-     * (For characters only, this is like while contains(current)==TRUE).
+     * (For characters only, this is like while contains(current)==true).
      *
      * When span() returns, the substring between where it started and the position
      * it returned consists only of set elements (characters or strings) that are in the set.
@@ -196,11 +205,13 @@
      * @stable ICU 3.8
      */
     USET_SPAN_SIMPLE = 2,
+#ifndef U_HIDE_DEPRECATED_API
     /**
      * One more than the last span condition.
-     * @stable ICU 3.8
+     * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
      */
     USET_SPAN_CONDITION_COUNT
+#endif  // U_HIDE_DEPRECATED_API
 } USetSpanCondition;
 
 enum {
@@ -252,7 +263,7 @@
  * it when done.
  * @stable ICU 4.2
  */
-U_STABLE USet* U_EXPORT2
+U_CAPI USet* U_EXPORT2
 uset_openEmpty(void);
 
 /**
@@ -265,7 +276,7 @@
  * it when done.
  * @stable ICU 2.4
  */
-U_STABLE USet* U_EXPORT2
+U_CAPI USet* U_EXPORT2
 uset_open(UChar32 start, UChar32 end);
 
 /**
@@ -277,7 +288,7 @@
  * @param ec the error code
  * @stable ICU 2.4
  */
-U_STABLE USet* U_EXPORT2
+U_CAPI USet* U_EXPORT2
 uset_openPattern(const UChar* pattern, int32_t patternLength,
                  UErrorCode* ec);
 
@@ -292,7 +303,7 @@
  * @param ec the error code
  * @stable ICU 2.4
  */
-U_STABLE USet* U_EXPORT2
+U_CAPI USet* U_EXPORT2
 uset_openPatternOptions(const UChar* pattern, int32_t patternLength,
                  uint32_t options,
                  UErrorCode* ec);
@@ -303,7 +314,7 @@
  * @param set the object to dispose of
  * @stable ICU 2.4
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 uset_close(USet* set);
 
 #if U_SHOW_CPLUSPLUS_API
@@ -334,19 +345,19 @@
  * @see uset_cloneAsThawed
  * @stable ICU 3.8
  */
-U_STABLE USet * U_EXPORT2
+U_CAPI USet * U_EXPORT2
 uset_clone(const USet *set);
 
 /**
  * Determines whether the set has been frozen (made immutable) or not.
  * See the ICU4J Freezable interface for details.
  * @param set the set
- * @return TRUE/FALSE for whether the set has been frozen
+ * @return true/false for whether the set has been frozen
  * @see uset_freeze
  * @see uset_cloneAsThawed
  * @stable ICU 3.8
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 uset_isFrozen(const USet *set);
 
 /**
@@ -363,7 +374,7 @@
  * @see uset_cloneAsThawed
  * @stable ICU 3.8
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 uset_freeze(USet *set);
 
 /**
@@ -376,7 +387,7 @@
  * @see uset_clone
  * @stable ICU 3.8
  */
-U_STABLE USet * U_EXPORT2
+U_CAPI USet * U_EXPORT2
 uset_cloneAsThawed(const USet *set);
 
 /**
@@ -388,7 +399,7 @@
  * @param end last character in the set, inclusive
  * @stable ICU 3.2
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 uset_set(USet* set,
          UChar32 start, UChar32 end);
 
@@ -413,7 +424,7 @@
  *
  * @stable ICU 2.8
  */
-U_STABLE int32_t U_EXPORT2 
+U_CAPI int32_t U_EXPORT2 
 uset_applyPattern(USet *set,
                   const UChar *pattern, int32_t patternLength,
                   uint32_t options,
@@ -441,7 +452,7 @@
  *
  * @stable ICU 3.2
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 uset_applyIntPropertyValue(USet* set,
                            UProperty prop, int32_t value, UErrorCode* ec);
 
@@ -480,7 +491,7 @@
  *
  * @stable ICU 3.2
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 uset_applyPropertyAlias(USet* set,
                         const UChar *prop, int32_t propLength,
                         const UChar *value, int32_t valueLength,
@@ -495,7 +506,7 @@
  * @param pos the given position
  * @stable ICU 3.2
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 uset_resemblesPattern(const UChar *pattern, int32_t patternLength,
                       int32_t pos);
 
@@ -506,7 +517,7 @@
  * @param set the set
  * @param result the string to receive the rules, may be NULL
  * @param resultCapacity the capacity of result, may be 0 if result is NULL
- * @param escapeUnprintable if TRUE then convert unprintable
+ * @param escapeUnprintable if true then convert unprintable
  * character to their hex escape representations, \\uxxxx or
  * \\Uxxxxxxxx.  Unprintable characters are those other than
  * U+000A, U+0020..U+007E.
@@ -514,7 +525,7 @@
  * @return length of string, possibly larger than resultCapacity
  * @stable ICU 2.4
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 uset_toPattern(const USet* set,
                UChar* result, int32_t resultCapacity,
                UBool escapeUnprintable,
@@ -522,13 +533,13 @@
 
 /**
  * Adds the given character to the given USet.  After this call,
- * uset_contains(set, c) will return TRUE.
+ * uset_contains(set, c) will return true.
  * A frozen set will not be modified.
  * @param set the object to which to add the character
  * @param c the character to add
  * @stable ICU 2.4
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 uset_add(USet* set, UChar32 c);
 
 /**
@@ -543,31 +554,31 @@
  * @param additionalSet the source set whose elements are to be added to this set.
  * @stable ICU 2.6
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 uset_addAll(USet* set, const USet *additionalSet);
 
 /**
  * Adds the given range of characters to the given USet.  After this call,
- * uset_contains(set, start, end) will return TRUE.
+ * uset_contains(set, start, end) will return true.
  * A frozen set will not be modified.
  * @param set the object to which to add the character
  * @param start the first character of the range to add, inclusive
  * @param end the last character of the range to add, inclusive
  * @stable ICU 2.2
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 uset_addRange(USet* set, UChar32 start, UChar32 end);
 
 /**
  * Adds the given string to the given USet.  After this call,
- * uset_containsString(set, str, strLen) will return TRUE.
+ * uset_containsString(set, str, strLen) will return true.
  * A frozen set will not be modified.
  * @param set the object to which to add the character
  * @param str the string to add
  * @param strLen the length of the string or -1 if null terminated.
  * @stable ICU 2.4
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 uset_addString(USet* set, const UChar* str, int32_t strLen);
 
 /**
@@ -579,42 +590,42 @@
  * @param strLen the length of the string or -1 if null terminated.
  * @stable ICU 3.4
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 uset_addAllCodePoints(USet* set, const UChar *str, int32_t strLen);
 
 /**
  * Removes the given character from the given USet.  After this call,
- * uset_contains(set, c) will return FALSE.
+ * uset_contains(set, c) will return false.
  * A frozen set will not be modified.
  * @param set the object from which to remove the character
  * @param c the character to remove
  * @stable ICU 2.4
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 uset_remove(USet* set, UChar32 c);
 
 /**
  * Removes the given range of characters from the given USet.  After this call,
- * uset_contains(set, start, end) will return FALSE.
+ * uset_contains(set, start, end) will return false.
  * A frozen set will not be modified.
  * @param set the object to which to add the character
  * @param start the first character of the range to remove, inclusive
  * @param end the last character of the range to remove, inclusive
  * @stable ICU 2.2
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 uset_removeRange(USet* set, UChar32 start, UChar32 end);
 
 /**
  * Removes the given string to the given USet.  After this call,
- * uset_containsString(set, str, strLen) will return FALSE.
+ * uset_containsString(set, str, strLen) will return false.
  * A frozen set will not be modified.
  * @param set the object to which to add the character
  * @param str the string to remove
  * @param strLen the length of the string or -1 if null terminated.
  * @stable ICU 2.4
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 uset_removeString(USet* set, const UChar* str, int32_t strLen);
 
 /**
@@ -628,7 +639,7 @@
  * removed from this set
  * @stable ICU 3.2
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 uset_removeAll(USet* set, const USet* removeSet);
 
 /**
@@ -645,7 +656,7 @@
  * to this set.
  * @stable ICU 3.2
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 uset_retain(USet* set, UChar32 start, UChar32 end);
 
 /**
@@ -660,7 +671,7 @@
  * @param retain set that defines which elements this set will retain
  * @stable ICU 3.2
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 uset_retainAll(USet* set, const USet* retain);
 
 /**
@@ -671,7 +682,7 @@
  * @param set the object on which to perfrom the compact
  * @stable ICU 3.2
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 uset_compact(USet* set);
 
 /**
@@ -682,7 +693,7 @@
  * @param set the set
  * @stable ICU 2.4
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 uset_complement(USet* set);
 
 /**
@@ -696,7 +707,7 @@
  * from this set.
  * @stable ICU 3.2
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 uset_complementAll(USet* set, const USet* complement);
 
 /**
@@ -706,7 +717,7 @@
  * @param set the set
  * @stable ICU 2.4
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 uset_clear(USet* set);
 
 /**
@@ -735,7 +746,7 @@
  * are ignored.
  * @stable ICU 4.2
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 uset_closeOver(USet* set, int32_t attributes);
 
 /**
@@ -744,51 +755,51 @@
  * @param set the set
  * @stable ICU 4.2
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 uset_removeAllStrings(USet* set);
 
 /**
- * Returns TRUE if the given USet contains no characters and no
+ * Returns true if the given USet contains no characters and no
  * strings.
  * @param set the set
  * @return true if set is empty
  * @stable ICU 2.4
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 uset_isEmpty(const USet* set);
 
 /**
- * Returns TRUE if the given USet contains the given character.
+ * Returns true if the given USet contains the given character.
  * This function works faster with a frozen set.
  * @param set the set
  * @param c The codepoint to check for within the set
  * @return true if set contains c
  * @stable ICU 2.4
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 uset_contains(const USet* set, UChar32 c);
 
 /**
- * Returns TRUE if the given USet contains all characters c
+ * Returns true if the given USet contains all characters c
  * where start <= c && c <= end.
  * @param set the set
  * @param start the first character of the range to test, inclusive
  * @param end the last character of the range to test, inclusive
- * @return TRUE if set contains the range
+ * @return true if set contains the range
  * @stable ICU 2.2
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 uset_containsRange(const USet* set, UChar32 start, UChar32 end);
 
 /**
- * Returns TRUE if the given USet contains the given string.
+ * Returns true if the given USet contains the given string.
  * @param set the set
  * @param str the string
  * @param strLen the length of the string or -1 if null terminated.
  * @return true if set contains str
  * @stable ICU 2.4
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 uset_containsString(const USet* set, const UChar* str, int32_t strLen);
 
 /**
@@ -801,7 +812,7 @@
  * @return an index from 0..size()-1, or -1
  * @stable ICU 3.2
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 uset_indexOf(const USet* set, UChar32 c);
 
 /**
@@ -814,7 +825,7 @@
  * @return the character at the given index, or (UChar32)-1.
  * @stable ICU 3.2
  */
-U_STABLE UChar32 U_EXPORT2
+U_CAPI UChar32 U_EXPORT2
 uset_charAt(const USet* set, int32_t charIndex);
 
 /**
@@ -825,7 +836,7 @@
  * contained in set
  * @stable ICU 2.4
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 uset_size(const USet* set);
 
 /**
@@ -836,7 +847,7 @@
  * and/or strings contained in set
  * @stable ICU 2.4
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 uset_getItemCount(const USet* set);
 
 /**
@@ -857,7 +868,7 @@
  * itemIndex is out of range
  * @stable ICU 2.4
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 uset_getItem(const USet* set, int32_t itemIndex,
              UChar32* start, UChar32* end,
              UChar* str, int32_t strCapacity,
@@ -871,7 +882,7 @@
  * @return true if the test condition is met
  * @stable ICU 3.2
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 uset_containsAll(const USet* set1, const USet* set2);
 
 /**
@@ -884,7 +895,7 @@
  * @return true if the test condition is met
  * @stable ICU 3.4
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 uset_containsAllCodePoints(const USet* set, const UChar *str, int32_t strLen);
 
 /**
@@ -895,7 +906,7 @@
  * @return true if the test condition is met
  * @stable ICU 3.2
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 uset_containsNone(const USet* set1, const USet* set2);
 
 /**
@@ -906,7 +917,7 @@
  * @return true if the test condition is met
  * @stable ICU 3.2
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 uset_containsSome(const USet* set1, const USet* set2);
 
 /**
@@ -928,7 +939,7 @@
  * @stable ICU 3.8
  * @see USetSpanCondition
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 uset_span(const USet *set, const UChar *s, int32_t length, USetSpanCondition spanCondition);
 
 /**
@@ -949,7 +960,7 @@
  * @stable ICU 3.8
  * @see USetSpanCondition
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 uset_spanBack(const USet *set, const UChar *s, int32_t length, USetSpanCondition spanCondition);
 
 /**
@@ -971,7 +982,7 @@
  * @stable ICU 3.8
  * @see USetSpanCondition
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 uset_spanUTF8(const USet *set, const char *s, int32_t length, USetSpanCondition spanCondition);
 
 /**
@@ -992,7 +1003,7 @@
  * @stable ICU 3.8
  * @see USetSpanCondition
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 uset_spanBackUTF8(const USet *set, const char *s, int32_t length, USetSpanCondition spanCondition);
 
 /**
@@ -1003,7 +1014,7 @@
  * @return true if the test condition is met
  * @stable ICU 3.2
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 uset_equals(const USet* set1, const USet* set2);
 
 /*********************************************************************
@@ -1059,7 +1070,7 @@
  * than U_BUFFER_OVERFLOW_ERROR.
  * @stable ICU 2.4
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 uset_serialize(const USet* set, uint16_t* dest, int32_t destCapacity, UErrorCode* pErrorCode);
 
 /**
@@ -1070,7 +1081,7 @@
  * @return true if the given array is valid, otherwise false
  * @stable ICU 2.4
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 uset_getSerializedSet(USerializedSet* fillSet, const uint16_t* src, int32_t srcLength);
 
 /**
@@ -1080,18 +1091,18 @@
  * @param c The codepoint to set
  * @stable ICU 2.4
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 uset_setSerializedToOne(USerializedSet* fillSet, UChar32 c);
 
 /**
- * Returns TRUE if the given USerializedSet contains the given
+ * Returns true if the given USerializedSet contains the given
  * character.
  * @param set the serialized set
  * @param c The codepoint to check for within the set
  * @return true if set contains c
  * @stable ICU 2.4
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 uset_serializedContains(const USerializedSet* set, UChar32 c);
 
 /**
@@ -1103,7 +1114,7 @@
  * contained in set
  * @stable ICU 2.4
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 uset_getSerializedRangeCount(const USerializedSet* set);
 
 /**
@@ -1119,7 +1130,7 @@
  * @return true if rangeIndex is valid, otherwise false
  * @stable ICU 2.4
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 uset_getSerializedRange(const USerializedSet* set, int32_t rangeIndex,
                         UChar32* pStart, UChar32* pEnd);
 
diff --git a/src/third_party/icu/source/common/unicode/usetiter.h b/src/third_party/icu/source/common/unicode/usetiter.h
index bf927b0..a817ef7 100644
--- a/src/third_party/icu/source/common/unicode/usetiter.h
+++ b/src/third_party/icu/source/common/unicode/usetiter.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
 * Copyright (c) 2002-2014, International Business Machines
@@ -8,6 +10,9 @@
 #define USETITER_H
 
 #include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
 #include "unicode/uobject.h"
 #include "unicode/unistr.h"
 
@@ -171,7 +176,7 @@
      * If there are no more elements in the set, return false.
      *
      * <p>
-     * If <tt>isString() == TRUE</tt>, the value is a
+     * If <tt>isString() == true</tt>, the value is a
      * string, otherwise the value is a
      * single code point.  Elements of either type can be retrieved
      * with the function <tt>getString()</tt>, while elements of
@@ -192,7 +197,7 @@
     /**
      * Returns the next element in the set, either a code point range
      * or a string.  If there are no more elements in the set, return
-     * false.  If <tt>isString() == TRUE</tt>, the value is a
+     * false.  If <tt>isString() == true</tt>, the value is a
      * string and can be accessed with <tt>getString()</tt>.  Otherwise the value is a
      * range of one or more code points from <tt>getCodepoint()</tt> to
      * <tt>getCodepointeEnd()</tt> inclusive.
@@ -200,7 +205,7 @@
      * <p>The order of iteration is all code points ranges in sorted
      * order, followed by all strings sorted order.  Ranges are
      * disjoint and non-contiguous.  The value returned from <tt>getString()</tt>
-     * is undefined unless <tt>isString() == TRUE</tt>.  Do not mix calls to
+     * is undefined unless <tt>isString() == true</tt>.  Do not mix calls to
      * <tt>next()</tt> and <tt>nextRange()</tt> without calling
      * <tt>reset()</tt> between them.  The results of doing so are
      * undefined.
@@ -315,4 +320,6 @@
 
 U_NAMESPACE_END
 
+#endif /* U_SHOW_CPLUSPLUS_API */
+
 #endif
diff --git a/src/third_party/icu/source/common/unicode/ushape.h b/src/third_party/icu/source/common/unicode/ushape.h
index 9fb5ab4..fed4869 100644
--- a/src/third_party/icu/source/common/unicode/ushape.h
+++ b/src/third_party/icu/source/common/unicode/ushape.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 ******************************************************************************
 *   file name:  ushape.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -91,12 +93,12 @@
  *        which must not indicate a failure before the function call.
  *
  * @return The number of UChars written to the destination buffer.
- *         If an error occured, then no output was written, or it may be
+ *         If an error occurred, then no output was written, or it may be
  *         incomplete. If <code>U_BUFFER_OVERFLOW_ERROR</code> is set, then
  *         the return value indicates the necessary destination buffer size.
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 u_shapeArabic(const UChar *source, int32_t sourceLength,
               UChar *dest, int32_t destSize,
               uint32_t options,
diff --git a/src/third_party/icu/source/common/unicode/usprep.h b/src/third_party/icu/source/common/unicode/usprep.h
index 638c32e..f8a0f58 100644
--- a/src/third_party/icu/source/common/unicode/usprep.h
+++ b/src/third_party/icu/source/common/unicode/usprep.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
  *******************************************************************************
  *
@@ -6,7 +8,7 @@
  *
  *******************************************************************************
  *   file name:  usprep.h
- *   encoding:   US-ASCII
+ *   encoding:   UTF-8
  *   tab size:   8 (not used)
  *   indentation:4
  *
@@ -23,7 +25,10 @@
  */
 
 #include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
 #include "unicode/localpointer.h"
+#endif   // U_SHOW_CPLUSPLUS_API
 
 /**
  *
@@ -31,14 +36,14 @@
  * StringPrep prepares Unicode strings for use in network protocols.
  * Profiles of StingPrep are set of rules and data according to with the
  * Unicode Strings are prepared. Each profiles contains tables which describe
- * how a code point should be treated. The tables are broadly classied into
+ * how a code point should be treated. The tables are broadly classified into
  * <ul>
- *     <li> Unassinged Table: Contains code points that are unassigned 
+ *     <li> Unassigned Table: Contains code points that are unassigned 
  *          in the Unicode Version supported by StringPrep. Currently 
  *          RFC 3454 supports Unicode 3.2. </li>
- *     <li> Prohibited Table: Contains code points that are prohibted from
+ *     <li> Prohibited Table: Contains code points that are prohibited from
  *          the output of the StringPrep processing function. </li>
- *     <li> Mapping Table: Contains code ponts that are deleted from the output or case mapped. </li>
+ *     <li> Mapping Table: Contains code points that are deleted from the output or case mapped. </li>
  * </ul>
  * 
  * The procedure for preparing Unicode strings:
@@ -179,7 +184,7 @@
  * @see usprep_close()
  * @stable ICU 2.8
  */
-U_STABLE UStringPrepProfile* U_EXPORT2
+U_CAPI UStringPrepProfile* U_EXPORT2
 usprep_open(const char* path, 
             const char* fileName,
             UErrorCode* status);
@@ -195,7 +200,7 @@
  * @see usprep_close()
  * @stable ICU 4.2
  */
-U_STABLE UStringPrepProfile* U_EXPORT2
+U_CAPI UStringPrepProfile* U_EXPORT2
 usprep_openByType(UStringPrepProfileType type,
 				  UErrorCode* status);
 
@@ -204,7 +209,7 @@
  * @param profile The profile to close
  * @stable ICU 2.8
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 usprep_close(UStringPrepProfile* profile);
 
 #if U_SHOW_CPLUSPLUS_API
@@ -228,7 +233,7 @@
 
 /**
  * Prepare the input buffer for use in applications with the given profile. This operation maps, normalizes(NFKC),
- * checks for prohited and BiDi characters in the order defined by RFC 3454
+ * checks for prohibited and BiDi characters in the order defined by RFC 3454
  * depending on the options specified in the profile.
  *
  * @param prep          The profile to use 
@@ -255,7 +260,7 @@
  * @stable ICU 2.8
  */
 
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 usprep_prepare(   const UStringPrepProfile* prep,
                   const UChar* src, int32_t srcLength, 
                   UChar* dest, int32_t destCapacity,
diff --git a/src/third_party/icu/source/common/unicode/ustring.h b/src/third_party/icu/source/common/unicode/ustring.h
index 6d141e8..10ea45e 100644
--- a/src/third_party/icu/source/common/unicode/ustring.h
+++ b/src/third_party/icu/source/common/unicode/ustring.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
 *   Copyright (C) 1998-2014, International Business Machines
@@ -87,7 +89,7 @@
  * @return The number of UChars in <code>chars</code>, minus the terminator.
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 u_strlen(const UChar *s);
 /*@}*/
 
@@ -104,7 +106,7 @@
  * @return The number of code points in the specified code units.
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 u_countChar32(const UChar *s, int32_t length);
 
 /**
@@ -125,7 +127,7 @@
  *         than 'number'. Same as (u_countChar32(s, length)>number).
  * @stable ICU 2.4
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 u_strHasMoreChar32Than(const UChar *s, int32_t length, int32_t number);
 
 /**
@@ -138,7 +140,7 @@
  * @return A pointer to <code>dst</code>.
  * @stable ICU 2.0
  */
-U_STABLE UChar* U_EXPORT2
+U_CAPI UChar* U_EXPORT2
 u_strcat(UChar     *dst, 
     const UChar     *src);
 
@@ -156,7 +158,7 @@
  * @return A pointer to <code>dst</code>.
  * @stable ICU 2.0
  */
-U_STABLE UChar* U_EXPORT2
+U_CAPI UChar* U_EXPORT2
 u_strncat(UChar     *dst, 
      const UChar     *src, 
      int32_t     n);
@@ -181,7 +183,7 @@
  * @see u_strFindFirst
  * @see u_strFindLast
  */
-U_STABLE UChar * U_EXPORT2
+U_CAPI UChar * U_EXPORT2
 u_strstr(const UChar *s, const UChar *substring);
 
 /**
@@ -205,7 +207,7 @@
  * @see u_strstr
  * @see u_strFindLast
  */
-U_STABLE UChar * U_EXPORT2
+U_CAPI UChar * U_EXPORT2
 u_strFindFirst(const UChar *s, int32_t length, const UChar *substring, int32_t subLength);
 
 /**
@@ -225,7 +227,7 @@
  * @see u_strstr
  * @see u_strFindFirst
  */
-U_STABLE UChar * U_EXPORT2
+U_CAPI UChar * U_EXPORT2
 u_strchr(const UChar *s, UChar c);
 
 /**
@@ -245,7 +247,7 @@
  * @see u_strstr
  * @see u_strFindFirst
  */
-U_STABLE UChar * U_EXPORT2
+U_CAPI UChar * U_EXPORT2
 u_strchr32(const UChar *s, UChar32 c);
 
 /**
@@ -268,7 +270,7 @@
  * @see u_strFindFirst
  * @see u_strFindLast
  */
-U_STABLE UChar * U_EXPORT2
+U_CAPI UChar * U_EXPORT2
 u_strrstr(const UChar *s, const UChar *substring);
 
 /**
@@ -292,7 +294,7 @@
  * @see u_strstr
  * @see u_strFindLast
  */
-U_STABLE UChar * U_EXPORT2
+U_CAPI UChar * U_EXPORT2
 u_strFindLast(const UChar *s, int32_t length, const UChar *substring, int32_t subLength);
 
 /**
@@ -312,7 +314,7 @@
  * @see u_strrstr
  * @see u_strFindLast
  */
-U_STABLE UChar * U_EXPORT2
+U_CAPI UChar * U_EXPORT2
 u_strrchr(const UChar *s, UChar c);
 
 /**
@@ -332,7 +334,7 @@
  * @see u_strrstr
  * @see u_strFindLast
  */
-U_STABLE UChar * U_EXPORT2
+U_CAPI UChar * U_EXPORT2
 u_strrchr32(const UChar *s, UChar32 c);
 
 /**
@@ -347,7 +349,7 @@
  *         characters in <code>matchSet</code>, or NULL if no such character is found.
  * @stable ICU 2.0
  */
-U_STABLE UChar * U_EXPORT2
+U_CAPI UChar * U_EXPORT2
 u_strpbrk(const UChar *string, const UChar *matchSet);
 
 /**
@@ -363,7 +365,7 @@
  * @see u_strspn
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 u_strcspn(const UChar *string, const UChar *matchSet);
 
 /**
@@ -379,7 +381,7 @@
  * @see u_strcspn
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 u_strspn(const UChar *string, const UChar *matchSet);
 
 /**
@@ -401,13 +403,13 @@
  * @param saveState The current pointer within the original string,
  *              which is set by this function. The saveState
  *              parameter should the address of a local variable of type
- *              UChar *. (i.e. defined "Uhar *myLocalSaveState" and use
+ *              UChar *. (i.e. defined "UChar *myLocalSaveState" and use
  *              &myLocalSaveState for this parameter).
  * @return A pointer to the next token found in src, or NULL
  *         when there are no more tokens.
  * @stable ICU 2.0
  */
-U_STABLE UChar * U_EXPORT2
+U_CAPI UChar * U_EXPORT2
 u_strtok_r(UChar    *src, 
      const UChar    *delim,
            UChar   **saveState);
@@ -422,7 +424,7 @@
  * value if <code>s1</code> is bitwise greater than <code>s2</code>.
  * @stable ICU 2.0
  */
-U_STABLE int32_t  U_EXPORT2
+U_CAPI int32_t  U_EXPORT2
 u_strcmp(const UChar     *s1, 
          const UChar     *s2);
 
@@ -437,7 +439,7 @@
  * in code point order
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 u_strcmpCodePointOrder(const UChar *s1, const UChar *s2);
 
 /**
@@ -460,14 +462,14 @@
  * @param s2 Second source string.
  * @param length2 Length of second source string, or -1 if NUL-terminated.
  *
- * @param codePointOrder Choose between code unit order (FALSE)
- *                       and code point order (TRUE).
+ * @param codePointOrder Choose between code unit order (false)
+ *                       and code point order (true).
  *
  * @return <0 or 0 or >0 as usual for string comparisons
  *
  * @stable ICU 2.2
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 u_strCompare(const UChar *s1, int32_t length1,
              const UChar *s2, int32_t length2,
              UBool codePointOrder);
@@ -483,8 +485,8 @@
  *
  * @param iter1 First source string iterator.
  * @param iter2 Second source string iterator.
- * @param codePointOrder Choose between code unit order (FALSE)
- *                       and code point order (TRUE).
+ * @param codePointOrder Choose between code unit order (false)
+ *                       and code point order (true).
  *
  * @return <0 or 0 or >0 as usual for string comparisons
  *
@@ -492,19 +494,9 @@
  *
  * @stable ICU 2.6
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 u_strCompareIter(UCharIterator *iter1, UCharIterator *iter2, UBool codePointOrder);
 
-#ifndef U_COMPARE_CODE_POINT_ORDER
-/* see also unistr.h and unorm.h */
-/**
- * Option bit for u_strCaseCompare, u_strcasecmp, unorm_compare, etc:
- * Compare strings in code point order instead of code unit order.
- * @stable ICU 2.2
- */
-#define U_COMPARE_CODE_POINT_ORDER  0x8000
-#endif
-
 /**
  * Compare two strings case-insensitively using full case folding.
  * This is equivalent to
@@ -545,7 +537,7 @@
  *
  * @stable ICU 2.2
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 u_strCaseCompare(const UChar *s1, int32_t length1,
                  const UChar *s2, int32_t length2,
                  uint32_t options,
@@ -563,7 +555,7 @@
  * value if <code>s1</code> is bitwise greater than <code>s2</code>.
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 u_strncmp(const UChar     *ucs1, 
      const UChar     *ucs2, 
      int32_t     n);
@@ -581,7 +573,7 @@
  * in code point order
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 u_strncmpCodePointOrder(const UChar *s1, const UChar *s2, int32_t n);
 
 /**
@@ -603,7 +595,7 @@
  * @return A negative, zero, or positive integer indicating the comparison result.
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 u_strcasecmp(const UChar *s1, const UChar *s2, uint32_t options);
 
 /**
@@ -627,7 +619,7 @@
  * @return A negative, zero, or positive integer indicating the comparison result.
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 u_strncasecmp(const UChar *s1, const UChar *s2, int32_t n, uint32_t options);
 
 /**
@@ -651,7 +643,7 @@
  * @return A negative, zero, or positive integer indicating the comparison result.
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 u_memcasecmp(const UChar *s1, const UChar *s2, int32_t length, uint32_t options);
 
 /**
@@ -662,7 +654,7 @@
  * @return A pointer to <code>dst</code>.
  * @stable ICU 2.0
  */
-U_STABLE UChar* U_EXPORT2
+U_CAPI UChar* U_EXPORT2
 u_strcpy(UChar     *dst, 
     const UChar     *src);
 
@@ -677,7 +669,7 @@
  * @return A pointer to <code>dst</code>.
  * @stable ICU 2.0
  */
-U_STABLE UChar* U_EXPORT2
+U_CAPI UChar* U_EXPORT2
 u_strncpy(UChar     *dst, 
      const UChar     *src, 
      int32_t     n);
@@ -694,7 +686,7 @@
  * @return A pointer to <code>dst</code>.
  * @stable ICU 2.0
  */
-U_STABLE UChar* U_EXPORT2 u_uastrcpy(UChar *dst,
+U_CAPI UChar* U_EXPORT2 u_uastrcpy(UChar *dst,
                const char *src );
 
 /**
@@ -709,7 +701,7 @@
  * @return A pointer to <code>dst</code>.
  * @stable ICU 2.0
  */
-U_STABLE UChar* U_EXPORT2 u_uastrncpy(UChar *dst,
+U_CAPI UChar* U_EXPORT2 u_uastrncpy(UChar *dst,
             const char *src,
             int32_t n);
 
@@ -723,7 +715,7 @@
  * @return A pointer to <code>dst</code>.
  * @stable ICU 2.0
  */
-U_STABLE char* U_EXPORT2 u_austrcpy(char *dst,
+U_CAPI char* U_EXPORT2 u_austrcpy(char *dst,
             const UChar *src );
 
 /**
@@ -738,7 +730,7 @@
  * @return A pointer to <code>dst</code>.
  * @stable ICU 2.0
  */
-U_STABLE char* U_EXPORT2 u_austrncpy(char *dst,
+U_CAPI char* U_EXPORT2 u_austrncpy(char *dst,
             const UChar *src,
             int32_t n );
 
@@ -752,7 +744,7 @@
  * @return A pointer to <code>dest</code>
  * @stable ICU 2.0
  */
-U_STABLE UChar* U_EXPORT2
+U_CAPI UChar* U_EXPORT2
 u_memcpy(UChar *dest, const UChar *src, int32_t count);
 
 /**
@@ -763,7 +755,7 @@
  * @return A pointer to <code>dest</code>
  * @stable ICU 2.0
  */
-U_STABLE UChar* U_EXPORT2
+U_CAPI UChar* U_EXPORT2
 u_memmove(UChar *dest, const UChar *src, int32_t count);
 
 /**
@@ -775,7 +767,7 @@
  * @return A pointer to <code>dest</code>.
  * @stable ICU 2.0
  */
-U_STABLE UChar* U_EXPORT2
+U_CAPI UChar* U_EXPORT2
 u_memset(UChar *dest, UChar c, int32_t count);
 
 /**
@@ -789,7 +781,7 @@
  *      When buf1 > buf2, a positive number is returned.
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 u_memcmp(const UChar *buf1, const UChar *buf2, int32_t count);
 
 /**
@@ -805,7 +797,7 @@
  * in code point order
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 u_memcmpCodePointOrder(const UChar *s1, const UChar *s2, int32_t count);
 
 /**
@@ -825,7 +817,7 @@
  * @see u_memchr32
  * @see u_strFindFirst
  */
-U_STABLE UChar* U_EXPORT2
+U_CAPI UChar* U_EXPORT2
 u_memchr(const UChar *s, UChar c, int32_t count);
 
 /**
@@ -845,7 +837,7 @@
  * @see u_memchr
  * @see u_strFindFirst
  */
-U_STABLE UChar* U_EXPORT2
+U_CAPI UChar* U_EXPORT2
 u_memchr32(const UChar *s, UChar32 c, int32_t count);
 
 /**
@@ -865,7 +857,7 @@
  * @see u_memrchr32
  * @see u_strFindLast
  */
-U_STABLE UChar* U_EXPORT2
+U_CAPI UChar* U_EXPORT2
 u_memrchr(const UChar *s, UChar c, int32_t count);
 
 /**
@@ -885,14 +877,14 @@
  * @see u_memrchr
  * @see u_strFindLast
  */
-U_STABLE UChar* U_EXPORT2
+U_CAPI UChar* U_EXPORT2
 u_memrchr32(const UChar *s, UChar32 c, int32_t count);
 
 /**
  * Unicode String literals in C.
  * We need one macro to declare a variable for the string
  * and to statically preinitialize it if possible,
- * and a second macro to dynamically intialize such a string variable if necessary.
+ * and a second macro to dynamically initialize such a string variable if necessary.
  *
  * The macros are defined for maximum performance.
  * They work only for strings that contain "invariant characters", i.e.,
@@ -903,35 +895,32 @@
  * parameters.
  * The string parameter must be a C string literal.
  * The length of the string, not including the terminating
- * <code>NUL</code>, must be specified as a constant.
+ * `NUL`, must be specified as a constant.
  * The U_STRING_DECL macro should be invoked exactly once for one
  * such string variable before it is used.
  *
  * Usage:
- * <pre>
- *    U_STRING_DECL(ustringVar1, "Quick-Fox 2", 11);
- *    U_STRING_DECL(ustringVar2, "jumps 5%", 8);
- *    static UBool didInit=FALSE;
+ *
+ *     U_STRING_DECL(ustringVar1, "Quick-Fox 2", 11);
+ *     U_STRING_DECL(ustringVar2, "jumps 5%", 8);
+ *     static UBool didInit=false;
+ *
+ *     int32_t function() {
+ *         if(!didInit) {
+ *             U_STRING_INIT(ustringVar1, "Quick-Fox 2", 11);
+ *             U_STRING_INIT(ustringVar2, "jumps 5%", 8);
+ *             didInit=true;
+ *         }
+ *         return u_strcmp(ustringVar1, ustringVar2);
+ *     }
  * 
- *    int32_t function() {
- *        if(!didInit) {
- *            U_STRING_INIT(ustringVar1, "Quick-Fox 2", 11);
- *            U_STRING_INIT(ustringVar2, "jumps 5%", 8);
- *            didInit=TRUE;
- *        }
- *        return u_strcmp(ustringVar1, ustringVar2);
- *    }
- * </pre>
+ * Note that the macros will NOT consistently work if their argument is another #`define`.
+ * The following will not work on all platforms, don't use it.
  * 
- * Note that the macros will NOT consistently work if their argument is another <code>#define</code>. 
- *  The following will not work on all platforms, don't use it.
- * 
- * <pre>
  *     #define GLUCK "Mr. Gluck"
  *     U_STRING_DECL(var, GLUCK, 9)
  *     U_STRING_INIT(var, GLUCK, 9)
- * </pre>
- * 
+ *
  * Instead, use the string literal "Mr. Gluck"  as the argument to both macro
  * calls.
  *
@@ -1003,7 +992,7 @@
  * @see UnicodeString#unescapeAt()
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 u_unescape(const char *src,
            UChar *dest, int32_t destCapacity);
 
@@ -1051,7 +1040,7 @@
  * @see UnicodeString#unescapeAt()
  * @stable ICU 2.0
  */
-U_STABLE UChar32 U_EXPORT2
+U_CAPI UChar32 U_EXPORT2
 u_unescapeAt(UNESCAPE_CHAR_AT charAt,
              int32_t *offset,
              int32_t length,
@@ -1077,7 +1066,7 @@
  *         only some of the result was written to the destination buffer.
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 u_strToUpper(UChar *dest, int32_t destCapacity,
              const UChar *src, int32_t srcLength,
              const char *locale,
@@ -1103,7 +1092,7 @@
  *         only some of the result was written to the destination buffer.
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 u_strToLower(UChar *dest, int32_t destCapacity,
              const UChar *src, int32_t srcLength,
              const char *locale,
@@ -1149,7 +1138,7 @@
  *         only some of the result was written to the destination buffer.
  * @stable ICU 2.1
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 u_strToTitle(UChar *dest, int32_t destCapacity,
              const UChar *src, int32_t srcLength,
              UBreakIterator *titleIter,
@@ -1182,7 +1171,7 @@
  *         only some of the result was written to the destination buffer.
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 u_strFoldCase(UChar *dest, int32_t destCapacity,
               const UChar *src, int32_t srcLength,
               uint32_t options,
@@ -1211,7 +1200,7 @@
  * @return The pointer to destination buffer.
  * @stable ICU 2.0
  */
-U_STABLE wchar_t* U_EXPORT2
+U_CAPI wchar_t* U_EXPORT2
 u_strToWCS(wchar_t *dest, 
            int32_t destCapacity,
            int32_t *pDestLength,
@@ -1240,7 +1229,7 @@
  * @return The pointer to destination buffer.
  * @stable ICU 2.0
  */
-U_STABLE UChar* U_EXPORT2
+U_CAPI UChar* U_EXPORT2
 u_strFromWCS(UChar   *dest,
              int32_t destCapacity, 
              int32_t *pDestLength,
@@ -1271,7 +1260,7 @@
  * @see u_strToUTF8WithSub
  * @see u_strFromUTF8
  */
-U_STABLE char* U_EXPORT2 
+U_CAPI char* U_EXPORT2 
 u_strToUTF8(char *dest,           
             int32_t destCapacity,
             int32_t *pDestLength,
@@ -1301,7 +1290,7 @@
  * @see u_strFromUTF8WithSub
  * @see u_strFromUTF8Lenient
  */
-U_STABLE UChar* U_EXPORT2
+U_CAPI UChar* U_EXPORT2
 u_strFromUTF8(UChar *dest,             
               int32_t destCapacity,
               int32_t *pDestLength,
@@ -1344,7 +1333,7 @@
  * @see u_strFromUTF8WithSub
  * @stable ICU 3.6
  */
-U_STABLE char* U_EXPORT2
+U_CAPI char* U_EXPORT2
 u_strToUTF8WithSub(char *dest,
             int32_t destCapacity,
             int32_t *pDestLength,
@@ -1389,7 +1378,7 @@
  * @see u_strToUTF8WithSub
  * @stable ICU 3.6
  */
-U_STABLE UChar* U_EXPORT2
+U_CAPI UChar* U_EXPORT2
 u_strFromUTF8WithSub(UChar *dest,
               int32_t destCapacity,
               int32_t *pDestLength,
@@ -1449,7 +1438,7 @@
  * @see u_strToUTF8WithSub
  * @stable ICU 3.6
  */
-U_STABLE UChar * U_EXPORT2
+U_CAPI UChar * U_EXPORT2
 u_strFromUTF8Lenient(UChar *dest,
                      int32_t destCapacity,
                      int32_t *pDestLength,
@@ -1479,7 +1468,7 @@
  * @see u_strFromUTF32
  * @stable ICU 2.0
  */
-U_STABLE UChar32* U_EXPORT2 
+U_CAPI UChar32* U_EXPORT2 
 u_strToUTF32(UChar32 *dest, 
              int32_t  destCapacity,
              int32_t  *pDestLength,
@@ -1509,7 +1498,7 @@
  * @see u_strToUTF32
  * @stable ICU 2.0
  */
-U_STABLE UChar* U_EXPORT2 
+U_CAPI UChar* U_EXPORT2 
 u_strFromUTF32(UChar   *dest,
                int32_t destCapacity, 
                int32_t *pDestLength,
@@ -1552,7 +1541,7 @@
  * @see u_strFromUTF32WithSub
  * @stable ICU 4.2
  */
-U_STABLE UChar32* U_EXPORT2
+U_CAPI UChar32* U_EXPORT2
 u_strToUTF32WithSub(UChar32 *dest,
              int32_t destCapacity,
              int32_t *pDestLength,
@@ -1596,7 +1585,7 @@
  * @see u_strToUTF32WithSub
  * @stable ICU 4.2
  */
-U_STABLE UChar* U_EXPORT2
+U_CAPI UChar* U_EXPORT2
 u_strFromUTF32WithSub(UChar *dest,
                int32_t destCapacity,
                int32_t *pDestLength,
@@ -1637,7 +1626,7 @@
  * @see u_strToUTF8WithSub
  * @see u_strFromJavaModifiedUTF8WithSub
  */
-U_STABLE char* U_EXPORT2 
+U_CAPI char* U_EXPORT2 
 u_strToJavaModifiedUTF8(
         char *dest,
         int32_t destCapacity,
@@ -1687,7 +1676,7 @@
  * @see u_strToJavaModifiedUTF8
  * @stable ICU 4.4
  */
-U_STABLE UChar* U_EXPORT2
+U_CAPI UChar* U_EXPORT2
 u_strFromJavaModifiedUTF8WithSub(
         UChar *dest,
         int32_t destCapacity,
diff --git a/src/third_party/icu/source/common/unicode/ustringtrie.h b/src/third_party/icu/source/common/unicode/ustringtrie.h
index 871d0f8..fd85648 100644
--- a/src/third_party/icu/source/common/unicode/ustringtrie.h
+++ b/src/third_party/icu/source/common/unicode/ustringtrie.h
@@ -1,10 +1,12 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *   Copyright (C) 2010-2012, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *******************************************************************************
 *   file name:  udicttrie.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
diff --git a/src/third_party/icu/source/common/unicode/utext.h b/src/third_party/icu/source/common/unicode/utext.h
index d431913..c6d1e53 100644
--- a/src/third_party/icu/source/common/unicode/utext.h
+++ b/src/third_party/icu/source/common/unicode/utext.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  utext.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -178,28 +180,9 @@
   *
   * @stable ICU 3.4
   */
-U_STABLE UText * U_EXPORT2
+U_CAPI UText * U_EXPORT2
 utext_close(UText *ut);
 
-#if U_SHOW_CPLUSPLUS_API
-
-U_NAMESPACE_BEGIN
-
-/**
- * \class LocalUTextPointer
- * "Smart pointer" class, closes a UText via utext_close().
- * For most methods see the LocalPointerBase base class.
- *
- * @see LocalPointerBase
- * @see LocalPointer
- * @stable ICU 4.4
- */
-U_DEFINE_LOCAL_OPEN_POINTER(LocalUTextPointer, UText, utext_close);
-
-U_NAMESPACE_END
-
-#endif
-
 /**
  * Open a read-only UText implementation for UTF-8 strings.
  * 
@@ -221,7 +204,7 @@
  *               will always be used and returned.
  * @stable ICU 3.4
  */
-U_STABLE UText * U_EXPORT2
+U_CAPI UText * U_EXPORT2
 utext_openUTF8(UText *ut, const char *s, int64_t length, UErrorCode *status);
 
 
@@ -239,7 +222,7 @@
  *               will always be used and returned.
  * @stable ICU 3.4
  */
-U_STABLE UText * U_EXPORT2
+U_CAPI UText * U_EXPORT2
 utext_openUChars(UText *ut, const UChar *s, int64_t length, UErrorCode *status);
 
 
@@ -256,7 +239,7 @@
  *                 will always be used and returned.
  * @stable ICU 3.4
  */
-U_STABLE UText * U_EXPORT2
+U_CAPI UText * U_EXPORT2
 utext_openUnicodeString(UText *ut, icu::UnicodeString *s, UErrorCode *status);
 
 
@@ -272,7 +255,7 @@
  *               will always be used and returned.
  * @stable ICU 3.4
  */
-U_STABLE UText * U_EXPORT2
+U_CAPI UText * U_EXPORT2
 utext_openConstUnicodeString(UText *ut, const icu::UnicodeString *s, UErrorCode *status);
 
 
@@ -288,7 +271,7 @@
  * @see Replaceable
  * @stable ICU 3.4
  */
-U_STABLE UText * U_EXPORT2
+U_CAPI UText * U_EXPORT2
 utext_openReplaceable(UText *ut, icu::Replaceable *rep, UErrorCode *status);
 
 /**
@@ -303,7 +286,7 @@
  * @see Replaceable
  * @stable ICU 3.4
  */
-U_STABLE UText * U_EXPORT2
+U_CAPI UText * U_EXPORT2
 utext_openCharacterIterator(UText *ut, icu::CharacterIterator *ci, UErrorCode *status);
 
 #endif
@@ -340,7 +323,7 @@
   *  shallow clones provide some protection against errors of this type by
   *  disabling text modification via the cloned UText.
   *
-  *  A shallow clone made with the readOnly parameter == FALSE will preserve the 
+  *  A shallow clone made with the readOnly parameter == false will preserve the 
   *  utext_isWritable() state of the source object.  Note, however, that
   *  write operations must be avoided while more than one UText exists that refer
   *  to the same underlying text.
@@ -356,8 +339,8 @@
   *                If non-NULL, must refer to an already existing UText, which will then
   *                be reset to become the clone.
   *  @param src    The UText to be cloned.
-  *  @param deep   TRUE to request a deep clone, FALSE for a shallow clone.
-  *  @param readOnly TRUE to request that the cloned UText have read only access to the 
+  *  @param deep   true to request a deep clone, false for a shallow clone.
+  *  @param readOnly true to request that the cloned UText have read only access to the 
   *                underlying text.  
 
   *  @param status Errors are returned here.  For deep clones, U_UNSUPPORTED_ERROR
@@ -366,7 +349,7 @@
   *  @return       The newly created clone, or NULL if the clone operation failed.
   *  @stable ICU 3.4
   */
-U_STABLE UText * U_EXPORT2
+U_CAPI UText * U_EXPORT2
 utext_clone(UText *dest, const UText *src, UBool deep, UBool readOnly, UErrorCode *status);
 
 
@@ -374,20 +357,20 @@
   *  Compare two UText objects for equality.
   *  UTexts are equal if they are iterating over the same text, and
   *    have the same iteration position within the text.
-  *    If either or both of the parameters are NULL, the comparison is FALSE.
+  *    If either or both of the parameters are NULL, the comparison is false.
   *
   *  @param a   The first of the two UTexts to compare.
   *  @param b   The other UText to be compared.
-  *  @return    TRUE if the two UTexts are equal.
+  *  @return    true if the two UTexts are equal.
   *  @stable ICU 3.6
   */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 utext_equals(const UText *a, const UText *b);
 
 
 /*****************************************************************************
  *
- *   Functions to work with the text represeted by a UText wrapper
+ *   Functions to work with the text represented by a UText wrapper
  *
  *****************************************************************************/
 
@@ -402,11 +385,11 @@
   *
   * @stable ICU 3.4
   */
-U_STABLE int64_t U_EXPORT2
+U_CAPI int64_t U_EXPORT2
 utext_nativeLength(UText *ut);
 
 /**
- *  Return TRUE if calculating the length of the text could be expensive.
+ *  Return true if calculating the length of the text could be expensive.
  *  Finding the length of NUL terminated strings is considered to be expensive.
  *
  *  Note that the value of this function may change
@@ -415,10 +398,10 @@
  *  be expensive to report it.
  *
  * @param ut the text to be accessed.
- * @return TRUE if determining the length of the text could be time consuming.
+ * @return true if determining the length of the text could be time consuming.
  * @stable ICU 3.4
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 utext_isLengthExpensive(const UText *ut);
 
 /**
@@ -431,7 +414,7 @@
  *
  * The iteration position will be set to the start of the returned code point.
  *
- * This function is roughly equivalent to the the sequence
+ * This function is roughly equivalent to the sequence
  *    utext_setNativeIndex(index);
  *    utext_current32();
  * (There is a subtle difference if the index is out of bounds by being less than zero - 
@@ -446,7 +429,7 @@
  * @return the code point at the specified index.
  * @stable ICU 3.4
  */
-U_STABLE UChar32 U_EXPORT2
+U_CAPI UChar32 U_EXPORT2
 utext_char32At(UText *ut, int64_t nativeIndex);
 
 
@@ -460,7 +443,7 @@
  * @return the Unicode code point at the current iterator position.
  * @stable ICU 3.4
  */
-U_STABLE UChar32 U_EXPORT2
+U_CAPI UChar32 U_EXPORT2
 utext_current32(UText *ut);
 
 
@@ -482,7 +465,7 @@
  * @see UTEXT_NEXT32
  * @stable ICU 3.4
  */
-U_STABLE UChar32 U_EXPORT2
+U_CAPI UChar32 U_EXPORT2
 utext_next32(UText *ut);
 
 
@@ -503,7 +486,7 @@
  *  @see UTEXT_PREVIOUS32
  *  @stable ICU 3.4
  */
-U_STABLE UChar32 U_EXPORT2
+U_CAPI UChar32 U_EXPORT2
 utext_previous32(UText *ut);
 
 
@@ -525,7 +508,7 @@
   *         or U_SENTINEL (-1) if it is out of bounds.
   * @stable ICU 3.4
   */
-U_STABLE UChar32 U_EXPORT2
+U_CAPI UChar32 U_EXPORT2
 utext_next32From(UText *ut, int64_t nativeIndex);
 
 
@@ -545,7 +528,7 @@
   *
   * @stable ICU 3.4
   */
-U_STABLE UChar32 U_EXPORT2
+U_CAPI UChar32 U_EXPORT2
 utext_previous32From(UText *ut, int64_t nativeIndex);
 
 /**
@@ -560,7 +543,7 @@
   * @return the current index position, in the native units of the text provider.
   * @stable ICU 3.4
   */
-U_STABLE int64_t U_EXPORT2
+U_CAPI int64_t U_EXPORT2
 utext_getNativeIndex(const UText *ut);
 
 /**
@@ -586,11 +569,11 @@
  * @param nativeIndex the native unit index of the new iteration position.
  * @stable ICU 3.4
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 utext_setNativeIndex(UText *ut, int64_t nativeIndex);
 
 /**
- * Move the iterator postion by delta code points.  The number of code points
+ * Move the iterator position by delta code points.  The number of code points
  * is a signed number; a negative delta will move the iterator backwards,
  * towards the start of the text.
  * <p>
@@ -601,15 +584,15 @@
  *
  * @param ut the text to be accessed.
  * @param delta the signed number of code points to move the iteration position.
- * @return TRUE if the position could be moved the requested number of positions while
+ * @return true if the position could be moved the requested number of positions while
  *              staying within the range [0 - text length].
  * @stable ICU 3.4
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 utext_moveIndex32(UText *ut, int32_t delta);
 
 /**
- * Get the native index of the character preceeding the current position.
+ * Get the native index of the character preceding the current position.
  * If the iteration position is already at the start of the text, zero
  * is returned.
  * The value returned is the same as that obtained from the following sequence,
@@ -626,11 +609,11 @@
  *   native index of the character most recently returned from utext_next().
  *
  * @param ut the text to be accessed
- * @return the native index of the character preceeding the current index position,
+ * @return the native index of the character preceding the current index position,
  *         or zero if the current position is at the start of the text.
  * @stable ICU 3.6
  */
-U_STABLE int64_t U_EXPORT2
+U_CAPI int64_t U_EXPORT2
 utext_getPreviousNativeIndex(UText *ut); 
 
 
@@ -653,10 +636,10 @@
  * @param  ut    the UText from which to extract data.
  * @param  nativeStart the native index of the first character to extract.\
  *               If the specified index is out of range,
- *               it will be pinned to to be within 0 <= index <= textLength
+ *               it will be pinned to be within 0 <= index <= textLength
  * @param  nativeLimit the native string index of the position following the last
  *               character to extract.  If the specified index is out of range,
- *               it will be pinned to to be within 0 <= index <= textLength.
+ *               it will be pinned to be within 0 <= index <= textLength.
  *               nativeLimit must be >= nativeStart.
  * @param  dest  the UChar (UTF-16) buffer into which the extracted text is placed
  * @param  destCapacity  The size, in UChars, of the destination buffer.  May be zero
@@ -668,7 +651,7 @@
  *
  * @stable ICU 3.4
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 utext_extract(UText *ut,
              int64_t nativeStart, int64_t nativeLimit,
              UChar *dest, int32_t destCapacity,
@@ -764,12 +747,14 @@
   *
   * @stable ICU 3.8
   */
-#define UTEXT_SETNATIVEINDEX(ut, ix)                       \
-    { int64_t __offset = (ix) - (ut)->chunkNativeStart; \
-      if (__offset>=0 && __offset<=(int64_t)(ut)->nativeIndexingLimit) { \
-          (ut)->chunkOffset=(int32_t)__offset; \
-      } else { \
-          utext_setNativeIndex((ut), (ix)); } }
+#define UTEXT_SETNATIVEINDEX(ut, ix) UPRV_BLOCK_MACRO_BEGIN { \
+    int64_t __offset = (ix) - (ut)->chunkNativeStart; \
+    if (__offset>=0 && __offset<(int64_t)(ut)->nativeIndexingLimit && (ut)->chunkContents[__offset]<0xdc00) { \
+        (ut)->chunkOffset=(int32_t)__offset; \
+    } else { \
+        utext_setNativeIndex((ut), (ix)); \
+    } \
+} UPRV_BLOCK_MACRO_END
 
 
 
@@ -783,16 +768,16 @@
 
 
 /**
- *  Return TRUE if the text can be written (modified) with utext_replace() or
+ *  Return true if the text can be written (modified) with utext_replace() or
  *  utext_copy().  For the text to be writable, the text provider must
  *  be of a type that supports writing and the UText must not be frozen.
  *
- *  Attempting to modify text when utext_isWriteable() is FALSE will fail -
+ *  Attempting to modify text when utext_isWriteable() is false will fail -
  *  the text will not be modified, and an error will be returned from the function
  *  that attempted the modification.
  *
  * @param  ut   the UText to be tested.
- * @return TRUE if the text is modifiable.
+ * @return true if the text is modifiable.
  *
  * @see    utext_freeze()
  * @see    utext_replace()
@@ -800,7 +785,7 @@
  * @stable ICU 3.4
  *
  */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 utext_isWritable(const UText *ut);
 
 
@@ -809,10 +794,10 @@
   * @see Replaceable::hasMetaData()
   *
   * @param ut The UText to be tested
-  * @return TRUE if the underlying text includes meta data.
+  * @return true if the underlying text includes meta data.
   * @stable ICU 3.4
   */
-U_STABLE UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 utext_hasMetaData(const UText *ut);
 
 
@@ -823,7 +808,7 @@
  *  newly inserted replacement text.
  *
  * This function is only available on UText types that support writing,
- * that is, ones where utext_isWritable() returns TRUE.
+ * that is, ones where utext_isWritable() returns true.
  *
  * When using this function, there should be only a single UText opened onto the
  * underlying native text string.  Behavior after a replace operation
@@ -843,7 +828,7 @@
  *
  * @stable ICU 3.4
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 utext_replace(UText *ut,
              int64_t nativeStart, int64_t nativeLimit,
              const UChar *replacementText, int32_t replacementLength,
@@ -865,7 +850,7 @@
  * at the destination position.
  *
  * This function is only available on UText types that support writing,
- * that is, ones where utext_isWritable() returns TRUE.
+ * that is, ones where utext_isWritable() returns true.
  *
  * When using this function, there should be only a single UText opened onto the
  * underlying native text string.  Behavior after a copy operation
@@ -878,12 +863,12 @@
  *                     to be copied.
  * @param destIndex    The native destination index to which the source substring is
  *                     copied or moved.
- * @param move         If TRUE, then the substring is moved, not copied/duplicated.
+ * @param move         If true, then the substring is moved, not copied/duplicated.
  * @param status       receives any error status.  Possible errors include U_NO_WRITE_PERMISSION
  *                       
  * @stable ICU 3.4
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 utext_copy(UText *ut,
           int64_t nativeStart, int64_t nativeLimit,
           int64_t destIndex,
@@ -904,7 +889,7 @@
   *  Caution:  freezing a UText will disable changes made via the specific
   *   frozen UText wrapper only; it will not have any effect on the ability to
   *   directly modify the text by bypassing the UText.  Any such backdoor modifications
-  *   are always an error while UText access is occuring because the underlying
+  *   are always an error while UText access is occurring because the underlying
   *   text can get out of sync with UText's buffering.
   *  </p>
   *
@@ -912,7 +897,7 @@
   *  @see   utext_isWritable()
   *  @stable ICU 3.6
   */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 utext_freeze(UText *ut);
 
 
@@ -987,7 +972,7 @@
   *  @param dest   A UText struct to be filled in with the result of the clone operation,
   *                or NULL if the clone function should heap-allocate a new UText struct.
   *  @param src    The UText to be cloned.
-  *  @param deep   TRUE to request a deep clone, FALSE for a shallow clone.
+  *  @param deep   true to request a deep clone, false for a shallow clone.
   *  @param status Errors are returned here.  For deep clones, U_UNSUPPORTED_ERROR
   *                should be returned if the text provider is unable to clone the
   *                original text.
@@ -1023,9 +1008,9 @@
  *
  * @param ut          the UText being accessed.
  * @param nativeIndex Requested index of the text to be accessed.
- * @param forward     If TRUE, then the returned chunk must contain text
+ * @param forward     If true, then the returned chunk must contain text
  *                    starting from the index, so that start<=index<limit.
- *                    If FALSE, then the returned chunk must contain text
+ *                    If false, then the returned chunk must contain text
  *                    before the index, so that start<index<=limit.
  * @return            True if the requested index could be accessed.  The chunk
  *                    will contain the requested text.
@@ -1052,7 +1037,7 @@
  * be NUL-terminated if there is sufficient space in the destination buffer.
  *
  * @param  ut            the UText from which to extract data.
- * @param  nativeStart   the native index of the first characer to extract.
+ * @param  nativeStart   the native index of the first character to extract.
  * @param  nativeLimit   the native string index of the position following the last
  *                       character to extract.
  * @param  dest          the UChar (UTF-16) buffer into which the extracted text is placed
@@ -1129,7 +1114,7 @@
  * @param nativeStart  The index of the start of the region to be copied or moved
  * @param nativeLimit  The index of the character following the region to be replaced.
  * @param nativeDest   The destination index to which the source substring is copied or moved.
- * @param move         If TRUE, then the substring is moved, not copied/duplicated.
+ * @param move         If true, then the substring is moved, not copied/duplicated.
  * @param status       receives any error status.  Possible errors include U_NO_WRITE_PERMISSION
  *
  * @stable ICU 3.4
@@ -1209,7 +1194,7 @@
 struct UTextFuncs {
     /**
      *   (public)  Function table size, sizeof(UTextFuncs)
-     *             Intended for use should the table grow to accomodate added
+     *             Intended for use should the table grow to accommodate added
      *             functions in the future, to allow tests for older format
      *             function tables that do not contain the extensions.
      *
@@ -1343,7 +1328,7 @@
 struct UText {
     /**
      *     (private)  Magic.  Used to help detect when UText functions are handed
-     *                        invalid or unitialized UText structs.
+     *                        invalid or uninitialized UText structs.
      *                        utext_openXYZ() functions take an initialized,
      *                        but not necessarily open, UText struct as an
      *                        optional fill-in parameter.  This magic field
@@ -1365,7 +1350,7 @@
 
 
     /**
-      *  Text provider properties.  This set of flags is maintainted by the
+      *  Text provider properties.  This set of flags is maintained by the
       *                             text provider implementation.
       *  @stable ICU 3.4
       */
@@ -1450,7 +1435,7 @@
     void          *pExtra;
 
     /**
-     * (protected) Pointer to string or text-containin object or similar.
+     * (protected) Pointer to string or text-containing object or similar.
      * This is the source of the text that this UText is wrapping, in a format
      *  that is known to the text provider functions.
      * @stable ICU 3.4
@@ -1550,10 +1535,10 @@
  * @return pointer to the UText, allocated if necessary, with extra space set up if requested.
  * @stable ICU 3.4
  */
-U_STABLE UText * U_EXPORT2
+U_CAPI UText * U_EXPORT2
 utext_setup(UText *ut, int32_t extraSpace, UErrorCode *status);
 
-#ifndef U_HIDE_INTERNAL_API
+// do not use #ifndef U_HIDE_INTERNAL_API around the following!
 /**
   * @internal
   *  Value used to help identify correctly initialized UText structs.
@@ -1562,7 +1547,6 @@
 enum {
     UTEXT_MAGIC = 0x345ad82c
 };
-#endif  /* U_HIDE_INTERNAL_API */
 
 /**
  * initializer to be used with local (stack) instances of a UText
@@ -1596,5 +1580,24 @@
 U_CDECL_END
 
 
+#if U_SHOW_CPLUSPLUS_API
+
+U_NAMESPACE_BEGIN
+
+/**
+ * \class LocalUTextPointer
+ * "Smart pointer" class, closes a UText via utext_close().
+ * For most methods see the LocalPointerBase base class.
+ *
+ * @see LocalPointerBase
+ * @see LocalPointer
+ * @stable ICU 4.4
+ */
+U_DEFINE_LOCAL_OPEN_POINTER(LocalUTextPointer, UText, utext_close);
+
+U_NAMESPACE_END
+
+#endif
+
 
 #endif
diff --git a/src/third_party/icu/source/common/unicode/utf.h b/src/third_party/icu/source/common/unicode/utf.h
index f5954fe..c9d5f57 100644
--- a/src/third_party/icu/source/common/unicode/utf.h
+++ b/src/third_party/icu/source/common/unicode/utf.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  utf.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -21,9 +23,6 @@
  * This file defines macros for checking whether a code point is
  * a surrogate or a non-character etc.
  *
- * The UChar and UChar32 data types for Unicode code units and code points
- * are defined in umachine.h because they can be machine-dependent.
- *
  * If U_NO_DEFAULT_INCLUDE_UTF_HEADERS is 0 then utf.h is included by utypes.h
  * and itself includes utf8.h and utf16.h after some
  * common definitions.
@@ -48,11 +47,11 @@
  * but are optimized for the much more frequently occurring BMP code points.
  *
  * umachine.h defines UChar to be an unsigned 16-bit integer.
- * Where available, UChar is defined to be a char16_t
- * or a wchar_t (if that is an unsigned 16-bit type), otherwise uint16_t.
+ * Since ICU 59, ICU uses char16_t in C++, UChar only in C,
+ * and defines UChar=char16_t by default. See the UChar API docs for details.
  *
  * UChar32 is defined to be a signed 32-bit integer (int32_t), large enough for a 21-bit
- * Unicode code point (Unicode scalar value, 0..0x10ffff).
+ * Unicode code point (Unicode scalar value, 0..0x10ffff) and U_SENTINEL (-1).
  * Before ICU 2.4, the definition of UChar32 was similarly platform-dependent as
  * the definition of UChar. For details see the documentation for UChar32 itself.
  *
@@ -61,11 +60,20 @@
  * For actual Unicode character properties see uchar.h.
  *
  * By default, string operations must be done with error checking in case
- * a string is not well-formed UTF-16.
- * The macros will detect if a surrogate code unit is unpaired
+ * a string is not well-formed UTF-16 or UTF-8.
+ *
+ * The U16_ macros detect if a surrogate code unit is unpaired
  * (lead unit without trail unit or vice versa) and just return the unit itself
  * as the code point.
  *
+ * The U8_ macros detect illegal byte sequences and return a negative value.
+ * Starting with ICU 60, the observable length of a single illegal byte sequence
+ * skipped by one of these macros follows the Unicode 6+ recommendation
+ * which is consistent with the W3C Encoding Standard.
+ *
+ * There are ..._OR_FFFD versions of both U16_ and U8_ macros
+ * that return U+FFFD for illegal code unit sequences.
+ *
  * The regular "safe" macros require that the initial, passed-in string index
  * is within bounds. They only check the index when they read more than one
  * code unit. This is usually done with code similar to the following loop:
@@ -89,16 +97,13 @@
  * The performance differences are much larger here because UTF-8 provides so
  * many opportunities for malformed sequences.
  * The unsafe UTF-8 macros are entirely implemented inside the macro definitions
- * and are fast, while the safe UTF-8 macros call functions for all but the
- * trivial (ASCII) cases.
- * (ICU 3.6 optimizes U8_NEXT() and U8_APPEND() to handle most other common
- * characters inline as well.)
+ * and are fast, while the safe UTF-8 macros call functions for some complicated cases.
  *
  * Unlike with UTF-16, malformed sequences cannot be expressed with distinct
  * code point values (0..U+10ffff). They are indicated with negative values instead.
  *
  * For more information see the ICU User Guide Strings chapter
- * (http://userguide.icu-project.org/strings).
+ * (https://unicode-org.github.io/icu/userguide/strings).
  *
  * <em>Usage:</em>
  * ICU coding guidelines for if() statements should be followed when using these macros.
@@ -119,13 +124,12 @@
 /**
  * Is this code point a Unicode noncharacter?
  * @param c 32-bit code point
- * @return TRUE or FALSE
+ * @return true or false
  * @stable ICU 2.4
  */
 #define U_IS_UNICODE_NONCHAR(c) \
     ((c)>=0xfdd0 && \
-     ((uint32_t)(c)<=0xfdef || ((c)&0xfffe)==0xfffe) && \
-     (uint32_t)(c)<=0x10ffff)
+     ((c)<=0xfdef || ((c)&0xfffe)==0xfffe) && (c)<=0x10ffff)
 
 /**
  * Is c a Unicode code point value (0..U+10ffff)
@@ -141,19 +145,17 @@
  * and that boundary is tested first for performance.
  *
  * @param c 32-bit code point
- * @return TRUE or FALSE
+ * @return true or false
  * @stable ICU 2.4
  */
 #define U_IS_UNICODE_CHAR(c) \
     ((uint32_t)(c)<0xd800 || \
-        ((uint32_t)(c)>0xdfff && \
-         (uint32_t)(c)<=0x10ffff && \
-         !U_IS_UNICODE_NONCHAR(c)))
+        (0xdfff<(c) && (c)<=0x10ffff && !U_IS_UNICODE_NONCHAR(c)))
 
 /**
  * Is this code point a BMP code point (U+0000..U+ffff)?
  * @param c 32-bit code point
- * @return TRUE or FALSE
+ * @return true or false
  * @stable ICU 2.8
  */
 #define U_IS_BMP(c) ((uint32_t)(c)<=0xffff)
@@ -161,7 +163,7 @@
 /**
  * Is this code point a supplementary code point (U+10000..U+10ffff)?
  * @param c 32-bit code point
- * @return TRUE or FALSE
+ * @return true or false
  * @stable ICU 2.8
  */
 #define U_IS_SUPPLEMENTARY(c) ((uint32_t)((c)-0x10000)<=0xfffff)
@@ -169,7 +171,7 @@
 /**
  * Is this code point a lead surrogate (U+d800..U+dbff)?
  * @param c 32-bit code point
- * @return TRUE or FALSE
+ * @return true or false
  * @stable ICU 2.4
  */
 #define U_IS_LEAD(c) (((c)&0xfffffc00)==0xd800)
@@ -177,7 +179,7 @@
 /**
  * Is this code point a trail surrogate (U+dc00..U+dfff)?
  * @param c 32-bit code point
- * @return TRUE or FALSE
+ * @return true or false
  * @stable ICU 2.4
  */
 #define U_IS_TRAIL(c) (((c)&0xfffffc00)==0xdc00)
@@ -185,7 +187,7 @@
 /**
  * Is this code point a surrogate (U+d800..U+dfff)?
  * @param c 32-bit code point
- * @return TRUE or FALSE
+ * @return true or false
  * @stable ICU 2.4
  */
 #define U_IS_SURROGATE(c) (((c)&0xfffff800)==0xd800)
@@ -194,7 +196,7 @@
  * Assuming c is a surrogate code point (U_IS_SURROGATE(c)),
  * is it a lead surrogate?
  * @param c 32-bit code point
- * @return TRUE or FALSE
+ * @return true or false
  * @stable ICU 2.4
  */
 #define U_IS_SURROGATE_LEAD(c) (((c)&0x400)==0)
@@ -203,7 +205,7 @@
  * Assuming c is a surrogate code point (U_IS_SURROGATE(c)),
  * is it a trail surrogate?
  * @param c 32-bit code point
- * @return TRUE or FALSE
+ * @return true or false
  * @stable ICU 4.2
  */
 #define U_IS_SURROGATE_TRAIL(c) (((c)&0x400)!=0)
diff --git a/src/third_party/icu/source/common/unicode/utf16.h b/src/third_party/icu/source/common/unicode/utf16.h
index bdd88a8..3902c60 100644
--- a/src/third_party/icu/source/common/unicode/utf16.h
+++ b/src/third_party/icu/source/common/unicode/utf16.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  utf16.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -21,7 +23,7 @@
  * This file defines macros to deal with 16-bit Unicode (UTF-16) code units and strings.
  *
  * For more information see utf.h and the ICU User Guide Strings chapter
- * (http://userguide.icu-project.org/strings).
+ * (https://unicode-org.github.io/icu/userguide/strings).
  *
  * <em>Usage:</em>
  * ICU coding guidelines for if() statements should be followed when using these macros.
@@ -32,6 +34,7 @@
 #ifndef __UTF16_H__
 #define __UTF16_H__
 
+#include <stdbool.h>
 #include "unicode/umachine.h"
 #ifndef __UTF_H__
 #   include "unicode/utf.h"
@@ -42,7 +45,7 @@
 /**
  * Does this code unit alone encode a code point (BMP, not a surrogate)?
  * @param c 16-bit code unit
- * @return TRUE or FALSE
+ * @return true or false
  * @stable ICU 2.4
  */
 #define U16_IS_SINGLE(c) !U_IS_SURROGATE(c)
@@ -50,7 +53,7 @@
 /**
  * Is this code unit a lead surrogate (U+d800..U+dbff)?
  * @param c 16-bit code unit
- * @return TRUE or FALSE
+ * @return true or false
  * @stable ICU 2.4
  */
 #define U16_IS_LEAD(c) (((c)&0xfffffc00)==0xd800)
@@ -58,7 +61,7 @@
 /**
  * Is this code unit a trail surrogate (U+dc00..U+dfff)?
  * @param c 16-bit code unit
- * @return TRUE or FALSE
+ * @return true or false
  * @stable ICU 2.4
  */
 #define U16_IS_TRAIL(c) (((c)&0xfffffc00)==0xdc00)
@@ -66,7 +69,7 @@
 /**
  * Is this code unit a surrogate (U+d800..U+dfff)?
  * @param c 16-bit code unit
- * @return TRUE or FALSE
+ * @return true or false
  * @stable ICU 2.4
  */
 #define U16_IS_SURROGATE(c) U_IS_SURROGATE(c)
@@ -75,7 +78,7 @@
  * Assuming c is a surrogate code point (U16_IS_SURROGATE(c)),
  * is it a lead surrogate?
  * @param c 16-bit code unit
- * @return TRUE or FALSE
+ * @return true or false
  * @stable ICU 2.4
  */
 #define U16_IS_SURROGATE_LEAD(c) (((c)&0x400)==0)
@@ -84,7 +87,7 @@
  * Assuming c is a surrogate code point (U16_IS_SURROGATE(c)),
  * is it a trail surrogate?
  * @param c 16-bit code unit
- * @return TRUE or FALSE
+ * @return true or false
  * @stable ICU 4.2
  */
 #define U16_IS_SURROGATE_TRAIL(c) (((c)&0x400)!=0)
@@ -161,7 +164,7 @@
  * @see U16_GET
  * @stable ICU 2.4
  */
-#define U16_GET_UNSAFE(s, i, c) { \
+#define U16_GET_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \
     (c)=(s)[i]; \
     if(U16_IS_SURROGATE(c)) { \
         if(U16_IS_SURROGATE_LEAD(c)) { \
@@ -170,7 +173,7 @@
             (c)=U16_GET_SUPPLEMENTARY((s)[(i)-1], (c)); \
         } \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /**
  * Get a code point from a string at a random-access offset,
@@ -183,8 +186,8 @@
  *
  * The length can be negative for a NUL-terminated string.
  *
- * If the offset points to a single, unpaired surrogate, then that itself
- * will be returned as the code point.
+ * If the offset points to a single, unpaired surrogate, then
+ * c is set to that unpaired surrogate.
  * Iteration through a string is more efficient with U16_NEXT_UNSAFE or U16_NEXT.
  *
  * @param s const UChar * string
@@ -195,7 +198,7 @@
  * @see U16_GET_UNSAFE
  * @stable ICU 2.4
  */
-#define U16_GET(s, start, i, length, c) { \
+#define U16_GET(s, start, i, length, c) UPRV_BLOCK_MACRO_BEGIN { \
     (c)=(s)[i]; \
     if(U16_IS_SURROGATE(c)) { \
         uint16_t __c2; \
@@ -209,7 +212,50 @@
             } \
         } \
     } \
-}
+} UPRV_BLOCK_MACRO_END
+
+/**
+ * Get a code point from a string at a random-access offset,
+ * without changing the offset.
+ * "Safe" macro, handles unpaired surrogates and checks for string boundaries.
+ *
+ * The offset may point to either the lead or trail surrogate unit
+ * for a supplementary code point, in which case the macro will read
+ * the adjacent matching surrogate as well.
+ *
+ * The length can be negative for a NUL-terminated string.
+ *
+ * If the offset points to a single, unpaired surrogate, then
+ * c is set to U+FFFD.
+ * Iteration through a string is more efficient with U16_NEXT_UNSAFE or U16_NEXT_OR_FFFD.
+ *
+ * @param s const UChar * string
+ * @param start starting string offset (usually 0)
+ * @param i string offset, must be start<=i<length
+ * @param length string length
+ * @param c output UChar32 variable
+ * @see U16_GET_UNSAFE
+ * @stable ICU 60
+ */
+#define U16_GET_OR_FFFD(s, start, i, length, c) UPRV_BLOCK_MACRO_BEGIN { \
+    (c)=(s)[i]; \
+    if(U16_IS_SURROGATE(c)) { \
+        uint16_t __c2; \
+        if(U16_IS_SURROGATE_LEAD(c)) { \
+            if((i)+1!=(length) && U16_IS_TRAIL(__c2=(s)[(i)+1])) { \
+                (c)=U16_GET_SUPPLEMENTARY((c), __c2); \
+            } else { \
+                (c)=0xfffd; \
+            } \
+        } else { \
+            if((i)>(start) && U16_IS_LEAD(__c2=(s)[(i)-1])) { \
+                (c)=U16_GET_SUPPLEMENTARY(__c2, (c)); \
+            } else { \
+                (c)=0xfffd; \
+            } \
+        } \
+    } \
+} UPRV_BLOCK_MACRO_END
 
 /* definitions with forward iteration --------------------------------------- */
 
@@ -232,12 +278,12 @@
  * @see U16_NEXT
  * @stable ICU 2.4
  */
-#define U16_NEXT_UNSAFE(s, i, c) { \
+#define U16_NEXT_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \
     (c)=(s)[(i)++]; \
     if(U16_IS_LEAD(c)) { \
         (c)=U16_GET_SUPPLEMENTARY((c), (s)[(i)++]); \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /**
  * Get a code point from a string at a code point boundary offset,
@@ -251,8 +297,7 @@
  * for a supplementary code point, in which case the macro will read
  * the following trail surrogate as well.
  * If the offset points to a trail surrogate or
- * to a single, unpaired lead surrogate, then that itself
- * will be returned as the code point.
+ * to a single, unpaired lead surrogate, then c is set to that unpaired surrogate.
  *
  * @param s const UChar * string
  * @param i string offset, must be i<length
@@ -261,7 +306,7 @@
  * @see U16_NEXT_UNSAFE
  * @stable ICU 2.4
  */
-#define U16_NEXT(s, i, length, c) { \
+#define U16_NEXT(s, i, length, c) UPRV_BLOCK_MACRO_BEGIN { \
     (c)=(s)[(i)++]; \
     if(U16_IS_LEAD(c)) { \
         uint16_t __c2; \
@@ -270,7 +315,41 @@
             (c)=U16_GET_SUPPLEMENTARY((c), __c2); \
         } \
     } \
-}
+} UPRV_BLOCK_MACRO_END
+
+/**
+ * Get a code point from a string at a code point boundary offset,
+ * and advance the offset to the next code point boundary.
+ * (Post-incrementing forward iteration.)
+ * "Safe" macro, handles unpaired surrogates and checks for string boundaries.
+ *
+ * The length can be negative for a NUL-terminated string.
+ *
+ * The offset may point to the lead surrogate unit
+ * for a supplementary code point, in which case the macro will read
+ * the following trail surrogate as well.
+ * If the offset points to a trail surrogate or
+ * to a single, unpaired lead surrogate, then c is set to U+FFFD.
+ *
+ * @param s const UChar * string
+ * @param i string offset, must be i<length
+ * @param length string length
+ * @param c output UChar32 variable
+ * @see U16_NEXT_UNSAFE
+ * @stable ICU 60
+ */
+#define U16_NEXT_OR_FFFD(s, i, length, c) UPRV_BLOCK_MACRO_BEGIN { \
+    (c)=(s)[(i)++]; \
+    if(U16_IS_SURROGATE(c)) { \
+        uint16_t __c2; \
+        if(U16_IS_SURROGATE_LEAD(c) && (i)!=(length) && U16_IS_TRAIL(__c2=(s)[(i)])) { \
+            ++(i); \
+            (c)=U16_GET_SUPPLEMENTARY((c), __c2); \
+        } else { \
+            (c)=0xfffd; \
+        } \
+    } \
+} UPRV_BLOCK_MACRO_END
 
 /**
  * Append a code point to a string, overwriting 1 or 2 code units.
@@ -285,14 +364,14 @@
  * @see U16_APPEND
  * @stable ICU 2.4
  */
-#define U16_APPEND_UNSAFE(s, i, c) { \
+#define U16_APPEND_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \
     if((uint32_t)(c)<=0xffff) { \
         (s)[(i)++]=(uint16_t)(c); \
     } else { \
         (s)[(i)++]=(uint16_t)(((c)>>10)+0xd7c0); \
         (s)[(i)++]=(uint16_t)(((c)&0x3ff)|0xdc00); \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /**
  * Append a code point to a string, overwriting 1 or 2 code units.
@@ -301,26 +380,26 @@
  * "Safe" macro, checks for a valid code point.
  * If a surrogate pair is written, checks for sufficient space in the string.
  * If the code point is not valid or a trail surrogate does not fit,
- * then isError is set to TRUE.
+ * then isError is set to true.
  *
  * @param s const UChar * string buffer
  * @param i string offset, must be i<capacity
  * @param capacity size of the string buffer
  * @param c code point to append
- * @param isError output UBool set to TRUE if an error occurs, otherwise not modified
+ * @param isError output UBool set to true if an error occurs, otherwise not modified
  * @see U16_APPEND_UNSAFE
  * @stable ICU 2.4
  */
-#define U16_APPEND(s, i, capacity, c, isError) { \
+#define U16_APPEND(s, i, capacity, c, isError) UPRV_BLOCK_MACRO_BEGIN { \
     if((uint32_t)(c)<=0xffff) { \
         (s)[(i)++]=(uint16_t)(c); \
     } else if((uint32_t)(c)<=0x10ffff && (i)+1<(capacity)) { \
         (s)[(i)++]=(uint16_t)(((c)>>10)+0xd7c0); \
         (s)[(i)++]=(uint16_t)(((c)&0x3ff)|0xdc00); \
     } else /* c>0x10ffff or not enough space */ { \
-        (isError)=TRUE; \
+        (isError)=true; \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /**
  * Advance the string offset from one code point boundary to the next.
@@ -332,11 +411,11 @@
  * @see U16_FWD_1
  * @stable ICU 2.4
  */
-#define U16_FWD_1_UNSAFE(s, i) { \
+#define U16_FWD_1_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \
     if(U16_IS_LEAD((s)[(i)++])) { \
         ++(i); \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /**
  * Advance the string offset from one code point boundary to the next.
@@ -351,11 +430,11 @@
  * @see U16_FWD_1_UNSAFE
  * @stable ICU 2.4
  */
-#define U16_FWD_1(s, i, length) { \
+#define U16_FWD_1(s, i, length) UPRV_BLOCK_MACRO_BEGIN { \
     if(U16_IS_LEAD((s)[(i)++]) && (i)!=(length) && U16_IS_TRAIL((s)[i])) { \
         ++(i); \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /**
  * Advance the string offset from one code point boundary to the n-th next one,
@@ -369,13 +448,13 @@
  * @see U16_FWD_N
  * @stable ICU 2.4
  */
-#define U16_FWD_N_UNSAFE(s, i, n) { \
+#define U16_FWD_N_UNSAFE(s, i, n) UPRV_BLOCK_MACRO_BEGIN { \
     int32_t __N=(n); \
     while(__N>0) { \
         U16_FWD_1_UNSAFE(s, i); \
         --__N; \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /**
  * Advance the string offset from one code point boundary to the n-th next one,
@@ -392,13 +471,13 @@
  * @see U16_FWD_N_UNSAFE
  * @stable ICU 2.4
  */
-#define U16_FWD_N(s, i, length, n) { \
+#define U16_FWD_N(s, i, length, n) UPRV_BLOCK_MACRO_BEGIN { \
     int32_t __N=(n); \
     while(__N>0 && ((i)<(length) || ((length)<0 && (s)[i]!=0))) { \
         U16_FWD_1(s, i, length); \
         --__N; \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /**
  * Adjust a random-access offset to a code point boundary
@@ -413,11 +492,11 @@
  * @see U16_SET_CP_START
  * @stable ICU 2.4
  */
-#define U16_SET_CP_START_UNSAFE(s, i) { \
+#define U16_SET_CP_START_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \
     if(U16_IS_TRAIL((s)[i])) { \
         --(i); \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /**
  * Adjust a random-access offset to a code point boundary
@@ -433,11 +512,11 @@
  * @see U16_SET_CP_START_UNSAFE
  * @stable ICU 2.4
  */
-#define U16_SET_CP_START(s, start, i) { \
+#define U16_SET_CP_START(s, start, i) UPRV_BLOCK_MACRO_BEGIN { \
     if(U16_IS_TRAIL((s)[i]) && (i)>(start) && U16_IS_LEAD((s)[(i)-1])) { \
         --(i); \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /* definitions with backward iteration -------------------------------------- */
 
@@ -461,12 +540,12 @@
  * @see U16_PREV
  * @stable ICU 2.4
  */
-#define U16_PREV_UNSAFE(s, i, c) { \
+#define U16_PREV_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \
     (c)=(s)[--(i)]; \
     if(U16_IS_TRAIL(c)) { \
         (c)=U16_GET_SUPPLEMENTARY((s)[--(i)], (c)); \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /**
  * Move the string offset from one code point boundary to the previous one
@@ -479,8 +558,7 @@
  * for a supplementary code point, then the macro will read
  * the preceding lead surrogate as well.
  * If the offset is behind a lead surrogate or behind a single, unpaired
- * trail surrogate, then that itself
- * will be returned as the code point.
+ * trail surrogate, then c is set to that unpaired surrogate.
  *
  * @param s const UChar * string
  * @param start starting string offset (usually 0)
@@ -489,7 +567,7 @@
  * @see U16_PREV_UNSAFE
  * @stable ICU 2.4
  */
-#define U16_PREV(s, start, i, c) { \
+#define U16_PREV(s, start, i, c) UPRV_BLOCK_MACRO_BEGIN { \
     (c)=(s)[--(i)]; \
     if(U16_IS_TRAIL(c)) { \
         uint16_t __c2; \
@@ -498,7 +576,40 @@
             (c)=U16_GET_SUPPLEMENTARY(__c2, (c)); \
         } \
     } \
-}
+} UPRV_BLOCK_MACRO_END
+
+/**
+ * Move the string offset from one code point boundary to the previous one
+ * and get the code point between them.
+ * (Pre-decrementing backward iteration.)
+ * "Safe" macro, handles unpaired surrogates and checks for string boundaries.
+ *
+ * The input offset may be the same as the string length.
+ * If the offset is behind a trail surrogate unit
+ * for a supplementary code point, then the macro will read
+ * the preceding lead surrogate as well.
+ * If the offset is behind a lead surrogate or behind a single, unpaired
+ * trail surrogate, then c is set to U+FFFD.
+ *
+ * @param s const UChar * string
+ * @param start starting string offset (usually 0)
+ * @param i string offset, must be start<i
+ * @param c output UChar32 variable
+ * @see U16_PREV_UNSAFE
+ * @stable ICU 60
+ */
+#define U16_PREV_OR_FFFD(s, start, i, c) UPRV_BLOCK_MACRO_BEGIN { \
+    (c)=(s)[--(i)]; \
+    if(U16_IS_SURROGATE(c)) { \
+        uint16_t __c2; \
+        if(U16_IS_SURROGATE_TRAIL(c) && (i)>(start) && U16_IS_LEAD(__c2=(s)[(i)-1])) { \
+            --(i); \
+            (c)=U16_GET_SUPPLEMENTARY(__c2, (c)); \
+        } else { \
+            (c)=0xfffd; \
+        } \
+    } \
+} UPRV_BLOCK_MACRO_END
 
 /**
  * Move the string offset from one code point boundary to the previous one.
@@ -511,11 +622,11 @@
  * @see U16_BACK_1
  * @stable ICU 2.4
  */
-#define U16_BACK_1_UNSAFE(s, i) { \
+#define U16_BACK_1_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \
     if(U16_IS_TRAIL((s)[--(i)])) { \
         --(i); \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /**
  * Move the string offset from one code point boundary to the previous one.
@@ -529,11 +640,11 @@
  * @see U16_BACK_1_UNSAFE
  * @stable ICU 2.4
  */
-#define U16_BACK_1(s, start, i) { \
+#define U16_BACK_1(s, start, i) UPRV_BLOCK_MACRO_BEGIN { \
     if(U16_IS_TRAIL((s)[--(i)]) && (i)>(start) && U16_IS_LEAD((s)[(i)-1])) { \
         --(i); \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /**
  * Move the string offset from one code point boundary to the n-th one before it,
@@ -548,13 +659,13 @@
  * @see U16_BACK_N
  * @stable ICU 2.4
  */
-#define U16_BACK_N_UNSAFE(s, i, n) { \
+#define U16_BACK_N_UNSAFE(s, i, n) UPRV_BLOCK_MACRO_BEGIN { \
     int32_t __N=(n); \
     while(__N>0) { \
         U16_BACK_1_UNSAFE(s, i); \
         --__N; \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /**
  * Move the string offset from one code point boundary to the n-th one before it,
@@ -570,13 +681,13 @@
  * @see U16_BACK_N_UNSAFE
  * @stable ICU 2.4
  */
-#define U16_BACK_N(s, start, i, n) { \
+#define U16_BACK_N(s, start, i, n) UPRV_BLOCK_MACRO_BEGIN { \
     int32_t __N=(n); \
     while(__N>0 && (i)>(start)) { \
         U16_BACK_1(s, start, i); \
         --__N; \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /**
  * Adjust a random-access offset to a code point boundary after a code point.
@@ -591,11 +702,11 @@
  * @see U16_SET_CP_LIMIT
  * @stable ICU 2.4
  */
-#define U16_SET_CP_LIMIT_UNSAFE(s, i) { \
+#define U16_SET_CP_LIMIT_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \
     if(U16_IS_LEAD((s)[(i)-1])) { \
         ++(i); \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /**
  * Adjust a random-access offset to a code point boundary after a code point.
@@ -614,10 +725,10 @@
  * @see U16_SET_CP_LIMIT_UNSAFE
  * @stable ICU 2.4
  */
-#define U16_SET_CP_LIMIT(s, start, i, length) { \
+#define U16_SET_CP_LIMIT(s, start, i, length) UPRV_BLOCK_MACRO_BEGIN { \
     if((start)<(i) && ((i)<(length) || (length)<0) && U16_IS_LEAD((s)[(i)-1]) && U16_IS_TRAIL((s)[i])) { \
         ++(i); \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 #endif
diff --git a/src/third_party/icu/source/common/unicode/utf32.h b/src/third_party/icu/source/common/unicode/utf32.h
index bf63e69..8822c4d 100644
--- a/src/third_party/icu/source/common/unicode/utf32.h
+++ b/src/third_party/icu/source/common/unicode/utf32.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  utf32.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
diff --git a/src/third_party/icu/source/common/unicode/utf8.h b/src/third_party/icu/source/common/unicode/utf8.h
index 808d9f2..5a07435 100644
--- a/src/third_party/icu/source/common/unicode/utf8.h
+++ b/src/third_party/icu/source/common/unicode/utf8.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  utf8.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -21,7 +23,7 @@
  * This file defines macros to deal with 8-bit Unicode (UTF-8) code units (bytes) and strings.
  *
  * For more information see utf.h and the ICU User Guide Strings chapter
- * (http://userguide.icu-project.org/strings).
+ * (https://unicode-org.github.io/icu/userguide/strings).
  *
  * <em>Usage:</em>
  * ICU coding guidelines for if() statements should be followed when using these macros.
@@ -32,6 +34,7 @@
 #ifndef __UTF8_H__
 #define __UTF8_H__
 
+#include <stdbool.h>
 #include "unicode/umachine.h"
 #ifndef __UTF_H__
 #   include "unicode/utf.h"
@@ -40,51 +43,23 @@
 /* internal definitions ----------------------------------------------------- */
 
 /**
- * \var utf8_countTrailBytes
- * Internal array with numbers of trail bytes for any given byte used in
- * lead byte position.
- *
- * This is internal since it is not meant to be called directly by external clients;
- * however it is called by public macros in this file and thus must remain stable,
- * and should not be hidden when other internal functions are hidden (otherwise
- * public macros would fail to compile).
- * @internal
- */
-#ifdef U_UTF8_IMPL
-U_EXPORT const uint8_t 
-#elif defined(U_STATIC_IMPLEMENTATION) || defined(U_COMMON_IMPLEMENTATION)
-U_CFUNC const uint8_t
-#else
-U_CFUNC U_IMPORT const uint8_t /* U_IMPORT2? */ /*U_IMPORT*/ 
-#endif
-utf8_countTrailBytes[256];
-
-/**
  * Counts the trail bytes for a UTF-8 lead byte.
- * Returns 0 for 0..0xbf as well as for 0xfe and 0xff.
+ * Returns 0 for 0..0xc1 as well as for 0xf5..0xff.
+ * leadByte might be evaluated multiple times.
  *
  * This is internal since it is not meant to be called directly by external clients;
  * however it is called by public macros in this file and thus must remain stable.
  *
- * Note: Beginning with ICU 50, the implementation uses a multi-condition expression
- * which was shown in 2012 (on x86-64) to compile to fast, branch-free code.
- * leadByte is evaluated multiple times.
- *
- * The pre-ICU 50 implementation used the exported array utf8_countTrailBytes:
- * #define U8_COUNT_TRAIL_BYTES(leadByte) (utf8_countTrailBytes[leadByte])
- * leadByte was evaluated exactly once.
- *
  * @param leadByte The first byte of a UTF-8 sequence. Must be 0..0xff.
  * @internal
  */
 #define U8_COUNT_TRAIL_BYTES(leadByte) \
-    ((uint8_t)(leadByte)<0xf0 ? \
-        ((uint8_t)(leadByte)>=0xc0)+((uint8_t)(leadByte)>=0xe0) : \
-        (uint8_t)(leadByte)<0xfe ? 3+((uint8_t)(leadByte)>=0xf8)+((uint8_t)(leadByte)>=0xfc) : 0)
+    (U8_IS_LEAD(leadByte) ? \
+        ((uint8_t)(leadByte)>=0xe0)+((uint8_t)(leadByte)>=0xf0)+1 : 0)
 
 /**
  * Counts the trail bytes for a UTF-8 lead byte of a valid UTF-8 sequence.
- * The maximum supported lead byte is 0xf4 corresponding to U+10FFFF.
+ * Returns 0 for 0..0xc1. Undefined for 0xf5..0xff.
  * leadByte might be evaluated multiple times.
  *
  * This is internal since it is not meant to be called directly by external clients;
@@ -94,7 +69,7 @@
  * @internal
  */
 #define U8_COUNT_TRAIL_BYTES_UNSAFE(leadByte) \
-    (((leadByte)>=0xc0)+((leadByte)>=0xe0)+((leadByte)>=0xf0))
+    (((uint8_t)(leadByte)>=0xc2)+((uint8_t)(leadByte)>=0xe0)+((uint8_t)(leadByte)>=0xf0))
 
 /**
  * Mask a UTF-8 lead byte, leave only the lower bits that form part of the code point value.
@@ -106,51 +81,85 @@
 #define U8_MASK_LEAD_BYTE(leadByte, countTrailBytes) ((leadByte)&=(1<<(6-(countTrailBytes)))-1)
 
 /**
+ * Internal bit vector for 3-byte UTF-8 validity check, for use in U8_IS_VALID_LEAD3_AND_T1.
+ * Each bit indicates whether one lead byte + first trail byte pair starts a valid sequence.
+ * Lead byte E0..EF bits 3..0 are used as byte index,
+ * first trail byte bits 7..5 are used as bit index into that byte.
+ * @see U8_IS_VALID_LEAD3_AND_T1
+ * @internal
+ */
+#define U8_LEAD3_T1_BITS "\x20\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x10\x30\x30"
+
+/**
+ * Internal 3-byte UTF-8 validity check.
+ * Non-zero if lead byte E0..EF and first trail byte 00..FF start a valid sequence.
+ * @internal
+ */
+#define U8_IS_VALID_LEAD3_AND_T1(lead, t1) (U8_LEAD3_T1_BITS[(lead)&0xf]&(1<<((uint8_t)(t1)>>5)))
+
+/**
+ * Internal bit vector for 4-byte UTF-8 validity check, for use in U8_IS_VALID_LEAD4_AND_T1.
+ * Each bit indicates whether one lead byte + first trail byte pair starts a valid sequence.
+ * First trail byte bits 7..4 are used as byte index,
+ * lead byte F0..F4 bits 2..0 are used as bit index into that byte.
+ * @see U8_IS_VALID_LEAD4_AND_T1
+ * @internal
+ */
+#define U8_LEAD4_T1_BITS "\x00\x00\x00\x00\x00\x00\x00\x00\x1E\x0F\x0F\x0F\x00\x00\x00\x00"
+
+/**
+ * Internal 4-byte UTF-8 validity check.
+ * Non-zero if lead byte F0..F4 and first trail byte 00..FF start a valid sequence.
+ * @internal
+ */
+#define U8_IS_VALID_LEAD4_AND_T1(lead, t1) (U8_LEAD4_T1_BITS[(uint8_t)(t1)>>4]&(1<<((lead)&7)))
+
+/**
  * Function for handling "next code point" with error-checking.
  *
  * This is internal since it is not meant to be called directly by external clients;
- * however it is U_STABLE (not U_INTERNAL) since it is called by public macros in this
+ * however it is called by public macros in this
  * file and thus must remain stable, and should not be hidden when other internal
  * functions are hidden (otherwise public macros would fail to compile).
  * @internal
  */
-U_STABLE UChar32 U_EXPORT2
+U_CAPI UChar32 U_EXPORT2
 utf8_nextCharSafeBody(const uint8_t *s, int32_t *pi, int32_t length, UChar32 c, UBool strict);
 
 /**
  * Function for handling "append code point" with error-checking.
  *
  * This is internal since it is not meant to be called directly by external clients;
- * however it is U_STABLE (not U_INTERNAL) since it is called by public macros in this
+ * however it is called by public macros in this
  * file and thus must remain stable, and should not be hidden when other internal
  * functions are hidden (otherwise public macros would fail to compile).
  * @internal
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 utf8_appendCharSafeBody(uint8_t *s, int32_t i, int32_t length, UChar32 c, UBool *pIsError);
 
 /**
  * Function for handling "previous code point" with error-checking.
  *
  * This is internal since it is not meant to be called directly by external clients;
- * however it is U_STABLE (not U_INTERNAL) since it is called by public macros in this
+ * however it is called by public macros in this
  * file and thus must remain stable, and should not be hidden when other internal
  * functions are hidden (otherwise public macros would fail to compile).
  * @internal
  */
-U_STABLE UChar32 U_EXPORT2
+U_CAPI UChar32 U_EXPORT2
 utf8_prevCharSafeBody(const uint8_t *s, int32_t start, int32_t *pi, UChar32 c, UBool strict);
 
 /**
  * Function for handling "skip backward one code point" with error-checking.
  *
  * This is internal since it is not meant to be called directly by external clients;
- * however it is U_STABLE (not U_INTERNAL) since it is called by public macros in this
+ * however it is called by public macros in this
  * file and thus must remain stable, and should not be hidden when other internal
  * functions are hidden (otherwise public macros would fail to compile).
  * @internal
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 utf8_back1SafeBody(const uint8_t *s, int32_t start, int32_t i);
 
 /* single-code point definitions -------------------------------------------- */
@@ -158,26 +167,27 @@
 /**
  * Does this code unit (byte) encode a code point by itself (US-ASCII 0..0x7f)?
  * @param c 8-bit code unit (byte)
- * @return TRUE or FALSE
+ * @return true or false
  * @stable ICU 2.4
  */
 #define U8_IS_SINGLE(c) (((c)&0x80)==0)
 
 /**
- * Is this code unit (byte) a UTF-8 lead byte?
+ * Is this code unit (byte) a UTF-8 lead byte? (0xC2..0xF4)
  * @param c 8-bit code unit (byte)
- * @return TRUE or FALSE
+ * @return true or false
  * @stable ICU 2.4
  */
-#define U8_IS_LEAD(c) ((uint8_t)((c)-0xc0)<0x3e)
+#define U8_IS_LEAD(c) ((uint8_t)((c)-0xc2)<=0x32)
+// 0x32=0xf4-0xc2
 
 /**
- * Is this code unit (byte) a UTF-8 trail byte?
+ * Is this code unit (byte) a UTF-8 trail byte? (0x80..0xBF)
  * @param c 8-bit code unit (byte)
- * @return TRUE or FALSE
+ * @return true or false
  * @stable ICU 2.4
  */
-#define U8_IS_TRAIL(c) (((c)&0xc0)==0x80)
+#define U8_IS_TRAIL(c) ((int8_t)(c)<-0x40)
 
 /**
  * How many code units (bytes) are used for the UTF-8 encoding
@@ -220,11 +230,11 @@
  * @see U8_GET
  * @stable ICU 2.4
  */
-#define U8_GET_UNSAFE(s, i, c) { \
+#define U8_GET_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \
     int32_t _u8_get_unsafe_index=(int32_t)(i); \
     U8_SET_CP_START_UNSAFE(s, _u8_get_unsafe_index); \
     U8_NEXT_UNSAFE(s, _u8_get_unsafe_index, c); \
-}
+} UPRV_BLOCK_MACRO_END
 
 /**
  * Get a code point from a string at a random-access offset,
@@ -247,11 +257,11 @@
  * @see U8_GET_UNSAFE
  * @stable ICU 2.4
  */
-#define U8_GET(s, start, i, length, c) { \
+#define U8_GET(s, start, i, length, c) UPRV_BLOCK_MACRO_BEGIN { \
     int32_t _u8_get_index=(i); \
     U8_SET_CP_START(s, start, _u8_get_index); \
     U8_NEXT(s, _u8_get_index, length, c); \
-}
+} UPRV_BLOCK_MACRO_END
 
 /**
  * Get a code point from a string at a random-access offset,
@@ -278,11 +288,11 @@
  * @see U8_GET
  * @stable ICU 51
  */
-#define U8_GET_OR_FFFD(s, start, i, length, c) { \
+#define U8_GET_OR_FFFD(s, start, i, length, c) UPRV_BLOCK_MACRO_BEGIN { \
     int32_t _u8_get_index=(i); \
     U8_SET_CP_START(s, start, _u8_get_index); \
     U8_NEXT_OR_FFFD(s, _u8_get_index, length, c); \
-}
+} UPRV_BLOCK_MACRO_END
 
 /* definitions with forward iteration --------------------------------------- */
 
@@ -303,9 +313,9 @@
  * @see U8_NEXT
  * @stable ICU 2.4
  */
-#define U8_NEXT_UNSAFE(s, i, c) { \
+#define U8_NEXT_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \
     (c)=(uint8_t)(s)[(i)++]; \
-    if((c)>=0x80) { \
+    if(!U8_IS_SINGLE(c)) { \
         if((c)<0xe0) { \
             (c)=(((c)&0x1f)<<6)|((s)[(i)++]&0x3f); \
         } else if((c)<0xf0) { \
@@ -317,7 +327,7 @@
             (i)+=3; \
         } \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /**
  * Get a code point from a string at a code point boundary offset,
@@ -339,32 +349,7 @@
  * @see U8_NEXT_UNSAFE
  * @stable ICU 2.4
  */
-#define U8_NEXT(s, i, length, c) { \
-    (c)=(uint8_t)(s)[(i)++]; \
-    if((c)>=0x80) { \
-        uint8_t __t1, __t2; \
-        if( /* handle U+1000..U+CFFF inline */ \
-            (0xe0<(c) && (c)<=0xec) && \
-            (((i)+1)<(length) || (length)<0) && \
-            (__t1=(uint8_t)((s)[i]-0x80))<=0x3f && \
-            (__t2=(uint8_t)((s)[(i)+1]-0x80))<= 0x3f \
-        ) { \
-            /* no need for (c&0xf) because the upper bits are truncated after <<12 in the cast to (UChar) */ \
-            (c)=(UChar)(((c)<<12)|(__t1<<6)|__t2); \
-            (i)+=2; \
-        } else if( /* handle U+0080..U+07FF inline */ \
-            ((c)<0xe0 && (c)>=0xc2) && \
-            ((i)!=(length)) && \
-            (__t1=(uint8_t)((s)[i]-0x80))<=0x3f \
-        ) { \
-            (c)=(((c)&0x1f)<<6)|__t1; \
-            ++(i); \
-        } else { \
-            /* function call for "complicated" and error cases */ \
-            (c)=utf8_nextCharSafeBody((const uint8_t *)s, &(i), (length), c, -1); \
-        } \
-    } \
-}
+#define U8_NEXT(s, i, length, c) U8_INTERNAL_NEXT_OR_SUB(s, i, length, c, U_SENTINEL)
 
 /**
  * Get a code point from a string at a code point boundary offset,
@@ -390,32 +375,36 @@
  * @see U8_NEXT
  * @stable ICU 51
  */
-#define U8_NEXT_OR_FFFD(s, i, length, c) { \
+#define U8_NEXT_OR_FFFD(s, i, length, c) U8_INTERNAL_NEXT_OR_SUB(s, i, length, c, 0xfffd)
+
+/** @internal */
+#define U8_INTERNAL_NEXT_OR_SUB(s, i, length, c, sub) UPRV_BLOCK_MACRO_BEGIN { \
     (c)=(uint8_t)(s)[(i)++]; \
-    if((c)>=0x80) { \
-        uint8_t __t1, __t2; \
-        if( /* handle U+1000..U+CFFF inline */ \
-            (0xe0<(c) && (c)<=0xec) && \
-            (((i)+1)<(length) || (length)<0) && \
-            (__t1=(uint8_t)((s)[i]-0x80))<=0x3f && \
-            (__t2=(uint8_t)((s)[(i)+1]-0x80))<= 0x3f \
-        ) { \
-            /* no need for (c&0xf) because the upper bits are truncated after <<12 in the cast to (UChar) */ \
-            (c)=(UChar)(((c)<<12)|(__t1<<6)|__t2); \
-            (i)+=2; \
-        } else if( /* handle U+0080..U+07FF inline */ \
-            ((c)<0xe0 && (c)>=0xc2) && \
-            ((i)!=(length)) && \
-            (__t1=(uint8_t)((s)[i]-0x80))<=0x3f \
-        ) { \
-            (c)=(((c)&0x1f)<<6)|__t1; \
-            ++(i); \
+    if(!U8_IS_SINGLE(c)) { \
+        uint8_t __t = 0; \
+        if((i)!=(length) && \
+            /* fetch/validate/assemble all but last trail byte */ \
+            ((c)>=0xe0 ? \
+                ((c)<0xf0 ?  /* U+0800..U+FFFF except surrogates */ \
+                    U8_LEAD3_T1_BITS[(c)&=0xf]&(1<<((__t=(s)[i])>>5)) && \
+                    (__t&=0x3f, 1) \
+                :  /* U+10000..U+10FFFF */ \
+                    ((c)-=0xf0)<=4 && \
+                    U8_LEAD4_T1_BITS[(__t=(s)[i])>>4]&(1<<(c)) && \
+                    ((c)=((c)<<6)|(__t&0x3f), ++(i)!=(length)) && \
+                    (__t=(s)[i]-0x80)<=0x3f) && \
+                /* valid second-to-last trail byte */ \
+                ((c)=((c)<<6)|__t, ++(i)!=(length)) \
+            :  /* U+0080..U+07FF */ \
+                (c)>=0xc2 && ((c)&=0x1f, 1)) && \
+            /* last trail byte */ \
+            (__t=(s)[i]-0x80)<=0x3f && \
+            ((c)=((c)<<6)|__t, ++(i), 1)) { \
         } else { \
-            /* function call for "complicated" and error cases */ \
-            (c)=utf8_nextCharSafeBody((const uint8_t *)s, &(i), (length), c, -3); \
+            (c)=(sub);  /* ill-formed*/ \
         } \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /**
  * Append a code point to a string, overwriting 1 to 4 bytes.
@@ -430,7 +419,7 @@
  * @see U8_APPEND
  * @stable ICU 2.4
  */
-#define U8_APPEND_UNSAFE(s, i, c) { \
+#define U8_APPEND_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \
     uint32_t __uc=(c); \
     if(__uc<=0x7f) { \
         (s)[(i)++]=(uint8_t)__uc; \
@@ -448,7 +437,7 @@
         } \
         (s)[(i)++]=(uint8_t)((__uc&0x3f)|0x80); \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /**
  * Append a code point to a string, overwriting 1 to 4 bytes.
@@ -457,17 +446,17 @@
  * "Safe" macro, checks for a valid code point.
  * If a non-ASCII code point is written, checks for sufficient space in the string.
  * If the code point is not valid or trail bytes do not fit,
- * then isError is set to TRUE.
+ * then isError is set to true.
  *
  * @param s const uint8_t * string buffer
  * @param i int32_t string offset, must be i<capacity
  * @param capacity int32_t size of the string buffer
  * @param c UChar32 code point to append
- * @param isError output UBool set to TRUE if an error occurs, otherwise not modified
+ * @param isError output UBool set to true if an error occurs, otherwise not modified
  * @see U8_APPEND_UNSAFE
  * @stable ICU 2.4
  */
-#define U8_APPEND(s, i, capacity, c, isError) { \
+#define U8_APPEND(s, i, capacity, c, isError) UPRV_BLOCK_MACRO_BEGIN { \
     uint32_t __uc=(c); \
     if(__uc<=0x7f) { \
         (s)[(i)++]=(uint8_t)__uc; \
@@ -484,9 +473,9 @@
         (s)[(i)++]=(uint8_t)(((__uc>>6)&0x3f)|0x80); \
         (s)[(i)++]=(uint8_t)((__uc&0x3f)|0x80); \
     } else { \
-        (isError)=TRUE; \
+        (isError)=true; \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /**
  * Advance the string offset from one code point boundary to the next.
@@ -498,9 +487,9 @@
  * @see U8_FWD_1
  * @stable ICU 2.4
  */
-#define U8_FWD_1_UNSAFE(s, i) { \
-    (i)+=1+U8_COUNT_TRAIL_BYTES_UNSAFE((uint8_t)(s)[i]); \
-}
+#define U8_FWD_1_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \
+    (i)+=1+U8_COUNT_TRAIL_BYTES_UNSAFE((s)[i]); \
+} UPRV_BLOCK_MACRO_END
 
 /**
  * Advance the string offset from one code point boundary to the next.
@@ -515,19 +504,28 @@
  * @see U8_FWD_1_UNSAFE
  * @stable ICU 2.4
  */
-#define U8_FWD_1(s, i, length) { \
-    uint8_t __b=(uint8_t)(s)[(i)++]; \
-    if(U8_IS_LEAD(__b)) { \
-        uint8_t __count=U8_COUNT_TRAIL_BYTES(__b); \
-        if((i)+__count>(length) && (length)>=0) { \
-            __count=(uint8_t)((length)-(i)); \
-        } \
-        while(__count>0 && U8_IS_TRAIL((s)[i])) { \
-            ++(i); \
-            --__count; \
+#define U8_FWD_1(s, i, length) UPRV_BLOCK_MACRO_BEGIN { \
+    uint8_t __b=(s)[(i)++]; \
+    if(U8_IS_LEAD(__b) && (i)!=(length)) { \
+        uint8_t __t1=(s)[i]; \
+        if((0xe0<=__b && __b<0xf0)) { \
+            if(U8_IS_VALID_LEAD3_AND_T1(__b, __t1) && \
+                    ++(i)!=(length) && U8_IS_TRAIL((s)[i])) { \
+                ++(i); \
+            } \
+        } else if(__b<0xe0) { \
+            if(U8_IS_TRAIL(__t1)) { \
+                ++(i); \
+            } \
+        } else /* c>=0xf0 */ { \
+            if(U8_IS_VALID_LEAD4_AND_T1(__b, __t1) && \
+                    ++(i)!=(length) && U8_IS_TRAIL((s)[i]) && \
+                    ++(i)!=(length) && U8_IS_TRAIL((s)[i])) { \
+                ++(i); \
+            } \
         } \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /**
  * Advance the string offset from one code point boundary to the n-th next one,
@@ -541,13 +539,13 @@
  * @see U8_FWD_N
  * @stable ICU 2.4
  */
-#define U8_FWD_N_UNSAFE(s, i, n) { \
+#define U8_FWD_N_UNSAFE(s, i, n) UPRV_BLOCK_MACRO_BEGIN { \
     int32_t __N=(n); \
     while(__N>0) { \
         U8_FWD_1_UNSAFE(s, i); \
         --__N; \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /**
  * Advance the string offset from one code point boundary to the n-th next one,
@@ -564,13 +562,13 @@
  * @see U8_FWD_N_UNSAFE
  * @stable ICU 2.4
  */
-#define U8_FWD_N(s, i, length, n) { \
+#define U8_FWD_N(s, i, length, n) UPRV_BLOCK_MACRO_BEGIN { \
     int32_t __N=(n); \
     while(__N>0 && ((i)<(length) || ((length)<0 && (s)[i]!=0))) { \
         U8_FWD_1(s, i, length); \
         --__N; \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /**
  * Adjust a random-access offset to a code point boundary
@@ -585,9 +583,9 @@
  * @see U8_SET_CP_START
  * @stable ICU 2.4
  */
-#define U8_SET_CP_START_UNSAFE(s, i) { \
+#define U8_SET_CP_START_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \
     while(U8_IS_TRAIL((s)[i])) { --(i); } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /**
  * Adjust a random-access offset to a code point boundary
@@ -595,19 +593,72 @@
  * If the offset points to a UTF-8 trail byte,
  * then the offset is moved backward to the corresponding lead byte.
  * Otherwise, it is not modified.
+ *
  * "Safe" macro, checks for illegal sequences and for string boundaries.
+ * Unlike U8_TRUNCATE_IF_INCOMPLETE(), this macro always reads s[i].
  *
  * @param s const uint8_t * string
  * @param start int32_t starting string offset (usually 0)
  * @param i int32_t string offset, must be start<=i
  * @see U8_SET_CP_START_UNSAFE
+ * @see U8_TRUNCATE_IF_INCOMPLETE
  * @stable ICU 2.4
  */
-#define U8_SET_CP_START(s, start, i) { \
+#define U8_SET_CP_START(s, start, i) UPRV_BLOCK_MACRO_BEGIN { \
     if(U8_IS_TRAIL((s)[(i)])) { \
         (i)=utf8_back1SafeBody(s, start, (i)); \
     } \
-}
+} UPRV_BLOCK_MACRO_END
+
+/**
+ * If the string ends with a UTF-8 byte sequence that is valid so far
+ * but incomplete, then reduce the length of the string to end before
+ * the lead byte of that incomplete sequence.
+ * For example, if the string ends with E1 80, the length is reduced by 2.
+ *
+ * In all other cases (the string ends with a complete sequence, or it is not
+ * possible for any further trail byte to extend the trailing sequence)
+ * the length remains unchanged.
+ *
+ * Useful for processing text split across multiple buffers
+ * (save the incomplete sequence for later)
+ * and for optimizing iteration
+ * (check for string length only once per character).
+ *
+ * "Safe" macro, checks for illegal sequences and for string boundaries.
+ * Unlike U8_SET_CP_START(), this macro never reads s[length].
+ *
+ * (In UTF-16, simply check for U16_IS_LEAD(last code unit).)
+ *
+ * @param s const uint8_t * string
+ * @param start int32_t starting string offset (usually 0)
+ * @param length int32_t string length (usually start<=length)
+ * @see U8_SET_CP_START
+ * @stable ICU 61
+ */
+#define U8_TRUNCATE_IF_INCOMPLETE(s, start, length) UPRV_BLOCK_MACRO_BEGIN { \
+    if((length)>(start)) { \
+        uint8_t __b1=s[(length)-1]; \
+        if(U8_IS_SINGLE(__b1)) { \
+            /* common ASCII character */ \
+        } else if(U8_IS_LEAD(__b1)) { \
+            --(length); \
+        } else if(U8_IS_TRAIL(__b1) && ((length)-2)>=(start)) { \
+            uint8_t __b2=s[(length)-2]; \
+            if(0xe0<=__b2 && __b2<=0xf4) { \
+                if(__b2<0xf0 ? U8_IS_VALID_LEAD3_AND_T1(__b2, __b1) : \
+                        U8_IS_VALID_LEAD4_AND_T1(__b2, __b1)) { \
+                    (length)-=2; \
+                } \
+            } else if(U8_IS_TRAIL(__b2) && ((length)-3)>=(start)) { \
+                uint8_t __b3=s[(length)-3]; \
+                if(0xf0<=__b3 && __b3<=0xf4 && U8_IS_VALID_LEAD4_AND_T1(__b3, __b2)) { \
+                    (length)-=3; \
+                } \
+            } \
+        } \
+    } \
+} UPRV_BLOCK_MACRO_END
 
 /* definitions with backward iteration -------------------------------------- */
 
@@ -630,7 +681,7 @@
  * @see U8_PREV
  * @stable ICU 2.4
  */
-#define U8_PREV_UNSAFE(s, i, c) { \
+#define U8_PREV_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \
     (c)=(uint8_t)(s)[--(i)]; \
     if(U8_IS_TRAIL(c)) { \
         uint8_t __b, __count=1, __shift=6; \
@@ -638,7 +689,7 @@
         /* c is a trail byte */ \
         (c)&=0x3f; \
         for(;;) { \
-            __b=(uint8_t)(s)[--(i)]; \
+            __b=(s)[--(i)]; \
             if(__b>=0xc0) { \
                 U8_MASK_LEAD_BYTE(__b, __count); \
                 (c)|=(UChar32)__b<<__shift; \
@@ -650,7 +701,7 @@
             } \
         } \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /**
  * Move the string offset from one code point boundary to the previous one
@@ -672,12 +723,12 @@
  * @see U8_PREV_UNSAFE
  * @stable ICU 2.4
  */
-#define U8_PREV(s, start, i, c) { \
+#define U8_PREV(s, start, i, c) UPRV_BLOCK_MACRO_BEGIN { \
     (c)=(uint8_t)(s)[--(i)]; \
-    if((c)>=0x80) { \
+    if(!U8_IS_SINGLE(c)) { \
         (c)=utf8_prevCharSafeBody((const uint8_t *)s, start, &(i), c, -1); \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /**
  * Move the string offset from one code point boundary to the previous one
@@ -703,12 +754,12 @@
  * @see U8_PREV
  * @stable ICU 51
  */
-#define U8_PREV_OR_FFFD(s, start, i, c) { \
+#define U8_PREV_OR_FFFD(s, start, i, c) UPRV_BLOCK_MACRO_BEGIN { \
     (c)=(uint8_t)(s)[--(i)]; \
-    if((c)>=0x80) { \
+    if(!U8_IS_SINGLE(c)) { \
         (c)=utf8_prevCharSafeBody((const uint8_t *)s, start, &(i), c, -3); \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /**
  * Move the string offset from one code point boundary to the previous one.
@@ -721,9 +772,9 @@
  * @see U8_BACK_1
  * @stable ICU 2.4
  */
-#define U8_BACK_1_UNSAFE(s, i) { \
+#define U8_BACK_1_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \
     while(U8_IS_TRAIL((s)[--(i)])) {} \
-}
+} UPRV_BLOCK_MACRO_END
 
 /**
  * Move the string offset from one code point boundary to the previous one.
@@ -737,11 +788,11 @@
  * @see U8_BACK_1_UNSAFE
  * @stable ICU 2.4
  */
-#define U8_BACK_1(s, start, i) { \
+#define U8_BACK_1(s, start, i) UPRV_BLOCK_MACRO_BEGIN { \
     if(U8_IS_TRAIL((s)[--(i)])) { \
         (i)=utf8_back1SafeBody(s, start, (i)); \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /**
  * Move the string offset from one code point boundary to the n-th one before it,
@@ -756,13 +807,13 @@
  * @see U8_BACK_N
  * @stable ICU 2.4
  */
-#define U8_BACK_N_UNSAFE(s, i, n) { \
+#define U8_BACK_N_UNSAFE(s, i, n) UPRV_BLOCK_MACRO_BEGIN { \
     int32_t __N=(n); \
     while(__N>0) { \
         U8_BACK_1_UNSAFE(s, i); \
         --__N; \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /**
  * Move the string offset from one code point boundary to the n-th one before it,
@@ -778,13 +829,13 @@
  * @see U8_BACK_N_UNSAFE
  * @stable ICU 2.4
  */
-#define U8_BACK_N(s, start, i, n) { \
+#define U8_BACK_N(s, start, i, n) UPRV_BLOCK_MACRO_BEGIN { \
     int32_t __N=(n); \
     while(__N>0 && (i)>(start)) { \
         U8_BACK_1(s, start, i); \
         --__N; \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /**
  * Adjust a random-access offset to a code point boundary after a code point.
@@ -799,10 +850,10 @@
  * @see U8_SET_CP_LIMIT
  * @stable ICU 2.4
  */
-#define U8_SET_CP_LIMIT_UNSAFE(s, i) { \
+#define U8_SET_CP_LIMIT_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \
     U8_BACK_1_UNSAFE(s, i); \
     U8_FWD_1_UNSAFE(s, i); \
-}
+} UPRV_BLOCK_MACRO_END
 
 /**
  * Adjust a random-access offset to a code point boundary after a code point.
@@ -821,11 +872,11 @@
  * @see U8_SET_CP_LIMIT_UNSAFE
  * @stable ICU 2.4
  */
-#define U8_SET_CP_LIMIT(s, start, i, length) { \
+#define U8_SET_CP_LIMIT(s, start, i, length) UPRV_BLOCK_MACRO_BEGIN { \
     if((start)<(i) && ((i)<(length) || (length)<0)) { \
         U8_BACK_1(s, start, i); \
         U8_FWD_1(s, i, length); \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 #endif
diff --git a/src/third_party/icu/source/common/unicode/utf_old.h b/src/third_party/icu/source/common/unicode/utf_old.h
index f9125b1..160f5ad 100644
--- a/src/third_party/icu/source/common/unicode/utf_old.h
+++ b/src/third_party/icu/source/common/unicode/utf_old.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  utf_old.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -15,12 +17,9 @@
 */
 
 /**
- * \file 
+ * \file
  * \brief C API: Deprecated macros for Unicode string handling
- */
-
-/**
- * 
+ *
  * The macros in utf_old.h are all deprecated and their use discouraged.
  * Some of the design principles behind the set of UTF macros
  * have changed or proved impractical.
@@ -110,7 +109,7 @@
  * Where such a distinction is useful, there are two versions of the macros, "unsafe" and "safe"
  * ones with ..._UNSAFE and ..._SAFE suffixes. The unsafe macros are fast but may cause
  * program failures if the strings are not well-formed. The safe macros have an additional, boolean
- * parameter "strict". If strict is FALSE, then only illegal sequences are detected.
+ * parameter "strict". If strict is false, then only illegal sequences are detected.
  * Otherwise, irregular sequences and non-characters are detected as well (like single surrogates).
  * Safe macros return special error code points for illegal/irregular sequences:
  * Typically, U+ffff, or values that would result in a code unit sequence of the same length
@@ -137,18 +136,33 @@
  *
  * <hr>
  *
- * @deprecated ICU 2.4. Use the macros in utf.h, utf16.h, utf8.h instead.
+ * Deprecated ICU 2.4. Use the macros in utf.h, utf16.h, utf8.h instead.
  */
 
 #ifndef __UTF_OLD_H__
 #define __UTF_OLD_H__
 
-#ifndef U_HIDE_DEPRECATED_API
-
 #include "unicode/utf.h"
 #include "unicode/utf8.h"
 #include "unicode/utf16.h"
 
+/**
+ * \def U_HIDE_OBSOLETE_UTF_OLD_H
+ *
+ * Hides the obsolete definitions in unicode/utf_old.h.
+ * Recommended to be set to 1 at compile time to make sure
+ * the long-deprecated macros are no longer used.
+ *
+ * For reasons for the deprecation see the utf_old.h file comments.
+ *
+ * @internal
+ */
+#ifndef U_HIDE_OBSOLETE_UTF_OLD_H
+#   define U_HIDE_OBSOLETE_UTF_OLD_H 0
+#endif
+
+#if !defined(U_HIDE_DEPRECATED_API) && !U_HIDE_OBSOLETE_UTF_OLD_H
+
 /* Formerly utf.h, part 1 --------------------------------------------------- */
 
 #ifdef U_USE_UTF_DEPRECATES
@@ -167,7 +181,7 @@
 
 /**
  * The default choice for general Unicode string macros is to use the ..._SAFE macro implementations
- * with strict=FALSE.
+ * with strict=false.
  *
  * @deprecated ICU 2.4. Obsolete, see utf_old.h.
  */
@@ -266,6 +280,25 @@
 /* Formerly utf8.h ---------------------------------------------------------- */
 
 /**
+* \var utf8_countTrailBytes
+* Internal array with numbers of trail bytes for any given byte used in
+* lead byte position.
+*
+* This is internal since it is not meant to be called directly by external clients;
+* however it is called by public macros in this file and thus must remain stable,
+* and should not be hidden when other internal functions are hidden (otherwise
+* public macros would fail to compile).
+* @internal
+*/
+#ifdef U_UTF8_IMPL
+// No forward declaration if compiling utf_impl.cpp, which defines utf8_countTrailBytes.
+#elif defined(U_STATIC_IMPLEMENTATION) || defined(U_COMMON_IMPLEMENTATION)
+U_CFUNC const uint8_t utf8_countTrailBytes[];
+#else
+U_CFUNC U_IMPORT const uint8_t utf8_countTrailBytes[];    /* U_IMPORT2? */ /*U_IMPORT*/
+#endif
+
+/**
  * Count the trail bytes for a UTF-8 lead byte.
  * @deprecated ICU 2.4. Renamed to U8_COUNT_TRAIL_BYTES, see utf_old.h.
  */
@@ -329,21 +362,21 @@
 #define UTF8_ARRAY_SIZE(size) ((5*(size))/2)
 
 /** @deprecated ICU 2.4. Renamed to U8_GET_UNSAFE, see utf_old.h. */
-#define UTF8_GET_CHAR_UNSAFE(s, i, c) { \
+#define UTF8_GET_CHAR_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \
     int32_t _utf8_get_char_unsafe_index=(int32_t)(i); \
     UTF8_SET_CHAR_START_UNSAFE(s, _utf8_get_char_unsafe_index); \
     UTF8_NEXT_CHAR_UNSAFE(s, _utf8_get_char_unsafe_index, c); \
-}
+} UPRV_BLOCK_MACRO_END
 
 /** @deprecated ICU 2.4. Use U8_GET instead, see utf_old.h. */
-#define UTF8_GET_CHAR_SAFE(s, start, i, length, c, strict) { \
+#define UTF8_GET_CHAR_SAFE(s, start, i, length, c, strict) UPRV_BLOCK_MACRO_BEGIN { \
     int32_t _utf8_get_char_safe_index=(int32_t)(i); \
     UTF8_SET_CHAR_START_SAFE(s, start, _utf8_get_char_safe_index); \
     UTF8_NEXT_CHAR_SAFE(s, _utf8_get_char_safe_index, length, c, strict); \
-}
+} UPRV_BLOCK_MACRO_END
 
 /** @deprecated ICU 2.4. Renamed to U8_NEXT_UNSAFE, see utf_old.h. */
-#define UTF8_NEXT_CHAR_UNSAFE(s, i, c) { \
+#define UTF8_NEXT_CHAR_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \
     (c)=(s)[(i)++]; \
     if((uint8_t)((c)-0xc0)<0x35) { \
         uint8_t __count=UTF8_COUNT_TRAIL_BYTES(c); \
@@ -360,10 +393,10 @@
             break; \
         } \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /** @deprecated ICU 2.4. Renamed to U8_APPEND_UNSAFE, see utf_old.h. */
-#define UTF8_APPEND_CHAR_UNSAFE(s, i, c) { \
+#define UTF8_APPEND_CHAR_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \
     if((uint32_t)(c)<=0x7f) { \
         (s)[(i)++]=(uint8_t)(c); \
     } else { \
@@ -380,29 +413,29 @@
         } \
         (s)[(i)++]=(uint8_t)(((c)&0x3f)|0x80); \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /** @deprecated ICU 2.4. Renamed to U8_FWD_1_UNSAFE, see utf_old.h. */
-#define UTF8_FWD_1_UNSAFE(s, i) { \
+#define UTF8_FWD_1_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \
     (i)+=1+UTF8_COUNT_TRAIL_BYTES((s)[i]); \
-}
+} UPRV_BLOCK_MACRO_END
 
 /** @deprecated ICU 2.4. Renamed to U8_FWD_N_UNSAFE, see utf_old.h. */
-#define UTF8_FWD_N_UNSAFE(s, i, n) { \
+#define UTF8_FWD_N_UNSAFE(s, i, n) UPRV_BLOCK_MACRO_BEGIN { \
     int32_t __N=(n); \
     while(__N>0) { \
         UTF8_FWD_1_UNSAFE(s, i); \
         --__N; \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /** @deprecated ICU 2.4. Renamed to U8_SET_CP_START_UNSAFE, see utf_old.h. */
-#define UTF8_SET_CHAR_START_UNSAFE(s, i) { \
+#define UTF8_SET_CHAR_START_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \
     while(UTF8_IS_TRAIL((s)[i])) { --(i); } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /** @deprecated ICU 2.4. Use U8_NEXT instead, see utf_old.h. */
-#define UTF8_NEXT_CHAR_SAFE(s, i, length, c, strict) { \
+#define UTF8_NEXT_CHAR_SAFE(s, i, length, c, strict) UPRV_BLOCK_MACRO_BEGIN { \
     (c)=(s)[(i)++]; \
     if((c)>=0x80) { \
         if(UTF8_IS_LEAD(c)) { \
@@ -411,16 +444,16 @@
             (c)=UTF8_ERROR_VALUE_1; \
         } \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /** @deprecated ICU 2.4. Use U8_APPEND instead, see utf_old.h. */
-#define UTF8_APPEND_CHAR_SAFE(s, i, length, c)  { \
+#define UTF8_APPEND_CHAR_SAFE(s, i, length, c)  UPRV_BLOCK_MACRO_BEGIN { \
     if((uint32_t)(c)<=0x7f) { \
         (s)[(i)++]=(uint8_t)(c); \
     } else { \
         (i)=utf8_appendCharSafeBody(s, (int32_t)(i), (int32_t)(length), c, NULL); \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /** @deprecated ICU 2.4. Renamed to U8_FWD_1, see utf_old.h. */
 #define UTF8_FWD_1_SAFE(s, i, length) U8_FWD_1(s, i, length)
@@ -432,7 +465,7 @@
 #define UTF8_SET_CHAR_START_SAFE(s, start, i) U8_SET_CP_START(s, start, i)
 
 /** @deprecated ICU 2.4. Renamed to U8_PREV_UNSAFE, see utf_old.h. */
-#define UTF8_PREV_CHAR_UNSAFE(s, i, c) { \
+#define UTF8_PREV_CHAR_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \
     (c)=(s)[--(i)]; \
     if(UTF8_IS_TRAIL(c)) { \
         uint8_t __b, __count=1, __shift=6; \
@@ -452,30 +485,30 @@
             } \
         } \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /** @deprecated ICU 2.4. Renamed to U8_BACK_1_UNSAFE, see utf_old.h. */
-#define UTF8_BACK_1_UNSAFE(s, i) { \
+#define UTF8_BACK_1_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \
     while(UTF8_IS_TRAIL((s)[--(i)])) {} \
-}
+} UPRV_BLOCK_MACRO_END
 
 /** @deprecated ICU 2.4. Renamed to U8_BACK_N_UNSAFE, see utf_old.h. */
-#define UTF8_BACK_N_UNSAFE(s, i, n) { \
+#define UTF8_BACK_N_UNSAFE(s, i, n) UPRV_BLOCK_MACRO_BEGIN { \
     int32_t __N=(n); \
     while(__N>0) { \
         UTF8_BACK_1_UNSAFE(s, i); \
         --__N; \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /** @deprecated ICU 2.4. Renamed to U8_SET_CP_LIMIT_UNSAFE, see utf_old.h. */
-#define UTF8_SET_CHAR_LIMIT_UNSAFE(s, i) { \
+#define UTF8_SET_CHAR_LIMIT_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \
     UTF8_BACK_1_UNSAFE(s, i); \
     UTF8_FWD_1_UNSAFE(s, i); \
-}
+} UPRV_BLOCK_MACRO_END
 
 /** @deprecated ICU 2.4. Use U8_PREV instead, see utf_old.h. */
-#define UTF8_PREV_CHAR_SAFE(s, start, i, c, strict) { \
+#define UTF8_PREV_CHAR_SAFE(s, start, i, c, strict) UPRV_BLOCK_MACRO_BEGIN { \
     (c)=(s)[--(i)]; \
     if((c)>=0x80) { \
         if((c)<=0xbf) { \
@@ -484,7 +517,7 @@
             (c)=UTF8_ERROR_VALUE_1; \
         } \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /** @deprecated ICU 2.4. Renamed to U8_BACK_1, see utf_old.h. */
 #define UTF8_BACK_1_SAFE(s, start, i) U8_BACK_1(s, start, i)
@@ -557,7 +590,7 @@
  * UTF16_PREV_CHAR[_UNSAFE]() is more efficient for that.
  * @deprecated ICU 2.4. Renamed to U16_GET_UNSAFE, see utf_old.h.
  */
-#define UTF16_GET_CHAR_UNSAFE(s, i, c) { \
+#define UTF16_GET_CHAR_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \
     (c)=(s)[i]; \
     if(UTF_IS_SURROGATE(c)) { \
         if(UTF_IS_SURROGATE_FIRST(c)) { \
@@ -566,10 +599,10 @@
             (c)=UTF16_GET_PAIR_VALUE((s)[(i)-1], (c)); \
         } \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /** @deprecated ICU 2.4. Use U16_GET instead, see utf_old.h. */
-#define UTF16_GET_CHAR_SAFE(s, start, i, length, c, strict) { \
+#define UTF16_GET_CHAR_SAFE(s, start, i, length, c, strict) UPRV_BLOCK_MACRO_BEGIN { \
     (c)=(s)[i]; \
     if(UTF_IS_SURROGATE(c)) { \
         uint16_t __c2; \
@@ -593,51 +626,51 @@
     } else if((strict) && !UTF_IS_UNICODE_CHAR(c)) { \
         (c)=UTF_ERROR_VALUE; \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /** @deprecated ICU 2.4. Renamed to U16_NEXT_UNSAFE, see utf_old.h. */
-#define UTF16_NEXT_CHAR_UNSAFE(s, i, c) { \
+#define UTF16_NEXT_CHAR_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \
     (c)=(s)[(i)++]; \
     if(UTF_IS_FIRST_SURROGATE(c)) { \
         (c)=UTF16_GET_PAIR_VALUE((c), (s)[(i)++]); \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /** @deprecated ICU 2.4. Renamed to U16_APPEND_UNSAFE, see utf_old.h. */
-#define UTF16_APPEND_CHAR_UNSAFE(s, i, c) { \
+#define UTF16_APPEND_CHAR_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \
     if((uint32_t)(c)<=0xffff) { \
         (s)[(i)++]=(uint16_t)(c); \
     } else { \
         (s)[(i)++]=(uint16_t)(((c)>>10)+0xd7c0); \
         (s)[(i)++]=(uint16_t)(((c)&0x3ff)|0xdc00); \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /** @deprecated ICU 2.4. Renamed to U16_FWD_1_UNSAFE, see utf_old.h. */
-#define UTF16_FWD_1_UNSAFE(s, i) { \
+#define UTF16_FWD_1_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \
     if(UTF_IS_FIRST_SURROGATE((s)[(i)++])) { \
         ++(i); \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /** @deprecated ICU 2.4. Renamed to U16_FWD_N_UNSAFE, see utf_old.h. */
-#define UTF16_FWD_N_UNSAFE(s, i, n) { \
+#define UTF16_FWD_N_UNSAFE(s, i, n) UPRV_BLOCK_MACRO_BEGIN { \
     int32_t __N=(n); \
     while(__N>0) { \
         UTF16_FWD_1_UNSAFE(s, i); \
         --__N; \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /** @deprecated ICU 2.4. Renamed to U16_SET_CP_START_UNSAFE, see utf_old.h. */
-#define UTF16_SET_CHAR_START_UNSAFE(s, i) { \
+#define UTF16_SET_CHAR_START_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \
     if(UTF_IS_SECOND_SURROGATE((s)[i])) { \
         --(i); \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /** @deprecated ICU 2.4. Use U16_NEXT instead, see utf_old.h. */
-#define UTF16_NEXT_CHAR_SAFE(s, i, length, c, strict) { \
+#define UTF16_NEXT_CHAR_SAFE(s, i, length, c, strict) UPRV_BLOCK_MACRO_BEGIN { \
     (c)=(s)[(i)++]; \
     if(UTF_IS_FIRST_SURROGATE(c)) { \
         uint16_t __c2; \
@@ -653,10 +686,10 @@
         /* unmatched second surrogate or other non-character */ \
         (c)=UTF_ERROR_VALUE; \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /** @deprecated ICU 2.4. Use U16_APPEND instead, see utf_old.h. */
-#define UTF16_APPEND_CHAR_SAFE(s, i, length, c) { \
+#define UTF16_APPEND_CHAR_SAFE(s, i, length, c) UPRV_BLOCK_MACRO_BEGIN { \
     if((uint32_t)(c)<=0xffff) { \
         (s)[(i)++]=(uint16_t)(c); \
     } else if((uint32_t)(c)<=0x10ffff) { \
@@ -669,7 +702,7 @@
     } else /* c>0x10ffff, write error value */ { \
         (s)[(i)++]=UTF_ERROR_VALUE; \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /** @deprecated ICU 2.4. Renamed to U16_FWD_1, see utf_old.h. */
 #define UTF16_FWD_1_SAFE(s, i, length) U16_FWD_1(s, i, length)
@@ -681,38 +714,38 @@
 #define UTF16_SET_CHAR_START_SAFE(s, start, i) U16_SET_CP_START(s, start, i)
 
 /** @deprecated ICU 2.4. Renamed to U16_PREV_UNSAFE, see utf_old.h. */
-#define UTF16_PREV_CHAR_UNSAFE(s, i, c) { \
+#define UTF16_PREV_CHAR_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \
     (c)=(s)[--(i)]; \
     if(UTF_IS_SECOND_SURROGATE(c)) { \
         (c)=UTF16_GET_PAIR_VALUE((s)[--(i)], (c)); \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /** @deprecated ICU 2.4. Renamed to U16_BACK_1_UNSAFE, see utf_old.h. */
-#define UTF16_BACK_1_UNSAFE(s, i) { \
+#define UTF16_BACK_1_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \
     if(UTF_IS_SECOND_SURROGATE((s)[--(i)])) { \
         --(i); \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /** @deprecated ICU 2.4. Renamed to U16_BACK_N_UNSAFE, see utf_old.h. */
-#define UTF16_BACK_N_UNSAFE(s, i, n) { \
+#define UTF16_BACK_N_UNSAFE(s, i, n) UPRV_BLOCK_MACRO_BEGIN { \
     int32_t __N=(n); \
     while(__N>0) { \
         UTF16_BACK_1_UNSAFE(s, i); \
         --__N; \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /** @deprecated ICU 2.4. Renamed to U16_SET_CP_LIMIT_UNSAFE, see utf_old.h. */
-#define UTF16_SET_CHAR_LIMIT_UNSAFE(s, i) { \
+#define UTF16_SET_CHAR_LIMIT_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \
     if(UTF_IS_FIRST_SURROGATE((s)[(i)-1])) { \
         ++(i); \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /** @deprecated ICU 2.4. Use U16_PREV instead, see utf_old.h. */
-#define UTF16_PREV_CHAR_SAFE(s, start, i, c, strict) { \
+#define UTF16_PREV_CHAR_SAFE(s, start, i, c, strict) UPRV_BLOCK_MACRO_BEGIN { \
     (c)=(s)[--(i)]; \
     if(UTF_IS_SECOND_SURROGATE(c)) { \
         uint16_t __c2; \
@@ -728,7 +761,7 @@
         /* unmatched first surrogate or other non-character */ \
         (c)=UTF_ERROR_VALUE; \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /** @deprecated ICU 2.4. Renamed to U16_BACK_1, see utf_old.h. */
 #define UTF16_BACK_1_SAFE(s, start, i) U16_BACK_1(s, start, i)
@@ -794,122 +827,122 @@
 #define UTF32_ARRAY_SIZE(size) (size)
 
 /** @deprecated ICU 2.4. Obsolete, see utf_old.h. */
-#define UTF32_GET_CHAR_UNSAFE(s, i, c) { \
+#define UTF32_GET_CHAR_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \
     (c)=(s)[i]; \
-}
+} UPRV_BLOCK_MACRO_END
 
 /** @deprecated ICU 2.4. Obsolete, see utf_old.h. */
-#define UTF32_GET_CHAR_SAFE(s, start, i, length, c, strict) { \
+#define UTF32_GET_CHAR_SAFE(s, start, i, length, c, strict) UPRV_BLOCK_MACRO_BEGIN { \
     (c)=(s)[i]; \
     if(!UTF32_IS_SAFE(c, strict)) { \
         (c)=UTF_ERROR_VALUE; \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /* definitions with forward iteration --------------------------------------- */
 
 /** @deprecated ICU 2.4. Obsolete, see utf_old.h. */
-#define UTF32_NEXT_CHAR_UNSAFE(s, i, c) { \
+#define UTF32_NEXT_CHAR_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \
     (c)=(s)[(i)++]; \
-}
+} UPRV_BLOCK_MACRO_END
 
 /** @deprecated ICU 2.4. Obsolete, see utf_old.h. */
-#define UTF32_APPEND_CHAR_UNSAFE(s, i, c) { \
+#define UTF32_APPEND_CHAR_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \
     (s)[(i)++]=(c); \
-}
+} UPRV_BLOCK_MACRO_END
 
 /** @deprecated ICU 2.4. Obsolete, see utf_old.h. */
-#define UTF32_FWD_1_UNSAFE(s, i) { \
+#define UTF32_FWD_1_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \
     ++(i); \
-}
+} UPRV_BLOCK_MACRO_END
 
 /** @deprecated ICU 2.4. Obsolete, see utf_old.h. */
-#define UTF32_FWD_N_UNSAFE(s, i, n) { \
+#define UTF32_FWD_N_UNSAFE(s, i, n) UPRV_BLOCK_MACRO_BEGIN { \
     (i)+=(n); \
-}
+} UPRV_BLOCK_MACRO_END
 
 /** @deprecated ICU 2.4. Obsolete, see utf_old.h. */
-#define UTF32_SET_CHAR_START_UNSAFE(s, i) { \
-}
+#define UTF32_SET_CHAR_START_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \
+} UPRV_BLOCK_MACRO_END
 
 /** @deprecated ICU 2.4. Obsolete, see utf_old.h. */
-#define UTF32_NEXT_CHAR_SAFE(s, i, length, c, strict) { \
+#define UTF32_NEXT_CHAR_SAFE(s, i, length, c, strict) UPRV_BLOCK_MACRO_BEGIN { \
     (c)=(s)[(i)++]; \
     if(!UTF32_IS_SAFE(c, strict)) { \
         (c)=UTF_ERROR_VALUE; \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /** @deprecated ICU 2.4. Obsolete, see utf_old.h. */
-#define UTF32_APPEND_CHAR_SAFE(s, i, length, c) { \
+#define UTF32_APPEND_CHAR_SAFE(s, i, length, c) UPRV_BLOCK_MACRO_BEGIN { \
     if((uint32_t)(c)<=0x10ffff) { \
         (s)[(i)++]=(c); \
     } else /* c>0x10ffff, write 0xfffd */ { \
         (s)[(i)++]=0xfffd; \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /** @deprecated ICU 2.4. Obsolete, see utf_old.h. */
-#define UTF32_FWD_1_SAFE(s, i, length) { \
+#define UTF32_FWD_1_SAFE(s, i, length) UPRV_BLOCK_MACRO_BEGIN { \
     ++(i); \
-}
+} UPRV_BLOCK_MACRO_END
 
 /** @deprecated ICU 2.4. Obsolete, see utf_old.h. */
-#define UTF32_FWD_N_SAFE(s, i, length, n) { \
+#define UTF32_FWD_N_SAFE(s, i, length, n) UPRV_BLOCK_MACRO_BEGIN { \
     if(((i)+=(n))>(length)) { \
         (i)=(length); \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /** @deprecated ICU 2.4. Obsolete, see utf_old.h. */
-#define UTF32_SET_CHAR_START_SAFE(s, start, i) { \
-}
+#define UTF32_SET_CHAR_START_SAFE(s, start, i) UPRV_BLOCK_MACRO_BEGIN { \
+} UPRV_BLOCK_MACRO_END
 
 /* definitions with backward iteration -------------------------------------- */
 
 /** @deprecated ICU 2.4. Obsolete, see utf_old.h. */
-#define UTF32_PREV_CHAR_UNSAFE(s, i, c) { \
+#define UTF32_PREV_CHAR_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \
     (c)=(s)[--(i)]; \
-}
+} UPRV_BLOCK_MACRO_END
 
 /** @deprecated ICU 2.4. Obsolete, see utf_old.h. */
-#define UTF32_BACK_1_UNSAFE(s, i) { \
+#define UTF32_BACK_1_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \
     --(i); \
-}
+} UPRV_BLOCK_MACRO_END
 
 /** @deprecated ICU 2.4. Obsolete, see utf_old.h. */
-#define UTF32_BACK_N_UNSAFE(s, i, n) { \
+#define UTF32_BACK_N_UNSAFE(s, i, n) UPRV_BLOCK_MACRO_BEGIN { \
     (i)-=(n); \
-}
+} UPRV_BLOCK_MACRO_END
 
 /** @deprecated ICU 2.4. Obsolete, see utf_old.h. */
-#define UTF32_SET_CHAR_LIMIT_UNSAFE(s, i) { \
-}
+#define UTF32_SET_CHAR_LIMIT_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \
+} UPRV_BLOCK_MACRO_END
 
 /** @deprecated ICU 2.4. Obsolete, see utf_old.h. */
-#define UTF32_PREV_CHAR_SAFE(s, start, i, c, strict) { \
+#define UTF32_PREV_CHAR_SAFE(s, start, i, c, strict) UPRV_BLOCK_MACRO_BEGIN { \
     (c)=(s)[--(i)]; \
     if(!UTF32_IS_SAFE(c, strict)) { \
         (c)=UTF_ERROR_VALUE; \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /** @deprecated ICU 2.4. Obsolete, see utf_old.h. */
-#define UTF32_BACK_1_SAFE(s, start, i) { \
+#define UTF32_BACK_1_SAFE(s, start, i) UPRV_BLOCK_MACRO_BEGIN { \
     --(i); \
-}
+} UPRV_BLOCK_MACRO_END
 
 /** @deprecated ICU 2.4. Obsolete, see utf_old.h. */
-#define UTF32_BACK_N_SAFE(s, start, i, n) { \
+#define UTF32_BACK_N_SAFE(s, start, i, n) UPRV_BLOCK_MACRO_BEGIN { \
     (i)-=(n); \
     if((i)<(start)) { \
         (i)=(start); \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /** @deprecated ICU 2.4. Obsolete, see utf_old.h. */
-#define UTF32_SET_CHAR_LIMIT_SAFE(s, i, length) { \
-}
+#define UTF32_SET_CHAR_LIMIT_SAFE(s, i, length) UPRV_BLOCK_MACRO_BEGIN { \
+} UPRV_BLOCK_MACRO_END
 
 /* Formerly utf.h, part 2 --------------------------------------------------- */
 
@@ -1163,7 +1196,6 @@
  */
 #define UTF_SET_CHAR_LIMIT(s, start, i, length) U16_SET_CP_LIMIT(s, start, i, length)
 
-#endif /* U_HIDE_DEPRECATED_API */
+#endif  // !U_HIDE_DEPRECATED_API && !U_HIDE_OBSOLETE_UTF_OLD_H
 
 #endif
-
diff --git a/src/third_party/icu/source/common/unicode/utrace.h b/src/third_party/icu/source/common/unicode/utrace.h
index 8860366..6ca252f 100644
--- a/src/third_party/icu/source/common/unicode/utrace.h
+++ b/src/third_party/icu/source/common/unicode/utrace.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  utrace.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -66,7 +68,14 @@
     UTRACE_FUNCTION_START=0,
     UTRACE_U_INIT=UTRACE_FUNCTION_START,
     UTRACE_U_CLEANUP,
+
+#ifndef U_HIDE_DEPRECATED_API
+    /**
+     * One more than the highest normal collation trace location.
+     * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
+     */
     UTRACE_FUNCTION_LIMIT,
+#endif  // U_HIDE_DEPRECATED_API
 
     UTRACE_CONVERSION_START=0x1000,
     UTRACE_UCNV_OPEN=UTRACE_CONVERSION_START,
@@ -77,7 +86,14 @@
     UTRACE_UCNV_FLUSH_CACHE,
     UTRACE_UCNV_LOAD,
     UTRACE_UCNV_UNLOAD,
+
+#ifndef U_HIDE_DEPRECATED_API
+    /**
+     * One more than the highest normal collation trace location.
+     * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
+     */
     UTRACE_CONVERSION_LIMIT,
+#endif  // U_HIDE_DEPRECATED_API
 
     UTRACE_COLLATION_START=0x2000,
     UTRACE_UCOL_OPEN=UTRACE_COLLATION_START,
@@ -89,7 +105,141 @@
     UTRACE_UCOL_STRCOLLITER,
     UTRACE_UCOL_OPEN_FROM_SHORT_STRING,
     UTRACE_UCOL_STRCOLLUTF8, /**< @stable ICU 50 */
-    UTRACE_COLLATION_LIMIT
+
+#ifndef U_HIDE_DEPRECATED_API
+    /**
+     * One more than the highest normal collation trace location.
+     * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
+     */
+    UTRACE_COLLATION_LIMIT,
+#endif  // U_HIDE_DEPRECATED_API
+
+    /**
+     * The lowest resource/data location.
+     * @stable ICU 65
+     */
+    UTRACE_UDATA_START=0x3000,
+
+    /**
+     * Indicates that a value was read from a resource bundle. Provides three
+     * C-style strings to UTraceData: type, file name, and resource path. The
+     * possible types are:
+     *
+     * - "string" (a string value was accessed)
+     * - "binary" (a binary value was accessed)
+     * - "intvector" (a integer vector value was accessed)
+     * - "int" (a signed integer value was accessed)
+     * - "uint" (a unsigned integer value was accessed)
+     * - "get" (a path was loaded, but the value was not accessed)
+     * - "getalias" (a path was loaded, and an alias was resolved)
+     *
+     * @stable ICU 65
+     */
+    UTRACE_UDATA_RESOURCE=UTRACE_UDATA_START,
+
+    /**
+     * Indicates that a resource bundle was opened.
+     *
+     * Provides one C-style string to UTraceData: file name.
+     * @stable ICU 65
+     */
+    UTRACE_UDATA_BUNDLE,
+
+    /**
+     * Indicates that a data file was opened, but not *.res files.
+     *
+     * Provides one C-style string to UTraceData: file name.
+     *
+     * @stable ICU 65
+     */
+    UTRACE_UDATA_DATA_FILE,
+
+    /**
+     * Indicates that a *.res file was opened.
+     *
+     * This differs from UTRACE_UDATA_BUNDLE because a res file is typically
+     * opened only once per application runtime, but the bundle corresponding
+     * to that res file may be opened many times.
+     *
+     * Provides one C-style string to UTraceData: file name.
+     *
+     * @stable ICU 65
+     */
+    UTRACE_UDATA_RES_FILE,
+
+#ifndef U_HIDE_INTERNAL_API
+    /**
+     * One more than the highest normal resource/data trace location.
+     * @internal The numeric value may change over time, see ICU ticket #12420.
+     */
+    UTRACE_RES_DATA_LIMIT,
+#endif  // U_HIDE_INTERNAL_API
+
+#ifndef U_HIDE_DRAFT_API
+    /**
+     * The lowest break iterator location.
+     * @draft ICU 67
+     */
+    UTRACE_UBRK_START=0x4000,
+
+    /**
+     * Indicates that a character instance of break iterator was created.
+     *
+     * @draft ICU 67
+     */
+    UTRACE_UBRK_CREATE_CHARACTER = UTRACE_UBRK_START,
+
+    /**
+     * Indicates that a word instance of break iterator was created.
+     *
+     * @draft ICU 67
+     */
+    UTRACE_UBRK_CREATE_WORD,
+
+    /**
+     * Indicates that a line instance of break iterator was created.
+     *
+     * Provides one C-style string to UTraceData: the lb value ("",
+     * "loose", "strict", or "normal").
+     *
+     * @draft ICU 67
+     */
+    UTRACE_UBRK_CREATE_LINE,
+
+    /**
+     * Indicates that a sentence instance of break iterator was created.
+     *
+     * @draft ICU 67
+     */
+    UTRACE_UBRK_CREATE_SENTENCE,
+
+    /**
+     * Indicates that a title instance of break iterator was created.
+     *
+     * @draft ICU 67
+     */
+    UTRACE_UBRK_CREATE_TITLE,
+
+    /**
+     * Indicates that an internal dictionary break engine was created.
+     *
+     * Provides one C-style string to UTraceData: the script code of what
+     * the break engine cover ("Hani", "Khmr", "Laoo", "Mymr", or "Thai").
+     *
+     * @draft ICU 67
+     */
+    UTRACE_UBRK_CREATE_BREAK_ENGINE,
+
+#endif  // U_HIDE_DRAFT_API
+
+#ifndef U_HIDE_INTERNAL_API
+    /**
+     * One more than the highest normal break iterator trace location.
+     * @internal The numeric value may change over time, see ICU ticket #12420.
+     */
+    UTRACE_UBRK_LIMIT,
+#endif  // U_HIDE_INTERNAL_API
+
 } UTraceFunctionNumber;
 
 /**
@@ -97,7 +247,7 @@
  * @param traceLevel A UTraceLevel value.
  * @stable ICU 2.8
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 utrace_setLevel(int32_t traceLevel);
 
 /**
@@ -105,7 +255,7 @@
  * @return The UTraceLevel value being used by ICU.
  * @stable ICU 2.8
  */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 utrace_getLevel(void);
 
 /* Trace function pointers types  ----------------------------- */
@@ -165,7 +315,7 @@
   *  tracing functions must themselves filter by checking that the
   *  current thread is the desired thread.
   *
-  *  @param context an uninterpretted pointer.  Whatever is passed in
+  *  @param context an uninterpreted pointer.  Whatever is passed in
   *                 here will in turn be passed to each of the tracing
   *                 functions UTraceEntry, UTraceExit and UTraceData.
   *                 ICU does not use or alter this pointer.
@@ -179,7 +329,7 @@
   *
   *  @stable ICU 2.8
   */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 utrace_setFunctions(const void *context,
                     UTraceEntry *e, UTraceExit *x, UTraceData *d);
 
@@ -193,7 +343,7 @@
   * @param d        The currently installed UTraceData function.
   * @stable ICU 2.8
   */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 utrace_getFunctions(const void **context,
                     UTraceEntry **e, UTraceExit **x, UTraceData **d);
 
@@ -302,7 +452,7 @@
   *                 human readable form.  Note that a UTraceData function may choose
   *                 to not format the data;  it could, for example, save it in
   *                 in the raw form it was received (more compact), leaving
-  *                 formatting for a later trace analyis tool.
+  *                 formatting for a later trace analysis tool.
   *  @param outBuf  pointer to a buffer to receive the formatted output.  Output
   *                 will be nul terminated if there is space in the buffer -
   *                 if the length of the requested output < the output buffer size.
@@ -315,7 +465,7 @@
   *                 If buffer capacity is insufficient, the required capacity is returned. 
   *  @stable ICU 2.8
   */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 utrace_vformat(char *outBuf, int32_t capacity,
               int32_t indent, const char *fmt,  va_list args);
 
@@ -336,7 +486,7 @@
   *                 If buffer capacity is insufficient, the required capacity is returned. 
   *  @stable ICU 2.8
   */
-U_STABLE int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 utrace_format(char *outBuf, int32_t capacity,
               int32_t indent, const char *fmt,  ...);
 
@@ -353,7 +503,7 @@
  * @see UTraceFunctionNumber
  * @stable ICU 2.8
  */
-U_STABLE const char * U_EXPORT2
+U_CAPI const char * U_EXPORT2
 utrace_functionName(int32_t fnNumber);
 
 U_CDECL_END
diff --git a/src/third_party/icu/source/common/unicode/utypes.h b/src/third_party/icu/source/common/unicode/utypes.h
index 8eee26a..89ed56d 100644
--- a/src/third_party/icu/source/common/unicode/utypes.h
+++ b/src/third_party/icu/source/common/unicode/utypes.h
@@ -1,6 +1,8 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
-*   Copyright (C) 1996-2015, International Business Machines
+*   Copyright (C) 1996-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 **********************************************************************
 *
@@ -145,7 +147,7 @@
 /**
  *  U_ICU_ENTRY_POINT is the name of the DLL entry point to the ICU data library.
  *    Defined as a literal, not a string.
- *    Tricky Preprocessor use - ## operator replaces macro paramters with the literal string
+ *    Tricky Preprocessor use - ## operator replaces macro parameters with the literal string
  *                              from the corresponding macro invocation, _before_ other macro substitutions.
  *                              Need a nested \#defines to get the actual version numbers rather than
  *                              the literal text U_ICU_VERSION_MAJOR_NUM into the name.
@@ -178,12 +180,12 @@
 
 /**
  * \def NULL
- * Define NULL if necessary, to 0 for C++ and to ((void *)0) for C.
+ * Define NULL if necessary, to nullptr for C++ and to ((void *)0) for C.
  * @stable ICU 2.0
  */
 #ifndef NULL
 #ifdef __cplusplus
-#define NULL    0
+#define NULL    nullptr
 #else
 #define NULL    ((void *)0)
 #endif
@@ -290,6 +292,11 @@
  * @stable ICU 3.4
  */
 
+#ifdef U_IN_DOXYGEN
+// This definition is required when generating the API docs.
+#define U_COMBINED_IMPLEMENTATION 1
+#endif
+
 #if defined(U_COMBINED_IMPLEMENTATION)
 #define U_DATA_API     U_EXPORT
 #define U_COMMON_API   U_EXPORT
@@ -379,104 +386,36 @@
 #define U_STANDARD_CPP_NAMESPACE
 #endif
 
-
-/*===========================================================================*/
-/* Global delete operator                                                    */
-/*===========================================================================*/
-
-/*
- * The ICU4C library must not use the global new and delete operators.
- * These operators here are defined to enable testing for this.
- * See Jitterbug 2581 for details of why this is necessary.
- *
- * Verification that ICU4C's memory usage is correct, i.e.,
- * that global new/delete are not used:
- *
- * a) Check for imports of global new/delete (see uobject.cpp for details)
- * b) Verify that new is never imported.
- * c) Verify that delete is only imported from object code for interface/mixin classes.
- * d) Add global delete and delete[] only for the ICU4C library itself
- *    and define them in a way that crashes or otherwise easily shows a problem.
- *
- * The following implements d).
- * The operator implementations crash; this is intentional and used for library debugging.
- *
- * Note: This is currently only done on Windows because
- * some Linux/Unix compilers have problems with defining global new/delete.
- * On Windows, it is _MSC_VER>=1200 for MSVC 6.0 and higher.
- */
-#if defined(__cplusplus) && U_DEBUG && U_OVERRIDE_CXX_ALLOCATION && (_MSC_VER>=1200) && !defined(U_STATIC_IMPLEMENTATION) && (defined(U_COMMON_IMPLEMENTATION) || defined(U_I18N_IMPLEMENTATION) || defined(U_IO_IMPLEMENTATION) || defined(U_LAYOUT_IMPLEMENTATION) || defined(U_LAYOUTEX_IMPLEMENTATION))
-
-#ifndef U_HIDE_INTERNAL_API
-/**
- * Global operator new, defined only inside ICU4C, must not be used.
- * Crashes intentionally.
- * @internal
- */
-inline void *
-operator new(size_t /*size*/) {
-    char *q=NULL;
-    *q=5; /* break it */
-    return q;
-}
-
-#ifdef _Ret_bytecap_
-/* This is only needed to suppress a Visual C++ 2008 warning for operator new[]. */
-_Ret_bytecap_(_Size)
-#endif
-/**
- * Global operator new[], defined only inside ICU4C, must not be used.
- * Crashes intentionally.
- * @internal
- */
-inline void *
-operator new[](size_t /*size*/) {
-    char *q=NULL;
-    *q=5; /* break it */
-    return q;
-}
-
-/**
- * Global operator delete, defined only inside ICU4C, must not be used.
- * Crashes intentionally.
- * @internal
- */
-inline void
-operator delete(void * /*p*/) {
-    char *q=NULL;
-    *q=5; /* break it */
-}
-
-/**
- * Global operator delete[], defined only inside ICU4C, must not be used.
- * Crashes intentionally.
- * @internal
- */
-inline void
-operator delete[](void * /*p*/) {
-    char *q=NULL;
-    *q=5; /* break it */
-}
-
-#endif /* U_HIDE_INTERNAL_API */
-#endif
-
 /*===========================================================================*/
 /* UErrorCode */
 /*===========================================================================*/
 
 /**
- * Error code to replace exception handling, so that the code is compatible with all C++ compilers,
- * and to use the same mechanism for C and C++.
+ * Standard ICU4C error code type, a substitute for exceptions.
  *
- * \par
- * ICU functions that take a reference (C++) or a pointer (C) to a UErrorCode
- * first test if(U_FAILURE(errorCode)) { return immediately; }
+ * Initialize the UErrorCode with U_ZERO_ERROR, and check for success or
+ * failure using U_SUCCESS() or U_FAILURE():
+ *
+ *     UErrorCode errorCode = U_ZERO_ERROR;
+ *     // call ICU API that needs an error code parameter.
+ *     if (U_FAILURE(errorCode)) {
+ *         // An error occurred. Handle it here.
+ *     }
+ *
+ * C++ code should use icu::ErrorCode, available in unicode/errorcode.h, or a
+ * suitable subclass.
+ *
+ * For more information, see:
+ * http://icu-project.org/userguide/conventions
+ *
+ * Note: By convention, ICU functions that take a reference (C++) or a pointer
+ * (C) to a UErrorCode first test:
+ *
+ *     if (U_FAILURE(errorCode)) { return immediately; }
+ *
  * so that in a chain of such functions the first one that sets an error code
  * causes the following ones to not perform any operations.
  *
- * \par
- * Error codes should be tested using U_FAILURE() and U_SUCCESS().
  * @stable ICU 2.0
  */
 typedef enum UErrorCode {
@@ -505,8 +444,13 @@
     
     U_PLUGIN_CHANGED_LEVEL_WARNING = -120, /**< A plugin caused a level change. May not be an error, but later plugins may not load. */
 
-    U_ERROR_WARNING_LIMIT,              /**< This must always be the last warning value to indicate the limit for UErrorCode warnings (last warning code +1) */
-
+#ifndef U_HIDE_DEPRECATED_API
+    /**
+     * One more than the highest normal UErrorCode warning value.
+     * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
+     */
+    U_ERROR_WARNING_LIMIT,
+#endif  // U_HIDE_DEPRECATED_API
 
     U_ZERO_ERROR              =  0,     /**< No error, no warning. */
 
@@ -527,24 +471,41 @@
     U_BUFFER_OVERFLOW_ERROR   = 15,     /**< A result would not fit in the supplied buffer */
     U_UNSUPPORTED_ERROR       = 16,     /**< Requested operation not supported in current context */
     U_RESOURCE_TYPE_MISMATCH  = 17,     /**< an operation is requested over a resource that does not support it */
-    U_ILLEGAL_ESCAPE_SEQUENCE = 18,     /**< ISO-2022 illlegal escape sequence */
+    U_ILLEGAL_ESCAPE_SEQUENCE = 18,     /**< ISO-2022 illegal escape sequence */
     U_UNSUPPORTED_ESCAPE_SEQUENCE = 19, /**< ISO-2022 unsupported escape sequence */
     U_NO_SPACE_AVAILABLE      = 20,     /**< No space available for in-buffer expansion for Arabic shaping */
     U_CE_NOT_FOUND_ERROR      = 21,     /**< Currently used only while setting variable top, but can be used generally */
     U_PRIMARY_TOO_LONG_ERROR  = 22,     /**< User tried to set variable top to a primary that is longer than two bytes */
     U_STATE_TOO_OLD_ERROR     = 23,     /**< ICU cannot construct a service from this state, as it is no longer supported */
     U_TOO_MANY_ALIASES_ERROR  = 24,     /**< There are too many aliases in the path to the requested resource.
-                                             It is very possible that a circular alias definition has occured */
+                                             It is very possible that a circular alias definition has occurred */
     U_ENUM_OUT_OF_SYNC_ERROR  = 25,     /**< UEnumeration out of sync with underlying collection */
     U_INVARIANT_CONVERSION_ERROR = 26,  /**< Unable to convert a UChar* string to char* with the invariant converter. */
     U_INVALID_STATE_ERROR     = 27,     /**< Requested operation can not be completed with ICU in its current state */
     U_COLLATOR_VERSION_MISMATCH = 28,   /**< Collator version is not compatible with the base version */
     U_USELESS_COLLATOR_ERROR  = 29,     /**< Collator is options only and no base is specified */
     U_NO_WRITE_PERMISSION     = 30,     /**< Attempt to modify read-only or constant data. */
+#ifndef U_HIDE_DRAFT_API
+    /**
+     * The input is impractically long for an operation.
+     * It is rejected because it may lead to problems such as excessive
+     * processing time, stack depth, or heap memory requirements.
+     *
+     * @draft ICU 68
+     */
+    U_INPUT_TOO_LONG_ERROR = 31,
+#endif  // U_HIDE_DRAFT_API
 
-    U_STANDARD_ERROR_LIMIT,             /**< This must always be the last value to indicate the limit for standard errors */
+#ifndef U_HIDE_DEPRECATED_API
+    /**
+     * One more than the highest standard error code.
+     * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
+     */
+    U_STANDARD_ERROR_LIMIT = 32,
+#endif  // U_HIDE_DEPRECATED_API
+
     /*
-     * the error code range 0x10000 0x10100 are reserved for Transliterator
+     * Error codes in the range 0x10000 0x10100 are reserved for Transliterator.
      */
     U_BAD_VARIABLE_DEFINITION=0x10000,/**< Missing '$' or duplicate variable name */
     U_PARSE_ERROR_START = 0x10000,    /**< Start of Transliterator errors */
@@ -573,7 +534,7 @@
     U_MULTIPLE_COMPOUND_FILTERS,      /**< More than one compound filter */
     U_INVALID_RBT_SYNTAX,             /**< A "::id" rule was passed to the RuleBasedTransliterator parser */
     U_INVALID_PROPERTY_PATTERN,       /**< UNUSED as of ICU 2.4 */
-    U_MALFORMED_PRAGMA,               /**< A 'use' pragma is invlalid */
+    U_MALFORMED_PRAGMA,               /**< A 'use' pragma is invalid */
     U_UNCLOSED_SEGMENT,               /**< A closing ')' is missing */
     U_ILLEGAL_CHAR_IN_SEGMENT,        /**< UNUSED as of ICU 2.4 */
     U_VARIABLE_RANGE_EXHAUSTED,       /**< Too many stand-ins generated for the given variable range */
@@ -582,10 +543,16 @@
     U_INTERNAL_TRANSLITERATOR_ERROR,  /**< Internal transliterator system error */
     U_INVALID_ID,                     /**< A "::id" rule specifies an unknown transliterator */
     U_INVALID_FUNCTION,               /**< A "&fn()" rule specifies an unknown transliterator */
-    U_PARSE_ERROR_LIMIT,              /**< The limit for Transliterator errors */
+#ifndef U_HIDE_DEPRECATED_API
+    /**
+     * One more than the highest normal Transliterator error code.
+     * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
+     */
+    U_PARSE_ERROR_LIMIT,
+#endif  // U_HIDE_DEPRECATED_API
 
     /*
-     * the error code range 0x10100 0x10200 are reserved for formatting API parsing error
+     * Error codes in the range 0x10100 0x10200 are reserved for the formatting API.
      */
     U_UNEXPECTED_TOKEN=0x10100,       /**< Syntax error in format pattern */
     U_FMT_PARSE_ERROR_START=0x10100,  /**< Start of format library errors */
@@ -607,17 +574,25 @@
     U_DEFAULT_KEYWORD_MISSING,        /**< Missing DEFAULT rule in plural rules */
     U_DECIMAL_NUMBER_SYNTAX_ERROR,    /**< Decimal number syntax error */
     U_FORMAT_INEXACT_ERROR,           /**< Cannot format a number exactly and rounding mode is ROUND_UNNECESSARY @stable ICU 4.8 */
-    U_FMT_PARSE_ERROR_LIMIT,          /**< The limit for format library errors */
+    U_NUMBER_ARG_OUTOFBOUNDS_ERROR,   /**< The argument to a NumberFormatter helper method was out of bounds; the bounds are usually 0 to 999. @stable ICU 61 */
+    U_NUMBER_SKELETON_SYNTAX_ERROR,   /**< The number skeleton passed to C++ NumberFormatter or C UNumberFormatter was invalid or contained a syntax error. @stable ICU 62 */
+#ifndef U_HIDE_DEPRECATED_API
+    /**
+     * One more than the highest normal formatting API error code.
+     * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
+     */
+    U_FMT_PARSE_ERROR_LIMIT = 0x10114,
+#endif  // U_HIDE_DEPRECATED_API
 
     /*
-     * the error code range 0x10200 0x102ff are reserved for Break Iterator related error
+     * Error codes in the range 0x10200 0x102ff are reserved for BreakIterator.
      */
     U_BRK_INTERNAL_ERROR=0x10200,          /**< An internal error (bug) was detected.             */
     U_BRK_ERROR_START=0x10200,             /**< Start of codes indicating Break Iterator failures */
     U_BRK_HEX_DIGITS_EXPECTED,             /**< Hex digits expected as part of a escaped char in a rule. */
     U_BRK_SEMICOLON_EXPECTED,              /**< Missing ';' at the end of a RBBI rule.            */
     U_BRK_RULE_SYNTAX,                     /**< Syntax error in RBBI rule.                        */
-    U_BRK_UNCLOSED_SET,                    /**< UnicodeSet witing an RBBI rule missing a closing ']'.  */
+    U_BRK_UNCLOSED_SET,                    /**< UnicodeSet writing an RBBI rule missing a closing ']'. */
     U_BRK_ASSIGN_ERROR,                    /**< Syntax error in RBBI rule assignment statement.   */
     U_BRK_VARIABLE_REDFINITION,            /**< RBBI rule $Variable redefined.                    */
     U_BRK_MISMATCHED_PAREN,                /**< Mis-matched parentheses in an RBBI rule.          */
@@ -626,11 +601,17 @@
     U_BRK_INIT_ERROR,                      /**< Initialization failure.  Probable missing ICU Data. */
     U_BRK_RULE_EMPTY_SET,                  /**< Rule contains an empty Unicode Set.               */
     U_BRK_UNRECOGNIZED_OPTION,             /**< !!option in RBBI rules not recognized.            */
-    U_BRK_MALFORMED_RULE_TAG,              /**< The {nnn} tag on a rule is mal formed             */
-    U_BRK_ERROR_LIMIT,                     /**< This must always be the last value to indicate the limit for Break Iterator failures */
+    U_BRK_MALFORMED_RULE_TAG,              /**< The {nnn} tag on a rule is malformed              */
+#ifndef U_HIDE_DEPRECATED_API
+    /**
+     * One more than the highest normal BreakIterator error code.
+     * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
+     */
+    U_BRK_ERROR_LIMIT,
+#endif  // U_HIDE_DEPRECATED_API
 
     /*
-     * The error codes in the range 0x10300-0x103ff are reserved for regular expression related errrs
+     * Error codes in the range 0x10300-0x103ff are reserved for regular expression related errors.
      */
     U_REGEX_INTERNAL_ERROR=0x10300,       /**< An internal error (bug) was detected.              */
     U_REGEX_ERROR_START=0x10300,          /**< Start of codes indicating Regexp failures          */
@@ -655,14 +636,18 @@
     U_REGEX_STACK_OVERFLOW,               /**< Regular expression backtrack stack overflow.       */
     U_REGEX_TIME_OUT,                     /**< Maximum allowed match time exceeded                */
     U_REGEX_STOPPED_BY_CALLER,            /**< Matching operation aborted by user callback fn.    */
-#ifndef U_HIDE_DRAFT_API
-    U_REGEX_PATTERN_TOO_BIG,              /**< Pattern exceeds limits on size or complexity. @draft ICU 55 */
-    U_REGEX_INVALID_CAPTURE_GROUP_NAME,   /**< Invalid capture group name. @draft ICU 55 */
-#endif  /* U_HIDE_DRAFT_API */
-    U_REGEX_ERROR_LIMIT=U_REGEX_STOPPED_BY_CALLER+3, /**< This must always be the last value to indicate the limit for regexp errors */
+    U_REGEX_PATTERN_TOO_BIG,              /**< Pattern exceeds limits on size or complexity. @stable ICU 55 */
+    U_REGEX_INVALID_CAPTURE_GROUP_NAME,   /**< Invalid capture group name. @stable ICU 55 */
+#ifndef U_HIDE_DEPRECATED_API
+    /**
+     * One more than the highest normal regular expression error code.
+     * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
+     */
+    U_REGEX_ERROR_LIMIT=U_REGEX_STOPPED_BY_CALLER+3,
+#endif  // U_HIDE_DEPRECATED_API
 
     /*
-     * The error code in the range 0x10400-0x104ff are reserved for IDNA related error codes
+     * Error codes in the range 0x10400-0x104ff are reserved for IDNA related error codes.
      */
     U_IDNA_PROHIBITED_ERROR=0x10400,
     U_IDNA_ERROR_START=0x10400,
@@ -674,7 +659,13 @@
     U_IDNA_LABEL_TOO_LONG_ERROR,
     U_IDNA_ZERO_LENGTH_LABEL_ERROR,
     U_IDNA_DOMAIN_NAME_TOO_LONG_ERROR,
+#ifndef U_HIDE_DEPRECATED_API
+    /**
+     * One more than the highest normal IDNA error code.
+     * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
+     */
     U_IDNA_ERROR_LIMIT,
+#endif  // U_HIDE_DEPRECATED_API
     /*
      * Aliases for StringPrep
      */
@@ -683,14 +674,26 @@
     U_STRINGPREP_CHECK_BIDI_ERROR = U_IDNA_CHECK_BIDI_ERROR,
     
     /*
-     * The error code in the range 0x10500-0x105ff are reserved for Plugin related error codes
+     * Error codes in the range 0x10500-0x105ff are reserved for Plugin related error codes.
      */
     U_PLUGIN_ERROR_START=0x10500,         /**< Start of codes indicating plugin failures */
     U_PLUGIN_TOO_HIGH=0x10500,            /**< The plugin's level is too high to be loaded right now. */
     U_PLUGIN_DIDNT_SET_LEVEL,             /**< The plugin didn't call uplug_setPlugLevel in response to a QUERY */
-    U_PLUGIN_ERROR_LIMIT,                 /**< This must always be the last value to indicate the limit for plugin errors */
+#ifndef U_HIDE_DEPRECATED_API
+    /**
+     * One more than the highest normal plug-in error code.
+     * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
+     */
+    U_PLUGIN_ERROR_LIMIT,
+#endif  // U_HIDE_DEPRECATED_API
 
-    U_ERROR_LIMIT=U_PLUGIN_ERROR_LIMIT      /**< This must always be the last value to indicate the limit for UErrorCode (last error code +1) */
+#ifndef U_HIDE_DEPRECATED_API
+    /**
+     * One more than the highest normal error code.
+     * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
+     */
+    U_ERROR_LIMIT=U_PLUGIN_ERROR_LIMIT
+#endif  // U_HIDE_DEPRECATED_API
 } UErrorCode;
 
 /* Use the following to determine if an UErrorCode represents */
@@ -728,7 +731,7 @@
  * in the UErrorCode enum above.
  * @stable ICU 2.0
  */
-U_STABLE const char * U_EXPORT2
+U_CAPI const char * U_EXPORT2
 u_errorName(UErrorCode code);
 
 
diff --git a/src/third_party/icu/source/common/unicode/uvernum.h b/src/third_party/icu/source/common/unicode/uvernum.h
index 6f3ae35..a4cbb9e 100644
--- a/src/third_party/icu/source/common/unicode/uvernum.h
+++ b/src/third_party/icu/source/common/unicode/uvernum.h
@@ -1,11 +1,13 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
-*   Copyright (C) 2000-2015, International Business Machines
+*   Copyright (C) 2000-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *******************************************************************************
 *
 *   file name:  uvernum.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -32,13 +34,14 @@
   *  by running the UNIX makefile target 'update-windows-makefiles' in icu/source.
   *
   *
-  * source/common/common.vcproj - update 'Output file name' on the link tab so
+  * source/common/common_uwp.vcxproj
+  * source/common/common.vcxproj - update 'Output file name' on the link tab so
   *                   that it contains the new major/minor combination
-  * source/i18n/i18n.vcproj - same as for the common.vcproj
-  * source/layout/layout.vcproj - same as for the common.vcproj
+  * source/i18n/i18n.vcxproj - same as for the common.vcxproj
+  * source/i18n/i18n_uwp.vcxproj - same as for the common_uwp.vcxproj
   * source/layoutex/layoutex.vcproj - same
-  * source/stubdata/stubdata.vcproj - same as for the common.vcproj
-  * source/io/io.vcproj - same as for the common.vcproj
+  * source/stubdata/stubdata.vcproj - same as for the common.vcxproj
+  * source/io/io.vcproj - same as for the common.vcxproj
   * source/data/makedata.mak - change U_ICUDATA_NAME so that it contains
   *                            the new major/minor combination and the Unicode version.
   */
@@ -51,13 +54,13 @@
  *  @stable ICU 2.4
  */
 #define U_COPYRIGHT_STRING \
-  " Copyright (C) 2015, International Business Machines Corporation and others. All Rights Reserved. "
+  " Copyright (C) 2016 and later: Unicode, Inc. and others. License & terms of use: http://www.unicode.org/copyright.html "
 
 /** The current ICU major version as an integer.
  *  This value will change in the subsequent releases of ICU
  *  @stable ICU 2.4
  */
-#define U_ICU_VERSION_MAJOR_NUM 56
+#define U_ICU_VERSION_MAJOR_NUM 68
 
 /** The current ICU minor version as an integer.
  *  This value will change in the subsequent releases of ICU
@@ -83,7 +86,7 @@
  *  This value will change in the subsequent releases of ICU
  *  @stable ICU 2.6
  */
-#define U_ICU_VERSION_SUFFIX _56
+#define U_ICU_VERSION_SUFFIX _68
 
 /**
  * \def U_DEF2_ICU_ENTRY_POINT_RENAME
@@ -100,16 +103,34 @@
  *  \def U_ICU_ENTRY_POINT_RENAME
  *  @stable ICU 4.2
  */
+/**
+ * Disable the version suffix. Use the custom suffix if exists.
+ * \def U_DISABLE_VERSION_SUFFIX
+ * @internal
+ */
+#ifndef U_DISABLE_VERSION_SUFFIX
+#define U_DISABLE_VERSION_SUFFIX 0
+#endif
 
 #ifndef U_ICU_ENTRY_POINT_RENAME
 #ifdef U_HAVE_LIB_SUFFIX
-#define U_DEF_ICU_ENTRY_POINT_RENAME(x,y,z) x ## y ##  z
-#define U_DEF2_ICU_ENTRY_POINT_RENAME(x,y,z) U_DEF_ICU_ENTRY_POINT_RENAME(x,y,z)
-#define U_ICU_ENTRY_POINT_RENAME(x)    U_DEF2_ICU_ENTRY_POINT_RENAME(x,U_ICU_VERSION_SUFFIX,U_LIB_SUFFIX_C_NAME)
+#   if !U_DISABLE_VERSION_SUFFIX
+#       define U_DEF_ICU_ENTRY_POINT_RENAME(x,y,z) x ## y ##  z
+#       define U_DEF2_ICU_ENTRY_POINT_RENAME(x,y,z) U_DEF_ICU_ENTRY_POINT_RENAME(x,y,z)
+#       define U_ICU_ENTRY_POINT_RENAME(x)    U_DEF2_ICU_ENTRY_POINT_RENAME(x,U_ICU_VERSION_SUFFIX,U_LIB_SUFFIX_C_NAME)
+#   else
+#       define U_DEF_ICU_ENTRY_POINT_RENAME(x,y) x ## y
+#       define U_DEF2_ICU_ENTRY_POINT_RENAME(x,y) U_DEF_ICU_ENTRY_POINT_RENAME(x,y)
+#       define U_ICU_ENTRY_POINT_RENAME(x)    U_DEF2_ICU_ENTRY_POINT_RENAME(x,U_LIB_SUFFIX_C_NAME)
+#   endif
 #else
-#define U_DEF_ICU_ENTRY_POINT_RENAME(x,y) x ## y
-#define U_DEF2_ICU_ENTRY_POINT_RENAME(x,y) U_DEF_ICU_ENTRY_POINT_RENAME(x,y)
-#define U_ICU_ENTRY_POINT_RENAME(x)    U_DEF2_ICU_ENTRY_POINT_RENAME(x,U_ICU_VERSION_SUFFIX)
+#   if !U_DISABLE_VERSION_SUFFIX
+#       define U_DEF_ICU_ENTRY_POINT_RENAME(x,y) x ## y
+#       define U_DEF2_ICU_ENTRY_POINT_RENAME(x,y) U_DEF_ICU_ENTRY_POINT_RENAME(x,y)
+#       define U_ICU_ENTRY_POINT_RENAME(x)    U_DEF2_ICU_ENTRY_POINT_RENAME(x,U_ICU_VERSION_SUFFIX)
+#   else
+#       define U_ICU_ENTRY_POINT_RENAME(x)    x
+#   endif
 #endif
 #endif
 
@@ -118,19 +139,26 @@
  *  This value will change in the subsequent releases of ICU
  *  @stable ICU 2.4
  */
-#define U_ICU_VERSION "56.1"
+#define U_ICU_VERSION "68.1"
 
-/** The current ICU library major/minor version as a string without dots, for library name suffixes.
- *  This value will change in the subsequent releases of ICU
- *  @stable ICU 2.6
+/**
+ * The current ICU library major version number as a string, for library name suffixes.
+ * This value will change in subsequent releases of ICU.
+ *
+ * Until ICU 4.8, this was the combination of the single-digit major and minor ICU version numbers
+ * into one string without dots ("48").
+ * Since ICU 49, it is the double-digit major ICU version number.
+ * See https://unicode-org.github.io/icu/userguide/design#version-numbers-in-icu
+ *
+ * @stable ICU 2.6
  */
-#define U_ICU_VERSION_SHORT "56"
+#define U_ICU_VERSION_SHORT "68"
 
 #ifndef U_HIDE_INTERNAL_API
 /** Data version in ICU4C.
  * @internal ICU 4.4 Internal Use Only
  **/
-#define U_ICU_DATA_VERSION "56.1"
+#define U_ICU_DATA_VERSION "68.1"
 #endif  /* U_HIDE_INTERNAL_API */
 
 /*===========================================================================
diff --git a/src/third_party/icu/source/common/unicode/uversion.h b/src/third_party/icu/source/common/unicode/uversion.h
index 74e3091..113568d 100644
--- a/src/third_party/icu/source/common/unicode/uversion.h
+++ b/src/third_party/icu/source/common/unicode/uversion.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *   Copyright (C) 2000-2011, International Business Machines
@@ -5,7 +7,7 @@
 *******************************************************************************
 *
 *   file name:  uversion.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -60,26 +62,22 @@
 /* C++ namespace if supported. Versioned unless versioning is disabled.      */
 /*===========================================================================*/
 
+/* Define C++ namespace symbols. */
+#ifdef __cplusplus
+
 /**
  * \def U_NAMESPACE_BEGIN
- * This is used to begin a declaration of a public ICU C++ API.
- * When not compiling for C++, it does nothing.
- * When compiling for C++, it begins an extern "C++" linkage block (to protect
- * against cases in which an external client includes ICU header files inside
- * an extern "C" linkage block).
+ * This is used to begin a declaration of a public ICU C++ API within
+ * versioned-ICU-namespace block.
  *
- * It also begins a versioned-ICU-namespace block.
  * @stable ICU 2.4
  */
 
 /**
  * \def U_NAMESPACE_END
  * This is used to end a declaration of a public ICU C++ API.
- * When not compiling for C++, it does nothing.
- * When compiling for C++, it ends the extern "C++" block begun by
- * U_NAMESPACE_BEGIN.
+ * It ends the versioned-ICU-namespace block begun by U_NAMESPACE_BEGIN.
  *
- * It also ends the versioned-ICU-namespace block begun by U_NAMESPACE_BEGIN.
  * @stable ICU 2.4
  */
 
@@ -87,9 +85,6 @@
  * \def U_NAMESPACE_USE
  * This is used to specify that the rest of the code uses the
  * public ICU C++ API namespace.
- * This is invoked by default; we recommend that you turn it off:
- * See the "Recommended Build Options" section of the ICU4C readme
- * (http://source.icu-project.org/repos/icu/icu/trunk/readme.html#RecBuild)
  * @stable ICU 2.4
  */
 
@@ -103,8 +98,6 @@
  * @stable ICU 2.4
  */
 
-/* Define namespace symbols if the compiler supports it. */
-#ifdef __cplusplus
 #   if U_DISABLE_RENAMING
 #       define U_ICU_NAMESPACE icu
         namespace U_ICU_NAMESPACE { }
@@ -114,23 +107,24 @@
         namespace icu = U_ICU_NAMESPACE;
 #   endif
 
-#   define U_NAMESPACE_BEGIN extern "C++" { namespace U_ICU_NAMESPACE {
-#   define U_NAMESPACE_END } }
+#   define U_NAMESPACE_BEGIN namespace U_ICU_NAMESPACE {
+#   define U_NAMESPACE_END }
 #   define U_NAMESPACE_USE using namespace U_ICU_NAMESPACE;
 #   define U_NAMESPACE_QUALIFIER U_ICU_NAMESPACE::
 
 #   ifndef U_USING_ICU_NAMESPACE
-#       define U_USING_ICU_NAMESPACE 1
+#       if defined(U_COMBINED_IMPLEMENTATION) || defined(U_COMMON_IMPLEMENTATION) || \
+                defined(U_I18N_IMPLEMENTATION) || defined(U_IO_IMPLEMENTATION) || \
+                defined(U_LAYOUTEX_IMPLEMENTATION) || defined(U_TOOLUTIL_IMPLEMENTATION)
+#           define U_USING_ICU_NAMESPACE 0
+#       else
+#           define U_USING_ICU_NAMESPACE 0
+#       endif
 #   endif
 #   if U_USING_ICU_NAMESPACE
         U_NAMESPACE_USE
 #   endif
-#else
-#   define U_NAMESPACE_BEGIN
-#   define U_NAMESPACE_END
-#   define U_NAMESPACE_USE
-#   define U_NAMESPACE_QUALIFIER
-#endif
+#endif /* __cplusplus */
 
 /*===========================================================================*/
 /* General version helper functions. Definitions in putil.c                  */
@@ -147,7 +141,7 @@
  *                      values of up to 255 each.
  * @stable ICU 2.4
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 u_versionFromString(UVersionInfo versionArray, const char *versionString);
 
 /**
@@ -161,7 +155,7 @@
  *                      fields with values of up to 255 each.
  * @stable ICU 4.2
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 u_versionFromUString(UVersionInfo versionArray, const UChar *versionString);
 
 
@@ -177,7 +171,7 @@
  *                      The buffer size must be at least U_MAX_VERSION_STRING_LENGTH.
  * @stable ICU 2.4
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 u_versionToString(const UVersionInfo versionArray, char *versionString);
 
 /**
@@ -188,6 +182,6 @@
  * @param versionArray the version # information, the result will be filled in
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2
+U_CAPI void U_EXPORT2
 u_getVersion(UVersionInfo versionArray);
 #endif
diff --git a/src/third_party/icu/source/common/unifiedcache.cpp b/src/third_party/icu/source/common/unifiedcache.cpp
index 6803566..0729335 100644
--- a/src/third_party/icu/source/common/unifiedcache.cpp
+++ b/src/third_party/icu/source/common/unifiedcache.cpp
@@ -1,44 +1,48 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
-* Copyright (C) 2015, International Business Machines Corporation and         
-* others. All Rights Reserved.                                                
+* Copyright (C) 2015, International Business Machines Corporation and
+* others. All Rights Reserved.
 ******************************************************************************
-*                                                                             
-* File UNIFIEDCACHE.CPP 
+*
+* File unifiedcache.cpp
 ******************************************************************************
 */
 
+#include "unifiedcache.h"
+
+#include <algorithm>      // For std::max()
+#include <mutex>
+
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
 #include "starboard/client_porting/poem/string_poem.h"
-#include "uhash.h"
-#include "unifiedcache.h"
-#include "umutex.h"
-#include "mutex.h"
+#endif  // defined(STARBOARD)
+
 #include "uassert.h"
+#include "uhash.h"
 #include "ucln_cmn.h"
 
 static icu::UnifiedCache *gCache = NULL;
-static icu::SharedObject *gNoValue = NULL;
-static UMutex gCacheMutex = U_MUTEX_INITIALIZER;
-static UConditionVar gInProgressValueAddedCond = U_CONDITION_INITIALIZER;
+static std::mutex *gCacheMutex = nullptr;
+static std::condition_variable *gInProgressValueAddedCond;
 static icu::UInitOnce gCacheInitOnce = U_INITONCE_INITIALIZER;
-static const int32_t MAX_EVICT_ITERATIONS = 10;
 
-static int32_t DEFAULT_MAX_UNUSED = 1000;
-static int32_t DEFAULT_PERCENTAGE_OF_IN_USE = 100;
+static const int32_t MAX_EVICT_ITERATIONS = 10;
+static const int32_t DEFAULT_MAX_UNUSED = 1000;
+static const int32_t DEFAULT_PERCENTAGE_OF_IN_USE = 100;
 
 
 U_CDECL_BEGIN
 static UBool U_CALLCONV unifiedcache_cleanup() {
     gCacheInitOnce.reset();
-    if (gCache) {
-        delete gCache;
-        gCache = NULL;
-    }
-    if (gNoValue) {
-        delete gNoValue;
-        gNoValue = NULL;
-    }
+    delete gCache;
+    gCache = nullptr;
+    gCacheMutex->~mutex();
+    gCacheMutex = nullptr;
+    gInProgressValueAddedCond->~condition_variable();
+    gInProgressValueAddedCond = nullptr;
     return TRUE;
 }
 U_CDECL_END
@@ -73,23 +77,17 @@
     ucln_common_registerCleanup(
             UCLN_COMMON_UNIFIED_CACHE, unifiedcache_cleanup);
 
-    // gNoValue must be created first to avoid assertion error in
-    // cache constructor.
-    gNoValue = new SharedObject();
+    gCacheMutex = STATIC_NEW(std::mutex);
+    gInProgressValueAddedCond = STATIC_NEW(std::condition_variable);
     gCache = new UnifiedCache(status);
     if (gCache == NULL) {
         status = U_MEMORY_ALLOCATION_ERROR;
     }
     if (U_FAILURE(status)) {
         delete gCache;
-        delete gNoValue;
         gCache = NULL;
-        gNoValue = NULL;
         return;
     }
-    // We add a softref because we want hash elements with gNoValue to be
-    // elligible for purging but we don't ever want gNoValue to be deleted.
-    gNoValue->addSoftRef();
 }
 
 UnifiedCache *UnifiedCache::getInstance(UErrorCode &status) {
@@ -104,14 +102,24 @@
 UnifiedCache::UnifiedCache(UErrorCode &status) :
         fHashtable(NULL),
         fEvictPos(UHASH_FIRST),
-        fItemsInUseCount(0),
+        fNumValuesTotal(0),
+        fNumValuesInUse(0),
         fMaxUnused(DEFAULT_MAX_UNUSED),
         fMaxPercentageOfInUse(DEFAULT_PERCENTAGE_OF_IN_USE),
-        fAutoEvictedCount(0) {
+        fAutoEvictedCount(0),
+        fNoValue(nullptr) {
     if (U_FAILURE(status)) {
         return;
     }
-    U_ASSERT(gNoValue != NULL);
+    fNoValue = new SharedObject();
+    if (fNoValue == nullptr) {
+        status = U_MEMORY_ALLOCATION_ERROR;
+        return;
+    }
+    fNoValue->softRefCount = 1;  // Add fake references to prevent fNoValue from being deleted
+    fNoValue->hardRefCount = 1;  // when other references to it are removed.
+    fNoValue->cachePtr = this;
+
     fHashtable = uhash_open(
             &ucache_hashKeys,
             &ucache_compareKeys,
@@ -132,28 +140,28 @@
         status = U_ILLEGAL_ARGUMENT_ERROR;
         return;
     }
-    Mutex lock(&gCacheMutex);
+    std::lock_guard<std::mutex> lock(*gCacheMutex);
     fMaxUnused = count;
     fMaxPercentageOfInUse = percentageOfInUseItems;
 }
 
 int32_t UnifiedCache::unusedCount() const {
-    Mutex lock(&gCacheMutex);
-    return uhash_count(fHashtable) - fItemsInUseCount;
+    std::lock_guard<std::mutex> lock(*gCacheMutex);
+    return uhash_count(fHashtable) - fNumValuesInUse;
 }
 
 int64_t UnifiedCache::autoEvictedCount() const {
-    Mutex lock(&gCacheMutex);
+    std::lock_guard<std::mutex> lock(*gCacheMutex);
     return fAutoEvictedCount;
 }
 
 int32_t UnifiedCache::keyCount() const {
-    Mutex lock(&gCacheMutex);
+    std::lock_guard<std::mutex> lock(*gCacheMutex);
     return uhash_count(fHashtable);
 }
 
 void UnifiedCache::flush() const {
-    Mutex lock(&gCacheMutex);
+    std::lock_guard<std::mutex> lock(*gCacheMutex);
 
     // Use a loop in case cache items that are flushed held hard references to
     // other cache items making those additional cache items eligible for
@@ -161,6 +169,12 @@
     while (_flush(FALSE));
 }
 
+void UnifiedCache::handleUnreferencedObject() const {
+    std::lock_guard<std::mutex> lock(*gCacheMutex);
+    --fNumValuesInUse;
+    _runEvictionSlice();
+}
+
 #ifdef UNIFIED_CACHE_DEBUG
 #include <stdio.h>
 
@@ -175,7 +189,7 @@
 }
 
 void UnifiedCache::dumpContents() const {
-    Mutex lock(&gCacheMutex);
+    std::lock_guard<std::mutex> lock(*gCacheMutex);
     _dumpContents();
 }
 
@@ -196,10 +210,10 @@
             ++cnt;
             fprintf(
                     stderr,
-                    "Unified Cache: Key '%s', error %d, value %p, total refcount %d, soft refcount %d\n", 
+                    "Unified Cache: Key '%s', error %d, value %p, total refcount %d, soft refcount %d\n",
                     key->writeDescription(buffer, 256),
                     key->creationStatus,
-                    sharedObject == gNoValue ? NULL :sharedObject,
+                    sharedObject == fNoValue ? NULL :sharedObject,
                     sharedObject->getRefCount(),
                     sharedObject->getSoftRefCount());
         }
@@ -213,16 +227,17 @@
     flush();
     {
         // Now all that should be left in the cache are entries that refer to
-        // each other and entries with hard references from outside the cache. 
+        // each other and entries with hard references from outside the cache.
         // Nothing we can do about these so proceed to wipe out the cache.
-        Mutex lock(&gCacheMutex);
+        std::lock_guard<std::mutex> lock(*gCacheMutex);
         _flush(TRUE);
     }
     uhash_close(fHashtable);
+    fHashtable = nullptr;
+    delete fNoValue;
+    fNoValue = nullptr;
 }
 
-// Returns the next element in the cache round robin style.
-// On entry, gCacheMutex must be held.
 const UHashElement *
 UnifiedCache::_nextElement() const {
     const UHashElement *element = uhash_nextElement(fHashtable, &fEvictPos);
@@ -233,46 +248,36 @@
     return element;
 }
 
-// Flushes the contents of the cache. If cache values hold references to other
-// cache values then _flush should be called in a loop until it returns FALSE.
-// On entry, gCacheMutex must be held.
-// On exit, those values with are evictable are flushed. If all is true
-// then every value is flushed even if it is not evictable.
-// Returns TRUE if any value in cache was flushed or FALSE otherwise.
 UBool UnifiedCache::_flush(UBool all) const {
     UBool result = FALSE;
     int32_t origSize = uhash_count(fHashtable);
     for (int32_t i = 0; i < origSize; ++i) {
         const UHashElement *element = _nextElement();
+        if (element == nullptr) {
+            break;
+        }
         if (all || _isEvictable(element)) {
             const SharedObject *sharedObject =
                     (const SharedObject *) element->value.pointer;
+            U_ASSERT(sharedObject->cachePtr == this);
             uhash_removeElement(fHashtable, element);
-            sharedObject->removeSoftRef();
+            removeSoftRef(sharedObject);    // Deletes the sharedObject when softRefCount goes to zero.
             result = TRUE;
         }
     }
     return result;
 }
 
-// Computes how many items should be evicted.
-// On entry, gCacheMutex must be held.
-// Returns number of items that should be evicted or a value <= 0 if no
-// items need to be evicted.
 int32_t UnifiedCache::_computeCountOfItemsToEvict() const {
-    int32_t maxPercentageOfInUseCount =
-            fItemsInUseCount * fMaxPercentageOfInUse / 100;
-    int32_t maxUnusedCount = fMaxUnused;
-    if (maxUnusedCount < maxPercentageOfInUseCount) {
-        maxUnusedCount = maxPercentageOfInUseCount;
-    }
-    return uhash_count(fHashtable) - fItemsInUseCount - maxUnusedCount;
+    int32_t totalItems = uhash_count(fHashtable);
+    int32_t evictableItems = totalItems - fNumValuesInUse;
+
+    int32_t unusedLimitByPercentage = fNumValuesInUse * fMaxPercentageOfInUse / 100;
+    int32_t unusedLimit = std::max(unusedLimitByPercentage, fMaxUnused);
+    int32_t countOfItemsToEvict = std::max(0, evictableItems - unusedLimit);
+    return countOfItemsToEvict;
 }
 
-// Run an eviction slice.
-// On entry, gCacheMutex must be held.
-// _runEvictionSlice runs a slice of the evict pipeline by examining the next
-// 10 entries in the cache round robin style evicting them if they are eligible.
 void UnifiedCache::_runEvictionSlice() const {
     int32_t maxItemsToEvict = _computeCountOfItemsToEvict();
     if (maxItemsToEvict <= 0) {
@@ -280,11 +285,14 @@
     }
     for (int32_t i = 0; i < MAX_EVICT_ITERATIONS; ++i) {
         const UHashElement *element = _nextElement();
+        if (element == nullptr) {
+            break;
+        }
         if (_isEvictable(element)) {
             const SharedObject *sharedObject =
                     (const SharedObject *) element->value.pointer;
             uhash_removeElement(fHashtable, element);
-            sharedObject->removeSoftRef();
+            removeSoftRef(sharedObject);   // Deletes sharedObject when SoftRefCount goes to zero.
             ++fAutoEvictedCount;
             if (--maxItemsToEvict == 0) {
                 break;
@@ -293,13 +301,8 @@
     }
 }
 
-
-// Places a new value and creationStatus in the cache for the given key.
-// On entry, gCacheMutex must be held. key must not exist in the cache. 
-// On exit, value and creation status placed under key. Soft reference added
-// to value on successful add. On error sets status.
 void UnifiedCache::_putNew(
-        const CacheKeyBase &key, 
+        const CacheKeyBase &key,
         const SharedObject *value,
         const UErrorCode creationStatus,
         UErrorCode &status) const {
@@ -312,29 +315,22 @@
         return;
     }
     keyToAdopt->fCreationStatus = creationStatus;
-    if (value->noSoftReferences()) {
-        _registerMaster(keyToAdopt, value);
+    if (value->softRefCount == 0) {
+        _registerPrimary(keyToAdopt, value);
     }
-    uhash_put(fHashtable, keyToAdopt, (void *) value, &status);
+    void *oldValue = uhash_put(fHashtable, keyToAdopt, (void *) value, &status);
+    U_ASSERT(oldValue == nullptr);
+    (void)oldValue;
     if (U_SUCCESS(status)) {
-        value->addSoftRef();
+        value->softRefCount++;
     }
 }
 
-// Places value and status at key if there is no value at key or if cache
-// entry for key is in progress. Otherwise, it leaves the current value and
-// status there.
-// On entry. gCacheMutex must not be held. value must be
-// included in the reference count of the object to which it points.
-// On exit, value and status are changed to what was already in the cache if
-// something was there and not in progress. Otherwise, value and status are left
-// unchanged in which case they are placed in the cache on a best-effort basis.
-// Caller must call removeRef() on value.
 void UnifiedCache::_putIfAbsentAndGet(
         const CacheKeyBase &key,
         const SharedObject *&value,
         UErrorCode &status) const {
-    Mutex lock(&gCacheMutex);
+    std::lock_guard<std::mutex> lock(*gCacheMutex);
     const UHashElement *element = uhash_find(fHashtable, &key);
     if (element != NULL && !_inProgress(element)) {
         _fetch(element, value, status);
@@ -347,49 +343,43 @@
     } else {
         _put(element, value, status);
     }
-    // Run an eviction slice. This will run even if we added a master entry
+    // Run an eviction slice. This will run even if we added a primary entry
     // which doesn't increase the unused count, but that is still o.k
     _runEvictionSlice();
 }
 
-// Attempts to fetch value and status for key from cache.
-// On entry, gCacheMutex must not be held value must be NULL and status must
-// be U_ZERO_ERROR.
-// On exit, either returns FALSE (In this
-// case caller should try to create the object) or returns TRUE with value
-// pointing to the fetched value and status set to fetched status. When
-// FALSE is returned status may be set to failure if an in progress hash
-// entry could not be made but value will remain unchanged. When TRUE is
-// returned, caler must call removeRef() on value.
+
 UBool UnifiedCache::_poll(
         const CacheKeyBase &key,
         const SharedObject *&value,
         UErrorCode &status) const {
     U_ASSERT(value == NULL);
     U_ASSERT(status == U_ZERO_ERROR);
-    Mutex lock(&gCacheMutex);
+    std::unique_lock<std::mutex> lock(*gCacheMutex);
     const UHashElement *element = uhash_find(fHashtable, &key);
-    while (element != NULL && _inProgress(element)) {
-        umtx_condWait(&gInProgressValueAddedCond, &gCacheMutex);
-        element = uhash_find(fHashtable, &key);
+
+    // If the hash table contains an inProgress placeholder entry for this key,
+    // this means that another thread is currently constructing the value object.
+    // Loop, waiting for that construction to complete.
+     while (element != NULL && _inProgress(element)) {
+         gInProgressValueAddedCond->wait(lock);
+         element = uhash_find(fHashtable, &key);
     }
+
+    // If the hash table contains an entry for the key,
+    // fetch out the contents and return them.
     if (element != NULL) {
-        _fetch(element, value, status);
+         _fetch(element, value, status);
         return TRUE;
     }
-    _putNew(key, gNoValue, U_ZERO_ERROR, status);
+
+    // The hash table contained nothing for this key.
+    // Insert an inProgress place holder value.
+    // Our caller will create the final value and update the hash table.
+    _putNew(key, fNoValue, U_ZERO_ERROR, status);
     return FALSE;
 }
 
-// Gets value out of cache.
-// On entry. gCacheMutex must not be held. value must be NULL. status
-// must be U_ZERO_ERROR.
-// On exit. value and status set to what is in cache at key or on cache
-// miss the key's createObject() is called and value and status are set to
-// the result of that. In this latter case, best effort is made to add the
-// value and status to the cache. If createObject() fails to create a value,
-// gNoValue is stored in cache, and value is set to NULL. Caller must call
-// removeRef on value if non NULL.
 void UnifiedCache::_get(
         const CacheKeyBase &key,
         const SharedObject *&value,
@@ -398,7 +388,7 @@
     U_ASSERT(value == NULL);
     U_ASSERT(status == U_ZERO_ERROR);
     if (_poll(key, value, status)) {
-        if (value == gNoValue) {
+        if (value == fNoValue) {
             SharedObject::clearPtr(value);
         }
         return;
@@ -410,134 +400,76 @@
     U_ASSERT(value == NULL || value->hasHardReferences());
     U_ASSERT(value != NULL || status != U_ZERO_ERROR);
     if (value == NULL) {
-        SharedObject::copyPtr(gNoValue, value);
+        SharedObject::copyPtr(fNoValue, value);
     }
     _putIfAbsentAndGet(key, value, status);
-    if (value == gNoValue) {
+    if (value == fNoValue) {
         SharedObject::clearPtr(value);
     }
 }
 
-void UnifiedCache::decrementItemsInUseWithLockingAndEviction() const {
-    Mutex mutex(&gCacheMutex);
-    decrementItemsInUse();
-    _runEvictionSlice();
+void UnifiedCache::_registerPrimary(
+            const CacheKeyBase *theKey, const SharedObject *value) const {
+    theKey->fIsPrimary = true;
+    value->cachePtr = this;
+    ++fNumValuesTotal;
+    ++fNumValuesInUse;
 }
 
-void UnifiedCache::incrementItemsInUse() const {
-    ++fItemsInUseCount;
-}
-
-void UnifiedCache::decrementItemsInUse() const {
-    --fItemsInUseCount;
-}
-
-// Register a master cache entry.
-// On entry, gCacheMutex must be held.
-// On exit, items in use count incremented, entry is marked as a master
-// entry, and value registered with cache so that subsequent calls to
-// addRef() and removeRef() on it correctly updates items in use count
-void UnifiedCache::_registerMaster(
-        const CacheKeyBase *theKey, const SharedObject *value) const {
-    theKey->fIsMaster = TRUE;
-    ++fItemsInUseCount;
-    value->registerWithCache(this);
-}
-
-// Store a value and error in given hash entry.
-// On entry, gCacheMutex must be held. Hash entry element must be in progress.
-// value must be non NULL.
-// On Exit, soft reference added to value. value and status stored in hash
-// entry. Soft reference removed from previous stored value. Waiting
-// threads notified.
 void UnifiedCache::_put(
-        const UHashElement *element, 
+        const UHashElement *element,
         const SharedObject *value,
         const UErrorCode status) const {
     U_ASSERT(_inProgress(element));
     const CacheKeyBase *theKey = (const CacheKeyBase *) element->key.pointer;
     const SharedObject *oldValue = (const SharedObject *) element->value.pointer;
     theKey->fCreationStatus = status;
-    if (value->noSoftReferences()) {
-        _registerMaster(theKey, value);
+    if (value->softRefCount == 0) {
+        _registerPrimary(theKey, value);
     }
-    value->addSoftRef();
+    value->softRefCount++;
     UHashElement *ptr = const_cast<UHashElement *>(element);
     ptr->value.pointer = (void *) value;
-    oldValue->removeSoftRef();
+    U_ASSERT(oldValue == fNoValue);
+    removeSoftRef(oldValue);
 
     // Tell waiting threads that we replace in-progress status with
     // an error.
-    umtx_condBroadcast(&gInProgressValueAddedCond);
+    gInProgressValueAddedCond->notify_all();
 }
 
-void
-UnifiedCache::copyPtr(const SharedObject *src, const SharedObject *&dest) {
-    if(src != dest) {
-        if(dest != NULL) {
-            dest->removeRefWhileHoldingCacheLock();
-        }
-        dest = src;
-        if(src != NULL) {
-            src->addRefWhileHoldingCacheLock();
-        }
-    }
-}
-
-void
-UnifiedCache::clearPtr(const SharedObject *&ptr) {
-    if (ptr != NULL) {
-        ptr->removeRefWhileHoldingCacheLock();
-        ptr = NULL;
-    }
-}
-
-
-// Fetch value and error code from a particular hash entry.
-// On entry, gCacheMutex must be held. value must be either NULL or must be
-// included in the ref count of the object to which it points.
-// On exit, value and status set to what is in the hash entry. Caller must
-// eventually call removeRef on value.
-// If hash entry is in progress, value will be set to gNoValue and status will
-// be set to U_ZERO_ERROR.
 void UnifiedCache::_fetch(
         const UHashElement *element,
         const SharedObject *&value,
-        UErrorCode &status) {
+        UErrorCode &status) const {
     const CacheKeyBase *theKey = (const CacheKeyBase *) element->key.pointer;
     status = theKey->fCreationStatus;
 
-    // Since we have the cache lock, calling regular SharedObject methods
+    // Since we have the cache lock, calling regular SharedObject add/removeRef
     // could cause us to deadlock on ourselves since they may need to lock
     // the cache mutex.
-    UnifiedCache::copyPtr((const SharedObject *) element->value.pointer, value);
+    removeHardRef(value);
+    value = static_cast<const SharedObject *>(element->value.pointer);
+    addHardRef(value);
 }
 
-// Determine if given hash entry is in progress.
-// On entry, gCacheMutex must be held.
-UBool UnifiedCache::_inProgress(const UHashElement *element) {
-    const SharedObject *value = NULL;
+
+UBool UnifiedCache::_inProgress(const UHashElement* element) const {
     UErrorCode status = U_ZERO_ERROR;
+    const SharedObject * value = NULL;
     _fetch(element, value, status);
     UBool result = _inProgress(value, status);
-
-    // Since we have the cache lock, calling regular SharedObject methods
-    // could cause us to deadlock on ourselves since they may need to lock
-    // the cache mutex.
-    UnifiedCache::clearPtr(value);
+    removeHardRef(value);
     return result;
 }
 
-// Determine if given hash entry is in progress.
-// On entry, gCacheMutex must be held.
 UBool UnifiedCache::_inProgress(
-        const SharedObject *theValue, UErrorCode creationStatus) {
-    return (theValue == gNoValue && creationStatus == U_ZERO_ERROR);
+        const SharedObject* theValue, UErrorCode creationStatus) const {
+    return (theValue == fNoValue && creationStatus == U_ZERO_ERROR);
 }
 
-// Determine if given hash entry is eligible for eviction.
-// On entry, gCacheMutex must be held.
-UBool UnifiedCache::_isEvictable(const UHashElement *element) {
+UBool UnifiedCache::_isEvictable(const UHashElement *element) const
+{
     const CacheKeyBase *theKey = (const CacheKeyBase *) element->key.pointer;
     const SharedObject *theValue =
             (const SharedObject *) element->value.pointer;
@@ -547,9 +479,49 @@
         return FALSE;
     }
 
-    // We can evict entries that are either not a master or have just
+    // We can evict entries that are either not a primary or have just
     // one reference (The one reference being from the cache itself).
-    return (!theKey->fIsMaster || (theValue->getSoftRefCount() == 1 && theValue->noHardReferences()));
+    return (!theKey->fIsPrimary || (theValue->softRefCount == 1 && theValue->noHardReferences()));
+}
+
+void UnifiedCache::removeSoftRef(const SharedObject *value) const {
+    U_ASSERT(value->cachePtr == this);
+    U_ASSERT(value->softRefCount > 0);
+    if (--value->softRefCount == 0) {
+        --fNumValuesTotal;
+        if (value->noHardReferences()) {
+            delete value;
+        } else {
+            // This path only happens from flush(all). Which only happens from the
+            // UnifiedCache destructor.  Nulling out value.cacheptr changes the behavior
+            // of value.removeRef(), causing the deletion to be done there.
+            value->cachePtr = nullptr;
+        }
+    }
+}
+
+int32_t UnifiedCache::removeHardRef(const SharedObject *value) const {
+    int refCount = 0;
+    if (value) {
+        refCount = umtx_atomic_dec(&value->hardRefCount);
+        U_ASSERT(refCount >= 0);
+        if (refCount == 0) {
+            --fNumValuesInUse;
+        }
+    }
+    return refCount;
+}
+
+int32_t UnifiedCache::addHardRef(const SharedObject *value) const {
+    int refCount = 0;
+    if (value) {
+        refCount = umtx_atomic_inc(&value->hardRefCount);
+        U_ASSERT(refCount >= 1);
+        if (refCount == 1) {
+            fNumValuesInUse++;
+        }
+    }
+    return refCount;
 }
 
 U_NAMESPACE_END
diff --git a/src/third_party/icu/source/common/unifiedcache.h b/src/third_party/icu/source/common/unifiedcache.h
index 35dabbb..a31998d 100644
--- a/src/third_party/icu/source/common/unifiedcache.h
+++ b/src/third_party/icu/source/common/unifiedcache.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 * Copyright (C) 2015, International Business Machines Corporation and
@@ -32,13 +34,13 @@
  */
 class U_COMMON_API CacheKeyBase : public UObject {
  public:
-   CacheKeyBase() : fCreationStatus(U_ZERO_ERROR), fIsMaster(FALSE) {}
+   CacheKeyBase() : fCreationStatus(U_ZERO_ERROR), fIsPrimary(false) {}
 
    /**
     * Copy constructor. Needed to support cloning.
     */
    CacheKeyBase(const CacheKeyBase &other) 
-           : UObject(other), fCreationStatus(other.fCreationStatus), fIsMaster(FALSE) { }
+           : UObject(other), fCreationStatus(other.fCreationStatus), fIsPrimary(false) { }
    virtual ~CacheKeyBase();
 
    /**
@@ -86,7 +88,7 @@
    }
  private:
    mutable UErrorCode fCreationStatus;
-   mutable UBool fIsMaster;
+   mutable UBool fIsPrimary;
    friend class UnifiedCache;
 };
 
@@ -105,7 +107,7 @@
     */
    virtual int32_t hashCode() const {
        const char *s = typeid(T).name();
-       return ustr_hashCharsN(s, uprv_strlen(s));
+       return ustr_hashCharsN(s, static_cast<int32_t>(uprv_strlen(s)));
    }
 
    /**
@@ -135,20 +137,20 @@
  protected:
    Locale   fLoc;
  public:
-   LocaleCacheKey(const Locale &loc) : fLoc(loc) {};
+   LocaleCacheKey(const Locale &loc) : fLoc(loc) {}
    LocaleCacheKey(const LocaleCacheKey<T> &other)
            : CacheKey<T>(other), fLoc(other.fLoc) { }
    virtual ~LocaleCacheKey() { }
    virtual int32_t hashCode() const {
-       return 37 *CacheKey<T>::hashCode() + fLoc.hashCode();
+       return (int32_t)(37u * (uint32_t)CacheKey<T>::hashCode() + (uint32_t)fLoc.hashCode());
    }
    virtual UBool operator == (const CacheKeyBase &other) const {
        // reflexive
        if (this == &other) {
-           return TRUE;
+           return true;
        }
        if (!CacheKey<T>::operator == (other)) {
-           return FALSE;
+           return false;
        }
        // We know this and other are of same class because operator== on
        // CacheKey returned true.
@@ -188,7 +190,7 @@
    UnifiedCache(UErrorCode &status);
 
    /**
-    * Returns the cache instance.
+    * Return a pointer to the global cache instance.
     */
    static UnifiedCache *getInstance(UErrorCode &status);
 
@@ -292,7 +294,7 @@
 
    /**
     * Configures at what point evcition of unused entries will begin.
-    * Eviction is triggered whenever the number of unused entries exeeds
+    * Eviction is triggered whenever the number of evictable keys exeeds
     * BOTH count AND (number of in-use items) * (percentageOfInUseItems / 100).
     * Once the number of unused entries drops below one of these,
     * eviction ceases. Because eviction happens incrementally,
@@ -339,60 +341,214 @@
     */
    int32_t unusedCount() const;
 
-   virtual void incrementItemsInUse() const;
-   virtual void decrementItemsInUseWithLockingAndEviction() const;
-   virtual void decrementItemsInUse() const;
+   virtual void handleUnreferencedObject() const;
    virtual ~UnifiedCache();
+   
  private:
    UHashtable *fHashtable;
    mutable int32_t fEvictPos;
-   mutable int32_t fItemsInUseCount;
+   mutable int32_t fNumValuesTotal;
+   mutable int32_t fNumValuesInUse;
    int32_t fMaxUnused;
    int32_t fMaxPercentageOfInUse;
    mutable int64_t fAutoEvictedCount;
+   SharedObject *fNoValue;
+   
    UnifiedCache(const UnifiedCache &other);
    UnifiedCache &operator=(const UnifiedCache &other);
+   
+   /**
+    * Flushes the contents of the cache. If cache values hold references to other
+    * cache values then _flush should be called in a loop until it returns false.
+    * 
+    * On entry, gCacheMutex must be held.
+    * On exit, those values with are evictable are flushed.
+    * 
+    *  @param all if false flush evictable items only, which are those with no external
+    *                    references, plus those that can be safely recreated.<br>
+    *            if true, flush all elements. Any values (sharedObjects) with remaining
+    *                     hard (external) references are not deleted, but are detached from
+    *                     the cache, so that a subsequent removeRefs can delete them.
+    *                     _flush is not thread safe when all is true.
+    *   @return true if any value in cache was flushed or false otherwise.
+    */
    UBool _flush(UBool all) const;
+   
+   /**
+    * Gets value out of cache.
+    * On entry. gCacheMutex must not be held. value must be NULL. status
+    * must be U_ZERO_ERROR.
+    * On exit. value and status set to what is in cache at key or on cache
+    * miss the key's createObject() is called and value and status are set to
+    * the result of that. In this latter case, best effort is made to add the
+    * value and status to the cache. If createObject() fails to create a value,
+    * fNoValue is stored in cache, and value is set to NULL. Caller must call
+    * removeRef on value if non NULL.
+    */
    void _get(
            const CacheKeyBase &key,
            const SharedObject *&value,
            const void *creationContext,
            UErrorCode &status) const;
-   UBool _poll(
-           const CacheKeyBase &key,
-           const SharedObject *&value,
-           UErrorCode &status) const;
-   void _putNew(
-           const CacheKeyBase &key,
-           const SharedObject *value,
-           const UErrorCode creationStatus,
-           UErrorCode &status) const;
+
+    /**
+     * Attempts to fetch value and status for key from cache.
+     * On entry, gCacheMutex must not be held value must be NULL and status must
+     * be U_ZERO_ERROR.
+     * On exit, either returns false (In this
+     * case caller should try to create the object) or returns true with value
+     * pointing to the fetched value and status set to fetched status. When
+     * false is returned status may be set to failure if an in progress hash
+     * entry could not be made but value will remain unchanged. When true is
+     * returned, caller must call removeRef() on value.
+     */
+    UBool _poll(
+            const CacheKeyBase &key,
+            const SharedObject *&value,
+            UErrorCode &status) const;
+    
+    /**
+     * Places a new value and creationStatus in the cache for the given key.
+     * On entry, gCacheMutex must be held. key must not exist in the cache. 
+     * On exit, value and creation status placed under key. Soft reference added
+     * to value on successful add. On error sets status.
+     */
+    void _putNew(
+        const CacheKeyBase &key,
+        const SharedObject *value,
+        const UErrorCode creationStatus,
+        UErrorCode &status) const;
+           
+    /**
+     * Places value and status at key if there is no value at key or if cache
+     * entry for key is in progress. Otherwise, it leaves the current value and
+     * status there.
+     * 
+     * On entry. gCacheMutex must not be held. Value must be
+     * included in the reference count of the object to which it points.
+     * 
+     * On exit, value and status are changed to what was already in the cache if
+     * something was there and not in progress. Otherwise, value and status are left
+     * unchanged in which case they are placed in the cache on a best-effort basis.
+     * Caller must call removeRef() on value.
+     */
    void _putIfAbsentAndGet(
            const CacheKeyBase &key,
            const SharedObject *&value,
            UErrorCode &status) const;
-   const UHashElement *_nextElement() const;
+
+    /**
+     * Returns the next element in the cache round robin style.
+     * Returns nullptr if the cache is empty.
+     * On entry, gCacheMutex must be held.
+     */
+    const UHashElement *_nextElement() const;
+   
+   /**
+    * Return the number of cache items that would need to be evicted
+    * to bring usage into conformance with eviction policy.
+    * 
+    * An item corresponds to an entry in the hash table, a hash table element.
+    * 
+    * On entry, gCacheMutex must be held.
+    */
    int32_t _computeCountOfItemsToEvict() const;
+   
+   /**
+    * Run an eviction slice.
+    * On entry, gCacheMutex must be held.
+    * _runEvictionSlice runs a slice of the evict pipeline by examining the next
+    * 10 entries in the cache round robin style evicting them if they are eligible.
+    */
    void _runEvictionSlice() const;
-   void _registerMaster( 
-        const CacheKeyBase *theKey, const SharedObject *value) const;
+ 
+   /**
+    * Register a primary cache entry. A primary key is the first key to create
+    * a given  SharedObject value. Subsequent keys whose create function
+    * produce referneces to an already existing SharedObject are not primary -
+    * they can be evicted and subsequently recreated.
+    * 
+    * On entry, gCacheMutex must be held.
+    * On exit, items in use count incremented, entry is marked as a primary
+    * entry, and value registered with cache so that subsequent calls to
+    * addRef() and removeRef() on it correctly interact with the cache.
+    */
+   void _registerPrimary(const CacheKeyBase *theKey, const SharedObject *value) const;
+        
+   /**
+    * Store a value and creation error status in given hash entry.
+    * On entry, gCacheMutex must be held. Hash entry element must be in progress.
+    * value must be non NULL.
+    * On Exit, soft reference added to value. value and status stored in hash
+    * entry. Soft reference removed from previous stored value. Waiting
+    * threads notified.
+    */
    void _put(
            const UHashElement *element,
            const SharedObject *value,
            const UErrorCode status) const;
+    /**
+     * Remove a soft reference, and delete the SharedObject if no references remain.
+     * To be used from within the UnifiedCache implementation only.
+     * gCacheMutex must be held by caller.
+     * @param value the SharedObject to be acted on.
+     */
+   void removeSoftRef(const SharedObject *value) const;
+   
+   /**
+    * Increment the hard reference count of the given SharedObject.
+    * gCacheMutex must be held by the caller.
+    * Update numValuesEvictable on transitions between zero and one reference.
+    * 
+    * @param value The SharedObject to be referenced.
+    * @return the hard reference count after the addition.
+    */
+   int32_t addHardRef(const SharedObject *value) const;
+   
+  /**
+    * Decrement the hard reference count of the given SharedObject.
+    * gCacheMutex must be held by the caller.
+    * Update numValuesEvictable on transitions between one and zero reference.
+    * 
+    * @param value The SharedObject to be referenced.
+    * @return the hard reference count after the removal.
+    */
+   int32_t removeHardRef(const SharedObject *value) const;
+
+   
 #ifdef UNIFIED_CACHE_DEBUG
    void _dumpContents() const;
 #endif
-   static void copyPtr(const SharedObject *src, const SharedObject *&dest);
-   static void clearPtr(const SharedObject *&ptr);
-   static void _fetch(
-           const UHashElement *element,
-           const SharedObject *&value,
-           UErrorCode &status);
-   static UBool _inProgress(const UHashElement *element);
-   static UBool _inProgress(
-           const SharedObject *theValue, UErrorCode creationStatus);
-   static UBool _isEvictable(const UHashElement *element);
+   
+   /**
+    *  Fetch value and error code from a particular hash entry.
+    *  On entry, gCacheMutex must be held. value must be either NULL or must be
+    *  included in the ref count of the object to which it points.
+    *  On exit, value and status set to what is in the hash entry. Caller must
+    *  eventually call removeRef on value.
+    *  If hash entry is in progress, value will be set to gNoValue and status will
+    *  be set to U_ZERO_ERROR.
+    */
+   void _fetch(const UHashElement *element, const SharedObject *&value,
+                       UErrorCode &status) const;
+                       
+    /**
+     * Determine if given hash entry is in progress.
+     * On entry, gCacheMutex must be held.
+     */
+   UBool _inProgress(const UHashElement *element) const;
+   
+   /**
+    * Determine if given hash entry is in progress.
+    * On entry, gCacheMutex must be held.
+    */
+   UBool _inProgress(const SharedObject *theValue, UErrorCode creationStatus) const;
+   
+   /**
+    * Determine if given hash entry is eligible for eviction.
+    * On entry, gCacheMutex must be held.
+    */
+   UBool _isEvictable(const UHashElement *element) const;
 };
 
 U_NAMESPACE_END
diff --git a/src/third_party/icu/source/common/unifilt.cpp b/src/third_party/icu/source/common/unifilt.cpp
index 5e1a131..4ab0d9b 100644
--- a/src/third_party/icu/source/common/unifilt.cpp
+++ b/src/third_party/icu/source/common/unifilt.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
 * Copyright (c) 2001-2012, International Business Machines
diff --git a/src/third_party/icu/source/common/unifunct.cpp b/src/third_party/icu/source/common/unifunct.cpp
index b834eee..f3995b2 100644
--- a/src/third_party/icu/source/common/unifunct.cpp
+++ b/src/third_party/icu/source/common/unifunct.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
 * Copyright (c) 2002-2004, International Business Machines
diff --git a/src/third_party/icu/source/common/uniquecharstr.h b/src/third_party/icu/source/common/uniquecharstr.h
new file mode 100644
index 0000000..10cc924
--- /dev/null
+++ b/src/third_party/icu/source/common/uniquecharstr.h
@@ -0,0 +1,98 @@
+// © 2020 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+// uniquecharstr.h
+// created: 2020sep01 Frank Yung-Fong Tang
+
+#ifndef __UNIQUECHARSTR_H__
+#define __UNIQUECHARSTR_H__
+
+#include "charstr.h"
+#include "uassert.h"
+#include "uhash.h"
+
+U_NAMESPACE_BEGIN
+
+/**
+ * Stores NUL-terminated strings with duplicate elimination.
+ * Checks for unique UTF-16 string pointers and converts to invariant characters.
+ *
+ * Intended to be stack-allocated. Add strings, get a unique number for each,
+ * freeze the object, get a char * pointer for each string,
+ * call orphanCharStrings() to capture the string storage, and let this object go out of scope.
+ */
+class UniqueCharStrings {
+public:
+    UniqueCharStrings(UErrorCode &errorCode) : strings(nullptr) {
+        // Note: We hash on string contents but store stable char16_t * pointers.
+        // If the strings are stored in resource bundles which should be built with
+        // duplicate elimination, then we should be able to hash on just the pointer values.
+        uhash_init(&map, uhash_hashUChars, uhash_compareUChars, uhash_compareLong, &errorCode);
+        if (U_FAILURE(errorCode)) { return; }
+        strings = new CharString();
+        if (strings == nullptr) {
+            errorCode = U_MEMORY_ALLOCATION_ERROR;
+        }
+    }
+    ~UniqueCharStrings() {
+        uhash_close(&map);
+        delete strings;
+    }
+
+    /** Returns/orphans the CharString that contains all strings. */
+    CharString *orphanCharStrings() {
+        CharString *result = strings;
+        strings = nullptr;
+        return result;
+    }
+
+    /**
+     * Adds a string and returns a unique number for it.
+     * The string's buffer contents must not change, nor move around in memory,
+     * while this UniqueCharStrings is in use.
+     * The string contents must be NUL-terminated exactly at s.length().
+     *
+     * Best used with read-only-alias UnicodeString objects that point to
+     * stable storage, such as strings returned by resource bundle functions.
+     */
+    int32_t add(const UnicodeString &s, UErrorCode &errorCode) {
+        if (U_FAILURE(errorCode)) { return 0; }
+        if (isFrozen) {
+            errorCode = U_NO_WRITE_PERMISSION;
+            return 0;
+        }
+        // The string points into the resource bundle.
+        const char16_t *p = s.getBuffer();
+        int32_t oldIndex = uhash_geti(&map, p);
+        if (oldIndex != 0) {  // found duplicate
+            return oldIndex;
+        }
+        // Explicit NUL terminator for the previous string.
+        // The strings object is also terminated with one implicit NUL.
+        strings->append(0, errorCode);
+        int32_t newIndex = strings->length();
+        strings->appendInvariantChars(s, errorCode);
+        uhash_puti(&map, const_cast<char16_t *>(p), newIndex, &errorCode);
+        return newIndex;
+    }
+
+    void freeze() { isFrozen = true; }
+
+    /**
+     * Returns a string pointer for its unique number, if this object is frozen.
+     * Otherwise nullptr.
+     */
+    const char *get(int32_t i) const {
+        U_ASSERT(isFrozen);
+        return isFrozen && i > 0 ? strings->data() + i : nullptr;
+    }
+
+private:
+    UHashtable map;
+    CharString *strings;
+    bool isFrozen = false;
+};
+
+U_NAMESPACE_END
+
+#endif  // __UNIQUECHARSTR_H__
diff --git a/src/third_party/icu/source/common/uniset.cpp b/src/third_party/icu/source/common/uniset.cpp
index a122e6d..69193f0 100644
--- a/src/third_party/icu/source/common/uniset.cpp
+++ b/src/third_party/icu/source/common/uniset.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
 *   Copyright (C) 1999-2015, International Business Machines
@@ -8,11 +10,14 @@
 **********************************************************************
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/utypes.h"
 #include "unicode/parsepos.h"
 #include "unicode/symtable.h"
 #include "unicode/uniset.h"
+#include "unicode/ustring.h"
 #include "unicode/utf8.h"
 #include "unicode/utf16.h"
 #include "ruleiter.h"
@@ -52,11 +57,8 @@
 // LOW <= all valid values. ZERO for codepoints
 #define UNICODESET_LOW 0x000000
 
-// initial storage. Must be >= 0
-#define START_EXTRA 16
-
-// extra amount for growth. Must be >= 0
-#define GROW_EXTRA START_EXTRA
+/** Max list [0, 1, 2, ..., max code point, HIGH] */
+constexpr int32_t MAX_LENGTH = UNICODESET_HIGH + 1;
 
 U_NAMESPACE_BEGIN
 
@@ -136,6 +138,18 @@
     return a.compare(b);
 }
 
+UBool UnicodeSet::hasStrings() const {
+    return strings != nullptr && !strings->isEmpty();
+}
+
+int32_t UnicodeSet::stringsSize() const {
+    return strings == nullptr ? 0 : strings->size();
+}
+
+UBool UnicodeSet::stringsContains(const UnicodeString &s) const {
+    return strings != nullptr && strings->contains((void*) &s);
+}
+
 //----------------------------------------------------------------
 // Constructors &c
 //----------------------------------------------------------------
@@ -143,23 +157,8 @@
 /**
  * Constructs an empty set.
  */
-UnicodeSet::UnicodeSet() :
-    len(1), capacity(1 + START_EXTRA), list(0), bmpSet(0), buffer(0),
-    bufferCapacity(0), patLen(0), pat(NULL), strings(NULL), stringSpan(NULL),
-    fFlags(0)
-{
-    UErrorCode status = U_ZERO_ERROR;
-    allocateStrings(status);
-    if (U_FAILURE(status)) {
-        return;
-    }
-    list = (UChar32*) uprv_malloc(sizeof(UChar32) * capacity);
-    if(list!=NULL){
-        list[0] = UNICODESET_HIGH;
-    } else { // If memory allocation failed, set to bogus state.
-        setToBogus();
-        return;
-    }
+UnicodeSet::UnicodeSet() {
+    list[0] = UNICODESET_HIGH;
     _dbgct(this);
 }
 
@@ -170,86 +169,39 @@
  * @param start first character, inclusive, of range
  * @param end last character, inclusive, of range
  */
-UnicodeSet::UnicodeSet(UChar32 start, UChar32 end) :
-    len(1), capacity(1 + START_EXTRA), list(0), bmpSet(0), buffer(0),
-    bufferCapacity(0), patLen(0), pat(NULL), strings(NULL), stringSpan(NULL),
-    fFlags(0)
-{
-    UErrorCode status = U_ZERO_ERROR;
-    allocateStrings(status);
-    if (U_FAILURE(status)) {
-        return;
-    }
-    list = (UChar32*) uprv_malloc(sizeof(UChar32) * capacity);
-    if(list!=NULL){
-        list[0] = UNICODESET_HIGH;
-        complement(start, end);
-    } else { // If memory allocation failed, set to bogus state.
-        setToBogus();
-        return;
-    }
+UnicodeSet::UnicodeSet(UChar32 start, UChar32 end) {
+    list[0] = UNICODESET_HIGH;
+    add(start, end);
     _dbgct(this);
 }
 
 /**
  * Constructs a set that is identical to the given UnicodeSet.
  */
-UnicodeSet::UnicodeSet(const UnicodeSet& o) :
-    UnicodeFilter(o),
-    len(0), capacity(o.isFrozen() ? o.len : o.len + GROW_EXTRA), list(0),
-    bmpSet(0),
-    buffer(0), bufferCapacity(0),
-    patLen(0), pat(NULL), strings(NULL), stringSpan(NULL),
-    fFlags(0)
-{
-    UErrorCode status = U_ZERO_ERROR;
-    allocateStrings(status);
-    if (U_FAILURE(status)) {
-        return;
-    }
-    list = (UChar32*) uprv_malloc(sizeof(UChar32) * capacity);
-    if(list!=NULL){
-        *this = o;
-    } else { // If memory allocation failed, set to bogus state.
-        setToBogus();
-        return;
-    }
+UnicodeSet::UnicodeSet(const UnicodeSet& o) : UnicodeFilter(o) {
+    *this = o;
     _dbgct(this);
 }
 
 // Copy-construct as thawed.
-UnicodeSet::UnicodeSet(const UnicodeSet& o, UBool /* asThawed */) :
-    UnicodeFilter(o),
-    len(0), capacity(o.len + GROW_EXTRA), list(0),
-    bmpSet(0),
-    buffer(0), bufferCapacity(0),
-    patLen(0), pat(NULL), strings(NULL), stringSpan(NULL),
-    fFlags(0)
-{
-    UErrorCode status = U_ZERO_ERROR;
-    allocateStrings(status);
-    if (U_FAILURE(status)) {
-        return;
-    }
-    list = (UChar32*) uprv_malloc(sizeof(UChar32) * capacity);
-    if(list!=NULL){
+UnicodeSet::UnicodeSet(const UnicodeSet& o, UBool /* asThawed */) : UnicodeFilter(o) {
+    if (ensureCapacity(o.len)) {
         // *this = o except for bmpSet and stringSpan
         len = o.len;
-        uprv_memcpy(list, o.list, len*sizeof(UChar32));
-        if (strings != NULL && o.strings != NULL) {
-            strings->assign(*o.strings, cloneUnicodeString, status);
-        } else { // Invalid strings.
-            setToBogus();
-            return;
+        uprv_memcpy(list, o.list, (size_t)len*sizeof(UChar32));
+        if (o.hasStrings()) {
+            UErrorCode status = U_ZERO_ERROR;
+            if (!allocateStrings(status) ||
+                    (strings->assign(*o.strings, cloneUnicodeString, status), U_FAILURE(status))) {
+                setToBogus();
+                return;
+            }
         }
         if (o.pat) {
-            setPattern(UnicodeString(o.pat, o.patLen));
+            setPattern(o.pat, o.patLen);
         }
-    } else { // If memory allocation failed, set to bogus state.
-        setToBogus();
-        return;
+        _dbgct(this);
     }
-    _dbgct(this);
 }
 
 /**
@@ -257,9 +209,11 @@
  */
 UnicodeSet::~UnicodeSet() {
     _dbgdt(this); // first!
-    uprv_free(list);
+    if (list != stackList) {
+        uprv_free(list);
+    }
     delete bmpSet;
-    if (buffer) {
+    if (buffer != stackList) {
         uprv_free(buffer);
     }
     delete strings;
@@ -271,6 +225,10 @@
  * Assigns this object to be a copy of another.
  */
 UnicodeSet& UnicodeSet::operator=(const UnicodeSet& o) {
+    return copyFrom(o, FALSE);
+}
+
+UnicodeSet& UnicodeSet::copyFrom(const UnicodeSet& o, UBool asThawed) {
     if (this == &o) {
         return *this;
     }
@@ -281,31 +239,30 @@
         setToBogus();
         return *this;
     }
-    UErrorCode ec = U_ZERO_ERROR;
-    ensureCapacity(o.len, ec);
-    if (U_FAILURE(ec)) {
-        return *this; // There is no way to report this error :-(
+    if (!ensureCapacity(o.len)) {
+        // ensureCapacity will mark the UnicodeSet as Bogus if OOM failure happens.
+        return *this;
     }
     len = o.len;
-    uprv_memcpy(list, o.list, len*sizeof(UChar32));
-    if (o.bmpSet == NULL) {
-        bmpSet = NULL;
-    } else {
+    uprv_memcpy(list, o.list, (size_t)len*sizeof(UChar32));
+    if (o.bmpSet != nullptr && !asThawed) {
         bmpSet = new BMPSet(*o.bmpSet, list, len);
         if (bmpSet == NULL) { // Check for memory allocation error.
             setToBogus();
             return *this;
         }
     }
-    if (strings != NULL && o.strings != NULL) {
-        strings->assign(*o.strings, cloneUnicodeString, ec);
-    } else { // Invalid strings.
-        setToBogus();
-        return *this;
+    if (o.hasStrings()) {
+        UErrorCode status = U_ZERO_ERROR;
+        if ((strings == nullptr && !allocateStrings(status)) ||
+                (strings->assign(*o.strings, cloneUnicodeString, status), U_FAILURE(status))) {
+            setToBogus();
+            return *this;
+        }
+    } else if (hasStrings()) {
+        strings->removeAllElements();
     }
-    if (o.stringSpan == NULL) {
-        stringSpan = NULL;
-    } else {
+    if (o.stringSpan != nullptr && !asThawed) {
         stringSpan = new UnicodeSetStringSpan(*o.stringSpan, *strings);
         if (stringSpan == NULL) { // Check for memory allocation error.
             setToBogus();
@@ -314,7 +271,7 @@
     }
     releasePattern();
     if (o.pat) {
-        setPattern(UnicodeString(o.pat, o.patLen));
+        setPattern(o.pat, o.patLen);
     }
     return *this;
 }
@@ -324,11 +281,11 @@
  * to support cloning in order to allow classes using
  * UnicodeMatchers, such as Transliterator, to implement cloning.
  */
-UnicodeFunctor* UnicodeSet::clone() const {
+UnicodeSet* UnicodeSet::clone() const {
     return new UnicodeSet(*this);
 }
 
-UnicodeFunctor *UnicodeSet::cloneAsThawed() const {
+UnicodeSet *UnicodeSet::cloneAsThawed() const {
     return new UnicodeSet(*this, TRUE);
 }
 
@@ -347,7 +304,8 @@
     for (int32_t i = 0; i < len; ++i) {
         if (list[i] != o.list[i]) return FALSE;
     }
-    if (*strings != *o.strings) return FALSE;
+    if (hasStrings() != o.hasStrings()) { return FALSE; }
+    if (hasStrings() && *strings != *o.strings) return FALSE;
     return TRUE;
 }
 
@@ -358,12 +316,12 @@
  * @see Object#hashCode()
  */
 int32_t UnicodeSet::hashCode(void) const {
-    int32_t result = len;
+    uint32_t result = static_cast<uint32_t>(len);
     for (int32_t i = 0; i < len; ++i) {
-        result *= 1000003;
+        result *= 1000003u;
         result += list[i];
     }
-    return result;
+    return static_cast<int32_t>(result);
 }
 
 //----------------------------------------------------------------
@@ -383,7 +341,7 @@
     for (int32_t i = 0; i < count; ++i) {
         n += getRangeEnd(i) - getRangeStart(i) + 1;
     }
-    return n + strings->size();
+    return n + stringsSize();
 }
 
 /**
@@ -392,7 +350,7 @@
  * @return <tt>true</tt> if this set contains no elements.
  */
 UBool UnicodeSet::isEmpty(void) const {
-    return len == 1 && strings->size() == 0;
+    return len == 1 && !hasStrings();
 }
 
 /**
@@ -492,7 +450,7 @@
     if (s.length() == 0) return FALSE;
     int32_t cp = getSingleCP(s);
     if (cp < 0) {
-        return strings->contains((void*) &s);
+        return stringsContains(s);
     } else {
         return contains((UChar32) cp);
     }
@@ -514,8 +472,7 @@
             return FALSE;
         }
     }
-    if (!strings->containsAll(*c.strings)) return FALSE;
-    return TRUE;
+    return !c.hasStrings() || (strings != nullptr && strings->containsAll(*c.strings));
 }
 
 /**
@@ -561,8 +518,7 @@
             return FALSE;
         }
     }
-    if (!strings->containsNone(*c.strings)) return FALSE;
-    return TRUE;
+    return strings == nullptr || !c.hasStrings() || strings->containsNone(*c.strings);
 }
 
 /**
@@ -603,7 +559,7 @@
             return TRUE;
         }
     }
-    if (strings->size() != 0) {
+    if (hasStrings()) {
         for (i=0; i<strings->size(); ++i) {
             const UnicodeString& s = *(const UnicodeString*)strings->elementAt(i);
             //if (s.length() == 0) {
@@ -638,7 +594,7 @@
             return U_MISMATCH;
         }
     } else {
-        if (strings->size() != 0) { // try strings first
+        if (hasStrings()) { // try strings first
 
             // might separate forward and backward loops later
             // for now they are combined
@@ -839,7 +795,39 @@
  */
 UnicodeSet& UnicodeSet::add(UChar32 start, UChar32 end) {
     if (pinCodePoint(start) < pinCodePoint(end)) {
-        UChar32 range[3] = { start, end+1, UNICODESET_HIGH };
+        UChar32 limit = end + 1;
+        // Fast path for adding a new range after the last one.
+        // Odd list length: [..., lastStart, lastLimit, HIGH]
+        if ((len & 1) != 0) {
+            // If the list is empty, set lastLimit low enough to not be adjacent to 0.
+            UChar32 lastLimit = len == 1 ? -2 : list[len - 2];
+            if (lastLimit <= start && !isFrozen() && !isBogus()) {
+                if (lastLimit == start) {
+                    // Extend the last range.
+                    list[len - 2] = limit;
+                    if (limit == UNICODESET_HIGH) {
+                        --len;
+                    }
+                } else {
+                    list[len - 1] = start;
+                    if (limit < UNICODESET_HIGH) {
+                        if (ensureCapacity(len + 2)) {
+                            list[len++] = limit;
+                            list[len++] = UNICODESET_HIGH;
+                        }
+                    } else {  // limit == UNICODESET_HIGH
+                        if (ensureCapacity(len + 1)) {
+                            list[len++] = UNICODESET_HIGH;
+                        }
+                    }
+                }
+                releasePattern();
+                return *this;
+            }
+        }
+        // This is slow. Could be much faster using findCodePoint(start)
+        // and modifying the list, dealing with adjacent & overlapping ranges.
+        UChar32 range[3] = { start, limit, UNICODESET_HIGH };
         add(range, 2, 0);
     } else if (start == end) {
         add(start);
@@ -908,10 +896,9 @@
         list[i] = c;
         // if we touched the HIGH mark, then add a new one
         if (c == (UNICODESET_HIGH - 1)) {
-            UErrorCode status = U_ZERO_ERROR;
-            ensureCapacity(len+1, status);
-            if (U_FAILURE(status)) {
-                return *this; // There is no way to report this error :-(
+            if (!ensureCapacity(len+1)) {
+                // ensureCapacity will mark the object as Bogus if OOM failure happens.
+                return *this;
             }
             list[len++] = UNICODESET_HIGH;
         }
@@ -953,20 +940,13 @@
         //                             ^
         //                             list[i]
 
-        UErrorCode status = U_ZERO_ERROR;
-        ensureCapacity(len+2, status);
-        if (U_FAILURE(status)) {
-            return *this; // There is no way to report this error :-(
+        if (!ensureCapacity(len+2)) {
+            // ensureCapacity will mark the object as Bogus if OOM failure happens.
+            return *this;
         }
 
-        //for (int32_t k=len-1; k>=i; --k) {
-        //    list[k+2] = list[k];
-        //}
-        UChar32* src = list + len;
-        UChar32* dst = src + 2;
-        UChar32* srclimit = list + i;
-        while (src > srclimit) *(--dst) = *(--src);
-
+        UChar32 *p = list + i;
+        uprv_memmove(p + 2, p, (len - i) * sizeof(*p));
         list[i] = c;
         list[i+1] = c+1;
         len += 2;
@@ -1002,7 +982,7 @@
     if (s.length() == 0 || isFrozen() || isBogus()) return *this;
     int32_t cp = getSingleCP(s);
     if (cp < 0) {
-        if (!strings->contains((void*) &s)) {
+        if (!stringsContains(s)) {
             _add(s);
             releasePattern();
         }
@@ -1021,12 +1001,16 @@
     if (isFrozen() || isBogus()) {
         return;
     }
+    UErrorCode ec = U_ZERO_ERROR;
+    if (strings == nullptr && !allocateStrings(ec)) {
+        setToBogus();
+        return;
+    }
     UnicodeString* t = new UnicodeString(s);
     if (t == NULL) { // Check for memory allocation error.
         setToBogus();
         return;
     }
-    UErrorCode ec = U_ZERO_ERROR;
     strings->sortedInsert(t, compareUnicodeString, ec);
     if (U_FAILURE(ec)) {
         setToBogus();
@@ -1109,7 +1093,10 @@
 }
 
 UnicodeSet& UnicodeSet::removeAllStrings() {
-    strings->removeAllElements();
+    if (!isFrozen() && hasStrings()) {
+        strings->removeAllElements();
+        releasePattern();
+    }
     return *this;
 }
 
@@ -1205,8 +1192,9 @@
     if (s.length() == 0 || isFrozen() || isBogus()) return *this;
     int32_t cp = getSingleCP(s);
     if (cp < 0) {
-        strings->removeElement((void*) &s);
-        releasePattern();
+        if (strings != nullptr && strings->removeElement((void*) &s)) {
+            releasePattern();
+        }
     } else {
         remove((UChar32)cp, (UChar32)cp);
     }
@@ -1248,24 +1236,17 @@
     if (isFrozen() || isBogus()) {
         return *this;
     }
-    UErrorCode status = U_ZERO_ERROR;
     if (list[0] == UNICODESET_LOW) {
-        ensureBufferCapacity(len-1, status);
-        if (U_FAILURE(status)) {
-            return *this;
-        }
-        uprv_memcpy(buffer, list + 1, (len-1)*sizeof(UChar32));
+        uprv_memmove(list, list + 1, (size_t)(len-1)*sizeof(UChar32));
         --len;
     } else {
-        ensureBufferCapacity(len+1, status);
-        if (U_FAILURE(status)) {
+        if (!ensureCapacity(len+1)) {
             return *this;
         }
-        uprv_memcpy(buffer + 1, list, len*sizeof(UChar32));
-        buffer[0] = UNICODESET_LOW;
+        uprv_memmove(list + 1, list, (size_t)len*sizeof(UChar32));
+        list[0] = UNICODESET_LOW;
         ++len;
     }
-    swapBuffers();
     releasePattern();
     return *this;
 }
@@ -1282,7 +1263,7 @@
     if (s.length() == 0 || isFrozen() || isBogus()) return *this;
     int32_t cp = getSingleCP(s);
     if (cp < 0) {
-        if (strings->contains((void*) &s)) {
+        if (stringsContains(s)) {
             strings->removeElement((void*) &s);
         } else {
             _add(s);
@@ -1313,7 +1294,7 @@
     if ( c.strings!=NULL ) {
         for (int32_t i=0; i<c.strings->size(); ++i) {
             const UnicodeString* s = (const UnicodeString*)c.strings->elementAt(i);
-            if (!strings->contains((void*) s)) {
+            if (!stringsContains(*s)) {
                 _add(*s);
             }
         }
@@ -1335,7 +1316,13 @@
         return *this;
     }
     retain(c.list, c.len, 0);
-    strings->retainAll(*c.strings);
+    if (hasStrings()) {
+        if (!c.hasStrings()) {
+            strings->removeAllElements();
+        } else {
+            strings->retainAll(*c.strings);
+        }
+    }
     return *this;
 }
 
@@ -1353,7 +1340,9 @@
         return *this;
     }
     retain(c.list, c.len, 2);
-    strings->removeAll(*c.strings);
+    if (hasStrings() && c.hasStrings()) {
+        strings->removeAll(*c.strings);
+    }
     return *this;
 }
 
@@ -1371,10 +1360,12 @@
     }
     exclusiveOr(c.list, c.len, 0);
 
-    for (int32_t i=0; i<c.strings->size(); ++i) {
-        void* e = c.strings->elementAt(i);
-        if (!strings->removeElement(e)) {
-            _add(*(const UnicodeString*)e);
+    if (c.strings != nullptr) {
+        for (int32_t i=0; i<c.strings->size(); ++i) {
+            void* e = c.strings->elementAt(i);
+            if (strings == nullptr || !strings->removeElement(e)) {
+                _add(*(const UnicodeString*)e);
+            }
         }
     }
     return *this;
@@ -1388,18 +1379,14 @@
     if (isFrozen()) {
         return *this;
     }
-    if (list != NULL) {
-        list[0] = UNICODESET_HIGH;
-    }
+    list[0] = UNICODESET_HIGH;
     len = 1;
     releasePattern();
     if (strings != NULL) {
         strings->removeAllElements();
     }
-    if (list != NULL && strings != NULL) {
-        // Remove bogus
-        fFlags = 0;
-    }
+    // Remove bogus
+    fFlags = 0;
     return *this;
 }
 
@@ -1433,10 +1420,6 @@
     return list[index*2 + 1] - 1;
 }
 
-int32_t UnicodeSet::getStringCount() const {
-    return strings->size();
-}
-
 const UnicodeString* UnicodeSet::getString(int32_t index) const {
     return (const UnicodeString*) strings->elementAt(index);
 }
@@ -1450,22 +1433,32 @@
         return *this;
     }
     // Delete buffer first to defragment memory less.
-    if (buffer != NULL) {
+    if (buffer != stackList) {
         uprv_free(buffer);
         buffer = NULL;
+        bufferCapacity = 0;
     }
-    if (len < capacity) {
-        // Make the capacity equal to len or 1.
-        // We don't want to realloc of 0 size.
-        int32_t newCapacity = len + (len == 0);
-        UChar32* temp = (UChar32*) uprv_realloc(list, sizeof(UChar32) * newCapacity);
+    if (list == stackList) {
+        // pass
+    } else if (len <= INITIAL_CAPACITY) {
+        uprv_memcpy(stackList, list, len * sizeof(UChar32));
+        uprv_free(list);
+        list = stackList;
+        capacity = INITIAL_CAPACITY;
+    } else if ((len + 7) < capacity) {
+        // If we have more than a little unused capacity, shrink it to len.
+        UChar32* temp = (UChar32*) uprv_realloc(list, sizeof(UChar32) * len);
         if (temp) {
             list = temp;
-            capacity = newCapacity;
+            capacity = len;
         }
         // else what the heck happened?! We allocated less memory!
         // Oh well. We'll keep our original array.
     }
+    if (strings != nullptr && strings->isEmpty()) {
+        delete strings;
+        strings = nullptr;
+    }
     return *this;
 }
 
@@ -1476,10 +1469,8 @@
 /**
  * Deserialize constructor.
  */
-UnicodeSet::UnicodeSet(const uint16_t data[], int32_t dataLen, ESerialization serialization, UErrorCode &ec)
-  : len(1), capacity(1+START_EXTRA), list(0), bmpSet(0), buffer(0),
-    bufferCapacity(0), patLen(0), pat(NULL), strings(NULL), stringSpan(NULL),
-    fFlags(0) {
+UnicodeSet::UnicodeSet(const uint16_t data[], int32_t dataLen, ESerialization serialization,
+                       UErrorCode &ec) {
 
   if(U_FAILURE(ec)) {
     setToBogus();
@@ -1494,24 +1485,15 @@
     return;
   }
 
-  allocateStrings(ec);
-  if (U_FAILURE(ec)) {
-    setToBogus();
-    return;
-  }
-
   // bmp?
   int32_t headerSize = ((data[0]&0x8000)) ?2:1;
   int32_t bmpLength = (headerSize==1)?data[0]:data[1];
 
-  len = (((data[0]&0x7FFF)-bmpLength)/2)+bmpLength;
+  int32_t newLength = (((data[0]&0x7FFF)-bmpLength)/2)+bmpLength;
 #ifdef DEBUG_SERIALIZE
-  printf("dataLen %d headerSize %d bmpLen %d len %d. data[0]=%X/%X/%X/%X\n", dataLen,headerSize,bmpLength,len, data[0],data[1],data[2],data[3]);
+  printf("dataLen %d headerSize %d bmpLen %d len %d. data[0]=%X/%X/%X/%X\n", dataLen,headerSize,bmpLength,newLength, data[0],data[1],data[2],data[3]);
 #endif
-  capacity = len+1;
-  list = (UChar32*) uprv_malloc(sizeof(UChar32) * capacity);
-  if(!list || U_FAILURE(ec)) {
-    setToBogus();
+  if(!ensureCapacity(newLength + 1)) {  // +1 for HIGH
     return;
   }
   // copy bmp
@@ -1523,15 +1505,18 @@
 #endif
   }
   // copy smp
-  for(i=bmpLength;i<len;i++) {
+  for(i=bmpLength;i<newLength;i++) {
     list[i] = ((UChar32)data[headerSize+bmpLength+(i-bmpLength)*2+0] << 16) +
               ((UChar32)data[headerSize+bmpLength+(i-bmpLength)*2+1]);
 #ifdef DEBUG_SERIALIZE
     printf("<<32@%d+[%d] %lX\n", headerSize+bmpLength+i, i, list[i]);
 #endif
   }
-  // terminator
-  list[len++]=UNICODESET_HIGH;
+  U_ASSERT(i == newLength);
+  if (i == 0 || list[i - 1] != UNICODESET_HIGH) {
+    list[i++] = UNICODESET_HIGH;
+  }
+  len = i;
 }
 
 
@@ -1652,32 +1637,65 @@
     return TRUE;
 }
 
-void UnicodeSet::ensureCapacity(int32_t newLen, UErrorCode& ec) {
-    if (newLen <= capacity)
-        return;
-    UChar32* temp = (UChar32*) uprv_realloc(list, sizeof(UChar32) * (newLen + GROW_EXTRA));
-    if (temp == NULL) {
-        ec = U_MEMORY_ALLOCATION_ERROR;
-        setToBogus();
-        return;
+int32_t UnicodeSet::nextCapacity(int32_t minCapacity) {
+    // Grow exponentially to reduce the frequency of allocations.
+    if (minCapacity < INITIAL_CAPACITY) {
+        return minCapacity + INITIAL_CAPACITY;
+    } else if (minCapacity <= 2500) {
+        return 5 * minCapacity;
+    } else {
+        int32_t newCapacity = 2 * minCapacity;
+        if (newCapacity > MAX_LENGTH) {
+            newCapacity = MAX_LENGTH;
+        }
+        return newCapacity;
     }
-    list = temp;
-    capacity = newLen + GROW_EXTRA;
-    // else we keep the original contents on the memory failure.
 }
 
-void UnicodeSet::ensureBufferCapacity(int32_t newLen, UErrorCode& ec) {
-    if (buffer != NULL && newLen <= bufferCapacity)
-        return;
-    UChar32* temp = (UChar32*) uprv_realloc(buffer, sizeof(UChar32) * (newLen + GROW_EXTRA));
+bool UnicodeSet::ensureCapacity(int32_t newLen) {
+    if (newLen > MAX_LENGTH) {
+        newLen = MAX_LENGTH;
+    }
+    if (newLen <= capacity) {
+        return true;
+    }
+    int32_t newCapacity = nextCapacity(newLen);
+    UChar32* temp = (UChar32*) uprv_malloc(newCapacity * sizeof(UChar32));
     if (temp == NULL) {
-        ec = U_MEMORY_ALLOCATION_ERROR;
+        setToBogus(); // set the object to bogus state if an OOM failure occurred.
+        return false;
+    }
+    // Copy only the actual contents.
+    uprv_memcpy(temp, list, len * sizeof(UChar32));
+    if (list != stackList) {
+        uprv_free(list);
+    }
+    list = temp;
+    capacity = newCapacity;
+    return true;
+}
+
+bool UnicodeSet::ensureBufferCapacity(int32_t newLen) {
+    if (newLen > MAX_LENGTH) {
+        newLen = MAX_LENGTH;
+    }
+    if (newLen <= bufferCapacity) {
+        return true;
+    }
+    int32_t newCapacity = nextCapacity(newLen);
+    UChar32* temp = (UChar32*) uprv_malloc(newCapacity * sizeof(UChar32));
+    if (temp == NULL) {
         setToBogus();
-        return;
+        return false;
+    }
+    // The buffer has no contents to be copied.
+    // It is always filled from scratch after this call.
+    if (buffer != stackList) {
+        uprv_free(buffer);
     }
     buffer = temp;
-    bufferCapacity = newLen + GROW_EXTRA;
-    // else we keep the original contents on the memory failure.
+    bufferCapacity = newCapacity;
+    return true;
 }
 
 /**
@@ -1714,9 +1732,7 @@
     if (isFrozen() || isBogus()) {
         return;
     }
-    UErrorCode status = U_ZERO_ERROR;
-    ensureBufferCapacity(len + otherLen, status);
-    if (U_FAILURE(status)) {
+    if (!ensureBufferCapacity(len + otherLen)) {
         return;
     }
 
@@ -1764,9 +1780,7 @@
     if (isFrozen() || isBogus() || other==NULL) {
         return;
     }
-    UErrorCode status = U_ZERO_ERROR;
-    ensureBufferCapacity(len + otherLen, status);
-    if (U_FAILURE(status)) {
+    if (!ensureBufferCapacity(len + otherLen)) {
         return;
     }
 
@@ -1877,9 +1891,7 @@
     if (isFrozen() || isBogus()) {
         return;
     }
-    UErrorCode status = U_ZERO_ERROR;
-    ensureBufferCapacity(len + otherLen, status);
-    if (U_FAILURE(status)) {
+    if (!ensureBufferCapacity(len + otherLen)) {
         return;
     }
 
@@ -2125,12 +2137,14 @@
         }
     }
 
-    for (int32_t i = 0; i<strings->size(); ++i) {
-        result.append(OPEN_BRACE);
-        _appendToPat(result,
-                     *(const UnicodeString*) strings->elementAt(i),
-                     escapeUnprintable);
-        result.append(CLOSE_BRACE);
+    if (strings != nullptr) {
+        for (int32_t i = 0; i<strings->size(); ++i) {
+            result.append(OPEN_BRACE);
+            _appendToPat(result,
+                         *(const UnicodeString*) strings->elementAt(i),
+                         escapeUnprintable);
+            result.append(CLOSE_BRACE);
+        }
     }
     return result.append(SET_CLOSE);
 }
@@ -2149,45 +2163,29 @@
 /**
 * Set the new pattern to cache.
 */
-void UnicodeSet::setPattern(const UnicodeString& newPat) {
+void UnicodeSet::setPattern(const char16_t *newPat, int32_t newPatLen) {
     releasePattern();
-    int32_t newPatLen = newPat.length();
     pat = (UChar *)uprv_malloc((newPatLen + 1) * sizeof(UChar));
     if (pat) {
         patLen = newPatLen;
-        newPat.extractBetween(0, patLen, pat);
+        u_memcpy(pat, newPat, patLen);
         pat[patLen] = 0;
     }
     // else we don't care if malloc failed. This was just a nice cache.
     // We can regenerate an equivalent pattern later when requested.
 }
 
-UnicodeFunctor *UnicodeSet::freeze() {
+UnicodeSet *UnicodeSet::freeze() {
     if(!isFrozen() && !isBogus()) {
-        // Do most of what compact() does before freezing because
-        // compact() will not work when the set is frozen.
-        // Small modification: Don't shrink if the savings would be tiny (<=GROW_EXTRA).
-
-        // Delete buffer first to defragment memory less.
-        if (buffer != NULL) {
-            uprv_free(buffer);
-            buffer = NULL;
-        }
-        if (capacity > (len + GROW_EXTRA)) {
-            // Make the capacity equal to len or 1.
-            // We don't want to realloc of 0 size.
-            capacity = len + (len == 0);
-            list = (UChar32*) uprv_realloc(list, sizeof(UChar32) * capacity);
-            if (list == NULL) { // Check for memory allocation error.
-                setToBogus();
-                return this;
-            }
-        }
+        compact();
 
         // Optimize contains() and span() and similar functions.
-        if (!strings->isEmpty()) {
+        if (hasStrings()) {
             stringSpan = new UnicodeSetStringSpan(*this, *strings, UnicodeSetStringSpan::ALL);
-            if (stringSpan != NULL && !stringSpan->needsStringSpanUTF16()) {
+            if (stringSpan == nullptr) {
+                setToBogus();
+                return this;
+            } else if (!stringSpan->needsStringSpanUTF16()) {
                 // All strings are irrelevant for span() etc. because
                 // all of each string's code points are contained in this set.
                 // Do not check needsStringSpanUTF8() because UTF-8 has at most as
@@ -2220,7 +2218,7 @@
     }
     if(stringSpan!=NULL) {
         return stringSpan->span(s, length, spanCondition);
-    } else if(!strings->isEmpty()) {
+    } else if(hasStrings()) {
         uint32_t which= spanCondition==USET_SPAN_NOT_CONTAINED ?
                             UnicodeSetStringSpan::FWD_UTF16_NOT_CONTAINED :
                             UnicodeSetStringSpan::FWD_UTF16_CONTAINED;
@@ -2257,7 +2255,7 @@
     }
     if(stringSpan!=NULL) {
         return stringSpan->spanBack(s, length, spanCondition);
-    } else if(!strings->isEmpty()) {
+    } else if(hasStrings()) {
         uint32_t which= spanCondition==USET_SPAN_NOT_CONTAINED ?
                             UnicodeSetStringSpan::BACK_UTF16_NOT_CONTAINED :
                             UnicodeSetStringSpan::BACK_UTF16_CONTAINED;
@@ -2295,7 +2293,7 @@
     }
     if(stringSpan!=NULL) {
         return stringSpan->spanUTF8((const uint8_t *)s, length, spanCondition);
-    } else if(!strings->isEmpty()) {
+    } else if(hasStrings()) {
         uint32_t which= spanCondition==USET_SPAN_NOT_CONTAINED ?
                             UnicodeSetStringSpan::FWD_UTF8_NOT_CONTAINED :
                             UnicodeSetStringSpan::FWD_UTF8_CONTAINED;
@@ -2333,7 +2331,7 @@
     }
     if(stringSpan!=NULL) {
         return stringSpan->spanBackUTF8((const uint8_t *)s, length, spanCondition);
-    } else if(!strings->isEmpty()) {
+    } else if(hasStrings()) {
         uint32_t which= spanCondition==USET_SPAN_NOT_CONTAINED ?
                             UnicodeSetStringSpan::BACK_UTF8_NOT_CONTAINED :
                             UnicodeSetStringSpan::BACK_UTF8_CONTAINED;
diff --git a/src/third_party/icu/source/common/uniset_closure.cpp b/src/third_party/icu/source/common/uniset_closure.cpp
index e645c12..6ef9da1 100644
--- a/src/third_party/icu/source/common/uniset_closure.cpp
+++ b/src/third_party/icu/source/common/uniset_closure.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  uniset_closure.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -19,7 +21,9 @@
 *   code also builds UnicodeSets from patterns and needs uniset_props.
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/brkiter.h"
 #include "unicode/locid.h"
 #include "unicode/parsepos.h"
@@ -30,10 +34,6 @@
 #include "util.h"
 #include "uvector.h"
 
-// initial storage. Must be >= 0
-// *** same as in uniset.cpp ! ***
-#define START_EXTRA 16
-
 U_NAMESPACE_BEGIN
 
 // TODO memory debugging provided inside uniset.cpp
@@ -48,42 +48,16 @@
 UnicodeSet::UnicodeSet(const UnicodeString& pattern,
                        uint32_t options,
                        const SymbolTable* symbols,
-                       UErrorCode& status) :
-    len(0), capacity(START_EXTRA), list(0), bmpSet(0), buffer(0),
-    bufferCapacity(0), patLen(0), pat(NULL), strings(NULL), stringSpan(NULL),
-    fFlags(0)
-{
-    if(U_SUCCESS(status)){
-        list = (UChar32*) uprv_malloc(sizeof(UChar32) * capacity);
-        /* test for NULL */
-        if(list == NULL) {
-            status = U_MEMORY_ALLOCATION_ERROR;  
-        }else{
-            allocateStrings(status);
-            applyPattern(pattern, options, symbols, status);
-        }
-    }
+                       UErrorCode& status) {
+    applyPattern(pattern, options, symbols, status);
     _dbgct(this);
 }
 
 UnicodeSet::UnicodeSet(const UnicodeString& pattern, ParsePosition& pos,
                        uint32_t options,
                        const SymbolTable* symbols,
-                       UErrorCode& status) :
-    len(0), capacity(START_EXTRA), list(0), bmpSet(0), buffer(0),
-    bufferCapacity(0), patLen(0), pat(NULL), strings(NULL), stringSpan(NULL),
-    fFlags(0)
-{
-    if(U_SUCCESS(status)){
-        list = (UChar32*) uprv_malloc(sizeof(UChar32) * capacity);
-        /* test for NULL */
-        if(list == NULL) {
-            status = U_MEMORY_ALLOCATION_ERROR;   
-        }else{
-            allocateStrings(status);
-            applyPattern(pattern, pos, options, symbols, status);
-        }
-    }
+                       UErrorCode& status) {
+    applyPattern(pattern, pos, options, symbols, status);
     _dbgct(this);
 }
 
@@ -128,7 +102,7 @@
     // _applyPattern calls add() etc., which set pat to empty.
     UnicodeString rebuiltPat;
     RuleCharacterIterator chars(pattern, symbols, pos);
-    applyPattern(chars, symbols, rebuiltPat, options, &UnicodeSet::closeOver, status);
+    applyPattern(chars, symbols, rebuiltPat, options, &UnicodeSet::closeOver, 0, status);
     if (U_FAILURE(status)) return *this;
     if (chars.inVariable()) {
         // syntaxError(chars, "Extra chars in variable value");
@@ -183,7 +157,6 @@
         return *this;
     }
     if (attribute & (USET_CASE_INSENSITIVE | USET_ADD_CASE_MAPPINGS)) {
-        const UCaseProps *csp = ucase_getSingleton();
         {
             UnicodeSet foldSet(*this);
             UnicodeString str;
@@ -199,14 +172,13 @@
             // start with input set to guarantee inclusion
             // USET_CASE: remove strings because the strings will actually be reduced (folded);
             //            therefore, start with no strings and add only those needed
-            if (attribute & USET_CASE_INSENSITIVE) {
+            if ((attribute & USET_CASE_INSENSITIVE) && foldSet.hasStrings()) {
                 foldSet.strings->removeAllElements();
             }
 
             int32_t n = getRangeCount();
             UChar32 result;
             const UChar *full;
-            int32_t locCache = 0;
 
             for (int32_t i=0; i<n; ++i) {
                 UChar32 start = getRangeStart(i);
@@ -215,32 +187,32 @@
                 if (attribute & USET_CASE_INSENSITIVE) {
                     // full case closure
                     for (UChar32 cp=start; cp<=end; ++cp) {
-                        ucase_addCaseClosure(csp, cp, &sa);
+                        ucase_addCaseClosure(cp, &sa);
                     }
                 } else {
                     // add case mappings
                     // (does not add long s for regular s, or Kelvin for k, for example)
                     for (UChar32 cp=start; cp<=end; ++cp) {
-                        result = ucase_toFullLower(csp, cp, NULL, NULL, &full, "", &locCache);
+                        result = ucase_toFullLower(cp, NULL, NULL, &full, UCASE_LOC_ROOT);
                         addCaseMapping(foldSet, result, full, str);
 
-                        result = ucase_toFullTitle(csp, cp, NULL, NULL, &full, "", &locCache);
+                        result = ucase_toFullTitle(cp, NULL, NULL, &full, UCASE_LOC_ROOT);
                         addCaseMapping(foldSet, result, full, str);
 
-                        result = ucase_toFullUpper(csp, cp, NULL, NULL, &full, "", &locCache);
+                        result = ucase_toFullUpper(cp, NULL, NULL, &full, UCASE_LOC_ROOT);
                         addCaseMapping(foldSet, result, full, str);
 
-                        result = ucase_toFullFolding(csp, cp, &full, 0);
+                        result = ucase_toFullFolding(cp, &full, 0);
                         addCaseMapping(foldSet, result, full, str);
                     }
                 }
             }
-            if (strings != NULL && strings->size() > 0) {
+            if (hasStrings()) {
                 if (attribute & USET_CASE_INSENSITIVE) {
                     for (int32_t j=0; j<strings->size(); ++j) {
                         str = *(const UnicodeString *) strings->elementAt(j);
                         str.foldCase();
-                        if(!ucase_addStringCaseClosure(csp, str.getBuffer(), str.length(), &sa)) {
+                        if(!ucase_addStringCaseClosure(str.getBuffer(), str.length(), &sa)) {
                             foldSet.add(str); // does not map to code points: add the folded string itself
                         }
                     }
diff --git a/src/third_party/icu/source/common/uniset_props.cpp b/src/third_party/icu/source/common/uniset_props.cpp
index 18df848..0c7af4b 100644
--- a/src/third_party/icu/source/common/uniset_props.cpp
+++ b/src/third_party/icu/source/common/uniset_props.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  uniset_props.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -16,8 +18,10 @@
 *   Character property dependent functions moved here from uniset.cpp
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/utypes.h"
 #include "unicode/uniset.h"
 #include "unicode/parsepos.h"
@@ -36,8 +40,6 @@
 #include "uprops.h"
 #include "propname.h"
 #include "normalizer2impl.h"
-#include "ucase.h"
-#include "ubidi_props.h"
 #include "uinvchar.h"
 #include "uprops.h"
 #include "charstr.h"
@@ -49,10 +51,6 @@
 
 U_NAMESPACE_USE
 
-// initial storage. Must be >= 0
-// *** same as in uniset.cpp ! ***
-#define START_EXTRA 16
-
 // Define UChar constants using hex for EBCDIC compatibility
 // Used #define to reduce private static exports and memory access time.
 #define SET_OPEN        ((UChar)0x005B) /*[*/
@@ -98,47 +96,13 @@
 U_CDECL_BEGIN
 static UBool U_CALLCONV uset_cleanup();
 
-struct Inclusion {
-    UnicodeSet  *fSet;
-    UInitOnce    fInitOnce;
-};
-static Inclusion gInclusions[UPROPS_SRC_COUNT]; // cached getInclusions()
-
 static UnicodeSet *uni32Singleton;
 static icu::UInitOnce uni32InitOnce = U_INITONCE_INITIALIZER;
 
-//----------------------------------------------------------------
-// Inclusions list
-//----------------------------------------------------------------
-
-// USetAdder implementation
-// Does not use uset.h to reduce code dependencies
-static void U_CALLCONV
-_set_add(USet *set, UChar32 c) {
-    ((UnicodeSet *)set)->add(c);
-}
-
-static void U_CALLCONV
-_set_addRange(USet *set, UChar32 start, UChar32 end) {
-    ((UnicodeSet *)set)->add(start, end);
-}
-
-static void U_CALLCONV
-_set_addString(USet *set, const UChar *str, int32_t length) {
-    ((UnicodeSet *)set)->add(UnicodeString((UBool)(length<0), str, length));
-}
-
 /**
  * Cleanup function for UnicodeSet
  */
 static UBool U_CALLCONV uset_cleanup(void) {
-    for(int32_t i = UPROPS_SRC_NONE; i < UPROPS_SRC_COUNT; ++i) {
-        Inclusion &in = gInclusions[i];
-        delete in.fSet;
-        in.fSet = NULL;
-        in.fInitOnce.reset();
-    }
-
     delete uni32Singleton;
     uni32Singleton = NULL;
     uni32InitOnce.reset();
@@ -149,114 +113,7 @@
 
 U_NAMESPACE_BEGIN
 
-/*
-Reduce excessive reallocation, and make it easier to detect initialization problems.
-Usually you don't see smaller sets than this for Unicode 5.0.
-*/
-#define DEFAULT_INCLUSION_CAPACITY 3072
-
-void U_CALLCONV UnicodeSet_initInclusion(int32_t src, UErrorCode &status) {
-    // This function is invoked only via umtx_initOnce().
-    // This function is a friend of class UnicodeSet.
-
-    U_ASSERT(src >=0 && src<UPROPS_SRC_COUNT);
-    UnicodeSet * &incl = gInclusions[src].fSet;
-    U_ASSERT(incl == NULL);
-
-    incl = new UnicodeSet();
-    if (incl == NULL) {
-        status = U_MEMORY_ALLOCATION_ERROR;
-        return;
-    }
-    USetAdder sa = {
-        (USet *)incl,
-        _set_add,
-        _set_addRange,
-        _set_addString,
-        NULL, // don't need remove()
-        NULL // don't need removeRange()
-    };
-
-    incl->ensureCapacity(DEFAULT_INCLUSION_CAPACITY, status);
-    switch(src) {
-    case UPROPS_SRC_CHAR:
-        uchar_addPropertyStarts(&sa, &status);
-        break;
-    case UPROPS_SRC_PROPSVEC:
-        upropsvec_addPropertyStarts(&sa, &status);
-        break;
-    case UPROPS_SRC_CHAR_AND_PROPSVEC:
-        uchar_addPropertyStarts(&sa, &status);
-        upropsvec_addPropertyStarts(&sa, &status);
-        break;
-#if !UCONFIG_NO_NORMALIZATION
-    case UPROPS_SRC_CASE_AND_NORM: {
-        const Normalizer2Impl *impl=Normalizer2Factory::getNFCImpl(status);
-        if(U_SUCCESS(status)) {
-            impl->addPropertyStarts(&sa, status);
-        }
-        ucase_addPropertyStarts(ucase_getSingleton(), &sa, &status);
-        break;
-    }
-    case UPROPS_SRC_NFC: {
-        const Normalizer2Impl *impl=Normalizer2Factory::getNFCImpl(status);
-        if(U_SUCCESS(status)) {
-            impl->addPropertyStarts(&sa, status);
-        }
-        break;
-    }
-    case UPROPS_SRC_NFKC: {
-        const Normalizer2Impl *impl=Normalizer2Factory::getNFKCImpl(status);
-        if(U_SUCCESS(status)) {
-            impl->addPropertyStarts(&sa, status);
-        }
-        break;
-    }
-    case UPROPS_SRC_NFKC_CF: {
-        const Normalizer2Impl *impl=Normalizer2Factory::getNFKC_CFImpl(status);
-        if(U_SUCCESS(status)) {
-            impl->addPropertyStarts(&sa, status);
-        }
-        break;
-    }
-    case UPROPS_SRC_NFC_CANON_ITER: {
-        const Normalizer2Impl *impl=Normalizer2Factory::getNFCImpl(status);
-        if(U_SUCCESS(status)) {
-            impl->addCanonIterPropertyStarts(&sa, status);
-        }
-        break;
-    }
-#endif
-    case UPROPS_SRC_CASE:
-        ucase_addPropertyStarts(ucase_getSingleton(), &sa, &status);
-        break;
-    case UPROPS_SRC_BIDI:
-        ubidi_addPropertyStarts(ubidi_getSingleton(), &sa, &status);
-        break;
-    default:
-        status = U_INTERNAL_PROGRAM_ERROR;
-        break;
-    }
-
-    if (U_FAILURE(status)) {
-        delete incl;
-        incl = NULL;
-        return;
-    }
-    // Compact for caching
-    incl->compact();
-    ucln_common_registerCleanup(UCLN_COMMON_USET, uset_cleanup);
-}
-
-
-
-const UnicodeSet* UnicodeSet::getInclusions(int32_t src, UErrorCode &status) {
-    U_ASSERT(src >=0 && src<UPROPS_SRC_COUNT);
-    Inclusion &i = gInclusions[src];
-    umtx_initOnce(i.fInitOnce, &UnicodeSet_initInclusion, src, status);
-    return i.fSet;
-}
-
+namespace {
 
 // Cache some sets for other services -------------------------------------- ***
 void U_CALLCONV createUni32Set(UErrorCode &errorCode) {
@@ -315,6 +172,8 @@
 // memory leak checker tools
 #define _dbgct(me)
 
+}  // namespace
+
 //----------------------------------------------------------------
 // Constructors &c
 //----------------------------------------------------------------
@@ -326,21 +185,8 @@
  * @param pattern a string specifying what characters are in the set
  */
 UnicodeSet::UnicodeSet(const UnicodeString& pattern,
-                       UErrorCode& status) :
-    len(0), capacity(START_EXTRA), list(0), bmpSet(0), buffer(0),
-    bufferCapacity(0), patLen(0), pat(NULL), strings(NULL), stringSpan(NULL),
-    fFlags(0)
-{
-    if(U_SUCCESS(status)){
-        list = (UChar32*) uprv_malloc(sizeof(UChar32) * capacity);
-        /* test for NULL */
-        if(list == NULL) {
-            status = U_MEMORY_ALLOCATION_ERROR;  
-        }else{
-            allocateStrings(status);
-            applyPattern(pattern, status);
-        }
-    }
+                       UErrorCode& status) {
+    applyPattern(pattern, status);
     _dbgct(this);
 }
 
@@ -382,7 +228,7 @@
     // _applyPattern calls add() etc., which set pat to empty.
     UnicodeString rebuiltPat;
     RuleCharacterIterator chars(pattern, symbols, pos);
-    applyPattern(chars, symbols, rebuiltPat, USET_IGNORE_SPACE, NULL, status);
+    applyPattern(chars, symbols, rebuiltPat, USET_IGNORE_SPACE, NULL, 0, status);
     if (U_FAILURE(status)) return;
     if (chars.inVariable()) {
         // syntaxError(chars, "Extra chars in variable value");
@@ -406,6 +252,8 @@
 // Implementation: Pattern parsing
 //----------------------------------------------------------------
 
+namespace {
+
 /**
  * A small all-inline class to manage a UnicodeSet pointer.  Add
  * operator->() etc. as needed.
@@ -424,6 +272,10 @@
     }
 };
 
+constexpr int32_t MAX_DEPTH = 100;
+
+}  // namespace
+
 /**
  * Parse the pattern from the given RuleCharacterIterator.  The
  * iterator is advanced over the parsed pattern.
@@ -443,8 +295,13 @@
                               UnicodeString& rebuiltPat,
                               uint32_t options,
                               UnicodeSet& (UnicodeSet::*caseClosure)(int32_t attribute),
+                              int32_t depth,
                               UErrorCode& ec) {
     if (U_FAILURE(ec)) return;
+    if (depth > MAX_DEPTH) {
+        ec = U_ILLEGAL_ARGUMENT_ERROR;
+        return;
+    }
 
     // Syntax characters: [ ] ^ - & { }
 
@@ -579,7 +436,7 @@
             }
             switch (setMode) {
             case 1:
-                nested->applyPattern(chars, symbols, patLocal, options, caseClosure, ec);
+                nested->applyPattern(chars, symbols, patLocal, options, caseClosure, depth + 1, ec);
                 break;
             case 2:
                 chars.skipIgnored(opts);
@@ -837,6 +694,8 @@
 // Property set implementation
 //----------------------------------------------------------------
 
+namespace {
+
 static UBool numericValueFilter(UChar32 ch, void* context) {
     return u_getNumericValue(ch) == *(double*)context;
 }
@@ -868,12 +727,14 @@
     return uscript_hasScript(ch, *(UScriptCode*)context);
 }
 
+}  // namespace
+
 /**
  * Generic filter-based scanning code for UCD property UnicodeSets.
  */
 void UnicodeSet::applyFilter(UnicodeSet::Filter filter,
                              void* context,
-                             int32_t src,
+                             const UnicodeSet* inclusions,
                              UErrorCode &status) {
     if (U_FAILURE(status)) return;
 
@@ -884,12 +745,8 @@
     // To improve performance, use an inclusions set which
     // encodes information about character ranges that are known
     // to have identical properties.
-    // getInclusions(src) contains exactly the first characters of
-    // same-value ranges for the given properties "source".
-    const UnicodeSet* inclusions = getInclusions(src, status);
-    if (U_FAILURE(status)) {
-        return;
-    }
+    // inclusions contains the first characters of
+    // same-value ranges for the given property.
 
     clear();
 
@@ -924,6 +781,8 @@
     }
 }
 
+namespace {
+
 static UBool mungeCharName(char* dst, const char* src, int32_t dstCapacity) {
     /* Note: we use ' ' in compiler code page */
     int32_t j = 0;
@@ -941,24 +800,44 @@
     return TRUE;
 }
 
+}  // namespace
+
 //----------------------------------------------------------------
 // Property set API
 //----------------------------------------------------------------
 
-#define FAIL(ec) {ec=U_ILLEGAL_ARGUMENT_ERROR; return *this;}
+#define FAIL(ec) UPRV_BLOCK_MACRO_BEGIN { \
+    ec=U_ILLEGAL_ARGUMENT_ERROR; \
+    return *this; \
+} UPRV_BLOCK_MACRO_END
 
 UnicodeSet&
 UnicodeSet::applyIntPropertyValue(UProperty prop, int32_t value, UErrorCode& ec) {
-    if (U_FAILURE(ec) || isFrozen()) return *this;
-
+    if (U_FAILURE(ec) || isFrozen()) { return *this; }
     if (prop == UCHAR_GENERAL_CATEGORY_MASK) {
-        applyFilter(generalCategoryMaskFilter, &value, UPROPS_SRC_CHAR, ec);
+        const UnicodeSet* inclusions = CharacterProperties::getInclusionsForProperty(prop, ec);
+        applyFilter(generalCategoryMaskFilter, &value, inclusions, ec);
     } else if (prop == UCHAR_SCRIPT_EXTENSIONS) {
+        const UnicodeSet* inclusions = CharacterProperties::getInclusionsForProperty(prop, ec);
         UScriptCode script = (UScriptCode)value;
-        applyFilter(scriptExtensionsFilter, &script, UPROPS_SRC_PROPSVEC, ec);
-    } else {
+        applyFilter(scriptExtensionsFilter, &script, inclusions, ec);
+    } else if (0 <= prop && prop < UCHAR_BINARY_LIMIT) {
+        if (value == 0 || value == 1) {
+            const USet *set = u_getBinaryPropertySet(prop, &ec);
+            if (U_FAILURE(ec)) { return *this; }
+            copyFrom(*UnicodeSet::fromUSet(set), TRUE);
+            if (value == 0) {
+                complement();
+            }
+        } else {
+            clear();
+        }
+    } else if (UCHAR_INT_START <= prop && prop < UCHAR_INT_LIMIT) {
+        const UnicodeSet* inclusions = CharacterProperties::getInclusionsForProperty(prop, ec);
         IntPropertyContext c = {prop, value};
-        applyFilter(intPropertyFilter, &c, uprops_getSource(prop), ec);
+        applyFilter(intPropertyFilter, &c, inclusions, ec);
+    } else {
+        ec = U_ILLEGAL_ARGUMENT_ERROR;
     }
     return *this;
 }
@@ -987,7 +866,7 @@
 
     UProperty p;
     int32_t v;
-    UBool mustNotBeEmpty = FALSE, invert = FALSE;
+    UBool invert = FALSE;
 
     if (value.length() > 0) {
         p = u_getPropertyEnum(pname.data());
@@ -1008,15 +887,16 @@
                     p == UCHAR_TRAIL_CANONICAL_COMBINING_CLASS ||
                     p == UCHAR_LEAD_CANONICAL_COMBINING_CLASS) {
                     char* end;
-                    double value = uprv_strtod(vname.data(), &end);
-                    v = (int32_t) value;
-                    if (v != value || v < 0 || *end != 0) {
-                        // non-integral or negative value, or trailing junk
+                    double val = uprv_strtod(vname.data(), &end);
+                    // Anything between 0 and 255 is valid even if unused.
+                    // Cast double->int only after range check.
+                    // We catch NaN here because comparing it with both 0 and 255 will be false
+                    // (as are all comparisons with NaN).
+                    if (*end != 0 || !(0 <= val && val <= 255) ||
+                            (v = (int32_t)val) != val) {
+                        // non-integral value or outside 0..255, or trailing junk
                         FAIL(ec);
                     }
-                    // If the resultant set is empty then the numeric value
-                    // was invalid.
-                    mustNotBeEmpty = TRUE;
                 } else {
                     FAIL(ec);
                 }
@@ -1029,11 +909,12 @@
             case UCHAR_NUMERIC_VALUE:
                 {
                     char* end;
-                    double value = uprv_strtod(vname.data(), &end);
+                    double val = uprv_strtod(vname.data(), &end);
                     if (*end != 0) {
                         FAIL(ec);
                     }
-                    applyFilter(numericValueFilter, &value, UPROPS_SRC_CHAR, ec);
+                    applyFilter(numericValueFilter, &val,
+                                CharacterProperties::getInclusionsForProperty(p, ec), ec);
                     return *this;
                 }
             case UCHAR_NAME:
@@ -1062,7 +943,8 @@
                     if (!mungeCharName(buf, vname.data(), sizeof(buf))) FAIL(ec);
                     UVersionInfo version;
                     u_versionFromString(version, buf);
-                    applyFilter(versionFilter, &version, UPROPS_SRC_PROPSVEC, ec);
+                    applyFilter(versionFilter, &version,
+                                CharacterProperties::getInclusionsForProperty(p, ec), ec);
                     return *this;
                 }
             case UCHAR_SCRIPT_EXTENSIONS:
@@ -1115,12 +997,6 @@
         complement();
     }
 
-    if (U_SUCCESS(ec) && (mustNotBeEmpty && isEmpty())) {
-        // mustNotBeEmpty is set to true if an empty set indicates
-        // invalid input.
-        ec = U_ILLEGAL_ARGUMENT_ERROR;
-    }
-
     if (isBogus() && U_SUCCESS(ec)) {
         // We likely ran out of memory. AHHH!
         ec = U_MEMORY_ALLOCATION_ERROR;
diff --git a/src/third_party/icu/source/common/unisetspan.cpp b/src/third_party/icu/source/common/unisetspan.cpp
index a13541a..7e53958 100644
--- a/src/third_party/icu/source/common/unisetspan.cpp
+++ b/src/third_party/icu/source/common/unisetspan.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 ******************************************************************************
 *   file name:  unisetspan.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -14,7 +16,9 @@
 *   created by: Markus W. Scherer
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/utypes.h"
 #include "unicode/uniset.h"
 #include "unicode/ustring.h"
@@ -399,7 +403,7 @@
     if(otherStringSpan.pSpanNotSet==&otherStringSpan.spanSet) {
         pSpanNotSet=&spanSet;
     } else {
-        pSpanNotSet=(UnicodeSet *)otherStringSpan.pSpanNotSet->clone();
+        pSpanNotSet=otherStringSpan.pSpanNotSet->clone();
     }
 
     // Allocate a block of meta data.
@@ -435,7 +439,7 @@
         if(spanSet.contains(c)) {
             return;  // Nothing to do.
         }
-        UnicodeSet *newSet=(UnicodeSet *)spanSet.cloneAsThawed();
+        UnicodeSet *newSet=spanSet.cloneAsThawed();
         if(newSet==NULL) {
             return;  // Out of memory.
         } else {
@@ -501,7 +505,7 @@
 static inline int32_t
 spanOneUTF8(const UnicodeSet &set, const uint8_t *s, int32_t length) {
     UChar32 c=*s;
-    if((int8_t)c>=0) {
+    if(U8_IS_SINGLE(c)) {
         return set.contains(c) ? 1 : -1;
     }
     // Take advantage of non-ASCII fastpaths in U8_NEXT_OR_FFFD().
@@ -513,7 +517,7 @@
 static inline int32_t
 spanOneBackUTF8(const UnicodeSet &set, const uint8_t *s, int32_t length) {
     UChar32 c=s[length-1];
-    if((int8_t)c>=0) {
+    if(U8_IS_SINGLE(c)) {
         return set.contains(c) ? 1 : -1;
     }
     int32_t i=length-1;
@@ -1005,11 +1009,9 @@
                     // Try to match if the increment is not listed already.
                     // Match at code point boundaries. (The UTF-8 strings were converted
                     // from UTF-16 and are guaranteed to be well-formed.)
-                    if( !U8_IS_TRAIL(s[pos-overlap]) &&
-                        !offsets.containsOffset(inc) &&
-                        matches8(s+pos-overlap, s8, length8)
-                        
-                    ) {
+                    if(!U8_IS_TRAIL(s[pos-overlap]) &&
+                            !offsets.containsOffset(inc) &&
+                            matches8(s+pos-overlap, s8, length8)) {
                         if(inc==rest) {
                             return length;  // Reached the end of the string.
                         }
@@ -1051,11 +1053,10 @@
                     // Try to match if the string is longer or starts earlier.
                     // Match at code point boundaries. (The UTF-8 strings were converted
                     // from UTF-16 and are guaranteed to be well-formed.)
-                    if( !U8_IS_TRAIL(s[pos-overlap]) &&
-                        (overlap>maxOverlap || /* redundant overlap==maxOverlap && */ inc>maxInc) &&
-                        matches8(s+pos-overlap, s8, length8)
-                        
-                    ) {
+                    if(!U8_IS_TRAIL(s[pos-overlap]) &&
+                            (overlap>maxOverlap ||
+                                /* redundant overlap==maxOverlap && */ inc>maxInc) &&
+                            matches8(s+pos-overlap, s8, length8)) {
                         maxInc=inc;  // Longest match from earliest start.
                         maxOverlap=overlap;
                         break;
diff --git a/src/third_party/icu/source/common/unisetspan.h b/src/third_party/icu/source/common/unisetspan.h
index 2fe0fc3..9a1307a 100644
--- a/src/third_party/icu/source/common/unisetspan.h
+++ b/src/third_party/icu/source/common/unisetspan.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 ******************************************************************************
 *   file name:  unisetspan.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -63,8 +65,8 @@
 
     /*
      * Do the strings need to be checked in span() etc.?
-     * @return TRUE if strings need to be checked (call span() here),
-     *         FALSE if not (use a BMPSet for best performance).
+     * @return true if strings need to be checked (call span() here),
+     *         false if not (use a BMPSet for best performance).
      */
     inline UBool needsStringSpanUTF16();
     inline UBool needsStringSpanUTF8();
diff --git a/src/third_party/icu/source/common/unistr.cpp b/src/third_party/icu/source/common/unistr.cpp
index 38a1eb1..c8f7e60 100644
--- a/src/third_party/icu/source/common/unistr.cpp
+++ b/src/third_party/icu/source/common/unistr.cpp
@@ -1,6 +1,8 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
-* Copyright (C) 1999-2015, International Business Machines Corporation and
+* Copyright (C) 1999-2016, International Business Machines Corporation and
 * others. All Rights Reserved.
 ******************************************************************************
 *
@@ -18,7 +20,9 @@
 ******************************************************************************
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/utypes.h"
 #include "unicode/appendable.h"
 #include "unicode/putil.h"
@@ -83,7 +87,7 @@
          UChar *dst, int32_t dstStart, int32_t count)
 {
   if(count>0) {
-    uprv_memmove(dst+dstStart, src+srcStart, (size_t)(count*sizeof(*src)));
+    uprv_memmove(dst+dstStart, src+srcStart, (size_t)count*sizeof(*src));
   }
 }
 
@@ -152,41 +156,39 @@
   if(count <= 0 || (uint32_t)c > 0x10ffff) {
     // just allocate and do not do anything else
     allocate(capacity);
-  } else {
-    // count > 0, allocate and fill the new string with count c's
-    int32_t unitCount = U16_LENGTH(c), length = count * unitCount;
+  } else if(c <= 0xffff) {
+    int32_t length = count;
     if(capacity < length) {
       capacity = length;
     }
     if(allocate(capacity)) {
       UChar *array = getArrayStart();
-      int32_t i = 0;
-
-      // fill the new string with c
-      if(unitCount == 1) {
-        // fill with length UChars
-        while(i < length) {
-          array[i++] = (UChar)c;
-        }
-      } else {
-        // get the code units for c
-        UChar units[U16_MAX_LENGTH];
-        U16_APPEND_UNSAFE(units, i, c);
-
-        // now it must be i==unitCount
-        i = 0;
-
-        // for Unicode, unitCount can only be 1, 2, 3, or 4
-        // 1 is handled above
-        while(i < length) {
-          int32_t unitIdx = 0;
-          while(unitIdx < unitCount) {
-            array[i++]=units[unitIdx++];
-          }
-        }
+      UChar unit = (UChar)c;
+      for(int32_t i = 0; i < length; ++i) {
+        array[i] = unit;
       }
+      setLength(length);
     }
-    setLength(length);
+  } else {  // supplementary code point, write surrogate pairs
+    if(count > (INT32_MAX / 2)) {
+      // We would get more than 2G UChars.
+      allocate(capacity);
+      return;
+    }
+    int32_t length = count * 2;
+    if(capacity < length) {
+      capacity = length;
+    }
+    if(allocate(capacity)) {
+      UChar *array = getArrayStart();
+      UChar lead = U16_LEAD(c);
+      UChar trail = U16_TRAIL(c);
+      for(int32_t i = 0; i < length; i += 2) {
+        array[i] = lead;
+        array[i + 1] = trail;
+      }
+      setLength(length);
+    }
   }
 }
 
@@ -219,9 +221,10 @@
 }
 
 UnicodeString::UnicodeString(UBool isTerminated,
-                             const UChar *text,
+                             ConstChar16Ptr textPtr,
                              int32_t textLength) {
   fUnion.fFields.fLengthAndFlags = kReadonlyAlias;
+  const UChar *text = textPtr;
   if(text == NULL) {
     // treat as an empty string, do not alias
     setToEmpty();
@@ -235,7 +238,8 @@
       // text is terminated, or else it would have failed the above test
       textLength = u_strlen(text);
     }
-    setArray((UChar *)text, textLength, isTerminated ? textLength + 1 : textLength);
+    setArray(const_cast<UChar *>(text), textLength,
+             isTerminated ? textLength + 1 : textLength);
   }
 }
 
@@ -307,12 +311,9 @@
   copyFrom(that);
 }
 
-#if U_HAVE_RVALUE_REFERENCES
 UnicodeString::UnicodeString(UnicodeString &&src) U_NOEXCEPT {
-  fUnion.fFields.fLengthAndFlags = kShortString;
-  moveFrom(src);
+  copyFieldsFrom(src, TRUE);
 }
-#endif
 
 UnicodeString::UnicodeString(const UnicodeString& that,
                              int32_t srcStart) {
@@ -334,7 +335,7 @@
 }
 
 // UnicodeString overrides clone() with a real implementation
-Replaceable *
+UnicodeString *
 UnicodeString::clone() const {
   return new UnicodeString(*this);
 }
@@ -343,33 +344,60 @@
 // array allocation
 //========================================
 
+namespace {
+
+const int32_t kGrowSize = 128;
+
+// The number of bytes for one int32_t reference counter and capacity UChars
+// must fit into a 32-bit size_t (at least when on a 32-bit platform).
+// We also add one for the NUL terminator, to avoid reallocation in getTerminatedBuffer(),
+// and round up to a multiple of 16 bytes.
+// This means that capacity must be at most (0xfffffff0 - 4) / 2 - 1 = 0x7ffffff5.
+// (With more complicated checks we could go up to 0x7ffffffd without rounding up,
+// but that does not seem worth it.)
+const int32_t kMaxCapacity = 0x7ffffff5;
+
+int32_t getGrowCapacity(int32_t newLength) {
+  int32_t growSize = (newLength >> 2) + kGrowSize;
+  if(growSize <= (kMaxCapacity - newLength)) {
+    return newLength + growSize;
+  } else {
+    return kMaxCapacity;
+  }
+}
+
+}  // namespace
+
 UBool
 UnicodeString::allocate(int32_t capacity) {
   if(capacity <= US_STACKBUF_SIZE) {
     fUnion.fFields.fLengthAndFlags = kShortString;
-  } else {
-    // count bytes for the refCounter and the string capacity, and
-    // round up to a multiple of 16; then divide by 4 and allocate int32_t's
-    // to be safely aligned for the refCount
-    // the +1 is for the NUL terminator, to avoid reallocation in getTerminatedBuffer()
-    int32_t words = (int32_t)(((sizeof(int32_t) + (capacity + 1) * U_SIZEOF_UCHAR + 15) & ~15) >> 2);
-    int32_t *array = (int32_t*) uprv_malloc( sizeof(int32_t) * words );
-    if(array != 0) {
+    return TRUE;
+  }
+  if(capacity <= kMaxCapacity) {
+    ++capacity;  // for the NUL
+    // Switch to size_t which is unsigned so that we can allocate up to 4GB.
+    // Reference counter + UChars.
+    size_t numBytes = sizeof(int32_t) + (size_t)capacity * U_SIZEOF_UCHAR;
+    // Round up to a multiple of 16.
+    numBytes = (numBytes + 15) & ~15;
+    int32_t *array = (int32_t *) uprv_malloc(numBytes);
+    if(array != NULL) {
       // set initial refCount and point behind the refCount
       *array++ = 1;
+      numBytes -= sizeof(int32_t);
 
       // have fArray point to the first UChar
       fUnion.fFields.fArray = (UChar *)array;
-      fUnion.fFields.fCapacity = (int32_t)((words - 1) * (sizeof(int32_t) / U_SIZEOF_UCHAR));
+      fUnion.fFields.fCapacity = (int32_t)(numBytes / U_SIZEOF_UCHAR);
       fUnion.fFields.fLengthAndFlags = kLongString;
-    } else {
-      fUnion.fFields.fLengthAndFlags = kIsBogus;
-      fUnion.fFields.fArray = 0;
-      fUnion.fFields.fCapacity = 0;
-      return FALSE;
+      return TRUE;
     }
   }
-  return TRUE;
+  fUnion.fFields.fLengthAndFlags = kIsBogus;
+  fUnion.fFields.fArray = 0;
+  fUnion.fFields.fCapacity = 0;
+  return FALSE;
 }
 
 //========================================
@@ -416,7 +444,7 @@
 // Factory methods
 //========================================
 
-UnicodeString UnicodeString::fromUTF8(const StringPiece &utf8) {
+UnicodeString UnicodeString::fromUTF8(StringPiece utf8) {
   UnicodeString result;
   result.setToUTF8(utf8);
   return result;
@@ -522,15 +550,17 @@
     }
     // else if(!fastCopy) fall through to case kWritableAlias
     // -> allocate a new buffer and copy the contents
+    U_FALLTHROUGH;
   case kWritableAlias: {
     // src is a writable alias; we make a copy of that instead
     int32_t srcLength = src.length();
     if(allocate(srcLength)) {
-      uprv_memcpy(getArrayStart(), src.getArrayStart(), srcLength * U_SIZEOF_UCHAR);
+      u_memcpy(getArrayStart(), src.getArrayStart(), srcLength);
       setLength(srcLength);
       break;
     }
     // if there is not enough memory, then fall through to setting to bogus
+    U_FALLTHROUGH;
   }
   default:
     // if src is bogus, set ourselves to bogus
@@ -544,7 +574,7 @@
   return *this;
 }
 
-UnicodeString &UnicodeString::moveFrom(UnicodeString &src) U_NOEXCEPT {
+UnicodeString &UnicodeString::operator=(UnicodeString &&src) U_NOEXCEPT {
   // No explicit check for self move assignment, consistent with standard library.
   // Self move assignment causes no crash nor leak but might make the object bogus.
   releaseArray();
@@ -552,7 +582,7 @@
   return *this;
 }
 
-// Same as moveFrom() except without memory management.
+// Same as move assignment except without memory management.
 void UnicodeString::copyFieldsFrom(UnicodeString &src, UBool setSrcToBogus) U_NOEXCEPT {
   int16_t lengthAndFlags = fUnion.fFields.fLengthAndFlags = src.fUnion.fFields.fLengthAndFlags;
   if(lengthAndFlags & kUsingStackBuffer) {
@@ -845,7 +875,7 @@
 }
 
 int32_t
-UnicodeString::extract(UChar *dest, int32_t destCapacity,
+UnicodeString::extract(Char16Ptr dest, int32_t destCapacity,
                        UErrorCode &errorCode) const {
   int32_t len = length();
   if(U_SUCCESS(errorCode)) {
@@ -854,7 +884,7 @@
     } else {
       const UChar *array = getArrayStart();
       if(len>0 && len<=destCapacity && array!=dest) {
-        uprv_memcpy(dest, array, len*U_SIZEOF_UCHAR);
+        u_memcpy(dest, array, len);
       }
       return u_terminateUChars(dest, destCapacity, len, &errorCode);
     }
@@ -1187,10 +1217,10 @@
   }
 }
 
-const UChar *
+const char16_t *
 UnicodeString::getTerminatedBuffer() {
   if(!isWritable()) {
-    return 0;
+    return nullptr;
   }
   UChar *array = getArrayStart();
   int32_t len = length();
@@ -1216,19 +1246,19 @@
       return array;
     }
   }
-  if(cloneArrayIfNeeded(len+1)) {
+  if(len<INT32_MAX && cloneArrayIfNeeded(len+1)) {
     array = getArrayStart();
     array[len] = 0;
     return array;
   } else {
-    return NULL;
+    return nullptr;
   }
 }
 
 // setTo() analogous to the readonly-aliasing constructor with the same signature
 UnicodeString &
 UnicodeString::setTo(UBool isTerminated,
-                     const UChar *text,
+                     ConstChar16Ptr textPtr,
                      int32_t textLength)
 {
   if(fUnion.fFields.fLengthAndFlags & kOpenGetBuffer) {
@@ -1236,6 +1266,7 @@
     return *this;
   }
 
+  const UChar *text = textPtr;
   if(text == NULL) {
     // treat as an empty string, do not alias
     releaseArray();
@@ -1298,7 +1329,7 @@
   return *this;
 }
 
-UnicodeString &UnicodeString::setToUTF8(const StringPiece &utf8) {
+UnicodeString &UnicodeString::setToUTF8(StringPiece utf8) {
   unBogus();
   int32_t length = utf8.length();
   int32_t capacity;
@@ -1418,34 +1449,56 @@
   }
 
   if(srcChars == 0) {
-    srcStart = srcLength = 0;
-  } else if(srcLength < 0) {
-    // get the srcLength if necessary
-    srcLength = u_strlen(srcChars + srcStart);
+    srcLength = 0;
+  } else {
+    // Perform all remaining operations relative to srcChars + srcStart.
+    // From this point forward, do not use srcStart.
+    srcChars += srcStart;
+    if (srcLength < 0) {
+      // get the srcLength if necessary
+      srcLength = u_strlen(srcChars);
+    }
   }
 
   // pin the indices to legal values
   pinIndices(start, length);
 
-  // calculate the size of the string after the replace
-  int32_t newLength = oldLength - length + srcLength;
+  // Calculate the size of the string after the replace.
+  // Avoid int32_t overflow.
+  int32_t newLength = oldLength - length;
+  if(srcLength > (INT32_MAX - newLength)) {
+    setToBogus();
+    return *this;
+  }
+  newLength += srcLength;
+
+  // Check for insertion into ourself
+  const UChar *oldArray = getArrayStart();
+  if (isBufferWritable() &&
+      oldArray < srcChars + srcLength &&
+      srcChars < oldArray + oldLength) {
+    // Copy into a new UnicodeString and start over
+    UnicodeString copy(srcChars, srcLength);
+    if (copy.isBogus()) {
+      setToBogus();
+      return *this;
+    }
+    return doReplace(start, length, copy.getArrayStart(), 0, srcLength);
+  }
 
   // cloneArrayIfNeeded(doCopyArray=FALSE) may change fArray but will not copy the current contents;
   // therefore we need to keep the current fArray
   UChar oldStackBuffer[US_STACKBUF_SIZE];
-  UChar *oldArray;
   if((fUnion.fFields.fLengthAndFlags&kUsingStackBuffer) && (newLength > US_STACKBUF_SIZE)) {
     // copy the stack buffer contents because it will be overwritten with
     // fUnion.fFields values
-    u_memcpy(oldStackBuffer, fUnion.fStackFields.fBuffer, oldLength);
+    u_memcpy(oldStackBuffer, oldArray, oldLength);
     oldArray = oldStackBuffer;
-  } else {
-    oldArray = getArrayStart();
   }
 
   // clone our array and allocate a bigger array if needed
   int32_t *bufferToDelete = 0;
-  if(!cloneArrayIfNeeded(newLength, newLength + (newLength >> 2) + kGrowSize,
+  if(!cloneArrayIfNeeded(newLength, getGrowCapacity(newLength),
                          FALSE, &bufferToDelete)
   ) {
     return *this;
@@ -1468,7 +1521,7 @@
   }
 
   // now fill in the hole with the new string
-  us_arrayCopy(srcChars, srcStart, newArray, start, srcLength);
+  us_arrayCopy(srcChars, 0, newArray, start, srcLength);
 
   setLength(newLength);
 
@@ -1501,18 +1554,41 @@
     return *this;
   }
 
+  // Perform all remaining operations relative to srcChars + srcStart.
+  // From this point forward, do not use srcStart.
+  srcChars += srcStart;
+
   if(srcLength < 0) {
     // get the srcLength if necessary
-    if((srcLength = u_strlen(srcChars + srcStart)) == 0) {
+    if((srcLength = u_strlen(srcChars)) == 0) {
       return *this;
     }
   }
 
   int32_t oldLength = length();
-  int32_t newLength = oldLength + srcLength;
+  int32_t newLength;
+  if (uprv_add32_overflow(oldLength, srcLength, &newLength)) {
+    setToBogus();
+    return *this;
+  }
+
+  // Check for append onto ourself
+  const UChar* oldArray = getArrayStart();
+  if (isBufferWritable() &&
+      oldArray < srcChars + srcLength &&
+      srcChars < oldArray + oldLength) {
+    // Copy into a new UnicodeString and start over
+    UnicodeString copy(srcChars, srcLength);
+    if (copy.isBogus()) {
+      setToBogus();
+      return *this;
+    }
+    return doAppend(copy.getArrayStart(), 0, srcLength);
+  }
+
   // optimize append() onto a large-enough, owned string
   if((newLength <= getCapacity() && isBufferWritable()) ||
-      cloneArrayIfNeeded(newLength, newLength + (newLength >> 2) + kGrowSize)) {
+      cloneArrayIfNeeded(newLength, getGrowCapacity(newLength))) {
     UChar *newArray = getArrayStart();
     // Do not copy characters when
     //   UChar *buffer=str.getAppendBuffer(...);
@@ -1521,8 +1597,8 @@
     // or
     //   str.appendString(buffer, length)
     // or similar.
-    if(srcChars + srcStart != newArray + oldLength) {
-      us_arrayCopy(srcChars, srcStart, newArray, oldLength, srcLength);
+    if(srcChars != newArray + oldLength) {
+      us_arrayCopy(srcChars, 0, newArray, oldLength, srcLength);
     }
     setLength(newLength);
   }
@@ -1679,14 +1755,14 @@
 // External Buffer
 //========================================
 
-UChar *
+char16_t *
 UnicodeString::getBuffer(int32_t minCapacity) {
   if(minCapacity>=-1 && cloneArrayIfNeeded(minCapacity)) {
     fUnion.fFields.fLengthAndFlags|=kOpenGetBuffer;
     setZeroLength();
     return getArrayStart();
   } else {
-    return 0;
+    return nullptr;
   }
 }
 
@@ -1860,7 +1936,9 @@
     return NULL;
   }
   int32_t oldLength = str.length();
-  if(str.cloneArrayIfNeeded(oldLength + minCapacity, oldLength + desiredCapacityHint)) {
+  if(minCapacity <= (kMaxCapacity - oldLength) &&
+      desiredCapacityHint <= (kMaxCapacity - oldLength) &&
+      str.cloneArrayIfNeeded(oldLength + minCapacity, oldLength + desiredCapacityHint)) {
     *resultCapacity = str.getCapacity() - oldLength;
     return str.getArrayStart() + oldLength;
   }
diff --git a/src/third_party/icu/source/common/unistr_case.cpp b/src/third_party/icu/source/common/unistr_case.cpp
index 1b52eb6..2138d60 100644
--- a/src/third_party/icu/source/common/unistr_case.cpp
+++ b/src/third_party/icu/source/common/unistr_case.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  unistr_case.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:2
 *
@@ -17,14 +19,18 @@
 */
 
 #include "unicode/utypes.h"
+#include "unicode/brkiter.h"
+#include "unicode/casemap.h"
+#include "unicode/edits.h"
 #include "unicode/putil.h"
 #include "cstring.h"
 #include "cmemory.h"
 #include "unicode/ustring.h"
 #include "unicode/unistr.h"
 #include "unicode/uchar.h"
+#include "uassert.h"
+#include "ucasemap_imp.h"
 #include "uelement.h"
-#include "ustr_imp.h"
 
 U_NAMESPACE_BEGIN
 
@@ -85,56 +91,123 @@
 //========================================
 
 UnicodeString &
-UnicodeString::caseMap(const UCaseMap *csm,
+UnicodeString::caseMap(int32_t caseLocale, uint32_t options, UCASEMAP_BREAK_ITERATOR_PARAM
                        UStringCaseMapper *stringCaseMapper) {
   if(isEmpty() || !isWritable()) {
     // nothing to do
     return *this;
   }
 
+  UChar oldBuffer[2 * US_STACKBUF_SIZE];
+  UChar *oldArray;
+  int32_t oldLength = length();
+  int32_t newLength;
+  UBool writable = isBufferWritable();
+  UErrorCode errorCode = U_ZERO_ERROR;
+
+#if !UCONFIG_NO_BREAK_ITERATION
+  // Read-only alias to the original string contents for the titlecasing BreakIterator.
+  // We cannot set the iterator simply to *this because *this is being modified.
+  UnicodeString oldString;
+#endif
+
+  // Try to avoid heap-allocating a new character array for this string.
+  if (writable ? oldLength <= UPRV_LENGTHOF(oldBuffer) : oldLength < US_STACKBUF_SIZE) {
+    // Short string: Copy the contents into a temporary buffer and
+    // case-map back into the current array, or into the stack buffer.
+    UChar *buffer = getArrayStart();
+    int32_t capacity;
+    oldArray = oldBuffer;
+    u_memcpy(oldBuffer, buffer, oldLength);
+    if (writable) {
+      capacity = getCapacity();
+    } else {
+      // Switch from the read-only alias or shared heap buffer to the stack buffer.
+      if (!cloneArrayIfNeeded(US_STACKBUF_SIZE, US_STACKBUF_SIZE, /* doCopyArray= */ FALSE)) {
+        return *this;
+      }
+      U_ASSERT(fUnion.fFields.fLengthAndFlags & kUsingStackBuffer);
+      buffer = fUnion.fStackFields.fBuffer;
+      capacity = US_STACKBUF_SIZE;
+    }
+#if !UCONFIG_NO_BREAK_ITERATION
+    if (iter != nullptr) {
+      oldString.setTo(FALSE, oldArray, oldLength);
+      iter->setText(oldString);
+    }
+#endif
+    newLength = stringCaseMapper(caseLocale, options, UCASEMAP_BREAK_ITERATOR
+                                 buffer, capacity,
+                                 oldArray, oldLength, NULL, errorCode);
+    if (U_SUCCESS(errorCode)) {
+      setLength(newLength);
+      return *this;
+    } else if (errorCode == U_BUFFER_OVERFLOW_ERROR) {
+      // common overflow handling below
+    } else {
+      setToBogus();
+      return *this;
+    }
+  } else {
+    // Longer string or read-only buffer:
+    // Collect only changes and then apply them to this string.
+    // Case mapping often changes only small parts of a string,
+    // and often does not change its length.
+    oldArray = getArrayStart();
+    Edits edits;
+    UChar replacementChars[200];
+#if !UCONFIG_NO_BREAK_ITERATION
+    if (iter != nullptr) {
+      oldString.setTo(FALSE, oldArray, oldLength);
+      iter->setText(oldString);
+    }
+#endif
+    stringCaseMapper(caseLocale, options | U_OMIT_UNCHANGED_TEXT, UCASEMAP_BREAK_ITERATOR
+                     replacementChars, UPRV_LENGTHOF(replacementChars),
+                     oldArray, oldLength, &edits, errorCode);
+    if (U_SUCCESS(errorCode)) {
+      // Grow the buffer at most once, not for multiple doReplace() calls.
+      newLength = oldLength + edits.lengthDelta();
+      if (newLength > oldLength && !cloneArrayIfNeeded(newLength, newLength)) {
+        return *this;
+      }
+      for (Edits::Iterator ei = edits.getCoarseChangesIterator(); ei.next(errorCode);) {
+        doReplace(ei.destinationIndex(), ei.oldLength(),
+                  replacementChars, ei.replacementIndex(), ei.newLength());
+      }
+      if (U_FAILURE(errorCode)) {
+        setToBogus();
+      }
+      return *this;
+    } else if (errorCode == U_BUFFER_OVERFLOW_ERROR) {
+      // common overflow handling below
+      newLength = oldLength + edits.lengthDelta();
+    } else {
+      setToBogus();
+      return *this;
+    }
+  }
+
+  // Handle buffer overflow, newLength is known.
   // We need to allocate a new buffer for the internal string case mapping function.
   // This is very similar to how doReplace() keeps the old array pointer
   // and deletes the old array itself after it is done.
   // In addition, we are forcing cloneArrayIfNeeded() to always allocate a new array.
-  UChar oldStackBuffer[US_STACKBUF_SIZE];
-  UChar *oldArray;
-  int32_t oldLength;
-
-  if(fUnion.fFields.fLengthAndFlags&kUsingStackBuffer) {
-    // copy the stack buffer contents because it will be overwritten
-    oldArray = oldStackBuffer;
-    oldLength = getShortLength();
-    u_memcpy(oldStackBuffer, fUnion.fStackFields.fBuffer, oldLength);
-  } else {
-    oldArray = getArrayStart();
-    oldLength = length();
-  }
-
-  int32_t capacity;
-  if(oldLength <= US_STACKBUF_SIZE) {
-    capacity = US_STACKBUF_SIZE;
-  } else {
-    capacity = oldLength + 20;
-  }
   int32_t *bufferToDelete = 0;
-  if(!cloneArrayIfNeeded(capacity, capacity, FALSE, &bufferToDelete, TRUE)) {
+  if (!cloneArrayIfNeeded(newLength, newLength, FALSE, &bufferToDelete, TRUE)) {
     return *this;
   }
-
-  // Case-map, and if the result is too long, then reallocate and repeat.
-  UErrorCode errorCode;
-  int32_t newLength;
-  do {
-    errorCode = U_ZERO_ERROR;
-    newLength = stringCaseMapper(csm, getArrayStart(), getCapacity(),
-                                 oldArray, oldLength, &errorCode);
-    setLength(newLength);
-  } while(errorCode==U_BUFFER_OVERFLOW_ERROR && cloneArrayIfNeeded(newLength, newLength, FALSE));
-
+  errorCode = U_ZERO_ERROR;
+  // No need to iter->setText() again: The case mapper restarts via iter->first().
+  newLength = stringCaseMapper(caseLocale, options, UCASEMAP_BREAK_ITERATOR
+                               getArrayStart(), getCapacity(),
+                               oldArray, oldLength, NULL, errorCode);
   if (bufferToDelete) {
     uprv_free(bufferToDelete);
   }
-  if(U_FAILURE(errorCode)) {
+  if (U_SUCCESS(errorCode)) {
+    setLength(newLength);
+  } else {
     setToBogus();
   }
   return *this;
@@ -142,10 +215,7 @@
 
 UnicodeString &
 UnicodeString::foldCase(uint32_t options) {
-  UCaseMap csm=UCASEMAP_INITIALIZER;
-  csm.csp=ucase_getSingleton();
-  csm.options=options;
-  return caseMap(&csm, ustrcase_internalFold);
+  return caseMap(UCASE_LOC_ROOT, options, UCASEMAP_BREAK_ITERATOR_NULL ustrcase_internalFold);
 }
 
 U_NAMESPACE_END
diff --git a/src/third_party/icu/source/common/unistr_case_locale.cpp b/src/third_party/icu/source/common/unistr_case_locale.cpp
index b5d729f..049ef2d 100644
--- a/src/third_party/icu/source/common/unistr_case_locale.cpp
+++ b/src/third_party/icu/source/common/unistr_case_locale.cpp
@@ -1,10 +1,12 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *   Copyright (C) 2011, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *******************************************************************************
 *   file name:  unistr_case_locale.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -15,12 +17,14 @@
 *   were moved here to break dependency cycles among parts of the common library.
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/utypes.h"
 #include "unicode/locid.h"
+#include "unicode/ucasemap.h"
 #include "unicode/unistr.h"
-#include "cmemory.h"
-#include "ustr_imp.h"
+#include "ucasemap_imp.h"
 
 U_NAMESPACE_BEGIN
 
@@ -28,44 +32,28 @@
 // Write implementation
 //========================================
 
-/*
- * Set parameters on an empty UCaseMap, for UCaseMap-less API functions.
- * Do this fast because it is called with every function call.
- */
-static inline void
-setTempCaseMap(UCaseMap *csm, const char *locale) {
-    if(csm->csp==NULL) {
-        csm->csp=ucase_getSingleton();
-    }
-    if(locale!=NULL && locale[0]==0) {
-        csm->locale[0]=0;
-    } else {
-        ustrcase_setTempCaseMapLocale(csm, locale);
-    }
-}
-
 UnicodeString &
 UnicodeString::toLower() {
-  return toLower(Locale::getDefault());
+  return caseMap(ustrcase_getCaseLocale(NULL), 0,
+                 UCASEMAP_BREAK_ITERATOR_NULL ustrcase_internalToLower);
 }
 
 UnicodeString &
 UnicodeString::toLower(const Locale &locale) {
-  UCaseMap csm=UCASEMAP_INITIALIZER;
-  setTempCaseMap(&csm, locale.getName());
-  return caseMap(&csm, ustrcase_internalToLower);
+  return caseMap(ustrcase_getCaseLocale(locale.getBaseName()), 0,
+                 UCASEMAP_BREAK_ITERATOR_NULL ustrcase_internalToLower);
 }
 
 UnicodeString &
 UnicodeString::toUpper() {
-  return toUpper(Locale::getDefault());
+  return caseMap(ustrcase_getCaseLocale(NULL), 0,
+                 UCASEMAP_BREAK_ITERATOR_NULL ustrcase_internalToUpper);
 }
 
 UnicodeString &
 UnicodeString::toUpper(const Locale &locale) {
-  UCaseMap csm=UCASEMAP_INITIALIZER;
-  setTempCaseMap(&csm, locale.getName());
-  return caseMap(&csm, ustrcase_internalToUpper);
+  return caseMap(ustrcase_getCaseLocale(locale.getBaseName()), 0,
+                 UCASEMAP_BREAK_ITERATOR_NULL ustrcase_internalToUpper);
 }
 
 U_NAMESPACE_END
diff --git a/src/third_party/icu/source/common/unistr_cnv.cpp b/src/third_party/icu/source/common/unistr_cnv.cpp
index 38998ff..64d3c16 100644
--- a/src/third_party/icu/source/common/unistr_cnv.cpp
+++ b/src/third_party/icu/source/common/unistr_cnv.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  unistr_cnv.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:2
 *
diff --git a/src/third_party/icu/source/common/unistr_props.cpp b/src/third_party/icu/source/common/unistr_props.cpp
index b49a4b4..4006475 100644
--- a/src/third_party/icu/source/common/unistr_props.cpp
+++ b/src/third_party/icu/source/common/unistr_props.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  unistr_props.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:2
 *
diff --git a/src/third_party/icu/source/common/unistr_titlecase_brkiter.cpp b/src/third_party/icu/source/common/unistr_titlecase_brkiter.cpp
index 1d3aff9..cefc98f 100644
--- a/src/third_party/icu/source/common/unistr_titlecase_brkiter.cpp
+++ b/src/third_party/icu/source/common/unistr_titlecase_brkiter.cpp
@@ -1,10 +1,12 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *   Copyright (C) 2011, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *******************************************************************************
 *   file name:  unistr_titlecase_brkiter.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:2
 *
@@ -18,72 +20,39 @@
 #include "unicode/utypes.h"
 
 #if !UCONFIG_NO_BREAK_ITERATION
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 
 #include "unicode/brkiter.h"
-#include "unicode/ubrk.h"
+#include "unicode/locid.h"
+#include "unicode/ucasemap.h"
 #include "unicode/unistr.h"
-#include "unicode/ustring.h"
-#include "cmemory.h"
-#include "ustr_imp.h"
-
-static int32_t U_CALLCONV
-unistr_case_internalToTitle(const UCaseMap *csm,
-                            UChar *dest, int32_t destCapacity,
-                            const UChar *src, int32_t srcLength,
-                            UErrorCode *pErrorCode) {
-  ubrk_setText(csm->iter, src, srcLength, pErrorCode);
-  return ustrcase_internalToTitle(csm, dest, destCapacity, src, srcLength, pErrorCode);
-}
-
-/*
- * Set parameters on an empty UCaseMap, for UCaseMap-less API functions.
- * Do this fast because it is called with every function call.
- */
-static inline void
-setTempCaseMap(UCaseMap *csm, const char *locale) {
-    if(csm->csp==NULL) {
-        csm->csp=ucase_getSingleton();
-    }
-    if(locale!=NULL && locale[0]==0) {
-        csm->locale[0]=0;
-    } else {
-        ustrcase_setTempCaseMapLocale(csm, locale);
-    }
-}
+#include "ucasemap_imp.h"
 
 U_NAMESPACE_BEGIN
 
 UnicodeString &
-UnicodeString::toTitle(BreakIterator *titleIter) {
-  return toTitle(titleIter, Locale::getDefault(), 0);
+UnicodeString::toTitle(BreakIterator *iter) {
+    return toTitle(iter, Locale::getDefault(), 0);
 }
 
 UnicodeString &
-UnicodeString::toTitle(BreakIterator *titleIter, const Locale &locale) {
-  return toTitle(titleIter, locale, 0);
+UnicodeString::toTitle(BreakIterator *iter, const Locale &locale) {
+    return toTitle(iter, locale, 0);
 }
 
 UnicodeString &
-UnicodeString::toTitle(BreakIterator *titleIter, const Locale &locale, uint32_t options) {
-  UCaseMap csm=UCASEMAP_INITIALIZER;
-  csm.options=options;
-  setTempCaseMap(&csm, locale.getName());
-  BreakIterator *bi=titleIter;
-  if(bi==NULL) {
-    UErrorCode errorCode=U_ZERO_ERROR;
-    bi=BreakIterator::createWordInstance(locale, errorCode);
-    if(U_FAILURE(errorCode)) {
-      setToBogus();
-      return *this;
+UnicodeString::toTitle(BreakIterator *iter, const Locale &locale, uint32_t options) {
+    LocalPointer<BreakIterator> ownedIter;
+    UErrorCode errorCode = U_ZERO_ERROR;
+    iter = ustrcase_getTitleBreakIterator(&locale, "", options, iter, ownedIter, errorCode);
+    if (iter == nullptr) {
+        setToBogus();
+        return *this;
     }
-  }
-  csm.iter=reinterpret_cast<UBreakIterator *>(bi);
-  caseMap(&csm, unistr_case_internalToTitle);
-  if(titleIter==NULL) {
-    delete bi;
-  }
-  return *this;
+    caseMap(ustrcase_getCaseLocale(locale.getBaseName()), options, iter, ustrcase_internalToTitle);
+    return *this;
 }
 
 U_NAMESPACE_END
diff --git a/src/third_party/icu/source/common/unistrappender.h b/src/third_party/icu/source/common/unistrappender.h
index 4a459c8..75fcb9e 100644
--- a/src/third_party/icu/source/common/unistrappender.h
+++ b/src/third_party/icu/source/common/unistrappender.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 * Copyright (C) 2015, International Business Machines Corporation and
diff --git a/src/third_party/icu/source/common/unorm.cpp b/src/third_party/icu/source/common/unorm.cpp
index f0a026f..2d9f460 100644
--- a/src/third_party/icu/source/common/unorm.cpp
+++ b/src/third_party/icu/source/common/unorm.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 * Copyright (c) 1996-2014, International Business Machines
diff --git a/src/third_party/icu/source/common/unormcmp.cpp b/src/third_party/icu/source/common/unormcmp.cpp
index ec3eeb2..fae2251 100644
--- a/src/third_party/icu/source/common/unormcmp.cpp
+++ b/src/third_party/icu/source/common/unormcmp.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  unormcmp.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -22,7 +24,9 @@
 
 #if !UCONFIG_NO_NORMALIZATION
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/unorm.h"
 #include "unicode/ustring.h"
 #include "cmemory.h"
@@ -144,7 +148,6 @@
                    uint32_t options,
                    UErrorCode *pErrorCode) {
     const Normalizer2Impl *nfcImpl;
-    const UCaseProps *csp;
 
     /* current-level start/limit - s1/s2 as current */
     const UChar *start1, *start2, *limit1, *limit2;
@@ -182,11 +185,6 @@
     } else {
         nfcImpl=NULL;
     }
-    if((options&U_COMPARE_IGNORE_CASE)!=0) {
-        csp=ucase_getSingleton();
-    } else {
-        csp=NULL;
-    }
     if(U_FAILURE(*pErrorCode)) {
         return 0;
     }
@@ -318,7 +316,7 @@
          */
 
         if( level1==0 && (options&U_COMPARE_IGNORE_CASE) &&
-            (length=ucase_toFullFolding(csp, (UChar32)cp1, &p, options))>=0
+            (length=ucase_toFullFolding((UChar32)cp1, &p, options))>=0
         ) {
             /* cp1 case-folds to the code point "length" or to p[length] */
             if(U_IS_SURROGATE(c1)) {
@@ -363,7 +361,7 @@
         }
 
         if( level2==0 && (options&U_COMPARE_IGNORE_CASE) &&
-            (length=ucase_toFullFolding(csp, (UChar32)cp2, &p, options))>=0
+            (length=ucase_toFullFolding((UChar32)cp2, &p, options))>=0
         ) {
             /* cp2 case-folds to the code point "length" or to p[length] */
             if(U_IS_SURROGATE(c2)) {
diff --git a/src/third_party/icu/source/common/unormimp.h b/src/third_party/icu/source/common/unormimp.h
index d2cfc9f..d2604ad 100644
--- a/src/third_party/icu/source/common/unormimp.h
+++ b/src/third_party/icu/source/common/unormimp.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  unormimp.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -416,7 +418,7 @@
  * The same bit is used for NFC and NFKC; (c) differs for them.
  * As usual, we build the "not skippable" flags so that unassigned
  * code points get a 0 bit.
- * This bit is only valid after (a)..(e) test FALSE; test NFD_NO before (f) as well.
+ * This bit is only valid after (a)..(e) test false; test NFD_NO before (f) as well.
  * Test Hangul LV syllables entirely in code.
  *
  *
diff --git a/src/third_party/icu/source/common/uobject.cpp b/src/third_party/icu/source/common/uobject.cpp
index cd96c02..00340bc 100644
--- a/src/third_party/icu/source/common/uobject.cpp
+++ b/src/third_party/icu/source/common/uobject.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 ******************************************************************************
 *   file name:  uobject.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -14,7 +16,9 @@
 *   created by: Markus W. Scherer
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/uobject.h"
 #include "cmemory.h"
 
@@ -57,32 +61,32 @@
  * and replace with uprv_malloc/uprv_free.
  */
 
-void * U_EXPORT2 UMemory::operator new(size_t size) U_NO_THROW {
+void * U_EXPORT2 UMemory::operator new(size_t size) U_NOEXCEPT {
     return uprv_malloc(size);
 }
 
-void U_EXPORT2 UMemory::operator delete(void *p) U_NO_THROW {
+void U_EXPORT2 UMemory::operator delete(void *p) U_NOEXCEPT {
     if(p!=NULL) {
         uprv_free(p);
     }
 }
 
-void * U_EXPORT2 UMemory::operator new[](size_t size) U_NO_THROW {
+void * U_EXPORT2 UMemory::operator new[](size_t size) U_NOEXCEPT {
     return uprv_malloc(size);
 }
 
-void U_EXPORT2 UMemory::operator delete[](void *p) U_NO_THROW {
+void U_EXPORT2 UMemory::operator delete[](void *p) U_NOEXCEPT {
     if(p!=NULL) {
         uprv_free(p);
     }
 }
 
 #if U_HAVE_DEBUG_LOCATION_NEW
-void * U_EXPORT2 UMemory::operator new(size_t size, const char* /*file*/, int /*line*/) U_NO_THROW {
+void * U_EXPORT2 UMemory::operator new(size_t size, const char* /*file*/, int /*line*/) U_NOEXCEPT {
     return UMemory::operator new(size);
 }
 
-void U_EXPORT2 UMemory::operator delete(void* p, const char* /*file*/, int /*line*/) U_NO_THROW {
+void U_EXPORT2 UMemory::operator delete(void* p, const char* /*file*/, int /*line*/) U_NOEXCEPT {
     UMemory::operator delete(p);
 }
 #endif /* U_HAVE_DEBUG_LOCATION_NEW */
diff --git a/src/third_party/icu/source/common/uposixdefs.h b/src/third_party/icu/source/common/uposixdefs.h
index ca84fef..23c3f6d 100644
--- a/src/third_party/icu/source/common/uposixdefs.h
+++ b/src/third_party/icu/source/common/uposixdefs.h
@@ -1,10 +1,12 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *   Copyright (C) 2011-2015, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *******************************************************************************
 *   file name:  uposixdefs.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -52,22 +54,24 @@
  *
  * z/OS needs this definition for timeval and to get usleep.
  */
-#if !defined(_XOPEN_SOURCE_EXTENDED)
+#if !defined(_XOPEN_SOURCE_EXTENDED) && defined(__TOS_MVS__)
 #   define _XOPEN_SOURCE_EXTENDED 1
 #endif
 
-/*
- * There is an issue with turning on _XOPEN_SOURCE_EXTENDED on certain platforms.
- * A compatibility issue exists between turning on _XOPEN_SOURCE_EXTENDED and using
- * standard C++ string class. As a result, standard C++ string class needs to be
- * turned off for the follwing platforms:
- *  -AIX/VACPP
- *  -Solaris/GCC
+/**
+ * Solaris says:
+ *   "...it is invalid to compile an XPG6 or a POSIX.1-2001 application with anything other
+ *   than a c99 or later compiler."
+ * Apparently C++11 is not "or later". Work around this.
  */
-#if (U_PLATFORM == U_PF_AIX && !defined(__GNUC__)) || (U_PLATFORM == U_PF_SOLARIS && defined(__GNUC__))
-#   if _XOPEN_SOURCE_EXTENDED && !defined(U_HAVE_STD_STRING)
-#   define U_HAVE_STD_STRING 0
-#   endif
+#if defined(__cplusplus) && (defined(sun) || defined(__sun)) && !defined (_STDC_C99)
+#   define _STDC_C99
+#endif
+
+#if !defined _POSIX_C_SOURCE && \
+    defined(__APPLE__) && defined(__MACH__) && !defined(__clang__)
+// Needed to prevent EOWNERDEAD issues with GCC on Mac
+#define _POSIX_C_SOURCE 200809L
 #endif
 
 #endif  /* __UPOSIXDEFS_H__ */
diff --git a/src/third_party/icu/source/common/uprops.cpp b/src/third_party/icu/source/common/uprops.cpp
index 3bf4431..1604ad9 100644
--- a/src/third_party/icu/source/common/uprops.cpp
+++ b/src/third_party/icu/source/common/uprops.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  uprops.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -23,20 +25,131 @@
 
 #include "unicode/utypes.h"
 #include "unicode/uchar.h"
+#include "unicode/ucptrie.h"
+#include "unicode/udata.h"
 #include "unicode/unorm2.h"
 #include "unicode/uscript.h"
 #include "unicode/ustring.h"
 #include "cstring.h"
+#include "mutex.h"
 #include "normalizer2impl.h"
 #include "umutex.h"
 #include "ubidi_props.h"
 #include "uprops.h"
 #include "ucase.h"
+#include "ucln_cmn.h"
+#include "ulayout_props.h"
 #include "ustr_imp.h"
 
 U_NAMESPACE_USE
 
-#define GET_BIDI_PROPS() ubidi_getSingleton()
+// Unicode text layout properties data -----------------------------------------
+
+namespace {
+
+icu::UInitOnce gLayoutInitOnce = U_INITONCE_INITIALIZER;
+UDataMemory *gLayoutMemory = nullptr;
+
+UCPTrie *gInpcTrie = nullptr;  // Indic_Positional_Category
+UCPTrie *gInscTrie = nullptr;  // Indic_Syllabic_Category
+UCPTrie *gVoTrie = nullptr;  // Vertical_Orientation
+
+int32_t gMaxInpcValue = 0;
+int32_t gMaxInscValue = 0;
+int32_t gMaxVoValue = 0;
+
+UBool U_CALLCONV uprops_cleanup() {
+    udata_close(gLayoutMemory);
+    gLayoutMemory = nullptr;
+
+    ucptrie_close(gInpcTrie);
+    gInpcTrie = nullptr;
+    ucptrie_close(gInscTrie);
+    gInscTrie = nullptr;
+    ucptrie_close(gVoTrie);
+    gVoTrie = nullptr;
+
+    gMaxInpcValue = 0;
+    gMaxInscValue = 0;
+    gMaxVoValue = 0;
+
+    gLayoutInitOnce.reset();
+    return TRUE;
+}
+
+UBool U_CALLCONV
+ulayout_isAcceptable(void * /*context*/,
+                     const char * /* type */, const char * /*name*/,
+                     const UDataInfo *pInfo) {
+    return pInfo->size >= 20 &&
+        pInfo->isBigEndian == U_IS_BIG_ENDIAN &&
+        pInfo->charsetFamily == U_CHARSET_FAMILY &&
+        pInfo->dataFormat[0] == ULAYOUT_FMT_0 &&
+        pInfo->dataFormat[1] == ULAYOUT_FMT_1 &&
+        pInfo->dataFormat[2] == ULAYOUT_FMT_2 &&
+        pInfo->dataFormat[3] == ULAYOUT_FMT_3 &&
+        pInfo->formatVersion[0] == 1;
+}
+
+// UInitOnce singleton initialization function
+void U_CALLCONV ulayout_load(UErrorCode &errorCode) {
+    gLayoutMemory = udata_openChoice(
+        nullptr, ULAYOUT_DATA_TYPE, ULAYOUT_DATA_NAME,
+        ulayout_isAcceptable, nullptr, &errorCode);
+    if (U_FAILURE(errorCode)) { return; }
+
+    const uint8_t *inBytes = (const uint8_t *)udata_getMemory(gLayoutMemory);
+    const int32_t *inIndexes = (const int32_t *)inBytes;
+    int32_t indexesLength = inIndexes[ULAYOUT_IX_INDEXES_LENGTH];
+    if (indexesLength < 12) {
+        errorCode = U_INVALID_FORMAT_ERROR;  // Not enough indexes.
+        return;
+    }
+    int32_t offset = indexesLength * 4;
+    int32_t top = inIndexes[ULAYOUT_IX_INPC_TRIE_TOP];
+    int32_t trieSize = top - offset;
+    if (trieSize >= 16) {
+        gInpcTrie = ucptrie_openFromBinary(
+            UCPTRIE_TYPE_ANY, UCPTRIE_VALUE_BITS_ANY,
+            inBytes + offset, trieSize, nullptr, &errorCode);
+    }
+    offset = top;
+    top = inIndexes[ULAYOUT_IX_INSC_TRIE_TOP];
+    trieSize = top - offset;
+    if (trieSize >= 16) {
+        gInscTrie = ucptrie_openFromBinary(
+            UCPTRIE_TYPE_ANY, UCPTRIE_VALUE_BITS_ANY,
+            inBytes + offset, trieSize, nullptr, &errorCode);
+    }
+    offset = top;
+    top = inIndexes[ULAYOUT_IX_VO_TRIE_TOP];
+    trieSize = top - offset;
+    if (trieSize >= 16) {
+        gVoTrie = ucptrie_openFromBinary(
+            UCPTRIE_TYPE_ANY, UCPTRIE_VALUE_BITS_ANY,
+            inBytes + offset, trieSize, nullptr, &errorCode);
+    }
+
+    uint32_t maxValues = inIndexes[ULAYOUT_IX_MAX_VALUES];
+    gMaxInpcValue = maxValues >> ULAYOUT_MAX_INPC_SHIFT;
+    gMaxInscValue = (maxValues >> ULAYOUT_MAX_INSC_SHIFT) & 0xff;
+    gMaxVoValue = (maxValues >> ULAYOUT_MAX_VO_SHIFT) & 0xff;
+
+    ucln_common_registerCleanup(UCLN_COMMON_UPROPS, uprops_cleanup);
+}
+
+UBool ulayout_ensureData(UErrorCode &errorCode) {
+    if (U_FAILURE(errorCode)) { return FALSE; }
+    umtx_initOnce(gLayoutInitOnce, &ulayout_load, errorCode);
+    return U_SUCCESS(errorCode);
+}
+
+UBool ulayout_ensureData() {
+    UErrorCode errorCode = U_ZERO_ERROR;
+    return ulayout_ensureData(errorCode);
+}
+
+}  // namespace
 
 /* general properties API functions ----------------------------------------- */
 
@@ -56,19 +169,19 @@
 }
 
 static UBool caseBinaryPropertyContains(const BinaryProperty &/*prop*/, UChar32 c, UProperty which) {
-    return ucase_hasBinaryProperty(c, which);
+    return static_cast<UBool>(ucase_hasBinaryProperty(c, which));
 }
 
 static UBool isBidiControl(const BinaryProperty &/*prop*/, UChar32 c, UProperty /*which*/) {
-    return ubidi_isBidiControl(GET_BIDI_PROPS(), c);
+    return ubidi_isBidiControl(c);
 }
 
 static UBool isMirrored(const BinaryProperty &/*prop*/, UChar32 c, UProperty /*which*/) {
-    return ubidi_isMirrored(GET_BIDI_PROPS(), c);
+    return ubidi_isMirrored(c);
 }
 
 static UBool isJoinControl(const BinaryProperty &/*prop*/, UChar32 c, UProperty /*which*/) {
-    return ubidi_isJoinControl(GET_BIDI_PROPS(), c);
+    return ubidi_isJoinControl(c);
 }
 
 #if UCONFIG_NO_NORMALIZATION
@@ -126,9 +239,8 @@
     }
     if(c>=0) {
         /* single code point */
-        const UCaseProps *csp=ucase_getSingleton();
         const UChar *resultString;
-        return (UBool)(ucase_toFullFolding(csp, c, &resultString, U_FOLD_CASE_DEFAULT)>=0);
+        return (UBool)(ucase_toFullFolding(c, &resultString, U_FOLD_CASE_DEFAULT)>=0);
     } else {
         /* guess some large but stack-friendly capacity */
         UChar dest[2*UCASE_MAX_STRING_LENGTH];
@@ -205,6 +317,11 @@
     return u_isxdigit(c);
 }
 
+static UBool isRegionalIndicator(const BinaryProperty &/*prop*/, UChar32 c, UProperty /*which*/) {
+    // Property starts are a subset of lb=RI etc.
+    return 0x1F1E6<=c && c<=0x1F1FF;
+}
+
 static const BinaryProperty binProps[UCHAR_BINARY_LIMIT]={
     /*
      * column and mask values for binary properties from u_getUnicodeProperties().
@@ -275,6 +392,10 @@
     { 2,                U_MASK(UPROPS_2_EMOJI_PRESENTATION), defaultContains },
     { 2,                U_MASK(UPROPS_2_EMOJI_MODIFIER), defaultContains },
     { 2,                U_MASK(UPROPS_2_EMOJI_MODIFIER_BASE), defaultContains },
+    { 2,                U_MASK(UPROPS_2_EMOJI_COMPONENT), defaultContains },
+    { 2,                0, isRegionalIndicator },
+    { 1,                U_MASK(UPROPS_PREPENDED_CONCATENATION_MARK), defaultContains },
+    { 2,                U_MASK(UPROPS_2_EXTENDED_PICTOGRAPHIC), defaultContains },
 };
 
 U_CAPI UBool U_EXPORT2
@@ -320,11 +441,11 @@
 }
 
 static int32_t getBiDiPairedBracketType(const IntProperty &/*prop*/, UChar32 c, UProperty /*which*/) {
-    return (int32_t)ubidi_getPairedBracketType(GET_BIDI_PROPS(), c);
+    return (int32_t)ubidi_getPairedBracketType(c);
 }
 
 static int32_t biDiGetMaxValue(const IntProperty &/*prop*/, UProperty which) {
-    return ubidi_getMaxValue(GET_BIDI_PROPS(), which);
+    return ubidi_getMaxValue(which);
 }
 
 #if UCONFIG_NO_NORMALIZATION
@@ -342,11 +463,11 @@
 }
 
 static int32_t getJoiningGroup(const IntProperty &/*prop*/, UChar32 c, UProperty /*which*/) {
-    return ubidi_getJoiningGroup(GET_BIDI_PROPS(), c);
+    return ubidi_getJoiningGroup(c);
 }
 
 static int32_t getJoiningType(const IntProperty &/*prop*/, UChar32 c, UProperty /*which*/) {
-    return ubidi_getJoiningType(GET_BIDI_PROPS(), c);
+    return ubidi_getJoiningType(c);
 }
 
 static int32_t getNumericType(const IntProperty &/*prop*/, UChar32 c, UProperty /*which*/) {
@@ -359,6 +480,11 @@
     return (int32_t)uscript_getScript(c, &errorCode);
 }
 
+static int32_t scriptGetMaxValue(const IntProperty &/*prop*/, UProperty /*which*/) {
+    uint32_t scriptX=uprv_getMaxValues(0)&UPROPS_SCRIPT_X_MASK;
+    return uprops_mergeScriptCodeOrIndex(scriptX);
+}
+
 /*
  * Map some of the Grapheme Cluster Break values to Hangul Syllable Types.
  * Hangul_Syllable_Type is fully redundant with a subset of Grapheme_Cluster_Break.
@@ -420,6 +546,32 @@
 }
 #endif
 
+static int32_t getInPC(const IntProperty &, UChar32 c, UProperty) {
+    return ulayout_ensureData() && gInpcTrie != nullptr ? ucptrie_get(gInpcTrie, c) : 0;
+}
+
+static int32_t getInSC(const IntProperty &, UChar32 c, UProperty) {
+    return ulayout_ensureData() && gInscTrie != nullptr ? ucptrie_get(gInscTrie, c) : 0;
+}
+
+static int32_t getVo(const IntProperty &, UChar32 c, UProperty) {
+    return ulayout_ensureData() && gVoTrie != nullptr ? ucptrie_get(gVoTrie, c) : 0;
+}
+
+static int32_t layoutGetMaxValue(const IntProperty &/*prop*/, UProperty which) {
+    if (!ulayout_ensureData()) { return 0; }
+    switch (which) {
+    case UCHAR_INDIC_POSITIONAL_CATEGORY:
+        return gMaxInpcValue;
+    case UCHAR_INDIC_SYLLABIC_CATEGORY:
+        return gMaxInscValue;
+    case UCHAR_VERTICAL_ORIENTATION:
+        return gMaxVoValue;
+    default:
+        return 0;
+    }
+}
+
 static const IntProperty intProps[UCHAR_INT_LIMIT-UCHAR_INT_START]={
     /*
      * column, mask and shift values for int-value properties from u_getUnicodeProperties().
@@ -439,7 +591,7 @@
     { UPROPS_SRC_BIDI,  0, 0,                               getJoiningType, biDiGetMaxValue },
     { 2,                UPROPS_LB_MASK, UPROPS_LB_SHIFT,    defaultGetValue, defaultGetMaxValue },
     { UPROPS_SRC_CHAR,  0, (int32_t)U_NT_COUNT-1,           getNumericType, getMaxValueFromShift },
-    { 0,                UPROPS_SCRIPT_MASK, 0,              getScript, defaultGetMaxValue },
+    { UPROPS_SRC_PROPSVEC, 0, 0,                            getScript, scriptGetMaxValue },
     { UPROPS_SRC_PROPSVEC, 0, (int32_t)U_HST_COUNT-1,       getHangulSyllableType, getMaxValueFromShift },
     // UCHAR_NFD_QUICK_CHECK: max=1=YES -- never "maybe", only "no" or "yes"
     { UPROPS_SRC_NFC,   0, (int32_t)UNORM_YES,              getNormQuickCheck, getMaxValueFromShift },
@@ -455,6 +607,9 @@
     { 2,                UPROPS_SB_MASK, UPROPS_SB_SHIFT,    defaultGetValue, defaultGetMaxValue },
     { 2,                UPROPS_WB_MASK, UPROPS_WB_SHIFT,    defaultGetValue, defaultGetMaxValue },
     { UPROPS_SRC_BIDI,  0, 0,                               getBiDiPairedBracketType, biDiGetMaxValue },
+    { UPROPS_SRC_INPC,  0, 0,                               getInPC, layoutGetMaxValue },
+    { UPROPS_SRC_INSC,  0, 0,                               getInSC, layoutGetMaxValue },
+    { UPROPS_SRC_VO,    0, 0,                               getVo, layoutGetMaxValue },
 };
 
 U_CAPI int32_t U_EXPORT2
@@ -556,6 +711,39 @@
     }
 }
 
+U_CFUNC void U_EXPORT2
+uprops_addPropertyStarts(UPropertySource src, const USetAdder *sa, UErrorCode *pErrorCode) {
+    if (!ulayout_ensureData(*pErrorCode)) { return; }
+    const UCPTrie *trie;
+    switch (src) {
+    case UPROPS_SRC_INPC:
+        trie = gInpcTrie;
+        break;
+    case UPROPS_SRC_INSC:
+        trie = gInscTrie;
+        break;
+    case UPROPS_SRC_VO:
+        trie = gVoTrie;
+        break;
+    default:
+        *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR;
+        return;
+    }
+
+    if (trie == nullptr) {
+        *pErrorCode = U_MISSING_RESOURCE_ERROR;
+        return;
+    }
+
+    // Add the start code point of each same-value range of the trie.
+    UChar32 start = 0, end;
+    while ((end = ucptrie_getRange(trie, start, UCPMAP_RANGE_NORMAL, 0,
+                                   nullptr, nullptr, nullptr)) >= 0) {
+        sa->add(sa->set, start);
+        start = end + 1;
+    }
+}
+
 #if !UCONFIG_NO_NORMALIZATION
 
 U_CAPI int32_t U_EXPORT2
@@ -574,14 +762,13 @@
     // case folding and NFKC.)
     // For the derivation, see Unicode's DerivedNormalizationProps.txt.
     const Normalizer2 *nfkc=Normalizer2::getNFKCInstance(*pErrorCode);
-    const UCaseProps *csp=ucase_getSingleton();
     if(U_FAILURE(*pErrorCode)) {
         return 0;
     }
     // first: b = NFKC(Fold(a))
     UnicodeString folded1String;
     const UChar *folded1;
-    int32_t folded1Length=ucase_toFullFolding(csp, c, &folded1, U_FOLD_CASE_DEFAULT);
+    int32_t folded1Length=ucase_toFullFolding(c, &folded1, U_FOLD_CASE_DEFAULT);
     if(folded1Length<0) {
         const Normalizer2Impl *nfkcImpl=Normalizer2Factory::getImpl(nfkc);
         if(nfkcImpl->getCompQuickCheck(nfkcImpl->getNorm16(c))!=UNORM_NO) {
diff --git a/src/third_party/icu/source/common/uprops.h b/src/third_party/icu/source/common/uprops.h
index b9b787f..8bf9299 100644
--- a/src/third_party/icu/source/common/uprops.h
+++ b/src/third_party/icu/source/common/uprops.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  uprops.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -86,8 +88,22 @@
      * ((ntv>>2)-0xbf) * 60^((ntv&3)+1) = (1..9)*(60^1..60^4)
      */
     UPROPS_NTV_BASE60_START=0x300,
+    /**
+     * Fraction-20 values:
+     * frac20 = ntv-0x324 = 0..0x17 -> 1|3|5|7 / 20|40|80|160|320|640
+     * numerator: num = 2*(frac20&3)+1
+     * denominator: den = 20<<(frac20>>2)
+     */
+    UPROPS_NTV_FRACTION20_START=UPROPS_NTV_BASE60_START+36,  // 0x300+9*4=0x324
+    /**
+     * Fraction-32 values:
+     * frac32 = ntv-0x34c = 0..15 -> 1|3|5|7 / 32|64|128|256
+     * numerator: num = 2*(frac32&3)+1
+     * denominator: den = 32<<(frac32>>2)
+     */
+    UPROPS_NTV_FRACTION32_START=UPROPS_NTV_FRACTION20_START+24,  // 0x324+6*4=0x34c
     /** No numeric value (yet). */
-    UPROPS_NTV_RESERVED_START=UPROPS_NTV_BASE60_START+36,  /* 0x300+9*4=0x324 */
+    UPROPS_NTV_RESERVED_START=UPROPS_NTV_FRACTION32_START+16,  // 0x34c+4*4=0x35c
 
     UPROPS_NTV_MAX_SMALL_INT=UPROPS_NTV_FRACTION_START-UPROPS_NTV_NUMERIC_START-1
 };
@@ -105,12 +121,12 @@
  * Properties in vector word 0
  * Bits
  * 31..24   DerivedAge version major/minor one nibble each
- * 23..22   3..1: Bits 7..0 = Script_Extensions index
+ * 23..22   3..1: Bits 21..20 & 7..0 = Script_Extensions index
  *             3: Script value from Script_Extensions
  *             2: Script=Inherited
  *             1: Script=Common
- *             0: Script=bits 7..0
- * 21..20   reserved
+ *             0: Script=bits 21..20 & 7..0
+ * 21..20   Bits 9..8 of the UScriptCode, or index to Script_Extensions
  * 19..17   East Asian Width
  * 16.. 8   UBlockCode
  *  7.. 0   UScriptCode, or index to Script_Extensions
@@ -121,22 +137,43 @@
 #define UPROPS_AGE_SHIFT        24
 
 /* Script_Extensions: mask includes Script */
-#define UPROPS_SCRIPT_X_MASK    0x00c000ff
+#define UPROPS_SCRIPT_X_MASK    0x00f000ff
 #define UPROPS_SCRIPT_X_SHIFT   22
 
+// The UScriptCode or Script_Extensions index is split across two bit fields.
+// (Starting with Unicode 13/ICU 66/2019 due to more varied Script_Extensions.)
+// Shift the high bits right by 12 to assemble the full value.
+#define UPROPS_SCRIPT_HIGH_MASK    0x00300000
+#define UPROPS_SCRIPT_HIGH_SHIFT   12
+#define UPROPS_MAX_SCRIPT          0x3ff
+
 #define UPROPS_EA_MASK          0x000e0000
 #define UPROPS_EA_SHIFT         17
 
 #define UPROPS_BLOCK_MASK       0x0001ff00
 #define UPROPS_BLOCK_SHIFT      8
 
-#define UPROPS_SCRIPT_MASK      0x000000ff
+#define UPROPS_SCRIPT_LOW_MASK  0x000000ff
 
 /* UPROPS_SCRIPT_X_WITH_COMMON must be the lowest value that involves Script_Extensions. */
 #define UPROPS_SCRIPT_X_WITH_COMMON     0x400000
 #define UPROPS_SCRIPT_X_WITH_INHERITED  0x800000
 #define UPROPS_SCRIPT_X_WITH_OTHER      0xc00000
 
+#ifdef __cplusplus
+
+namespace {
+
+inline uint32_t uprops_mergeScriptCodeOrIndex(uint32_t scriptX) {
+    return
+        ((scriptX & UPROPS_SCRIPT_HIGH_MASK) >> UPROPS_SCRIPT_HIGH_SHIFT) |
+        (scriptX & UPROPS_SCRIPT_LOW_MASK);
+}
+
+}  // namespace
+
+#endif  // __cplusplus
+
 /*
  * Properties in vector word 1
  * Each bit encodes one binary property.
@@ -180,15 +217,14 @@
     UPROPS_VARIATION_SELECTOR,
     UPROPS_PATTERN_SYNTAX,                      /* new in ICU 3.4 and Unicode 4.1 */
     UPROPS_PATTERN_WHITE_SPACE,
-    UPROPS_RESERVED,                            /* reserved & unused */
+    UPROPS_PREPENDED_CONCATENATION_MARK,        // new in ICU 60 and Unicode 10
     UPROPS_BINARY_1_TOP                         /* ==32 - full! */
 };
 
 /*
  * Properties in vector word 2
  * Bits
- * 31..28   http://www.unicode.org/reports/tr51/#Emoji_Properties
- * 27..26   reserved
+ * 31..26   http://www.unicode.org/reports/tr51/#Emoji_Properties
  * 25..20   Line Break
  * 19..15   Sentence Break
  * 14..10   Word Break
@@ -196,10 +232,12 @@
  *  4.. 0   Decomposition Type
  */
 enum {
-    UPROPS_2_EMOJI=28,
+    UPROPS_2_EXTENDED_PICTOGRAPHIC=26,
+    UPROPS_2_EMOJI_COMPONENT,
+    UPROPS_2_EMOJI,
     UPROPS_2_EMOJI_PRESENTATION,
     UPROPS_2_EMOJI_MODIFIER,
-    UPROPS_2_EMOJI_MODIFIER_BASE,
+    UPROPS_2_EMOJI_MODIFIER_BASE
 };
 
 #define UPROPS_LB_MASK          0x03f00000
@@ -387,6 +425,10 @@
     UPROPS_SRC_NFKC_CF,
     /** From normalizer2impl.cpp/nfc.nrm canonical iterator data */
     UPROPS_SRC_NFC_CANON_ITER,
+    // Text layout properties.
+    UPROPS_SRC_INPC,
+    UPROPS_SRC_INSC,
+    UPROPS_SRC_VO,
     /** One more than the highest UPropertySource (UPROPS_SRC_) constant. */
     UPROPS_SRC_COUNT
 };
@@ -415,6 +457,9 @@
 U_CFUNC void U_EXPORT2
 upropsvec_addPropertyStarts(const USetAdder *sa, UErrorCode *pErrorCode);
 
+U_CFUNC void U_EXPORT2
+uprops_addPropertyStarts(UPropertySource src, const USetAdder *sa, UErrorCode *pErrorCode);
+
 /**
  * Return a set of characters for property enumeration.
  * For each two consecutive characters (start, limit) in the set,
@@ -442,6 +487,12 @@
 
 class UnicodeSet;
 
+class CharacterProperties {
+public:
+    CharacterProperties() = delete;
+    static const UnicodeSet *getInclusionsForProperty(UProperty prop, UErrorCode &errorCode);
+};
+
 // implemented in uniset_props.cpp
 U_CFUNC UnicodeSet *
 uniset_getUnicode32Instance(UErrorCode &errorCode);
diff --git a/src/third_party/icu/source/common/ures_cnv.c b/src/third_party/icu/source/common/ures_cnv.cpp
similarity index 89%
rename from src/third_party/icu/source/common/ures_cnv.c
rename to src/third_party/icu/source/common/ures_cnv.cpp
index c972901..1aa58e7 100644
--- a/src/third_party/icu/source/common/ures_cnv.c
+++ b/src/third_party/icu/source/common/ures_cnv.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  ures_cnv.c
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -41,7 +43,7 @@
     }
     else {
         length=u_strlen(myPath);
-        if(length>=sizeof(pathBuffer)) {
+        if(length>=(int32_t)sizeof(pathBuffer)) {
             *status=U_ILLEGAL_ARGUMENT_ERROR;
             return NULL;
         } else if(uprv_isInvariantUString(myPath, length)) {
@@ -59,7 +61,7 @@
             if(U_FAILURE(*status)) {
                 return NULL;
             }
-            if(length>=sizeof(pathBuffer)) {
+            if(length>=(int32_t)sizeof(pathBuffer)) {
                 /* not NUL-terminated - path too long */
                 *status=U_ILLEGAL_ARGUMENT_ERROR;
                 return NULL;
diff --git a/src/third_party/icu/source/common/uresbund.cpp b/src/third_party/icu/source/common/uresbund.cpp
index ec52c1d..6d68b6a 100644
--- a/src/third_party/icu/source/common/uresbund.cpp
+++ b/src/third_party/icu/source/common/uresbund.cpp
@@ -1,6 +1,8 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
-* Copyright (C) 1997-2015, International Business Machines Corporation and
+* Copyright (C) 1997-2016, International Business Machines Corporation and
 * others. All Rights Reserved.
 ******************************************************************************
 *
@@ -19,8 +21,11 @@
 ******************************************************************************
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
+#include "unicode/ures.h"
 #include "unicode/ustring.h"
 #include "unicode/ucnv.h"
 #include "charstr.h"
@@ -30,6 +35,7 @@
 #include "ucln_cmn.h"
 #include "cmemory.h"
 #include "cstring.h"
+#include "mutex.h"
 #include "uhash.h"
 #include "unicode/uenum.h"
 #include "uenumimp.h"
@@ -37,6 +43,7 @@
 #include "umutex.h"
 #include "putilimp.h"
 #include "uassert.h"
+#include "uresdata.h"
 
 using namespace icu;
 
@@ -46,9 +53,9 @@
       completely removed.
 */
 static UHashtable *cache = NULL;
-static icu::UInitOnce gCacheInitOnce;
+static icu::UInitOnce gCacheInitOnce = U_INITONCE_INITIALIZER;
 
-static UMutex resbMutex = U_MUTEX_INITIALIZER;
+static UMutex resbMutex;
 
 /* INTERNAL: hashes an entry  */
 static int32_t U_CALLCONV hashEntry(const UHashTok parm) {
@@ -92,13 +99,12 @@
  *  Internal function
  */
 static void entryIncrease(UResourceDataEntry *entry) {
-    umtx_lock(&resbMutex);
+    Mutex lock(&resbMutex);
     entry->fCountExisting++;
     while(entry->fParent != NULL) {
       entry = entry->fParent;
       entry->fCountExisting++;
     }
-    umtx_unlock(&resbMutex);
 }
 
 /**
@@ -180,9 +186,8 @@
     /*if shared data hasn't even been lazy evaluated yet
     * return 0
     */
-    umtx_lock(&resbMutex);
+    Mutex lock(&resbMutex);
     if (cache == NULL) {
-        umtx_unlock(&resbMutex);
         return 0;
     }
 
@@ -214,7 +219,6 @@
          * got decremented by free_entry().
          */
     } while(deletedMore);
-    umtx_unlock(&resbMutex);
 
     return rbDeletedNum;
 }
@@ -228,9 +232,8 @@
   const UHashElement *e;
   UResourceDataEntry *resB;
   
-    umtx_lock(&resbMutex);
+    Mutex lock(&resbMutex);
     if (cache == NULL) {
-      umtx_unlock(&resbMutex);
       fprintf(stderr,"%s:%d: RB Cache is NULL.\n", __FILE__, __LINE__);
       return FALSE;
     }
@@ -249,9 +252,6 @@
     }
     
     fprintf(stderr,"%s:%d: RB Cache still contains %d items.\n", __FILE__, __LINE__, uhash_count(cache));
-
-    umtx_unlock(&resbMutex);
-    
     return cacheNotEmpty;
 }
 
@@ -269,7 +269,7 @@
 }
 
 /** INTERNAL: Initializes the cache for resources */
-static void createCache(UErrorCode &status) {
+static void U_CALLCONV createCache(UErrorCode &status) {
     U_ASSERT(cache == NULL);
     cache = uhash_open(hashEntry, compareEntries, NULL, &status);
     ucln_common_registerCleanup(UCLN_COMMON_URES, ures_cleanup);
@@ -367,7 +367,12 @@
         /* this is the actual loading */
         res_load(&(r->fData), r->fPath, r->fName, status);
 
-        if (U_FAILURE(*status)) { 
+        if (U_FAILURE(*status)) {
+            /* if we failed to load due to an out-of-memory error, exit early. */
+            if (*status == U_MEMORY_ALLOCATION_ERROR) {
+                uprv_free(r);
+                return NULL;
+            }
             /* we have no such entry in dll, so it will always use fallback */
             *status = U_USING_FALLBACK_WARNING;
             r->fBogus = U_USING_FALLBACK_WARNING;
@@ -392,7 +397,8 @@
                 /* We'll try to get alias string from the bundle */
                 aliasres = res_getResource(&(r->fData), "%%ALIAS");
                 if (aliasres != RES_BOGUS) {
-                    const UChar *alias = res_getString(&(r->fData), aliasres, &aliasLen);
+                    // No tracing: called during initial data loading
+                    const UChar *alias = res_getStringNoTrace(&(r->fData), aliasres, &aliasLen);
                     if(alias != NULL && aliasLen > 0) { /* if there is actual alias - unload and load new data */
                         u_UCharsToChars(alias, aliasName, aliasLen+1);
                         r->fAlias = init_entry(aliasName, path, status);
@@ -483,6 +489,9 @@
 
         /*Fallback data stuff*/
         *hasChopped = chopLocale(name);
+        if (*hasChopped && *name == '\0') {
+            uprv_strcpy(name, "und");
+        }
     }
     return r;
 }
@@ -507,6 +516,18 @@
   ures_setIsStackObject(resB, TRUE);
 }
 
+U_NAMESPACE_BEGIN
+
+StackUResourceBundle::StackUResourceBundle() {
+    ures_initStackObject(&bundle);
+}
+
+StackUResourceBundle::~StackUResourceBundle() {
+    ures_close(&bundle);
+}
+
+U_NAMESPACE_END
+
 static UBool  // returns U_SUCCESS(*status)
 loadParentsExceptRoot(UResourceDataEntry *&t1,
                       char name[], int32_t nameCapacity,
@@ -518,7 +539,8 @@
         Resource parentRes = res_getResource(&t1->fData, "%%Parent");
         if (parentRes != RES_BOGUS) {  // An explicit parent was found.
             int32_t parentLocaleLen = 0;
-            const UChar *parentLocaleName = res_getString(&(t1->fData), parentRes, &parentLocaleLen);
+            // No tracing: called during initial data loading
+            const UChar *parentLocaleName = res_getStringNoTrace(&(t1->fData), parentRes, &parentLocaleLen);
             if(parentLocaleName != NULL && 0 < parentLocaleLen && parentLocaleLen < nameCapacity) {
                 u_UCharsToChars(parentLocaleName, name, parentLocaleLen + 1);
                 if (uprv_strcmp(name, kRootLocaleName) == 0) {
@@ -537,6 +559,11 @@
         UErrorCode usrStatus = U_ZERO_ERROR;
         if (usingUSRData) {  // This code inserts user override data into the inheritance chain.
             u2 = init_entry(name, usrDataPath, &usrStatus);
+            // If we failed due to out-of-memory, report that to the caller and exit early.
+            if (usrStatus == U_MEMORY_ALLOCATION_ERROR) {
+                *status = usrStatus;
+                return FALSE;
+            }
         }
 
         if (usingUSRData && U_SUCCESS(usrStatus) && u2->fBogus == U_ZERO_ERROR) {
@@ -637,86 +664,105 @@
         }
     }
  
-    umtx_lock(&resbMutex);
-    { /* umtx_lock */
-        /* We're going to skip all the locales that do not have any data */
-        r = findFirstExisting(path, name, &isRoot, &hasChopped, &isDefault, &intStatus);
+    Mutex lock(&resbMutex);    // Lock resbMutex until the end of this function.
 
-        if(r != NULL) { /* if there is one real locale, we can look for parents. */
+    /* We're going to skip all the locales that do not have any data */
+    r = findFirstExisting(path, name, &isRoot, &hasChopped, &isDefault, &intStatus);
+
+    // If we failed due to out-of-memory, report the failure and exit early.
+    if (intStatus == U_MEMORY_ALLOCATION_ERROR) {
+        *status = intStatus;
+        goto finish;
+    }
+
+    if(r != NULL) { /* if there is one real locale, we can look for parents. */
+        t1 = r;
+        hasRealData = TRUE;
+        if ( usingUSRData ) {  /* This code inserts user override data into the inheritance chain */
+            UErrorCode usrStatus = U_ZERO_ERROR;
+            UResourceDataEntry *u1 = init_entry(t1->fName, usrDataPath, &usrStatus);
+            // If we failed due to out-of-memory, report the failure and exit early.
+            if (intStatus == U_MEMORY_ALLOCATION_ERROR) {
+                *status = intStatus;
+                goto finish;
+            }
+            if ( u1 != NULL ) {
+                if(u1->fBogus == U_ZERO_ERROR) {
+                    u1->fParent = t1;
+                    r = u1;
+                } else {
+                    /* the USR override data wasn't found, set it to be deleted */
+                    u1->fCountExisting = 0;
+                }
+            }
+        }
+        if (hasChopped && !isRoot) {
+            if (!loadParentsExceptRoot(t1, name, UPRV_LENGTHOF(name), usingUSRData, usrDataPath, status)) {
+                goto finish;
+            }
+        }
+    }
+
+    /* we could have reached this point without having any real data */
+    /* if that is the case, we need to chain in the default locale   */
+    if(r==NULL && openType == URES_OPEN_LOCALE_DEFAULT_ROOT && !isDefault && !isRoot) {
+        /* insert default locale */
+        uprv_strcpy(name, uloc_getDefault());
+        r = findFirstExisting(path, name, &isRoot, &hasChopped, &isDefault, &intStatus);
+        // If we failed due to out-of-memory, report the failure and exit early.
+        if (intStatus == U_MEMORY_ALLOCATION_ERROR) {
+            *status = intStatus;
+            goto finish;
+        }
+        intStatus = U_USING_DEFAULT_WARNING;
+        if(r != NULL) { /* the default locale exists */
             t1 = r;
             hasRealData = TRUE;
-            if ( usingUSRData ) {  /* This code inserts user override data into the inheritance chain */
-                UErrorCode usrStatus = U_ZERO_ERROR;
-                UResourceDataEntry *u1 = init_entry(t1->fName, usrDataPath, &usrStatus);
-               if ( u1 != NULL ) {
-                 if(u1->fBogus == U_ZERO_ERROR) {
-                   u1->fParent = t1;
-                   r = u1;
-                 } else {
-                   /* the USR override data wasn't found, set it to be deleted */
-                   u1->fCountExisting = 0;
-                 }
-               }
-            }
+            isDefault = TRUE;
+            // TODO: Why not if (usingUSRData) { ... } like in the non-default-locale code path?
             if (hasChopped && !isRoot) {
                 if (!loadParentsExceptRoot(t1, name, UPRV_LENGTHOF(name), usingUSRData, usrDataPath, status)) {
-                    goto finishUnlock;
+                    goto finish;
                 }
             }
         }
+    }
 
-        /* we could have reached this point without having any real data */
-        /* if that is the case, we need to chain in the default locale   */
-        if(r==NULL && openType == URES_OPEN_LOCALE_DEFAULT_ROOT && !isDefault && !isRoot) {
-            /* insert default locale */
-            uprv_strcpy(name, uloc_getDefault());
-            r = findFirstExisting(path, name, &isRoot, &hasChopped, &isDefault, &intStatus);
+    /* we could still have r == NULL at this point - maybe even default locale is not */
+    /* present */
+    if(r == NULL) {
+        uprv_strcpy(name, kRootLocaleName);
+        r = findFirstExisting(path, name, &isRoot, &hasChopped, &isDefault, &intStatus);
+        // If we failed due to out-of-memory, report the failure and exit early.
+        if (intStatus == U_MEMORY_ALLOCATION_ERROR) {
+            *status = intStatus;
+            goto finish;
+        }
+        if(r != NULL) {
+            t1 = r;
             intStatus = U_USING_DEFAULT_WARNING;
-            if(r != NULL) { /* the default locale exists */
-                t1 = r;
-                hasRealData = TRUE;
-                isDefault = TRUE;
-                // TODO: Why not if (usingUSRData) { ... } like in the non-default-locale code path?
-                if (hasChopped && !isRoot) {
-                    if (!loadParentsExceptRoot(t1, name, UPRV_LENGTHOF(name), usingUSRData, usrDataPath, status)) {
-                        goto finishUnlock;
-                    }
-                }
-            } 
+            hasRealData = TRUE;
+        } else { /* we don't even have the root locale */
+            *status = U_MISSING_RESOURCE_ERROR;
+            goto finish;
         }
-
-        /* we could still have r == NULL at this point - maybe even default locale is not */
-        /* present */
-        if(r == NULL) {
-            uprv_strcpy(name, kRootLocaleName);
-            r = findFirstExisting(path, name, &isRoot, &hasChopped, &isDefault, &intStatus);
-            if(r != NULL) {
-                t1 = r;
-                intStatus = U_USING_DEFAULT_WARNING;
-                hasRealData = TRUE;
-            } else { /* we don't even have the root locale */
-                *status = U_MISSING_RESOURCE_ERROR;
-                goto finishUnlock;
-            }
-        } else if(!isRoot && uprv_strcmp(t1->fName, kRootLocaleName) != 0 &&
-                t1->fParent == NULL && !r->fData.noFallback) {
-            if (!insertRootBundle(t1, status)) {
-                goto finishUnlock;
-            }
-            if(!hasRealData) {
-                r->fBogus = U_USING_DEFAULT_WARNING;
-            }
+    } else if(!isRoot && uprv_strcmp(t1->fName, kRootLocaleName) != 0 &&
+            t1->fParent == NULL && !r->fData.noFallback) {
+        if (!insertRootBundle(t1, status)) {
+            goto finish;
         }
-
-        // TODO: Does this ever loop?
-        while(r != NULL && !isRoot && t1->fParent != NULL) {
-            t1->fParent->fCountExisting++;
-            t1 = t1->fParent;
+        if(!hasRealData) {
+            r->fBogus = U_USING_DEFAULT_WARNING;
         }
-    } /* umtx_lock */
-finishUnlock:
-    umtx_unlock(&resbMutex);
+    }
 
+    // TODO: Does this ever loop?
+    while(r != NULL && !isRoot && t1->fParent != NULL) {
+        t1->fParent->fCountExisting++;
+        t1 = t1->fParent;
+    }
+
+finish:
     if(U_SUCCESS(*status)) {
         if(intStatus != U_ZERO_ERROR) {
             *status = intStatus;  
@@ -740,7 +786,7 @@
         return NULL;
     }
 
-    umtx_lock(&resbMutex);
+    Mutex lock(&resbMutex);
     // findFirstExisting() without fallbacks.
     UResourceDataEntry *r = init_entry(localeID, path, status);
     if(U_SUCCESS(*status)) {
@@ -778,7 +824,6 @@
             t1 = t1->fParent;
         }
     }
-    umtx_unlock(&resbMutex);
     return r;
 }
 
@@ -821,9 +866,8 @@
  */
 
 static void entryClose(UResourceDataEntry *resB) {
-  umtx_lock(&resbMutex);
+  Mutex lock(&resbMutex);
   entryCloseInt(resB);
-  umtx_unlock(&resbMutex);
 }
 
 /*
@@ -1079,10 +1123,11 @@
                             UResourceDataEntry *dataEntry = mainRes->fData;
                             char stackPath[URES_MAX_BUFFER_SIZE];
                             char *pathBuf = stackPath, *myPath = pathBuf;
-                            if(uprv_strlen(keyPath) > URES_MAX_BUFFER_SIZE) {
+                            if(uprv_strlen(keyPath) >= UPRV_LENGTHOF(stackPath)) {
                                 pathBuf = (char *)uprv_malloc((uprv_strlen(keyPath)+1)*sizeof(char));
                                 if(pathBuf == NULL) {
                                     *status = U_MEMORY_ALLOCATION_ERROR;
+                                    ures_close(mainRes);
                                     return NULL;
                                 }
                             }
@@ -1126,6 +1171,7 @@
                     if(mainRes != result) {
                         ures_close(mainRes);
                     }
+                    ResourceTracer(resB).maybeTrace("getalias");
                     return result;
                 }
             } else {
@@ -1205,6 +1251,7 @@
     /*resB->fParent = parent->fRes;*/
     uprv_memmove(&resB->fResData, rdata, sizeof(ResourceData));
     resB->fSize = res_countArrayItems(&(resB->fResData), resB->fRes);
+    ResourceTracer(resB).trace("get");
     return resB;
 }
 
@@ -1253,7 +1300,7 @@
         *status = U_ILLEGAL_ARGUMENT_ERROR;
         return NULL;
     }
-    s = res_getString(&(resB->fResData), resB->fRes, len);
+    s = res_getString({resB}, &(resB->fResData), resB->fRes, len);
     if (s == NULL) {
         *status = U_RESOURCE_TYPE_MISMATCH;
     }
@@ -1342,7 +1389,7 @@
     *status = U_ILLEGAL_ARGUMENT_ERROR;
     return NULL;
   }
-  p = res_getBinary(&(resB->fResData), resB->fRes, len);
+  p = res_getBinary({resB}, &(resB->fResData), resB->fRes, len);
   if (p == NULL) {
     *status = U_RESOURCE_TYPE_MISMATCH;
   }
@@ -1359,7 +1406,7 @@
     *status = U_ILLEGAL_ARGUMENT_ERROR;
     return NULL;
   }
-  p = res_getIntVector(&(resB->fResData), resB->fRes, len);
+  p = res_getIntVector({resB}, &(resB->fResData), resB->fRes, len);
   if (p == NULL) {
     *status = U_RESOURCE_TYPE_MISMATCH;
   }
@@ -1380,7 +1427,7 @@
     *status = U_RESOURCE_TYPE_MISMATCH;
     return 0xffffffff;
   }
-  return RES_GET_INT(resB->fRes);
+  return res_getInt({resB}, resB->fRes);
 }
 
 U_CAPI uint32_t U_EXPORT2 ures_getUInt(const UResourceBundle* resB, UErrorCode *status) {
@@ -1395,7 +1442,7 @@
     *status = U_RESOURCE_TYPE_MISMATCH;
     return 0xffffffff;
   }
-  return RES_GET_UINT(resB->fRes);
+  return res_getUInt({resB}, resB->fRes);
 }
 
 U_CAPI UResType U_EXPORT2 ures_getType(const UResourceBundle *resB) {
@@ -1406,10 +1453,18 @@
 }
 
 U_CAPI const char * U_EXPORT2 ures_getKey(const UResourceBundle *resB) {
+  //
+  // TODO: Trace ures_getKey? I guess not usually.
+  //
+  // We usually get the key string to decide whether we want the value, or to
+  // make a key-value pair. Tracing the value should suffice.
+  //
+  // However, I believe we have some data (e.g., in res_index) where the key
+  // strings are the data. Tracing the enclosing table should suffice.
+  //
   if(resB == NULL) {
     return NULL;
   }
-  
   return(resB->fKey);
 }
 
@@ -1429,7 +1484,7 @@
     ures_close(tempRes);
     return result;
   } else {
-    return res_getString(&(resB->fResData), r, len); 
+    return res_getString({resB, sIndex}, &(resB->fResData), r, len); 
   }
 }
 
@@ -1465,7 +1520,7 @@
     switch(RES_GET_TYPE(resB->fRes)) {
     case URES_STRING:
     case URES_STRING_V2:
-      return res_getString(&(resB->fResData), resB->fRes, len); 
+      return res_getString({resB}, &(resB->fResData), resB->fRes, len);
     case URES_TABLE:
     case URES_TABLE16:
     case URES_TABLE32:
@@ -1487,7 +1542,8 @@
     case URES_BINARY:
     case URES_INT_VECTOR:
         *status = U_RESOURCE_TYPE_MISMATCH;
-    default: /*fall through*/
+        U_FALLTHROUGH;
+    default:
       return NULL;
     }
   }
@@ -1609,7 +1665,7 @@
         switch(RES_GET_TYPE(resB->fRes)) {
         case URES_STRING:
         case URES_STRING_V2:
-            return res_getString(&(resB->fResData), resB->fRes, len);
+            return res_getString({resB}, &(resB->fResData), resB->fRes, len);
         case URES_TABLE:
         case URES_TABLE16:
         case URES_TABLE32:
@@ -1740,7 +1796,7 @@
 
   return result;
 }
-U_INTERNAL const UChar* U_EXPORT2 
+U_CAPI const UChar* U_EXPORT2 
 ures_getStringByKeyWithFallback(const UResourceBundle *resB, 
                                 const char* inKey, 
                                 int32_t* len,
@@ -1886,32 +1942,27 @@
 
 namespace {
 
-void getAllContainerItemsWithFallback(
+void getAllItemsWithFallback(
         const UResourceBundle *bundle, ResourceDataValue &value,
-        ResourceArraySink *arraySink, ResourceTableSink *tableSink,
+        ResourceSink &sink,
         UErrorCode &errorCode) {
     if (U_FAILURE(errorCode)) { return; }
     // We recursively enumerate child-first,
     // only storing parent items in the absence of child items.
-    // We store a placeholder value for the no-fallback/no-inheritance marker
+    // The sink needs to store a placeholder value for the no-fallback/no-inheritance marker
     // to prevent a parent item from being stored.
     //
     // It would be possible to recursively enumerate parent-first,
     // overriding parent items with child items.
-    // When we see the no-fallback/no-inheritance marker,
-    // then we would remove the parent's item.
+    // When the sink sees the no-fallback/no-inheritance marker,
+    // then it would remove the parent's item.
     // We would deserialize parent values even though they are overridden in a child bundle.
-    UResType expectedType = arraySink != NULL ? URES_ARRAY : URES_TABLE;
-    if (ures_getType(bundle) == expectedType) {
-        value.pResData = &bundle->fResData;
-        if (arraySink != NULL) {
-            ures_getAllArrayItems(&bundle->fResData, bundle->fRes, value, *arraySink, errorCode);
-        } else /* tableSink != NULL */ {
-            ures_getAllTableItems(&bundle->fResData, bundle->fRes, value, *tableSink, errorCode);
-        }
-    }
-    UResourceDataEntry *entry = bundle->fData->fParent;
-    if (entry != NULL && U_SUCCESS(entry->fBogus)) {
+    value.setData(&bundle->fResData);
+    UResourceDataEntry *parentEntry = bundle->fData->fParent;
+    UBool hasParent = parentEntry != NULL && U_SUCCESS(parentEntry->fBogus);
+    value.setResource(bundle->fRes, ResourceTracer(bundle));
+    sink.put(bundle->fKey, value, !hasParent, errorCode);
+    if (hasParent) {
         // We might try to query the sink whether
         // any fallback from the parent bundle is still possible.
 
@@ -1922,82 +1973,92 @@
         // so that we need not create UResourceBundle objects.
         UResourceBundle parentBundle;
         ures_initStackObject(&parentBundle);
-        parentBundle.fTopLevelData = parentBundle.fData = entry;
+        parentBundle.fTopLevelData = parentBundle.fData = parentEntry;
         // TODO: What is the difference between bundle fData and fTopLevelData?
-        uprv_memcpy(&parentBundle.fResData, &entry->fData, sizeof(ResourceData));
+        uprv_memcpy(&parentBundle.fResData, &parentEntry->fData, sizeof(ResourceData));
         // TODO: Try to replace bundle.fResData with just using bundle.fData->fData.
         parentBundle.fHasFallback = !parentBundle.fResData.noFallback;
         parentBundle.fIsTopLevel = TRUE;
         parentBundle.fRes = parentBundle.fResData.rootRes;
         parentBundle.fSize = res_countArrayItems(&(parentBundle.fResData), parentBundle.fRes);
         parentBundle.fIndex = -1;
-        entryIncrease(entry);
+        entryIncrease(parentEntry);
 
         // Look up the container item in the parent bundle.
         UResourceBundle containerBundle;
         ures_initStackObject(&containerBundle);
         const UResourceBundle *rb;
+        UErrorCode pathErrorCode = U_ZERO_ERROR;  // Ignore if parents up to root do not have this path.
         if (bundle->fResPath == NULL || *bundle->fResPath == 0) {
             rb = &parentBundle;
         } else {
             rb = ures_getByKeyWithFallback(&parentBundle, bundle->fResPath,
-                                           &containerBundle, &errorCode);
+                                           &containerBundle, &pathErrorCode);
         }
-        if (U_SUCCESS(errorCode) && ures_getType(rb) == expectedType) {
-            getAllContainerItemsWithFallback(rb, value,
-                                             arraySink, tableSink, errorCode);
+        if (U_SUCCESS(pathErrorCode)) {
+            getAllItemsWithFallback(rb, value, sink, errorCode);
         }
         ures_close(&containerBundle);
         ures_close(&parentBundle);
     }
 }
 
-void getAllContainerItemsWithFallback(
-        const UResourceBundle *bundle, const char *path,
-        ResourceArraySink *arraySink, ResourceTableSink *tableSink,
-        UErrorCode &errorCode) {
+}  // namespace
+
+// Requires a ResourceDataValue fill-in, so that we need not cast from a ResourceValue.
+// Unfortunately, the caller must know which subclass to make and pass in.
+// Alternatively, we could make it as polymorphic as in Java by
+// returning a ResourceValue pointer (possibly wrapped into a LocalPointer)
+// that the caller then owns.
+//
+// Also requires a UResourceBundle fill-in, so that the value's ResourceTracer
+// can point to a non-local bundle.
+// Without tracing, the child bundle could be a function-local object.
+U_CAPI void U_EXPORT2
+ures_getValueWithFallback(const UResourceBundle *bundle, const char *path,
+                          UResourceBundle *tempFillIn,
+                          ResourceDataValue &value, UErrorCode &errorCode) {
     if (U_FAILURE(errorCode)) { return; }
-    if (path == NULL) {
+    if (path == nullptr) {
         errorCode = U_ILLEGAL_ARGUMENT_ERROR;
         return;
     }
-    UResourceBundle stackBundle;
-    ures_initStackObject(&stackBundle);
     const UResourceBundle *rb;
     if (*path == 0) {
         // empty path
         rb = bundle;
     } else {
-        rb = ures_getByKeyWithFallback(bundle, path, &stackBundle, &errorCode);
+        rb = ures_getByKeyWithFallback(bundle, path, tempFillIn, &errorCode);
         if (U_FAILURE(errorCode)) {
-            ures_close(&stackBundle);
             return;
         }
     }
-    UResType expectedType = arraySink != NULL ? URES_ARRAY : URES_TABLE;
-    if (ures_getType(rb) != expectedType) {
-        errorCode = U_RESOURCE_TYPE_MISMATCH;
-        ures_close(&stackBundle);
+    value.setData(&rb->fResData);
+    value.setResource(rb->fRes, ResourceTracer(rb));
+}
+
+U_CAPI void U_EXPORT2
+ures_getAllItemsWithFallback(const UResourceBundle *bundle, const char *path,
+                             icu::ResourceSink &sink, UErrorCode &errorCode) {
+    if (U_FAILURE(errorCode)) { return; }
+    if (path == nullptr) {
+        errorCode = U_ILLEGAL_ARGUMENT_ERROR;
         return;
     }
+    StackUResourceBundle stackBundle;
+    const UResourceBundle *rb;
+    if (*path == 0) {
+        // empty path
+        rb = bundle;
+    } else {
+        rb = ures_getByKeyWithFallback(bundle, path, stackBundle.getAlias(), &errorCode);
+        if (U_FAILURE(errorCode)) {
+            return;
+        }
+    }
     // Get all table items with fallback.
     ResourceDataValue value;
-    getAllContainerItemsWithFallback(rb, value, arraySink, tableSink, errorCode);
-    ures_close(&stackBundle);
-}
-
-}  // namespace
-
-U_CAPI void U_EXPORT2
-ures_getAllArrayItemsWithFallback(const UResourceBundle *bundle, const char *path,
-                                  ResourceArraySink &sink, UErrorCode &errorCode) {
-    getAllContainerItemsWithFallback(bundle, path, &sink, NULL, errorCode);
-}
-
-U_CAPI void U_EXPORT2
-ures_getAllTableItemsWithFallback(const UResourceBundle *bundle, const char *path,
-                                  ResourceTableSink &sink, UErrorCode &errorCode) {
-    getAllContainerItemsWithFallback(bundle, path, NULL, &sink, errorCode);
+    getAllItemsWithFallback(rb, value, sink, errorCode);
 }
 
 U_CAPI UResourceBundle* U_EXPORT2 ures_getByKey(const UResourceBundle *resB, const char* inKey, UResourceBundle *fillIn, UErrorCode *status) {
@@ -2080,7 +2141,7 @@
                     switch (RES_GET_TYPE(res)) {
                     case URES_STRING:
                     case URES_STRING_V2:
-                        return res_getString(rd, res, len);
+                        return res_getString({resB, key}, rd, res, len);
                     case URES_ALIAS:
                       {
                         const UChar* result = 0;
@@ -2102,7 +2163,7 @@
             switch (RES_GET_TYPE(res)) {
             case URES_STRING:
             case URES_STRING_V2:
-                return res_getString(&(resB->fResData), res, len);
+                return res_getString({resB, key}, &(resB->fResData), res, len);
             case URES_ALIAS:
               {
                 const UChar* result = 0;
@@ -2123,6 +2184,7 @@
         /* here should go a first attempt to locate the key using index table */
         const ResourceData *rd = getFallbackData(resB, &key, &realData, &res, status);
         if(U_SUCCESS(*status)) {
+            // TODO: Tracing
             return res_getString(rd, res, len);
         } else {
             *status = U_MISSING_RESOURCE_ERROR;
@@ -2152,7 +2214,7 @@
  *  INTERNAL: Get the name of the first real locale (not placeholder) 
  *  that has resource bundle data.
  */
-U_INTERNAL const char*  U_EXPORT2
+U_CAPI const char*  U_EXPORT2
 ures_getLocaleInternal(const UResourceBundle* resourceBundle, UErrorCode* status)
 {
     if (status==NULL || U_FAILURE(*status)) {
@@ -2268,6 +2330,8 @@
     r->fSize = res_countArrayItems(&(r->fResData), r->fRes);
     r->fIndex = -1;
 
+    ResourceTracer(r).traceOpen();
+
     return r;
 }
 
@@ -2291,9 +2355,11 @@
 }
 
 /**
- *  API: This function is used to open a resource bundle 
+ *  Internal API: This function is used to open a resource bundle 
  *  proper fallback chaining is executed while initialization. 
  *  The result is stored in cache for later fallback search.
+ * 
+ * Same as ures_open(), but uses the fill-in parameter and does not allocate a new bundle.
  */
 U_CAPI void U_EXPORT2
 ures_openFillIn(UResourceBundle *r, const char* path,
@@ -2306,6 +2372,18 @@
 }
 
 /**
+ * Same as ures_openDirect(), but uses the fill-in parameter and does not allocate a new bundle.
+ */
+U_CAPI void U_EXPORT2
+ures_openDirectFillIn(UResourceBundle *r, const char* path, const char* localeID, UErrorCode* status) {
+    if(U_SUCCESS(*status) && r == NULL) {
+        *status = U_ILLEGAL_ARGUMENT_ERROR;
+        return;
+    }
+    ures_openWithType(r, path, localeID, URES_OPEN_DIRECT, status);
+}
+
+/**
  *  API: Counts members. For arrays and tables, returns number of resources.
  *  For strings, returns 1.
  */
@@ -2346,7 +2424,7 @@
  * @see ures_getVersion
  * @internal
  */
-U_INTERNAL const char* U_EXPORT2 
+U_CAPI const char* U_EXPORT2 
 ures_getVersionNumberInternal(const UResourceBundle *resourceBundle)
 {
     if (!resourceBundle) return NULL;
@@ -2431,7 +2509,10 @@
     return ures_getSize(&ctx->installed);
 }
 
-static const char* U_CALLCONV 
+U_CDECL_BEGIN
+
+
+static const char * U_CALLCONV
 ures_loc_nextLocale(UEnumeration* en,
                     int32_t* resultLength,
                     UErrorCode* status) {
@@ -2440,7 +2521,7 @@
     UResourceBundle *k = NULL;
     const char *result = NULL;
     int32_t len = 0;
-    if(ures_hasNext(res) && (k = ures_getNextResource(res, &ctx->curr, status))) {
+    if(ures_hasNext(res) && (k = ures_getNextResource(res, &ctx->curr, status)) != 0) {
         result = ures_getKey(k);
         len = (int32_t)uprv_strlen(result);
     }
@@ -2457,6 +2538,7 @@
     ures_resetIterator(res);
 }
 
+U_CDECL_END
 
 static const UEnumeration gLocalesEnum = {
     NULL,
@@ -2533,8 +2615,8 @@
     char defVal[1024] = ""; /* default value for given locale */
     char defLoc[1024] = ""; /* default value for given locale */
     char base[1024] = ""; /* base locale */
-    char found[1024];
-    char parent[1024];
+    char found[1024] = "";
+    char parent[1024] = "";
     char full[1024] = "";
     UResourceBundle bund1, bund2;
     UResourceBundle *res = NULL;
@@ -2861,7 +2943,7 @@
     valuesBuf[0]=0;
     valuesBuf[1]=0;
     
-    while((locale = uenum_next(locs, &locLen, status))) {
+    while((locale = uenum_next(locs, &locLen, status)) != 0) {
         UResourceBundle   *bund = NULL;
         UResourceBundle   *subPtr = NULL;
         UErrorCode subStatus = U_ZERO_ERROR; /* don't fail if a bundle is unopenable */
@@ -2886,7 +2968,7 @@
             continue;
         }
         
-        while((subPtr = ures_getNextResource(&item,&subItem,&subStatus))
+        while((subPtr = ures_getNextResource(&item,&subItem,&subStatus)) != 0
             && U_SUCCESS(subStatus)) {
             const char *k;
             int32_t i;
@@ -2938,7 +3020,7 @@
 }
 #if 0
 /* This code isn't needed, and given the documentation warnings the implementation is suspect */
-U_INTERNAL UBool U_EXPORT2
+U_CAPI UBool U_EXPORT2
 ures_equal(const UResourceBundle* res1, const UResourceBundle* res2){
     if(res1==NULL || res2==NULL){
         return res1==res2; /* pointer comparision */
@@ -2974,7 +3056,7 @@
     }
     return TRUE;
 }
-U_INTERNAL UResourceBundle* U_EXPORT2
+U_CAPI UResourceBundle* U_EXPORT2
 ures_clone(const UResourceBundle* res, UErrorCode* status){
     UResourceBundle* bundle = NULL;
     UResourceBundle* ret = NULL;
@@ -2990,7 +3072,7 @@
     }
     return ret;
 }
-U_INTERNAL const UResourceBundle* U_EXPORT2
+U_CAPI const UResourceBundle* U_EXPORT2
 ures_getParentBundle(const UResourceBundle* res){
     if(res==NULL){
         return NULL;
@@ -2999,7 +3081,7 @@
 }
 #endif
 
-U_INTERNAL void U_EXPORT2
+U_CAPI void U_EXPORT2
 ures_getVersionByKey(const UResourceBundle* res, const char *key, UVersionInfo ver, UErrorCode *status) {
   const UChar *str;
   int32_t len;
diff --git a/src/third_party/icu/source/common/uresdata.cpp b/src/third_party/icu/source/common/uresdata.cpp
index 264d0cc..302a797 100644
--- a/src/third_party/icu/source/common/uresdata.cpp
+++ b/src/third_party/icu/source/common/uresdata.cpp
@@ -1,10 +1,12 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
-* Copyright (C) 1999-2015, International Business Machines Corporation
+* Copyright (C) 1999-2016, International Business Machines Corporation
 *               and others. All Rights Reserved.
 *******************************************************************************
 *   file name:  uresdata.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -17,8 +19,10 @@
 *   06/24/02    weiv        Added support for resource sharing
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/utypes.h"
 #include "unicode/udata.h"
 #include "unicode/ustring.h"
@@ -33,6 +37,7 @@
 #include "uinvchar.h"
 #include "uresdata.h"
 #include "uresimp.h"
+#include "utracimp.h"
 
 /*
  * Resource access helpers
@@ -307,7 +312,7 @@
 }
 
 U_CAPI const UChar * U_EXPORT2
-res_getString(const ResourceData *pResData, Resource res, int32_t *pLength) {
+res_getStringNoTrace(const ResourceData *pResData, Resource res, int32_t *pLength) {
     const UChar *p;
     uint32_t offset=RES_GET_OFFSET(res);
     int32_t length;
@@ -382,6 +387,37 @@
     return FALSE;
 }
 
+int32_t getStringArray(const ResourceData *pResData, const icu::ResourceArray &array,
+                       icu::UnicodeString *dest, int32_t capacity,
+                       UErrorCode &errorCode) {
+    if(U_FAILURE(errorCode)) {
+        return 0;
+    }
+    if(dest == NULL ? capacity != 0 : capacity < 0) {
+        errorCode = U_ILLEGAL_ARGUMENT_ERROR;
+        return 0;
+    }
+    int32_t length = array.getSize();
+    if(length == 0) {
+        return 0;
+    }
+    if(length > capacity) {
+        errorCode = U_BUFFER_OVERFLOW_ERROR;
+        return length;
+    }
+    for(int32_t i = 0; i < length; ++i) {
+        int32_t sLength;
+        // No tracing: handled by the caller
+        const UChar *s = res_getStringNoTrace(pResData, array.internalGetResource(pResData, i), &sLength);
+        if(s == NULL) {
+            errorCode = U_RESOURCE_TYPE_MISMATCH;
+            return 0;
+        }
+        dest[i].setTo(TRUE, s, sLength);
+    }
+    return length;
+}
+
 }  // namespace
 
 U_CAPI const UChar * U_EXPORT2
@@ -404,7 +440,7 @@
 }
 
 U_CAPI const uint8_t * U_EXPORT2
-res_getBinary(const ResourceData *pResData, Resource res, int32_t *pLength) {
+res_getBinaryNoTrace(const ResourceData *pResData, Resource res, int32_t *pLength) {
     const uint8_t *p;
     uint32_t offset=RES_GET_OFFSET(res);
     int32_t length;
@@ -424,7 +460,7 @@
 
 
 U_CAPI const int32_t * U_EXPORT2
-res_getIntVector(const ResourceData *pResData, Resource res, int32_t *pLength) {
+res_getIntVectorNoTrace(const ResourceData *pResData, Resource res, int32_t *pLength) {
     const int32_t *p;
     uint32_t offset=RES_GET_OFFSET(res);
     int32_t length;
@@ -465,42 +501,6 @@
     }
 }
 
-namespace {
-
-int32_t getArrayLength(const ResourceData *pResData, Resource res) {
-    uint32_t offset=RES_GET_OFFSET(res);
-    if(offset == 0) {
-        return 0;
-    }
-    int32_t type = RES_GET_TYPE(res);
-    if(type == URES_ARRAY) {
-        return *(pResData->pRoot+offset);
-    } else if(type == URES_ARRAY16) {
-        return pResData->p16BitUnits[offset];
-    } else {
-        return 0;
-    }
-}
-
-int32_t getTableLength(const ResourceData *pResData, Resource res) {
-    uint32_t offset=RES_GET_OFFSET(res);
-    if(offset == 0) {
-        return 0;
-    }
-    int32_t type = RES_GET_TYPE(res);
-    if(type == URES_TABLE) {
-        return *((const uint16_t *)(pResData->pRoot+offset));
-    } else if(type == URES_TABLE16) {
-        return pResData->p16BitUnits[offset];
-    } else if(type == URES_TABLE32) {
-        return *(pResData->pRoot+offset);
-    } else {
-        return 0;
-    }
-}
-
-}  // namespace
-
 U_NAMESPACE_BEGIN
 
 ResourceDataValue::~ResourceDataValue() {}
@@ -513,7 +513,7 @@
     if(U_FAILURE(errorCode)) {
         return NULL;
     }
-    const UChar *s = res_getString(pResData, res, &length);
+    const UChar *s = res_getString(fTraceInfo, &getData(), res, &length);
     if(s == NULL) {
         errorCode = U_RESOURCE_TYPE_MISMATCH;
     }
@@ -524,7 +524,7 @@
     if(U_FAILURE(errorCode)) {
         return NULL;
     }
-    const UChar *s = res_getAlias(pResData, res, &length);
+    const UChar *s = res_getAlias(&getData(), res, &length);
     if(s == NULL) {
         errorCode = U_RESOURCE_TYPE_MISMATCH;
     }
@@ -538,7 +538,7 @@
     if(RES_GET_TYPE(res) != URES_INT) {
         errorCode = U_RESOURCE_TYPE_MISMATCH;
     }
-    return RES_GET_INT(res);
+    return res_getInt(fTraceInfo, res);
 }
 
 uint32_t ResourceDataValue::getUInt(UErrorCode &errorCode) const {
@@ -548,14 +548,14 @@
     if(RES_GET_TYPE(res) != URES_INT) {
         errorCode = U_RESOURCE_TYPE_MISMATCH;
     }
-    return RES_GET_UINT(res);
+    return res_getUInt(fTraceInfo, res);
 }
 
 const int32_t *ResourceDataValue::getIntVector(int32_t &length, UErrorCode &errorCode) const {
     if(U_FAILURE(errorCode)) {
         return NULL;
     }
-    const int32_t *iv = res_getIntVector(pResData, res, &length);
+    const int32_t *iv = res_getIntVector(fTraceInfo, &getData(), res, &length);
     if(iv == NULL) {
         errorCode = U_RESOURCE_TYPE_MISMATCH;
     }
@@ -566,13 +566,138 @@
     if(U_FAILURE(errorCode)) {
         return NULL;
     }
-    const uint8_t *b = res_getBinary(pResData, res, &length);
+    const uint8_t *b = res_getBinary(fTraceInfo, &getData(), res, &length);
     if(b == NULL) {
         errorCode = U_RESOURCE_TYPE_MISMATCH;
     }
     return b;
 }
 
+ResourceArray ResourceDataValue::getArray(UErrorCode &errorCode) const {
+    if(U_FAILURE(errorCode)) {
+        return ResourceArray();
+    }
+    const uint16_t *items16 = NULL;
+    const Resource *items32 = NULL;
+    uint32_t offset=RES_GET_OFFSET(res);
+    int32_t length = 0;
+    switch(RES_GET_TYPE(res)) {
+    case URES_ARRAY:
+        if (offset!=0) {  // empty if offset==0
+            items32 = (const Resource *)getData().pRoot+offset;
+            length = *items32++;
+        }
+        break;
+    case URES_ARRAY16:
+        items16 = getData().p16BitUnits+offset;
+        length = *items16++;
+        break;
+    default:
+        errorCode = U_RESOURCE_TYPE_MISMATCH;
+        return ResourceArray();
+    }
+    return ResourceArray(items16, items32, length, fTraceInfo);
+}
+
+ResourceTable ResourceDataValue::getTable(UErrorCode &errorCode) const {
+    if(U_FAILURE(errorCode)) {
+        return ResourceTable();
+    }
+    const uint16_t *keys16 = NULL;
+    const int32_t *keys32 = NULL;
+    const uint16_t *items16 = NULL;
+    const Resource *items32 = NULL;
+    uint32_t offset = RES_GET_OFFSET(res);
+    int32_t length = 0;
+    switch(RES_GET_TYPE(res)) {
+    case URES_TABLE:
+        if (offset != 0) {  // empty if offset==0
+            keys16 = (const uint16_t *)(getData().pRoot+offset);
+            length = *keys16++;
+            items32 = (const Resource *)(keys16+length+(~length&1));
+        }
+        break;
+    case URES_TABLE16:
+        keys16 = getData().p16BitUnits+offset;
+        length = *keys16++;
+        items16 = keys16 + length;
+        break;
+    case URES_TABLE32:
+        if (offset != 0) {  // empty if offset==0
+            keys32 = getData().pRoot+offset;
+            length = *keys32++;
+            items32 = (const Resource *)keys32 + length;
+        }
+        break;
+    default:
+        errorCode = U_RESOURCE_TYPE_MISMATCH;
+        return ResourceTable();
+    }
+    return ResourceTable(keys16, keys32, items16, items32, length, fTraceInfo);
+}
+
+UBool ResourceDataValue::isNoInheritanceMarker() const {
+    return ::isNoInheritanceMarker(&getData(), res);
+}
+
+int32_t ResourceDataValue::getStringArray(UnicodeString *dest, int32_t capacity,
+                                          UErrorCode &errorCode) const {
+    return ::getStringArray(&getData(), getArray(errorCode), dest, capacity, errorCode);
+}
+
+int32_t ResourceDataValue::getStringArrayOrStringAsArray(UnicodeString *dest, int32_t capacity,
+                                                         UErrorCode &errorCode) const {
+    if(URES_IS_ARRAY(res)) {
+        return ::getStringArray(&getData(), getArray(errorCode), dest, capacity, errorCode);
+    }
+    if(U_FAILURE(errorCode)) {
+        return 0;
+    }
+    if(dest == NULL ? capacity != 0 : capacity < 0) {
+        errorCode = U_ILLEGAL_ARGUMENT_ERROR;
+        return 0;
+    }
+    if(capacity < 1) {
+        errorCode = U_BUFFER_OVERFLOW_ERROR;
+        return 1;
+    }
+    int32_t sLength;
+    const UChar *s = res_getString(fTraceInfo, &getData(), res, &sLength);
+    if(s != NULL) {
+        dest[0].setTo(TRUE, s, sLength);
+        return 1;
+    }
+    errorCode = U_RESOURCE_TYPE_MISMATCH;
+    return 0;
+}
+
+UnicodeString ResourceDataValue::getStringOrFirstOfArray(UErrorCode &errorCode) const {
+    UnicodeString us;
+    if(U_FAILURE(errorCode)) {
+        return us;
+    }
+    int32_t sLength;
+    const UChar *s = res_getString(fTraceInfo, &getData(), res, &sLength);
+    if(s != NULL) {
+        us.setTo(TRUE, s, sLength);
+        return us;
+    }
+    ResourceArray array = getArray(errorCode);
+    if(U_FAILURE(errorCode)) {
+        return us;
+    }
+    if(array.getSize() > 0) {
+        // Tracing is already performed above (unimportant for trace that this is an array)
+        s = res_getStringNoTrace(&getData(), array.internalGetResource(&getData(), 0), &sLength);
+        if(s != NULL) {
+            us.setTo(TRUE, s, sLength);
+            return us;
+        }
+    }
+    errorCode = U_RESOURCE_TYPE_MISMATCH;
+    return us;
+}
+
 U_NAMESPACE_END
 
 static Resource
@@ -640,7 +765,9 @@
                         int32_t indexR, const char **key) {
     uint32_t offset=RES_GET_OFFSET(table);
     int32_t length;
-    U_ASSERT(indexR>=0); /* to ensure the index is not negative */
+    if (indexR < 0) {
+        return RES_BOGUS;
+    }
     switch(RES_GET_TYPE(table)) {
     case URES_TABLE: {
         if (offset != 0) { /* empty if offset==0 */
@@ -693,97 +820,61 @@
     return res_getTableItemByKey(pResData, pResData->rootRes, &idx, &realKey);
 }
 
-// TODO: Ported from Java, but enumerating at this low level may prevent us
-// from doing necessary things, like resolving aliases,
-// which need access to higher-level UResourceBundle code.
-// Consider porting the low-level Container/Array/Table classes from Java,
-// with getters for keys and values,
-// and doing the enumeration in the higher-level code on top of those accessors.
-U_CFUNC void
-ures_getAllTableItems(const ResourceData *pResData, Resource table,
-                      icu::ResourceDataValue &value, icu::ResourceTableSink &sink,
-                      UErrorCode &errorCode) {
-    if(U_FAILURE(errorCode)) { return; }
-    const uint16_t *keys16 = NULL;
-    const int32_t *keys32 = NULL;
-    const uint16_t *items16 = NULL;
-    const Resource *items32 = NULL;
-    uint32_t offset = RES_GET_OFFSET(table);
-    int32_t length = 0;
-    switch(RES_GET_TYPE(table)) {
-    case URES_TABLE: {
-        if (offset != 0) { /* empty if offset==0 */
-            keys16 = (const uint16_t *)(pResData->pRoot+offset);
-            length = *keys16++;
-            items32 = (const Resource *)(keys16+length+(~length&1));
-        }
-        break;
-    }
-    case URES_TABLE16: {
-        keys16 = pResData->p16BitUnits+offset;
-        length = *keys16++;
-        items16 = keys16 + length;
-        break;
-    }
-    case URES_TABLE32: {
-        if (offset != 0) { /* empty if offset==0 */
-            keys32 = pResData->pRoot+offset;
-            length = *keys32++;
-            items32 = (const Resource *)keys32 + length;
-        }
-        break;
-    }
-    default:
-        errorCode = U_RESOURCE_TYPE_MISMATCH;
-        return;
-    }
 
-    for (int32_t i = 0; i < length; ++i) {
-        const char *key;
-        if (keys16 != NULL) {
-            key=RES_GET_KEY16(pResData, keys16[i]);
+UBool icu::ResourceTable::getKeyAndValue(int32_t i,
+                                         const char *&key, icu::ResourceValue &value) const {
+    if(0 <= i && i < length) {
+        icu::ResourceDataValue &rdValue = static_cast<icu::ResourceDataValue &>(value);
+        if (keys16 != nullptr) {
+            key = RES_GET_KEY16(&rdValue.getData(), keys16[i]);
         } else {
-            key=RES_GET_KEY32(pResData, keys32[i]);
+            key = RES_GET_KEY32(&rdValue.getData(), keys32[i]);
         }
         Resource res;
-        if (items16 != NULL) {
-            res = makeResourceFrom16(pResData, items16[i]);
+        if (items16 != nullptr) {
+            res = makeResourceFrom16(&rdValue.getData(), items16[i]);
         } else {
             res = items32[i];
         }
-        int32_t type = RES_GET_TYPE(res);
-        if (URES_IS_ARRAY(type)) {
-            int32_t numItems = getArrayLength(pResData, res);
-            icu::ResourceArraySink *subSink = sink.getOrCreateArraySink(key, numItems, errorCode);
-            if (subSink != NULL) {
-                ures_getAllArrayItems(pResData, res, value, *subSink, errorCode);
-            }
-        } else if (URES_IS_TABLE(type)) {
-            int32_t numItems = getTableLength(pResData, res);
-            icu::ResourceTableSink *subSink = sink.getOrCreateTableSink(key, numItems, errorCode);
-            if (subSink != NULL) {
-                ures_getAllTableItems(pResData, res, value, *subSink, errorCode);
-            }
-        /* TODO: settle on how to deal with aliases, port to Java
-        } else if (type == URES_ALIAS) {
-            // aliases not handled in resource enumeration
-            errorCode = U_UNSUPPORTED_ERROR;
-            return; */
-        } else if (isNoInheritanceMarker(pResData, res)) {
-            sink.putNoFallback(key, errorCode);
-        } else {
-            value.setResource(res);
-            sink.put(key, value, errorCode);
-        }
-        if(U_FAILURE(errorCode)) { return; }
+        // Note: the ResourceTracer keeps a reference to the field of this
+        // ResourceTable. This is OK because the ResourceTable should remain
+        // alive for the duration that fields are being read from it
+        // (including nested fields).
+        rdValue.setResource(res, ResourceTracer(fTraceInfo, key));
+        return TRUE;
     }
-    sink.leave(errorCode);
+    return FALSE;
+}
+
+UBool icu::ResourceTable::findValue(const char *key, ResourceValue &value) const {
+    icu::ResourceDataValue &rdValue = static_cast<icu::ResourceDataValue &>(value);
+    const char *realKey = nullptr;
+    int32_t i;
+    if (keys16 != nullptr) {
+        i = _res_findTableItem(&rdValue.getData(), keys16, length, key, &realKey);
+    } else {
+        i = _res_findTable32Item(&rdValue.getData(), keys32, length, key, &realKey);
+    }
+    if (i >= 0) {
+        Resource res;
+        if (items16 != nullptr) {
+            res = makeResourceFrom16(&rdValue.getData(), items16[i]);
+        } else {
+            res = items32[i];
+        }
+        // Same note about lifetime as in getKeyAndValue().
+        rdValue.setResource(res, ResourceTracer(fTraceInfo, key));
+        return TRUE;
+    }
+    return FALSE;
 }
 
 U_CAPI Resource U_EXPORT2
 res_getArrayItem(const ResourceData *pResData, Resource array, int32_t indexR) {
     uint32_t offset=RES_GET_OFFSET(array);
-    U_ASSERT(indexR>=0); /* to ensure the index is not negative */
+    if (indexR < 0) {
+        return RES_BOGUS;
+    }
     switch(RES_GET_TYPE(array)) {
     case URES_ARRAY: {
         if (offset!=0) { /* empty if offset==0 */
@@ -807,65 +898,27 @@
     return RES_BOGUS;
 }
 
-U_CFUNC void
-ures_getAllArrayItems(const ResourceData *pResData, Resource array,
-                      icu::ResourceDataValue &value, icu::ResourceArraySink &sink,
-                      UErrorCode &errorCode) {
-    if(U_FAILURE(errorCode)) { return; }
-    const uint16_t *items16 = NULL;
-    const Resource *items32 = NULL;
-    uint32_t offset=RES_GET_OFFSET(array);
-    int32_t length = 0;
-    switch(RES_GET_TYPE(array)) {
-    case URES_ARRAY: {
-        if (offset!=0) { /* empty if offset==0 */
-            items32 = (const Resource *)pResData->pRoot+offset;
-            length = *items32++;
-        }
-        break;
+uint32_t icu::ResourceArray::internalGetResource(const ResourceData *pResData, int32_t i) const {
+    if (items16 != NULL) {
+        return makeResourceFrom16(pResData, items16[i]);
+    } else {
+        return items32[i];
     }
-    case URES_ARRAY16: {
-        items16 = pResData->p16BitUnits+offset;
-        length = *items16++;
-        break;
-    }
-    default:
-        errorCode = U_RESOURCE_TYPE_MISMATCH;
-        return;
-    }
+}
 
-    for (int32_t i = 0; i < length; ++i) {
-        Resource res;
-        if (items16 != NULL) {
-            res = makeResourceFrom16(pResData, items16[i]);
-        } else {
-            res = items32[i];
-        }
-        int32_t type = RES_GET_TYPE(res);
-        if (URES_IS_ARRAY(type)) {
-            int32_t numItems = getArrayLength(pResData, res);
-            icu::ResourceArraySink *subSink = sink.getOrCreateArraySink(i, numItems, errorCode);
-            if (subSink != NULL) {
-                ures_getAllArrayItems(pResData, res, value, *subSink, errorCode);
-            }
-        } else if (URES_IS_TABLE(type)) {
-            int32_t numItems = getTableLength(pResData, res);
-            icu::ResourceTableSink *subSink = sink.getOrCreateTableSink(i, numItems, errorCode);
-            if (subSink != NULL) {
-                ures_getAllTableItems(pResData, res, value, *subSink, errorCode);
-            }
-        /* TODO: settle on how to deal with aliases, port to Java
-        } else if (type == URES_ALIAS) {
-            // aliases not handled in resource enumeration
-            errorCode = U_UNSUPPORTED_ERROR;
-            return; */
-        } else {
-            value.setResource(res);
-            sink.put(i, value, errorCode);
-        }
-        if(U_FAILURE(errorCode)) { return; }
+UBool icu::ResourceArray::getValue(int32_t i, icu::ResourceValue &value) const {
+    if(0 <= i && i < length) {
+        icu::ResourceDataValue &rdValue = static_cast<icu::ResourceDataValue &>(value);
+        // Note: the ResourceTracer keeps a reference to the field of this
+        // ResourceArray. This is OK because the ResourceArray should remain
+        // alive for the duration that fields are being read from it
+        // (including nested fields).
+        rdValue.setResource(
+            internalGetResource(&rdValue.getData(), i),
+            ResourceTracer(fTraceInfo, i));
+        return TRUE;
     }
-    sink.leave(errorCode);
+    return FALSE;
 }
 
 U_CFUNC Resource
@@ -914,14 +967,14 @@
       if(t2 == RES_BOGUS) { 
         /* if we fail to get the resource by key, maybe we got an index */
         indexR = uprv_strtol(pathP, &closeIndex, 10);
-        if(*closeIndex == 0) {
+        if(indexR >= 0 && *closeIndex == 0 && (*pathP != '0' || closeIndex - pathP == 1)) {
           /* if we indeed have an index, try to get the item by index */
           t2 = res_getTableItemByIndex(pResData, t1, indexR, key);
-        }
+        } // else t2 is already RES_BOGUS
       }
     } else if(URES_IS_ARRAY(type)) {
       indexR = uprv_strtol(pathP, &closeIndex, 10);
-      if(*closeIndex == 0) {
+      if(indexR >= 0 && *closeIndex == 0) {
         t2 = res_getArrayItem(pResData, t1, indexR);
       } else {
         t2 = RES_BOGUS; /* have an array, but don't have a valid index */
@@ -976,7 +1029,7 @@
     int32_t keyIndex, sortIndex;
 } Row;
 
-static int32_t
+static int32_t U_CALLCONV
 ures_compareRows(const void *context, const void *left, const void *right) {
     const char *keyChars=(const char *)context;
     return (int32_t)uprv_strcmp(keyChars+((const Row *)left)->keyIndex,
@@ -1052,6 +1105,7 @@
     switch(RES_GET_TYPE(res)) {
     case URES_ALIAS:
         /* physically same value layout as string, fall through */
+        U_FALLTHROUGH;
     case URES_STRING:
         count=udata_readInt32(ds, (int32_t)*p);
         /* swap length */
diff --git a/src/third_party/icu/source/common/uresdata.h b/src/third_party/icu/source/common/uresdata.h
index 1afa77c..7c2152e 100644
--- a/src/third_party/icu/source/common/uresdata.h
+++ b/src/third_party/icu/source/common/uresdata.h
@@ -1,10 +1,12 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
-* Copyright (C) 1999-2015, International Business Machines
+* Copyright (C) 1999-2016, International Business Machines
 *                Corporation and others. All Rights Reserved.
 ******************************************************************************
 *   file name:  uresdata.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -67,14 +69,16 @@
 #define RES_GET_OFFSET(res) ((res)&0x0fffffff)
 #define RES_GET_POINTER(pRoot, res) ((pRoot)+RES_GET_OFFSET(res))
 
-/* get signed and unsigned integer values directly from the Resource handle */
+/* get signed and unsigned integer values directly from the Resource handle
+ * NOTE: For proper logging, please use the res_getInt() constexpr
+ */
 #if U_SIGNED_RIGHT_SHIFT_IS_ARITHMETIC
-#   define RES_GET_INT(res) (((int32_t)((res)<<4L))>>4L)
+#   define RES_GET_INT_NO_TRACE(res) (((int32_t)((res)<<4L))>>4L)
 #else
-#   define RES_GET_INT(res) (int32_t)(((res)&0x08000000) ? (res)|0xf0000000 : (res)&0x07ffffff)
+#   define RES_GET_INT_NO_TRACE(res) (int32_t)(((res)&0x08000000) ? (res)|0xf0000000 : (res)&0x07ffffff)
 #endif
 
-#define RES_GET_UINT(res) ((res)&0x0fffffff)
+#define RES_GET_UINT_NO_TRACE(res) ((res)&0x0fffffff)
 
 #define URES_IS_ARRAY(type) ((int32_t)(type)==URES_ARRAY || (int32_t)(type)==URES_ARRAY16)
 #define URES_IS_TABLE(type) ((int32_t)(type)==URES_TABLE || (int32_t)(type)==URES_TABLE16 || (int32_t)(type)==URES_TABLE32)
@@ -379,7 +383,7 @@
 /*
  * Structure for a single, memory-mapped ResourceBundle.
  */
-typedef struct {
+typedef struct ResourceData {
     UDataMemory *data;
     const int32_t *pRoot;
     const uint16_t *p16BitUnits;
@@ -398,7 +402,7 @@
 /*
  * Read a resource bundle from memory.
  */
-U_INTERNAL void U_EXPORT2
+U_CAPI void U_EXPORT2
 res_read(ResourceData *pResData,
          const UDataInfo *pInfo, const void *inBytes, int32_t length,
          UErrorCode *errorCode);
@@ -418,39 +422,43 @@
 U_CFUNC void
 res_unload(ResourceData *pResData);
 
-U_INTERNAL UResType U_EXPORT2
+U_CAPI UResType U_EXPORT2
 res_getPublicType(Resource res);
 
+///////////////////////////////////////////////////////////////////////////
+// To enable tracing, use the inline versions of the res_get* functions. //
+///////////////////////////////////////////////////////////////////////////
+
 /*
  * Return a pointer to a zero-terminated, const UChar* string
  * and set its length in *pLength.
  * Returns NULL if not found.
  */
-U_INTERNAL const UChar * U_EXPORT2
-res_getString(const ResourceData *pResData, Resource res, int32_t *pLength);
+U_CAPI const UChar * U_EXPORT2
+res_getStringNoTrace(const ResourceData *pResData, Resource res, int32_t *pLength);
 
-U_INTERNAL const UChar * U_EXPORT2
+U_CAPI const uint8_t * U_EXPORT2
+res_getBinaryNoTrace(const ResourceData *pResData, Resource res, int32_t *pLength);
+
+U_CAPI const int32_t * U_EXPORT2
+res_getIntVectorNoTrace(const ResourceData *pResData, Resource res, int32_t *pLength);
+
+U_CAPI const UChar * U_EXPORT2
 res_getAlias(const ResourceData *pResData, Resource res, int32_t *pLength);
 
-U_INTERNAL const uint8_t * U_EXPORT2
-res_getBinary(const ResourceData *pResData, Resource res, int32_t *pLength);
-
-U_INTERNAL const int32_t * U_EXPORT2
-res_getIntVector(const ResourceData *pResData, Resource res, int32_t *pLength);
-
-U_INTERNAL Resource U_EXPORT2
+U_CAPI Resource U_EXPORT2
 res_getResource(const ResourceData *pResData, const char *key);
 
-U_INTERNAL int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 res_countArrayItems(const ResourceData *pResData, Resource res);
 
-U_INTERNAL Resource U_EXPORT2
+U_CAPI Resource U_EXPORT2
 res_getArrayItem(const ResourceData *pResData, Resource array, int32_t indexS);
 
-U_INTERNAL Resource U_EXPORT2
+U_CAPI Resource U_EXPORT2
 res_getTableItemByIndex(const ResourceData *pResData, Resource table, int32_t indexS, const char ** key);
 
-U_INTERNAL Resource U_EXPORT2
+U_CAPI Resource U_EXPORT2
 res_getTableItemByKey(const ResourceData *pResData, Resource table, int32_t *indexS, const char* * key);
 
 /**
@@ -468,17 +476,55 @@
 #ifdef __cplusplus
 
 #include "resource.h"
+#include "restrace.h"
 
 U_NAMESPACE_BEGIN
 
+inline const UChar* res_getString(const ResourceTracer& traceInfo,
+        const ResourceData *pResData, Resource res, int32_t *pLength) {
+    traceInfo.trace("string");
+    return res_getStringNoTrace(pResData, res, pLength);
+}
+
+inline const uint8_t* res_getBinary(const ResourceTracer& traceInfo,
+        const ResourceData *pResData, Resource res, int32_t *pLength) {
+    traceInfo.trace("binary");
+    return res_getBinaryNoTrace(pResData, res, pLength);
+}
+
+inline const int32_t* res_getIntVector(const ResourceTracer& traceInfo,
+        const ResourceData *pResData, Resource res, int32_t *pLength) {
+    traceInfo.trace("intvector");
+    return res_getIntVectorNoTrace(pResData, res, pLength);
+}
+
+inline int32_t res_getInt(const ResourceTracer& traceInfo, Resource res) {
+    traceInfo.trace("int");
+    return RES_GET_INT_NO_TRACE(res);
+}
+
+inline uint32_t res_getUInt(const ResourceTracer& traceInfo, Resource res) {
+    traceInfo.trace("uint");
+    return RES_GET_UINT_NO_TRACE(res);
+}
+
 class ResourceDataValue : public ResourceValue {
 public:
-    ResourceDataValue() : pResData(NULL), res(URES_NONE) {}
+    ResourceDataValue() :
+        res(static_cast<Resource>(URES_NONE)),
+        fTraceInfo() {}
     virtual ~ResourceDataValue();
 
-    void setData(const ResourceData *data) { pResData = data; }
-    void setResource(Resource r) { res = r; }
+    void setData(const ResourceData *data) {
+        resData = *data;
+    }
 
+    void setResource(Resource r, ResourceTracer&& traceInfo) {
+        res = r;
+        fTraceInfo = traceInfo;
+    }
+
+    const ResourceData &getData() const { return resData; }
     virtual UResType getType() const;
     virtual const UChar *getString(int32_t &length, UErrorCode &errorCode) const;
     virtual const UChar *getAliasString(int32_t &length, UErrorCode &errorCode) const;
@@ -486,33 +532,25 @@
     virtual uint32_t getUInt(UErrorCode &errorCode) const;
     virtual const int32_t *getIntVector(int32_t &length, UErrorCode &errorCode) const;
     virtual const uint8_t *getBinary(int32_t &length, UErrorCode &errorCode) const;
-
-    const ResourceData *pResData;
+    virtual ResourceArray getArray(UErrorCode &errorCode) const;
+    virtual ResourceTable getTable(UErrorCode &errorCode) const;
+    virtual UBool isNoInheritanceMarker() const;
+    virtual int32_t getStringArray(UnicodeString *dest, int32_t capacity,
+                                   UErrorCode &errorCode) const;
+    virtual int32_t getStringArrayOrStringAsArray(UnicodeString *dest, int32_t capacity,
+                                                  UErrorCode &errorCode) const;
+    virtual UnicodeString getStringOrFirstOfArray(UErrorCode &errorCode) const;
 
 private:
+    // TODO(ICU-20769): If UResourceBundle.fResData becomes a pointer,
+    // then remove this value field again and just store a pResData pointer.
+    ResourceData resData;
     Resource res;
+    ResourceTracer fTraceInfo;
 };
 
 U_NAMESPACE_END
 
-/**
- * @param value will be set during enumeration; input contents is ignored
- * @param sink receives all table item key-value pairs
- */
-U_CFUNC void
-ures_getAllTableItems(const ResourceData *pResData, Resource table,
-                      icu::ResourceDataValue &value, icu::ResourceTableSink &sink,
-                      UErrorCode &errorCode);
-
-/**
- * @param value will be set during enumeration; input contents is ignored
- * @param sink receives all array item values
- */
-U_CFUNC void
-ures_getAllArrayItems(const ResourceData *pResData, Resource array,
-                      icu::ResourceDataValue &value, icu::ResourceArraySink &sink,
-                      UErrorCode &errorCode);
-
 #endif  /* __cplusplus */
 
 /**
diff --git a/src/third_party/icu/source/common/uresimp.h b/src/third_party/icu/source/common/uresimp.h
index 6b264db..69d8256 100644
--- a/src/third_party/icu/source/common/uresimp.h
+++ b/src/third_party/icu/source/common/uresimp.h
@@ -1,6 +1,8 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
-*   Copyright (C) 2000-2015, International Business Machines
+*   Copyright (C) 2000-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 **********************************************************************
 */
@@ -9,6 +11,7 @@
 #define URESIMP_H
 
 #include "unicode/ures.h"
+#include "unicode/utypes.h"
 
 #include "uresdata.h"
 
@@ -64,6 +67,9 @@
     char *fVersion;
     UResourceDataEntry *fTopLevelData; /* for getting the valid locale */
     char *fResPath; /* full path to the resource: "zh_TW/CollationElements/Sequence" */
+    // TODO(ICU-20769): Try to change the by-value fResData into a pointer,
+    // with the struct in only one place for each bundle.
+    // Also replace class ResourceDataValue.resData with a pResData pointer again.
     ResourceData fResData;
     char fResBuf[RES_BUFSIZE];
     int32_t fResPathLen;
@@ -80,6 +86,60 @@
 
 U_CAPI void U_EXPORT2 ures_initStackObject(UResourceBundle* resB);
 
+#ifdef __cplusplus
+
+U_NAMESPACE_BEGIN
+
+/**
+ * \class StackUResourceBundle
+ * "Smart pointer" like class, closes a UResourceBundle via ures_close().
+ *
+ * This code:
+ *
+ *   StackUResourceBundle bundle;
+ *   foo(bundle.getAlias());
+ *
+ * Is equivalent to this code:
+ *
+ *   UResourceBundle bundle;
+ *   ures_initStackObject(&bundle);
+ *   foo(&bundle);
+ *   ures_close(&bundle);
+ *
+ * @see LocalUResourceBundlePointer
+ * @internal
+ */
+class U_COMMON_API StackUResourceBundle {
+public:
+    // No heap allocation. Use only on the stack.
+    static void* U_EXPORT2 operator new(size_t) U_NOEXCEPT = delete;
+    static void* U_EXPORT2 operator new[](size_t) U_NOEXCEPT = delete;
+#if U_HAVE_PLACEMENT_NEW
+    static void* U_EXPORT2 operator new(size_t, void*) U_NOEXCEPT = delete;
+#endif
+
+    StackUResourceBundle();
+    ~StackUResourceBundle();
+
+    UResourceBundle* getAlias() { return &bundle; }
+
+    UResourceBundle& ref() { return bundle; }
+    const UResourceBundle& ref() const { return bundle; }
+
+    StackUResourceBundle(const StackUResourceBundle&) = delete;
+    StackUResourceBundle& operator=(const StackUResourceBundle&) = delete;
+
+    StackUResourceBundle(StackUResourceBundle&&) = delete;
+    StackUResourceBundle& operator=(StackUResourceBundle&&) = delete;
+
+private:
+    UResourceBundle bundle;
+};
+
+U_NAMESPACE_END
+
+#endif  /* __cplusplus */
+
 /**
  * Opens a resource bundle for the locale;
  * if there is not even a base language bundle, then loads the root bundle;
@@ -97,7 +157,7 @@
 U_CFUNC const char* ures_getPath(const UResourceBundle* resB);
 /**
  * If anything was in the RB cache, dump it to the screen.
- * @return TRUE if there was anything into the cache
+ * @return true if there was anything into the cache
  */
 U_CAPI UBool U_EXPORT2 ures_dumpCacheContents(void);
 #endif
@@ -158,7 +218,7 @@
  * @param isAvailable If non-null, pointer to fillin parameter that indicates whether the 
  * requested locale was available. The locale is defined as 'available' if it physically 
  * exists within the specified tree.
- * @param omitDefault if TRUE, omit keyword and value if default. 'de_DE\@collation=standard' -> 'de_DE'
+ * @param omitDefault if true, omit keyword and value if default. 'de_DE\@collation=standard' -> 'de_DE'
  * @param status error code
  * @return  the actual buffer size needed for the full locale.  If it's greater 
  * than resultCapacity, the returned full name will be truncated and an error code will be returned.
@@ -225,12 +285,13 @@
 #ifdef __cplusplus
 
 U_CAPI void U_EXPORT2
-ures_getAllArrayItemsWithFallback(const UResourceBundle *bundle, const char *path,
-                                  icu::ResourceArraySink &sink, UErrorCode &errorCode);
+ures_getValueWithFallback(const UResourceBundle *bundle, const char *path,
+                          UResourceBundle *tempFillIn,
+                          icu::ResourceDataValue &value, UErrorCode &errorCode);
 
 U_CAPI void U_EXPORT2
-ures_getAllTableItemsWithFallback(const UResourceBundle *bundle, const char *path,
-                                  icu::ResourceTableSink &sink, UErrorCode &errorCode);
+ures_getAllItemsWithFallback(const UResourceBundle *bundle, const char *path,
+                             icu::ResourceSink &sink, UErrorCode &errorCode);
 
 #endif  /* __cplusplus */
 
@@ -277,4 +338,27 @@
 ures_getLocaleInternal(const UResourceBundle* resourceBundle, 
                UErrorCode* status);
 
+/**
+ * Same as ures_openDirect() but uses the fill-in parameter instead of allocating a new bundle.
+ * 
+ * @param r The existing UResourceBundle to fill in. If NULL then status will be
+ *          set to U_ILLEGAL_ARGUMENT_ERROR.
+ * @param packageName   The packageName and locale together point to an ICU udata object,
+ *                      as defined by <code> udata_open( packageName, "res", locale, err) </code>
+ *                      or equivalent.  Typically, packageName will refer to a (.dat) file, or to
+ *                      a package registered with udata_setAppData(). Using a full file or directory
+ *                      pathname for packageName is deprecated. If NULL, ICU data will be used.
+ * @param locale  specifies the locale for which we want to open the resource
+ *                if NULL, the default locale will be used. If strlen(locale) == 0
+ *                root locale will be used.
+ * @param status The error code.
+ * @see ures_openDirect
+ * @internal
+ */
+U_CAPI void U_EXPORT2
+ures_openDirectFillIn(UResourceBundle *r,
+                      const char *packageName,
+                      const char *locale,
+                      UErrorCode *status);
+
 #endif /*URESIMP_H*/
diff --git a/src/third_party/icu/source/common/ureslocs.h b/src/third_party/icu/source/common/ureslocs.h
index e89ddb9..f7c3344 100644
--- a/src/third_party/icu/source/common/ureslocs.h
+++ b/src/third_party/icu/source/common/ureslocs.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
 *   Copyright (C) 2009-2014 International Business Machines
diff --git a/src/third_party/icu/source/common/uresource.cpp b/src/third_party/icu/source/common/uresource.cpp
deleted file mode 100644
index e69de29..0000000
--- a/src/third_party/icu/source/common/uresource.cpp
+++ /dev/null
diff --git a/src/third_party/icu/source/common/uresource.h b/src/third_party/icu/source/common/uresource.h
deleted file mode 100644
index e69de29..0000000
--- a/src/third_party/icu/source/common/uresource.h
+++ /dev/null
diff --git a/src/third_party/icu/source/common/usc_impl.c b/src/third_party/icu/source/common/usc_impl.cpp
similarity index 96%
rename from src/third_party/icu/source/common/usc_impl.c
rename to src/third_party/icu/source/common/usc_impl.cpp
index e30c7f5..111029b 100644
--- a/src/third_party/icu/source/common/usc_impl.c
+++ b/src/third_party/icu/source/common/usc_impl.cpp
@@ -1,6 +1,8 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
-*   Copyright (C) 1999-2014, International Business Machines
+*   Copyright (C) 1999-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 **********************************************************************
 *
@@ -17,8 +19,6 @@
 #include "usc_impl.h"
 #include "cmemory.h"
 
-#define ARRAY_SIZE(array) (sizeof array  / sizeof array[0])
-
 #define PAREN_STACK_DEPTH 32
 
 #define MOD(sp) ((sp) % PAREN_STACK_DEPTH)
@@ -156,7 +156,7 @@
 static int32_t
 getPairIndex(UChar32 ch)
 {
-    int32_t pairedCharCount = ARRAY_SIZE(pairedChars);
+    int32_t pairedCharCount = UPRV_LENGTHOF(pairedChars);
     int32_t pairedCharPower = 1 << highBit(pairedCharCount);
     int32_t pairedCharExtra = pairedCharCount - pairedCharPower;
 
@@ -197,7 +197,7 @@
         return NULL;
     }
 
-    result = uprv_malloc(sizeof (UScriptRun));
+    result = (UScriptRun *)uprv_malloc(sizeof (UScriptRun));
 
     if (result == NULL) {
         *pErrorCode = U_MEMORY_ALLOCATION_ERROR;
diff --git a/src/third_party/icu/source/common/usc_impl.h b/src/third_party/icu/source/common/usc_impl.h
index 2e972b0..4489964 100644
--- a/src/third_party/icu/source/common/usc_impl.h
+++ b/src/third_party/icu/source/common/usc_impl.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
 *   Copyright (C) 1999-2011, International Business Machines
diff --git a/src/third_party/icu/source/common/uscript.c b/src/third_party/icu/source/common/uscript.cpp
similarity index 90%
rename from src/third_party/icu/source/common/uscript.c
rename to src/third_party/icu/source/common/uscript.cpp
index 3700099..f8bd7e7 100644
--- a/src/third_party/icu/source/common/uscript.c
+++ b/src/third_party/icu/source/common/uscript.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
 *   Copyright (C) 1997-2014, International Business Machines
@@ -16,8 +18,11 @@
 #include "unicode/uchar.h"
 #include "unicode/uscript.h"
 #include "unicode/uloc.h"
+#include "bytesinkutil.h"
+#include "charstr.h"
 #include "cmemory.h"
 #include "cstring.h"
+#include "ulocimp.h"
 
 static const UScriptCode JAPANESE[3] = { USCRIPT_KATAKANA, USCRIPT_HIRAGANA, USCRIPT_HAN };
 static const UScriptCode KOREAN[2] = { USCRIPT_HANGUL, USCRIPT_HAN };
@@ -53,8 +58,8 @@
 getCodesFromLocale(const char *locale,
                    UScriptCode *scripts, int32_t capacity, UErrorCode *err) {
     UErrorCode internalErrorCode = U_ZERO_ERROR;
-    char lang[8];
-    char script[8];
+    char lang[8] = {0};
+    char script[8] = {0};
     int32_t scriptLength;
     if(U_FAILURE(*err)) { return 0; }
     // Multi-script languages, equivalent to the LocaleScript data
@@ -96,7 +101,6 @@
                 int32_t capacity,
                 UErrorCode* err){
     UBool triedCode;
-    char likely[ULOC_FULLNAME_CAPACITY];
     UErrorCode internalErrorCode;
     int32_t length;
 
@@ -123,10 +127,13 @@
     if(U_FAILURE(*err) || length != 0) {
         return length;
     }
-    (void)uloc_addLikelySubtags(nameOrAbbrOrLocale,
-                                likely, UPRV_LENGTHOF(likely), &internalErrorCode);
+    icu::CharString likely;
+    {
+        icu::CharStringByteSink sink(&likely);
+        ulocimp_addLikelySubtags(nameOrAbbrOrLocale, sink, &internalErrorCode);
+    }
     if(U_SUCCESS(internalErrorCode) && internalErrorCode != U_STRING_NOT_TERMINATED_WARNING) {
-        length = getCodesFromLocale(likely, fillIn, capacity, err);
+        length = getCodesFromLocale(likely.data(), fillIn, capacity, err);
         if(U_FAILURE(*err) || length != 0) {
             return length;
         }
diff --git a/src/third_party/icu/source/common/uscript_props.cpp b/src/third_party/icu/source/common/uscript_props.cpp
index bb1eb04..e951655 100644
--- a/src/third_party/icu/source/common/uscript_props.cpp
+++ b/src/third_party/icu/source/common/uscript_props.cpp
@@ -1,10 +1,12 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
-*   Copyright (C) 2013-2015, International Business Machines
+*   Copyright (C) 2013-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *******************************************************************************
 *   file name:  uscript_props.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -12,7 +14,9 @@
 *   created by: Markus W. Scherer
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/utypes.h"
 #include "unicode/unistr.h"
 #include "unicode/uscript.h"
@@ -32,7 +36,7 @@
 const int32_t UNKNOWN = 1 << 21;
 const int32_t EXCLUSION = 2 << 21;
 const int32_t LIMITED_USE = 3 << 21;
-const int32_t ASPIRATIONAL = 4 << 21;
+// st int32_t ASPIRATIONAL = 4 << 21; -- not used any more since Unicode 10
 const int32_t RECOMMENDED = 5 << 21;
 
 // Bits 31..24: Single-bit flags
@@ -70,10 +74,10 @@
     0x0EA5 | RECOMMENDED | LB_LETTERS,  // Laoo
     0x004C | RECOMMENDED | CASED,  // Latn
     0x0D15 | RECOMMENDED,  // Mlym
-    0x1826 | ASPIRATIONAL,  // Mong
+    0x1826 | EXCLUSION,  // Mong
     0x1000 | RECOMMENDED | LB_LETTERS,  // Mymr
     0x168F | EXCLUSION,  // Ogam
-    0x10308 | EXCLUSION,  // Ital
+    0x10300 | EXCLUSION,  // Ital
     0x0B15 | RECOMMENDED,  // Orya
     0x16A0 | EXCLUSION,  // Runr
     0x0D85 | RECOMMENDED,  // Sinh
@@ -83,8 +87,8 @@
     0x078C | RECOMMENDED | RTL,  // Thaa
     0x0E17 | RECOMMENDED | LB_LETTERS,  // Thai
     0x0F40 | RECOMMENDED,  // Tibt
-    0x14C0 | ASPIRATIONAL,  // Cans
-    0xA288 | ASPIRATIONAL | LB_LETTERS,  // Yiii
+    0x14C0 | LIMITED_USE,  // Cans
+    0xA288 | LIMITED_USE | LB_LETTERS,  // Yiii
     0x1703 | EXCLUSION,  // Tglg
     0x1723 | EXCLUSION,  // Hano
     0x1743 | EXCLUSION,  // Buhd
@@ -103,7 +107,7 @@
     0x10A00 | EXCLUSION | RTL,  // Khar
     0xA800 | LIMITED_USE,  // Sylo
     0x1980 | LIMITED_USE | LB_LETTERS,  // Talu
-    0x2D5E | ASPIRATIONAL,  // Tfng
+    0x2D30 | LIMITED_USE,  // Tfng
     0x103A0 | EXCLUSION,  // Xpeo
     0x1B05 | LIMITED_USE,  // Bali
     0x1BC0 | LIMITED_USE,  // Batk
@@ -130,12 +134,12 @@
     0x0840 | LIMITED_USE | RTL,  // Mand
     0,
     0x10980 | EXCLUSION | RTL,  // Mero
-    0x07D8 | LIMITED_USE | RTL,  // Nkoo
+    0x07CA | LIMITED_USE | RTL,  // Nkoo
     0x10C00 | EXCLUSION | RTL,  // Orkh
     0x1036B | EXCLUSION,  // Perm
     0xA840 | EXCLUSION,  // Phag
     0x10900 | EXCLUSION | RTL,  // Phnx
-    0x16F00 | ASPIRATIONAL,  // Plrd
+    0x16F00 | LIMITED_USE,  // Plrd
     0,
     0,
     0,
@@ -147,7 +151,7 @@
     0x12000 | EXCLUSION,  // Xsux
     0,
     0xFDD0 | UNKNOWN,  // Zzzz
-    0x102B7 | EXCLUSION,  // Cari
+    0x102A0 | EXCLUSION,  // Cari
     0x304B | RECOMMENDED | LB_LETTERS,  // Jpan
     0x1A20 | LIMITED_USE | LB_LETTERS,  // Lana
     0x10280 | EXCLUSION,  // Lyci
@@ -164,7 +168,7 @@
     0x11103 | LIMITED_USE,  // Cakm
     0xAC00 | RECOMMENDED,  // Kore
     0x11083 | EXCLUSION,  // Kthi
-    0x10AC1 | EXCLUSION | RTL,  // Mani
+    0x10AD8 | EXCLUSION | RTL,  // Mani
     0x10B60 | EXCLUSION | RTL,  // Phli
     0x10B8F | EXCLUSION | RTL,  // Phlp
     0,
@@ -174,7 +178,7 @@
     0,
     0,
     0xA6A0 | LIMITED_USE,  // Bamu
-    0xA4E8 | LIMITED_USE,  // Lisu
+    0xA4D0 | LIMITED_USE,  // Lisu
     0,
     0x10A60 | EXCLUSION | RTL,  // Sarb
     0x16AE6 | EXCLUSION,  // Bass
@@ -193,11 +197,11 @@
     0,
     0,
     0x16A4F | EXCLUSION,  // Mroo
-    0,
+    0x1B1C4 | EXCLUSION | LB_LETTERS,  // Nshu
     0x11183 | EXCLUSION,  // Shrd
     0x110D0 | EXCLUSION,  // Sora
     0x11680 | EXCLUSION,  // Takr
-    0,
+    0x18229 | EXCLUSION | LB_LETTERS,  // Tang
     0,
     0x14400 | EXCLUSION,  // Hluw
     0x11208 | EXCLUSION,  // Khoj
@@ -210,6 +214,32 @@
     0x1128F | EXCLUSION,  // Mult
     0x11AC0 | EXCLUSION,  // Pauc
     0x1158E | EXCLUSION,  // Sidd
+    0x1E909 | LIMITED_USE | RTL | CASED,  // Adlm
+    0x11C0E | EXCLUSION,  // Bhks
+    0x11C72 | EXCLUSION,  // Marc
+    0x11412 | LIMITED_USE,  // Newa
+    0x104B5 | LIMITED_USE | CASED,  // Osge
+    0x5B57 | RECOMMENDED | LB_LETTERS,  // Hanb
+    0x1112 | RECOMMENDED,  // Jamo
+    0,
+    0x11D10 | EXCLUSION,  // Gonm
+    0x11A5C | EXCLUSION,  // Soyo
+    0x11A0B | EXCLUSION,  // Zanb
+    0x1180B | EXCLUSION,  // Dogr
+    0x11D71 | LIMITED_USE,  // Gong
+    0x11EE5 | EXCLUSION,  // Maka
+    0x16E40 | EXCLUSION | CASED,  // Medf
+    0x10D12 | LIMITED_USE | RTL,  // Rohg
+    0x10F42 | EXCLUSION | RTL,  // Sogd
+    0x10F19 | EXCLUSION | RTL,  // Sogo
+    0x10FF1 | EXCLUSION | RTL,  // Elym
+    0x1E108 | LIMITED_USE,  // Hmnp
+    0x119CE | EXCLUSION,  // Nand
+    0x1E2E1 | LIMITED_USE,  // Wcho
+    0x10FBF | EXCLUSION | RTL,  // Chrs
+    0x1190C | EXCLUSION,  // Diak
+    0x18C65 | EXCLUSION | LB_LETTERS,  // Kits
+    0x10E88 | EXCLUSION | RTL,  // Yezi
     // End copy-paste from parsescriptmetadata.py
 };
 
diff --git a/src/third_party/icu/source/common/uset.cpp b/src/third_party/icu/source/common/uset.cpp
index a59c7d0..188ecec 100644
--- a/src/third_party/icu/source/common/uset.cpp
+++ b/src/third_party/icu/source/common/uset.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  uset.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -18,7 +20,9 @@
 *   instantiating a new USet.
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/utypes.h"
 #include "unicode/uobject.h"
 #include "unicode/uset.h"
@@ -248,7 +252,7 @@
 public:
     /* Try to have the compiler inline these*/
     inline static int32_t getStringCount(const UnicodeSet& set) {
-        return set.getStringCount();
+        return set.stringsSize();
     }
     inline static const UnicodeString* getString(const UnicodeSet& set,
                                                  int32_t i) {
diff --git a/src/third_party/icu/source/common/uset_imp.h b/src/third_party/icu/source/common/uset_imp.h
index 07a7381..7233b93 100644
--- a/src/third_party/icu/source/common/uset_imp.h
+++ b/src/third_party/icu/source/common/uset_imp.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  uset_imp.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
diff --git a/src/third_party/icu/source/common/uset_props.cpp b/src/third_party/icu/source/common/uset_props.cpp
index bf2ee37..ff4def9 100644
--- a/src/third_party/icu/source/common/uset_props.cpp
+++ b/src/third_party/icu/source/common/uset_props.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  uset_props.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -17,7 +19,9 @@
 *   uniset_props.cpp, split off for modularization.
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/utypes.h"
 #include "unicode/uobject.h"
 #include "unicode/uset.h"
diff --git a/src/third_party/icu/source/common/usetiter.cpp b/src/third_party/icu/source/common/usetiter.cpp
index da669dc..adaba49 100644
--- a/src/third_party/icu/source/common/usetiter.cpp
+++ b/src/third_party/icu/source/common/usetiter.cpp
@@ -1,10 +1,14 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
 * Copyright (c) 2002-2006, International Business Machines
 * Corporation and others.  All Rights Reserved.
 **********************************************************************
 */
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/usetiter.h"
 #include "unicode/uniset.h"
 #include "unicode/unistr.h"
@@ -115,7 +119,7 @@
         stringCount = 0;
     } else {
         endRange = set->getRangeCount() - 1;
-        stringCount = set->strings->size();
+        stringCount = set->stringsSize();
     }
     range = 0;
     endElement = -1;
diff --git a/src/third_party/icu/source/common/ushape.cpp b/src/third_party/icu/source/common/ushape.cpp
index b1d5c71..7115f1a 100644
--- a/src/third_party/icu/source/common/ushape.cpp
+++ b/src/third_party/icu/source/common/ushape.cpp
@@ -1,12 +1,14 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
  ******************************************************************************
  *
- *   Copyright (C) 2000-2014, International Business Machines
+ *   Copyright (C) 2000-2016, International Business Machines
  *   Corporation and others.  All Rights Reserved.
  *
  ******************************************************************************
  *   file name:  ushape.cpp
- *   encoding:   US-ASCII
+ *   encoding:   UTF-8
  *   tab size:   8 (not used)
  *   indentation:4
  *
@@ -16,8 +18,10 @@
  *   Arabic letter shaping implemented by Ayman Roshdy
  */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/utypes.h"
 #include "unicode/uchar.h"
 #include "unicode/ustring.h"
@@ -342,18 +346,16 @@
 _shapeToArabicDigitsWithContext(UChar *s, int32_t length,
                                 UChar digitBase,
                                 UBool isLogical, UBool lastStrongWasAL) {
-    const UBiDiProps *bdp;
     int32_t i;
     UChar c;
 
-    bdp=ubidi_getSingleton();
     digitBase-=0x30;
 
     /* the iteration direction depends on the type of input */
     if(isLogical) {
         for(i=0; i<length; ++i) {
             c=s[i];
-            switch(ubidi_getClass(bdp, c)) {
+            switch(ubidi_getClass(c)) {
             case U_LEFT_TO_RIGHT: /* L */
             case U_RIGHT_TO_LEFT: /* R */
                 lastStrongWasAL=FALSE;
@@ -373,7 +375,7 @@
     } else {
         for(i=length; i>0; /* pre-decrement in the body */) {
             c=s[--i];
-            switch(ubidi_getClass(bdp, c)) {
+            switch(ubidi_getClass(c)) {
             case U_LEFT_TO_RIGHT: /* L */
             case U_RIGHT_TO_LEFT: /* R */
                 lastStrongWasAL=FALSE;
@@ -779,7 +781,7 @@
             count--;
         }
 
-        uprv_memcpy(dest, tempbuffer, sourceLength*U_SIZEOF_UCHAR);
+        u_memcpy(dest, tempbuffer, sourceLength);
         destSize = u_strlen(dest);
     }
 
@@ -837,7 +839,7 @@
                 tempbuffer[i] = SPACE_CHAR;
         }
 
-        uprv_memcpy(dest, tempbuffer, sourceLength*U_SIZEOF_UCHAR);
+        u_memcpy(dest, tempbuffer, sourceLength);
         destSize = sourceLength;
     }
 
@@ -879,7 +881,7 @@
             count--;
         }
 
-        uprv_memcpy(dest,tempbuffer, sourceLength*U_SIZEOF_UCHAR);
+        u_memcpy(dest, tempbuffer, sourceLength);
         destSize = sourceLength;
     }
 
@@ -930,7 +932,7 @@
                 tempbuffer[j] = LAM_CHAR;
                 /* to ensure the array index is within the range */
                 U_ASSERT(dest[i] >= 0xFEF5u
-                    && dest[i]-0xFEF5u < sizeof(convertLamAlef)/sizeof(convertLamAlef[0]));
+                    && dest[i]-0xFEF5u < UPRV_LENGTHOF(convertLamAlef));
                 tempbuffer[j-1] = convertLamAlef[ dest[i] - 0xFEF5 ];
                 j--;
                 countl--;
@@ -943,7 +945,7 @@
             i--;
             j--;
         }
-        uprv_memcpy(dest, tempbuffer, sourceLength*U_SIZEOF_UCHAR);
+        u_memcpy(dest, tempbuffer, sourceLength);
 
         uprv_free(tempbuffer);
 
@@ -1004,14 +1006,14 @@
     }
 
     if(countr > 0) {
-        uprv_memmove(tempbuffer, tempbuffer+countr, sourceLength*U_SIZEOF_UCHAR);
+        u_memmove(tempbuffer, tempbuffer+countr, sourceLength);
         if(u_strlen(tempbuffer) < sourceLength) {
             for(i=sourceLength-1;i>=sourceLength-countr;i--) {
                 tempbuffer[i] = SPACE_CHAR;
             }
         }
     }
-    uprv_memcpy(dest, tempbuffer, sourceLength*U_SIZEOF_UCHAR);
+    u_memcpy(dest, tempbuffer, sourceLength);
 
     uprv_free(tempbuffer);
 
@@ -1179,7 +1181,7 @@
                 j++;
             }
 
-            uprv_memcpy(dest, tempbuffer, destSize*U_SIZEOF_UCHAR);
+            u_memcpy(dest, tempbuffer, destSize);
         }
     }
 
@@ -1324,8 +1326,8 @@
                     } else {
                         /* to ensure the array index is within the range */
                         U_ASSERT(dest[i] >= 0x064Bu
-                            && dest[i]-0x064Bu < sizeof(IrrelevantPos)/sizeof(IrrelevantPos[0]));
-                        dest[i] =  0xFE70 + IrrelevantPos[(dest[i] - 0x064B)] + Shape;
+                            && dest[i]-0x064Bu < UPRV_LENGTHOF(IrrelevantPos));
+                        dest[i] =  0xFE70 + IrrelevantPos[(dest[i] - 0x064B)] + static_cast<UChar>(Shape);
                     }
                 }else if ((currLink & APRESENT) > 0) {
                     dest[i] = (UChar)(0xFB50 + (currLink >> 8) + Shape);
@@ -1573,7 +1575,7 @@
                 return 0;
             }
         }
-        uprv_memcpy(tempbuffer, source, sourceLength*U_SIZEOF_UCHAR);
+        u_memcpy(tempbuffer, source, sourceLength);
         if (tempsource != NULL){
             uprv_free(tempsource);
         }
@@ -1639,7 +1641,7 @@
             countSpaces(tempbuffer,destLength,options,&spacesCountl,&spacesCountr);
             invertBuffer(tempbuffer,destLength,options,spacesCountl,spacesCountr);
         }
-        uprv_memcpy(dest, tempbuffer, uprv_min(destLength, destCapacity)*U_SIZEOF_UCHAR);
+        u_memcpy(dest, tempbuffer, uprv_min(destLength, destCapacity));
 
         if(tempbuffer!=buffer) {
             uprv_free(tempbuffer);
@@ -1661,7 +1663,7 @@
             *pErrorCode=U_BUFFER_OVERFLOW_ERROR;
             return sourceLength;
         }
-        uprv_memcpy(dest, source, sourceLength*U_SIZEOF_UCHAR);
+        u_memcpy(dest, source, sourceLength);
         destLength=sourceLength;
     }
 
diff --git a/src/third_party/icu/source/common/usprep.cpp b/src/third_party/icu/source/common/usprep.cpp
index 1cfbb21..730d294 100644
--- a/src/third_party/icu/source/common/usprep.cpp
+++ b/src/third_party/icu/source/common/usprep.cpp
@@ -1,12 +1,14 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
  *******************************************************************************
  *
- *   Copyright (C) 2003-2014, International Business Machines
+ *   Copyright (C) 2003-2016, International Business Machines
  *   Corporation and others.  All Rights Reserved.
  *
  *******************************************************************************
  *   file name:  usprep.cpp
- *   encoding:   US-ASCII
+ *   encoding:   UTF-8
  *   tab size:   8 (not used)
  *   indentation:4
  *
@@ -18,7 +20,9 @@
 
 #if !UCONFIG_NO_IDNA
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/usprep.h"
 
 #include "unicode/normalizer2.h"
@@ -44,10 +48,9 @@
 Static cache for already opened StringPrep profiles
 */
 static UHashtable *SHARED_DATA_HASHTABLE = NULL;
-static icu::UInitOnce gSharedDataInitOnce;
+static icu::UInitOnce gSharedDataInitOnce = U_INITONCE_INITIALIZER;
 
-static UMutex usprepMutex = U_MUTEX_INITIALIZER;
-
+static UMutex usprepMutex;
 /* format version of spp file */
 //static uint8_t formatVersion[4]={ 0, 0, 0, 0 };
 
@@ -111,7 +114,9 @@
     UHashTok namekey, pathkey;
     namekey.pointer = b->name;
     pathkey.pointer = b->path;
-    return uhash_hashChars(namekey)+37*uhash_hashChars(pathkey);
+    uint32_t unsignedHash = static_cast<uint32_t>(uhash_hashChars(namekey)) +
+            37u * static_cast<uint32_t>(uhash_hashChars(pathkey));
+    return static_cast<int32_t>(unsignedHash);
 }
 
 /* compares two entries */
@@ -346,17 +351,13 @@
         newProfile->doNFKC = (UBool)((newProfile->indexes[_SPREP_OPTIONS] & _SPREP_NORMALIZATION_ON) > 0);
         newProfile->checkBiDi = (UBool)((newProfile->indexes[_SPREP_OPTIONS] & _SPREP_CHECK_BIDI_ON) > 0);
 
-        if(newProfile->checkBiDi) {
-            newProfile->bdp = ubidi_getSingleton();
-        }
-
         LocalMemory<UStringPrepKey> key;
         LocalMemory<char> keyName;
         LocalMemory<char> keyPath;
         if( key.allocateInsteadAndReset() == NULL ||
-            keyName.allocateInsteadAndCopy(uprv_strlen(name)+1) == NULL ||
+            keyName.allocateInsteadAndCopy(static_cast<int32_t>(uprv_strlen(name)+1)) == NULL ||
             (path != NULL &&
-             keyPath.allocateInsteadAndCopy(uprv_strlen(path)+1) == NULL)
+             keyPath.allocateInsteadAndCopy(static_cast<int32_t>(uprv_strlen(path)+1)) == NULL)
          ) {
             *status = U_MEMORY_ALLOCATION_ERROR;
             usprep_unload(newProfile.getAlias());
@@ -410,7 +411,7 @@
         return NULL;
     }
     int32_t index = (int32_t)type;
-    if (index < 0 || index >= (int32_t)(sizeof(PROFILE_NAMES)/sizeof(PROFILE_NAMES[0]))) {
+    if (index < 0 || index >= UPRV_LENGTHOF(PROFILE_NAMES)) {
         *status = U_ILLEGAL_ARGUMENT_ERROR;
         return NULL;
     }
@@ -729,12 +730,12 @@
             ((result < _SPREP_TYPE_THRESHOLD) && (result & 0x01) /* first bit says it the code point is prohibited*/)
            ){
             *status = U_STRINGPREP_PROHIBITED_ERROR;
-            uprv_syntaxError(b1, b2Index-U16_LENGTH(ch), b2Len, parseError);
+            uprv_syntaxError(b2, b2Index-U16_LENGTH(ch), b2Len, parseError);
             return 0;
         }
 
         if(profile->checkBiDi) {
-            direction = ubidi_getClass(profile->bdp, ch);
+            direction = ubidi_getClass(ch);
             if(firstCharDir == U_CHAR_DIRECTION_COUNT){
                 firstCharDir = direction;
             }
diff --git a/src/third_party/icu/source/common/ustack.cpp b/src/third_party/icu/source/common/ustack.cpp
index 8837b4b..03e8027 100644
--- a/src/third_party/icu/source/common/ustack.cpp
+++ b/src/third_party/icu/source/common/ustack.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
 *   Copyright (C) 2003-2011, International Business Machines
@@ -5,7 +7,9 @@
 **********************************************************************
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "uvector.h"
 
 U_NAMESPACE_BEGIN
diff --git a/src/third_party/icu/source/common/ustr_cnv.cpp b/src/third_party/icu/source/common/ustr_cnv.cpp
index b33c6a5..9a25a99 100644
--- a/src/third_party/icu/source/common/ustr_cnv.cpp
+++ b/src/third_party/icu/source/common/ustr_cnv.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  ustr_cnv.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -26,6 +28,7 @@
 #include "cmemory.h"
 #include "umutex.h"
 #include "ustr_cnv.h"
+#include "ucnv_bld.h"
 
 /* mutexed access to a shared default converter ----------------------------- */
 
@@ -37,14 +40,14 @@
     UConverter *converter = NULL;
     
     if (gDefaultConverter != NULL) {
-        umtx_lock(NULL);
+        icu::umtx_lock(NULL);
         
         /* need to check to make sure it wasn't taken out from under us */
         if (gDefaultConverter != NULL) {
             converter = gDefaultConverter;
             gDefaultConverter = NULL;
         }
-        umtx_unlock(NULL);
+        icu::umtx_unlock(NULL);
     }
 
     /* if the cache was empty, create a converter */
@@ -66,13 +69,13 @@
         if (converter != NULL) {
             ucnv_reset(converter);
         }
-        umtx_lock(NULL);
-
+        ucnv_enableCleanup();
+        icu::umtx_lock(NULL);
         if(gDefaultConverter == NULL) {
             gDefaultConverter = converter;
             converter = NULL;
         }
-        umtx_unlock(NULL);
+        icu::umtx_unlock(NULL);
     }
 
     if(converter != NULL) {
@@ -86,14 +89,14 @@
     UConverter *converter = NULL;
     
     if (gDefaultConverter != NULL) {
-        umtx_lock(NULL);
+        icu::umtx_lock(NULL);
         
         /* need to check to make sure it wasn't taken out from under us */
         if (gDefaultConverter != NULL) {
             converter = gDefaultConverter;
             gDefaultConverter = NULL;
         }
-        umtx_unlock(NULL);
+        icu::umtx_unlock(NULL);
     }
 
     /* if the cache was populated, flush it */
diff --git a/src/third_party/icu/source/common/ustr_cnv.h b/src/third_party/icu/source/common/ustr_cnv.h
index abcd3d8..861e3eb 100644
--- a/src/third_party/icu/source/common/ustr_cnv.h
+++ b/src/third_party/icu/source/common/ustr_cnv.h
@@ -1,10 +1,12 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*  
 **********************************************************************
 *   Copyright (C) 1999-2010, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 **********************************************************************
 *   file name:  ustr_cnv.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
diff --git a/src/third_party/icu/source/common/ustr_imp.h b/src/third_party/icu/source/common/ustr_imp.h
index 051292a..3c4b9cc 100644
--- a/src/third_party/icu/source/common/ustr_imp.h
+++ b/src/third_party/icu/source/common/ustr_imp.h
@@ -1,10 +1,12 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*  
 **********************************************************************
 *   Copyright (C) 1999-2015, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 **********************************************************************
 *   file name:  ustr_imp.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -16,23 +18,7 @@
 #define __USTR_IMP_H__
 
 #include "unicode/utypes.h"
-#include "unicode/uiter.h"
-#include "ucase.h"
-
-/** Simple declaration to avoid including unicode/ubrk.h. */
-#ifndef UBRK_TYPEDEF_UBREAK_ITERATOR
-#   define UBRK_TYPEDEF_UBREAK_ITERATOR
-    typedef struct UBreakIterator UBreakIterator;
-#endif
-
-#ifndef U_COMPARE_IGNORE_CASE
-/* see also unorm.h */
-/**
- * Option bit for unorm_compare:
- * Perform case-insensitive comparison.
- */
-#define U_COMPARE_IGNORE_CASE       0x10000
-#endif
+#include "unicode/utf8.h"
 
 /**
  * Internal option for unorm_cmpEquivFold() for strncmp style.
@@ -43,7 +29,7 @@
 /**
  * Compare two strings in code point order or code unit order.
  * Works in strcmp style (both lengths -1),
- * strncmp style (lengths equal and >=0, flag TRUE),
+ * strncmp style (lengths equal and >=0, flag true),
  * and memcmp/UnicodeString style (at least one length >=0).
  */
 U_CFUNC int32_t U_EXPORT2
@@ -51,211 +37,6 @@
                 const UChar *s2, int32_t length2,
                 UBool strncmpStyle, UBool codePointOrder);
 
-/**
- * Internal API, used by u_strcasecmp() etc.
- * Compare strings case-insensitively,
- * in code point order or code unit order.
- */
-U_CFUNC int32_t
-u_strcmpFold(const UChar *s1, int32_t length1,
-             const UChar *s2, int32_t length2,
-             uint32_t options,
-             UErrorCode *pErrorCode);
-
-/**
- * Interanl API, used for detecting length of
- * shared prefix case-insensitively.
- * @param s1            input string 1
- * @param length1       length of string 1, or -1 (NULL terminated)
- * @param s2            input string 2
- * @param length2       length of string 2, or -1 (NULL terminated)
- * @param options       compare options
- * @param matchLen1     (output) length of partial prefix match in s1
- * @param matchLen2     (output) length of partial prefix match in s2
- * @param pErrorCode    receives error status
- */
-U_CAPI void
-u_caseInsensitivePrefixMatch(const UChar *s1, int32_t length1,
-                             const UChar *s2, int32_t length2,
-                             uint32_t options,
-                             int32_t *matchLen1, int32_t *matchLen2,
-                             UErrorCode *pErrorCode);
-
-/**
- * Are the Unicode properties loaded?
- * This must be used before internal functions are called that do
- * not perform this check.
- * Generate a debug assertion failure if data is not loaded.
- */
-U_CFUNC UBool
-uprv_haveProperties(UErrorCode *pErrorCode);
-
-/**
-  * Load the Unicode property data.
-  * Intended primarily for use from u_init().
-  * Has no effect if property data is already loaded.
-  * NOT thread safe.
-  */
-/*U_CFUNC int8_t
-uprv_loadPropsData(UErrorCode *errorCode);*/
-
-/*
- * Internal string casing functions implementing
- * ustring.h/ustrcase.c and UnicodeString case mapping functions.
- */
-
-struct UCaseMap {
-    const UCaseProps *csp;
-#if !UCONFIG_NO_BREAK_ITERATION
-    UBreakIterator *iter;  /* We adopt the iterator, so we own it. */
-#endif
-    char locale[32];
-    int32_t locCache;
-    uint32_t options;
-};
-
-#ifndef __UCASEMAP_H__
-typedef struct UCaseMap UCaseMap;
-#endif
-
-#if UCONFIG_NO_BREAK_ITERATION
-#   define UCASEMAP_INITIALIZER { NULL, { 0 }, 0, 0 }
-#else
-#   define UCASEMAP_INITIALIZER { NULL, NULL, { 0 }, 0, 0 }
-#endif
-
-U_CFUNC void
-ustrcase_setTempCaseMapLocale(UCaseMap *csm, const char *locale);
-
-#ifndef U_STRING_CASE_MAPPER_DEFINED
-#define U_STRING_CASE_MAPPER_DEFINED
-
-/**
- * String case mapping function type, used by ustrcase_map().
- * All error checking must be done.
- * The UCaseMap must be fully initialized, with locale and/or iter set as needed.
- * src and dest must not overlap.
- */
-typedef int32_t U_CALLCONV
-UStringCaseMapper(const UCaseMap *csm,
-                  UChar *dest, int32_t destCapacity,
-                  const UChar *src, int32_t srcLength,
-                  UErrorCode *pErrorCode);
-
-#endif
-
-/** Implements UStringCaseMapper. */
-U_CFUNC int32_t U_CALLCONV
-ustrcase_internalToLower(const UCaseMap *csm,
-                         UChar *dest, int32_t destCapacity,
-                         const UChar *src, int32_t srcLength,
-                         UErrorCode *pErrorCode);
-
-/** Implements UStringCaseMapper. */
-U_CFUNC int32_t U_CALLCONV
-ustrcase_internalToUpper(const UCaseMap *csm,
-                         UChar *dest, int32_t destCapacity,
-                         const UChar *src, int32_t srcLength,
-                         UErrorCode *pErrorCode);
-
-#if !UCONFIG_NO_BREAK_ITERATION
-
-/** Implements UStringCaseMapper. */
-U_CFUNC int32_t U_CALLCONV
-ustrcase_internalToTitle(const UCaseMap *csm,
-                         UChar *dest, int32_t destCapacity,
-                         const UChar *src, int32_t srcLength,
-                         UErrorCode *pErrorCode);
-
-#endif
-
-/** Implements UStringCaseMapper. */
-U_CFUNC int32_t U_CALLCONV
-ustrcase_internalFold(const UCaseMap *csm,
-                      UChar *dest, int32_t destCapacity,
-                      const UChar *src, int32_t srcLength,
-                      UErrorCode *pErrorCode);
-
-/**
- * Implements argument checking and buffer handling
- * for string case mapping as a common function.
- */
-U_CFUNC int32_t
-ustrcase_map(const UCaseMap *csm,
-             UChar *dest, int32_t destCapacity,
-             const UChar *src, int32_t srcLength,
-             UStringCaseMapper *stringCaseMapper,
-             UErrorCode *pErrorCode);
-
-/**
- * UTF-8 string case mapping function type, used by ucasemap_mapUTF8().
- * UTF-8 version of UStringCaseMapper.
- * All error checking must be done.
- * The UCaseMap must be fully initialized, with locale and/or iter set as needed.
- * src and dest must not overlap.
- */
-typedef int32_t U_CALLCONV
-UTF8CaseMapper(const UCaseMap *csm,
-               uint8_t *dest, int32_t destCapacity,
-               const uint8_t *src, int32_t srcLength,
-               UErrorCode *pErrorCode);
-
-/** Implements UTF8CaseMapper. */
-U_CFUNC int32_t U_CALLCONV
-ucasemap_internalUTF8ToTitle(const UCaseMap *csm,
-         uint8_t *dest, int32_t destCapacity,
-         const uint8_t *src, int32_t srcLength,
-         UErrorCode *pErrorCode);
-
-/**
- * Implements argument checking and buffer handling
- * for UTF-8 string case mapping as a common function.
- */
-U_CFUNC int32_t
-ucasemap_mapUTF8(const UCaseMap *csm,
-                 uint8_t *dest, int32_t destCapacity,
-                 const uint8_t *src, int32_t srcLength,
-                 UTF8CaseMapper *stringCaseMapper,
-                 UErrorCode *pErrorCode);
-
-#ifdef __cplusplus
-
-U_NAMESPACE_BEGIN
-namespace GreekUpper {
-
-// Data bits.
-static const uint32_t UPPER_MASK = 0x3ff;
-static const uint32_t HAS_VOWEL = 0x1000;
-static const uint32_t HAS_YPOGEGRAMMENI = 0x2000;
-static const uint32_t HAS_ACCENT = 0x4000;
-static const uint32_t HAS_DIALYTIKA = 0x8000;
-// Further bits during data building and processing, not stored in the data map.
-static const uint32_t HAS_COMBINING_DIALYTIKA = 0x10000;
-static const uint32_t HAS_OTHER_GREEK_DIACRITIC = 0x20000;
-
-static const uint32_t HAS_VOWEL_AND_ACCENT = HAS_VOWEL | HAS_ACCENT;
-static const uint32_t HAS_VOWEL_AND_ACCENT_AND_DIALYTIKA =
-        HAS_VOWEL_AND_ACCENT | HAS_DIALYTIKA;
-static const uint32_t HAS_EITHER_DIALYTIKA = HAS_DIALYTIKA | HAS_COMBINING_DIALYTIKA;
-
-// State bits.
-static const uint32_t AFTER_CASED = 1;
-static const uint32_t AFTER_VOWEL_WITH_ACCENT = 2;
-
-uint32_t getLetterData(UChar32 c);
-
-/**
- * Returns a non-zero value for each of the Greek combining diacritics
- * listed in The Unicode Standard, version 8, chapter 7.2 Greek,
- * plus some perispomeni look-alikes.
- */
-uint32_t getDiacriticData(UChar32 c);
-
-}  // namespace GreekUpper
-U_NAMESPACE_END
-
-#endif  // __cplusplus
-
 U_CAPI int32_t U_EXPORT2 
 ustr_hashUCharsN(const UChar *str, int32_t length);
 
@@ -266,6 +47,18 @@
 ustr_hashICharsN(const char *str, int32_t length);
 
 /**
+ * Convert an ASCII-range lowercase character to uppercase.
+ * 
+ * @param c A UChar.
+ * @return If UChar is a lowercase ASCII character, returns the uppercase version.
+ *         Otherwise, returns the input character.
+ */
+U_CAPI UChar U_EXPORT2
+u_asciiToUpper(UChar c);
+
+// TODO: Add u_asciiToLower if/when there is a need for it.
+
+/**
  * NUL-terminate a UChar * string if possible.
  * If length  < destCapacity then NUL-terminate.
  * If length == destCapacity then do not terminate but set U_STRING_NOT_TERMINATED_WARNING.
@@ -301,4 +94,62 @@
 U_CAPI int32_t U_EXPORT2
 u_terminateWChars(wchar_t *dest, int32_t destCapacity, int32_t length, UErrorCode *pErrorCode);
 
+/**
+ * Counts the bytes of any whole valid sequence for a UTF-8 lead byte.
+ * Returns 1 for ASCII 0..0x7f.
+ * Returns 0 for 0x80..0xc1 as well as for 0xf5..0xff.
+ * leadByte might be evaluated multiple times.
+ *
+ * @param leadByte The first byte of a UTF-8 sequence. Must be 0..0xff.
+ * @return 0..4
+ */
+#define U8_COUNT_BYTES(leadByte) \
+    (U8_IS_SINGLE(leadByte) ? 1 : U8_COUNT_BYTES_NON_ASCII(leadByte))
+
+/**
+ * Counts the bytes of any whole valid sequence for a UTF-8 lead byte.
+ * Returns 0 for 0x00..0xc1 as well as for 0xf5..0xff.
+ * leadByte might be evaluated multiple times.
+ *
+ * @param leadByte The first byte of a UTF-8 sequence. Must be 0..0xff.
+ * @return 0 or 2..4
+ */
+#define U8_COUNT_BYTES_NON_ASCII(leadByte) \
+    (U8_IS_LEAD(leadByte) ? ((uint8_t)(leadByte)>=0xe0)+((uint8_t)(leadByte)>=0xf0)+2 : 0)
+
+#ifdef __cplusplus
+
+U_NAMESPACE_BEGIN
+
+class UTF8 {
+public:
+    UTF8() = delete;  // all static
+
+    /**
+     * Is t a valid UTF-8 trail byte?
+     *
+     * @param prev Must be the preceding lead byte if i==1 and length>=3;
+     *             otherwise ignored.
+     * @param t The i-th byte following the lead byte.
+     * @param i The index (1..3) of byte t in the byte sequence. 0<i<length
+     * @param length The length (2..4) of the byte sequence according to the lead byte.
+     * @return true if t is a valid trail byte in this context.
+     */
+    static inline UBool isValidTrail(int32_t prev, uint8_t t, int32_t i, int32_t length) {
+        // The first trail byte after a 3- or 4-byte lead byte
+        // needs to be validated together with its lead byte.
+        if (length <= 2 || i > 1) {
+            return U8_IS_TRAIL(t);
+        } else if (length == 3) {
+            return U8_IS_VALID_LEAD3_AND_T1(prev, t);
+        } else {  // length == 4
+            return U8_IS_VALID_LEAD4_AND_T1(prev, t);
+        }
+    }
+};
+
+U_NAMESPACE_END
+
+#endif  // __cplusplus
+
 #endif
diff --git a/src/third_party/icu/source/common/ustr_titlecase_brkiter.cpp b/src/third_party/icu/source/common/ustr_titlecase_brkiter.cpp
index 738bd62..70f68b9 100644
--- a/src/third_party/icu/source/common/ustr_titlecase_brkiter.cpp
+++ b/src/third_party/icu/source/common/ustr_titlecase_brkiter.cpp
@@ -1,10 +1,12 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *   Copyright (C) 2011, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *******************************************************************************
 *   file name:  ustr_titlecase_brkiter.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -19,34 +21,173 @@
 
 #if !UCONFIG_NO_BREAK_ITERATION
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/brkiter.h"
+#include "unicode/casemap.h"
+#include "unicode/chariter.h"
+#include "unicode/localpointer.h"
 #include "unicode/ubrk.h"
 #include "unicode/ucasemap.h"
+#include "unicode/utext.h"
 #include "cmemory.h"
+#include "uassert.h"
 #include "ucase.h"
-#include "ustr_imp.h"
+#include "ucasemap_imp.h"
 
-/* functions available in the common library (for unistr_case.cpp) */
+U_NAMESPACE_BEGIN
 
-/*
- * Set parameters on an empty UCaseMap, for UCaseMap-less API functions.
- * Do this fast because it is called with every function call.
- * Duplicate of the same function in ustrcase.cpp, to keep it inline.
+/**
+ * Whole-string BreakIterator.
+ * Titlecasing only calls setText(), first(), and next().
+ * We implement the rest only to satisfy the abstract interface.
  */
-static inline void
-setTempCaseMap(UCaseMap *csm, const char *locale) {
-    if(csm->csp==NULL) {
-        csm->csp=ucase_getSingleton();
+class WholeStringBreakIterator : public BreakIterator {
+public:
+    WholeStringBreakIterator() : BreakIterator(), length(0) {}
+    ~WholeStringBreakIterator() U_OVERRIDE;
+    UBool operator==(const BreakIterator&) const U_OVERRIDE;
+    WholeStringBreakIterator *clone() const U_OVERRIDE;
+    static UClassID U_EXPORT2 getStaticClassID();
+    UClassID getDynamicClassID() const U_OVERRIDE;
+    CharacterIterator &getText() const U_OVERRIDE;
+    UText *getUText(UText *fillIn, UErrorCode &errorCode) const U_OVERRIDE;
+    void  setText(const UnicodeString &text) U_OVERRIDE;
+    void  setText(UText *text, UErrorCode &errorCode) U_OVERRIDE;
+    void  adoptText(CharacterIterator* it) U_OVERRIDE;
+    int32_t first() U_OVERRIDE;
+    int32_t last() U_OVERRIDE;
+    int32_t previous() U_OVERRIDE;
+    int32_t next() U_OVERRIDE;
+    int32_t current() const U_OVERRIDE;
+    int32_t following(int32_t offset) U_OVERRIDE;
+    int32_t preceding(int32_t offset) U_OVERRIDE;
+    UBool isBoundary(int32_t offset) U_OVERRIDE;
+    int32_t next(int32_t n) U_OVERRIDE;
+    WholeStringBreakIterator *createBufferClone(void *stackBuffer, int32_t &BufferSize,
+                                                UErrorCode &errorCode) U_OVERRIDE;
+    WholeStringBreakIterator &refreshInputText(UText *input, UErrorCode &errorCode) U_OVERRIDE;
+
+private:
+    int32_t length;
+};
+
+UOBJECT_DEFINE_RTTI_IMPLEMENTATION(WholeStringBreakIterator)
+
+WholeStringBreakIterator::~WholeStringBreakIterator() {}
+UBool WholeStringBreakIterator::operator==(const BreakIterator&) const { return FALSE; }
+WholeStringBreakIterator *WholeStringBreakIterator::clone() const { return nullptr; }
+
+CharacterIterator &WholeStringBreakIterator::getText() const {
+    UPRV_UNREACHABLE;  // really should not be called
+}
+UText *WholeStringBreakIterator::getUText(UText * /*fillIn*/, UErrorCode &errorCode) const {
+    if (U_SUCCESS(errorCode)) {
+        errorCode = U_UNSUPPORTED_ERROR;
     }
-    if(locale!=NULL && locale[0]==0) {
-        csm->locale[0]=0;
-    } else {
-        ustrcase_setTempCaseMapLocale(csm, locale);
-    }
+    return nullptr;
 }
 
-/* public API functions */
+void  WholeStringBreakIterator::setText(const UnicodeString &text) {
+    length = text.length();
+}
+void  WholeStringBreakIterator::setText(UText *text, UErrorCode &errorCode) {
+    if (U_SUCCESS(errorCode)) {
+        int64_t length64 = utext_nativeLength(text);
+        if (length64 <= INT32_MAX) {
+            length = (int32_t)length64;
+        } else {
+            errorCode = U_INDEX_OUTOFBOUNDS_ERROR;
+        }
+    }
+}
+void  WholeStringBreakIterator::adoptText(CharacterIterator*) {
+    UPRV_UNREACHABLE;  // should not be called
+}
+
+int32_t WholeStringBreakIterator::first() { return 0; }
+int32_t WholeStringBreakIterator::last() { return length; }
+int32_t WholeStringBreakIterator::previous() { return 0; }
+int32_t WholeStringBreakIterator::next() { return length; }
+int32_t WholeStringBreakIterator::current() const { return 0; }
+int32_t WholeStringBreakIterator::following(int32_t /*offset*/) { return length; }
+int32_t WholeStringBreakIterator::preceding(int32_t /*offset*/) { return 0; }
+UBool WholeStringBreakIterator::isBoundary(int32_t /*offset*/) { return FALSE; }
+int32_t WholeStringBreakIterator::next(int32_t /*n*/) { return length; }
+
+WholeStringBreakIterator *WholeStringBreakIterator::createBufferClone(
+        void * /*stackBuffer*/, int32_t & /*BufferSize*/, UErrorCode &errorCode) {
+    if (U_SUCCESS(errorCode)) {
+        errorCode = U_UNSUPPORTED_ERROR;
+    }
+    return nullptr;
+}
+WholeStringBreakIterator &WholeStringBreakIterator::refreshInputText(
+        UText * /*input*/, UErrorCode &errorCode) {
+    if (U_SUCCESS(errorCode)) {
+        errorCode = U_UNSUPPORTED_ERROR;
+    }
+    return *this;
+}
+
+U_CFUNC
+BreakIterator *ustrcase_getTitleBreakIterator(
+        const Locale *locale, const char *locID, uint32_t options, BreakIterator *iter,
+        LocalPointer<BreakIterator> &ownedIter, UErrorCode &errorCode) {
+    if (U_FAILURE(errorCode)) { return nullptr; }
+    options &= U_TITLECASE_ITERATOR_MASK;
+    if (options != 0 && iter != nullptr) {
+        errorCode = U_ILLEGAL_ARGUMENT_ERROR;
+        return nullptr;
+    }
+    if (iter == nullptr) {
+        switch (options) {
+        case 0:
+            iter = BreakIterator::createWordInstance(
+                locale != nullptr ? *locale : Locale(locID), errorCode);
+            break;
+        case U_TITLECASE_WHOLE_STRING:
+            iter = new WholeStringBreakIterator();
+            if (iter == nullptr) {
+                errorCode = U_MEMORY_ALLOCATION_ERROR;
+            }
+            break;
+        case U_TITLECASE_SENTENCES:
+            iter = BreakIterator::createSentenceInstance(
+                locale != nullptr ? *locale : Locale(locID), errorCode);
+            break;
+        default:
+            errorCode = U_ILLEGAL_ARGUMENT_ERROR;
+            break;
+        }
+        ownedIter.adoptInstead(iter);
+    }
+    return iter;
+}
+
+int32_t CaseMap::toTitle(
+        const char *locale, uint32_t options, BreakIterator *iter,
+        const UChar *src, int32_t srcLength,
+        UChar *dest, int32_t destCapacity, Edits *edits,
+        UErrorCode &errorCode) {
+    LocalPointer<BreakIterator> ownedIter;
+    iter = ustrcase_getTitleBreakIterator(nullptr, locale, options, iter, ownedIter, errorCode);
+    if(iter==NULL) {
+        return 0;
+    }
+    UnicodeString s(srcLength<0, src, srcLength);
+    iter->setText(s);
+    return ustrcase_map(
+        ustrcase_getCaseLocale(locale), options, iter,
+        dest, destCapacity,
+        src, srcLength,
+        ustrcase_internalToTitle, edits, errorCode);
+}
+
+U_NAMESPACE_END
+
+U_NAMESPACE_USE
 
 U_CAPI int32_t U_EXPORT2
 u_strToTitle(UChar *dest, int32_t destCapacity,
@@ -54,22 +195,20 @@
              UBreakIterator *titleIter,
              const char *locale,
              UErrorCode *pErrorCode) {
-    UCaseMap csm=UCASEMAP_INITIALIZER;
-    setTempCaseMap(&csm, locale);
-    if(titleIter!=NULL) {
-        ubrk_setText(csm.iter=titleIter, src, srcLength, pErrorCode);
-    } else {
-        csm.iter=ubrk_open(UBRK_WORD, csm.locale, src, srcLength, pErrorCode);
+    LocalPointer<BreakIterator> ownedIter;
+    BreakIterator *iter = ustrcase_getTitleBreakIterator(
+        nullptr, locale, 0, reinterpret_cast<BreakIterator *>(titleIter),
+        ownedIter, *pErrorCode);
+    if (iter == nullptr) {
+        return 0;
     }
-    int32_t length=ustrcase_map(
-        &csm,
+    UnicodeString s(srcLength<0, src, srcLength);
+    iter->setText(s);
+    return ustrcase_mapWithOverlap(
+        ustrcase_getCaseLocale(locale), 0, iter,
         dest, destCapacity,
         src, srcLength,
-        ustrcase_internalToTitle, pErrorCode);
-    if(titleIter==NULL && csm.iter!=NULL) {
-        ubrk_close(csm.iter);
-    }
-    return length;
+        ustrcase_internalToTitle, *pErrorCode);
 }
 
 U_CAPI int32_t U_EXPORT2
@@ -77,16 +216,25 @@
                  UChar *dest, int32_t destCapacity,
                  const UChar *src, int32_t srcLength,
                  UErrorCode *pErrorCode) {
-    if(csm->iter!=NULL) {
-        ubrk_setText(csm->iter, src, srcLength, pErrorCode);
-    } else {
-        csm->iter=ubrk_open(UBRK_WORD, csm->locale, src, srcLength, pErrorCode);
+    if (U_FAILURE(*pErrorCode)) {
+        return 0;
     }
+    if (csm->iter == NULL) {
+        LocalPointer<BreakIterator> ownedIter;
+        BreakIterator *iter = ustrcase_getTitleBreakIterator(
+            nullptr, csm->locale, csm->options, nullptr, ownedIter, *pErrorCode);
+        if (iter == nullptr) {
+            return 0;
+        }
+        csm->iter = ownedIter.orphan();
+    }
+    UnicodeString s(srcLength<0, src, srcLength);
+    csm->iter->setText(s);
     return ustrcase_map(
-        csm,
+        csm->caseLocale, csm->options, csm->iter,
         dest, destCapacity,
         src, srcLength,
-        ustrcase_internalToTitle, pErrorCode);
+        ustrcase_internalToTitle, NULL, *pErrorCode);
 }
 
 #endif  // !UCONFIG_NO_BREAK_ITERATION
diff --git a/src/third_party/icu/source/common/ustr_wcs.cpp b/src/third_party/icu/source/common/ustr_wcs.cpp
index d786b05..59fc0c5 100644
--- a/src/third_party/icu/source/common/ustr_wcs.cpp
+++ b/src/third_party/icu/source/common/ustr_wcs.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  ustr_wcs.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -46,7 +48,7 @@
     char *newBuffer=(char *)uprv_malloc(reqCapacity*size);
     if(newBuffer!=NULL) {
         if(length>0) {
-            uprv_memcpy(newBuffer, *pBuffer, length*size);
+            uprv_memcpy(newBuffer, *pBuffer, (size_t)length*size);
         }
         *pCapacity=reqCapacity;
     } else {
@@ -204,7 +206,7 @@
         count = (int32_t)(pIntTarget-intTarget);
        
         if(0 < count && count <= destCapacity){
-            uprv_memcpy(dest,intTarget,count*sizeof(wchar_t));
+            uprv_memcpy(dest, intTarget, (size_t)count*sizeof(wchar_t));
         }  
 
         if(pDestLength){
@@ -256,13 +258,13 @@
         srcLength = u_strlen(src);
     }
     if(0 < srcLength && srcLength <= destCapacity){
-        uprv_memcpy(dest,src,srcLength*U_SIZEOF_UCHAR);
+        u_memcpy((UChar *)dest, src, srcLength);
     }
     if(pDestLength){
        *pDestLength = srcLength;
     }
 
-    u_terminateUChars(dest,destCapacity,srcLength,pErrorCode);
+    u_terminateUChars((UChar *)dest,destCapacity,srcLength,pErrorCode);
 
     return dest;
 
@@ -344,7 +346,7 @@
         pSrcLimit = src + srcLength;
 
         for(;;){
-            register int32_t nulLen = 0;
+            int32_t nulLen = 0;
 
             /* find nulls in the string */
             while(nulLen<srcLength && pSrc[nulLen++]!=0){
@@ -399,7 +401,7 @@
                 }
                 if(nulLen>0){
                     /* copy the contents to tempStack */
-                    uprv_memcpy(pWStack,pSrc,nulLen*sizeof(wchar_t));
+                    uprv_memcpy(pWStack, pSrc, (size_t)nulLen*sizeof(wchar_t));
                 }
             
                 /* null terminate the tempBuffer */
@@ -508,10 +510,10 @@
 #ifdef U_WCHAR_IS_UTF16
     /* wchar_t is UTF-16 just do a memcpy */
     if(srcLength == -1){
-        srcLength = u_strlen(src);
+        srcLength = u_strlen((const UChar *)src);
     }
     if(0 < srcLength && srcLength <= destCapacity){
-        uprv_memcpy(dest,src,srcLength*U_SIZEOF_UCHAR);
+        u_memcpy(dest, (const UChar *)src, srcLength);
     }
     if(pDestLength){
        *pDestLength = srcLength;
diff --git a/src/third_party/icu/source/common/ustrcase.cpp b/src/third_party/icu/source/common/ustrcase.cpp
index 5b8f8f6..32c8edb 100644
--- a/src/third_party/icu/source/common/ustrcase.cpp
+++ b/src/third_party/icu/source/common/ustrcase.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  ustrcase.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -18,10 +20,15 @@
 *   to the Unicode Character Database (uprops.dat).
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/utypes.h"
 #include "unicode/brkiter.h"
+#include "unicode/casemap.h"
+#include "unicode/edits.h"
+#include "unicode/stringoptions.h"
 #include "unicode/ustring.h"
 #include "unicode/ucasemap.h"
 #include "unicode/ubrk.h"
@@ -29,42 +36,74 @@
 #include "unicode/utf16.h"
 #include "cmemory.h"
 #include "ucase.h"
+#include "ucasemap_imp.h"
 #include "ustr_imp.h"
 #include "uassert.h"
-
-U_NAMESPACE_USE
-
-/* string casing ------------------------------------------------------------ */
-
+U_NAMESPACE_BEGIN
+namespace {
+int32_t checkOverflowAndEditsError(int32_t destIndex, int32_t destCapacity,
+                                   Edits *edits, UErrorCode &errorCode) {
+    if (U_SUCCESS(errorCode)) {
+        if (destIndex > destCapacity) {
+            errorCode = U_BUFFER_OVERFLOW_ERROR;
+        } else if (edits != NULL) {
+            edits->copyErrorTo(errorCode);
+        }
+    }
+    return destIndex;
+}
 /* Appends a full case mapping result, see UCASE_MAX_STRING_LENGTH. */
-static inline int32_t
+inline int32_t
 appendResult(UChar *dest, int32_t destIndex, int32_t destCapacity,
-             int32_t result, const UChar *s) {
+             int32_t result, const UChar *s,
+             int32_t cpLength, uint32_t options, icu::Edits *edits) {
     UChar32 c;
     int32_t length;
-
     /* decode the result */
     if(result<0) {
         /* (not) original code point */
+        if(edits!=NULL) {
+            edits->addUnchanged(cpLength);
+        }
+        if(options & U_OMIT_UNCHANGED_TEXT) {
+            return destIndex;
+        }
         c=~result;
-        length=-1;
-    } else if(result<=UCASE_MAX_STRING_LENGTH) {
-        c=U_SENTINEL;
-        length=result;
+        if(destIndex<destCapacity && c<=0xffff) {  // BMP slightly-fastpath
+            dest[destIndex++]=(UChar)c;
+            return destIndex;
+        }
+        length=cpLength;
     } else {
-        c=result;
-        length=-1;
+        if(result<=UCASE_MAX_STRING_LENGTH) {
+            c=U_SENTINEL;
+            length=result;
+        } else if(destIndex<destCapacity && result<=0xffff) {  // BMP slightly-fastpath
+            dest[destIndex++]=(UChar)result;
+            if(edits!=NULL) {
+                edits->addReplace(cpLength, 1);
+            }
+            return destIndex;
+        } else {
+            c=result;
+            length=U16_LENGTH(c);
+        }
+        if(edits!=NULL) {
+            edits->addReplace(cpLength, length);
+        }
     }
-
+    if(length>(INT32_MAX-destIndex)) {
+        return -1;  // integer overflow
+    }
     if(destIndex<destCapacity) {
         /* append the result */
-        if(length<0) {
+        if(c>=0) {
             /* code point */
             UBool isError=FALSE;
             U16_APPEND(dest, destIndex, destCapacity, c, isError);
             if(isError) {
                 /* overflow, nothing written */
-                destIndex+=U16_LENGTH(c);
+                destIndex+=length;
             }
         } else {
             /* string */
@@ -80,28 +119,48 @@
         }
     } else {
         /* preflight */
-        if(length<0) {
-            destIndex+=U16_LENGTH(c);
-        } else {
-            destIndex+=length;
-        }
+        destIndex+=length;
     }
     return destIndex;
 }
-
-static inline int32_t
+inline int32_t
 appendUChar(UChar *dest, int32_t destIndex, int32_t destCapacity, UChar c) {
     if(destIndex<destCapacity) {
         dest[destIndex]=c;
+    } else if(destIndex==INT32_MAX) {
+        return -1;  // integer overflow
     }
     return destIndex+1;
 }
-
-static UChar32 U_CALLCONV
+int32_t
+appendNonEmptyUnchanged(UChar *dest, int32_t destIndex, int32_t destCapacity,
+                        const UChar *s, int32_t length, uint32_t options, icu::Edits *edits) {
+    if(edits!=NULL) {
+        edits->addUnchanged(length);
+    }
+    if(options & U_OMIT_UNCHANGED_TEXT) {
+        return destIndex;
+    }
+    if(length>(INT32_MAX-destIndex)) {
+        return -1;  // integer overflow
+    }
+    if((destIndex+length)<=destCapacity) {
+        u_memcpy(dest+destIndex, s, length);
+    }
+    return destIndex + length;
+}
+inline int32_t
+appendUnchanged(UChar *dest, int32_t destIndex, int32_t destCapacity,
+                const UChar *s, int32_t length, uint32_t options, icu::Edits *edits) {
+    if (length <= 0) {
+        return destIndex;
+    }
+    return appendNonEmptyUnchanged(dest, destIndex, destCapacity, s, length, options, edits);
+}
+UChar32 U_CALLCONV
 utf16_caseContextIterator(void *context, int8_t dir) {
     UCaseContext *csc=(UCaseContext *)context;
     UChar32 c;
-
     if(dir<0) {
         /* reset for backward iteration */
         csc->index=csc->cpStart;
@@ -114,7 +173,6 @@
         /* continue current iteration direction */
         dir=csc->dir;
     }
-
     if(dir<0) {
         if(csc->start<csc->index) {
             U16_PREV((const UChar *)csc->p, csc->start, csc->index, c);
@@ -128,184 +186,337 @@
     }
     return U_SENTINEL;
 }
-
-/*
- * Case-maps [srcStart..srcLimit[ but takes
- * context [0..srcLength[ into account.
+/**
+ * caseLocale >= 0: Lowercases [srcStart..srcLimit[ but takes context [0..srcLength[ into account.
+ * caseLocale < 0: Case-folds [srcStart..srcLimit[.
  */
-static int32_t
-_caseMap(const UCaseMap *csm, UCaseMapFull *map,
-         UChar *dest, int32_t destCapacity,
-         const UChar *src, UCaseContext *csc,
-         int32_t srcStart, int32_t srcLimit,
-         UErrorCode *pErrorCode) {
-    const UChar *s;
-    UChar32 c, c2 = 0;
-    int32_t srcIndex, destIndex;
-    int32_t locCache;
-
-    locCache=csm->locCache;
-
-    /* case mapping loop */
-    srcIndex=srcStart;
-    destIndex=0;
-    while(srcIndex<srcLimit) {
-        csc->cpStart=srcIndex;
-        U16_NEXT(src, srcIndex, srcLimit, c);
-        csc->cpLimit=srcIndex;
-        c=map(csm->csp, c, utf16_caseContextIterator, csc, &s, csm->locale, &locCache);
-        if((destIndex<destCapacity) && (c<0 ? (c2=~c)<=0xffff : UCASE_MAX_STRING_LENGTH<c && (c2=c)<=0xffff)) {
-            /* fast path version of appendResult() for BMP results */
-            dest[destIndex++]=(UChar)c2;
+int32_t toLower(int32_t caseLocale, uint32_t options,
+                UChar *dest, int32_t destCapacity,
+                const UChar *src, UCaseContext *csc, int32_t srcStart, int32_t srcLimit,
+                icu::Edits *edits, UErrorCode &errorCode) {
+    const int8_t *latinToLower;
+    if (caseLocale == UCASE_LOC_ROOT ||
+            (caseLocale >= 0 ?
+                !(caseLocale == UCASE_LOC_TURKISH || caseLocale == UCASE_LOC_LITHUANIAN) :
+                (options & _FOLD_CASE_OPTIONS_MASK) == U_FOLD_CASE_DEFAULT)) {
+        latinToLower = LatinCase::TO_LOWER_NORMAL;
+    } else {
+        latinToLower = LatinCase::TO_LOWER_TR_LT;
+    }
+    const UTrie2 *trie = ucase_getTrie();
+    int32_t destIndex = 0;
+    int32_t prev = srcStart;
+    int32_t srcIndex = srcStart;
+    for (;;) {
+        // fast path for simple cases
+        UChar lead = 0;
+        while (srcIndex < srcLimit) {
+            lead = src[srcIndex];
+            int32_t delta;
+            if (lead < LatinCase::LONG_S) {
+                int8_t d = latinToLower[lead];
+                if (d == LatinCase::EXC) { break; }
+                ++srcIndex;
+                if (d == 0) { continue; }
+                delta = d;
+            } else if (lead >= 0xd800) {
+                break;  // surrogate or higher
+            } else {
+                uint16_t props = UTRIE2_GET16_FROM_U16_SINGLE_LEAD(trie, lead);
+                if (UCASE_HAS_EXCEPTION(props)) { break; }
+                ++srcIndex;
+                if (!UCASE_IS_UPPER_OR_TITLE(props) || (delta = UCASE_GET_DELTA(props)) == 0) {
+                    continue;
+                }
+            }
+            lead += static_cast<UChar>(delta);
+            destIndex = appendUnchanged(dest, destIndex, destCapacity,
+                                        src + prev, srcIndex - 1 - prev, options, edits);
+            if (destIndex >= 0) {
+                destIndex = appendUChar(dest, destIndex, destCapacity, lead);
+                if (edits != nullptr) {
+                    edits->addReplace(1, 1);
+                }
+            }
+            if (destIndex < 0) {
+                errorCode = U_INDEX_OUTOFBOUNDS_ERROR;
+                return 0;
+            }
+            prev = srcIndex;
+        }
+        if (srcIndex >= srcLimit) {
+            break;
+        }
+        // slow path
+        int32_t cpStart = srcIndex++;
+        UChar trail;
+        UChar32 c;
+        if (U16_IS_LEAD(lead) && srcIndex < srcLimit && U16_IS_TRAIL(trail = src[srcIndex])) {
+            c = U16_GET_SUPPLEMENTARY(lead, trail);
+            ++srcIndex;
         } else {
-            destIndex=appendResult(dest, destIndex, destCapacity, c, s);
+            c = lead;
+        }
+        const UChar *s;
+        if (caseLocale >= 0) {
+            csc->cpStart = cpStart;
+            csc->cpLimit = srcIndex;
+            c = ucase_toFullLower(c, utf16_caseContextIterator, csc, &s, caseLocale);
+        } else {
+            c = ucase_toFullFolding(c, &s, options);
+        }
+        if (c >= 0) {
+            destIndex = appendUnchanged(dest, destIndex, destCapacity,
+                                        src + prev, cpStart - prev, options, edits);
+            if (destIndex >= 0) {
+                destIndex = appendResult(dest, destIndex, destCapacity, c, s,
+                                         srcIndex - cpStart, options, edits);
+            }
+            if (destIndex < 0) {
+                errorCode = U_INDEX_OUTOFBOUNDS_ERROR;
+                return 0;
+            }
+            prev = srcIndex;
         }
     }
-
-    if(destIndex>destCapacity) {
-        *pErrorCode=U_BUFFER_OVERFLOW_ERROR;
+    destIndex = appendUnchanged(dest, destIndex, destCapacity,
+                                src + prev, srcIndex - prev, options, edits);
+    if (destIndex < 0) {
+        errorCode = U_INDEX_OUTOFBOUNDS_ERROR;
+        return 0;
     }
     return destIndex;
 }
-
-#if !UCONFIG_NO_BREAK_ITERATION
-
-U_CFUNC int32_t U_CALLCONV
-ustrcase_internalToTitle(const UCaseMap *csm,
-                         UChar *dest, int32_t destCapacity,
-                         const UChar *src, int32_t srcLength,
-                         UErrorCode *pErrorCode) {
-    const UChar *s;
-    UChar32 c;
-    int32_t prev, titleStart, titleLimit, idx, destIndex, length;
-    UBool isFirstIndex;
-
-    if(U_FAILURE(*pErrorCode)) {
+int32_t toUpper(int32_t caseLocale, uint32_t options,
+                UChar *dest, int32_t destCapacity,
+                const UChar *src, UCaseContext *csc, int32_t srcLength,
+                icu::Edits *edits, UErrorCode &errorCode) {
+    const int8_t *latinToUpper;
+    if (caseLocale == UCASE_LOC_TURKISH) {
+        latinToUpper = LatinCase::TO_UPPER_TR;
+    } else {
+        latinToUpper = LatinCase::TO_UPPER_NORMAL;
+    }
+    const UTrie2 *trie = ucase_getTrie();
+    int32_t destIndex = 0;
+    int32_t prev = 0;
+    int32_t srcIndex = 0;
+    for (;;) {
+        // fast path for simple cases
+        UChar lead = 0;
+        while (srcIndex < srcLength) {
+            lead = src[srcIndex];
+            int32_t delta;
+            if (lead < LatinCase::LONG_S) {
+                int8_t d = latinToUpper[lead];
+                if (d == LatinCase::EXC) { break; }
+                ++srcIndex;
+                if (d == 0) { continue; }
+                delta = d;
+            } else if (lead >= 0xd800) {
+                break;  // surrogate or higher
+            } else {
+                uint16_t props = UTRIE2_GET16_FROM_U16_SINGLE_LEAD(trie, lead);
+                if (UCASE_HAS_EXCEPTION(props)) { break; }
+                ++srcIndex;
+                if (UCASE_GET_TYPE(props) != UCASE_LOWER || (delta = UCASE_GET_DELTA(props)) == 0) {
+                    continue;
+                }
+            }
+            lead += static_cast<UChar>(delta);
+            destIndex = appendUnchanged(dest, destIndex, destCapacity,
+                                        src + prev, srcIndex - 1 - prev, options, edits);
+            if (destIndex >= 0) {
+                destIndex = appendUChar(dest, destIndex, destCapacity, lead);
+                if (edits != nullptr) {
+                    edits->addReplace(1, 1);
+                }
+            }
+            if (destIndex < 0) {
+                errorCode = U_INDEX_OUTOFBOUNDS_ERROR;
+                return 0;
+            }
+            prev = srcIndex;
+        }
+        if (srcIndex >= srcLength) {
+            break;
+        }
+        // slow path
+        int32_t cpStart;
+        csc->cpStart = cpStart = srcIndex++;
+        UChar trail;
+        UChar32 c;
+        if (U16_IS_LEAD(lead) && srcIndex < srcLength && U16_IS_TRAIL(trail = src[srcIndex])) {
+            c = U16_GET_SUPPLEMENTARY(lead, trail);
+            ++srcIndex;
+        } else {
+            c = lead;
+        }
+        csc->cpLimit = srcIndex;
+        const UChar *s;
+        c = ucase_toFullUpper(c, utf16_caseContextIterator, csc, &s, caseLocale);
+        if (c >= 0) {
+            destIndex = appendUnchanged(dest, destIndex, destCapacity,
+                                        src + prev, cpStart - prev, options, edits);
+            if (destIndex >= 0) {
+                destIndex = appendResult(dest, destIndex, destCapacity, c, s,
+                                         srcIndex - cpStart, options, edits);
+            }
+            if (destIndex < 0) {
+                errorCode = U_INDEX_OUTOFBOUNDS_ERROR;
+                return 0;
+            }
+            prev = srcIndex;
+        }
+    }
+    destIndex = appendUnchanged(dest, destIndex, destCapacity,
+                                src + prev, srcIndex - prev, options, edits);
+    if (destIndex < 0) {
+        errorCode = U_INDEX_OUTOFBOUNDS_ERROR;
         return 0;
     }
-
-    // Use the C++ abstract base class to minimize dependencies.
-    // TODO: Change UCaseMap.iter to store a BreakIterator directly.
-    BreakIterator *bi=reinterpret_cast<BreakIterator *>(csm->iter);
-
+    return destIndex;
+}
+}  // namespace
+U_NAMESPACE_END
+U_NAMESPACE_USE
+#if !UCONFIG_NO_BREAK_ITERATION
+U_CFUNC int32_t U_CALLCONV
+ustrcase_internalToTitle(int32_t caseLocale, uint32_t options, BreakIterator *iter,
+                         UChar *dest, int32_t destCapacity,
+                         const UChar *src, int32_t srcLength,
+                         icu::Edits *edits,
+                         UErrorCode &errorCode) {
+    if (!ustrcase_checkTitleAdjustmentOptions(options, errorCode)) {
+        return 0;
+    }
     /* set up local variables */
-    int32_t locCache=csm->locCache;
     UCaseContext csc=UCASECONTEXT_INITIALIZER;
     csc.p=(void *)src;
     csc.limit=srcLength;
-    destIndex=0;
-    prev=0;
-    isFirstIndex=TRUE;
-
+    int32_t destIndex=0;
+    int32_t prev=0;
+    UBool isFirstIndex=TRUE;
     /* titlecasing loop */
     while(prev<srcLength) {
         /* find next index where to titlecase */
+        int32_t index;
         if(isFirstIndex) {
             isFirstIndex=FALSE;
-            idx=bi->first();
+            index=iter->first();
         } else {
-            idx=bi->next();
+            index=iter->next();
         }
-        if(idx==UBRK_DONE || idx>srcLength) {
-            idx=srcLength;
+        if(index==UBRK_DONE || index>srcLength) {
+            index=srcLength;
         }
-
         /*
-         * Unicode 4 & 5 section 3.13 Default Case Operations:
-         *
-         * R3  toTitlecase(X): Find the word boundaries based on Unicode Standard Annex
-         * #29, "Text Boundaries." Between each pair of word boundaries, find the first
-         * cased character F. If F exists, map F to default_title(F); then map each
-         * subsequent character C to default_lower(C).
-         *
-         * In this implementation, segment [prev..index[ into 3 parts:
-         * a) uncased characters (copy as-is) [prev..titleStart[
-         * b) first case letter (titlecase)         [titleStart..titleLimit[
+         * Segment [prev..index[ into 3 parts:
+         * a) skipped characters (copy as-is) [prev..titleStart[
+         * b) first letter (titlecase)              [titleStart..titleLimit[
          * c) subsequent characters (lowercase)                 [titleLimit..index[
          */
-        if(prev<idx) {
-            /* find and copy uncased characters [prev..titleStart[ */
-            titleStart=titleLimit=prev;
-            U16_NEXT(src, titleLimit, idx, c);
-            if((csm->options&U_TITLECASE_NO_BREAK_ADJUSTMENT)==0 && UCASE_NONE==ucase_getType(csm->csp, c)) {
-                /* Adjust the titlecasing index (titleStart) to the next cased character. */
-                for(;;) {
+        if(prev<index) {
+            // Find and copy skipped characters [prev..titleStart[
+            int32_t titleStart=prev;
+            int32_t titleLimit=prev;
+            UChar32 c;
+            U16_NEXT(src, titleLimit, index, c);
+            if ((options&U_TITLECASE_NO_BREAK_ADJUSTMENT)==0) {
+                // Adjust the titlecasing index to the next cased character,
+                // or to the next letter/number/symbol/private use.
+                // Stop with titleStart<titleLimit<=index
+                // if there is a character to be titlecased,
+                // or else stop with titleStart==titleLimit==index.
+                UBool toCased = (options&U_TITLECASE_ADJUST_TO_CASED) != 0;
+                while (toCased ? UCASE_NONE==ucase_getType(c) : !ustrcase_isLNS(c)) {
                     titleStart=titleLimit;
-                    if(titleLimit==idx) {
-                        /*
-                         * only uncased characters in [prev..index[
-                         * stop with titleStart==titleLimit==index
-                         */
+                    if(titleLimit==index) {
                         break;
                     }
-                    U16_NEXT(src, titleLimit, idx, c);
-                    if(UCASE_NONE!=ucase_getType(csm->csp, c)) {
-                        break; /* cased letter at [titleStart..titleLimit[ */
-                    }
+                    U16_NEXT(src, titleLimit, index, c);
                 }
-                length=titleStart-prev;
-                if(length>0) {
-                    if((destIndex+length)<=destCapacity) {
-                        uprv_memcpy(dest+destIndex, src+prev, length*U_SIZEOF_UCHAR);
+                if (prev < titleStart) {
+                    destIndex=appendUnchanged(dest, destIndex, destCapacity,
+                                              src+prev, titleStart-prev, options, edits);
+                    if(destIndex<0) {
+                        errorCode=U_INDEX_OUTOFBOUNDS_ERROR;
+                        return 0;
                     }
-                    destIndex+=length;
                 }
             }
-
             if(titleStart<titleLimit) {
                 /* titlecase c which is from [titleStart..titleLimit[ */
                 csc.cpStart=titleStart;
                 csc.cpLimit=titleLimit;
-                c=ucase_toFullTitle(csm->csp, c, utf16_caseContextIterator, &csc, &s, csm->locale, &locCache);
-                destIndex=appendResult(dest, destIndex, destCapacity, c, s); 
-
-                /* Special case Dutch IJ titlecasing */
-                if ( titleStart+1 < idx && 
-                     ucase_getCaseLocale(csm->locale,&locCache) == UCASE_LOC_DUTCH &&
-                     ( src[titleStart] == (UChar32) 0x0049 || src[titleStart] == (UChar32) 0x0069 ) &&
-                     ( src[titleStart+1] == (UChar32) 0x004A || src[titleStart+1] == (UChar32) 0x006A )) { 
-                            c=(UChar32) 0x004A;
-                            destIndex=appendResult(dest, destIndex, destCapacity, c, s);
-                            titleLimit++;
+                const UChar *s;
+                c=ucase_toFullTitle(c, utf16_caseContextIterator, &csc, &s, caseLocale);
+                destIndex=appendResult(dest, destIndex, destCapacity, c, s,
+                                       titleLimit-titleStart, options, edits);
+                if(destIndex<0) {
+                    errorCode=U_INDEX_OUTOFBOUNDS_ERROR;
+                    return 0;
                 }
-
+                /* Special case Dutch IJ titlecasing */
+                if (titleStart+1 < index &&
+                        caseLocale == UCASE_LOC_DUTCH &&
+                        (src[titleStart] == 0x0049 || src[titleStart] == 0x0069)) {
+                    if (src[titleStart+1] == 0x006A) {
+                        destIndex=appendUChar(dest, destIndex, destCapacity, 0x004A);
+                        if(destIndex<0) {
+                            errorCode=U_INDEX_OUTOFBOUNDS_ERROR;
+                            return 0;
+                        }
+                        if(edits!=NULL) {
+                            edits->addReplace(1, 1);
+                        }
+                        titleLimit++;
+                    } else if (src[titleStart+1] == 0x004A) {
+                        // Keep the capital J from getting lowercased.
+                        destIndex=appendUnchanged(dest, destIndex, destCapacity,
+                                                  src+titleStart+1, 1, options, edits);
+                        if(destIndex<0) {
+                            errorCode=U_INDEX_OUTOFBOUNDS_ERROR;
+                            return 0;
+                        }
+                        titleLimit++;
+                    }
+                }
                 /* lowercase [titleLimit..index[ */
-                if(titleLimit<idx) {
-                    if((csm->options&U_TITLECASE_NO_LOWERCASE)==0) {
+                if(titleLimit<index) {
+                    if((options&U_TITLECASE_NO_LOWERCASE)==0) {
                         /* Normal operation: Lowercase the rest of the word. */
                         destIndex+=
-                            _caseMap(
-                                csm, ucase_toFullLower,
+                            toLower(
+                                caseLocale, options,
                                 dest+destIndex, destCapacity-destIndex,
-                                src, &csc,
-                                titleLimit, idx,
-                                pErrorCode);
+                                src, &csc, titleLimit, index,
+                                edits, errorCode);
+                        if(errorCode==U_BUFFER_OVERFLOW_ERROR) {
+                            errorCode=U_ZERO_ERROR;
+                        }
+                        if(U_FAILURE(errorCode)) {
+                            return destIndex;
+                        }
                     } else {
                         /* Optionally just copy the rest of the word unchanged. */
-                        length=idx-titleLimit;
-                        if((destIndex+length)<=destCapacity) {
-                            uprv_memcpy(dest+destIndex, src+titleLimit, length*U_SIZEOF_UCHAR);
+                        destIndex=appendUnchanged(dest, destIndex, destCapacity,
+                                                  src+titleLimit, index-titleLimit, options, edits);
+                        if(destIndex<0) {
+                            errorCode=U_INDEX_OUTOFBOUNDS_ERROR;
+                            return 0;
                         }
-                        destIndex+=length;
                     }
                 }
             }
         }
-
-        prev=idx;
+        prev=index;
     }
-
-    if(destIndex>destCapacity) {
-        *pErrorCode=U_BUFFER_OVERFLOW_ERROR;
-    }
-    return destIndex;
+    return checkOverflowAndEditsError(destIndex, destCapacity, edits, errorCode);
 }
-
 #endif  // !UCONFIG_NO_BREAK_ITERATION
-
 U_NAMESPACE_BEGIN
 namespace GreekUpper {
-
 // Data generated by prototype code, see
 // http://site.icu-project.org/design/case/greek-upper
 // TODO: Move this data into ucase.icu.
@@ -456,7 +667,6 @@
     0x03FE,
     0x03FF,
 };
-
 static const uint16_t data1F00[] = {
     // U+1F00..1FFF
     0x0391 | HAS_VOWEL,
@@ -716,10 +926,8 @@
     0,
     0,
 };
-
 // U+2126 Ohm sign
 static const uint16_t data2126 = 0x03A9 | HAS_VOWEL;
-
 uint32_t getLetterData(UChar32 c) {
     if (c < 0x370 || 0x2126 < c || (0x3ff < c && c < 0x1f00)) {
         return 0;
@@ -733,7 +941,6 @@
         return 0;
     }
 }
-
 uint32_t getDiacriticData(UChar32 c) {
     switch (c) {
     case 0x0300:  // varia
@@ -759,12 +966,11 @@
         return 0;
     }
 }
-
-UBool isFollowedByCasedLetter(const UCaseProps *csp, const UChar *s, int32_t i, int32_t length) {
+UBool isFollowedByCasedLetter(const UChar *s, int32_t i, int32_t length) {
     while (i < length) {
         UChar32 c;
         U16_NEXT(s, i, length, c);
-        int32_t type = ucase_getTypeOrIgnorable(csp, c);
+        int32_t type = ucase_getTypeOrIgnorable(c);
         if ((type & UCASE_IGNORABLE) != 0) {
             // Case-ignorable, continue with the loop.
         } else if (type != UCASE_NONE) {
@@ -775,18 +981,17 @@
     }
     return FALSE;  // Not followed by cased letter.
 }
-
 /**
  * Greek string uppercasing with a state machine.
  * Probably simpler than a stateless function that has to figure out complex context-before
  * for each character.
  * TODO: Try to re-consolidate one way or another with the non-Greek function.
  */
-int32_t toUpper(const UCaseMap *csm,
+int32_t toUpper(uint32_t options,
                 UChar *dest, int32_t destCapacity,
                 const UChar *src, int32_t srcLength,
-                UErrorCode *pErrorCode) {
-    int32_t locCache = UCASE_LOC_GREEK;
+                Edits *edits,
+                UErrorCode &errorCode) {
     int32_t destIndex=0;
     uint32_t state = 0;
     for (int32_t i = 0; i < srcLength;) {
@@ -794,7 +999,7 @@
         UChar32 c;
         U16_NEXT(src, nextIndex, srcLength, c);
         uint32_t nextState = 0;
-        int32_t type = ucase_getTypeOrIgnorable(csm->csp, c);
+        int32_t type = ucase_getTypeOrIgnorable(c);
         if ((type & UCASE_IGNORABLE) != 0) {
             // c is case-ignorable
             nextState |= (state & AFTER_CASED);
@@ -841,7 +1046,7 @@
                     (data & HAS_ACCENT) != 0 &&
                     numYpogegrammeni == 0 &&
                     (state & AFTER_CASED) == 0 &&
-                    !isFollowedByCasedLetter(csm->csp, src, nextIndex, srcLength)) {
+                    !isFollowedByCasedLetter(src, nextIndex, srcLength)) {
                 // Keep disjunctive "or" with (only) a tonos.
                 // We use the same "word boundary" conditions as for the Final_Sigma test.
                 if (i == nextIndex) {
@@ -859,128 +1064,132 @@
                     data &= ~HAS_EITHER_DIALYTIKA;
                 }
             }
-            destIndex=appendUChar(dest, destIndex, destCapacity, (UChar)upper);
-            if ((data & HAS_EITHER_DIALYTIKA) != 0) {
-                destIndex=appendUChar(dest, destIndex, destCapacity, 0x308);  // restore or add a dialytika
+            UBool change;
+            if (edits == nullptr && (options & U_OMIT_UNCHANGED_TEXT) == 0) {
+                change = TRUE;  // common, simple usage
+            } else {
+                // Find out first whether we are changing the text.
+                change = src[i] != upper || numYpogegrammeni > 0;
+                int32_t i2 = i + 1;
+                if ((data & HAS_EITHER_DIALYTIKA) != 0) {
+                    change |= i2 >= nextIndex || src[i2] != 0x308;
+                    ++i2;
+                }
+                if (addTonos) {
+                    change |= i2 >= nextIndex || src[i2] != 0x301;
+                    ++i2;
+                }
+                int32_t oldLength = nextIndex - i;
+                int32_t newLength = (i2 - i) + numYpogegrammeni;
+                change |= oldLength != newLength;
+                if (change) {
+                    if (edits != NULL) {
+                        edits->addReplace(oldLength, newLength);
+                    }
+                } else {
+                    if (edits != NULL) {
+                        edits->addUnchanged(oldLength);
+                    }
+                    // Write unchanged text?
+                    change = (options & U_OMIT_UNCHANGED_TEXT) == 0;
+                }
             }
-            if (addTonos) {
-                destIndex=appendUChar(dest, destIndex, destCapacity, 0x301);
-            }
-            while (numYpogegrammeni > 0) {
-                destIndex=appendUChar(dest, destIndex, destCapacity, 0x399);
-                --numYpogegrammeni;
+            if (change) {
+                destIndex=appendUChar(dest, destIndex, destCapacity, (UChar)upper);
+                if (destIndex >= 0 && (data & HAS_EITHER_DIALYTIKA) != 0) {
+                    destIndex=appendUChar(dest, destIndex, destCapacity, 0x308);  // restore or add a dialytika
+                }
+                if (destIndex >= 0 && addTonos) {
+                    destIndex=appendUChar(dest, destIndex, destCapacity, 0x301);
+                }
+                while (destIndex >= 0 && numYpogegrammeni > 0) {
+                    destIndex=appendUChar(dest, destIndex, destCapacity, 0x399);
+                    --numYpogegrammeni;
+                }
+                if(destIndex<0) {
+                    errorCode=U_INDEX_OUTOFBOUNDS_ERROR;
+                    return 0;
+                }
             }
         } else {
             const UChar *s;
-            UChar32 c2 = 0;
-            c=ucase_toFullUpper(csm->csp, c, NULL, NULL, &s, csm->locale, &locCache);
-            if((destIndex<destCapacity) && (c<0 ? (c2=~c)<=0xffff : UCASE_MAX_STRING_LENGTH<c && (c2=c)<=0xffff)) {
-                /* fast path version of appendResult() for BMP results */
-                dest[destIndex++]=(UChar)c2;
-            } else {
-                destIndex=appendResult(dest, destIndex, destCapacity, c, s);
+            c=ucase_toFullUpper(c, NULL, NULL, &s, UCASE_LOC_GREEK);
+            destIndex = appendResult(dest, destIndex, destCapacity, c, s,
+                                     nextIndex - i, options, edits);
+            if (destIndex < 0) {
+                errorCode = U_INDEX_OUTOFBOUNDS_ERROR;
+                return 0;
             }
         }
         i = nextIndex;
         state = nextState;
     }
-
-    if(destIndex>destCapacity) {
-        *pErrorCode=U_BUFFER_OVERFLOW_ERROR;
-    }
     return destIndex;
 }
-
 }  // namespace GreekUpper
 U_NAMESPACE_END
-
 /* functions available in the common library (for unistr_case.cpp) */
-
 U_CFUNC int32_t U_CALLCONV
-ustrcase_internalToLower(const UCaseMap *csm,
+ustrcase_internalToLower(int32_t caseLocale, uint32_t options, UCASEMAP_BREAK_ITERATOR_UNUSED
                          UChar *dest, int32_t destCapacity,
                          const UChar *src, int32_t srcLength,
-                         UErrorCode *pErrorCode) {
+                         icu::Edits *edits,
+                         UErrorCode &errorCode) {
     UCaseContext csc=UCASECONTEXT_INITIALIZER;
     csc.p=(void *)src;
     csc.limit=srcLength;
-    return _caseMap(
-        csm, ucase_toFullLower,
+    int32_t destIndex = toLower(
+        caseLocale, options,
         dest, destCapacity,
         src, &csc, 0, srcLength,
-        pErrorCode);
+        edits, errorCode);
+    return checkOverflowAndEditsError(destIndex, destCapacity, edits, errorCode);
 }
-
 U_CFUNC int32_t U_CALLCONV
-ustrcase_internalToUpper(const UCaseMap *csm,
+ustrcase_internalToUpper(int32_t caseLocale, uint32_t options, UCASEMAP_BREAK_ITERATOR_UNUSED
                          UChar *dest, int32_t destCapacity,
                          const UChar *src, int32_t srcLength,
-                         UErrorCode *pErrorCode) {
-    int32_t locCache = csm->locCache;
-    if (ucase_getCaseLocale(csm->locale, &locCache) == UCASE_LOC_GREEK) {
-        return GreekUpper::toUpper(csm, dest, destCapacity, src, srcLength, pErrorCode);
+                         icu::Edits *edits,
+                         UErrorCode &errorCode) {
+    int32_t destIndex;
+    if (caseLocale == UCASE_LOC_GREEK) {
+        destIndex = GreekUpper::toUpper(options, dest, destCapacity,
+                                        src, srcLength, edits, errorCode);
+    } else {
+        UCaseContext csc=UCASECONTEXT_INITIALIZER;
+        csc.p=(void *)src;
+        csc.limit=srcLength;
+        destIndex = toUpper(
+            caseLocale, options,
+            dest, destCapacity,
+            src, &csc, srcLength,
+            edits, errorCode);
     }
-    UCaseContext csc=UCASECONTEXT_INITIALIZER;
-    csc.p=(void *)src;
-    csc.limit=srcLength;
-    return _caseMap(
-        csm, ucase_toFullUpper,
-        dest, destCapacity,
-        src, &csc, 0, srcLength,
-        pErrorCode);
+    return checkOverflowAndEditsError(destIndex, destCapacity, edits, errorCode);
 }
-
-static int32_t
-ustr_foldCase(const UCaseProps *csp,
-              UChar *dest, int32_t destCapacity,
-              const UChar *src, int32_t srcLength,
-              uint32_t options,
-              UErrorCode *pErrorCode) {
-    int32_t srcIndex, destIndex;
-
-    const UChar *s;
-    UChar32 c, c2 = 0;
-
-    /* case mapping loop */
-    srcIndex=destIndex=0;
-    while(srcIndex<srcLength) {
-        U16_NEXT(src, srcIndex, srcLength, c);
-        c=ucase_toFullFolding(csp, c, &s, options);
-        if((destIndex<destCapacity) && (c<0 ? (c2=~c)<=0xffff : UCASE_MAX_STRING_LENGTH<c && (c2=c)<=0xffff)) {
-            /* fast path version of appendResult() for BMP results */
-            dest[destIndex++]=(UChar)c2;
-        } else {
-            destIndex=appendResult(dest, destIndex, destCapacity, c, s);
-        }
-    }
-
-    if(destIndex>destCapacity) {
-        *pErrorCode=U_BUFFER_OVERFLOW_ERROR;
-    }
-    return destIndex;
-}
-
 U_CFUNC int32_t U_CALLCONV
-ustrcase_internalFold(const UCaseMap *csm,
+ustrcase_internalFold(int32_t /* caseLocale */, uint32_t options, UCASEMAP_BREAK_ITERATOR_UNUSED
                       UChar *dest, int32_t destCapacity,
                       const UChar *src, int32_t srcLength,
-                      UErrorCode *pErrorCode) {
-    return ustr_foldCase(csm->csp, dest, destCapacity, src, srcLength, csm->options, pErrorCode);
+                      icu::Edits *edits,
+                      UErrorCode &errorCode) {
+    int32_t destIndex = toLower(
+        -1, options,
+        dest, destCapacity,
+        src, nullptr, 0, srcLength,
+        edits, errorCode);
+    return checkOverflowAndEditsError(destIndex, destCapacity, edits, errorCode);
 }
-
 U_CFUNC int32_t
-ustrcase_map(const UCaseMap *csm,
+ustrcase_map(int32_t caseLocale, uint32_t options, UCASEMAP_BREAK_ITERATOR_PARAM
              UChar *dest, int32_t destCapacity,
              const UChar *src, int32_t srcLength,
              UStringCaseMapper *stringCaseMapper,
-             UErrorCode *pErrorCode) {
-    UChar buffer[300];
-    UChar *temp;
-
+             icu::Edits *edits,
+             UErrorCode &errorCode) {
     int32_t destLength;
-
     /* check argument values */
-    if(U_FAILURE(*pErrorCode)) {
+    if(U_FAILURE(errorCode)) {
         return 0;
     }
     if( destCapacity<0 ||
@@ -988,15 +1197,53 @@
         src==NULL ||
         srcLength<-1
     ) {
-        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
+        errorCode=U_ILLEGAL_ARGUMENT_ERROR;
         return 0;
     }
-
     /* get the string length */
     if(srcLength==-1) {
         srcLength=u_strlen(src);
     }
-
+    /* check for overlapping source and destination */
+    if( dest!=NULL &&
+        ((src>=dest && src<(dest+destCapacity)) ||
+         (dest>=src && dest<(src+srcLength)))
+    ) {
+        errorCode=U_ILLEGAL_ARGUMENT_ERROR;
+        return 0;
+    }
+    if (edits != nullptr && (options & U_EDITS_NO_RESET) == 0) {
+        edits->reset();
+    }
+    destLength=stringCaseMapper(caseLocale, options, UCASEMAP_BREAK_ITERATOR
+                                dest, destCapacity, src, srcLength, edits, errorCode);
+    return u_terminateUChars(dest, destCapacity, destLength, &errorCode);
+}
+U_CFUNC int32_t
+ustrcase_mapWithOverlap(int32_t caseLocale, uint32_t options, UCASEMAP_BREAK_ITERATOR_PARAM
+                        UChar *dest, int32_t destCapacity,
+                        const UChar *src, int32_t srcLength,
+                        UStringCaseMapper *stringCaseMapper,
+                        UErrorCode &errorCode) {
+    UChar buffer[300];
+    UChar *temp;
+    int32_t destLength;
+    /* check argument values */
+    if(U_FAILURE(errorCode)) {
+        return 0;
+    }
+    if( destCapacity<0 ||
+        (dest==NULL && destCapacity>0) ||
+        src==NULL ||
+        srcLength<-1
+    ) {
+        errorCode=U_ILLEGAL_ARGUMENT_ERROR;
+        return 0;
+    }
+    /* get the string length */
+    if(srcLength==-1) {
+        srcLength=u_strlen(src);
+    }
     /* check for overlapping source and destination */
     if( dest!=NULL &&
         ((src>=dest && src<(dest+destCapacity)) ||
@@ -1010,50 +1257,52 @@
             /* allocate a buffer */
             temp=(UChar *)uprv_malloc(destCapacity*U_SIZEOF_UCHAR);
             if(temp==NULL) {
-                *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
+                errorCode=U_MEMORY_ALLOCATION_ERROR;
                 return 0;
             }
         }
     } else {
         temp=dest;
     }
-
-    destLength=stringCaseMapper(csm, temp, destCapacity, src, srcLength, pErrorCode);
+    destLength=stringCaseMapper(caseLocale, options, UCASEMAP_BREAK_ITERATOR
+                                temp, destCapacity, src, srcLength, NULL, errorCode);
     if(temp!=dest) {
         /* copy the result string to the destination buffer */
-        if(destLength>0) {
-            int32_t copyLength= destLength<=destCapacity ? destLength : destCapacity;
-            if(copyLength>0) {
-                uprv_memmove(dest, temp, copyLength*U_SIZEOF_UCHAR);
-            }
+        if (U_SUCCESS(errorCode) && 0 < destLength && destLength <= destCapacity) {
+            u_memmove(dest, temp, destLength);
         }
         if(temp!=buffer) {
             uprv_free(temp);
         }
     }
-
-    return u_terminateUChars(dest, destCapacity, destLength, pErrorCode);
+    return u_terminateUChars(dest, destCapacity, destLength, &errorCode);
 }
-
 /* public API functions */
-
 U_CAPI int32_t U_EXPORT2
 u_strFoldCase(UChar *dest, int32_t destCapacity,
               const UChar *src, int32_t srcLength,
               uint32_t options,
               UErrorCode *pErrorCode) {
-    UCaseMap csm=UCASEMAP_INITIALIZER;
-    csm.csp=ucase_getSingleton();
-    csm.options=options;
-    return ustrcase_map(
-        &csm,
+    return ustrcase_mapWithOverlap(
+        UCASE_LOC_ROOT, options, UCASEMAP_BREAK_ITERATOR_NULL
         dest, destCapacity,
         src, srcLength,
-        ustrcase_internalFold, pErrorCode);
+        ustrcase_internalFold, *pErrorCode);
 }
-
+U_NAMESPACE_BEGIN
+int32_t CaseMap::fold(
+        uint32_t options,
+        const UChar *src, int32_t srcLength,
+        UChar *dest, int32_t destCapacity, Edits *edits,
+        UErrorCode &errorCode) {
+    return ustrcase_map(
+        UCASE_LOC_ROOT, options, UCASEMAP_BREAK_ITERATOR_NULL
+        dest, destCapacity,
+        src, srcLength,
+        ustrcase_internalFold, edits, errorCode);
+}
+U_NAMESPACE_END
 /* case-insensitive string comparisons -------------------------------------- */
-
 /*
  * This function is a copy of unorm_cmpEquivFold() minus the parts for
  * canonical equivalence.
@@ -1062,13 +1311,11 @@
  * It makes caseless (but not canonical caseless) matches independent of
  * the normalization code.
  */
-
 /* stack element for previous-level source/decomposition pointers */
 struct CmpEquivLevel {
     const UChar *start, *s, *limit;
 };
 typedef struct CmpEquivLevel CmpEquivLevel;
-
 /**
  * Internal implementation code comparing string with case fold.
  * This function is called from u_strcmpFold() and u_caseInsensitivePrefixMatch().
@@ -1090,76 +1337,57 @@
             int32_t *matchLen1, int32_t *matchLen2,
             UErrorCode *pErrorCode) {
     int32_t cmpRes = 0;
-
-    const UCaseProps *csp;
-
     /* current-level start/limit - s1/s2 as current */
     const UChar *start1, *start2, *limit1, *limit2;
-
     /* points to the original start address */
     const UChar *org1, *org2;
-
     /* points to the end of match + 1 */
     const UChar *m1, *m2;
-
     /* case folding variables */
     const UChar *p;
     int32_t length;
-
     /* stacks of previous-level start/current/limit */
     CmpEquivLevel stack1[2], stack2[2];
-
     /* case folding buffers, only use current-level start/limit */
     UChar fold1[UCASE_MAX_STRING_LENGTH+1], fold2[UCASE_MAX_STRING_LENGTH+1];
-
     /* track which is the current level per string */
     int32_t level1, level2;
-
     /* current code units, and code points for lookups */
     UChar32 c1, c2, cp1, cp2;
-
     /* no argument error checking because this itself is not an API */
-
     /*
      * assume that at least the option U_COMPARE_IGNORE_CASE is set
      * otherwise this function would have to behave exactly as uprv_strCompare()
      */
-    csp=ucase_getSingleton();
     if(U_FAILURE(*pErrorCode)) {
         return 0;
     }
-
     /* initialize */
     if(matchLen1) {
         U_ASSERT(matchLen2 !=NULL);
         *matchLen1=0;
         *matchLen2=0;
     }
-
     start1=m1=org1=s1;
     if(length1==-1) {
         limit1=NULL;
     } else {
         limit1=s1+length1;
     }
-
     start2=m2=org2=s2;
     if(length2==-1) {
         limit2=NULL;
     } else {
         limit2=s2+length2;
     }
-
     level1=level2=0;
     c1=c2=-1;
-
     /* comparison loop */
     for(;;) {
         /*
          * here a code unit value of -1 means "get another code unit"
          * below it will mean "this source is finished"
          */
-
         if(c1<0) {
             /* get next code unit from string 1, post-increment */
             for(;;) {
@@ -1172,7 +1400,6 @@
                     ++s1;
                     break;
                 }
-
                 /* reached end of level buffer, pop one level */
                 do {
                     --level1;
@@ -1182,7 +1409,6 @@
                 limit1=stack1[level1].limit;        /*Not uninitialized*/
             }
         }
-
         if(c2<0) {
             /* get next code unit from string 2, post-increment */
             for(;;) {
@@ -1195,7 +1421,6 @@
                     ++s2;
                     break;
                 }
-
                 /* reached end of level buffer, pop one level */
                 do {
                     --level2;
@@ -1205,19 +1430,16 @@
                 limit2=stack2[level2].limit;        /*Not uninitialized*/
             }
         }
-
         /*
          * compare c1 and c2
          * either variable c1, c2 is -1 only if the corresponding string is finished
          */
         if(c1==c2) {
             const UChar *next1, *next2;
-
             if(c1<0) {
                 cmpRes=0;   /* c1==c2==-1 indicating end of strings */
                 break;
             }
-
             /*
              * Note: Move the match positions in both strings at the same time
              *      only when corresponding code point(s) in the original strings
@@ -1237,17 +1459,14 @@
                  *      code is at the end of all stacks.
                  */
                 U_ASSERT(level1==1);
-
                 /* is s1 at the end of the current stack? */
                 next1=stack1[0].s;
             }
-
             if (next1!=NULL) {
                 if(level2==0) {
                     next2=s2;
                 } else if(s2==limit2) {
                     U_ASSERT(level2==1);
-
                     /* is s2 at the end of the current stack? */
                     next2=stack2[0].s;
                 }
@@ -1266,12 +1485,10 @@
             break;
         }
         /* c1!=c2 && c1>=0 && c2>=0 */
-
         /* get complete code points for c1, c2 for lookups if either is a surrogate */
         cp1=c1;
         if(U_IS_SURROGATE(c1)) {
             UChar c;
-
             if(U_IS_SURROGATE_LEAD(c1)) {
                 if(s1!=limit1 && U16_IS_TRAIL(c=*s1)) {
                     /* advance ++s1; only below if cp1 decomposes/case-folds */
@@ -1283,11 +1500,9 @@
                 }
             }
         }
-
         cp2=c2;
         if(U_IS_SURROGATE(c2)) {
             UChar c;
-
             if(U_IS_SURROGATE_LEAD(c2)) {
                 if(s2!=limit2 && U16_IS_TRAIL(c=*s2)) {
                     /* advance ++s2; only below if cp2 decomposes/case-folds */
@@ -1299,14 +1514,12 @@
                 }
             }
         }
-
         /*
          * go down one level for each string
          * continue with the main loop as soon as there is a real change
          */
-
         if( level1==0 &&
-            (length=ucase_toFullFolding(csp, (UChar32)cp1, &p, options))>=0
+            (length=ucase_toFullFolding((UChar32)cp1, &p, options))>=0
         ) {
             /* cp1 case-folds to the code point "length" or to p[length] */
             if(U_IS_SURROGATE(c1)) {
@@ -1326,13 +1539,11 @@
                     c2=*(s2-1);
                 }
             }
-
             /* push current level pointers */
             stack1[0].start=start1;
             stack1[0].s=s1;
             stack1[0].limit=limit1;
             ++level1;
-
             /* copy the folding result to fold1[] */
             if(length<=UCASE_MAX_STRING_LENGTH) {
                 u_memcpy(fold1, p, length);
@@ -1341,18 +1552,15 @@
                 U16_APPEND_UNSAFE(fold1, i, length);
                 length=i;
             }
-
             /* set next level pointers to case folding */
             start1=s1=fold1;
             limit1=fold1+length;
-
             /* get ready to read from decomposition, continue with loop */
             c1=-1;
             continue;
         }
-
         if( level2==0 &&
-            (length=ucase_toFullFolding(csp, (UChar32)cp2, &p, options))>=0
+            (length=ucase_toFullFolding((UChar32)cp2, &p, options))>=0
         ) {
             /* cp2 case-folds to the code point "length" or to p[length] */
             if(U_IS_SURROGATE(c2)) {
@@ -1372,13 +1580,11 @@
                     c1=*(s1-1);
                 }
             }
-
             /* push current level pointers */
             stack2[0].start=start2;
             stack2[0].s=s2;
             stack2[0].limit=limit2;
             ++level2;
-
             /* copy the folding result to fold2[] */
             if(length<=UCASE_MAX_STRING_LENGTH) {
                 u_memcpy(fold2, p, length);
@@ -1387,16 +1593,13 @@
                 U16_APPEND_UNSAFE(fold2, i, length);
                 length=i;
             }
-
             /* set next level pointers to case folding */
             start2=s2=fold2;
             limit2=fold2+length;
-
             /* get ready to read from decomposition, continue with loop */
             c2=-1;
             continue;
         }
-
         /*
          * no decomposition/case folding, max level for both sides:
          * return difference result
@@ -1413,7 +1616,6 @@
          * except: uprv_strCompare() fetches c=*s while this functions fetches c=*s++
          * so we have slightly different pointer/start/limit comparisons here
          */
-
         if(c1>=0xd800 && c2>=0xd800 && (options&U_COMPARE_CODE_POINT_ORDER)) {
             /* subtract 0x2800 from BMP code points to make them smaller than supplementary ones */
             if(
@@ -1425,7 +1627,6 @@
                 /* BMP code point - may be surrogate code point - make <d800 */
                 c1-=0x2800;
             }
-
             if(
                 (c2<=0xdbff && s2!=limit2 && U16_IS_TRAIL(*s2)) ||
                 (U16_IS_TRAIL(c2) && start2!=(s2-1) && U16_IS_LEAD(*(s2-2)))
@@ -1436,18 +1637,15 @@
                 c2-=0x2800;
             }
         }
-
         cmpRes=c1-c2;
         break;
     }
-
     if(matchLen1) {
-        *matchLen1=m1-org1;
-        *matchLen2=m2-org2;
+        *matchLen1=static_cast<int32_t>(m1-org1);
+        *matchLen2=static_cast<int32_t>(m2-org2);
     }
     return cmpRes;
 }
-
 /* internal function */
 U_CFUNC int32_t
 u_strcmpFold(const UChar *s1, int32_t length1,
@@ -1456,9 +1654,7 @@
              UErrorCode *pErrorCode) {
     return _cmpFold(s1, length1, s2, length2, options, NULL, NULL, pErrorCode);
 }
-
 /* public API functions */
-
 U_CAPI int32_t U_EXPORT2
 u_strCaseCompare(const UChar *s1, int32_t length1,
                  const UChar *s2, int32_t length2,
@@ -1476,7 +1672,6 @@
                         options|U_COMPARE_IGNORE_CASE,
                         pErrorCode);
 }
-
 U_CAPI int32_t U_EXPORT2
 u_strcasecmp(const UChar *s1, const UChar *s2, uint32_t options) {
     UErrorCode errorCode=U_ZERO_ERROR;
@@ -1484,7 +1679,6 @@
                         options|U_COMPARE_IGNORE_CASE,
                         &errorCode);
 }
-
 U_CAPI int32_t U_EXPORT2
 u_memcasecmp(const UChar *s1, const UChar *s2, int32_t length, uint32_t options) {
     UErrorCode errorCode=U_ZERO_ERROR;
@@ -1492,7 +1686,6 @@
                         options|U_COMPARE_IGNORE_CASE,
                         &errorCode);
 }
-
 U_CAPI int32_t U_EXPORT2
 u_strncasecmp(const UChar *s1, const UChar *s2, int32_t n, uint32_t options) {
     UErrorCode errorCode=U_ZERO_ERROR;
@@ -1500,7 +1693,6 @@
                         options|(U_COMPARE_IGNORE_CASE|_STRNCMP_STYLE),
                         &errorCode);
 }
-
 /* internal API - detect length of shared prefix */
 U_CAPI void
 u_caseInsensitivePrefixMatch(const UChar *s1, int32_t length1,
diff --git a/src/third_party/icu/source/common/ustrcase_locale.cpp b/src/third_party/icu/source/common/ustrcase_locale.cpp
index 5707c5a..2ecd24f 100644
--- a/src/third_party/icu/source/common/ustrcase_locale.cpp
+++ b/src/third_party/icu/source/common/ustrcase_locale.cpp
@@ -1,10 +1,12 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *   Copyright (C) 2011, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *******************************************************************************
 *   file name:  ustrcase_locale.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -16,66 +18,24 @@
 */
 
 #include "unicode/utypes.h"
+#include "uassert.h"
+#include "unicode/brkiter.h"
+#include "unicode/casemap.h"
 #include "unicode/ucasemap.h"
 #include "unicode/uloc.h"
 #include "unicode/ustring.h"
 #include "ucase.h"
-#include "ustr_imp.h"
+#include "ucasemap_imp.h"
 
-U_CFUNC void
-ustrcase_setTempCaseMapLocale(UCaseMap *csm, const char *locale) {
-    /*
-     * We could call ucasemap_setLocale(), but here we really only care about
-     * the initial language subtag, we need not return the real string via
-     * ucasemap_getLocale(), and we don't care about only getting "x" from
-     * "x-some-thing" etc.
-     *
-     * We ignore locales with a longer-than-3 initial subtag.
-     *
-     * We also do not fill in the locCache because it is rarely used,
-     * and not worth setting unless we reuse it for many case mapping operations.
-     * (That's why UCaseMap was created.)
-     */
-    int i;
-    char c;
-
-    /* the internal functions require locale!=NULL */
-    if(locale==NULL) {
-        // Do not call uprv_getDefaultLocaleID() because that does not see
-        // changes to the default locale via uloc_setDefault().
-        // It would also be inefficient if used frequently because uprv_getDefaultLocaleID()
-        // does not cache the locale ID.
-        //
-        // Unfortunately, uloc_getDefault() has many dependencies.
-        // We only care about a small set of language subtags,
-        // and we do not need the locale ID to be canonicalized.
-        //
-        // Best is to not call case mapping functions with a NULL locale ID.
-        locale=uloc_getDefault();
+U_CFUNC int32_t
+ustrcase_getCaseLocale(const char *locale) {
+    if (locale == NULL) {
+        locale = uloc_getDefault();
     }
-    for(i=0; i<4 && (c=locale[i])!=0 && c!='-' && c!='_'; ++i) {
-        csm->locale[i]=c;
-    }
-    if(i<=3) {
-        csm->locale[i]=0;  /* Up to 3 non-separator characters. */
+    if (*locale == 0) {
+        return UCASE_LOC_ROOT;
     } else {
-        csm->locale[0]=0;  /* Longer-than-3 initial subtag: Ignore. */
-    }
-}
-
-/*
- * Set parameters on an empty UCaseMap, for UCaseMap-less API functions.
- * Do this fast because it is called with every function call.
- */
-static inline void
-setTempCaseMap(UCaseMap *csm, const char *locale) {
-    if(csm->csp==NULL) {
-        csm->csp=ucase_getSingleton();
-    }
-    if(locale!=NULL && locale[0]==0) {
-        csm->locale[0]=0;
-    } else {
-        ustrcase_setTempCaseMapLocale(csm, locale);
+        return ucase_getCaseLocale(locale);
     }
 }
 
@@ -86,13 +46,11 @@
              const UChar *src, int32_t srcLength,
              const char *locale,
              UErrorCode *pErrorCode) {
-    UCaseMap csm=UCASEMAP_INITIALIZER;
-    setTempCaseMap(&csm, locale);
-    return ustrcase_map(
-        &csm,
+    return ustrcase_mapWithOverlap(
+        ustrcase_getCaseLocale(locale), 0, UCASEMAP_BREAK_ITERATOR_NULL
         dest, destCapacity,
         src, srcLength,
-        ustrcase_internalToLower, pErrorCode);
+        ustrcase_internalToLower, *pErrorCode);
 }
 
 U_CAPI int32_t U_EXPORT2
@@ -100,11 +58,37 @@
              const UChar *src, int32_t srcLength,
              const char *locale,
              UErrorCode *pErrorCode) {
-    UCaseMap csm=UCASEMAP_INITIALIZER;
-    setTempCaseMap(&csm, locale);
-    return ustrcase_map(
-        &csm,
+    return ustrcase_mapWithOverlap(
+        ustrcase_getCaseLocale(locale), 0, UCASEMAP_BREAK_ITERATOR_NULL
         dest, destCapacity,
         src, srcLength,
-        ustrcase_internalToUpper, pErrorCode);
+        ustrcase_internalToUpper, *pErrorCode);
 }
+
+U_NAMESPACE_BEGIN
+
+int32_t CaseMap::toLower(
+        const char *locale, uint32_t options,
+        const UChar *src, int32_t srcLength,
+        UChar *dest, int32_t destCapacity, Edits *edits,
+        UErrorCode &errorCode) {
+    return ustrcase_map(
+        ustrcase_getCaseLocale(locale), options, UCASEMAP_BREAK_ITERATOR_NULL
+        dest, destCapacity,
+        src, srcLength,
+        ustrcase_internalToLower, edits, errorCode);
+}
+
+int32_t CaseMap::toUpper(
+        const char *locale, uint32_t options,
+        const UChar *src, int32_t srcLength,
+        UChar *dest, int32_t destCapacity, Edits *edits,
+        UErrorCode &errorCode) {
+    return ustrcase_map(
+        ustrcase_getCaseLocale(locale), options, UCASEMAP_BREAK_ITERATOR_NULL
+        dest, destCapacity,
+        src, srcLength,
+        ustrcase_internalToUpper, edits, errorCode);
+}
+
+U_NAMESPACE_END
diff --git a/src/third_party/icu/source/common/ustrenum.cpp b/src/third_party/icu/source/common/ustrenum.cpp
index cdf36b9..eb1660f 100644
--- a/src/third_party/icu/source/common/ustrenum.cpp
+++ b/src/third_party/icu/source/common/ustrenum.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
 * Copyright (c) 2002-2014, International Business Machines
@@ -8,7 +10,9 @@
 * Since: ICU 2.4
 **********************************************************************
 */
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
+#endif  // defined(STARBOARD)
 #include "utypeinfo.h"  // for 'typeid' to work 
 
 #include "unicode/ustring.h"
diff --git a/src/third_party/icu/source/common/ustrenum.h b/src/third_party/icu/source/common/ustrenum.h
index 3816dbf..a82162e 100644
--- a/src/third_party/icu/source/common/ustrenum.h
+++ b/src/third_party/icu/source/common/ustrenum.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
 * Copyright (c) 2002-2014, International Business Machines
diff --git a/src/third_party/icu/source/common/ustrfmt.c b/src/third_party/icu/source/common/ustrfmt.cpp
similarity index 93%
rename from src/third_party/icu/source/common/ustrfmt.c
rename to src/third_party/icu/source/common/ustrfmt.cpp
index 5e9fb92..1a9b15a 100644
--- a/src/third_party/icu/source/common/ustrfmt.c
+++ b/src/third_party/icu/source/common/ustrfmt.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
 *   Copyright (C) 2001-2006, International Business Machines
diff --git a/src/third_party/icu/source/common/ustrfmt.h b/src/third_party/icu/source/common/ustrfmt.h
index f1891bd..53eb055 100644
--- a/src/third_party/icu/source/common/ustrfmt.h
+++ b/src/third_party/icu/source/common/ustrfmt.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
 *   Copyright (C) 2001-2006, International Business Machines
diff --git a/src/third_party/icu/source/common/ustring.cpp b/src/third_party/icu/source/common/ustring.cpp
index c938530..032abe4 100644
--- a/src/third_party/icu/source/common/ustring.cpp
+++ b/src/third_party/icu/source/common/ustring.cpp
@@ -1,7 +1,9 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
-*   Copyright (C) 1998-2014, International Business Machines
+*   Copyright (C) 1998-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *
 ******************************************************************************
@@ -15,9 +17,12 @@
 ******************************************************************************
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/utypes.h"
 #include "unicode/putil.h"
+#include "unicode/uchar.h"
 #include "unicode/ustring.h"
 #include "unicode/utf16.h"
 #include "cstring.h"
@@ -43,7 +48,7 @@
         /* the leading edge of the match is in the middle of a surrogate pair */
         return FALSE;
     }
-    if(U16_IS_LEAD(*(matchLimit-1)) && match!=limit && U16_IS_TRAIL(*matchLimit)) {
+    if(U16_IS_LEAD(*(matchLimit-1)) && matchLimit!=limit && U16_IS_TRAIL(*matchLimit)) {
         /* the trailing edge of the match is in the middle of a surrogate pair */
         return FALSE;
     }
@@ -992,7 +997,7 @@
 u_strlen(const UChar *s) 
 {
 #if U_SIZEOF_WCHAR_T == U_SIZEOF_UCHAR
-    return (int32_t)uprv_wcslen(s);
+    return (int32_t)uprv_wcslen((const wchar_t *)s);
 #else
     const UChar *t = s;
     while(*t != 0) {
@@ -1114,7 +1119,7 @@
 U_CAPI UChar * U_EXPORT2
 u_memcpy(UChar *dest, const UChar *src, int32_t count) {
     if(count > 0) {
-        uprv_memcpy(dest, src, count*U_SIZEOF_UCHAR);
+        uprv_memcpy(dest, src, (size_t)count*U_SIZEOF_UCHAR);
     }
     return dest;
 }
@@ -1122,7 +1127,7 @@
 U_CAPI UChar * U_EXPORT2
 u_memmove(UChar *dest, const UChar *src, int32_t count) {
     if(count > 0) {
-        uprv_memmove(dest, src, count*U_SIZEOF_UCHAR);
+        uprv_memmove(dest, src, (size_t)count*U_SIZEOF_UCHAR);
     }
     return dest;
 }
@@ -1180,7 +1185,7 @@
     /*t*/ 0x74, 0x09,
     /*v*/ 0x76, 0x0b
 };
-enum { UNESCAPE_MAP_LENGTH = sizeof(UNESCAPE_MAP) / sizeof(UNESCAPE_MAP[0]) };
+enum { UNESCAPE_MAP_LENGTH = UPRV_LENGTHOF(UNESCAPE_MAP) };
 
 /* Convert one octal digit to a numeric value 0..7, or -1 on failure */
 static int8_t _digit8(UChar c) {
@@ -1292,7 +1297,15 @@
             int32_t ahead = *offset + 1;
             c = charAt(*offset, context);
             if (c == 0x5C /*'\\'*/ && ahead < length) {
-                c = (UChar) u_unescapeAt(charAt, &ahead, length, context);
+                // Calling u_unescapeAt recursively may cause a stack overflow if
+                // we have repeated surrogate lead after that. Limit the
+                // length to 5 ('u' and 4 hex) after ahead.
+                int32_t tailLimit = ahead + 5;
+                if (tailLimit > length) {
+                    tailLimit = length;
+                }
+                c = (UChar) u_unescapeAt(charAt, &ahead, tailLimit,
+                                         context);
             }
             if (U16_IS_TRAIL(c)) {
                 *offset = ahead;
@@ -1426,7 +1439,7 @@
  * NUL-terminate a string no matter what its type.
  * Set warning and error codes accordingly.
  */
-#define __TERMINATE_STRING(dest, destCapacity, length, pErrorCode)      \
+#define __TERMINATE_STRING(dest, destCapacity, length, pErrorCode) UPRV_BLOCK_MACRO_BEGIN { \
     if(pErrorCode!=NULL && U_SUCCESS(*pErrorCode)) {                    \
         /* not a public function, so no complete argument checking */   \
                                                                         \
@@ -1446,7 +1459,16 @@
             /* even the string itself did not fit - set an error code */ \
             *pErrorCode=U_BUFFER_OVERFLOW_ERROR;                        \
         }                                                               \
+    } \
+} UPRV_BLOCK_MACRO_END
+
+U_CAPI UChar U_EXPORT2
+u_asciiToUpper(UChar c) {
+    if (u'a' <= c && c <= u'z') {
+        c = c + u'A' - u'a';
     }
+    return c;
+}
 
 U_CAPI int32_t U_EXPORT2
 u_terminateUChars(UChar *dest, int32_t destCapacity, int32_t length, UErrorCode *pErrorCode) {
@@ -1486,7 +1508,7 @@
   the output range. [LIU]
 */
 
-#define STRING_HASH(TYPE, STR, STRLEN, DEREF) \
+#define STRING_HASH(TYPE, STR, STRLEN, DEREF) UPRV_BLOCK_MACRO_BEGIN { \
     uint32_t hash = 0;                        \
     const TYPE *p = (const TYPE*) STR;        \
     if (p != NULL) {                          \
@@ -1498,7 +1520,8 @@
             p += inc;                         \
         }                                     \
     }                                         \
-    return static_cast<int32_t>(hash)
+    return static_cast<int32_t>(hash);        \
+} UPRV_BLOCK_MACRO_END
 
 /* Used by UnicodeString to compute its hashcode - Not public API. */
 U_CAPI int32_t U_EXPORT2
diff --git a/src/third_party/icu/source/common/ustrtrns.cpp b/src/third_party/icu/source/common/ustrtrns.cpp
index 02c99aa..c1466a3 100644
--- a/src/third_party/icu/source/common/ustrtrns.cpp
+++ b/src/third_party/icu/source/common/ustrtrns.cpp
@@ -1,7 +1,9 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
-*   Copyright (C) 2001-2014, International Business Machines
+*   Copyright (C) 2001-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *
 ******************************************************************************
@@ -23,7 +25,9 @@
  *******************************************************************************
  */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/putil.h"
 #include "unicode/ustring.h"
 #include "unicode/utf.h"
@@ -254,148 +258,6 @@
             pErrorCode);
 }
 
-/* for utf8_nextCharSafeBodyTerminated() */
-static const UChar32
-utf8_minLegal[4]={ 0, 0x80, 0x800, 0x10000 };
-
-/*
- * Version of utf8_nextCharSafeBody() with the following differences:
- * - checks for NUL termination instead of length
- * - works with pointers instead of indexes
- * - always strict (strict==-1)
- *
- * *ps points to after the lead byte and will be moved to after the last trail byte.
- * c is the lead byte.
- * @return the code point, or U_SENTINEL
- */
-static UChar32
-utf8_nextCharSafeBodyTerminated(const uint8_t **ps, UChar32 c) {
-    const uint8_t *s=*ps;
-    uint8_t trail, illegal=0;
-    uint8_t count=U8_COUNT_TRAIL_BYTES(c);
-    U_ASSERT(count<6);
-    U8_MASK_LEAD_BYTE((c), count);
-    /* count==0 for illegally leading trail bytes and the illegal bytes 0xfe and 0xff */
-    switch(count) {
-    /* each branch falls through to the next one */
-    case 5:
-    case 4:
-        /* count>=4 is always illegal: no more than 3 trail bytes in Unicode's UTF-8 */
-        illegal=1;
-        break;
-    case 3:
-        trail=(uint8_t)(*s++ - 0x80);
-        c=(c<<6)|trail;
-        if(trail>0x3f || c>=0x110) {
-            /* not a trail byte, or code point>0x10ffff (outside Unicode) */
-            illegal=1;
-            break;
-        }
-    case 2: /*fall through*/
-        trail=(uint8_t)(*s++ - 0x80);
-        if(trail>0x3f) {
-            /* not a trail byte */
-            illegal=1;
-            break;
-        }
-        c=(c<<6)|trail;
-    case 1: /*fall through*/
-        trail=(uint8_t)(*s++ - 0x80);
-        if(trail>0x3f) {
-            /* not a trail byte */
-            illegal=1;
-        }
-        c=(c<<6)|trail;
-        break;
-    case 0:
-        return U_SENTINEL;
-    /* no default branch to optimize switch()  - all values are covered */
-    }
-
-    /* correct sequence - all trail bytes have (b7..b6)==(10)? */
-    /* illegal is also set if count>=4 */
-    if(illegal || c<utf8_minLegal[count] || U_IS_SURROGATE(c)) {
-        /* error handling */
-        /* don't go beyond this sequence */
-        s=*ps;
-        while(count>0 && U8_IS_TRAIL(*s)) {
-            ++s;
-            --count;
-        }
-        c=U_SENTINEL;
-    }
-    *ps=s;
-    return c;
-}
-
-/*
- * Version of utf8_nextCharSafeBody() with the following differences:
- * - works with pointers instead of indexes
- * - always strict (strict==-1)
- *
- * *ps points to after the lead byte and will be moved to after the last trail byte.
- * c is the lead byte.
- * @return the code point, or U_SENTINEL
- */
-static UChar32
-utf8_nextCharSafeBodyPointer(const uint8_t **ps, const uint8_t *limit, UChar32 c) {
-    const uint8_t *s=*ps;
-    uint8_t trail, illegal=0;
-    uint8_t count=U8_COUNT_TRAIL_BYTES(c);
-    if((limit-s)>=count) {
-        U8_MASK_LEAD_BYTE((c), count);
-        /* count==0 for illegally leading trail bytes and the illegal bytes 0xfe and 0xff */
-        switch(count) {
-        /* each branch falls through to the next one */
-        case 5:
-        case 4:
-            /* count>=4 is always illegal: no more than 3 trail bytes in Unicode's UTF-8 */
-            illegal=1;
-            break;
-        case 3:
-            trail=*s++;
-            c=(c<<6)|(trail&0x3f);
-            if(c<0x110) {
-                illegal|=(trail&0xc0)^0x80;
-            } else {
-                /* code point>0x10ffff, outside Unicode */
-                illegal=1;
-                break;
-            }
-        case 2: /*fall through*/
-            trail=*s++;
-            c=(c<<6)|(trail&0x3f);
-            illegal|=(trail&0xc0)^0x80;
-        case 1: /*fall through*/
-            trail=*s++;
-            c=(c<<6)|(trail&0x3f);
-            illegal|=(trail&0xc0)^0x80;
-            break;
-        case 0:
-            return U_SENTINEL;
-        /* no default branch to optimize switch()  - all values are covered */
-        }
-    } else {
-        illegal=1; /* too few bytes left */
-    }
-
-    /* correct sequence - all trail bytes have (b7..b6)==(10)? */
-    /* illegal is also set if count>=4 */
-    U_ASSERT(illegal || count<UPRV_LENGTHOF(utf8_minLegal));
-    if(illegal || c<utf8_minLegal[count] || U_IS_SURROGATE(c)) {
-        /* error handling */
-        /* don't go beyond this sequence */
-        s=*ps;
-        while(count>0 && s<limit && U8_IS_TRAIL(*s)) {
-            ++s;
-            --count;
-        }
-        c=U_SENTINEL;
-    }
-    *ps=s;
-    return c;
-}
-
 U_CAPI UChar* U_EXPORT2
 u_strFromUTF8WithSub(UChar *dest,
               int32_t destCapacity,
@@ -404,19 +266,10 @@
               int32_t srcLength,
               UChar32 subchar, int32_t *pNumSubstitutions,
               UErrorCode *pErrorCode){
-    UChar *pDest = dest;
-    UChar *pDestLimit = dest+destCapacity;
-    UChar32 ch;
-    int32_t reqLength = 0;
-    const uint8_t* pSrc = (const uint8_t*) src;
-    uint8_t t1, t2; /* trail bytes */
-    int32_t numSubstitutions;
-
     /* args check */
-    if(pErrorCode==NULL || U_FAILURE(*pErrorCode)){
+    if(U_FAILURE(*pErrorCode)) {
         return NULL;
     }
-        
     if( (src==NULL && srcLength!=0) || srcLength < -1 ||
         (destCapacity<0) || (dest == NULL && destCapacity > 0) ||
         subchar > 0x10ffff || U_IS_SURROGATE(subchar)
@@ -428,7 +281,10 @@
     if(pNumSubstitutions!=NULL) {
         *pNumSubstitutions=0;
     }
-    numSubstitutions=0;
+    UChar *pDest = dest;
+    UChar *pDestLimit = dest+destCapacity;
+    int32_t reqLength = 0;
+    int32_t numSubstitutions=0;
 
     /*
      * Inline processing of UTF-8 byte sequences:
@@ -449,95 +305,81 @@
          * The code explicitly checks for NULs only in the lead byte position.
          * A NUL byte in the trail byte position fails the trail byte range check anyway.
          */
-        while(((ch = *pSrc) != 0) && (pDest < pDestLimit)) {
-            if(ch <= 0x7f){
-                *pDest++=(UChar)ch;
-                ++pSrc;
+        int32_t i;
+        UChar32 c;
+        for(i = 0; (c = (uint8_t)src[i]) != 0 && (pDest < pDestLimit);) {
+            // modified copy of U8_NEXT()
+            ++i;
+            if(U8_IS_SINGLE(c)) {
+                *pDest++=(UChar)c;
             } else {
-                if(ch > 0xe0) {
-                    if( /* handle U+1000..U+CFFF inline */
-                        ch <= 0xec &&
-                        (t1 = (uint8_t)(pSrc[1] - 0x80)) <= 0x3f &&
-                        (t2 = (uint8_t)(pSrc[2] - 0x80)) <= 0x3f
-                    ) {
-                        /* no need for (ch & 0xf) because the upper bits are truncated after <<12 in the cast to (UChar) */
-                        *pDest++ = (UChar)((ch << 12) | (t1 << 6) | t2);
-                        pSrc += 3;
-                        continue;
-                    }
-                } else if(ch < 0xe0) {
-                    if( /* handle U+0080..U+07FF inline */
-                        ch >= 0xc2 &&
-                        (t1 = (uint8_t)(pSrc[1] - 0x80)) <= 0x3f
-                    ) {
-                        *pDest++ = (UChar)(((ch & 0x1f) << 6) | t1);
-                        pSrc += 2;
-                        continue;
-                    }
-                }
-
-                /* function call for "complicated" and error cases */
-                ++pSrc; /* continue after the lead byte */
-                ch=utf8_nextCharSafeBodyTerminated(&pSrc, ch);
-                if(ch<0 && (++numSubstitutions, ch = subchar) < 0) {
-                    *pErrorCode = U_INVALID_CHAR_FOUND;
-                    return NULL;
-                } else if(ch<=0xFFFF) {
-                    *(pDest++)=(UChar)ch;
+                uint8_t __t1, __t2;
+                if( /* handle U+0800..U+FFFF inline */
+                        (0xe0<=(c) && (c)<0xf0) &&
+                        U8_IS_VALID_LEAD3_AND_T1((c), src[i]) &&
+                        (__t2=src[(i)+1]-0x80)<=0x3f) {
+                    *pDest++ = (((c)&0xf)<<12)|((src[i]&0x3f)<<6)|__t2;
+                    i+=2;
+                } else if( /* handle U+0080..U+07FF inline */
+                        ((c)<0xe0 && (c)>=0xc2) &&
+                        (__t1=src[i]-0x80)<=0x3f) {
+                    *pDest++ = (((c)&0x1f)<<6)|__t1;
+                    ++(i);
                 } else {
-                    *(pDest++)=U16_LEAD(ch);
-                    if(pDest<pDestLimit) {
-                        *(pDest++)=U16_TRAIL(ch);
+                    /* function call for "complicated" and error cases */
+                    (c)=utf8_nextCharSafeBody((const uint8_t *)src, &(i), -1, c, -1);
+                    if(c<0 && (++numSubstitutions, c = subchar) < 0) {
+                        *pErrorCode = U_INVALID_CHAR_FOUND;
+                        return NULL;
+                    } else if(c<=0xFFFF) {
+                        *(pDest++)=(UChar)c;
                     } else {
-                        reqLength++;
-                        break;
+                        *(pDest++)=U16_LEAD(c);
+                        if(pDest<pDestLimit) {
+                            *(pDest++)=U16_TRAIL(c);
+                        } else {
+                            reqLength++;
+                            break;
+                        }
                     }
                 }
             }
         }
 
         /* Pre-flight the rest of the string. */
-        while((ch = *pSrc) != 0) {
-            if(ch <= 0x7f){
+        while((c = (uint8_t)src[i]) != 0) {
+            // modified copy of U8_NEXT()
+            ++i;
+            if(U8_IS_SINGLE(c)) {
                 ++reqLength;
-                ++pSrc;
             } else {
-                if(ch > 0xe0) {
-                    if( /* handle U+1000..U+CFFF inline */
-                        ch <= 0xec &&
-                        (uint8_t)(pSrc[1] - 0x80) <= 0x3f &&
-                        (uint8_t)(pSrc[2] - 0x80) <= 0x3f
-                    ) {
-                        ++reqLength;
-                        pSrc += 3;
-                        continue;
+                uint8_t __t1, __t2;
+                if( /* handle U+0800..U+FFFF inline */
+                        (0xe0<=(c) && (c)<0xf0) &&
+                        U8_IS_VALID_LEAD3_AND_T1((c), src[i]) &&
+                        (__t2=src[(i)+1]-0x80)<=0x3f) {
+                    ++reqLength;
+                    i+=2;
+                } else if( /* handle U+0080..U+07FF inline */
+                        ((c)<0xe0 && (c)>=0xc2) &&
+                        (__t1=src[i]-0x80)<=0x3f) {
+                    ++reqLength;
+                    ++(i);
+                } else {
+                    /* function call for "complicated" and error cases */
+                    (c)=utf8_nextCharSafeBody((const uint8_t *)src, &(i), -1, c, -1);
+                    if(c<0 && (++numSubstitutions, c = subchar) < 0) {
+                        *pErrorCode = U_INVALID_CHAR_FOUND;
+                        return NULL;
                     }
-                } else if(ch < 0xe0) {
-                    if( /* handle U+0080..U+07FF inline */
-                        ch >= 0xc2 &&
-                        (uint8_t)(pSrc[1] - 0x80) <= 0x3f
-                    ) {
-                        ++reqLength;
-                        pSrc += 2;
-                        continue;
-                    }
+                    reqLength += U16_LENGTH(c);
                 }
-
-                /* function call for "complicated" and error cases */
-                ++pSrc; /* continue after the lead byte */
-                ch=utf8_nextCharSafeBodyTerminated(&pSrc, ch);
-                if(ch<0 && (++numSubstitutions, ch = subchar) < 0) {
-                    *pErrorCode = U_INVALID_CHAR_FOUND;
-                    return NULL;
-                }
-                reqLength += U16_LENGTH(ch);
             }
         }
     } else /* srcLength >= 0 */ {
-        const uint8_t *pSrcLimit = pSrc + srcLength;
-        int32_t count;
-
-        /* Faster loop without ongoing checking for pSrcLimit and pDestLimit. */
+        /* Faster loop without ongoing checking for srcLength and pDestLimit. */
+        int32_t i = 0;
+        UChar32 c;
         for(;;) {
             /*
              * Each iteration of the inner loop progresses by at most 3 UTF-8
@@ -545,10 +387,10 @@
              * For supplementary code points (4 & 2), which are rare,
              * there is an additional adjustment.
              */
-            count = (int32_t)(pDestLimit - pDest);
-            srcLength = (int32_t)((pSrcLimit - pSrc) / 3);
-            if(count > srcLength) {
-                count = srcLength; /* min(remaining dest, remaining src/3) */
+            int32_t count = (int32_t)(pDestLimit - pDest);
+            int32_t count2 = (srcLength - i) / 3;
+            if(count > count2) {
+                count = count2; /* min(remaining dest, remaining src/3) */
             }
             if(count < 3) {
                 /*
@@ -559,147 +401,123 @@
             }
 
             do {
-                ch = *pSrc;
-                if(ch <= 0x7f){
-                    *pDest++=(UChar)ch;
-                    ++pSrc;
+                // modified copy of U8_NEXT()
+                c = (uint8_t)src[i++];
+                if(U8_IS_SINGLE(c)) {
+                    *pDest++=(UChar)c;
                 } else {
-                    if(ch > 0xe0) {
-                        if( /* handle U+1000..U+CFFF inline */
-                            ch <= 0xec &&
-                            (t1 = (uint8_t)(pSrc[1] - 0x80)) <= 0x3f &&
-                            (t2 = (uint8_t)(pSrc[2] - 0x80)) <= 0x3f
-                        ) {
-                            /* no need for (ch & 0xf) because the upper bits are truncated after <<12 in the cast to (UChar) */
-                            *pDest++ = (UChar)((ch << 12) | (t1 << 6) | t2);
-                            pSrc += 3;
-                            continue;
+                    uint8_t __t1, __t2;
+                    if( /* handle U+0800..U+FFFF inline */
+                            (0xe0<=(c) && (c)<0xf0) &&
+                            ((i)+1)<srcLength &&
+                            U8_IS_VALID_LEAD3_AND_T1((c), src[i]) &&
+                            (__t2=src[(i)+1]-0x80)<=0x3f) {
+                        *pDest++ = (((c)&0xf)<<12)|((src[i]&0x3f)<<6)|__t2;
+                        i+=2;
+                    } else if( /* handle U+0080..U+07FF inline */
+                            ((c)<0xe0 && (c)>=0xc2) &&
+                            ((i)!=srcLength) &&
+                            (__t1=src[i]-0x80)<=0x3f) {
+                        *pDest++ = (((c)&0x1f)<<6)|__t1;
+                        ++(i);
+                    } else {
+                        if(c >= 0xf0 || subchar > 0xffff) {
+                            // We may read up to four bytes and write up to two UChars,
+                            // which we didn't account for with computing count,
+                            // so we adjust it here.
+                            if(--count == 0) {
+                                --i;  // back out byte c
+                                break;
+                            }
                         }
-                    } else if(ch < 0xe0) {
-                        if( /* handle U+0080..U+07FF inline */
-                            ch >= 0xc2 &&
-                            (t1 = (uint8_t)(pSrc[1] - 0x80)) <= 0x3f
-                        ) {
-                            *pDest++ = (UChar)(((ch & 0x1f) << 6) | t1);
-                            pSrc += 2;
-                            continue;
-                        }
-                    }
 
-                    if(ch >= 0xf0 || subchar > 0xffff) {
-                        /*
-                         * We may read up to six bytes and write up to two UChars,
-                         * which we didn't account for with computing count,
-                         * so we adjust it here.
-                         */
-                        if(--count == 0) {
-                            break;
+                        /* function call for "complicated" and error cases */
+                        (c)=utf8_nextCharSafeBody((const uint8_t *)src, &(i), srcLength, c, -1);
+                        if(c<0 && (++numSubstitutions, c = subchar) < 0) {
+                            *pErrorCode = U_INVALID_CHAR_FOUND;
+                            return NULL;
+                        } else if(c<=0xFFFF) {
+                            *(pDest++)=(UChar)c;
+                        } else {
+                            *(pDest++)=U16_LEAD(c);
+                            *(pDest++)=U16_TRAIL(c);
                         }
                     }
-
-                    /* function call for "complicated" and error cases */
-                    ++pSrc; /* continue after the lead byte */
-                    ch=utf8_nextCharSafeBodyPointer(&pSrc, pSrcLimit, ch);
-                    if(ch<0 && (++numSubstitutions, ch = subchar) < 0){
-                        *pErrorCode = U_INVALID_CHAR_FOUND;
-                        return NULL;
-                    }else if(ch<=0xFFFF){
-                        *(pDest++)=(UChar)ch;
-                    }else{
-                        *(pDest++)=U16_LEAD(ch);
-                        *(pDest++)=U16_TRAIL(ch);
-                    }
                 }
             } while(--count > 0);
         }
 
-        while((pSrc<pSrcLimit) && (pDest<pDestLimit)) {
-            ch = *pSrc;
-            if(ch <= 0x7f){
-                *pDest++=(UChar)ch;
-                ++pSrc;
+        while(i < srcLength && (pDest < pDestLimit)) {
+            // modified copy of U8_NEXT()
+            c = (uint8_t)src[i++];
+            if(U8_IS_SINGLE(c)) {
+                *pDest++=(UChar)c;
             } else {
-                if(ch > 0xe0) {
-                    if( /* handle U+1000..U+CFFF inline */
-                        ch <= 0xec &&
-                        ((pSrcLimit - pSrc) >= 3) &&
-                        (t1 = (uint8_t)(pSrc[1] - 0x80)) <= 0x3f &&
-                        (t2 = (uint8_t)(pSrc[2] - 0x80)) <= 0x3f
-                    ) {
-                        /* no need for (ch & 0xf) because the upper bits are truncated after <<12 in the cast to (UChar) */
-                        *pDest++ = (UChar)((ch << 12) | (t1 << 6) | t2);
-                        pSrc += 3;
-                        continue;
-                    }
-                } else if(ch < 0xe0) {
-                    if( /* handle U+0080..U+07FF inline */
-                        ch >= 0xc2 &&
-                        ((pSrcLimit - pSrc) >= 2) &&
-                        (t1 = (uint8_t)(pSrc[1] - 0x80)) <= 0x3f
-                    ) {
-                        *pDest++ = (UChar)(((ch & 0x1f) << 6) | t1);
-                        pSrc += 2;
-                        continue;
-                    }
-                }
-
-                /* function call for "complicated" and error cases */
-                ++pSrc; /* continue after the lead byte */
-                ch=utf8_nextCharSafeBodyPointer(&pSrc, pSrcLimit, ch);
-                if(ch<0 && (++numSubstitutions, ch = subchar) < 0){
-                    *pErrorCode = U_INVALID_CHAR_FOUND;
-                    return NULL;
-                }else if(ch<=0xFFFF){
-                    *(pDest++)=(UChar)ch;
-                }else{
-                    *(pDest++)=U16_LEAD(ch);
-                    if(pDest<pDestLimit){
-                        *(pDest++)=U16_TRAIL(ch);
-                    }else{
-                        reqLength++;
-                        break;
+                uint8_t __t1, __t2;
+                if( /* handle U+0800..U+FFFF inline */
+                        (0xe0<=(c) && (c)<0xf0) &&
+                        ((i)+1)<srcLength &&
+                        U8_IS_VALID_LEAD3_AND_T1((c), src[i]) &&
+                        (__t2=src[(i)+1]-0x80)<=0x3f) {
+                    *pDest++ = (((c)&0xf)<<12)|((src[i]&0x3f)<<6)|__t2;
+                    i+=2;
+                } else if( /* handle U+0080..U+07FF inline */
+                        ((c)<0xe0 && (c)>=0xc2) &&
+                        ((i)!=srcLength) &&
+                        (__t1=src[i]-0x80)<=0x3f) {
+                    *pDest++ = (((c)&0x1f)<<6)|__t1;
+                    ++(i);
+                } else {
+                    /* function call for "complicated" and error cases */
+                    (c)=utf8_nextCharSafeBody((const uint8_t *)src, &(i), srcLength, c, -1);
+                    if(c<0 && (++numSubstitutions, c = subchar) < 0) {
+                        *pErrorCode = U_INVALID_CHAR_FOUND;
+                        return NULL;
+                    } else if(c<=0xFFFF) {
+                        *(pDest++)=(UChar)c;
+                    } else {
+                        *(pDest++)=U16_LEAD(c);
+                        if(pDest<pDestLimit) {
+                            *(pDest++)=U16_TRAIL(c);
+                        } else {
+                            reqLength++;
+                            break;
+                        }
                     }
                 }
             }
         }
-        /* do not fill the dest buffer just count the UChars needed */
-        while(pSrc < pSrcLimit){
-            ch = *pSrc;
-            if(ch <= 0x7f){
-                reqLength++;
-                ++pSrc;
-            } else {
-                if(ch > 0xe0) {
-                    if( /* handle U+1000..U+CFFF inline */
-                        ch <= 0xec &&
-                        ((pSrcLimit - pSrc) >= 3) &&
-                        (uint8_t)(pSrc[1] - 0x80) <= 0x3f &&
-                        (uint8_t)(pSrc[2] - 0x80) <= 0x3f
-                    ) {
-                        reqLength++;
-                        pSrc += 3;
-                        continue;
-                    }
-                } else if(ch < 0xe0) {
-                    if( /* handle U+0080..U+07FF inline */
-                        ch >= 0xc2 &&
-                        ((pSrcLimit - pSrc) >= 2) &&
-                        (uint8_t)(pSrc[1] - 0x80) <= 0x3f
-                    ) {
-                        reqLength++;
-                        pSrc += 2;
-                        continue;
-                    }
-                }
 
-                /* function call for "complicated" and error cases */
-                ++pSrc; /* continue after the lead byte */
-                ch=utf8_nextCharSafeBodyPointer(&pSrc, pSrcLimit, ch);
-                if(ch<0 && (++numSubstitutions, ch = subchar) < 0){
-                    *pErrorCode = U_INVALID_CHAR_FOUND;
-                    return NULL;
+        /* Pre-flight the rest of the string. */
+        while(i < srcLength) {
+            // modified copy of U8_NEXT()
+            c = (uint8_t)src[i++];
+            if(U8_IS_SINGLE(c)) {
+                ++reqLength;
+            } else {
+                uint8_t __t1, __t2;
+                if( /* handle U+0800..U+FFFF inline */
+                        (0xe0<=(c) && (c)<0xf0) &&
+                        ((i)+1)<srcLength &&
+                        U8_IS_VALID_LEAD3_AND_T1((c), src[i]) &&
+                        (__t2=src[(i)+1]-0x80)<=0x3f) {
+                    ++reqLength;
+                    i+=2;
+                } else if( /* handle U+0080..U+07FF inline */
+                        ((c)<0xe0 && (c)>=0xc2) &&
+                        ((i)!=srcLength) &&
+                        (__t1=src[i]-0x80)<=0x3f) {
+                    ++reqLength;
+                    ++(i);
+                } else {
+                    /* function call for "complicated" and error cases */
+                    (c)=utf8_nextCharSafeBody((const uint8_t *)src, &(i), srcLength, c, -1);
+                    if(c<0 && (++numSubstitutions, c = subchar) < 0) {
+                        *pErrorCode = U_INVALID_CHAR_FOUND;
+                        return NULL;
+                    }
+                    reqLength += U16_LENGTH(c);
                 }
-                reqLength+=U16_LENGTH(ch);
             }
         }
     }
@@ -747,7 +565,7 @@
     uint8_t* pSrc = (uint8_t*) src;
 
     /* args check */
-    if(pErrorCode==NULL || U_FAILURE(*pErrorCode)){
+    if(U_FAILURE(*pErrorCode)){
         return NULL;
     }
         
@@ -988,7 +806,7 @@
     int32_t numSubstitutions;
 
     /* args check */
-    if(pErrorCode==NULL || U_FAILURE(*pErrorCode)){
+    if(U_FAILURE(*pErrorCode)){
         return NULL;
     }
         
@@ -1260,18 +1078,8 @@
         int32_t srcLength,
         UChar32 subchar, int32_t *pNumSubstitutions,
         UErrorCode *pErrorCode) {
-    UChar *pDest = dest;
-    UChar *pDestLimit = dest+destCapacity;
-    UChar32 ch;
-    int32_t reqLength = 0;
-    const uint8_t* pSrc = (const uint8_t*) src;
-    const uint8_t *pSrcLimit;
-    int32_t count;
-    uint8_t t1, t2; /* trail bytes */
-    int32_t numSubstitutions;
-
     /* args check */
-    if(U_FAILURE(*pErrorCode)){
+    if(U_FAILURE(*pErrorCode)) {
         return NULL;
     }
     if( (src==NULL && srcLength!=0) || srcLength < -1 ||
@@ -1285,18 +1093,22 @@
     if(pNumSubstitutions!=NULL) {
         *pNumSubstitutions=0;
     }
-    numSubstitutions=0;
+    UChar *pDest = dest;
+    UChar *pDestLimit = dest+destCapacity;
+    int32_t reqLength = 0;
+    int32_t numSubstitutions=0;
 
     if(srcLength < 0) {
         /*
          * Transform a NUL-terminated ASCII string.
          * Handle non-ASCII strings with slower code.
          */
-        while(((ch = *pSrc) != 0) && ch <= 0x7f && (pDest < pDestLimit)) {
-            *pDest++=(UChar)ch;
-            ++pSrc;
+        UChar32 c;
+        while(((c = (uint8_t)*src) != 0) && c <= 0x7f && (pDest < pDestLimit)) {
+            *pDest++=(UChar)c;
+            ++src;
         }
-        if(ch == 0) {
+        if(c == 0) {
             reqLength=(int32_t)(pDest - dest);
             if(pDestLength) {
                 *pDestLength = reqLength;
@@ -1306,33 +1118,38 @@
             u_terminateUChars(dest, destCapacity, reqLength, pErrorCode);
             return dest;
         }
-        srcLength = uprv_strlen((const char *)pSrc);
+        srcLength = static_cast<int32_t>(uprv_strlen(src));
     }
 
-    /* Faster loop without ongoing checking for pSrcLimit and pDestLimit. */
-    pSrcLimit = (pSrc == NULL) ? NULL : pSrc + srcLength;
+    /* Faster loop without ongoing checking for srcLength and pDestLimit. */
+    UChar32 ch;
+    uint8_t t1, t2;
+    int32_t i = 0;
     for(;;) {
-        count = (int32_t)(pDestLimit - pDest);
-        srcLength = (int32_t)(pSrcLimit - pSrc);
-        if(count >= srcLength && srcLength > 0 && *pSrc <= 0x7f) {
+        int32_t count = (int32_t)(pDestLimit - pDest);
+        int32_t count2 = srcLength - i;
+        if(count >= count2 && srcLength > 0 && U8_IS_SINGLE(*src)) {
             /* fast ASCII loop */
-            const uint8_t *prevSrc = pSrc;
-            int32_t delta;
-            while(pSrc < pSrcLimit && (ch = *pSrc) <= 0x7f) {
-                *pDest++=(UChar)ch;
-                ++pSrc;
+            int32_t start = i;
+            uint8_t b;
+            while(i < srcLength && U8_IS_SINGLE(b = src[i])) {
+                *pDest++=b;
+                ++i;
             }
-            delta = (int32_t)(pSrc - prevSrc);
+            int32_t delta = i - start;
             count -= delta;
-            srcLength -= delta;
+            count2 -= delta;
         }
         /*
          * Each iteration of the inner loop progresses by at most 3 UTF-8
          * bytes and one UChar.
          */
-        srcLength /= 3;
-        if(count > srcLength) {
-            count = srcLength; /* min(remaining dest, remaining src/3) */
+        if(subchar > 0xFFFF) {
+            break;
+        }
+        count2 /= 3;
+        if(count > count2) {
+            count = count2; /* min(remaining dest, remaining src/3) */
         }
         if(count < 3) {
             /*
@@ -1342,29 +1159,28 @@
             break;
         }
         do {
-            ch = *pSrc;
-            if(ch <= 0x7f){
+            ch = (uint8_t)src[i++];
+            if(U8_IS_SINGLE(ch)) {
                 *pDest++=(UChar)ch;
-                ++pSrc;
             } else {
                 if(ch >= 0xe0) {
                     if( /* handle U+0000..U+FFFF inline */
                         ch <= 0xef &&
-                        (t1 = (uint8_t)(pSrc[1] - 0x80)) <= 0x3f &&
-                        (t2 = (uint8_t)(pSrc[2] - 0x80)) <= 0x3f
+                        (t1 = (uint8_t)(src[i] - 0x80)) <= 0x3f &&
+                        (t2 = (uint8_t)(src[i+1] - 0x80)) <= 0x3f
                     ) {
                         /* no need for (ch & 0xf) because the upper bits are truncated after <<12 in the cast to (UChar) */
                         *pDest++ = (UChar)((ch << 12) | (t1 << 6) | t2);
-                        pSrc += 3;
+                        i += 2;
                         continue;
                     }
                 } else {
                     if( /* handle U+0000..U+07FF inline */
                         ch >= 0xc0 &&
-                        (t1 = (uint8_t)(pSrc[1] - 0x80)) <= 0x3f
+                        (t1 = (uint8_t)(src[i] - 0x80)) <= 0x3f
                     ) {
                         *pDest++ = (UChar)(((ch & 0x1f) << 6) | t1);
-                        pSrc += 2;
+                        ++i;
                         continue;
                     }
                 }
@@ -1377,49 +1193,43 @@
                      * We need to write two UChars, adjusted count for that,
                      * and ran out of space.
                      */
+                    --i;  // back out byte ch
                     break;
                 } else {
                     /* function call for error cases */
-                    ++pSrc; /* continue after the lead byte */
-                    utf8_nextCharSafeBodyPointer(&pSrc, pSrcLimit, ch);
+                    utf8_nextCharSafeBody((const uint8_t *)src, &(i), srcLength, ch, -1);
                     ++numSubstitutions;
-                    if(subchar<=0xFFFF) {
-                        *(pDest++)=(UChar)subchar;
-                    } else {
-                        *(pDest++)=U16_LEAD(subchar);
-                        *(pDest++)=U16_TRAIL(subchar);
-                    }
+                    *(pDest++)=(UChar)subchar;
                 }
             }
         } while(--count > 0);
     }
 
-    while((pSrc<pSrcLimit) && (pDest<pDestLimit)) {
-        ch = *pSrc;
-        if(ch <= 0x7f){
+    while(i < srcLength && (pDest < pDestLimit)) {
+        ch = (uint8_t)src[i++];
+        if(U8_IS_SINGLE(ch)){
             *pDest++=(UChar)ch;
-            ++pSrc;
         } else {
             if(ch >= 0xe0) {
                 if( /* handle U+0000..U+FFFF inline */
                     ch <= 0xef &&
-                    ((pSrcLimit - pSrc) >= 3) &&
-                    (t1 = (uint8_t)(pSrc[1] - 0x80)) <= 0x3f &&
-                    (t2 = (uint8_t)(pSrc[2] - 0x80)) <= 0x3f
+                    (i+1) < srcLength &&
+                    (t1 = (uint8_t)(src[i] - 0x80)) <= 0x3f &&
+                    (t2 = (uint8_t)(src[i+1] - 0x80)) <= 0x3f
                 ) {
                     /* no need for (ch & 0xf) because the upper bits are truncated after <<12 in the cast to (UChar) */
                     *pDest++ = (UChar)((ch << 12) | (t1 << 6) | t2);
-                    pSrc += 3;
+                    i += 2;
                     continue;
                 }
             } else {
                 if( /* handle U+0000..U+07FF inline */
                     ch >= 0xc0 &&
-                    ((pSrcLimit - pSrc) >= 2) &&
-                    (t1 = (uint8_t)(pSrc[1] - 0x80)) <= 0x3f
+                    i < srcLength &&
+                    (t1 = (uint8_t)(src[i] - 0x80)) <= 0x3f
                 ) {
                     *pDest++ = (UChar)(((ch & 0x1f) << 6) | t1);
-                    pSrc += 2;
+                    ++i;
                     continue;
                 }
             }
@@ -1429,8 +1239,7 @@
                 return NULL;
             } else {
                 /* function call for error cases */
-                ++pSrc; /* continue after the lead byte */
-                utf8_nextCharSafeBodyPointer(&pSrc, pSrcLimit, ch);
+                utf8_nextCharSafeBody((const uint8_t *)src, &(i), srcLength, ch, -1);
                 ++numSubstitutions;
                 if(subchar<=0xFFFF) {
                     *(pDest++)=(UChar)subchar;
@@ -1447,32 +1256,31 @@
         }
     }
 
-    /* do not fill the dest buffer just count the UChars needed */
-    while(pSrc < pSrcLimit){
-        ch = *pSrc;
-        if(ch <= 0x7f) {
+    /* Pre-flight the rest of the string. */
+    while(i < srcLength) {
+        ch = (uint8_t)src[i++];
+        if(U8_IS_SINGLE(ch)) {
             reqLength++;
-            ++pSrc;
         } else {
             if(ch >= 0xe0) {
                 if( /* handle U+0000..U+FFFF inline */
                     ch <= 0xef &&
-                    ((pSrcLimit - pSrc) >= 3) &&
-                    (uint8_t)(pSrc[1] - 0x80) <= 0x3f &&
-                    (uint8_t)(pSrc[2] - 0x80) <= 0x3f
+                    (i+1) < srcLength &&
+                    (uint8_t)(src[i] - 0x80) <= 0x3f &&
+                    (uint8_t)(src[i+1] - 0x80) <= 0x3f
                 ) {
                     reqLength++;
-                    pSrc += 3;
+                    i += 2;
                     continue;
                 }
             } else {
                 if( /* handle U+0000..U+07FF inline */
                     ch >= 0xc0 &&
-                    ((pSrcLimit - pSrc) >= 2) &&
-                    (uint8_t)(pSrc[1] - 0x80) <= 0x3f
+                    i < srcLength &&
+                    (uint8_t)(src[i] - 0x80) <= 0x3f
                 ) {
                     reqLength++;
-                    pSrc += 2;
+                    ++i;
                     continue;
                 }
             }
@@ -1482,8 +1290,7 @@
                 return NULL;
             } else {
                 /* function call for error cases */
-                ++pSrc; /* continue after the lead byte */
-                utf8_nextCharSafeBodyPointer(&pSrc, pSrcLimit, ch);
+                utf8_nextCharSafeBody((const uint8_t *)src, &(i), srcLength, ch, -1);
                 ++numSubstitutions;
                 reqLength+=U16_LENGTH(ch);
             }
diff --git a/src/third_party/icu/source/common/utext.cpp b/src/third_party/icu/source/common/utext.cpp
index 01fa874..2b0dd26 100644
--- a/src/third_party/icu/source/common/utext.cpp
+++ b/src/third_party/icu/source/common/utext.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  utext.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -14,8 +16,13 @@
 *   created by: Markus W. Scherer
 */
 
+#include <cstddef>
+
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
+
 #include "unicode/utypes.h"
 #include "unicode/ustring.h"
 #include "unicode/unistr.h"
@@ -566,8 +573,8 @@
 //    when a provider asks for a UText to be allocated with extra storage.
 
 struct ExtendedUText {
-    UText          ut;
-    UAlignedMemory extension;
+    UText               ut;
+    std::max_align_t    extension;
 };
 
 static const UText emptyText = UTEXT_INITIALIZER;
@@ -582,7 +589,7 @@
         // We need to heap-allocate storage for the new UText
         int32_t spaceRequired = sizeof(UText);
         if (extraSpace > 0) {
-            spaceRequired = sizeof(ExtendedUText) + extraSpace - sizeof(UAlignedMemory);
+            spaceRequired = sizeof(ExtendedUText) + extraSpace - sizeof(std::max_align_t);
         }
         ut = (UText *)uprv_malloc(spaceRequired);
         if (ut == NULL) {
@@ -847,9 +854,11 @@
 //------------------------------------------------------------------------------
 
 // Chunk size.
-//     Must be less than 85, because of byte mapping from UChar indexes to native indexes.
+//     Must be less than 85 (256/3), because of byte mapping from UChar indexes to native indexes.
 //     Worst case is three native bytes to one UChar.  (Supplemenaries are 4 native bytes
 //     to two UChars.)
+//     The longest illegal byte sequence treated as a single error (and converted to U+FFFD)
+//     is a three-byte sequence (truncated four-byte sequence).
 //
 enum { UTF8_TEXT_CHUNK_SIZE=32 };
 
@@ -1032,6 +1041,7 @@
             // Requested index is in this buffer.
             u8b = (UTF8Buf *)ut->p;   // the current buffer
             mapIndex = ix - u8b->toUCharsMapStart;
+            U_ASSERT(mapIndex < (int32_t)sizeof(UTF8Buf::mapToUChars));
             ut->chunkOffset = u8b->mapToUChars[mapIndex] - u8b->bufStartIdx;
             return TRUE;
 
@@ -1193,9 +1203,9 @@
         // Swap the UText buffers.
         //  We want to fill what was previously the alternate buffer,
         //  and make what was the current buffer be the new alternate.
-        UTF8Buf *u8b = (UTF8Buf *)ut->q;
+        UTF8Buf *u8b_swap = (UTF8Buf *)ut->q;
         ut->q = ut->p;
-        ut->p = u8b;
+        ut->p = u8b_swap;
 
         int32_t strLen = ut->b;
         UBool   nulTerminated = FALSE;
@@ -1204,9 +1214,9 @@
             nulTerminated = TRUE;
         }
 
-        UChar   *buf = u8b->buf;
-        uint8_t *mapToNative  = u8b->mapToNative;
-        uint8_t *mapToUChars  = u8b->mapToUChars;
+        UChar   *buf = u8b_swap->buf;
+        uint8_t *mapToNative  = u8b_swap->mapToNative;
+        uint8_t *mapToUChars  = u8b_swap->mapToUChars;
         int32_t  destIx       = 0;
         int32_t  srcIx        = ix;
         UBool    seenNonAscii = FALSE;
@@ -1227,7 +1237,7 @@
                 // General case, handle everything.
                 if (seenNonAscii == FALSE) {
                     seenNonAscii = TRUE;
-                    u8b->bufNILimit = destIx;
+                    u8b_swap->bufNILimit = destIx;
                 }
 
                 int32_t  cIx      = srcIx;
@@ -1260,22 +1270,22 @@
         mapToUChars[srcIx - ix] = (uint8_t)destIx;
 
         //  fill in Buffer descriptor
-        u8b->bufNativeStart     = ix;
-        u8b->bufNativeLimit     = srcIx;
-        u8b->bufStartIdx        = 0;
-        u8b->bufLimitIdx        = destIx;
+        u8b_swap->bufNativeStart     = ix;
+        u8b_swap->bufNativeLimit     = srcIx;
+        u8b_swap->bufStartIdx        = 0;
+        u8b_swap->bufLimitIdx        = destIx;
         if (seenNonAscii == FALSE) {
-            u8b->bufNILimit     = destIx;
+            u8b_swap->bufNILimit     = destIx;
         }
-        u8b->toUCharsMapStart   = u8b->bufNativeStart;
+        u8b_swap->toUCharsMapStart   = u8b_swap->bufNativeStart;
 
         // Set UText chunk to refer to this buffer.
         ut->chunkContents       = buf;
         ut->chunkOffset         = 0;
-        ut->chunkLength         = u8b->bufLimitIdx;
-        ut->chunkNativeStart    = u8b->bufNativeStart;
-        ut->chunkNativeLimit    = u8b->bufNativeLimit;
-        ut->nativeIndexingLimit = u8b->bufNILimit;
+        ut->chunkLength         = u8b_swap->bufLimitIdx;
+        ut->chunkNativeStart    = u8b_swap->bufNativeStart;
+        ut->chunkNativeLimit    = u8b_swap->bufNativeLimit;
+        ut->nativeIndexingLimit = u8b_swap->bufNILimit;
 
         // For zero terminated strings, keep track of the maximum point
         //   scanned so far.
@@ -1298,20 +1308,27 @@
         // Can only do this if the incoming index is somewhere in the interior of the string.
         //   If index is at the end, there is no character there to look at.
         if (ix != ut->b) {
+            // Note: this function will only move the index back if it is on a trail byte
+            //       and there is a preceding lead byte and the sequence from the lead 
+            //       through this trail could be part of a valid UTF-8 sequence
+            //       Otherwise the index remains unchanged.
             U8_SET_CP_START(s8, 0, ix);
         }
 
         // Swap the UText buffers.
         //  We want to fill what was previously the alternate buffer,
         //  and make what was the current buffer be the new alternate.
-        UTF8Buf *u8b = (UTF8Buf *)ut->q;
+        UTF8Buf *u8b_swap = (UTF8Buf *)ut->q;
         ut->q = ut->p;
-        ut->p = u8b;
+        ut->p = u8b_swap;
 
-        UChar   *buf = u8b->buf;
-        uint8_t *mapToNative = u8b->mapToNative;
-        uint8_t *mapToUChars = u8b->mapToUChars;
-        int32_t  toUCharsMapStart = ix - (UTF8_TEXT_CHUNK_SIZE*3 + 1);
+        UChar   *buf = u8b_swap->buf;
+        uint8_t *mapToNative = u8b_swap->mapToNative;
+        uint8_t *mapToUChars = u8b_swap->mapToUChars;
+        int32_t  toUCharsMapStart = ix - sizeof(UTF8Buf::mapToUChars) + 1;
+        // Note that toUCharsMapStart can be negative. Happens when the remaining
+        // text from current position to the beginning is less than the buffer size.
+        // + 1 because mapToUChars must have a slot at the end for the bufNativeLimit entry.
         int32_t  destIx = UTF8_TEXT_CHUNK_SIZE+2;   // Start in the overflow region
                                                     //   at end of buffer to leave room
                                                     //   for a surrogate pair at the
@@ -1338,6 +1355,7 @@
             if (c<0x80) {
                 // Special case ASCII range for speed.
                 buf[destIx] = (UChar)c;
+                U_ASSERT(toUCharsMapStart <= srcIx);
                 mapToUChars[srcIx - toUCharsMapStart] = (uint8_t)destIx;
                 mapToNative[destIx] = (uint8_t)(srcIx - toUCharsMapStart);
             } else {
@@ -1367,6 +1385,7 @@
                 do {
                     mapToUChars[sIx-- - toUCharsMapStart] = (uint8_t)destIx;
                 } while (sIx >= srcIx);
+                U_ASSERT(toUCharsMapStart <= (srcIx+1));
 
                 // Set native indexing limit to be the current position.
                 //   We are processing a non-ascii, non-native-indexing char now;
@@ -1375,19 +1394,19 @@
                 bufNILimit = destIx;
             }
         }
-        u8b->bufNativeStart     = srcIx;
-        u8b->bufNativeLimit     = ix;
-        u8b->bufStartIdx        = destIx;
-        u8b->bufLimitIdx        = UTF8_TEXT_CHUNK_SIZE+2;
-        u8b->bufNILimit         = bufNILimit - u8b->bufStartIdx;
-        u8b->toUCharsMapStart   = toUCharsMapStart;
+        u8b_swap->bufNativeStart     = srcIx;
+        u8b_swap->bufNativeLimit     = ix;
+        u8b_swap->bufStartIdx        = destIx;
+        u8b_swap->bufLimitIdx        = UTF8_TEXT_CHUNK_SIZE+2;
+        u8b_swap->bufNILimit         = bufNILimit - u8b_swap->bufStartIdx;
+        u8b_swap->toUCharsMapStart   = toUCharsMapStart;
 
-        ut->chunkContents       = &buf[u8b->bufStartIdx];
-        ut->chunkLength         = u8b->bufLimitIdx - u8b->bufStartIdx;
+        ut->chunkContents       = &buf[u8b_swap->bufStartIdx];
+        ut->chunkLength         = u8b_swap->bufLimitIdx - u8b_swap->bufStartIdx;
         ut->chunkOffset         = ut->chunkLength;
-        ut->chunkNativeStart    = u8b->bufNativeStart;
-        ut->chunkNativeLimit    = u8b->bufNativeLimit;
-        ut->nativeIndexingLimit = u8b->bufNILimit;
+        ut->chunkNativeStart    = u8b_swap->bufNativeStart;
+        ut->chunkNativeLimit    = u8b_swap->bufNativeLimit;
+        ut->nativeIndexingLimit = u8b_swap->bufNILimit;
         return TRUE;
     }
 
@@ -1541,6 +1560,7 @@
     U_ASSERT(index>=ut->chunkNativeStart+ut->nativeIndexingLimit);
     U_ASSERT(index<=ut->chunkNativeLimit);
     int32_t mapIndex = index - u8b->toUCharsMapStart;
+    U_ASSERT(mapIndex < (int32_t)sizeof(UTF8Buf::mapToUChars));
     int32_t offset = u8b->mapToUChars[mapIndex] - u8b->bufStartIdx;
     U_ASSERT(offset>=0 && offset<=ut->chunkLength);
     return offset;
@@ -2225,13 +2245,13 @@
     }
 
     if(move) {
-        // move: copy to destIndex, then replace original with nothing
+        // move: copy to destIndex, then remove original
         int32_t segLength=limit32-start32;
         us->copy(start32, limit32, destIndex32);
         if(destIndex32<start32) {
             start32+=segLength;
         }
-        us->replace(start32, segLength, NULL, 0);
+        us->remove(start32, segLength);
     } else {
         // copy
         us->copy(start32, limit32, destIndex32);
diff --git a/src/third_party/icu/source/common/utf_impl.c b/src/third_party/icu/source/common/utf_impl.c
deleted file mode 100644
index c9fad64..0000000
--- a/src/third_party/icu/source/common/utf_impl.c
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
-******************************************************************************
-*
-*   Copyright (C) 1999-2012, International Business Machines
-*   Corporation and others.  All Rights Reserved.
-*
-******************************************************************************
-*   file name:  utf_impl.c
-*   encoding:   US-ASCII
-*   tab size:   8 (not used)
-*   indentation:4
-*
-*   created on: 1999sep13
-*   created by: Markus W. Scherer
-*
-*   This file provides implementation functions for macros in the utfXX.h
-*   that would otherwise be too long as macros.
-*/
-
-/* set import/export definitions */
-#include "starboard/client_porting/poem/assert_poem.h"
-#ifndef U_UTF8_IMPL
-#   define U_UTF8_IMPL
-#endif
-
-#include "unicode/utypes.h"
-#include "unicode/utf.h"
-#include "unicode/utf8.h"
-#include "unicode/utf_old.h"
-#include "uassert.h"
-
-/*
- * This table could be replaced on many machines by
- * a few lines of assembler code using an
- * "index of first 0-bit from msb" instruction and
- * one or two more integer instructions.
- *
- * For example, on an i386, do something like
- * - MOV AL, leadByte
- * - NOT AL         (8-bit, leave b15..b8==0..0, reverse only b7..b0)
- * - MOV AH, 0
- * - BSR BX, AX     (16-bit)
- * - MOV AX, 6      (result)
- * - JZ finish      (ZF==1 if leadByte==0xff)
- * - SUB AX, BX (result)
- * -finish:
- * (BSR: Bit Scan Reverse, scans for a 1-bit, starting from the MSB)
- *
- * In Unicode, all UTF-8 byte sequences with more than 4 bytes are illegal;
- * lead bytes above 0xf4 are illegal.
- * We keep them in this table for skipping long ISO 10646-UTF-8 sequences.
- */
-U_EXPORT const uint8_t 
-utf8_countTrailBytes[256]={
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-    3, 3, 3, 3, 3,
-    3, 3, 3,    /* illegal in Unicode */
-    4, 4, 4, 4, /* illegal in Unicode */
-    5, 5,       /* illegal in Unicode */
-    0, 0        /* illegal bytes 0xfe and 0xff */
-};
-
-static const UChar32
-utf8_minLegal[4]={ 0, 0x80, 0x800, 0x10000 };
-
-static const UChar32
-utf8_errorValue[6]={
-    UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_2, UTF_ERROR_VALUE, 0x10ffff,
-    0x3ffffff, 0x7fffffff
-};
-
-static UChar32
-errorValue(int32_t count, int8_t strict) {
-    if(strict>=0) {
-        return utf8_errorValue[count];
-    } else if(strict==-3) {
-        return 0xfffd;
-    } else {
-        return U_SENTINEL;
-    }
-}
-
-/*
- * Handle the non-inline part of the U8_NEXT() and U8_NEXT_FFFD() macros
- * and their obsolete sibling UTF8_NEXT_CHAR_SAFE().
- *
- * U8_NEXT() supports NUL-terminated strings indicated via length<0.
- *
- * The "strict" parameter controls the error behavior:
- * <0  "Safe" behavior of U8_NEXT():
- *     -1: All illegal byte sequences yield U_SENTINEL=-1.
- *     -2: Same as -1, except for lenient treatment of surrogate code points as legal.
- *         Some implementations use this for roundtripping of
- *         Unicode 16-bit strings that are not well-formed UTF-16, that is, they
- *         contain unpaired surrogates.
- *     -3: All illegal byte sequences yield U+FFFD.
- *  0  Obsolete "safe" behavior of UTF8_NEXT_CHAR_SAFE(..., FALSE):
- *     All illegal byte sequences yield a positive code point such that this
- *     result code point would be encoded with the same number of bytes as
- *     the illegal sequence.
- * >0  Obsolete "strict" behavior of UTF8_NEXT_CHAR_SAFE(..., TRUE):
- *     Same as the obsolete "safe" behavior, but non-characters are also treated
- *     like illegal sequences.
- *
- * Note that a UBool is the same as an int8_t.
- */
-U_CAPI UChar32 U_EXPORT2
-utf8_nextCharSafeBody(const uint8_t *s, int32_t *pi, int32_t length, UChar32 c, UBool strict) {
-    int32_t i=*pi;
-    uint8_t count=U8_COUNT_TRAIL_BYTES(c);
-    U_ASSERT(count <= 5); /* U8_COUNT_TRAIL_BYTES returns value 0...5 */
-    if(i+count<=length || length<0) {
-        uint8_t trail;
-
-        U8_MASK_LEAD_BYTE(c, count);
-        /* support NUL-terminated strings: do not read beyond the first non-trail byte */
-        switch(count) {
-        /* each branch falls through to the next one */
-        case 0:
-            /* count==0 for illegally leading trail bytes and the illegal bytes 0xfe and 0xff */
-        case 5:
-        case 4:
-            /* count>=4 is always illegal: no more than 3 trail bytes in Unicode's UTF-8 */
-            break;
-        case 3:
-            trail=s[i++]-0x80;
-            c=(c<<6)|trail;
-            /* c>=0x110 would result in code point>0x10ffff, outside Unicode */
-            if(c>=0x110 || trail>0x3f) { break; }
-        case 2:
-            trail=s[i++]-0x80;
-            c=(c<<6)|trail;
-            /*
-             * test for a surrogate d800..dfff unless we are lenient:
-             * before the last (c<<6), a surrogate is c=360..37f
-             */
-            if(((c&0xffe0)==0x360 && strict!=-2) || trail>0x3f) { break; }
-        case 1:
-            trail=s[i++]-0x80;
-            c=(c<<6)|trail;
-            if(trail>0x3f) { break; }
-            /* correct sequence - all trail bytes have (b7..b6)==(10) */
-            if(c>=utf8_minLegal[count] &&
-                    /* strict: forbid non-characters like U+fffe */
-                    (strict<=0 || !U_IS_UNICODE_NONCHAR(c))) {
-                *pi=i;
-                return c;
-            }
-        /* no default branch to optimize switch()  - all values are covered */
-        }
-    } else {
-        /* too few bytes left */
-        count=length-i;
-    }
-
-    /* error handling */
-    i=*pi;
-    while(count>0 && U8_IS_TRAIL(s[i])) {
-        ++i;
-        --count;
-    }
-    c=errorValue(i-*pi, strict);
-    *pi=i;
-    return c;
-}
-
-U_CAPI int32_t U_EXPORT2
-utf8_appendCharSafeBody(uint8_t *s, int32_t i, int32_t length, UChar32 c, UBool *pIsError) {
-    if((uint32_t)(c)<=0x7ff) {
-        if((i)+1<(length)) {
-            (s)[(i)++]=(uint8_t)(((c)>>6)|0xc0);
-            (s)[(i)++]=(uint8_t)(((c)&0x3f)|0x80);
-            return i;
-        }
-    } else if((uint32_t)(c)<=0xffff) {
-        /* Starting with Unicode 3.2, surrogate code points must not be encoded in UTF-8. */
-        if((i)+2<(length) && !U_IS_SURROGATE(c)) {
-            (s)[(i)++]=(uint8_t)(((c)>>12)|0xe0);
-            (s)[(i)++]=(uint8_t)((((c)>>6)&0x3f)|0x80);
-            (s)[(i)++]=(uint8_t)(((c)&0x3f)|0x80);
-            return i;
-        }
-    } else if((uint32_t)(c)<=0x10ffff) {
-        if((i)+3<(length)) {
-            (s)[(i)++]=(uint8_t)(((c)>>18)|0xf0);
-            (s)[(i)++]=(uint8_t)((((c)>>12)&0x3f)|0x80);
-            (s)[(i)++]=(uint8_t)((((c)>>6)&0x3f)|0x80);
-            (s)[(i)++]=(uint8_t)(((c)&0x3f)|0x80);
-            return i;
-        }
-    }
-    /* c>0x10ffff or not enough space, write an error value */
-    if(pIsError!=NULL) {
-        *pIsError=TRUE;
-    } else {
-        length-=i;
-        if(length>0) {
-            int32_t offset;
-            if(length>3) {
-                length=3;
-            }
-            s+=i;
-            offset=0;
-            c=utf8_errorValue[length-1];
-            UTF8_APPEND_CHAR_UNSAFE(s, offset, c);
-            i=i+offset;
-        }
-    }
-    return i;
-}
-
-U_CAPI UChar32 U_EXPORT2
-utf8_prevCharSafeBody(const uint8_t *s, int32_t start, int32_t *pi, UChar32 c, UBool strict) {
-    int32_t i=*pi;
-    uint8_t b, count=1, shift=6;
-
-    if(!U8_IS_TRAIL(c)) { return errorValue(0, strict); }
-
-    /* extract value bits from the last trail byte */
-    c&=0x3f;
-
-    for(;;) {
-        if(i<=start) {
-            /* no lead byte at all */
-            return errorValue(0, strict);
-        }
-
-        /* read another previous byte */
-        b=s[--i];
-        if((uint8_t)(b-0x80)<0x7e) { /* 0x80<=b<0xfe */
-            if(b&0x40) {
-                /* lead byte, this will always end the loop */
-                uint8_t shouldCount=U8_COUNT_TRAIL_BYTES(b);
-
-                if(count==shouldCount) {
-                    /* set the new position */
-                    *pi=i;
-                    U8_MASK_LEAD_BYTE(b, count);
-                    c|=(UChar32)b<<shift;
-                    if(count>=4 || c>0x10ffff || c<utf8_minLegal[count] || (U_IS_SURROGATE(c) && strict!=-2) || (strict>0 && U_IS_UNICODE_NONCHAR(c))) {
-                        /* illegal sequence or (strict and non-character) */
-                        if(count>=4) {
-                            count=3;
-                        }
-                        c=errorValue(count, strict);
-                    } else {
-                        /* exit with correct c */
-                    }
-                } else {
-                    /* the lead byte does not match the number of trail bytes */
-                    /* only set the position to the lead byte if it would
-                       include the trail byte that we started with */
-                    if(count<shouldCount) {
-                        *pi=i;
-                        c=errorValue(count, strict);
-                    } else {
-                        c=errorValue(0, strict);
-                    }
-                }
-                break;
-            } else if(count<5) {
-                /* trail byte */
-                c|=(UChar32)(b&0x3f)<<shift;
-                ++count;
-                shift+=6;
-            } else {
-                /* more than 5 trail bytes is illegal */
-                c=errorValue(0, strict);
-                break;
-            }
-        } else {
-            /* single-byte character precedes trailing bytes */
-            c=errorValue(0, strict);
-            break;
-        }
-    }
-    return c;
-}
-
-U_CAPI int32_t U_EXPORT2
-utf8_back1SafeBody(const uint8_t *s, int32_t start, int32_t i) {
-    /* i had been decremented once before the function call */
-    int32_t I=i, Z;
-    uint8_t b;
-
-    /* read at most the 6 bytes s[Z] to s[i], inclusively */
-    if(I-5>start) {
-        Z=I-5;
-    } else {
-        Z=start;
-    }
-
-    /* return I if the sequence starting there is long enough to include i */
-    do {
-        b=s[I];
-        if((uint8_t)(b-0x80)>=0x7e) { /* not 0x80<=b<0xfe */
-            break;
-        } else if(b>=0xc0) {
-            if(U8_COUNT_TRAIL_BYTES(b)>=(i-I)) {
-                return I;
-            } else {
-                break;
-            }
-        }
-    } while(Z<=--I);
-
-    /* return i itself to be consistent with the FWD_1 macro */
-    return i;
-}
diff --git a/src/third_party/icu/source/common/utf_impl.cpp b/src/third_party/icu/source/common/utf_impl.cpp
new file mode 100644
index 0000000..bcdb98e
--- /dev/null
+++ b/src/third_party/icu/source/common/utf_impl.cpp
@@ -0,0 +1,332 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+/*
+******************************************************************************
+*
+*   Copyright (C) 1999-2012, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+******************************************************************************
+*   file name:  utf_impl.cpp
+*   encoding:   UTF-8
+*   tab size:   8 (not used)
+*   indentation:4
+*
+*   created on: 1999sep13
+*   created by: Markus W. Scherer
+*
+*   This file provides implementation functions for macros in the utfXX.h
+*   that would otherwise be too long as macros.
+*/
+
+/* set import/export definitions */
+#if defined(STARBOARD)
+#include "starboard/client_porting/poem/assert_poem.h"
+#endif  // defined(STARBOARD)
+#ifndef U_UTF8_IMPL
+#   define U_UTF8_IMPL
+#endif
+
+#include "unicode/utypes.h"
+#include "unicode/utf.h"
+#include "unicode/utf8.h"
+#include "uassert.h"
+
+/*
+ * Table of the number of utf8 trail bytes, indexed by the lead byte.
+ * Used by the deprecated macro UTF8_COUNT_TRAIL_BYTES, defined in utf_old.h
+ *
+ * The current macro, U8_COUNT_TRAIL_BYTES, does _not_ use this table.
+ *
+ * Note that this table cannot be removed, even if UTF8_COUNT_TRAIL_BYTES were
+ * changed to no longer use it. References to the table from expansions of UTF8_COUNT_TRAIL_BYTES
+ * may exist in old client code that must continue to run with newer icu library versions.
+ *
+ * This table could be replaced on many machines by
+ * a few lines of assembler code using an
+ * "index of first 0-bit from msb" instruction and
+ * one or two more integer instructions.
+ *
+ * For example, on an i386, do something like
+ * - MOV AL, leadByte
+ * - NOT AL         (8-bit, leave b15..b8==0..0, reverse only b7..b0)
+ * - MOV AH, 0
+ * - BSR BX, AX     (16-bit)
+ * - MOV AX, 6      (result)
+ * - JZ finish      (ZF==1 if leadByte==0xff)
+ * - SUB AX, BX (result)
+ * -finish:
+ * (BSR: Bit Scan Reverse, scans for a 1-bit, starting from the MSB)
+ */
+extern "C" U_EXPORT const uint8_t
+utf8_countTrailBytes[256]={
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+    // illegal C0 & C1
+    // 2-byte lead bytes C2..DF
+    0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+    // 3-byte lead bytes E0..EF
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+    // 4-byte lead bytes F0..F4
+    // illegal F5..FF
+    3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static const UChar32
+utf8_errorValue[6]={
+    // Same values as UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_2, UTF_ERROR_VALUE,
+    // but without relying on the obsolete unicode/utf_old.h.
+    0x15, 0x9f, 0xffff,
+    0x10ffff
+};
+
+static UChar32
+errorValue(int32_t count, int8_t strict) {
+    if(strict>=0) {
+        return utf8_errorValue[count];
+    } else if(strict==-3) {
+        return 0xfffd;
+    } else {
+        return U_SENTINEL;
+    }
+}
+
+/*
+ * Handle the non-inline part of the U8_NEXT() and U8_NEXT_FFFD() macros
+ * and their obsolete sibling UTF8_NEXT_CHAR_SAFE().
+ *
+ * U8_NEXT() supports NUL-terminated strings indicated via length<0.
+ *
+ * The "strict" parameter controls the error behavior:
+ * <0  "Safe" behavior of U8_NEXT():
+ *     -1: All illegal byte sequences yield U_SENTINEL=-1.
+ *     -2: Same as -1, except for lenient treatment of surrogate code points as legal.
+ *         Some implementations use this for roundtripping of
+ *         Unicode 16-bit strings that are not well-formed UTF-16, that is, they
+ *         contain unpaired surrogates.
+ *     -3: All illegal byte sequences yield U+FFFD.
+ *  0  Obsolete "safe" behavior of UTF8_NEXT_CHAR_SAFE(..., FALSE):
+ *     All illegal byte sequences yield a positive code point such that this
+ *     result code point would be encoded with the same number of bytes as
+ *     the illegal sequence.
+ * >0  Obsolete "strict" behavior of UTF8_NEXT_CHAR_SAFE(..., TRUE):
+ *     Same as the obsolete "safe" behavior, but non-characters are also treated
+ *     like illegal sequences.
+ *
+ * Note that a UBool is the same as an int8_t.
+ */
+U_CAPI UChar32 U_EXPORT2
+utf8_nextCharSafeBody(const uint8_t *s, int32_t *pi, int32_t length, UChar32 c, UBool strict) {
+    // *pi is one after byte c.
+    int32_t i=*pi;
+    // length can be negative for NUL-terminated strings: Read and validate one byte at a time.
+    if(i==length || c>0xf4) {
+        // end of string, or not a lead byte
+    } else if(c>=0xf0) {
+        // Test for 4-byte sequences first because
+        // U8_NEXT() handles shorter valid sequences inline.
+        uint8_t t1=s[i], t2, t3;
+        c&=7;
+        if(U8_IS_VALID_LEAD4_AND_T1(c, t1) &&
+                ++i!=length && (t2=s[i]-0x80)<=0x3f &&
+                ++i!=length && (t3=s[i]-0x80)<=0x3f) {
+            ++i;
+            c=(c<<18)|((t1&0x3f)<<12)|(t2<<6)|t3;
+            // strict: forbid non-characters like U+fffe
+            if(strict<=0 || !U_IS_UNICODE_NONCHAR(c)) {
+                *pi=i;
+                return c;
+            }
+        }
+    } else if(c>=0xe0) {
+        c&=0xf;
+        if(strict!=-2) {
+            uint8_t t1=s[i], t2;
+            if(U8_IS_VALID_LEAD3_AND_T1(c, t1) &&
+                    ++i!=length && (t2=s[i]-0x80)<=0x3f) {
+                ++i;
+                c=(c<<12)|((t1&0x3f)<<6)|t2;
+                // strict: forbid non-characters like U+fffe
+                if(strict<=0 || !U_IS_UNICODE_NONCHAR(c)) {
+                    *pi=i;
+                    return c;
+                }
+            }
+        } else {
+            // strict=-2 -> lenient: allow surrogates
+            uint8_t t1=s[i]-0x80, t2;
+            if(t1<=0x3f && (c>0 || t1>=0x20) &&
+                    ++i!=length && (t2=s[i]-0x80)<=0x3f) {
+                *pi=i+1;
+                return (c<<12)|(t1<<6)|t2;
+            }
+        }
+    } else if(c>=0xc2) {
+        uint8_t t1=s[i]-0x80;
+        if(t1<=0x3f) {
+            *pi=i+1;
+            return ((c-0xc0)<<6)|t1;
+        }
+    }  // else 0x80<=c<0xc2 is not a lead byte
+
+    /* error handling */
+    c=errorValue(i-*pi, strict);
+    *pi=i;
+    return c;
+}
+
+U_CAPI int32_t U_EXPORT2
+utf8_appendCharSafeBody(uint8_t *s, int32_t i, int32_t length, UChar32 c, UBool *pIsError) {
+    if((uint32_t)(c)<=0x7ff) {
+        if((i)+1<(length)) {
+            (s)[(i)++]=(uint8_t)(((c)>>6)|0xc0);
+            (s)[(i)++]=(uint8_t)(((c)&0x3f)|0x80);
+            return i;
+        }
+    } else if((uint32_t)(c)<=0xffff) {
+        /* Starting with Unicode 3.2, surrogate code points must not be encoded in UTF-8. */
+        if((i)+2<(length) && !U_IS_SURROGATE(c)) {
+            (s)[(i)++]=(uint8_t)(((c)>>12)|0xe0);
+            (s)[(i)++]=(uint8_t)((((c)>>6)&0x3f)|0x80);
+            (s)[(i)++]=(uint8_t)(((c)&0x3f)|0x80);
+            return i;
+        }
+    } else if((uint32_t)(c)<=0x10ffff) {
+        if((i)+3<(length)) {
+            (s)[(i)++]=(uint8_t)(((c)>>18)|0xf0);
+            (s)[(i)++]=(uint8_t)((((c)>>12)&0x3f)|0x80);
+            (s)[(i)++]=(uint8_t)((((c)>>6)&0x3f)|0x80);
+            (s)[(i)++]=(uint8_t)(((c)&0x3f)|0x80);
+            return i;
+        }
+    }
+    /* c>0x10ffff or not enough space, write an error value */
+    if(pIsError!=NULL) {
+        *pIsError=TRUE;
+    } else {
+        length-=i;
+        if(length>0) {
+            int32_t offset;
+            if(length>3) {
+                length=3;
+            }
+            s+=i;
+            offset=0;
+            c=utf8_errorValue[length-1];
+            U8_APPEND_UNSAFE(s, offset, c);
+            i=i+offset;
+        }
+    }
+    return i;
+}
+
+U_CAPI UChar32 U_EXPORT2
+utf8_prevCharSafeBody(const uint8_t *s, int32_t start, int32_t *pi, UChar32 c, UBool strict) {
+    // *pi is the index of byte c.
+    int32_t i=*pi;
+    if(U8_IS_TRAIL(c) && i>start) {
+        uint8_t b1=s[--i];
+        if(U8_IS_LEAD(b1)) {
+            if(b1<0xe0) {
+                *pi=i;
+                return ((b1-0xc0)<<6)|(c&0x3f);
+            } else if(b1<0xf0 ? U8_IS_VALID_LEAD3_AND_T1(b1, c) : U8_IS_VALID_LEAD4_AND_T1(b1, c)) {
+                // Truncated 3- or 4-byte sequence.
+                *pi=i;
+                return errorValue(1, strict);
+            }
+        } else if(U8_IS_TRAIL(b1) && i>start) {
+            // Extract the value bits from the last trail byte.
+            c&=0x3f;
+            uint8_t b2=s[--i];
+            if(0xe0<=b2 && b2<=0xf4) {
+                if(b2<0xf0) {
+                    b2&=0xf;
+                    if(strict!=-2) {
+                        if(U8_IS_VALID_LEAD3_AND_T1(b2, b1)) {
+                            *pi=i;
+                            c=(b2<<12)|((b1&0x3f)<<6)|c;
+                            if(strict<=0 || !U_IS_UNICODE_NONCHAR(c)) {
+                                return c;
+                            } else {
+                                // strict: forbid non-characters like U+fffe
+                                return errorValue(2, strict);
+                            }
+                        }
+                    } else {
+                        // strict=-2 -> lenient: allow surrogates
+                        b1-=0x80;
+                        if((b2>0 || b1>=0x20)) {
+                            *pi=i;
+                            return (b2<<12)|(b1<<6)|c;
+                        }
+                    }
+                } else if(U8_IS_VALID_LEAD4_AND_T1(b2, b1)) {
+                    // Truncated 4-byte sequence.
+                    *pi=i;
+                    return errorValue(2, strict);
+                }
+            } else if(U8_IS_TRAIL(b2) && i>start) {
+                uint8_t b3=s[--i];
+                if(0xf0<=b3 && b3<=0xf4) {
+                    b3&=7;
+                    if(U8_IS_VALID_LEAD4_AND_T1(b3, b2)) {
+                        *pi=i;
+                        c=(b3<<18)|((b2&0x3f)<<12)|((b1&0x3f)<<6)|c;
+                        if(strict<=0 || !U_IS_UNICODE_NONCHAR(c)) {
+                            return c;
+                        } else {
+                            // strict: forbid non-characters like U+fffe
+                            return errorValue(3, strict);
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return errorValue(0, strict);
+}
+
+U_CAPI int32_t U_EXPORT2
+utf8_back1SafeBody(const uint8_t *s, int32_t start, int32_t i) {
+    // Same as utf8_prevCharSafeBody(..., strict=-1) minus assembling code points.
+    int32_t orig_i=i;
+    uint8_t c=s[i];
+    if(U8_IS_TRAIL(c) && i>start) {
+        uint8_t b1=s[--i];
+        if(U8_IS_LEAD(b1)) {
+            if(b1<0xe0 ||
+                    (b1<0xf0 ? U8_IS_VALID_LEAD3_AND_T1(b1, c) : U8_IS_VALID_LEAD4_AND_T1(b1, c))) {
+                return i;
+            }
+        } else if(U8_IS_TRAIL(b1) && i>start) {
+            uint8_t b2=s[--i];
+            if(0xe0<=b2 && b2<=0xf4) {
+                if(b2<0xf0 ? U8_IS_VALID_LEAD3_AND_T1(b2, b1) : U8_IS_VALID_LEAD4_AND_T1(b2, b1)) {
+                    return i;
+                }
+            } else if(U8_IS_TRAIL(b2) && i>start) {
+                uint8_t b3=s[--i];
+                if(0xf0<=b3 && b3<=0xf4 && U8_IS_VALID_LEAD4_AND_T1(b3, b2)) {
+                    return i;
+                }
+            }
+        }
+    }
+    return orig_i;
+}
diff --git a/src/third_party/icu/source/common/util.cpp b/src/third_party/icu/source/common/util.cpp
index acb1585..86e5c79 100644
--- a/src/third_party/icu/source/common/util.cpp
+++ b/src/third_party/icu/source/common/util.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
 *   Copyright (c) 2001-2011, International Business Machines
@@ -274,6 +276,16 @@
     return -1; // text ended before end of pat
 }
 
+int32_t ICU_Utility::parseAsciiInteger(const UnicodeString& str, int32_t& pos) {
+    int32_t result = 0;
+    UChar c;
+    while (pos < str.length() && (c = str.charAt(pos)) >= u'0' && c <= u'9') {
+        result = result * 10 + (c - u'0');
+        pos++;
+    }
+    return result;
+}
+
 /**
  * Append a character to a rule that is being built up.  To flush
  * the quoteBuf to rule, make one final call with isLiteral == TRUE.
diff --git a/src/third_party/icu/source/common/util.h b/src/third_party/icu/source/common/util.h
index 7cb2c5a..9c3b76d 100644
--- a/src/third_party/icu/source/common/util.h
+++ b/src/third_party/icu/source/common/util.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
  **********************************************************************
  *   Copyright (c) 2001-2011, International Business Machines
@@ -44,6 +46,13 @@
                                        int32_t radix = 10,
                                        int32_t minDigits = 1);
 
+    /** Returns a bogus UnicodeString by value. */
+    static inline UnicodeString makeBogusString() {
+        UnicodeString result;
+        result.setToBogus();
+        return result;
+    }
+
     /**
      * Return true if the character is NOT printable ASCII.
      *
@@ -55,8 +64,8 @@
     /**
      * Escape unprintable characters using \uxxxx notation for U+0000 to
      * U+FFFF and \Uxxxxxxxx for U+10000 and above.  If the character is
-     * printable ASCII, then do nothing and return FALSE.  Otherwise,
-     * append the escaped notation and return TRUE.
+     * printable ASCII, then do nothing and return false.  Otherwise,
+     * append the escaped notation and return true.
      */
     static UBool escapeUnprintable(UnicodeString& result, UChar32 c);
 
@@ -86,7 +95,7 @@
      * after pos, or str.length(), if there is none.
      */
     static int32_t skipWhitespace(const UnicodeString& str, int32_t& pos,
-                                  UBool advance = FALSE);
+                                  UBool advance = false);
 
     /**
      * Skip over Pattern_White_Space in a Replaceable.
@@ -170,13 +179,22 @@
      * Parse an integer at pos, either of the form \d+ or of the form
      * 0x[0-9A-Fa-f]+ or 0[0-7]+, that is, in standard decimal, hex,
      * or octal format.
-     * @param pos INPUT-OUTPUT parameter.  On input, the first
-     * character to parse.  On output, the character after the last
-     * parsed character.
+     * @param pos INPUT-OUTPUT parameter.  On input, the index of the first
+     * character to parse.  On output, the index of the character after the
+     * last parsed character.
      */
     static int32_t parseInteger(const UnicodeString& rule, int32_t& pos, int32_t limit);
 
     /**
+     * Parse an integer at pos using only ASCII digits.
+     * Base 10 only.
+     * @param pos INPUT-OUTPUT parameter.  On input, the index of the first
+     * character to parse.  On output, the index of the character after the
+     * last parsed character.
+     */
+    static int32_t parseAsciiInteger(const UnicodeString& str, int32_t& pos);
+
+    /**
      * Parse a Unicode identifier from the given string at the given
      * position.  Return the identifier, or an empty string if there
      * is no identifier.
diff --git a/src/third_party/icu/source/common/util_props.cpp b/src/third_party/icu/source/common/util_props.cpp
index 1bdaadd..95a112b 100644
--- a/src/third_party/icu/source/common/util_props.cpp
+++ b/src/third_party/icu/source/common/util_props.cpp
@@ -1,6 +1,8 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
-*   Copyright (c) 2001-2011, International Business Machines
+*   Copyright (c) 2001-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 **********************************************************************
 *   Date        Name        Description
@@ -101,6 +103,7 @@
                 return -1;
             }
             // FALL THROUGH to skipWhitespace
+            U_FALLTHROUGH;
         case 126 /*'~'*/:
             pos = skipWhitespace(rule, pos);
             break;
diff --git a/src/third_party/icu/source/common/utrace.c b/src/third_party/icu/source/common/utrace.cpp
similarity index 94%
rename from src/third_party/icu/source/common/utrace.c
rename to src/third_party/icu/source/common/utrace.cpp
index 5754a92..1ad4a48 100644
--- a/src/third_party/icu/source/common/utrace.c
+++ b/src/third_party/icu/source/common/utrace.cpp
@@ -1,16 +1,19 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *   Copyright (C) 2003-2014, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *******************************************************************************
 *   file name:  utrace.c
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 */
 
-#define   UTRACE_IMPL
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/utrace.h"
 #include "utracimp.h"
 #include "cstring.h"
@@ -23,7 +26,11 @@
 static UTraceData      *pTraceDataFunc  = NULL;
 static const void      *gTraceContext   = NULL;
 
-U_EXPORT int32_t
+/**
+ * \var utrace_level
+ * Trace level variable. Negative for "off".
+ */
+static int32_t
 utrace_level = UTRACE_ERROR;
 
 U_CAPI void U_EXPORT2
@@ -63,8 +70,7 @@
             fmt = gExitFmtPtrStatus;
             break;
         default:
-            U_ASSERT(FALSE);
-            fmt = gExitFmt;
+            UPRV_UNREACHABLE;
         }
 
         va_start(args, returnType);
@@ -133,7 +139,7 @@
 
 /* Output a pointer value in hex.  Work with any size of pointer   */
 static void outputPtrBytes(void *val, char *outBuf, int32_t *outIx, int32_t capacity) {
-    int32_t  i;
+    uint32_t  i;
     int32_t  incVal = 1;              /* +1 for big endian, -1 for little endian          */
     char     *p     = (char *)&val;   /* point to current byte to output in the ptr val  */
 
@@ -229,7 +235,7 @@
 
         case 'S':
             /* UChar * string, with length, len==-1 for null terminated. */
-            ptrArg = va_arg(args, void *);             /* Ptr    */
+            ptrArg = va_arg(args, char *);             /* Ptr    */
             intArg =(int32_t)va_arg(args, int32_t);    /* Length */
             outputUString((const UChar *)ptrArg, intArg, outBuf, &outIx, capacity, indent);
             break;
@@ -260,7 +266,7 @@
             
         case 'p':
             /*  Pointers.   */
-            ptrArg = va_arg(args, void *);
+            ptrArg = va_arg(args, char *);
             outputPtrBytes(ptrArg, outBuf, &outIx, capacity);
             break;
 
@@ -331,7 +337,7 @@
                             break;
                         case 's':
                             charsToOutput = 0;
-                            outputString(*ptrPtr, outBuf, &outIx, capacity, indent);
+                            outputString((const char *)*ptrPtr, outBuf, &outIx, capacity, indent);
                             outputChar('\n', outBuf, &outIx, capacity, indent);
                             longArg = *ptrPtr==NULL? 0: 1;   /* for test for null term. array. */
                             ptrPtr++;
@@ -473,6 +479,16 @@
     NULL
 };
 
+
+static const char* const
+trResDataNames[] = {
+    "resc",
+    "bundle-open",
+    "file-open",
+    "res-open",
+    NULL
+};
+
                 
 U_CAPI const char * U_EXPORT2
 utrace_functionName(int32_t fnNumber) {
@@ -482,6 +498,8 @@
         return trConvNames[fnNumber - UTRACE_CONVERSION_START];
     } else if(UTRACE_COLLATION_START <= fnNumber && fnNumber < UTRACE_COLLATION_LIMIT){
         return trCollNames[fnNumber - UTRACE_COLLATION_START];
+    } else if(UTRACE_UDATA_START <= fnNumber && fnNumber < UTRACE_RES_DATA_LIMIT){
+        return trResDataNames[fnNumber - UTRACE_UDATA_START];
     } else {
         return "[BOGUS Trace Function Number]";
     }
diff --git a/src/third_party/icu/source/common/utracimp.h b/src/third_party/icu/source/common/utracimp.h
index 317fbe3..f32fe1d 100644
--- a/src/third_party/icu/source/common/utracimp.h
+++ b/src/third_party/icu/source/common/utracimp.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 *******************************************************************************
 *   file name:  utracimp.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -45,20 +47,6 @@
 
 U_CDECL_BEGIN
 
-/**
- * \var utrace_level
- * Trace level variable. Negative for "off".
- * Use only via UTRACE_ macros.
- * @internal
- */
-#ifdef UTRACE_IMPL
-U_EXPORT int32_t
-#else
-U_CFUNC U_COMMON_API int32_t
-#endif
-utrace_level;
-
-
 /** 
  *   Traced Function Exit return types.  
  *   Flags indicating the number and types of varargs included in a call
@@ -156,10 +144,12 @@
  */
 #define UTRACE_ENTRY(fnNumber) \
     int32_t utraceFnNumber=(fnNumber); \
+UPRV_BLOCK_MACRO_BEGIN { \
     if(utrace_getLevel()>=UTRACE_INFO) { \
         utrace_entry(fnNumber); \
         utraceFnNumber |= UTRACE_TRACED_ENTRY; \
-    }
+    } \
+} UPRV_BLOCK_MACRO_END
 
 
 /**
@@ -174,10 +164,12 @@
  */
 #define UTRACE_ENTRY_OC(fnNumber) \
     int32_t utraceFnNumber=(fnNumber); \
+UPRV_BLOCK_MACRO_BEGIN { \
     if(utrace_getLevel()>=UTRACE_OPEN_CLOSE) { \
         utrace_entry(fnNumber); \
         utraceFnNumber |= UTRACE_TRACED_ENTRY; \
-    }
+    } \
+} UPRV_BLOCK_MACRO_END
 
 /**
  * Trace statement for each exit point of a function that has a UTRACE_ENTRY()
@@ -191,10 +183,11 @@
  *
  * @internal
  */
-#define UTRACE_EXIT() \
-    {if(utraceFnNumber & UTRACE_TRACED_ENTRY) { \
+#define UTRACE_EXIT() UPRV_BLOCK_MACRO_BEGIN { \
+    if(utraceFnNumber & UTRACE_TRACED_ENTRY) { \
         utrace_exit(utraceFnNumber & ~UTRACE_TRACED_ENTRY, UTRACE_EXITV_NONE); \
-    }}
+    } \
+} UPRV_BLOCK_MACRO_END
 
 /**
  * Trace statement for each exit point of a function that has a UTRACE_ENTRY()
@@ -204,25 +197,29 @@
  *
  * @internal 
  */
-#define UTRACE_EXIT_VALUE(val) \
-    {if(utraceFnNumber & UTRACE_TRACED_ENTRY) { \
+#define UTRACE_EXIT_VALUE(val) UPRV_BLOCK_MACRO_BEGIN { \
+    if(utraceFnNumber & UTRACE_TRACED_ENTRY) { \
         utrace_exit(utraceFnNumber & ~UTRACE_TRACED_ENTRY, UTRACE_EXITV_I32, val); \
-    }}
+    } \
+} UPRV_BLOCK_MACRO_END
 
-#define UTRACE_EXIT_STATUS(status) \
-    {if(utraceFnNumber & UTRACE_TRACED_ENTRY) { \
+#define UTRACE_EXIT_STATUS(status) UPRV_BLOCK_MACRO_BEGIN { \
+    if(utraceFnNumber & UTRACE_TRACED_ENTRY) { \
         utrace_exit(utraceFnNumber & ~UTRACE_TRACED_ENTRY, UTRACE_EXITV_STATUS, status); \
-    }}
+    } \
+} UPRV_BLOCK_MACRO_END
 
-#define UTRACE_EXIT_VALUE_STATUS(val, status) \
-    {if(utraceFnNumber & UTRACE_TRACED_ENTRY) { \
+#define UTRACE_EXIT_VALUE_STATUS(val, status) UPRV_BLOCK_MACRO_BEGIN { \
+    if(utraceFnNumber & UTRACE_TRACED_ENTRY) { \
         utrace_exit(utraceFnNumber & ~UTRACE_TRACED_ENTRY, (UTRACE_EXITV_I32 | UTRACE_EXITV_STATUS), val, status); \
-    }}
+    } \
+} UPRV_BLOCK_MACRO_END
 
-#define UTRACE_EXIT_PTR_STATUS(ptr, status) \
-    {if(utraceFnNumber & UTRACE_TRACED_ENTRY) { \
+#define UTRACE_EXIT_PTR_STATUS(ptr, status) UPRV_BLOCK_MACRO_BEGIN { \
+    if(utraceFnNumber & UTRACE_TRACED_ENTRY) { \
         utrace_exit(utraceFnNumber & ~UTRACE_TRACED_ENTRY, (UTRACE_EXITV_PTR | UTRACE_EXITV_STATUS), ptr, status); \
-    }}
+    } \
+} UPRV_BLOCK_MACRO_END
 
 /**
  * Trace statement used inside functions that have a UTRACE_ENTRY() statement.
@@ -232,10 +229,11 @@
  * Calls utrace_data() if the level is high enough.
  * @internal
  */
-#define UTRACE_DATA0(level, fmt) \
+#define UTRACE_DATA0(level, fmt) UPRV_BLOCK_MACRO_BEGIN { \
     if(UTRACE_LEVEL(level)) { \
         utrace_data(utraceFnNumber & ~UTRACE_TRACED_ENTRY, (level), (fmt)); \
-    }
+    } \
+} UPRV_BLOCK_MACRO_END
 
 /**
  * Trace statement used inside functions that have a UTRACE_ENTRY() statement.
@@ -245,10 +243,11 @@
  * Calls utrace_data() if the level is high enough.
  * @internal
  */
-#define UTRACE_DATA1(level, fmt, a) \
+#define UTRACE_DATA1(level, fmt, a) UPRV_BLOCK_MACRO_BEGIN { \
     if(UTRACE_LEVEL(level)) { \
         utrace_data(utraceFnNumber & ~UTRACE_TRACED_ENTRY , (level), (fmt), (a)); \
-    }
+    } \
+} UPRV_BLOCK_MACRO_END
 
 /**
  * Trace statement used inside functions that have a UTRACE_ENTRY() statement.
@@ -258,10 +257,11 @@
  * Calls utrace_data() if the level is high enough.
  * @internal
  */
-#define UTRACE_DATA2(level, fmt, a, b) \
+#define UTRACE_DATA2(level, fmt, a, b) UPRV_BLOCK_MACRO_BEGIN { \
     if(UTRACE_LEVEL(level)) { \
         utrace_data(utraceFnNumber & ~UTRACE_TRACED_ENTRY , (level), (fmt), (a), (b)); \
-    }
+    } \
+} UPRV_BLOCK_MACRO_END
 
 /**
  * Trace statement used inside functions that have a UTRACE_ENTRY() statement.
@@ -271,10 +271,11 @@
  * Calls utrace_data() if the level is high enough.
  * @internal
  */
-#define UTRACE_DATA3(level, fmt, a, b, c) \
+#define UTRACE_DATA3(level, fmt, a, b, c) UPRV_BLOCK_MACRO_BEGIN { \
     if(UTRACE_LEVEL(level)) { \
         utrace_data(utraceFnNumber & ~UTRACE_TRACED_ENTRY, (level), (fmt), (a), (b), (c)); \
-    }
+    } \
+} UPRV_BLOCK_MACRO_END
 
 /**
  * Trace statement used inside functions that have a UTRACE_ENTRY() statement.
@@ -284,10 +285,11 @@
  * Calls utrace_data() if the level is high enough.
  * @internal
  */
-#define UTRACE_DATA4(level, fmt, a, b, c, d) \
+#define UTRACE_DATA4(level, fmt, a, b, c, d) UPRV_BLOCK_MACRO_BEGIN { \
     if(UTRACE_LEVEL(level)) { \
         utrace_data(utraceFnNumber & ~UTRACE_TRACED_ENTRY, (level), (fmt), (a), (b), (c), (d)); \
-    }
+    } \
+} UPRV_BLOCK_MACRO_END
 
 /**
  * Trace statement used inside functions that have a UTRACE_ENTRY() statement.
@@ -297,10 +299,11 @@
  * Calls utrace_data() if the level is high enough.
  * @internal
  */
-#define UTRACE_DATA5(level, fmt, a, b, c, d, e) \
+#define UTRACE_DATA5(level, fmt, a, b, c, d, e) UPRV_BLOCK_MACRO_BEGIN { \
     if(UTRACE_LEVEL(level)) { \
         utrace_data(utraceFnNumber & ~UTRACE_TRACED_ENTRY, (level), (fmt), (a), (b), (c), (d), (e)); \
-    }
+    } \
+} UPRV_BLOCK_MACRO_END
 
 /**
  * Trace statement used inside functions that have a UTRACE_ENTRY() statement.
@@ -310,10 +313,11 @@
  * Calls utrace_data() if the level is high enough.
  * @internal
  */
-#define UTRACE_DATA6(level, fmt, a, b, c, d, e, f) \
+#define UTRACE_DATA6(level, fmt, a, b, c, d, e, f) UPRV_BLOCK_MACRO_BEGIN { \
     if(UTRACE_LEVEL(level)) { \
         utrace_data(utraceFnNumber & ~UTRACE_TRACED_ENTRY, (level), (fmt), (a), (b), (c), (d), (e), (f)); \
-    }
+    } \
+} UPRV_BLOCK_MACRO_END
 
 /**
  * Trace statement used inside functions that have a UTRACE_ENTRY() statement.
@@ -323,10 +327,11 @@
  * Calls utrace_data() if the level is high enough.
  * @internal
  */
-#define UTRACE_DATA7(level, fmt, a, b, c, d, e, f, g) \
+#define UTRACE_DATA7(level, fmt, a, b, c, d, e, f, g) UPRV_BLOCK_MACRO_BEGIN { \
     if(UTRACE_LEVEL(level)) { \
         utrace_data(utraceFnNumber & ~UTRACE_TRACED_ENTRY, (level), (fmt), (a), (b), (c), (d), (e), (f), (g)); \
-    }
+    } \
+} UPRV_BLOCK_MACRO_END
 
 /**
  * Trace statement used inside functions that have a UTRACE_ENTRY() statement.
@@ -336,10 +341,11 @@
  * Calls utrace_data() if the level is high enough.
  * @internal
  */
-#define UTRACE_DATA8(level, fmt, a, b, c, d, e, f, g, h) \
+#define UTRACE_DATA8(level, fmt, a, b, c, d, e, f, g, h) UPRV_BLOCK_MACRO_BEGIN { \
     if(UTRACE_LEVEL(level)) { \
         utrace_data(utraceFnNumber & ~UTRACE_TRACED_ENTRY, (level), (fmt), (a), (b), (c), (d), (e), (f), (g), (h)); \
-    }
+    } \
+} UPRV_BLOCK_MACRO_END
 
 /**
  * Trace statement used inside functions that have a UTRACE_ENTRY() statement.
@@ -349,10 +355,11 @@
  * Calls utrace_data() if the level is high enough.
  * @internal
  */
-#define UTRACE_DATA9(level, fmt, a, b, c, d, e, f, g, h, i) \
+#define UTRACE_DATA9(level, fmt, a, b, c, d, e, f, g, h, i) UPRV_BLOCK_MACRO_BEGIN { \
     if(UTRACE_LEVEL(level)) { \
         utrace_data(utraceFnNumber & ~UTRACE_TRACED_ENTRY, (level), (fmt), (a), (b), (c), (d), (e), (f), (g), (h), (i)); \
-    }
+    } \
+} UPRV_BLOCK_MACRO_END
 
 #else
 
diff --git a/src/third_party/icu/source/common/utrie.cpp b/src/third_party/icu/source/common/utrie.cpp
index dab65da..6182169 100644
--- a/src/third_party/icu/source/common/utrie.cpp
+++ b/src/third_party/icu/source/common/utrie.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 ******************************************************************************
 *   file name:  utrie.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -23,7 +25,9 @@
 #   include <stdio.h>
 #endif
 #endif
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/utypes.h"
 #include "cmemory.h"
 #include "utrie.h"
@@ -141,7 +145,7 @@
         uprv_free(aliasData);
     } else {
         uprv_memcpy(trie->index, other->index, sizeof(trie->index));
-        uprv_memcpy(trie->data, other->data, other->dataLength*4);
+        uprv_memcpy(trie->data, other->data, (size_t)other->dataLength*4);
         trie->dataLength=other->dataLength;
         trie->isDataAllocated=isDataAllocated;
     }
@@ -841,7 +845,7 @@
         }
 
         /* write 32-bit data values */
-        uprv_memcpy(dest16, trie->data, 4*trie->dataLength);
+        uprv_memcpy(dest16, trie->data, 4*(size_t)trie->dataLength);
     }
 
     return length;
diff --git a/src/third_party/icu/source/common/utrie.h b/src/third_party/icu/source/common/utrie.h
index 3cec027..2fd2c46 100644
--- a/src/third_party/icu/source/common/utrie.h
+++ b/src/third_party/icu/source/common/utrie.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 ******************************************************************************
 *   file name:  utrie.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -19,7 +21,6 @@
 
 #include "unicode/utypes.h"
 #include "unicode/utf16.h"
-#include "udataswp.h"
 
 U_CDECL_BEGIN
 
@@ -181,7 +182,7 @@
     ]
 
 /** Internal trie getter from a pair of surrogates */
-#define _UTRIE_GET_FROM_PAIR(trie, data, c, c2, result, resultType) { \
+#define _UTRIE_GET_FROM_PAIR(trie, data, c, c2, result, resultType) UPRV_BLOCK_MACRO_BEGIN { \
     int32_t __offset; \
 \
     /* get data for lead surrogate */ \
@@ -194,18 +195,18 @@
     } else { \
         (result)=(resultType)((trie)->initialValue); \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /** Internal trie getter from a BMP code point, treating a lead surrogate as a normal code point */
 #define _UTRIE_GET_FROM_BMP(trie, data, c16) \
-    _UTRIE_GET_RAW(trie, data, 0xd800<=(c16) && (c16)<=0xdbff ? UTRIE_LEAD_INDEX_DISP : 0, c16);
+    _UTRIE_GET_RAW(trie, data, 0xd800<=(c16) && (c16)<=0xdbff ? UTRIE_LEAD_INDEX_DISP : 0, c16)
 
 /**
  * Internal trie getter from a code point.
  * Could be faster(?) but longer with
  *   if((c32)<=0xd7ff) { (result)=_UTRIE_GET_RAW(trie, data, 0, c32); }
  */
-#define _UTRIE_GET(trie, data, c32, result, resultType) \
+#define _UTRIE_GET(trie, data, c32, result, resultType) UPRV_BLOCK_MACRO_BEGIN { \
     if((uint32_t)(c32)<=0xffff) { \
         /* BMP code points */ \
         (result)=_UTRIE_GET_FROM_BMP(trie, data, c32); \
@@ -216,10 +217,11 @@
     } else { \
         /* out of range */ \
         (result)=(resultType)((trie)->initialValue); \
-    }
+    } \
+} UPRV_BLOCK_MACRO_END
 
 /** Internal next-post-increment: get the next code point (c, c2) and its data */
-#define _UTRIE_NEXT(trie, data, src, limit, c, c2, result, resultType) { \
+#define _UTRIE_NEXT(trie, data, src, limit, c, c2, result, resultType) UPRV_BLOCK_MACRO_BEGIN { \
     (c)=*(src)++; \
     if(!U16_IS_LEAD(c)) { \
         (c2)=0; \
@@ -232,10 +234,10 @@
         (c2)=0; \
         (result)=_UTRIE_GET_RAW((trie), data, UTRIE_LEAD_INDEX_DISP, (c)); \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /** Internal previous: get the previous code point (c, c2) and its data */
-#define _UTRIE_PREVIOUS(trie, data, start, src, c, c2, result, resultType) { \
+#define _UTRIE_PREVIOUS(trie, data, start, src, c, c2, result, resultType) UPRV_BLOCK_MACRO_BEGIN { \
     (c)=*--(src); \
     if(!U16_IS_SURROGATE(c)) { \
         (c2)=0; \
@@ -256,7 +258,7 @@
         (c2)=0; \
         (result)=_UTRIE_GET_RAW((trie), data, UTRIE_LEAD_INDEX_DISP, (c)); \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /* Public UTrie API ---------------------------------------------------------*/
 
@@ -458,13 +460,13 @@
  * of code points with the same value as retrieved from the trie and
  * transformed by the UTrieEnumValue function.
  *
- * The callback function can stop the enumeration by returning FALSE.
+ * The callback function can stop the enumeration by returning false.
  *
  * @param context an opaque pointer, as passed into utrie_enum()
  * @param start the first code point in a contiguous range with value
  * @param limit one past the last code point in a contiguous range with value
  * @param value the value that is set for all code points in [start..limit[
- * @return FALSE to stop the enumeration
+ * @return false to stop the enumeration
  */
 typedef UBool U_CALLCONV
 UTrieEnumRange(const void *context, UChar32 start, UChar32 limit, uint32_t value);
@@ -554,7 +556,7 @@
      * Index values at build-time are 32 bits wide for easier processing.
      * Bit 31 is set if the data block is used by multiple index values (from utrie_setRange()).
      */
-    int32_t index[UTRIE_MAX_INDEX_LENGTH];
+    int32_t index[UTRIE_MAX_INDEX_LENGTH+UTRIE_SURROGATE_BLOCK_COUNT];
     uint32_t *data;
 
     uint32_t leadUnitValue;
@@ -665,7 +667,7 @@
  * @param trie the build-time trie
  * @param c the code point
  * @param value the value
- * @return FALSE if a failure occurred (illegal argument or data array overrun)
+ * @return false if a failure occurred (illegal argument or data array overrun)
  */
 U_CAPI UBool U_EXPORT2
 utrie_set32(UNewTrie *trie, UChar32 c, uint32_t value);
@@ -675,7 +677,7 @@
  *
  * @param trie the build-time trie
  * @param c the code point
- * @param pInBlockZero if not NULL, then *pInBlockZero is set to TRUE
+ * @param pInBlockZero if not NULL, then *pInBlockZero is set to true
  *                     iff the value is retrieved from block 0;
  *                     block 0 is the all-initial-value initial block
  * @return the value
@@ -686,14 +688,14 @@
 /**
  * Set a value in a range of code points [start..limit[.
  * All code points c with start<=c<limit will get the value if
- * overwrite is TRUE or if the old value is 0.
+ * overwrite is true or if the old value is 0.
  *
  * @param trie the build-time trie
  * @param start the first code point to get the value
  * @param limit one past the last code point to get the value
  * @param value the value
  * @param overwrite flag for whether old non-initial values are to be overwritten
- * @return FALSE if a failure occurred (illegal argument or data array overrun)
+ * @return false if a failure occurred (illegal argument or data array overrun)
  */
 U_CAPI UBool U_EXPORT2
 utrie_setRange32(UNewTrie *trie, UChar32 start, UChar32 limit, uint32_t value, UBool overwrite);
@@ -730,17 +732,13 @@
                 UBool reduceTo16Bits,
                 UErrorCode *pErrorCode);
 
-/**
- * Swap a serialized UTrie.
- * @internal
- */
-U_CAPI int32_t U_EXPORT2
-utrie_swap(const UDataSwapper *ds,
-           const void *inData, int32_t length, void *outData,
-           UErrorCode *pErrorCode);
-
 /* serialization ------------------------------------------------------------ */
 
+// UTrie signature values, in platform endianness and opposite endianness.
+// The UTrie signature ASCII byte values spell "Trie".
+#define UTRIE_SIG       0x54726965
+#define UTRIE_OE_SIG    0x65697254
+
 /**
  * Trie data structure in serialized form:
  *
diff --git a/src/third_party/icu/source/common/utrie2.cpp b/src/third_party/icu/source/common/utrie2.cpp
index 9a9d5cc..4a1ab21 100644
--- a/src/third_party/icu/source/common/utrie2.cpp
+++ b/src/third_party/icu/source/common/utrie2.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 ******************************************************************************
 *   file name:  utrie2.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -22,13 +24,14 @@
 *   This file contains only the runtime and enumeration code, for read-only access.
 *   See utrie2_builder.c for the builder code.
 */
-#ifdef UTRIE2_DEBUG
-#   include <stdio.h>
-#endif
-
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/utypes.h"
+#ifdef UCPTRIE_DEBUG
+#include "unicode/umutablecptrie.h"
+#endif
 #include "unicode/utf.h"
 #include "unicode/utf8.h"
 #include "unicode/utf16.h"
@@ -202,6 +205,9 @@
     trie->memory=(uint32_t *)data;
     trie->length=actualLength;
     trie->isMemoryOwned=FALSE;
+#ifdef UTRIE2_DEBUG
+    trie->name="fromSerialized";
+#endif
 
     /* set the pointers to its index and data arrays */
     p16=(const uint16_t *)(header+1);
@@ -294,6 +300,9 @@
     trie->errorValue=errorValue;
     trie->highStart=0;
     trie->highValueIndex=dataMove+UTRIE2_DATA_START_OFFSET;
+#ifdef UTRIE2_DEBUG
+    trie->name="dummy";
+#endif
 
     /* set the header fields */
     header=(UTrie2Header *)trie->memory;
@@ -373,34 +382,15 @@
         }
         if(trie->newTrie!=NULL) {
             uprv_free(trie->newTrie->data);
+#ifdef UCPTRIE_DEBUG
+            umutablecptrie_close(trie->newTrie->t3);
+#endif
             uprv_free(trie->newTrie);
         }
         uprv_free(trie);
     }
 }
 
-U_CAPI int32_t U_EXPORT2
-utrie2_getVersion(const void *data, int32_t length, UBool anyEndianOk) {
-    uint32_t signature;
-    if(length<16 || data==NULL || (U_POINTER_MASK_LSB(data, 3)!=0)) {
-        return 0;
-    }
-    signature=*(const uint32_t *)data;
-    if(signature==UTRIE2_SIG) {
-        return 2;
-    }
-    if(anyEndianOk && signature==UTRIE2_OE_SIG) {
-        return 2;
-    }
-    if(signature==UTRIE_SIG) {
-        return 1;
-    }
-    if(anyEndianOk && signature==UTRIE_OE_SIG) {
-        return 1;
-    }
-    return 0;
-}
-
 U_CAPI UBool U_EXPORT2
 utrie2_isFrozen(const UTrie2 *trie) {
     return (UBool)(trie->newTrie==NULL);
@@ -430,96 +420,6 @@
     return trie->length;
 }
 
-U_CAPI int32_t U_EXPORT2
-utrie2_swap(const UDataSwapper *ds,
-            const void *inData, int32_t length, void *outData,
-            UErrorCode *pErrorCode) {
-    const UTrie2Header *inTrie;
-    UTrie2Header trie;
-    int32_t dataLength, size;
-    UTrie2ValueBits valueBits;
-
-    if(U_FAILURE(*pErrorCode)) {
-        return 0;
-    }
-    if(ds==NULL || inData==NULL || (length>=0 && outData==NULL)) {
-        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
-        return 0;
-    }
-
-    /* setup and swapping */
-    if(length>=0 && length<(int32_t)sizeof(UTrie2Header)) {
-        *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
-        return 0;
-    }
-
-    inTrie=(const UTrie2Header *)inData;
-    trie.signature=ds->readUInt32(inTrie->signature);
-    trie.options=ds->readUInt16(inTrie->options);
-    trie.indexLength=ds->readUInt16(inTrie->indexLength);
-    trie.shiftedDataLength=ds->readUInt16(inTrie->shiftedDataLength);
-
-    valueBits=(UTrie2ValueBits)(trie.options&UTRIE2_OPTIONS_VALUE_BITS_MASK);
-    dataLength=(int32_t)trie.shiftedDataLength<<UTRIE2_INDEX_SHIFT;
-
-    if( trie.signature!=UTRIE2_SIG ||
-        valueBits<0 || UTRIE2_COUNT_VALUE_BITS<=valueBits ||
-        trie.indexLength<UTRIE2_INDEX_1_OFFSET ||
-        dataLength<UTRIE2_DATA_START_OFFSET
-    ) {
-        *pErrorCode=U_INVALID_FORMAT_ERROR; /* not a UTrie */
-        return 0;
-    }
-
-    size=sizeof(UTrie2Header)+trie.indexLength*2;
-    switch(valueBits) {
-    case UTRIE2_16_VALUE_BITS:
-        size+=dataLength*2;
-        break;
-    case UTRIE2_32_VALUE_BITS:
-        size+=dataLength*4;
-        break;
-    default:
-        *pErrorCode=U_INVALID_FORMAT_ERROR;
-        return 0;
-    }
-
-    if(length>=0) {
-        UTrie2Header *outTrie;
-
-        if(length<size) {
-            *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
-            return 0;
-        }
-
-        outTrie=(UTrie2Header *)outData;
-
-        /* swap the header */
-        ds->swapArray32(ds, &inTrie->signature, 4, &outTrie->signature, pErrorCode);
-        ds->swapArray16(ds, &inTrie->options, 12, &outTrie->options, pErrorCode);
-
-        /* swap the index and the data */
-        switch(valueBits) {
-        case UTRIE2_16_VALUE_BITS:
-            ds->swapArray16(ds, inTrie+1, (trie.indexLength+dataLength)*2, outTrie+1, pErrorCode);
-            break;
-        case UTRIE2_32_VALUE_BITS:
-            ds->swapArray16(ds, inTrie+1, trie.indexLength*2, outTrie+1, pErrorCode);
-            ds->swapArray32(ds, (const uint16_t *)(inTrie+1)+trie.indexLength, dataLength*4,
-                                     (uint16_t *)(outTrie+1)+trie.indexLength, pErrorCode);
-            break;
-        default:
-            *pErrorCode=U_INVALID_FORMAT_ERROR;
-            return 0;
-        }
-    }
-
-    return size;
-}
-
-// utrie2_swapAnyVersion() should be defined here but lives in utrie2_builder.c
-// to avoid a dependency from utrie2.cpp on utrie.c.
-
 /* enumeration -------------------------------------------------------------- */
 
 #define MIN_VALUE(a, b) ((a)<(b) ? (a) : (b))
@@ -746,7 +646,7 @@
     codePointLimit=codePointStart;
     if(start>=codePointStart) {
         codePoint=U_SENTINEL;
-        return 0;
+        return static_cast<uint16_t>(trie->errorValue);
     }
     uint16_t result;
     UTRIE2_U16_PREV16(trie, start, codePointStart, codePoint, result);
@@ -757,7 +657,7 @@
     codePointStart=codePointLimit;
     if(codePointLimit==limit) {
         codePoint=U_SENTINEL;
-        return 0;
+        return static_cast<uint16_t>(trie->errorValue);
     }
     uint16_t result;
     UTRIE2_U16_NEXT16(trie, codePointLimit, limit, codePoint, result);
diff --git a/src/third_party/icu/source/common/utrie2.h b/src/third_party/icu/source/common/utrie2.h
index 36ea9b4..d1e1e15 100644
--- a/src/third_party/icu/source/common/utrie2.h
+++ b/src/third_party/icu/source/common/utrie2.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 ******************************************************************************
 *   file name:  utrie2.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -18,8 +20,8 @@
 #define __UTRIE2_H__
 
 #include "unicode/utypes.h"
+#include "unicode/utf8.h"
 #include "putilimp.h"
-#include "udataswp.h"
 
 U_CDECL_BEGIN
 
@@ -52,6 +54,8 @@
  *   is truncated, omitting both the BMP portion and the high range.
  * - There is a special small index for 2-byte UTF-8, and the initial data
  *   entries are designed for fast 1/2-byte UTF-8 lookup.
+ *   Starting with ICU 60, C0 and C1 are not recognized as UTF-8 lead bytes any more at all,
+ *   and the associated 2-byte indexes are unused.
  */
 
 /**
@@ -157,13 +161,13 @@
  * of code points with the same value as retrieved from the trie and
  * transformed by the UTrie2EnumValue function.
  *
- * The callback function can stop the enumeration by returning FALSE.
+ * The callback function can stop the enumeration by returning false.
  *
  * @param context an opaque pointer, as passed into utrie2_enum()
  * @param start the first code point in a contiguous range with value
  * @param end the last code point in a contiguous range with value (inclusive)
  * @param value the value that is set for all code points in [start..end]
- * @return FALSE to stop the enumeration
+ * @return false to stop the enumeration
  */
 typedef UBool U_CALLCONV
 UTrie2EnumRange(const void *context, UChar32 start, UChar32 end, uint32_t value);
@@ -252,7 +256,7 @@
 /**
  * Set a value in a range of code points [start..end].
  * All code points c with start<=c<=end will get the value if
- * overwrite is TRUE or if the old value is the initial value.
+ * overwrite is true or if the old value is the initial value.
  *
  * @param trie the unfrozen trie
  * @param start the first code point to get the value
@@ -294,7 +298,7 @@
  * Test if the trie is frozen. (See utrie2_freeze().)
  *
  * @param trie the trie
- * @return TRUE if the trie is frozen, that is, immutable, ready for serialization
+ * @return true if the trie is frozen, that is, immutable, ready for serialization
  *         and for use with fast macros
  */
 U_CAPI UBool U_EXPORT2
@@ -326,40 +330,6 @@
 /* Public UTrie2 API: miscellaneous functions ------------------------------- */
 
 /**
- * Get the UTrie version from 32-bit-aligned memory containing the serialized form
- * of either a UTrie (version 1) or a UTrie2 (version 2).
- *
- * @param data a pointer to 32-bit-aligned memory containing the serialized form
- *             of a UTrie, version 1 or 2
- * @param length the number of bytes available at data;
- *               can be more than necessary (see return value)
- * @param anyEndianOk If FALSE, only platform-endian serialized forms are recognized.
- *                    If TRUE, opposite-endian serialized forms are recognized as well.
- * @return the UTrie version of the serialized form, or 0 if it is not
- *         recognized as a serialized UTrie
- */
-U_CAPI int32_t U_EXPORT2
-utrie2_getVersion(const void *data, int32_t length, UBool anyEndianOk);
-
-/**
- * Swap a serialized UTrie2.
- * @internal
- */
-U_CAPI int32_t U_EXPORT2
-utrie2_swap(const UDataSwapper *ds,
-            const void *inData, int32_t length, void *outData,
-            UErrorCode *pErrorCode);
-
-/**
- * Swap a serialized UTrie or UTrie2.
- * @internal
- */
-U_CAPI int32_t U_EXPORT2
-utrie2_swapAnyVersion(const UDataSwapper *ds,
-                      const void *inData, int32_t length, void *outData,
-                      UErrorCode *pErrorCode);
-
-/**
  * Build a UTrie2 (version 2) from a UTrie (version 1).
  * Enumerates all values in the UTrie and builds a UTrie2 with the same values.
  * The resulting UTrie2 will be frozen.
@@ -700,10 +670,14 @@
     /* private: used by builder and unserialization functions */
     void *memory;           /* serialized bytes; NULL if not frozen yet */
     int32_t length;         /* number of serialized bytes at memory; 0 if not frozen yet */
-    UBool isMemoryOwned;    /* TRUE if the trie owns the memory */
+    UBool isMemoryOwned;    /* true if the trie owns the memory */
     UBool padding1;
     int16_t padding2;
     UNewTrie2 *newTrie;     /* builder object; NULL when frozen */
+
+#ifdef UTRIE2_DEBUG
+    const char *name;
+#endif
 };
 
 /**
@@ -822,7 +796,7 @@
  * Do not call directly.
  * @internal
  */
-U_INTERNAL int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 utrie2_internalU8NextIndex(const UTrie2 *trie, UChar32 c,
                            const uint8_t *src, const uint8_t *limit);
 
@@ -831,7 +805,7 @@
  * Do not call directly.
  * @internal
  */
-U_INTERNAL int32_t U_EXPORT2
+U_CAPI int32_t U_EXPORT2
 utrie2_internalU8PrevIndex(const UTrie2 *trie, UChar32 c,
                            const uint8_t *start, const uint8_t *src);
 
@@ -897,7 +871,7 @@
     (trie)->data[_UTRIE2_INDEX_FROM_CP(trie, asciiOffset, c)]
 
 /** Internal next-post-increment: get the next code point (c) and its data. */
-#define _UTRIE2_U16_NEXT(trie, data, src, limit, c, result) { \
+#define _UTRIE2_U16_NEXT(trie, data, src, limit, c, result) UPRV_BLOCK_MACRO_BEGIN { \
     { \
         uint16_t __c2; \
         (c)=*(src)++; \
@@ -911,10 +885,10 @@
             (result)=_UTRIE2_GET_FROM_SUPP((trie), data, (c)); \
         } \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /** Internal pre-decrement-previous: get the previous code point (c) and its data */
-#define _UTRIE2_U16_PREV(trie, data, start, src, c, result) { \
+#define _UTRIE2_U16_PREV(trie, data, start, src, c, result) UPRV_BLOCK_MACRO_BEGIN { \
     { \
         uint16_t __c2; \
         (c)=*--(src); \
@@ -926,34 +900,34 @@
             (result)=_UTRIE2_GET_FROM_SUPP((trie), data, (c)); \
         } \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /** Internal UTF-8 next-post-increment: get the next code point's data. */
-#define _UTRIE2_U8_NEXT(trie, ascii, data, src, limit, result) { \
+#define _UTRIE2_U8_NEXT(trie, ascii, data, src, limit, result) UPRV_BLOCK_MACRO_BEGIN { \
     uint8_t __lead=(uint8_t)*(src)++; \
-    if(__lead<0xc0) { \
+    if(U8_IS_SINGLE(__lead)) { \
         (result)=(trie)->ascii[__lead]; \
     } else { \
         uint8_t __t1, __t2; \
-        if( /* handle U+0000..U+07FF inline */ \
-            __lead<0xe0 && (src)<(limit) && \
+        if( /* handle U+0800..U+FFFF inline */ \
+            0xe0<=__lead && __lead<0xf0 && ((src)+1)<(limit) && \
+            U8_IS_VALID_LEAD3_AND_T1(__lead, __t1=(uint8_t)*(src)) && \
+            (__t2=(uint8_t)(*((src)+1)-0x80))<= 0x3f \
+        ) { \
+            (src)+=2; \
+            (result)=(trie)->data[ \
+                ((int32_t)((trie)->index[((__lead-0xe0)<<(12-UTRIE2_SHIFT_2))+ \
+                                         ((__t1&0x3f)<<(6-UTRIE2_SHIFT_2))+(__t2>>UTRIE2_SHIFT_2)]) \
+                <<UTRIE2_INDEX_SHIFT)+ \
+                (__t2&UTRIE2_DATA_MASK)]; \
+        } else if( /* handle U+0080..U+07FF inline */ \
+            __lead<0xe0 && __lead>=0xc2 && (src)<(limit) && \
             (__t1=(uint8_t)(*(src)-0x80))<=0x3f \
         ) { \
             ++(src); \
             (result)=(trie)->data[ \
                 (trie)->index[(UTRIE2_UTF8_2B_INDEX_2_OFFSET-0xc0)+__lead]+ \
                 __t1]; \
-        } else if( /* handle U+0000..U+CFFF inline */ \
-            __lead<0xed && ((src)+1)<(limit) && \
-            (__t1=(uint8_t)(*(src)-0x80))<=0x3f && (__lead>0xe0 || __t1>=0x20) && \
-            (__t2=(uint8_t)(*((src)+1)-0x80))<= 0x3f \
-        ) { \
-            (src)+=2; \
-            (result)=(trie)->data[ \
-                ((int32_t)((trie)->index[((__lead-0xe0)<<(12-UTRIE2_SHIFT_2))+ \
-                                         (__t1<<(6-UTRIE2_SHIFT_2))+(__t2>>UTRIE2_SHIFT_2)]) \
-                <<UTRIE2_INDEX_SHIFT)+ \
-                (__t2&UTRIE2_DATA_MASK)]; \
         } else { \
             int32_t __index=utrie2_internalU8NextIndex((trie), __lead, (const uint8_t *)(src), \
                                                                        (const uint8_t *)(limit)); \
@@ -961,12 +935,12 @@
             (result)=(trie)->data[__index>>3]; \
         } \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 /** Internal UTF-8 pre-decrement-previous: get the previous code point's data. */
-#define _UTRIE2_U8_PREV(trie, ascii, data, start, src, result) { \
+#define _UTRIE2_U8_PREV(trie, ascii, data, start, src, result) UPRV_BLOCK_MACRO_BEGIN { \
     uint8_t __b=(uint8_t)*--(src); \
-    if(__b<0x80) { \
+    if(U8_IS_SINGLE(__b)) { \
         (result)=(trie)->ascii[__b]; \
     } else { \
         int32_t __index=utrie2_internalU8PrevIndex((trie), __b, (const uint8_t *)(start), \
@@ -974,15 +948,8 @@
         (src)-=__index&7; \
         (result)=(trie)->data[__index>>3]; \
     } \
-}
+} UPRV_BLOCK_MACRO_END
 
 U_CDECL_END
 
-/**
- * Work around MSVC 2003 optimization bugs.
- */
-#if defined (U_HAVE_MSVC_2003_OR_EARLIER)
-#pragma optimize("", off)
-#endif
-
 #endif
diff --git a/src/third_party/icu/source/common/utrie2_builder.cpp b/src/third_party/icu/source/common/utrie2_builder.cpp
index 625e323..95ba2d8 100644
--- a/src/third_party/icu/source/common/utrie2_builder.cpp
+++ b/src/third_party/icu/source/common/utrie2_builder.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 ******************************************************************************
 *   file name:  utrie2_builder.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -22,17 +24,26 @@
 *   This file contains only the builder code.
 *   See utrie2.c for the runtime and enumeration code.
 */
+// #define UTRIE2_DEBUG
 #ifdef UTRIE2_DEBUG
 #   include <stdio.h>
 #endif
+// #define UCPTRIE_DEBUG
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/utypes.h"
+#ifdef UCPTRIE_DEBUG
+#include "unicode/ucptrie.h"
+#include "unicode/umutablecptrie.h"
+#include "ucptrie_impl.h"
+#endif
 #include "cmemory.h"
 #include "utrie2.h"
 #include "utrie2_impl.h"
 
-#include "utrie.h" /* for utrie2_fromUTrie() and utrie_swap() */
+#include "utrie.h"  // for utrie2_fromUTrie()
 
 /* Implementation notes ----------------------------------------------------- */
 
@@ -131,8 +142,14 @@
     trie->errorValue=errorValue;
     trie->highStart=0x110000;
     trie->newTrie=newTrie;
+#ifdef UTRIE2_DEBUG
+    trie->name="open";
+#endif
 
     newTrie->data=data;
+#ifdef UCPTRIE_DEBUG
+    newTrie->t3=umutablecptrie_open(initialValue, errorValue, pErrorCode);
+#endif
     newTrie->dataCapacity=UNEWTRIE2_INITIAL_DATA_LENGTH;
     newTrie->initialValue=initialValue;
     newTrie->errorValue=errorValue;
@@ -245,15 +262,23 @@
         uprv_free(trie);
         return NULL;
     }
+#ifdef UCPTRIE_DEBUG
+    if(other->t3==nullptr) {
+        trie->t3=nullptr;
+    } else {
+        UErrorCode errorCode=U_ZERO_ERROR;
+        trie->t3=umutablecptrie_clone(other->t3, &errorCode);
+    }
+#endif
     trie->dataCapacity=other->dataCapacity;
 
     /* clone data */
     uprv_memcpy(trie->index1, other->index1, sizeof(trie->index1));
-    uprv_memcpy(trie->index2, other->index2, other->index2Length*4);
+    uprv_memcpy(trie->index2, other->index2, (size_t)other->index2Length*4);
     trie->index2NullOffset=other->index2NullOffset;
     trie->index2Length=other->index2Length;
 
-    uprv_memcpy(trie->data, other->data, other->dataLength*4);
+    uprv_memcpy(trie->data, other->data, (size_t)other->dataLength*4);
     trie->dataNullOffset=other->dataNullOffset;
     trie->dataLength=other->dataLength;
 
@@ -261,7 +286,7 @@
     if(other->isCompacted) {
         trie->firstFreeBlock=0;
     } else {
-        uprv_memcpy(trie->map, other->map, (other->dataLength>>UTRIE2_SHIFT_2)*4);
+        uprv_memcpy(trie->map, other->map, ((size_t)other->dataLength>>UTRIE2_SHIFT_2)*4);
         trie->firstFreeBlock=other->firstFreeBlock;
     }
 
@@ -287,6 +312,7 @@
 
     trie=(UTrie2 *)uprv_malloc(sizeof(UTrie2));
     if(trie==NULL) {
+        *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
         return NULL;
     }
     uprv_memcpy(trie, other, sizeof(UTrie2));
@@ -311,6 +337,7 @@
     }
 
     if(trie->memory==NULL && trie->newTrie==NULL) {
+        *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
         uprv_free(trie);
         trie=NULL;
     }
@@ -342,6 +369,22 @@
 }
 
 #ifdef UTRIE2_DEBUG
+static long countInitial(const UTrie2 *trie) {
+    uint32_t initialValue=trie->initialValue;
+    int32_t length=trie->dataLength;
+    long count=0;
+    if(trie->data16!=nullptr) {
+        for(int32_t i=0; i<length; ++i) {
+            if(trie->data16[i]==initialValue) { ++count; }
+        }
+    } else {
+        for(int32_t i=0; i<length; ++i) {
+            if(trie->data32[i]==initialValue) { ++count; }
+        }
+    }
+    return count;
+}
+
 static void
 utrie_printLengths(const UTrie *trie) {
     long indexLength=trie->indexLength;
@@ -356,8 +399,8 @@
     long indexLength=trie->indexLength;
     long dataLength=(long)trie->dataLength;
     long totalLength=(long)sizeof(UTrie2Header)+indexLength*2+dataLength*(trie->data32!=NULL ? 4 : 2);
-    printf("**UTrie2Lengths(%s)** index:%6ld  data:%6ld  serialized:%6ld\n",
-           which, indexLength, dataLength, totalLength);
+    printf("**UTrie2Lengths(%s %s)** index:%6ld  data:%6ld  countInitial:%6ld  serialized:%6ld\n",
+           which, trie->name, indexLength, dataLength, countInitial(trie), totalLength);
 }
 #endif
 
@@ -541,7 +584,7 @@
             if(data==NULL) {
                 return -1;
             }
-            uprv_memcpy(data, trie->data, trie->dataLength*4);
+            uprv_memcpy(data, trie->data, (size_t)trie->dataLength*4);
             uprv_free(trie->data);
             trie->data=data;
             trie->dataCapacity=capacity;
@@ -621,6 +664,9 @@
         *pErrorCode=U_NO_WRITE_PERMISSION;
         return;
     }
+#ifdef UCPTRIE_DEBUG
+    umutablecptrie_set(trie->t3, c, value, pErrorCode);
+#endif
 
     block=getDataBlock(trie, c, forLSCP);
     if(block<0) {
@@ -716,6 +762,9 @@
         *pErrorCode=U_NO_WRITE_PERMISSION;
         return;
     }
+#ifdef UCPTRIE_DEBUG
+    umutablecptrie_setRange(newTrie->t3, start, end, value, pErrorCode);
+#endif
     if(!overwrite && value==newTrie->initialValue) {
         return; /* nothing to do */
     }
@@ -731,7 +780,7 @@
             return;
         }
 
-        nextStart=(start+UTRIE2_DATA_BLOCK_LENGTH)&~UTRIE2_DATA_MASK;
+        nextStart=(start+UTRIE2_DATA_MASK)&~UTRIE2_DATA_MASK;
         if(nextStart<=limit) {
             fillBlock(newTrie->data+block, start&UTRIE2_DATA_MASK, UTRIE2_DATA_BLOCK_LENGTH,
                       value, newTrie->initialValue, overwrite);
@@ -982,6 +1031,10 @@
  */
 static void
 compactData(UNewTrie2 *trie) {
+#ifdef UTRIE2_DEBUG
+    int32_t countSame=0, sumOverlaps=0;
+#endif
+
     int32_t start, newStart, movedStart;
     int32_t blockLength, overlap;
     int32_t i, mapIndex, blockCount;
@@ -1022,6 +1075,9 @@
         if( (movedStart=findSameDataBlock(trie->data, newStart, start, blockLength))
              >=0
         ) {
+#ifdef UTRIE2_DEBUG
+            ++countSame;
+#endif
             /* found an identical block, set the other block's index value for the current block */
             for(i=blockCount, mapIndex=start>>UTRIE2_SHIFT_2; i>0; --i) {
                 trie->map[mapIndex++]=movedStart;
@@ -1041,6 +1097,9 @@
             overlap>0 && !equal_uint32(trie->data+(newStart-overlap), trie->data+start, overlap);
             overlap-=UTRIE2_DATA_GRANULARITY) {}
 
+#ifdef UTRIE2_DEBUG
+            sumOverlaps+=overlap;
+#endif
         if(overlap>0 || newStart<start) {
             /* some overlap, or just move the whole block */
             movedStart=newStart-overlap;
@@ -1080,8 +1139,8 @@
 
 #ifdef UTRIE2_DEBUG
     /* we saved some space */
-    printf("compacting UTrie2: count of 32-bit data words %lu->%lu\n",
-            (long)trie->dataLength, (long)newStart);
+    printf("compacting UTrie2: count of 32-bit data words %lu->%lu  countSame=%ld  sumOverlaps=%ld\n",
+            (long)trie->dataLength, (long)newStart, (long)countSame, (long)sumOverlaps);
 #endif
 
     trie->dataLength=newStart;
@@ -1162,7 +1221,7 @@
 
 #ifdef UTRIE2_DEBUG
     /* we saved some space */
-    printf("compacting UTrie2: count of 16-bit index-2 words %lu->%lu\n",
+    printf("compacting UTrie2: count of 16-bit index words %lu->%lu\n",
             (long)trie->index2Length, (long)newStart);
 #endif
 
@@ -1192,7 +1251,7 @@
     trie->highStart=newTrie->highStart=highStart;
 
 #ifdef UTRIE2_DEBUG
-    printf("UTrie2: highStart U+%04lx  highValue 0x%lx  initialValue 0x%lx\n",
+    printf("UTrie2: highStart U+%06lx  highValue 0x%lx  initialValue 0x%lx\n",
             (long)highStart, (long)highValue, (long)trie->initialValue);
 #endif
 
@@ -1210,7 +1269,7 @@
         compactIndex2(newTrie);
 #ifdef UTRIE2_DEBUG
     } else {
-        printf("UTrie2: highStart U+%04lx  count of 16-bit index-2 words %lu->%lu\n",
+        printf("UTrie2: highStart U+%04lx  count of 16-bit index words %lu->%lu\n",
                 (long)highStart, (long)trie->newTrie->index2Length, (long)UTRIE2_INDEX_1_OFFSET);
 #endif
     }
@@ -1333,7 +1392,7 @@
     if(highStart<=0x10000) {
         trie->index2NullOffset=0xffff;
     } else {
-        trie->index2NullOffset=UTRIE2_INDEX_2_OFFSET+newTrie->index2NullOffset;
+        trie->index2NullOffset=static_cast<uint16_t>(UTRIE2_INDEX_2_OFFSET+newTrie->index2NullOffset);
     }
     trie->dataNullOffset=(uint16_t)(dataMove+newTrie->dataNullOffset);
     trie->highValueIndex=dataMove+trie->dataLength-UTRIE2_DATA_GRANULARITY;
@@ -1403,38 +1462,25 @@
         /* write 32-bit data values */
         trie->data16=NULL;
         trie->data32=(uint32_t *)dest16;
-        uprv_memcpy(dest16, newTrie->data, newTrie->dataLength*4);
+        uprv_memcpy(dest16, newTrie->data, (size_t)newTrie->dataLength*4);
         break;
     default:
         *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
         return;
     }
 
+#ifdef UTRIE2_DEBUG
+    utrie2_printLengths(trie, "");
+#endif
+
+#ifdef UCPTRIE_DEBUG
+    umutablecptrie_setName(newTrie->t3, trie->name);
+    ucptrie_close(
+        umutablecptrie_buildImmutable(
+            newTrie->t3, UCPTRIE_TYPE_FAST, (UCPTrieValueWidth)valueBits, pErrorCode));
+#endif
     /* Delete the UNewTrie2. */
     uprv_free(newTrie->data);
     uprv_free(newTrie);
     trie->newTrie=NULL;
 }
-
-/*
- * This is here to avoid a dependency from utrie2.cpp on utrie.c.
- * This file already depends on utrie.c.
- * Otherwise, this should be in utrie2.cpp right after utrie2_swap().
- */
-U_CAPI int32_t U_EXPORT2
-utrie2_swapAnyVersion(const UDataSwapper *ds,
-                      const void *inData, int32_t length, void *outData,
-                      UErrorCode *pErrorCode) {
-    if(U_SUCCESS(*pErrorCode)) {
-        switch(utrie2_getVersion(inData, length, TRUE)) {
-        case 1:
-            return utrie_swap(ds, inData, length, outData, pErrorCode);
-        case 2:
-            return utrie2_swap(ds, inData, length, outData, pErrorCode);
-        default:
-            *pErrorCode=U_INVALID_FORMAT_ERROR;
-            return 0;
-        }
-    }
-    return 0;
-}
diff --git a/src/third_party/icu/source/common/utrie2_impl.h b/src/third_party/icu/source/common/utrie2_impl.h
index ecb3b6f..2a14db3 100644
--- a/src/third_party/icu/source/common/utrie2_impl.h
+++ b/src/third_party/icu/source/common/utrie2_impl.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
@@ -6,7 +8,7 @@
 *
 ******************************************************************************
 *   file name:  utrie2_impl.h
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -20,22 +22,20 @@
 #ifndef __UTRIE2_IMPL_H__
 #define __UTRIE2_IMPL_H__
 
+#ifdef UCPTRIE_DEBUG
+#include "unicode/umutablecptrie.h"
+#endif
 #include "utrie2.h"
 
 /* Public UTrie2 API implementation ----------------------------------------- */
 
 /*
- * These definitions are mostly needed by utrie2.c,
+ * These definitions are mostly needed by utrie2.cpp,
  * but also by utrie2_serialize() and utrie2_swap().
  */
 
-/*
- * UTrie and UTrie2 signature values,
- * in platform endianness and opposite endianness.
- */
-#define UTRIE_SIG       0x54726965
-#define UTRIE_OE_SIG    0x65697254
-
+// UTrie2 signature values, in platform endianness and opposite endianness.
+// The UTrie2 signature ASCII byte values spell "Tri2".
 #define UTRIE2_SIG      0x54726932
 #define UTRIE2_OE_SIG   0x32697254
 
@@ -143,6 +143,9 @@
     int32_t index1[UNEWTRIE2_INDEX_1_LENGTH];
     int32_t index2[UNEWTRIE2_MAX_INDEX_2_LENGTH];
     uint32_t *data;
+#ifdef UCPTRIE_DEBUG
+    UMutableCPTrie *t3;
+#endif
 
     uint32_t initialValue, errorValue;
     int32_t index2Length, dataCapacity, dataLength;
diff --git a/src/third_party/icu/source/common/utrie_swap.cpp b/src/third_party/icu/source/common/utrie_swap.cpp
new file mode 100644
index 0000000..6e8b138
--- /dev/null
+++ b/src/third_party/icu/source/common/utrie_swap.cpp
@@ -0,0 +1,348 @@
+// © 2018 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+// utrie_swap.cpp
+// created: 2018aug08 Markus W. Scherer
+
+#include "unicode/utypes.h"
+#include "cmemory.h"
+#include "ucptrie_impl.h"
+#include "udataswp.h"
+#include "utrie.h"
+#include "utrie2_impl.h"
+
+// These functions for swapping different generations of ICU code point tries are here
+// so that their implementation files need not depend on swapper code,
+// need not depend on each other, and so that other swapper code
+// need not depend on other trie code.
+
+namespace {
+
+constexpr int32_t ASCII_LIMIT = 0x80;
+
+}  // namespace
+
+U_CAPI int32_t U_EXPORT2
+utrie_swap(const UDataSwapper *ds,
+           const void *inData, int32_t length, void *outData,
+           UErrorCode *pErrorCode) {
+    const UTrieHeader *inTrie;
+    UTrieHeader trie;
+    int32_t size;
+    UBool dataIs32;
+
+    if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
+        return 0;
+    }
+    if(ds==NULL || inData==NULL || (length>=0 && outData==NULL)) {
+        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
+        return 0;
+    }
+
+    /* setup and swapping */
+    if(length>=0 && (uint32_t)length<sizeof(UTrieHeader)) {
+        *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
+        return 0;
+    }
+
+    inTrie=(const UTrieHeader *)inData;
+    trie.signature=ds->readUInt32(inTrie->signature);
+    trie.options=ds->readUInt32(inTrie->options);
+    trie.indexLength=udata_readInt32(ds, inTrie->indexLength);
+    trie.dataLength=udata_readInt32(ds, inTrie->dataLength);
+
+    if( trie.signature!=0x54726965 ||
+        (trie.options&UTRIE_OPTIONS_SHIFT_MASK)!=UTRIE_SHIFT ||
+        ((trie.options>>UTRIE_OPTIONS_INDEX_SHIFT)&UTRIE_OPTIONS_SHIFT_MASK)!=UTRIE_INDEX_SHIFT ||
+        trie.indexLength<UTRIE_BMP_INDEX_LENGTH ||
+        (trie.indexLength&(UTRIE_SURROGATE_BLOCK_COUNT-1))!=0 ||
+        trie.dataLength<UTRIE_DATA_BLOCK_LENGTH ||
+        (trie.dataLength&(UTRIE_DATA_GRANULARITY-1))!=0 ||
+        ((trie.options&UTRIE_OPTIONS_LATIN1_IS_LINEAR)!=0 && trie.dataLength<(UTRIE_DATA_BLOCK_LENGTH+0x100))
+    ) {
+        *pErrorCode=U_INVALID_FORMAT_ERROR; /* not a UTrie */
+        return 0;
+    }
+
+    dataIs32=(UBool)((trie.options&UTRIE_OPTIONS_DATA_IS_32_BIT)!=0);
+    size=sizeof(UTrieHeader)+trie.indexLength*2+trie.dataLength*(dataIs32?4:2);
+
+    if(length>=0) {
+        UTrieHeader *outTrie;
+
+        if(length<size) {
+            *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
+            return 0;
+        }
+
+        outTrie=(UTrieHeader *)outData;
+
+        /* swap the header */
+        ds->swapArray32(ds, inTrie, sizeof(UTrieHeader), outTrie, pErrorCode);
+
+        /* swap the index and the data */
+        if(dataIs32) {
+            ds->swapArray16(ds, inTrie+1, trie.indexLength*2, outTrie+1, pErrorCode);
+            ds->swapArray32(ds, (const uint16_t *)(inTrie+1)+trie.indexLength, trie.dataLength*4,
+                                     (uint16_t *)(outTrie+1)+trie.indexLength, pErrorCode);
+        } else {
+            ds->swapArray16(ds, inTrie+1, (trie.indexLength+trie.dataLength)*2, outTrie+1, pErrorCode);
+        }
+    }
+
+    return size;
+}
+
+U_CAPI int32_t U_EXPORT2
+utrie2_swap(const UDataSwapper *ds,
+            const void *inData, int32_t length, void *outData,
+            UErrorCode *pErrorCode) {
+    const UTrie2Header *inTrie;
+    UTrie2Header trie;
+    int32_t dataLength, size;
+    UTrie2ValueBits valueBits;
+
+    if(U_FAILURE(*pErrorCode)) {
+        return 0;
+    }
+    if(ds==NULL || inData==NULL || (length>=0 && outData==NULL)) {
+        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
+        return 0;
+    }
+
+    /* setup and swapping */
+    if(length>=0 && length<(int32_t)sizeof(UTrie2Header)) {
+        *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
+        return 0;
+    }
+
+    inTrie=(const UTrie2Header *)inData;
+    trie.signature=ds->readUInt32(inTrie->signature);
+    trie.options=ds->readUInt16(inTrie->options);
+    trie.indexLength=ds->readUInt16(inTrie->indexLength);
+    trie.shiftedDataLength=ds->readUInt16(inTrie->shiftedDataLength);
+
+    valueBits=(UTrie2ValueBits)(trie.options&UTRIE2_OPTIONS_VALUE_BITS_MASK);
+    dataLength=(int32_t)trie.shiftedDataLength<<UTRIE2_INDEX_SHIFT;
+
+    if( trie.signature!=UTRIE2_SIG ||
+        valueBits<0 || UTRIE2_COUNT_VALUE_BITS<=valueBits ||
+        trie.indexLength<UTRIE2_INDEX_1_OFFSET ||
+        dataLength<UTRIE2_DATA_START_OFFSET
+    ) {
+        *pErrorCode=U_INVALID_FORMAT_ERROR; /* not a UTrie */
+        return 0;
+    }
+
+    size=sizeof(UTrie2Header)+trie.indexLength*2;
+    switch(valueBits) {
+    case UTRIE2_16_VALUE_BITS:
+        size+=dataLength*2;
+        break;
+    case UTRIE2_32_VALUE_BITS:
+        size+=dataLength*4;
+        break;
+    default:
+        *pErrorCode=U_INVALID_FORMAT_ERROR;
+        return 0;
+    }
+
+    if(length>=0) {
+        UTrie2Header *outTrie;
+
+        if(length<size) {
+            *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
+            return 0;
+        }
+
+        outTrie=(UTrie2Header *)outData;
+
+        /* swap the header */
+        ds->swapArray32(ds, &inTrie->signature, 4, &outTrie->signature, pErrorCode);
+        ds->swapArray16(ds, &inTrie->options, 12, &outTrie->options, pErrorCode);
+
+        /* swap the index and the data */
+        switch(valueBits) {
+        case UTRIE2_16_VALUE_BITS:
+            ds->swapArray16(ds, inTrie+1, (trie.indexLength+dataLength)*2, outTrie+1, pErrorCode);
+            break;
+        case UTRIE2_32_VALUE_BITS:
+            ds->swapArray16(ds, inTrie+1, trie.indexLength*2, outTrie+1, pErrorCode);
+            ds->swapArray32(ds, (const uint16_t *)(inTrie+1)+trie.indexLength, dataLength*4,
+                                     (uint16_t *)(outTrie+1)+trie.indexLength, pErrorCode);
+            break;
+        default:
+            *pErrorCode=U_INVALID_FORMAT_ERROR;
+            return 0;
+        }
+    }
+
+    return size;
+}
+
+U_CAPI int32_t U_EXPORT2
+ucptrie_swap(const UDataSwapper *ds,
+             const void *inData, int32_t length, void *outData,
+             UErrorCode *pErrorCode) {
+    const UCPTrieHeader *inTrie;
+    UCPTrieHeader trie;
+    int32_t dataLength, size;
+    UCPTrieValueWidth valueWidth;
+
+    if(U_FAILURE(*pErrorCode)) {
+        return 0;
+    }
+    if(ds==nullptr || inData==nullptr || (length>=0 && outData==nullptr)) {
+        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
+        return 0;
+    }
+
+    /* setup and swapping */
+    if(length>=0 && length<(int32_t)sizeof(UCPTrieHeader)) {
+        *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
+        return 0;
+    }
+
+    inTrie=(const UCPTrieHeader *)inData;
+    trie.signature=ds->readUInt32(inTrie->signature);
+    trie.options=ds->readUInt16(inTrie->options);
+    trie.indexLength=ds->readUInt16(inTrie->indexLength);
+    trie.dataLength = ds->readUInt16(inTrie->dataLength);
+
+    UCPTrieType type = (UCPTrieType)((trie.options >> 6) & 3);
+    valueWidth = (UCPTrieValueWidth)(trie.options & UCPTRIE_OPTIONS_VALUE_BITS_MASK);
+    dataLength = ((int32_t)(trie.options & UCPTRIE_OPTIONS_DATA_LENGTH_MASK) << 4) | trie.dataLength;
+
+    int32_t minIndexLength = type == UCPTRIE_TYPE_FAST ?
+        UCPTRIE_BMP_INDEX_LENGTH : UCPTRIE_SMALL_INDEX_LENGTH;
+    if( trie.signature!=UCPTRIE_SIG ||
+        type > UCPTRIE_TYPE_SMALL ||
+        (trie.options & UCPTRIE_OPTIONS_RESERVED_MASK) != 0 ||
+        valueWidth > UCPTRIE_VALUE_BITS_8 ||
+        trie.indexLength < minIndexLength ||
+        dataLength < ASCII_LIMIT
+    ) {
+        *pErrorCode=U_INVALID_FORMAT_ERROR; /* not a UCPTrie */
+        return 0;
+    }
+
+    size=sizeof(UCPTrieHeader)+trie.indexLength*2;
+    switch(valueWidth) {
+    case UCPTRIE_VALUE_BITS_16:
+        size+=dataLength*2;
+        break;
+    case UCPTRIE_VALUE_BITS_32:
+        size+=dataLength*4;
+        break;
+    case UCPTRIE_VALUE_BITS_8:
+        size+=dataLength;
+        break;
+    default:
+        *pErrorCode=U_INVALID_FORMAT_ERROR;
+        return 0;
+    }
+
+    if(length>=0) {
+        UCPTrieHeader *outTrie;
+
+        if(length<size) {
+            *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
+            return 0;
+        }
+
+        outTrie=(UCPTrieHeader *)outData;
+
+        /* swap the header */
+        ds->swapArray32(ds, &inTrie->signature, 4, &outTrie->signature, pErrorCode);
+        ds->swapArray16(ds, &inTrie->options, 12, &outTrie->options, pErrorCode);
+
+        /* swap the index */
+        const uint16_t *inIndex=reinterpret_cast<const uint16_t *>(inTrie+1);
+        uint16_t *outIndex=reinterpret_cast<uint16_t *>(outTrie+1);
+        ds->swapArray16(ds, inIndex, trie.indexLength*2, outIndex, pErrorCode);
+
+        /* swap the data */
+        const uint16_t *inData=inIndex+trie.indexLength;
+        uint16_t *outData=outIndex+trie.indexLength;
+        switch(valueWidth) {
+        case UCPTRIE_VALUE_BITS_16:
+            ds->swapArray16(ds, inData, dataLength*2, outData, pErrorCode);
+            break;
+        case UCPTRIE_VALUE_BITS_32:
+            ds->swapArray32(ds, inData, dataLength*4, outData, pErrorCode);
+            break;
+        case UCPTRIE_VALUE_BITS_8:
+            if(inTrie!=outTrie) {
+                uprv_memmove(outData, inData, dataLength);
+            }
+            break;
+        default:
+            *pErrorCode=U_INVALID_FORMAT_ERROR;
+            return 0;
+        }
+    }
+
+    return size;
+}
+
+namespace {
+
+/**
+ * Gets the trie version from 32-bit-aligned memory containing the serialized form
+ * of a UTrie (version 1), a UTrie2 (version 2), or a UCPTrie (version 3).
+ *
+ * @param data a pointer to 32-bit-aligned memory containing the serialized form of a trie
+ * @param length the number of bytes available at data;
+ *               can be more than necessary (see return value)
+ * @param anyEndianOk If FALSE, only platform-endian serialized forms are recognized.
+ *                    If TRUE, opposite-endian serialized forms are recognized as well.
+ * @return the trie version of the serialized form, or 0 if it is not
+ *         recognized as a serialized trie
+ */
+int32_t
+getVersion(const void *data, int32_t length, UBool anyEndianOk) {
+    uint32_t signature;
+    if(length<16 || data==nullptr || (U_POINTER_MASK_LSB(data, 3)!=0)) {
+        return 0;
+    }
+    signature=*(const uint32_t *)data;
+    if(signature==UCPTRIE_SIG) {
+        return 3;
+    }
+    if(anyEndianOk && signature==UCPTRIE_OE_SIG) {
+        return 3;
+    }
+    if(signature==UTRIE2_SIG) {
+        return 2;
+    }
+    if(anyEndianOk && signature==UTRIE2_OE_SIG) {
+        return 2;
+    }
+    if(signature==UTRIE_SIG) {
+        return 1;
+    }
+    if(anyEndianOk && signature==UTRIE_OE_SIG) {
+        return 1;
+    }
+    return 0;
+}
+
+}  // namespace
+
+U_CAPI int32_t U_EXPORT2
+utrie_swapAnyVersion(const UDataSwapper *ds,
+                     const void *inData, int32_t length, void *outData,
+                     UErrorCode *pErrorCode) {
+    if(U_FAILURE(*pErrorCode)) { return 0; }
+    switch(getVersion(inData, length, TRUE)) {
+    case 1:
+        return utrie_swap(ds, inData, length, outData, pErrorCode);
+    case 2:
+        return utrie2_swap(ds, inData, length, outData, pErrorCode);
+    case 3:
+        return ucptrie_swap(ds, inData, length, outData, pErrorCode);
+    default:
+        *pErrorCode=U_INVALID_FORMAT_ERROR;
+        return 0;
+    }
+}
diff --git a/src/third_party/icu/source/common/uts46.cpp b/src/third_party/icu/source/common/uts46.cpp
index 327f39c..e7f556b 100644
--- a/src/third_party/icu/source/common/uts46.cpp
+++ b/src/third_party/icu/source/common/uts46.cpp
@@ -1,10 +1,12 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 *   Copyright (C) 2010-2015, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *******************************************************************************
 *   file name:  uts46.cpp
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -16,7 +18,9 @@
 
 #if !UCONFIG_NO_IDNA
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "unicode/idna.h"
 #include "unicode/normalizer2.h"
 #include "unicode/uscript.h"
@@ -69,7 +73,7 @@
 IDNA::~IDNA() {}
 
 void
-IDNA::labelToASCII_UTF8(const StringPiece &label, ByteSink &dest,
+IDNA::labelToASCII_UTF8(StringPiece label, ByteSink &dest,
                         IDNAInfo &info, UErrorCode &errorCode) const {
     if(U_SUCCESS(errorCode)) {
         UnicodeString destString;
@@ -79,7 +83,7 @@
 }
 
 void
-IDNA::labelToUnicodeUTF8(const StringPiece &label, ByteSink &dest,
+IDNA::labelToUnicodeUTF8(StringPiece label, ByteSink &dest,
                          IDNAInfo &info, UErrorCode &errorCode) const {
     if(U_SUCCESS(errorCode)) {
         UnicodeString destString;
@@ -89,7 +93,7 @@
 }
 
 void
-IDNA::nameToASCII_UTF8(const StringPiece &name, ByteSink &dest,
+IDNA::nameToASCII_UTF8(StringPiece name, ByteSink &dest,
                        IDNAInfo &info, UErrorCode &errorCode) const {
     if(U_SUCCESS(errorCode)) {
         UnicodeString destString;
@@ -99,7 +103,7 @@
 }
 
 void
-IDNA::nameToUnicodeUTF8(const StringPiece &name, ByteSink &dest,
+IDNA::nameToUnicodeUTF8(StringPiece name, ByteSink &dest,
                         IDNAInfo &info, UErrorCode &errorCode) const {
     if(U_SUCCESS(errorCode)) {
         UnicodeString destString;
@@ -132,19 +136,19 @@
                   IDNAInfo &info, UErrorCode &errorCode) const;
 
     virtual void
-    labelToASCII_UTF8(const StringPiece &label, ByteSink &dest,
+    labelToASCII_UTF8(StringPiece label, ByteSink &dest,
                       IDNAInfo &info, UErrorCode &errorCode) const;
 
     virtual void
-    labelToUnicodeUTF8(const StringPiece &label, ByteSink &dest,
+    labelToUnicodeUTF8(StringPiece label, ByteSink &dest,
                        IDNAInfo &info, UErrorCode &errorCode) const;
 
     virtual void
-    nameToASCII_UTF8(const StringPiece &name, ByteSink &dest,
+    nameToASCII_UTF8(StringPiece name, ByteSink &dest,
                      IDNAInfo &info, UErrorCode &errorCode) const;
 
     virtual void
-    nameToUnicodeUTF8(const StringPiece &name, ByteSink &dest,
+    nameToUnicodeUTF8(StringPiece name, ByteSink &dest,
                       IDNAInfo &info, UErrorCode &errorCode) const;
 
 private:
@@ -155,7 +159,7 @@
             IDNAInfo &info, UErrorCode &errorCode) const;
 
     void
-    processUTF8(const StringPiece &src,
+    processUTF8(StringPiece src,
                 UBool isLabel, UBool toASCII,
                 ByteSink &dest,
                 IDNAInfo &info, UErrorCode &errorCode) const;
@@ -252,25 +256,25 @@
 }
 
 void
-UTS46::labelToASCII_UTF8(const StringPiece &label, ByteSink &dest,
+UTS46::labelToASCII_UTF8(StringPiece label, ByteSink &dest,
                          IDNAInfo &info, UErrorCode &errorCode) const {
     processUTF8(label, TRUE, TRUE, dest, info, errorCode);
 }
 
 void
-UTS46::labelToUnicodeUTF8(const StringPiece &label, ByteSink &dest,
+UTS46::labelToUnicodeUTF8(StringPiece label, ByteSink &dest,
                           IDNAInfo &info, UErrorCode &errorCode) const {
     processUTF8(label, TRUE, FALSE, dest, info, errorCode);
 }
 
 void
-UTS46::nameToASCII_UTF8(const StringPiece &name, ByteSink &dest,
+UTS46::nameToASCII_UTF8(StringPiece name, ByteSink &dest,
                         IDNAInfo &info, UErrorCode &errorCode) const {
     processUTF8(name, FALSE, TRUE, dest, info, errorCode);
 }
 
 void
-UTS46::nameToUnicodeUTF8(const StringPiece &name, ByteSink &dest,
+UTS46::nameToUnicodeUTF8(StringPiece name, ByteSink &dest,
                          IDNAInfo &info, UErrorCode &errorCode) const {
     processUTF8(name, FALSE, FALSE, dest, info, errorCode);
 }
@@ -402,7 +406,7 @@
 }
 
 void
-UTS46::processUTF8(const StringPiece &src,
+UTS46::processUTF8(StringPiece src,
                    UBool isLabel, UBool toASCII,
                    ByteSink &dest,
                    IDNAInfo &info, UErrorCode &errorCode) const {
@@ -556,7 +560,10 @@
             destArray=dest.getBuffer();
             destLength+=newLength-labelLength;
             labelLimit=labelStart+=newLength+1;
-        } else if(0xdf<=c && c<=0x200d && (c==0xdf || c==0x3c2 || c>=0x200c)) {
+            continue;
+        } else if(c<0xdf) {
+            // pass
+        } else if(c<=0x200d && (c==0xdf || c==0x3c2 || c>=0x200c)) {
             info.isTransDiff=TRUE;
             if(doMapDevChars) {
                 destLength=mapDevChars(dest, labelStart, labelLimit, errorCode);
@@ -564,15 +571,23 @@
                     return dest;
                 }
                 destArray=dest.getBuffer();
-                // Do not increment labelLimit in case c was removed.
                 // All deviation characters have been mapped, no need to check for them again.
                 doMapDevChars=FALSE;
-            } else {
-                ++labelLimit;
+                // Do not increment labelLimit in case c was removed.
+                continue;
             }
-        } else {
-            ++labelLimit;
+        } else if(U16_IS_SURROGATE(c)) {
+            if(U16_IS_SURROGATE_LEAD(c) ?
+                    (labelLimit+1)==destLength || !U16_IS_TRAIL(destArray[labelLimit+1]) :
+                    labelLimit==labelStart || !U16_IS_LEAD(destArray[labelLimit-1])) {
+                // Map an unpaired surrogate to U+FFFD before normalization so that when
+                // that removes characters we do not turn two unpaired ones into a pair.
+                info.labelErrors|=UIDNA_ERROR_DISALLOWED;
+                dest.setCharAt(labelLimit, 0xfffd);
+                destArray=dest.getBuffer();
+            }
         }
+        ++labelLimit;
     }
     // Permit an empty label at the end (0<labelStart==labelLimit==destLength is ok)
     // but not an empty label elsewhere nor a completely empty domain name.
@@ -702,6 +717,16 @@
     UBool wasPunycode;
     if(labelLength>=4 && label[0]==0x78 && label[1]==0x6e && label[2]==0x2d && label[3]==0x2d) {
         // Label starts with "xn--", try to un-Punycode it.
+        // In IDNA2008, labels like "xn--" (decodes to an empty string) and
+        // "xn--ASCII-" (decodes to just "ASCII") fail the round-trip validation from
+        // comparing the ToUnicode input with the back-to-ToASCII output.
+        // They are alternate encodings of the respective ASCII labels.
+        // Ignore "xn---" here: It will fail Punycode.decode() which logically comes before
+        // the round-trip verification.
+        if(labelLength==4 || (labelLength>5 && label[labelLength-1]==u'-')) {
+            info.labelErrors|=UIDNA_ERROR_INVALID_ACE_LABEL;
+            return markBadACELabel(dest, labelStart, labelLength, toASCII, info, errorCode);
+        }
         wasPunycode=TRUE;
         UChar *unicodeBuffer=fromPunycode.getBuffer(-1);  // capacity==-1: most labels should fit
         if(unicodeBuffer==NULL) {
@@ -913,10 +938,10 @@
     UBool isASCII=TRUE;
     UBool onlyLDH=TRUE;
     const UChar *label=dest.getBuffer()+labelStart;
-    // Ok to cast away const because we own the UnicodeString.
-    UChar *s=(UChar *)label+4;  // After the initial "xn--".
     const UChar *limit=label+labelLength;
-    do {
+    // Start after the initial "xn--".
+    // Ok to cast away const because we own the UnicodeString.
+    for(UChar *s=const_cast<UChar *>(label+4); s<limit; ++s) {
         UChar c=*s;
         if(c<=0x7f) {
             if(c==0x2e) {
@@ -933,7 +958,7 @@
         } else {
             isASCII=onlyLDH=FALSE;
         }
-    } while(++s<limit);
+    }
     if(onlyLDH) {
         dest.insert(labelStart+labelLength, (UChar)0xfffd);
         if(dest.isBogus()) {
@@ -1014,8 +1039,8 @@
     ) {
         info.isOkBiDi=FALSE;
     }
-    // Get the directionalities of the intervening characters.
-    uint32_t mask=0;
+    // Add the directionalities of the intervening characters.
+    uint32_t mask=firstMask|lastMask;
     while(i<labelLength) {
         U16_NEXT_UNSAFE(label, i, c);
         mask|=U_MASK(u_charDirection(c));
@@ -1044,7 +1069,7 @@
     // label. [...]
     // The following rule, consisting of six conditions, applies to labels
     // in BIDI domain names.
-    if(((firstMask|mask|lastMask)&R_AL_AN_MASK)!=0) {
+    if((mask&R_AL_AN_MASK)!=0) {
         info.isBiDi=TRUE;
     }
 }
@@ -1125,7 +1150,6 @@
 
 UBool
 UTS46::isLabelOkContextJ(const UChar *label, int32_t labelLength) const {
-    const UBiDiProps *bdp=ubidi_getSingleton();
     // [IDNA2008-Tables]
     // 200C..200D  ; CONTEXTJ    # ZERO WIDTH NON-JOINER..ZERO WIDTH JOINER
     for(int32_t i=0; i<labelLength; ++i) {
@@ -1147,7 +1171,7 @@
             }
             // check precontext (Joining_Type:{L,D})(Joining_Type:T)*
             for(;;) {
-                UJoiningType type=ubidi_getJoiningType(bdp, c);
+                UJoiningType type=ubidi_getJoiningType(c);
                 if(type==U_JT_TRANSPARENT) {
                     if(j==0) {
                         return FALSE;
@@ -1165,7 +1189,7 @@
                     return FALSE;
                 }
                 U16_NEXT_UNSAFE(label, j, c);
-                UJoiningType type=ubidi_getJoiningType(bdp, c);
+                UJoiningType type=ubidi_getJoiningType(c);
                 if(type==U_JT_TRANSPARENT) {
                     // just skip this character
                 } else if(type==U_JT_RIGHT_JOINING || type==U_JT_DUAL_JOINING) {
@@ -1414,7 +1438,7 @@
     if(!checkArgs(label, length, dest, capacity, pInfo, pErrorCode)) {
         return 0;
     }
-    StringPiece src(label, length<0 ? uprv_strlen(label) : length);
+    StringPiece src(label, length<0 ? static_cast<int32_t>(uprv_strlen(label)) : length);
     CheckedArrayByteSink sink(dest, capacity);
     IDNAInfo info;
     reinterpret_cast<const IDNA *>(idna)->labelToASCII_UTF8(src, sink, info, *pErrorCode);
@@ -1430,7 +1454,7 @@
     if(!checkArgs(label, length, dest, capacity, pInfo, pErrorCode)) {
         return 0;
     }
-    StringPiece src(label, length<0 ? uprv_strlen(label) : length);
+    StringPiece src(label, length<0 ? static_cast<int32_t>(uprv_strlen(label)) : length);
     CheckedArrayByteSink sink(dest, capacity);
     IDNAInfo info;
     reinterpret_cast<const IDNA *>(idna)->labelToUnicodeUTF8(src, sink, info, *pErrorCode);
@@ -1446,7 +1470,7 @@
     if(!checkArgs(name, length, dest, capacity, pInfo, pErrorCode)) {
         return 0;
     }
-    StringPiece src(name, length<0 ? uprv_strlen(name) : length);
+    StringPiece src(name, length<0 ? static_cast<int32_t>(uprv_strlen(name)) : length);
     CheckedArrayByteSink sink(dest, capacity);
     IDNAInfo info;
     reinterpret_cast<const IDNA *>(idna)->nameToASCII_UTF8(src, sink, info, *pErrorCode);
@@ -1462,7 +1486,7 @@
     if(!checkArgs(name, length, dest, capacity, pInfo, pErrorCode)) {
         return 0;
     }
-    StringPiece src(name, length<0 ? uprv_strlen(name) : length);
+    StringPiece src(name, length<0 ? static_cast<int32_t>(uprv_strlen(name)) : length);
     CheckedArrayByteSink sink(dest, capacity);
     IDNAInfo info;
     reinterpret_cast<const IDNA *>(idna)->nameToUnicodeUTF8(src, sink, info, *pErrorCode);
diff --git a/src/third_party/icu/source/common/utypeinfo.h b/src/third_party/icu/source/common/utypeinfo.h
index 6874c6b..c666373 100644
--- a/src/third_party/icu/source/common/utypeinfo.h
+++ b/src/third_party/icu/source/common/utypeinfo.h
@@ -1,7 +1,9 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
-*   Copyright (C) 2012-2014, International Business Machines
+*   Copyright (C) 2012-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *
 ******************************************************************************
@@ -11,18 +13,18 @@
 #define __UTYPEINFO_H__
 
 // Windows header <typeinfo> does not define 'exception' in 'std' namespace.
-// Therefore, a project using ICU cannot be compiled with _HAS_EXCEPTION
+// Therefore, a project using ICU cannot be compiled with _HAS_EXCEPTIONS
 // set to 0 on Windows with Visual Studio. To work around that, we have to
-// include <exception> explicilty and add using statement below.
+// include <exception> explicitly and add using statement below.
 // Whenever 'typeid' is used, this header has to be included
 // instead of <typeinfo>.
-// Visual Stuido 10 emits warning 4275 with this change. If you compile
+// Visual Studio 10 emits warning 4275 with this change. If you compile
 // with exception disabled, you have to suppress warning 4275.
 #if defined(_MSC_VER) && _HAS_EXCEPTIONS == 0
 #include <exception>
 using std::exception;
 #endif
-#if !defined(_MSC_VER)
+#if defined(__GLIBCXX__)
 namespace std { class type_info; } // WORKAROUND: http://llvm.org/bugs/show_bug.cgi?id=13364
 #endif
 #include <typeinfo>  // for 'typeid' to work
diff --git a/src/third_party/icu/source/common/utypes.c b/src/third_party/icu/source/common/utypes.cpp
similarity index 95%
rename from src/third_party/icu/source/common/utypes.c
rename to src/third_party/icu/source/common/utypes.cpp
index 6ff8460..63e05b1 100644
--- a/src/third_party/icu/source/common/utypes.c
+++ b/src/third_party/icu/source/common/utypes.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
@@ -102,7 +104,8 @@
     "U_INVALID_STATE_ERROR",
     "U_COLLATOR_VERSION_MISMATCH",
     "U_USELESS_COLLATOR_ERROR",
-    "U_NO_WRITE_PERMISSION"
+    "U_NO_WRITE_PERMISSION",
+    "U_INPUT_TOO_LONG_ERROR"
 };
 static const char * const
 _uFmtErrorName[U_FMT_PARSE_ERROR_LIMIT - U_FMT_PARSE_ERROR_START] = {
@@ -123,7 +126,9 @@
     "U_UNDEFINED_KEYWORD",
     "U_DEFAULT_KEYWORD_MISSING",
     "U_DECIMAL_NUMBER_SYNTAX_ERROR",
-    "U_FORMAT_INEXACT_ERROR"
+    "U_FORMAT_INEXACT_ERROR",
+    "U_NUMBER_ARG_OUTOFBOUNDS_ERROR",
+    "U_NUMBER_SKELETON_SYNTAX_ERROR",
 };
 
 static const char * const
diff --git a/src/third_party/icu/source/common/uvector.cpp b/src/third_party/icu/source/common/uvector.cpp
index b55f277..72bec15 100644
--- a/src/third_party/icu/source/common/uvector.cpp
+++ b/src/third_party/icu/source/common/uvector.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 * Copyright (C) 1999-2013, International Business Machines Corporation and
@@ -8,7 +10,9 @@
 **********************************************************************
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "uvector.h"
 #include "cmemory.h"
 #include "uarrsort.h"
diff --git a/src/third_party/icu/source/common/uvector.h b/src/third_party/icu/source/common/uvector.h
index 29cda39..a2bef92 100644
--- a/src/third_party/icu/source/common/uvector.h
+++ b/src/third_party/icu/source/common/uvector.h
@@ -1,6 +1,8 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
-*   Copyright (C) 1999-2013, International Business Machines
+*   Copyright (C) 1999-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 **********************************************************************
 *   Date        Name        Description
@@ -59,10 +61,10 @@
  *
  * <p>In order to implement methods such as contains() and indexOf(),
  * UVector needs a way to compare objects for equality.  To do so, it
- * uses a comparison frunction, or "comparer."  If the comparer is not
+ * uses a comparison function, or "comparer."  If the comparer is not
  * set, or is set to zero, then all such methods will act as if the
  * vector contains no element.  That is, indexOf() will always return
- * -1, contains() will always return FALSE, etc.
+ * -1, contains() will always return false, etc.
  *
  * <p><b>To do</b>
  *
@@ -140,19 +142,19 @@
 
     UBool equals(const UVector &other) const;
 
-    void* firstElement(void) const;
+    inline void* firstElement(void) const;
 
-    void* lastElement(void) const;
+    inline void* lastElement(void) const;
 
-    int32_t lastElementi(void) const;
+    inline int32_t lastElementi(void) const;
 
     int32_t indexOf(void* obj, int32_t startIndex = 0) const;
 
     int32_t indexOf(int32_t obj, int32_t startIndex = 0) const;
 
-    UBool contains(void* obj) const;
+    inline UBool contains(void* obj) const;
 
-    UBool contains(int32_t obj) const;
+    inline UBool contains(int32_t obj) const;
 
     UBool containsAll(const UVector& other) const;
 
@@ -166,9 +168,9 @@
 
     void removeAllElements();
 
-    int32_t size(void) const;
+    inline int32_t size(void) const;
 
-    UBool isEmpty(void) const;
+    inline UBool isEmpty(void) const;
 
     UBool ensureCapacity(int32_t minimumCapacity, UErrorCode &status);
 
@@ -193,7 +195,7 @@
 
     UElementsAreEqual *setComparer(UElementsAreEqual *c);
 
-    void* operator[](int32_t index) const;
+    inline void* operator[](int32_t index) const;
 
     /**
      * Removes the element at the given index from this vector and
@@ -307,19 +309,19 @@
     // It's okay not to have a virtual destructor (in UVector)
     // because UStack has no special cleanup to do.
 
-    UBool empty(void) const;
+    inline UBool empty(void) const;
 
-    void* peek(void) const;
+    inline void* peek(void) const;
 
-    int32_t peeki(void) const;
+    inline int32_t peeki(void) const;
     
     void* pop(void);
     
     int32_t popi(void);
     
-    void* push(void* obj, UErrorCode &status);
+    inline void* push(void* obj, UErrorCode &status);
 
-    int32_t push(int32_t i, UErrorCode &status);
+    inline int32_t push(int32_t i, UErrorCode &status);
 
     /*
     If the object o occurs as an item in this stack,
diff --git a/src/third_party/icu/source/common/uvectr32.cpp b/src/third_party/icu/source/common/uvectr32.cpp
index 9b89510..4b8001d 100644
--- a/src/third_party/icu/source/common/uvectr32.cpp
+++ b/src/third_party/icu/source/common/uvectr32.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 * Copyright (C) 1999-2015, International Business Machines Corporation and
@@ -8,8 +10,10 @@
 **********************************************************************
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "uvectr32.h"
 #include "cmemory.h"
 #include "putilimp.h"
diff --git a/src/third_party/icu/source/common/uvectr32.h b/src/third_party/icu/source/common/uvectr32.h
index d03eba6..0d81dfb 100644
--- a/src/third_party/icu/source/common/uvectr32.h
+++ b/src/third_party/icu/source/common/uvectr32.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
 *   Copyright (C) 1999-2011, International Business Machines
@@ -95,21 +97,21 @@
     // java.util.Vector API
     //------------------------------------------------------------
 
-    void addElement(int32_t elem, UErrorCode &status);
+    inline void addElement(int32_t elem, UErrorCode &status);
 
     void setElementAt(int32_t elem, int32_t index);
 
     void insertElementAt(int32_t elem, int32_t index, UErrorCode &status);
     
-    int32_t elementAti(int32_t index) const;
+    inline int32_t elementAti(int32_t index) const;
 
     UBool equals(const UVector32 &other) const;
 
-    int32_t lastElementi(void) const;
+    inline int32_t lastElementi(void) const;
 
     int32_t indexOf(int32_t elem, int32_t startIndex = 0) const;
 
-    UBool contains(int32_t elem) const;
+    inline UBool contains(int32_t elem) const;
 
     UBool containsAll(const UVector32& other) const;
 
@@ -121,9 +123,9 @@
 
     void removeAllElements();
 
-    int32_t size(void) const;
+    inline int32_t size(void) const;
 
-    UBool isEmpty(void) const;
+    inline UBool isEmpty(void) const;
 
     // Inline.  Use this one for speedy size check.
     inline UBool ensureCapacity(int32_t minimumCapacity, UErrorCode &status);
@@ -161,7 +163,7 @@
     /**
      * Returns a pointer to the internal array holding the vector.
      */
-    int32_t *getBuffer() const;
+    inline int32_t *getBuffer() const;
 
     /**
      * Set the maximum allowed buffer capacity for this vector/stack.
@@ -195,16 +197,16 @@
     //  In the original UVector, these were in a separate derived class, UStack.
     //  Here in UVector32, they are all together.
 public:
-    UBool empty(void) const;   // TODO:  redundant, same as empty().  Remove it?
+    inline UBool empty(void) const;   // TODO:  redundant, same as empty().  Remove it?
 
-    int32_t peeki(void) const;
+    inline int32_t peeki(void) const;
     
-    int32_t popi(void);
+    inline int32_t popi(void);
     
-    int32_t push(int32_t i, UErrorCode &status);
+    inline int32_t push(int32_t i, UErrorCode &status);
 
-    int32_t *reserveBlock(int32_t size, UErrorCode &status);
-    int32_t *popFrame(int32_t size);
+    inline int32_t *reserveBlock(int32_t size, UErrorCode &status);
+    inline int32_t *popFrame(int32_t size);
 };
 
 
@@ -212,7 +214,7 @@
 
 inline UBool UVector32::ensureCapacity(int32_t minimumCapacity, UErrorCode &status) {
     if ((minimumCapacity >= 0) && (capacity >= minimumCapacity)) {
-        return TRUE;
+        return true;
     } else {
         return expandCapacity(minimumCapacity, status);
     }
@@ -231,7 +233,7 @@
 }
 
 inline int32_t *UVector32::reserveBlock(int32_t size, UErrorCode &status) {
-    if (ensureCapacity(count+size, status) == FALSE) {
+    if (ensureCapacity(count+size, status) == false) {
         return NULL;
     }
     int32_t  *rp = elements+count;
diff --git a/src/third_party/icu/source/common/uvectr64.cpp b/src/third_party/icu/source/common/uvectr64.cpp
index c218091..bdc9098 100644
--- a/src/third_party/icu/source/common/uvectr64.cpp
+++ b/src/third_party/icu/source/common/uvectr64.cpp
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 * Copyright (C) 1999-2015, International Business Machines Corporation and
@@ -5,8 +7,10 @@
 ******************************************************************************
 */
 
+#if defined(STARBOARD)
 #include "starboard/client_porting/poem/assert_poem.h"
 #include "starboard/client_porting/poem/string_poem.h"
+#endif  // defined(STARBOARD)
 #include "uvectr64.h"
 #include "cmemory.h"
 #include "putilimp.h"
diff --git a/src/third_party/icu/source/common/uvectr64.h b/src/third_party/icu/source/common/uvectr64.h
index 0692821..15c9b3f 100644
--- a/src/third_party/icu/source/common/uvectr64.h
+++ b/src/third_party/icu/source/common/uvectr64.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
 *   Copyright (C) 1999-2014, International Business Machines
@@ -94,17 +96,17 @@
     // subset of java.util.Vector API
     //------------------------------------------------------------
 
-    void addElement(int64_t elem, UErrorCode &status);
+    inline void addElement(int64_t elem, UErrorCode &status);
 
     void setElementAt(int64_t elem, int32_t index);
 
     void insertElementAt(int64_t elem, int32_t index, UErrorCode &status);
     
-    int64_t elementAti(int32_t index) const;
+    inline int64_t elementAti(int32_t index) const;
 
     //UBool equals(const UVector64 &other) const;
 
-    int64_t lastElementi(void) const;
+    inline int64_t lastElementi(void) const;
 
     //int32_t indexOf(int64_t elem, int32_t startIndex = 0) const;
 
@@ -120,7 +122,7 @@
 
     void removeAllElements();
 
-    int32_t size(void) const;
+    inline int32_t size(void) const;
 
     inline UBool isEmpty(void) const { return count == 0; }
 
@@ -150,7 +152,7 @@
     /**
      * Returns a pointer to the internal array holding the vector.
      */
-    int64_t *getBuffer() const;
+    inline int64_t *getBuffer() const;
 
     /**
      * Set the maximum allowed buffer capacity for this vector/stack.
@@ -188,12 +190,12 @@
 
     //int64_t peeki(void) const;
     
-    int64_t popi(void);
+    inline int64_t popi(void);
     
-    int64_t push(int64_t i, UErrorCode &status);
+    inline int64_t push(int64_t i, UErrorCode &status);
 
-    int64_t *reserveBlock(int32_t size, UErrorCode &status);
-    int64_t *popFrame(int32_t size);
+    inline int64_t *reserveBlock(int32_t size, UErrorCode &status);
+    inline int64_t *popFrame(int32_t size);
 };
 
 
@@ -201,7 +203,7 @@
 
 inline UBool UVector64::ensureCapacity(int32_t minimumCapacity, UErrorCode &status) {
     if ((minimumCapacity >= 0) && (capacity >= minimumCapacity)) {
-        return TRUE;
+        return true;
     } else {
         return expandCapacity(minimumCapacity, status);
     }
@@ -220,7 +222,7 @@
 }
 
 inline int64_t *UVector64::reserveBlock(int32_t size, UErrorCode &status) {
-    if (ensureCapacity(count+size, status) == FALSE) {
+    if (ensureCapacity(count+size, status) == false) {
         return NULL;
     }
     int64_t  *rp = elements+count;
diff --git a/src/third_party/icu/source/common/wintz.c b/src/third_party/icu/source/common/wintz.c
deleted file mode 100644
index fa04588..0000000
--- a/src/third_party/icu/source/common/wintz.c
+++ /dev/null
@@ -1,438 +0,0 @@
-/*
-********************************************************************************
-*   Copyright (C) 2005-2015, International Business Machines
-*   Corporation and others.  All Rights Reserved.
-********************************************************************************
-*
-* File WINTZ.CPP
-*
-********************************************************************************
-*/
-
-#include "unicode/utypes.h"
-
-#if U_PLATFORM_HAS_WIN32_API
-
-#include "wintz.h"
-#include "cmemory.h"
-#include "cstring.h"
-
-#include "unicode/ures.h"
-#include "unicode/ustring.h"
-
-#   define WIN32_LEAN_AND_MEAN
-#   define VC_EXTRALEAN
-#   define NOUSER
-#   define NOSERVICE
-#   define NOIME
-#   define NOMCX
-#include <windows.h>
-
-#define MAX_LENGTH_ID 40
-
-/* The layout of the Tzi value in the registry */
-typedef struct
-{
-    int32_t bias;
-    int32_t standardBias;
-    int32_t daylightBias;
-    SYSTEMTIME standardDate;
-    SYSTEMTIME daylightDate;
-} TZI;
-
-/**
- * Various registry keys and key fragments.
- */
-static const char CURRENT_ZONE_REGKEY[] = "SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation\\";
-/* static const char STANDARD_NAME_REGKEY[] = "StandardName"; Currently unused constant */
-static const char STANDARD_TIME_REGKEY[] = " Standard Time";
-static const char TZI_REGKEY[] = "TZI";
-static const char STD_REGKEY[] = "Std";
-
-/**
- * HKLM subkeys used to probe for the flavor of Windows.  Note that we
- * specifically check for the "GMT" zone subkey; this is present on
- * NT, but on XP has become "GMT Standard Time".  We need to
- * discriminate between these cases.
- */
-static const char* const WIN_TYPE_PROBE_REGKEY[] = {
-    /* WIN_9X_ME_TYPE */
-    "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Time Zones",
-
-    /* WIN_NT_TYPE */
-    "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones\\GMT"
-
-    /* otherwise: WIN_2K_XP_TYPE */
-};
-
-/**
- * The time zone root subkeys (under HKLM) for different flavors of
- * Windows.
- */
-static const char* const TZ_REGKEY[] = {
-    /* WIN_9X_ME_TYPE */
-    "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Time Zones\\",
-
-    /* WIN_NT_TYPE | WIN_2K_XP_TYPE */
-    "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones\\"
-};
-
-/**
- * Flavor of Windows, from our perspective.  Not a real OS version,
- * but rather the flavor of the layout of the time zone information in
- * the registry.
- */
-enum {
-    WIN_9X_ME_TYPE = 1,
-    WIN_NT_TYPE = 2,
-    WIN_2K_XP_TYPE = 3
-};
-
-static int32_t gWinType = 0;
-
-static int32_t detectWindowsType()
-{
-    int32_t winType;
-    LONG result;
-    HKEY hkey;
-
-    /* Detect the version of windows by trying to open a sequence of
-        probe keys.  We don't use the OS version API because what we
-        really want to know is how the registry is laid out.
-        Specifically, is it 9x/Me or not, and is it "GMT" or "GMT
-        Standard Time". */
-    for (winType = 0; winType < 2; winType++) {
-        result = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
-                              WIN_TYPE_PROBE_REGKEY[winType],
-                              0,
-                              KEY_QUERY_VALUE,
-                              &hkey);
-        RegCloseKey(hkey);
-
-        if (result == ERROR_SUCCESS) {
-            break;
-        }
-    }
-
-    return winType+1; /* +1 to bring it inline with the enum */
-}
-
-static LONG openTZRegKey(HKEY *hkey, const char *winid)
-{
-    char subKeyName[110]; /* TODO: why 96?? */
-    char *name;
-    LONG result;
-
-    /* This isn't thread safe, but it's good enough because the result should be constant per system. */
-    if (gWinType <= 0) {
-        gWinType = detectWindowsType();
-    }
-
-    uprv_strcpy(subKeyName, TZ_REGKEY[(gWinType != WIN_9X_ME_TYPE)]);
-    name = &subKeyName[strlen(subKeyName)];
-    uprv_strcat(subKeyName, winid);
-
-    if (gWinType == WIN_9X_ME_TYPE) {
-        /* Remove " Standard Time" */
-        char *pStd = uprv_strstr(subKeyName, STANDARD_TIME_REGKEY);
-        if (pStd) {
-            *pStd = 0;
-        }
-    }
-
-    result = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
-                            subKeyName,
-                            0,
-                            KEY_QUERY_VALUE,
-                            hkey);
-    return result;
-}
-
-static LONG getTZI(const char *winid, TZI *tzi)
-{
-    DWORD cbData = sizeof(TZI);
-    LONG result;
-    HKEY hkey;
-
-    result = openTZRegKey(&hkey, winid);
-
-    if (result == ERROR_SUCCESS) {
-        result = RegQueryValueExA(hkey,
-                                    TZI_REGKEY,
-                                    NULL,
-                                    NULL,
-                                    (LPBYTE)tzi,
-                                    &cbData);
-
-    }
-
-    RegCloseKey(hkey);
-
-    return result;
-}
-
-static LONG getSTDName(const char *winid, char *regStdName, int32_t length) {
-    DWORD cbData = length;
-    LONG result;
-    HKEY hkey;
-
-    result = openTZRegKey(&hkey, winid);
-
-    if (result == ERROR_SUCCESS) {
-        result = RegQueryValueExA(hkey,
-                                    STD_REGKEY,
-                                    NULL,
-                                    NULL,
-                                    (LPBYTE)regStdName,
-                                    &cbData);
-
-    }
-
-    RegCloseKey(hkey);
-
-    return result;
-}
-
-static LONG getTZKeyName(char* tzKeyName, int32_t length) {
-    HKEY hkey;
-    LONG result = FALSE;
-    DWORD cbData = length;
-
-    if(ERROR_SUCCESS == RegOpenKeyExA(
-        HKEY_LOCAL_MACHINE,
-        CURRENT_ZONE_REGKEY,
-        0, 
-        KEY_QUERY_VALUE,
-        &hkey))
-    {
-         result = RegQueryValueExA(
-             hkey,
-             "TimeZoneKeyName",
-             NULL,
-             NULL,
-             (LPBYTE)tzKeyName,
-             &cbData);
-    }
-
-    return result;
-}
-
-/*
-  This code attempts to detect the Windows time zone, as set in the
-  Windows Date and Time control panel.  It attempts to work on
-  multiple flavors of Windows (9x, Me, NT, 2000, XP) and on localized
-  installs.  It works by directly interrogating the registry and
-  comparing the data there with the data returned by the
-  GetTimeZoneInformation API, along with some other strategies.  The
-  registry contains time zone data under one of two keys (depending on
-  the flavor of Windows):
-
-    HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Time Zones\
-    HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\
-
-  Under this key are several subkeys, one for each time zone.  These
-  subkeys are named "Pacific" on Win9x/Me and "Pacific Standard Time"
-  on WinNT/2k/XP.  There are some other wrinkles; see the code for
-  details.  The subkey name is NOT LOCALIZED, allowing us to support
-  localized installs.
-
-  Under the subkey are data values.  We care about:
-
-    Std   Standard time display name, localized
-    TZI   Binary block of data
-
-  The TZI data is of particular interest.  It contains the offset, two
-  more offsets for standard and daylight time, and the start and end
-  rules.  This is the same data returned by the GetTimeZoneInformation
-  API.  The API may modify the data on the way out, so we have to be
-  careful, but essentially we do a binary comparison against the TZI
-  blocks of various registry keys.  When we find a match, we know what
-  time zone Windows is set to.  Since the registry key is not
-  localized, we can then translate the key through a simple table
-  lookup into the corresponding ICU time zone.
-
-  This strategy doesn't always work because there are zones which
-  share an offset and rules, so more than one TZI block will match.
-  For example, both Tokyo and Seoul are at GMT+9 with no DST rules;
-  their TZI blocks are identical.  For these cases, we fall back to a
-  name lookup.  We attempt to match the display name as stored in the
-  registry for the current zone to the display name stored in the
-  registry for various Windows zones.  By comparing the registry data
-  directly we avoid conversion complications.
-
-  Author: Alan Liu
-  Since: ICU 2.6
-  Based on original code by Carl Brown <cbrown@xnetinc.com>
-*/
-
-/**
- * Main Windows time zone detection function.  Returns the Windows
- * time zone, translated to an ICU time zone, or NULL upon failure.
- */
-U_CFUNC const char* U_EXPORT2
-uprv_detectWindowsTimeZone() {
-    UErrorCode status = U_ZERO_ERROR;
-    UResourceBundle* bundle = NULL;
-    char* icuid = NULL;
-    char apiStdName[MAX_LENGTH_ID];
-    char regStdName[MAX_LENGTH_ID];
-    char tmpid[MAX_LENGTH_ID];
-    int32_t len;
-    int id;
-    int errorCode;
-    UChar ISOcodeW[3]; /* 2 letter iso code in UTF-16*/
-    char  ISOcodeA[3]; /* 2 letter iso code in ansi */
-
-    LONG result;
-    TZI tziKey;
-    TZI tziReg;
-    TIME_ZONE_INFORMATION apiTZI;
-
-    BOOL isVistaOrHigher;
-    BOOL tryPreVistaFallback;
-    OSVERSIONINFO osVerInfo;
-
-    /* Obtain TIME_ZONE_INFORMATION from the API, and then convert it
-       to TZI.  We could also interrogate the registry directly; we do
-       this below if needed. */
-    uprv_memset(&apiTZI, 0, sizeof(apiTZI));
-    uprv_memset(&tziKey, 0, sizeof(tziKey));
-    uprv_memset(&tziReg, 0, sizeof(tziReg));
-    GetTimeZoneInformation(&apiTZI);
-    tziKey.bias = apiTZI.Bias;
-    uprv_memcpy((char *)&tziKey.standardDate, (char*)&apiTZI.StandardDate,
-           sizeof(apiTZI.StandardDate));
-    uprv_memcpy((char *)&tziKey.daylightDate, (char*)&apiTZI.DaylightDate,
-           sizeof(apiTZI.DaylightDate));
-
-    /* Convert the wchar_t* standard name to char* */
-    uprv_memset(apiStdName, 0, sizeof(apiStdName));
-    wcstombs(apiStdName, apiTZI.StandardName, MAX_LENGTH_ID);
-
-    tmpid[0] = 0;
-
-    id = GetUserGeoID(GEOCLASS_NATION);
-    errorCode = GetGeoInfoW(id,GEO_ISO2,ISOcodeW,3,0);
-    u_strToUTF8(ISOcodeA, 3, NULL, ISOcodeW, 3, &status);
-
-    bundle = ures_openDirect(NULL, "windowsZones", &status);
-    ures_getByKey(bundle, "mapTimezones", bundle, &status);
-
-    /*
-        Windows Vista+ provides us with a "TimeZoneKeyName" that is not localized
-        and can be used to directly map a name in our bundle. Try to use that first
-        if we're on Vista or higher
-    */
-    uprv_memset(&osVerInfo, 0, sizeof(osVerInfo));
-    osVerInfo.dwOSVersionInfoSize = sizeof(osVerInfo);
-    GetVersionEx(&osVerInfo);
-    isVistaOrHigher = osVerInfo.dwMajorVersion >= 6;	/* actually includes Windows Server 2008 as well, but don't worry about it */
-    tryPreVistaFallback = TRUE;
-    if(isVistaOrHigher) {
-        result = getTZKeyName(regStdName, sizeof(regStdName));
-        if(ERROR_SUCCESS == result) {
-            UResourceBundle* winTZ = ures_getByKey(bundle, regStdName, NULL, &status);
-            if(U_SUCCESS(status)) {
-                const UChar* icuTZ = NULL;
-                if (errorCode != 0) {
-                    icuTZ = ures_getStringByKey(winTZ, ISOcodeA, &len, &status);
-                }
-                if (errorCode==0 || icuTZ==NULL) {
-                    /* fallback to default "001" and reset status */
-                    status = U_ZERO_ERROR;
-                    icuTZ = ures_getStringByKey(winTZ, "001", &len, &status);
-                }
-
-                if(U_SUCCESS(status)) {
-                    int index=0;
-                    while (! (*icuTZ == '\0' || *icuTZ ==' ')) {
-                        tmpid[index++]=(char)(*icuTZ++);  /* safe to assume 'char' is ASCII compatible on windows */
-                    }
-                    tmpid[index]='\0';
-                    tryPreVistaFallback = FALSE;
-                }
-            }
-        }
-    }
-
-    if(tryPreVistaFallback) {
-
-        /* Note: We get the winid not from static tables but from resource bundle. */
-        while (U_SUCCESS(status) && ures_hasNext(bundle)) {
-            UBool idFound = FALSE;
-            const char* winid;
-            UResourceBundle* winTZ = ures_getNextResource(bundle, NULL, &status);
-            if (U_FAILURE(status)) {
-                break;
-            }
-            winid = ures_getKey(winTZ);
-            result = getTZI(winid, &tziReg);
-
-            if (result == ERROR_SUCCESS) {
-                /* Windows alters the DaylightBias in some situations.
-                   Using the bias and the rules suffices, so overwrite
-                   these unreliable fields. */
-                tziKey.standardBias = tziReg.standardBias;
-                tziKey.daylightBias = tziReg.daylightBias;
-
-                if (uprv_memcmp((char *)&tziKey, (char*)&tziReg, sizeof(tziKey)) == 0) {
-                    const UChar* icuTZ = NULL;
-                    if (errorCode != 0) {
-                        icuTZ = ures_getStringByKey(winTZ, ISOcodeA, &len, &status);
-                    }
-                    if (errorCode==0 || icuTZ==NULL) {
-                        /* fallback to default "001" and reset status */
-                        status = U_ZERO_ERROR;
-                        icuTZ = ures_getStringByKey(winTZ, "001", &len, &status);
-                    }
-
-                    if (U_SUCCESS(status)) {
-                        /* Get the standard name from the registry key to compare with
-                           the one from Windows API call. */
-                        uprv_memset(regStdName, 0, sizeof(regStdName));
-                        result = getSTDName(winid, regStdName, sizeof(regStdName));
-                        if (result == ERROR_SUCCESS) {
-                            if (uprv_strcmp(apiStdName, regStdName) == 0) {
-                                idFound = TRUE;
-                            }
-                        }
-
-                        /* tmpid buffer holds the ICU timezone ID corresponding to the timezone ID from Windows.
-                         * If none is found, tmpid buffer will contain a fallback ID (i.e. the time zone ID matching
-                         * the current time zone information)
-                         */
-                        if (idFound || tmpid[0] == 0) {
-                            /* if icuTZ has more than one city, take only the first (i.e. terminate icuTZ at first space) */
-                            int index=0;
-                            while (! (*icuTZ == '\0' || *icuTZ ==' ')) {
-                                tmpid[index++]=(char)(*icuTZ++);  /* safe to assume 'char' is ASCII compatible on windows */
-                            }
-                            tmpid[index]='\0';
-                        }
-                    }
-                }
-            }
-            ures_close(winTZ);
-            if (idFound) {
-                break;
-            }
-        }
-    }
-
-    /*
-     * Copy the timezone ID to icuid to be returned.
-     */
-    if (tmpid[0] != 0) {
-        len = uprv_strlen(tmpid);
-        icuid = (char*)uprv_calloc(len + 1, sizeof(char));
-        if (icuid != NULL) {
-            uprv_strcpy(icuid, tmpid);
-        }
-    }
-
-    ures_close(bundle);
-    
-    return icuid;
-}
-
-#endif /* U_PLATFORM_HAS_WIN32_API */
diff --git a/src/third_party/icu/source/common/wintz.cpp b/src/third_party/icu/source/common/wintz.cpp
new file mode 100644
index 0000000..ebf3165
--- /dev/null
+++ b/src/third_party/icu/source/common/wintz.cpp
@@ -0,0 +1,331 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+/*
+********************************************************************************
+*   Copyright (C) 2005-2015, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+********************************************************************************
+*
+* File WINTZ.CPP
+*
+********************************************************************************
+*/
+
+#include "unicode/utypes.h"
+
+#if U_PLATFORM_USES_ONLY_WIN32_API
+
+#include "wintz.h"
+#include "charstr.h"
+#include "cmemory.h"
+#include "cstring.h"
+
+#include "unicode/ures.h"
+#include "unicode/unistr.h"
+#include "uresimp.h"
+
+#ifndef WIN32_LEAN_AND_MEAN
+#   define WIN32_LEAN_AND_MEAN
+#endif
+#   define VC_EXTRALEAN
+#   define NOUSER
+#   define NOSERVICE
+#   define NOIME
+#   define NOMCX
+#include <windows.h>
+
+U_NAMESPACE_BEGIN
+
+// Note these constants and the struct are only used when dealing with the fallback path for RDP sesssions.
+
+// This is the location of the time zones in the registry on Vista+ systems.
+// See: https://docs.microsoft.com/windows/win32/api/timezoneapi/ns-timezoneapi-dynamic_time_zone_information
+#define WINDOWS_TIMEZONES_REG_KEY_PATH L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones"
+
+// Max length for a registry key is 255. +1 for null.
+// See: https://docs.microsoft.com/windows/win32/sysinfo/registry-element-size-limits
+#define WINDOWS_MAX_REG_KEY_LENGTH 256
+
+#if U_PLATFORM_HAS_WINUWP_API == 0
+
+// This is the layout of the TZI binary value in the registry.
+// See: https://docs.microsoft.com/windows/win32/api/timezoneapi/ns-timezoneapi-time_zone_information
+typedef struct _REG_TZI_FORMAT {
+    LONG Bias;
+    LONG StandardBias;
+    LONG DaylightBias;
+    SYSTEMTIME StandardDate;
+    SYSTEMTIME DaylightDate;
+} REG_TZI_FORMAT;
+
+#endif // U_PLATFORM_HAS_WINUWP_API
+
+/**
+* This is main Windows time zone detection function.
+* 
+* It returns the Windows time zone converted to an ICU time zone as a heap-allocated buffer, or nullptr upon failure.
+*
+* We use the Win32 API GetDynamicTimeZoneInformation (which is available since Vista) to get the current time zone info,
+* as this API returns a non-localized time zone name which can be then mapped to an ICU time zone.
+* 
+* However, in some RDP/terminal services situations, this struct isn't always fully complete, and the TimeZoneKeyName
+* field of the struct might be NULL. This can happen with some 3rd party RDP clients, and also when using older versions
+* of the RDP protocol, which don't send the newer TimeZoneKeyNamei information and only send the StandardName and DaylightName.
+* 
+* Since these 3rd party clients and older RDP clients only send the pre-Vista time zone information to the server, this means that we 
+* need to fallback on using the pre-Vista methods to determine the time zone. This unfortunately requires examining the registry directly
+* in order to try and determine the current time zone.
+* 
+* Note that this can however still fail in some cases though if the client and server are using different languages, as the StandardName
+* that is sent by client is localized in the client's language. However, we must compare this to the names that are on the server, which
+* are localized in registry using the server's language. Despite that, this is the best we can do.
+* 
+* Note: This fallback method won't work for the UWP version though, as we can't use the registry APIs in UWP.
+* 
+* Once we have the current Windows time zone, then we can then map it to an ICU time zone ID (~ Olsen ID).
+*/
+U_CAPI const char* U_EXPORT2
+uprv_detectWindowsTimeZone()
+{
+    // We first try to obtain the time zone directly by using the TimeZoneKeyName field of the DYNAMIC_TIME_ZONE_INFORMATION struct.
+    DYNAMIC_TIME_ZONE_INFORMATION dynamicTZI;
+    uprv_memset(&dynamicTZI, 0, sizeof(dynamicTZI));
+    SYSTEMTIME systemTimeAllZero;
+    uprv_memset(&systemTimeAllZero, 0, sizeof(systemTimeAllZero));
+
+    if (GetDynamicTimeZoneInformation(&dynamicTZI) == TIME_ZONE_ID_INVALID) {
+        return nullptr;
+    }
+
+    // If the DST setting has been turned off in the Control Panel, then return "Etc/GMT<offset>".
+    //
+    // Note: This logic is based on how the Control Panel itself determines if DST is 'off' on Windows.
+    // The code is somewhat convoluted; in a sort of pseudo-code it looks like this:
+    // 
+    //   IF (GetDynamicTimeZoneInformation != TIME_ZONE_ID_INVALID) && (DynamicDaylightTimeDisabled != 0) &&
+    //      (StandardDate == DaylightDate) &&
+    //      (
+    //       (TimeZoneKeyName != Empty && StandardDate == 0) ||
+    //       (TimeZoneKeyName == Empty && StandardDate != 0)
+    //      )
+    //   THEN
+    //     DST setting is "Disabled".
+    //
+    if (dynamicTZI.DynamicDaylightTimeDisabled != 0 &&
+        uprv_memcmp(&dynamicTZI.StandardDate, &dynamicTZI.DaylightDate, sizeof(dynamicTZI.StandardDate)) == 0 &&
+        ((dynamicTZI.TimeZoneKeyName[0] != L'\0' && uprv_memcmp(&dynamicTZI.StandardDate, &systemTimeAllZero, sizeof(systemTimeAllZero)) == 0) ||
+         (dynamicTZI.TimeZoneKeyName[0] == L'\0' && uprv_memcmp(&dynamicTZI.StandardDate, &systemTimeAllZero, sizeof(systemTimeAllZero)) != 0)))
+    {
+        LONG utcOffsetMins = dynamicTZI.Bias;
+        if (utcOffsetMins == 0) {
+            return uprv_strdup("Etc/UTC");
+        }
+
+        // No way to support when DST is turned off and the offset in minutes is not a multiple of 60.
+        if (utcOffsetMins % 60 == 0) {
+            char gmtOffsetTz[11] = {}; // "Etc/GMT+dd" is 11-char long with a terminal null.
+            // Important note on the sign convention for zones:
+            //
+            // From https://en.wikipedia.org/wiki/Tz_database#Area
+            //   "In order to conform with the POSIX style, those zone names beginning with "Etc/GMT" have their sign reversed
+            //   from the standard ISO 8601 convention. In the "Etc" area, zones west of GMT have a positive sign and those
+            //   east have a negative sign in their name (e.g "Etc/GMT-14" is 14 hours ahead of GMT)."
+            //
+            // Regarding the POSIX style, from https://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html
+            //   "The offset specifies the time value you must add to the local time to get a Coordinated Universal Time value."
+            //
+            // However, the Bias value in DYNAMIC_TIME_ZONE_INFORMATION *already* follows the POSIX convention.
+            // 
+            // From https://docs.microsoft.com/en-us/windows/win32/api/timezoneapi/ns-timezoneapi-dynamic_time_zone_information
+            //   "The bias is the difference, in minutes, between Coordinated Universal Time (UTC) and
+            //   local time. All translations between UTC and local time are based on the following formula:
+            //      UTC = local time + bias"
+            //
+            // For example, a time zone that is 3 hours ahead of UTC (UTC+03:00) would have a Bias value of -180, and the
+            // corresponding time zone ID would be "Etc/GMT-3". (So there is no need to negate utcOffsetMins below.)
+            int ret = snprintf(gmtOffsetTz, UPRV_LENGTHOF(gmtOffsetTz), "Etc/GMT%+ld", utcOffsetMins / 60);
+            if (ret > 0 && ret < UPRV_LENGTHOF(gmtOffsetTz)) {
+                return uprv_strdup(gmtOffsetTz);
+            }
+        }
+    }
+
+    // If DST is NOT disabled, but the TimeZoneKeyName field of the struct is NULL, then we may be dealing with a
+    // RDP/terminal services session where the 'Time Zone Redirection' feature is enabled. However, either the RDP
+    // client sent the server incomplete info (some 3rd party RDP clients only send the StandardName and  DaylightName,
+    // but do not send the important TimeZoneKeyName), or if the RDP server has not appropriately populated the struct correctly.
+    //
+    // In this case we unfortunately have no choice but to fallback to using the pre-Vista method of determining the
+    // time zone, which requires examining the registry directly.
+    //
+    // Note that this can however still fail though if the client and server are using different languages, as the StandardName
+    // that is sent by client is *localized* in the client's language. However, we must compare this to the names that are
+    // on the server, which are *localized* in registry using the server's language.
+    //
+    // One other note is that this fallback method doesn't work for the UWP version, as we can't use the registry APIs.
+
+    // windowsTimeZoneName will point at timezoneSubKeyName if we had to fallback to using the registry, and we found a match.
+    WCHAR timezoneSubKeyName[WINDOWS_MAX_REG_KEY_LENGTH];
+    WCHAR *windowsTimeZoneName = dynamicTZI.TimeZoneKeyName;
+
+    if (dynamicTZI.TimeZoneKeyName[0] == 0) {
+
+// We can't use the registry APIs in the UWP version.
+#if U_PLATFORM_HAS_WINUWP_API == 1
+        (void)timezoneSubKeyName; // suppress unused variable warnings.
+        return nullptr;
+#else
+        // Open the path to the time zones in the Windows registry.
+        LONG ret;
+        HKEY hKeyAllTimeZones = nullptr;
+        ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, WINDOWS_TIMEZONES_REG_KEY_PATH, 0, KEY_READ,
+                            reinterpret_cast<PHKEY>(&hKeyAllTimeZones));
+        
+        if (ret != ERROR_SUCCESS) {
+            // If we can't open the key, then we can't do much, so fail.
+            return nullptr;
+        }
+
+        // Read the number of subkeys under the time zone registry path.
+        DWORD numTimeZoneSubKeys;
+        ret = RegQueryInfoKeyW(hKeyAllTimeZones, nullptr, nullptr, nullptr, &numTimeZoneSubKeys,
+                               nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr);
+        
+        if (ret != ERROR_SUCCESS) {
+            RegCloseKey(hKeyAllTimeZones);
+            return nullptr;
+        }
+
+        // Examine each of the subkeys to try and find a match for the localized standard name ("Std").
+        //
+        // Note: The name of the time zone subkey itself is not localized, but the "Std" name is localized. This means
+        // that we could fail to find a match if the RDP client and RDP server are using different languages, but unfortunately
+        // there isn't much we can do about it.
+        HKEY hKeyTimeZoneSubKey = nullptr;
+        ULONG registryValueType;
+        WCHAR registryStandardName[WINDOWS_MAX_REG_KEY_LENGTH];
+
+        for (DWORD i = 0; i < numTimeZoneSubKeys; i++) {
+            // Note: RegEnumKeyExW wants the size of the buffer in characters.
+            DWORD size = UPRV_LENGTHOF(timezoneSubKeyName);
+            ret = RegEnumKeyExW(hKeyAllTimeZones, i, timezoneSubKeyName, &size, nullptr, nullptr, nullptr, nullptr);
+
+            if (ret != ERROR_SUCCESS) {
+                RegCloseKey(hKeyAllTimeZones);
+                return nullptr;
+            }
+            
+            ret = RegOpenKeyExW(hKeyAllTimeZones, timezoneSubKeyName, 0, KEY_READ,
+                                reinterpret_cast<PHKEY>(&hKeyTimeZoneSubKey));
+            
+            if (ret != ERROR_SUCCESS) {
+                RegCloseKey(hKeyAllTimeZones);
+                return nullptr;
+            }
+
+            // Note: RegQueryValueExW wants the size of the buffer in bytes.
+            size = sizeof(registryStandardName);
+            ret = RegQueryValueExW(hKeyTimeZoneSubKey, L"Std", nullptr, &registryValueType,
+                                   reinterpret_cast<LPBYTE>(registryStandardName), &size);
+            
+            if (ret != ERROR_SUCCESS || registryValueType != REG_SZ) {
+                RegCloseKey(hKeyTimeZoneSubKey);
+                RegCloseKey(hKeyAllTimeZones);
+                return nullptr;
+            }
+
+            // Note: wcscmp does an ordinal (byte) comparison.
+            if (wcscmp(reinterpret_cast<WCHAR *>(registryStandardName), dynamicTZI.StandardName) == 0) {
+                // Since we are comparing the *localized* time zone name, it's possible that some languages might use
+                // the same string for more than one time zone. Thus we need to examine the TZI data in the registry to
+                // compare the GMT offset (the bias), and the DST transition dates, to ensure it's the same time zone
+                // as the currently reported one.
+                REG_TZI_FORMAT registryTziValue;
+                uprv_memset(&registryTziValue, 0, sizeof(registryTziValue));
+
+                // Note: RegQueryValueExW wants the size of the buffer in bytes.
+                DWORD timezoneTziValueSize = sizeof(registryTziValue);
+                ret = RegQueryValueExW(hKeyTimeZoneSubKey, L"TZI", nullptr, &registryValueType,
+                                     reinterpret_cast<LPBYTE>(&registryTziValue), &timezoneTziValueSize);
+
+                if (ret == ERROR_SUCCESS) {
+                    if ((dynamicTZI.Bias == registryTziValue.Bias) &&
+                        (memcmp((const void *)&dynamicTZI.StandardDate, (const void *)&registryTziValue.StandardDate, sizeof(SYSTEMTIME)) == 0) &&
+                        (memcmp((const void *)&dynamicTZI.DaylightDate, (const void *)&registryTziValue.DaylightDate, sizeof(SYSTEMTIME)) == 0))
+                    {
+                        // We found a matching time zone.
+                        windowsTimeZoneName = timezoneSubKeyName;
+                        break;
+                    }
+                }
+            }
+            RegCloseKey(hKeyTimeZoneSubKey);
+            hKeyTimeZoneSubKey = nullptr;
+        }
+
+        if (hKeyTimeZoneSubKey != nullptr) {
+            RegCloseKey(hKeyTimeZoneSubKey);
+        }
+        if (hKeyAllTimeZones != nullptr) {
+            RegCloseKey(hKeyAllTimeZones);
+        }
+#endif // U_PLATFORM_HAS_WINUWP_API
+    }
+
+    CharString winTZ;
+    UErrorCode status = U_ZERO_ERROR;
+    winTZ.appendInvariantChars(UnicodeString(TRUE, windowsTimeZoneName, -1), status);
+
+    // Map Windows Timezone name (non-localized) to ICU timezone ID (~ Olson timezone id).
+    StackUResourceBundle winTZBundle;
+    ures_openDirectFillIn(winTZBundle.getAlias(), nullptr, "windowsZones", &status);
+    ures_getByKey(winTZBundle.getAlias(), "mapTimezones", winTZBundle.getAlias(), &status);
+    ures_getByKey(winTZBundle.getAlias(), winTZ.data(), winTZBundle.getAlias(), &status);
+
+    if (U_FAILURE(status)) {
+        return nullptr;
+    }
+    
+    // Note: Since the ISO 3166 country/region codes are all invariant ASCII chars, we can
+    // directly downcast from wchar_t to do the conversion.
+    // We could call the A version of the GetGeoInfo API, but that would be slightly slower than calling the W API,
+    // as the A version of the API will end up calling MultiByteToWideChar anyways internally.
+    wchar_t regionCodeW[3] = {};
+    char regionCode[3] = {}; // 2 letter ISO 3166 country/region code made entirely of invariant chars.
+    int geoId = GetUserGeoID(GEOCLASS_NATION);
+    int regionCodeLen = GetGeoInfoW(geoId, GEO_ISO2, regionCodeW, UPRV_LENGTHOF(regionCodeW), 0);
+
+    const UChar *icuTZ16 = nullptr;
+    int32_t tzListLen = 0;
+
+    if (regionCodeLen != 0) {
+        for (int i = 0; i < UPRV_LENGTHOF(regionCodeW); i++) {
+            regionCode[i] = static_cast<char>(regionCodeW[i]);
+        }
+        icuTZ16 = ures_getStringByKey(winTZBundle.getAlias(), regionCode, &tzListLen, &status);
+    }
+    if (regionCodeLen == 0 || U_FAILURE(status)) {
+        // fallback to default "001" (world)
+        status = U_ZERO_ERROR;
+        icuTZ16 = ures_getStringByKey(winTZBundle.getAlias(), "001", &tzListLen, &status);
+    }
+
+    // Note: We want the first entry in the string returned by ures_getStringByKey.
+    // However this string can be a space delimited list of timezones:
+    //  Ex: "America/New_York America/Detroit America/Indiana/Petersburg ..."
+    // We need to stop at the first space, so we pass tzLen (instead of tzListLen) to appendInvariantChars below.
+    int32_t tzLen = 0;
+    if (tzListLen > 0) {
+        while (!(icuTZ16[tzLen] == u'\0' || icuTZ16[tzLen] == u' ')) {
+            tzLen++;
+        }
+    }
+
+    // Note: cloneData returns nullptr if the status is a failure, so this
+    // will return nullptr if the above look-up fails.
+    CharString icuTZStr;
+    return icuTZStr.appendInvariantChars(icuTZ16, tzLen, status).cloneData(status);
+}
+
+U_NAMESPACE_END
+#endif /* U_PLATFORM_USES_ONLY_WIN32_API  */
diff --git a/src/third_party/icu/source/common/wintz.h b/src/third_party/icu/source/common/wintz.h
index 081b38d..ce9c1e9 100644
--- a/src/third_party/icu/source/common/wintz.h
+++ b/src/third_party/icu/source/common/wintz.h
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ********************************************************************************
 *   Copyright (C) 2005-2011, International Business Machines
@@ -14,7 +16,7 @@
 
 #include "unicode/utypes.h"
 
-#if U_PLATFORM_HAS_WIN32_API
+#if U_PLATFORM_USES_ONLY_WIN32_API
 
 /**
  * \file 
@@ -26,9 +28,9 @@
 typedef struct _TIME_ZONE_INFORMATION TIME_ZONE_INFORMATION;
 U_CDECL_END
 
-U_CFUNC const char* U_EXPORT2
+U_CAPI const char* U_EXPORT2
 uprv_detectWindowsTimeZone();
 
-#endif /* U_PLATFORM_HAS_WIN32_API */
+#endif /* U_PLATFORM_USES_ONLY_WIN32_API  */
 
 #endif /* __WINTZ */