feature/plural: move and regenerate remaining code

Move parts of code and do some renaming.

Manually change go generate directives and added new package to
x/text/gen.go

Regenerate tables for original and destination package.

Change-Id: I728dde1c0f7dcc289372fb815ecc4ed85d182cc2
Reviewed-on: https://go-review.googlesource.com/39132
Run-TryBot: Marcel van Lohuizen <mpvl@golang.org>
Reviewed-by: Nigel Tao <nigeltao@golang.org>
diff --git a/feature/plural/common.go b/feature/plural/common.go
new file mode 100644
index 0000000..00432d2
--- /dev/null
+++ b/feature/plural/common.go
@@ -0,0 +1,53 @@
+// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
+
+package plural
+
+import "golang.org/x/text/internal/format/plural"
+
+var countMap = map[string]plural.Form{
+	"other": plural.Other,
+	"zero":  plural.Zero,
+	"one":   plural.One,
+	"two":   plural.Two,
+	"few":   plural.Few,
+	"many":  plural.Many,
+}
+
+type pluralCheck struct {
+	// category:
+	// 3..7: opID
+	// 0..2: category
+	cat   byte
+	setID byte
+}
+
+// opID identifies the type of operand in the plural rule, being i, n or f.
+// (v, w, and t are treated as filters in our implementation.)
+type opID byte
+
+const (
+	opMod           opID = 0x1    // is '%' used?
+	opNotEqual      opID = 0x2    // using "!=" to compare
+	opI             opID = 0 << 2 // integers after taking the absolute value
+	opN             opID = 1 << 2 // full number (must be integer)
+	opF             opID = 2 << 2 // fraction
+	opV             opID = 3 << 2 // number of visible digits
+	opW             opID = 4 << 2 // number of visible digits without trailing zeros
+	opBretonM       opID = 5 << 2 // hard-wired rule for Breton
+	opItalian800    opID = 6 << 2 // hard-wired rule for Italian
+	opAzerbaijan00s opID = 7 << 2 // hard-wired rule for Azerbaijan
+)
+const (
+	// Use this plural form to indicate the next rule needs to match as well.
+	// The last condition in the list will have the correct plural form.
+	andNext  = 0x7
+	formMask = 0x7
+
+	opShift = 3
+
+	// numN indicates the maximum integer, or maximum mod value, for which we
+	// have inclusion masks.
+	numN = 100
+	// The common denominator of the modulo that is taken.
+	maxMod = 100
+)
diff --git a/internal/number/data_test.go b/feature/plural/data_test.go
similarity index 98%
rename from internal/number/data_test.go
rename to feature/plural/data_test.go
index 350be59..7bbf8c5 100644
--- a/internal/number/data_test.go
+++ b/feature/plural/data_test.go
@@ -1,6 +1,6 @@
-// This file was generated by go generate; DO NOT EDIT
+// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
 
-package number
+package plural
 
 import "golang.org/x/text/internal/format/plural"
 
