From 621e49bb465f500cc46d47e39e828cf76d6381d7 Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Tue, 24 Jul 2018 14:35:44 +0200 Subject: update vendor --- vendor/golang.org/x/text/internal/number/common.go | 51 + .../golang.org/x/text/internal/number/decimal.go | 498 ++++++++ .../x/text/internal/number/decimal_test.go | 329 ++++++ vendor/golang.org/x/text/internal/number/format.go | 540 +++++++++ .../x/text/internal/number/format_test.go | 522 +++++++++ vendor/golang.org/x/text/internal/number/gen.go | 458 ++++++++ .../x/text/internal/number/gen_common.go | 55 + vendor/golang.org/x/text/internal/number/number.go | 156 +++ .../x/text/internal/number/number_test.go | 104 ++ .../golang.org/x/text/internal/number/pattern.go | 485 ++++++++ .../x/text/internal/number/pattern_test.go | 438 +++++++ .../x/text/internal/number/roundingmode_string.go | 16 + vendor/golang.org/x/text/internal/number/tables.go | 1211 ++++++++++++++++++++ .../x/text/internal/number/tables_test.go | 125 ++ 14 files changed, 4988 insertions(+) create mode 100644 vendor/golang.org/x/text/internal/number/common.go create mode 100644 vendor/golang.org/x/text/internal/number/decimal.go create mode 100644 vendor/golang.org/x/text/internal/number/decimal_test.go create mode 100644 vendor/golang.org/x/text/internal/number/format.go create mode 100644 vendor/golang.org/x/text/internal/number/format_test.go create mode 100644 vendor/golang.org/x/text/internal/number/gen.go create mode 100644 vendor/golang.org/x/text/internal/number/gen_common.go create mode 100644 vendor/golang.org/x/text/internal/number/number.go create mode 100644 vendor/golang.org/x/text/internal/number/number_test.go create mode 100644 vendor/golang.org/x/text/internal/number/pattern.go create mode 100644 vendor/golang.org/x/text/internal/number/pattern_test.go create mode 100644 vendor/golang.org/x/text/internal/number/roundingmode_string.go create mode 100644 vendor/golang.org/x/text/internal/number/tables.go create mode 100644 vendor/golang.org/x/text/internal/number/tables_test.go (limited to 'vendor/golang.org/x/text/internal/number') diff --git a/vendor/golang.org/x/text/internal/number/common.go b/vendor/golang.org/x/text/internal/number/common.go new file mode 100644 index 0000000..052876e --- /dev/null +++ b/vendor/golang.org/x/text/internal/number/common.go @@ -0,0 +1,51 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +package number + +import "unicode/utf8" + +// A system identifies a CLDR numbering system. +type system byte + +type systemData struct { + id system + digitSize byte // number of UTF-8 bytes per digit + zero [utf8.UTFMax]byte // UTF-8 sequence of zero digit. +} + +// A SymbolType identifies a symbol of a specific kind. +type SymbolType int + +const ( + SymDecimal SymbolType = iota + SymGroup + SymList + SymPercentSign + SymPlusSign + SymMinusSign + SymExponential + SymSuperscriptingExponent + SymPerMille + SymInfinity + SymNan + SymTimeSeparator + + NumSymbolTypes +) + +const hasNonLatnMask = 0x8000 + +// symOffset is an offset into altSymData if the bit indicated by hasNonLatnMask +// is not 0 (with this bit masked out), and an offset into symIndex otherwise. +// +// TODO: this type can be a byte again if we use an indirection into altsymData +// and introduce an alt -> offset slice (the length of this will be number of +// alternatives plus 1). This also allows getting rid of the compactTag field +// in altSymData. In total this will save about 1K. +type symOffset uint16 + +type altSymData struct { + compactTag uint16 + symIndex symOffset + system system +} diff --git a/vendor/golang.org/x/text/internal/number/decimal.go b/vendor/golang.org/x/text/internal/number/decimal.go new file mode 100644 index 0000000..9b4035e --- /dev/null +++ b/vendor/golang.org/x/text/internal/number/decimal.go @@ -0,0 +1,498 @@ +// Copyright 2017 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 stringer -type RoundingMode + +package number + +import ( + "math" + "strconv" +) + +// RoundingMode determines how a number is rounded to the desired precision. +type RoundingMode byte + +const ( + ToNearestEven RoundingMode = iota // towards the nearest integer, or towards an even number if equidistant. + ToNearestZero // towards the nearest integer, or towards zero if equidistant. + ToNearestAway // towards the nearest integer, or away from zero if equidistant. + ToPositiveInf // towards infinity + ToNegativeInf // towards negative infinity + ToZero // towards zero + AwayFromZero // away from zero + numModes +) + +const maxIntDigits = 20 + +// A Decimal represents a floating point number in decimal format. +// Digits represents a number [0, 1.0), and the absolute value represented by +// Decimal is Digits * 10^Exp. Leading and trailing zeros may be omitted and Exp +// may point outside a valid position in Digits. +// +// Examples: +// Number Decimal +// 12345 Digits: [1, 2, 3, 4, 5], Exp: 5 +// 12.345 Digits: [1, 2, 3, 4, 5], Exp: 2 +// 12000 Digits: [1, 2], Exp: 5 +// 12000.00 Digits: [1, 2], Exp: 5 +// 0.00123 Digits: [1, 2, 3], Exp: -2 +// 0 Digits: [], Exp: 0 +type Decimal struct { + digits + + buf [maxIntDigits]byte +} + +type digits struct { + Digits []byte // mantissa digits, big-endian + Exp int32 // exponent + Neg bool + Inf bool // Takes precedence over Digits and Exp. + NaN bool // Takes precedence over Inf. +} + +// Digits represents a floating point number represented in digits of the +// base in which a number is to be displayed. It is similar to Decimal, but +// keeps track of trailing fraction zeros and the comma placement for +// engineering notation. Digits must have at least one digit. +// +// Examples: +// Number Decimal +// decimal +// 12345 Digits: [1, 2, 3, 4, 5], Exp: 5 End: 5 +// 12.345 Digits: [1, 2, 3, 4, 5], Exp: 2 End: 5 +// 12000 Digits: [1, 2], Exp: 5 End: 5 +// 12000.00 Digits: [1, 2], Exp: 5 End: 7 +// 0.00123 Digits: [1, 2, 3], Exp: -2 End: 3 +// 0 Digits: [], Exp: 0 End: 1 +// scientific (actual exp is Exp - Comma) +// 0e0 Digits: [0], Exp: 1, End: 1, Comma: 1 +// .0e0 Digits: [0], Exp: 0, End: 1, Comma: 0 +// 0.0e0 Digits: [0], Exp: 1, End: 2, Comma: 1 +// 1.23e4 Digits: [1, 2, 3], Exp: 5, End: 3, Comma: 1 +// .123e5 Digits: [1, 2, 3], Exp: 5, End: 3, Comma: 0 +// engineering +// 12.3e3 Digits: [1, 2, 3], Exp: 5, End: 3, Comma: 2 +type Digits struct { + digits + // End indicates the end position of the number. + End int32 // For decimals Exp <= End. For scientific len(Digits) <= End. + // Comma is used for the comma position for scientific (always 0 or 1) and + // engineering notation (always 0, 1, 2, or 3). + Comma uint8 + // IsScientific indicates whether this number is to be rendered as a + // scientific number. + IsScientific bool +} + +func (d *Digits) NumFracDigits() int { + if d.Exp >= d.End { + return 0 + } + return int(d.End - d.Exp) +} + +// normalize returns a new Decimal with leading and trailing zeros removed. +func (d *Decimal) normalize() (n Decimal) { + n = *d + b := n.Digits + // Strip leading zeros. Resulting number of digits is significant digits. + for len(b) > 0 && b[0] == 0 { + b = b[1:] + n.Exp-- + } + // Strip trailing zeros + for len(b) > 0 && b[len(b)-1] == 0 { + b = b[:len(b)-1] + } + if len(b) == 0 { + n.Exp = 0 + } + n.Digits = b + return n +} + +func (d *Decimal) clear() { + b := d.Digits + if b == nil { + b = d.buf[:0] + } + *d = Decimal{} + d.Digits = b[:0] +} + +func (x *Decimal) String() string { + if x.NaN { + return "NaN" + } + var buf []byte + if x.Neg { + buf = append(buf, '-') + } + if x.Inf { + buf = append(buf, "Inf"...) + return string(buf) + } + switch { + case len(x.Digits) == 0: + buf = append(buf, '0') + case x.Exp <= 0: + // 0.00ddd + buf = append(buf, "0."...) + buf = appendZeros(buf, -int(x.Exp)) + buf = appendDigits(buf, x.Digits) + + case /* 0 < */ int(x.Exp) < len(x.Digits): + // dd.ddd + buf = appendDigits(buf, x.Digits[:x.Exp]) + buf = append(buf, '.') + buf = appendDigits(buf, x.Digits[x.Exp:]) + + default: // len(x.Digits) <= x.Exp + // ddd00 + buf = appendDigits(buf, x.Digits) + buf = appendZeros(buf, int(x.Exp)-len(x.Digits)) + } + return string(buf) +} + +func appendDigits(buf []byte, digits []byte) []byte { + for _, c := range digits { + buf = append(buf, c+'0') + } + return buf +} + +// appendZeros appends n 0 digits to buf and returns buf. +func appendZeros(buf []byte, n int) []byte { + for ; n > 0; n-- { + buf = append(buf, '0') + } + return buf +} + +func (d *digits) round(mode RoundingMode, n int) { + if n >= len(d.Digits) { + return + } + // Make rounding decision: The result mantissa is truncated ("rounded down") + // by default. Decide if we need to increment, or "round up", the (unsigned) + // mantissa. + inc := false + switch mode { + case ToNegativeInf: + inc = d.Neg + case ToPositiveInf: + inc = !d.Neg + case ToZero: + // nothing to do + case AwayFromZero: + inc = true + case ToNearestEven: + inc = d.Digits[n] > 5 || d.Digits[n] == 5 && + (len(d.Digits) > n+1 || n == 0 || d.Digits[n-1]&1 != 0) + case ToNearestAway: + inc = d.Digits[n] >= 5 + case ToNearestZero: + inc = d.Digits[n] > 5 || d.Digits[n] == 5 && len(d.Digits) > n+1 + default: + panic("unreachable") + } + if inc { + d.roundUp(n) + } else { + d.roundDown(n) + } +} + +// roundFloat rounds a floating point number. +func (r RoundingMode) roundFloat(x float64) float64 { + // Make rounding decision: The result mantissa is truncated ("rounded down") + // by default. Decide if we need to increment, or "round up", the (unsigned) + // mantissa. + abs := x + if x < 0 { + abs = -x + } + i, f := math.Modf(abs) + if f == 0.0 { + return x + } + inc := false + switch r { + case ToNegativeInf: + inc = x < 0 + case ToPositiveInf: + inc = x >= 0 + case ToZero: + // nothing to do + case AwayFromZero: + inc = true + case ToNearestEven: + // TODO: check overflow + inc = f > 0.5 || f == 0.5 && int64(i)&1 != 0 + case ToNearestAway: + inc = f >= 0.5 + case ToNearestZero: + inc = f > 0.5 + default: + panic("unreachable") + } + if inc { + i += 1 + } + if abs != x { + i = -i + } + return i +} + +func (x *digits) roundUp(n int) { + if n < 0 || n >= len(x.Digits) { + return // nothing to do + } + // find first digit < 9 + for n > 0 && x.Digits[n-1] >= 9 { + n-- + } + + if n == 0 { + // all digits are 9s => round up to 1 and update exponent + x.Digits[0] = 1 // ok since len(x.Digits) > n + x.Digits = x.Digits[:1] + x.Exp++ + return + } + x.Digits[n-1]++ + x.Digits = x.Digits[:n] + // x already trimmed +} + +func (x *digits) roundDown(n int) { + if n < 0 || n >= len(x.Digits) { + return // nothing to do + } + x.Digits = x.Digits[:n] + trim(x) +} + +// trim cuts off any trailing zeros from x's mantissa; +// they are meaningless for the value of x. +func trim(x *digits) { + i := len(x.Digits) + for i > 0 && x.Digits[i-1] == 0 { + i-- + } + x.Digits = x.Digits[:i] + if i == 0 { + x.Exp = 0 + } +} + +// A Converter converts a number into decimals according to the given rounding +// criteria. +type Converter interface { + Convert(d *Decimal, r RoundingContext) +} + +const ( + signed = true + unsigned = false +) + +// Convert converts the given number to the decimal representation using the +// supplied RoundingContext. +func (d *Decimal) Convert(r RoundingContext, number interface{}) { + switch f := number.(type) { + case Converter: + d.clear() + f.Convert(d, r) + case float32: + d.ConvertFloat(r, float64(f), 32) + case float64: + d.ConvertFloat(r, f, 64) + case int: + d.ConvertInt(r, signed, uint64(f)) + case int8: + d.ConvertInt(r, signed, uint64(f)) + case int16: + d.ConvertInt(r, signed, uint64(f)) + case int32: + d.ConvertInt(r, signed, uint64(f)) + case int64: + d.ConvertInt(r, signed, uint64(f)) + case uint: + d.ConvertInt(r, unsigned, uint64(f)) + case uint8: + d.ConvertInt(r, unsigned, uint64(f)) + case uint16: + d.ConvertInt(r, unsigned, uint64(f)) + case uint32: + d.ConvertInt(r, unsigned, uint64(f)) + case uint64: + d.ConvertInt(r, unsigned, f) + + default: + d.NaN = true + // TODO: + // case string: if produced by strconv, allows for easy arbitrary pos. + // case reflect.Value: + // case big.Float + // case big.Int + // case big.Rat? + // catch underlyings using reflect or will this already be done by the + // message package? + } +} + +// ConvertInt converts an integer to decimals. +func (d *Decimal) ConvertInt(r RoundingContext, signed bool, x uint64) { + if r.Increment > 0 { + // TODO: if uint64 is too large, fall back to float64 + if signed { + d.ConvertFloat(r, float64(int64(x)), 64) + } else { + d.ConvertFloat(r, float64(x), 64) + } + return + } + d.clear() + if signed && int64(x) < 0 { + x = uint64(-int64(x)) + d.Neg = true + } + d.fillIntDigits(x) + d.Exp = int32(len(d.Digits)) +} + +// ConvertFloat converts a floating point number to decimals. +func (d *Decimal) ConvertFloat(r RoundingContext, x float64, size int) { + d.clear() + if math.IsNaN(x) { + d.NaN = true + return + } + // Simple case: decimal notation + if r.Increment > 0 { + scale := int(r.IncrementScale) + mult := 1.0 + if scale > len(scales) { + mult = math.Pow(10, float64(scale)) + } else { + mult = scales[scale] + } + // We multiply x instead of dividing inc as it gives less rounding + // issues. + x *= mult + x /= float64(r.Increment) + x = r.Mode.roundFloat(x) + x *= float64(r.Increment) + x /= mult + } + + abs := x + if x < 0 { + d.Neg = true + abs = -x + } + if math.IsInf(abs, 1) { + d.Inf = true + return + } + + // By default we get the exact decimal representation. + verb := byte('g') + prec := -1 + // As the strconv API does not return the rounding accuracy, we can only + // round using ToNearestEven. + if r.Mode == ToNearestEven { + if n := r.RoundSignificantDigits(); n >= 0 { + prec = n + } else if n = r.RoundFractionDigits(); n >= 0 { + prec = n + verb = 'f' + } + } else { + // TODO: At this point strconv's rounding is imprecise to the point that + // it is not useable for this purpose. + // See https://github.com/golang/go/issues/21714 + // If rounding is requested, we ask for a large number of digits and + // round from there to simulate rounding only once. + // Ideally we would have strconv export an AppendDigits that would take + // a rounding mode and/or return an accuracy. Something like this would + // work: + // AppendDigits(dst []byte, x float64, base, size, prec int) (digits []byte, exp, accuracy int) + hasPrec := r.RoundSignificantDigits() >= 0 + hasScale := r.RoundFractionDigits() >= 0 + if hasPrec || hasScale { + // prec is the number of mantissa bits plus some extra for safety. + // We need at least the number of mantissa bits as decimals to + // accurately represent the floating point without rounding, as each + // bit requires one more decimal to represent: 0.5, 0.25, 0.125, ... + prec = 60 + } + } + + b := strconv.AppendFloat(d.Digits[:0], abs, verb, prec, size) + i := 0 + k := 0 + beforeDot := 1 + for i < len(b) { + if c := b[i]; '0' <= c && c <= '9' { + b[k] = c - '0' + k++ + d.Exp += int32(beforeDot) + } else if c == '.' { + beforeDot = 0 + d.Exp = int32(k) + } else { + break + } + i++ + } + d.Digits = b[:k] + if i != len(b) { + i += len("e") + pSign := i + exp := 0 + for i++; i < len(b); i++ { + exp *= 10 + exp += int(b[i] - '0') + } + if b[pSign] == '-' { + exp = -exp + } + d.Exp = int32(exp) + 1 + } +} + +func (d *Decimal) fillIntDigits(x uint64) { + if cap(d.Digits) < maxIntDigits { + d.Digits = d.buf[:] + } else { + d.Digits = d.buf[:maxIntDigits] + } + i := 0 + for ; x > 0; x /= 10 { + d.Digits[i] = byte(x % 10) + i++ + } + d.Digits = d.Digits[:i] + for p := 0; p < i; p++ { + i-- + d.Digits[p], d.Digits[i] = d.Digits[i], d.Digits[p] + } +} + +var scales [70]float64 + +func init() { + x := 1.0 + for i := range scales { + scales[i] = x + x *= 10 + } +} diff --git a/vendor/golang.org/x/text/internal/number/decimal_test.go b/vendor/golang.org/x/text/internal/number/decimal_test.go new file mode 100644 index 0000000..97c7e25 --- /dev/null +++ b/vendor/golang.org/x/text/internal/number/decimal_test.go @@ -0,0 +1,329 @@ +// Copyright 2017 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 number + +import ( + "fmt" + "math" + "strconv" + "strings" + "testing" +) + +func mkfloat(num string) float64 { + u, _ := strconv.ParseUint(num, 10, 32) + return float64(u) +} + +// mkdec creates a decimal from a string. All ASCII digits are converted to +// digits in the decimal. The dot is used to indicate the scale by which the +// digits are shifted. Numbers may have an additional exponent or be the special +// value NaN, Inf, or -Inf. +func mkdec(num string) (d Decimal) { + var r RoundingContext + d.Convert(r, dec(num)) + return +} + +type dec string + +func (s dec) Convert(d *Decimal, _ RoundingContext) { + num := string(s) + if num[0] == '-' { + d.Neg = true + num = num[1:] + } + switch num { + case "NaN": + d.NaN = true + return + case "Inf": + d.Inf = true + return + } + if p := strings.IndexAny(num, "eE"); p != -1 { + i64, err := strconv.ParseInt(num[p+1:], 10, 32) + if err != nil { + panic(err) + } + d.Exp = int32(i64) + num = num[:p] + } + if p := strings.IndexByte(num, '.'); p != -1 { + d.Exp += int32(p) + num = num[:p] + num[p+1:] + } else { + d.Exp += int32(len(num)) + } + d.Digits = []byte(num) + for i := range d.Digits { + d.Digits[i] -= '0' + } + *d = d.normalize() +} + +func byteNum(s string) []byte { + b := make([]byte, len(s)) + for i := 0; i < len(s); i++ { + if c := s[i]; '0' <= c && c <= '9' { + b[i] = s[i] - '0' + } else { + b[i] = s[i] - 'a' + 10 + } + } + return b +} + +func strNum(s string) string { + return string(byteNum(s)) +} + +func TestDecimalString(t *testing.T) { + for _, test := range []struct { + x Decimal + want string + }{ + {want: "0"}, + {Decimal{digits: digits{Digits: nil, Exp: 1000}}, "0"}, // exponent of 1000 is ignored + {Decimal{digits: digits{Digits: byteNum("12345"), Exp: 0}}, "0.12345"}, + {Decimal{digits: digits{Digits: byteNum("12345"), Exp: -3}}, "0.00012345"}, + {Decimal{digits: digits{Digits: byteNum("12345"), Exp: +3}}, "123.45"}, + {Decimal{digits: digits{Digits: byteNum("12345"), Exp: +10}}, "1234500000"}, + } { + if got := test.x.String(); got != test.want { + t.Errorf("%v == %q; want %q", test.x, got, test.want) + } + } +} + +func TestRounding(t *testing.T) { + testCases := []struct { + x string + n int + // modes is the result for modes. Signs are left out of the result. + // The results are stored in the following order: + // zero, negInf + // nearZero, nearEven, nearAway + // away, posInf + modes [numModes]string + }{ + {"0", 1, [numModes]string{ + "0", "0", + "0", "0", "0", + "0", "0"}}, + {"1", 1, [numModes]string{ + "1", "1", + "1", "1", "1", + "1", "1"}}, + {"5", 1, [numModes]string{ + "5", "5", + "5", "5", "5", + "5", "5"}}, + {"15", 1, [numModes]string{ + "10", "10", + "10", "20", "20", + "20", "20"}}, + {"45", 1, [numModes]string{ + "40", "40", + "40", "40", "50", + "50", "50"}}, + {"95", 1, [numModes]string{ + "90", "90", + "90", "100", "100", + "100", "100"}}, + + {"12344999", 4, [numModes]string{ + "12340000", "12340000", + "12340000", "12340000", "12340000", + "12350000", "12350000"}}, + {"12345000", 4, [numModes]string{ + "12340000", "12340000", + "12340000", "12340000", "12350000", + "12350000", "12350000"}}, + {"12345001", 4, [numModes]string{ + "12340000", "12340000", + "12350000", "12350000", "12350000", + "12350000", "12350000"}}, + {"12345100", 4, [numModes]string{ + "12340000", "12340000", + "12350000", "12350000", "12350000", + "12350000", "12350000"}}, + {"23454999", 4, [numModes]string{ + "23450000", "23450000", + "23450000", "23450000", "23450000", + "23460000", "23460000"}}, + {"23455000", 4, [numModes]string{ + "23450000", "23450000", + "23450000", "23460000", "23460000", + "23460000", "23460000"}}, + {"23455001", 4, [numModes]string{ + "23450000", "23450000", + "23460000", "23460000", "23460000", + "23460000", "23460000"}}, + {"23455100", 4, [numModes]string{ + "23450000", "23450000", + "23460000", "23460000", "23460000", + "23460000", "23460000"}}, + + {"99994999", 4, [numModes]string{ + "99990000", "99990000", + "99990000", "99990000", "99990000", + "100000000", "100000000"}}, + {"99995000", 4, [numModes]string{ + "99990000", "99990000", + "99990000", "100000000", "100000000", + "100000000", "100000000"}}, + {"99999999", 4, [numModes]string{ + "99990000", "99990000", + "100000000", "100000000", "100000000", + "100000000", "100000000"}}, + + {"12994999", 4, [numModes]string{ + "12990000", "12990000", + "12990000", "12990000", "12990000", + "13000000", "13000000"}}, + {"12995000", 4, [numModes]string{ + "12990000", "12990000", + "12990000", "13000000", "13000000", + "13000000", "13000000"}}, + {"12999999", 4, [numModes]string{ + "12990000", "12990000", + "13000000", "13000000", "13000000", + "13000000", "13000000"}}, + } + modes := []RoundingMode{ + ToZero, ToNegativeInf, + ToNearestZero, ToNearestEven, ToNearestAway, + AwayFromZero, ToPositiveInf, + } + for _, tc := range testCases { + // Create negative counterpart tests: the sign is reversed and + // ToPositiveInf and ToNegativeInf swapped. + negModes := tc.modes + negModes[1], negModes[6] = negModes[6], negModes[1] + for i, res := range negModes { + negModes[i] = "-" + res + } + for i, m := range modes { + t.Run(fmt.Sprintf("x:%s/n:%d/%s", tc.x, tc.n, m), func(t *testing.T) { + d := mkdec(tc.x) + d.round(m, tc.n) + if got := d.String(); got != tc.modes[i] { + t.Errorf("pos decimal: got %q; want %q", d.String(), tc.modes[i]) + } + + mult := math.Pow(10, float64(len(tc.x)-tc.n)) + f := mkfloat(tc.x) + f = m.roundFloat(f/mult) * mult + if got := fmt.Sprintf("%.0f", f); got != tc.modes[i] { + t.Errorf("pos float: got %q; want %q", got, tc.modes[i]) + } + + // Test the negative case. This is the same as the positive + // case, but with ToPositiveInf and ToNegativeInf swapped. + d = mkdec(tc.x) + d.Neg = true + d.round(m, tc.n) + if got, want := d.String(), negModes[i]; got != want { + t.Errorf("neg decimal: got %q; want %q", d.String(), want) + } + + f = -mkfloat(tc.x) + f = m.roundFloat(f/mult) * mult + if got := fmt.Sprintf("%.0f", f); got != negModes[i] { + t.Errorf("neg float: got %q; want %q", got, negModes[i]) + } + }) + } + } +} + +func TestConvert(t *testing.T) { + scale2 := RoundingContext{} + scale2.SetScale(2) + scale2away := RoundingContext{Mode: AwayFromZero} + scale2away.SetScale(2) + inc0_05 := RoundingContext{Increment: 5, IncrementScale: 2} + inc0_05.SetScale(2) + inc50 := RoundingContext{Increment: 50} + prec3 := RoundingContext{} + prec3.SetPrecision(3) + roundShift := RoundingContext{DigitShift: 2, MaxFractionDigits: 2} + testCases := []struct { + x interface{} + rc RoundingContext + out string + }{ + {-0.001, scale2, "-0.00"}, + {0.1234, prec3, "0.123"}, + {1234.0, prec3, "1230"}, + {1.2345e10, prec3, "12300000000"}, + + {int8(-34), scale2, "-34"}, + {int16(-234), scale2, "-234"}, + {int32(-234), scale2, "-234"}, + {int64(-234), scale2, "-234"}, + {int(-234), scale2, "-234"}, + {uint8(234), scale2, "234"}, + {uint16(234), scale2, "234"}, + {uint32(234), scale2, "234"}, + {uint64(234), scale2, "234"}, + {uint(234), scale2, "234"}, + {-1e9, scale2, "-1000000000.00"}, + // The following two causes this result to have a lot of digits: + // 1) 0.234 cannot be accurately represented as a float64, and + // 2) as strconv does not support the rounding AwayFromZero, Convert + // leaves the rounding to caller. + {0.234, scale2away, + "0.2340000000000000135447209004269097931683063507080078125"}, + + {0.0249, inc0_05, "0.00"}, + {0.025, inc0_05, "0.00"}, + {0.0251, inc0_05, "0.05"}, + {0.03, inc0_05, "0.05"}, + {0.049, inc0_05, "0.05"}, + {0.05, inc0_05, "0.05"}, + {0.051, inc0_05, "0.05"}, + {0.0749, inc0_05, "0.05"}, + {0.075, inc0_05, "0.10"}, + {0.0751, inc0_05, "0.10"}, + {324, inc50, "300"}, + {325, inc50, "300"}, + {326, inc50, "350"}, + {349, inc50, "350"}, + {350, inc50, "350"}, + {351, inc50, "350"}, + {374, inc50, "350"}, + {375, inc50, "400"}, + {376, inc50, "400"}, + + // Here the scale is 2, but the digits get shifted left. As we use + // AppendFloat to do the rounding an exta 0 gets added. + {0.123, roundShift, "0.1230"}, + + {converter(3), scale2, "100"}, + + {math.Inf(1), inc50, "Inf"}, + {math.Inf(-1), inc50, "-Inf"}, + {math.NaN(), inc50, "NaN"}, + {"clearly not a number", scale2, "NaN"}, + } + for _, tc := range testCases { + var d Decimal + t.Run(fmt.Sprintf("%T:%v-%v", tc.x, tc.x, tc.rc), func(t *testing.T) { + d.Convert(tc.rc, tc.x) + if got := d.String(); got != tc.out { + t.Errorf("got %q; want %q", got, tc.out) + } + }) + } +} + +type converter int + +func (c converter) Convert(d *Decimal, r RoundingContext) { + d.Digits = append(d.Digits, 1, 0, 0) + d.Exp = 3 +} diff --git a/vendor/golang.org/x/text/internal/number/format.go b/vendor/golang.org/x/text/internal/number/format.go new file mode 100644 index 0000000..910bdeb --- /dev/null +++ b/vendor/golang.org/x/text/internal/number/format.go @@ -0,0 +1,540 @@ +// Copyright 2017 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 number + +import ( + "strconv" + "unicode/utf8" + + "golang.org/x/text/language" +) + +// TODO: +// - grouping of fractions +// - allow user-defined superscript notation (such as 4) +// - same for non-breaking spaces, like   + +// A VisibleDigits computes digits, comma placement and trailing zeros as they +// will be shown to the user. +type VisibleDigits interface { + Digits(buf []byte, t language.Tag, scale int) Digits + // TODO: Do we also need to add the verb or pass a format.State? +} + +// Formatting proceeds along the following lines: +// 0) Compose rounding information from format and context. +// 1) Convert a number into a Decimal. +// 2) Sanitize Decimal by adding trailing zeros, removing leading digits, and +// (non-increment) rounding. The Decimal that results from this is suitable +// for determining the plural form. +// 3) Render the Decimal in the localized form. + +// Formatter contains all the information needed to render a number. +type Formatter struct { + Pattern + Info +} + +func (f *Formatter) init(t language.Tag, index []uint8) { + f.Info = InfoFromTag(t) + for ; ; t = t.Parent() { + if ci, ok := language.CompactIndex(t); ok { + f.Pattern = formats[index[ci]] + break + } + } +} + +// InitPattern initializes a Formatter for the given Pattern. +func (f *Formatter) InitPattern(t language.Tag, pat *Pattern) { + f.Info = InfoFromTag(t) + f.Pattern = *pat +} + +// InitDecimal initializes a Formatter using the default Pattern for the given +// language. +func (f *Formatter) InitDecimal(t language.Tag) { + f.init(t, tagToDecimal) +} + +// InitScientific initializes a Formatter using the default Pattern for the +// given language. +func (f *Formatter) InitScientific(t language.Tag) { + f.init(t, tagToScientific) + f.Pattern.MinFractionDigits = 0 + f.Pattern.MaxFractionDigits = -1 +} + +// InitEngineering initializes a Formatter using the default Pattern for the +// given language. +func (f *Formatter) InitEngineering(t language.Tag) { + f.init(t, tagToScientific) + f.Pattern.MinFractionDigits = 0 + f.Pattern.MaxFractionDigits = -1 + f.Pattern.MaxIntegerDigits = 3 + f.Pattern.MinIntegerDigits = 1 +} + +// InitPercent initializes a Formatter using the default Pattern for the given +// language. +func (f *Formatter) InitPercent(t language.Tag) { + f.init(t, tagToPercent) +} + +// InitPerMille initializes a Formatter using the default Pattern for the given +// language. +func (f *Formatter) InitPerMille(t language.Tag) { + f.init(t, tagToPercent) + f.Pattern.DigitShift = 3 +} + +func (f *Formatter) Append(dst []byte, x interface{}) []byte { + var d Decimal + r := f.RoundingContext + d.Convert(r, x) + return f.Render(dst, FormatDigits(&d, r)) +} + +func FormatDigits(d *Decimal, r RoundingContext) Digits { + if r.isScientific() { + return scientificVisibleDigits(r, d) + } + return decimalVisibleDigits(r, d) +} + +func (f *Formatter) Format(dst []byte, d *Decimal) []byte { + return f.Render(dst, FormatDigits(d, f.RoundingContext)) +} + +func (f *Formatter) Render(dst []byte, d Digits) []byte { + var result []byte + var postPrefix, preSuffix int + if d.IsScientific { + result, postPrefix, preSuffix = appendScientific(dst, f, &d) + } else { + result, postPrefix, preSuffix = appendDecimal(dst, f, &d) + } + if f.PadRune == 0 { + return result + } + width := int(f.FormatWidth) + if count := utf8.RuneCount(result); count < width { + insertPos := 0 + switch f.Flags & PadMask { + case PadAfterPrefix: + insertPos = postPrefix + case PadBeforeSuffix: + insertPos = preSuffix + case PadAfterSuffix: + insertPos = len(result) + } + num := width - count + pad := [utf8.UTFMax]byte{' '} + sz := 1 + if r := f.PadRune; r != 0 { + sz = utf8.EncodeRune(pad[:], r) + } + extra := sz * num + if n := len(result) + extra; n < cap(result) { + result = result[:n] + copy(result[insertPos+extra:], result[insertPos:]) + } else { + buf := make([]byte, n) + copy(buf, result[:insertPos]) + copy(buf[insertPos+extra:], result[insertPos:]) + result = buf + } + for ; num > 0; num-- { + insertPos += copy(result[insertPos:], pad[:sz]) + } + } + return result +} + +// decimalVisibleDigits converts d according to the RoundingContext. Note that +// the exponent may change as a result of this operation. +func decimalVisibleDigits(r RoundingContext, d *Decimal) Digits { + if d.NaN || d.Inf { + return Digits{digits: digits{Neg: d.Neg, NaN: d.NaN, Inf: d.Inf}} + } + n := Digits{digits: d.normalize().digits} + + exp := n.Exp + exp += int32(r.DigitShift) + + // Cap integer digits. Remove *most-significant* digits. + if r.MaxIntegerDigits > 0 { + if p := int(exp) - int(r.MaxIntegerDigits); p > 0 { + if p > len(n.Digits) { + p = len(n.Digits) + } + if n.Digits = n.Digits[p:]; len(n.Digits) == 0 { + exp = 0 + } else { + exp -= int32(p) + } + // Strip leading zeros. + for len(n.Digits) > 0 && n.Digits[0] == 0 { + n.Digits = n.Digits[1:] + exp-- + } + } + } + + // Rounding if not already done by Convert. + p := len(n.Digits) + if maxSig := int(r.MaxSignificantDigits); maxSig > 0 { + p = maxSig + } + if maxFrac := int(r.MaxFractionDigits); maxFrac >= 0 { + if cap := int(exp) + maxFrac; cap < p { + p = int(exp) + maxFrac + } + if p < 0 { + p = 0 + } + } + n.round(r.Mode, p) + + // set End (trailing zeros) + n.End = int32(len(n.Digits)) + if n.End == 0 { + exp = 0 + if r.MinFractionDigits > 0 { + n.End = int32(r.MinFractionDigits) + } + if p := int32(r.MinSignificantDigits) - 1; p > n.End { + n.End = p + } + } else { + if end := exp + int32(r.MinFractionDigits); end > n.End { + n.End = end + } + if n.End < int32(r.MinSignificantDigits) { + n.End = int32(r.MinSignificantDigits) + } + } + n.Exp = exp + return n +} + +// appendDecimal appends a formatted number to dst. It returns two possible +// insertion points for padding. +func appendDecimal(dst []byte, f *Formatter, n *Digits) (b []byte, postPre, preSuf int) { + if dst, ok := f.renderSpecial(dst, n); ok { + return dst, 0, len(dst) + } + digits := n.Digits + exp := n.Exp + + // Split in integer and fraction part. + var intDigits, fracDigits []byte + numInt := 0 + numFrac := int(n.End - n.Exp) + if exp > 0 { + numInt = int(exp) + if int(exp) >= len(digits) { // ddddd | ddddd00 + intDigits = digits + } else { // ddd.dd + intDigits = digits[:exp] + fracDigits = digits[exp:] + } + } else { + fracDigits = digits + } + + neg := n.Neg + affix, suffix := f.getAffixes(neg) + dst = appendAffix(dst, f, affix, neg) + savedLen := len(dst) + + minInt := int(f.MinIntegerDigits) + if minInt == 0 && f.MinSignificantDigits > 0 { + minInt = 1 + } + // add leading zeros + for i := minInt; i > numInt; i-- { + dst = f.AppendDigit(dst, 0) + if f.needsSep(i) { + dst = append(dst, f.Symbol(SymGroup)...) + } + } + i := 0 + for ; i < len(intDigits); i++ { + dst = f.AppendDigit(dst, intDigits[i]) + if f.needsSep(numInt - i) { + dst = append(dst, f.Symbol(SymGroup)...) + } + } + for ; i < numInt; i++ { + dst = f.AppendDigit(dst, 0) + if f.needsSep(numInt - i) { + dst = append(dst, f.Symbol(SymGroup)...) + } + } + + if numFrac > 0 || f.Flags&AlwaysDecimalSeparator != 0 { + dst = append(dst, f.Symbol(SymDecimal)...) + } + // Add trailing zeros + i = 0 + for n := -int(n.Exp); i < n; i++ { + dst = f.AppendDigit(dst, 0) + } + for _, d := range fracDigits { + i++ + dst = f.AppendDigit(dst, d) + } + for ; i < numFrac; i++ { + dst = f.AppendDigit(dst, 0) + } + return appendAffix(dst, f, suffix, neg), savedLen, len(dst) +} + +func scientificVisibleDigits(r RoundingContext, d *Decimal) Digits { + if d.NaN || d.Inf { + return Digits{digits: digits{Neg: d.Neg, NaN: d.NaN, Inf: d.Inf}} + } + n := Digits{digits: d.normalize().digits, IsScientific: true} + + // Normalize to have at least one digit. This simplifies engineering + // notation. + if len(n.Digits) == 0 { + n.Digits = append(n.Digits, 0) + n.Exp = 1 + } + + // Significant digits are transformed by the parser for scientific notation + // and do not need to be handled here. + maxInt, numInt := int(r.MaxIntegerDigits), int(r.MinIntegerDigits) + if numInt == 0 { + numInt = 1 + } + + // If a maximum number of integers is specified, the minimum must be 1 + // and the exponent is grouped by this number (e.g. for engineering) + if maxInt > numInt { + // Correct the exponent to reflect a single integer digit. + numInt = 1 + // engineering + // 0.01234 ([12345]e-1) -> 1.2345e-2 12.345e-3 + // 12345 ([12345]e+5) -> 1.2345e4 12.345e3 + d := int(n.Exp-1) % maxInt + if d < 0 { + d += maxInt + } + numInt += d + } + + p := len(n.Digits) + if maxSig := int(r.MaxSignificantDigits); maxSig > 0 { + p = maxSig + } + if maxFrac := int(r.MaxFractionDigits); maxFrac >= 0 && numInt+maxFrac < p { + p = numInt + maxFrac + } + n.round(r.Mode, p) + + n.Comma = uint8(numInt) + n.End = int32(len(n.Digits)) + if minSig := int32(r.MinFractionDigits) + int32(numInt); n.End < minSig { + n.End = minSig + } + return n +} + +// appendScientific appends a formatted number to dst. It returns two possible +// insertion points for padding. +func appendScientific(dst []byte, f *Formatter, n *Digits) (b []byte, postPre, preSuf int) { + if dst, ok := f.renderSpecial(dst, n); ok { + return dst, 0, 0 + } + digits := n.Digits + numInt := int(n.Comma) + numFrac := int(n.End) - int(n.Comma) + + var intDigits, fracDigits []byte + if numInt <= len(digits) { + intDigits = digits[:numInt] + fracDigits = digits[numInt:] + } else { + intDigits = digits + } + neg := n.Neg + affix, suffix := f.getAffixes(neg) + dst = appendAffix(dst, f, affix, neg) + savedLen := len(dst) + + i := 0 + for ; i < len(intDigits); i++ { + dst = f.AppendDigit(dst, intDigits[i]) + if f.needsSep(numInt - i) { + dst = append(dst, f.Symbol(SymGroup)...) + } + } + for ; i < numInt; i++ { + dst = f.AppendDigit(dst, 0) + if f.needsSep(numInt - i) { + dst = append(dst, f.Symbol(SymGroup)...) + } + } + + if numFrac > 0 || f.Flags&AlwaysDecimalSeparator != 0 { + dst = append(dst, f.Symbol(SymDecimal)...) + } + i = 0 + for ; i < len(fracDigits); i++ { + dst = f.AppendDigit(dst, fracDigits[i]) + } + for ; i < numFrac; i++ { + dst = f.AppendDigit(dst, 0) + } + + // exp + buf := [12]byte{} + // TODO: use exponential if superscripting is not available (no Latin + // numbers or no tags) and use exponential in all other cases. + exp := n.Exp - int32(n.Comma) + exponential := f.Symbol(SymExponential) + if exponential == "E" { + dst = append(dst, "\u202f"...) // NARROW NO-BREAK SPACE + dst = append(dst, f.Symbol(SymSuperscriptingExponent)...) + dst = append(dst, "\u202f"...) // NARROW NO-BREAK SPACE + dst = f.AppendDigit(dst, 1) + dst = f.AppendDigit(dst, 0) + switch { + case exp < 0: + dst = append(dst, superMinus...) + exp = -exp + case f.Flags&AlwaysExpSign != 0: + dst = append(dst, superPlus...) + } + b = strconv.AppendUint(buf[:0], uint64(exp), 10) + for i := len(b); i < int(f.MinExponentDigits); i++ { + dst = append(dst, superDigits[0]...) + } + for _, c := range b { + dst = append(dst, superDigits[c-'0']...) + } + } else { + dst = append(dst, exponential...) + switch { + case exp < 0: + dst = append(dst, f.Symbol(SymMinusSign)...) + exp = -exp + case f.Flags&AlwaysExpSign != 0: + dst = append(dst, f.Symbol(SymPlusSign)...) + } + b = strconv.AppendUint(buf[:0], uint64(exp), 10) + for i := len(b); i < int(f.MinExponentDigits); i++ { + dst = f.AppendDigit(dst, 0) + } + for _, c := range b { + dst = f.AppendDigit(dst, c-'0') + } + } + return appendAffix(dst, f, suffix, neg), savedLen, len(dst) +} + +const ( + superMinus = "\u207B" // SUPERSCRIPT HYPHEN-MINUS + superPlus = "\u207A" // SUPERSCRIPT PLUS SIGN +) + +var ( + // Note: the digits are not sequential!!! + superDigits = []string{ + "\u2070", // SUPERSCRIPT DIGIT ZERO + "\u00B9", // SUPERSCRIPT DIGIT ONE + "\u00B2", // SUPERSCRIPT DIGIT TWO + "\u00B3", // SUPERSCRIPT DIGIT THREE + "\u2074", // SUPERSCRIPT DIGIT FOUR + "\u2075", // SUPERSCRIPT DIGIT FIVE + "\u2076", // SUPERSCRIPT DIGIT SIX + "\u2077", // SUPERSCRIPT DIGIT SEVEN + "\u2078", // SUPERSCRIPT DIGIT EIGHT + "\u2079", // SUPERSCRIPT DIGIT NINE + } +) + +func (f *Formatter) getAffixes(neg bool) (affix, suffix string) { + str := f.Affix + if str != "" { + if f.NegOffset > 0 { + if neg { + str = str[f.NegOffset:] + } else { + str = str[:f.NegOffset] + } + } + sufStart := 1 + str[0] + affix = str[1:sufStart] + suffix = str[sufStart+1:] + } + // TODO: introduce a NeedNeg sign to indicate if the left pattern already + // has a sign marked? + if f.NegOffset == 0 && (neg || f.Flags&AlwaysSign != 0) { + affix = "-" + affix + } + return affix, suffix +} + +func (f *Formatter) renderSpecial(dst []byte, d *Digits) (b []byte, ok bool) { + if d.NaN { + return fmtNaN(dst, f), true + } + if d.Inf { + return fmtInfinite(dst, f, d), true + } + return dst, false +} + +func fmtNaN(dst []byte, f *Formatter) []byte { + return append(dst, f.Symbol(SymNan)...) +} + +func fmtInfinite(dst []byte, f *Formatter, d *Digits) []byte { + affix, suffix := f.getAffixes(d.Neg) + dst = appendAffix(dst, f, affix, d.Neg) + dst = append(dst, f.Symbol(SymInfinity)...) + dst = appendAffix(dst, f, suffix, d.Neg) + return dst +} + +func appendAffix(dst []byte, f *Formatter, affix string, neg bool) []byte { + quoting := false + escaping := false + for _, r := range affix { + switch { + case escaping: + // escaping occurs both inside and outside of quotes + dst = append(dst, string(r)...) + escaping = false + case r == '\\': + escaping = true + case r == '\'': + quoting = !quoting + case quoting: + dst = append(dst, string(r)...) + case r == '%': + if f.DigitShift == 3 { + dst = append(dst, f.Symbol(SymPerMille)...) + } else { + dst = append(dst, f.Symbol(SymPercentSign)...) + } + case r == '-' || r == '+': + if neg { + dst = append(dst, f.Symbol(SymMinusSign)...) + } else if f.Flags&ElideSign == 0 { + dst = append(dst, f.Symbol(SymPlusSign)...) + } else { + dst = append(dst, ' ') + } + default: + dst = append(dst, string(r)...) + } + } + return dst +} diff --git a/vendor/golang.org/x/text/internal/number/format_test.go b/vendor/golang.org/x/text/internal/number/format_test.go new file mode 100644 index 0000000..01a0894 --- /dev/null +++ b/vendor/golang.org/x/text/internal/number/format_test.go @@ -0,0 +1,522 @@ +// Copyright 2017 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 number + +import ( + "fmt" + "log" + "testing" + + "golang.org/x/text/language" +) + +func TestAppendDecimal(t *testing.T) { + type pairs map[string]string // alternates with decimal input and result + + testCases := []struct { + pattern string + // We want to be able to test some forms of patterns that cannot be + // represented as a string. + pat *Pattern + + test pairs + }{{ + pattern: "0", + test: pairs{ + "0": "0", + "1": "1", + "-1": "-1", + ".00": "0", + "10.": "10", + "12": "12", + "1.2": "1", + "NaN": "NaN", + "-Inf": "-∞", + }, + }, { + pattern: "+0;+0", + test: pairs{ + "0": "+0", + "1": "+1", + "-1": "-1", + ".00": "+0", + "10.": "+10", + "12": "+12", + "1.2": "+1", + "NaN": "NaN", + "-Inf": "-∞", + "Inf": "+∞", + }, + }, { + pattern: "0 +;0 +", + test: pairs{ + "0": "0 +", + "1": "1 +", + "-1": "1 -", + ".00": "0 +", + }, + }, { + pattern: "0;0-", + test: pairs{ + "-1": "1-", + "NaN": "NaN", + "-Inf": "∞-", + "Inf": "∞", + }, + }, { + pattern: "0000", + test: pairs{ + "0": "0000", + "1": "0001", + "12": "0012", + "12345": "12345", + }, + }, { + pattern: ".0", + test: pairs{ + "0": ".0", + "1": "1.0", + "1.2": "1.2", + "1.2345": "1.2", + }, + }, { + pattern: "#.0", + test: pairs{ + "0": ".0", + }, + }, { + pattern: "#.0#", + test: pairs{ + "0": ".0", + "1": "1.0", + }, + }, { + pattern: "0.0#", + test: pairs{ + "0": "0.0", + }, + }, { + pattern: "#0.###", + test: pairs{ + "0": "0", + "1": "1", + "1.2": "1.2", + "1.2345": "1.234", // rounding should have been done earlier + "1234.5": "1234.5", + "1234.567": "1234.567", + }, + }, { + pattern: "#0.######", + test: pairs{ + "0": "0", + "1234.5678": "1234.5678", + "0.123456789": "0.123457", + "NaN": "NaN", + "Inf": "∞", + }, + + // Test separators. + }, { + pattern: "#,#.00", + test: pairs{ + "100": "1,0,0.00", + }, + }, { + pattern: "#,0.##", + test: pairs{ + "10": "1,0", + }, + }, { + pattern: "#,0", + test: pairs{ + "10": "1,0", + }, + }, { + pattern: "#,##,#.00", + test: pairs{ + "1000": "1,00,0.00", + }, + }, { + pattern: "#,##0.###", + test: pairs{ + "0": "0", + "1234.5678": "1,234.568", + "0.123456789": "0.123", + }, + }, { + pattern: "#,##,##0.###", + test: pairs{ + "0": "0", + "123456789012": "1,23,45,67,89,012", + "0.123456789": "0.123", + }, + }, { + pattern: "0,00,000.###", + test: pairs{ + "0": "0,00,000", + "123456789012": "1,23,45,67,89,012", + "12.3456789": "0,00,012.346", + "0.123456789": "0,00,000.123", + }, + + // Support for ill-formed patterns. + }, { + pattern: "#", + test: pairs{ + ".00": "", // This is the behavior of fmt. + "0": "", // This is the behavior of fmt. + "1": "1", + "10.": "10", + }, + }, { + pattern: ".#", + test: pairs{ + "0": "", // This is the behavior of fmt. + "1": "1", + "1.2": "1.2", + "1.2345": "1.2", + }, + }, { + pattern: "#,#.##", + test: pairs{ + "10": "1,0", + }, + }, { + pattern: "#,#", + test: pairs{ + "10": "1,0", + }, + + // Special patterns + }, { + pattern: "#,max_int=2", + pat: &Pattern{ + RoundingContext: RoundingContext{ + MaxIntegerDigits: 2, + }, + }, + test: pairs{ + "2017": "17", + }, + }, { + pattern: "0,max_int=2", + pat: &Pattern{ + RoundingContext: RoundingContext{ + MaxIntegerDigits: 2, + MinIntegerDigits: 1, + }, + }, + test: pairs{ + "2000": "0", + "2001": "1", + "2017": "17", + }, + }, { + pattern: "00,max_int=2", + pat: &Pattern{ + RoundingContext: RoundingContext{ + MaxIntegerDigits: 2, + MinIntegerDigits: 2, + }, + }, + test: pairs{ + "2000": "00", + "2001": "01", + "2017": "17", + }, + }, { + pattern: "@@@@,max_int=2", + pat: &Pattern{ + RoundingContext: RoundingContext{ + MaxIntegerDigits: 2, + MinSignificantDigits: 4, + }, + }, + test: pairs{ + "2017": "17.00", + "2000": "0.000", + "2001": "1.000", + }, + + // Significant digits + }, { + pattern: "@@##", + test: pairs{ + "1": "1.0", + "0.1": "0.10", // leading zero does not count as significant digit + "123": "123", + "1234": "1234", + "12345": "12340", + }, + }, { + pattern: "@@@@", + test: pairs{ + "1": "1.000", + ".1": "0.1000", + ".001": "0.001000", + "123": "123.0", + "1234": "1234", + "12345": "12340", // rounding down + "NaN": "NaN", + "-Inf": "-∞", + }, + + // TODO: rounding + // {"@@@@": "23456": "23460"}, // rounding up + // TODO: padding + + // Scientific and Engineering notation + }, { + pattern: "#E0", + test: pairs{ + "0": "0\u202f×\u202f10⁰", + "1": "1\u202f×\u202f10⁰", + "123.456": "1\u202f×\u202f10²", + }, + }, { + pattern: "#E+0", + test: pairs{ + "0": "0\u202f×\u202f10⁺⁰", + "1000": "1\u202f×\u202f10⁺³", + "1E100": "1\u202f×\u202f10⁺¹⁰⁰", + "1E-100": "1\u202f×\u202f10⁻¹⁰⁰", + "NaN": "NaN", + "-Inf": "-∞", + }, + }, { + pattern: "##0E00", + test: pairs{ + "100": "100\u202f×\u202f10⁰⁰", + "12345": "12\u202f×\u202f10⁰³", + "123.456": "123\u202f×\u202f10⁰⁰", + }, + }, { + pattern: "##0.###E00", + test: pairs{ + "100": "100\u202f×\u202f10⁰⁰", + "12345": "12.345\u202f×\u202f10⁰³", + "123456": "123.456\u202f×\u202f10⁰³", + "123.456": "123.456\u202f×\u202f10⁰⁰", + "123.4567": "123.457\u202f×\u202f10⁰⁰", + }, + }, { + pattern: "##0.000E00", + test: pairs{ + "100": "100.000\u202f×\u202f10⁰⁰", + "12345": "12.345\u202f×\u202f10⁰³", + "123.456": "123.456\u202f×\u202f10⁰⁰", + "12.3456": "12.346\u202f×\u202f10⁰⁰", + }, + }, { + pattern: "@@E0", + test: pairs{ + "0": "0.0\u202f×\u202f10⁰", + "99": "9.9\u202f×\u202f10¹", + "0.99": "9.9\u202f×\u202f10⁻¹", + }, + }, { + pattern: "@###E00", + test: pairs{ + "0": "0\u202f×\u202f10⁰⁰", + "1": "1\u202f×\u202f10⁰⁰", + "11": "1.1\u202f×\u202f10⁰¹", + "111": "1.11\u202f×\u202f10⁰²", + "1111": "1.111\u202f×\u202f10⁰³", + "11111": "1.111\u202f×\u202f10⁰⁴", + "0.1": "1\u202f×\u202f10⁻⁰¹", + "0.11": "1.1\u202f×\u202f10⁻⁰¹", + "0.001": "1\u202f×\u202f10⁻⁰³", + }, + }, { + pattern: "*x##0", + test: pairs{ + "0": "xx0", + "10": "x10", + "100": "100", + "1000": "1000", + }, + }, { + pattern: "##0*x", + test: pairs{ + "0": "0xx", + "10": "10x", + "100": "100", + "1000": "1000", + }, + }, { + pattern: "* ###0.000", + test: pairs{ + "0": " 0.000", + "123": " 123.000", + "123.456": " 123.456", + "1234.567": "1234.567", + }, + }, { + pattern: "**0.0#######E00", + test: pairs{ + "0": "***0.0\u202f×\u202f10⁰⁰", + "10": "***1.0\u202f×\u202f10⁰¹", + "11": "***1.1\u202f×\u202f10⁰¹", + "111": "**1.11\u202f×\u202f10⁰²", + "1111": "*1.111\u202f×\u202f10⁰³", + "11111": "1.1111\u202f×\u202f10⁰⁴", + "11110": "*1.111\u202f×\u202f10⁰⁴", + "11100": "**1.11\u202f×\u202f10⁰⁴", + "11000": "***1.1\u202f×\u202f10⁰⁴", + "10000": "***1.0\u202f×\u202f10⁰⁴", + }, + }, { + pattern: "*xpre0suf", + test: pairs{ + "0": "pre0suf", + "10": "pre10suf", + }, + }, { + pattern: "*∞ pre ###0 suf", + test: pairs{ + "0": "∞∞∞ pre 0 suf", + "10": "∞∞ pre 10 suf", + "100": "∞ pre 100 suf", + "1000": " pre 1000 suf", + }, + }, { + pattern: "pre *∞###0 suf", + test: pairs{ + "0": "pre ∞∞∞0 suf", + "10": "pre ∞∞10 suf", + "100": "pre ∞100 suf", + "1000": "pre 1000 suf", + }, + }, { + pattern: "pre ###0*∞ suf", + test: pairs{ + "0": "pre 0∞∞∞ suf", + "10": "pre 10∞∞ suf", + "100": "pre 100∞ suf", + "1000": "pre 1000 suf", + }, + }, { + pattern: "pre ###0 suf *∞", + test: pairs{ + "0": "pre 0 suf ∞∞∞", + "10": "pre 10 suf ∞∞", + "100": "pre 100 suf ∞", + "1000": "pre 1000 suf ", + }, + }, { + // Take width of positive pattern. + pattern: "**###0;**-#####0x", + test: pairs{ + "0": "***0", + "-1": "*-1x", + }, + }, { + pattern: "0.00%", + test: pairs{ + "0.1": "10.00%", + }, + }, { + pattern: "0.##%", + test: pairs{ + "0.1": "10%", + "0.11": "11%", + "0.111": "11.1%", + "0.1111": "11.11%", + "0.11111": "11.11%", + }, + }, { + pattern: "‰ 0.0#", + test: pairs{ + "0.1": "‰ 100.0", + "0.11": "‰ 110.0", + "0.111": "‰ 111.0", + "0.1111": "‰ 111.1", + "0.11111": "‰ 111.11", + "0.111111": "‰ 111.11", + }, + }} + + // TODO: + // "#,##0.00¤", + // "#,##0.00 ¤;(#,##0.00 ¤)", + + for _, tc := range testCases { + pat := tc.pat + if pat == nil { + var err error + if pat, err = ParsePattern(tc.pattern); err != nil { + log.Fatal(err) + } + } + var f Formatter + f.InitPattern(language.English, pat) + for num, want := range tc.test { + buf := make([]byte, 100) + t.Run(tc.pattern+"/"+num, func(t *testing.T) { + var d Decimal + d.Convert(f.RoundingContext, dec(num)) + buf = f.Format(buf[:0], &d) + if got := string(buf); got != want { + t.Errorf("\n got %[1]q (%[1]s)\nwant %[2]q (%[2]s)", got, want) + } + }) + } + } +} + +func TestLocales(t *testing.T) { + testCases := []struct { + tag language.Tag + num string + want string + }{ + {language.Make("en"), "123456.78", "123,456.78"}, + {language.Make("de"), "123456.78", "123.456,78"}, + {language.Make("de-CH"), "123456.78", "123’456.78"}, + {language.Make("fr"), "123456.78", "123 456,78"}, + {language.Make("bn"), "123456.78", "১,২৩,৪৫৬.৭৮"}, + } + for _, tc := range testCases { + t.Run(fmt.Sprint(tc.tag, "/", tc.num), func(t *testing.T) { + var f Formatter + f.InitDecimal(tc.tag) + var d Decimal + d.Convert(f.RoundingContext, dec(tc.num)) + b := f.Format(nil, &d) + if got := string(b); got != tc.want { + t.Errorf("got %[1]q (%[1]s); want %[2]q (%[2]s)", got, tc.want) + } + }) + } +} + +func TestFormatters(t *testing.T) { + var f Formatter + testCases := []struct { + init func(t language.Tag) + num string + want string + }{ + {f.InitDecimal, "123456.78", "123,456.78"}, + {f.InitScientific, "123456.78", "1.23\u202f×\u202f10⁵"}, + {f.InitEngineering, "123456.78", "123.46\u202f×\u202f10³"}, + {f.InitEngineering, "1234", "1.23\u202f×\u202f10³"}, + + {f.InitPercent, "0.1234", "12.34%"}, + {f.InitPerMille, "0.1234", "123.40‰"}, + } + for i, tc := range testCases { + t.Run(fmt.Sprint(i, "/", tc.num), func(t *testing.T) { + tc.init(language.English) + f.SetScale(2) + var d Decimal + d.Convert(f.RoundingContext, dec(tc.num)) + b := f.Format(nil, &d) + if got := string(b); got != tc.want { + t.Errorf("got %[1]q (%[1]s); want %[2]q (%[2]s)", got, tc.want) + } + }) + } +} diff --git a/vendor/golang.org/x/text/internal/number/gen.go b/vendor/golang.org/x/text/internal/number/gen.go new file mode 100644 index 0000000..48f180f --- /dev/null +++ b/vendor/golang.org/x/text/internal/number/gen.go @@ -0,0 +1,458 @@ +// 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 ( + "flag" + "fmt" + "log" + "reflect" + "strings" + "unicode/utf8" + + "golang.org/x/text/internal" + "golang.org/x/text/internal/gen" + "golang.org/x/text/internal/number" + "golang.org/x/text/internal/stringset" + "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 = "number" + + 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", "numberingSystem") + data, err := d.DecodeZip(r) + if err != nil { + log.Fatalf("DecodeZip: %v", err) + } + + w := gen.NewCodeWriter() + defer w.WriteGoFile(*outputFile, pkg) + + fmt.Fprintln(w, `import "golang.org/x/text/internal/stringset"`) + + gen.WriteCLDRVersion(w) + + genNumSystem(w, data) + genSymbols(w, data) + genFormats(w, data) +} + +var systemMap = map[string]system{"latn": 0} + +func getNumberSystem(str string) system { + ns, ok := systemMap[str] + if !ok { + log.Fatalf("No index for numbering system %q", str) + } + return ns +} + +func genNumSystem(w *gen.CodeWriter, data *cldr.CLDR) { + numSysData := []systemData{ + {digitSize: 1, zero: [4]byte{'0'}}, + } + + for _, ns := range data.Supplemental().NumberingSystems.NumberingSystem { + if len(ns.Digits) == 0 { + continue + } + switch ns.Id { + case "latn": + // hard-wired + continue + case "hanidec": + // non-consecutive digits: treat as "algorithmic" + continue + } + + zero, sz := utf8.DecodeRuneInString(ns.Digits) + if ns.Digits[sz-1]+9 > 0xBF { // 1011 1111: highest continuation byte + log.Fatalf("Last byte of zero value overflows for %s", ns.Id) + } + + i := rune(0) + for _, r := range ns.Digits { + // Verify that we can do simple math on the UTF-8 byte sequence + // of zero to get the digit. + if zero+i != r { + // Runes not consecutive. + log.Fatalf("Digit %d of %s (%U) is not offset correctly from zero value", i, ns.Id, r) + } + i++ + } + var x [utf8.UTFMax]byte + utf8.EncodeRune(x[:], zero) + id := system(len(numSysData)) + systemMap[ns.Id] = id + numSysData = append(numSysData, systemData{ + id: id, + digitSize: byte(sz), + zero: x, + }) + } + w.WriteVar("numSysData", numSysData) + + algoID := system(len(numSysData)) + fmt.Fprintln(w, "const (") + for _, ns := range data.Supplemental().NumberingSystems.NumberingSystem { + id, ok := systemMap[ns.Id] + if !ok { + id = algoID + systemMap[ns.Id] = id + algoID++ + } + fmt.Fprintf(w, "num%s = %#x\n", strings.Title(ns.Id), id) + } + fmt.Fprintln(w, "numNumberSystems") + fmt.Fprintln(w, ")") + + fmt.Fprintln(w, "var systemMap = map[string]system{") + for _, ns := range data.Supplemental().NumberingSystems.NumberingSystem { + fmt.Fprintf(w, "%q: num%s,\n", ns.Id, strings.Title(ns.Id)) + w.Size += len(ns.Id) + 16 + 1 // very coarse approximation + } + fmt.Fprintln(w, "}") +} + +func genSymbols(w *gen.CodeWriter, data *cldr.CLDR) { + d, err := cldr.ParseDraft(*draft) + if err != nil { + log.Fatalf("invalid draft level: %v", err) + } + + nNumberSystems := system(len(systemMap)) + + type symbols [NumSymbolTypes]string + + type key struct { + tag int // from language.CompactIndex + system system + } + symbolMap := map[key]*symbols{} + + defaults := map[int]system{} + + for _, lang := range data.Locales() { + ldml := data.RawLDML(lang) + if ldml.Numbers == nil { + continue + } + langIndex, ok := language.CompactIndex(language.MustParse(lang)) + if !ok { + log.Fatalf("No compact index for language %s", lang) + } + if d := ldml.Numbers.DefaultNumberingSystem; len(d) > 0 { + defaults[langIndex] = getNumberSystem(d[0].Data()) + } + + syms := cldr.MakeSlice(&ldml.Numbers.Symbols) + syms.SelectDraft(d) + + getFirst := func(name string, x interface{}) string { + v := reflect.ValueOf(x) + slice := cldr.MakeSlice(x) + slice.SelectAnyOf("alt", "", "alt") + if reflect.Indirect(v).Len() == 0 { + return "" + } else if reflect.Indirect(v).Len() > 1 { + log.Fatalf("%s: multiple values of %q within single symbol not supported.", lang, name) + } + return reflect.Indirect(v).Index(0).MethodByName("Data").Call(nil)[0].String() + } + + for _, sym := range ldml.Numbers.Symbols { + if sym.NumberSystem == "" { + // This is just linking the default of root to "latn". + continue + } + symbolMap[key{langIndex, getNumberSystem(sym.NumberSystem)}] = &symbols{ + SymDecimal: getFirst("decimal", &sym.Decimal), + SymGroup: getFirst("group", &sym.Group), + SymList: getFirst("list", &sym.List), + SymPercentSign: getFirst("percentSign", &sym.PercentSign), + SymPlusSign: getFirst("plusSign", &sym.PlusSign), + SymMinusSign: getFirst("minusSign", &sym.MinusSign), + SymExponential: getFirst("exponential", &sym.Exponential), + SymSuperscriptingExponent: getFirst("superscriptingExponent", &sym.SuperscriptingExponent), + SymPerMille: getFirst("perMille", &sym.PerMille), + SymInfinity: getFirst("infinity", &sym.Infinity), + SymNan: getFirst("nan", &sym.Nan), + SymTimeSeparator: getFirst("timeSeparator", &sym.TimeSeparator), + } + } + } + + // Expand all values. + for k, syms := range symbolMap { + for t := SymDecimal; t < NumSymbolTypes; t++ { + p := k.tag + for syms[t] == "" { + p = int(internal.Parent[p]) + if pSyms, ok := symbolMap[key{p, k.system}]; ok && (*pSyms)[t] != "" { + syms[t] = (*pSyms)[t] + break + } + if p == 0 /* und */ { + // Default to root, latn. + syms[t] = (*symbolMap[key{}])[t] + } + } + } + } + + // Unique the symbol sets and write the string data. + m := map[symbols]int{} + sb := stringset.NewBuilder() + + symIndex := [][NumSymbolTypes]byte{} + + for ns := system(0); ns < nNumberSystems; ns++ { + for _, l := range data.Locales() { + langIndex, _ := language.CompactIndex(language.MustParse(l)) + s := symbolMap[key{langIndex, ns}] + if s == nil { + continue + } + if _, ok := m[*s]; !ok { + m[*s] = len(symIndex) + sb.Add(s[:]...) + var x [NumSymbolTypes]byte + for i := SymDecimal; i < NumSymbolTypes; i++ { + x[i] = byte(sb.Index((*s)[i])) + } + symIndex = append(symIndex, x) + } + } + } + w.WriteVar("symIndex", symIndex) + w.WriteVar("symData", sb.Set()) + + // resolveSymbolIndex gets the index from the closest matching locale, + // including the locale itself. + resolveSymbolIndex := func(langIndex int, ns system) symOffset { + for { + if sym := symbolMap[key{langIndex, ns}]; sym != nil { + return symOffset(m[*sym]) + } + if langIndex == 0 { + return 0 // und, latn + } + langIndex = int(internal.Parent[langIndex]) + } + } + + // Create an index with the symbols for each locale for the latn numbering + // system. If this is not the default, or the only one, for a locale, we + // will overwrite the value later. + var langToDefaults [language.NumCompactTags]symOffset + for _, l := range data.Locales() { + langIndex, _ := language.CompactIndex(language.MustParse(l)) + langToDefaults[langIndex] = resolveSymbolIndex(langIndex, 0) + } + + // Delete redundant entries. + for _, l := range data.Locales() { + langIndex, _ := language.CompactIndex(language.MustParse(l)) + def := defaults[langIndex] + syms := symbolMap[key{langIndex, def}] + if syms == nil { + continue + } + for ns := system(0); ns < nNumberSystems; ns++ { + if ns == def { + continue + } + if altSyms, ok := symbolMap[key{langIndex, ns}]; ok && *altSyms == *syms { + delete(symbolMap, key{langIndex, ns}) + } + } + } + + // Create a sorted list of alternatives per language. This will only need to + // be referenced if a user specified an alternative numbering system. + var langToAlt []altSymData + for _, l := range data.Locales() { + langIndex, _ := language.CompactIndex(language.MustParse(l)) + start := len(langToAlt) + if start >= hasNonLatnMask { + log.Fatalf("Number of alternative assignments >= %x", hasNonLatnMask) + } + // Create the entry for the default value. + def := defaults[langIndex] + langToAlt = append(langToAlt, altSymData{ + compactTag: uint16(langIndex), + system: def, + symIndex: resolveSymbolIndex(langIndex, def), + }) + + for ns := system(0); ns < nNumberSystems; ns++ { + if def == ns { + continue + } + if sym := symbolMap[key{langIndex, ns}]; sym != nil { + langToAlt = append(langToAlt, altSymData{ + compactTag: uint16(langIndex), + system: ns, + symIndex: resolveSymbolIndex(langIndex, ns), + }) + } + } + if def == 0 && len(langToAlt) == start+1 { + // No additional data: erase the entry. + langToAlt = langToAlt[:start] + } else { + // Overwrite the entry in langToDefaults. + langToDefaults[langIndex] = hasNonLatnMask | symOffset(start) + } + } + w.WriteComment(` +langToDefaults maps a compact language index to the default numbering system +and default symbol set`) + w.WriteVar("langToDefaults", langToDefaults) + + w.WriteComment(` +langToAlt is a list of numbering system and symbol set pairs, sorted and +marked by compact language index.`) + w.WriteVar("langToAlt", langToAlt) +} + +// genFormats generates the lookup table for decimal, scientific and percent +// patterns. +// +// CLDR allows for patterns to be different per language for different numbering +// systems. In practice the patterns are set to be consistent for a language +// independent of the numbering system. genFormats verifies that no language +// deviates from this. +func genFormats(w *gen.CodeWriter, data *cldr.CLDR) { + d, err := cldr.ParseDraft(*draft) + if err != nil { + log.Fatalf("invalid draft level: %v", err) + } + + // Fill the first slot with a dummy so we can identify unspecified tags. + formats := []number.Pattern{{}} + patterns := map[string]int{} + + // TODO: It would be possible to eliminate two of these slices by having + // another indirection and store a reference to the combination of patterns. + decimal := make([]byte, language.NumCompactTags) + scientific := make([]byte, language.NumCompactTags) + percent := make([]byte, language.NumCompactTags) + + for _, lang := range data.Locales() { + ldml := data.RawLDML(lang) + if ldml.Numbers == nil { + continue + } + langIndex, ok := language.CompactIndex(language.MustParse(lang)) + if !ok { + log.Fatalf("No compact index for language %s", lang) + } + type patternSlice []*struct { + cldr.Common + Numbers string `xml:"numbers,attr"` + Count string `xml:"count,attr"` + } + + add := func(name string, tags []byte, ps patternSlice) { + sl := cldr.MakeSlice(&ps) + sl.SelectDraft(d) + if len(ps) == 0 { + return + } + if len(ps) > 2 || len(ps) == 2 && ps[0] != ps[1] { + log.Fatalf("Inconsistent %d patterns for language %s", name, lang) + } + s := ps[0].Data() + + index, ok := patterns[s] + if !ok { + nf, err := number.ParsePattern(s) + if err != nil { + log.Fatal(err) + } + index = len(formats) + patterns[s] = index + formats = append(formats, *nf) + } + tags[langIndex] = byte(index) + } + + for _, df := range ldml.Numbers.DecimalFormats { + for _, l := range df.DecimalFormatLength { + if l.Type != "" { + continue + } + for _, f := range l.DecimalFormat { + add("decimal", decimal, f.Pattern) + } + } + } + for _, df := range ldml.Numbers.ScientificFormats { + for _, l := range df.ScientificFormatLength { + if l.Type != "" { + continue + } + for _, f := range l.ScientificFormat { + add("scientific", scientific, f.Pattern) + } + } + } + for _, df := range ldml.Numbers.PercentFormats { + for _, l := range df.PercentFormatLength { + if l.Type != "" { + continue + } + for _, f := range l.PercentFormat { + add("percent", percent, f.Pattern) + } + } + } + } + + // Complete the parent tag array to reflect inheritance. An index of 0 + // indicates an unspecified value. + for _, data := range [][]byte{decimal, scientific, percent} { + for i := range data { + p := uint16(i) + for ; data[p] == 0; p = internal.Parent[p] { + } + data[i] = data[p] + } + } + w.WriteVar("tagToDecimal", decimal) + w.WriteVar("tagToScientific", scientific) + w.WriteVar("tagToPercent", percent) + + value := strings.Replace(fmt.Sprintf("%#v", formats), "number.", "", -1) + // Break up the lines. This won't give ideal perfect formatting, but it is + // better than one huge line. + value = strings.Replace(value, ", ", ",\n", -1) + fmt.Fprintf(w, "var formats = %s\n", value) +} diff --git a/vendor/golang.org/x/text/internal/number/gen_common.go b/vendor/golang.org/x/text/internal/number/gen_common.go new file mode 100644 index 0000000..f88b838 --- /dev/null +++ b/vendor/golang.org/x/text/internal/number/gen_common.go @@ -0,0 +1,55 @@ +// 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 "unicode/utf8" + +// A system identifies a CLDR numbering system. +type system byte + +type systemData struct { + id system + digitSize byte // number of UTF-8 bytes per digit + zero [utf8.UTFMax]byte // UTF-8 sequence of zero digit. +} + +// A SymbolType identifies a symbol of a specific kind. +type SymbolType int + +const ( + SymDecimal SymbolType = iota + SymGroup + SymList + SymPercentSign + SymPlusSign + SymMinusSign + SymExponential + SymSuperscriptingExponent + SymPerMille + SymInfinity + SymNan + SymTimeSeparator + + NumSymbolTypes +) + +const hasNonLatnMask = 0x8000 + +// symOffset is an offset into altSymData if the bit indicated by hasNonLatnMask +// is not 0 (with this bit masked out), and an offset into symIndex otherwise. +// +// TODO: this type can be a byte again if we use an indirection into altsymData +// and introduce an alt -> offset slice (the length of this will be number of +// alternatives plus 1). This also allows getting rid of the compactTag field +// in altSymData. In total this will save about 1K. +type symOffset uint16 + +type altSymData struct { + compactTag uint16 + symIndex symOffset + system system +} diff --git a/vendor/golang.org/x/text/internal/number/number.go b/vendor/golang.org/x/text/internal/number/number.go new file mode 100644 index 0000000..2a21f07 --- /dev/null +++ b/vendor/golang.org/x/text/internal/number/number.go @@ -0,0 +1,156 @@ +// 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 number contains tools and data for formatting numbers. +package number + +import ( + "unicode/utf8" + + "golang.org/x/text/internal" + "golang.org/x/text/language" +) + +// Info holds number formatting configuration data. +type Info struct { + system systemData // numbering system information + symIndex symOffset // index to symbols +} + +// InfoFromLangID returns a Info for the given compact language identifier and +// numbering system identifier. If system is the empty string, the default +// numbering system will be taken for that language. +func InfoFromLangID(compactIndex int, numberSystem string) Info { + p := langToDefaults[compactIndex] + // Lookup the entry for the language. + pSymIndex := symOffset(0) // Default: Latin, default symbols + system, ok := systemMap[numberSystem] + if !ok { + // Take the value for the default numbering system. This is by far the + // most common case as an alternative numbering system is hardly used. + if p&hasNonLatnMask == 0 { // Latn digits. + pSymIndex = p + } else { // Non-Latn or multiple numbering systems. + // Take the first entry from the alternatives list. + data := langToAlt[p&^hasNonLatnMask] + pSymIndex = data.symIndex + system = data.system + } + } else { + langIndex := compactIndex + ns := system + outerLoop: + for ; ; p = langToDefaults[langIndex] { + if p&hasNonLatnMask == 0 { + if ns == 0 { + // The index directly points to the symbol data. + pSymIndex = p + break + } + // Move to the parent and retry. + langIndex = int(internal.Parent[langIndex]) + } else { + // The index points to a list of symbol data indexes. + for _, e := range langToAlt[p&^hasNonLatnMask:] { + if int(e.compactTag) != langIndex { + if langIndex == 0 { + // The CLDR root defines full symbol information for + // all numbering systems (even though mostly by + // means of aliases). Fall back to the default entry + // for Latn if there is no data for the numbering + // system of this language. + if ns == 0 { + break + } + // Fall back to Latin and start from the original + // language. See + // http://unicode.org/reports/tr35/#Locale_Inheritance. + ns = numLatn + langIndex = compactIndex + continue outerLoop + } + // Fall back to parent. + langIndex = int(internal.Parent[langIndex]) + } else if e.system == ns { + pSymIndex = e.symIndex + break outerLoop + } + } + } + } + } + if int(system) >= len(numSysData) { // algorithmic + // Will generate ASCII digits in case the user inadvertently calls + // WriteDigit or Digit on it. + d := numSysData[0] + d.id = system + return Info{ + system: d, + symIndex: pSymIndex, + } + } + return Info{ + system: numSysData[system], + symIndex: pSymIndex, + } +} + +// InfoFromTag returns a Info for the given language tag. +func InfoFromTag(t language.Tag) Info { + for { + if index, ok := language.CompactIndex(t); ok { + return InfoFromLangID(index, t.TypeForKey("nu")) + } + t = t.Parent() + } +} + +// IsDecimal reports if the numbering system can convert decimal to native +// symbols one-to-one. +func (n Info) IsDecimal() bool { + return int(n.system.id) < len(numSysData) +} + +// WriteDigit writes the UTF-8 sequence for n corresponding to the given ASCII +// digit to dst and reports the number of bytes written. dst must be large +// enough to hold the rune (can be up to utf8.UTFMax bytes). +func (n Info) WriteDigit(dst []byte, asciiDigit rune) int { + copy(dst, n.system.zero[:n.system.digitSize]) + dst[n.system.digitSize-1] += byte(asciiDigit - '0') + return int(n.system.digitSize) +} + +// AppendDigit appends the UTF-8 sequence for n corresponding to the given digit +// to dst and reports the number of bytes written. dst must be large enough to +// hold the rune (can be up to utf8.UTFMax bytes). +func (n Info) AppendDigit(dst []byte, digit byte) []byte { + dst = append(dst, n.system.zero[:n.system.digitSize]...) + dst[len(dst)-1] += digit + return dst +} + +// Digit returns the digit for the numbering system for the corresponding ASCII +// value. For example, ni.Digit('3') could return '三'. Note that the argument +// is the rune constant '3', which equals 51, not the integer constant 3. +func (n Info) Digit(asciiDigit rune) rune { + var x [utf8.UTFMax]byte + n.WriteDigit(x[:], asciiDigit) + r, _ := utf8.DecodeRune(x[:]) + return r +} + +// Symbol returns the string for the given symbol type. +func (n Info) Symbol(t SymbolType) string { + return symData.Elem(int(symIndex[n.symIndex][t])) +} + +func formatForLang(t language.Tag, index []byte) *Pattern { + for ; ; t = t.Parent() { + if x, ok := language.CompactIndex(t); ok { + return &formats[index[x]] + } + } +} diff --git a/vendor/golang.org/x/text/internal/number/number_test.go b/vendor/golang.org/x/text/internal/number/number_test.go new file mode 100644 index 0000000..cbc28ab --- /dev/null +++ b/vendor/golang.org/x/text/internal/number/number_test.go @@ -0,0 +1,104 @@ +// 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 number + +import ( + "fmt" + "testing" + + "golang.org/x/text/internal/testtext" + "golang.org/x/text/language" +) + +func TestInfo(t *testing.T) { + testCases := []struct { + lang string + sym SymbolType + wantSym string + wantNine rune + }{ + {"und", SymDecimal, ".", '9'}, + {"de", SymGroup, ".", '9'}, + {"de-BE", SymGroup, ".", '9'}, // inherits from de (no number data in CLDR) + {"de-BE-oxendict", SymGroup, ".", '9'}, // inherits from de (no compact index) + + // U+096F DEVANAGARI DIGIT NINE ('९') + {"de-BE-u-nu-deva", SymGroup, ".", '\u096f'}, // miss -> latn -> de + {"de-Cyrl-BE", SymGroup, ",", '9'}, // inherits from root + {"de-CH", SymGroup, "’", '9'}, // overrides values in de + {"de-CH-oxendict", SymGroup, "’", '9'}, // inherits from de-CH (no compact index) + {"de-CH-u-nu-deva", SymGroup, "’", '\u096f'}, // miss -> latn -> de-CH + + {"bn-u-nu-beng", SymGroup, ",", '\u09ef'}, + {"bn-u-nu-deva", SymGroup, ",", '\u096f'}, + {"bn-u-nu-latn", SymGroup, ",", '9'}, + + {"pa", SymExponential, "E", '9'}, + + // "×۱۰^" -> U+00d7 U+06f1 U+06f0^" + // U+06F0 EXTENDED ARABIC-INDIC DIGIT ZERO + // U+06F1 EXTENDED ARABIC-INDIC DIGIT ONE + // U+06F9 EXTENDED ARABIC-INDIC DIGIT NINE + {"pa-u-nu-arabext", SymExponential, "\u00d7\u06f1\u06f0^", '\u06f9'}, + + // "གྲངས་མེད" - > U+0f42 U+0fb2 U+0f44 U+0f66 U+0f0b U+0f58 U+0f7a U+0f51 + // Examples: + // U+0F29 TIBETAN DIGIT NINE (༩) + {"dz", SymInfinity, "\u0f42\u0fb2\u0f44\u0f66\u0f0b\u0f58\u0f7a\u0f51", '\u0f29'}, // defaults to tibt + {"dz-u-nu-latn", SymInfinity, "∞", '9'}, // select alternative + {"dz-u-nu-tibt", SymInfinity, "\u0f42\u0fb2\u0f44\u0f66\u0f0b\u0f58\u0f7a\u0f51", '\u0f29'}, + {"en-u-nu-tibt", SymInfinity, "∞", '\u0f29'}, + + // algorithmic number systems fall back to ASCII if Digits is used. + {"en-u-nu-hanidec", SymPlusSign, "+", '9'}, + {"en-u-nu-roman", SymPlusSign, "+", '9'}, + } + for _, tc := range testCases { + t.Run(fmt.Sprintf("%s:%v", tc.lang, tc.sym), func(t *testing.T) { + info := InfoFromTag(language.MustParse(tc.lang)) + if got := info.Symbol(tc.sym); got != tc.wantSym { + t.Errorf("sym: got %q; want %q", got, tc.wantSym) + } + if got := info.Digit('9'); got != tc.wantNine { + t.Errorf("Digit(9): got %+q; want %+q", got, tc.wantNine) + } + var buf [4]byte + if got := string(buf[:info.WriteDigit(buf[:], '9')]); got != string(tc.wantNine) { + t.Errorf("WriteDigit(9): got %+q; want %+q", got, tc.wantNine) + } + if got := string(info.AppendDigit([]byte{}, 9)); got != string(tc.wantNine) { + t.Errorf("AppendDigit(9): got %+q; want %+q", got, tc.wantNine) + } + }) + } +} + +func TestFormats(t *testing.T) { + testCases := []struct { + lang string + pattern string + index []byte + }{ + {"en", "#,##0.###", tagToDecimal}, + {"de", "#,##0.###", tagToDecimal}, + {"de-CH", "#,##0.###", tagToDecimal}, + {"pa", "#,##,##0.###", tagToDecimal}, + {"pa-Arab", "#,##0.###", tagToDecimal}, // Does NOT inherit from pa! + {"mr", "#,##,##0.###", tagToDecimal}, + {"mr-IN", "#,##,##0.###", tagToDecimal}, // Inherits from mr. + {"nl", "#E0", tagToScientific}, + {"nl-MX", "#E0", tagToScientific}, // Inherits through Tag.Parent. + {"zgh", "#,##0 %", tagToPercent}, + } + for _, tc := range testCases { + testtext.Run(t, tc.lang, func(t *testing.T) { + got := formatForLang(language.MustParse(tc.lang), tc.index) + want, _ := ParsePattern(tc.pattern) + if *got != *want { + t.Errorf("\ngot %#v;\nwant %#v", got, want) + } + }) + } +} diff --git a/vendor/golang.org/x/text/internal/number/pattern.go b/vendor/golang.org/x/text/internal/number/pattern.go new file mode 100644 index 0000000..b95ca40 --- /dev/null +++ b/vendor/golang.org/x/text/internal/number/pattern.go @@ -0,0 +1,485 @@ +// Copyright 2015 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 number + +import ( + "errors" + "unicode/utf8" +) + +// This file contains a parser for the CLDR number patterns as described in +// http://unicode.org/reports/tr35/tr35-numbers.html#Number_Format_Patterns. +// +// The following BNF is derived from this standard. +// +// pattern := subpattern (';' subpattern)? +// subpattern := affix? number exponent? affix? +// number := decimal | sigDigits +// decimal := '#'* '0'* ('.' fraction)? | '#' | '0' +// fraction := '0'* '#'* +// sigDigits := '#'* '@' '@'* '#'* +// exponent := 'E' '+'? '0'* '0' +// padSpec := '*' \L +// +// Notes: +// - An affix pattern may contain any runes, but runes with special meaning +// should be escaped. +// - Sequences of digits, '#', and '@' in decimal and sigDigits may have +// interstitial commas. + +// TODO: replace special characters in affixes (-, +, ¤) with control codes. + +// Pattern holds information for formatting numbers. It is designed to hold +// information from CLDR number patterns. +// +// This pattern is precompiled for all patterns for all languages. Even though +// the number of patterns is not very large, we want to keep this small. +// +// This type is only intended for internal use. +type Pattern struct { + RoundingContext + + Affix string // includes prefix and suffix. First byte is prefix length. + Offset uint16 // Offset into Affix for prefix and suffix + NegOffset uint16 // Offset into Affix for negative prefix and suffix or 0. + PadRune rune + FormatWidth uint16 + + GroupingSize [2]uint8 + Flags PatternFlag +} + +// A RoundingContext indicates how a number should be converted to digits. +// It contains all information needed to determine the "visible digits" as +// required by the pluralization rules. +type RoundingContext struct { + // TODO: unify these two fields so that there is a more unambiguous meaning + // of how precision is handled. + MaxSignificantDigits int16 // -1 is unlimited + MaxFractionDigits int16 // -1 is unlimited + + Increment uint32 + IncrementScale uint8 // May differ from printed scale. + + Mode RoundingMode + + DigitShift uint8 // Number of decimals to shift. Used for % and ‰. + + // Number of digits. + MinIntegerDigits uint8 + + MaxIntegerDigits uint8 + MinFractionDigits uint8 + MinSignificantDigits uint8 + + MinExponentDigits uint8 +} + +// RoundSignificantDigits returns the number of significant digits an +// implementation of Convert may round to or n < 0 if there is no maximum or +// a maximum is not recommended. +func (r *RoundingContext) RoundSignificantDigits() (n int) { + if r.MaxFractionDigits == 0 && r.MaxSignificantDigits > 0 { + return int(r.MaxSignificantDigits) + } else if r.isScientific() && r.MaxIntegerDigits == 1 { + if r.MaxSignificantDigits == 0 || + int(r.MaxFractionDigits+1) == int(r.MaxSignificantDigits) { + // Note: don't add DigitShift: it is only used for decimals. + return int(r.MaxFractionDigits) + 1 + } + } + return -1 +} + +// RoundFractionDigits returns the number of fraction digits an implementation +// of Convert may round to or n < 0 if there is no maximum or a maximum is not +// recommended. +func (r *RoundingContext) RoundFractionDigits() (n int) { + if r.MinExponentDigits == 0 && + r.MaxSignificantDigits == 0 && + r.MaxFractionDigits >= 0 { + return int(r.MaxFractionDigits) + int(r.DigitShift) + } + return -1 +} + +// SetScale fixes the RoundingContext to a fixed number of fraction digits. +func (r *RoundingContext) SetScale(scale int) { + r.MinFractionDigits = uint8(scale) + r.MaxFractionDigits = int16(scale) +} + +func (r *RoundingContext) SetPrecision(prec int) { + r.MaxSignificantDigits = int16(prec) +} + +func (r *RoundingContext) isScientific() bool { + return r.MinExponentDigits > 0 +} + +func (f *Pattern) needsSep(pos int) bool { + p := pos - 1 + size := int(f.GroupingSize[0]) + if size == 0 || p == 0 { + return false + } + if p == size { + return true + } + if p -= size; p < 0 { + return false + } + // TODO: make second groupingsize the same as first if 0 so that we can + // avoid this check. + if x := int(f.GroupingSize[1]); x != 0 { + size = x + } + return p%size == 0 +} + +// A PatternFlag is a bit mask for the flag field of a Pattern. +type PatternFlag uint8 + +const ( + AlwaysSign PatternFlag = 1 << iota + ElideSign // Use space instead of plus sign. AlwaysSign must be true. + AlwaysExpSign + AlwaysDecimalSeparator + ParenthesisForNegative // Common pattern. Saves space. + + PadAfterNumber + PadAfterAffix + + PadBeforePrefix = 0 // Default + PadAfterPrefix = PadAfterAffix + PadBeforeSuffix = PadAfterNumber + PadAfterSuffix = PadAfterNumber | PadAfterAffix + PadMask = PadAfterNumber | PadAfterAffix +) + +type parser struct { + *Pattern + + leadingSharps int + + pos int + err error + doNotTerminate bool + groupingCount uint + hasGroup bool + buf []byte +} + +func (p *parser) setError(err error) { + if p.err == nil { + p.err = err + } +} + +func (p *parser) updateGrouping() { + if p.hasGroup && + 0 < p.groupingCount && p.groupingCount < 255 { + p.GroupingSize[1] = p.GroupingSize[0] + p.GroupingSize[0] = uint8(p.groupingCount) + } + p.groupingCount = 0 + p.hasGroup = true +} + +var ( + // TODO: more sensible and localizeable error messages. + errMultiplePadSpecifiers = errors.New("format: pattern has multiple pad specifiers") + errInvalidPadSpecifier = errors.New("format: invalid pad specifier") + errInvalidQuote = errors.New("format: invalid quote") + errAffixTooLarge = errors.New("format: prefix or suffix exceeds maximum UTF-8 length of 256 bytes") + errDuplicatePercentSign = errors.New("format: duplicate percent sign") + errDuplicatePermilleSign = errors.New("format: duplicate permille sign") + errUnexpectedEnd = errors.New("format: unexpected end of pattern") +) + +// ParsePattern extracts formatting information from a CLDR number pattern. +// +// See http://unicode.org/reports/tr35/tr35-numbers.html#Number_Format_Patterns. +func ParsePattern(s string) (f *Pattern, err error) { + p := parser{Pattern: &Pattern{}} + + s = p.parseSubPattern(s) + + if s != "" { + // Parse negative sub pattern. + if s[0] != ';' { + p.setError(errors.New("format: error parsing first sub pattern")) + return nil, p.err + } + neg := parser{Pattern: &Pattern{}} // just for extracting the affixes. + s = neg.parseSubPattern(s[len(";"):]) + p.NegOffset = uint16(len(p.buf)) + p.buf = append(p.buf, neg.buf...) + } + if s != "" { + p.setError(errors.New("format: spurious characters at end of pattern")) + } + if p.err != nil { + return nil, p.err + } + if affix := string(p.buf); affix == "\x00\x00" || affix == "\x00\x00\x00\x00" { + // No prefix or suffixes. + p.NegOffset = 0 + } else { + p.Affix = affix + } + if p.Increment == 0 { + p.IncrementScale = 0 + } + return p.Pattern, nil +} + +func (p *parser) parseSubPattern(s string) string { + s = p.parsePad(s, PadBeforePrefix) + s = p.parseAffix(s) + s = p.parsePad(s, PadAfterPrefix) + + s = p.parse(p.number, s) + p.updateGrouping() + + s = p.parsePad(s, PadBeforeSuffix) + s = p.parseAffix(s) + s = p.parsePad(s, PadAfterSuffix) + return s +} + +func (p *parser) parsePad(s string, f PatternFlag) (tail string) { + if len(s) >= 2 && s[0] == '*' { + r, sz := utf8.DecodeRuneInString(s[1:]) + if p.PadRune != 0 { + p.err = errMultiplePadSpecifiers + } else { + p.Flags |= f + p.PadRune = r + } + return s[1+sz:] + } + return s +} + +func (p *parser) parseAffix(s string) string { + x := len(p.buf) + p.buf = append(p.buf, 0) // placeholder for affix length + + s = p.parse(p.affix, s) + + n := len(p.buf) - x - 1 + if n > 0xFF { + p.setError(errAffixTooLarge) + } + p.buf[x] = uint8(n) + return s +} + +// state implements a state transition. It returns the new state. A state +// function may set an error on the parser or may simply return on an incorrect +// token and let the next phase fail. +type state func(r rune) state + +// parse repeatedly applies a state function on the given string until a +// termination condition is reached. +func (p *parser) parse(fn state, s string) (tail string) { + for i, r := range s { + p.doNotTerminate = false + if fn = fn(r); fn == nil || p.err != nil { + return s[i:] + } + p.FormatWidth++ + } + if p.doNotTerminate { + p.setError(errUnexpectedEnd) + } + return "" +} + +func (p *parser) affix(r rune) state { + switch r { + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + '#', '@', '.', '*', ',', ';': + return nil + case '\'': + p.FormatWidth-- + return p.escapeFirst + case '%': + if p.DigitShift != 0 { + p.setError(errDuplicatePercentSign) + } + p.DigitShift = 2 + case '\u2030': // ‰ Per mille + if p.DigitShift != 0 { + p.setError(errDuplicatePermilleSign) + } + p.DigitShift = 3 + // TODO: handle currency somehow: ¤, ¤¤, ¤¤¤, ¤¤¤¤ + } + p.buf = append(p.buf, string(r)...) + return p.affix +} + +func (p *parser) escapeFirst(r rune) state { + switch r { + case '\'': + p.buf = append(p.buf, "\\'"...) + return p.affix + default: + p.buf = append(p.buf, '\'') + p.buf = append(p.buf, string(r)...) + } + return p.escape +} + +func (p *parser) escape(r rune) state { + switch r { + case '\'': + p.FormatWidth-- + p.buf = append(p.buf, '\'') + return p.affix + default: + p.buf = append(p.buf, string(r)...) + } + return p.escape +} + +// number parses a number. The BNF says the integer part should always have +// a '0', but that does not appear to be the case according to the rest of the +// documentation. We will allow having only '#' numbers. +func (p *parser) number(r rune) state { + switch r { + case '#': + p.groupingCount++ + p.leadingSharps++ + case '@': + p.groupingCount++ + p.leadingSharps = 0 + p.MaxFractionDigits = -1 + return p.sigDigits(r) + case ',': + if p.leadingSharps == 0 { // no leading commas + return nil + } + p.updateGrouping() + case 'E': + p.MaxIntegerDigits = uint8(p.leadingSharps) + return p.exponent + case '.': // allow ".##" etc. + p.updateGrouping() + return p.fraction + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + return p.integer(r) + default: + return nil + } + return p.number +} + +func (p *parser) integer(r rune) state { + if !('0' <= r && r <= '9') { + var next state + switch r { + case 'E': + if p.leadingSharps > 0 { + p.MaxIntegerDigits = uint8(p.leadingSharps) + p.MinIntegerDigits + } + next = p.exponent + case '.': + next = p.fraction + case ',': + next = p.integer + } + p.updateGrouping() + return next + } + p.Increment = p.Increment*10 + uint32(r-'0') + p.groupingCount++ + p.MinIntegerDigits++ + return p.integer +} + +func (p *parser) sigDigits(r rune) state { + switch r { + case '@': + p.groupingCount++ + p.MaxSignificantDigits++ + p.MinSignificantDigits++ + case '#': + return p.sigDigitsFinal(r) + case 'E': + p.updateGrouping() + return p.normalizeSigDigitsWithExponent() + default: + p.updateGrouping() + return nil + } + return p.sigDigits +} + +func (p *parser) sigDigitsFinal(r rune) state { + switch r { + case '#': + p.groupingCount++ + p.MaxSignificantDigits++ + case 'E': + p.updateGrouping() + return p.normalizeSigDigitsWithExponent() + default: + p.updateGrouping() + return nil + } + return p.sigDigitsFinal +} + +func (p *parser) normalizeSigDigitsWithExponent() state { + p.MinIntegerDigits, p.MaxIntegerDigits = 1, 1 + p.MinFractionDigits = p.MinSignificantDigits - 1 + p.MaxFractionDigits = p.MaxSignificantDigits - 1 + p.MinSignificantDigits, p.MaxSignificantDigits = 0, 0 + return p.exponent +} + +func (p *parser) fraction(r rune) state { + switch r { + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + p.Increment = p.Increment*10 + uint32(r-'0') + p.IncrementScale++ + p.MinFractionDigits++ + p.MaxFractionDigits++ + case '#': + p.MaxFractionDigits++ + case 'E': + if p.leadingSharps > 0 { + p.MaxIntegerDigits = uint8(p.leadingSharps) + p.MinIntegerDigits + } + return p.exponent + default: + return nil + } + return p.fraction +} + +func (p *parser) exponent(r rune) state { + switch r { + case '+': + // Set mode and check it wasn't already set. + if p.Flags&AlwaysExpSign != 0 || p.MinExponentDigits > 0 { + break + } + p.Flags |= AlwaysExpSign + p.doNotTerminate = true + return p.exponent + case '0': + p.MinExponentDigits++ + return p.exponent + } + // termination condition + if p.MinExponentDigits == 0 { + p.setError(errors.New("format: need at least one digit")) + } + return nil +} diff --git a/vendor/golang.org/x/text/internal/number/pattern_test.go b/vendor/golang.org/x/text/internal/number/pattern_test.go new file mode 100644 index 0000000..a7517d0 --- /dev/null +++ b/vendor/golang.org/x/text/internal/number/pattern_test.go @@ -0,0 +1,438 @@ +// Copyright 2015 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 number + +import ( + "reflect" + "testing" + "unsafe" +) + +var testCases = []struct { + pat string + want *Pattern +}{{ + "#", + &Pattern{ + FormatWidth: 1, + // TODO: Should MinIntegerDigits be 1? + }, +}, { + "0", + &Pattern{ + FormatWidth: 1, + RoundingContext: RoundingContext{ + MinIntegerDigits: 1, + }, + }, +}, { + "+0", + &Pattern{ + Affix: "\x01+\x00", + FormatWidth: 2, + RoundingContext: RoundingContext{ + MinIntegerDigits: 1, + }, + }, +}, { + "0+", + &Pattern{ + Affix: "\x00\x01+", + FormatWidth: 2, + RoundingContext: RoundingContext{ + MinIntegerDigits: 1, + }, + }, +}, { + "0000", + &Pattern{ + FormatWidth: 4, + RoundingContext: RoundingContext{ + MinIntegerDigits: 4, + }, + }, +}, { + ".#", + &Pattern{ + FormatWidth: 2, + RoundingContext: RoundingContext{ + MaxFractionDigits: 1, + }, + }, +}, { + "#0.###", + &Pattern{ + FormatWidth: 6, + RoundingContext: RoundingContext{ + MinIntegerDigits: 1, + MaxFractionDigits: 3, + }, + }, +}, { + "#0.######", + &Pattern{ + FormatWidth: 9, + RoundingContext: RoundingContext{ + MinIntegerDigits: 1, + MaxFractionDigits: 6, + }, + }, +}, { + "#,0", + &Pattern{ + FormatWidth: 3, + GroupingSize: [2]uint8{1, 0}, + RoundingContext: RoundingContext{ + MinIntegerDigits: 1, + }, + }, +}, { + "#,0.00", + &Pattern{ + FormatWidth: 6, + GroupingSize: [2]uint8{1, 0}, + RoundingContext: RoundingContext{ + MinIntegerDigits: 1, + MinFractionDigits: 2, + MaxFractionDigits: 2, + }, + }, +}, { + "#,##0.###", + &Pattern{ + FormatWidth: 9, + GroupingSize: [2]uint8{3, 0}, + RoundingContext: RoundingContext{ + MinIntegerDigits: 1, + MaxFractionDigits: 3, + }, + }, +}, { + "#,##,##0.###", + &Pattern{ + FormatWidth: 12, + GroupingSize: [2]uint8{3, 2}, + RoundingContext: RoundingContext{ + MinIntegerDigits: 1, + MaxFractionDigits: 3, + }, + }, +}, { + // Ignore additional separators. + "#,####,##,##0.###", + &Pattern{ + FormatWidth: 17, + GroupingSize: [2]uint8{3, 2}, + RoundingContext: RoundingContext{ + MinIntegerDigits: 1, + MaxFractionDigits: 3, + }, + }, +}, { + "#E0", + &Pattern{ + FormatWidth: 3, + RoundingContext: RoundingContext{ + MaxIntegerDigits: 1, + MinExponentDigits: 1, + }, + }, +}, { + // At least one exponent digit is required. As long as this is true, one can + // determine that scientific rendering is needed if MinExponentDigits > 0. + "#E#", + nil, +}, { + "0E0", + &Pattern{ + FormatWidth: 3, + RoundingContext: RoundingContext{ + MinIntegerDigits: 1, + MinExponentDigits: 1, + }, + }, +}, { + "##0.###E00", + &Pattern{ + FormatWidth: 10, + RoundingContext: RoundingContext{ + MinIntegerDigits: 1, + MaxIntegerDigits: 3, + MaxFractionDigits: 3, + MinExponentDigits: 2, + }, + }, +}, { + "##00.0#E0", + &Pattern{ + FormatWidth: 9, + RoundingContext: RoundingContext{ + MinIntegerDigits: 2, + MaxIntegerDigits: 4, + MinFractionDigits: 1, + MaxFractionDigits: 2, + MinExponentDigits: 1, + }, + }, +}, { + "#00.0E+0", + &Pattern{ + FormatWidth: 8, + Flags: AlwaysExpSign, + RoundingContext: RoundingContext{ + MinIntegerDigits: 2, + MaxIntegerDigits: 3, + MinFractionDigits: 1, + MaxFractionDigits: 1, + MinExponentDigits: 1, + }, + }, +}, { + "0.0E++0", + nil, +}, { + "#0E+", + nil, +}, { + // significant digits + "@", + &Pattern{ + FormatWidth: 1, + RoundingContext: RoundingContext{ + MinSignificantDigits: 1, + MaxSignificantDigits: 1, + MaxFractionDigits: -1, + }, + }, +}, { + // significant digits + "@@@@", + &Pattern{ + FormatWidth: 4, + RoundingContext: RoundingContext{ + MinSignificantDigits: 4, + MaxSignificantDigits: 4, + MaxFractionDigits: -1, + }, + }, +}, { + "@###", + &Pattern{ + FormatWidth: 4, + RoundingContext: RoundingContext{ + MinSignificantDigits: 1, + MaxSignificantDigits: 4, + MaxFractionDigits: -1, + }, + }, +}, { + // Exponents in significant digits mode gets normalized. + "@@E0", + &Pattern{ + FormatWidth: 4, + RoundingContext: RoundingContext{ + MinIntegerDigits: 1, + MaxIntegerDigits: 1, + MinFractionDigits: 1, + MaxFractionDigits: 1, + MinExponentDigits: 1, + }, + }, +}, { + "@###E00", + &Pattern{ + FormatWidth: 7, + RoundingContext: RoundingContext{ + MinIntegerDigits: 1, + MaxIntegerDigits: 1, + MinFractionDigits: 0, + MaxFractionDigits: 3, + MinExponentDigits: 2, + }, + }, +}, { + // The significant digits mode does not allow fractions. + "@###.#E0", + nil, +}, { + //alternative negative pattern + "#0.###;(#0.###)", + &Pattern{ + Affix: "\x00\x00\x01(\x01)", + NegOffset: 2, + FormatWidth: 6, + RoundingContext: RoundingContext{ + MinIntegerDigits: 1, + MaxFractionDigits: 3, + }, + }, +}, { + // Rounding increment + "1.05", + &Pattern{ + FormatWidth: 4, + RoundingContext: RoundingContext{ + Increment: 105, + IncrementScale: 2, + MinIntegerDigits: 1, + MinFractionDigits: 2, + MaxFractionDigits: 2, + }, + }, +}, { + // Rounding increment with grouping + "1,05", + &Pattern{ + FormatWidth: 4, + GroupingSize: [2]uint8{2, 0}, + RoundingContext: RoundingContext{ + Increment: 105, + IncrementScale: 0, + MinIntegerDigits: 3, + MinFractionDigits: 0, + MaxFractionDigits: 0, + }, + }, +}, { + "0.0%", + &Pattern{ + Affix: "\x00\x01%", + FormatWidth: 4, + RoundingContext: RoundingContext{ + DigitShift: 2, + MinIntegerDigits: 1, + MinFractionDigits: 1, + MaxFractionDigits: 1, + }, + }, +}, { + "0.0‰", + &Pattern{ + Affix: "\x00\x03‰", + FormatWidth: 4, + RoundingContext: RoundingContext{ + DigitShift: 3, + MinIntegerDigits: 1, + MinFractionDigits: 1, + MaxFractionDigits: 1, + }, + }, +}, { + "#,##0.00¤", + &Pattern{ + Affix: "\x00\x02¤", + FormatWidth: 9, + GroupingSize: [2]uint8{3, 0}, + RoundingContext: RoundingContext{ + MinIntegerDigits: 1, + MinFractionDigits: 2, + MaxFractionDigits: 2, + }, + }, +}, { + "#,##0.00 ¤;(#,##0.00 ¤)", + &Pattern{Affix: "\x00\x04\u00a0¤\x01(\x05\u00a0¤)", + NegOffset: 6, + FormatWidth: 10, + GroupingSize: [2]uint8{3, 0}, + RoundingContext: RoundingContext{ + DigitShift: 0, + MinIntegerDigits: 1, + MinFractionDigits: 2, + MaxFractionDigits: 2, + }, + }, +}, { + // padding + "*x#", + &Pattern{ + PadRune: 'x', + FormatWidth: 1, + }, +}, { + // padding + "#*x", + &Pattern{ + PadRune: 'x', + FormatWidth: 1, + Flags: PadBeforeSuffix, + }, +}, { + "*xpre#suf", + &Pattern{ + Affix: "\x03pre\x03suf", + PadRune: 'x', + FormatWidth: 7, + }, +}, { + "pre*x#suf", + &Pattern{ + Affix: "\x03pre\x03suf", + PadRune: 'x', + FormatWidth: 7, + Flags: PadAfterPrefix, + }, +}, { + "pre#*xsuf", + &Pattern{ + Affix: "\x03pre\x03suf", + PadRune: 'x', + FormatWidth: 7, + Flags: PadBeforeSuffix, + }, +}, { + "pre#suf*x", + &Pattern{ + Affix: "\x03pre\x03suf", + PadRune: 'x', + FormatWidth: 7, + Flags: PadAfterSuffix, + }, +}, { + `* #0 o''clock`, + &Pattern{Affix: "\x00\x09 o\\'clock", + FormatWidth: 10, + PadRune: 32, + RoundingContext: RoundingContext{ + MinIntegerDigits: 0x1, + }, + }, +}, { + `'123'* #0'456'`, + &Pattern{Affix: "\x05'123'\x05'456'", + FormatWidth: 8, + PadRune: 32, + RoundingContext: RoundingContext{ + MinIntegerDigits: 0x1, + }, + Flags: PadAfterPrefix}, +}, { + // no duplicate padding + "*xpre#suf*x", nil, +}, { + // no duplicate padding + "*xpre#suf*x", nil, +}} + +func TestParsePattern(t *testing.T) { + for i, tc := range testCases { + t.Run(tc.pat, func(t *testing.T) { + f, err := ParsePattern(tc.pat) + if !reflect.DeepEqual(f, tc.want) { + t.Errorf("%d:%s:\ngot %#v;\nwant %#v", i, tc.pat, f, tc.want) + } + if got, want := err != nil, tc.want == nil; got != want { + t.Errorf("%d:%s:error: got %v; want %v", i, tc.pat, err, want) + } + }) + } +} + +func TestPatternSize(t *testing.T) { + if sz := unsafe.Sizeof(Pattern{}); sz > 56 { + t.Errorf("got %d; want <= 56", sz) + } + +} diff --git a/vendor/golang.org/x/text/internal/number/roundingmode_string.go b/vendor/golang.org/x/text/internal/number/roundingmode_string.go new file mode 100644 index 0000000..f264ea5 --- /dev/null +++ b/vendor/golang.org/x/text/internal/number/roundingmode_string.go @@ -0,0 +1,16 @@ +// Code generated by "stringer -type RoundingMode"; DO NOT EDIT. + +package number + +import "fmt" + +const _RoundingMode_name = "ToNearestEvenToNearestZeroToNearestAwayToPositiveInfToNegativeInfToZeroAwayFromZeronumModes" + +var _RoundingMode_index = [...]uint8{0, 13, 26, 39, 52, 65, 71, 83, 91} + +func (i RoundingMode) String() string { + if i >= RoundingMode(len(_RoundingMode_index)-1) { + return fmt.Sprintf("RoundingMode(%d)", i) + } + return _RoundingMode_name[_RoundingMode_index[i]:_RoundingMode_index[i+1]] +} diff --git a/vendor/golang.org/x/text/internal/number/tables.go b/vendor/golang.org/x/text/internal/number/tables.go new file mode 100644 index 0000000..56a897b --- /dev/null +++ b/vendor/golang.org/x/text/internal/number/tables.go @@ -0,0 +1,1211 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +package number + +import "golang.org/x/text/internal/stringset" + +// CLDRVersion is the CLDR version from which the tables in this package are derived. +const CLDRVersion = "32" + +var numSysData = []systemData{ // 59 elements + 0: {id: 0x0, digitSize: 0x1, zero: [4]uint8{0x30, 0x0, 0x0, 0x0}}, + 1: {id: 0x1, digitSize: 0x4, zero: [4]uint8{0xf0, 0x9e, 0xa5, 0x90}}, + 2: {id: 0x2, digitSize: 0x4, zero: [4]uint8{0xf0, 0x91, 0x9c, 0xb0}}, + 3: {id: 0x3, digitSize: 0x2, zero: [4]uint8{0xd9, 0xa0, 0x0, 0x0}}, + 4: {id: 0x4, digitSize: 0x2, zero: [4]uint8{0xdb, 0xb0, 0x0, 0x0}}, + 5: {id: 0x5, digitSize: 0x3, zero: [4]uint8{0xe1, 0xad, 0x90, 0x0}}, + 6: {id: 0x6, digitSize: 0x3, zero: [4]uint8{0xe0, 0xa7, 0xa6, 0x0}}, + 7: {id: 0x7, digitSize: 0x4, zero: [4]uint8{0xf0, 0x91, 0xb1, 0x90}}, + 8: {id: 0x8, digitSize: 0x4, zero: [4]uint8{0xf0, 0x91, 0x81, 0xa6}}, + 9: {id: 0x9, digitSize: 0x4, zero: [4]uint8{0xf0, 0x91, 0x84, 0xb6}}, + 10: {id: 0xa, digitSize: 0x3, zero: [4]uint8{0xea, 0xa9, 0x90, 0x0}}, + 11: {id: 0xb, digitSize: 0x3, zero: [4]uint8{0xe0, 0xa5, 0xa6, 0x0}}, + 12: {id: 0xc, digitSize: 0x3, zero: [4]uint8{0xef, 0xbc, 0x90, 0x0}}, + 13: {id: 0xd, digitSize: 0x4, zero: [4]uint8{0xf0, 0x91, 0xb5, 0x90}}, + 14: {id: 0xe, digitSize: 0x3, zero: [4]uint8{0xe0, 0xab, 0xa6, 0x0}}, + 15: {id: 0xf, digitSize: 0x3, zero: [4]uint8{0xe0, 0xa9, 0xa6, 0x0}}, + 16: {id: 0x10, digitSize: 0x4, zero: [4]uint8{0xf0, 0x96, 0xad, 0x90}}, + 17: {id: 0x11, digitSize: 0x3, zero: [4]uint8{0xea, 0xa7, 0x90, 0x0}}, + 18: {id: 0x12, digitSize: 0x3, zero: [4]uint8{0xea, 0xa4, 0x80, 0x0}}, + 19: {id: 0x13, digitSize: 0x3, zero: [4]uint8{0xe1, 0x9f, 0xa0, 0x0}}, + 20: {id: 0x14, digitSize: 0x3, zero: [4]uint8{0xe0, 0xb3, 0xa6, 0x0}}, + 21: {id: 0x15, digitSize: 0x3, zero: [4]uint8{0xe1, 0xaa, 0x80, 0x0}}, + 22: {id: 0x16, digitSize: 0x3, zero: [4]uint8{0xe1, 0xaa, 0x90, 0x0}}, + 23: {id: 0x17, digitSize: 0x3, zero: [4]uint8{0xe0, 0xbb, 0x90, 0x0}}, + 24: {id: 0x18, digitSize: 0x3, zero: [4]uint8{0xe1, 0xb1, 0x80, 0x0}}, + 25: {id: 0x19, digitSize: 0x3, zero: [4]uint8{0xe1, 0xa5, 0x86, 0x0}}, + 26: {id: 0x1a, digitSize: 0x4, zero: [4]uint8{0xf0, 0x9d, 0x9f, 0x8e}}, + 27: {id: 0x1b, digitSize: 0x4, zero: [4]uint8{0xf0, 0x9d, 0x9f, 0x98}}, + 28: {id: 0x1c, digitSize: 0x4, zero: [4]uint8{0xf0, 0x9d, 0x9f, 0xb6}}, + 29: {id: 0x1d, digitSize: 0x4, zero: [4]uint8{0xf0, 0x9d, 0x9f, 0xac}}, + 30: {id: 0x1e, digitSize: 0x4, zero: [4]uint8{0xf0, 0x9d, 0x9f, 0xa2}}, + 31: {id: 0x1f, digitSize: 0x3, zero: [4]uint8{0xe0, 0xb5, 0xa6, 0x0}}, + 32: {id: 0x20, digitSize: 0x4, zero: [4]uint8{0xf0, 0x91, 0x99, 0x90}}, + 33: {id: 0x21, digitSize: 0x3, zero: [4]uint8{0xe1, 0xa0, 0x90, 0x0}}, + 34: {id: 0x22, digitSize: 0x4, zero: [4]uint8{0xf0, 0x96, 0xa9, 0xa0}}, + 35: {id: 0x23, digitSize: 0x3, zero: [4]uint8{0xea, 0xaf, 0xb0, 0x0}}, + 36: {id: 0x24, digitSize: 0x3, zero: [4]uint8{0xe1, 0x81, 0x80, 0x0}}, + 37: {id: 0x25, digitSize: 0x3, zero: [4]uint8{0xe1, 0x82, 0x90, 0x0}}, + 38: {id: 0x26, digitSize: 0x3, zero: [4]uint8{0xea, 0xa7, 0xb0, 0x0}}, + 39: {id: 0x27, digitSize: 0x4, zero: [4]uint8{0xf0, 0x91, 0x91, 0x90}}, + 40: {id: 0x28, digitSize: 0x2, zero: [4]uint8{0xdf, 0x80, 0x0, 0x0}}, + 41: {id: 0x29, digitSize: 0x3, zero: [4]uint8{0xe1, 0xb1, 0x90, 0x0}}, + 42: {id: 0x2a, digitSize: 0x3, zero: [4]uint8{0xe0, 0xad, 0xa6, 0x0}}, + 43: {id: 0x2b, digitSize: 0x4, zero: [4]uint8{0xf0, 0x90, 0x92, 0xa0}}, + 44: {id: 0x2c, digitSize: 0x3, zero: [4]uint8{0xea, 0xa3, 0x90, 0x0}}, + 45: {id: 0x2d, digitSize: 0x4, zero: [4]uint8{0xf0, 0x91, 0x87, 0x90}}, + 46: {id: 0x2e, digitSize: 0x4, zero: [4]uint8{0xf0, 0x91, 0x8b, 0xb0}}, + 47: {id: 0x2f, digitSize: 0x3, zero: [4]uint8{0xe0, 0xb7, 0xa6, 0x0}}, + 48: {id: 0x30, digitSize: 0x4, zero: [4]uint8{0xf0, 0x91, 0x83, 0xb0}}, + 49: {id: 0x31, digitSize: 0x3, zero: [4]uint8{0xe1, 0xae, 0xb0, 0x0}}, + 50: {id: 0x32, digitSize: 0x4, zero: [4]uint8{0xf0, 0x91, 0x9b, 0x80}}, + 51: {id: 0x33, digitSize: 0x3, zero: [4]uint8{0xe1, 0xa7, 0x90, 0x0}}, + 52: {id: 0x34, digitSize: 0x3, zero: [4]uint8{0xe0, 0xaf, 0xa6, 0x0}}, + 53: {id: 0x35, digitSize: 0x3, zero: [4]uint8{0xe0, 0xb1, 0xa6, 0x0}}, + 54: {id: 0x36, digitSize: 0x3, zero: [4]uint8{0xe0, 0xb9, 0x90, 0x0}}, + 55: {id: 0x37, digitSize: 0x3, zero: [4]uint8{0xe0, 0xbc, 0xa0, 0x0}}, + 56: {id: 0x38, digitSize: 0x4, zero: [4]uint8{0xf0, 0x91, 0x93, 0x90}}, + 57: {id: 0x39, digitSize: 0x3, zero: [4]uint8{0xea, 0x98, 0xa0, 0x0}}, + 58: {id: 0x3a, digitSize: 0x4, zero: [4]uint8{0xf0, 0x91, 0xa3, 0xa0}}, +} // Size: 378 bytes + +const ( + numAdlm = 0x1 + numAhom = 0x2 + numArab = 0x3 + numArabext = 0x4 + numArmn = 0x3b + numArmnlow = 0x3c + numBali = 0x5 + numBeng = 0x6 + numBhks = 0x7 + numBrah = 0x8 + numCakm = 0x9 + numCham = 0xa + numCyrl = 0x3d + numDeva = 0xb + numEthi = 0x3e + numFullwide = 0xc + numGeor = 0x3f + numGonm = 0xd + numGrek = 0x40 + numGreklow = 0x41 + numGujr = 0xe + numGuru = 0xf + numHanidays = 0x42 + numHanidec = 0x43 + numHans = 0x44 + numHansfin = 0x45 + numHant = 0x46 + numHantfin = 0x47 + numHebr = 0x48 + numHmng = 0x10 + numJava = 0x11 + numJpan = 0x49 + numJpanfin = 0x4a + numKali = 0x12 + numKhmr = 0x13 + numKnda = 0x14 + numLana = 0x15 + numLanatham = 0x16 + numLaoo = 0x17 + numLatn = 0x0 + numLepc = 0x18 + numLimb = 0x19 + numMathbold = 0x1a + numMathdbl = 0x1b + numMathmono = 0x1c + numMathsanb = 0x1d + numMathsans = 0x1e + numMlym = 0x1f + numModi = 0x20 + numMong = 0x21 + numMroo = 0x22 + numMtei = 0x23 + numMymr = 0x24 + numMymrshan = 0x25 + numMymrtlng = 0x26 + numNewa = 0x27 + numNkoo = 0x28 + numOlck = 0x29 + numOrya = 0x2a + numOsma = 0x2b + numRoman = 0x4b + numRomanlow = 0x4c + numSaur = 0x2c + numShrd = 0x2d + numSind = 0x2e + numSinh = 0x2f + numSora = 0x30 + numSund = 0x31 + numTakr = 0x32 + numTalu = 0x33 + numTaml = 0x4d + numTamldec = 0x34 + numTelu = 0x35 + numThai = 0x36 + numTibt = 0x37 + numTirh = 0x38 + numVaii = 0x39 + numWara = 0x3a + numNumberSystems +) + +var systemMap = map[string]system{ + "adlm": numAdlm, + "ahom": numAhom, + "arab": numArab, + "arabext": numArabext, + "armn": numArmn, + "armnlow": numArmnlow, + "bali": numBali, + "beng": numBeng, + "bhks": numBhks, + "brah": numBrah, + "cakm": numCakm, + "cham": numCham, + "cyrl": numCyrl, + "deva": numDeva, + "ethi": numEthi, + "fullwide": numFullwide, + "geor": numGeor, + "gonm": numGonm, + "grek": numGrek, + "greklow": numGreklow, + "gujr": numGujr, + "guru": numGuru, + "hanidays": numHanidays, + "hanidec": numHanidec, + "hans": numHans, + "hansfin": numHansfin, + "hant": numHant, + "hantfin": numHantfin, + "hebr": numHebr, + "hmng": numHmng, + "java": numJava, + "jpan": numJpan, + "jpanfin": numJpanfin, + "kali": numKali, + "khmr": numKhmr, + "knda": numKnda, + "lana": numLana, + "lanatham": numLanatham, + "laoo": numLaoo, + "latn": numLatn, + "lepc": numLepc, + "limb": numLimb, + "mathbold": numMathbold, + "mathdbl": numMathdbl, + "mathmono": numMathmono, + "mathsanb": numMathsanb, + "mathsans": numMathsans, + "mlym": numMlym, + "modi": numModi, + "mong": numMong, + "mroo": numMroo, + "mtei": numMtei, + "mymr": numMymr, + "mymrshan": numMymrshan, + "mymrtlng": numMymrtlng, + "newa": numNewa, + "nkoo": numNkoo, + "olck": numOlck, + "orya": numOrya, + "osma": numOsma, + "roman": numRoman, + "romanlow": numRomanlow, + "saur": numSaur, + "shrd": numShrd, + "sind": numSind, + "sinh": numSinh, + "sora": numSora, + "sund": numSund, + "takr": numTakr, + "talu": numTalu, + "taml": numTaml, + "tamldec": numTamldec, + "telu": numTelu, + "thai": numThai, + "tibt": numTibt, + "tirh": numTirh, + "vaii": numVaii, + "wara": numWara, +} + +var symIndex = [][12]uint8{ // 81 elements + 0: [12]uint8{0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb}, + 1: [12]uint8{0x1, 0xc, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb}, + 2: [12]uint8{0x0, 0x1, 0x2, 0xd, 0xe, 0xf, 0x6, 0x7, 0x8, 0x9, 0x10, 0xb}, + 3: [12]uint8{0x1, 0x0, 0x2, 0xd, 0xe, 0xf, 0x6, 0x7, 0x8, 0x9, 0x10, 0xb}, + 4: [12]uint8{0x0, 0x1, 0x2, 0x11, 0xe, 0xf, 0x6, 0x7, 0x8, 0x9, 0x10, 0xb}, + 5: [12]uint8{0x1, 0x0, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x12, 0xb}, + 6: [12]uint8{0x1, 0x0, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb}, + 7: [12]uint8{0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x13, 0xb}, + 8: [12]uint8{0x0, 0x1, 0x2, 0x3, 0xe, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb}, + 9: [12]uint8{0x1, 0x0, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0x0}, + 10: [12]uint8{0x1, 0x0, 0x2, 0x3, 0x4, 0x5, 0x6, 0x14, 0x8, 0x9, 0xa, 0xb}, + 11: [12]uint8{0x1, 0xc, 0x2, 0x3, 0x4, 0x5, 0x6, 0x14, 0x8, 0x9, 0xa, 0xb}, + 12: [12]uint8{0x0, 0x15, 0x2, 0x3, 0x4, 0x5, 0x6, 0x14, 0x8, 0x9, 0xa, 0xb}, + 13: [12]uint8{0x0, 0xc, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb}, + 14: [12]uint8{0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x16, 0xb}, + 15: [12]uint8{0x1, 0x0, 0x2, 0x3, 0x4, 0x5, 0x17, 0x7, 0x8, 0x9, 0xa, 0xb}, + 16: [12]uint8{0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x17, 0x7, 0x8, 0x9, 0xa, 0x0}, + 17: [12]uint8{0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x17, 0x7, 0x8, 0x9, 0xa, 0xb}, + 18: [12]uint8{0x1, 0xc, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0x0}, + 19: [12]uint8{0x1, 0xc, 0x2, 0x3, 0x4, 0x5, 0x18, 0x7, 0x8, 0x9, 0xa, 0xb}, + 20: [12]uint8{0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x19, 0x1a, 0xa, 0xb}, + 21: [12]uint8{0x1, 0xc, 0x2, 0x3, 0x4, 0x1b, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb}, + 22: [12]uint8{0x1, 0xc, 0x2, 0x3, 0x4, 0x1b, 0x18, 0x7, 0x8, 0x9, 0xa, 0xb}, + 23: [12]uint8{0x1, 0x0, 0x2, 0x3, 0x4, 0x1b, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb}, + 24: [12]uint8{0x0, 0x1, 0x2, 0x3, 0xe, 0x1c, 0x6, 0x7, 0x8, 0x9, 0x1d, 0xb}, + 25: [12]uint8{0x1, 0xc, 0x2, 0x3, 0x4, 0x1b, 0x6, 0x7, 0x8, 0x9, 0x1e, 0x0}, + 26: [12]uint8{0x0, 0x15, 0x2, 0x3, 0x4, 0x1b, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb}, + 27: [12]uint8{0x0, 0x1, 0x2, 0x3, 0xe, 0xf, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb}, + 28: [12]uint8{0x1, 0xc, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x1f, 0xb}, + 29: [12]uint8{0x0, 0x15, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb}, + 30: [12]uint8{0x1, 0xc, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x20, 0xb}, + 31: [12]uint8{0x1, 0xc, 0x2, 0x3, 0x4, 0x5, 0x21, 0x7, 0x8, 0x9, 0x22, 0xb}, + 32: [12]uint8{0x1, 0xc, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x23, 0xb}, + 33: [12]uint8{0x1, 0x0, 0x2, 0x3, 0x4, 0x1b, 0x18, 0x14, 0x8, 0x9, 0x24, 0xb}, + 34: [12]uint8{0x1, 0xc, 0x2, 0x3, 0x4, 0x1b, 0x18, 0x7, 0x8, 0x9, 0x24, 0xb}, + 35: [12]uint8{0x1, 0xc, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x25, 0xb}, + 36: [12]uint8{0x1, 0x0, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x26, 0xb}, + 37: [12]uint8{0x1, 0xc, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x27, 0xb}, + 38: [12]uint8{0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x28, 0xb}, + 39: [12]uint8{0x1, 0xc, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x29, 0xb}, + 40: [12]uint8{0x1, 0x0, 0x2, 0x3, 0xe, 0x1c, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb}, + 41: [12]uint8{0x1, 0xc, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x2a, 0xb}, + 42: [12]uint8{0x1, 0xc, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x2b, 0xb}, + 43: [12]uint8{0x1, 0xc, 0x2, 0x3, 0x4, 0x1b, 0x2c, 0x14, 0x8, 0x9, 0x24, 0xb}, + 44: [12]uint8{0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0x0}, + 45: [12]uint8{0x1, 0xc, 0x2, 0x3, 0x4, 0x5, 0x17, 0x7, 0x8, 0x9, 0xa, 0xb}, + 46: [12]uint8{0x1, 0x0, 0x2, 0x3, 0x4, 0x1b, 0x17, 0x7, 0x8, 0x9, 0xa, 0xb}, + 47: [12]uint8{0x1, 0xc, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x2d, 0x0}, + 48: [12]uint8{0x1, 0xc, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x2e, 0xb}, + 49: [12]uint8{0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x2f, 0xb}, + 50: [12]uint8{0x1, 0xc, 0x2, 0x3, 0x4, 0x5, 0x30, 0x7, 0x8, 0x9, 0xa, 0xb}, + 51: [12]uint8{0x1, 0xc, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x31, 0xb}, + 52: [12]uint8{0x1, 0xc, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x32, 0xb}, + 53: [12]uint8{0x1, 0x15, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb}, + 54: [12]uint8{0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x33, 0xb}, + 55: [12]uint8{0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x34, 0xb}, + 56: [12]uint8{0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x7, 0x3c, 0x9, 0xa, 0xb}, + 57: [12]uint8{0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x7, 0x3c, 0x9, 0x3d, 0xb}, + 58: [12]uint8{0x35, 0x36, 0x37, 0x11, 0x3e, 0x3f, 0x3b, 0x7, 0x3c, 0x9, 0xa, 0xb}, + 59: [12]uint8{0x35, 0x36, 0x37, 0x11, 0x39, 0x3a, 0x3b, 0x7, 0x3c, 0x9, 0xa, 0xb}, + 60: [12]uint8{0x35, 0x36, 0x37, 0x11, 0x39, 0x40, 0x3b, 0x7, 0x3c, 0x9, 0xa, 0xb}, + 61: [12]uint8{0x35, 0x36, 0x37, 0x41, 0x3e, 0x3f, 0x3b, 0x7, 0x3c, 0x9, 0xa, 0xb}, + 62: [12]uint8{0x35, 0x36, 0x37, 0x38, 0x3e, 0x3f, 0x3b, 0x7, 0x3c, 0x9, 0xa, 0xb}, + 63: [12]uint8{0x35, 0xc, 0x37, 0x38, 0x39, 0x42, 0x3b, 0x7, 0x3c, 0x9, 0xa, 0x0}, + 64: [12]uint8{0x35, 0xc, 0x37, 0x38, 0x39, 0x42, 0x43, 0x7, 0x44, 0x9, 0x24, 0xb}, + 65: [12]uint8{0x35, 0x36, 0x37, 0x38, 0x39, 0x5, 0x3b, 0x7, 0x3c, 0x9, 0x33, 0xb}, + 66: [12]uint8{0x35, 0x36, 0x37, 0x11, 0x45, 0x46, 0x43, 0x7, 0x3c, 0x9, 0xa, 0x35}, + 67: [12]uint8{0x35, 0x36, 0x37, 0x11, 0xe, 0x1c, 0x43, 0x7, 0x3c, 0x9, 0x1d, 0xb}, + 68: [12]uint8{0x35, 0x36, 0x37, 0x11, 0xe, 0x1c, 0x43, 0x7, 0x3c, 0x9, 0xa, 0x35}, + 69: [12]uint8{0x35, 0x36, 0x37, 0x11, 0x45, 0x5, 0x43, 0x7, 0x3c, 0x9, 0xa, 0x35}, + 70: [12]uint8{0x1, 0xc, 0x37, 0x11, 0x45, 0x47, 0x43, 0x7, 0x3c, 0x9, 0xa, 0x0}, + 71: [12]uint8{0x35, 0x1, 0x37, 0x11, 0x4, 0x5, 0x43, 0x7, 0x3c, 0x9, 0xa, 0x35}, + 72: [12]uint8{0x1, 0xc, 0x37, 0x11, 0x45, 0x47, 0x43, 0x7, 0x3c, 0x9, 0x24, 0xb}, + 73: [12]uint8{0x35, 0x36, 0x2, 0x3, 0x45, 0x46, 0x43, 0x7, 0x8, 0x9, 0xa, 0x35}, + 74: [12]uint8{0x35, 0x36, 0x37, 0x11, 0x4, 0x5, 0x43, 0x7, 0x3c, 0x9, 0x31, 0x35}, + 75: [12]uint8{0x35, 0x36, 0x37, 0x11, 0x4, 0x5, 0x43, 0x7, 0x3c, 0x9, 0x32, 0x35}, + 76: [12]uint8{0x35, 0x36, 0x37, 0x11, 0x48, 0x46, 0x43, 0x7, 0x3c, 0x9, 0x33, 0x35}, + 77: [12]uint8{0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0x49}, + 78: [12]uint8{0x0, 0x1, 0x4a, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x28, 0xb}, + 79: [12]uint8{0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x4b, 0xb}, + 80: [12]uint8{0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x4c, 0x4d, 0xb}, +} // Size: 996 bytes + +var symData = stringset.Set{ + Data: "" + // Size: 599 bytes + ".,;%+-E׉∞NaN:\u00a0\u200e%\u200e\u200e+\u200e-ليس\u00a0رقمًا٪NDТерхьаш" + + "\u00a0дац·’mnne×10^0/00INF−\u200e−ناعددepälukuՈչԹარ\u00a0არის\u00a0რიცხვ" + + "იZMdMсан\u00a0емес¤¤¤сан\u00a0эмесບໍ່\u200bແມ່ນ\u200bໂຕ\u200bເລກNSဂဏန်" + + "းမဟုတ်သောННне\u00a0числочыыһыла\u00a0буотах·10^epilohosan\u00a0dälTFЕs" + + "on\u00a0emasҳақиқий\u00a0сон\u00a0эмас非數值非数值٫٬؛٪\u061c\u061c+\u061c-اس؉ل" + + "يس\u00a0رقم\u200f+\u200f-\u200f−٪\u200f\u061c−×۱۰^؉\u200f\u200e+\u200e" + + "\u200e-\u200e\u200e−\u200e+\u200e:၊ཨང་མེན་གྲངས་མེདཨང་མད", + Index: []uint16{ // 79 elements + // Entry 0 - 3F + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0009, 0x000c, 0x000f, 0x0012, 0x0013, 0x0015, 0x001c, 0x0020, + 0x0024, 0x0036, 0x0038, 0x003a, 0x0050, 0x0052, 0x0055, 0x0058, + 0x0059, 0x005e, 0x0062, 0x0065, 0x0068, 0x006e, 0x0078, 0x0080, + 0x0086, 0x00ae, 0x00af, 0x00b2, 0x00c2, 0x00c8, 0x00d8, 0x0105, + 0x0107, 0x012e, 0x0132, 0x0142, 0x015e, 0x0163, 0x016a, 0x0173, + 0x0175, 0x0177, 0x0180, 0x01a0, 0x01a9, 0x01b2, 0x01b4, 0x01b6, + 0x01b8, 0x01bc, 0x01bf, 0x01c2, 0x01c6, 0x01c8, 0x01d6, 0x01da, + // Entry 40 - 7F + 0x01de, 0x01e4, 0x01e9, 0x01ee, 0x01f5, 0x01fa, 0x0201, 0x0208, + 0x0211, 0x0215, 0x0218, 0x021b, 0x0230, 0x0248, 0x0257, + }, +} // Size: 797 bytes + +// langToDefaults maps a compact language index to the default numbering system +// and default symbol set +var langToDefaults = [768]symOffset{ + // Entry 0 - 3F + 0x8000, 0x0006, 0x0014, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8003, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0003, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0002, 0x0003, 0x0003, 0x0003, 0x0003, 0x0002, 0x0002, + 0x0002, 0x0004, 0x0002, 0x0004, 0x0002, 0x0002, 0x0002, 0x0003, + 0x0002, 0x0000, 0x8005, 0x0000, 0x0000, 0x0000, 0x8006, 0x0005, + 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0001, 0x0000, + // Entry 40 - 7F + 0x0000, 0x0000, 0x8009, 0x0000, 0x0000, 0x800a, 0x0000, 0x0000, + 0x800c, 0x0001, 0x0000, 0x0000, 0x0006, 0x0006, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x800e, 0x0000, + 0x0000, 0x0007, 0x0007, 0x0000, 0x0000, 0x0000, 0x0000, 0x800f, + 0x0008, 0x0008, 0x8011, 0x0001, 0x0001, 0x0001, 0x803c, 0x0000, + 0x0009, 0x0009, 0x0009, 0x0000, 0x0000, 0x000a, 0x000b, 0x000a, + 0x000c, 0x000a, 0x000a, 0x000c, 0x000a, 0x000d, 0x000d, 0x000a, + 0x000a, 0x0001, 0x0001, 0x0000, 0x0001, 0x0001, 0x803f, 0x0000, + // Entry 80 - BF + 0x0000, 0x0000, 0x000e, 0x000e, 0x000e, 0x000f, 0x000f, 0x000f, + 0x0000, 0x0000, 0x0006, 0x0000, 0x0000, 0x0000, 0x000a, 0x0010, + 0x0000, 0x0006, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0011, + 0x0000, 0x000a, 0x0000, 0x0000, 0x0000, 0x0000, 0x000a, 0x0000, + 0x0009, 0x0000, 0x0000, 0x0012, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // Entry C0 - FF + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0006, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0013, 0x0000, 0x0000, 0x000f, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000, + 0x0000, 0x0015, 0x0015, 0x0006, 0x0000, 0x0006, 0x0006, 0x0000, + 0x0000, 0x0006, 0x0006, 0x0001, 0x0000, 0x0000, 0x0006, 0x0006, + // Entry 100 - 13F + 0x0006, 0x0006, 0x0000, 0x0000, 0x0006, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0006, 0x0000, 0x0006, 0x0000, 0x0000, 0x0006, 0x0006, + 0x0016, 0x0016, 0x0017, 0x0017, 0x0001, 0x0001, 0x8041, 0x0018, + 0x0018, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0019, 0x0019, + 0x0000, 0x0000, 0x0017, 0x0017, 0x0017, 0x8044, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0006, 0x0006, 0x0001, 0x0001, + // Entry 140 - 17F + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0006, 0x0006, 0x0006, 0x0006, + 0x0000, 0x0000, 0x8047, 0x0000, 0x0006, 0x0006, 0x001a, 0x001a, + 0x001a, 0x001a, 0x804a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x804c, + 0x001b, 0x0000, 0x0000, 0x0006, 0x0006, 0x0006, 0x000a, 0x000a, + 0x0001, 0x0001, 0x001c, 0x001c, 0x0009, 0x0009, 0x804f, 0x0000, + // Entry 180 - 1BF + 0x0000, 0x0000, 0x0000, 0x8052, 0x0006, 0x0006, 0x001d, 0x0006, + 0x0006, 0x0006, 0x0000, 0x0000, 0x0000, 0x0000, 0x0006, 0x0006, + 0x0000, 0x0000, 0x0000, 0x001e, 0x001e, 0x001f, 0x001f, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0001, 0x000d, + 0x000d, 0x0000, 0x0000, 0x0020, 0x0020, 0x0006, 0x0006, 0x0021, + 0x0021, 0x0000, 0x0000, 0x0006, 0x0006, 0x0000, 0x0000, 0x8054, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8056, 0x001b, 0x0000, 0x0000, + 0x0001, 0x0001, 0x0022, 0x0022, 0x0000, 0x0000, 0x0000, 0x0023, + // Entry 1C0 - 1FF + 0x0023, 0x0000, 0x0000, 0x0006, 0x0006, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0024, 0x0024, + 0x8058, 0x0000, 0x0000, 0x0016, 0x0016, 0x0006, 0x0006, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0025, 0x0025, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x000d, 0x000d, 0x0000, 0x0000, 0x0006, 0x0006, + 0x0000, 0x0000, 0x0006, 0x0006, 0x0000, 0x0000, 0x0000, 0x0000, + 0x805a, 0x0000, 0x0000, 0x0006, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0006, 0x0006, 0x805b, 0x0026, 0x805d, 0x0000, 0x0000, 0x0000, + // Entry 200 - 23F + 0x0000, 0x805e, 0x0015, 0x0015, 0x0000, 0x0000, 0x0006, 0x0006, + 0x0006, 0x8061, 0x0000, 0x0000, 0x8062, 0x0006, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0006, 0x0001, 0x0001, 0x0015, 0x0015, + 0x0006, 0x0006, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0027, 0x0027, 0x0027, 0x8065, 0x8067, 0x001b, 0x0000, 0x0000, + 0x0000, 0x0001, 0x0001, 0x0001, 0x0001, 0x8069, 0x0028, 0x0006, + 0x0001, 0x0006, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + // Entry 240 - 27F + 0x0001, 0x0001, 0x0001, 0x0001, 0x0000, 0x0006, 0x0000, 0x0000, + 0x001a, 0x001a, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0000, + 0x0000, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, 0x0029, + 0x0006, 0x0006, 0x0000, 0x0000, 0x002a, 0x002a, 0x0000, 0x0000, + 0x0000, 0x0000, 0x806b, 0x0000, 0x0000, 0x002b, 0x002b, 0x002b, + 0x002b, 0x0006, 0x0006, 0x000d, 0x000d, 0x0006, 0x0006, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x002c, 0x002c, 0x002d, 0x002d, + 0x002e, 0x002e, 0x0000, 0x0000, 0x0000, 0x002f, 0x002f, 0x0000, + // Entry 280 - 2BF + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0000, 0x0000, + 0x0000, 0x806d, 0x0022, 0x0022, 0x0022, 0x0000, 0x0006, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0001, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0030, 0x0030, 0x0000, + 0x8071, 0x0031, 0x0006, 0x0006, 0x0006, 0x0000, 0x0001, 0x0001, + // Entry 2C0 - 2FF + 0x000d, 0x000d, 0x0001, 0x0001, 0x0000, 0x0000, 0x0032, 0x0032, + 0x8074, 0x8076, 0x001b, 0x8077, 0x8079, 0x0028, 0x807b, 0x0034, + 0x0033, 0x0033, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0006, 0x0006, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0035, + 0x0035, 0x0006, 0x0006, 0x0000, 0x0000, 0x0000, 0x0001, 0x0001, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0036, 0x0037, 0x0037, + 0x0036, 0x0036, 0x0001, 0x0001, 0x807d, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8080, 0x0036, 0x0036, 0x0036, 0x0000, 0x0000, +} // Size: 1536 bytes + +// langToAlt is a list of numbering system and symbol set pairs, sorted and +// marked by compact language index. +var langToAlt = []altSymData{ // 131 elements + 1: {compactTag: 0x0, symIndex: 0x38, system: 0x3}, + 2: {compactTag: 0x0, symIndex: 0x42, system: 0x4}, + 3: {compactTag: 0xc, symIndex: 0x39, system: 0x3}, + 4: {compactTag: 0xc, symIndex: 0x2, system: 0x0}, + 5: {compactTag: 0x2a, symIndex: 0x0, system: 0x6}, + 6: {compactTag: 0x2e, symIndex: 0x5, system: 0x0}, + 7: {compactTag: 0x2e, symIndex: 0x3a, system: 0x3}, + 8: {compactTag: 0x2e, symIndex: 0x42, system: 0x4}, + 9: {compactTag: 0x42, symIndex: 0x0, system: 0x6}, + 10: {compactTag: 0x45, symIndex: 0x0, system: 0x0}, + 11: {compactTag: 0x45, symIndex: 0x4f, system: 0x37}, + 12: {compactTag: 0x48, symIndex: 0x1, system: 0x0}, + 13: {compactTag: 0x48, symIndex: 0x38, system: 0x3}, + 14: {compactTag: 0x56, symIndex: 0x0, system: 0x9}, + 15: {compactTag: 0x5f, symIndex: 0x3a, system: 0x3}, + 16: {compactTag: 0x5f, symIndex: 0x8, system: 0x0}, + 17: {compactTag: 0x62, symIndex: 0x1, system: 0x0}, + 18: {compactTag: 0x62, symIndex: 0x38, system: 0x3}, + 19: {compactTag: 0x62, symIndex: 0x42, system: 0x4}, + 20: {compactTag: 0x62, symIndex: 0x0, system: 0x5}, + 21: {compactTag: 0x62, symIndex: 0x0, system: 0x6}, + 22: {compactTag: 0x62, symIndex: 0x0, system: 0x8}, + 23: {compactTag: 0x62, symIndex: 0x0, system: 0x9}, + 24: {compactTag: 0x62, symIndex: 0x0, system: 0xa}, + 25: {compactTag: 0x62, symIndex: 0x0, system: 0xb}, + 26: {compactTag: 0x62, symIndex: 0x0, system: 0xc}, + 27: {compactTag: 0x62, symIndex: 0x0, system: 0xd}, + 28: {compactTag: 0x62, symIndex: 0x0, system: 0xe}, + 29: {compactTag: 0x62, symIndex: 0x0, system: 0xf}, + 30: {compactTag: 0x62, symIndex: 0x0, system: 0x11}, + 31: {compactTag: 0x62, symIndex: 0x0, system: 0x12}, + 32: {compactTag: 0x62, symIndex: 0x0, system: 0x13}, + 33: {compactTag: 0x62, symIndex: 0x0, system: 0x14}, + 34: {compactTag: 0x62, symIndex: 0x0, system: 0x15}, + 35: {compactTag: 0x62, symIndex: 0x0, system: 0x16}, + 36: {compactTag: 0x62, symIndex: 0x0, system: 0x17}, + 37: {compactTag: 0x62, symIndex: 0x0, system: 0x18}, + 38: {compactTag: 0x62, symIndex: 0x0, system: 0x19}, + 39: {compactTag: 0x62, symIndex: 0x0, system: 0x1f}, + 40: {compactTag: 0x62, symIndex: 0x0, system: 0x21}, + 41: {compactTag: 0x62, symIndex: 0x0, system: 0x23}, + 42: {compactTag: 0x62, symIndex: 0x0, system: 0x24}, + 43: {compactTag: 0x62, symIndex: 0x0, system: 0x25}, + 44: {compactTag: 0x62, symIndex: 0x0, system: 0x28}, + 45: {compactTag: 0x62, symIndex: 0x0, system: 0x29}, + 46: {compactTag: 0x62, symIndex: 0x0, system: 0x2a}, + 47: {compactTag: 0x62, symIndex: 0x0, system: 0x2b}, + 48: {compactTag: 0x62, symIndex: 0x0, system: 0x2c}, + 49: {compactTag: 0x62, symIndex: 0x0, system: 0x2d}, + 50: {compactTag: 0x62, symIndex: 0x0, system: 0x30}, + 51: {compactTag: 0x62, symIndex: 0x0, system: 0x31}, + 52: {compactTag: 0x62, symIndex: 0x0, system: 0x32}, + 53: {compactTag: 0x62, symIndex: 0x0, system: 0x33}, + 54: {compactTag: 0x62, symIndex: 0x0, system: 0x34}, + 55: {compactTag: 0x62, symIndex: 0x0, system: 0x35}, + 56: {compactTag: 0x62, symIndex: 0x0, system: 0x36}, + 57: {compactTag: 0x62, symIndex: 0x0, system: 0x37}, + 58: {compactTag: 0x62, symIndex: 0x0, system: 0x39}, + 59: {compactTag: 0x62, symIndex: 0x0, system: 0x43}, + 60: {compactTag: 0x66, symIndex: 0x0, system: 0x0}, + 61: {compactTag: 0x66, symIndex: 0x38, system: 0x3}, + 62: {compactTag: 0x66, symIndex: 0x42, system: 0x4}, + 63: {compactTag: 0x7e, symIndex: 0x50, system: 0x37}, + 64: {compactTag: 0x7e, symIndex: 0x0, system: 0x0}, + 65: {compactTag: 0x116, symIndex: 0x43, system: 0x4}, + 66: {compactTag: 0x116, symIndex: 0x18, system: 0x0}, + 67: {compactTag: 0x116, symIndex: 0x3b, system: 0x3}, + 68: {compactTag: 0x125, symIndex: 0x1, system: 0x0}, + 69: {compactTag: 0x125, symIndex: 0x3c, system: 0x3}, + 70: {compactTag: 0x125, symIndex: 0x44, system: 0x4}, + 71: {compactTag: 0x15a, symIndex: 0x0, system: 0x0}, + 72: {compactTag: 0x15a, symIndex: 0x3b, system: 0x3}, + 73: {compactTag: 0x15a, symIndex: 0x45, system: 0x4}, + 74: {compactTag: 0x162, symIndex: 0x0, system: 0x0}, + 75: {compactTag: 0x162, symIndex: 0x38, system: 0x3}, + 76: {compactTag: 0x16f, symIndex: 0x1b, system: 0x0}, + 77: {compactTag: 0x16f, symIndex: 0x0, system: 0x9}, + 78: {compactTag: 0x16f, symIndex: 0x0, system: 0xa}, + 79: {compactTag: 0x17e, symIndex: 0x0, system: 0x0}, + 80: {compactTag: 0x17e, symIndex: 0x3d, system: 0x3}, + 81: {compactTag: 0x17e, symIndex: 0x42, system: 0x4}, + 82: {compactTag: 0x183, symIndex: 0x6, system: 0x0}, + 83: {compactTag: 0x183, symIndex: 0x38, system: 0x3}, + 84: {compactTag: 0x1af, symIndex: 0x0, system: 0x0}, + 85: {compactTag: 0x1af, symIndex: 0x3e, system: 0x3}, + 86: {compactTag: 0x1b4, symIndex: 0x42, system: 0x4}, + 87: {compactTag: 0x1b4, symIndex: 0x1b, system: 0x0}, + 88: {compactTag: 0x1d0, symIndex: 0x42, system: 0x4}, + 89: {compactTag: 0x1d0, symIndex: 0x0, system: 0x0}, + 90: {compactTag: 0x1f0, symIndex: 0x0, system: 0xb}, + 91: {compactTag: 0x1fa, symIndex: 0x4e, system: 0x24}, + 92: {compactTag: 0x1fa, symIndex: 0x26, system: 0x0}, + 93: {compactTag: 0x1fc, symIndex: 0x42, system: 0x4}, + 94: {compactTag: 0x201, symIndex: 0x15, system: 0x0}, + 95: {compactTag: 0x201, symIndex: 0x3f, system: 0x3}, + 96: {compactTag: 0x201, symIndex: 0x46, system: 0x4}, + 97: {compactTag: 0x209, symIndex: 0x0, system: 0xb}, + 98: {compactTag: 0x20c, symIndex: 0x6, system: 0x0}, + 99: {compactTag: 0x20c, symIndex: 0x38, system: 0x3}, + 100: {compactTag: 0x20c, symIndex: 0x42, system: 0x4}, + 101: {compactTag: 0x22b, symIndex: 0x0, system: 0x0}, + 102: {compactTag: 0x22b, symIndex: 0x47, system: 0x4}, + 103: {compactTag: 0x22c, symIndex: 0x42, system: 0x4}, + 104: {compactTag: 0x22c, symIndex: 0x1b, system: 0x0}, + 105: {compactTag: 0x235, symIndex: 0x42, system: 0x4}, + 106: {compactTag: 0x235, symIndex: 0x28, system: 0x0}, + 107: {compactTag: 0x262, symIndex: 0x38, system: 0x3}, + 108: {compactTag: 0x262, symIndex: 0x0, system: 0x0}, + 109: {compactTag: 0x299, symIndex: 0x22, system: 0x0}, + 110: {compactTag: 0x299, symIndex: 0x40, system: 0x3}, + 111: {compactTag: 0x299, symIndex: 0x48, system: 0x4}, + 112: {compactTag: 0x299, symIndex: 0x4d, system: 0xc}, + 113: {compactTag: 0x2b8, symIndex: 0x31, system: 0x0}, + 114: {compactTag: 0x2b8, symIndex: 0x3e, system: 0x3}, + 115: {compactTag: 0x2b8, symIndex: 0x42, system: 0x4}, + 116: {compactTag: 0x2c8, symIndex: 0x1b, system: 0x0}, + 117: {compactTag: 0x2c8, symIndex: 0x49, system: 0x4}, + 118: {compactTag: 0x2c9, symIndex: 0x49, system: 0x4}, + 119: {compactTag: 0x2cb, symIndex: 0x33, system: 0x0}, + 120: {compactTag: 0x2cb, symIndex: 0x4a, system: 0x4}, + 121: {compactTag: 0x2cc, symIndex: 0x42, system: 0x4}, + 122: {compactTag: 0x2cc, symIndex: 0x28, system: 0x0}, + 123: {compactTag: 0x2ce, symIndex: 0x34, system: 0x0}, + 124: {compactTag: 0x2ce, symIndex: 0x4b, system: 0x4}, + 125: {compactTag: 0x2f4, symIndex: 0x0, system: 0x0}, + 126: {compactTag: 0x2f4, symIndex: 0x38, system: 0x3}, + 127: {compactTag: 0x2f4, symIndex: 0x42, system: 0x4}, + 128: {compactTag: 0x2fa, symIndex: 0x36, system: 0x0}, + 129: {compactTag: 0x2fa, symIndex: 0x41, system: 0x3}, + 130: {compactTag: 0x2fa, symIndex: 0x4c, system: 0x4}, +} // Size: 810 bytes + +var tagToDecimal = []uint8{ // 768 elements + // Entry 0 - 3F + 0x01, 0x01, 0x08, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x05, 0x05, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + // Entry 40 - 7F + 0x01, 0x01, 0x05, 0x05, 0x05, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x05, 0x05, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x05, 0x05, + 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x05, 0x05, + // Entry 80 - BF + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + // Entry C0 - FF + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + // Entry 100 - 13F + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + // Entry 140 - 17F + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x05, 0x05, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x05, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + // Entry 180 - 1BF + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x05, 0x05, 0x05, 0x05, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + // Entry 1C0 - 1FF + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x05, 0x05, 0x01, 0x01, + 0x05, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + // Entry 200 - 23F + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x05, 0x05, + 0x01, 0x01, 0x01, 0x05, 0x01, 0x01, 0x05, 0x05, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + // Entry 240 - 27F + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + // Entry 280 - 2BF + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x05, 0x05, 0x05, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + // Entry 2C0 - 2FF + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +} // Size: 792 bytes + +var tagToScientific = []uint8{ // 768 elements + // Entry 0 - 3F + 0x02, 0x02, 0x09, 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, 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 40 - 7F + 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, 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, 0x02, 0x02, + // Entry 80 - BF + 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, 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, 0x02, 0x02, + // Entry C0 - FF + 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, 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, 0x02, 0x02, + // Entry 100 - 13F + 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, 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, 0x02, 0x02, + // Entry 140 - 17F + 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, 0x02, + 0x02, 0x02, 0x0c, 0x0c, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x0c, 0x0c, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + // Entry 180 - 1BF + 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, 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, 0x02, 0x02, + // Entry 1C0 - 1FF + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x0d, 0x0d, + 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, 0x02, + 0x0c, 0x0c, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + // Entry 200 - 23F + 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, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x0c, 0x02, 0x02, 0x0c, 0x0c, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + // Entry 240 - 27F + 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, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x0d, 0x0d, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + // Entry 280 - 2BF + 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, 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, 0x02, 0x02, + // Entry 2C0 - 2FF + 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, 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, 0x02, 0x02, +} // Size: 792 bytes + +var tagToPercent = []uint8{ // 768 elements + // Entry 0 - 3F + 0x04, 0x04, 0x0a, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x06, 0x06, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, + 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + // Entry 40 - 7F + 0x04, 0x04, 0x06, 0x06, 0x06, 0x04, 0x04, 0x04, + 0x03, 0x03, 0x06, 0x06, 0x03, 0x04, 0x04, 0x03, + 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x06, 0x06, + 0x06, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, + 0x03, 0x03, 0x03, 0x04, 0x04, 0x03, 0x03, 0x03, + 0x04, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x03, + 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x07, 0x07, + // Entry 80 - BF + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x04, + 0x03, 0x04, 0x04, 0x03, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x06, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + // Entry C0 - FF + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + // Entry 100 - 13F + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x04, 0x04, 0x0b, 0x0b, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, + 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + // Entry 140 - 17F + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x06, 0x06, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x06, 0x06, 0x04, 0x04, 0x04, 0x03, 0x03, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + // Entry 180 - 1BF + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, + 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x06, 0x06, 0x06, 0x06, 0x04, 0x04, + 0x04, 0x04, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, + // Entry 1C0 - 1FF + 0x04, 0x04, 0x04, 0x03, 0x03, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x03, 0x03, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + // Entry 200 - 23F + 0x04, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x06, 0x06, + 0x04, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + // Entry 240 - 27F + 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, + 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, + 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, + 0x03, 0x03, 0x04, 0x04, 0x04, 0x03, 0x03, 0x04, + // Entry 280 - 2BF + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x06, 0x06, 0x06, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x04, + 0x04, 0x04, 0x0e, 0x0e, 0x0e, 0x04, 0x03, 0x03, + // Entry 2C0 - 2FF + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +} // Size: 792 bytes + +var formats = []Pattern{Pattern{RoundingContext: RoundingContext{MaxSignificantDigits: 0, + MaxFractionDigits: 0, + Increment: 0x0, + IncrementScale: 0x0, + Mode: 0x0, + DigitShift: 0x0, + MinIntegerDigits: 0x0, + MaxIntegerDigits: 0x0, + MinFractionDigits: 0x0, + MinSignificantDigits: 0x0, + MinExponentDigits: 0x0}, + Affix: "", + Offset: 0x0, + NegOffset: 0x0, + PadRune: 0, + FormatWidth: 0x0, + GroupingSize: [2]uint8{0x0, + 0x0}, + Flags: 0x0}, + Pattern{RoundingContext: RoundingContext{MaxSignificantDigits: 0, + MaxFractionDigits: 3, + Increment: 0x0, + IncrementScale: 0x0, + Mode: 0x0, + DigitShift: 0x0, + MinIntegerDigits: 0x1, + MaxIntegerDigits: 0x0, + MinFractionDigits: 0x0, + MinSignificantDigits: 0x0, + MinExponentDigits: 0x0}, + Affix: "", + Offset: 0x0, + NegOffset: 0x0, + PadRune: 0, + FormatWidth: 0x9, + GroupingSize: [2]uint8{0x3, + 0x0}, + Flags: 0x0}, + Pattern{RoundingContext: RoundingContext{MaxSignificantDigits: 0, + MaxFractionDigits: 0, + Increment: 0x0, + IncrementScale: 0x0, + Mode: 0x0, + DigitShift: 0x0, + MinIntegerDigits: 0x0, + MaxIntegerDigits: 0x1, + MinFractionDigits: 0x0, + MinSignificantDigits: 0x0, + MinExponentDigits: 0x1}, + Affix: "", + Offset: 0x0, + NegOffset: 0x0, + PadRune: 0, + FormatWidth: 0x3, + GroupingSize: [2]uint8{0x0, + 0x0}, + Flags: 0x0}, + Pattern{RoundingContext: RoundingContext{MaxSignificantDigits: 0, + MaxFractionDigits: 0, + Increment: 0x0, + IncrementScale: 0x0, + Mode: 0x0, + DigitShift: 0x2, + MinIntegerDigits: 0x1, + MaxIntegerDigits: 0x0, + MinFractionDigits: 0x0, + MinSignificantDigits: 0x0, + MinExponentDigits: 0x0}, + Affix: "\x00\x03\u00a0%", + Offset: 0x0, + NegOffset: 0x0, + PadRune: 0, + FormatWidth: 0x7, + GroupingSize: [2]uint8{0x3, + 0x0}, + Flags: 0x0}, + Pattern{RoundingContext: RoundingContext{MaxSignificantDigits: 0, + MaxFractionDigits: 0, + Increment: 0x0, + IncrementScale: 0x0, + Mode: 0x0, + DigitShift: 0x2, + MinIntegerDigits: 0x1, + MaxIntegerDigits: 0x0, + MinFractionDigits: 0x0, + MinSignificantDigits: 0x0, + MinExponentDigits: 0x0}, + Affix: "\x00\x01%", + Offset: 0x0, + NegOffset: 0x0, + PadRune: 0, + FormatWidth: 0x6, + GroupingSize: [2]uint8{0x3, + 0x0}, + Flags: 0x0}, + Pattern{RoundingContext: RoundingContext{MaxSignificantDigits: 0, + MaxFractionDigits: 3, + Increment: 0x0, + IncrementScale: 0x0, + Mode: 0x0, + DigitShift: 0x0, + MinIntegerDigits: 0x1, + MaxIntegerDigits: 0x0, + MinFractionDigits: 0x0, + MinSignificantDigits: 0x0, + MinExponentDigits: 0x0}, + Affix: "", + Offset: 0x0, + NegOffset: 0x0, + PadRune: 0, + FormatWidth: 0xc, + GroupingSize: [2]uint8{0x3, + 0x2}, + Flags: 0x0}, + Pattern{RoundingContext: RoundingContext{MaxSignificantDigits: 0, + MaxFractionDigits: 0, + Increment: 0x0, + IncrementScale: 0x0, + Mode: 0x0, + DigitShift: 0x2, + MinIntegerDigits: 0x1, + MaxIntegerDigits: 0x0, + MinFractionDigits: 0x0, + MinSignificantDigits: 0x0, + MinExponentDigits: 0x0}, + Affix: "\x00\x01%", + Offset: 0x0, + NegOffset: 0x0, + PadRune: 0, + FormatWidth: 0x9, + GroupingSize: [2]uint8{0x3, + 0x2}, + Flags: 0x0}, + Pattern{RoundingContext: RoundingContext{MaxSignificantDigits: 0, + MaxFractionDigits: 0, + Increment: 0x0, + IncrementScale: 0x0, + Mode: 0x0, + DigitShift: 0x2, + MinIntegerDigits: 0x1, + MaxIntegerDigits: 0x0, + MinFractionDigits: 0x0, + MinSignificantDigits: 0x0, + MinExponentDigits: 0x0}, + Affix: "\x00\x03\u00a0%", + Offset: 0x0, + NegOffset: 0x0, + PadRune: 0, + FormatWidth: 0xa, + GroupingSize: [2]uint8{0x3, + 0x2}, + Flags: 0x0}, + Pattern{RoundingContext: RoundingContext{MaxSignificantDigits: 0, + MaxFractionDigits: 6, + Increment: 0x0, + IncrementScale: 0x0, + Mode: 0x0, + DigitShift: 0x0, + MinIntegerDigits: 0x1, + MaxIntegerDigits: 0x0, + MinFractionDigits: 0x0, + MinSignificantDigits: 0x0, + MinExponentDigits: 0x0}, + Affix: "", + Offset: 0x0, + NegOffset: 0x0, + PadRune: 0, + FormatWidth: 0x8, + GroupingSize: [2]uint8{0x0, + 0x0}, + Flags: 0x0}, + Pattern{RoundingContext: RoundingContext{MaxSignificantDigits: 0, + MaxFractionDigits: 6, + Increment: 0x0, + IncrementScale: 0x0, + Mode: 0x0, + DigitShift: 0x0, + MinIntegerDigits: 0x1, + MaxIntegerDigits: 0x0, + MinFractionDigits: 0x6, + MinSignificantDigits: 0x0, + MinExponentDigits: 0x3}, + Affix: "", + Offset: 0x0, + NegOffset: 0x0, + PadRune: 0, + FormatWidth: 0xd, + GroupingSize: [2]uint8{0x0, + 0x0}, + Flags: 0x4}, + Pattern{RoundingContext: RoundingContext{MaxSignificantDigits: 0, + MaxFractionDigits: 0, + Increment: 0x0, + IncrementScale: 0x0, + Mode: 0x0, + DigitShift: 0x2, + MinIntegerDigits: 0x1, + MaxIntegerDigits: 0x0, + MinFractionDigits: 0x0, + MinSignificantDigits: 0x0, + MinExponentDigits: 0x0}, + Affix: "\x00\x01%", + Offset: 0x0, + NegOffset: 0x0, + PadRune: 0, + FormatWidth: 0x2, + GroupingSize: [2]uint8{0x0, + 0x0}, + Flags: 0x0}, + Pattern{RoundingContext: RoundingContext{MaxSignificantDigits: 0, + MaxFractionDigits: 0, + Increment: 0x0, + IncrementScale: 0x0, + Mode: 0x0, + DigitShift: 0x2, + MinIntegerDigits: 0x1, + MaxIntegerDigits: 0x0, + MinFractionDigits: 0x0, + MinSignificantDigits: 0x0, + MinExponentDigits: 0x0}, + Affix: "\x03%\u00a0\x00", + Offset: 0x0, + NegOffset: 0x0, + PadRune: 0, + FormatWidth: 0x7, + GroupingSize: [2]uint8{0x3, + 0x0}, + Flags: 0x0}, + Pattern{RoundingContext: RoundingContext{MaxSignificantDigits: 0, + MaxFractionDigits: 0, + Increment: 0x0, + IncrementScale: 0x0, + Mode: 0x0, + DigitShift: 0x0, + MinIntegerDigits: 0x0, + MaxIntegerDigits: 0x1, + MinFractionDigits: 0x0, + MinSignificantDigits: 0x0, + MinExponentDigits: 0x1}, + Affix: "\x01[\x01]", + Offset: 0x0, + NegOffset: 0x0, + PadRune: 0, + FormatWidth: 0x5, + GroupingSize: [2]uint8{0x0, + 0x0}, + Flags: 0x0}, + Pattern{RoundingContext: RoundingContext{MaxSignificantDigits: 0, + MaxFractionDigits: 0, + Increment: 0x0, + IncrementScale: 0x0, + Mode: 0x0, + DigitShift: 0x0, + MinIntegerDigits: 0x0, + MaxIntegerDigits: 0x0, + MinFractionDigits: 0x0, + MinSignificantDigits: 0x0, + MinExponentDigits: 0x0}, + Affix: "", + Offset: 0x0, + NegOffset: 0x0, + PadRune: 0, + FormatWidth: 0x1, + GroupingSize: [2]uint8{0x0, + 0x0}, + Flags: 0x0}, + Pattern{RoundingContext: RoundingContext{MaxSignificantDigits: 0, + MaxFractionDigits: 0, + Increment: 0x0, + IncrementScale: 0x0, + Mode: 0x0, + DigitShift: 0x2, + MinIntegerDigits: 0x1, + MaxIntegerDigits: 0x0, + MinFractionDigits: 0x0, + MinSignificantDigits: 0x0, + MinExponentDigits: 0x0}, + Affix: "\x01%\x00", + Offset: 0x0, + NegOffset: 0x0, + PadRune: 0, + FormatWidth: 0x6, + GroupingSize: [2]uint8{0x3, + 0x0}, + Flags: 0x0}} + +// Total table size 8599 bytes (8KiB); checksum: F01E770E diff --git a/vendor/golang.org/x/text/internal/number/tables_test.go b/vendor/golang.org/x/text/internal/number/tables_test.go new file mode 100644 index 0000000..054e23d --- /dev/null +++ b/vendor/golang.org/x/text/internal/number/tables_test.go @@ -0,0 +1,125 @@ +// 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 number + +import ( + "flag" + "log" + "reflect" + "testing" + + "golang.org/x/text/internal/gen" + "golang.org/x/text/internal/testtext" + "golang.org/x/text/language" + "golang.org/x/text/unicode/cldr" +) + +var draft = flag.String("draft", + "contributed", + `Minimal draft requirements (approved, contributed, provisional, unconfirmed).`) + +func TestNumberSystems(t *testing.T) { + testtext.SkipIfNotLong(t) + + r := gen.OpenCLDRCoreZip() + defer r.Close() + + d := &cldr.Decoder{} + d.SetDirFilter("supplemental") + d.SetSectionFilter("numberingSystem") + data, err := d.DecodeZip(r) + if err != nil { + t.Fatalf("DecodeZip: %v", err) + } + + for _, ns := range data.Supplemental().NumberingSystems.NumberingSystem { + n := systemMap[ns.Id] + if int(n) >= len(numSysData) { + continue + } + info := InfoFromLangID(0, ns.Id) + val := '0' + for _, rWant := range ns.Digits { + if rGot := info.Digit(val); rGot != rWant { + t.Errorf("%s:%d: got %U; want %U", ns.Id, val, rGot, rWant) + } + val++ + } + } +} + +func TestSymbols(t *testing.T) { + testtext.SkipIfNotLong(t) + + draft, err := cldr.ParseDraft(*draft) + if err != nil { + log.Fatalf("invalid draft level: %v", err) + } + + r := gen.OpenCLDRCoreZip() + defer r.Close() + + d := &cldr.Decoder{} + d.SetDirFilter("main") + d.SetSectionFilter("numbers") + data, err := d.DecodeZip(r) + if err != nil { + t.Fatalf("DecodeZip: %v", err) + } + + for _, lang := range data.Locales() { + ldml := data.RawLDML(lang) + if ldml.Numbers == nil { + continue + } + langIndex, ok := language.CompactIndex(language.MustParse(lang)) + if !ok { + t.Fatalf("No compact index for language %s", lang) + } + + syms := cldr.MakeSlice(&ldml.Numbers.Symbols) + syms.SelectDraft(draft) + + for _, sym := range ldml.Numbers.Symbols { + if sym.NumberSystem == "" { + continue + } + testCases := []struct { + name string + st SymbolType + x interface{} + }{ + {"Decimal", SymDecimal, sym.Decimal}, + {"Group", SymGroup, sym.Group}, + {"List", SymList, sym.List}, + {"PercentSign", SymPercentSign, sym.PercentSign}, + {"PlusSign", SymPlusSign, sym.PlusSign}, + {"MinusSign", SymMinusSign, sym.MinusSign}, + {"Exponential", SymExponential, sym.Exponential}, + {"SuperscriptingExponent", SymSuperscriptingExponent, sym.SuperscriptingExponent}, + {"PerMille", SymPerMille, sym.PerMille}, + {"Infinity", SymInfinity, sym.Infinity}, + {"NaN", SymNan, sym.Nan}, + {"TimeSeparator", SymTimeSeparator, sym.TimeSeparator}, + } + info := InfoFromLangID(langIndex, sym.NumberSystem) + for _, tc := range testCases { + // Extract the wanted value. + v := reflect.ValueOf(tc.x) + if v.Len() == 0 { + return + } + if v.Len() > 1 { + t.Fatalf("Multiple values of %q within single symbol not supported.", tc.name) + } + want := v.Index(0).MethodByName("Data").Call(nil)[0].String() + got := info.Symbol(tc.st) + if got != want { + t.Errorf("%s:%s:%s: got %q; want %q", lang, sym.NumberSystem, tc.name, got, want) + } + } + } + } +} -- cgit v1.2.3