diff --git a/segmenter/segmenter.go b/segmenter/segmenter.go index a4053b3..28ae0ea 100644 --- a/segmenter/segmenter.go +++ b/segmenter/segmenter.go @@ -18,25 +18,27 @@ import ( ucd "github.com/go-text/typesetting/unicodedata" ) -// Break is a flag storing the break properties between two runes of +// breakAttr is a flag storing the break properties between two runes of // the input text. -type Break uint8 +type breakAttr uint8 const ( - LineBoundary Break = 1 << iota - MandatoryLineBoundary // implies LineBoundary + lineBoundary breakAttr = 1 << iota + mandatoryLineBoundary // implies LineBoundary - // GraphemeBoundary is on if the cursor can appear in front of a character, + // graphemeBoundary is on if the cursor can appear in front of a character, // i.e. if we are at a grapheme boundary. - GraphemeBoundary + graphemeBoundary - // WordBoundary is on if we are at the beginning or end of a word. + // wordBoundary is on if we are at the beginning or end of a word. // // To actually detect words, you should also look for runes // with the [Alphabetic] property, or with a General_Category of Number. - // See also http://unicode.org/reports/tr44/#Alphabetic and + // + // See also https://unicode.org/reports/tr29/#Word_Boundary_Rules, + // http://unicode.org/reports/tr44/#Alphabetic and // http://unicode.org/reports/tr44/#General_Category_Values - WordBoundary + wordBoundary ) const paragraphSeparator rune = 0x2029 @@ -123,7 +125,7 @@ func newCursor(text []rune) *cursor { return &cr } -// ComputeBreakAttributes does the heavy lifting of text segmentation, +// computeBreakAttributes does the heavy lifting of text segmentation, // by computing a break attribute for each rune. // // More precisely, `attributes` must be a slice of length len(text)+1, @@ -132,7 +134,7 @@ func newCursor(text []rune) *cursor { // // Unicode defines a lot of properties; for now we only handle // grapheme, word and line breaking. -func ComputeBreakAttributes(text []rune, attributes []Break) { +func computeBreakAttributes(text []rune, attributes []breakAttr) { // The rules are somewhat complex, but the general logic is pretty simple: // iterate through the input slice, fetch context information // from previous and following runes required by the rules, @@ -146,21 +148,21 @@ func ComputeBreakAttributes(text []rune, attributes []Break) { for i := 0; i <= len(text); i++ { // note that we accept i == len(text) to fill the last attribute cr.startIteration(text, i) - var attr Break + var attr breakAttr // UAX#29 Grapheme and word Boundaries isGraphemeBoundary := cr.applyGraphemeBoundaryRules() if isGraphemeBoundary { - attr |= GraphemeBoundary + attr |= graphemeBoundary } isWordBoundary, removePrevNoExtend := cr.applyWordBoundaryRules(i) if isWordBoundary { - attr |= WordBoundary + attr |= wordBoundary } if removePrevNoExtend { - attributes[cr.prevWordNoExtend] &^= WordBoundary + attributes[cr.prevWordNoExtend] &^= wordBoundary } // UAX#14 Line Breaking @@ -169,14 +171,14 @@ func ComputeBreakAttributes(text []rune, attributes []Break) { switch bo { case breakEmpty: // rule LB31 : default to allow line break - attr |= LineBoundary + attr |= lineBoundary case breakProhibited: - attr &^= LineBoundary + attr &^= lineBoundary case breakAllowed: - attr |= LineBoundary + attr |= lineBoundary case breakMandatory: - attr |= LineBoundary - attr |= MandatoryLineBoundary + attr |= lineBoundary + attr |= mandatoryLineBoundary } cr.endIteration(i == 0) @@ -186,14 +188,14 @@ func ComputeBreakAttributes(text []rune, attributes []Break) { // start and end of the paragraph are always // grapheme boundaries and word boundaries - attributes[0] |= GraphemeBoundary | WordBoundary // Rule GB1 and WB1 - attributes[len(text)] |= GraphemeBoundary | WordBoundary // Rule GB2 and WB2 + attributes[0] |= graphemeBoundary | wordBoundary // Rule GB1 and WB1 + attributes[len(text)] |= graphemeBoundary | wordBoundary // Rule GB2 and WB2 // never break before the first char, // but always break after the last - attributes[0] &^= LineBoundary // Rule LB2 - attributes[len(text)] |= LineBoundary // Rule LB3 - attributes[len(text)] |= MandatoryLineBoundary // Rule LB3 + attributes[0] &^= lineBoundary // Rule LB2 + attributes[len(text)] |= lineBoundary // Rule LB3 + attributes[len(text)] |= mandatoryLineBoundary // Rule LB3 } // Segmenter is the entry point of the package. @@ -210,36 +212,36 @@ type Segmenter struct { text []rune // with length len(text) + 1 : // the attribute at indice i is about the - // rune at i-1 and i - // See also `computeAttributes` + // rune at i-1 and i. + // See also [ComputeBreakAttributes] // Example : // text : [b, u, l, l] // attributes : [ b, b u, u l, l l, l ] - attributes []Break + attributes []breakAttr } // Init resets the segmenter storage with the given input, // and computes the attributes required to segment the text. func (seg *Segmenter) Init(paragraph []rune) { seg.text = append(seg.text[:0], paragraph...) - seg.attributes = append(seg.attributes[:0], make([]Break, len(paragraph)+1)...) - ComputeBreakAttributes(seg.text, seg.attributes) + seg.attributes = append(seg.attributes[:0], make([]breakAttr, len(paragraph)+1)...) + computeBreakAttributes(seg.text, seg.attributes) } // attributeIterator is an helper type used to // handle iterating over a slice of runeAttr type attributeIterator struct { src *Segmenter - pos int // the current position in the input slice - lastBreak int // the start of the current segment - flag Break // break where this flag is on + pos int // the current position in the input slice + lastBreak int // the start of the current segment + flag breakAttr // break where this flag is on } // next returns true if there is still a segment to process, // and advances the iterator; or return false. -// if returning true, the segment it at li.lastBreak:li.pos +// if returning true, the segment is at [iter.lastBreak:iter.pos] func (iter *attributeIterator) next() bool { - iter.lastBreak = iter.pos // remember the start of the next line + iter.lastBreak = iter.pos // remember the start of the next segment iter.pos++ for iter.pos <= len(iter.src.text) { // can we break before i ? @@ -251,6 +253,17 @@ func (iter *attributeIterator) next() bool { return false } +// Line is the content of a line delimited by the segmenter. +type Line struct { + // Text is a subslice of the original input slice, containing the delimited line + Text []rune + // Offset is the start of the line in the input rune slice + Offset int + // IsMandatoryBreak is true if breaking (at the end of the line) + // is mandatory + IsMandatoryBreak bool +} + // LineIterator provides a convenient way of // iterating over the lines delimited by a `Segmenter`. type LineIterator struct { @@ -266,25 +279,22 @@ func (li *LineIterator) Line() Line { return Line{ Offset: li.lastBreak, Text: li.src.text[li.lastBreak:li.pos], // pos is not included since we break right before - IsMandatoryBreak: li.src.attributes[li.pos]&MandatoryLineBoundary != 0, + IsMandatoryBreak: li.src.attributes[li.pos]&mandatoryLineBoundary != 0, } } -// Line is the content of a line delimited by the segmenter. -type Line struct { - // Text is a subslice of the original input slice, containing the delimited line - Text []rune - // Offset is the start of the line in the input rune slice - Offset int - // IsMandatoryBreak is true if breaking (at the end of the line) - // is mandatory - IsMandatoryBreak bool -} - // LineIterator returns an iterator on the lines // delimited in [Init]. func (sg *Segmenter) LineIterator() *LineIterator { - return &LineIterator{attributeIterator: attributeIterator{src: sg, flag: LineBoundary}} + return &LineIterator{attributeIterator: attributeIterator{src: sg, flag: lineBoundary}} +} + +// Grapheme is the content of a grapheme delimited by the segmenter. +type Grapheme struct { + // Text is a subslice of the original input slice, containing the delimited grapheme + Text []rune + // Offset is the start of the grapheme in the input rune slice + Offset int } // GraphemeIterator provides a convenient way of @@ -305,16 +315,70 @@ func (gr *GraphemeIterator) Grapheme() Grapheme { } } -// Line is the content of a grapheme delimited by the segmenter. -type Grapheme struct { - // Text is a subslice of the original input slice, containing the delimited grapheme +// GraphemeIterator returns an iterator over the graphemes +// delimited in [Init]. +func (sg *Segmenter) GraphemeIterator() *GraphemeIterator { + return &GraphemeIterator{attributeIterator: attributeIterator{src: sg, flag: graphemeBoundary}} +} + +// Word is the content of a word delimited by the segmenter. +// +// More precisely, a word is formed by runes +// with the [Alphabetic] property, or with a General_Category of Number, +// delimited by the Word Boundary Unicode Property. +// +// See also https://unicode.org/reports/tr29/#Word_Boundary_Rules, +// http://unicode.org/reports/tr44/#Alphabetic and +// http://unicode.org/reports/tr44/#General_Category_Values +type Word struct { + // Text is a subslice of the original input slice, containing the delimited word Text []rune - // Offset is the start of the grapheme in the input rune slice + // Offset is the start of the word in the input rune slice Offset int } -// GraphemeIterator returns an iterator over the graphemes +type WordIterator struct { + attributeIterator + + inWord bool // true if we have seen the start of a word +} + +// Next returns true if there is still a word to process, +// and advances the iterator; or return false. +func (gr *WordIterator) Next() bool { + hasBoundary := gr.next() + if !hasBoundary { + return false + } + + if gr.inWord { // we are have reached the END of a word + gr.inWord = false + return true + } + + // do we start a word ? if so, mark it + if gr.pos < len(gr.src.text) { + gr.inWord = unicode.Is(ucd.Word, gr.src.text[gr.pos]) + } + // in any case, advance again + return gr.Next() +} + +// Word returns the current `Word` +func (gr *WordIterator) Word() Word { + return Word{ + Offset: gr.lastBreak, + Text: gr.src.text[gr.lastBreak:gr.pos], + } +} + +// WordIterator returns an iterator over the word // delimited in [Init]. -func (sg *Segmenter) GraphemeIterator() *GraphemeIterator { - return &GraphemeIterator{attributeIterator: attributeIterator{src: sg, flag: GraphemeBoundary}} +func (sg *Segmenter) WordIterator() *WordIterator { + // check is we start at a word + inWord := false + if len(sg.text) != 0 { + inWord = unicode.Is(ucd.Word, sg.text[0]) + } + return &WordIterator{attributeIterator: attributeIterator{src: sg, flag: wordBoundary}, inWord: inWord} } diff --git a/segmenter/segmenter_test.go b/segmenter/segmenter_test.go index f873c5c..15e13e3 100644 --- a/segmenter/segmenter_test.go +++ b/segmenter/segmenter_test.go @@ -41,11 +41,21 @@ func collectGraphemes(s *Segmenter, input []rune) []string { return out } +func collectWords(s *Segmenter, input []rune) []string { + s.Init(input) + iter := s.WordIterator() + var out []string + for iter.Next() { + out = append(out, string(iter.Word().Text)) + } + return out +} + func collectWordBoundaries(s *Segmenter, input []rune) []bool { s.Init(input) out := make([]bool, len(s.attributes)) for i, a := range s.attributes { - out[i] = a&WordBoundary != 0 + out[i] = a&wordBoundary != 0 } return out } @@ -156,6 +166,23 @@ func TestWordBreakUnicodeReference(t *testing.T) { } } +func TestWordSegmenter(t *testing.T) { + var seg Segmenter + for _, test := range []struct { + input string + words []string + }{ + {"My name is Cris", []string{"My", "name", "is", "Cris"}}, + {"Je m'appelle Benoit.", []string{"Je", "m'appelle", "Benoit"}}, + {"Hi : nice ?! suit !", []string{"Hi", "nice", "suit"}}, + } { + got := collectWords(&seg, []rune(test.input)) + if !reflect.DeepEqual(test.words, got) { + t.Errorf("for %s, expected %v, got %v", test.input, test.words, got) + } + } +} + func lineSegmentCount(s *Segmenter, input []rune) int { s.Init(input) iter := s.LineIterator() diff --git a/unicodedata/word_break.go b/unicodedata/word_break.go index e350cff..d062b3c 100644 --- a/unicodedata/word_break.go +++ b/unicodedata/word_break.go @@ -1856,3 +1856,795 @@ var wordBreaks = [...]*unicode.RangeTable{ WordBreakSingle_Quote, // Single_Quote WordBreakWSegSpace, // WSegSpace } + +// Word contains all the runes we may found in a word, +// that is either a Number (Nd, Nl, No) or a rune with the Alphabetic property +var Word = &unicode.RangeTable{ + R16: []unicode.Range16{ + {Lo: 0x0030, Hi: 0x0039, Stride: 1}, + {Lo: 0x0041, Hi: 0x005a, Stride: 1}, + {Lo: 0x0061, Hi: 0x007a, Stride: 1}, + {Lo: 0x00aa, Hi: 0x00b2, Stride: 8}, + {Lo: 0x00b3, Hi: 0x00b5, Stride: 2}, + {Lo: 0x00b9, Hi: 0x00ba, Stride: 1}, + {Lo: 0x00bc, Hi: 0x00be, Stride: 1}, + {Lo: 0x00c0, Hi: 0x00d6, Stride: 1}, + {Lo: 0x00d8, Hi: 0x00f6, Stride: 1}, + {Lo: 0x00f8, Hi: 0x02c1, Stride: 1}, + {Lo: 0x02c6, Hi: 0x02d1, Stride: 1}, + {Lo: 0x02e0, Hi: 0x02e4, Stride: 1}, + {Lo: 0x02ec, Hi: 0x02ee, Stride: 2}, + {Lo: 0x0345, Hi: 0x0370, Stride: 43}, + {Lo: 0x0371, Hi: 0x0374, Stride: 1}, + {Lo: 0x0376, Hi: 0x0377, Stride: 1}, + {Lo: 0x037a, Hi: 0x037d, Stride: 1}, + {Lo: 0x037f, Hi: 0x0386, Stride: 7}, + {Lo: 0x0388, Hi: 0x038a, Stride: 1}, + {Lo: 0x038c, Hi: 0x038e, Stride: 2}, + {Lo: 0x038f, Hi: 0x03a1, Stride: 1}, + {Lo: 0x03a3, Hi: 0x03f5, Stride: 1}, + {Lo: 0x03f7, Hi: 0x0481, Stride: 1}, + {Lo: 0x048a, Hi: 0x052f, Stride: 1}, + {Lo: 0x0531, Hi: 0x0556, Stride: 1}, + {Lo: 0x0559, Hi: 0x0560, Stride: 7}, + {Lo: 0x0561, Hi: 0x0588, Stride: 1}, + {Lo: 0x05b0, Hi: 0x05bd, Stride: 1}, + {Lo: 0x05bf, Hi: 0x05c1, Stride: 2}, + {Lo: 0x05c2, Hi: 0x05c4, Stride: 2}, + {Lo: 0x05c5, Hi: 0x05c7, Stride: 2}, + {Lo: 0x05d0, Hi: 0x05ea, Stride: 1}, + {Lo: 0x05ef, Hi: 0x05f2, Stride: 1}, + {Lo: 0x0610, Hi: 0x061a, Stride: 1}, + {Lo: 0x0620, Hi: 0x0657, Stride: 1}, + {Lo: 0x0659, Hi: 0x0669, Stride: 1}, + {Lo: 0x066e, Hi: 0x06d3, Stride: 1}, + {Lo: 0x06d5, Hi: 0x06dc, Stride: 1}, + {Lo: 0x06e1, Hi: 0x06e8, Stride: 1}, + {Lo: 0x06ed, Hi: 0x06fc, Stride: 1}, + {Lo: 0x06ff, Hi: 0x0710, Stride: 17}, + {Lo: 0x0711, Hi: 0x073f, Stride: 1}, + {Lo: 0x074d, Hi: 0x07b1, Stride: 1}, + {Lo: 0x07c0, Hi: 0x07ea, Stride: 1}, + {Lo: 0x07f4, Hi: 0x07f5, Stride: 1}, + {Lo: 0x07fa, Hi: 0x0800, Stride: 6}, + {Lo: 0x0801, Hi: 0x0817, Stride: 1}, + {Lo: 0x081a, Hi: 0x082c, Stride: 1}, + {Lo: 0x0840, Hi: 0x0858, Stride: 1}, + {Lo: 0x0860, Hi: 0x086a, Stride: 1}, + {Lo: 0x0870, Hi: 0x0887, Stride: 1}, + {Lo: 0x0889, Hi: 0x088e, Stride: 1}, + {Lo: 0x08a0, Hi: 0x08c9, Stride: 1}, + {Lo: 0x08d4, Hi: 0x08df, Stride: 1}, + {Lo: 0x08e3, Hi: 0x08e9, Stride: 1}, + {Lo: 0x08f0, Hi: 0x093b, Stride: 1}, + {Lo: 0x093d, Hi: 0x094c, Stride: 1}, + {Lo: 0x094e, Hi: 0x0950, Stride: 1}, + {Lo: 0x0955, Hi: 0x0963, Stride: 1}, + {Lo: 0x0966, Hi: 0x096f, Stride: 1}, + {Lo: 0x0971, Hi: 0x0983, Stride: 1}, + {Lo: 0x0985, Hi: 0x098c, Stride: 1}, + {Lo: 0x098f, Hi: 0x0990, Stride: 1}, + {Lo: 0x0993, Hi: 0x09a8, Stride: 1}, + {Lo: 0x09aa, Hi: 0x09b0, Stride: 1}, + {Lo: 0x09b2, Hi: 0x09b6, Stride: 4}, + {Lo: 0x09b7, Hi: 0x09b9, Stride: 1}, + {Lo: 0x09bd, Hi: 0x09c4, Stride: 1}, + {Lo: 0x09c7, Hi: 0x09c8, Stride: 1}, + {Lo: 0x09cb, Hi: 0x09cc, Stride: 1}, + {Lo: 0x09ce, Hi: 0x09d7, Stride: 9}, + {Lo: 0x09dc, Hi: 0x09dd, Stride: 1}, + {Lo: 0x09df, Hi: 0x09e3, Stride: 1}, + {Lo: 0x09e6, Hi: 0x09f1, Stride: 1}, + {Lo: 0x09f4, Hi: 0x09f9, Stride: 1}, + {Lo: 0x09fc, Hi: 0x0a01, Stride: 5}, + {Lo: 0x0a02, Hi: 0x0a03, Stride: 1}, + {Lo: 0x0a05, Hi: 0x0a0a, Stride: 1}, + {Lo: 0x0a0f, Hi: 0x0a10, Stride: 1}, + {Lo: 0x0a13, Hi: 0x0a28, Stride: 1}, + {Lo: 0x0a2a, Hi: 0x0a30, Stride: 1}, + {Lo: 0x0a32, Hi: 0x0a33, Stride: 1}, + {Lo: 0x0a35, Hi: 0x0a36, Stride: 1}, + {Lo: 0x0a38, Hi: 0x0a39, Stride: 1}, + {Lo: 0x0a3e, Hi: 0x0a42, Stride: 1}, + {Lo: 0x0a47, Hi: 0x0a48, Stride: 1}, + {Lo: 0x0a4b, Hi: 0x0a4c, Stride: 1}, + {Lo: 0x0a51, Hi: 0x0a59, Stride: 8}, + {Lo: 0x0a5a, Hi: 0x0a5c, Stride: 1}, + {Lo: 0x0a5e, Hi: 0x0a66, Stride: 8}, + {Lo: 0x0a67, Hi: 0x0a75, Stride: 1}, + {Lo: 0x0a81, Hi: 0x0a83, Stride: 1}, + {Lo: 0x0a85, Hi: 0x0a8d, Stride: 1}, + {Lo: 0x0a8f, Hi: 0x0a91, Stride: 1}, + {Lo: 0x0a93, Hi: 0x0aa8, Stride: 1}, + {Lo: 0x0aaa, Hi: 0x0ab0, Stride: 1}, + {Lo: 0x0ab2, Hi: 0x0ab3, Stride: 1}, + {Lo: 0x0ab5, Hi: 0x0ab9, Stride: 1}, + {Lo: 0x0abd, Hi: 0x0ac5, Stride: 1}, + {Lo: 0x0ac7, Hi: 0x0ac9, Stride: 1}, + {Lo: 0x0acb, Hi: 0x0acc, Stride: 1}, + {Lo: 0x0ad0, Hi: 0x0ae0, Stride: 16}, + {Lo: 0x0ae1, Hi: 0x0ae3, Stride: 1}, + {Lo: 0x0ae6, Hi: 0x0aef, Stride: 1}, + {Lo: 0x0af9, Hi: 0x0afc, Stride: 1}, + {Lo: 0x0b01, Hi: 0x0b03, Stride: 1}, + {Lo: 0x0b05, Hi: 0x0b0c, Stride: 1}, + {Lo: 0x0b0f, Hi: 0x0b10, Stride: 1}, + {Lo: 0x0b13, Hi: 0x0b28, Stride: 1}, + {Lo: 0x0b2a, Hi: 0x0b30, Stride: 1}, + {Lo: 0x0b32, Hi: 0x0b33, Stride: 1}, + {Lo: 0x0b35, Hi: 0x0b39, Stride: 1}, + {Lo: 0x0b3d, Hi: 0x0b44, Stride: 1}, + {Lo: 0x0b47, Hi: 0x0b48, Stride: 1}, + {Lo: 0x0b4b, Hi: 0x0b4c, Stride: 1}, + {Lo: 0x0b56, Hi: 0x0b57, Stride: 1}, + {Lo: 0x0b5c, Hi: 0x0b5d, Stride: 1}, + {Lo: 0x0b5f, Hi: 0x0b63, Stride: 1}, + {Lo: 0x0b66, Hi: 0x0b6f, Stride: 1}, + {Lo: 0x0b71, Hi: 0x0b77, Stride: 1}, + {Lo: 0x0b82, Hi: 0x0b83, Stride: 1}, + {Lo: 0x0b85, Hi: 0x0b8a, Stride: 1}, + {Lo: 0x0b8e, Hi: 0x0b90, Stride: 1}, + {Lo: 0x0b92, Hi: 0x0b95, Stride: 1}, + {Lo: 0x0b99, Hi: 0x0b9a, Stride: 1}, + {Lo: 0x0b9c, Hi: 0x0b9e, Stride: 2}, + {Lo: 0x0b9f, Hi: 0x0ba3, Stride: 4}, + {Lo: 0x0ba4, Hi: 0x0ba8, Stride: 4}, + {Lo: 0x0ba9, Hi: 0x0baa, Stride: 1}, + {Lo: 0x0bae, Hi: 0x0bb9, Stride: 1}, + {Lo: 0x0bbe, Hi: 0x0bc2, Stride: 1}, + {Lo: 0x0bc6, Hi: 0x0bc8, Stride: 1}, + {Lo: 0x0bca, Hi: 0x0bcc, Stride: 1}, + {Lo: 0x0bd0, Hi: 0x0bd7, Stride: 7}, + {Lo: 0x0be6, Hi: 0x0bf2, Stride: 1}, + {Lo: 0x0c00, Hi: 0x0c0c, Stride: 1}, + {Lo: 0x0c0e, Hi: 0x0c10, Stride: 1}, + {Lo: 0x0c12, Hi: 0x0c28, Stride: 1}, + {Lo: 0x0c2a, Hi: 0x0c39, Stride: 1}, + {Lo: 0x0c3d, Hi: 0x0c44, Stride: 1}, + {Lo: 0x0c46, Hi: 0x0c48, Stride: 1}, + {Lo: 0x0c4a, Hi: 0x0c4c, Stride: 1}, + {Lo: 0x0c55, Hi: 0x0c56, Stride: 1}, + {Lo: 0x0c58, Hi: 0x0c5a, Stride: 1}, + {Lo: 0x0c5d, Hi: 0x0c60, Stride: 3}, + {Lo: 0x0c61, Hi: 0x0c63, Stride: 1}, + {Lo: 0x0c66, Hi: 0x0c6f, Stride: 1}, + {Lo: 0x0c78, Hi: 0x0c7e, Stride: 1}, + {Lo: 0x0c80, Hi: 0x0c83, Stride: 1}, + {Lo: 0x0c85, Hi: 0x0c8c, Stride: 1}, + {Lo: 0x0c8e, Hi: 0x0c90, Stride: 1}, + {Lo: 0x0c92, Hi: 0x0ca8, Stride: 1}, + {Lo: 0x0caa, Hi: 0x0cb3, Stride: 1}, + {Lo: 0x0cb5, Hi: 0x0cb9, Stride: 1}, + {Lo: 0x0cbd, Hi: 0x0cc4, Stride: 1}, + {Lo: 0x0cc6, Hi: 0x0cc8, Stride: 1}, + {Lo: 0x0cca, Hi: 0x0ccc, Stride: 1}, + {Lo: 0x0cd5, Hi: 0x0cd6, Stride: 1}, + {Lo: 0x0cdd, Hi: 0x0cde, Stride: 1}, + {Lo: 0x0ce0, Hi: 0x0ce3, Stride: 1}, + {Lo: 0x0ce6, Hi: 0x0cef, Stride: 1}, + {Lo: 0x0cf1, Hi: 0x0cf3, Stride: 1}, + {Lo: 0x0d00, Hi: 0x0d0c, Stride: 1}, + {Lo: 0x0d0e, Hi: 0x0d10, Stride: 1}, + {Lo: 0x0d12, Hi: 0x0d3a, Stride: 1}, + {Lo: 0x0d3d, Hi: 0x0d44, Stride: 1}, + {Lo: 0x0d46, Hi: 0x0d48, Stride: 1}, + {Lo: 0x0d4a, Hi: 0x0d4c, Stride: 1}, + {Lo: 0x0d4e, Hi: 0x0d54, Stride: 6}, + {Lo: 0x0d55, Hi: 0x0d63, Stride: 1}, + {Lo: 0x0d66, Hi: 0x0d78, Stride: 1}, + {Lo: 0x0d7a, Hi: 0x0d7f, Stride: 1}, + {Lo: 0x0d81, Hi: 0x0d83, Stride: 1}, + {Lo: 0x0d85, Hi: 0x0d96, Stride: 1}, + {Lo: 0x0d9a, Hi: 0x0db1, Stride: 1}, + {Lo: 0x0db3, Hi: 0x0dbb, Stride: 1}, + {Lo: 0x0dbd, Hi: 0x0dc0, Stride: 3}, + {Lo: 0x0dc1, Hi: 0x0dc6, Stride: 1}, + {Lo: 0x0dcf, Hi: 0x0dd4, Stride: 1}, + {Lo: 0x0dd6, Hi: 0x0dd8, Stride: 2}, + {Lo: 0x0dd9, Hi: 0x0ddf, Stride: 1}, + {Lo: 0x0de6, Hi: 0x0def, Stride: 1}, + {Lo: 0x0df2, Hi: 0x0df3, Stride: 1}, + {Lo: 0x0e01, Hi: 0x0e3a, Stride: 1}, + {Lo: 0x0e40, Hi: 0x0e46, Stride: 1}, + {Lo: 0x0e4d, Hi: 0x0e50, Stride: 3}, + {Lo: 0x0e51, Hi: 0x0e59, Stride: 1}, + {Lo: 0x0e81, Hi: 0x0e82, Stride: 1}, + {Lo: 0x0e84, Hi: 0x0e86, Stride: 2}, + {Lo: 0x0e87, Hi: 0x0e8a, Stride: 1}, + {Lo: 0x0e8c, Hi: 0x0ea3, Stride: 1}, + {Lo: 0x0ea5, Hi: 0x0ea7, Stride: 2}, + {Lo: 0x0ea8, Hi: 0x0eb9, Stride: 1}, + {Lo: 0x0ebb, Hi: 0x0ebd, Stride: 1}, + {Lo: 0x0ec0, Hi: 0x0ec4, Stride: 1}, + {Lo: 0x0ec6, Hi: 0x0ecd, Stride: 7}, + {Lo: 0x0ed0, Hi: 0x0ed9, Stride: 1}, + {Lo: 0x0edc, Hi: 0x0edf, Stride: 1}, + {Lo: 0x0f00, Hi: 0x0f20, Stride: 32}, + {Lo: 0x0f21, Hi: 0x0f33, Stride: 1}, + {Lo: 0x0f40, Hi: 0x0f47, Stride: 1}, + {Lo: 0x0f49, Hi: 0x0f6c, Stride: 1}, + {Lo: 0x0f71, Hi: 0x0f83, Stride: 1}, + {Lo: 0x0f88, Hi: 0x0f97, Stride: 1}, + {Lo: 0x0f99, Hi: 0x0fbc, Stride: 1}, + {Lo: 0x1000, Hi: 0x1036, Stride: 1}, + {Lo: 0x1038, Hi: 0x103b, Stride: 3}, + {Lo: 0x103c, Hi: 0x1049, Stride: 1}, + {Lo: 0x1050, Hi: 0x109d, Stride: 1}, + {Lo: 0x10a0, Hi: 0x10c5, Stride: 1}, + {Lo: 0x10c7, Hi: 0x10cd, Stride: 6}, + {Lo: 0x10d0, Hi: 0x10fa, Stride: 1}, + {Lo: 0x10fc, Hi: 0x1248, Stride: 1}, + {Lo: 0x124a, Hi: 0x124d, Stride: 1}, + {Lo: 0x1250, Hi: 0x1256, Stride: 1}, + {Lo: 0x1258, Hi: 0x125a, Stride: 2}, + {Lo: 0x125b, Hi: 0x125d, Stride: 1}, + {Lo: 0x1260, Hi: 0x1288, Stride: 1}, + {Lo: 0x128a, Hi: 0x128d, Stride: 1}, + {Lo: 0x1290, Hi: 0x12b0, Stride: 1}, + {Lo: 0x12b2, Hi: 0x12b5, Stride: 1}, + {Lo: 0x12b8, Hi: 0x12be, Stride: 1}, + {Lo: 0x12c0, Hi: 0x12c2, Stride: 2}, + {Lo: 0x12c3, Hi: 0x12c5, Stride: 1}, + {Lo: 0x12c8, Hi: 0x12d6, Stride: 1}, + {Lo: 0x12d8, Hi: 0x1310, Stride: 1}, + {Lo: 0x1312, Hi: 0x1315, Stride: 1}, + {Lo: 0x1318, Hi: 0x135a, Stride: 1}, + {Lo: 0x1369, Hi: 0x137c, Stride: 1}, + {Lo: 0x1380, Hi: 0x138f, Stride: 1}, + {Lo: 0x13a0, Hi: 0x13f5, Stride: 1}, + {Lo: 0x13f8, Hi: 0x13fd, Stride: 1}, + {Lo: 0x1401, Hi: 0x166c, Stride: 1}, + {Lo: 0x166f, Hi: 0x167f, Stride: 1}, + {Lo: 0x1681, Hi: 0x169a, Stride: 1}, + {Lo: 0x16a0, Hi: 0x16ea, Stride: 1}, + {Lo: 0x16ee, Hi: 0x16f8, Stride: 1}, + {Lo: 0x1700, Hi: 0x1713, Stride: 1}, + {Lo: 0x171f, Hi: 0x1733, Stride: 1}, + {Lo: 0x1740, Hi: 0x1753, Stride: 1}, + {Lo: 0x1760, Hi: 0x176c, Stride: 1}, + {Lo: 0x176e, Hi: 0x1770, Stride: 1}, + {Lo: 0x1772, Hi: 0x1773, Stride: 1}, + {Lo: 0x1780, Hi: 0x17b3, Stride: 1}, + {Lo: 0x17b6, Hi: 0x17c8, Stride: 1}, + {Lo: 0x17d7, Hi: 0x17dc, Stride: 5}, + {Lo: 0x17e0, Hi: 0x17e9, Stride: 1}, + {Lo: 0x17f0, Hi: 0x17f9, Stride: 1}, + {Lo: 0x1810, Hi: 0x1819, Stride: 1}, + {Lo: 0x1820, Hi: 0x1878, Stride: 1}, + {Lo: 0x1880, Hi: 0x18aa, Stride: 1}, + {Lo: 0x18b0, Hi: 0x18f5, Stride: 1}, + {Lo: 0x1900, Hi: 0x191e, Stride: 1}, + {Lo: 0x1920, Hi: 0x192b, Stride: 1}, + {Lo: 0x1930, Hi: 0x1938, Stride: 1}, + {Lo: 0x1946, Hi: 0x196d, Stride: 1}, + {Lo: 0x1970, Hi: 0x1974, Stride: 1}, + {Lo: 0x1980, Hi: 0x19ab, Stride: 1}, + {Lo: 0x19b0, Hi: 0x19c9, Stride: 1}, + {Lo: 0x19d0, Hi: 0x19da, Stride: 1}, + {Lo: 0x1a00, Hi: 0x1a1b, Stride: 1}, + {Lo: 0x1a20, Hi: 0x1a5e, Stride: 1}, + {Lo: 0x1a61, Hi: 0x1a74, Stride: 1}, + {Lo: 0x1a80, Hi: 0x1a89, Stride: 1}, + {Lo: 0x1a90, Hi: 0x1a99, Stride: 1}, + {Lo: 0x1aa7, Hi: 0x1abf, Stride: 24}, + {Lo: 0x1ac0, Hi: 0x1acc, Stride: 12}, + {Lo: 0x1acd, Hi: 0x1ace, Stride: 1}, + {Lo: 0x1b00, Hi: 0x1b33, Stride: 1}, + {Lo: 0x1b35, Hi: 0x1b43, Stride: 1}, + {Lo: 0x1b45, Hi: 0x1b4c, Stride: 1}, + {Lo: 0x1b50, Hi: 0x1b59, Stride: 1}, + {Lo: 0x1b80, Hi: 0x1ba9, Stride: 1}, + {Lo: 0x1bac, Hi: 0x1be5, Stride: 1}, + {Lo: 0x1be7, Hi: 0x1bf1, Stride: 1}, + {Lo: 0x1c00, Hi: 0x1c36, Stride: 1}, + {Lo: 0x1c40, Hi: 0x1c49, Stride: 1}, + {Lo: 0x1c4d, Hi: 0x1c7d, Stride: 1}, + {Lo: 0x1c80, Hi: 0x1c88, Stride: 1}, + {Lo: 0x1c90, Hi: 0x1cba, Stride: 1}, + {Lo: 0x1cbd, Hi: 0x1cbf, Stride: 1}, + {Lo: 0x1ce9, Hi: 0x1cec, Stride: 1}, + {Lo: 0x1cee, Hi: 0x1cf3, Stride: 1}, + {Lo: 0x1cf5, Hi: 0x1cf6, Stride: 1}, + {Lo: 0x1cfa, Hi: 0x1d00, Stride: 6}, + {Lo: 0x1d01, Hi: 0x1dbf, Stride: 1}, + {Lo: 0x1de7, Hi: 0x1df4, Stride: 1}, + {Lo: 0x1e00, Hi: 0x1f15, Stride: 1}, + {Lo: 0x1f18, Hi: 0x1f1d, Stride: 1}, + {Lo: 0x1f20, Hi: 0x1f45, Stride: 1}, + {Lo: 0x1f48, Hi: 0x1f4d, Stride: 1}, + {Lo: 0x1f50, Hi: 0x1f57, Stride: 1}, + {Lo: 0x1f59, Hi: 0x1f5f, Stride: 2}, + {Lo: 0x1f60, Hi: 0x1f7d, Stride: 1}, + {Lo: 0x1f80, Hi: 0x1fb4, Stride: 1}, + {Lo: 0x1fb6, Hi: 0x1fbc, Stride: 1}, + {Lo: 0x1fbe, Hi: 0x1fc2, Stride: 4}, + {Lo: 0x1fc3, Hi: 0x1fc4, Stride: 1}, + {Lo: 0x1fc6, Hi: 0x1fcc, Stride: 1}, + {Lo: 0x1fd0, Hi: 0x1fd3, Stride: 1}, + {Lo: 0x1fd6, Hi: 0x1fdb, Stride: 1}, + {Lo: 0x1fe0, Hi: 0x1fec, Stride: 1}, + {Lo: 0x1ff2, Hi: 0x1ff4, Stride: 1}, + {Lo: 0x1ff6, Hi: 0x1ffc, Stride: 1}, + {Lo: 0x2070, Hi: 0x2071, Stride: 1}, + {Lo: 0x2074, Hi: 0x2079, Stride: 1}, + {Lo: 0x207f, Hi: 0x2089, Stride: 1}, + {Lo: 0x2090, Hi: 0x209c, Stride: 1}, + {Lo: 0x2102, Hi: 0x2107, Stride: 5}, + {Lo: 0x210a, Hi: 0x2113, Stride: 1}, + {Lo: 0x2115, Hi: 0x2119, Stride: 4}, + {Lo: 0x211a, Hi: 0x211d, Stride: 1}, + {Lo: 0x2124, Hi: 0x212a, Stride: 2}, + {Lo: 0x212b, Hi: 0x212d, Stride: 1}, + {Lo: 0x212f, Hi: 0x2139, Stride: 1}, + {Lo: 0x213c, Hi: 0x213f, Stride: 1}, + {Lo: 0x2145, Hi: 0x2149, Stride: 1}, + {Lo: 0x214e, Hi: 0x2150, Stride: 2}, + {Lo: 0x2151, Hi: 0x2189, Stride: 1}, + {Lo: 0x2460, Hi: 0x249b, Stride: 1}, + {Lo: 0x24b6, Hi: 0x24ff, Stride: 1}, + {Lo: 0x2776, Hi: 0x2793, Stride: 1}, + {Lo: 0x2c00, Hi: 0x2ce4, Stride: 1}, + {Lo: 0x2ceb, Hi: 0x2cee, Stride: 1}, + {Lo: 0x2cf2, Hi: 0x2cf3, Stride: 1}, + {Lo: 0x2cfd, Hi: 0x2d00, Stride: 3}, + {Lo: 0x2d01, Hi: 0x2d25, Stride: 1}, + {Lo: 0x2d27, Hi: 0x2d2d, Stride: 6}, + {Lo: 0x2d30, Hi: 0x2d67, Stride: 1}, + {Lo: 0x2d6f, Hi: 0x2d80, Stride: 17}, + {Lo: 0x2d81, Hi: 0x2d96, Stride: 1}, + {Lo: 0x2da0, Hi: 0x2da6, Stride: 1}, + {Lo: 0x2da8, Hi: 0x2dae, Stride: 1}, + {Lo: 0x2db0, Hi: 0x2db6, Stride: 1}, + {Lo: 0x2db8, Hi: 0x2dbe, Stride: 1}, + {Lo: 0x2dc0, Hi: 0x2dc6, Stride: 1}, + {Lo: 0x2dc8, Hi: 0x2dce, Stride: 1}, + {Lo: 0x2dd0, Hi: 0x2dd6, Stride: 1}, + {Lo: 0x2dd8, Hi: 0x2dde, Stride: 1}, + {Lo: 0x2de0, Hi: 0x2dff, Stride: 1}, + {Lo: 0x2e2f, Hi: 0x3005, Stride: 470}, + {Lo: 0x3006, Hi: 0x3007, Stride: 1}, + {Lo: 0x3021, Hi: 0x3029, Stride: 1}, + {Lo: 0x3031, Hi: 0x3035, Stride: 1}, + {Lo: 0x3038, Hi: 0x303c, Stride: 1}, + {Lo: 0x3041, Hi: 0x3096, Stride: 1}, + {Lo: 0x309d, Hi: 0x309f, Stride: 1}, + {Lo: 0x30a1, Hi: 0x30fa, Stride: 1}, + {Lo: 0x30fc, Hi: 0x30ff, Stride: 1}, + {Lo: 0x3105, Hi: 0x312f, Stride: 1}, + {Lo: 0x3131, Hi: 0x318e, Stride: 1}, + {Lo: 0x3192, Hi: 0x3195, Stride: 1}, + {Lo: 0x31a0, Hi: 0x31bf, Stride: 1}, + {Lo: 0x31f0, Hi: 0x31ff, Stride: 1}, + {Lo: 0x3220, Hi: 0x3229, Stride: 1}, + {Lo: 0x3248, Hi: 0x324f, Stride: 1}, + {Lo: 0x3251, Hi: 0x325f, Stride: 1}, + {Lo: 0x3280, Hi: 0x3289, Stride: 1}, + {Lo: 0x32b1, Hi: 0x32bf, Stride: 1}, + {Lo: 0x3400, Hi: 0x4dbf, Stride: 1}, + {Lo: 0x4e00, Hi: 0xa48c, Stride: 1}, + {Lo: 0xa4d0, Hi: 0xa4fd, Stride: 1}, + {Lo: 0xa500, Hi: 0xa60c, Stride: 1}, + {Lo: 0xa610, Hi: 0xa62b, Stride: 1}, + {Lo: 0xa640, Hi: 0xa66e, Stride: 1}, + {Lo: 0xa674, Hi: 0xa67b, Stride: 1}, + {Lo: 0xa67f, Hi: 0xa6ef, Stride: 1}, + {Lo: 0xa717, Hi: 0xa71f, Stride: 1}, + {Lo: 0xa722, Hi: 0xa788, Stride: 1}, + {Lo: 0xa78b, Hi: 0xa7ca, Stride: 1}, + {Lo: 0xa7d0, Hi: 0xa7d1, Stride: 1}, + {Lo: 0xa7d3, Hi: 0xa7d5, Stride: 2}, + {Lo: 0xa7d6, Hi: 0xa7d9, Stride: 1}, + {Lo: 0xa7f2, Hi: 0xa805, Stride: 1}, + {Lo: 0xa807, Hi: 0xa827, Stride: 1}, + {Lo: 0xa830, Hi: 0xa835, Stride: 1}, + {Lo: 0xa840, Hi: 0xa873, Stride: 1}, + {Lo: 0xa880, Hi: 0xa8c3, Stride: 1}, + {Lo: 0xa8c5, Hi: 0xa8d0, Stride: 11}, + {Lo: 0xa8d1, Hi: 0xa8d9, Stride: 1}, + {Lo: 0xa8f2, Hi: 0xa8f7, Stride: 1}, + {Lo: 0xa8fb, Hi: 0xa8fd, Stride: 2}, + {Lo: 0xa8fe, Hi: 0xa92a, Stride: 1}, + {Lo: 0xa930, Hi: 0xa952, Stride: 1}, + {Lo: 0xa960, Hi: 0xa97c, Stride: 1}, + {Lo: 0xa980, Hi: 0xa9b2, Stride: 1}, + {Lo: 0xa9b4, Hi: 0xa9bf, Stride: 1}, + {Lo: 0xa9cf, Hi: 0xa9d9, Stride: 1}, + {Lo: 0xa9e0, Hi: 0xa9fe, Stride: 1}, + {Lo: 0xaa00, Hi: 0xaa36, Stride: 1}, + {Lo: 0xaa40, Hi: 0xaa4d, Stride: 1}, + {Lo: 0xaa50, Hi: 0xaa59, Stride: 1}, + {Lo: 0xaa60, Hi: 0xaa76, Stride: 1}, + {Lo: 0xaa7a, Hi: 0xaabe, Stride: 1}, + {Lo: 0xaac0, Hi: 0xaac2, Stride: 2}, + {Lo: 0xaadb, Hi: 0xaadd, Stride: 1}, + {Lo: 0xaae0, Hi: 0xaaef, Stride: 1}, + {Lo: 0xaaf2, Hi: 0xaaf5, Stride: 1}, + {Lo: 0xab01, Hi: 0xab06, Stride: 1}, + {Lo: 0xab09, Hi: 0xab0e, Stride: 1}, + {Lo: 0xab11, Hi: 0xab16, Stride: 1}, + {Lo: 0xab20, Hi: 0xab26, Stride: 1}, + {Lo: 0xab28, Hi: 0xab2e, Stride: 1}, + {Lo: 0xab30, Hi: 0xab5a, Stride: 1}, + {Lo: 0xab5c, Hi: 0xab69, Stride: 1}, + {Lo: 0xab70, Hi: 0xabea, Stride: 1}, + {Lo: 0xabf0, Hi: 0xabf9, Stride: 1}, + {Lo: 0xac00, Hi: 0xd7a3, Stride: 1}, + {Lo: 0xd7b0, Hi: 0xd7c6, Stride: 1}, + {Lo: 0xd7cb, Hi: 0xd7fb, Stride: 1}, + {Lo: 0xf900, Hi: 0xfa6d, Stride: 1}, + {Lo: 0xfa70, Hi: 0xfad9, Stride: 1}, + {Lo: 0xfb00, Hi: 0xfb06, Stride: 1}, + {Lo: 0xfb13, Hi: 0xfb17, Stride: 1}, + {Lo: 0xfb1d, Hi: 0xfb28, Stride: 1}, + {Lo: 0xfb2a, Hi: 0xfb36, Stride: 1}, + {Lo: 0xfb38, Hi: 0xfb3c, Stride: 1}, + {Lo: 0xfb3e, Hi: 0xfb40, Stride: 2}, + {Lo: 0xfb41, Hi: 0xfb43, Stride: 2}, + {Lo: 0xfb44, Hi: 0xfb46, Stride: 2}, + {Lo: 0xfb47, Hi: 0xfbb1, Stride: 1}, + {Lo: 0xfbd3, Hi: 0xfd3d, Stride: 1}, + {Lo: 0xfd50, Hi: 0xfd8f, Stride: 1}, + {Lo: 0xfd92, Hi: 0xfdc7, Stride: 1}, + {Lo: 0xfdf0, Hi: 0xfdfb, Stride: 1}, + {Lo: 0xfe70, Hi: 0xfe74, Stride: 1}, + {Lo: 0xfe76, Hi: 0xfefc, Stride: 1}, + {Lo: 0xff10, Hi: 0xff19, Stride: 1}, + {Lo: 0xff21, Hi: 0xff3a, Stride: 1}, + {Lo: 0xff41, Hi: 0xff5a, Stride: 1}, + {Lo: 0xff66, Hi: 0xffbe, Stride: 1}, + {Lo: 0xffc2, Hi: 0xffc7, Stride: 1}, + {Lo: 0xffca, Hi: 0xffcf, Stride: 1}, + {Lo: 0xffd2, Hi: 0xffd7, Stride: 1}, + {Lo: 0xffda, Hi: 0xffdc, Stride: 1}, + }, + R32: []unicode.Range32{ + {Lo: 0x10000, Hi: 0x1000b, Stride: 1}, + {Lo: 0x1000d, Hi: 0x10026, Stride: 1}, + {Lo: 0x10028, Hi: 0x1003a, Stride: 1}, + {Lo: 0x1003c, Hi: 0x1003d, Stride: 1}, + {Lo: 0x1003f, Hi: 0x1004d, Stride: 1}, + {Lo: 0x10050, Hi: 0x1005d, Stride: 1}, + {Lo: 0x10080, Hi: 0x100fa, Stride: 1}, + {Lo: 0x10107, Hi: 0x10133, Stride: 1}, + {Lo: 0x10140, Hi: 0x10178, Stride: 1}, + {Lo: 0x1018a, Hi: 0x1018b, Stride: 1}, + {Lo: 0x10280, Hi: 0x1029c, Stride: 1}, + {Lo: 0x102a0, Hi: 0x102d0, Stride: 1}, + {Lo: 0x102e1, Hi: 0x102fb, Stride: 1}, + {Lo: 0x10300, Hi: 0x10323, Stride: 1}, + {Lo: 0x1032d, Hi: 0x1034a, Stride: 1}, + {Lo: 0x10350, Hi: 0x1037a, Stride: 1}, + {Lo: 0x10380, Hi: 0x1039d, Stride: 1}, + {Lo: 0x103a0, Hi: 0x103c3, Stride: 1}, + {Lo: 0x103c8, Hi: 0x103cf, Stride: 1}, + {Lo: 0x103d1, Hi: 0x103d5, Stride: 1}, + {Lo: 0x10400, Hi: 0x1049d, Stride: 1}, + {Lo: 0x104a0, Hi: 0x104a9, Stride: 1}, + {Lo: 0x104b0, Hi: 0x104d3, Stride: 1}, + {Lo: 0x104d8, Hi: 0x104fb, Stride: 1}, + {Lo: 0x10500, Hi: 0x10527, Stride: 1}, + {Lo: 0x10530, Hi: 0x10563, Stride: 1}, + {Lo: 0x10570, Hi: 0x1057a, Stride: 1}, + {Lo: 0x1057c, Hi: 0x1058a, Stride: 1}, + {Lo: 0x1058c, Hi: 0x10592, Stride: 1}, + {Lo: 0x10594, Hi: 0x10595, Stride: 1}, + {Lo: 0x10597, Hi: 0x105a1, Stride: 1}, + {Lo: 0x105a3, Hi: 0x105b1, Stride: 1}, + {Lo: 0x105b3, Hi: 0x105b9, Stride: 1}, + {Lo: 0x105bb, Hi: 0x105bc, Stride: 1}, + {Lo: 0x10600, Hi: 0x10736, Stride: 1}, + {Lo: 0x10740, Hi: 0x10755, Stride: 1}, + {Lo: 0x10760, Hi: 0x10767, Stride: 1}, + {Lo: 0x10780, Hi: 0x10785, Stride: 1}, + {Lo: 0x10787, Hi: 0x107b0, Stride: 1}, + {Lo: 0x107b2, Hi: 0x107ba, Stride: 1}, + {Lo: 0x10800, Hi: 0x10805, Stride: 1}, + {Lo: 0x10808, Hi: 0x1080a, Stride: 2}, + {Lo: 0x1080b, Hi: 0x10835, Stride: 1}, + {Lo: 0x10837, Hi: 0x10838, Stride: 1}, + {Lo: 0x1083c, Hi: 0x1083f, Stride: 3}, + {Lo: 0x10840, Hi: 0x10855, Stride: 1}, + {Lo: 0x10858, Hi: 0x10876, Stride: 1}, + {Lo: 0x10879, Hi: 0x1089e, Stride: 1}, + {Lo: 0x108a7, Hi: 0x108af, Stride: 1}, + {Lo: 0x108e0, Hi: 0x108f2, Stride: 1}, + {Lo: 0x108f4, Hi: 0x108f5, Stride: 1}, + {Lo: 0x108fb, Hi: 0x1091b, Stride: 1}, + {Lo: 0x10920, Hi: 0x10939, Stride: 1}, + {Lo: 0x10980, Hi: 0x109b7, Stride: 1}, + {Lo: 0x109bc, Hi: 0x109cf, Stride: 1}, + {Lo: 0x109d2, Hi: 0x10a03, Stride: 1}, + {Lo: 0x10a05, Hi: 0x10a06, Stride: 1}, + {Lo: 0x10a0c, Hi: 0x10a13, Stride: 1}, + {Lo: 0x10a15, Hi: 0x10a17, Stride: 1}, + {Lo: 0x10a19, Hi: 0x10a35, Stride: 1}, + {Lo: 0x10a40, Hi: 0x10a48, Stride: 1}, + {Lo: 0x10a60, Hi: 0x10a7e, Stride: 1}, + {Lo: 0x10a80, Hi: 0x10a9f, Stride: 1}, + {Lo: 0x10ac0, Hi: 0x10ac7, Stride: 1}, + {Lo: 0x10ac9, Hi: 0x10ae4, Stride: 1}, + {Lo: 0x10aeb, Hi: 0x10aef, Stride: 1}, + {Lo: 0x10b00, Hi: 0x10b35, Stride: 1}, + {Lo: 0x10b40, Hi: 0x10b55, Stride: 1}, + {Lo: 0x10b58, Hi: 0x10b72, Stride: 1}, + {Lo: 0x10b78, Hi: 0x10b91, Stride: 1}, + {Lo: 0x10ba9, Hi: 0x10baf, Stride: 1}, + {Lo: 0x10c00, Hi: 0x10c48, Stride: 1}, + {Lo: 0x10c80, Hi: 0x10cb2, Stride: 1}, + {Lo: 0x10cc0, Hi: 0x10cf2, Stride: 1}, + {Lo: 0x10cfa, Hi: 0x10d27, Stride: 1}, + {Lo: 0x10d30, Hi: 0x10d39, Stride: 1}, + {Lo: 0x10e60, Hi: 0x10e7e, Stride: 1}, + {Lo: 0x10e80, Hi: 0x10ea9, Stride: 1}, + {Lo: 0x10eab, Hi: 0x10eac, Stride: 1}, + {Lo: 0x10eb0, Hi: 0x10eb1, Stride: 1}, + {Lo: 0x10f00, Hi: 0x10f27, Stride: 1}, + {Lo: 0x10f30, Hi: 0x10f45, Stride: 1}, + {Lo: 0x10f51, Hi: 0x10f54, Stride: 1}, + {Lo: 0x10f70, Hi: 0x10f81, Stride: 1}, + {Lo: 0x10fb0, Hi: 0x10fcb, Stride: 1}, + {Lo: 0x10fe0, Hi: 0x10ff6, Stride: 1}, + {Lo: 0x11000, Hi: 0x11045, Stride: 1}, + {Lo: 0x11052, Hi: 0x1106f, Stride: 1}, + {Lo: 0x11071, Hi: 0x11075, Stride: 1}, + {Lo: 0x11080, Hi: 0x110b8, Stride: 1}, + {Lo: 0x110c2, Hi: 0x110d0, Stride: 14}, + {Lo: 0x110d1, Hi: 0x110e8, Stride: 1}, + {Lo: 0x110f0, Hi: 0x110f9, Stride: 1}, + {Lo: 0x11100, Hi: 0x11132, Stride: 1}, + {Lo: 0x11136, Hi: 0x1113f, Stride: 1}, + {Lo: 0x11144, Hi: 0x11147, Stride: 1}, + {Lo: 0x11150, Hi: 0x11172, Stride: 1}, + {Lo: 0x11176, Hi: 0x11180, Stride: 10}, + {Lo: 0x11181, Hi: 0x111bf, Stride: 1}, + {Lo: 0x111c1, Hi: 0x111c4, Stride: 1}, + {Lo: 0x111ce, Hi: 0x111da, Stride: 1}, + {Lo: 0x111dc, Hi: 0x111e1, Stride: 5}, + {Lo: 0x111e2, Hi: 0x111f4, Stride: 1}, + {Lo: 0x11200, Hi: 0x11211, Stride: 1}, + {Lo: 0x11213, Hi: 0x11234, Stride: 1}, + {Lo: 0x11237, Hi: 0x1123e, Stride: 7}, + {Lo: 0x1123f, Hi: 0x11241, Stride: 1}, + {Lo: 0x11280, Hi: 0x11286, Stride: 1}, + {Lo: 0x11288, Hi: 0x1128a, Stride: 2}, + {Lo: 0x1128b, Hi: 0x1128d, Stride: 1}, + {Lo: 0x1128f, Hi: 0x1129d, Stride: 1}, + {Lo: 0x1129f, Hi: 0x112a8, Stride: 1}, + {Lo: 0x112b0, Hi: 0x112e8, Stride: 1}, + {Lo: 0x112f0, Hi: 0x112f9, Stride: 1}, + {Lo: 0x11300, Hi: 0x11303, Stride: 1}, + {Lo: 0x11305, Hi: 0x1130c, Stride: 1}, + {Lo: 0x1130f, Hi: 0x11310, Stride: 1}, + {Lo: 0x11313, Hi: 0x11328, Stride: 1}, + {Lo: 0x1132a, Hi: 0x11330, Stride: 1}, + {Lo: 0x11332, Hi: 0x11333, Stride: 1}, + {Lo: 0x11335, Hi: 0x11339, Stride: 1}, + {Lo: 0x1133d, Hi: 0x11344, Stride: 1}, + {Lo: 0x11347, Hi: 0x11348, Stride: 1}, + {Lo: 0x1134b, Hi: 0x1134c, Stride: 1}, + {Lo: 0x11350, Hi: 0x11357, Stride: 7}, + {Lo: 0x1135d, Hi: 0x11363, Stride: 1}, + {Lo: 0x11400, Hi: 0x11441, Stride: 1}, + {Lo: 0x11443, Hi: 0x11445, Stride: 1}, + {Lo: 0x11447, Hi: 0x1144a, Stride: 1}, + {Lo: 0x11450, Hi: 0x11459, Stride: 1}, + {Lo: 0x1145f, Hi: 0x11461, Stride: 1}, + {Lo: 0x11480, Hi: 0x114c1, Stride: 1}, + {Lo: 0x114c4, Hi: 0x114c5, Stride: 1}, + {Lo: 0x114c7, Hi: 0x114d0, Stride: 9}, + {Lo: 0x114d1, Hi: 0x114d9, Stride: 1}, + {Lo: 0x11580, Hi: 0x115b5, Stride: 1}, + {Lo: 0x115b8, Hi: 0x115be, Stride: 1}, + {Lo: 0x115d8, Hi: 0x115dd, Stride: 1}, + {Lo: 0x11600, Hi: 0x1163e, Stride: 1}, + {Lo: 0x11640, Hi: 0x11644, Stride: 4}, + {Lo: 0x11650, Hi: 0x11659, Stride: 1}, + {Lo: 0x11680, Hi: 0x116b5, Stride: 1}, + {Lo: 0x116b8, Hi: 0x116c0, Stride: 8}, + {Lo: 0x116c1, Hi: 0x116c9, Stride: 1}, + {Lo: 0x11700, Hi: 0x1171a, Stride: 1}, + {Lo: 0x1171d, Hi: 0x1172a, Stride: 1}, + {Lo: 0x11730, Hi: 0x1173b, Stride: 1}, + {Lo: 0x11740, Hi: 0x11746, Stride: 1}, + {Lo: 0x11800, Hi: 0x11838, Stride: 1}, + {Lo: 0x118a0, Hi: 0x118f2, Stride: 1}, + {Lo: 0x118ff, Hi: 0x11906, Stride: 1}, + {Lo: 0x11909, Hi: 0x1190c, Stride: 3}, + {Lo: 0x1190d, Hi: 0x11913, Stride: 1}, + {Lo: 0x11915, Hi: 0x11916, Stride: 1}, + {Lo: 0x11918, Hi: 0x11935, Stride: 1}, + {Lo: 0x11937, Hi: 0x11938, Stride: 1}, + {Lo: 0x1193b, Hi: 0x1193c, Stride: 1}, + {Lo: 0x1193f, Hi: 0x11942, Stride: 1}, + {Lo: 0x11950, Hi: 0x11959, Stride: 1}, + {Lo: 0x119a0, Hi: 0x119a7, Stride: 1}, + {Lo: 0x119aa, Hi: 0x119d7, Stride: 1}, + {Lo: 0x119da, Hi: 0x119df, Stride: 1}, + {Lo: 0x119e1, Hi: 0x119e3, Stride: 2}, + {Lo: 0x119e4, Hi: 0x11a00, Stride: 28}, + {Lo: 0x11a01, Hi: 0x11a32, Stride: 1}, + {Lo: 0x11a35, Hi: 0x11a3e, Stride: 1}, + {Lo: 0x11a50, Hi: 0x11a97, Stride: 1}, + {Lo: 0x11a9d, Hi: 0x11ab0, Stride: 19}, + {Lo: 0x11ab1, Hi: 0x11af8, Stride: 1}, + {Lo: 0x11c00, Hi: 0x11c08, Stride: 1}, + {Lo: 0x11c0a, Hi: 0x11c36, Stride: 1}, + {Lo: 0x11c38, Hi: 0x11c3e, Stride: 1}, + {Lo: 0x11c40, Hi: 0x11c50, Stride: 16}, + {Lo: 0x11c51, Hi: 0x11c6c, Stride: 1}, + {Lo: 0x11c72, Hi: 0x11c8f, Stride: 1}, + {Lo: 0x11c92, Hi: 0x11ca7, Stride: 1}, + {Lo: 0x11ca9, Hi: 0x11cb6, Stride: 1}, + {Lo: 0x11d00, Hi: 0x11d06, Stride: 1}, + {Lo: 0x11d08, Hi: 0x11d09, Stride: 1}, + {Lo: 0x11d0b, Hi: 0x11d36, Stride: 1}, + {Lo: 0x11d3a, Hi: 0x11d3c, Stride: 2}, + {Lo: 0x11d3d, Hi: 0x11d3f, Stride: 2}, + {Lo: 0x11d40, Hi: 0x11d41, Stride: 1}, + {Lo: 0x11d43, Hi: 0x11d46, Stride: 3}, + {Lo: 0x11d47, Hi: 0x11d50, Stride: 9}, + {Lo: 0x11d51, Hi: 0x11d59, Stride: 1}, + {Lo: 0x11d60, Hi: 0x11d65, Stride: 1}, + {Lo: 0x11d67, Hi: 0x11d68, Stride: 1}, + {Lo: 0x11d6a, Hi: 0x11d8e, Stride: 1}, + {Lo: 0x11d90, Hi: 0x11d91, Stride: 1}, + {Lo: 0x11d93, Hi: 0x11d96, Stride: 1}, + {Lo: 0x11d98, Hi: 0x11da0, Stride: 8}, + {Lo: 0x11da1, Hi: 0x11da9, Stride: 1}, + {Lo: 0x11ee0, Hi: 0x11ef6, Stride: 1}, + {Lo: 0x11f00, Hi: 0x11f10, Stride: 1}, + {Lo: 0x11f12, Hi: 0x11f3a, Stride: 1}, + {Lo: 0x11f3e, Hi: 0x11f40, Stride: 1}, + {Lo: 0x11f50, Hi: 0x11f59, Stride: 1}, + {Lo: 0x11fb0, Hi: 0x11fc0, Stride: 16}, + {Lo: 0x11fc1, Hi: 0x11fd4, Stride: 1}, + {Lo: 0x12000, Hi: 0x12399, Stride: 1}, + {Lo: 0x12400, Hi: 0x1246e, Stride: 1}, + {Lo: 0x12480, Hi: 0x12543, Stride: 1}, + {Lo: 0x12f90, Hi: 0x12ff0, Stride: 1}, + {Lo: 0x13000, Hi: 0x1342f, Stride: 1}, + {Lo: 0x13441, Hi: 0x13446, Stride: 1}, + {Lo: 0x14400, Hi: 0x14646, Stride: 1}, + {Lo: 0x16800, Hi: 0x16a38, Stride: 1}, + {Lo: 0x16a40, Hi: 0x16a5e, Stride: 1}, + {Lo: 0x16a60, Hi: 0x16a69, Stride: 1}, + {Lo: 0x16a70, Hi: 0x16abe, Stride: 1}, + {Lo: 0x16ac0, Hi: 0x16ac9, Stride: 1}, + {Lo: 0x16ad0, Hi: 0x16aed, Stride: 1}, + {Lo: 0x16b00, Hi: 0x16b2f, Stride: 1}, + {Lo: 0x16b40, Hi: 0x16b43, Stride: 1}, + {Lo: 0x16b50, Hi: 0x16b59, Stride: 1}, + {Lo: 0x16b5b, Hi: 0x16b61, Stride: 1}, + {Lo: 0x16b63, Hi: 0x16b77, Stride: 1}, + {Lo: 0x16b7d, Hi: 0x16b8f, Stride: 1}, + {Lo: 0x16e40, Hi: 0x16e96, Stride: 1}, + {Lo: 0x16f00, Hi: 0x16f4a, Stride: 1}, + {Lo: 0x16f4f, Hi: 0x16f87, Stride: 1}, + {Lo: 0x16f8f, Hi: 0x16f9f, Stride: 1}, + {Lo: 0x16fe0, Hi: 0x16fe1, Stride: 1}, + {Lo: 0x16fe3, Hi: 0x16ff0, Stride: 13}, + {Lo: 0x16ff1, Hi: 0x17000, Stride: 15}, + {Lo: 0x17001, Hi: 0x187f7, Stride: 1}, + {Lo: 0x18800, Hi: 0x18cd5, Stride: 1}, + {Lo: 0x18d00, Hi: 0x18d08, Stride: 1}, + {Lo: 0x1aff0, Hi: 0x1aff3, Stride: 1}, + {Lo: 0x1aff5, Hi: 0x1affb, Stride: 1}, + {Lo: 0x1affd, Hi: 0x1affe, Stride: 1}, + {Lo: 0x1b000, Hi: 0x1b122, Stride: 1}, + {Lo: 0x1b132, Hi: 0x1b150, Stride: 30}, + {Lo: 0x1b151, Hi: 0x1b152, Stride: 1}, + {Lo: 0x1b155, Hi: 0x1b164, Stride: 15}, + {Lo: 0x1b165, Hi: 0x1b167, Stride: 1}, + {Lo: 0x1b170, Hi: 0x1b2fb, Stride: 1}, + {Lo: 0x1bc00, Hi: 0x1bc6a, Stride: 1}, + {Lo: 0x1bc70, Hi: 0x1bc7c, Stride: 1}, + {Lo: 0x1bc80, Hi: 0x1bc88, Stride: 1}, + {Lo: 0x1bc90, Hi: 0x1bc99, Stride: 1}, + {Lo: 0x1bc9e, Hi: 0x1d2c0, Stride: 5666}, + {Lo: 0x1d2c1, Hi: 0x1d2d3, Stride: 1}, + {Lo: 0x1d2e0, Hi: 0x1d2f3, Stride: 1}, + {Lo: 0x1d360, Hi: 0x1d378, Stride: 1}, + {Lo: 0x1d400, Hi: 0x1d454, Stride: 1}, + {Lo: 0x1d456, Hi: 0x1d49c, Stride: 1}, + {Lo: 0x1d49e, Hi: 0x1d49f, Stride: 1}, + {Lo: 0x1d4a2, Hi: 0x1d4a5, Stride: 3}, + {Lo: 0x1d4a6, Hi: 0x1d4a9, Stride: 3}, + {Lo: 0x1d4aa, Hi: 0x1d4ac, Stride: 1}, + {Lo: 0x1d4ae, Hi: 0x1d4b9, Stride: 1}, + {Lo: 0x1d4bb, Hi: 0x1d4bd, Stride: 2}, + {Lo: 0x1d4be, Hi: 0x1d4c3, Stride: 1}, + {Lo: 0x1d4c5, Hi: 0x1d505, Stride: 1}, + {Lo: 0x1d507, Hi: 0x1d50a, Stride: 1}, + {Lo: 0x1d50d, Hi: 0x1d514, Stride: 1}, + {Lo: 0x1d516, Hi: 0x1d51c, Stride: 1}, + {Lo: 0x1d51e, Hi: 0x1d539, Stride: 1}, + {Lo: 0x1d53b, Hi: 0x1d53e, Stride: 1}, + {Lo: 0x1d540, Hi: 0x1d544, Stride: 1}, + {Lo: 0x1d546, Hi: 0x1d54a, Stride: 4}, + {Lo: 0x1d54b, Hi: 0x1d550, Stride: 1}, + {Lo: 0x1d552, Hi: 0x1d6a5, Stride: 1}, + {Lo: 0x1d6a8, Hi: 0x1d6c0, Stride: 1}, + {Lo: 0x1d6c2, Hi: 0x1d6da, Stride: 1}, + {Lo: 0x1d6dc, Hi: 0x1d6fa, Stride: 1}, + {Lo: 0x1d6fc, Hi: 0x1d714, Stride: 1}, + {Lo: 0x1d716, Hi: 0x1d734, Stride: 1}, + {Lo: 0x1d736, Hi: 0x1d74e, Stride: 1}, + {Lo: 0x1d750, Hi: 0x1d76e, Stride: 1}, + {Lo: 0x1d770, Hi: 0x1d788, Stride: 1}, + {Lo: 0x1d78a, Hi: 0x1d7a8, Stride: 1}, + {Lo: 0x1d7aa, Hi: 0x1d7c2, Stride: 1}, + {Lo: 0x1d7c4, Hi: 0x1d7cb, Stride: 1}, + {Lo: 0x1d7ce, Hi: 0x1d7ff, Stride: 1}, + {Lo: 0x1df00, Hi: 0x1df1e, Stride: 1}, + {Lo: 0x1df25, Hi: 0x1df2a, Stride: 1}, + {Lo: 0x1e000, Hi: 0x1e006, Stride: 1}, + {Lo: 0x1e008, Hi: 0x1e018, Stride: 1}, + {Lo: 0x1e01b, Hi: 0x1e021, Stride: 1}, + {Lo: 0x1e023, Hi: 0x1e024, Stride: 1}, + {Lo: 0x1e026, Hi: 0x1e02a, Stride: 1}, + {Lo: 0x1e030, Hi: 0x1e06d, Stride: 1}, + {Lo: 0x1e08f, Hi: 0x1e100, Stride: 113}, + {Lo: 0x1e101, Hi: 0x1e12c, Stride: 1}, + {Lo: 0x1e137, Hi: 0x1e13d, Stride: 1}, + {Lo: 0x1e140, Hi: 0x1e149, Stride: 1}, + {Lo: 0x1e14e, Hi: 0x1e290, Stride: 322}, + {Lo: 0x1e291, Hi: 0x1e2ad, Stride: 1}, + {Lo: 0x1e2c0, Hi: 0x1e2eb, Stride: 1}, + {Lo: 0x1e2f0, Hi: 0x1e2f9, Stride: 1}, + {Lo: 0x1e4d0, Hi: 0x1e4eb, Stride: 1}, + {Lo: 0x1e4f0, Hi: 0x1e4f9, Stride: 1}, + {Lo: 0x1e7e0, Hi: 0x1e7e6, Stride: 1}, + {Lo: 0x1e7e8, Hi: 0x1e7eb, Stride: 1}, + {Lo: 0x1e7ed, Hi: 0x1e7ee, Stride: 1}, + {Lo: 0x1e7f0, Hi: 0x1e7fe, Stride: 1}, + {Lo: 0x1e800, Hi: 0x1e8c4, Stride: 1}, + {Lo: 0x1e8c7, Hi: 0x1e8cf, Stride: 1}, + {Lo: 0x1e900, Hi: 0x1e943, Stride: 1}, + {Lo: 0x1e947, Hi: 0x1e94b, Stride: 4}, + {Lo: 0x1e950, Hi: 0x1e959, Stride: 1}, + {Lo: 0x1ec71, Hi: 0x1ecab, Stride: 1}, + {Lo: 0x1ecad, Hi: 0x1ecaf, Stride: 1}, + {Lo: 0x1ecb1, Hi: 0x1ecb4, Stride: 1}, + {Lo: 0x1ed01, Hi: 0x1ed2d, Stride: 1}, + {Lo: 0x1ed2f, Hi: 0x1ed3d, Stride: 1}, + {Lo: 0x1ee00, Hi: 0x1ee03, Stride: 1}, + {Lo: 0x1ee05, Hi: 0x1ee1f, Stride: 1}, + {Lo: 0x1ee21, Hi: 0x1ee22, Stride: 1}, + {Lo: 0x1ee24, Hi: 0x1ee27, Stride: 3}, + {Lo: 0x1ee29, Hi: 0x1ee32, Stride: 1}, + {Lo: 0x1ee34, Hi: 0x1ee37, Stride: 1}, + {Lo: 0x1ee39, Hi: 0x1ee3b, Stride: 2}, + {Lo: 0x1ee42, Hi: 0x1ee47, Stride: 5}, + {Lo: 0x1ee49, Hi: 0x1ee4d, Stride: 2}, + {Lo: 0x1ee4e, Hi: 0x1ee4f, Stride: 1}, + {Lo: 0x1ee51, Hi: 0x1ee52, Stride: 1}, + {Lo: 0x1ee54, Hi: 0x1ee57, Stride: 3}, + {Lo: 0x1ee59, Hi: 0x1ee61, Stride: 2}, + {Lo: 0x1ee62, Hi: 0x1ee64, Stride: 2}, + {Lo: 0x1ee67, Hi: 0x1ee6a, Stride: 1}, + {Lo: 0x1ee6c, Hi: 0x1ee72, Stride: 1}, + {Lo: 0x1ee74, Hi: 0x1ee77, Stride: 1}, + {Lo: 0x1ee79, Hi: 0x1ee7c, Stride: 1}, + {Lo: 0x1ee7e, Hi: 0x1ee80, Stride: 2}, + {Lo: 0x1ee81, Hi: 0x1ee89, Stride: 1}, + {Lo: 0x1ee8b, Hi: 0x1ee9b, Stride: 1}, + {Lo: 0x1eea1, Hi: 0x1eea3, Stride: 1}, + {Lo: 0x1eea5, Hi: 0x1eea9, Stride: 1}, + {Lo: 0x1eeab, Hi: 0x1eebb, Stride: 1}, + {Lo: 0x1f100, Hi: 0x1f10c, Stride: 1}, + {Lo: 0x1f130, Hi: 0x1f149, Stride: 1}, + {Lo: 0x1f150, Hi: 0x1f169, Stride: 1}, + {Lo: 0x1f170, Hi: 0x1f189, Stride: 1}, + {Lo: 0x1fbf0, Hi: 0x1fbf9, Stride: 1}, + {Lo: 0x20000, Hi: 0x2a6df, Stride: 1}, + {Lo: 0x2a700, Hi: 0x2b739, Stride: 1}, + {Lo: 0x2b740, Hi: 0x2b81d, Stride: 1}, + {Lo: 0x2b820, Hi: 0x2cea1, Stride: 1}, + {Lo: 0x2ceb0, Hi: 0x2ebe0, Stride: 1}, + {Lo: 0x2ebf0, Hi: 0x2ee5d, Stride: 1}, + {Lo: 0x2f800, Hi: 0x2fa1d, Stride: 1}, + {Lo: 0x30000, Hi: 0x3134a, Stride: 1}, + {Lo: 0x31350, Hi: 0x323af, Stride: 1}, + }, + LatinOffset: 9, +}