Bug 1408855 - Update Harfbuzz to version 1.6.0. r=jfkthame
authorRyan VanderMeulen <ryanvm@gmail.com>
Tue, 17 Oct 2017 11:17:04 -0400
changeset 386698 f1e264617d1e688667a137aad5451f4d2cb27a14
parent 386697 b81cc01a1ec22557a14f845aa53690328626e850
child 386699 84b2d5c67f73b48b760ef3f12aed9e8796441635
push id32699
push userarchaeopteryx@coole-files.de
push dateTue, 17 Oct 2017 21:52:51 +0000
treeherdermozilla-central@f78d59473334 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjfkthame
bugs1408855
milestone58.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1408855 - Update Harfbuzz to version 1.6.0. r=jfkthame
gfx/harfbuzz/Makefile.am
gfx/harfbuzz/NEWS
gfx/harfbuzz/README-mozilla
gfx/harfbuzz/configure.ac
gfx/harfbuzz/src/Makefile.am
gfx/harfbuzz/src/check-externs.sh
gfx/harfbuzz/src/gen-use-table.py
gfx/harfbuzz/src/harfbuzz-icu.pc
gfx/harfbuzz/src/harfbuzz.pc
gfx/harfbuzz/src/harfbuzz.pc.in
gfx/harfbuzz/src/hb-blob.cc
gfx/harfbuzz/src/hb-buffer.h
gfx/harfbuzz/src/hb-common.cc
gfx/harfbuzz/src/hb-common.h
gfx/harfbuzz/src/hb-coretext.cc
gfx/harfbuzz/src/hb-coretext.h
gfx/harfbuzz/src/hb-face-private.hh
gfx/harfbuzz/src/hb-face.cc
gfx/harfbuzz/src/hb-face.h
gfx/harfbuzz/src/hb-font-private.hh
gfx/harfbuzz/src/hb-font.cc
gfx/harfbuzz/src/hb-font.h
gfx/harfbuzz/src/hb-ft.cc
gfx/harfbuzz/src/hb-ft.h
gfx/harfbuzz/src/hb-glib.cc
gfx/harfbuzz/src/hb-graphite2.cc
gfx/harfbuzz/src/hb-open-file-private.hh
gfx/harfbuzz/src/hb-ot-font.cc
gfx/harfbuzz/src/hb-ot-layout-gpos-table.hh
gfx/harfbuzz/src/hb-ot-layout-gsubgpos-private.hh
gfx/harfbuzz/src/hb-ot-layout-private.hh
gfx/harfbuzz/src/hb-ot-shape-complex-arabic-table.hh
gfx/harfbuzz/src/hb-ot-shape-complex-arabic.cc
gfx/harfbuzz/src/hb-ot-shape-complex-default.cc
gfx/harfbuzz/src/hb-ot-shape-complex-hangul.cc
gfx/harfbuzz/src/hb-ot-shape-complex-hebrew.cc
gfx/harfbuzz/src/hb-ot-shape-complex-indic-machine.hh
gfx/harfbuzz/src/hb-ot-shape-complex-indic-machine.rl
gfx/harfbuzz/src/hb-ot-shape-complex-indic-private.hh
gfx/harfbuzz/src/hb-ot-shape-complex-indic-table.cc
gfx/harfbuzz/src/hb-ot-shape-complex-indic.cc
gfx/harfbuzz/src/hb-ot-shape-complex-myanmar-machine.hh
gfx/harfbuzz/src/hb-ot-shape-complex-myanmar-machine.rl
gfx/harfbuzz/src/hb-ot-shape-complex-myanmar.cc
gfx/harfbuzz/src/hb-ot-shape-complex-private.hh
gfx/harfbuzz/src/hb-ot-shape-complex-thai.cc
gfx/harfbuzz/src/hb-ot-shape-complex-tibetan.cc
gfx/harfbuzz/src/hb-ot-shape-complex-use-machine.hh
gfx/harfbuzz/src/hb-ot-shape-complex-use-machine.rl
gfx/harfbuzz/src/hb-ot-shape-complex-use-private.hh
gfx/harfbuzz/src/hb-ot-shape-complex-use-table.cc
gfx/harfbuzz/src/hb-ot-shape-complex-use.cc
gfx/harfbuzz/src/hb-ot-shape-normalize.cc
gfx/harfbuzz/src/hb-ot-shape.cc
gfx/harfbuzz/src/hb-ot-tag.cc
gfx/harfbuzz/src/hb-shaper-private.hh
gfx/harfbuzz/src/hb-ucdn.cc
gfx/harfbuzz/src/hb-unicode-private.hh
gfx/harfbuzz/src/hb-version.h
--- a/gfx/harfbuzz/Makefile.am
+++ b/gfx/harfbuzz/Makefile.am
@@ -1,21 +1,22 @@
 # Process this file with automake to produce Makefile.in
 
 NULL =
 
 ACLOCAL_AMFLAGS = -I m4
 
-SUBDIRS = src util test docs win32
+SUBDIRS = src util test docs
 
 EXTRA_DIST = \
 	autogen.sh \
 	harfbuzz.doap \
 	README.python \
 	BUILD.md \
+	RELEASING.md \
 	CMakeLists.txt \
 	$(NULL)
 
 MAINTAINERCLEANFILES = \
 	$(GITIGNORE_MAINTAINERCLEANFILES_TOPLEVEL) \
 	$(GITIGNORE_MAINTAINERCLEANFILES_M4_LIBTOOL) \
 	$(GITIGNORE_MAINTAINERCLEANFILES_MAKEFILE_IN) \
 	$(srcdir)/INSTALL \
--- a/gfx/harfbuzz/NEWS
+++ b/gfx/harfbuzz/NEWS
@@ -1,8 +1,43 @@
+Overview of changes leading to 1.6.0
+Friday, October the 13th, 2017
+====================================
+
+- Update to Unicode 10.
+
+- Various Indic and Universal Shaping Engine fixes as a result of
+  HarfBuzz Hackfest with Jonathan Kew at Web Engines Hackfest at
+  the Igalia offices in A Coruña, Spain.  Thanks Igalia for having
+  us!
+
+- Implement Unicode Arabic Mark Ordering Algorithm UTR#53.
+
+- Implement optical sizing / tracking in CoreText backend, using
+  new API hb_font_set_ptem().
+
+- Allow notifying hb_font_t that underlying FT_Face changed sizing,
+  using new API hb_ft_font_changed().
+
+- More Graphite backend RTL fixes.
+
+- Fix caching of variable font shaping plans.
+
+- hb-view / hb-shape now accept following new arguments:
+
+  o --unicodes: takes a list of hex numbers that represent Unicode
+    codepoints.
+
+New API:
++hb_face_get_table_tags()
++hb_font_set_ptem()
++hb_font_get_ptem()
++hb_ft_font_changed()
+
+
 Overview of changes leading to 1.5.1
 Tuesday, September 5, 2017
 ====================================
 
 - Fix "unsafe-to-break" in fallback shaping and other corner cases.
   All our tests pass with --verify now, meaning unsafe-to-break API
   works as expected.
 - Add --unicodes to hb-view / hb-shape.
--- a/gfx/harfbuzz/README-mozilla
+++ b/gfx/harfbuzz/README-mozilla
@@ -1,14 +1,14 @@
-gfx/harfbuzz status as of 2017-09-05:
+gfx/harfbuzz status as of 2017-10-13:
 
 This directory contains the harfbuzz source from the 'master' branch of
 https://github.com/behdad/harfbuzz.
 
-Current version: 1.5.1
+Current version: 1.6.0
 
 UPDATING:
 
 Note that gfx/harfbuzz/src/hb-version.h is not present in the upstream Git
 repository. It is created at build time by the harfbuzz build system;
 but as we don't use that build system in mozilla, it is necessary to refresh
 this file when updating harfbuzz, and check it into the mozilla tree.
 
--- a/gfx/harfbuzz/configure.ac
+++ b/gfx/harfbuzz/configure.ac
@@ -1,11 +1,11 @@
 AC_PREREQ([2.64])
 AC_INIT([HarfBuzz],
-        [1.5.1],
+        [1.6.0],
         [https://github.com/behdad/harfbuzz/issues/new],
         [harfbuzz],
         [http://harfbuzz.org/])
 
 AC_CONFIG_MACRO_DIR([m4])
 AC_CONFIG_SRCDIR([src/harfbuzz.pc.in])
 AC_CONFIG_HEADERS([config.h])
 
@@ -64,18 +64,18 @@ GTK_DOC_CHECK([1.15],[--flavour no-tmpl]
 	if test "x$enable_gtk_doc" = xyes; then
 		have_gtk_doc=true
 	fi
 ], [
 	AM_CONDITIONAL([ENABLE_GTK_DOC], false)
 ])
 
 # Functions and headers
-AC_CHECK_FUNCS(atexit mprotect sysconf getpagesize mmap isatty)
-AC_CHECK_HEADERS(unistd.h sys/mman.h)
+AC_CHECK_FUNCS(atexit mprotect sysconf getpagesize mmap isatty newlocale strtod_l)
+AC_CHECK_HEADERS(unistd.h sys/mman.h xlocale.h)
 
 # Compiler flags
 AC_CANONICAL_HOST
 AC_CHECK_ALIGNOF([struct{char;}])
 if test "x$GCC" = "xyes"; then
 
 	# Make symbols link locally
 	LDFLAGS="$LDFLAGS -Bsymbolic-functions"
@@ -489,18 +489,16 @@ src/hb-version.h
 src/hb-ucdn/Makefile
 util/Makefile
 test/Makefile
 test/api/Makefile
 test/fuzzing/Makefile
 test/shaping/Makefile
 docs/Makefile
 docs/version.xml
-win32/Makefile
-win32/config.h.win32
 ])
 
 AC_OUTPUT
 
 AC_MSG_NOTICE([
 
 Build configuration:
 
--- a/gfx/harfbuzz/src/Makefile.am
+++ b/gfx/harfbuzz/src/Makefile.am
@@ -117,17 +117,17 @@ if HAVE_GCC
 libharfbuzz_la_LINK = $(LINK) $(libharfbuzz_la_LDFLAGS)
 else
 libharfbuzz_la_LINK = $(CXXLINK) $(libharfbuzz_la_LDFLAGS)
 endif
 endif
 
 libharfbuzz_la_SOURCES = $(HBSOURCES) $(HBHEADERS) $(HBNODISTHEADERS)
 libharfbuzz_la_CPPFLAGS = $(HBCFLAGS)
-libharfbuzz_la_LDFLAGS = $(AM_LDFLAGS) -version-info $(HB_LIBTOOL_VERSION_INFO) $(export_symbols) -no-undefined
+libharfbuzz_la_LDFLAGS = $(AM_LDFLAGS) -lm -version-info $(HB_LIBTOOL_VERSION_INFO) $(export_symbols) -no-undefined
 libharfbuzz_la_LIBADD = $(HBLIBS)
 EXTRA_libharfbuzz_la_DEPENDENCIES = $(harfbuzz_def_dependency)
 pkginclude_HEADERS = $(HBHEADERS)
 nodist_pkginclude_HEADERS = $(HBNODISTHEADERS)
 pkgconfigdir = $(libdir)/pkgconfig
 pkgconfig_DATA = harfbuzz.pc
 EXTRA_DIST += harfbuzz.pc.in
 
@@ -295,16 +295,17 @@ test_buffer_serialize_SOURCES = test-buf
 test_buffer_serialize_CPPFLAGS = $(HBCFLAGS)
 test_buffer_serialize_LDADD = libharfbuzz.la $(HBLIBS)
 
 check: harfbuzz.def # For check-defs.sh
 
 dist_check_SCRIPTS = \
 	check-c-linkage-decls.sh \
 	check-defs.sh \
+	check-externs.sh \
 	check-header-guards.sh \
 	check-includes.sh \
 	check-libstdc++.sh \
 	check-static-inits.sh \
 	check-symbols.sh \
 	$(NULL)
 
 check_PROGRAMS = \
new file mode 100755
--- /dev/null
+++ b/gfx/harfbuzz/src/check-externs.sh
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+LC_ALL=C
+export LC_ALL
+
+test -z "$srcdir" && srcdir=.
+stat=0
+
+test "x$HBHEADERS" = x && HBHEADERS=`cd "$srcdir"; find . -maxdepth 1 -name 'hb*.h'`
+test "x$EGREP" = x && EGREP='grep -E'
+
+
+echo 'Checking that all public symbols are exported with HB_EXTERN'
+
+for x in $HBHEADERS; do
+	test -f "$srcdir/$x" && x="$srcdir/$x"
+	$EGREP -B1 '^hb_' "$x" | $EGREP -E -v '^(--|hb_|HB_EXTERN )' -A1
+done |
+grep . >&2 && stat=1
+
+exit $stat
--- a/gfx/harfbuzz/src/gen-use-table.py
+++ b/gfx/harfbuzz/src/gen-use-table.py
@@ -112,16 +112,17 @@ property_names = [
 	'Visual_Order_Left',
 	'Left_And_Right',
 	'Top',
 	'Bottom',
 	'Top_And_Bottom',
 	'Top_And_Right',
 	'Top_And_Left',
 	'Top_And_Left_And_Right',
+	'Bottom_And_Left',
 	'Bottom_And_Right',
 	'Top_And_Bottom_And_Right',
 	'Overstruck',
 ]
 
 class PropertyValue(object):
 	def __init__(self, name_):
 		self.name = name_
@@ -148,17 +149,17 @@ def is_BASE(U, UISC, UGC):
 			Tone_Letter,
 			Vowel_Independent #SPEC-DRAFT
 			] or
 		(UGC == Lo and UISC in [Avagraha, Bindu, Consonant_Final, Consonant_Medial,
 					Consonant_Subjoined, Vowel, Vowel_Dependent]))
 def is_BASE_IND(U, UISC, UGC):
 	#SPEC-DRAFT return (UISC in [Consonant_Dead, Modifying_Letter] or UGC == Po)
 	return (UISC in [Consonant_Dead, Modifying_Letter] or
-		(UGC == Po and not U in [0x104E, 0x2022]) or
+		(UGC == Po and not U in [0x104E, 0x2022, 0x11A3F, 0x11A45]) or
 		False # SPEC-DRAFT-OUTDATED! U == 0x002D
 		)
 def is_BASE_NUM(U, UISC, UGC):
 	return UISC == Brahmi_Joining_Number
 def is_BASE_OTHER(U, UISC, UGC):
 	if UISC == Consonant_Placeholder: return True #SPEC-DRAFT
 	#SPEC-DRAFT return U in [0x00A0, 0x00D7, 0x2015, 0x2022, 0x25CC, 0x25FB, 0x25FC, 0x25FD, 0x25FE]
 	return U in [0x2015, 0x2022, 0x25FB, 0x25FC, 0x25FD, 0x25FE]
@@ -172,16 +173,18 @@ def is_CONS_FINAL_MOD(U, UISC, UGC):
 	return  UISC == Syllable_Modifier
 def is_CONS_MED(U, UISC, UGC):
 	return UISC == Consonant_Medial and UGC != Lo
 def is_CONS_MOD(U, UISC, UGC):
 	return UISC in [Nukta, Gemination_Mark, Consonant_Killer]
 def is_CONS_SUB(U, UISC, UGC):
 	#SPEC-DRAFT return UISC == Consonant_Subjoined
 	return UISC == Consonant_Subjoined and UGC != Lo
+def is_CONS_WITH_STACKER(U, UISC, UGC):
+	return UISC == Consonant_With_Stacker
 def is_HALANT(U, UISC, UGC):
 	return UISC in [Virama, Invisible_Stacker]
 def is_HALANT_NUM(U, UISC, UGC):
 	return UISC == Number_Joiner
 def is_ZWNJ(U, UISC, UGC):
 	return UISC == Non_Joiner
 def is_ZWJ(U, UISC, UGC):
 	return UISC == Joiner
@@ -193,19 +196,17 @@ def is_OTHER(U, UISC, UGC):
 		and not is_SYM_MOD(U, UISC, UGC)
 		and not is_CGJ(U, UISC, UGC)
 		and not is_Word_Joiner(U, UISC, UGC)
 		and not is_VARIATION_SELECTOR(U, UISC, UGC)
 	)
 def is_Reserved(U, UISC, UGC):
 	return UGC == 'Cn'
 def is_REPHA(U, UISC, UGC):
-	#return UISC == Consonant_Preceding_Repha
-	#SPEC-OUTDATED hack to categorize Consonant_With_Stacker and Consonant_Prefixed
-	return UISC in [Consonant_Preceding_Repha, Consonant_With_Stacker, Consonant_Prefixed]
+	return UISC in [Consonant_Preceding_Repha, Consonant_Prefixed]
 def is_SYM(U, UISC, UGC):
 	if U == 0x25CC: return False #SPEC-DRAFT
 	#SPEC-DRAFT return UGC in [So, Sc] or UISC == Symbol_Letter
 	return UGC in [So, Sc]
 def is_SYM_MOD(U, UISC, UGC):
 	return U in [0x1B6B, 0x1B6C, 0x1B6D, 0x1B6E, 0x1B6F, 0x1B70, 0x1B71, 0x1B72, 0x1B73]
 def is_VARIATION_SELECTOR(U, UISC, UGC):
 	return 0xFE00 <= U <= 0xFE0F
@@ -224,16 +225,17 @@ use_mapping = {
 	'N':	is_BASE_NUM,
 	'GB':	is_BASE_OTHER,
 	'CGJ':	is_CGJ,
 	'F':	is_CONS_FINAL,
 	'FM':	is_CONS_FINAL_MOD,
 	'M':	is_CONS_MED,
 	'CM':	is_CONS_MOD,
 	'SUB':	is_CONS_SUB,
+	'CS':	is_CONS_WITH_STACKER,
 	'H':	is_HALANT,
 	'HN':	is_HALANT_NUM,
 	'ZWNJ':	is_ZWNJ,
 	'ZWJ':	is_ZWJ,
 	'WJ':	is_Word_Joiner,
 	'O':	is_OTHER,
 	'Rsv':	is_Reserved,
 	'R':	is_REPHA,
@@ -247,17 +249,17 @@ use_mapping = {
 use_positions = {
 	'F': {
 		'Abv': [Top],
 		'Blw': [Bottom],
 		'Pst': [Right],
 	},
 	'M': {
 		'Abv': [Top],
-		'Blw': [Bottom],
+		'Blw': [Bottom, Bottom_And_Left],
 		'Pst': [Right],
 		'Pre': [Left],
 	},
 	'CM': {
 		'Abv': [Top],
 		'Blw': [Bottom],
 	},
 	'V': {
@@ -293,18 +295,20 @@ def map_to_use(data):
 		# have UIPC
 		if U == 0x17DD: UISC = Vowel_Dependent
 		if 0x1CE2 <= U <= 0x1CE8: UISC = Cantillation_Mark
 
 		# TODO: U+1CED should only be allowed after some of
 		# the nasalization marks, maybe only for U+1CE9..U+1CF1.
 		if U == 0x1CED: UISC = Tone_Mark
 
-		evals = [(k, v(U,UISC,UGC)) for k,v in items]
-		values = [k for k,v in evals if v]
+		# TODO: https://github.com/behdad/harfbuzz/issues/525
+		if U == 0x1A7F: UISC = Consonant_Final; UIPC = Bottom
+
+		values = [k for k,v in items if v(U,UISC,UGC)]
 		assert len(values) == 1, "%s %s %s %s" % (hex(U), UISC, UGC, values)
 		USE = values[0]
 
 		# Resolve Indic_Positional_Category
 
 		# TODO: Not in Unicode 8.0 yet, but in spec.
 		if U == 0x1B6C: UIPC = Bottom
 
--- a/gfx/harfbuzz/src/harfbuzz-icu.pc
+++ b/gfx/harfbuzz/src/harfbuzz-icu.pc
@@ -1,13 +1,13 @@
 prefix=/usr/local
 exec_prefix=/usr/local
 libdir=/usr/local/lib
 includedir=/usr/local/include
 
 Name: harfbuzz
 Description: HarfBuzz text shaping library ICU integration
-Version: 1.5.1
+Version: 1.6.0
 
 Requires: harfbuzz
 Requires.private: icu-uc
 Libs: -L${libdir} -lharfbuzz-icu
 Cflags: -I${includedir}/harfbuzz
--- a/gfx/harfbuzz/src/harfbuzz.pc
+++ b/gfx/harfbuzz/src/harfbuzz.pc
@@ -1,13 +1,13 @@
 prefix=/usr/local
 exec_prefix=/usr/local
 libdir=/usr/local/lib
 includedir=/usr/local/include
 
 Name: harfbuzz
 Description: HarfBuzz text shaping library
-Version: 1.5.1
+Version: 1.6.0
 
 Libs: -L${libdir} -lharfbuzz
-Libs.private:    
+Libs.private: -lm    
 Requires.private: glib-2.0 >= 2.19.1 
 Cflags: -I${includedir}/harfbuzz
--- a/gfx/harfbuzz/src/harfbuzz.pc.in
+++ b/gfx/harfbuzz/src/harfbuzz.pc.in
@@ -3,11 +3,11 @@ exec_prefix=%exec_prefix%
 libdir=%libdir%
 includedir=%includedir%
 
 Name: harfbuzz
 Description: HarfBuzz text shaping library
 Version: %VERSION%
 
 Libs: -L${libdir} -lharfbuzz
-Libs.private: %libs_private%
+Libs.private: -lm %libs_private%
 Requires.private: %requires_private%
 Cflags: -I${includedir}/harfbuzz
--- a/gfx/harfbuzz/src/hb-blob.cc
+++ b/gfx/harfbuzz/src/hb-blob.cc
@@ -123,16 +123,22 @@ hb_blob_create (const char        *data,
       hb_blob_destroy (blob);
       return hb_blob_get_empty ();
     }
   }
 
   return blob;
 }
 
+static void
+_hb_blob_destroy (void *data)
+{
+  hb_blob_destroy ((hb_blob_t *) data);
+}
+
 /**
  * hb_blob_create_sub_blob:
  * @parent: Parent blob.
  * @offset: Start offset of sub-blob within @parent, in bytes.
  * @length: Length of sub-blob.
  *
  * Returns a blob that represents a range of bytes in @parent.  The new
  * blob is always created with %HB_MEMORY_MODE_READONLY, meaning that it
@@ -159,17 +165,17 @@ hb_blob_create_sub_blob (hb_blob_t    *p
     return hb_blob_get_empty ();
 
   hb_blob_make_immutable (parent);
 
   blob = hb_blob_create (parent->data + offset,
 			 MIN (length, parent->length - offset),
 			 HB_MEMORY_MODE_READONLY,
 			 hb_blob_reference (parent),
-			 (hb_destroy_func_t) hb_blob_destroy);
+			 _hb_blob_destroy);
 
   return blob;
 }
 
 /**
  * hb_blob_get_empty:
  *
  * Returns the singleton empty blob.
--- a/gfx/harfbuzz/src/hb-buffer.h
+++ b/gfx/harfbuzz/src/hb-buffer.h
@@ -499,17 +499,17 @@ typedef enum { /*< flags >*/
   HB_BUFFER_DIFF_FLAG_CODEPOINT_MISMATCH	= 0x0010,
   HB_BUFFER_DIFF_FLAG_CLUSTER_MISMATCH		= 0x0020,
   HB_BUFFER_DIFF_FLAG_GLYPH_FLAGS_MISMATCH	= 0x0040,
   HB_BUFFER_DIFF_FLAG_POSITION_MISMATCH		= 0x0080
 
 } hb_buffer_diff_flags_t;
 
 /* Compare the contents of two buffers, report types of differences. */
-hb_buffer_diff_flags_t
+HB_EXTERN hb_buffer_diff_flags_t
 hb_buffer_diff (hb_buffer_t *buffer,
 		hb_buffer_t *reference,
 		hb_codepoint_t dottedcircle_glyph,
 		unsigned int position_fuzz);
 
 
 /*
  * Debugging.
--- a/gfx/harfbuzz/src/hb-common.cc
+++ b/gfx/harfbuzz/src/hb-common.cc
@@ -27,16 +27,19 @@
  */
 
 #include "hb-private.hh"
 
 #include "hb-mutex-private.hh"
 #include "hb-object-private.hh"
 
 #include <locale.h>
+#ifdef HAVE_XLOCALE_H
+#include <xlocale.h>
+#endif
 
 
 /* hb_options_t */
 
 hb_options_union_t _hb_options;
 
 void
 _hb_options_init (void)
@@ -241,18 +244,18 @@ struct hb_language_item_t {
 };
 
 
 /* Thread-safe lock-free language list */
 
 static hb_language_item_t *langs;
 
 #ifdef HB_USE_ATEXIT
-static
-void free_langs (void)
+static void
+free_langs (void)
 {
   while (langs) {
     hb_language_item_t *next = langs->next;
     langs->finish ();
     free (langs);
     langs = next;
   }
 }
@@ -689,30 +692,76 @@ parse_uint32 (const char **pp, const cha
   if (errno || p == pend)
     return false;
 
   *pv = v;
   *pp += pend - p;
   return true;
 }
 
+#if defined (HAVE_NEWLOCALE) && defined (HAVE_STRTOD_L)
+#define USE_XLOCALE 1
+#endif
+
+#ifdef USE_XLOCALE
+
+static locale_t C_locale;
+
+#ifdef HB_USE_ATEXIT
+static void
+free_C_locale (void)
+{
+  if (C_locale)
+    freelocale (C_locale);
+}
+#endif
+
+static locale_t
+get_C_locale (void)
+{
+retry:
+  locale_t C = (locale_t) hb_atomic_ptr_get (&C_locale);
+
+  if (unlikely (!C))
+  {
+    C = newlocale (LC_ALL_MASK, "C", NULL);
+
+    if (!hb_atomic_ptr_cmpexch (&C_locale, NULL, C))
+    {
+      freelocale (C_locale);
+      goto retry;
+    }
+
+#ifdef HB_USE_ATEXIT
+    atexit (free_C_locale); /* First person registers atexit() callback. */
+#endif
+  }
+
+  return C;
+}
+#endif
+
 static bool
 parse_float (const char **pp, const char *end, float *pv)
 {
   char buf[32];
   unsigned int len = MIN (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - *pp));
   strncpy (buf, *pp, len);
   buf[len] = '\0';
 
   char *p = buf;
   char *pend = p;
   float v;
 
   errno = 0;
+#ifdef USE_XLOCALE
+  v = strtod_l (p, &pend, get_C_locale ());
+#else
   v = strtod (p, &pend);
+#endif
   if (errno || p == pend)
     return false;
 
   *pv = v;
   *pp += pend - p;
   return true;
 }
 
--- a/gfx/harfbuzz/src/hb-common.h
+++ b/gfx/harfbuzz/src/hb-common.h
@@ -38,40 +38,26 @@
 #  define HB_BEGIN_DECLS	extern "C" {
 #  define HB_END_DECLS		}
 # else /* !__cplusplus */
 #  define HB_BEGIN_DECLS
 #  define HB_END_DECLS
 # endif /* !__cplusplus */
 #endif
 
-#if !defined (HB_DONT_DEFINE_STDINT)
-
 #if defined (_SVR4) || defined (SVR4) || defined (__OpenBSD__) || \
     defined (_sgi) || defined (__sun) || defined (sun) || \
     defined (__digital__) || defined (__HP_cc)
 #  include <inttypes.h>
 #elif defined (_AIX)
 #  include <sys/inttypes.h>
-/* VS 2010 (_MSC_VER 1600) has stdint.h */
-#elif defined (_MSC_VER) && _MSC_VER < 1600
-typedef __int8 int8_t;
-typedef unsigned __int8 uint8_t;
-typedef __int16 int16_t;
-typedef unsigned __int16 uint16_t;
-typedef __int32 int32_t;
-typedef unsigned __int32 uint32_t;
-typedef __int64 int64_t;
-typedef unsigned __int64 uint64_t;
 #else
 #  include <stdint.h>
 #endif
 
-#endif
-
 HB_BEGIN_DECLS
 
 
 typedef int hb_bool_t;
 
 typedef uint32_t hb_codepoint_t;
 typedef int32_t hb_position_t;
 typedef uint32_t hb_mask_t;
@@ -316,16 +302,24 @@ typedef enum
    */
   /*9.0*/ HB_SCRIPT_ADLAM			= HB_TAG ('A','d','l','m'),
   /*9.0*/ HB_SCRIPT_BHAIKSUKI			= HB_TAG ('B','h','k','s'),
   /*9.0*/ HB_SCRIPT_MARCHEN			= HB_TAG ('M','a','r','c'),
   /*9.0*/ HB_SCRIPT_OSAGE			= HB_TAG ('O','s','g','e'),
   /*9.0*/ HB_SCRIPT_TANGUT			= HB_TAG ('T','a','n','g'),
   /*9.0*/ HB_SCRIPT_NEWA			= HB_TAG ('N','e','w','a'),
 
+  /*
+   * Since 1.6.0
+   */
+  /*10.0*/HB_SCRIPT_MASARAM_GONDI		= HB_TAG ('G','o','n','m'),
+  /*10.0*/HB_SCRIPT_NUSHU			= HB_TAG ('N','s','h','u'),
+  /*10.0*/HB_SCRIPT_SOYOMBO			= HB_TAG ('S','o','y','o'),
+  /*10.0*/HB_SCRIPT_ZANABAZAR_SQUARE		= HB_TAG ('Z','a','n','b'),
+
   /* No script set. */
   HB_SCRIPT_INVALID				= HB_TAG_NONE,
 
   /* Dummy values to ensure any hb_tag_t value can be passed/stored as hb_script_t
    * without risking undefined behavior.  Include both a signed and unsigned max,
    * since technically enums are int, and indeed, hb_script_t ends up being signed.
    * See this thread for technicalities:
    *
--- a/gfx/harfbuzz/src/hb-coretext.cc
+++ b/gfx/harfbuzz/src/hb-coretext.cc
@@ -25,22 +25,37 @@
  * Mozilla Author(s): Jonathan Kew
  * Google Author(s): Behdad Esfahbod
  */
 
 #define HB_SHAPER coretext
 #include "hb-shaper-impl-private.hh"
 
 #include "hb-coretext.h"
+#include <math.h>
 
 
 #ifndef HB_DEBUG_CORETEXT
 #define HB_DEBUG_CORETEXT (HB_DEBUG+0)
 #endif
 
+/* https://developer.apple.com/documentation/coretext/1508745-ctfontcreatewithgraphicsfont */
+#define HB_CORETEXT_DEFAULT_FONT_SIZE 12.f
+
+static CGFloat
+coretext_font_size (float ptem)
+{
+  /* CoreText points are CSS pixels (96 per inch),
+   * NOT typographic points (72 per inch).
+   *
+   * https://developer.apple.com/library/content/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Explained/Explained.html
+   */
+  ptem *= 96.f / 72.f;
+  return ptem <= 0.f ? HB_CORETEXT_DEFAULT_FONT_SIZE : ptem;
+}
 
 static void
 release_table_data (void *user_data)
 {
   CFDataRef cf_data = reinterpret_cast<CFDataRef> (user_data);
   CFRelease(cf_data);
 }
 
@@ -57,26 +72,32 @@ reference_table  (hb_face_t *face HB_UNU
   if (!data || !length)
     return NULL;
 
   return hb_blob_create (data, length, HB_MEMORY_MODE_READONLY,
 			 reinterpret_cast<void *> (const_cast<__CFData *> (cf_data)),
 			 release_table_data);
 }
 
+static void
+_hb_cg_font_release (void *data)
+{
+  CGFontRelease ((CGFontRef) data);
+}
+
 hb_face_t *
 hb_coretext_face_create (CGFontRef cg_font)
 {
-  return hb_face_create_for_tables (reference_table, CGFontRetain (cg_font), (hb_destroy_func_t) CGFontRelease);
+  return hb_face_create_for_tables (reference_table, CGFontRetain (cg_font), _hb_cg_font_release);
 }
 
-
 HB_SHAPER_DATA_ENSURE_DEFINE(coretext, face)
-HB_SHAPER_DATA_ENSURE_DEFINE(coretext, font)
-
+HB_SHAPER_DATA_ENSURE_DEFINE_WITH_CONDITION(coretext, font,
+	fabs (CTFontGetSize((CTFontRef) data) - coretext_font_size (font->ptem)) <= .5
+)
 
 /*
  * shaper face data
  */
 
 static CTFontDescriptorRef
 get_last_resort_font_desc (void)
 {
@@ -108,17 +129,17 @@ release_data (void *info, const void *da
 
   hb_blob_destroy ((hb_blob_t *) info);
 }
 
 static CGFontRef
 create_cg_font (hb_face_t *face)
 {
   CGFontRef cg_font = NULL;
-  if (face->destroy == (hb_destroy_func_t) CGFontRelease)
+  if (face->destroy == _hb_cg_font_release)
   {
     cg_font = CGFontRetain ((CGFontRef) face->user_data);
   }
   else
   {
     hb_blob_t *blob = hb_face_reference_blob (face);
     unsigned int blob_length;
     const char *blob_data = hb_blob_get_data (blob, &blob_length);
@@ -135,17 +156,43 @@ create_cg_font (hb_face_t *face)
     }
   }
   return cg_font;
 }
 
 static CTFontRef
 create_ct_font (CGFontRef cg_font, CGFloat font_size)
 {
-  CTFontRef ct_font = CTFontCreateWithGraphicsFont (cg_font, font_size, NULL, NULL);
+  CTFontRef ct_font = NULL;
+
+  /* CoreText does not enable trak table usage / tracking when creating a CTFont
+   * using CTFontCreateWithGraphicsFont. The only way of enabling tracking seems
+   * to be through the CTFontCreateUIFontForLanguage call. */
+  CFStringRef cg_postscript_name = CGFontCopyPostScriptName (cg_font);
+  if (CFStringHasPrefix (cg_postscript_name, CFSTR (".SFNSText")) ||
+      CFStringHasPrefix (cg_postscript_name, CFSTR (".SFNSDisplay")))
+  {
+    CTFontUIFontType font_type = kCTFontUIFontSystem;
+    if (CFStringHasSuffix (cg_postscript_name, CFSTR ("-Bold")))
+      font_type = kCTFontUIFontEmphasizedSystem;
+
+    ct_font = CTFontCreateUIFontForLanguage (font_type, font_size, NULL);
+    CFStringRef ct_result_name = CTFontCopyPostScriptName(ct_font);
+    if (CFStringCompare (ct_result_name, cg_postscript_name, 0) != kCFCompareEqualTo)
+    {
+      CFRelease(ct_font);
+      ct_font = NULL;
+    }
+    CFRelease (ct_result_name);
+  }
+  CFRelease (cg_postscript_name);
+
+  if (!ct_font)
+    ct_font = CTFontCreateWithGraphicsFont (cg_font, font_size, NULL, NULL);
+
   if (unlikely (!ct_font)) {
     DEBUG_MSG (CORETEXT, cg_font, "Font CTFontCreateWithGraphicsFont() failed");
     return NULL;
   }
 
   /* crbug.com/576941 and crbug.com/625902 and the investigation in the latter
    * bug indicate that the cascade list reconfiguration occasionally causes
    * crashes in CoreText on OS X 10.9, thus let's skip this step on older
@@ -197,90 +244,73 @@ create_ct_font (CGFontRef cg_font, CGFlo
       DEBUG_MSG (CORETEXT, ct_font, "Font copy with empty cascade list failed");
   }
 
   if (original_url)
     CFRelease (original_url);
   return ct_font;
 }
 
-struct hb_coretext_shaper_face_data_t {
-  CGFontRef cg_font;
-  CTFontRef ct_font;
-};
-
 hb_coretext_shaper_face_data_t *
 _hb_coretext_shaper_face_data_create (hb_face_t *face)
 {
-  hb_coretext_shaper_face_data_t *data = (hb_coretext_shaper_face_data_t *) calloc (1, sizeof (hb_coretext_shaper_face_data_t));
-  if (unlikely (!data))
-    return NULL;
+  CGFontRef cg_font = create_cg_font (face);
 
-  data->cg_font = create_cg_font (face);
-  if (unlikely (!data->cg_font))
+  if (unlikely (!cg_font))
   {
     DEBUG_MSG (CORETEXT, face, "CGFont creation failed..");
-    free (data);
     return NULL;
   }
 
-  /* We use 36pt size instead of UPEM, because CoreText implements the 'trak' table,
-   * which can make the font too tight at large sizes.  36pt should be a good semi-neutral
-   * size.
-   *
-   * Since we always create CTFont at a fixed size, our CTFont lives in face_data
-   * instead of font_data.  Which is good, because when people change scale on
-   * hb_font_t, we won't need to update our CTFont. */
-  data->ct_font = create_ct_font (data->cg_font, 36.);
-  if (unlikely (!data->ct_font))
-  {
-    DEBUG_MSG (CORETEXT, face, "CTFont creation failed.");
-    CFRelease (data->cg_font);
-    free (data);
-    return NULL;
-  }
-
-  return data;
+  return (hb_coretext_shaper_face_data_t *) cg_font;
 }
 
 void
 _hb_coretext_shaper_face_data_destroy (hb_coretext_shaper_face_data_t *data)
 {
-  CFRelease (data->ct_font);
-  CFRelease (data->cg_font);
-  free (data);
+  CFRelease ((CGFontRef) data);
 }
 
 /*
  * Since: 0.9.10
  */
 CGFontRef
 hb_coretext_face_get_cg_font (hb_face_t *face)
 {
   if (unlikely (!hb_coretext_shaper_face_data_ensure (face))) return NULL;
-  hb_coretext_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
-  return face_data->cg_font;
+  return (CGFontRef) HB_SHAPER_DATA_GET (face);
 }
 
 
 /*
  * shaper font data
  */
 
-struct hb_coretext_shaper_font_data_t {};
+hb_coretext_shaper_font_data_t *
+_hb_coretext_shaper_font_data_create (hb_font_t *font)
+{
+  hb_face_t *face = font->face;
+  if (unlikely (!hb_coretext_shaper_face_data_ensure (face))) return NULL;
+  CGFontRef cg_font = (CGFontRef) HB_SHAPER_DATA_GET (face);
 
-hb_coretext_shaper_font_data_t *
-_hb_coretext_shaper_font_data_create (hb_font_t *font HB_UNUSED)
-{
-  return (hb_coretext_shaper_font_data_t *) HB_SHAPER_DATA_SUCCEEDED;
+  CTFontRef ct_font = create_ct_font (cg_font, coretext_font_size (font->ptem));
+
+  if (unlikely (!ct_font))
+  {
+    DEBUG_MSG (CORETEXT, font, "CGFont creation failed..");
+    return NULL;
+  }
+
+  return (hb_coretext_shaper_font_data_t *) ct_font;
 }
 
 void
 _hb_coretext_shaper_font_data_destroy (hb_coretext_shaper_font_data_t *data)
 {
+  CFRelease ((CTFontRef) data);
 }
 
 
 /*
  * shaper shape_plan data
  */
 
 struct hb_coretext_shaper_shape_plan_data_t {};
@@ -298,20 +328,18 @@ hb_coretext_shaper_shape_plan_data_t *
 void
 _hb_coretext_shaper_shape_plan_data_destroy (hb_coretext_shaper_shape_plan_data_t *data HB_UNUSED)
 {
 }
 
 CTFontRef
 hb_coretext_font_get_ct_font (hb_font_t *font)
 {
-  hb_face_t *face = font->face;
-  if (unlikely (!hb_coretext_shaper_face_data_ensure (face))) return NULL;
-  hb_coretext_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
-  return face_data->ct_font;
+  if (unlikely (!hb_coretext_shaper_font_data_ensure (font))) return NULL;
+  return (CTFontRef)HB_SHAPER_DATA_GET (font);
 }
 
 
 /*
  * shaper
  */
 
 struct feature_record_t {
@@ -533,19 +561,20 @@ static int
 hb_bool_t
 _hb_coretext_shape (hb_shape_plan_t    *shape_plan,
 		    hb_font_t          *font,
                     hb_buffer_t        *buffer,
                     const hb_feature_t *features,
                     unsigned int        num_features)
 {
   hb_face_t *face = font->face;
-  hb_coretext_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
+  CGFontRef cg_font = (CGFontRef) HB_SHAPER_DATA_GET (face);
+  CTFontRef ct_font = (CTFontRef) HB_SHAPER_DATA_GET (font);
 
-  CGFloat ct_font_size = CTFontGetSize (face_data->ct_font);
+  CGFloat ct_font_size = CTFontGetSize (ct_font);
   CGFloat x_mult = (CGFloat) font->x_scale / ct_font_size;
   CGFloat y_mult = (CGFloat) font->y_scale / ct_font_size;
 
   /* Attach marks to their bases, to match the 'ot' shaper.
    * Adapted from hb-ot-shape:hb_form_clusters().
    * Note that this only makes us be closer to the 'ot' shaper,
    * but by no means the same.  For example, if there's
    * B1 M1 B2 M2, and B1-B2 form a ligature, M2's cluster will
@@ -670,17 +699,17 @@ hb_bool_t
 							   1,
 							   &kCFTypeDictionaryKeyCallBacks,
 							   &kCFTypeDictionaryValueCallBacks);
 	  CFRelease (features_array);
 
 	  CTFontDescriptorRef font_desc = CTFontDescriptorCreateWithAttributes (attributes);
 	  CFRelease (attributes);
 
-	  range->font = CTFontCreateCopyWithAttributes (face_data->ct_font, 0.0, NULL, font_desc);
+	  range->font = CTFontCreateCopyWithAttributes (ct_font, 0.0, NULL, font_desc);
 	  CFRelease (font_desc);
 	}
 	else
 	{
 	  range->font = NULL;
 	}
 
 	range->index_first = last_index;
@@ -824,17 +853,17 @@ resize_and_retry:
 							    kCFAllocatorNull);
 	if (unlikely (!lang))
 	  FAIL ("CFStringCreateWithCStringNoCopy failed");
 	CFAttributedStringSetAttribute (attr_string, CFRangeMake (0, chars_len),
 					kCTLanguageAttributeName, lang);
 	CFRelease (lang);
       }
       CFAttributedStringSetAttribute (attr_string, CFRangeMake (0, chars_len),
-				      kCTFontAttributeName, face_data->ct_font);
+				      kCTFontAttributeName, ct_font);
 
       if (num_features && range_records.len)
       {
 	unsigned int start = 0;
 	range_record_t *last_range = &range_records[0];
 	for (unsigned int k = 0; k < chars_len; k++)
 	{
 	  range_record_t *range = last_range;
@@ -942,17 +971,17 @@ resize_and_retry:
       /* CoreText does automatic font fallback (AKA "cascading") for  characters
        * not supported by the requested font, and provides no way to turn it off,
        * so we must detect if the returned run uses a font other than the requested
        * one and fill in the buffer with .notdef glyphs instead of random glyph
        * indices from a different font.
        */
       CFDictionaryRef attributes = CTRunGetAttributes (run);
       CTFontRef run_ct_font = static_cast<CTFontRef>(CFDictionaryGetValue (attributes, kCTFontAttributeName));
-      if (!CFEqual (run_ct_font, face_data->ct_font))
+      if (!CFEqual (run_ct_font, ct_font))
       {
 	/* The run doesn't use our main font instance.  We have to figure out
 	 * whether font fallback happened, or this is just CoreText giving us
 	 * another CTFont using the same underlying CGFont.  CoreText seems
 	 * to do that in a variety of situations, one of which being vertical
 	 * text, but also perhaps for caching reasons.
 	 *
 	 * First, see if it uses any of our subfonts created to set font features...
@@ -980,23 +1009,23 @@ resize_and_retry:
 	    matched = true;
 	    break;
 	  }
 	if (!matched)
 	{
 	  CGFontRef run_cg_font = CTFontCopyGraphicsFont (run_ct_font, 0);
 	  if (run_cg_font)
 	  {
-	    matched = CFEqual (run_cg_font, face_data->cg_font);
+	    matched = CFEqual (run_cg_font, cg_font);
 	    CFRelease (run_cg_font);
 	  }
 	}
 	if (!matched)
 	{
-	  CFStringRef font_ps_name = CTFontCopyName (face_data->ct_font, kCTFontPostScriptNameKey);
+	  CFStringRef font_ps_name = CTFontCopyName (ct_font, kCTFontPostScriptNameKey);
 	  CFStringRef run_ps_name = CTFontCopyName (run_ct_font, kCTFontPostScriptNameKey);
 	  CFComparisonResult result = CFStringCompare (run_ps_name, font_ps_name, 0);
 	  CFRelease (run_ps_name);
 	  CFRelease (font_ps_name);
 	  if (result == kCFCompareEqualTo)
 	    matched = true;
 	}
 	if (!matched)
@@ -1258,32 +1287,30 @@ HB_SHAPER_DATA_ENSURE_DEFINE(coretext_aa
  * shaper face data
  */
 
 struct hb_coretext_aat_shaper_face_data_t {};
 
 hb_coretext_aat_shaper_face_data_t *
 _hb_coretext_aat_shaper_face_data_create (hb_face_t *face)
 {
-  hb_blob_t *mort_blob = face->reference_table (HB_CORETEXT_TAG_MORT);
-  /* Umm, we just reference the table to check whether it exists.
-   * Maybe add better API for this? */
-  if (!hb_blob_get_length (mort_blob))
+  static const hb_tag_t tags[] = {HB_CORETEXT_TAG_MORX, HB_CORETEXT_TAG_MORT, HB_CORETEXT_TAG_KERX};
+
+  for (unsigned int i = 0; i < ARRAY_LENGTH (tags); i++)
   {
-    hb_blob_destroy (mort_blob);
-    mort_blob = face->reference_table (HB_CORETEXT_TAG_MORX);
-    if (!hb_blob_get_length (mort_blob))
+    hb_blob_t *blob = face->reference_table (tags[i]);
+    if (hb_blob_get_length (blob))
     {
-      hb_blob_destroy (mort_blob);
-      return NULL;
+      hb_blob_destroy (blob);
+      return hb_coretext_shaper_face_data_ensure (face) ? (hb_coretext_aat_shaper_face_data_t *) HB_SHAPER_DATA_SUCCEEDED : NULL;
     }
+    hb_blob_destroy (blob);
   }
-  hb_blob_destroy (mort_blob);
 
-  return hb_coretext_shaper_face_data_ensure (face) ? (hb_coretext_aat_shaper_face_data_t *) HB_SHAPER_DATA_SUCCEEDED : NULL;
+  return NULL;
 }
 
 void
 _hb_coretext_aat_shaper_face_data_destroy (hb_coretext_aat_shaper_face_data_t *data HB_UNUSED)
 {
 }
 
 
--- a/gfx/harfbuzz/src/hb-coretext.h
+++ b/gfx/harfbuzz/src/hb-coretext.h
@@ -37,16 +37,17 @@
 #  include <ApplicationServices/ApplicationServices.h>
 #endif
 
 HB_BEGIN_DECLS
 
 
 #define HB_CORETEXT_TAG_MORT HB_TAG('m','o','r','t')
 #define HB_CORETEXT_TAG_MORX HB_TAG('m','o','r','x')
+#define HB_CORETEXT_TAG_KERX HB_TAG('k','e','r','x')
 
 
 HB_EXTERN hb_face_t *
 hb_coretext_face_create (CGFontRef cg_font);
 
 
 HB_EXTERN CGFontRef
 hb_coretext_face_get_cg_font (hb_face_t *face);
--- a/gfx/harfbuzz/src/hb-face-private.hh
+++ b/gfx/harfbuzz/src/hb-face-private.hh
@@ -49,23 +49,16 @@ struct hb_face_t {
   hb_reference_table_func_t  reference_table_func;
   void                      *user_data;
   hb_destroy_func_t          destroy;
 
   unsigned int index;			/* Face index in a collection, zero-based. */
   mutable unsigned int upem;		/* Units-per-EM. */
   mutable unsigned int num_glyphs;	/* Number of glyphs. */
 
-  enum dirty_t {
-    DIRTY_NOTHING	= 0x0000,
-    DIRTY_INDEX		= 0x0001,
-    DIRTY_UPEM		= 0x0002,
-    DIRTY_NUM_GLYPHS	= 0x0004,
-  } dirty;
-
   struct hb_shaper_data_t shaper_data;	/* Various shaper data. */
 
   /* Various non-shaping data. */
   /* ... */
 
   /* Cache */
   struct plan_node_t {
     hb_shape_plan_t *shape_plan;
@@ -101,18 +94,16 @@ struct hb_face_t {
     return num_glyphs;
   }
 
   private:
   HB_INTERNAL void load_upem (void) const;
   HB_INTERNAL void load_num_glyphs (void) const;
 };
 
-HB_MARK_AS_FLAG_T (hb_face_t::dirty_t);
-
 extern HB_INTERNAL const hb_face_t _hb_face_nil;
 
 #define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
 #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_PROTOTYPE(shaper, face);
 #include "hb-shaper-list.hh"
 #undef HB_SHAPER_IMPLEMENT
 #undef HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
 
--- a/gfx/harfbuzz/src/hb-face.cc
+++ b/gfx/harfbuzz/src/hb-face.cc
@@ -46,18 +46,16 @@ const hb_face_t _hb_face_nil = {
   NULL, /* reference_table_func */
   NULL, /* user_data */
   NULL, /* destroy */
 
   0,    /* index */
   1000, /* upem */
   0,    /* num_glyphs */
 
-  hb_face_t::DIRTY_NOTHING, /* dirty */
-
   {
 #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID,
 #include "hb-shaper-list.hh"
 #undef HB_SHAPER_IMPLEMENT
   },
 
   NULL, /* shape_plans */
 };
@@ -115,18 +113,20 @@ static hb_face_for_data_closure_t *
 
   closure->blob = blob;
   closure->index = index;
 
   return closure;
 }
 
 static void
-_hb_face_for_data_closure_destroy (hb_face_for_data_closure_t *closure)
+_hb_face_for_data_closure_destroy (void *data)
 {
+  hb_face_for_data_closure_t *closure = (hb_face_for_data_closure_t *) data;
+
   hb_blob_destroy (closure->blob);
   free (closure);
 }
 
 static hb_blob_t *
 _hb_face_for_data_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
 {
   hb_face_for_data_closure_t *data = (hb_face_for_data_closure_t *) user_data;
@@ -166,17 +166,17 @@ hb_face_create (hb_blob_t    *blob,
 
   hb_face_for_data_closure_t *closure = _hb_face_for_data_closure_create (OT::Sanitizer<OT::OpenTypeFontFile>::sanitize (hb_blob_reference (blob)), index);
 
   if (unlikely (!closure))
     return hb_face_get_empty ();
 
   face = hb_face_create_for_tables (_hb_face_for_data_reference_table,
 				    closure,
-				    (hb_destroy_func_t) _hb_face_for_data_closure_destroy);
+				    _hb_face_for_data_closure_destroy);
 
   face->index = index;
 
   return face;
 }
 
 /**
  * hb_face_get_empty:
@@ -362,21 +362,16 @@ hb_face_reference_blob (hb_face_t *face)
  **/
 void
 hb_face_set_index (hb_face_t    *face,
 		   unsigned int  index)
 {
   if (face->immutable)
     return;
 
-  if (face->index == index)
-    return;
-
-  face->dirty |= face->DIRTY_INDEX;
-
   face->index = index;
 }
 
 /**
  * hb_face_get_index:
  * @face: a face.
  *
  * 
@@ -402,21 +397,16 @@ hb_face_get_index (hb_face_t    *face)
  **/
 void
 hb_face_set_upem (hb_face_t    *face,
 		  unsigned int  upem)
 {
   if (face->immutable)
     return;
 
-  if (face->upem == upem)
-    return;
-
-  face->dirty |= face->DIRTY_UPEM;
-
   face->upem = upem;
 }
 
 /**
  * hb_face_get_upem:
  * @face: a face.
  *
  * 
@@ -451,21 +441,16 @@ hb_face_t::load_upem (void) const
  **/
 void
 hb_face_set_glyph_count (hb_face_t    *face,
 			 unsigned int  glyph_count)
 {
   if (face->immutable)
     return;
 
-  if (face->num_glyphs == glyph_count)
-    return;
-
-  face->dirty |= face->DIRTY_NUM_GLYPHS;
-
   face->num_glyphs = glyph_count;
 }
 
 /**
  * hb_face_get_glyph_count:
  * @face: a face.
  *
  * 
@@ -484,9 +469,38 @@ void
 hb_face_t::load_num_glyphs (void) const
 {
   hb_blob_t *maxp_blob = OT::Sanitizer<OT::maxp>::sanitize (reference_table (HB_OT_TAG_maxp));
   const OT::maxp *maxp_table = OT::Sanitizer<OT::maxp>::lock_instance (maxp_blob);
   num_glyphs = maxp_table->get_num_glyphs ();
   hb_blob_destroy (maxp_blob);
 }
 
+/**
+ * hb_face_get_table_tags:
+ * @face: a face.
+ *
+ * Retrieves table tags for a face, if possible.
+ *
+ * Return value: total number of tables, or 0 if not possible to list.
+ *
+ * Since: 1.6.0
+ **/
+unsigned int
+hb_face_get_table_tags (hb_face_t    *face,
+			unsigned int  start_offset,
+			unsigned int *table_count, /* IN/OUT */
+			hb_tag_t     *table_tags /* OUT */)
+{
+  if (face->destroy != _hb_face_for_data_closure_destroy)
+  {
+    if (table_count)
+      *table_count = 0;
+    return 0;
+  }
 
+  hb_face_for_data_closure_t *data = (hb_face_for_data_closure_t *) face->user_data;
+
+  const OT::OpenTypeFontFile &ot_file = *OT::Sanitizer<OT::OpenTypeFontFile>::lock_instance (data->blob);
+  const OT::OpenTypeFontFace &ot_face = ot_file.get_face (data->index);
+
+  return ot_face.get_table_tags (start_offset, table_count, table_tags);
+}
--- a/gfx/harfbuzz/src/hb-face.h
+++ b/gfx/harfbuzz/src/hb-face.h
@@ -106,12 +106,17 @@ hb_face_get_upem (hb_face_t *face);
 
 HB_EXTERN void
 hb_face_set_glyph_count (hb_face_t    *face,
 			 unsigned int  glyph_count);
 
 HB_EXTERN unsigned int
 hb_face_get_glyph_count (hb_face_t *face);
 
+HB_EXTERN unsigned int
+hb_face_get_table_tags (hb_face_t    *face,
+			unsigned int  start_offset,
+			unsigned int *table_count, /* IN/OUT */
+			hb_tag_t     *table_tags /* OUT */);
 
 HB_END_DECLS
 
 #endif /* HB_FACE_H */
--- a/gfx/harfbuzz/src/hb-font-private.hh
+++ b/gfx/harfbuzz/src/hb-font-private.hh
@@ -103,34 +103,26 @@ struct hb_font_t {
   hb_face_t *face;
 
   int x_scale;
   int y_scale;
 
   unsigned int x_ppem;
   unsigned int y_ppem;
 
+  float ptem;
+
   /* Font variation coordinates. */
   unsigned int num_coords;
   int *coords;
 
   hb_font_funcs_t   *klass;
   void              *user_data;
   hb_destroy_func_t  destroy;
 
-  enum dirty_t {
-    DIRTY_NOTHING	= 0x0000,
-    DIRTY_FACE		= 0x0001,
-    DIRTY_PARENT	= 0x0002,
-    DIRTY_FUNCS		= 0x0004,
-    DIRTY_SCALE		= 0x0008,
-    DIRTY_PPEM		= 0x0010,
-    DIRTY_VARIATIONS	= 0x0020,
-  } dirty;
-
   struct hb_shaper_data_t shaper_data;
 
 
   /* Convert from font-space to user-space */
   inline int dir_scale (hb_direction_t direction)
   { return HB_DIRECTION_IS_VERTICAL(direction) ? y_scale : x_scale; }
   inline hb_position_t em_scale_x (int16_t v) { return em_scale (v, x_scale); }
   inline hb_position_t em_scale_y (int16_t v) { return em_scale (v, y_scale); }
@@ -548,18 +540,16 @@ struct hb_font_t {
     return (hb_position_t) (scaled / upem);
   }
   inline hb_position_t em_scalef (float v, int scale)
   {
     return (hb_position_t) (v * scale / face->get_upem ());
   }
 };
 
-HB_MARK_AS_FLAG_T (hb_font_t::dirty_t);
-
 #define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
 #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_PROTOTYPE(shaper, font);
 #include "hb-shaper-list.hh"
 #undef HB_SHAPER_IMPLEMENT
 #undef HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
 
 
 #endif /* HB_FONT_PRIVATE_HH */
--- a/gfx/harfbuzz/src/hb-font.cc
+++ b/gfx/harfbuzz/src/hb-font.cc
@@ -1152,18 +1152,30 @@ hb_font_create_sub_font (hb_font_t *pare
     return font;
 
   font->parent = hb_font_reference (parent);
 
   font->x_scale = parent->x_scale;
   font->y_scale = parent->y_scale;
   font->x_ppem = parent->x_ppem;
   font->y_ppem = parent->y_ppem;
+  font->ptem = parent->ptem;
 
-  /* TODO: copy variation coordinates. */
+  font->num_coords = parent->num_coords;
+  if (!font->num_coords)
+    font->coords = NULL;
+  else
+  {
+    unsigned int size = parent->num_coords * sizeof (parent->coords[0]);
+    font->coords = (int *) malloc (size);
+    if (unlikely (!font->coords))
+      font->num_coords = 0;
+    else
+      memcpy (font->coords, parent->coords, size);
+  }
 
   return font;
 }
 
 /**
  * hb_font_get_empty:
  *
  * 
@@ -1183,26 +1195,25 @@ hb_font_get_empty (void)
     NULL, /* parent */
     const_cast<hb_face_t *> (&_hb_face_nil),
 
     1000, /* x_scale */
     1000, /* y_scale */
 
     0, /* x_ppem */
     0, /* y_ppem */
+    0, /* ptem */
 
     0, /* num_coords */
     NULL, /* coords */
 
     const_cast<hb_font_funcs_t *> (&_hb_font_funcs_nil), /* klass */
     NULL, /* user_data */
     NULL, /* destroy */
 
-    hb_font_t::DIRTY_NOTHING, /* dirty */
-
     {
 #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID,
 #include "hb-shaper-list.hh"
 #undef HB_SHAPER_IMPLEMENT
     }
   };
 
   return const_cast<hb_font_t *> (&_hb_font_nil);
@@ -1345,21 +1356,16 @@ hb_font_set_parent (hb_font_t *font,
 		    hb_font_t *parent)
 {
   if (font->immutable)
     return;
 
   if (!parent)
     parent = hb_font_get_empty ();
 
-  if (parent == font->parent)
-    return;
-
-  font->dirty |= font->DIRTY_PARENT;
-
   hb_font_t *old = font->parent;
 
   font->parent = hb_font_reference (parent);
 
   hb_font_destroy (old);
 }
 
 /**
@@ -1392,21 +1398,16 @@ hb_font_set_face (hb_font_t *font,
 		  hb_face_t *face)
 {
   if (font->immutable)
     return;
 
   if (unlikely (!face))
     face = hb_face_get_empty ();
 
-  if (font->face == face)
-    return;
-
-  font->dirty |= font->DIRTY_FACE;
-
   hb_face_t *old = font->face;
 
   font->face = hb_face_reference (face);
 
   hb_face_destroy (old);
 }
 
 /**
@@ -1450,18 +1451,16 @@ hb_font_set_funcs (hb_font_t         *fo
   }
 
   if (font->destroy)
     font->destroy (font->user_data);
 
   if (!klass)
     klass = hb_font_funcs_get_empty ();
 
-  font->dirty |= font->DIRTY_FUNCS;
-
   hb_font_funcs_reference (klass);
   hb_font_funcs_destroy (font->klass);
   font->klass = klass;
   font->user_data = font_data;
   font->destroy = destroy;
 }
 
 /**
@@ -1507,21 +1506,16 @@ hb_font_set_funcs_data (hb_font_t       
 void
 hb_font_set_scale (hb_font_t *font,
 		   int x_scale,
 		   int y_scale)
 {
   if (font->immutable)
     return;
 
-  if (font->x_scale == x_scale && font->y_scale == y_scale)
-    return;
-
-  font->dirty |= font->DIRTY_SCALE;
-
   font->x_scale = x_scale;
   font->y_scale = y_scale;
 }
 
 /**
  * hb_font_get_scale:
  * @font: a font.
  * @x_scale: (out): 
@@ -1553,21 +1547,16 @@ hb_font_get_scale (hb_font_t *font,
 void
 hb_font_set_ppem (hb_font_t *font,
 		  unsigned int x_ppem,
 		  unsigned int y_ppem)
 {
   if (font->immutable)
     return;
 
-  if (font->x_ppem == x_ppem && font->y_ppem == y_ppem)
-    return;
-
-  font->dirty |= font->DIRTY_PPEM;
-
   font->x_ppem = x_ppem;
   font->y_ppem = y_ppem;
 }
 
 /**
  * hb_font_get_ppem:
  * @font: a font.
  * @x_ppem: (out): 
@@ -1581,35 +1570,59 @@ void
 hb_font_get_ppem (hb_font_t *font,
 		  unsigned int *x_ppem,
 		  unsigned int *y_ppem)
 {
   if (x_ppem) *x_ppem = font->x_ppem;
   if (y_ppem) *y_ppem = font->y_ppem;
 }
 
+/**
+ * hb_font_set_ptem:
+ * @font: a font.
+ * @ptem: 
+ *
+ * Sets "point size" of the font.
+ *
+ * Since: 1.6.0
+ **/
+void
+hb_font_set_ptem (hb_font_t *font, float ptem)
+{
+  if (font->immutable)
+    return;
+
+  font->ptem = ptem;
+}
+
+/**
+ * hb_font_get_ptem:
+ * @font: a font.
+ *
+ * Gets the "point size" of the font.  A value of 0 means unset.
+ *
+ * Return value: Point size.
+ *
+ * Since: 0.9.2
+ **/
+float
+hb_font_get_ptem (hb_font_t *font)
+{
+  return font->ptem;
+}
+
 /*
  * Variations
  */
 
 static void
 _hb_font_adopt_var_coords_normalized (hb_font_t *font,
 				      int *coords, /* 2.14 normalized */
 				      unsigned int coords_length)
 {
-  if (font->num_coords == coords_length &&
-      (coords_length == 0 ||
-       0 == memcmp (font->coords, coords, coords_length * sizeof (coords[0]))))
-  {
-    free (coords);
-    return;
-  }
-
-  font->dirty |= font->DIRTY_VARIATIONS;
-
   free (font->coords);
 
   font->coords = coords;
   font->num_coords = coords_length;
 }
 
 /**
  * hb_font_set_variations:
--- a/gfx/harfbuzz/src/hb-font.h
+++ b/gfx/harfbuzz/src/hb-font.h
@@ -602,16 +602,26 @@ hb_font_set_ppem (hb_font_t *font,
 		  unsigned int x_ppem,
 		  unsigned int y_ppem);
 
 HB_EXTERN void
 hb_font_get_ppem (hb_font_t *font,
 		  unsigned int *x_ppem,
 		  unsigned int *y_ppem);
 
+/*
+ * Point size per EM.  Used for optical-sizing in CoreText.
+ * A value of zero means "not set".
+ */
+HB_EXTERN void
+hb_font_set_ptem (hb_font_t *font, float ptem);
+
+HB_EXTERN float
+hb_font_get_ptem (hb_font_t *font);
+
 HB_EXTERN void
 hb_font_set_variations (hb_font_t *font,
 			const hb_variation_t *variations,
 			unsigned int variations_length);
 
 HB_EXTERN void
 hb_font_set_var_coords_design (hb_font_t *font,
 			       const float *coords,
--- a/gfx/harfbuzz/src/hb-ft.cc
+++ b/gfx/harfbuzz/src/hb-ft.cc
@@ -90,24 +90,26 @@ static hb_ft_font_t *
   ft_font->unref = unref;
 
   ft_font->load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING;
 
   return ft_font;
 }
 
 static void
-_hb_ft_face_destroy (FT_Face ft_face)
+_hb_ft_face_destroy (void *data)
 {
-  FT_Done_Face (ft_face);
+  FT_Done_Face ((FT_Face) data);
 }
 
 static void
-_hb_ft_font_destroy (hb_ft_font_t *ft_font)
+_hb_ft_font_destroy (void *data)
 {
+  hb_ft_font_t *ft_font = (hb_ft_font_t *) data;
+
   if (ft_font->unref)
     _hb_ft_face_destroy (ft_font->ft_face);
 
   free (ft_font);
 }
 
 /**
  * hb_ft_font_set_load_flags:
@@ -119,17 +121,17 @@ static void
  * Since: 1.0.5
  **/
 void
 hb_ft_font_set_load_flags (hb_font_t *font, int load_flags)
 {
   if (font->immutable)
     return;
 
-  if (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy)
+  if (font->destroy != _hb_ft_font_destroy)
     return;
 
   hb_ft_font_t *ft_font = (hb_ft_font_t *) font->user_data;
 
   ft_font->load_flags = load_flags;
 }
 
 /**
@@ -139,28 +141,28 @@ hb_ft_font_set_load_flags (hb_font_t *fo
  * 
  *
  * Return value:
  * Since: 1.0.5
  **/
 int
 hb_ft_font_get_load_flags (hb_font_t *font)
 {
-  if (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy)
+  if (font->destroy != _hb_ft_font_destroy)
     return 0;
 
   const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font->user_data;
 
   return ft_font->load_flags;
 }
 
 FT_Face
 hb_ft_font_get_face (hb_font_t *font)
 {
-  if (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy)
+  if (font->destroy != _hb_ft_font_destroy)
     return NULL;
 
   const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font->user_data;
 
   return ft_font->ft_face;
 }
 
 
@@ -469,17 +471,17 @@ retry:
 #endif
   };
 
   bool symbol = ft_face->charmap && ft_face->charmap->encoding == FT_ENCODING_MS_SYMBOL;
 
   hb_font_set_funcs (font,
 		     funcs,
 		     _hb_ft_font_create (ft_face, symbol, unref),
-		     (hb_destroy_func_t) _hb_ft_font_destroy);
+		     _hb_ft_font_destroy);
 }
 
 
 static hb_blob_t *
 reference_table  (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
 {
   FT_Face ft_face = (FT_Face) user_data;
   FT_Byte *buffer;
@@ -548,17 +550,17 @@ hb_ft_face_create (FT_Face           ft_
  *
  * Return value: (transfer full): 
  * Since: 0.9.38
  **/
 hb_face_t *
 hb_ft_face_create_referenced (FT_Face ft_face)
 {
   FT_Reference_Face (ft_face);
-  return hb_ft_face_create (ft_face, (hb_destroy_func_t) _hb_ft_face_destroy);
+  return hb_ft_face_create (ft_face, _hb_ft_face_destroy);
 }
 
 static void
 hb_ft_face_finalize (FT_Face ft_face)
 {
   hb_face_destroy ((hb_face_t *) ft_face->generic.data);
 }
 
@@ -603,16 +605,29 @@ hb_ft_font_create (FT_Face           ft_
 {
   hb_font_t *font;
   hb_face_t *face;
 
   face = hb_ft_face_create (ft_face, destroy);
   font = hb_font_create (face);
   hb_face_destroy (face);
   _hb_ft_font_set_funcs (font, ft_face, false);
+  hb_ft_font_changed (font);
+  return font;
+}
+
+void
+hb_ft_font_changed (hb_font_t *font)
+{
+  if (font->destroy != _hb_ft_font_destroy)
+    return;
+
+  hb_ft_font_t *ft_font = (hb_ft_font_t *) font->user_data;
+  FT_Face ft_face = ft_font->ft_face;
+
   hb_font_set_scale (font,
 		     (int) (((uint64_t) ft_face->size->metrics.x_scale * (uint64_t) ft_face->units_per_EM + (1u<<15)) >> 16),
 		     (int) (((uint64_t) ft_face->size->metrics.y_scale * (uint64_t) ft_face->units_per_EM + (1u<<15)) >> 16));
 #if 0 /* hb-ft works in no-hinting model */
   hb_font_set_ppem (font,
 		    ft_face->size->metrics.x_ppem,
 		    ft_face->size->metrics.y_ppem);
 #endif
@@ -633,34 +648,32 @@ hb_ft_font_create (FT_Face           ft_
 	hb_font_set_var_coords_normalized (font, coords, mm_var->num_axis);
       }
     }
     free (coords);
     free (ft_coords);
     free (mm_var);
   }
 #endif
-
-  return font;
 }
 
 /**
  * hb_ft_font_create_referenced:
  * @ft_face:
  *
  * 
  *
  * Return value: (transfer full): 
  * Since: 0.9.38
  **/
 hb_font_t *
 hb_ft_font_create_referenced (FT_Face ft_face)
 {
   FT_Reference_Face (ft_face);
-  return hb_ft_font_create (ft_face, (hb_destroy_func_t) _hb_ft_face_destroy);
+  return hb_ft_font_create (ft_face, _hb_ft_face_destroy);
 }
 
 
 /* Thread-safe, lock-free, FT_Library */
 
 static FT_Library ft_library;
 
 #ifdef HB_USE_ATEXIT
--- a/gfx/harfbuzz/src/hb-ft.h
+++ b/gfx/harfbuzz/src/hb-ft.h
@@ -111,16 +111,22 @@ HB_EXTERN FT_Face
 hb_ft_font_get_face (hb_font_t *font);
 
 HB_EXTERN void
 hb_ft_font_set_load_flags (hb_font_t *font, int load_flags);
 
 HB_EXTERN int
 hb_ft_font_get_load_flags (hb_font_t *font);
 
-/* Makes an hb_font_t use FreeType internally to implement font functions. */
+/* Call when size or variations settings on underlying FT_Face change. */
+HB_EXTERN void
+hb_ft_font_changed (hb_font_t *font);
+
+/* Makes an hb_font_t use FreeType internally to implement font functions.
+ * Note: this internally creates an FT_Face.  Use it when you create your
+ * hb_face_t using hb_face_create(). */
 HB_EXTERN void
 hb_ft_font_set_funcs (hb_font_t *font);
 
 
 HB_END_DECLS
 
 #endif /* HB_FT_H */
--- a/gfx/harfbuzz/src/hb-glib.cc
+++ b/gfx/harfbuzz/src/hb-glib.cc
@@ -378,25 +378,32 @@ hb_glib_get_unicode_funcs (void)
 #undef HB_UNICODE_FUNC_IMPLEMENT
     }
   };
 
   return const_cast<hb_unicode_funcs_t *> (&_hb_glib_unicode_funcs);
 }
 
 #if GLIB_CHECK_VERSION(2,31,10)
+
+static void
+_hb_g_bytes_unref (void *data)
+{
+  g_bytes_unref ((GBytes *) data);
+}
+
 /**
  * hb_glib_blob_create:
  *
  * Since: 0.9.38
  **/
 hb_blob_t *
 hb_glib_blob_create (GBytes *gbytes)
 {
   gsize size = 0;
   gconstpointer data = g_bytes_get_data (gbytes, &size);
   return hb_blob_create ((const char *) data,
 			 size,
 			 HB_MEMORY_MODE_READONLY,
 			 g_bytes_ref (gbytes),
-			 (hb_destroy_func_t) g_bytes_unref);
+			 _hb_g_bytes_unref);
 }
 #endif
--- a/gfx/harfbuzz/src/hb-graphite2.cc
+++ b/gfx/harfbuzz/src/hb-graphite2.cc
@@ -384,17 +384,17 @@ hb_bool_t
         pPos->x_advance = 0.;
 
       pPos->y_advance = gr_slot_advance_Y (is, grface, NULL) * yscale;
       curradvy += pPos->y_advance;
     }
   }
   else
   {
-    curradvx = gr_seg_advance_X(seg);
+    curradvx = gr_seg_advance_X(seg) * xscale;
     for (is = gr_seg_first_slot (seg); is; pPos++, info++, is = gr_slot_next_in_segment (is))
     {
       if (info->cluster != currclus)
       {
         pPos->x_advance = info->var1.i32 * xscale;
         curradvx -= pPos->x_advance;
         currclus = info->cluster;
       } else
--- a/gfx/harfbuzz/src/hb-open-file-private.hh
+++ b/gfx/harfbuzz/src/hb-open-file-private.hh
@@ -74,16 +74,34 @@ typedef struct OffsetTable
 
   inline unsigned int get_table_count (void) const
   { return numTables; }
   inline const TableRecord& get_table (unsigned int i) const
   {
     if (unlikely (i >= numTables)) return Null(TableRecord);
     return tables[i];
   }
+  inline unsigned int get_table_tags (unsigned int start_offset,
+				      unsigned int *table_count, /* IN/OUT */
+				      hb_tag_t     *table_tags /* OUT */) const
+  {
+    if (table_count)
+    {
+      if (start_offset >= numTables)
+        *table_count = 0;
+      else
+        *table_count = MIN (*table_count, numTables - start_offset);
+
+      const TableRecord *sub_tables = tables + start_offset;
+      unsigned int count = *table_count;
+      for (unsigned int i = 0; i < count; i++)
+	table_tags[i] = sub_tables[i].tag;
+    }
+    return numTables;
+  }
   inline bool find_table_index (hb_tag_t tag, unsigned int *table_index) const
   {
     Tag t;
     t.set (tag);
     unsigned int count = numTables;
     for (unsigned int i = 0; i < count; i++)
     {
       if (t == tables[i].tag)
--- a/gfx/harfbuzz/src/hb-ot-font.cc
+++ b/gfx/harfbuzz/src/hb-ot-font.cc
@@ -453,18 +453,20 @@ static hb_ot_font_t *
 			   ot_font->h_metrics.ascender - ot_font->h_metrics.descender); /* TODO Can we do this lazily? */
   ot_font->glyf.init (face);
   ot_font->cbdt.init (face);
 
   return ot_font;
 }
 
 static void
-_hb_ot_font_destroy (hb_ot_font_t *ot_font)
+_hb_ot_font_destroy (void *data)
 {
+  hb_ot_font_t *ot_font = (hb_ot_font_t *) data;
+
   ot_font->cmap.fini ();
   ot_font->h_metrics.fini ();
   ot_font->v_metrics.fini ();
   ot_font->glyf.fini ();
   ot_font->cbdt.fini ();
 
   free (ot_font);
 }
@@ -622,10 +624,10 @@ hb_ot_font_set_funcs (hb_font_t *font)
 {
   hb_ot_font_t *ot_font = _hb_ot_font_create (font->face);
   if (unlikely (!ot_font))
     return;
 
   hb_font_set_funcs (font,
 		     _hb_ot_get_font_funcs (),
 		     ot_font,
-		     (hb_destroy_func_t) _hb_ot_font_destroy);
+		     _hb_ot_font_destroy);
 }
--- a/gfx/harfbuzz/src/hb-ot-layout-gpos-table.hh
+++ b/gfx/harfbuzz/src/hb-ot-layout-gpos-table.hh
@@ -1082,17 +1082,19 @@ struct MarkBasePosFormat1
 
     /* Now we search backwards for a non-mark glyph */
     hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
     skippy_iter.reset (buffer->idx, 1);
     skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks);
     do {
       if (!skippy_iter.prev ()) return_trace (false);
       /* We only want to attach to the first of a MultipleSubst sequence.  Reject others. */
-      if (0 == _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx])) break;
+      if (!_hb_glyph_info_multiplied (&buffer->info[skippy_iter.idx]) ||
+	  0 == _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx]))
+	break;
       skippy_iter.reject ();
     } while (1);
 
     /* Checking that matched glyph is actually a base glyph by GDEF is too strong; disabled */
     //if (!_hb_glyph_info_is_base_glyph (&buffer->info[skippy_iter.idx])) { return_trace (false); }
 
     unsigned int base_index = (this+baseCoverage).get_coverage  (buffer->info[skippy_iter.idx].codepoint);
     if (base_index == NOT_COVERED) return_trace (false);
--- a/gfx/harfbuzz/src/hb-ot-layout-gsubgpos-private.hh
+++ b/gfx/harfbuzz/src/hb-ot-layout-gsubgpos-private.hh
@@ -369,16 +369,23 @@ struct hb_apply_context_t :
       idx = start_index_;
       num_items = num_items_;
       end = c->buffer->len;
       matcher.set_syllable (start_index_ == c->buffer->idx ? c->buffer->cur().syllable () : 0);
     }
 
     inline void reject (void) { num_items++; match_glyph_data--; }
 
+    inline matcher_t::may_skip_t
+    may_skip (const hb_apply_context_t *c,
+	      const hb_glyph_info_t    &info) const
+    {
+      return matcher.may_skip (c, info);
+    }
+
     inline bool next (void)
     {
       assert (num_items > 0);
       while (idx + num_items < end)
       {
 	idx++;
 	const hb_glyph_info_t &info = c->buffer->info[idx];
 
@@ -731,48 +738,90 @@ static inline bool match_input (hb_apply
    * - If all components of the ligature were marks, we call this a mark ligature.
    *
    * - If there is no GDEF, and the ligature is NOT a mark ligature, we categorize
    *   it as a ligature glyph.
    *
    * - Ligatures cannot be formed across glyphs attached to different components
    *   of previous ligatures.  Eg. the sequence is LAM,SHADDA,LAM,FATHA,HEH, and
    *   LAM,LAM,HEH form a ligature, leaving SHADDA,FATHA next to eachother.
-   *   However, it would be wrong to ligate that SHADDA,FATHA sequence.o
-   *   There is an exception to this: If a ligature tries ligating with marks that
-   *   belong to it itself, go ahead, assuming that the font designer knows what
-   *   they are doing (otherwise it can break Indic stuff when a matra wants to
-   *   ligate with a conjunct...)
+   *   However, it would be wrong to ligate that SHADDA,FATHA sequence.
+   *   There are a couple of exceptions to this:
+   *
+   *   o If a ligature tries ligating with marks that belong to it itself, go ahead,
+   *     assuming that the font designer knows what they are doing (otherwise it can
+   *     break Indic stuff when a matra wants to ligate with a conjunct,
+   *
+   *   o If two marks want to ligate and they belong to different components of the
+   *     same ligature glyph, and said ligature glyph is to be ignored according to
+   *     mark-filtering rules, then allow.
+   *     https://github.com/behdad/harfbuzz/issues/545
    */
 
   bool is_mark_ligature = _hb_glyph_info_is_mark (&buffer->cur());
 
   unsigned int total_component_count = 0;
   total_component_count += _hb_glyph_info_get_lig_num_comps (&buffer->cur());
 
   unsigned int first_lig_id = _hb_glyph_info_get_lig_id (&buffer->cur());
   unsigned int first_lig_comp = _hb_glyph_info_get_lig_comp (&buffer->cur());
 
+  enum {
+    LIGBASE_NOT_CHECKED,
+    LIGBASE_MAY_NOT_SKIP,
+    LIGBASE_MAY_SKIP
+  } ligbase = LIGBASE_NOT_CHECKED;
+
   match_positions[0] = buffer->idx;
   for (unsigned int i = 1; i < count; i++)
   {
     if (!skippy_iter.next ()) return_trace (false);
 
     match_positions[i] = skippy_iter.idx;
 
     unsigned int this_lig_id = _hb_glyph_info_get_lig_id (&buffer->info[skippy_iter.idx]);
     unsigned int this_lig_comp = _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx]);
 
-    if (first_lig_id && first_lig_comp) {
+    if (first_lig_id && first_lig_comp)
+    {
       /* If first component was attached to a previous ligature component,
        * all subsequent components should be attached to the same ligature
-       * component, otherwise we shouldn't ligate them. */
+       * component, otherwise we shouldn't ligate them... */
       if (first_lig_id != this_lig_id || first_lig_comp != this_lig_comp)
-	return_trace (false);
-    } else {
+      {
+        /* ...unless, we are attached to a base ligature and that base
+	 * ligature is ignorable. */
+        if (ligbase == LIGBASE_NOT_CHECKED)
+	{
+	  bool found = false;
+	  const hb_glyph_info_t *out = buffer->out_info;
+	  unsigned int j = buffer->out_len;
+	  while (j && _hb_glyph_info_get_lig_id (&out[j - 1]) == first_lig_id)
+	  {
+	    if (_hb_glyph_info_get_lig_comp (&out[j - 1]) == 0)
+	    {
+	      j--;
+	      found = true;
+	      break;
+	    }
+	    j--;
+	  }
+
+	  if (found && skippy_iter.may_skip (c, out[j]) == hb_apply_context_t::matcher_t::SKIP_YES)
+	    ligbase = LIGBASE_MAY_SKIP;
+	  else
+	    ligbase = LIGBASE_MAY_NOT_SKIP;
+	}
+
+        if (ligbase == LIGBASE_MAY_NOT_SKIP)
+	  return_trace (false);
+      }
+    }
+    else
+    {
       /* If first component was NOT attached to a previous ligature component,
        * all subsequent components should also NOT be attached to any ligature
        * component, unless they are attached to the first component itself! */
       if (this_lig_id && this_lig_comp && (this_lig_id != first_lig_id))
 	return_trace (false);
     }
 
     is_mark_ligature = is_mark_ligature && _hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx]);
--- a/gfx/harfbuzz/src/hb-ot-layout-private.hh
+++ b/gfx/harfbuzz/src/hb-ot-layout-private.hh
@@ -342,16 +342,18 @@ static inline void
   info->unicode_props() = (modified_class<<8) | (info->unicode_props() & 0xFF);
 }
 static inline unsigned int
 _hb_glyph_info_get_modified_combining_class (const hb_glyph_info_t *info)
 {
   return _hb_glyph_info_is_unicode_mark (info) ? info->unicode_props()>>8 : 0;
 }
 
+#define info_cc(info) (_hb_glyph_info_get_modified_combining_class (&(info)))
+
 static inline bool
 _hb_glyph_info_is_unicode_space (const hb_glyph_info_t *info)
 {
   return _hb_glyph_info_get_general_category (info) ==
 	 HB_UNICODE_GENERAL_CATEGORY_SPACE_SEPARATOR;
 }
 static inline void
 _hb_glyph_info_set_unicode_space_fallback_type (hb_glyph_info_t *info, hb_unicode_funcs_t::space_t s)
--- a/gfx/harfbuzz/src/hb-ot-shape-complex-arabic-table.hh
+++ b/gfx/harfbuzz/src/hb-ot-shape-complex-arabic-table.hh
@@ -1,20 +1,20 @@
 /* == Start of generated table == */
 /*
  * The following table is generated by running:
  *
  *   ./gen-arabic-table.py ArabicShaping.txt UnicodeData.txt Blocks.txt
  *
  * on files with these headers:
  *
- * # ArabicShaping-9.0.0.txt
- * # Date: 2016-02-24, 22:25:00 GMT [RP]
- * # Blocks-9.0.0.txt
- * # Date: 2016-02-05, 23:48:00 GMT [KW]
+ * # ArabicShaping-10.0.0.txt
+ * # Date: 2017-02-16, 00:00:00 GMT [RP, KW]
+ * # Blocks-10.0.0.txt
+ * # Date: 2017-04-12, 17:30:00 GMT [KW]
  * UnicodeData.txt does not have a header.
  */
 
 #ifndef HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH
 #define HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH
 
 
 #define X	JOINING_TYPE_X
@@ -67,17 +67,20 @@ static const uint8_t joining_table[] =
   /* FILLER */
 
   /* 0800 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
   /* 0820 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
 
   /* Mandaic */
 
   /* 0840 */ R,D,D,D,D,D,R,R,D,R,D,D,D,D,D,D,D,D,D,D,R,D,U,U,U,X,X,X,X,X,X,X,
-  /* 0860 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
+
+  /* Syriac Supplement */
+
+  /* 0860 */ D,U,D,D,D,D,U,R,D,R,R,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
   /* 0880 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
 
   /* Arabic Extended-A */
 
   /* 08A0 */ D,D,D,D,D,D,D,D,D,D,R,R,R,U,R,D,D,R,R,D,D,X,D,D,D,R,D,D,D,D,X,X,
   /* 08C0 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
   /* 08E0 */ X,X,U,
 
@@ -125,17 +128,17 @@ static const uint8_t joining_table[] =
 #define joining_offset_0x1e900u 1146
 
   /* Adlam */
 
   /* 1E900 */ D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,
   /* 1E920 */ D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,
   /* 1E940 */ D,D,D,D,
 
-}; /* Table items: 1214; occupancy: 54% */
+}; /* Table items: 1214; occupancy: 55% */
 
 
 static unsigned int
 joining_type (hb_codepoint_t u)
 {
   switch (u >> 12)
   {
     case 0x0u:
--- a/gfx/harfbuzz/src/hb-ot-shape-complex-arabic.cc
+++ b/gfx/harfbuzz/src/hb-ot-shape-complex-arabic.cc
@@ -608,25 +608,100 @@ postprocess_glyphs_arabic (const hb_ot_s
 			   hb_buffer_t              *buffer,
 			   hb_font_t                *font)
 {
   apply_stch (plan, buffer, font);
 
   HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action);
 }
 
+/* http://www.unicode.org/reports/tr53/tr53-1.pdf */
+
+static hb_codepoint_t
+modifier_combining_marks[] =
+{
+  0x0654u, /* ARABIC HAMZA ABOVE */
+  0x0655u, /* ARABIC HAMZA BELOW */
+  0x0658u, /* ARABIC MARK NOON GHUNNA */
+  0x06DCu, /* ARABIC SMALL HIGH SEEN */
+  0x06E3u, /* ARABIC SMALL LOW SEEN */
+  0x06E7u, /* ARABIC SMALL HIGH YEH */
+  0x06E8u, /* ARABIC SMALL HIGH NOON */
+  0x08F3u, /* ARABIC SMALL HIGH WAW */
+};
+
+static inline bool
+info_is_mcm (const hb_glyph_info_t &info)
+{
+  hb_codepoint_t u = info.codepoint;
+  for (unsigned int i = 0; i < ARRAY_LENGTH (modifier_combining_marks); i++)
+    if (u == modifier_combining_marks[i])
+      return true;
+  return false;
+}
+
+static void
+reorder_marks_arabic (const hb_ot_shape_plan_t *plan,
+		      hb_buffer_t              *buffer,
+		      unsigned int              start,
+		      unsigned int              end)
+{
+  hb_glyph_info_t *info = buffer->info;
+
+  unsigned int i = start;
+  for (unsigned int cc = 220; cc <= 230; cc += 10)
+  {
+    DEBUG_MSG (ARABIC, buffer, "Looking for %d's starting at %d\n", cc, i);
+    while (i < end && info_cc(info[i]) < cc)
+      i++;
+    DEBUG_MSG (ARABIC, buffer, "Looking for %d's stopped at %d\n", cc, i);
+
+    if (i == end)
+      break;
+
+    if (info_cc(info[i]) > cc)
+      continue;
+
+    /* Technically we should also check "info_cc(info[j]) == cc"
+     * in the following loop.  But not doing it is safe; we might
+     * end up moving all the 220 MCMs and 230 MCMs together in one
+     * move and be done. */
+    unsigned int j = i;
+    while (j < end && info_is_mcm (info[j]))
+      j++;
+    DEBUG_MSG (ARABIC, buffer, "Found %d's from %d to %d\n", cc, i, j);
+
+    if (i == j)
+      continue;
+
+    /* Shift it! */
+    DEBUG_MSG (ARABIC, buffer, "Shifting %d's: %d %d\n", cc, i, j);
+    hb_glyph_info_t temp[HB_OT_SHAPE_COMPLEX_MAX_COMBINING_MARKS];
+    assert (j - i <= ARRAY_LENGTH (temp));
+    buffer->merge_clusters (start, j);
+    memmove (temp, &info[i], (j - i) * sizeof (hb_glyph_info_t));
+    memmove (&info[start + j - i], &info[start], (i - start) * sizeof (hb_glyph_info_t));
+    memmove (&info[start], temp, (j - i) * sizeof (hb_glyph_info_t));
+
+    start += j - i;
+
+    i = j;
+  }
+}
+
 const hb_ot_complex_shaper_t _hb_ot_complex_shaper_arabic =
 {
   "arabic",
   collect_features_arabic,
   NULL, /* override_features */
   data_create_arabic,
   data_destroy_arabic,
   NULL, /* preprocess_text */
   postprocess_glyphs_arabic,
   HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT,
   NULL, /* decompose */
   NULL, /* compose */
   setup_masks_arabic,
   NULL, /* disable_otl */
+  reorder_marks_arabic,
   HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
   true, /* fallback_position */
 };
--- a/gfx/harfbuzz/src/hb-ot-shape-complex-default.cc
+++ b/gfx/harfbuzz/src/hb-ot-shape-complex-default.cc
@@ -36,11 +36,12 @@ const hb_ot_complex_shaper_t _hb_ot_comp
   NULL, /* data_destroy */
   NULL, /* preprocess_text */
   NULL, /* postprocess_glyphs */
   HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT,
   NULL, /* decompose */
   NULL, /* compose */
   NULL, /* setup_masks */
   NULL, /* disable_otl */
+  NULL, /* reorder_marks */
   HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
   true, /* fallback_position */
 };
--- a/gfx/harfbuzz/src/hb-ot-shape-complex-hangul.cc
+++ b/gfx/harfbuzz/src/hb-ot-shape-complex-hangul.cc
@@ -421,11 +421,12 @@ const hb_ot_complex_shaper_t _hb_ot_comp
   data_destroy_hangul,
   preprocess_text_hangul,
   NULL, /* postprocess_glyphs */
   HB_OT_SHAPE_NORMALIZATION_MODE_NONE,
   NULL, /* decompose */
   NULL, /* compose */
   setup_masks_hangul,
   NULL, /* disable_otl */
+  NULL, /* reorder_marks */
   HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
   false, /* fallback_position */
 };
--- a/gfx/harfbuzz/src/hb-ot-shape-complex-hebrew.cc
+++ b/gfx/harfbuzz/src/hb-ot-shape-complex-hebrew.cc
@@ -176,11 +176,12 @@ const hb_ot_complex_shaper_t _hb_ot_comp
   NULL, /* data_destroy */
   NULL, /* preprocess_text */
   NULL, /* postprocess_glyphs */
   HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT,
   NULL, /* decompose */
   compose_hebrew,
   NULL, /* setup_masks */
   disable_otl_hebrew,
+  NULL, /* reorder_marks */
   HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
   true, /* fallback_position */
 };
--- a/gfx/harfbuzz/src/hb-ot-shape-complex-indic-machine.hh
+++ b/gfx/harfbuzz/src/hb-ot-shape-complex-indic-machine.hh
@@ -51,17 +51,17 @@ static const unsigned char _indic_syllab
 	8u, 13u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 
 	5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 4u, 8u, 6u, 6u, 16u, 16u, 
 	4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 
 	16u, 16u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 
 	4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 5u, 8u, 4u, 14u, 4u, 14u, 5u, 8u, 
 	5u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 
 	5u, 7u, 7u, 7u, 8u, 8u, 1u, 16u, 8u, 13u, 4u, 8u, 6u, 6u, 16u, 16u, 
 	4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 
-	16u, 16u, 8u, 8u, 1u, 18u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 
+	16u, 16u, 8u, 8u, 1u, 19u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 
 	3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 
 	3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 5u, 14u, 5u, 14u, 
 	5u, 10u, 9u, 10u, 9u, 9u, 9u, 10u, 9u, 10u, 9u, 9u, 5u, 10u, 3u, 13u, 
 	3u, 10u, 5u, 10u, 3u, 10u, 3u, 13u, 3u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 
 	3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 
 	5u, 14u, 3u, 14u, 1u, 16u, 4u, 14u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 
 	1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 
 	1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 
@@ -96,17 +96,17 @@ static const unsigned char _indic_syllab
 	3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 
 	3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 
 	1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 1u, 17u, 3u, 17u, 
 	1u, 17u, 4u, 14u, 5u, 10u, 9u, 10u, 9u, 9u, 9u, 10u, 9u, 10u, 9u, 9u, 
 	5u, 10u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 3u, 17u, 3u, 17u, 1u, 16u, 
 	3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 
 	5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 13u, 3u, 10u, 5u, 10u, 3u, 10u, 
 	3u, 13u, 1u, 16u, 3u, 10u, 5u, 10u, 5u, 10u, 9u, 10u, 9u, 9u, 9u, 10u, 
-	9u, 10u, 9u, 9u, 5u, 10u, 0
+	9u, 10u, 9u, 9u, 5u, 10u, 1u, 16u, 0
 };
 
 static const char _indic_syllable_machine_key_spans[] = {
 	1, 16, 6, 4, 3, 1, 4, 3, 
 	1, 4, 3, 1, 4, 3, 1, 5, 
 	1, 1, 5, 1, 1, 5, 1, 1, 
 	5, 1, 1, 11, 11, 11, 11, 11, 
 	11, 11, 11, 11, 11, 1, 16, 6, 
@@ -122,17 +122,17 @@ static const char _indic_syllable_machin
 	6, 4, 3, 1, 4, 3, 1, 4, 
 	3, 1, 4, 3, 1, 5, 1, 1, 
 	5, 1, 1, 5, 1, 1, 5, 1, 
 	1, 11, 11, 11, 11, 11, 11, 11, 
 	11, 11, 11, 11, 4, 11, 11, 4, 
 	3, 4, 3, 1, 4, 3, 1, 4, 
 	3, 1, 1, 16, 6, 5, 1, 1, 
 	5, 1, 1, 5, 1, 1, 5, 1, 
-	1, 1, 18, 15, 15, 14, 16, 15, 
+	1, 1, 19, 15, 15, 14, 16, 15, 
 	15, 14, 16, 15, 15, 14, 16, 15, 
 	15, 14, 16, 15, 15, 14, 10, 10, 
 	6, 2, 1, 2, 2, 1, 6, 11, 
 	8, 6, 8, 11, 12, 12, 11, 10, 
 	12, 11, 10, 12, 11, 10, 12, 11, 
 	10, 12, 16, 11, 15, 15, 16, 16, 
 	16, 16, 16, 15, 15, 16, 16, 16, 
 	16, 16, 15, 15, 16, 16, 16, 16, 
@@ -167,17 +167,17 @@ static const char _indic_syllable_machin
 	15, 15, 16, 16, 16, 16, 16, 15, 
 	15, 16, 16, 16, 16, 16, 15, 15, 
 	16, 16, 16, 16, 16, 15, 17, 15, 
 	17, 11, 6, 2, 1, 2, 2, 1, 
 	6, 16, 15, 15, 14, 15, 15, 16, 
 	12, 11, 10, 12, 11, 10, 12, 11, 
 	10, 12, 11, 10, 11, 8, 6, 8, 
 	11, 16, 8, 6, 6, 2, 1, 2, 
-	2, 1, 6
+	2, 1, 6, 16
 };
 
 static const short _indic_syllable_machine_index_offsets[] = {
 	0, 2, 19, 26, 31, 35, 37, 42, 
 	46, 48, 53, 57, 59, 64, 68, 70, 
 	76, 78, 80, 86, 88, 90, 96, 98, 
 	100, 106, 108, 110, 122, 134, 146, 158, 
 	170, 182, 194, 206, 218, 230, 232, 249, 
@@ -193,62 +193,62 @@ static const short _indic_syllable_machi
 	697, 704, 709, 713, 715, 720, 724, 726, 
 	731, 735, 737, 742, 746, 748, 754, 756, 
 	758, 764, 766, 768, 774, 776, 778, 784, 
 	786, 788, 800, 812, 824, 836, 848, 860, 
 	872, 884, 896, 908, 920, 925, 937, 949, 
 	954, 958, 963, 967, 969, 974, 978, 980, 
 	985, 989, 991, 993, 1010, 1017, 1023, 1025, 
 	1027, 1033, 1035, 1037, 1043, 1045, 1047, 1053, 
-	1055, 1057, 1059, 1078, 1094, 1110, 1125, 1142, 
-	1158, 1174, 1189, 1206, 1222, 1238, 1253, 1270, 
-	1286, 1302, 1317, 1334, 1350, 1366, 1381, 1392, 
-	1403, 1410, 1413, 1415, 1418, 1421, 1423, 1430, 
-	1442, 1451, 1458, 1467, 1479, 1492, 1505, 1517, 
-	1528, 1541, 1553, 1564, 1577, 1589, 1600, 1613, 
-	1625, 1636, 1649, 1666, 1678, 1694, 1710, 1727, 
-	1744, 1761, 1778, 1795, 1811, 1827, 1844, 1861, 
-	1878, 1895, 1912, 1928, 1944, 1961, 1978, 1995, 
-	2012, 2029, 2045, 2061, 2078, 2095, 2112, 2129, 
-	2146, 2162, 2178, 2194, 2210, 2225, 2242, 2258, 
-	2274, 2289, 2306, 2322, 2338, 2353, 2370, 2386, 
-	2402, 2417, 2434, 2450, 2466, 2481, 2492, 2503, 
-	2510, 2513, 2515, 2518, 2521, 2523, 2530, 2542, 
-	2551, 2558, 2567, 2579, 2592, 2605, 2617, 2628, 
-	2641, 2653, 2664, 2677, 2689, 2700, 2713, 2725, 
-	2736, 2749, 2766, 2778, 2794, 2810, 2827, 2844, 
-	2861, 2878, 2895, 2911, 2927, 2944, 2961, 2978, 
-	2995, 3012, 3028, 3044, 3061, 3078, 3095, 3112, 
-	3129, 3145, 3161, 3178, 3195, 3212, 3229, 3241, 
-	3258, 3274, 3290, 3305, 3322, 3338, 3354, 3369, 
-	3386, 3402, 3418, 3433, 3450, 3466, 3482, 3497, 
-	3514, 3530, 3546, 3561, 3572, 3583, 3590, 3593, 
-	3595, 3598, 3601, 3603, 3610, 3622, 3631, 3638, 
-	3647, 3659, 3672, 3685, 3697, 3708, 3721, 3733, 
-	3744, 3757, 3769, 3780, 3793, 3805, 3816, 3829, 
-	3846, 3858, 3874, 3890, 3907, 3924, 3941, 3958, 
-	3975, 3991, 4007, 4024, 4041, 4058, 4075, 4092, 
-	4108, 4124, 4141, 4158, 4175, 4192, 4209, 4225, 
-	4241, 4258, 4275, 4292, 4309, 4326, 4338, 4354, 
-	4366, 4382, 4398, 4413, 4430, 4446, 4462, 4477, 
-	4494, 4510, 4526, 4541, 4558, 4574, 4590, 4605, 
-	4622, 4638, 4654, 4669, 4680, 4691, 4698, 4701, 
-	4703, 4706, 4709, 4711, 4718, 4730, 4739, 4746, 
-	4755, 4767, 4780, 4793, 4805, 4816, 4829, 4841, 
-	4852, 4865, 4877, 4888, 4901, 4913, 4924, 4937, 
-	4954, 4966, 4982, 4998, 5015, 5032, 5049, 5066, 
-	5083, 5099, 5115, 5132, 5149, 5166, 5183, 5200, 
-	5216, 5232, 5249, 5266, 5283, 5300, 5317, 5333, 
-	5349, 5366, 5383, 5400, 5417, 5434, 5450, 5468, 
-	5484, 5502, 5514, 5521, 5524, 5526, 5529, 5532, 
-	5534, 5541, 5558, 5574, 5590, 5605, 5621, 5637, 
-	5654, 5667, 5679, 5690, 5703, 5715, 5726, 5739, 
-	5751, 5762, 5775, 5787, 5798, 5810, 5819, 5826, 
-	5835, 5847, 5864, 5873, 5880, 5887, 5890, 5892, 
-	5895, 5898, 5900
+	1055, 1057, 1059, 1079, 1095, 1111, 1126, 1143, 
+	1159, 1175, 1190, 1207, 1223, 1239, 1254, 1271, 
+	1287, 1303, 1318, 1335, 1351, 1367, 1382, 1393, 
+	1404, 1411, 1414, 1416, 1419, 1422, 1424, 1431, 
+	1443, 1452, 1459, 1468, 1480, 1493, 1506, 1518, 
+	1529, 1542, 1554, 1565, 1578, 1590, 1601, 1614, 
+	1626, 1637, 1650, 1667, 1679, 1695, 1711, 1728, 
+	1745, 1762, 1779, 1796, 1812, 1828, 1845, 1862, 
+	1879, 1896, 1913, 1929, 1945, 1962, 1979, 1996, 
+	2013, 2030, 2046, 2062, 2079, 2096, 2113, 2130, 
+	2147, 2163, 2179, 2195, 2211, 2226, 2243, 2259, 
+	2275, 2290, 2307, 2323, 2339, 2354, 2371, 2387, 
+	2403, 2418, 2435, 2451, 2467, 2482, 2493, 2504, 
+	2511, 2514, 2516, 2519, 2522, 2524, 2531, 2543, 
+	2552, 2559, 2568, 2580, 2593, 2606, 2618, 2629, 
+	2642, 2654, 2665, 2678, 2690, 2701, 2714, 2726, 
+	2737, 2750, 2767, 2779, 2795, 2811, 2828, 2845, 
+	2862, 2879, 2896, 2912, 2928, 2945, 2962, 2979, 
+	2996, 3013, 3029, 3045, 3062, 3079, 3096, 3113, 
+	3130, 3146, 3162, 3179, 3196, 3213, 3230, 3242, 
+	3259, 3275, 3291, 3306, 3323, 3339, 3355, 3370, 
+	3387, 3403, 3419, 3434, 3451, 3467, 3483, 3498, 
+	3515, 3531, 3547, 3562, 3573, 3584, 3591, 3594, 
+	3596, 3599, 3602, 3604, 3611, 3623, 3632, 3639, 
+	3648, 3660, 3673, 3686, 3698, 3709, 3722, 3734, 
+	3745, 3758, 3770, 3781, 3794, 3806, 3817, 3830, 
+	3847, 3859, 3875, 3891, 3908, 3925, 3942, 3959, 
+	3976, 3992, 4008, 4025, 4042, 4059, 4076, 4093, 
+	4109, 4125, 4142, 4159, 4176, 4193, 4210, 4226, 
+	4242, 4259, 4276, 4293, 4310, 4327, 4339, 4355, 
+	4367, 4383, 4399, 4414, 4431, 4447, 4463, 4478, 
+	4495, 4511, 4527, 4542, 4559, 4575, 4591, 4606, 
+	4623, 4639, 4655, 4670, 4681, 4692, 4699, 4702, 
+	4704, 4707, 4710, 4712, 4719, 4731, 4740, 4747, 
+	4756, 4768, 4781, 4794, 4806, 4817, 4830, 4842, 
+	4853, 4866, 4878, 4889, 4902, 4914, 4925, 4938, 
+	4955, 4967, 4983, 4999, 5016, 5033, 5050, 5067, 
+	5084, 5100, 5116, 5133, 5150, 5167, 5184, 5201, 
+	5217, 5233, 5250, 5267, 5284, 5301, 5318, 5334, 
+	5350, 5367, 5384, 5401, 5418, 5435, 5451, 5469, 
+	5485, 5503, 5515, 5522, 5525, 5527, 5530, 5533, 
+	5535, 5542, 5559, 5575, 5591, 5606, 5622, 5638, 
+	5655, 5668, 5680, 5691, 5704, 5716, 5727, 5740, 
+	5752, 5763, 5776, 5788, 5799, 5811, 5820, 5827, 
+	5836, 5848, 5865, 5874, 5881, 5888, 5891, 5893, 
+	5896, 5899, 5901, 5908
 };
 
 static const short _indic_syllable_machine_indicies[] = {
 	1, 0, 2, 3, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 2, 0, 1, 0, 0, 0, 0, 
 	4, 0, 5, 5, 6, 1, 0, 7, 
 	7, 6, 0, 6, 0, 8, 8, 9, 
@@ -376,621 +376,623 @@ static const short _indic_syllable_machi
 	170, 0, 157, 0, 0, 0, 0, 172, 
 	0, 173, 0, 0, 0, 157, 0, 174, 
 	0, 175, 0, 176, 167, 167, 168, 157, 
 	0, 177, 0, 178, 0, 179, 164, 164, 
 	165, 157, 0, 180, 0, 181, 0, 182, 
 	161, 161, 162, 157, 0, 183, 0, 184, 
 	0, 186, 185, 188, 189, 190, 191, 192, 
 	193, 84, 79, 194, 195, 196, 196, 156, 
-	197, 198, 199, 200, 201, 187, 203, 204, 
-	205, 206, 6, 1, 207, 208, 202, 202, 
-	38, 209, 202, 202, 210, 202, 211, 204, 
-	212, 212, 6, 1, 207, 208, 202, 202, 
-	202, 209, 202, 202, 210, 202, 204, 212, 
-	212, 6, 1, 207, 208, 202, 202, 202, 
-	209, 202, 202, 210, 202, 213, 202, 202, 
-	202, 19, 214, 202, 1, 207, 208, 202, 
-	202, 202, 215, 202, 213, 202, 216, 217, 
-	218, 219, 6, 1, 207, 208, 202, 202, 
-	36, 220, 202, 202, 210, 202, 221, 217, 
-	222, 222, 6, 1, 207, 208, 202, 202, 
-	202, 220, 202, 202, 210, 202, 217, 222, 
-	222, 6, 1, 207, 208, 202, 202, 202, 
-	220, 202, 202, 210, 202, 223, 202, 202, 
-	202, 19, 224, 202, 1, 207, 208, 202, 
-	202, 202, 215, 202, 223, 202, 225, 226, 
-	227, 228, 6, 1, 207, 208, 202, 202, 
-	34, 229, 202, 202, 210, 202, 230, 226, 
-	231, 231, 6, 1, 207, 208, 202, 202, 
-	202, 229, 202, 202, 210, 202, 226, 231, 
-	231, 6, 1, 207, 208, 202, 202, 202, 
-	229, 202, 202, 210, 202, 232, 202, 202, 
-	202, 19, 233, 202, 1, 207, 208, 202, 
-	202, 202, 215, 202, 232, 202, 234, 235, 
-	236, 237, 6, 1, 207, 208, 202, 202, 
-	32, 238, 202, 202, 210, 202, 239, 235, 
-	240, 240, 6, 1, 207, 208, 202, 202, 
-	202, 238, 202, 202, 210, 202, 235, 240, 
-	240, 6, 1, 207, 208, 202, 202, 202, 
-	238, 202, 202, 210, 202, 241, 202, 202, 
-	202, 19, 242, 202, 1, 207, 208, 202, 
-	202, 202, 215, 202, 241, 202, 243, 244, 
-	245, 246, 6, 1, 207, 208, 202, 202, 
-	30, 247, 202, 202, 210, 202, 248, 244, 
-	249, 249, 6, 1, 207, 208, 202, 202, 
-	202, 247, 202, 202, 210, 202, 244, 249, 
-	249, 6, 1, 207, 208, 202, 202, 202, 
-	247, 202, 202, 210, 202, 19, 250, 202, 
-	1, 207, 208, 202, 202, 202, 215, 202, 
-	251, 251, 202, 1, 207, 208, 202, 202, 
-	202, 215, 202, 252, 202, 202, 253, 207, 
-	208, 202, 207, 208, 202, 254, 202, 207, 
-	255, 202, 207, 256, 202, 207, 202, 252, 
-	202, 202, 202, 207, 208, 202, 257, 202, 
-	258, 259, 202, 1, 207, 208, 202, 202, 
-	4, 202, 3, 202, 251, 251, 202, 1, 
-	207, 208, 202, 251, 251, 202, 1, 207, 
-	208, 202, 257, 202, 251, 251, 202, 1, 
-	207, 208, 202, 257, 202, 258, 251, 202, 
-	1, 207, 208, 202, 202, 4, 202, 19, 
-	202, 260, 260, 6, 1, 207, 208, 202, 
-	202, 202, 215, 202, 261, 28, 262, 263, 
-	9, 1, 207, 208, 202, 202, 202, 215, 
-	202, 28, 262, 263, 9, 1, 207, 208, 
-	202, 202, 202, 215, 202, 262, 262, 9, 
-	1, 207, 208, 202, 202, 202, 215, 202, 
-	264, 25, 265, 266, 12, 1, 207, 208, 
-	202, 202, 202, 215, 202, 25, 265, 266, 
-	12, 1, 207, 208, 202, 202, 202, 215, 
-	202, 265, 265, 12, 1, 207, 208, 202, 
-	202, 202, 215, 202, 267, 22, 268, 269, 
-	15, 1, 207, 208, 202, 202, 202, 215, 
-	202, 22, 268, 269, 15, 1, 207, 208, 
-	202, 202, 202, 215, 202, 268, 268, 15, 
-	1, 207, 208, 202, 202, 202, 215, 202, 
-	270, 19, 251, 271, 202, 1, 207, 208, 
-	202, 202, 202, 215, 202, 19, 251, 271, 
-	202, 1, 207, 208, 202, 202, 202, 215, 
-	202, 251, 272, 202, 1, 207, 208, 202, 
-	202, 202, 215, 202, 19, 202, 251, 251, 
-	202, 1, 207, 208, 202, 202, 202, 215, 
-	202, 2, 3, 202, 202, 19, 250, 202, 
-	1, 207, 208, 202, 202, 202, 215, 202, 
-	2, 202, 244, 249, 249, 6, 1, 207, 
-	208, 202, 202, 202, 247, 202, 243, 244, 
-	249, 249, 6, 1, 207, 208, 202, 202, 
-	202, 247, 202, 202, 210, 202, 243, 244, 
-	245, 249, 6, 1, 207, 208, 202, 202, 
-	30, 247, 202, 202, 210, 202, 241, 202, 
-	273, 202, 260, 260, 6, 1, 207, 208, 
-	202, 202, 202, 215, 202, 241, 202, 241, 
-	202, 202, 202, 251, 251, 202, 1, 207, 
-	208, 202, 202, 202, 215, 202, 241, 202, 
-	241, 202, 202, 202, 251, 274, 202, 1, 
-	207, 208, 202, 202, 202, 215, 202, 241, 
-	202, 241, 202, 273, 202, 251, 251, 202, 
-	1, 207, 208, 202, 202, 202, 215, 202, 
-	241, 202, 241, 3, 202, 202, 19, 242, 
-	202, 1, 207, 208, 202, 202, 202, 215, 
-	202, 241, 202, 234, 235, 240, 240, 6, 
-	1, 207, 208, 202, 202, 202, 238, 202, 
-	202, 210, 202, 234, 235, 236, 240, 6, 
-	1, 207, 208, 202, 202, 32, 238, 202, 
-	202, 210, 202, 232, 202, 275, 202, 260, 
-	260, 6, 1, 207, 208, 202, 202, 202, 
-	215, 202, 232, 202, 232, 202, 202, 202, 
-	251, 251, 202, 1, 207, 208, 202, 202, 
-	202, 215, 202, 232, 202, 232, 202, 202, 
-	202, 251, 276, 202, 1, 207, 208, 202, 
-	202, 202, 215, 202, 232, 202, 232, 202, 
-	275, 202, 251, 251, 202, 1, 207, 208, 
-	202, 202, 202, 215, 202, 232, 202, 232, 
-	3, 202, 202, 19, 233, 202, 1, 207, 
-	208, 202, 202, 202, 215, 202, 232, 202, 
-	225, 226, 231, 231, 6, 1, 207, 208, 
-	202, 202, 202, 229, 202, 202, 210, 202, 
-	225, 226, 227, 231, 6, 1, 207, 208, 
-	202, 202, 34, 229, 202, 202, 210, 202, 
-	223, 202, 277, 202, 260, 260, 6, 1, 
-	207, 208, 202, 202, 202, 215, 202, 223, 
-	202, 223, 202, 202, 202, 251, 251, 202, 
-	1, 207, 208, 202, 202, 202, 215, 202, 
-	223, 202, 223, 202, 202, 202, 251, 278, 
-	202, 1, 207, 208, 202, 202, 202, 215, 
-	202, 223, 202, 223, 202, 277, 202, 251, 
-	251, 202, 1, 207, 208, 202, 202, 202, 
-	215, 202, 223, 202, 223, 3, 202, 202, 
-	19, 224, 202, 1, 207, 208, 202, 202, 
-	202, 215, 202, 223, 202, 216, 217, 222, 
-	222, 6, 1, 207, 208, 202, 202, 202, 
-	220, 202, 202, 210, 202, 216, 217, 218, 
-	222, 6, 1, 207, 208, 202, 202, 36, 
-	220, 202, 202, 210, 202, 213, 202, 279, 
-	202, 260, 260, 6, 1, 207, 208, 202, 
-	202, 202, 215, 202, 213, 202, 213, 202, 
-	202, 202, 251, 251, 202, 1, 207, 208, 
-	202, 202, 202, 215, 202, 213, 202, 213, 
-	202, 202, 202, 251, 280, 202, 1, 207, 
-	208, 202, 202, 202, 215, 202, 213, 202, 
-	213, 202, 279, 202, 251, 251, 202, 1, 
-	207, 208, 202, 202, 202, 215, 202, 213, 
-	202, 213, 3, 202, 202, 19, 214, 202, 
-	1, 207, 208, 202, 202, 202, 215, 202, 
-	213, 202, 203, 204, 212, 212, 6, 1, 
-	207, 208, 202, 202, 202, 209, 202, 202, 
-	210, 202, 203, 204, 205, 212, 6, 1, 
-	207, 208, 202, 202, 38, 209, 202, 202, 
-	210, 202, 282, 283, 284, 285, 45, 40, 
-	286, 287, 281, 281, 77, 288, 281, 281, 
-	289, 281, 290, 283, 291, 285, 45, 40, 
-	286, 287, 281, 281, 281, 288, 281, 281, 
-	289, 281, 283, 291, 285, 45, 40, 286, 
-	287, 281, 281, 281, 288, 281, 281, 289, 
-	281, 292, 281, 281, 281, 58, 293, 281, 
-	40, 286, 287, 281, 281, 281, 294, 281, 
-	292, 281, 295, 296, 297, 298, 45, 40, 
-	286, 287, 281, 281, 75, 299, 281, 281, 
-	289, 281, 300, 296, 301, 301, 45, 40, 
-	286, 287, 281, 281, 281, 299, 281, 281, 
-	289, 281, 296, 301, 301, 45, 40, 286, 
-	287, 281, 281, 281, 299, 281, 281, 289, 
-	281, 302, 281, 281, 281, 58, 303, 281, 
-	40, 286, 287, 281, 281, 281, 294, 281, 
-	302, 281, 304, 305, 306, 307, 45, 40, 
-	286, 287, 281, 281, 73, 308, 281, 281, 
-	289, 281, 309, 305, 310, 310, 45, 40, 
-	286, 287, 281, 281, 281, 308, 281, 281, 
-	289, 281, 305, 310, 310, 45, 40, 286, 
-	287, 281, 281, 281, 308, 281, 281, 289, 
-	281, 311, 281, 281, 281, 58, 312, 281, 
-	40, 286, 287, 281, 281, 281, 294, 281, 
-	311, 281, 313, 314, 315, 316, 45, 40, 
-	286, 287, 281, 281, 71, 317, 281, 281, 
-	289, 281, 318, 314, 319, 319, 45, 40, 
-	286, 287, 281, 281, 281, 317, 281, 281, 
-	289, 281, 314, 319, 319, 45, 40, 286, 
-	287, 281, 281, 281, 317, 281, 281, 289, 
-	281, 320, 281, 281, 281, 58, 321, 281, 
-	40, 286, 287, 281, 281, 281, 294, 281, 
-	320, 281, 322, 323, 324, 325, 45, 40, 
-	286, 287, 281, 281, 69, 326, 281, 281, 
-	289, 281, 327, 323, 328, 328, 45, 40, 
-	286, 287, 281, 281, 281, 326, 281, 281, 
-	289, 281, 323, 328, 328, 45, 40, 286, 
-	287, 281, 281, 281, 326, 281, 281, 289, 
-	281, 58, 329, 281, 40, 286, 287, 281, 
-	281, 281, 294, 281, 330, 330, 281, 40, 
-	286, 287, 281, 281, 281, 294, 281, 331, 
-	281, 281, 332, 286, 287, 281, 286, 287, 
-	281, 333, 281, 286, 334, 281, 286, 335, 
-	281, 286, 281, 331, 281, 281, 281, 286, 
-	287, 281, 336, 281, 337, 338, 281, 40, 
-	286, 287, 281, 281, 43, 281, 42, 281, 
-	330, 330, 281, 40, 286, 287, 281, 330, 
-	330, 281, 40, 286, 287, 281, 336, 281, 
-	330, 330, 281, 40, 286, 287, 281, 336, 
-	281, 337, 330, 281, 40, 286, 287, 281, 
-	281, 43, 281, 58, 281, 339, 339, 45, 
-	40, 286, 287, 281, 281, 281, 294, 281, 
-	340, 67, 341, 342, 48, 40, 286, 287, 
-	281, 281, 281, 294, 281, 67, 341, 342, 
-	48, 40, 286, 287, 281, 281, 281, 294, 
-	281, 341, 341, 48, 40, 286, 287, 281, 
-	281, 281, 294, 281, 343, 64, 344, 345, 
-	51, 40, 286, 287, 281, 281, 281, 294, 
-	281, 64, 344, 345, 51, 40, 286, 287, 
-	281, 281, 281, 294, 281, 344, 344, 51, 
-	40, 286, 287, 281, 281, 281, 294, 281, 
-	346, 61, 347, 348, 54, 40, 286, 287, 
-	281, 281, 281, 294, 281, 61, 347, 348, 
-	54, 40, 286, 287, 281, 281, 281, 294, 
-	281, 347, 347, 54, 40, 286, 287, 281, 
-	281, 281, 294, 281, 349, 58, 330, 350, 
-	281, 40, 286, 287, 281, 281, 281, 294, 
-	281, 58, 330, 350, 281, 40, 286, 287, 
-	281, 281, 281, 294, 281, 330, 351, 281, 
-	40, 286, 287, 281, 281, 281, 294, 281, 
-	58, 281, 330, 330, 281, 40, 286, 287, 
-	281, 281, 281, 294, 281, 41, 42, 281, 
-	281, 58, 329, 281, 40, 286, 287, 281, 
-	281, 281, 294, 281, 41, 281, 323, 328, 
-	328, 45, 40, 286, 287, 281, 281, 281, 
-	326, 281, 322, 323, 328, 328, 45, 40, 
-	286, 287, 281, 281, 281, 326, 281, 281, 
-	289, 281, 322, 323, 324, 328, 45, 40, 
-	286, 287, 281, 281, 69, 326, 281, 281, 
-	289, 281, 320, 281, 352, 281, 339, 339, 
-	45, 40, 286, 287, 281, 281, 281, 294, 
-	281, 320, 281, 320, 281, 281, 281, 330, 
-	330, 281, 40, 286, 287, 281, 281, 281, 
-	294, 281, 320, 281, 320, 281, 281, 281, 
-	330, 353, 281, 40, 286, 287, 281, 281, 
-	281, 294, 281, 320, 281, 320, 281, 352, 
-	281, 330, 330, 281, 40, 286, 287, 281, 
-	281, 281, 294, 281, 320, 281, 320, 42, 
-	281, 281, 58, 321, 281, 40, 286, 287, 
-	281, 281, 281, 294, 281, 320, 281, 313, 
-	314, 319, 319, 45, 40, 286, 287, 281, 
-	281, 281, 317, 281, 281, 289, 281, 313, 
-	314, 315, 319, 45, 40, 286, 287, 281, 
-	281, 71, 317, 281, 281, 289, 281, 311, 
-	281, 354, 281, 339, 339, 45, 40, 286, 
-	287, 281, 281, 281, 294, 281, 311, 281, 
-	311, 281, 281, 281, 330, 330, 281, 40, 
-	286, 287, 281, 281, 281, 294, 281, 311, 
-	281, 311, 281, 281, 281, 330, 355, 281, 
-	40, 286, 287, 281, 281, 281, 294, 281, 
-	311, 281, 311, 281, 354, 281, 330, 330, 
-	281, 40, 286, 287, 281, 281, 281, 294, 
-	281, 311, 281, 311, 42, 281, 281, 58, 
-	312, 281, 40, 286, 287, 281, 281, 281, 
-	294, 281, 311, 281, 304, 305, 310, 310, 
-	45, 40, 286, 287, 281, 281, 281, 308, 
-	281, 281, 289, 281, 304, 305, 306, 310, 
-	45, 40, 286, 287, 281, 281, 73, 308, 
-	281, 281, 289, 281, 302, 281, 356, 281, 
-	339, 339, 45, 40, 286, 287, 281, 281, 
-	281, 294, 281, 302, 281, 302, 281, 281, 
-	281, 330, 330, 281, 40, 286, 287, 281, 
-	281, 281, 294, 281, 302, 281, 302, 281, 
-	281, 281, 330, 357, 281, 40, 286, 287, 
-	281, 281, 281, 294, 281, 302, 281, 302, 
-	281, 356, 281, 330, 330, 281, 40, 286, 
-	287, 281, 281, 281, 294, 281, 302, 281, 
-	302, 42, 281, 281, 58, 303, 281, 40, 
-	286, 287, 281, 281, 281, 294, 281, 302, 
-	281, 295, 296, 301, 301, 45, 40, 286, 
-	287, 281, 281, 281, 299, 281, 281, 289, 
-	281, 295, 296, 297, 301, 45, 40, 286, 
-	287, 281, 281, 75, 299, 281, 281, 289, 
-	281, 292, 281, 358, 281, 339, 339, 45, 
-	40, 286, 287, 281, 281, 281, 294, 281, 
-	292, 281, 292, 281, 281, 281, 330, 330, 
-	281, 40, 286, 287, 281, 281, 281, 294, 
-	281, 292, 281, 292, 281, 281, 281, 330, 
-	359, 281, 40, 286, 287, 281, 281, 281, 
-	294, 281, 292, 281, 292, 281, 358, 281, 
-	330, 330, 281, 40, 286, 287, 281, 281, 
-	281, 294, 281, 292, 281, 76, 44, 44, 
-	45, 40, 281, 281, 281, 281, 281, 76, 
-	281, 292, 42, 281, 281, 58, 293, 281, 
-	40, 286, 287, 281, 281, 281, 294, 281, 
-	292, 281, 282, 283, 291, 285, 45, 40, 
-	286, 287, 281, 281, 281, 288, 281, 281, 
-	289, 281, 361, 191, 362, 362, 84, 79, 
-	194, 195, 360, 360, 360, 197, 360, 360, 
-	200, 360, 191, 362, 362, 84, 79, 194, 
-	195, 360, 360, 360, 197, 360, 360, 200, 
-	360, 363, 360, 360, 360, 98, 364, 360, 
-	79, 194, 195, 360, 360, 360, 365, 360, 
-	363, 360, 366, 367, 368, 369, 84, 79, 
-	194, 195, 360, 360, 115, 370, 360, 360, 
-	200, 360, 371, 367, 372, 372, 84, 79, 
-	194, 195, 360, 360, 360, 370, 360, 360, 
-	200, 360, 367, 372, 372, 84, 79, 194, 
-	195, 360, 360, 360, 370, 360, 360, 200, 
-	360, 373, 360, 360, 360, 98, 374, 360, 
-	79, 194, 195, 360, 360, 360, 365, 360, 
-	373, 360, 375, 376, 377, 378, 84, 79, 
-	194, 195, 360, 360, 113, 379, 360, 360, 
-	200, 360, 380, 376, 381, 381, 84, 79, 
-	194, 195, 360, 360, 360, 379, 360, 360, 
-	200, 360, 376, 381, 381, 84, 79, 194, 
-	195, 360, 360, 360, 379, 360, 360, 200, 
-	360, 382, 360, 360, 360, 98, 383, 360, 
-	79, 194, 195, 360, 360, 360, 365, 360, 
-	382, 360, 384, 385, 386, 387, 84, 79, 
-	194, 195, 360, 360, 111, 388, 360, 360, 
-	200, 360, 389, 385, 390, 390, 84, 79, 
-	194, 195, 360, 360, 360, 388, 360, 360, 
-	200, 360, 385, 390, 390, 84, 79, 194, 
-	195, 360, 360, 360, 388, 360, 360, 200, 
-	360, 391, 360, 360, 360, 98, 392, 360, 
-	79, 194, 195, 360, 360, 360, 365, 360, 
-	391, 360, 393, 394, 395, 396, 84, 79, 
-	194, 195, 360, 360, 109, 397, 360, 360, 
-	200, 360, 398, 394, 399, 399, 84, 79, 
-	194, 195, 360, 360, 360, 397, 360, 360, 
-	200, 360, 394, 399, 399, 84, 79, 194, 
-	195, 360, 360, 360, 397, 360, 360, 200, 
-	360, 98, 400, 360, 79, 194, 195, 360, 
-	360, 360, 365, 360, 401, 401, 360, 79, 
-	194, 195, 360, 360, 360, 365, 360, 402, 
-	360, 360, 403, 194, 195, 360, 194, 195, 
-	360, 404, 360, 194, 405, 360, 194, 406, 
-	360, 194, 360, 402, 360, 360, 360, 194, 
-	195, 360, 407, 360, 408, 409, 360, 79, 
-	194, 195, 360, 360, 82, 360, 81, 360, 
-	401, 401, 360, 79, 194, 195, 360, 401, 
-	401, 360, 79, 194, 195, 360, 407, 360, 
-	401, 401, 360, 79, 194, 195, 360, 407, 
-	360, 408, 401, 360, 79, 194, 195, 360, 
-	360, 82, 360, 98, 360, 410, 410, 84, 
-	79, 194, 195, 360, 360, 360, 365, 360, 
-	411, 107, 412, 413, 88, 79, 194, 195, 
-	360, 360, 360, 365, 360, 107, 412, 413, 
-	88, 79, 194, 195, 360, 360, 360, 365, 
-	360, 412, 412, 88, 79, 194, 195, 360, 
-	360, 360, 365, 360, 414, 104, 415, 416, 
-	91, 79, 194, 195, 360, 360, 360, 365, 
-	360, 104, 415, 416, 91, 79, 194, 195, 
-	360, 360, 360, 365, 360, 415, 415, 91, 
-	79, 194, 195, 360, 360, 360, 365, 360, 
-	417, 101, 418, 419, 94, 79, 194, 195, 
-	360, 360, 360, 365, 360, 101, 418, 419, 
-	94, 79, 194, 195, 360, 360, 360, 365, 
-	360, 418, 418, 94, 79, 194, 195, 360, 
-	360, 360, 365, 360, 420, 98, 401, 421, 
-	360, 79, 194, 195, 360, 360, 360, 365, 
-	360, 98, 401, 421, 360, 79, 194, 195, 
-	360, 360, 360, 365, 360, 401, 422, 360, 
-	79, 194, 195, 360, 360, 360, 365, 360, 
-	98, 360, 401, 401, 360, 79, 194, 195, 
-	360, 360, 360, 365, 360, 80, 81, 360, 
-	360, 98, 400, 360, 79, 194, 195, 360, 
-	360, 360, 365, 360, 80, 360, 394, 399, 
-	399, 84, 79, 194, 195, 360, 360, 360, 
-	397, 360, 393, 394, 399, 399, 84, 79, 
-	194, 195, 360, 360, 360, 397, 360, 360, 
-	200, 360, 393, 394, 395, 399, 84, 79, 
-	194, 195, 360, 360, 109, 397, 360, 360, 
-	200, 360, 391, 360, 423, 360, 410, 410, 
-	84, 79, 194, 195, 360, 360, 360, 365, 
-	360, 391, 360, 391, 360, 360, 360, 401, 
-	401, 360, 79, 194, 195, 360, 360, 360, 
-	365, 360, 391, 360, 391, 360, 360, 360, 
-	401, 424, 360, 79, 194, 195, 360, 360, 
-	360, 365, 360, 391, 360, 391, 360, 423, 
-	360, 401, 401, 360, 79, 194, 195, 360, 
-	360, 360, 365, 360, 391, 360, 391, 81, 
-	360, 360, 98, 392, 360, 79, 194, 195, 
-	360, 360, 360, 365, 360, 391, 360, 384, 
-	385, 390, 390, 84, 79, 194, 195, 360, 
-	360, 360, 388, 360, 360, 200, 360, 384, 
-	385, 386, 390, 84, 79, 194, 195, 360, 
-	360, 111, 388, 360, 360, 200, 360, 382, 
-	360, 425, 360, 410, 410, 84, 79, 194, 
-	195, 360, 360, 360, 365, 360, 382, 360, 
-	382, 360, 360, 360, 401, 401, 360, 79, 
-	194, 195, 360, 360, 360, 365, 360, 382, 
-	360, 382, 360, 360, 360, 401, 426, 360, 
-	79, 194, 195, 360, 360, 360, 365, 360, 
-	382, 360, 382, 360, 425, 360, 401, 401, 
-	360, 79, 194, 195, 360, 360, 360, 365, 
-	360, 382, 360, 382, 81, 360, 360, 98, 
-	383, 360, 79, 194, 195, 360, 360, 360, 
-	365, 360, 382, 360, 375, 376, 381, 381, 
-	84, 79, 194, 195, 360, 360, 360, 379, 
-	360, 360, 200, 360, 375, 376, 377, 381, 
-	84, 79, 194, 195, 360, 360, 113, 379, 
-	360, 360, 200, 360, 373, 360, 427, 360, 
-	410, 410, 84, 79, 194, 195, 360, 360, 
-	360, 365, 360, 373, 360, 373, 360, 360, 
-	360, 401, 401, 360, 79, 194, 195, 360, 
-	360, 360, 365, 360, 373, 360, 373, 360, 
-	360, 360, 401, 428, 360, 79, 194, 195, 
-	360, 360, 360, 365, 360, 373, 360, 373, 
-	360, 427, 360, 401, 401, 360, 79, 194, 
-	195, 360, 360, 360, 365, 360, 373, 360, 
-	373, 81, 360, 360, 98, 374, 360, 79, 
-	194, 195, 360, 360, 360, 365, 360, 373, 
-	360, 366, 367, 372, 372, 84, 79, 194, 
-	195, 360, 360, 360, 370, 360, 360, 200, 
-	360, 366, 367, 368, 372, 84, 79, 194, 
-	195, 360, 360, 115, 370, 360, 360, 200, 
-	360, 363, 360, 429, 360, 410, 410, 84, 
-	79, 194, 195, 360, 360, 360, 365, 360, 
-	363, 360, 363, 360, 360, 360, 401, 401, 
-	360, 79, 194, 195, 360, 360, 360, 365, 
-	360, 363, 360, 363, 360, 360, 360, 401, 
-	430, 360, 79, 194, 195, 360, 360, 360, 
-	365, 360, 363, 360, 363, 360, 429, 360, 
-	401, 401, 360, 79, 194, 195, 360, 360, 
-	360, 365, 360, 363, 360, 363, 81, 360, 
-	360, 98, 364, 360, 79, 194, 195, 360, 
-	360, 360, 365, 360, 363, 360, 116, 83, 
-	83, 84, 79, 431, 431, 431, 431, 156, 
-	116, 431, 190, 191, 362, 362, 84, 79, 
-	194, 195, 360, 360, 360, 197, 360, 360, 
-	200, 360, 116, 83, 83, 84, 79, 431, 
-	431, 431, 431, 431, 116, 431, 433, 434, 
-	435, 436, 123, 118, 437, 438, 432, 432, 
-	155, 439, 432, 432, 440, 432, 441, 434, 
-	436, 436, 123, 118, 437, 438, 432, 432, 
-	432, 439, 432, 432, 440, 432, 434, 436, 
-	436, 123, 118, 437, 438, 432, 432, 432, 
-	439, 432, 432, 440, 432, 442, 432, 432, 
-	432, 136, 443, 432, 118, 437, 438, 432, 
-	432, 432, 444, 432, 442, 432, 445, 446, 
-	447, 448, 123, 118, 437, 438, 432, 432, 
-	153, 449, 432, 432, 440, 432, 450, 446, 
-	451, 451, 123, 118, 437, 438, 432, 432, 
-	432, 449, 432, 432, 440, 432, 446, 451, 
-	451, 123, 118, 437, 438, 432, 432, 432, 
-	449, 432, 432, 440, 432, 452, 432, 432, 
-	432, 136, 453, 432, 118, 437, 438, 432, 
-	432, 432, 444, 432, 452, 432, 454, 455, 
-	456, 457, 123, 118, 437, 438, 432, 432, 
-	151, 458, 432, 432, 440, 432, 459, 455, 
-	460, 460, 123, 118, 437, 438, 432, 432, 
-	432, 458, 432, 432, 440, 432, 455, 460, 
-	460, 123, 118, 437, 438, 432, 432, 432, 
-	458, 432, 432, 440, 432, 461, 432, 432, 
-	432, 136, 462, 432, 118, 437, 438, 432, 
-	432, 432, 444, 432, 461, 432, 463, 464, 
-	465, 466, 123, 118, 437, 438, 432, 432, 
-	149, 467, 432, 432, 440, 432, 468, 464, 
-	469, 469, 123, 118, 437, 438, 432, 432, 
-	432, 467, 432, 432, 440, 432, 464, 469, 
-	469, 123, 118, 437, 438, 432, 432, 432, 
-	467, 432, 432, 440, 432, 470, 432, 432, 
-	432, 136, 471, 432, 118, 437, 438, 432, 
-	432, 432, 444, 432, 470, 432, 472, 473, 
-	474, 475, 123, 118, 437, 438, 432, 432, 
-	147, 476, 432, 432, 440, 432, 477, 473, 
-	478, 478, 123, 118, 437, 438, 432, 432, 
-	432, 476, 432, 432, 440, 432, 473, 478, 
-	478, 123, 118, 437, 438, 432, 432, 432, 
-	476, 432, 432, 440, 432, 136, 479, 432, 
-	118, 437, 438, 432, 432, 432, 444, 432, 
-	480, 480, 432, 118, 437, 438, 432, 432, 
-	432, 444, 432, 481, 432, 432, 482, 437, 
-	438, 432, 437, 438, 432, 483, 432, 437, 
-	484, 432, 437, 485, 432, 437, 432, 481, 
-	432, 432, 432, 437, 438, 432, 486, 432, 
-	487, 488, 432, 118, 437, 438, 432, 432, 
-	121, 432, 120, 432, 480, 480, 432, 118, 
-	437, 438, 432, 480, 480, 432, 118, 437, 
-	438, 432, 486, 432, 480, 480, 432, 118, 
-	437, 438, 432, 486, 432, 487, 480, 432, 
-	118, 437, 438, 432, 432, 121, 432, 136, 
-	432, 489, 489, 123, 118, 437, 438, 432, 
-	432, 432, 444, 432, 490, 145, 491, 492, 
-	126, 118, 437, 438, 432, 432, 432, 444, 
-	432, 145, 491, 492, 126, 118, 437, 438, 
-	432, 432, 432, 444, 432, 491, 491, 126, 
-	118, 437, 438, 432, 432, 432, 444, 432, 
-	493, 142, 494, 495, 129, 118, 437, 438, 
-	432, 432, 432, 444, 432, 142, 494, 495, 
-	129, 118, 437, 438, 432, 432, 432, 444, 
-	432, 494, 494, 129, 118, 437, 438, 432, 
-	432, 432, 444, 432, 496, 139, 497, 498, 
-	132, 118, 437, 438, 432, 432, 432, 444, 
-	432, 139, 497, 498, 132, 118, 437, 438, 
-	432, 432, 432, 444, 432, 497, 497, 132, 
-	118, 437, 438, 432, 432, 432, 444, 432, 
-	499, 136, 480, 500, 432, 118, 437, 438, 
-	432, 432, 432, 444, 432, 136, 480, 500, 
-	432, 118, 437, 438, 432, 432, 432, 444, 
-	432, 480, 501, 432, 118, 437, 438, 432, 
-	432, 432, 444, 432, 136, 432, 480, 480, 
-	432, 118, 437, 438, 432, 432, 432, 444, 
-	432, 119, 120, 432, 432, 136, 479, 432, 
-	118, 437, 438, 432, 432, 432, 444, 432, 
-	119, 432, 473, 478, 478, 123, 118, 437, 
-	438, 432, 432, 432, 476, 432, 472, 473, 
-	478, 478, 123, 118, 437, 438, 432, 432, 
-	432, 476, 432, 432, 440, 432, 472, 473, 
-	474, 478, 123, 118, 437, 438, 432, 432, 
-	147, 476, 432, 432, 440, 432, 470, 432, 
-	502, 432, 489, 489, 123, 118, 437, 438, 
-	432, 432, 432, 444, 432, 470, 432, 470, 
-	432, 432, 432, 480, 480, 432, 118, 437, 
-	438, 432, 432, 432, 444, 432, 470, 432, 
-	470, 432, 432, 432, 480, 503, 432, 118, 
-	437, 438, 432, 432, 432, 444, 432, 470, 
-	432, 470, 432, 502, 432, 480, 480, 432, 
-	118, 437, 438, 432, 432, 432, 444, 432, 
-	470, 432, 470, 120, 432, 432, 136, 471, 
-	432, 118, 437, 438, 432, 432, 432, 444, 
-	432, 470, 432, 463, 464, 469, 469, 123, 
-	118, 437, 438, 432, 432, 432, 467, 432, 
-	432, 440, 432, 463, 464, 465, 469, 123, 
-	118, 437, 438, 432, 432, 149, 467, 432, 
-	432, 440, 432, 461, 432, 504, 432, 489, 
-	489, 123, 118, 437, 438, 432, 432, 432, 
-	444, 432, 461, 432, 461, 432, 432, 432, 
-	480, 480, 432, 118, 437, 438, 432, 432, 
-	432, 444, 432, 461, 432, 461, 432, 432, 
-	432, 480, 505, 432, 118, 437, 438, 432, 
-	432, 432, 444, 432, 461, 432, 461, 432, 
-	504, 432, 480, 480, 432, 118, 437, 438, 
-	432, 432, 432, 444, 432, 461, 432, 461, 
-	120, 432, 432, 136, 462, 432, 118, 437, 
-	438, 432, 432, 432, 444, 432, 461, 432, 
-	454, 455, 460, 460, 123, 118, 437, 438, 
-	432, 432, 432, 458, 432, 432, 440, 432, 
-	454, 455, 456, 460, 123, 118, 437, 438, 
-	432, 432, 151, 458, 432, 432, 440, 432, 
-	452, 432, 506, 432, 489, 489, 123, 118, 
-	437, 438, 432, 432, 432, 444, 432, 452, 
-	432, 452, 432, 432, 432, 480, 480, 432, 
-	118, 437, 438, 432, 432, 432, 444, 432, 
-	452, 432, 452, 432, 432, 432, 480, 507, 
-	432, 118, 437, 438, 432, 432, 432, 444, 
-	432, 452, 432, 452, 432, 506, 432, 480, 
-	480, 432, 118, 437, 438, 432, 432, 432, 
-	444, 432, 452, 432, 452, 120, 432, 432, 
-	136, 453, 432, 118, 437, 438, 432, 432, 
-	432, 444, 432, 452, 432, 445, 446, 451, 
-	451, 123, 118, 437, 438, 432, 432, 432, 
-	449, 432, 432, 440, 432, 445, 446, 447, 
-	451, 123, 118, 437, 438, 432, 432, 153, 
-	449, 432, 432, 440, 432, 442, 432, 508, 
-	432, 489, 489, 123, 118, 437, 438, 432, 
-	432, 432, 444, 432, 442, 432, 442, 432, 
-	432, 432, 480, 480, 432, 118, 437, 438, 
-	432, 432, 432, 444, 432, 442, 432, 442, 
-	432, 432, 432, 480, 509, 432, 118, 437, 
-	438, 432, 432, 432, 444, 432, 442, 432, 
-	442, 432, 508, 432, 480, 480, 432, 118, 
-	437, 438, 432, 432, 432, 444, 432, 442, 
-	432, 442, 120, 432, 432, 136, 443, 432, 
-	118, 437, 438, 432, 432, 432, 444, 432, 
-	442, 432, 433, 434, 436, 436, 123, 118, 
-	437, 438, 432, 432, 432, 439, 432, 432, 
-	440, 432, 188, 189, 190, 191, 510, 362, 
-	84, 79, 194, 195, 196, 196, 156, 197, 
-	360, 188, 200, 360, 203, 511, 205, 206, 
-	6, 1, 207, 208, 202, 202, 38, 209, 
-	202, 202, 210, 202, 213, 189, 190, 191, 
-	512, 513, 84, 157, 514, 515, 202, 196, 
-	156, 516, 202, 213, 200, 202, 116, 517, 
-	517, 84, 157, 207, 208, 202, 202, 156, 
-	518, 202, 519, 202, 202, 520, 514, 515, 
-	202, 514, 515, 202, 254, 202, 514, 521, 
-	202, 514, 522, 202, 514, 202, 519, 202, 
-	202, 202, 514, 515, 202, 523, 3, 360, 
-	360, 401, 430, 360, 79, 194, 195, 360, 
-	360, 360, 365, 360, 523, 360, 524, 367, 
-	525, 526, 84, 157, 514, 515, 202, 202, 
-	158, 370, 202, 202, 200, 202, 527, 367, 
-	528, 528, 84, 157, 514, 515, 202, 202, 
-	202, 370, 202, 202, 200, 202, 367, 528, 
-	528, 84, 157, 514, 515, 202, 202, 202, 
-	370, 202, 202, 200, 202, 524, 367, 528, 
-	528, 84, 157, 514, 515, 202, 202, 202, 
-	370, 202, 202, 200, 202, 524, 367, 525, 
-	528, 84, 157, 514, 515, 202, 202, 158, 
-	370, 202, 202, 200, 202, 213, 202, 279, 
-	116, 529, 529, 160, 157, 207, 208, 202, 
-	202, 202, 518, 202, 213, 202, 530, 184, 
-	531, 532, 162, 157, 514, 515, 202, 202, 
-	202, 533, 202, 184, 531, 532, 162, 157, 
-	514, 515, 202, 202, 202, 533, 202, 531, 
-	531, 162, 157, 514, 515, 202, 202, 202, 
-	533, 202, 534, 181, 535, 536, 165, 157, 
-	514, 515, 202, 202, 202, 533, 202, 181, 
-	535, 536, 165, 157, 514, 515, 202, 202, 
-	202, 533, 202, 535, 535, 165, 157, 514, 
-	515, 202, 202, 202, 533, 202, 537, 178, 
-	538, 539, 168, 157, 514, 515, 202, 202, 
-	202, 533, 202, 178, 538, 539, 168, 157, 
-	514, 515, 202, 202, 202, 533, 202, 538, 
-	538, 168, 157, 514, 515, 202, 202, 202, 
-	533, 202, 540, 175, 541, 542, 202, 157, 
-	514, 515, 202, 202, 202, 533, 202, 175, 
-	541, 542, 202, 157, 514, 515, 202, 202, 
-	202, 533, 202, 541, 541, 202, 157, 514, 
-	515, 202, 202, 202, 533, 202, 543, 202, 
-	544, 545, 202, 157, 514, 515, 202, 202, 
-	172, 202, 171, 202, 541, 541, 202, 157, 
-	514, 515, 202, 541, 541, 202, 157, 514, 
-	515, 202, 543, 202, 541, 541, 202, 157, 
-	514, 515, 202, 543, 202, 544, 541, 202, 
-	157, 514, 515, 202, 202, 172, 202, 523, 
-	171, 360, 360, 98, 364, 360, 79, 194, 
-	195, 360, 360, 360, 365, 360, 523, 360, 
-	547, 546, 548, 548, 546, 186, 549, 550, 
-	546, 548, 548, 546, 186, 549, 550, 546, 
-	551, 546, 546, 552, 549, 550, 546, 549, 
-	550, 546, 553, 546, 549, 554, 546, 549, 
-	555, 546, 549, 546, 551, 546, 546, 546, 
-	549, 550, 546, 0
+	197, 198, 199, 200, 201, 202, 187, 204, 
+	205, 206, 207, 6, 1, 208, 209, 203, 
+	203, 38, 210, 203, 203, 211, 203, 212, 
+	205, 213, 213, 6, 1, 208, 209, 203, 
+	203, 203, 210, 203, 203, 211, 203, 205, 
+	213, 213, 6, 1, 208, 209, 203, 203, 
+	203, 210, 203, 203, 211, 203, 214, 203, 
+	203, 203, 19, 215, 203, 1, 208, 209, 
+	203, 203, 203, 216, 203, 214, 203, 217, 
+	218, 219, 220, 6, 1, 208, 209, 203, 
+	203, 36, 221, 203, 203, 211, 203, 222, 
+	218, 223, 223, 6, 1, 208, 209, 203, 
+	203, 203, 221, 203, 203, 211, 203, 218, 
+	223, 223, 6, 1, 208, 209, 203, 203, 
+	203, 221, 203, 203, 211, 203, 224, 203, 
+	203, 203, 19, 225, 203, 1, 208, 209, 
+	203, 203, 203, 216, 203, 224, 203, 226, 
+	227, 228, 229, 6, 1, 208, 209, 203, 
+	203, 34, 230, 203, 203, 211, 203, 231, 
+	227, 232, 232, 6, 1, 208, 209, 203, 
+	203, 203, 230, 203, 203, 211, 203, 227, 
+	232, 232, 6, 1, 208, 209, 203, 203, 
+	203, 230, 203, 203, 211, 203, 233, 203, 
+	203, 203, 19, 234, 203, 1, 208, 209, 
+	203, 203, 203, 216, 203, 233, 203, 235, 
+	236, 237, 238, 6, 1, 208, 209, 203, 
+	203, 32, 239, 203, 203, 211, 203, 240, 
+	236, 241, 241, 6, 1, 208, 209, 203, 
+	203, 203, 239, 203, 203, 211, 203, 236, 
+	241, 241, 6, 1, 208, 209, 203, 203, 
+	203, 239, 203, 203, 211, 203, 242, 203, 
+	203, 203, 19, 243, 203, 1, 208, 209, 
+	203, 203, 203, 216, 203, 242, 203, 244, 
+	245, 246, 247, 6, 1, 208, 209, 203, 
+	203, 30, 248, 203, 203, 211, 203, 249, 
+	245, 250, 250, 6, 1, 208, 209, 203, 
+	203, 203, 248, 203, 203, 211, 203, 245, 
+	250, 250, 6, 1, 208, 209, 203, 203, 
+	203, 248, 203, 203, 211, 203, 19, 251, 
+	203, 1, 208, 209, 203, 203, 203, 216, 
+	203, 252, 252, 203, 1, 208, 209, 203, 
+	203, 203, 216, 203, 253, 203, 203, 254, 
+	208, 209, 203, 208, 209, 203, 255, 203, 
+	208, 256, 203, 208, 257, 203, 208, 203, 
+	253, 203, 203, 203, 208, 209, 203, 258, 
+	203, 259, 260, 203, 1, 208, 209, 203, 
+	203, 4, 203, 3, 203, 252, 252, 203, 
+	1, 208, 209, 203, 252, 252, 203, 1, 
+	208, 209, 203, 258, 203, 252, 252, 203, 
+	1, 208, 209, 203, 258, 203, 259, 252, 
+	203, 1, 208, 209, 203, 203, 4, 203, 
+	19, 203, 261, 261, 6, 1, 208, 209, 
+	203, 203, 203, 216, 203, 262, 28, 263, 
+	264, 9, 1, 208, 209, 203, 203, 203, 
+	216, 203, 28, 263, 264, 9, 1, 208, 
+	209, 203, 203, 203, 216, 203, 263, 263, 
+	9, 1, 208, 209, 203, 203, 203, 216, 
+	203, 265, 25, 266, 267, 12, 1, 208, 
+	209, 203, 203, 203, 216, 203, 25, 266, 
+	267, 12, 1, 208, 209, 203, 203, 203, 
+	216, 203, 266, 266, 12, 1, 208, 209, 
+	203, 203, 203, 216, 203, 268, 22, 269, 
+	270, 15, 1, 208, 209, 203, 203, 203, 
+	216, 203, 22, 269, 270, 15, 1, 208, 
+	209, 203, 203, 203, 216, 203, 269, 269, 
+	15, 1, 208, 209, 203, 203, 203, 216, 
+	203, 271, 19, 252, 272, 203, 1, 208, 
+	209, 203, 203, 203, 216, 203, 19, 252, 
+	272, 203, 1, 208, 209, 203, 203, 203, 
+	216, 203, 252, 273, 203, 1, 208, 209, 
+	203, 203, 203, 216, 203, 19, 203, 252, 
+	252, 203, 1, 208, 209, 203, 203, 203, 
+	216, 203, 2, 3, 203, 203, 19, 251, 
+	203, 1, 208, 209, 203, 203, 203, 216, 
+	203, 2, 203, 245, 250, 250, 6, 1, 
+	208, 209, 203, 203, 203, 248, 203, 244, 
+	245, 250, 250, 6, 1, 208, 209, 203, 
+	203, 203, 248, 203, 203, 211, 203, 244, 
+	245, 246, 250, 6, 1, 208, 209, 203, 
+	203, 30, 248, 203, 203, 211, 203, 242, 
+	203, 274, 203, 261, 261, 6, 1, 208, 
+	209, 203, 203, 203, 216, 203, 242, 203, 
+	242, 203, 203, 203, 252, 252, 203, 1, 
+	208, 209, 203, 203, 203, 216, 203, 242, 
+	203, 242, 203, 203, 203, 252, 275, 203, 
+	1, 208, 209, 203, 203, 203, 216, 203, 
+	242, 203, 242, 203, 274, 203, 252, 252, 
+	203, 1, 208, 209, 203, 203, 203, 216, 
+	203, 242, 203, 242, 3, 203, 203, 19, 
+	243, 203, 1, 208, 209, 203, 203, 203, 
+	216, 203, 242, 203, 235, 236, 241, 241, 
+	6, 1, 208, 209, 203, 203, 203, 239, 
+	203, 203, 211, 203, 235, 236, 237, 241, 
+	6, 1, 208, 209, 203, 203, 32, 239, 
+	203, 203, 211, 203, 233, 203, 276, 203, 
+	261, 261, 6, 1, 208, 209, 203, 203, 
+	203, 216, 203, 233, 203, 233, 203, 203, 
+	203, 252, 252, 203, 1, 208, 209, 203, 
+	203, 203, 216, 203, 233, 203, 233, 203, 
+	203, 203, 252, 277, 203, 1, 208, 209, 
+	203, 203, 203, 216, 203, 233, 203, 233, 
+	203, 276, 203, 252, 252, 203, 1, 208, 
+	209, 203, 203, 203, 216, 203, 233, 203, 
+	233, 3, 203, 203, 19, 234, 203, 1, 
+	208, 209, 203, 203, 203, 216, 203, 233, 
+	203, 226, 227, 232, 232, 6, 1, 208, 
+	209, 203, 203, 203, 230, 203, 203, 211, 
+	203, 226, 227, 228, 232, 6, 1, 208, 
+	209, 203, 203, 34, 230, 203, 203, 211, 
+	203, 224, 203, 278, 203, 261, 261, 6, 
+	1, 208, 209, 203, 203, 203, 216, 203, 
+	224, 203, 224, 203, 203, 203, 252, 252, 
+	203, 1, 208, 209, 203, 203, 203, 216, 
+	203, 224, 203, 224, 203, 203, 203, 252, 
+	279, 203, 1, 208, 209, 203, 203, 203, 
+	216, 203, 224, 203, 224, 203, 278, 203, 
+	252, 252, 203, 1, 208, 209, 203, 203, 
+	203, 216, 203, 224, 203, 224, 3, 203, 
+	203, 19, 225, 203, 1, 208, 209, 203, 
+	203, 203, 216, 203, 224, 203, 217, 218, 
+	223, 223, 6, 1, 208, 209, 203, 203, 
+	203, 221, 203, 203, 211, 203, 217, 218, 
+	219, 223, 6, 1, 208, 209, 203, 203, 
+	36, 221, 203, 203, 211, 203, 214, 203, 
+	280, 203, 261, 261, 6, 1, 208, 209, 
+	203, 203, 203, 216, 203, 214, 203, 214, 
+	203, 203, 203, 252, 252, 203, 1, 208, 
+	209, 203, 203, 203, 216, 203, 214, 203, 
+	214, 203, 203, 203, 252, 281, 203, 1, 
+	208, 209, 203, 203, 203, 216, 203, 214, 
+	203, 214, 203, 280, 203, 252, 252, 203, 
+	1, 208, 209, 203, 203, 203, 216, 203, 
+	214, 203, 214, 3, 203, 203, 19, 215, 
+	203, 1, 208, 209, 203, 203, 203, 216, 
+	203, 214, 203, 204, 205, 213, 213, 6, 
+	1, 208, 209, 203, 203, 203, 210, 203, 
+	203, 211, 203, 204, 205, 206, 213, 6, 
+	1, 208, 209, 203, 203, 38, 210, 203, 
+	203, 211, 203, 283, 284, 285, 286, 45, 
+	40, 287, 288, 282, 282, 77, 289, 282, 
+	282, 290, 282, 291, 284, 292, 286, 45, 
+	40, 287, 288, 282, 282, 282, 289, 282, 
+	282, 290, 282, 284, 292, 286, 45, 40, 
+	287, 288, 282, 282, 282, 289, 282, 282, 
+	290, 282, 293, 282, 282, 282, 58, 294, 
+	282, 40, 287, 288, 282, 282, 282, 295, 
+	282, 293, 282, 296, 297, 298, 299, 45, 
+	40, 287, 288, 282, 282, 75, 300, 282, 
+	282, 290, 282, 301, 297, 302, 302, 45, 
+	40, 287, 288, 282, 282, 282, 300, 282, 
+	282, 290, 282, 297, 302, 302, 45, 40, 
+	287, 288, 282, 282, 282, 300, 282, 282, 
+	290, 282, 303, 282, 282, 282, 58, 304, 
+	282, 40, 287, 288, 282, 282, 282, 295, 
+	282, 303, 282, 305, 306, 307, 308, 45, 
+	40, 287, 288, 282, 282, 73, 309, 282, 
+	282, 290, 282, 310, 306, 311, 311, 45, 
+	40, 287, 288, 282, 282, 282, 309, 282, 
+	282, 290, 282, 306, 311, 311, 45, 40, 
+	287, 288, 282, 282, 282, 309, 282, 282, 
+	290, 282, 312, 282, 282, 282, 58, 313, 
+	282, 40, 287, 288, 282, 282, 282, 295, 
+	282, 312, 282, 314, 315, 316, 317, 45, 
+	40, 287, 288, 282, 282, 71, 318, 282, 
+	282, 290, 282, 319, 315, 320, 320, 45, 
+	40, 287, 288, 282, 282, 282, 318, 282, 
+	282, 290, 282, 315, 320, 320, 45, 40, 
+	287, 288, 282, 282, 282, 318, 282, 282, 
+	290, 282, 321, 282, 282, 282, 58, 322, 
+	282, 40, 287, 288, 282, 282, 282, 295, 
+	282, 321, 282, 323, 324, 325, 326, 45, 
+	40, 287, 288, 282, 282, 69, 327, 282, 
+	282, 290, 282, 328, 324, 329, 329, 45, 
+	40, 287, 288, 282, 282, 282, 327, 282, 
+	282, 290, 282, 324, 329, 329, 45, 40, 
+	287, 288, 282, 282, 282, 327, 282, 282, 
+	290, 282, 58, 330, 282, 40, 287, 288, 
+	282, 282, 282, 295, 282, 331, 331, 282, 
+	40, 287, 288, 282, 282, 282, 295, 282, 
+	332, 282, 282, 333, 287, 288, 282, 287, 
+	288, 282, 334, 282, 287, 335, 282, 287, 
+	336, 282, 287, 282, 332, 282, 282, 282, 
+	287, 288, 282, 337, 282, 338, 339, 282, 
+	40, 287, 288, 282, 282, 43, 282, 42, 
+	282, 331, 331, 282, 40, 287, 288, 282, 
+	331, 331, 282, 40, 287, 288, 282, 337, 
+	282, 331, 331, 282, 40, 287, 288, 282, 
+	337, 282, 338, 331, 282, 40, 287, 288, 
+	282, 282, 43, 282, 58, 282, 340, 340, 
+	45, 40, 287, 288, 282, 282, 282, 295, 
+	282, 341, 67, 342, 343, 48, 40, 287, 
+	288, 282, 282, 282, 295, 282, 67, 342, 
+	343, 48, 40, 287, 288, 282, 282, 282, 
+	295, 282, 342, 342, 48, 40, 287, 288, 
+	282, 282, 282, 295, 282, 344, 64, 345, 
+	346, 51, 40, 287, 288, 282, 282, 282, 
+	295, 282, 64, 345, 346, 51, 40, 287, 
+	288, 282, 282, 282, 295, 282, 345, 345, 
+	51, 40, 287, 288, 282, 282, 282, 295, 
+	282, 347, 61, 348, 349, 54, 40, 287, 
+	288, 282, 282, 282, 295, 282, 61, 348, 
+	349, 54, 40, 287, 288, 282, 282, 282, 
+	295, 282, 348, 348, 54, 40, 287, 288, 
+	282, 282, 282, 295, 282, 350, 58, 331, 
+	351, 282, 40, 287, 288, 282, 282, 282, 
+	295, 282, 58, 331, 351, 282, 40, 287, 
+	288, 282, 282, 282, 295, 282, 331, 352, 
+	282, 40, 287, 288, 282, 282, 282, 295, 
+	282, 58, 282, 331, 331, 282, 40, 287, 
+	288, 282, 282, 282, 295, 282, 41, 42, 
+	282, 282, 58, 330, 282, 40, 287, 288, 
+	282, 282, 282, 295, 282, 41, 282, 324, 
+	329, 329, 45, 40, 287, 288, 282, 282, 
+	282, 327, 282, 323, 324, 329, 329, 45, 
+	40, 287, 288, 282, 282, 282, 327, 282, 
+	282, 290, 282, 323, 324, 325, 329, 45, 
+	40, 287, 288, 282, 282, 69, 327, 282, 
+	282, 290, 282, 321, 282, 353, 282, 340, 
+	340, 45, 40, 287, 288, 282, 282, 282, 
+	295, 282, 321, 282, 321, 282, 282, 282, 
+	331, 331, 282, 40, 287, 288, 282, 282, 
+	282, 295, 282, 321, 282, 321, 282, 282, 
+	282, 331, 354, 282, 40, 287, 288, 282, 
+	282, 282, 295, 282, 321, 282, 321, 282, 
+	353, 282, 331, 331, 282, 40, 287, 288, 
+	282, 282, 282, 295, 282, 321, 282, 321, 
+	42, 282, 282, 58, 322, 282, 40, 287, 
+	288, 282, 282, 282, 295, 282, 321, 282, 
+	314, 315, 320, 320, 45, 40, 287, 288, 
+	282, 282, 282, 318, 282, 282, 290, 282, 
+	314, 315, 316, 320, 45, 40, 287, 288, 
+	282, 282, 71, 318, 282, 282, 290, 282, 
+	312, 282, 355, 282, 340, 340, 45, 40, 
+	287, 288, 282, 282, 282, 295, 282, 312, 
+	282, 312, 282, 282, 282, 331, 331, 282, 
+	40, 287, 288, 282, 282, 282, 295, 282, 
+	312, 282, 312, 282, 282, 282, 331, 356, 
+	282, 40, 287, 288, 282, 282, 282, 295, 
+	282, 312, 282, 312, 282, 355, 282, 331, 
+	331, 282, 40, 287, 288, 282, 282, 282, 
+	295, 282, 312, 282, 312, 42, 282, 282, 
+	58, 313, 282, 40, 287, 288, 282, 282, 
+	282, 295, 282, 312, 282, 305, 306, 311, 
+	311, 45, 40, 287, 288, 282, 282, 282, 
+	309, 282, 282, 290, 282, 305, 306, 307, 
+	311, 45, 40, 287, 288, 282, 282, 73, 
+	309, 282, 282, 290, 282, 303, 282, 357, 
+	282, 340, 340, 45, 40, 287, 288, 282, 
+	282, 282, 295, 282, 303, 282, 303, 282, 
+	282, 282, 331, 331, 282, 40, 287, 288, 
+	282, 282, 282, 295, 282, 303, 282, 303, 
+	282, 282, 282, 331, 358, 282, 40, 287, 
+	288, 282, 282, 282, 295, 282, 303, 282, 
+	303, 282, 357, 282, 331, 331, 282, 40, 
+	287, 288, 282, 282, 282, 295, 282, 303, 
+	282, 303, 42, 282, 282, 58, 304, 282, 
+	40, 287, 288, 282, 282, 282, 295, 282, 
+	303, 282, 296, 297, 302, 302, 45, 40, 
+	287, 288, 282, 282, 282, 300, 282, 282, 
+	290, 282, 296, 297, 298, 302, 45, 40, 
+	287, 288, 282, 282, 75, 300, 282, 282, 
+	290, 282, 293, 282, 359, 282, 340, 340, 
+	45, 40, 287, 288, 282, 282, 282, 295, 
+	282, 293, 282, 293, 282, 282, 282, 331, 
+	331, 282, 40, 287, 288, 282, 282, 282, 
+	295, 282, 293, 282, 293, 282, 282, 282, 
+	331, 360, 282, 40, 287, 288, 282, 282, 
+	282, 295, 282, 293, 282, 293, 282, 359, 
+	282, 331, 331, 282, 40, 287, 288, 282, 
+	282, 282, 295, 282, 293, 282, 76, 44, 
+	44, 45, 40, 282, 282, 282, 282, 282, 
+	76, 282, 293, 42, 282, 282, 58, 294, 
+	282, 40, 287, 288, 282, 282, 282, 295, 
+	282, 293, 282, 283, 284, 292, 286, 45, 
+	40, 287, 288, 282, 282, 282, 289, 282, 
+	282, 290, 282, 362, 191, 363, 363, 84, 
+	79, 194, 195, 361, 361, 361, 197, 361, 
+	361, 200, 361, 191, 363, 363, 84, 79, 
+	194, 195, 361, 361, 361, 197, 361, 361, 
+	200, 361, 364, 361, 361, 361, 98, 365, 
+	361, 79, 194, 195, 361, 361, 361, 366, 
+	361, 364, 361, 367, 368, 369, 370, 84, 
+	79, 194, 195, 361, 361, 115, 371, 361, 
+	361, 200, 361, 372, 368, 373, 373, 84, 
+	79, 194, 195, 361, 361, 361, 371, 361, 
+	361, 200, 361, 368, 373, 373, 84, 79, 
+	194, 195, 361, 361, 361, 371, 361, 361, 
+	200, 361, 374, 361, 361, 361, 98, 375, 
+	361, 79, 194, 195, 361, 361, 361, 366, 
+	361, 374, 361, 376, 377, 378, 379, 84, 
+	79, 194, 195, 361, 361, 113, 380, 361, 
+	361, 200, 361, 381, 377, 382, 382, 84, 
+	79, 194, 195, 361, 361, 361, 380, 361, 
+	361, 200, 361, 377, 382, 382, 84, 79, 
+	194, 195, 361, 361, 361, 380, 361, 361, 
+	200, 361, 383, 361, 361, 361, 98, 384, 
+	361, 79, 194, 195, 361, 361, 361, 366, 
+	361, 383, 361, 385, 386, 387, 388, 84, 
+	79, 194, 195, 361, 361, 111, 389, 361, 
+	361, 200, 361, 390, 386, 391, 391, 84, 
+	79, 194, 195, 361, 361, 361, 389, 361, 
+	361, 200, 361, 386, 391, 391, 84, 79, 
+	194, 195, 361, 361, 361, 389, 361, 361, 
+	200, 361, 392, 361, 361, 361, 98, 393, 
+	361, 79, 194, 195, 361, 361, 361, 366, 
+	361, 392, 361, 394, 395, 396, 397, 84, 
+	79, 194, 195, 361, 361, 109, 398, 361, 
+	361, 200, 361, 399, 395, 400, 400, 84, 
+	79, 194, 195, 361, 361, 361, 398, 361, 
+	361, 200, 361, 395, 400, 400, 84, 79, 
+	194, 195, 361, 361, 361, 398, 361, 361, 
+	200, 361, 98, 401, 361, 79, 194, 195, 
+	361, 361, 361, 366, 361, 402, 402, 361, 
+	79, 194, 195, 361, 361, 361, 366, 361, 
+	403, 361, 361, 404, 194, 195, 361, 194, 
+	195, 361, 405, 361, 194, 406, 361, 194, 
+	407, 361, 194, 361, 403, 361, 361, 361, 
+	194, 195, 361, 408, 361, 409, 410, 361, 
+	79, 194, 195, 361, 361, 82, 361, 81, 
+	361, 402, 402, 361, 79, 194, 195, 361, 
+	402, 402, 361, 79, 194, 195, 361, 408, 
+	361, 402, 402, 361, 79, 194, 195, 361, 
+	408, 361, 409, 402, 361, 79, 194, 195, 
+	361, 361, 82, 361, 98, 361, 411, 411, 
+	84, 79, 194, 195, 361, 361, 361, 366, 
+	361, 412, 107, 413, 414, 88, 79, 194, 
+	195, 361, 361, 361, 366, 361, 107, 413, 
+	414, 88, 79, 194, 195, 361, 361, 361, 
+	366, 361, 413, 413, 88, 79, 194, 195, 
+	361, 361, 361, 366, 361, 415, 104, 416, 
+	417, 91, 79, 194, 195, 361, 361, 361, 
+	366, 361, 104, 416, 417, 91, 79, 194, 
+	195, 361, 361, 361, 366, 361, 416, 416, 
+	91, 79, 194, 195, 361, 361, 361, 366, 
+	361, 418, 101, 419, 420, 94, 79, 194, 
+	195, 361, 361, 361, 366, 361, 101, 419, 
+	420, 94, 79, 194, 195, 361, 361, 361, 
+	366, 361, 419, 419, 94, 79, 194, 195, 
+	361, 361, 361, 366, 361, 421, 98, 402, 
+	422, 361, 79, 194, 195, 361, 361, 361, 
+	366, 361, 98, 402, 422, 361, 79, 194, 
+	195, 361, 361, 361, 366, 361, 402, 423, 
+	361, 79, 194, 195, 361, 361, 361, 366, 
+	361, 98, 361, 402, 402, 361, 79, 194, 
+	195, 361, 361, 361, 366, 361, 80, 81, 
+	361, 361, 98, 401, 361, 79, 194, 195, 
+	361, 361, 361, 366, 361, 80, 361, 395, 
+	400, 400, 84, 79, 194, 195, 361, 361, 
+	361, 398, 361, 394, 395, 400, 400, 84, 
+	79, 194, 195, 361, 361, 361, 398, 361, 
+	361, 200, 361, 394, 395, 396, 400, 84, 
+	79, 194, 195, 361, 361, 109, 398, 361, 
+	361, 200, 361, 392, 361, 424, 361, 411, 
+	411, 84, 79, 194, 195, 361, 361, 361, 
+	366, 361, 392, 361, 392, 361, 361, 361, 
+	402, 402, 361, 79, 194, 195, 361, 361, 
+	361, 366, 361, 392, 361, 392, 361, 361, 
+	361, 402, 425, 361, 79, 194, 195, 361, 
+	361, 361, 366, 361, 392, 361, 392, 361, 
+	424, 361, 402, 402, 361, 79, 194, 195, 
+	361, 361, 361, 366, 361, 392, 361, 392, 
+	81, 361, 361, 98, 393, 361, 79, 194, 
+	195, 361, 361, 361, 366, 361, 392, 361, 
+	385, 386, 391, 391, 84, 79, 194, 195, 
+	361, 361, 361, 389, 361, 361, 200, 361, 
+	385, 386, 387, 391, 84, 79, 194, 195, 
+	361, 361, 111, 389, 361, 361, 200, 361, 
+	383, 361, 426, 361, 411, 411, 84, 79, 
+	194, 195, 361, 361, 361, 366, 361, 383, 
+	361, 383, 361, 361, 361, 402, 402, 361, 
+	79, 194, 195, 361, 361, 361, 366, 361, 
+	383, 361, 383, 361, 361, 361, 402, 427, 
+	361, 79, 194, 195, 361, 361, 361, 366, 
+	361, 383, 361, 383, 361, 426, 361, 402, 
+	402, 361, 79, 194, 195, 361, 361, 361, 
+	366, 361, 383, 361, 383, 81, 361, 361, 
+	98, 384, 361, 79, 194, 195, 361, 361, 
+	361, 366, 361, 383, 361, 376, 377, 382, 
+	382, 84, 79, 194, 195, 361, 361, 361, 
+	380, 361, 361, 200, 361, 376, 377, 378, 
+	382, 84, 79, 194, 195, 361, 361, 113, 
+	380, 361, 361, 200, 361, 374, 361, 428, 
+	361, 411, 411, 84, 79, 194, 195, 361, 
+	361, 361, 366, 361, 374, 361, 374, 361, 
+	361, 361, 402, 402, 361, 79, 194, 195, 
+	361, 361, 361, 366, 361, 374, 361, 374, 
+	361, 361, 361, 402, 429, 361, 79, 194, 
+	195, 361, 361, 361, 366, 361, 374, 361, 
+	374, 361, 428, 361, 402, 402, 361, 79, 
+	194, 195, 361, 361, 361, 366, 361, 374, 
+	361, 374, 81, 361, 361, 98, 375, 361, 
+	79, 194, 195, 361, 361, 361, 366, 361, 
+	374, 361, 367, 368, 373, 373, 84, 79, 
+	194, 195, 361, 361, 361, 371, 361, 361, 
+	200, 361, 367, 368, 369, 373, 84, 79, 
+	194, 195, 361, 361, 115, 371, 361, 361, 
+	200, 361, 364, 361, 430, 361, 411, 411, 
+	84, 79, 194, 195, 361, 361, 361, 366, 
+	361, 364, 361, 364, 361, 361, 361, 402, 
+	402, 361, 79, 194, 195, 361, 361, 361, 
+	366, 361, 364, 361, 364, 361, 361, 361, 
+	402, 431, 361, 79, 194, 195, 361, 361, 
+	361, 366, 361, 364, 361, 364, 361, 430, 
+	361, 402, 402, 361, 79, 194, 195, 361, 
+	361, 361, 366, 361, 364, 361, 364, 81, 
+	361, 361, 98, 365, 361, 79, 194, 195, 
+	361, 361, 361, 366, 361, 364, 361, 116, 
+	83, 83, 84, 79, 432, 432, 432, 432, 
+	156, 116, 432, 190, 191, 363, 363, 84, 
+	79, 194, 195, 361, 361, 361, 197, 361, 
+	361, 200, 361, 116, 83, 83, 84, 79, 
+	432, 432, 432, 432, 432, 116, 432, 434, 
+	435, 436, 437, 123, 118, 438, 439, 433, 
+	433, 155, 440, 433, 433, 441, 433, 442, 
+	435, 437, 437, 123, 118, 438, 439, 433, 
+	433, 433, 440, 433, 433, 441, 433, 435, 
+	437, 437, 123, 118, 438, 439, 433, 433, 
+	433, 440, 433, 433, 441, 433, 443, 433, 
+	433, 433, 136, 444, 433, 118, 438, 439, 
+	433, 433, 433, 445, 433, 443, 433, 446, 
+	447, 448, 449, 123, 118, 438, 439, 433, 
+	433, 153, 450, 433, 433, 441, 433, 451, 
+	447, 452, 452, 123, 118, 438, 439, 433, 
+	433, 433, 450, 433, 433, 441, 433, 447, 
+	452, 452, 123, 118, 438, 439, 433, 433, 
+	433, 450, 433, 433, 441, 433, 453, 433, 
+	433, 433, 136, 454, 433, 118, 438, 439, 
+	433, 433, 433, 445, 433, 453, 433, 455, 
+	456, 457, 458, 123, 118, 438, 439, 433, 
+	433, 151, 459, 433, 433, 441, 433, 460, 
+	456, 461, 461, 123, 118, 438, 439, 433, 
+	433, 433, 459, 433, 433, 441, 433, 456, 
+	461, 461, 123, 118, 438, 439, 433, 433, 
+	433, 459, 433, 433, 441, 433, 462, 433, 
+	433, 433, 136, 463, 433, 118, 438, 439, 
+	433, 433, 433, 445, 433, 462, 433, 464, 
+	465, 466, 467, 123, 118, 438, 439, 433, 
+	433, 149, 468, 433, 433, 441, 433, 469, 
+	465, 470, 470, 123, 118, 438, 439, 433, 
+	433, 433, 468, 433, 433, 441, 433, 465, 
+	470, 470, 123, 118, 438, 439, 433, 433, 
+	433, 468, 433, 433, 441, 433, 471, 433, 
+	433, 433, 136, 472, 433, 118, 438, 439, 
+	433, 433, 433, 445, 433, 471, 433, 473, 
+	474, 475, 476, 123, 118, 438, 439, 433, 
+	433, 147, 477, 433, 433, 441, 433, 478, 
+	474, 479, 479, 123, 118, 438, 439, 433, 
+	433, 433, 477, 433, 433, 441, 433, 474, 
+	479, 479, 123, 118, 438, 439, 433, 433, 
+	433, 477, 433, 433, 441, 433, 136, 480, 
+	433, 118, 438, 439, 433, 433, 433, 445, 
+	433, 481, 481, 433, 118, 438, 439, 433, 
+	433, 433, 445, 433, 482, 433, 433, 483, 
+	438, 439, 433, 438, 439, 433, 484, 433, 
+	438, 485, 433, 438, 486, 433, 438, 433, 
+	482, 433, 433, 433, 438, 439, 433, 487, 
+	433, 488, 489, 433, 118, 438, 439, 433, 
+	433, 121, 433, 120, 433, 481, 481, 433, 
+	118, 438, 439, 433, 481, 481, 433, 118, 
+	438, 439, 433, 487, 433, 481, 481, 433, 
+	118, 438, 439, 433, 487, 433, 488, 481, 
+	433, 118, 438, 439, 433, 433, 121, 433, 
+	136, 433, 490, 490, 123, 118, 438, 439, 
+	433, 433, 433, 445, 433, 491, 145, 492, 
+	493, 126, 118, 438, 439, 433, 433, 433, 
+	445, 433, 145, 492, 493, 126, 118, 438, 
+	439, 433, 433, 433, 445, 433, 492, 492, 
+	126, 118, 438, 439, 433, 433, 433, 445, 
+	433, 494, 142, 495, 496, 129, 118, 438, 
+	439, 433, 433, 433, 445, 433, 142, 495, 
+	496, 129, 118, 438, 439, 433, 433, 433, 
+	445, 433, 495, 495, 129, 118, 438, 439, 
+	433, 433, 433, 445, 433, 497, 139, 498, 
+	499, 132, 118, 438, 439, 433, 433, 433, 
+	445, 433, 139, 498, 499, 132, 118, 438, 
+	439, 433, 433, 433, 445, 433, 498, 498, 
+	132, 118, 438, 439, 433, 433, 433, 445, 
+	433, 500, 136, 481, 501, 433, 118, 438, 
+	439, 433, 433, 433, 445, 433, 136, 481, 
+	501, 433, 118, 438, 439, 433, 433, 433, 
+	445, 433, 481, 502, 433, 118, 438, 439, 
+	433, 433, 433, 445, 433, 136, 433, 481, 
+	481, 433, 118, 438, 439, 433, 433, 433, 
+	445, 433, 119, 120, 433, 433, 136, 480, 
+	433, 118, 438, 439, 433, 433, 433, 445, 
+	433, 119, 433, 474, 479, 479, 123, 118, 
+	438, 439, 433, 433, 433, 477, 433, 473, 
+	474, 479, 479, 123, 118, 438, 439, 433, 
+	433, 433, 477, 433, 433, 441, 433, 473, 
+	474, 475, 479, 123, 118, 438, 439, 433, 
+	433, 147, 477, 433, 433, 441, 433, 471, 
+	433, 503, 433, 490, 490, 123, 118, 438, 
+	439, 433, 433, 433, 445, 433, 471, 433, 
+	471, 433, 433, 433, 481, 481, 433, 118, 
+	438, 439, 433, 433, 433, 445, 433, 471, 
+	433, 471, 433, 433, 433, 481, 504, 433, 
+	118, 438, 439, 433, 433, 433, 445, 433, 
+	471, 433, 471, 433, 503, 433, 481, 481, 
+	433, 118, 438, 439, 433, 433, 433, 445, 
+	433, 471, 433, 471, 120, 433, 433, 136, 
+	472, 433, 118, 438, 439, 433, 433, 433, 
+	445, 433, 471, 433, 464, 465, 470, 470, 
+	123, 118, 438, 439, 433, 433, 433, 468, 
+	433, 433, 441, 433, 464, 465, 466, 470, 
+	123, 118, 438, 439, 433, 433, 149, 468, 
+	433, 433, 441, 433, 462, 433, 505, 433, 
+	490, 490, 123, 118, 438, 439, 433, 433, 
+	433, 445, 433, 462, 433, 462, 433, 433, 
+	433, 481, 481, 433, 118, 438, 439, 433, 
+	433, 433, 445, 433, 462, 433, 462, 433, 
+	433, 433, 481, 506, 433, 118, 438, 439, 
+	433, 433, 433, 445, 433, 462, 433, 462, 
+	433, 505, 433, 481, 481, 433, 118, 438, 
+	439, 433, 433, 433, 445, 433, 462, 433, 
+	462, 120, 433, 433, 136, 463, 433, 118, 
+	438, 439, 433, 433, 433, 445, 433, 462, 
+	433, 455, 456, 461, 461, 123, 118, 438, 
+	439, 433, 433, 433, 459, 433, 433, 441, 
+	433, 455, 456, 457, 461, 123, 118, 438, 
+	439, 433, 433, 151, 459, 433, 433, 441, 
+	433, 453, 433, 507, 433, 490, 490, 123, 
+	118, 438, 439, 433, 433, 433, 445, 433, 
+	453, 433, 453, 433, 433, 433, 481, 481, 
+	433, 118, 438, 439, 433, 433, 433, 445, 
+	433, 453, 433, 453, 433, 433, 433, 481, 
+	508, 433, 118, 438, 439, 433, 433, 433, 
+	445, 433, 453, 433, 453, 433, 507, 433, 
+	481, 481, 433, 118, 438, 439, 433, 433, 
+	433, 445, 433, 453, 433, 453, 120, 433, 
+	433, 136, 454, 433, 118, 438, 439, 433, 
+	433, 433, 445, 433, 453, 433, 446, 447, 
+	452, 452, 123, 118, 438, 439, 433, 433, 
+	433, 450, 433, 433, 441, 433, 446, 447, 
+	448, 452, 123, 118, 438, 439, 433, 433, 
+	153, 450, 433, 433, 441, 433, 443, 433, 
+	509, 433, 490, 490, 123, 118, 438, 439, 
+	433, 433, 433, 445, 433, 443, 433, 443, 
+	433, 433, 433, 481, 481, 433, 118, 438, 
+	439, 433, 433, 433, 445, 433, 443, 433, 
+	443, 433, 433, 433, 481, 510, 433, 118, 
+	438, 439, 433, 433, 433, 445, 433, 443, 
+	433, 443, 433, 509, 433, 481, 481, 433, 
+	118, 438, 439, 433, 433, 433, 445, 433, 
+	443, 433, 443, 120, 433, 433, 136, 444, 
+	433, 118, 438, 439, 433, 433, 433, 445, 
+	433, 443, 433, 434, 435, 437, 437, 123, 
+	118, 438, 439, 433, 433, 433, 440, 433, 
+	433, 441, 433, 188, 189, 190, 191, 511, 
+	363, 84, 79, 194, 195, 196, 196, 156, 
+	197, 361, 188, 200, 361, 204, 512, 206, 
+	207, 6, 1, 208, 209, 203, 203, 38, 
+	210, 203, 203, 211, 203, 214, 189, 190, 
+	191, 513, 514, 84, 157, 515, 516, 203, 
+	196, 156, 517, 203, 214, 200, 203, 116, 
+	518, 518, 84, 157, 208, 209, 203, 203, 
+	156, 519, 203, 520, 203, 203, 521, 515, 
+	516, 203, 515, 516, 203, 255, 203, 515, 
+	522, 203, 515, 523, 203, 515, 203, 520, 
+	203, 203, 203, 515, 516, 203, 524, 3, 
+	361, 361, 402, 431, 361, 79, 194, 195, 
+	361, 361, 361, 366, 361, 524, 361, 525, 
+	368, 526, 527, 84, 157, 515, 516, 203, 
+	203, 158, 371, 203, 203, 200, 203, 528, 
+	368, 529, 529, 84, 157, 515, 516, 203, 
+	203, 203, 371, 203, 203, 200, 203, 368, 
+	529, 529, 84, 157, 515, 516, 203, 203, 
+	203, 371, 203, 203, 200, 203, 525, 368, 
+	529, 529, 84, 157, 515, 516, 203, 203, 
+	203, 371, 203, 203, 200, 203, 525, 368, 
+	526, 529, 84, 157, 515, 516, 203, 203, 
+	158, 371, 203, 203, 200, 203, 214, 203, 
+	280, 116, 530, 530, 160, 157, 208, 209, 
+	203, 203, 203, 519, 203, 214, 203, 531, 
+	184, 532, 533, 162, 157, 515, 516, 203, 
+	203, 203, 534, 203, 184, 532, 533, 162, 
+	157, 515, 516, 203, 203, 203, 534, 203, 
+	532, 532, 162, 157, 515, 516, 203, 203, 
+	203, 534, 203, 535, 181, 536, 537, 165, 
+	157, 515, 516, 203, 203, 203, 534, 203, 
+	181, 536, 537, 165, 157, 515, 516, 203, 
+	203, 203, 534, 203, 536, 536, 165, 157, 
+	515, 516, 203, 203, 203, 534, 203, 538, 
+	178, 539, 540, 168, 157, 515, 516, 203, 
+	203, 203, 534, 203, 178, 539, 540, 168, 
+	157, 515, 516, 203, 203, 203, 534, 203, 
+	539, 539, 168, 157, 515, 516, 203, 203, 
+	203, 534, 203, 541, 175, 542, 543, 203, 
+	157, 515, 516, 203, 203, 203, 534, 203, 
+	175, 542, 543, 203, 157, 515, 516, 203, 
+	203, 203, 534, 203, 542, 542, 203, 157, 
+	515, 516, 203, 203, 203, 534, 203, 544, 
+	203, 545, 546, 203, 157, 515, 516, 203, 
+	203, 172, 203, 171, 203, 542, 542, 203, 
+	157, 515, 516, 203, 542, 542, 203, 157, 
+	515, 516, 203, 544, 203, 542, 542, 203, 
+	157, 515, 516, 203, 544, 203, 545, 542, 
+	203, 157, 515, 516, 203, 203, 172, 203, 
+	524, 171, 361, 361, 98, 365, 361, 79, 
+	194, 195, 361, 361, 361, 366, 361, 524, 
+	361, 548, 547, 549, 549, 547, 186, 550, 
+	551, 547, 549, 549, 547, 186, 550, 551, 
+	547, 552, 547, 547, 553, 550, 551, 547, 
+	550, 551, 547, 554, 547, 550, 555, 547, 
+	550, 556, 547, 550, 547, 552, 547, 547, 
+	547, 550, 551, 547, 188, 432, 432, 432, 
+	432, 432, 432, 432, 432, 432, 196, 432, 
+	432, 432, 432, 188, 432, 0
 };
 
 static const short _indic_syllable_machine_trans_targs[] = {
 	178, 200, 207, 209, 210, 4, 213, 5, 
 	7, 216, 8, 10, 219, 11, 13, 222, 
 	14, 16, 17, 199, 19, 20, 221, 22, 
 	23, 218, 25, 26, 215, 224, 228, 232, 
 	235, 239, 242, 246, 249, 253, 256, 178, 
@@ -1009,61 +1011,61 @@ static const short _indic_syllable_machi
 	436, 129, 130, 458, 132, 133, 455, 135, 
 	136, 452, 461, 465, 469, 472, 476, 479, 
 	483, 486, 490, 493, 414, 498, 509, 152, 
 	512, 154, 515, 155, 157, 518, 158, 160, 
 	521, 161, 524, 526, 527, 166, 167, 523, 
 	169, 170, 520, 172, 173, 517, 175, 176, 
 	514, 178, 532, 178, 179, 258, 337, 339, 
 	413, 415, 359, 360, 416, 412, 494, 495, 
-	384, 530, 178, 180, 182, 36, 257, 202, 
-	203, 255, 227, 181, 35, 183, 251, 1, 
-	184, 186, 34, 250, 248, 185, 33, 187, 
-	244, 188, 190, 32, 243, 241, 189, 31, 
-	191, 237, 192, 194, 30, 236, 234, 193, 
-	29, 195, 230, 196, 198, 28, 229, 226, 
-	197, 27, 212, 0, 201, 206, 178, 204, 
-	205, 208, 2, 211, 3, 214, 6, 24, 
-	217, 9, 21, 220, 12, 18, 223, 15, 
-	225, 231, 233, 238, 240, 245, 247, 252, 
-	254, 178, 259, 261, 73, 334, 281, 282, 
-	335, 306, 260, 72, 262, 330, 38, 263, 
-	265, 71, 329, 327, 264, 70, 266, 323, 
-	267, 269, 69, 322, 320, 268, 68, 270, 
-	316, 271, 273, 67, 315, 313, 272, 66, 
-	274, 309, 275, 277, 65, 308, 305, 276, 
-	64, 291, 37, 280, 285, 178, 283, 284, 
-	287, 39, 290, 40, 293, 43, 61, 296, 
-	46, 58, 299, 49, 55, 302, 52, 304, 
-	310, 312, 317, 319, 324, 326, 331, 333, 
-	178, 338, 109, 340, 408, 75, 341, 343, 
-	108, 407, 405, 342, 107, 344, 401, 345, 
-	347, 106, 400, 398, 346, 105, 348, 394, 
-	349, 351, 104, 393, 391, 350, 103, 352, 
-	387, 353, 355, 102, 386, 383, 354, 101, 
-	369, 74, 358, 363, 178, 361, 362, 365, 
-	76, 368, 77, 371, 80, 98, 374, 83, 
-	95, 377, 86, 92, 380, 89, 382, 388, 
-	390, 395, 397, 402, 404, 409, 411, 178, 
-	178, 417, 419, 146, 145, 439, 440, 492, 
-	464, 418, 420, 488, 111, 421, 423, 144, 
-	487, 485, 422, 143, 424, 481, 425, 427, 
-	142, 480, 478, 426, 141, 428, 474, 429, 
-	431, 140, 473, 471, 430, 139, 432, 467, 
-	433, 435, 138, 466, 463, 434, 137, 449, 
-	110, 438, 443, 178, 441, 442, 445, 112, 
-	448, 113, 451, 116, 134, 454, 119, 131, 
-	457, 122, 128, 460, 125, 462, 468, 470, 
-	475, 477, 482, 484, 489, 491, 147, 496, 
-	497, 511, 500, 501, 529, 148, 505, 499, 
-	504, 502, 503, 506, 507, 150, 510, 508, 
-	149, 151, 513, 153, 174, 163, 516, 156, 
-	171, 519, 159, 168, 522, 162, 165, 525, 
-	164, 528, 178, 531, 177, 534, 535, 533, 
-	538, 178, 536, 537
+	384, 530, 539, 178, 180, 182, 36, 257, 
+	202, 203, 255, 227, 181, 35, 183, 251, 
+	1, 184, 186, 34, 250, 248, 185, 33, 
+	187, 244, 188, 190, 32, 243, 241, 189, 
+	31, 191, 237, 192, 194, 30, 236, 234, 
+	193, 29, 195, 230, 196, 198, 28, 229, 
+	226, 197, 27, 212, 0, 201, 206, 178, 
+	204, 205, 208, 2, 211, 3, 214, 6, 
+	24, 217, 9, 21, 220, 12, 18, 223, 
+	15, 225, 231, 233, 238, 240, 245, 247, 
+	252, 254, 178, 259, 261, 73, 334, 281, 
+	282, 335, 306, 260, 72, 262, 330, 38, 
+	263, 265, 71, 329, 327, 264, 70, 266, 
+	323, 267, 269, 69, 322, 320, 268, 68, 
+	270, 316, 271, 273, 67, 315, 313, 272, 
+	66, 274, 309, 275, 277, 65, 308, 305, 
+	276, 64, 291, 37, 280, 285, 178, 283, 
+	284, 287, 39, 290, 40, 293, 43, 61, 
+	296, 46, 58, 299, 49, 55, 302, 52, 
+	304, 310, 312, 317, 319, 324, 326, 331, 
+	333, 178, 338, 109, 340, 408, 75, 341, 
+	343, 108, 407, 405, 342, 107, 344, 401, 
+	345, 347, 106, 400, 398, 346, 105, 348, 
+	394, 349, 351, 104, 393, 391, 350, 103, 
+	352, 387, 353, 355, 102, 386, 383, 354, 
+	101, 369, 74, 358, 363, 178, 361, 362, 
+	365, 76, 368, 77, 371, 80, 98, 374, 
+	83, 95, 377, 86, 92, 380, 89, 382, 
+	388, 390, 395, 397, 402, 404, 409, 411, 
+	178, 178, 417, 419, 146, 145, 439, 440, 
+	492, 464, 418, 420, 488, 111, 421, 423, 
+	144, 487, 485, 422, 143, 424, 481, 425, 
+	427, 142, 480, 478, 426, 141, 428, 474, 
+	429, 431, 140, 473, 471, 430, 139, 432, 
+	467, 433, 435, 138, 466, 463, 434, 137, 
+	449, 110, 438, 443, 178, 441, 442, 445, 
+	112, 448, 113, 451, 116, 134, 454, 119, 
+	131, 457, 122, 128, 460, 125, 462, 468, 
+	470, 475, 477, 482, 484, 489, 491, 147, 
+	496, 497, 511, 500, 501, 529, 148, 505, 
+	499, 504, 502, 503, 506, 507, 150, 510, 
+	508, 149, 151, 513, 153, 174, 163, 516, 
+	156, 171, 519, 159, 168, 522, 162, 165, 
+	525, 164, 528, 178, 531, 177, 534, 535, 
+	533, 538, 178, 536, 537
 };
 
 static const char _indic_syllable_machine_trans_actions[] = {
 	1, 0, 2, 2, 2, 0, 2, 0, 
 	0, 2, 0, 0, 2, 0, 0, 2, 
 	0, 0, 0, 2, 0, 0, 2, 0, 
 	0, 2, 0, 0, 2, 2, 2, 2, 
 	2, 2, 2, 2, 2, 2, 2, 3, 
@@ -1082,61 +1084,61 @@ static const char _indic_syllable_machin
 	2, 0, 0, 2, 0, 0, 2, 0, 
 	0, 2, 2, 2, 2, 2, 2, 2, 
 	2, 2, 2, 2, 6, 0, 8, 0, 
 	2, 0, 2, 0, 0, 2, 0, 0, 
 	2, 0, 2, 2, 2, 0, 0, 2, 
 	0, 0, 2, 0, 0, 2, 0, 0, 
 	2, 9, 0, 12, 2, 2, 6, 2, 
 	13, 13, 0, 0, 2, 2, 6, 2, 
-	6, 2, 14, 2, 2, 0, 2, 0, 
+	6, 2, 0, 14, 2, 2, 0, 2, 
+	0, 0, 2, 2, 2, 0, 2, 2, 
+	0, 2, 2, 0, 2, 2, 2, 0, 
+	2, 2, 2, 2, 0, 2, 2, 2, 
+	0, 2, 2, 2, 2, 0, 2, 2, 
+	2, 0, 2, 2, 2, 2, 0, 2, 
+	2, 2, 0, 2, 0, 0, 0, 15, 
+	0, 0, 2, 0, 2, 0, 2, 0, 
+	0, 2, 0, 0, 2, 0, 0, 2, 
+	0, 2, 2, 2, 2, 2, 2, 2, 
+	2, 2, 16, 2, 2, 0, 2, 0, 
 	0, 2, 2, 2, 0, 2, 2, 0, 
 	2, 2, 0, 2, 2, 2, 0, 2, 
 	2, 2, 2, 0, 2, 2, 2, 0, 
 	2, 2, 2, 2, 0, 2, 2, 2, 
 	0, 2, 2, 2, 2, 0, 2, 2, 
-	2, 0, 2, 0, 0, 0, 15, 0, 
+	2, 0, 2, 0, 0, 0, 17, 0, 
 	0, 2, 0, 2, 0, 2, 0, 0, 
 	2, 0, 0, 2, 0, 0, 2, 0, 
 	2, 2, 2, 2, 2, 2, 2, 2, 
-	2, 16, 2, 2, 0, 2, 0, 0, 
-	2, 2, 2, 0, 2, 2, 0, 2, 
-	2, 0, 2, 2, 2, 0, 2, 2, 
-	2, 2, 0, 2, 2, 2, 0, 2, 
-	2, 2, 2, 0, 2, 2, 2, 0, 
-	2, 2, 2, 2, 0, 2, 2, 2, 
-	0, 2, 0, 0, 0, 17, 0, 0, 
-	2, 0, 2, 0, 2, 0, 0, 2, 
-	0, 0, 2, 0, 0, 2, 0, 2, 
-	2, 2, 2, 2, 2, 2, 2, 2, 
-	18, 6, 0, 6, 6, 0, 6, 2, 
-	0, 6, 2, 6, 0, 6, 6, 6, 
+	2, 18, 6, 0, 6, 6, 0, 6, 
 	2, 0, 6, 2, 6, 0, 6, 6, 
 	6, 2, 0, 6, 2, 6, 0, 6, 
 	6, 6, 2, 0, 6, 2, 6, 0, 
-	6, 0, 0, 0, 19, 0, 0, 2, 
-	0, 2, 0, 2, 0, 0, 2, 0, 
-	0, 2, 0, 0, 2, 0, 2, 2, 
-	2, 2, 2, 2, 2, 2, 2, 20, 
-	21, 2, 2, 0, 0, 0, 0, 2, 
-	2, 2, 2, 2, 0, 2, 2, 0, 
-	2, 2, 2, 0, 2, 2, 2, 2, 
+	6, 6, 6, 2, 0, 6, 2, 6, 
+	0, 6, 0, 0, 0, 19, 0, 0, 
+	2, 0, 2, 0, 2, 0, 0, 2, 
+	0, 0, 2, 0, 0, 2, 0, 2, 
+	2, 2, 2, 2, 2, 2, 2, 2, 
+	20, 21, 2, 2, 0, 0, 0, 0, 
+	2, 2, 2, 2, 2, 0, 2, 2, 
 	0, 2, 2, 2, 0, 2, 2, 2, 
 	2, 0, 2, 2, 2, 0, 2, 2, 
 	2, 2, 0, 2, 2, 2, 0, 2, 
-	0, 0, 0, 22, 0, 0, 2, 0, 
-	2, 0, 2, 0, 0, 2, 0, 0, 
-	2, 0, 0, 2, 0, 2, 2, 2, 
-	2, 2, 2, 2, 2, 2, 0, 0, 
-	8, 2, 0, 0, 2, 0, 2, 0, 
-	0, 0, 0, 8, 8, 0, 8, 8, 
-	0, 0, 2, 0, 0, 0, 2, 0, 
-	0, 2, 0, 0, 2, 0, 0, 2, 
-	0, 2, 23, 2, 0, 0, 0, 0, 
-	0, 24, 0, 0
+	2, 2, 2, 0, 2, 2, 2, 0, 
+	2, 0, 0, 0, 22, 0, 0, 2, 
+	0, 2, 0, 2, 0, 0, 2, 0, 
+	0, 2, 0, 0, 2, 0, 2, 2, 
+	2, 2, 2, 2, 2, 2, 2, 0, 
+	0, 8, 2, 0, 0, 2, 0, 2, 
+	0, 0, 0, 0, 8, 8, 0, 8, 
+	8, 0, 0, 2, 0, 0, 0, 2, 
+	0, 0, 2, 0, 0, 2, 0, 0, 
+	2, 0, 2, 23, 2, 0, 0, 0, 
+	0, 0, 24, 0, 0
 };
 
 static const char _indic_syllable_machine_to_state_actions[] = {
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
@@ -1197,17 +1199,17 @@ static const char _indic_syllable_machin
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0
+	0, 0, 0, 0
 };
 
 static const char _indic_syllable_machine_from_state_actions[] = {
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
@@ -1268,17 +1270,17 @@ static const char _indic_syllable_machin
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0
+	0, 0, 0, 0
 };
 
 static const short _indic_syllable_machine_eof_trans[] = {
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 40, 40, 40, 
@@ -1294,76 +1296,76 @@ static const short _indic_syllable_machi
 	118, 118, 118, 118, 118, 118, 118, 118, 
 	118, 118, 118, 118, 118, 118, 118, 118, 
 	118, 118, 118, 118, 118, 118, 118, 118, 
 	118, 118, 118, 118, 118, 118, 118, 118, 
 	118, 118, 118, 79, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 186, 0, 203, 203, 203, 203, 203, 
-	203, 203, 203, 203, 203, 203, 203, 203, 
-	203, 203, 203, 203, 203, 203, 203, 203, 
-	203, 203, 203, 203, 203, 203, 203, 203, 
-	203, 203, 203, 203, 203, 203, 203, 203, 
-	203, 203, 203, 203, 203, 203, 203, 203, 
-	203, 203, 203, 203, 203, 203, 203, 203, 
-	203, 203, 203, 203, 203, 203, 203, 203, 
-	203, 203, 203, 203, 203, 203, 203, 203, 
-	203, 203, 203, 203, 203, 203, 203, 203, 
-	203, 203, 282, 282, 282, 282, 282, 282, 
-	282, 282, 282, 282, 282, 282, 282, 282, 
-	282, 282, 282, 282, 282, 282, 282, 282, 
-	282, 282, 282, 282, 282, 282, 282, 282, 
-	282, 282, 282, 282, 282, 282, 282, 282, 
-	282, 282, 282, 282, 282, 282, 282, 282, 
-	282, 282, 282, 282, 282, 282, 282, 282, 
-	282, 282, 282, 282, 282, 282, 282, 282, 
-	282, 282, 282, 282, 282, 282, 282, 282, 
-	282, 282, 282, 282, 282, 282, 282, 282, 
-	282, 361, 361, 361, 361, 361, 361, 361, 
-	361, 361, 361, 361, 361, 361, 361, 361, 
-	361, 361, 361, 361, 361, 361, 361, 361, 
-	361, 361, 361, 361, 361, 361, 361, 361, 
-	361, 361, 361, 361, 361, 361, 361, 361, 
-	361, 361, 361, 361, 361, 361, 361, 361, 
-	361, 361, 361, 361, 361, 361, 361, 361, 
-	361, 361, 361, 361, 361, 361, 361, 361, 
-	361, 361, 361, 361, 361, 361, 361, 361, 
-	361, 361, 361, 361, 361, 432, 361, 432, 
-	433, 433, 433, 433, 433, 433, 433, 433, 
-	433, 433, 433, 433, 433, 433, 433, 433, 
-	433, 433, 433, 433, 433, 433, 433, 433, 
-	433, 433, 433, 433, 433, 433, 433, 433, 
-	433, 433, 433, 433, 433, 433, 433, 433, 
-	433, 433, 433, 433, 433, 433, 433, 433, 
-	433, 433, 433, 433, 433, 433, 433, 433, 
-	433, 433, 433, 433, 433, 433, 433, 433, 
-	433, 433, 433, 433, 433, 433, 433, 433, 
-	433, 433, 433, 433, 433, 433, 361, 203, 
-	203, 203, 203, 203, 203, 203, 203, 203, 
-	203, 361, 203, 203, 203, 203, 203, 203, 
-	203, 203, 203, 203, 203, 203, 203, 203, 
-	203, 203, 203, 203, 203, 203, 203, 203, 
-	203, 361, 547, 547, 547, 547, 547, 547, 
-	547, 547, 547
+	1, 186, 0, 204, 204, 204, 204, 204, 
+	204, 204, 204, 204, 204, 204, 204, 204, 
+	204, 204, 204, 204, 204, 204, 204, 204, 
+	204, 204, 204, 204, 204, 204, 204, 204, 
+	204, 204, 204, 204, 204, 204, 204, 204, 
+	204, 204, 204, 204, 204, 204, 204, 204, 
+	204, 204, 204, 204, 204, 204, 204, 204, 
+	204, 204, 204, 204, 204, 204, 204, 204, 
+	204, 204, 204, 204, 204, 204, 204, 204, 
+	204, 204, 204, 204, 204, 204, 204, 204, 
+	204, 204, 283, 283, 283, 283, 283, 283, 
+	283, 283, 283, 283, 283, 283, 283, 283, 
+	283, 283, 283, 283, 283, 283, 283, 283, 
+	283, 283, 283, 283, 283, 283, 283, 283, 
+	283, 283, 283, 283, 283, 283, 283, 283, 
+	283, 283, 283, 283, 283, 283, 283, 283, 
+	283, 283, 283, 283, 283, 283, 283, 283, 
+	283, 283, 283, 283, 283, 283, 283, 283, 
+	283, 283, 283, 283, 283, 283, 283, 283, 
+	283, 283, 283, 283, 283, 283, 283, 283, 
+	283, 362, 362, 362, 362, 362, 362, 362, 
+	362, 362, 362, 362, 362, 362, 362, 362, 
+	362, 362, 362, 362, 362, 362, 362, 362, 
+	362, 362, 362, 362, 362, 362, 362, 362, 
+	362, 362, 362, 362, 362, 362, 362, 362, 
+	362, 362, 362, 362, 362, 362, 362, 362, 
+	362, 362, 362, 362, 362, 362, 362, 362, 
+	362, 362, 362, 362, 362, 362, 362, 362, 
+	362, 362, 362, 362, 362, 362, 362, 362, 
+	362, 362, 362, 362, 362, 433, 362, 433, 
+	434, 434, 434, 434, 434, 434, 434, 434, 
+	434, 434, 434, 434, 434, 434, 434, 434, 
+	434, 434, 434, 434, 434, 434, 434, 434, 
+	434, 434, 434, 434, 434, 434, 434, 434, 
+	434, 434, 434, 434, 434, 434, 434, 434, 
+	434, 434, 434, 434, 434, 434, 434, 434, 
+	434, 434, 434, 434, 434, 434, 434, 434, 
+	434, 434, 434, 434, 434, 434, 434, 434, 
+	434, 434, 434, 434, 434, 434, 434, 434, 
+	434, 434, 434, 434, 434, 434, 362, 204, 
+	204, 204, 204, 204, 204, 204, 204, 204, 
+	204, 362, 204, 204, 204, 204, 204, 204, 
+	204, 204, 204, 204, 204, 204, 204, 204, 
+	204, 204, 204, 204, 204, 204, 204, 204, 
+	204, 362, 548, 548, 548, 548, 548, 548, 
+	548, 548, 548, 433
 };
 
 static const int indic_syllable_machine_start = 178;
 static const int indic_syllable_machine_first_final = 178;
 static const int indic_syllable_machine_error = -1;
 
 static const int indic_syllable_machine_en_main = 178;
 
 
 #line 36 "hb-ot-shape-complex-indic-machine.rl"
 
 
 
-#line 96 "hb-ot-shape-complex-indic-machine.rl"
+#line 97 "hb-ot-shape-complex-indic-machine.rl"
 
 
 #define found_syllable(syllable_type) \
   HB_STMT_START { \
     if (0) fprintf (stderr, "syllable %d..%d %s\n", last, p+1, #syllable_type); \
     for (unsigned int i = last; i < p+1; i++) \
       info[i].syllable() = (syllable_serial << 4) | syllable_type; \
     last = p+1; \
@@ -1373,48 +1375,48 @@ static const int indic_syllable_machine_
 
 static void
 find_syllables (hb_buffer_t *buffer)
 {
   unsigned int p, pe, eof, ts HB_UNUSED, te HB_UNUSED, act HB_UNUSED;
   int cs;
   hb_glyph_info_t *info = buffer->info;
   
-#line 1382 "hb-ot-shape-complex-indic-machine.hh"
+#line 1384 "hb-ot-shape-complex-indic-machine.hh"
 	{
 	cs = indic_syllable_machine_start;
 	ts = 0;
 	te = 0;
 	act = 0;
 	}
 
-#line 117 "hb-ot-shape-complex-indic-machine.rl"
+#line 118 "hb-ot-shape-complex-indic-machine.rl"
 
 
   p = 0;
   pe = eof = buffer->len;
 
   unsigned int last = 0;
   unsigned int syllable_serial = 1;
   
-#line 1399 "hb-ot-shape-complex-indic-machine.hh"
+#line 1401 "hb-ot-shape-complex-indic-machine.hh"
 	{
 	int _slen;
 	int _trans;
 	const unsigned char *_keys;
 	const short *_inds;
 	if ( p == pe )
 		goto _test_eof;
 _resume:
 	switch ( _indic_syllable_machine_from_state_actions[cs] ) {
 	case 11:
 #line 1 "NONE"
 	{ts = p;}
 	break;
-#line 1413 "hb-ot-shape-complex-indic-machine.hh"
+#line 1415 "hb-ot-shape-complex-indic-machine.hh"
 	}
 
 	_keys = _indic_syllable_machine_trans_keys + (cs<<1);
 	_inds = _indic_syllable_machine_indicies + _indic_syllable_machine_index_offsets[cs];
 
 	_slen = _indic_syllable_machine_key_spans[cs];
 	_trans = _inds[ _slen > 0 && _keys[0] <=( info[p].indic_category()) &&
 		( info[p].indic_category()) <= _keys[1] ?
@@ -1427,81 +1429,81 @@ find_syllables (hb_buffer_t *buffer)
 		goto _again;
 
 	switch ( _indic_syllable_machine_trans_actions[_trans] ) {
 	case 2:
 #line 1 "NONE"
 	{te = p+1;}
 	break;
 	case 15:
-#line 87 "hb-ot-shape-complex-indic-machine.rl"
+#line 88 "hb-ot-shape-complex-indic-machine.rl"
 	{te = p+1;{ found_syllable (consonant_syllable); }}
 	break;
 	case 17:
-#line 88 "hb-ot-shape-complex-indic-machine.rl"
+#line 89 "hb-ot-shape-complex-indic-machine.rl"
 	{te = p+1;{ found_syllable (vowel_syllable); }}
 	break;
 	case 22:
-#line 89 "hb-ot-shape-complex-indic-machine.rl"
+#line 90 "hb-ot-shape-complex-indic-machine.rl"
 	{te = p+1;{ found_syllable (standalone_cluster); }}
 	break;
 	case 24:
-#line 90 "hb-ot-shape-complex-indic-machine.rl"
+#line 91 "hb-ot-shape-complex-indic-machine.rl"
 	{te = p+1;{ found_syllable (symbol_cluster); }}
 	break;
 	case 19:
-#line 91 "hb-ot-shape-complex-indic-machine.rl"
+#line 92 "hb-ot-shape-complex-indic-machine.rl"
 	{te = p+1;{ found_syllable (broken_cluster); }}
 	break;
 	case 12:
-#line 92 "hb-ot-shape-complex-indic-machine.rl"
+#line 93 "hb-ot-shape-complex-indic-machine.rl"
 	{te = p+1;{ found_syllable (non_indic_cluster); }}
 	break;
 	case 14:
-#line 87 "hb-ot-shape-complex-indic-machine.rl"
+#line 88 "hb-ot-shape-complex-indic-machine.rl"
 	{te = p;p--;{ found_syllable (consonant_syllable); }}
 	break;
 	case 16:
-#line 88 "hb-ot-shape-complex-indic-machine.rl"
+#line 89 "hb-ot-shape-complex-indic-machine.rl"
 	{te = p;p--;{ found_syllable (vowel_syllable); }}
 	break;
 	case 21:
-#line 89 "hb-ot-shape-complex-indic-machine.rl"
+#line 90 "hb-ot-shape-complex-indic-machine.rl"
 	{te = p;p--;{ found_syllable (standalone_cluster); }}
 	break;
 	case 23:
-#line 90 "hb-ot-shape-complex-indic-machine.rl"
+#line 91 "hb-ot-shape-complex-indic-machine.rl"
 	{te = p;p--;{ found_syllable (symbol_cluster); }}
 	break;
 	case 18:
-#line 91 "hb-ot-shape-complex-indic-machine.rl"
+#line 92 "hb-ot-shape-complex-indic-machine.rl"
 	{te = p;p--;{ found_syllable (broken_cluster); }}
 	break;
 	case 20:
-#line 92 "hb-ot-shape-complex-indic-machine.rl"
+#line 93 "hb-ot-shape-complex-indic-machine.rl"
 	{te = p;p--;{ found_syllable (non_indic_cluster); }}
 	break;
 	case 1:
-#line 87 "hb-ot-shape-complex-indic-machine.rl"
+#line 88 "hb-ot-shape-complex-indic-machine.rl"
 	{{p = ((te))-1;}{ found_syllable (consonant_syllable); }}
 	break;
 	case 3:
-#line 88 "hb-ot-shape-complex-indic-machine.rl"
+#line 89 "hb-ot-shape-complex-indic-machine.rl"
 	{{p = ((te))-1;}{ found_syllable (vowel_syllable); }}
 	break;
 	case 7:
-#line 89 "hb-ot-shape-complex-indic-machine.rl"
+#line 90 "hb-ot-shape-complex-indic-machine.rl"
 	{{p = ((te))-1;}{ found_syllable (standalone_cluster); }}
 	break;
 	case 9:
-#line 90 "hb-ot-shape-complex-indic-machine.rl"
+#line 91 "hb-ot-shape-complex-indic-machine.rl"
 	{{p = ((te))-1;}{ found_syllable (symbol_cluster); }}
 	break;
 	case 4:
-#line 91 "hb-ot-shape-complex-indic-machine.rl"
+#line 92 "hb-ot-shape-complex-indic-machine.rl"
 	{{p = ((te))-1;}{ found_syllable (broken_cluster); }}
 	break;
 	case 5:
 #line 1 "NONE"
 	{	switch( act ) {
 	case 1:
 	{{p = ((te))-1;} found_syllable (consonant_syllable); }
 	break;
@@ -1512,53 +1514,53 @@ find_syllables (hb_buffer_t *buffer)
 	{{p = ((te))-1;} found_syllable (non_indic_cluster); }
 	break;
 	}
 	}
 	break;
 	case 8:
 #line 1 "NONE"
 	{te = p+1;}
-#line 87 "hb-ot-shape-complex-indic-machine.rl"
+#line 88 "hb-ot-shape-complex-indic-machine.rl"
 	{act = 1;}
 	break;
 	case 6:
 #line 1 "NONE"
 	{te = p+1;}
-#line 91 "hb-ot-shape-complex-indic-machine.rl"
+#line 92 "hb-ot-shape-complex-indic-machine.rl"
 	{act = 5;}
 	break;
 	case 13:
 #line 1 "NONE"
 	{te = p+1;}
-#line 92 "hb-ot-shape-complex-indic-machine.rl"
+#line 93 "hb-ot-shape-complex-indic-machine.rl"
 	{act = 6;}
 	break;
-#line 1536 "hb-ot-shape-complex-indic-machine.hh"
+#line 1538 "hb-ot-shape-complex-indic-machine.hh"
 	}
 
 _again:
 	switch ( _indic_syllable_machine_to_state_actions[cs] ) {
 	case 10:
 #line 1 "NONE"
 	{ts = 0;}
 	break;
-#line 1545 "hb-ot-shape-complex-indic-machine.hh"
+#line 1547 "hb-ot-shape-complex-indic-machine.hh"
 	}
 
 	if ( ++p != pe )
 		goto _resume;
 	_test_eof: {}
 	if ( p == eof )
 	{
 	if ( _indic_syllable_machine_eof_trans[cs] > 0 ) {
 		_trans = _indic_syllable_machine_eof_trans[cs] - 1;
 		goto _eof_trans;
 	}
 	}
 
 	}
 
-#line 126 "hb-ot-shape-complex-indic-machine.rl"
+#line 127 "hb-ot-shape-complex-indic-machine.rl"
 
 }
 
 #endif /* HB_OT_SHAPE_COMPLEX_INDIC_MACHINE_HH */
--- a/gfx/harfbuzz/src/hb-ot-shape-complex-indic-machine.rl
+++ b/gfx/harfbuzz/src/hb-ot-shape-complex-indic-machine.rl
@@ -52,16 +52,17 @@ A    = 10;
 PLACEHOLDER = 11;
 DOTTEDCIRCLE = 12;
 RS    = 13;
 Coeng = 14;
 Repha = 15;
 Ra    = 16;
 CM    = 17;
 Symbol= 18;
+CS    = 19;
 
 c = (C | Ra);			# is_consonant
 n = ((ZWNJ?.RS)? (N.N?)?);	# is_consonant_modifier
 z = ZWJ|ZWNJ;			# is_joiner
 h = H | Coeng;			# is_halant_or_coeng
 reph = (Ra H | Repha);		# possible reph
 
 cn = c.ZWJ?.n?;
@@ -71,19 +72,19 @@ matra_group = z{0,3}.M.N?.(H | forced_ra
 syllable_tail = (z?.SM.SM?.ZWNJ?)? A{0,3}? VD{0,2};
 place_holder = PLACEHOLDER | DOTTEDCIRCLE;
 halant_group = (z?.h.(ZWJ.N?)?);
 final_halant_group = halant_group | h.ZWNJ;
 medial_group = CM?;
 halant_or_matra_group = (final_halant_group | (h.ZWJ)? matra_group{0,4}) (Coeng (cn|V))?;
 
 
-consonant_syllable =	Repha? (cn.halant_group){0,4} cn medial_group halant_or_matra_group syllable_tail;
+consonant_syllable =	(Repha|CS)? (cn.halant_group){0,4} cn medial_group halant_or_matra_group syllable_tail;
 vowel_syllable =	reph? V.n? (ZWJ | (halant_group.cn){0,4} medial_group halant_or_matra_group syllable_tail);
-standalone_cluster =	(Repha? PLACEHOLDER | reph? DOTTEDCIRCLE).n? (halant_group.cn){0,4} medial_group halant_or_matra_group syllable_tail;
+standalone_cluster =	((Repha|CS)? PLACEHOLDER | reph? DOTTEDCIRCLE).n? (halant_group.cn){0,4} medial_group halant_or_matra_group syllable_tail;
 symbol_cluster = 	symbol syllable_tail;
 broken_cluster =	reph? n? (halant_group.cn){0,4} medial_group halant_or_matra_group syllable_tail;
 other =			any;
 
 main := |*
 	consonant_syllable	=> { found_syllable (consonant_syllable); };
 	vowel_syllable		=> { found_syllable (vowel_syllable); };
 	standalone_cluster	=> { found_syllable (standalone_cluster); };
--- a/gfx/harfbuzz/src/hb-ot-shape-complex-indic-private.hh
+++ b/gfx/harfbuzz/src/hb-ot-shape-complex-indic-private.hh
@@ -55,27 +55,28 @@ enum indic_category_t {
   OT_A = 10,
   OT_PLACEHOLDER = 11,
   OT_DOTTEDCIRCLE = 12,
   OT_RS = 13, /* Register Shifter, used in Khmer OT spec. */
   OT_Coeng = 14, /* Khmer-style Virama. */
   OT_Repha = 15, /* Atomically-encoded logical or visual repha. */
   OT_Ra = 16,
   OT_CM = 17,  /* Consonant-Medial. */
-  OT_Symbol = 18 /* Avagraha, etc that take marks (SM,A,VD). */
+  OT_Symbol = 18, /* Avagraha, etc that take marks (SM,A,VD). */
+  OT_CS = 19
 };
 
 #define MEDIAL_FLAGS (FLAG (OT_CM))
 
 /* Note:
  *
  * We treat Vowels and placeholders as if they were consonants.  This is safe because Vowels
  * cannot happen in a consonant syllable.  The plus side however is, we can call the
  * consonant syllable logic from the vowel syllable function and get it all right! */
-#define CONSONANT_FLAGS (FLAG (OT_C) | FLAG (OT_Ra) | MEDIAL_FLAGS | FLAG (OT_V) | FLAG (OT_PLACEHOLDER) | FLAG (OT_DOTTEDCIRCLE))
+#define CONSONANT_FLAGS (FLAG (OT_C) | FLAG (OT_CS) | FLAG (OT_Ra) | MEDIAL_FLAGS | FLAG (OT_V) | FLAG (OT_PLACEHOLDER) | FLAG (OT_DOTTEDCIRCLE))
 #define JOINER_FLAGS (FLAG (OT_ZWJ) | FLAG (OT_ZWNJ))
 #define HALANT_OR_COENG_FLAGS (FLAG (OT_H) | FLAG (OT_Coeng))
 
 
 /* Visual positions in a syllable from left to right. */
 enum indic_position_t {
   POS_START,
 
@@ -116,18 +117,18 @@ enum indic_syllabic_category_t {
   INDIC_SYLLABIC_CATEGORY_CONSONANT_HEAD_LETTER		= OT_C,
   INDIC_SYLLABIC_CATEGORY_CONSONANT_KILLER		= OT_M, /* U+17CD only. */
   INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL		= OT_CM,
   INDIC_SYLLABIC_CATEGORY_CONSONANT_PLACEHOLDER		= OT_PLACEHOLDER,
   INDIC_SYLLABIC_CATEGORY_CONSONANT_PRECEDING_REPHA	= OT_Repha,
   INDIC_SYLLABIC_CATEGORY_CONSONANT_PREFIXED		= OT_X, /* Don't care. */
   INDIC_SYLLABIC_CATEGORY_CONSONANT_SUBJOINED		= OT_CM,
   INDIC_SYLLABIC_CATEGORY_CONSONANT_SUCCEEDING_REPHA	= OT_N,
-  INDIC_SYLLABIC_CATEGORY_CONSONANT_WITH_STACKER	= OT_C,
-  INDIC_SYLLABIC_CATEGORY_GEMINATION_MARK		= OT_SM,
+  INDIC_SYLLABIC_CATEGORY_CONSONANT_WITH_STACKER	= OT_CS,
+  INDIC_SYLLABIC_CATEGORY_GEMINATION_MARK		= OT_SM, /* https://github.com/behdad/harfbuzz/issues/552 */
   INDIC_SYLLABIC_CATEGORY_INVISIBLE_STACKER		= OT_Coeng,
   INDIC_SYLLABIC_CATEGORY_JOINER			= OT_ZWJ,
   INDIC_SYLLABIC_CATEGORY_MODIFYING_LETTER		= OT_X,
   INDIC_SYLLABIC_CATEGORY_NON_JOINER			= OT_ZWNJ,
   INDIC_SYLLABIC_CATEGORY_NUKTA				= OT_N,
   INDIC_SYLLABIC_CATEGORY_NUMBER			= OT_PLACEHOLDER,
   INDIC_SYLLABIC_CATEGORY_NUMBER_JOINER			= OT_PLACEHOLDER, /* Don't care. */
   INDIC_SYLLABIC_CATEGORY_PURE_KILLER			= OT_M, /* Is like a vowel matra. */
--- a/gfx/harfbuzz/src/hb-ot-shape-complex-indic-table.cc
+++ b/gfx/harfbuzz/src/hb-ot-shape-complex-indic-table.cc
@@ -1,71 +1,72 @@
 /* == Start of generated table == */
 /*
  * The following table is generated by running:
  *
  *   ./gen-indic-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt Blocks.txt
  *
  * on files with these headers:
  *
- * # IndicSyllabicCategory-9.0.0.txt
- * # Date: 2016-05-21, 02:46:00 GMT [RP]
- * # IndicPositionalCategory-9.0.0.txt
- * # Date: 2016-02-25, 00:48:00 GMT [RP]
- * # Blocks-9.0.0.txt
- * # Date: 2016-02-05, 23:48:00 GMT [KW]
+ * # IndicSyllabicCategory-10.0.0.txt
+ * # Date: 2017-05-31, 01:07:00 GMT [KW, RP]
+ * # IndicPositionalCategory-10.0.0.txt
+ * # Date: 2017-05-31, 01:07:00 GMT [RP]
+ * # Blocks-10.0.0.txt
+ * # Date: 2017-04-12, 17:30:00 GMT [KW]
  */
 
 #include "hb-ot-shape-complex-indic-private.hh"
 
 
 #define ISC_A	INDIC_SYLLABIC_CATEGORY_AVAGRAHA		/*  15 chars; Avagraha */
-#define ISC_Bi	INDIC_SYLLABIC_CATEGORY_BINDU			/*  67 chars; Bindu */
+#define ISC_Bi	INDIC_SYLLABIC_CATEGORY_BINDU			/*  80 chars; Bindu */
 #define ISC_BJN	INDIC_SYLLABIC_CATEGORY_BRAHMI_JOINING_NUMBER	/*  20 chars; Brahmi_Joining_Number */
-#define ISC_Ca	INDIC_SYLLABIC_CATEGORY_CANTILLATION_MARK	/*  53 chars; Cantillation_Mark */
-#define ISC_C	INDIC_SYLLABIC_CATEGORY_CONSONANT		/* 1907 chars; Consonant */
+#define ISC_Ca	INDIC_SYLLABIC_CATEGORY_CANTILLATION_MARK	/*  57 chars; Cantillation_Mark */
+#define ISC_C	INDIC_SYLLABIC_CATEGORY_CONSONANT		/* 2024 chars; Consonant */
 #define ISC_CD	INDIC_SYLLABIC_CATEGORY_CONSONANT_DEAD		/*  10 chars; Consonant_Dead */
-#define ISC_CF	INDIC_SYLLABIC_CATEGORY_CONSONANT_FINAL		/*  62 chars; Consonant_Final */
+#define ISC_CF	INDIC_SYLLABIC_CATEGORY_CONSONANT_FINAL		/*  68 chars; Consonant_Final */
 #define ISC_CHL	INDIC_SYLLABIC_CATEGORY_CONSONANT_HEAD_LETTER	/*   5 chars; Consonant_Head_Letter */
 #define ISC_CK	INDIC_SYLLABIC_CATEGORY_CONSONANT_KILLER	/*   2 chars; Consonant_Killer */
-#define ISC_CM	INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL	/*  22 chars; Consonant_Medial */
-#define ISC_CP	INDIC_SYLLABIC_CATEGORY_CONSONANT_PLACEHOLDER	/*  16 chars; Consonant_Placeholder */
-#define ISC_CPR	INDIC_SYLLABIC_CATEGORY_CONSONANT_PRECEDING_REPHA	/*   1 chars; Consonant_Preceding_Repha */
-#define ISC_CPrf	INDIC_SYLLABIC_CATEGORY_CONSONANT_PREFIXED	/*   2 chars; Consonant_Prefixed */
-#define ISC_CS	INDIC_SYLLABIC_CATEGORY_CONSONANT_SUBJOINED	/*  90 chars; Consonant_Subjoined */
-#define ISC_CSR	INDIC_SYLLABIC_CATEGORY_CONSONANT_SUCCEEDING_REPHA	/*   4 chars; Consonant_Succeeding_Repha */
+#define ISC_CM	INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL	/*  27 chars; Consonant_Medial */
+#define ISC_CP	INDIC_SYLLABIC_CATEGORY_CONSONANT_PLACEHOLDER	/*  18 chars; Consonant_Placeholder */
+#define ISC_CPR	INDIC_SYLLABIC_CATEGORY_CONSONANT_PRECEDING_REPHA	/*   2 chars; Consonant_Preceding_Repha */
+#define ISC_CPrf	INDIC_SYLLABIC_CATEGORY_CONSONANT_PREFIXED	/*   7 chars; Consonant_Prefixed */
+#define ISC_CS	INDIC_SYLLABIC_CATEGORY_CONSONANT_SUBJOINED	/*  95 chars; Consonant_Subjoined */
+#define ISC_CSR	INDIC_SYLLABIC_CATEGORY_CONSONANT_SUCCEEDING_REPHA	/*   5 chars; Consonant_Succeeding_Repha */
 #define ISC_CWS	INDIC_SYLLABIC_CATEGORY_CONSONANT_WITH_STACKER	/*   4 chars; Consonant_With_Stacker */
-#define ISC_GM	INDIC_SYLLABIC_CATEGORY_GEMINATION_MARK		/*   2 chars; Gemination_Mark */
-#define ISC_IS	INDIC_SYLLABIC_CATEGORY_INVISIBLE_STACKER	/*   7 chars; Invisible_Stacker */
+#define ISC_GM	INDIC_SYLLABIC_CATEGORY_GEMINATION_MARK		/*   3 chars; Gemination_Mark */
+#define ISC_IS	INDIC_SYLLABIC_CATEGORY_INVISIBLE_STACKER	/*  10 chars; Invisible_Stacker */
 #define ISC_ZWJ	INDIC_SYLLABIC_CATEGORY_JOINER			/*   1 chars; Joiner */
 #define ISC_ML	INDIC_SYLLABIC_CATEGORY_MODIFYING_LETTER	/*   1 chars; Modifying_Letter */
 #define ISC_ZWNJ	INDIC_SYLLABIC_CATEGORY_NON_JOINER		/*   1 chars; Non_Joiner */
-#define ISC_N	INDIC_SYLLABIC_CATEGORY_NUKTA			/*  24 chars; Nukta */
-#define ISC_Nd	INDIC_SYLLABIC_CATEGORY_NUMBER			/* 459 chars; Number */
+#define ISC_N	INDIC_SYLLABIC_CATEGORY_NUKTA			/*  28 chars; Nukta */
+#define ISC_Nd	INDIC_SYLLABIC_CATEGORY_NUMBER			/* 469 chars; Number */
 #define ISC_NJ	INDIC_SYLLABIC_CATEGORY_NUMBER_JOINER		/*   1 chars; Number_Joiner */
 #define ISC_x	INDIC_SYLLABIC_CATEGORY_OTHER			/*   1 chars; Other */
-#define ISC_PK	INDIC_SYLLABIC_CATEGORY_PURE_KILLER		/*  16 chars; Pure_Killer */
+#define ISC_PK	INDIC_SYLLABIC_CATEGORY_PURE_KILLER		/*  21 chars; Pure_Killer */
 #define ISC_RS	INDIC_SYLLABIC_CATEGORY_REGISTER_SHIFTER	/*   2 chars; Register_Shifter */
 #define ISC_SM	INDIC_SYLLABIC_CATEGORY_SYLLABLE_MODIFIER	/*  22 chars; Syllable_Modifier */
 #define ISC_TL	INDIC_SYLLABIC_CATEGORY_TONE_LETTER		/*   7 chars; Tone_Letter */
 #define ISC_TM	INDIC_SYLLABIC_CATEGORY_TONE_MARK		/*  42 chars; Tone_Mark */
 #define ISC_V	INDIC_SYLLABIC_CATEGORY_VIRAMA			/*  24 chars; Virama */
-#define ISC_Vs	INDIC_SYLLABIC_CATEGORY_VISARGA			/*  31 chars; Visarga */
+#define ISC_Vs	INDIC_SYLLABIC_CATEGORY_VISARGA			/*  34 chars; Visarga */
 #define ISC_Vo	INDIC_SYLLABIC_CATEGORY_VOWEL			/*  30 chars; Vowel */
-#define ISC_M	INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT		/* 602 chars; Vowel_Dependent */
-#define ISC_VI	INDIC_SYLLABIC_CATEGORY_VOWEL_INDEPENDENT	/* 431 chars; Vowel_Independent */
+#define ISC_M	INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT		/* 633 chars; Vowel_Dependent */
+#define ISC_VI	INDIC_SYLLABIC_CATEGORY_VOWEL_INDEPENDENT	/* 443 chars; Vowel_Independent */
 
-#define IMC_B	INDIC_MATRA_CATEGORY_BOTTOM			/* 300 chars; Bottom */
+#define IMC_B	INDIC_MATRA_CATEGORY_BOTTOM			/* 330 chars; Bottom */
+#define IMC_BL	INDIC_MATRA_CATEGORY_BOTTOM_AND_LEFT		/*   1 chars; Bottom_And_Left */
 #define IMC_BR	INDIC_MATRA_CATEGORY_BOTTOM_AND_RIGHT		/*   2 chars; Bottom_And_Right */
 #define IMC_L	INDIC_MATRA_CATEGORY_LEFT			/*  57 chars; Left */
 #define IMC_LR	INDIC_MATRA_CATEGORY_LEFT_AND_RIGHT		/*  21 chars; Left_And_Right */
 #define IMC_x	INDIC_MATRA_CATEGORY_NOT_APPLICABLE		/*   1 chars; Not_Applicable */
 #define IMC_O	INDIC_MATRA_CATEGORY_OVERSTRUCK			/*  10 chars; Overstruck */
-#define IMC_R	INDIC_MATRA_CATEGORY_RIGHT			/* 258 chars; Right */
-#define IMC_T	INDIC_MATRA_CATEGORY_TOP			/* 342 chars; Top */
+#define IMC_R	INDIC_MATRA_CATEGORY_RIGHT			/* 262 chars; Right */
+#define IMC_T	INDIC_MATRA_CATEGORY_TOP			/* 380 chars; Top */
 #define IMC_TB	INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM		/*  10 chars; Top_And_Bottom */
 #define IMC_TBR	INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM_AND_RIGHT	/*   1 chars; Top_And_Bottom_And_Right */
 #define IMC_TL	INDIC_MATRA_CATEGORY_TOP_AND_LEFT		/*   6 chars; Top_And_Left */
 #define IMC_TLR	INDIC_MATRA_CATEGORY_TOP_AND_LEFT_AND_RIGHT	/*   4 chars; Top_And_Left_And_Right */
 #define IMC_TR	INDIC_MATRA_CATEGORY_TOP_AND_RIGHT		/*  13 chars; Top_And_Right */
 #define IMC_VOL	INDIC_MATRA_CATEGORY_VISUAL_ORDER_LEFT		/*  19 chars; Visual_Order_Left */
 
 #define _(S,M) INDIC_COMBINE_CATEGORIES (ISC_##S, IMC_##M)
@@ -128,17 +129,17 @@ static const INDIC_TABLE_ELEMENT_TYPE in
   /* 09B8 */  _(C,x),  _(C,x),  _(x,x),  _(x,x),  _(N,B),  _(A,x),  _(M,R),  _(M,L),
   /* 09C0 */  _(M,R),  _(M,B),  _(M,B),  _(M,B),  _(M,B),  _(x,x),  _(x,x),  _(M,L),
   /* 09C8 */  _(M,L),  _(x,x),  _(x,x), _(M,LR), _(M,LR),  _(V,B), _(CD,x),  _(x,x),
   /* 09D0 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(M,R),
   /* 09D8 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(C,x),  _(C,x),  _(x,x),  _(C,x),
   /* 09E0 */ _(VI,x), _(VI,x),  _(M,B),  _(M,B),  _(x,x),  _(x,x), _(Nd,x), _(Nd,x),
   /* 09E8 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
   /* 09F0 */  _(C,x),  _(C,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
-  /* 09F8 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 09F8 */  _(x,x),  _(x,x),  _(x,x),  _(x,x), _(Bi,x),  _(x,x),  _(x,x),  _(x,x),
 
   /* Gurmukhi */
 
   /* 0A00 */  _(x,x), _(Bi,T), _(Bi,T), _(Vs,R),  _(x,x), _(VI,x), _(VI,x), _(VI,x),
   /* 0A08 */ _(VI,x), _(VI,x), _(VI,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x), _(VI,x),
   /* 0A10 */ _(VI,x),  _(x,x),  _(x,x), _(VI,x), _(VI,x),  _(C,x),  _(C,x),  _(C,x),
   /* 0A18 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
   /* 0A20 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
@@ -166,17 +167,17 @@ static const INDIC_TABLE_ELEMENT_TYPE in
   /* 0AB8 */  _(C,x),  _(C,x),  _(x,x),  _(x,x),  _(N,B),  _(A,x),  _(M,R),  _(M,L),
   /* 0AC0 */  _(M,R),  _(M,B),  _(M,B),  _(M,B),  _(M,B),  _(M,T),  _(x,x),  _(M,T),
   /* 0AC8 */  _(M,T), _(M,TR),  _(x,x),  _(M,R),  _(M,R),  _(V,B),  _(x,x),  _(x,x),
   /* 0AD0 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
   /* 0AD8 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
   /* 0AE0 */ _(VI,x), _(VI,x),  _(M,B),  _(M,B),  _(x,x),  _(x,x), _(Nd,x), _(Nd,x),
   /* 0AE8 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
   /* 0AF0 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
-  /* 0AF8 */  _(x,x),  _(C,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 0AF8 */  _(x,x),  _(C,x), _(Ca,T), _(Ca,T), _(Ca,T),  _(N,T),  _(N,T),  _(N,T),
 
   /* Oriya */
 
   /* 0B00 */  _(x,x), _(Bi,T), _(Bi,R), _(Vs,R),  _(x,x), _(VI,x), _(VI,x), _(VI,x),
   /* 0B08 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),  _(x,x),  _(x,x), _(VI,x),
   /* 0B10 */ _(VI,x),  _(x,x),  _(x,x), _(VI,x), _(VI,x),  _(C,x),  _(C,x),  _(C,x),
   /* 0B18 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
   /* 0B20 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
@@ -246,24 +247,24 @@ static const INDIC_TABLE_ELEMENT_TYPE in
   /* 0CD8 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(C,x),  _(x,x),
   /* 0CE0 */ _(VI,x), _(VI,x),  _(M,B),  _(M,B),  _(x,x),  _(x,x), _(Nd,x), _(Nd,x),
   /* 0CE8 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
   /* 0CF0 */  _(x,x),_(CWS,x),_(CWS,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
   /* 0CF8 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
 
   /* Malayalam */
 
-  /* 0D00 */  _(x,x), _(Bi,T), _(Bi,R), _(Vs,R),  _(x,x), _(VI,x), _(VI,x), _(VI,x),
+  /* 0D00 */ _(Bi,T), _(Bi,T), _(Bi,R), _(Vs,R),  _(x,x), _(VI,x), _(VI,x), _(VI,x),
   /* 0D08 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),  _(x,x), _(VI,x), _(VI,x),
   /* 0D10 */ _(VI,x),  _(x,x), _(VI,x), _(VI,x), _(VI,x),  _(C,x),  _(C,x),  _(C,x),
   /* 0D18 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
   /* 0D20 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
   /* 0D28 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
   /* 0D30 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
-  /* 0D38 */  _(C,x),  _(C,x),  _(C,x),  _(x,x),  _(x,x),  _(A,x),  _(M,R),  _(M,R),
+  /* 0D38 */  _(C,x),  _(C,x),  _(C,x), _(PK,T), _(PK,T),  _(A,x),  _(M,R),  _(M,R),
   /* 0D40 */  _(M,R),  _(M,R),  _(M,R),  _(M,B),  _(M,B),  _(x,x),  _(M,L),  _(M,L),
   /* 0D48 */  _(M,L),  _(x,x), _(M,LR), _(M,LR), _(M,LR),  _(V,T),_(CPR,x),  _(x,x),
   /* 0D50 */  _(x,x),  _(x,x),  _(x,x),  _(x,x), _(CD,x), _(CD,x), _(CD,x),  _(M,R),
   /* 0D58 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x), _(VI,x),
   /* 0D60 */ _(VI,x), _(VI,x),  _(M,B),  _(M,B),  _(x,x),  _(x,x), _(Nd,x), _(Nd,x),
   /* 0D68 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
   /* 0D70 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
   /* 0D78 */  _(x,x),  _(x,x), _(CD,x), _(CD,x), _(CD,x), _(CD,x), _(CD,x), _(CD,x),
@@ -336,17 +337,17 @@ static const INDIC_TABLE_ELEMENT_TYPE in
 
 
   /* Vedic Extensions */
 
   /* 1CD0 */ _(Ca,T), _(Ca,T), _(Ca,T),  _(x,x), _(Ca,O), _(Ca,B), _(Ca,B), _(Ca,B),
   /* 1CD8 */ _(Ca,B), _(Ca,B), _(Ca,T), _(Ca,T), _(Ca,B), _(Ca,B), _(Ca,B), _(Ca,B),
   /* 1CE0 */ _(Ca,T), _(Ca,R),  _(x,O),  _(x,O),  _(x,O),  _(x,O),  _(x,O),  _(x,O),
   /* 1CE8 */  _(x,O),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,B),  _(x,x),  _(x,x),
-  /* 1CF0 */  _(x,x),  _(x,x), _(Vs,x), _(Vs,x), _(Ca,T),  _(x,x),  _(x,x),  _(x,x),
+  /* 1CF0 */  _(x,x),  _(x,x), _(Vs,x), _(Vs,x), _(Ca,T),  _(x,x),  _(x,x), _(Ca,R),
   /* 1CF8 */ _(Ca,x), _(Ca,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
 
 #define indic_offset_0x2008u 1656
 
 
   /* General Punctuation */
 
   /* 2008 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),_(ZWNJ,x),_(ZWJ,x),  _(x,x),  _(x,x),
@@ -363,17 +364,17 @@ static const INDIC_TABLE_ELEMENT_TYPE in
 
 #define indic_offset_0xa8e0u 1696
 
 
   /* Devanagari Extended */
 
   /* A8E0 */ _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T),
   /* A8E8 */ _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T),
-  /* A8F0 */ _(Ca,T), _(Ca,T),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* A8F0 */ _(Ca,T), _(Ca,T), _(Bi,x), _(Bi,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
 
 #define indic_offset_0xa9e0u 1720
 
 
   /* Myanmar Extended-B */
 
   /* A9E0 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(M,T),  _(x,x),  _(C,x),
   /* A9E8 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
@@ -385,17 +386,17 @@ static const INDIC_TABLE_ELEMENT_TYPE in
 
   /* Myanmar Extended-A */
 
   /* AA60 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
   /* AA68 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
   /* AA70 */  _(x,x),  _(C,x),  _(C,x),  _(C,x), _(CP,x), _(CP,x), _(CP,x),  _(x,x),
   /* AA78 */  _(x,x),  _(x,x),  _(C,x), _(TM,R), _(TM,T), _(TM,R),  _(C,x),  _(C,x),
 
-}; /* Table items: 1784; occupancy: 69% */
+}; /* Table items: 1784; occupancy: 70% */
 
 INDIC_TABLE_ELEMENT_TYPE
 hb_indic_get_categories (hb_codepoint_t u)
 {
   switch (u >> 12)
   {
     case 0x0u:
       if (hb_in_range<hb_codepoint_t> (u, 0x0028u, 0x003Fu)) return indic_table[u - 0x0028u + indic_offset_0x0028u];
@@ -417,23 +418,16 @@ hb_indic_get_categories (hb_codepoint_t 
       break;
 
     case 0xAu:
       if (hb_in_range<hb_codepoint_t> (u, 0xA8E0u, 0xA8F7u)) return indic_table[u - 0xA8E0u + indic_offset_0xa8e0u];
       if (hb_in_range<hb_codepoint_t> (u, 0xA9E0u, 0xA9FFu)) return indic_table[u - 0xA9E0u + indic_offset_0xa9e0u];
       if (hb_in_range<hb_codepoint_t> (u, 0xAA60u, 0xAA7Fu)) return indic_table[u - 0xAA60u + indic_offset_0xaa60u];
       break;
 
-    case 0x11u:
-      // According to ScriptExtensions.txt, these Grantha marks may also be used in Tamil,
-      // so the Indic shaper needs to know their categories.
-      if (unlikely (u == 0x11303)) return _(Vs,R);
-      if (unlikely (u == 0x1133c)) return _(N,B);
-      break;
-
     default:
       break;
   }
   return _(x,x);
 }
 
 #undef _
 
@@ -469,16 +463,17 @@ hb_indic_get_categories (hb_codepoint_t 
 #undef ISC_TM
 #undef ISC_V
 #undef ISC_Vs
 #undef ISC_Vo
 #undef ISC_M
 #undef ISC_VI
 
 #undef IMC_B
+#undef IMC_BL
 #undef IMC_BR
 #undef IMC_L
 #undef IMC_LR
 #undef IMC_x
 #undef IMC_O
 #undef IMC_R
 #undef IMC_T
 #undef IMC_TB
--- a/gfx/harfbuzz/src/hb-ot-shape-complex-indic.cc
+++ b/gfx/harfbuzz/src/hb-ot-shape-complex-indic.cc
@@ -203,17 +203,31 @@ set_indic_properties (hb_glyph_info_t &i
   else if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x17CDu, 0x17D1u) ||
 		     u == 0x17CBu || u == 0x17D3u || u == 0x17DDu)) /* Khmer Various signs */
   {
     /* These can occur mid-syllable (eg. before matras), even though Unicode marks them as Syllable_Modifier.
      * https://github.com/roozbehp/unicode-data/issues/5 */
     cat = OT_M;
     pos = POS_ABOVE_C;
   }
+  else if (unlikely (u == 0x0A51u))
+  {
+    /* https://github.com/behdad/harfbuzz/issues/524 */
+    cat = OT_M;
+    pos = POS_BELOW_C;
+  }
 
+  /* According to ScriptExtensions.txt, these Grantha marks may also be used in Tamil,
+   * so the Indic shaper needs to know their categories. */
+  else if (unlikely (u == 0x11303u)) cat = OT_SM;
+  else if (unlikely (u == 0x1133cu)) cat = OT_N;
+
+  else if (unlikely (u == 0x0AFBu)) cat = OT_N; /* https://github.com/behdad/harfbuzz/issues/552 */
+
+  else if (unlikely (u == 0x0980u)) cat = OT_PLACEHOLDER; /* https://github.com/behdad/harfbuzz/issues/538 */
   else if (unlikely (u == 0x17C6u)) cat = OT_N; /* Khmer Bindu doesn't like to be repositioned. */
   else if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x2010u, 0x2011u)))
 				    cat = OT_PLACEHOLDER;
   else if (unlikely (u == 0x25CCu)) cat = OT_DOTTEDCIRCLE;
 
 
   /*
    * Re-assign position.
@@ -672,16 +686,31 @@ static void
 initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
 				       hb_face_t *face,
 				       hb_buffer_t *buffer,
 				       unsigned int start, unsigned int end)
 {
   const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data;
   hb_glyph_info_t *info = buffer->info;
 
+  /* https://github.com/behdad/harfbuzz/issues/435#issuecomment-335560167
+   * // For compatibility with legacy useage in Kannada,
+   * // Ra+h+ZWJ must behave like Ra+ZWJ+h...
+   */
+  if (buffer->props.script == HB_SCRIPT_KANNADA &&
+      start + 3 <= end &&
+      is_one_of (info[start  ], FLAG (OT_Ra)) &&
+      is_one_of (info[start+1], FLAG (OT_H)) &&
+      is_one_of (info[start+2], FLAG (OT_ZWJ)))
+  {
+    buffer->merge_clusters (start+1, start+3);
+    hb_glyph_info_t tmp = info[start+1];
+    info[start+1] = info[start+2];
+    info[start+2] = tmp;
+  }
 
   /* 1. Find base consonant:
    *
    * The shaping engine finds the base consonant of the syllable, using the
    * following algorithm: starting from the end of the syllable, move backwards
    * until a consonant is found that does not have a below-base or post-base
    * form (post-base forms have to follow below-base forms), or that is not a
    * pre-base reordering Ra, or arrive at the first consonant. The consonant
@@ -837,18 +866,18 @@ initial_reordering_consonant_syllable (c
       /* Have no other consonant, so Reph is not formed and Ra becomes base. */
       has_reph = false;
     }
   }
 
 
   /* 2. Decompose and reorder Matras:
    *
-   * Each matra and any syllable modifier sign in the cluster are moved to the
-   * appropriate position relative to the consonant(s) in the cluster. The
+   * Each matra and any syllable modifier sign in the syllable are moved to the
+   * appropriate position relative to the consonant(s) in the syllable. The
    * shaping engine decomposes two- or three-part matras into their constituent
    * parts before any repositioning. Matra characters are classified by which
    * consonant in a conjunct they have affinity for and are reordered to the
    * following positions:
    *
    *   o Before first half form in the syllable
    *   o After subjoined consonants
    *   o After post-form consonant
@@ -1264,17 +1293,17 @@ final_reordering_syllable (const hb_ot_s
 			   hb_buffer_t *buffer,
 			   unsigned int start, unsigned int end)
 {
   const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data;
   hb_glyph_info_t *info = buffer->info;
 
 
   /* This function relies heavily on halant glyphs.  Lots of ligation
-   * and possibly multiplication substitutions happened prior to this
+   * and possibly multiple substitutions happened prior to this
    * phase, and that might have messed up our properties.  Recover
    * from a particular case of that where we're fairly sure that a
    * class of OT_H is desired but has been lost. */
   if (indic_plan->virama_glyph)
   {
     unsigned int virama_glyph = indic_plan->virama_glyph;
     for (unsigned int i = start; i < end; i++)
       if (info[i].codepoint == virama_glyph &&
@@ -1288,17 +1317,17 @@ final_reordering_syllable (const hb_ot_s
   }
 
 
   /* 4. Final reordering:
    *
    * After the localized forms and basic shaping forms GSUB features have been
    * applied (see below), the shaping engine performs some final glyph
    * reordering before applying all the remaining font features to the entire
-   * cluster.
+   * syllable.
    */
 
   bool try_pref = !!indic_plan->mask_array[PREF];
 
   /* Find base again */
   unsigned int base;
   for (base = start; base < end; base++)
     if (info[base].indic_position() >= POS_BASE_C)
@@ -1671,18 +1700,18 @@ final_reordering_syllable (const hb_ot_s
   {
     switch ((hb_tag_t) plan->props.script)
     {
       case HB_SCRIPT_TAMIL:
       case HB_SCRIPT_SINHALA:
         break;
 
       default:
-	/* Uniscribe merges the entire cluster... Except for Tamil & Sinhala.
-	 * This means, half forms are submerged into the main consonants cluster.
+	/* Uniscribe merges the entire syllable into a single cluster... Except for Tamil & Sinhala.
+	 * This means, half forms are submerged into the main consonant's cluster.
 	 * This is unnecessary, and makes cursor positioning harder, but that's what
 	 * Uniscribe does. */
 	buffer->merge_clusters (start, end);
 	break;
     }
   }
 }
 
@@ -1821,11 +1850,12 @@ const hb_ot_complex_shaper_t _hb_ot_comp
   data_destroy_indic,
   NULL, /* preprocess_text */
   NULL, /* postprocess_glyphs */
   HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT,
   decompose_indic,
   compose_indic,
   setup_masks_indic,
   NULL, /* disable_otl */
+  NULL, /* reorder_marks */
   HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
   false, /* fallback_position */
 };
--- a/gfx/harfbuzz/src/hb-ot-shape-complex-myanmar-machine.hh
+++ b/gfx/harfbuzz/src/hb-ot-shape-complex-myanmar-machine.hh
@@ -29,248 +29,252 @@
 #ifndef HB_OT_SHAPE_COMPLEX_MYANMAR_MACHINE_HH
 #define HB_OT_SHAPE_COMPLEX_MYANMAR_MACHINE_HH
 
 #include "hb-private.hh"
 
 
 #line 36 "hb-ot-shape-complex-myanmar-machine.hh"
 static const unsigned char _myanmar_syllable_machine_trans_keys[] = {
-	1u, 31u, 3u, 30u, 5u, 29u, 5u, 8u, 5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u, 
+	1u, 32u, 3u, 30u, 5u, 29u, 5u, 8u, 5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u, 
 	3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 1u, 16u, 3u, 29u, 3u, 29u, 3u, 29u, 
 	3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 5u, 29u, 5u, 8u, 
 	5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 
-	3u, 30u, 3u, 29u, 1u, 30u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 
-	3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 8u, 8u, 0
+	3u, 30u, 3u, 29u, 1u, 32u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 
+	3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 1u, 32u, 8u, 8u, 0
 };
 
 static const char _myanmar_syllable_machine_key_spans[] = {
-	31, 28, 25, 4, 25, 23, 21, 21, 
+	32, 28, 25, 4, 25, 23, 21, 21, 
 	27, 27, 27, 27, 16, 27, 27, 27, 
 	27, 27, 27, 27, 27, 27, 25, 4, 
 	25, 23, 21, 21, 27, 27, 27, 27, 
-	28, 27, 30, 27, 27, 27, 27, 27, 
-	27, 27, 27, 27, 1
+	28, 27, 32, 27, 27, 27, 27, 27, 
+	27, 27, 27, 27, 32, 1
 };
 
 static const short _myanmar_syllable_machine_index_offsets[] = {
-	0, 32, 61, 87, 92, 118, 142, 164, 
-	186, 214, 242, 270, 298, 315, 343, 371, 
-	399, 427, 455, 483, 511, 539, 567, 593, 
-	598, 624, 648, 670, 692, 720, 748, 776, 
-	804, 833, 861, 892, 920, 948, 976, 1004, 
-	1032, 1060, 1088, 1116, 1144
+	0, 33, 62, 88, 93, 119, 143, 165, 
+	187, 215, 243, 271, 299, 316, 344, 372, 
+	400, 428, 456, 484, 512, 540, 568, 594, 
+	599, 625, 649, 671, 693, 721, 749, 777, 
+	805, 834, 862, 895, 923, 951, 979, 1007, 
+	1035, 1063, 1091, 1119, 1147, 1180
 };
 
 static const char _myanmar_syllable_machine_indicies[] = {
 	1, 1, 2, 3, 4, 4, 0, 5, 
 	0, 6, 1, 0, 0, 0, 0, 7, 
-	0, 8, 1, 0, 9, 10, 11, 12, 
-	13, 14, 15, 16, 17, 18, 19, 0, 
-	21, 22, 23, 23, 20, 24, 20, 25, 
-	20, 20, 20, 20, 20, 20, 20, 26, 
-	20, 20, 27, 28, 29, 30, 31, 32, 
-	33, 34, 35, 36, 20, 23, 23, 20, 
-	24, 20, 20, 20, 20, 20, 20, 20, 
-	20, 20, 37, 20, 20, 20, 20, 20, 
-	20, 31, 20, 20, 20, 35, 20, 23, 
-	23, 20, 24, 20, 23, 23, 20, 24, 
-	20, 20, 20, 20, 20, 20, 20, 20, 
-	20, 20, 20, 20, 20, 20, 20, 20, 
-	31, 20, 20, 20, 35, 20, 38, 20, 
-	23, 23, 20, 24, 20, 31, 20, 20, 
-	20, 20, 20, 20, 20, 39, 20, 20, 
-	20, 20, 20, 20, 31, 20, 23, 23, 
-	20, 24, 20, 20, 20, 20, 20, 20, 
-	20, 20, 20, 39, 20, 20, 20, 20, 
-	20, 20, 31, 20, 23, 23, 20, 24, 
-	20, 20, 20, 20, 20, 20, 20, 20, 
-	20, 20, 20, 20, 20, 20, 20, 20, 
-	31, 20, 21, 20, 23, 23, 20, 24, 
-	20, 25, 20, 20, 20, 20, 20, 20, 
-	20, 40, 20, 20, 40, 20, 20, 20, 
-	31, 41, 20, 20, 35, 20, 21, 20, 
-	23, 23, 20, 24, 20, 25, 20, 20, 
-	20, 20, 20, 20, 20, 20, 20, 20, 
-	20, 20, 20, 20, 31, 20, 20, 20, 
-	35, 20, 21, 20, 23, 23, 20, 24, 
-	20, 25, 20, 20, 20, 20, 20, 20, 
-	20, 40, 20, 20, 20, 20, 20, 20, 
-	31, 41, 20, 20, 35, 20, 21, 20, 
-	23, 23, 20, 24, 20, 25, 20, 20, 
-	20, 20, 20, 20, 20, 20, 20, 20, 
-	20, 20, 20, 20, 31, 41, 20, 20, 
-	35, 20, 1, 1, 20, 20, 20, 20, 
-	20, 20, 20, 20, 20, 20, 20, 20, 
-	20, 1, 20, 21, 20, 23, 23, 20, 
-	24, 20, 25, 20, 20, 20, 20, 20, 
-	20, 20, 26, 20, 20, 27, 28, 29, 
-	30, 31, 32, 33, 34, 35, 20, 21, 
-	20, 23, 23, 20, 24, 20, 25, 20, 
-	20, 20, 20, 20, 20, 20, 34, 20, 
-	20, 20, 20, 20, 20, 31, 32, 33, 
-	34, 35, 20, 21, 20, 23, 23, 20, 
-	24, 20, 25, 20, 20, 20, 20, 20, 
-	20, 20, 20, 20, 20, 20, 20, 20, 
-	20, 31, 32, 33, 34, 35, 20, 21, 
-	20, 23, 23, 20, 24, 20, 25, 20, 
-	20, 20, 20, 20, 20, 20, 20, 20, 
-	20, 20, 20, 20, 20, 31, 32, 33, 
-	20, 35, 20, 21, 20, 23, 23, 20, 
-	24, 20, 25, 20, 20, 20, 20, 20, 
-	20, 20, 20, 20, 20, 20, 20, 20, 
-	20, 31, 20, 33, 20, 35, 20, 21, 
-	20, 23, 23, 20, 24, 20, 25, 20, 
-	20, 20, 20, 20, 20, 20, 34, 20, 
-	20, 27, 20, 29, 20, 31, 32, 33, 
-	34, 35, 20, 21, 20, 23, 23, 20, 
-	24, 20, 25, 20, 20, 20, 20, 20, 
-	20, 20, 34, 20, 20, 27, 20, 20, 
-	20, 31, 32, 33, 34, 35, 20, 21, 
-	20, 23, 23, 20, 24, 20, 25, 20, 
-	20, 20, 20, 20, 20, 20, 34, 20, 
-	20, 27, 28, 29, 20, 31, 32, 33, 
-	34, 35, 20, 21, 22, 23, 23, 20, 
-	24, 20, 25, 20, 20, 20, 20, 20, 
-	20, 20, 26, 20, 20, 27, 28, 29, 
-	30, 31, 32, 33, 34, 35, 20, 3, 
-	3, 42, 5, 42, 42, 42, 42, 42, 
-	42, 42, 42, 42, 43, 42, 42, 42, 
-	42, 42, 42, 13, 42, 42, 42, 17, 
-	42, 3, 3, 42, 5, 42, 3, 3, 
-	42, 5, 42, 42, 42, 42, 42, 42, 
-	42, 42, 42, 42, 42, 42, 42, 42, 
-	42, 42, 13, 42, 42, 42, 17, 42, 
-	44, 42, 3, 3, 42, 5, 42, 13, 
-	42, 42, 42, 42, 42, 42, 42, 45, 
-	42, 42, 42, 42, 42, 42, 13, 42, 
-	3, 3, 42, 5, 42, 42, 42, 42, 
-	42, 42, 42, 42, 42, 45, 42, 42, 
-	42, 42, 42, 42, 13, 42, 3, 3, 
-	42, 5, 42, 42, 42, 42, 42, 42, 
-	42, 42, 42, 42, 42, 42, 42, 42, 
-	42, 42, 13, 42, 2, 42, 3, 3, 
-	42, 5, 42, 6, 42, 42, 42, 42, 
-	42, 42, 42, 46, 42, 42, 46, 42, 
-	42, 42, 13, 47, 42, 42, 17, 42, 
-	2, 42, 3, 3, 42, 5, 42, 6, 
-	42, 42, 42, 42, 42, 42, 42, 42, 
-	42, 42, 42, 42, 42, 42, 13, 42, 
-	42, 42, 17, 42, 2, 42, 3, 3, 
-	42, 5, 42, 6, 42, 42, 42, 42, 
-	42, 42, 42, 46, 42, 42, 42, 42, 
-	42, 42, 13, 47, 42, 42, 17, 42, 
-	2, 42, 3, 3, 42, 5, 42, 6, 
-	42, 42, 42, 42, 42, 42, 42, 42, 
-	42, 42, 42, 42, 42, 42, 13, 47, 
-	42, 42, 17, 42, 21, 22, 23, 23, 
-	20, 24, 20, 25, 20, 20, 20, 20, 
-	20, 20, 20, 48, 20, 20, 27, 28, 
+	0, 8, 9, 0, 10, 11, 12, 13, 
+	14, 15, 16, 17, 18, 19, 20, 1, 
+	0, 22, 23, 24, 24, 21, 25, 21, 
+	26, 21, 21, 21, 21, 21, 21, 21, 
+	27, 21, 21, 28, 29, 30, 31, 32, 
+	33, 34, 35, 36, 37, 21, 24, 24, 
+	21, 25, 21, 21, 21, 21, 21, 21, 
+	21, 21, 21, 38, 21, 21, 21, 21, 
+	21, 21, 32, 21, 21, 21, 36, 21, 
+	24, 24, 21, 25, 21, 24, 24, 21, 
+	25, 21, 21, 21, 21, 21, 21, 21, 
+	21, 21, 21, 21, 21, 21, 21, 21, 
+	21, 32, 21, 21, 21, 36, 21, 39, 
+	21, 24, 24, 21, 25, 21, 32, 21, 
+	21, 21, 21, 21, 21, 21, 40, 21, 
+	21, 21, 21, 21, 21, 32, 21, 24, 
+	24, 21, 25, 21, 21, 21, 21, 21, 
+	21, 21, 21, 21, 40, 21, 21, 21, 
+	21, 21, 21, 32, 21, 24, 24, 21, 
+	25, 21, 21, 21, 21, 21, 21, 21, 
+	21, 21, 21, 21, 21, 21, 21, 21, 
+	21, 32, 21, 22, 21, 24, 24, 21, 
+	25, 21, 26, 21, 21, 21, 21, 21, 
+	21, 21, 41, 21, 21, 41, 21, 21, 
+	21, 32, 42, 21, 21, 36, 21, 22, 
+	21, 24, 24, 21, 25, 21, 26, 21, 
+	21, 21, 21, 21, 21, 21, 21, 21, 
+	21, 21, 21, 21, 21, 32, 21, 21, 
+	21, 36, 21, 22, 21, 24, 24, 21, 
+	25, 21, 26, 21, 21, 21, 21, 21, 
+	21, 21, 41, 21, 21, 21, 21, 21, 
+	21, 32, 42, 21, 21, 36, 21, 22, 
+	21, 24, 24, 21, 25, 21, 26, 21, 
+	21, 21, 21, 21, 21, 21, 21, 21, 
+	21, 21, 21, 21, 21, 32, 42, 21, 
+	21, 36, 21, 1, 1, 21, 21, 21, 
+	21, 21, 21, 21, 21, 21, 21, 21, 
+	21, 21, 1, 21, 22, 21, 24, 24, 
+	21, 25, 21, 26, 21, 21, 21, 21, 
+	21, 21, 21, 27, 21, 21, 28, 29, 
+	30, 31, 32, 33, 34, 35, 36, 21, 
+	22, 21, 24, 24, 21, 25, 21, 26, 
+	21, 21, 21, 21, 21, 21, 21, 35, 
+	21, 21, 21, 21, 21, 21, 32, 33, 
+	34, 35, 36, 21, 22, 21, 24, 24, 
+	21, 25, 21, 26, 21, 21, 21, 21, 
+	21, 21, 21, 21, 21, 21, 21, 21, 
+	21, 21, 32, 33, 34, 35, 36, 21, 
+	22, 21, 24, 24, 21, 25, 21, 26, 
+	21, 21, 21, 21, 21, 21, 21, 21, 
+	21, 21, 21, 21, 21, 21, 32, 33, 
+	34, 21, 36, 21, 22, 21, 24, 24, 
+	21, 25, 21, 26, 21, 21, 21, 21, 
+	21, 21, 21, 21, 21, 21, 21, 21, 
+	21, 21, 32, 21, 34, 21, 36, 21, 
+	22, 21, 24, 24, 21, 25, 21, 26, 
+	21, 21, 21, 21, 21, 21, 21, 35, 
+	21, 21, 28, 21, 30, 21, 32, 33, 
+	34, 35, 36, 21, 22, 21, 24, 24, 
+	21, 25, 21, 26, 21, 21, 21, 21, 
+	21, 21, 21, 35, 21, 21, 28, 21, 
+	21, 21, 32, 33, 34, 35, 36, 21, 
+	22, 21, 24, 24, 21, 25, 21, 26, 
+	21, 21, 21, 21, 21, 21, 21, 35, 
+	21, 21, 28, 29, 30, 21, 32, 33, 
+	34, 35, 36, 21, 22, 23, 24, 24, 
+	21, 25, 21, 26, 21, 21, 21, 21, 
+	21, 21, 21, 27, 21, 21, 28, 29, 
+	30, 31, 32, 33, 34, 35, 36, 21, 
+	3, 3, 43, 5, 43, 43, 43, 43, 
+	43, 43, 43, 43, 43, 44, 43, 43, 
+	43, 43, 43, 43, 14, 43, 43, 43, 
+	18, 43, 3, 3, 43, 5, 43, 3, 
+	3, 43, 5, 43, 43, 43, 43, 43, 
+	43, 43, 43, 43, 43, 43, 43, 43, 
+	43, 43, 43, 14, 43, 43, 43, 18, 
+	43, 45, 43, 3, 3, 43, 5, 43, 
+	14, 43, 43, 43, 43, 43, 43, 43, 
+	46, 43, 43, 43, 43, 43, 43, 14, 
+	43, 3, 3, 43, 5, 43, 43, 43, 
+	43, 43, 43, 43, 43, 43, 46, 43, 
+	43, 43, 43, 43, 43, 14, 43, 3, 
+	3, 43, 5, 43, 43, 43, 43, 43, 
+	43, 43, 43, 43, 43, 43, 43, 43, 
+	43, 43, 43, 14, 43, 2, 43, 3, 
+	3, 43, 5, 43, 6, 43, 43, 43, 
+	43, 43, 43, 43, 47, 43, 43, 47, 
+	43, 43, 43, 14, 48, 43, 43, 18, 
+	43, 2, 43, 3, 3, 43, 5, 43, 
+	6, 43, 43, 43, 43, 43, 43, 43, 
+	43, 43, 43, 43, 43, 43, 43, 14, 
+	43, 43, 43, 18, 43, 2, 43, 3, 
+	3, 43, 5, 43, 6, 43, 43, 43, 
+	43, 43, 43, 43, 47, 43, 43, 43, 
+	43, 43, 43, 14, 48, 43, 43, 18, 
+	43, 2, 43, 3, 3, 43, 5, 43, 
+	6, 43, 43, 43, 43, 43, 43, 43, 
+	43, 43, 43, 43, 43, 43, 43, 14, 
+	48, 43, 43, 18, 43, 22, 23, 24, 
+	24, 21, 25, 21, 26, 21, 21, 21, 
+	21, 21, 21, 21, 49, 21, 21, 28, 
 	29, 30, 31, 32, 33, 34, 35, 36, 
-	20, 21, 49, 23, 23, 20, 24, 20, 
-	25, 20, 20, 20, 20, 20, 20, 20, 
-	26, 20, 20, 27, 28, 29, 30, 31, 
-	32, 33, 34, 35, 20, 1, 1, 2, 
-	3, 3, 3, 42, 5, 42, 6, 1, 
-	42, 42, 42, 42, 1, 42, 8, 1, 
-	42, 9, 10, 11, 12, 13, 14, 15, 
-	16, 17, 18, 42, 2, 42, 3, 3, 
-	42, 5, 42, 6, 42, 42, 42, 42, 
-	42, 42, 42, 8, 42, 42, 9, 10, 
-	11, 12, 13, 14, 15, 16, 17, 42, 
-	2, 42, 3, 3, 42, 5, 42, 6, 
-	42, 42, 42, 42, 42, 42, 42, 16, 
-	42, 42, 42, 42, 42, 42, 13, 14, 
-	15, 16, 17, 42, 2, 42, 3, 3, 
-	42, 5, 42, 6, 42, 42, 42, 42, 
-	42, 42, 42, 42, 42, 42, 42, 42, 
-	42, 42, 13, 14, 15, 16, 17, 42, 
-	2, 42, 3, 3, 42, 5, 42, 6, 
-	42, 42, 42, 42, 42, 42, 42, 42, 
-	42, 42, 42, 42, 42, 42, 13, 14, 
-	15, 42, 17, 42, 2, 42, 3, 3, 
-	42, 5, 42, 6, 42, 42, 42, 42, 
-	42, 42, 42, 42, 42, 42, 42, 42, 
-	42, 42, 13, 42, 15, 42, 17, 42, 
-	2, 42, 3, 3, 42, 5, 42, 6, 
-	42, 42, 42, 42, 42, 42, 42, 16, 
-	42, 42, 9, 42, 11, 42, 13, 14, 
-	15, 16, 17, 42, 2, 42, 3, 3, 
-	42, 5, 42, 6, 42, 42, 42, 42, 
-	42, 42, 42, 16, 42, 42, 9, 42, 
-	42, 42, 13, 14, 15, 16, 17, 42, 
-	2, 42, 3, 3, 42, 5, 42, 6, 
-	42, 42, 42, 42, 42, 42, 42, 16, 
-	42, 42, 9, 10, 11, 42, 13, 14, 
-	15, 16, 17, 42, 2, 3, 3, 3, 
-	42, 5, 42, 6, 42, 42, 42, 42, 
-	42, 42, 42, 8, 42, 42, 9, 10, 
-	11, 12, 13, 14, 15, 16, 17, 42, 
-	51, 50, 0
+	37, 21, 22, 50, 24, 24, 21, 25, 
+	21, 26, 21, 21, 21, 21, 21, 21, 
+	21, 27, 21, 21, 28, 29, 30, 31, 
+	32, 33, 34, 35, 36, 21, 1, 1, 
+	2, 3, 3, 3, 43, 5, 43, 6, 
+	1, 43, 43, 43, 43, 1, 43, 8, 
+	43, 43, 10, 11, 12, 13, 14, 15, 
+	16, 17, 18, 19, 43, 1, 43, 2, 
+	43, 3, 3, 43, 5, 43, 6, 43, 
+	43, 43, 43, 43, 43, 43, 8, 43, 
+	43, 10, 11, 12, 13, 14, 15, 16, 
+	17, 18, 43, 2, 43, 3, 3, 43, 
+	5, 43, 6, 43, 43, 43, 43, 43, 
+	43, 43, 17, 43, 43, 43, 43, 43, 
+	43, 14, 15, 16, 17, 18, 43, 2, 
+	43, 3, 3, 43, 5, 43, 6, 43, 
+	43, 43, 43, 43, 43, 43, 43, 43, 
+	43, 43, 43, 43, 43, 14, 15, 16, 
+	17, 18, 43, 2, 43, 3, 3, 43, 
+	5, 43, 6, 43, 43, 43, 43, 43, 
+	43, 43, 43, 43, 43, 43, 43, 43, 
+	43, 14, 15, 16, 43, 18, 43, 2, 
+	43, 3, 3, 43, 5, 43, 6, 43, 
+	43, 43, 43, 43, 43, 43, 43, 43, 
+	43, 43, 43, 43, 43, 14, 43, 16, 
+	43, 18, 43, 2, 43, 3, 3, 43, 
+	5, 43, 6, 43, 43, 43, 43, 43, 
+	43, 43, 17, 43, 43, 10, 43, 12, 
+	43, 14, 15, 16, 17, 18, 43, 2, 
+	43, 3, 3, 43, 5, 43, 6, 43, 
+	43, 43, 43, 43, 43, 43, 17, 43, 
+	43, 10, 43, 43, 43, 14, 15, 16, 
+	17, 18, 43, 2, 43, 3, 3, 43, 
+	5, 43, 6, 43, 43, 43, 43, 43, 
+	43, 43, 17, 43, 43, 10, 11, 12, 
+	43, 14, 15, 16, 17, 18, 43, 2, 
+	3, 3, 3, 43, 5, 43, 6, 43, 
+	43, 43, 43, 43, 43, 43, 8, 43, 
+	43, 10, 11, 12, 13, 14, 15, 16, 
+	17, 18, 43, 1, 1, 51, 51, 51, 
+	51, 51, 51, 51, 51, 1, 51, 51, 
+	51, 51, 1, 51, 51, 51, 51, 51, 
+	51, 51, 51, 51, 51, 51, 51, 51, 
+	51, 51, 1, 51, 52, 51, 0
 };
 
 static const char _myanmar_syllable_machine_trans_targs[] = {
 	0, 1, 22, 0, 0, 23, 29, 32, 
-	35, 36, 40, 41, 42, 25, 38, 39, 
-	37, 28, 43, 44, 0, 2, 12, 0, 
-	3, 9, 13, 14, 18, 19, 20, 5, 
-	16, 17, 15, 8, 21, 4, 6, 7, 
-	10, 11, 0, 24, 26, 27, 30, 31, 
-	33, 34, 0, 0
+	35, 44, 36, 40, 41, 42, 25, 38, 
+	39, 37, 28, 43, 45, 0, 2, 12, 
+	0, 3, 9, 13, 14, 18, 19, 20, 
+	5, 16, 17, 15, 8, 21, 4, 6, 
+	7, 10, 11, 0, 24, 26, 27, 30, 
+	31, 33, 34, 0, 0
 };
 
 static const char _myanmar_syllable_machine_trans_actions[] = {
 	3, 0, 0, 4, 5, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 6, 0, 0, 7, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 6, 0, 0, 
+	7, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 8, 0, 0, 0, 0, 0, 
-	0, 0, 9, 10
+	0, 0, 0, 8, 0, 0, 0, 0, 
+	0, 0, 0, 9, 10
 };
 
 static const char _myanmar_syllable_machine_to_state_actions[] = {
 	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
 };
 
 static const char _myanmar_syllable_machine_from_state_actions[] = {
 	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, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0
+	0, 0, 0, 0, 0, 0
 };
 
 static const short _myanmar_syllable_machine_eof_trans[] = {
-	0, 21, 21, 21, 21, 21, 21, 21, 
-	21, 21, 21, 21, 21, 21, 21, 21, 
-	21, 21, 21, 21, 21, 21, 43, 43, 
-	43, 43, 43, 43, 43, 43, 43, 43, 
-	21, 21, 43, 43, 43, 43, 43, 43, 
-	43, 43, 43, 43, 51
+	0, 22, 22, 22, 22, 22, 22, 22, 
+	22, 22, 22, 22, 22, 22, 22, 22, 
+	22, 22, 22, 22, 22, 22, 44, 44, 
+	44, 44, 44, 44, 44, 44, 44, 44, 
+	22, 22, 44, 44, 44, 44, 44, 44, 
+	44, 44, 44, 44, 52, 52
 };
 
 static const int myanmar_syllable_machine_start = 0;
 static const int myanmar_syllable_machine_first_final = 0;
 static const int myanmar_syllable_machine_error = -1;
 
 static const int myanmar_syllable_machine_en_main = 0;
 
 
 #line 36 "hb-ot-shape-complex-myanmar-machine.rl"
 
 
 
-#line 93 "hb-ot-shape-complex-myanmar-machine.rl"
+#line 94 "hb-ot-shape-complex-myanmar-machine.rl"
 
 
 #define found_syllable(syllable_type) \
   HB_STMT_START { \
     if (0) fprintf (stderr, "syllable %d..%d %s\n", last, p+1, #syllable_type); \
     for (unsigned int i = last; i < p+1; i++) \
       info[i].syllable() = (syllable_serial << 4) | syllable_type; \
     last = p+1; \
@@ -280,48 +284,48 @@ static const int myanmar_syllable_machin
 
 static void
 find_syllables (hb_buffer_t *buffer)
 {
   unsigned int p, pe, eof, ts HB_UNUSED, te HB_UNUSED, act HB_UNUSED;
   int cs;
   hb_glyph_info_t *info = buffer->info;
   
-#line 289 "hb-ot-shape-complex-myanmar-machine.hh"
+#line 293 "hb-ot-shape-complex-myanmar-machine.hh"
 	{
 	cs = myanmar_syllable_machine_start;
 	ts = 0;
 	te = 0;
 	act = 0;
 	}
 
-#line 114 "hb-ot-shape-complex-myanmar-machine.rl"
+#line 115 "hb-ot-shape-complex-myanmar-machine.rl"
 
 
   p = 0;
   pe = eof = buffer->len;
 
   unsigned int last = 0;
   unsigned int syllable_serial = 1;
   
-#line 306 "hb-ot-shape-complex-myanmar-machine.hh"
+#line 310 "hb-ot-shape-complex-myanmar-machine.hh"
 	{
 	int _slen;
 	int _trans;
 	const unsigned char *_keys;
 	const char *_inds;
 	if ( p == pe )
 		goto _test_eof;
 _resume:
 	switch ( _myanmar_syllable_machine_from_state_actions[cs] ) {
 	case 2:
 #line 1 "NONE"
 	{ts = p;}
 	break;
-#line 320 "hb-ot-shape-complex-myanmar-machine.hh"
+#line 324 "hb-ot-shape-complex-myanmar-machine.hh"
 	}
 
 	_keys = _myanmar_syllable_machine_trans_keys + (cs<<1);
 	_inds = _myanmar_syllable_machine_indicies + _myanmar_syllable_machine_index_offsets[cs];
 
 	_slen = _myanmar_syllable_machine_key_spans[cs];
 	_trans = _inds[ _slen > 0 && _keys[0] <=( info[p].myanmar_category()) &&
 		( info[p].myanmar_category()) <= _keys[1] ?
@@ -330,71 +334,71 @@ find_syllables (hb_buffer_t *buffer)
 _eof_trans:
 	cs = _myanmar_syllable_machine_trans_targs[_trans];
 
 	if ( _myanmar_syllable_machine_trans_actions[_trans] == 0 )
 		goto _again;
 
 	switch ( _myanmar_syllable_machine_trans_actions[_trans] ) {
 	case 7:
-#line 85 "hb-ot-shape-complex-myanmar-machine.rl"
+#line 86 "hb-ot-shape-complex-myanmar-machine.rl"
 	{te = p+1;{ found_syllable (consonant_syllable); }}
 	break;
 	case 5:
-#line 86 "hb-ot-shape-complex-myanmar-machine.rl"
+#line 87 "hb-ot-shape-complex-myanmar-machine.rl"
 	{te = p+1;{ found_syllable (non_myanmar_cluster); }}
 	break;
 	case 10:
-#line 87 "hb-ot-shape-complex-myanmar-machine.rl"
+#line 88 "hb-ot-shape-complex-myanmar-machine.rl"
 	{te = p+1;{ found_syllable (punctuation_cluster); }}
 	break;
 	case 4:
-#line 88 "hb-ot-shape-complex-myanmar-machine.rl"
+#line 89 "hb-ot-shape-complex-myanmar-machine.rl"
 	{te = p+1;{ found_syllable (broken_cluster); }}
 	break;
 	case 3:
-#line 89 "hb-ot-shape-complex-myanmar-machine.rl"
+#line 90 "hb-ot-shape-complex-myanmar-machine.rl"
 	{te = p+1;{ found_syllable (non_myanmar_cluster); }}
 	break;
 	case 6:
-#line 85 "hb-ot-shape-complex-myanmar-machine.rl"
+#line 86 "hb-ot-shape-complex-myanmar-machine.rl"
 	{te = p;p--;{ found_syllable (consonant_syllable); }}
 	break;
 	case 8:
-#line 88 "hb-ot-shape-complex-myanmar-machine.rl"
+#line 89 "hb-ot-shape-complex-myanmar-machine.rl"
 	{te = p;p--;{ found_syllable (broken_cluster); }}
 	break;
 	case 9:
-#line 89 "hb-ot-shape-complex-myanmar-machine.rl"
+#line 90 "hb-ot-shape-complex-myanmar-machine.rl"
 	{te = p;p--;{ found_syllable (non_myanmar_cluster); }}
 	break;
-#line 370 "hb-ot-shape-complex-myanmar-machine.hh"
+#line 374 "hb-ot-shape-complex-myanmar-machine.hh"
 	}
 
 _again:
 	switch ( _myanmar_syllable_machine_to_state_actions[cs] ) {
 	case 1:
 #line 1 "NONE"
 	{ts = 0;}
 	break;
-#line 379 "hb-ot-shape-complex-myanmar-machine.hh"
+#line 383 "hb-ot-shape-complex-myanmar-machine.hh"
 	}
 
 	if ( ++p != pe )
 		goto _resume;
 	_test_eof: {}
 	if ( p == eof )
 	{
 	if ( _myanmar_syllable_machine_eof_trans[cs] > 0 ) {
 		_trans = _myanmar_syllable_machine_eof_trans[cs] - 1;
 		goto _eof_trans;
 	}
 	}
 
 	}
 
-#line 123 "hb-ot-shape-complex-myanmar-machine.rl"
+#line 124 "hb-ot-shape-complex-myanmar-machine.rl"
 
 }
 
 #undef found_syllable
 
 #endif /* HB_OT_SHAPE_COMPLEX_MYANMAR_MACHINE_HH */
--- a/gfx/harfbuzz/src/hb-ot-shape-complex-myanmar-machine.rl
+++ b/gfx/harfbuzz/src/hb-ot-shape-complex-myanmar-machine.rl
@@ -36,17 +36,17 @@
 }%%
 
 %%{
 
 # Same order as enum myanmar_category_t.  Not sure how to avoid duplication.
 A    = 10;
 As   = 18;
 C    = 1;
-D    = 19;
+D    = 32;
 D0   = 20;
 DB   = 3;
 GB   = 11;
 H    = 4;
 IV   = 2;
 MH   = 21;
 MR   = 22;
 MW   = 23;
@@ -57,31 +57,32 @@ VAbv = 26;
 VBlw = 27;
 VPre = 28;
 VPst = 29;
 VS   = 30;
 ZWJ  = 6;
 ZWNJ = 5;
 Ra   = 16;
 P    = 31;
+CS   = 19;
 
 j = ZWJ|ZWNJ;			# Joiners
 k = (Ra As H);			# Kinzi
 
 c = C|Ra;			# is_consonant
 
 medial_group = MY? MR? MW? MH? As?;
 main_vowel_group = VPre* VAbv* VBlw* A* (DB As?)?;
 post_vowel_group = VPst MH? As* VAbv* A* (DB As?)?;
 pwo_tone_group = PT A* DB? As?;
 
 complex_syllable_tail = As* medial_group main_vowel_group post_vowel_group* pwo_tone_group* V* j?;
 syllable_tail = (H | complex_syllable_tail);
 
-consonant_syllable =	k? (c|IV|D|GB).VS? (H (c|IV).VS?)* syllable_tail;
+consonant_syllable =	(k|CS)? (c|IV|D|GB).VS? (H (c|IV).VS?)* syllable_tail;
 punctuation_cluster = 	P V;
 broken_cluster =	k? VS? syllable_tail;
 other =			any;
 
 main := |*
 	consonant_syllable	=> { found_syllable (consonant_syllable); };
 	j			=> { found_syllable (non_myanmar_cluster); };
 	punctuation_cluster	=> { found_syllable (punctuation_cluster); };
--- a/gfx/harfbuzz/src/hb-ot-shape-complex-myanmar.cc
+++ b/gfx/harfbuzz/src/hb-ot-shape-complex-myanmar.cc
@@ -125,32 +125,32 @@ enum syllable_type_t {
 };
 
 #include "hb-ot-shape-complex-myanmar-machine.hh"
 
 
 /* Note: This enum is duplicated in the -machine.rl source file.
  * Not sure how to avoid duplication. */
 enum myanmar_category_t {
-  OT_As  = 18, /* Asat */
-  OT_D   = 19, /* Digits except zero */
+  OT_As  = 18,  /* Asat */
   OT_D0  = 20, /* Digit zero */
   OT_DB  = OT_N, /* Dot below */
   OT_GB  = OT_PLACEHOLDER,
   OT_MH  = 21, /* Various consonant medial types */
   OT_MR  = 22, /* Various consonant medial types */
   OT_MW  = 23, /* Various consonant medial types */
   OT_MY  = 24, /* Various consonant medial types */
   OT_PT  = 25, /* Pwo and other tones */
   OT_VAbv = 26,
   OT_VBlw = 27,
   OT_VPre = 28,
   OT_VPst = 29,
   OT_VS   = 30, /* Variation selectors */
-  OT_P    = 31  /* Punctuation */
+  OT_P    = 31, /* Punctuation */
+  OT_D    = 32, /* Digits except zero */
 };
 
 
 static inline bool
 is_one_of (const hb_glyph_info_t &info, unsigned int flags)
 {
   /* If it ligated, all bets are off. */
   if (_hb_glyph_info_ligated (&info)) return false;
@@ -519,16 +519,17 @@ const hb_ot_complex_shaper_t _hb_ot_comp
   NULL, /* data_destroy */
   NULL, /* preprocess_text */
   NULL, /* postprocess_glyphs */
   HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT,
   NULL, /* decompose */
   NULL, /* compose */
   NULL, /* setup_masks */
   NULL, /* disable_otl */
+  NULL, /* reorder_marks */
   HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
   true, /* fallback_position */
 };
 
 const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar =
 {
   "myanmar",
   collect_features_myanmar,
@@ -537,11 +538,12 @@ const hb_ot_complex_shaper_t _hb_ot_comp
   NULL, /* data_destroy */
   NULL, /* preprocess_text */
   NULL, /* postprocess_glyphs */
   HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT,
   NULL, /* decompose */
   NULL, /* compose */
   setup_masks_myanmar,
   NULL, /* disable_otl */
+  NULL, /* reorder_marks */
   HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY,
   false, /* fallback_position */
 };
--- a/gfx/harfbuzz/src/hb-ot-shape-complex-private.hh
+++ b/gfx/harfbuzz/src/hb-ot-shape-complex-private.hh
@@ -34,16 +34,18 @@
 
 
 
 /* buffer var allocations, used by complex shapers */
 #define complex_var_u8_0()	var2.u8[2]
 #define complex_var_u8_1()	var2.u8[3]
 
 
+#define HB_OT_SHAPE_COMPLEX_MAX_COMBINING_MARKS 32
+
 enum hb_ot_shape_zero_width_marks_type_t {
   HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
   HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY,
   HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE
 };
 
 
 /* Master OT shaper list */
@@ -149,16 +151,26 @@ struct hb_ot_complex_shaper_t
   /* disable_otl()
    * Called during shape().
    * If set and returns true, GDEF/GSUB/GPOS of the font are ignored
    * and fallback operations used.
    * May be NULL.
    */
   bool (*disable_otl) (const hb_ot_shape_plan_t *plan);
 
+  /* reorder_marks()
+   * Called during shape().
+   * Shapers can use to modify ordering of combining marks.
+   * May be NULL.
+   */
+  void (*reorder_marks) (const hb_ot_shape_plan_t *plan,
+			 hb_buffer_t              *buffer,
+			 unsigned int              start,
+			 unsigned int              end);
+
   hb_ot_shape_zero_width_marks_type_t zero_width_marks;
 
   bool fallback_position;
 };
 
 #define HB_COMPLEX_SHAPER_IMPLEMENT(name) extern HB_INTERNAL const hb_ot_complex_shaper_t _hb_ot_complex_shaper_##name;
 HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS
 #undef HB_COMPLEX_SHAPER_IMPLEMENT
@@ -248,20 +260,22 @@ hb_ot_shape_complex_categorize (const hb
     case HB_SCRIPT_ORIYA:
     case HB_SCRIPT_TAMIL:
     case HB_SCRIPT_TELUGU:
 
     /* Unicode-3.0 additions */
     case HB_SCRIPT_SINHALA:
 
       /* If the designer designed the font for the 'DFLT' script,
-       * use the default shaper.  Otherwise, use the specific shaper.
+       * (or we ended up arbitrarily pick 'latn'), use the default shaper.
+       * Otherwise, use the specific shaper.
        * Note that for some simple scripts, there may not be *any*
        * GSUB/GPOS needed, so there may be no scripts found! */
-      if (planner->map.chosen_script[0] == HB_TAG ('D','F','L','T'))
+      if (planner->map.chosen_script[0] == HB_TAG ('D','F','L','T') ||
+	  planner->map.chosen_script[0] == HB_TAG ('l','a','t','n'))
 	return &_hb_ot_complex_shaper_default;
       else
 	return &_hb_ot_complex_shaper_indic;
 
     case HB_SCRIPT_KHMER:
       /* A number of Khmer fonts in the wild don't have a 'pref' feature,
        * and as such won't shape properly via the Indic shaper;
        * however, they typically have 'liga' / 'clig' features that implement
@@ -357,21 +371,28 @@ hb_ot_shape_complex_categorize (const hb
     case HB_SCRIPT_AHOM:
     //case HB_SCRIPT_MULTANI:
 
     /* Unicode-9.0 additions */
     case HB_SCRIPT_BHAIKSUKI:
     case HB_SCRIPT_MARCHEN:
     case HB_SCRIPT_NEWA:
 
+    /* Unicode-10.0 additions */
+    case HB_SCRIPT_MASARAM_GONDI:
+    case HB_SCRIPT_SOYOMBO:
+    case HB_SCRIPT_ZANABAZAR_SQUARE:
+
       /* If the designer designed the font for the 'DFLT' script,
-       * use the default shaper.  Otherwise, use the specific shaper.
+       * (or we ended up arbitrarily pick 'latn'), use the default shaper.
+       * Otherwise, use the specific shaper.
        * Note that for some simple scripts, there may not be *any*
        * GSUB/GPOS needed, so there may be no scripts found! */
-      if (planner->map.chosen_script[0] == HB_TAG ('D','F','L','T'))
+      if (planner->map.chosen_script[0] == HB_TAG ('D','F','L','T') ||
+	  planner->map.chosen_script[0] == HB_TAG ('l','a','t','n'))
 	return &_hb_ot_complex_shaper_default;
       else
 	return &_hb_ot_complex_shaper_use;
   }
 }
 
 
 #endif /* HB_OT_SHAPE_COMPLEX_PRIVATE_HH */
--- a/gfx/harfbuzz/src/hb-ot-shape-complex-thai.cc
+++ b/gfx/harfbuzz/src/hb-ot-shape-complex-thai.cc
@@ -373,11 +373,12 @@ const hb_ot_complex_shaper_t _hb_ot_comp
   NULL, /* data_destroy */
   preprocess_text_thai,
   NULL, /* postprocess_glyphs */
   HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT,
   NULL, /* decompose */
   NULL, /* compose */
   NULL, /* setup_masks */
   NULL, /* disable_otl */
+  NULL, /* reorder_marks */
   HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
   false,/* fallback_position */
 };
--- a/gfx/harfbuzz/src/hb-ot-shape-complex-tibetan.cc
+++ b/gfx/harfbuzz/src/hb-ot-shape-complex-tibetan.cc
@@ -53,11 +53,12 @@ const hb_ot_complex_shaper_t _hb_ot_comp
   NULL, /* data_destroy */
   NULL, /* preprocess_text */
   NULL, /* postprocess_glyphs */
   HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT,
   NULL, /* decompose */
   NULL, /* compose */
   NULL, /* setup_masks */
   NULL, /* disable_otl */
+  NULL, /* reorder_marks */
   HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
   true, /* fallback_position */
 };
--- a/gfx/harfbuzz/src/hb-ot-shape-complex-use-machine.hh
+++ b/gfx/harfbuzz/src/hb-ot-shape-complex-use-machine.hh
@@ -31,280 +31,281 @@
 #ifndef HB_OT_SHAPE_COMPLEX_USE_MACHINE_HH
 #define HB_OT_SHAPE_COMPLEX_USE_MACHINE_HH
 
 #include "hb-private.hh"
 
 
 #line 38 "hb-ot-shape-complex-use-machine.hh"
 static const unsigned char _use_syllable_machine_trans_keys[] = {
-	1u, 1u, 0u, 39u, 21u, 21u, 8u, 39u, 8u, 39u, 1u, 1u, 8u, 39u, 8u, 39u, 
+	1u, 1u, 0u, 43u, 21u, 21u, 8u, 39u, 8u, 39u, 1u, 1u, 8u, 39u, 8u, 39u, 
 	8u, 39u, 8u, 26u, 8u, 26u, 8u, 26u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 
 	8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 
 	13u, 21u, 4u, 4u, 13u, 13u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 26u, 
 	8u, 26u, 8u, 26u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 
 	8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 1u, 1u, 1u, 39u, 8u, 39u, 
-	21u, 42u, 41u, 42u, 42u, 42u, 0
+	21u, 42u, 41u, 42u, 42u, 42u, 1u, 5u, 0
 };
 
 static const char _use_syllable_machine_key_spans[] = {
-	1, 40, 1, 32, 32, 1, 32, 32, 
+	1, 44, 1, 32, 32, 1, 32, 32, 
 	32, 19, 19, 19, 32, 32, 32, 32, 
 	32, 32, 32, 32, 32, 32, 32, 32, 
 	9, 1, 1, 32, 32, 32, 32, 19, 
 	19, 19, 32, 32, 32, 32, 32, 32, 
 	32, 32, 32, 32, 32, 1, 39, 32, 
-	22, 2, 1
+	22, 2, 1, 5
 };
 
 static const short _use_syllable_machine_index_offsets[] = {
-	0, 2, 43, 45, 78, 111, 113, 146, 
-	179, 212, 232, 252, 272, 305, 338, 371, 
-	404, 437, 470, 503, 536, 569, 602, 635, 
-	668, 678, 680, 682, 715, 748, 781, 814, 
-	834, 854, 874, 907, 940, 973, 1006, 1039, 
-	1072, 1105, 1138, 1171, 1204, 1237, 1239, 1279, 
-	1312, 1335, 1338
+	0, 2, 47, 49, 82, 115, 117, 150, 
+	183, 216, 236, 256, 276, 309, 342, 375, 
+	408, 441, 474, 507, 540, 573, 606, 639, 
+	672, 682, 684, 686, 719, 752, 785, 818, 
+	838, 858, 878, 911, 944, 977, 1010, 1043, 
+	1076, 1109, 1142, 1175, 1208, 1241, 1243, 1283, 
+	1316, 1339, 1342, 1344
 };
 
 static const char _use_syllable_machine_indicies[] = {
 	1, 0, 2, 3, 4, 2, 5, 3, 
 	4, 4, 6, 4, 4, 1, 7, 4, 
 	4, 4, 2, 2, 8, 9, 4, 4, 
 	10, 11, 12, 13, 14, 15, 16, 10, 
 	17, 18, 19, 20, 21, 22, 4, 23, 
-	24, 25, 4, 27, 26, 29, 28, 28, 
-	30, 31, 28, 28, 28, 28, 28, 28, 
-	28, 28, 32, 33, 34, 35, 36, 37, 
-	38, 39, 33, 40, 32, 41, 42, 43, 
-	44, 28, 45, 46, 47, 28, 29, 28, 
-	28, 30, 31, 28, 28, 28, 28, 28, 
-	28, 28, 28, 48, 33, 34, 35, 36, 
-	37, 38, 39, 33, 40, 41, 41, 42, 
-	43, 44, 28, 45, 46, 47, 28, 30, 
-	49, 29, 28, 28, 30, 31, 28, 28, 
-	28, 28, 28, 28, 28, 28, 28, 33, 
-	34, 35, 36, 37, 38, 39, 33, 40, 
-	41, 41, 42, 43, 44, 28, 45, 46, 
-	47, 28, 29, 28, 28, 28, 28, 28, 
-	28, 28, 28, 28, 28, 28, 28, 28, 
-	33, 34, 35, 36, 37, 28, 28, 28, 
-	28, 28, 28, 42, 43, 44, 28, 45, 
-	46, 47, 28, 29, 28, 28, 28, 28, 
-	28, 28, 28, 28, 28, 28, 28, 28, 
-	28, 28, 34, 35, 36, 37, 28, 28, 
-	28, 28, 28, 28, 28, 28, 28, 28, 
-	45, 46, 47, 28, 29, 28, 28, 28, 
-	28, 28, 28, 28, 28, 28, 28, 28, 
-	28, 28, 28, 28, 35, 36, 37, 28, 
-	29, 28, 28, 28, 28, 28, 28, 28, 
-	28, 28, 28, 28, 28, 28, 28, 28, 
-	28, 36, 37, 28, 29, 28, 28, 28, 
-	28, 28, 28, 28, 28, 28, 28, 28, 
-	28, 28, 28, 28, 28, 28, 37, 28, 
-	29, 28, 28, 28, 28, 28, 28, 28, 
-	28, 28, 28, 28, 28, 28, 28, 28, 
-	35, 36, 37, 28, 28, 28, 28, 28, 
-	28, 28, 28, 28, 28, 45, 46, 47, 
-	28, 29, 28, 28, 28, 28, 28, 28, 
-	28, 28, 28, 28, 28, 28, 28, 28, 
-	28, 35, 36, 37, 28, 28, 28, 28, 
-	28, 28, 28, 28, 28, 28, 28, 46, 
-	47, 28, 29, 28, 28, 28, 28, 28, 
-	28, 28, 28, 28, 28, 28, 28, 28, 
-	28, 28, 35, 36, 37, 28, 28, 28, 
-	28, 28, 28, 28, 28, 28, 28, 28, 
-	28, 47, 28, 29, 28, 28, 28, 28, 
-	28, 28, 28, 28, 28, 28, 28, 28, 
-	28, 28, 34, 35, 36, 37, 28, 28, 
-	28, 28, 28, 28, 42, 43, 44, 28, 
-	45, 46, 47, 28, 29, 28, 28, 28, 
-	28, 28, 28, 28, 28, 28, 28, 28, 
-	28, 28, 28, 34, 35, 36, 37, 28, 
-	28, 28, 28, 28, 28, 28, 43, 44, 
-	28, 45, 46, 47, 28, 29, 28, 28, 
-	28, 28, 28, 28, 28, 28, 28, 28, 
-	28, 28, 28, 28, 34, 35, 36, 37, 
-	28, 28, 28, 28, 28, 28, 28, 28, 
-	44, 28, 45, 46, 47, 28, 29, 28, 
-	28, 28, 28, 28, 28, 28, 28, 28, 
-	28, 28, 28, 28, 33, 34, 35, 36, 
-	37, 28, 39, 33, 28, 28, 28, 42, 
-	43, 44, 28, 45, 46, 47, 28, 29, 
-	28, 28, 28, 28, 28, 28, 28, 28, 
-	28, 28, 28, 28, 28, 33, 34, 35, 
-	36, 37, 28, 50, 33, 28, 28, 28, 
-	42, 43, 44, 28, 45, 46, 47, 28, 
-	29, 28, 28, 28, 28, 28, 28, 28, 
-	28, 28, 28, 28, 28, 28, 33, 34, 
-	35, 36, 37, 28, 28, 33, 28, 28, 
-	28, 42, 43, 44, 28, 45, 46, 47, 
-	28, 29, 28, 28, 28, 28, 28, 28, 
-	28, 28, 28, 28, 28, 28, 28, 33, 
-	34, 35, 36, 37, 38, 39, 33, 28, 
-	28, 28, 42, 43, 44, 28, 45, 46, 
-	47, 28, 29, 28, 28, 30, 31, 28, 
-	28, 28, 28, 28, 28, 28, 28, 28, 
-	33, 34, 35, 36, 37, 38, 39, 33, 
-	40, 28, 41, 42, 43, 44, 28, 45, 
-	46, 47, 28, 29, 28, 28, 30, 31, 
-	28, 28, 28, 28, 28, 28, 28, 28, 
-	28, 33, 34, 35, 36, 37, 38, 39, 
-	33, 40, 32, 41, 42, 43, 44, 28, 
-	45, 46, 47, 28, 52, 51, 51, 51, 
-	51, 51, 51, 51, 53, 51, 5, 54, 
-	52, 51, 6, 55, 55, 1, 56, 55, 
-	55, 55, 55, 55, 55, 55, 55, 57, 
+	24, 25, 4, 4, 4, 26, 4, 28, 
+	27, 30, 29, 29, 31, 32, 29, 29, 
+	29, 29, 29, 29, 29, 29, 33, 34, 
+	35, 36, 37, 38, 39, 40, 34, 41, 
+	33, 42, 43, 44, 45, 29, 46, 47, 
+	48, 29, 30, 29, 29, 31, 32, 29, 
+	29, 29, 29, 29, 29, 29, 29, 49, 
+	34, 35, 36, 37, 38, 39, 40, 34, 
+	41, 42, 42, 43, 44, 45, 29, 46, 
+	47, 48, 29, 31, 50, 30, 29, 29, 
+	31, 32, 29, 29, 29, 29, 29, 29, 
+	29, 29, 29, 34, 35, 36, 37, 38, 
+	39, 40, 34, 41, 42, 42, 43, 44, 
+	45, 29, 46, 47, 48, 29, 30, 29, 
+	29, 29, 29, 29, 29, 29, 29, 29, 
+	29, 29, 29, 29, 34, 35, 36, 37, 
+	38, 29, 29, 29, 29, 29, 29, 43, 
+	44, 45, 29, 46, 47, 48, 29, 30, 
+	29, 29, 29, 29, 29, 29, 29, 29, 
+	29, 29, 29, 29, 29, 29, 35, 36, 
+	37, 38, 29, 29, 29, 29, 29, 29, 
+	29, 29, 29, 29, 46, 47, 48, 29, 
+	30, 29, 29, 29, 29, 29, 29, 29, 
+	29, 29, 29, 29, 29, 29, 29, 29, 
+	36, 37, 38, 29, 30, 29, 29, 29, 
+	29, 29, 29, 29, 29, 29, 29, 29, 
+	29, 29, 29, 29, 29, 37, 38, 29, 
+	30, 29, 29, 29, 29, 29, 29, 29, 
+	29, 29, 29, 29, 29, 29, 29, 29, 
+	29, 29, 38, 29, 30, 29, 29, 29, 
+	29, 29, 29, 29, 29, 29, 29, 29, 
+	29, 29, 29, 29, 36, 37, 38, 29, 
+	29, 29, 29, 29, 29, 29, 29, 29, 
+	29, 46, 47, 48, 29, 30, 29, 29, 
+	29, 29, 29, 29, 29, 29, 29, 29, 
+	29, 29, 29, 29, 29, 36, 37, 38, 
+	29, 29, 29, 29, 29, 29, 29, 29, 
+	29, 29, 29, 47, 48, 29, 30, 29, 
+	29, 29, 29, 29, 29, 29, 29, 29, 
+	29, 29, 29, 29, 29, 29, 36, 37, 
+	38, 29, 29, 29, 29, 29, 29, 29, 
+	29, 29, 29, 29, 29, 48, 29, 30, 
+	29, 29, 29, 29, 29, 29, 29, 29, 
+	29, 29, 29, 29, 29, 29, 35, 36, 
+	37, 38, 29, 29, 29, 29, 29, 29, 
+	43, 44, 45, 29, 46, 47, 48, 29, 
+	30, 29, 29, 29, 29, 29, 29, 29, 
+	29, 29, 29, 29, 29, 29, 29, 35, 
+	36, 37, 38, 29, 29, 29, 29, 29, 
+	29, 29, 44, 45, 29, 46, 47, 48, 
+	29, 30, 29, 29, 29, 29, 29, 29, 
+	29, 29, 29, 29, 29, 29, 29, 29, 
+	35, 36, 37, 38, 29, 29, 29, 29, 
+	29, 29, 29, 29, 45, 29, 46, 47, 
+	48, 29, 30, 29, 29, 29, 29, 29, 
+	29, 29, 29, 29, 29, 29, 29, 29, 
+	34, 35, 36, 37, 38, 29, 40, 34, 
+	29, 29, 29, 43, 44, 45, 29, 46, 
+	47, 48, 29, 30, 29, 29, 29, 29, 
+	29, 29, 29, 29, 29, 29, 29, 29, 
+	29, 34, 35, 36, 37, 38, 29, 51, 
+	34, 29, 29, 29, 43, 44, 45, 29, 
+	46, 47, 48, 29, 30, 29, 29, 29, 
+	29, 29, 29, 29, 29, 29, 29, 29, 
+	29, 29, 34, 35, 36, 37, 38, 29, 
+	29, 34, 29, 29, 29, 43, 44, 45, 
+	29, 46, 47, 48, 29, 30, 29, 29, 
+	29, 29, 29, 29, 29, 29, 29, 29, 
+	29, 29, 29, 34, 35, 36, 37, 38, 
+	39, 40, 34, 29, 29, 29, 43, 44, 
+	45, 29, 46, 47, 48, 29, 30, 29, 
+	29, 31, 32, 29, 29, 29, 29, 29, 
+	29, 29, 29, 29, 34, 35, 36, 37, 
+	38, 39, 40, 34, 41, 29, 42, 43, 
+	44, 45, 29, 46, 47, 48, 29, 30, 
+	29, 29, 31, 32, 29, 29, 29, 29, 
+	29, 29, 29, 29, 29, 34, 35, 36, 
+	37, 38, 39, 40, 34, 41, 33, 42, 
+	43, 44, 45, 29, 46, 47, 48, 29, 
+	53, 52, 52, 52, 52, 52, 52, 52, 
+	54, 52, 5, 55, 53, 52, 6, 56, 
+	56, 1, 57, 56, 56, 56, 56, 56, 
+	56, 56, 56, 58, 10, 11, 12, 13, 
+	14, 15, 16, 10, 17, 19, 19, 20, 
+	21, 22, 56, 23, 24, 25, 56, 6, 
+	56, 56, 1, 57, 56, 56, 56, 56, 
+	56, 56, 56, 56, 56, 10, 11, 12, 
+	13, 14, 15, 16, 10, 17, 19, 19, 
+	20, 21, 22, 56, 23, 24, 25, 56, 
+	6, 56, 56, 56, 56, 56, 56, 56, 
+	56, 56, 56, 56, 56, 56, 10, 11, 
+	12, 13, 14, 56, 56, 56, 56, 56, 
+	56, 20, 21, 22, 56, 23, 24, 25, 
+	56, 6, 56, 56, 56, 56, 56, 56, 
+	56, 56, 56, 56, 56, 56, 56, 56, 
+	11, 12, 13, 14, 56, 56, 56, 56, 
+	56, 56, 56, 56, 56, 56, 23, 24, 
+	25, 56, 6, 56, 56, 56, 56, 56, 
+	56, 56, 56, 56, 56, 56, 56, 56, 
+	56, 56, 12, 13, 14, 56, 6, 56, 
+	56, 56, 56, 56, 56, 56, 56, 56, 
+	56, 56, 56, 56, 56, 56, 56, 13, 
+	14, 56, 6, 56, 56, 56, 56, 56, 
+	56, 56, 56, 56, 56, 56, 56, 56, 
+	56, 56, 56, 56, 14, 56, 6, 56, 
+	56, 56, 56, 56, 56, 56, 56, 56, 
+	56, 56, 56, 56, 56, 56, 12, 13, 
+	14, 56, 56, 56, 56, 56, 56, 56, 
+	56, 56, 56, 23, 24, 25, 56, 6, 
+	56, 56, 56, 56, 56, 56, 56, 56, 
+	56, 56, 56, 56, 56, 56, 56, 12, 
+	13, 14, 56, 56, 56, 56, 56, 56, 
+	56, 56, 56, 56, 56, 24, 25, 56, 
+	6, 56, 56, 56, 56, 56, 56, 56, 
+	56, 56, 56, 56, 56, 56, 56, 56, 
+	12, 13, 14, 56, 56, 56, 56, 56, 
+	56, 56, 56, 56, 56, 56, 56, 25, 
+	56, 6, 56, 56, 56, 56, 56, 56, 
+	56, 56, 56, 56, 56, 56, 56, 56, 
+	11, 12, 13, 14, 56, 56, 56, 56, 
+	56, 56, 20, 21, 22, 56, 23, 24, 
+	25, 56, 6, 56, 56, 56, 56, 56, 
+	56, 56, 56, 56, 56, 56, 56, 56, 
+	56, 11, 12, 13, 14, 56, 56, 56, 
+	56, 56, 56, 56, 21, 22, 56, 23, 
+	24, 25, 56, 6, 56, 56, 56, 56, 
+	56, 56, 56, 56, 56, 56, 56, 56, 
+	56, 56, 11, 12, 13, 14, 56, 56, 
+	56, 56, 56, 56, 56, 56, 22, 56, 
+	23, 24, 25, 56, 6, 56, 56, 56, 
+	56, 56, 56, 56, 56, 56, 56, 56, 
+	56, 56, 10, 11, 12, 13, 14, 56, 
+	16, 10, 56, 56, 56, 20, 21, 22, 
+	56, 23, 24, 25, 56, 6, 56, 56, 
+	56, 56, 56, 56, 56, 56, 56, 56, 
+	56, 56, 56, 10, 11, 12, 13, 14, 
+	56, 59, 10, 56, 56, 56, 20, 21, 
+	22, 56, 23, 24, 25, 56, 6, 56, 
+	56, 56, 56, 56, 56, 56, 56, 56, 
+	56, 56, 56, 56, 10, 11, 12, 13, 
+	14, 56, 56, 10, 56, 56, 56, 20, 
+	21, 22, 56, 23, 24, 25, 56, 6, 
+	56, 56, 56, 56, 56, 56, 56, 56, 
+	56, 56, 56, 56, 56, 10, 11, 12, 
+	13, 14, 15, 16, 10, 56, 56, 56, 
+	20, 21, 22, 56, 23, 24, 25, 56, 
+	6, 56, 56, 1, 57, 56, 56, 56, 
+	56, 56, 56, 56, 56, 56, 10, 11, 
+	12, 13, 14, 15, 16, 10, 17, 56, 
+	19, 20, 21, 22, 56, 23, 24, 25, 
+	56, 1, 60, 3, 56, 56, 56, 3, 
+	56, 56, 6, 56, 56, 1, 57, 56, 
+	56, 56, 56, 56, 56, 56, 56, 56, 
 	10, 11, 12, 13, 14, 15, 16, 10, 
-	17, 19, 19, 20, 21, 22, 55, 23, 
-	24, 25, 55, 6, 55, 55, 1, 56, 
-	55, 55, 55, 55, 55, 55, 55, 55, 
-	55, 10, 11, 12, 13, 14, 15, 16, 
-	10, 17, 19, 19, 20, 21, 22, 55, 
-	23, 24, 25, 55, 6, 55, 55, 55, 
-	55, 55, 55, 55, 55, 55, 55, 55, 
-	55, 55, 10, 11, 12, 13, 14, 55, 
-	55, 55, 55, 55, 55, 20, 21, 22, 
-	55, 23, 24, 25, 55, 6, 55, 55, 
-	55, 55, 55, 55, 55, 55, 55, 55, 
-	55, 55, 55, 55, 11, 12, 13, 14, 
-	55, 55, 55, 55, 55, 55, 55, 55, 
-	55, 55, 23, 24, 25, 55, 6, 55, 
-	55, 55, 55, 55, 55, 55, 55, 55, 
-	55, 55, 55, 55, 55, 55, 12, 13, 
-	14, 55, 6, 55, 55, 55, 55, 55, 
-	55, 55, 55, 55, 55, 55, 55, 55, 
-	55, 55, 55, 13, 14, 55, 6, 55, 
-	55, 55, 55, 55, 55, 55, 55, 55, 
-	55, 55, 55, 55, 55, 55, 55, 55, 
-	14, 55, 6, 55, 55, 55, 55, 55, 
-	55, 55, 55, 55, 55, 55, 55, 55, 
-	55, 55, 12, 13, 14, 55, 55, 55, 
-	55, 55, 55, 55, 55, 55, 55, 23, 
-	24, 25, 55, 6, 55, 55, 55, 55, 
-	55, 55, 55, 55, 55, 55, 55, 55, 
-	55, 55, 55, 12, 13, 14, 55, 55, 
-	55, 55, 55, 55, 55, 55, 55, 55, 
-	55, 24, 25, 55, 6, 55, 55, 55, 
-	55, 55, 55, 55, 55, 55, 55, 55, 
-	55, 55, 55, 55, 12, 13, 14, 55, 
-	55, 55, 55, 55, 55, 55, 55, 55, 
-	55, 55, 55, 25, 55, 6, 55, 55, 
-	55, 55, 55, 55, 55, 55, 55, 55, 
-	55, 55, 55, 55, 11, 12, 13, 14, 
-	55, 55, 55, 55, 55, 55, 20, 21, 
-	22, 55, 23, 24, 25, 55, 6, 55, 
-	55, 55, 55, 55, 55, 55, 55, 55, 
-	55, 55, 55, 55, 55, 11, 12, 13, 
-	14, 55, 55, 55, 55, 55, 55, 55, 
-	21, 22, 55, 23, 24, 25, 55, 6, 
-	55, 55, 55, 55, 55, 55, 55, 55, 
-	55, 55, 55, 55, 55, 55, 11, 12, 
-	13, 14, 55, 55, 55, 55, 55, 55, 
-	55, 55, 22, 55, 23, 24, 25, 55, 
-	6, 55, 55, 55, 55, 55, 55, 55, 
-	55, 55, 55, 55, 55, 55, 10, 11, 
-	12, 13, 14, 55, 16, 10, 55, 55, 
-	55, 20, 21, 22, 55, 23, 24, 25, 
-	55, 6, 55, 55, 55, 55, 55, 55, 
-	55, 55, 55, 55, 55, 55, 55, 10, 
-	11, 12, 13, 14, 55, 58, 10, 55, 
-	55, 55, 20, 21, 22, 55, 23, 24, 
-	25, 55, 6, 55, 55, 55, 55, 55, 
-	55, 55, 55, 55, 55, 55, 55, 55, 
-	10, 11, 12, 13, 14, 55, 55, 10, 
-	55, 55, 55, 20, 21, 22, 55, 23, 
-	24, 25, 55, 6, 55, 55, 55, 55, 
-	55, 55, 55, 55, 55, 55, 55, 55, 
-	55, 10, 11, 12, 13, 14, 15, 16, 
-	10, 55, 55, 55, 20, 21, 22, 55, 
-	23, 24, 25, 55, 6, 55, 55, 1, 
-	56, 55, 55, 55, 55, 55, 55, 55, 
-	55, 55, 10, 11, 12, 13, 14, 15, 
-	16, 10, 17, 55, 19, 20, 21, 22, 
-	55, 23, 24, 25, 55, 1, 59, 3, 
-	55, 55, 55, 3, 55, 55, 6, 55, 
-	55, 1, 56, 55, 55, 55, 55, 55, 
-	55, 55, 55, 55, 10, 11, 12, 13, 
-	14, 15, 16, 10, 17, 18, 19, 20, 
-	21, 22, 55, 23, 24, 25, 55, 6, 
-	55, 55, 1, 56, 55, 55, 55, 55, 
-	55, 55, 55, 55, 55, 10, 11, 12, 
-	13, 14, 15, 16, 10, 17, 18, 19, 
-	20, 21, 22, 55, 23, 24, 25, 55, 
-	61, 60, 60, 60, 60, 60, 60, 60, 
-	60, 60, 60, 60, 60, 60, 60, 60, 
-	60, 60, 60, 60, 61, 62, 60, 61, 
-	62, 60, 62, 60, 0
+	17, 18, 19, 20, 21, 22, 56, 23, 
+	24, 25, 56, 6, 56, 56, 1, 57, 
+	56, 56, 56, 56, 56, 56, 56, 56, 
+	56, 10, 11, 12, 13, 14, 15, 16, 
+	10, 17, 18, 19, 20, 21, 22, 56, 
+	23, 24, 25, 56, 62, 61, 61, 61, 
+	61, 61, 61, 61, 61, 61, 61, 61, 
+	61, 61, 61, 61, 61, 61, 61, 61, 
+	62, 63, 61, 62, 63, 61, 63, 61, 
+	3, 60, 60, 60, 3, 60, 0
 };
 
 static const char _use_syllable_machine_trans_targs[] = {
 	1, 27, 2, 3, 1, 24, 1, 45, 
 	46, 48, 29, 30, 31, 32, 33, 40, 
 	41, 43, 47, 44, 37, 38, 39, 34, 
-	35, 36, 1, 1, 1, 1, 4, 5, 
-	23, 7, 8, 9, 10, 11, 18, 19, 
-	21, 22, 15, 16, 17, 12, 13, 14, 
-	6, 1, 20, 1, 25, 26, 1, 1, 
-	0, 28, 42, 1, 1, 49, 50
+	35, 36, 51, 1, 1, 1, 1, 4, 
+	5, 23, 7, 8, 9, 10, 11, 18, 
+	19, 21, 22, 15, 16, 17, 12, 13, 
+	14, 6, 1, 20, 1, 25, 26, 1, 
+	1, 0, 28, 42, 1, 1, 49, 50
 };
 
 static const char _use_syllable_machine_trans_actions[] = {
 	1, 2, 0, 0, 5, 0, 6, 0, 
 	2, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 2, 2, 0, 0, 0, 0, 
-	0, 0, 7, 8, 9, 10, 0, 0, 
+	0, 0, 0, 7, 8, 9, 10, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 11, 0, 12, 0, 0, 13, 14, 
-	0, 2, 0, 15, 16, 0, 0
+	0, 0, 11, 0, 12, 0, 0, 13, 
+	14, 0, 2, 0, 15, 16, 0, 0
 };
 
 static const char _use_syllable_machine_to_state_actions[] = {
 	0, 3, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0
+	0, 0, 0, 0
 };
 
 static const char _use_syllable_machine_from_state_actions[] = {
 	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, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0
+	0, 0, 0, 0
 };
 
 static const short _use_syllable_machine_eof_trans[] = {
-	1, 0, 27, 29, 29, 50, 29, 29, 
-	29, 29, 29, 29, 29, 29, 29, 29, 
-	29, 29, 29, 29, 29, 29, 29, 29, 
-	52, 55, 52, 56, 56, 56, 56, 56, 
-	56, 56, 56, 56, 56, 56, 56, 56, 
-	56, 56, 56, 56, 56, 60, 56, 56, 
-	61, 61, 61
+	1, 0, 28, 30, 30, 51, 30, 30, 
+	30, 30, 30, 30, 30, 30, 30, 30, 
+	30, 30, 30, 30, 30, 30, 30, 30, 
+	53, 56, 53, 57, 57, 57, 57, 57, 
+	57, 57, 57, 57, 57, 57, 57, 57, 
+	57, 57, 57, 57, 57, 61, 57, 57, 
+	62, 62, 62, 61
 };
 
 static const int use_syllable_machine_start = 1;
 static const int use_syllable_machine_first_final = 1;
 static const int use_syllable_machine_error = -1;
 
 static const int use_syllable_machine_en_main = 1;
 
 
 #line 38 "hb-ot-shape-complex-use-machine.rl"
 
 
 
-#line 139 "hb-ot-shape-complex-use-machine.rl"
+#line 140 "hb-ot-shape-complex-use-machine.rl"
 
 
 #define found_syllable(syllable_type) \
   HB_STMT_START { \
     if (0) fprintf (stderr, "syllable %d..%d %s\n", last, p+1, #syllable_type); \
     for (unsigned int i = last; i < p+1; i++) \
       info[i].syllable() = (syllable_serial << 4) | syllable_type; \
     last = p+1; \
@@ -314,48 +315,48 @@ static const int use_syllable_machine_en
 
 static void
 find_syllables (hb_buffer_t *buffer)
 {
   unsigned int p, pe, eof, ts HB_UNUSED, te HB_UNUSED, act HB_UNUSED;
   int cs;
   hb_glyph_info_t *info = buffer->info;
   
-#line 323 "hb-ot-shape-complex-use-machine.hh"
+#line 324 "hb-ot-shape-complex-use-machine.hh"
 	{
 	cs = use_syllable_machine_start;
 	ts = 0;
 	te = 0;
 	act = 0;
 	}
 
-#line 160 "hb-ot-shape-complex-use-machine.rl"
+#line 161 "hb-ot-shape-complex-use-machine.rl"
 
 
   p = 0;
   pe = eof = buffer->len;
 
   unsigned int last = 0;
   unsigned int syllable_serial = 1;
   
-#line 340 "hb-ot-shape-complex-use-machine.hh"
+#line 341 "hb-ot-shape-complex-use-machine.hh"
 	{
 	int _slen;
 	int _trans;
 	const unsigned char *_keys;
 	const char *_inds;
 	if ( p == pe )
 		goto _test_eof;
 _resume:
 	switch ( _use_syllable_machine_from_state_actions[cs] ) {
 	case 4:
 #line 1 "NONE"
 	{ts = p;}
 	break;
-#line 354 "hb-ot-shape-complex-use-machine.hh"
+#line 355 "hb-ot-shape-complex-use-machine.hh"
 	}
 
 	_keys = _use_syllable_machine_trans_keys + (cs<<1);
 	_inds = _use_syllable_machine_indicies + _use_syllable_machine_index_offsets[cs];
 
 	_slen = _use_syllable_machine_key_spans[cs];
 	_trans = _inds[ _slen > 0 && _keys[0] <=( info[p].use_category()) &&
 		( info[p].use_category()) <= _keys[1] ?
@@ -368,91 +369,91 @@ find_syllables (hb_buffer_t *buffer)
 		goto _again;
 
 	switch ( _use_syllable_machine_trans_actions[_trans] ) {
 	case 2:
 #line 1 "NONE"
 	{te = p+1;}
 	break;
 	case 8:
-#line 128 "hb-ot-shape-complex-use-machine.rl"
+#line 129 "hb-ot-shape-complex-use-machine.rl"
 	{te = p+1;{ found_syllable (independent_cluster); }}
 	break;
 	case 10:
-#line 130 "hb-ot-shape-complex-use-machine.rl"
+#line 131 "hb-ot-shape-complex-use-machine.rl"
 	{te = p+1;{ found_syllable (standard_cluster); }}
 	break;
 	case 6:
-#line 134 "hb-ot-shape-complex-use-machine.rl"
+#line 135 "hb-ot-shape-complex-use-machine.rl"
 	{te = p+1;{ found_syllable (broken_cluster); }}
 	break;
 	case 5:
-#line 135 "hb-ot-shape-complex-use-machine.rl"
+#line 136 "hb-ot-shape-complex-use-machine.rl"
 	{te = p+1;{ found_syllable (non_cluster); }}
 	break;
 	case 7:
-#line 128 "hb-ot-shape-complex-use-machine.rl"
+#line 129 "hb-ot-shape-complex-use-machine.rl"
 	{te = p;p--;{ found_syllable (independent_cluster); }}
 	break;
 	case 11:
-#line 129 "hb-ot-shape-complex-use-machine.rl"
+#line 130 "hb-ot-shape-complex-use-machine.rl"
 	{te = p;p--;{ found_syllable (virama_terminated_cluster); }}
 	break;
 	case 9:
-#line 130 "hb-ot-shape-complex-use-machine.rl"
+#line 131 "hb-ot-shape-complex-use-machine.rl"
 	{te = p;p--;{ found_syllable (standard_cluster); }}
 	break;
 	case 13:
-#line 131 "hb-ot-shape-complex-use-machine.rl"
+#line 132 "hb-ot-shape-complex-use-machine.rl"
 	{te = p;p--;{ found_syllable (number_joiner_terminated_cluster); }}
 	break;
 	case 12:
-#line 132 "hb-ot-shape-complex-use-machine.rl"
+#line 133 "hb-ot-shape-complex-use-machine.rl"
 	{te = p;p--;{ found_syllable (numeral_cluster); }}
 	break;
 	case 16:
-#line 133 "hb-ot-shape-complex-use-machine.rl"
+#line 134 "hb-ot-shape-complex-use-machine.rl"
 	{te = p;p--;{ found_syllable (symbol_cluster); }}
 	break;
 	case 14:
-#line 134 "hb-ot-shape-complex-use-machine.rl"
+#line 135 "hb-ot-shape-complex-use-machine.rl"
 	{te = p;p--;{ found_syllable (broken_cluster); }}
 	break;
 	case 15:
-#line 135 "hb-ot-shape-complex-use-machine.rl"
+#line 136 "hb-ot-shape-complex-use-machine.rl"
 	{te = p;p--;{ found_syllable (non_cluster); }}
 	break;
 	case 1:
-#line 134 "hb-ot-shape-complex-use-machine.rl"
+#line 135 "hb-ot-shape-complex-use-machine.rl"
 	{{p = ((te))-1;}{ found_syllable (broken_cluster); }}
 	break;
-#line 428 "hb-ot-shape-complex-use-machine.hh"
+#line 429 "hb-ot-shape-complex-use-machine.hh"
 	}
 
 _again:
 	switch ( _use_syllable_machine_to_state_actions[cs] ) {
 	case 3:
 #line 1 "NONE"
 	{ts = 0;}
 	break;
-#line 437 "hb-ot-shape-complex-use-machine.hh"
+#line 438 "hb-ot-shape-complex-use-machine.hh"
 	}
 
 	if ( ++p != pe )
 		goto _resume;
 	_test_eof: {}
 	if ( p == eof )
 	{
 	if ( _use_syllable_machine_eof_trans[cs] > 0 ) {
 		_trans = _use_syllable_machine_eof_trans[cs] - 1;
 		goto _eof_trans;
 	}
 	}
 
 	}
 
-#line 169 "hb-ot-shape-complex-use-machine.rl"
+#line 170 "hb-ot-shape-complex-use-machine.rl"
 
 }
 
 #undef found_syllable
 
 #endif /* HB_OT_SHAPE_COMPLEX_USE_MACHINE_HH */
--- a/gfx/harfbuzz/src/hb-ot-shape-complex-use-machine.rl
+++ b/gfx/harfbuzz/src/hb-ot-shape-complex-use-machine.rl
@@ -81,32 +81,33 @@ VBlw	= 34; # VOWEL_BELOW / VOWEL_BELOW_P
 VPst	= 35; # VOWEL_POST	UIPC = Right
 VPre	= 22; # VOWEL_PRE / VOWEL_PRE_ABOVE / VOWEL_PRE_ABOVE_POST / VOWEL_PRE_POST
 VMAbv	= 37; # VOWEL_MOD_ABOVE
 VMBlw	= 38; # VOWEL_MOD_BELOW
 VMPst	= 39; # VOWEL_MOD_POST
 VMPre	= 23; # VOWEL_MOD_PRE
 SMAbv	= 41; # SYM_MOD_ABOVE
 SMBlw	= 42; # SYM_MOD_BELOW
+CS	= 43; # CONS_WITH_STACKER
 
 
 consonant_modifiers = CMAbv* CMBlw* ((H B | SUB) VS? CMAbv? CMBlw*)*;
 # Override: Allow two MBlw. https://github.com/behdad/harfbuzz/issues/376
 medial_consonants = MPre? MAbv? MBlw?.MBlw? MPst?;
 dependent_vowels = VPre* VAbv* VBlw* VPst*;
 vowel_modifiers = VMPre* VMAbv* VMBlw* VMPst*;
 final_consonants = FAbv* FBlw* FPst* FM?;
 
 virama_terminated_cluster =
-	R? (B | GB) VS?
+	(R|CS)? (B | GB) VS?
 	consonant_modifiers
 	H
 ;
 standard_cluster =
-	R? (B | GB) VS?
+	(R|CS)? (B | GB) VS?
 	consonant_modifiers
 	medial_consonants
 	dependent_vowels
 	vowel_modifiers
 	final_consonants
 ;
 
 broken_cluster =
--- a/gfx/harfbuzz/src/hb-ot-shape-complex-use-private.hh
+++ b/gfx/harfbuzz/src/hb-ot-shape-complex-use-private.hh
@@ -82,15 +82,16 @@ enum use_category_t {
   USE_VBlw	= 34,	/* VOWEL_BELOW / VOWEL_BELOW_POST */
   USE_VPst	= 35,	/* VOWEL_POST	UIPC = Right */
   USE_VPre	= 22,	/* VOWEL_PRE / VOWEL_PRE_ABOVE / VOWEL_PRE_ABOVE_POST / VOWEL_PRE_POST */
   USE_VMAbv	= 37,	/* VOWEL_MOD_ABOVE */
   USE_VMBlw	= 38,	/* VOWEL_MOD_BELOW */
   USE_VMPst	= 39,	/* VOWEL_MOD_POST */
   USE_VMPre	= 23,	/* VOWEL_MOD_PRE */
   USE_SMAbv	= 41,	/* SYM_MOD_ABOVE */
-  USE_SMBlw	= 42	/* SYM_MOD_BELOW */
+  USE_SMBlw	= 42,	/* SYM_MOD_BELOW */
+  USE_CS	= 43	/* CONS_WITH_STACKER */
 };
 
 HB_INTERNAL USE_TABLE_ELEMENT_TYPE
 hb_use_get_categories (hb_codepoint_t u);
 
 #endif /* HB_OT_SHAPE_COMPLEX_USE_PRIVATE_HH */
--- a/gfx/harfbuzz/src/hb-ot-shape-complex-use-table.cc
+++ b/gfx/harfbuzz/src/hb-ot-shape-complex-use-table.cc
@@ -1,29 +1,30 @@
 /* == Start of generated table == */
 /*
  * The following table is generated by running:
  *
  *   ./gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt UnicodeData.txt Blocks.txt
  *
  * on files with these headers:
  *
- * # IndicSyllabicCategory-9.0.0.txt
- * # Date: 2016-05-21, 02:46:00 GMT [RP]
- * # IndicPositionalCategory-9.0.0.txt
- * # Date: 2016-06-09, 19:33:00 GMT [RP]
- * # Blocks-9.0.0.txt
- * # Date: 2016-02-05, 23:48:00 GMT [KW]
+ * # IndicSyllabicCategory-10.0.0.txt
+ * # Date: 2017-05-31, 01:07:00 GMT [KW, RP]
+ * # IndicPositionalCategory-10.0.0.txt
+ * # Date: 2017-05-31, 01:07:00 GMT [RP]
+ * # Blocks-10.0.0.txt
+ * # Date: 2017-04-12, 17:30:00 GMT [KW]
  * UnicodeData.txt does not have a header.
  */
 
 #include "hb-ot-shape-complex-use-private.hh"
 
 #define B	USE_B	/* BASE */
 #define CGJ	USE_CGJ	/* CGJ */
+#define CS	USE_CS	/* CONS_WITH_STACKER */
 #define FM	USE_FM	/* CONS_FINAL_MOD */
 #define GB	USE_GB	/* BASE_OTHER */
 #define H	USE_H	/* HALANT */
 #define HN	USE_HN	/* HALANT_NUM */
 #define IND	USE_IND	/* BASE_IND */
 #define N	USE_N	/* BASE_NUM */
 #define O	USE_O	/* OTHER */
 #define R	USE_R	/* REPHA */
@@ -92,17 +93,17 @@ static const USE_TABLE_ELEMENT_TYPE use_
 
   /* 0980 */     O, VMAbv, VMPst, VMPst,     O,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     B,
   /* 0990 */     B,     O,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 09A0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     B,     B,     B,     B,     B,     B,
   /* 09B0 */     B,     O,     B,     O,     O,     O,     B,     B,     B,     B,     O,     O, CMBlw,     B,  VPst,  VPre,
   /* 09C0 */  VPst,  VBlw,  VBlw,  VBlw,  VBlw,     O,     O,  VPre,  VPre,     O,     O,  VPre,  VPre,     H,   IND,     O,
   /* 09D0 */     O,     O,     O,     O,     O,     O,     O,  VPst,     O,     O,     O,     O,     B,     B,     O,     B,
   /* 09E0 */     B,     B,  VBlw,  VBlw,     O,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 09F0 */     B,     B,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 09F0 */     B,     B,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     B,     O,     O,     O,
 
   /* Gurmukhi */
 
   /* 0A00 */     O, VMAbv, VMAbv, VMPst,     O,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     B,
   /* 0A10 */     B,     O,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 0A20 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     B,     B,     B,     B,     B,     B,
   /* 0A30 */     B,     O,     B,     B,     O,     B,     B,     O,     B,     B,     O,     O, CMBlw,     O,  VPst,  VPre,
   /* 0A40 */  VPst,  VBlw,  VBlw,     O,     O,     O,     O,  VAbv,  VAbv,     O,     O,  VAbv,  VAbv,     H,     O,     O,
@@ -114,17 +115,17 @@ static const USE_TABLE_ELEMENT_TYPE use_
 
   /* 0A80 */     O, VMAbv, VMAbv, VMPst,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     B,
   /* 0A90 */     B,     B,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 0AA0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     B,     B,     B,     B,     B,     B,
   /* 0AB0 */     B,     O,     B,     B,     O,     B,     B,     B,     B,     B,     O,     O, CMBlw,     B,  VPst,  VPre,
   /* 0AC0 */  VPst,  VBlw,  VBlw,  VBlw,  VBlw,  VAbv,     O,  VAbv,  VAbv,  VAbv,     O,  VPst,  VPst,     H,     O,     O,
   /* 0AD0 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
   /* 0AE0 */     B,     B,  VBlw,  VBlw,     O,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 0AF0 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     B,     O,     O,     O,     O,     O,     O,
+  /* 0AF0 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     B, VMAbv, VMAbv, VMAbv, CMAbv, CMAbv, CMAbv,
 
   /* Oriya */
 
   /* 0B00 */     O, VMAbv, VMPst, VMPst,     O,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     B,
   /* 0B10 */     B,     O,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 0B20 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     B,     B,     B,     B,     B,     B,
   /* 0B30 */     B,     O,     B,     B,     O,     B,     B,     B,     B,     B,     O,     O, CMBlw,     B,  VPst,  VAbv,
   /* 0B40 */  VPst,  VBlw,  VBlw,  VBlw,  VBlw,     O,     O,  VPre,  VPre,     O,     O,  VPre,  VPre,     H,     O,     O,
@@ -158,24 +159,24 @@ static const USE_TABLE_ELEMENT_TYPE use_
 
   /* 0C80 */     O, VMAbv, VMPst, VMPst,     O,     B,     B,     B,     B,     B,     B,     B,     B,     O,     B,     B,
   /* 0C90 */     B,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 0CA0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     B,     B,     B,     B,     B,     B,
   /* 0CB0 */     B,     B,     B,     B,     O,     B,     B,     B,     B,     B,     O,     O, CMBlw,     B,  VPst,  VAbv,
   /* 0CC0 */  VAbv,  VPst,  VPst,  VPst,  VPst,     O,  VAbv,  VAbv,  VAbv,     O,  VAbv,  VAbv,  VAbv,     H,     O,     O,
   /* 0CD0 */     O,     O,     O,     O,     O,  VPst,  VPst,     O,     O,     O,     O,     O,     O,     O,     B,     O,
   /* 0CE0 */     B,     B,  VBlw,  VBlw,     O,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 0CF0 */     O,     R,     R,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 0CF0 */     O,    CS,    CS,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
 
   /* Malayalam */
 
-  /* 0D00 */     O, VMAbv, VMPst, VMPst,     O,     B,     B,     B,     B,     B,     B,     B,     B,     O,     B,     B,
+  /* 0D00 */ VMAbv, VMAbv, VMPst, VMPst,     O,     B,     B,     B,     B,     B,     B,     B,     B,     O,     B,     B,
   /* 0D10 */     B,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 0D20 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 0D30 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     B,  VPst,  VPst,
+  /* 0D30 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,  VAbv,  VAbv,     B,  VPst,  VPst,
   /* 0D40 */  VPst,  VPst,  VPst,  VBlw,  VBlw,     O,  VPre,  VPre,  VPre,     O,  VPre,  VPre,  VPre,     H,     R,     O,
   /* 0D50 */     O,     O,     O,     O,   IND,   IND,   IND,  VPst,     O,     O,     O,     O,     O,     O,     O,     B,
   /* 0D60 */     B,     B,  VBlw,  VBlw,     O,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 0D70 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,   IND,   IND,   IND,   IND,   IND,   IND,
 
   /* Sinhala */
 
   /* 0D80 */     O,     O, VMPst, VMPst,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
@@ -269,19 +270,19 @@ static const USE_TABLE_ELEMENT_TYPE use_
   /* 1A00 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 1A10 */     B,     B,     B,     B,     B,     B,     B,  VAbv,  VBlw,  VPre,  VPst,  VAbv,     O,     O,     O,     O,
 
   /* Tai Tham */
 
   /* 1A20 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 1A30 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 1A40 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 1A50 */     B,     B,     B,     B,     B,  MPre,  MBlw,  FPst,  FAbv,  FAbv,  FAbv,  FBlw,  FBlw,  FBlw,  FBlw,     O,
+  /* 1A50 */     B,     B,     B,     B,     B,  MPre,  MBlw,   SUB,  FAbv,  FAbv,  FAbv,   SUB,   SUB,   SUB,   SUB,     O,
   /* 1A60 */     H,  VPst,  VAbv,  VPst,  VPst,  VAbv,  VAbv,  VAbv,  VAbv,  VBlw,  VBlw,  VAbv,  VBlw,  VPst,  VPre,  VPre,
-  /* 1A70 */  VPre,  VPre,  VPre,  VAbv,  VAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv,    FM,    FM,    FM,     O,     O,    FM,
+  /* 1A70 */  VPre,  VPre,  VPre,  VAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv,  VAbv,    FM,    FM,     O,     O,  FBlw,
   /* 1A80 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
   /* 1A90 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
 
 #define use_offset_0x1b00u 2168
 
 
   /* Balinese */
 
@@ -318,17 +319,17 @@ static const USE_TABLE_ELEMENT_TYPE use_
 
 #define use_offset_0x1cd0u 2504
 
 
   /* Vedic Extensions */
 
   /* 1CD0 */ VMAbv, VMAbv, VMAbv,     O, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMAbv, VMAbv, VMBlw, VMBlw, VMBlw, VMBlw,
   /* 1CE0 */ VMAbv, VMPst, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw,     O,     O,     O,     O, VMBlw,     O,     O,
-  /* 1CF0 */     O,     O, VMPst, VMPst, VMAbv,     O,     O,     O, VMAbv, VMAbv,     O,     O,     O,     O,     O,     O,
+  /* 1CF0 */     O,     O, VMPst, VMPst, VMAbv,     O,     O, VMPst, VMAbv, VMAbv,     O,     O,     O,     O,     O,     O,
 
 #define use_offset_0x1df8u 2552
 
 
   /* Combining Diacritical Marks Supplement */
                                                                          O,     O,     O,    FM,     O,     O,     O,     O,
 
 #define use_offset_0x2008u 2560
@@ -371,17 +372,17 @@ static const USE_TABLE_ELEMENT_TYPE use_
   /* A8A0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* A8B0 */     B,     B,     B,     B,  FPst,  VPst,  VPst,  VPst,  VPst,  VPst,  VPst,  VPst,  VPst,  VPst,  VPst,  VPst,
   /* A8C0 */  VPst,  VPst,  VPst,  VPst,     H, VMAbv,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
   /* A8D0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
 
   /* Devanagari Extended */
 
   /* A8E0 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv,
-  /* A8F0 */ VMAbv, VMAbv,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* A8F0 */ VMAbv, VMAbv,     B,     B,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
 
   /* Kayah Li */
 
   /* A900 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* A910 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* A920 */     B,     B,     B,     B,     B,     B,  VAbv,  VAbv,  VAbv,  VAbv,  VAbv, VMBlw, VMBlw, VMBlw,     O,     O,
 
   /* Rejang */
@@ -392,17 +393,17 @@ static const USE_TABLE_ELEMENT_TYPE use_
   /* A960 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
   /* A970 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
 
   /* Javanese */
 
   /* A980 */ VMAbv, VMAbv,  FAbv, VMPst,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* A990 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* A9A0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* A9B0 */     B,     B,     B, CMAbv,  VPst,  VPst,  VAbv,  VAbv,  VBlw,  VBlw,  VPre,  VPre,  VAbv,   SUB,  MPst,  MPst,
+  /* A9B0 */     B,     B,     B, CMAbv,  VPst,  VPst,  VAbv,  VAbv,  VBlw,  VBlw,  VPre,  VPre,  VAbv,   SUB,  MPst,  MBlw,
   /* A9C0 */     H,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
   /* A9D0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
 
   /* Myanmar Extended-B */
 
   /* A9E0 */     B,     B,     B,     B,     B,  VAbv,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* A9F0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,
 
@@ -462,17 +463,17 @@ static const USE_TABLE_ELEMENT_TYPE use_
   /* 10A30 */     B,     B,     B,     B,     O,     O,     O,     O, CMAbv, CMBlw, CMBlw,     O,     O,     O,     O,     H,
   /* 10A40 */     B,     B,     B,     B,     B,     B,     B,     B,
 
 #define use_offset_0x11000u 3528
 
 
   /* Brahmi */
 
-  /* 11000 */ VMPst, VMAbv, VMPst,     R,     R,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 11000 */ VMPst, VMAbv, VMPst,    CS,    CS,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 11010 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 11020 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 11030 */     B,     B,     B,     B,     B,     B,     B,     B,  VAbv,  VAbv,  VAbv,  VAbv,  VBlw,  VBlw,  VBlw,  VBlw,
   /* 11040 */  VBlw,  VBlw,  VAbv,  VAbv,  VAbv,  VAbv,     H,     O,     O,     O,     O,     O,     O,     O,     O,     O,
   /* 11050 */     O,     O,     N,     N,     N,     N,     N,     N,     N,     N,     N,     N,     N,     N,     N,     N,
   /* 11060 */     N,     N,     N,     N,     N,     N,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 11070 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
 
@@ -540,17 +541,17 @@ static const USE_TABLE_ELEMENT_TYPE use_
 
   /* Grantha */
 
   /* 11300 */ VMAbv, VMAbv, VMPst, VMPst,     O,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     B,
   /* 11310 */     B,     O,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 11320 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     B,     B,     B,     B,     B,     B,
   /* 11330 */     B,     O,     B,     B,     O,     B,     B,     B,     B,     B,     O,     O, CMBlw,     B,  VPst,  VPst,
   /* 11340 */  VAbv,  VPst,  VPst,  VPst,  VPst,     O,     O,  VPre,  VPre,     O,     O,  VPre,  VPre,     H,     O,     O,
-  /* 11350 */     O,     O,     O,     O,     O,     O,     O,  VPst,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 11350 */     O,     O,     O,     O,     O,     O,     O,  VPst,     O,     O,     O,     O,     O,     O,     B,     B,
   /* 11360 */     B,     B,  VPst,  VPst,     O,     O, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv,     O,     O,     O,
   /* 11370 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv,     O,     O,     O,
 
 #define use_offset_0x11400u 4288
 
 
   /* Newa */
 
@@ -610,17 +611,36 @@ static const USE_TABLE_ELEMENT_TYPE use_
 
   /* Ahom */
 
   /* 11700 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 11710 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,  MBlw,  MPre,  MAbv,
   /* 11720 */  VPst,  VPst,  VAbv,  VAbv,  VBlw,  VBlw,  VPre,  VAbv,  VBlw,  VAbv,  VAbv,  VAbv,     O,     O,     O,     O,
   /* 11730 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,
 
-#define use_offset_0x11c00u 4960
+#define use_offset_0x11a00u 4960
+
+
+  /* Zanabazar Square */
+
+  /* 11A00 */     B,  VAbv,  VBlw,  VBlw,  VAbv,  VAbv,  VAbv,  VAbv,  VAbv,  VAbv,  VBlw,     B,     B,     B,     B,     B,
+  /* 11A10 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 11A20 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 11A30 */     B,     B,     B,    FM,  VBlw, VMAbv, VMAbv, VMAbv, VMAbv, VMPst,     R,  MBlw,  MBlw,  MBlw,  MBlw,    GB,
+  /* 11A40 */     O,     O,     O,     O,     O,    GB,     O,     H,     O,     O,     O,     O,     O,     O,     O,     O,
+
+  /* Soyombo */
+
+  /* 11A50 */     B,  VAbv,  VBlw,  VBlw,  VAbv,  VAbv,  VAbv,  VPst,  VPst,  VBlw,  VBlw,  VBlw,     B,     B,     B,     B,
+  /* 11A60 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 11A70 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 11A80 */     B,     B,     B,     B,     O,     O,     R,     R,     R,     R,  FBlw,  FBlw,  FBlw,  FBlw,  FBlw,  FBlw,
+  /* 11A90 */  FBlw,  FBlw,  FBlw,  FBlw,  FBlw,  FBlw, VMAbv, VMPst, CMAbv,     H,     O,     O,     O,     O,     O,     O,
+
+#define use_offset_0x11c00u 5120
 
 
   /* Bhaiksuki */
 
   /* 11C00 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     B,     B,     B,     B,     B,     B,
   /* 11C10 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 11C20 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,  VPst,
   /* 11C30 */  VAbv,  VAbv,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,     O,  VAbv,  VAbv,  VAbv,  VAbv, VMAbv, VMAbv, VMPst,     H,
@@ -631,17 +651,29 @@ static const USE_TABLE_ELEMENT_TYPE use_
   /* Marchen */
 
   /* 11C70 */     O,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 11C80 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 11C90 */     O,     O,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,
   /* 11CA0 */   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,     O,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,
   /* 11CB0 */  VBlw,  VPre,  VBlw,  VAbv,  VPst, VMAbv, VMAbv,     O,
 
-}; /* Table items: 5144; occupancy: 72% */
+#define use_offset_0x11d00u 5304
+
+
+  /* Masaram Gondi */
+
+  /* 11D00 */     B,     B,     B,     B,     B,     B,     B,     O,     B,     B,     O,     B,     B,     B,     B,     B,
+  /* 11D10 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 11D20 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 11D30 */     B,  VAbv,  VAbv,  VAbv,  VAbv,  VAbv,  VBlw,     O,     O,     O,  VAbv,     O,  VAbv,  VAbv,     O,  VAbv,
+  /* 11D40 */ VMAbv, VMAbv, CMBlw,  VAbv,  VBlw,     H,     R,  MBlw,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 11D50 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
+
+}; /* Table items: 5400; occupancy: 73% */
 
 USE_TABLE_ELEMENT_TYPE
 hb_use_get_categories (hb_codepoint_t u)
 {
   switch (u >> 12)
   {
     case 0x0u:
       if (hb_in_range<hb_codepoint_t> (u, 0x0028u, 0x003Fu)) return use_table[u - 0x0028u + use_offset_0x0028u];
@@ -679,28 +711,31 @@ hb_use_get_categories (hb_codepoint_t u)
       break;
 
     case 0x11u:
       if (hb_in_range<hb_codepoint_t> (u, 0x11000u, 0x110BFu)) return use_table[u - 0x11000u + use_offset_0x11000u];
       if (hb_in_range<hb_codepoint_t> (u, 0x11100u, 0x1123Fu)) return use_table[u - 0x11100u + use_offset_0x11100u];
       if (hb_in_range<hb_codepoint_t> (u, 0x11280u, 0x11377u)) return use_table[u - 0x11280u + use_offset_0x11280u];
       if (hb_in_range<hb_codepoint_t> (u, 0x11400u, 0x114DFu)) return use_table[u - 0x11400u + use_offset_0x11400u];
       if (hb_in_range<hb_codepoint_t> (u, 0x11580u, 0x1173Fu)) return use_table[u - 0x11580u + use_offset_0x11580u];
+      if (hb_in_range<hb_codepoint_t> (u, 0x11A00u, 0x11A9Fu)) return use_table[u - 0x11A00u + use_offset_0x11a00u];
       if (hb_in_range<hb_codepoint_t> (u, 0x11C00u, 0x11CB7u)) return use_table[u - 0x11C00u + use_offset_0x11c00u];
+      if (hb_in_range<hb_codepoint_t> (u, 0x11D00u, 0x11D5Fu)) return use_table[u - 0x11D00u + use_offset_0x11d00u];
       if (unlikely (u == 0x1107Fu)) return HN;
       break;
 
     default:
       break;
   }
   return USE_O;
 }
 
 #undef B
 #undef CGJ
+#undef CS
 #undef FM
 #undef GB
 #undef H
 #undef HN
 #undef IND
 #undef N
 #undef O
 #undef R
--- a/gfx/harfbuzz/src/hb-ot-shape-complex-use.cc
+++ b/gfx/harfbuzz/src/hb-ot-shape-complex-use.cc
@@ -602,11 +602,12 @@ const hb_ot_complex_shaper_t _hb_ot_comp
   data_destroy_use,
   NULL, /* preprocess_text */
   NULL, /* postprocess_glyphs */
   HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT,
   decompose_use,
   compose_use,
   setup_masks_use,
   NULL, /* disable_otl */
+  NULL, /* reorder_marks */
   HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY,
   false, /* fallback_position */
 };
--- a/gfx/harfbuzz/src/hb-ot-shape-normalize.cc
+++ b/gfx/harfbuzz/src/hb-ot-shape-normalize.cc
@@ -340,76 +340,92 @@ void
     if (_hb_glyph_info_get_modified_combining_class (&buffer->info[i]) == 0)
       continue;
 
     unsigned int end;
     for (end = i + 1; end < count; end++)
       if (_hb_glyph_info_get_modified_combining_class (&buffer->info[end]) == 0)
         break;
 
-    /* We are going to do a O(n^2).  Only do this if the sequence is short. */
-    if (end - i > 10) {
+    /* We are going to do a O(n^2).  Only do this if the sequence is short,
+     * but not too short ;). */
+    if (end - i < 2 || end - i > HB_OT_SHAPE_COMPLEX_MAX_COMBINING_MARKS) {
       i = end;
       continue;
     }
 
     buffer->sort (i, end, compare_combining_class);
 
+    if (plan->shaper->reorder_marks)
+      plan->shaper->reorder_marks (plan, buffer, i, end);
+
     i = end;
   }
 
 
   if (mode == HB_OT_SHAPE_NORMALIZATION_MODE_NONE ||
       mode == HB_OT_SHAPE_NORMALIZATION_MODE_DECOMPOSED)
     return;
 
   /* Third round, recompose */
 
   /* As noted in the comment earlier, we don't try to combine
    * ccc=0 chars with their previous Starter. */
 
   buffer->clear_output ();
   count = buffer->len;
   unsigned int starter = 0;
+  bool combine = true;
   buffer->next_glyph ();
   while (buffer->idx < count && !buffer->in_error)
   {
     hb_codepoint_t composed, glyph;
-    if (/* We don't try to compose a non-mark character with it's preceding starter.
+    if (combine &&
+	/* We don't try to compose a non-mark character with it's preceding starter.
 	 * This is both an optimization to avoid trying to compose every two neighboring
 	 * glyphs in most scripts AND a desired feature for Hangul.  Apparently Hangul
 	 * fonts are not designed to mix-and-match pre-composed syllables and Jamo. */
-	HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->cur())) &&
-	/* If there's anything between the starter and this char, they should have CCC
-	 * smaller than this character's. */
-	(starter == buffer->out_len - 1 ||
-	 _hb_glyph_info_get_modified_combining_class (&buffer->prev()) < _hb_glyph_info_get_modified_combining_class (&buffer->cur())) &&
-	/* And compose. */
-	c.compose (&c,
-		   buffer->out_info[starter].codepoint,
-		   buffer->cur().codepoint,
-		   &composed) &&
-	/* And the font has glyph for the composite. */
-	font->get_nominal_glyph (composed, &glyph))
+	HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->cur())))
     {
-      /* Composes. */
-      buffer->next_glyph (); /* Copy to out-buffer. */
-      if (unlikely (buffer->in_error))
-        return;
-      buffer->merge_out_clusters (starter, buffer->out_len);
-      buffer->out_len--; /* Remove the second composable. */
-      /* Modify starter and carry on. */
-      buffer->out_info[starter].codepoint = composed;
-      buffer->out_info[starter].glyph_index() = glyph;
-      _hb_glyph_info_set_unicode_props (&buffer->out_info[starter], buffer);
+      if (/* If there's anything between the starter and this char, they should have CCC
+	   * smaller than this character's. */
+	  (starter == buffer->out_len - 1 ||
+	   info_cc (buffer->prev()) < info_cc (buffer->cur())) &&
+	  /* And compose. */
+	  c.compose (&c,
+		     buffer->out_info[starter].codepoint,
+		     buffer->cur().codepoint,
+		     &composed) &&
+	  /* And the font has glyph for the composite. */
+	  font->get_nominal_glyph (composed, &glyph))
+      {
+	/* Composes. */
+	buffer->next_glyph (); /* Copy to out-buffer. */
+	if (unlikely (buffer->in_error))
+	  return;
+	buffer->merge_out_clusters (starter, buffer->out_len);
+	buffer->out_len--; /* Remove the second composable. */
+	/* Modify starter and carry on. */
+	buffer->out_info[starter].codepoint = composed;
+	buffer->out_info[starter].glyph_index() = glyph;
+	_hb_glyph_info_set_unicode_props (&buffer->out_info[starter], buffer);
 
-      continue;
+	continue;
+      }
+      else if (/* We sometimes custom-tailor the sorted order of marks. In that case, stop
+		* trying to combine as soon as combining-class drops. */
+	       starter < buffer->out_len - 1 &&
+	       info_cc (buffer->prev()) > info_cc (buffer->cur()))
+        combine = false;
     }
 
     /* Blocked, or doesn't compose. */
     buffer->next_glyph ();
 
-    if (_hb_glyph_info_get_modified_combining_class (&buffer->prev()) == 0)
+    if (info_cc (buffer->prev()) == 0)
+    {
       starter = buffer->out_len - 1;
+      combine = true;
+    }
   }
   buffer->swap_buffers ();
 
 }
--- a/gfx/harfbuzz/src/hb-ot-shape.cc
+++ b/gfx/harfbuzz/src/hb-ot-shape.cc
@@ -688,86 +688,82 @@ hb_ot_position_default (hb_ot_shape_cont
   }
   if (c->buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_SPACE_FALLBACK)
     _hb_ot_shape_fallback_spaces (c->plan, c->font, c->buffer);
 }
 
 static inline void
 hb_ot_position_complex (hb_ot_shape_context_t *c)
 {
-  hb_ot_layout_position_start (c->font, c->buffer);
-
   unsigned int count = c->buffer->len;
+  hb_glyph_info_t *info = c->buffer->info;
+  hb_glyph_position_t *pos = c->buffer->pos;
 
   /* If the font has no GPOS, AND, no fallback positioning will
    * happen, AND, direction is forward, then when zeroing mark
    * widths, we shift the mark with it, such that the mark
    * is positioned hanging over the previous glyph.  When
    * direction is backward we don't shift and it will end up
    * hanging over the next glyph after the final reordering.
    * If fallback positinoing happens or GPOS is present, we don't
    * care.
    */
   bool adjust_offsets_when_zeroing = c->fallback_positioning &&
 				     !c->plan->shaper->fallback_position &&
 				     HB_DIRECTION_IS_FORWARD (c->buffer->props.direction);
 
+  /* We change glyph origin to what GPOS expects (horizontal), apply GPOS, change it back. */
+
+  /* The nil glyph_h_origin() func returns 0, so no need to apply it. */
+  if (c->font->has_glyph_h_origin_func ())
+    for (unsigned int i = 0; i < count; i++)
+      c->font->add_glyph_h_origin (info[i].codepoint,
+				   &pos[i].x_offset,
+				   &pos[i].y_offset);
+
+  hb_ot_layout_position_start (c->font, c->buffer);
+
   switch (c->plan->shaper->zero_width_marks)
   {
     case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY:
       zero_mark_widths_by_gdef (c->buffer, adjust_offsets_when_zeroing);
       break;
 
     default:
     case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE:
     case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE:
       break;
   }
 
   if (likely (!c->fallback_positioning))
-  {
-    hb_glyph_info_t *info = c->buffer->info;
-    hb_glyph_position_t *pos = c->buffer->pos;
-
-    /* Change glyph origin to what GPOS expects (horizontal), apply GPOS, change it back. */
-
-    /* The nil glyph_h_origin() func returns 0, so no need to apply it. */
-    if (c->font->has_glyph_h_origin_func ())
-      for (unsigned int i = 0; i < count; i++)
-	c->font->add_glyph_h_origin (info[i].codepoint,
-				     &pos[i].x_offset,
-				     &pos[i].y_offset);
-
     c->plan->position (c->font, c->buffer);
 
-    /* The nil glyph_h_origin() func returns 0, so no need to apply it. */
-    if (c->font->has_glyph_h_origin_func ())
-      for (unsigned int i = 0; i < count; i++)
-	c->font->subtract_glyph_h_origin (info[i].codepoint,
-					  &pos[i].x_offset,
-					  &pos[i].y_offset);
-
-  }
-
   switch (c->plan->shaper->zero_width_marks)
   {
     case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE:
       zero_mark_widths_by_gdef (c->buffer, adjust_offsets_when_zeroing);
       break;
 
     default:
     case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE:
     case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY:
       break;
   }
 
   /* Finishing off GPOS has to follow a certain order. */
   hb_ot_layout_position_finish_advances (c->font, c->buffer);
   hb_ot_zero_width_default_ignorables (c);
   hb_ot_layout_position_finish_offsets (c->font, c->buffer);
+
+  /* The nil glyph_h_origin() func returns 0, so no need to apply it. */
+  if (c->font->has_glyph_h_origin_func ())
+    for (unsigned int i = 0; i < count; i++)
+      c->font->subtract_glyph_h_origin (info[i].codepoint,
+					&pos[i].x_offset,
+					&pos[i].y_offset);
 }
 
 static inline void
 hb_ot_position (hb_ot_shape_context_t *c)
 {
   c->buffer->clear_positions ();
 
   hb_ot_position_default (c);
--- a/gfx/harfbuzz/src/hb-ot-tag.cc
+++ b/gfx/harfbuzz/src/hb-ot-tag.cc
@@ -265,57 +265,71 @@ static const LangTag ot_languages[] = {
   {"bts",	HB_TAG('B','T','S',' ')},	/* Batak Simalungun */
   {"bug",	HB_TAG('B','U','G',' ')},	/* Buginese */
   {"bxr",	HB_TAG('R','B','U',' ')},	/* Russian Buriat */
   {"byn",	HB_TAG('B','I','L',' ')},	/* Bilen */
   {"ca",	HB_TAG('C','A','T',' ')},	/* Catalan */
   {"cak",	HB_TAG('C','A','K',' ')},	/* Kaqchikel */
   {"cbk",	HB_TAG('C','B','K',' ')},	/* Chavacano */
   {"cbl",	HB_TAG('Q','I','N',' ')},	/* Bualkhaw Chin */
+  {"cco",	HB_TAG('C','C','H','N')},	/* Chinantec */
   {"ce",	HB_TAG('C','H','E',' ')},	/* Chechen */
   {"ceb",	HB_TAG('C','E','B',' ')},	/* Cebuano */
   {"cfm",	HB_TAG('H','A','L',' ')},	/* Halam/Falam Chin */
   {"cgg",	HB_TAG('C','G','G',' ')},	/* Chiga */
   {"ch",	HB_TAG('C','H','A',' ')},	/* Chamorro */
+  {"chj",	HB_TAG('C','C','H','N')},	/* Chinantec */
   {"chk",	HB_TAG('C','H','K','0')},	/* Chuukese */
   {"cho",	HB_TAG('C','H','O',' ')},	/* Choctaw */
   {"chp",	HB_TAG('C','H','P',' ')},	/* Chipewyan */
+  {"chq",	HB_TAG('C','C','H','N')},	/* Chinantec */
   {"chr",	HB_TAG('C','H','R',' ')},	/* Cherokee */
   {"chy",	HB_TAG('C','H','Y',' ')},	/* Cheyenne */
+  {"chz",	HB_TAG('C','C','H','N')},	/* Chinantec */
   {"cja",	HB_TAG('C','J','A',' ')},	/* Western Cham */
   {"cjm",	HB_TAG('C','J','M',' ')},	/* Eastern Cham */
   {"cka",	HB_TAG('Q','I','N',' ')},	/* Khumi Awa Chin */
   {"ckb",	HB_TAG('K','U','R',' ')},	/* Central Kurdish (Sorani) */
   {"ckt",	HB_TAG('C','H','K',' ')},	/* Chukchi */
   {"cld",	HB_TAG('S','Y','R',' ')},	/* Chaldean Neo-Aramaic */
+  {"cle",	HB_TAG('C','C','H','N')},	/* Chinantec */
   {"cmr",	HB_TAG('Q','I','N',' ')},	/* Mro-Khimi Chin */
   {"cnb",	HB_TAG('Q','I','N',' ')},	/* Chinbon Chin */
   {"cnh",	HB_TAG('Q','I','N',' ')},	/* Hakha Chin */
   {"cnk",	HB_TAG('Q','I','N',' ')},	/* Khumi Chin */
+  {"cnl",	HB_TAG('C','C','H','N')},	/* Chinantec */
+  {"cnt",	HB_TAG('C','C','H','N')},	/* Chinantec */
   {"cnw",	HB_TAG('Q','I','N',' ')},	/* Ngawn Chin */
   {"cop",	HB_TAG('C','O','P',' ')},	/* Coptic */
+  {"cpa",	HB_TAG('C','C','H','N')},	/* Chinantec */
   {"cpp",	HB_TAG('C','P','P',' ')},	/* Creoles */
   {"cr",	HB_TAG('C','R','E',' ')},	/* Cree */
   {"cre",	HB_TAG('Y','C','R',' ')},	/* Y-Cree */
   {"crh",	HB_TAG('C','R','T',' ')},	/* Crimean Tatar */
   {"crj",	HB_TAG('E','C','R',' ')},	/* [Southern] East Cree */
   {"crk",	HB_TAG('W','C','R',' ')},	/* West-Cree */
   {"crl",	HB_TAG('E','C','R',' ')},	/* [Northern] East Cree */
   {"crm",	HB_TAG('M','C','R',' ')},	/* Moose Cree */
   {"crx",	HB_TAG('C','R','R',' ')},	/* Carrier */
   {"cs",	HB_TAG('C','S','Y',' ')},	/* Czech */
+  {"csa",	HB_TAG('C','C','H','N')},	/* Chinantec */
   {"csb",	HB_TAG('C','S','B',' ')},	/* Kashubian */
   {"csh",	HB_TAG('Q','I','N',' ')},	/* Asho Chin */
+  {"cso",	HB_TAG('C','C','H','N')},	/* Chinantec */
   {"csy",	HB_TAG('Q','I','N',' ')},	/* Siyin Chin */
   {"ctd",	HB_TAG('Q','I','N',' ')},	/* Tedim Chin */
+  {"cte",	HB_TAG('C','C','H','N')},	/* Chinantec */
   {"ctg",	HB_TAG('C','T','G',' ')},	/* Chittagonian */
+  {"ctl",	HB_TAG('C','C','H','N')},	/* Chinantec */
   {"cts",	HB_TAG('B','I','K',' ')},	/* Northern Catanduanes Bikol */
   {"cu",	HB_TAG('C','S','L',' ')},	/* Church Slavic */
+  {"cuc",	HB_TAG('C','C','H','N')},	/* Chinantec */
   {"cuk",	HB_TAG('C','U','K',' ')},	/* San Blas Kuna */
   {"cv",	HB_TAG('C','H','U',' ')},	/* Chuvash */
+  {"cvn",	HB_TAG('C','C','H','N')},	/* Chinantec */
   {"cwd",	HB_TAG('D','C','R',' ')},	/* Woods Cree */
   {"cy",	HB_TAG('W','E','L',' ')},	/* Welsh */
   {"czt",	HB_TAG('Q','I','N',' ')},	/* Zotung Chin */
   {"da",	HB_TAG('D','A','N',' ')},	/* Danish */
   {"dao",	HB_TAG('Q','I','N',' ')},	/* Daai Chin */
   {"dap",	HB_TAG('N','I','S',' ')},	/* Nisi (India) */
   {"dar",	HB_TAG('D','A','R',' ')},	/* Dargwa */
   {"dax",	HB_TAG('D','A','X',' ')},	/* Dayi */
@@ -375,17 +389,16 @@ static const LangTag ot_languages[] = {
   {"gd",	HB_TAG('G','A','E',' ')},	/* Scottish Gaelic */
   {"gez",	HB_TAG('G','E','Z',' ')},	/* Ge'ez */
   {"ggo",	HB_TAG('G','O','N',' ')},	/* Southern Gondi */
   {"gih",	HB_TAG('G','I','H',' ')},	/* Githabul */
   {"gil",	HB_TAG('G','I','L','0')},	/* Kiribati (Gilbertese) */
   {"gkp",	HB_TAG('G','K','P',' ')},	/* Kpelle (Guinea) */
   {"gl",	HB_TAG('G','A','L',' ')},	/* Galician */
   {"gld",	HB_TAG('N','A','N',' ')},	/* Nanai */
-  {"gle",	HB_TAG('I','R','T',' ')},	/* Irish Traditional */
   {"glk",	HB_TAG('G','L','K',' ')},	/* Gilaki */
   {"gn",	HB_TAG('G','U','A',' ')},	/* Guarani [macrolanguage] */
   {"gnn",	HB_TAG('G','N','N',' ')},	/* Gumatj */
   {"gno",	HB_TAG('G','O','N',' ')},	/* Northern Gondi */
   {"gog",	HB_TAG('G','O','G',' ')},	/* Gogo */
   {"gon",	HB_TAG('G','O','N',' ')},	/* Gondi [macrolanguage] */
   {"grt",	HB_TAG('G','R','O',' ')},	/* Garo */
   {"gru",	HB_TAG('S','O','G',' ')},	/* Sodo Gurage */
@@ -533,17 +546,16 @@ static const LangTag ot_languages[] = {
   {"luy",	HB_TAG('L','U','H',' ')},	/* Luyia/Oluluyia [macrolanguage] */
   {"luz",	HB_TAG('L','R','C',' ')},	/* Southern Luri */
   {"lv",	HB_TAG('L','V','I',' ')},	/* Latvian */
   {"lzz",	HB_TAG('L','A','Z',' ')},	/* Laz */
   {"mad",	HB_TAG('M','A','D',' ')},	/* Madurese */
   {"mag",	HB_TAG('M','A','G',' ')},	/* Magahi */
   {"mai",	HB_TAG('M','T','H',' ')},	/* Maithili */
   {"mak",	HB_TAG('M','K','R',' ')},	/* Makasar */
-  {"mal",	HB_TAG('M','A','L',' ')},	/* Malayalam */
   {"mam",	HB_TAG('M','A','M',' ')},	/* Mam */
   {"man",	HB_TAG('M','N','K',' ')},	/* Manding/Mandingo [macrolanguage] */
   {"mdc",	HB_TAG('M','L','E',' ')},	/* Male (Papua New Guinea) */
   {"mdf",	HB_TAG('M','O','K',' ')},	/* Moksha */
   {"mdr",	HB_TAG('M','D','R',' ')},	/* Mandar */
   {"mdy",	HB_TAG('M','L','E',' ')},	/* Male (Ethiopia) */
   {"men",	HB_TAG('M','D','E',' ')},	/* Mende (Sierra Leone) */
   {"mer",	HB_TAG('M','E','R',' ')},	/* Meru */
--- a/gfx/harfbuzz/src/hb-shaper-private.hh
+++ b/gfx/harfbuzz/src/hb-shaper-private.hh
@@ -83,21 +83,33 @@ struct hb_shaper_data_t {
 	HB_SHAPER_DATA_ENSURE_FUNC (shaper, object) (hb_##object##_t *object)
 
 #define HB_SHAPER_DATA_DESTROY(shaper, object) \
     if (HB_SHAPER_DATA_TYPE (shaper, object) *data = HB_SHAPER_DATA (shaper, object)) \
       if (data != HB_SHAPER_DATA_INVALID && data != HB_SHAPER_DATA_SUCCEEDED) \
         HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (data);
 
 #define HB_SHAPER_DATA_ENSURE_DEFINE(shaper, object) \
+	HB_SHAPER_DATA_ENSURE_DEFINE_WITH_CONDITION(shaper, object, true)
+
+#define HB_SHAPER_DATA_ENSURE_DEFINE_WITH_CONDITION(shaper, object, condition) \
 bool \
 HB_SHAPER_DATA_ENSURE_FUNC(shaper, object) (hb_##object##_t *object) \
 {\
   retry: \
   HB_SHAPER_DATA_TYPE (shaper, object) *data = (HB_SHAPER_DATA_TYPE (shaper, object) *) hb_atomic_ptr_get (&HB_SHAPER_DATA (shaper, object)); \
+  if (likely (data) && !(condition)) { \
+    /* Drop and recreate. */ \
+    /* If someone dropped it in the mean time, throw it away and don't touch it. \
+     * Otherwise, destruct it. */ \
+    if (hb_atomic_ptr_cmpexch (&HB_SHAPER_DATA (shaper, object), data, NULL)) { \
+      HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (data); \
+    } \
+    goto retry; \
+  } \
   if (unlikely (!data)) { \
     data = HB_SHAPER_DATA_CREATE_FUNC (shaper, object) (object); \
     if (unlikely (!data)) \
       data = (HB_SHAPER_DATA_TYPE (shaper, object) *) HB_SHAPER_DATA_INVALID; \
     if (!hb_atomic_ptr_cmpexch (&HB_SHAPER_DATA (shaper, object), NULL, data)) { \
       if (data && \
 	  data != HB_SHAPER_DATA_INVALID && \
 	  data != HB_SHAPER_DATA_SUCCEEDED) \
--- a/gfx/harfbuzz/src/hb-ucdn.cc
+++ b/gfx/harfbuzz/src/hb-ucdn.cc
@@ -155,72 +155,81 @@ static const hb_script_t ucdn_script_tra
     HB_SCRIPT_OLD_HUNGARIAN,
     HB_SCRIPT_SIGNWRITING,
     HB_SCRIPT_ADLAM,
     HB_SCRIPT_BHAIKSUKI,
     HB_SCRIPT_MARCHEN,
     HB_SCRIPT_NEWA,
     HB_SCRIPT_OSAGE,
     HB_SCRIPT_TANGUT,
+    HB_SCRIPT_MASARAM_GONDI,
+    HB_SCRIPT_NUSHU,
+    HB_SCRIPT_SOYOMBO,
+    HB_SCRIPT_ZANABAZAR_SQUARE,
 };
 
 static hb_unicode_combining_class_t
-hb_ucdn_combining_class(hb_unicode_funcs_t *ufuncs, hb_codepoint_t unicode,
+hb_ucdn_combining_class(hb_unicode_funcs_t *ufuncs HB_UNUSED,
+			hb_codepoint_t unicode,
 			void *user_data HB_UNUSED)
 {
     return (hb_unicode_combining_class_t) ucdn_get_combining_class(unicode);
 }
 
 static unsigned int
-hb_ucdn_eastasian_width(hb_unicode_funcs_t *ufuncs, hb_codepoint_t unicode,
+hb_ucdn_eastasian_width(hb_unicode_funcs_t *ufuncs HB_UNUSED,
+			hb_codepoint_t unicode,
 			void *user_data HB_UNUSED)
 {
     int w = ucdn_get_east_asian_width(unicode);
     return (w == UCDN_EAST_ASIAN_F || w == UCDN_EAST_ASIAN_W) ? 2 : 1;
 }
 
 static hb_unicode_general_category_t
-hb_ucdn_general_category(hb_unicode_funcs_t *ufuncs, hb_codepoint_t unicode,
+hb_ucdn_general_category(hb_unicode_funcs_t *ufuncs HB_UNUSED,
+			 hb_codepoint_t unicode,
 			 void *user_data HB_UNUSED)
 {
     return (hb_unicode_general_category_t)ucdn_get_general_category(unicode);
 }
 
 static hb_codepoint_t
-hb_ucdn_mirroring(hb_unicode_funcs_t *ufuncs, hb_codepoint_t unicode,
+hb_ucdn_mirroring(hb_unicode_funcs_t *ufuncs HB_UNUSED,
+		  hb_codepoint_t unicode,
 		  void *user_data HB_UNUSED)
 {
     return ucdn_mirror(unicode);
 }
 
 static hb_script_t
-hb_ucdn_script(hb_unicode_funcs_t *ufuncs, hb_codepoint_t unicode,
+hb_ucdn_script(hb_unicode_funcs_t *ufuncs HB_UNUSED,
+	       hb_codepoint_t unicode,
 	       void *user_data HB_UNUSED)
 {
     return ucdn_script_translate[ucdn_get_script(unicode)];
 }
 
 static hb_bool_t
-hb_ucdn_compose(hb_unicode_funcs_t *ufuncs,
+hb_ucdn_compose(hb_unicode_funcs_t *ufuncs HB_UNUSED,
 		hb_codepoint_t a, hb_codepoint_t b, hb_codepoint_t *ab,
 		void *user_data HB_UNUSED)
 {
     return ucdn_compose(ab, a, b);
 }
 
 static hb_bool_t
-hb_ucdn_decompose(hb_unicode_funcs_t *ufuncs,
+hb_ucdn_decompose(hb_unicode_funcs_t *ufuncs HB_UNUSED,
 		  hb_codepoint_t ab, hb_codepoint_t *a, hb_codepoint_t *b,
 		  void *user_data HB_UNUSED)
 {
     return ucdn_decompose(ab, a, b);
 }
 
 static unsigned int
-hb_ucdn_decompose_compatibility(hb_unicode_funcs_t *ufuncs,
+hb_ucdn_decompose_compatibility(hb_unicode_funcs_t *ufuncs HB_UNUSED,
 				hb_codepoint_t u, hb_codepoint_t *decomposed,
 				void *user_data HB_UNUSED)
 {
     return ucdn_compat_decompose(u, decomposed);
 }
 
 extern "C" HB_INTERNAL
 hb_unicode_funcs_t *
--- a/gfx/harfbuzz/src/hb-unicode-private.hh
+++ b/gfx/harfbuzz/src/hb-unicode-private.hh
@@ -100,24 +100,20 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIM
     decomposed[ret] = 0;
     return ret;
   }
 
 
   inline unsigned int
   modified_combining_class (hb_codepoint_t unicode)
   {
-    /* XXX This hack belongs to the Arabic shaper:
-     * Put HAMZA ABOVE in the same class as SHADDA. */
-    if (unlikely (unicode == 0x0654u)) unicode = 0x0651u;
-
     /* XXX This hack belongs to the Myanmar shaper. */
     if (unlikely (unicode == 0x1037u)) unicode = 0x103Au;
 
-    /* XXX This hack belongs to the SEA shaper (for Tai Tham):
+    /* XXX This hack belongs to the USE shaper (for Tai Tham):
      * Reorder SAKOT to ensure it comes after any tone marks. */
     if (unlikely (unicode == 0x1A60u)) return 254;
 
     /* XXX This hack belongs to the Tibetan shaper:
      * Reorder PADMA to ensure it comes after any vowel marks. */
     if (unlikely (unicode == 0x0FC6u)) return 254;
     /* Reorder TSA -PHRU to reorder before U+0F74 */
     if (unlikely (unicode == 0x0F39u)) return 127;
@@ -136,16 +132,17 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIM
   }
 
   /* Default_Ignorable codepoints:
    *
    * Note: While U+115F, U+1160, U+3164 and U+FFA0 are Default_Ignorable,
    * we do NOT want to hide them, as the way Uniscribe has implemented them
    * is with regular spacing glyphs, and that's the way fonts are made to work.
    * As such, we make exceptions for those four.
+   * Also ignoring U+1BCA0..1BCA3. https://github.com/behdad/harfbuzz/issues/503
    *
    * Unicode 7.0:
    * $ grep '; Default_Ignorable_Code_Point ' DerivedCoreProperties.txt | sed 's/;.*#/#/'
    * 00AD          # Cf       SOFT HYPHEN
    * 034F          # Mn       COMBINING GRAPHEME JOINER
    * 061C          # Cf       ARABIC LETTER MARK
    * 115F..1160    # Lo   [2] HANGUL CHOSEONG FILLER..HANGUL JUNGSEONG FILLER
    * 17B4..17B5    # Mn   [2] KHMER VOWEL INHERENT AQ..KHMER VOWEL INHERENT AA
@@ -192,18 +189,17 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIM
 	case 0xFF: return hb_in_range<hb_codepoint_t> (ch, 0xFFF0u, 0xFFF8u);
 	default: return false;
       }
     }
     else
     {
       /* Other planes */
       switch (plane) {
-	case 0x01: return hb_in_ranges<hb_codepoint_t> (ch, 0x1BCA0u, 0x1BCA3u,
-					    0x1D173u, 0x1D17Au);
+	case 0x01: return hb_in_range<hb_codepoint_t> (ch, 0x1D173u, 0x1D17Au);
 	case 0x0E: return hb_in_range<hb_codepoint_t> (ch, 0xE0000u, 0xE0FFFu);
 	default: return false;
       }
     }
   }
 
   /* Space estimates based on:
    * http://www.unicode.org/charts/PDF/U2000.pdf
--- a/gfx/harfbuzz/src/hb-version.h
+++ b/gfx/harfbuzz/src/hb-version.h
@@ -32,20 +32,20 @@
 #define HB_VERSION_H
 
 #include "hb-common.h"
 
 HB_BEGIN_DECLS
 
 
 #define HB_VERSION_MAJOR 1
-#define HB_VERSION_MINOR 5
-#define HB_VERSION_MICRO 1
+#define HB_VERSION_MINOR 6
+#define HB_VERSION_MICRO 0
 
-#define HB_VERSION_STRING "1.5.1"
+#define HB_VERSION_STRING "1.6.0"
 
 #define HB_VERSION_ATLEAST(major,minor,micro) \
 	((major)*10000+(minor)*100+(micro) <= \
 	 HB_VERSION_MAJOR*10000+HB_VERSION_MINOR*100+HB_VERSION_MICRO)
 
 
 HB_EXTERN void
 hb_version (unsigned int *major,