Switch to using the dep tool and update all the dependencies

This commit is contained in:
Nick Craig-Wood
2017-05-11 15:39:54 +01:00
parent 5135ff73cb
commit 98c2d2c41b
5321 changed files with 4483197 additions and 5918 deletions
+70
View File
@@ -0,0 +1,70 @@
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
package plural
// Form defines a plural form.
//
// Not all languages support all forms. Also, the meaning of each form varies
// per language. It is important to note that the name of a form does not
// necessarily correspond one-to-one with the set of numbers. For instance,
// for Croation, One matches not only 1, but also 11, 21, etc.
//
// Each language must at least support the form "other".
type Form byte
const (
Other Form = iota
Zero
One
Two
Few
Many
)
var countMap = map[string]Form{
"other": Other,
"zero": Zero,
"one": One,
"two": Two,
"few": Few,
"many": 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
)
+192
View File
@@ -0,0 +1,192 @@
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
package plural
type pluralTest struct {
locales string
form int
integer []string
decimal []string
}
var ordinalTests = []pluralTest{ // 59 elements
0: {locales: "af am ar bg bs ce cs da de dsb el es et eu fa fi fy gl he hr hsb id in is iw ja km kn ko ky lt lv ml mn my nb nl pa pl prg pt root ru sh si sk sl sr sw ta te th tr ur uz yue zh zu", form: 0, integer: []string{"0~15", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
1: {locales: "sv", form: 2, integer: []string{"1", "2", "21", "22", "31", "32", "41", "42", "51", "52", "61", "62", "71", "72", "81", "82", "101", "1001"}, decimal: []string(nil)},
2: {locales: "sv", form: 0, integer: []string{"0", "3~17", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
3: {locales: "fil fr ga hy lo mo ms ro tl vi", form: 2, integer: []string{"1"}, decimal: []string(nil)},
4: {locales: "fil fr ga hy lo mo ms ro tl vi", form: 0, integer: []string{"0", "2~16", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
5: {locales: "hu", form: 2, integer: []string{"1", "5"}, decimal: []string(nil)},
6: {locales: "hu", form: 0, integer: []string{"0", "2~4", "6~17", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
7: {locales: "ne", form: 2, integer: []string{"1~4"}, decimal: []string(nil)},
8: {locales: "ne", form: 0, integer: []string{"0", "5~19", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
9: {locales: "be", form: 4, integer: []string{"2", "3", "22", "23", "32", "33", "42", "43", "52", "53", "62", "63", "72", "73", "82", "83", "102", "1002"}, decimal: []string(nil)},
10: {locales: "be", form: 0, integer: []string{"0", "1", "4~17", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
11: {locales: "uk", form: 4, integer: []string{"3", "23", "33", "43", "53", "63", "73", "83", "103", "1003"}, decimal: []string(nil)},
12: {locales: "uk", form: 0, integer: []string{"0~2", "4~16", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
13: {locales: "kk", form: 5, integer: []string{"6", "9", "10", "16", "19", "20", "26", "29", "30", "36", "39", "40", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
14: {locales: "kk", form: 0, integer: []string{"0~5", "7", "8", "11~15", "17", "18", "21", "101", "1001"}, decimal: []string(nil)},
15: {locales: "it", form: 5, integer: []string{"8", "11", "80", "800"}, decimal: []string(nil)},
16: {locales: "it", form: 0, integer: []string{"0~7", "9", "10", "12~17", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
17: {locales: "ka", form: 2, integer: []string{"1"}, decimal: []string(nil)},
18: {locales: "ka", form: 5, integer: []string{"0", "2~16", "102", "1002"}, decimal: []string(nil)},
19: {locales: "ka", form: 0, integer: []string{"21~36", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
20: {locales: "sq", form: 2, integer: []string{"1"}, decimal: []string(nil)},
21: {locales: "sq", form: 5, integer: []string{"4", "24", "34", "44", "54", "64", "74", "84", "104", "1004"}, decimal: []string(nil)},
22: {locales: "sq", form: 0, integer: []string{"0", "2", "3", "5~17", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
23: {locales: "en", form: 2, integer: []string{"1", "21", "31", "41", "51", "61", "71", "81", "101", "1001"}, decimal: []string(nil)},
24: {locales: "en", form: 3, integer: []string{"2", "22", "32", "42", "52", "62", "72", "82", "102", "1002"}, decimal: []string(nil)},
25: {locales: "en", form: 4, integer: []string{"3", "23", "33", "43", "53", "63", "73", "83", "103", "1003"}, decimal: []string(nil)},
26: {locales: "en", form: 0, integer: []string{"0", "4~18", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
27: {locales: "mr", form: 2, integer: []string{"1"}, decimal: []string(nil)},
28: {locales: "mr", form: 3, integer: []string{"2", "3"}, decimal: []string(nil)},
29: {locales: "mr", form: 4, integer: []string{"4"}, decimal: []string(nil)},
30: {locales: "mr", form: 0, integer: []string{"0", "5~19", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
31: {locales: "ca", form: 2, integer: []string{"1", "3"}, decimal: []string(nil)},
32: {locales: "ca", form: 3, integer: []string{"2"}, decimal: []string(nil)},
33: {locales: "ca", form: 4, integer: []string{"4"}, decimal: []string(nil)},
34: {locales: "ca", form: 0, integer: []string{"0", "5~19", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
35: {locales: "mk", form: 2, integer: []string{"1", "21", "31", "41", "51", "61", "71", "81", "101", "1001"}, decimal: []string(nil)},
36: {locales: "mk", form: 3, integer: []string{"2", "22", "32", "42", "52", "62", "72", "82", "102", "1002"}, decimal: []string(nil)},
37: {locales: "mk", form: 5, integer: []string{"7", "8", "27", "28", "37", "38", "47", "48", "57", "58", "67", "68", "77", "78", "87", "88", "107", "1007"}, decimal: []string(nil)},
38: {locales: "mk", form: 0, integer: []string{"0", "3~6", "9~19", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
39: {locales: "az", form: 2, integer: []string{"1", "2", "5", "7", "8", "11", "12", "15", "17", "18", "20~22", "25", "101", "1001"}, decimal: []string(nil)},
40: {locales: "az", form: 4, integer: []string{"3", "4", "13", "14", "23", "24", "33", "34", "43", "44", "53", "54", "63", "64", "73", "74", "100", "1003"}, decimal: []string(nil)},
41: {locales: "az", form: 5, integer: []string{"0", "6", "16", "26", "36", "40", "46", "56", "106", "1006"}, decimal: []string(nil)},
42: {locales: "az", form: 0, integer: []string{"9", "10", "19", "29", "30", "39", "49", "59", "69", "79", "109", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
43: {locales: "gu hi", form: 2, integer: []string{"1"}, decimal: []string(nil)},
44: {locales: "gu hi", form: 3, integer: []string{"2", "3"}, decimal: []string(nil)},
45: {locales: "gu hi", form: 4, integer: []string{"4"}, decimal: []string(nil)},
46: {locales: "gu hi", form: 5, integer: []string{"6"}, decimal: []string(nil)},
47: {locales: "gu hi", form: 0, integer: []string{"0", "5", "7~20", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
48: {locales: "as bn", form: 2, integer: []string{"1", "5", "7~10"}, decimal: []string(nil)},
49: {locales: "as bn", form: 3, integer: []string{"2", "3"}, decimal: []string(nil)},
50: {locales: "as bn", form: 4, integer: []string{"4"}, decimal: []string(nil)},
51: {locales: "as bn", form: 5, integer: []string{"6"}, decimal: []string(nil)},
52: {locales: "as bn", form: 0, integer: []string{"0", "11~25", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
53: {locales: "cy", form: 1, integer: []string{"0", "7~9"}, decimal: []string(nil)},
54: {locales: "cy", form: 2, integer: []string{"1"}, decimal: []string(nil)},
55: {locales: "cy", form: 3, integer: []string{"2"}, decimal: []string(nil)},
56: {locales: "cy", form: 4, integer: []string{"3", "4"}, decimal: []string(nil)},
57: {locales: "cy", form: 5, integer: []string{"5", "6"}, decimal: []string(nil)},
58: {locales: "cy", form: 0, integer: []string{"10~25", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
} // Size: 4272 bytes
var cardinalTests = []pluralTest{ // 115 elements
0: {locales: "bm bo dz id ig ii in ja jbo jv jw kde kea km ko lkt lo ms my nqo root sah ses sg th to vi wo yo yue zh", form: 0, integer: []string{"0~15", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"0.0~1.5", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
1: {locales: "am as bn fa gu hi kn mr zu", form: 2, integer: []string{"0", "1"}, decimal: []string{"0.0~1.0", "0.00~0.04"}},
2: {locales: "am as bn fa gu hi kn mr zu", form: 0, integer: []string{"2~17", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"1.1~2.6", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
3: {locales: "ff fr hy kab", form: 2, integer: []string{"0", "1"}, decimal: []string{"0.0~1.5"}},
4: {locales: "ff fr hy kab", form: 0, integer: []string{"2~17", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"2.0~3.5", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
5: {locales: "ast ca de en et fi fy gl it ji nl sv sw ur yi", form: 2, integer: []string{"1"}, decimal: []string(nil)},
6: {locales: "ast ca de en et fi fy gl it ji nl sv sw ur yi", form: 0, integer: []string{"0", "2~16", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"0.0~1.5", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
7: {locales: "si", form: 2, integer: []string{"0", "1"}, decimal: []string{"0.0", "0.1", "1.0", "0.00", "0.01", "1.00", "0.000", "0.001", "1.000", "0.0000", "0.0001", "1.0000"}},
8: {locales: "si", form: 0, integer: []string{"2~17", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"0.2~0.9", "1.1~1.8", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
9: {locales: "ak bh guw ln mg nso pa ti wa", form: 2, integer: []string{"0", "1"}, decimal: []string{"0.0", "1.0", "0.00", "1.00", "0.000", "1.000", "0.0000", "1.0000"}},
10: {locales: "ak bh guw ln mg nso pa ti wa", form: 0, integer: []string{"2~17", "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"}},
11: {locales: "tzm", form: 2, integer: []string{"0", "1", "11~24"}, decimal: []string{"0.0", "1.0", "11.0", "12.0", "13.0", "14.0", "15.0", "16.0", "17.0", "18.0", "19.0", "20.0", "21.0", "22.0", "23.0", "24.0"}},
12: {locales: "tzm", form: 0, integer: []string{"2~10", "100~106", "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"}},
13: {locales: "pt", form: 2, integer: []string{"0", "1"}, decimal: []string{"0.0", "1.0", "0.00", "1.00", "0.000", "1.000", "0.0000", "1.0000"}},
14: {locales: "pt", form: 0, integer: []string{"2~17", "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"}},
15: {locales: "af asa az bem bez bg brx ce cgg chr ckb dv ee el eo es eu fo fur gsw ha haw hu jgo jmc ka kaj kcg kk kkj kl ks ksb ku ky lb lg mas mgo ml mn nah nb nd ne nn nnh no nr ny nyn om or os pap ps rm rof rwk saq sdh seh sn so sq ss ssy st syr ta te teo tig tk tn tr ts ug uz ve vo vun wae xh xog", form: 2, integer: []string{"1"}, decimal: []string{"1.0", "1.00", "1.000", "1.0000"}},
16: {locales: "af asa az bem bez bg brx ce cgg chr ckb dv ee el eo es eu fo fur gsw ha haw hu jgo jmc ka kaj kcg kk kkj kl ks ksb ku ky lb lg mas mgo ml mn nah nb nd ne nn nnh no nr ny nyn om or os pap ps rm rof rwk saq sdh seh sn so sq ss ssy st syr ta te teo tig tk tn tr ts ug uz ve vo vun wae xh xog", form: 0, integer: []string{"0", "2~16", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"0.0~0.9", "1.1~1.6", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
17: {locales: "pt_PT", form: 2, integer: []string{"1"}, decimal: []string(nil)},
18: {locales: "pt_PT", form: 0, integer: []string{"0", "2~16", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"0.0~1.5", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
19: {locales: "da", form: 2, integer: []string{"1"}, decimal: []string{"0.1~1.6"}},
20: {locales: "da", form: 0, integer: []string{"0", "2~16", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"0.0", "2.0~3.4", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
21: {locales: "is", form: 2, integer: []string{"1", "21", "31", "41", "51", "61", "71", "81", "101", "1001"}, decimal: []string{"0.1~1.6", "10.1", "100.1", "1000.1"}},
22: {locales: "is", form: 0, integer: []string{"0", "2~16", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"0.0", "2.0", "3.0", "4.0", "5.0", "6.0", "7.0", "8.0", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
23: {locales: "mk", form: 2, integer: []string{"1", "11", "21", "31", "41", "51", "61", "71", "101", "1001"}, decimal: []string{"0.1", "1.1", "2.1", "3.1", "4.1", "5.1", "6.1", "7.1", "10.1", "100.1", "1000.1"}},
24: {locales: "mk", form: 0, integer: []string{"0", "2~10", "12~17", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"0.0", "0.2~1.0", "1.2~1.7", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
25: {locales: "fil tl", form: 2, integer: []string{"0~3", "5", "7", "8", "10~13", "15", "17", "18", "20", "21", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"0.0~0.3", "0.5", "0.7", "0.8", "1.0~1.3", "1.5", "1.7", "1.8", "2.0", "2.1", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
26: {locales: "fil tl", form: 0, integer: []string{"4", "6", "9", "14", "16", "19", "24", "26", "104", "1004"}, decimal: []string{"0.4", "0.6", "0.9", "1.4", "1.6", "1.9", "2.4", "2.6", "10.4", "100.4", "1000.4"}},
27: {locales: "lv prg", form: 1, integer: []string{"0", "10~20", "30", "40", "50", "60", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"0.0", "10.0", "11.0", "12.0", "13.0", "14.0", "15.0", "16.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
28: {locales: "lv prg", form: 2, integer: []string{"1", "21", "31", "41", "51", "61", "71", "81", "101", "1001"}, decimal: []string{"0.1", "1.0", "1.1", "2.1", "3.1", "4.1", "5.1", "6.1", "7.1", "10.1", "100.1", "1000.1"}},
29: {locales: "lv prg", form: 0, integer: []string{"2~9", "22~29", "102", "1002"}, decimal: []string{"0.2~0.9", "1.2~1.9", "10.2", "100.2", "1000.2"}},
30: {locales: "lag", form: 1, integer: []string{"0"}, decimal: []string{"0.0", "0.00", "0.000", "0.0000"}},
31: {locales: "lag", form: 2, integer: []string{"1"}, decimal: []string{"0.1~1.6"}},
32: {locales: "lag", form: 0, integer: []string{"2~17", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"2.0~3.5", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
33: {locales: "ksh", form: 1, integer: []string{"0"}, decimal: []string{"0.0", "0.00", "0.000", "0.0000"}},
34: {locales: "ksh", form: 2, integer: []string{"1"}, decimal: []string{"1.0", "1.00", "1.000", "1.0000"}},
35: {locales: "ksh", form: 0, integer: []string{"2~17", "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"}},
36: {locales: "iu kw naq se sma smi smj smn sms", form: 2, integer: []string{"1"}, decimal: []string{"1.0", "1.00", "1.000", "1.0000"}},
37: {locales: "iu kw naq se sma smi smj smn sms", form: 3, integer: []string{"2"}, decimal: []string{"2.0", "2.00", "2.000", "2.0000"}},
38: {locales: "iu kw naq se sma smi smj smn sms", form: 0, integer: []string{"0", "3~17", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"0.0~0.9", "1.1~1.6", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
39: {locales: "shi", form: 2, integer: []string{"0", "1"}, decimal: []string{"0.0~1.0", "0.00~0.04"}},
40: {locales: "shi", form: 4, integer: []string{"2~10"}, decimal: []string{"2.0", "3.0", "4.0", "5.0", "6.0", "7.0", "8.0", "9.0", "10.0", "2.00", "3.00", "4.00", "5.00", "6.00", "7.00", "8.00"}},
41: {locales: "shi", form: 0, integer: []string{"11~26", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"1.1~1.9", "2.1~2.7", "10.1", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
42: {locales: "mo ro", form: 2, integer: []string{"1"}, decimal: []string(nil)},
43: {locales: "mo ro", form: 4, integer: []string{"0", "2~16", "101", "1001"}, decimal: []string{"0.0~1.5", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
44: {locales: "mo ro", form: 0, integer: []string{"20~35", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
45: {locales: "bs hr sh sr", form: 2, integer: []string{"1", "21", "31", "41", "51", "61", "71", "81", "101", "1001"}, decimal: []string{"0.1", "1.1", "2.1", "3.1", "4.1", "5.1", "6.1", "7.1", "10.1", "100.1", "1000.1"}},
46: {locales: "bs hr sh sr", form: 4, integer: []string{"2~4", "22~24", "32~34", "42~44", "52~54", "62", "102", "1002"}, decimal: []string{"0.2~0.4", "1.2~1.4", "2.2~2.4", "3.2~3.4", "4.2~4.4", "5.2", "10.2", "100.2", "1000.2"}},
47: {locales: "bs hr sh sr", form: 0, integer: []string{"0", "5~19", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"0.0", "0.5~1.0", "1.5~2.0", "2.5~2.7", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
48: {locales: "gd", form: 2, integer: []string{"1", "11"}, decimal: []string{"1.0", "11.0", "1.00", "11.00", "1.000", "11.000", "1.0000"}},
49: {locales: "gd", form: 3, integer: []string{"2", "12"}, decimal: []string{"2.0", "12.0", "2.00", "12.00", "2.000", "12.000", "2.0000"}},
50: {locales: "gd", form: 4, integer: []string{"3~10", "13~19"}, decimal: []string{"3.0", "4.0", "5.0", "6.0", "7.0", "8.0", "9.0", "10.0", "13.0", "14.0", "15.0", "16.0", "17.0", "18.0", "19.0", "3.00"}},
51: {locales: "gd", form: 0, integer: []string{"0", "20~34", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"0.0~0.9", "1.1~1.6", "10.1", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
52: {locales: "sl", form: 2, integer: []string{"1", "101", "201", "301", "401", "501", "601", "701", "1001"}, decimal: []string(nil)},
53: {locales: "sl", form: 3, integer: []string{"2", "102", "202", "302", "402", "502", "602", "702", "1002"}, decimal: []string(nil)},
54: {locales: "sl", form: 4, integer: []string{"3", "4", "103", "104", "203", "204", "303", "304", "403", "404", "503", "504", "603", "604", "703", "704", "1003"}, decimal: []string{"0.0~1.5", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
55: {locales: "sl", form: 0, integer: []string{"0", "5~19", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
56: {locales: "dsb hsb", form: 2, integer: []string{"1", "101", "201", "301", "401", "501", "601", "701", "1001"}, decimal: []string{"0.1", "1.1", "2.1", "3.1", "4.1", "5.1", "6.1", "7.1", "10.1", "100.1", "1000.1"}},
57: {locales: "dsb hsb", form: 3, integer: []string{"2", "102", "202", "302", "402", "502", "602", "702", "1002"}, decimal: []string{"0.2", "1.2", "2.2", "3.2", "4.2", "5.2", "6.2", "7.2", "10.2", "100.2", "1000.2"}},
58: {locales: "dsb hsb", form: 4, integer: []string{"3", "4", "103", "104", "203", "204", "303", "304", "403", "404", "503", "504", "603", "604", "703", "704", "1003"}, decimal: []string{"0.3", "0.4", "1.3", "1.4", "2.3", "2.4", "3.3", "3.4", "4.3", "4.4", "5.3", "5.4", "6.3", "6.4", "7.3", "7.4", "10.3", "100.3", "1000.3"}},
59: {locales: "dsb hsb", form: 0, integer: []string{"0", "5~19", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"0.0", "0.5~1.0", "1.5~2.0", "2.5~2.7", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
60: {locales: "he iw", form: 2, integer: []string{"1"}, decimal: []string(nil)},
61: {locales: "he iw", form: 3, integer: []string{"2"}, decimal: []string(nil)},
62: {locales: "he iw", form: 5, integer: []string{"20", "30", "40", "50", "60", "70", "80", "90", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
63: {locales: "he iw", form: 0, integer: []string{"0", "3~17", "101", "1001"}, decimal: []string{"0.0~1.5", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
64: {locales: "cs sk", form: 2, integer: []string{"1"}, decimal: []string(nil)},
65: {locales: "cs sk", form: 4, integer: []string{"2~4"}, decimal: []string(nil)},
66: {locales: "cs sk", form: 5, integer: []string(nil), decimal: []string{"0.0~1.5", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
67: {locales: "cs sk", form: 0, integer: []string{"0", "5~19", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
68: {locales: "pl", form: 2, integer: []string{"1"}, decimal: []string(nil)},
69: {locales: "pl", form: 4, integer: []string{"2~4", "22~24", "32~34", "42~44", "52~54", "62", "102", "1002"}, decimal: []string(nil)},
70: {locales: "pl", form: 5, integer: []string{"0", "5~19", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
71: {locales: "pl", form: 0, integer: []string(nil), decimal: []string{"0.0~1.5", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
72: {locales: "be", form: 2, integer: []string{"1", "21", "31", "41", "51", "61", "71", "81", "101", "1001"}, decimal: []string{"1.0", "21.0", "31.0", "41.0", "51.0", "61.0", "71.0", "81.0", "101.0", "1001.0"}},
73: {locales: "be", form: 4, integer: []string{"2~4", "22~24", "32~34", "42~44", "52~54", "62", "102", "1002"}, decimal: []string{"2.0", "3.0", "4.0", "22.0", "23.0", "24.0", "32.0", "33.0", "102.0", "1002.0"}},
74: {locales: "be", form: 5, integer: []string{"0", "5~19", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"0.0", "5.0", "6.0", "7.0", "8.0", "9.0", "10.0", "11.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
75: {locales: "be", form: 0, integer: []string(nil), decimal: []string{"0.1~0.9", "1.1~1.7", "10.1", "100.1", "1000.1"}},
76: {locales: "lt", form: 2, integer: []string{"1", "21", "31", "41", "51", "61", "71", "81", "101", "1001"}, decimal: []string{"1.0", "21.0", "31.0", "41.0", "51.0", "61.0", "71.0", "81.0", "101.0", "1001.0"}},
77: {locales: "lt", form: 4, integer: []string{"2~9", "22~29", "102", "1002"}, decimal: []string{"2.0", "3.0", "4.0", "5.0", "6.0", "7.0", "8.0", "9.0", "22.0", "102.0", "1002.0"}},
78: {locales: "lt", form: 5, integer: []string(nil), decimal: []string{"0.1~0.9", "1.1~1.7", "10.1", "100.1", "1000.1"}},
79: {locales: "lt", form: 0, integer: []string{"0", "10~20", "30", "40", "50", "60", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"0.0", "10.0", "11.0", "12.0", "13.0", "14.0", "15.0", "16.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
80: {locales: "mt", form: 2, integer: []string{"1"}, decimal: []string{"1.0", "1.00", "1.000", "1.0000"}},
81: {locales: "mt", form: 4, integer: []string{"0", "2~10", "102~107", "1002"}, decimal: []string{"0.0", "2.0", "3.0", "4.0", "5.0", "6.0", "7.0", "8.0", "10.0", "102.0", "1002.0"}},
82: {locales: "mt", form: 5, integer: []string{"11~19", "111~117", "1011"}, decimal: []string{"11.0", "12.0", "13.0", "14.0", "15.0", "16.0", "17.0", "18.0", "111.0", "1011.0"}},
83: {locales: "mt", form: 0, integer: []string{"20~35", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"0.1~0.9", "1.1~1.7", "10.1", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
84: {locales: "ru uk", form: 2, integer: []string{"1", "21", "31", "41", "51", "61", "71", "81", "101", "1001"}, decimal: []string(nil)},
85: {locales: "ru uk", form: 4, integer: []string{"2~4", "22~24", "32~34", "42~44", "52~54", "62", "102", "1002"}, decimal: []string(nil)},
86: {locales: "ru uk", form: 5, integer: []string{"0", "5~19", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
87: {locales: "ru uk", form: 0, integer: []string(nil), decimal: []string{"0.0~1.5", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
88: {locales: "br", form: 2, integer: []string{"1", "21", "31", "41", "51", "61", "81", "101", "1001"}, decimal: []string{"1.0", "21.0", "31.0", "41.0", "51.0", "61.0", "81.0", "101.0", "1001.0"}},
89: {locales: "br", form: 3, integer: []string{"2", "22", "32", "42", "52", "62", "82", "102", "1002"}, decimal: []string{"2.0", "22.0", "32.0", "42.0", "52.0", "62.0", "82.0", "102.0", "1002.0"}},
90: {locales: "br", form: 4, integer: []string{"3", "4", "9", "23", "24", "29", "33", "34", "39", "43", "44", "49", "103", "1003"}, decimal: []string{"3.0", "4.0", "9.0", "23.0", "24.0", "29.0", "33.0", "34.0", "103.0", "1003.0"}},
91: {locales: "br", form: 5, integer: []string{"1000000"}, decimal: []string{"1000000.0", "1000000.00", "1000000.000"}},
92: {locales: "br", form: 0, integer: []string{"0", "5~8", "10~20", "100", "1000", "10000", "100000"}, decimal: []string{"0.0~0.9", "1.1~1.6", "10.0", "100.0", "1000.0", "10000.0", "100000.0"}},
93: {locales: "ga", form: 2, integer: []string{"1"}, decimal: []string{"1.0", "1.00", "1.000", "1.0000"}},
94: {locales: "ga", form: 3, integer: []string{"2"}, decimal: []string{"2.0", "2.00", "2.000", "2.0000"}},
95: {locales: "ga", form: 4, integer: []string{"3~6"}, decimal: []string{"3.0", "4.0", "5.0", "6.0", "3.00", "4.00", "5.00", "6.00", "3.000", "4.000", "5.000", "6.000", "3.0000", "4.0000", "5.0000", "6.0000"}},
96: {locales: "ga", form: 5, integer: []string{"7~10"}, decimal: []string{"7.0", "8.0", "9.0", "10.0", "7.00", "8.00", "9.00", "10.00", "7.000", "8.000", "9.000", "10.000", "7.0000", "8.0000", "9.0000", "10.0000"}},
97: {locales: "ga", form: 0, integer: []string{"0", "11~25", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"0.0~0.9", "1.1~1.6", "10.1", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
98: {locales: "gv", form: 2, integer: []string{"1", "11", "21", "31", "41", "51", "61", "71", "101", "1001"}, decimal: []string(nil)},
99: {locales: "gv", form: 3, integer: []string{"2", "12", "22", "32", "42", "52", "62", "72", "102", "1002"}, decimal: []string(nil)},
100: {locales: "gv", form: 4, integer: []string{"0", "20", "40", "60", "80", "100", "120", "140", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
101: {locales: "gv", form: 5, integer: []string(nil), decimal: []string{"0.0~1.5", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
102: {locales: "gv", form: 0, integer: []string{"3~10", "13~19", "23", "103", "1003"}, decimal: []string(nil)},
103: {locales: "ar ars", form: 1, integer: []string{"0"}, decimal: []string{"0.0", "0.00", "0.000", "0.0000"}},
104: {locales: "ar ars", form: 2, integer: []string{"1"}, decimal: []string{"1.0", "1.00", "1.000", "1.0000"}},
105: {locales: "ar ars", form: 3, integer: []string{"2"}, decimal: []string{"2.0", "2.00", "2.000", "2.0000"}},
106: {locales: "ar ars", form: 4, integer: []string{"3~10", "103~110", "1003"}, decimal: []string{"3.0", "4.0", "5.0", "6.0", "7.0", "8.0", "9.0", "10.0", "103.0", "1003.0"}},
107: {locales: "ar ars", form: 5, integer: []string{"11~26", "111", "1011"}, decimal: []string{"11.0", "12.0", "13.0", "14.0", "15.0", "16.0", "17.0", "18.0", "111.0", "1011.0"}},
108: {locales: "ar ars", form: 0, integer: []string{"100~102", "200~202", "300~302", "400~402", "500~502", "600", "1000", "10000", "100000", "1000000"}, decimal: []string{"0.1~0.9", "1.1~1.7", "10.1", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
109: {locales: "cy", form: 1, integer: []string{"0"}, decimal: []string{"0.0", "0.00", "0.000", "0.0000"}},
110: {locales: "cy", form: 2, integer: []string{"1"}, decimal: []string{"1.0", "1.00", "1.000", "1.0000"}},
111: {locales: "cy", form: 3, integer: []string{"2"}, decimal: []string{"2.0", "2.00", "2.000", "2.0000"}},
112: {locales: "cy", form: 4, integer: []string{"3"}, decimal: []string{"3.0", "3.00", "3.000", "3.0000"}},
113: {locales: "cy", form: 5, integer: []string{"6"}, decimal: []string{"6.0", "6.00", "6.000", "6.0000"}},
114: {locales: "cy", form: 0, 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: 166DAB75
+513
View File
@@ -0,0 +1,513 @@
// 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
// This file generates data for the CLDR plural rules, as defined in
// http://unicode.org/reports/tr35/tr35-numbers.html#Language_Plural_Rules
//
// We assume a slightly simplified grammar:
//
// condition = and_condition ('or' and_condition)* samples
// and_condition = relation ('and' relation)*
// relation = expr ('=' | '!=') range_list
// expr = operand ('%' '10' '0'* )?
// operand = 'n' | 'i' | 'f' | 't' | 'v' | 'w'
// range_list = (range | value) (',' range_list)*
// range = value'..'value
// value = digit+
// digit = 0|1|2|3|4|5|6|7|8|9
//
// samples = ('@integer' sampleList)?
// ('@decimal' sampleList)?
// sampleList = sampleRange (',' sampleRange)* (',' ('…'|'...'))?
// sampleRange = decimalValue ('~' decimalValue)?
// decimalValue = value ('.' value)?
//
// Symbol Value
// n absolute value of the source number (integer and decimals).
// i integer digits of n.
// v number of visible fraction digits in n, with trailing zeros.
// w number of visible fraction digits in n, without trailing zeros.
// f visible fractional digits in n, with trailing zeros.
// t visible fractional digits in n, without trailing zeros.
//
// The algorithm for which the data is generated is based on the following
// observations
//
// - the number of different sets of numbers which the plural rules use to
// test inclusion is limited,
// - most numbers that are tested on are < 100
//
// This allows us to define a bitmap for each number < 100 where a bit i
// indicates whether this number is included in some defined set i.
// The function matchPlural in plural.go defines how we can subsequently use
// this data to determine inclusion.
//
// There are a few languages for which this doesn't work. For one Italian and
// Azerbaijan, which both test against numbers > 100 for ordinals and Breton,
// which considers whether numbers are multiples of hundreds. The model here
// could be extended to handle Italian and Azerbaijan fairly easily (by
// considering the numbers 100, 200, 300, ..., 800, 900 in addition to the first
// 100), but for now it seems easier to just hard-code these cases.
import (
"bufio"
"bytes"
"flag"
"fmt"
"log"
"strconv"
"strings"
"golang.org/x/text/internal"
"golang.org/x/text/internal/gen"
"golang.org/x/text/language"
"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)
genPluralsTests(w, data)
}
type pluralTest struct {
locales string // space-separated list of locales for this test
form int // Use int instead of Form to simplify generation.
integer []string // Entries of the form \d+ or \d+~\d+
decimal []string // Entries of the form \f+ or \f+ +~\f+, where f is \d+\.\d+
}
func genPluralsTests(w *gen.CodeWriter, data *cldr.CLDR) {
w.WriteType(pluralTest{})
for _, plurals := range data.Supplemental().Plurals {
if plurals.Type == "" {
// The empty type is reserved for plural ranges.
continue
}
tests := []pluralTest{}
for _, pRules := range plurals.PluralRules {
for _, rule := range pRules.PluralRule {
test := pluralTest{
locales: pRules.Locales,
form: int(countMap[rule.Count]),
}
scan := bufio.NewScanner(strings.NewReader(rule.Data()))
scan.Split(splitTokens)
var p *[]string
for scan.Scan() {
switch t := scan.Text(); t {
case "@integer":
p = &test.integer
case "@decimal":
p = &test.decimal
case ",", "…":
default:
if p != nil {
*p = append(*p, t)
}
}
}
tests = append(tests, test)
}
}
w.WriteVar(plurals.Type+"Tests", tests)
}
}
func genPlurals(w *gen.CodeWriter, data *cldr.CLDR) {
for _, plurals := range data.Supplemental().Plurals {
if plurals.Type == "" {
continue
}
// Initialize setMap and inclusionMasks. They are already populated with
// a few entries to serve as an example and to assign nice numbers to
// common cases.
// setMap contains sets of numbers represented by boolean arrays where
// a true value for element i means that the number i is included.
setMap := map[[numN]bool]int{
// The above init func adds an entry for including all numbers.
[numN]bool{1: true}: 1, // fix {1} to a nice value
[numN]bool{2: true}: 2, // fix {2} to a nice value
[numN]bool{0: true}: 3, // fix {0} to a nice value
}
// inclusionMasks contains bit masks for every number under numN to
// indicate in which set the number is included. Bit 1 << x will be set
// if it is included in set x.
inclusionMasks := [numN]uint64{
// Note: these entries are not complete: more bits will be set along the way.
0: 1 << 3,
1: 1 << 1,
2: 1 << 2,
}
// Create set {0..99}. We will assign this set the identifier 0.
var all [numN]bool
for i := range all {
// Mark number i as being included in the set (which has identifier 0).
inclusionMasks[i] |= 1 << 0
// Mark number i as included in the set.
all[i] = true
}
// Register the identifier for the set.
setMap[all] = 0
rules := []pluralCheck{}
index := []byte{0}
langMap := map[int]byte{0: 0} // From compact language index to index
for _, pRules := range plurals.PluralRules {
// Parse the rules.
var conds []orCondition
for _, rule := range pRules.PluralRule {
form := countMap[rule.Count]
conds = parsePluralCondition(conds, rule.Data(), form)
}
// Encode the rules.
for _, c := range conds {
// If an or condition only has filters, we create an entry for
// this filter and the set that contains all values.
empty := true
for _, b := range c.used {
empty = empty && !b
}
if empty {
rules = append(rules, pluralCheck{
cat: byte(opMod<<opShift) | byte(c.form),
setID: 0, // all values
})
continue
}
// We have some entries with values.
for i, set := range c.set {
if !c.used[i] {
continue
}
index, ok := setMap[set]
if !ok {
index = len(setMap)
setMap[set] = index
for i := range inclusionMasks {
if set[i] {
inclusionMasks[i] |= 1 << uint64(index)
}
}
}
rules = append(rules, pluralCheck{
cat: byte(i<<opShift | andNext),
setID: byte(index),
})
}
// Now set the last entry to the plural form the rule matches.
rules[len(rules)-1].cat &^= formMask
rules[len(rules)-1].cat |= byte(c.form)
}
// Point the relevant locales to the created entries.
for _, loc := range strings.Split(pRules.Locales, " ") {
if strings.TrimSpace(loc) == "" {
continue
}
lang, ok := language.CompactIndex(language.MustParse(loc))
if !ok {
log.Printf("No compact index for locale %q", loc)
}
langMap[lang] = byte(len(index) - 1)
}
index = append(index, byte(len(rules)))
}
w.WriteVar(plurals.Type+"Rules", rules)
w.WriteVar(plurals.Type+"Index", index)
// Expand the values.
langToIndex := make([]byte, language.NumCompactTags)
for i := range langToIndex {
for p := i; ; p = int(internal.Parent[p]) {
if x, ok := langMap[p]; ok {
langToIndex[i] = x
break
}
}
}
w.WriteVar(plurals.Type+"LangToIndex", langToIndex)
// Need to convert array to slice because of golang.org/issue/7651.
// This will allow tables to be dropped when unused. This is especially
// relevant for the ordinal data, which I suspect won't be used as much.
w.WriteVar(plurals.Type+"InclusionMasks", inclusionMasks[:])
if len(rules) > 0xFF {
log.Fatalf("Too many entries for rules: %#x", len(rules))
}
if len(index) > 0xFF {
log.Fatalf("Too many entries for index: %#x", len(index))
}
if len(setMap) > 64 { // maximum number of bits.
log.Fatalf("Too many entries for setMap: %d", len(setMap))
}
w.WriteComment(
"Slots used for %s: %X of 0xFF rules; %X of 0xFF indexes; %d of 64 sets",
plurals.Type, len(rules), len(index), len(setMap))
// Prevent comment from attaching to the next entry.
fmt.Fprint(w, "\n\n")
}
}
type orCondition struct {
original string // for debugging
form Form
used [32]bool
set [32][numN]bool
}
func (o *orCondition) add(op opID, mod int, v []int) (ok bool) {
ok = true
for _, x := range v {
if x >= maxMod {
ok = false
break
}
}
for i := 0; i < numN; i++ {
m := i
if mod != 0 {
m = i % mod
}
if !intIn(m, v) {
o.set[op][i] = false
}
}
if ok {
o.used[op] = true
}
return ok
}
func intIn(x int, a []int) bool {
for _, y := range a {
if x == y {
return true
}
}
return false
}
var operandIndex = map[string]opID{
"i": opI,
"n": opN,
"f": opF,
"v": opV,
"w": opW,
}
// parsePluralCondition parses the condition of a single pluralRule and appends
// the resulting or conditions to conds.
//
// Example rules:
// // Category "one" in English: only allow 1 with no visible fraction
// i = 1 and v = 0 @integer 1
//
// // Category "few" in Czech: all numbers with visible fractions
// v != 0 @decimal ...
//
// // Category "zero" in Latvian: all multiples of 10 or the numbers 11-19 or
// // numbers with a fraction 11..19 and no trailing zeros.
// n % 10 = 0 or n % 100 = 11..19 or v = 2 and f % 100 = 11..19 @integer ...
//
// @integer and @decimal are followed by examples and are not relevant for the
// rule itself. The are used here to signal the termination of the rule.
func parsePluralCondition(conds []orCondition, s string, f Form) []orCondition {
scan := bufio.NewScanner(strings.NewReader(s))
scan.Split(splitTokens)
for {
cond := orCondition{original: s, form: f}
// Set all numbers to be allowed for all number classes and restrict
// from here on.
for i := range cond.set {
for j := range cond.set[i] {
cond.set[i][j] = true
}
}
andLoop:
for {
var token string
scan.Scan() // Must exist.
switch class := scan.Text(); class {
case "t":
class = "w" // equal to w for t == 0
fallthrough
case "n", "i", "f", "v", "w":
op := scanToken(scan)
opCode := operandIndex[class]
mod := 0
if op == "%" {
opCode |= opMod
switch v := scanUint(scan); v {
case 10, 100:
mod = v
case 1000:
// A more general solution would be to allow checking
// against multiples of 100 and include entries for the
// numbers 100..900 in the inclusion masks. At the
// moment this would only help Azerbaijan and Italian.
// Italian doesn't use '%', so this must be Azerbaijan.
cond.used[opAzerbaijan00s] = true
return append(conds, cond)
case 1000000:
cond.used[opBretonM] = true
return append(conds, cond)
default:
log.Fatalf("Modulo value not supported %d", v)
}
op = scanToken(scan)
}
if op != "=" && op != "!=" {
log.Fatalf("Unexpected op %q", op)
}
if op == "!=" {
opCode |= opNotEqual
}
a := []int{}
v := scanUint(scan)
if class == "w" && v != 0 {
log.Fatalf("Must compare against zero for operand type %q", class)
}
token = scanToken(scan)
for {
switch token {
case "..":
end := scanUint(scan)
for ; v <= end; v++ {
a = append(a, v)
}
token = scanToken(scan)
default: // ",", "or", "and", "@..."
a = append(a, v)
}
if token != "," {
break
}
v = scanUint(scan)
token = scanToken(scan)
}
if !cond.add(opCode, mod, a) {
// Detected large numbers. As we ruled out Azerbaijan, this
// must be the many rule for Italian ordinals.
cond.set[opItalian800] = cond.set[opN]
cond.used[opItalian800] = true
}
case "@integer", "@decimal": // "other" entry: tests only.
return conds
default:
log.Fatalf("Unexpected operand class %q (%s)", class, s)
}
switch token {
case "or":
conds = append(conds, cond)
break andLoop
case "@integer", "@decimal": // examples
// There is always an example in practice, so we always terminate here.
if err := scan.Err(); err != nil {
log.Fatal(err)
}
return append(conds, cond)
case "and":
// keep accumulating
default:
log.Fatalf("Unexpected token %q", token)
}
}
}
}
func scanToken(scan *bufio.Scanner) string {
scan.Scan()
return scan.Text()
}
func scanUint(scan *bufio.Scanner) int {
scan.Scan()
val, err := strconv.ParseUint(scan.Text(), 10, 32)
if err != nil {
log.Fatal(err)
}
return int(val)
}
// splitTokens can be used with bufio.Scanner to tokenize CLDR plural rules.
func splitTokens(data []byte, atEOF bool) (advance int, token []byte, err error) {
condTokens := [][]byte{
[]byte(".."),
[]byte(","),
[]byte("!="),
[]byte("="),
}
advance, token, err = bufio.ScanWords(data, atEOF)
for _, t := range condTokens {
if len(t) >= len(token) {
continue
}
switch p := bytes.Index(token, t); {
case p == -1:
case p == 0:
advance = len(t)
token = token[:len(t)]
return advance - len(token) + len(t), token[:len(t)], err
case p < advance:
// Don't split when "=" overlaps "!=".
if t[0] == '=' && token[p-1] == '!' {
continue
}
advance = p
token = token[:p]
}
}
return advance, token, err
}
+74
View File
@@ -0,0 +1,74 @@
// 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
// Form defines a plural form.
//
// Not all languages support all forms. Also, the meaning of each form varies
// per language. It is important to note that the name of a form does not
// necessarily correspond one-to-one with the set of numbers. For instance,
// for Croation, One matches not only 1, but also 11, 21, etc.
//
// Each language must at least support the form "other".
type Form byte
const (
Other Form = iota
Zero
One
Two
Few
Many
)
var countMap = map[string]Form{
"other": Other,
"zero": Zero,
"one": One,
"two": Two,
"few": Few,
"many": 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
)
+234
View File
@@ -0,0 +1,234 @@
// 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.
//go:generate go run gen.go gen_common.go
// Package plural provides utilities for handling linguistic plurals in text.
//
// The definitions in this package are based on the plural rule handling defined
// in CLDR. See
// http://unicode.org/reports/tr35/tr35-numbers.html#Language_Plural_Rules for
// details.
package plural
import (
"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
inclusionMasks []uint64
}
var (
// 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[:],
}
cardinal = &Rules{
cardinalRules,
cardinalIndex,
cardinalLangToIndex,
cardinalInclusionMasks[:],
}
)
// 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
}
// 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) 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 validForms(p *Rules, t language.Tag) (forms []Form) {
index, _ := language.CompactIndex(t)
offset := p.langToIndex[index]
rules := p.rules[p.index[offset]:p.index[offset+1]]
forms = append(forms, Other)
last := Other
for _, r := range rules {
if cat := Form(r.cat & formMask); cat != andNext && last != cat {
forms = append(forms, cat)
last = cat
}
}
return forms
}
func (p *Rules) matchComponents(t language.Tag, n, f, scale int) Form {
index, _ := language.CompactIndex(t)
return matchPlural(p, index, n, f, scale)
}
func matchPlural(p *Rules, index int, n, f, v int) Form {
nMask := p.inclusionMasks[n%maxMod]
// Compute the fMask inline in the rules below, as it is relatively rare.
// fMask := p.inclusionMasks[f%maxMod]
vMask := p.inclusionMasks[v%maxMod]
// Do the matching
offset := p.langToIndex[index]
rules := p.rules[p.index[offset]:p.index[offset+1]]
for i := 0; i < len(rules); i++ {
rule := rules[i]
setBit := uint64(1 << rule.setID)
var skip bool
switch op := opID(rule.cat >> opShift); op {
case opI: // i = x
skip = n >= numN || nMask&setBit == 0
case opI | opNotEqual: // i != x
skip = n < numN && nMask&setBit != 0
case opI | opMod: // i % m = x
skip = nMask&setBit == 0
case opI | opMod | opNotEqual: // i % m != x
skip = nMask&setBit != 0
case opN: // n = x
skip = f != 0 || n >= numN || nMask&setBit == 0
case opN | opNotEqual: // n != x
skip = f == 0 && n < numN && nMask&setBit != 0
case opN | opMod: // n % m = x
skip = f != 0 || nMask&setBit == 0
case opN | opMod | opNotEqual: // n % m != x
skip = f == 0 && nMask&setBit != 0
case opF: // f = x
skip = f >= numN || p.inclusionMasks[f%maxMod]&setBit == 0
case opF | opNotEqual: // f != x
skip = f < numN && p.inclusionMasks[f%maxMod]&setBit != 0
case opF | opMod: // f % m = x
skip = p.inclusionMasks[f%maxMod]&setBit == 0
case opF | opMod | opNotEqual: // f % m != x
skip = p.inclusionMasks[f%maxMod]&setBit != 0
case opV: // v = x
skip = v < numN && vMask&setBit == 0
case opV | opNotEqual: // v != x
skip = v < numN && vMask&setBit != 0
case opW: // w == 0
skip = f != 0
case opW | opNotEqual: // w != 0
skip = f == 0
// Hard-wired rules that cannot be handled by our algorithm.
case opBretonM:
skip = f != 0 || n == 0 || n%1000000 != 0
case opAzerbaijan00s:
// 100,200,300,400,500,600,700,800,900
skip = n == 0 || n >= 1000 || n%100 != 0
case opItalian800:
skip = (f != 0 || n >= numN || nMask&setBit == 0) && n != 800
}
if skip {
// advance over AND entries.
for ; i < len(rules) && rules[i].cat&formMask == andNext; i++ {
}
continue
}
// return if we have a final entry.
if cat := rule.cat & formMask; cat != andNext {
return Form(cat)
}
}
return Other
}
+203
View File
@@ -0,0 +1,203 @@
// 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.
package plural
import (
"fmt"
"reflect"
"strconv"
"strings"
"testing"
"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 TestValidForms(t *testing.T) {
testCases := []struct {
tag language.Tag
want []Form
}{
{language.AmericanEnglish, []Form{Other, One}},
{language.Portuguese, []Form{Other, One}},
{language.Latvian, []Form{Other, Zero, One}},
{language.Arabic, []Form{Other, Zero, One, Two, Few, Many}},
{language.Russian, []Form{Other, One, Few, Many}},
}
for _, tc := range testCases {
got := validForms(cardinal, tc.tag)
if !reflect.DeepEqual(got, tc.want) {
t.Errorf("validForms(%v): got %v; want %v", tc.tag, got, tc.want)
}
}
}
func TestOrdinal(t *testing.T) {
testPlurals(t, Ordinal, ordinalTests)
}
func TestCardinal(t *testing.T) {
testPlurals(t, Cardinal, cardinalTests)
}
func testPlurals(t *testing.T, p *Rules, testCases []pluralTest) {
for _, tc := range testCases {
for _, loc := range strings.Split(tc.locales, " ") {
tag := language.MustParse(loc)
// Test integers
for _, s := range tc.integer {
a := strings.Split(s, "~")
from := parseUint(t, a[0])
to := from
if len(a) > 1 {
to = parseUint(t, a[1])
}
for n := from; n <= to; n++ {
t.Run(fmt.Sprintf("%s/int(%d)", loc, n), func(t *testing.T) {
if f := p.matchComponents(tag, n, 0, 0); f != Form(tc.form) {
t.Errorf("matchComponents: got %v; want %v", f, Form(tc.form))
}
digits := []byte(fmt.Sprint(n))
for i := range digits {
digits[i] -= '0'
}
if f := p.MatchDigits(tag, digits, 0, 0); f != Form(tc.form) {
t.Errorf("MatchDigits: got %v; want %v", f, Form(tc.form))
}
})
}
}
// Test decimals
for _, s := range tc.decimal {
a := strings.Split(s, "~")
from, scale := parseFixedPoint(t, a[0])
to := from
if len(a) > 1 {
var toScale int
if to, toScale = parseFixedPoint(t, a[1]); toScale != scale {
t.Fatalf("%s:%s: non-matching scales %d versus %d", loc, s, scale, toScale)
}
}
m := 1
for i := 0; i < scale; i++ {
m *= 10
}
for n := from; n <= to; n++ {
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 != Form(tc.form) {
t.Errorf("matchComponents: got %v; want %v", f, Form(tc.form))
}
digits := []byte(strings.Replace(num, ".", "", 1))
for i := range digits {
digits[i] -= '0'
}
if f := p.MatchDigits(tag, digits, -scale, scale); f != Form(tc.form) {
t.Errorf("MatchDigits: got %v; want %v", f, Form(tc.form))
}
})
}
}
}
}
}
func parseUint(t *testing.T, s string) int {
val, err := strconv.ParseUint(s, 10, 32)
if err != nil {
t.Fatal(err)
}
return int(val)
}
func parseFixedPoint(t *testing.T, s string) (val, scale int) {
p := strings.Index(s, ".")
s = strings.Replace(s, ".", "", 1)
v, err := strconv.ParseUint(s, 10, 32)
if err != nil {
t.Fatal(err)
}
return int(v), len(s) - p
}
func BenchmarkPluralSimpleCases(b *testing.B) {
p := Cardinal
en, _ := language.CompactIndex(language.English)
zh, _ := language.CompactIndex(language.Chinese)
for i := 0; i < b.N; i++ {
matchPlural(p, en, 0, 0, 0) // 0
matchPlural(p, en, 1, 0, 0) // 1
matchPlural(p, en, 2, 12, 3) // 2.120
matchPlural(p, zh, 0, 0, 0) // 0
matchPlural(p, zh, 1, 0, 0) // 1
matchPlural(p, zh, 2, 12, 3) // 2.120
}
}
func BenchmarkPluralComplexCases(b *testing.B) {
p := Cardinal
ar, _ := language.CompactIndex(language.Arabic)
lv, _ := language.CompactIndex(language.Latvian)
for i := 0; i < b.N; i++ {
matchPlural(p, lv, 0, 19, 2) // 0.19
matchPlural(p, lv, 11, 0, 3) // 11.000
matchPlural(p, lv, 100, 123, 4) // 0.1230
matchPlural(p, ar, 0, 0, 0) // 0
matchPlural(p, ar, 110, 0, 0) // 110
matchPlural(p, ar, 99, 99, 2) // 99.99
}
}
+541
View File
@@ -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