@@ -191,4 +191,4 @@
 	114: {locales: "cy", form: 0x0, integer: []string{"4", "5", "7~20", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"0.1~0.9", "1.1~1.7", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
 } // Size: 8304 bytes
 
-// Total table size 12576 bytes (12KiB); checksum: 35F73741
+// Total table size 12576 bytes (12KiB); checksum: 166DAB75
diff --git a/feature/plural/gen.go b/feature/plural/gen.go
index 05a6722..e93967b 100644
--- a/feature/plural/gen.go
+++ b/feature/plural/gen.go
@@ -57,6 +57,7 @@
 import (
 	"bufio"
 	"bytes"
+	"flag"
 	"fmt"
 	"log"
 	"strconv"
@@ -69,6 +70,50 @@
 	"golang.org/x/text/unicode/cldr"
 )
 
+var (
+	test = flag.Bool("test", false,
+		"test existing tables; can be used to compare web data with package data.")
+	outputFile     = flag.String("output", "tables.go", "output file")
+	outputTestFile = flag.String("testoutput", "data_test.go", "output file")
+
+	draft = flag.String("draft",
+		"contributed",
+		`Minimal draft requirements (approved, contributed, provisional, unconfirmed).`)
+)
+
+func main() {
+	gen.Init()
+
+	const pkg = "plural"
+
+	gen.Repackage("gen_common.go", "common.go", pkg)
+	// Read the CLDR zip file.
+	r := gen.OpenCLDRCoreZip()
+	defer r.Close()
+
+	d := &cldr.Decoder{}
+	d.SetDirFilter("supplemental", "main")
+	d.SetSectionFilter("numbers", "plurals")
+	data, err := d.DecodeZip(r)
+	if err != nil {
+		log.Fatalf("DecodeZip: %v", err)
+	}
+
+	w := gen.NewCodeWriter()
+	defer w.WriteGoFile(*outputFile, pkg)
+
+	gen.WriteCLDRVersion(w)
+
+	genPlurals(w, data)
+
+	w = gen.NewCodeWriter()
+	defer w.WriteGoFile(*outputTestFile, pkg)
+
+	fmt.Fprintln(w, `import "golang.org/x/text/internal/format/plural"`)
+
+	genPluralsTests(w, data)
+}
+
 type pluralTest struct {
 	locales string // space-separated list of locales for this test
 	form    plural.Form
diff --git a/feature/plural/gen_common.go b/feature/plural/gen_common.go
new file mode 100644
index 0000000..c6f2168
--- /dev/null
+++ b/feature/plural/gen_common.go
@@ -0,0 +1,57 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build ignore
+
+package main
+
+import "golang.org/x/text/internal/format/plural"
+
+var countMap = map[string]plural.Form{
+	"other": plural.Other,
+	"zero":  plural.Zero,
+	"one":   plural.One,
+	"two":   plural.Two,
+	"few":   plural.Few,
+	"many":  plural.Many,
+}
+
+type pluralCheck struct {
+	// category:
+	// 3..7: opID
+	// 0..2: category
+	cat   byte
+	setID byte
+}
+
+// opID identifies the type of operand in the plural rule, being i, n or f.
+// (v, w, and t are treated as filters in our implementation.)
+type opID byte
+
+const (
+	opMod           opID = 0x1    // is '%' used?
+	opNotEqual      opID = 0x2    // using "!=" to compare
+	opI             opID = 0 << 2 // integers after taking the absolute value
+	opN             opID = 1 << 2 // full number (must be integer)
+	opF             opID = 2 << 2 // fraction
+	opV             opID = 3 << 2 // number of visible digits
+	opW             opID = 4 << 2 // number of visible digits without trailing zeros
+	opBretonM       opID = 5 << 2 // hard-wired rule for Breton
+	opItalian800    opID = 6 << 2 // hard-wired rule for Italian
+	opAzerbaijan00s opID = 7 << 2 // hard-wired rule for Azerbaijan
+)
+const (
+	// Use this plural form to indicate the next rule needs to match as well.
+	// The last condition in the list will have the correct plural form.
+	andNext  = 0x7
+	formMask = 0x7
+
+	opShift = 3
+
+	// numN indicates the maximum integer, or maximum mod value, for which we
+	// have inclusion masks.
+	numN = 100
+	// The common denominator of the modulo that is taken.
+	maxMod = 100
+)
diff --git a/feature/plural/plural.go b/feature/plural/plural.go
index 5714e11..48a50c4 100644
--- a/feature/plural/plural.go
+++ b/feature/plural/plural.go
@@ -2,11 +2,21 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-package number
+//go:generate go run gen.go gen_common.go
 
-import "golang.org/x/text/internal/format/plural"
+// Package plural provides utilities for handling linguistic plurals in text.
+package plural
 
-type pluralRules struct {
+import (
+	"golang.org/x/text/internal/format/plural"
+	"golang.org/x/text/language"
+)
+
+// Rules defines the plural rules for all languages for a certain plural type.
+//
+//
+// This package is UNDER CONSTRUCTION and its API may change.
+type Rules struct {
 	rules          []pluralCheck
 	index          []byte
 	langToIndex    []byte
@@ -14,13 +24,21 @@
 }
 
 var (
-	ordinalData = pluralRules{
+	// Cardinal defines the plural rules for numbers indicating quantities.
+	Cardinal *Rules = cardinal
+
+	// Ordinal defines the plural rules for numbers indicating position
+	// (first, second, etc.).
+	Ordinal *Rules = ordinal
+
+	ordinal = &Rules{
 		ordinalRules,
 		ordinalIndex,
 		ordinalLangToIndex,
 		ordinalInclusionMasks[:],
 	}
-	cardinalData = pluralRules{
+
+	cardinal = &Rules{
 		cardinalRules,
 		cardinalIndex,
 		cardinalLangToIndex,
@@ -28,9 +46,86 @@
 	}
 )
 
-// See gen_plural.go for an explanation of the algorithm.
+// getIntApprox converts the digits in slice digits[start:end] to an integer
+// according to the following rules:
+//	- Let i be asInt(digits[start:end]), where out-of-range digits are assumed
+//	  to be zero.
+//	- Result n is big if i / 10^nMod > 1.
+//	- Otherwise the result is i % 10^nMod.
+//
+// For example, if digits is {1, 2, 3} and start:end is 0:5, then the result
+// for various values of nMod is:
+//	- when nMod == 2, n == big
+//	- when nMod == 3, n == big
+//	- when nMod == 4, n == big
+//	- when nMod == 5, n == 12300
+//	- when nMod == 6, n == 12300
+//	- when nMod == 7, n == 12300
+func getIntApprox(digits []byte, start, end, nMod, big int) (n int) {
+	// Leading 0 digits just result in 0.
+	p := start
+	if p < 0 {
+		p = 0
+	}
+	// Range only over the part for which we have digits.
+	mid := end
+	if mid >= len(digits) {
+		mid = len(digits)
+	}
+	// Check digits more significant that nMod.
+	if q := end - nMod; q > 0 {
+		if q > mid {
+			q = mid
+		}
+		for ; p < q; p++ {
+			if digits[p] != 0 {
+				return big
+			}
+		}
+	}
+	for ; p < mid; p++ {
+		n = 10*n + int(digits[p])
+	}
+	// Multiply for trailing zeros.
+	for ; p < end; p++ {
+		n *= 10
+	}
+	return n
+}
 
-func matchPlural(p *pluralRules, index int, n, f, v int) plural.Form {
+// MatchDigits computes the plural form for the given language and the given
+// decimal floating point digits. The digits are stored in big-endian order and
+// are of value byte(0) - byte(9). The floating point position is indicated by
+// exp and the number of visible decimals is scale. All leading and trailing
+// zeros may be omitted from digits.
+//
+// The following table contains examples of possible arguments to represent
+// the given numbers.
+//      decimal    digits              exp    scale
+//      123        []byte{1, 2, 3}     3      0
+//      123.4      []byte{1, 2, 3, 4}  3      1
+//      123.40     []byte{1, 2, 3, 4}  3      2
+//      100000     []byte{1}           6......0
+//      100000.00  []byte{1}           6......3
+func (p *Rules) MatchDigits(t language.Tag, digits []byte, exp, scale int) plural.Form {
+	index, _ := language.CompactIndex(t)
+	endN := len(digits) + exp
+
+	// Differentiate up to including mod 1000000 for the integer part.
+	n := getIntApprox(digits, 0, endN, 6, 1000000)
+
+	// Differentiate up to including mod 100 for the fractional part.
+	f := getIntApprox(digits, endN, endN+scale, 2, 100)
+
+	return matchPlural(p, index, n, f, scale)
+}
+
+func (p *Rules) matchComponents(t language.Tag, n, f, scale int) plural.Form {
+	index, _ := language.CompactIndex(t)
+	return matchPlural(p, index, n, f, scale)
+}
+
+func matchPlural(p *Rules, index int, n, f, v int) plural.Form {
 	nMask := p.inclusionMasks[n%maxMod]
 	// Compute the fMask inline in the rules below, as it is relatively rare.
 	// fMask := p.inclusionMasks[f%maxMod]
diff --git a/feature/plural/plural_test.go b/feature/plural/plural_test.go
index 3383d8c..4b4779b 100644
--- a/feature/plural/plural_test.go
+++ b/feature/plural/plural_test.go
@@ -2,9 +2,10 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-package number
+package plural
 
 import (
+	"fmt"
 	"strconv"
 	"strings"
 	"testing"
@@ -12,18 +13,70 @@
 	"golang.org/x/text/language"
 )
 
+func TestGetIntApprox(t *testing.T) {
+	const big = 1234567890
+	testCases := []struct {
+		digits string
+		start  int
+		end    int
+		nMod   int
+		want   int
+	}{
+		{"123", 0, 1, 1, 1},
+		{"123", 0, 2, 1, big},
+		{"123", 0, 2, 2, 12},
+		{"123", 3, 4, 2, 0},
+		{"12345", 3, 4, 2, 4},
+
+		{"123", 0, 5, 2, big},
+		{"123", 0, 5, 3, big},
+		{"123", 0, 5, 4, big},
+		{"123", 0, 5, 5, 12300},
+		{"123", 0, 5, 6, 12300},
+		{"123", 0, 5, 7, 12300},
+
+		// Translation of examples in MatchDigits.
+		// Integer parts
+		{"123", 0, 3, 3, 123},  // 123
+		{"1234", 0, 3, 3, 123}, // 123.4
+		{"1", 0, 6, 8, 100000}, // 100000
+
+		// Fraction parts
+		{"123", 3, 3, 3, 0},   // 123
+		{"1234", 3, 4, 3, 4},  // 123.4
+		{"1234", 3, 5, 3, 40}, // 123.40
+		{"1", 6, 8, 8, 0},     // 100000.00
+	}
+	for _, tc := range testCases {
+		t.Run(fmt.Sprintf("%s:%d:%d/%d", tc.digits, tc.start, tc.end, tc.nMod), func(t *testing.T) {
+			got := getIntApprox(mkDigits(tc.digits), tc.start, tc.end, tc.nMod, big)
+			if got != tc.want {
+				t.Errorf("got %d; want %d", got, tc.want)
+			}
+		})
+	}
+}
+
+func mkDigits(s string) []byte {
+	b := []byte(s)
+	for i := range b {
+		b[i] -= '0'
+	}
+	return b
+}
+
 func TestOrdinal(t *testing.T) {
-	testPlurals(t, &ordinalData, ordinalTests)
+	testPlurals(t, Ordinal, ordinalTests)
 }
 
 func TestCardinal(t *testing.T) {
-	testPlurals(t, &cardinalData, cardinalTests)
+	testPlurals(t, Cardinal, cardinalTests)
 }
 
-func testPlurals(t *testing.T, p *pluralRules, testCases []pluralTest) {
+func testPlurals(t *testing.T, p *Rules, testCases []pluralTest) {
 	for _, tc := range testCases {
 		for _, loc := range strings.Split(tc.locales, " ") {
-			langIndex, _ := language.CompactIndex(language.MustParse(loc))
+			tag := language.MustParse(loc)
 			// Test integers
 			for _, s := range tc.integer {
 				a := strings.Split(s, "~")
@@ -33,9 +86,18 @@
 					to = parseUint(t, a[1])
 				}
 				for n := from; n <= to; n++ {
-					if f := matchPlural(p, langIndex, n, 0, 0); f != tc.form {
-						t.Errorf("%s:int(%d) = %v; want %v", loc, n, f, tc.form)
-					}
+					t.Run(fmt.Sprintf("%s/int(%d)", loc, n), func(t *testing.T) {
+						if f := p.matchComponents(tag, n, 0, 0); f != tc.form {
+							t.Errorf("matchComponents: got %v; want %v", f, tc.form)
+						}
+						digits := []byte(fmt.Sprint(n))
+						for i := range digits {
+							digits[i] -= '0'
+						}
+						if f := p.MatchDigits(tag, digits, 0, 0); f != tc.form {
+							t.Errorf("MatchDigits: got %v; want %v", f, tc.form)
+						}
+					})
 				}
 			}
 			// Test decimals
@@ -54,9 +116,20 @@
 					m *= 10
 				}
 				for n := from; n <= to; n++ {
-					if f := matchPlural(p, langIndex, n/m, n%m, scale); f != tc.form {
-						t.Errorf("%[1]s:dec(%[2]d.%0[4]*[3]d) = %[5]v; want %[6]v", loc, n/m, n%m, scale, f, tc.form)
-					}
+					num := fmt.Sprintf("%[1]d.%0[3]*[2]d", n/m, n%m, scale)
+					name := fmt.Sprintf("%s:dec(%s)", loc, num)
+					t.Run(name, func(t *testing.T) {
+						if f := p.matchComponents(tag, n/m, n%m, scale); f != tc.form {
+							t.Errorf("matchComponents: got %v; want %v", f, tc.form)
+						}
+						digits := []byte(strings.Replace(num, ".", "", 1))
+						for i := range digits {
+							digits[i] -= '0'
+						}
+						if f := p.MatchDigits(tag, digits, -scale, scale); f != tc.form {
+							t.Errorf("MatchDigits: got %v; want %v", f, tc.form)
+						}
+					})
 				}
 			}
 		}
@@ -82,7 +155,7 @@
 }
 
 func BenchmarkPluralSimpleCases(b *testing.B) {
-	p := &cardinalData
+	p := Cardinal
 	en, _ := language.CompactIndex(language.English)
 	zh, _ := language.CompactIndex(language.Chinese)
 	for i := 0; i < b.N; i++ {
@@ -96,7 +169,7 @@
 }
 
 func BenchmarkPluralComplexCases(b *testing.B) {
-	p := &cardinalData
+	p := Cardinal
 	ar, _ := language.CompactIndex(language.Arabic)
 	lv, _ := language.CompactIndex(language.Latvian)
 	for i := 0; i < b.N; i++ {
diff --git a/feature/plural/tables.go b/feature/plural/tables.go
new file mode 100644
index 0000000..c5f4913
--- /dev/null
+++ b/feature/plural/tables.go
@@ -0,0 +1,541 @@
+// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
+
+package plural
+
+// CLDRVersion is the CLDR version from which the tables in this package are derived.
+const CLDRVersion = "30"
+
+var ordinalRules = []pluralCheck{ // 58 elements
+	0:  {cat: 0x2f, setID: 0x4},
+	1:  {cat: 0x3a, setID: 0x5},
+	2:  {cat: 0x22, setID: 0x1},
+	3:  {cat: 0x22, setID: 0x6},
+	4:  {cat: 0x22, setID: 0x7},
+	5:  {cat: 0x2f, setID: 0x8},
+	6:  {cat: 0x3c, setID: 0x9},
+	7:  {cat: 0x2f, setID: 0xa},
+	8:  {cat: 0x3c, setID: 0xb},
+	9:  {cat: 0x2d, setID: 0xc},
+	10: {cat: 0x2d, setID: 0xd},
+	11: {cat: 0x2f, setID: 0xe},
+	12: {cat: 0x35, setID: 0x3},
+	13: {cat: 0xc5, setID: 0xf},
+	14: {cat: 0x2, setID: 0x1},
+	15: {cat: 0x5, setID: 0x3},
+	16: {cat: 0xd, setID: 0x10},
+	17: {cat: 0x22, setID: 0x1},
+	18: {cat: 0x2f, setID: 0x11},
+	19: {cat: 0x3d, setID: 0x12},
+	20: {cat: 0x2f, setID: 0x13},
+	21: {cat: 0x3a, setID: 0x14},
+	22: {cat: 0x2f, setID: 0x15},
+	23: {cat: 0x3b, setID: 0x16},
+	24: {cat: 0x2f, setID: 0xa},
+	25: {cat: 0x3c, setID: 0xb},
+	26: {cat: 0x22, setID: 0x1},
+	27: {cat: 0x23, setID: 0x17},
+	28: {cat: 0x24, setID: 0x18},
+	29: {cat: 0x22, setID: 0x19},
+	30: {cat: 0x23, setID: 0x2},
+	31: {cat: 0x24, setID: 0x18},
+	32: {cat: 0xf, setID: 0x13},
+	33: {cat: 0x1a, setID: 0x14},
+	34: {cat: 0xf, setID: 0x15},
+	35: {cat: 0x1b, setID: 0x16},
+	36: {cat: 0xf, setID: 0x1a},
+	37: {cat: 0x1d, setID: 0x1b},
+	38: {cat: 0xa, setID: 0x1c},
+	39: {cat: 0xa, setID: 0x1d},
+	40: {cat: 0xc, setID: 0x1e},
+	41: {cat: 0xe4, setID: 0x0},
+	42: {cat: 0x5, setID: 0x3},
+	43: {cat: 0xd, setID: 0xc},
+	44: {cat: 0xd, setID: 0x1f},
+	45: {cat: 0x22, setID: 0x1},
+	46: {cat: 0x23, setID: 0x17},
+	47: {cat: 0x24, setID: 0x18},
+	48: {cat: 0x25, setID: 0x20},
+	49: {cat: 0x22, setID: 0x21},
+	50: {cat: 0x23, setID: 0x17},
+	51: {cat: 0x24, setID: 0x18},
+	52: {cat: 0x25, setID: 0x20},
+	53: {cat: 0x21, setID: 0x22},
+	54: {cat: 0x22, setID: 0x1},
+	55: {cat: 0x23, setID: 0x2},
+	56: {cat: 0x24, setID: 0x23},
+	57: {cat: 0x25, setID: 0x24},
+} // Size: 140 bytes
+
+var ordinalIndex = []uint8{ // 20 elements
+	0x00, 0x00, 0x02, 0x03, 0x04, 0x05, 0x07, 0x09,
+	0x0d, 0x0e, 0x11, 0x14, 0x1a, 0x1d, 0x20, 0x26,
+	0x2d, 0x31, 0x35, 0x3a,
+} // Size: 44 bytes
+
+var ordinalLangToIndex = []uint8{ // 752 elements
+	// Entry 0 - 3F
+	0x00, 0x0d, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00,
+	0x0f, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x05,
+	0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	// Entry 40 - 7F
+	0x00, 0x00, 0x11, 0x11, 0x11, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x12, 0x12, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	// Entry 80 - BF
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x0b, 0x0b,
+	0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+	0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+	0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+	0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+	0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+	0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+	0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+	// Entry C0 - FF
+	0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+	0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+	0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+	0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+	0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+	0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	// Entry 100 - 13F
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00,
+	0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+	0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+	0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+	0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+	// Entry 140 - 17F
+	0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+	0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+	0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x02, 0x02,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	// Entry 180 - 1BF
+	0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	// Entry 1C0 - 1FF
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x0e, 0x0e, 0x00, 0x00,
+	0x00, 0x00, 0x0c, 0x0c, 0x02, 0x02, 0x02, 0x02,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	// Entry 200 - 23F
+	0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	// Entry 240 - 27F
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02,
+	0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a,
+	// Entry 280 - 2BF
+	0x0a, 0x0a, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00,
+	// Entry 2C0 - 2FF
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+} // Size: 776 bytes
+
+var ordinalInclusionMasks = []uint64{ // 100 elements
+	// Entry 0 - 1F
+	0x0000000400004009, 0x00000002120800d3, 0x0000000010a10195, 0x0000000842810581,
+	0x0000000841030081, 0x0000001210010041, 0x0000001100011001, 0x0000000614010001,
+	0x0000000614018001, 0x0000000600012001, 0x0000000200014001, 0x0000000010198031,
+	0x0000000010610331, 0x0000000040010f01, 0x0000000040070001, 0x0000000010010001,
+	0x0000000000011001, 0x000000001c010001, 0x000000001c010001, 0x0000000000012001,
+	0x0000000020014001, 0x0000000010080011, 0x0000000010200111, 0x0000000040000501,
+	0x0000000040020001, 0x0000000010000001, 0x0000000000001001, 0x0000000014000001,
+	0x0000000014000001, 0x0000000000002001, 0x0000000000004001, 0x0000000010080011,
+	// Entry 20 - 3F
+	0x0000000010200111, 0x0000000040000501, 0x0000000040020001, 0x0000000010000001,
+	0x0000000000001001, 0x0000000014000001, 0x0000000014000001, 0x0000000000002001,
+	0x0000000080014001, 0x0000000010080011, 0x0000000010200111, 0x0000000040000501,
+	0x0000000040020001, 0x0000000010000001, 0x0000000000001001, 0x0000000014000001,
+	0x0000000014000001, 0x0000000000002001, 0x0000000020004001, 0x0000000010080011,
+	0x0000000010200111, 0x0000000040000501, 0x0000000040020001, 0x0000000010000001,
+	0x0000000000001001, 0x0000000014000001, 0x0000000014000001, 0x0000000000002001,
+	0x0000000080014001, 0x0000000010080011, 0x0000000010200111, 0x0000000040000501,
+	// Entry 40 - 5F
+	0x0000000040020001, 0x0000000010000001, 0x0000000000001001, 0x0000000014000001,
+	0x0000000014000001, 0x0000000000002001, 0x0000000020004001, 0x0000000010080011,
+	0x0000000010200111, 0x0000000040000501, 0x0000000040020001, 0x0000000010000001,
+	0x0000000000001001, 0x0000000014000001, 0x0000000014000001, 0x0000000000002001,
+	0x000000002001c001, 0x0000000010080011, 0x0000000010200111, 0x0000000040000501,
+	0x0000000040020001, 0x0000000010000001, 0x0000000000001001, 0x0000000014000001,
+	0x0000000014000001, 0x0000000000002001, 0x0000000080004001, 0x0000000010080011,
+	0x0000000010200111, 0x0000000040000501, 0x0000000040020001, 0x0000000010000001,
+	// Entry 60 - 7F
+	0x0000000000001001, 0x0000000014000001, 0x0000000014000001, 0x0000000000002001,
+} // Size: 824 bytes
+
+// Slots used for ordinal: 3A of 0xFF rules; 14 of 0xFF indexes; 37 of 64 sets
+
+var cardinalRules = []pluralCheck{ // 169 elements
+	0:   {cat: 0x2, setID: 0x3},
+	1:   {cat: 0x22, setID: 0x1},
+	2:   {cat: 0x2, setID: 0x4},
+	3:   {cat: 0x7, setID: 0x1},
+	4:   {cat: 0x62, setID: 0x3},
+	5:   {cat: 0x22, setID: 0x4},
+	6:   {cat: 0x7, setID: 0x3},
+	7:   {cat: 0x42, setID: 0x1},
+	8:   {cat: 0x22, setID: 0x4},
+	9:   {cat: 0x22, setID: 0x4},
+	10:  {cat: 0x22, setID: 0x5},
+	11:  {cat: 0x27, setID: 0x6},
+	12:  {cat: 0x32, setID: 0x2},
+	13:  {cat: 0x22, setID: 0x1},
+	14:  {cat: 0x27, setID: 0x1},
+	15:  {cat: 0x62, setID: 0x3},
+	16:  {cat: 0x22, setID: 0x1},
+	17:  {cat: 0x7, setID: 0x4},
+	18:  {cat: 0x92, setID: 0x3},
+	19:  {cat: 0xf, setID: 0x7},
+	20:  {cat: 0x1f, setID: 0x8},
+	21:  {cat: 0x82, setID: 0x3},
+	22:  {cat: 0x92, setID: 0x3},
+	23:  {cat: 0xf, setID: 0x7},
+	24:  {cat: 0x62, setID: 0x3},
+	25:  {cat: 0x4a, setID: 0x7},
+	26:  {cat: 0x7, setID: 0x9},
+	27:  {cat: 0x62, setID: 0x3},
+	28:  {cat: 0x1f, setID: 0xa},
+	29:  {cat: 0x62, setID: 0x3},
+	30:  {cat: 0x5f, setID: 0xa},
+	31:  {cat: 0x72, setID: 0x3},
+	32:  {cat: 0x29, setID: 0xb},
+	33:  {cat: 0x29, setID: 0xc},
+	34:  {cat: 0x4f, setID: 0xc},
+	35:  {cat: 0x61, setID: 0x2},
+	36:  {cat: 0x2f, setID: 0x7},
+	37:  {cat: 0x3a, setID: 0x8},
+	38:  {cat: 0x4f, setID: 0x7},
+	39:  {cat: 0x5f, setID: 0x8},
+	40:  {cat: 0x62, setID: 0x2},
+	41:  {cat: 0x4f, setID: 0x7},
+	42:  {cat: 0x72, setID: 0x2},
+	43:  {cat: 0x21, setID: 0x3},
+	44:  {cat: 0x7, setID: 0x4},
+	45:  {cat: 0x32, setID: 0x3},
+	46:  {cat: 0x21, setID: 0x3},
+	47:  {cat: 0x22, setID: 0x1},
+	48:  {cat: 0x22, setID: 0x1},
+	49:  {cat: 0x23, setID: 0x2},
+	50:  {cat: 0x2, setID: 0x3},
+	51:  {cat: 0x22, setID: 0x1},
+	52:  {cat: 0x24, setID: 0xd},
+	53:  {cat: 0x7, setID: 0x1},
+	54:  {cat: 0x62, setID: 0x3},
+	55:  {cat: 0x74, setID: 0x3},
+	56:  {cat: 0x24, setID: 0x3},
+	57:  {cat: 0x2f, setID: 0xe},
+	58:  {cat: 0x34, setID: 0x1},
+	59:  {cat: 0xf, setID: 0x7},
+	60:  {cat: 0x1f, setID: 0x8},
+	61:  {cat: 0x62, setID: 0x3},
+	62:  {cat: 0x4f, setID: 0x7},
+	63:  {cat: 0x5a, setID: 0x8},
+	64:  {cat: 0xf, setID: 0xf},
+	65:  {cat: 0x1f, setID: 0x10},
+	66:  {cat: 0x64, setID: 0x3},
+	67:  {cat: 0x4f, setID: 0xf},
+	68:  {cat: 0x5c, setID: 0x10},
+	69:  {cat: 0x22, setID: 0x11},
+	70:  {cat: 0x23, setID: 0x12},
+	71:  {cat: 0x24, setID: 0x13},
+	72:  {cat: 0xf, setID: 0x1},
+	73:  {cat: 0x62, setID: 0x3},
+	74:  {cat: 0xf, setID: 0x2},
+	75:  {cat: 0x63, setID: 0x3},
+	76:  {cat: 0xf, setID: 0x14},
+	77:  {cat: 0x64, setID: 0x3},
+	78:  {cat: 0x74, setID: 0x3},
+	79:  {cat: 0xf, setID: 0x1},
+	80:  {cat: 0x62, setID: 0x3},
+	81:  {cat: 0x4a, setID: 0x1},
+	82:  {cat: 0xf, setID: 0x2},
+	83:  {cat: 0x63, setID: 0x3},
+	84:  {cat: 0x4b, setID: 0x2},
+	85:  {cat: 0xf, setID: 0x14},
+	86:  {cat: 0x64, setID: 0x3},
+	87:  {cat: 0x4c, setID: 0x14},
+	88:  {cat: 0x7, setID: 0x1},
+	89:  {cat: 0x62, setID: 0x3},
+	90:  {cat: 0x7, setID: 0x2},
+	91:  {cat: 0x63, setID: 0x3},
+	92:  {cat: 0x2f, setID: 0xb},
+	93:  {cat: 0x37, setID: 0x15},
+	94:  {cat: 0x65, setID: 0x3},
+	95:  {cat: 0x7, setID: 0x1},
+	96:  {cat: 0x62, setID: 0x3},
+	97:  {cat: 0x7, setID: 0x16},
+	98:  {cat: 0x64, setID: 0x3},
+	99:  {cat: 0x75, setID: 0x3},
+	100: {cat: 0x7, setID: 0x1},
+	101: {cat: 0x62, setID: 0x3},
+	102: {cat: 0xf, setID: 0xf},
+	103: {cat: 0x1f, setID: 0x10},
+	104: {cat: 0x64, setID: 0x3},
+	105: {cat: 0xf, setID: 0x17},
+	106: {cat: 0x17, setID: 0x1},
+	107: {cat: 0x65, setID: 0x3},
+	108: {cat: 0xf, setID: 0x18},
+	109: {cat: 0x65, setID: 0x3},
+	110: {cat: 0xf, setID: 0x10},
+	111: {cat: 0x65, setID: 0x3},
+	112: {cat: 0x2f, setID: 0x7},
+	113: {cat: 0x3a, setID: 0x8},
+	114: {cat: 0x2f, setID: 0xf},
+	115: {cat: 0x3c, setID: 0x10},
+	116: {cat: 0x2d, setID: 0xb},
+	117: {cat: 0x2d, setID: 0x18},
+	118: {cat: 0x2d, setID: 0x19},
+	119: {cat: 0x2f, setID: 0x7},
+	120: {cat: 0x3a, setID: 0xc},
+	121: {cat: 0x2f, setID: 0x1a},
+	122: {cat: 0x3c, setID: 0xc},
+	123: {cat: 0x55, setID: 0x3},
+	124: {cat: 0x22, setID: 0x1},
+	125: {cat: 0x24, setID: 0x3},
+	126: {cat: 0x2c, setID: 0xd},
+	127: {cat: 0x2d, setID: 0xc},
+	128: {cat: 0xf, setID: 0x7},
+	129: {cat: 0x1f, setID: 0x8},
+	130: {cat: 0x62, setID: 0x3},
+	131: {cat: 0xf, setID: 0xf},
+	132: {cat: 0x1f, setID: 0x10},
+	133: {cat: 0x64, setID: 0x3},
+	134: {cat: 0xf, setID: 0xb},
+	135: {cat: 0x65, setID: 0x3},
+	136: {cat: 0xf, setID: 0x18},
+	137: {cat: 0x65, setID: 0x3},
+	138: {cat: 0xf, setID: 0x19},
+	139: {cat: 0x65, setID: 0x3},
+	140: {cat: 0x2f, setID: 0x7},
+	141: {cat: 0x3a, setID: 0x1b},
+	142: {cat: 0x2f, setID: 0x1c},
+	143: {cat: 0x3b, setID: 0x1d},
+	144: {cat: 0x2f, setID: 0x1e},
+	145: {cat: 0x3c, setID: 0x1f},
+	146: {cat: 0x37, setID: 0x3},
+	147: {cat: 0xa5, setID: 0x0},
+	148: {cat: 0x22, setID: 0x1},
+	149: {cat: 0x23, setID: 0x2},
+	150: {cat: 0x24, setID: 0x20},
+	151: {cat: 0x25, setID: 0x21},
+	152: {cat: 0xf, setID: 0x7},
+	153: {cat: 0x62, setID: 0x3},
+	154: {cat: 0xf, setID: 0x1c},
+	155: {cat: 0x63, setID: 0x3},
+	156: {cat: 0xf, setID: 0x22},
+	157: {cat: 0x64, setID: 0x3},
+	158: {cat: 0x75, setID: 0x3},
+	159: {cat: 0x21, setID: 0x3},
+	160: {cat: 0x22, setID: 0x1},
+	161: {cat: 0x23, setID: 0x2},
+	162: {cat: 0x2c, setID: 0x23},
+	163: {cat: 0x2d, setID: 0x5},
+	164: {cat: 0x21, setID: 0x3},
+	165: {cat: 0x22, setID: 0x1},
+	166: {cat: 0x23, setID: 0x2},
+	167: {cat: 0x24, setID: 0x24},
+	168: {cat: 0x25, setID: 0x25},
+} // Size: 362 bytes
+
+var cardinalIndex = []uint8{ // 37 elements
+	0x00, 0x00, 0x02, 0x03, 0x05, 0x08, 0x09, 0x0b,
+	0x0d, 0x0e, 0x10, 0x13, 0x17, 0x1a, 0x20, 0x2b,
+	0x2e, 0x30, 0x32, 0x35, 0x3b, 0x45, 0x48, 0x4f,
+	0x58, 0x5f, 0x64, 0x70, 0x77, 0x7c, 0x80, 0x8c,
+	0x94, 0x98, 0x9f, 0xa4, 0xa9,
+} // Size: 61 bytes
+
+var cardinalLangToIndex = []uint8{ // 752 elements
+	// Entry 0 - 3F
+	0x00, 0x03, 0x03, 0x08, 0x08, 0x08, 0x00, 0x00,
+	0x05, 0x05, 0x01, 0x01, 0x22, 0x22, 0x22, 0x22,
+	0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
+	0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
+	0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
+	0x22, 0x22, 0x01, 0x01, 0x08, 0x08, 0x03, 0x03,
+	0x08, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x1b,
+	0x1b, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x05,
+	// Entry 40 - 7F
+	0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00,
+	0x1f, 0x1f, 0x08, 0x08, 0x14, 0x00, 0x00, 0x14,
+	0x14, 0x03, 0x03, 0x03, 0x03, 0x03, 0x08, 0x08,
+	0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x19,
+	0x19, 0x00, 0x00, 0x23, 0x23, 0x0a, 0x0a, 0x0a,
+	0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+	0x03, 0x03, 0x00, 0x00, 0x17, 0x17, 0x00, 0x00,
+	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+	// Entry 80 - BF
+	0x08, 0x08, 0x08, 0x08, 0x08, 0x03, 0x03, 0x03,
+	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+	// Entry C0 - FF
+	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x08, 0x08,
+	0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+	0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+	// Entry 100 - 13F
+	0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+	0x08, 0x08, 0x08, 0x08, 0x03, 0x03, 0x08, 0x08,
+	0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02,
+	0x02, 0x02, 0x03, 0x03, 0x0d, 0x0d, 0x08, 0x08,
+	0x08, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+	0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+	0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+	0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+	// Entry 140 - 17F
+	0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+	0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+	0x08, 0x08, 0x03, 0x03, 0x20, 0x20, 0x15, 0x15,
+	0x03, 0x03, 0x08, 0x08, 0x08, 0x08, 0x01, 0x01,
+	0x05, 0x00, 0x00, 0x21, 0x21, 0x08, 0x08, 0x08,
+	0x08, 0x08, 0x08, 0x18, 0x18, 0x01, 0x01, 0x14,
+	0x14, 0x14, 0x17, 0x17, 0x08, 0x08, 0x02, 0x02,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x0b,
+	// Entry 180 - 1BF
+	0x03, 0x03, 0x03, 0x03, 0x11, 0x00, 0x00, 0x00,
+	0x08, 0x08, 0x08, 0x08, 0x00, 0x08, 0x08, 0x02,
+	0x02, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08,
+	0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x01,
+	0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08,
+	0x08, 0x08, 0x00, 0x00, 0x10, 0x10, 0x08, 0x11,
+	0x11, 0x08, 0x08, 0x0f, 0x0f, 0x08, 0x08, 0x08,
+	// Entry 1C0 - 1FF
+	0x08, 0x00, 0x00, 0x05, 0x05, 0x05, 0x05, 0x05,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x1c, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x0e, 0x08,
+	0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x05, 0x05,
+	0x00, 0x00, 0x08, 0x08, 0x0c, 0x0c, 0x08, 0x08,
+	0x08, 0x08, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
+	0x1d, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x08, 0x11, 0x11, 0x08, 0x08, 0x08, 0x08, 0x08,
+	// Entry 200 - 23F
+	0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x03, 0x03,
+	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00,
+	0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x08, 0x05,
+	0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+	0x08, 0x08, 0x08, 0x08, 0x08, 0x05, 0x00, 0x00,
+	0x05, 0x05, 0x08, 0x1a, 0x1a, 0x0e, 0x0e, 0x08,
+	0x08, 0x07, 0x09, 0x07, 0x09, 0x09, 0x09, 0x09,
+	0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x00, 0x00,
+	// Entry 240 - 27F
+	0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x13, 0x13,
+	0x13, 0x08, 0x08, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
+	0x1e, 0x1e, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00,
+	0x08, 0x08, 0x00, 0x00, 0x08, 0x11, 0x11, 0x11,
+	0x11, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x12,
+	0x00, 0x00, 0x12, 0x12, 0x04, 0x04, 0x19, 0x19,
+	0x16, 0x16, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
+	0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+	// Entry 280 - 2BF
+	0x08, 0x08, 0x08, 0x14, 0x14, 0x14, 0x14, 0x14,
+	0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x08, 0x08,
+	0x08, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+	0x03, 0x03, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+	0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x05,
+	0x05, 0x05, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
+	0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x06, 0x06,
+	0x08, 0x08, 0x1e, 0x1e, 0x03, 0x03, 0x03, 0x08,
+	// Entry 2C0 - 2FF
+	0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x08,
+	0x08, 0x08, 0x05, 0x08, 0x08, 0x00, 0x08, 0x08,
+	0x08, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+} // Size: 776 bytes
+
+var cardinalInclusionMasks = []uint64{ // 100 elements
+	// Entry 0 - 1F
+	0x0000000400a00859, 0x0000000000a242d3, 0x000000001464e245, 0x000000194478e201,
+	0x000000094478e401, 0x0000000905286001, 0x0000002905286401, 0x0000000a05286001,
+	0x0000000a05286001, 0x0000000a45286401, 0x0000000a80a86801, 0x000000008a8251a1,
+	0x00000000b605d021, 0x00000000c609d021, 0x00000000c609d421, 0x0000000085085021,
+	0x0000000085085421, 0x0000000085085021, 0x0000000085085021, 0x00000000c5085421,
+	0x0000000400800821, 0x00000000008000a1, 0x0000000014008021, 0x0000000044008021,
+	0x0000000044008421, 0x0000000005000021, 0x0000000005000421, 0x0000000005000021,
+	0x0000000005000021, 0x0000000045000421, 0x0000000000800821, 0x00000000008000a1,
+	// Entry 20 - 3F
+	0x0000000014008021, 0x0000000044008021, 0x0000000044008421, 0x0000000005000021,
+	0x0000000005000421, 0x0000000005000021, 0x0000000005000021, 0x0000000045000421,
+	0x0000000400800821, 0x00000000008000a1, 0x0000000014008021, 0x0000000044008021,
+	0x0000000044008421, 0x0000000005000021, 0x0000000005000421, 0x0000000005000021,
+	0x0000000005000021, 0x0000000045000421, 0x0000000000800821, 0x00000000008000a1,
+	0x0000000014008021, 0x0000000044008021, 0x0000000044008421, 0x0000000005000021,
+	0x0000000005000421, 0x0000000005000021, 0x0000000005000021, 0x0000000045000421,
+	0x0000000400800821, 0x00000000008000a1, 0x0000000014008021, 0x0000000044008021,
+	// Entry 40 - 5F
+	0x0000000044008421, 0x0000000005000021, 0x0000000005000421, 0x0000000005000021,
+	0x0000000005000021, 0x0000000045000421, 0x0000000080800821, 0x00000000888000a1,
+	0x00000000b4008021, 0x00000000c4008021, 0x00000000c4008421, 0x0000000085000021,
+	0x0000000085000421, 0x0000000085000021, 0x0000000085000021, 0x00000000c5000421,
+	0x0000000400800821, 0x00000000008000a1, 0x0000000014008021, 0x0000000044008021,
+	0x0000000044008421, 0x0000000005000021, 0x0000000005000421, 0x0000000005000021,
+	0x0000000005000021, 0x0000000045000421, 0x0000000080800821, 0x00000000888000a1,
+	0x00000000b4008021, 0x00000000c4008021, 0x00000000c4008421, 0x0000000085000021,
+	// Entry 60 - 7F
+	0x0000000085000421, 0x0000000085000021, 0x0000000085000021, 0x00000000c5000421,
+} // Size: 824 bytes
+
+// Slots used for cardinal: A9 of 0xFF rules; 25 of 0xFF indexes; 38 of 64 sets
+
+// Total table size 3807 bytes (3KiB); checksum: A9B90899
diff --git a/gen.go b/gen.go
index a694fdd..79af97e 100644
--- a/gen.go
+++ b/gen.go
@@ -110,6 +110,7 @@
 		_          = generate("./secure/precis", unicode, norm, rangetable, cases, width, bidi)
 		_          = generate("./currency", unicode, cldr, language, internal)
 		_          = generate("./internal/number", unicode, cldr, language, internal)
+		_          = generate("./feature/plural", unicode, cldr, language, internal)
 		_          = generate("./internal/export/idna", unicode, bidi, norm)
 		_          = generate("./language/display", unicode, cldr, language, internal)
 		_          = generate("./collate", unicode, norm, cldr, language, rangetable)
diff --git a/internal/number/common.go b/internal/number/common.go
index a29abe4..e428a72 100644
--- a/internal/number/common.go
+++ b/internal/number/common.go
@@ -1,12 +1,8 @@
-// This file was generated by go generate; DO NOT EDIT
+// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
 
 package number
 
-import (
-	"unicode/utf8"
-
-	"golang.org/x/text/internal/format/plural"
-)
+import "unicode/utf8"
 
 // A system identifies a CLDR numbering system.
 type system byte
@@ -42,51 +38,3 @@
 	system     system
 	symIndex   byte
 }
-
-var countMap = map[string]plural.Form{
-	"other": plural.Other,
-	"zero":  plural.Zero,
-	"one":   plural.One,
-	"two":   plural.Two,
-	"few":   plural.Few,
-	"many":  plural.Many,
-}
-
-type pluralCheck struct {
-	// category:
-	// 3..7: opID
-	// 0..2: category
-	cat   byte
-	setID byte
-}
-
-// opID identifies the type of operand in the plural rule, being i, n or f.
-// (v, w, and t are treated as filters in our implementation.)
-type opID byte
-
-const (
-	opMod           opID = 0x1    // is '%' used?
-	opNotEqual      opID = 0x2    // using "!=" to compare
-	opI             opID = 0 << 2 // integers after taking the absolute value
-	opN             opID = 1 << 2 // full number (must be integer)
-	opF             opID = 2 << 2 // fraction
-	opV             opID = 3 << 2 // number of visible digits
-	opW             opID = 4 << 2 // number of visible digits without trailing zeros
-	opBretonM       opID = 5 << 2 // hard-wired rule for Breton
-	opItalian800    opID = 6 << 2 // hard-wired rule for Italian
-	opAzerbaijan00s opID = 7 << 2 // hard-wired rule for Azerbaijan
-)
-const (
-	// Use this plural form to indicate the next rule needs to match as well.
-	// The last condition in the list will have the correct plural form.
-	andNext  = 0x7
-	formMask = 0x7
-
-	opShift = 3
-
-	// numN indicates the maximum integer, or maximum mod value, for which we
-	// have inclusion masks.
-	numN = 100
-	// The common denominator of the modulo that is taken.
-	maxMod = 100
-)
diff --git a/internal/number/gen.go b/internal/number/gen.go
index 0d5f592..598c96c 100644
--- a/internal/number/gen.go
+++ b/internal/number/gen.go
@@ -45,7 +45,7 @@
 
 	d := &cldr.Decoder{}
 	d.SetDirFilter("supplemental", "main")
-	d.SetSectionFilter("numbers", "numberingSystem", "plurals")
+	d.SetSectionFilter("numbers", "numberingSystem")
 	data, err := d.DecodeZip(r)
 	if err != nil {
 		log.Fatalf("DecodeZip: %v", err)
@@ -60,15 +60,7 @@
 
 	genNumSystem(w, data)
 	genSymbols(w, data)
-	genPlurals(w, data)
 	genFormats(w, data)
-
-	w = gen.NewCodeWriter()
-	defer w.WriteGoFile(*outputTestFile, pkg)
-
-	fmt.Fprintln(w, `import "golang.org/x/text/internal/format/plural"`)
-
-	genPluralsTests(w, data)
 }
 
 var systemMap = map[string]system{"latn": 0}
diff --git a/internal/number/gen_common.go b/internal/number/gen_common.go
index b0c71c5..c4b791c 100644
--- a/internal/number/gen_common.go
+++ b/internal/number/gen_common.go
@@ -6,11 +6,7 @@
 
 package main
 
-import (
-	"unicode/utf8"
-
-	"golang.org/x/text/internal/format/plural"
-)
+import "unicode/utf8"
 
 // A system identifies a CLDR numbering system.
 type system byte
@@ -46,51 +42,3 @@
 	system     system
 	symIndex   byte
 }
-
-var countMap = map[string]plural.Form{
-	"other": plural.Other,
-	"zero":  plural.Zero,
-	"one":   plural.One,
-	"two":   plural.Two,
-	"few":   plural.Few,
-	"many":  plural.Many,
-}
-
-type pluralCheck struct {
-	// category:
-	// 3..7: opID
-	// 0..2: category
-	cat   byte
-	setID byte
-}
-
-// opID identifies the type of operand in the plural rule, being i, n or f.
-// (v, w, and t are treated as filters in our implementation.)
-type opID byte
-
-const (
-	opMod           opID = 0x1    // is '%' used?
-	opNotEqual      opID = 0x2    // using "!=" to compare
-	opI             opID = 0 << 2 // integers after taking the absolute value
-	opN             opID = 1 << 2 // full number (must be integer)
-	opF             opID = 2 << 2 // fraction
-	opV             opID = 3 << 2 // number of visible digits
-	opW             opID = 4 << 2 // number of visible digits without trailing zeros
-	opBretonM       opID = 5 << 2 // hard-wired rule for Breton
-	opItalian800    opID = 6 << 2 // hard-wired rule for Italian
-	opAzerbaijan00s opID = 7 << 2 // hard-wired rule for Azerbaijan
-)
-const (
-	// Use this plural form to indicate the next rule needs to match as well.
-	// The last condition in the list will have the correct plural form.
-	andNext  = 0x7
-	formMask = 0x7
-
-	opShift = 3
-
-	// numN indicates the maximum integer, or maximum mod value, for which we
-	// have inclusion masks.
-	numN = 100
-	// The common denominator of the modulo that is taken.
-	maxMod = 100
-)
diff --git a/internal/number/number.go b/internal/number/number.go
index d412194..34f4477 100644
--- a/internal/number/number.go
+++ b/internal/number/number.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:generate go run gen.go gen_common.go gen_plural.go
+//go:generate go run gen.go gen_common.go
 
 // Package number contains tools and data for formatting numbers.
 package number
diff --git a/internal/number/tables.go b/internal/number/tables.go
index 845e0b1..5c799b4 100644
--- a/internal/number/tables.go
+++ b/internal/number/tables.go
@@ -1,4 +1,4 @@
-// This file was generated by go generate; DO NOT EDIT
+// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
 
 package number
 
@@ -516,539 +516,6 @@
 	72: {compactTag: 0x2e4, system: 0x4, symIndex: 0x3b},
 } // Size: 316 bytes
 
-var ordinalRules = []pluralCheck{ // 58 elements
-	0:  {cat: 0x2f, setID: 0x4},
-	1:  {cat: 0x3a, setID: 0x5},
-	2:  {cat: 0x22, setID: 0x1},
-	3:  {cat: 0x22, setID: 0x6},
-	4:  {cat: 0x22, setID: 0x7},
-	5:  {cat: 0x2f, setID: 0x8},
-	6:  {cat: 0x3c, setID: 0x9},
-	7:  {cat: 0x2f, setID: 0xa},
-	8:  {cat: 0x3c, setID: 0xb},
-	9:  {cat: 0x2d, setID: 0xc},
-	10: {cat: 0x2d, setID: 0xd},
-	11: {cat: 0x2f, setID: 0xe},
-	12: {cat: 0x35, setID: 0x3},
-	13: {cat: 0xc5, setID: 0xf},
-	14: {cat: 0x2, setID: 0x1},
-	15: {cat: 0x5, setID: 0x3},
-	16: {cat: 0xd, setID: 0x10},
-	17: {cat: 0x22, setID: 0x1},
-	18: {cat: 0x2f, setID: 0x11},
-	19: {cat: 0x3d, setID: 0x12},
-	20: {cat: 0x2f, setID: 0x13},
-	21: {cat: 0x3a, setID: 0x14},
-	22: {cat: 0x2f, setID: 0x15},
-	23: {cat: 0x3b, setID: 0x16},
-	24: {cat: 0x2f, setID: 0xa},
-	25: {cat: 0x3c, setID: 0xb},
-	26: {cat: 0x22, setID: 0x1},
-	27: {cat: 0x23, setID: 0x17},
-	28: {cat: 0x24, setID: 0x18},
-	29: {cat: 0x22, setID: 0x19},
-	30: {cat: 0x23, setID: 0x2},
-	31: {cat: 0x24, setID: 0x18},
-	32: {cat: 0xf, setID: 0x13},
-	33: {cat: 0x1a, setID: 0x14},
-	34: {cat: 0xf, setID: 0x15},
-	35: {cat: 0x1b, setID: 0x16},
-	36: {cat: 0xf, setID: 0x1a},
-	37: {cat: 0x1d, setID: 0x1b},
-	38: {cat: 0xa, setID: 0x1c},
-	39: {cat: 0xa, setID: 0x1d},
-	40: {cat: 0xc, setID: 0x1e},
-	41: {cat: 0xe4, setID: 0x0},
-	42: {cat: 0x5, setID: 0x3},
-	43: {cat: 0xd, setID: 0xc},
-	44: {cat: 0xd, setID: 0x1f},
-	45: {cat: 0x22, setID: 0x1},
-	46: {cat: 0x23, setID: 0x17},
-	47: {cat: 0x24, setID: 0x18},
-	48: {cat: 0x25, setID: 0x20},
-	49: {cat: 0x22, setID: 0x21},
-	50: {cat: 0x23, setID: 0x17},
-	51: {cat: 0x24, setID: 0x18},
-	52: {cat: 0x25, setID: 0x20},
-	53: {cat: 0x21, setID: 0x22},
-	54: {cat: 0x22, setID: 0x1},
-	55: {cat: 0x23, setID: 0x2},
-	56: {cat: 0x24, setID: 0x23},
-	57: {cat: 0x25, setID: 0x24},
-} // Size: 140 bytes
-
-var ordinalIndex = []uint8{ // 20 elements
-	0x00, 0x00, 0x02, 0x03, 0x04, 0x05, 0x07, 0x09,
-	0x0d, 0x0e, 0x11, 0x14, 0x1a, 0x1d, 0x20, 0x26,
-	0x2d, 0x31, 0x35, 0x3a,
-} // Size: 44 bytes
-
-var ordinalLangToIndex = []uint8{ // 752 elements
-	// Entry 0 - 3F
-	0x00, 0x0d, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00,
-	0x0f, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x05,
-	0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	// Entry 40 - 7F
-	0x00, 0x00, 0x11, 0x11, 0x11, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x12, 0x12, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	// Entry 80 - BF
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x0b, 0x0b,
-	0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-	0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-	0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-	0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-	0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-	0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-	0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-	// Entry C0 - FF
-	0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-	0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-	0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-	0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-	0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-	0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	// Entry 100 - 13F
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00,
-	0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-	0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-	0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-	0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-	// Entry 140 - 17F
-	0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-	0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-	0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x02, 0x02,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	// Entry 180 - 1BF
-	0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	// Entry 1C0 - 1FF
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x0e, 0x0e, 0x00, 0x00,
-	0x00, 0x00, 0x0c, 0x0c, 0x02, 0x02, 0x02, 0x02,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	// Entry 200 - 23F
-	0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	// Entry 240 - 27F
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02,
-	0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a,
-	// Entry 280 - 2BF
-	0x0a, 0x0a, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00,
-	// Entry 2C0 - 2FF
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-} // Size: 776 bytes
-
-var ordinalInclusionMasks = []uint64{ // 100 elements
-	// Entry 0 - 1F
-	0x0000000400004009, 0x00000002120800d3, 0x0000000010a10195, 0x0000000842810581,
-	0x0000000841030081, 0x0000001210010041, 0x0000001100011001, 0x0000000614010001,
-	0x0000000614018001, 0x0000000600012001, 0x0000000200014001, 0x0000000010198031,
-	0x0000000010610331, 0x0000000040010f01, 0x0000000040070001, 0x0000000010010001,
-	0x0000000000011001, 0x000000001c010001, 0x000000001c010001, 0x0000000000012001,
-	0x0000000020014001, 0x0000000010080011, 0x0000000010200111, 0x0000000040000501,
-	0x0000000040020001, 0x0000000010000001, 0x0000000000001001, 0x0000000014000001,
-	0x0000000014000001, 0x0000000000002001, 0x0000000000004001, 0x0000000010080011,
-	// Entry 20 - 3F
-	0x0000000010200111, 0x0000000040000501, 0x0000000040020001, 0x0000000010000001,
-	0x0000000000001001, 0x0000000014000001, 0x0000000014000001, 0x0000000000002001,
-	0x0000000080014001, 0x0000000010080011, 0x0000000010200111, 0x0000000040000501,
-	0x0000000040020001, 0x0000000010000001, 0x0000000000001001, 0x0000000014000001,
-	0x0000000014000001, 0x0000000000002001, 0x0000000020004001, 0x0000000010080011,
-	0x0000000010200111, 0x0000000040000501, 0x0000000040020001, 0x0000000010000001,
-	0x0000000000001001, 0x0000000014000001, 0x0000000014000001, 0x0000000000002001,
-	0x0000000080014001, 0x0000000010080011, 0x0000000010200111, 0x0000000040000501,
-	// Entry 40 - 5F
-	0x0000000040020001, 0x0000000010000001, 0x0000000000001001, 0x0000000014000001,
-	0x0000000014000001, 0x0000000000002001, 0x0000000020004001, 0x0000000010080011,
-	0x0000000010200111, 0x0000000040000501, 0x0000000040020001, 0x0000000010000001,
-	0x0000000000001001, 0x0000000014000001, 0x0000000014000001, 0x0000000000002001,
-	0x000000002001c001, 0x0000000010080011, 0x0000000010200111, 0x0000000040000501,
-	0x0000000040020001, 0x0000000010000001, 0x0000000000001001, 0x0000000014000001,
-	0x0000000014000001, 0x0000000000002001, 0x0000000080004001, 0x0000000010080011,
-	0x0000000010200111, 0x0000000040000501, 0x0000000040020001, 0x0000000010000001,
-	// Entry 60 - 7F
-	0x0000000000001001, 0x0000000014000001, 0x0000000014000001, 0x0000000000002001,
-} // Size: 824 bytes
-
-// Slots used for ordinal: 3A of 0xFF rules; 14 of 0xFF indexes; 37 of 64 sets
-
-var cardinalRules = []pluralCheck{ // 169 elements
-	0:   {cat: 0x2, setID: 0x3},
-	1:   {cat: 0x22, setID: 0x1},
-	2:   {cat: 0x2, setID: 0x4},
-	3:   {cat: 0x7, setID: 0x1},
-	4:   {cat: 0x62, setID: 0x3},
-	5:   {cat: 0x22, setID: 0x4},
-	6:   {cat: 0x7, setID: 0x3},
-	7:   {cat: 0x42, setID: 0x1},
-	8:   {cat: 0x22, setID: 0x4},
-	9:   {cat: 0x22, setID: 0x4},
-	10:  {cat: 0x22, setID: 0x5},
-	11:  {cat: 0x27, setID: 0x6},
-	12:  {cat: 0x32, setID: 0x2},
-	13:  {cat: 0x22, setID: 0x1},
-	14:  {cat: 0x27, setID: 0x1},
-	15:  {cat: 0x62, setID: 0x3},
-	16:  {cat: 0x22, setID: 0x1},
-	17:  {cat: 0x7, setID: 0x4},
-	18:  {cat: 0x92, setID: 0x3},
-	19:  {cat: 0xf, setID: 0x7},
-	20:  {cat: 0x1f, setID: 0x8},
-	21:  {cat: 0x82, setID: 0x3},
-	22:  {cat: 0x92, setID: 0x3},
-	23:  {cat: 0xf, setID: 0x7},
-	24:  {cat: 0x62, setID: 0x3},
-	25:  {cat: 0x4a, setID: 0x7},
-	26:  {cat: 0x7, setID: 0x9},
-	27:  {cat: 0x62, setID: 0x3},
-	28:  {cat: 0x1f, setID: 0xa},
-	29:  {cat: 0x62, setID: 0x3},
-	30:  {cat: 0x5f, setID: 0xa},
-	31:  {cat: 0x72, setID: 0x3},
-	32:  {cat: 0x29, setID: 0xb},
-	33:  {cat: 0x29, setID: 0xc},
-	34:  {cat: 0x4f, setID: 0xc},
-	35:  {cat: 0x61, setID: 0x2},
-	36:  {cat: 0x2f, setID: 0x7},
-	37:  {cat: 0x3a, setID: 0x8},
-	38:  {cat: 0x4f, setID: 0x7},
-	39:  {cat: 0x5f, setID: 0x8},
-	40:  {cat: 0x62, setID: 0x2},
-	41:  {cat: 0x4f, setID: 0x7},
-	42:  {cat: 0x72, setID: 0x2},
-	43:  {cat: 0x21, setID: 0x3},
-	44:  {cat: 0x7, setID: 0x4},
-	45:  {cat: 0x32, setID: 0x3},
-	46:  {cat: 0x21, setID: 0x3},
-	47:  {cat: 0x22, setID: 0x1},
-	48:  {cat: 0x22, setID: 0x1},
-	49:  {cat: 0x23, setID: 0x2},
-	50:  {cat: 0x2, setID: 0x3},
-	51:  {cat: 0x22, setID: 0x1},
-	52:  {cat: 0x24, setID: 0xd},
-	53:  {cat: 0x7, setID: 0x1},
-	54:  {cat: 0x62, setID: 0x3},
-	55:  {cat: 0x74, setID: 0x3},
-	56:  {cat: 0x24, setID: 0x3},
-	57:  {cat: 0x2f, setID: 0xe},
-	58:  {cat: 0x34, setID: 0x1},
-	59:  {cat: 0xf, setID: 0x7},
-	60:  {cat: 0x1f, setID: 0x8},
-	61:  {cat: 0x62, setID: 0x3},
-	62:  {cat: 0x4f, setID: 0x7},
-	63:  {cat: 0x5a, setID: 0x8},
-	64:  {cat: 0xf, setID: 0xf},
-	65:  {cat: 0x1f, setID: 0x10},
-	66:  {cat: 0x64, setID: 0x3},
-	67:  {cat: 0x4f, setID: 0xf},
-	68:  {cat: 0x5c, setID: 0x10},
-	69:  {cat: 0x22, setID: 0x11},
-	70:  {cat: 0x23, setID: 0x12},
-	71:  {cat: 0x24, setID: 0x13},
-	72:  {cat: 0xf, setID: 0x1},
-	73:  {cat: 0x62, setID: 0x3},
-	74:  {cat: 0xf, setID: 0x2},
-	75:  {cat: 0x63, setID: 0x3},
-	76:  {cat: 0xf, setID: 0x14},
-	77:  {cat: 0x64, setID: 0x3},
-	78:  {cat: 0x74, setID: 0x3},
-	79:  {cat: 0xf, setID: 0x1},
-	80:  {cat: 0x62, setID: 0x3},
-	81:  {cat: 0x4a, setID: 0x1},
-	82:  {cat: 0xf, setID: 0x2},
-	83:  {cat: 0x63, setID: 0x3},
-	84:  {cat: 0x4b, setID: 0x2},
-	85:  {cat: 0xf, setID: 0x14},
-	86:  {cat: 0x64, setID: 0x3},
-	87:  {cat: 0x4c, setID: 0x14},
-	88:  {cat: 0x7, setID: 0x1},
-	89:  {cat: 0x62, setID: 0x3},
-	90:  {cat: 0x7, setID: 0x2},
-	91:  {cat: 0x63, setID: 0x3},
-	92:  {cat: 0x2f, setID: 0xb},
-	93:  {cat: 0x37, setID: 0x15},
-	94:  {cat: 0x65, setID: 0x3},
-	95:  {cat: 0x7, setID: 0x1},
-	96:  {cat: 0x62, setID: 0x3},
-	97:  {cat: 0x7, setID: 0x16},
-	98:  {cat: 0x64, setID: 0x3},
-	99:  {cat: 0x75, setID: 0x3},
-	100: {cat: 0x7, setID: 0x1},
-	101: {cat: 0x62, setID: 0x3},
-	102: {cat: 0xf, setID: 0xf},
-	103: {cat: 0x1f, setID: 0x10},
-	104: {cat: 0x64, setID: 0x3},
-	105: {cat: 0xf, setID: 0x17},
-	106: {cat: 0x17, setID: 0x1},
-	107: {cat: 0x65, setID: 0x3},
-	108: {cat: 0xf, setID: 0x18},
-	109: {cat: 0x65, setID: 0x3},
-	110: {cat: 0xf, setID: 0x10},
-	111: {cat: 0x65, setID: 0x3},
-	112: {cat: 0x2f, setID: 0x7},
-	113: {cat: 0x3a, setID: 0x8},
-	114: {cat: 0x2f, setID: 0xf},
-	115: {cat: 0x3c, setID: 0x10},
-	116: {cat: 0x2d, setID: 0xb},
-	117: {cat: 0x2d, setID: 0x18},
-	118: {cat: 0x2d, setID: 0x19},
-	119: {cat: 0x2f, setID: 0x7},
-	120: {cat: 0x3a, setID: 0xc},
-	121: {cat: 0x2f, setID: 0x1a},
-	122: {cat: 0x3c, setID: 0xc},
-	123: {cat: 0x55, setID: 0x3},
-	124: {cat: 0x22, setID: 0x1},
-	125: {cat: 0x24, setID: 0x3},
-	126: {cat: 0x2c, setID: 0xd},
-	127: {cat: 0x2d, setID: 0xc},
-	128: {cat: 0xf, setID: 0x7},
-	129: {cat: 0x1f, setID: 0x8},
-	130: {cat: 0x62, setID: 0x3},
-	131: {cat: 0xf, setID: 0xf},
-	132: {cat: 0x1f, setID: 0x10},
-	133: {cat: 0x64, setID: 0x3},
-	134: {cat: 0xf, setID: 0xb},
-	135: {cat: 0x65, setID: 0x3},
-	136: {cat: 0xf, setID: 0x18},
-	137: {cat: 0x65, setID: 0x3},
-	138: {cat: 0xf, setID: 0x19},
-	139: {cat: 0x65, setID: 0x3},
-	140: {cat: 0x2f, setID: 0x7},
-	141: {cat: 0x3a, setID: 0x1b},
-	142: {cat: 0x2f, setID: 0x1c},
-	143: {cat: 0x3b, setID: 0x1d},
-	144: {cat: 0x2f, setID: 0x1e},
-	145: {cat: 0x3c, setID: 0x1f},
-	146: {cat: 0x37, setID: 0x3},
-	147: {cat: 0xa5, setID: 0x0},
-	148: {cat: 0x22, setID: 0x1},
-	149: {cat: 0x23, setID: 0x2},
-	150: {cat: 0x24, setID: 0x20},
-	151: {cat: 0x25, setID: 0x21},
-	152: {cat: 0xf, setID: 0x7},
-	153: {cat: 0x62, setID: 0x3},
-	154: {cat: 0xf, setID: 0x1c},
-	155: {cat: 0x63, setID: 0x3},
-	156: {cat: 0xf, setID: 0x22},
-	157: {cat: 0x64, setID: 0x3},
-	158: {cat: 0x75, setID: 0x3},
-	159: {cat: 0x21, setID: 0x3},
-	160: {cat: 0x22, setID: 0x1},
-	161: {cat: 0x23, setID: 0x2},
-	162: {cat: 0x2c, setID: 0x23},
-	163: {cat: 0x2d, setID: 0x5},
-	164: {cat: 0x21, setID: 0x3},
-	165: {cat: 0x22, setID: 0x1},
-	166: {cat: 0x23, setID: 0x2},
-	167: {cat: 0x24, setID: 0x24},
-	168: {cat: 0x25, setID: 0x25},
-} // Size: 362 bytes
-
-var cardinalIndex = []uint8{ // 37 elements
-	0x00, 0x00, 0x02, 0x03, 0x05, 0x08, 0x09, 0x0b,
-	0x0d, 0x0e, 0x10, 0x13, 0x17, 0x1a, 0x20, 0x2b,
-	0x2e, 0x30, 0x32, 0x35, 0x3b, 0x45, 0x48, 0x4f,
-	0x58, 0x5f, 0x64, 0x70, 0x77, 0x7c, 0x80, 0x8c,
-	0x94, 0x98, 0x9f, 0xa4, 0xa9,
-} // Size: 61 bytes
-
-var cardinalLangToIndex = []uint8{ // 752 elements
-	// Entry 0 - 3F
-	0x00, 0x03, 0x03, 0x08, 0x08, 0x08, 0x00, 0x00,
-	0x05, 0x05, 0x01, 0x01, 0x22, 0x22, 0x22, 0x22,
-	0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
-	0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
-	0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
-	0x22, 0x22, 0x01, 0x01, 0x08, 0x08, 0x03, 0x03,
-	0x08, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x1b,
-	0x1b, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x05,
-	// Entry 40 - 7F
-	0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00,
-	0x1f, 0x1f, 0x08, 0x08, 0x14, 0x00, 0x00, 0x14,
-	0x14, 0x03, 0x03, 0x03, 0x03, 0x03, 0x08, 0x08,
-	0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x19,
-	0x19, 0x00, 0x00, 0x23, 0x23, 0x0a, 0x0a, 0x0a,
-	0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-	0x03, 0x03, 0x00, 0x00, 0x17, 0x17, 0x00, 0x00,
-	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
-	// Entry 80 - BF
-	0x08, 0x08, 0x08, 0x08, 0x08, 0x03, 0x03, 0x03,
-	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-	// Entry C0 - FF
-	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x08, 0x08,
-	0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-	0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-	// Entry 100 - 13F
-	0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-	0x08, 0x08, 0x08, 0x08, 0x03, 0x03, 0x08, 0x08,
-	0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02,
-	0x02, 0x02, 0x03, 0x03, 0x0d, 0x0d, 0x08, 0x08,
-	0x08, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-	0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-	0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-	0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-	// Entry 140 - 17F
-	0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-	0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-	0x08, 0x08, 0x03, 0x03, 0x20, 0x20, 0x15, 0x15,
-	0x03, 0x03, 0x08, 0x08, 0x08, 0x08, 0x01, 0x01,
-	0x05, 0x00, 0x00, 0x21, 0x21, 0x08, 0x08, 0x08,
-	0x08, 0x08, 0x08, 0x18, 0x18, 0x01, 0x01, 0x14,
-	0x14, 0x14, 0x17, 0x17, 0x08, 0x08, 0x02, 0x02,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x0b,
-	// Entry 180 - 1BF
-	0x03, 0x03, 0x03, 0x03, 0x11, 0x00, 0x00, 0x00,
-	0x08, 0x08, 0x08, 0x08, 0x00, 0x08, 0x08, 0x02,
-	0x02, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08,
-	0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x01,
-	0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08,
-	0x08, 0x08, 0x00, 0x00, 0x10, 0x10, 0x08, 0x11,
-	0x11, 0x08, 0x08, 0x0f, 0x0f, 0x08, 0x08, 0x08,
-	// Entry 1C0 - 1FF
-	0x08, 0x00, 0x00, 0x05, 0x05, 0x05, 0x05, 0x05,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x1c, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x0e, 0x08,
-	0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x05, 0x05,
-	0x00, 0x00, 0x08, 0x08, 0x0c, 0x0c, 0x08, 0x08,
-	0x08, 0x08, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
-	0x1d, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x08, 0x11, 0x11, 0x08, 0x08, 0x08, 0x08, 0x08,
-	// Entry 200 - 23F
-	0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x03, 0x03,
-	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00,
-	0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x08, 0x05,
-	0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-	0x08, 0x08, 0x08, 0x08, 0x08, 0x05, 0x00, 0x00,
-	0x05, 0x05, 0x08, 0x1a, 0x1a, 0x0e, 0x0e, 0x08,
-	0x08, 0x07, 0x09, 0x07, 0x09, 0x09, 0x09, 0x09,
-	0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x00, 0x00,
-	// Entry 240 - 27F
-	0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x13, 0x13,
-	0x13, 0x08, 0x08, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
-	0x1e, 0x1e, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00,
-	0x08, 0x08, 0x00, 0x00, 0x08, 0x11, 0x11, 0x11,
-	0x11, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x12,
-	0x00, 0x00, 0x12, 0x12, 0x04, 0x04, 0x19, 0x19,
-	0x16, 0x16, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
-	0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-	// Entry 280 - 2BF
-	0x08, 0x08, 0x08, 0x14, 0x14, 0x14, 0x14, 0x14,
-	0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x08, 0x08,
-	0x08, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-	0x03, 0x03, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-	0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x05,
-	0x05, 0x05, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
-	0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x06, 0x06,
-	0x08, 0x08, 0x1e, 0x1e, 0x03, 0x03, 0x03, 0x08,
-	// Entry 2C0 - 2FF
-	0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x08,
-	0x08, 0x08, 0x05, 0x08, 0x08, 0x00, 0x08, 0x08,
-	0x08, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
-} // Size: 776 bytes
-
-var cardinalInclusionMasks = []uint64{ // 100 elements
-	// Entry 0 - 1F
-	0x0000000400a00859, 0x0000000000a242d3, 0x000000001464e245, 0x000000194478e201,
-	0x000000094478e401, 0x0000000905286001, 0x0000002905286401, 0x0000000a05286001,
-	0x0000000a05286001, 0x0000000a45286401, 0x0000000a80a86801, 0x000000008a8251a1,
-	0x00000000b605d021, 0x00000000c609d021, 0x00000000c609d421, 0x0000000085085021,
-	0x0000000085085421, 0x0000000085085021, 0x0000000085085021, 0x00000000c5085421,
-	0x0000000400800821, 0x00000000008000a1, 0x0000000014008021, 0x0000000044008021,
-	0x0000000044008421, 0x0000000005000021, 0x0000000005000421, 0x0000000005000021,
-	0x0000000005000021, 0x0000000045000421, 0x0000000000800821, 0x00000000008000a1,
-	// Entry 20 - 3F
-	0x0000000014008021, 0x0000000044008021, 0x0000000044008421, 0x0000000005000021,
-	0x0000000005000421, 0x0000000005000021, 0x0000000005000021, 0x0000000045000421,
-	0x0000000400800821, 0x00000000008000a1, 0x0000000014008021, 0x0000000044008021,
-	0x0000000044008421, 0x0000000005000021, 0x0000000005000421, 0x0000000005000021,
-	0x0000000005000021, 0x0000000045000421, 0x0000000000800821, 0x00000000008000a1,
-	0x0000000014008021, 0x0000000044008021, 0x0000000044008421, 0x0000000005000021,
-	0x0000000005000421, 0x0000000005000021, 0x0000000005000021, 0x0000000045000421,
-	0x0000000400800821, 0x00000000008000a1, 0x0000000014008021, 0x0000000044008021,
-	// Entry 40 - 5F
-	0x0000000044008421, 0x0000000005000021, 0x0000000005000421, 0x0000000005000021,
-	0x0000000005000021, 0x0000000045000421, 0x0000000080800821, 0x00000000888000a1,
-	0x00000000b4008021, 0x00000000c4008021, 0x00000000c4008421, 0x0000000085000021,
-	0x0000000085000421, 0x0000000085000021, 0x0000000085000021, 0x00000000c5000421,
-	0x0000000400800821, 0x00000000008000a1, 0x0000000014008021, 0x0000000044008021,
-	0x0000000044008421, 0x0000000005000021, 0x0000000005000421, 0x0000000005000021,
-	0x0000000005000021, 0x0000000045000421, 0x0000000080800821, 0x00000000888000a1,
-	0x00000000b4008021, 0x00000000c4008021, 0x00000000c4008421, 0x0000000085000021,
-	// Entry 60 - 7F
-	0x0000000085000421, 0x0000000085000021, 0x0000000085000021, 0x00000000c5000421,
-} // Size: 824 bytes
-
-// Slots used for cardinal: A9 of 0xFF rules; 25 of 0xFF indexes; 38 of 64 sets
-
 var tagToDecimal = []uint8{ // 752 elements
 	// Entry 0 - 3F
 	0x01, 0x01, 0x08, 0x01, 0x01, 0x01, 0x01, 0x01,
@@ -1649,4 +1116,4 @@
 		MaxSignificantDigits: 0x0,
 		MinExponentDigits:    0x0}}
 
-// Total table size 10908 bytes (10KiB); checksum: B1AF61E6
+// Total table size 7101 bytes (6KiB); checksum: A4A81DF0