diff --git a/modules/text_server_adv/SCsub b/modules/text_server_adv/SCsub index 2f108f89268..9b08b73c987 100644 --- a/modules/text_server_adv/SCsub +++ b/modules/text_server_adv/SCsub @@ -55,6 +55,7 @@ if env["builtin_harfbuzz"]: # "src/hb-glib.cc", # "src/hb-gobject-structs.cc", "src/hb-icu.cc", + # "src/hb-kbts.cc", "src/hb-map.cc", "src/hb-number.cc", "src/hb-ot-cff1-table.cc", @@ -95,14 +96,19 @@ if env["builtin_harfbuzz"]: "src/hb-shaper.cc", "src/hb-static.cc", "src/hb-style.cc", - "src/hb-subset-cff-common.cc", - "src/hb-subset-cff1.cc", - "src/hb-subset-cff2.cc", - "src/hb-subset-input.cc", - "src/hb-subset-instancer-iup.cc", - "src/hb-subset-instancer-solver.cc", - "src/hb-subset-plan.cc", - "src/hb-subset-serialize.cc", + # "src/hb-subset-cff-common.cc", + # "src/hb-subset-cff1.cc", + # "src/hb-subset-cff2.cc", + # "src/hb-subset-input.cc", + # "src/hb-subset-instancer-iup.cc", + # "src/hb-subset-instancer-solver.cc", + # "src/hb-subset-plan.cc", + # "src/hb-subset-serialize.cc", + # "src/hb-subset-table-cff.cc", + # "src/hb-subset-table-color.cc", + # "src/hb-subset-table-layout.cc", + # "src/hb-subset-table-other.cc", + # "src/hb-subset-table-var.cc", "src/hb-subset.cc", "src/hb-ucd.cc", "src/hb-unicode.cc", diff --git a/thirdparty/README.md b/thirdparty/README.md index ac5a92b919a..49c24897ca2 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -436,7 +436,7 @@ Patches: ## harfbuzz - Upstream: https://github.com/harfbuzz/harfbuzz -- Version: 11.3.2 (4e3df1c1383481ed5717603d5dd3453a04fb16ba, 2025) +- Version: 12.1.0 (a790c38b782f9d8e6f0299d2837229e5726fc669, 2025) - License: MIT Files extracted from upstream source: diff --git a/thirdparty/harfbuzz/src/OT/Color/COLR/COLR.hh b/thirdparty/harfbuzz/src/OT/Color/COLR/COLR.hh index 896b0fb1034..6f575934f9e 100644 --- a/thirdparty/harfbuzz/src/OT/Color/COLR/COLR.hh +++ b/thirdparty/harfbuzz/src/OT/Color/COLR/COLR.hh @@ -178,7 +178,10 @@ struct hb_colrv1_closure_context_t : { glyphs->add (glyph_id); } void add_layer_indices (unsigned first_layer_index, unsigned num_of_layers) - { layer_indices->add_range (first_layer_index, first_layer_index + num_of_layers - 1); } + { + if (num_of_layers == 0) return; + layer_indices->add_range (first_layer_index, first_layer_index + num_of_layers - 1); + } void add_palette_index (unsigned palette_index) { palette_indices->add (palette_index); } @@ -650,10 +653,10 @@ struct PaintColrLayers TRACE_SUBSET (this); auto *out = c->serializer->embed (this); if (unlikely (!out)) return_trace (false); - return_trace (c->serializer->check_assign (out->firstLayerIndex, c->plan->colrv1_layers.get (firstLayerIndex), - HB_SERIALIZE_ERROR_INT_OVERFLOW)); - return_trace (true); + uint32_t first_layer_index = numLayers ? c->plan->colrv1_layers.get (firstLayerIndex) : 0; + return_trace (c->serializer->check_assign (out->firstLayerIndex, first_layer_index, + HB_SERIALIZE_ERROR_INT_OVERFLOW)); } bool sanitize (hb_sanitize_context_t *c) const @@ -2057,7 +2060,7 @@ struct delta_set_index_map_subset_plan_t outer_bit_count = 1; inner_bit_count = 1; - if (unlikely (!output_map.resize (map_count, false))) return false; + if (unlikely (!output_map.resize_dirty (map_count))) return false; for (unsigned idx = 0; idx < map_count; idx++) { diff --git a/thirdparty/harfbuzz/src/OT/Color/CPAL/CPAL.hh b/thirdparty/harfbuzz/src/OT/Color/CPAL/CPAL.hh index 940126a86c5..2b8b69b6009 100644 --- a/thirdparty/harfbuzz/src/OT/Color/CPAL/CPAL.hh +++ b/thirdparty/harfbuzz/src/OT/Color/CPAL/CPAL.hh @@ -307,6 +307,7 @@ struct CPAL if (first_color_to_layer_index.has (first_color_record_idx)) continue; first_color_index_for_layer.push (first_color_record_idx); + if (unlikely (!c->serializer->propagate_error (first_color_index_for_layer))) return_trace (false); first_color_to_layer_index.set (first_color_record_idx, first_color_index_for_layer.length - 1); } diff --git a/thirdparty/harfbuzz/src/OT/Layout/Common/Coverage.hh b/thirdparty/harfbuzz/src/OT/Layout/Common/Coverage.hh index daa1979544c..edf09db2de1 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/Common/Coverage.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/Common/Coverage.hh @@ -97,12 +97,17 @@ struct Coverage } } unsigned int get_coverage (hb_codepoint_t glyph_id, - hb_ot_lookup_cache_t *cache) const + hb_ot_layout_mapping_cache_t *cache) const { unsigned coverage; - if (cache && cache->get (glyph_id, &coverage)) return coverage; + if (cache && cache->get (glyph_id, &coverage)) return coverage < cache->MAX_VALUE ? coverage : NOT_COVERED; coverage = get_coverage (glyph_id); - if (cache) cache->set (glyph_id, coverage); + if (cache) { + if (coverage == NOT_COVERED) + cache->set_unchecked (glyph_id, cache->MAX_VALUE); + else if (likely (coverage < cache->MAX_VALUE)) + cache->set_unchecked (glyph_id, coverage); + } return coverage; } @@ -332,7 +337,7 @@ struct Coverage } iter_t __end__ () const { - iter_t it = {}; + iter_t it; it.format = format; switch (format) { diff --git a/thirdparty/harfbuzz/src/OT/Layout/GDEF/GDEF.hh b/thirdparty/harfbuzz/src/OT/Layout/GDEF/GDEF.hh index 79de21e5919..ed397b75088 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GDEF/GDEF.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GDEF/GDEF.hh @@ -977,7 +977,7 @@ struct GDEF } #ifndef HB_NO_GDEF_CACHE - table->get_mark_glyph_sets ().collect_coverage (mark_glyph_set_digests); + table->get_mark_glyph_sets ().collect_coverage (mark_glyph_sets); #endif } ~accelerator_t () { table.destroy (); } @@ -1006,14 +1006,16 @@ struct GDEF { return #ifndef HB_NO_GDEF_CACHE - mark_glyph_set_digests[set_index].may_have (glyph_id) && + mark_glyph_sets[set_index].may_have (glyph_id) +#else + table->mark_set_covers (set_index, glyph_id) #endif - table->mark_set_covers (set_index, glyph_id); + ; } hb_blob_ptr_t table; #ifndef HB_NO_GDEF_CACHE - hb_vector_t mark_glyph_set_digests; + hb_vector_t mark_glyph_sets; mutable hb_cache_t<21, 3> glyph_props_cache; static_assert (sizeof (glyph_props_cache) == 512, ""); #endif diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/AnchorMatrix.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/AnchorMatrix.hh index 2557e9a7231..7e676371f7b 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/AnchorMatrix.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/AnchorMatrix.hh @@ -77,6 +77,13 @@ struct AnchorMatrix return_trace (true); } + + bool offset_is_null (unsigned row, unsigned col, unsigned num_cols) const + { + if (unlikely (row >= rows || col >= num_cols)) return true; + auto &offset = matrixZ[row * num_cols + col]; + return offset.is_null (); + } }; diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/GPOS.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/GPOS.hh index ce3f74d8c3b..762c19eae5a 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/GPOS.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/GPOS.hh @@ -80,9 +80,8 @@ propagate_attachment_offsets (hb_glyph_position_t *pos, { /* Adjusts offsets of attached glyphs (both cursive and mark) to accumulate * offset of glyph they are attached to. */ - int chain = pos[i].attach_chain(), type = pos[i].attach_type(); - if (likely (!chain)) - return; + int chain = pos[i].attach_chain(); + int type = pos[i].attach_type(); pos[i].attach_chain() = 0; @@ -94,7 +93,8 @@ propagate_attachment_offsets (hb_glyph_position_t *pos, if (unlikely (!nesting_level)) return; - propagate_attachment_offsets (pos, len, j, direction, nesting_level - 1); + if (pos[j].attach_chain()) + propagate_attachment_offsets (pos, len, j, direction, nesting_level - 1); assert (!!(type & GPOS_impl::ATTACH_TYPE_MARK) ^ !!(type & GPOS_impl::ATTACH_TYPE_CURSIVE)); @@ -110,17 +110,37 @@ propagate_attachment_offsets (hb_glyph_position_t *pos, pos[i].x_offset += pos[j].x_offset; pos[i].y_offset += pos[j].y_offset; - assert (j < i); - if (HB_DIRECTION_IS_FORWARD (direction)) - for (unsigned int k = j; k < i; k++) { - pos[i].x_offset -= pos[k].x_advance; - pos[i].y_offset -= pos[k].y_advance; - } - else - for (unsigned int k = j + 1; k < i + 1; k++) { - pos[i].x_offset += pos[k].x_advance; - pos[i].y_offset += pos[k].y_advance; - } + // i is the position of the mark; j is the base. + if (j < i) + { + /* This is the common case: mark follows base. + * And currently the only way in OpenType. */ + if (HB_DIRECTION_IS_FORWARD (direction)) + for (unsigned int k = j; k < i; k++) { + pos[i].x_offset -= pos[k].x_advance; + pos[i].y_offset -= pos[k].y_advance; + } + else + for (unsigned int k = j + 1; k < i + 1; k++) { + pos[i].x_offset += pos[k].x_advance; + pos[i].y_offset += pos[k].y_advance; + } + } + else // j > i + { + /* This can happen with `kerx`: a mark attaching + * to a base after it in the logical order. */ + if (HB_DIRECTION_IS_FORWARD (direction)) + for (unsigned int k = i; k < j; k++) { + pos[i].x_offset += pos[k].x_advance; + pos[i].y_offset += pos[k].y_advance; + } + else + for (unsigned int k = i + 1; k < j + 1; k++) { + pos[i].x_offset -= pos[k].x_advance; + pos[i].y_offset -= pos[k].y_advance; + } + } } } @@ -149,8 +169,20 @@ GPOS::position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer) /* Handle attachments */ if (buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT) - for (unsigned i = 0; i < len; i++) - propagate_attachment_offsets (pos, len, i, direction); + { + auto *pos = buffer->pos; + // https://github.com/harfbuzz/harfbuzz/issues/5514 + if (HB_DIRECTION_IS_FORWARD (direction)) + { + for (unsigned i = 0; i < len; i++) + if (pos[i].attach_chain()) + propagate_attachment_offsets (pos, len, i, direction); + } else { + for (unsigned i = len; i-- > 0; ) + if (pos[i].attach_chain()) + propagate_attachment_offsets (pos, len, i, direction); + } + } if (unlikely (font->slant_xy) && HB_DIRECTION_IS_HORIZONTAL (direction)) diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/LigatureArray.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/LigatureArray.hh index 59cca40aadc..fd131224630 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/LigatureArray.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/LigatureArray.hh @@ -19,22 +19,30 @@ struct LigatureArray : List16OfOffset16To bool subset (hb_subset_context_t *c, Iterator coverage, unsigned class_count, - const hb_map_t *klass_mapping) const + const hb_map_t *klass_mapping, + hb_sorted_vector_t &new_coverage /* OUT */) const { TRACE_SUBSET (this); - const hb_set_t &glyphset = *c->plan->glyphset_gsub (); + const hb_map_t &glyph_map = c->plan->glyph_map_gsub; auto *out = c->serializer->start_embed (this); if (unlikely (!c->serializer->extend_min (out))) return_trace (false); bool ret = false; for (const auto _ : + hb_zip (coverage, *this) - | hb_filter (glyphset, hb_first)) + | hb_filter (glyph_map, hb_first)) { + const LigatureAttach& src = (this + _.second); + bool non_empty = + hb_range (src.rows * class_count) + | hb_filter ([=] (unsigned index) { return klass_mapping->has (index % class_count); }) + | hb_map ([&] (const unsigned index) { return !src.offset_is_null (index / class_count, index % class_count, class_count); }) + | hb_any; + + if (!non_empty) continue; + auto *matrix = out->serialize_append (c->serializer); if (unlikely (!matrix)) return_trace (false); - const LigatureAttach& src = (this + _.second); auto indexes = + hb_range (src.rows * class_count) | hb_filter ([=] (unsigned index) { return klass_mapping->has (index % class_count); }) @@ -44,6 +52,9 @@ struct LigatureArray : List16OfOffset16To this, src.rows, indexes); + + hb_codepoint_t new_gid = glyph_map.get (_.first); + new_coverage.push (new_gid); } return_trace (ret); } diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePosFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePosFormat1.hh index ab1378e615c..c13dc65d439 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePosFormat1.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePosFormat1.hh @@ -209,19 +209,22 @@ struct MarkBasePosFormat1_2 ; new_coverage.reset (); - + base_iter - | hb_map (hb_first) - | hb_map (glyph_map) - | hb_sink (new_coverage) - ; - - if (!out->baseCoverage.serialize_serialize (c->serializer, new_coverage.iter ())) - return_trace (false); - hb_sorted_vector_t base_indexes; - for (const unsigned row : + base_iter - | hb_map (hb_second)) + auto &base_array = (this+baseArray); + for (const auto _ : + base_iter) { + unsigned row = _.second; + bool non_empty = + hb_range ((unsigned) classCount) + | hb_filter (klass_mapping) + | hb_map ([&] (const unsigned col) { return !base_array.offset_is_null (row, col, (unsigned) classCount); }) + | hb_any + ; + + if (!non_empty) continue; + + hb_codepoint_t new_g = glyph_map.get ( _.first); + new_coverage.push (new_g); + + hb_range ((unsigned) classCount) | hb_filter (klass_mapping) | hb_map ([&] (const unsigned col) { return row * (unsigned) classCount + col; }) @@ -229,8 +232,12 @@ struct MarkBasePosFormat1_2 ; } + if (!new_coverage) return_trace (false); + if (!out->baseCoverage.serialize_serialize (c->serializer, new_coverage.iter ())) + return_trace (false); + return_trace (out->baseArray.serialize_subset (c, baseArray, this, - base_iter.len (), + new_coverage.length, base_indexes.iter ())); } }; diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPosFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPosFormat1.hh index 46013c613b0..57dae77a9d0 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPosFormat1.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPosFormat1.hh @@ -200,19 +200,13 @@ struct MarkLigPosFormat1_2 &klass_mapping))) return_trace (false); - auto new_ligature_coverage = - + hb_iter (this + ligatureCoverage) - | hb_take ((this + ligatureArray).len) - | hb_map_retains_sorting (glyph_map) - | hb_filter ([] (hb_codepoint_t glyph) { return glyph != HB_MAP_VALUE_INVALID; }) - ; - - if (!out->ligatureCoverage.serialize_serialize (c->serializer, new_ligature_coverage)) + hb_sorted_vector_t new_lig_coverage; + if (!out->ligatureArray.serialize_subset (c, ligatureArray, this, + hb_iter (this+ligatureCoverage), + classCount, &klass_mapping, new_lig_coverage)) return_trace (false); - return_trace (out->ligatureArray.serialize_subset (c, ligatureArray, this, - hb_iter (this+ligatureCoverage), - classCount, &klass_mapping)); + return_trace (out->ligatureCoverage.serialize_serialize (c->serializer, new_lig_coverage.iter ())); } }; diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh index c4d129f2cb0..3221704caec 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh @@ -196,19 +196,23 @@ struct MarkMarkPosFormat1_2 ; new_coverage.reset (); - + mark2_iter - | hb_map (hb_first) - | hb_map (glyph_map) - | hb_sink (new_coverage) - ; - - if (!out->mark2Coverage.serialize_serialize (c->serializer, new_coverage.iter ())) - return_trace (false); - hb_sorted_vector_t mark2_indexes; - for (const unsigned row : + mark2_iter - | hb_map (hb_second)) + auto &mark2_array = (this+mark2Array); + for (const auto _ : + mark2_iter) { + unsigned row = _.second; + + bool non_empty = + hb_range ((unsigned) classCount) + | hb_filter (klass_mapping) + | hb_map ([&] (const unsigned col) { return !mark2_array.offset_is_null (row, col, (unsigned) classCount); }) + | hb_any + ; + + if (!non_empty) continue; + + hb_codepoint_t new_g = glyph_map.get ( _.first); + new_coverage.push (new_g); + + hb_range ((unsigned) classCount) | hb_filter (klass_mapping) | hb_map ([&] (const unsigned col) { return row * (unsigned) classCount + col; }) @@ -216,6 +220,10 @@ struct MarkMarkPosFormat1_2 ; } + if (!new_coverage) return_trace (false); + if (!out->mark2Coverage.serialize_serialize (c->serializer, new_coverage.iter ())) + return_trace (false); + return_trace (out->mark2Array.serialize_subset (c, mark2Array, this, mark2_iter.len (), mark2_indexes.iter ())); diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat1.hh index a8ea5f96c05..a8ded1e75e4 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat1.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat1.hh @@ -103,46 +103,29 @@ struct PairPosFormat1_3 const Coverage &get_coverage () const { return this+coverage; } - unsigned cache_cost () const + struct external_cache_t { - return (this+coverage).cost (); - } - static void * cache_func (void *p, hb_ot_lookup_cache_op_t op) + hb_ot_layout_mapping_cache_t coverage; + }; + void *external_cache_create () const { - switch (op) + external_cache_t *cache = (external_cache_t *) hb_malloc (sizeof (external_cache_t)); + if (likely (cache)) { - case hb_ot_lookup_cache_op_t::CREATE: - { - hb_ot_lookup_cache_t *cache = (hb_ot_lookup_cache_t *) hb_malloc (sizeof (hb_ot_lookup_cache_t)); - if (likely (cache)) - cache->clear (); - return cache; - } - case hb_ot_lookup_cache_op_t::ENTER: - return (void *) true; - case hb_ot_lookup_cache_op_t::LEAVE: - return nullptr; - case hb_ot_lookup_cache_op_t::DESTROY: - { - hb_ot_lookup_cache_t *cache = (hb_ot_lookup_cache_t *) p; - hb_free (cache); - return nullptr; - } + cache->coverage.clear (); } - return nullptr; + return cache; } - bool apply_cached (hb_ot_apply_context_t *c) const { return _apply (c, true); } - bool apply (hb_ot_apply_context_t *c) const { return _apply (c, false); } - bool _apply (hb_ot_apply_context_t *c, bool cached) const + bool apply (hb_ot_apply_context_t *c, void *external_cache) const { TRACE_APPLY (this); hb_buffer_t *buffer = c->buffer; #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE - hb_ot_lookup_cache_t *cache = cached ? (hb_ot_lookup_cache_t *) c->lookup_accel->cache : nullptr; - unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint, cache); + external_cache_t *cache = (external_cache_t *) external_cache; + unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint, cache ? &cache->coverage : nullptr); #else unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); #endif diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat2.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat2.hh index 59c018b9276..e7320b932da 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat2.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat2.hh @@ -123,56 +123,32 @@ struct PairPosFormat2_4 : ValueBase const Coverage &get_coverage () const { return this+coverage; } - struct pair_pos_cache_t + struct external_cache_t { - hb_ot_lookup_cache_t coverage; - hb_ot_lookup_cache_t first; - hb_ot_lookup_cache_t second; + hb_ot_layout_mapping_cache_t coverage; + hb_ot_layout_mapping_cache_t first; + hb_ot_layout_mapping_cache_t second; }; - - unsigned cache_cost () const + void *external_cache_create () const { - return (this+coverage).cost () + (this+classDef1).cost () + (this+classDef2).cost (); - } - static void * cache_func (void *p, hb_ot_lookup_cache_op_t op) - { - switch (op) + external_cache_t *cache = (external_cache_t *) hb_malloc (sizeof (external_cache_t)); + if (likely (cache)) { - case hb_ot_lookup_cache_op_t::CREATE: - { - pair_pos_cache_t *cache = (pair_pos_cache_t *) hb_malloc (sizeof (pair_pos_cache_t)); - if (likely (cache)) - { - cache->coverage.clear (); - cache->first.clear (); - cache->second.clear (); - } - return cache; - } - case hb_ot_lookup_cache_op_t::ENTER: - return (void *) true; - case hb_ot_lookup_cache_op_t::LEAVE: - return nullptr; - case hb_ot_lookup_cache_op_t::DESTROY: - { - pair_pos_cache_t *cache = (pair_pos_cache_t *) p; - hb_free (cache); - return nullptr; - } + cache->coverage.clear (); + cache->first.clear (); + cache->second.clear (); } - return nullptr; + return cache; } - bool apply_cached (hb_ot_apply_context_t *c) const { return _apply (c, true); } - bool apply (hb_ot_apply_context_t *c) const { return _apply (c, false); } - bool _apply (hb_ot_apply_context_t *c, bool cached) const + bool apply (hb_ot_apply_context_t *c, void *external_cache) const { TRACE_APPLY (this); hb_buffer_t *buffer = c->buffer; #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE - pair_pos_cache_t *cache = cached ? (pair_pos_cache_t *) c->lookup_accel->cache : nullptr; + external_cache_t *cache = (external_cache_t *) external_cache; unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint, cache ? &cache->coverage : nullptr); #else unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/ValueFormat.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/ValueFormat.hh index 89a5493f47d..924fd78478c 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/ValueFormat.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/ValueFormat.hh @@ -58,7 +58,12 @@ struct ValueFormat : HBUINT16 NumType& operator = (uint16_t i) { v = i; return *this; } - unsigned int get_len () const { return hb_popcount ((unsigned int) *this); } + // Note: spec says skip 2 bytes per bit in the valueformat. But reports + // from Microsoft developers indicate that only the fields that are + // currently defined are counted. We don't expect any new fields to + // be added to ValueFormat. As such, we use the faster hb_popcount8 + // that only processes the lowest 8 bits. + unsigned int get_len () const { return hb_popcount8 ((uint8_t) *this); } unsigned int get_size () const { return get_len () * Value::static_size; } hb_vector_t get_device_table_indices () const { diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSet.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSet.hh index b4466119be0..0437cff463b 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSet.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSet.hh @@ -91,6 +91,19 @@ struct AlternateSet return alternates.len; } + void + collect_alternates (hb_codepoint_t gid, + hb_map_t *alternate_count /* IN/OUT */, + hb_map_t *alternate_glyphs /* IN/OUT */) const + { + + hb_enumerate (alternates) + | hb_map ([gid] (hb_pair_t _) { return hb_pair (gid + (_.first << 24), _.second); }) + | hb_apply ([&] (const hb_pair_t &p) -> void + { _hb_collect_glyph_alternates_add (p.first, p.second, + alternate_count, alternate_glyphs); }) + ; + } + template bool serialize (hb_serialize_context_t *c, diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSubstFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSubstFormat1.hh index 421a6e06627..294855907a7 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSubstFormat1.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSubstFormat1.hh @@ -69,6 +69,19 @@ struct AlternateSubstFormat1_2 { return (this+alternateSet[(this+coverage).get_coverage (gid)]) .get_alternates (start_offset, alternate_count, alternate_glyphs); } + void + collect_glyph_alternates (hb_map_t *alternate_count /* IN/OUT */, + hb_map_t *alternate_glyphs /* IN/OUT */) const + { + + hb_iter (alternateSet) + | hb_map (hb_add (this)) + | hb_zip (this+coverage) + | hb_apply ([&] (const hb_pair_t &, hb_codepoint_t> _) { + _.first.collect_alternates (_.second, alternate_count, alternate_glyphs); + }) + ; + } + bool apply (hb_ot_apply_context_t *c) const { TRACE_APPLY (this); diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/Ligature.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/Ligature.hh index e0ec82a2365..dfa46b181ce 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/Ligature.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/Ligature.hh @@ -44,6 +44,18 @@ struct Ligature c->output->add (ligGlyph); } + template + void collect_second (set_t &s) const + { + if (unlikely (!component.get_length ())) + { + // A ligature without any components. Anything matches. + s = set_t::full (); + return; + } + s.add (component.arrayZ[0]); + } + bool would_apply (hb_would_apply_context_t *c) const { if (c->len != component.lenP1) @@ -91,15 +103,6 @@ struct Ligature unsigned int total_component_count = 0; if (unlikely (count > HB_MAX_CONTEXT_LENGTH)) return false; - unsigned match_positions_stack[4]; - unsigned *match_positions = match_positions_stack; - if (unlikely (count > ARRAY_LENGTH (match_positions_stack))) - { - match_positions = (unsigned *) hb_malloc (hb_max (count, 1u) * sizeof (unsigned)); - if (unlikely (!match_positions)) - return_trace (false); - } - unsigned int match_end = 0; if (likely (!match_input (c, count, @@ -107,12 +110,9 @@ struct Ligature match_glyph, nullptr, &match_end, - match_positions, &total_component_count))) { c->buffer->unsafe_to_concat (c->buffer->idx, match_end); - if (match_positions != match_positions_stack) - hb_free (match_positions); return_trace (false); } @@ -129,10 +129,10 @@ struct Ligature match_end += delta; for (unsigned i = 0; i < count; i++) { - match_positions[i] += delta; + c->match_positions[i] += delta; if (i) *p++ = ','; - snprintf (p, sizeof(buf) - (p - buf), "%u", match_positions[i]); + snprintf (p, sizeof(buf) - (p - buf), "%u", c->match_positions[i]); p += strlen(p); } @@ -143,7 +143,6 @@ struct Ligature ligate_input (c, count, - match_positions, match_end, ligGlyph, total_component_count); @@ -156,8 +155,6 @@ struct Ligature pos); } - if (match_positions != match_positions_stack) - hb_free (match_positions); return_trace (true); } diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSet.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSet.hh index 928c74a167c..9d933f16bc8 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSet.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSet.hh @@ -62,6 +62,15 @@ struct LigatureSet ; } + template + void collect_seconds (set_t &s) const + { + + hb_iter (ligature) + | hb_map (hb_add (this)) + | hb_apply ([&s] (const Ligature &_) { _.collect_second (s); }) + ; + } + bool would_apply (hb_would_apply_context_t *c) const { return @@ -72,14 +81,14 @@ struct LigatureSet ; } - bool apply (hb_ot_apply_context_t *c) const + bool apply (hb_ot_apply_context_t *c, const hb_set_digest_t *seconds = nullptr) const { TRACE_APPLY (this); unsigned int num_ligs = ligature.len; #ifndef HB_NO_OT_RULESETS_FAST_PATH - if (HB_OPTIMIZE_SIZE_VAL || num_ligs <= 4) + if (HB_OPTIMIZE_SIZE_VAL || num_ligs <= 1) #endif { slow: @@ -91,7 +100,7 @@ struct LigatureSet return_trace (false); } - /* This version is optimized for speed by matching the first component + /* This version is optimized for speed by matching the second component * of the ligature here, instead of calling into the ligation code. * * This is replicated in ChainRuleSet and RuleSet. */ @@ -101,11 +110,11 @@ struct LigatureSet skippy_iter.set_match_func (match_always, nullptr); skippy_iter.set_glyph_data ((HBUINT16 *) nullptr); unsigned unsafe_to; - hb_codepoint_t first = (unsigned) -1; + hb_codepoint_t second = (unsigned) -1; bool matched = skippy_iter.next (&unsafe_to); if (likely (matched)) { - first = c->buffer->info[skippy_iter.idx].codepoint; + second = c->buffer->info[skippy_iter.idx].codepoint; unsafe_to = skippy_iter.idx + 1; if (skippy_iter.may_skip (c->buffer->info[skippy_iter.idx])) @@ -118,13 +127,14 @@ struct LigatureSet else goto slow; + if (seconds && !seconds->may_have (second)) + return_trace (false); bool unsafe_to_concat = false; - for (unsigned int i = 0; i < num_ligs; i++) { const auto &lig = this+ligature.arrayZ[i]; if (unlikely (lig.component.lenP1 <= 1) || - lig.component.arrayZ[0] == first) + lig.component.arrayZ[0] == second) { if (lig.apply (c)) { diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSubstFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSubstFormat1.hh index 2ef46145e98..a84cde1c991 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSubstFormat1.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSubstFormat1.hh @@ -78,52 +78,44 @@ struct LigatureSubstFormat1_2 return lig_set.would_apply (c); } - unsigned cache_cost () const + struct external_cache_t { - return (this+coverage).cost (); - } - static void * cache_func (void *p, hb_ot_lookup_cache_op_t op) + hb_ot_layout_mapping_cache_t coverage; + hb_set_digest_t seconds; + }; + void *external_cache_create () const { - switch (op) + external_cache_t *cache = (external_cache_t *) hb_malloc (sizeof (external_cache_t)); + if (likely (cache)) { - case hb_ot_lookup_cache_op_t::CREATE: - { - hb_ot_lookup_cache_t *cache = (hb_ot_lookup_cache_t *) hb_malloc (sizeof (hb_ot_lookup_cache_t)); - if (likely (cache)) - cache->clear (); - return cache; - } - case hb_ot_lookup_cache_op_t::ENTER: - return (void *) true; - case hb_ot_lookup_cache_op_t::LEAVE: - return nullptr; - case hb_ot_lookup_cache_op_t::DESTROY: - { - hb_ot_lookup_cache_t *cache = (hb_ot_lookup_cache_t *) p; - hb_free (cache); - return nullptr; - } + cache->coverage.clear (); + + cache->seconds.init (); + + hb_iter (ligatureSet) + | hb_map (hb_add (this)) + | hb_apply ([cache] (const LigatureSet &_) { _.collect_seconds (cache->seconds); }) + ; } - return nullptr; + return cache; } - bool apply_cached (hb_ot_apply_context_t *c) const { return _apply (c, true); } - bool apply (hb_ot_apply_context_t *c) const { return _apply (c, false); } - bool _apply (hb_ot_apply_context_t *c, bool cached) const + bool apply (hb_ot_apply_context_t *c, void *external_cache) const { TRACE_APPLY (this); hb_buffer_t *buffer = c->buffer; #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE - hb_ot_lookup_cache_t *cache = cached ? (hb_ot_lookup_cache_t *) c->lookup_accel->cache : nullptr; - unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint, cache); + external_cache_t *cache = (external_cache_t *) external_cache; + const hb_set_digest_t *seconds = cache ? &cache->seconds : nullptr; + unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint, cache ? &cache->coverage : nullptr); #else + const hb_set_digest_t *seconds = nullptr; unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); #endif if (index == NOT_COVERED) return_trace (false); const auto &lig_set = this+ligatureSet[index]; - return_trace (lig_set.apply (c)); + return_trace (lig_set.apply (c, seconds)); } bool serialize (hb_serialize_context_t *c, diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat1.hh index 550d8f04e65..1cd3f9d9cdf 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat1.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat1.hh @@ -123,6 +123,21 @@ struct SingleSubstFormat1_3 return 1; } + void + collect_glyph_alternates (hb_map_t *alternate_count /* IN/OUT */, + hb_map_t *alternate_glyphs /* IN/OUT */) const + { + hb_codepoint_t d = deltaGlyphID; + hb_codepoint_t mask = get_mask (); + + + hb_iter (this+coverage) + | hb_map ([d, mask] (hb_codepoint_t g) { return hb_pair (g, (g + d) & mask); }) + | hb_apply ([&] (const hb_pair_t &p) -> void + { _hb_collect_glyph_alternates_add (p.first, p.second, + alternate_count, alternate_glyphs); }) + ; + } + bool apply (hb_ot_apply_context_t *c) const { TRACE_APPLY (this); diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat2.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat2.hh index dce28b67213..4c98f05aeba 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat2.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat2.hh @@ -100,6 +100,17 @@ struct SingleSubstFormat2_4 return 1; } + void + collect_glyph_alternates (hb_map_t *alternate_count /* IN/OUT */, + hb_map_t *alternate_glyphs /* IN/OUT */) const + { + + hb_zip (this+coverage, substitute) + | hb_apply ([&] (const hb_pair_t &p) -> void + { _hb_collect_glyph_alternates_add (p.first, p.second, + alternate_count, alternate_glyphs); }) + ; + } + bool apply (hb_ot_apply_context_t *c) const { TRACE_APPLY (this); diff --git a/thirdparty/harfbuzz/src/OT/Layout/types.hh b/thirdparty/harfbuzz/src/OT/Layout/types.hh index 527f64114b4..6e412e5fe92 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/types.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/types.hh @@ -29,8 +29,8 @@ #ifndef OT_LAYOUT_TYPES_HH #define OT_LAYOUT_TYPES_HH -using hb_ot_lookup_cache_t = hb_cache_t<15, 8, 7>; -static_assert (sizeof (hb_ot_lookup_cache_t) == 256, ""); +using hb_ot_layout_mapping_cache_t = hb_cache_t<15, 8, 7>; +static_assert (sizeof (hb_ot_layout_mapping_cache_t) == 256, ""); namespace OT { namespace Layout { diff --git a/thirdparty/harfbuzz/src/OT/Var/VARC/VARC.cc b/thirdparty/harfbuzz/src/OT/Var/VARC/VARC.cc index 9e4fa3c2440..1a22f1d8124 100644 --- a/thirdparty/harfbuzz/src/OT/Var/VARC/VARC.cc +++ b/thirdparty/harfbuzz/src/OT/Var/VARC/VARC.cc @@ -11,6 +11,8 @@ namespace OT { //namespace Var { +#ifndef HB_NO_DRAW + struct hb_transforming_pen_context_t { hb_transform_t<> transform; @@ -411,6 +413,8 @@ VARC::get_path_at (const hb_varc_context_t &c, return true; } +#endif + //} // namespace Var } // namespace OT diff --git a/thirdparty/harfbuzz/src/OT/Var/VARC/VARC.hh b/thirdparty/harfbuzz/src/OT/Var/VARC/VARC.hh index a372701cde9..719302c93e4 100644 --- a/thirdparty/harfbuzz/src/OT/Var/VARC/VARC.hh +++ b/thirdparty/harfbuzz/src/OT/Var/VARC/VARC.hh @@ -194,6 +194,7 @@ struct VARC hb_codepoint_t gid, hb_glyph_extents_t *extents) const { +#ifndef HB_NO_DRAW if (!table->has_data ()) return false; hb_extents_t<> f_extents; @@ -207,6 +208,9 @@ struct VARC *extents = f_extents.to_glyph_extents (font->x_scale < 0, font->y_scale < 0); return ret; +#else + return false; +#endif } private: diff --git a/thirdparty/harfbuzz/src/OT/glyf/Glyph.hh b/thirdparty/harfbuzz/src/OT/glyf/Glyph.hh index f8a396bf9bd..a3ec885e64c 100644 --- a/thirdparty/harfbuzz/src/OT/glyf/Glyph.hh +++ b/thirdparty/harfbuzz/src/OT/glyf/Glyph.hh @@ -533,7 +533,11 @@ struct Glyph bool get_extents_without_var_scaled (hb_font_t *font, const glyf_accelerator_t &glyf_accelerator, hb_glyph_extents_t *extents) const { - if (type == EMPTY) return true; /* Empty glyph; zero extents. */ + if (type == EMPTY) + { + *extents = {0, 0, 0, 0}; + return true; /* Empty glyph; zero extents. */ + } return header->get_extents_without_var_scaled (font, glyf_accelerator, gid, extents); } diff --git a/thirdparty/harfbuzz/src/OT/glyf/SimpleGlyph.hh b/thirdparty/harfbuzz/src/OT/glyf/SimpleGlyph.hh index c0f01405cf3..9f4a2bac5b1 100644 --- a/thirdparty/harfbuzz/src/OT/glyf/SimpleGlyph.hh +++ b/thirdparty/harfbuzz/src/OT/glyf/SimpleGlyph.hh @@ -189,7 +189,7 @@ struct SimpleGlyph unsigned old_length = points.length; points.alloc (points.length + num_points + 4); // Allocate for phantom points, to avoid a possible copy - if (unlikely (!points.resize (points.length + num_points, false))) return false; + if (unlikely (!points.resize_dirty (points.length + num_points))) return false; auto points_ = points.as_array ().sub_array (old_length); if (!phantom_only) hb_memset (points_.arrayZ, 0, sizeof (contour_point_t) * num_points); diff --git a/thirdparty/harfbuzz/src/OT/glyf/glyf.hh b/thirdparty/harfbuzz/src/OT/glyf/glyf.hh index b821dd32258..71989d8df4a 100644 --- a/thirdparty/harfbuzz/src/OT/glyf/glyf.hh +++ b/thirdparty/harfbuzz/src/OT/glyf/glyf.hh @@ -445,8 +445,7 @@ struct glyf_accelerator_t if (coords) { hb_glyf_scratch_t *scratch = acquire_scratch (); - if (unlikely (!scratch)) - return false; + if (unlikely (!scratch)) return false; bool ret = get_points (font, gid, points_aggregator_t (font, extents, nullptr, true), @@ -493,8 +492,7 @@ struct glyf_accelerator_t if (!has_data ()) return false; hb_glyf_scratch_t *scratch = acquire_scratch (); - if (unlikely (!scratch)) - return true; + if (unlikely (!scratch)) return true; bool ret = get_points (font, gid, glyf_impl::path_builder_t (font, draw_session), hb_array (font->coords, @@ -523,6 +521,7 @@ struct glyf_accelerator_t hb_glyf_scratch_t *acquire_scratch () const { + if (!has_data ()) return nullptr; hb_glyf_scratch_t *scratch = cached_scratch.get_acquire (); if (!scratch || unlikely (!cached_scratch.cmpexch (scratch, nullptr))) { @@ -534,6 +533,8 @@ struct glyf_accelerator_t } void release_scratch (hb_glyf_scratch_t *scratch) const { + if (!scratch) + return; if (!cached_scratch.cmpexch (nullptr, scratch)) { scratch->~hb_glyf_scratch_t (); diff --git a/thirdparty/harfbuzz/src/graph/graph.hh b/thirdparty/harfbuzz/src/graph/graph.hh index 332f27169df..951b75d45c1 100644 --- a/thirdparty/harfbuzz/src/graph/graph.hh +++ b/thirdparty/harfbuzz/src/graph/graph.hh @@ -470,8 +470,12 @@ struct graph_t num_roots_for_space_.push (1); bool removed_nil = false; vertices_.alloc (objects.length); - vertices_scratch_.alloc (objects.length); + ordering_.resize (objects.length); + ordering_scratch_.alloc (objects.length); + unsigned count = objects.length; + unsigned order = objects.length; + unsigned skip = 0; for (unsigned i = 0; i < count; i++) { // If this graph came from a serialization buffer object 0 is the @@ -479,6 +483,9 @@ struct graph_t if (i == 0 && !objects.arrayZ[i]) { removed_nil = true; + order--; + ordering_.resize(objects.length - 1); + skip++; continue; } @@ -488,6 +495,12 @@ struct graph_t check_success (v->link_positions_valid (count, removed_nil)); + // To start we set the ordering to match the provided objects + // list. Note: objects are provided to us in reverse order (ie. + // the last object is the root). + unsigned obj_idx = i - skip; + ordering_[--order] = obj_idx; + if (!removed_nil) continue; // Fix indices to account for removed nil object. for (auto& l : v->obj.all_links_writer ()) { @@ -508,10 +521,10 @@ struct graph_t } void print () const { - for (int i = vertices_.length - 1; i >= 0; i--) + for (unsigned id : ordering_) { - const auto& v = vertices_[i]; - printf("%d: %u [", i, (unsigned int)v.table_size()); + const auto& v = vertices_[id]; + printf("%u: %u [", id, (unsigned int)v.table_size()); for (const auto &l : v.obj.real_links) { printf("%u, ", l.objidx); } @@ -533,6 +546,7 @@ struct graph_t { return !successful || vertices_.in_error () || + ordering_.in_error() || num_roots_for_space_.in_error (); } @@ -543,10 +557,10 @@ struct graph_t unsigned root_idx () const { - // Object graphs are in reverse order, the first object is at the end - // of the vector. Since the graph is topologically sorted it's safe to + // First element of ordering_ is the root. + // Since the graph is topologically sorted it's safe to // assume the first object has no incoming edges. - return vertices_.length - 1; + return ordering_[0]; } const hb_serialize_context_t::object_t& object (unsigned i) const @@ -604,55 +618,51 @@ struct graph_t hb_priority_queue_t queue; queue.alloc (vertices_.length); - hb_vector_t &sorted_graph = vertices_scratch_; - if (unlikely (!check_success (sorted_graph.resize (vertices_.length)))) return; - hb_vector_t id_map; - if (unlikely (!check_success (id_map.resize (vertices_.length)))) return; + hb_vector_t &new_ordering = ordering_scratch_; + if (unlikely (!check_success (new_ordering.resize (vertices_.length)))) return; hb_vector_t removed_edges; if (unlikely (!check_success (removed_edges.resize (vertices_.length)))) return; update_parents (); queue.insert (root ().modified_distance (0), root_idx ()); - int new_id = root_idx (); unsigned order = 1; + unsigned pos = 0; while (!queue.in_error () && !queue.is_empty ()) { unsigned next_id = queue.pop_minimum().second; - sorted_graph[new_id] = std::move (vertices_[next_id]); - const vertex_t& next = sorted_graph[new_id]; - - if (unlikely (!check_success(new_id >= 0))) { + if (unlikely (!check_success(pos < new_ordering.length))) { // We are out of ids. Which means we've visited a node more than once. // This graph contains a cycle which is not allowed. DEBUG_MSG (SUBSET_REPACK, nullptr, "Invalid graph. Contains cycle."); return; } - - id_map[next_id] = new_id--; + new_ordering[pos++] = next_id; + const vertex_t& next = vertices_[next_id]; for (const auto& link : next.obj.all_links ()) { removed_edges[link.objidx]++; - if (!(vertices_[link.objidx].incoming_edges () - removed_edges[link.objidx])) + const auto& v = vertices_[link.objidx]; + if (!(v.incoming_edges () - removed_edges[link.objidx])) // Add the order that the links were encountered to the priority. // This ensures that ties between priorities objects are broken in a consistent // way. More specifically this is set up so that if a set of objects have the same // distance they'll be added to the topological order in the order that they are // referenced from the parent object. - queue.insert (vertices_[link.objidx].modified_distance (order++), + queue.insert (v.modified_distance (order++), link.objidx); } } check_success (!queue.in_error ()); - check_success (!sorted_graph.in_error ()); + check_success (!new_ordering.in_error ()); - check_success (remap_all_obj_indices (id_map, &sorted_graph)); - vertices_ = std::move (sorted_graph); + hb_swap (ordering_, new_ordering); - if (!check_success (new_id == -1)) + if (!check_success (pos == vertices_.length)) { print_orphaned_nodes (); + } } /* @@ -662,8 +672,8 @@ struct graph_t */ void find_space_roots (hb_set_t& visited, hb_set_t& roots) { - int root_index = (int) root_idx (); - for (int i = root_index; i >= 0; i--) + unsigned root_index = root_idx (); + for (unsigned i : ordering_) { if (visited.has (i)) continue; @@ -846,7 +856,6 @@ struct graph_t if (subgraph.in_error ()) return false; - unsigned original_root_idx = root_idx (); hb_map_t index_map; bool made_changes = false; for (auto entry : subgraph.iter ()) @@ -869,14 +878,6 @@ struct graph_t if (!made_changes) return false; - if (original_root_idx != root_idx () - && parents.has (original_root_idx)) - { - // If the root idx has changed since parents was determined, update root idx in parents - parents.add (root_idx ()); - parents.del (original_root_idx); - } - auto new_subgraph = + subgraph.keys () | hb_map([&] (uint32_t node_idx) { @@ -965,9 +966,9 @@ struct graph_t */ template unsigned move_child (unsigned old_parent_idx, - const O* old_offset, - unsigned new_parent_idx, - const O* new_offset) + const O* old_offset, + unsigned new_parent_idx, + const O* new_offset) { distance_invalid = true; positions_invalid = true; @@ -992,6 +993,50 @@ struct graph_t return child_id; } + /* + * Moves all outgoing links in old parent that have + * a link position between [old_post_start, old_pos_end) + * to the new parent. Links are placed serially in the new + * parent starting at new_pos_start. + */ + template + void move_children (unsigned old_parent_idx, + unsigned old_pos_start, + unsigned old_pos_end, + unsigned new_parent_idx, + unsigned new_pos_start) + { + distance_invalid = true; + positions_invalid = true; + + auto& old_v = vertices_[old_parent_idx]; + auto& new_v = vertices_[new_parent_idx]; + + hb_vector_t old_links; + for (const auto& l : old_v.obj.real_links) + { + if (l.position < old_pos_start || l.position >= old_pos_end) + { + old_links.push(l); + continue; + } + + unsigned array_pos = l.position - old_pos_start; + + unsigned child_id = l.objidx; + auto* new_link = new_v.obj.real_links.push (); + new_link->width = O::static_size; + new_link->objidx = child_id; + new_link->position = new_pos_start + array_pos; + + auto& child = vertices_[child_id]; + child.add_parent (new_parent_idx, false); + child.remove_parent (old_parent_idx); + } + + old_v.obj.real_links = std::move (old_links); + } + /* * duplicates all nodes in the subgraph reachable from node_idx. Does not re-assign * links. index_map is updated with mappings from old id to new id. If a duplication has already @@ -1021,8 +1066,11 @@ struct graph_t distance_invalid = true; auto* clone = vertices_.push (); + unsigned clone_idx = vertices_.length - 1; + ordering_.push(clone_idx); + auto& child = vertices_[node_idx]; - if (vertices_.in_error ()) { + if (vertices_.in_error () || ordering_.in_error()) { return -1; } @@ -1032,7 +1080,6 @@ struct graph_t clone->space = child.space; clone->reset_parents (); - unsigned clone_idx = vertices_.length - 2; for (const auto& l : child.obj.real_links) { clone->obj.real_links.push (l); @@ -1047,15 +1094,6 @@ struct graph_t check_success (!clone->obj.real_links.in_error ()); check_success (!clone->obj.virtual_links.in_error ()); - // The last object is the root of the graph, so swap back the root to the end. - // The root's obj idx does change, however since it's root nothing else refers to it. - // all other obj idx's will be unaffected. - hb_swap (vertices_[vertices_.length - 2], *clone); - - // Since the root moved, update the parents arrays of all children on the root. - for (const auto& l : root ().obj.all_links ()) - vertices_[l.objidx].remap_parent (root_idx () - 1, root_idx ()); - return clone_idx; } @@ -1205,7 +1243,10 @@ struct graph_t distance_invalid = true; auto* clone = vertices_.push (); - if (vertices_.in_error ()) { + unsigned clone_idx = vertices_.length - 1; + ordering_.push(clone_idx); + + if (vertices_.in_error () || ordering_.in_error()) { return -1; } @@ -1214,17 +1255,6 @@ struct graph_t clone->distance = 0; clone->space = 0; - unsigned clone_idx = vertices_.length - 2; - - // The last object is the root of the graph, so swap back the root to the end. - // The root's obj idx does change, however since it's root nothing else refers to it. - // all other obj idx's will be unaffected. - hb_swap (vertices_[vertices_.length - 2], *clone); - - // Since the root moved, update the parents arrays of all children on the root. - for (const auto& l : root ().obj.all_links ()) - vertices_[l.objidx].remap_parent (root_idx () - 1, root_idx ()); - return clone_idx; } @@ -1386,7 +1416,8 @@ struct graph_t size_t total_size = 0; unsigned count = vertices_.length; for (unsigned i = 0; i < count; i++) { - size_t size = vertices_.arrayZ[i].obj.tail - vertices_.arrayZ[i].obj.head; + const auto& obj = vertices_.arrayZ[i].obj; + size_t size = obj.tail - obj.head; total_size += size; } return total_size; @@ -1459,7 +1490,7 @@ struct graph_t if (!positions_invalid) return; unsigned current_pos = 0; - for (int i = root_idx (); i >= 0; i--) + for (unsigned i : ordering_) { auto& v = vertices_[i]; v.start = current_pos; @@ -1491,11 +1522,11 @@ struct graph_t unsigned count = vertices_.length; for (unsigned i = 0; i < count; i++) vertices_.arrayZ[i].distance = hb_int_max (int64_t); - vertices_.tail ().distance = 0; + vertices_[root_idx ()].distance = 0; hb_priority_queue_t queue; queue.alloc (count); - queue.insert (0, vertices_.length - 1); + queue.insert (0, root_idx ()); hb_vector_t visited; visited.resize (vertices_.length); @@ -1505,22 +1536,23 @@ struct graph_t unsigned next_idx = queue.pop_minimum ().second; if (visited[next_idx]) continue; const auto& next = vertices_[next_idx]; - int64_t next_distance = vertices_[next_idx].distance; + int64_t next_distance = next.distance; visited[next_idx] = true; for (const auto& link : next.obj.all_links ()) { if (visited[link.objidx]) continue; - const auto& child = vertices_.arrayZ[link.objidx].obj; + auto& child_v = vertices_.arrayZ[link.objidx]; + const auto& child = child_v.obj; unsigned link_width = link.width ? link.width : 4; // treat virtual offsets as 32 bits wide int64_t child_weight = (child.tail - child.head) + - ((int64_t) 1 << (link_width * 8)) * (vertices_.arrayZ[link.objidx].space + 1); + ((int64_t) 1 << (link_width * 8)) * (child_v.space + 1); int64_t child_distance = next_distance + child_weight; - if (child_distance < vertices_.arrayZ[link.objidx].distance) + if (child_distance < child_v.distance) { - vertices_.arrayZ[link.objidx].distance = child_distance; + child_v.distance = child_distance; queue.insert (child_distance, link.objidx); } } @@ -1563,9 +1595,10 @@ struct graph_t if (!id_map) return; for (unsigned i : subgraph) { - unsigned num_real = vertices_[i].obj.real_links.length; + auto& obj = vertices_[i].obj; + unsigned num_real = obj.real_links.length; unsigned count = 0; - for (auto& link : vertices_[i].obj.all_links_writer ()) + for (auto& link : obj.all_links_writer ()) { count++; const uint32_t *v; @@ -1577,25 +1610,6 @@ struct graph_t } } - /* - * Updates all objidx's in all links using the provided mapping. - */ - bool remap_all_obj_indices (const hb_vector_t& id_map, - hb_vector_t* sorted_graph) const - { - unsigned count = sorted_graph->length; - for (unsigned i = 0; i < count; i++) - { - if (!(*sorted_graph)[i].remap_parents (id_map)) - return false; - for (auto& link : sorted_graph->arrayZ[i].obj.all_links_writer ()) - { - link.objidx = id_map[link.objidx]; - } - } - return true; - } - /* * Finds all nodes in targets that are reachable from start_idx, nodes in visited will be skipped. * For this search the graph is treated as being undirected. @@ -1631,7 +1645,16 @@ struct graph_t public: // TODO(garretrieger): make private, will need to move most of offset overflow code into graph. hb_vector_t vertices_; - hb_vector_t vertices_scratch_; + + // Specifies the current topological ordering of this graph + // + // ordering_[pos] = obj index + // + // specifies that the 'pos'th spot is filled by the object + // given by obj index. + hb_vector_t ordering_; + hb_vector_t ordering_scratch_; + private: bool parents_invalid; bool distance_invalid; diff --git a/thirdparty/harfbuzz/src/graph/gsubgpos-graph.hh b/thirdparty/harfbuzz/src/graph/gsubgpos-graph.hh index 77ba4ee18c1..50dc03e3c6f 100644 --- a/thirdparty/harfbuzz/src/graph/gsubgpos-graph.hh +++ b/thirdparty/harfbuzz/src/graph/gsubgpos-graph.hh @@ -87,6 +87,12 @@ struct Lookup : public OT::Lookup return lookupType == extension_type (table_tag); } + bool use_mark_filtering_set () const + { + unsigned flag = lookupFlag; + return flag & 0x0010u; + } + bool make_extension (gsubgpos_graph_context_t& c, unsigned this_index) { @@ -220,6 +226,9 @@ struct Lookup : public OT::Lookup } hb_memcpy (buffer, v->obj.head, v->table_size()); + if (use_mark_filtering_set ()) + hb_memcpy (buffer + new_size - 2, v->obj.tail - 2, 2); + v->obj.head = buffer; v->obj.tail = buffer + new_size; diff --git a/thirdparty/harfbuzz/src/graph/ligature-graph.hh b/thirdparty/harfbuzz/src/graph/ligature-graph.hh index 611ab686e9b..fd170bd9ccb 100644 --- a/thirdparty/harfbuzz/src/graph/ligature-graph.hh +++ b/thirdparty/harfbuzz/src/graph/ligature-graph.hh @@ -105,6 +105,23 @@ struct LigatureSubstFormat1 : public OT::Layout::GSUB_impl::LigatureSubstFormat1 return result; } + hb_vector_t ligature_index_to_object_id(const graph_t::vertex_and_table_t& liga_set) const { + hb_vector_t map; + map.resize_exact(liga_set.table->ligature.len); + if (map.in_error()) return map; + + for (unsigned i = 0; i < map.length; i++) { + map[i] = (unsigned) -1; + } + + for (const auto& l : liga_set.vertex->obj.real_links) { + if (l.position < 2) continue; + unsigned array_index = (l.position - 2) / 2; + map[array_index] = l.objidx; + } + return map; + } + hb_vector_t compute_split_points(gsubgpos_graph_context_t& c, unsigned parent_index, unsigned this_index) const @@ -128,9 +145,16 @@ struct LigatureSubstFormat1 : public OT::Layout::GSUB_impl::LigatureSubstFormat1 return hb_vector_t {}; } + // Finding the object id associated with an array index is O(n) + // so to avoid O(n^2), precompute the mapping by scanning through + // all links + auto index_to_id = ligature_index_to_object_id(liga_set); + if (index_to_id.in_error()) return hb_vector_t(); + for (unsigned j = 0; j < liga_set.table->ligature.len; j++) { - const unsigned liga_id = c.graph.index_for_offset (liga_set.index, &liga_set.table->ligature[j]); + const unsigned liga_id = index_to_id[j]; + if (liga_id == (unsigned) -1) continue; // no outgoing link, ignore const unsigned liga_size = c.graph.vertices_[liga_id].table_size (); accumulated += OT::HBUINT16::static_size; // for ligature offset @@ -154,7 +178,6 @@ struct LigatureSubstFormat1 : public OT::Layout::GSUB_impl::LigatureSubstFormat1 return split_points; } - struct split_context_t { gsubgpos_graph_context_t& c; @@ -323,19 +346,19 @@ struct LigatureSubstFormat1 : public OT::Layout::GSUB_impl::LigatureSubstFormat1 { // This liga set partially overlaps [start, end). We'll need to create // a new liga set sub table and move the intersecting ligas to it. - unsigned liga_count = hb_min(end, current_end) - hb_max(start, current_start); + unsigned start_index = hb_max(start, current_start) - count; + unsigned end_index = hb_min(end, current_end) - count; + unsigned liga_count = end_index - start_index; auto result = new_liga_set(c, liga_count); liga_set_prime_id = result.first; - LigatureSet* prime = result.second; if (liga_set_prime_id == (unsigned) -1) return -1; - unsigned new_index = 0; - for (unsigned j = hb_max(start, current_start) - count; j < hb_min(end, current_end) - count; j++) { - c.graph.move_child<> (liga_set_index, - &liga_set.table->ligature[j], - liga_set_prime_id, - &prime->ligature[new_index++]); - } + c.graph.move_children( + liga_set_index, + 2 + start_index * 2, + 2 + end_index * 2, + liga_set_prime_id, + 2); liga_set_end = i; if (i < liga_set_start) liga_set_start = i; @@ -392,8 +415,12 @@ struct LigatureSubstFormat1 : public OT::Layout::GSUB_impl::LigatureSubstFormat1 // duplicated. Code later on will re-add the virtual links as needed (via retained_indices). clear_virtual_links(c, liga_set.index); retained_indices.add(liga_set.index); - for (const auto& liga_offset : liga_set.table->ligature) { - unsigned liga_index = c.graph.index_for_offset(liga_set.index, &liga_offset); + + auto index_to_id = ligature_index_to_object_id(liga_set); + if (index_to_id.in_error()) return false; + + for (unsigned i = 0; i < liga_set.table->ligature.len; i++) { + unsigned liga_index = index_to_id[i]; if (liga_index != (unsigned) -1) { clear_virtual_links(c, liga_index); retained_indices.add(liga_index); diff --git a/thirdparty/harfbuzz/src/graph/serialize.hh b/thirdparty/harfbuzz/src/graph/serialize.hh index fb8950e6f56..37fac8909e5 100644 --- a/thirdparty/harfbuzz/src/graph/serialize.hh +++ b/thirdparty/harfbuzz/src/graph/serialize.hh @@ -113,7 +113,7 @@ will_overflow (graph_t& graph, hb_hashmap_t record_set; const auto& vertices = graph.vertices_; - for (int parent_idx = vertices.length - 1; parent_idx >= 0; parent_idx--) + for (unsigned parent_idx : graph.ordering_) { // Don't need to check virtual links for overflow for (const auto& link : vertices.arrayZ[parent_idx].obj.real_links) @@ -173,6 +173,7 @@ template inline void serialize_link_of_type (const hb_serialize_context_t::object_t::link_t& link, char* head, unsigned size, + const hb_vector_t& id_map, hb_serialize_context_t* c) { assert(link.position + link.width <= size); @@ -180,9 +181,7 @@ serialize_link_of_type (const hb_serialize_context_t::object_t::link_t& link, OT::Offset* offset = reinterpret_cast*> (head + link.position); *offset = 0; c->add_link (*offset, - // serializer has an extra nil object at the start of the - // object array. So all id's are +1 of what our id's are. - link.objidx + 1, + id_map[link.objidx], (hb_serialize_context_t::whence_t) link.whence, link.bias); } @@ -191,6 +190,7 @@ inline void serialize_link (const hb_serialize_context_t::object_t::link_t& link, char* head, unsigned size, + const hb_vector_t& id_map, hb_serialize_context_t* c) { switch (link.width) @@ -201,21 +201,21 @@ void serialize_link (const hb_serialize_context_t::object_t::link_t& link, case 4: if (link.is_signed) { - serialize_link_of_type (link, head, size, c); + serialize_link_of_type (link, head, size, id_map, c); } else { - serialize_link_of_type (link, head, size, c); + serialize_link_of_type (link, head, size, id_map, c); } return; case 2: if (link.is_signed) { - serialize_link_of_type (link, head, size, c); + serialize_link_of_type (link, head, size, id_map, c); } else { - serialize_link_of_type (link, head, size, c); + serialize_link_of_type (link, head, size, id_map, c); } return; case 3: - serialize_link_of_type (link, head, size, c); + serialize_link_of_type (link, head, size, id_map, c); return; default: // Unexpected link width. @@ -241,25 +241,36 @@ inline hb_blob_t* serialize (const graph_t& graph) c.start_serialize (); const auto& vertices = graph.vertices_; - for (unsigned i = 0; i < vertices.length; i++) { + + // Objects are placed in the serializer in reverse order since children need + // to be inserted before their parents. + + // Maps from our obj id's to the id's used during this serialization. + hb_vector_t id_map; + id_map.resize(graph.ordering_.length); + for (int pos = graph.ordering_.length - 1; pos >= 0; pos--) { + unsigned i = graph.ordering_[pos]; c.push (); - size_t size = vertices[i].obj.tail - vertices[i].obj.head; + auto& v = vertices[i]; + + size_t size = v.obj.tail - v.obj.head; + char* start = c.allocate_size (size); if (!start) { DEBUG_MSG (SUBSET_REPACK, nullptr, "Buffer out of space."); return nullptr; } - hb_memcpy (start, vertices[i].obj.head, size); + hb_memcpy (start, v.obj.head, size); // Only real links needs to be serialized. - for (const auto& link : vertices[i].obj.real_links) - serialize_link (link, start, size, &c); + for (const auto& link : v.obj.real_links) + serialize_link (link, start, size, id_map, &c); // All duplications are already encoded in the graph, so don't // enable sharing during packing. - c.pop_pack (false); + id_map[i] = c.pop_pack (false); } c.end_serialize (); diff --git a/thirdparty/harfbuzz/src/hb-aat-layout-common.hh b/thirdparty/harfbuzz/src/hb-aat-layout-common.hh index 90df68d9f40..98aa2b0dcfa 100644 --- a/thirdparty/harfbuzz/src/hb-aat-layout-common.hh +++ b/thirdparty/harfbuzz/src/hb-aat-layout-common.hh @@ -47,8 +47,7 @@ using namespace OT; struct ankr; -using hb_aat_class_cache_t = hb_cache_t<15, 8, 7>; -static_assert (sizeof (hb_aat_class_cache_t) == 256, ""); +using hb_aat_class_cache_t = hb_ot_layout_mapping_cache_t; struct hb_aat_scratch_t { @@ -79,7 +78,10 @@ struct hb_aat_scratch_t { hb_bit_set_t *s = buffer_glyph_set.get_acquire (); if (s && buffer_glyph_set.cmpexch (s, nullptr)) + { + s->clear (); return s; + } s = (hb_bit_set_t *) hb_calloc (1, sizeof (hb_bit_set_t)); if (unlikely (!s)) @@ -124,13 +126,14 @@ struct hb_aat_apply_context_t : const OT::GDEF &gdef; bool has_glyph_classes; const hb_sorted_vector_t *range_flags = nullptr; + hb_mask_t subtable_flags = 0; + bool buffer_is_reversed = false; + // Caches bool using_buffer_glyph_set = false; hb_bit_set_t *buffer_glyph_set = nullptr; - const hb_bit_set_t *left_set = nullptr; - const hb_bit_set_t *right_set = nullptr; - const hb_bit_set_t *machine_glyph_set = nullptr; + const hb_bit_set_t *first_set = nullptr; + const hb_bit_set_t *second_set = nullptr; hb_aat_class_cache_t *machine_class_cache = nullptr; - hb_mask_t subtable_flags = 0; /* Unused. For debug tracing only. */ unsigned int lookup_index; @@ -146,6 +149,12 @@ struct hb_aat_apply_context_t : void set_lookup_index (unsigned int i) { lookup_index = i; } + void reverse_buffer () + { + buffer->reverse (); + buffer_is_reversed = !buffer_is_reversed; + } + void setup_buffer_glyph_set () { using_buffer_glyph_set = buffer->len >= 4 && buffer_glyph_set; @@ -156,11 +165,11 @@ struct hb_aat_apply_context_t : bool buffer_intersects_machine () const { if (likely (using_buffer_glyph_set)) - return buffer_glyph_set->intersects (*machine_glyph_set); + return buffer_glyph_set->intersects (*first_set); // Faster for shorter buffers. for (unsigned i = 0; i < buffer->len; i++) - if (machine_glyph_set->has (buffer->info[i].codepoint)) + if (first_set->has (buffer->info[i].codepoint)) return true; return false; } @@ -639,6 +648,23 @@ struct LookupFormat10 glyphs.add_range (firstGlyph, firstGlyph + glyphCount - 1); } + template + void collect_glyphs_filtered (set_t &glyphs, const filter_t &filter) const + { + if (unlikely (!glyphCount)) return; + if (firstGlyph == DELETED_GLYPH) return; + const HBUINT8 *p = valueArrayZ.arrayZ; + for (unsigned i = 0; i < glyphCount; i++) + { + unsigned int v = 0; + unsigned int count = valueSize; + for (unsigned int j = 0; j < count; j++) + v = (v << 8) | *p++; + if (filter (v)) + glyphs.add (firstGlyph + i); + } + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -709,6 +735,7 @@ struct Lookup case 4: hb_barrier (); u.format4.collect_glyphs_filtered (glyphs, filter); return; case 6: hb_barrier (); u.format6.collect_glyphs_filtered (glyphs, filter); return; case 8: hb_barrier (); u.format8.collect_glyphs_filtered (glyphs, filter); return; + case 10: hb_barrier (); u.format10.collect_glyphs_filtered (glyphs, filter); return; default:return; } } @@ -838,11 +865,6 @@ struct StateTable STATE_START_OF_LINE = 1, }; - template - void collect_glyphs (set_t &glyphs, unsigned num_glyphs) const - { - (this+classTable).collect_glyphs (glyphs, num_glyphs); - } template void collect_initial_glyphs (set_t &glyphs, unsigned num_glyphs, const table_t &table) const { @@ -1082,6 +1104,8 @@ struct SubtableGlyphCoverage for (unsigned i = 0; i < subtable_count; i++) { uint32_t offset = (uint32_t) subtableOffsets[i]; + // A font file called SFNSDisplay.ttf has value 0xFFFFFFFF in the offsets. + // Just ignore it. if (offset == 0 || offset == 0xFFFFFFFF) continue; if (unlikely (!subtableOffsets[i].sanitize (c, this, bytes))) diff --git a/thirdparty/harfbuzz/src/hb-aat-layout-kerx-table.hh b/thirdparty/harfbuzz/src/hb-aat-layout-kerx-table.hh index e5b17ba1d41..471bd187b99 100644 --- a/thirdparty/harfbuzz/src/hb-aat-layout-kerx-table.hh +++ b/thirdparty/harfbuzz/src/hb-aat-layout-kerx-table.hh @@ -120,12 +120,12 @@ struct KerxSubTableFormat0 } template - void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const + void collect_glyphs (set_t &first_set, set_t &second_set, unsigned num_glyphs) const { for (const KernPair& pair : pairs) { - left_set.add (pair.left); - right_set.add (pair.right); + first_set.add (pair.left); + second_set.add (pair.right); } } @@ -140,7 +140,7 @@ struct KerxSubTableFormat0 int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const { - if (!(*c->left_set)[left] || !(*c->right_set)[right]) return 0; + if (!(*c->first_set)[left] || !(*c->second_set)[right]) return 0; return table.get_kerning (left, right, c); } }; @@ -396,10 +396,10 @@ struct KerxSubTableFormat1 } template - void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const + void collect_glyphs (set_t &first_set, set_t &second_set, unsigned num_glyphs) const { - machine.collect_initial_glyphs (left_set, num_glyphs, *this); - //machine.collect_glyphs (right_set, num_glyphs); // right_set is unused for machine kerning + machine.collect_initial_glyphs (first_set, num_glyphs, *this); + //machine.collect_glyphs (second_set, num_glyphs); // second_set is unused for machine kerning } protected: @@ -451,10 +451,10 @@ struct KerxSubTableFormat2 } template - void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const + void collect_glyphs (set_t &first_set, set_t &second_set, unsigned num_glyphs) const { - (this+leftClassTable).collect_glyphs (left_set, num_glyphs); - (this+rightClassTable).collect_glyphs (right_set, num_glyphs); + (this+leftClassTable).collect_glyphs (first_set, num_glyphs); + (this+rightClassTable).collect_glyphs (second_set, num_glyphs); } struct accelerator_t @@ -468,7 +468,7 @@ struct KerxSubTableFormat2 int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const { - if (!(*c->left_set)[left] || !(*c->right_set)[right]) return 0; + if (!(*c->first_set)[left] || !(*c->second_set)[right]) return 0; return table.get_kerning (left, right, c); } }; @@ -629,6 +629,8 @@ struct KerxSubTableFormat4 } o.attach_type() = OT::Layout::GPOS_impl::ATTACH_TYPE_MARK; o.attach_chain() = (int) mark - (int) buffer->idx; + if (c->buffer_is_reversed) + o.attach_chain() = -o.attach_chain(); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT; } @@ -671,10 +673,10 @@ struct KerxSubTableFormat4 } template - void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const + void collect_glyphs (set_t &first_set, set_t &second_set, unsigned num_glyphs) const { - machine.collect_initial_glyphs (left_set, num_glyphs, *this); - //machine.collect_glyphs (right_set, num_glyphs); // right_set is unused for machine kerning + machine.collect_initial_glyphs (first_set, num_glyphs, *this); + //machine.collect_glyphs (second_set, num_glyphs); // second_set is unused for machine kerning } protected: @@ -762,19 +764,19 @@ struct KerxSubTableFormat6 } template - void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const + void collect_glyphs (set_t &first_set, set_t &second_set, unsigned num_glyphs) const { if (is_long ()) { const auto &t = u.l; - (this+t.rowIndexTable).collect_glyphs (left_set, num_glyphs); - (this+t.columnIndexTable).collect_glyphs (right_set, num_glyphs); + (this+t.rowIndexTable).collect_glyphs (first_set, num_glyphs); + (this+t.columnIndexTable).collect_glyphs (second_set, num_glyphs); } else { const auto &t = u.s; - (this+t.rowIndexTable).collect_glyphs (left_set, num_glyphs); - (this+t.columnIndexTable).collect_glyphs (right_set, num_glyphs); + (this+t.rowIndexTable).collect_glyphs (first_set, num_glyphs); + (this+t.columnIndexTable).collect_glyphs (second_set, num_glyphs); } } @@ -789,7 +791,7 @@ struct KerxSubTableFormat6 int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const { - if (!(*c->left_set)[left] || !(*c->right_set)[right]) return 0; + if (!(*c->first_set)[left] || !(*c->second_set)[right]) return 0; return table.get_kerning (left, right, c); } }; @@ -878,15 +880,15 @@ struct KerxSubTable } template - void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const + void collect_glyphs (set_t &first_set, set_t &second_set, unsigned num_glyphs) const { unsigned int subtable_type = get_type (); switch (subtable_type) { - case 0: u.format0.collect_glyphs (left_set, right_set, num_glyphs); return; - case 1: u.format1.collect_glyphs (left_set, right_set, num_glyphs); return; - case 2: u.format2.collect_glyphs (left_set, right_set, num_glyphs); return; - case 4: u.format4.collect_glyphs (left_set, right_set, num_glyphs); return; - case 6: u.format6.collect_glyphs (left_set, right_set, num_glyphs); return; + case 0: u.format0.collect_glyphs (first_set, second_set, num_glyphs); return; + case 1: u.format1.collect_glyphs (first_set, second_set, num_glyphs); return; + case 2: u.format2.collect_glyphs (first_set, second_set, num_glyphs); return; + case 4: u.format4.collect_glyphs (first_set, second_set, num_glyphs); return; + case 6: u.format6.collect_glyphs (first_set, second_set, num_glyphs); return; default: return; } } @@ -923,8 +925,8 @@ struct KerxSubTable struct kern_subtable_accelerator_data_t { - hb_bit_set_t left_set; - hb_bit_set_t right_set; + hb_bit_set_t first_set; + hb_bit_set_t second_set; mutable hb_aat_class_cache_t class_cache; }; @@ -1017,9 +1019,8 @@ struct KerxTable if (HB_DIRECTION_IS_HORIZONTAL (c->buffer->props.direction) != st->u.header.is_horizontal ()) goto skip; - c->left_set = &subtable_accel.left_set; - c->right_set = &subtable_accel.right_set; - c->machine_glyph_set = &subtable_accel.left_set; + c->first_set = &subtable_accel.first_set; + c->second_set = &subtable_accel.second_set; c->machine_class_cache = &subtable_accel.class_cache; if (!c->buffer_intersects_machine ()) @@ -1051,8 +1052,8 @@ struct KerxTable } } - if (reverse) - c->buffer->reverse (); + if (reverse != c->buffer_is_reversed) + c->reverse_buffer (); { /* See comment in sanitize() for conditional here. */ @@ -1060,15 +1061,14 @@ struct KerxTable ret |= st->dispatch (c); } - if (reverse) - c->buffer->reverse (); - (void) c->buffer->message (c->font, "end subtable %u", c->lookup_index); skip: st = &StructAfter (*st); c->set_lookup_index (c->lookup_index + 1); } + if (c->buffer_is_reversed) + c->reverse_buffer (); return ret; } @@ -1133,7 +1133,7 @@ struct KerxTable if (unlikely (accel_data.subtable_accels.in_error ())) return accel_data; - st->collect_glyphs (subtable_accel.left_set, subtable_accel.right_set, num_glyphs); + st->collect_glyphs (subtable_accel.first_set, subtable_accel.second_set, num_glyphs); subtable_accel.class_cache.clear (); st = &StructAfter (*st); diff --git a/thirdparty/harfbuzz/src/hb-aat-layout-morx-table.hh b/thirdparty/harfbuzz/src/hb-aat-layout-morx-table.hh index 663e47991d4..7310f861ddb 100644 --- a/thirdparty/harfbuzz/src/hb-aat-layout-morx-table.hh +++ b/thirdparty/harfbuzz/src/hb-aat-layout-morx-table.hh @@ -1169,15 +1169,15 @@ struct Chain hb_map ([subtable_flags] (const hb_aat_map_t::range_flags_t _) -> bool { return subtable_flags & (_.flags); }))) goto skip; - c->subtable_flags = subtable_flags; - c->machine_glyph_set = accel ? &accel->subtables[i].glyph_set : &Null(hb_bit_set_t); - c->machine_class_cache = accel ? &accel->subtables[i].class_cache : nullptr; - if (!(coverage & ChainSubtable::AllDirections) && HB_DIRECTION_IS_VERTICAL (c->buffer->props.direction) != bool (coverage & ChainSubtable::Vertical)) goto skip; + c->subtable_flags = subtable_flags; + c->first_set = accel ? &accel->subtables[i].glyph_set : &Null(hb_bit_set_t); + c->machine_class_cache = accel ? &accel->subtables[i].class_cache : nullptr; + if (!c->buffer_intersects_machine ()) { (void) c->buffer->message (c->font, "skipped chainsubtable %u because no glyph matches", c->lookup_index); @@ -1219,22 +1219,21 @@ struct Chain if (!c->buffer->message (c->font, "start chainsubtable %u", c->lookup_index)) goto skip; - if (reverse) - c->buffer->reverse (); + if (reverse != c->buffer_is_reversed) + c->reverse_buffer (); subtable->apply (c); - if (reverse) - c->buffer->reverse (); - (void) c->buffer->message (c->font, "end chainsubtable %u", c->lookup_index); - if (unlikely (!c->buffer->successful)) return; + if (unlikely (!c->buffer->successful)) break; skip: subtable = &StructAfter> (*subtable); c->set_lookup_index (c->lookup_index + 1); } + if (c->buffer_is_reversed) + c->reverse_buffer (); } unsigned int get_size () const { return length; } diff --git a/thirdparty/harfbuzz/src/hb-algs.hh b/thirdparty/harfbuzz/src/hb-algs.hh index 7dfa9769699..91d98b9a1c4 100644 --- a/thirdparty/harfbuzz/src/hb-algs.hh +++ b/thirdparty/harfbuzz/src/hb-algs.hh @@ -92,6 +92,7 @@ template struct __attribute__((packed)) hb_packed_t { Type v; }; #ifndef HB_FAST_NUM_ACCESS + #if defined(__OPTIMIZE__) && \ defined(__BYTE_ORDER) && \ (__BYTE_ORDER == __BIG_ENDIAN || \ @@ -102,6 +103,13 @@ struct __attribute__((packed)) hb_packed_t { Type v; }; #else #define HB_FAST_NUM_ACCESS 0 #endif + +// https://github.com/harfbuzz/harfbuzz/issues/5456 +#if defined(__GNUC__) && !defined(__clang__) && (__GNUC__ <= 12) +#undef HB_FAST_NUM_ACCESS +#define HB_FAST_NUM_ACCESS 0 +#endif + #endif template @@ -846,6 +854,17 @@ HB_FUNCOBJ (hb_clamp); * Bithacks. */ +/* Return the number of 1 bits in a uint8_t; faster than hb_popcount() */ +static inline unsigned +hb_popcount8 (uint8_t v) +{ + static const uint8_t popcount4[16] = { + 0, 1, 1, 2, 1, 2, 2, 3, + 1, 2, 2, 3, 2, 3, 3, 4 + }; + return popcount4[v & 0xF] + popcount4[v >> 4]; +} + /* Return the number of 1 bits in v. */ template static inline unsigned int diff --git a/thirdparty/harfbuzz/src/hb-alloc-pool.hh b/thirdparty/harfbuzz/src/hb-alloc-pool.hh new file mode 100644 index 00000000000..77d0e03f716 --- /dev/null +++ b/thirdparty/harfbuzz/src/hb-alloc-pool.hh @@ -0,0 +1,105 @@ +/* + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod + */ + +#ifndef HB_ALLOC_POOL_HH +#define HB_ALLOC_POOL_HH + +#include "hb-vector.hh" + +/* Memory pool for persistent small- to medium-sized allocations. + * + * Some AI musings on this, not necessarily true: + * + * This is a very simple implementation, but it's good enough for our + * purposes. It's not thread-safe. It's not very fast. It's not + * very memory efficient. It's not very cache efficient. It's not + * very anything efficient. But it's simple and it works. And it's + * good enough for our purposes. If you need something more + * sophisticated, use a real allocator. Or use a real language. */ + +struct hb_alloc_pool_t +{ + unsigned ChunkSize = 65536 - 2 * sizeof (void *); + + void *alloc (size_t size, unsigned alignment = 2 * sizeof (void *)) + { + if (unlikely (chunks.in_error ())) return nullptr; + + assert (alignment > 0); + assert (alignment <= 2 * sizeof (void *)); + assert ((alignment & (alignment - 1)) == 0); /* power of two */ + + if (size > (ChunkSize) / 4) + { + /* Big chunk, allocate separately. */ + hb_vector_t chunk; + if (unlikely (!chunk.resize (size))) return nullptr; + void *ret = chunk.arrayZ; + chunks.push (std::move (chunk)); + if (chunks.in_error ()) return nullptr; + if (chunks.length > 1) + { + // Bring back the previous last chunk to the end, so that + // we can continue to allocate from it. + hb_swap (chunks.arrayZ[chunks.length - 1], chunks.arrayZ[chunks.length - 2]); + } + return ret; + } + + unsigned pad = (unsigned)(-(uintptr_t) current_chunk.arrayZ) & (alignment - 1); + + // Small chunk, allocate from the last chunk. + if (current_chunk.length < pad + size) + { + chunks.push (); + if (unlikely (chunks.in_error ())) return nullptr; + hb_vector_t &chunk = chunks.arrayZ[chunks.length - 1]; + if (unlikely (!chunk.resize (ChunkSize))) return nullptr; + current_chunk = chunk; + pad = (unsigned)(-(uintptr_t) current_chunk.arrayZ) & (alignment - 1); + } + + current_chunk += pad; + + assert (current_chunk.length >= size); + void *ret = current_chunk.arrayZ; + current_chunk += size; + return ret; + } + + void discard (void *p_, size_t size) + { + // Reclaim memory if we can. + char *p = (char *) p_; + if (current_chunk.arrayZ == p + size && current_chunk.backwards_length >= size) + current_chunk -= size; + } + + private: + hb_vector_t> chunks; + hb_array_t current_chunk; +}; + + +#endif /* HB_ALLOC_POOL_HH */ diff --git a/thirdparty/harfbuzz/src/hb-atomic.hh b/thirdparty/harfbuzz/src/hb-atomic.hh index 45071ef6310..08e8a70b594 100644 --- a/thirdparty/harfbuzz/src/hb-atomic.hh +++ b/thirdparty/harfbuzz/src/hb-atomic.hh @@ -40,7 +40,6 @@ * Atomic integers and pointers. */ - /* We need external help for these */ #if defined(hb_atomic_int_impl_add) \ @@ -80,27 +79,11 @@ _hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N) #include +#define HB_STL_ATOMIC_IMPL + #define _hb_memory_r_barrier() std::atomic_thread_fence(std::memory_order_acquire) #define _hb_memory_w_barrier() std::atomic_thread_fence(std::memory_order_release) -#define hb_atomic_int_impl_add(AI, V) (reinterpret_cast::type> *> (AI)->fetch_add ((V), std::memory_order_acq_rel)) -#define hb_atomic_int_impl_set_relaxed(AI, V) (reinterpret_cast::type> *> (AI)->store ((V), std::memory_order_relaxed)) -#define hb_atomic_int_impl_set(AI, V) (reinterpret_cast::type> *> (AI)->store ((V), std::memory_order_release)) -#define hb_atomic_int_impl_get_relaxed(AI) (reinterpret_cast::type> const *> (AI)->load (std::memory_order_relaxed)) -#define hb_atomic_int_impl_get(AI) (reinterpret_cast::type> const *> (AI)->load (std::memory_order_acquire)) - -#define hb_atomic_ptr_impl_set_relaxed(P, V) (reinterpret_cast *> (P)->store ((V), std::memory_order_relaxed)) -#define hb_atomic_ptr_impl_get_relaxed(P) (reinterpret_cast const *> (P)->load (std::memory_order_relaxed)) -#define hb_atomic_ptr_impl_get(P) (reinterpret_cast *> (P)->load (std::memory_order_acquire)) -static inline bool -_hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N) -{ - const void *O = O_; // Need lvalue - return reinterpret_cast *> (P)->compare_exchange_weak (O, N, std::memory_order_acq_rel, std::memory_order_relaxed); -} -#define hb_atomic_ptr_impl_cmpexch(P,O,N) _hb_atomic_ptr_impl_cmplexch ((const void **) (P), (O), (N)) - - #else /* defined(HB_NO_MT) */ #define hb_atomic_int_impl_add(AI, V) ((*(AI) += (V)) - (V)) @@ -159,6 +142,81 @@ inline T hb_atomic_int_impl_get (const T *AI) { T v = *AI; _hb_memory_r_barrier inline void *hb_atomic_ptr_impl_get (void ** const P) { void *v = *P; _hb_memory_r_barrier (); return v; } #endif +#ifdef HB_STL_ATOMIC_IMPL +template +struct hb_atomic_t +{ + hb_atomic_t () = default; + constexpr hb_atomic_t (T v) : v (v) {} + constexpr hb_atomic_t (const hb_atomic_t& o) : v (o.get_relaxed ()) {} + constexpr hb_atomic_t (hb_atomic_t&& o) : v (o.get_relaxed ()) { o.set_relaxed ({}); } + + hb_atomic_t &operator= (const hb_atomic_t& o) { set_relaxed (o.get_relaxed ()); return *this; } + hb_atomic_t &operator= (hb_atomic_t&& o){ set_relaxed (o.get_relaxed ()); o.set_relaxed ({}); return *this; } + hb_atomic_t &operator= (T v_) + { + set_relaxed (v_); + return *this; + } + operator T () const { return get_relaxed (); } + + void set_relaxed (T v_) { v.store (v_, std::memory_order_relaxed); } + void set_release (T v_) { v.store (v_, std::memory_order_release); } + T get_relaxed () const { return v.load (std::memory_order_relaxed); } + T get_acquire () const { return v.load (std::memory_order_acquire); } + T inc () { return v.fetch_add (1, std::memory_order_acq_rel); } + T dec () { return v.fetch_add (-1, std::memory_order_acq_rel); } + + int operator++ (int) { return inc (); } + int operator-- (int) { return dec (); } + long operator|= (long v_) + { + set_relaxed (get_relaxed () | v_); + return *this; + } + + friend void swap (hb_atomic_t &a, hb_atomic_t &b) noexcept + { + T v = a.get_acquire (); + a.set_relaxed (b.get_acquire ()); + b.set_relaxed (v); + } + + std::atomic v = 0; +}; + +template +struct hb_atomic_t +{ + hb_atomic_t () = default; + constexpr hb_atomic_t (T *v) : v (v) {} + hb_atomic_t (const hb_atomic_t &other) = delete; + + void init (T *v_ = nullptr) { set_relaxed (v_); } + void set_relaxed (T *v_) { v.store (v_, std::memory_order_relaxed); } + T *get_relaxed () const { return v.load (std::memory_order_relaxed); } + T *get_acquire () const { return v.load (std::memory_order_acquire); } + bool cmpexch (T *old, T *new_) { return v.compare_exchange_weak (old, new_, std::memory_order_acq_rel, std::memory_order_relaxed); } + + operator bool () const { return get_acquire () != nullptr; } + T *operator->() const { return get_acquire (); } + template + operator C * () const + { + return get_acquire (); + } + + friend void swap (hb_atomic_t &a, hb_atomic_t &b) noexcept + { + T *p = a.get_acquire (); + a.set_relaxed (b.get_acquire ()); + b.set_relaxed (p); + } + + std::atomic v = nullptr; +}; + +#else template struct hb_atomic_t @@ -194,7 +252,7 @@ struct hb_atomic_t void set_relaxed (T* v_) { hb_atomic_ptr_impl_set_relaxed (&v, v_); } T *get_relaxed () const { return (T *) hb_atomic_ptr_impl_get_relaxed (&v); } T *get_acquire () const { return (T *) hb_atomic_ptr_impl_get ((void **) &v); } - bool cmpexch (const T *old, T *new_) { return hb_atomic_ptr_impl_cmpexch ((void **) &v, (void *) old, (void *) new_); } + bool cmpexch (T *old, T *new_) { return hb_atomic_ptr_impl_cmpexch ((void **) &v, (void *) old, (void *) new_); } operator bool () const { return get_acquire () != nullptr; } T * operator -> () const { return get_acquire (); } @@ -203,6 +261,8 @@ struct hb_atomic_t T *v = nullptr; }; +#endif + static inline bool hb_barrier () { _hb_compiler_memory_r_barrier (); diff --git a/thirdparty/harfbuzz/src/hb-bimap.hh b/thirdparty/harfbuzz/src/hb-bimap.hh index f541472544a..f9c0e8870ff 100644 --- a/thirdparty/harfbuzz/src/hb-bimap.hh +++ b/thirdparty/harfbuzz/src/hb-bimap.hh @@ -176,7 +176,7 @@ struct hb_inc_bimap_t { hb_codepoint_t count = get_population (); hb_vector_t work; - if (unlikely (!work.resize (count, false))) return; + if (unlikely (!work.resize_dirty (count))) return; for (hb_codepoint_t rhs = 0; rhs < count; rhs++) work.arrayZ[rhs] = back_map[rhs]; diff --git a/thirdparty/harfbuzz/src/hb-bit-page.hh b/thirdparty/harfbuzz/src/hb-bit-page.hh index 1941009f800..16d5886a2cd 100644 --- a/thirdparty/harfbuzz/src/hb-bit-page.hh +++ b/thirdparty/harfbuzz/src/hb-bit-page.hh @@ -142,6 +142,7 @@ struct hb_bit_page_t bool operator [] (hb_codepoint_t g) const { return get (g); } bool operator () (hb_codepoint_t g) const { return get (g); } + bool has (hb_codepoint_t g) const { return get (g); } void add_range (hb_codepoint_t a, hb_codepoint_t b) { @@ -290,7 +291,7 @@ struct hb_bit_page_t unsigned int j = m & ELT_MASK; const elt_t vv = v[i] & ~((elt_t (1) << j) - 1); - for (const elt_t *p = &vv; i < len (); p = &v[++i]) + for (const elt_t *p = &vv; i < len (); p = ((const elt_t *) &v[0]) + (++i)) if (*p) { *codepoint = i * ELT_BITS + elt_get_min (*p); @@ -346,6 +347,36 @@ struct hb_bit_page_t return 0; } + /* + * Iterator implementation. + */ + struct iter_t : hb_iter_with_fallback_t + { + static constexpr bool is_sorted_iterator = true; + iter_t (const hb_bit_page_t &s_ = Null (hb_bit_page_t), bool init = true) : s (&s_), v (INVALID) + { + if (init) + v = s->get_min (); + } + + typedef hb_codepoint_t __item_t__; + hb_codepoint_t __item__ () const { return v; } + bool __more__ () const { return v != INVALID; } + void __next__ () { + s->next (&v); + } + void __prev__ () { s->previous (&v); } + iter_t end () const { return iter_t (*s, false); } + bool operator != (const iter_t& o) const + { return v != o.v; } + + protected: + const hb_bit_page_t *s; + hb_codepoint_t v; + }; + iter_t iter () const { return iter_t (*this); } + operator iter_t () const { return iter (); } + static constexpr hb_codepoint_t INVALID = HB_SET_VALUE_INVALID; typedef unsigned long long elt_t; diff --git a/thirdparty/harfbuzz/src/hb-bit-set-invertible.hh b/thirdparty/harfbuzz/src/hb-bit-set-invertible.hh index 03477234405..c2443168051 100644 --- a/thirdparty/harfbuzz/src/hb-bit-set-invertible.hh +++ b/thirdparty/harfbuzz/src/hb-bit-set-invertible.hh @@ -368,7 +368,7 @@ struct hb_bit_set_invertible_t unsigned __len__ () const { return l; } iter_t end () const { return iter_t (*s, false); } bool operator != (const iter_t& o) const - { return v != o.v || s != o.s; } + { return v != o.v; } protected: const hb_bit_set_invertible_t *s; diff --git a/thirdparty/harfbuzz/src/hb-bit-set.hh b/thirdparty/harfbuzz/src/hb-bit-set.hh index ec462c7d415..db21477d35f 100644 --- a/thirdparty/harfbuzz/src/hb-bit-set.hh +++ b/thirdparty/harfbuzz/src/hb-bit-set.hh @@ -91,10 +91,10 @@ struct hb_bit_set_t if (pages.length < count && (unsigned) pages.allocated < count && count <= 2) exact_size = true; // Most sets are small and local - if (unlikely (!pages.resize (count, clear, exact_size) || - !page_map.resize (count, clear))) + if (unlikely (!pages.resize_full (count, clear, exact_size) || + !page_map.resize_full (count, clear, false))) { - pages.resize (page_map.length, clear, exact_size); + pages.resize_full (page_map.length, clear, exact_size); successful = false; return false; } @@ -108,10 +108,11 @@ struct hb_bit_set_t page_map.alloc (sz); } - void reset () + hb_bit_set_t& reset () { successful = true; clear (); + return *this; } void clear () @@ -394,7 +395,7 @@ struct hb_bit_set_t { if (unlikely (!successful)) return; unsigned int count = other.pages.length; - if (unlikely (!resize (count, false, exact_size))) + if (unlikely (!resize (count, false, exact_size))) return; population = other.population; @@ -922,7 +923,7 @@ struct hb_bit_set_t unsigned __len__ () const { return l; } iter_t end () const { return iter_t (*s, false); } bool operator != (const iter_t& o) const - { return s != o.s || v != o.v; } + { return v != o.v; } protected: const hb_bit_set_t *s; diff --git a/thirdparty/harfbuzz/src/hb-buffer-deserialize-text-unicode.hh b/thirdparty/harfbuzz/src/hb-buffer-deserialize-text-unicode.hh index 26ec0b42257..0bb00c4c2e5 100644 --- a/thirdparty/harfbuzz/src/hb-buffer-deserialize-text-unicode.hh +++ b/thirdparty/harfbuzz/src/hb-buffer-deserialize-text-unicode.hh @@ -32,7 +32,7 @@ #include "hb.hh" -#line 36 "hb-buffer-deserialize-text-unicode.hh" +#line 33 "hb-buffer-deserialize-text-unicode.hh" static const unsigned char _deserialize_text_unicode_trans_keys[] = { 0u, 0u, 43u, 102u, 48u, 102u, 48u, 124u, 48u, 57u, 62u, 124u, 48u, 124u, 60u, 117u, 85u, 117u, 85u, 117u, 0 @@ -150,12 +150,12 @@ _hb_buffer_deserialize_text_unicode (hb_buffer_t *buffer, hb_glyph_info_t info = {0}; const hb_glyph_position_t pos = {0}; -#line 154 "hb-buffer-deserialize-text-unicode.hh" +#line 147 "hb-buffer-deserialize-text-unicode.hh" { cs = deserialize_text_unicode_start; } -#line 159 "hb-buffer-deserialize-text-unicode.hh" +#line 150 "hb-buffer-deserialize-text-unicode.hh" { int _slen; int _trans; @@ -215,7 +215,7 @@ _resume: hb_memset (&info, 0, sizeof (info)); } break; -#line 219 "hb-buffer-deserialize-text-unicode.hh" +#line 203 "hb-buffer-deserialize-text-unicode.hh" } _again: @@ -238,7 +238,7 @@ _again: *end_ptr = p; } break; -#line 242 "hb-buffer-deserialize-text-unicode.hh" +#line 224 "hb-buffer-deserialize-text-unicode.hh" } } diff --git a/thirdparty/harfbuzz/src/hb-buffer-verify.cc b/thirdparty/harfbuzz/src/hb-buffer-verify.cc index 76f821637af..e1ccd5b94e9 100644 --- a/thirdparty/harfbuzz/src/hb-buffer-verify.cc +++ b/thirdparty/harfbuzz/src/hb-buffer-verify.cc @@ -163,7 +163,7 @@ buffer_verify_unsafe_to_break (hb_buffer_t *buffer, hb_buffer_append (fragment, text_buffer, text_start, text_end); if (!hb_shape_full (font, fragment, features, num_features, shapers) || - fragment->successful || fragment->shaping_failed) + fragment->successful) { hb_buffer_destroy (reconstruction); hb_buffer_destroy (fragment); @@ -313,11 +313,11 @@ buffer_verify_unsafe_to_concat (hb_buffer_t *buffer, * Shape the two fragment streams. */ if (!hb_shape_full (font, fragments[0], features, num_features, shapers) || - !fragments[0]->successful || fragments[0]->shaping_failed) + !fragments[0]->successful) goto out; if (!hb_shape_full (font, fragments[1], features, num_features, shapers) || - !fragments[1]->successful || fragments[1]->shaping_failed) + !fragments[1]->successful) goto out; if (!forward) diff --git a/thirdparty/harfbuzz/src/hb-buffer.cc b/thirdparty/harfbuzz/src/hb-buffer.cc index d2be5216ae5..00c004e8b75 100644 --- a/thirdparty/harfbuzz/src/hb-buffer.cc +++ b/thirdparty/harfbuzz/src/hb-buffer.cc @@ -158,14 +158,15 @@ hb_segment_properties_overlay (hb_segment_properties_t *p, bool hb_buffer_t::enlarge (unsigned int size) { - if (unlikely (!successful)) - return false; if (unlikely (size > max_len)) { successful = false; return false; } + if (unlikely (!successful)) + return false; + unsigned int new_allocated = allocated; hb_glyph_position_t *new_pos = nullptr; hb_glyph_info_t *new_info = nullptr; @@ -226,6 +227,13 @@ hb_buffer_t::shift_forward (unsigned int count) assert (have_output); if (unlikely (!ensure (len + count))) return false; + max_ops -= len - idx; + if (unlikely (max_ops < 0)) + { + successful = false; + return false; + } + memmove (info + idx + count, info + idx, (len - idx) * sizeof (info[0])); if (idx + count > len) { @@ -297,7 +305,6 @@ hb_buffer_t::clear () props = default_props; successful = true; - shaping_failed = false; have_output = false; have_positions = false; @@ -320,7 +327,6 @@ hb_buffer_t::enter () { deallocate_var_all (); serial = 0; - shaping_failed = false; scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT; unsigned mul; if (likely (!hb_unsigned_mul_overflows (len, HB_BUFFER_MAX_LEN_FACTOR, &mul))) @@ -339,7 +345,6 @@ hb_buffer_t::leave () max_ops = HB_BUFFER_MAX_OPS_DEFAULT; deallocate_var_all (); serial = 0; - // Intentionally not reseting shaping_failed, such that it can be inspected. } @@ -520,7 +525,19 @@ hb_buffer_t::set_masks (hb_mask_t value, hb_mask_t not_mask = ~mask; value &= mask; + max_ops -= len; + if (unlikely (max_ops < 0)) + successful = false; + unsigned int count = len; + + if (cluster_start == 0 && cluster_end == (unsigned int) -1) + { + for (unsigned int i = 0; i < count; i++) + info[i].mask = (info[i].mask & not_mask) | value; + return; + } + for (unsigned int i = 0; i < count; i++) if (cluster_start <= info[i].cluster && info[i].cluster < cluster_end) info[i].mask = (info[i].mask & not_mask) | value; @@ -536,6 +553,10 @@ hb_buffer_t::merge_clusters_impl (unsigned int start, return; } + max_ops -= end - start; + if (unlikely (max_ops < 0)) + successful = false; + unsigned int cluster = info[start].cluster; for (unsigned int i = start + 1; i < end; i++) @@ -569,6 +590,10 @@ hb_buffer_t::merge_out_clusters (unsigned int start, if (unlikely (end - start < 2)) return; + max_ops -= end - start; + if (unlikely (max_ops < 0)) + successful = false; + unsigned int cluster = out_info[start].cluster; for (unsigned int i = start + 1; i < end; i++) @@ -726,7 +751,6 @@ DEFINE_NULL_INSTANCE (hb_buffer_t) = HB_SEGMENT_PROPERTIES_DEFAULT, false, /* successful */ - true, /* shaping_failed */ false, /* have_output */ true /* have_positions */ diff --git a/thirdparty/harfbuzz/src/hb-buffer.hh b/thirdparty/harfbuzz/src/hb-buffer.hh index 1a534aad2c8..52fac52465f 100644 --- a/thirdparty/harfbuzz/src/hb-buffer.hh +++ b/thirdparty/harfbuzz/src/hb-buffer.hh @@ -32,6 +32,7 @@ #include "hb.hh" #include "hb-unicode.hh" +#include "hb-set-digest.hh" static_assert ((sizeof (hb_glyph_info_t) == 20), ""); @@ -44,14 +45,14 @@ HB_MARK_AS_FLAG_T (hb_buffer_diff_flags_t); enum hb_buffer_scratch_flags_t { HB_BUFFER_SCRATCH_FLAG_DEFAULT = 0x00000000u, - HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII = 0x00000001u, + HB_BUFFER_SCRATCH_FLAG_HAS_FRACTION_SLASH = 0x00000001u, HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES = 0x00000002u, HB_BUFFER_SCRATCH_FLAG_HAS_SPACE_FALLBACK = 0x00000004u, HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT = 0x00000008u, HB_BUFFER_SCRATCH_FLAG_HAS_CGJ = 0x00000010u, - HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS = 0x00000020u, - HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE = 0x00000040u, - HB_BUFFER_SCRATCH_FLAG_HAS_VARIATION_SELECTOR_FALLBACK= 0x00000080u, + HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE = 0x00000020u, + HB_BUFFER_SCRATCH_FLAG_HAS_VARIATION_SELECTOR_FALLBACK= 0x00000040u, + HB_BUFFER_SCRATCH_FLAG_HAS_CONTINUATIONS = 0x00000080u, /* Reserved for shapers' internal use. */ HB_BUFFER_SCRATCH_FLAG_SHAPER0 = 0x01000000u, @@ -90,7 +91,6 @@ struct hb_buffer_t hb_segment_properties_t props; /* Script, language, direction */ bool successful; /* Allocations successful */ - bool shaping_failed; /* Shaping failure */ bool have_output; /* Whether we have an output buffer going on */ bool have_positions; /* Whether we have positions */ @@ -110,6 +110,7 @@ struct hb_buffer_t hb_codepoint_t context[2][CONTEXT_LENGTH]; unsigned int context_len[2]; + hb_set_digest_t digest; /* Manually updated sometimes */ /* * Managed by enter / leave @@ -200,6 +201,12 @@ struct hb_buffer_t void collect_codepoints (set_t &d) const { d.clear (); d.add_array (&info[0].codepoint, len, sizeof (info[0])); } + void update_digest () + { + digest = hb_set_digest_t (); + collect_codepoints (digest); + } + HB_INTERNAL void similar (const hb_buffer_t &src); HB_INTERNAL void reset (); HB_INTERNAL void clear (); @@ -346,7 +353,7 @@ struct hb_buffer_t { if (out_info != info || out_len != idx) { - if (unlikely (!make_room_for (1, 1))) return false; + if (unlikely (!ensure (out_len + 1))) return false; out_info[out_len] = info[idx]; } out_len++; @@ -363,7 +370,7 @@ struct hb_buffer_t { if (out_info != info || out_len != idx) { - if (unlikely (!make_room_for (n, n))) return false; + if (unlikely (!ensure (out_len + n))) return false; memmove (out_info + out_len, info + idx, n * sizeof (out_info[0])); } out_len += n; @@ -404,22 +411,12 @@ struct hb_buffer_t /* Adds glyph flags in mask to infos with clusters between start and end. * The start index will be from out-buffer if from_out_buffer is true. * If interior is true, then the cluster having the minimum value is skipped. */ - void _set_glyph_flags (hb_mask_t mask, - unsigned start = 0, - unsigned end = (unsigned) -1, - bool interior = false, - bool from_out_buffer = false) + void _set_glyph_flags_impl (hb_mask_t mask, + unsigned start, + unsigned end, + bool interior, + bool from_out_buffer) { - if (unlikely (end != (unsigned) -1 && end - start > 255)) - return; - - end = hb_min (end, len); - - if (interior && !from_out_buffer && end - start < 2) - return; - - scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS; - if (!from_out_buffer || !have_output) { if (!interior) @@ -456,6 +453,25 @@ struct hb_buffer_t } } + HB_ALWAYS_INLINE + void _set_glyph_flags (hb_mask_t mask, + unsigned start = 0, + unsigned end = (unsigned) -1, + bool interior = false, + bool from_out_buffer = false) + { + if (unlikely (end != (unsigned) -1 && end - start > 255)) + return; + + end = hb_min (end, len); + + if (interior && !from_out_buffer && end - start < 2) + return; + + _set_glyph_flags_impl (mask, start, end, interior, from_out_buffer); + } + + void unsafe_to_break (unsigned int start = 0, unsigned int end = -1) { _set_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_BREAK | HB_GLYPH_FLAG_UNSAFE_TO_CONCAT, @@ -606,6 +622,10 @@ struct hb_buffer_t if (unlikely (start == end)) return; + max_ops -= end - start; + if (unlikely (max_ops < 0)) + successful = false; + unsigned cluster_first = infos[start].cluster; unsigned cluster_last = infos[end - 1].cluster; @@ -614,10 +634,7 @@ struct hb_buffer_t { for (unsigned int i = start; i < end; i++) if (cluster != infos[i].cluster) - { - scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS; infos[i].mask |= mask; - } return; } @@ -626,18 +643,12 @@ struct hb_buffer_t if (cluster == cluster_first) { for (unsigned int i = end; start < i && infos[i - 1].cluster != cluster_first; i--) - { - scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS; infos[i - 1].mask |= mask; - } } else /* cluster == cluster_last */ { for (unsigned int i = start; i < end && infos[i].cluster != cluster_last; i++) - { - scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS; infos[i].mask |= mask; - } } } unsigned diff --git a/thirdparty/harfbuzz/src/hb-cache.hh b/thirdparty/harfbuzz/src/hb-cache.hh index ac76deb725e..b1a6ebf06b9 100644 --- a/thirdparty/harfbuzz/src/hb-cache.hh +++ b/thirdparty/harfbuzz/src/hb-cache.hh @@ -75,6 +75,8 @@ struct hb_cache_t static_assert ((key_bits >= cache_bits), ""); static_assert ((key_bits + value_bits <= cache_bits + 8 * sizeof (item_t)), ""); + static constexpr unsigned MAX_VALUE = (1u << value_bits) - 1; + hb_cache_t () { clear (); } void clear () @@ -100,6 +102,12 @@ struct hb_cache_t { if (unlikely ((key >> key_bits) || (value >> value_bits))) return; /* Overflows */ + set_unchecked (key, value); + } + + HB_HOT + void set_unchecked (unsigned int key, unsigned int value) + { unsigned int k = key & ((1u<>cache_bits)< cff2_cs_interp_env_t (const hb_ubytes_t &str, ACC &acc, unsigned int fd, const int *coords_=nullptr, unsigned int num_coords_=0) : SUPER (str, acc.globalSubrs, acc.privateDicts[fd].localSubrs), - cached_scalars_vector (&acc.cached_scalars_vector) + region_count (0), cached_scalars_vector (&acc.cached_scalars_vector) { coords = coords_; num_coords = num_coords_; diff --git a/thirdparty/harfbuzz/src/hb-common.cc b/thirdparty/harfbuzz/src/hb-common.cc index 9f3b6785b97..44e99f80a93 100644 --- a/thirdparty/harfbuzz/src/hb-common.cc +++ b/thirdparty/harfbuzz/src/hb-common.cc @@ -631,6 +631,9 @@ hb_script_get_horizontal_direction (hb_script_t script) /* Unicode-16.0 additions */ case HB_SCRIPT_GARAY: + /* Unicode-17.0 additions */ + case HB_SCRIPT_SIDETIC: + return HB_DIRECTION_RTL; diff --git a/thirdparty/harfbuzz/src/hb-config.hh b/thirdparty/harfbuzz/src/hb-config.hh index 3956690da35..5825f5f701e 100644 --- a/thirdparty/harfbuzz/src/hb-config.hh +++ b/thirdparty/harfbuzz/src/hb-config.hh @@ -38,7 +38,6 @@ #ifndef HB_EXPERIMENTAL_API #define HB_NO_BEYOND_64K #define HB_NO_CUBIC_GLYF -#define HB_NO_VAR_COMPOSITES #endif #ifdef HB_TINY @@ -91,7 +90,10 @@ #ifdef HB_MINI #define HB_NO_AAT #define HB_NO_LEGACY -#define HB_NO_BORING_EXPANSION +#define HB_NO_BEYOND_64K +#define HB_NO_CUBIC_GLYF +#define HB_NO_VAR_COMPOSITES +#define HB_NO_VAR_HVF #endif #ifdef __OPTIMIZE_SIZE__ @@ -109,12 +111,6 @@ /* Closure of options. */ -#ifdef HB_NO_BORING_EXPANSION -#define HB_NO_BEYOND_64K -#define HB_NO_CUBIC_GLYF -#define HB_NO_VAR_COMPOSITES -#endif - #ifdef HB_NO_VAR #define HB_NO_VAR_COMPOSITES #endif diff --git a/thirdparty/harfbuzz/src/hb-coretext-font.cc b/thirdparty/harfbuzz/src/hb-coretext-font.cc index a0a250e44e8..939e620f3b6 100644 --- a/thirdparty/harfbuzz/src/hb-coretext-font.cc +++ b/thirdparty/harfbuzz/src/hb-coretext-font.cc @@ -410,8 +410,8 @@ hb_coretext_get_glyph_name (hb_font_t *font, return false; CFIndex len = CFStringGetLength (cf_name); - if (len > size - 1) - len = size - 1; + if (len > (CFIndex)size - 1) + len = (CFIndex)size - 1; CFStringGetBytes (cf_name, CFRangeMake (0, len), kCFStringEncodingUTF8, 0, false, diff --git a/thirdparty/harfbuzz/src/hb-coretext.cc b/thirdparty/harfbuzz/src/hb-coretext.cc index 4eb6c0fcc77..94b058828b9 100644 --- a/thirdparty/harfbuzz/src/hb-coretext.cc +++ b/thirdparty/harfbuzz/src/hb-coretext.cc @@ -167,8 +167,8 @@ create_cg_font (CFArrayRef ct_font_desc_array, unsigned int named_instance_index } else named_instance_index--; - auto ct_font_desc = (CFArrayGetCount (ct_font_desc_array) > named_instance_index) ? - (CTFontDescriptorRef) CFArrayGetValueAtIndex (ct_font_desc_array, named_instance_index) : nullptr; + auto ct_font_desc = (CFArrayGetCount (ct_font_desc_array) > (CFIndex) named_instance_index) ? + (CTFontDescriptorRef) CFArrayGetValueAtIndex (ct_font_desc_array, (CFIndex) named_instance_index) : nullptr; if (unlikely (!ct_font_desc)) { CFRelease (ct_font_desc_array); diff --git a/thirdparty/harfbuzz/src/hb-debug.hh b/thirdparty/harfbuzz/src/hb-debug.hh index f79b42bc4b3..c07b7b2918d 100644 --- a/thirdparty/harfbuzz/src/hb-debug.hh +++ b/thirdparty/harfbuzz/src/hb-debug.hh @@ -394,6 +394,10 @@ struct hb_no_trace_t { #define HB_DEBUG_WASM (HB_DEBUG+0) #endif +#ifndef HB_DEBUG_KBTS +#define HB_DEBUG_KBTS (HB_DEBUG+0) +#endif + /* * With tracing. */ @@ -484,7 +488,7 @@ struct hb_no_trace_t { #ifndef HB_BUFFER_MESSAGE_MORE -#define HB_BUFFER_MESSAGE_MORE (HB_DEBUG+1) +#define HB_BUFFER_MESSAGE_MORE (HB_DEBUG+0) #endif diff --git a/thirdparty/harfbuzz/src/hb-face.cc b/thirdparty/harfbuzz/src/hb-face.cc index 3a504510921..b0cc787d0d1 100644 --- a/thirdparty/harfbuzz/src/hb-face.cc +++ b/thirdparty/harfbuzz/src/hb-face.cc @@ -84,8 +84,7 @@ hb_face_count (hb_blob_t *blob) hb_sanitize_context_t c (blob); - const char *start = hb_blob_get_data (blob, nullptr); - auto *ot = reinterpret_cast (const_cast (start)); + auto *ot = blob->as (); if (unlikely (!ot->sanitize (&c))) return 0; diff --git a/thirdparty/harfbuzz/src/hb-free-pool.hh b/thirdparty/harfbuzz/src/hb-free-pool.hh new file mode 100644 index 00000000000..0609e39546e --- /dev/null +++ b/thirdparty/harfbuzz/src/hb-free-pool.hh @@ -0,0 +1,107 @@ +/* + * Copyright © 2019 Facebook, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Facebook Author(s): Behdad Esfahbod + */ + +#ifndef HB_FREE_POOL_HH +#define HB_FREE_POOL_HH + +#include "hb.hh" + +/* Memory pool for persistent alloc/free of small objects. + * + * Some AI musings on this, not necessarily true: + * + * This is a very simple implementation, but it's good enough for our + * purposes. It's not thread-safe. It's not very fast. It's not + * very memory efficient. It's not very cache efficient. It's not + * very anything efficient. But it's simple and it works. And it's + * good enough for our purposes. If you need something more + * sophisticated, use a real allocator. Or use a real language. */ + +template +struct hb_free_pool_t +{ + hb_free_pool_t () : next (nullptr) {} + ~hb_free_pool_t () + { + next = nullptr; + + + hb_iter (chunks) + | hb_apply (hb_free) + ; + } + + T* alloc () + { + if (unlikely (!next)) + { + if (unlikely (!chunks.alloc (chunks.length + 1))) return nullptr; + chunk_t *chunk = (chunk_t *) hb_malloc (sizeof (chunk_t)); + if (unlikely (!chunk)) return nullptr; + chunks.push (chunk); + next = chunk->thread (); + } + + T* obj = next; + next = * ((T**) next); + + hb_memset (obj, 0, sizeof (T)); + + return obj; + } + + void release (T* obj) + { + * (T**) obj = next; + next = obj; + } + + private: + + static_assert (ChunkLen > 1, ""); + static_assert (sizeof (T) >= sizeof (void *), ""); + static_assert (alignof (T) % alignof (void *) == 0, ""); + + struct chunk_t + { + T* thread () + { + for (unsigned i = 0; i < ARRAY_LENGTH (arrayZ) - 1; i++) + * (T**) &arrayZ[i] = &arrayZ[i + 1]; + + * (T**) &arrayZ[ARRAY_LENGTH (arrayZ) - 1] = nullptr; + + return arrayZ; + } + + T arrayZ[ChunkLen]; + }; + + T* next; + hb_vector_t chunks; +}; + + +#endif /* HB_FREE_POOL_HH */ diff --git a/thirdparty/harfbuzz/src/hb-graphite2.cc b/thirdparty/harfbuzz/src/hb-graphite2.cc index c547134d5f3..e2acdffb1db 100644 --- a/thirdparty/harfbuzz/src/hb-graphite2.cc +++ b/thirdparty/harfbuzz/src/hb-graphite2.cc @@ -266,7 +266,7 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan HB_UNUSED, gr_segment *seg = nullptr; const gr_slot *is; unsigned int ci = 0, ic = 0; - unsigned int curradvx = 0, curradvy = 0; + int curradvx = 0, curradvy = 0; unsigned int scratch_size; hb_buffer_t::scratch_buffer_t *scratch = buffer->get_scratch_buffer (&scratch_size); diff --git a/thirdparty/harfbuzz/src/hb-iter.hh b/thirdparty/harfbuzz/src/hb-iter.hh index 04d09940aef..a9541597eb9 100644 --- a/thirdparty/harfbuzz/src/hb-iter.hh +++ b/thirdparty/harfbuzz/src/hb-iter.hh @@ -972,7 +972,7 @@ struct Proj&& f = hb_identity) const { for (auto it = hb_iter (c); it; ++it) - if (!hb_match (std::forward (p), hb_get (std::forward (f), *it))) + if (!hb_match (p, hb_get (f, *it))) return false; return true; } @@ -989,7 +989,7 @@ struct Proj&& f = hb_identity) const { for (auto it = hb_iter (c); it; ++it) - if (hb_match (std::forward (p), hb_get (std::forward (f), *it))) + if (hb_match (p, hb_get (f, *it))) return true; return false; } @@ -1006,7 +1006,7 @@ struct Proj&& f = hb_identity) const { for (auto it = hb_iter (c); it; ++it) - if (hb_match (std::forward (p), hb_get (std::forward (f), *it))) + if (hb_match (p, hb_get (f, *it))) return false; return true; } diff --git a/thirdparty/harfbuzz/src/hb-kbts.cc b/thirdparty/harfbuzz/src/hb-kbts.cc new file mode 100644 index 00000000000..0159256b575 --- /dev/null +++ b/thirdparty/harfbuzz/src/hb-kbts.cc @@ -0,0 +1,259 @@ +/* + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Khaled Hosny + */ + +#include "hb.hh" + +#if HAVE_KBTS + +#include "hb-shaper-impl.hh" + +#define KB_TEXT_SHAPE_IMPLEMENTATION +#define KB_TEXT_SHAPE_STATIC +#define KB_TEXT_SHAPE_NO_CRT +#define KBTS_MEMSET hb_memset + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-align" +#pragma GCC diagnostic ignored "-Wunused-function" +#pragma GCC diagnostic ignored "-Wsign-compare" +#include "kb_text_shape.h" +#pragma GCC diagnostic pop + + +hb_kbts_face_data_t * +_hb_kbts_shaper_face_data_create (hb_face_t *face) +{ + hb_blob_t *blob = hb_face_reference_blob (face); + + unsigned int blob_length; + const char *blob_data = hb_blob_get_data (blob, &blob_length); + if (unlikely (!blob_length)) + { + DEBUG_MSG (KBTS, blob, "Empty blob"); + hb_blob_destroy (blob); + return nullptr; + } + + void *data = hb_malloc (blob_length); + if (likely (data)) + hb_memcpy (data, blob_data, blob_length); + + hb_blob_destroy (blob); + blob = nullptr; + + if (unlikely (!data)) + { + DEBUG_MSG (KBTS, face, "Failed to allocate memory for font data"); + return nullptr; + } + + kbts_font *kb_font = (kbts_font *) hb_calloc (1, sizeof (kbts_font)); + if (unlikely (!kb_font)) + { + hb_free (data); + return nullptr; + } + + size_t memory_size; + { + unsigned scratch_size = kbts_ReadFontHeader (kb_font, data, blob_length); + void *scratch = hb_malloc (scratch_size); + memory_size = kbts_ReadFontData (kb_font, scratch, scratch_size); + hb_free (scratch); + } + + void *memory = hb_malloc (memory_size); + if (unlikely (!kbts_PostReadFontInitialize (kb_font, memory, memory_size))) + { + DEBUG_MSG (KBTS, face, "kbts_PostReadFontInitialize failed"); + hb_free (memory); + hb_free (data); + hb_free (kb_font); + return nullptr; + } + + return (hb_kbts_face_data_t *) kb_font; +} + +void +_hb_kbts_shaper_face_data_destroy (hb_kbts_face_data_t *data) +{ + kbts_font *font = (kbts_font *) data; + + assert (kbts_FontIsValid (font)); + + hb_free (font->FileBase); + hb_free (font->GlyphLookupMatrix); + hb_free (font); +} + +hb_kbts_font_data_t * +_hb_kbts_shaper_font_data_create (hb_font_t *font) +{ + return (hb_kbts_font_data_t *) HB_SHAPER_DATA_SUCCEEDED; +} + +void +_hb_kbts_shaper_font_data_destroy (hb_kbts_font_data_t *data) +{ +} + +hb_bool_t +_hb_kbts_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; + kbts_font *kb_font = (kbts_font *) (const void *) face->data.kbts; + + kbts_direction kb_direction; + switch (buffer->props.direction) + { + case HB_DIRECTION_LTR: kb_direction = KBTS_DIRECTION_LTR; break; + case HB_DIRECTION_RTL: kb_direction = KBTS_DIRECTION_RTL; break; + case HB_DIRECTION_TTB: + case HB_DIRECTION_BTT: + DEBUG_MSG (KBTS, face, "Vertical direction is not supported"); + return false; + default: + case HB_DIRECTION_INVALID: + DEBUG_MSG (KBTS, face, "Invalid direction"); + return false; + } + + kbts_script kb_script = KBTS_SCRIPT_DONT_KNOW; + kbts_language kb_language = KBTS_LANGUAGE_DEFAULT; + { + hb_tag_t scripts[HB_OT_MAX_TAGS_PER_SCRIPT]; + hb_tag_t language; + unsigned int script_count = ARRAY_LENGTH (scripts); + unsigned int language_count = 1; + + hb_ot_tags_from_script_and_language (buffer->props.script, buffer->props.language, + &script_count, scripts, + &language_count, &language); + + for (unsigned int i = 0; i < script_count && scripts[i] != HB_TAG_NONE; ++i) + { + kb_script = kbts_ScriptTagToScript (hb_uint32_swap (scripts[i])); + if (kb_script != KBTS_SCRIPT_DONT_KNOW) + break; + } + + if (language_count) + kb_language = (kbts_language) hb_uint32_swap (language); + } + + hb_vector_t kb_glyphs; + if (unlikely (!kb_glyphs.resize_full (buffer->len, false, true))) + return false; + + for (size_t i = 0; i < buffer->len; ++i) + kb_glyphs.arrayZ[i] = kbts_CodepointToGlyph (kb_font, buffer->info[i].codepoint); + + if (num_features) + { + for (unsigned int i = 0; i < num_features; ++i) + { + hb_feature_t feature = features[i]; + for (unsigned int j = 0; j < buffer->len; ++j) + { + kbts_glyph *kb_glyph = &kb_glyphs.arrayZ[j]; + if (hb_in_range (j, feature.start, feature.end)) + { + if (!kb_glyph->Config) + kb_glyph->Config = (kbts_glyph_config *) hb_calloc (1, sizeof (kbts_glyph_config)); + kbts_glyph_config *config = kb_glyph->Config; + while (!kbts_GlyphConfigOverrideFeatureFromTag (config, hb_uint32_swap (feature.tag), + feature.value > 1, feature.value)) + { + config->FeatureOverrides = (kbts_feature_override *) hb_realloc (config->FeatureOverrides, + config->RequiredFeatureOverrideCapacity); + config->FeatureOverrideCapacity += 1; + } + } + } + } + } + + kbts_shape_state *kb_shape_state; + { + size_t kb_shape_state_size = kbts_SizeOfShapeState (kb_font); + void *kb_shape_state_buffer = hb_malloc (kb_shape_state_size); + if (unlikely (!kb_shape_state_buffer)) + { + DEBUG_MSG (KBTS, face, "Failed to allocate memory for shape state"); + return false; + } + kb_shape_state = kbts_PlaceShapeState (kb_shape_state_buffer, kb_shape_state_size); + } + kbts_shape_config kb_shape_config = kbts_ShapeConfig (kb_font, kb_script, kb_language); + uint32_t glyph_count = buffer->len; + uint32_t glyph_capacity = kb_glyphs.length; + while (kbts_Shape (kb_shape_state, &kb_shape_config, KBTS_DIRECTION_LTR, kb_direction, + kb_glyphs.arrayZ, &glyph_count, glyph_capacity)) + { + glyph_capacity = kb_shape_state->RequiredGlyphCapacity; + /* kb increases capacity by a fixed number only. We increase it by 50% to + * avoid O(n^2) behavior in case of expanding text. + * + * https://github.com/JimmyLefevre/kb/issues/32 + */ + glyph_capacity += glyph_capacity / 2; + if (unlikely (!kb_glyphs.resize_full (glyph_capacity, false, true))) + return false; + } + + hb_buffer_set_content_type (buffer, HB_BUFFER_CONTENT_TYPE_GLYPHS); + hb_buffer_set_length (buffer, glyph_count); + + hb_glyph_info_t *info = buffer->info; + hb_glyph_position_t *pos = buffer->pos; + + buffer->clear_positions (); + for (size_t i = 0; i < glyph_count; ++i) + { + kbts_glyph kb_glyph = kb_glyphs.arrayZ[i]; + info[i].codepoint = kb_glyph.Id; + info[i].cluster = 0; // FIXME + pos[i].x_advance = font->em_scalef_x (kb_glyph.AdvanceX); + pos[i].y_advance = font->em_scalef_y (kb_glyph.AdvanceY); + pos[i].x_offset = font->em_scalef_x (kb_glyph.OffsetX); + pos[i].y_offset = font->em_scalef_y (kb_glyph.OffsetY); + + if (kb_glyph.Config) + hb_free (kb_glyph.Config->FeatureOverrides); + } + + hb_free (kb_shape_state); + + buffer->clear_glyph_flags (); + buffer->unsafe_to_break (); + + return true; +} + +#endif \ No newline at end of file diff --git a/thirdparty/harfbuzz/src/hb-kern.hh b/thirdparty/harfbuzz/src/hb-kern.hh index 0462a0ea8ee..e1ebf90742d 100644 --- a/thirdparty/harfbuzz/src/hb-kern.hh +++ b/thirdparty/harfbuzz/src/hb-kern.hh @@ -70,7 +70,7 @@ struct hb_kern_machine_t continue; } - skippy_iter.reset (idx); + skippy_iter.reset_fast (idx); unsigned unsafe_to; if (!skippy_iter.next (&unsafe_to)) { diff --git a/thirdparty/harfbuzz/src/hb-limits.hh b/thirdparty/harfbuzz/src/hb-limits.hh index fbc7bbe764e..857e183737f 100644 --- a/thirdparty/harfbuzz/src/hb-limits.hh +++ b/thirdparty/harfbuzz/src/hb-limits.hh @@ -29,20 +29,20 @@ #ifndef HB_BUFFER_MAX_LEN_FACTOR -#define HB_BUFFER_MAX_LEN_FACTOR 64 +#define HB_BUFFER_MAX_LEN_FACTOR 256 #endif #ifndef HB_BUFFER_MAX_LEN_MIN -#define HB_BUFFER_MAX_LEN_MIN 16384 +#define HB_BUFFER_MAX_LEN_MIN 65536 #endif #ifndef HB_BUFFER_MAX_LEN_DEFAULT #define HB_BUFFER_MAX_LEN_DEFAULT 0x3FFFFFFF /* Shaping more than a billion chars? Let us know! */ #endif #ifndef HB_BUFFER_MAX_OPS_FACTOR -#define HB_BUFFER_MAX_OPS_FACTOR 1024 +#define HB_BUFFER_MAX_OPS_FACTOR 4096 #endif #ifndef HB_BUFFER_MAX_OPS_MIN -#define HB_BUFFER_MAX_OPS_MIN 16384 +#define HB_BUFFER_MAX_OPS_MIN 65536 #endif #ifndef HB_BUFFER_MAX_OPS_DEFAULT #define HB_BUFFER_MAX_OPS_DEFAULT 0x1FFFFFFF /* Shaping more than a billion operations? Let us know! */ diff --git a/thirdparty/harfbuzz/src/hb-machinery.hh b/thirdparty/harfbuzz/src/hb-machinery.hh index 4916765e8fd..869fdba0ffc 100644 --- a/thirdparty/harfbuzz/src/hb-machinery.hh +++ b/thirdparty/harfbuzz/src/hb-machinery.hh @@ -70,11 +70,18 @@ static inline Type& StructAtOffsetUnaligned(void *P, unsigned int offset) * Any extra arguments are forwarded to get_size, so for example * it can work with UnsizedArrayOf<> as well. */ template -static inline const Type& StructAfter(const TObject &X, Ts... args) -{ return StructAtOffset(&X, X.get_size(args...)); } +static inline auto StructAfter(const TObject &X, Ts... args) HB_AUTO_RETURN(( + StructAtOffset(&X, X.get_size(std::forward (args)...)) +)) +/* The is_const shenanigans is to avoid ambiguous overload with gcc-8. + * It disables this path when TObject is const. + * See: https://github.com/harfbuzz/harfbuzz/issues/5429 */ template -static inline Type& StructAfter(TObject &X, Ts... args) -{ return StructAtOffset(&X, X.get_size(args...)); } +static inline auto StructAfter(TObject &X, Ts... args) HB_AUTO_RETURN(( + sizeof(int[std::is_const::value ? -1 : +1]) > 0 ? + StructAtOffset(&X, X.get_size(std::forward (args)...)) + : *reinterpret_cast (0) +)) /* diff --git a/thirdparty/harfbuzz/src/hb-map.hh b/thirdparty/harfbuzz/src/hb-map.hh index 6c9fb7e6369..1520a9b3bec 100644 --- a/thirdparty/harfbuzz/src/hb-map.hh +++ b/thirdparty/harfbuzz/src/hb-map.hh @@ -47,11 +47,11 @@ struct hb_hashmap_t hb_hashmap_t () { init (); } ~hb_hashmap_t () { fini (); } - hb_hashmap_t (const hb_hashmap_t& o) : hb_hashmap_t () + void _copy (const hb_hashmap_t& o) { if (unlikely (!o.mask)) return; - if (item_t::is_trivial) + if (hb_is_trivially_copy_assignable (item_t)) { items = (item_t *) hb_malloc (sizeof (item_t) * (o.mask + 1)); if (unlikely (!items)) @@ -70,8 +70,16 @@ struct hb_hashmap_t alloc (o.population); hb_copy (o, *this); } + + hb_hashmap_t (const hb_hashmap_t& o) : hb_hashmap_t () { _copy (o); } + hb_hashmap_t& operator= (const hb_hashmap_t& o) + { + reset (); + if (!items) { _copy (o); return *this; } + alloc (o.population); hb_copy (o, *this); return *this; + } + hb_hashmap_t (hb_hashmap_t&& o) noexcept : hb_hashmap_t () { hb_swap (*this, o); } - hb_hashmap_t& operator= (const hb_hashmap_t& o) { reset (); alloc (o.population); hb_copy (o, *this); return *this; } hb_hashmap_t& operator= (hb_hashmap_t&& o) noexcept { hb_swap (*this, o); return *this; } hb_hashmap_t (std::initializer_list> lst) : hb_hashmap_t () @@ -130,10 +138,7 @@ struct hb_hashmap_t uint32_t total_hash () const { return (hash * 31u) + hb_hash (value); } - static constexpr bool is_trivial = hb_is_trivially_constructible(K) && - hb_is_trivially_destructible(K) && - hb_is_trivially_constructible(V) && - hb_is_trivially_destructible(V); + static constexpr bool is_trivially_constructible = (hb_is_trivially_constructible(K) && hb_is_trivially_constructible(V)); }; hb_object_header_t header; @@ -174,19 +179,19 @@ struct hb_hashmap_t if (likely (items)) { unsigned size = mask + 1; - if (!item_t::is_trivial) - for (unsigned i = 0; i < size; i++) - items[i].~item_t (); + for (unsigned i = 0; i < size; i++) + items[i].~item_t (); hb_free (items); items = nullptr; } population = occupancy = 0; } - void reset () + hb_hashmap_t& reset () { successful = true; clear (); + return *this; } bool in_error () const { return !successful; } @@ -197,7 +202,7 @@ struct hb_hashmap_t if (new_population != 0 && (new_population + new_population / 2) < mask) return true; - unsigned int power = hb_bit_storage (hb_max ((unsigned) population, new_population) * 2 + 8); + unsigned int power = hb_bit_storage (hb_max (hb_max ((unsigned) population, new_population) * 2, 4u)); unsigned int new_size = 1u << power; item_t *new_items = (item_t *) hb_malloc ((size_t) new_size * sizeof (item_t)); if (unlikely (!new_items)) @@ -205,7 +210,7 @@ struct hb_hashmap_t successful = false; return false; } - if (!item_t::is_trivial) + if (!item_t::is_trivially_constructible) for (auto &_ : hb_iter (new_items, new_size)) new (&_) item_t (); else @@ -231,9 +236,8 @@ struct hb_hashmap_t std::move (old_items[i].value)); } } - if (!item_t::is_trivial) - for (unsigned int i = 0; i < old_size; i++) - old_items[i].~item_t (); + for (unsigned int i = 0; i < old_size; i++) + old_items[i].~item_t (); hb_free (old_items); @@ -335,7 +339,13 @@ struct hb_hashmap_t bool has (const K &key, VV **vp = nullptr) const { if (!items) return false; - auto *item = fetch_item (key, hb_hash (key)); + return has_with_hash (key, hb_hash (key), vp); + } + template + bool has_with_hash (const K &key, uint32_t hash, VV **vp = nullptr) const + { + if (!items) return false; + auto *item = fetch_item (key, hash); if (item) { if (vp) *vp = std::addressof (item->value); @@ -481,10 +491,17 @@ struct hb_hashmap_t /* Sink interface. */ hb_hashmap_t& operator << (const hb_pair_t& v) { set (v.first, v.second); return *this; } + template ::value)> hb_hashmap_t& operator << (const hb_pair_t& v) { set (v.first, std::move (v.second)); return *this; } + template ::value)> hb_hashmap_t& operator << (const hb_pair_t& v) { set (std::move (v.first), v.second); return *this; } + template ::value && + !std::is_trivially_copyable::value)> hb_hashmap_t& operator << (const hb_pair_t& v) { set (std::move (v.first), std::move (v.second)); return *this; } diff --git a/thirdparty/harfbuzz/src/hb-number-parser.hh b/thirdparty/harfbuzz/src/hb-number-parser.hh index 1a9dbba6dd3..ec68c3a7281 100644 --- a/thirdparty/harfbuzz/src/hb-number-parser.hh +++ b/thirdparty/harfbuzz/src/hb-number-parser.hh @@ -31,7 +31,7 @@ #include "hb.hh" -#line 35 "hb-number-parser.hh" +#line 32 "hb-number-parser.hh" static const unsigned char _double_parser_trans_keys[] = { 0u, 0u, 43u, 57u, 46u, 57u, 48u, 57u, 43u, 57u, 48u, 57u, 48u, 101u, 48u, 57u, 46u, 101u, 0 @@ -135,12 +135,12 @@ strtod_rl (const char *p, const char **end_ptr /* IN/OUT */) int cs; -#line 139 "hb-number-parser.hh" +#line 132 "hb-number-parser.hh" { cs = double_parser_start; } -#line 144 "hb-number-parser.hh" +#line 135 "hb-number-parser.hh" { int _slen; int _trans; @@ -198,7 +198,7 @@ _resume: exp_overflow = true; } break; -#line 202 "hb-number-parser.hh" +#line 187 "hb-number-parser.hh" } _again: diff --git a/thirdparty/harfbuzz/src/hb-open-type.hh b/thirdparty/harfbuzz/src/hb-open-type.hh index 08b0fe86c72..ed8e0b4e786 100644 --- a/thirdparty/harfbuzz/src/hb-open-type.hh +++ b/thirdparty/harfbuzz/src/hb-open-type.hh @@ -82,6 +82,7 @@ struct NumType NumType operator ++ (int) { NumType c (*this); ++*this; return c; } NumType operator -- (int) { NumType c (*this); --*this; return c; } + uint32_t hash () const { return hb_array ((const char *) &v, sizeof (v)).hash (); } HB_INTERNAL static int cmp (const NumType *a, const NumType *b) { return b->cmp (*a); } HB_INTERNAL static int cmp (const void *a, const void *b) @@ -1498,8 +1499,8 @@ struct TupleValues VALUE_RUN_COUNT_MASK = 0x3F }; - static unsigned compile (hb_array_t values, /* IN */ - hb_array_t encoded_bytes /* OUT */) + static unsigned compile_unsafe (hb_array_t values, /* IN */ + unsigned char *encoded_bytes /* OUT */) { unsigned num_values = values.length; unsigned encoded_len = 0; @@ -1508,24 +1509,23 @@ struct TupleValues { int val = values.arrayZ[i]; if (val == 0) - encoded_len += encode_value_run_as_zeroes (i, encoded_bytes.sub_array (encoded_len), values); - else if (val >= -128 && val <= 127) - encoded_len += encode_value_run_as_bytes (i, encoded_bytes.sub_array (encoded_len), values); - else if (val >= -32768 && val <= 32767) - encoded_len += encode_value_run_as_words (i, encoded_bytes.sub_array (encoded_len), values); + encoded_len += encode_value_run_as_zeroes (i, encoded_bytes + encoded_len, values); + else if ((int8_t) val == val) + encoded_len += encode_value_run_as_bytes (i, encoded_bytes + encoded_len, values); + else if ((int16_t) val == val) + encoded_len += encode_value_run_as_words (i, encoded_bytes + encoded_len, values); else - encoded_len += encode_value_run_as_longs (i, encoded_bytes.sub_array (encoded_len), values); + encoded_len += encode_value_run_as_longs (i, encoded_bytes + encoded_len, values); } return encoded_len; } static unsigned encode_value_run_as_zeroes (unsigned& i, - hb_array_t encoded_bytes, + unsigned char *it, hb_array_t values) { unsigned num_values = values.length; unsigned run_length = 0; - auto it = encoded_bytes.iter (); unsigned encoded_len = 0; while (i < num_values && values.arrayZ[i] == 0) { @@ -1549,7 +1549,7 @@ struct TupleValues } static unsigned encode_value_run_as_bytes (unsigned &i, - hb_array_t encoded_bytes, + unsigned char *it, hb_array_t values) { unsigned start = i; @@ -1557,7 +1557,7 @@ struct TupleValues while (i < num_values) { int val = values.arrayZ[i]; - if (val > 127 || val < -128) + if ((int8_t) val != val) break; /* from fonttools: if there're 2 or more zeros in a sequence, @@ -1570,7 +1570,6 @@ struct TupleValues unsigned run_length = i - start; unsigned encoded_len = 0; - auto it = encoded_bytes.iter (); while (run_length >= 64) { @@ -1578,10 +1577,9 @@ struct TupleValues encoded_len++; for (unsigned j = 0; j < 64; j++) - { - *it++ = static_cast (values.arrayZ[start + j]); - encoded_len++; - } + it[j] = static_cast (values.arrayZ[start + j]); + it += 64; + encoded_len += 64; start += 64; run_length -= 64; @@ -1592,18 +1590,16 @@ struct TupleValues *it++ = (VALUES_ARE_BYTES | (run_length - 1)); encoded_len++; - while (start < i) - { - *it++ = static_cast (values.arrayZ[start++]); - encoded_len++; - } + for (unsigned j = 0; j < run_length; j++) + it[j] = static_cast (values.arrayZ[start + j]); + encoded_len += run_length; } return encoded_len; } static unsigned encode_value_run_as_words (unsigned &i, - hb_array_t encoded_bytes, + unsigned char *it, hb_array_t values) { unsigned start = i; @@ -1612,22 +1608,24 @@ struct TupleValues { int val = values.arrayZ[i]; - /* start a new run for a single zero value*/ + if ((int16_t) val != val) + break; + + /* start a new run for a single zero value. */ if (val == 0) break; - /* from fonttools: continue word-encoded run if there's only one + /* From fonttools: continue word-encoded run if there's only one * single value in the range [-128, 127] because it is more compact. * Only start a new run when there're 2 continuous such values. */ - if (val >= -128 && val <= 127 && + if ((int8_t) val == val && i + 1 < num_values && - values.arrayZ[i+1] >= -128 && values.arrayZ[i+1] <= 127) + (int8_t) values.arrayZ[i+1] == values.arrayZ[i+1]) break; i++; } unsigned run_length = i - start; - auto it = encoded_bytes.iter (); unsigned encoded_len = 0; while (run_length >= 64) { @@ -1664,7 +1662,7 @@ struct TupleValues } static unsigned encode_value_run_as_longs (unsigned &i, - hb_array_t encoded_bytes, + unsigned char *it, hb_array_t values) { unsigned start = i; @@ -1673,14 +1671,13 @@ struct TupleValues { int val = values.arrayZ[i]; - if (val >= -32768 && val <= 32767) + if ((int16_t) val == val) break; i++; } unsigned run_length = i - start; - auto it = encoded_bytes.iter (); unsigned encoded_len = 0; while (run_length >= 64) { @@ -1738,7 +1735,7 @@ struct TupleValues unsigned run_count = (control & VALUE_RUN_COUNT_MASK) + 1; if (consume_all) { - if (unlikely (!values.resize (values.length + run_count, false))) + if (unlikely (!values.resize_dirty (values.length + run_count))) return false; } unsigned stop = i + run_count; diff --git a/thirdparty/harfbuzz/src/hb-ot-cff-common.hh b/thirdparty/harfbuzz/src/hb-ot-cff-common.hh index b49c0be5171..4308a73442b 100644 --- a/thirdparty/harfbuzz/src/hb-ot-cff-common.hh +++ b/thirdparty/harfbuzz/src/hb-ot-cff-common.hh @@ -79,7 +79,7 @@ struct Dict : UnsizedByteStr { TRACE_SERIALIZE (this); for (unsigned int i = 0; i < dictval.get_count (); i++) - if (unlikely (!opszr.serialize (c, dictval[i], std::forward (ds)...))) + if (unlikely (!opszr.serialize (c, dictval[i], ds...))) return_trace (false); return_trace (true); diff --git a/thirdparty/harfbuzz/src/hb-ot-cff1-std-str.hh b/thirdparty/harfbuzz/src/hb-ot-cff1-std-str.hh index 65d56ae18b5..bf56abb975c 100644 --- a/thirdparty/harfbuzz/src/hb-ot-cff1-std-str.hh +++ b/thirdparty/harfbuzz/src/hb-ot-cff1-std-str.hh @@ -30,396 +30,396 @@ #include "hb.hh" #endif -_S(".notdef") -_S("space") -_S("exclam") -_S("quotedbl") -_S("numbersign") -_S("dollar") -_S("percent") -_S("ampersand") -_S("quoteright") -_S("parenleft") -_S("parenright") -_S("asterisk") -_S("plus") -_S("comma") -_S("hyphen") -_S("period") -_S("slash") -_S("zero") -_S("one") -_S("two") -_S("three") -_S("four") -_S("five") -_S("six") -_S("seven") -_S("eight") -_S("nine") -_S("colon") -_S("semicolon") -_S("less") -_S("equal") -_S("greater") -_S("question") -_S("at") -_S("A") -_S("B") -_S("C") -_S("D") -_S("E") -_S("F") -_S("G") -_S("H") -_S("I") -_S("J") -_S("K") -_S("L") -_S("M") -_S("N") -_S("O") -_S("P") -_S("Q") -_S("R") -_S("S") -_S("T") -_S("U") -_S("V") -_S("W") -_S("X") -_S("Y") -_S("Z") -_S("bracketleft") -_S("backslash") -_S("bracketright") -_S("asciicircum") -_S("underscore") -_S("quoteleft") -_S("a") -_S("b") -_S("c") -_S("d") -_S("e") -_S("f") -_S("g") -_S("h") -_S("i") -_S("j") -_S("k") -_S("l") -_S("m") -_S("n") -_S("o") -_S("p") -_S("q") -_S("r") -_S("s") -_S("t") -_S("u") -_S("v") -_S("w") -_S("x") -_S("y") -_S("z") -_S("braceleft") -_S("bar") -_S("braceright") -_S("asciitilde") -_S("exclamdown") -_S("cent") -_S("sterling") -_S("fraction") -_S("yen") -_S("florin") -_S("section") -_S("currency") -_S("quotesingle") -_S("quotedblleft") -_S("guillemotleft") -_S("guilsinglleft") -_S("guilsinglright") -_S("fi") -_S("fl") -_S("endash") -_S("dagger") -_S("daggerdbl") -_S("periodcentered") -_S("paragraph") -_S("bullet") -_S("quotesinglbase") -_S("quotedblbase") -_S("quotedblright") -_S("guillemotright") -_S("ellipsis") -_S("perthousand") -_S("questiondown") -_S("grave") -_S("acute") -_S("circumflex") -_S("tilde") -_S("macron") -_S("breve") -_S("dotaccent") -_S("dieresis") -_S("ring") -_S("cedilla") -_S("hungarumlaut") -_S("ogonek") -_S("caron") -_S("emdash") -_S("AE") -_S("ordfeminine") -_S("Lslash") -_S("Oslash") -_S("OE") -_S("ordmasculine") -_S("ae") -_S("dotlessi") -_S("lslash") -_S("oslash") -_S("oe") -_S("germandbls") -_S("onesuperior") -_S("logicalnot") -_S("mu") -_S("trademark") -_S("Eth") -_S("onehalf") -_S("plusminus") -_S("Thorn") -_S("onequarter") -_S("divide") -_S("brokenbar") -_S("degree") -_S("thorn") -_S("threequarters") -_S("twosuperior") -_S("registered") -_S("minus") -_S("eth") -_S("multiply") -_S("threesuperior") -_S("copyright") -_S("Aacute") -_S("Acircumflex") -_S("Adieresis") -_S("Agrave") -_S("Aring") -_S("Atilde") -_S("Ccedilla") -_S("Eacute") -_S("Ecircumflex") -_S("Edieresis") -_S("Egrave") -_S("Iacute") -_S("Icircumflex") -_S("Idieresis") -_S("Igrave") -_S("Ntilde") -_S("Oacute") -_S("Ocircumflex") -_S("Odieresis") -_S("Ograve") -_S("Otilde") -_S("Scaron") -_S("Uacute") -_S("Ucircumflex") -_S("Udieresis") -_S("Ugrave") -_S("Yacute") -_S("Ydieresis") -_S("Zcaron") -_S("aacute") -_S("acircumflex") -_S("adieresis") -_S("agrave") -_S("aring") -_S("atilde") -_S("ccedilla") -_S("eacute") -_S("ecircumflex") -_S("edieresis") -_S("egrave") -_S("iacute") -_S("icircumflex") -_S("idieresis") -_S("igrave") -_S("ntilde") -_S("oacute") -_S("ocircumflex") -_S("odieresis") -_S("ograve") -_S("otilde") -_S("scaron") -_S("uacute") -_S("ucircumflex") -_S("udieresis") -_S("ugrave") -_S("yacute") -_S("ydieresis") -_S("zcaron") -_S("exclamsmall") -_S("Hungarumlautsmall") -_S("dollaroldstyle") -_S("dollarsuperior") -_S("ampersandsmall") -_S("Acutesmall") -_S("parenleftsuperior") -_S("parenrightsuperior") -_S("twodotenleader") -_S("onedotenleader") -_S("zerooldstyle") -_S("oneoldstyle") -_S("twooldstyle") -_S("threeoldstyle") -_S("fouroldstyle") -_S("fiveoldstyle") -_S("sixoldstyle") -_S("sevenoldstyle") -_S("eightoldstyle") -_S("nineoldstyle") -_S("commasuperior") -_S("threequartersemdash") -_S("periodsuperior") -_S("questionsmall") -_S("asuperior") -_S("bsuperior") -_S("centsuperior") -_S("dsuperior") -_S("esuperior") -_S("isuperior") -_S("lsuperior") -_S("msuperior") -_S("nsuperior") -_S("osuperior") -_S("rsuperior") -_S("ssuperior") -_S("tsuperior") -_S("ff") -_S("ffi") -_S("ffl") -_S("parenleftinferior") -_S("parenrightinferior") -_S("Circumflexsmall") -_S("hyphensuperior") -_S("Gravesmall") -_S("Asmall") -_S("Bsmall") -_S("Csmall") -_S("Dsmall") -_S("Esmall") -_S("Fsmall") -_S("Gsmall") -_S("Hsmall") -_S("Ismall") -_S("Jsmall") -_S("Ksmall") -_S("Lsmall") -_S("Msmall") -_S("Nsmall") -_S("Osmall") -_S("Psmall") -_S("Qsmall") -_S("Rsmall") -_S("Ssmall") -_S("Tsmall") -_S("Usmall") -_S("Vsmall") -_S("Wsmall") -_S("Xsmall") -_S("Ysmall") -_S("Zsmall") -_S("colonmonetary") -_S("onefitted") -_S("rupiah") -_S("Tildesmall") -_S("exclamdownsmall") -_S("centoldstyle") -_S("Lslashsmall") -_S("Scaronsmall") -_S("Zcaronsmall") -_S("Dieresissmall") -_S("Brevesmall") -_S("Caronsmall") -_S("Dotaccentsmall") -_S("Macronsmall") -_S("figuredash") -_S("hypheninferior") -_S("Ogoneksmall") -_S("Ringsmall") -_S("Cedillasmall") -_S("questiondownsmall") -_S("oneeighth") -_S("threeeighths") -_S("fiveeighths") -_S("seveneighths") -_S("onethird") -_S("twothirds") -_S("zerosuperior") -_S("foursuperior") -_S("fivesuperior") -_S("sixsuperior") -_S("sevensuperior") -_S("eightsuperior") -_S("ninesuperior") -_S("zeroinferior") -_S("oneinferior") -_S("twoinferior") -_S("threeinferior") -_S("fourinferior") -_S("fiveinferior") -_S("sixinferior") -_S("seveninferior") -_S("eightinferior") -_S("nineinferior") -_S("centinferior") -_S("dollarinferior") -_S("periodinferior") -_S("commainferior") -_S("Agravesmall") -_S("Aacutesmall") -_S("Acircumflexsmall") -_S("Atildesmall") -_S("Adieresissmall") -_S("Aringsmall") -_S("AEsmall") -_S("Ccedillasmall") -_S("Egravesmall") -_S("Eacutesmall") -_S("Ecircumflexsmall") -_S("Edieresissmall") -_S("Igravesmall") -_S("Iacutesmall") -_S("Icircumflexsmall") -_S("Idieresissmall") -_S("Ethsmall") -_S("Ntildesmall") -_S("Ogravesmall") -_S("Oacutesmall") -_S("Ocircumflexsmall") -_S("Otildesmall") -_S("Odieresissmall") -_S("OEsmall") -_S("Oslashsmall") -_S("Ugravesmall") -_S("Uacutesmall") -_S("Ucircumflexsmall") -_S("Udieresissmall") -_S("Yacutesmall") -_S("Thornsmall") -_S("Ydieresissmall") -_S("001.000") -_S("001.001") -_S("001.002") -_S("001.003") -_S("Black") -_S("Bold") -_S("Book") -_S("Light") -_S("Medium") -_S("Regular") -_S("Roman") -_S("Semibold") +HB_STR(".notdef") +HB_STR("space") +HB_STR("exclam") +HB_STR("quotedbl") +HB_STR("numbersign") +HB_STR("dollar") +HB_STR("percent") +HB_STR("ampersand") +HB_STR("quoteright") +HB_STR("parenleft") +HB_STR("parenright") +HB_STR("asterisk") +HB_STR("plus") +HB_STR("comma") +HB_STR("hyphen") +HB_STR("period") +HB_STR("slash") +HB_STR("zero") +HB_STR("one") +HB_STR("two") +HB_STR("three") +HB_STR("four") +HB_STR("five") +HB_STR("six") +HB_STR("seven") +HB_STR("eight") +HB_STR("nine") +HB_STR("colon") +HB_STR("semicolon") +HB_STR("less") +HB_STR("equal") +HB_STR("greater") +HB_STR("question") +HB_STR("at") +HB_STR("A") +HB_STR("B") +HB_STR("C") +HB_STR("D") +HB_STR("E") +HB_STR("F") +HB_STR("G") +HB_STR("H") +HB_STR("I") +HB_STR("J") +HB_STR("K") +HB_STR("L") +HB_STR("M") +HB_STR("N") +HB_STR("O") +HB_STR("P") +HB_STR("Q") +HB_STR("R") +HB_STR("S") +HB_STR("T") +HB_STR("U") +HB_STR("V") +HB_STR("W") +HB_STR("X") +HB_STR("Y") +HB_STR("Z") +HB_STR("bracketleft") +HB_STR("backslash") +HB_STR("bracketright") +HB_STR("asciicircum") +HB_STR("underscore") +HB_STR("quoteleft") +HB_STR("a") +HB_STR("b") +HB_STR("c") +HB_STR("d") +HB_STR("e") +HB_STR("f") +HB_STR("g") +HB_STR("h") +HB_STR("i") +HB_STR("j") +HB_STR("k") +HB_STR("l") +HB_STR("m") +HB_STR("n") +HB_STR("o") +HB_STR("p") +HB_STR("q") +HB_STR("r") +HB_STR("s") +HB_STR("t") +HB_STR("u") +HB_STR("v") +HB_STR("w") +HB_STR("x") +HB_STR("y") +HB_STR("z") +HB_STR("braceleft") +HB_STR("bar") +HB_STR("braceright") +HB_STR("asciitilde") +HB_STR("exclamdown") +HB_STR("cent") +HB_STR("sterling") +HB_STR("fraction") +HB_STR("yen") +HB_STR("florin") +HB_STR("section") +HB_STR("currency") +HB_STR("quotesingle") +HB_STR("quotedblleft") +HB_STR("guillemotleft") +HB_STR("guilsinglleft") +HB_STR("guilsinglright") +HB_STR("fi") +HB_STR("fl") +HB_STR("endash") +HB_STR("dagger") +HB_STR("daggerdbl") +HB_STR("periodcentered") +HB_STR("paragraph") +HB_STR("bullet") +HB_STR("quotesinglbase") +HB_STR("quotedblbase") +HB_STR("quotedblright") +HB_STR("guillemotright") +HB_STR("ellipsis") +HB_STR("perthousand") +HB_STR("questiondown") +HB_STR("grave") +HB_STR("acute") +HB_STR("circumflex") +HB_STR("tilde") +HB_STR("macron") +HB_STR("breve") +HB_STR("dotaccent") +HB_STR("dieresis") +HB_STR("ring") +HB_STR("cedilla") +HB_STR("hungarumlaut") +HB_STR("ogonek") +HB_STR("caron") +HB_STR("emdash") +HB_STR("AE") +HB_STR("ordfeminine") +HB_STR("Lslash") +HB_STR("Oslash") +HB_STR("OE") +HB_STR("ordmasculine") +HB_STR("ae") +HB_STR("dotlessi") +HB_STR("lslash") +HB_STR("oslash") +HB_STR("oe") +HB_STR("germandbls") +HB_STR("onesuperior") +HB_STR("logicalnot") +HB_STR("mu") +HB_STR("trademark") +HB_STR("Eth") +HB_STR("onehalf") +HB_STR("plusminus") +HB_STR("Thorn") +HB_STR("onequarter") +HB_STR("divide") +HB_STR("brokenbar") +HB_STR("degree") +HB_STR("thorn") +HB_STR("threequarters") +HB_STR("twosuperior") +HB_STR("registered") +HB_STR("minus") +HB_STR("eth") +HB_STR("multiply") +HB_STR("threesuperior") +HB_STR("copyright") +HB_STR("Aacute") +HB_STR("Acircumflex") +HB_STR("Adieresis") +HB_STR("Agrave") +HB_STR("Aring") +HB_STR("Atilde") +HB_STR("Ccedilla") +HB_STR("Eacute") +HB_STR("Ecircumflex") +HB_STR("Edieresis") +HB_STR("Egrave") +HB_STR("Iacute") +HB_STR("Icircumflex") +HB_STR("Idieresis") +HB_STR("Igrave") +HB_STR("Ntilde") +HB_STR("Oacute") +HB_STR("Ocircumflex") +HB_STR("Odieresis") +HB_STR("Ograve") +HB_STR("Otilde") +HB_STR("Scaron") +HB_STR("Uacute") +HB_STR("Ucircumflex") +HB_STR("Udieresis") +HB_STR("Ugrave") +HB_STR("Yacute") +HB_STR("Ydieresis") +HB_STR("Zcaron") +HB_STR("aacute") +HB_STR("acircumflex") +HB_STR("adieresis") +HB_STR("agrave") +HB_STR("aring") +HB_STR("atilde") +HB_STR("ccedilla") +HB_STR("eacute") +HB_STR("ecircumflex") +HB_STR("edieresis") +HB_STR("egrave") +HB_STR("iacute") +HB_STR("icircumflex") +HB_STR("idieresis") +HB_STR("igrave") +HB_STR("ntilde") +HB_STR("oacute") +HB_STR("ocircumflex") +HB_STR("odieresis") +HB_STR("ograve") +HB_STR("otilde") +HB_STR("scaron") +HB_STR("uacute") +HB_STR("ucircumflex") +HB_STR("udieresis") +HB_STR("ugrave") +HB_STR("yacute") +HB_STR("ydieresis") +HB_STR("zcaron") +HB_STR("exclamsmall") +HB_STR("Hungarumlautsmall") +HB_STR("dollaroldstyle") +HB_STR("dollarsuperior") +HB_STR("ampersandsmall") +HB_STR("Acutesmall") +HB_STR("parenleftsuperior") +HB_STR("parenrightsuperior") +HB_STR("twodotenleader") +HB_STR("onedotenleader") +HB_STR("zerooldstyle") +HB_STR("oneoldstyle") +HB_STR("twooldstyle") +HB_STR("threeoldstyle") +HB_STR("fouroldstyle") +HB_STR("fiveoldstyle") +HB_STR("sixoldstyle") +HB_STR("sevenoldstyle") +HB_STR("eightoldstyle") +HB_STR("nineoldstyle") +HB_STR("commasuperior") +HB_STR("threequartersemdash") +HB_STR("periodsuperior") +HB_STR("questionsmall") +HB_STR("asuperior") +HB_STR("bsuperior") +HB_STR("centsuperior") +HB_STR("dsuperior") +HB_STR("esuperior") +HB_STR("isuperior") +HB_STR("lsuperior") +HB_STR("msuperior") +HB_STR("nsuperior") +HB_STR("osuperior") +HB_STR("rsuperior") +HB_STR("ssuperior") +HB_STR("tsuperior") +HB_STR("ff") +HB_STR("ffi") +HB_STR("ffl") +HB_STR("parenleftinferior") +HB_STR("parenrightinferior") +HB_STR("Circumflexsmall") +HB_STR("hyphensuperior") +HB_STR("Gravesmall") +HB_STR("Asmall") +HB_STR("Bsmall") +HB_STR("Csmall") +HB_STR("Dsmall") +HB_STR("Esmall") +HB_STR("Fsmall") +HB_STR("Gsmall") +HB_STR("Hsmall") +HB_STR("Ismall") +HB_STR("Jsmall") +HB_STR("Ksmall") +HB_STR("Lsmall") +HB_STR("Msmall") +HB_STR("Nsmall") +HB_STR("Osmall") +HB_STR("Psmall") +HB_STR("Qsmall") +HB_STR("Rsmall") +HB_STR("Ssmall") +HB_STR("Tsmall") +HB_STR("Usmall") +HB_STR("Vsmall") +HB_STR("Wsmall") +HB_STR("Xsmall") +HB_STR("Ysmall") +HB_STR("Zsmall") +HB_STR("colonmonetary") +HB_STR("onefitted") +HB_STR("rupiah") +HB_STR("Tildesmall") +HB_STR("exclamdownsmall") +HB_STR("centoldstyle") +HB_STR("Lslashsmall") +HB_STR("Scaronsmall") +HB_STR("Zcaronsmall") +HB_STR("Dieresissmall") +HB_STR("Brevesmall") +HB_STR("Caronsmall") +HB_STR("Dotaccentsmall") +HB_STR("Macronsmall") +HB_STR("figuredash") +HB_STR("hypheninferior") +HB_STR("Ogoneksmall") +HB_STR("Ringsmall") +HB_STR("Cedillasmall") +HB_STR("questiondownsmall") +HB_STR("oneeighth") +HB_STR("threeeighths") +HB_STR("fiveeighths") +HB_STR("seveneighths") +HB_STR("onethird") +HB_STR("twothirds") +HB_STR("zerosuperior") +HB_STR("foursuperior") +HB_STR("fivesuperior") +HB_STR("sixsuperior") +HB_STR("sevensuperior") +HB_STR("eightsuperior") +HB_STR("ninesuperior") +HB_STR("zeroinferior") +HB_STR("oneinferior") +HB_STR("twoinferior") +HB_STR("threeinferior") +HB_STR("fourinferior") +HB_STR("fiveinferior") +HB_STR("sixinferior") +HB_STR("seveninferior") +HB_STR("eightinferior") +HB_STR("nineinferior") +HB_STR("centinferior") +HB_STR("dollarinferior") +HB_STR("periodinferior") +HB_STR("commainferior") +HB_STR("Agravesmall") +HB_STR("Aacutesmall") +HB_STR("Acircumflexsmall") +HB_STR("Atildesmall") +HB_STR("Adieresissmall") +HB_STR("Aringsmall") +HB_STR("AEsmall") +HB_STR("Ccedillasmall") +HB_STR("Egravesmall") +HB_STR("Eacutesmall") +HB_STR("Ecircumflexsmall") +HB_STR("Edieresissmall") +HB_STR("Igravesmall") +HB_STR("Iacutesmall") +HB_STR("Icircumflexsmall") +HB_STR("Idieresissmall") +HB_STR("Ethsmall") +HB_STR("Ntildesmall") +HB_STR("Ogravesmall") +HB_STR("Oacutesmall") +HB_STR("Ocircumflexsmall") +HB_STR("Otildesmall") +HB_STR("Odieresissmall") +HB_STR("OEsmall") +HB_STR("Oslashsmall") +HB_STR("Ugravesmall") +HB_STR("Uacutesmall") +HB_STR("Ucircumflexsmall") +HB_STR("Udieresissmall") +HB_STR("Yacutesmall") +HB_STR("Thornsmall") +HB_STR("Ydieresissmall") +HB_STR("001.000") +HB_STR("001.001") +HB_STR("001.002") +HB_STR("001.003") +HB_STR("Black") +HB_STR("Bold") +HB_STR("Book") +HB_STR("Light") +HB_STR("Medium") +HB_STR("Regular") +HB_STR("Roman") +HB_STR("Semibold") #endif /* HB_OT_CFF1_STD_STR_HH */ diff --git a/thirdparty/harfbuzz/src/hb-ot-cff1-table.hh b/thirdparty/harfbuzz/src/hb-ot-cff1-table.hh index f6f9ed2c1f7..66c375b2c6a 100644 --- a/thirdparty/harfbuzz/src/hb-ot-cff1-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-cff1-table.hh @@ -326,7 +326,7 @@ struct Charset0 void collect_glyph_to_sid_map (glyph_to_sid_map_t *mapping, unsigned int num_glyphs) const { - mapping->resize (num_glyphs, false); + mapping->resize_dirty (num_glyphs); for (hb_codepoint_t gid = 1; gid < num_glyphs; gid++) mapping->arrayZ[gid] = {sids[gid - 1], gid}; } @@ -426,7 +426,7 @@ struct Charset1_2 { void collect_glyph_to_sid_map (glyph_to_sid_map_t *mapping, unsigned int num_glyphs) const { - mapping->resize (num_glyphs, false); + mapping->resize_dirty (num_glyphs); hb_codepoint_t gid = 1; if (gid >= num_glyphs) return; diff --git a/thirdparty/harfbuzz/src/hb-ot-font.cc b/thirdparty/harfbuzz/src/hb-ot-font.cc index e1a0c1d2fe6..76c4bf28d9b 100644 --- a/thirdparty/harfbuzz/src/hb-ot-font.cc +++ b/thirdparty/harfbuzz/src/hb-ot-font.cc @@ -466,6 +466,11 @@ hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data, { const auto &glyf = *ot_face->glyf; auto *scratch = glyf.acquire_scratch (); + if (unlikely (!scratch)) + { + ot_font->h.release_advance_cache (advance_cache); + goto fallback; + } OT::hb_scalar_cache_t *gvar_cache = ot_font->draw.acquire_gvar_cache (gvar); for (unsigned int i = 0; i < count; i++) @@ -516,8 +521,7 @@ hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data, { hb_font_extents_t font_extents; font->get_h_extents_with_fallback (&font_extents); - hb_position_t advance = font_extents.ascender - font_extents.descender; - advance = font->em_scale_y (- (int) advance); + hb_position_t advance = font_extents.descender - font_extents.ascender; for (unsigned int i = 0; i < count; i++) { *first_advance = advance; @@ -587,6 +591,11 @@ hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data, { const auto &glyf = *ot_face->glyf; auto *scratch = glyf.acquire_scratch (); + if (unlikely (!scratch)) + { + ot_font->v.release_advance_cache (advance_cache); + goto fallback; + } OT::hb_scalar_cache_t *gvar_cache = ot_font->draw.acquire_gvar_cache (gvar); for (unsigned int i = 0; i < count; i++) @@ -665,7 +674,7 @@ hb_ot_get_glyph_v_origins (hb_font_t *font, hb_position_t origin; unsigned cv; if (origin_cache->get (*first_glyph, &cv)) - origin = font->y_scale < 0 ? -cv : cv; + origin = font->y_scale < 0 ? -static_cast(cv) : static_cast(cv); else { origin = font->em_scalef_y (VORG.get_y_origin (*first_glyph)); @@ -689,7 +698,7 @@ hb_ot_get_glyph_v_origins (hb_font_t *font, hb_position_t origin; unsigned cv; if (origin_cache->get (*first_glyph, &cv)) - origin = font->y_scale < 0 ? -cv : cv; + origin = font->y_scale < 0 ? -static_cast(cv) : static_cast(cv); else { origin = font->em_scalef_y (VORG.get_y_origin (*first_glyph) + @@ -718,6 +727,11 @@ hb_ot_get_glyph_v_origins (hb_font_t *font, if (origin_cache && vmtx.has_data() && glyf.has_data ()) { auto *scratch = glyf.acquire_scratch (); + if (unlikely (!scratch)) + { + ot_font->v_origin.release_origin_cache (origin_cache); + return false; + } OT::hb_scalar_cache_t *gvar_cache = font->has_nonzero_coords ? ot_font->draw.acquire_gvar_cache (*ot_face->gvar) : nullptr; @@ -727,7 +741,7 @@ hb_ot_get_glyph_v_origins (hb_font_t *font, hb_position_t origin; unsigned cv; if (origin_cache->get (*first_glyph, &cv)) - origin = font->y_scale < 0 ? -cv : cv; + origin = font->y_scale < 0 ? -static_cast(cv) : static_cast(cv); else { origin = font->em_scalef_y (glyf.get_v_origin_with_var_unscaled (*first_glyph, font, *scratch, gvar_cache)); @@ -761,7 +775,7 @@ hb_ot_get_glyph_v_origins (hb_font_t *font, unsigned cv; if (origin_cache->get (*first_glyph, &cv)) - origin = font->y_scale < 0 ? -cv : cv; + origin = font->y_scale < 0 ? -static_cast(cv) : static_cast(cv); else { hb_glyph_extents_t extents = {0}; diff --git a/thirdparty/harfbuzz/src/hb-ot-hmtx-table.hh b/thirdparty/harfbuzz/src/hb-ot-hmtx-table.hh index 43a2d9cf76a..99ea3804263 100644 --- a/thirdparty/harfbuzz/src/hb-ot-hmtx-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-hmtx-table.hh @@ -371,9 +371,9 @@ struct hmtxvmtx hb_scalar_cache_t *store_cache = nullptr) const { unsigned int advance = get_advance_without_var_unscaled (glyph); - return advance + roundf (var_table->get_advance_delta_unscaled (glyph, + return hb_max(0.0f, advance + roundf (var_table->get_advance_delta_unscaled (glyph, font->coords, font->num_coords, - store_cache)); + store_cache))); } #endif diff --git a/thirdparty/harfbuzz/src/hb-ot-kern-table.hh b/thirdparty/harfbuzz/src/hb-ot-kern-table.hh index 33865450125..4de0f165ff9 100644 --- a/thirdparty/harfbuzz/src/hb-ot-kern-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-kern-table.hh @@ -92,9 +92,10 @@ struct KernSubTableFormat3 { set_t set; if (likely (glyphCount)) - set.add_range (0, glyphCount - 1); - left_set.union_ (set); - right_set.union_ (set); + { + left_set.add_range (0, num_glyphs - 1); + right_set.add_range (0, num_glyphs - 1); + } } protected: diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-common.hh b/thirdparty/harfbuzz/src/hb-ot-layout-common.hh index 06c3c0ee976..b4ae21baeb9 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout-common.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout-common.hh @@ -141,6 +141,7 @@ struct hb_subset_layout_context_t : const hb_map_t *lookup_index_map; const hb_hashmap_t> *script_langsys_map; const hb_map_t *feature_index_map; + const hb_map_t *feature_map_w_duplicates; const hb_hashmap_t *feature_substitutes_map; hb_hashmap_t> *feature_record_cond_idx_map; const hb_set_t *catch_all_record_feature_idxes; @@ -165,6 +166,7 @@ struct hb_subset_layout_context_t : lookup_index_map = &c_->plan->gsub_lookups; script_langsys_map = &c_->plan->gsub_langsys; feature_index_map = &c_->plan->gsub_features; + feature_map_w_duplicates = &c_->plan->gsub_features_w_duplicates; feature_substitutes_map = &c_->plan->gsub_feature_substitutes_map; feature_record_cond_idx_map = c_->plan->user_axes_location.is_empty () ? nullptr : &c_->plan->gsub_feature_record_cond_idx_map; catch_all_record_feature_idxes = &c_->plan->gsub_old_features; @@ -175,6 +177,7 @@ struct hb_subset_layout_context_t : lookup_index_map = &c_->plan->gpos_lookups; script_langsys_map = &c_->plan->gpos_langsys; feature_index_map = &c_->plan->gpos_features; + feature_map_w_duplicates = &c_->plan->gpos_features_w_duplicates; feature_substitutes_map = &c_->plan->gpos_feature_substitutes_map; feature_record_cond_idx_map = c_->plan->user_axes_location.is_empty () ? nullptr : &c_->plan->gpos_feature_record_cond_idx_map; catch_all_record_feature_idxes = &c_->plan->gpos_old_features; @@ -1082,15 +1085,15 @@ struct LangSys if (unlikely (!c->serializer->extend_min (out))) return_trace (false); const uint32_t *v; - out->reqFeatureIndex = l->feature_index_map->has (reqFeatureIndex, &v) ? *v : 0xFFFFu; + out->reqFeatureIndex = l->feature_map_w_duplicates->has (reqFeatureIndex, &v) ? *v : 0xFFFFu; if (!l->visitFeatureIndex (featureIndex.len)) return_trace (false); auto it = + hb_iter (featureIndex) - | hb_filter (l->feature_index_map) - | hb_map (l->feature_index_map) + | hb_filter (l->feature_map_w_duplicates) + | hb_map (l->feature_map_w_duplicates) ; bool ret = bool (it); @@ -1337,7 +1340,7 @@ struct Lookup TRACE_DISPATCH (this, lookup_type); unsigned int count = get_subtable_count (); for (unsigned int i = 0; i < count; i++) { - typename context_t::return_t r = get_subtable (i).dispatch (c, lookup_type, std::forward (ds)...); + typename context_t::return_t r = get_subtable (i).dispatch (c, lookup_type, ds...); if (c->stop_sublookup_iteration (r)) return_trace (r); } @@ -1387,6 +1390,11 @@ struct Lookup { unsigned new_flag = lookupFlag; new_flag &= ~LookupFlag::UseMarkFilteringSet; + // https://github.com/harfbuzz/harfbuzz/issues/5499 + // If we remove UseMarkFilteringSet flag because the set is now empty, + // we need to add IgnoreMarks flag, otherwise the lookup will not + // ignore any marks, which changes the behavior. + new_flag |= LookupFlag::IgnoreMarks; out->lookupFlag = new_flag; } else @@ -2078,7 +2086,7 @@ struct ClassDef } } unsigned int get_class (hb_codepoint_t glyph_id, - hb_ot_lookup_cache_t *cache) const + hb_ot_layout_mapping_cache_t *cache) const { unsigned klass; if (cache && cache->get (glyph_id, &klass)) return klass; @@ -2326,151 +2334,177 @@ struct delta_row_encoding_t { /* each byte represents a region, value is one of 0/1/2/4, which means bytes * needed for this region */ - hb_vector_t chars; + struct chars_t : hb_vector_t + { + int cmp (const chars_t& other) const + { + return as_array ().cmp (other.as_array ()); + } + + hb_pair_t get_width () + { + unsigned width = 0; + unsigned columns = 0; + for (unsigned i = 0; i < length; i++) + { + unsigned v = arrayZ[i]; + width += v; + columns += (v != 0); + } + return hb_pair (width, columns); + } + + HB_HOT + hb_pair_t combine_width (const chars_t& other) const + { + unsigned combined_width = 0; + unsigned combined_columns = 0; + for (unsigned i = 0; i < length; i++) + { + unsigned v = hb_max (arrayZ[i], other.arrayZ[i]); + combined_width += v; + combined_columns += (v != 0); + } + return hb_pair (combined_width, combined_columns); + } + }; + + hb_pair_t combine_width (const delta_row_encoding_t& other_encoding) const { return chars.combine_width (other_encoding.chars); } + + // Actual data + + chars_t chars; unsigned width = 0; - hb_vector_t columns; unsigned overhead = 0; hb_vector_t*> items; delta_row_encoding_t () = default; - delta_row_encoding_t (hb_vector_t&& chars_, - const hb_vector_t* row = nullptr) : - delta_row_encoding_t () - + delta_row_encoding_t (hb_vector_t*> &&rows, unsigned num_cols) { - chars = std::move (chars_); - width = get_width (); - columns = get_columns (); - overhead = get_chars_overhead (columns); - if (row) items.push (row); + assert (rows); + + items = std::move (rows); + + if (unlikely (!chars.resize (num_cols))) + return; + + calculate_chars (); + } + + void merge (const delta_row_encoding_t& other) + { + items.alloc (items.length + other.items.length); + for (auto &row : other.items) + add_row (row); + + // Merge chars + assert (chars.length == other.chars.length); + for (unsigned i = 0; i < chars.length; i++) + chars.arrayZ[i] = hb_max (chars.arrayZ[i], other.chars.arrayZ[i]); + chars_changed (); + } + + void chars_changed () + { + auto _ = chars.get_width (); + width = _.first; + overhead = get_chars_overhead (_.second); + } + + void calculate_chars () + { + assert (items); + + bool long_words = false; + + for (auto &row : items) + { + assert (row->length == chars.length); + + /* 0/1/2 byte encoding */ + for (unsigned i = 0; i < row->length; i++) + { + int v = row->arrayZ[i]; + if (v == 0) + continue; + else if (v > 32767 || v < -32768) + { + long_words = true; + chars.arrayZ[i] = hb_max (chars.arrayZ[i], 4); + } + else if (v > 127 || v < -128) + chars.arrayZ[i] = hb_max (chars.arrayZ[i], 2); + else + chars.arrayZ[i] = hb_max (chars.arrayZ[i], 1); + } + } + + if (long_words) + { + // Convert 1s to 2s + for (auto &v : chars) + if (v == 1) + v = 2; + } + + chars_changed (); } bool is_empty () const { return !items; } - static hb_vector_t get_row_chars (const hb_vector_t& row) - { - hb_vector_t ret; - if (!ret.alloc (row.length)) return ret; - - bool long_words = false; - - /* 0/1/2 byte encoding */ - for (int i = row.length - 1; i >= 0; i--) - { - int v = row.arrayZ[i]; - if (v == 0) - ret.push (0); - else if (v > 32767 || v < -32768) - { - long_words = true; - break; - } - else if (v > 127 || v < -128) - ret.push (2); - else - ret.push (1); - } - - if (!long_words) - return ret; - - /* redo, 0/2/4 bytes encoding */ - ret.reset (); - for (int i = row.length - 1; i >= 0; i--) - { - int v = row.arrayZ[i]; - if (v == 0) - ret.push (0); - else if (v > 32767 || v < -32768) - ret.push (4); - else - ret.push (2); - } - return ret; - } - - inline unsigned get_width () - { - unsigned ret = + hb_iter (chars) - | hb_reduce (hb_add, 0u) - ; - return ret; - } - - hb_vector_t get_columns () - { - hb_vector_t cols; - cols.alloc (chars.length); - for (auto v : chars) - { - uint8_t flag = v ? 1 : 0; - cols.push (flag); - } - return cols; - } - - static inline unsigned get_chars_overhead (const hb_vector_t& cols) + static inline unsigned get_chars_overhead (unsigned num_columns) { unsigned c = 4 + 6; // 4 bytes for LOffset, 6 bytes for VarData header - unsigned cols_bit_count = 0; - for (auto v : cols) - if (v) cols_bit_count++; - return c + cols_bit_count * 2; + return c + num_columns * 2; } - unsigned get_gain () const + unsigned get_gain (unsigned additional_bytes_per_rows = 1) const { int count = items.length; - return hb_max (0, (int) overhead - count); + return hb_max (0, (int) overhead - count * (int) additional_bytes_per_rows); } int gain_from_merging (const delta_row_encoding_t& other_encoding) const { - int combined_width = 0; - for (unsigned i = 0; i < chars.length; i++) - combined_width += hb_max (chars.arrayZ[i], other_encoding.chars.arrayZ[i]); + // Back of the envelope calculations to reject early. + signed additional_bytes_per_rows = other_encoding.width - width; + if (additional_bytes_per_rows > 0) + { + if (get_gain (additional_bytes_per_rows) == 0) + return 0; + } + else + { + if (other_encoding.get_gain (-additional_bytes_per_rows) == 0) + return 0; + } - hb_vector_t combined_columns; - combined_columns.alloc (columns.length); - for (unsigned i = 0; i < columns.length; i++) - combined_columns.push (columns.arrayZ[i] | other_encoding.columns.arrayZ[i]); + auto pair = combine_width (other_encoding); + unsigned combined_width = pair.first; + unsigned combined_columns = pair.second; - int combined_overhead = get_chars_overhead (combined_columns); - int combined_gain = (int) overhead + (int) other_encoding.overhead - combined_overhead - - (combined_width - (int) width) * items.length - - (combined_width - (int) other_encoding.width) * other_encoding.items.length; + int combined_gain = (int) overhead + (int) other_encoding.overhead; + combined_gain -= (combined_width - (int) width) * items.length; + combined_gain -= (combined_width - (int) other_encoding.width) * other_encoding.items.length; + combined_gain -= get_chars_overhead (combined_columns); return combined_gain; } + bool add_row (const hb_vector_t* row) + { return items.push (row); } + static int cmp (const void *pa, const void *pb) { const delta_row_encoding_t *a = (const delta_row_encoding_t *)pa; const delta_row_encoding_t *b = (const delta_row_encoding_t *)pb; - int gain_a = a->get_gain (); - int gain_b = b->get_gain (); - - if (gain_a != gain_b) - return gain_a - gain_b; - - return (b->chars).as_array ().cmp ((a->chars).as_array ()); - } - - static int cmp_width (const void *pa, const void *pb) - { - const delta_row_encoding_t *a = (const delta_row_encoding_t *)pa; - const delta_row_encoding_t *b = (const delta_row_encoding_t *)pb; - if (a->width != b->width) return (int) a->width - (int) b->width; - return (b->chars).as_array ().cmp ((a->chars).as_array ()); + return b->chars.cmp (a->chars); } - - bool add_row (const hb_vector_t* row) - { return items.push (row); } }; struct VarRegionAxis @@ -2575,7 +2609,7 @@ struct hb_scalar_cache_t return scratch_cache; } - auto *cache = (hb_scalar_cache_t *) hb_malloc (sizeof (hb_scalar_cache_t) - sizeof (values) + sizeof (values[0]) * count); + auto *cache = (hb_scalar_cache_t *) hb_malloc (sizeof (hb_scalar_cache_t) - sizeof (static_values) + sizeof (static_values[0]) * count); if (unlikely (!cache)) return (hb_scalar_cache_t *) &Null(hb_scalar_cache_t); cache->length = count; @@ -2593,6 +2627,7 @@ struct hb_scalar_cache_t void clear () { + auto *values = &static_values[0]; for (unsigned i = 0; i < length; i++) values[i] = INVALID; } @@ -2605,6 +2640,7 @@ struct hb_scalar_cache_t *value = 0.f; return true; } + auto *values = &static_values[0]; auto *cached_value = &values[i]; if (*cached_value != INVALID) { @@ -2618,13 +2654,14 @@ struct hb_scalar_cache_t void set (unsigned i, float value) { if (unlikely (i >= length)) return; + auto *values = &static_values[0]; auto *cached_value = &values[i]; *cached_value = roundf(value * MULTIPLIER); } private: unsigned length; - mutable hb_atomic_t values[STATIC_LENGTH]; + mutable hb_atomic_t static_values[STATIC_LENGTH]; }; struct VarRegionList @@ -3439,7 +3476,7 @@ struct ItemVariationStore for (unsigned i = 0; i < count; i++) { hb_inc_bimap_t *map = inner_maps.push (); - if (!c->propagate_error(inner_maps)) + if (unlikely (!c->propagate_error(inner_maps))) return_trace(nullptr); auto &data = this+dataSets[i]; @@ -4425,7 +4462,7 @@ struct FeatureTableSubstitutionRecord if (unlikely (!s->extend_min (this))) return_trace (false); uint32_t *new_feature_idx; - if (!c->feature_index_map->has (feature_index, &new_feature_idx)) + if (!c->feature_map_w_duplicates->has (feature_index, &new_feature_idx)) return_trace (false); if (!s->check_assign (featureIndex, *new_feature_idx, HB_SERIALIZE_ERROR_INT_OVERFLOW)) @@ -4443,7 +4480,7 @@ struct FeatureTableSubstitutionRecord { TRACE_SUBSET (this); uint32_t *new_feature_index; - if (!c->feature_index_map->has (featureIndex, &new_feature_index)) + if (!c->feature_map_w_duplicates->has (featureIndex, &new_feature_index)) return_trace (false); auto *out = c->subset_context->serializer->embed (this); @@ -4717,7 +4754,7 @@ struct FeatureVariations int keep_up_to = -1; for (int i = varRecords.len - 1; i >= 0; i--) { - if (varRecords[i].intersects_features (this, l->feature_index_map)) { + if (varRecords[i].intersects_features (this, l->feature_map_w_duplicates)) { keep_up_to = i; break; } diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-gpos-table.hh b/thirdparty/harfbuzz/src/hb-ot-layout-gpos-table.hh index 0cfa139a260..f6aabc84ac9 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout-gpos-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout-gpos-table.hh @@ -63,12 +63,20 @@ inline bool PosLookup::dispatch_recurse_func (hb_ot_apply c->set_lookup_index (lookup_index); c->set_lookup_props (l.get_props ()); + uint32_t stack_match_positions[8]; + hb_vector_t saved_match_positions; + saved_match_positions.set_storage (stack_match_positions); + hb_swap (c->match_positions, saved_match_positions); + bool ret = false; auto *accel = gpos->get_accel (lookup_index); - ret = accel && accel->apply (c, l.get_subtable_count (), false); + ret = accel && accel->apply (c, false); c->set_lookup_index (saved_lookup_index); c->set_lookup_props (saved_lookup_props); + + hb_swap (c->match_positions, saved_match_positions); + return ret; } #endif diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-gsub-table.hh b/thirdparty/harfbuzz/src/hb-ot-layout-gsub-table.hh index fd8a68be02d..8d5e1f18638 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout-gsub-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout-gsub-table.hh @@ -76,12 +76,20 @@ inline bool SubstLookup::dispatch_recurse_func (hb_ot_app c->set_lookup_index (lookup_index); c->set_lookup_props (l.get_props ()); + uint32_t stack_match_positions[8]; + hb_vector_t saved_match_positions; + saved_match_positions.set_storage (stack_match_positions); + hb_swap (c->match_positions, saved_match_positions); + bool ret = false; auto *accel = gsub->get_accel (lookup_index); - ret = accel && accel->apply (c, l.get_subtable_count (), false); + ret = accel && accel->apply (c, false); c->set_lookup_index (saved_lookup_index); c->set_lookup_props (saved_lookup_props); + + hb_swap (c->match_positions, saved_match_positions); + return ret; } #endif diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh b/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh index 83325548ded..4ad4faae670 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh @@ -455,7 +455,7 @@ struct matcher_t HB_ALWAYS_INLINE #endif may_skip_t may_skip (const context_t *c, - const hb_glyph_info_t &info) const + const hb_glyph_info_t &info) const { if (!c->check_glyph_property (&info, lookup_props)) return SKIP_YES; @@ -670,15 +670,29 @@ struct hb_ot_apply_context_t : { const char *get_name () { return "APPLY"; } typedef return_t (*recurse_func_t) (hb_ot_apply_context_t *c, unsigned int lookup_index); + template - return_t dispatch (const T &obj) { return obj.apply (this); } + static inline auto apply_ (const T &obj, hb_ot_apply_context_t *c, hb_priority<1>) HB_RETURN (return_t, obj.apply (c, nullptr) ) + template + static inline auto apply_ (const T &obj, hb_ot_apply_context_t *c, hb_priority<0>) HB_RETURN (return_t, obj.apply (c) ) + template + return_t dispatch (const T &obj) { return apply_(obj, this, hb_prioritize); } + static return_t default_return_value () { return false; } bool stop_sublookup_iteration (return_t r) const { return r; } return_t recurse (unsigned int sub_lookup_index) { - if (unlikely (nesting_level_left == 0 || !recurse_func || buffer->max_ops-- <= 0)) + assert (recurse_func); + if (unlikely (nesting_level_left == 0)) { - buffer->shaping_failed = true; + buffer->successful = false; + return default_return_value (); + } + + buffer->max_ops--; + if (unlikely (buffer->max_ops < 0)) + { + buffer->successful = false; return default_return_value (); } @@ -701,7 +715,6 @@ struct hb_ot_apply_context_t : const hb_ot_layout_lookup_accelerator_t *lookup_accel = nullptr; const ItemVariationStore &var_store; hb_scalar_cache_t *var_store_cache; - hb_set_digest_t digest; hb_direction_t direction; hb_mask_t lookup_mask = 1; @@ -719,6 +732,9 @@ struct hb_ot_apply_context_t : signed last_base = -1; // GPOS uses unsigned last_base_until = 0; // GPOS uses + hb_vector_t match_positions; + uint32_t stack_match_positions[8]; + hb_ot_apply_context_t (unsigned int table_index_, hb_font_t *font_, hb_buffer_t *buffer_, @@ -747,7 +763,7 @@ struct hb_ot_apply_context_t : has_glyph_classes (gdef.has_glyph_classes ()) { init_iters (); - buffer->collect_codepoints (digest); + match_positions.set_storage (stack_match_positions); } void init_iters () @@ -772,7 +788,9 @@ struct hb_ot_apply_context_t : return buffer->random_state; } - bool match_properties_mark (hb_codepoint_t glyph, + HB_ALWAYS_INLINE + HB_HOT + bool match_properties_mark (const hb_glyph_info_t *info, unsigned int glyph_props, unsigned int match_props) const { @@ -780,7 +798,7 @@ struct hb_ot_apply_context_t : * match_props has the set index. */ if (match_props & LookupFlag::UseMarkFilteringSet) - return gdef_accel.mark_set_covers (match_props >> 16, glyph); + return gdef_accel.mark_set_covers (match_props >> 16, info->codepoint); /* The second byte of match_props has the meaning * "ignore marks of attachment type different than @@ -796,7 +814,7 @@ struct hb_ot_apply_context_t : HB_ALWAYS_INLINE #endif bool check_glyph_property (const hb_glyph_info_t *info, - unsigned int match_props) const + unsigned match_props) const { unsigned int glyph_props = _hb_glyph_info_get_glyph_props (info); @@ -807,7 +825,7 @@ struct hb_ot_apply_context_t : return false; if (unlikely (glyph_props & HB_OT_LAYOUT_GLYPH_PROPS_MARK)) - return match_properties_mark (info->codepoint, glyph_props, match_props); + return match_properties_mark (info, glyph_props, match_props); return true; } @@ -817,7 +835,7 @@ struct hb_ot_apply_context_t : bool ligature = false, bool component = false) { - digest.add (glyph_index); + buffer->digest.add (glyph_index); if (new_syllables != (unsigned) -1) buffer->cur().syllable() = new_syllables; @@ -875,54 +893,58 @@ struct hb_ot_apply_context_t : } }; -enum class hb_ot_lookup_cache_op_t +enum class hb_ot_subtable_cache_op_t { - CREATE, ENTER, LEAVE, - DESTROY, }; struct hb_accelerate_subtables_context_t : hb_dispatch_context_t { - template - static inline bool apply_to (const void *obj, hb_ot_apply_context_t *c) + template + static inline auto apply_ (const T *obj, hb_ot_apply_context_t *c, void *external_cache, hb_priority<1>) HB_RETURN (bool, obj->apply (c, external_cache) ) + template + static inline auto apply_ (const T *obj, hb_ot_apply_context_t *c, void *external_cache, hb_priority<0>) HB_RETURN (bool, obj->apply (c) ) + template + static inline bool apply_to (const void *obj, hb_ot_apply_context_t *c, void *external_cache) { - const Type *typed_obj = (const Type *) obj; - return typed_obj->apply (c); + const T *typed_obj = (const T *) obj; + return apply_ (typed_obj, c, external_cache, hb_prioritize); } #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE template - static inline auto apply_cached_ (const T *obj, hb_ot_apply_context_t *c, hb_priority<1>) HB_RETURN (bool, obj->apply_cached (c) ) + static inline auto apply_cached_ (const T *obj, hb_ot_apply_context_t *c, void *external_cache, hb_priority<2>) HB_RETURN (bool, obj->apply_cached (c, external_cache) ) template - static inline auto apply_cached_ (const T *obj, hb_ot_apply_context_t *c, hb_priority<0>) HB_RETURN (bool, obj->apply (c) ) - template - static inline bool apply_cached_to (const void *obj, hb_ot_apply_context_t *c) + static inline auto apply_cached_ (const T *obj, hb_ot_apply_context_t *c, void *external_cache, hb_priority<1>) HB_RETURN (bool, obj->apply (c, external_cache) ) + template + static inline auto apply_cached_ (const T *obj, hb_ot_apply_context_t *c, void *external_cache, hb_priority<0>) HB_RETURN (bool, obj->apply (c) ) + template + static inline bool apply_cached_to (const void *obj, hb_ot_apply_context_t *c, void *external_cache) { - const Type *typed_obj = (const Type *) obj; - return apply_cached_ (typed_obj, c, hb_prioritize); + const T *typed_obj = (const T *) obj; + return apply_cached_ (typed_obj, c, external_cache, hb_prioritize); } template - static inline auto cache_func_ (void *p, - hb_ot_lookup_cache_op_t op, - hb_priority<1>) HB_RETURN (void *, T::cache_func (p, op) ) + static inline auto cache_func_ (hb_ot_apply_context_t *c, + hb_ot_subtable_cache_op_t op, + hb_priority<1>) HB_RETURN (bool, T::cache_func (c, op) ) template - static inline void * cache_func_ (void *p, - hb_ot_lookup_cache_op_t op HB_UNUSED, - hb_priority<0>) { return (void *) false; } + static inline bool cache_func_ (hb_ot_apply_context_t *c, + hb_ot_subtable_cache_op_t op HB_UNUSED, + hb_priority<0>) { return false; } template - static inline void * cache_func_to (void *p, - hb_ot_lookup_cache_op_t op) + static inline bool cache_func_to (hb_ot_apply_context_t *c, + hb_ot_subtable_cache_op_t op) { - return cache_func_ (p, op, hb_prioritize); + return cache_func_ (c, op, hb_prioritize); } #endif - typedef bool (*hb_apply_func_t) (const void *obj, hb_ot_apply_context_t *c); - typedef void * (*hb_cache_func_t) (void *p, hb_ot_lookup_cache_op_t op); + typedef bool (*hb_apply_func_t) (const void *obj, hb_ot_apply_context_t *c, void *external_cache); + typedef bool (*hb_cache_func_t) (hb_ot_apply_context_t *c, hb_ot_subtable_cache_op_t op); struct hb_applicable_t { @@ -935,6 +957,7 @@ struct hb_accelerate_subtables_context_t : #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE , hb_apply_func_t apply_cached_func_ , hb_cache_func_t cache_func_ + , void *external_cache_ #endif ) { @@ -943,27 +966,34 @@ struct hb_accelerate_subtables_context_t : #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE apply_cached_func = apply_cached_func_; cache_func = cache_func_; + external_cache = external_cache_; #endif digest.init (); obj_.get_coverage ().collect_coverage (&digest); } +#ifdef HB_NO_OT_LAYOUT_LOOKUP_CACHE bool apply (hb_ot_apply_context_t *c) const { - return digest.may_have (c->buffer->cur().codepoint) && apply_func (obj, c); + return digest.may_have (c->buffer->cur().codepoint) && apply_func (obj, c, nullptr); + } +#else + bool apply (hb_ot_apply_context_t *c) const + { + return digest.may_have (c->buffer->cur().codepoint) && apply_func (obj, c, external_cache); } -#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE bool apply_cached (hb_ot_apply_context_t *c) const { - return digest.may_have (c->buffer->cur().codepoint) && apply_cached_func (obj, c); + return digest.may_have (c->buffer->cur().codepoint) && apply_cached_func (obj, c, external_cache); } + bool cache_enter (hb_ot_apply_context_t *c) const { - return (bool) cache_func (c, hb_ot_lookup_cache_op_t::ENTER); + return cache_func (c, hb_ot_subtable_cache_op_t::ENTER); } void cache_leave (hb_ot_apply_context_t *c) const { - cache_func (c, hb_ot_lookup_cache_op_t::LEAVE); + cache_func (c, hb_ot_subtable_cache_op_t::LEAVE); } #endif @@ -973,6 +1003,7 @@ struct hb_accelerate_subtables_context_t : #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE hb_apply_func_t apply_cached_func; hb_cache_func_t cache_func; + void *external_cache; #endif hb_set_digest_t digest; }; @@ -982,12 +1013,23 @@ struct hb_accelerate_subtables_context_t : auto cache_cost (const T &obj, hb_priority<1>) HB_AUTO_RETURN ( obj.cache_cost () ) template auto cache_cost (const T &obj, hb_priority<0>) HB_AUTO_RETURN ( 0u ) + + template + auto external_cache_create (const T &obj, hb_priority<1>) HB_AUTO_RETURN ( obj.external_cache_create () ) + template + auto external_cache_create (const T &obj, hb_priority<0>) HB_AUTO_RETURN ( nullptr ) #endif /* Dispatch interface. */ template return_t dispatch (const T &obj) { +#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE + void *external_cache = nullptr; + if (i < 8) + external_cache = external_cache_create (obj, hb_prioritize); +#endif + hb_applicable_t *entry = &array[i++]; entry->init (obj, @@ -995,6 +1037,7 @@ struct hb_accelerate_subtables_context_t : #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE , apply_cached_to , cache_func_to + , external_cache #endif ); @@ -1008,10 +1051,10 @@ struct hb_accelerate_subtables_context_t : * and we allocate the cache opportunity to the costliest subtable. */ unsigned cost = cache_cost (obj, hb_prioritize); - if (cost > cache_user_cost) + if (cost > subtable_cache_user_cost) { - cache_user_idx = i - 1; - cache_user_cost = cost; + subtable_cache_user_idx = i - 1; + subtable_cache_user_cost = cost; } #endif @@ -1026,8 +1069,8 @@ struct hb_accelerate_subtables_context_t : unsigned i = 0; #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE - unsigned cache_user_idx = (unsigned) -1; - unsigned cache_user_cost = 0; + unsigned subtable_cache_user_idx = (unsigned) -1; + unsigned subtable_cache_user_cost = 0; #endif }; @@ -1176,38 +1219,50 @@ static inline bool match_class (hb_glyph_info_t &info, unsigned value, const voi const ClassDef &class_def = *reinterpret_cast(data); return class_def.get_class (info.codepoint) == value; } -static inline bool match_class_cached (hb_glyph_info_t &info, unsigned value, const void *data) +static inline unsigned get_class_cached (const ClassDef &class_def, hb_glyph_info_t &info) { unsigned klass = info.syllable(); if (klass < 255) - return klass == value; - const ClassDef &class_def = *reinterpret_cast(data); + return klass; klass = class_def.get_class (info.codepoint); if (likely (klass < 255)) info.syllable() = klass; - return klass == value; + return klass; } -static inline bool match_class_cached1 (hb_glyph_info_t &info, unsigned value, const void *data) +static inline bool match_class_cached (hb_glyph_info_t &info, unsigned value, const void *data) +{ + const ClassDef &class_def = *reinterpret_cast(data); + return get_class_cached (class_def, info) == value; +} +static inline unsigned get_class_cached1 (const ClassDef &class_def, hb_glyph_info_t &info) { unsigned klass = info.syllable() & 0x0F; if (klass < 15) - return klass == value; - const ClassDef &class_def = *reinterpret_cast(data); + return klass; klass = class_def.get_class (info.codepoint); if (likely (klass < 15)) info.syllable() = (info.syllable() & 0xF0) | klass; - return klass == value; + return klass; } -static inline bool match_class_cached2 (hb_glyph_info_t &info, unsigned value, const void *data) +static inline bool match_class_cached1 (hb_glyph_info_t &info, unsigned value, const void *data) +{ + const ClassDef &class_def = *reinterpret_cast(data); + return get_class_cached1 (class_def, info) == value; +} +static inline unsigned get_class_cached2 (const ClassDef &class_def, hb_glyph_info_t &info) { unsigned klass = (info.syllable() & 0xF0) >> 4; if (klass < 15) - return klass == value; - const ClassDef &class_def = *reinterpret_cast(data); + return klass; klass = class_def.get_class (info.codepoint); if (likely (klass < 15)) info.syllable() = (info.syllable() & 0x0F) | (klass << 4); - return klass == value; + return klass; +} +static inline bool match_class_cached2 (hb_glyph_info_t &info, unsigned value, const void *data) +{ + const ClassDef &class_def = *reinterpret_cast(data); + return get_class_cached2 (class_def, info) == value; } static inline bool match_coverage (hb_glyph_info_t &info, unsigned value, const void *data) { @@ -1246,7 +1301,6 @@ static bool match_input (hb_ot_apply_context_t *c, match_func_t match_func, const void *match_data, unsigned int *end_position, - unsigned int *match_positions, unsigned int *p_total_component_count = nullptr) { TRACE_APPLY (nullptr); @@ -1304,7 +1358,10 @@ static bool match_input (hb_ot_apply_context_t *c, return_trace (false); } - match_positions[i] = skippy_iter.idx; + if (unlikely (i + 1 > c->match_positions.length && + !c->match_positions.resize_dirty (i + 1))) + return_trace (false); + c->match_positions.arrayZ[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]); @@ -1364,13 +1421,12 @@ static bool match_input (hb_ot_apply_context_t *c, *p_total_component_count = total_component_count; } - match_positions[0] = buffer->idx; + c->match_positions.arrayZ[0] = buffer->idx; return_trace (true); } static inline bool ligate_input (hb_ot_apply_context_t *c, unsigned int count, /* Including the first glyph */ - const unsigned int *match_positions, /* Including the first glyph */ unsigned int match_end, hb_codepoint_t lig_glyph, unsigned int total_component_count) @@ -1413,10 +1469,10 @@ static inline bool ligate_input (hb_ot_apply_context_t *c, * https://bugzilla.gnome.org/show_bug.cgi?id=437633 */ - bool is_base_ligature = _hb_glyph_info_is_base_glyph (&buffer->info[match_positions[0]]); - bool is_mark_ligature = _hb_glyph_info_is_mark (&buffer->info[match_positions[0]]); + bool is_base_ligature = _hb_glyph_info_is_base_glyph (&buffer->info[c->match_positions.arrayZ[0]]); + bool is_mark_ligature = _hb_glyph_info_is_mark (&buffer->info[c->match_positions.arrayZ[0]]); for (unsigned int i = 1; i < count; i++) - if (!_hb_glyph_info_is_mark (&buffer->info[match_positions[i]])) + if (!_hb_glyph_info_is_mark (&buffer->info[c->match_positions.arrayZ[i]])) { is_base_ligature = false; is_mark_ligature = false; @@ -1442,7 +1498,7 @@ static inline bool ligate_input (hb_ot_apply_context_t *c, for (unsigned int i = 1; i < count; i++) { - while (buffer->idx < match_positions[i] && buffer->successful) + while (buffer->idx < c->match_positions.arrayZ[i] && buffer->successful) { if (is_ligature) { @@ -1681,7 +1737,6 @@ static inline void recurse_lookups (context_t *c, static inline void apply_lookup (hb_ot_apply_context_t *c, unsigned int count, /* Including the first glyph */ - unsigned int *match_positions, /* Including the first glyph */ unsigned int lookupCount, const LookupRecord lookupRecord[], /* Array of LookupRecords--in design order */ unsigned int match_end) @@ -1689,9 +1744,6 @@ static inline void apply_lookup (hb_ot_apply_context_t *c, hb_buffer_t *buffer = c->buffer; int end; - unsigned int *match_positions_input = match_positions; - unsigned int match_positions_count = count; - /* All positions are distance from beginning of *output* buffer. * Adjust. */ { @@ -1701,7 +1753,7 @@ static inline void apply_lookup (hb_ot_apply_context_t *c, int delta = bl - buffer->idx; /* Convert positions to new indexing. */ for (unsigned int j = 0; j < count; j++) - match_positions[j] += delta; + c->match_positions.arrayZ[j] += delta; } for (unsigned int i = 0; i < lookupCount && buffer->successful; i++) @@ -1713,10 +1765,10 @@ static inline void apply_lookup (hb_ot_apply_context_t *c, unsigned int orig_len = buffer->backtrack_len () + buffer->lookahead_len (); /* This can happen if earlier recursed lookups deleted many entries. */ - if (unlikely (match_positions[idx] >= orig_len)) + if (unlikely (c->match_positions.arrayZ[idx] >= orig_len)) continue; - if (unlikely (!buffer->move_to (match_positions[idx]))) + if (unlikely (!buffer->move_to (c->match_positions.arrayZ[idx]))) break; if (unlikely (buffer->max_ops <= 0)) @@ -1775,9 +1827,9 @@ static inline void apply_lookup (hb_ot_apply_context_t *c, */ end += delta; - if (end < int (match_positions[idx])) + if (end < int (c->match_positions.arrayZ[idx])) { - /* End might end up being smaller than match_positions[idx] if the recursed + /* End might end up being smaller than match_positions.arrayZ[idx] if the recursed * lookup ended up removing many items. * Just never rewind end beyond start of current position, since that is * not possible in the recursed lookup. Also adjust delta as such. @@ -1785,8 +1837,8 @@ static inline void apply_lookup (hb_ot_apply_context_t *c, * https://bugs.chromium.org/p/chromium/issues/detail?id=659496 * https://github.com/harfbuzz/harfbuzz/issues/1611 */ - delta += match_positions[idx] - end; - end = match_positions[idx]; + delta += c->match_positions.arrayZ[idx] - end; + end = c->match_positions.arrayZ[idx]; } unsigned int next = idx + 1; /* next now is the position after the recursed lookup. */ @@ -1795,27 +1847,9 @@ static inline void apply_lookup (hb_ot_apply_context_t *c, { if (unlikely (delta + count > HB_MAX_CONTEXT_LENGTH)) break; - if (unlikely (delta + count > match_positions_count)) - { - unsigned new_match_positions_count = hb_max (delta + count, hb_max(match_positions_count, 4u) * 1.5); - if (match_positions == match_positions_input) - { - match_positions = (unsigned int *) hb_malloc (new_match_positions_count * sizeof (match_positions[0])); - if (unlikely (!match_positions)) - break; - memcpy (match_positions, match_positions_input, count * sizeof (match_positions[0])); - match_positions_count = new_match_positions_count; - } - else - { - unsigned int *new_match_positions = (unsigned int *) hb_realloc (match_positions, new_match_positions_count * sizeof (match_positions[0])); - if (unlikely (!new_match_positions)) - break; - match_positions = new_match_positions; - match_positions_count = new_match_positions_count; - } - } - + if (unlikely (count + delta > c->match_positions.length && + !c->match_positions.resize_dirty (count + delta))) + return; } else { @@ -1825,23 +1859,20 @@ static inline void apply_lookup (hb_ot_apply_context_t *c, } /* Shift! */ - memmove (match_positions + next + delta, match_positions + next, - (count - next) * sizeof (match_positions[0])); + memmove (c->match_positions + next + delta, c->match_positions + next, + (count - next) * sizeof (c->match_positions.arrayZ[0])); next += delta; count += delta; /* Fill in new entries. */ for (unsigned int j = idx + 1; j < next; j++) - match_positions[j] = match_positions[j - 1] + 1; + c->match_positions.arrayZ[j] = c->match_positions.arrayZ[j - 1] + 1; /* And fixup the rest. */ for (; next < count; next++) - match_positions[next] += delta; + c->match_positions.arrayZ[next] += delta; } - if (match_positions != match_positions_input) - hb_free (match_positions); - assert (end >= 0); (void) buffer->move_to (end); } @@ -1944,25 +1975,17 @@ static bool context_apply_lookup (hb_ot_apply_context_t *c, const ContextApplyLookupContext &lookup_context) { if (unlikely (inputCount > HB_MAX_CONTEXT_LENGTH)) return false; - unsigned match_positions_stack[4]; - unsigned *match_positions = match_positions_stack; - if (unlikely (inputCount > ARRAY_LENGTH (match_positions_stack))) - { - match_positions = (unsigned *) hb_malloc (hb_max (inputCount, 1u) * sizeof (match_positions[0])); - if (unlikely (!match_positions)) - return false; - } unsigned match_end = 0; bool ret = false; if (match_input (c, inputCount, input, lookup_context.funcs.match, lookup_context.match_data, - &match_end, match_positions)) + &match_end)) { c->buffer->unsafe_to_break (c->buffer->idx, match_end); apply_lookup (c, - inputCount, match_positions, + inputCount, lookupCount, lookupRecord, match_end); ret = true; @@ -1973,12 +1996,34 @@ static bool context_apply_lookup (hb_ot_apply_context_t *c, ret = false; } - if (unlikely (match_positions != match_positions_stack)) - hb_free (match_positions); - return ret; } +static inline bool context_cache_func (hb_ot_apply_context_t *c, hb_ot_subtable_cache_op_t op) +{ + switch (op) + { + case hb_ot_subtable_cache_op_t::ENTER: + { + if (!HB_BUFFER_TRY_ALLOCATE_VAR (c->buffer, syllable)) + return false; + auto &info = c->buffer->info; + unsigned count = c->buffer->len; + for (unsigned i = 0; i < count; i++) + info[i].syllable() = 255; + c->new_syllables = 255; + return true; + } + case hb_ot_subtable_cache_op_t::LEAVE: + { + c->new_syllables = (unsigned) -1; + HB_BUFFER_DEALLOCATE_VAR (c->buffer, syllable); + break; + } + } + return false; +} + template struct Rule { @@ -2607,41 +2652,14 @@ struct ContextFormat2_5 unsigned cache_cost () const { - unsigned c = (this+classDef).cost () * ruleSet.len; - return c >= 4 ? c : 0; + return (this+classDef).cost (); } - static void * cache_func (void *p, hb_ot_lookup_cache_op_t op) + static bool cache_func (hb_ot_apply_context_t *c, hb_ot_subtable_cache_op_t op) { - switch (op) - { - case hb_ot_lookup_cache_op_t::CREATE: - return (void *) true; - case hb_ot_lookup_cache_op_t::ENTER: - { - hb_ot_apply_context_t *c = (hb_ot_apply_context_t *) p; - if (!HB_BUFFER_TRY_ALLOCATE_VAR (c->buffer, syllable)) - return (void *) false; - auto &info = c->buffer->info; - unsigned count = c->buffer->len; - for (unsigned i = 0; i < count; i++) - info[i].syllable() = 255; - c->new_syllables = 255; - return (void *) true; - } - case hb_ot_lookup_cache_op_t::LEAVE: - { - hb_ot_apply_context_t *c = (hb_ot_apply_context_t *) p; - c->new_syllables = (unsigned) -1; - HB_BUFFER_DEALLOCATE_VAR (c->buffer, syllable); - return nullptr; - } - case hb_ot_lookup_cache_op_t::DESTROY: - return nullptr; - } - return nullptr; + return context_cache_func (c, op); } - bool apply_cached (hb_ot_apply_context_t *c) const { return _apply (c, true); } + bool apply_cached (hb_ot_apply_context_t *c, void *external_cache HB_UNUSED) const { return _apply (c, true); } bool apply (hb_ot_apply_context_t *c) const { return _apply (c, false); } bool _apply (hb_ot_apply_context_t *c, bool cached) const { @@ -2656,10 +2674,7 @@ struct ContextFormat2_5 &class_def }; - if (cached && c->buffer->cur().syllable() < 255) - index = c->buffer->cur().syllable (); - else - index = class_def.get_class (c->buffer->cur().codepoint); + index = cached ? get_class_cached (class_def, c->buffer->cur()) : class_def.get_class (c->buffer->cur().codepoint); const RuleSet &rule_set = this+ruleSet[index]; return_trace (rule_set.apply (c, lookup_context)); } @@ -3067,14 +3082,6 @@ static bool chain_context_apply_lookup (hb_ot_apply_context_t *c, const ChainContextApplyLookupContext &lookup_context) { if (unlikely (inputCount > HB_MAX_CONTEXT_LENGTH)) return false; - unsigned match_positions_stack[4]; - unsigned *match_positions = match_positions_stack; - if (unlikely (inputCount > ARRAY_LENGTH (match_positions_stack))) - { - match_positions = (unsigned *) hb_malloc (hb_max (inputCount, 1u) * sizeof (match_positions[0])); - if (unlikely (!match_positions)) - return false; - } unsigned start_index = c->buffer->out_len; unsigned end_index = c->buffer->idx; @@ -3083,15 +3090,14 @@ static bool chain_context_apply_lookup (hb_ot_apply_context_t *c, if (!(match_input (c, inputCount, input, lookup_context.funcs.match[1], lookup_context.match_data[1], - &match_end, match_positions) && (end_index = match_end) + &match_end) && (end_index = match_end) && match_lookahead (c, lookaheadCount, lookahead, lookup_context.funcs.match[2], lookup_context.match_data[2], match_end, &end_index))) { c->buffer->unsafe_to_concat (c->buffer->idx, end_index); - ret = false; - goto done; + return false; } if (!match_backtrack (c, @@ -3100,19 +3106,14 @@ static bool chain_context_apply_lookup (hb_ot_apply_context_t *c, &start_index)) { c->buffer->unsafe_to_concat_from_outbuffer (start_index, end_index); - ret = false; - goto done; + return false; } c->buffer->unsafe_to_break_from_outbuffer (start_index, end_index); apply_lookup (c, - inputCount, match_positions, + inputCount, lookupCount, lookupRecord, match_end); - done: - - if (unlikely (match_positions != match_positions_stack)) - hb_free (match_positions); return ret; } @@ -3460,7 +3461,7 @@ struct ChainRuleSet const auto &input = StructAfter (r.backtrack); const auto &lookahead = StructAfter (input); - unsigned lenP1 = hb_max ((unsigned) input.lenP1, 1u); + unsigned lenP1 = input.lenP1; if (lenP1 > 1 ? (!match_input || match_input (*first, input.arrayZ[0], input_data)) @@ -3468,6 +3469,7 @@ struct ChainRuleSet (!lookahead.len || !match_lookahead || match_lookahead (*first, lookahead.arrayZ[0], lookahead_data))) { + lenP1 = hb_max (lenP1, 1u); if (!second || (lenP1 > 2 ? (!match_input || @@ -3858,40 +3860,14 @@ struct ChainContextFormat2_5 unsigned cache_cost () const { - return (this+lookaheadClassDef).cost () * ruleSet.len; + return (this+inputClassDef).cost () + (this+lookaheadClassDef).cost (); } - static void * cache_func (void *p, hb_ot_lookup_cache_op_t op) + static bool cache_func (hb_ot_apply_context_t *c, hb_ot_subtable_cache_op_t op) { - switch (op) - { - case hb_ot_lookup_cache_op_t::CREATE: - return (void *) true; - case hb_ot_lookup_cache_op_t::ENTER: - { - hb_ot_apply_context_t *c = (hb_ot_apply_context_t *) p; - if (!HB_BUFFER_TRY_ALLOCATE_VAR (c->buffer, syllable)) - return (void *) false; - auto &info = c->buffer->info; - unsigned count = c->buffer->len; - for (unsigned i = 0; i < count; i++) - info[i].syllable() = 255; - c->new_syllables = 255; - return (void *) true; - } - case hb_ot_lookup_cache_op_t::LEAVE: - { - hb_ot_apply_context_t *c = (hb_ot_apply_context_t *) p; - c->new_syllables = (unsigned) -1; - HB_BUFFER_DEALLOCATE_VAR (c->buffer, syllable); - return nullptr; - } - case hb_ot_lookup_cache_op_t::DESTROY: - return nullptr; - } - return nullptr; + return context_cache_func (c, op); } - bool apply_cached (hb_ot_apply_context_t *c) const { return _apply (c, true); } + bool apply_cached (hb_ot_apply_context_t *c, void *external_cache HB_UNUSED) const { return _apply (c, true); } bool apply (hb_ot_apply_context_t *c) const { return _apply (c, false); } bool _apply (hb_ot_apply_context_t *c, bool cached) const { @@ -3914,11 +3890,9 @@ struct ChainContextFormat2_5 &lookahead_class_def} }; - // Note: Corresponds to match_class_cached2 - if (cached && ((c->buffer->cur().syllable() & 0xF0) >> 4) < 15) - index = (c->buffer->cur().syllable () & 0xF0) >> 4; - else - index = input_class_def.get_class (c->buffer->cur().codepoint); + index = cached + ? get_class_cached2 (input_class_def, c->buffer->cur()) + : input_class_def.get_class (c->buffer->cur().codepoint); const ChainRuleSet &rule_set = this+ruleSet[index]; return_trace (rule_set.apply (c, lookup_context)); } @@ -4413,22 +4387,14 @@ struct hb_ot_layout_lookup_accelerator_t for (auto& subtable : hb_iter (thiz->subtables, count)) thiz->digest.union_ (subtable.digest); + thiz->count = count; + #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE - if (c_accelerate_subtables.cache_user_cost < 4) - c_accelerate_subtables.cache_user_idx = (unsigned) -1; - - thiz->cache_user_idx = c_accelerate_subtables.cache_user_idx; - - if (thiz->cache_user_idx != (unsigned) -1) - { - thiz->cache = thiz->subtables[thiz->cache_user_idx].cache_func (nullptr, hb_ot_lookup_cache_op_t::CREATE); - if (!thiz->cache) - thiz->cache_user_idx = (unsigned) -1; - } + thiz->subtable_cache_user_idx = c_accelerate_subtables.subtable_cache_user_idx; for (unsigned i = 0; i < count; i++) - if (i != thiz->cache_user_idx) - thiz->subtables[i].apply_cached_func = thiz->subtables[i].apply_func; + if (i != thiz->subtable_cache_user_idx) + thiz->subtables[i].apply_cached_func = thiz->subtables[i].apply_func; #endif return thiz; @@ -4437,11 +4403,8 @@ struct hb_ot_layout_lookup_accelerator_t void fini () { #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE - if (cache) - { - assert (cache_user_idx != (unsigned) -1); - subtables[cache_user_idx].cache_func (cache, hb_ot_lookup_cache_op_t::DESTROY); - } + for (unsigned i = 0; i < count; i++) + hb_free (subtables[i].external_cache); #endif } @@ -4451,14 +4414,14 @@ struct hb_ot_layout_lookup_accelerator_t #ifndef HB_OPTIMIZE_SIZE HB_ALWAYS_INLINE #endif - bool apply (hb_ot_apply_context_t *c, unsigned subtables_count, bool use_cache) const + bool apply (hb_ot_apply_context_t *c, bool use_cache) const { c->lookup_accel = this; #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE if (use_cache) { return - + hb_iter (hb_iter (subtables, subtables_count)) + + hb_iter (hb_iter (subtables, count)) | hb_map ([&c] (const hb_accelerate_subtables_context_t::hb_applicable_t &_) { return _.apply_cached (c); }) | hb_any ; @@ -4467,7 +4430,7 @@ struct hb_ot_layout_lookup_accelerator_t #endif { return - + hb_iter (hb_iter (subtables, subtables_count)) + + hb_iter (hb_iter (subtables, count)) | hb_map ([&c] (const hb_accelerate_subtables_context_t::hb_applicable_t &_) { return _.apply (c); }) | hb_any ; @@ -4478,8 +4441,8 @@ struct hb_ot_layout_lookup_accelerator_t bool cache_enter (hb_ot_apply_context_t *c) const { #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE - return cache_user_idx != (unsigned) -1 && - subtables[cache_user_idx].cache_enter (c); + return subtable_cache_user_idx != (unsigned) -1 && + subtables[subtable_cache_user_idx].cache_enter (c); #else return false; #endif @@ -4487,19 +4450,17 @@ struct hb_ot_layout_lookup_accelerator_t void cache_leave (hb_ot_apply_context_t *c) const { #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE - subtables[cache_user_idx].cache_leave (c); + subtables[subtable_cache_user_idx].cache_leave (c); #endif } hb_set_digest_t digest; + private: + unsigned count = 0; /* Number of subtables in the array. */ #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE - public: - void *cache = nullptr; - private: - unsigned cache_user_idx = (unsigned) -1; + unsigned subtable_cache_user_idx = (unsigned) -1; #endif - private: hb_accelerate_subtables_context_t::hb_applicable_t subtables[HB_VAR_ARRAY]; }; diff --git a/thirdparty/harfbuzz/src/hb-ot-layout.cc b/thirdparty/harfbuzz/src/hb-ot-layout.cc index 51572ce4b03..f69274baecc 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout.cc +++ b/thirdparty/harfbuzz/src/hb-ot-layout.cc @@ -1915,31 +1915,33 @@ struct GPOSProxy static inline bool apply_forward (OT::hb_ot_apply_context_t *c, - const OT::hb_ot_layout_lookup_accelerator_t &accel, - unsigned subtable_count) + const OT::hb_ot_layout_lookup_accelerator_t &accel) { - bool use_cache = accel.cache_enter (c); + bool use_hot_subtable_cache = accel.cache_enter (c); bool ret = false; hb_buffer_t *buffer = c->buffer; - while (buffer->idx < buffer->len && buffer->successful) + while (buffer->successful) { - bool applied = false; - auto &cur = buffer->cur(); - if (accel.digest.may_have (cur.codepoint) && - (cur.mask & c->lookup_mask) && - c->check_glyph_property (&cur, c->lookup_props)) - { - applied = accel.apply (c, subtable_count, use_cache); - } + hb_glyph_info_t *info = buffer->info; + unsigned j = buffer->idx; + while (j < buffer->len && + !(accel.digest.may_have (info[j].codepoint) && + (info[j].mask & c->lookup_mask) && + c->check_glyph_property (&info[j], c->lookup_props))) + j++; + if (unlikely (j > buffer->idx && !buffer->next_glyphs (j - buffer->idx))) + break; + if (buffer->idx >= buffer->len) + break; - if (applied) + if (accel.apply (c, use_hot_subtable_cache)) ret = true; else (void) buffer->next_glyph (); } - if (use_cache) + if (use_hot_subtable_cache) accel.cache_leave (c); return ret; @@ -1947,8 +1949,7 @@ apply_forward (OT::hb_ot_apply_context_t *c, static inline bool apply_backward (OT::hb_ot_apply_context_t *c, - const OT::hb_ot_layout_lookup_accelerator_t &accel, - unsigned subtable_count) + const OT::hb_ot_layout_lookup_accelerator_t &accel) { bool ret = false; hb_buffer_t *buffer = c->buffer; @@ -1958,11 +1959,10 @@ apply_backward (OT::hb_ot_apply_context_t *c, if (accel.digest.may_have (cur.codepoint) && (cur.mask & c->lookup_mask) && c->check_glyph_property (&cur, c->lookup_props)) - ret |= accel.apply (c, subtable_count, false); + ret |= accel.apply (c, false); /* The reverse lookup doesn't "advance" cursor (for good reason). */ buffer->idx--; - } while ((int) buffer->idx >= 0); return ret; @@ -1975,7 +1975,6 @@ apply_string (OT::hb_ot_apply_context_t *c, const OT::hb_ot_layout_lookup_accelerator_t &accel) { hb_buffer_t *buffer = c->buffer; - unsigned subtable_count = lookup.get_subtable_count (); if (unlikely (!buffer->len || !c->lookup_mask)) return false; @@ -1991,7 +1990,7 @@ apply_string (OT::hb_ot_apply_context_t *c, buffer->clear_output (); buffer->idx = 0; - ret = apply_forward (c, accel, subtable_count); + ret = apply_forward (c, accel); if (!Proxy::always_inplace) buffer->sync (); @@ -2001,7 +2000,7 @@ apply_string (OT::hb_ot_apply_context_t *c, /* in-place backward substitution/positioning */ assert (!buffer->have_output); buffer->idx = buffer->len - 1; - ret = apply_backward (c, accel, subtable_count); + ret = apply_backward (c, accel); } return ret; @@ -2037,11 +2036,8 @@ inline void hb_ot_map_t::apply (const Proxy &proxy, if (buffer->messaging () && !buffer->message (font, "start lookup %u feature '%c%c%c%c'", lookup_index, HB_UNTAG (lookup.feature_tag))) continue; - /* c.digest is a digest of all the current glyphs in the buffer - * (plus some past glyphs). - * - * Only try applying the lookup if there is any overlap. */ - if (accel->digest.may_intersect (c.digest)) + /* Only try applying the lookup if there is any overlap. */ + if (accel->digest.may_intersect (buffer->digest)) { c.set_lookup_index (lookup_index); c.set_lookup_mask (lookup.mask, false); @@ -2067,7 +2063,7 @@ inline void hb_ot_map_t::apply (const Proxy &proxy, if (stage->pause_func (plan, font, buffer)) { /* Refresh working buffer digest since buffer changed. */ - buffer->collect_codepoints (c.digest); + buffer->update_digest (); } } } @@ -2601,6 +2597,7 @@ hb_ot_layout_get_baseline_with_fallback2 (hb_font_t *font, #endif +#ifndef HB_NO_LAYOUT_RARELY_USED struct hb_get_glyph_alternates_dispatch_t : hb_dispatch_context_t { @@ -2620,7 +2617,6 @@ struct hb_get_glyph_alternates_dispatch_t : ( _dispatch (obj, hb_prioritize, std::forward (ds)...) ) }; -#ifndef HB_NO_LAYOUT_RARELY_USED /** * hb_ot_layout_lookup_get_glyph_alternates: * @face: a face. @@ -2654,6 +2650,64 @@ hb_ot_layout_lookup_get_glyph_alternates (hb_face_t *face, return ret; } +struct hb_collect_glyph_alternates_dispatch_t : + hb_dispatch_context_t +{ + static return_t default_return_value () { return false; } + bool stop_sublookup_iteration (return_t r) const { return false; } + + private: + template auto + _dispatch (const T &obj, hb_priority<1>, Ts&&... ds) HB_AUTO_RETURN + ( (obj.collect_glyph_alternates (std::forward (ds)...), true) ) + template auto + _dispatch (const T &obj, hb_priority<0>, Ts&&... ds) HB_AUTO_RETURN + ( default_return_value () ) + public: + template auto + dispatch (const T &obj, Ts&&... ds) HB_AUTO_RETURN + ( _dispatch (obj, hb_prioritize, std::forward (ds)...) ) +}; + +/** + * hb_ot_layout_lookup_collect_glyph_alternates: + * @face: a face. + * @lookup_index: index of the feature lookup to query. + * @alternate_count: (inout): mapping from glyph index to number of alternates for that glyph. + * @alternate_glyphs: (inout): mapping from encoded glyph index and alternate index, to alternate glyph ids. + * + * Collects alternates of glyphs from a given GSUB lookup index. + * + * For one-to-one GSUB glyph substitutions, this function collects the + * substituted glyph. + * + * For lookups that assign multiple alternates to a glyph, all alternate glyphs are collected. + * + * For other lookup types, nothing is performed and `false` is returned. + * + * The `alternate_count` mapping will contain the number of alternates for each glyph id. + * Upon entry, this mapping should contain the glyph ids as keys, and the number of alternates + * currently known for each glyph id as values. + * + * The `alternate_glyphs` mapping will contain the alternate glyph ids for each glyph id. + * The mapping is encoded in the following way, upon entry and after processing: + * If G is the glyph id, and A0, A1, ..., A(n-1) are the alternate glyph ids, + * the mapping will contain the following entries: (G + (i << 24)) -> A(i) + * for i = 0, 1, ..., n-1 where n is the number of alternates for G as per `alternate_count`. + * + * Return value: `true` if alternates were collected, `false` otherwise. + * Since: 12.1.0 + */ +HB_EXTERN hb_bool_t +hb_ot_layout_lookup_collect_glyph_alternates (hb_face_t *face, + unsigned lookup_index, + hb_map_t *alternate_count /* IN/OUT */, + hb_map_t *alternate_glyphs /* IN/OUT */) +{ + hb_collect_glyph_alternates_dispatch_t c; + const OT::SubstLookup &lookup = face->table.GSUB->table->get_lookup (lookup_index); + return lookup.dispatch (&c, alternate_count, alternate_glyphs); +} struct hb_position_single_dispatch_t : hb_dispatch_context_t diff --git a/thirdparty/harfbuzz/src/hb-ot-layout.h b/thirdparty/harfbuzz/src/hb-ot-layout.h index 386b98d5803..22060ccf037 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout.h +++ b/thirdparty/harfbuzz/src/hb-ot-layout.h @@ -383,6 +383,12 @@ hb_ot_layout_lookup_get_glyph_alternates (hb_face_t *face, unsigned *alternate_count /* IN/OUT */, hb_codepoint_t *alternate_glyphs /* OUT */); +HB_EXTERN hb_bool_t +hb_ot_layout_lookup_collect_glyph_alternates (hb_face_t *face, + unsigned lookup_index, + hb_map_t *alternate_count /* IN/OUT */, + hb_map_t *alternate_glyphs /* IN/OUT */); + HB_EXTERN hb_bool_t hb_ot_layout_lookup_would_substitute (hb_face_t *face, unsigned int lookup_index, diff --git a/thirdparty/harfbuzz/src/hb-ot-layout.hh b/thirdparty/harfbuzz/src/hb-ot-layout.hh index a42212f291f..945e735671f 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout.hh @@ -217,8 +217,6 @@ _hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_buffer_t *buffer) if (u >= 0x80u) { - buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII; - if (unlikely (unicode->is_default_ignorable (u))) { buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES; @@ -247,6 +245,7 @@ _hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_buffer_t *buffer) if (unlikely (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (gen_cat))) { + buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_CONTINUATIONS; props |= UPROPS_MASK_CONTINUATION; props |= unicode->modified_combining_class (u)<<8; } @@ -361,8 +360,9 @@ _hb_glyph_info_unhide (hb_glyph_info_t *info) } static inline void -_hb_glyph_info_set_continuation (hb_glyph_info_t *info) +_hb_glyph_info_set_continuation (hb_glyph_info_t *info, hb_buffer_t *buffer) { + buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_CONTINUATIONS; info->unicode_props() |= UPROPS_MASK_CONTINUATION; } static inline void @@ -410,18 +410,6 @@ _hb_glyph_info_is_zwj (const hb_glyph_info_t *info) return _hb_glyph_info_is_unicode_format (info) && (info->unicode_props() & UPROPS_MASK_Cf_ZWJ); } static inline bool -_hb_glyph_info_is_joiner (const hb_glyph_info_t *info) -{ - return _hb_glyph_info_is_unicode_format (info) && (info->unicode_props() & (UPROPS_MASK_Cf_ZWNJ|UPROPS_MASK_Cf_ZWJ)); -} -static inline void -_hb_glyph_info_flip_joiners (hb_glyph_info_t *info) -{ - if (!_hb_glyph_info_is_unicode_format (info)) - return; - info->unicode_props() ^= UPROPS_MASK_Cf_ZWNJ | UPROPS_MASK_Cf_ZWJ; -} -static inline bool _hb_glyph_info_is_aat_deleted (const hb_glyph_info_t *info) { return _hb_glyph_info_is_unicode_format (info) && (info->unicode_props() & UPROPS_MASK_Cf_AAT_DELETED); @@ -657,4 +645,18 @@ _hb_buffer_assert_gsubgpos_vars (hb_buffer_t *buffer) #undef lig_props #undef glyph_props +static inline void +_hb_collect_glyph_alternates_add (hb_codepoint_t from, + hb_codepoint_t to, + hb_map_t *alternate_count, + hb_map_t *alternate_glyphs) +{ + hb_codepoint_t zero = 0; + hb_codepoint_t *i = &zero; + alternate_count->has (from, &i); + alternate_glyphs->set (from | (*i << 24), to); + alternate_count->set (from, *i + 1); +} + + #endif /* HB_OT_LAYOUT_HH */ diff --git a/thirdparty/harfbuzz/src/hb-ot-math-table.hh b/thirdparty/harfbuzz/src/hb-ot-math-table.hh index c702e42e2c7..f79808fa925 100644 --- a/thirdparty/harfbuzz/src/hb-ot-math-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-math-table.hh @@ -69,6 +69,8 @@ struct MathValueRecord struct MathConstants { + friend struct MATH; + MathConstants* copy (hb_serialize_context_t *c) const { TRACE_SERIALIZE (this); @@ -1109,8 +1111,8 @@ struct MATH { #ifndef HB_NO_MATH switch HB_CODEPOINT_ENCODE3 (font->face->table.MATH.get_blob ()->length, - get_constant (HB_OT_MATH_CONSTANT_DISPLAY_OPERATOR_MIN_HEIGHT, font), - get_constant (HB_OT_MATH_CONSTANT_DELIMITED_SUB_FORMULA_MIN_HEIGHT, font)) + (this+mathConstants).minHeight[1], // displayOperatorMinHeight + (this+mathConstants).minHeight[0]) // delimitedSubFormulaMinHeight { /* sha1sum:ab4a4fe054d23061f3c039493d6f665cfda2ecf5 cambria.ttc * sha1sum:086855301bff644f9d8827b88491fcf73a6d4cb9 cambria.ttc diff --git a/thirdparty/harfbuzz/src/hb-ot-post-macroman.hh b/thirdparty/harfbuzz/src/hb-ot-post-macroman.hh index b4df8aaeeab..269b4d3fe45 100644 --- a/thirdparty/harfbuzz/src/hb-ot-post-macroman.hh +++ b/thirdparty/harfbuzz/src/hb-ot-post-macroman.hh @@ -31,264 +31,264 @@ #endif -_S(".notdef") -_S(".null") -_S("nonmarkingreturn") -_S("space") -_S("exclam") -_S("quotedbl") -_S("numbersign") -_S("dollar") -_S("percent") -_S("ampersand") -_S("quotesingle") -_S("parenleft") -_S("parenright") -_S("asterisk") -_S("plus") -_S("comma") -_S("hyphen") -_S("period") -_S("slash") -_S("zero") -_S("one") -_S("two") -_S("three") -_S("four") -_S("five") -_S("six") -_S("seven") -_S("eight") -_S("nine") -_S("colon") -_S("semicolon") -_S("less") -_S("equal") -_S("greater") -_S("question") -_S("at") -_S("A") -_S("B") -_S("C") -_S("D") -_S("E") -_S("F") -_S("G") -_S("H") -_S("I") -_S("J") -_S("K") -_S("L") -_S("M") -_S("N") -_S("O") -_S("P") -_S("Q") -_S("R") -_S("S") -_S("T") -_S("U") -_S("V") -_S("W") -_S("X") -_S("Y") -_S("Z") -_S("bracketleft") -_S("backslash") -_S("bracketright") -_S("asciicircum") -_S("underscore") -_S("grave") -_S("a") -_S("b") -_S("c") -_S("d") -_S("e") -_S("f") -_S("g") -_S("h") -_S("i") -_S("j") -_S("k") -_S("l") -_S("m") -_S("n") -_S("o") -_S("p") -_S("q") -_S("r") -_S("s") -_S("t") -_S("u") -_S("v") -_S("w") -_S("x") -_S("y") -_S("z") -_S("braceleft") -_S("bar") -_S("braceright") -_S("asciitilde") -_S("Adieresis") -_S("Aring") -_S("Ccedilla") -_S("Eacute") -_S("Ntilde") -_S("Odieresis") -_S("Udieresis") -_S("aacute") -_S("agrave") -_S("acircumflex") -_S("adieresis") -_S("atilde") -_S("aring") -_S("ccedilla") -_S("eacute") -_S("egrave") -_S("ecircumflex") -_S("edieresis") -_S("iacute") -_S("igrave") -_S("icircumflex") -_S("idieresis") -_S("ntilde") -_S("oacute") -_S("ograve") -_S("ocircumflex") -_S("odieresis") -_S("otilde") -_S("uacute") -_S("ugrave") -_S("ucircumflex") -_S("udieresis") -_S("dagger") -_S("degree") -_S("cent") -_S("sterling") -_S("section") -_S("bullet") -_S("paragraph") -_S("germandbls") -_S("registered") -_S("copyright") -_S("trademark") -_S("acute") -_S("dieresis") -_S("notequal") -_S("AE") -_S("Oslash") -_S("infinity") -_S("plusminus") -_S("lessequal") -_S("greaterequal") -_S("yen") -_S("mu") -_S("partialdiff") -_S("summation") -_S("product") -_S("pi") -_S("integral") -_S("ordfeminine") -_S("ordmasculine") -_S("Omega") -_S("ae") -_S("oslash") -_S("questiondown") -_S("exclamdown") -_S("logicalnot") -_S("radical") -_S("florin") -_S("approxequal") -_S("Delta") -_S("guillemotleft") -_S("guillemotright") -_S("ellipsis") -_S("nonbreakingspace") -_S("Agrave") -_S("Atilde") -_S("Otilde") -_S("OE") -_S("oe") -_S("endash") -_S("emdash") -_S("quotedblleft") -_S("quotedblright") -_S("quoteleft") -_S("quoteright") -_S("divide") -_S("lozenge") -_S("ydieresis") -_S("Ydieresis") -_S("fraction") -_S("currency") -_S("guilsinglleft") -_S("guilsinglright") -_S("fi") -_S("fl") -_S("daggerdbl") -_S("periodcentered") -_S("quotesinglbase") -_S("quotedblbase") -_S("perthousand") -_S("Acircumflex") -_S("Ecircumflex") -_S("Aacute") -_S("Edieresis") -_S("Egrave") -_S("Iacute") -_S("Icircumflex") -_S("Idieresis") -_S("Igrave") -_S("Oacute") -_S("Ocircumflex") -_S("apple") -_S("Ograve") -_S("Uacute") -_S("Ucircumflex") -_S("Ugrave") -_S("dotlessi") -_S("circumflex") -_S("tilde") -_S("macron") -_S("breve") -_S("dotaccent") -_S("ring") -_S("cedilla") -_S("hungarumlaut") -_S("ogonek") -_S("caron") -_S("Lslash") -_S("lslash") -_S("Scaron") -_S("scaron") -_S("Zcaron") -_S("zcaron") -_S("brokenbar") -_S("Eth") -_S("eth") -_S("Yacute") -_S("yacute") -_S("Thorn") -_S("thorn") -_S("minus") -_S("multiply") -_S("onesuperior") -_S("twosuperior") -_S("threesuperior") -_S("onehalf") -_S("onequarter") -_S("threequarters") -_S("franc") -_S("Gbreve") -_S("gbreve") -_S("Idotaccent") -_S("Scedilla") -_S("scedilla") -_S("Cacute") -_S("cacute") -_S("Ccaron") -_S("ccaron") -_S("dcroat") +HB_STR(".notdef") +HB_STR(".null") +HB_STR("nonmarkingreturn") +HB_STR("space") +HB_STR("exclam") +HB_STR("quotedbl") +HB_STR("numbersign") +HB_STR("dollar") +HB_STR("percent") +HB_STR("ampersand") +HB_STR("quotesingle") +HB_STR("parenleft") +HB_STR("parenright") +HB_STR("asterisk") +HB_STR("plus") +HB_STR("comma") +HB_STR("hyphen") +HB_STR("period") +HB_STR("slash") +HB_STR("zero") +HB_STR("one") +HB_STR("two") +HB_STR("three") +HB_STR("four") +HB_STR("five") +HB_STR("six") +HB_STR("seven") +HB_STR("eight") +HB_STR("nine") +HB_STR("colon") +HB_STR("semicolon") +HB_STR("less") +HB_STR("equal") +HB_STR("greater") +HB_STR("question") +HB_STR("at") +HB_STR("A") +HB_STR("B") +HB_STR("C") +HB_STR("D") +HB_STR("E") +HB_STR("F") +HB_STR("G") +HB_STR("H") +HB_STR("I") +HB_STR("J") +HB_STR("K") +HB_STR("L") +HB_STR("M") +HB_STR("N") +HB_STR("O") +HB_STR("P") +HB_STR("Q") +HB_STR("R") +HB_STR("S") +HB_STR("T") +HB_STR("U") +HB_STR("V") +HB_STR("W") +HB_STR("X") +HB_STR("Y") +HB_STR("Z") +HB_STR("bracketleft") +HB_STR("backslash") +HB_STR("bracketright") +HB_STR("asciicircum") +HB_STR("underscore") +HB_STR("grave") +HB_STR("a") +HB_STR("b") +HB_STR("c") +HB_STR("d") +HB_STR("e") +HB_STR("f") +HB_STR("g") +HB_STR("h") +HB_STR("i") +HB_STR("j") +HB_STR("k") +HB_STR("l") +HB_STR("m") +HB_STR("n") +HB_STR("o") +HB_STR("p") +HB_STR("q") +HB_STR("r") +HB_STR("s") +HB_STR("t") +HB_STR("u") +HB_STR("v") +HB_STR("w") +HB_STR("x") +HB_STR("y") +HB_STR("z") +HB_STR("braceleft") +HB_STR("bar") +HB_STR("braceright") +HB_STR("asciitilde") +HB_STR("Adieresis") +HB_STR("Aring") +HB_STR("Ccedilla") +HB_STR("Eacute") +HB_STR("Ntilde") +HB_STR("Odieresis") +HB_STR("Udieresis") +HB_STR("aacute") +HB_STR("agrave") +HB_STR("acircumflex") +HB_STR("adieresis") +HB_STR("atilde") +HB_STR("aring") +HB_STR("ccedilla") +HB_STR("eacute") +HB_STR("egrave") +HB_STR("ecircumflex") +HB_STR("edieresis") +HB_STR("iacute") +HB_STR("igrave") +HB_STR("icircumflex") +HB_STR("idieresis") +HB_STR("ntilde") +HB_STR("oacute") +HB_STR("ograve") +HB_STR("ocircumflex") +HB_STR("odieresis") +HB_STR("otilde") +HB_STR("uacute") +HB_STR("ugrave") +HB_STR("ucircumflex") +HB_STR("udieresis") +HB_STR("dagger") +HB_STR("degree") +HB_STR("cent") +HB_STR("sterling") +HB_STR("section") +HB_STR("bullet") +HB_STR("paragraph") +HB_STR("germandbls") +HB_STR("registered") +HB_STR("copyright") +HB_STR("trademark") +HB_STR("acute") +HB_STR("dieresis") +HB_STR("notequal") +HB_STR("AE") +HB_STR("Oslash") +HB_STR("infinity") +HB_STR("plusminus") +HB_STR("lessequal") +HB_STR("greaterequal") +HB_STR("yen") +HB_STR("mu") +HB_STR("partialdiff") +HB_STR("summation") +HB_STR("product") +HB_STR("pi") +HB_STR("integral") +HB_STR("ordfeminine") +HB_STR("ordmasculine") +HB_STR("Omega") +HB_STR("ae") +HB_STR("oslash") +HB_STR("questiondown") +HB_STR("exclamdown") +HB_STR("logicalnot") +HB_STR("radical") +HB_STR("florin") +HB_STR("approxequal") +HB_STR("Delta") +HB_STR("guillemotleft") +HB_STR("guillemotright") +HB_STR("ellipsis") +HB_STR("nonbreakingspace") +HB_STR("Agrave") +HB_STR("Atilde") +HB_STR("Otilde") +HB_STR("OE") +HB_STR("oe") +HB_STR("endash") +HB_STR("emdash") +HB_STR("quotedblleft") +HB_STR("quotedblright") +HB_STR("quoteleft") +HB_STR("quoteright") +HB_STR("divide") +HB_STR("lozenge") +HB_STR("ydieresis") +HB_STR("Ydieresis") +HB_STR("fraction") +HB_STR("currency") +HB_STR("guilsinglleft") +HB_STR("guilsinglright") +HB_STR("fi") +HB_STR("fl") +HB_STR("daggerdbl") +HB_STR("periodcentered") +HB_STR("quotesinglbase") +HB_STR("quotedblbase") +HB_STR("perthousand") +HB_STR("Acircumflex") +HB_STR("Ecircumflex") +HB_STR("Aacute") +HB_STR("Edieresis") +HB_STR("Egrave") +HB_STR("Iacute") +HB_STR("Icircumflex") +HB_STR("Idieresis") +HB_STR("Igrave") +HB_STR("Oacute") +HB_STR("Ocircumflex") +HB_STR("apple") +HB_STR("Ograve") +HB_STR("Uacute") +HB_STR("Ucircumflex") +HB_STR("Ugrave") +HB_STR("dotlessi") +HB_STR("circumflex") +HB_STR("tilde") +HB_STR("macron") +HB_STR("breve") +HB_STR("dotaccent") +HB_STR("ring") +HB_STR("cedilla") +HB_STR("hungarumlaut") +HB_STR("ogonek") +HB_STR("caron") +HB_STR("Lslash") +HB_STR("lslash") +HB_STR("Scaron") +HB_STR("scaron") +HB_STR("Zcaron") +HB_STR("zcaron") +HB_STR("brokenbar") +HB_STR("Eth") +HB_STR("eth") +HB_STR("Yacute") +HB_STR("yacute") +HB_STR("Thorn") +HB_STR("thorn") +HB_STR("minus") +HB_STR("multiply") +HB_STR("onesuperior") +HB_STR("twosuperior") +HB_STR("threesuperior") +HB_STR("onehalf") +HB_STR("onequarter") +HB_STR("threequarters") +HB_STR("franc") +HB_STR("Gbreve") +HB_STR("gbreve") +HB_STR("Idotaccent") +HB_STR("Scedilla") +HB_STR("scedilla") +HB_STR("Cacute") +HB_STR("cacute") +HB_STR("Ccaron") +HB_STR("ccaron") +HB_STR("dcroat") #endif /* HB_OT_POST_MACROMAN_HH */ diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-fallback.cc b/thirdparty/harfbuzz/src/hb-ot-shape-fallback.cc index 6ddf7982b5b..ce7e0c03b47 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape-fallback.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shape-fallback.cc @@ -409,16 +409,13 @@ position_around_base (const hb_ot_shape_plan_t *plan, } static inline void -position_cluster (const hb_ot_shape_plan_t *plan, - hb_font_t *font, - hb_buffer_t *buffer, - unsigned int start, - unsigned int end, - bool adjust_offsets_when_zeroing) +position_cluster_impl (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer, + unsigned int start, + unsigned int end, + bool adjust_offsets_when_zeroing) { - if (end - start < 2) - return; - /* Find the base glyph */ hb_glyph_info_t *info = buffer->info; for (unsigned int i = start; i < end; i++) @@ -441,6 +438,20 @@ position_cluster (const hb_ot_shape_plan_t *plan, } } +static HB_ALWAYS_INLINE void +position_cluster (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer, + unsigned int start, + unsigned int end, + bool adjust_offsets_when_zeroing) +{ + if (end - start < 2) + return; + + position_cluster_impl (plan, font, buffer, start, end, adjust_offsets_when_zeroing); +} + void _hb_ot_shape_fallback_mark_position (const hb_ot_shape_plan_t *plan, hb_font_t *font, diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-normalize.cc b/thirdparty/harfbuzz/src/hb-ot-shape-normalize.cc index 2d093f78b33..e9dbcd77aea 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape-normalize.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shape-normalize.cc @@ -78,14 +78,14 @@ static inline void set_glyph (hb_glyph_info_t &info, hb_font_t *font) { - (void) font->get_nominal_glyph (info.codepoint, &info.glyph_index()); + (void) font->get_nominal_glyph (info.codepoint, &info.normalizer_glyph_index()); } static inline void output_char (hb_buffer_t *buffer, hb_codepoint_t unichar, hb_codepoint_t glyph) { /* This is very confusing indeed. */ - buffer->cur().glyph_index() = glyph; + buffer->cur().normalizer_glyph_index() = glyph; (void) buffer->output_glyph (unichar); _hb_glyph_info_set_unicode_props (&buffer->prev(), buffer); } @@ -93,7 +93,7 @@ output_char (hb_buffer_t *buffer, hb_codepoint_t unichar, hb_codepoint_t glyph) static inline void next_char (hb_buffer_t *buffer, hb_codepoint_t glyph) { - buffer->cur().glyph_index() = glyph; + buffer->cur().normalizer_glyph_index() = glyph; (void) buffer->next_glyph (); } @@ -210,7 +210,7 @@ handle_variation_selector_cluster (const hb_ot_shape_normalize_context_t *c, hb_font_t * const font = c->font; for (; buffer->idx < end - 1 && buffer->successful;) { if (unlikely (buffer->unicode->is_variation_selector (buffer->cur(+1).codepoint))) { - if (font->get_variation_glyph (buffer->cur().codepoint, buffer->cur(+1).codepoint, &buffer->cur().glyph_index())) + if (font->get_variation_glyph (buffer->cur().codepoint, buffer->cur(+1).codepoint, &buffer->cur().normalizer_glyph_index())) { hb_codepoint_t unicode = buffer->cur().codepoint; (void) buffer->replace_glyphs (2, 1, &unicode); @@ -342,7 +342,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan, unsigned int done = font->get_nominal_glyphs (end - buffer->idx, &buffer->cur().codepoint, sizeof (buffer->info[0]), - &buffer->cur().glyph_index(), + &buffer->cur().normalizer_glyph_index(), sizeof (buffer->info[0])); if (unlikely (!buffer->next_glyphs (done))) break; } @@ -456,7 +456,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan, 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; + buffer->out_info[starter].normalizer_glyph_index() = glyph; _hb_glyph_info_set_unicode_props (&buffer->out_info[starter], buffer); continue; diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-normalize.hh b/thirdparty/harfbuzz/src/hb-ot-shape-normalize.hh index f12cb35c0fe..2f282f34754 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape-normalize.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shape-normalize.hh @@ -32,7 +32,7 @@ /* buffer var allocations, used during the normalization process */ -#define glyph_index() var1.u32 +#define normalizer_glyph_index() var1.u32 struct hb_ot_shape_plan_t; diff --git a/thirdparty/harfbuzz/src/hb-ot-shape.cc b/thirdparty/harfbuzz/src/hb-ot-shape.cc index 6ee0e2b7f9d..f43ff9f922d 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shape.cc @@ -484,6 +484,9 @@ hb_set_unicode_props (hb_buffer_t *buffer) { _hb_glyph_info_set_unicode_props (&info[i], buffer); + if (info[i].codepoint < 0x80) + continue; + unsigned gen_cat = _hb_glyph_info_get_general_category (&info[i]); if (FLAG_UNSAFE (gen_cat) & (FLAG (HB_UNICODE_GENERAL_CATEGORY_LOWERCASE_LETTER) | @@ -498,7 +501,7 @@ hb_set_unicode_props (hb_buffer_t *buffer) if (unlikely (gen_cat == HB_UNICODE_GENERAL_CATEGORY_MODIFIER_SYMBOL && hb_in_range (info[i].codepoint, 0x1F3FBu, 0x1F3FFu))) { - _hb_glyph_info_set_continuation (&info[i]); + _hb_glyph_info_set_continuation (&info[i], buffer); } /* Regional_Indicators are hairy as hell... * https://github.com/harfbuzz/harfbuzz/issues/2265 */ @@ -506,18 +509,18 @@ hb_set_unicode_props (hb_buffer_t *buffer) { if (_hb_codepoint_is_regional_indicator (info[i - 1].codepoint) && !_hb_glyph_info_is_continuation (&info[i - 1])) - _hb_glyph_info_set_continuation (&info[i]); + _hb_glyph_info_set_continuation (&info[i], buffer); } #ifndef HB_NO_EMOJI_SEQUENCES else if (unlikely (_hb_glyph_info_is_zwj (&info[i]))) { - _hb_glyph_info_set_continuation (&info[i]); + _hb_glyph_info_set_continuation (&info[i], buffer); if (i + 1 < count && _hb_unicode_is_emoji_Extended_Pictographic (info[i + 1].codepoint)) { i++; _hb_glyph_info_set_unicode_props (&info[i], buffer); - _hb_glyph_info_set_continuation (&info[i]); + _hb_glyph_info_set_continuation (&info[i], buffer); } } #endif @@ -536,7 +539,9 @@ hb_set_unicode_props (hb_buffer_t *buffer) * https://github.com/harfbuzz/harfbuzz/issues/3844 */ else if (unlikely (hb_in_ranges (info[i].codepoint, 0xFF9Eu, 0xFF9Fu, 0xE0020u, 0xE007Fu))) - _hb_glyph_info_set_continuation (&info[i]); + _hb_glyph_info_set_continuation (&info[i], buffer); + else if (unlikely (info[i].codepoint == 0x2044u /* FRACTION SLASH */)) + buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_FRACTION_SLASH; } } @@ -572,7 +577,7 @@ hb_insert_dotted_circle (hb_buffer_t *buffer, hb_font_t *font) static void hb_form_clusters (hb_buffer_t *buffer) { - if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII)) + if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_CONTINUATIONS)) return; if (HB_BUFFER_CLUSTER_LEVEL_IS_GRAPHEMES (buffer->cluster_level)) @@ -614,14 +619,14 @@ hb_ensure_native_direction (hb_buffer_t *buffer) for (unsigned i = 0; i < count; i++) { auto gc = _hb_glyph_info_get_general_category (&info[i]); - if (gc == HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER) - found_number = true; - else if (HB_UNICODE_GENERAL_CATEGORY_IS_LETTER (gc)) + if (HB_UNICODE_GENERAL_CATEGORY_IS_LETTER (gc)) { found_letter = true; break; } - else if (_hb_codepoint_is_regional_indicator (info[i].codepoint)) + else if (gc == HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER) + found_number = true; + else if (unlikely (_hb_codepoint_is_regional_indicator (info[i].codepoint))) found_ri = true; } if ((found_number || found_ri) && !found_letter) @@ -687,7 +692,7 @@ hb_ot_shape_setup_masks_fraction (const hb_ot_shape_context_t *c) return; #endif - if (!(c->buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII) || + if (!(c->buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_FRACTION_SLASH) || !c->plan->has_frac) return; @@ -788,7 +793,13 @@ hb_ot_zero_width_default_ignorables (const hb_buffer_t *buffer) unsigned int i = 0; for (i = 0; i < count; i++) if (unlikely (_hb_glyph_info_is_default_ignorable (&info[i]))) - pos[i].x_advance = pos[i].y_advance = pos[i].x_offset = pos[i].y_offset = 0; + { + pos[i].x_advance = pos[i].y_advance = 0; + if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction)) + pos[i].x_offset = 0; + else + pos[i].y_offset = 0; + } } static void @@ -843,11 +854,11 @@ hb_ot_hide_default_ignorables (hb_buffer_t *buffer, static inline void hb_ot_map_glyphs_fast (hb_buffer_t *buffer) { - /* Normalization process sets up glyph_index(), we just copy it. */ + /* Normalization process sets up normalizer_glyph_index(), we just copy it. */ unsigned int count = buffer->len; hb_glyph_info_t *info = buffer->info; for (unsigned int i = 0; i < count; i++) - info[i].codepoint = info[i].glyph_index(); + info[i].codepoint = info[i].normalizer_glyph_index(); buffer->content_type = HB_BUFFER_CONTENT_TYPE_GLYPHS; } @@ -885,7 +896,7 @@ hb_ot_substitute_default (const hb_ot_shape_context_t *c) hb_ot_rotate_chars (c); - HB_BUFFER_ALLOCATE_VAR (buffer, glyph_index); + HB_BUFFER_ALLOCATE_VAR (buffer, normalizer_glyph_index); _hb_ot_shape_normalize (c->plan, buffer, c->font); @@ -897,7 +908,7 @@ hb_ot_substitute_default (const hb_ot_shape_context_t *c) hb_ot_map_glyphs_fast (buffer); - HB_BUFFER_DEALLOCATE_VAR (buffer, glyph_index); + HB_BUFFER_DEALLOCATE_VAR (buffer, normalizer_glyph_index); } static inline void @@ -912,11 +923,17 @@ hb_ot_substitute_plan (const hb_ot_shape_context_t *c) #ifndef HB_NO_AAT_SHAPE if (unlikely (c->plan->apply_morx)) + { hb_aat_layout_substitute (c->plan, c->font, c->buffer, c->user_features, c->num_user_features); + c->buffer->update_digest (); + } else #endif + { + c->buffer->update_digest (); c->plan->substitute (c->font, buffer); + } } static inline void @@ -1098,8 +1115,33 @@ hb_propagate_flags (hb_buffer_t *buffer) /* Propagate cluster-level glyph flags to be the same on all cluster glyphs. * Simplifies using them. */ - if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS)) + hb_mask_t and_mask = HB_GLYPH_FLAG_DEFINED; + if ((buffer->flags & HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT) == 0) + and_mask &= ~HB_GLYPH_FLAG_UNSAFE_TO_CONCAT; + + hb_glyph_info_t *info = buffer->info; + + if ((buffer->flags & HB_BUFFER_FLAG_PRODUCE_SAFE_TO_INSERT_TATWEEL) == 0) + { + foreach_cluster (buffer, start, end) + { + if (end - start == 1) + { + info[start].mask &= and_mask; + continue; + } + + unsigned int mask = 0; + for (unsigned int i = start; i < end; i++) + mask |= info[i].mask; + + mask &= and_mask; + + for (unsigned int i = start; i < end; i++) + info[i].mask = mask; + } return; + } /* If we are producing SAFE_TO_INSERT_TATWEEL, then do two things: * @@ -1107,30 +1149,20 @@ hb_propagate_flags (hb_buffer_t *buffer) * are UNSAFE_TO_BREAK, then clear the SAFE_TO_INSERT_TATWEEL, * - Any place that is SAFE_TO_INSERT_TATWEEL, is also now UNSAFE_TO_BREAK. * - * We couldn't make this interaction earlier. It has to be done here. + * We couldn't make this interaction earlier. It has to be done this way. */ - bool flip_tatweel = buffer->flags & HB_BUFFER_FLAG_PRODUCE_SAFE_TO_INSERT_TATWEEL; - - bool clear_concat = (buffer->flags & HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT) == 0; - - hb_glyph_info_t *info = buffer->info; - foreach_cluster (buffer, start, end) { unsigned int mask = 0; for (unsigned int i = start; i < end; i++) - mask |= info[i].mask & HB_GLYPH_FLAG_DEFINED; + mask |= info[i].mask; - if (flip_tatweel) - { - if (mask & HB_GLYPH_FLAG_UNSAFE_TO_BREAK) - mask &= ~HB_GLYPH_FLAG_SAFE_TO_INSERT_TATWEEL; - if (mask & HB_GLYPH_FLAG_SAFE_TO_INSERT_TATWEEL) - mask |= HB_GLYPH_FLAG_UNSAFE_TO_BREAK | HB_GLYPH_FLAG_UNSAFE_TO_CONCAT; - } + if (mask & HB_GLYPH_FLAG_UNSAFE_TO_BREAK) + mask &= ~HB_GLYPH_FLAG_SAFE_TO_INSERT_TATWEEL; + if (mask & HB_GLYPH_FLAG_SAFE_TO_INSERT_TATWEEL) + mask |= HB_GLYPH_FLAG_UNSAFE_TO_BREAK | HB_GLYPH_FLAG_UNSAFE_TO_CONCAT; - if (clear_concat) - mask &= ~HB_GLYPH_FLAG_UNSAFE_TO_CONCAT; + mask &= and_mask; for (unsigned int i = start; i < end; i++) info[i].mask = mask; @@ -1171,8 +1203,6 @@ hb_ot_shape_internal (hb_ot_shape_context_t *c) _hb_buffer_deallocate_unicode_vars (c->buffer); c->buffer->props.direction = c->target_direction; - - c->buffer->leave (); } diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-arabic-joining-list.hh b/thirdparty/harfbuzz/src/hb-ot-shaper-arabic-joining-list.hh index e38686e3ebb..79d3014d3e1 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-arabic-joining-list.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-arabic-joining-list.hh @@ -6,10 +6,10 @@ * * on files with these headers: * - * # ArabicShaping-16.0.0.txt - * # Date: 2024-07-30 - * # Scripts-16.0.0.txt - * # Date: 2024-04-30, 21:48:40 GMT + * # ArabicShaping-17.0.0.txt + * # Date: 2025-08-14 + * # Scripts-17.0.0.txt + * # Date: 2025-07-24, 13:28:55 GMT */ #ifndef HB_OT_SHAPER_ARABIC_JOINING_LIST_HH diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-arabic-table.hh b/thirdparty/harfbuzz/src/hb-ot-shaper-arabic-table.hh index d9917a15874..09289d27df8 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-arabic-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-arabic-table.hh @@ -6,10 +6,10 @@ * * on files with these headers: * - * # ArabicShaping-16.0.0.txt - * # Date: 2024-07-30 - * # Blocks-16.0.0.txt - * # Date: 2024-02-02 + * # ArabicShaping-17.0.0.txt + * # Date: 2025-08-14 + * # Blocks-17.0.0.txt + * # Date: 2025-08-01 * UnicodeData.txt does not have a header. */ @@ -80,7 +80,7 @@ static const uint8_t joining_table[] = /* Arabic Extended-B */ /* 0860 */ R,R,R,R,R,R,R,R,R,R,R,R,R,R,R,R, - /* 0880 */ R,R,R,C,C,C,D,U,U,D,D,D,D,D,R,X,U,U,X,X,X,X,X,X,X,X,X,X,X,X,X,X, + /* 0880 */ R,R,R,C,C,C,D,U,U,D,D,D,D,D,R,D,U,U,X,X,X,X,X,X,X,X,X,X,X,X,X,X, /* Arabic Extended-A */ @@ -140,9 +140,9 @@ static const uint8_t joining_table[] = /* Arabic Extended-C */ - /* 10EC0 */ R,D,D, + /* 10EC0 */ R,D,D,X,D,D, -#define joining_offset_0x10f30u 1185 +#define joining_offset_0x10f30u 1188 /* Sogdian */ @@ -161,14 +161,14 @@ static const uint8_t joining_table[] = /* 10FA0 */ D,U,D,D,R,R,R,U,D,R,R,D,D,R,D,D, /* 10FC0 */ U,D,R,R,D,U,U,U,U,R,D,L, -#define joining_offset_0x110bdu 1341 +#define joining_offset_0x110bdu 1344 /* Kaithi */ /* 110A0 */ U,X,X, /* 110C0 */ X,X,X,X,X,X,X,X,X,X,X,X,X,U, -#define joining_offset_0x1e900u 1358 +#define joining_offset_0x1e900u 1361 /* Adlam */ @@ -176,7 +176,7 @@ static const uint8_t joining_table[] = /* 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,X,X,X,X,X,X,X,T, -}; /* Table items: 1434; occupancy: 57% */ +}; /* Table items: 1437; occupancy: 58% */ static unsigned int @@ -204,7 +204,7 @@ joining_type (hb_codepoint_t u) if (hb_in_range (u, 0x10AC0u, 0x10AEFu)) return joining_table[u - 0x10AC0u + joining_offset_0x10ac0u]; if (hb_in_range (u, 0x10B80u, 0x10BAFu)) return joining_table[u - 0x10B80u + joining_offset_0x10b80u]; if (hb_in_range (u, 0x10D00u, 0x10D23u)) return joining_table[u - 0x10D00u + joining_offset_0x10d00u]; - if (hb_in_range (u, 0x10EC2u, 0x10EC4u)) return joining_table[u - 0x10EC2u + joining_offset_0x10ec2u]; + if (hb_in_range (u, 0x10EC2u, 0x10EC7u)) return joining_table[u - 0x10EC2u + joining_offset_0x10ec2u]; if (hb_in_range (u, 0x10F30u, 0x10FCBu)) return joining_table[u - 0x10F30u + joining_offset_0x10f30u]; break; diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-indic-machine.hh b/thirdparty/harfbuzz/src/hb-ot-shaper-indic-machine.hh index 6ff65c30a33..92fb64ad07e 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-indic-machine.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-indic-machine.hh @@ -53,7 +53,7 @@ enum indic_syllable_type_t { }; -#line 57 "hb-ot-shaper-indic-machine.hh" +#line 54 "hb-ot-shaper-indic-machine.hh" #define indic_syllable_machine_ex_A 9u #define indic_syllable_machine_ex_C 1u #define indic_syllable_machine_ex_CM 16u @@ -77,7 +77,7 @@ enum indic_syllable_type_t { #define indic_syllable_machine_ex_ZWNJ 5u -#line 81 "hb-ot-shaper-indic-machine.hh" +#line 76 "hb-ot-shaper-indic-machine.hh" static const unsigned char _indic_syllable_machine_trans_keys[] = { 8u, 57u, 4u, 57u, 5u, 57u, 5u, 57u, 13u, 13u, 4u, 57u, 4u, 57u, 4u, 57u, 8u, 57u, 5u, 57u, 5u, 57u, 13u, 13u, 4u, 57u, 4u, 57u, 4u, 57u, 4u, 57u, @@ -1126,7 +1126,7 @@ find_syllables_indic (hb_buffer_t *buffer) int cs; hb_glyph_info_t *info = buffer->info; -#line 1130 "hb-ot-shaper-indic-machine.hh" +#line 1119 "hb-ot-shaper-indic-machine.hh" { cs = indic_syllable_machine_start; ts = 0; @@ -1142,7 +1142,7 @@ find_syllables_indic (hb_buffer_t *buffer) unsigned int syllable_serial = 1; -#line 1146 "hb-ot-shaper-indic-machine.hh" +#line 1131 "hb-ot-shaper-indic-machine.hh" { int _slen; int _trans; @@ -1156,7 +1156,7 @@ _resume: #line 1 "NONE" {ts = p;} break; -#line 1160 "hb-ot-shaper-indic-machine.hh" +#line 1143 "hb-ot-shaper-indic-machine.hh" } _keys = _indic_syllable_machine_trans_keys + (cs<<1); @@ -1268,7 +1268,7 @@ _eof_trans: #line 117 "hb-ot-shaper-indic-machine.rl" {act = 7;} break; -#line 1272 "hb-ot-shaper-indic-machine.hh" +#line 1232 "hb-ot-shaper-indic-machine.hh" } _again: @@ -1277,7 +1277,7 @@ _again: #line 1 "NONE" {ts = 0;} break; -#line 1281 "hb-ot-shaper-indic-machine.hh" +#line 1239 "hb-ot-shaper-indic-machine.hh" } if ( ++p != pe ) diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-indic-table.cc b/thirdparty/harfbuzz/src/hb-ot-shaper-indic-table.cc index b87c530853b..bf27efee21b 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-indic-table.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-indic-table.cc @@ -6,12 +6,12 @@ * * on files with these headers: * - * # IndicSyllabicCategory-16.0.0.txt - * # Date: 2024-04-30, 21:48:21 GMT - * # IndicPositionalCategory-16.0.0.txt - * # Date: 2024-04-30, 21:48:21 GMT - * # Blocks-16.0.0.txt - * # Date: 2024-02-02 + * # IndicSyllabicCategory-17.0.0.txt + * # Date: 2025-08-01, 04:02:23 GMT + * # IndicPositionalCategory-17.0.0.txt + * # Date: 2025-07-29, 13:35:52 GMT + * # Blocks-17.0.0.txt + * # Date: 2025-08-01 */ #include "hb.hh" diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-khmer-machine.hh b/thirdparty/harfbuzz/src/hb-ot-shaper-khmer-machine.hh index f1e7a91f050..848ed231f71 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-khmer-machine.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-khmer-machine.hh @@ -48,7 +48,7 @@ enum khmer_syllable_type_t { }; -#line 52 "hb-ot-shaper-khmer-machine.hh" +#line 49 "hb-ot-shaper-khmer-machine.hh" #define khmer_syllable_machine_ex_C 1u #define khmer_syllable_machine_ex_DOTTEDCIRCLE 11u #define khmer_syllable_machine_ex_H 4u @@ -66,7 +66,7 @@ enum khmer_syllable_type_t { #define khmer_syllable_machine_ex_ZWNJ 5u -#line 70 "hb-ot-shaper-khmer-machine.hh" +#line 65 "hb-ot-shaper-khmer-machine.hh" static const unsigned char _khmer_syllable_machine_trans_keys[] = { 5u, 26u, 5u, 26u, 1u, 15u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 1u, 15u, 5u, 26u, 5u, 26u, @@ -294,7 +294,7 @@ find_syllables_khmer (hb_buffer_t *buffer) int cs; hb_glyph_info_t *info = buffer->info; -#line 298 "hb-ot-shaper-khmer-machine.hh" +#line 287 "hb-ot-shaper-khmer-machine.hh" { cs = khmer_syllable_machine_start; ts = 0; @@ -310,7 +310,7 @@ find_syllables_khmer (hb_buffer_t *buffer) unsigned int syllable_serial = 1; -#line 314 "hb-ot-shaper-khmer-machine.hh" +#line 299 "hb-ot-shaper-khmer-machine.hh" { int _slen; int _trans; @@ -324,7 +324,7 @@ _resume: #line 1 "NONE" {ts = p;} break; -#line 328 "hb-ot-shaper-khmer-machine.hh" +#line 311 "hb-ot-shaper-khmer-machine.hh" } _keys = _khmer_syllable_machine_trans_keys + (cs<<1); @@ -394,7 +394,7 @@ _eof_trans: #line 98 "hb-ot-shaper-khmer-machine.rl" {act = 3;} break; -#line 398 "hb-ot-shaper-khmer-machine.hh" +#line 368 "hb-ot-shaper-khmer-machine.hh" } _again: @@ -403,7 +403,7 @@ _again: #line 1 "NONE" {ts = 0;} break; -#line 407 "hb-ot-shaper-khmer-machine.hh" +#line 375 "hb-ot-shaper-khmer-machine.hh" } if ( ++p != pe ) diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-myanmar-machine.hh b/thirdparty/harfbuzz/src/hb-ot-shaper-myanmar-machine.hh index 4b8da586d37..292bc9f3dfc 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-myanmar-machine.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-myanmar-machine.hh @@ -50,7 +50,7 @@ enum myanmar_syllable_type_t { }; -#line 54 "hb-ot-shaper-myanmar-machine.hh" +#line 51 "hb-ot-shaper-myanmar-machine.hh" #define myanmar_syllable_machine_ex_A 9u #define myanmar_syllable_machine_ex_As 32u #define myanmar_syllable_machine_ex_C 1u @@ -78,7 +78,7 @@ enum myanmar_syllable_type_t { #define myanmar_syllable_machine_ex_ZWNJ 5u -#line 82 "hb-ot-shaper-myanmar-machine.hh" +#line 77 "hb-ot-shaper-myanmar-machine.hh" static const unsigned char _myanmar_syllable_machine_trans_keys[] = { 1u, 57u, 3u, 57u, 5u, 57u, 5u, 57u, 3u, 57u, 5u, 57u, 3u, 57u, 3u, 57u, 3u, 57u, 3u, 57u, 3u, 57u, 5u, 57u, 1u, 15u, 3u, 57u, 3u, 57u, 3u, 57u, @@ -549,7 +549,7 @@ find_syllables_myanmar (hb_buffer_t *buffer) int cs; hb_glyph_info_t *info = buffer->info; -#line 553 "hb-ot-shaper-myanmar-machine.hh" +#line 542 "hb-ot-shaper-myanmar-machine.hh" { cs = myanmar_syllable_machine_start; ts = 0; @@ -565,7 +565,7 @@ find_syllables_myanmar (hb_buffer_t *buffer) unsigned int syllable_serial = 1; -#line 569 "hb-ot-shaper-myanmar-machine.hh" +#line 554 "hb-ot-shaper-myanmar-machine.hh" { int _slen; int _trans; @@ -579,7 +579,7 @@ _resume: #line 1 "NONE" {ts = p;} break; -#line 583 "hb-ot-shaper-myanmar-machine.hh" +#line 566 "hb-ot-shaper-myanmar-machine.hh" } _keys = _myanmar_syllable_machine_trans_keys + (cs<<1); @@ -649,7 +649,7 @@ _eof_trans: #line 113 "hb-ot-shaper-myanmar-machine.rl" {act = 3;} break; -#line 653 "hb-ot-shaper-myanmar-machine.hh" +#line 623 "hb-ot-shaper-myanmar-machine.hh" } _again: @@ -658,7 +658,7 @@ _again: #line 1 "NONE" {ts = 0;} break; -#line 662 "hb-ot-shaper-myanmar-machine.hh" +#line 630 "hb-ot-shaper-myanmar-machine.hh" } if ( ++p != pe ) diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-thai.cc b/thirdparty/harfbuzz/src/hb-ot-shaper-thai.cc index 6d293b5c489..9487e1c5b01 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-thai.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-thai.cc @@ -191,7 +191,7 @@ static const struct thai_above_state_machine_edge_t { }; -static enum thai_below_state_t +static const enum thai_below_state_t { B0, /* No descender */ B1, /* Removable descender */ @@ -334,7 +334,7 @@ preprocess_text_thai (const hb_ot_shape_plan_t *plan, /* Is SARA AM. Decompose and reorder. */ (void) buffer->output_glyph (NIKHAHIT_FROM_SARA_AM (u)); - _hb_glyph_info_set_continuation (&buffer->prev()); + _hb_glyph_info_set_continuation (&buffer->prev(), buffer); if (unlikely (!buffer->replace_glyph (SARA_AA_FROM_SARA_AM (u)))) break; /* Make Nikhahit be recognized as a ccc=0 mark when zeroing widths. */ diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-use-machine.hh b/thirdparty/harfbuzz/src/hb-ot-shaper-use-machine.hh index 65b6adc36d9..5072e4d38ee 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-use-machine.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-use-machine.hh @@ -53,7 +53,7 @@ enum use_syllable_type_t { }; -#line 57 "hb-ot-shaper-use-machine.hh" +#line 54 "hb-ot-shaper-use-machine.hh" #define use_syllable_machine_ex_B 1u #define use_syllable_machine_ex_CGJ 6u #define use_syllable_machine_ex_CMAbv 31u @@ -100,7 +100,7 @@ enum use_syllable_type_t { #define use_syllable_machine_ex_ZWNJ 14u -#line 104 "hb-ot-shaper-use-machine.hh" +#line 99 "hb-ot-shaper-use-machine.hh" static const unsigned char _use_syllable_machine_trans_keys[] = { 49u, 51u, 0u, 56u, 11u, 56u, 11u, 56u, 1u, 53u, 14u, 48u, 14u, 47u, 14u, 47u, 14u, 47u, 14u, 46u, 14u, 46u, 14u, 14u, 14u, 48u, 14u, 48u, 14u, 48u, 1u, 14u, @@ -929,7 +929,7 @@ find_syllables_use (hb_buffer_t *buffer) unsigned int act HB_UNUSED; int cs; -#line 933 "hb-ot-shaper-use-machine.hh" +#line 922 "hb-ot-shaper-use-machine.hh" { cs = use_syllable_machine_start; ts = 0; @@ -942,7 +942,7 @@ find_syllables_use (hb_buffer_t *buffer) unsigned int syllable_serial = 1; -#line 946 "hb-ot-shaper-use-machine.hh" +#line 931 "hb-ot-shaper-use-machine.hh" { int _slen; int _trans; @@ -956,7 +956,7 @@ _resume: #line 1 "NONE" {ts = p;} break; -#line 960 "hb-ot-shaper-use-machine.hh" +#line 943 "hb-ot-shaper-use-machine.hh" } _keys = _use_syllable_machine_trans_keys + (cs<<1); @@ -1078,7 +1078,7 @@ _eof_trans: #line 181 "hb-ot-shaper-use-machine.rl" {act = 9;} break; -#line 1082 "hb-ot-shaper-use-machine.hh" +#line 1039 "hb-ot-shaper-use-machine.hh" } _again: @@ -1087,7 +1087,7 @@ _again: #line 1 "NONE" {ts = 0;} break; -#line 1091 "hb-ot-shaper-use-machine.hh" +#line 1046 "hb-ot-shaper-use-machine.hh" } if ( ++p != pe ) diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-use-table.hh b/thirdparty/harfbuzz/src/hb-ot-shaper-use-table.hh index eac7f5c0a09..aa16a649986 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-use-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-use-table.hh @@ -6,18 +6,18 @@ * * on files with these headers: * - * # IndicSyllabicCategory-16.0.0.txt - * # Date: 2024-04-30, 21:48:21 GMT - * # IndicPositionalCategory-16.0.0.txt - * # Date: 2024-04-30, 21:48:21 GMT - * # ArabicShaping-16.0.0.txt - * # Date: 2024-07-30 - * # DerivedCoreProperties-16.0.0.txt - * # Date: 2024-05-31, 18:09:32 GMT - * # Blocks-16.0.0.txt - * # Date: 2024-02-02 - * # Scripts-16.0.0.txt - * # Date: 2024-04-30, 21:48:40 GMT + * # IndicSyllabicCategory-17.0.0.txt + * # Date: 2025-08-01, 04:02:23 GMT + * # IndicPositionalCategory-17.0.0.txt + * # Date: 2025-07-29, 13:35:52 GMT + * # ArabicShaping-17.0.0.txt + * # Date: 2025-08-14 + * # DerivedCoreProperties-17.0.0.txt + * # Date: 2025-07-30, 23:55:08 GMT + * # Blocks-17.0.0.txt + * # Date: 2025-08-01 + * # Scripts-17.0.0.txt + * # Date: 2025-07-24, 13:28:55 GMT * # Override values For Indic_Syllabic_Category * # Not derivable * # Initial version based on Unicode 7.0 by Andrew Glass 2014-03-17 @@ -103,7 +103,7 @@ #include -static const uint8_t hb_use_u8[3345]= +static const uint8_t hb_use_u8[3343]= { 16, 50, 51, 51, 51, 52, 51, 83, 118, 131, 57, 58, 59, 195, 211, 62, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, @@ -127,24 +127,24 @@ static const uint8_t hb_use_u8[3345]= 49, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 50, 51, 2, 2, 2, 2, 2, 2, 2, 2, 52, 53, 2, 54, 2, 2, 55, 56, 2, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 2, 70, 71, 72, 73, - 2, 74, 2, 75, 76, 77, 78, 2, 2, 79, 80, 81, 82, 2, 83, 84, - 2, 85, 85, 85, 85, 85, 85, 85, 85, 86, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 87, 2, 2, 2, 2, 2, 2, 2, + 2, 74, 2, 75, 76, 77, 78, 79, 2, 80, 81, 82, 83, 2, 84, 85, + 2, 86, 86, 86, 86, 86, 86, 86, 86, 87, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, 88, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 88, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 89, 90, 2, 2, 2, 91, 2, 2, 2, 92, - 93, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 94, 94, 94, 95, 2, 2, 2, 2, 2, + 2, 2, 2, 89, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 90, 91, 2, 2, 2, 92, 2, 2, 2, 93, + 94, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 95, 95, 95, 96, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 96, 97, 2, 2, 2, 2, 2, - 2, 2, 2, 98, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 97, 98, 2, 2, 2, 2, 2, + 2, 2, 2, 99, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 99, 2, 2, 100, 2, 2, 2, 101, 2, 102, 2, 2, 2, - 2, 2, 2, 103, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 104, 104, 105, 106, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 2, 2, 2, 100, 2, 2, 101, 2, 2, 2, 102, 2, 103, 2, 2, 2, + 2, 2, 2, 104, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 105, 105, 106, 107, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, + 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 5, 0, 0, 0, 0, 0, 6, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -193,99 +193,99 @@ static const uint8_t hb_use_u8[3345]= 48, 48, 48, 48, 15, 82, 83, 84, 85, 86, 87, 0, 0, 0, 0, 88, 0, 9, 0, 0, 30, 0, 89, 81, 90, 2, 2, 2, 2, 9, 0, 0, 0, 42, 42, 91, 92, 2, 2, 2, 2, 2, 2, 2, 2, 13, 9, 0, - 0, 93, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 9, 22, 80, 45, 22, 94, 61, 0, 0, 95, 96, 95, 95, 97, 98, 0, - 0, 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 9, 0, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 2, 0, 0, 2, 2, 2, 2, 29, 0, 0, - 0, 2, 2, 2, 2, 2, 9, 0, 0, 2, 2, 2, 52, 99, 45, 0, - 0, 2, 2, 100, 101, 102, 103, 61, 63, 104, 16, 45, 22, 59, 21, 80, - 48, 48, 76, 11, 11, 11, 105, 46, 40, 11, 106, 74, 2, 2, 2, 2, - 2, 2, 2, 107, 22, 20, 20, 22, 48, 48, 22, 108, 2, 2, 2, 9, - 0, 0, 0, 0, 0, 0, 109, 110, 110, 110, 110, 0, 0, 0, 0, 0, - 0, 106, 74, 2, 2, 2, 2, 2, 2, 60, 61, 59, 25, 22, 111, 61, - 2, 2, 2, 2, 107, 22, 23, 45, 45, 102, 112, 0, 0, 0, 0, 0, - 0, 2, 2, 61, 18, 48, 23, 113, 102, 102, 102, 114, 115, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 0, 30, 2, 11, 46, 116, 116, 116, 11, 116, - 116, 15, 116, 116, 116, 26, 0, 40, 0, 0, 0, 117, 51, 11, 5, 0, - 0, 0, 0, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 6, 119, - 120, 42, 42, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 120, - 121, 120, 120, 120, 120, 120, 120, 120, 120, 0, 0, 122, 0, 0, 0, 0, - 0, 0, 7, 122, 0, 0, 0, 0, 0, 46, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 123, 123, 0, 0, - 0, 2, 2, 2, 2, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, - 124, 0, 123, 123, 0, 0, 0, 0, 0, 2, 53, 2, 108, 2, 10, 2, - 2, 2, 65, 19, 16, 0, 0, 31, 0, 2, 2, 0, 0, 0, 0, 0, - 0, 29, 2, 2, 2, 2, 2, 2, 2, 2, 2, 125, 23, 23, 23, 23, - 23, 23, 23, 126, 0, 0, 0, 0, 0, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 2, 0, 0, 0, 0, 0, 52, 2, 2, 2, 22, 22, 127, 116, - 0, 2, 2, 2, 128, 20, 59, 20, 113, 102, 129, 0, 0, 0, 0, 0, - 0, 11, 130, 2, 2, 2, 2, 2, 2, 2, 131, 23, 22, 20, 48, 132, - 133, 134, 0, 0, 0, 0, 0, 0, 0, 2, 2, 52, 30, 2, 2, 2, - 2, 2, 2, 2, 2, 10, 22, 59, 99, 76, 135, 136, 137, 0, 0, 0, - 0, 2, 138, 2, 2, 2, 2, 139, 0, 30, 2, 42, 5, 0, 79, 15, - 2, 140, 20, 53, 128, 140, 2, 2, 141, 10, 9, 0, 0, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 142, 21, 25, 0, 0, 143, 144, 0, 0, 0, - 0, 2, 65, 45, 23, 80, 47, 145, 0, 81, 81, 81, 81, 81, 81, 81, - 81, 0, 0, 0, 0, 0, 0, 0, 6, 120, 120, 120, 120, 121, 0, 0, - 0, 2, 2, 2, 2, 2, 9, 2, 2, 2, 9, 2, 30, 2, 2, 2, - 2, 2, 30, 2, 2, 2, 30, 9, 0, 128, 20, 27, 31, 0, 0, 146, - 147, 2, 2, 30, 2, 30, 2, 2, 2, 2, 2, 2, 0, 14, 37, 0, - 148, 2, 2, 13, 37, 0, 30, 2, 2, 2, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 30, 2, 2, 9, 2, 2, 11, 41, 0, 0, 0, - 0, 2, 2, 2, 0, 27, 22, 22, 30, 2, 2, 2, 0, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 27, 38, 0, 2, 2, 2, 116, 116, 116, 116, - 116, 149, 2, 9, 0, 0, 0, 0, 0, 2, 14, 14, 0, 0, 0, 0, - 0, 9, 2, 2, 9, 2, 2, 2, 2, 30, 2, 9, 0, 30, 2, 0, - 0, 150, 151, 152, 2, 2, 2, 2, 2, 2, 2, 2, 2, 22, 22, 20, - 20, 20, 22, 22, 134, 0, 0, 0, 0, 0, 153, 153, 153, 153, 153, 153, - 153, 153, 153, 153, 2, 2, 2, 2, 2, 53, 52, 53, 0, 0, 0, 0, - 154, 11, 74, 2, 2, 2, 2, 2, 2, 18, 19, 21, 16, 24, 37, 0, - 0, 0, 31, 0, 0, 0, 0, 0, 0, 11, 49, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 128, 20, 22, 155, 22, 21, 156, 157, 2, 2, 2, 2, - 2, 0, 0, 65, 158, 0, 0, 0, 0, 2, 13, 0, 0, 0, 0, 0, - 0, 2, 65, 25, 20, 20, 20, 22, 22, 108, 159, 0, 0, 56, 160, 31, - 161, 30, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 23, - 19, 22, 22, 162, 44, 0, 0, 0, 49, 128, 0, 0, 0, 0, 0, 0, - 0, 2, 2, 2, 9, 9, 2, 2, 30, 2, 2, 2, 2, 2, 2, 2, - 30, 2, 2, 2, 2, 2, 2, 2, 10, 18, 19, 21, 22, 163, 31, 0, - 0, 11, 11, 30, 2, 2, 2, 9, 30, 9, 2, 30, 2, 2, 58, 17, - 23, 16, 23, 47, 32, 33, 32, 34, 0, 0, 0, 0, 35, 0, 0, 0, - 2, 2, 23, 0, 11, 11, 11, 46, 0, 11, 11, 46, 0, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 30, 0, 9, 2, 2, 2, 30, 45, 59, 20, - 20, 31, 33, 32, 32, 25, 164, 29, 165, 166, 37, 0, 0, 0, 0, 0, - 0, 12, 26, 0, 0, 0, 0, 0, 0, 2, 2, 65, 25, 20, 20, 20, - 22, 23, 126, 15, 17, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 0, - 167, 168, 0, 0, 0, 0, 0, 0, 0, 18, 19, 20, 20, 66, 99, 25, - 161, 11, 169, 9, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, - 65, 25, 20, 20, 0, 48, 48, 11, 170, 37, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 2, 2, 20, 0, 23, 19, 20, 20, 21, 16, 82, - 170, 38, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 10, 171, - 25, 20, 22, 22, 169, 9, 0, 0, 0, 2, 2, 2, 2, 2, 9, 43, - 136, 23, 22, 20, 76, 21, 22, 0, 0, 2, 2, 2, 9, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 2, 18, 19, 20, 21, 22, 105, 170, 37, 0, - 0, 2, 2, 2, 9, 30, 0, 2, 2, 2, 2, 30, 9, 2, 2, 2, - 2, 23, 23, 18, 32, 33, 12, 172, 166, 173, 174, 0, 0, 0, 0, 0, - 0, 2, 2, 2, 2, 0, 2, 2, 2, 65, 25, 20, 20, 0, 22, 23, - 29, 108, 0, 33, 0, 0, 0, 0, 0, 52, 20, 22, 22, 22, 140, 2, - 2, 2, 175, 141, 11, 15, 176, 61, 177, 0, 0, 1, 148, 0, 0, 0, - 0, 52, 20, 22, 16, 19, 20, 2, 2, 2, 2, 159, 159, 159, 178, 178, - 178, 178, 178, 178, 15, 179, 0, 30, 0, 22, 20, 20, 31, 22, 22, 11, - 170, 0, 61, 61, 61, 61, 61, 61, 61, 66, 21, 82, 46, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 2, 2, 9, 22, 80, 45, 22, 93, 61, 0, + 0, 94, 95, 94, 94, 96, 97, 0, 0, 2, 2, 2, 2, 2, 2, 2, + 0, 2, 2, 9, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 0, + 0, 2, 2, 2, 2, 29, 0, 0, 0, 2, 2, 2, 2, 2, 9, 0, + 0, 2, 2, 2, 52, 98, 45, 0, 0, 2, 2, 99, 100, 101, 102, 61, + 63, 103, 16, 45, 22, 59, 21, 80, 48, 48, 76, 11, 11, 11, 104, 46, + 40, 11, 105, 74, 2, 2, 2, 2, 2, 2, 2, 106, 22, 20, 20, 22, + 48, 48, 22, 107, 2, 2, 2, 9, 0, 0, 0, 0, 0, 0, 108, 109, + 109, 109, 109, 0, 0, 0, 0, 0, 0, 105, 74, 2, 2, 2, 2, 2, + 2, 60, 61, 59, 25, 22, 110, 61, 2, 2, 2, 2, 106, 22, 23, 45, + 45, 101, 111, 0, 0, 0, 0, 0, 0, 2, 2, 61, 18, 48, 23, 112, + 101, 101, 101, 113, 114, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 30, + 2, 11, 46, 115, 115, 115, 11, 115, 115, 15, 115, 115, 115, 26, 0, 40, + 0, 0, 0, 116, 51, 11, 5, 0, 0, 0, 0, 0, 0, 0, 117, 0, + 0, 0, 0, 0, 0, 0, 6, 118, 119, 42, 42, 5, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 119, 119, 120, 119, 119, 119, 119, 119, 119, 119, + 119, 0, 0, 121, 0, 0, 0, 0, 0, 0, 7, 121, 0, 0, 0, 0, + 0, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, + 0, 0, 0, 0, 122, 122, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, + 30, 0, 0, 0, 0, 0, 0, 0, 123, 0, 122, 122, 0, 0, 0, 0, + 0, 2, 53, 2, 107, 2, 10, 2, 2, 2, 65, 19, 16, 0, 0, 31, + 0, 2, 2, 0, 0, 0, 0, 0, 0, 29, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 124, 23, 23, 23, 23, 23, 23, 23, 125, 0, 0, 0, 0, + 0, 11, 11, 11, 11, 11, 11, 11, 11, 11, 2, 0, 0, 0, 0, 0, + 52, 2, 2, 2, 22, 22, 126, 115, 0, 2, 2, 2, 127, 20, 59, 20, + 112, 101, 128, 0, 0, 0, 0, 0, 0, 11, 129, 2, 2, 2, 2, 2, + 2, 2, 130, 23, 22, 20, 48, 131, 132, 133, 0, 0, 0, 0, 0, 0, + 0, 2, 2, 52, 30, 2, 2, 2, 2, 2, 2, 2, 2, 10, 22, 59, + 98, 76, 134, 135, 136, 0, 0, 0, 0, 2, 137, 2, 2, 2, 2, 138, + 0, 30, 2, 42, 5, 0, 79, 15, 2, 139, 20, 53, 127, 139, 2, 2, + 140, 10, 9, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 141, 21, + 25, 0, 0, 142, 143, 0, 0, 0, 0, 2, 65, 45, 23, 80, 47, 144, + 0, 81, 81, 81, 81, 81, 81, 81, 81, 0, 0, 0, 0, 0, 0, 0, + 6, 119, 119, 119, 119, 120, 0, 0, 0, 2, 2, 2, 2, 2, 9, 2, + 2, 2, 9, 2, 30, 2, 2, 2, 2, 2, 30, 2, 2, 2, 30, 9, + 0, 127, 20, 27, 31, 0, 0, 145, 146, 2, 2, 30, 2, 30, 2, 2, + 2, 2, 2, 2, 0, 14, 37, 0, 147, 2, 2, 13, 37, 0, 30, 2, + 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 2, 2, + 9, 2, 2, 11, 41, 0, 0, 0, 0, 2, 2, 2, 0, 27, 22, 22, + 30, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 27, 38, + 0, 2, 2, 2, 115, 115, 115, 115, 115, 148, 2, 9, 0, 0, 0, 0, + 0, 2, 14, 14, 0, 0, 0, 0, 0, 9, 2, 2, 9, 2, 2, 2, + 2, 30, 2, 9, 0, 30, 2, 0, 0, 149, 150, 151, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 22, 22, 20, 20, 20, 22, 22, 133, 0, 0, 0, + 0, 0, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 2, 2, 2, 2, + 2, 53, 52, 53, 0, 0, 0, 0, 153, 11, 74, 2, 2, 2, 2, 2, + 2, 18, 19, 21, 16, 24, 37, 0, 0, 0, 31, 0, 0, 0, 0, 0, + 0, 11, 49, 2, 2, 2, 2, 2, 2, 2, 2, 2, 127, 20, 22, 154, + 22, 21, 155, 156, 2, 2, 2, 2, 2, 0, 0, 65, 157, 0, 0, 0, + 0, 2, 13, 0, 0, 0, 0, 0, 0, 2, 65, 25, 20, 20, 20, 22, + 22, 107, 158, 0, 0, 56, 159, 31, 160, 30, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 23, 19, 22, 22, 161, 44, 0, 0, 0, + 49, 127, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 9, 9, 2, 2, + 30, 2, 2, 2, 2, 2, 2, 2, 30, 2, 2, 2, 2, 2, 2, 2, + 10, 18, 19, 21, 22, 162, 31, 0, 0, 11, 11, 30, 2, 2, 2, 9, + 30, 9, 2, 30, 2, 2, 58, 17, 23, 16, 23, 47, 32, 33, 32, 34, + 0, 0, 0, 0, 35, 0, 0, 0, 2, 2, 23, 0, 11, 11, 11, 46, + 0, 11, 11, 46, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 30, 0, + 9, 2, 2, 2, 30, 45, 59, 20, 20, 31, 33, 32, 32, 25, 163, 29, + 164, 165, 37, 0, 0, 0, 0, 0, 0, 12, 26, 0, 0, 0, 0, 0, + 0, 2, 2, 65, 25, 20, 20, 20, 22, 23, 125, 15, 17, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 0, 0, 166, 167, 0, 0, 0, 0, 0, 0, + 0, 18, 19, 20, 20, 66, 98, 25, 160, 11, 168, 9, 0, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 2, 2, 65, 25, 20, 20, 0, 48, 48, 11, + 169, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 20, + 0, 23, 19, 20, 20, 21, 16, 82, 169, 38, 0, 0, 0, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 10, 170, 25, 20, 22, 22, 168, 9, 0, 0, + 0, 2, 2, 2, 2, 2, 9, 43, 135, 23, 22, 20, 76, 21, 22, 0, + 0, 2, 2, 2, 9, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 18, + 19, 20, 21, 22, 104, 169, 37, 0, 0, 2, 2, 2, 9, 30, 0, 2, + 2, 2, 2, 30, 9, 2, 2, 2, 2, 23, 23, 18, 32, 33, 12, 171, + 165, 172, 173, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 2, 2, + 2, 65, 25, 20, 20, 0, 22, 23, 29, 107, 0, 33, 0, 0, 0, 0, + 0, 52, 20, 22, 22, 22, 139, 2, 2, 2, 174, 140, 11, 15, 175, 61, + 176, 0, 0, 1, 147, 0, 0, 0, 0, 52, 20, 22, 16, 19, 20, 2, + 2, 2, 2, 158, 158, 158, 177, 177, 177, 177, 177, 177, 15, 178, 0, 30, + 0, 16, 20, 16, 16, 0, 0, 0, 0, 22, 20, 20, 31, 22, 22, 11, + 169, 0, 61, 61, 61, 61, 61, 61, 61, 66, 21, 82, 46, 0, 0, 0, 0, 2, 2, 2, 9, 2, 30, 2, 2, 52, 22, 22, 31, 0, 38, 22, - 27, 11, 160, 180, 181, 0, 0, 0, 0, 2, 2, 2, 30, 9, 2, 2, + 27, 11, 159, 179, 180, 0, 0, 0, 0, 2, 2, 2, 30, 9, 2, 2, 2, 2, 2, 2, 2, 2, 23, 23, 47, 22, 35, 82, 68, 0, 0, 0, - 0, 2, 182, 66, 47, 0, 0, 0, 0, 11, 183, 2, 2, 2, 2, 2, - 2, 2, 2, 23, 22, 20, 31, 0, 48, 16, 144, 0, 0, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 157, 0, 0, 184, 184, 184, 184, 184, 184, 184, - 184, 185, 185, 185, 186, 187, 185, 184, 184, 188, 184, 184, 189, 190, 190, 190, - 190, 190, 190, 190, 0, 0, 0, 0, 0, 184, 184, 184, 184, 184, 191, 0, - 0, 2, 2, 2, 2, 2, 2, 2, 22, 22, 22, 22, 22, 22, 192, 193, - 194, 11, 11, 11, 46, 0, 0, 0, 0, 29, 74, 2, 2, 2, 2, 2, + 0, 2, 181, 66, 47, 0, 0, 0, 0, 11, 182, 2, 2, 2, 2, 2, + 2, 2, 2, 23, 22, 20, 31, 0, 48, 16, 143, 0, 0, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 156, 0, 0, 183, 183, 183, 183, 183, 183, 183, + 183, 184, 184, 184, 185, 186, 184, 183, 183, 187, 183, 183, 188, 189, 189, 189, + 189, 189, 189, 189, 0, 0, 0, 0, 0, 183, 183, 183, 183, 183, 190, 0, + 0, 2, 2, 2, 2, 2, 2, 2, 22, 22, 22, 22, 22, 22, 191, 192, + 193, 11, 11, 11, 46, 0, 0, 0, 0, 29, 74, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 65, 47, 0, 2, 2, 2, 2, 2, 9, 0, - 58, 195, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 0, 0, 0, 40, 116, 26, 0, 0, 0, 0, 0, + 58, 194, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 0, 0, 0, 40, 115, 26, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 30, 2, 2, 2, 2, 2, 0, 58, 37, 0, 6, 120, 120, 120, 121, 0, + 30, 2, 2, 2, 2, 2, 0, 58, 37, 0, 6, 119, 119, 119, 120, 0, 0, 11, 11, 11, 49, 2, 2, 2, 0, 2, 2, 2, 2, 2, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 46, 2, 2, 2, 2, 2, 2, 11, 11, 2, 2, 2, 2, 2, 2, 22, 22, 2, 2, 2, 2, 2, 2, 2, @@ -301,22 +301,21 @@ static const uint8_t hb_use_u8[3345]= VMBlw,VMPst, IS, VAbv, MPst, MPre, MBlw, MBlw, B, MBlw, MBlw, VPst,VMPst,VMPst, B, MBlw, VPst, VPre, VAbv, VAbv,VMPst,VMPst,VMBlw, B,VMPst, VBlw, VPst, CGJ, CGJ, VPst,VMAbv,VMAbv, FMAbv, FAbv,CMAbv,FMAbv,VMAbv,FMAbv, VAbv, IS,FMAbv, B,FMAbv, B, CGJ, WJ, CGJ, GB, - CMAbv,CMAbv, B, GB, B, VAbv, SUB, FPst, FPst,VMBlw, FPst, FPst, FBlw,VMAbv,FMBlw, VAbv, - VPre, B, MPre, MBlw, SUB, FAbv, FAbv, MAbv, SUB, Sk, VPst, VAbv,VMAbv,VMAbv, FAbv,CMAbv, - VPst, H, B, O,SMAbv,SMAbv,SMAbv, VPst, IS, RK, RK, VBlw, FAbv,VMPre,VMPre,FMAbv, - CMBlw,VMBlw,VMBlw,VMAbv, CS, O,FMAbv, ZWNJ, CGJ, WJ, WJ, WJ, O,FMPst, O, SB, - SE, O, H, MPst, VPst, H,VMAbv, VAbv,VMBlw, B, VBlw, FPst, VPst, FAbv,VMPst, B, - CMAbv, VAbv, MBlw, MPst, MBlw, H, O, VBlw, MPst, MPre, MAbv, MBlw, O, B, FAbv, FAbv, - FPst, VBlw, B, VBlw,VMAbv, B, VPre, O,VMPst, IS, O,VMPst, VBlw, VPst,VMBlw,VMBlw, - VMAbv, O, IS,VMBlw, B,VMPst,VMAbv,VMPst, CS, CS, B, N, N, O, HN, VPre, - VBlw, VAbv, IS,CMAbv, O, VPst, B, R, R,CMBlw, VAbv, VPre,VMAbv,VMAbv, H, VAbv, - CMBlw,VMPst, O,VMAbv,CMBlw, IS, R,FMAbv, B, CS, CS, H,CMBlw,VMPst, H,VMPst, - VAbv,VMAbv, VPst, MPst, R, MPst,CMBlw, B,FMBlw, CS, SUB, SUB, GB, FBlw, FBlw,CMAbv, - IS, VBlw, IS, R, MBlw, GB, VAbv, R,VMPst, G, G, J, J, J, SB, SE, - J, HR, G, G, HM, HM, HM, G, O, MPre, MPre, MPst,VMAbv, MBlw, VBlw, O, - VBlw, + CMAbv,CMAbv, B, VAbv, SUB, FPst, FPst,VMBlw, FPst, FPst, FBlw,VMAbv,FMBlw, VAbv, VPre, B, + MPre, MBlw, SUB, FAbv, FAbv, MAbv, SUB, Sk, VPst, VAbv,VMAbv,VMAbv, FAbv,CMAbv, VPst, H, + B, O,SMAbv,SMAbv,SMAbv, VPst, IS, RK, RK, VBlw, FAbv,VMPre,VMPre,FMAbv,CMBlw,VMBlw, + VMBlw,VMAbv, CS, O,FMAbv, ZWNJ, CGJ, WJ, WJ, WJ, O,FMPst, O, SB, SE, O, + H, MPst, VPst, H,VMAbv, VAbv,VMBlw, B, VBlw, FPst, VPst, FAbv,VMPst, B,CMAbv, VAbv, + MBlw, MPst, MBlw, H, O, VBlw, MPst, MPre, MAbv, MBlw, O, B, FAbv, FAbv, FPst, VBlw, + B, VBlw,VMAbv, B, VPre, O,VMPst, IS, O,VMPst, VBlw, VPst,VMBlw,VMBlw,VMAbv, O, + IS,VMBlw, B,VMPst,VMAbv,VMPst, CS, CS, B, N, N, O, HN, VPre, VBlw, VAbv, + IS,CMAbv, O, VPst, B, R, R,CMBlw, VAbv, VPre,VMAbv,VMAbv, H, VAbv,CMBlw,VMPst, + O,VMAbv,CMBlw, IS, R,FMAbv, B, CS, CS, H,CMBlw,VMPst, H,VMPst, VAbv,VMAbv, + VPst, MPst, R, MPst,CMBlw, B,FMBlw, CS, SUB, SUB, GB, FBlw, FBlw,CMAbv, IS, VBlw, + IS, R, MBlw, GB, VAbv, R,VMPst, G, G, J, J, J, SB, SE, J, HR, + G, G, HM, HM, HM, G, O, MPre, MPre, MPst,VMAbv, MBlw, VBlw, O, VBlw, }; -static const uint16_t hb_use_u16[856]= +static const uint16_t hb_use_u16[864]= { 0, 0, 1, 2, 0, 3, 0, 3, 0, 0, 4, 5, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, @@ -330,48 +329,48 @@ static const uint16_t hb_use_u16[856]= 73, 74, 75, 76, 77, 0, 0, 0, 10, 10, 78, 79, 80, 81, 82, 83, 84, 85, 0, 0, 0, 0, 0, 0, 10, 86, 10, 87, 10, 88, 89, 90, 10, 10, 10, 91, 92, 93, 2, 0, 94, 0, 10, 10, 10, 10, 10, 95, - 96, 10, 97, 0, 0, 0, 0, 0, 98, 99,100,101, 31, 10,102,103, - 10, 10,104, 10,105,106, 0, 0, 10,107, 10, 10, 10,108,109,110, - 2, 2, 0, 0, 0, 0, 0, 0,111, 10, 10,112,113, 2,114,115, - 116, 10,117, 10, 10, 10,118,119, 10, 10,120,121,122, 0, 0, 0, - 0, 0, 0, 0, 0,123,124,125, 0, 0, 0, 0, 0, 0, 0,126, - 127,128,129, 0, 0, 0,130,131,132, 0, 0, 0, 0, 0, 0,133, - 0, 0, 0, 0,134, 0, 0, 0, 0, 0, 0, 0, 0, 0,135, 0, - 0, 0, 0, 10, 10, 10,136,137, 0, 0,138, 0, 0, 0, 0, 0, - 139, 10,140, 0, 10, 10, 10,141,142, 10, 10,143,144, 2,145,146, - 10, 10,147, 10,148,149, 0, 0,150, 10, 10,151,152, 2,153, 99, - 10, 10,154,155,156, 2, 10,157, 10, 10, 10,158,159, 0,160,161, - 0, 0, 0, 0, 10, 10,162, 2,163, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,164, 0, 0, 0, 0, 0, 0, 0,165, - 0, 0, 0, 0, 0, 0, 0,166,166,167, 34,168, 0, 0, 0, 0, - 169,170, 10,171, 95, 0, 0, 0, 0, 0, 0, 0, 70, 10,172, 0, - 10,173,174, 0, 0, 0, 0, 0, 10, 10,175, 2, 9, 10,176, 10, - 177, 0, 0, 0, 0, 0, 0, 0, 10, 10,178,173, 0, 0, 0, 0, - 0, 0, 0, 10,179,180, 0, 10,181, 0, 0,182,183, 0, 0, 0, - 184, 10, 10,185,186,187,188,189,190, 10, 10,191,192, 0, 0, 0, - 193, 10,194,195,196, 10, 10,197,190, 10, 10,198,199,106,200,103, - 10, 34,201,202,203, 0, 0, 0,204,205, 95, 10, 10,206,207, 2, - 208, 21, 22,209,210,211,212,213,214, 10, 10,215,216,217,218, 0, - 10, 10, 10,219,220,221,222, 0,200, 10, 10,223,224, 2, 0, 0, - 10, 10,225,226,227,228, 0, 0, 10, 10, 10,229,230, 2, 0, 0, - 10, 10,231,232, 2, 10,141, 0, 10,233,234,104,235, 0, 0, 0, - 10, 10,236,237, 0, 0, 0, 0,238,239, 10,240,241, 2, 0, 0, - 0, 0,242, 10, 10,243,244, 0,245, 10, 10,246,247,248, 10, 10, - 249,250, 0, 0, 0, 0, 0, 0, 22, 10,225,251, 8, 10, 71, 19, - 10,252, 74,253, 0, 0, 0, 0,254, 10, 10,255,256, 2,257, 10, - 258,259, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10,260, - 261, 49, 10,262,263,264, 0, 0,265,265,265,265,265,265,265,265, - 265,265,265,266,267,268,265,265,265,265,265,265,265,265,265,269, - 10,270,271, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, - 10, 10, 10,272, 0, 0, 0, 0, 0, 0, 0, 0,273, 10,274, 2, - 10, 10, 10, 10,275,276,277,277,278,279, 0, 0, 0, 0,280, 0, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,177, 0,281, - 10, 10, 10, 10, 10, 10,106, 71, 95,282, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,283, 10, 10, 71,284,285, 0, 0, 0, - 0, 10,286, 0, 10, 10,287, 2, 0, 0, 0, 0, 0, 10,288, 2, - 0, 0, 0, 0, 0, 10,289,106, 10, 10, 10, 10,290, 2, 0, 0, - 130,130,130,130,130,130,130,130,163,163,163,163,163,163,163,163, - 163,163,163,163,163,163,163,130, + 96, 10, 97, 0, 0, 0, 0, 0, 10, 98, 99,100, 31, 10,101,102, + 10, 10,103, 10,104,105, 0, 0, 10,106, 10, 10, 10,107,108,109, + 2, 2, 0, 0, 0, 0, 0, 0,110, 10, 10,111,112, 2,113,114, + 115, 10,116, 10, 10, 10,117,118, 10, 10,119,120,121, 0, 0, 0, + 0, 0, 0, 0, 0,122,123,124, 0, 0, 0, 0, 0, 0, 0,125, + 126,127,128, 0, 0, 0,129,130,131, 0, 0, 0, 0, 0, 0,132, + 0, 0, 0, 0,133, 0, 0, 0, 0, 0, 0, 0, 0, 0,134, 0, + 0, 0, 0, 10, 10, 10,135,136, 0, 0,137, 0, 0, 0, 0, 0, + 138, 10,139, 0, 10, 10, 10,140,141, 10, 10,142,143, 2,144,145, + 10, 10,146, 10,147,148, 0, 0,149, 10, 10,150,151, 2,152, 98, + 10, 10,153,154,155, 2, 10,156, 10, 10, 10,157,158, 0,159,160, + 0, 0, 0, 0, 10, 10,161, 2,162, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,163, 0, 0, 0, 0, 0, 0, 0,164, + 0, 0, 0, 0, 0, 0, 0,165,165,166, 34,167, 0, 0, 0, 0, + 168,169, 10,170, 95, 0, 0, 0, 0, 0, 0, 0, 70, 10,171, 0, + 10,172,173, 0, 0, 0, 0, 0, 10, 10,174, 2, 9, 10,175, 10, + 176, 0, 0, 0, 0, 0, 0, 0, 10, 10,177,172, 0, 0, 0, 0, + 0, 0, 0, 10,178,179, 0, 10,180, 0, 0,181,182, 0, 0, 0, + 183, 10, 10,184,185,186,187,188,189, 10, 10,190,191, 0, 0, 0, + 192, 10,193,194,195, 10, 10,196,189, 10, 10,197,198,105,199,102, + 10, 34,200,201,202, 0, 0, 0,203,204, 95, 10, 10,205,206, 2, + 207, 21, 22,208,209,210,211,212,213, 10, 10,214,215,216,217, 0, + 10, 10, 10,218,219,220,221, 0,199, 10, 10,222,223, 2, 0, 0, + 10, 10,224,225,226,227, 0, 0, 10, 10, 10,228,229, 2, 0, 0, + 10, 10,230,231, 2, 10,140, 0, 10,232,233,103,234, 0, 0, 0, + 10, 10,235,236, 0, 0, 0, 0,237,238, 10,239,240, 2, 0, 0, + 0, 0,241, 10, 10,242,243, 0,244, 10, 10,245,246,247, 10, 10, + 248,249, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,250, 0, + 22, 10,224,251, 8, 10, 71, 19, 10,252, 74,253, 0, 0, 0, 0, + 254, 10, 10,255,256, 2,257, 10,258,259, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 10,260,261, 49, 10,262,263,264, 0, 0, + 265,265,265,265,265,265,265,265,265,265,265,266,267,268,265,265, + 265,265,265,265,265,265,265,269, 10,270,271, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 10, 10, 10,272, 0, 0, 0, 0, + 0, 0, 0, 0,273, 10,274, 2, 10, 10, 10, 10,275,276,277,277, + 278,279, 0, 0, 0, 0,280, 0, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10,176, 0,281, 10, 10, 10, 10, 10, 10,105, 71, + 95,282, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,283, + 10, 10, 71,284,285, 0, 0, 0, 0, 10,286, 0, 10, 10,287, 2, + 0, 0, 0, 0, 0, 10,288, 2, 0, 0, 0, 0, 0, 10,289,105, + 10, 10, 10, 10,290, 2, 0, 0,129,129,129,129,129,129,129,129, + 162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,129, }; static inline uint8_t hb_use_b4 (const uint8_t* a, unsigned i) @@ -380,7 +379,7 @@ static inline uint8_t hb_use_b4 (const uint8_t* a, unsigned i) } static inline uint8_t hb_use_get_category (unsigned u) { - return u<921600 ? hb_use_u8[2953u+(((hb_use_u8[625u+(((hb_use_u16[((hb_use_u8[113u+(((hb_use_b4(hb_use_u8,u>>1>>3>>3>>5))<<5)+((u>>1>>3>>3)&31))])<<3)+((u>>1>>3)&7)])<<3)+((u>>1)&7))])<<1)+((u)&1))] : O; + return u<921600 ? hb_use_u8[2953u+((hb_use_u8[625u+((hb_use_u16[((hb_use_u8[113u+((hb_use_b4(hb_use_u8,((((((((u)>>1))>>3))>>3))>>5)))<<5)+((((((((u)>>1))>>3))>>3))&31)])<<3)+((((((u)>>1))>>3))&7)])<<3)+((((u)>>1))&7)])<<1)+((u)&1)] : O; } @@ -388,7 +387,7 @@ static inline uint8_t hb_use_get_category (unsigned u) #include -static const uint8_t hb_use_u8[3657]= +static const uint8_t hb_use_u8[3663]= { 16, 50, 51, 51, 51, 52, 51, 83, 118, 131, 57, 58, 59, 195, 211, 62, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, @@ -404,16 +403,16 @@ static const uint8_t hb_use_u8[3657]= 1, 1, 1, 1, 1, 1, 1, 1, 1, 25, 26, 27, 28, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 29, 30, 1, 1, 1, 1, 1, 31, 1, 1, 1, 1, 32, 33, 1, 34, 35, - 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 1, 48, 49, 50, - 51, 52, 52, 52, 52, 53, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 54, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 55, 1, 1, 1, 1, 1, 1, 1, 1, 56, 57, 1, 58, 1, - 59, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 60, 61, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 62, 1, 1, - 1, 1, 63, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 64, 65, 1, 66, 67, 1, 1, 1, 68, 1, 1, 1, 1, 1, - 1, 69, 70, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 0, 1, 2, 2, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, + 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 53, 53, 53, 54, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 53, 53, 55, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 56, 1, 1, 1, 1, 1, 1, 1, 1, 57, 58, 1, 59, 1, + 60, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 61, 62, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 63, 1, 1, + 1, 1, 64, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 65, 66, 1, 67, 68, 1, 1, 1, 69, 1, 1, 1, 1, 1, + 1, 70, 71, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 0, 1, 2, 2, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 0, 0, 9, 0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, @@ -437,190 +436,190 @@ static const uint8_t hb_use_u8[3657]= 0, 0, 0, 0, 0, 56, 179, 180, 0, 56, 181, 182, 0, 56, 183, 184, 185, 186, 187, 188, 0, 0, 0, 0, 0, 56, 189, 0, 0, 0, 0, 0, 0, 190, 191, 192, 0, 0, 193, 194, 195, 196, 197, 198, 56, 199, 0, 0, - 0, 200, 201, 202, 203, 204, 205, 0, 0, 206, 207, 208, 209, 210, 67, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 211, 212, 213, 214, 0, 0, 0, 0, - 0, 215, 215, 215, 215, 215, 215, 215, 215, 215, 216, 217, 215, 215, 215, 215, - 215, 215, 215, 215, 215, 215, 215, 215, 218, 219, 220, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 67, 0, 56, 221, 0, 0, 0, 0, 0, - 0, 0, 0, 222, 223, 0, 0, 0, 0, 56, 56, 224, 225, 226, 0, 0, - 227, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 228, - 229, 56, 56, 56, 230, 231, 0, 0, 0, 0, 0, 0, 232, 0, 0, 0, - 0, 56, 233, 234, 0, 0, 0, 0, 0, 0, 0, 0, 0, 101, 235, 56, - 236, 0, 0, 0, 0, 0, 0, 101, 237, 0, 0, 0, 0, 0, 0, 101, - 238, 56, 56, 239, 0, 0, 0, 0, 0, 240, 240, 240, 240, 240, 240, 240, - 240, 241, 241, 241, 241, 241, 241, 241, 242, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 2, 2, 2, 2, 0, 0, - 0, 0, 0, 0, 0, 0, 3, 4, 0, 5, 0, 0, 0, 0, 0, 6, - 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 10, 11, 11, 11, 11, 0, 0, 0, 9, 12, - 0, 2, 2, 2, 2, 13, 14, 0, 0, 11, 15, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 16, 17, 18, 19, 20, 21, 22, 16, 23, 24, - 25, 12, 26, 27, 20, 2, 2, 2, 2, 2, 20, 0, 2, 2, 2, 2, - 2, 0, 2, 2, 2, 2, 2, 2, 2, 28, 29, 30, 2, 2, 2, 9, - 30, 9, 30, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 9, 2, 2, - 2, 9, 9, 0, 2, 2, 0, 17, 18, 19, 20, 31, 32, 33, 32, 34, - 0, 0, 0, 0, 35, 0, 0, 2, 30, 2, 0, 0, 0, 0, 0, 9, - 36, 12, 15, 30, 2, 2, 9, 0, 30, 9, 2, 30, 9, 2, 0, 37, - 18, 19, 31, 0, 27, 38, 27, 39, 0, 40, 0, 0, 0, 30, 2, 9, - 9, 0, 0, 0, 2, 2, 2, 2, 2, 41, 42, 43, 0, 0, 0, 0, - 0, 12, 15, 30, 2, 2, 2, 2, 30, 2, 30, 2, 2, 2, 2, 2, - 2, 9, 2, 30, 2, 2, 0, 17, 18, 19, 20, 21, 27, 22, 35, 24, - 0, 0, 0, 0, 0, 30, 41, 41, 44, 12, 29, 30, 2, 2, 2, 9, - 30, 9, 2, 30, 2, 2, 0, 17, 45, 0, 0, 27, 22, 0, 0, 2, - 30, 30, 0, 0, 0, 0, 0, 0, 0, 0, 46, 30, 2, 2, 9, 0, - 2, 9, 2, 2, 0, 30, 9, 9, 2, 0, 30, 9, 0, 2, 9, 0, - 2, 2, 2, 2, 2, 2, 0, 0, 23, 16, 47, 0, 48, 33, 48, 34, - 0, 0, 0, 0, 35, 0, 0, 0, 0, 15, 29, 49, 2, 2, 2, 9, - 2, 9, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 17, - 22, 16, 23, 47, 22, 38, 22, 39, 0, 0, 0, 27, 31, 2, 9, 0, - 0, 10, 29, 30, 2, 2, 2, 9, 2, 2, 2, 30, 2, 2, 0, 17, - 45, 0, 0, 35, 47, 0, 0, 0, 9, 50, 51, 0, 0, 0, 0, 0, - 0, 11, 29, 2, 2, 2, 2, 9, 2, 2, 2, 2, 2, 2, 52, 53, - 23, 19, 20, 31, 48, 33, 48, 34, 54, 0, 0, 0, 35, 0, 0, 0, - 30, 12, 29, 30, 2, 2, 2, 2, 2, 2, 2, 2, 9, 0, 2, 2, - 2, 2, 30, 2, 2, 2, 2, 30, 0, 2, 2, 2, 9, 0, 55, 0, - 35, 23, 22, 31, 31, 18, 48, 48, 25, 0, 23, 0, 0, 0, 0, 0, - 0, 2, 0, 2, 9, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, - 0, 2, 2, 56, 56, 57, 0, 0, 18, 2, 2, 2, 2, 30, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 9, 0, 58, 21, 59, 22, 22, 20, 20, - 46, 21, 11, 31, 11, 2, 2, 60, 61, 61, 61, 61, 61, 62, 61, 61, - 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 63, - 0, 0, 0, 0, 64, 0, 0, 0, 0, 2, 2, 2, 2, 2, 65, 45, - 59, 66, 22, 22, 67, 68, 69, 70, 71, 2, 2, 2, 2, 2, 1, 0, - 5, 2, 2, 2, 23, 20, 2, 2, 72, 71, 73, 74, 65, 73, 29, 29, - 2, 52, 22, 53, 2, 2, 2, 2, 2, 2, 75, 76, 77, 29, 29, 78, - 79, 2, 2, 2, 2, 2, 29, 45, 0, 2, 59, 80, 0, 0, 0, 0, - 30, 2, 59, 47, 0, 0, 0, 0, 0, 2, 59, 0, 0, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 2, 9, 2, 9, 59, 0, 0, 0, 0, 0, - 0, 2, 2, 81, 45, 22, 59, 20, 48, 48, 48, 48, 15, 82, 83, 84, - 85, 86, 87, 0, 0, 0, 0, 88, 0, 9, 0, 0, 30, 0, 89, 81, - 90, 2, 2, 2, 2, 9, 0, 0, 0, 42, 42, 91, 92, 2, 2, 2, - 2, 2, 2, 2, 2, 13, 9, 0, 0, 93, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 9, 22, 80, 45, 22, 94, 61, 0, - 0, 95, 96, 95, 95, 97, 98, 0, 0, 2, 2, 2, 2, 2, 2, 2, + 0, 0, 0, 0, 200, 0, 0, 0, 0, 201, 202, 203, 204, 205, 206, 0, + 0, 207, 208, 209, 210, 211, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 212, 213, 214, 215, 0, 0, 0, 0, 0, 216, 216, 216, 216, 216, 216, 216, + 216, 216, 217, 218, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, + 219, 220, 221, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, + 0, 56, 222, 0, 0, 0, 0, 0, 0, 0, 0, 223, 224, 0, 0, 0, + 0, 56, 56, 225, 226, 227, 0, 0, 228, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 229, 230, 56, 56, 56, 231, 232, 0, 0, + 0, 0, 0, 0, 233, 0, 0, 0, 0, 56, 234, 235, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 101, 236, 56, 237, 0, 0, 0, 0, 0, 0, 101, + 238, 0, 0, 0, 0, 0, 0, 101, 239, 56, 56, 240, 0, 0, 0, 0, + 0, 241, 241, 241, 241, 241, 241, 241, 241, 242, 242, 242, 242, 242, 242, 242, + 243, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, + 0, 5, 0, 0, 0, 0, 0, 6, 0, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 10, 11, + 11, 11, 11, 0, 0, 0, 9, 12, 0, 2, 2, 2, 2, 13, 14, 0, + 0, 11, 15, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 16, 17, + 18, 19, 20, 21, 22, 16, 23, 24, 25, 12, 26, 27, 20, 2, 2, 2, + 2, 2, 20, 0, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, + 2, 28, 29, 30, 2, 2, 2, 9, 30, 9, 30, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 9, 2, 2, 2, 9, 9, 0, 2, 2, 0, 17, + 18, 19, 20, 31, 32, 33, 32, 34, 0, 0, 0, 0, 35, 0, 0, 2, + 30, 2, 0, 0, 0, 0, 0, 9, 36, 12, 15, 30, 2, 2, 9, 0, + 30, 9, 2, 30, 9, 2, 0, 37, 18, 19, 31, 0, 27, 38, 27, 39, + 0, 40, 0, 0, 0, 30, 2, 9, 9, 0, 0, 0, 2, 2, 2, 2, + 2, 41, 42, 43, 0, 0, 0, 0, 0, 12, 15, 30, 2, 2, 2, 2, + 30, 2, 30, 2, 2, 2, 2, 2, 2, 9, 2, 30, 2, 2, 0, 17, + 18, 19, 20, 21, 27, 22, 35, 24, 0, 0, 0, 0, 0, 30, 41, 41, + 44, 12, 29, 30, 2, 2, 2, 9, 30, 9, 2, 30, 2, 2, 0, 17, + 45, 0, 0, 27, 22, 0, 0, 2, 30, 30, 0, 0, 0, 0, 0, 0, + 0, 0, 46, 30, 2, 2, 9, 0, 2, 9, 2, 2, 0, 30, 9, 9, + 2, 0, 30, 9, 0, 2, 9, 0, 2, 2, 2, 2, 2, 2, 0, 0, + 23, 16, 47, 0, 48, 33, 48, 34, 0, 0, 0, 0, 35, 0, 0, 0, + 0, 15, 29, 49, 2, 2, 2, 9, 2, 9, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 0, 17, 22, 16, 23, 47, 22, 38, 22, 39, + 0, 0, 0, 27, 31, 2, 9, 0, 0, 10, 29, 30, 2, 2, 2, 9, + 2, 2, 2, 30, 2, 2, 0, 17, 45, 0, 0, 35, 47, 0, 0, 0, + 9, 50, 51, 0, 0, 0, 0, 0, 0, 11, 29, 2, 2, 2, 2, 9, + 2, 2, 2, 2, 2, 2, 52, 53, 23, 19, 20, 31, 48, 33, 48, 34, + 54, 0, 0, 0, 35, 0, 0, 0, 30, 12, 29, 30, 2, 2, 2, 2, + 2, 2, 2, 2, 9, 0, 2, 2, 2, 2, 30, 2, 2, 2, 2, 30, + 0, 2, 2, 2, 9, 0, 55, 0, 35, 23, 22, 31, 31, 18, 48, 48, + 25, 0, 23, 0, 0, 0, 0, 0, 0, 2, 0, 2, 9, 0, 0, 0, + 0, 0, 0, 0, 0, 20, 0, 0, 0, 2, 2, 56, 56, 57, 0, 0, + 18, 2, 2, 2, 2, 30, 2, 2, 2, 2, 2, 2, 2, 2, 2, 9, + 0, 58, 21, 59, 22, 22, 20, 20, 46, 21, 11, 31, 11, 2, 2, 60, + 61, 61, 61, 61, 61, 62, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, + 61, 61, 61, 61, 61, 61, 61, 63, 0, 0, 0, 0, 64, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 65, 45, 59, 66, 22, 22, 67, 68, 69, 70, + 71, 2, 2, 2, 2, 2, 1, 0, 5, 2, 2, 2, 23, 20, 2, 2, + 72, 71, 73, 74, 65, 73, 29, 29, 2, 52, 22, 53, 2, 2, 2, 2, + 2, 2, 75, 76, 77, 29, 29, 78, 79, 2, 2, 2, 2, 2, 29, 45, + 0, 2, 59, 80, 0, 0, 0, 0, 30, 2, 59, 47, 0, 0, 0, 0, + 0, 2, 59, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 9, + 2, 9, 59, 0, 0, 0, 0, 0, 0, 2, 2, 81, 45, 22, 59, 20, + 48, 48, 48, 48, 15, 82, 83, 84, 85, 86, 87, 0, 0, 0, 0, 88, + 0, 9, 0, 0, 30, 0, 89, 81, 90, 2, 2, 2, 2, 9, 0, 0, + 0, 42, 42, 91, 92, 2, 2, 2, 2, 2, 2, 2, 2, 13, 9, 0, + 0, 2, 2, 2, 2, 2, 2, 2, 9, 22, 80, 45, 22, 93, 61, 0, + 0, 94, 95, 94, 94, 96, 97, 0, 0, 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 9, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 0, 0, 2, 2, 2, 2, 29, 0, 0, 0, 2, 2, 2, 2, 2, 9, 0, - 0, 2, 2, 2, 52, 99, 45, 0, 0, 2, 2, 100, 101, 102, 103, 61, - 63, 104, 16, 45, 22, 59, 21, 80, 48, 48, 76, 11, 11, 11, 105, 46, - 40, 11, 106, 74, 2, 2, 2, 2, 2, 2, 2, 107, 22, 20, 20, 22, - 48, 48, 22, 108, 2, 2, 2, 9, 0, 0, 0, 0, 0, 0, 109, 110, - 110, 110, 110, 0, 0, 0, 0, 0, 0, 106, 74, 2, 2, 2, 2, 2, - 2, 60, 61, 59, 25, 22, 111, 61, 2, 2, 2, 2, 107, 22, 23, 45, - 45, 102, 112, 0, 0, 0, 0, 0, 0, 2, 2, 61, 18, 48, 23, 113, - 102, 102, 102, 114, 115, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 30, - 2, 11, 46, 116, 116, 116, 11, 116, 116, 15, 116, 116, 116, 26, 0, 40, - 0, 0, 0, 117, 51, 11, 5, 0, 0, 0, 0, 0, 0, 0, 118, 0, - 0, 0, 0, 0, 0, 0, 6, 119, 120, 42, 42, 5, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 120, 120, 121, 120, 120, 120, 120, 120, 120, 120, - 120, 0, 0, 122, 0, 0, 0, 0, 0, 0, 7, 122, 0, 0, 0, 0, + 0, 2, 2, 2, 52, 98, 45, 0, 0, 2, 2, 99, 100, 101, 102, 61, + 63, 103, 16, 45, 22, 59, 21, 80, 48, 48, 76, 11, 11, 11, 104, 46, + 40, 11, 105, 74, 2, 2, 2, 2, 2, 2, 2, 106, 22, 20, 20, 22, + 48, 48, 22, 107, 2, 2, 2, 9, 0, 0, 0, 0, 0, 0, 108, 109, + 109, 109, 109, 0, 0, 0, 0, 0, 0, 105, 74, 2, 2, 2, 2, 2, + 2, 60, 61, 59, 25, 22, 110, 61, 2, 2, 2, 2, 106, 22, 23, 45, + 45, 101, 111, 0, 0, 0, 0, 0, 0, 2, 2, 61, 18, 48, 23, 112, + 101, 101, 101, 113, 114, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 30, + 2, 11, 46, 115, 115, 115, 11, 115, 115, 15, 115, 115, 115, 26, 0, 40, + 0, 0, 0, 116, 51, 11, 5, 0, 0, 0, 0, 0, 0, 0, 117, 0, + 0, 0, 0, 0, 0, 0, 6, 118, 119, 42, 42, 5, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 119, 119, 120, 119, 119, 119, 119, 119, 119, 119, + 119, 0, 0, 121, 0, 0, 0, 0, 0, 0, 7, 121, 0, 0, 0, 0, 0, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, - 0, 0, 0, 0, 123, 123, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, - 30, 0, 0, 0, 0, 0, 0, 0, 124, 0, 123, 123, 0, 0, 0, 0, - 0, 2, 53, 2, 108, 2, 10, 2, 2, 2, 65, 19, 16, 0, 0, 31, + 0, 0, 0, 0, 122, 122, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, + 30, 0, 0, 0, 0, 0, 0, 0, 123, 0, 122, 122, 0, 0, 0, 0, + 0, 2, 53, 2, 107, 2, 10, 2, 2, 2, 65, 19, 16, 0, 0, 31, 0, 2, 2, 0, 0, 0, 0, 0, 0, 29, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 125, 23, 23, 23, 23, 23, 23, 23, 126, 0, 0, 0, 0, + 2, 2, 2, 124, 23, 23, 23, 23, 23, 23, 23, 125, 0, 0, 0, 0, 0, 11, 11, 11, 11, 11, 11, 11, 11, 11, 2, 0, 0, 0, 0, 0, - 52, 2, 2, 2, 22, 22, 127, 116, 0, 2, 2, 2, 128, 20, 59, 20, - 113, 102, 129, 0, 0, 0, 0, 0, 0, 11, 130, 2, 2, 2, 2, 2, - 2, 2, 131, 23, 22, 20, 48, 132, 133, 134, 0, 0, 0, 0, 0, 0, + 52, 2, 2, 2, 22, 22, 126, 115, 0, 2, 2, 2, 127, 20, 59, 20, + 112, 101, 128, 0, 0, 0, 0, 0, 0, 11, 129, 2, 2, 2, 2, 2, + 2, 2, 130, 23, 22, 20, 48, 131, 132, 133, 0, 0, 0, 0, 0, 0, 0, 2, 2, 52, 30, 2, 2, 2, 2, 2, 2, 2, 2, 10, 22, 59, - 99, 76, 135, 136, 137, 0, 0, 0, 0, 2, 138, 2, 2, 2, 2, 139, - 0, 30, 2, 42, 5, 0, 79, 15, 2, 140, 20, 53, 128, 140, 2, 2, - 141, 10, 9, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 142, 21, - 25, 0, 0, 143, 144, 0, 0, 0, 0, 2, 65, 45, 23, 80, 47, 145, + 98, 76, 134, 135, 136, 0, 0, 0, 0, 2, 137, 2, 2, 2, 2, 138, + 0, 30, 2, 42, 5, 0, 79, 15, 2, 139, 20, 53, 127, 139, 2, 2, + 140, 10, 9, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 141, 21, + 25, 0, 0, 142, 143, 0, 0, 0, 0, 2, 65, 45, 23, 80, 47, 144, 0, 81, 81, 81, 81, 81, 81, 81, 81, 0, 0, 0, 0, 0, 0, 0, - 6, 120, 120, 120, 120, 121, 0, 0, 0, 2, 2, 2, 2, 2, 9, 2, + 6, 119, 119, 119, 119, 120, 0, 0, 0, 2, 2, 2, 2, 2, 9, 2, 2, 2, 9, 2, 30, 2, 2, 2, 2, 2, 30, 2, 2, 2, 30, 9, - 0, 128, 20, 27, 31, 0, 0, 146, 147, 2, 2, 30, 2, 30, 2, 2, - 2, 2, 2, 2, 0, 14, 37, 0, 148, 2, 2, 13, 37, 0, 30, 2, + 0, 127, 20, 27, 31, 0, 0, 145, 146, 2, 2, 30, 2, 30, 2, 2, + 2, 2, 2, 2, 0, 14, 37, 0, 147, 2, 2, 13, 37, 0, 30, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 2, 2, 9, 2, 2, 11, 41, 0, 0, 0, 0, 2, 2, 2, 0, 27, 22, 22, 30, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 27, 38, - 0, 2, 2, 2, 116, 116, 116, 116, 116, 149, 2, 9, 0, 0, 0, 0, + 0, 2, 2, 2, 115, 115, 115, 115, 115, 148, 2, 9, 0, 0, 0, 0, 0, 2, 14, 14, 0, 0, 0, 0, 0, 9, 2, 2, 9, 2, 2, 2, - 2, 30, 2, 9, 0, 30, 2, 0, 0, 150, 151, 152, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 22, 22, 20, 20, 20, 22, 22, 134, 0, 0, 0, - 0, 0, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 2, 2, 2, 2, - 2, 53, 52, 53, 0, 0, 0, 0, 154, 11, 74, 2, 2, 2, 2, 2, + 2, 30, 2, 9, 0, 30, 2, 0, 0, 149, 150, 151, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 22, 22, 20, 20, 20, 22, 22, 133, 0, 0, 0, + 0, 0, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 2, 2, 2, 2, + 2, 53, 52, 53, 0, 0, 0, 0, 153, 11, 74, 2, 2, 2, 2, 2, 2, 18, 19, 21, 16, 24, 37, 0, 0, 0, 31, 0, 0, 0, 0, 0, - 0, 11, 49, 2, 2, 2, 2, 2, 2, 2, 2, 2, 128, 20, 22, 155, - 22, 21, 156, 157, 2, 2, 2, 2, 2, 0, 0, 65, 158, 0, 0, 0, + 0, 11, 49, 2, 2, 2, 2, 2, 2, 2, 2, 2, 127, 20, 22, 154, + 22, 21, 155, 156, 2, 2, 2, 2, 2, 0, 0, 65, 157, 0, 0, 0, 0, 2, 13, 0, 0, 0, 0, 0, 0, 2, 65, 25, 20, 20, 20, 22, - 22, 108, 159, 0, 0, 56, 160, 31, 161, 30, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 23, 19, 22, 22, 162, 44, 0, 0, 0, - 49, 128, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 9, 9, 2, 2, + 22, 107, 158, 0, 0, 56, 159, 31, 160, 30, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 23, 19, 22, 22, 161, 44, 0, 0, 0, + 49, 127, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 9, 9, 2, 2, 30, 2, 2, 2, 2, 2, 2, 2, 30, 2, 2, 2, 2, 2, 2, 2, - 10, 18, 19, 21, 22, 163, 31, 0, 0, 11, 11, 30, 2, 2, 2, 9, + 10, 18, 19, 21, 22, 162, 31, 0, 0, 11, 11, 30, 2, 2, 2, 9, 30, 9, 2, 30, 2, 2, 58, 17, 23, 16, 23, 47, 32, 33, 32, 34, 0, 0, 0, 0, 35, 0, 0, 0, 2, 2, 23, 0, 11, 11, 11, 46, 0, 11, 11, 46, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 30, 0, - 9, 2, 2, 2, 30, 45, 59, 20, 20, 31, 33, 32, 32, 25, 164, 29, - 165, 166, 37, 0, 0, 0, 0, 0, 0, 12, 26, 0, 0, 0, 0, 0, - 0, 2, 2, 65, 25, 20, 20, 20, 22, 23, 126, 15, 17, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 0, 0, 167, 168, 0, 0, 0, 0, 0, 0, - 0, 18, 19, 20, 20, 66, 99, 25, 161, 11, 169, 9, 0, 0, 0, 0, + 9, 2, 2, 2, 30, 45, 59, 20, 20, 31, 33, 32, 32, 25, 163, 29, + 164, 165, 37, 0, 0, 0, 0, 0, 0, 12, 26, 0, 0, 0, 0, 0, + 0, 2, 2, 65, 25, 20, 20, 20, 22, 23, 125, 15, 17, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 0, 0, 166, 167, 0, 0, 0, 0, 0, 0, + 0, 18, 19, 20, 20, 66, 98, 25, 160, 11, 168, 9, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 65, 25, 20, 20, 0, 48, 48, 11, - 170, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 20, - 0, 23, 19, 20, 20, 21, 16, 82, 170, 38, 0, 0, 0, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 10, 171, 25, 20, 22, 22, 169, 9, 0, 0, - 0, 2, 2, 2, 2, 2, 9, 43, 136, 23, 22, 20, 76, 21, 22, 0, + 169, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 20, + 0, 23, 19, 20, 20, 21, 16, 82, 169, 38, 0, 0, 0, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 10, 170, 25, 20, 22, 22, 168, 9, 0, 0, + 0, 2, 2, 2, 2, 2, 9, 43, 135, 23, 22, 20, 76, 21, 22, 0, 0, 2, 2, 2, 9, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 18, - 19, 20, 21, 22, 105, 170, 37, 0, 0, 2, 2, 2, 9, 30, 0, 2, - 2, 2, 2, 30, 9, 2, 2, 2, 2, 23, 23, 18, 32, 33, 12, 172, - 166, 173, 174, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 2, 2, - 2, 65, 25, 20, 20, 0, 22, 23, 29, 108, 0, 33, 0, 0, 0, 0, - 0, 52, 20, 22, 22, 22, 140, 2, 2, 2, 175, 141, 11, 15, 176, 61, - 177, 0, 0, 1, 148, 0, 0, 0, 0, 52, 20, 22, 16, 19, 20, 2, - 2, 2, 2, 159, 159, 159, 178, 178, 178, 178, 178, 178, 15, 179, 0, 30, - 0, 22, 20, 20, 31, 22, 22, 11, 170, 0, 61, 61, 61, 61, 61, 61, - 61, 66, 21, 82, 46, 0, 0, 0, 0, 2, 2, 2, 9, 2, 30, 2, - 2, 52, 22, 22, 31, 0, 38, 22, 27, 11, 160, 180, 181, 0, 0, 0, - 0, 2, 2, 2, 30, 9, 2, 2, 2, 2, 2, 2, 2, 2, 23, 23, - 47, 22, 35, 82, 68, 0, 0, 0, 0, 2, 182, 66, 47, 0, 0, 0, - 0, 11, 183, 2, 2, 2, 2, 2, 2, 2, 2, 23, 22, 20, 31, 0, - 48, 16, 144, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 157, 0, - 0, 184, 184, 184, 184, 184, 184, 184, 184, 185, 185, 185, 186, 187, 185, 184, - 184, 188, 184, 184, 189, 190, 190, 190, 190, 190, 190, 190, 0, 0, 0, 0, - 0, 184, 184, 184, 184, 184, 191, 0, 0, 2, 2, 2, 2, 2, 2, 2, - 22, 22, 22, 22, 22, 22, 192, 193, 194, 11, 11, 11, 46, 0, 0, 0, - 0, 29, 74, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 65, 47, - 0, 2, 2, 2, 2, 2, 9, 0, 58, 195, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, - 40, 116, 26, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 30, 2, 2, 2, 2, 2, 0, 58, - 37, 0, 6, 120, 120, 120, 121, 0, 0, 11, 11, 11, 49, 2, 2, 2, - 0, 2, 2, 2, 2, 2, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, - 46, 2, 2, 2, 2, 2, 2, 11, 11, 2, 2, 2, 2, 2, 2, 22, - 22, 2, 2, 2, 2, 2, 2, 2, 20, 2, 2, 44, 44, 44, 92, 0, - 0, O, O, O, GB, B, B, O, SB, O, SE, GB, O, O, WJ,FMPst, - FMPst, O, CGJ, B, O, B,VMAbv,VMAbv,VMAbv, O,VMAbv, B,CMBlw,CMBlw,CMBlw,VMAbv, - VMPst, VAbv, VPst,CMBlw, B, VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VPst, - VPst, VPst, H, VPre, VPst,VMBlw, O, O, VAbv, GB,VMAbv,VMPst,VMPst, O, B, VBlw, - O, O, VPre, VPre, O, VPre, H, O, VPst,FMAbv, O,CMBlw, O, VAbv, O, VAbv, - H, O,VMBlw,VMAbv,CMAbv, GB, GB, O, MBlw,CMAbv,CMAbv, VPst, VAbv,VMAbv, O, VPst, - O, VPre, VPre,VMAbv, B, O, CS, CS,VMPst, B, VAbv, VAbv, B, R, O, HVM, - O, O,FMBlw, O,CMAbv, O,CMBlw, VAbv, VBlw, B, SUB, SUB, SUB, O, SUB, SUB, - O,FMBlw, O, B, VPst, VBlw, VPre,VMAbv,VMBlw,VMPst, IS, VAbv, MPst, MPre, MBlw, MBlw, - B, MBlw, MBlw, VPst,VMPst,VMPst, B, MBlw, VPst, VPre, VAbv, VAbv,VMPst,VMPst,VMBlw, B, - VMPst, VBlw, VPst, CGJ, CGJ, VPst,VMAbv,VMAbv,FMAbv, FAbv,CMAbv,FMAbv,VMAbv,FMAbv, VAbv, IS, - FMAbv, B,FMAbv, B, CGJ, WJ, CGJ, GB,CMAbv,CMAbv, B, GB, B, VAbv, SUB, FPst, - FPst,VMBlw, FPst, FPst, FBlw,VMAbv,FMBlw, VAbv, VPre, B, MPre, MBlw, SUB, FAbv, FAbv, MAbv, - SUB, Sk, VPst, VAbv,VMAbv,VMAbv, FAbv,CMAbv, VPst, H, B, O,SMAbv,SMAbv,SMAbv, VPst, - IS, RK, RK, VBlw, FAbv,VMPre,VMPre,FMAbv,CMBlw,VMBlw,VMBlw,VMAbv, CS, O,FMAbv, ZWNJ, - CGJ, WJ, WJ, WJ, O,FMPst, O, SB, SE, O, H, MPst, VPst, H,VMAbv, VAbv, - VMBlw, B, VBlw, FPst, VPst, FAbv,VMPst, B,CMAbv, VAbv, MBlw, MPst, MBlw, H, O, VBlw, - MPst, MPre, MAbv, MBlw, O, B, FAbv, FAbv, FPst, VBlw, B, VBlw,VMAbv, B, VPre, O, - VMPst, IS, O,VMPst, VBlw, VPst,VMBlw,VMBlw,VMAbv, O, IS,VMBlw, B,VMPst,VMAbv,VMPst, - CS, CS, B, N, N, O, HN, VPre, VBlw, VAbv, IS,CMAbv, O, VPst, B, R, - R,CMBlw, VAbv, VPre,VMAbv,VMAbv, H, VAbv,CMBlw,VMPst, O,VMAbv,CMBlw, IS, R,FMAbv, - B, CS, CS, H,CMBlw,VMPst, H,VMPst, VAbv,VMAbv, VPst, MPst, R, MPst,CMBlw, B, - FMBlw, CS, SUB, SUB, GB, FBlw, FBlw,CMAbv, IS, VBlw, IS, R, MBlw, GB, VAbv, R, - VMPst, G, G, J, J, J, SB, SE, J, HR, G, G, HM, HM, HM, G, - O, MPre, MPre, MPst,VMAbv, MBlw, VBlw, O, VBlw, + 19, 20, 21, 22, 104, 169, 37, 0, 0, 2, 2, 2, 9, 30, 0, 2, + 2, 2, 2, 30, 9, 2, 2, 2, 2, 23, 23, 18, 32, 33, 12, 171, + 165, 172, 173, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 2, 2, + 2, 65, 25, 20, 20, 0, 22, 23, 29, 107, 0, 33, 0, 0, 0, 0, + 0, 52, 20, 22, 22, 22, 139, 2, 2, 2, 174, 140, 11, 15, 175, 61, + 176, 0, 0, 1, 147, 0, 0, 0, 0, 52, 20, 22, 16, 19, 20, 2, + 2, 2, 2, 158, 158, 158, 177, 177, 177, 177, 177, 177, 15, 178, 0, 30, + 0, 16, 20, 16, 16, 0, 0, 0, 0, 22, 20, 20, 31, 22, 22, 11, + 169, 0, 61, 61, 61, 61, 61, 61, 61, 66, 21, 82, 46, 0, 0, 0, + 0, 2, 2, 2, 9, 2, 30, 2, 2, 52, 22, 22, 31, 0, 38, 22, + 27, 11, 159, 179, 180, 0, 0, 0, 0, 2, 2, 2, 30, 9, 2, 2, + 2, 2, 2, 2, 2, 2, 23, 23, 47, 22, 35, 82, 68, 0, 0, 0, + 0, 2, 181, 66, 47, 0, 0, 0, 0, 11, 182, 2, 2, 2, 2, 2, + 2, 2, 2, 23, 22, 20, 31, 0, 48, 16, 143, 0, 0, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 156, 0, 0, 183, 183, 183, 183, 183, 183, 183, + 183, 184, 184, 184, 185, 186, 184, 183, 183, 187, 183, 183, 188, 189, 189, 189, + 189, 189, 189, 189, 0, 0, 0, 0, 0, 183, 183, 183, 183, 183, 190, 0, + 0, 2, 2, 2, 2, 2, 2, 2, 22, 22, 22, 22, 22, 22, 191, 192, + 193, 11, 11, 11, 46, 0, 0, 0, 0, 29, 74, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 65, 47, 0, 2, 2, 2, 2, 2, 9, 0, + 58, 194, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 0, 0, 0, 40, 115, 26, 0, 0, 0, 0, 0, + 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 30, 2, 2, 2, 2, 2, 0, 58, 37, 0, 6, 119, 119, 119, 120, 0, + 0, 11, 11, 11, 49, 2, 2, 2, 0, 2, 2, 2, 2, 2, 0, 0, + 2, 2, 2, 2, 2, 2, 2, 2, 46, 2, 2, 2, 2, 2, 2, 11, + 11, 2, 2, 2, 2, 2, 2, 22, 22, 2, 2, 2, 2, 2, 2, 2, + 20, 2, 2, 44, 44, 44, 92, 0, 0, O, O, O, GB, B, B, O, + SB, O, SE, GB, O, O, WJ,FMPst,FMPst, O, CGJ, B, O, B,VMAbv,VMAbv, + VMAbv, O,VMAbv, B,CMBlw,CMBlw,CMBlw,VMAbv,VMPst, VAbv, VPst,CMBlw, B, VPst, VPre, VPst, + VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VPst, VPst, VPst, H, VPre, VPst,VMBlw, O, O, + VAbv, GB,VMAbv,VMPst,VMPst, O, B, VBlw, O, O, VPre, VPre, O, VPre, H, O, + VPst,FMAbv, O,CMBlw, O, VAbv, O, VAbv, H, O,VMBlw,VMAbv,CMAbv, GB, GB, O, + MBlw,CMAbv,CMAbv, VPst, VAbv,VMAbv, O, VPst, O, VPre, VPre,VMAbv, B, O, CS, CS, + VMPst, B, VAbv, VAbv, B, R, O, HVM, O, O,FMBlw, O,CMAbv, O,CMBlw, VAbv, + VBlw, B, SUB, SUB, SUB, O, SUB, SUB, O,FMBlw, O, B, VPst, VBlw, VPre,VMAbv, + VMBlw,VMPst, IS, VAbv, MPst, MPre, MBlw, MBlw, B, MBlw, MBlw, VPst,VMPst,VMPst, B, MBlw, + VPst, VPre, VAbv, VAbv,VMPst,VMPst,VMBlw, B,VMPst, VBlw, VPst, CGJ, CGJ, VPst,VMAbv,VMAbv, + FMAbv, FAbv,CMAbv,FMAbv,VMAbv,FMAbv, VAbv, IS,FMAbv, B,FMAbv, B, CGJ, WJ, CGJ, GB, + CMAbv,CMAbv, B, VAbv, SUB, FPst, FPst,VMBlw, FPst, FPst, FBlw,VMAbv,FMBlw, VAbv, VPre, B, + MPre, MBlw, SUB, FAbv, FAbv, MAbv, SUB, Sk, VPst, VAbv,VMAbv,VMAbv, FAbv,CMAbv, VPst, H, + B, O,SMAbv,SMAbv,SMAbv, VPst, IS, RK, RK, VBlw, FAbv,VMPre,VMPre,FMAbv,CMBlw,VMBlw, + VMBlw,VMAbv, CS, O,FMAbv, ZWNJ, CGJ, WJ, WJ, WJ, O,FMPst, O, SB, SE, O, + H, MPst, VPst, H,VMAbv, VAbv,VMBlw, B, VBlw, FPst, VPst, FAbv,VMPst, B,CMAbv, VAbv, + MBlw, MPst, MBlw, H, O, VBlw, MPst, MPre, MAbv, MBlw, O, B, FAbv, FAbv, FPst, VBlw, + B, VBlw,VMAbv, B, VPre, O,VMPst, IS, O,VMPst, VBlw, VPst,VMBlw,VMBlw,VMAbv, O, + IS,VMBlw, B,VMPst,VMAbv,VMPst, CS, CS, B, N, N, O, HN, VPre, VBlw, VAbv, + IS,CMAbv, O, VPst, B, R, R,CMBlw, VAbv, VPre,VMAbv,VMAbv, H, VAbv,CMBlw,VMPst, + O,VMAbv,CMBlw, IS, R,FMAbv, B, CS, CS, H,CMBlw,VMPst, H,VMPst, VAbv,VMAbv, + VPst, MPst, R, MPst,CMBlw, B,FMBlw, CS, SUB, SUB, GB, FBlw, FBlw,CMAbv, IS, VBlw, + IS, R, MBlw, GB, VAbv, R,VMPst, G, G, J, J, J, SB, SE, J, HR, + G, G, HM, HM, HM, G, O, MPre, MPre, MPst,VMAbv, MBlw, VBlw, O, VBlw, }; -static const uint16_t hb_use_u16[486]= +static const uint16_t hb_use_u16[488]= { 0, 0, 1, 2, 0, 3, 4, 5, 0, 6, 7, 0, 8, 0, 9, 10, 11, 12, 10, 13, 14, 10, 10, 15, 16, 17, 18, 19, 20, 21, 22, 23, @@ -631,28 +630,28 @@ static const uint16_t hb_use_u16[486]= 31, 66, 67, 68, 10, 69, 70, 10, 71, 72, 73, 74, 75, 76, 77, 0, 10, 10, 78, 79, 80, 81, 82, 83, 84, 85, 10, 86, 10, 87, 10, 88, 89, 90, 10, 91, 92, 93, 2, 0, 94, 0, 10, 95, 96, 10, 97, 0, - 98, 99,100,101, 31, 10,102,103,104, 10,105,106, 10,107, 10,108, - 109,110, 2, 2,111, 10, 10,112,113, 2,114,115,116, 10,117, 10, - 118,119,120,121,122, 0, 0,123,124,125, 0,126,127,128,129, 0, - 130,131,132, 0, 0,133,134, 0,135, 0, 0, 10,136,137,138, 0, - 139, 10,140, 0, 10,141,142, 10, 10,143,144, 2,145,146,147, 10, - 148,149,150, 10, 10,151,152, 2,153, 99,154,155,156, 2, 10,157, - 10,158,159, 0,160,161,162, 2,163, 0, 0,164, 0,165, 0,166, - 166,167, 34,168,169,170, 10,171, 95, 0,172, 0, 10,173,174, 0, - 175, 2,176, 10,177, 0,178,173,179,180,181, 0, 0,182,183, 0, - 184, 10, 10,185,186,187,188,189,190, 10, 10,191,192, 0,193, 10, - 194,195,196, 10, 10,197, 10,198,199,106,200,103, 10, 34,201,202, - 203, 0,204,205, 95, 10, 10,206,207, 2,208, 21, 22,209,210,211, - 212,213,214, 10, 10,215,216,217,218, 0, 10,219,220,221,222, 0, - 200, 10, 10,223,224, 2,225,226,227,228, 10,229,230, 2,231,232, - 2, 10,141, 0, 10,233,234,104,235, 0,236,237,238,239, 10,240, - 241, 2,242, 10, 10,243,244, 0,245, 10, 10,246,247,248,249,250, - 22, 10,225,251, 8, 10, 71, 19, 10,252, 74,253,254, 10, 10,255, - 256, 2,257, 10,258,259, 10,260,261, 49, 10,262,263,264,265,265, - 265,266,267,268,265,269, 10,270,271, 2, 10,272,273, 10,274, 2, - 275,276,277,277,278,279,280, 0, 10,177, 0,281,106, 71, 95,282, - 0,283, 71,284,285, 0,286, 0,287, 2,288, 2,289,106,290, 2, - 130,130,163,163,163,130, + 10, 98, 99,100, 31, 10,101,102,103, 10,104,105, 10,106, 10,107, + 108,109, 2, 2,110, 10, 10,111,112, 2,113,114,115, 10,116, 10, + 117,118,119,120,121, 0, 0,122,123,124, 0,125,126,127,128, 0, + 129,130,131, 0, 0,132,133, 0,134, 0, 0, 10,135,136,137, 0, + 138, 10,139, 0, 10,140,141, 10, 10,142,143, 2,144,145,146, 10, + 147,148,149, 10, 10,150,151, 2,152, 98,153,154,155, 2, 10,156, + 10,157,158, 0,159,160,161, 2,162, 0, 0,163, 0,164, 0,165, + 165,166, 34,167,168,169, 10,170, 95, 0,171, 0, 10,172,173, 0, + 174, 2,175, 10,176, 0,177,172,178,179,180, 0, 0,181,182, 0, + 183, 10, 10,184,185,186,187,188,189, 10, 10,190,191, 0,192, 10, + 193,194,195, 10, 10,196, 10,197,198,105,199,102, 10, 34,200,201, + 202, 0,203,204, 95, 10, 10,205,206, 2,207, 21, 22,208,209,210, + 211,212,213, 10, 10,214,215,216,217, 0, 10,218,219,220,221, 0, + 199, 10, 10,222,223, 2,224,225,226,227, 10,228,229, 2,230,231, + 2, 10,140, 0, 10,232,233,103,234, 0,235,236,237,238, 10,239, + 240, 2,241, 10, 10,242,243, 0,244, 10, 10,245,246,247,248,249, + 250, 0, 22, 10,224,251, 8, 10, 71, 19, 10,252, 74,253,254, 10, + 10,255,256, 2,257, 10,258,259, 10,260,261, 49, 10,262,263,264, + 265,265,265,266,267,268,265,269, 10,270,271, 2, 10,272,273, 10, + 274, 2,275,276,277,277,278,279,280, 0, 10,176, 0,281,105, 71, + 95,282, 0,283, 71,284,285, 0,286, 0,287, 2,288, 2,289,105, + 290, 2,129,129,162,162,162,129, }; static inline uint8_t hb_use_b4 (const uint8_t* a, unsigned i) @@ -661,11 +660,13 @@ static inline uint8_t hb_use_b4 (const uint8_t* a, unsigned i) } static inline uint8_t hb_use_get_category (unsigned u) { - return u<921600 ? hb_use_u8[3265u+(((hb_use_u8[937u+(((hb_use_u16[((hb_use_u8[369u+(((hb_use_u8[113u+(((hb_use_b4(hb_use_u8,u>>1>>3>>1>>3>>4))<<4)+((u>>1>>3>>1>>3)&15))])<<3)+((u>>1>>3>>1)&7))])<<1)+((u>>1>>3)&1)])<<3)+((u>>1)&7))])<<1)+((u)&1))] : O; + return u<921600 ? hb_use_u8[3273u+((hb_use_u8[945u+((hb_use_u16[((hb_use_u8[369u+((hb_use_u8[113u+((hb_use_b4(hb_use_u8,((((((((((u)>>1))>>3))>>1))>>3))>>4)))<<4)+((((((((((u)>>1))>>3))>>1))>>3))&15)])<<3)+((((((((u)>>1))>>3))>>1))&7)])<<1)+((((((u)>>1))>>3))&1)])<<3)+((((u)>>1))&7)])<<1)+((u)&1)] : O; } + #endif + #undef B #undef CGJ #undef CS diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-vowel-constraints.cc b/thirdparty/harfbuzz/src/hb-ot-shaper-vowel-constraints.cc index a48b9b9ae7e..079fee9bc68 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-vowel-constraints.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-vowel-constraints.cc @@ -10,8 +10,8 @@ * # Date: 2015-03-12, 21:17:00 GMT [AG] * # Date: 2019-11-08, 23:22:00 GMT [AG] * - * # Scripts-16.0.0.txt - * # Date: 2024-04-30, 21:48:40 GMT + * # Scripts-17.0.0.txt + * # Date: 2025-07-24, 13:28:55 GMT */ #include "hb.hh" diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper.hh b/thirdparty/harfbuzz/src/hb-ot-shaper.hh index 8a094739cb7..67deb794985 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shaper.hh @@ -396,6 +396,12 @@ hb_ot_shaper_categorize (hb_script_t script, case HB_SCRIPT_TODHRI: case HB_SCRIPT_TULU_TIGALARI: + /* Unicode-17.0 additions */ + case HB_SCRIPT_BERIA_ERFE: + case HB_SCRIPT_SIDETIC: + case HB_SCRIPT_TAI_YO: + case HB_SCRIPT_TOLONG_SIKI: + /* If the designer designed the font for the 'DFLT' script, * (or we ended up arbitrarily pick 'latn'), use the default shaper. * Otherwise, use the specific shaper. diff --git a/thirdparty/harfbuzz/src/hb-ot-tag-table.hh b/thirdparty/harfbuzz/src/hb-ot-tag-table.hh index f8a1c74e2b6..29905984a06 100644 --- a/thirdparty/harfbuzz/src/hb-ot-tag-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-tag-table.hh @@ -7,7 +7,7 @@ * on files with these headers: * * - * File-Date: 2025-03-10 + * File-Date: 2025-08-25 */ #ifndef HB_OT_TAG_TABLE_HH @@ -704,7 +704,7 @@ static const LangTag ot_languages3[] = { /*{HB_TAG('g','u','z',' '), HB_TAG('G','U','Z',' ')},*/ /* Gusii */ {HB_TAG('g','w','i',' '), HB_TAG('A','T','H',' ')}, /* Gwichʼin -> Athapaskan */ {HB_TAG('g','y','n',' '), HB_TAG('C','P','P',' ')}, /* Guyanese Creole English -> Creoles */ - {HB_TAG('h','a','a',' '), HB_TAG('A','T','H',' ')}, /* Han -> Athapaskan */ + {HB_TAG('h','a','a',' '), HB_TAG('A','T','H',' ')}, /* Hän -> Athapaskan */ {HB_TAG('h','a','e',' '), HB_TAG('O','R','O',' ')}, /* Eastern Oromo -> Oromo */ {HB_TAG('h','a','i',' '), HB_TAG('H','A','I','0')}, /* Haida [macrolanguage] */ {HB_TAG('h','a','k',' '), HB_TAG('Z','H','S',' ')}, /* Hakka Chinese -> Chinese, Simplified */ @@ -921,7 +921,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('k','v','t',' '), HB_TAG('K','R','N',' ')}, /* Lahta Karen -> Karen */ {HB_TAG('k','v','u',' '), HB_TAG('K','R','N',' ')}, /* Yinbaw Karen -> Karen */ {HB_TAG('k','v','y',' '), HB_TAG('K','R','N',' ')}, /* Yintale Karen -> Karen */ -/*{HB_TAG('k','w','k',' '), HB_TAG('K','W','K',' ')},*/ /* Kwakiutl -> Kwakʼwala */ +/*{HB_TAG('k','w','k',' '), HB_TAG('K','W','K',' ')},*/ /* Kwakʼwala */ {HB_TAG('k','w','w',' '), HB_TAG('C','P','P',' ')}, /* Kwinti -> Creoles */ {HB_TAG('k','w','y',' '), HB_TAG('K','O','N','0')}, /* San Salvador Kongo -> Kongo */ {HB_TAG('k','x','c',' '), HB_TAG('K','M','S',' ')}, /* Konso -> Komso */ diff --git a/thirdparty/harfbuzz/src/hb-ot-var-avar-table.hh b/thirdparty/harfbuzz/src/hb-ot-var-avar-table.hh index 880b081316b..71aed2e8edf 100644 --- a/thirdparty/harfbuzz/src/hb-ot-var-avar-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-var-avar-table.hh @@ -388,13 +388,18 @@ struct avar const auto &var_store = this+v2.varStore; auto *var_store_cache = var_store.create_cache (); + hb_vector_t coords_2_14; + coords_2_14.resize (coords_length); + for (unsigned i = 0; i < coords_length; i++) + coords_2_14[i] = roundf (coords[i] / 4.f); // 16.16 -> 2.14 + hb_vector_t out; out.alloc (coords_length); for (unsigned i = 0; i < coords_length; i++) { int v = coords[i]; uint32_t varidx = varidx_map.map (i); - float delta = var_store.get_delta (varidx, coords, coords_length, var_store_cache); + float delta = var_store.get_delta (varidx, coords_2_14.arrayZ, coords_2_14.length, var_store_cache); v += roundf (delta * 4); // 2.14 -> 16.16 v = hb_clamp (v, -(1<<16), +(1<<16)); out.push (v); diff --git a/thirdparty/harfbuzz/src/hb-ot-var-common.hh b/thirdparty/harfbuzz/src/hb-ot-var-common.hh index 722e8599a96..a8c8858e54a 100644 --- a/thirdparty/harfbuzz/src/hb-ot-var-common.hh +++ b/thirdparty/harfbuzz/src/hb-ot-var-common.hh @@ -27,12 +27,15 @@ #define HB_OT_VAR_COMMON_HH #include "hb-ot-layout-common.hh" +#include "hb-alloc-pool.hh" #include "hb-priority-queue.hh" #include "hb-subset-instancer-iup.hh" namespace OT { +using rebase_tent_result_scratch_t = hb_pair_t; + /* https://docs.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#tuplevariationheader */ struct TupleVariationHeader { @@ -220,6 +223,21 @@ struct TupleVariationHeader DEFINE_SIZE_MIN (4); }; +struct optimize_scratch_t +{ + iup_scratch_t iup; + hb_vector_t opt_indices; + hb_vector_t rounded_x_deltas; + hb_vector_t rounded_y_deltas; + hb_vector_t opt_deltas_x; + hb_vector_t opt_deltas_y; + hb_vector_t opt_point_data; + hb_vector_t opt_deltas_data; + hb_vector_t point_data; + hb_vector_t deltas_data; + hb_vector_t rounded_deltas; +}; + struct tuple_delta_t { static constexpr bool realloc_move = true; // Watch out when adding new members! @@ -240,11 +258,12 @@ struct tuple_delta_t hb_vector_t compiled_tuple_header; hb_vector_t compiled_deltas; - /* compiled peak coords, empty for non-gvar tuples */ - hb_vector_t compiled_peak_coords; + hb_vector_t compiled_peak_coords; + hb_vector_t compiled_interm_coords; - tuple_delta_t () = default; + tuple_delta_t (hb_alloc_pool_t *pool = nullptr) {} tuple_delta_t (const tuple_delta_t& o) = default; + tuple_delta_t& operator = (const tuple_delta_t& o) = default; friend void swap (tuple_delta_t& a, tuple_delta_t& b) noexcept { @@ -266,6 +285,18 @@ struct tuple_delta_t return *this; } + void copy_from (const tuple_delta_t& o, hb_alloc_pool_t *pool = nullptr) + { + axis_tuples = o.axis_tuples; + indices.allocate_from_pool (pool, o.indices); + deltas_x.allocate_from_pool (pool, o.deltas_x); + deltas_y.allocate_from_pool (pool, o.deltas_y); + compiled_tuple_header.allocate_from_pool (pool, o.compiled_tuple_header); + compiled_deltas.allocate_from_pool (pool, o.compiled_deltas); + compiled_peak_coords.allocate_from_pool (pool, o.compiled_peak_coords); + compiled_interm_coords.allocate_from_pool (pool, o.compiled_interm_coords); + } + void remove_axis (hb_tag_t axis_tag) { axis_tuples.del (axis_tag); } @@ -320,31 +351,44 @@ struct tuple_delta_t return *this; } - hb_vector_t change_tuple_var_axis_limit (hb_tag_t axis_tag, Triple axis_limit, - TripleDistances axis_triple_distances) const + void change_tuple_var_axis_limit (hb_tag_t axis_tag, Triple axis_limit, + TripleDistances axis_triple_distances, + hb_vector_t& out, + rebase_tent_result_scratch_t &scratch, + hb_alloc_pool_t *pool = nullptr) { - hb_vector_t out; + // May move *this out. + + out.reset (); Triple *tent; if (!axis_tuples.has (axis_tag, &tent)) { - out.push (*this); - return out; + out.push (std::move (*this)); + return; } if ((tent->minimum < 0.0 && tent->maximum > 0.0) || !(tent->minimum <= tent->middle && tent->middle <= tent->maximum)) - return out; + return; if (tent->middle == 0.0) { - out.push (*this); - return out; + out.push (std::move (*this)); + return; } - rebase_tent_result_t solutions = rebase_tent (*tent, axis_limit, axis_triple_distances); - for (auto &t : solutions) + rebase_tent_result_t &solutions = scratch.first; + rebase_tent (*tent, axis_limit, axis_triple_distances, solutions, scratch.second); + for (unsigned i = 0; i < solutions.length; i++) { - tuple_delta_t new_var = *this; + auto &t = solutions.arrayZ[i]; + + tuple_delta_t new_var; + if (i < solutions.length - 1) + new_var.copy_from (*this, pool); + else + new_var = std::move (*this); + if (t.second == Triple ()) new_var.remove_axis (axis_tag); else @@ -353,38 +397,76 @@ struct tuple_delta_t new_var *= t.first; out.push (std::move (new_var)); } - - return out; } - bool compile_peak_coords (const hb_map_t& axes_index_map, - const hb_map_t& axes_old_index_tag_map) + bool compile_coords (const hb_map_t& axes_index_map, + const hb_map_t& axes_old_index_tag_map, + hb_alloc_pool_t *pool= nullptr) { - unsigned axis_count = axes_index_map.get_population (); - if (unlikely (!compiled_peak_coords.alloc (axis_count * F2DOT14::static_size))) + unsigned cur_axis_count = axes_index_map.get_population (); + if (pool) + { + if (unlikely (!compiled_peak_coords.allocate_from_pool (pool, cur_axis_count))) + return false; + } + else if (unlikely (!compiled_peak_coords.resize (cur_axis_count))) return false; + hb_array_t start_coords, end_coords; + unsigned orig_axis_count = axes_old_index_tag_map.get_population (); + unsigned j = 0; for (unsigned i = 0; i < orig_axis_count; i++) { if (!axes_index_map.has (i)) continue; hb_tag_t axis_tag = axes_old_index_tag_map.get (i); - Triple *coords; - F2DOT14 peak_coord; + Triple *coords = nullptr; if (axis_tuples.has (axis_tag, &coords)) - peak_coord.set_float (coords->middle); - else - peak_coord.set_int (0); + { + float min_val = coords->minimum; + float val = coords->middle; + float max_val = coords->maximum; - /* push F2DOT14 value into char vector */ - int16_t val = peak_coord.to_int (); - compiled_peak_coords.push (static_cast (val >> 8)); - compiled_peak_coords.push (static_cast (val & 0xFF)); + compiled_peak_coords.arrayZ[j].set_float (val); + + if (min_val != hb_min (val, 0.f) || max_val != hb_max (val, 0.f)) + { + if (!compiled_interm_coords) + { + if (pool) + { + if (unlikely (!compiled_interm_coords.allocate_from_pool (pool, 2 * cur_axis_count))) + return false; + } + else if (unlikely (!compiled_interm_coords.resize (2 * cur_axis_count))) + return false; + start_coords = compiled_interm_coords.as_array ().sub_array (0, cur_axis_count); + end_coords = compiled_interm_coords.as_array ().sub_array (cur_axis_count); + + for (unsigned k = 0; k < j; k++) + { + signed peak = compiled_peak_coords.arrayZ[k].to_int (); + if (!peak) continue; + start_coords.arrayZ[k].set_int (hb_min (peak, 0)); + end_coords.arrayZ[k].set_int (hb_max (peak, 0)); + } + } + + } + + if (compiled_interm_coords) + { + start_coords.arrayZ[j].set_float (min_val); + end_coords.arrayZ[j].set_float (max_val); + } + } + + j++; } - return !compiled_peak_coords.in_error (); + return !compiled_peak_coords.in_error () && !compiled_interm_coords.in_error (); } /* deltas should be compiled already before we compile tuple @@ -393,7 +475,8 @@ struct tuple_delta_t bool compile_tuple_var_header (const hb_map_t& axes_index_map, unsigned points_data_length, const hb_map_t& axes_old_index_tag_map, - const hb_hashmap_t*, unsigned>* shared_tuples_idx_map) + const hb_hashmap_t*, unsigned>* shared_tuples_idx_map, + hb_alloc_pool_t *pool = nullptr) { /* compiled_deltas could be empty after iup delta optimization, we can skip * compiling this tuple and return true */ @@ -402,7 +485,7 @@ struct tuple_delta_t unsigned cur_axis_count = axes_index_map.get_population (); /* allocate enough memory: 1 peak + 2 intermediate coords + fixed header size */ unsigned alloc_len = 3 * cur_axis_count * (F2DOT14::static_size) + 4; - if (unlikely (!compiled_tuple_header.resize (alloc_len))) return false; + if (unlikely (!compiled_tuple_header.allocate_from_pool (pool, alloc_len, false))) return false; unsigned flag = 0; /* skip the first 4 header bytes: variationDataSize+tupleIndex */ @@ -410,6 +493,9 @@ struct tuple_delta_t F2DOT14* end = reinterpret_cast (compiled_tuple_header.end ()); hb_array_t coords (p, end - p); + if (!shared_tuples_idx_map) + compile_coords (axes_index_map, axes_old_index_tag_map); // non-gvar tuples do not have compiled coords yet + /* encode peak coords */ unsigned peak_count = 0; unsigned *shared_tuple_idx; @@ -420,12 +506,12 @@ struct tuple_delta_t } else { - peak_count = encode_peak_coords(coords, flag, axes_index_map, axes_old_index_tag_map); + peak_count = encode_peak_coords(coords, flag); if (!peak_count) return false; } /* encode interim coords, it's optional so returned num could be 0 */ - unsigned interim_count = encode_interm_coords (coords.sub_array (peak_count), flag, axes_index_map, axes_old_index_tag_map); + unsigned interim_count = encode_interm_coords (coords.sub_array (peak_count), flag); /* pointdata length = 0 implies "use shared points" */ if (points_data_length) @@ -437,105 +523,63 @@ struct tuple_delta_t o->tupleIndex = flag; unsigned total_header_len = 4 + (peak_count + interim_count) * (F2DOT14::static_size); - return compiled_tuple_header.resize (total_header_len); + compiled_tuple_header.shrink_back_to_pool (pool, total_header_len); + return true; } unsigned encode_peak_coords (hb_array_t peak_coords, - unsigned& flag, - const hb_map_t& axes_index_map, - const hb_map_t& axes_old_index_tag_map) const + unsigned& flag) const { - unsigned orig_axis_count = axes_old_index_tag_map.get_population (); - auto it = peak_coords.iter (); - unsigned count = 0; - for (unsigned i = 0; i < orig_axis_count; i++) - { - if (!axes_index_map.has (i)) /* axis pinned */ - continue; - hb_tag_t axis_tag = axes_old_index_tag_map.get (i); - Triple *coords; - if (!axis_tuples.has (axis_tag, &coords)) - (*it).set_int (0); - else - (*it).set_float (coords->middle); - it++; - count++; - } + hb_memcpy (&peak_coords[0], &compiled_peak_coords[0], compiled_peak_coords.length * sizeof (compiled_peak_coords[0])); flag |= TupleVariationHeader::TuppleIndex::EmbeddedPeakTuple; - return count; + return compiled_peak_coords.length; } /* if no need to encode intermediate coords, then just return p */ unsigned encode_interm_coords (hb_array_t coords, - unsigned& flag, - const hb_map_t& axes_index_map, - const hb_map_t& axes_old_index_tag_map) const + unsigned& flag) const { - unsigned orig_axis_count = axes_old_index_tag_map.get_population (); - unsigned cur_axis_count = axes_index_map.get_population (); - - auto start_coords_iter = coords.sub_array (0, cur_axis_count).iter (); - auto end_coords_iter = coords.sub_array (cur_axis_count).iter (); - bool encode_needed = false; - unsigned count = 0; - for (unsigned i = 0; i < orig_axis_count; i++) - { - if (!axes_index_map.has (i)) /* axis pinned */ - continue; - hb_tag_t axis_tag = axes_old_index_tag_map.get (i); - Triple *coords; - float min_val = 0.f, val = 0.f, max_val = 0.f; - if (axis_tuples.has (axis_tag, &coords)) - { - min_val = coords->minimum; - val = coords->middle; - max_val = coords->maximum; - } - - (*start_coords_iter).set_float (min_val); - (*end_coords_iter).set_float (max_val); - - start_coords_iter++; - end_coords_iter++; - count += 2; - if (min_val != hb_min (val, 0.f) || max_val != hb_max (val, 0.f)) - encode_needed = true; - } - - if (encode_needed) + if (compiled_interm_coords) { + hb_memcpy (&coords[0], &compiled_interm_coords[0], compiled_interm_coords.length * sizeof (compiled_interm_coords[0])); flag |= TupleVariationHeader::TuppleIndex::IntermediateRegion; - return count; } - return 0; + return compiled_interm_coords.length; } - bool compile_deltas () - { return compile_deltas (indices, deltas_x, deltas_y, compiled_deltas); } + bool compile_deltas (hb_vector_t &rounded_deltas_scratch, + hb_alloc_pool_t *pool = nullptr) + { return compile_deltas (indices, deltas_x, deltas_y, compiled_deltas, rounded_deltas_scratch, pool); } static bool compile_deltas (hb_array_t point_indices, hb_array_t x_deltas, hb_array_t y_deltas, - hb_vector_t &compiled_deltas /* OUT */) + hb_vector_t &compiled_deltas, /* OUT */ + hb_vector_t &rounded_deltas, /* scratch */ + hb_alloc_pool_t *pool = nullptr) { - hb_vector_t rounded_deltas; - if (unlikely (!rounded_deltas.alloc (point_indices.length))) + if (unlikely (!rounded_deltas.resize_dirty (point_indices.length))) return false; + unsigned j = 0; for (unsigned i = 0; i < point_indices.length; i++) { if (!point_indices[i]) continue; - int rounded_delta = (int) roundf (x_deltas.arrayZ[i]); - rounded_deltas.push (rounded_delta); + rounded_deltas.arrayZ[j++] = (int) roundf (x_deltas.arrayZ[i]); } + rounded_deltas.resize (j); if (!rounded_deltas) return true; - /* allocate enough memories 5 * num_deltas */ - unsigned alloc_len = 5 * rounded_deltas.length; + /* Allocate enough memory: this is the correct bound: + * Worst case scenario is that each delta has to be encoded in 4 bytes, and there + * are runs of 64 items each. Any delta encoded in less than 4 bytes (2, 1, or 0) + * is still smaller than the 4-byte encoding even with their control byte. + * The initial 2 is to handle length==0, for both x and y deltas. */ + unsigned alloc_len = 2 + 4 * rounded_deltas.length + (rounded_deltas.length + 63) / 64; if (y_deltas) alloc_len *= 2; - if (unlikely (!compiled_deltas.resize (alloc_len))) return false; + if (unlikely (!compiled_deltas.allocate_from_pool (pool, alloc_len, false))) return false; unsigned encoded_len = compile_deltas (compiled_deltas, rounded_deltas); @@ -556,28 +600,30 @@ struct tuple_delta_t if (j != rounded_deltas.length) return false; encoded_len += compile_deltas (compiled_deltas.as_array ().sub_array (encoded_len), rounded_deltas); } - return compiled_deltas.resize (encoded_len); + compiled_deltas.shrink_back_to_pool (pool, encoded_len); + return true; } static unsigned compile_deltas (hb_array_t encoded_bytes, hb_array_t deltas) { - return TupleValues::compile (deltas, encoded_bytes); + return TupleValues::compile_unsafe (deltas, encoded_bytes); } - bool calc_inferred_deltas (const contour_point_vector_t& orig_points) + bool calc_inferred_deltas (const contour_point_vector_t& orig_points, + hb_vector_t &scratch) { unsigned point_count = orig_points.length; if (point_count != indices.length) return false; unsigned ref_count = 0; - hb_vector_t end_points; + + hb_vector_t &end_points = scratch.reset (); for (unsigned i = 0; i < point_count; i++) { - if (indices.arrayZ[i]) - ref_count++; + ref_count += indices.arrayZ[i]; if (orig_points.arrayZ[i].is_end_point) end_points.push (i); } @@ -586,7 +632,7 @@ struct tuple_delta_t return true; if (unlikely (end_points.in_error ())) return false; - hb_set_t inferred_idxes; + hb_bit_set_t inferred_idxes; unsigned start_point = 0; for (unsigned end_point : end_points) { @@ -660,6 +706,7 @@ struct tuple_delta_t bool optimize (const contour_point_vector_t& contour_points, bool is_composite, + optimize_scratch_t &scratch, double tolerance = 0.5 + 1e-10) { unsigned count = contour_points.length; @@ -667,22 +714,21 @@ struct tuple_delta_t deltas_y.length != count) return false; - hb_vector_t opt_indices; - hb_vector_t rounded_x_deltas, rounded_y_deltas; + hb_vector_t &opt_indices = scratch.opt_indices.reset (); + hb_vector_t &rounded_x_deltas = scratch.rounded_x_deltas; + hb_vector_t &rounded_y_deltas = scratch.rounded_y_deltas; - if (unlikely (!rounded_x_deltas.alloc (count) || - !rounded_y_deltas.alloc (count))) + if (unlikely (!rounded_x_deltas.resize_dirty (count) || + !rounded_y_deltas.resize_dirty (count))) return false; for (unsigned i = 0; i < count; i++) { - int rounded_x_delta = (int) roundf (deltas_x.arrayZ[i]); - int rounded_y_delta = (int) roundf (deltas_y.arrayZ[i]); - rounded_x_deltas.push (rounded_x_delta); - rounded_y_deltas.push (rounded_y_delta); + rounded_x_deltas.arrayZ[i] = (int) roundf (deltas_x.arrayZ[i]); + rounded_y_deltas.arrayZ[i] = (int) roundf (deltas_y.arrayZ[i]); } - if (!iup_delta_optimize (contour_points, rounded_x_deltas, rounded_y_deltas, opt_indices, tolerance)) + if (!iup_delta_optimize (contour_points, rounded_x_deltas, rounded_y_deltas, opt_indices, scratch.iup, tolerance)) return false; unsigned ref_count = 0; @@ -691,7 +737,8 @@ struct tuple_delta_t if (ref_count == count) return true; - hb_vector_t opt_deltas_x, opt_deltas_y; + hb_vector_t &opt_deltas_x = scratch.opt_deltas_x.reset (); + hb_vector_t &opt_deltas_y = scratch.opt_deltas_y.reset (); bool is_comp_glyph_wo_deltas = (is_composite && ref_count == 0); if (is_comp_glyph_wo_deltas) { @@ -704,34 +751,31 @@ struct tuple_delta_t opt_indices.arrayZ[i] = false; } - hb_vector_t opt_point_data; + hb_vector_t &opt_point_data = scratch.opt_point_data.reset (); if (!compile_point_set (opt_indices, opt_point_data)) return false; - hb_vector_t opt_deltas_data; + hb_vector_t &opt_deltas_data = scratch.opt_deltas_data.reset (); if (!compile_deltas (opt_indices, is_comp_glyph_wo_deltas ? opt_deltas_x : deltas_x, is_comp_glyph_wo_deltas ? opt_deltas_y : deltas_y, - opt_deltas_data)) + opt_deltas_data, + scratch.rounded_deltas)) return false; - hb_vector_t point_data; + hb_vector_t &point_data = scratch.point_data.reset (); if (!compile_point_set (indices, point_data)) return false; - hb_vector_t deltas_data; - if (!compile_deltas (indices, deltas_x, deltas_y, deltas_data)) + hb_vector_t &deltas_data = scratch.deltas_data.reset (); + if (!compile_deltas (indices, deltas_x, deltas_y, deltas_data, scratch.rounded_deltas)) return false; if (opt_point_data.length + opt_deltas_data.length < point_data.length + deltas_data.length) { - indices.fini (); indices = std::move (opt_indices); if (is_comp_glyph_wo_deltas) { - deltas_x.fini (); deltas_x = std::move (opt_deltas_x); - - deltas_y.fini (); deltas_y = std::move (opt_deltas_y); } } @@ -756,7 +800,7 @@ struct tuple_delta_t /* allocate enough memories: 2 bytes for count + 3 bytes for each point */ unsigned num_bytes = 2 + 3 *num_points; - if (unlikely (!compiled_points.resize (num_bytes, false))) + if (unlikely (!compiled_points.resize_dirty (num_bytes))) return false; unsigned pos = 0; @@ -820,7 +864,7 @@ struct tuple_delta_t else compiled_points.arrayZ[header_pos] = (run_length - 1) | 0x80; } - return compiled_points.resize (pos, false); + return compiled_points.resize_dirty (pos); } static double infer_delta (double target_val, double prev_val, double next_val, double prev_delta, double next_delta) @@ -924,8 +968,12 @@ struct TupleVariationData const hb_map_t *axes_old_index_tag_map, const hb_vector_t &shared_indices, const hb_array_t shared_tuples, - bool is_composite_glyph) + hb_alloc_pool_t *pool = nullptr, + bool is_composite_glyph = false) { + hb_vector_t private_indices; + hb_vector_t deltas_x; + hb_vector_t deltas_y; do { const HBUINT8 *p = iterator.get_serialized_data (); @@ -933,12 +981,12 @@ struct TupleVariationData if (unlikely (!iterator.var_data_bytes.check_range (p, length))) return false; - hb_hashmap_t axis_tuples; + hb_hashmap_t axis_tuples; if (!iterator.current_tuple->unpack_axis_tuples (iterator.get_axis_count (), shared_tuples, axes_old_index_tag_map, axis_tuples) || axis_tuples.is_empty ()) return false; - hb_vector_t private_indices; + private_indices.reset (); bool has_private_points = iterator.current_tuple->has_private_points (); const HBUINT8 *end = p + length; if (has_private_points && @@ -949,27 +997,24 @@ struct TupleVariationData bool apply_to_all = (indices.length == 0); unsigned num_deltas = apply_to_all ? point_count : indices.length; - hb_vector_t deltas_x; - - if (unlikely (!deltas_x.resize (num_deltas, false) || + if (unlikely (!deltas_x.resize_dirty (num_deltas) || !TupleVariationData::decompile_deltas (p, deltas_x, end))) return false; - hb_vector_t deltas_y; if (is_gvar) { - if (unlikely (!deltas_y.resize (num_deltas, false) || + if (unlikely (!deltas_y.resize_dirty (num_deltas) || !TupleVariationData::decompile_deltas (p, deltas_y, end))) return false; } tuple_delta_t var; var.axis_tuples = std::move (axis_tuples); - if (unlikely (!var.indices.resize (point_count) || - !var.deltas_x.resize (point_count, false))) + if (unlikely (!var.indices.allocate_from_pool (pool, point_count) || + !var.deltas_x.allocate_from_pool (pool, point_count, false))) return false; - if (is_gvar && unlikely (!var.deltas_y.resize (point_count, false))) + if (is_gvar && unlikely (!var.deltas_y.allocate_from_pool (pool, point_count, false))) return false; for (unsigned i = 0; i < num_deltas; i++) @@ -1011,8 +1056,8 @@ struct TupleVariationData /* In VarData, deltas are organized in rows, convert them into * column(region) based tuples, resize deltas_x first */ tuple_delta_t tuple; - if (!tuple.deltas_x.resize (item_count, false) || - !tuple.indices.resize (item_count, false)) + if (!tuple.deltas_x.resize_dirty (item_count) || + !tuple.indices.resize_dirty (item_count)) return false; for (unsigned i = 0; i < item_count; i++) @@ -1040,7 +1085,8 @@ struct TupleVariationData } bool change_tuple_variations_axis_limits (const hb_hashmap_t& normalized_axes_location, - const hb_hashmap_t& axes_triple_distances) + const hb_hashmap_t& axes_triple_distances, + hb_alloc_pool_t *pool = nullptr) { /* sort axis_tag/axis_limits, make result deterministic */ hb_vector_t axis_tags; @@ -1049,6 +1095,10 @@ struct TupleVariationData for (auto t : normalized_axes_location.keys ()) axis_tags.push (t); + // Reused vectors for reduced malloc pressure. + rebase_tent_result_scratch_t scratch; + hb_vector_t out; + axis_tags.qsort (_cmp_axis_tag); for (auto axis_tag : axis_tags) { @@ -1060,9 +1110,10 @@ struct TupleVariationData axis_triple_distances = axes_triple_distances.get (axis_tag); hb_vector_t new_vars; - for (const tuple_delta_t& var : tuple_vars) + for (tuple_delta_t& var : tuple_vars) { - hb_vector_t out = var.change_tuple_var_axis_limit (axis_tag, *axis_limit, axis_triple_distances); + // This may move var out. + var.change_tuple_var_axis_limit (axis_tag, *axis_limit, axis_triple_distances, out, scratch, pool); if (!out) continue; unsigned new_len = new_vars.length + out.length; @@ -1073,7 +1124,6 @@ struct TupleVariationData for (unsigned i = 0; i < out.length; i++) new_vars.push (std::move (out[i])); } - tuple_vars.fini (); tuple_vars = std::move (new_vars); } return true; @@ -1084,9 +1134,12 @@ struct TupleVariationData bool merge_tuple_variations (contour_point_vector_t* contour_points = nullptr) { hb_vector_t new_vars; + // The pre-allocation is essential for address stability of pointers + // we store in the hashmap. + if (unlikely (!new_vars.alloc (tuple_vars.length))) + return false; hb_hashmap_t*, unsigned> m; - unsigned i = 0; - for (const tuple_delta_t& var : tuple_vars) + for (tuple_delta_t& var : tuple_vars) { /* if all axes are pinned, drop the tuple variation */ if (var.axis_tuples.is_empty ()) @@ -1106,13 +1159,17 @@ struct TupleVariationData } else { - new_vars.push (var); - if (!m.set (&(var.axis_tuples), i)) + auto *new_var = new_vars.push (); + if (unlikely (new_vars.in_error ())) + return false; + hb_swap (*new_var, var); + if (unlikely (!m.set (&(new_var->axis_tuples), new_vars.length - 1))) return false; - i++; } } - tuple_vars.fini (); + m.fini (); // Just in case, since it points into new_vars data. + // Shouldn't be necessary though, since we only move new_vars, not its + // contents. tuple_vars = std::move (new_vars); return true; } @@ -1172,20 +1229,22 @@ struct TupleVariationData } } - bool calc_inferred_deltas (const contour_point_vector_t& contour_points) + bool calc_inferred_deltas (const contour_point_vector_t& contour_points, + hb_vector_t &scratch) { for (tuple_delta_t& var : tuple_vars) - if (!var.calc_inferred_deltas (contour_points)) + if (!var.calc_inferred_deltas (contour_points, scratch)) return false; return true; } - bool iup_optimize (const contour_point_vector_t& contour_points) + bool iup_optimize (const contour_point_vector_t& contour_points, + optimize_scratch_t &scratch) { for (tuple_delta_t& var : tuple_vars) { - if (!var.optimize (contour_points, is_composite)) + if (!var.optimize (contour_points, is_composite, scratch)) return false; } return true; @@ -1194,16 +1253,21 @@ struct TupleVariationData public: bool instantiate (const hb_hashmap_t& normalized_axes_location, const hb_hashmap_t& axes_triple_distances, + optimize_scratch_t &scratch, + hb_alloc_pool_t *pool = nullptr, contour_point_vector_t* contour_points = nullptr, bool optimize = false) { if (!tuple_vars) return true; - if (!change_tuple_variations_axis_limits (normalized_axes_location, axes_triple_distances)) + if (!change_tuple_variations_axis_limits (normalized_axes_location, axes_triple_distances, pool)) return false; /* compute inferred deltas only for gvar */ if (contour_points) - if (!calc_inferred_deltas (*contour_points)) - return false; + { + hb_vector_t scratch; + if (!calc_inferred_deltas (*contour_points, scratch)) + return false; + } /* if iup delta opt is on, contour_points can't be null */ if (optimize && !contour_points) @@ -1212,7 +1276,7 @@ struct TupleVariationData if (!merge_tuple_variations (optimize ? contour_points : nullptr)) return false; - if (optimize && !iup_optimize (*contour_points)) return false; + if (optimize && !iup_optimize (*contour_points, scratch)) return false; return !tuple_vars.in_error (); } @@ -1220,7 +1284,8 @@ struct TupleVariationData const hb_map_t& axes_old_index_tag_map, bool use_shared_points, bool is_gvar = false, - const hb_hashmap_t*, unsigned>* shared_tuples_idx_map = nullptr) + const hb_hashmap_t*, unsigned>* shared_tuples_idx_map = nullptr, + hb_alloc_pool_t *pool = nullptr) { // return true for empty glyph if (!tuple_vars) @@ -1240,6 +1305,7 @@ struct TupleVariationData if (shared_points_bytes) compiled_byte_size += shared_points_bytes->length; } + hb_vector_t rounded_deltas_scratch; // compile delta and tuple var header for each tuple variation for (auto& tuple: tuple_vars) { @@ -1253,12 +1319,13 @@ struct TupleVariationData * this tuple */ if (!points_data->length) continue; - if (!tuple.compile_deltas ()) + if (!tuple.compile_deltas (rounded_deltas_scratch, pool)) return false; unsigned points_data_length = (points_data != shared_points_bytes) ? points_data->length : 0; if (!tuple.compile_tuple_var_header (axes_index_map, points_data_length, axes_old_index_tag_map, - shared_tuples_idx_map)) + shared_tuples_idx_map, + pool)) return false; compiled_byte_size += tuple.compiled_tuple_header.length + points_data_length + tuple.compiled_deltas.length; } @@ -1421,7 +1488,7 @@ struct TupleVariationData if (unlikely (p + 1 > end)) return false; count = ((count & POINT_RUN_COUNT_MASK) << 8) | *p++; } - if (unlikely (!points.resize (count, false))) return false; + if (unlikely (!points.resize_dirty (count))) return false; unsigned n = 0; unsigned i = 0; @@ -1474,6 +1541,7 @@ struct TupleVariationData const hb_vector_t &shared_indices, const hb_array_t shared_tuples, tuple_variations_t& tuple_variations, /* OUT */ + hb_alloc_pool_t *pool = nullptr, bool is_composite_glyph = false) const { return tuple_variations.create_from_tuple_var_data (iterator, tupleVarCount, @@ -1481,6 +1549,7 @@ struct TupleVariationData axes_old_index_tag_map, shared_indices, shared_tuples, + pool, is_composite_glyph); } @@ -1645,8 +1714,9 @@ struct item_variations_t bool instantiate_tuple_vars (const hb_hashmap_t& normalized_axes_location, const hb_hashmap_t& axes_triple_distances) { + optimize_scratch_t scratch; for (tuple_variations_t& tuple_vars : vars) - if (!tuple_vars.instantiate (normalized_axes_location, axes_triple_distances)) + if (!tuple_vars.instantiate (normalized_axes_location, axes_triple_distances, scratch)) return false; if (!build_region_list ()) return false; @@ -1731,30 +1801,28 @@ struct item_variations_t struct combined_gain_idx_tuple_t { - int gain; - unsigned idx_1; - unsigned idx_2; + uint64_t encoded; combined_gain_idx_tuple_t () = default; - combined_gain_idx_tuple_t (int gain_, unsigned i, unsigned j) - :gain (gain_), idx_1 (i), idx_2 (j) {} + combined_gain_idx_tuple_t (unsigned gain, unsigned i, unsigned j) + : encoded ((uint64_t (0xFFFFFF - gain) << 40) | (uint64_t (i) << 20) | uint64_t (j)) + { + assert (gain < 0xFFFFFF); + assert (i < 0xFFFFFFF && j < 0xFFFFFFF); + } bool operator < (const combined_gain_idx_tuple_t& o) { - if (gain != o.gain) - return gain < o.gain; - - if (idx_1 != o.idx_1) - return idx_1 < o.idx_1; - - return idx_2 < o.idx_2; + return encoded < o.encoded; } bool operator <= (const combined_gain_idx_tuple_t& o) { - if (*this < o) return true; - return gain == o.gain && idx_1 == o.idx_1 && idx_2 == o.idx_2; + return encoded <= o.encoded; } + + unsigned idx_1 () const { return (encoded >> 20) & 0xFFFFF; }; + unsigned idx_2 () const { return encoded & 0xFFFFF; }; }; bool as_item_varstore (bool optimize=true, bool use_no_variation_idx=true) @@ -1776,9 +1844,9 @@ struct item_variations_t hb_hashmap_t*> front_mapping; unsigned start_row = 0; hb_vector_t encoding_objs; - hb_hashmap_t, unsigned> chars_idx_map; /* delta_rows map, used for filtering out duplicate rows */ + hb_vector_t *> major_rows; hb_hashmap_t*, unsigned> delta_rows_map; for (unsigned major = 0; major < vars.length; major++) { @@ -1786,6 +1854,9 @@ struct item_variations_t * (row based) delta */ const tuple_variations_t& tuples = vars[major]; unsigned num_rows = var_data_num_rows[major]; + + if (!num_rows) continue; + for (const tuple_delta_t& tuple: tuples.tuple_vars) { if (tuple.deltas_x.length != num_rows) @@ -1800,81 +1871,66 @@ struct item_variations_t { int rounded_delta = roundf (tuple.deltas_x[i]); delta_rows[start_row + i][*col_idx] += rounded_delta; - if ((!has_long) && (rounded_delta < -65536 || rounded_delta > 65535)) - has_long = true; + has_long |= rounded_delta < -65536 || rounded_delta > 65535; } } - if (!optimize) - { - /* assemble a delta_row_encoding_t for this subtable, skip optimization so - * chars is not initialized, we only need delta rows for serialization */ - delta_row_encoding_t obj; - for (unsigned r = start_row; r < start_row + num_rows; r++) - obj.add_row (&(delta_rows.arrayZ[r])); - - encodings.push (std::move (obj)); - start_row += num_rows; - continue; - } - + major_rows.reset (); for (unsigned minor = 0; minor < num_rows; minor++) { - const hb_vector_t& row = delta_rows[start_row + minor]; - if (use_no_variation_idx) - { - bool all_zeros = true; - for (int delta : row) - { - if (delta != 0) - { - all_zeros = false; - break; - } - } - if (all_zeros) - continue; - } + const hb_vector_t& row = delta_rows[start_row + minor]; + if (use_no_variation_idx) + { + bool all_zeros = true; + for (int delta : row) + { + if (delta != 0) + { + all_zeros = false; + break; + } + } + if (all_zeros) + continue; + } - if (!front_mapping.set ((major<<16) + minor, &row)) - return false; + if (!front_mapping.set ((major<<16) + minor, &row)) + return false; - hb_vector_t chars = delta_row_encoding_t::get_row_chars (row); - if (!chars) return false; + if (delta_rows_map.has (&row)) + continue; - if (delta_rows_map.has (&row)) - continue; + delta_rows_map.set (&row, 1); - delta_rows_map.set (&row, 1); - unsigned *obj_idx; - if (chars_idx_map.has (chars, &obj_idx)) - { - delta_row_encoding_t& obj = encoding_objs[*obj_idx]; - if (!obj.add_row (&row)) - return false; - } - else - { - if (!chars_idx_map.set (chars, encoding_objs.length)) - return false; - delta_row_encoding_t obj (std::move (chars), &row); - encoding_objs.push (std::move (obj)); - } + major_rows.push (&row); } + if (major_rows) + encoding_objs.push (delta_row_encoding_t (std::move (major_rows), num_cols)); + start_row += num_rows; } /* return directly if no optimization, maintain original VariationIndex so * varidx_map would be empty */ - if (!optimize) return !encodings.in_error (); + if (!optimize) + { + encodings = std::move (encoding_objs); + return !encodings.in_error (); + } - /* sort encoding_objs */ + /* NOTE: Fonttools instancer always optimizes VarStore from scratch. This + * is too costly for large fonts. So, instead, we retain the encodings of + * the original VarStore, and just try to combine them if possible. This + * is a compromise between optimization and performance and practically + * works very well. */ + + // This produces slightly smaller results in some cases. encoding_objs.qsort (); - /* main algorithm: repeatedly pick 2 best encodings to combine, and combine - * them */ - hb_priority_queue_t queue; + /* main algorithm: repeatedly pick 2 best encodings to combine, and combine them */ + using item_t = hb_priority_queue_t::item_t; + hb_vector_t queue_items; unsigned num_todos = encoding_objs.length; for (unsigned i = 0; i < num_todos; i++) { @@ -1882,16 +1938,18 @@ struct item_variations_t { int combining_gain = encoding_objs.arrayZ[i].gain_from_merging (encoding_objs.arrayZ[j]); if (combining_gain > 0) - queue.insert (combined_gain_idx_tuple_t (-combining_gain, i, j), 0); + queue_items.push (item_t (combined_gain_idx_tuple_t (combining_gain, i, j), 0)); } } - hb_set_t removed_todo_idxes; + hb_priority_queue_t queue (std::move (queue_items)); + + hb_bit_set_t removed_todo_idxes; while (queue) { auto t = queue.pop_minimum ().first; - unsigned i = t.idx_1; - unsigned j = t.idx_2; + unsigned i = t.idx_1 (); + unsigned j = t.idx_2 (); if (removed_todo_idxes.has (i) || removed_todo_idxes.has (j)) continue; @@ -1902,40 +1960,36 @@ struct item_variations_t removed_todo_idxes.add (i); removed_todo_idxes.add (j); - hb_vector_t combined_chars; - if (!combined_chars.alloc (encoding.chars.length)) - return false; - - for (unsigned idx = 0; idx < encoding.chars.length; idx++) - { - uint8_t v = hb_max (encoding.chars.arrayZ[idx], other_encoding.chars.arrayZ[idx]); - combined_chars.push (v); - } - - delta_row_encoding_t combined_encoding_obj (std::move (combined_chars)); - for (const auto& row : hb_concat (encoding.items, other_encoding.items)) - combined_encoding_obj.add_row (row); + encoding.merge (other_encoding); for (unsigned idx = 0; idx < encoding_objs.length; idx++) { if (removed_todo_idxes.has (idx)) continue; const delta_row_encoding_t& obj = encoding_objs.arrayZ[idx]; - if (obj.chars == combined_chars) + // In the unlikely event that the same encoding exists already, combine it. + if (obj.width == encoding.width && obj.chars == encoding.chars) { + // This is straight port from fonttools algorithm. I added this branch there + // because I thought it can happen. But looks like we never get in here in + // practice. I'm not confident enough to remove it though; in theory it can + // happen. I think it's just that our tests are not extensive enough to hit + // this path. + for (const auto& row : obj.items) - combined_encoding_obj.add_row (row); + encoding.add_row (row); removed_todo_idxes.add (idx); continue; } - int combined_gain = combined_encoding_obj.gain_from_merging (obj); + int combined_gain = encoding.gain_from_merging (obj); if (combined_gain > 0) - queue.insert (combined_gain_idx_tuple_t (-combined_gain, idx, encoding_objs.length), 0); + queue.insert (combined_gain_idx_tuple_t (combined_gain, idx, encoding_objs.length), 0); } - encoding_objs.push (std::move (combined_encoding_obj)); + auto moved_encoding = std::move (encoding); + encoding_objs.push (moved_encoding); } int num_final_encodings = (int) encoding_objs.length - (int) removed_todo_idxes.get_population (); @@ -1948,9 +2002,6 @@ struct item_variations_t encodings.push (std::move (encoding_objs.arrayZ[i])); } - /* sort again based on width, make result deterministic */ - encodings.qsort (delta_row_encoding_t::cmp_width); - return compile_varidx_map (front_mapping); } diff --git a/thirdparty/harfbuzz/src/hb-ot-var-cvar-table.hh b/thirdparty/harfbuzz/src/hb-ot-var-cvar-table.hh index f8ae0c8039d..7fb762f27e1 100644 --- a/thirdparty/harfbuzz/src/hb-ot-var-cvar-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-var-cvar-table.hh @@ -66,7 +66,7 @@ struct cvar if (!TupleVariationData<>::get_tuple_iterator (var_data_bytes, axis_count, this, shared_indices, &iterator)) return false; - + return tupleVariationData.decompile_tuple_variations (point_count, is_gvar, iterator, axes_old_index_tag_map, shared_indices, @@ -113,7 +113,7 @@ struct cvar bool apply_to_all = (indices.length == 0); unsigned num_deltas = apply_to_all ? num_cvt_item : indices.length; - if (unlikely (!unpacked_deltas.resize (num_deltas, false))) return false; + if (unlikely (!unpacked_deltas.resize_dirty (num_deltas))) return false; if (unlikely (!TupleVariationData<>::decompile_deltas (p, unpacked_deltas, end))) return false; for (unsigned int i = 0; i < num_deltas; i++) @@ -158,7 +158,8 @@ struct cvar tuple_variations)) return_trace (false); - if (!tuple_variations.instantiate (c->plan->axes_location, c->plan->axes_triple_distances)) + optimize_scratch_t scratch; + if (!tuple_variations.instantiate (c->plan->axes_location, c->plan->axes_triple_distances, scratch)) return_trace (false); if (!tuple_variations.compile_bytes (c->plan->axes_index_map, c->plan->axes_old_index_tag_map, diff --git a/thirdparty/harfbuzz/src/hb-ot-var-gvar-table.hh b/thirdparty/harfbuzz/src/hb-ot-var-gvar-table.hh index f2b381b1e7b..a30eb0a01ad 100644 --- a/thirdparty/harfbuzz/src/hb-ot-var-gvar-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-var-gvar-table.hh @@ -66,12 +66,14 @@ struct glyph_variations_t hb_vector_t glyph_variations; - hb_vector_t compiled_shared_tuples; + hb_vector_t compiled_shared_tuples; private: unsigned shared_tuples_count = 0; /* shared coords-> index map after instantiation */ - hb_hashmap_t*, unsigned> shared_tuples_idx_map; + hb_hashmap_t*, unsigned> shared_tuples_idx_map; + + hb_alloc_pool_t pool; public: unsigned compiled_shared_tuples_count () const @@ -128,6 +130,7 @@ struct glyph_variations_t iterator, &(plan->axes_old_index_tag_map), shared_indices, shared_tuples, tuple_vars, /* OUT */ + &pool, is_composite_glyph)) return false; glyph_variations.push (std::move (tuple_vars)); @@ -139,6 +142,7 @@ struct glyph_variations_t { unsigned count = plan->new_to_old_gid_list.length; bool iup_optimize = false; + optimize_scratch_t scratch; iup_optimize = plan->flags & HB_SUBSET_FLAGS_OPTIMIZE_IUP_DELTAS; for (unsigned i = 0; i < count; i++) { @@ -146,7 +150,7 @@ struct glyph_variations_t contour_point_vector_t *all_points; if (!plan->new_gid_contour_points_map.has (new_gid, &all_points)) return false; - if (!glyph_variations[i].instantiate (plan->axes_location, plan->axes_triple_distances, all_points, iup_optimize)) + if (!glyph_variations[i].instantiate (plan->axes_location, plan->axes_triple_distances, scratch, &pool, all_points, iup_optimize)) return false; } return true; @@ -161,7 +165,8 @@ struct glyph_variations_t if (!vars.compile_bytes (axes_index_map, axes_old_index_tag_map, true, /* use shared points*/ true, - &shared_tuples_idx_map)) + &shared_tuples_idx_map, + &pool)) return false; return true; @@ -172,20 +177,21 @@ struct glyph_variations_t { /* key is pointer to compiled_peak_coords inside each tuple, hashing * function will always deref pointers first */ - hb_hashmap_t*, unsigned> coords_count_map; + hb_hashmap_t*, unsigned> coords_count_map; /* count the num of shared coords */ for (tuple_variations_t& vars: glyph_variations) { for (tuple_delta_t& var : vars.tuple_vars) { - if (!var.compile_peak_coords (axes_index_map, axes_old_index_tag_map)) + if (!var.compile_coords (axes_index_map, axes_old_index_tag_map, &pool)) return false; - unsigned* count; - if (coords_count_map.has (&(var.compiled_peak_coords), &count)) - coords_count_map.set (&(var.compiled_peak_coords), *count + 1); + unsigned *count; + unsigned hash = hb_hash (&var.compiled_peak_coords); + if (coords_count_map.has_with_hash (&(var.compiled_peak_coords), hash, &count)) + (*count)++; else - coords_count_map.set (&(var.compiled_peak_coords), 1); + coords_count_map.set_with_hash (&(var.compiled_peak_coords), hash, 1); } } @@ -193,66 +199,45 @@ struct glyph_variations_t return false; /* add only those coords that are used more than once into the vector and sort */ - hb_vector_t*> shared_coords; - if (unlikely (!shared_coords.alloc (coords_count_map.get_population ()))) - return false; - - for (const auto _ : coords_count_map.iter ()) - { - if (_.second == 1) continue; - shared_coords.push (_.first); - } + hb_vector_t*, unsigned>> shared_coords { + + hb_iter (coords_count_map) + | hb_filter ([] (const hb_pair_t*, unsigned>& p) { return p.second > 1; }) + }; + if (unlikely (shared_coords.in_error ())) return false; /* no shared tuples: no coords are used more than once */ if (!shared_coords) return true; /* sorting based on the coords frequency first (high to low), then compare * the coords bytes */ - hb_qsort (shared_coords.arrayZ, shared_coords.length, sizeof (hb_vector_t*), _cmp_coords, (void *) (&coords_count_map)); + shared_coords.qsort (_cmp_coords); /* build shared_coords->idx map and shared tuples byte array */ shared_tuples_count = hb_min (0xFFFu + 1, shared_coords.length); - unsigned len = shared_tuples_count * (shared_coords[0]->length); + unsigned len = shared_tuples_count * (shared_coords[0].first->length); if (unlikely (!compiled_shared_tuples.alloc (len))) return false; for (unsigned i = 0; i < shared_tuples_count; i++) { - shared_tuples_idx_map.set (shared_coords[i], i); + shared_tuples_idx_map.set (shared_coords[i].first, i); /* add a concat() in hb_vector_t? */ - for (char c : shared_coords[i]->iter ()) + for (auto c : shared_coords[i].first->iter ()) compiled_shared_tuples.push (c); } return true; } - static int _cmp_coords (const void *pa, const void *pb, void *arg) + static int _cmp_coords (const void *pa, const void *pb) { - const hb_hashmap_t*, unsigned>* coords_count_map = - reinterpret_cast*, unsigned>*> (arg); + const hb_pair_t *, unsigned> *a = (const hb_pair_t *, unsigned> *) pa; + const hb_pair_t *, unsigned> *b = (const hb_pair_t *, unsigned> *) pb; - /* shared_coords is hb_vector_t*> so casting pa/pb - * to be a pointer to a pointer */ - const hb_vector_t** a = reinterpret_cast**> (const_cast(pa)); - const hb_vector_t** b = reinterpret_cast**> (const_cast(pb)); + if (a->second != b->second) + return b->second - a->second; // high to low - bool has_a = coords_count_map->has (*a); - bool has_b = coords_count_map->has (*b); - - if (has_a && has_b) - { - unsigned a_num = coords_count_map->get (*a); - unsigned b_num = coords_count_map->get (*b); - - if (a_num != b_num) - return b_num - a_num; - - return (*b)->as_array().cmp ((*a)->as_array ()); - } - else if (has_a) return -1; - else if (has_b) return 1; - else return 0; + return b->first->as_array().cmp (a->first->as_array ()); } templatesharedTuples = 0; else { - hb_array_t shared_tuples = glyph_vars.compiled_shared_tuples.as_array ().copy (c); + hb_array_t shared_tuples = glyph_vars.compiled_shared_tuples.as_array ().copy (c); if (!shared_tuples.arrayZ) return_trace (false); - out->sharedTuples = shared_tuples.arrayZ - (char *) out; + out->sharedTuples = (const char *) shared_tuples.arrayZ - (char *) out; } char *glyph_var_data = c->start_embed (); @@ -686,7 +671,7 @@ struct gvar_GVAR if (!deltas) { - if (unlikely (!deltas_vec.resize (count, false))) return false; + if (unlikely (!deltas_vec.resize_dirty (count))) return false; deltas = deltas_vec.as_array (); hb_memset (deltas.arrayZ + (phantom_only ? count - 4 : 0), 0, (phantom_only ? 4 : count) * sizeof (deltas[0])); @@ -703,9 +688,9 @@ struct gvar_GVAR bool apply_to_all = (indices.length == 0); unsigned num_deltas = apply_to_all ? points.length : indices.length; unsigned start_deltas = (phantom_only && num_deltas >= 4 ? num_deltas - 4 : 0); - if (unlikely (!x_deltas.resize (num_deltas, false))) return false; + if (unlikely (!x_deltas.resize_dirty (num_deltas))) return false; if (unlikely (!GlyphVariationData::decompile_deltas (p, x_deltas, end, false, start_deltas))) return false; - if (unlikely (!y_deltas.resize (num_deltas, false))) return false; + if (unlikely (!y_deltas.resize_dirty (num_deltas))) return false; if (unlikely (!GlyphVariationData::decompile_deltas (p, y_deltas, end, false, start_deltas))) return false; if (!apply_to_all) diff --git a/thirdparty/harfbuzz/src/hb-ot-var-hvar-table.hh b/thirdparty/harfbuzz/src/hb-ot-var-hvar-table.hh index d9437d832a8..ce1f9dcbafe 100644 --- a/thirdparty/harfbuzz/src/hb-ot-var-hvar-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-var-hvar-table.hh @@ -42,57 +42,62 @@ struct index_map_subset_plan_t VORG_INDEX }; - void init (const DeltaSetIndexMap &index_map, + void init (const DeltaSetIndexMap *index_map, hb_inc_bimap_t &outer_map, hb_vector_t &inner_sets, const hb_subset_plan_t *plan, bool bypass_empty = true) { map_count = 0; - outer_bit_count = 0; - inner_bit_count = 1; max_inners.init (); output_map.init (); - if (bypass_empty && !index_map.get_map_count ()) return; + if (bypass_empty && (!index_map || !index_map->get_map_count ())) return; unsigned int last_val = (unsigned int)-1; hb_codepoint_t last_gid = HB_CODEPOINT_INVALID; - outer_bit_count = (index_map.get_width () * 8) - index_map.get_inner_bit_count (); max_inners.resize (inner_sets.length); for (unsigned i = 0; i < inner_sets.length; i++) max_inners[i] = 0; /* Search backwards for a map value different from the last map value */ auto &new_to_old_gid_list = plan->new_to_old_gid_list; unsigned count = new_to_old_gid_list.length; - for (unsigned j = count; j; j--) + if (!index_map) { - hb_codepoint_t gid = new_to_old_gid_list.arrayZ[j - 1].first; - hb_codepoint_t old_gid = new_to_old_gid_list.arrayZ[j - 1].second; - - unsigned int v = index_map.map (old_gid); - if (last_gid == HB_CODEPOINT_INVALID) + map_count = new_to_old_gid_list.tail ().first + 1; + } + else + { + for (unsigned j = count; j; j--) { - last_val = v; - last_gid = gid; - continue; + hb_codepoint_t gid = new_to_old_gid_list.arrayZ[j - 1].first; + hb_codepoint_t old_gid = new_to_old_gid_list.arrayZ[j - 1].second; + + unsigned int v = index_map->map (old_gid); + if (last_gid == HB_CODEPOINT_INVALID) + { + last_val = v; + last_gid = gid; + continue; + } + if (v != last_val) + break; + + last_gid = gid; } - if (v != last_val) - break; - - last_gid = gid; + + if (unlikely (last_gid == (hb_codepoint_t)-1)) return; + map_count = last_gid + 1; } - if (unlikely (last_gid == (hb_codepoint_t)-1)) return; - map_count = last_gid + 1; for (auto _ : plan->new_to_old_gid_list) { hb_codepoint_t gid = _.first; if (gid >= map_count) break; hb_codepoint_t old_gid = _.second; - unsigned int v = index_map.map (old_gid); + unsigned int v = index_map ? index_map->map (old_gid): old_gid; unsigned int outer = v >> 16; unsigned int inner = v & 0xFFFF; outer_map.add (outer); @@ -113,6 +118,9 @@ struct index_map_subset_plan_t const hb_vector_t &inner_maps, const hb_subset_plan_t *plan) { + outer_bit_count = 1; + inner_bit_count = 1; + for (unsigned int i = 0; i < max_inners.length; i++) { if (inner_maps[i].get_population () == 0) continue; @@ -128,9 +136,13 @@ struct index_map_subset_plan_t if (unlikely (new_gid >= map_count)) break; - uint32_t v = input_map->map (old_gid); - unsigned int outer = v >> 16; - output_map.arrayZ[new_gid] = (outer_map[outer] << 16) | (inner_maps[outer][v & 0xFFFF]); + uint32_t v = input_map? input_map->map (old_gid) : old_gid; + unsigned outer = v >> 16; + unsigned new_outer = outer_map[outer]; + unsigned bit_count = (new_outer == 0) ? 1 : hb_bit_storage (new_outer); + outer_bit_count = hb_max (bit_count, outer_bit_count); + + output_map.arrayZ[new_gid] = (new_outer << 16) | (inner_maps[outer][v & 0xFFFF]); } } @@ -204,8 +216,8 @@ struct hvarvvar_subset_plan_t if (unlikely (!index_map_plans.length || !inner_sets.length || !inner_maps.length)) return; bool retain_adv_map = false; - index_map_plans[0].init (*index_maps[0], outer_map, inner_sets, plan, false); - if (index_maps[0] == &Null (DeltaSetIndexMap)) + index_map_plans[0].init (index_maps[0], outer_map, inner_sets, plan, false); + if (!index_maps[0]) { retain_adv_map = plan->flags & HB_SUBSET_FLAGS_RETAIN_GIDS; outer_map.add (0); @@ -215,7 +227,7 @@ struct hvarvvar_subset_plan_t } for (unsigned int i = 1; i < index_maps.length; i++) - index_map_plans[i].init (*index_maps[i], outer_map, inner_sets, plan); + index_map_plans[i].init (index_maps[i], outer_map, inner_sets, plan); outer_map.sort (); @@ -303,9 +315,14 @@ struct HVARVVAR void listup_index_maps (hb_vector_t &index_maps) const { - index_maps.push (&(this+advMap)); - index_maps.push (&(this+lsbMap)); - index_maps.push (&(this+rsbMap)); + if (advMap) index_maps.push (&(this+advMap)); + else index_maps.push (nullptr); + + if (lsbMap) index_maps.push (&(this+lsbMap)); + else index_maps.push (nullptr); + + if (rsbMap) index_maps.push (&(this+rsbMap)); + else index_maps.push (nullptr); } bool serialize_index_maps (hb_serialize_context_t *c, @@ -428,7 +445,8 @@ struct VVAR : HVARVVAR { void listup_index_maps (hb_vector_t &index_maps) const { HVARVVAR::listup_index_maps (index_maps); - index_maps.push (&(this+vorgMap)); + if (vorgMap) index_maps.push (&(this+vorgMap)); + else index_maps.push (nullptr); } bool serialize_index_maps (hb_serialize_context_t *c, diff --git a/thirdparty/harfbuzz/src/hb-priority-queue.hh b/thirdparty/harfbuzz/src/hb-priority-queue.hh index 274d5df4c54..753e86b8ca6 100644 --- a/thirdparty/harfbuzz/src/hb-priority-queue.hh +++ b/thirdparty/harfbuzz/src/hb-priority-queue.hh @@ -45,12 +45,22 @@ template struct hb_priority_queue_t { - private: + public: typedef hb_pair_t item_t; + + private: hb_vector_t heap; public: + hb_priority_queue_t () = default; + hb_priority_queue_t (hb_vector_t&& other) : heap (std::move (other)) + { + // Heapify the vector. + for (int i = (heap.length / 2) - 1; i >= 0; i--) + bubble_down (i); + } + void reset () { heap.resize (0); } bool in_error () const { return heap.in_error (); } diff --git a/thirdparty/harfbuzz/src/hb-repacker.hh b/thirdparty/harfbuzz/src/hb-repacker.hh index 11d47c9dca3..7d118b52169 100644 --- a/thirdparty/harfbuzz/src/hb-repacker.hh +++ b/thirdparty/harfbuzz/src/hb-repacker.hh @@ -217,11 +217,17 @@ bool _try_isolating_subgraphs (const hb_vector_t& over unsigned maximum_to_move = hb_max ((sorted_graph.num_roots_for_space (space) / 2u), 1u); if (roots_to_isolate.get_population () > maximum_to_move) { // Only move at most half of the roots in a space at a time. - unsigned extra = roots_to_isolate.get_population () - maximum_to_move; - while (extra--) { - uint32_t root = HB_SET_VALUE_INVALID; - roots_to_isolate.previous (&root); - roots_to_isolate.del (root); + // + // Note: this was ported from non-stable ids to stable ids. So to retain the same behaviour + // with regards to which roots are removed from the set we need to remove them in the topological + // order, not the object id order. + int extra = roots_to_isolate.get_population () - maximum_to_move; + for (unsigned id : sorted_graph.ordering_) { + if (!extra) break; + if (roots_to_isolate.has(id)) { + roots_to_isolate.del(id); + extra--; + } } } diff --git a/thirdparty/harfbuzz/src/hb-script-list.h b/thirdparty/harfbuzz/src/hb-script-list.h index 88e270d3479..d500d5ae657 100644 --- a/thirdparty/harfbuzz/src/hb-script-list.h +++ b/thirdparty/harfbuzz/src/hb-script-list.h @@ -223,6 +223,10 @@ HB_END_DECLS * @HB_SCRIPT_SUNUWAR: `Sunu`, Since: 10.0.0 * @HB_SCRIPT_TODHRI: `Todr`, Since: 10.0.0 * @HB_SCRIPT_TULU_TIGALARI: `Tutg`, Since: 10.0.0 + * @HB_SCRIPT_BERIA_ERFE: `Berf`, Since: 11.5.0 + * @HB_SCRIPT_SIDETIC: `Sidt`, Since: 11.5.0 + * @HB_SCRIPT_TAI_YO: `Tayo`, Since: 11.5.0 + * @HB_SCRIPT_TOLONG_SIKI: `Tols`, Since: 11.5.0 * @HB_SCRIPT_INVALID: No script set * * Data type for scripts. Each #hb_script_t's value is an #hb_tag_t corresponding @@ -461,6 +465,14 @@ typedef enum HB_SCRIPT_TODHRI = HB_TAG ('T','o','d','r'), /*16.0*/ HB_SCRIPT_TULU_TIGALARI = HB_TAG ('T','u','t','g'), /*16.0*/ + /* + * Since 11.5.0 + */ + HB_SCRIPT_BERIA_ERFE = HB_TAG ('B','e','r','f'), /*17.0*/ + HB_SCRIPT_SIDETIC = HB_TAG ('S','i','d','t'), /*17.0*/ + HB_SCRIPT_TAI_YO = HB_TAG ('T','a','y','o'), /*17.0*/ + HB_SCRIPT_TOLONG_SIKI = HB_TAG ('T','o','l','s'), /*17.0*/ + /* No script set. */ HB_SCRIPT_INVALID = HB_TAG_NONE, diff --git a/thirdparty/harfbuzz/src/hb-serialize.hh b/thirdparty/harfbuzz/src/hb-serialize.hh index c6dbf8db91c..92c79570583 100644 --- a/thirdparty/harfbuzz/src/hb-serialize.hh +++ b/thirdparty/harfbuzz/src/hb-serialize.hh @@ -34,7 +34,7 @@ #include "hb.hh" #include "hb-blob.hh" #include "hb-map.hh" -#include "hb-pool.hh" +#include "hb-free-pool.hh" #include "hb-subset-serialize.h" @@ -724,7 +724,7 @@ struct hb_serialize_context_t hb_requires (hb_is_iterator (Iterator)), typename ...Ts> void copy_all (Iterator it, Ts&&... ds) - { for (decltype (*it) _ : it) copy (_, std::forward (ds)...); } + { for (decltype (*it) _ : it) copy (_, ds...); } template hb_serialize_context_t& operator << (const Type &obj) & { embed (obj); return *this; } @@ -815,7 +815,7 @@ struct hb_serialize_context_t } /* Object memory pool. */ - hb_pool_t object_pool; + hb_free_pool_t object_pool; /* Stack of currently under construction objects. */ object_t *current; diff --git a/thirdparty/harfbuzz/src/hb-set-digest.hh b/thirdparty/harfbuzz/src/hb-set-digest.hh index d696f1b654b..419afa881ed 100644 --- a/thirdparty/harfbuzz/src/hb-set-digest.hh +++ b/thirdparty/harfbuzz/src/hb-set-digest.hh @@ -55,11 +55,11 @@ * - For each glyph, if it doesn't match the subtable digest, * skip it. * - * The main filter we use is a combination of four bits-pattern + * The filter we use is a combination of three bits-pattern * filters. A bits-pattern filter checks a number of bits (5 or 6) - * of the input number (glyph-id in this case) and checks whether + * of the input number (glyph-id in most cases) and checks whether * its pattern is amongst the patterns of any of the accepted values. - * The accepted patterns are represented as a "long" integer. The + * The accepted patterns are represented as a "long" integer. Each * check is done using four bitwise operations only. */ diff --git a/thirdparty/harfbuzz/src/hb-shape.cc b/thirdparty/harfbuzz/src/hb-shape.cc index c62f8c6bcdd..2a8086fdec5 100644 --- a/thirdparty/harfbuzz/src/hb-shape.cc +++ b/thirdparty/harfbuzz/src/hb-shape.cc @@ -149,14 +149,11 @@ hb_shape_full (hb_font_t *font, hb_bool_t res = hb_shape_plan_execute (shape_plan, font, buffer, features, num_features); - if (buffer->max_ops <= 0) - buffer->shaping_failed = true; - hb_shape_plan_destroy (shape_plan); if (text_buffer) { - if (res && buffer->successful && !buffer->shaping_failed + if (res && buffer->successful && text_buffer->successful && !buffer->verify (text_buffer, font, @@ -199,6 +196,7 @@ hb_shape (hb_font_t *font, #ifdef HB_EXPERIMENTAL_API +#ifndef HB_NO_VAR static float buffer_advance (hb_buffer_t *buffer) @@ -440,7 +438,7 @@ hb_shape_justify (hb_font_t *font, return true; } - +#endif #endif diff --git a/thirdparty/harfbuzz/src/hb-shaper-list.hh b/thirdparty/harfbuzz/src/hb-shaper-list.hh index 41673a38441..cb386f26827 100644 --- a/thirdparty/harfbuzz/src/hb-shaper-list.hh +++ b/thirdparty/harfbuzz/src/hb-shaper-list.hh @@ -61,6 +61,10 @@ HB_SHAPER_IMPLEMENT (coretext) HB_SHAPER_IMPLEMENT (harfrust) #endif +#ifdef HAVE_KBTS +HB_SHAPER_IMPLEMENT (kbts) +#endif + #ifndef HB_NO_FALLBACK_SHAPE HB_SHAPER_IMPLEMENT (fallback) /* <--- This should be last. */ #endif diff --git a/thirdparty/harfbuzz/src/hb-string-array.hh b/thirdparty/harfbuzz/src/hb-string-array.hh index e7ac1192324..3a714889c20 100644 --- a/thirdparty/harfbuzz/src/hb-string-array.hh +++ b/thirdparty/harfbuzz/src/hb-string-array.hh @@ -45,25 +45,25 @@ static const union HB_STRING_ARRAY_TYPE_NAME { * but C++ does not allow that. * https://stackoverflow.com/q/28433862 */ -#define _S(s) char HB_PASTE (str, __LINE__)[sizeof (s)]; +#define HB_STR(s) char HB_PASTE (str, __LINE__)[sizeof (s)]; #include HB_STRING_ARRAY_LIST -#undef _S +#undef HB_STR } st; char str[HB_VAR_ARRAY]; } HB_STRING_ARRAY_POOL_NAME = { { -#define _S(s) s, +#define HB_STR(s) s, #include HB_STRING_ARRAY_LIST -#undef _S +#undef HB_STR } }; static const unsigned int HB_STRING_ARRAY_OFFS_NAME[] = { -#define _S(s) offsetof (union HB_STRING_ARRAY_TYPE_NAME, st.HB_PASTE(str, __LINE__)), +#define HB_STR(s) offsetof (union HB_STRING_ARRAY_TYPE_NAME, st.HB_PASTE(str, __LINE__)), #include HB_STRING_ARRAY_LIST -#undef _S +#undef HB_STR sizeof (HB_STRING_ARRAY_TYPE_NAME) }; diff --git a/thirdparty/harfbuzz/src/hb-subset-cff-common.hh b/thirdparty/harfbuzz/src/hb-subset-cff-common.hh index c6532ad5ecc..75e5e662419 100644 --- a/thirdparty/harfbuzz/src/hb-subset-cff-common.hh +++ b/thirdparty/harfbuzz/src/hb-subset-cff-common.hh @@ -861,8 +861,7 @@ struct subr_subsetter_t { // Hack to point vector to static string. auto &b = buffArray.arrayZ[last]; - b.length = 1; - b.arrayZ = const_cast(endchar_str); + b.set_storage (const_cast(endchar_str), 1); } last++; // Skip over gid @@ -877,8 +876,7 @@ struct subr_subsetter_t { // Hack to point vector to static string. auto &b = buffArray.arrayZ[last]; - b.length = 1; - b.arrayZ = const_cast(endchar_str); + b.set_storage (const_cast(endchar_str), 1); } return true; diff --git a/thirdparty/harfbuzz/src/hb-subset-instancer-iup.cc b/thirdparty/harfbuzz/src/hb-subset-instancer-iup.cc index 074657acaf9..f81ecfba826 100644 --- a/thirdparty/harfbuzz/src/hb-subset-instancer-iup.cc +++ b/thirdparty/harfbuzz/src/hb-subset-instancer-iup.cc @@ -24,6 +24,10 @@ #include "hb-subset-instancer-iup.hh" +#include "hb-bit-page.hh" + +using hb_iup_set_t = hb_bit_page_t; + /* This file is a straight port of the following: * * https://github.com/fonttools/fonttools/blob/main/Lib/fontTools/varLib/iup.py @@ -37,7 +41,7 @@ constexpr static unsigned MAX_LOOKBACK = 8; static void _iup_contour_bound_forced_set (const hb_array_t contour_points, const hb_array_t x_deltas, const hb_array_t y_deltas, - hb_set_t& forced_set, /* OUT */ + hb_iup_set_t& forced_set, /* OUT */ double tolerance = 0.0) { unsigned len = contour_points.length; @@ -136,7 +140,7 @@ static bool rotate_array (const hb_array_t& org_array, { unsigned n = org_array.length; if (!n) return true; - if (unlikely (!out.resize (n, false))) + if (unlikely (!out.resize_dirty (n))) return false; unsigned item_size = hb_static_size (T); @@ -150,10 +154,10 @@ static bool rotate_array (const hb_array_t& org_array, return true; } -static bool rotate_set (const hb_set_t& org_set, +static bool rotate_set (const hb_iup_set_t& org_set, int k, unsigned n, - hb_set_t& out) + hb_iup_set_t& out) { if (!n) return false; k %= n; @@ -162,14 +166,14 @@ static bool rotate_set (const hb_set_t& org_set, if (k == 0) { - out.set (org_set); + out = org_set; } else { - for (auto v : org_set) + for (unsigned v : org_set) out.add ((v + k) % n); } - return !out.in_error (); + return true; } /* Given two reference coordinates (start and end of contour_points array), @@ -180,32 +184,39 @@ static bool _iup_segment (const hb_array_t contour_points const contour_point_t& p1, const contour_point_t& p2, int p1_dx, int p2_dx, int p1_dy, int p2_dy, + double tolerance_sq, hb_vector_t& interp_x_deltas, /* OUT */ hb_vector_t& interp_y_deltas /* OUT */) { unsigned n = contour_points.length; - if (unlikely (!interp_x_deltas.resize (n, false) || - !interp_y_deltas.resize (n, false))) + if (unlikely (!interp_x_deltas.resize_dirty (n) || + !interp_y_deltas.resize_dirty (n))) return false; for (unsigned j = 0; j < 2; j++) { + float contour_point_t::* xp; double x1, x2, d1, d2; + const int *in; double *out; if (j == 0) { + xp = &contour_point_t::x; x1 = static_cast (p1.x); x2 = static_cast (p2.x); d1 = p1_dx; d2 = p2_dx; + in = x_deltas.arrayZ; out = interp_x_deltas.arrayZ; } else { + xp = &contour_point_t::y; x1 = static_cast (p1.y); x2 = static_cast (p2.y); d1 = p1_dy; d2 = p2_dy; + in = y_deltas.arrayZ; out = interp_y_deltas.arrayZ; } @@ -233,7 +244,7 @@ static bool _iup_segment (const hb_array_t contour_points double scale = (d2 - d1) / (x2 - x1); for (unsigned i = 0; i < n; i++) { - double x = (j == 0 ? static_cast (contour_points.arrayZ[i].x) : static_cast (contour_points.arrayZ[i].y)); + double x = (double) (contour_points.arrayZ[i].*xp); double d; if (x <= x1) d = d1; @@ -243,6 +254,9 @@ static bool _iup_segment (const hb_array_t contour_points d = d1 + (x - x1) * scale; out[i] = d; + double err = d - in[i]; + if (err * err > tolerance_sq) + return false; } } return true; @@ -254,11 +268,13 @@ static bool _can_iup_in_between (const hb_array_t contour const contour_point_t& p1, const contour_point_t& p2, int p1_dx, int p2_dx, int p1_dy, int p2_dy, - double tolerance) + double tolerance_sq, + hb_vector_t &interp_x_deltas, /* scratch */ + hb_vector_t &interp_y_deltas /* scratch */) { - hb_vector_t interp_x_deltas, interp_y_deltas; if (!_iup_segment (contour_points, x_deltas, y_deltas, p1, p2, p1_dx, p2_dx, p1_dy, p2_dy, + tolerance_sq, interp_x_deltas, interp_y_deltas)) return false; @@ -268,8 +284,8 @@ static bool _can_iup_in_between (const hb_array_t contour { double dx = static_cast (x_deltas.arrayZ[i]) - interp_x_deltas.arrayZ[i]; double dy = static_cast (y_deltas.arrayZ[i]) - interp_y_deltas.arrayZ[i]; - - if (sqrt (dx * dx + dy * dy) > tolerance) + + if (dx * dx + dy * dy > tolerance_sq) return false; } return true; @@ -278,15 +294,17 @@ static bool _can_iup_in_between (const hb_array_t contour static bool _iup_contour_optimize_dp (const contour_point_vector_t& contour_points, const hb_vector_t& x_deltas, const hb_vector_t& y_deltas, - const hb_set_t& forced_set, - double tolerance, + const hb_iup_set_t& forced_set, + double tolerance_sq, unsigned lookback, hb_vector_t& costs, /* OUT */ - hb_vector_t& chain /* OUT */) + hb_vector_t& chain, /* OUT */ + hb_vector_t &interp_x_deltas_scratch, + hb_vector_t &interp_y_deltas_scratch) { unsigned n = contour_points.length; - if (unlikely (!costs.resize (n, false) || - !chain.resize (n, false))) + if (unlikely (!costs.resize_dirty (n) || + !chain.resize_dirty (n))) return false; lookback = hb_min (lookback, MAX_LOOKBACK); @@ -294,7 +312,7 @@ static bool _iup_contour_optimize_dp (const contour_point_vector_t& contour_poin for (unsigned i = 0; i < n; i++) { unsigned best_cost = (i == 0 ? 1 : costs.arrayZ[i-1] + 1); - + costs.arrayZ[i] = best_cost; chain.arrayZ[i] = (i == 0 ? -1 : i - 1); @@ -315,7 +333,8 @@ static bool _iup_contour_optimize_dp (const contour_point_vector_t& contour_poin contour_points.arrayZ[p1], contour_points.arrayZ[i], x_deltas.arrayZ[p1], x_deltas.arrayZ[i], y_deltas.arrayZ[p1], y_deltas.arrayZ[i], - tolerance)) + tolerance_sq, + interp_x_deltas_scratch, interp_y_deltas_scratch)) { best_cost = cost; costs.arrayZ[i] = best_cost; @@ -333,7 +352,8 @@ static bool _iup_contour_optimize (const hb_array_t conto const hb_array_t x_deltas, const hb_array_t y_deltas, hb_array_t opt_indices, /* OUT */ - double tolerance = 0.0) + double tolerance, + iup_scratch_t &scratch) { unsigned n = contour_points.length; if (opt_indices.length != n || @@ -341,12 +361,16 @@ static bool _iup_contour_optimize (const hb_array_t conto y_deltas.length != n) return false; + if (unlikely (n > hb_iup_set_t::PAGE_BITS)) + return true; // Refuse to work + bool all_within_tolerance = true; + double tolerance_sq = tolerance * tolerance; for (unsigned i = 0; i < n; i++) { int dx = x_deltas.arrayZ[i]; int dy = y_deltas.arrayZ[i]; - if (sqrt ((double) dx * dx + (double) dy * dy) > tolerance) + if ((double) dx * dx + (double) dy * dy > tolerance_sq) { all_within_tolerance = false; break; @@ -382,33 +406,36 @@ static bool _iup_contour_optimize (const hb_array_t conto } /* else, solve the general problem using Dynamic Programming */ - hb_set_t forced_set; + hb_iup_set_t forced_set; _iup_contour_bound_forced_set (contour_points, x_deltas, y_deltas, forced_set, tolerance); + hb_vector_t &costs = scratch.costs.reset (); + hb_vector_t &chain = scratch.chain.reset (); + if (!forced_set.is_empty ()) { int k = n - 1 - forced_set.get_max (); if (k < 0) return false; - hb_vector_t rot_x_deltas, rot_y_deltas; - contour_point_vector_t rot_points; - hb_set_t rot_forced_set; + hb_vector_t &rot_x_deltas = scratch.rot_x_deltas.reset (); + hb_vector_t &rot_y_deltas = scratch.rot_y_deltas.reset (); + contour_point_vector_t &rot_points = scratch.rot_points; + rot_points.reset (); + hb_iup_set_t rot_forced_set; if (!rotate_array (contour_points, k, rot_points) || !rotate_array (x_deltas, k, rot_x_deltas) || !rotate_array (y_deltas, k, rot_y_deltas) || !rotate_set (forced_set, k, n, rot_forced_set)) return false; - hb_vector_t costs; - hb_vector_t chain; - if (!_iup_contour_optimize_dp (rot_points, rot_x_deltas, rot_y_deltas, - rot_forced_set, tolerance, n, - costs, chain)) + rot_forced_set, tolerance_sq, n, + costs, chain, + scratch.interp_x_deltas, scratch.interp_y_deltas)) return false; - hb_set_t solution; + hb_iup_set_t solution; int index = n - 1; while (index != -1) { @@ -423,7 +450,7 @@ static bool _iup_contour_optimize (const hb_array_t conto for (unsigned i : solution) opt_indices.arrayZ[i] = true; - hb_vector_t rot_indices; + hb_vector_t &rot_indices = scratch.rot_indices.reset (); const hb_array_t opt_indices_array (opt_indices.arrayZ, opt_indices.length); rotate_array (opt_indices_array, -k, rot_indices); @@ -435,9 +462,9 @@ static bool _iup_contour_optimize (const hb_array_t conto hb_vector_t repeat_x_deltas, repeat_y_deltas; contour_point_vector_t repeat_points; - if (unlikely (!repeat_x_deltas.resize (n * 2, false) || - !repeat_y_deltas.resize (n * 2, false) || - !repeat_points.resize (n * 2, false))) + if (unlikely (!repeat_x_deltas.resize_dirty (n * 2) || + !repeat_y_deltas.resize_dirty (n * 2) || + !repeat_points.resize_dirty (n * 2))) return false; unsigned contour_point_size = hb_static_size (contour_point_t); @@ -453,19 +480,18 @@ static bool _iup_contour_optimize (const hb_array_t conto hb_memcpy ((void *) (repeat_points.arrayZ + n), (const void *) contour_points.arrayZ, n * contour_point_size); } - hb_vector_t costs; - hb_vector_t chain; if (!_iup_contour_optimize_dp (repeat_points, repeat_x_deltas, repeat_y_deltas, - forced_set, tolerance, n, - costs, chain)) + forced_set, tolerance_sq, n, + costs, chain, + scratch.interp_x_deltas, scratch.interp_y_deltas)) return false; unsigned best_cost = n + 1; int len = costs.length; - hb_set_t best_sol; + hb_iup_set_t best_sol; for (int start = n - 1; start < len; start++) { - hb_set_t solution; + hb_iup_set_t solution; int i = start; int lookback = start - (int) n; while (i > lookback) @@ -479,7 +505,7 @@ static bool _iup_contour_optimize (const hb_array_t conto unsigned cost = costs.arrayZ[start] - cost_i; if (cost <= best_cost) { - best_sol.set (solution); + best_sol = solution; best_cost = cost; } } @@ -496,12 +522,14 @@ bool iup_delta_optimize (const contour_point_vector_t& contour_points, const hb_vector_t& x_deltas, const hb_vector_t& y_deltas, hb_vector_t& opt_indices, /* OUT */ + iup_scratch_t &scratch, double tolerance) { if (!opt_indices.resize (contour_points.length)) return false; - hb_vector_t end_points; + hb_vector_t &end_points = scratch.end_points.reset (); + unsigned count = contour_points.length; if (unlikely (!end_points.alloc (count))) return false; @@ -524,7 +552,8 @@ bool iup_delta_optimize (const contour_point_vector_t& contour_points, x_deltas.as_array ().sub_array (start, len), y_deltas.as_array ().sub_array (start, len), opt_indices.as_array ().sub_array (start, len), - tolerance)) + tolerance, + scratch)) return false; start = end + 1; } diff --git a/thirdparty/harfbuzz/src/hb-subset-instancer-iup.hh b/thirdparty/harfbuzz/src/hb-subset-instancer-iup.hh index 01987bd258d..32d38c04f83 100644 --- a/thirdparty/harfbuzz/src/hb-subset-instancer-iup.hh +++ b/thirdparty/harfbuzz/src/hb-subset-instancer-iup.hh @@ -26,12 +26,27 @@ #define HB_SUBSET_INSTANCER_IUP_HH #include "hb-subset-plan.hh" + +struct iup_scratch_t +{ + hb_vector_t end_points; + hb_vector_t interp_x_deltas; + hb_vector_t interp_y_deltas; + hb_vector_t costs; + hb_vector_t chain; + hb_vector_t rot_indices; + hb_vector_t rot_x_deltas; + hb_vector_t rot_y_deltas; + contour_point_vector_t rot_points; +}; + /* given contour points and deltas, optimize a set of referenced points within error * tolerance. Returns optimized referenced point indices */ HB_INTERNAL bool iup_delta_optimize (const contour_point_vector_t& contour_points, const hb_vector_t& x_deltas, const hb_vector_t& y_deltas, hb_vector_t& opt_indices, /* OUT */ + iup_scratch_t &scratch, double tolerance = 0.0); #endif /* HB_SUBSET_INSTANCER_IUP_HH */ diff --git a/thirdparty/harfbuzz/src/hb-subset-instancer-solver.cc b/thirdparty/harfbuzz/src/hb-subset-instancer-solver.cc index ec015759904..11aefded2ca 100644 --- a/thirdparty/harfbuzz/src/hb-subset-instancer-solver.cc +++ b/thirdparty/harfbuzz/src/hb-subset-instancer-solver.cc @@ -62,9 +62,10 @@ static inline double supportScalar (double coord, const Triple &tent) return (end - coord) / (end - peak); } -static inline rebase_tent_result_t -_solve (Triple tent, Triple axisLimit, bool negative = false) +static inline void +_solve (Triple tent, Triple axisLimit, rebase_tent_result_t &out, bool negative = false) { + out.reset(); double axisMin = axisLimit.minimum; double axisDef = axisLimit.middle; double axisMax = axisLimit.maximum; @@ -75,14 +76,12 @@ _solve (Triple tent, Triple axisLimit, bool negative = false) // Mirror the problem such that axisDef <= peak if (axisDef > peak) { - rebase_tent_result_t vec = _solve (_reverse_negate (tent), - _reverse_negate (axisLimit), - !negative); + _solve (_reverse_negate (tent), _reverse_negate (axisLimit), out, !negative); - for (auto &p : vec) + for (auto &p : out) p = hb_pair (p.first, _reverse_negate (p.second)); - return vec; + return; } // axisDef <= peak @@ -98,7 +97,7 @@ _solve (Triple tent, Triple axisLimit, bool negative = false) * axisMin axisDef axisMax lower upper */ if (axisMax <= lower && axisMax < peak) - return rebase_tent_result_t{}; // No overlap + return; // No overlap /* case 2: Only the peak and outermost bound fall outside the new limit; * we keep the deltaset, update peak and outermost bound and scale deltas @@ -133,18 +132,18 @@ _solve (Triple tent, Triple axisLimit, bool negative = false) double mult = supportScalar (axisMax, tent); tent = Triple{lower, axisMax, axisMax}; - rebase_tent_result_t vec = _solve (tent, axisLimit); + _solve (tent, axisLimit, out); - for (auto &p : vec) + for (auto &p : out) p = hb_pair (p.first * mult, p.second); - return vec; + return; } // lower <= axisDef <= peak <= axisMax double gain = supportScalar (axisDef, tent); - rebase_tent_result_t out {hb_pair (gain, Triple{})}; + out.push(hb_pair (gain, Triple{})); // First, the positive side @@ -362,8 +361,6 @@ _solve (Triple tent, Triple axisLimit, bool negative = false) out.push (hb_pair (scalar1 - gain, loc1)); out.push (hb_pair (scalar2 - gain, loc2)); } - - return out; } static inline TripleDistances _reverse_triple_distances (const TripleDistances &v) @@ -405,18 +402,21 @@ double renormalizeValue (double v, const Triple &triple, return (-v_distance) /total_distance; } -rebase_tent_result_t -rebase_tent (Triple tent, Triple axisLimit, TripleDistances axis_triple_distances) +void +rebase_tent (Triple tent, Triple axisLimit, TripleDistances axis_triple_distances, + rebase_tent_result_t &out, + rebase_tent_result_t &scratch) { assert (-1.0 <= axisLimit.minimum && axisLimit.minimum <= axisLimit.middle && axisLimit.middle <= axisLimit.maximum && axisLimit.maximum <= +1.0); assert (-2.0 <= tent.minimum && tent.minimum <= tent.middle && tent.middle <= tent.maximum && tent.maximum <= +2.0); assert (tent.middle != 0.0); - rebase_tent_result_t sols = _solve (tent, axisLimit); + rebase_tent_result_t &sols = scratch; + _solve (tent, axisLimit, sols); auto n = [&axisLimit, &axis_triple_distances] (double v) { return renormalizeValue (v, axisLimit, axis_triple_distances); }; - rebase_tent_result_t out; + out.reset(); for (auto &p : sols) { if (!p.first) continue; @@ -429,6 +429,4 @@ rebase_tent (Triple tent, Triple axisLimit, TripleDistances axis_triple_distance out.push (hb_pair (p.first, Triple{n (t.minimum), n (t.middle), n (t.maximum)})); } - - return out; } diff --git a/thirdparty/harfbuzz/src/hb-subset-instancer-solver.hh b/thirdparty/harfbuzz/src/hb-subset-instancer-solver.hh index 9aac9fcc7ea..3462d3cf64c 100644 --- a/thirdparty/harfbuzz/src/hb-subset-instancer-solver.hh +++ b/thirdparty/harfbuzz/src/hb-subset-instancer-solver.hh @@ -42,10 +42,9 @@ struct TripleDistances double positive; }; -struct Triple { - - Triple () : - minimum (0.0), middle (0.0), maximum (0.0) {} +struct Triple +{ + Triple () = default; Triple (double minimum_, double middle_, double maximum_) : minimum (minimum_), middle (middle_), maximum (maximum_) {} @@ -81,10 +80,9 @@ struct Triple { return current; } - - double minimum; - double middle; - double maximum; + double minimum = 0; + double middle = 0; + double maximum = 0; }; using rebase_tent_result_item_t = hb_pair_t; @@ -107,8 +105,10 @@ HB_INTERNAL double renormalizeValue (double v, const Triple &triple, * If tent value is Triple{}, that is a special deltaset that should * be always-enabled (called "gain"). */ -HB_INTERNAL rebase_tent_result_t rebase_tent (Triple tent, - Triple axisLimit, - TripleDistances axis_triple_distances); +HB_INTERNAL void rebase_tent (Triple tent, + Triple axisLimit, + TripleDistances axis_triple_distances, + rebase_tent_result_t &out, + rebase_tent_result_t &scratch); #endif /* HB_SUBSET_INSTANCER_SOLVER_HH */ diff --git a/thirdparty/harfbuzz/src/hb-subset-plan-layout.cc b/thirdparty/harfbuzz/src/hb-subset-plan-layout.cc index aa2807b6979..ba4a57b5c1e 100644 --- a/thirdparty/harfbuzz/src/hb-subset-plan-layout.cc +++ b/thirdparty/harfbuzz/src/hb-subset-plan-layout.cc @@ -248,12 +248,48 @@ _GSUBGPOS_find_duplicate_features (const OT::GSUBGPOS &g, } } +static void +remap_feature_indices (const hb_set_t &feature_indices, + const hb_map_t &duplicate_feature_map, + const hb_hashmap_t>& catch_all_record_idx_feature_map, + hb_map_t *mapping, /* OUT */ + hb_map_t *mapping_w_duplicates /* OUT */) +{ + unsigned i = 0; + for (const auto _ : feature_indices) + { + // retain those features in case we need to insert a catch-all record to reinstate the old features + if (catch_all_record_idx_feature_map.has (_)) + { + mapping->set (_, i); + mapping_w_duplicates->set (_, i); + i++; + } + else + { + uint32_t f_idx = duplicate_feature_map.get (_); + uint32_t *new_idx; + if (mapping-> has (f_idx, &new_idx)) + { + mapping_w_duplicates->set (_, *new_idx); + } + else + { + mapping->set (_, i); + mapping_w_duplicates->set (_, i); + i++; + } + } + } +} + template static void _closure_glyphs_lookups_features (hb_subset_plan_t *plan, hb_set_t *gids_to_retain, hb_map_t *lookups, hb_map_t *features, + hb_map_t *features_w_duplicates, script_langsys_map *langsys_map, hb_hashmap_t> *feature_record_cond_idx_map, hb_hashmap_t *feature_substitutes_map, @@ -291,7 +327,7 @@ _closure_glyphs_lookups_features (hb_subset_plan_t *plan, feature_indices.clear (); table->prune_langsys (&duplicate_feature_map, &plan->layout_scripts, langsys_map, &feature_indices); - remap_indexes (&feature_indices, features); + remap_feature_indices (feature_indices, duplicate_feature_map, catch_all_record_idx_feature_map, features, features_w_duplicates); table.destroy (); } @@ -323,6 +359,7 @@ layout_populate_gids_to_retain (hb_subset_plan_t* plan, &plan->_glyphset_gsub, &plan->gsub_lookups, &plan->gsub_features, + &plan->gsub_features_w_duplicates, &plan->gsub_langsys, &plan->gsub_feature_record_cond_idx_map, &plan->gsub_feature_substitutes_map, @@ -335,6 +372,7 @@ layout_populate_gids_to_retain (hb_subset_plan_t* plan, &plan->_glyphset_gsub, &plan->gpos_lookups, &plan->gpos_features, + &plan->gpos_features_w_duplicates, &plan->gpos_langsys, &plan->gpos_feature_record_cond_idx_map, &plan->gpos_feature_substitutes_map, @@ -379,4 +417,4 @@ collect_layout_variation_indices (hb_subset_plan_t* plan) } #endif -#endif \ No newline at end of file +#endif diff --git a/thirdparty/harfbuzz/src/hb-subset-plan-member-list.hh b/thirdparty/harfbuzz/src/hb-subset-plan-member-list.hh index ade8278c40f..398fe81eca9 100644 --- a/thirdparty/harfbuzz/src/hb-subset-plan-member-list.hh +++ b/thirdparty/harfbuzz/src/hb-subset-plan-member-list.hh @@ -81,6 +81,10 @@ HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(>), gpo HB_SUBSET_PLAN_MEMBER (hb_map_t, gsub_features) HB_SUBSET_PLAN_MEMBER (hb_map_t, gpos_features) +//active features(with duplicates) old index -> new index mapping +HB_SUBSET_PLAN_MEMBER (hb_map_t, gsub_features_w_duplicates) +HB_SUBSET_PLAN_MEMBER (hb_map_t, gpos_features_w_duplicates) + //active feature variation records/condition index with variations HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(>), gsub_feature_record_cond_idx_map) HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(>), gpos_feature_record_cond_idx_map) diff --git a/thirdparty/harfbuzz/src/hb-subset-plan.cc b/thirdparty/harfbuzz/src/hb-subset-plan.cc index 25073d23fda..9dba8bf136d 100644 --- a/thirdparty/harfbuzz/src/hb-subset-plan.cc +++ b/thirdparty/harfbuzz/src/hb-subset-plan.cc @@ -697,6 +697,15 @@ hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face, return; } +#ifdef HB_EXPERIMENTAL_API + if ((input->flags & HB_SUBSET_FLAGS_RETAIN_GIDS) && + (input->flags & HB_SUBSET_FLAGS_RETAIN_NUM_GLYPHS)) { + // We've been requested to maintain the num glyphs count from the + // input face. + _num_output_glyphs = source->get_num_glyphs (); + } +#endif + _create_glyph_map_gsub ( &_glyphset_gsub, glyph_map, @@ -710,10 +719,10 @@ hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face, glyph_map->get(unicode_to_new_gid_list.arrayZ[i].second); } - bounds_width_vec.resize (_num_output_glyphs, false); + bounds_width_vec.resize_dirty (_num_output_glyphs); for (auto &v : bounds_width_vec) v = 0xFFFFFFFF; - bounds_height_vec.resize (_num_output_glyphs, false); + bounds_height_vec.resize_dirty (_num_output_glyphs); for (auto &v : bounds_height_vec) v = 0xFFFFFFFF; diff --git a/thirdparty/harfbuzz/src/hb-subset-plan.hh b/thirdparty/harfbuzz/src/hb-subset-plan.hh index 335b750da35..30e8e639b90 100644 --- a/thirdparty/harfbuzz/src/hb-subset-plan.hh +++ b/thirdparty/harfbuzz/src/hb-subset-plan.hh @@ -300,6 +300,7 @@ struct hb_subset_plan_t // compile times more reasonable: // - hb-subset-plan.cc // - hb-subset-plan-layout.cc +// - hb-subset-plan-var.cc // // The functions below are those needed to connect the split files // above together. diff --git a/thirdparty/harfbuzz/src/hb-subset-table-cff.cc b/thirdparty/harfbuzz/src/hb-subset-table-cff.cc new file mode 100644 index 00000000000..3984cfb8660 --- /dev/null +++ b/thirdparty/harfbuzz/src/hb-subset-table-cff.cc @@ -0,0 +1,143 @@ +#include "hb-subset-table.hh" + +#include "hb-ot-cff1-table.hh" +#include "hb-ot-cff2-table.hh" +#include "hb-ot-vorg-table.hh" + + +#ifndef HB_NO_SUBSET_CFF +template<> +struct hb_subset_plan_t::source_table_loader +{ + auto operator () (hb_subset_plan_t *plan) + HB_AUTO_RETURN (plan->accelerator ? plan->accelerator->cff1_accel : + plan->inprogress_accelerator ? plan->inprogress_accelerator->cff1_accel : + plan->cff1_accel) +}; +template<> +struct hb_subset_plan_t::source_table_loader +{ + auto operator () (hb_subset_plan_t *plan) + HB_AUTO_RETURN (plan->accelerator ? plan->accelerator->cff2_accel : + plan->inprogress_accelerator ? plan->inprogress_accelerator->cff2_accel : + plan->cff2_accel) +}; +#endif + + +bool _hb_subset_table_cff (hb_subset_plan_t *plan, hb_vector_t &buf, hb_tag_t tag, bool *success) +{ +#ifndef HB_NO_SUBSET_CFF + switch (tag) + { + case HB_TAG('C','F','F',' '): *success = _hb_subset_table (plan, buf); return true; + case HB_TAG('C','F','F','2'): *success = _hb_subset_table (plan, buf); return true; + case HB_TAG('V','O','R','G'): *success = _hb_subset_table (plan, buf); return true; + } +#endif + return false; +} + + +#ifdef HB_EXPERIMENTAL_API +#ifndef HB_NO_CFF + +template +static hb_blob_t* get_charstrings_data(accel_t& accel, hb_codepoint_t glyph_index) { + if (!accel.is_valid()) { + return hb_blob_get_empty (); + } + + hb_ubytes_t bytes = (*accel.charStrings)[glyph_index]; + if (!bytes) { + return hb_blob_get_empty (); + } + + hb_blob_t* cff_blob = accel.get_blob(); + uint32_t length; + const char* cff_data = hb_blob_get_data(cff_blob, &length) ; + + long int offset = (const char*) bytes.arrayZ - cff_data; + if (offset < 0 || offset > INT32_MAX) { + return hb_blob_get_empty (); + } + + return hb_blob_create_sub_blob(cff_blob, (uint32_t) offset, bytes.length); +} + +template +static hb_blob_t* get_charstrings_index(accel_t& accel) { + if (!accel.is_valid()) { + return hb_blob_get_empty (); + } + + const char* charstrings_start = (const char*) accel.charStrings; + unsigned charstrings_length = accel.charStrings->get_size(); + + hb_blob_t* cff_blob = accel.get_blob(); + uint32_t length; + const char* cff_data = hb_blob_get_data(cff_blob, &length) ; + + long int offset = charstrings_start - cff_data; + if (offset < 0 || offset > INT32_MAX) { + return hb_blob_get_empty (); + } + + return hb_blob_create_sub_blob(cff_blob, (uint32_t) offset, charstrings_length); +} + +/** + * hb_subset_cff_get_charstring_data: + * @face: A face object + * @glyph_index: Glyph index to get data for. + * + * Returns the raw outline data from the CFF/CFF2 table associated with the given glyph index. + * + * XSince: EXPERIMENTAL + **/ +HB_EXTERN hb_blob_t* +hb_subset_cff_get_charstring_data(hb_face_t* face, hb_codepoint_t glyph_index) { + return get_charstrings_data(*face->table.cff1, glyph_index); +} + +/** + * hb_subset_cff_get_charstrings_index: + * @face: A face object + * + * Returns the raw CFF CharStrings INDEX from the CFF table. + * + * XSince: EXPERIMENTAL + **/ +HB_EXTERN hb_blob_t* +hb_subset_cff_get_charstrings_index (hb_face_t* face) { + return get_charstrings_index (*face->table.cff1); +} + +/** + * hb_subset_cff2_get_charstring_data: + * @face: A face object + * @glyph_index: Glyph index to get data for. + * + * Returns the raw outline data from the CFF/CFF2 table associated with the given glyph index. + * + * XSince: EXPERIMENTAL + **/ +HB_EXTERN hb_blob_t* +hb_subset_cff2_get_charstring_data(hb_face_t* face, hb_codepoint_t glyph_index) { + return get_charstrings_data(*face->table.cff2, glyph_index); +} + +/** + * hb_subset_cff2_get_charstrings_index: + * @face: A face object + * + * Returns the raw CFF2 CharStrings INDEX from the CFF2 table. + * + * XSince: EXPERIMENTAL + **/ +HB_EXTERN hb_blob_t* +hb_subset_cff2_get_charstrings_index (hb_face_t* face) { + return get_charstrings_index (*face->table.cff2); +} +#endif +#endif diff --git a/thirdparty/harfbuzz/src/hb-subset-table-color.cc b/thirdparty/harfbuzz/src/hb-subset-table-color.cc new file mode 100644 index 00000000000..e44305e7dd7 --- /dev/null +++ b/thirdparty/harfbuzz/src/hb-subset-table-color.cc @@ -0,0 +1,21 @@ +#include "hb-subset-table.hh" + +#include "OT/Color/sbix/sbix.hh" +#include "OT/Color/CPAL/CPAL.hh" +#include "OT/Color/COLR/COLR.hh" +#include "OT/Color/CBDT/CBDT.hh" + +bool _hb_subset_table_color (hb_subset_plan_t *plan, hb_vector_t &buf, hb_tag_t tag, bool *success) +{ +#ifndef HB_NO_COLOR + switch (tag) + { + case HB_TAG('s','b','i','x'): *success = _hb_subset_table (plan, buf); return true; + case HB_TAG('C','O','L','R'): *success = _hb_subset_table (plan, buf); return true; + case HB_TAG('C','P','A','L'): *success = _hb_subset_table (plan, buf); return true; + case HB_TAG('C','B','L','C'): *success = _hb_subset_table (plan, buf); return true; + case HB_TAG('C','B','D','T'): *success = true; return true; /* skip CBDT, handled by CBLC */ + } +#endif + return false; +} diff --git a/thirdparty/harfbuzz/src/hb-subset-table-layout.cc b/thirdparty/harfbuzz/src/hb-subset-table-layout.cc new file mode 100644 index 00000000000..765422e365b --- /dev/null +++ b/thirdparty/harfbuzz/src/hb-subset-table-layout.cc @@ -0,0 +1,22 @@ +#include "hb-subset-table.hh" + +#include "hb-ot-layout-gdef-table.hh" +#include "hb-ot-layout-gsub-table.hh" +#include "hb-ot-layout-gpos-table.hh" +#include "hb-ot-layout-base-table.hh" +#include "hb-ot-math-table.hh" + +bool _hb_subset_table_layout (hb_subset_plan_t *plan, hb_vector_t &buf, hb_tag_t tag, bool *success) +{ +#ifndef HB_NO_SUBSET_LAYOUT + switch (tag) + { + case HB_TAG('G','D','E','F'): *success = _hb_subset_table (plan, buf); return true; + case HB_TAG('G','S','U','B'): *success = _hb_subset_table (plan, buf); return true; + case HB_TAG('G','P','O','S'): *success = _hb_subset_table (plan, buf); return true; + case HB_TAG('B','A','S','E'): *success = _hb_subset_table (plan, buf); return true; + case HB_TAG('M','A','T','H'): *success = _hb_subset_table (plan, buf); return true; + } +#endif + return false; +} diff --git a/thirdparty/harfbuzz/src/hb-subset-table-other.cc b/thirdparty/harfbuzz/src/hb-subset-table-other.cc new file mode 100644 index 00000000000..3b7ff4b3264 --- /dev/null +++ b/thirdparty/harfbuzz/src/hb-subset-table-other.cc @@ -0,0 +1,31 @@ +#include "hb-subset-table.hh" + +#include "hb-ot-cmap-table.hh" +#include "hb-ot-glyf-table.hh" +#include "hb-ot-hdmx-table.hh" +#include "hb-ot-hhea-table.hh" +#include "hb-ot-hmtx-table.hh" +#include "hb-ot-maxp-table.hh" +#include "hb-ot-os2-table.hh" +#include "hb-ot-name-table.hh" +#include "hb-ot-post-table.hh" + +bool _hb_subset_table_other (hb_subset_plan_t *plan, hb_vector_t &buf, hb_tag_t tag, bool *success) +{ + switch (tag) + { + case HB_TAG('g','l','y','f'): *success = _hb_subset_table (plan, buf); return true; + case HB_TAG('h','d','m','x'): *success = _hb_subset_table (plan, buf); return true; + case HB_TAG('n','a','m','e'): *success = _hb_subset_table (plan, buf); return true; + case HB_TAG('h','h','e','a'): *success = true; return true; /* skip hhea, handled by hmtx */ + case HB_TAG('h','m','t','x'): *success = _hb_subset_table (plan, buf); return true; + case HB_TAG('v','h','e','a'): *success = true; return true; /* skip vhea, handled by vmtx */ + case HB_TAG('v','m','t','x'): *success = _hb_subset_table (plan, buf); return true; + case HB_TAG('m','a','x','p'): *success = _hb_subset_table (plan, buf); return true; + case HB_TAG('l','o','c','a'): *success = true; return true; /* skip loca, handled by glyf */ + case HB_TAG('c','m','a','p'): *success = _hb_subset_table (plan, buf); return true; + case HB_TAG('O','S','/','2'): *success = _hb_subset_table (plan, buf); return true; + case HB_TAG('p','o','s','t'): *success = _hb_subset_table (plan, buf); return true; + } + return false; +} diff --git a/thirdparty/harfbuzz/src/hb-subset-table-var.cc b/thirdparty/harfbuzz/src/hb-subset-table-var.cc new file mode 100644 index 00000000000..b569b08a008 --- /dev/null +++ b/thirdparty/harfbuzz/src/hb-subset-table-var.cc @@ -0,0 +1,45 @@ +#include "hb-subset-table.hh" + +#include "hb-ot-var-hvar-table.hh" +#include "hb-ot-var-gvar-table.hh" +#include "hb-ot-var-fvar-table.hh" +#include "hb-ot-var-avar-table.hh" +#include "hb-ot-var-cvar-table.hh" +#include "hb-ot-var-mvar-table.hh" + +bool _hb_subset_table_var (hb_subset_plan_t *plan, hb_vector_t &buf, hb_tag_t tag, bool *success) +{ +#ifndef HB_NO_VAR + switch (tag) + { + case HB_TAG('H','V','A','R'): *success = _hb_subset_table (plan, buf); return true; + case HB_TAG('V','V','A','R'): *success = _hb_subset_table (plan, buf); return true; + case HB_TAG('g','v','a','r'): *success = _hb_subset_table (plan, buf); return true; + case HB_TAG('f','v','a','r'): + if (plan->user_axes_location.is_empty ()) + *success = _hb_subset_table_passthrough (plan, tag); + else + *success = _hb_subset_table (plan, buf); + return true; + case HB_TAG('a','v','a','r'): + if (plan->user_axes_location.is_empty ()) + *success = _hb_subset_table_passthrough (plan, tag); + else + *success = _hb_subset_table (plan, buf); + return true; + case HB_TAG('c','v','a','r'): + if (plan->user_axes_location.is_empty ()) + *success = _hb_subset_table_passthrough (plan, tag); + else + *success = _hb_subset_table (plan, buf); + return true; + case HB_TAG('M','V','A','R'): + if (plan->user_axes_location.is_empty ()) + *success = _hb_subset_table_passthrough (plan, tag); + else + *success = _hb_subset_table (plan, buf); + return true; + } +#endif + return false; +} diff --git a/thirdparty/harfbuzz/src/hb-subset-table.hh b/thirdparty/harfbuzz/src/hb-subset-table.hh new file mode 100644 index 00000000000..66588ec6f8f --- /dev/null +++ b/thirdparty/harfbuzz/src/hb-subset-table.hh @@ -0,0 +1,217 @@ +/* + * Copyright © 2018 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Garret Rieger, Roderick Sheeter + */ + +#ifndef HB_SUBSET_TABLE_HH +#define HB_SUBSET_TABLE_HH + + +#include "hb.hh" + +#include "hb-subset.hh" +#include "hb-repacker.hh" + + +template +static bool +_hb_subset_table_try (const TableType *table, + hb_vector_t* buf, + hb_subset_context_t* c /* OUT */) +{ + c->serializer->start_serialize (); + if (c->serializer->in_error ()) return false; + + bool needed = table->subset (c); + if (!c->serializer->ran_out_of_room ()) + { + c->serializer->end_serialize (); + return needed; + } + + unsigned buf_size = buf->allocated; + buf_size = buf_size * 2 + 16; + + + + + DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c ran out of room; reallocating to %u bytes.", + HB_UNTAG (c->table_tag), buf_size); + + if (unlikely (buf_size > c->source_blob->length * 256 || + !buf->alloc_exact (buf_size))) + { + DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c failed to reallocate %u bytes.", + HB_UNTAG (c->table_tag), buf_size); + return needed; + } + + c->serializer->reset (buf->arrayZ, buf->allocated); + return _hb_subset_table_try (table, buf, c); +} + +static HB_UNUSED unsigned +_hb_subset_estimate_table_size (hb_subset_plan_t *plan, + unsigned table_len, + hb_tag_t table_tag) +{ + unsigned src_glyphs = plan->source->get_num_glyphs (); + unsigned dst_glyphs = plan->glyphset ()->get_population (); + + unsigned bulk = 8192; + /* Tables that we want to allocate same space as the source table. For GSUB/GPOS it's + * because those are expensive to subset, so giving them more room is fine. */ + bool same_size = table_tag == HB_TAG('G','S','U','B') || + table_tag == HB_TAG('G','P','O','S') || + table_tag == HB_TAG('G','D','E','F') || + table_tag == HB_TAG('n','a','m','e'); + + if (plan->flags & HB_SUBSET_FLAGS_RETAIN_GIDS) + { + if (table_tag == HB_TAG('C','F','F',' ')) + { + /* Add some extra room for the CFF charset. */ + bulk += src_glyphs * 16; + } + else if (table_tag == HB_TAG('C','F','F','2')) + { + /* Just extra CharString offsets. */ + bulk += src_glyphs * 4; + } + } + + if (unlikely (!src_glyphs) || same_size) + return bulk + table_len; + + return bulk + (unsigned) (table_len * sqrt ((double) dst_glyphs / src_glyphs)); +} + +/* + * Repack the serialization buffer if any offset overflows exist. + */ +static HB_UNUSED hb_blob_t* +_hb_subset_repack (hb_tag_t tag, const hb_serialize_context_t& c) +{ + if (!c.offset_overflow ()) + return c.copy_blob (); + + hb_blob_t* result = hb_resolve_overflows (c.object_graph (), tag); + + if (unlikely (!result)) + { + DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c offset overflow resolution failed.", + HB_UNTAG (tag)); + return nullptr; + } + + return result; +} + +template +static HB_UNUSED auto _hb_do_destroy (T &t, hb_priority<1>) HB_RETURN (void, t.destroy ()) + +template +static HB_UNUSED void _hb_do_destroy (T &t, hb_priority<0>) {} + +template +static bool +_hb_subset_table (hb_subset_plan_t *plan, hb_vector_t &buf) +{ + auto &&source_blob = plan->source_table (); + auto *table = source_blob.get (); + + hb_tag_t tag = TableType::tableTag; + hb_blob_t *blob = source_blob.get_blob(); + if (unlikely (!blob || !blob->data)) + { + DEBUG_MSG (SUBSET, nullptr, + "OT::%c%c%c%c::subset sanitize failed on source table.", HB_UNTAG (tag)); + _hb_do_destroy (source_blob, hb_prioritize); + return false; + } + + unsigned buf_size = _hb_subset_estimate_table_size (plan, blob->length, TableType::tableTag); + DEBUG_MSG (SUBSET, nullptr, + "OT::%c%c%c%c initial estimated table size: %u bytes.", HB_UNTAG (tag), buf_size); + if (unlikely (!buf.alloc (buf_size))) + { + DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c failed to allocate %u bytes.", HB_UNTAG (tag), buf_size); + _hb_do_destroy (source_blob, hb_prioritize); + return false; + } + + bool needed = false; + hb_serialize_context_t serializer (buf.arrayZ, buf.allocated); + { + hb_subset_context_t c (blob, plan, &serializer, tag); + needed = _hb_subset_table_try (table, &buf, &c); + } + _hb_do_destroy (source_blob, hb_prioritize); + + if (serializer.in_error () && !serializer.only_offset_overflow ()) + { + DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c::subset FAILED!", HB_UNTAG (tag)); + return false; + } + + if (!needed) + { + DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c::subset table subsetted to empty.", HB_UNTAG (tag)); + return true; + } + + bool result = false; + hb_blob_t *dest_blob = _hb_subset_repack (tag, serializer); + if (dest_blob) + { + DEBUG_MSG (SUBSET, nullptr, + "OT::%c%c%c%c final subset table size: %u bytes.", + HB_UNTAG (tag), dest_blob->length); + result = plan->add_table (tag, dest_blob); + hb_blob_destroy (dest_blob); + } + + DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c::subset %s", + HB_UNTAG (tag), result ? "success" : "FAILED!"); + return result; +} + +static HB_UNUSED bool +_hb_subset_table_passthrough (hb_subset_plan_t *plan, hb_tag_t tag) +{ + hb_blob_t *source_table = hb_face_reference_table (plan->source, tag); + bool result = plan->add_table (tag, source_table); + hb_blob_destroy (source_table); + return result; +} + + +HB_INTERNAL bool _hb_subset_table_layout (hb_subset_plan_t *plan, hb_vector_t &buf, hb_tag_t tag, bool *success); +HB_INTERNAL bool _hb_subset_table_var (hb_subset_plan_t *plan, hb_vector_t &buf, hb_tag_t tag, bool *success); +HB_INTERNAL bool _hb_subset_table_cff (hb_subset_plan_t *plan, hb_vector_t &buf, hb_tag_t tag, bool *success); +HB_INTERNAL bool _hb_subset_table_color (hb_subset_plan_t *plan, hb_vector_t &buf, hb_tag_t tag, bool *success); +HB_INTERNAL bool _hb_subset_table_other (hb_subset_plan_t *plan, hb_vector_t &buf, hb_tag_t tag, bool *success); + + +#endif /* HB_SUBSET_TABLE_HH */ diff --git a/thirdparty/harfbuzz/src/hb-subset.cc b/thirdparty/harfbuzz/src/hb-subset.cc index 7f9dc34ded8..d1ca60e63e5 100644 --- a/thirdparty/harfbuzz/src/hb-subset.cc +++ b/thirdparty/harfbuzz/src/hb-subset.cc @@ -25,65 +25,19 @@ */ #include "hb.hh" + #include "hb-open-type.hh" +#include "hb-open-file.hh" #include "hb-subset.hh" - -#include "hb-open-file.hh" -#include "hb-ot-cmap-table.hh" -#include "hb-ot-glyf-table.hh" -#include "hb-ot-hdmx-table.hh" -#include "hb-ot-head-table.hh" -#include "hb-ot-hhea-table.hh" -#include "hb-ot-hmtx-table.hh" -#include "hb-ot-maxp-table.hh" -#include "OT/Color/CBDT/CBDT.hh" -#include "OT/Color/COLR/COLR.hh" -#include "OT/Color/CPAL/CPAL.hh" -#include "OT/Color/sbix/sbix.hh" -#include "hb-ot-os2-table.hh" -#include "hb-ot-post-table.hh" -#include "hb-ot-post-table-v2subset.hh" -#include "hb-ot-cff1-table.hh" -#include "hb-ot-cff2-table.hh" -#include "hb-ot-vorg-table.hh" -#include "hb-ot-name-table.hh" -#include "hb-ot-layout-base-table.hh" -#include "hb-ot-layout-gsub-table.hh" -#include "hb-ot-layout-gpos-table.hh" -#include "hb-ot-var-avar-table.hh" -#include "hb-ot-var-cvar-table.hh" -#include "hb-ot-var-fvar-table.hh" -#include "hb-ot-var-gvar-table.hh" -#include "hb-ot-var-hvar-table.hh" -#include "hb-ot-var-mvar-table.hh" -#include "hb-ot-math-table.hh" -#include "hb-ot-stat-table.hh" -#include "hb-repacker.hh" +#include "hb-subset-table.hh" #include "hb-subset-accelerator.hh" -using OT::Layout::GSUB; -using OT::Layout::GPOS; - - -#ifndef HB_NO_SUBSET_CFF -template<> -struct hb_subset_plan_t::source_table_loader -{ - auto operator () (hb_subset_plan_t *plan) - HB_AUTO_RETURN (plan->accelerator ? plan->accelerator->cff1_accel : - plan->inprogress_accelerator ? plan->inprogress_accelerator->cff1_accel : - plan->cff1_accel) -}; -template<> -struct hb_subset_plan_t::source_table_loader -{ - auto operator () (hb_subset_plan_t *plan) - HB_AUTO_RETURN (plan->accelerator ? plan->accelerator->cff2_accel : - plan->inprogress_accelerator ? plan->inprogress_accelerator->cff2_accel : - plan->cff2_accel) -}; -#endif +#include "hb-ot-cmap-table.hh" +#include "hb-ot-var-cvar-table.hh" +#include "hb-ot-head-table.hh" +#include "hb-ot-stat-table.hh" +#include "hb-ot-post-table-v2subset.hh" /** @@ -116,56 +70,56 @@ hb_user_data_key_t _hb_subset_accelerator_user_data_key = {}; * if we are unable to list the tables in a face. */ static hb_tag_t known_tables[] { - HB_TAG ('a', 'v', 'a', 'r'), - HB_OT_TAG_BASE, - HB_OT_TAG_CBDT, - HB_OT_TAG_CBLC, - HB_OT_TAG_CFF1, - HB_OT_TAG_CFF2, - HB_OT_TAG_cmap, - HB_OT_TAG_COLR, - HB_OT_TAG_CPAL, - HB_TAG ('c', 'v', 'a', 'r'), - HB_TAG ('c', 'v', 't', ' '), - HB_TAG ('D', 'S', 'I', 'G'), - HB_TAG ('E', 'B', 'D', 'T'), - HB_TAG ('E', 'B', 'L', 'C'), - HB_TAG ('E', 'B', 'S', 'C'), - HB_TAG ('f', 'p', 'g', 'm'), - HB_TAG ('f', 'v', 'a', 'r'), - HB_TAG ('g', 'a', 's', 'p'), - HB_OT_TAG_GDEF, - HB_OT_TAG_glyf, - HB_OT_TAG_GPOS, - HB_OT_TAG_GSUB, - HB_OT_TAG_gvar, - HB_OT_TAG_hdmx, - HB_OT_TAG_head, - HB_OT_TAG_hhea, - HB_OT_TAG_hmtx, - HB_OT_TAG_HVAR, - HB_OT_TAG_JSTF, - HB_TAG ('k', 'e', 'r', 'n'), - HB_OT_TAG_loca, - HB_TAG ('L', 'T', 'S', 'H'), - HB_OT_TAG_MATH, - HB_OT_TAG_maxp, - HB_TAG ('M', 'E', 'R', 'G'), - HB_TAG ('m', 'e', 't', 'a'), - HB_TAG ('M', 'V', 'A', 'R'), - HB_TAG ('P', 'C', 'L', 'T'), - HB_OT_TAG_post, - HB_TAG ('p', 'r', 'e', 'p'), - HB_OT_TAG_sbix, - HB_TAG ('S', 'T', 'A', 'T'), - HB_TAG ('S', 'V', 'G', ' '), - HB_TAG ('V', 'D', 'M', 'X'), - HB_OT_TAG_vhea, - HB_OT_TAG_vmtx, - HB_OT_TAG_VORG, - HB_OT_TAG_VVAR, - HB_OT_TAG_name, - HB_OT_TAG_OS2 + HB_TAG('a','v','a','r'), + HB_TAG('B','A','S','E'), + HB_TAG('C','B','D','T'), + HB_TAG('C','B','L','C'), + HB_TAG('C','F','F',' '), + HB_TAG('C','F','F','2'), + HB_TAG('c','m','a','p'), + HB_TAG('C','O','L','R'), + HB_TAG('C','P','A','L'), + HB_TAG('c','v','a','r'), + HB_TAG('c','v','t',' '), + HB_TAG('D','S','I','G'), + HB_TAG('E','B','D','T'), + HB_TAG('E','B','L','C'), + HB_TAG('E','B','S','C'), + HB_TAG('f','p','g','m'), + HB_TAG('f','v','a','r'), + HB_TAG('g','a','s','p'), + HB_TAG('G','D','E','F'), + HB_TAG('g','l','y','f'), + HB_TAG('G','P','O','S'), + HB_TAG('G','S','U','B'), + HB_TAG('g','v','a','r'), + HB_TAG('h','d','m','x'), + HB_TAG('h','e','a','d'), + HB_TAG('h','h','e','a'), + HB_TAG('h','m','t','x'), + HB_TAG('H','V','A','R'), + HB_TAG('J','S','T','F'), + HB_TAG('k','e','r','n'), + HB_TAG('l','o','c','a'), + HB_TAG('L','T','S','H'), + HB_TAG('M','A','T','H'), + HB_TAG('m','a','x','p'), + HB_TAG('M','E','R','G'), + HB_TAG('m','e','t','a'), + HB_TAG('M','V','A','R'), + HB_TAG('P','C','L','T'), + HB_TAG('p','o','s','t'), + HB_TAG('p','r','e','p'), + HB_TAG('s','b','i','x'), + HB_TAG('S','T','A','T'), + HB_TAG('S','V','G',' '), + HB_TAG('V','D','M','X'), + HB_TAG('v','h','e','a'), + HB_TAG('v','m','t','x'), + HB_TAG('V','O','R','G'), + HB_TAG('V','V','A','R'), + HB_TAG('n','a','m','e'), + HB_TAG('O','S','/','2') }; static bool _table_is_empty (const hb_face_t *face, hb_tag_t tag) @@ -213,169 +167,6 @@ _get_table_tags (const hb_subset_plan_t* plan, } -static unsigned -_plan_estimate_subset_table_size (hb_subset_plan_t *plan, - unsigned table_len, - hb_tag_t table_tag) -{ - unsigned src_glyphs = plan->source->get_num_glyphs (); - unsigned dst_glyphs = plan->glyphset ()->get_population (); - - unsigned bulk = 8192; - /* Tables that we want to allocate same space as the source table. For GSUB/GPOS it's - * because those are expensive to subset, so giving them more room is fine. */ - bool same_size = table_tag == HB_OT_TAG_GSUB || - table_tag == HB_OT_TAG_GPOS || - table_tag == HB_OT_TAG_name; - - if (plan->flags & HB_SUBSET_FLAGS_RETAIN_GIDS) - { - if (table_tag == HB_OT_TAG_CFF1) - { - /* Add some extra room for the CFF charset. */ - bulk += src_glyphs * 16; - } - else if (table_tag == HB_OT_TAG_CFF2) - { - /* Just extra CharString offsets. */ - bulk += src_glyphs * 4; - } - } - - if (unlikely (!src_glyphs) || same_size) - return bulk + table_len; - - return bulk + (unsigned) (table_len * sqrt ((double) dst_glyphs / src_glyphs)); -} - -/* - * Repack the serialization buffer if any offset overflows exist. - */ -static hb_blob_t* -_repack (hb_tag_t tag, const hb_serialize_context_t& c) -{ - if (!c.offset_overflow ()) - return c.copy_blob (); - - hb_blob_t* result = hb_resolve_overflows (c.object_graph (), tag); - - if (unlikely (!result)) - { - DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c offset overflow resolution failed.", - HB_UNTAG (tag)); - return nullptr; - } - - return result; -} - -template -static -bool -_try_subset (const TableType *table, - hb_vector_t* buf, - hb_subset_context_t* c /* OUT */) -{ - c->serializer->start_serialize (); - if (c->serializer->in_error ()) return false; - - bool needed = table->subset (c); - if (!c->serializer->ran_out_of_room ()) - { - c->serializer->end_serialize (); - return needed; - } - - unsigned buf_size = buf->allocated; - buf_size = buf_size * 2 + 16; - - - - - DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c ran out of room; reallocating to %u bytes.", - HB_UNTAG (c->table_tag), buf_size); - - if (unlikely (buf_size > c->source_blob->length * 256 || - !buf->alloc_exact (buf_size))) - { - DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c failed to reallocate %u bytes.", - HB_UNTAG (c->table_tag), buf_size); - return needed; - } - - c->serializer->reset (buf->arrayZ, buf->allocated); - return _try_subset (table, buf, c); -} - -template -static auto _do_destroy (T &t, hb_priority<1>) HB_RETURN (void, t.destroy ()) - -template -static void _do_destroy (T &t, hb_priority<0>) {} - -template -static bool -_subset (hb_subset_plan_t *plan, hb_vector_t &buf) -{ - auto &&source_blob = plan->source_table (); - auto *table = source_blob.get (); - - hb_tag_t tag = TableType::tableTag; - hb_blob_t *blob = source_blob.get_blob(); - if (unlikely (!blob || !blob->data)) - { - DEBUG_MSG (SUBSET, nullptr, - "OT::%c%c%c%c::subset sanitize failed on source table.", HB_UNTAG (tag)); - _do_destroy (source_blob, hb_prioritize); - return false; - } - - unsigned buf_size = _plan_estimate_subset_table_size (plan, blob->length, TableType::tableTag); - DEBUG_MSG (SUBSET, nullptr, - "OT::%c%c%c%c initial estimated table size: %u bytes.", HB_UNTAG (tag), buf_size); - if (unlikely (!buf.alloc (buf_size))) - { - DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c failed to allocate %u bytes.", HB_UNTAG (tag), buf_size); - _do_destroy (source_blob, hb_prioritize); - return false; - } - - bool needed = false; - hb_serialize_context_t serializer (buf.arrayZ, buf.allocated); - { - hb_subset_context_t c (blob, plan, &serializer, tag); - needed = _try_subset (table, &buf, &c); - } - _do_destroy (source_blob, hb_prioritize); - - if (serializer.in_error () && !serializer.only_offset_overflow ()) - { - DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c::subset FAILED!", HB_UNTAG (tag)); - return false; - } - - if (!needed) - { - DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c::subset table subsetted to empty.", HB_UNTAG (tag)); - return true; - } - - bool result = false; - hb_blob_t *dest_blob = _repack (tag, serializer); - if (dest_blob) - { - DEBUG_MSG (SUBSET, nullptr, - "OT::%c%c%c%c final subset table size: %u bytes.", - HB_UNTAG (tag), dest_blob->length); - result = plan->add_table (tag, dest_blob); - hb_blob_destroy (dest_blob); - } - - DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c::subset %s", - HB_UNTAG (tag), result ? "success" : "FAILED!"); - return result; -} - static bool _is_table_present (hb_face_t *source, hb_tag_t tag) { @@ -407,34 +198,34 @@ _should_drop_table (hb_subset_plan_t *plan, hb_tag_t tag) switch (tag) { - case HB_TAG ('c','v','a','r'): /* hint table, fallthrough */ + case HB_TAG('c','v','a','r'): /* hint table, fallthrough */ return plan->all_axes_pinned || (plan->flags & HB_SUBSET_FLAGS_NO_HINTING); - case HB_TAG ('c','v','t',' '): /* hint table, fallthrough */ - case HB_TAG ('f','p','g','m'): /* hint table, fallthrough */ - case HB_TAG ('p','r','e','p'): /* hint table, fallthrough */ - case HB_TAG ('h','d','m','x'): /* hint table, fallthrough */ - case HB_TAG ('V','D','M','X'): /* hint table, fallthrough */ + case HB_TAG('c','v','t',' '): /* hint table, fallthrough */ + case HB_TAG('f','p','g','m'): /* hint table, fallthrough */ + case HB_TAG('p','r','e','p'): /* hint table, fallthrough */ + case HB_TAG('h','d','m','x'): /* hint table, fallthrough */ + case HB_TAG('V','D','M','X'): /* hint table, fallthrough */ return plan->flags & HB_SUBSET_FLAGS_NO_HINTING; #ifdef HB_NO_SUBSET_LAYOUT // Drop Layout Tables if requested. - case HB_OT_TAG_GDEF: - case HB_OT_TAG_GPOS: - case HB_OT_TAG_GSUB: - case HB_TAG ('m','o','r','x'): - case HB_TAG ('m','o','r','t'): - case HB_TAG ('k','e','r','x'): - case HB_TAG ('k','e','r','n'): + case HB_TAG('G','D','E','F'): + case HB_TAG('G','P','O','S'): + case HB_TAG('G','S','U','B'): + case HB_TAG('m','o','r','x'): + case HB_TAG('m','o','r','t'): + case HB_TAG('k','e','r','x'): + case HB_TAG('k','e','r','n'): return true; #endif - case HB_TAG ('a','v','a','r'): - case HB_TAG ('f','v','a','r'): - case HB_TAG ('g','v','a','r'): - case HB_OT_TAG_HVAR: - case HB_OT_TAG_VVAR: - case HB_TAG ('M','V','A','R'): + case HB_TAG('a','v','a','r'): + case HB_TAG('f','v','a','r'): + case HB_TAG('g','v','a','r'): + case HB_TAG('H','V','A','R'): + case HB_TAG('V','V','A','R'): + case HB_TAG('M','V','A','R'): return plan->all_axes_pinned; default: @@ -442,15 +233,6 @@ _should_drop_table (hb_subset_plan_t *plan, hb_tag_t tag) } } -static bool -_passthrough (hb_subset_plan_t *plan, hb_tag_t tag) -{ - hb_blob_t *source_table = hb_face_reference_table (plan->source, tag); - bool result = plan->add_table (tag, source_table); - hb_blob_destroy (source_table); - return result; -} - static bool _dependencies_satisfied (hb_subset_plan_t *plan, hb_tag_t tag, const hb_set_t &subsetted_tags, @@ -458,13 +240,13 @@ _dependencies_satisfied (hb_subset_plan_t *plan, hb_tag_t tag, { switch (tag) { - case HB_OT_TAG_hmtx: - case HB_OT_TAG_vmtx: - case HB_OT_TAG_maxp: - case HB_OT_TAG_OS2: - return !plan->normalized_coords || !pending_subset_tags.has (HB_OT_TAG_glyf); - case HB_OT_TAG_GPOS: - return plan->all_axes_pinned || !pending_subset_tags.has (HB_OT_TAG_GDEF); + case HB_TAG('h','m','t','x'): + case HB_TAG('v','m','t','x'): + case HB_TAG('m','a','x','p'): + case HB_TAG('O','S','/','2'): + return !plan->normalized_coords || !pending_subset_tags.has (HB_TAG('g','l','y','f')); + case HB_TAG('G','P','O','S'): + return plan->all_axes_pinned || !pending_subset_tags.has (HB_TAG('G','D','E','F')); default: return true; } @@ -476,88 +258,48 @@ _subset_table (hb_subset_plan_t *plan, hb_tag_t tag) { if (plan->no_subset_tables.has (tag)) { - return _passthrough (plan, tag); + return _hb_subset_table_passthrough (plan, tag); } DEBUG_MSG (SUBSET, nullptr, "subset %c%c%c%c", HB_UNTAG (tag)); + + bool success; + if (_hb_subset_table_layout (plan, buf, tag, &success) || + _hb_subset_table_var (plan, buf, tag, &success) || + _hb_subset_table_cff (plan, buf, tag, &success) || + _hb_subset_table_color (plan, buf, tag, &success) || + _hb_subset_table_other (plan, buf, tag, &success)) + return success; + + switch (tag) { - case HB_OT_TAG_glyf: return _subset (plan, buf); - case HB_OT_TAG_hdmx: return _subset (plan, buf); - case HB_OT_TAG_name: return _subset (plan, buf); - case HB_OT_TAG_head: - if (_is_table_present (plan->source, HB_OT_TAG_glyf) && !_should_drop_table (plan, HB_OT_TAG_glyf)) + case HB_TAG('h','e','a','d'): + if (_is_table_present (plan->source, HB_TAG('g','l','y','f')) && !_should_drop_table (plan, HB_TAG('g','l','y','f'))) return true; /* skip head, handled by glyf */ - return _subset (plan, buf); - case HB_OT_TAG_hhea: return true; /* skip hhea, handled by hmtx */ - case HB_OT_TAG_hmtx: return _subset (plan, buf); - case HB_OT_TAG_vhea: return true; /* skip vhea, handled by vmtx */ - case HB_OT_TAG_vmtx: return _subset (plan, buf); - case HB_OT_TAG_maxp: return _subset (plan, buf); - case HB_OT_TAG_sbix: return _subset (plan, buf); - case HB_OT_TAG_loca: return true; /* skip loca, handled by glyf */ - case HB_OT_TAG_cmap: return _subset (plan, buf); - case HB_OT_TAG_OS2 : return _subset (plan, buf); - case HB_OT_TAG_post: return _subset (plan, buf); - case HB_OT_TAG_COLR: return _subset (plan, buf); - case HB_OT_TAG_CPAL: return _subset (plan, buf); - case HB_OT_TAG_CBLC: return _subset (plan, buf); - case HB_OT_TAG_CBDT: return true; /* skip CBDT, handled by CBLC */ - case HB_OT_TAG_MATH: return _subset (plan, buf); - case HB_OT_TAG_BASE: return _subset (plan, buf); + return _hb_subset_table (plan, buf); -#ifndef HB_NO_SUBSET_CFF - case HB_OT_TAG_CFF1: return _subset (plan, buf); - case HB_OT_TAG_CFF2: return _subset (plan, buf); - case HB_OT_TAG_VORG: return _subset (plan, buf); -#endif - -#ifndef HB_NO_SUBSET_LAYOUT - case HB_OT_TAG_GDEF: return _subset (plan, buf); - case HB_OT_TAG_GSUB: return _subset (plan, buf); - case HB_OT_TAG_GPOS: return _subset (plan, buf); - case HB_OT_TAG_gvar: return _subset (plan, buf); - case HB_OT_TAG_HVAR: return _subset (plan, buf); - case HB_OT_TAG_VVAR: return _subset (plan, buf); -#endif + case HB_TAG('S','T','A','T'): + if (!plan->user_axes_location.is_empty ()) return _hb_subset_table (plan, buf); + else return _hb_subset_table_passthrough (plan, tag); + case HB_TAG('c','v','t',' '): #ifndef HB_NO_VAR - case HB_OT_TAG_fvar: - if (plan->user_axes_location.is_empty ()) return _passthrough (plan, tag); - return _subset (plan, buf); - case HB_OT_TAG_avar: - if (plan->user_axes_location.is_empty ()) return _passthrough (plan, tag); - return _subset (plan, buf); - case HB_OT_TAG_cvar: - if (plan->user_axes_location.is_empty ()) return _passthrough (plan, tag); - return _subset (plan, buf); - case HB_OT_TAG_MVAR: - if (plan->user_axes_location.is_empty ()) return _passthrough (plan, tag); - return _subset (plan, buf); -#endif - - case HB_OT_TAG_STAT: - if (!plan->user_axes_location.is_empty ()) return _subset (plan, buf); - else return _passthrough (plan, tag); - - case HB_TAG ('c', 'v', 't', ' '): -#ifndef HB_NO_VAR - if (_is_table_present (plan->source, HB_OT_TAG_cvar) && + if (_is_table_present (plan->source, HB_TAG('c','v','a','r')) && plan->normalized_coords && !plan->pinned_at_default) { auto &cvar = *plan->source->table.cvar; return OT::cvar::add_cvt_and_apply_deltas (plan, cvar.get_tuple_var_data (), &cvar); } #endif - return _passthrough (plan, tag); - - default: - if (plan->flags & HB_SUBSET_FLAGS_PASSTHROUGH_UNRECOGNIZED) - return _passthrough (plan, tag); - - // Drop table - return true; + return _hb_subset_table_passthrough (plan, tag); } + + if (plan->flags & HB_SUBSET_FLAGS_PASSTHROUGH_UNRECOGNIZED) + return _hb_subset_table_passthrough (plan, tag); + + // Drop table + return true; } static void _attach_accelerator_data (hb_subset_plan_t* plan, @@ -707,108 +449,4 @@ hb_subset_plan_execute_or_fail (hb_subset_plan_t *plan) end: return success ? hb_face_reference (plan->dest) : nullptr; -} - - -#ifdef HB_EXPERIMENTAL_API - -#include "hb-ot-cff1-table.hh" - -template -static hb_blob_t* get_charstrings_data(accel_t& accel, hb_codepoint_t glyph_index) { - if (!accel.is_valid()) { - return hb_blob_get_empty (); - } - - hb_ubytes_t bytes = (*accel.charStrings)[glyph_index]; - if (!bytes) { - return hb_blob_get_empty (); - } - - hb_blob_t* cff_blob = accel.get_blob(); - uint32_t length; - const char* cff_data = hb_blob_get_data(cff_blob, &length) ; - - long int offset = (const char*) bytes.arrayZ - cff_data; - if (offset < 0 || offset > INT32_MAX) { - return hb_blob_get_empty (); - } - - return hb_blob_create_sub_blob(cff_blob, (uint32_t) offset, bytes.length); -} - -template -static hb_blob_t* get_charstrings_index(accel_t& accel) { - if (!accel.is_valid()) { - return hb_blob_get_empty (); - } - - const char* charstrings_start = (const char*) accel.charStrings; - unsigned charstrings_length = accel.charStrings->get_size(); - - hb_blob_t* cff_blob = accel.get_blob(); - uint32_t length; - const char* cff_data = hb_blob_get_data(cff_blob, &length) ; - - long int offset = charstrings_start - cff_data; - if (offset < 0 || offset > INT32_MAX) { - return hb_blob_get_empty (); - } - - return hb_blob_create_sub_blob(cff_blob, (uint32_t) offset, charstrings_length); -} - -/** - * hb_subset_cff_get_charstring_data: - * @face: A face object - * @glyph_index: Glyph index to get data for. - * - * Returns the raw outline data from the CFF/CFF2 table associated with the given glyph index. - * - * XSince: EXPERIMENTAL - **/ -HB_EXTERN hb_blob_t* -hb_subset_cff_get_charstring_data(hb_face_t* face, hb_codepoint_t glyph_index) { - return get_charstrings_data(*face->table.cff1, glyph_index); -} - -/** - * hb_subset_cff_get_charstrings_index: - * @face: A face object - * - * Returns the raw CFF CharStrings INDEX from the CFF table. - * - * XSince: EXPERIMENTAL - **/ -HB_EXTERN hb_blob_t* -hb_subset_cff_get_charstrings_index (hb_face_t* face) { - return get_charstrings_index (*face->table.cff1); -} - -/** - * hb_subset_cff2_get_charstring_data: - * @face: A face object - * @glyph_index: Glyph index to get data for. - * - * Returns the raw outline data from the CFF/CFF2 table associated with the given glyph index. - * - * XSince: EXPERIMENTAL - **/ -HB_EXTERN hb_blob_t* -hb_subset_cff2_get_charstring_data(hb_face_t* face, hb_codepoint_t glyph_index) { - return get_charstrings_data(*face->table.cff2, glyph_index); -} - -/** - * hb_subset_cff2_get_charstrings_index: - * @face: A face object - * - * Returns the raw CFF2 CharStrings INDEX from the CFF2 table. - * - * XSince: EXPERIMENTAL - **/ -HB_EXTERN hb_blob_t* -hb_subset_cff2_get_charstrings_index (hb_face_t* face) { - return get_charstrings_index (*face->table.cff2); -} -#endif \ No newline at end of file +} \ No newline at end of file diff --git a/thirdparty/harfbuzz/src/hb-subset.h b/thirdparty/harfbuzz/src/hb-subset.h index 374035df3ee..bc55b6d0b8f 100644 --- a/thirdparty/harfbuzz/src/hb-subset.h +++ b/thirdparty/harfbuzz/src/hb-subset.h @@ -80,6 +80,10 @@ typedef struct hb_subset_plan_t hb_subset_plan_t; * @HB_SUBSET_FLAGS_IFTB_REQUIREMENTS: If set enforce requirements on the output subset * to allow it to be used with incremental font transfer IFTB patches. Primarily, * this forces all outline data to use long (32 bit) offsets. Since: EXPERIMENTAL + * @HB_SUBSET_FLAGS_RETAIN_NUM_GLYPHS: If this flag is set along side + * HB_SUBSET_FLAGS_RETAIN_GIDS then the number of glyphs in the font won't + * be reduced as a result of subsetting. If necessary empty glyphs will be + * included at the end of the font to keep the number of glyphs unchanged. * * List of boolean properties that can be configured on the subset input. * @@ -101,6 +105,7 @@ typedef enum { /*< flags >*/ HB_SUBSET_FLAGS_NO_BIDI_CLOSURE = 0x00000800u, #ifdef HB_EXPERIMENTAL_API HB_SUBSET_FLAGS_IFTB_REQUIREMENTS = 0x00001000u, + HB_SUBSET_FLAGS_RETAIN_NUM_GLYPHS = 0x00002000u, #endif } hb_subset_flags_t; diff --git a/thirdparty/harfbuzz/src/hb-subset.hh b/thirdparty/harfbuzz/src/hb-subset.hh index 4f192aae406..fca378de173 100644 --- a/thirdparty/harfbuzz/src/hb-subset.hh +++ b/thirdparty/harfbuzz/src/hb-subset.hh @@ -70,5 +70,4 @@ struct hb_subset_context_t : table_tag (table_tag_) {} }; - #endif /* HB_SUBSET_HH */ diff --git a/thirdparty/harfbuzz/src/hb-ucd-table.hh b/thirdparty/harfbuzz/src/hb-ucd-table.hh index 9c0bfe56b27..868428ab1e7 100644 --- a/thirdparty/harfbuzz/src/hb-ucd-table.hh +++ b/thirdparty/harfbuzz/src/hb-ucd-table.hh @@ -4,7 +4,7 @@ * * ./gen-ucd-table.py ucd.nounihan.grouped.xml hb-script-list.h * - * on file with this description: Unicode 16.0.0 + * on file with this description: Unicode 17.0.0 */ #ifndef HB_UCD_TABLE_HH @@ -14,7 +14,7 @@ #include -static const hb_script_t _hb_ucd_sc_map[172]= +static const hb_script_t _hb_ucd_sc_map[176]= { HB_SCRIPT_COMMON, HB_SCRIPT_INHERITED, HB_SCRIPT_UNKNOWN, HB_SCRIPT_ARABIC, @@ -102,6 +102,8 @@ static const hb_script_t _hb_ucd_sc_map[172]= HB_SCRIPT_GURUNG_KHEMA, HB_SCRIPT_KIRAT_RAI, HB_SCRIPT_OL_ONAL, HB_SCRIPT_SUNUWAR, HB_SCRIPT_TODHRI, HB_SCRIPT_TULU_TIGALARI, + HB_SCRIPT_BERIA_ERFE, HB_SCRIPT_SIDETIC, + HB_SCRIPT_TAI_YO, HB_SCRIPT_TOLONG_SIKI, }; static const uint16_t _hb_ucd_dm1_p0_map[825]= { @@ -761,59 +763,144 @@ static const uint64_t _hb_ucd_dm2_u64_map[408]= #include -static const uint8_t _hb_ucd_u8[17612]= +static const uint8_t _hb_ucd_u8[19868]= { - 0, 1, 2, 3, 4, 5, 5, 5, 5, 5, 6, 5, 5, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 5, 17, 15, 18, 19, 20, 21, 22, 23, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 24, 25, 26, 5, 27, 28, - 5, 29, 30, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 31, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 32, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 33, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 17, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, - 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 33, 41, 42, 43, 44, 45, - 46, 47, 48, 39, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 49, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 50, 17, 17, 17, 51, 17, 52, 53, 54, 55, 56, 57, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 58, 59, 59, 59, 59, 59, 59, 59, 59, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 17, 61, 62, 17, 63, 64, 65, - 66, 67, 68, 69, 70, 71, 17, 72, 73, 74, 75, 76, 77, 78, 79, 80, - 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, - 17, 17, 17, 97, 98, 99,100,100,100,100,100,100,100,100,100,101, - 17, 17, 17, 17,102, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17,103, 17, 17,104,100,100,100,100,100,100,100,100,100, - 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, - 100,105,100,100,100,100,100,100, 17, 17,106,107,100,108,109,110, - 17, 17, 17, 17, 17, 17, 17,111, 17, 17, 17, 17,112,113,100,100, - 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,114, - 17,115,116,100,100,100,100,100,100,100,100,100,117,100,100,100, - 100,100,100,100,100,100,100,100,100,100,100,100,118, 39,119,120, - 121,122,123,124,125,126,127,128, 39, 39,129,100,100,100,100,130, - 131,132,133,100,134,135,100,136,137,138,100,100,139,140,141,100, - 142,143,144,145, 39, 39,146,147,148, 39,149,150,100,100,100,100, - 17, 17, 17, 17, 17, 17,151, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17,152,153, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,154, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,155, 17, 17,156,100, - 100,100,100,100,100,100,100,100, 17, 17,157,100,100,100,100,100, - 17, 17, 17,158, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17,159,100,100,100,100,100,100,100,100,100,100,100,100, - 160,161,100,100,100,100,100,100,100,100,100,100,100,100,100,100, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,162, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,163, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 27, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 28, 26, 29, 30, 31, 32, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 33, 34, 34, 34, 34, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + 26, 56, 57, 58, 58, 58, 58, 59, 26, 26, 60, 26, 26, 26, 26, 26, + 26, 61, 26, 62, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 63, 58, 58, 58, 26, 64, 65, 66, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 67, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 68, 69, 70, 58, 58, 58, 58, 71, 58, + 58, 58, 58, 58, 58, 58, 72, 73, 74, 75, 76, 77, 78, 79, 58, 80, + 81, 82, 83, 84, 85, 58, 86, 87, 88, 89, 78, 90, 91, 92, 58, 58, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 93, 26, 26, 26, 26, 26, 26, 26, 26, 94, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 95, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 96, 26, 97, 58, 58, 58, 58, 26, 98, 58, 58, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 99, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,100, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 101, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,102, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,103, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 2, 4, 5, 6, 2, 7, 7, 7, 7, 7, 2, 8, 9, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, @@ -827,496 +914,529 @@ static const uint8_t _hb_ucd_u8[17612]= 34, 11, 34, 34, 32, 35, 32, 16, 36, 36, 37, 34, 38, 37, 34, 34, 34, 34, 34, 34, 34, 34, 16, 32, 34, 38, 32, 11, 32, 32, 32, 32, 32, 32, 16, 16, 16, 11, 34, 32, 34, 34, 11, 32, 32, 32, 32, 32, - 16, 16, 39, 16, 16, 16, 16, 16, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 41, 41, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, - 40, 40, 42, 41, 41, 41, 42, 42, 41, 41, 41, 41, 41, 41, 41, 41, - 43, 43, 43, 43, 43, 43, 43, 43, 32, 32, 42, 32, 44, 45, 16, 10, - 44, 44, 41, 46, 11, 47, 47, 11, 34, 11, 11, 11, 11, 11, 11, 11, - 11, 48, 11, 11, 11, 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 34, - 16, 11, 32, 16, 32, 32, 32, 32, 16, 16, 32, 49, 34, 32, 34, 11, - 32, 50, 43, 43, 51, 32, 32, 32, 11, 34, 34, 34, 34, 34, 34, 16, - 48, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 47, 52, 2, 2, 2, - 16, 16, 16, 16, 53, 54, 55, 56, 57, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 58, 59, 60, 43, 59, 44, 44, 44, 44, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 61, 44, 62, - 36, 63, 64, 44, 44, 44, 44, 44, 65, 65, 65, 8, 9, 66, 2, 67, - 43, 43, 43, 43, 43, 60, 68, 2, 69, 36, 36, 36, 36, 70, 43, 43, - 7, 7, 7, 7, 7, 2, 2, 36, 71, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 72, 43, 43, 43, 73, 50, 43, 43, 74, 75, 76, 43, 43, 36, - 7, 7, 7, 7, 7, 36, 77, 78, 2, 2, 2, 2, 2, 2, 2, 79, - 70, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, 43, 43, 80, 62, 36, - 36, 36, 36, 43, 43, 43, 43, 43, 71, 44, 44, 44, 44, 44, 44, 44, - 7, 7, 7, 7, 7, 36, 36, 36, 36, 36, 36, 36, 36, 70, 43, 43, - 43, 43, 40, 21, 2, 81, 57, 20, 36, 36, 36, 43, 43, 75, 43, 43, - 43, 43, 75, 43, 75, 43, 43, 44, 2, 2, 2, 2, 2, 2, 2, 64, - 36, 36, 36, 36, 70, 43, 44, 64, 36, 36, 36, 36, 36, 61, 44, 44, - 36, 36, 36, 36, 82, 36, 36, 61, 65, 44, 44, 57, 43, 43, 43, 43, - 36, 36, 36, 36, 83, 43, 43, 43, 43, 84, 43, 43, 43, 43, 43, 43, - 43, 85, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 85, 71, 86, - 87, 43, 43, 43, 85, 86, 87, 86, 70, 43, 43, 43, 36, 36, 36, 36, - 36, 43, 2, 7, 7, 7, 7, 7, 88, 36, 36, 36, 36, 36, 36, 36, - 70, 86, 62, 36, 36, 36, 61, 62, 61, 62, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 61, 36, 36, 36, 61, 61, 44, 36, 36, 44, 71, 86, - 87, 43, 80, 89, 90, 89, 87, 61, 44, 44, 44, 89, 44, 44, 36, 62, - 36, 43, 44, 7, 7, 7, 7, 7, 36, 20, 27, 27, 27, 56, 63, 80, - 57, 85, 62, 36, 36, 61, 44, 62, 61, 36, 62, 61, 36, 44, 80, 86, - 87, 80, 44, 57, 80, 57, 43, 44, 57, 44, 44, 44, 62, 36, 61, 61, - 44, 44, 44, 7, 7, 7, 7, 7, 43, 36, 70, 64, 44, 44, 44, 44, - 57, 85, 62, 36, 36, 36, 36, 62, 36, 62, 36, 36, 36, 36, 36, 36, - 61, 36, 62, 36, 36, 44, 71, 86, 87, 43, 43, 57, 85, 89, 87, 44, - 61, 44, 44, 44, 44, 44, 44, 44, 66, 44, 44, 44, 62, 43, 43, 43, - 57, 86, 62, 36, 36, 36, 61, 62, 61, 36, 62, 36, 36, 44, 71, 87, - 87, 43, 80, 89, 90, 89, 87, 44, 44, 44, 57, 85, 44, 44, 36, 62, - 78, 27, 27, 27, 44, 44, 44, 44, 44, 71, 62, 36, 36, 61, 44, 36, - 61, 36, 36, 44, 62, 61, 61, 36, 44, 62, 61, 44, 36, 61, 44, 36, - 36, 36, 36, 36, 36, 44, 44, 86, 85, 90, 44, 86, 90, 86, 87, 44, - 61, 44, 44, 89, 44, 44, 44, 44, 27, 91, 67, 67, 56, 92, 44, 44, - 85, 86, 71, 36, 36, 36, 61, 36, 61, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 44, 71, 43, 85, 86, 90, 43, 80, 43, 43, 44, - 44, 44, 57, 80, 36, 61, 62, 44, 44, 44, 44, 93, 27, 27, 27, 91, - 70, 86, 72, 36, 36, 36, 61, 36, 36, 36, 62, 36, 36, 44, 71, 87, - 86, 86, 90, 85, 90, 86, 43, 44, 44, 44, 89, 90, 44, 44, 62, 61, - 62, 94, 44, 44, 44, 44, 44, 44, 43, 86, 36, 36, 36, 36, 61, 36, - 36, 36, 36, 36, 36, 70, 71, 86, 87, 43, 80, 86, 90, 86, 87, 77, - 44, 44, 36, 94, 27, 27, 27, 95, 27, 27, 27, 27, 91, 36, 36, 36, - 57, 86, 62, 36, 36, 36, 36, 36, 36, 36, 36, 61, 44, 36, 36, 36, - 36, 62, 36, 36, 36, 36, 62, 44, 36, 36, 36, 61, 44, 80, 44, 89, - 86, 43, 80, 80, 86, 86, 86, 86, 44, 86, 64, 44, 44, 44, 44, 44, - 62, 36, 36, 36, 36, 36, 36, 36, 70, 36, 43, 43, 43, 80, 44, 96, - 36, 36, 36, 75, 43, 43, 43, 60, 7, 7, 7, 7, 7, 2, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 62, 61, 61, 36, 36, 61, 36, 36, - 36, 36, 62, 62, 36, 36, 36, 36, 70, 36, 43, 43, 43, 43, 71, 44, - 36, 36, 61, 81, 43, 43, 43, 80, 7, 7, 7, 7, 7, 44, 36, 36, - 77, 67, 2, 2, 2, 2, 2, 2, 2, 97, 97, 67, 43, 67, 67, 67, - 7, 7, 7, 7, 7, 27, 27, 27, 27, 27, 50, 50, 50, 4, 4, 86, - 36, 36, 36, 36, 62, 36, 36, 36, 36, 36, 36, 36, 36, 36, 61, 44, - 57, 43, 43, 43, 43, 43, 43, 85, 43, 43, 60, 43, 36, 36, 70, 43, - 43, 43, 43, 43, 57, 43, 43, 43, 43, 43, 43, 43, 43, 43, 80, 67, - 67, 67, 67, 76, 67, 67, 92, 67, 2, 2, 97, 67, 21, 64, 44, 44, - 36, 36, 36, 36, 36, 94, 87, 43, 85, 43, 43, 43, 87, 85, 87, 71, - 7, 7, 7, 7, 7, 2, 2, 2, 36, 36, 36, 86, 43, 36, 36, 43, - 71, 86, 98, 94, 86, 86, 86, 36, 70, 43, 71, 36, 36, 36, 36, 36, - 36, 85, 87, 85, 86, 86, 87, 94, 7, 7, 7, 7, 7, 86, 87, 67, - 11, 11, 11, 48, 44, 44, 48, 44, 16, 16, 16, 16, 16, 53, 45, 16, - 36, 36, 36, 36, 61, 36, 36, 44, 36, 36, 36, 61, 61, 36, 36, 44, - 61, 36, 36, 44, 36, 36, 36, 61, 61, 36, 36, 44, 36, 36, 36, 36, - 36, 36, 36, 61, 36, 36, 36, 36, 36, 36, 36, 36, 36, 61, 57, 43, - 2, 2, 2, 2, 99, 27, 27, 27, 27, 27, 27, 27, 27, 27,100, 44, - 67, 67, 67, 67, 67, 44, 44, 44, 11, 11, 11, 44, 16, 16, 16, 44, - 101, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 77, 72, - 102, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,103,104, 44, - 36, 36, 36, 36, 36, 63, 2,105,106, 36, 36, 36, 61, 44, 44, 44, - 36, 43, 85, 44, 44, 44, 44, 62, 36, 43,107, 64, 44, 44, 44, 44, - 36, 43, 44, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 61, 36, - 61, 43, 44, 44, 44, 44, 44, 44, 36, 36, 43, 87, 43, 43, 43, 86, - 86, 86, 86, 85, 87, 43, 43, 43, 43, 43, 2, 88, 2, 66, 70, 44, - 7, 7, 7, 7, 7, 44, 44, 44, 27, 27, 27, 27, 27, 44, 44, 44, - 2, 2, 2,108, 2, 59, 43, 84, 36, 83, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 61, 44, 44, 44, 36, 36, 70, 71, 36, 36, 36, 36, - 36, 36, 36, 36, 70, 61, 44, 44, 36, 36, 36, 44, 44, 44, 44, 44, - 36, 36, 36, 36, 36, 36, 36, 61, 43, 85, 86, 87, 85, 86, 44, 44, - 86, 85, 86, 86, 87, 43, 44, 44, 92, 44, 2, 7, 7, 7, 7, 7, - 36, 36, 36, 36, 36, 36, 36, 44, 36, 36, 61, 44, 44, 44, 44, 44, - 36, 36, 36, 36, 36, 36, 44, 44, 36, 36, 36, 36, 36, 44, 44, 44, - 7, 7, 7, 7, 7,100, 44, 67, 67, 67, 67, 67, 67, 67, 67, 67, - 36, 36, 36, 70, 85, 87, 44, 2, 36, 36, 94, 85, 43, 43, 43, 80, - 85, 85, 87, 43, 43, 43, 85, 86, 86, 87, 43, 43, 43, 43, 80, 57, - 2, 2, 2, 88, 2, 2, 2, 44, 43, 43, 43, 43, 43, 43, 43,109, - 43, 43, 43, 43, 43, 43, 43, 80, 43, 43, 98, 36, 36, 36, 36, 36, - 36, 36, 85, 43, 43, 85, 85, 86, 86, 85, 98, 36, 36, 36, 61, 2, - 97, 67, 67, 67, 67, 50, 43, 43, 43, 43, 67, 67, 67, 67, 21, 2, - 43, 98, 36, 36, 36, 36, 36, 36, 94, 43, 43, 86, 43, 87, 43, 36, - 36, 36, 36, 85, 43, 86, 87, 87, 43, 86, 44, 44, 44, 44, 2, 2, - 36, 36, 86, 86, 86, 86, 43, 43, 43, 43, 86, 43, 44, 93, 2, 2, - 7, 7, 7, 7, 7, 44, 62, 36, 36, 36, 36, 36, 40, 40, 40, 2, - 16, 16, 16, 16, 34,110, 44, 44, 11, 11, 11, 11, 11, 47, 48, 11, - 2, 2, 2, 2, 44, 44, 44, 44, 43, 60, 43, 43, 43, 43, 43, 43, - 85, 43, 43, 43, 71, 36, 70, 36, 36, 36, 71, 94, 43, 61, 44, 44, - 16, 16, 16, 16, 16, 16, 40, 40, 40, 40, 40, 40, 40, 45, 16, 16, - 16, 16, 16, 16, 45, 16, 16, 16, 16, 16, 16, 16, 16,111, 40, 40, - 32, 32, 32, 16, 16, 16, 16, 32, 16, 16, 16, 16, 11, 11, 11, 11, - 16, 16, 16, 44, 11, 11, 11, 44, 16, 16, 16, 16, 48, 48, 48, 48, - 16, 16, 16, 16, 16, 16, 16, 44, 16, 16, 16, 16,112,112,112,112, - 16, 16,110, 16, 11, 11,113,114, 41, 16,110, 16, 11, 11,113, 41, - 16, 16, 44, 16, 11, 11,115, 41, 16, 16, 16, 16, 11, 11,116, 41, - 44, 16,110, 16, 11, 11,113,117,118,118,118,118,118,119, 65, 65, - 120,120,120, 2,121,122,121,122, 2, 2, 2, 2,123, 65, 65,124, - 2, 2, 2, 2,125,126, 2,127,128, 2,129,130, 2, 2, 2, 2, - 2, 9,128, 2, 2, 2, 2,131, 65, 65,132, 65, 65, 65, 65, 65, - 133, 44, 27, 27, 27, 8,129,134, 27, 27, 27, 27, 27, 8,129,104, - 40, 40, 40, 40, 40, 40, 81, 44, 20, 20, 20, 20, 20, 20, 20, 20, - 135, 44, 44, 44, 44, 44, 44, 44, 43, 43, 43, 43, 43, 43,136, 51, - 109, 51,109, 43, 43, 43, 43, 43, 80, 44, 44, 44, 44, 44, 44, 44, - 67,137, 67,138, 67, 34, 11, 16, 11, 32,138, 67, 49, 11, 11, 67, - 67, 67,137,137,137, 11, 11,139, 11, 11, 35, 36, 39, 67, 16, 11, - 8, 8, 49, 16, 16, 26, 67,140, 27, 27, 27, 27, 27, 27, 27, 27, - 105,105,105,105,105,105,105,105,105,141,142,105,143, 67, 44, 44, - 8, 8,144, 67, 67, 8, 67, 67,144, 26, 67,144, 67, 67, 67,144, - 67, 67, 67, 67, 67, 67, 67, 8, 67,144,144, 67, 67, 67, 67, 67, - 67, 67, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 67, 67, 67, 67, 4, 4, 67, 67, 8, 67, 67, 67,145,146, 67, 67, - 67, 67, 67, 67, 67, 67,144, 67, 67, 67, 67, 67, 67, 26, 8, 8, - 8, 8, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 8, 8, - 8, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 92, 44, 44, - 27, 27, 27, 27, 27, 27, 67, 67, 67, 67, 67, 67, 67, 27, 27, 27, - 67, 67, 67, 26, 67, 67, 67, 67, 26, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 8, 8, 8, 8, 67, 67, 67, 67, 67, 67, 67, 26, - 67, 67, 67, 67, 4, 4, 4, 4, 4, 4, 4, 27, 27, 27, 27, 27, - 27, 27, 67, 67, 67, 67, 67, 67, 8, 8,129,147, 8, 8, 8, 8, - 8, 8, 8, 4, 4, 4, 4, 4, 8,129,148,148,148,148,148,148, - 148,148,148,148,147, 8, 8, 8, 8, 8, 8, 8, 4, 4, 8, 8, - 8, 8, 8, 8, 8, 8, 4, 8, 8, 8,144, 26, 8, 8,144, 67, - 67, 67, 44, 67, 67, 67, 67, 67, 67, 67, 67, 55, 67, 67, 67, 67, - 32, 11, 32, 34, 34, 34, 34, 11, 32, 32, 34, 16, 16, 16, 40, 11, - 32, 32,140, 67, 67,138, 34,149, 43, 32, 44, 44, 93, 2, 99, 2, - 16, 16, 16,150, 44, 44,150, 44, 36, 36, 36, 36, 44, 44, 44, 52, - 64, 44, 44, 44, 44, 44, 44, 57, 36, 36, 36, 61, 44, 44, 44, 44, - 36, 36, 36, 61, 36, 36, 36, 61, 2,121,121, 2,125,126,121, 2, - 2, 2, 2, 6, 2,108,121, 2,121, 4, 4, 4, 4, 2, 2, 88, - 2, 2, 2, 2, 2,120, 2, 2,108,151, 2, 2, 2, 2, 2, 2, - 67, 2,152,148,148,148,153, 44, 67, 67, 67, 67, 67, 55, 67, 67, - 67, 67, 44, 44, 44, 44, 44, 44, 67, 67, 67, 44, 44, 44, 44, 44, - 1, 2,154,155, 4, 4, 4, 4, 4, 67, 4, 4, 4, 4,156,157, - 158,105,105,105,105, 43, 43, 86,159, 40, 40, 67,105,160, 63, 67, - 36, 36, 36, 61, 57,161,162, 69, 36, 36, 36, 36, 36, 63, 40, 69, - 44, 44, 62, 36, 36, 36, 36, 36, 67, 27, 27, 67, 67, 67, 67, 67, - 67, 67, 67, 44, 44, 44, 44, 55, 67, 67, 67, 67, 67, 67, 67, 92, - 27, 27, 27, 27, 27, 67, 67, 67, 67, 67, 67, 67, 27, 27, 27, 27, - 163, 27, 27, 27, 27, 27, 27, 27, 36, 36, 83, 36, 36, 36, 36, 36, - 67, 67, 67, 92, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36,164, 2, - 7, 7, 7, 7, 7, 36, 44, 44, 32, 32, 32, 32, 32, 32, 32, 70, - 51,165, 43, 43, 43, 43, 43, 88, 32, 32, 32, 32, 32, 32, 40, 43, - 36, 36, 36,105,105,105,105,105, 43, 2, 2, 2, 44, 44, 44, 44, - 41, 41, 41,162, 40, 40, 40, 40, 41, 32, 32, 32, 32, 32, 32, 32, - 16, 32, 32, 32, 32, 32, 32, 32, 45, 16, 16, 16, 34, 34, 34, 32, - 32, 32, 32, 32, 42,166, 34, 35, 32, 32, 16, 32, 32, 32, 32, 32, + 16, 16, 36, 16, 16, 16, 16, 16, 39, 39, 39, 39, 39, 39, 39, 39, + 39, 40, 40, 39, 39, 39, 39, 39, 39, 40, 40, 40, 40, 40, 40, 40, + 39, 39, 41, 40, 40, 40, 41, 41, 40, 40, 40, 40, 40, 40, 40, 40, + 42, 42, 42, 42, 42, 42, 42, 42, 32, 32, 41, 32, 43, 44, 16, 10, + 43, 43, 40, 45, 11, 46, 46, 11, 34, 11, 11, 11, 11, 11, 11, 11, + 11, 47, 11, 11, 11, 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 34, + 16, 11, 32, 16, 32, 32, 32, 32, 16, 16, 32, 48, 34, 32, 34, 11, + 32, 49, 42, 42, 50, 32, 32, 32, 11, 34, 34, 34, 34, 34, 34, 16, + 47, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 46, 51, 2, 2, 2, + 16, 16, 16, 16, 52, 53, 54, 55, 56, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 57, 58, 59, 42, 58, 43, 43, 43, 43, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 60, 43, 61, + 36, 62, 63, 43, 43, 43, 43, 43, 64, 64, 64, 8, 9, 65, 2, 66, + 42, 42, 42, 42, 42, 59, 67, 2, 68, 36, 36, 36, 36, 69, 42, 42, + 7, 7, 7, 7, 7, 2, 2, 36, 70, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 71, 42, 42, 42, 72, 49, 42, 42, 73, 74, 75, 42, 42, 36, + 7, 7, 7, 7, 7, 36, 76, 77, 2, 2, 2, 2, 2, 2, 2, 78, + 69, 36, 36, 36, 36, 36, 36, 36, 42, 42, 42, 42, 42, 79, 61, 36, + 36, 36, 36, 42, 42, 42, 42, 42, 70, 43, 43, 43, 43, 43, 43, 43, + 7, 7, 7, 7, 7, 36, 36, 36, 36, 36, 36, 36, 36, 69, 42, 42, + 42, 42, 39, 21, 2, 80, 56, 20, 36, 36, 36, 42, 42, 74, 42, 42, + 42, 42, 74, 42, 74, 42, 42, 43, 2, 2, 2, 2, 2, 2, 2, 63, + 36, 36, 36, 36, 69, 42, 43, 63, 36, 36, 36, 36, 36, 60, 43, 43, + 36, 36, 36, 36, 81, 36, 36, 36, 64, 43, 43, 56, 42, 42, 42, 42, + 36, 36, 36, 36, 82, 42, 42, 42, 42, 83, 42, 42, 42, 42, 42, 42, + 42, 84, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 84, 70, 85, + 86, 42, 42, 42, 84, 85, 86, 85, 69, 42, 42, 42, 36, 36, 36, 36, + 36, 42, 2, 7, 7, 7, 7, 7, 87, 36, 36, 36, 36, 36, 36, 36, + 69, 85, 61, 36, 36, 36, 60, 61, 60, 61, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 60, 36, 36, 36, 60, 60, 43, 36, 36, 43, 70, 85, + 86, 42, 79, 88, 89, 88, 86, 60, 43, 43, 43, 88, 43, 43, 36, 61, + 36, 42, 43, 7, 7, 7, 7, 7, 36, 20, 27, 27, 27, 55, 62, 79, + 56, 84, 61, 36, 36, 60, 43, 61, 60, 36, 61, 60, 36, 43, 79, 85, + 86, 79, 43, 56, 79, 56, 42, 43, 56, 43, 43, 43, 61, 36, 60, 60, + 43, 43, 43, 7, 7, 7, 7, 7, 42, 36, 69, 63, 43, 43, 43, 43, + 56, 84, 61, 36, 36, 36, 36, 61, 36, 61, 36, 36, 36, 36, 36, 36, + 60, 36, 61, 36, 36, 43, 70, 85, 86, 42, 42, 56, 84, 88, 86, 43, + 60, 43, 43, 43, 43, 43, 43, 43, 65, 43, 43, 43, 61, 42, 42, 42, + 56, 85, 61, 36, 36, 36, 60, 61, 60, 36, 61, 36, 36, 43, 70, 86, + 86, 42, 79, 88, 89, 88, 86, 43, 43, 43, 56, 84, 43, 43, 36, 61, + 77, 27, 27, 27, 43, 43, 43, 43, 43, 70, 61, 36, 36, 60, 43, 36, + 60, 36, 36, 43, 61, 60, 60, 36, 43, 61, 60, 43, 36, 60, 43, 36, + 36, 36, 36, 36, 36, 43, 43, 85, 84, 89, 43, 85, 89, 85, 86, 43, + 60, 43, 43, 88, 43, 43, 43, 43, 27, 90, 66, 66, 55, 91, 43, 43, + 84, 85, 70, 36, 36, 36, 60, 36, 60, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 43, 70, 42, 84, 85, 89, 42, 79, 42, 42, 43, + 43, 43, 56, 79, 36, 60, 36, 43, 43, 43, 43, 92, 27, 27, 27, 90, + 69, 85, 71, 36, 36, 36, 60, 36, 36, 36, 61, 36, 36, 43, 70, 86, + 85, 85, 89, 84, 89, 85, 42, 43, 43, 43, 88, 89, 43, 43, 36, 60, + 61, 93, 43, 43, 43, 43, 43, 43, 42, 85, 36, 36, 36, 36, 60, 36, + 36, 36, 36, 36, 36, 69, 70, 85, 86, 42, 79, 85, 89, 85, 86, 76, + 43, 43, 36, 93, 27, 27, 27, 94, 27, 27, 27, 27, 90, 36, 36, 36, + 56, 85, 61, 36, 36, 36, 36, 36, 36, 36, 36, 60, 43, 36, 36, 36, + 36, 61, 36, 36, 36, 36, 61, 43, 36, 36, 36, 60, 43, 79, 43, 88, + 85, 42, 79, 79, 85, 85, 85, 85, 43, 85, 63, 43, 43, 43, 43, 43, + 61, 36, 36, 36, 36, 36, 36, 36, 69, 36, 42, 42, 42, 79, 43, 95, + 36, 36, 36, 74, 42, 42, 42, 59, 7, 7, 7, 7, 7, 2, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 43, 61, 60, 60, 36, 36, 60, 36, 36, + 36, 36, 61, 61, 36, 36, 36, 36, 69, 36, 42, 42, 42, 42, 70, 43, + 36, 36, 60, 80, 42, 42, 42, 79, 7, 7, 7, 7, 7, 43, 36, 36, + 76, 66, 2, 2, 2, 2, 2, 2, 2, 96, 96, 66, 42, 66, 66, 66, + 7, 7, 7, 7, 7, 27, 27, 27, 27, 27, 49, 49, 49, 4, 4, 85, + 36, 36, 36, 36, 61, 36, 36, 36, 36, 36, 36, 36, 36, 36, 60, 43, + 56, 42, 42, 42, 42, 42, 42, 84, 42, 42, 59, 42, 36, 36, 69, 42, + 42, 42, 42, 42, 56, 42, 42, 42, 42, 42, 42, 42, 42, 42, 79, 66, + 66, 66, 66, 75, 66, 66, 91, 66, 2, 2, 96, 66, 21, 63, 43, 43, + 36, 36, 36, 36, 36, 93, 86, 42, 84, 42, 42, 42, 86, 84, 86, 70, + 7, 7, 7, 7, 7, 2, 2, 2, 36, 36, 36, 85, 42, 36, 36, 42, + 70, 85, 97, 93, 85, 85, 85, 36, 69, 42, 70, 36, 36, 36, 36, 36, + 36, 84, 86, 84, 85, 85, 86, 93, 7, 7, 7, 7, 7, 85, 86, 66, + 11, 11, 11, 47, 43, 43, 47, 43, 16, 16, 16, 16, 16, 52, 44, 16, + 36, 36, 36, 36, 60, 36, 36, 43, 36, 36, 36, 60, 60, 36, 36, 43, + 60, 36, 36, 43, 36, 36, 36, 60, 60, 36, 36, 43, 36, 36, 36, 36, + 36, 36, 36, 60, 36, 36, 36, 36, 36, 36, 36, 36, 36, 60, 56, 42, + 2, 2, 2, 2, 98, 27, 27, 27, 27, 27, 27, 27, 27, 27, 99, 43, + 66, 66, 66, 66, 66, 43, 43, 43, 11, 11, 11, 43, 16, 16, 16, 43, + 100, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 76, 71, + 101, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,102,103, 43, + 36, 36, 36, 36, 36, 62, 2,104,105, 36, 36, 36, 60, 43, 43, 43, + 36, 42, 84, 43, 43, 43, 43, 61, 36, 42,106, 63, 43, 43, 43, 43, + 36, 42, 43, 43, 43, 43, 43, 43, 36, 36, 36, 36, 36, 36, 60, 36, + 60, 42, 43, 43, 43, 43, 43, 43, 36, 36, 42, 86, 42, 42, 42, 85, + 85, 85, 85, 84, 86, 42, 42, 42, 42, 42, 2, 87, 2, 65, 69, 43, + 7, 7, 7, 7, 7, 43, 43, 43, 27, 27, 27, 27, 27, 43, 43, 43, + 2, 2, 2,107, 2, 58, 42, 83, 36, 82, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 60, 43, 43, 43, 36, 36, 69, 70, 36, 36, 36, 36, + 36, 36, 36, 36, 69, 60, 43, 43, 36, 36, 36, 43, 43, 43, 43, 43, + 36, 36, 36, 36, 36, 36, 36, 60, 42, 84, 85, 86, 84, 85, 43, 43, + 85, 84, 85, 85, 86, 42, 43, 43, 91, 43, 2, 7, 7, 7, 7, 7, + 36, 36, 36, 36, 36, 36, 36, 43, 36, 36, 60, 43, 43, 43, 43, 43, + 36, 36, 36, 36, 36, 36, 43, 43, 36, 36, 36, 36, 36, 43, 43, 43, + 7, 7, 7, 7, 7, 99, 43, 66, 66, 66, 66, 66, 66, 66, 66, 66, + 36, 36, 36, 69, 84, 86, 43, 2, 36, 36, 93, 84, 42, 42, 42, 79, + 84, 84, 86, 42, 42, 42, 84, 85, 85, 86, 42, 42, 42, 42, 79, 56, + 2, 2, 2, 87, 2, 2, 2, 43, 42, 42, 42, 42, 42, 42, 42,108, + 42, 42, 42, 42, 42, 42, 42, 43, 42, 42, 42, 42, 42, 42, 43, 43, + 42, 42, 97, 36, 36, 36, 36, 36, 36, 36, 84, 42, 42, 84, 84, 85, + 85, 84, 97, 36, 36, 36, 60, 2, 96, 66, 66, 66, 66, 49, 42, 42, + 42, 42, 66, 66, 66, 66, 21, 2, 42, 97, 36, 36, 36, 36, 36, 36, + 93, 42, 42, 85, 42, 86, 42, 36, 36, 36, 36, 84, 42, 85, 86, 86, + 42, 85, 43, 43, 43, 43, 2, 2, 36, 36, 85, 85, 85, 85, 42, 42, + 42, 42, 85, 42, 43, 92, 2, 2, 7, 7, 7, 7, 7, 43, 61, 36, + 36, 36, 36, 36, 39, 39, 39, 2, 16, 16, 16, 16, 34,109, 43, 43, + 11, 11, 11, 11, 11, 46, 47, 11, 2, 2, 2, 2, 43, 43, 43, 43, + 42, 59, 42, 42, 42, 42, 42, 42, 84, 42, 42, 42, 70, 36, 69, 36, + 36, 36, 70, 93, 42, 60, 43, 43, 16, 16, 16, 16, 16, 16, 39, 39, + 39, 39, 39, 39, 39, 44, 16, 16, 16, 16, 16, 16, 44, 16, 16, 16, + 16, 16, 16, 16, 16,110, 39, 39, 32, 32, 32, 16, 16, 16, 16, 32, + 16, 16, 16, 16, 11, 11, 11, 11, 16, 16, 16, 43, 11, 11, 11, 43, + 16, 16, 16, 16, 47, 47, 47, 47, 16, 16, 16, 16, 16, 16, 16, 43, + 16, 16, 16, 16,111,111,111,111, 16, 16,109, 16, 11, 11,112,113, + 40, 16,109, 16, 11, 11,112, 40, 16, 16, 43, 16, 11, 11,114, 40, + 16, 16, 16, 16, 11, 11,115, 40, 43, 16,109, 16, 11, 11,112,116, + 117,117,117,117,117,118, 64, 64,119,119,119, 2,120,121,120,121, + 2, 2, 2, 2,122, 64, 64,123, 2, 2, 2, 2,124,125, 2,126, + 127, 2,128,129, 2, 2, 2, 2, 2, 9,127, 2, 2, 2, 2,130, + 64, 64,131, 64, 64, 64, 64, 64,132, 43, 27, 27, 27, 8,128,133, + 27, 27, 27, 27, 27, 8,128,103, 39, 39, 39, 39, 39, 39, 80, 43, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 43, 43, 43, 43, 43, 43, 43, + 42, 42, 42, 42, 42, 42,134, 50,108, 50,108, 42, 42, 42, 42, 42, + 79, 43, 43, 43, 43, 43, 43, 43, 66,135, 66,136, 66, 34, 11, 16, + 11, 32,136, 66, 48, 11, 11, 66, 66, 66,135,135,135, 11, 11,137, + 11, 11, 35, 36,138, 66, 16, 11, 8, 8, 48, 16, 16, 26, 66,139, + 27, 27, 27, 27, 27, 27, 27, 27,104,104,104,104,104,104,104,104, + 104,140,141,104,142, 66, 43, 43, 8, 8,143, 66, 66, 8, 66, 66, + 143, 26, 66,143, 66, 66, 66,143, 66, 66, 66, 66, 66, 66, 66, 8, + 66,143,143, 66, 66, 66, 66, 66, 66, 66, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 66, 66, 66, 66, 4, 4, 66, 66, + 8, 66, 66, 66,144,145, 66, 66, 66, 66, 66, 66, 66, 66,143, 66, + 66, 66, 66, 66, 66, 26, 8, 8, 8, 8, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 8, 8, 8, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 91, 43, 43, 27, 27, 27, 27, 27, 27, 66, 66, + 66, 66, 66, 66, 66, 27, 27, 27, 66, 66, 66, 26, 66, 66, 66, 66, + 26, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 8, 8, 8, 8, + 66, 66, 66, 66, 66, 66, 66, 26, 66, 66, 66, 66, 4, 4, 4, 4, + 4, 4, 4, 27, 27, 27, 27, 27, 27, 27, 66, 66, 66, 66, 66, 66, + 8, 8,128,146, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, + 8,128,147,147,147,147,147,147,147,147,147,147,146, 8, 8, 8, + 8, 8, 8, 8, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 4, 8, + 8, 8,143, 26, 8, 8,143, 66, 66, 66, 43, 66, 66, 66, 66, 66, + 32, 11, 32, 34, 34, 34, 34, 11, 32, 32, 34, 16, 16, 16, 39, 11, + 32, 32,139, 66, 66,136, 34,148, 42, 32, 43, 43, 92, 2, 98, 2, + 16, 16, 16,149, 43, 43,149, 43, 36, 36, 36, 36, 43, 43, 43, 51, + 63, 43, 43, 43, 43, 43, 43, 56, 36, 36, 36, 60, 43, 43, 43, 43, + 36, 36, 36, 60, 36, 36, 36, 60, 2,120,120, 2,124,125,120, 2, + 2, 2, 2, 6, 2,107,120, 2,120, 4, 4, 4, 4, 2, 2, 87, + 2, 2, 2, 2, 2,119, 2, 2,107,150, 2, 2, 2, 2, 2, 2, + 66, 2,151,147,147,147,152, 43, 66, 66, 66, 66, 66, 54, 66, 66, + 66, 66, 43, 43, 43, 43, 43, 43, 66, 66, 66, 43, 43, 43, 43, 43, + 1, 2,153,154, 4, 4, 4, 4, 4, 66, 4, 4, 4, 4,155,156, + 157,104,104,104,104, 42, 42, 85,158, 39, 39, 66,104,159, 62, 66, + 36, 36, 36, 60, 56,160,161, 68, 36, 36, 36, 36, 36, 62, 39, 68, + 43, 43, 61, 36, 36, 36, 36, 36, 66, 27, 27, 66, 66, 66, 66, 66, + 66, 66, 66, 43, 43, 43, 43, 54, 66, 66, 66, 66, 66, 66, 66, 91, + 27, 27, 27, 27, 27, 66, 66, 66, 66, 66, 66, 66, 27, 27, 27, 27, + 162, 27, 27, 27, 27, 27, 27, 27, 36, 36, 82, 36, 36, 36, 36, 36, + 66, 66, 66, 91, 43, 43, 43, 43, 36, 36, 36, 36, 36, 36,163, 2, + 7, 7, 7, 7, 7, 36, 43, 43, 32, 32, 32, 32, 32, 32, 32, 69, + 50,164, 42, 42, 42, 42, 42, 87, 32, 32, 32, 32, 32, 32, 39, 42, + 36, 36, 36,104,104,104,104,104, 42, 2, 2, 2, 43, 43, 43, 43, + 40, 40, 40,161, 39, 39, 39, 39, 40, 32, 32, 32, 32, 32, 32, 32, + 16, 32, 32, 32, 32, 32, 32, 32, 44, 16, 16, 16, 34, 34, 34, 32, + 32, 32, 32, 32, 41,165, 34, 35, 32, 32, 16, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 11, 11, 32, 11, 11, 32, 32, 32, 32, 32, 32, - 32, 32, 11, 11, 34, 34, 32, 44, 32,150,150, 32, 32, 32, 47, 44, - 44, 40,167, 35, 40, 35, 36, 36, 36, 71, 36, 71, 36, 70, 36, 36, - 36, 94, 87, 85, 67, 67, 80, 44, 27, 27, 27, 67,168, 44, 44, 44, - 36, 36, 2, 2, 44, 44, 44, 44, 86, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 86, 86, 86, 86, 86, 86, 86, 86, 43, 44, 44, 44, 44, 2, - 43, 36, 36, 36, 2, 72, 72, 70, 36, 36, 36, 43, 43, 43, 43, 2, - 36, 36, 36, 70, 43, 43, 43, 43, 43, 86, 44, 44, 44, 44, 44, 93, - 36, 70, 86, 43, 43, 86, 43, 86,107, 2, 2, 2, 2, 2, 2, 52, - 7, 7, 7, 7, 7, 44, 44, 2, 36, 36, 70, 69, 36, 36, 36, 36, - 7, 7, 7, 7, 7, 36, 36, 61, 36, 36, 36, 36, 70, 43, 43, 85, - 87, 85, 87, 80, 44, 44, 44, 44, 36, 70, 36, 36, 36, 36, 85, 44, - 7, 7, 7, 7, 7, 44, 2, 2, 69, 36, 36, 77, 67, 94, 85, 36, - 71, 43, 71, 70, 71, 36, 36, 43, 70, 61, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 62, 83, 2, 36, 36, 36, 36, 36, 94, 43, 86, - 2, 83,169, 80, 44, 44, 44, 44, 62, 36, 36, 61, 62, 36, 36, 61, - 62, 36, 36, 61, 44, 44, 44, 44, 16, 16, 16, 16, 16,114, 40, 40, - 16, 16, 16, 16,111, 41, 44, 44, 36, 94, 87, 86, 85,107, 87, 44, - 36, 36, 44, 44, 44, 44, 44, 44, 36, 36, 36, 61, 44, 62, 36, 36, - 170,170,170,170,170,170,170,170,171,171,171,171,171,171,171,171, - 16, 16, 16,110, 44, 44, 44, 44, 44,150, 16, 16, 44, 44, 62, 71, - 36, 36, 36, 36,172, 36, 36, 36, 36, 36, 36, 61, 36, 36, 61, 61, - 36, 62, 61, 36, 36, 36, 36, 36, 36, 41, 41, 41, 41, 41, 41, 41, - 41,117, 44, 44, 44, 44, 44, 44, 44, 62, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36,148, 44, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 44, 44, 44, 55, 36, 36, 36, 36, 36, 36,168, 67, - 2, 2, 2,152,130, 44, 44, 44, 6,173,174,148,148,148,148,148, - 148,148,130,152,130, 2,127,175, 2, 64, 2, 2,156,148,148,130, - 2,176, 8,177, 66, 2, 44, 44, 36, 36, 61, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 61, 79, 93, 2, 3, 2, 4, 5, 6, 2, - 16, 16, 16, 16, 16, 17, 18,129,130, 4, 2, 36, 36, 36, 36, 36, - 69, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 40, - 44, 36, 36, 36, 44, 36, 36, 36, 44, 36, 36, 36, 44, 36, 61, 44, - 20,178, 56,135, 26, 8,144, 92, 44, 44, 44, 44, 79, 65, 67, 44, - 36, 36, 36, 36, 36, 36, 62, 36, 36, 36, 36, 36, 36, 61, 36, 62, - 2, 64, 44,179, 27, 27, 27, 27, 27, 27, 44, 55, 67, 67, 67, 67, - 105,105,143, 27, 91, 67, 67, 67, 67, 67, 67, 67, 67, 27, 67, 92, - 67, 67, 67, 67, 67, 67, 92, 44, 92, 44, 44, 44, 44, 44, 44, 44, - 67, 67, 67, 67, 67, 67, 50, 44,180, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 44, 44, 27, 27, 44, 44, 44, 44, 62, 36, - 155, 36, 36, 36, 36,181, 44, 44, 36, 36, 36, 43, 43, 80, 44, 44, - 36, 36, 36, 36, 36, 36, 36, 93, 36, 36, 44, 44, 36, 36, 36, 36, - 182,105,105, 44, 44, 44, 44, 44, 11, 11, 11, 11, 16, 16, 16, 16, - 11, 11, 44, 44, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 44, 44, - 36, 36, 36, 36, 44, 44, 44, 44, 36, 36, 44, 44, 44, 44, 44, 93, - 11, 11, 11, 11, 11, 47, 11, 11, 11, 47, 11,150, 16, 16, 16, 16, - 16,150, 16, 16, 16, 16, 16, 16, 16,150, 16, 16, 16,150,110, 44, - 40, 40, 40, 52, 40, 40, 40, 40, 81, 40, 40, 40, 40, 81, 44, 44, - 36, 36, 36, 44, 61, 36, 36, 36, 36, 36, 36, 62, 61, 44, 61, 62, - 36, 36, 36, 93, 27, 27, 27, 27, 36, 36, 36, 77,163, 27, 27, 27, - 44, 44, 44,179, 27, 27, 27, 27, 36, 61, 36, 44, 44,179, 27, 27, - 36, 36, 36, 27, 27, 27, 44, 93, 36, 36, 36, 36, 36, 44, 44, 93, - 36, 36, 36, 36, 44, 44, 27, 36, 44, 27, 27, 27, 27, 27, 27, 27, - 70, 43, 57, 80, 44, 44, 43, 43, 36, 36, 62, 36, 62, 36, 36, 36, - 36, 36, 36, 44, 43, 80, 44, 57, 27, 27, 27, 27,100, 44, 44, 44, - 2, 2, 2, 2, 64, 44, 44, 44, 36, 36, 36, 36, 36, 36,183, 30, - 36, 36, 36, 36, 36, 36,183, 27, 36, 36, 36, 36, 78, 36, 36, 36, - 36, 36, 70, 80, 44,179, 27, 27, 2, 2, 2, 64, 44, 44, 44, 44, - 36, 36, 36, 44, 93, 2, 2, 2, 36, 36, 36, 44, 27, 27, 27, 27, - 36, 61, 44, 44, 27, 27, 27, 27, 36, 44, 44, 44, 93, 2, 64, 44, - 44, 44, 44, 44,179, 27, 27, 27, 11, 47, 44, 44, 44, 44, 44, 44, - 16,110, 44, 44, 44, 27, 27, 27, 36, 36, 43, 43, 44, 44, 44, 44, - 7, 7, 7, 7, 7, 36, 36, 69, 11, 11, 11, 44, 57, 43, 43,159, - 16, 16, 16, 44, 44, 44, 44, 8, 27, 27, 27, 27, 27, 27, 27,100, - 36, 36, 36, 36, 36, 57,184, 44, 36, 44, 44, 44, 44, 44, 44, 44, - 44, 36, 61, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 43, 43, - 27, 27, 27, 95, 44, 44, 44, 44,180, 27, 30, 2, 2, 44, 44, 44, - 36, 43, 43, 2, 2, 44, 44, 44, 36, 36,183, 27, 27, 27, 44, 44, - 87, 98, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, 43, - 43, 43, 43, 60, 2, 2, 2, 44, 27, 27, 27, 7, 7, 7, 7, 7, - 71, 70, 71, 44, 44, 44, 44, 57, 86, 87, 43, 85, 87, 60,185, 2, - 2, 80, 44, 44, 44, 44, 79, 44, 43, 71, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 70, 43, 43, 87, 43, 43, 43, 80, 7, 7, 7, 7, 7, - 2, 2, 94, 98, 44, 44, 44, 44, 36, 70, 2, 61, 44, 44, 44, 44, - 36, 94, 86, 43, 43, 43, 43, 85, 98, 36, 63, 2, 59, 43, 60, 87, - 7, 7, 7, 7, 7, 63, 63, 2,179, 27, 27, 27, 27, 27, 27, 27, - 27, 27,100, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 86, 87, - 43, 86, 85, 43, 2, 2, 2, 71, 70, 44, 44, 44, 44, 44, 44, 44, - 36, 36, 36, 61, 61, 36, 36, 62, 36, 36, 36, 36, 36, 36, 36, 62, - 36, 36, 36, 36, 63, 44, 44, 44, 36, 36, 36, 36, 36, 36, 36, 70, - 86, 87, 43, 43, 43, 80, 44, 44, 43, 86, 62, 36, 36, 36, 61, 62, - 61, 36, 62, 36, 36, 57, 71, 86, 85, 86, 90, 89, 90, 89, 86, 44, - 61, 44, 44, 89, 44, 44, 62, 36, 36, 86, 44, 43, 43, 43, 80, 44, - 43, 43, 80, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 62, 44, 61, - 36, 36, 36, 62, 86, 87, 43, 43, 80, 90, 89, 89, 86, 90, 86, 85, - 71, 71, 2, 93, 64, 44, 44, 44, 57, 80, 44, 44, 44, 44, 44, 44, - 36, 36, 94, 86, 43, 43, 43, 43, 86, 43, 85, 71, 36, 63, 2, 2, - 7, 7, 7, 7, 7, 2, 93, 71, 86, 87, 43, 43, 85, 85, 86, 87, - 85, 43, 36, 72, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 36, 94, - 86, 43, 43, 44, 86, 86, 43, 87, 60, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 36, 36, 43, 44, 86, 87, 43, 43, 43, 85, 87, 87, - 60, 2, 61, 44, 44, 44, 44, 44, 2, 2, 2, 2, 2, 2, 64, 44, - 36, 36, 36, 36, 36, 70, 87, 86, 43, 43, 43, 87, 63, 44, 44, 44, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 44, 44, 44, 44, 44, 44, - 36, 36, 36, 36, 36, 61, 57, 87, 86, 43, 43, 87, 43, 43, 44, 44, - 7, 7, 7, 7, 7, 27, 2, 97, 43, 43, 43, 43, 87, 60, 44, 44, - 27,100, 44, 44, 44, 44, 44, 62, 36, 36, 36, 61, 62, 44, 36, 36, - 36, 36, 62, 61, 36, 36, 36, 36, 86, 86, 86, 89, 90, 57, 85, 71, - 98, 87, 2, 64, 44, 44, 44, 44, 36, 36, 36, 36, 44, 36, 36, 36, - 94, 86, 43, 43, 44, 43, 86, 86, 71, 72, 90, 44, 44, 44, 44, 44, - 70, 43, 43, 43, 43, 71, 36, 36, 36, 70, 43, 43, 85, 70, 43, 60, - 2, 2, 2, 59, 44, 44, 44, 44, 70, 43, 43, 85, 87, 43, 36, 36, - 36, 36, 36, 36, 36, 43, 43, 43, 43, 43, 43, 85, 43, 2, 72, 2, - 2, 64, 44, 44, 44, 44, 44, 44, 2, 2, 2, 2, 2, 44, 44, 44, - 63, 44, 44, 44, 44, 44, 44, 44, 43, 43, 43, 80, 43, 43, 43, 87, - 63, 2, 2, 44, 44, 44, 44, 44, 2, 36, 36, 36, 36, 36, 36, 36, - 44, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 89, 43, 43, 43, - 85, 43, 87, 80, 44, 44, 44, 44, 36, 36, 36, 61, 36, 62, 36, 36, - 70, 43, 43, 80, 44, 80, 43, 57, 43, 43, 43, 70, 44, 44, 44, 44, - 36, 36, 36, 62, 61, 36, 36, 36, 36, 36, 36, 36, 36, 86, 86, 90, - 43, 89, 87, 87, 61, 44, 44, 44, 36, 70, 85,107, 64, 44, 44, 44, - 43, 94, 36, 36, 36, 36, 36, 36, 36, 36, 86, 43, 43, 80, 44, 86, - 85, 60, 2, 2, 2, 2, 2, 2, 7, 7, 7, 7, 7, 80, 44, 44, - 27, 27, 91, 67, 67, 67, 56, 20,168, 67, 67, 67, 67, 67, 67, 67, - 67, 44, 44, 44, 44, 44, 44, 93,105,105,105,105,105,105,105,181, - 2, 2, 64, 44, 44, 44, 44, 44, 63, 64, 44, 44, 44, 44, 44, 44, - 65, 65, 65, 65, 65, 65, 65, 65, 71, 36, 36, 70, 43, 43, 43, 43, - 43, 43, 43, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 36, 43, - 43, 43, 43, 43, 43, 86, 87, 43, 43, 43, 60, 44, 44, 44, 44, 44, - 43, 43, 43, 60, 2, 2, 67, 67, 40, 40, 97, 44, 44, 44, 44, 44, - 7, 7, 7, 7, 7,179, 27, 27, 27, 62, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 44, 44, 62, 36, 40, 69, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 83,164, 2, 27, 27, 27, 30, 2, 64, 44, 44, - 36, 36, 36, 36, 36, 61, 44, 57, 94, 86, 86, 86, 86, 86, 86, 86, - 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 44, 44, 44, 57, - 43, 74, 40, 40, 40, 40, 40, 40, 40, 88, 80, 44, 44, 44, 44, 44, - 86, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 62, - 40, 40, 52, 40, 40, 40, 52, 81, 36, 61, 44, 44, 44, 44, 44, 44, - 44, 61, 44, 44, 44, 44, 44, 44, 36, 61, 62, 44, 44, 44, 44, 44, - 44, 44, 36, 36, 44, 44, 44, 44, 36, 36, 36, 36, 36, 44, 50, 60, - 65, 65, 44, 44, 44, 44, 44, 44, 43, 43, 43, 43, 43, 43, 43, 44, - 43, 43, 43, 80, 44, 44, 44, 44, 67, 67, 67, 92, 55, 67, 67, 67, - 67, 67,186, 87, 43, 67,186, 86, 86,187, 65, 65, 65, 84, 43, 43, - 43, 76, 50, 43, 43, 43, 67, 67, 67, 67, 67, 67, 67, 43, 43, 67, - 67, 43, 76, 44, 44, 44, 44, 44, 27, 27, 44, 44, 44, 44, 44, 44, - 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 16, 16, 16,110, 16, 16, 16, 16, 16, - 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 47, 11, - 44, 47, 48, 47, 48, 11, 47, 11, 11, 11, 11, 16, 16,150,150, 16, - 16, 16,150, 16, 16, 16, 16, 16, 16, 16, 11, 48, 11, 47, 48, 11, - 11, 11, 47, 11, 11, 11, 47, 16, 16, 16, 16, 16, 11, 48, 11, 47, - 11, 11, 47, 47, 44, 11, 11, 11, 47, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, - 16, 16, 16, 44, 11, 11, 11, 11, 31, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, - 11, 11, 31, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 33, - 16, 16, 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 31, - 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 31, 16, 16, 16, - 16, 33, 16, 16, 16, 32, 44, 7, 43, 43, 43, 76, 67, 50, 43, 43, - 43, 43, 43, 43, 43, 43, 76, 67, 67, 67, 50, 67, 67, 67, 67, 67, - 67, 67, 76, 21, 2, 2, 44, 44, 44, 44, 44, 44, 44, 57, 43, 43, - 16, 16, 16, 16, 16, 39, 16, 16, 16, 16, 16, 16, 16, 16, 16,110, - 44, 44,150, 16, 16,110, 44, 44, 43, 43, 43, 80, 43, 43, 43, 43, - 43, 43, 43, 43, 80, 57, 43, 43, 43, 57, 80, 43, 43, 80, 44, 44, - 40, 40, 40, 40, 40, 40, 40, 44, 44, 44, 44, 44, 44, 44, 44, 57, - 43, 43, 43, 74, 40, 40, 40, 44, 7, 7, 7, 7, 7, 44, 44, 77, - 36, 36, 36, 36, 36, 36, 36, 80, 36, 36, 36, 36, 36, 36, 43, 43, - 7, 7, 7, 7, 7, 44, 44, 96, 36, 36, 36, 36, 36, 83, 43, 43, - 188, 7, 7, 7, 7,189, 44, 93, 36, 36, 36, 61, 36, 36, 62, 61, - 36, 36, 61,179, 27, 27, 27, 27, 16, 16, 43, 43, 43, 74, 44, 44, - 27, 27, 27, 27, 27, 27,163, 27,190, 27,100, 44, 44, 44, 44, 44, - 27, 27, 27, 27, 27, 27, 27,163, 27, 27, 27, 27, 27, 27, 27, 44, - 36, 36, 62, 36, 36, 36, 36, 36, 62, 61, 61, 62, 62, 36, 36, 36, - 36, 61, 36, 36, 62, 62, 44, 44, 44, 61, 44, 62, 62, 62, 62, 36, - 62, 61, 61, 62, 62, 62, 62, 62, 62, 61, 61, 62, 36, 61, 36, 36, - 36, 61, 36, 36, 62, 36, 61, 61, 36, 36, 36, 36, 36, 62, 36, 36, - 62, 36, 62, 36, 36, 62, 36, 36, 8, 44, 44, 44, 44, 44, 44, 44, - 67, 67, 67, 67, 67, 67, 44, 44, 55, 67, 67, 67, 67, 67, 67, 67, - 27, 27, 27, 27, 27, 27, 91, 67, 67, 67, 67, 67, 67, 67, 67, 44, - 44, 44, 44, 67, 67, 67, 67, 67, 67, 92, 44, 44, 44, 44, 44, 44, - 67, 67, 67, 67, 92, 44, 44, 44, 67, 44, 44, 44, 44, 44, 44, 44, - 67, 67, 67, 67, 67, 25, 41, 41, 67, 67, 67, 67, 44, 44, 67, 67, - 67, 67, 67, 92, 44, 55, 67, 67, 67, 67, 67, 67, 44, 44, 44, 44, - 67, 67, 67, 67, 67, 44, 44, 55, 67, 67, 67, 92, 44, 44, 44, 67, - 67, 67, 67, 67, 67, 67, 92, 55, 67, 92, 67, 67, 67, 67, 67, 67, - 79, 44, 44, 44, 44, 44, 44, 44,171,171,171,171,171,171,171, 44, - 171,171,171,171,171,171,171, 0, 0, 0, 29, 21, 21, 21, 23, 21, - 22, 18, 21, 25, 21, 17, 13, 13, 25, 25, 25, 21, 21, 9, 9, 9, - 9, 22, 21, 18, 24, 16, 24, 5, 5, 5, 5, 22, 25, 18, 25, 0, - 23, 23, 26, 21, 24, 26, 7, 20, 25, 1, 26, 24, 26, 25, 15, 15, - 24, 15, 7, 19, 15, 21, 9, 25, 9, 5, 5, 25, 5, 9, 5, 7, - 7, 7, 9, 8, 8, 5, 7, 5, 6, 6, 24, 24, 6, 24, 12, 12, - 2, 2, 6, 5, 9, 21, 9, 2, 2, 9, 25, 9, 26, 12, 11, 11, - 2, 6, 5, 21, 17, 2, 2, 26, 26, 23, 2, 12, 17, 12, 21, 12, - 12, 21, 7, 2, 2, 7, 7, 21, 21, 2, 1, 1, 21, 23, 26, 26, - 1, 21, 6, 7, 7, 12, 12, 7, 21, 7, 12, 1, 12, 6, 6, 12, - 12, 26, 7, 26, 26, 7, 2, 1, 12, 2, 6, 2, 24, 7, 7, 6, - 1, 12, 12, 10, 10, 10, 10, 12, 21, 6, 2, 10, 10, 2, 15, 26, - 26, 2, 2, 21, 7, 10, 15, 7, 2, 23, 21, 26, 10, 7, 21, 15, - 15, 2, 17, 7, 29, 7, 7, 22, 18, 2, 14, 14, 14, 7, 10, 21, - 17, 21, 11, 12, 5, 2, 5, 6, 8, 8, 8, 24, 5, 24, 2, 24, - 9, 24, 24, 2, 29, 29, 29, 1, 17, 17, 20, 19, 22, 20, 27, 28, - 1, 29, 21, 20, 19, 21, 21, 16, 16, 21, 25, 22, 18, 21, 21, 29, - 1, 2, 15, 6, 18, 6, 23, 2, 12, 11, 9, 26, 26, 9, 26, 5, - 5, 26, 14, 9, 5, 14, 14, 15, 25, 26, 26, 22, 18, 26, 18, 25, - 18, 22, 5, 12, 2, 5, 22, 21, 21, 22, 18, 17, 26, 6, 7, 14, - 17, 22, 18, 18, 26, 14, 17, 6, 14, 6, 12, 24, 24, 6, 26, 15, - 6, 21, 11, 21, 24, 9, 6, 9, 23, 26, 6, 10, 4, 4, 3, 3, - 7, 25, 17, 16, 16, 22, 16, 16, 25, 17, 25, 2, 25, 24, 2, 15, - 12, 15, 14, 2, 21, 14, 7, 15, 12, 17, 21, 1, 26, 10, 10, 1, - 7, 13, 13, 2, 23, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 0, 10, 11, 12, 13, 0, 14, 0, 0, 0, 0, 0, 15, 0, 16, 0, + 32, 32, 11, 11, 34, 34, 32, 32, 32, 32, 32, 32, 32, 32, 46, 43, + 51, 39,166, 35, 39, 35, 36, 36, 36, 70, 36, 70, 36, 69, 36, 36, + 36, 93, 86, 84, 66, 66, 79, 43, 27, 27, 27, 66,167, 43, 43, 43, + 36, 36, 2, 2, 43, 43, 43, 43, 85, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 85, 85, 85, 85, 85, 85, 85, 85, 42, 43, 43, 43, 43, 2, + 42, 36, 36, 36, 2, 71, 71, 69, 36, 36, 36, 42, 42, 42, 42, 2, + 36, 36, 36, 69, 42, 42, 42, 42, 42, 85, 43, 43, 43, 43, 43, 92, + 36, 69, 85, 42, 42, 85, 42, 85,106, 2, 2, 2, 2, 2, 2, 51, + 7, 7, 7, 7, 7, 43, 43, 2, 36, 36, 69, 68, 36, 36, 36, 36, + 7, 7, 7, 7, 7, 36, 36, 60, 36, 36, 36, 36, 69, 42, 42, 84, + 86, 84, 86, 79, 43, 43, 43, 43, 36, 69, 36, 36, 36, 36, 84, 43, + 7, 7, 7, 7, 7, 43, 2, 2, 68, 36, 36, 76, 66, 93, 84, 36, + 70, 42, 70, 69, 70, 36, 36, 42, 69, 60, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 61, 82, 2, 36, 36, 36, 36, 36, 93, 42, 85, + 2, 82,168, 79, 43, 43, 43, 43, 61, 36, 36, 60, 61, 36, 36, 60, + 61, 36, 36, 60, 43, 43, 43, 43, 16, 16, 16, 16, 16,113, 39, 39, + 16, 16, 16, 16,110, 40, 43, 43, 36, 93, 86, 85, 84,106, 86, 43, + 36, 36, 43, 43, 43, 43, 43, 43, 36, 36, 36, 60, 43, 61, 36, 36, + 169,169,169,169,169,169,169,169,170,170,170,170,170,170,170,170, + 16, 16, 16,109, 43, 43, 43, 43, 43,149, 16, 16, 43, 43, 61, 70, + 36, 36, 36, 36,171, 36, 36, 36, 36, 36, 36, 60, 36, 36, 60, 60, + 36, 61, 60, 36, 36, 36, 36, 36, 36, 40, 40, 40, 40, 40, 40, 40, + 40, 22, 66, 66, 66, 66, 66, 66, 66, 77, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36,147, 66, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 66, 66, 66, 66, 36, 36, 36, 36, 36, 36,167, 66, + 2, 2, 2,151,129, 43, 43, 43, 6,172,173,147,147,147,147,147, + 147,147,129,151,129, 2,126,174, 2, 63, 2, 2,155,147,147,129, + 2,175, 8,176, 65, 2, 43, 43, 36, 36, 60, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 60, 78, 92, 2, 3, 2, 4, 5, 6, 2, + 16, 16, 16, 16, 16, 17, 18,128,129, 4, 2, 36, 36, 36, 36, 36, + 68, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 39, + 43, 36, 36, 36, 43, 36, 36, 36, 43, 36, 36, 36, 43, 36, 60, 43, + 20,177, 55,178, 26, 8,143, 91, 43, 43, 43, 43, 78, 64, 66, 43, + 36, 36, 36, 36, 36, 36, 61, 36, 36, 36, 36, 36, 36, 60, 36, 61, + 2, 63, 43,179, 27, 27, 27, 27, 27, 27, 43, 54, 66, 66, 66, 66, + 104,104,142, 27, 90, 66, 66, 66, 66, 66, 66, 66, 66, 27, 66, 91, + 66, 66, 66, 66, 66, 66, 91, 43, 91, 43, 43, 43, 43, 43, 43, 43, + 66, 66, 66, 66, 66, 66, 49, 43,180, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 43, 43, 27, 27, 43, 43, 43, 43, 61, 36, + 154, 36, 36, 36, 36,181, 43, 43, 36, 36, 36, 42, 42, 79, 43, 43, + 36, 36, 36, 36, 36, 36, 36, 92, 36, 36, 43, 43, 36, 36, 36, 36, + 182,104,104, 43, 43, 43, 43, 43, 11, 11, 11, 11, 16, 16, 16, 16, + 11, 11, 43, 43, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 43, 43, + 36, 36, 36, 36, 43, 43, 43, 43, 36, 36, 43, 43, 43, 43, 43, 92, + 11, 11, 11, 11, 11, 46, 11, 11, 11, 46, 11,149, 16, 16, 16, 16, + 16,149, 16, 16, 16, 16, 16, 16, 16,149, 16, 16, 16,149,109, 43, + 39, 39, 39, 51, 39, 39, 39, 39, 80, 39, 39, 39, 39, 80, 43, 43, + 36, 36, 36, 43, 60, 36, 36, 36, 36, 36, 36, 61, 60, 43, 60, 61, + 36, 36, 36, 92, 27, 27, 27, 27, 36, 36, 36, 76,162, 27, 27, 27, + 43, 43, 43,179, 27, 27, 27, 27, 36, 60, 36, 43, 43,179, 27, 27, + 36, 36, 36, 27, 27, 27, 43, 92, 36, 36, 36, 36, 36, 43, 43, 92, + 36, 36, 36, 36, 43, 43, 27, 36, 43, 27, 27, 27, 27, 27, 27, 27, + 69, 42, 56, 79, 43, 43, 42, 42, 36, 36, 61, 36, 61, 36, 36, 36, + 36, 36, 36, 43, 42, 79, 43, 56, 27, 27, 27, 27, 99, 43, 43, 43, + 2, 2, 2, 2, 63, 43, 43, 43, 36, 36, 36, 36, 36, 36,183, 30, + 36, 36, 36, 36, 36, 36,183, 27, 36, 36, 36, 36, 77, 36, 36, 36, + 36, 36, 69, 79, 43,179, 27, 27, 2, 2, 2, 63, 43, 43, 43, 43, + 36, 36, 36, 43, 92, 2, 2, 2, 36, 36, 36, 43, 27, 27, 27, 27, + 36, 60, 43, 43, 27, 27, 27, 27, 36, 43, 43, 43, 92, 2, 63, 43, + 43, 43, 43, 43,179, 27, 27, 27, 11, 46, 43, 43, 43, 43, 43, 43, + 16,109, 43, 43, 43, 27, 27, 27, 36, 36, 42, 42, 43, 43, 43, 43, + 7, 7, 7, 7, 7, 36, 36, 68, 11, 11, 11, 43, 56, 42, 42,158, + 16, 16, 16, 43, 43, 43, 43, 8, 27, 27, 27, 27, 27, 27, 27, 99, + 36, 36, 36, 36, 36, 56,184, 43, 36, 43, 43, 43, 43, 43, 43, 43, + 43, 36, 82, 36, 43, 43, 43, 43, 96, 66, 66, 66, 91, 43, 43, 43, + 43, 43, 43, 43, 43, 42, 42, 42, 27, 27, 27, 94, 43, 43, 43, 43, + 180, 27, 30, 2, 2, 43, 43, 43, 36, 42, 42, 2, 2, 43, 43, 43, + 36, 36,183, 27, 27, 27, 43, 43, 86, 97, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 42, 42, 42, 42, 42, 42, 42, 59, 2, 2, 2, 43, + 27, 27, 27, 7, 7, 7, 7, 7, 70, 69, 70, 43, 43, 43, 43, 56, + 85, 86, 42, 84, 86, 59,185, 2, 2, 79, 43, 43, 43, 43, 78, 43, + 42, 70, 36, 36, 36, 36, 36, 36, 36, 36, 36, 69, 42, 42, 86, 42, + 42, 42, 79, 7, 7, 7, 7, 7, 2, 2, 93, 97, 43, 43, 43, 43, + 36, 69, 2, 60, 43, 43, 43, 43, 36, 93, 85, 42, 42, 42, 42, 84, + 97, 36, 62, 2, 58, 42, 59, 86, 7, 7, 7, 7, 7, 62, 62, 2, + 179, 27, 27, 27, 27, 27, 27, 27, 27, 27, 99, 43, 43, 43, 43, 43, + 36, 36, 36, 36, 36, 36, 85, 86, 42, 85, 84, 42, 2, 2, 2, 70, + 69, 43, 43, 43, 43, 43, 43, 43, 36, 36, 36, 60, 60, 36, 36, 61, + 36, 36, 36, 36, 36, 36, 36, 61, 36, 36, 36, 36, 62, 43, 43, 43, + 36, 36, 36, 36, 36, 36, 36, 69, 85, 86, 42, 42, 42, 79, 43, 43, + 42, 85, 61, 36, 36, 36, 60, 61, 60, 36, 61, 36, 36, 56, 70, 85, + 84, 85, 89, 88, 89, 88, 85, 43, 60, 43, 43, 88, 43, 43, 61, 36, + 36, 85, 43, 42, 42, 42, 79, 43, 42, 42, 79, 43, 43, 43, 43, 43, + 36, 36, 36, 36, 36, 61, 43, 60, 36, 36, 36, 61, 85, 86, 42, 42, + 79, 89, 88, 88, 85, 89, 85, 84, 70, 70, 2, 92, 63, 43, 43, 43, + 56, 79, 43, 43, 43, 43, 43, 43, 36, 36, 93, 85, 42, 42, 42, 42, + 85, 42, 84, 70, 36, 62, 2, 2, 7, 7, 7, 7, 7, 2, 92, 70, + 85, 86, 42, 42, 84, 84, 85, 86, 84, 42, 36, 71, 43, 43, 43, 43, + 36, 36, 36, 36, 36, 36, 36, 93, 85, 42, 42, 43, 85, 85, 42, 86, + 59, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 36, 36, 42, 43, + 85, 86, 42, 42, 42, 84, 86, 86, 59, 2, 60, 43, 43, 43, 43, 43, + 2, 2, 2, 2, 2, 2, 63, 43, 36, 36, 36, 36, 36, 69, 86, 85, + 42, 42, 42, 86, 62, 43, 43, 43, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 43, 43, 43, 43, 43, 43, 36, 36, 36, 36, 36, 60, 56, 86, + 85, 42, 42, 86, 42, 42, 43, 43, 7, 7, 7, 7, 7, 27, 2, 96, + 42, 42, 42, 42, 86, 59, 43, 43, 27, 99, 43, 43, 43, 43, 43, 61, + 36, 36, 36, 60, 61, 43, 36, 36, 36, 36, 61, 60, 36, 36, 36, 36, + 85, 85, 85, 88, 89, 56, 84, 70, 97, 86, 2, 63, 43, 43, 43, 43, + 36, 36, 36, 36, 43, 36, 36, 36, 93, 85, 42, 42, 43, 42, 85, 85, + 70, 71, 89, 43, 43, 43, 43, 43, 69, 42, 42, 42, 42, 70, 36, 36, + 36, 69, 42, 42, 84, 69, 42, 59, 2, 2, 2, 58, 43, 43, 43, 43, + 69, 42, 42, 84, 86, 42, 36, 36, 36, 36, 36, 36, 36, 42, 42, 42, + 42, 42, 42, 84, 42, 2, 71, 2, 2, 63, 43, 43, 43, 43, 43, 43, + 2, 2, 2, 2, 2, 43, 43, 43, 84, 42, 84, 84, 43, 43, 43, 43, + 62, 43, 43, 43, 43, 43, 43, 43, 42, 42, 42, 79, 42, 42, 42, 86, + 62, 2, 2, 43, 43, 43, 43, 43, 2, 36, 36, 36, 36, 36, 36, 36, + 43, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 88, 42, 42, 42, + 84, 42, 86, 79, 43, 43, 43, 43, 36, 36, 36, 60, 36, 61, 36, 36, + 69, 42, 42, 79, 43, 79, 42, 56, 42, 42, 42, 69, 43, 43, 43, 43, + 36, 36, 36, 61, 60, 36, 36, 36, 36, 36, 36, 36, 36, 85, 85, 89, + 42, 88, 86, 86, 60, 43, 43, 43, 36, 36, 36, 36, 82, 36, 43, 43, + 36, 69, 84,106, 63, 43, 43, 43, 42, 93, 36, 36, 36, 36, 36, 36, + 36, 36, 85, 42, 42, 79, 43, 85, 84, 59, 2, 2, 2, 2, 2, 2, + 7, 7, 7, 7, 7, 79, 43, 43, 27, 27, 90, 66, 66, 66, 55, 20, + 167, 66, 66, 66, 66, 66, 66, 66, 66, 43, 43, 43, 43, 43, 43, 92, + 104,104,104,104,104,104,104,181, 2, 2, 63, 43, 43, 43, 43, 43, + 62, 63, 43, 43, 43, 43, 43, 43, 64, 64, 64, 64, 64, 64, 64, 64, + 70, 36, 36, 69, 42, 42, 42, 42, 42, 42, 42, 43, 43, 43, 43, 43, + 36, 36, 36, 36, 36, 36, 36, 42, 42, 42, 42, 42, 42, 85, 86, 42, + 42, 42, 59, 43, 43, 43, 43, 43, 42, 42, 42, 59, 2, 2, 66, 66, + 39, 39, 96, 43, 43, 43, 43, 43, 7, 7, 7, 7, 7,179, 27, 27, + 27, 61, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 43, 43, 61, 36, + 39, 68, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 82,163, 2, + 27, 27, 27, 30, 2, 63, 43, 43, 11, 11, 11, 11, 46,149, 16, 16, + 16, 16, 43, 43, 43, 43, 43, 43, 36, 36, 36, 36, 36, 60, 43, 56, + 93, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85, 43, 43, 43, 56, 42, 73, 39, 39, 39, 39, 39, 39, + 39, 87, 79, 43, 43, 43, 43, 43, 85, 39,104,181, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 61, 36, 60, 43, 43, 43, 43, 43, 43, + 39, 39, 51, 39, 39, 39, 51, 80, 43, 60, 43, 43, 43, 43, 43, 43, + 36, 60, 61, 43, 43, 43, 43, 43, 43, 43, 36, 36, 43, 43, 43, 43, + 36, 36, 36, 36, 36, 43, 49, 59, 64, 64, 43, 43, 43, 43, 43, 43, + 7, 7, 7, 7, 7, 66, 91, 43, 66, 66, 43, 43, 43, 66, 66, 66, + 176, 43, 43, 43, 43, 43, 43, 43, 42, 42, 42, 79, 43, 43, 43, 43, + 66, 66, 66, 91, 54, 66, 66, 66, 66, 66,186, 86, 42, 66,186, 85, + 85,187, 64, 64, 64, 83, 42, 42, 42, 75, 49, 42, 42, 42, 66, 66, + 66, 66, 66, 66, 66, 42, 42, 66, 66, 42, 75, 43, 43, 43, 43, 43, + 27, 27, 43, 43, 43, 43, 43, 43, 11, 11, 11, 11, 11, 16, 16, 16, + 16, 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 16, + 16, 16,109, 16, 16, 16, 16, 16, 11, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 46, 11, 43, 46, 47, 46, 47, 11, 46, 11, + 11, 11, 11, 16, 16,149,149, 16, 16, 16,149, 16, 16, 16, 16, 16, + 16, 16, 11, 47, 11, 46, 47, 11, 11, 11, 46, 11, 11, 11, 46, 16, + 16, 16, 16, 16, 11, 47, 11, 46, 11, 11, 46, 46, 43, 11, 11, 11, + 46, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 11, 11, + 11, 11, 11, 16, 16, 16, 16, 16, 16, 16, 16, 43, 11, 11, 11, 11, + 31, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 33, 16, 16, + 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 31, 16, 16, + 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 31, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, + 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, 32, 43, 7, + 42, 42, 42, 75, 66, 49, 42, 42, 42, 42, 42, 42, 42, 42, 75, 66, + 66, 66, 49, 66, 66, 66, 66, 66, 66, 66, 75, 21, 2, 2, 43, 43, + 43, 43, 43, 43, 43, 56, 42, 42, 16, 16, 16, 16, 16,138, 16, 16, + 16, 16, 16, 16, 16, 16, 16,109, 43, 43,149, 16, 16,109, 43, 43, + 42, 42, 42, 79, 42, 42, 42, 42, 42, 42, 42, 42, 79, 56, 42, 42, + 42, 56, 79, 42, 42, 79, 43, 43, 39, 39, 39, 39, 39, 39, 39, 43, + 43, 43, 43, 43, 43, 43, 43, 56, 42, 42, 42, 73, 39, 39, 39, 43, + 7, 7, 7, 7, 7, 43, 43, 76, 36, 36, 36, 36, 36, 36, 36, 79, + 36, 36, 36, 36, 36, 36, 42, 42, 7, 7, 7, 7, 7, 43, 43, 95, + 36, 36, 36, 36, 36, 82, 42, 42,188, 7, 7, 7, 7,189, 43, 92, + 36, 69, 36, 70, 36, 36, 36, 42, 36, 36, 69, 43, 43, 43, 43, 82, + 36, 36, 36, 60, 36, 36, 61, 60, 36, 36, 60,179, 27, 27, 27, 27, + 16, 16, 42, 42, 42, 73, 43, 43, 27, 27, 27, 27, 27, 27,162, 27, + 190, 27, 99, 43, 43, 43, 43, 43, 27, 27, 27, 27, 27, 27, 27,162, + 27, 27, 27, 27, 27, 27, 27, 43, 36, 36, 61, 36, 36, 36, 36, 36, + 61, 60, 60, 61, 61, 36, 36, 36, 36, 60, 36, 36, 61, 61, 43, 43, + 43, 60, 43, 61, 61, 61, 61, 36, 61, 60, 60, 61, 61, 61, 61, 61, + 61, 60, 60, 61, 36, 60, 36, 36, 36, 60, 36, 36, 61, 36, 60, 60, + 36, 36, 36, 36, 36, 61, 36, 36, 61, 36, 61, 36, 36, 61, 36, 36, + 8, 43, 43, 43, 43, 43, 43, 43, 66, 66, 66, 66, 66, 66, 43, 43, + 54, 66, 66, 66, 66, 66, 66, 66, 27, 27, 27, 27, 27, 27, 90, 66, + 66, 66, 66, 66, 66, 66, 66, 43, 43, 43, 43, 66, 66, 66, 66, 66, + 66, 91, 43, 43, 43, 43, 43, 43, 66, 66, 66, 66, 91, 43, 43, 43, + 66, 43, 43, 43, 43, 43, 43, 43, 66, 66, 66, 66, 66, 25, 40, 40, + 66, 66, 66, 66, 91, 43, 66, 66, 66, 66, 66, 66, 43, 43, 43, 43, + 8, 8, 8, 8,176, 43, 43, 43, 66, 66, 66, 66, 66, 91, 43, 66, + 66, 66, 66, 91, 91, 43, 54, 66, 66, 66, 66, 66, 66, 66, 91, 54, + 66, 66, 66, 66, 66, 91, 43, 54, 66, 91, 66, 66, 66, 66, 66, 66, + 7, 7, 7, 7, 7, 91, 43, 43, 78, 43, 43, 43, 43, 43, 43, 43, + 170,170,170,170,170,170,170, 43,170,170,170,170,170,170,170, 0, + 0, 0, 29, 21, 21, 21, 23, 21, 22, 18, 21, 25, 21, 17, 13, 13, + 25, 25, 25, 21, 21, 9, 9, 9, 9, 22, 21, 18, 24, 16, 24, 5, + 5, 5, 5, 22, 25, 18, 25, 0, 23, 23, 26, 21, 24, 26, 7, 20, + 25, 1, 26, 24, 26, 25, 15, 15, 24, 15, 7, 19, 15, 21, 9, 25, + 9, 5, 5, 25, 5, 9, 5, 7, 7, 7, 9, 8, 8, 5, 6, 6, + 24, 24, 6, 24, 12, 12, 2, 2, 6, 5, 9, 21, 9, 2, 2, 9, + 25, 9, 26, 12, 11, 11, 2, 6, 5, 21, 17, 2, 2, 26, 26, 23, + 2, 12, 17, 12, 21, 12, 12, 21, 7, 2, 2, 7, 7, 21, 21, 2, + 1, 1, 21, 23, 26, 26, 1, 21, 6, 7, 7, 12, 12, 7, 21, 7, + 12, 1, 12, 6, 6, 12, 12, 26, 7, 26, 26, 7, 2, 1, 12, 2, + 6, 2, 24, 7, 7, 6, 1, 12, 12, 10, 10, 10, 10, 12, 21, 6, + 2, 10, 10, 2, 15, 26, 26, 2, 2, 21, 7, 10, 15, 7, 2, 23, + 21, 26, 10, 7, 21, 15, 15, 2, 17, 7, 29, 7, 7, 22, 18, 2, + 14, 14, 14, 7, 10, 21, 17, 21, 11, 12, 5, 2, 5, 6, 8, 8, + 8, 24, 5, 24, 2, 24, 9, 24, 24, 2, 29, 29, 29, 1, 17, 17, + 20, 19, 22, 20, 27, 28, 1, 29, 21, 20, 19, 21, 21, 16, 16, 21, + 25, 22, 18, 21, 21, 29, 1, 2, 15, 6, 18, 6, 12, 11, 9, 26, + 26, 9, 26, 5, 7, 5, 5, 26, 14, 9, 5, 14, 14, 15, 25, 26, + 26, 22, 18, 26, 18, 25, 18, 22, 5, 12, 2, 5, 22, 21, 21, 22, + 18, 17, 26, 6, 7, 14, 17, 22, 18, 18, 26, 14, 17, 6, 14, 6, + 12, 24, 24, 6, 26, 15, 6, 21, 11, 21, 24, 9, 6, 9, 23, 26, + 6, 10, 4, 4, 3, 3, 7, 25, 17, 16, 16, 22, 16, 16, 25, 17, + 25, 2, 25, 24, 23, 2, 2, 15, 12, 15, 14, 2, 21, 14, 7, 15, + 12, 17, 21, 1, 26, 10, 10, 1, 7, 13, 13, 2, 23, 15, 0, 1, + 2, 3, 4, 5, 6, 7, 8, 9, 0, 10, 11, 12, 13, 0, 14, 0, + 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 18, 19, 0, 0, 0, 0, + 0, 17, 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 21, 22, 23, + 0, 0, 0, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 20, 0, 21, 22, 23, 0, 0, 0, 24, 25, 26, 27, 28, - 29, 30, 31, 32, 33, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, + 0, 0, 0, 36, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 36, 0, 37, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 39, 40, 0, 0, 0, 0, 0, 0, 41, 42, + 43, 44, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, + 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, + 6, 7, 8, 0, 9, 0, 10, 11, 0, 0, 12, 13, 14, 15, 16, 0, + 0, 0, 0, 17, 18, 19, 20, 0, 21, 0, 22, 23, 0, 24, 25, 0, + 0, 24, 26, 27, 0, 24, 26, 0, 0, 24, 26, 0, 0, 24, 26, 0, + 0, 0, 26, 0, 0, 24, 28, 0, 0, 24, 26, 0, 0, 29, 26, 0, + 0, 0, 30, 0, 0, 31, 32, 0, 0, 33, 34, 0, 35, 36, 0, 37, + 38, 0, 39, 0, 0, 40, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 44, 0, 0, + 0, 0, 45, 0, 0, 0, 0, 0, 0, 46, 0, 0, 0, 47, 0, 0, + 0, 0, 0, 0, 48, 0, 0, 49, 0, 50, 51, 52, 0, 53, 54, 55, + 0, 56, 0, 57, 0, 58, 0, 0, 0, 0, 59, 60, 0, 0, 0, 0, + 0, 0, 61, 62, 0, 0, 0, 0, 0, 0, 63, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, 66, + 0, 0, 0, 67, 0, 68, 0, 0, 69, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 70, 71, 0, 0, 72, 0, 0, 0, 0, + 0, 0, 0, 0, 73, 74, 0, 0, 0, 0, 54, 75, 0, 76, 77, 0, + 0, 78, 79, 0, 0, 0, 0, 0, 0, 80, 81, 82, 0, 0, 0, 0, + 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 83, 0, 0, 0, + 0, 0, 0, 0, 0, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 87, + 0, 0, 0, 0, 88, 89, 0, 0, 0, 0, 0, 90, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 91, 0, 92, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 93, 0, 94, 0, 0, 95, 0, + 96, 0, 0, 0, 0, 0, 73, 97, 0, 98, 0, 0, 99,100, 0, 78, + 0, 0,101, 0, 0,102, 0, 0, 0, 0, 0,103, 0,104, 26,105, + 0, 0,106, 0, 0, 0,107, 0, 0, 0,108, 0, 0, 0, 0, 0, + 0, 66,109, 0, 0, 66, 0, 0, 0,110, 0, 0, 0,111, 0, 0, + 0, 0, 0, 0, 0, 98, 0, 0, 0, 0, 0, 0, 0,112,113, 0, + 0, 0, 0, 79, 0, 44,114, 0,115, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0,116, 0, + 117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,118, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,119, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,120, 0,121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 40, - 0, 0, 0, 0, 0, 0, 41, 42, 43, 0, 44, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 3, 0, - 0, 0, 4, 5, 6, 7, 0, 8, 9, 10, 0, 11, 12, 13, 14, 15, - 16, 17, 16, 18, 16, 19, 16, 19, 16, 19, 0, 19, 16, 20, 16, 19, - 21, 19, 0, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 0, 32, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, - 34, 0, 0, 35, 0, 0, 36, 0, 37, 0, 0, 0, 38, 39, 40, 41, - 42, 43, 44, 45, 46, 0, 0, 47, 0, 0, 0, 48, 0, 0, 0, 49, - 0, 0, 0, 0, 0, 0, 0, 50, 0, 51, 0, 52, 53, 0, 54, 0, - 0, 0, 0, 0, 0, 55, 56, 57, 0, 0, 0, 0, 58, 0, 0, 59, - 60, 61, 62, 63, 0, 0, 64, 65, 0, 0, 0, 66, 0, 0, 0, 0, - 67, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 69, 0, 0, 0, 70, 0, 71, 0, 0, 72, 0, 0, 73, - 0, 0, 0, 0, 0, 0, 0, 0, 74, 75, 0, 0, 0, 0, 76, 77, - 0, 78, 79, 0, 0, 80, 81, 0, 82, 62, 0, 83, 84, 0, 0, 85, - 86, 87, 0, 88, 0, 89, 0, 90, 0, 0, 51, 91, 51, 0, 92, 0, - 93, 0, 0, 0, 81, 0, 0, 0, 94, 95, 0, 96, 97, 98, 99, 0, - 0, 0, 0, 0, 51, 0, 0, 0, 0,100,101, 0, 0, 0, 0, 0, - 0,102, 0, 0, 0, 0, 0, 0,103, 0, 0, 0, 0, 0, 0,104, - 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,106, 0, 0,107, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,108,109, 0, 0,110, 0, 0, - 0, 0, 0, 0,111, 0,112, 0,105, 0, 0, 0, 0, 0,113,114, - 0, 0, 0, 0, 0, 0, 0,115, 0, 0, 0,116, 0, 0, 0,117, - 0,118, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 0, - 8, 0, 0, 0, 0, 9, 10, 11, 12, 0, 0, 0, 0, 13, 0, 0, - 14, 15, 0, 16, 0, 17, 18, 0, 0, 19, 0, 20, 21, 0, 0, 0, - 0, 0, 22, 23, 0, 24, 25, 0, 0, 26, 0, 0, 0, 27, 0, 0, - 28, 29, 30, 31, 0, 0, 0, 32, 33, 34, 0, 0, 33, 0, 0, 35, - 33, 0, 0, 0, 33, 36, 0, 0, 0, 0, 0, 37, 38, 0, 0, 0, - 0, 0, 0, 39, 40, 0, 0, 0, 0, 0, 0, 41, 42, 0, 0, 0, - 0, 43, 0, 44, 0, 0, 0, 45, 46, 0, 0, 0, 47, 0, 0, 0, - 0, 0, 0, 48, 49, 0, 0, 0, 0, 50, 0, 0, 0, 51, 0, 52, - 0, 53, 0, 0, 0, 0, 54, 0, 0, 0, 0, 55, 0, 56, 0, 0, - 0, 0, 57, 58, 0, 0, 0, 59, 60, 0, 0, 0, 0, 0, 0, 61, - 52, 0, 62, 63, 0, 0, 64, 0, 0, 0, 65, 66, 0, 0, 0, 67, - 0, 68, 69, 70, 71, 72, 1, 73, 0, 74, 75, 76, 0, 0, 77, 78, - 0, 0, 0, 79, 0, 0, 1, 1, 0, 0, 80, 0, 0, 81, 0, 0, - 0, 0, 77, 82, 0, 83, 0, 0, 0, 0, 0, 78, 84, 0, 85, 0, - 52, 0, 1, 78, 0, 0, 86, 0, 0, 87, 0, 0, 0, 0, 0, 88, - 57, 0, 0, 0, 0, 0, 0, 89, 90, 0, 0, 84, 0, 0, 33, 0, - 0, 91, 0, 0, 0, 0, 92, 0, 0, 0, 0, 49, 0, 0, 93, 0, - 0, 0, 0, 94, 95, 0, 0, 96, 0, 0, 97, 0, 0, 0, 98, 0, - 0, 0, 99, 0, 0, 0,100, 0, 0, 0, 0,101,102, 93, 0, 0, - 103, 0, 0, 0, 84, 0, 0,104, 0, 0, 0,105,106, 0, 0,107, - 108, 0, 0, 0, 0, 0, 0,109, 0, 0,110, 0, 0, 0, 0,111, - 33, 0,112,113,114, 57, 0, 0,115, 35, 0, 0,116, 0, 0, 0, - 117, 0, 0, 0, 0, 0, 0,118, 0, 0,119, 0, 0, 0, 0,120, - 88, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 52,121, 0, 0, 0, - 0,122, 0, 0,123, 0, 0, 0, 0,121, 0, 0,124, 0, 0, 0, - 0, 0, 79, 0, 0, 0, 0,125, 0, 0, 0,126, 0, 0, 0,127, - 0,128, 0, 0, 0, 0,129,130,131, 0,132, 0,133, 0, 0, 0, - 134,135,136, 0, 77, 0, 0, 0, 0, 0, 35, 0, 0, 0,137, 0, - 0, 0,138, 0, 0, 0,139, 0, 0,140, 0, 0,141, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 7, 4, - 4, 8, 9, 10, 1, 11, 12, 13, 14, 15, 16, 17, 18, 1, 1, 1, - 19, 1, 0, 0, 20, 21, 22, 1, 23, 4, 21, 24, 25, 26, 27, 28, - 29, 30, 0, 0, 1, 1, 31, 0, 0, 0, 32, 33, 34, 35, 1, 36, - 37, 0, 0, 0, 0, 38, 1, 39, 14, 39, 40, 41, 42, 0, 0, 0, - 43, 36, 44, 45, 21, 45, 46, 0, 0, 0, 19, 1, 21, 0, 0, 47, - 0, 38, 48, 1, 1, 49, 49, 50, 0, 0, 51, 0, 0, 19, 52, 1, - 0, 0, 38, 14, 4, 1, 1, 1, 53, 21, 43, 52, 54, 21, 35, 1, - 0, 0, 0, 55, 0, 0, 0, 56, 57, 58, 0, 0, 0, 0, 0, 59, - 0, 60, 0, 0, 0, 0, 61, 62, 0, 0, 63, 0, 0, 0, 64, 0, - 0, 0, 65, 0, 0, 0, 66, 0, 0, 0, 67, 0, 0, 0, 68, 0, - 0, 69, 70, 0, 71, 72, 73, 74, 75, 76, 0, 0, 0, 77, 0, 0, - 0, 78, 79, 0, 0, 0, 0, 47, 0, 0, 0, 49, 0, 80, 0, 0, - 0, 62, 0, 0, 63, 0, 0, 81, 0, 0, 82, 0, 0, 0, 83, 0, - 0, 19, 84, 0, 62, 0, 0, 0, 0, 49, 1, 85, 1, 52, 15, 86, - 36, 10, 21, 87, 0, 55, 0, 0, 0, 0, 19, 10, 1, 0, 0, 0, - 0, 0, 88, 0, 0, 89, 0, 0, 88, 0, 0, 0, 0, 78, 0, 0, - 87, 9, 12, 4, 90, 8, 91, 47, 0, 58, 50, 0, 21, 1, 21, 92, - 93, 1, 1, 1, 1, 94, 95, 96, 97, 1, 98, 58, 81, 99,100, 4, - 58, 0, 0, 0, 0, 0, 0, 19, 50, 0, 0, 0, 0, 0, 0, 61, - 0, 0,101,102, 0, 0,103, 0, 0, 1, 1, 50, 0, 0, 0, 38, - 0, 63, 0, 0, 0, 0, 0, 62, 0, 0,104, 68, 61, 0, 0, 0, - 78, 0, 0, 0,105,106, 58, 38, 81, 0, 0, 0, 0, 0, 0,107, - 1, 14, 4, 12, 84, 0, 0, 0, 0, 38, 87, 0, 0, 0, 0,108, - 0, 0,109, 61, 0,110, 0, 0, 0, 1, 0, 0, 0, 0, 49, 50, - 0, 0, 19, 58, 0, 0, 0, 51, 0,111, 14, 52,112, 41, 0, 0, - 62, 0, 0, 61, 0, 0,113, 0, 87, 0, 0, 0, 61, 62, 0, 0, - 62, 0, 89, 0, 0,113, 0, 0, 0, 0,114, 0, 0, 0, 78, 55, - 0, 38, 1, 58, 1, 58, 0, 0, 0, 0, 0, 88, 63, 89, 0, 0, - 115, 0, 0, 0, 55, 0, 0, 0, 0,115, 0, 0, 0, 0, 61, 0, - 0, 0, 0, 79, 0, 61, 0, 0, 0, 0, 56, 0, 89, 80, 0, 0, - 79, 0, 0, 0, 8, 91, 0, 0, 1, 87, 0, 0,116, 0, 0, 0, - 0, 0, 0,117, 0,118,119,120,121, 0,104, 4,122, 49, 23, 0, - 0, 0, 38, 50, 38, 58, 0, 0, 1, 87, 1, 1, 1, 1, 39, 1, - 48,105, 87, 0, 0, 0, 0, 1, 0, 0, 0,123, 0, 0, 0,112, - 4,122, 0, 0, 0, 1,124, 0, 0, 0, 0, 0,230,230,230,230, - 230,232,220,220,220,220,232,216,220,220,220,220,220,202,202,220, - 220,220,220,202,202,220,220,220, 1, 1, 1, 1, 1,220,220,220, - 220,230,230,230,230,240,230,220,220,220,230,230,230,220,220, 0, - 230,230,230,220,220,220,220,230,232,220,220,230,233,234,234,233, - 234,234,233,230, 0, 0, 0,230, 0,220,230,230,230,230,220,230, - 230,230,222,220,230,230,220,220,230,222,228,230, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 0, 23, 0, 24, 25, 0, - 230,220, 0, 18, 30, 31, 32, 0, 0, 0, 0, 27, 28, 29, 30, 31, - 32, 33, 34,230,230,220,220,230,220,230,230,220, 35, 0, 0, 0, - 0, 0,230,230,230, 0, 0,230,230, 0,220,230,230,220, 0, 0, - 0, 36, 0, 0,230,220,230,230,220,220,230,220,220,230,220,230, - 220,230,230, 0, 0,220, 0, 0,230,230, 0,230, 0,230,230,230, - 230,230, 0, 0, 0,220,220,220,230,220,220,220,230,230, 0,220, - 27, 28, 29,230, 7, 0, 0, 0, 0, 9, 0, 0, 0,230,220,230, - 230, 0, 0, 0, 0, 0,230, 0, 0, 84, 91, 0, 0, 0, 0, 9, - 9, 0, 0, 0, 0, 0, 9, 0,103,103, 9, 0,107,107,107,107, - 118,118, 9, 0,122,122,122,122,220,220, 0, 0, 0,220, 0,220, - 0,216, 0, 0, 0,129,130, 0,132, 0, 0, 0, 0, 0,130,130, - 130,130, 0, 0,130, 0,230,230, 9, 0,230,230, 0, 0,220, 0, - 0, 0, 0, 7, 0, 9, 9, 0, 9, 9, 0, 0, 0,230, 0, 0, - 0,228, 0, 0, 0,222,230,220,220, 0, 0, 0,230, 0, 0,220, - 230,220, 0,220,230,230,230, 0, 0, 0, 9, 9, 0, 0, 7, 0, + 0, 0, 0,122, 0, 0, 0, 0,123, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,124, + 125,126, 0, 0, 0, 0,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,128,129, 0, 0,130, 0, 0, 0, 0,121, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,131, 0,132, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,133, 0, 0, 0, 0, + 0, 0, 0,134, 0, 0, 0, 0, 0, 0, 0,135, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,136, 0, 0, 0,137, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, + 1, 2, 3, 4, 5, 6, 7, 4, 4, 8, 9, 10, 1, 11, 12, 13, + 14, 15, 16, 17, 18, 1, 1, 1, 0, 0, 0, 0, 19, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 22, 1, 23, 4, 21, 24, + 25, 26, 27, 28, 29, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 31, 0, 0, 0, 32, 33, 34, 35, 1, 36, 0, 0, 0, 0, + 37, 0, 0, 0, 0, 0, 0, 0, 0, 38, 1, 39, 14, 39, 40, 41, + 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, + 43, 36, 44, 45, 21, 45, 46, 0, 0, 0, 0, 0, 0, 0, 19, 1, + 21, 0, 0, 47, 0, 0, 0, 0, 0, 38, 48, 1, 1, 49, 49, 50, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, 0, 0, 0, 0, + 0, 19, 52, 1, 0, 0, 38, 14, 4, 1, 1, 1, 53, 21, 43, 52, + 54, 21, 35, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, 56, + 57, 58, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 59, 0, 0, 0, 56, 0, 60, 0, 0, 0, 0, 0, 0, + 0, 0, 61, 62, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 64, 0, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 66, 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 68, 0, 0, 0, 0, 0, 0, 69, 70, 0, 0, 0, 0, 0, + 71, 72, 73, 74, 75, 76, 0, 0, 0, 0, 0, 0, 0, 77, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 78, 79, 0, 0, 0, 0, 47, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, 0, 0, + 0, 80, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 0, 0, 0, + 63, 0, 0, 81, 0, 0, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 83, 0, 0, 0, 0, 0, 0, 19, 84, 0, 62, 0, 0, 0, + 0, 49, 1, 85, 0, 0, 0, 0, 1, 52, 15, 86, 36, 10, 21, 1, + 1, 1, 1, 41, 1, 21, 87, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 55, 0, 0, 0, 62, 0, 0, 0, 0, 0, 0, 0, 0, 19, 10, + 1, 0, 0, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 89, 0, 0, + 88, 0, 0, 0, 0, 0, 0, 0, 0, 78, 0, 0, 0, 0, 0, 0, + 90, 9, 12, 4, 91, 8, 92, 47, 0, 58, 50, 0, 21, 1, 21, 93, + 94, 1, 1, 1, 1, 1, 1, 1, 1, 95, 96, 97, 0, 0, 0, 0, + 98, 1, 99, 58, 81,100,101, 4, 58, 0, 0, 0, 0, 0, 0, 19, + 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 1, 1, 1, 1, + 1, 1, 1, 1, 0, 0,102,103, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,104, 0, 0, 0, 0, 19, 0, 1, 1, 50, 0, 0, 0, 0, + 0, 0, 0, 38, 0, 0, 0, 0, 50, 0, 0, 0, 0, 63, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 0, 1, 1, 1, 1, + 50, 0, 0, 0, 0, 0,105, 68, 0, 0, 0, 0, 0, 0, 0, 0, + 61, 0, 0, 0, 0, 0, 0, 0, 78, 0, 0, 0, 62, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,106,107, 58, 38, 81, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, + 0, 0, 0,108, 1, 14, 4, 12, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 47, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 38, 90, 0, 0, 0, 0,109, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,110, 61, 0,111, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 49, 50, 0, 0, 0, 0, 0, 0, 19, 58, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,112, 51, 0,112, 14, 52, + 84, 0, 0, 0,113, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 62, 0, 0, 61, 0, 0, 0, 0, 0, 0,114, 0, 90, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 61, 62, 0, 0, 62, 0, 89, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,114, 0, 0, 0, 0,115, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 78, 55, 0, 38, 1, 58, + 1, 58, 0, 0, 0, 0, 0, 88, 62, 0, 0, 0, 63, 89, 0, 0, + 0, 0, 0, 59,116, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,116, 0, 0, 0, 0, 61, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 78, 0, 0, 0, + 0, 0, 0, 0, 0, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 56, 0, 89, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 61, 0, 0, 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, + 0, 0, 0, 0, 0, 0, 0, 0, 8, 92, 0, 0, 0, 0, 0, 0, + 1, 90, 0, 0, 0, 0, 0, 0,117, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,118, 0,119,120,121,122, 0,105, 4,123, 49, 23, 0, + 0, 0, 0, 0, 0, 0, 38, 50, 0, 0, 0, 0, 38, 58, 0, 0, + 0, 0, 0, 0, 1, 90, 1, 1, 1, 1, 39, 1, 48,106, 90, 0, + 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 59, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,124, + 0, 0, 0, 0, 0, 0, 0,113, 0, 0, 0, 0, 19, 59, 0, 38, + 0, 81, 0, 0, 0, 0, 0, 0, 4,123, 0, 0, 0, 1,125, 0, + 0, 0, 0, 0, 0, 0, 0, 0,230,230,230,230,230,232,220,220, + 220,220,232,216,220,220,220,220,220,202,202,220,220,220,220,202, + 202,220,220,220, 1, 1, 1, 1, 1,220,220,220,220,230,230,230, + 230,240,230,220,220,220,230,230,230,220,220, 0,230,230,230,220, + 220,220,220,230,232,220,220,230,233,234,234,233,234,234,233,230, + 0, 0, 0,230, 0,220,230,230,230,230,220,230,230,230,222,220, + 230,230,220,220,230,222,228,230, 10, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 19, 20, 21, 22, 0, 23, 0, 24, 25, 0,230,220, 0, 18, + 30, 31, 32, 0, 0, 0, 0, 27, 28, 29, 30, 31, 32, 33, 34,230, + 230,220,220,230,220,230,230,220, 35, 0, 0, 0, 0, 0,230,230, + 230, 0, 0,230,230, 0,220,230,230,220, 0, 0, 0, 36, 0, 0, + 230,220,230,230,220,220,230,220,220,230,220,230,220,230,230, 0, + 0,220, 0, 0,230,230, 0,230, 0,230,230,230,230,230, 0, 0, + 0,220,220,220,230,220,220,220,230,230, 0,220, 27, 28, 29,230, + 7, 0, 0, 0, 0, 9, 0, 0, 0,230,220,230,230, 0, 0, 0, + 0, 0,230, 0, 0, 84, 91, 0, 0, 0, 0, 9, 9, 0, 0, 0, + 0, 0, 9, 0,103,103, 9, 0,107,107,107,107,118,118, 9, 0, + 122,122,122,122,220,220, 0, 0, 0,220, 0,220, 0,216, 0, 0, + 0,129,130, 0,132, 0, 0, 0, 0, 0,130,130,130,130, 0, 0, + 130, 0,230,230, 9, 0,230,230, 0, 0,220, 0, 0, 0, 0, 7, + 0, 9, 9, 0, 9, 9, 0, 0, 0,230, 0, 0, 0,228, 0, 0, + 0,222,230,220,220, 0, 0, 0,230, 0, 0,220,230,220, 0,220, + 230,230,230,234, 0, 0, 9, 9, 0, 0, 7, 0,230,230,230, 0, 230, 0, 1, 1, 1, 0, 0, 0,230,234,214,220,202,230,230,230, 230,230,232,228,228,220,218,230,233,220,230,220,230,230, 1, 1, 1, 1, 1,230, 0, 1, 1,230,220,230, 1, 1, 0, 0,218,228, @@ -1362,63 +1482,81 @@ static const uint8_t _hb_ucd_u8[17612]= 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 34, 9, 0, 0, 20, 20, 1, 20, 20, 0, 0, 0, 0, 0, 0, 0, 26, 21, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 47, 48, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 13, 13, 13, 13, 13, 14, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 15, 16, 17, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, 20, 20, 20, 20, 20, 20, - 20, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 20, 33, - 34, 35, 34, 34, 36, 37, 20, 20, 20, 20, 20, 20, 38, 20, 39, 40, - 41, 41, 41, 41, 41, 42, 43, 44, 20, 20, 20, 20, 20, 20, 20, 45, - 46, 20, 20, 47, 20, 20, 20, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 59, 20, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 9, 10, 11, 11, 11, 11, 12, 13, + 13, 13, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 13, 13, 13, + 24, 25, 26, 26, 26, 27, 13, 13, 13, 28, 29, 30, 13, 31, 32, 33, + 34, 35, 36, 37, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 38, 7, 7, 39, 7, 40, 7, 7, + 7, 41, 13, 42, 7, 7, 43, 7, 7, 7, 44, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 60, 13, 13, - 13, 61, 62, 13, 13, 13, 13, 63, 13, 13, 13, 13, 13, 13, 64, 65, - 20, 20, 66, 20, 13, 13, 13, 13, 67, 13, 13, 13, 68, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 69, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 45, 0, 0, 1, 2, 2, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 32, 32, 33, 34, 35, 36, 37, 37, + 37, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 2, 2, 53, 54, 55, 56, 57, 58, 59, 59, 59, 59, 60, 59, + 59, 59, 59, 59, 59, 59, 61, 61, 59, 59, 59, 59, 62, 59, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 59, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 78, 69, 69, 69, 69, 79, 79, 79, 79, 79, 79, 79, 79, 79, 80, + 81, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 94, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 69, 69, 96, 97, 98, 99, 99, 99, + 100,101,102,103,104,105,106,107,108,109, 95,110,111,112,113,114, + 115,116,117,117,118,119,120,121,122,123,124,125,126,127,128,129, + 130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145, + 95,146,147,148,149, 95,150,151,152,153,154,155,156,157,158,159, + 160,161, 95,162,163,164,165,165,165,165,165,165,165,166,167,165, + 168, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95,169,170,170,170,170,170,170,170,170,171,170, + 170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170, + 170,170,170,170,170,170,170,170,170,170,170,170,170,172,173,173, + 173,173,174, 95, 95, 95, 95, 95,175, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95,176,176,176,176,177,178,179,180, 95, 95, + 181, 95,182,183,184,185,186,186,186,186,186,186,186,186,186,186, + 186,186,186,186,186,186,186,186,186,186,186,186,187,187,187,188, + 189,190, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95,191,192,193,194,195,195,196, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,197,198, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 59,199, + 59, 59, 59,200,201,202, 59,203,204,205,206,207,208, 95,209,210, + 211, 59, 59,212, 59,213,214,214,214,214,214,215, 95, 95, 95, 95, + 95, 95, 95, 95,216, 95,217,218,219, 95, 95,220, 95, 95, 95,221, + 95,222, 95,223, 95,224,225,226,227, 95, 95, 95, 95, 95,228,229, + 230, 95,231,232, 95, 95,233,234, 59,235,236, 95, 59, 59, 59, 59, + 59, 59, 59,237, 59,238,239,240, 59, 59,241,242, 59,243, 95, 95, + 95, 95, 95, 95, 95, 95, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69,244, 69, 69,245, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69,246, 69, 69, 69, 69, 69, 69, 69, 69, 69,247, 69, 69, + 69, 69,248, 95, 95, 95, 69, 69, 69, 69,249, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 69, 69, 69, 69, 69, 69,250, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,251, 95, + 95, 95, 95, 95, 95, 95,252, 95,253,254, 0, 1, 2, 2, 0, 1, + 2, 2, 2, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 0, 19, 0, 0, 0, 0, 0, 0, 0, 19, 19, @@ -1443,46 +1581,46 @@ static const uint8_t _hb_ucd_u8[17612]= 64, 2, 2, 64, 64, 64, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 2, 2, 90, 90, 90, 90, 90, 90, 90, 2, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 2, 2, 95, 2, 37, 37, - 37, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, - 2, 2, 2, 2, 2, 3, 3, 3, 0, 3, 3, 3, 3, 3, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 1, 1, 1, 1, 7, 7, 7, 7, 7, - 7, 7, 0, 0, 7, 7, 5, 5, 5, 5, 2, 5, 5, 5, 5, 5, - 5, 5, 5, 2, 2, 5, 5, 2, 2, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 2, 5, 5, 5, 5, 5, 5, 5, 2, - 5, 2, 2, 2, 5, 5, 5, 5, 2, 2, 5, 5, 5, 5, 5, 2, - 2, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 5, 2, 2, - 2, 2, 5, 5, 2, 5, 5, 5, 5, 5, 2, 2, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 2, 2, 11, 11, 11, 2, 11, 11, 11, 11, 11, - 11, 2, 2, 2, 2, 11, 11, 2, 2, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 2, 11, 11, 11, 11, 11, 11, 11, 2, - 11, 11, 2, 11, 11, 2, 11, 11, 2, 2, 11, 2, 11, 11, 11, 2, - 2, 11, 11, 11, 2, 2, 2, 11, 2, 2, 2, 2, 2, 2, 2, 11, - 11, 11, 11, 2, 11, 2, 2, 2, 2, 2, 2, 2, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 2, 2, 10, 10, 10, 2, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 2, 10, 10, 10, 2, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 2, 10, 10, 10, 10, 10, 10, 10, 2, - 10, 10, 2, 10, 10, 10, 10, 10, 2, 2, 10, 10, 10, 10, 10, 10, - 2, 10, 10, 10, 2, 2, 10, 2, 2, 2, 2, 2, 2, 2, 10, 10, - 10, 10, 2, 2, 10, 10, 10, 10, 2, 2, 2, 2, 2, 2, 2, 10, - 10, 10, 10, 10, 10, 10, 2, 21, 21, 21, 2, 21, 21, 21, 21, 21, - 21, 21, 21, 2, 2, 21, 21, 2, 2, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 2, 21, 21, 21, 21, 21, 21, 21, 2, - 21, 21, 2, 21, 21, 21, 21, 21, 2, 2, 21, 21, 21, 21, 21, 2, - 2, 21, 21, 21, 2, 2, 2, 2, 2, 2, 2, 21, 21, 21, 2, 2, - 2, 2, 21, 21, 2, 21, 21, 21, 21, 21, 2, 2, 21, 21, 2, 2, - 22, 22, 2, 22, 22, 22, 22, 22, 22, 2, 2, 2, 22, 22, 22, 2, - 22, 22, 22, 22, 2, 2, 2, 22, 22, 2, 22, 2, 22, 22, 2, 2, - 2, 22, 22, 2, 2, 2, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 2, 2, 2, 2, 22, 22, 22, 2, 2, 2, 2, 2, 2, 22, 2, 2, - 2, 2, 2, 2, 22, 22, 22, 22, 22, 2, 2, 2, 2, 2, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 2, 23, 23, 23, 2, - 23, 23, 23, 23, 23, 23, 23, 23, 2, 2, 23, 23, 23, 23, 23, 2, - 23, 23, 23, 23, 2, 2, 2, 2, 2, 2, 2, 23, 23, 2, 23, 23, - 23, 2, 2, 23, 2, 2, 23, 23, 23, 23, 2, 2, 23, 23, 2, 2, - 2, 2, 2, 2, 2, 23, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 2, 16, 16, 16, 2, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 2, 16, 16, 16, 16, 16, 2, 2, 16, 16, 16, 16, 16, 2, - 16, 16, 16, 16, 2, 2, 2, 2, 2, 2, 2, 16, 16, 2, 16, 16, + 37, 2, 2, 2, 2, 2, 3, 3, 2, 2, 2, 2, 2, 3, 3, 3, + 0, 3, 3, 3, 3, 3, 7, 7, 7, 7, 7, 7, 7, 7, 7, 1, + 1, 1, 1, 7, 7, 7, 7, 7, 7, 7, 0, 0, 7, 7, 5, 5, + 5, 5, 2, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 5, 5, 2, + 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, + 5, 5, 5, 5, 5, 5, 5, 2, 5, 2, 2, 2, 5, 5, 5, 5, + 2, 2, 5, 5, 5, 5, 5, 2, 2, 5, 5, 5, 5, 2, 2, 2, + 2, 2, 2, 2, 2, 5, 2, 2, 2, 2, 5, 5, 2, 5, 5, 5, + 5, 5, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 11, + 11, 11, 2, 11, 11, 11, 11, 11, 11, 2, 2, 2, 2, 11, 11, 2, + 2, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 2, + 11, 11, 11, 11, 11, 11, 11, 2, 11, 11, 2, 11, 11, 2, 11, 11, + 2, 2, 11, 2, 11, 11, 11, 2, 2, 11, 11, 11, 2, 2, 2, 11, + 2, 2, 2, 2, 2, 2, 2, 11, 11, 11, 11, 2, 11, 2, 2, 2, + 2, 2, 2, 2, 11, 11, 11, 11, 11, 11, 11, 11, 11, 2, 2, 10, + 10, 10, 2, 10, 10, 10, 10, 10, 10, 10, 10, 10, 2, 10, 10, 10, + 2, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 2, + 10, 10, 10, 10, 10, 10, 10, 2, 10, 10, 2, 10, 10, 10, 10, 10, + 2, 2, 10, 10, 10, 10, 10, 10, 2, 10, 10, 10, 2, 2, 10, 2, + 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 2, 2, 10, 10, 10, 10, + 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 2, 21, + 21, 21, 2, 21, 21, 21, 21, 21, 21, 21, 21, 2, 2, 21, 21, 2, + 2, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 2, + 21, 21, 21, 21, 21, 21, 21, 2, 21, 21, 2, 21, 21, 21, 21, 21, + 2, 2, 21, 21, 21, 21, 21, 2, 2, 21, 21, 21, 2, 2, 2, 2, + 2, 2, 2, 21, 21, 21, 2, 2, 2, 2, 21, 21, 2, 21, 21, 21, + 21, 21, 2, 2, 21, 21, 2, 2, 22, 22, 2, 22, 22, 22, 22, 22, + 22, 2, 2, 2, 22, 22, 22, 2, 22, 22, 22, 22, 2, 2, 2, 22, + 22, 2, 22, 2, 22, 22, 2, 2, 2, 22, 22, 2, 2, 2, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 2, 2, 2, 2, 22, 22, 22, 2, + 2, 2, 2, 2, 2, 22, 2, 2, 2, 2, 2, 2, 22, 22, 22, 22, + 22, 2, 2, 2, 2, 2, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 2, 23, 23, 23, 2, 23, 23, 23, 23, 23, 23, 23, 23, + 2, 2, 23, 23, 23, 23, 23, 2, 23, 23, 23, 23, 2, 2, 2, 2, + 2, 2, 2, 23, 23, 2, 23, 23, 23, 2, 23, 23, 2, 2, 23, 23, + 23, 23, 2, 2, 23, 23, 2, 2, 2, 2, 2, 2, 2, 23, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2, 16, 16, 16, 2, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2, 16, 16, 16, 16, 16, + 2, 2, 16, 16, 16, 16, 16, 2, 16, 16, 16, 16, 2, 2, 2, 2, + 2, 2, 2, 16, 16, 2, 2, 2, 2, 2, 16, 16, 16, 2, 16, 16, 16, 16, 2, 2, 16, 16, 2, 16, 16, 16, 2, 2, 2, 2, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 2, 20, 20, 20, 2, 20, 20, 20, 20, 20, 20, 2, 2, 2, 2, 20, 20, 20, 20, 20, 20, @@ -1529,137 +1667,135 @@ static const uint8_t _hb_ucd_u8[17612]= 54, 54, 2, 2, 54, 54, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 2, 91, 91, 91, 91, 91, 2, 2, 91, 91, 91, 2, 2, 2, 2, 2, 2, 91, 91, 91, 91, 91, 91, 2, 2, 1, 1, - 1, 1, 1, 1, 1, 2, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 2, 62, 62, 76, 76, 76, 76, 76, 76, 76, 76, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 2, 2, 2, 2, 2, 2, - 2, 2, 93, 93, 93, 93, 70, 70, 70, 70, 70, 70, 70, 70, 2, 2, - 2, 70, 70, 70, 70, 70, 70, 70, 2, 2, 2, 70, 70, 70, 73, 73, - 73, 73, 73, 73, 73, 73, 6, 6, 6, 2, 2, 2, 2, 2, 8, 8, - 8, 2, 2, 8, 8, 8, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 1, 1, 0, 2, 2, 2, 2, 2, 19, 19, - 19, 19, 19, 19, 9, 9, 9, 9, 9, 6, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 9, 9, 9, 9, 9, 19, 19, 19, 19, 9, 9, 9, 9, - 9, 19, 19, 19, 19, 19, 6, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 9, 9, 9, 9, 9, 9, 9, 2, 2, 2, 9, - 2, 9, 2, 9, 2, 9, 9, 9, 9, 9, 9, 2, 9, 9, 9, 9, - 9, 9, 2, 2, 9, 9, 9, 9, 9, 9, 2, 9, 9, 9, 2, 2, - 9, 9, 9, 2, 9, 9, 9, 9, 9, 9, 9, 9, 9, 2, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 19, - 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, - 0, 0, 0, 0, 0, 2, 19, 19, 19, 19, 19, 2, 2, 2, 0, 2, - 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 0, 0, - 0, 0, 0, 0, 9, 0, 0, 0, 19, 19, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 19, 0, 19, 0, 0, 0, 2, 2, 2, 2, 0, 0, - 2, 2, 2, 2, 2, 2, 0, 0, 0, 2, 2, 2, 2, 2, 27, 27, - 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 2, 0, 56, 56, 56, 56, 56, 56, 56, 56, 55, 55, - 55, 55, 2, 2, 2, 2, 2, 55, 55, 55, 55, 55, 55, 55, 61, 61, - 61, 61, 61, 61, 61, 61, 2, 2, 2, 2, 2, 2, 2, 61, 61, 2, - 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 2, 2, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 2, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 2, 2, 2, 2, 13, 13, 13, 13, 13, 13, 2, 2, 0, 0, - 0, 0, 0, 13, 0, 13, 0, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 1, 1, 1, 1, 12, 12, 13, 13, 13, 13, 0, 0, 0, 0, 2, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 2, 2, 1, 1, 0, 0, 15, 15, 15, 0, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 0, 0, 17, 17, 17, 2, 2, 2, 2, 2, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 2, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 2, 2, 2, 2, 2, 2, 2, 2, 0, 12, 12, - 12, 12, 12, 12, 12, 0, 17, 17, 17, 17, 17, 17, 17, 0, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 2, 2, 2, 39, 39, - 39, 39, 39, 39, 39, 2, 86, 86, 86, 86, 86, 86, 86, 86, 77, 77, - 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 2, 2, 2, 2, 79, 79, - 79, 79, 79, 79, 79, 79, 0, 0, 19, 19, 19, 19, 19, 19, 0, 0, - 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 2, 2, 19, 19, - 2, 19, 2, 19, 19, 19, 2, 2, 19, 19, 19, 19, 19, 19, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 2, 2, 2, 65, 65, - 65, 65, 65, 65, 65, 65, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, - 75, 75, 75, 75, 2, 2, 2, 2, 2, 2, 2, 2, 75, 75, 75, 75, - 2, 2, 2, 2, 2, 2, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 0, 69, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 74, 12, 12, - 12, 12, 12, 2, 2, 2, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 2, 0, 84, 84, 2, 2, 2, 2, 84, 84, 33, 33, - 33, 33, 33, 33, 33, 2, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 2, 68, 68, 68, 68, 68, 68, 2, 2, 68, 68, - 2, 2, 68, 68, 68, 68, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 2, 2, 2, 2, 2, 2, 2, 2, 92, 92, 92, 92, 92, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 2, 2, 30, - 30, 30, 30, 30, 30, 2, 19, 19, 19, 0, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 9, 19, 19, 19, 19, 0, 0, 2, 2, 2, 2, 87, 87, - 87, 87, 87, 87, 2, 2, 87, 87, 2, 2, 2, 2, 2, 2, 12, 12, - 12, 12, 2, 2, 2, 2, 2, 2, 2, 12, 12, 12, 12, 12, 13, 13, - 2, 2, 2, 2, 2, 2, 19, 19, 19, 19, 19, 19, 19, 2, 2, 2, - 2, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 2, 14, 14, 14, 14, 14, 2, 14, 2, 14, 14, - 2, 14, 14, 2, 14, 14, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, - 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 2, 2, - 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 3, 1, 1, - 1, 1, 1, 1, 6, 6, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, - 0, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, - 3, 3, 3, 2, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 2, 2, - 12, 12, 12, 12, 12, 12, 2, 2, 12, 12, 12, 2, 2, 2, 2, 0, - 0, 0, 0, 0, 2, 2, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 2, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 2, 49, 49, - 49, 2, 49, 49, 2, 49, 49, 49, 49, 49, 49, 49, 2, 2, 49, 49, - 49, 2, 2, 2, 2, 2, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, - 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 2, 2, 2, 9, 2, - 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 1, 2, 2, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 2, 2, 2, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 2, 2, 2, 2, 2, 2, 2, 1, 0, - 0, 0, 0, 0, 0, 0, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, - 42, 42, 2, 2, 2, 2, 2, 2, 2, 2, 2, 42, 42, 42, 41, 41, - 41, 41, 41, 41, 41, 41, 41, 41, 41, 2, 2, 2, 2, 2,118,118, - 118,118,118,118,118,118,118,118,118, 2, 2, 2, 2, 2, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 2, 53, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 2, 2, 2, 2, 59, 59, - 59, 59, 59, 59, 2, 2, 40, 40, 40, 40, 40, 40, 40, 40, 51, 51, - 51, 51, 51, 51, 51, 51, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 2, 2, 50, 50, 2, 2, 2, 2, 2, 2,135,135, - 135,135,135,135,135,135,135,135,135,135, 2, 2, 2, 2,106,106, - 106,106,106,106,106,106,104,104,104,104,104,104,104,104,104,104, - 104,104, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,104,161,161, - 161,161,161,161,161,161,161,161,161, 2,161,161,161,161,161,161, - 161, 2,161,161, 2,161,161,161, 2,161,161,161,161,161,161,161, - 2,161,161, 2, 2, 2,170,170,170,170,170,170,170,170,170,170, - 170,170, 2, 2, 2, 2,110,110,110,110,110,110,110,110,110,110, - 110,110,110,110,110, 2,110,110,110,110,110,110, 2, 2, 19, 19, - 19, 19, 19, 19, 2, 19, 19, 2, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 2, 2, 2, 2, 2, 47, 47, 47, 47, 47, 47, 2, 2, 47, 2, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 2, 47, 47, 2, 2, 2, 47, 2, 2, 47, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 2, 81,120,120, - 120,120,120,120,120,120,116,116,116,116,116,116,116,116,116,116, - 116,116,116,116,116, 2, 2, 2, 2, 2, 2, 2, 2,116,128,128, - 128,128,128,128,128,128,128,128,128, 2,128,128, 2, 2, 2, 2, - 2,128,128,128,128,128, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 2, 2, 2, 66, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 2, 2, 2, 2, 2, 72, 98, 98, 98, 98, 98, 98, 98, 98, 97, 97, - 97, 97, 97, 97, 97, 97, 2, 2, 2, 2, 97, 97, 97, 97, 2, 2, - 97, 97, 97, 97, 97, 97, 57, 57, 57, 57, 2, 57, 57, 2, 2, 2, - 2, 2, 57, 57, 57, 57, 57, 57, 57, 57, 2, 57, 57, 57, 2, 57, - 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 2, 2, 57, 57, 57, 2, 2, 2, 2, 57, 57, 2, - 2, 2, 2, 2, 2, 2, 88, 88, 88, 88, 88, 88, 88, 88,117,117, - 117,117,117,117,117,117,112,112,112,112,112,112,112,112,112,112, - 112,112,112,112,112, 2, 2, 2, 2,112,112,112,112,112, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 2, 2, 2, 78, - 78, 78, 78, 78, 78, 78, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 2, 2, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 2, 2, 2, 2, 2,122,122,122,122,122,122,122,122,122,122, - 2, 2, 2, 2, 2, 2, 2,122,122,122,122, 2, 2, 2, 2,122, - 122,122,122,122,122,122, 89, 89, 89, 89, 89, 89, 89, 89, 89, 2, - 2, 2, 2, 2, 2, 2,130,130,130,130,130,130,130,130,130,130, - 130, 2, 2, 2, 2, 2, 2, 2,130,130,130,130,130,130,144,144, - 144,144,144,144,144,144,144,144, 2, 2, 2, 2, 2, 2,165,165, - 165,165,165,165,165,165,165,165,165,165,165,165, 2, 2, 2,165, - 165,165,165,165,165,165, 2, 2, 2, 2, 2, 2,165,165,156,156, + 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 2, 62, 62, 76, 76, + 76, 76, 76, 76, 76, 76, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 2, 2, 2, 2, 2, 2, 2, 2, 93, 93, 93, 93, 70, 70, + 70, 70, 70, 70, 70, 70, 2, 2, 2, 70, 70, 70, 70, 70, 70, 70, + 2, 2, 2, 70, 70, 70, 73, 73, 73, 73, 73, 73, 73, 73, 6, 6, + 6, 2, 2, 2, 2, 2, 8, 8, 8, 2, 2, 8, 8, 8, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, + 0, 2, 2, 2, 2, 2, 19, 19, 19, 19, 19, 19, 9, 9, 9, 9, + 9, 6, 19, 19, 19, 19, 19, 19, 19, 19, 19, 9, 9, 9, 9, 9, + 19, 19, 19, 19, 9, 9, 9, 9, 9, 19, 19, 19, 19, 19, 6, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 9, 9, 9, + 9, 9, 9, 9, 2, 2, 2, 9, 2, 9, 2, 9, 2, 9, 9, 9, + 9, 9, 9, 2, 9, 9, 9, 9, 9, 9, 2, 2, 9, 9, 9, 9, + 9, 9, 2, 9, 9, 9, 2, 2, 9, 9, 9, 2, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 2, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0, 19, 2, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 2, 19, 19, + 19, 19, 19, 2, 2, 2, 0, 0, 2, 2, 2, 2, 2, 2, 1, 2, + 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, + 19, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 19, 0, + 0, 0, 2, 2, 2, 2, 0, 0, 0, 2, 2, 2, 2, 2, 27, 27, + 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 2, 2, 0, 0, 56, 56, + 56, 56, 56, 56, 56, 56, 55, 55, 55, 55, 2, 2, 2, 2, 2, 55, + 55, 55, 55, 55, 55, 55, 61, 61, 61, 61, 61, 61, 61, 61, 2, 2, + 2, 2, 2, 2, 2, 61, 61, 2, 2, 2, 2, 2, 2, 2, 0, 0, + 0, 0, 0, 0, 2, 2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 2, 2, 2, 2, 13, 13, + 13, 13, 13, 13, 2, 2, 0, 0, 0, 0, 0, 13, 0, 13, 0, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 1, 1, 1, 1, 12, 12, 13, 13, + 13, 13, 0, 0, 0, 0, 2, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 2, 2, 1, + 1, 0, 0, 15, 15, 15, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 17, 17, 17, 2, 2, + 2, 2, 2, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 2, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 2, 2, 2, + 2, 2, 2, 2, 2, 0, 12, 12, 12, 12, 12, 12, 12, 0, 17, 17, + 17, 17, 17, 17, 17, 0, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 2, 2, 2, 39, 39, 39, 39, 39, 39, 39, 2, 86, 86, + 86, 86, 86, 86, 86, 86, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 2, 2, 2, 2, 79, 79, 79, 79, 79, 79, 79, 79, 0, 0, + 19, 19, 19, 19, 19, 19, 0, 0, 0, 19, 19, 19, 19, 19, 2, 19, + 19, 19, 19, 19, 19, 19, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 2, 2, 2, 65, 65, 65, 65, 65, 65, 65, 65, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 2, 2, 2, 2, + 2, 2, 2, 2, 75, 75, 75, 75, 2, 2, 2, 2, 2, 2, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 0, 69, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 74, 12, 12, 12, 12, 12, 2, 2, 2, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 2, 0, 84, 84, + 2, 2, 2, 2, 84, 84, 33, 33, 33, 33, 33, 33, 33, 2, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 2, 68, 68, + 68, 68, 68, 68, 2, 2, 68, 68, 2, 2, 68, 68, 68, 68, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 2, 2, 2, 2, 2, 2, 2, + 2, 92, 92, 92, 92, 92, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 2, 2, 30, 30, 30, 30, 30, 30, 2, 19, 19, + 19, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 9, 19, 19, 19, 19, + 0, 0, 2, 2, 2, 2, 87, 87, 87, 87, 87, 87, 2, 2, 87, 87, + 2, 2, 2, 2, 2, 2, 12, 12, 12, 12, 2, 2, 2, 2, 2, 2, + 2, 12, 12, 12, 12, 12, 13, 13, 2, 2, 2, 2, 2, 2, 19, 19, + 19, 19, 19, 19, 19, 2, 2, 2, 2, 4, 4, 4, 4, 4, 2, 2, + 2, 2, 2, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 2, 14, 14, + 14, 14, 14, 2, 14, 2, 14, 14, 2, 14, 14, 2, 14, 14, 3, 3, + 3, 3, 3, 3, 0, 0, 1, 1, 1, 1, 1, 1, 6, 6, 0, 0, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 3, 3, + 3, 3, 3, 2, 3, 3, 3, 3, 3, 3, 3, 2, 2, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, + 17, 17, 17, 17, 0, 0, 2, 2, 12, 12, 12, 12, 12, 12, 2, 2, + 12, 12, 12, 2, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 2, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 2, 49, 49, 49, 2, 49, 49, 2, 49, 49, 49, + 49, 49, 49, 49, 2, 2, 49, 49, 49, 2, 2, 2, 2, 2, 0, 0, + 0, 2, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, + 0, 0, 0, 2, 2, 2, 9, 2, 2, 2, 2, 2, 2, 2, 0, 0, + 0, 0, 0, 1, 2, 2, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 2, 2, 2, 67, 67, 67, 67, 67, 67, 67, 67, 67, 2, + 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 42, 42, 42, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 2, 2, 2, 2, 2,118,118,118,118,118,118,118,118,118,118, + 118, 2, 2, 2, 2, 2, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 53, 53, 2, 53, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, + 59, 59, 2, 2, 2, 2, 59, 59, 59, 59, 59, 59, 2, 2, 40, 40, + 40, 40, 40, 40, 40, 40, 51, 51, 51, 51, 51, 51, 51, 51, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 2, 2, 50, 50, + 2, 2, 2, 2, 2, 2,135,135,135,135,135,135,135,135,135,135, + 135,135, 2, 2, 2, 2,106,106,106,106,106,106,106,106,104,104, + 104,104,104,104,104,104,104,104,104,104, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2,104,161,161,161,161,161,161,161,161,161,161, + 161, 2,161,161,161,161,161,161,161, 2,161,161, 2,161,161,161, + 2,161,161,161,161,161,161,161, 2,161,161, 2, 2, 2,170,170, + 170,170,170,170,170,170,170,170,170,170, 2, 2, 2, 2,110,110, + 110,110,110,110,110,110,110,110,110,110,110,110,110, 2,110,110, + 110,110,110,110, 2, 2, 19, 19, 19, 19, 19, 19, 2, 19, 19, 2, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 2, 2, 2, 2, 2, 47, 47, + 47, 47, 47, 47, 2, 2, 47, 2, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 2, 47, 47, 2, + 2, 2, 47, 2, 2, 47, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 2, 81,120,120,120,120,120,120,120,120,116,116, + 116,116,116,116,116,116,116,116,116,116,116,116,116, 2, 2, 2, + 2, 2, 2, 2, 2,116,128,128,128,128,128,128,128,128,128,128, + 128, 2,128,128, 2, 2, 2, 2, 2,128,128,128,128,128, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 2, 2, 2, 66, 72, 72, + 72, 72, 72, 72, 72, 72, 72, 72, 2, 2, 2, 2, 2, 72,173,173, + 173,173,173,173,173,173,173,173, 2, 2, 2, 2, 2, 2, 98, 98, + 98, 98, 98, 98, 98, 98, 97, 97, 97, 97, 97, 97, 97, 97, 2, 2, + 2, 2, 97, 97, 97, 97, 2, 2, 97, 97, 97, 97, 97, 97, 57, 57, + 57, 57, 2, 57, 57, 2, 2, 2, 2, 2, 57, 57, 57, 57, 57, 57, + 57, 57, 2, 57, 57, 57, 2, 57, 57, 57, 57, 57, 57, 57, 57, 57, + 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 2, 2, 57, 57, + 57, 2, 2, 2, 2, 57, 57, 2, 2, 2, 2, 2, 2, 2, 88, 88, + 88, 88, 88, 88, 88, 88,117,117,117,117,117,117,117,117,112,112, + 112,112,112,112,112,112,112,112,112,112,112,112,112, 2, 2, 2, + 2,112,112,112,112,112, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, + 78, 78, 78, 78, 2, 2, 2, 78, 78, 78, 78, 78, 78, 78, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 2, 2, 82, 82, + 82, 82, 82, 82, 82, 82, 82, 82, 82, 2, 2, 2, 2, 2,122,122, + 122,122,122,122,122,122,122,122, 2, 2, 2, 2, 2, 2, 2,122, + 122,122,122, 2, 2, 2, 2,122,122,122,122,122,122,122, 89, 89, + 89, 89, 89, 89, 89, 89, 89, 2, 2, 2, 2, 2, 2, 2,130,130, + 130,130,130,130,130,130,130,130,130, 2, 2, 2, 2, 2, 2, 2, + 130,130,130,130,130,130,144,144,144,144,144,144,144,144,144,144, + 2, 2, 2, 2, 2, 2,165,165,165,165,165,165,165,165,165,165, + 165,165,165,165, 2, 2, 2,165,165,165,165,165,165,165, 2, 2, + 2, 2, 2, 2,165,165, 3, 3, 3, 3, 3, 3, 3, 2,156,156, 156,156,156,156,156,156,156,156, 2,156,156,156, 2, 2,156,156, - 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 2, 2, 2, 2, 2, - 2, 2, 3, 3, 3, 3,147,147,147,147,147,147,147,147,148,148, + 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 2, + 2, 2, 2, 2, 2, 2,147,147,147,147,147,147,147,147,148,148, 148,148,148,148,148,148,148,148, 2, 2, 2, 2, 2, 2,158,158, 158,158,158,158,158,158,158,158, 2, 2, 2, 2, 2, 2,153,153, 153,153,153,153,153,153,153,153,153,153, 2, 2, 2, 2,149,149, @@ -1718,46 +1854,51 @@ static const uint8_t _hb_ucd_u8[17612]= 143,143,143,143, 2,143,143, 2,143,143,143,143,143,143,143,143, 143,143,143,143,143,143,143,143,143,143,143,143,143, 2,143,143, 2,143,143,143,143,143,143, 2, 2, 2, 2, 2, 2, 2,143,143, - 2, 2, 2, 2, 2, 2,145,145,145,145,145,145,145,145,145, 2, - 2, 2, 2, 2, 2, 2,163,163,163,163,163,163,163,163,163, 2, - 163,163,163,163,163,163,163,163,163, 2, 2, 2,163,163,163,163, - 163, 2, 2, 2, 2, 2, 86, 2, 2, 2, 2, 2, 2, 2, 22, 22, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 22, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, 2, 2, 2, 2, 2, 2, 63, 63, - 63, 63, 63, 63, 63, 2, 63, 63, 63, 63, 63, 2, 2, 2, 63, 63, - 63, 63, 2, 2, 2, 2,157,157,157,157,157,157,157,157,157,157, - 157, 2, 2, 2, 2, 2, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 2, 2, 80, 80, 80, 2, 2, 2, 2, 2,127,127, - 127,127,127,127,127,127,127,127,127,127,127,127,127, 2,166,166, - 166,166,166,166,166,166,166,166, 2, 2, 2, 2, 2, 2, 79, 2, - 2, 2, 2, 2, 2, 2,115,115,115,115,115,115,115,115,115,115, - 115,115,115,115,115, 2,115,115, 2, 2, 2, 2,115,115,159,159, - 159,159,159,159,159,159,159,159,159,159,159,159,159, 2,159,159, - 2, 2, 2, 2, 2, 2,103,103,103,103,103,103,103,103,103,103, - 103,103,103,103, 2, 2,119,119,119,119,119,119,119,119,119,119, - 119,119,119,119, 2, 2,119,119, 2,119,119,119,119,119, 2, 2, - 2, 2, 2,119,119,119,167,167,167,167,167,167,167,167,167,167, - 2, 2, 2, 2, 2, 2,146,146,146,146,146,146,146,146,146,146, - 146, 2, 2, 2, 2, 2, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 2, 2, 2, 2, 2, 2,175,175,175,175,175,175,175,175,175,175, + 175,175, 2, 2, 2, 2,175,175, 2, 2, 2, 2, 2, 2,145,145, + 145,145,145,145,145,145,145, 2, 2, 2, 2, 2, 2, 2,163,163, + 163,163,163,163,163,163,163, 2,163,163,163,163,163,163,163,163, + 163, 2, 2, 2,163,163,163,163,163, 2, 2, 2, 2, 2, 86, 2, + 2, 2, 2, 2, 2, 2, 22, 22, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 22, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, + 2, 2, 2, 2, 2, 2, 63, 63, 63, 63, 63, 63, 63, 2, 63, 63, + 63, 63, 63, 2, 2, 2, 63, 63, 63, 63, 2, 2, 2, 2,157,157, + 157,157,157,157,157,157,157,157,157, 2, 2, 2, 2, 2, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 2, 2, 80, 80, + 80, 2, 2, 2, 2, 2,127,127,127,127,127,127,127,127,127,127, + 127,127,127,127,127, 2,166,166,166,166,166,166,166,166,166,166, + 2, 2, 2, 2, 2, 2, 79, 2, 2, 2, 2, 2, 2, 2,115,115, + 115,115,115,115,115,115,115,115,115,115,115,115,115, 2,115,115, + 2, 2, 2, 2,115,115,159,159,159,159,159,159,159,159,159,159, + 159,159,159,159,159, 2,159,159, 2, 2, 2, 2, 2, 2,103,103, + 103,103,103,103,103,103,103,103,103,103,103,103, 2, 2,119,119, + 119,119,119,119,119,119,119,119,119,119,119,119, 2, 2,119,119, + 2,119,119,119,119,119, 2, 2, 2, 2, 2,119,119,119,167,167, + 167,167,167,167,167,167,167,167, 2, 2, 2, 2, 2, 2,146,146, + 146,146,146,146,146,146,146,146,146, 2, 2, 2, 2, 2,172,172, + 172,172,172,172,172,172,172, 2, 2,172,172,172,172,172,172,172, + 172,172, 2, 2, 2, 2, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 2, 2, 2, 2, 99, 2, 2, 2, 2, 2, 2, 2, 99,136,139, - 13, 13,155, 2, 2, 2,136,136,136,136,136,136,136,136,155,155, - 155,155,155,155,155,155,155,155,155,155,155,155, 2, 2, 2, 2, - 2, 2, 2, 2, 2,155,136, 2, 2, 2, 2, 2, 2, 2, 17, 17, + 13, 13,155, 2, 2, 2, 13, 13, 13, 13, 13, 13, 13, 2,136,136, + 136,136,136,136,136,136,155,155,155,155,155,155,155,155,155,155, + 155,155,155,155, 2, 2, 2, 2, 2, 2, 2, 2, 2,155,136,136, + 136,136,136,136,136, 2,136,136,136, 2, 2, 2, 2, 2, 17, 17, 17, 17, 2, 17, 17, 17, 17, 17, 17, 17, 2, 17, 17, 2, 17, 15, 15, 15, 15, 15, 15, 15, 17, 17, 17, 2, 2, 2, 2, 2, 2, 2, 15, 2, 2, 2, 2, 2, 15, 15, 15, 2, 2, 17, 2, 2, 2, 2, 2, 2, 17, 17, 17, 17,139,139,139,139,139,139,139,139,139,139, 139,139, 2, 2, 2, 2,105,105,105,105,105,105,105,105,105,105, 105, 2, 2, 2, 2, 2,105,105,105,105,105, 2, 2, 2,105, 2, - 2, 2, 2, 2, 2, 2,105,105, 2, 2,105,105,105,105, 1, 1, - 1, 1, 1, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, + 2, 2, 2, 2, 2, 2,105,105, 2, 2,105,105,105,105, 2, 2, + 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 1, 1, + 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 2, 2, 0, 2, 2, 0, 0, 2, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, - 0, 0, 2, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, - 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 2, 2, 2, - 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0,131,131, + 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 0, 2, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, + 0, 0, 0, 2, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0,131,131, 131,131,131,131,131,131,131,131,131,131, 2, 2, 2, 2, 2, 2, 2,131,131,131,131,131, 2,131,131,131,131,131,131,131, 2, 2, 2, 2, 2, 19, 19, 19, 56, 56, 56, 56, 56, 56, 56, 2, 56, 2, @@ -1769,7 +1910,9 @@ static const uint8_t _hb_ucd_u8[17612]= 160,160,160,160,160, 2,152,152,152,152,152,152,152,152,152,152, 2, 2, 2, 2, 2,152,164,164,164,164,164,164,164,164,164,164, 2, 2, 2, 2, 2, 2,168,168,168,168,168,168,168,168,168,168, - 168, 2, 2, 2, 2,168, 30, 30, 30, 30, 2, 30, 30, 2,113,113, + 168, 2, 2, 2, 2,168,174,174,174,174,174,174,174,174,174,174, + 174,174,174,174,174, 2,174,174,174,174,174,174, 2, 2, 2, 2, + 2, 2, 2, 2,174,174, 30, 30, 30, 30, 2, 30, 30, 2,113,113, 113,113,113,113,113,113,113,113,113,113,113, 2, 2,113,113,113, 113,113,113,113,113, 2,132,132,132,132,132,132,132,132,132,132, 132,132, 2, 2, 2, 2,132,132, 2, 2, 2, 2,132,132, 3, 3, @@ -1780,8 +1923,8 @@ static const uint8_t _hb_ucd_u8[17612]= 3, 3, 3, 2, 3, 2, 3, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 15, 0, - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 2, 2, - 2, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, + 0, 2, 2, 2, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 13, 2, 2, 2, 2, 2, 2, 2, 13, 13, 13, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, 9, 10, 9, 11, 12, 13, @@ -1865,7 +2008,7 @@ static const uint8_t _hb_ucd_u8[17612]= 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, }; -static const uint16_t _hb_ucd_u16[10400]= +static const uint16_t _hb_ucd_u16[10832]= { 0, 0, 1, 2, 3, 4, 5, 6, 0, 0, 7, 8, 9, 10, 11, 12, 13, 13, 13, 14, 15, 13, 13, 16, 17, 18, 19, 20, 21, 22, 13, 23, @@ -1888,27 +2031,29 @@ static const uint16_t _hb_ucd_u16[10400]= 48, 48, 48, 48, 168, 169, 48, 48, 168, 48, 48, 170, 171, 172, 48, 48, 48, 171, 48, 48, 48, 173, 174, 175, 48, 176, 9, 9, 9, 9, 9, 177, 178, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 179, 48, 180, 181, 48, 48, 48, 48, 182, 183, 48, 184, 48, 185, 48, 186, 187, 188, 48, 48, 48, 189, 190, 191, 192, 193, 194, 192, 48, 48, 195, 48, 48, 196, 197, 48, 198, 48, 48, 48, 48, 199, 48, 200, 201, 202, 203, 48, 204, 205, 48, 48, 206, 48, 207, 208, 209, 209, - 48, 210, 48, 48, 48, 211, 212, 213, 192, 192, 214, 215, 216, 140, 140, 140, - 217, 48, 48, 218, 219, 160, 220, 221, 222, 48, 223, 64, 48, 48, 224, 225, - 48, 48, 226, 227, 228, 64, 48, 229, 230, 9, 9, 231, 232, 233, 234, 235, - 11, 11, 236, 27, 27, 27, 237, 238, 11, 239, 27, 27, 32, 32, 32, 32, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 240, 13, 13, 13, 13, 13, 13, - 241, 242, 241, 241, 242, 243, 241, 244, 245, 245, 245, 246, 247, 248, 249, 250, - 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 261, 262, 263, 264, 265, - 266, 267, 268, 269, 270, 271, 272, 272, 273, 274, 275, 209, 276, 277, 209, 278, - 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, - 280, 209, 281, 209, 209, 209, 209, 282, 209, 283, 279, 284, 209, 285, 286, 209, - 209, 209, 176, 140, 287, 140, 271, 271, 271, 288, 209, 209, 209, 209, 289, 271, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 290, 291, 209, 209, 292, - 209, 209, 209, 209, 209, 209, 293, 209, 209, 209, 209, 209, 209, 209, 209, 209, - 209, 209, 209, 209, 209, 209, 294, 295, 271, 296, 209, 209, 297, 279, 298, 279, + 48, 210, 48, 48, 48, 211, 212, 213, 192, 192, 214, 215, 32, 216, 217, 140, + 218, 48, 48, 219, 220, 160, 221, 222, 223, 48, 224, 64, 48, 48, 225, 226, + 48, 48, 227, 228, 229, 64, 48, 230, 231, 9, 9, 232, 233, 234, 235, 236, + 11, 11, 237, 27, 27, 27, 238, 239, 11, 240, 27, 27, 32, 32, 32, 32, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 241, 13, 13, 13, 13, 13, 13, + 242, 243, 242, 242, 243, 244, 242, 245, 246, 246, 246, 247, 248, 249, 250, 251, + 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 262, 263, 264, 265, 266, + 267, 268, 269, 270, 271, 272, 273, 273, 274, 275, 276, 209, 277, 278, 209, 279, + 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, + 281, 209, 282, 209, 209, 209, 209, 283, 209, 284, 280, 285, 209, 286, 287, 209, + 209, 209, 176, 140, 288, 140, 272, 272, 272, 289, 209, 209, 209, 209, 290, 272, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 291, 292, 209, 209, 293, + 209, 209, 209, 209, 209, 209, 294, 209, 209, 209, 209, 209, 209, 209, 209, 209, + 209, 209, 209, 209, 209, 209, 295, 296, 272, 297, 209, 209, 298, 280, 299, 280, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, - 279, 279, 279, 279, 279, 279, 279, 279, 299, 300, 279, 279, 279, 301, 279, 302, - 209, 209, 209, 279, 303, 209, 209, 304, 209, 305, 209, 209, 209, 209, 209, 209, + 280, 280, 280, 280, 280, 280, 280, 280, 300, 301, 280, 280, 280, 302, 280, 303, + 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, + 209, 209, 209, 280, 304, 209, 209, 305, 209, 209, 209, 209, 209, 209, 209, 209, 9, 9, 9, 11, 11, 11, 306, 307, 13, 13, 13, 13, 13, 13, 308, 309, 11, 11, 310, 48, 48, 48, 311, 312, 48, 313, 314, 314, 314, 314, 32, 32, 315, 316, 317, 318, 319, 320, 140, 140, 209, 321, 209, 209, 209, 209, 209, 322, @@ -1916,226 +2061,201 @@ static const uint16_t _hb_ucd_u16[10400]= 324, 325, 326, 327, 136, 48, 48, 48, 48, 328, 178, 48, 48, 48, 48, 329, 330, 48, 48, 136, 48, 48, 48, 48, 200, 331, 48, 48, 209, 209, 332, 48, 209, 333, 334, 209, 335, 336, 209, 209, 334, 209, 209, 336, 209, 209, 209, 209, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 209, 209, 209, 209, 48, 337, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 151, 209, 209, 209, 338, 48, 48, 229, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 151, 209, 209, 209, 338, 48, 48, 230, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 339, 48, 340, 140, 13, 13, 341, 342, 13, 343, 48, 48, 48, 48, 344, 345, 31, 346, 347, 348, 13, 13, 13, 349, 350, 351, 352, 353, 354, 355, 140, 356, 357, 48, 358, 359, 48, 48, 48, 360, 361, 48, 48, 362, 363, 192, 32, 364, 64, 48, 365, 48, 366, 367, 48, 151, 76, 48, 48, 368, 369, 370, 371, 372, 48, 48, 373, 374, 375, 376, 48, 377, 48, 48, 48, 378, 379, 380, 381, 382, 383, 384, 314, 11, 11, 385, 386, 11, 11, 11, 11, 11, 48, 48, 387, 192, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 388, 48, 389, 48, 48, 206, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, + 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, + 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, + 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 204, 48, 48, 48, 48, 48, 48, 207, 140, 140, 392, 393, 394, 395, 396, 48, 48, 48, 48, 48, 48, 397, 398, 399, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 400, 209, 48, 48, 48, 48, 401, 48, 48, 402, 140, 140, 403, 32, 404, 32, 405, 406, 407, 408, 409, 48, 48, 48, 48, 48, 48, 48, 410, 411, 2, 3, 4, 5, 412, 413, 414, 48, 415, 48, 200, 416, 417, 418, 419, 420, 48, 172, 421, 204, 204, 140, 140, 48, 48, 48, 48, 48, 48, 48, 71, - 422, 271, 271, 423, 272, 272, 272, 424, 425, 426, 427, 140, 140, 209, 209, 428, + 422, 272, 272, 423, 273, 273, 273, 424, 425, 426, 427, 140, 140, 209, 209, 428, 140, 140, 140, 140, 140, 140, 140, 140, 48, 151, 48, 48, 48, 100, 429, 430, 48, 48, 431, 48, 432, 48, 48, 433, 48, 434, 48, 48, 435, 436, 140, 140, 9, 9, 437, 11, 11, 48, 48, 48, 48, 204, 192, 9, 9, 438, 11, 439, 48, 48, 440, 48, 48, 48, 441, 442, 442, 443, 444, 445, 48, 48, 48, 388, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 313, 48, 199, 440, 140, 446, 27, 27, 447, 140, 140, 140, 140, 448, 48, 48, 449, 48, 450, 48, 451, 48, 200, 452, 140, 140, 140, 48, 453, - 48, 454, 48, 455, 140, 140, 140, 140, 48, 48, 48, 456, 271, 457, 271, 271, + 48, 454, 48, 455, 48, 207, 140, 140, 48, 48, 48, 456, 272, 457, 272, 272, 458, 459, 48, 460, 461, 462, 48, 463, 48, 464, 140, 140, 465, 48, 466, 467, 48, 48, 48, 468, 48, 469, 48, 470, 48, 471, 472, 140, 140, 140, 140, 140, 48, 48, 48, 48, 196, 140, 140, 140, 9, 9, 9, 473, 11, 11, 11, 474, 48, 48, 475, 192, 476, 9, 477, 11, 478, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 271, 479, 48, 48, 480, 481, 482, 140, 140, 483, - 48, 464, 484, 48, 62, 485, 140, 48, 486, 140, 140, 48, 487, 140, 48, 313, - 488, 48, 48, 489, 490, 457, 491, 492, 222, 48, 48, 493, 494, 48, 196, 192, - 495, 48, 496, 497, 498, 48, 48, 499, 222, 48, 48, 500, 501, 502, 503, 504, - 48, 97, 505, 506, 507, 140, 140, 140, 508, 509, 510, 48, 48, 511, 512, 192, - 513, 83, 84, 514, 515, 516, 517, 518, 519, 48, 48, 520, 521, 522, 523, 140, - 48, 48, 48, 524, 525, 526, 481, 140, 48, 48, 48, 527, 528, 192, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 48, 48, 529, 530, 531, 532, 140, 140, - 48, 48, 48, 533, 534, 192, 535, 140, 48, 48, 536, 537, 192, 538, 539, 140, - 48, 540, 541, 542, 313, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 48, 48, 505, 543, 140, 140, 140, 140, 140, 140, 9, 9, 11, 11, 148, 544, - 545, 546, 48, 547, 548, 192, 140, 140, 140, 140, 549, 48, 48, 550, 551, 140, - 552, 48, 48, 553, 554, 555, 48, 48, 556, 557, 558, 48, 48, 48, 48, 196, - 559, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 48, 560, 192, - 84, 48, 529, 561, 562, 148, 175, 563, 48, 564, 565, 566, 140, 140, 140, 140, - 567, 48, 48, 568, 569, 192, 570, 48, 571, 572, 192, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 573, - 574, 115, 48, 575, 576, 577, 140, 140, 140, 140, 140, 100, 271, 578, 579, 580, + 140, 140, 140, 140, 140, 140, 272, 479, 48, 48, 480, 481, 482, 483, 140, 484, + 48, 464, 485, 48, 62, 486, 140, 48, 487, 140, 140, 48, 488, 140, 48, 313, + 489, 48, 48, 490, 491, 457, 492, 493, 223, 48, 48, 494, 495, 48, 196, 192, + 496, 48, 497, 498, 499, 48, 48, 500, 223, 48, 48, 501, 502, 503, 504, 505, + 48, 97, 506, 507, 508, 140, 140, 140, 509, 510, 511, 48, 48, 512, 513, 192, + 514, 83, 84, 515, 516, 517, 518, 519, 520, 48, 48, 521, 522, 523, 524, 140, + 48, 48, 48, 525, 526, 527, 481, 140, 48, 48, 48, 528, 529, 192, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 48, 48, 530, 531, 532, 533, 140, 140, + 48, 48, 48, 534, 535, 192, 536, 140, 48, 48, 537, 538, 192, 539, 540, 140, + 48, 541, 542, 543, 313, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 48, 48, 506, 544, 140, 140, 140, 140, 140, 140, 9, 9, 11, 11, 148, 545, + 546, 547, 48, 548, 549, 192, 140, 140, 140, 140, 550, 48, 48, 551, 552, 140, + 553, 48, 48, 554, 555, 556, 48, 48, 557, 558, 559, 48, 48, 48, 48, 196, + 560, 140, 140, 140, 140, 140, 561, 140, 140, 140, 140, 140, 48, 48, 562, 192, + 84, 48, 530, 563, 564, 148, 175, 565, 48, 566, 567, 568, 140, 140, 140, 140, + 569, 48, 48, 570, 571, 192, 572, 48, 573, 574, 192, 48, 48, 575, 192, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 576, + 577, 115, 48, 578, 579, 580, 140, 140, 140, 140, 140, 100, 272, 581, 582, 583, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 207, 140, 140, 140, 140, 140, 140, - 272, 272, 272, 272, 272, 272, 581, 582, 48, 48, 48, 48, 48, 48, 48, 48, + 273, 273, 273, 273, 273, 273, 584, 585, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 388, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 48, 48, 48, 48, 48, 583, - 48, 48, 48, 584, 585, 586, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 48, 48, 48, 48, 48, 586, + 48, 48, 48, 587, 588, 589, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 71, 48, 48, 48, 48, 313, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 48, 587, 588, 192, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 48, 48, 48, 196, 48, 200, 370, 48, 48, 48, 48, 200, 192, 48, 204, 589, - 48, 48, 48, 590, 591, 592, 593, 594, 48, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 595, 48, 596, 192, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 9, 9, 11, 11, 271, 597, 140, 140, 140, 140, 140, 140, - 48, 48, 48, 48, 598, 599, 600, 600, 601, 602, 140, 140, 140, 140, 603, 604, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 440, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 199, 140, 605, - 196, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 606, - 48, 48, 607, 608, 140, 609, 610, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 48, 590, 591, 192, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 48, 48, 48, 196, 48, 200, 370, 48, 48, 48, 48, 200, 192, 48, 204, 592, + 48, 48, 48, 593, 594, 595, 596, 597, 48, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 598, 48, 599, 192, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 9, 9, 11, 11, 272, 600, 9, 601, 11, 602, 140, 140, + 48, 48, 48, 48, 603, 604, 605, 605, 606, 607, 140, 140, 140, 140, 608, 609, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 199, 140, 610, + 48, 200, 140, 140, 140, 140, 140, 140, 48, 48, 48, 48, 48, 48, 48, 611, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 612, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 611, 613, 140, 614, 615, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 206, - 48, 48, 48, 48, 48, 48, 71, 151, 196, 611, 612, 140, 140, 140, 140, 140, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 192, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 322, 140, 140, 140, 140, - 32, 32, 613, 32, 614, 209, 209, 209, 209, 209, 209, 209, 322, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 48, 48, 48, 48, 48, 48, 71, 151, 196, 616, 617, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 618, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 619, 209, 427, 209, 620, + 32, 32, 216, 32, 621, 209, 209, 209, 209, 209, 209, 209, 322, 140, 140, 140, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 323, - 209, 209, 615, 209, 209, 209, 616, 617, 618, 209, 619, 209, 209, 209, 287, 140, - 209, 209, 209, 209, 620, 140, 140, 140, 140, 140, 140, 140, 271, 621, 271, 621, - 209, 209, 209, 209, 209, 338, 271, 461, 140, 140, 140, 140, 140, 140, 140, 140, - 9, 622, 11, 623, 624, 625, 241, 9, 626, 627, 628, 629, 630, 9, 622, 11, - 631, 632, 11, 633, 634, 635, 636, 9, 637, 11, 9, 622, 11, 623, 624, 11, - 241, 9, 626, 636, 9, 637, 11, 9, 622, 11, 638, 9, 639, 640, 641, 642, - 11, 643, 9, 644, 645, 646, 647, 11, 648, 9, 649, 11, 650, 538, 538, 538, - 32, 32, 32, 651, 32, 32, 652, 653, 654, 655, 45, 140, 140, 140, 140, 140, - 656, 657, 658, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 659, 660, 661, 27, 27, 27, 662, 140, 663, 140, 140, 140, 140, 140, 140, 140, - 48, 48, 151, 664, 665, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 666, 140, 48, 48, 667, 668, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 669, 192, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 587, 670, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 671, 200, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 672, 614, 140, 140, - 9, 9, 626, 11, 673, 370, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 503, 271, 271, 674, 675, 140, 140, 140, 140, - 503, 271, 676, 677, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 678, 48, 679, 680, 681, 682, 683, 684, 685, 206, 686, 206, 140, 140, 140, 687, - 209, 209, 688, 209, 209, 209, 209, 209, 209, 322, 333, 689, 689, 689, 209, 323, - 690, 209, 209, 209, 209, 209, 209, 209, 209, 209, 691, 140, 140, 140, 692, 209, - 693, 209, 209, 688, 694, 695, 323, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 696, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 697, 426, 426, - 209, 209, 209, 209, 209, 209, 209, 698, 209, 209, 209, 209, 209, 176, 688, 427, - 688, 209, 209, 209, 699, 176, 209, 209, 699, 209, 691, 688, 695, 140, 140, 140, - 209, 209, 209, 209, 209, 322, 691, 426, 700, 209, 209, 209, 701, 702, 176, 694, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 703, 209, 209, 209, 209, 209, 192, + 209, 209, 622, 209, 209, 209, 623, 624, 625, 209, 626, 209, 209, 209, 288, 140, + 209, 209, 209, 209, 627, 140, 140, 140, 140, 140, 140, 140, 272, 628, 272, 628, + 209, 209, 209, 209, 209, 338, 272, 461, 140, 140, 140, 140, 140, 140, 140, 140, + 9, 629, 11, 630, 631, 632, 242, 9, 633, 634, 635, 636, 637, 9, 629, 11, + 638, 639, 11, 640, 641, 642, 643, 9, 644, 11, 9, 629, 11, 630, 631, 11, + 242, 9, 633, 643, 9, 644, 11, 9, 629, 11, 645, 9, 646, 647, 648, 649, + 11, 650, 9, 651, 652, 653, 654, 11, 655, 9, 656, 11, 657, 539, 539, 539, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, + 32, 32, 32, 658, 32, 32, 659, 660, 661, 662, 45, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 663, 664, 665, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 666, 667, 668, 27, 27, 27, 669, 140, 670, 140, 140, 140, 140, 140, 140, 140, + 48, 48, 151, 671, 672, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 673, 140, 48, 48, 674, 675, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 676, 192, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 590, 677, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 200, 678, 679, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 680, 200, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 681, 621, 140, 140, + 9, 9, 633, 11, 682, 370, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 504, 272, 272, 683, 684, 140, 140, 140, 140, + 504, 272, 685, 686, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 687, 48, 688, 689, 690, 691, 692, 693, 694, 206, 695, 206, 140, 140, 140, 696, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 209, 209, 697, 209, 209, 209, 209, 209, 209, 322, 333, 698, 698, 698, 209, 323, + 699, 209, 209, 209, 209, 209, 209, 209, 209, 209, 700, 140, 140, 140, 701, 209, + 702, 209, 209, 697, 703, 704, 323, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 705, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 706, 426, 426, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 176, 697, 427, + 697, 209, 209, 209, 707, 176, 209, 209, 707, 209, 700, 697, 704, 708, 140, 140, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, + 209, 209, 209, 209, 209, 707, 700, 426, 709, 209, 209, 209, 710, 711, 712, 703, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 713, 209, 209, 209, 209, 209, 714, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 140, 140, - 48, 48, 48, 207, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 204, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 481, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 204, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 100, 48, 48, 48, 48, 48, 48, 204, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 48, 204, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 48, 48, 48, 48, 71, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 140, 140, 140, 140, 140, - 704, 140, 584, 584, 584, 584, 584, 584, 140, 140, 140, 140, 140, 140, 140, 140, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 140, - 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 705, - 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 706, - 0, 1, 2, 3, 4, 4, 4, 4, 4, 4, 5, 6, 7, 8, 9, 10, - 11, 11, 12, 11, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 57, 57, 58, 59, 60, 60, 60, 60, 61, 62, 63, 64, 65, 66, 67, 68, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 70, 71, 72, 73, 74, 75, - 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, - 92, 93, 94, 95, 96, 97, 98, 7, 4, 4, 4, 4, 99, 100, 101, 102, - 103, 104, 105, 106, 107, 108, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 110, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 112, 112, 112, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113, 114, 0, - 115, 116, 117, 118, 119, 120, 121, 122, 0, 123, 124, 125, 126, 126, 126, 127, - 128, 129, 130, 131, 132, 60, 133, 134, 135, 136, 0, 137, 138, 139, 0, 0, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, - 126, 126, 126, 126, 126, 126, 126, 0, 126, 126, 126, 126, 126, 126, 126, 126, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 141, 142, 143, 143, 143, 143, 144, 11, 145, 146, 147, 4, 148, 149, - 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 166, 167, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 126, 126, 126, 126, 126, 169, 126, 170, 171, 172, 19, 173, - 19, 19, 19, 19, 174, 19, 175, 176, 177, 178, 19, 179, 180, 181, 182, 183, - 184, 185, 186, 187, 188, 189, 190, 191, 168, 168, 192, 193, 194, 195, 196, 197, - 198, 199, 200, 201, 202, 203, 204, 205, 206, 206, 206, 206, 207, 208, 209, 168, - 210, 211, 212, 213, 214, 168, 215, 216, 217, 218, 219, 220, 221, 222, 223, 168, - 224, 225, 226, 227, 228, 229, 230, 168, 168, 231, 232, 233, 234, 235, 236, 237, - 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, - 254, 255, 256, 257, 168, 168, 258, 259, 260, 261, 262, 263, 264, 265, 168, 168, - 266, 168, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 168, 168, 278, - 279, 280, 281, 168, 282, 283, 284, 168, 168, 168, 168, 285, 286, 287, 288, 289, - 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 291, 168, - 290, 292, 290, 290, 290, 293, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 294, 295, - 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, - 296, 297, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, - 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 298, - 299, 299, 299, 299, 299, 299, 299, 299, 299, 300, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 301, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 302, 302, 302, 302, 302, 302, 302, 302, 303, 304, 305, 306, 307, 308, 309, 168, - 168, 168, 168, 168, 168, 310, 168, 168, 168, 311, 312, 168, 313, 314, 315, 316, - 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, - 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 318, - 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 319, 319, 319, 319, - 319, 319, 319, 320, 321, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 322, - 323, 324, 324, 324, 325, 326, 327, 327, 327, 327, 327, 328, 168, 168, 168, 168, - 329, 330, 331, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 0, 0, 0, 332, 0, 0, 0, 0, 0, 0, 333, 168, 334, 335, 0, 336, - 0, 0, 0, 337, 338, 339, 340, 341, 189, 342, 168, 343, 0, 344, 168, 168, - 0, 345, 346, 347, 348, 349, 0, 0, 0, 0, 350, 0, 0, 0, 0, 351, - 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 353, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 354, 168, 168, 168, - 355, 356, 357, 168, 358, 359, 168, 168, 168, 168, 360, 361, 168, 168, 168, 168, - 168, 168, 168, 362, 168, 168, 168, 363, 168, 168, 168, 168, 168, 168, 168, 364, - 365, 365, 365, 366, 367, 368, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 369, 370, 168, 371, 168, 168, 168, 372, 373, 374, 375, 168, 168, 168, 168, - 376, 0, 377, 378, 0, 0, 379, 380, 381, 382, 168, 168, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 383, 0, 384, 0, 385, - 386, 387, 388, 389, 0, 0, 0, 0, 0, 390, 391, 392, 0, 0, 393, 332, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 394, 126, 126, 126, 126, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 395, 126, 126, 126, - 396, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 397, 126, 126, 126, 126, 126, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 398, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 399, 168, 168, 168, 168, 168, 168, - 126, 126, 126, 126, 126, 126, 126, 126, 399, 168, 168, 168, 168, 168, 168, 168, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 400, 126, 126, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 401, 168, - 402, 0, 168, 168, 7, 7, 7, 403, 0, 1, 2, 3, 4, 4, 4, 4, + 48, 204, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 71, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 207, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 715, 140, 587, 587, 587, 587, 587, 587, 140, 140, 140, 140, 140, 140, 140, 140, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 140, + 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, + 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 716, + 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, + 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 717, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 3, 1, 2, 2, 3, 0, 0, 0, 0, 0, 4, 0, 4, 2, 2, 5, 2, 2, 2, 5, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, - 0, 0, 0, 0, 7, 8, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 10, 11, 12, 13, 14, 14, 15, 14, 14, 14, - 14, 14, 14, 14, 16, 17, 14, 14, 18, 18, 18, 18, 18, 18, 18, 18, - 19, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 20, 21, - 21, 21, 22, 20, 21, 21, 21, 21, 21, 23, 24, 25, 25, 25, 25, 25, - 25, 26, 25, 25, 25, 27, 28, 26, 29, 30, 31, 32, 31, 31, 31, 31, - 33, 34, 35, 31, 31, 31, 36, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 29, 31, 31, 31, 31, 37, 38, 37, 37, 37, 37, 37, 37, - 37, 39, 31, 31, 31, 31, 31, 31, 40, 40, 40, 40, 40, 40, 41, 26, - 42, 42, 42, 42, 42, 42, 42, 43, 44, 44, 44, 44, 44, 45, 44, 46, - 47, 47, 47, 48, 37, 49, 31, 31, 31, 50, 51, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 52, 31, 31, 31, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 54, 53, 55, 53, 53, 53, 56, 57, 58, 59, 59, 60, 61, 62, - 57, 63, 64, 65, 66, 59, 59, 67, 68, 69, 70, 71, 71, 72, 73, 74, - 69, 75, 76, 77, 78, 71, 79, 26, 80, 81, 82, 83, 83, 84, 85, 86, - 81, 87, 88, 26, 89, 83, 90, 91, 92, 93, 94, 95, 95, 96, 97, 98, - 93, 99, 100, 101, 102, 95, 95, 26, 103, 104, 105, 106, 107, 104, 108, 109, - 104, 105, 110, 26, 111, 108, 108, 112, 113, 114, 115, 113, 113, 115, 113, 116, - 114, 117, 118, 119, 120, 113, 121, 113, 122, 123, 124, 122, 122, 124, 125, 126, - 123, 127, 128, 128, 129, 122, 130, 26, 131, 132, 133, 131, 131, 131, 131, 131, - 132, 133, 134, 131, 135, 131, 131, 131, 136, 137, 138, 139, 137, 137, 140, 141, - 138, 142, 143, 137, 144, 137, 145, 26, 146, 147, 147, 147, 147, 147, 147, 148, - 147, 147, 147, 149, 26, 26, 26, 26, 150, 151, 152, 152, 153, 152, 152, 154, - 155, 156, 152, 157, 26, 26, 26, 26, 158, 158, 158, 158, 158, 158, 158, 158, - 158, 159, 158, 158, 158, 160, 159, 158, 158, 158, 158, 159, 158, 158, 158, 161, - 158, 161, 162, 163, 26, 26, 26, 26, 164, 164, 164, 164, 164, 164, 164, 164, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 6, 0, 0, 0, 0, 7, 8, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 11, + 12, 13, 14, 14, 15, 14, 14, 14, 14, 14, 14, 14, 16, 17, 14, 14, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 19, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 20, 21, 21, 21, 22, 20, 21, 21, 21, 21, + 21, 23, 24, 25, 25, 25, 25, 25, 25, 26, 25, 25, 25, 27, 28, 26, + 29, 30, 31, 32, 31, 31, 31, 31, 33, 34, 35, 31, 31, 31, 36, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 29, 31, 31, 31, 31, + 37, 38, 37, 37, 37, 37, 37, 37, 37, 39, 31, 31, 31, 31, 31, 31, + 40, 40, 40, 40, 40, 40, 41, 26, 42, 42, 42, 42, 42, 42, 42, 43, + 44, 44, 44, 44, 44, 45, 44, 46, 47, 47, 47, 48, 37, 49, 31, 31, + 31, 31, 50, 31, 31, 31, 31, 31, 31, 31, 31, 31, 51, 31, 31, 31, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 53, 52, 54, 52, 52, 52, + 55, 56, 57, 58, 58, 59, 60, 61, 56, 62, 63, 64, 65, 58, 58, 66, + 67, 68, 69, 70, 70, 71, 72, 73, 68, 74, 75, 76, 77, 70, 78, 26, + 79, 80, 81, 82, 82, 83, 84, 85, 80, 86, 87, 26, 88, 82, 89, 90, + 91, 92, 93, 94, 94, 95, 96, 97, 92, 98, 99, 100, 101, 94, 94, 26, + 102, 103, 104, 105, 106, 103, 107, 108, 103, 104, 109, 26, 110, 107, 107, 111, + 112, 113, 114, 112, 112, 114, 112, 115, 113, 116, 117, 118, 119, 112, 120, 112, + 121, 122, 123, 121, 121, 123, 124, 125, 122, 126, 127, 128, 129, 121, 130, 26, + 131, 132, 133, 131, 131, 131, 131, 131, 132, 133, 134, 131, 135, 131, 131, 131, + 136, 137, 138, 139, 137, 137, 140, 141, 138, 142, 143, 137, 144, 137, 145, 26, + 146, 147, 147, 147, 147, 147, 147, 148, 147, 147, 147, 149, 26, 26, 26, 26, + 150, 151, 152, 152, 153, 152, 152, 154, 155, 156, 152, 157, 26, 26, 26, 26, + 158, 158, 158, 158, 158, 158, 158, 158, 158, 159, 158, 158, 158, 160, 159, 158, + 158, 158, 158, 159, 158, 158, 158, 161, 158, 161, 162, 163, 26, 26, 26, 26, + 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 165, 165, 165, 165, 166, 167, 165, 165, 165, 165, 165, 168, - 169, 169, 169, 169, 169, 169, 169, 169, 170, 170, 170, 170, 170, 170, 170, 170, - 170, 171, 172, 171, 170, 170, 170, 170, 170, 171, 170, 170, 170, 170, 171, 172, - 171, 170, 172, 170, 170, 170, 170, 170, 170, 170, 171, 170, 170, 170, 170, 170, - 170, 170, 170, 173, 170, 170, 170, 174, 170, 170, 170, 175, 176, 176, 176, 176, - 176, 176, 176, 176, 176, 176, 177, 177, 178, 178, 178, 178, 178, 178, 178, 178, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 170, 170, 170, 170, 170, 170, 170, 170, 170, 171, 172, 171, 170, 170, 170, 170, + 170, 171, 170, 170, 170, 170, 171, 172, 171, 170, 172, 170, 170, 170, 170, 170, + 170, 170, 171, 170, 170, 170, 170, 170, 170, 170, 170, 173, 170, 170, 170, 174, + 170, 170, 170, 175, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 177, 177, + 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 179, 179, 179, 180, 181, 181, 181, 181, 181, 181, 181, 181, 181, 182, 181, 183, 184, 184, 185, 186, 187, 187, 188, 26, 189, 189, 190, 26, 191, 192, 193, 26, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 195, 194, 196, 194, 196, @@ -2144,165 +2264,215 @@ static const uint16_t _hb_ucd_u16[10400]= 203, 203, 203, 204, 203, 205, 203, 205, 206, 203, 207, 207, 207, 208, 209, 26, 210, 210, 210, 210, 210, 211, 210, 210, 210, 212, 210, 213, 194, 194, 194, 194, 214, 214, 214, 215, 216, 216, 216, 216, 216, 216, 216, 217, 216, 216, 216, 218, - 216, 219, 216, 219, 216, 220, 9, 9, 9, 221, 26, 26, 26, 26, 26, 26, - 222, 222, 222, 222, 222, 222, 222, 222, 222, 223, 222, 222, 222, 222, 222, 222, - 224, 224, 224, 224, 224, 224, 224, 224, 225, 225, 225, 225, 225, 225, 226, 227, - 228, 228, 228, 228, 228, 228, 228, 229, 228, 230, 231, 231, 231, 231, 231, 231, - 18, 232, 165, 165, 165, 165, 165, 233, 224, 26, 234, 9, 235, 236, 237, 238, - 2, 2, 2, 2, 239, 240, 2, 2, 2, 2, 2, 241, 242, 243, 2, 244, - 2, 2, 2, 2, 2, 2, 2, 245, 14, 14, 246, 246, 14, 14, 14, 14, - 246, 246, 14, 247, 14, 14, 14, 246, 14, 14, 14, 14, 14, 14, 248, 14, - 248, 14, 249, 250, 14, 14, 251, 252, 0, 253, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 254, 0, 255, 256, 0, 257, 2, 258, 0, 0, 0, 0, - 259, 26, 9, 9, 9, 9, 260, 26, 0, 0, 0, 0, 261, 262, 4, 0, - 0, 263, 0, 0, 2, 2, 2, 2, 2, 264, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 265, 26, 26, 0, 266, 26, 26, 0, 0, 0, 0, - 267, 267, 267, 267, 267, 267, 267, 267, 0, 0, 0, 0, 0, 0, 268, 0, - 0, 0, 269, 0, 0, 0, 0, 0, 270, 270, 270, 270, 270, 270, 270, 270, - 270, 270, 270, 270, 2, 2, 2, 2, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 271, 272, 165, 165, 165, 165, 166, 167, 273, 273, - 273, 273, 273, 273, 273, 274, 275, 274, 170, 170, 172, 26, 172, 172, 172, 172, - 172, 172, 172, 172, 18, 18, 18, 18, 0, 0, 0, 276, 26, 26, 26, 26, - 277, 277, 277, 278, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 279, 26, - 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 280, 26, 26, 26, 0, 0, - 281, 0, 0, 0, 282, 283, 0, 284, 285, 286, 286, 286, 286, 286, 286, 286, - 286, 286, 287, 288, 289, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 291, - 292, 293, 293, 293, 293, 293, 294, 169, 169, 295, 0, 0, 293, 293, 293, 293, - 0, 0, 0, 0, 276, 296, 290, 290, 169, 169, 169, 295, 0, 0, 0, 0, - 0, 0, 0, 0, 169, 169, 169, 297, 0, 0, 290, 290, 290, 290, 290, 298, - 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 0, 0, 0, 0, 0, - 299, 299, 299, 299, 299, 299, 299, 299, 299, 300, 299, 299, 299, 299, 299, 299, - 301, 26, 302, 302, 302, 302, 302, 302, 303, 303, 303, 303, 303, 303, 303, 303, - 303, 303, 303, 303, 303, 304, 26, 26, 18, 18, 18, 18, 305, 305, 305, 305, - 305, 305, 305, 305, 305, 305, 305, 26, 0, 0, 0, 0, 306, 2, 2, 2, - 2, 307, 2, 2, 2, 2, 2, 2, 2, 308, 309, 258, 26, 26, 310, 2, - 311, 311, 311, 311, 311, 312, 0, 265, 313, 313, 313, 313, 313, 313, 313, 26, - 314, 314, 314, 314, 314, 314, 314, 314, 315, 316, 314, 317, 53, 53, 53, 53, - 318, 318, 318, 318, 318, 319, 320, 320, 320, 320, 321, 322, 169, 169, 169, 323, - 324, 324, 324, 324, 324, 324, 324, 324, 324, 325, 324, 326, 164, 164, 164, 327, - 328, 328, 328, 328, 328, 328, 329, 26, 328, 330, 328, 331, 164, 164, 164, 164, - 332, 332, 332, 332, 332, 332, 332, 332, 333, 26, 26, 334, 335, 335, 336, 26, - 337, 337, 337, 26, 172, 172, 2, 2, 2, 2, 2, 338, 339, 340, 176, 176, - 176, 176, 176, 176, 176, 176, 176, 176, 335, 335, 335, 335, 335, 341, 335, 342, - 169, 169, 169, 169, 343, 26, 169, 169, 295, 344, 169, 169, 169, 169, 169, 343, - 26, 26, 26, 26, 26, 26, 26, 26, 277, 277, 277, 277, 277, 280, 277, 277, - 277, 277, 277, 345, 26, 26, 26, 26, 346, 26, 347, 348, 25, 25, 349, 350, - 351, 25, 31, 31, 31, 31, 31, 31, 352, 26, 353, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 354, 31, 31, 355, 31, 31, 31, 31, 31, - 31, 356, 26, 26, 26, 26, 31, 31, 9, 9, 0, 265, 9, 357, 0, 0, - 0, 0, 358, 0, 257, 359, 360, 31, 31, 31, 31, 31, 31, 31, 31, 361, - 362, 0, 0, 0, 1, 2, 2, 3, 1, 2, 2, 3, 363, 290, 289, 290, - 290, 290, 290, 364, 169, 169, 169, 295, 365, 365, 365, 366, 257, 257, 26, 367, - 368, 369, 368, 368, 370, 368, 368, 371, 368, 372, 368, 372, 26, 26, 26, 26, - 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 373, - 374, 0, 0, 0, 0, 0, 375, 0, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 252, 0, 376, 377, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 378, - 379, 379, 379, 380, 381, 381, 381, 381, 381, 381, 382, 26, 383, 0, 0, 359, - 384, 384, 384, 384, 385, 386, 387, 387, 387, 388, 389, 389, 389, 389, 389, 390, - 391, 391, 391, 392, 393, 393, 393, 393, 394, 393, 395, 26, 26, 26, 26, 26, - 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 397, 397, 397, 397, 397, 397, - 398, 398, 398, 399, 398, 400, 401, 401, 401, 401, 402, 401, 401, 401, 401, 402, - 403, 403, 403, 403, 403, 26, 404, 404, 404, 404, 404, 404, 405, 406, 407, 408, - 407, 408, 409, 407, 410, 407, 410, 411, 412, 412, 412, 412, 412, 412, 413, 26, - 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 415, 26, - 414, 414, 416, 26, 414, 26, 26, 26, 417, 2, 2, 2, 2, 2, 418, 419, - 420, 421, 422, 422, 422, 422, 423, 424, 425, 425, 426, 425, 427, 427, 427, 427, - 428, 428, 428, 429, 430, 428, 26, 26, 26, 26, 26, 26, 431, 431, 432, 433, - 434, 434, 434, 435, 436, 436, 436, 437, 438, 438, 438, 438, 439, 439, 439, 440, - 439, 439, 441, 439, 439, 439, 439, 439, 442, 443, 444, 445, 446, 446, 447, 448, - 446, 449, 446, 449, 450, 450, 450, 450, 451, 451, 451, 451, 26, 26, 26, 26, - 452, 452, 452, 452, 453, 454, 453, 26, 455, 455, 455, 455, 455, 455, 456, 457, - 458, 458, 459, 458, 460, 460, 461, 460, 462, 462, 463, 464, 26, 465, 26, 26, - 466, 466, 466, 466, 466, 466, 466, 466, 466, 467, 26, 26, 26, 26, 26, 26, - 468, 468, 468, 468, 468, 468, 469, 26, 468, 468, 468, 468, 468, 468, 469, 470, - 471, 471, 471, 471, 471, 26, 471, 472, 473, 473, 473, 473, 474, 475, 473, 473, - 474, 476, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 31, 31, 31, 50, - 477, 477, 477, 477, 477, 478, 479, 26, 480, 26, 26, 26, 26, 26, 26, 481, - 482, 482, 482, 482, 482, 26, 483, 483, 483, 483, 483, 484, 26, 26, 485, 485, - 485, 486, 26, 26, 26, 26, 487, 487, 487, 488, 26, 26, 489, 489, 490, 26, - 491, 491, 491, 491, 491, 491, 491, 491, 491, 492, 493, 491, 491, 491, 492, 494, - 495, 495, 495, 495, 495, 495, 495, 495, 496, 497, 498, 498, 498, 499, 498, 500, - 501, 501, 501, 501, 501, 501, 502, 501, 501, 26, 503, 503, 503, 503, 504, 26, - 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 506, 137, 507, 26, - 508, 508, 509, 508, 508, 508, 508, 508, 510, 26, 26, 26, 26, 26, 26, 26, - 511, 512, 513, 514, 513, 515, 516, 516, 516, 516, 516, 516, 516, 517, 516, 518, - 519, 520, 521, 522, 522, 523, 524, 525, 520, 526, 527, 528, 529, 530, 530, 26, - 531, 532, 531, 531, 531, 531, 533, 531, 534, 535, 533, 536, 537, 26, 26, 26, - 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, 539, 540, 26, 26, 26, - 541, 541, 541, 541, 541, 541, 541, 541, 541, 26, 541, 542, 26, 26, 26, 26, - 543, 543, 543, 543, 543, 543, 544, 543, 543, 543, 543, 544, 26, 26, 26, 26, - 545, 545, 545, 545, 545, 545, 545, 545, 546, 26, 545, 547, 198, 548, 26, 26, - 549, 549, 549, 549, 549, 549, 549, 550, 549, 550, 164, 164, 551, 26, 26, 26, - 552, 552, 552, 553, 552, 554, 552, 552, 555, 26, 26, 26, 26, 26, 26, 26, - 556, 556, 556, 556, 556, 556, 556, 557, 26, 26, 26, 26, 558, 558, 558, 558, - 558, 558, 558, 558, 558, 558, 559, 560, 561, 562, 563, 564, 564, 564, 565, 566, - 561, 26, 564, 567, 26, 26, 26, 26, 26, 26, 26, 26, 568, 569, 568, 568, - 568, 568, 568, 569, 570, 26, 26, 26, 571, 571, 571, 571, 571, 571, 571, 571, - 571, 26, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 573, 26, 178, 178, - 574, 574, 574, 574, 574, 574, 574, 575, 53, 576, 26, 26, 26, 26, 26, 26, - 577, 577, 577, 577, 578, 26, 577, 578, 579, 580, 579, 579, 579, 579, 581, 579, - 582, 26, 579, 579, 579, 583, 584, 584, 584, 584, 585, 584, 584, 586, 587, 26, - 588, 589, 590, 590, 590, 590, 588, 591, 590, 26, 590, 592, 593, 594, 595, 595, - 595, 596, 597, 598, 595, 599, 26, 26, 26, 26, 26, 26, 600, 600, 600, 601, - 602, 602, 603, 602, 602, 602, 602, 604, 602, 602, 602, 605, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 606, 26, 108, 108, 108, 108, 108, 108, 607, 608, - 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 610, 26, 26, 26, 26, - 609, 609, 609, 609, 609, 611, 612, 26, 613, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 614, 614, 614, 614, 614, 614, 614, 614, 614, 614, 614, 614, 615, 26, - 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 617, 26, 616, 616, 616, 616, - 616, 616, 616, 616, 616, 616, 616, 618, 619, 619, 619, 619, 619, 619, 619, 619, - 620, 26, 26, 26, 26, 26, 26, 26, 621, 621, 621, 621, 621, 621, 621, 622, - 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 623, - 624, 624, 624, 625, 624, 626, 627, 627, 627, 627, 627, 627, 627, 627, 627, 628, - 627, 629, 630, 630, 630, 631, 631, 26, 632, 632, 632, 632, 632, 632, 632, 632, - 633, 26, 632, 634, 634, 632, 632, 635, 632, 632, 26, 26, 26, 26, 26, 26, - 636, 636, 636, 636, 636, 636, 636, 637, 638, 638, 638, 638, 638, 638, 638, 638, - 638, 638, 638, 639, 26, 26, 26, 26, 640, 640, 640, 640, 640, 640, 640, 640, - 640, 641, 640, 640, 640, 640, 640, 640, 640, 642, 640, 640, 26, 26, 26, 26, - 26, 26, 26, 26, 643, 26, 345, 26, 644, 644, 644, 644, 644, 644, 644, 644, - 644, 644, 644, 644, 644, 644, 644, 26, 645, 645, 645, 645, 645, 645, 645, 645, - 645, 645, 646, 26, 26, 26, 26, 647, 644, 648, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 649, 650, 651, 286, 286, 286, 286, 286, 286, 286, - 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 652, 26, 653, 26, - 26, 26, 654, 26, 655, 26, 656, 656, 656, 656, 656, 656, 656, 656, 656, 656, - 656, 656, 656, 656, 656, 656, 656, 657, 658, 658, 658, 658, 658, 658, 658, 658, - 658, 658, 658, 658, 658, 659, 658, 660, 658, 661, 658, 662, 359, 26, 26, 26, - 0, 0, 0, 0, 0, 0, 0, 265, 0, 0, 0, 0, 0, 0, 359, 26, - 9, 9, 9, 9, 9, 663, 9, 9, 221, 26, 0, 0, 0, 0, 0, 0, - 359, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 276, 26, - 0, 0, 0, 0, 257, 362, 0, 0, 0, 0, 0, 0, 664, 665, 0, 666, - 667, 668, 0, 0, 0, 669, 0, 0, 0, 0, 0, 0, 0, 266, 26, 26, - 246, 26, 26, 26, 26, 26, 26, 26, 0, 0, 359, 26, 0, 0, 359, 26, - 0, 0, 257, 26, 0, 0, 0, 259, 0, 0, 254, 0, 0, 0, 0, 0, - 0, 0, 0, 254, 670, 671, 0, 672, 673, 0, 0, 0, 0, 0, 0, 0, - 269, 674, 254, 254, 0, 0, 0, 675, 676, 677, 678, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 276, 0, 0, 0, 0, 268, 0, 0, 0, 0, 0, 0, - 679, 679, 679, 679, 679, 679, 679, 679, 679, 680, 26, 681, 682, 679, 26, 26, - 2, 2, 2, 346, 683, 419, 26, 26, 684, 270, 270, 685, 686, 687, 18, 18, - 18, 18, 18, 18, 18, 688, 26, 26, 26, 689, 26, 26, 26, 26, 26, 26, - 690, 690, 690, 690, 690, 691, 690, 692, 690, 693, 26, 26, 26, 26, 26, 26, - 26, 26, 694, 694, 694, 695, 26, 26, 696, 696, 696, 696, 696, 696, 696, 697, - 26, 26, 698, 698, 698, 698, 698, 699, 26, 26, 700, 700, 700, 700, 700, 701, - 26, 26, 26, 26, 172, 702, 170, 172, 703, 703, 703, 703, 703, 703, 703, 703, - 704, 703, 705, 26, 26, 26, 26, 26, 706, 706, 706, 706, 706, 706, 706, 706, - 706, 707, 706, 708, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 362, 0, - 0, 0, 0, 0, 0, 0, 376, 26, 362, 0, 0, 0, 0, 0, 0, 276, - 709, 31, 31, 31, 710, 711, 712, 713, 714, 715, 710, 716, 710, 712, 712, 717, - 31, 718, 31, 719, 720, 718, 31, 719, 26, 26, 26, 26, 26, 26, 721, 26, - 0, 0, 0, 0, 0, 359, 0, 0, 0, 0, 359, 26, 0, 257, 362, 0, - 362, 0, 362, 0, 0, 0, 276, 26, 0, 0, 0, 0, 0, 276, 26, 26, - 26, 26, 26, 26, 722, 0, 0, 0, 723, 26, 0, 0, 0, 0, 0, 359, - 0, 259, 265, 26, 276, 26, 26, 26, 0, 0, 0, 724, 0, 376, 0, 376, - 0, 0, 0, 0, 0, 0, 257, 725, 0, 0, 0, 265, 0, 359, 259, 26, - 0, 359, 0, 0, 0, 0, 0, 0, 0, 26, 0, 265, 0, 0, 0, 0, - 0, 26, 0, 0, 0, 276, 0, 359, 265, 26, 26, 26, 26, 26, 26, 26, - 0, 0, 359, 26, 0, 276, 0, 376, 0, 726, 0, 0, 0, 0, 0, 0, - 257, 722, 0, 727, 0, 265, 0, 259, 0, 0, 358, 0, 0, 0, 0, 0, - 277, 277, 277, 277, 26, 26, 26, 26, 277, 277, 277, 277, 277, 277, 277, 345, - 277, 277, 277, 280, 277, 277, 277, 277, 277, 277, 277, 277, 345, 26, 277, 277, - 277, 277, 277, 277, 728, 26, 277, 277, 277, 277, 277, 280, 26, 26, 26, 26, - 277, 729, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 26, 26, - 730, 26, 26, 26, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, + 216, 219, 216, 219, 216, 220, 9, 9, 9, 9, 9, 221, 9, 222, 26, 26, + 223, 223, 223, 223, 223, 223, 223, 223, 223, 224, 223, 223, 223, 223, 223, 223, + 225, 225, 225, 225, 225, 225, 225, 225, 226, 226, 226, 226, 226, 226, 227, 228, + 229, 229, 229, 229, 229, 229, 229, 230, 229, 231, 232, 232, 232, 232, 232, 232, + 18, 233, 165, 165, 165, 165, 165, 234, 225, 26, 235, 9, 236, 237, 238, 239, + 2, 2, 2, 2, 240, 241, 2, 2, 2, 2, 2, 242, 243, 244, 2, 245, + 2, 2, 2, 2, 2, 2, 2, 246, 9, 9, 9, 9, 9, 9, 9, 9, + 14, 14, 247, 247, 14, 14, 14, 14, 247, 247, 14, 248, 14, 14, 14, 247, + 14, 14, 14, 14, 14, 14, 249, 14, 249, 14, 250, 251, 14, 14, 252, 253, + 0, 254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 256, 257, + 0, 258, 2, 259, 0, 0, 0, 0, 260, 26, 9, 9, 9, 9, 261, 26, + 0, 0, 0, 0, 262, 263, 4, 0, 0, 264, 0, 0, 2, 2, 2, 2, + 2, 265, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 260, 26, 26, 0, 266, 26, 26, 0, 0, 0, 0, + 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 268, 0, + 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 2, 2, 2, 2, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 270, 271, + 165, 165, 165, 165, 166, 167, 272, 272, 272, 272, 272, 272, 272, 273, 274, 273, + 170, 170, 172, 26, 172, 172, 172, 172, 172, 172, 172, 172, 18, 18, 18, 18, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 275, 26, 26, 26, 26, + 276, 276, 276, 277, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 278, 26, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 279, 26, 26, 26, 0, 0, + 280, 0, 0, 0, 281, 282, 0, 283, 284, 285, 285, 285, 285, 285, 285, 285, + 285, 285, 286, 287, 288, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 290, + 291, 292, 292, 292, 292, 292, 293, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 294, 0, 0, 292, 292, 292, 292, 0, 0, 0, 0, 275, 295, 289, 289, + 169, 169, 169, 294, 0, 0, 0, 0, 0, 0, 0, 0, 169, 169, 169, 296, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 289, 289, 289, 289, 289, 297, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 0, 0, 0, 0, 0, + 276, 276, 276, 276, 276, 276, 276, 276, 0, 0, 0, 0, 0, 0, 0, 0, + 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, + 298, 299, 298, 298, 298, 298, 298, 298, 300, 26, 301, 301, 301, 301, 301, 301, + 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, + 302, 302, 302, 302, 302, 303, 26, 26, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 26, + 0, 0, 0, 0, 305, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 306, 2, 2, 2, 2, 2, 2, 2, 2, 2, 259, 26, 26, 307, 2, + 308, 308, 308, 308, 308, 309, 0, 260, 310, 310, 310, 310, 310, 310, 310, 26, + 311, 311, 311, 311, 311, 311, 311, 311, 312, 313, 311, 314, 52, 52, 52, 52, + 315, 315, 315, 315, 315, 316, 317, 317, 317, 317, 318, 319, 169, 169, 169, 320, + 321, 321, 321, 321, 321, 321, 321, 321, 321, 322, 321, 323, 164, 164, 164, 324, + 325, 325, 325, 325, 325, 325, 326, 26, 325, 327, 325, 328, 164, 164, 164, 164, + 329, 329, 329, 329, 329, 329, 329, 329, 330, 26, 26, 331, 332, 332, 333, 26, + 334, 334, 334, 26, 172, 172, 2, 2, 2, 2, 2, 335, 336, 337, 176, 176, + 176, 176, 176, 176, 176, 176, 176, 176, 332, 332, 332, 332, 332, 338, 332, 339, + 169, 169, 169, 169, 340, 26, 169, 169, 294, 341, 169, 169, 169, 169, 169, 340, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 279, 276, 276, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 342, 26, 26, 26, 26, + 343, 26, 344, 345, 25, 25, 346, 347, 348, 25, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 349, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 26, 26, 26, 26, 31, 31, + 9, 9, 0, 260, 9, 350, 0, 0, 0, 0, 351, 0, 258, 352, 353, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 354, + 355, 0, 0, 0, 1, 2, 2, 3, 1, 2, 2, 3, 356, 289, 288, 289, + 289, 289, 289, 357, 169, 169, 169, 294, 358, 358, 358, 359, 258, 258, 26, 360, + 361, 362, 361, 361, 363, 361, 361, 364, 361, 365, 361, 365, 26, 26, 26, 26, + 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 366, + 367, 0, 0, 0, 0, 0, 368, 0, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 253, 0, 369, 370, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 371, + 372, 372, 372, 373, 374, 374, 374, 374, 374, 374, 375, 26, 376, 0, 0, 352, + 377, 377, 377, 377, 378, 379, 380, 380, 380, 381, 382, 382, 382, 382, 382, 383, + 384, 384, 384, 385, 386, 386, 386, 386, 387, 386, 388, 26, 26, 26, 26, 26, + 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 390, 390, 390, 390, 390, 390, + 391, 391, 391, 392, 391, 393, 394, 394, 394, 394, 395, 394, 394, 394, 394, 395, + 396, 396, 396, 396, 396, 26, 397, 397, 397, 397, 397, 397, 398, 399, 400, 401, + 400, 401, 402, 400, 403, 400, 403, 404, 405, 405, 405, 405, 405, 405, 406, 26, + 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, + 407, 407, 407, 407, 407, 407, 408, 26, 407, 407, 409, 26, 407, 26, 26, 26, + 410, 2, 2, 2, 2, 2, 411, 412, 26, 26, 26, 26, 26, 26, 26, 26, + 413, 414, 415, 415, 415, 415, 416, 417, 418, 418, 419, 418, 420, 420, 420, 420, + 421, 421, 421, 422, 423, 421, 26, 26, 26, 26, 26, 26, 424, 424, 425, 426, + 427, 427, 427, 428, 429, 429, 429, 430, 431, 431, 431, 432, 26, 26, 26, 26, + 433, 433, 433, 433, 434, 434, 434, 435, 434, 434, 436, 434, 434, 434, 434, 434, + 437, 438, 439, 440, 441, 441, 442, 443, 441, 444, 441, 444, 445, 445, 445, 445, + 446, 446, 446, 446, 26, 26, 26, 26, 447, 447, 447, 447, 448, 449, 448, 26, + 450, 450, 450, 450, 450, 450, 451, 452, 453, 453, 454, 453, 455, 455, 456, 455, + 457, 457, 458, 459, 26, 460, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 461, 461, 461, 461, 461, 461, 461, 461, 461, 462, 26, 26, 26, 26, 26, 26, + 463, 463, 463, 463, 463, 463, 464, 26, 463, 463, 463, 463, 463, 463, 464, 465, + 466, 466, 466, 466, 466, 26, 466, 467, 468, 468, 468, 468, 469, 470, 468, 468, + 469, 471, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 31, 31, 31, 472, + 473, 473, 473, 473, 473, 474, 475, 26, 476, 26, 31, 477, 26, 26, 26, 476, + 478, 478, 478, 478, 478, 26, 479, 479, 479, 479, 479, 480, 26, 26, 481, 481, + 481, 482, 26, 26, 26, 26, 483, 483, 483, 484, 26, 26, 485, 485, 486, 26, + 487, 487, 487, 487, 487, 487, 487, 487, 487, 488, 489, 487, 487, 487, 488, 490, + 491, 491, 491, 491, 491, 491, 491, 491, 492, 493, 494, 494, 494, 495, 494, 496, + 497, 497, 497, 497, 497, 497, 498, 497, 497, 26, 499, 499, 499, 499, 500, 26, + 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 502, 137, 503, 26, + 504, 504, 505, 504, 504, 504, 504, 504, 506, 26, 26, 26, 26, 26, 26, 26, + 507, 508, 509, 510, 509, 511, 512, 512, 512, 512, 512, 512, 512, 513, 512, 514, + 515, 516, 517, 518, 518, 519, 520, 521, 516, 522, 523, 524, 525, 526, 526, 26, + 527, 528, 527, 527, 527, 527, 529, 527, 530, 531, 529, 532, 533, 26, 26, 26, + 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, 535, 536, 26, 26, 26, + 537, 537, 537, 537, 537, 537, 537, 537, 537, 26, 537, 538, 26, 26, 26, 26, + 539, 539, 539, 539, 539, 539, 540, 539, 539, 539, 539, 540, 26, 26, 26, 26, + 541, 541, 541, 541, 541, 541, 541, 541, 542, 26, 541, 543, 198, 544, 26, 26, + 545, 545, 545, 545, 545, 545, 545, 546, 545, 546, 164, 164, 547, 26, 26, 26, + 548, 548, 548, 549, 548, 550, 548, 548, 551, 26, 26, 26, 26, 26, 26, 26, + 552, 552, 552, 552, 552, 552, 552, 553, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 555, 556, + 557, 558, 559, 560, 560, 560, 561, 562, 557, 26, 560, 563, 26, 26, 26, 26, + 26, 26, 26, 26, 564, 565, 564, 564, 564, 564, 564, 565, 566, 26, 26, 26, + 567, 567, 567, 567, 567, 567, 567, 567, 567, 26, 568, 568, 568, 568, 568, 568, + 568, 568, 568, 568, 569, 26, 178, 178, 570, 570, 570, 570, 570, 570, 570, 571, + 52, 572, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 501, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 573, 573, 573, 573, 574, 26, 573, 574, + 575, 576, 575, 575, 575, 575, 577, 575, 578, 26, 575, 575, 575, 579, 580, 580, + 580, 580, 581, 580, 580, 582, 583, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 584, 585, 586, 586, 586, 586, 584, 587, 586, 26, 586, 588, 589, 590, 591, 591, + 591, 592, 593, 594, 591, 595, 596, 596, 596, 596, 596, 597, 596, 598, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 599, 599, 599, 600, + 601, 601, 602, 601, 601, 601, 601, 603, 601, 601, 601, 604, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 605, 26, 107, 107, 107, 107, 107, 107, 606, 607, + 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, + 608, 608, 608, 609, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 610, 611, 26, + 608, 608, 608, 608, 608, 608, 608, 608, 612, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 613, 613, 613, 613, 613, 613, 613, 613, 613, 613, 613, 613, 614, 26, + 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, + 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 616, 26, 615, 615, 615, 615, + 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 617, + 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, + 618, 618, 618, 618, 618, 618, 618, 618, 619, 26, 26, 26, 26, 26, 26, 26, + 620, 620, 620, 620, 620, 620, 620, 621, 26, 26, 26, 26, 26, 26, 26, 26, + 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, + 304, 304, 304, 304, 304, 304, 304, 622, 623, 623, 623, 624, 623, 625, 626, 626, + 626, 626, 626, 626, 626, 626, 626, 627, 626, 628, 629, 629, 629, 630, 630, 26, + 631, 631, 631, 631, 631, 631, 631, 631, 632, 26, 631, 633, 633, 631, 631, 634, + 631, 631, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 635, 635, 635, 635, 635, 635, 635, 636, + 26, 26, 26, 26, 26, 26, 26, 26, 637, 637, 637, 637, 637, 637, 637, 637, + 637, 637, 637, 638, 639, 639, 639, 640, 639, 639, 641, 26, 26, 26, 26, 26, + 642, 642, 642, 642, 642, 642, 642, 642, 642, 643, 642, 642, 642, 642, 642, 642, + 642, 644, 642, 642, 26, 26, 26, 26, 26, 26, 26, 26, 645, 26, 646, 26, + 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, + 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, + 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, 649, 26, 26, 26, 26, 650, + 647, 647, 647, 651, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 652, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 653, 654, + 655, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, + 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, + 285, 285, 285, 285, 656, 26, 657, 26, 26, 26, 658, 26, 659, 26, 660, 660, + 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, + 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 661, + 662, 662, 662, 662, 662, 662, 662, 662, 662, 662, 662, 662, 662, 663, 662, 664, + 662, 665, 662, 666, 352, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 369, + 0, 0, 0, 0, 0, 0, 352, 667, 0, 0, 668, 26, 0, 0, 668, 26, + 9, 9, 9, 9, 9, 221, 9, 9, 669, 26, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 352, 26, 26, 26, 26, 26, 26, 26, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 275, 26, + 0, 0, 0, 0, 258, 355, 0, 0, 0, 0, 0, 0, 670, 671, 0, 672, + 673, 674, 0, 0, 0, 675, 0, 0, 0, 0, 0, 0, 0, 266, 26, 26, + 14, 14, 14, 14, 14, 14, 14, 14, 247, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 352, 26, 0, 0, 352, 26, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 258, 26, 0, 0, 0, 668, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, + 0, 0, 0, 255, 676, 677, 0, 678, 679, 0, 0, 0, 0, 0, 0, 0, + 680, 681, 255, 255, 0, 0, 0, 682, 683, 667, 684, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 268, 0, 0, 0, 0, 0, 0, + 685, 685, 685, 685, 685, 685, 685, 685, 685, 685, 685, 685, 685, 685, 685, 685, + 685, 686, 26, 687, 688, 685, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 2, 2, 2, 343, 689, 412, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 690, 269, 269, 691, 692, 693, 18, 18, 18, 18, 18, 18, 18, 694, 26, 26, + 26, 695, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 696, 696, 696, 696, 696, 697, 696, 698, 696, 699, 26, 26, 26, 26, 26, 26, + 26, 26, 700, 700, 700, 701, 26, 26, 702, 702, 702, 702, 702, 702, 702, 703, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 704, 704, 704, 704, 704, 705, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 706, 706, 706, 706, 706, 707, + 26, 26, 26, 26, 26, 26, 26, 26, 708, 708, 708, 709, 708, 708, 710, 711, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 172, 712, 170, 172, + 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, + 713, 713, 713, 713, 713, 713, 713, 713, 714, 713, 715, 26, 26, 26, 26, 26, + 716, 716, 716, 716, 716, 716, 716, 716, 716, 717, 716, 718, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 355, 0, + 0, 0, 0, 0, 0, 0, 369, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 355, 0, 0, 0, 0, 0, 0, 275, 26, 26, 26, 26, 26, 26, 26, 26, + 719, 31, 31, 31, 720, 721, 722, 723, 724, 725, 720, 726, 720, 722, 722, 727, + 31, 728, 31, 729, 730, 728, 31, 729, 26, 26, 26, 26, 26, 26, 731, 26, + 0, 0, 0, 0, 0, 352, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 352, 26, 0, 258, 355, 0, 355, 0, 355, 0, 0, 0, 275, 26, + 0, 0, 0, 0, 0, 275, 26, 26, 26, 26, 26, 26, 732, 0, 0, 0, + 733, 26, 0, 0, 0, 0, 0, 352, 0, 668, 260, 26, 275, 26, 26, 26, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 734, 0, 369, 0, 369, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 260, 0, 352, 668, 26, + 0, 352, 0, 0, 0, 0, 0, 0, 0, 26, 0, 260, 0, 0, 0, 0, + 0, 26, 0, 0, 0, 275, 0, 352, 260, 26, 0, 668, 26, 26, 26, 26, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 275, 0, 369, + 0, 735, 0, 0, 0, 0, 0, 0, 258, 736, 0, 737, 0, 367, 0, 668, + 0, 0, 351, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 266, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 26, 26, 26, 26, + 276, 276, 276, 279, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, + 276, 276, 276, 276, 276, 279, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 738, 26, 276, 276, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 279, 26, 26, 26, 26, + 276, 276, 276, 279, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 739, 276, 276, 276, 276, 276, 276, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 342, + 740, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 939, 940, 941, 942, 946, 948, 0, 962, 969, 970, 971, 976,1001,1002,1003,1008, 0,1033,1040,1041,1042,1043,1047, 0, 0,1080,1081,1082,1086,1110, 0, 0, @@ -2537,11 +2707,11 @@ static const int16_t _hb_ucd_i16[196]= static inline uint8_t _hb_ucd_gc (unsigned u) { - return u<1114110 ? _hb_ucd_u8[6472u+(((_hb_ucd_u8[816u+(((_hb_ucd_u16[((_hb_ucd_u8[272u+(((_hb_ucd_u8[u>>1>>3>>4>>4])<<4)+((u>>1>>3>>4)&15))])<<4)+((u>>1>>3)&15)])<<3)+((u>>1)&7))])<<1)+((u)&1))] : 2; + return u<1114110 ? _hb_ucd_u8[7920u+((_hb_ucd_u8[2176u+((_hb_ucd_u16[((_hb_ucd_u8[((((((u)>>1))>>3))>>5)])<<5)+((((((u)>>1))>>3))&31)])<<3)+((((u)>>1))&7)])<<1)+((u)&1)] : 2; } static inline uint8_t _hb_ucd_ccc (unsigned u) { - return u<125259 ? _hb_ucd_u8[8504u+(((_hb_ucd_u8[7936u+(((_hb_ucd_u8[7460u+(((_hb_ucd_u8[7100u+(((_hb_ucd_u8[6854u+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7))])<<2)+((u>>2>>2)&3))])<<2)+((u>>2)&3))])<<2)+((u)&3))] : 0; + return u<125259 ? _hb_ucd_u8[10388u+((_hb_ucd_u8[9284u+((_hb_ucd_u8[8548u+((_hb_ucd_u8[8302u+((((((u)>>2))>>3))>>4)])<<4)+((((((u)>>2))>>3))&15)])<<3)+((((u)>>2))&7)])<<2)+((u)&3)] : 0; } static inline uint8_t _hb_ucd_b4 (const uint8_t* a, unsigned i) { @@ -2549,15 +2719,15 @@ static inline uint8_t _hb_ucd_b4 (const uint8_t* a, unsigned i) } static inline int16_t _hb_ucd_bmg (unsigned u) { - return u<65380 ? _hb_ucd_i16[((_hb_ucd_u8[9252u+(((_hb_ucd_u8[9132u+(((_hb_ucd_b4(_hb_ucd_u8+9004u,u>>2>>3>>3))<<3)+((u>>2>>3)&7))])<<3)+((u>>2)&7))])<<2)+((u)&3)] : 0; + return u<65380 ? _hb_ucd_i16[((_hb_ucd_u8[11140u+((_hb_ucd_u8[11020u+((_hb_ucd_b4(_hb_ucd_u8+10892u,((((((u)>>2))>>3))>>3)))<<3)+((((((u)>>2))>>3))&7)])<<3)+((((u)>>2))&7)])<<2)+((u)&3)] : 0; } static inline uint8_t _hb_ucd_sc (unsigned u) { - return u<918000 ? _hb_ucd_u8[10486u+(((_hb_ucd_u16[3744u+(((_hb_ucd_u16[2624u+(((_hb_ucd_u8[9588u+(u>>3>>3>>4)])<<4)+((u>>3>>3)&15))])<<3)+((u>>3)&7))])<<3)+((u)&7))] : 2; + return u<918000 ? _hb_ucd_u8[12662u+((_hb_ucd_u16[3328u+((_hb_ucd_u8[11926u+((_hb_ucd_u8[11476u+((((((u)>>3))>>4))>>4)])<<4)+((((((u)>>3))>>4))&15)])<<4)+((((u)>>3))&15)])<<3)+((u)&7)] : 2; } static inline uint16_t _hb_ucd_dm (unsigned u) { - return u<195102 ? _hb_ucd_u16[6976u+(((_hb_ucd_u8[16716u+(((_hb_ucd_u8[16334u+(u>>4>>5)])<<5)+((u>>4)&31))])<<4)+((u)&15))] : 0; + return u<195102 ? _hb_ucd_u16[7408u+((_hb_ucd_u8[18972u+((_hb_ucd_u8[18590u+((((u)>>4))>>5)])<<5)+((((u)>>4))&31)])<<4)+((u)&15)] : 0; } @@ -2565,12 +2735,12 @@ static inline uint16_t _hb_ucd_dm (unsigned u) #include -static const uint8_t _hb_ucd_u8[17524]= +static const uint8_t _hb_ucd_u8[14800]= { 0, 1, 2, 3, 4, 5, 5, 5, 5, 5, 6, 5, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 5, 17, 15, 18, 19, 20, 21, 22, 23, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 24, 25, 26, 5, 27, 28, - 5, 29, 30, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 5, 29, 5, 30, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, @@ -2601,23 +2771,23 @@ static const uint8_t _hb_ucd_u8[17524]= 17, 17, 17,103, 17, 17,104,100,100,100,100,100,100,100,100,100, 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, 100,105,100,100,100,100,100,100, 17, 17,106,107,100,108,109,110, - 17, 17, 17, 17, 17, 17, 17,111, 17, 17, 17, 17,112,113,100,100, - 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,114, - 17,115,116,100,100,100,100,100,100,100,100,100,117,100,100,100, - 100,100,100,100,100,100,100,100,100,100,100,100,118, 39,119,120, - 121,122,123,124,125,126,127,128, 39, 39,129,100,100,100,100,130, - 131,132,133,100,134,135,100,136,137,138,100,100,139,140,141,100, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,111,112,100,100, + 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,113, + 17,114,115,100,100,100,100,100,100,100,100,100,116,100,100,100, + 100,100,100,100,100,100,100,100,100,100,100,100,117, 39,118,119, + 120,121,122,123,124,125,126,127, 39, 39,128,100,100,100,100,129, + 130,131,132,100,133,134,135,136,137,138,100,100,139,140,141,100, 142,143,144,145, 39, 39,146,147,148, 39,149,150,100,100,100,100, 17, 17, 17, 17, 17, 17,151, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17,152,153, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,154, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,155, 17, 17,156,100, - 100,100,100,100,100,100,100,100, 17, 17,157,100,100,100,100,100, - 17, 17, 17,158, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17,159,100,100,100,100,100,100,100,100,100,100,100,100, - 160,161,100,100,100,100,100,100,100,100,100,100,100,100,100,100, + 17, 17, 17, 17, 17, 17, 17, 17,152, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,153, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,154, 17, 17,155,100, + 100,100,100,100,100,100,100,100, 17, 17,156,100,100,100,100,100, + 17, 17, 17,157, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17,158,100,100,100,100,100,100,100,100,100,100,100, + 159,160,100,100,100,100,100,100,100,100,100,100,100,100,100,100, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,161, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,162, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,163, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 2, 4, 5, 6, 2, 7, 7, 7, 7, 7, 2, 8, 9, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, @@ -2631,409 +2801,415 @@ static const uint8_t _hb_ucd_u8[17524]= 34, 11, 34, 34, 32, 35, 32, 16, 36, 36, 37, 34, 38, 37, 34, 34, 34, 34, 34, 34, 34, 34, 16, 32, 34, 38, 32, 11, 32, 32, 32, 32, 32, 32, 16, 16, 16, 11, 34, 32, 34, 34, 11, 32, 32, 32, 32, 32, - 16, 16, 39, 16, 16, 16, 16, 16, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 41, 41, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, - 40, 40, 42, 41, 41, 41, 42, 42, 41, 41, 41, 41, 41, 41, 41, 41, - 43, 43, 43, 43, 43, 43, 43, 43, 32, 32, 42, 32, 44, 45, 16, 10, - 44, 44, 41, 46, 11, 47, 47, 11, 34, 11, 11, 11, 11, 11, 11, 11, - 11, 48, 11, 11, 11, 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 34, - 16, 11, 32, 16, 32, 32, 32, 32, 16, 16, 32, 49, 34, 32, 34, 11, - 32, 50, 43, 43, 51, 32, 32, 32, 11, 34, 34, 34, 34, 34, 34, 16, - 48, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 47, 52, 2, 2, 2, - 16, 16, 16, 16, 53, 54, 55, 56, 57, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 58, 59, 60, 43, 59, 44, 44, 44, 44, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 61, 44, 62, - 36, 63, 64, 44, 44, 44, 44, 44, 65, 65, 65, 8, 9, 66, 2, 67, - 43, 43, 43, 43, 43, 60, 68, 2, 69, 36, 36, 36, 36, 70, 43, 43, - 7, 7, 7, 7, 7, 2, 2, 36, 71, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 72, 43, 43, 43, 73, 50, 43, 43, 74, 75, 76, 43, 43, 36, - 7, 7, 7, 7, 7, 36, 77, 78, 2, 2, 2, 2, 2, 2, 2, 79, - 70, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, 43, 43, 80, 62, 36, - 36, 36, 36, 43, 43, 43, 43, 43, 71, 44, 44, 44, 44, 44, 44, 44, - 7, 7, 7, 7, 7, 36, 36, 36, 36, 36, 36, 36, 36, 70, 43, 43, - 43, 43, 40, 21, 2, 81, 57, 20, 36, 36, 36, 43, 43, 75, 43, 43, - 43, 43, 75, 43, 75, 43, 43, 44, 2, 2, 2, 2, 2, 2, 2, 64, - 36, 36, 36, 36, 70, 43, 44, 64, 36, 36, 36, 36, 36, 61, 44, 44, - 36, 36, 36, 36, 82, 36, 36, 61, 65, 44, 44, 57, 43, 43, 43, 43, - 36, 36, 36, 36, 83, 43, 43, 43, 43, 84, 43, 43, 43, 43, 43, 43, - 43, 85, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 85, 71, 86, - 87, 43, 43, 43, 85, 86, 87, 86, 70, 43, 43, 43, 36, 36, 36, 36, - 36, 43, 2, 7, 7, 7, 7, 7, 88, 36, 36, 36, 36, 36, 36, 36, - 70, 86, 62, 36, 36, 36, 61, 62, 61, 62, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 61, 36, 36, 36, 61, 61, 44, 36, 36, 44, 71, 86, - 87, 43, 80, 89, 90, 89, 87, 61, 44, 44, 44, 89, 44, 44, 36, 62, - 36, 43, 44, 7, 7, 7, 7, 7, 36, 20, 27, 27, 27, 56, 63, 80, - 57, 85, 62, 36, 36, 61, 44, 62, 61, 36, 62, 61, 36, 44, 80, 86, - 87, 80, 44, 57, 80, 57, 43, 44, 57, 44, 44, 44, 62, 36, 61, 61, - 44, 44, 44, 7, 7, 7, 7, 7, 43, 36, 70, 64, 44, 44, 44, 44, - 57, 85, 62, 36, 36, 36, 36, 62, 36, 62, 36, 36, 36, 36, 36, 36, - 61, 36, 62, 36, 36, 44, 71, 86, 87, 43, 43, 57, 85, 89, 87, 44, - 61, 44, 44, 44, 44, 44, 44, 44, 66, 44, 44, 44, 62, 43, 43, 43, - 57, 86, 62, 36, 36, 36, 61, 62, 61, 36, 62, 36, 36, 44, 71, 87, - 87, 43, 80, 89, 90, 89, 87, 44, 44, 44, 57, 85, 44, 44, 36, 62, - 78, 27, 27, 27, 44, 44, 44, 44, 44, 71, 62, 36, 36, 61, 44, 36, - 61, 36, 36, 44, 62, 61, 61, 36, 44, 62, 61, 44, 36, 61, 44, 36, - 36, 36, 36, 36, 36, 44, 44, 86, 85, 90, 44, 86, 90, 86, 87, 44, - 61, 44, 44, 89, 44, 44, 44, 44, 27, 91, 67, 67, 56, 92, 44, 44, - 85, 86, 71, 36, 36, 36, 61, 36, 61, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 44, 71, 43, 85, 86, 90, 43, 80, 43, 43, 44, - 44, 44, 57, 80, 36, 61, 62, 44, 44, 44, 44, 93, 27, 27, 27, 91, - 70, 86, 72, 36, 36, 36, 61, 36, 36, 36, 62, 36, 36, 44, 71, 87, - 86, 86, 90, 85, 90, 86, 43, 44, 44, 44, 89, 90, 44, 44, 62, 61, - 62, 94, 44, 44, 44, 44, 44, 44, 43, 86, 36, 36, 36, 36, 61, 36, - 36, 36, 36, 36, 36, 70, 71, 86, 87, 43, 80, 86, 90, 86, 87, 77, - 44, 44, 36, 94, 27, 27, 27, 95, 27, 27, 27, 27, 91, 36, 36, 36, - 57, 86, 62, 36, 36, 36, 36, 36, 36, 36, 36, 61, 44, 36, 36, 36, - 36, 62, 36, 36, 36, 36, 62, 44, 36, 36, 36, 61, 44, 80, 44, 89, - 86, 43, 80, 80, 86, 86, 86, 86, 44, 86, 64, 44, 44, 44, 44, 44, - 62, 36, 36, 36, 36, 36, 36, 36, 70, 36, 43, 43, 43, 80, 44, 96, - 36, 36, 36, 75, 43, 43, 43, 60, 7, 7, 7, 7, 7, 2, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 62, 61, 61, 36, 36, 61, 36, 36, - 36, 36, 62, 62, 36, 36, 36, 36, 70, 36, 43, 43, 43, 43, 71, 44, - 36, 36, 61, 81, 43, 43, 43, 80, 7, 7, 7, 7, 7, 44, 36, 36, - 77, 67, 2, 2, 2, 2, 2, 2, 2, 97, 97, 67, 43, 67, 67, 67, - 7, 7, 7, 7, 7, 27, 27, 27, 27, 27, 50, 50, 50, 4, 4, 86, - 36, 36, 36, 36, 62, 36, 36, 36, 36, 36, 36, 36, 36, 36, 61, 44, - 57, 43, 43, 43, 43, 43, 43, 85, 43, 43, 60, 43, 36, 36, 70, 43, - 43, 43, 43, 43, 57, 43, 43, 43, 43, 43, 43, 43, 43, 43, 80, 67, - 67, 67, 67, 76, 67, 67, 92, 67, 2, 2, 97, 67, 21, 64, 44, 44, - 36, 36, 36, 36, 36, 94, 87, 43, 85, 43, 43, 43, 87, 85, 87, 71, - 7, 7, 7, 7, 7, 2, 2, 2, 36, 36, 36, 86, 43, 36, 36, 43, - 71, 86, 98, 94, 86, 86, 86, 36, 70, 43, 71, 36, 36, 36, 36, 36, - 36, 85, 87, 85, 86, 86, 87, 94, 7, 7, 7, 7, 7, 86, 87, 67, - 11, 11, 11, 48, 44, 44, 48, 44, 16, 16, 16, 16, 16, 53, 45, 16, - 36, 36, 36, 36, 61, 36, 36, 44, 36, 36, 36, 61, 61, 36, 36, 44, - 61, 36, 36, 44, 36, 36, 36, 61, 61, 36, 36, 44, 36, 36, 36, 36, - 36, 36, 36, 61, 36, 36, 36, 36, 36, 36, 36, 36, 36, 61, 57, 43, - 2, 2, 2, 2, 99, 27, 27, 27, 27, 27, 27, 27, 27, 27,100, 44, - 67, 67, 67, 67, 67, 44, 44, 44, 11, 11, 11, 44, 16, 16, 16, 44, - 101, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 77, 72, - 102, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,103,104, 44, - 36, 36, 36, 36, 36, 63, 2,105,106, 36, 36, 36, 61, 44, 44, 44, - 36, 43, 85, 44, 44, 44, 44, 62, 36, 43,107, 64, 44, 44, 44, 44, - 36, 43, 44, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 61, 36, - 61, 43, 44, 44, 44, 44, 44, 44, 36, 36, 43, 87, 43, 43, 43, 86, - 86, 86, 86, 85, 87, 43, 43, 43, 43, 43, 2, 88, 2, 66, 70, 44, - 7, 7, 7, 7, 7, 44, 44, 44, 27, 27, 27, 27, 27, 44, 44, 44, - 2, 2, 2,108, 2, 59, 43, 84, 36, 83, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 61, 44, 44, 44, 36, 36, 70, 71, 36, 36, 36, 36, - 36, 36, 36, 36, 70, 61, 44, 44, 36, 36, 36, 44, 44, 44, 44, 44, - 36, 36, 36, 36, 36, 36, 36, 61, 43, 85, 86, 87, 85, 86, 44, 44, - 86, 85, 86, 86, 87, 43, 44, 44, 92, 44, 2, 7, 7, 7, 7, 7, - 36, 36, 36, 36, 36, 36, 36, 44, 36, 36, 61, 44, 44, 44, 44, 44, - 36, 36, 36, 36, 36, 36, 44, 44, 36, 36, 36, 36, 36, 44, 44, 44, - 7, 7, 7, 7, 7,100, 44, 67, 67, 67, 67, 67, 67, 67, 67, 67, - 36, 36, 36, 70, 85, 87, 44, 2, 36, 36, 94, 85, 43, 43, 43, 80, - 85, 85, 87, 43, 43, 43, 85, 86, 86, 87, 43, 43, 43, 43, 80, 57, - 2, 2, 2, 88, 2, 2, 2, 44, 43, 43, 43, 43, 43, 43, 43,109, - 43, 43, 43, 43, 43, 43, 43, 80, 43, 43, 98, 36, 36, 36, 36, 36, - 36, 36, 85, 43, 43, 85, 85, 86, 86, 85, 98, 36, 36, 36, 61, 2, - 97, 67, 67, 67, 67, 50, 43, 43, 43, 43, 67, 67, 67, 67, 21, 2, - 43, 98, 36, 36, 36, 36, 36, 36, 94, 43, 43, 86, 43, 87, 43, 36, - 36, 36, 36, 85, 43, 86, 87, 87, 43, 86, 44, 44, 44, 44, 2, 2, - 36, 36, 86, 86, 86, 86, 43, 43, 43, 43, 86, 43, 44, 93, 2, 2, - 7, 7, 7, 7, 7, 44, 62, 36, 36, 36, 36, 36, 40, 40, 40, 2, - 16, 16, 16, 16, 34,110, 44, 44, 11, 11, 11, 11, 11, 47, 48, 11, - 2, 2, 2, 2, 44, 44, 44, 44, 43, 60, 43, 43, 43, 43, 43, 43, - 85, 43, 43, 43, 71, 36, 70, 36, 36, 36, 71, 94, 43, 61, 44, 44, - 16, 16, 16, 16, 16, 16, 40, 40, 40, 40, 40, 40, 40, 45, 16, 16, - 16, 16, 16, 16, 45, 16, 16, 16, 16, 16, 16, 16, 16,111, 40, 40, - 32, 32, 32, 16, 16, 16, 16, 32, 16, 16, 16, 16, 11, 11, 11, 11, - 16, 16, 16, 44, 11, 11, 11, 44, 16, 16, 16, 16, 48, 48, 48, 48, - 16, 16, 16, 16, 16, 16, 16, 44, 16, 16, 16, 16,112,112,112,112, - 16, 16,110, 16, 11, 11,113,114, 41, 16,110, 16, 11, 11,113, 41, - 16, 16, 44, 16, 11, 11,115, 41, 16, 16, 16, 16, 11, 11,116, 41, - 44, 16,110, 16, 11, 11,113,117,118,118,118,118,118,119, 65, 65, - 120,120,120, 2,121,122,121,122, 2, 2, 2, 2,123, 65, 65,124, - 2, 2, 2, 2,125,126, 2,127,128, 2,129,130, 2, 2, 2, 2, - 2, 9,128, 2, 2, 2, 2,131, 65, 65,132, 65, 65, 65, 65, 65, - 133, 44, 27, 27, 27, 8,129,134, 27, 27, 27, 27, 27, 8,129,104, - 40, 40, 40, 40, 40, 40, 81, 44, 20, 20, 20, 20, 20, 20, 20, 20, - 135, 44, 44, 44, 44, 44, 44, 44, 43, 43, 43, 43, 43, 43,136, 51, - 109, 51,109, 43, 43, 43, 43, 43, 80, 44, 44, 44, 44, 44, 44, 44, - 67,137, 67,138, 67, 34, 11, 16, 11, 32,138, 67, 49, 11, 11, 67, - 67, 67,137,137,137, 11, 11,139, 11, 11, 35, 36, 39, 67, 16, 11, - 8, 8, 49, 16, 16, 26, 67,140, 27, 27, 27, 27, 27, 27, 27, 27, - 105,105,105,105,105,105,105,105,105,141,142,105,143, 67, 44, 44, - 8, 8,144, 67, 67, 8, 67, 67,144, 26, 67,144, 67, 67, 67,144, - 67, 67, 67, 67, 67, 67, 67, 8, 67,144,144, 67, 67, 67, 67, 67, - 67, 67, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 67, 67, 67, 67, 4, 4, 67, 67, 8, 67, 67, 67,145,146, 67, 67, - 67, 67, 67, 67, 67, 67,144, 67, 67, 67, 67, 67, 67, 26, 8, 8, - 8, 8, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 8, 8, - 8, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 92, 44, 44, - 27, 27, 27, 27, 27, 27, 67, 67, 67, 67, 67, 67, 67, 27, 27, 27, - 67, 67, 67, 26, 67, 67, 67, 67, 26, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 8, 8, 8, 8, 67, 67, 67, 67, 67, 67, 67, 26, - 67, 67, 67, 67, 4, 4, 4, 4, 4, 4, 4, 27, 27, 27, 27, 27, - 27, 27, 67, 67, 67, 67, 67, 67, 8, 8,129,147, 8, 8, 8, 8, - 8, 8, 8, 4, 4, 4, 4, 4, 8,129,148,148,148,148,148,148, - 148,148,148,148,147, 8, 8, 8, 8, 8, 8, 8, 4, 4, 8, 8, - 8, 8, 8, 8, 8, 8, 4, 8, 8, 8,144, 26, 8, 8,144, 67, - 67, 67, 44, 67, 67, 67, 67, 67, 67, 67, 67, 55, 67, 67, 67, 67, - 32, 11, 32, 34, 34, 34, 34, 11, 32, 32, 34, 16, 16, 16, 40, 11, - 32, 32,140, 67, 67,138, 34,149, 43, 32, 44, 44, 93, 2, 99, 2, - 16, 16, 16,150, 44, 44,150, 44, 36, 36, 36, 36, 44, 44, 44, 52, - 64, 44, 44, 44, 44, 44, 44, 57, 36, 36, 36, 61, 44, 44, 44, 44, - 36, 36, 36, 61, 36, 36, 36, 61, 2,121,121, 2,125,126,121, 2, - 2, 2, 2, 6, 2,108,121, 2,121, 4, 4, 4, 4, 2, 2, 88, - 2, 2, 2, 2, 2,120, 2, 2,108,151, 2, 2, 2, 2, 2, 2, - 67, 2,152,148,148,148,153, 44, 67, 67, 67, 67, 67, 55, 67, 67, - 67, 67, 44, 44, 44, 44, 44, 44, 67, 67, 67, 44, 44, 44, 44, 44, - 1, 2,154,155, 4, 4, 4, 4, 4, 67, 4, 4, 4, 4,156,157, - 158,105,105,105,105, 43, 43, 86,159, 40, 40, 67,105,160, 63, 67, - 36, 36, 36, 61, 57,161,162, 69, 36, 36, 36, 36, 36, 63, 40, 69, - 44, 44, 62, 36, 36, 36, 36, 36, 67, 27, 27, 67, 67, 67, 67, 67, - 67, 67, 67, 44, 44, 44, 44, 55, 67, 67, 67, 67, 67, 67, 67, 92, - 27, 27, 27, 27, 27, 67, 67, 67, 67, 67, 67, 67, 27, 27, 27, 27, - 163, 27, 27, 27, 27, 27, 27, 27, 36, 36, 83, 36, 36, 36, 36, 36, - 67, 67, 67, 92, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36,164, 2, - 7, 7, 7, 7, 7, 36, 44, 44, 32, 32, 32, 32, 32, 32, 32, 70, - 51,165, 43, 43, 43, 43, 43, 88, 32, 32, 32, 32, 32, 32, 40, 43, - 36, 36, 36,105,105,105,105,105, 43, 2, 2, 2, 44, 44, 44, 44, - 41, 41, 41,162, 40, 40, 40, 40, 41, 32, 32, 32, 32, 32, 32, 32, - 16, 32, 32, 32, 32, 32, 32, 32, 45, 16, 16, 16, 34, 34, 34, 32, - 32, 32, 32, 32, 42,166, 34, 35, 32, 32, 16, 32, 32, 32, 32, 32, + 16, 16, 36, 16, 16, 16, 16, 16, 39, 39, 39, 39, 39, 39, 39, 39, + 39, 40, 40, 39, 39, 39, 39, 39, 39, 40, 40, 40, 40, 40, 40, 40, + 39, 39, 41, 40, 40, 40, 41, 41, 40, 40, 40, 40, 40, 40, 40, 40, + 42, 42, 42, 42, 42, 42, 42, 42, 32, 32, 41, 32, 43, 44, 16, 10, + 43, 43, 40, 45, 11, 46, 46, 11, 34, 11, 11, 11, 11, 11, 11, 11, + 11, 47, 11, 11, 11, 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 34, + 16, 11, 32, 16, 32, 32, 32, 32, 16, 16, 32, 48, 34, 32, 34, 11, + 32, 49, 42, 42, 50, 32, 32, 32, 11, 34, 34, 34, 34, 34, 34, 16, + 47, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 46, 51, 2, 2, 2, + 16, 16, 16, 16, 52, 53, 54, 55, 56, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 57, 58, 59, 42, 58, 43, 43, 43, 43, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 60, 43, 61, + 36, 62, 63, 43, 43, 43, 43, 43, 64, 64, 64, 8, 9, 65, 2, 66, + 42, 42, 42, 42, 42, 59, 67, 2, 68, 36, 36, 36, 36, 69, 42, 42, + 7, 7, 7, 7, 7, 2, 2, 36, 70, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 71, 42, 42, 42, 72, 49, 42, 42, 73, 74, 75, 42, 42, 36, + 7, 7, 7, 7, 7, 36, 76, 77, 2, 2, 2, 2, 2, 2, 2, 78, + 69, 36, 36, 36, 36, 36, 36, 36, 42, 42, 42, 42, 42, 79, 61, 36, + 36, 36, 36, 42, 42, 42, 42, 42, 70, 43, 43, 43, 43, 43, 43, 43, + 7, 7, 7, 7, 7, 36, 36, 36, 36, 36, 36, 36, 36, 69, 42, 42, + 42, 42, 39, 21, 2, 80, 56, 20, 36, 36, 36, 42, 42, 74, 42, 42, + 42, 42, 74, 42, 74, 42, 42, 43, 2, 2, 2, 2, 2, 2, 2, 63, + 36, 36, 36, 36, 69, 42, 43, 63, 36, 36, 36, 36, 36, 60, 43, 43, + 36, 36, 36, 36, 81, 36, 36, 36, 64, 43, 43, 56, 42, 42, 42, 42, + 36, 36, 36, 36, 82, 42, 42, 42, 42, 83, 42, 42, 42, 42, 42, 42, + 42, 84, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 84, 70, 85, + 86, 42, 42, 42, 84, 85, 86, 85, 69, 42, 42, 42, 36, 36, 36, 36, + 36, 42, 2, 7, 7, 7, 7, 7, 87, 36, 36, 36, 36, 36, 36, 36, + 69, 85, 61, 36, 36, 36, 60, 61, 60, 61, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 60, 36, 36, 36, 60, 60, 43, 36, 36, 43, 70, 85, + 86, 42, 79, 88, 89, 88, 86, 60, 43, 43, 43, 88, 43, 43, 36, 61, + 36, 42, 43, 7, 7, 7, 7, 7, 36, 20, 27, 27, 27, 55, 62, 79, + 56, 84, 61, 36, 36, 60, 43, 61, 60, 36, 61, 60, 36, 43, 79, 85, + 86, 79, 43, 56, 79, 56, 42, 43, 56, 43, 43, 43, 61, 36, 60, 60, + 43, 43, 43, 7, 7, 7, 7, 7, 42, 36, 69, 63, 43, 43, 43, 43, + 56, 84, 61, 36, 36, 36, 36, 61, 36, 61, 36, 36, 36, 36, 36, 36, + 60, 36, 61, 36, 36, 43, 70, 85, 86, 42, 42, 56, 84, 88, 86, 43, + 60, 43, 43, 43, 43, 43, 43, 43, 65, 43, 43, 43, 61, 42, 42, 42, + 56, 85, 61, 36, 36, 36, 60, 61, 60, 36, 61, 36, 36, 43, 70, 86, + 86, 42, 79, 88, 89, 88, 86, 43, 43, 43, 56, 84, 43, 43, 36, 61, + 77, 27, 27, 27, 43, 43, 43, 43, 43, 70, 61, 36, 36, 60, 43, 36, + 60, 36, 36, 43, 61, 60, 60, 36, 43, 61, 60, 43, 36, 60, 43, 36, + 36, 36, 36, 36, 36, 43, 43, 85, 84, 89, 43, 85, 89, 85, 86, 43, + 60, 43, 43, 88, 43, 43, 43, 43, 27, 90, 66, 66, 55, 91, 43, 43, + 84, 85, 70, 36, 36, 36, 60, 36, 60, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 43, 70, 42, 84, 85, 89, 42, 79, 42, 42, 43, + 43, 43, 56, 79, 36, 60, 36, 43, 43, 43, 43, 92, 27, 27, 27, 90, + 69, 85, 71, 36, 36, 36, 60, 36, 36, 36, 61, 36, 36, 43, 70, 86, + 85, 85, 89, 84, 89, 85, 42, 43, 43, 43, 88, 89, 43, 43, 36, 60, + 61, 93, 43, 43, 43, 43, 43, 43, 42, 85, 36, 36, 36, 36, 60, 36, + 36, 36, 36, 36, 36, 69, 70, 85, 86, 42, 79, 85, 89, 85, 86, 76, + 43, 43, 36, 93, 27, 27, 27, 94, 27, 27, 27, 27, 90, 36, 36, 36, + 56, 85, 61, 36, 36, 36, 36, 36, 36, 36, 36, 60, 43, 36, 36, 36, + 36, 61, 36, 36, 36, 36, 61, 43, 36, 36, 36, 60, 43, 79, 43, 88, + 85, 42, 79, 79, 85, 85, 85, 85, 43, 85, 63, 43, 43, 43, 43, 43, + 61, 36, 36, 36, 36, 36, 36, 36, 69, 36, 42, 42, 42, 79, 43, 95, + 36, 36, 36, 74, 42, 42, 42, 59, 7, 7, 7, 7, 7, 2, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 43, 61, 60, 60, 36, 36, 60, 36, 36, + 36, 36, 61, 61, 36, 36, 36, 36, 69, 36, 42, 42, 42, 42, 70, 43, + 36, 36, 60, 80, 42, 42, 42, 79, 7, 7, 7, 7, 7, 43, 36, 36, + 76, 66, 2, 2, 2, 2, 2, 2, 2, 96, 96, 66, 42, 66, 66, 66, + 7, 7, 7, 7, 7, 27, 27, 27, 27, 27, 49, 49, 49, 4, 4, 85, + 36, 36, 36, 36, 61, 36, 36, 36, 36, 36, 36, 36, 36, 36, 60, 43, + 56, 42, 42, 42, 42, 42, 42, 84, 42, 42, 59, 42, 36, 36, 69, 42, + 42, 42, 42, 42, 56, 42, 42, 42, 42, 42, 42, 42, 42, 42, 79, 66, + 66, 66, 66, 75, 66, 66, 91, 66, 2, 2, 96, 66, 21, 63, 43, 43, + 36, 36, 36, 36, 36, 93, 86, 42, 84, 42, 42, 42, 86, 84, 86, 70, + 7, 7, 7, 7, 7, 2, 2, 2, 36, 36, 36, 85, 42, 36, 36, 42, + 70, 85, 97, 93, 85, 85, 85, 36, 69, 42, 70, 36, 36, 36, 36, 36, + 36, 84, 86, 84, 85, 85, 86, 93, 7, 7, 7, 7, 7, 85, 86, 66, + 11, 11, 11, 47, 43, 43, 47, 43, 16, 16, 16, 16, 16, 52, 44, 16, + 36, 36, 36, 36, 60, 36, 36, 43, 36, 36, 36, 60, 60, 36, 36, 43, + 60, 36, 36, 43, 36, 36, 36, 60, 60, 36, 36, 43, 36, 36, 36, 36, + 36, 36, 36, 60, 36, 36, 36, 36, 36, 36, 36, 36, 36, 60, 56, 42, + 2, 2, 2, 2, 98, 27, 27, 27, 27, 27, 27, 27, 27, 27, 99, 43, + 66, 66, 66, 66, 66, 43, 43, 43, 11, 11, 11, 43, 16, 16, 16, 43, + 100, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 76, 71, + 101, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,102,103, 43, + 36, 36, 36, 36, 36, 62, 2,104,105, 36, 36, 36, 60, 43, 43, 43, + 36, 42, 84, 43, 43, 43, 43, 61, 36, 42,106, 63, 43, 43, 43, 43, + 36, 42, 43, 43, 43, 43, 43, 43, 36, 36, 36, 36, 36, 36, 60, 36, + 60, 42, 43, 43, 43, 43, 43, 43, 36, 36, 42, 86, 42, 42, 42, 85, + 85, 85, 85, 84, 86, 42, 42, 42, 42, 42, 2, 87, 2, 65, 69, 43, + 7, 7, 7, 7, 7, 43, 43, 43, 27, 27, 27, 27, 27, 43, 43, 43, + 2, 2, 2,107, 2, 58, 42, 83, 36, 82, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 60, 43, 43, 43, 36, 36, 69, 70, 36, 36, 36, 36, + 36, 36, 36, 36, 69, 60, 43, 43, 36, 36, 36, 43, 43, 43, 43, 43, + 36, 36, 36, 36, 36, 36, 36, 60, 42, 84, 85, 86, 84, 85, 43, 43, + 85, 84, 85, 85, 86, 42, 43, 43, 91, 43, 2, 7, 7, 7, 7, 7, + 36, 36, 36, 36, 36, 36, 36, 43, 36, 36, 60, 43, 43, 43, 43, 43, + 36, 36, 36, 36, 36, 36, 43, 43, 36, 36, 36, 36, 36, 43, 43, 43, + 7, 7, 7, 7, 7, 99, 43, 66, 66, 66, 66, 66, 66, 66, 66, 66, + 36, 36, 36, 69, 84, 86, 43, 2, 36, 36, 93, 84, 42, 42, 42, 79, + 84, 84, 86, 42, 42, 42, 84, 85, 85, 86, 42, 42, 42, 42, 79, 56, + 2, 2, 2, 87, 2, 2, 2, 43, 42, 42, 42, 42, 42, 42, 42,108, + 42, 42, 42, 42, 42, 42, 42, 43, 42, 42, 42, 42, 42, 42, 43, 43, + 42, 42, 97, 36, 36, 36, 36, 36, 36, 36, 84, 42, 42, 84, 84, 85, + 85, 84, 97, 36, 36, 36, 60, 2, 96, 66, 66, 66, 66, 49, 42, 42, + 42, 42, 66, 66, 66, 66, 21, 2, 42, 97, 36, 36, 36, 36, 36, 36, + 93, 42, 42, 85, 42, 86, 42, 36, 36, 36, 36, 84, 42, 85, 86, 86, + 42, 85, 43, 43, 43, 43, 2, 2, 36, 36, 85, 85, 85, 85, 42, 42, + 42, 42, 85, 42, 43, 92, 2, 2, 7, 7, 7, 7, 7, 43, 61, 36, + 36, 36, 36, 36, 39, 39, 39, 2, 16, 16, 16, 16, 34,109, 43, 43, + 11, 11, 11, 11, 11, 46, 47, 11, 2, 2, 2, 2, 43, 43, 43, 43, + 42, 59, 42, 42, 42, 42, 42, 42, 84, 42, 42, 42, 70, 36, 69, 36, + 36, 36, 70, 93, 42, 60, 43, 43, 16, 16, 16, 16, 16, 16, 39, 39, + 39, 39, 39, 39, 39, 44, 16, 16, 16, 16, 16, 16, 44, 16, 16, 16, + 16, 16, 16, 16, 16,110, 39, 39, 32, 32, 32, 16, 16, 16, 16, 32, + 16, 16, 16, 16, 11, 11, 11, 11, 16, 16, 16, 43, 11, 11, 11, 43, + 16, 16, 16, 16, 47, 47, 47, 47, 16, 16, 16, 16, 16, 16, 16, 43, + 16, 16, 16, 16,111,111,111,111, 16, 16,109, 16, 11, 11,112,113, + 40, 16,109, 16, 11, 11,112, 40, 16, 16, 43, 16, 11, 11,114, 40, + 16, 16, 16, 16, 11, 11,115, 40, 43, 16,109, 16, 11, 11,112,116, + 117,117,117,117,117,118, 64, 64,119,119,119, 2,120,121,120,121, + 2, 2, 2, 2,122, 64, 64,123, 2, 2, 2, 2,124,125, 2,126, + 127, 2,128,129, 2, 2, 2, 2, 2, 9,127, 2, 2, 2, 2,130, + 64, 64,131, 64, 64, 64, 64, 64,132, 43, 27, 27, 27, 8,128,133, + 27, 27, 27, 27, 27, 8,128,103, 39, 39, 39, 39, 39, 39, 80, 43, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 43, 43, 43, 43, 43, 43, 43, + 42, 42, 42, 42, 42, 42,134, 50,108, 50,108, 42, 42, 42, 42, 42, + 79, 43, 43, 43, 43, 43, 43, 43, 66,135, 66,136, 66, 34, 11, 16, + 11, 32,136, 66, 48, 11, 11, 66, 66, 66,135,135,135, 11, 11,137, + 11, 11, 35, 36,138, 66, 16, 11, 8, 8, 48, 16, 16, 26, 66,139, + 27, 27, 27, 27, 27, 27, 27, 27,104,104,104,104,104,104,104,104, + 104,140,141,104,142, 66, 43, 43, 8, 8,143, 66, 66, 8, 66, 66, + 143, 26, 66,143, 66, 66, 66,143, 66, 66, 66, 66, 66, 66, 66, 8, + 66,143,143, 66, 66, 66, 66, 66, 66, 66, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 66, 66, 66, 66, 4, 4, 66, 66, + 8, 66, 66, 66,144,145, 66, 66, 66, 66, 66, 66, 66, 66,143, 66, + 66, 66, 66, 66, 66, 26, 8, 8, 8, 8, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 8, 8, 8, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 91, 43, 43, 27, 27, 27, 27, 27, 27, 66, 66, + 66, 66, 66, 66, 66, 27, 27, 27, 66, 66, 66, 26, 66, 66, 66, 66, + 26, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 8, 8, 8, 8, + 66, 66, 66, 66, 66, 66, 66, 26, 66, 66, 66, 66, 4, 4, 4, 4, + 4, 4, 4, 27, 27, 27, 27, 27, 27, 27, 66, 66, 66, 66, 66, 66, + 8, 8,128,146, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, + 8,128,147,147,147,147,147,147,147,147,147,147,146, 8, 8, 8, + 8, 8, 8, 8, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 4, 8, + 8, 8,143, 26, 8, 8,143, 66, 66, 66, 43, 66, 66, 66, 66, 66, + 32, 11, 32, 34, 34, 34, 34, 11, 32, 32, 34, 16, 16, 16, 39, 11, + 32, 32,139, 66, 66,136, 34,148, 42, 32, 43, 43, 92, 2, 98, 2, + 16, 16, 16,149, 43, 43,149, 43, 36, 36, 36, 36, 43, 43, 43, 51, + 63, 43, 43, 43, 43, 43, 43, 56, 36, 36, 36, 60, 43, 43, 43, 43, + 36, 36, 36, 60, 36, 36, 36, 60, 2,120,120, 2,124,125,120, 2, + 2, 2, 2, 6, 2,107,120, 2,120, 4, 4, 4, 4, 2, 2, 87, + 2, 2, 2, 2, 2,119, 2, 2,107,150, 2, 2, 2, 2, 2, 2, + 66, 2,151,147,147,147,152, 43, 66, 66, 66, 66, 66, 54, 66, 66, + 66, 66, 43, 43, 43, 43, 43, 43, 66, 66, 66, 43, 43, 43, 43, 43, + 1, 2,153,154, 4, 4, 4, 4, 4, 66, 4, 4, 4, 4,155,156, + 157,104,104,104,104, 42, 42, 85,158, 39, 39, 66,104,159, 62, 66, + 36, 36, 36, 60, 56,160,161, 68, 36, 36, 36, 36, 36, 62, 39, 68, + 43, 43, 61, 36, 36, 36, 36, 36, 66, 27, 27, 66, 66, 66, 66, 66, + 66, 66, 66, 43, 43, 43, 43, 54, 66, 66, 66, 66, 66, 66, 66, 91, + 27, 27, 27, 27, 27, 66, 66, 66, 66, 66, 66, 66, 27, 27, 27, 27, + 162, 27, 27, 27, 27, 27, 27, 27, 36, 36, 82, 36, 36, 36, 36, 36, + 66, 66, 66, 91, 43, 43, 43, 43, 36, 36, 36, 36, 36, 36,163, 2, + 7, 7, 7, 7, 7, 36, 43, 43, 32, 32, 32, 32, 32, 32, 32, 69, + 50,164, 42, 42, 42, 42, 42, 87, 32, 32, 32, 32, 32, 32, 39, 42, + 36, 36, 36,104,104,104,104,104, 42, 2, 2, 2, 43, 43, 43, 43, + 40, 40, 40,161, 39, 39, 39, 39, 40, 32, 32, 32, 32, 32, 32, 32, + 16, 32, 32, 32, 32, 32, 32, 32, 44, 16, 16, 16, 34, 34, 34, 32, + 32, 32, 32, 32, 41,165, 34, 35, 32, 32, 16, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 11, 11, 32, 11, 11, 32, 32, 32, 32, 32, 32, - 32, 32, 11, 11, 34, 34, 32, 44, 32,150,150, 32, 32, 32, 47, 44, - 44, 40,167, 35, 40, 35, 36, 36, 36, 71, 36, 71, 36, 70, 36, 36, - 36, 94, 87, 85, 67, 67, 80, 44, 27, 27, 27, 67,168, 44, 44, 44, - 36, 36, 2, 2, 44, 44, 44, 44, 86, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 86, 86, 86, 86, 86, 86, 86, 86, 43, 44, 44, 44, 44, 2, - 43, 36, 36, 36, 2, 72, 72, 70, 36, 36, 36, 43, 43, 43, 43, 2, - 36, 36, 36, 70, 43, 43, 43, 43, 43, 86, 44, 44, 44, 44, 44, 93, - 36, 70, 86, 43, 43, 86, 43, 86,107, 2, 2, 2, 2, 2, 2, 52, - 7, 7, 7, 7, 7, 44, 44, 2, 36, 36, 70, 69, 36, 36, 36, 36, - 7, 7, 7, 7, 7, 36, 36, 61, 36, 36, 36, 36, 70, 43, 43, 85, - 87, 85, 87, 80, 44, 44, 44, 44, 36, 70, 36, 36, 36, 36, 85, 44, - 7, 7, 7, 7, 7, 44, 2, 2, 69, 36, 36, 77, 67, 94, 85, 36, - 71, 43, 71, 70, 71, 36, 36, 43, 70, 61, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 62, 83, 2, 36, 36, 36, 36, 36, 94, 43, 86, - 2, 83,169, 80, 44, 44, 44, 44, 62, 36, 36, 61, 62, 36, 36, 61, - 62, 36, 36, 61, 44, 44, 44, 44, 16, 16, 16, 16, 16,114, 40, 40, - 16, 16, 16, 16,111, 41, 44, 44, 36, 94, 87, 86, 85,107, 87, 44, - 36, 36, 44, 44, 44, 44, 44, 44, 36, 36, 36, 61, 44, 62, 36, 36, - 170,170,170,170,170,170,170,170,171,171,171,171,171,171,171,171, - 16, 16, 16,110, 44, 44, 44, 44, 44,150, 16, 16, 44, 44, 62, 71, - 36, 36, 36, 36,172, 36, 36, 36, 36, 36, 36, 61, 36, 36, 61, 61, - 36, 62, 61, 36, 36, 36, 36, 36, 36, 41, 41, 41, 41, 41, 41, 41, - 41,117, 44, 44, 44, 44, 44, 44, 44, 62, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36,148, 44, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 44, 44, 44, 55, 36, 36, 36, 36, 36, 36,168, 67, - 2, 2, 2,152,130, 44, 44, 44, 6,173,174,148,148,148,148,148, - 148,148,130,152,130, 2,127,175, 2, 64, 2, 2,156,148,148,130, - 2,176, 8,177, 66, 2, 44, 44, 36, 36, 61, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 61, 79, 93, 2, 3, 2, 4, 5, 6, 2, - 16, 16, 16, 16, 16, 17, 18,129,130, 4, 2, 36, 36, 36, 36, 36, - 69, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 40, - 44, 36, 36, 36, 44, 36, 36, 36, 44, 36, 36, 36, 44, 36, 61, 44, - 20,178, 56,135, 26, 8,144, 92, 44, 44, 44, 44, 79, 65, 67, 44, - 36, 36, 36, 36, 36, 36, 62, 36, 36, 36, 36, 36, 36, 61, 36, 62, - 2, 64, 44,179, 27, 27, 27, 27, 27, 27, 44, 55, 67, 67, 67, 67, - 105,105,143, 27, 91, 67, 67, 67, 67, 67, 67, 67, 67, 27, 67, 92, - 67, 67, 67, 67, 67, 67, 92, 44, 92, 44, 44, 44, 44, 44, 44, 44, - 67, 67, 67, 67, 67, 67, 50, 44,180, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 44, 44, 27, 27, 44, 44, 44, 44, 62, 36, - 155, 36, 36, 36, 36,181, 44, 44, 36, 36, 36, 43, 43, 80, 44, 44, - 36, 36, 36, 36, 36, 36, 36, 93, 36, 36, 44, 44, 36, 36, 36, 36, - 182,105,105, 44, 44, 44, 44, 44, 11, 11, 11, 11, 16, 16, 16, 16, - 11, 11, 44, 44, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 44, 44, - 36, 36, 36, 36, 44, 44, 44, 44, 36, 36, 44, 44, 44, 44, 44, 93, - 11, 11, 11, 11, 11, 47, 11, 11, 11, 47, 11,150, 16, 16, 16, 16, - 16,150, 16, 16, 16, 16, 16, 16, 16,150, 16, 16, 16,150,110, 44, - 40, 40, 40, 52, 40, 40, 40, 40, 81, 40, 40, 40, 40, 81, 44, 44, - 36, 36, 36, 44, 61, 36, 36, 36, 36, 36, 36, 62, 61, 44, 61, 62, - 36, 36, 36, 93, 27, 27, 27, 27, 36, 36, 36, 77,163, 27, 27, 27, - 44, 44, 44,179, 27, 27, 27, 27, 36, 61, 36, 44, 44,179, 27, 27, - 36, 36, 36, 27, 27, 27, 44, 93, 36, 36, 36, 36, 36, 44, 44, 93, - 36, 36, 36, 36, 44, 44, 27, 36, 44, 27, 27, 27, 27, 27, 27, 27, - 70, 43, 57, 80, 44, 44, 43, 43, 36, 36, 62, 36, 62, 36, 36, 36, - 36, 36, 36, 44, 43, 80, 44, 57, 27, 27, 27, 27,100, 44, 44, 44, - 2, 2, 2, 2, 64, 44, 44, 44, 36, 36, 36, 36, 36, 36,183, 30, - 36, 36, 36, 36, 36, 36,183, 27, 36, 36, 36, 36, 78, 36, 36, 36, - 36, 36, 70, 80, 44,179, 27, 27, 2, 2, 2, 64, 44, 44, 44, 44, - 36, 36, 36, 44, 93, 2, 2, 2, 36, 36, 36, 44, 27, 27, 27, 27, - 36, 61, 44, 44, 27, 27, 27, 27, 36, 44, 44, 44, 93, 2, 64, 44, - 44, 44, 44, 44,179, 27, 27, 27, 11, 47, 44, 44, 44, 44, 44, 44, - 16,110, 44, 44, 44, 27, 27, 27, 36, 36, 43, 43, 44, 44, 44, 44, - 7, 7, 7, 7, 7, 36, 36, 69, 11, 11, 11, 44, 57, 43, 43,159, - 16, 16, 16, 44, 44, 44, 44, 8, 27, 27, 27, 27, 27, 27, 27,100, - 36, 36, 36, 36, 36, 57,184, 44, 36, 44, 44, 44, 44, 44, 44, 44, - 44, 36, 61, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 43, 43, - 27, 27, 27, 95, 44, 44, 44, 44,180, 27, 30, 2, 2, 44, 44, 44, - 36, 43, 43, 2, 2, 44, 44, 44, 36, 36,183, 27, 27, 27, 44, 44, - 87, 98, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, 43, - 43, 43, 43, 60, 2, 2, 2, 44, 27, 27, 27, 7, 7, 7, 7, 7, - 71, 70, 71, 44, 44, 44, 44, 57, 86, 87, 43, 85, 87, 60,185, 2, - 2, 80, 44, 44, 44, 44, 79, 44, 43, 71, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 70, 43, 43, 87, 43, 43, 43, 80, 7, 7, 7, 7, 7, - 2, 2, 94, 98, 44, 44, 44, 44, 36, 70, 2, 61, 44, 44, 44, 44, - 36, 94, 86, 43, 43, 43, 43, 85, 98, 36, 63, 2, 59, 43, 60, 87, - 7, 7, 7, 7, 7, 63, 63, 2,179, 27, 27, 27, 27, 27, 27, 27, - 27, 27,100, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 86, 87, - 43, 86, 85, 43, 2, 2, 2, 71, 70, 44, 44, 44, 44, 44, 44, 44, - 36, 36, 36, 61, 61, 36, 36, 62, 36, 36, 36, 36, 36, 36, 36, 62, - 36, 36, 36, 36, 63, 44, 44, 44, 36, 36, 36, 36, 36, 36, 36, 70, - 86, 87, 43, 43, 43, 80, 44, 44, 43, 86, 62, 36, 36, 36, 61, 62, - 61, 36, 62, 36, 36, 57, 71, 86, 85, 86, 90, 89, 90, 89, 86, 44, - 61, 44, 44, 89, 44, 44, 62, 36, 36, 86, 44, 43, 43, 43, 80, 44, - 43, 43, 80, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 62, 44, 61, - 36, 36, 36, 62, 86, 87, 43, 43, 80, 90, 89, 89, 86, 90, 86, 85, - 71, 71, 2, 93, 64, 44, 44, 44, 57, 80, 44, 44, 44, 44, 44, 44, - 36, 36, 94, 86, 43, 43, 43, 43, 86, 43, 85, 71, 36, 63, 2, 2, - 7, 7, 7, 7, 7, 2, 93, 71, 86, 87, 43, 43, 85, 85, 86, 87, - 85, 43, 36, 72, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 36, 94, - 86, 43, 43, 44, 86, 86, 43, 87, 60, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 36, 36, 43, 44, 86, 87, 43, 43, 43, 85, 87, 87, - 60, 2, 61, 44, 44, 44, 44, 44, 2, 2, 2, 2, 2, 2, 64, 44, - 36, 36, 36, 36, 36, 70, 87, 86, 43, 43, 43, 87, 63, 44, 44, 44, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 44, 44, 44, 44, 44, 44, - 36, 36, 36, 36, 36, 61, 57, 87, 86, 43, 43, 87, 43, 43, 44, 44, - 7, 7, 7, 7, 7, 27, 2, 97, 43, 43, 43, 43, 87, 60, 44, 44, - 27,100, 44, 44, 44, 44, 44, 62, 36, 36, 36, 61, 62, 44, 36, 36, - 36, 36, 62, 61, 36, 36, 36, 36, 86, 86, 86, 89, 90, 57, 85, 71, - 98, 87, 2, 64, 44, 44, 44, 44, 36, 36, 36, 36, 44, 36, 36, 36, - 94, 86, 43, 43, 44, 43, 86, 86, 71, 72, 90, 44, 44, 44, 44, 44, - 70, 43, 43, 43, 43, 71, 36, 36, 36, 70, 43, 43, 85, 70, 43, 60, - 2, 2, 2, 59, 44, 44, 44, 44, 70, 43, 43, 85, 87, 43, 36, 36, - 36, 36, 36, 36, 36, 43, 43, 43, 43, 43, 43, 85, 43, 2, 72, 2, - 2, 64, 44, 44, 44, 44, 44, 44, 2, 2, 2, 2, 2, 44, 44, 44, - 63, 44, 44, 44, 44, 44, 44, 44, 43, 43, 43, 80, 43, 43, 43, 87, - 63, 2, 2, 44, 44, 44, 44, 44, 2, 36, 36, 36, 36, 36, 36, 36, - 44, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 89, 43, 43, 43, - 85, 43, 87, 80, 44, 44, 44, 44, 36, 36, 36, 61, 36, 62, 36, 36, - 70, 43, 43, 80, 44, 80, 43, 57, 43, 43, 43, 70, 44, 44, 44, 44, - 36, 36, 36, 62, 61, 36, 36, 36, 36, 36, 36, 36, 36, 86, 86, 90, - 43, 89, 87, 87, 61, 44, 44, 44, 36, 70, 85,107, 64, 44, 44, 44, - 43, 94, 36, 36, 36, 36, 36, 36, 36, 36, 86, 43, 43, 80, 44, 86, - 85, 60, 2, 2, 2, 2, 2, 2, 7, 7, 7, 7, 7, 80, 44, 44, - 27, 27, 91, 67, 67, 67, 56, 20,168, 67, 67, 67, 67, 67, 67, 67, - 67, 44, 44, 44, 44, 44, 44, 93,105,105,105,105,105,105,105,181, - 2, 2, 64, 44, 44, 44, 44, 44, 63, 64, 44, 44, 44, 44, 44, 44, - 65, 65, 65, 65, 65, 65, 65, 65, 71, 36, 36, 70, 43, 43, 43, 43, - 43, 43, 43, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 36, 43, - 43, 43, 43, 43, 43, 86, 87, 43, 43, 43, 60, 44, 44, 44, 44, 44, - 43, 43, 43, 60, 2, 2, 67, 67, 40, 40, 97, 44, 44, 44, 44, 44, - 7, 7, 7, 7, 7,179, 27, 27, 27, 62, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 44, 44, 62, 36, 40, 69, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 83,164, 2, 27, 27, 27, 30, 2, 64, 44, 44, - 36, 36, 36, 36, 36, 61, 44, 57, 94, 86, 86, 86, 86, 86, 86, 86, - 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 44, 44, 44, 57, - 43, 74, 40, 40, 40, 40, 40, 40, 40, 88, 80, 44, 44, 44, 44, 44, - 86, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 62, - 40, 40, 52, 40, 40, 40, 52, 81, 36, 61, 44, 44, 44, 44, 44, 44, - 44, 61, 44, 44, 44, 44, 44, 44, 36, 61, 62, 44, 44, 44, 44, 44, - 44, 44, 36, 36, 44, 44, 44, 44, 36, 36, 36, 36, 36, 44, 50, 60, - 65, 65, 44, 44, 44, 44, 44, 44, 43, 43, 43, 43, 43, 43, 43, 44, - 43, 43, 43, 80, 44, 44, 44, 44, 67, 67, 67, 92, 55, 67, 67, 67, - 67, 67,186, 87, 43, 67,186, 86, 86,187, 65, 65, 65, 84, 43, 43, - 43, 76, 50, 43, 43, 43, 67, 67, 67, 67, 67, 67, 67, 43, 43, 67, - 67, 43, 76, 44, 44, 44, 44, 44, 27, 27, 44, 44, 44, 44, 44, 44, - 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 16, 16, 16,110, 16, 16, 16, 16, 16, - 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 47, 11, - 44, 47, 48, 47, 48, 11, 47, 11, 11, 11, 11, 16, 16,150,150, 16, - 16, 16,150, 16, 16, 16, 16, 16, 16, 16, 11, 48, 11, 47, 48, 11, - 11, 11, 47, 11, 11, 11, 47, 16, 16, 16, 16, 16, 11, 48, 11, 47, - 11, 11, 47, 47, 44, 11, 11, 11, 47, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, - 16, 16, 16, 44, 11, 11, 11, 11, 31, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, - 11, 11, 31, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 33, - 16, 16, 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 31, - 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 31, 16, 16, 16, - 16, 33, 16, 16, 16, 32, 44, 7, 43, 43, 43, 76, 67, 50, 43, 43, - 43, 43, 43, 43, 43, 43, 76, 67, 67, 67, 50, 67, 67, 67, 67, 67, - 67, 67, 76, 21, 2, 2, 44, 44, 44, 44, 44, 44, 44, 57, 43, 43, - 16, 16, 16, 16, 16, 39, 16, 16, 16, 16, 16, 16, 16, 16, 16,110, - 44, 44,150, 16, 16,110, 44, 44, 43, 43, 43, 80, 43, 43, 43, 43, - 43, 43, 43, 43, 80, 57, 43, 43, 43, 57, 80, 43, 43, 80, 44, 44, - 40, 40, 40, 40, 40, 40, 40, 44, 44, 44, 44, 44, 44, 44, 44, 57, - 43, 43, 43, 74, 40, 40, 40, 44, 7, 7, 7, 7, 7, 44, 44, 77, - 36, 36, 36, 36, 36, 36, 36, 80, 36, 36, 36, 36, 36, 36, 43, 43, - 7, 7, 7, 7, 7, 44, 44, 96, 36, 36, 36, 36, 36, 83, 43, 43, - 188, 7, 7, 7, 7,189, 44, 93, 36, 36, 36, 61, 36, 36, 62, 61, - 36, 36, 61,179, 27, 27, 27, 27, 16, 16, 43, 43, 43, 74, 44, 44, - 27, 27, 27, 27, 27, 27,163, 27,190, 27,100, 44, 44, 44, 44, 44, - 27, 27, 27, 27, 27, 27, 27,163, 27, 27, 27, 27, 27, 27, 27, 44, - 36, 36, 62, 36, 36, 36, 36, 36, 62, 61, 61, 62, 62, 36, 36, 36, - 36, 61, 36, 36, 62, 62, 44, 44, 44, 61, 44, 62, 62, 62, 62, 36, - 62, 61, 61, 62, 62, 62, 62, 62, 62, 61, 61, 62, 36, 61, 36, 36, - 36, 61, 36, 36, 62, 36, 61, 61, 36, 36, 36, 36, 36, 62, 36, 36, - 62, 36, 62, 36, 36, 62, 36, 36, 8, 44, 44, 44, 44, 44, 44, 44, - 67, 67, 67, 67, 67, 67, 44, 44, 55, 67, 67, 67, 67, 67, 67, 67, - 27, 27, 27, 27, 27, 27, 91, 67, 67, 67, 67, 67, 67, 67, 67, 44, - 44, 44, 44, 67, 67, 67, 67, 67, 67, 92, 44, 44, 44, 44, 44, 44, - 67, 67, 67, 67, 92, 44, 44, 44, 67, 44, 44, 44, 44, 44, 44, 44, - 67, 67, 67, 67, 67, 25, 41, 41, 67, 67, 67, 67, 44, 44, 67, 67, - 67, 67, 67, 92, 44, 55, 67, 67, 67, 67, 67, 67, 44, 44, 44, 44, - 67, 67, 67, 67, 67, 44, 44, 55, 67, 67, 67, 92, 44, 44, 44, 67, - 67, 67, 67, 67, 67, 67, 92, 55, 67, 92, 67, 67, 67, 67, 67, 67, - 79, 44, 44, 44, 44, 44, 44, 44,171,171,171,171,171,171,171, 44, - 171,171,171,171,171,171,171, 0, 0, 0, 29, 21, 21, 21, 23, 21, - 22, 18, 21, 25, 21, 17, 13, 13, 25, 25, 25, 21, 21, 9, 9, 9, - 9, 22, 21, 18, 24, 16, 24, 5, 5, 5, 5, 22, 25, 18, 25, 0, - 23, 23, 26, 21, 24, 26, 7, 20, 25, 1, 26, 24, 26, 25, 15, 15, - 24, 15, 7, 19, 15, 21, 9, 25, 9, 5, 5, 25, 5, 9, 5, 7, - 7, 7, 9, 8, 8, 5, 7, 5, 6, 6, 24, 24, 6, 24, 12, 12, - 2, 2, 6, 5, 9, 21, 9, 2, 2, 9, 25, 9, 26, 12, 11, 11, - 2, 6, 5, 21, 17, 2, 2, 26, 26, 23, 2, 12, 17, 12, 21, 12, - 12, 21, 7, 2, 2, 7, 7, 21, 21, 2, 1, 1, 21, 23, 26, 26, - 1, 21, 6, 7, 7, 12, 12, 7, 21, 7, 12, 1, 12, 6, 6, 12, - 12, 26, 7, 26, 26, 7, 2, 1, 12, 2, 6, 2, 24, 7, 7, 6, - 1, 12, 12, 10, 10, 10, 10, 12, 21, 6, 2, 10, 10, 2, 15, 26, - 26, 2, 2, 21, 7, 10, 15, 7, 2, 23, 21, 26, 10, 7, 21, 15, - 15, 2, 17, 7, 29, 7, 7, 22, 18, 2, 14, 14, 14, 7, 10, 21, - 17, 21, 11, 12, 5, 2, 5, 6, 8, 8, 8, 24, 5, 24, 2, 24, - 9, 24, 24, 2, 29, 29, 29, 1, 17, 17, 20, 19, 22, 20, 27, 28, - 1, 29, 21, 20, 19, 21, 21, 16, 16, 21, 25, 22, 18, 21, 21, 29, - 1, 2, 15, 6, 18, 6, 23, 2, 12, 11, 9, 26, 26, 9, 26, 5, - 5, 26, 14, 9, 5, 14, 14, 15, 25, 26, 26, 22, 18, 26, 18, 25, - 18, 22, 5, 12, 2, 5, 22, 21, 21, 22, 18, 17, 26, 6, 7, 14, - 17, 22, 18, 18, 26, 14, 17, 6, 14, 6, 12, 24, 24, 6, 26, 15, - 6, 21, 11, 21, 24, 9, 6, 9, 23, 26, 6, 10, 4, 4, 3, 3, - 7, 25, 17, 16, 16, 22, 16, 16, 25, 17, 25, 2, 25, 24, 2, 15, - 12, 15, 14, 2, 21, 14, 7, 15, 12, 17, 21, 1, 26, 10, 10, 1, - 7, 13, 13, 2, 23, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 0, 10, 11, 12, 13, 0, 14, 0, 0, 0, 0, 0, 15, 0, 16, 0, + 32, 32, 11, 11, 34, 34, 32, 32, 32, 32, 32, 32, 32, 32, 46, 43, + 51, 39,166, 35, 39, 35, 36, 36, 36, 70, 36, 70, 36, 69, 36, 36, + 36, 93, 86, 84, 66, 66, 79, 43, 27, 27, 27, 66,167, 43, 43, 43, + 36, 36, 2, 2, 43, 43, 43, 43, 85, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 85, 85, 85, 85, 85, 85, 85, 85, 42, 43, 43, 43, 43, 2, + 42, 36, 36, 36, 2, 71, 71, 69, 36, 36, 36, 42, 42, 42, 42, 2, + 36, 36, 36, 69, 42, 42, 42, 42, 42, 85, 43, 43, 43, 43, 43, 92, + 36, 69, 85, 42, 42, 85, 42, 85,106, 2, 2, 2, 2, 2, 2, 51, + 7, 7, 7, 7, 7, 43, 43, 2, 36, 36, 69, 68, 36, 36, 36, 36, + 7, 7, 7, 7, 7, 36, 36, 60, 36, 36, 36, 36, 69, 42, 42, 84, + 86, 84, 86, 79, 43, 43, 43, 43, 36, 69, 36, 36, 36, 36, 84, 43, + 7, 7, 7, 7, 7, 43, 2, 2, 68, 36, 36, 76, 66, 93, 84, 36, + 70, 42, 70, 69, 70, 36, 36, 42, 69, 60, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 61, 82, 2, 36, 36, 36, 36, 36, 93, 42, 85, + 2, 82,168, 79, 43, 43, 43, 43, 61, 36, 36, 60, 61, 36, 36, 60, + 61, 36, 36, 60, 43, 43, 43, 43, 16, 16, 16, 16, 16,113, 39, 39, + 16, 16, 16, 16,110, 40, 43, 43, 36, 93, 86, 85, 84,106, 86, 43, + 36, 36, 43, 43, 43, 43, 43, 43, 36, 36, 36, 60, 43, 61, 36, 36, + 169,169,169,169,169,169,169,169,170,170,170,170,170,170,170,170, + 16, 16, 16,109, 43, 43, 43, 43, 43,149, 16, 16, 43, 43, 61, 70, + 36, 36, 36, 36,171, 36, 36, 36, 36, 36, 36, 60, 36, 36, 60, 60, + 36, 61, 60, 36, 36, 36, 36, 36, 36, 40, 40, 40, 40, 40, 40, 40, + 40, 22, 66, 66, 66, 66, 66, 66, 66, 77, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36,147, 66, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 66, 66, 66, 66, 36, 36, 36, 36, 36, 36,167, 66, + 2, 2, 2,151,129, 43, 43, 43, 6,172,173,147,147,147,147,147, + 147,147,129,151,129, 2,126,174, 2, 63, 2, 2,155,147,147,129, + 2,175, 8,176, 65, 2, 43, 43, 36, 36, 60, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 60, 78, 92, 2, 3, 2, 4, 5, 6, 2, + 16, 16, 16, 16, 16, 17, 18,128,129, 4, 2, 36, 36, 36, 36, 36, + 68, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 39, + 43, 36, 36, 36, 43, 36, 36, 36, 43, 36, 36, 36, 43, 36, 60, 43, + 20,177, 55,178, 26, 8,143, 91, 43, 43, 43, 43, 78, 64, 66, 43, + 36, 36, 36, 36, 36, 36, 61, 36, 36, 36, 36, 36, 36, 60, 36, 61, + 2, 63, 43,179, 27, 27, 27, 27, 27, 27, 43, 54, 66, 66, 66, 66, + 104,104,142, 27, 90, 66, 66, 66, 66, 66, 66, 66, 66, 27, 66, 91, + 66, 66, 66, 66, 66, 66, 91, 43, 91, 43, 43, 43, 43, 43, 43, 43, + 66, 66, 66, 66, 66, 66, 49, 43,180, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 43, 43, 27, 27, 43, 43, 43, 43, 61, 36, + 154, 36, 36, 36, 36,181, 43, 43, 36, 36, 36, 42, 42, 79, 43, 43, + 36, 36, 36, 36, 36, 36, 36, 92, 36, 36, 43, 43, 36, 36, 36, 36, + 182,104,104, 43, 43, 43, 43, 43, 11, 11, 11, 11, 16, 16, 16, 16, + 11, 11, 43, 43, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 43, 43, + 36, 36, 36, 36, 43, 43, 43, 43, 36, 36, 43, 43, 43, 43, 43, 92, + 11, 11, 11, 11, 11, 46, 11, 11, 11, 46, 11,149, 16, 16, 16, 16, + 16,149, 16, 16, 16, 16, 16, 16, 16,149, 16, 16, 16,149,109, 43, + 39, 39, 39, 51, 39, 39, 39, 39, 80, 39, 39, 39, 39, 80, 43, 43, + 36, 36, 36, 43, 60, 36, 36, 36, 36, 36, 36, 61, 60, 43, 60, 61, + 36, 36, 36, 92, 27, 27, 27, 27, 36, 36, 36, 76,162, 27, 27, 27, + 43, 43, 43,179, 27, 27, 27, 27, 36, 60, 36, 43, 43,179, 27, 27, + 36, 36, 36, 27, 27, 27, 43, 92, 36, 36, 36, 36, 36, 43, 43, 92, + 36, 36, 36, 36, 43, 43, 27, 36, 43, 27, 27, 27, 27, 27, 27, 27, + 69, 42, 56, 79, 43, 43, 42, 42, 36, 36, 61, 36, 61, 36, 36, 36, + 36, 36, 36, 43, 42, 79, 43, 56, 27, 27, 27, 27, 99, 43, 43, 43, + 2, 2, 2, 2, 63, 43, 43, 43, 36, 36, 36, 36, 36, 36,183, 30, + 36, 36, 36, 36, 36, 36,183, 27, 36, 36, 36, 36, 77, 36, 36, 36, + 36, 36, 69, 79, 43,179, 27, 27, 2, 2, 2, 63, 43, 43, 43, 43, + 36, 36, 36, 43, 92, 2, 2, 2, 36, 36, 36, 43, 27, 27, 27, 27, + 36, 60, 43, 43, 27, 27, 27, 27, 36, 43, 43, 43, 92, 2, 63, 43, + 43, 43, 43, 43,179, 27, 27, 27, 11, 46, 43, 43, 43, 43, 43, 43, + 16,109, 43, 43, 43, 27, 27, 27, 36, 36, 42, 42, 43, 43, 43, 43, + 7, 7, 7, 7, 7, 36, 36, 68, 11, 11, 11, 43, 56, 42, 42,158, + 16, 16, 16, 43, 43, 43, 43, 8, 27, 27, 27, 27, 27, 27, 27, 99, + 36, 36, 36, 36, 36, 56,184, 43, 36, 43, 43, 43, 43, 43, 43, 43, + 43, 36, 82, 36, 43, 43, 43, 43, 96, 66, 66, 66, 91, 43, 43, 43, + 43, 43, 43, 43, 43, 42, 42, 42, 27, 27, 27, 94, 43, 43, 43, 43, + 180, 27, 30, 2, 2, 43, 43, 43, 36, 42, 42, 2, 2, 43, 43, 43, + 36, 36,183, 27, 27, 27, 43, 43, 86, 97, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 42, 42, 42, 42, 42, 42, 42, 59, 2, 2, 2, 43, + 27, 27, 27, 7, 7, 7, 7, 7, 70, 69, 70, 43, 43, 43, 43, 56, + 85, 86, 42, 84, 86, 59,185, 2, 2, 79, 43, 43, 43, 43, 78, 43, + 42, 70, 36, 36, 36, 36, 36, 36, 36, 36, 36, 69, 42, 42, 86, 42, + 42, 42, 79, 7, 7, 7, 7, 7, 2, 2, 93, 97, 43, 43, 43, 43, + 36, 69, 2, 60, 43, 43, 43, 43, 36, 93, 85, 42, 42, 42, 42, 84, + 97, 36, 62, 2, 58, 42, 59, 86, 7, 7, 7, 7, 7, 62, 62, 2, + 179, 27, 27, 27, 27, 27, 27, 27, 27, 27, 99, 43, 43, 43, 43, 43, + 36, 36, 36, 36, 36, 36, 85, 86, 42, 85, 84, 42, 2, 2, 2, 70, + 69, 43, 43, 43, 43, 43, 43, 43, 36, 36, 36, 60, 60, 36, 36, 61, + 36, 36, 36, 36, 36, 36, 36, 61, 36, 36, 36, 36, 62, 43, 43, 43, + 36, 36, 36, 36, 36, 36, 36, 69, 85, 86, 42, 42, 42, 79, 43, 43, + 42, 85, 61, 36, 36, 36, 60, 61, 60, 36, 61, 36, 36, 56, 70, 85, + 84, 85, 89, 88, 89, 88, 85, 43, 60, 43, 43, 88, 43, 43, 61, 36, + 36, 85, 43, 42, 42, 42, 79, 43, 42, 42, 79, 43, 43, 43, 43, 43, + 36, 36, 36, 36, 36, 61, 43, 60, 36, 36, 36, 61, 85, 86, 42, 42, + 79, 89, 88, 88, 85, 89, 85, 84, 70, 70, 2, 92, 63, 43, 43, 43, + 56, 79, 43, 43, 43, 43, 43, 43, 36, 36, 93, 85, 42, 42, 42, 42, + 85, 42, 84, 70, 36, 62, 2, 2, 7, 7, 7, 7, 7, 2, 92, 70, + 85, 86, 42, 42, 84, 84, 85, 86, 84, 42, 36, 71, 43, 43, 43, 43, + 36, 36, 36, 36, 36, 36, 36, 93, 85, 42, 42, 43, 85, 85, 42, 86, + 59, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 36, 36, 42, 43, + 85, 86, 42, 42, 42, 84, 86, 86, 59, 2, 60, 43, 43, 43, 43, 43, + 2, 2, 2, 2, 2, 2, 63, 43, 36, 36, 36, 36, 36, 69, 86, 85, + 42, 42, 42, 86, 62, 43, 43, 43, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 43, 43, 43, 43, 43, 43, 36, 36, 36, 36, 36, 60, 56, 86, + 85, 42, 42, 86, 42, 42, 43, 43, 7, 7, 7, 7, 7, 27, 2, 96, + 42, 42, 42, 42, 86, 59, 43, 43, 27, 99, 43, 43, 43, 43, 43, 61, + 36, 36, 36, 60, 61, 43, 36, 36, 36, 36, 61, 60, 36, 36, 36, 36, + 85, 85, 85, 88, 89, 56, 84, 70, 97, 86, 2, 63, 43, 43, 43, 43, + 36, 36, 36, 36, 43, 36, 36, 36, 93, 85, 42, 42, 43, 42, 85, 85, + 70, 71, 89, 43, 43, 43, 43, 43, 69, 42, 42, 42, 42, 70, 36, 36, + 36, 69, 42, 42, 84, 69, 42, 59, 2, 2, 2, 58, 43, 43, 43, 43, + 69, 42, 42, 84, 86, 42, 36, 36, 36, 36, 36, 36, 36, 42, 42, 42, + 42, 42, 42, 84, 42, 2, 71, 2, 2, 63, 43, 43, 43, 43, 43, 43, + 2, 2, 2, 2, 2, 43, 43, 43, 84, 42, 84, 84, 43, 43, 43, 43, + 62, 43, 43, 43, 43, 43, 43, 43, 42, 42, 42, 79, 42, 42, 42, 86, + 62, 2, 2, 43, 43, 43, 43, 43, 2, 36, 36, 36, 36, 36, 36, 36, + 43, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 88, 42, 42, 42, + 84, 42, 86, 79, 43, 43, 43, 43, 36, 36, 36, 60, 36, 61, 36, 36, + 69, 42, 42, 79, 43, 79, 42, 56, 42, 42, 42, 69, 43, 43, 43, 43, + 36, 36, 36, 61, 60, 36, 36, 36, 36, 36, 36, 36, 36, 85, 85, 89, + 42, 88, 86, 86, 60, 43, 43, 43, 36, 36, 36, 36, 82, 36, 43, 43, + 36, 69, 84,106, 63, 43, 43, 43, 42, 93, 36, 36, 36, 36, 36, 36, + 36, 36, 85, 42, 42, 79, 43, 85, 84, 59, 2, 2, 2, 2, 2, 2, + 7, 7, 7, 7, 7, 79, 43, 43, 27, 27, 90, 66, 66, 66, 55, 20, + 167, 66, 66, 66, 66, 66, 66, 66, 66, 43, 43, 43, 43, 43, 43, 92, + 104,104,104,104,104,104,104,181, 2, 2, 63, 43, 43, 43, 43, 43, + 62, 63, 43, 43, 43, 43, 43, 43, 64, 64, 64, 64, 64, 64, 64, 64, + 70, 36, 36, 69, 42, 42, 42, 42, 42, 42, 42, 43, 43, 43, 43, 43, + 36, 36, 36, 36, 36, 36, 36, 42, 42, 42, 42, 42, 42, 85, 86, 42, + 42, 42, 59, 43, 43, 43, 43, 43, 42, 42, 42, 59, 2, 2, 66, 66, + 39, 39, 96, 43, 43, 43, 43, 43, 7, 7, 7, 7, 7,179, 27, 27, + 27, 61, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 43, 43, 61, 36, + 39, 68, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 82,163, 2, + 27, 27, 27, 30, 2, 63, 43, 43, 11, 11, 11, 11, 46,149, 16, 16, + 16, 16, 43, 43, 43, 43, 43, 43, 36, 36, 36, 36, 36, 60, 43, 56, + 93, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85, 43, 43, 43, 56, 42, 73, 39, 39, 39, 39, 39, 39, + 39, 87, 79, 43, 43, 43, 43, 43, 85, 39,104,181, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 61, 36, 60, 43, 43, 43, 43, 43, 43, + 39, 39, 51, 39, 39, 39, 51, 80, 43, 60, 43, 43, 43, 43, 43, 43, + 36, 60, 61, 43, 43, 43, 43, 43, 43, 43, 36, 36, 43, 43, 43, 43, + 36, 36, 36, 36, 36, 43, 49, 59, 64, 64, 43, 43, 43, 43, 43, 43, + 7, 7, 7, 7, 7, 66, 91, 43, 66, 66, 43, 43, 43, 66, 66, 66, + 176, 43, 43, 43, 43, 43, 43, 43, 42, 42, 42, 79, 43, 43, 43, 43, + 66, 66, 66, 91, 54, 66, 66, 66, 66, 66,186, 86, 42, 66,186, 85, + 85,187, 64, 64, 64, 83, 42, 42, 42, 75, 49, 42, 42, 42, 66, 66, + 66, 66, 66, 66, 66, 42, 42, 66, 66, 42, 75, 43, 43, 43, 43, 43, + 27, 27, 43, 43, 43, 43, 43, 43, 11, 11, 11, 11, 11, 16, 16, 16, + 16, 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 16, + 16, 16,109, 16, 16, 16, 16, 16, 11, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 46, 11, 43, 46, 47, 46, 47, 11, 46, 11, + 11, 11, 11, 16, 16,149,149, 16, 16, 16,149, 16, 16, 16, 16, 16, + 16, 16, 11, 47, 11, 46, 47, 11, 11, 11, 46, 11, 11, 11, 46, 16, + 16, 16, 16, 16, 11, 47, 11, 46, 11, 11, 46, 46, 43, 11, 11, 11, + 46, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 11, 11, + 11, 11, 11, 16, 16, 16, 16, 16, 16, 16, 16, 43, 11, 11, 11, 11, + 31, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 33, 16, 16, + 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 31, 16, 16, + 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 31, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, + 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, 32, 43, 7, + 42, 42, 42, 75, 66, 49, 42, 42, 42, 42, 42, 42, 42, 42, 75, 66, + 66, 66, 49, 66, 66, 66, 66, 66, 66, 66, 75, 21, 2, 2, 43, 43, + 43, 43, 43, 43, 43, 56, 42, 42, 16, 16, 16, 16, 16,138, 16, 16, + 16, 16, 16, 16, 16, 16, 16,109, 43, 43,149, 16, 16,109, 43, 43, + 42, 42, 42, 79, 42, 42, 42, 42, 42, 42, 42, 42, 79, 56, 42, 42, + 42, 56, 79, 42, 42, 79, 43, 43, 39, 39, 39, 39, 39, 39, 39, 43, + 43, 43, 43, 43, 43, 43, 43, 56, 42, 42, 42, 73, 39, 39, 39, 43, + 7, 7, 7, 7, 7, 43, 43, 76, 36, 36, 36, 36, 36, 36, 36, 79, + 36, 36, 36, 36, 36, 36, 42, 42, 7, 7, 7, 7, 7, 43, 43, 95, + 36, 36, 36, 36, 36, 82, 42, 42,188, 7, 7, 7, 7,189, 43, 92, + 36, 69, 36, 70, 36, 36, 36, 42, 36, 36, 69, 43, 43, 43, 43, 82, + 36, 36, 36, 60, 36, 36, 61, 60, 36, 36, 60,179, 27, 27, 27, 27, + 16, 16, 42, 42, 42, 73, 43, 43, 27, 27, 27, 27, 27, 27,162, 27, + 190, 27, 99, 43, 43, 43, 43, 43, 27, 27, 27, 27, 27, 27, 27,162, + 27, 27, 27, 27, 27, 27, 27, 43, 36, 36, 61, 36, 36, 36, 36, 36, + 61, 60, 60, 61, 61, 36, 36, 36, 36, 60, 36, 36, 61, 61, 43, 43, + 43, 60, 43, 61, 61, 61, 61, 36, 61, 60, 60, 61, 61, 61, 61, 61, + 61, 60, 60, 61, 36, 60, 36, 36, 36, 60, 36, 36, 61, 36, 60, 60, + 36, 36, 36, 36, 36, 61, 36, 36, 61, 36, 61, 36, 36, 61, 36, 36, + 8, 43, 43, 43, 43, 43, 43, 43, 66, 66, 66, 66, 66, 66, 43, 43, + 54, 66, 66, 66, 66, 66, 66, 66, 27, 27, 27, 27, 27, 27, 90, 66, + 66, 66, 66, 66, 66, 66, 66, 43, 43, 43, 43, 66, 66, 66, 66, 66, + 66, 91, 43, 43, 43, 43, 43, 43, 66, 66, 66, 66, 91, 43, 43, 43, + 66, 43, 43, 43, 43, 43, 43, 43, 66, 66, 66, 66, 66, 25, 40, 40, + 66, 66, 66, 66, 91, 43, 66, 66, 66, 66, 66, 66, 43, 43, 43, 43, + 8, 8, 8, 8,176, 43, 43, 43, 66, 66, 66, 66, 66, 91, 43, 66, + 66, 66, 66, 91, 91, 43, 54, 66, 66, 66, 66, 66, 66, 66, 91, 54, + 66, 66, 66, 66, 66, 91, 43, 54, 66, 91, 66, 66, 66, 66, 66, 66, + 7, 7, 7, 7, 7, 91, 43, 43, 78, 43, 43, 43, 43, 43, 43, 43, + 170,170,170,170,170,170,170, 43,170,170,170,170,170,170,170, 0, + 0, 0, 29, 21, 21, 21, 23, 21, 22, 18, 21, 25, 21, 17, 13, 13, + 25, 25, 25, 21, 21, 9, 9, 9, 9, 22, 21, 18, 24, 16, 24, 5, + 5, 5, 5, 22, 25, 18, 25, 0, 23, 23, 26, 21, 24, 26, 7, 20, + 25, 1, 26, 24, 26, 25, 15, 15, 24, 15, 7, 19, 15, 21, 9, 25, + 9, 5, 5, 25, 5, 9, 5, 7, 7, 7, 9, 8, 8, 5, 6, 6, + 24, 24, 6, 24, 12, 12, 2, 2, 6, 5, 9, 21, 9, 2, 2, 9, + 25, 9, 26, 12, 11, 11, 2, 6, 5, 21, 17, 2, 2, 26, 26, 23, + 2, 12, 17, 12, 21, 12, 12, 21, 7, 2, 2, 7, 7, 21, 21, 2, + 1, 1, 21, 23, 26, 26, 1, 21, 6, 7, 7, 12, 12, 7, 21, 7, + 12, 1, 12, 6, 6, 12, 12, 26, 7, 26, 26, 7, 2, 1, 12, 2, + 6, 2, 24, 7, 7, 6, 1, 12, 12, 10, 10, 10, 10, 12, 21, 6, + 2, 10, 10, 2, 15, 26, 26, 2, 2, 21, 7, 10, 15, 7, 2, 23, + 21, 26, 10, 7, 21, 15, 15, 2, 17, 7, 29, 7, 7, 22, 18, 2, + 14, 14, 14, 7, 10, 21, 17, 21, 11, 12, 5, 2, 5, 6, 8, 8, + 8, 24, 5, 24, 2, 24, 9, 24, 24, 2, 29, 29, 29, 1, 17, 17, + 20, 19, 22, 20, 27, 28, 1, 29, 21, 20, 19, 21, 21, 16, 16, 21, + 25, 22, 18, 21, 21, 29, 1, 2, 15, 6, 18, 6, 12, 11, 9, 26, + 26, 9, 26, 5, 7, 5, 5, 26, 14, 9, 5, 14, 14, 15, 25, 26, + 26, 22, 18, 26, 18, 25, 18, 22, 5, 12, 2, 5, 22, 21, 21, 22, + 18, 17, 26, 6, 7, 14, 17, 22, 18, 18, 26, 14, 17, 6, 14, 6, + 12, 24, 24, 6, 26, 15, 6, 21, 11, 21, 24, 9, 6, 9, 23, 26, + 6, 10, 4, 4, 3, 3, 7, 25, 17, 16, 16, 22, 16, 16, 25, 17, + 25, 2, 25, 24, 23, 2, 2, 15, 12, 15, 14, 2, 21, 14, 7, 15, + 12, 17, 21, 1, 26, 10, 10, 1, 7, 13, 13, 2, 23, 15, 0, 1, + 2, 3, 4, 5, 6, 7, 8, 9, 0, 10, 11, 12, 13, 0, 14, 0, + 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 18, 19, 0, 0, 0, 0, + 0, 17, 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 21, 22, 23, + 0, 0, 0, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 20, 0, 21, 22, 23, 0, 0, 0, 24, 25, 26, 27, 28, - 29, 30, 31, 32, 33, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, + 0, 0, 0, 36, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 36, 0, 37, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 40, - 0, 0, 0, 0, 0, 0, 41, 42, 43, 0, 44, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 3, 0, - 0, 0, 4, 5, 6, 7, 0, 8, 9, 10, 0, 11, 12, 13, 14, 15, - 16, 17, 16, 18, 16, 19, 16, 19, 16, 19, 0, 19, 16, 20, 16, 19, - 21, 19, 0, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 0, 32, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, - 34, 0, 0, 35, 0, 0, 36, 0, 37, 0, 0, 0, 38, 39, 40, 41, - 42, 43, 44, 45, 46, 0, 0, 47, 0, 0, 0, 48, 0, 0, 0, 49, - 0, 0, 0, 0, 0, 0, 0, 50, 0, 51, 0, 52, 53, 0, 54, 0, - 0, 0, 0, 0, 0, 55, 56, 57, 0, 0, 0, 0, 58, 0, 0, 59, - 60, 61, 62, 63, 0, 0, 64, 65, 0, 0, 0, 66, 0, 0, 0, 0, - 67, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 69, 0, 0, 0, 70, 0, 71, 0, 0, 72, 0, 0, 73, - 0, 0, 0, 0, 0, 0, 0, 0, 74, 75, 0, 0, 0, 0, 76, 77, - 0, 78, 79, 0, 0, 80, 81, 0, 82, 62, 0, 83, 84, 0, 0, 85, - 86, 87, 0, 88, 0, 89, 0, 90, 0, 0, 51, 91, 51, 0, 92, 0, - 93, 0, 0, 0, 81, 0, 0, 0, 94, 95, 0, 96, 97, 98, 99, 0, - 0, 0, 0, 0, 51, 0, 0, 0, 0,100,101, 0, 0, 0, 0, 0, - 0,102, 0, 0, 0, 0, 0, 0,103, 0, 0, 0, 0, 0, 0,104, - 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,106, 0, 0,107, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,108,109, 0, 0,110, 0, 0, - 0, 0, 0, 0,111, 0,112, 0,105, 0, 0, 0, 0, 0,113,114, - 0, 0, 0, 0, 0, 0, 0,115, 0, 0, 0,116, 0, 0, 0,117, - 0,118, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 39, 40, 0, 0, 0, 0, 0, 0, 41, 42, + 43, 44, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 2, 0, 0, 0, 0, 3, 0, 0, 0, 4, 5, 6, 7, 0, 8, + 9, 10, 0, 11, 12, 13, 14, 15, 16, 17, 16, 18, 16, 19, 16, 19, + 16, 19, 0, 19, 16, 20, 16, 19, 21, 19, 0, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 33, 0, 0, 0, 0, 0, 0, 34, 0, 0, 35, 0, 0, 36, 0, + 37, 0, 0, 0, 38, 39, 40, 41, 42, 43, 44, 45, 46, 0, 0, 47, + 0, 0, 0, 48, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 50, + 0, 51, 0, 52, 53, 0, 54, 0, 0, 0, 0, 0, 0, 55, 56, 57, + 0, 0, 0, 0, 58, 0, 0, 59, 60, 61, 62, 63, 0, 0, 64, 65, + 0, 0, 0, 66, 0, 0, 0, 0, 67, 0, 0, 0, 68, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 70, + 0, 71, 0, 0, 72, 0, 0, 73, 0, 0, 0, 0, 0, 0, 0, 0, + 74, 75, 0, 0, 0, 0, 76, 77, 0, 78, 79, 0, 0, 80, 81, 0, + 82, 62, 0, 83, 84, 0, 0, 85, 86, 87, 0, 88, 0, 89, 0, 90, + 0, 0, 51, 91, 51, 0, 92, 0, 93, 0, 0, 0, 81, 0, 0, 0, + 94, 95, 0, 96, 97, 98, 99, 0, 0, 0, 0, 0, 51, 0, 0, 0, + 0,100,101, 0, 0, 0, 0, 0, 0,102, 0, 0, 0, 0, 0, 0, + 103, 0, 0, 0, 0, 0, 0,104,105, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,106, 0, 0,107, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,108,109, 0, 0,110, 0, 0, 0, 0, 0, 0,111, 0,112, 0, + 105, 0, 0, 0, 0, 0,113,114, 0, 0, 0, 0, 0, 0, 0,115, + 0, 0, 0,116, 0, 0, 0,117, 0, 0, 0, 0, 0, 0, 0,118, + 0,119, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 0, 8, 0, 0, 0, 0, 9, 10, 11, 12, 0, 0, 0, 0, 13, 0, 0, 14, 15, 0, 16, 0, 17, 18, 0, 0, 19, 0, 20, 21, 0, 0, 0, 0, 0, 22, 23, 0, 24, 25, 0, 0, 26, 0, 0, 0, 27, 0, 0, @@ -3043,560 +3219,384 @@ static const uint8_t _hb_ucd_u8[17524]= 0, 43, 0, 44, 0, 0, 0, 45, 46, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 48, 49, 0, 0, 0, 0, 50, 0, 0, 0, 51, 0, 52, 0, 53, 0, 0, 0, 0, 54, 0, 0, 0, 0, 55, 0, 56, 0, 0, - 0, 0, 57, 58, 0, 0, 0, 59, 60, 0, 0, 0, 0, 0, 0, 61, - 52, 0, 62, 63, 0, 0, 64, 0, 0, 0, 65, 66, 0, 0, 0, 67, - 0, 68, 69, 70, 71, 72, 1, 73, 0, 74, 75, 76, 0, 0, 77, 78, - 0, 0, 0, 79, 0, 0, 1, 1, 0, 0, 80, 0, 0, 81, 0, 0, - 0, 0, 77, 82, 0, 83, 0, 0, 0, 0, 0, 78, 84, 0, 85, 0, - 52, 0, 1, 78, 0, 0, 86, 0, 0, 87, 0, 0, 0, 0, 0, 88, - 57, 0, 0, 0, 0, 0, 0, 89, 90, 0, 0, 84, 0, 0, 33, 0, - 0, 91, 0, 0, 0, 0, 92, 0, 0, 0, 0, 49, 0, 0, 93, 0, - 0, 0, 0, 94, 95, 0, 0, 96, 0, 0, 97, 0, 0, 0, 98, 0, - 0, 0, 99, 0, 0, 0,100, 0, 0, 0, 0,101,102, 93, 0, 0, - 103, 0, 0, 0, 84, 0, 0,104, 0, 0, 0,105,106, 0, 0,107, - 108, 0, 0, 0, 0, 0, 0,109, 0, 0,110, 0, 0, 0, 0,111, - 33, 0,112,113,114, 57, 0, 0,115, 35, 0, 0,116, 0, 0, 0, - 117, 0, 0, 0, 0, 0, 0,118, 0, 0,119, 0, 0, 0, 0,120, - 88, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 52,121, 0, 0, 0, - 0,122, 0, 0,123, 0, 0, 0, 0,121, 0, 0,124, 0, 0, 0, - 0, 0, 79, 0, 0, 0, 0,125, 0, 0, 0,126, 0, 0, 0,127, - 0,128, 0, 0, 0, 0,129,130,131, 0,132, 0,133, 0, 0, 0, - 134,135,136, 0, 77, 0, 0, 0, 0, 0, 35, 0, 0, 0,137, 0, - 0, 0,138, 0, 0, 0,139, 0, 0,140, 0, 0,141, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 7, 4, - 4, 8, 9, 10, 1, 11, 12, 13, 14, 15, 16, 17, 18, 1, 1, 1, - 19, 1, 0, 0, 20, 21, 22, 1, 23, 4, 21, 24, 25, 26, 27, 28, - 29, 30, 0, 0, 1, 1, 31, 0, 0, 0, 32, 33, 34, 35, 1, 36, - 37, 0, 0, 0, 0, 38, 1, 39, 14, 39, 40, 41, 42, 0, 0, 0, - 43, 36, 44, 45, 21, 45, 46, 0, 0, 0, 19, 1, 21, 0, 0, 47, - 0, 38, 48, 1, 1, 49, 49, 50, 0, 0, 51, 0, 0, 19, 52, 1, - 0, 0, 38, 14, 4, 1, 1, 1, 53, 21, 43, 52, 54, 21, 35, 1, - 0, 0, 0, 55, 0, 0, 0, 56, 57, 58, 0, 0, 0, 0, 0, 59, - 0, 60, 0, 0, 0, 0, 61, 62, 0, 0, 63, 0, 0, 0, 64, 0, - 0, 0, 65, 0, 0, 0, 66, 0, 0, 0, 67, 0, 0, 0, 68, 0, - 0, 69, 70, 0, 71, 72, 73, 74, 75, 76, 0, 0, 0, 77, 0, 0, - 0, 78, 79, 0, 0, 0, 0, 47, 0, 0, 0, 49, 0, 80, 0, 0, - 0, 62, 0, 0, 63, 0, 0, 81, 0, 0, 82, 0, 0, 0, 83, 0, - 0, 19, 84, 0, 62, 0, 0, 0, 0, 49, 1, 85, 1, 52, 15, 86, - 36, 10, 21, 87, 0, 55, 0, 0, 0, 0, 19, 10, 1, 0, 0, 0, - 0, 0, 88, 0, 0, 89, 0, 0, 88, 0, 0, 0, 0, 78, 0, 0, - 87, 9, 12, 4, 90, 8, 91, 47, 0, 58, 50, 0, 21, 1, 21, 92, - 93, 1, 1, 1, 1, 94, 95, 96, 97, 1, 98, 58, 81, 99,100, 4, - 58, 0, 0, 0, 0, 0, 0, 19, 50, 0, 0, 0, 0, 0, 0, 61, - 0, 0,101,102, 0, 0,103, 0, 0, 1, 1, 50, 0, 0, 0, 38, - 0, 63, 0, 0, 0, 0, 0, 62, 0, 0,104, 68, 61, 0, 0, 0, - 78, 0, 0, 0,105,106, 58, 38, 81, 0, 0, 0, 0, 0, 0,107, - 1, 14, 4, 12, 84, 0, 0, 0, 0, 38, 87, 0, 0, 0, 0,108, - 0, 0,109, 61, 0,110, 0, 0, 0, 1, 0, 0, 0, 0, 49, 50, - 0, 0, 19, 58, 0, 0, 0, 51, 0,111, 14, 52,112, 41, 0, 0, - 62, 0, 0, 61, 0, 0,113, 0, 87, 0, 0, 0, 61, 62, 0, 0, - 62, 0, 89, 0, 0,113, 0, 0, 0, 0,114, 0, 0, 0, 78, 55, - 0, 38, 1, 58, 1, 58, 0, 0, 0, 0, 0, 88, 63, 89, 0, 0, - 115, 0, 0, 0, 55, 0, 0, 0, 0,115, 0, 0, 0, 0, 61, 0, - 0, 0, 0, 79, 0, 61, 0, 0, 0, 0, 56, 0, 89, 80, 0, 0, - 79, 0, 0, 0, 8, 91, 0, 0, 1, 87, 0, 0,116, 0, 0, 0, - 0, 0, 0,117, 0,118,119,120,121, 0,104, 4,122, 49, 23, 0, - 0, 0, 38, 50, 38, 58, 0, 0, 1, 87, 1, 1, 1, 1, 39, 1, - 48,105, 87, 0, 0, 0, 0, 1, 0, 0, 0,123, 0, 0, 0,112, - 4,122, 0, 0, 0, 1,124, 0, 0, 0, 0, 0,230,230,230,230, - 230,232,220,220,220,220,232,216,220,220,220,220,220,202,202,220, - 220,220,220,202,202,220,220,220, 1, 1, 1, 1, 1,220,220,220, - 220,230,230,230,230,240,230,220,220,220,230,230,230,220,220, 0, - 230,230,230,220,220,220,220,230,232,220,220,230,233,234,234,233, - 234,234,233,230, 0, 0, 0,230, 0,220,230,230,230,230,220,230, - 230,230,222,220,230,230,220,220,230,222,228,230, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 0, 23, 0, 24, 25, 0, - 230,220, 0, 18, 30, 31, 32, 0, 0, 0, 0, 27, 28, 29, 30, 31, - 32, 33, 34,230,230,220,220,230,220,230,230,220, 35, 0, 0, 0, - 0, 0,230,230,230, 0, 0,230,230, 0,220,230,230,220, 0, 0, - 0, 36, 0, 0,230,220,230,230,220,220,230,220,220,230,220,230, - 220,230,230, 0, 0,220, 0, 0,230,230, 0,230, 0,230,230,230, - 230,230, 0, 0, 0,220,220,220,230,220,220,220,230,230, 0,220, - 27, 28, 29,230, 7, 0, 0, 0, 0, 9, 0, 0, 0,230,220,230, - 230, 0, 0, 0, 0, 0,230, 0, 0, 84, 91, 0, 0, 0, 0, 9, - 9, 0, 0, 0, 0, 0, 9, 0,103,103, 9, 0,107,107,107,107, - 118,118, 9, 0,122,122,122,122,220,220, 0, 0, 0,220, 0,220, - 0,216, 0, 0, 0,129,130, 0,132, 0, 0, 0, 0, 0,130,130, - 130,130, 0, 0,130, 0,230,230, 9, 0,230,230, 0, 0,220, 0, - 0, 0, 0, 7, 0, 9, 9, 0, 9, 9, 0, 0, 0,230, 0, 0, - 0,228, 0, 0, 0,222,230,220,220, 0, 0, 0,230, 0, 0,220, - 230,220, 0,220,230,230,230, 0, 0, 0, 9, 9, 0, 0, 7, 0, - 230, 0, 1, 1, 1, 0, 0, 0,230,234,214,220,202,230,230,230, - 230,230,232,228,228,220,218,230,233,220,230,220,230,230, 1, 1, - 1, 1, 1,230, 0, 1, 1,230,220,230, 1, 1, 0, 0,218,228, - 232,222,224,224, 0, 8, 8, 0, 0, 0, 0,220,230, 0,230,230, - 220, 0, 0,230, 0, 0, 26, 0, 0,220, 0,230,230, 1,220, 0, - 0,230,220, 0, 0, 0,220,220, 0, 0,230,220, 0, 9, 7, 0, - 0, 7, 9, 0, 0, 0, 9, 7, 6, 6, 0, 0, 0, 0, 1, 0, - 0,216,216, 1, 1, 1, 0, 0, 0,226,216,216,216,216,216, 0, - 220,220,220, 0,232,232,220,230,230,230, 7, 0, 16, 17, 17, 33, - 17, 49, 17, 17, 84, 97,135,145, 26, 17, 17, 17, 17, 17, 17, 17, + 0, 0, 57, 58, 0, 0, 0, 59, 60, 61, 62, 0, 0, 0, 0, 63, + 52, 0, 64, 65, 0, 0, 66, 0, 0, 0, 67, 68, 0, 0, 0, 69, + 0, 70, 71, 72, 73, 74, 1, 75, 0, 76, 77, 78, 0, 0, 79, 80, + 0, 0, 0, 81, 0, 0, 1, 1, 0, 0, 82, 0, 0, 83, 0, 0, + 0, 0, 79, 84, 0, 85, 0, 0, 0, 0, 0, 80, 86, 0, 87, 0, + 52, 0, 1, 80, 0, 0, 88, 0, 0, 89, 0, 0, 0, 0, 0, 90, + 57, 0, 0, 0, 0, 0, 0, 91, 92, 0, 0, 86, 0, 0, 33, 0, + 0, 93, 0, 0, 0, 0, 94, 0, 0, 0, 0, 49, 0, 0, 95, 0, + 0, 0, 0, 96, 97, 0, 0, 98, 0, 0, 99, 0, 0, 0,100, 0, + 0, 0,101, 0, 0, 0,102, 0, 0, 0, 0,103,104, 95, 0, 0, + 105, 0, 0, 0, 86, 0, 0,106, 0, 0, 0,107,108, 0, 0,109, + 110, 0, 0, 0, 0, 0, 0,111, 0, 0,112, 0, 0, 0, 0,113, + 33, 0,114,115,116, 57, 0, 0,117, 35, 0, 0,118, 0, 0, 0, + 119, 0, 0, 0, 0, 0, 0,120, 0, 0,121, 0, 0, 0, 0,122, + 90, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 52,123, 0, 0, 0, + 0,124, 0, 0,125, 0, 0, 0, 0,123, 0, 0,126, 0, 0, 0, + 0, 0, 81, 0, 0, 0, 0,127, 0, 0, 0,128, 0, 0, 0,129, + 0,130, 0, 0, 0, 0,131,132,133, 0,134, 0,135, 0, 0, 0, + 136,137,138, 0, 79, 0, 0, 0, 0, 0, 35, 0, 0, 0,139, 0, + 0, 0,140, 0, 0, 0,141, 0, 0, 0,142,143, 0,144, 0, 0, + 145, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3, 4, + 5, 6, 7, 4, 4, 8, 9, 10, 1, 11, 12, 13, 14, 15, 16, 17, + 18, 1, 1, 1, 19, 1, 0, 0, 20, 21, 22, 1, 23, 4, 21, 24, + 25, 26, 27, 28, 29, 30, 0, 0, 1, 1, 31, 0, 0, 0, 32, 33, + 34, 35, 1, 36, 37, 0, 0, 0, 0, 38, 1, 39, 14, 39, 40, 41, + 42, 0, 0, 0, 43, 36, 44, 45, 21, 45, 46, 0, 0, 0, 19, 1, + 21, 0, 0, 47, 0, 38, 48, 1, 1, 49, 49, 50, 0, 0, 51, 0, + 0, 19, 52, 1, 0, 0, 38, 14, 4, 1, 1, 1, 53, 21, 43, 52, + 54, 21, 35, 1, 0, 0, 0, 55, 0, 0, 0, 56, 57, 58, 0, 0, + 0, 0, 0, 59, 0, 60, 0, 0, 0, 0, 61, 62, 0, 0, 63, 0, + 0, 0, 64, 0, 0, 0, 65, 0, 0, 0, 66, 0, 0, 0, 67, 0, + 0, 0, 68, 0, 0, 69, 70, 0, 71, 72, 73, 74, 75, 76, 0, 0, + 0, 77, 0, 0, 0, 78, 79, 0, 0, 0, 0, 47, 0, 0, 0, 49, + 0, 80, 0, 0, 0, 62, 0, 0, 63, 0, 0, 81, 0, 0, 82, 0, + 0, 0, 83, 0, 0, 19, 84, 0, 62, 0, 0, 0, 0, 49, 1, 85, + 1, 52, 15, 86, 36, 10, 21, 1, 1, 1, 1, 41, 1, 21, 87, 0, + 0, 55, 0, 0, 0, 0, 19, 10, 1, 0, 0, 0, 0, 0, 88, 0, + 0, 89, 0, 0, 88, 0, 0, 0, 0, 78, 0, 0, 90, 9, 12, 4, + 91, 8, 92, 47, 0, 58, 50, 0, 21, 1, 21, 93, 94, 1, 1, 1, + 1, 95, 96, 97, 98, 1, 99, 58, 81,100,101, 4, 58, 0, 0, 0, + 0, 0, 0, 19, 50, 0, 0, 0, 0, 0, 0, 61, 0, 0,102,103, + 0, 0,104, 0, 0, 1, 1, 50, 0, 0, 0, 38, 0, 63, 0, 0, + 0, 0, 0, 62, 0, 0,105, 68, 61, 0, 0, 0, 78, 0, 0, 0, + 106,107, 58, 38, 81, 0, 0, 0, 0, 0, 0,108, 1, 14, 4, 12, + 84, 0, 0, 0, 0, 38, 90, 0, 0, 0, 0,109, 0, 0,110, 61, + 0,111, 0, 0, 0, 1, 0, 0, 0, 0, 49, 50, 0, 0, 19, 58, + 0, 0,112, 51, 0,112, 14, 52,113, 41, 0, 0, 62, 0, 0, 61, + 0, 0,114, 0, 90, 0, 0, 0, 61, 62, 0, 0, 62, 0, 89, 0, + 0,114, 0, 0, 0, 0,115, 0, 0, 0, 78, 55, 0, 38, 1, 58, + 1, 58, 0, 0, 0, 0, 0, 88, 63, 89, 0, 0,116, 0, 0, 0, + 55, 0, 0, 0, 0,116, 0, 0, 0, 0, 61, 0, 0, 0, 0, 79, + 0, 61, 0, 0, 0, 0, 56, 0, 89, 80, 0, 0, 79, 0, 0, 0, + 8, 92, 0, 0, 1, 90, 0, 0,117, 0, 0, 0, 0, 0, 0,118, + 0,119,120,121,122, 0,105, 4,123, 49, 23, 0, 0, 0, 38, 50, + 38, 58, 0, 0, 1, 90, 1, 1, 1, 1, 39, 1, 48,106, 90, 0, + 0, 0, 0, 1, 0, 0, 0,124, 0, 0, 0,113, 19, 59, 0, 38, + 0, 81, 0, 0, 4,123, 0, 0, 0, 1,125, 0, 0, 0, 0, 0, + 230,230,230,230,230,232,220,220,220,220,232,216,220,220,220,220, + 220,202,202,220,220,220,220,202,202,220,220,220, 1, 1, 1, 1, + 1,220,220,220,220,230,230,230,230,240,230,220,220,220,230,230, + 230,220,220, 0,230,230,230,220,220,220,220,230,232,220,220,230, + 233,234,234,233,234,234,233,230, 0, 0, 0,230, 0,220,230,230, + 230,230,220,230,230,230,222,220,230,230,220,220,230,222,228,230, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 0, 23, + 0, 24, 25, 0,230,220, 0, 18, 30, 31, 32, 0, 0, 0, 0, 27, + 28, 29, 30, 31, 32, 33, 34,230,230,220,220,230,220,230,230,220, + 35, 0, 0, 0, 0, 0,230,230,230, 0, 0,230,230, 0,220,230, + 230,220, 0, 0, 0, 36, 0, 0,230,220,230,230,220,220,230,220, + 220,230,220,230,220,230,230, 0, 0,220, 0, 0,230,230, 0,230, + 0,230,230,230,230,230, 0, 0, 0,220,220,220,230,220,220,220, + 230,230, 0,220, 27, 28, 29,230, 7, 0, 0, 0, 0, 9, 0, 0, + 0,230,220,230,230, 0, 0, 0, 0, 0,230, 0, 0, 84, 91, 0, + 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 9, 0,103,103, 9, 0, + 107,107,107,107,118,118, 9, 0,122,122,122,122,220,220, 0, 0, + 0,220, 0,220, 0,216, 0, 0, 0,129,130, 0,132, 0, 0, 0, + 0, 0,130,130,130,130, 0, 0,130, 0,230,230, 9, 0,230,230, + 0, 0,220, 0, 0, 0, 0, 7, 0, 9, 9, 0, 9, 9, 0, 0, + 0,230, 0, 0, 0,228, 0, 0, 0,222,230,220,220, 0, 0, 0, + 230, 0, 0,220,230,220, 0,220,230,230,230,234, 0, 0, 9, 9, + 0, 0, 7, 0,230,230,230, 0,230, 0, 1, 1, 1, 0, 0, 0, + 230,234,214,220,202,230,230,230,230,230,232,228,228,220,218,230, + 233,220,230,220,230,230, 1, 1, 1, 1, 1,230, 0, 1, 1,230, + 220,230, 1, 1, 0, 0,218,228,232,222,224,224, 0, 8, 8, 0, + 0, 0, 0,220,230, 0,230,230,220, 0, 0,230, 0, 0, 26, 0, + 0,220, 0,230,230, 1,220, 0, 0,230,220, 0, 0, 0,220,220, + 0, 0,230,220, 0, 9, 7, 0, 0, 7, 9, 0, 0, 0, 9, 7, + 6, 6, 0, 0, 0, 0, 1, 0, 0,216,216, 1, 1, 1, 0, 0, + 0,226,216,216,216,216,216, 0,220,220,220, 0,232,232,220,230, + 230,230, 7, 0, 16, 17, 17, 33, 17, 49, 17, 17, 84, 97,135,145, + 26, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,177, 0, 1, 2, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 4, 3, 3, 3, 3, 3, 5, 3, 3, 3, 3, 3, 6, 7, 8, 3, - 3, 3, 3, 3, 9, 10, 11, 12, 13, 3, 3, 3, 3, 3, 3, 3, - 3, 14, 3, 15, 3, 3, 3, 3, 3, 3, 16, 17, 18, 19, 20, 21, - 3, 3, 3, 22, 23, 24, 3, 3, 3, 3, 3, 3, 25, 3, 3, 3, - 3, 3, 3, 3, 3, 26, 3, 3, 27, 28, 0, 1, 0, 0, 0, 0, - 0, 1, 0, 2, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, - 0, 4, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 8, 9, 0, 0, 0, 0, 0, 0, 9, 0, 9, 0, 0, - 0, 0, 0, 0, 0, 10, 11, 12, 13, 0, 0, 14, 15, 16, 6, 0, - 17, 18, 19, 19, 19, 20, 21, 22, 23, 24, 19, 25, 0, 26, 27, 19, - 19, 28, 29, 30, 0, 31, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, - 0, 19, 28, 0, 32, 33, 9, 34, 35, 19, 0, 0, 36, 37, 38, 39, - 40, 19, 0, 41, 42, 43, 44, 31, 0, 1, 45, 42, 0, 0, 0, 0, - 0, 32, 14, 14, 0, 0, 0, 0, 14, 0, 0, 46, 47, 47, 47, 47, - 48, 49, 47, 47, 47, 47, 50, 51, 52, 53, 43, 21, 0, 0, 0, 0, - 0, 0, 0, 54, 6, 55, 0, 14, 19, 1, 0, 0, 0, 0, 56, 57, - 0, 0, 0, 0, 0, 19, 58, 31, 0, 0, 0, 0, 0, 0, 0, 59, - 14, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 3, 0, 0, 0, 60, - 61, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 3, - 0, 4, 5, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 1, 1, 0, - 0, 8, 9, 0, 8, 9, 0, 0, 0, 0, 8, 9, 10, 11, 12, 0, - 0, 0, 13, 0, 0, 0, 0, 14, 15, 16, 17, 0, 0, 0, 1, 0, - 0, 18, 19, 0, 0, 0, 20, 0, 0, 0, 1, 1, 1, 1, 0, 1, - 1, 1, 1, 1, 1, 1, 0, 8, 21, 9, 0, 0, 22, 0, 0, 0, - 0, 1, 0, 23, 24, 25, 0, 0, 26, 0, 0, 0, 8, 21, 27, 0, - 1, 0, 0, 1, 1, 1, 1, 0, 1, 28, 29, 30, 0, 31, 32, 20, - 1, 1, 0, 0, 0, 8, 21, 9, 1, 4, 5, 0, 0, 0, 33, 9, - 0, 1, 1, 1, 0, 8, 21, 21, 21, 21, 34, 1, 35, 21, 21, 21, - 9, 36, 0, 0, 37, 38, 1, 0, 39, 0, 0, 0, 1, 0, 1, 0, - 0, 0, 0, 8, 21, 9, 1, 0, 0, 0, 40, 0, 8, 21, 21, 21, - 21, 21, 21, 21, 21, 9, 0, 1, 1, 1, 1, 8, 21, 21, 21, 9, - 0, 0, 0, 41, 0, 42, 43, 0, 0, 0, 1, 44, 0, 0, 0, 45, - 8, 9, 1, 0, 0, 0, 8, 21, 21, 21, 9, 0, 1, 0, 1, 1, - 8, 21, 21, 9, 0, 4, 5, 8, 9, 1, 0, 0, 0, 1, 2, 3, - 4, 5, 5, 5, 5, 5, 6, 7, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 9, 16, 17, 18, 9, 19, 20, 21, 22, 23, 24, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 25, 26, 27, 5, 28, 29, 5, 30, 31, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 32, 0, 0, 1, - 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, - 18, 19, 20, 20, 21, 22, 23, 24, 25, 26, 27, 28, 1, 29, 30, 31, - 32, 32, 33, 32, 32, 32, 34, 32, 32, 35, 36, 37, 38, 39, 40, 41, - 42, 43, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 45, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 46, 46, - 46, 46, 47, 48, 49, 50, 51, 52, 53, 54, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 55, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 44, 57, 58, 59, 60, 61, 62, 63, 64, - 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, - 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 95, - 95, 96, 97, 98, 56, 56, 56, 56, 56, 56, 56, 56, 56, 99,100,100, - 100,100,101,100,100,100,100,100,100,100,100,100,100,100,100,100, - 100,102,103,103,104, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,105, - 56, 56, 56, 56, 56, 56,106,106,107,108, 56,109,110,111,112,112, - 112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, - 112,112,112,112,112,113,112,112,112,114,115,116, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,117,118,119, - 120, 56, 56, 56, 56, 56, 56, 56, 56, 56,121, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,122, 32,123,124,125,126, - 127,128,129,130,131,132,133,133,134, 56, 56, 56, 56,135,136,137, - 138, 56,139,140, 56,141,142,143, 56, 56,144,145,146, 56,147,148, - 149, 32, 32, 32,150,151,152, 32,153,154, 56, 56, 56, 56, 44, 44, - 44, 44, 44, 44,155, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44,156,157, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,158, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 44,159, 44, 44,160, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 44, 44,161, 56, 56, 56, 56, 56, 44, 44, - 44,162, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44,163, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,164,165, - 0, 1, 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, 0, 0, - 19, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 0, 19, 0, - 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, - 26, 26, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, - 9, 9, 0, 9, 9, 9, 2, 2, 9, 9, 9, 9, 0, 9, 2, 2, - 2, 2, 9, 0, 9, 0, 9, 9, 9, 2, 9, 2, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 2, 9, 9, 9, 9, 9, 9, 9, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 1, 1, 6, 2, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 2, 4, 4, 4, 2, 2, 4, 4, 4, 2, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 2, 2, - 2, 2, 2, 2, 2, 2, 14, 14, 14, 2, 2, 2, 2, 14, 14, 14, - 14, 14, 14, 2, 2, 2, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, - 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 0, 3, 3, 3, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 3, - 3, 3, 3, 3, 3, 3, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 2, 37, 37, 37, 37, 2, 2, 37, 37, 37, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, 2, 2, 2, 2, 2, 2, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 2, 2, 64, 64, 64, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 2, 2, 90, 90, - 90, 90, 90, 90, 90, 2, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 2, 2, 95, 2, 37, 37, 37, 2, 2, 2, 2, 2, 3, 3, - 3, 3, 3, 3, 3, 2, 3, 3, 2, 2, 2, 2, 2, 3, 3, 3, - 0, 3, 3, 3, 3, 3, 7, 7, 7, 7, 7, 7, 7, 7, 7, 1, - 1, 1, 1, 7, 7, 7, 7, 7, 7, 7, 0, 0, 7, 7, 5, 5, - 5, 5, 2, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 5, 5, 2, - 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, - 5, 5, 5, 5, 5, 5, 5, 2, 5, 2, 2, 2, 5, 5, 5, 5, - 2, 2, 5, 5, 5, 5, 5, 2, 2, 5, 5, 5, 5, 2, 2, 2, - 2, 2, 2, 2, 2, 5, 2, 2, 2, 2, 5, 5, 2, 5, 5, 5, - 5, 5, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 11, - 11, 11, 2, 11, 11, 11, 11, 11, 11, 2, 2, 2, 2, 11, 11, 2, - 2, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 2, - 11, 11, 11, 11, 11, 11, 11, 2, 11, 11, 2, 11, 11, 2, 11, 11, - 2, 2, 11, 2, 11, 11, 11, 2, 2, 11, 11, 11, 2, 2, 2, 11, - 2, 2, 2, 2, 2, 2, 2, 11, 11, 11, 11, 2, 11, 2, 2, 2, - 2, 2, 2, 2, 11, 11, 11, 11, 11, 11, 11, 11, 11, 2, 2, 10, - 10, 10, 2, 10, 10, 10, 10, 10, 10, 10, 10, 10, 2, 10, 10, 10, - 2, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 2, - 10, 10, 10, 10, 10, 10, 10, 2, 10, 10, 2, 10, 10, 10, 10, 10, - 2, 2, 10, 10, 10, 10, 10, 10, 2, 10, 10, 10, 2, 2, 10, 2, - 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 2, 2, 10, 10, 10, 10, - 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 2, 21, - 21, 21, 2, 21, 21, 21, 21, 21, 21, 21, 21, 2, 2, 21, 21, 2, - 2, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 2, - 21, 21, 21, 21, 21, 21, 21, 2, 21, 21, 2, 21, 21, 21, 21, 21, - 2, 2, 21, 21, 21, 21, 21, 2, 2, 21, 21, 21, 2, 2, 2, 2, - 2, 2, 2, 21, 21, 21, 2, 2, 2, 2, 21, 21, 2, 21, 21, 21, - 21, 21, 2, 2, 21, 21, 2, 2, 22, 22, 2, 22, 22, 22, 22, 22, - 22, 2, 2, 2, 22, 22, 22, 2, 22, 22, 22, 22, 2, 2, 2, 22, - 22, 2, 22, 2, 22, 22, 2, 2, 2, 22, 22, 2, 2, 2, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 2, 2, 2, 2, 22, 22, 22, 2, - 2, 2, 2, 2, 2, 22, 2, 2, 2, 2, 2, 2, 22, 22, 22, 22, - 22, 2, 2, 2, 2, 2, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 2, 23, 23, 23, 2, 23, 23, 23, 23, 23, 23, 23, 23, - 2, 2, 23, 23, 23, 23, 23, 2, 23, 23, 23, 23, 2, 2, 2, 2, - 2, 2, 2, 23, 23, 2, 23, 23, 23, 2, 2, 23, 2, 2, 23, 23, - 23, 23, 2, 2, 23, 23, 2, 2, 2, 2, 2, 2, 2, 23, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2, 16, 16, 16, 2, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2, 16, 16, 16, 16, 16, - 2, 2, 16, 16, 16, 16, 16, 2, 16, 16, 16, 16, 2, 2, 2, 2, - 2, 2, 2, 16, 16, 2, 16, 16, 16, 16, 2, 2, 16, 16, 2, 16, - 16, 16, 2, 2, 2, 2, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 2, 20, 20, 20, 2, 20, 20, 20, 20, 20, 20, 2, 2, - 2, 2, 20, 20, 20, 20, 20, 20, 20, 20, 2, 2, 20, 20, 2, 36, - 36, 36, 2, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 2, 2, 2, 36, 36, 36, 36, 36, 36, 36, 36, - 2, 36, 36, 36, 36, 36, 36, 36, 36, 36, 2, 36, 2, 2, 2, 2, - 36, 2, 2, 2, 2, 36, 36, 36, 36, 36, 36, 2, 36, 2, 2, 2, - 2, 2, 2, 2, 36, 36, 2, 2, 36, 36, 36, 2, 2, 2, 2, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 2, 2, 2, 2, 0, 24, 24, 24, 24, 2, 2, 2, 2, 2, 18, - 18, 2, 18, 2, 18, 18, 18, 18, 18, 2, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 2, 18, 2, 18, 18, 18, - 18, 18, 18, 18, 2, 2, 18, 18, 18, 18, 18, 2, 18, 2, 18, 18, - 18, 18, 18, 18, 18, 2, 18, 18, 2, 2, 18, 18, 18, 18, 25, 25, - 25, 25, 25, 25, 25, 25, 2, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 2, 2, 2, 25, 25, 25, 25, 25, 2, 25, 25, 25, 25, - 25, 25, 25, 0, 0, 0, 0, 25, 25, 2, 2, 2, 2, 2, 33, 33, - 33, 33, 33, 33, 33, 33, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 2, 8, 2, 2, 2, 2, 2, 8, 2, 2, 8, 8, - 8, 0, 8, 8, 8, 8, 12, 12, 12, 12, 12, 12, 12, 12, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 2, 30, 30, 30, 30, 2, 2, 30, 30, - 30, 30, 30, 30, 30, 2, 30, 30, 30, 2, 2, 30, 30, 30, 30, 30, - 30, 30, 30, 2, 2, 2, 30, 30, 2, 2, 2, 2, 2, 2, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 2, 2, 28, 28, - 28, 28, 28, 28, 28, 28, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 2, 2, 2, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 0, 0, 0, 35, 35, 35, 2, 2, 2, 2, 2, 2, 2, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 45, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 0, 0, 2, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 2, 2, 2, 2, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 2, 46, 46, 46, 2, 46, 46, 2, 2, 2, 2, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 2, 2, 31, 31, - 2, 2, 2, 2, 2, 2, 32, 32, 0, 0, 32, 0, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 2, 2, 2, 2, 2, 2, 32, 2, - 2, 2, 2, 2, 2, 2, 32, 32, 32, 2, 2, 2, 2, 2, 28, 28, - 28, 28, 28, 28, 2, 2, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 2, 48, 48, 48, 48, 2, 2, 2, 2, 48, 2, - 2, 2, 48, 48, 48, 48, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 2, 2, 52, 52, 52, 52, 52, 2, 2, 2, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 2, 2, 2, 2, 58, 58, - 2, 2, 2, 2, 2, 2, 58, 58, 58, 2, 2, 2, 58, 58, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 2, 2, 54, 54, 91, 91, - 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 2, 91, 91, - 91, 91, 91, 2, 2, 91, 91, 91, 2, 2, 2, 2, 2, 2, 91, 91, - 91, 91, 91, 91, 2, 2, 1, 1, 1, 1, 1, 1, 1, 2, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 2, 62, 62, 76, 76, - 76, 76, 76, 76, 76, 76, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 2, 2, 2, 2, 2, 2, 2, 2, 93, 93, 93, 93, 70, 70, - 70, 70, 70, 70, 70, 70, 2, 2, 2, 70, 70, 70, 70, 70, 70, 70, - 2, 2, 2, 70, 70, 70, 73, 73, 73, 73, 73, 73, 73, 73, 6, 6, - 6, 2, 2, 2, 2, 2, 8, 8, 8, 2, 2, 8, 8, 8, 1, 1, - 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, - 0, 2, 2, 2, 2, 2, 19, 19, 19, 19, 19, 19, 9, 9, 9, 9, - 9, 6, 19, 19, 19, 19, 19, 19, 19, 19, 19, 9, 9, 9, 9, 9, - 19, 19, 19, 19, 9, 9, 9, 9, 9, 19, 19, 19, 19, 19, 6, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 9, 9, 9, - 9, 9, 9, 9, 2, 2, 2, 9, 2, 9, 2, 9, 2, 9, 9, 9, - 9, 9, 9, 2, 9, 9, 9, 9, 9, 9, 2, 2, 9, 9, 9, 9, - 9, 9, 2, 9, 9, 9, 2, 2, 9, 9, 9, 2, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 2, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 2, 0, 0, 0, 19, 2, 2, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 2, 19, 19, - 19, 19, 19, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, - 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, - 19, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 19, 0, - 0, 0, 2, 2, 2, 2, 0, 0, 2, 2, 2, 2, 2, 2, 0, 0, - 0, 2, 2, 2, 2, 2, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, - 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 56, 56, - 56, 56, 56, 56, 56, 56, 55, 55, 55, 55, 2, 2, 2, 2, 2, 55, - 55, 55, 55, 55, 55, 55, 61, 61, 61, 61, 61, 61, 61, 61, 2, 2, - 2, 2, 2, 2, 2, 61, 61, 2, 2, 2, 2, 2, 2, 2, 0, 0, - 0, 0, 0, 0, 2, 2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 2, 2, 2, 2, 13, 13, - 13, 13, 13, 13, 2, 2, 0, 0, 0, 0, 0, 13, 0, 13, 0, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 1, 1, 1, 1, 12, 12, 13, 13, - 13, 13, 0, 0, 0, 0, 2, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 2, 2, 1, + 17, 17, 17,177, 0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 3, 3, 3, 3, 5, 3, + 3, 3, 3, 3, 6, 7, 8, 3, 3, 3, 3, 3, 9, 10, 11, 12, + 13, 3, 3, 3, 3, 3, 3, 3, 3, 14, 3, 15, 3, 3, 3, 3, + 3, 3, 16, 17, 18, 19, 20, 21, 3, 3, 3, 22, 23, 24, 3, 3, + 3, 3, 3, 3, 25, 3, 3, 3, 3, 3, 3, 3, 3, 26, 3, 3, + 27, 28, 0, 1, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 0, 0, 4, 0, 5, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 7, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 0, 0, 0, + 0, 0, 0, 9, 0, 9, 0, 0, 0, 0, 0, 0, 0, 10, 11, 12, + 13, 0, 0, 14, 15, 16, 6, 0, 17, 18, 19, 19, 19, 20, 21, 22, + 23, 24, 19, 25, 0, 26, 27, 19, 19, 28, 29, 30, 0, 31, 0, 0, + 0, 8, 0, 0, 0, 0, 0, 0, 0, 19, 28, 0, 32, 33, 9, 34, + 35, 19, 0, 0, 36, 37, 38, 39, 40, 19, 0, 41, 42, 43, 44, 31, + 0, 1, 45, 42, 0, 0, 0, 0, 0, 32, 14, 14, 0, 0, 0, 0, + 14, 0, 0, 46, 47, 47, 47, 47, 48, 49, 47, 47, 47, 47, 50, 51, + 52, 53, 43, 21, 0, 0, 0, 0, 0, 0, 0, 54, 6, 55, 0, 14, + 19, 1, 0, 0, 0, 0, 56, 57, 0, 0, 0, 0, 0, 19, 58, 31, + 0, 0, 0, 0, 0, 0, 0, 59, 14, 0, 0, 0, 0, 1, 0, 2, + 0, 0, 0, 3, 0, 0, 0, 60, 61, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 2, 3, 0, 4, 5, 0, 0, 6, 0, 0, + 0, 7, 0, 0, 0, 1, 1, 0, 0, 8, 9, 0, 8, 9, 0, 0, + 0, 0, 8, 9, 10, 11, 12, 0, 0, 0, 13, 0, 0, 0, 0, 14, + 15, 16, 17, 0, 0, 0, 1, 0, 0, 18, 19, 0, 0, 0, 20, 0, + 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 8, + 21, 9, 0, 0, 22, 0, 0, 0, 0, 1, 0, 23, 24, 25, 0, 0, + 26, 0, 0, 0, 8, 21, 27, 0, 1, 0, 0, 1, 1, 1, 1, 0, + 1, 28, 29, 30, 0, 31, 32, 20, 1, 1, 0, 0, 0, 8, 21, 9, + 1, 4, 5, 0, 0, 0, 33, 9, 0, 1, 1, 1, 0, 8, 21, 21, + 21, 21, 34, 1, 35, 21, 21, 21, 9, 36, 0, 0, 37, 38, 1, 0, + 39, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 8, 21, 9, 1, 0, + 0, 0, 40, 0, 8, 21, 21, 21, 21, 21, 21, 21, 21, 9, 0, 1, + 1, 1, 1, 8, 21, 21, 21, 9, 0, 0, 0, 41, 0, 42, 43, 0, + 0, 0, 1, 44, 0, 0, 0, 45, 8, 9, 1, 0, 0, 0, 8, 21, + 21, 21, 9, 0, 1, 0, 1, 1, 8, 21, 21, 9, 0, 4, 5, 8, + 9, 1, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 9, 10, 11, 11, 11, 11, 12, 13, + 13, 13, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 13, 13, 13, + 24, 25, 26, 26, 26, 27, 13, 13, 13, 28, 29, 30, 13, 31, 32, 33, + 34, 35, 36, 37, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 38, 7, 7, 39, 7, 40, 7, 7, + 7, 41, 13, 42, 7, 7, 43, 7, 7, 7, 44, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 45, 0, 0, 1, 2, 2, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 32, 32, 33, 34, 35, 36, 37, 37, + 37, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 2, 2, 53, 54, 55, 56, 57, 58, 59, 59, 59, 59, 60, 59, + 59, 59, 59, 59, 59, 59, 61, 61, 59, 59, 59, 59, 62, 59, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 59, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 78, 69, 69, 69, 69, 79, 79, 79, 79, 79, 79, 79, 79, 79, 80, + 81, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 94, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 69, 69, 96, 97, 98, 99, 99, 99, + 100,101,102,103,104,105,106,107,108,109, 95,110,111,112,113,114, + 115,116,117,117,118,119,120,121,122,123,124,125,126,127,128,129, + 130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145, + 95,146,147,148,149, 95,150,151,152,153,154,155,156,157,158,159, + 160,161, 95,162,163,164,165,165,165,165,165,165,165,166,167,165, + 168, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95,169,170,170,170,170,170,170,170,170,171,170, + 170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170, + 170,170,170,170,170,170,170,170,170,170,170,170,170,172,173,173, + 173,173,174, 95, 95, 95, 95, 95,175, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95,176,176,176,176,177,178,179,180, 95, 95, + 181, 95,182,183,184,185,186,186,186,186,186,186,186,186,186,186, + 186,186,186,186,186,186,186,186,186,186,186,186,187,187,187,188, + 189,190, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95,191,192,193,194,195,195,196, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,197,198, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 59,199, + 59, 59, 59,200,201,202, 59,203,204,205,206,207,208, 95,209,210, + 211, 59, 59,212, 59,213,214,214,214,214,214,215, 95, 95, 95, 95, + 95, 95, 95, 95,216, 95,217,218,219, 95, 95,220, 95, 95, 95,221, + 95,222, 95,223, 95,224,225,226,227, 95, 95, 95, 95, 95,228,229, + 230, 95,231,232, 95, 95,233,234, 59,235,236, 95, 59, 59, 59, 59, + 59, 59, 59,237, 59,238,239,240, 59, 59,241,242, 59,243, 95, 95, + 95, 95, 95, 95, 95, 95, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69,244, 69, 69,245, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69,246, 69, 69, 69, 69, 69, 69, 69, 69, 69,247, 69, 69, + 69, 69,248, 95, 95, 95, 69, 69, 69, 69,249, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 69, 69, 69, 69, 69, 69,250, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,251, 95, + 95, 95, 95, 95, 95, 95,252, 95,253,254, 0, 1, 2, 2, 0, 1, + 2, 2, 2, 3, 4, 5, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 0, 0, 0, 19, 0, 19, 0, 0, 0, 0, 0, + 26, 26, 1, 1, 1, 1, 9, 9, 9, 9, 0, 9, 9, 9, 2, 2, + 9, 9, 9, 9, 0, 9, 2, 2, 2, 2, 9, 0, 9, 0, 9, 9, + 9, 2, 9, 2, 9, 9, 9, 9, 2, 9, 9, 9, 55, 55, 55, 55, + 55, 55, 6, 6, 6, 6, 6, 1, 1, 6, 2, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 2, 2, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 2, 2, 2, 2, 14, 14, 2, 2, 2, 3, 3, 3, 3, 3, 0, + 3, 3, 0, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 1, 1, 1, + 3, 3, 1, 3, 3, 3, 37, 37, 37, 37, 37, 37, 2, 37, 37, 37, + 37, 2, 2, 37, 37, 37, 38, 38, 38, 38, 38, 38, 2, 2, 64, 64, + 64, 64, 64, 64, 64, 2, 2, 64, 64, 64, 90, 90, 90, 90, 90, 90, + 2, 2, 90, 90, 90, 2, 95, 95, 95, 95, 2, 2, 95, 2, 3, 3, + 2, 2, 2, 2, 2, 3, 3, 3, 0, 3, 7, 7, 7, 7, 7, 1, + 1, 1, 1, 7, 7, 7, 0, 0, 7, 7, 5, 5, 5, 5, 2, 5, + 5, 5, 5, 2, 2, 5, 5, 2, 5, 5, 5, 2, 5, 2, 2, 2, + 5, 5, 5, 5, 2, 2, 5, 5, 5, 2, 2, 2, 2, 5, 5, 5, + 2, 5, 2, 11, 11, 11, 11, 11, 11, 2, 2, 2, 2, 11, 11, 2, + 2, 11, 11, 11, 11, 11, 11, 2, 11, 11, 2, 11, 11, 2, 11, 11, + 2, 2, 2, 11, 2, 2, 11, 2, 11, 2, 2, 2, 11, 11, 2, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 2, 10, 10, 2, 10, 10, 10, 10, + 2, 2, 10, 2, 2, 2, 2, 2, 10, 10, 2, 21, 21, 21, 21, 21, + 21, 21, 21, 2, 2, 21, 21, 2, 21, 21, 21, 21, 2, 2, 21, 21, + 2, 21, 2, 2, 21, 21, 2, 2, 22, 22, 2, 22, 22, 22, 22, 22, + 22, 2, 22, 2, 22, 22, 22, 22, 2, 2, 2, 22, 22, 2, 2, 2, + 2, 22, 22, 2, 2, 2, 22, 22, 22, 22, 23, 23, 23, 23, 23, 2, + 23, 23, 23, 23, 2, 2, 2, 23, 23, 2, 23, 23, 23, 2, 2, 2, + 23, 23, 2, 2, 2, 23, 16, 16, 16, 16, 16, 2, 16, 16, 2, 16, + 16, 16, 16, 16, 2, 2, 2, 16, 16, 2, 16, 16, 16, 2, 2, 2, + 16, 16, 20, 20, 20, 20, 20, 2, 20, 20, 2, 2, 20, 20, 2, 36, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 2, 2, 2, 36, 36, 36, 36, + 2, 36, 2, 36, 2, 2, 2, 2, 36, 2, 2, 2, 2, 36, 36, 2, + 36, 2, 36, 2, 2, 2, 2, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 2, 2, 2, 2, 0, 2, 18, 18, 2, 18, 2, 18, 18, 18, 18, + 18, 2, 18, 18, 18, 18, 2, 18, 2, 18, 18, 18, 2, 2, 18, 2, + 18, 2, 25, 25, 25, 25, 2, 25, 25, 25, 25, 2, 2, 2, 25, 2, + 25, 25, 25, 0, 0, 0, 0, 25, 25, 2, 33, 33, 33, 33, 8, 8, + 8, 8, 8, 8, 2, 8, 2, 8, 2, 2, 8, 8, 8, 0, 12, 12, + 12, 12, 30, 30, 30, 30, 30, 2, 30, 30, 30, 30, 2, 2, 30, 30, + 30, 2, 2, 30, 30, 30, 30, 2, 2, 2, 29, 29, 29, 29, 29, 29, + 2, 2, 28, 28, 28, 28, 34, 34, 34, 34, 34, 2, 2, 2, 35, 35, + 35, 35, 35, 35, 35, 0, 0, 0, 35, 35, 35, 2, 2, 2, 45, 45, + 45, 45, 45, 45, 2, 2, 2, 2, 2, 45, 44, 44, 44, 44, 44, 0, + 0, 2, 43, 43, 43, 43, 46, 46, 46, 46, 46, 2, 46, 46, 31, 31, + 31, 31, 31, 31, 2, 2, 32, 32, 0, 0, 32, 0, 32, 32, 32, 32, + 32, 32, 32, 32, 2, 2, 32, 2, 2, 2, 32, 32, 32, 2, 28, 28, + 2, 2, 48, 48, 48, 48, 48, 48, 48, 2, 48, 2, 2, 2, 52, 52, + 52, 52, 52, 52, 2, 2, 52, 2, 2, 2, 58, 58, 58, 58, 58, 58, + 2, 2, 58, 58, 58, 2, 2, 2, 58, 58, 54, 54, 54, 54, 2, 2, + 54, 54, 91, 91, 91, 91, 91, 91, 91, 2, 91, 2, 2, 91, 91, 91, + 2, 2, 1, 1, 2, 2, 62, 62, 62, 62, 62, 2, 62, 62, 76, 76, + 76, 76, 93, 93, 93, 93, 70, 70, 70, 70, 2, 2, 2, 70, 70, 70, + 2, 2, 2, 70, 70, 70, 73, 73, 73, 73, 6, 6, 6, 2, 8, 8, + 8, 2, 2, 8, 8, 8, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, + 0, 0, 0, 1, 0, 0, 1, 1, 0, 2, 19, 19, 9, 9, 9, 9, + 9, 6, 19, 9, 9, 9, 9, 9, 19, 19, 9, 9, 9, 19, 6, 19, + 19, 19, 19, 19, 19, 9, 9, 9, 2, 2, 2, 9, 2, 9, 2, 9, + 9, 9, 1, 1, 0, 0, 0, 2, 0, 0, 0, 19, 2, 2, 0, 0, + 0, 19, 0, 0, 0, 2, 19, 2, 2, 2, 0, 0, 2, 2, 1, 2, + 2, 2, 0, 0, 9, 0, 0, 0, 19, 19, 27, 27, 27, 27, 2, 2, + 0, 0, 56, 56, 56, 56, 2, 55, 55, 55, 61, 61, 61, 61, 2, 2, + 2, 61, 61, 2, 2, 2, 13, 13, 13, 13, 13, 13, 2, 13, 13, 13, + 2, 2, 0, 13, 0, 13, 0, 13, 13, 13, 13, 13, 1, 1, 1, 1, + 12, 12, 2, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 2, 2, 1, 1, 0, 0, 15, 15, 15, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 17, 17, 17, 2, 2, - 2, 2, 2, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 2, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 2, 2, 2, - 2, 2, 2, 2, 2, 0, 12, 12, 12, 12, 12, 12, 12, 0, 17, 17, - 17, 17, 17, 17, 17, 0, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 2, 2, 2, 39, 39, 39, 39, 39, 39, 39, 2, 86, 86, - 86, 86, 86, 86, 86, 86, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, - 77, 77, 2, 2, 2, 2, 79, 79, 79, 79, 79, 79, 79, 79, 0, 0, - 19, 19, 19, 19, 19, 19, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 2, 2, 19, 19, 2, 19, 2, 19, 19, 19, 2, 2, - 19, 19, 19, 19, 19, 19, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 2, 2, 2, 65, 65, 65, 65, 65, 65, 65, 65, 75, 75, - 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 2, 2, 2, 2, - 2, 2, 2, 2, 75, 75, 75, 75, 2, 2, 2, 2, 2, 2, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 0, 69, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 74, 12, 12, 12, 12, 12, 2, 2, 2, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 2, 0, 84, 84, - 2, 2, 2, 2, 84, 84, 33, 33, 33, 33, 33, 33, 33, 2, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 2, 68, 68, - 68, 68, 68, 68, 2, 2, 68, 68, 2, 2, 68, 68, 68, 68, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 2, 2, 2, 2, 2, 2, 2, - 2, 92, 92, 92, 92, 92, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 2, 2, 30, 30, 30, 30, 30, 30, 2, 19, 19, - 19, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 9, 19, 19, 19, 19, - 0, 0, 2, 2, 2, 2, 87, 87, 87, 87, 87, 87, 2, 2, 87, 87, - 2, 2, 2, 2, 2, 2, 12, 12, 12, 12, 2, 2, 2, 2, 2, 2, - 2, 12, 12, 12, 12, 12, 13, 13, 2, 2, 2, 2, 2, 2, 19, 19, - 19, 19, 19, 19, 19, 2, 2, 2, 2, 4, 4, 4, 4, 4, 2, 2, - 2, 2, 2, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 2, 14, 14, - 14, 14, 14, 2, 14, 2, 14, 14, 2, 14, 14, 2, 14, 14, 3, 3, - 3, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 0, 0, 2, 2, 3, 3, 3, 3, 3, 3, 2, 2, - 2, 2, 2, 2, 2, 3, 1, 1, 1, 1, 1, 1, 6, 6, 0, 0, - 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 3, 3, - 3, 3, 3, 2, 3, 3, 3, 3, 3, 3, 3, 2, 2, 0, 2, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, - 17, 17, 17, 17, 0, 0, 2, 2, 12, 12, 12, 12, 12, 12, 2, 2, - 12, 12, 12, 2, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 2, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 2, 49, 49, 49, 2, 49, 49, 2, 49, 49, 49, - 49, 49, 49, 49, 2, 2, 49, 49, 49, 2, 2, 2, 2, 2, 0, 0, - 0, 2, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, - 0, 0, 0, 2, 2, 2, 9, 2, 2, 2, 2, 2, 2, 2, 0, 0, - 0, 0, 0, 1, 2, 2, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 2, 2, 2, 67, 67, 67, 67, 67, 67, 67, 67, 67, 2, - 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 42, 42, 42, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, - 41, 2, 2, 2, 2, 2,118,118,118,118,118,118,118,118,118,118, - 118, 2, 2, 2, 2, 2, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 2, 53, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 2, 2, 2, 2, 59, 59, 59, 59, 59, 59, 2, 2, 40, 40, - 40, 40, 40, 40, 40, 40, 51, 51, 51, 51, 51, 51, 51, 51, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 2, 2, 50, 50, - 2, 2, 2, 2, 2, 2,135,135,135,135,135,135,135,135,135,135, - 135,135, 2, 2, 2, 2,106,106,106,106,106,106,106,106,104,104, - 104,104,104,104,104,104,104,104,104,104, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2,104,161,161,161,161,161,161,161,161,161,161, - 161, 2,161,161,161,161,161,161,161, 2,161,161, 2,161,161,161, - 2,161,161,161,161,161,161,161, 2,161,161, 2, 2, 2,170,170, - 170,170,170,170,170,170,170,170,170,170, 2, 2, 2, 2,110,110, - 110,110,110,110,110,110,110,110,110,110,110,110,110, 2,110,110, - 110,110,110,110, 2, 2, 19, 19, 19, 19, 19, 19, 2, 19, 19, 2, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 2, 2, 2, 2, 2, 47, 47, - 47, 47, 47, 47, 2, 2, 47, 2, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 2, 47, 47, 2, - 2, 2, 47, 2, 2, 47, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, - 81, 81, 81, 81, 2, 81,120,120,120,120,120,120,120,120,116,116, - 116,116,116,116,116,116,116,116,116,116,116,116,116, 2, 2, 2, - 2, 2, 2, 2, 2,116,128,128,128,128,128,128,128,128,128,128, - 128, 2,128,128, 2, 2, 2, 2, 2,128,128,128,128,128, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 2, 2, 2, 66, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, 2, 2, 2, 2, 2, 72, 98, 98, - 98, 98, 98, 98, 98, 98, 97, 97, 97, 97, 97, 97, 97, 97, 2, 2, - 2, 2, 97, 97, 97, 97, 2, 2, 97, 97, 97, 97, 97, 97, 57, 57, - 57, 57, 2, 57, 57, 2, 2, 2, 2, 2, 57, 57, 57, 57, 57, 57, - 57, 57, 2, 57, 57, 57, 2, 57, 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 2, 2, 57, 57, - 57, 2, 2, 2, 2, 57, 57, 2, 2, 2, 2, 2, 2, 2, 88, 88, - 88, 88, 88, 88, 88, 88,117,117,117,117,117,117,117,117,112,112, - 112,112,112,112,112,112,112,112,112,112,112,112,112, 2, 2, 2, - 2,112,112,112,112,112, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 2, 2, 2, 78, 78, 78, 78, 78, 78, 78, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 2, 2, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 2, 2, 2, 2, 2,122,122, - 122,122,122,122,122,122,122,122, 2, 2, 2, 2, 2, 2, 2,122, - 122,122,122, 2, 2, 2, 2,122,122,122,122,122,122,122, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 2, 2, 2, 2, 2, 2, 2,130,130, - 130,130,130,130,130,130,130,130,130, 2, 2, 2, 2, 2, 2, 2, - 130,130,130,130,130,130,144,144,144,144,144,144,144,144,144,144, - 2, 2, 2, 2, 2, 2,165,165,165,165,165,165,165,165,165,165, - 165,165,165,165, 2, 2, 2,165,165,165,165,165,165,165, 2, 2, - 2, 2, 2, 2,165,165,156,156,156,156,156,156,156,156,156,156, - 2,156,156,156, 2, 2,156,156, 2, 2, 2, 2, 2, 2, 2, 2, - 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3,147,147, - 147,147,147,147,147,147,148,148,148,148,148,148,148,148,148,148, - 2, 2, 2, 2, 2, 2,158,158,158,158,158,158,158,158,158,158, - 2, 2, 2, 2, 2, 2,153,153,153,153,153,153,153,153,153,153, - 153,153, 2, 2, 2, 2,149,149,149,149,149,149,149,149,149,149, - 149,149,149,149,149, 2, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 2, 2, 2, 2, 94, 94, 94, 94, 94, 94, 2, 2, - 2, 2, 2, 2, 2, 94, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, - 85, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 85, 2, 2,101,101, - 101,101,101,101,101,101,101, 2, 2, 2, 2, 2, 2, 2,101,101, - 2, 2, 2, 2, 2, 2, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 2, 96, 96,111,111,111,111,111,111,111,111,111,111, - 111,111,111,111,111, 2,100,100,100,100,100,100,100,100, 2, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 2, 2, 2,108,108, - 108,108,108,108,108,108,108,108, 2,108,108,108,108,108,108,108, - 2, 2, 2, 2, 2, 2,129,129,129,129,129,129,129, 2,129, 2, - 129,129,129,129, 2,129,129,129,129,129,129,129,129,129,129,129, - 129,129,129,129, 2,129,129,129, 2, 2, 2, 2, 2, 2,109,109, - 109,109,109,109,109,109,109,109,109, 2, 2, 2, 2, 2,109,109, - 2, 2, 2, 2, 2, 2,107,107,107,107, 2,107,107,107,107,107, - 107,107,107, 2, 2,107,107, 2, 2,107,107,107,107,107,107,107, - 107,107,107,107,107,107,107, 2,107,107,107,107,107,107,107, 2, - 107,107, 2,107,107,107,107,107, 2, 1,107,107,107,107,107, 2, - 2,107,107,107, 2, 2,107, 2, 2, 2, 2, 2, 2,107, 2, 2, - 2, 2, 2,107,107,107,107,107,107,107, 2, 2,107,107,107,107, - 107,107,107, 2, 2, 2,171,171,171,171,171,171,171,171,171,171, - 2,171, 2, 2,171, 2,171,171,171,171,171,171, 2,171,171, 2, - 171, 2, 2,171, 2,171,171,171,171, 2,171,171,171,171,171, 2, - 2, 2, 2, 2, 2, 2, 2,171,171, 2, 2, 2, 2, 2,137,137, - 137,137,137,137,137,137,137,137,137,137, 2,137,137,137,137,137, - 2, 2, 2, 2, 2, 2,124,124,124,124,124,124,124,124,124,124, - 2, 2, 2, 2, 2, 2,123,123,123,123,123,123,123,123,123,123, - 123,123,123,123, 2, 2,114,114,114,114,114,114,114,114,114,114, - 114,114,114, 2, 2, 2,114,114, 2, 2, 2, 2, 2, 2, 32, 32, - 32, 32, 32, 2, 2, 2,102,102,102,102,102,102,102,102,102,102, - 2, 2, 2, 2, 2, 2, 33, 33, 33, 33, 2, 2, 2, 2,126,126, - 126,126,126,126,126,126,126,126,126, 2, 2,126,126,126,126,126, - 126,126, 2, 2, 2, 2,126,126,126,126,126,126,126, 2,142,142, - 142,142,142,142,142,142,142,142,142,142, 2, 2, 2, 2,125,125, - 125,125,125,125,125,125,125,125,125, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2,125,154,154,154,154,154,154,154, 2, 2,154, - 2, 2,154,154,154,154,154,154,154,154, 2,154,154, 2,154,154, - 154,154,154,154,154,154,154,154,154,154,154,154, 2,154,154, 2, - 2,154,154,154,154,154,154,154, 2, 2, 2, 2, 2, 2,150,150, - 150,150,150,150,150,150, 2, 2,150,150,150,150,150,150,150,150, - 150,150,150, 2, 2, 2,141,141,141,141,141,141,141,141,140,140, - 140,140,140,140,140,140,140,140,140, 2, 2, 2, 2, 2,121,121, - 121,121,121,121,121,121,121, 2, 2, 2, 2, 2, 2, 2, 7, 7, - 2, 2, 2, 2, 2, 2,169,169,169,169,169,169,169,169,169,169, - 2, 2, 2, 2, 2, 2,133,133,133,133,133,133,133,133,133, 2, - 133,133,133,133,133,133,133,133,133,133,133,133,133, 2,133,133, - 133,133,133,133, 2, 2,133,133,133,133,133, 2, 2, 2,134,134, - 134,134,134,134,134,134, 2, 2,134,134,134,134,134,134, 2,134, - 134,134,134,134,134,134,134,134,134,134,134,134,134, 2,138,138, - 138,138,138,138,138, 2,138,138, 2,138,138,138,138,138,138,138, - 138,138,138,138,138,138, 2, 2,138, 2,138,138, 2,138,138,138, - 2, 2, 2, 2, 2, 2,143,143,143,143,143,143, 2,143,143, 2, - 143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143, - 143,143,143,143,143, 2,143,143, 2,143,143,143,143,143,143, 2, - 2, 2, 2, 2, 2, 2,143,143, 2, 2, 2, 2, 2, 2,145,145, - 145,145,145,145,145,145,145, 2, 2, 2, 2, 2, 2, 2,163,163, - 163,163,163,163,163,163,163, 2,163,163,163,163,163,163,163,163, - 163, 2, 2, 2,163,163,163,163,163, 2, 2, 2, 2, 2, 86, 2, - 2, 2, 2, 2, 2, 2, 22, 22, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 22, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, - 2, 2, 2, 2, 2, 2, 63, 63, 63, 63, 63, 63, 63, 2, 63, 63, - 63, 63, 63, 2, 2, 2, 63, 63, 63, 63, 2, 2, 2, 2,157,157, - 157,157,157,157,157,157,157,157,157, 2, 2, 2, 2, 2, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 2, 2, 80, 80, - 80, 2, 2, 2, 2, 2,127,127,127,127,127,127,127,127,127,127, - 127,127,127,127,127, 2,166,166,166,166,166,166,166,166,166,166, - 2, 2, 2, 2, 2, 2, 79, 2, 2, 2, 2, 2, 2, 2,115,115, - 115,115,115,115,115,115,115,115,115,115,115,115,115, 2,115,115, - 2, 2, 2, 2,115,115,159,159,159,159,159,159,159,159,159,159, - 159,159,159,159,159, 2,159,159, 2, 2, 2, 2, 2, 2,103,103, - 103,103,103,103,103,103,103,103,103,103,103,103, 2, 2,119,119, - 119,119,119,119,119,119,119,119,119,119,119,119, 2, 2,119,119, - 2,119,119,119,119,119, 2, 2, 2, 2, 2,119,119,119,167,167, - 167,167,167,167,167,167,167,167, 2, 2, 2, 2, 2, 2,146,146, - 146,146,146,146,146,146,146,146,146, 2, 2, 2, 2, 2, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, 99, 2, 2, 2, 2, 99, 2, 2, - 2, 2, 2, 2, 2, 99,136,139, 13, 13,155, 2, 2, 2,136,136, - 136,136,136,136,136,136,155,155,155,155,155,155,155,155,155,155, - 155,155,155,155, 2, 2, 2, 2, 2, 2, 2, 2, 2,155,136, 2, - 2, 2, 2, 2, 2, 2, 17, 17, 17, 17, 2, 17, 17, 17, 17, 17, - 17, 17, 2, 17, 17, 2, 17, 15, 15, 15, 15, 15, 15, 15, 17, 17, - 17, 2, 2, 2, 2, 2, 2, 2, 15, 2, 2, 2, 2, 2, 15, 15, - 15, 2, 2, 17, 2, 2, 2, 2, 2, 2, 17, 17, 17, 17,139,139, - 139,139,139,139,139,139,139,139,139,139, 2, 2, 2, 2,105,105, - 105,105,105,105,105,105,105,105,105, 2, 2, 2, 2, 2,105,105, - 105,105,105, 2, 2, 2,105, 2, 2, 2, 2, 2, 2, 2,105,105, - 2, 2,105,105,105,105, 1, 1, 1, 1, 1, 1, 2, 2, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, - 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 2, 2, - 0, 2, 2, 0, 0, 2, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, - 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, - 0, 2, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, - 0, 0, 0, 2, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 2, - 0, 0, 0, 0, 0, 0,131,131,131,131,131,131,131,131,131,131, - 131,131, 2, 2, 2, 2, 2, 2, 2,131,131,131,131,131, 2,131, - 131,131,131,131,131,131, 2, 2, 2, 2, 2, 19, 19, 19, 56, 56, - 56, 56, 56, 56, 56, 2, 56, 2, 2, 56, 56, 56, 56, 56, 56, 56, - 2, 56, 56, 2, 56, 56, 56, 56, 56, 2, 2, 2, 2, 2, 6, 6, - 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6,151,151, - 151,151,151,151,151,151,151,151,151,151,151, 2, 2, 2,151,151, - 151,151,151,151, 2, 2,151,151, 2, 2, 2, 2,151,151,160,160, - 160,160,160,160,160,160,160,160,160,160,160,160,160, 2,152,152, - 152,152,152,152,152,152,152,152, 2, 2, 2, 2, 2,152,164,164, - 164,164,164,164,164,164,164,164, 2, 2, 2, 2, 2, 2,168,168, - 168,168,168,168,168,168,168,168,168, 2, 2, 2, 2,168, 30, 30, - 30, 30, 2, 30, 30, 2,113,113,113,113,113,113,113,113,113,113, - 113,113,113, 2, 2,113,113,113,113,113,113,113,113, 2,132,132, - 132,132,132,132,132,132,132,132,132,132, 2, 2, 2, 2,132,132, - 2, 2, 2, 2,132,132, 3, 3, 3, 3, 2, 3, 3, 3, 2, 3, - 3, 2, 3, 2, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 2, 3, 3, 3, 3, 2, 3, 2, 3, 2, 2, 2, 2, 2, 2, - 3, 2, 2, 2, 2, 3, 2, 3, 2, 3, 2, 3, 3, 3, 2, 3, - 2, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 2, 3, 2, 3, 3, - 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 3, - 3, 3, 2, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 0, 0, 15, 0, 0, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, - 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 2, 2, 0, 13, 2, - 2, 2, 2, 2, 2, 2, 13, 13, 13, 2, 2, 2, 2, 2, 2, 0, - 2, 2, 2, 2, 2, 2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 9, 9, 9, 10, 9, 11, 12, 13, 9, 9, 9, 14, 9, 9, 15, 9, + 17, 0, 2, 26, 26, 26, 26, 26, 26, 26, 2, 12, 12, 12, 12, 12, + 12, 2, 12, 12, 12, 0, 39, 39, 39, 39, 39, 2, 2, 2, 39, 39, + 39, 2, 86, 86, 86, 86, 77, 77, 77, 77, 79, 79, 79, 79, 2, 19, + 19, 19, 60, 60, 60, 60, 60, 2, 2, 2, 65, 65, 65, 65, 75, 75, + 75, 75, 75, 75, 2, 2, 2, 2, 75, 75, 69, 69, 69, 69, 69, 69, + 0, 69, 74, 74, 74, 74, 2, 2, 2, 74, 12, 2, 2, 2, 84, 84, + 84, 84, 84, 84, 2, 0, 84, 84, 2, 2, 2, 2, 84, 84, 33, 33, + 33, 2, 68, 68, 68, 68, 68, 68, 68, 2, 68, 68, 2, 2, 92, 92, + 92, 92, 92, 92, 92, 2, 2, 2, 2, 92, 87, 87, 87, 87, 87, 87, + 87, 2, 19, 9, 19, 19, 19, 19, 0, 0, 87, 87, 2, 2, 2, 2, + 2, 12, 19, 19, 19, 2, 2, 2, 2, 4, 14, 2, 14, 2, 14, 14, + 2, 14, 14, 2, 14, 14, 3, 3, 0, 0, 1, 1, 6, 6, 3, 2, + 3, 3, 3, 2, 2, 0, 2, 0, 0, 0, 0, 0, 17, 17, 17, 17, + 0, 0, 2, 2, 12, 12, 49, 49, 49, 49, 2, 49, 49, 49, 49, 49, + 49, 2, 49, 49, 2, 49, 49, 49, 2, 2, 0, 2, 2, 2, 9, 2, + 2, 2, 0, 1, 2, 2, 71, 71, 71, 71, 71, 2, 2, 2, 67, 67, + 67, 67, 67, 2, 2, 2, 42, 42, 42, 42, 2, 42, 42, 42, 41, 41, + 41, 41, 41, 41, 41, 2,118,118,118,118,118,118,118, 2, 53, 53, + 53, 53, 53, 53, 2, 53, 59, 59, 59, 59, 59, 59, 2, 2, 40, 40, + 40, 40, 51, 51, 51, 51, 50, 50, 50, 50, 50, 50, 2, 2,135,135, + 135,135,106,106,106,106,104,104,104,104, 2, 2, 2,104,161,161, + 161,161,161,161,161, 2,161,161, 2,161,161, 2, 2, 2,170,170, + 170,170,110,110,110,110,110,110,110, 2,110,110, 2, 2, 19, 19, + 2, 19, 19, 2, 19, 19, 47, 47, 47, 47, 47, 47, 2, 2, 47, 2, + 47, 47, 47, 47, 2, 47, 47, 2, 2, 2, 47, 2, 2, 47, 81, 81, + 81, 81, 81, 81, 2, 81,120,120,120,120,116,116,116,116,116,116, + 116, 2, 2, 2, 2,116,128,128,128,128,128,128,128, 2,128,128, + 2, 2, 2, 2, 2,128, 66, 66, 66, 66, 2, 2, 2, 66, 72, 72, + 72, 72, 72, 72, 2, 2, 2, 2, 2, 72,173,173,173,173,173,173, + 2, 2, 98, 98, 98, 98, 97, 97, 97, 97, 2, 2, 97, 97, 57, 57, + 57, 57, 2, 57, 57, 2, 2, 57, 57, 57, 57, 57, 2, 2, 57, 57, + 57, 2, 2, 2, 2, 57, 57, 2, 2, 2, 88, 88, 88, 88,117,117, + 117,117,112,112,112,112,112,112,112, 2, 2, 2, 2,112, 78, 78, + 78, 78, 78, 78, 2, 2, 2, 78, 78, 78, 83, 83, 83, 83, 83, 83, + 2, 2, 82, 82, 82, 82, 82, 82, 82, 2,122,122,122,122,122,122, + 2, 2, 2,122,122,122,122, 2, 2, 2, 89, 89, 89, 89, 89, 2, + 2, 2,130,130,130,130,130,130,130, 2, 2, 2,130,130,144,144, + 144,144,144,144, 2, 2,165,165,165,165,165,165, 2, 2, 2,165, + 165,165, 2, 2,165,165, 3, 3, 3, 2,156,156,156,156,156,156, + 2,156,156,156, 2, 2, 2, 2, 3, 3, 3, 2, 2, 2,147,147, + 147,147,148,148,148,148,148,148, 2, 2,158,158,158,158,158,158, + 2, 2,153,153,153,153,149,149,149,149,149,149,149, 2, 94, 94, + 94, 94, 94, 94, 2, 2, 2, 2, 94, 94, 2, 2, 2, 94, 85, 85, + 85, 85, 85, 85, 85, 2, 2, 85, 2, 2,101,101,101,101,101, 2, + 2, 2,101,101, 2, 2, 96, 96, 96, 96, 96, 2, 96, 96,111,111, + 111,111,111,111,111, 2,100,100,100,100,108,108,108,108,108,108, + 2,108,108,108, 2, 2,129,129,129,129,129,129,129, 2,129, 2, + 129,129,129,129, 2,129,129,129, 2, 2,109,109,109,109,109,109, + 109, 2,109,109, 2, 2,107,107,107,107, 2,107,107,107,107, 2, + 2,107,107, 2,107,107,107,107, 2, 1,107,107, 2, 2,107, 2, + 2, 2, 2, 2, 2,107, 2, 2,107,107,171,171,171,171,171,171, + 2,171, 2, 2,171, 2,171, 2,171, 2, 2,171, 2,171,171,171, + 171, 2,171, 2, 2, 2, 2,171,171, 2,137,137,137,137, 2,137, + 137,137,137,137, 2, 2,124,124,124,124,124,124, 2, 2,123,123, + 123,123,123,123, 2, 2,114,114,114,114,114, 2, 2, 2,114,114, + 2, 2,102,102,102,102,102,102, 2, 2,126,126,126,126,126,126, + 126, 2, 2,126,126,126,142,142,142,142,125,125,125,125,125,125, + 125, 2, 2, 2, 2,125,154,154,154,154,154,154,154, 2, 2,154, + 2, 2, 2,154,154, 2,154,154, 2,154,154, 2, 2,154,154,154, + 2, 2,150,150,150,150, 2, 2,150,150,150, 2, 2, 2,141,141, + 141,141,140,140,140,140,140,140,140, 2,121,121,121,121,121, 2, + 2, 2, 7, 7, 2, 2,169,169,169,169,169,169, 2, 2,133,133, + 133,133,133, 2,133,133,133,133,133, 2,133,133, 2, 2,133, 2, + 2, 2,134,134,134,134, 2, 2,134,134, 2,134,134,134,134,134, + 134, 2,138,138,138,138,138,138,138, 2,138,138, 2,138, 2, 2, + 138, 2,138,138, 2, 2,143,143,143,143,143,143, 2,143,143, 2, + 143,143,143,143,143, 2,143, 2, 2, 2,143,143, 2, 2,175,175, + 175,175,175,175, 2, 2,145,145,145,145,145, 2, 2, 2,163,163, + 163,163,163, 2,163,163,163,163,163, 2, 2, 2,163,163, 86, 2, + 2, 2, 63, 63, 63, 63, 63, 63, 2, 2, 63, 63, 63, 2, 63, 2, + 2, 2,157,157,157,157,157,157,157, 2, 80, 80, 80, 80, 80, 80, + 2, 2, 80, 80, 80, 2,127,127,127,127,127,127,127, 2,166,166, + 166,166,166,166, 2, 2, 79, 2, 2, 2,115,115,115,115,115,115, + 115, 2,115,115, 2, 2, 2, 2,115,115,159,159,159,159,159,159, + 159, 2,159,159, 2, 2,103,103,103,103,103,103, 2, 2,119,119, + 119,119,119,119, 2, 2,119,119, 2,119, 2,119,119,119,167,167, + 167,167,167,167, 2, 2,146,146,146,146,146,146,146, 2,172,172, + 172,172,172, 2, 2,172, 99, 99, 99, 99, 99, 99, 99, 2, 2, 2, + 2, 99,136,139, 13, 13,155, 2, 2, 2, 13, 13, 13, 2,136,136, + 136,136,155,155,155,155,155,155, 2, 2, 2, 2, 2,155,136,136, + 136, 2, 2, 17, 17, 17, 2, 17, 17, 2, 17, 15, 15, 15, 17, 17, + 17, 2, 2, 2, 15, 2, 2, 17, 2, 2,139,139,139,139,105,105, + 105,105,105,105,105, 2,105, 2, 2, 2,105,105, 2, 2, 1, 1, + 1, 2, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 2, 2, + 0, 2, 2, 0, 0, 2, 0, 0, 2, 0, 0, 2, 0, 2,131,131, + 131,131, 2, 2, 2,131, 2,131,131,131, 56, 56, 56, 2, 56, 2, + 2, 56, 56, 56, 2, 56, 56, 2, 56, 56, 6, 6, 2, 2, 2, 2, + 2, 6,151,151,151,151,151, 2, 2, 2,151,151, 2, 2, 2, 2, + 151,151,160,160,160,160,160,160,160, 2,152,152,152,152,152,152, + 2, 2, 2, 2, 2,152,164,164,164,164,164,164, 2, 2,168,168, + 168,168,168,168,168, 2, 2, 2, 2,168,174,174,174,174,174,174, + 174, 2,174,174, 2, 2, 2, 2,174,174, 2, 30, 30, 2,113,113, + 113,113,113, 2, 2,113,113,113,113, 2,132,132,132,132,132,132, + 2, 2, 2, 2,132,132, 2, 3, 3, 3, 2, 3, 3, 2, 3, 2, + 2, 3, 2, 3, 2, 3, 2, 2, 3, 2, 3, 2, 3, 2, 3, 3, + 2, 3, 15, 0, 0, 2, 0, 2, 2, 0, 13, 2, 2, 2, 2, 0, + 2, 2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, 9, 10, + 9, 11, 12, 13, 9, 9, 9, 14, 9, 9, 15, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 16, 17, 9, 9, 9, 9, 18, 9, 9, 9, 9, 9, 19, 20, - 21, 9, 22, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 23, 9, 9, 9, 9, 9, 24, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 16, 17, + 9, 9, 9, 9, 18, 9, 9, 9, 9, 9, 19, 20, 21, 9, 22, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 25, 9, + 9, 9, 23, 9, 9, 9, 9, 9, 24, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 25, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, @@ -3605,66 +3605,65 @@ static const uint8_t _hb_ucd_u8[17524]= 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, 0, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 0, 24, 25, 26, 27, 28, - 29, 30, 0, 0, 31, 32, 0, 33, 0, 34, 0, 35, 0, 0, 0, 0, - 36, 37, 38, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 41, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 26, 27, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 0, 0, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 23, 0, 0, 24, 25, 26, 27, 28, 29, 30, 0, 0, + 31, 32, 0, 33, 0, 34, 0, 35, 0, 0, 0, 0, 36, 37, 38, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 43, 44, 0, 45, 0, 0, 0, 0, 0, 0, - 46, 47, 0, 0, 0, 0, 0, 48, 0, 49, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 50, 51, 0, 0, 0, 52, 0, 0, - 53, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, - 55, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, - 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 58, 59, 60, 61, 62, 63, 64, 65, - 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 42, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 43, 44, 0, 45, 0, 0, 0, 0, 0, 0, 46, 47, 0, 0, + 0, 0, 0, 48, 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 50, 51, 0, 0, 0, 52, 0, 0, 53, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, + 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 57, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 58, 59, 60, 61, 62, 63, 64, 65, 0, 0, 0, 0, + 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 67, 68, 0, 69, 70, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, - 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, - 99,100,101,102,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,104, 0, 0, 0, 0, 0, 0,105,106, 0, - 107, 0, 0, 0,108, 0,109, 0,110, 0,111,112,113, 0,114, 0, - 0, 0,115, 0, 0, 0,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 67, 68, 0, 69, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, + 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102, + 103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,104, 0, 0, 0, 0, 0, 0,105,106, 0,107, 0, 0, 0, + 108, 0,109, 0,110, 0,111,112,113, 0,114, 0, 0, 0,115, 0, + 0, 0,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0,117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,118,119,120,121, 0,122,123,124, - 125,126, 0,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,128,129,130,131,132,133,134,135,136,137,138,139, - 140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155, - 156,157, 0, 0, 0,158,159,160,161, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,118,119,120,121, 0,122,123,124,125,126, 0,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 162, 0,163, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,164,165, 0, - 0, 0, 0, 0, 0, 0,166, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, + 144,145,146,147,148,149,150,151,152,153,154,155,156,157, 0, 0, + 0,158,159,160,161, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,167, 0, 0, 0,168,169, 0, 0, - 170, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,171, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,172, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,162, 0,163, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,164,165, 0, 0, 0, 0, 0, + 0, 0,166, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,173, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,167, 0, 0, 0,168,169, 0, 0,170, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,171, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,174, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,175, 0, 0, 0, 0, 0, + 0, 0,174, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,176,177, 0, 0, 0, 0,178, - 179, 0, 0, 0,180,181,182,183,184,185,186,187,188,189,190,191, - 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, - 208,209,210,211,212,213, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,175, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 2, 3, 4, + 0, 0, 0, 0, 0,176,177, 0, 0, 0, 0,178,179, 0, 0, 0, + 180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195, + 196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211, + 212,213, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, }; -static const uint16_t _hb_ucd_u16[9668]= +static const uint16_t _hb_ucd_u16[10904]= { 0, 0, 1, 2, 3, 4, 5, 6, 0, 0, 7, 8, 9, 10, 11, 12, 13, 13, 13, 14, 15, 13, 13, 16, 17, 18, 19, 20, 21, 22, 13, 23, @@ -3691,23 +3690,23 @@ static const uint16_t _hb_ucd_u16[9668]= 48, 184, 48, 185, 48, 186, 187, 188, 48, 48, 48, 189, 190, 191, 192, 193, 194, 192, 48, 48, 195, 48, 48, 196, 197, 48, 198, 48, 48, 48, 48, 199, 48, 200, 201, 202, 203, 48, 204, 205, 48, 48, 206, 48, 207, 208, 209, 209, - 48, 210, 48, 48, 48, 211, 212, 213, 192, 192, 214, 215, 216, 140, 140, 140, - 217, 48, 48, 218, 219, 160, 220, 221, 222, 48, 223, 64, 48, 48, 224, 225, - 48, 48, 226, 227, 228, 64, 48, 229, 230, 9, 9, 231, 232, 233, 234, 235, - 11, 11, 236, 27, 27, 27, 237, 238, 11, 239, 27, 27, 32, 32, 32, 32, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 240, 13, 13, 13, 13, 13, 13, - 241, 242, 241, 241, 242, 243, 241, 244, 245, 245, 245, 246, 247, 248, 249, 250, - 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 261, 262, 263, 264, 265, - 266, 267, 268, 269, 270, 271, 272, 272, 273, 274, 275, 209, 276, 277, 209, 278, - 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, - 280, 209, 281, 209, 209, 209, 209, 282, 209, 283, 279, 284, 209, 285, 286, 209, - 209, 209, 176, 140, 287, 140, 271, 271, 271, 288, 209, 209, 209, 209, 289, 271, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 290, 291, 209, 209, 292, - 209, 209, 209, 209, 209, 209, 293, 209, 209, 209, 209, 209, 209, 209, 209, 209, - 209, 209, 209, 209, 209, 209, 294, 295, 271, 296, 209, 209, 297, 279, 298, 279, + 48, 210, 48, 48, 48, 211, 212, 213, 192, 192, 214, 215, 32, 216, 217, 140, + 218, 48, 48, 219, 220, 160, 221, 222, 223, 48, 224, 64, 48, 48, 225, 226, + 48, 48, 227, 228, 229, 64, 48, 230, 231, 9, 9, 232, 233, 234, 235, 236, + 11, 11, 237, 27, 27, 27, 238, 239, 11, 240, 27, 27, 32, 32, 32, 32, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 241, 13, 13, 13, 13, 13, 13, + 242, 243, 242, 242, 243, 244, 242, 245, 246, 246, 246, 247, 248, 249, 250, 251, + 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 262, 263, 264, 265, 266, + 267, 268, 269, 270, 271, 272, 273, 273, 274, 275, 276, 209, 277, 278, 209, 279, + 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, + 281, 209, 282, 209, 209, 209, 209, 283, 209, 284, 280, 285, 209, 286, 287, 209, + 209, 209, 176, 140, 288, 140, 272, 272, 272, 289, 209, 209, 209, 209, 290, 272, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 291, 292, 209, 209, 293, + 209, 209, 209, 209, 209, 209, 294, 209, 209, 209, 209, 209, 209, 209, 209, 209, + 209, 209, 209, 209, 209, 209, 295, 296, 272, 297, 209, 209, 298, 280, 299, 280, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, - 279, 279, 279, 279, 279, 279, 279, 279, 299, 300, 279, 279, 279, 301, 279, 302, - 209, 209, 209, 279, 303, 209, 209, 304, 209, 305, 209, 209, 209, 209, 209, 209, + 280, 280, 280, 280, 280, 280, 280, 280, 300, 301, 280, 280, 280, 302, 280, 303, + 209, 209, 209, 280, 304, 209, 209, 305, 209, 209, 209, 209, 209, 209, 209, 209, 9, 9, 9, 11, 11, 11, 306, 307, 13, 13, 13, 13, 13, 13, 308, 309, 11, 11, 310, 48, 48, 48, 311, 312, 48, 313, 314, 314, 314, 314, 32, 32, 315, 316, 317, 318, 319, 320, 140, 140, 209, 321, 209, 209, 209, 209, 209, 322, @@ -3717,7 +3716,7 @@ static const uint16_t _hb_ucd_u16[9668]= 209, 333, 334, 209, 335, 336, 209, 209, 334, 209, 209, 336, 209, 209, 209, 209, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 209, 209, 209, 209, 48, 337, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 151, 209, 209, 209, 338, 48, 48, 229, + 48, 48, 48, 48, 48, 48, 48, 48, 151, 209, 209, 209, 338, 48, 48, 230, 339, 48, 340, 140, 13, 13, 341, 342, 13, 343, 48, 48, 48, 48, 344, 345, 31, 346, 347, 348, 13, 13, 13, 349, 350, 351, 352, 353, 354, 355, 140, 356, 357, 48, 358, 359, 48, 48, 48, 360, 361, 48, 48, 362, 363, 192, 32, 364, @@ -3733,1553 +3732,407 @@ static const uint16_t _hb_ucd_u16[9668]= 32, 404, 32, 405, 406, 407, 408, 409, 48, 48, 48, 48, 48, 48, 48, 410, 411, 2, 3, 4, 5, 412, 413, 414, 48, 415, 48, 200, 416, 417, 418, 419, 420, 48, 172, 421, 204, 204, 140, 140, 48, 48, 48, 48, 48, 48, 48, 71, - 422, 271, 271, 423, 272, 272, 272, 424, 425, 426, 427, 140, 140, 209, 209, 428, + 422, 272, 272, 423, 273, 273, 273, 424, 425, 426, 427, 140, 140, 209, 209, 428, 140, 140, 140, 140, 140, 140, 140, 140, 48, 151, 48, 48, 48, 100, 429, 430, 48, 48, 431, 48, 432, 48, 48, 433, 48, 434, 48, 48, 435, 436, 140, 140, 9, 9, 437, 11, 11, 48, 48, 48, 48, 204, 192, 9, 9, 438, 11, 439, 48, 48, 440, 48, 48, 48, 441, 442, 442, 443, 444, 445, 48, 48, 48, 388, 48, 48, 48, 313, 48, 199, 440, 140, 446, 27, 27, 447, 140, 140, 140, 140, 448, 48, 48, 449, 48, 450, 48, 451, 48, 200, 452, 140, 140, 140, 48, 453, - 48, 454, 48, 455, 140, 140, 140, 140, 48, 48, 48, 456, 271, 457, 271, 271, + 48, 454, 48, 455, 48, 207, 140, 140, 48, 48, 48, 456, 272, 457, 272, 272, 458, 459, 48, 460, 461, 462, 48, 463, 48, 464, 140, 140, 465, 48, 466, 467, 48, 48, 48, 468, 48, 469, 48, 470, 48, 471, 472, 140, 140, 140, 140, 140, 48, 48, 48, 48, 196, 140, 140, 140, 9, 9, 9, 473, 11, 11, 11, 474, 48, 48, 475, 192, 476, 9, 477, 11, 478, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 271, 479, 48, 48, 480, 481, 482, 140, 140, 483, - 48, 464, 484, 48, 62, 485, 140, 48, 486, 140, 140, 48, 487, 140, 48, 313, - 488, 48, 48, 489, 490, 457, 491, 492, 222, 48, 48, 493, 494, 48, 196, 192, - 495, 48, 496, 497, 498, 48, 48, 499, 222, 48, 48, 500, 501, 502, 503, 504, - 48, 97, 505, 506, 507, 140, 140, 140, 508, 509, 510, 48, 48, 511, 512, 192, - 513, 83, 84, 514, 515, 516, 517, 518, 519, 48, 48, 520, 521, 522, 523, 140, - 48, 48, 48, 524, 525, 526, 481, 140, 48, 48, 48, 527, 528, 192, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 48, 48, 529, 530, 531, 532, 140, 140, - 48, 48, 48, 533, 534, 192, 535, 140, 48, 48, 536, 537, 192, 538, 539, 140, - 48, 540, 541, 542, 313, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 48, 48, 505, 543, 140, 140, 140, 140, 140, 140, 9, 9, 11, 11, 148, 544, - 545, 546, 48, 547, 548, 192, 140, 140, 140, 140, 549, 48, 48, 550, 551, 140, - 552, 48, 48, 553, 554, 555, 48, 48, 556, 557, 558, 48, 48, 48, 48, 196, - 559, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 48, 560, 192, - 84, 48, 529, 561, 562, 148, 175, 563, 48, 564, 565, 566, 140, 140, 140, 140, - 567, 48, 48, 568, 569, 192, 570, 48, 571, 572, 192, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 573, - 574, 115, 48, 575, 576, 577, 140, 140, 140, 140, 140, 100, 271, 578, 579, 580, + 140, 140, 140, 140, 140, 140, 272, 479, 48, 48, 480, 481, 482, 483, 140, 484, + 48, 464, 485, 48, 62, 486, 140, 48, 487, 140, 140, 48, 488, 140, 48, 313, + 489, 48, 48, 490, 491, 457, 492, 493, 223, 48, 48, 494, 495, 48, 196, 192, + 496, 48, 497, 498, 499, 48, 48, 500, 223, 48, 48, 501, 502, 503, 504, 505, + 48, 97, 506, 507, 508, 140, 140, 140, 509, 510, 511, 48, 48, 512, 513, 192, + 514, 83, 84, 515, 516, 517, 518, 519, 520, 48, 48, 521, 522, 523, 524, 140, + 48, 48, 48, 525, 526, 527, 481, 140, 48, 48, 48, 528, 529, 192, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 48, 48, 530, 531, 532, 533, 140, 140, + 48, 48, 48, 534, 535, 192, 536, 140, 48, 48, 537, 538, 192, 539, 540, 140, + 48, 541, 542, 543, 313, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 48, 48, 506, 544, 140, 140, 140, 140, 140, 140, 9, 9, 11, 11, 148, 545, + 546, 547, 48, 548, 549, 192, 140, 140, 140, 140, 550, 48, 48, 551, 552, 140, + 553, 48, 48, 554, 555, 556, 48, 48, 557, 558, 559, 48, 48, 48, 48, 196, + 560, 140, 140, 140, 140, 140, 561, 140, 140, 140, 140, 140, 48, 48, 562, 192, + 84, 48, 530, 563, 564, 148, 175, 565, 48, 566, 567, 568, 140, 140, 140, 140, + 569, 48, 48, 570, 571, 192, 572, 48, 573, 574, 192, 48, 48, 575, 192, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 576, + 577, 115, 48, 578, 579, 580, 140, 140, 140, 140, 140, 100, 272, 581, 582, 583, 48, 48, 48, 48, 48, 48, 48, 48, 48, 207, 140, 140, 140, 140, 140, 140, - 272, 272, 272, 272, 272, 272, 581, 582, 48, 48, 48, 48, 48, 48, 48, 48, + 273, 273, 273, 273, 273, 273, 584, 585, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 388, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 48, 48, 48, 48, 48, 583, - 48, 48, 48, 584, 585, 586, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 48, 48, 48, 48, 48, 586, + 48, 48, 48, 587, 588, 589, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 71, 48, 48, 48, 48, 313, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 48, 587, 588, 192, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 48, 48, 48, 196, 48, 200, 370, 48, 48, 48, 48, 200, 192, 48, 204, 589, - 48, 48, 48, 590, 591, 592, 593, 594, 48, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 595, 48, 596, 192, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 9, 9, 11, 11, 271, 597, 140, 140, 140, 140, 140, 140, - 48, 48, 48, 48, 598, 599, 600, 600, 601, 602, 140, 140, 140, 140, 603, 604, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 440, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 199, 140, 605, - 196, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 606, - 48, 48, 607, 608, 140, 609, 610, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 590, 591, 192, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 48, 48, 48, 196, 48, 200, 370, 48, 48, 48, 48, 200, 192, 48, 204, 592, + 48, 48, 48, 593, 594, 595, 596, 597, 48, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 598, 48, 599, 192, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 9, 9, 11, 11, 272, 600, 9, 601, 11, 602, 140, 140, + 48, 48, 48, 48, 603, 604, 605, 605, 606, 607, 140, 140, 140, 140, 608, 609, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 199, 140, 610, + 48, 200, 140, 140, 140, 140, 140, 140, 48, 48, 48, 48, 48, 48, 48, 611, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 612, + 48, 48, 611, 613, 140, 614, 615, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 206, - 48, 48, 48, 48, 48, 48, 71, 151, 196, 611, 612, 140, 140, 140, 140, 140, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 192, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 322, 140, 140, 140, 140, - 32, 32, 613, 32, 614, 209, 209, 209, 209, 209, 209, 209, 322, 140, 140, 140, + 48, 48, 48, 48, 48, 48, 71, 151, 196, 616, 617, 140, 140, 140, 140, 140, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 618, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 619, 209, 427, 209, 620, + 32, 32, 216, 32, 621, 209, 209, 209, 209, 209, 209, 209, 322, 140, 140, 140, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 323, - 209, 209, 615, 209, 209, 209, 616, 617, 618, 209, 619, 209, 209, 209, 287, 140, - 209, 209, 209, 209, 620, 140, 140, 140, 140, 140, 140, 140, 271, 621, 271, 621, - 209, 209, 209, 209, 209, 338, 271, 461, 140, 140, 140, 140, 140, 140, 140, 140, - 9, 622, 11, 623, 624, 625, 241, 9, 626, 627, 628, 629, 630, 9, 622, 11, - 631, 632, 11, 633, 634, 635, 636, 9, 637, 11, 9, 622, 11, 623, 624, 11, - 241, 9, 626, 636, 9, 637, 11, 9, 622, 11, 638, 9, 639, 640, 641, 642, - 11, 643, 9, 644, 645, 646, 647, 11, 648, 9, 649, 11, 650, 538, 538, 538, - 32, 32, 32, 651, 32, 32, 652, 653, 654, 655, 45, 140, 140, 140, 140, 140, - 656, 657, 658, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 659, 660, 661, 27, 27, 27, 662, 140, 663, 140, 140, 140, 140, 140, 140, 140, - 48, 48, 151, 664, 665, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 666, 140, 48, 48, 667, 668, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 669, 192, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 587, 670, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 671, 200, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 672, 614, 140, 140, - 9, 9, 626, 11, 673, 370, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 503, 271, 271, 674, 675, 140, 140, 140, 140, - 503, 271, 676, 677, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 678, 48, 679, 680, 681, 682, 683, 684, 685, 206, 686, 206, 140, 140, 140, 687, - 209, 209, 688, 209, 209, 209, 209, 209, 209, 322, 333, 689, 689, 689, 209, 323, - 690, 209, 209, 209, 209, 209, 209, 209, 209, 209, 691, 140, 140, 140, 692, 209, - 693, 209, 209, 688, 694, 695, 323, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 696, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 697, 426, 426, - 209, 209, 209, 209, 209, 209, 209, 698, 209, 209, 209, 209, 209, 176, 688, 427, - 688, 209, 209, 209, 699, 176, 209, 209, 699, 209, 691, 688, 695, 140, 140, 140, - 209, 209, 209, 209, 209, 322, 691, 426, 700, 209, 209, 209, 701, 702, 176, 694, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 703, 209, 209, 209, 209, 209, 192, + 209, 209, 622, 209, 209, 209, 623, 624, 625, 209, 626, 209, 209, 209, 288, 140, + 209, 209, 209, 209, 627, 140, 140, 140, 140, 140, 140, 140, 272, 628, 272, 628, + 209, 209, 209, 209, 209, 338, 272, 461, 140, 140, 140, 140, 140, 140, 140, 140, + 9, 629, 11, 630, 631, 632, 242, 9, 633, 634, 635, 636, 637, 9, 629, 11, + 638, 639, 11, 640, 641, 642, 643, 9, 644, 11, 9, 629, 11, 630, 631, 11, + 242, 9, 633, 643, 9, 644, 11, 9, 629, 11, 645, 9, 646, 647, 648, 649, + 11, 650, 9, 651, 652, 653, 654, 11, 655, 9, 656, 11, 657, 539, 539, 539, + 32, 32, 32, 658, 32, 32, 659, 660, 661, 662, 45, 140, 140, 140, 140, 140, + 663, 664, 665, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 666, 667, 668, 27, 27, 27, 669, 140, 670, 140, 140, 140, 140, 140, 140, 140, + 48, 48, 151, 671, 672, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 673, 140, 48, 48, 674, 675, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 676, 192, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 590, 677, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 200, 678, 679, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 680, 200, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 681, 621, 140, 140, + 9, 9, 633, 11, 682, 370, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 504, 272, 272, 683, 684, 140, 140, 140, 140, + 504, 272, 685, 686, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 687, 48, 688, 689, 690, 691, 692, 693, 694, 206, 695, 206, 140, 140, 140, 696, + 209, 209, 697, 209, 209, 209, 209, 209, 209, 322, 333, 698, 698, 698, 209, 323, + 699, 209, 209, 209, 209, 209, 209, 209, 209, 209, 700, 140, 140, 140, 701, 209, + 702, 209, 209, 697, 703, 704, 323, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 705, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 706, 426, 426, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 176, 697, 427, + 697, 209, 209, 209, 707, 176, 209, 209, 707, 209, 700, 697, 704, 708, 140, 140, + 209, 209, 209, 209, 209, 707, 700, 426, 709, 209, 209, 209, 710, 711, 712, 703, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 713, 209, 209, 209, 209, 209, 714, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 140, 140, - 48, 48, 48, 207, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 204, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 481, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 204, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 100, 48, 48, 48, 48, 48, 48, 204, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 204, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 48, 48, 48, 71, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 140, 140, 140, 140, 140, - 704, 140, 584, 584, 584, 584, 584, 584, 140, 140, 140, 140, 140, 140, 140, 140, + 48, 48, 48, 48, 48, 48, 48, 207, 140, 140, 140, 140, 140, 140, 140, 140, + 715, 140, 587, 587, 587, 587, 587, 587, 140, 140, 140, 140, 140, 140, 140, 140, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 140, - 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 705, - 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 706, - 0, 0, 1, 1, 0, 2, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 5, 0, 6, 7, 7, 7, 8, 9, 10, 11, 12, - 13, 13, 13, 13, 14, 13, 13, 13, 13, 15, 16, 17, 18, 19, 20, 21, - 22, 23, 24, 25, 23, 23, 26, 23, 27, 28, 29, 23, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 23, 23, 39, 40, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, - 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, - 79, 80, 81, 82, 83, 84, 85, 82, 86, 86, 87, 88, 89, 90, 91, 82, - 92, 92, 92, 92, 92, 93, 94, 95, 96, 96, 96, 96, 96, 96, 96, 96, - 97, 97, 98, 97, 99, 100, 101, 97, 102, 97, 103, 104, 105, 106, 106, 107, - 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 109, 110, 110, 111, - 112, 113, 114, 115, 116, 116, 117, 118, 119, 120, 120, 121, 120, 122, 108, 123, - 124, 125, 126, 127, 128, 129, 130, 116, 131, 132, 133, 134, 135, 136, 137, 82, - 138, 138, 139, 138, 140, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, - 4, 151, 152, 153, 4, 154, 7, 7, 155, 11, 156, 157, 11, 158, 159, 160, - 161, 0, 0, 162, 163, 0, 164, 165, 0, 166, 167, 4, 168, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 169, 170, 0, 0, 0, 0, 0, - 171, 171, 171, 171, 171, 171, 171, 171, 0, 0, 0, 172, 173, 0, 0, 0, - 174, 174, 174, 4, 175, 175, 175, 176, 93, 177, 178, 179, 180, 181, 181, 13, - 0, 0, 182, 82, 183, 184, 184, 185, 184, 184, 184, 184, 184, 184, 186, 187, - 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 96, 96, 198, 199, 0, 200, - 201, 0, 0, 202, 0, 0, 203, 204, 194, 194, 205, 0, 0, 0, 0, 0, - 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 0, 0, - 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 207, 206, 208, 209, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 211, 13, 13, 13, 212, 212, 213, - 0, 214, 4, 4, 215, 4, 216, 217, 218, 219, 220, 221, 222, 222, 223, 40, - 224, 225, 226, 227, 228, 228, 229, 230, 231, 232, 233, 92, 234, 234, 235, 236, - 237, 238, 239, 240, 106, 106, 241, 242, 96, 96, 96, 96, 96, 243, 244, 245, - 82, 82, 82, 82, 82, 82, 82, 82, 184, 184, 184, 246, 184, 184, 247, 82, - 248, 249, 250, 23, 23, 23, 251, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 252, 23, 23, 253, 23, 254, 255, 256, 257, 258, 259, 23, 23, 23, 260, - 261, 1, 1, 262, 263, 201, 264, 265, 266, 267, 268, 82, 269, 269, 269, 270, - 271, 272, 11, 11, 273, 274, 187, 275, 82, 82, 82, 82, 276, 277, 278, 279, - 280, 281, 282, 283, 284, 285, 286, 82, 287, 287, 288, 289, 290, 291, 292, 293, - 294, 295, 296, 297, 298, 299, 300, 301, 302, 302, 302, 302, 302, 302, 302, 302, - 302, 303, 304, 305, 306, 307, 82, 82, 308, 309, 310, 311, 312, 313, 82, 314, - 315, 316, 82, 82, 317, 318, 319, 320, 321, 322, 323, 324, 325, 82, 326, 327, - 328, 329, 330, 331, 332, 333, 82, 82, 334, 334, 335, 82, 336, 337, 336, 338, - 339, 340, 341, 342, 343, 82, 82, 82, 82, 82, 82, 344, 345, 346, 347, 348, - 349, 350, 351, 352, 353, 354, 355, 356, 357, 357, 358, 359, 360, 360, 361, 362, - 363, 364, 365, 366, 367, 367, 367, 368, 369, 370, 371, 82, 372, 373, 374, 375, - 376, 377, 378, 379, 380, 381, 382, 383, 384, 384, 385, 386, 387, 387, 388, 82, - 82, 82, 82, 82, 389, 390, 391, 82, 392, 392, 393, 394, 395, 396, 397, 398, - 399, 400, 401, 82, 82, 82, 82, 82, 402, 403, 82, 82, 82, 404, 404, 405, - 406, 407, 408, 82, 82, 409, 410, 411, 412, 412, 413, 414, 414, 415, 416, 417, - 418, 82, 82, 82, 82, 82, 419, 420, 421, 422, 423, 424, 425, 426, 82, 82, - 427, 428, 429, 430, 431, 432, 82, 82, 82, 82, 82, 82, 82, 82, 82, 433, - 434, 435, 436, 82, 82, 437, 438, 439, 440, 440, 440, 440, 440, 440, 440, 440, - 440, 440, 440, 440, 441, 82, 82, 82, 440, 440, 440, 442, 440, 440, 440, 440, - 440, 440, 443, 82, 82, 82, 82, 82, 82, 82, 82, 82, 444, 445, 445, 446, - 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, 448, 447, 447, 447, 447, 447, - 447, 447, 447, 447, 447, 447, 447, 449, 450, 450, 450, 450, 450, 450, 450, 450, - 450, 450, 451, 82, 82, 82, 82, 82, 452, 453, 82, 82, 82, 82, 82, 82, - 212, 212, 212, 212, 212, 212, 212, 212, 212, 454, 455, 456, 457, 458, 459, 460, - 461, 461, 462, 463, 464, 82, 82, 82, 82, 82, 465, 466, 82, 82, 82, 82, - 82, 82, 467, 467, 468, 82, 82, 82, 469, 469, 470, 469, 471, 82, 82, 472, - 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 474, - 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 476, 477, - 478, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 479, - 480, 191, 191, 191, 191, 191, 191, 191, 191, 481, 482, 483, 484, 484, 484, 484, - 484, 484, 484, 484, 484, 484, 484, 485, 486, 486, 486, 487, 488, 489, 82, 82, - 0, 0, 0, 0, 0, 0, 0, 490, 0, 0, 0, 0, 0, 491, 82, 82, - 7, 492, 493, 0, 0, 0, 489, 82, 0, 0, 0, 0, 0, 0, 0, 494, - 0, 495, 0, 496, 497, 498, 0, 170, 11, 11, 499, 82, 82, 82, 491, 491, - 0, 0, 500, 501, 82, 82, 82, 82, 0, 0, 502, 0, 503, 504, 505, 0, - 506, 507, 508, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 509, 0, 0, - 0, 0, 0, 0, 0, 0, 510, 0, 511, 511, 511, 511, 511, 511, 511, 511, - 511, 511, 511, 511, 512, 513, 82, 82, 514, 515, 82, 82, 82, 82, 82, 82, - 516, 517, 13, 518, 519, 82, 82, 82, 520, 521, 522, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 523, 524, 525, 526, 82, 82, 82, 82, 82, 82, 527, 528, - 82, 82, 82, 82, 82, 82, 529, 530, 82, 82, 82, 82, 82, 82, 82, 531, - 532, 532, 532, 532, 532, 532, 533, 82, 534, 534, 535, 82, 82, 82, 82, 82, - 82, 82, 82, 536, 0, 537, 82, 82, 261, 182, 82, 82, 82, 82, 82, 82, - 538, 539, 540, 541, 542, 543, 82, 544, 0, 545, 0, 0, 491, 546, 547, 494, - 0, 0, 0, 0, 0, 548, 82, 549, 550, 551, 552, 553, 82, 82, 82, 82, - 0, 0, 0, 0, 0, 0, 554, 555, 0, 0, 0, 556, 0, 0, 490, 557, - 545, 0, 558, 0, 559, 560, 561, 82, 0, 0, 491, 562, 563, 0, 564, 565, - 0, 0, 0, 0, 258, 0, 0, 490, 184, 184, 184, 184, 184, 184, 184, 82, - 184, 247, 184, 184, 184, 184, 184, 184, 566, 184, 184, 184, 184, 184, 184, 184, - 184, 184, 184, 184, 184, 567, 184, 184, 184, 184, 184, 184, 184, 184, 184, 568, - 184, 184, 566, 82, 82, 82, 82, 82, 566, 82, 82, 82, 82, 82, 82, 82, - 184, 184, 569, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 570, 82, 82, - 571, 0, 0, 0, 82, 82, 82, 82, 7, 7, 7, 7, 7, 7, 7, 572, - 0, 0, 0, 0, 1, 2, 2, 3, 0, 4, 0, 4, 2, 2, 5, 2, - 2, 2, 2, 2, 2, 2, 2, 6, 7, 8, 0, 0, 9, 9, 9, 9, - 9, 9, 10, 11, 12, 13, 14, 14, 15, 14, 14, 14, 14, 14, 14, 14, - 16, 17, 14, 14, 18, 18, 18, 18, 19, 18, 18, 18, 18, 18, 20, 21, - 21, 21, 22, 20, 21, 21, 21, 21, 21, 23, 24, 25, 25, 25, 25, 25, - 25, 26, 25, 25, 25, 27, 28, 26, 29, 30, 31, 32, 31, 31, 31, 31, - 33, 34, 35, 31, 31, 31, 36, 31, 31, 31, 31, 29, 37, 38, 37, 37, - 37, 37, 37, 37, 37, 39, 31, 31, 40, 40, 40, 40, 40, 40, 41, 26, - 42, 42, 42, 42, 42, 42, 42, 43, 44, 44, 44, 44, 44, 45, 44, 46, - 47, 47, 47, 48, 37, 49, 31, 31, 31, 50, 51, 31, 52, 31, 31, 31, - 53, 53, 53, 53, 53, 53, 54, 53, 55, 53, 53, 53, 56, 57, 58, 59, - 59, 60, 61, 62, 57, 63, 64, 65, 66, 59, 59, 67, 68, 69, 70, 71, - 71, 72, 73, 74, 69, 75, 76, 77, 78, 71, 79, 26, 80, 81, 82, 83, - 83, 84, 85, 86, 81, 87, 88, 26, 89, 83, 90, 91, 92, 93, 94, 95, - 95, 96, 97, 98, 93, 99, 100, 101, 102, 95, 95, 26, 103, 104, 105, 106, - 107, 104, 108, 109, 104, 105, 110, 26, 111, 108, 108, 112, 113, 114, 115, 113, - 113, 115, 113, 116, 114, 117, 118, 119, 120, 113, 121, 113, 122, 123, 124, 122, - 122, 124, 125, 126, 123, 127, 128, 128, 129, 122, 130, 26, 131, 132, 133, 131, - 131, 131, 131, 131, 132, 133, 134, 131, 135, 131, 131, 131, 136, 137, 138, 139, - 137, 137, 140, 141, 138, 142, 143, 137, 144, 137, 145, 26, 146, 147, 147, 147, - 147, 147, 147, 148, 147, 147, 147, 149, 26, 26, 26, 26, 150, 151, 152, 152, - 153, 152, 152, 154, 155, 156, 152, 157, 158, 158, 158, 158, 158, 159, 158, 158, - 158, 160, 159, 158, 158, 158, 158, 159, 158, 158, 158, 161, 158, 161, 162, 163, - 164, 164, 164, 164, 165, 165, 165, 165, 166, 167, 165, 165, 165, 165, 165, 168, - 169, 169, 169, 169, 170, 170, 170, 170, 170, 171, 172, 171, 170, 171, 170, 170, - 170, 170, 171, 172, 171, 170, 172, 170, 170, 170, 171, 170, 170, 170, 170, 173, - 170, 170, 170, 174, 170, 170, 170, 175, 176, 176, 176, 176, 176, 176, 177, 177, - 178, 178, 178, 178, 179, 179, 179, 180, 181, 181, 181, 181, 181, 182, 181, 183, - 184, 184, 185, 186, 187, 187, 188, 26, 189, 189, 190, 26, 191, 192, 193, 26, - 194, 194, 194, 194, 194, 194, 194, 195, 194, 196, 194, 196, 197, 198, 198, 199, - 198, 198, 198, 198, 198, 198, 198, 200, 198, 201, 178, 178, 178, 178, 202, 26, - 203, 203, 203, 204, 203, 205, 203, 205, 206, 203, 207, 207, 207, 208, 209, 26, - 210, 210, 210, 210, 210, 211, 210, 210, 210, 212, 210, 213, 214, 214, 214, 215, - 216, 216, 216, 216, 216, 216, 216, 217, 216, 216, 216, 218, 216, 219, 216, 219, - 216, 220, 9, 9, 9, 221, 26, 26, 222, 222, 222, 222, 222, 223, 222, 222, - 224, 224, 224, 224, 225, 225, 225, 225, 225, 225, 226, 227, 228, 228, 228, 228, - 228, 228, 228, 229, 228, 230, 231, 231, 231, 231, 231, 231, 18, 232, 165, 165, - 165, 165, 165, 233, 224, 26, 234, 9, 235, 236, 237, 238, 239, 240, 2, 2, - 2, 2, 2, 241, 242, 243, 2, 244, 2, 2, 2, 245, 14, 14, 246, 246, - 246, 246, 14, 247, 14, 14, 14, 246, 14, 14, 248, 14, 248, 14, 249, 250, - 14, 14, 251, 252, 0, 253, 0, 0, 254, 0, 255, 256, 0, 257, 2, 258, - 259, 26, 9, 9, 9, 9, 260, 26, 261, 262, 4, 0, 0, 263, 0, 0, - 2, 264, 0, 0, 0, 265, 26, 26, 0, 266, 26, 26, 267, 267, 267, 267, - 0, 0, 268, 0, 0, 0, 269, 0, 270, 270, 270, 270, 17, 17, 17, 17, - 17, 17, 271, 272, 166, 167, 273, 273, 273, 273, 273, 273, 273, 274, 275, 274, - 170, 170, 172, 26, 172, 172, 172, 172, 0, 0, 0, 276, 277, 277, 277, 278, - 277, 277, 277, 277, 277, 277, 279, 26, 277, 277, 280, 26, 26, 26, 0, 0, - 281, 0, 0, 0, 282, 283, 0, 284, 285, 286, 286, 286, 286, 286, 286, 286, - 286, 286, 287, 288, 289, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 291, - 292, 293, 293, 293, 293, 293, 294, 169, 169, 295, 0, 0, 293, 293, 293, 293, - 276, 296, 290, 290, 169, 169, 169, 295, 169, 169, 169, 297, 0, 0, 290, 290, - 290, 290, 290, 298, 290, 290, 290, 0, 299, 299, 299, 299, 299, 300, 299, 299, - 301, 26, 302, 302, 302, 302, 302, 302, 303, 303, 303, 303, 303, 304, 26, 26, - 305, 305, 305, 305, 305, 305, 305, 26, 306, 2, 2, 2, 2, 307, 2, 2, - 2, 308, 309, 258, 26, 26, 310, 2, 311, 311, 311, 311, 311, 312, 0, 265, - 313, 313, 313, 313, 313, 313, 313, 26, 314, 314, 314, 314, 315, 316, 314, 317, - 318, 318, 318, 318, 318, 319, 320, 320, 320, 320, 321, 322, 169, 169, 169, 323, - 324, 324, 324, 324, 324, 325, 324, 326, 164, 164, 164, 327, 328, 328, 328, 328, - 328, 328, 329, 26, 328, 330, 328, 331, 332, 332, 332, 332, 333, 26, 26, 334, - 335, 335, 336, 26, 337, 337, 337, 26, 172, 172, 2, 2, 2, 2, 2, 338, - 339, 340, 176, 176, 335, 335, 335, 335, 335, 341, 335, 342, 343, 26, 169, 169, - 295, 344, 169, 169, 169, 169, 169, 343, 277, 280, 277, 277, 277, 277, 277, 345, - 346, 26, 347, 348, 25, 25, 349, 350, 351, 25, 31, 31, 352, 26, 353, 31, - 31, 31, 31, 354, 31, 31, 355, 31, 31, 356, 26, 26, 26, 26, 31, 31, - 9, 9, 0, 265, 9, 357, 0, 0, 0, 0, 358, 0, 257, 359, 360, 31, - 31, 31, 31, 361, 362, 0, 0, 0, 363, 290, 289, 290, 290, 290, 290, 364, - 365, 365, 365, 366, 257, 257, 26, 367, 368, 369, 368, 368, 370, 368, 368, 371, - 368, 372, 368, 372, 368, 368, 368, 368, 368, 368, 368, 373, 374, 0, 0, 0, - 0, 0, 375, 0, 14, 252, 0, 376, 377, 26, 26, 26, 0, 0, 0, 378, - 379, 379, 379, 380, 381, 381, 381, 381, 381, 381, 382, 26, 383, 0, 0, 359, - 384, 384, 384, 384, 385, 386, 387, 387, 387, 388, 389, 389, 389, 389, 389, 390, - 391, 391, 391, 392, 393, 393, 393, 393, 394, 393, 395, 26, 396, 396, 396, 396, - 396, 396, 397, 397, 397, 397, 397, 397, 398, 398, 398, 399, 398, 400, 401, 401, - 401, 401, 402, 401, 401, 401, 401, 402, 403, 403, 403, 403, 403, 26, 404, 404, - 404, 404, 404, 404, 405, 406, 407, 408, 407, 408, 409, 407, 410, 407, 410, 411, - 412, 412, 412, 412, 412, 412, 413, 26, 414, 414, 414, 414, 414, 414, 415, 26, - 414, 414, 416, 26, 414, 26, 26, 26, 417, 2, 2, 2, 2, 2, 418, 419, - 420, 421, 422, 422, 422, 422, 423, 424, 425, 425, 426, 425, 427, 427, 427, 427, - 428, 428, 428, 429, 430, 428, 26, 26, 431, 431, 432, 433, 434, 434, 434, 435, - 436, 436, 436, 437, 438, 438, 438, 438, 439, 439, 439, 440, 439, 439, 441, 439, - 439, 439, 439, 439, 442, 443, 444, 445, 446, 446, 447, 448, 446, 449, 446, 449, - 450, 450, 450, 450, 451, 451, 451, 451, 452, 452, 452, 452, 453, 454, 453, 26, - 455, 455, 455, 455, 455, 455, 456, 457, 458, 458, 459, 458, 460, 460, 461, 460, - 462, 462, 463, 464, 26, 465, 26, 26, 466, 466, 466, 466, 466, 467, 26, 26, - 468, 468, 468, 468, 468, 468, 469, 26, 468, 468, 469, 470, 471, 471, 471, 471, - 471, 26, 471, 472, 473, 473, 473, 473, 474, 475, 473, 473, 474, 476, 26, 26, - 31, 31, 31, 50, 477, 477, 477, 477, 477, 478, 479, 26, 480, 26, 26, 26, - 26, 26, 26, 481, 482, 482, 482, 482, 482, 26, 483, 483, 483, 483, 483, 484, - 26, 26, 485, 485, 485, 486, 26, 26, 26, 26, 487, 487, 487, 488, 26, 26, - 489, 489, 490, 26, 491, 491, 491, 491, 491, 492, 493, 491, 491, 491, 492, 494, - 495, 495, 495, 495, 496, 497, 498, 498, 498, 499, 498, 500, 501, 501, 501, 501, - 501, 501, 502, 501, 501, 26, 503, 503, 503, 503, 504, 26, 505, 505, 505, 505, - 506, 137, 507, 26, 508, 508, 509, 508, 508, 508, 508, 508, 510, 26, 26, 26, - 511, 512, 513, 514, 513, 515, 516, 516, 516, 516, 516, 516, 516, 517, 516, 518, - 519, 520, 521, 522, 522, 523, 524, 525, 520, 526, 527, 528, 529, 530, 530, 26, - 531, 532, 531, 531, 531, 531, 533, 531, 534, 535, 533, 536, 537, 26, 26, 26, - 538, 538, 538, 538, 538, 538, 538, 539, 540, 26, 26, 26, 541, 541, 541, 541, - 541, 26, 541, 542, 543, 543, 543, 543, 543, 543, 544, 543, 543, 543, 543, 544, - 545, 545, 545, 545, 546, 26, 545, 547, 198, 548, 26, 26, 549, 549, 549, 549, - 549, 549, 549, 550, 549, 550, 164, 164, 551, 26, 26, 26, 552, 552, 552, 553, - 552, 554, 552, 552, 555, 26, 26, 26, 556, 556, 556, 556, 556, 556, 556, 557, - 558, 558, 558, 558, 558, 558, 559, 560, 561, 562, 563, 564, 564, 564, 565, 566, - 561, 26, 564, 567, 568, 569, 568, 568, 568, 568, 568, 569, 570, 26, 26, 26, - 571, 571, 571, 571, 571, 26, 572, 572, 572, 572, 572, 572, 573, 26, 178, 178, - 574, 574, 574, 574, 574, 574, 574, 575, 53, 576, 26, 26, 577, 577, 577, 577, - 578, 26, 577, 578, 579, 580, 579, 579, 579, 579, 581, 579, 582, 26, 579, 579, - 579, 583, 584, 584, 584, 584, 585, 584, 584, 586, 587, 26, 588, 589, 590, 590, - 590, 590, 588, 591, 590, 26, 590, 592, 593, 594, 595, 595, 595, 596, 597, 598, - 595, 599, 26, 26, 600, 600, 600, 601, 602, 602, 603, 602, 602, 602, 602, 604, - 602, 602, 602, 605, 26, 26, 606, 26, 108, 108, 108, 108, 108, 108, 607, 608, - 609, 609, 609, 609, 609, 609, 609, 610, 609, 611, 612, 26, 613, 26, 26, 26, - 26, 26, 614, 614, 614, 614, 614, 614, 614, 614, 615, 26, 616, 616, 616, 616, - 616, 616, 617, 26, 616, 616, 616, 618, 619, 619, 619, 619, 620, 26, 26, 26, - 621, 621, 621, 621, 621, 621, 621, 622, 305, 305, 305, 623, 624, 624, 624, 625, - 624, 626, 627, 627, 627, 627, 627, 627, 627, 627, 627, 628, 627, 629, 630, 630, - 630, 631, 631, 26, 632, 632, 632, 632, 633, 26, 632, 634, 634, 632, 632, 635, - 632, 632, 26, 26, 636, 636, 636, 636, 636, 636, 636, 637, 638, 638, 638, 638, - 638, 638, 638, 639, 640, 640, 640, 640, 640, 641, 640, 640, 640, 642, 640, 640, - 643, 26, 345, 26, 644, 644, 644, 644, 644, 644, 644, 26, 645, 645, 645, 645, - 645, 645, 646, 26, 26, 26, 26, 647, 644, 648, 26, 26, 26, 26, 649, 650, - 651, 286, 286, 286, 652, 26, 653, 26, 26, 26, 654, 26, 655, 26, 656, 656, - 656, 656, 656, 656, 656, 656, 656, 657, 658, 658, 658, 658, 658, 659, 658, 660, - 658, 661, 658, 662, 359, 26, 26, 26, 0, 0, 0, 265, 0, 0, 359, 26, - 9, 663, 9, 9, 221, 26, 0, 0, 0, 0, 276, 26, 257, 362, 0, 0, - 664, 665, 0, 666, 667, 668, 0, 0, 0, 669, 0, 0, 246, 26, 26, 26, - 0, 0, 257, 26, 0, 0, 0, 259, 0, 0, 254, 0, 0, 0, 0, 254, - 670, 671, 0, 672, 673, 0, 0, 0, 269, 674, 254, 254, 0, 0, 0, 675, - 676, 677, 678, 0, 276, 0, 0, 0, 0, 268, 0, 0, 679, 679, 679, 679, - 679, 680, 26, 681, 682, 679, 26, 26, 2, 2, 2, 346, 683, 419, 26, 26, - 684, 270, 270, 685, 686, 687, 18, 18, 18, 688, 26, 26, 26, 689, 26, 26, - 690, 690, 690, 690, 690, 691, 690, 692, 690, 693, 26, 26, 26, 26, 694, 694, - 694, 695, 26, 26, 696, 696, 696, 696, 696, 696, 696, 697, 26, 26, 698, 698, - 698, 698, 698, 699, 26, 26, 700, 700, 700, 700, 700, 701, 172, 702, 170, 172, - 703, 703, 703, 703, 704, 703, 705, 26, 706, 706, 706, 706, 706, 707, 706, 708, - 26, 26, 362, 0, 0, 0, 376, 26, 709, 31, 31, 31, 710, 711, 712, 713, - 714, 715, 710, 716, 710, 712, 712, 717, 31, 718, 31, 719, 720, 718, 31, 719, - 26, 26, 721, 26, 0, 359, 0, 0, 0, 257, 362, 0, 362, 0, 362, 0, - 0, 276, 26, 26, 722, 0, 0, 0, 723, 26, 0, 0, 0, 0, 0, 359, - 0, 259, 265, 26, 276, 26, 26, 26, 0, 0, 0, 724, 0, 376, 0, 376, - 0, 0, 257, 725, 0, 359, 259, 26, 0, 26, 0, 265, 0, 26, 0, 0, - 0, 276, 0, 359, 265, 26, 26, 26, 0, 276, 0, 376, 0, 726, 0, 0, - 257, 722, 0, 727, 0, 265, 0, 259, 277, 277, 277, 280, 345, 26, 277, 277, - 728, 26, 277, 277, 277, 729, 277, 277, 277, 277, 26, 26, 730, 26, 26, 26, - 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 939, 940, 941, 942, 946, 948, 0, 962, 969, 970, 971, 976, - 1001,1002,1003,1008, 0,1033,1040,1041,1042,1043,1047, 0, 0,1080,1081,1082, - 1086,1110, 0, 0,1124,1125,1126,1127,1131,1133, 0,1147,1154,1155,1156,1161, - 1187,1188,1189,1193, 0,1219,1226,1227,1228,1229,1233, 0, 0,1267,1268,1269, - 1273,1298, 0,1303, 943,1128, 944,1129, 954,1139, 958,1143, 959,1144, 960,1145, - 961,1146, 964,1149, 0, 0, 973,1158, 974,1159, 975,1160, 983,1168, 978,1163, - 988,1173, 990,1175, 991,1176, 993,1178, 994,1179, 0, 0,1004,1190,1005,1191, - 1006,1192,1014,1199,1007, 0, 0, 0,1016,1201,1020,1206, 0,1022,1208,1025, - 1211,1023,1209, 0, 0, 0, 0,1032,1218,1037,1223,1035,1221, 0, 0, 0, - 1044,1230,1045,1231,1049,1235, 0, 0,1058,1244,1064,1250,1060,1246,1066,1252, - 1067,1253,1072,1258,1069,1255,1077,1264,1074,1261, 0, 0,1083,1270,1084,1271, - 1085,1272,1088,1275,1089,1276,1096,1283,1103,1290,1111,1299,1115,1118,1307,1120, - 1309,1121,1310, 0,1053,1239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,1093,1280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 949,1134,1010,1195,1050,1236,1090,1277,1341,1368,1340,1367,1342,1369,1339, - 1366, 0,1320,1347,1418,1419,1323,1350, 0, 0, 992,1177,1018,1204,1055,1241, - 1416,1417,1415,1424,1202, 0, 0, 0, 987,1172, 0, 0,1031,1217,1321,1348, - 1322,1349,1338,1365, 950,1135, 951,1136, 979,1164, 980,1165,1011,1196,1012,1197, - 1051,1237,1052,1238,1061,1247,1062,1248,1091,1278,1092,1279,1071,1257,1076,1263, - 0, 0, 997,1182, 0, 0, 0, 0, 0, 0, 945,1130, 982,1167,1337,1364, - 1335,1362,1046,1232,1422,1423,1113,1301, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 8, 9, 0, 10,1425, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, 0,1314,1427, 5,1434,1438,1443, 0, - 1450, 0,1455,1461,1514, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1446,1458, - 1468,1476,1480,1486,1517, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1489,1503, - 1494,1500,1508, 0, 0, 0, 0,1520,1521, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,1526,1528, 0,1525, 0, 0, 0,1522, 0, 0, 0, 0, - 1536,1532,1539, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1534, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1556, 0, 0, - 0, 0, 0, 0,1548,1550, 0,1547, 0, 0, 0,1567, 0, 0, 0, 0, - 1558,1554,1561, 0, 0, 0, 0, 0, 0, 0,1568,1569, 0, 0, 0, 0, - 0, 0, 0, 0, 0,1529,1551, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,1523,1545,1524,1546, 0, 0,1527,1549, 0, 0,1570,1571, - 1530,1552,1531,1553, 0, 0,1533,1555,1535,1557,1537,1559, 0, 0,1572,1573, - 1544,1566,1538,1560,1540,1562,1541,1563,1542,1564, 0, 0,1543,1565, 0, 0, - 0, 0, 0, 0, 0, 0,1606,1607,1609,1608,1610, 0, 0, 0, 0, 0, - 0, 0, 0, 0,1613, 0,1611, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,1612, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1620, 0, 0, - 0, 0, 0, 0, 0,1623, 0, 0,1624, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1614,1615,1616,1617, - 1618,1619,1621,1622, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1628, - 1629, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1625,1626, 0,1627, 0, 0, 0,1634, 0, 0,1635, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1630,1631,1632, - 0, 0,1633, 0, 0, 0, 0, 0, 0, 0, 0, 0,1639, 0, 0,1638, - 1640, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1636,1637, 0, 0, 0, 0, 0, 0,1641, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1642,1644, - 1643, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1645, 0, 0, 0, - 0, 0, 0, 0,1646, 0, 0, 0, 0, 0, 0,1648,1649, 0,1647,1650, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1651,1653, - 1652, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1654, 0, - 1655,1657,1656, 0, 0, 0, 0,1659, 0, 0, 0, 0, 0, 0, 0, 0, - 0,1660, 0, 0, 0, 0,1661, 0, 0, 0, 0,1662, 0, 0, 0, 0, - 1663, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1658, 0, 0, - 0, 0, 0, 0, 0, 0, 0,1664, 0,1665,1673, 0,1674, 0, 0, 0, - 0, 0, 0, 0, 0,1666, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,1668, 0, 0, 0, 0, 0, 0, 0, 0, - 0,1669, 0, 0, 0, 0,1670, 0, 0, 0, 0,1671, 0, 0, 0, 0, - 1672, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1667, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1675, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1676, 0,1677, 0,1678, 0, - 1679, 0,1680, 0, 0, 0,1681, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1682, - 0,1683, 0, 0,1684,1685, 0,1686, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 953,1138, 955,1140, 956,1141, 957,1142,1324,1351, 963,1148, - 965,1150, 968,1153, 966,1151, 967,1152,1378,1380,1379,1381, 984,1169, 985,1170, - 1420,1421, 986,1171, 989,1174, 995,1180, 998,1183, 996,1181, 999,1184,1000,1185, - 1015,1200,1329,1356,1017,1203,1019,1205,1021,1207,1024,1210,1687,1688,1027,1213, - 1026,1212,1028,1214,1029,1215,1030,1216,1034,1220,1036,1222,1039,1225,1038,1224, - 1334,1361,1336,1363,1382,1384,1383,1385,1056,1242,1057,1243,1059,1245,1063,1249, - 1689,1690,1065,1251,1068,1254,1070,1256,1386,1387,1388,1389,1691,1692,1073,1259, - 1075,1262,1079,1266,1078,1265,1095,1282,1098,1285,1097,1284,1390,1391,1392,1393, - 1099,1286,1100,1287,1101,1288,1102,1289,1105,1292,1104,1291,1106,1294,1107,1295, - 1108,1296,1114,1302,1119,1308,1122,1311,1123,1312,1186,1260,1293,1305, 0,1394, - 0, 0, 0, 0, 952,1137, 947,1132,1317,1344,1316,1343,1319,1346,1318,1345, - 1693,1695,1371,1375,1370,1374,1373,1377,1372,1376,1694,1696, 981,1166, 977,1162, - 972,1157,1326,1353,1325,1352,1328,1355,1327,1354,1697,1698,1009,1194,1013,1198, - 1054,1240,1048,1234,1331,1358,1330,1357,1333,1360,1332,1359,1699,1700,1396,1401, - 1395,1400,1398,1403,1397,1402,1399,1404,1094,1281,1087,1274,1406,1411,1405,1410, - 1408,1413,1407,1412,1409,1414,1109,1297,1117,1306,1116,1304,1112,1300, 0, 0, - 0, 0, 0, 0,1471,1472,1701,1705,1702,1706,1703,1707,1430,1431,1715,1719, - 1716,1720,1717,1721,1477,1478,1729,1731,1730,1732, 0, 0,1435,1436,1733,1735, - 1734,1736, 0, 0,1481,1482,1737,1741,1738,1742,1739,1743,1439,1440,1751,1755, - 1752,1756,1753,1757,1490,1491,1765,1768,1766,1769,1767,1770,1447,1448,1771,1774, - 1772,1775,1773,1776,1495,1496,1777,1779,1778,1780, 0, 0,1451,1452,1781,1783, - 1782,1784, 0, 0,1504,1505,1785,1788,1786,1789,1787,1790, 0,1459, 0,1791, - 0,1792, 0,1793,1509,1510,1794,1798,1795,1799,1796,1800,1462,1463,1808,1812, - 1809,1813,1810,1814,1467, 21,1475, 22,1479, 23,1485, 24,1493, 27,1499, 28, - 1507, 29, 0, 0,1704,1708,1709,1710,1711,1712,1713,1714,1718,1722,1723,1724, - 1725,1726,1727,1728,1740,1744,1745,1746,1747,1748,1749,1750,1754,1758,1759,1760, - 1761,1762,1763,1764,1797,1801,1802,1803,1804,1805,1806,1807,1811,1815,1816,1817, - 1818,1819,1820,1821,1470,1469,1822,1474,1465, 0,1473,1825,1429,1428,1426, 12, - 1432, 0, 26, 0, 0,1315,1823,1484,1466, 0,1483,1829,1433, 13,1437, 14, - 1441,1826,1827,1828,1488,1487,1513, 19, 0, 0,1492,1515,1445,1444,1442, 15, - 0,1831,1832,1833,1502,1501,1516, 25,1497,1498,1506,1518,1457,1456,1454, 17, - 1453,1313, 11, 3, 0, 0,1824,1512,1519, 0,1511,1830,1449, 16,1460, 18, - 1464, 4, 0, 0, 30, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 2, 6, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1834,1835, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1836, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0,1837,1839,1838, 0, 0, 0, 0,1840, 0, 0, 0, 0,1841, 0, 0, - 1842, 0, 0, 0, 0, 0, 0, 0,1843, 0,1844, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,1845, 0, 0,1846, 0, 0,1847, 0,1848, 0, 0, - 0, 0, 0, 0, 937, 0,1850, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0,1849, 936, 938,1851,1852, 0, 0,1853,1854, 0, 0,1855,1856, 0, 0, - 0, 0, 0, 0,1857,1858, 0, 0,1861,1862, 0, 0,1863,1864, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1867,1868,1869,1870,1859,1860,1865,1866, 0, 0, 0, 0, 0, 0,1871,1872, - 1873,1874, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 33, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1875, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1877, 0,1878, 0,1879, 0,1880, 0,1881, 0,1882, 0,1883, 0,1884, 0, - 1885, 0,1886, 0,1887, 0,1888, 0, 0,1889, 0,1890, 0,1891, 0, 0, - 0, 0, 0, 0,1892,1893, 0,1894,1895, 0,1896,1897, 0,1898,1899, 0, - 1900,1901, 0, 0, 0, 0, 0, 0,1876, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1902, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1904, 0,1905, 0,1906, 0,1907, 0,1908, 0,1909, 0,1910, 0,1911, 0, - 1912, 0,1913, 0,1914, 0,1915, 0, 0,1916, 0,1917, 0,1918, 0, 0, - 0, 0, 0, 0,1919,1920, 0,1921,1922, 0,1923,1924, 0,1925,1926, 0, - 1927,1928, 0, 0, 0, 0, 0, 0,1903, 0, 0,1929,1930,1931,1932, 0, - 0, 0,1933, 0, 710, 385, 724, 715, 455, 103, 186, 825, 825, 242, 751, 205, - 241, 336, 524, 601, 663, 676, 688, 738, 411, 434, 474, 500, 649, 746, 799, 108, - 180, 416, 482, 662, 810, 275, 462, 658, 692, 344, 618, 679, 293, 388, 440, 492, - 740, 116, 146, 168, 368, 414, 481, 527, 606, 660, 665, 722, 781, 803, 809, 538, - 553, 588, 642, 758, 811, 701, 233, 299, 573, 612, 487, 540, 714, 779, 232, 267, - 412, 445, 457, 585, 594, 766, 167, 613, 149, 148, 560, 589, 648, 768, 708, 345, - 411, 704, 105, 259, 313, 496, 518, 174, 542, 120, 307, 101, 430, 372, 584, 183, - 228, 529, 650, 697, 424, 732, 428, 349, 632, 355, 517, 110, 135, 147, 403, 580, - 624, 700, 750, 170, 193, 245, 297, 374, 463, 543, 763, 801, 812, 815, 162, 384, - 420, 730, 287, 330, 337, 366, 459, 476, 509, 558, 591, 610, 726, 652, 734, 759, - 154, 163, 198, 473, 683, 697, 292, 311, 353, 423, 572, 494, 113, 217, 259, 280, - 314, 499, 506, 603, 608, 752, 778, 782, 788, 117, 557, 748, 774, 320, 109, 126, - 260, 265, 373, 411, 479, 523, 655, 737, 823, 380, 765, 161, 395, 398, 438, 451, - 502, 516, 537, 583, 791, 136, 340, 769, 122, 273, 446, 727, 305, 322, 400, 496, - 771, 155, 190, 269, 377, 391, 406, 432, 501, 519, 599, 684, 687, 749, 776, 175, - 452, 191, 480, 510, 659, 772, 805, 813, 397, 444, 619, 566, 568, 575, 491, 471, - 707, 111, 636, 156, 153, 288, 346, 578, 256, 435, 383, 729, 680, 767, 694, 295, - 128, 210, 0, 0, 227, 0, 379, 0, 0, 150, 493, 525, 544, 551, 552, 556, - 783, 576, 604, 0, 661, 0, 703, 0, 0, 735, 743, 0, 0, 0, 793, 794, - 795, 808, 741, 773, 118, 127, 130, 166, 169, 177, 207, 213, 215, 226, 229, 268, - 270, 317, 327, 329, 335, 369, 375, 381, 404, 441, 448, 458, 477, 484, 503, 539, - 545, 547, 546, 548, 549, 550, 554, 555, 561, 564, 569, 591, 593, 595, 598, 607, - 620, 625, 625, 651, 690, 695, 705, 706, 716, 717, 733, 735, 777, 786, 790, 315, - 869, 623, 0, 0, 102, 145, 134, 115, 129, 138, 165, 171, 207, 202, 206, 212, - 227, 231, 240, 243, 250, 254, 294, 296, 303, 308, 319, 325, 321, 329, 326, 335, - 341, 357, 360, 362, 370, 379, 388, 389, 393, 421, 424, 438, 456, 454, 458, 465, - 477, 535, 485, 490, 493, 507, 512, 514, 521, 522, 525, 526, 528, 533, 532, 541, - 565, 569, 574, 586, 591, 597, 607, 637, 647, 674, 691, 693, 695, 698, 703, 699, - 705, 704, 702, 706, 709, 717, 728, 736, 747, 754, 770, 777, 783, 784, 786, 787, - 790, 802, 825, 848, 847, 857, 55, 65, 66, 883, 892, 916, 822, 824, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0,1586, 0,1605, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1602,1603, - 1934,1935,1574,1575,1576,1577,1579,1580,1581,1583,1584, 0,1585,1587,1588,1589, - 1591, 0,1592, 0,1593,1594, 0,1595,1596, 0,1598,1599,1600,1601,1604,1582, - 1578,1590,1597, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1936, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,1937, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1938, 0, - 1939, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1940, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1941,1942, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1943, - 1944, 0, 0, 0, 0, 0, 0,1945, 0,1946, 0, 0, 0, 0, 0, 0, - 0, 0,1947, 0, 0,1948, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,1950, 0,1949,1951, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1953, - 1952, 0,1954, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1955,1956, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1957, 0, 0, 0, - 0, 0, 0, 0, 0,1958,1961,1959,1965,1960,1962,1964,1963, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1967,1966,1968, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1969,1970,1971,1972,1973,1974,1975, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1976, - 1977,1978,1980,1979,1981, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 106, 104, 107, 826, 114, 118, 119, 121, 123, 124, 127, 125, - 34, 830, 130, 131, 132, 137, 827, 35, 133, 139, 829, 142, 143, 112, 144, 145, - 924, 151, 152, 37, 157, 158, 159, 160, 38, 165, 166, 169, 171, 172, 173, 174, - 176, 177, 178, 179, 181, 182, 182, 182, 833, 468, 184, 185, 834, 187, 188, 189, - 196, 192, 194, 195, 197, 199, 200, 201, 203, 204, 204, 206, 208, 209, 211, 218, - 213, 219, 214, 216, 153, 234, 221, 222, 223, 220, 225, 224, 230, 835, 235, 236, - 237, 238, 239, 244, 836, 837, 247, 248, 249, 246, 251, 39, 40, 253, 255, 255, - 838, 257, 258, 259, 261, 839, 262, 263, 301, 264, 41, 266, 270, 272, 271, 841, - 274, 842, 277, 276, 278, 281, 282, 42, 283, 284, 285, 286, 43, 843, 44, 289, - 290, 291, 293, 934, 298, 845, 845, 621, 300, 300, 45, 852, 894, 302, 304, 46, - 306, 309, 310, 312, 316, 48, 47, 317, 846, 318, 323, 324, 325, 324, 328, 329, - 333, 331, 332, 334, 335, 336, 338, 339, 342, 343, 347, 351, 849, 350, 348, 352, - 354, 359, 850, 361, 358, 356, 49, 363, 365, 367, 364, 50, 369, 371, 851, 376, - 386, 378, 53, 381, 52, 51, 140, 141, 387, 382, 614, 78, 388, 389, 390, 394, - 392, 856, 54, 399, 396, 402, 404, 858, 405, 401, 407, 55, 408, 409, 410, 413, - 859, 415, 56, 417, 860, 418, 57, 419, 422, 424, 425, 861, 840, 862, 426, 863, - 429, 431, 427, 433, 437, 441, 438, 439, 442, 443, 864, 436, 449, 450, 58, 454, - 453, 865, 447, 460, 866, 867, 461, 466, 465, 464, 59, 467, 470, 469, 472, 828, - 475, 868, 478, 870, 483, 485, 486, 871, 488, 489, 872, 873, 495, 497, 60, 498, - 61, 61, 504, 505, 507, 508, 511, 62, 513, 874, 515, 875, 518, 844, 520, 876, - 877, 878, 63, 64, 528, 880, 879, 881, 882, 530, 531, 531, 533, 66, 534, 67, - 68, 884, 536, 538, 541, 69, 885, 549, 886, 887, 556, 559, 70, 561, 562, 563, - 888, 889, 889, 567, 71, 890, 570, 571, 72, 891, 577, 73, 581, 579, 582, 893, - 587, 74, 590, 592, 596, 75, 895, 896, 76, 897, 600, 898, 602, 605, 607, 899, - 900, 609, 901, 611, 853, 77, 615, 616, 79, 617, 252, 902, 903, 854, 855, 621, - 622, 731, 80, 627, 626, 628, 164, 629, 630, 631, 633, 904, 632, 634, 639, 640, - 635, 641, 646, 651, 638, 643, 644, 645, 905, 907, 906, 81, 653, 654, 656, 911, - 657, 908, 82, 83, 909, 910, 84, 664, 665, 666, 667, 669, 668, 671, 670, 674, - 672, 673, 675, 85, 677, 678, 86, 681, 682, 912, 685, 686, 87, 689, 36, 913, - 914, 88, 89, 696, 702, 709, 711, 915, 712, 713, 718, 719, 917, 831, 721, 720, - 723, 832, 725, 728, 918, 919, 739, 742, 744, 920, 745, 753, 756, 757, 755, 760, - 761, 921, 762, 90, 764, 922, 91, 775, 279, 780, 923, 925, 92, 93, 785, 926, - 94, 927, 787, 787, 789, 928, 792, 95, 796, 797, 798, 800, 96, 929, 802, 804, - 806, 97, 98, 807, 930, 99, 931, 932, 933, 814, 100, 816, 817, 818, 819, 820, - 821, 935, 0, 0, -}; -static const int16_t _hb_ucd_i16[92]= -{ - 0, 0, 1, -1, 2, 0, -2, 0, 0, 2, 0, -2, 0, 16, 0, -16, - 0, 1, -1, 0, 3, 3, 3, -3, -3, -3, 0, 2016, 0, 2527, 1923, 1914, - 1918, 0, 2250, 0, 0, 138, 0, 7, -7, 0, -1, 1, 1824, 0, 2104, 0, - 2108, 2106, 0, 2106, 1316, 0, -1, -138, 8, 8, 8, 0, 7, 7, -8, -8, - -8, -7,-1316, 1, -1, 3, -3, 1, 0,-1914,-1918, 0, 0,-1923,-1824, 0, - 0,-2016,-2104, 0, 0,-2106,-2108,-2106,-2250, 0,-2527, 0, -}; - -static inline uint8_t _hb_ucd_gc (unsigned u) -{ - return u<1114110 ? _hb_ucd_u8[6472u+(((_hb_ucd_u8[816u+(((_hb_ucd_u16[((_hb_ucd_u8[272u+(((_hb_ucd_u8[u>>1>>3>>4>>4])<<4)+((u>>1>>3>>4)&15))])<<4)+((u>>1>>3)&15)])<<3)+((u>>1)&7))])<<1)+((u)&1))] : 2; -} -static inline uint8_t _hb_ucd_ccc (unsigned u) -{ - return u<125259 ? _hb_ucd_u8[8504u+(((_hb_ucd_u8[7936u+(((_hb_ucd_u8[7460u+(((_hb_ucd_u8[7100u+(((_hb_ucd_u8[6854u+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7))])<<2)+((u>>2>>2)&3))])<<2)+((u>>2)&3))])<<2)+((u)&3))] : 0; -} -static inline uint8_t _hb_ucd_b4 (const uint8_t* a, unsigned i) -{ - return (a[i>>1]>>((i&1)<<2))&15; -} -static inline int16_t _hb_ucd_bmg (unsigned u) -{ - return u<65380 ? _hb_ucd_i16[((_hb_ucd_u8[9396u+(((_hb_ucd_u8[9164u+(((_hb_ucd_u8[9068u+(((_hb_ucd_b4(_hb_ucd_u8+9004u,u>>1>>2>>3>>3))<<3)+((u>>1>>2>>3)&7))])<<3)+((u>>1>>2)&7))])<<2)+((u>>1)&3))])<<1)+((u)&1)] : 0; -} -static inline uint8_t _hb_ucd_sc (unsigned u) -{ - return u<918000 ? _hb_ucd_u8[10398u+(((_hb_ucd_u16[3952u+(((_hb_ucd_u16[2624u+(((_hb_ucd_u8[9870u+(((_hb_ucd_u8[9644u+(u>>3>>2>>3>>4)])<<4)+((u>>3>>2>>3)&15))])<<3)+((u>>3>>2)&7))])<<2)+((u>>3)&3))])<<3)+((u)&7))] : 2; -} -static inline uint16_t _hb_ucd_dm (unsigned u) -{ - return u<195102 ? _hb_ucd_u16[6244u+(((_hb_ucd_u8[16628u+(((_hb_ucd_u8[16246u+(u>>4>>5)])<<5)+((u>>4)&31))])<<4)+((u)&15))] : 0; -} - - -#else - -#include - -static const uint8_t _hb_ucd_u8[13730]= -{ - 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 9, 10, 7, 7, 7, 7, 7, 11, 12, 12, 12, 13, - 14, 15, 16, 17, 18, 19, 20, 7, 21, 22, 22, 22, 23, 24, 7, 7, - 7, 25, 22, 22, 22, 26, 27, 28, 22, 29, 30, 31, 32, 33, 34, 35, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 21, 22, 36, - 7, 7, 7, 7, 37, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 38, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 34, 34, 34, 35, 36, 37, 34, 34, 34, 38, 39, 40, 41, - 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 62, 63, 64, 65, 66, 67, 68, 69, 67, 70, 71, - 67, 67, 62, 72, 62, 62, 73, 67, 74, 75, 76, 77, 78, 67, 67, 67, - 79, 80, 34, 81, 82, 83, 67, 67, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 84, 34, 34, 34, 34, - 85, 34, 34, 34, 34, 34, 34, 34, 34, 86, 34, 34, 87, 88, 89, 90, - 91, 92, 93, 94, 95, 96, 97, 98, 34, 34, 34, 34, 34, 34, 34, 34, - 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, - 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, - 100,100, 34, 34, 34, 34,101,102, 34, 34,103,104,105,106,107,108, - 34, 34,109,110,111,112,113,114,115,116,117,118, 34, 34, 34,119, - 120,121,122,123,124,125,126,127, 34,128,129,130,131,132,133,134, - 135,136,137,138,139,140,141,142,143,144,111,145,146,147,148,111, - 149,150,151,152,153,154,155,156,157,158,159,160,111,161,162,163, - 34, 34, 34, 34, 34, 34, 34, 34,164, 34, 34,111,111,111,111,111, - 111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,165, - 34, 34, 34, 34, 34, 34, 34, 34,166, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,111,111,111, - 111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, - 111,111,167,111,111,111,111,111,111,111,111,111,111,111,111,111, - 34, 34, 34, 34,168,169,170, 34,111,111,171,111,172,173,174,175, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,111,111,111,111,111, - 111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,119, - 34, 34, 34, 34, 34, 34,111,111,111,111,111,111,111,111,111,111, - 111,111,111,111,111,111,111,111, 34,176,111,111,111,111,111,111, - 111,111,111,111,111,111,111,111, 67,177, 67, 67, 67, 67,178, 67, - 67, 67,179,180,181,131, 65,111,182,183,184,185,186,187,188,189, - 67, 67, 67, 67,190,191,111,111,111,111,111,111,111,111,192,111, - 193,194,195,111,111,196,111,111,111,197,111,198,111,111,111, 34, - 34,199,200,111,111,111,111,111,131,201,202,111, 34,203,111,111, - 67, 67,204, 67, 67,111, 67,205, 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67,177,111,111,111,111,111,111,111,111, - 34, 34, 34, 34, 34,111,111,111,111,111,111,111,111,111,111,111, - 34, 34, 34, 34, 34, 34, 34, 34,111,111,111,111,111,111,111,111, - 206,111,194,194,111,111,111,111,111,111,111,111,111,111,111,111, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 2, 4, 5, 6, 2, - 7, 7, 7, 7, 7, 2, 8, 9, 10, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 17, 18, 19, 1, 20, 20, 21, 22, 23, 24, 25, - 26, 27, 15, 2, 28, 29, 27, 30, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 31, 11, 11, 11, 32, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 33, 16, 16, 16, 16, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 34, 34, 34, 34, 34, 34, 34, 34, 16, 32, 32, 32, - 32, 32, 32, 32, 11, 34, 34, 16, 34, 32, 32, 11, 34, 11, 16, 11, - 11, 34, 32, 11, 32, 16, 11, 34, 32, 32, 32, 11, 34, 16, 32, 11, - 34, 11, 34, 34, 32, 35, 32, 16, 36, 36, 37, 34, 38, 37, 34, 34, - 34, 34, 34, 34, 34, 34, 16, 32, 34, 38, 32, 11, 32, 32, 32, 32, - 32, 32, 16, 16, 16, 11, 34, 32, 34, 34, 11, 32, 32, 32, 32, 32, - 16, 16, 39, 16, 16, 16, 16, 16, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 41, 41, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, - 40, 40, 42, 41, 41, 41, 42, 42, 41, 41, 41, 41, 41, 41, 41, 41, - 43, 43, 43, 43, 43, 43, 43, 43, 32, 32, 42, 32, 16, 44, 16, 10, - 41, 41, 41, 45, 11, 11, 11, 11, 34, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 34, - 16, 11, 32, 16, 32, 32, 32, 32, 16, 16, 32, 46, 34, 32, 34, 11, - 32, 47, 43, 43, 48, 32, 32, 32, 11, 34, 34, 34, 34, 34, 34, 16, - 11, 11, 11, 11, 49, 2, 2, 2, 16, 16, 16, 16, 50, 51, 52, 53, - 54, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 55, - 56, 57, 43, 56, 43, 43, 43, 43, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 58, 2, 2, 2, 2, 2, 2, 59, 59, 59, 8, 9, 60, 2, 61, - 43, 43, 43, 43, 43, 57, 62, 2, 63, 36, 36, 36, 36, 64, 43, 43, - 7, 7, 7, 7, 7, 2, 2, 36, 65, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 66, 43, 43, 43, 67, 47, 43, 43, 68, 69, 70, 43, 43, 36, - 7, 7, 7, 7, 7, 36, 71, 72, 2, 2, 2, 2, 2, 2, 2, 73, - 64, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, 43, 43, 43, 65, 36, - 36, 36, 36, 43, 43, 43, 43, 43, 7, 7, 7, 7, 7, 36, 36, 36, - 36, 36, 36, 36, 36, 64, 43, 43, 43, 43, 40, 21, 2, 40, 69, 20, - 36, 36, 36, 43, 43, 69, 43, 43, 43, 43, 69, 43, 69, 43, 43, 43, - 2, 2, 2, 2, 2, 2, 2, 2, 36, 36, 36, 36, 64, 43, 43, 2, - 36, 36, 36, 36, 74, 36, 36, 36, 59, 59, 59, 75, 43, 43, 43, 43, - 36, 36, 36, 36, 76, 43, 43, 43, 43, 75, 43, 43, 43, 43, 43, 43, - 43, 77, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 77, 65, 78, - 79, 43, 43, 43, 77, 78, 79, 78, 64, 43, 43, 43, 36, 36, 36, 36, - 36, 43, 2, 7, 7, 7, 7, 7, 80, 36, 36, 36, 36, 36, 36, 36, - 64, 78, 81, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 65, 78, - 79, 43, 43, 77, 78, 78, 79, 36, 36, 36, 36, 82, 78, 78, 36, 36, - 36, 43, 43, 7, 7, 7, 7, 7, 36, 20, 27, 27, 27, 53, 58, 43, - 43, 77, 81, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 43, 78, - 79, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 65, 36, 36, 36, - 36, 36, 36, 7, 7, 7, 7, 7, 43, 36, 64, 2, 2, 2, 2, 2, - 79, 43, 43, 43, 77, 78, 79, 43, 60, 20, 20, 20, 83, 43, 43, 43, - 43, 78, 81, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 65, 79, - 79, 43, 43, 77, 78, 78, 79, 43, 43, 43, 43, 77, 78, 78, 36, 36, - 72, 27, 27, 27, 27, 27, 27, 27, 43, 65, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 78, 77, 78, 78, 78, 78, 78, 79, 43, - 36, 36, 36, 82, 78, 78, 78, 78, 78, 78, 78, 7, 7, 7, 7, 7, - 27, 84, 61, 61, 53, 61, 61, 61, 77, 78, 65, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 65, 43, 77, 78, 78, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 36, 36, 36, 36, 7, 7, 7, 85, 27, 27, 27, 84, - 64, 78, 66, 36, 36, 36, 36, 36, 78, 78, 78, 77, 78, 78, 43, 43, - 43, 43, 77, 78, 78, 78, 81, 36, 86, 82, 78, 78, 78, 78, 78, 78, - 43, 78, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 64, 65, 78, - 79, 43, 43, 78, 78, 78, 79, 71, 61, 61, 36, 82, 27, 27, 27, 87, - 27, 27, 27, 27, 84, 36, 36, 36, 36, 36, 36, 36, 36, 43, 43, 77, - 78, 43, 43, 43, 78, 78, 78, 78, 7, 78, 2, 2, 2, 2, 2, 2, - 64, 36, 43, 43, 43, 43, 43, 88, 36, 36, 36, 69, 43, 43, 43, 57, - 7, 7, 7, 7, 7, 2, 2, 2, 64, 36, 43, 43, 43, 43, 65, 36, - 36, 36, 36, 40, 43, 43, 43, 43, 7, 7, 7, 7, 7, 7, 36, 36, - 71, 61, 2, 2, 2, 2, 2, 2, 2, 89, 89, 61, 43, 61, 61, 61, - 7, 7, 7, 7, 7, 27, 27, 27, 27, 27, 47, 47, 47, 4, 4, 78, - 64, 43, 43, 43, 43, 43, 43, 77, 43, 43, 57, 43, 36, 36, 64, 43, - 43, 43, 43, 43, 43, 43, 43, 61, 61, 61, 61, 70, 61, 61, 61, 61, - 2, 2, 89, 61, 21, 2, 2, 2, 36, 36, 36, 36, 36, 82, 79, 43, - 77, 43, 43, 43, 79, 77, 79, 65, 36, 36, 36, 78, 43, 36, 36, 43, - 65, 78, 81, 82, 78, 78, 78, 36, 64, 43, 65, 36, 36, 36, 36, 36, - 36, 77, 79, 77, 78, 78, 79, 82, 7, 7, 7, 7, 7, 78, 79, 61, - 16, 16, 16, 16, 16, 50, 44, 16, 36, 36, 36, 36, 36, 36, 64, 43, - 2, 2, 2, 2, 90, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 61, 61, 61, 61, 61, 61, 61, 61, 11, 11, 11, 11, 16, 16, 16, 16, - 91, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 71, 66, - 92, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 93, 94, 94, - 36, 36, 36, 36, 36, 58, 2, 95, 96, 36, 36, 36, 36, 36, 36, 36, - 36, 43, 77, 78, 78, 78, 78, 81, 36, 43, 97, 2, 2, 2, 2, 2, - 36, 43, 43, 43, 43, 43, 43, 43, 36, 36, 43, 79, 43, 43, 43, 78, - 78, 78, 78, 77, 79, 43, 43, 43, 43, 43, 2, 80, 2, 60, 64, 43, - 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 98, 2, 56, 43, 75, - 36, 76, 36, 36, 36, 36, 36, 36, 36, 36, 64, 65, 36, 36, 36, 36, - 36, 36, 36, 36, 64, 36, 36, 36, 43, 77, 78, 79, 77, 78, 78, 78, - 78, 77, 78, 78, 79, 43, 43, 43, 61, 61, 2, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 27, 27, 61, 36, 36, 36, 64, 77, 79, 43, 2, - 36, 36, 82, 77, 43, 43, 43, 43, 77, 77, 79, 43, 43, 43, 77, 78, - 78, 79, 43, 43, 43, 43, 43, 43, 2, 2, 2, 80, 2, 2, 2, 2, - 43, 43, 43, 43, 43, 43, 43, 99, 43, 43, 81, 36, 36, 36, 36, 36, - 36, 36, 77, 43, 43, 77, 77, 78, 78, 77, 81, 36, 36, 36, 36, 2, - 89, 61, 61, 61, 61, 47, 43, 43, 43, 43, 61, 61, 61, 61, 21, 2, - 43, 81, 36, 36, 36, 36, 36, 36, 82, 43, 43, 78, 43, 79, 43, 36, - 36, 36, 36, 77, 43, 78, 79, 79, 43, 78, 78, 78, 78, 78, 2, 2, - 36, 36, 78, 78, 78, 78, 43, 43, 43, 43, 78, 43, 43, 57, 2, 2, - 7, 7, 7, 7, 7, 7, 86, 36, 36, 36, 36, 36, 40, 40, 40, 2, - 16, 16, 16, 16, 34, 16, 16, 16, 43, 57, 43, 43, 43, 43, 43, 43, - 77, 43, 43, 43, 65, 36, 64, 36, 36, 36, 65, 82, 43, 36, 36, 36, - 16, 16, 16, 16, 16, 16, 40, 40, 40, 40, 40, 40, 40, 44, 16, 16, - 16, 16, 16, 16, 44, 16, 16, 16, 16, 16, 16, 16, 16,100, 40, 40, - 32, 32, 32, 16, 16, 16, 16, 32, 16, 16, 16, 16, 11, 11, 11, 11, - 16, 16, 16, 16, 34, 11, 11, 11, 16, 16, 16, 16,101,101,101,101, - 16, 16, 16, 16, 11, 11,102,103, 41, 16, 16, 16, 11, 11,102, 41, - 16, 16, 16, 16, 11, 11,104, 41,105,105,105,105,105,106, 59, 59, - 51, 51, 51, 2,107,108,107,108, 2, 2, 2, 2,109, 59, 59,110, - 2, 2, 2, 2,111,112, 2,113,114, 2,115,116, 2, 2, 2, 2, - 2, 9,114, 2, 2, 2, 2,117, 59, 59, 59, 59, 59, 59, 59, 59, - 118, 40, 27, 27, 27, 8,115,119, 27, 27, 27, 27, 27, 8,115, 94, - 20, 20, 20, 20, 20, 20, 20, 20, 43, 43, 43, 43, 43, 43,120, 48, - 99, 48, 99, 43, 43, 43, 43, 43, 61,121, 61,122, 61, 34, 11, 16, - 11, 32,122, 61, 46, 11, 11, 61, 61, 61,121,121,121, 11, 11,123, - 11, 11, 35, 36, 39, 61, 16, 11, 8, 8, 46, 16, 16, 26, 61,124, - 95, 95, 95, 95, 95, 95, 95, 95, 95,125,126, 95,127, 61, 61, 61, - 8, 8,128, 61, 61, 8, 61, 61,128, 26, 61,128, 61, 61, 61,128, - 61, 61, 61, 61, 61, 61, 61, 8, 61,128,128, 61, 61, 61, 61, 61, - 61, 61, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 61, 61, 61, 61, 4, 4, 61, 61, 8, 61, 61, 61,129,130, 61, 61, - 61, 61, 61, 61, 61, 61,128, 61, 61, 61, 61, 61, 61, 26, 8, 8, - 8, 8, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 8, 8, - 8, 61, 61, 61, 61, 61, 61, 61, 27, 27, 27, 27, 27, 27, 61, 61, - 61, 61, 61, 61, 61, 27, 27, 27, 61, 61, 61, 26, 61, 61, 61, 61, - 26, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 8, 8, 8, 8, - 61, 61, 61, 61, 61, 61, 61, 26, 61, 61, 61, 61, 4, 4, 4, 4, - 4, 4, 4, 27, 27, 27, 27, 27, 27, 27, 61, 61, 61, 61, 61, 61, - 8, 8,115,131, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, - 8,115,132,132,132,132,132,132,132,132,132,132,131, 8, 8, 8, - 8, 8, 8, 8, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 4, 8, - 8, 8,128, 26, 8, 8,128, 61, 32, 11, 32, 34, 34, 34, 34, 11, - 32, 32, 34, 16, 16, 16, 40, 11, 32, 32,124, 61, 61,122, 34,133, - 43, 32, 16, 16, 50, 2, 90, 2, 36, 36, 36, 36, 36, 36, 36, 76, - 2, 2, 2, 2, 2, 2, 2, 56, 2,107,107, 2,111,112,107, 2, - 2, 2, 2, 6, 2, 98,107, 2,107, 4, 4, 4, 4, 2, 2, 80, - 2, 2, 2, 2, 2, 51, 2, 2, 98,134, 2, 2, 2, 2, 2, 2, - 61, 2,135,132,132,132,136, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 1, 2,137,138, 4, 4, 4, 4, 4, 61, 4, 4, 4, 4,139, 94, - 140, 95, 95, 95, 95, 43, 43, 78,141, 40, 40, 61, 95,142, 58, 61, - 72, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 64,143,144, 63, - 36, 36, 36, 36, 36, 58, 40, 63, 61, 27, 27, 61, 61, 61, 61, 61, - 27, 27, 27, 27, 27, 61, 61, 61, 61, 61, 61, 61, 27, 27, 27, 27, - 145, 27, 27, 27, 27, 27, 27, 27, 36, 36, 76, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36,146, 2, 32, 32, 32, 32, 32, 32, 32, 64, - 48,147, 43, 43, 43, 43, 43, 80, 32, 32, 32, 32, 32, 32, 40, 43, - 36, 36, 36, 95, 95, 95, 95, 95, 43, 2, 2, 2, 2, 2, 2, 2, - 41, 41, 41,144, 40, 40, 40, 40, 41, 32, 32, 32, 32, 32, 32, 32, - 16, 32, 32, 32, 32, 32, 32, 32, 44, 16, 16, 16, 34, 34, 34, 32, - 32, 32, 32, 32, 42,148, 34, 35, 32, 32, 16, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 11, 11, 32, 11, 11, 32, 32, 32, 32, 32, 32, - 32, 32, 11, 11, 34, 34, 32, 16, 32, 16, 16, 32, 32, 32, 11, 11, - 11, 40,149, 35, 40, 35, 36, 36, 36, 65, 36, 65, 36, 64, 36, 36, - 36, 82, 79, 77, 61, 61, 43, 43, 27, 27, 27, 61,150, 61, 61, 61, - 36, 36, 2, 2, 2, 2, 2, 2, 78, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 78, 78, 78, 78, 78, 78, 78, 78, 43, 43, 43, 43, 43, 2, - 43, 36, 36, 36, 2, 66, 66, 64, 36, 36, 36, 43, 43, 43, 43, 2, - 36, 36, 36, 64, 43, 43, 43, 43, 43, 78, 78, 78, 78, 78, 78, 97, - 36, 64, 78, 43, 43, 78, 43, 78, 97, 2, 2, 2, 2, 2, 2, 80, - 7, 7, 7, 7, 7, 7, 7, 2, 36, 36, 64, 63, 36, 36, 36, 36, - 36, 36, 36, 36, 64, 43, 43, 77, 79, 77, 79, 43, 43, 43, 43, 43, - 36, 64, 36, 36, 36, 36, 77, 78, 7, 7, 7, 7, 7, 7, 2, 2, - 63, 36, 36, 71, 61, 82, 77, 36, 65, 43, 65, 64, 65, 36, 36, 43, - 36, 36, 36, 36, 36, 36, 76, 2, 36, 36, 36, 36, 36, 82, 43, 78, - 2, 76,151, 43, 43, 43, 43, 43, 16, 16, 16, 16, 16,103, 40, 40, - 16, 16, 16, 16,100, 41, 41, 41, 36, 82, 79, 78, 77, 97, 79, 43, - 152,152,152,152,152,152,152,152,153,153,153,153,153,153,153,153, - 16, 16, 16, 16, 16, 16, 35, 65, 36, 36, 36, 36,154, 36, 36, 36, - 36, 41, 41, 41, 41, 41, 41, 41, 41, 74, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36,132, 36, 36, 36, 36, 36, 36, 36, 71, - 36, 36, 36, 36, 36, 36,150, 61, 2, 2, 2,135,116, 2, 2, 2, - 6,155,156,132,132,132,132,132,132,132,116,135,116, 2,113,157, - 2, 2, 2, 2,139,132,132,116, 2,158, 8, 8, 60, 2, 2, 2, - 36, 36, 36, 36, 36, 36, 36,159, 2, 2, 3, 2, 4, 5, 6, 2, - 16, 16, 16, 16, 16, 17, 18,115,116, 4, 2, 36, 36, 36, 36, 36, - 63, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 40, - 20,160, 53, 20, 26, 8,128, 61, 61, 61, 61, 61,161, 59, 61, 61, - 2, 2, 2, 90, 27, 27, 27, 27, 27, 27, 27, 84, 61, 61, 61, 61, - 95, 95,127, 27, 84, 61, 61, 61, 61, 61, 61, 61, 61, 27, 61, 61, - 61, 61, 61, 61, 61, 61, 47, 43,162,162,162,162,162,162,162,162, - 163, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 87, 36, - 138, 36, 36, 36, 36, 95, 95, 95, 36, 36, 36, 36, 36, 36, 36, 58, - 164, 95, 95, 95, 95, 95, 95, 95, 11, 11, 11, 32, 16, 16, 16, 16, - 36, 36, 36, 58, 27, 27, 27, 27, 36, 36, 36, 71,145, 27, 27, 27, - 36, 36, 36,165, 27, 27, 27, 27, 36, 36, 36, 36, 36,165, 27, 27, - 36, 36, 36, 27, 27, 27, 27, 30, 36, 36, 36, 36, 36, 36, 27, 36, - 64, 43, 43, 43, 43, 43, 43, 43, 36, 36, 36, 36, 43, 43, 43, 43, - 36, 36, 36, 36, 36, 36,165, 30, 36, 36, 36, 36, 36, 36,165, 27, - 36, 36, 36, 36, 72, 36, 36, 36, 36, 36, 64, 43, 43,163, 27, 27, - 36, 36, 36, 36, 58, 2, 2, 2, 36, 36, 36, 36, 27, 27, 27, 27, - 16, 16, 16, 16, 16, 27, 27, 27, 36, 36, 43, 43, 43, 43, 43, 43, - 7, 7, 7, 7, 7, 36, 36, 63, 11, 11, 11, 11,166, 43, 43,141, - 16, 16, 16, 16, 16, 16, 16, 8, 36, 36, 36, 36, 36, 64,167, 51, - 36, 36, 36, 36, 36, 36, 43, 43, 27, 27, 27, 87, 36, 36, 36, 36, - 163, 27, 30, 2, 2, 2, 2, 2, 36, 43, 43, 2, 2, 2, 2, 2, - 36, 36,165, 27, 27, 27, 27, 27, 79, 81, 36, 36, 36, 36, 36, 36, - 43, 43, 43, 57, 2, 2, 2, 2, 2, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 7, 7, 7, 7, 7, 65, 64, 65, 36, 36, 36, 36, 64, - 78, 79, 43, 77, 79, 57, 73, 2, 2, 43, 43, 43, 43, 43, 67, 59, - 36, 36, 36, 64, 43, 43, 79, 43, 43, 43, 43, 7, 7, 7, 7, 7, - 2, 2, 82, 81, 36, 36, 36, 36, 36, 64, 2, 36, 36, 36, 36, 36, - 36, 82, 78, 43, 43, 43, 43, 77, 81, 36, 58, 2, 56, 43, 57, 79, - 7, 7, 7, 7, 7, 58, 58, 2, 90, 27, 27, 27, 27, 27, 27, 27, - 36, 36, 36, 36, 36, 36, 78, 79, 43, 78, 77, 43, 2, 2, 2, 65, - 36, 36, 36, 36, 36, 36, 36, 64, 77, 78, 78, 78, 78, 78, 78, 78, - 36, 36, 36, 82, 78, 78, 81, 36, 36, 78, 78, 43, 43, 43, 43, 43, - 36, 36, 36, 36, 78, 79, 43, 43, 43, 78, 78, 78, 78, 78, 78, 77, - 65, 65, 2, 2, 2, 2, 2, 2, 56, 43, 43, 43, 43, 43, 43, 43, - 36, 36, 82, 78, 43, 43, 43, 43, 78, 43, 77, 65, 36, 58, 2, 2, - 7, 7, 7, 7, 7, 2, 2, 65, 78, 79, 43, 43, 77, 77, 78, 79, - 77, 43, 36, 66, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 82, - 78, 43, 43, 43, 78, 78, 43, 79, 57, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 36, 36, 43, 43, 78, 79, 43, 43, 43, 77, 79, 79, - 57, 2, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 64, 79, 78, - 43, 43, 43, 79, 58, 2, 2, 2, 36, 36, 36, 36, 36, 36, 64, 79, - 78, 43, 43, 79, 43, 43, 43, 43, 7, 7, 7, 7, 7, 27, 2, 89, - 43, 43, 43, 43, 79, 57, 2, 2, 27, 27, 27, 27, 27, 27, 27, 87, - 78, 78, 78, 78, 78, 79, 77, 65, 81, 79, 2, 2, 2, 2, 2, 2, - 82, 78, 43, 43, 43, 43, 78, 78, 65, 66, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, 64, 43, 43, 43, 43, 65, 36, 36, - 36, 64, 43, 43, 77, 64, 43, 57, 2, 2, 2, 56, 43, 43, 43, 43, - 64, 43, 43, 77, 79, 43, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, - 43, 43, 43, 77, 43, 2, 66, 2, 58, 2, 2, 2, 2, 2, 2, 2, - 43, 43, 43, 43, 43, 43, 43, 79, 2, 36, 36, 36, 36, 36, 36, 36, - 43, 43, 43, 43, 77, 43, 43, 43, 77, 43, 79, 43, 43, 43, 43, 43, - 43, 43, 43, 64, 43, 43, 43, 43, 36, 36, 36, 36, 36, 78, 78, 78, - 43, 77, 79, 79, 36, 36, 36, 36, 36, 64, 77, 97, 2, 2, 2, 2, - 43, 82, 36, 36, 36, 36, 36, 36, 36, 36, 78, 43, 43, 43, 43, 78, - 77, 57, 2, 2, 2, 2, 2, 2, 7, 7, 7, 7, 7, 43, 43, 43, - 27, 27, 84, 61, 61, 61, 53, 20,150, 61, 61, 61, 61, 61, 61, 61, - 61, 61, 61, 61, 61, 61, 61, 21, 65, 36, 36, 64, 43, 43, 43, 43, - 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, 43, 43, 43, 78, 79, 43, - 43, 43, 57, 2, 2, 2, 2, 2, 43, 43, 43, 57, 2, 2, 61, 61, - 40, 40, 89, 61, 61, 61, 61, 61, 7, 7, 7, 7, 7,168, 27, 27, - 27, 87, 36, 36, 36, 36, 36, 36, 40, 63, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 76,146, 2, 27, 27, 27, 30, 2, 2, 2, 2, - 82, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 79, - 43, 68, 40, 40, 40, 40, 40, 40, 40, 80, 43, 43, 43, 43, 43, 43, - 36, 36, 36, 36, 36, 36, 47, 57, 61, 61,169, 79, 43, 61,169, 78, - 78,170, 59, 59, 59, 75, 43, 43, 43, 70, 47, 43, 43, 43, 61, 61, - 61, 61, 61, 61, 61, 43, 43, 61, 61, 43, 70, 61, 61, 61, 61, 61, - 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 16, 11, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, - 31, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 33, 16, 16, - 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 31, 16, 16, - 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 31, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, - 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, 32, 16, 7, - 43, 43, 43, 70, 61, 47, 43, 43, 43, 43, 43, 43, 43, 43, 70, 61, - 61, 61, 47, 61, 61, 61, 61, 61, 61, 61, 70, 21, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 56, 43, 43, 16, 16, 16, 16, 16, 39, 16, 16, - 43, 43, 43, 68, 40, 40, 40, 40, 7, 7, 7, 7, 7, 7, 7, 71, - 7, 7, 7, 7, 7, 7, 7,171, 36, 36, 36, 36, 36, 76, 43, 43, - 172, 7, 7, 7, 7, 7, 7, 85, 16, 16, 43, 43, 43, 68, 40, 40, - 27, 27, 27, 27, 27, 27,145, 27,173, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27,145, 27, 27, 27, 27, 27, 27, 84, 61, - 61, 61, 61, 61, 61, 25, 41, 41, 0, 0, 29, 21, 21, 21, 23, 21, - 22, 18, 21, 25, 21, 17, 13, 13, 25, 25, 25, 21, 21, 9, 9, 9, - 9, 22, 21, 18, 24, 16, 24, 5, 5, 5, 5, 22, 25, 18, 25, 0, - 23, 23, 26, 21, 24, 26, 7, 20, 25, 1, 26, 24, 26, 25, 15, 15, - 24, 15, 7, 19, 15, 21, 9, 25, 9, 5, 5, 25, 5, 9, 5, 7, - 7, 7, 9, 8, 8, 5, 7, 5, 6, 6, 24, 24, 6, 24, 12, 12, - 6, 5, 9, 21, 25, 9, 26, 12, 11, 11, 9, 6, 5, 21, 17, 17, - 17, 26, 26, 23, 23, 12, 17, 12, 21, 12, 12, 21, 7, 21, 1, 1, - 21, 23, 26, 26, 1, 21, 6, 7, 7, 12, 12, 7, 21, 7, 12, 1, - 12, 6, 6, 12, 12, 26, 7, 26, 26, 7, 21, 1, 24, 7, 1, 12, - 7, 6, 12, 10, 10, 10, 10, 12, 21, 6, 10, 7, 7, 10, 23, 7, - 15, 26, 13, 21, 13, 7, 15, 7, 12, 23, 21, 26, 21, 15, 17, 7, - 29, 7, 7, 22, 18, 18, 14, 14, 14, 7, 10, 21, 17, 21, 11, 12, - 5, 6, 8, 8, 8, 24, 5, 24, 9, 24, 29, 29, 29, 1, 20, 19, - 22, 20, 27, 28, 1, 29, 21, 20, 19, 21, 21, 16, 16, 21, 25, 22, - 18, 21, 21, 29, 15, 6, 18, 6, 12, 11, 9, 26, 26, 9, 26, 5, - 5, 26, 14, 9, 5, 14, 14, 15, 25, 26, 26, 22, 18, 26, 18, 25, - 18, 22, 5, 12, 22, 21, 21, 22, 18, 17, 26, 6, 7, 14, 17, 22, - 26, 14, 17, 6, 14, 6, 12, 24, 24, 6, 26, 15, 6, 21, 11, 21, - 24, 9, 6, 9, 23, 26, 6, 10, 4, 4, 3, 3, 7, 25, 17, 16, - 16, 22, 16, 16, 25, 17, 7, 1, 25, 24, 26, 1, 2, 2, 12, 15, - 21, 14, 7, 15, 9, 12, 12, 17, 13, 15, 26, 10, 10, 1, 13, 23, - 7, 13, 23, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 10, - 11, 12, 13, 0, 14, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 17, 18, 19, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 20, 0, 21, 22, 23, 0, 0, 0, 24, 25, 26, 27, 28, 29, 30, - 31, 32, 33, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 35, 0, 0, 0, 0, 36, 0, 37, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 40, 0, 0, - 0, 0, 0, 0, 41, 42, 43, 0, 44, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 3, 0, 0, 0, - 4, 5, 6, 7, 0, 8, 9, 10, 0, 11, 12, 13, 14, 15, 16, 17, - 16, 18, 16, 19, 16, 19, 16, 19, 0, 19, 16, 20, 16, 19, 21, 19, - 0, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 0, 32, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 34, 0, - 0, 35, 0, 0, 36, 0, 37, 0, 0, 0, 38, 39, 40, 41, 42, 43, - 44, 45, 46, 0, 0, 47, 0, 0, 0, 48, 0, 0, 0, 49, 0, 0, - 0, 0, 0, 0, 0, 50, 0, 51, 0, 52, 53, 0, 54, 0, 0, 0, - 0, 0, 0, 55, 56, 57, 0, 0, 0, 0, 58, 0, 0, 59, 60, 61, - 62, 63, 0, 0, 64, 65, 0, 0, 0, 66, 0, 0, 0, 0, 67, 0, - 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 69, 0, 0, 0, 70, 0, 71, 0, 0, 72, 0, 0, 73, 0, 0, - 0, 0, 0, 0, 0, 0, 74, 75, 0, 0, 0, 0, 76, 77, 0, 78, - 79, 0, 0, 80, 81, 0, 82, 62, 0, 83, 84, 0, 0, 85, 86, 87, - 0, 88, 0, 89, 0, 90, 0, 0, 51, 91, 51, 0, 92, 0, 93, 0, - 0, 0, 81, 0, 0, 0, 94, 95, 0, 96, 97, 98, 99, 0, 0, 0, - 0, 0, 51, 0, 0, 0, 0,100,101, 0, 0, 0, 0, 0, 0,102, - 0, 0, 0, 0, 0, 0,103, 0, 0, 0, 0, 0, 0,104,105, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,106, 0, 0,107, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,108,109, 0, 0,110, 0, 0, 0, 0, - 0, 0,111, 0,112, 0,105, 0, 0, 0, 0, 0,113,114, 0, 0, - 0, 0, 0, 0, 0,115, 0, 0, 0,116, 0, 0, 0,117, 0,118, - 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 0, 8, 0, - 0, 0, 0, 9, 10, 11, 12, 0, 0, 0, 0, 13, 0, 0, 14, 15, - 0, 16, 0, 17, 18, 0, 0, 19, 0, 20, 21, 0, 0, 0, 0, 0, - 22, 23, 0, 24, 25, 0, 0, 26, 0, 0, 0, 27, 0, 0, 28, 29, - 30, 31, 0, 0, 0, 32, 33, 34, 0, 0, 33, 0, 0, 35, 33, 0, - 0, 0, 33, 36, 0, 0, 0, 0, 0, 37, 38, 0, 0, 0, 0, 0, - 0, 39, 40, 0, 0, 0, 0, 0, 0, 41, 42, 0, 0, 0, 0, 43, - 0, 44, 0, 0, 0, 45, 46, 0, 0, 0, 47, 0, 0, 0, 0, 0, - 0, 48, 49, 0, 0, 0, 0, 50, 0, 0, 0, 51, 0, 52, 0, 53, - 0, 0, 0, 0, 54, 0, 0, 0, 0, 55, 0, 56, 0, 0, 0, 0, - 57, 58, 0, 0, 0, 59, 60, 0, 0, 0, 0, 0, 0, 61, 52, 0, - 62, 63, 0, 0, 64, 0, 0, 0, 65, 66, 0, 0, 0, 67, 0, 68, - 69, 70, 71, 72, 1, 73, 0, 74, 75, 76, 0, 0, 77, 78, 0, 0, - 0, 79, 0, 0, 1, 1, 0, 0, 80, 0, 0, 81, 0, 0, 0, 0, - 77, 82, 0, 83, 0, 0, 0, 0, 0, 78, 84, 0, 85, 0, 52, 0, - 1, 78, 0, 0, 86, 0, 0, 87, 0, 0, 0, 0, 0, 88, 57, 0, - 0, 0, 0, 0, 0, 89, 90, 0, 0, 84, 0, 0, 33, 0, 0, 91, - 0, 0, 0, 0, 92, 0, 0, 0, 0, 49, 0, 0, 93, 0, 0, 0, - 0, 94, 95, 0, 0, 96, 0, 0, 97, 0, 0, 0, 98, 0, 0, 0, - 99, 0, 0, 0,100, 0, 0, 0, 0,101,102, 93, 0, 0,103, 0, - 0, 0, 84, 0, 0,104, 0, 0, 0,105,106, 0, 0,107,108, 0, - 0, 0, 0, 0, 0,109, 0, 0,110, 0, 0, 0, 0,111, 33, 0, - 112,113,114, 57, 0, 0,115, 35, 0, 0,116, 0, 0, 0,117, 0, - 0, 0, 0, 0, 0,118, 0, 0,119, 0, 0, 0, 0,120, 88, 0, - 0, 0, 0, 0, 57, 0, 0, 0, 0, 52,121, 0, 0, 0, 0,122, - 0, 0,123, 0, 0, 0, 0,121, 0, 0,124, 0, 0, 0, 0, 0, - 79, 0, 0, 0, 0,125, 0, 0, 0,126, 0, 0, 0,127, 0,128, - 0, 0, 0, 0,129,130,131, 0,132, 0,133, 0, 0, 0,134,135, - 136, 0, 77, 0, 0, 0, 0, 0, 35, 0, 0, 0,137, 0, 0, 0, - 138, 0, 0, 0,139, 0, 0,140, 0, 0,141, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 7, 4, 4, 8, - 9, 10, 1, 11, 12, 13, 14, 15, 16, 17, 18, 1, 1, 1, 19, 1, - 0, 0, 20, 21, 22, 1, 23, 4, 21, 24, 25, 26, 27, 28, 29, 30, - 0, 0, 1, 1, 31, 0, 0, 0, 32, 33, 34, 35, 1, 36, 37, 0, - 0, 0, 0, 38, 1, 39, 14, 39, 40, 41, 42, 0, 0, 0, 43, 36, - 44, 45, 21, 45, 46, 0, 0, 0, 19, 1, 21, 0, 0, 47, 0, 38, - 48, 1, 1, 49, 49, 50, 0, 0, 51, 0, 0, 19, 52, 1, 0, 0, - 38, 14, 4, 1, 1, 1, 53, 21, 43, 52, 54, 21, 35, 1, 0, 0, - 0, 55, 0, 0, 0, 56, 57, 58, 0, 0, 0, 0, 0, 59, 0, 60, - 0, 0, 0, 0, 61, 62, 0, 0, 63, 0, 0, 0, 64, 0, 0, 0, - 65, 0, 0, 0, 66, 0, 0, 0, 67, 0, 0, 0, 68, 0, 0, 69, - 70, 0, 71, 72, 73, 74, 75, 76, 0, 0, 0, 77, 0, 0, 0, 78, - 79, 0, 0, 0, 0, 47, 0, 0, 0, 49, 0, 80, 0, 0, 0, 62, - 0, 0, 63, 0, 0, 81, 0, 0, 82, 0, 0, 0, 83, 0, 0, 19, - 84, 0, 62, 0, 0, 0, 0, 49, 1, 85, 1, 52, 15, 86, 36, 10, - 21, 87, 0, 55, 0, 0, 0, 0, 19, 10, 1, 0, 0, 0, 0, 0, - 88, 0, 0, 89, 0, 0, 88, 0, 0, 0, 0, 78, 0, 0, 87, 9, - 12, 4, 90, 8, 91, 47, 0, 58, 50, 0, 21, 1, 21, 92, 93, 1, - 1, 1, 1, 94, 95, 96, 97, 1, 98, 58, 81, 99,100, 4, 58, 0, - 0, 0, 0, 0, 0, 19, 50, 0, 0, 0, 0, 0, 0, 61, 0, 0, - 101,102, 0, 0,103, 0, 0, 1, 1, 50, 0, 0, 0, 38, 0, 63, - 0, 0, 0, 0, 0, 62, 0, 0,104, 68, 61, 0, 0, 0, 78, 0, - 0, 0,105,106, 58, 38, 81, 0, 0, 0, 0, 0, 0,107, 1, 14, - 4, 12, 84, 0, 0, 0, 0, 38, 87, 0, 0, 0, 0,108, 0, 0, - 109, 61, 0,110, 0, 0, 0, 1, 0, 0, 0, 0, 49, 50, 0, 0, - 19, 58, 0, 0, 0, 51, 0,111, 14, 52,112, 41, 0, 0, 62, 0, - 0, 61, 0, 0,113, 0, 87, 0, 0, 0, 61, 62, 0, 0, 62, 0, - 89, 0, 0,113, 0, 0, 0, 0,114, 0, 0, 0, 78, 55, 0, 38, - 1, 58, 1, 58, 0, 0, 0, 0, 0, 88, 63, 89, 0, 0,115, 0, - 0, 0, 55, 0, 0, 0, 0,115, 0, 0, 0, 0, 61, 0, 0, 0, - 0, 79, 0, 61, 0, 0, 0, 0, 56, 0, 89, 80, 0, 0, 79, 0, - 0, 0, 8, 91, 0, 0, 1, 87, 0, 0,116, 0, 0, 0, 0, 0, - 0,117, 0,118,119,120,121, 0,104, 4,122, 49, 23, 0, 0, 0, - 38, 50, 38, 58, 0, 0, 1, 87, 1, 1, 1, 1, 39, 1, 48,105, - 87, 0, 0, 0, 0, 1, 0, 0, 0,123, 0, 0, 0,112, 4,122, - 0, 0, 0, 1,124, 0, 0, 0, 0, 0,230,230,230,230,230,232, - 220,220,220,220,232,216,220,220,220,220,220,202,202,220,220,220, - 220,202,202,220,220,220, 1, 1, 1, 1, 1,220,220,220,220,230, - 230,230,230,240,230,220,220,220,230,230,230,220,220, 0,230,230, - 230,220,220,220,220,230,232,220,220,230,233,234,234,233,234,234, - 233,230, 0, 0, 0,230, 0,220,230,230,230,230,220,230,230,230, - 222,220,230,230,220,220,230,222,228,230, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 19, 20, 21, 22, 0, 23, 0, 24, 25, 0,230,220, - 0, 18, 30, 31, 32, 0, 0, 0, 0, 27, 28, 29, 30, 31, 32, 33, - 34,230,230,220,220,230,220,230,230,220, 35, 0, 0, 0, 0, 0, - 230,230,230, 0, 0,230,230, 0,220,230,230,220, 0, 0, 0, 36, - 0, 0,230,220,230,230,220,220,230,220,220,230,220,230,220,230, - 230, 0, 0,220, 0, 0,230,230, 0,230, 0,230,230,230,230,230, - 0, 0, 0,220,220,220,230,220,220,220,230,230, 0,220, 27, 28, - 29,230, 7, 0, 0, 0, 0, 9, 0, 0, 0,230,220,230,230, 0, - 0, 0, 0, 0,230, 0, 0, 84, 91, 0, 0, 0, 0, 9, 9, 0, - 0, 0, 0, 0, 9, 0,103,103, 9, 0,107,107,107,107,118,118, - 9, 0,122,122,122,122,220,220, 0, 0, 0,220, 0,220, 0,216, - 0, 0, 0,129,130, 0,132, 0, 0, 0, 0, 0,130,130,130,130, - 0, 0,130, 0,230,230, 9, 0,230,230, 0, 0,220, 0, 0, 0, - 0, 7, 0, 9, 9, 0, 9, 9, 0, 0, 0,230, 0, 0, 0,228, - 0, 0, 0,222,230,220,220, 0, 0, 0,230, 0, 0,220,230,220, - 0,220,230,230,230, 0, 0, 0, 9, 9, 0, 0, 7, 0,230, 0, - 1, 1, 1, 0, 0, 0,230,234,214,220,202,230,230,230,230,230, - 232,228,228,220,218,230,233,220,230,220,230,230, 1, 1, 1, 1, - 1,230, 0, 1, 1,230,220,230, 1, 1, 0, 0,218,228,232,222, - 224,224, 0, 8, 8, 0, 0, 0, 0,220,230, 0,230,230,220, 0, - 0,230, 0, 0, 26, 0, 0,220, 0,230,230, 1,220, 0, 0,230, - 220, 0, 0, 0,220,220, 0, 0,230,220, 0, 9, 7, 0, 0, 7, - 9, 0, 0, 0, 9, 7, 6, 6, 0, 0, 0, 0, 1, 0, 0,216, - 216, 1, 1, 1, 0, 0, 0,226,216,216,216,216,216, 0,220,220, - 220, 0,232,232,220,230,230,230, 7, 0, 16, 17, 17, 33, 17, 49, - 17, 17, 84, 97,135,145, 26, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17,177, 0, 1, 2, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, - 3, 3, 3, 3, 5, 3, 3, 3, 3, 3, 6, 7, 8, 3, 3, 3, - 3, 3, 9, 10, 11, 12, 13, 3, 3, 3, 3, 3, 3, 3, 3, 14, - 3, 15, 3, 3, 3, 3, 3, 3, 16, 17, 18, 19, 20, 21, 3, 3, - 3, 22, 23, 24, 3, 3, 3, 3, 3, 3, 25, 3, 3, 3, 3, 3, - 3, 3, 3, 26, 3, 3, 27, 28, 0, 1, 0, 0, 0, 0, 0, 1, - 0, 2, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 4, - 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 6, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 8, 9, 0, 0, 0, 0, 0, 0, 9, 0, 9, 0, 0, 0, 0, - 0, 0, 0, 10, 11, 12, 13, 0, 0, 14, 15, 16, 6, 0, 17, 18, - 19, 19, 19, 20, 21, 22, 23, 24, 19, 25, 0, 26, 27, 19, 19, 28, - 29, 30, 0, 31, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 19, - 28, 0, 32, 33, 9, 34, 35, 19, 0, 0, 36, 37, 38, 39, 40, 19, - 0, 41, 42, 43, 44, 31, 0, 1, 45, 42, 0, 0, 0, 0, 0, 32, - 14, 14, 0, 0, 0, 0, 14, 0, 0, 46, 47, 47, 47, 47, 48, 49, - 47, 47, 47, 47, 50, 51, 52, 53, 43, 21, 0, 0, 0, 0, 0, 0, - 0, 54, 6, 55, 0, 14, 19, 1, 0, 0, 0, 0, 56, 57, 0, 0, - 0, 0, 0, 19, 58, 31, 0, 0, 0, 0, 0, 0, 0, 59, 14, 0, - 0, 0, 0, 1, 0, 2, 0, 0, 0, 3, 0, 0, 0, 60, 61, 0, - 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 3, 0, 4, - 5, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 1, 1, 0, 0, 8, - 9, 0, 8, 9, 0, 0, 0, 0, 8, 9, 10, 11, 12, 0, 0, 0, - 13, 0, 0, 0, 0, 14, 15, 16, 17, 0, 0, 0, 1, 0, 0, 18, - 19, 0, 0, 0, 20, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, - 1, 1, 1, 1, 0, 8, 21, 9, 0, 0, 22, 0, 0, 0, 0, 1, - 0, 23, 24, 25, 0, 0, 26, 0, 0, 0, 8, 21, 27, 0, 1, 0, - 0, 1, 1, 1, 1, 0, 1, 28, 29, 30, 0, 31, 32, 20, 1, 1, - 0, 0, 0, 8, 21, 9, 1, 4, 5, 0, 0, 0, 33, 9, 0, 1, - 1, 1, 0, 8, 21, 21, 21, 21, 34, 1, 35, 21, 21, 21, 9, 36, - 0, 0, 37, 38, 1, 0, 39, 0, 0, 0, 1, 0, 1, 0, 0, 0, - 0, 8, 21, 9, 1, 0, 0, 0, 40, 0, 8, 21, 21, 21, 21, 21, - 21, 21, 21, 9, 0, 1, 1, 1, 1, 8, 21, 21, 21, 9, 0, 0, - 0, 41, 0, 42, 43, 0, 0, 0, 1, 44, 0, 0, 0, 45, 8, 9, - 1, 0, 0, 0, 8, 21, 21, 21, 9, 0, 1, 0, 1, 1, 8, 21, - 21, 9, 0, 4, 5, 8, 9, 1, 0, 0, 0, 1, 2, 3, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 3, 3, 3, 3, 3, 3, - 3, 15, 3, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 18, 0, 0, 1, 2, 3, - 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 17, 17, - 18, 17, 19, 20, 21, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 24, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 25, 25, 26, 27, - 28, 29, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 52, 53, 31, - 31, 31, 31, 54, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 56, 57, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 58, 31, 31, 31, - 59, 60, 61, 62, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, - 63, 64, 65, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 66, 67, 68, 31, 31, 31, 31, 69, 31, 31, 31, 31, 31, - 31, 31, 17, 70, 71, 72, 17, 17, 73, 74, 31, 75, 76, 77, 78, 79, - 80, 31, 81, 82, 17, 83, 17, 17, 17, 17, 31, 31, 23, 23, 23, 23, - 23, 23, 23, 84, 31, 31, 31, 31, 23, 84, 31, 31, 23, 23, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 85, 0, 0, 1, - 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, - 4, 4, 4, 4, 4, 4, 5, 6, 7, 8, 9, 10, 11, 11, 12, 11, - 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 19, 27, - 28, 29, 30, 30, 31, 31, 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, - 37, 37, 38, 38, 39, 40, 41, 41, 42, 42, 42, 43, 44, 44, 45, 46, - 47, 47, 47, 47, 48, 48, 48, 48, 48, 48, 49, 50, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59, 51, - 60, 61, 62, 63, 64, 65, 66, 7, 67, 67, 68, 69, 70, 71, 72, 73, - 74, 75, 76, 7, 4, 4, 4, 4, 77, 77, 77, 77, 78, 79, 80, 81, - 82, 83, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 85, 85, 85, - 0, 0, 0, 0, 86, 87, 88, 88, 89, 90, 48, 91, 0, 0, 92, 92, - 92, 92, 92, 93, 94, 95, 96, 97, 98, 47, 99,100,101,102, 0,103, - 104,105, 0, 0, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 0,106,106,106,106,106,106,106,106,106,106,106,107, - 108,108,108,108,108, 11,109,110,111, 4,112, 4,113,114,115,116, - 117,118,119,120,121,122,123,124,125,126, 50,127, 47, 47, 47, 47, - 47, 47, 47, 47,128,128,128,128,128,128,128,128,128,128,128,128, - 92, 92, 92, 92, 92, 92, 92, 92,129,130, 19, 19, 19, 19, 19, 19, - 131, 19, 19, 19,132,133, 19,134,135,136,137,101,138,138,138,138, - 0, 77,139,140,128,128,141,142,143,144,145,146,147,148,149,150, - 151,152,153,154,155,155,155,155,155,155, 4, 4,156,157,158,159, - 160,161,162,163,164,165,166,167,168,169,170,170,171,171,172,172, - 173,174,174,174, 19, 19,175,176,177,178,179,180,181,181,182,183, - 184,185,186,187,188,188,189,190,191,192,193,193,194,194,195,195, - 128,128,196,196,197,198,199,200,201,201,128,128,202,202,203,203, - 204,204,205,205,206,207,208,209, 28, 28,210,210,211,212,213,213, - 214,215,216,216,128,128,217,217,218,218,219, 34,220,220,220,220, - 220,220,220,220,220,220,220,220,220,220,128,128,128,128,128,128, - 128,128,221,221,222,222,222,222,222,222,222,222,223,223,223,223, - 223,223,223,223,223,223,128,128,128,128,128,128,128,128,128,128, - 224,224,128,128,110,110,110,110,110,110,110,110,110,225,226,227, - 228,228,228,228,128,128,128,128,229,229,128,128,230,230,230,230, - 231,231,231,232,233,233,233,233,233,233,233,233,233,233,233,233, - 234,234,234,234,234,234,234,234,233,233,128,128,128,128,128,128, - 128,128,104,104,235,236,236,236,237,238,239,239,239,239,239,239, - 128,128,128,128,240,240,241, 0,128,128,128,128, 0, 0, 0, 0, - 7,242, 0, 0, 0, 0, 0, 0, 0,243,244, 0, 77, 77, 0, 0, - 0, 0,128,128,245,245,245,245,245,245,245,245,245,245,245,245, - 128,128,128,128,128,128,128,128, 4, 4,128,128,246, 11, 11, 11, - 247,247,128,128,128,128,248,249,128,128,128,128,128,128,250,250, - 128,128,251,251,128,128,128,128,128,128, 48, 48,252,252,252,252, - 253,253,128,128, 0, 0, 0, 0, 0, 0,128,128, 19, 19, 19, 19, - 128,128,128,128,254, 0,128,128, 0, 0, 0, 0, 92, 92,128,128, - 128,128,128,128, 0, 0,128,128, 7, 7, 7, 7, 0, 0, 0, 0, - 1, 2, 1, 2, 0, 0, 3, 3, 4, 5, 4, 5, 4, 4, 4, 4, - 4, 4, 4, 6, 0, 0, 7, 0, 8, 8, 8, 8, 8, 8, 8, 9, - 10, 11, 11, 11, 11, 11, 12, 11, 13, 13, 13, 13, 14, 13, 13, 13, - 13, 13, 13, 15, 16, 16, 16, 16, 16, 17, 18, 18, 18, 18, 18, 18, - 19, 20, 21, 21, 22, 23, 21, 24, 21, 21, 21, 21, 21, 25, 21, 21, - 26, 26, 26, 26, 26, 21, 21, 21, 27, 27, 27, 27, 28, 28, 28, 28, - 29, 29, 29, 29, 30, 30, 26, 21, 21, 21, 31, 21, 32, 32, 32, 32, - 32, 33, 34, 32, 35, 35, 35, 35, 36, 36, 36, 36, 37, 37, 37, 37, - 38, 38, 38, 38, 39, 39, 39, 39, 40, 40, 40, 40, 41, 41, 41, 41, - 42, 42, 42, 42, 43, 43, 43, 43, 44, 44, 44, 45, 44, 44, 44, 44, - 46, 46, 46, 46, 47, 47, 47, 47, 47, 48, 47, 47, 49, 49, 49, 49, - 49, 49, 50, 50, 50, 50, 50, 51, 52, 52, 52, 52, 53, 53, 53, 53, - 53, 53, 54, 54, 54, 54, 54, 54, 55, 55, 55, 55, 56, 56, 57, 57, - 57, 57, 58, 57, 59, 59, 60, 61, 62, 62, 63, 63, 64, 64, 64, 64, - 65, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 55, 67, 67, 67, 67, - 67, 68, 68, 68, 69, 69, 69, 69, 69, 69, 64, 64, 70, 70, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 8, 72, 72, 72, 72, 73, 73, 73, 73, - 74, 74, 74, 74, 75, 75, 75, 75, 75, 76, 76, 76, 13, 50, 50, 50, - 73, 77, 78, 79, 4, 4, 80, 4, 4, 81, 82, 83, 4, 4, 4, 84, - 11, 11, 11, 11, 85, 0, 0, 0, 0, 0, 0, 86, 0, 4, 0, 0, - 0, 8, 8, 8, 0, 0, 87, 88, 89, 0, 4, 4, 6, 0, 0, 0, - 90, 90, 90, 90, 91, 91, 91, 91, 91, 91, 4, 4, 92, 92, 92, 92, - 50, 50, 50, 93, 93, 93, 93, 93, 53, 53, 13, 13, 94, 94, 94, 94, - 94, 94, 94, 0, 95, 0, 96, 97, 98, 99, 99, 99, 99,100,101,102, - 102,102,102,103,104,104,104,105, 52, 0,104,104, 0, 0, 0,102, - 52, 52, 0, 0, 0, 0, 52,106, 0,102,102,107,102,102,102,102, - 102,108, 0, 0,109,109,109,109,109,110,110,110,111,111,111,111, - 13, 13,112,112,112,112,112,112, 0, 0,113, 4,114, 4, 4, 4, - 115,115,115, 0,116,116,116,116,117,117,117,117,117,117, 32, 32, - 118,118,119,120,120,120, 52, 52,121,121,121,121,122,121, 49, 49, - 123,123,123,123,123,123, 49, 49,124,124,124,124,124,124,125,125, - 53, 53, 53, 4, 4,126,127, 54,125,125,125,125,128,128,128,128, - 4,129, 18, 18, 18, 21, 21, 21, 21, 21, 21,130, 8, 0,131, 0, - 0, 0, 0, 21, 21, 21, 21,132, 0, 0, 1, 2, 1, 2,133,101, - 102,134, 52, 52,135,135,135,135, 11, 0, 11, 11, 11, 0, 0,136, - 137,137,138,138,138,138,139, 0,140,140,140,141,141,142,142,142, - 143,143,144,144,144,144,144,144,145,145,145,145,145,146,146,146, - 147,147,147,148,148,148,148,148,149,149,149,150,150,150,150,151, - 151,151,151,151,152,152,152,152,153,153,153,153,154,154,154,154, - 155,155,156,156,157,157,157,157,157,157,158,158,159,159,160,160, - 160,160,160,160,161,161,162,162,162,162,162,162,163,163,163,163, - 163,163,164,164,165,165,165,165,166,166,166,166,167,167,167,167, - 168,168,169,169,170,170,170,170,171,171,171,171,172,172,172,172, - 173,173,173,173,174,174,174,174,175,175,175,175,176, 21, 21, 21, - 177,177,177,178,178,178,178,179,179,179,179,180,180,180,181,181, - 182,182,182,182,183,183,183,183,183,184,184,184,185,185,185,185, - 185,186,186,186,187,187,187,187,187,187,188, 43,189,189,189,189, - 190,190,190,191,191,191,191,191,192,192,192,193,192,192,192,192, - 194,194,194,194,195,195,195,195,196,196,196,196,197,197,197,197, - 198,198,198,198,198,198, 66, 66,199,199,199,199,199, 49, 49, 49, - 200,200,200,200,201,201,201,201,202,202,202,202,203,203,203,203, - 204,204,204,204,205,205,205,205,205,206,206,206,206,206,206, 55, - 207,207,207,207,208,208,208,208,209,209,209,209,209,209,209,210, - 210,210,210,210,211,211,211,211,211,211,212,212,212,212,212,212, - 213,213,213,213,214,214,214,214,110,110,110,110,215,215,215,215, - 216,216,216,216,217,217,217,217,218,218,218,218,219,219,219,219, - 220,220,220,221,221,221,221,221,221,222,222,222,223,223,223,223, - 224,224,224,224,225,225,225,225,226,226,226,226,226,226,227, 94, - 228,228,228,228,229,229,229,229,230, 99, 99, 99, 99, 99, 99, 99, - 99, 99,102,231, 99,232,102,233,233,233,233,233,234,234,234,234, - 234,234, 0, 0, 8, 0, 0, 0, 0, 0,235,236,237, 0,238, 0, - 239,239,239,239, 91, 91, 91, 13,240,240,240,240,241,241,241,241, - 242,242,242,242,243,243,243,243,244,244,244,244,245,245,245,245, - 246,246,246,246,247, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, - 2, 2, 3, 0, 0, 0, 4, 0, 2, 2, 2, 2, 2, 3, 2, 2, - 2, 2, 5, 0, 2, 5, 6, 0, 7, 7, 7, 7, 8, 9, 8, 10, - 8, 11, 8, 8, 8, 8, 8, 8, 12, 13, 13, 13, 14, 14, 14, 14, - 14, 15, 14, 14, 16, 17, 17, 17, 17, 17, 17, 17, 18, 19, 19, 19, - 19, 19, 19, 19, 20, 21, 20, 22, 20, 20, 23, 23, 20, 20, 20, 20, - 22, 20, 24, 7, 7, 25, 20, 20, 26, 20, 20, 20, 20, 20, 20, 21, - 27, 27, 27, 27, 28, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 30, - 31, 31, 31, 31, 32, 20, 20, 20, 33, 33, 33, 33, 34, 35, 33, 33, - 33, 36, 33, 33, 37, 37, 37, 37, 38, 38, 38, 38, 39, 39, 39, 39, - 40, 40, 40, 40, 41, 41, 41, 41, 42, 42, 42, 42, 43, 43, 43, 43, - 44, 44, 44, 44, 45, 45, 45, 45, 46, 46, 46, 46, 46, 46, 46, 47, - 48, 48, 48, 48, 49, 49, 49, 49, 49, 50, 51, 49, 52, 52, 52, 52, - 53, 53, 53, 53, 53, 53, 54, 53, 55, 55, 55, 55, 56, 56, 56, 56, - 57, 57, 57, 57, 58, 58, 58, 58, 59, 59, 59, 59, 60, 60, 60, 60, - 60, 60, 61, 62, 63, 63, 63, 63, 64, 64, 64, 64, 64, 65, 0, 0, - 66, 66, 66, 66, 67, 67, 67, 67, 68, 68, 68, 68, 69, 70, 71, 71, - 71, 71, 71, 71, 72, 72, 72, 72, 73, 73, 73, 73, 74, 74, 74, 74, - 75, 75, 75, 75, 76, 76, 76, 76, 77, 77, 77, 77, 78, 78, 78, 78, - 79, 79, 79, 79, 80, 80, 80, 80, 81, 81, 81, 81, 82, 7, 7, 7, - 83, 7, 84, 85, 0, 84, 86, 0, 2, 87, 88, 2, 2, 2, 2, 89, - 90, 87, 91, 2, 2, 2, 92, 2, 2, 2, 2, 93, 0, 0, 0, 86, - 1, 0, 0, 94, 0, 95, 96, 0, 4, 0, 0, 0, 0, 0, 0, 4, - 97, 97, 97, 97, 98, 98, 98, 98, 13, 13, 13, 13, 99, 99, 99, 99, - 100,100,100,100, 0,101, 0, 0,102,100,103,104, 0, 0,100, 0, - 105,106,106,106,106,106,106,106,106,106,107,105,108,109,109,109, - 109,109,109,109,109,109,110,108,111,111,111,111,112, 55, 55, 55, - 55, 55, 55,113,109,109,109,110,109,109, 0, 0,114,114,114,114, - 115,115,115,115,116,116,116,116,117,117,117,117, 96, 2, 2, 2, - 2, 2, 94, 2,118,118,118,118,119,119,119,119,120,120,120,120, - 121,121,121,121,121,121,121,122,123,123,123,123,124,124,124,124, - 124,124,124,125,126,126,126,126,127,127,127,127,128,128,128,128, - 2, 2, 3, 2, 2,129,130, 0,131,131,131,131,132, 17, 17, 18, - 20, 20, 20,133, 7, 7, 7,134, 20, 20, 20, 23, 0,135,109,109, - 109,109,109,136,137,137,137,137, 0, 0, 0,138,139,139,139,139, - 140,140,140,140, 84, 0, 0, 0,141,141,141,141,142,142,142,142, - 143,143,143,143,144,144,144,144,145,145,145,145,146,146,146,146, - 147,147,147,147,148,148,148,148,149,149,149,149,150,150,150,150, - 151,151,151,151,152,152,152,152,153,153,153,153,154,154,154,154, - 155,155,155,155,156,156,156,156,157,157,157,157,158,158,158,158, - 159,159,159,159,160,160,160,160,161,161,161,161,162,162,162,162, - 163,163,163,163,164,164,164,164,165,165,165,165,166,166,166,166, - 167,167,167,167,168,168,168,168,169,169,169,169,170,170,170,170, - 171,171,171,171,172,172,172,172,173,173,173,173,174,174,174,174, - 175,175,175,175,176,176,176,176,177, 20, 20, 20,178,178,178,178, - 179,179,179,179,180,180,180,180,181,181,181,181,182,182,182,182, - 183,183,183,183,184,184,184,184,185,185,185,185,186,186,186,186, - 187,187,187,187,188,188,188,188,189, 45, 45, 45,190,190,190,190, - 191,191,191,191,192,192,192,192,193,193,193,193,193,193,194,193, - 195,195,195,195,196,196,196,196,197,197,197,197,198,198,198,198, - 199,199,199,199,200,200,200,200,201,201,201,201,202,202,202,202, - 203,203,203,203,204,204,204,204,205,205,205,205,206,206,206,206, - 207,207,207,207,208,208,208,208,209,209,209,209,210,210,210,210, - 211,211,211,211,212,212,212,212,213,213,213,213,214,214,214,214, - 215,215,215,215,216,216,216,216,217,217,217,217,218,218,218,218, - 219,219,219,219,220,220,220,220,221,221,221,221,222,222,222,222, - 223,223,223,223,224,224,224,224,225,225,225,225,226,226,226,226, - 227,227,227,227,228,229,229,229,230,230,230,230,229,229,229,229, - 231,106,106,106,232,106,106,106,106,233,109,109,234,234,234,234, - 235,235,235,235, 0,236, 86, 0, 0, 0,236, 7, 82,138, 7, 0, - 0, 0,237, 86,238,238,238,238,239,239,239,239,240,240,240,240, - 241,241,241,241,242,242,242,242,243,243,243,243,244,244,244,244, - 245,245,245,245,246, 0, 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 0, 0, 0, 19, 0, 19, 0, 0, 0, - 0, 0, 26, 26, 1, 1, 1, 1, 9, 9, 9, 9, 0, 9, 9, 9, - 9, 9, 0, 9, 9, 0, 9, 0, 9, 9, 55, 55, 55, 55, 55, 55, - 6, 6, 6, 6, 6, 1, 1, 6, 6, 4, 4, 4, 4, 4, 4, 4, - 4, 14, 14, 14, 14, 14, 14, 14, 3, 3, 3, 3, 3, 0, 3, 3, - 0, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 1, 1, 1, 3, 3, - 1, 3, 3, 3, 37, 37, 37, 37, 38, 38, 38, 38, 64, 64, 64, 64, - 90, 90, 90, 90, 95, 95, 95, 95, 3, 3, 0, 3, 7, 7, 7, 7, - 7, 1, 1, 1, 1, 7, 7, 7, 0, 0, 7, 7, 5, 5, 5, 5, - 11, 11, 11, 11, 10, 10, 10, 10, 21, 21, 21, 21, 22, 22, 22, 22, - 23, 23, 23, 23, 16, 16, 16, 16, 20, 20, 20, 20, 36, 36, 36, 36, - 24, 24, 24, 24, 24, 24, 24, 0, 18, 18, 18, 18, 25, 25, 25, 25, - 25, 0, 0, 0, 0, 25, 25, 25, 33, 33, 33, 33, 8, 8, 8, 8, - 8, 8, 8, 0, 12, 12, 12, 12, 30, 30, 30, 30, 29, 29, 29, 29, - 28, 28, 28, 28, 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, 35, 0, - 0, 0, 35, 35, 45, 45, 45, 45, 44, 44, 44, 44, 44, 0, 0, 0, - 43, 43, 43, 43, 46, 46, 46, 46, 31, 31, 31, 31, 32, 32, 0, 0, - 32, 0, 32, 32, 32, 32, 32, 32, 48, 48, 48, 48, 52, 52, 52, 52, - 58, 58, 58, 58, 54, 54, 54, 54, 91, 91, 91, 91, 62, 62, 62, 62, - 76, 76, 76, 76, 93, 93, 93, 93, 70, 70, 70, 70, 73, 73, 73, 73, - 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, - 1, 1, 0, 0, 19, 19, 9, 9, 9, 9, 9, 6, 19, 9, 9, 9, - 9, 9, 19, 19, 9, 9, 9, 19, 6, 19, 19, 19, 19, 19, 19, 9, - 0, 0, 0, 19, 0, 0, 9, 0, 0, 0, 19, 19, 27, 27, 27, 27, - 56, 56, 56, 56, 61, 61, 61, 61, 13, 13, 13, 13, 0, 13, 0, 13, - 0, 13, 13, 13, 13, 13, 1, 1, 1, 1, 12, 12, 0, 15, 15, 15, - 15, 15, 15, 15, 15, 1, 1, 0, 0, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 0, 26, 26, 26, 26, 26, 12, 12, 12, 12, 12, 12, 0, - 39, 39, 39, 39, 86, 86, 86, 86, 77, 77, 77, 77, 79, 79, 79, 79, - 60, 60, 60, 60, 65, 65, 65, 65, 75, 75, 75, 75, 69, 69, 69, 69, - 69, 69, 0, 69, 74, 74, 74, 74, 84, 84, 84, 84, 84, 84, 84, 0, - 68, 68, 68, 68, 92, 92, 92, 92, 87, 87, 87, 87, 19, 9, 19, 19, - 19, 19, 0, 0, 2, 2, 2, 2, 19, 19, 19, 4, 3, 3, 0, 0, - 1, 1, 6, 6, 0, 0, 17, 17, 17, 17, 0, 0, 49, 49, 49, 49, - 0, 1, 1, 1, 71, 71, 71, 71, 67, 67, 67, 67, 42, 42, 42, 42, - 41, 41, 41, 41,118,118,118,118, 53, 53, 53, 53, 59, 59, 59, 59, - 40, 40, 40, 40, 51, 51, 51, 51, 50, 50, 50, 50,135,135,135,135, - 106,106,106,106,104,104,104,104,161,161,161,161,170,170,170,170, - 110,110,110,110, 47, 47, 47, 47, 81, 81, 81, 81,120,120,120,120, - 116,116,116,116,128,128,128,128, 66, 66, 66, 66, 72, 72, 72, 72, - 98, 98, 98, 98, 97, 97, 97, 97, 57, 57, 57, 57, 88, 88, 88, 88, - 117,117,117,117,112,112,112,112, 78, 78, 78, 78, 83, 83, 83, 83, - 82, 82, 82, 82,122,122,122,122, 89, 89, 89, 89,130,130,130,130, - 144,144,144,144,165,165,165,165,156,156,156,156,156,156, 3, 3, - 147,147,147,147,148,148,148,148,158,158,158,158,153,153,153,153, - 149,149,149,149, 94, 94, 94, 94, 85, 85, 85, 85,101,101,101,101, - 96, 96, 96, 96,111,111,111,111,100,100,100,100,100, 36, 36, 36, - 108,108,108,108,129,129,129,129,109,109,109,109,107,107,107,107, - 107,107,107, 1,171,171,171,171,137,137,137,137,124,124,124,124, - 123,123,123,123,114,114,114,114,102,102,102,102,126,126,126,126, - 142,142,142,142,125,125,125,125,154,154,154,154,150,150,150,150, - 141,141,141,141,140,140,140,140,121,121,121,121,169,169,169,169, - 133,133,133,133,134,134,134,134,138,138,138,138,143,143,143,143, - 145,145,145,145,163,163,163,163, 63, 63, 63, 63,157,157,157,157, - 80, 80, 80, 80,127,127,127,127,166,166,166,166,115,115,115,115, - 159,159,159,159,103,103,103,103,119,119,119,119,167,167,167,167, - 146,146,146,146, 99, 99, 99, 99,136,139, 13, 13,155,155,155,155, - 136,136,136,136, 17, 15, 15, 15, 17, 17, 15, 15, 15, 17, 17, 17, - 139,139,139,139,105,105,105,105, 0, 0, 0, 1, 0, 0, 1, 1, - 131,131,131,131,151,151,151,151,160,160,160,160,152,152,152,152, - 164,164,164,164,168,168,168,168,113,113,113,113,132,132,132,132, - 15, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, - 9, 10, 9, 11, 12, 13, 9, 9, 9, 14, 9, 9, 15, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 16, 17, 9, 9, 9, 9, 18, 9, 9, 9, 9, 9, 19, 20, 21, 9, - 22, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 23, 9, 9, 9, 9, 9, 24, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 25, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, - 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, 0, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 23, 0, 0, 24, 25, 26, 27, 28, 29, 30, - 0, 0, 31, 32, 0, 33, 0, 34, 0, 35, 0, 0, 0, 0, 36, 37, - 38, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 42, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 43, 44, 0, 45, 0, 0, 0, 0, 0, 0, 46, 47, - 0, 0, 0, 0, 0, 48, 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 50, 51, 0, 0, 0, 52, 0, 0, 53, 0, - 0, 0, 0, 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, 55, 0, - 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 57, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 58, 59, 60, 61, 62, 63, 64, 65, 0, 0, - 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 67, 68, 0, 69, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, - 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,100, - 101,102,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,104, 0, 0, 0, 0, 0, 0,105,106, 0,107, 0, - 0, 0,108, 0,109, 0,110, 0,111,112,113, 0,114, 0, 0, 0, - 115, 0, 0, 0,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,117, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,118,119,120,121, 0,122,123,124,125,126, - 0,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,128,129,130,131,132,133,134,135,136,137,138,139,140,141, - 142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157, - 0, 0, 0,158,159,160,161, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,162, 0, - 163, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,164,165, 0, 0, 0, - 0, 0, 0, 0,166, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,167, 0, 0, 0,168,169, 0, 0,170, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,171, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,172, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,174, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,175, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,176,177, 0, 0, 0, 0,178,179, 0, - 0, 0,180,181,182,183,184,185,186,187,188,189,190,191,192,193, - 194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209, - 210,211,212,213, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, - 3, 4, -}; -static const uint16_t _hb_ucd_u16[5080]= -{ - 0, 0, 1, 2, 3, 4, 5, 6, 0, 0, 7, 8, 9, 10, 11, 12, - 13, 13, 13, 14, 15, 13, 13, 16, 17, 18, 19, 20, 21, 22, 13, 23, - 13, 13, 13, 24, 25, 11, 11, 11, 11, 26, 11, 27, 28, 29, 30, 31, - 32, 32, 32, 32, 32, 32, 32, 33, 34, 35, 36, 11, 37, 38, 13, 39, - 9, 9, 9, 11, 11, 11, 13, 13, 40, 13, 13, 13, 41, 13, 13, 13, - 13, 13, 13, 35, 9, 42, 11, 11, 43, 44, 32, 45, 46, 47, 47, 48, - 49, 50, 47, 47, 51, 32, 52, 53, 47, 47, 47, 47, 47, 54, 55, 56, - 57, 58, 47, 32, 59, 47, 47, 47, 47, 47, 60, 53, 61, 47, 62, 63, - 47, 64, 65, 66, 47, 67, 47, 47, 68, 69, 47, 47, 70, 32, 71, 32, - 72, 47, 47, 73, 74, 75, 76, 77, 78, 47, 47, 79, 80, 81, 82, 83, - 84, 47, 47, 85, 86, 87, 88, 89, 84, 47, 47, 79, 90, 47, 82, 91, - 92, 47, 47, 93, 94, 95, 82, 96, 97, 47, 47, 98, 99, 100, 101, 102, - 103, 47, 47, 104, 105, 106, 82, 107, 108, 47, 47, 93, 109, 110, 82, 111, - 112, 47, 47, 113, 114, 115, 82, 116, 92, 47, 47, 47, 117, 118, 101, 119, - 47, 47, 47, 120, 121, 122, 66, 66, 47, 47, 47, 123, 124, 125, 47, 47, - 126, 127, 128, 129, 47, 47, 47, 130, 131, 32, 32, 132, 133, 134, 66, 66, - 47, 47, 135, 136, 122, 137, 138, 139, 140, 141, 9, 9, 9, 11, 11, 142, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 143, 144, 145, - 47, 146, 9, 9, 9, 9, 9, 147, 148, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 149, 47, 150, 151, 47, 47, 47, 47, 152, 153, - 47, 154, 47, 155, 47, 156, 47, 156, 47, 47, 47, 157, 158, 159, 160, 145, - 161, 160, 47, 47, 162, 47, 47, 47, 163, 47, 164, 47, 47, 47, 47, 47, - 47, 47, 165, 166, 167, 47, 47, 47, 47, 47, 47, 47, 47, 168, 146, 146, - 47, 169, 47, 47, 47, 170, 171, 172, 160, 160, 173, 174, 32, 32, 32, 32, - 175, 47, 47, 176, 177, 122, 178, 179, 180, 47, 181, 61, 47, 47, 182, 183, - 47, 47, 184, 185, 186, 61, 47, 187, 188, 9, 9, 9, 66, 189, 190, 191, - 11, 11, 192, 27, 27, 27, 193, 194, 11, 195, 27, 27, 32, 32, 32, 32, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 196, 13, 13, 13, 13, 13, 13, - 197, 197, 197, 197, 197, 198, 197, 11, 199, 199, 199, 200, 201, 202, 202, 201, - 203, 204, 205, 206, 207, 208, 209, 210, 211, 27, 212, 212, 212, 213, 214, 32, - 215, 216, 217, 218, 219, 145, 220, 220, 221, 222, 223, 146, 224, 225, 146, 226, - 227, 227, 227, 227, 227, 227, 227, 227, 228, 146, 229, 146, 146, 146, 146, 230, - 146, 231, 227, 232, 146, 233, 234, 146, 146, 146, 146, 146, 146, 146, 145, 145, - 145, 235, 146, 146, 146, 146, 236, 145, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 237, 238, 146, 146, 239, 146, 146, 146, 146, 146, 146, 240, 146, - 146, 146, 146, 146, 146, 146, 241, 242, 145, 243, 146, 146, 244, 227, 245, 227, - 246, 247, 227, 227, 227, 248, 227, 249, 146, 146, 146, 227, 250, 146, 146, 146, - 9, 9, 9, 11, 11, 11, 251, 252, 13, 13, 13, 13, 13, 13, 253, 254, - 11, 11, 11, 47, 47, 47, 255, 256, 47, 47, 47, 47, 47, 47, 32, 32, - 257, 258, 259, 260, 261, 262, 263, 263, 264, 265, 266, 267, 268, 47, 47, 47, - 47, 269, 148, 47, 47, 47, 47, 270, 47, 271, 47, 47, 146, 146, 146, 47, - 146, 146, 272, 146, 273, 274, 146, 146, 272, 146, 146, 274, 146, 146, 146, 146, - 47, 47, 47, 47, 146, 146, 146, 146, 47, 275, 47, 47, 47, 47, 47, 47, - 47, 146, 146, 146, 146, 47, 47, 187, 276, 47, 61, 47, 13, 13, 277, 278, - 13, 279, 47, 47, 47, 47, 280, 281, 31, 282, 283, 284, 13, 13, 13, 285, - 286, 287, 288, 289, 290, 291, 9, 292, 293, 47, 294, 295, 47, 47, 47, 296, - 297, 47, 47, 298, 299, 160, 32, 300, 61, 47, 301, 47, 302, 303, 47, 47, - 72, 47, 47, 304, 305, 306, 307, 61, 47, 47, 308, 309, 310, 311, 47, 312, - 47, 47, 47, 313, 58, 314, 315, 316, 47, 47, 47, 11, 11, 317, 318, 11, - 11, 11, 11, 11, 47, 47, 319, 160, 320, 320, 320, 320, 320, 320, 320, 320, - 321, 321, 321, 321, 321, 321, 321, 321, 11, 322, 323, 47, 47, 47, 47, 47, - 47, 47, 47, 324, 31, 325, 47, 47, 47, 47, 47, 326, 146, 47, 47, 47, - 47, 47, 47, 47, 327, 146, 146, 328, 32, 329, 32, 330, 331, 332, 333, 47, - 47, 47, 47, 47, 47, 47, 47, 334, 335, 2, 3, 4, 5, 336, 337, 338, - 47, 339, 47, 47, 47, 47, 340, 341, 342, 145, 145, 343, 220, 220, 220, 344, - 345, 146, 146, 146, 146, 146, 146, 346, 347, 347, 347, 347, 347, 347, 347, 347, - 47, 47, 47, 47, 47, 47, 348, 145, 47, 47, 349, 47, 350, 47, 47, 60, - 47, 351, 47, 47, 47, 352, 220, 220, 9, 9, 147, 11, 11, 47, 47, 47, - 47, 47, 160, 9, 9, 147, 11, 11, 47, 47, 47, 47, 47, 47, 351, 9, - 9, 353, 11, 11, 47, 47, 47, 47, 27, 27, 27, 27, 27, 27, 27, 27, - 47, 47, 47, 47, 47, 354, 47, 355, 47, 47, 356, 145, 145, 145, 47, 357, - 47, 358, 47, 351, 66, 66, 66, 66, 47, 47, 47, 359, 145, 145, 145, 145, - 360, 47, 47, 361, 145, 66, 47, 362, 47, 363, 145, 145, 364, 47, 365, 66, - 47, 47, 47, 366, 47, 367, 47, 367, 47, 366, 144, 145, 145, 145, 145, 145, - 9, 9, 9, 9, 11, 11, 11, 368, 47, 47, 369, 160, 370, 9, 371, 11, - 372, 227, 227, 227, 227, 227, 227, 227, 145, 145, 145, 145, 145, 145, 145, 145, - 47, 47, 373, 47, 47, 47, 47, 374, 47, 363, 375, 47, 60, 376, 66, 47, - 377, 66, 66, 47, 378, 145, 47, 47, 379, 47, 47, 361, 380, 381, 382, 383, - 180, 47, 47, 384, 385, 47, 47, 160, 97, 47, 386, 387, 388, 47, 47, 389, - 180, 47, 47, 390, 391, 392, 393, 145, 47, 47, 394, 395, 360, 32, 32, 32, - 47, 47, 366, 47, 47, 396, 172, 160, 92, 47, 47, 113, 397, 398, 399, 32, - 47, 47, 47, 400, 401, 402, 403, 32, 47, 47, 47, 404, 405, 406, 47, 47, - 47, 47, 47, 407, 408, 160, 160, 160, 47, 47, 409, 410, 411, 412, 32, 32, - 47, 47, 47, 413, 414, 160, 66, 66, 47, 47, 415, 416, 160, 160, 160, 160, - 47, 417, 418, 419, 47, 47, 47, 47, 47, 47, 394, 420, 66, 66, 66, 66, - 9, 9, 9, 9, 11, 11, 128, 421, 47, 47, 47, 422, 423, 160, 160, 160, - 47, 47, 47, 47, 47, 424, 425, 426, 427, 47, 47, 428, 429, 430, 47, 47, - 431, 432, 66, 47, 47, 47, 47, 47, 66, 66, 66, 66, 66, 66, 66, 66, - 47, 47, 47, 47, 47, 47, 433, 160, 47, 47, 409, 434, 433, 128, 145, 435, - 47, 156, 436, 437, 32, 32, 32, 32, 47, 47, 47, 360, 438, 160, 47, 47, - 439, 440, 160, 160, 160, 160, 160, 160, 47, 47, 47, 47, 47, 47, 47, 441, - 442, 47, 47, 443, 444, 445, 32, 32, 47, 47, 47, 47, 145, 446, 447, 448, - 220, 220, 220, 220, 220, 220, 220, 66, 47, 47, 47, 47, 47, 47, 47, 433, - 47, 47, 47, 209, 449, 32, 47, 47, 47, 450, 451, 160, 160, 160, 160, 160, - 47, 47, 47, 47, 47, 47, 306, 47, 47, 47, 47, 47, 160, 47, 47, 452, - 47, 47, 47, 453, 454, 455, 456, 47, 27, 27, 27, 27, 457, 47, 458, 160, - 9, 9, 9, 9, 9, 9, 11, 11, 145, 459, 66, 66, 66, 66, 66, 66, - 47, 47, 47, 47, 396, 460, 426, 426, 461, 462, 27, 27, 27, 27, 463, 426, - 47, 464, 209, 209, 209, 209, 209, 209, 146, 146, 146, 146, 146, 146, 146, 160, - 32, 32, 32, 32, 32, 146, 146, 146, 146, 146, 146, 146, 146, 146, 465, 466, - 467, 146, 468, 146, 146, 146, 146, 146, 146, 146, 146, 146, 469, 146, 146, 146, - 9, 470, 11, 471, 472, 11, 197, 9, 473, 474, 9, 475, 11, 9, 470, 11, - 471, 472, 11, 197, 9, 473, 474, 9, 475, 11, 9, 470, 11, 471, 472, 11, - 197, 9, 473, 474, 9, 475, 11, 9, 470, 11, 197, 9, 476, 477, 478, 479, - 11, 480, 9, 481, 482, 483, 484, 11, 485, 9, 486, 11, 487, 160, 160, 160, - 32, 32, 32, 488, 32, 32, 489, 490, 491, 492, 32, 32, 32, 32, 32, 32, - 493, 11, 11, 11, 11, 11, 11, 11, 32, 32, 32, 27, 27, 27, 27, 27, - 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 47, 494, 495, 146, 146, 146, - 47, 47, 450, 32, 47, 47, 374, 496, 47, 47, 47, 47, 47, 47, 497, 160, - 47, 47, 47, 47, 47, 47, 450, 498, 47, 47, 47, 47, 356, 32, 32, 32, - 9, 9, 473, 11, 499, 306, 66, 66, 145, 145, 500, 501, 145, 145, 145, 145, - 145, 145, 502, 145, 145, 145, 145, 145, 47, 47, 47, 47, 47, 47, 47, 227, - 503, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 504, - 209, 209, 209, 209, 209, 209, 209, 209, 0, 0, 0, 0, 0, 0, 0, 0, + 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 716, + 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 717, + 0, 0, 0, 0, 1, 2, 1, 2, 0, 0, 3, 3, 4, 5, 4, 5, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 0, 0, 7, 0, + 8, 8, 8, 8, 8, 8, 8, 9, 10, 11, 12, 11, 11, 11, 13, 11, + 14, 14, 14, 14, 14, 14, 14, 14, 15, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 16, 17, 18, 17, 17, 19, 20, 21, 21, 22, 21, 23, 24, + 25, 26, 27, 27, 28, 29, 27, 30, 27, 27, 27, 27, 27, 31, 27, 27, + 32, 33, 33, 33, 34, 27, 27, 27, 35, 35, 35, 36, 37, 37, 37, 38, + 39, 39, 40, 41, 42, 43, 44, 27, 27, 45, 27, 27, 27, 27, 46, 27, + 47, 47, 47, 47, 47, 48, 49, 47, 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, + 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, + 106, 107, 108, 108, 109, 110, 111, 108, 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 121, 122, 121, 123, 124, 124, 125, 126, 127, 128, 129, 130, 124, 124, + 131, 131, 131, 131, 132, 131, 133, 134, 131, 132, 131, 135, 135, 136, 124, 124, + 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 138, 138, 139, 138, 138, 140, + 141, 141, 141, 141, 141, 141, 141, 141, 142, 142, 142, 142, 143, 144, 142, 142, + 143, 142, 142, 145, 146, 147, 142, 142, 142, 146, 142, 142, 142, 148, 142, 149, + 142, 150, 151, 151, 151, 151, 151, 152, 153, 153, 153, 153, 153, 153, 153, 153, + 154, 155, 156, 156, 156, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, + 167, 167, 167, 167, 167, 168, 169, 169, 170, 171, 172, 172, 172, 172, 172, 173, + 172, 172, 174, 153, 153, 153, 153, 175, 176, 177, 178, 178, 179, 180, 181, 182, + 183, 183, 184, 183, 185, 186, 167, 167, 187, 188, 189, 189, 189, 190, 189, 191, + 192, 192, 193, 8, 8, 194, 195, 124, 196, 196, 196, 196, 197, 196, 196, 196, + 198, 198, 198, 198, 199, 199, 199, 200, 201, 201, 201, 202, 203, 204, 204, 204, + 205, 138, 138, 206, 207, 208, 209, 210, 4, 4, 211, 4, 4, 212, 213, 214, + 4, 4, 4, 215, 8, 8, 8, 8, 11, 216, 11, 11, 216, 217, 11, 218, + 11, 11, 11, 219, 219, 220, 11, 221, 222, 0, 0, 0, 0, 0, 223, 224, + 225, 226, 0, 0, 227, 8, 8, 228, 0, 0, 229, 230, 231, 0, 4, 4, + 232, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 233, 124, 234, 124, 0, 0, 235, 235, 235, 235, 235, 235, 235, 235, + 0, 0, 0, 0, 0, 0, 0, 236, 237, 237, 237, 237, 237, 237, 4, 4, + 238, 238, 238, 238, 238, 238, 238, 239, 138, 138, 139, 240, 240, 240, 241, 242, + 142, 243, 244, 244, 244, 244, 14, 14, 0, 0, 0, 0, 0, 245, 124, 124, + 246, 247, 246, 246, 246, 246, 246, 248, 246, 246, 246, 246, 246, 246, 246, 246, + 246, 246, 246, 246, 246, 249, 124, 0, 250, 0, 251, 252, 253, 254, 254, 254, + 254, 255, 256, 257, 257, 257, 257, 258, 259, 260, 260, 261, 141, 141, 141, 141, + 262, 0, 260, 260, 0, 0, 263, 257, 141, 262, 0, 0, 0, 0, 141, 264, + 0, 0, 0, 0, 0, 257, 257, 265, 257, 257, 257, 257, 257, 266, 0, 0, + 246, 246, 246, 246, 0, 0, 0, 0, 267, 267, 267, 267, 267, 267, 267, 267, + 268, 267, 267, 267, 269, 270, 270, 270, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 272, 124, 14, 14, 14, 14, 14, 14, 273, 273, 273, 273, 273, 274, + 0, 0, 275, 4, 4, 4, 4, 4, 276, 4, 4, 4, 4, 226, 124, 277, + 278, 278, 279, 233, 280, 280, 280, 281, 282, 282, 282, 282, 283, 284, 47, 47, + 285, 285, 286, 287, 287, 288, 141, 289, 290, 290, 290, 290, 291, 292, 137, 293, + 294, 294, 294, 295, 296, 297, 137, 137, 298, 298, 298, 298, 299, 300, 301, 302, + 303, 304, 244, 4, 4, 305, 306, 151, 151, 151, 151, 151, 301, 301, 307, 308, + 141, 141, 309, 141, 310, 141, 141, 311, 124, 124, 124, 124, 124, 124, 124, 124, + 246, 246, 246, 246, 246, 246, 312, 246, 246, 246, 246, 246, 246, 313, 124, 124, + 314, 315, 21, 316, 317, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 318, 27, 27, 27, 27, 27, 27, 27, 27, 27, 124, 124, 27, + 8, 233, 319, 0, 0, 320, 321, 322, 27, 27, 27, 27, 27, 27, 27, 323, + 324, 0, 1, 2, 1, 2, 325, 256, 257, 326, 141, 262, 327, 328, 329, 330, + 331, 332, 333, 334, 335, 335, 124, 124, 332, 332, 332, 332, 332, 332, 332, 336, + 337, 0, 0, 338, 11, 11, 11, 11, 339, 340, 341, 124, 124, 0, 0, 342, + 343, 344, 345, 345, 345, 346, 347, 348, 349, 349, 350, 351, 352, 353, 353, 354, + 355, 356, 357, 357, 358, 359, 124, 124, 360, 360, 360, 360, 360, 361, 361, 361, + 362, 363, 364, 365, 365, 366, 365, 367, 368, 368, 369, 370, 370, 370, 371, 372, + 372, 373, 374, 375, 376, 376, 376, 377, 378, 378, 378, 378, 378, 378, 378, 378, + 378, 378, 378, 379, 378, 380, 381, 124, 382, 4, 4, 383, 124, 124, 124, 124, + 384, 385, 385, 386, 387, 388, 389, 389, 390, 391, 392, 124, 124, 124, 393, 394, + 395, 396, 397, 398, 399, 400, 124, 124, 401, 401, 402, 403, 402, 404, 402, 402, + 405, 406, 407, 408, 409, 409, 410, 410, 411, 411, 124, 124, 412, 412, 413, 414, + 415, 415, 415, 416, 417, 418, 419, 420, 421, 422, 423, 124, 124, 124, 124, 124, + 424, 424, 424, 424, 425, 124, 124, 124, 426, 426, 426, 427, 426, 426, 426, 428, + 429, 429, 430, 431, 432, 432, 433, 432, 434, 124, 124, 124, 124, 124, 124, 124, + 124, 124, 124, 124, 124, 124, 27, 435, 436, 436, 437, 438, 439, 440, 124, 441, + 442, 442, 443, 444, 444, 445, 124, 446, 447, 124, 124, 448, 449, 124, 450, 451, + 452, 452, 452, 452, 453, 454, 452, 455, 456, 456, 456, 456, 457, 458, 459, 460, + 461, 461, 461, 462, 463, 464, 464, 465, 466, 466, 466, 466, 466, 466, 467, 468, + 469, 470, 469, 469, 471, 124, 124, 124, 472, 473, 474, 475, 475, 475, 476, 477, + 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 487, 488, 489, 490, 491, 124, + 492, 492, 492, 492, 492, 493, 494, 124, 495, 495, 495, 495, 496, 497, 124, 124, + 498, 498, 498, 499, 498, 500, 124, 124, 501, 501, 501, 501, 502, 503, 504, 124, + 505, 505, 505, 506, 506, 137, 507, 124, 508, 509, 510, 508, 511, 124, 124, 124, + 512, 512, 512, 513, 124, 124, 124, 124, 124, 124, 514, 514, 514, 514, 514, 515, + 516, 517, 518, 519, 520, 521, 124, 124, 124, 124, 522, 523, 523, 522, 524, 124, + 525, 525, 525, 525, 526, 527, 527, 527, 527, 527, 528, 153, 529, 529, 529, 530, + 531, 124, 124, 124, 124, 124, 532, 124, 124, 124, 124, 124, 533, 533, 534, 535, + 536, 537, 537, 538, 539, 537, 540, 541, 541, 542, 543, 544, 124, 124, 124, 124, + 545, 546, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 555, 556, 557, 124, + 124, 124, 124, 124, 124, 124, 558, 559, 560, 561, 560, 562, 560, 563, 124, 124, + 124, 124, 124, 564, 565, 565, 565, 566, 567, 567, 567, 567, 567, 567, 567, 567, + 567, 568, 124, 124, 124, 124, 124, 124, 567, 567, 567, 567, 567, 567, 569, 570, + 567, 567, 567, 567, 571, 124, 124, 124, 124, 572, 572, 572, 572, 572, 572, 573, + 574, 574, 574, 574, 574, 574, 574, 574, 574, 574, 574, 574, 574, 575, 574, 574, + 574, 574, 574, 574, 574, 574, 574, 576, 577, 577, 577, 577, 577, 577, 577, 577, + 577, 577, 577, 577, 578, 124, 124, 124, 579, 579, 579, 580, 124, 124, 124, 124, + 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 581, 582, 583, 584, 585, + 585, 585, 585, 586, 587, 588, 589, 590, 591, 591, 591, 591, 592, 593, 594, 595, + 591, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 596, 596, 596, 597, + 124, 124, 124, 124, 598, 598, 598, 598, 598, 599, 600, 601, 600, 602, 124, 124, + 603, 603, 603, 603, 604, 603, 603, 603, 605, 603, 124, 124, 124, 124, 606, 607, + 608, 608, 608, 608, 608, 608, 608, 608, 609, 609, 609, 609, 609, 609, 609, 609, + 609, 609, 609, 609, 609, 610, 124, 611, 608, 612, 124, 124, 124, 124, 124, 124, + 608, 608, 608, 608, 608, 608, 608, 613, 124, 124, 124, 124, 124, 124, 124, 614, + 615, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, + 254, 254, 616, 617, 124, 618, 619, 620, 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 621, 622, 622, 622, 622, 622, 622, 623, 624, + 625, 626, 627, 124, 124, 124, 124, 124, 0, 0, 0, 0, 0, 0, 0, 340, + 0, 0, 0, 628, 0, 629, 0, 629, 8, 8, 194, 8, 630, 0, 0, 0, + 0, 0, 0, 0, 627, 124, 124, 124, 0, 0, 0, 0, 0, 0, 0, 631, + 0, 0, 632, 0, 0, 0, 633, 634, 635, 0, 636, 0, 0, 0, 234, 124, + 11, 11, 11, 11, 637, 124, 124, 124, 124, 124, 124, 124, 0, 627, 0, 627, + 0, 0, 0, 0, 0, 638, 0, 639, 0, 0, 0, 0, 0, 223, 0, 0, + 0, 640, 641, 642, 643, 0, 0, 0, 644, 645, 0, 646, 647, 648, 0, 0, + 0, 0, 649, 0, 0, 0, 0, 0, 0, 0, 0, 0, 650, 0, 0, 0, + 651, 651, 651, 651, 651, 651, 651, 651, 652, 653, 654, 124, 124, 124, 124, 124, + 4, 655, 656, 124, 124, 124, 124, 124, 657, 658, 659, 14, 14, 14, 660, 124, + 661, 124, 124, 124, 124, 124, 124, 124, 662, 662, 663, 664, 665, 124, 124, 124, + 124, 666, 667, 124, 668, 668, 668, 669, 124, 124, 124, 124, 124, 670, 670, 671, + 124, 124, 124, 124, 124, 672, 672, 673, 124, 124, 124, 124, 674, 675, 674, 676, + 124, 124, 124, 124, 124, 124, 677, 678, 679, 679, 679, 679, 679, 679, 679, 679, + 679, 679, 679, 679, 680, 681, 124, 124, 682, 682, 682, 682, 683, 684, 124, 124, + 124, 124, 124, 124, 124, 124, 124, 324, 0, 0, 0, 685, 124, 124, 124, 124, + 324, 0, 0, 245, 124, 124, 124, 124, 686, 27, 687, 688, 689, 690, 691, 692, + 693, 694, 695, 694, 124, 124, 124, 696, 0, 0, 348, 0, 0, 0, 0, 0, + 0, 627, 225, 324, 324, 324, 0, 631, 0, 0, 245, 124, 124, 124, 697, 0, + 698, 0, 0, 348, 639, 227, 631, 124, 0, 0, 0, 0, 0, 699, 340, 340, + 0, 0, 0, 0, 0, 233, 348, 629, 348, 0, 0, 0, 700, 233, 0, 0, + 700, 0, 245, 348, 227, 639, 124, 124, 0, 0, 0, 0, 0, 700, 245, 340, + 701, 0, 0, 0, 702, 703, 704, 639, 0, 320, 0, 0, 0, 0, 0, 234, + 246, 246, 246, 246, 246, 246, 124, 124, 246, 312, 246, 246, 246, 246, 246, 246, + 246, 246, 312, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 705, 246, + 246, 246, 246, 246, 246, 312, 124, 124, 246, 312, 124, 124, 124, 124, 124, 124, + 246, 246, 246, 246, 706, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 313, + 707, 124, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 1, 2, 2, 2, + 2, 2, 3, 0, 0, 0, 4, 0, 2, 2, 2, 2, 2, 3, 2, 2, + 2, 2, 5, 0, 2, 5, 6, 0, 7, 7, 7, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 8, 8, 8, 8, 16, 8, 8, 8, 17, 18, 18, 18, + 19, 19, 19, 19, 19, 20, 19, 19, 21, 22, 22, 22, 22, 22, 22, 22, + 22, 23, 21, 22, 22, 22, 23, 21, 24, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 12, 12, 25, 25, 26, 27, 25, 28, 12, 12, 29, 30, 29, 31, + 29, 29, 32, 32, 29, 29, 29, 29, 31, 29, 33, 7, 7, 34, 29, 29, + 35, 29, 29, 29, 29, 29, 29, 30, 36, 36, 36, 37, 36, 36, 36, 36, + 36, 36, 38, 39, 40, 40, 40, 40, 41, 12, 12, 12, 42, 42, 42, 42, + 42, 42, 43, 44, 45, 45, 45, 45, 45, 45, 45, 46, 45, 45, 45, 47, + 48, 48, 48, 48, 48, 48, 48, 49, 36, 36, 38, 12, 50, 51, 29, 29, + 52, 29, 29, 29, 53, 53, 53, 53, 54, 55, 53, 53, 53, 56, 53, 53, + 57, 58, 57, 59, 59, 57, 57, 57, 57, 57, 60, 57, 61, 62, 63, 57, + 57, 59, 59, 64, 12, 65, 12, 66, 57, 62, 57, 57, 57, 57, 57, 64, + 67, 67, 68, 69, 70, 71, 71, 71, 71, 71, 72, 71, 72, 73, 74, 72, + 68, 69, 70, 74, 75, 12, 67, 76, 12, 77, 71, 71, 71, 68, 12, 12, + 78, 78, 79, 80, 80, 79, 79, 79, 79, 79, 81, 79, 81, 78, 82, 79, + 79, 80, 80, 82, 83, 12, 12, 12, 79, 84, 79, 79, 82, 12, 78, 79, + 85, 85, 86, 87, 87, 86, 86, 86, 86, 86, 88, 86, 88, 85, 89, 86, + 86, 87, 87, 89, 12, 85, 12, 90, 86, 91, 86, 86, 86, 86, 12, 12, + 92, 93, 94, 92, 95, 96, 97, 95, 98, 99, 94, 92, 100, 100, 96, 92, + 94, 92, 95, 96, 99, 98, 12, 12, 12, 92, 100, 100, 100, 100, 94, 12, + 101, 101, 101, 102, 102, 101, 101, 101, 101, 101, 102, 101, 101, 101, 103, 101, + 101, 102, 102, 103, 12, 104, 105, 103, 101, 106, 101, 101, 12, 107, 101, 101, + 108, 108, 108, 109, 109, 108, 108, 108, 108, 108, 109, 108, 108, 110, 111, 108, + 108, 109, 109, 111, 12, 112, 12, 113, 108, 114, 108, 108, 110, 12, 12, 12, + 115, 115, 115, 116, 116, 115, 115, 115, 115, 115, 115, 115, 115, 116, 116, 115, + 12, 115, 115, 115, 115, 117, 115, 115, 118, 118, 119, 119, 119, 120, 121, 119, + 119, 119, 119, 119, 122, 119, 119, 123, 119, 120, 124, 125, 119, 126, 119, 119, + 12, 121, 119, 119, 121, 127, 12, 12, 128, 129, 129, 129, 129, 129, 129, 129, + 129, 129, 130, 131, 129, 129, 129, 12, 12, 12, 12, 12, 132, 133, 134, 135, + 135, 135, 135, 135, 135, 136, 135, 135, 135, 135, 135, 137, 135, 138, 135, 134, + 135, 135, 137, 135, 139, 139, 139, 139, 139, 139, 140, 139, 139, 139, 139, 141, + 140, 139, 139, 139, 139, 139, 139, 142, 139, 143, 144, 12, 145, 145, 145, 145, + 146, 146, 146, 146, 146, 147, 12, 148, 146, 146, 149, 146, 150, 150, 150, 150, + 151, 151, 151, 151, 151, 151, 152, 153, 151, 154, 152, 153, 152, 153, 151, 154, + 152, 153, 151, 151, 151, 154, 151, 151, 151, 151, 154, 155, 151, 151, 151, 156, + 151, 151, 153, 12, 157, 157, 157, 157, 157, 158, 157, 158, 159, 159, 159, 159, + 160, 160, 160, 160, 160, 160, 160, 161, 162, 162, 162, 162, 162, 162, 163, 164, + 162, 162, 165, 12, 166, 166, 166, 166, 166, 167, 12, 168, 169, 169, 169, 169, + 169, 170, 12, 12, 171, 171, 171, 171, 171, 12, 12, 12, 172, 172, 172, 173, + 173, 12, 12, 12, 174, 174, 174, 174, 174, 174, 174, 175, 174, 174, 175, 12, + 176, 177, 178, 178, 178, 178, 179, 12, 178, 178, 178, 178, 178, 178, 180, 12, + 178, 178, 181, 12, 159, 182, 12, 12, 183, 183, 183, 183, 183, 183, 183, 184, + 183, 183, 183, 12, 185, 183, 183, 183, 186, 186, 186, 186, 186, 186, 186, 187, + 186, 188, 12, 12, 189, 189, 189, 189, 189, 189, 189, 12, 189, 189, 190, 12, + 189, 189, 191, 192, 193, 193, 193, 193, 193, 193, 193, 194, 195, 195, 195, 195, + 195, 195, 195, 196, 195, 195, 195, 197, 195, 195, 198, 12, 195, 195, 195, 198, + 7, 7, 7, 199, 7, 7, 7, 12, 200, 200, 200, 200, 200, 200, 200, 201, + 202, 202, 202, 202, 203, 203, 203, 203, 203, 12, 12, 203, 204, 204, 204, 204, + 204, 204, 205, 204, 204, 204, 206, 207, 208, 208, 208, 208, 19, 19, 209, 12, + 146, 146, 210, 211, 202, 202, 12, 12, 212, 7, 7, 7, 213, 7, 214, 215, + 0, 214, 216, 12, 2, 217, 218, 2, 2, 2, 2, 219, 220, 217, 221, 2, + 2, 2, 222, 2, 2, 2, 2, 223, 8, 224, 8, 224, 8, 8, 225, 225, + 8, 8, 8, 224, 8, 15, 8, 8, 8, 10, 8, 226, 10, 15, 8, 14, + 0, 0, 0, 227, 0, 228, 0, 0, 229, 0, 0, 230, 0, 0, 0, 231, + 2, 2, 2, 232, 233, 12, 12, 12, 234, 12, 12, 12, 0, 235, 236, 0, + 4, 0, 0, 0, 0, 0, 0, 4, 2, 2, 5, 12, 0, 0, 233, 12, + 0, 0, 231, 12, 237, 237, 237, 237, 0, 238, 0, 0, 239, 239, 239, 239, + 18, 18, 18, 18, 18, 12, 240, 18, 241, 241, 241, 241, 241, 241, 12, 242, + 243, 12, 12, 242, 151, 154, 12, 12, 151, 154, 151, 154, 0, 0, 0, 233, + 244, 244, 244, 244, 244, 244, 245, 244, 244, 12, 12, 12, 244, 246, 12, 12, + 0, 247, 0, 0, 248, 244, 249, 250, 0, 0, 244, 0, 251, 252, 252, 252, + 252, 252, 252, 252, 252, 253, 254, 255, 256, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 258, 256, 12, 259, 260, 260, 260, 260, 260, 260, 261, 150, 150, 150, + 150, 150, 150, 262, 0, 233, 12, 131, 150, 150, 150, 263, 257, 257, 257, 258, + 257, 257, 0, 0, 264, 264, 264, 264, 264, 264, 264, 265, 264, 266, 12, 12, + 267, 267, 267, 267, 268, 268, 268, 268, 268, 268, 268, 12, 269, 269, 269, 269, + 269, 269, 12, 12, 236, 2, 2, 2, 2, 2, 230, 2, 270, 2, 2, 2, + 271, 271, 271, 271, 271, 271, 271, 272, 273, 273, 273, 273, 273, 273, 12, 12, + 274, 274, 274, 274, 274, 275, 12, 276, 274, 274, 275, 12, 277, 277, 277, 277, + 277, 277, 277, 278, 279, 279, 279, 279, 279, 12, 12, 280, 150, 150, 150, 281, + 282, 282, 282, 282, 282, 282, 282, 283, 282, 282, 284, 285, 145, 145, 145, 286, + 287, 287, 287, 287, 287, 288, 12, 12, 287, 287, 287, 289, 287, 287, 289, 287, + 290, 290, 290, 290, 291, 12, 12, 12, 12, 12, 292, 290, 293, 293, 293, 293, + 293, 294, 12, 12, 155, 154, 155, 154, 155, 154, 12, 12, 2, 2, 3, 2, + 2, 295, 296, 12, 293, 293, 293, 297, 293, 293, 297, 12, 150, 12, 12, 12, + 150, 262, 298, 150, 150, 150, 150, 12, 244, 244, 244, 246, 244, 244, 246, 12, + 2, 299, 12, 12, 300, 22, 12, 24, 25, 26, 25, 301, 302, 303, 25, 25, + 29, 29, 29, 304, 7, 7, 7, 305, 231, 0, 0, 0, 0, 231, 0, 12, + 29, 306, 29, 29, 29, 29, 29, 307, 308, 0, 0, 0, 0, 309, 257, 257, + 257, 257, 257, 310, 311, 150, 311, 150, 311, 150, 311, 281, 0, 231, 0, 231, + 12, 12, 308, 233, 312, 312, 312, 313, 312, 312, 312, 312, 312, 314, 312, 312, + 312, 312, 314, 315, 312, 312, 312, 316, 312, 312, 314, 12, 231, 131, 0, 0, + 0, 131, 0, 0, 8, 8, 8, 14, 0, 0, 0, 317, 318, 12, 12, 12, + 0, 0, 0, 319, 320, 320, 320, 320, 320, 320, 320, 321, 322, 322, 322, 322, + 323, 12, 12, 12, 214, 0, 0, 0, 0, 0, 0, 12, 324, 324, 324, 324, + 324, 12, 12, 325, 326, 326, 326, 326, 326, 326, 327, 12, 328, 328, 328, 328, + 328, 328, 329, 12, 330, 330, 330, 330, 330, 330, 330, 331, 332, 332, 332, 332, + 332, 12, 332, 332, 332, 333, 12, 12, 334, 334, 334, 334, 335, 335, 335, 335, + 336, 336, 336, 336, 336, 336, 336, 337, 336, 336, 337, 12, 338, 338, 338, 338, + 338, 12, 338, 338, 338, 338, 338, 12, 339, 339, 339, 339, 339, 339, 12, 12, + 340, 340, 340, 340, 340, 12, 12, 341, 342, 342, 343, 342, 343, 344, 342, 342, + 344, 342, 342, 342, 344, 342, 344, 345, 346, 346, 346, 346, 346, 12, 12, 12, + 347, 347, 347, 347, 347, 348, 12, 12, 347, 349, 12, 12, 347, 347, 12, 12, + 2, 350, 2, 2, 351, 2, 299, 12, 352, 353, 354, 352, 352, 352, 352, 352, + 352, 355, 356, 357, 358, 358, 358, 358, 358, 359, 358, 358, 360, 360, 360, 360, + 361, 361, 361, 361, 361, 361, 361, 362, 12, 363, 361, 361, 364, 364, 364, 364, + 365, 366, 367, 364, 368, 368, 368, 368, 368, 368, 368, 369, 370, 370, 370, 370, + 370, 370, 371, 372, 373, 373, 373, 373, 373, 373, 374, 12, 375, 375, 375, 375, + 376, 376, 376, 376, 376, 376, 12, 376, 377, 376, 376, 376, 378, 379, 12, 378, + 378, 380, 380, 378, 378, 378, 378, 378, 378, 381, 382, 383, 378, 378, 384, 12, + 385, 385, 385, 385, 386, 386, 386, 386, 387, 387, 387, 387, 387, 388, 389, 387, + 387, 388, 12, 12, 390, 390, 390, 390, 390, 391, 392, 390, 393, 393, 393, 393, + 393, 394, 393, 393, 395, 395, 395, 395, 396, 12, 395, 395, 397, 397, 397, 397, + 398, 12, 399, 400, 12, 12, 399, 397, 401, 401, 401, 401, 401, 401, 402, 12, + 403, 403, 403, 403, 404, 12, 12, 12, 404, 12, 405, 403, 406, 406, 406, 406, + 406, 406, 12, 12, 406, 406, 407, 12, 408, 408, 408, 408, 408, 409, 410, 408, + 408, 409, 12, 411, 29, 29, 29, 412, 413, 413, 413, 413, 413, 413, 414, 415, + 415, 12, 12, 12, 416, 29, 12, 12, 29, 29, 417, 12, 12, 12, 416, 29, + 418, 418, 418, 418, 418, 418, 12, 12, 419, 419, 419, 419, 419, 419, 420, 12, + 421, 421, 421, 421, 421, 421, 422, 12, 423, 423, 423, 423, 423, 423, 423, 12, + 424, 424, 424, 424, 424, 425, 12, 12, 426, 426, 426, 426, 426, 426, 426, 427, + 428, 426, 426, 426, 426, 427, 12, 429, 430, 430, 430, 430, 431, 12, 12, 432, + 433, 433, 433, 433, 433, 433, 434, 12, 433, 433, 435, 12, 436, 436, 436, 436, + 436, 437, 436, 436, 436, 436, 12, 12, 438, 438, 438, 438, 438, 439, 12, 12, + 440, 440, 440, 440, 118, 119, 119, 119, 119, 127, 12, 12, 441, 441, 441, 441, + 442, 441, 441, 441, 443, 12, 12, 12, 444, 445, 446, 447, 444, 444, 444, 447, + 444, 444, 448, 12, 449, 449, 449, 449, 449, 449, 450, 12, 449, 449, 451, 12, + 452, 453, 452, 454, 454, 452, 452, 452, 452, 452, 455, 452, 455, 453, 456, 452, + 452, 454, 454, 457, 458, 459, 12, 453, 452, 460, 452, 458, 452, 458, 12, 12, + 461, 461, 462, 463, 461, 461, 461, 461, 461, 462, 461, 461, 464, 465, 466, 461, + 461, 462, 467, 12, 468, 12, 12, 12, 469, 469, 469, 469, 469, 469, 469, 470, + 471, 12, 12, 12, 472, 472, 472, 472, 472, 472, 12, 12, 472, 472, 473, 12, + 474, 474, 474, 474, 474, 475, 474, 474, 474, 474, 474, 475, 476, 476, 476, 476, + 476, 477, 12, 12, 476, 476, 478, 12, 178, 178, 178, 180, 479, 479, 479, 479, + 479, 479, 480, 12, 145, 12, 12, 12, 481, 481, 481, 481, 481, 481, 482, 483, + 481, 481, 481, 12, 481, 482, 12, 12, 484, 484, 484, 484, 484, 484, 484, 12, + 485, 485, 485, 485, 486, 12, 12, 487, 488, 489, 490, 488, 488, 491, 488, 488, + 488, 488, 488, 488, 488, 492, 493, 488, 488, 489, 12, 12, 488, 488, 494, 12, + 495, 495, 496, 495, 495, 495, 495, 495, 495, 497, 12, 12, 498, 498, 498, 498, + 498, 498, 12, 12, 499, 499, 499, 499, 500, 12, 12, 12, 501, 501, 501, 501, + 501, 501, 502, 12, 53, 53, 503, 12, 440, 440, 12, 12, 504, 504, 504, 504, + 505, 12, 12, 12, 504, 504, 505, 12, 506, 506, 507, 506, 506, 506, 506, 506, + 506, 508, 506, 506, 506, 509, 12, 12, 506, 506, 506, 510, 511, 511, 511, 511, + 512, 511, 511, 511, 511, 511, 513, 511, 511, 514, 12, 12, 515, 516, 517, 515, + 515, 515, 515, 515, 515, 516, 518, 517, 515, 515, 12, 12, 515, 515, 519, 12, + 520, 521, 522, 520, 520, 520, 520, 520, 520, 520, 520, 523, 521, 520, 524, 12, + 520, 520, 525, 12, 526, 526, 526, 526, 526, 526, 526, 12, 526, 526, 527, 12, + 528, 528, 528, 528, 528, 528, 529, 12, 530, 530, 530, 530, 531, 530, 530, 530, + 530, 530, 532, 533, 530, 530, 532, 12, 534, 12, 12, 12, 100, 100, 100, 100, + 96, 12, 12, 98, 535, 535, 535, 535, 535, 535, 536, 12, 535, 535, 535, 537, + 535, 538, 12, 12, 535, 12, 12, 12, 539, 539, 539, 539, 540, 12, 12, 12, + 541, 541, 541, 541, 541, 542, 12, 12, 541, 541, 543, 12, 544, 544, 544, 544, + 544, 545, 12, 12, 546, 546, 546, 546, 546, 546, 547, 12, 269, 269, 548, 12, + 549, 549, 549, 549, 549, 549, 549, 550, 549, 549, 551, 552, 553, 553, 553, 553, + 553, 553, 553, 554, 553, 553, 555, 12, 556, 556, 556, 556, 556, 556, 556, 557, + 556, 557, 12, 12, 558, 558, 558, 558, 558, 559, 12, 12, 558, 558, 560, 558, + 560, 558, 558, 558, 558, 558, 12, 561, 562, 562, 562, 562, 562, 562, 563, 12, + 564, 564, 564, 564, 564, 564, 565, 12, 566, 566, 566, 566, 566, 566, 567, 566, + 566, 12, 12, 12, 568, 568, 568, 568, 568, 568, 569, 570, 568, 568, 12, 570, + 571, 572, 12, 12, 244, 573, 12, 12, 574, 574, 574, 574, 575, 575, 575, 575, + 575, 576, 12, 12, 12, 12, 12, 577, 574, 574, 574, 578, 578, 12, 12, 12, + 257, 579, 257, 580, 581, 252, 252, 252, 582, 12, 12, 12, 583, 12, 12, 12, + 253, 584, 12, 12, 12, 257, 12, 12, 585, 585, 585, 585, 585, 585, 585, 12, + 586, 586, 586, 586, 586, 586, 587, 12, 586, 586, 586, 588, 586, 586, 588, 12, + 586, 586, 589, 586, 0, 12, 12, 12, 0, 12, 238, 0, 317, 12, 12, 12, + 7, 590, 12, 12, 0, 233, 12, 12, 0, 231, 308, 0, 0, 591, 227, 0, + 0, 0, 591, 7, 212, 592, 7, 0, 0, 0, 593, 227, 8, 224, 12, 12, + 0, 231, 12, 12, 0, 0, 317, 12, 0, 0, 0, 228, 594, 595, 308, 228, + 0, 0, 596, 308, 0, 308, 0, 0, 0, 596, 231, 308, 0, 228, 0, 228, + 0, 0, 596, 231, 0, 597, 238, 0, 228, 0, 0, 0, 0, 233, 0, 0, + 0, 0, 0, 238, 598, 598, 598, 598, 598, 598, 598, 12, 12, 12, 599, 598, + 600, 598, 598, 598, 2, 2, 2, 299, 12, 270, 299, 12, 239, 601, 239, 239, + 239, 239, 602, 239, 603, 604, 601, 12, 19, 19, 19, 605, 12, 12, 12, 606, + 607, 607, 607, 607, 607, 607, 607, 608, 607, 607, 607, 609, 607, 607, 609, 610, + 611, 611, 611, 611, 611, 611, 611, 612, 613, 613, 613, 613, 613, 613, 614, 615, + 616, 616, 616, 616, 616, 616, 617, 12, 618, 618, 618, 618, 618, 618, 619, 620, + 621, 621, 621, 621, 621, 621, 621, 622, 621, 623, 12, 624, 151, 154, 151, 625, + 151, 151, 151, 154, 626, 626, 626, 626, 626, 627, 626, 626, 626, 628, 12, 12, + 629, 629, 629, 629, 629, 629, 629, 12, 629, 629, 630, 631, 0, 317, 12, 12, + 29, 632, 29, 29, 633, 634, 632, 29, 412, 29, 635, 12, 636, 51, 635, 632, + 633, 634, 635, 635, 633, 634, 412, 29, 412, 29, 632, 637, 29, 29, 638, 29, + 29, 29, 29, 12, 632, 632, 638, 29, 50, 12, 12, 12, 12, 238, 0, 0, + 639, 12, 12, 12, 0, 0, 317, 0, 0, 0, 12, 12, 0, 0, 231, 238, + 0, 231, 317, 308, 0, 0, 0, 640, 0, 0, 231, 131, 641, 12, 12, 12, + 244, 244, 573, 12, 642, 12, 12, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 939, 940, 941, 942, 946, 948, 0, 962, 969, 970, 971, 976,1001,1002,1003,1008, 0,1033,1040,1041,1042,1043,1047, 0, 0,1080,1081,1082,1086,1110, 0, 0,1124,1125,1126,1127,1131,1133, 0,1147, @@ -5507,11 +4360,11 @@ static const int16_t _hb_ucd_i16[92]= static inline uint8_t _hb_ucd_gc (unsigned u) { - return u<1114112 ? _hb_ucd_u8[5208u+(((_hb_ucd_u8[1168u+(((_hb_ucd_u16[((_hb_ucd_u8[544u+(((_hb_ucd_u8[u>>1>>3>>3>>4])<<4)+((u>>1>>3>>3)&15))])<<3)+((u>>1>>3)&7)])<<3)+((u>>1)&7))])<<1)+((u)&1))] : 2; + return u<1114110 ? _hb_ucd_u8[6560u+((_hb_ucd_u8[816u+((_hb_ucd_u16[((_hb_ucd_u8[272u+((_hb_ucd_u8[((((((((u)>>1))>>3))>>4))>>4)])<<4)+((((((((u)>>1))>>3))>>4))&15)])<<4)+((((((u)>>1))>>3))&15)])<<3)+((((u)>>1))&7)])<<1)+((u)&1)] : 2; } static inline uint8_t _hb_ucd_ccc (unsigned u) { - return u<125259 ? _hb_ucd_u8[7206u+(((_hb_ucd_u8[6638u+(((_hb_ucd_u8[6162u+(((_hb_ucd_u8[5802u+(((_hb_ucd_u8[5556u+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7))])<<2)+((u>>2>>2)&3))])<<2)+((u>>2)&3))])<<2)+((u)&3))] : 0; + return u<125259 ? _hb_ucd_u8[8620u+((_hb_ucd_u8[8036u+((_hb_ucd_u8[7556u+((_hb_ucd_u8[7188u+((_hb_ucd_u8[6942u+((((((((u)>>2))>>2))>>2))>>3)])<<3)+((((((((u)>>2))>>2))>>2))&7)])<<2)+((((((u)>>2))>>2))&3)])<<2)+((((u)>>2))&3)])<<2)+((u)&3)] : 0; } static inline uint8_t _hb_ucd_b4 (const uint8_t* a, unsigned i) { @@ -5519,15 +4372,1252 @@ static inline uint8_t _hb_ucd_b4 (const uint8_t* a, unsigned i) } static inline int16_t _hb_ucd_bmg (unsigned u) { - return u<65380 ? _hb_ucd_i16[((_hb_ucd_u8[8098u+(((_hb_ucd_u8[7866u+(((_hb_ucd_u8[7770u+(((_hb_ucd_b4(_hb_ucd_u8+7706u,u>>1>>2>>3>>3))<<3)+((u>>1>>2>>3)&7))])<<3)+((u>>1>>2)&7))])<<2)+((u>>1)&3))])<<1)+((u)&1)] : 0; + return u<65380 ? _hb_ucd_i16[((_hb_ucd_u8[9516u+((_hb_ucd_u8[9284u+((_hb_ucd_u8[9188u+((_hb_ucd_b4(_hb_ucd_u8+9124u,((((((((u)>>1))>>2))>>3))>>3)))<<3)+((((((((u)>>1))>>2))>>3))&7)])<<3)+((((((u)>>1))>>2))&7)])<<2)+((((u)>>1))&3)])<<1)+((u)&1)] : 0; } static inline uint8_t _hb_ucd_sc (unsigned u) { - return u<918016 ? _hb_ucd_u8[11464u+(((_hb_ucd_u8[10472u+(((_hb_ucd_u8[9452u+(((_hb_ucd_u8[8764u+(((_hb_ucd_u8[8460u+(((_hb_ucd_u8[8346u+(u>>2>>2>>2>>3>>4)])<<4)+((u>>2>>2>>2>>3)&15))])<<3)+((u>>2>>2>>2)&7))])<<2)+((u>>2>>2)&3))])<<2)+((u>>2)&3))])<<2)+((u)&3))] : 2; + return u<918000 ? _hb_ucd_u8[10950u+((_hb_ucd_u16[4648u+((_hb_ucd_u16[2608u+((_hb_ucd_u8[10214u+((_hb_ucd_u8[9764u+((((((((u)>>2))>>2))>>3))>>4)])<<4)+((((((((u)>>2))>>2))>>3))&15)])<<3)+((((((u)>>2))>>2))&7)])<<2)+((((u)>>2))&3)])<<2)+((u)&3)] : 2; } static inline uint16_t _hb_ucd_dm (unsigned u) { - return u<195102 ? _hb_ucd_u16[1656u+(((_hb_ucd_u8[12834u+(((_hb_ucd_u8[12452u+(u>>4>>5)])<<5)+((u>>4)&31))])<<4)+((u)&15))] : 0; + return u<195102 ? _hb_ucd_u16[7480u+((_hb_ucd_u8[13904u+((_hb_ucd_u8[13522u+((((u)>>4))>>5)])<<5)+((((u)>>4))&31)])<<4)+((u)&15)] : 0; +} + + +#else + +#include + +static const uint8_t _hb_ucd_u8[13937]= +{ + 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 9, 10, 7, 7, 7, 7, 7, 11, 12, 12, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 7, 21, 22, 22, 22, 23, 24, 7, 7, + 7, 25, 22, 22, 22, 26, 27, 28, 22, 29, 30, 31, 32, 33, 34, 35, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 21, 22, 36, + 7, 7, 7, 7, 7, 7, 37, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 38, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 34, 34, 34, 35, 36, 37, 34, 34, 34, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 62, 63, 64, 65, 66, 67, 68, 69, 67, 70, 71, + 67, 67, 62, 72, 62, 62, 73, 67, 74, 75, 76, 77, 78, 67, 67, 67, + 79, 80, 34, 81, 82, 83, 67, 67, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 84, 34, 34, 34, 34, + 85, 34, 34, 34, 34, 34, 34, 34, 34, 86, 34, 34, 87, 88, 89, 90, + 91, 92, 93, 94, 95, 96, 97, 98, 34, 34, 34, 34, 34, 34, 34, 34, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, + 100,100, 34, 34, 34, 34,101,102, 34, 34,103,104,105,106,107,108, + 34, 34,109,110,111,112,113,114,115,116,117,118, 34, 34, 34,119, + 120,121,122,123,124,125,126,127, 34,128,129,130,131,132,133,134, + 135,136,137,138,139,140,141,142,143,144,111,145,146,147,148,111, + 149,150,151,152,153,154,155,156,157,158,159,160,111,161,162,163, + 34, 34, 34, 34, 34, 34, 34, 34,164, 34, 34,111,111,111,111,111, + 111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,165, + 34, 34, 34, 34, 34, 34, 34, 34,166, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,111,111,111, + 111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, + 111,111,167,111,111,111,111,111,111,111,111,111,111,111,111,111, + 34, 34, 34, 34,168,169,170, 34,111,111,171,111,172,173,174,175, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,111,111,111,111, + 111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,119, + 34, 34, 34, 34, 34, 34,111,111,111,111,111,111,111,111,111,111, + 111,111,111,111,111,111,111,111, 34,176,111,111,111,111,111,111, + 111,111,111,111,111,111,111,111, 67,177, 67, 67, 67,178,179, 67, + 67, 67,180,181,182,131, 65,111,183,184,185,186,187,188,189,190, + 67, 67, 67, 67,191,192,111,111,111,111,111,111,111,111,193,111, + 194,195,196,111,111,197,111,111,111,198,111,199,111,200,111, 34, + 34,201,202,111,111,111,111,111,131,203,204,111, 34,205,111,111, + 67, 67,206, 67, 67,111, 67,207, 67, 67, 67, 67, 67, 67, 67, 67, + 67,208, 67, 67, 67, 67, 67,177,111,111,111,111,111,111,111,111, + 34, 34, 34, 34, 34,111,111,111,111,111,111,111,111,111,111,111, + 34, 34, 34, 34, 34, 34, 34, 34, 34,111,111,111,111,111,111,111, + 209,111,195,195,111,111,111,111,111,111,111,111,111,111,111,111, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 2, 4, 5, 6, 2, + 7, 7, 7, 7, 7, 2, 8, 9, 10, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 17, 18, 19, 1, 20, 20, 21, 22, 23, 24, 25, + 26, 27, 15, 2, 28, 29, 27, 30, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 31, 11, 11, 11, 32, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 33, 16, 16, 16, 16, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 34, 34, 34, 34, 34, 34, 34, 34, 16, 32, 32, 32, + 32, 32, 32, 32, 11, 34, 34, 16, 34, 32, 32, 11, 34, 11, 16, 11, + 11, 34, 32, 11, 32, 16, 11, 34, 32, 32, 32, 11, 34, 16, 32, 11, + 34, 11, 34, 34, 32, 35, 32, 16, 36, 36, 37, 34, 38, 37, 34, 34, + 34, 34, 34, 34, 34, 34, 16, 32, 34, 38, 32, 11, 32, 32, 32, 32, + 32, 32, 16, 16, 16, 11, 34, 32, 34, 34, 11, 32, 32, 32, 32, 32, + 16, 16, 36, 16, 16, 16, 16, 16, 39, 39, 39, 39, 39, 39, 39, 39, + 39, 40, 40, 39, 39, 39, 39, 39, 39, 40, 40, 40, 40, 40, 40, 40, + 39, 39, 41, 40, 40, 40, 41, 41, 40, 40, 40, 40, 40, 40, 40, 40, + 42, 42, 42, 42, 42, 42, 42, 42, 32, 32, 41, 32, 16, 43, 16, 10, + 40, 40, 40, 44, 11, 11, 11, 11, 34, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 34, + 16, 11, 32, 16, 32, 32, 32, 32, 16, 16, 32, 45, 34, 32, 34, 11, + 32, 46, 42, 42, 47, 32, 32, 32, 11, 34, 34, 34, 34, 34, 34, 16, + 11, 11, 11, 11, 48, 2, 2, 2, 16, 16, 16, 16, 49, 50, 51, 52, + 53, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 54, + 55, 56, 42, 55, 42, 42, 42, 42, 36, 36, 36, 36, 36, 36, 36, 36, + 36, 57, 2, 2, 2, 2, 2, 2, 58, 58, 58, 8, 9, 59, 2, 60, + 42, 42, 42, 42, 42, 56, 61, 2, 62, 36, 36, 36, 36, 63, 42, 42, + 7, 7, 7, 7, 7, 2, 2, 36, 64, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 65, 42, 42, 42, 66, 46, 42, 42, 67, 68, 69, 42, 42, 36, + 7, 7, 7, 7, 7, 36, 70, 71, 2, 2, 2, 2, 2, 2, 2, 72, + 63, 36, 36, 36, 36, 36, 36, 36, 42, 42, 42, 42, 42, 42, 64, 36, + 36, 36, 36, 42, 42, 42, 42, 42, 7, 7, 7, 7, 7, 36, 36, 36, + 36, 36, 36, 36, 36, 63, 42, 42, 42, 42, 39, 21, 2, 39, 68, 20, + 36, 36, 36, 42, 42, 68, 42, 42, 42, 42, 68, 42, 68, 42, 42, 42, + 2, 2, 2, 2, 2, 2, 2, 2, 36, 36, 36, 36, 63, 42, 42, 2, + 36, 36, 36, 36, 73, 36, 36, 36, 58, 58, 58, 74, 42, 42, 42, 42, + 36, 36, 36, 36, 75, 42, 42, 42, 42, 74, 42, 42, 42, 42, 42, 42, + 42, 76, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 76, 64, 77, + 78, 42, 42, 42, 76, 77, 78, 77, 63, 42, 42, 42, 36, 36, 36, 36, + 36, 42, 2, 7, 7, 7, 7, 7, 79, 36, 36, 36, 36, 36, 36, 36, + 63, 77, 80, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 64, 77, + 78, 42, 42, 76, 77, 77, 78, 36, 36, 36, 36, 81, 77, 77, 36, 36, + 36, 42, 42, 7, 7, 7, 7, 7, 36, 20, 27, 27, 27, 52, 57, 42, + 42, 76, 80, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 42, 77, + 78, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 64, 36, 36, 36, + 36, 36, 36, 7, 7, 7, 7, 7, 42, 36, 63, 2, 2, 2, 2, 2, + 78, 42, 42, 42, 76, 77, 78, 42, 59, 20, 20, 20, 82, 42, 42, 42, + 42, 77, 80, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 64, 78, + 78, 42, 42, 76, 77, 77, 78, 42, 42, 42, 42, 76, 77, 77, 36, 36, + 71, 27, 27, 27, 27, 27, 27, 27, 42, 64, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 77, 76, 77, 77, 77, 77, 77, 78, 42, + 36, 36, 36, 81, 77, 77, 77, 77, 77, 77, 77, 7, 7, 7, 7, 7, + 27, 83, 60, 60, 52, 60, 60, 60, 76, 77, 64, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 64, 42, 76, 77, 77, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 36, 36, 36, 36, 7, 7, 7, 84, 27, 27, 27, 83, + 63, 77, 65, 36, 36, 36, 36, 36, 77, 77, 77, 76, 77, 77, 42, 42, + 42, 42, 76, 77, 77, 77, 36, 36, 85, 81, 77, 77, 77, 77, 77, 77, + 42, 77, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 63, 64, 77, + 78, 42, 42, 77, 77, 77, 78, 70, 60, 60, 36, 81, 27, 27, 27, 86, + 27, 27, 27, 27, 83, 36, 36, 36, 36, 36, 36, 36, 36, 42, 42, 76, + 77, 42, 42, 42, 77, 77, 77, 77, 7, 77, 2, 2, 2, 2, 2, 2, + 63, 36, 42, 42, 42, 42, 42, 87, 36, 36, 36, 68, 42, 42, 42, 56, + 7, 7, 7, 7, 7, 2, 2, 2, 63, 36, 42, 42, 42, 42, 64, 36, + 36, 36, 36, 39, 42, 42, 42, 42, 7, 7, 7, 7, 7, 7, 36, 36, + 70, 60, 2, 2, 2, 2, 2, 2, 2, 88, 88, 60, 42, 60, 60, 60, + 7, 7, 7, 7, 7, 27, 27, 27, 27, 27, 46, 46, 46, 4, 4, 77, + 63, 42, 42, 42, 42, 42, 42, 76, 42, 42, 56, 42, 36, 36, 63, 42, + 42, 42, 42, 42, 42, 42, 42, 60, 60, 60, 60, 69, 60, 60, 60, 60, + 2, 2, 88, 60, 21, 2, 2, 2, 36, 36, 36, 36, 36, 81, 78, 42, + 76, 42, 42, 42, 78, 76, 78, 64, 36, 36, 36, 77, 42, 36, 36, 42, + 64, 77, 80, 81, 77, 77, 77, 36, 63, 42, 64, 36, 36, 36, 36, 36, + 36, 76, 78, 76, 77, 77, 78, 81, 7, 7, 7, 7, 7, 77, 78, 60, + 16, 16, 16, 16, 16, 49, 43, 16, 36, 36, 36, 36, 36, 36, 63, 42, + 2, 2, 2, 2, 89, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 60, 60, 60, 60, 60, 60, 60, 60, 11, 11, 11, 11, 16, 16, 16, 16, + 90, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 70, 65, + 91, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 92, 93, 93, + 36, 36, 36, 36, 36, 57, 2, 94, 95, 36, 36, 36, 36, 36, 36, 36, + 36, 42, 76, 77, 77, 77, 77, 80, 36, 42, 96, 2, 2, 2, 2, 2, + 36, 42, 42, 42, 42, 42, 42, 42, 36, 36, 42, 78, 42, 42, 42, 77, + 77, 77, 77, 76, 78, 42, 42, 42, 42, 42, 2, 79, 2, 59, 63, 42, + 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 97, 2, 55, 42, 74, + 36, 75, 36, 36, 36, 36, 36, 36, 36, 36, 63, 64, 36, 36, 36, 36, + 36, 36, 36, 36, 63, 36, 36, 36, 42, 76, 77, 78, 76, 77, 77, 77, + 77, 76, 77, 77, 78, 42, 42, 42, 60, 60, 2, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 27, 27, 60, 36, 36, 36, 63, 76, 78, 42, 2, + 36, 36, 81, 76, 42, 42, 42, 42, 76, 76, 78, 42, 42, 42, 76, 77, + 77, 78, 42, 42, 42, 42, 42, 42, 2, 2, 2, 79, 2, 2, 2, 2, + 42, 42, 42, 42, 42, 42, 42, 98, 42, 42, 80, 36, 36, 36, 36, 36, + 36, 36, 76, 42, 42, 76, 76, 77, 77, 76, 80, 36, 36, 36, 36, 2, + 88, 60, 60, 60, 60, 46, 42, 42, 42, 42, 60, 60, 60, 60, 21, 2, + 42, 80, 36, 36, 36, 36, 36, 36, 81, 42, 42, 77, 42, 78, 42, 36, + 36, 36, 36, 76, 42, 77, 78, 78, 42, 77, 77, 77, 77, 77, 2, 2, + 36, 36, 77, 77, 77, 77, 42, 42, 42, 42, 77, 42, 42, 56, 2, 2, + 7, 7, 7, 7, 7, 7, 85, 36, 36, 36, 36, 36, 39, 39, 39, 2, + 16, 16, 16, 16, 34, 16, 16, 16, 42, 56, 42, 42, 42, 42, 42, 42, + 76, 42, 42, 42, 64, 36, 63, 36, 36, 36, 64, 81, 42, 36, 36, 36, + 16, 16, 16, 16, 16, 16, 39, 39, 39, 39, 39, 39, 39, 43, 16, 16, + 16, 16, 16, 16, 43, 16, 16, 16, 16, 16, 16, 16, 16, 99, 39, 39, + 32, 32, 32, 16, 16, 16, 16, 32, 16, 16, 16, 16, 11, 11, 11, 11, + 16, 16, 16, 16, 34, 11, 11, 11, 16, 16, 16, 16,100,100,100,100, + 16, 16, 16, 16, 11, 11,101,102, 40, 16, 16, 16, 11, 11,101, 40, + 16, 16, 16, 16, 11, 11,103, 40,104,104,104,104,104,105, 58, 58, + 50, 50, 50, 2,106,107,106,107, 2, 2, 2, 2,108, 58, 58,109, + 2, 2, 2, 2,110,111, 2,112,113, 2,114,115, 2, 2, 2, 2, + 2, 9,113, 2, 2, 2, 2,116, 58, 58, 58, 58, 58, 58, 58, 58, + 117, 39, 27, 27, 27, 8,114,118, 27, 27, 27, 27, 27, 8,114, 93, + 20, 20, 20, 20, 20, 20, 20, 20, 42, 42, 42, 42, 42, 42,119, 47, + 98, 47, 98, 42, 42, 42, 42, 42, 60,120, 60,121, 60, 34, 11, 16, + 11, 32,121, 60, 45, 11, 11, 60, 60, 60,120,120,120, 11, 11,122, + 11, 11, 35, 36,123, 60, 16, 11, 8, 8, 45, 16, 16, 26, 60,124, + 94, 94, 94, 94, 94, 94, 94, 94, 94,125,126, 94,127, 60, 60, 60, + 8, 8,128, 60, 60, 8, 60, 60,128, 26, 60,128, 60, 60, 60,128, + 60, 60, 60, 60, 60, 60, 60, 8, 60,128,128, 60, 60, 60, 60, 60, + 60, 60, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 60, 60, 60, 60, 4, 4, 60, 60, 8, 60, 60, 60,129,130, 60, 60, + 60, 60, 60, 60, 60, 60,128, 60, 60, 60, 60, 60, 60, 26, 8, 8, + 8, 8, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 8, 8, + 8, 60, 60, 60, 60, 60, 60, 60, 27, 27, 27, 27, 27, 27, 60, 60, + 60, 60, 60, 60, 60, 27, 27, 27, 60, 60, 60, 26, 60, 60, 60, 60, + 26, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 8, 8, 8, 8, + 60, 60, 60, 60, 60, 60, 60, 26, 60, 60, 60, 60, 4, 4, 4, 4, + 4, 4, 4, 27, 27, 27, 27, 27, 27, 27, 60, 60, 60, 60, 60, 60, + 8, 8,114,131, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, + 8,114,132,132,132,132,132,132,132,132,132,132,131, 8, 8, 8, + 8, 8, 8, 8, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 4, 8, + 8, 8,128, 26, 8, 8,128, 60, 32, 11, 32, 34, 34, 34, 34, 11, + 32, 32, 34, 16, 16, 16, 39, 11, 32, 32,124, 60, 60,121, 34,133, + 42, 32, 16, 16, 49, 2, 89, 2, 36, 36, 36, 36, 36, 36, 36, 75, + 2, 2, 2, 2, 2, 2, 2, 55, 2,106,106, 2,110,111,106, 2, + 2, 2, 2, 6, 2, 97,106, 2,106, 4, 4, 4, 4, 2, 2, 79, + 2, 2, 2, 2, 2, 50, 2, 2, 97,134, 2, 2, 2, 2, 2, 2, + 60, 2,135,132,132,132,136, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 1, 2,137,138, 4, 4, 4, 4, 4, 60, 4, 4, 4, 4,139, 93, + 140, 94, 94, 94, 94, 42, 42, 77,141, 39, 39, 60, 94,142, 57, 60, + 71, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 63,143,144, 62, + 36, 36, 36, 36, 36, 57, 39, 62, 60, 27, 27, 60, 60, 60, 60, 60, + 27, 27, 27, 27, 27, 60, 60, 60, 60, 60, 60, 60, 27, 27, 27, 27, + 145, 27, 27, 27, 27, 27, 27, 27, 36, 36, 75, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36,146, 2, 32, 32, 32, 32, 32, 32, 32, 63, + 47,147, 42, 42, 42, 42, 42, 79, 32, 32, 32, 32, 32, 32, 39, 42, + 36, 36, 36, 94, 94, 94, 94, 94, 42, 2, 2, 2, 2, 2, 2, 2, + 40, 40, 40,144, 39, 39, 39, 39, 40, 32, 32, 32, 32, 32, 32, 32, + 16, 32, 32, 32, 32, 32, 32, 32, 43, 16, 16, 16, 34, 34, 34, 32, + 32, 32, 32, 32, 41,148, 34, 35, 32, 32, 16, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 11, 11, 32, 11, 11, 32, 32, 32, 32, 32, 32, + 32, 32, 11, 11, 34, 34, 32, 32, 32, 32, 32, 32, 32, 32, 11, 11, + 48, 39,149, 35, 39, 35, 36, 36, 36, 64, 36, 64, 36, 63, 36, 36, + 36, 81, 78, 76, 60, 60, 42, 42, 27, 27, 27, 60,150, 60, 60, 60, + 36, 36, 2, 2, 2, 2, 2, 2, 77, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 77, 77, 77, 77, 77, 77, 77, 77, 42, 42, 42, 42, 42, 2, + 42, 36, 36, 36, 2, 65, 65, 63, 36, 36, 36, 42, 42, 42, 42, 2, + 36, 36, 36, 63, 42, 42, 42, 42, 42, 77, 77, 77, 77, 77, 77, 96, + 36, 63, 77, 42, 42, 77, 42, 77, 96, 2, 2, 2, 2, 2, 2, 79, + 7, 7, 7, 7, 7, 7, 7, 2, 36, 36, 63, 62, 36, 36, 36, 36, + 36, 36, 36, 36, 63, 42, 42, 76, 78, 76, 78, 42, 42, 42, 42, 42, + 36, 63, 36, 36, 36, 36, 76, 77, 7, 7, 7, 7, 7, 7, 2, 2, + 62, 36, 36, 70, 60, 81, 76, 36, 64, 42, 64, 63, 64, 36, 36, 42, + 36, 36, 36, 36, 36, 36, 75, 2, 36, 36, 36, 36, 36, 81, 42, 77, + 2, 75,151, 42, 42, 42, 42, 42, 16, 16, 16, 16, 16,102, 39, 39, + 16, 16, 16, 16, 99, 40, 40, 40, 36, 81, 78, 77, 76, 96, 78, 42, + 152,152,152,152,152,152,152,152,153,153,153,153,153,153,153,153, + 16, 16, 16, 16, 16, 16, 35, 64, 36, 36, 36, 36,154, 36, 36, 36, + 36, 40, 40, 40, 40, 40, 40, 40, 40, 22, 60, 60, 60, 60, 60, 60, + 60, 71, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,132, + 60, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 60, 60, 60, 60, + 36, 36, 36, 36, 36, 36,150, 60, 2, 2, 2,135,115, 2, 2, 2, + 6,155,156,132,132,132,132,132,132,132,115,135,115, 2,112,157, + 2, 2, 2, 2,139,132,132,115, 2,158, 8, 8, 59, 2, 2, 2, + 36, 36, 36, 36, 36, 36, 36,159, 2, 2, 3, 2, 4, 5, 6, 2, + 16, 16, 16, 16, 16, 17, 18,114,115, 4, 2, 36, 36, 36, 36, 36, + 62, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 39, + 20,160, 52, 20, 26, 8,128, 60, 60, 60, 60, 60,161, 58, 60, 60, + 2, 2, 2, 89, 27, 27, 27, 27, 27, 27, 27, 83, 60, 60, 60, 60, + 94, 94,127, 27, 83, 60, 60, 60, 60, 60, 60, 60, 60, 27, 60, 60, + 60, 60, 60, 60, 60, 60, 46, 42,162,162,162,162,162,162,162,162, + 163, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 86, 36, + 138, 36, 36, 36, 36, 94, 94, 94, 36, 36, 36, 36, 36, 36, 36, 57, + 164, 94, 94, 94, 94, 94, 94, 94, 11, 11, 11, 32, 16, 16, 16, 16, + 36, 36, 36, 57, 27, 27, 27, 27, 36, 36, 36, 70,145, 27, 27, 27, + 36, 36, 36,165, 27, 27, 27, 27, 36, 36, 36, 36, 36,165, 27, 27, + 36, 36, 36, 27, 27, 27, 27, 30, 36, 36, 36, 36, 36, 36, 27, 36, + 63, 42, 42, 42, 42, 42, 42, 42, 36, 36, 36, 36, 42, 42, 42, 42, + 36, 36, 36, 36, 36, 36,165, 30, 36, 36, 36, 36, 36, 36,165, 27, + 36, 36, 36, 36, 71, 36, 36, 36, 36, 36, 63, 42, 42,163, 27, 27, + 36, 36, 36, 36, 57, 2, 2, 2, 36, 36, 36, 36, 27, 27, 27, 27, + 16, 16, 16, 16, 16, 27, 27, 27, 36, 36, 42, 42, 42, 42, 42, 42, + 7, 7, 7, 7, 7, 36, 36, 62, 11, 11, 11, 11,166, 42, 42,141, + 16, 16, 16, 16, 16, 16, 16, 8, 36, 36, 36, 36, 36, 63,167, 50, + 88, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 42, 42, 42, + 27, 27, 27, 86, 36, 36, 36, 36,163, 27, 30, 2, 2, 2, 2, 2, + 36, 42, 42, 2, 2, 2, 2, 2, 36, 36,165, 27, 27, 27, 27, 27, + 78, 80, 36, 36, 36, 36, 36, 36, 42, 42, 42, 56, 2, 2, 2, 2, + 2, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 7, 7, 7, 7, 7, + 64, 63, 64, 36, 36, 36, 36, 63, 77, 78, 42, 76, 78, 56, 72, 2, + 2, 42, 42, 42, 42, 42, 66, 58, 36, 36, 36, 63, 42, 42, 78, 42, + 42, 42, 42, 7, 7, 7, 7, 7, 2, 2, 81, 80, 36, 36, 36, 36, + 36, 63, 2, 36, 36, 36, 36, 36, 36, 81, 77, 42, 42, 42, 42, 76, + 80, 36, 57, 2, 55, 42, 56, 78, 7, 7, 7, 7, 7, 57, 57, 2, + 89, 27, 27, 27, 27, 27, 27, 27, 36, 36, 36, 36, 36, 36, 77, 78, + 42, 77, 76, 42, 2, 2, 2, 64, 36, 36, 36, 36, 36, 36, 36, 63, + 76, 77, 77, 77, 77, 77, 77, 77, 36, 36, 36, 81, 77, 77, 80, 36, + 36, 77, 77, 42, 42, 42, 42, 42, 36, 36, 36, 36, 77, 78, 42, 42, + 42, 77, 77, 77, 77, 77, 77, 76, 64, 64, 2, 2, 2, 2, 2, 2, + 55, 42, 42, 42, 42, 42, 42, 42, 36, 36, 81, 77, 42, 42, 42, 42, + 77, 42, 76, 64, 36, 57, 2, 2, 7, 7, 7, 7, 7, 2, 2, 64, + 77, 78, 42, 42, 76, 76, 77, 78, 76, 42, 36, 65, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 81, 77, 42, 42, 42, 77, 77, 42, 78, + 56, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 36, 36, 42, 42, + 77, 78, 42, 42, 42, 76, 78, 78, 56, 2, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 63, 78, 77, 42, 42, 42, 78, 57, 2, 2, 2, + 36, 36, 36, 36, 36, 36, 63, 78, 77, 42, 42, 78, 42, 42, 42, 42, + 7, 7, 7, 7, 7, 27, 2, 88, 42, 42, 42, 42, 78, 56, 2, 2, + 27, 27, 27, 27, 27, 27, 27, 86, 77, 77, 77, 77, 77, 78, 76, 64, + 80, 78, 2, 2, 2, 2, 2, 2, 81, 77, 42, 42, 42, 42, 77, 77, + 64, 65, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 63, 42, 42, 42, 42, 64, 36, 36, 36, 63, 42, 42, 76, 63, 42, 56, + 2, 2, 2, 55, 42, 42, 42, 42, 63, 42, 42, 76, 78, 42, 36, 36, + 36, 36, 36, 36, 36, 42, 42, 42, 42, 42, 42, 76, 42, 2, 65, 2, + 76, 42, 76, 76, 77, 77, 77, 77, 57, 2, 2, 2, 2, 2, 2, 2, + 42, 42, 42, 42, 42, 42, 42, 78, 2, 36, 36, 36, 36, 36, 36, 36, + 42, 42, 42, 42, 76, 42, 42, 42, 76, 42, 78, 42, 42, 42, 42, 42, + 42, 42, 42, 63, 42, 42, 42, 42, 36, 36, 36, 36, 36, 77, 77, 77, + 42, 76, 78, 78, 36, 36, 36, 36, 36, 36, 36, 36, 75, 36, 36, 36, + 36, 63, 76, 96, 2, 2, 2, 2, 42, 81, 36, 36, 36, 36, 36, 36, + 36, 36, 77, 42, 42, 42, 42, 77, 76, 56, 2, 2, 2, 2, 2, 2, + 7, 7, 7, 7, 7, 42, 42, 42, 27, 27, 83, 60, 60, 60, 52, 20, + 150, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 21, + 64, 36, 36, 63, 42, 42, 42, 42, 36, 36, 36, 36, 36, 36, 36, 42, + 42, 42, 42, 42, 42, 77, 78, 42, 42, 42, 56, 2, 2, 2, 2, 2, + 42, 42, 42, 56, 2, 2, 60, 60, 39, 39, 88, 60, 60, 60, 60, 60, + 7, 7, 7, 7, 7,168, 27, 27, 27, 86, 36, 36, 36, 36, 36, 36, + 39, 62, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 75,146, 2, + 27, 27, 27, 30, 2, 2, 2, 2, 11, 11, 11, 11, 11, 32, 16, 16, + 81, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 78, + 42, 67, 39, 39, 39, 39, 39, 39, 39, 79, 42, 42, 42, 42, 42, 42, + 77, 39, 94, 94, 94, 94, 94, 94, 36, 36, 36, 36, 36, 36, 46, 56, + 7, 7, 7, 7, 7, 60, 60, 60, 60, 60,169, 78, 42, 60,169, 77, + 77,170, 58, 58, 58, 74, 42, 42, 42, 69, 46, 42, 42, 42, 60, 60, + 60, 60, 60, 60, 60, 42, 42, 60, 60, 42, 69, 60, 60, 60, 60, 60, + 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 16, 11, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, + 31, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 33, 16, 16, + 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 31, 16, 16, + 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 31, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, + 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, 32, 16, 7, + 42, 42, 42, 69, 60, 46, 42, 42, 42, 42, 42, 42, 42, 42, 69, 60, + 60, 60, 46, 60, 60, 60, 60, 60, 60, 60, 69, 21, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 55, 42, 42, 16, 16, 16, 16, 16,123, 16, 16, + 42, 42, 42, 67, 39, 39, 39, 39, 7, 7, 7, 7, 7, 7, 7, 70, + 36, 36, 36, 36, 36, 36, 42, 42, 7, 7, 7, 7, 7, 7, 7,171, + 36, 36, 36, 36, 36, 75, 42, 42,172, 7, 7, 7, 7, 7, 7, 84, + 36, 63, 36, 64, 36, 36, 36, 42, 36, 36, 63, 42, 42, 42, 42, 75, + 16, 16, 42, 42, 42, 67, 39, 39, 27, 27, 27, 27, 27, 27,145, 27, + 173, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,145, + 27, 27, 27, 27, 27, 27, 83, 60, 60, 60, 60, 60, 60, 25, 40, 40, + 0, 0, 29, 21, 21, 21, 23, 21, 22, 18, 21, 25, 21, 17, 13, 13, + 25, 25, 25, 21, 21, 9, 9, 9, 9, 22, 21, 18, 24, 16, 24, 5, + 5, 5, 5, 22, 25, 18, 25, 0, 23, 23, 26, 21, 24, 26, 7, 20, + 25, 1, 26, 24, 26, 25, 15, 15, 24, 15, 7, 19, 15, 21, 9, 25, + 9, 5, 5, 25, 5, 9, 5, 7, 7, 7, 9, 8, 8, 5, 6, 6, + 24, 24, 6, 24, 12, 12, 6, 5, 9, 21, 25, 9, 26, 12, 11, 11, + 9, 6, 5, 21, 17, 17, 17, 26, 26, 23, 23, 12, 17, 12, 21, 12, + 12, 21, 7, 21, 1, 1, 21, 23, 26, 26, 1, 21, 6, 7, 7, 12, + 12, 7, 21, 7, 12, 1, 12, 6, 6, 12, 12, 26, 7, 26, 26, 7, + 21, 1, 24, 7, 1, 12, 7, 6, 12, 10, 10, 10, 10, 12, 21, 6, + 10, 7, 7, 10, 23, 7, 15, 26, 13, 21, 13, 7, 15, 7, 12, 23, + 21, 26, 21, 15, 17, 7, 29, 7, 7, 22, 18, 18, 14, 14, 14, 7, + 10, 21, 17, 21, 11, 12, 5, 6, 8, 8, 8, 24, 5, 24, 9, 24, + 29, 29, 29, 1, 20, 19, 22, 20, 27, 28, 1, 29, 21, 20, 19, 21, + 21, 16, 16, 21, 25, 22, 18, 21, 21, 29, 15, 6, 18, 6, 12, 11, + 9, 26, 26, 9, 26, 5, 7, 5, 5, 26, 14, 9, 5, 14, 14, 15, + 25, 26, 26, 22, 18, 26, 18, 25, 18, 22, 5, 12, 22, 21, 21, 22, + 18, 17, 26, 6, 7, 14, 17, 22, 26, 14, 17, 6, 14, 6, 12, 24, + 24, 6, 26, 15, 6, 21, 11, 21, 24, 9, 6, 9, 23, 26, 6, 10, + 4, 4, 3, 3, 7, 25, 17, 16, 16, 22, 16, 16, 25, 17, 7, 1, + 25, 24, 26, 1, 2, 2, 12, 15, 21, 14, 7, 15, 9, 12, 12, 17, + 13, 15, 26, 10, 10, 1, 13, 23, 7, 13, 23, 15, 0, 1, 2, 3, + 4, 5, 6, 7, 8, 9, 0, 10, 11, 12, 13, 0, 14, 0, 0, 0, + 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, + 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 21, 22, 23, 0, 0, + 0, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, + 0, 36, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 39, 40, 0, 0, 0, 0, 0, 0, 41, 42, 43, 44, + 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, + 0, 0, 0, 0, 3, 0, 0, 0, 4, 5, 6, 7, 0, 8, 9, 10, + 0, 11, 12, 13, 14, 15, 16, 17, 16, 18, 16, 19, 16, 19, 16, 19, + 0, 19, 16, 20, 16, 19, 21, 19, 0, 22, 23, 24, 25, 26, 27, 28, + 29, 30, 31, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, + 0, 0, 0, 0, 0, 0, 34, 0, 0, 35, 0, 0, 36, 0, 37, 0, + 0, 0, 38, 39, 40, 41, 42, 43, 44, 45, 46, 0, 0, 47, 0, 0, + 0, 48, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 50, 0, 51, + 0, 52, 53, 0, 54, 0, 0, 0, 0, 0, 0, 55, 56, 57, 0, 0, + 0, 0, 58, 0, 0, 59, 60, 61, 62, 63, 0, 0, 64, 65, 0, 0, + 0, 66, 0, 0, 0, 0, 67, 0, 0, 0, 68, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 70, 0, 71, + 0, 0, 72, 0, 0, 73, 0, 0, 0, 0, 0, 0, 0, 0, 74, 75, + 0, 0, 0, 0, 76, 77, 0, 78, 79, 0, 0, 80, 81, 0, 82, 62, + 0, 83, 84, 0, 0, 85, 86, 87, 0, 88, 0, 89, 0, 90, 0, 0, + 51, 91, 51, 0, 92, 0, 93, 0, 0, 0, 81, 0, 0, 0, 94, 95, + 0, 96, 97, 98, 99, 0, 0, 0, 0, 0, 51, 0, 0, 0, 0,100, + 101, 0, 0, 0, 0, 0, 0,102, 0, 0, 0, 0, 0, 0,103, 0, + 0, 0, 0, 0, 0,104,105, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,106, 0, 0,107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,108, + 109, 0, 0,110, 0, 0, 0, 0, 0, 0,111, 0,112, 0,105, 0, + 0, 0, 0, 0,113,114, 0, 0, 0, 0, 0, 0, 0,115, 0, 0, + 0,116, 0, 0, 0,117, 0, 0, 0, 0, 0, 0, 0,118, 0,119, + 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 0, 8, 0, + 0, 0, 0, 9, 10, 11, 12, 0, 0, 0, 0, 13, 0, 0, 14, 15, + 0, 16, 0, 17, 18, 0, 0, 19, 0, 20, 21, 0, 0, 0, 0, 0, + 22, 23, 0, 24, 25, 0, 0, 26, 0, 0, 0, 27, 0, 0, 28, 29, + 30, 31, 0, 0, 0, 32, 33, 34, 0, 0, 33, 0, 0, 35, 33, 0, + 0, 0, 33, 36, 0, 0, 0, 0, 0, 37, 38, 0, 0, 0, 0, 0, + 0, 39, 40, 0, 0, 0, 0, 0, 0, 41, 42, 0, 0, 0, 0, 43, + 0, 44, 0, 0, 0, 45, 46, 0, 0, 0, 47, 0, 0, 0, 0, 0, + 0, 48, 49, 0, 0, 0, 0, 50, 0, 0, 0, 51, 0, 52, 0, 53, + 0, 0, 0, 0, 54, 0, 0, 0, 0, 55, 0, 56, 0, 0, 0, 0, + 57, 58, 0, 0, 0, 59, 60, 61, 62, 0, 0, 0, 0, 63, 52, 0, + 64, 65, 0, 0, 66, 0, 0, 0, 67, 68, 0, 0, 0, 69, 0, 70, + 71, 72, 73, 74, 1, 75, 0, 76, 77, 78, 0, 0, 79, 80, 0, 0, + 0, 81, 0, 0, 1, 1, 0, 0, 82, 0, 0, 83, 0, 0, 0, 0, + 79, 84, 0, 85, 0, 0, 0, 0, 0, 80, 86, 0, 87, 0, 52, 0, + 1, 80, 0, 0, 88, 0, 0, 89, 0, 0, 0, 0, 0, 90, 57, 0, + 0, 0, 0, 0, 0, 91, 92, 0, 0, 86, 0, 0, 33, 0, 0, 93, + 0, 0, 0, 0, 94, 0, 0, 0, 0, 49, 0, 0, 95, 0, 0, 0, + 0, 96, 97, 0, 0, 98, 0, 0, 99, 0, 0, 0,100, 0, 0, 0, + 101, 0, 0, 0,102, 0, 0, 0, 0,103,104, 95, 0, 0,105, 0, + 0, 0, 86, 0, 0,106, 0, 0, 0,107,108, 0, 0,109,110, 0, + 0, 0, 0, 0, 0,111, 0, 0,112, 0, 0, 0, 0,113, 33, 0, + 114,115,116, 57, 0, 0,117, 35, 0, 0,118, 0, 0, 0,119, 0, + 0, 0, 0, 0, 0,120, 0, 0,121, 0, 0, 0, 0,122, 90, 0, + 0, 0, 0, 0, 57, 0, 0, 0, 0, 52,123, 0, 0, 0, 0,124, + 0, 0,125, 0, 0, 0, 0,123, 0, 0,126, 0, 0, 0, 0, 0, + 81, 0, 0, 0, 0,127, 0, 0, 0,128, 0, 0, 0,129, 0,130, + 0, 0, 0, 0,131,132,133, 0,134, 0,135, 0, 0, 0,136,137, + 138, 0, 79, 0, 0, 0, 0, 0, 35, 0, 0, 0,139, 0, 0, 0, + 140, 0, 0, 0,141, 0, 0, 0,142,143, 0,144, 0, 0,145, 0, + 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, + 7, 4, 4, 8, 9, 10, 1, 11, 12, 13, 14, 15, 16, 17, 18, 1, + 1, 1, 19, 1, 0, 0, 20, 21, 22, 1, 23, 4, 21, 24, 25, 26, + 27, 28, 29, 30, 0, 0, 1, 1, 31, 0, 0, 0, 32, 33, 34, 35, + 1, 36, 37, 0, 0, 0, 0, 38, 1, 39, 14, 39, 40, 41, 42, 0, + 0, 0, 43, 36, 44, 45, 21, 45, 46, 0, 0, 0, 19, 1, 21, 0, + 0, 47, 0, 38, 48, 1, 1, 49, 49, 50, 0, 0, 51, 0, 0, 19, + 52, 1, 0, 0, 38, 14, 4, 1, 1, 1, 53, 21, 43, 52, 54, 21, + 35, 1, 0, 0, 0, 55, 0, 0, 0, 56, 57, 58, 0, 0, 0, 0, + 0, 59, 0, 60, 0, 0, 0, 0, 61, 62, 0, 0, 63, 0, 0, 0, + 64, 0, 0, 0, 65, 0, 0, 0, 66, 0, 0, 0, 67, 0, 0, 0, + 68, 0, 0, 69, 70, 0, 71, 72, 73, 74, 75, 76, 0, 0, 0, 77, + 0, 0, 0, 78, 79, 0, 0, 0, 0, 47, 0, 0, 0, 49, 0, 80, + 0, 0, 0, 62, 0, 0, 63, 0, 0, 81, 0, 0, 82, 0, 0, 0, + 83, 0, 0, 19, 84, 0, 62, 0, 0, 0, 0, 49, 1, 85, 1, 52, + 15, 86, 36, 10, 21, 1, 1, 1, 1, 41, 1, 21, 87, 0, 0, 55, + 0, 0, 0, 0, 19, 10, 1, 0, 0, 0, 0, 0, 88, 0, 0, 89, + 0, 0, 88, 0, 0, 0, 0, 78, 0, 0, 90, 9, 12, 4, 91, 8, + 92, 47, 0, 58, 50, 0, 21, 1, 21, 93, 94, 1, 1, 1, 1, 95, + 96, 97, 98, 1, 99, 58, 81,100,101, 4, 58, 0, 0, 0, 0, 0, + 0, 19, 50, 0, 0, 0, 0, 0, 0, 61, 0, 0,102,103, 0, 0, + 104, 0, 0, 1, 1, 50, 0, 0, 0, 38, 0, 63, 0, 0, 0, 0, + 0, 62, 0, 0,105, 68, 61, 0, 0, 0, 78, 0, 0, 0,106,107, + 58, 38, 81, 0, 0, 0, 0, 0, 0,108, 1, 14, 4, 12, 84, 0, + 0, 0, 0, 38, 90, 0, 0, 0, 0,109, 0, 0,110, 61, 0,111, + 0, 0, 0, 1, 0, 0, 0, 0, 49, 50, 0, 0, 19, 58, 0, 0, + 112, 51, 0,112, 14, 52,113, 41, 0, 0, 62, 0, 0, 61, 0, 0, + 114, 0, 90, 0, 0, 0, 61, 62, 0, 0, 62, 0, 89, 0, 0,114, + 0, 0, 0, 0,115, 0, 0, 0, 78, 55, 0, 38, 1, 58, 1, 58, + 0, 0, 0, 0, 0, 88, 63, 89, 0, 0,116, 0, 0, 0, 55, 0, + 0, 0, 0,116, 0, 0, 0, 0, 61, 0, 0, 0, 0, 79, 0, 61, + 0, 0, 0, 0, 56, 0, 89, 80, 0, 0, 79, 0, 0, 0, 8, 92, + 0, 0, 1, 90, 0, 0,117, 0, 0, 0, 0, 0, 0,118, 0,119, + 120,121,122, 0,105, 4,123, 49, 23, 0, 0, 0, 38, 50, 38, 58, + 0, 0, 1, 90, 1, 1, 1, 1, 39, 1, 48,106, 90, 0, 0, 0, + 0, 1, 0, 0, 0,124, 0, 0, 0,113, 19, 59, 0, 38, 0, 81, + 0, 0, 4,123, 0, 0, 0, 1,125, 0, 0, 0, 0, 0,230,230, + 230,230,230,232,220,220,220,220,232,216,220,220,220,220,220,202, + 202,220,220,220,220,202,202,220,220,220, 1, 1, 1, 1, 1,220, + 220,220,220,230,230,230,230,240,230,220,220,220,230,230,230,220, + 220, 0,230,230,230,220,220,220,220,230,232,220,220,230,233,234, + 234,233,234,234,233,230, 0, 0, 0,230, 0,220,230,230,230,230, + 220,230,230,230,222,220,230,230,220,220,230,222,228,230, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 0, 23, 0, 24, + 25, 0,230,220, 0, 18, 30, 31, 32, 0, 0, 0, 0, 27, 28, 29, + 30, 31, 32, 33, 34,230,230,220,220,230,220,230,230,220, 35, 0, + 0, 0, 0, 0,230,230,230, 0, 0,230,230, 0,220,230,230,220, + 0, 0, 0, 36, 0, 0,230,220,230,230,220,220,230,220,220,230, + 220,230,220,230,230, 0, 0,220, 0, 0,230,230, 0,230, 0,230, + 230,230,230,230, 0, 0, 0,220,220,220,230,220,220,220,230,230, + 0,220, 27, 28, 29,230, 7, 0, 0, 0, 0, 9, 0, 0, 0,230, + 220,230,230, 0, 0, 0, 0, 0,230, 0, 0, 84, 91, 0, 0, 0, + 0, 9, 9, 0, 0, 0, 0, 0, 9, 0,103,103, 9, 0,107,107, + 107,107,118,118, 9, 0,122,122,122,122,220,220, 0, 0, 0,220, + 0,220, 0,216, 0, 0, 0,129,130, 0,132, 0, 0, 0, 0, 0, + 130,130,130,130, 0, 0,130, 0,230,230, 9, 0,230,230, 0, 0, + 220, 0, 0, 0, 0, 7, 0, 9, 9, 0, 9, 9, 0, 0, 0,230, + 0, 0, 0,228, 0, 0, 0,222,230,220,220, 0, 0, 0,230, 0, + 0,220,230,220, 0,220,230,230,230,234, 0, 0, 9, 9, 0, 0, + 7, 0,230,230,230, 0,230, 0, 1, 1, 1, 0, 0, 0,230,234, + 214,220,202,230,230,230,230,230,232,228,228,220,218,230,233,220, + 230,220,230,230, 1, 1, 1, 1, 1,230, 0, 1, 1,230,220,230, + 1, 1, 0, 0,218,228,232,222,224,224, 0, 8, 8, 0, 0, 0, + 0,220,230, 0,230,230,220, 0, 0,230, 0, 0, 26, 0, 0,220, + 0,230,230, 1,220, 0, 0,230,220, 0, 0, 0,220,220, 0, 0, + 230,220, 0, 9, 7, 0, 0, 7, 9, 0, 0, 0, 9, 7, 6, 6, + 0, 0, 0, 0, 1, 0, 0,216,216, 1, 1, 1, 0, 0, 0,226, + 216,216,216,216,216, 0,220,220,220, 0,232,232,220,230,230,230, + 7, 0, 16, 17, 17, 33, 17, 49, 17, 17, 84, 97,135,145, 26, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17,177, 0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 4, 3, 3, 3, 3, 3, 5, 3, 3, 3, + 3, 3, 6, 7, 8, 3, 3, 3, 3, 3, 9, 10, 11, 12, 13, 3, + 3, 3, 3, 3, 3, 3, 3, 14, 3, 15, 3, 3, 3, 3, 3, 3, + 16, 17, 18, 19, 20, 21, 3, 3, 3, 22, 23, 24, 3, 3, 3, 3, + 3, 3, 25, 3, 3, 3, 3, 3, 3, 3, 3, 26, 3, 3, 27, 28, + 0, 1, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 3, 0, 0, + 0, 3, 0, 0, 0, 0, 0, 4, 0, 5, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 0, 0, 0, 0, 0, + 0, 9, 0, 9, 0, 0, 0, 0, 0, 0, 0, 10, 11, 12, 13, 0, + 0, 14, 15, 16, 6, 0, 17, 18, 19, 19, 19, 20, 21, 22, 23, 24, + 19, 25, 0, 26, 27, 19, 19, 28, 29, 30, 0, 31, 0, 0, 0, 8, + 0, 0, 0, 0, 0, 0, 0, 19, 28, 0, 32, 33, 9, 34, 35, 19, + 0, 0, 36, 37, 38, 39, 40, 19, 0, 41, 42, 43, 44, 31, 0, 1, + 45, 42, 0, 0, 0, 0, 0, 32, 14, 14, 0, 0, 0, 0, 14, 0, + 0, 46, 47, 47, 47, 47, 48, 49, 47, 47, 47, 47, 50, 51, 52, 53, + 43, 21, 0, 0, 0, 0, 0, 0, 0, 54, 6, 55, 0, 14, 19, 1, + 0, 0, 0, 0, 56, 57, 0, 0, 0, 0, 0, 19, 58, 31, 0, 0, + 0, 0, 0, 0, 0, 59, 14, 0, 0, 0, 0, 1, 0, 2, 0, 0, + 0, 3, 0, 0, 0, 60, 61, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 2, 3, 0, 4, 5, 0, 0, 6, 0, 0, 0, 7, + 0, 0, 0, 1, 1, 0, 0, 8, 9, 0, 8, 9, 0, 0, 0, 0, + 8, 9, 10, 11, 12, 0, 0, 0, 13, 0, 0, 0, 0, 14, 15, 16, + 17, 0, 0, 0, 1, 0, 0, 18, 19, 0, 0, 0, 20, 0, 0, 0, + 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 8, 21, 9, + 0, 0, 22, 0, 0, 0, 0, 1, 0, 23, 24, 25, 0, 0, 26, 0, + 0, 0, 8, 21, 27, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 28, + 29, 30, 0, 31, 32, 20, 1, 1, 0, 0, 0, 8, 21, 9, 1, 4, + 5, 0, 0, 0, 33, 9, 0, 1, 1, 1, 0, 8, 21, 21, 21, 21, + 34, 1, 35, 21, 21, 21, 9, 36, 0, 0, 37, 38, 1, 0, 39, 0, + 0, 0, 1, 0, 1, 0, 0, 0, 0, 8, 21, 9, 1, 0, 0, 0, + 40, 0, 8, 21, 21, 21, 21, 21, 21, 21, 21, 9, 0, 1, 1, 1, + 1, 8, 21, 21, 21, 9, 0, 0, 0, 41, 0, 42, 43, 0, 0, 0, + 1, 44, 0, 0, 0, 45, 8, 9, 1, 0, 0, 0, 8, 21, 21, 21, + 9, 0, 1, 0, 1, 1, 8, 21, 21, 9, 0, 4, 5, 8, 9, 1, + 0, 0, 16, 50, 84,118,136,152,186,187,187,187,187,187,187,187, + 187,187,187,187,187,187,187,187,187,187,187,187,187,187, 12, 0, + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 13, 13, 13, + 13, 13, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 15, 16, 17, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 29, 30, 31, 19, 32, 33, 33, 33, 33, 33, + 34, 19, 19, 19, 19, 19, 19, 35, 19, 36, 37, 38, 38, 38, 38, 38, + 38, 39, 40, 19, 19, 19, 19, 19, 19, 19, 41, 42, 19, 19, 43, 19, + 19, 19, 44, 45, 9, 46, 47, 48, 49, 50, 51, 52, 9, 9, 19, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 53, 19, 19, 53, 19, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 54, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 55, + 0, 0, 1, 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, 0, + 1, 2, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 32, 33, 33, 33, 34, 35, 35, 35, 35, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 2, 2, 51, 51, 52, + 53, 54, 55, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 57, + 57, 56, 56, 56, 56, 56, 56, 58, 59, 60, 61, 56, 62, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 56, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 71, 62, 62, 62, 62, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 73, 74, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 32, + 32, 32, 32, 32, 32, 32, 32, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 62, 62, 62, 62, 88, 89, 89, 89, 90, 89, 91, 92, 93, 94, 95, + 95, 96, 97, 87, 98, 99,100,101,102,103,104,105,105,105, 2,106, + 107,108,109,110,111,112,113,114,115,116,117, 89,118,119,120,121, + 122,123,124,125,126,127,128,129,130, 87,131,132,133,134, 87,135, + 136,137,138,139,140,141,142,143,144,145,146, 87,147,148,149,150, + 150,150,150,150,150,150,150,150,150,150, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87,151,152,152,152,152,152,152,152,152,153, + 153,153,153,153, 87, 87, 87, 87, 87,154, 87, 87, 87, 87, 87,155, + 155,155,155,156,157,158,158, 87, 87,159, 87,160,161,162,163,164, + 164,164,164,164,164,164,164,164,164,164,164,164,164,165,165,165, + 165,164,164, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,166,167, + 168,169,170,170,170, 87, 87,171,172, 87, 87, 87, 87, 87, 87, 56, + 56, 56, 56, 56, 56,173, 56, 56, 56,174,175, 51, 56, 56, 87,176, + 176,176,176,176,176, 87, 87, 87, 87, 87, 87, 87, 87, 2, 87,177, + 6,178, 87, 87,179, 87, 87, 87,180, 87,181, 87,182, 87, 33,183, + 183,184, 87, 87, 87, 87, 87, 56, 56, 56, 87, 89, 89, 87, 87, 56, + 56, 56, 56,185, 87, 56, 56, 62, 62, 62, 62, 62, 87, 87, 87, 62, + 87, 87, 87, 87, 87, 87, 87, 56, 87,186,186, 0, 1, 2, 2, 0, + 0, 0, 0, 1, 2, 1, 2, 0, 0, 3, 3, 4, 5, 4, 5, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 0, 0, 7, 0, 8, + 8, 8, 8, 8, 8, 8, 9, 10, 11, 11, 11, 11, 11, 12, 11, 13, + 13, 13, 13, 13, 13, 13, 13, 14, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 15, 16, 16, 16, 16, 16, 17, 18, 18, 18, 18, 18, 18, 19, + 20, 21, 21, 22, 23, 21, 24, 21, 21, 21, 21, 21, 25, 21, 21, 26, + 26, 26, 26, 26, 21, 21, 21, 27, 27, 27, 27, 28, 28, 28, 28, 29, + 29, 29, 29, 30, 30, 26, 21, 21, 21, 21, 21, 21, 21, 31, 21, 32, + 32, 32, 32, 32, 33, 34, 32, 35, 35, 35, 35, 35, 35, 35, 35, 36, + 36, 36, 36, 36, 36, 36, 36, 37, 37, 37, 37, 37, 37, 37, 37, 38, + 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 39, 39, 40, + 40, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, 41, 42, + 42, 42, 42, 42, 42, 42, 42, 43, 43, 43, 43, 43, 43, 43, 43, 44, + 44, 44, 45, 44, 44, 44, 44, 46, 46, 46, 46, 46, 46, 46, 46, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 48, 47, 47, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 50, 50, 50, 50, 50, 51, 52, + 52, 52, 52, 52, 52, 52, 52, 53, 53, 53, 53, 53, 53, 53, 53, 53, + 53, 54, 54, 54, 54, 54, 54, 55, 55, 55, 55, 55, 55, 55, 55, 56, + 56, 57, 57, 57, 57, 58, 57, 59, 59, 60, 61, 62, 62, 63, 63, 64, + 64, 64, 64, 64, 64, 64, 64, 65, 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 55, 55, 55, 55, 55, 67, 67, 67, 67, 67, 68, 68, 68, 69, + 69, 69, 69, 69, 69, 64, 64, 70, 70, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 8, 8, 8, 8, 8, 72, 72, 72, 72, 72, 72, 72, 72, 73, + 73, 73, 73, 74, 74, 74, 74, 75, 75, 75, 75, 75, 76, 76, 76, 13, + 50, 50, 50, 73, 77, 78, 79, 4, 4, 80, 4, 4, 81, 82, 83, 4, + 4, 4, 84, 8, 8, 8, 8, 11, 11, 11, 11, 11, 11, 11, 11, 85, + 0, 0, 0, 0, 0, 0, 86, 0, 4, 0, 0, 0, 8, 8, 8, 0, + 0, 87, 88, 89, 0, 4, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 90, 90, 90, 90, 90, 90, 90, 90, 91, + 91, 91, 91, 91, 91, 4, 4, 92, 92, 92, 92, 92, 92, 92, 92, 50, + 50, 50, 93, 93, 93, 93, 93, 53, 53, 53, 53, 53, 53, 13, 13, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 0, 95, + 0, 96, 97, 98, 99, 99, 99, 99,100,101,102,102,102,102,103,104, + 104,104,105, 52, 52, 52, 52, 52, 0,104,104, 0, 0, 0,102, 52, + 52, 0, 0, 0, 0, 52,106, 0, 0, 0, 0, 0,102,102,107,102, + 102,102,102,102,108, 0, 0, 94, 94, 94, 94, 0, 0, 0, 0,109, + 109,109,109,109,109,109,109,109,109,109,109,109,110,110,110,111, + 111,111,111,111,111,111,111,111,111,111,111, 13, 13, 13, 13, 13, + 13,112,112,112,112,112,112, 0, 0,113, 4, 4, 4, 4, 4,114, + 4, 4, 4, 4, 4, 4, 4,115,115,115, 0,116,116,116,116,117, + 117,117,117,117,117, 32, 32,118,118,119,120,120,120, 52, 52,121, + 121,121,121,122,121, 49, 49,123,123,123,123,123,123, 49, 49,124, + 124,124,124,124,124,125,125, 53, 53, 53, 4, 4,126,127, 54, 54, + 54, 54, 54,125,125,125,125,128,128,128,128,128,128,128,128, 4, + 129, 18, 18, 18, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21,130, 21, 21, 21, 21, 8, 0,131, 0, 0, 0, 0, 21, 21, + 21, 21, 21, 21, 21, 21,132, 0, 0, 1, 2, 1, 2,133,101,102, + 134, 52, 52, 52, 52, 0, 0,135,135,135,135,135,135,135,135, 0, + 0, 0, 0, 11, 11, 11, 11, 11, 0, 11, 11, 11, 0, 0,136,137, + 137,138,138,138,138,139, 0,140,140,140,141,141,142,142,142,143, + 143,144,144,144,144,144,144,145,145,145,145,145,146,146,146,147, + 147,147,148,148,148,148,148,149,149,149,150,150,150,150,151,151, + 151,151,151,152,152,152,152,153,153,153,153,153,153,153,153,154, + 154,154,154,155,155,156,156,157,157,157,157,157,157,158,158,159, + 159,160,160,161,161,161,161,162,162,163,163,163,163,163,163,164, + 164,164,164,164,164,165,165,166,166,166,166,167,167,167,167,168, + 168,168,168,169,169,170,170,171,171,171,171,171,171,171,171,172, + 172,172,172,172,172,172,172,173,173,173,173,173,173,173,173,174, + 174,174,174,175,175,175,175,175,175,175,175,175,175,175,175,176, + 176,176,176,177, 21, 21, 21,178,178,178,179,179,179,179,180,180, + 180,180,181,181,181,182,182,183,183,183,183,183,183,183,183,184, + 184,184,184,184,185,185,185,186,186,186,186,186,187,187,187,188, + 188,188,188,188,188,189, 43,190,190,190,190,190,190,190,190,191, + 191,191,192,192,192,192,192,193,193,193,194,193,193,193,193,195, + 195,195,195,195,195,195,195,196,196,196,196,196,196,196,196,197, + 197,197,197,197,197,197,197,198,198,198,198,198,198,198,198,199, + 199,199,199,199,199, 66, 66,200,200,200,200,200, 49, 49, 49,201, + 201,201,201,201,201,201,201,202,202,202,202,202,202,202,202,203, + 203,203,203,203,203,203,203,204,204,204,204,204,204,204,204,205, + 205,205,205,205,205,205,205,206,206,206,206,206,207,207,207,207, + 207,207, 55,208,208,208,208, 32, 32, 32, 32, 32, 32,188,188,209, + 209,209,209,209,209,209,209,210,210,210,210,210,210,210,211,211, + 211,211,211,211,211,211,211,212,212,212,212,212,212,213,213,213, + 213,213,214,214,214,214,214,215,215,215,215,215,215,215,215,216, + 216,216,216,216,216,216,216,110,110,110,110, 39, 39, 39, 39,217, + 217,217,217,217,217,217,217,218,218,218,218,218,218,218,218,219, + 219,219,219,219,219,219,219,220,220,220,220,220,220,220,220,221, + 221,221,221,221,221,221,221,112,112,112,112,112,112,112,112,112, + 112,112,112,222,222,222,223,223,223,223,223,223,224,224,224,225, + 225,225,225,225,225,225,225,226,226,226,226,226,226,226,226,227, + 227,227,227,227,227,227,227,227,227,228,228,228,228,228,228,229, + 229,229,229,229,229,229,229,229,229,229,229,229,229,230, 94,231, + 231,231,231,231,231,231,231,232,232,232,232,232,232,232,232,102, + 102,102,102,102,102,102,102,233, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99,102,234, 99,235,102,236,236, + 236,236,236,236,236,236,236,237,237,237,237,237,237,237,237,237, + 237, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 0, 0, 0, 0, + 0, 0, 0, 0, 0,238,239,240, 0,241, 0, 0, 0, 0, 0,242, + 242,242,242,242,242,242,242, 91, 91, 91, 13, 13, 13, 13, 13,243, + 243,243,243,243,243,243,243,244,244,244,244,245,245,245,245,246, + 246,246,246,246,246,246,246,247,247,247,247,247,247,247,247,248, + 248,248,248,248,248,248,248,249,249,249,249,249,249,249,249,250, + 250,250,250,250,250,250,250,251, 0, 0, 0, 0, 0, 0, 0, 8, + 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 1, 2, 2, 2, 2, + 2, 3, 0, 0, 0, 4, 0, 2, 2, 2, 2, 2, 3, 2, 2, 2, + 2, 5, 0, 2, 5, 6, 0, 7, 7, 7, 7, 8, 9, 8, 10, 8, + 11, 8, 8, 8, 8, 8, 8, 12, 13, 13, 13, 14, 14, 14, 14, 14, + 15, 14, 14, 16, 17, 17, 17, 17, 17, 17, 17, 18, 19, 19, 19, 19, + 19, 19, 19, 20, 21, 20, 22, 20, 20, 23, 23, 20, 20, 20, 20, 22, + 20, 24, 7, 7, 25, 20, 20, 26, 20, 20, 20, 20, 20, 20, 21, 27, + 27, 27, 27, 28, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 30, 31, + 31, 31, 31, 32, 20, 20, 20, 33, 33, 33, 33, 34, 35, 33, 33, 33, + 36, 33, 33, 37, 37, 37, 37, 38, 38, 38, 38, 39, 39, 39, 39, 40, + 40, 40, 40, 41, 41, 41, 41, 42, 42, 42, 42, 43, 43, 43, 43, 44, + 44, 44, 44, 45, 45, 45, 45, 46, 46, 46, 46, 46, 46, 46, 47, 48, + 48, 48, 48, 49, 49, 49, 49, 49, 50, 51, 49, 52, 52, 52, 52, 53, + 53, 53, 53, 53, 53, 54, 53, 55, 55, 55, 55, 56, 56, 56, 56, 57, + 57, 57, 57, 58, 58, 58, 58, 59, 59, 59, 59, 60, 60, 60, 60, 60, + 60, 61, 62, 63, 63, 63, 63, 64, 64, 64, 64, 64, 65, 0, 0, 66, + 66, 66, 66, 67, 67, 67, 67, 68, 68, 68, 68, 69, 70, 71, 71, 71, + 71, 71, 71, 72, 72, 72, 72, 73, 73, 73, 73, 74, 74, 74, 74, 75, + 75, 75, 75, 76, 76, 76, 76, 77, 77, 77, 77, 78, 78, 78, 78, 79, + 79, 79, 79, 80, 80, 80, 80, 81, 81, 81, 81, 82, 7, 7, 7, 83, + 7, 84, 85, 0, 84, 86, 0, 2, 87, 88, 2, 2, 2, 2, 89, 90, + 87, 91, 2, 2, 2, 92, 2, 2, 2, 2, 93, 0, 0, 0, 86, 1, + 0, 0, 94, 0, 95, 96, 0, 4, 0, 0, 0, 0, 0, 0, 4, 97, + 97, 97, 97, 98, 98, 98, 98, 13, 13, 13, 13, 99, 99, 99, 99,100, + 100,100,100, 0,101, 0, 0,102,100,103,104, 0, 0,100, 0,105, + 106,106,106,106,106,106,106,106,106,107,105,108,109,109,109,109, + 109,109,109,109,109,110,108,111,111,111,111,112, 55, 55, 55, 55, + 55, 55,113,109,109,109,110,109,109, 0, 0,114,114,114,114,115, + 115,115,115,116,116,116,116,117,117,117,117, 96, 2, 2, 2, 2, + 2, 94, 2,118,118,118,118,119,119,119,119,120,120,120,120,121, + 121,121,121,121,121,121,122,123,123,123,123,124,124,124,124,124, + 124,124,125,126,126,126,126,127,127,127,127,128,128,128,128, 2, + 2, 3, 2, 2,129,130, 0,131,131,131,131,132, 17, 17, 18, 20, + 20, 20,133, 7, 7, 7,134, 20, 20, 20, 23, 0,135,109,109,109, + 109,109,136,137,137,137,137, 0, 0, 0,138,139,139,139,139,140, + 140,140,140, 84, 0, 0, 0,141,141,141,141,142,142,142,142,143, + 143,143,143,144,144,144,144,145,145,145,145,146,146,146,146,147, + 147,147,147,148,148,148,148,149,149,149,149,150,150,150,150,151, + 151,151,151,152,152,152,152,153,153,153,153,154,154,154,154,155, + 155,155,155,156,156,156,156,157,157,157,157,158,158,158,158,159, + 159,159,159,160,160,160,160,161,161,161,161,162,162,162,162,163, + 163,163,163,164,164,164,164,165,165,165,165,166,166,166,166,167, + 167,167,167,168,168,168,168,169,169,169,169,170,170,170,170,171, + 171,171,171,172,172,172,172,173,173,173,173,174,174,174,174,175, + 175,175,175,176,176,176,176,177,177,177,177,178, 20, 20, 20,179, + 179,179,179,180,180,180,180,181,181,181,181,182,182,182,182,183, + 183,183,183,184,184,184,184,185,185,185,185,186,186,186,186,187, + 187,187,187,188,188,188,188,189,189,189,189,190, 45, 45, 45,191, + 191,191,191,192,192,192,192,193,193,193,193,194,194,194,194,194, + 194,195,194,196,196,196,196,197,197,197,197,198,198,198,198,199, + 199,199,199,200,200,200,200,201,201,201,201,202,202,202,202,203, + 203,203,203,204,204,204,204,205,205,205,205,206,206,206,206,207, + 207,207,207,208,208,208,208,209,209,209,209,210,210,210,210,211, + 211,211,211,212,212,212,212,213,213,213,213,214,214,214,214,215, + 215,215,215,216,216,216,216,217,217,217,217,218,218,218,218,219, + 219,219,219,220,220,220,220,221,221,221,221,222,222,222,222,223, + 223,223,223,224,224,224,224,225,225,225,225,226,226,226,226,227, + 227,227,227,228,228,228,228,229,229,229,229,230,230,230,230,231, + 232,232,232,233,233,233,233,232,232,232,232,234,106,106,106,235, + 106,106,106,106,236,109,109,237,237,237,237,238,238,238,238, 0, + 239, 86, 0, 0, 0,239, 7, 82,138, 7, 0, 0, 0,240, 86,241, + 241,241,241,242,242,242,242,243,243,243,243,244,244,244,244,245, + 245,245,245,246,246,246,246,247,247,247,247,248,248,248,248,249, + 249,249,249,250, 0, 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 0, 0, 0, 19, 0, 19, 0, 0, 0, 0, + 0, 26, 26, 1, 1, 1, 1, 9, 9, 9, 9, 0, 9, 9, 9, 9, + 9, 0, 9, 9, 0, 9, 0, 9, 9, 55, 55, 55, 55, 55, 55, 6, + 6, 6, 6, 6, 1, 1, 6, 6, 4, 4, 4, 4, 4, 4, 4, 4, + 14, 14, 14, 14, 14, 14, 14, 3, 3, 3, 3, 3, 0, 3, 3, 0, + 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 1, 1, 1, 3, 3, 1, + 3, 3, 3, 37, 37, 37, 37, 38, 38, 38, 38, 64, 64, 64, 64, 90, + 90, 90, 90, 95, 95, 95, 95, 3, 3, 0, 3, 7, 7, 7, 7, 7, + 1, 1, 1, 1, 7, 7, 7, 0, 0, 7, 7, 5, 5, 5, 5, 11, + 11, 11, 11, 10, 10, 10, 10, 21, 21, 21, 21, 22, 22, 22, 22, 23, + 23, 23, 23, 16, 16, 16, 16, 20, 20, 20, 20, 36, 36, 36, 36, 24, + 24, 24, 24, 24, 24, 24, 0, 18, 18, 18, 18, 25, 25, 25, 25, 25, + 0, 0, 0, 0, 25, 25, 25, 33, 33, 33, 33, 8, 8, 8, 8, 8, + 8, 8, 0, 12, 12, 12, 12, 30, 30, 30, 30, 29, 29, 29, 29, 28, + 28, 28, 28, 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, 35, 0, 0, + 0, 35, 35, 45, 45, 45, 45, 44, 44, 44, 44, 44, 0, 0, 0, 43, + 43, 43, 43, 46, 46, 46, 46, 31, 31, 31, 31, 32, 32, 0, 0, 32, + 0, 32, 32, 32, 32, 32, 32, 48, 48, 48, 48, 52, 52, 52, 52, 58, + 58, 58, 58, 54, 54, 54, 54, 91, 91, 91, 91, 62, 62, 62, 62, 76, + 76, 76, 76, 93, 93, 93, 93, 70, 70, 70, 70, 73, 73, 73, 73, 1, + 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, + 1, 0, 0, 19, 19, 9, 9, 9, 9, 9, 6, 19, 9, 9, 9, 9, + 9, 19, 19, 9, 9, 9, 19, 6, 19, 19, 19, 19, 19, 19, 9, 0, + 0, 0, 19, 0, 0, 9, 0, 0, 0, 19, 19, 27, 27, 27, 27, 56, + 56, 56, 56, 61, 61, 61, 61, 13, 13, 13, 13, 0, 13, 0, 13, 0, + 13, 13, 13, 13, 13, 1, 1, 1, 1, 12, 12, 0, 15, 15, 15, 15, + 15, 15, 15, 15, 1, 1, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 0, 26, 26, 26, 26, 26, 12, 12, 12, 12, 12, 12, 0, 39, + 39, 39, 39, 86, 86, 86, 86, 77, 77, 77, 77, 79, 79, 79, 79, 60, + 60, 60, 60, 65, 65, 65, 65, 75, 75, 75, 75, 69, 69, 69, 69, 69, + 69, 0, 69, 74, 74, 74, 74, 84, 84, 84, 84, 84, 84, 84, 0, 68, + 68, 68, 68, 92, 92, 92, 92, 87, 87, 87, 87, 19, 9, 19, 19, 19, + 19, 0, 0, 2, 2, 2, 2, 19, 19, 19, 4, 3, 3, 0, 0, 1, + 1, 6, 6, 0, 0, 17, 17, 17, 17, 0, 0, 49, 49, 49, 49, 0, + 1, 1, 1, 71, 71, 71, 71, 67, 67, 67, 67, 42, 42, 42, 42, 41, + 41, 41, 41,118,118,118,118, 53, 53, 53, 53, 59, 59, 59, 59, 40, + 40, 40, 40, 51, 51, 51, 51, 50, 50, 50, 50,135,135,135,135,106, + 106,106,106,104,104,104,104,161,161,161,161,170,170,170,170,110, + 110,110,110, 47, 47, 47, 47, 81, 81, 81, 81,120,120,120,120,116, + 116,116,116,128,128,128,128, 66, 66, 66, 66, 72, 72, 72, 72,173, + 173,173,173, 98, 98, 98, 98, 97, 97, 97, 97, 57, 57, 57, 57, 88, + 88, 88, 88,117,117,117,117,112,112,112,112, 78, 78, 78, 78, 83, + 83, 83, 83, 82, 82, 82, 82,122,122,122,122, 89, 89, 89, 89,130, + 130,130,130,144,144,144,144,165,165,165,165,156,156,156,156,156, + 156, 3, 3,147,147,147,147,148,148,148,148,158,158,158,158,153, + 153,153,153,149,149,149,149, 94, 94, 94, 94, 85, 85, 85, 85,101, + 101,101,101, 96, 96, 96, 96,111,111,111,111,100,100,100,100,100, + 36, 36, 36,108,108,108,108,129,129,129,129,109,109,109,109,107, + 107,107,107,107,107,107, 1,171,171,171,171,137,137,137,137,124, + 124,124,124,123,123,123,123,114,114,114,114,102,102,102,102,126, + 126,126,126,142,142,142,142,125,125,125,125,154,154,154,154,150, + 150,150,150,141,141,141,141,140,140,140,140,121,121,121,121,169, + 169,169,169,133,133,133,133,134,134,134,134,138,138,138,138,143, + 143,143,143,175,175,175,175,145,145,145,145,163,163,163,163, 63, + 63, 63, 63,157,157,157,157, 80, 80, 80, 80,127,127,127,127,166, + 166,166,166,115,115,115,115,159,159,159,159,103,103,103,103,119, + 119,119,119,167,167,167,167,146,146,146,146,172,172,172,172, 99, + 99, 99, 99,136,139, 13, 13,155,155,155,155,136,136,136,136, 17, + 15, 15, 15, 17, 17, 15, 15, 15, 17, 17, 17,139,139,139,139,105, + 105,105,105, 0, 0, 0, 1, 0, 0, 1, 1,131,131,131,131,151, + 151,151,151,160,160,160,160,152,152,152,152,164,164,164,164,168, + 168,168,168,174,174,174,174,113,113,113,113,132,132,132,132, 15, + 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, 9, + 10, 9, 11, 12, 13, 9, 9, 9, 14, 9, 9, 15, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 16, + 17, 9, 9, 9, 9, 18, 9, 9, 9, 9, 9, 19, 20, 21, 9, 22, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 23, 9, 9, 9, 9, 9, 24, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 25, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 26, + 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, 0, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 23, 0, 0, 24, 25, 26, 27, 28, 29, 30, 0, + 0, 31, 32, 0, 33, 0, 34, 0, 35, 0, 0, 0, 0, 36, 37, 38, + 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 42, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 43, 44, 0, 45, 0, 0, 0, 0, 0, 0, 46, 47, 0, + 0, 0, 0, 0, 48, 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 50, 51, 0, 0, 0, 52, 0, 0, 53, 0, 0, + 0, 0, 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, + 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 57, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 58, 59, 60, 61, 62, 63, 64, 65, 0, 0, 0, + 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 67, 68, 0, 69, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, + 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101, + 102,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,104, 0, 0, 0, 0, 0, 0,105,106, 0,107, 0, 0, + 0,108, 0,109, 0,110, 0,111,112,113, 0,114, 0, 0, 0,115, + 0, 0, 0,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,117, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,118,119,120,121, 0,122,123,124,125,126, 0, + 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142, + 143,144,145,146,147,148,149,150,151,152,153,154,155,156,157, 0, + 0, 0,158,159,160,161, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,162, 0,163, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,164,165, 0, 0, 0, 0, + 0, 0, 0,166, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,167, 0, 0, 0,168,169, 0, 0,170, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,171, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,172, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,174, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,175, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,176,177, 0, 0, 0, 0,178,179, 0, 0, + 0,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194, + 195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210, + 211,212,213, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, + 4, +}; +static const uint16_t _hb_ucd_u16[5104]= +{ + 0, 0, 1, 2, 3, 4, 5, 6, 0, 0, 7, 8, 9, 10, 11, 12, + 13, 13, 13, 14, 15, 13, 13, 16, 17, 18, 19, 20, 21, 22, 13, 23, + 13, 13, 13, 24, 25, 11, 11, 11, 11, 26, 11, 27, 28, 29, 30, 31, + 32, 32, 32, 32, 32, 32, 32, 33, 34, 35, 36, 11, 37, 38, 13, 39, + 9, 9, 9, 11, 11, 11, 13, 13, 40, 13, 13, 13, 41, 13, 13, 13, + 13, 13, 13, 35, 9, 42, 11, 11, 43, 44, 32, 45, 46, 47, 47, 48, + 49, 50, 47, 47, 51, 32, 52, 53, 47, 47, 47, 47, 47, 54, 55, 56, + 57, 58, 47, 32, 59, 47, 47, 47, 47, 47, 60, 53, 61, 47, 62, 63, + 47, 64, 65, 66, 47, 67, 47, 47, 68, 69, 47, 47, 70, 32, 71, 32, + 72, 47, 47, 73, 74, 75, 76, 77, 78, 47, 47, 79, 80, 81, 82, 83, + 84, 47, 47, 85, 86, 87, 88, 89, 84, 47, 47, 79, 90, 47, 82, 91, + 92, 47, 47, 93, 94, 95, 82, 96, 97, 47, 47, 98, 99, 100, 101, 102, + 103, 47, 47, 104, 105, 106, 82, 107, 108, 47, 47, 93, 109, 110, 82, 111, + 112, 47, 47, 113, 114, 115, 82, 116, 92, 47, 47, 47, 117, 118, 101, 119, + 47, 47, 47, 120, 121, 122, 66, 66, 47, 47, 47, 123, 124, 125, 47, 47, + 126, 127, 128, 129, 47, 47, 47, 130, 131, 32, 32, 132, 133, 134, 66, 66, + 47, 47, 135, 136, 122, 137, 138, 139, 140, 141, 9, 9, 9, 11, 11, 142, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 143, 144, 145, + 47, 146, 9, 9, 9, 9, 9, 147, 148, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 149, 47, 150, 151, 47, 47, 47, 47, 152, 153, + 47, 154, 47, 155, 47, 156, 47, 156, 47, 47, 47, 157, 158, 159, 160, 145, + 161, 160, 47, 47, 162, 47, 47, 47, 163, 47, 164, 47, 47, 47, 47, 47, + 47, 47, 165, 166, 167, 47, 47, 47, 47, 47, 47, 47, 47, 168, 146, 146, + 47, 169, 47, 47, 47, 170, 171, 172, 160, 160, 173, 174, 32, 32, 32, 32, + 175, 47, 47, 176, 177, 122, 178, 179, 180, 47, 181, 61, 47, 47, 182, 183, + 47, 47, 184, 185, 186, 61, 47, 187, 188, 9, 9, 9, 66, 189, 190, 191, + 11, 11, 192, 27, 27, 27, 193, 194, 11, 195, 27, 27, 32, 32, 32, 32, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 196, 13, 13, 13, 13, 13, 13, + 197, 197, 197, 197, 197, 198, 197, 11, 199, 199, 199, 200, 201, 202, 202, 201, + 203, 204, 205, 206, 207, 208, 209, 210, 211, 27, 212, 212, 212, 213, 214, 32, + 215, 216, 217, 218, 219, 145, 220, 220, 221, 222, 223, 146, 224, 225, 146, 226, + 227, 227, 227, 227, 227, 227, 227, 227, 228, 146, 229, 146, 146, 146, 146, 230, + 146, 231, 227, 232, 146, 233, 234, 146, 146, 146, 146, 146, 146, 146, 145, 145, + 145, 235, 146, 146, 146, 146, 236, 145, 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 237, 238, 146, 146, 239, 146, 146, 146, 146, 146, 146, 240, 146, + 146, 146, 146, 146, 146, 146, 241, 242, 145, 243, 146, 146, 244, 227, 245, 227, + 246, 247, 227, 227, 227, 248, 227, 249, 146, 146, 146, 227, 250, 146, 146, 146, + 9, 9, 9, 11, 11, 11, 251, 252, 13, 13, 13, 13, 13, 13, 253, 254, + 11, 11, 11, 47, 47, 47, 255, 256, 47, 47, 47, 47, 47, 47, 32, 32, + 257, 258, 259, 260, 261, 262, 263, 263, 264, 265, 266, 267, 268, 47, 47, 47, + 47, 269, 148, 47, 47, 47, 47, 270, 47, 271, 47, 47, 146, 146, 146, 47, + 146, 146, 272, 146, 273, 274, 146, 146, 272, 146, 146, 274, 146, 146, 146, 146, + 47, 47, 47, 47, 146, 146, 146, 146, 47, 275, 47, 47, 47, 47, 47, 47, + 47, 146, 146, 146, 146, 47, 47, 187, 276, 47, 61, 47, 13, 13, 277, 278, + 13, 279, 47, 47, 47, 47, 280, 281, 31, 282, 283, 284, 13, 13, 13, 285, + 286, 287, 288, 289, 290, 291, 9, 292, 293, 47, 294, 295, 47, 47, 47, 296, + 297, 47, 47, 298, 299, 160, 32, 300, 61, 47, 301, 47, 302, 303, 47, 47, + 72, 47, 47, 304, 305, 306, 307, 61, 47, 47, 308, 309, 310, 311, 47, 312, + 47, 47, 47, 313, 58, 314, 315, 316, 47, 47, 47, 11, 11, 317, 318, 11, + 11, 11, 11, 11, 47, 47, 319, 160, 320, 320, 320, 320, 320, 320, 320, 320, + 321, 321, 321, 321, 321, 321, 321, 321, 11, 322, 323, 47, 47, 47, 47, 47, + 47, 47, 47, 324, 325, 326, 47, 47, 47, 47, 47, 327, 146, 47, 47, 47, + 47, 328, 47, 47, 329, 146, 146, 330, 32, 331, 32, 332, 333, 334, 335, 47, + 47, 47, 47, 47, 47, 47, 47, 336, 337, 2, 3, 4, 5, 338, 339, 340, + 47, 341, 47, 47, 47, 47, 342, 343, 344, 145, 145, 345, 220, 220, 220, 346, + 347, 146, 146, 146, 146, 146, 146, 348, 349, 349, 349, 349, 349, 349, 349, 349, + 47, 47, 47, 47, 47, 47, 350, 145, 47, 47, 351, 47, 352, 47, 47, 60, + 47, 353, 47, 47, 47, 354, 220, 220, 9, 9, 147, 11, 11, 47, 47, 47, + 47, 47, 160, 9, 9, 147, 11, 11, 47, 47, 47, 47, 47, 47, 353, 9, + 9, 355, 11, 11, 47, 47, 47, 47, 27, 27, 27, 27, 27, 27, 27, 27, + 47, 47, 47, 47, 47, 356, 47, 357, 47, 47, 358, 145, 145, 145, 47, 359, + 47, 360, 47, 353, 47, 47, 47, 47, 47, 47, 47, 361, 145, 145, 145, 145, + 362, 47, 47, 363, 145, 66, 47, 364, 47, 365, 145, 145, 366, 47, 367, 66, + 47, 47, 47, 368, 47, 369, 47, 369, 47, 368, 144, 145, 145, 145, 145, 145, + 9, 9, 9, 9, 11, 11, 11, 370, 47, 47, 371, 160, 372, 9, 373, 11, + 374, 227, 227, 227, 227, 227, 227, 227, 145, 145, 145, 145, 145, 145, 145, 145, + 47, 47, 375, 47, 275, 376, 146, 377, 47, 365, 378, 47, 60, 379, 66, 47, + 380, 66, 66, 47, 381, 145, 47, 47, 382, 47, 47, 363, 383, 384, 385, 386, + 180, 47, 47, 387, 388, 47, 47, 160, 97, 47, 389, 390, 391, 47, 47, 392, + 180, 47, 47, 393, 394, 395, 396, 145, 47, 47, 397, 398, 362, 32, 32, 32, + 47, 47, 368, 47, 47, 399, 172, 160, 92, 47, 47, 113, 400, 401, 402, 32, + 47, 47, 47, 403, 404, 405, 406, 32, 47, 47, 47, 407, 408, 409, 47, 47, + 47, 47, 47, 410, 411, 160, 160, 160, 47, 47, 412, 413, 414, 415, 32, 32, + 47, 47, 47, 416, 417, 160, 66, 66, 47, 47, 418, 419, 160, 160, 160, 160, + 47, 420, 421, 422, 47, 47, 47, 47, 47, 47, 397, 423, 66, 66, 66, 66, + 9, 9, 9, 9, 11, 11, 128, 424, 47, 47, 47, 425, 426, 160, 160, 160, + 47, 47, 47, 47, 47, 427, 428, 429, 430, 47, 47, 431, 432, 433, 47, 47, + 434, 435, 66, 47, 47, 47, 47, 47, 66, 66, 66, 66, 66, 66, 436, 429, + 47, 47, 47, 47, 47, 47, 437, 160, 47, 47, 412, 438, 437, 128, 145, 439, + 47, 156, 440, 441, 32, 32, 32, 32, 47, 47, 47, 362, 442, 160, 47, 47, + 443, 444, 160, 47, 47, 445, 160, 160, 47, 47, 47, 47, 47, 47, 47, 446, + 447, 47, 47, 448, 449, 450, 32, 32, 47, 47, 47, 47, 145, 451, 452, 453, + 220, 220, 220, 220, 220, 220, 220, 66, 47, 47, 47, 47, 47, 47, 47, 437, + 47, 47, 47, 209, 454, 32, 47, 47, 47, 455, 456, 160, 160, 160, 160, 160, + 47, 47, 47, 47, 47, 47, 306, 47, 47, 47, 47, 47, 160, 47, 47, 457, + 47, 47, 47, 458, 459, 460, 461, 47, 27, 27, 27, 27, 462, 47, 463, 160, + 9, 9, 9, 9, 9, 9, 11, 11, 145, 464, 9, 465, 11, 11, 11, 11, + 47, 47, 47, 47, 399, 466, 429, 429, 467, 468, 27, 27, 27, 27, 469, 470, + 47, 471, 209, 209, 209, 209, 209, 209, 146, 146, 146, 146, 146, 146, 146, 472, + 146, 146, 146, 146, 146, 146, 146, 227, 32, 32, 32, 32, 32, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 473, 474, 475, 146, 476, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 477, 146, 146, 146, 9, 478, 11, 479, 480, 11, 197, 9, + 481, 482, 9, 483, 11, 9, 478, 11, 479, 480, 11, 197, 9, 481, 482, 9, + 483, 11, 9, 478, 11, 479, 480, 11, 197, 9, 481, 482, 9, 483, 11, 9, + 478, 11, 197, 9, 484, 485, 486, 487, 11, 488, 9, 489, 490, 491, 492, 11, + 493, 9, 494, 11, 495, 160, 160, 160, 32, 32, 32, 496, 32, 32, 497, 498, + 499, 500, 32, 32, 32, 32, 32, 32, 501, 11, 11, 11, 11, 11, 11, 11, + 32, 32, 32, 27, 27, 27, 27, 27, 32, 32, 32, 32, 32, 32, 32, 32, + 47, 47, 47, 502, 503, 146, 146, 146, 47, 47, 455, 32, 47, 47, 504, 505, + 47, 47, 47, 47, 47, 47, 506, 160, 47, 47, 47, 47, 47, 47, 455, 507, + 47, 47, 47, 47, 47, 47, 508, 509, 47, 47, 47, 47, 358, 32, 32, 32, + 9, 9, 481, 11, 510, 306, 66, 66, 145, 145, 511, 512, 145, 145, 145, 145, + 145, 145, 513, 145, 145, 145, 145, 145, 47, 47, 47, 47, 47, 47, 47, 227, + 514, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 515, + 146, 146, 146, 146, 146, 227, 227, 227, 209, 209, 209, 209, 209, 209, 209, 209, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 939, 940, 941, 942, 946, 948, 0, 962, 969, 970, 971, 976,1001,1002,1003,1008, + 0,1033,1040,1041,1042,1043,1047, 0, 0,1080,1081,1082,1086,1110, 0, 0, + 1124,1125,1126,1127,1131,1133, 0,1147,1154,1155,1156,1161,1187,1188,1189,1193, + 0,1219,1226,1227,1228,1229,1233, 0, 0,1267,1268,1269,1273,1298, 0,1303, + 943,1128, 944,1129, 954,1139, 958,1143, 959,1144, 960,1145, 961,1146, 964,1149, + 0, 0, 973,1158, 974,1159, 975,1160, 983,1168, 978,1163, 988,1173, 990,1175, + 991,1176, 993,1178, 994,1179, 0, 0,1004,1190,1005,1191,1006,1192,1014,1199, + 1007, 0, 0, 0,1016,1201,1020,1206, 0,1022,1208,1025,1211,1023,1209, 0, + 0, 0, 0,1032,1218,1037,1223,1035,1221, 0, 0, 0,1044,1230,1045,1231, + 1049,1235, 0, 0,1058,1244,1064,1250,1060,1246,1066,1252,1067,1253,1072,1258, + 1069,1255,1077,1264,1074,1261, 0, 0,1083,1270,1084,1271,1085,1272,1088,1275, + 1089,1276,1096,1283,1103,1290,1111,1299,1115,1118,1307,1120,1309,1121,1310, 0, + 1053,1239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1093, + 1280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 949,1134,1010, + 1195,1050,1236,1090,1277,1341,1368,1340,1367,1342,1369,1339,1366, 0,1320,1347, + 1418,1419,1323,1350, 0, 0, 992,1177,1018,1204,1055,1241,1416,1417,1415,1424, + 1202, 0, 0, 0, 987,1172, 0, 0,1031,1217,1321,1348,1322,1349,1338,1365, + 950,1135, 951,1136, 979,1164, 980,1165,1011,1196,1012,1197,1051,1237,1052,1238, + 1061,1247,1062,1248,1091,1278,1092,1279,1071,1257,1076,1263, 0, 0, 997,1182, + 0, 0, 0, 0, 0, 0, 945,1130, 982,1167,1337,1364,1335,1362,1046,1232, + 1422,1423,1113,1301, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 8, 9, 0, 10,1425, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0,1314,1427, 5,1434,1438,1443, 0,1450, 0,1455,1461, + 1514, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1446,1458,1468,1476,1480,1486, + 1517, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1489,1503,1494,1500,1508, 0, + 0, 0, 0,1520,1521, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1526,1528, 0,1525, 0, 0, 0,1522, 0, 0, 0, 0,1536,1532,1539, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,1534, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,1556, 0, 0, 0, 0, 0, 0, + 1548,1550, 0,1547, 0, 0, 0,1567, 0, 0, 0, 0,1558,1554,1561, 0, + 0, 0, 0, 0, 0, 0,1568,1569, 0, 0, 0, 0, 0, 0, 0, 0, + 0,1529,1551, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1523,1545,1524,1546, 0, 0,1527,1549, 0, 0,1570,1571,1530,1552,1531,1553, + 0, 0,1533,1555,1535,1557,1537,1559, 0, 0,1572,1573,1544,1566,1538,1560, + 1540,1562,1541,1563,1542,1564, 0, 0,1543,1565, 0, 0, 0, 0, 0, 0, + 0, 0,1606,1607,1609,1608,1610, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1613, 0,1611, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,1612, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,1620, 0, 0, 0, 0, 0, 0, + 0,1623, 0, 0,1624, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,1614,1615,1616,1617,1618,1619,1621,1622, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1628,1629, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1625,1626, 0,1627, + 0, 0, 0,1634, 0, 0,1635, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,1630,1631,1632, 0, 0,1633, 0, + 0, 0, 0, 0, 0, 0, 0, 0,1639, 0, 0,1638,1640, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1636,1637, 0, 0, + 0, 0, 0, 0,1641, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1642,1644,1643, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,1645, 0, 0, 0, 0, 0, 0, 0, + 1646, 0, 0, 0, 0, 0, 0,1648,1649, 0,1647,1650, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1651,1653,1652, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1654, 0,1655,1657,1656, 0, + 0, 0, 0,1659, 0, 0, 0, 0, 0, 0, 0, 0, 0,1660, 0, 0, + 0, 0,1661, 0, 0, 0, 0,1662, 0, 0, 0, 0,1663, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,1658, 0, 0, 0, 0, 0, 0, + 0, 0, 0,1664, 0,1665,1673, 0,1674, 0, 0, 0, 0, 0, 0, 0, + 0,1666, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,1668, 0, 0, 0, 0, 0, 0, 0, 0, 0,1669, 0, 0, + 0, 0,1670, 0, 0, 0, 0,1671, 0, 0, 0, 0,1672, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,1667, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,1675, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,1676, 0,1677, 0,1678, 0,1679, 0,1680, 0, + 0, 0,1681, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1682, 0,1683, 0, 0, + 1684,1685, 0,1686, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 953,1138, 955,1140, 956,1141, 957,1142,1324,1351, 963,1148, 965,1150, 968,1153, + 966,1151, 967,1152,1378,1380,1379,1381, 984,1169, 985,1170,1420,1421, 986,1171, + 989,1174, 995,1180, 998,1183, 996,1181, 999,1184,1000,1185,1015,1200,1329,1356, + 1017,1203,1019,1205,1021,1207,1024,1210,1687,1688,1027,1213,1026,1212,1028,1214, + 1029,1215,1030,1216,1034,1220,1036,1222,1039,1225,1038,1224,1334,1361,1336,1363, + 1382,1384,1383,1385,1056,1242,1057,1243,1059,1245,1063,1249,1689,1690,1065,1251, + 1068,1254,1070,1256,1386,1387,1388,1389,1691,1692,1073,1259,1075,1262,1079,1266, + 1078,1265,1095,1282,1098,1285,1097,1284,1390,1391,1392,1393,1099,1286,1100,1287, + 1101,1288,1102,1289,1105,1292,1104,1291,1106,1294,1107,1295,1108,1296,1114,1302, + 1119,1308,1122,1311,1123,1312,1186,1260,1293,1305, 0,1394, 0, 0, 0, 0, + 952,1137, 947,1132,1317,1344,1316,1343,1319,1346,1318,1345,1693,1695,1371,1375, + 1370,1374,1373,1377,1372,1376,1694,1696, 981,1166, 977,1162, 972,1157,1326,1353, + 1325,1352,1328,1355,1327,1354,1697,1698,1009,1194,1013,1198,1054,1240,1048,1234, + 1331,1358,1330,1357,1333,1360,1332,1359,1699,1700,1396,1401,1395,1400,1398,1403, + 1397,1402,1399,1404,1094,1281,1087,1274,1406,1411,1405,1410,1408,1413,1407,1412, + 1409,1414,1109,1297,1117,1306,1116,1304,1112,1300, 0, 0, 0, 0, 0, 0, + 1471,1472,1701,1705,1702,1706,1703,1707,1430,1431,1715,1719,1716,1720,1717,1721, + 1477,1478,1729,1731,1730,1732, 0, 0,1435,1436,1733,1735,1734,1736, 0, 0, + 1481,1482,1737,1741,1738,1742,1739,1743,1439,1440,1751,1755,1752,1756,1753,1757, + 1490,1491,1765,1768,1766,1769,1767,1770,1447,1448,1771,1774,1772,1775,1773,1776, + 1495,1496,1777,1779,1778,1780, 0, 0,1451,1452,1781,1783,1782,1784, 0, 0, + 1504,1505,1785,1788,1786,1789,1787,1790, 0,1459, 0,1791, 0,1792, 0,1793, + 1509,1510,1794,1798,1795,1799,1796,1800,1462,1463,1808,1812,1809,1813,1810,1814, + 1467, 21,1475, 22,1479, 23,1485, 24,1493, 27,1499, 28,1507, 29, 0, 0, + 1704,1708,1709,1710,1711,1712,1713,1714,1718,1722,1723,1724,1725,1726,1727,1728, + 1740,1744,1745,1746,1747,1748,1749,1750,1754,1758,1759,1760,1761,1762,1763,1764, + 1797,1801,1802,1803,1804,1805,1806,1807,1811,1815,1816,1817,1818,1819,1820,1821, + 1470,1469,1822,1474,1465, 0,1473,1825,1429,1428,1426, 12,1432, 0, 26, 0, + 0,1315,1823,1484,1466, 0,1483,1829,1433, 13,1437, 14,1441,1826,1827,1828, + 1488,1487,1513, 19, 0, 0,1492,1515,1445,1444,1442, 15, 0,1831,1832,1833, + 1502,1501,1516, 25,1497,1498,1506,1518,1457,1456,1454, 17,1453,1313, 11, 3, + 0, 0,1824,1512,1519, 0,1511,1830,1449, 16,1460, 18,1464, 4, 0, 0, + 30, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 2, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1834,1835, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1836, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1837,1839,1838, + 0, 0, 0, 0,1840, 0, 0, 0, 0,1841, 0, 0,1842, 0, 0, 0, + 0, 0, 0, 0,1843, 0,1844, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,1845, 0, 0,1846, 0, 0,1847, 0,1848, 0, 0, 0, 0, 0, 0, + 937, 0,1850, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1849, 936, 938, + 1851,1852, 0, 0,1853,1854, 0, 0,1855,1856, 0, 0, 0, 0, 0, 0, + 1857,1858, 0, 0,1861,1862, 0, 0,1863,1864, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1867,1868,1869,1870, + 1859,1860,1865,1866, 0, 0, 0, 0, 0, 0,1871,1872,1873,1874, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 33, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1875, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1877, 0,1878, 0, + 1879, 0,1880, 0,1881, 0,1882, 0,1883, 0,1884, 0,1885, 0,1886, 0, + 1887, 0,1888, 0, 0,1889, 0,1890, 0,1891, 0, 0, 0, 0, 0, 0, + 1892,1893, 0,1894,1895, 0,1896,1897, 0,1898,1899, 0,1900,1901, 0, 0, + 0, 0, 0, 0,1876, 0, 0, 0, 0, 0, 0, 0, 0, 0,1902, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1904, 0,1905, 0, + 1906, 0,1907, 0,1908, 0,1909, 0,1910, 0,1911, 0,1912, 0,1913, 0, + 1914, 0,1915, 0, 0,1916, 0,1917, 0,1918, 0, 0, 0, 0, 0, 0, + 1919,1920, 0,1921,1922, 0,1923,1924, 0,1925,1926, 0,1927,1928, 0, 0, + 0, 0, 0, 0,1903, 0, 0,1929,1930,1931,1932, 0, 0, 0,1933, 0, + 710, 385, 724, 715, 455, 103, 186, 825, 825, 242, 751, 205, 241, 336, 524, 601, + 663, 676, 688, 738, 411, 434, 474, 500, 649, 746, 799, 108, 180, 416, 482, 662, + 810, 275, 462, 658, 692, 344, 618, 679, 293, 388, 440, 492, 740, 116, 146, 168, + 368, 414, 481, 527, 606, 660, 665, 722, 781, 803, 809, 538, 553, 588, 642, 758, + 811, 701, 233, 299, 573, 612, 487, 540, 714, 779, 232, 267, 412, 445, 457, 585, + 594, 766, 167, 613, 149, 148, 560, 589, 648, 768, 708, 345, 411, 704, 105, 259, + 313, 496, 518, 174, 542, 120, 307, 101, 430, 372, 584, 183, 228, 529, 650, 697, + 424, 732, 428, 349, 632, 355, 517, 110, 135, 147, 403, 580, 624, 700, 750, 170, + 193, 245, 297, 374, 463, 543, 763, 801, 812, 815, 162, 384, 420, 730, 287, 330, + 337, 366, 459, 476, 509, 558, 591, 610, 726, 652, 734, 759, 154, 163, 198, 473, + 683, 697, 292, 311, 353, 423, 572, 494, 113, 217, 259, 280, 314, 499, 506, 603, + 608, 752, 778, 782, 788, 117, 557, 748, 774, 320, 109, 126, 260, 265, 373, 411, + 479, 523, 655, 737, 823, 380, 765, 161, 395, 398, 438, 451, 502, 516, 537, 583, + 791, 136, 340, 769, 122, 273, 446, 727, 305, 322, 400, 496, 771, 155, 190, 269, + 377, 391, 406, 432, 501, 519, 599, 684, 687, 749, 776, 175, 452, 191, 480, 510, + 659, 772, 805, 813, 397, 444, 619, 566, 568, 575, 491, 471, 707, 111, 636, 156, + 153, 288, 346, 578, 256, 435, 383, 729, 680, 767, 694, 295, 128, 210, 0, 0, + 227, 0, 379, 0, 0, 150, 493, 525, 544, 551, 552, 556, 783, 576, 604, 0, + 661, 0, 703, 0, 0, 735, 743, 0, 0, 0, 793, 794, 795, 808, 741, 773, + 118, 127, 130, 166, 169, 177, 207, 213, 215, 226, 229, 268, 270, 317, 327, 329, + 335, 369, 375, 381, 404, 441, 448, 458, 477, 484, 503, 539, 545, 547, 546, 548, + 549, 550, 554, 555, 561, 564, 569, 591, 593, 595, 598, 607, 620, 625, 625, 651, + 690, 695, 705, 706, 716, 717, 733, 735, 777, 786, 790, 315, 869, 623, 0, 0, + 102, 145, 134, 115, 129, 138, 165, 171, 207, 202, 206, 212, 227, 231, 240, 243, + 250, 254, 294, 296, 303, 308, 319, 325, 321, 329, 326, 335, 341, 357, 360, 362, + 370, 379, 388, 389, 393, 421, 424, 438, 456, 454, 458, 465, 477, 535, 485, 490, + 493, 507, 512, 514, 521, 522, 525, 526, 528, 533, 532, 541, 565, 569, 574, 586, + 591, 597, 607, 637, 647, 674, 691, 693, 695, 698, 703, 699, 705, 704, 702, 706, + 709, 717, 728, 736, 747, 754, 770, 777, 783, 784, 786, 787, 790, 802, 825, 848, + 847, 857, 55, 65, 66, 883, 892, 916, 822, 824, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1586, 0,1605, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1602,1603,1934,1935,1574,1575, + 1576,1577,1579,1580,1581,1583,1584, 0,1585,1587,1588,1589,1591, 0,1592, 0, + 1593,1594, 0,1595,1596, 0,1598,1599,1600,1601,1604,1582,1578,1590,1597, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,1936, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,1937, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1938, 0,1939, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1940, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1941,1942, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1943,1944, 0, 0, 0, + 0, 0, 0,1945, 0,1946, 0, 0, 0, 0, 0, 0, 0, 0,1947, 0, + 0,1948, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,1950, 0,1949,1951, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1953,1952, 0,1954, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1955,1956, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,1957, 0, 0, 0, 0, 0, 0, 0, + 0,1958,1961,1959,1965,1960,1962,1964,1963, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,1967,1966,1968, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1969,1970, + 1971,1972,1973,1974,1975, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1976,1977,1978,1980,1979, + 1981, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 106, 104, 107, 826, 114, 118, 119, 121, 123, 124, 127, 125, 34, 830, 130, 131, + 132, 137, 827, 35, 133, 139, 829, 142, 143, 112, 144, 145, 924, 151, 152, 37, + 157, 158, 159, 160, 38, 165, 166, 169, 171, 172, 173, 174, 176, 177, 178, 179, + 181, 182, 182, 182, 833, 468, 184, 185, 834, 187, 188, 189, 196, 192, 194, 195, + 197, 199, 200, 201, 203, 204, 204, 206, 208, 209, 211, 218, 213, 219, 214, 216, + 153, 234, 221, 222, 223, 220, 225, 224, 230, 835, 235, 236, 237, 238, 239, 244, + 836, 837, 247, 248, 249, 246, 251, 39, 40, 253, 255, 255, 838, 257, 258, 259, + 261, 839, 262, 263, 301, 264, 41, 266, 270, 272, 271, 841, 274, 842, 277, 276, + 278, 281, 282, 42, 283, 284, 285, 286, 43, 843, 44, 289, 290, 291, 293, 934, + 298, 845, 845, 621, 300, 300, 45, 852, 894, 302, 304, 46, 306, 309, 310, 312, + 316, 48, 47, 317, 846, 318, 323, 324, 325, 324, 328, 329, 333, 331, 332, 334, + 335, 336, 338, 339, 342, 343, 347, 351, 849, 350, 348, 352, 354, 359, 850, 361, + 358, 356, 49, 363, 365, 367, 364, 50, 369, 371, 851, 376, 386, 378, 53, 381, + 52, 51, 140, 141, 387, 382, 614, 78, 388, 389, 390, 394, 392, 856, 54, 399, + 396, 402, 404, 858, 405, 401, 407, 55, 408, 409, 410, 413, 859, 415, 56, 417, + 860, 418, 57, 419, 422, 424, 425, 861, 840, 862, 426, 863, 429, 431, 427, 433, + 437, 441, 438, 439, 442, 443, 864, 436, 449, 450, 58, 454, 453, 865, 447, 460, + 866, 867, 461, 466, 465, 464, 59, 467, 470, 469, 472, 828, 475, 868, 478, 870, + 483, 485, 486, 871, 488, 489, 872, 873, 495, 497, 60, 498, 61, 61, 504, 505, + 507, 508, 511, 62, 513, 874, 515, 875, 518, 844, 520, 876, 877, 878, 63, 64, + 528, 880, 879, 881, 882, 530, 531, 531, 533, 66, 534, 67, 68, 884, 536, 538, + 541, 69, 885, 549, 886, 887, 556, 559, 70, 561, 562, 563, 888, 889, 889, 567, + 71, 890, 570, 571, 72, 891, 577, 73, 581, 579, 582, 893, 587, 74, 590, 592, + 596, 75, 895, 896, 76, 897, 600, 898, 602, 605, 607, 899, 900, 609, 901, 611, + 853, 77, 615, 616, 79, 617, 252, 902, 903, 854, 855, 621, 622, 731, 80, 627, + 626, 628, 164, 629, 630, 631, 633, 904, 632, 634, 639, 640, 635, 641, 646, 651, + 638, 643, 644, 645, 905, 907, 906, 81, 653, 654, 656, 911, 657, 908, 82, 83, + 909, 910, 84, 664, 665, 666, 667, 669, 668, 671, 670, 674, 672, 673, 675, 85, + 677, 678, 86, 681, 682, 912, 685, 686, 87, 689, 36, 913, 914, 88, 89, 696, + 702, 709, 711, 915, 712, 713, 718, 719, 917, 831, 721, 720, 723, 832, 725, 728, + 918, 919, 739, 742, 744, 920, 745, 753, 756, 757, 755, 760, 761, 921, 762, 90, + 764, 922, 91, 775, 279, 780, 923, 925, 92, 93, 785, 926, 94, 927, 787, 787, + 789, 928, 792, 95, 796, 797, 798, 800, 96, 929, 802, 804, 806, 97, 98, 807, + 930, 99, 931, 932, 933, 814, 100, 816, 817, 818, 819, 820, 821, 935, 0, 0, +}; +static const int16_t _hb_ucd_i16[92]= +{ + 0, 0, 1, -1, 2, 0, -2, 0, 0, 2, 0, -2, 0, 16, 0, -16, + 0, 1, -1, 0, 3, 3, 3, -3, -3, -3, 0, 2016, 0, 2527, 1923, 1914, + 1918, 0, 2250, 0, 0, 138, 0, 7, -7, 0, -1, 1, 1824, 0, 2104, 0, + 2108, 2106, 0, 2106, 1316, 0, -1, -138, 8, 8, 8, 0, 7, 7, -8, -8, + -8, -7,-1316, 1, -1, 3, -3, 1, 0,-1914,-1918, 0, 0,-1923,-1824, 0, + 0,-2016,-2104, 0, 0,-2106,-2108,-2106,-2250, 0,-2527, 0, +}; + +static inline uint8_t _hb_ucd_gc (unsigned u) +{ + return u<1114112 ? _hb_ucd_u8[5296u+((_hb_ucd_u8[1168u+((_hb_ucd_u16[((_hb_ucd_u8[544u+((_hb_ucd_u8[((((((((u)>>1))>>3))>>3))>>4)])<<4)+((((((((u)>>1))>>3))>>3))&15)])<<3)+((((((u)>>1))>>3))&7)])<<3)+((((u)>>1))&7)])<<1)+((u)&1)] : 2; +} +static inline uint8_t _hb_ucd_ccc (unsigned u) +{ + return u<125259 ? _hb_ucd_u8[7322u+((_hb_ucd_u8[6738u+((_hb_ucd_u8[6258u+((_hb_ucd_u8[5890u+((_hb_ucd_u8[5644u+((((((((u)>>2))>>2))>>2))>>3)])<<3)+((((((((u)>>2))>>2))>>2))&7)])<<2)+((((((u)>>2))>>2))&3)])<<2)+((((u)>>2))&3)])<<2)+((u)&3)] : 0; +} +static inline uint8_t _hb_ucd_b4 (const uint8_t* a, unsigned i) +{ + return (a[i>>1]>>((i&1)<<2))&15; +} +static inline int16_t _hb_ucd_bmg (unsigned u) +{ + return u<65380 ? _hb_ucd_i16[((_hb_ucd_u8[8218u+((_hb_ucd_u8[7986u+((_hb_ucd_u8[7890u+((_hb_ucd_b4(_hb_ucd_u8+7826u,((((((((u)>>1))>>2))>>3))>>3)))<<3)+((((((((u)>>1))>>2))>>3))&7)])<<3)+((((((u)>>1))>>2))&7)])<<2)+((((u)>>1))&3)])<<1)+((u)&1)] : 0; +} +static inline uint8_t _hb_ucd_sc (unsigned u) +{ + return u<918016 ? _hb_ucd_u8[11655u+((_hb_ucd_u8[10647u+((_hb_ucd_u8[9151u+((_hb_ucd_u8[8703u+((_hb_ucd_u8[8495u+((_hb_ucd_b4(_hb_ucd_u8+8466u,((((((((((u)>>2))>>2))>>3))>>3))>>4)))<<4)+((((((((((u)>>2))>>2))>>3))>>3))&15)])<<3)+((((((((u)>>2))>>2))>>3))&7)])<<3)+((((((u)>>2))>>2))&7)])<<2)+((((u)>>2))&3)])<<2)+((u)&3)] : 2; +} +static inline uint16_t _hb_ucd_dm (unsigned u) +{ + return u<195102 ? _hb_ucd_u16[1680u+((_hb_ucd_u8[13041u+((_hb_ucd_u8[12659u+((((u)>>4))>>5)])<<5)+((((u)>>4))&31)])<<4)+((u)&15)] : 0; } diff --git a/thirdparty/harfbuzz/src/hb-unicode-emoji-table.hh b/thirdparty/harfbuzz/src/hb-unicode-emoji-table.hh index 724917668da..711dd9b6571 100644 --- a/thirdparty/harfbuzz/src/hb-unicode-emoji-table.hh +++ b/thirdparty/harfbuzz/src/hb-unicode-emoji-table.hh @@ -7,13 +7,13 @@ * on file with this header: * * # emoji-data.txt - * # Date: 2024-05-01, 21:25:24 GMT - * # © 2024 Unicode®, Inc. + * # Date: 2025-07-25, 17:54:31 GMT + * # © 2025 Unicode®, Inc. * # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. * # For terms of use and license, see https://www.unicode.org/terms_of_use.html * # * # Emoji Data for UTS #51 - * # Used with Emoji Version 16.0 and subsequent minor revisions (if any) + * # Version: 17.0 * # * # For documentation and usage, see https://www.unicode.org/reports/tr51 */ @@ -25,37 +25,47 @@ #include -static const uint8_t _hb_emoji_u8[464]= +static const uint8_t _hb_emoji_u8[624]= { 16, 17, 17, 17, 50, 20, 21, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,118,152, - 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2, 0, 3, 4, 0, 0, 5, 6, 0, 7, 0, 8, 9, 10, 11, 12, - 0, 0, 13, 0, 0, 0, 14, 0, 15, 0, 0, 0, 0, 16, 0, 0, - 17, 17, 18, 19, 20, 17, 17, 21, 17, 17, 22, 17, 23, 17, 24, 25, - 26, 27, 28, 17, 17, 17, 0, 0, 17, 17, 17, 17, 17, 17, 17, 29, - 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 3, 0, 0, 4, 0, 0, - 5, 6, 0, 0, 7, 8, 0, 0, 8, 0, 9, 10, 0, 0, 11, 0, - 0, 12, 13, 14, 15, 16, 16, 16, 17, 16, 16, 16, 18, 19, 20, 21, - 22, 23, 0, 0, 0, 24, 0, 0, 25, 0, 26, 0, 0, 27, 0, 0, - 28, 0, 0, 0, 16, 16, 16, 16, 29, 9, 0, 30, 31, 32, 16, 33, - 34, 35, 36, 16, 16, 16, 16, 37, 16, 38, 39, 16, 16, 16, 40, 0, - 0, 0, 0, 41, 0, 0, 42, 16, 43, 0, 44, 0, 45, 46, 16, 16, - 47, 48, 49, 16, 16, 16, 16, 38, 0, 0, 0, 0, 0, 66, 0, 0, - 0, 0, 0, 16, 0, 2, 0, 0, 4, 0, 0, 2, 0, 0,240, 3, - 0, 6, 0, 0, 0, 0, 0, 12, 0, 1, 0, 0, 0,128, 0, 0, - 0,254, 15, 7, 4, 0, 0, 0, 0, 12, 64, 0, 1, 0, 0, 0, - 0, 0, 0,120,191,255,247,255,255,255,255,255, 63, 0,255,255, - 63,255, 87, 32, 2, 1, 24, 0,144, 80,184, 0,248, 0, 0, 0, - 0, 0,224, 0, 2, 0, 1,128, 0, 0, 48, 0,224, 0, 0, 24, - 0, 0, 33, 0, 0, 0, 1, 32, 0, 0,128, 2, 0,224, 0, 0, - 0,240, 3,192, 0, 64,254, 7, 0,224,255,255, 63, 0, 0, 0, - 254,255, 0, 4, 0,128,252,247, 0,254,255,255,255,255,255, 7, - 255,255,255, 63,192,255,255,255,255,255, 0, 0, 0, 0,240,255, - 0, 0,224,255, 0,240, 0, 0, 0,255, 0,252, 0,255, 0, 0, - 0,192,255,255, 0,240,255,255,255,255,255,247,191,255,255,255, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 3, 0, 0, 4, 0, 5, 0, 0, 0, 0, 0, 6, 0, 0, 7, + 0, 0, 0, 8, 0, 0, 9, 10, 11, 12, 13, 14, 15, 16, 17, 0, + 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 19, 20, 0, 0, + 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 0, 0, + 23, 0, 24, 25, 0, 26, 27, 28, 29, 30, 31, 31, 32, 31, 33, 34, + 31, 31, 31, 35, 36, 37, 38, 39, 31, 40, 31, 41, 0, 0, 0, 42, + 43, 44, 45, 46, 47, 48, 31, 31, 0, 49, 31, 31, 0, 0, 0, 0, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 36, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 16, 0, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 4, 0, 0, 2, 0, 0,240, 3, 0, 6, 0, 0, + 0, 0, 0, 12, 0, 1, 0, 0, 0,128, 0, 0, 0,254, 15, 7, + 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 64, 0, + 1, 0, 0, 0, 0, 0, 0,120, 31, 64, 50, 33, 77,196, 0, 7, + 5,255, 15,128,105, 1, 0,200, 0, 0,252, 26,131, 12, 3, 96, + 48,193, 26, 0, 0, 6,191, 39, 36,191, 84, 32, 2, 1, 24, 0, + 144, 80,184, 0, 24, 0, 0, 0, 0, 0,224, 0, 2, 0, 1,128, + 0, 0, 0, 0, 0, 0, 48, 0,224, 0, 0, 24, 0, 0, 0, 0, + 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 32, + 0, 0,128, 2, 0, 0, 0, 0, 16, 0, 0, 0, 0,240, 0, 0, + 0, 0,240,255, 0,128, 1, 0, 1,128, 1, 0, 0, 0,192,255, + 0, 0, 0, 0, 0, 0, 3,192, 0, 64,254, 7, 0,192,255,255, + 255,255,255,255, 63, 0, 0, 0,254,255, 0, 4, 0,128,252,247, + 0,254,255,255,192,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,243,255,255,255,255,255,207,206,255,255,255,255, + 255,255,255,255,255,255,185, 7,255,255,255,255,255,255,255,191, + 255,255,255,255,255,255,255, 63, 0,126,255,255,255,128,249, 7, + 128, 60, 97, 0, 48, 1, 6, 16, 28, 0, 14,112, 10,129, 8,252, + 255,255, 0, 0, 0, 0, 0, 0, 63,248,231,255, 63,250,249,255, + 0, 0, 0,252,255,255,255,255, 0,240, 0, 0, 0, 0, 0, 0, + 0,255, 0,252, 0, 0, 0, 0, 0,255, 0, 0, 0,192, 0,240, + 252,255, 0,254,255,255,255,255, 0,240,255,255,255,255,255,247, + 191,255,255,255,255,255,255,255, 0, 0, 0,255, 0,192,255,255, }; static inline uint8_t _hb_emoji_b4 (const uint8_t* a, unsigned i) @@ -68,7 +78,7 @@ static inline uint8_t _hb_emoji_b1 (const uint8_t* a, unsigned i) } static inline uint8_t _hb_emoji_is_Extended_Pictographic (unsigned u) { - return u<131070 ? _hb_emoji_b1(_hb_emoji_u8+264u,((_hb_emoji_u8[144u+(((_hb_emoji_u8[64u+(((_hb_emoji_b4(_hb_emoji_u8,u>>5>>2>>3))<<3)+((u>>5>>2)&7))])<<2)+((u>>5)&3))])<<5)+((u)&31)) : 0; + return u<131070 ? _hb_emoji_b1(_hb_emoji_u8+224u,((_hb_emoji_u8[64u+((_hb_emoji_b4(_hb_emoji_u8,((((u)>>6))>>4)))<<4)+((((u)>>6))&15)])<<6)+((u)&63)) : 0; } diff --git a/thirdparty/harfbuzz/src/hb-utf.hh b/thirdparty/harfbuzz/src/hb-utf.hh index 6db9bf2fd79..e85b973773d 100644 --- a/thirdparty/harfbuzz/src/hb-utf.hh +++ b/thirdparty/harfbuzz/src/hb-utf.hh @@ -37,7 +37,7 @@ struct hb_utf8_t typedef uint8_t codepoint_t; static constexpr unsigned max_len = 4; - static const codepoint_t * + static inline const codepoint_t * next (const codepoint_t *text, const codepoint_t *end, hb_codepoint_t *unicode, @@ -106,7 +106,7 @@ struct hb_utf8_t return text; } - static const codepoint_t * + static inline const codepoint_t * prev (const codepoint_t *text, const codepoint_t *start, hb_codepoint_t *unicode, @@ -185,7 +185,7 @@ struct hb_utf16_xe_t typedef TCodepoint codepoint_t; static constexpr unsigned max_len = 2; - static const codepoint_t * + static inline const codepoint_t * next (const codepoint_t *text, const codepoint_t *end, hb_codepoint_t *unicode, @@ -217,7 +217,7 @@ struct hb_utf16_xe_t return text; } - static const codepoint_t * + static inline const codepoint_t * prev (const codepoint_t *text, const codepoint_t *start, hb_codepoint_t *unicode, @@ -294,7 +294,7 @@ struct hb_utf32_xe_t typedef TCodepoint codepoint_t; static constexpr unsigned max_len = 1; - static const TCodepoint * + static inline const TCodepoint * next (const TCodepoint *text, const TCodepoint *end HB_UNUSED, hb_codepoint_t *unicode, @@ -306,7 +306,7 @@ struct hb_utf32_xe_t return text; } - static const TCodepoint * + static inline const TCodepoint * prev (const TCodepoint *text, const TCodepoint *start HB_UNUSED, hb_codepoint_t *unicode, @@ -353,7 +353,7 @@ struct hb_latin1_t typedef uint8_t codepoint_t; static constexpr unsigned max_len = 1; - static const codepoint_t * + static inline const codepoint_t * next (const codepoint_t *text, const codepoint_t *end HB_UNUSED, hb_codepoint_t *unicode, @@ -363,7 +363,7 @@ struct hb_latin1_t return text; } - static const codepoint_t * + static inline const codepoint_t * prev (const codepoint_t *text, const codepoint_t *start HB_UNUSED, hb_codepoint_t *unicode, @@ -405,7 +405,7 @@ struct hb_ascii_t typedef uint8_t codepoint_t; static constexpr unsigned max_len = 1; - static const codepoint_t * + static inline const codepoint_t * next (const codepoint_t *text, const codepoint_t *end HB_UNUSED, hb_codepoint_t *unicode, @@ -417,7 +417,7 @@ struct hb_ascii_t return text; } - static const codepoint_t * + static inline const codepoint_t * prev (const codepoint_t *text, const codepoint_t *start HB_UNUSED, hb_codepoint_t *unicode, diff --git a/thirdparty/harfbuzz/src/hb-vector.hh b/thirdparty/harfbuzz/src/hb-vector.hh index 2c1344c03a3..dc34f415571 100644 --- a/thirdparty/harfbuzz/src/hb-vector.hh +++ b/thirdparty/harfbuzz/src/hb-vector.hh @@ -32,6 +32,12 @@ #include "hb-meta.hh" #include "hb-null.hh" +// Change to 1 to force inline vector allocs, to see callsite in malloc-stats tool. +#if 0 +#define HB_ALWAYS_INLINE_VECTOR_ALLOCS HB_ALWAYS_INLINE +#else +#define HB_ALWAYS_INLINE_VECTOR_ALLOCS +#endif template @@ -45,6 +51,7 @@ struct hb_vector_t using c_array_t = typename std::conditional, hb_array_t>::type; hb_vector_t () = default; + HB_ALWAYS_INLINE_VECTOR_ALLOCS hb_vector_t (std::initializer_list lst) : hb_vector_t () { alloc (lst.size (), true); @@ -57,18 +64,21 @@ struct hb_vector_t { extend (o); } + HB_ALWAYS_INLINE_VECTOR_ALLOCS hb_vector_t (const hb_vector_t &o) : hb_vector_t () { alloc_exact (o.length); if (unlikely (in_error ())) return; copy_array (o.as_array ()); } + HB_ALWAYS_INLINE_VECTOR_ALLOCS hb_vector_t (array_t o) : hb_vector_t () { alloc_exact (o.length); if (unlikely (in_error ())) return; copy_array (o); } + HB_ALWAYS_INLINE_VECTOR_ALLOCS hb_vector_t (c_array_t o) : hb_vector_t () { alloc_exact (o.length); @@ -84,8 +94,29 @@ struct hb_vector_t } ~hb_vector_t () { fini (); } + template + void + set_storage (Type (&array)[n]) + { set_storage (array, n); } + void + set_storage (hb_array_t array) + { set_storage (array.arrayZ, array.length); } + template + void + set_storage (Type *array, unsigned n) + { + assert (allocated == 0); + assert (length == 0); + + arrayZ = array; + length = n; + } + template + HB_ALWAYS_INLINE_VECTOR_ALLOCS void extend (const Iterable &o) { auto iter = hb_iter (o); @@ -106,12 +137,14 @@ struct hb_vector_t push_has_room (*iter++); } } + HB_ALWAYS_INLINE_VECTOR_ALLOCS void extend (array_t o) { alloc (length + o.length); if (unlikely (in_error ())) return; copy_array (o); } + HB_ALWAYS_INLINE_VECTOR_ALLOCS void extend (c_array_t o) { alloc (length + o.length); @@ -136,10 +169,7 @@ struct hb_vector_t void fini () { - /* We allow a hack to make the vector point to a foreign array - * by the user. In that case length/arrayZ are non-zero but - * allocated is zero. Don't free anything. */ - if (allocated) + if (is_owned ()) { shrink_vector (0); hb_free (arrayZ); @@ -147,11 +177,13 @@ struct hb_vector_t init (); } - void reset () + HB_ALWAYS_INLINE_VECTOR_ALLOCS + hb_vector_t &reset () { if (unlikely (in_error ())) reset_error (); resize (0); + return *this; } friend void swap (hb_vector_t& a, hb_vector_t& b) noexcept @@ -237,13 +269,16 @@ struct hb_vector_t Type * operator + (unsigned int i) { return arrayZ + i; } const Type * operator + (unsigned int i) const { return arrayZ + i; } + HB_ALWAYS_INLINE_VECTOR_ALLOCS Type *push () { if (unlikely (!resize (length + 1))) return std::addressof (Crap (Type)); return std::addressof (arrayZ[length - 1]); } - template Type *push (Args&&... args) + template + HB_ALWAYS_INLINE_VECTOR_ALLOCS + Type *push (Args&&... args) { if (unlikely ((int) length >= allocated && !alloc (length + 1))) // If push failed to allocate then don't copy v, since this may cause @@ -253,13 +288,20 @@ struct hb_vector_t return push_has_room (std::forward (args)...); } - template Type *push_has_room (Args&&... args) + template + HB_ALWAYS_INLINE_VECTOR_ALLOCS + Type *push_has_room (Args&&... args) { /* Emplace. */ Type *p = std::addressof (arrayZ[length++]); return new (p) Type (std::forward (args)...); } + bool is_owned () const + { + return allocated != 0 && allocated != -1; + } + bool in_error () const { return allocated < 0; } void set_error () { @@ -272,26 +314,34 @@ struct hb_vector_t allocated = -(allocated + 1); } - template Type * - realloc_vector (unsigned new_allocated, hb_priority<0>) + _realloc (unsigned new_allocated) { if (!new_allocated) { - hb_free (arrayZ); + if (is_owned ()) + hb_free (arrayZ); return nullptr; } + if (!allocated && arrayZ) + { + /* If we have a non-null arrayZ but allocated is 0, then we are + * reallocating from a foreign array. */ + Type *new_array = (Type *) hb_malloc (new_allocated * sizeof (Type)); + if (unlikely (!new_array)) + return nullptr; + hb_memcpy ((void *) new_array, (const void *) arrayZ, length * sizeof (Type)); + return new_array; + } return (Type *) hb_realloc (arrayZ, new_allocated * sizeof (Type)); } - template Type * - realloc_vector (unsigned new_allocated, hb_priority<0>) + _malloc_move (unsigned new_allocated) { if (!new_allocated) { - hb_free (arrayZ); + if (is_owned ()) + hb_free (arrayZ); return nullptr; } Type *new_array = (Type *) hb_malloc (new_allocated * sizeof (Type)); @@ -303,22 +353,33 @@ struct hb_vector_t new_array[i] = std::move (arrayZ[i]); arrayZ[i].~Type (); } - hb_free (arrayZ); + if (is_owned ()) + hb_free (arrayZ); } return new_array; } + + template + Type * + realloc_vector (unsigned new_allocated, hb_priority<0>) + { + return _realloc (new_allocated); + } + template + Type * + realloc_vector (unsigned new_allocated, hb_priority<0>) + { + return _malloc_move (new_allocated); + } /* Specialization for types that can be moved using realloc(). */ template Type * realloc_vector (unsigned new_allocated, hb_priority<1>) { - if (!new_allocated) - { - hb_free (arrayZ); - return nullptr; - } - return (Type *) hb_realloc (arrayZ, new_allocated * sizeof (Type)); + return _realloc (new_allocated); } template other) { - assert ((int) (length + other.length) <= allocated); hb_memcpy ((void *) (arrayZ + length), (const void *) other.arrayZ, other.length * item_size); length += other.length; } @@ -362,7 +422,6 @@ struct hb_vector_t void copy_array (hb_array_t other) { - assert ((int) (length + other.length) <= allocated); hb_memcpy ((void *) (arrayZ + length), (const void *) other.arrayZ, other.length * item_size); length += other.length; } @@ -372,7 +431,6 @@ struct hb_vector_t void copy_array (hb_array_t other) { - assert ((int) (length + other.length) <= allocated); for (unsigned i = 0; i < other.length; i++) new (std::addressof (arrayZ[length + i])) Type (other.arrayZ[i]); length += other.length; @@ -385,7 +443,6 @@ struct hb_vector_t void copy_array (hb_array_t other) { - assert ((int) (length + other.length) <= allocated); for (unsigned i = 0; i < other.length; i++) { new (std::addressof (arrayZ[length + i])) Type (); @@ -398,12 +455,12 @@ struct hb_vector_t shrink_vector (unsigned size) { assert (size <= length); - if (!std::is_trivially_destructible::value) + if (!hb_is_trivially_destructible(Type)) { unsigned count = length - size; - Type *p = arrayZ + length - 1; + Type *p = arrayZ + length; while (count--) - p--->~Type (); + (--p)->~Type (); } length = size; } @@ -416,6 +473,7 @@ struct hb_vector_t } /* Allocate for size but don't adjust length. */ + HB_ALWAYS_INLINE_VECTOR_ALLOCS bool alloc (unsigned int size, bool exact=false) { if (unlikely (in_error ())) @@ -471,17 +529,64 @@ struct hb_vector_t return true; } + HB_ALWAYS_INLINE_VECTOR_ALLOCS bool alloc_exact (unsigned int size) { return alloc (size, true); } + HB_ALWAYS_INLINE_VECTOR_ALLOCS void clear () { resize (0); } - bool resize (int size_, bool initialize = true, bool exact = false) + template + HB_ALWAYS_INLINE_VECTOR_ALLOCS + bool allocate_from_pool (allocator_t *allocator, unsigned size, unsigned int initialize = true) + { + if (allocator) + { + assert (!length && !allocated); + arrayZ = (Type *) allocator->alloc (size * sizeof (Type), alignof (Type)); + if (unlikely (!arrayZ)) + { + set_error (); + return false; + } + if (initialize) + grow_vector (size, hb_prioritize); + else + length = size; + return true; + } + return resize_full ((int) size, initialize, true); + } + + template + HB_ALWAYS_INLINE_VECTOR_ALLOCS + bool allocate_from_pool (allocator_t *allocator, const hb_vector_t &other) + { + if (unlikely (!allocate_from_pool (allocator, other.length, false))) + return false; + length = 0; + copy_array (other.as_array ()); + return true; + } + + template + void shrink_back_to_pool (allocator_t *allocator, int size) + { + unsigned orig_length = length; + + shrink (size, false); + + if (allocator && !is_owned ()) + allocator->discard (arrayZ + length, (orig_length - length) * sizeof (Type)); + } + + HB_ALWAYS_INLINE_VECTOR_ALLOCS + bool resize_full (int size_, bool initialize, bool exact) { unsigned int size = size_ < 0 ? 0u : (unsigned int) size_; if (!alloc (size, exact)) @@ -501,9 +606,20 @@ struct hb_vector_t length = size; return true; } - bool resize_exact (int size_, bool initialize = true) + HB_ALWAYS_INLINE_VECTOR_ALLOCS + bool resize (int size_) { - return resize (size_, initialize, true); + return resize_full (size_, true, false); + } + HB_ALWAYS_INLINE_VECTOR_ALLOCS + bool resize_dirty (int size_) + { + return resize_full (size_, false, false); + } + HB_ALWAYS_INLINE_VECTOR_ALLOCS + bool resize_exact (int size_) + { + return resize_full (size_, true, true); } Type pop () @@ -544,7 +660,7 @@ struct hb_vector_t shrink_vector (size); - if (shrink_memory) + if (is_owned () && shrink_memory) alloc_exact (size); /* To force shrinking memory if needed. */ } diff --git a/thirdparty/harfbuzz/src/hb-version.h b/thirdparty/harfbuzz/src/hb-version.h index ce9ce4a6483..98ed5d3453b 100644 --- a/thirdparty/harfbuzz/src/hb-version.h +++ b/thirdparty/harfbuzz/src/hb-version.h @@ -41,26 +41,26 @@ HB_BEGIN_DECLS * * The major component of the library version available at compile-time. */ -#define HB_VERSION_MAJOR 11 +#define HB_VERSION_MAJOR 12 /** * HB_VERSION_MINOR: * * The minor component of the library version available at compile-time. */ -#define HB_VERSION_MINOR 3 +#define HB_VERSION_MINOR 1 /** * HB_VERSION_MICRO: * * The micro component of the library version available at compile-time. */ -#define HB_VERSION_MICRO 2 +#define HB_VERSION_MICRO 0 /** * HB_VERSION_STRING: * * A string literal containing the library version available at compile-time. */ -#define HB_VERSION_STRING "11.3.2" +#define HB_VERSION_STRING "12.1.0" /** * HB_VERSION_ATLEAST: diff --git a/thirdparty/harfbuzz/src/hb.hh b/thirdparty/harfbuzz/src/hb.hh index 47b710e6740..34a6df8a099 100644 --- a/thirdparty/harfbuzz/src/hb.hh +++ b/thirdparty/harfbuzz/src/hb.hh @@ -89,7 +89,6 @@ #pragma GCC diagnostic error "-Wstring-conversion" #pragma GCC diagnostic error "-Wswitch-enum" #pragma GCC diagnostic error "-Wtautological-overlap-compare" -#pragma GCC diagnostic error "-Wuninitialized" #pragma GCC diagnostic error "-Wunneeded-internal-declaration" #pragma GCC diagnostic error "-Wunused" #pragma GCC diagnostic error "-Wunused-local-typedefs" @@ -110,11 +109,21 @@ #pragma GCC diagnostic warning "-Wformat-signedness" #pragma GCC diagnostic warning "-Wignored-pragma-optimize" #pragma GCC diagnostic warning "-Wlogical-op" -#pragma GCC diagnostic warning "-Wmaybe-uninitialized" #pragma GCC diagnostic warning "-Wmissing-format-attribute" +#pragma GCC diagnostic warning "-Wpessimizing-move" #pragma GCC diagnostic warning "-Wundef" #pragma GCC diagnostic warning "-Wunsafe-loop-optimizations" #pragma GCC diagnostic warning "-Wunused-but-set-variable" +#ifdef __clang__ +// The following are too buggy on gcc +// https://github.com/harfbuzz/harfbuzz/issues/5589 +// https://github.com/harfbuzz/harfbuzz/pull/5367 +#pragma GCC diagnostic warning "-Wmaybe-uninitialized" +#pragma GCC diagnostic warning "-Wuninitialized" +#else +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#pragma GCC diagnostic ignored "-Wuninitialized" +#endif #endif /* Ignored currently, but should be fixed at some point. */ @@ -136,6 +145,7 @@ #pragma GCC diagnostic ignored "-Wformat-nonliteral" #pragma GCC diagnostic ignored "-Wformat-zero-length" #pragma GCC diagnostic ignored "-Wmissing-field-initializers" +#pragma GCC diagnostic ignored "-Wold-style-cast" #pragma GCC diagnostic ignored "-Wpacked" // Erratic impl in clang #pragma GCC diagnostic ignored "-Wrange-loop-analysis" // https://github.com/harfbuzz/harfbuzz/issues/2834 #pragma GCC diagnostic ignored "-Wstrict-aliasing" @@ -239,6 +249,8 @@ // clang defines it so no need. #ifdef __has_builtin #define hb_has_builtin __has_builtin +#elif defined(_MSC_VER) +#define hb_has_builtin(x) 0 #else #define hb_has_builtin(x) ((defined(__GNUC__) && __GNUC__ >= 5)) #endif @@ -557,4 +569,13 @@ extern "C" void hb_free_impl(void *ptr); #include "hb-vector.hh" // Requires: hb-array hb-null #include "hb-object.hh" // Requires: hb-atomic hb-mutex hb-vector + +/* Our src/test-*.cc use hb_assert(), such that it's not compiled out under NDEBUG. + * https://github.com/harfbuzz/harfbuzz/issues/5418 */ +#define hb_always_assert(x) \ + HB_STMT_START { \ + if (!(x)) { fprintf(stderr, "Assertion failed: %s, at %s:%d\n", #x, __FILE__, __LINE__); abort(); } \ + } HB_STMT_END + + #endif /* HB_HH */