From b530b8cda3cb576951e32cbaf73bbf1c25d6807e Mon Sep 17 00:00:00 2001 From: Justin King Date: Wed, 19 Feb 2025 14:01:22 -0800 Subject: [PATCH 1/7] Update strings.format to adhere to the specification Signed-off-by: Justin King --- WORKSPACE | 4 +- conformance/BUILD.bazel | 7 + conformance/conformance_test.go | 1 + conformance/go.mod | 3 +- conformance/go.sum | 12 +- ext/formatting.go | 642 ++- ext/strings.go | 29 +- ext/strings_test.go | 244 +- go.mod | 3 +- go.sum | 6 +- vendor/cel.dev/expr/README.md | 2 - vendor/golang.org/x/text/LICENSE | 27 - vendor/golang.org/x/text/PATENTS | 22 - .../x/text/feature/plural/common.go | 70 - .../x/text/feature/plural/message.go | 244 -- .../x/text/feature/plural/plural.go | 262 -- .../x/text/feature/plural/tables.go | 552 --- .../x/text/internal/catmsg/catmsg.go | 417 -- .../x/text/internal/catmsg/codec.go | 407 -- .../x/text/internal/catmsg/varint.go | 62 - .../x/text/internal/format/format.go | 41 - .../x/text/internal/format/parser.go | 358 -- vendor/golang.org/x/text/internal/internal.go | 49 - .../x/text/internal/language/common.go | 16 - .../x/text/internal/language/compact.go | 29 - .../text/internal/language/compact/compact.go | 61 - .../internal/language/compact/language.go | 260 -- .../text/internal/language/compact/parents.go | 120 - .../text/internal/language/compact/tables.go | 1015 ----- .../x/text/internal/language/compact/tags.go | 91 - .../x/text/internal/language/compose.go | 167 - .../x/text/internal/language/coverage.go | 28 - .../x/text/internal/language/language.go | 627 --- .../x/text/internal/language/lookup.go | 412 -- .../x/text/internal/language/match.go | 226 -- .../x/text/internal/language/parse.go | 608 --- .../x/text/internal/language/tables.go | 3494 ----------------- .../x/text/internal/language/tags.go | 48 - vendor/golang.org/x/text/internal/match.go | 67 - .../x/text/internal/number/common.go | 55 - .../x/text/internal/number/decimal.go | 500 --- .../x/text/internal/number/format.go | 535 --- .../x/text/internal/number/number.go | 152 - .../x/text/internal/number/pattern.go | 485 --- .../internal/number/roundingmode_string.go | 30 - .../x/text/internal/number/tables.go | 1219 ------ .../x/text/internal/stringset/set.go | 86 - vendor/golang.org/x/text/internal/tag/tag.go | 100 - vendor/golang.org/x/text/language/coverage.go | 187 - vendor/golang.org/x/text/language/doc.go | 98 - vendor/golang.org/x/text/language/language.go | 605 --- vendor/golang.org/x/text/language/match.go | 735 ---- vendor/golang.org/x/text/language/parse.go | 256 -- vendor/golang.org/x/text/language/tables.go | 298 -- vendor/golang.org/x/text/language/tags.go | 145 - vendor/golang.org/x/text/message/catalog.go | 36 - .../x/text/message/catalog/catalog.go | 365 -- .../golang.org/x/text/message/catalog/dict.go | 129 - .../golang.org/x/text/message/catalog/go19.go | 15 - .../x/text/message/catalog/gopre19.go | 23 - vendor/golang.org/x/text/message/doc.go | 99 - vendor/golang.org/x/text/message/format.go | 510 --- vendor/golang.org/x/text/message/message.go | 192 - vendor/golang.org/x/text/message/print.go | 984 ----- vendor/modules.txt | 16 +- 65 files changed, 396 insertions(+), 18192 deletions(-) delete mode 100644 vendor/golang.org/x/text/LICENSE delete mode 100644 vendor/golang.org/x/text/PATENTS delete mode 100644 vendor/golang.org/x/text/feature/plural/common.go delete mode 100644 vendor/golang.org/x/text/feature/plural/message.go delete mode 100644 vendor/golang.org/x/text/feature/plural/plural.go delete mode 100644 vendor/golang.org/x/text/feature/plural/tables.go delete mode 100644 vendor/golang.org/x/text/internal/catmsg/catmsg.go delete mode 100644 vendor/golang.org/x/text/internal/catmsg/codec.go delete mode 100644 vendor/golang.org/x/text/internal/catmsg/varint.go delete mode 100644 vendor/golang.org/x/text/internal/format/format.go delete mode 100644 vendor/golang.org/x/text/internal/format/parser.go delete mode 100644 vendor/golang.org/x/text/internal/internal.go delete mode 100644 vendor/golang.org/x/text/internal/language/common.go delete mode 100644 vendor/golang.org/x/text/internal/language/compact.go delete mode 100644 vendor/golang.org/x/text/internal/language/compact/compact.go delete mode 100644 vendor/golang.org/x/text/internal/language/compact/language.go delete mode 100644 vendor/golang.org/x/text/internal/language/compact/parents.go delete mode 100644 vendor/golang.org/x/text/internal/language/compact/tables.go delete mode 100644 vendor/golang.org/x/text/internal/language/compact/tags.go delete mode 100644 vendor/golang.org/x/text/internal/language/compose.go delete mode 100644 vendor/golang.org/x/text/internal/language/coverage.go delete mode 100644 vendor/golang.org/x/text/internal/language/language.go delete mode 100644 vendor/golang.org/x/text/internal/language/lookup.go delete mode 100644 vendor/golang.org/x/text/internal/language/match.go delete mode 100644 vendor/golang.org/x/text/internal/language/parse.go delete mode 100644 vendor/golang.org/x/text/internal/language/tables.go delete mode 100644 vendor/golang.org/x/text/internal/language/tags.go delete mode 100644 vendor/golang.org/x/text/internal/match.go delete mode 100644 vendor/golang.org/x/text/internal/number/common.go delete mode 100644 vendor/golang.org/x/text/internal/number/decimal.go delete mode 100644 vendor/golang.org/x/text/internal/number/format.go delete mode 100644 vendor/golang.org/x/text/internal/number/number.go delete mode 100644 vendor/golang.org/x/text/internal/number/pattern.go delete mode 100644 vendor/golang.org/x/text/internal/number/roundingmode_string.go delete mode 100644 vendor/golang.org/x/text/internal/number/tables.go delete mode 100644 vendor/golang.org/x/text/internal/stringset/set.go delete mode 100644 vendor/golang.org/x/text/internal/tag/tag.go delete mode 100644 vendor/golang.org/x/text/language/coverage.go delete mode 100644 vendor/golang.org/x/text/language/doc.go delete mode 100644 vendor/golang.org/x/text/language/language.go delete mode 100644 vendor/golang.org/x/text/language/match.go delete mode 100644 vendor/golang.org/x/text/language/parse.go delete mode 100644 vendor/golang.org/x/text/language/tables.go delete mode 100644 vendor/golang.org/x/text/language/tags.go delete mode 100644 vendor/golang.org/x/text/message/catalog.go delete mode 100644 vendor/golang.org/x/text/message/catalog/catalog.go delete mode 100644 vendor/golang.org/x/text/message/catalog/dict.go delete mode 100644 vendor/golang.org/x/text/message/catalog/go19.go delete mode 100644 vendor/golang.org/x/text/message/catalog/gopre19.go delete mode 100644 vendor/golang.org/x/text/message/doc.go delete mode 100644 vendor/golang.org/x/text/message/format.go delete mode 100644 vendor/golang.org/x/text/message/message.go delete mode 100644 vendor/golang.org/x/text/message/print.go diff --git a/WORKSPACE b/WORKSPACE index 133a6b8e3..b52b8319a 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -101,8 +101,8 @@ go_repository( go_repository( name = "dev_cel_expr", importpath = "cel.dev/expr", - sum = "h1:NciYrtDRIR0lNCnH1LFJegdjspNx9fI59O7TWcua/W4=", - version = "v0.19.1", + sum = "h1:o+Wj235dy4gFYlYin3JsMpp3EEfMrPm/6tdoyjT98S0=", + version = "v0.21.2", ) # local_repository( diff --git a/conformance/BUILD.bazel b/conformance/BUILD.bazel index 4bca746d2..6b2e50bcf 100644 --- a/conformance/BUILD.bazel +++ b/conformance/BUILD.bazel @@ -55,6 +55,13 @@ _TESTS_TO_SKIP = [ # Future enhancments. "enums/strong_proto2", "enums/strong_proto3", + + # Type deductions + "type_deductions/wrappers/wrapper_promotion_2", + "type_deductions/legacy_nullable_types/null_assignable_to_message_parameter_candidate", + "type_deductions/legacy_nullable_types/null_assignable_to_duration_parameter_candidate", + "type_deductions/legacy_nullable_types/null_assignable_to_timestamp_parameter_candidate", + "type_deductions/legacy_nullable_types/null_assignable_to_abstract_parameter_candidate", ] go_test( diff --git a/conformance/conformance_test.go b/conformance/conformance_test.go index 4eead5c4d..4b37ea2e8 100644 --- a/conformance/conformance_test.go +++ b/conformance/conformance_test.go @@ -92,6 +92,7 @@ func init() { ext.Protos(), ext.Strings(), cel.Lib(celBlockLib{}), + cel.EnableIdentifierEscapeSyntax(), } var err error diff --git a/conformance/go.mod b/conformance/go.mod index 65aa6edd6..b666bfe67 100644 --- a/conformance/go.mod +++ b/conformance/go.mod @@ -3,7 +3,7 @@ module github.com/google/cel-go/conformance go 1.21.1 require ( - cel.dev/expr v0.19.1 + cel.dev/expr v0.21.2 github.com/bazelbuild/rules_go v0.49.0 github.com/google/cel-go v0.21.0 github.com/google/go-cmp v0.6.0 @@ -14,7 +14,6 @@ require ( github.com/antlr4-go/antlr/v4 v4.13.0 // indirect github.com/stoewer/go-strcase v1.2.0 // indirect golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc // indirect - golang.org/x/text v0.16.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240826202546-f6391c0de4c7 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240826202546-f6391c0de4c7 // indirect ) diff --git a/conformance/go.sum b/conformance/go.sum index 8e4f44922..cadf61fd9 100644 --- a/conformance/go.sum +++ b/conformance/go.sum @@ -1,9 +1,5 @@ -cel.dev/expr v0.18.0 h1:CJ6drgk+Hf96lkLikr4rFf19WrU0BOWEihyZnI2TAzo= -cel.dev/expr v0.18.0/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw= -cel.dev/expr v0.19.0 h1:lXuo+nDhpyJSpWxpPVi5cPUwzKb+dsdOiw6IreM5yt0= -cel.dev/expr v0.19.0/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw= -cel.dev/expr v0.19.1 h1:NciYrtDRIR0lNCnH1LFJegdjspNx9fI59O7TWcua/W4= -cel.dev/expr v0.19.1/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw= +cel.dev/expr v0.21.2 h1:o+Wj235dy4gFYlYin3JsMpp3EEfMrPm/6tdoyjT98S0= +cel.dev/expr v0.21.2/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw= github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI= github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g= github.com/bazelbuild/rules_go v0.49.0 h1:5vCbuvy8Q11g41lseGJDc5vxhDjJtfxr6nM/IC4VmqM= @@ -21,8 +17,6 @@ github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc h1:mCRnTeVUjcrhlRmO0VK8a6k6Rrf6TF9htwo2pJVSjIU= golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= google.golang.org/genproto/googleapis/api v0.0.0-20240826202546-f6391c0de4c7 h1:YcyjlL1PRr2Q17/I0dPk2JmYS5CDXfcdb2Z3YRioEbw= google.golang.org/genproto/googleapis/api v0.0.0-20240826202546-f6391c0de4c7/go.mod h1:OCdP9MfskevB/rbYvHTsXTtKC+3bHWajPdoKgjcYkfo= google.golang.org/genproto/googleapis/rpc v0.0.0-20240826202546-f6391c0de4c7 h1:2035KHhUv+EpyB+hWgJnaWKJOdX1E95w2S8Rr4uWKTs= @@ -32,3 +26,5 @@ google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWn gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/ext/formatting.go b/ext/formatting.go index aa334ccd9..36b765e60 100644 --- a/ext/formatting.go +++ b/ext/formatting.go @@ -21,11 +21,9 @@ import ( "sort" "strconv" "strings" + "time" "unicode" - "golang.org/x/text/language" - "golang.org/x/text/message" - "github.com/google/cel-go/cel" "github.com/google/cel-go/common/ast" "github.com/google/cel-go/common/overloads" @@ -34,368 +32,366 @@ import ( "github.com/google/cel-go/common/types/traits" ) -type clauseImpl func(ref.Val, string) (string, error) - -func clauseForType(argType ref.Type) (clauseImpl, error) { - switch argType { - case types.IntType, types.UintType: - return formatDecimal, nil - case types.StringType, types.BytesType, types.BoolType, types.NullType, types.TypeType: - return FormatString, nil - case types.TimestampType, types.DurationType: - // special case to ensure timestamps/durations get printed as CEL literals - return func(arg ref.Val, locale string) (string, error) { - argStrVal := arg.ConvertToType(types.StringType) - argStr := argStrVal.Value().(string) - if arg.Type() == types.TimestampType { - return fmt.Sprintf("timestamp(%q)", argStr), nil - } - if arg.Type() == types.DurationType { - return fmt.Sprintf("duration(%q)", argStr), nil - } - return "", fmt.Errorf("cannot convert argument of type %s to timestamp/duration", arg.Type().TypeName()) - }, nil - case types.ListType: - return formatList, nil - case types.MapType: - return formatMap, nil - case types.DoubleType: - // avoid formatFixed so we can output a period as the decimal separator in order - // to always be a valid CEL literal - return func(arg ref.Val, locale string) (string, error) { - argDouble, ok := arg.Value().(float64) - if !ok { - return "", fmt.Errorf("couldn't convert %s to float64", arg.Type().TypeName()) - } - fmtStr := fmt.Sprintf("%%.%df", defaultPrecision) - return fmt.Sprintf(fmtStr, argDouble), nil - }, nil - case types.TypeType: - return func(arg ref.Val, locale string) (string, error) { - return fmt.Sprintf("type(%s)", arg.Value().(string)), nil - }, nil - default: - return nil, fmt.Errorf("no formatting function for %s", argType.TypeName()) - } +type clauseImpl func(ref.Val) (string, error) + +type appendingFormatter struct { + buf []byte } -func formatList(arg ref.Val, locale string) (string, error) { - argList := arg.(traits.Lister) - argIterator := argList.Iterator() - var listStrBuilder strings.Builder - _, err := listStrBuilder.WriteRune('[') - if err != nil { - return "", fmt.Errorf("error writing to list string: %w", err) - } - for argIterator.HasNext() == types.True { - member := argIterator.Next() - memberFormat, err := clauseForType(member.Type()) - if err != nil { - return "", err +type formattedMapEntry struct { + key string + val string +} + +func (af *appendingFormatter) format(arg ref.Val) error { + switch arg.Type() { + case types.BoolType: + argBool, ok := arg.Value().(bool) + if !ok { + return fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.BoolType) } - unquotedStr, err := memberFormat(member, locale) - if err != nil { - return "", err + af.buf = strconv.AppendBool(af.buf, argBool) + return nil + case types.IntType: + argInt, ok := arg.Value().(int64) + if !ok { + return fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.IntType) } - str := quoteForCEL(member, unquotedStr) - _, err = listStrBuilder.WriteString(str) - if err != nil { - return "", fmt.Errorf("error writing to list string: %w", err) + af.buf = strconv.AppendInt(af.buf, argInt, 10) + return nil + case types.UintType: + argUint, ok := arg.Value().(uint64) + if !ok { + return fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.UintType) } - if argIterator.HasNext() == types.True { - _, err = listStrBuilder.WriteString(", ") - if err != nil { - return "", fmt.Errorf("error writing to list string: %w", err) - } + af.buf = strconv.AppendUint(af.buf, argUint, 10) + return nil + case types.DoubleType: + argDbl, ok := arg.Value().(float64) + if !ok { + return fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.DoubleType) } - } - _, err = listStrBuilder.WriteRune(']') - if err != nil { - return "", fmt.Errorf("error writing to list string: %w", err) - } - return listStrBuilder.String(), nil -} - -func formatMap(arg ref.Val, locale string) (string, error) { - argMap := arg.(traits.Mapper) - argIterator := argMap.Iterator() - type mapPair struct { - key string - value string - } - argPairs := make([]mapPair, argMap.Size().Value().(int64)) - i := 0 - for argIterator.HasNext() == types.True { - key := argIterator.Next() - var keyFormat clauseImpl - switch key.Type() { - case types.StringType, types.BoolType: - keyFormat = FormatString - case types.IntType, types.UintType: - keyFormat = formatDecimal - default: - return "", fmt.Errorf("no formatting function for map key of type %s", key.Type().TypeName()) + if math.IsNaN(argDbl) { + af.buf = append(af.buf, "NaN"...) + return nil } - unquotedKeyStr, err := keyFormat(key, locale) - if err != nil { - return "", err + if math.IsInf(argDbl, -1) { + af.buf = append(af.buf, "-Infinity"...) + return nil } - keyStr := quoteForCEL(key, unquotedKeyStr) - value, found := argMap.Find(key) - if !found { - return "", fmt.Errorf("could not find key: %q", key) + if math.IsInf(argDbl, 1) { + af.buf = append(af.buf, "Infinity"...) + return nil } - valueFormat, err := clauseForType(value.Type()) - if err != nil { - return "", err + af.buf = strconv.AppendFloat(af.buf, argDbl, 'f', -1, 64) + return nil + case types.BytesType: + argBytes, ok := arg.Value().([]byte) + if !ok { + return fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.BytesType) } - unquotedValueStr, err := valueFormat(value, locale) - if err != nil { - return "", err + af.buf = append(af.buf, argBytes...) + return nil + case types.StringType: + argStr, ok := arg.Value().(string) + if !ok { + return fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.StringType) } - valueStr := quoteForCEL(value, unquotedValueStr) - argPairs[i] = mapPair{keyStr, valueStr} - i++ - } - sort.SliceStable(argPairs, func(x, y int) bool { - return argPairs[x].key < argPairs[y].key - }) - var mapStrBuilder strings.Builder - _, err := mapStrBuilder.WriteRune('{') - if err != nil { - return "", fmt.Errorf("error writing to map string: %w", err) - } - for i, entry := range argPairs { - _, err = mapStrBuilder.WriteString(fmt.Sprintf("%s:%s", entry.key, entry.value)) - if err != nil { - return "", fmt.Errorf("error writing to map string: %w", err) + af.buf = append(af.buf, argStr...) + return nil + case types.DurationType: + argDur, ok := arg.Value().(time.Duration) + if !ok { + return fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.DurationType) } - if i < len(argPairs)-1 { - _, err = mapStrBuilder.WriteString(", ") - if err != nil { - return "", fmt.Errorf("error writing to map string: %w", err) + af.buf = strconv.AppendFloat(af.buf, argDur.Seconds(), 'f', -1, 64) + af.buf = append(af.buf, "s"...) + return nil + case types.TimestampType: + argTime, ok := arg.Value().(time.Time) + if !ok { + return fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.TimestampType) + } + af.buf = argTime.UTC().AppendFormat(af.buf, time.RFC3339Nano) + return nil + case types.NullType: + af.buf = append(af.buf, "null"...) + return nil + case types.TypeType: + argType, ok := arg.Value().(string) + if !ok { + return fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.TypeType) + } + af.buf = append(af.buf, argType...) + return nil + case types.ListType: + argList, ok := arg.(traits.Lister) + if !ok { + return fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.ListType) + } + argIter := argList.Iterator() + af.buf = append(af.buf, "["...) + if argIter.HasNext() == types.True { + if err := af.format(argIter.Next()); err != nil { + return err + } + for argIter.HasNext() == types.True { + af.buf = append(af.buf, ", "...) + if err := af.format(argIter.Next()); err != nil { + return err + } } } - } - _, err = mapStrBuilder.WriteRune('}') - if err != nil { - return "", fmt.Errorf("error writing to map string: %w", err) - } - return mapStrBuilder.String(), nil -} - -// quoteForCEL takes a formatted, unquoted value and quotes it in a manner suitable -// for embedding directly in CEL. -func quoteForCEL(refVal ref.Val, unquotedValue string) string { - switch refVal.Type() { - case types.StringType: - return fmt.Sprintf("%q", unquotedValue) - case types.BytesType: - return fmt.Sprintf("b%q", unquotedValue) - case types.DoubleType: - // special case to handle infinity/NaN - num := refVal.Value().(float64) - if math.IsInf(num, 1) || math.IsInf(num, -1) || math.IsNaN(num) { - return fmt.Sprintf("%q", unquotedValue) + af.buf = append(af.buf, "]"...) + return nil + case types.MapType: + argMap, ok := arg.(traits.Mapper) + if !ok { + return fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.MapType) + } + argIter := argMap.Iterator() + ents := []formattedMapEntry{} + for argIter.HasNext() == types.True { + key := argIter.Next() + val, ok := argMap.Find(key) + if !ok { + return fmt.Errorf("key missing from map: '%s'", key) + } + keyStr, err := FormatString(key) + if err != nil { + return err + } + valStr, err := FormatString(val) + if err != nil { + return err + } + ents = append(ents, formattedMapEntry{keyStr, valStr}) + } + sort.SliceStable(ents, func(x, y int) bool { + return ents[x].key < ents[y].key + }) + af.buf = append(af.buf, "{"...) + for i, e := range ents { + if i > 0 { + af.buf = append(af.buf, ", "...) + } + af.buf = append(af.buf, e.key...) + af.buf = append(af.buf, ": "...) + af.buf = append(af.buf, e.val...) } - return unquotedValue + af.buf = append(af.buf, "}"...) + return nil default: - return unquotedValue + return stringFormatError(runtimeID, arg.Type().TypeName()) } } // FormatString returns the string representation of a CEL value. // // It is used to implement the %s specifier in the (string).format() extension function. -func FormatString(arg ref.Val, locale string) (string, error) { - switch arg.Type() { - case types.ListType: - return formatList(arg, locale) - case types.MapType: - return formatMap(arg, locale) - case types.IntType, types.UintType, types.DoubleType, - types.BoolType, types.StringType, types.TimestampType, types.BytesType, types.DurationType, types.TypeType: - argStrVal := arg.ConvertToType(types.StringType) - argStr, ok := argStrVal.Value().(string) - if !ok { - return "", fmt.Errorf("could not convert argument %q to string", argStrVal) - } - return argStr, nil - case types.NullType: - return "null", nil - default: - return "", stringFormatError(runtimeID, arg.Type().TypeName()) +func FormatString(arg ref.Val) (string, error) { + var fmter appendingFormatter + if err := fmter.format(arg); err != nil { + return "", err } + return string(fmter.buf), nil } -func formatDecimal(arg ref.Val, locale string) (string, error) { +type stringFormatter struct{} + +func (c *stringFormatter) String(arg ref.Val) (string, error) { + return FormatString(arg) +} + +func (c *stringFormatter) Decimal(arg ref.Val) (string, error) { switch arg.Type() { case types.IntType: - argInt, ok := arg.ConvertToType(types.IntType).Value().(int64) + argInt, ok := arg.Value().(int64) if !ok { - return "", fmt.Errorf("could not convert \"%s\" to int64", arg.Value()) + return "", fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.IntType) } - return fmt.Sprintf("%d", argInt), nil + return strconv.FormatInt(argInt, 10), nil case types.UintType: - argInt, ok := arg.ConvertToType(types.UintType).Value().(uint64) + argUint, ok := arg.Value().(uint64) if !ok { - return "", fmt.Errorf("could not convert \"%s\" to uint64", arg.Value()) + return "", fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.UintType) } - return fmt.Sprintf("%d", argInt), nil + return strconv.FormatUint(argUint, 10), nil + case types.DoubleType: + argDbl, ok := arg.Value().(float64) + if !ok { + return "", fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.DoubleType) + } + if math.IsNaN(argDbl) { + return "NaN", nil + } + if math.IsInf(argDbl, -1) { + return "-Infinity", nil + } + if math.IsInf(argDbl, 1) { + return "Infinity", nil + } + return strconv.FormatFloat(argDbl, 'f', -1, 64), nil default: return "", decimalFormatError(runtimeID, arg.Type().TypeName()) } } -func matchLanguage(locale string) (language.Tag, error) { - matcher, err := makeMatcher(locale) - if err != nil { - return language.Und, err - } - tag, _ := language.MatchStrings(matcher, locale) - return tag, nil -} - -func makeMatcher(locale string) (language.Matcher, error) { - tags := make([]language.Tag, 0) - tag, err := language.Parse(locale) - if err != nil { - return nil, err - } - tags = append(tags, tag) - return language.NewMatcher(tags), nil -} - -type stringFormatter struct{} - -func (c *stringFormatter) String(arg ref.Val, locale string) (string, error) { - return FormatString(arg, locale) -} - -func (c *stringFormatter) Decimal(arg ref.Val, locale string) (string, error) { - return formatDecimal(arg, locale) -} - -func (c *stringFormatter) Fixed(precision *int) func(ref.Val, string) (string, error) { - if precision == nil { - precision = new(int) - *precision = defaultPrecision - } - return func(arg ref.Val, locale string) (string, error) { - strException := false - if arg.Type() == types.StringType { - argStr := arg.Value().(string) - if argStr == "NaN" || argStr == "Infinity" || argStr == "-Infinity" { - strException = true +func (c *stringFormatter) Fixed(precision int) func(ref.Val) (string, error) { + return func(arg ref.Val) (string, error) { + fmtStr := fmt.Sprintf("%%.%df", precision) + switch arg.Type() { + case types.IntType: + argInt, ok := arg.Value().(int64) + if !ok { + return "", fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.IntType) } - } - if arg.Type() != types.DoubleType && !strException { + return fmt.Sprintf(fmtStr, argInt), nil + case types.UintType: + argUint, ok := arg.Value().(uint64) + if !ok { + return "", fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.UintType) + } + return fmt.Sprintf(fmtStr, argUint), nil + case types.DoubleType: + argDbl, ok := arg.Value().(float64) + if !ok { + return "", fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.DoubleType) + } + if math.IsNaN(argDbl) { + return "NaN", nil + } + if math.IsInf(argDbl, -1) { + return "-Infinity", nil + } + if math.IsInf(argDbl, 1) { + return "Infinity", nil + } + return fmt.Sprintf(fmtStr, argDbl), nil + default: return "", fixedPointFormatError(runtimeID, arg.Type().TypeName()) } - argFloatVal := arg.ConvertToType(types.DoubleType) - argFloat, ok := argFloatVal.Value().(float64) - if !ok { - return "", fmt.Errorf("could not convert \"%s\" to float64", argFloatVal.Value()) - } - fmtStr := fmt.Sprintf("%%.%df", *precision) - - matchedLocale, err := matchLanguage(locale) - if err != nil { - return "", fmt.Errorf("error matching locale: %w", err) - } - return message.NewPrinter(matchedLocale).Sprintf(fmtStr, argFloat), nil } } -func (c *stringFormatter) Scientific(precision *int) func(ref.Val, string) (string, error) { - if precision == nil { - precision = new(int) - *precision = defaultPrecision - } - return func(arg ref.Val, locale string) (string, error) { - strException := false - if arg.Type() == types.StringType { - argStr := arg.Value().(string) - if argStr == "NaN" || argStr == "Infinity" || argStr == "-Infinity" { - strException = true +func (c *stringFormatter) Scientific(precision int) func(ref.Val) (string, error) { + return func(arg ref.Val) (string, error) { + fmtStr := fmt.Sprintf("%%1.%de", precision) + switch arg.Type() { + case types.IntType: + argInt, ok := arg.Value().(int64) + if !ok { + return "", fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.IntType) } - } - if arg.Type() != types.DoubleType && !strException { + return fmt.Sprintf(fmtStr, argInt), nil + case types.UintType: + argUint, ok := arg.Value().(uint64) + if !ok { + return "", fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.UintType) + } + return fmt.Sprintf(fmtStr, argUint), nil + case types.DoubleType: + argDbl, ok := arg.Value().(float64) + if !ok { + return "", fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.DoubleType) + } + if math.IsNaN(argDbl) { + return "NaN", nil + } + if math.IsInf(argDbl, -1) { + return "-Infinity", nil + } + if math.IsInf(argDbl, 1) { + return "Infinity", nil + } + return fmt.Sprintf(fmtStr, argDbl), nil + default: return "", scientificFormatError(runtimeID, arg.Type().TypeName()) } - argFloatVal := arg.ConvertToType(types.DoubleType) - argFloat, ok := argFloatVal.Value().(float64) - if !ok { - return "", fmt.Errorf("could not convert \"%v\" to float64", argFloatVal.Value()) - } - matchedLocale, err := matchLanguage(locale) - if err != nil { - return "", fmt.Errorf("error matching locale: %w", err) - } - fmtStr := fmt.Sprintf("%%%de", *precision) - return message.NewPrinter(matchedLocale).Sprintf(fmtStr, argFloat), nil } } -func (c *stringFormatter) Binary(arg ref.Val, locale string) (string, error) { +func (c *stringFormatter) Binary(arg ref.Val) (string, error) { switch arg.Type() { - case types.IntType: - argInt := arg.Value().(int64) - // locale is intentionally unused as integers formatted as binary - // strings are locale-independent - return fmt.Sprintf("%b", argInt), nil - case types.UintType: - argInt := arg.Value().(uint64) - return fmt.Sprintf("%b", argInt), nil case types.BoolType: - argBool := arg.Value().(bool) + argBool, ok := arg.Value().(bool) + if !ok { + return "", fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.BoolType) + } if argBool { return "1", nil } return "0", nil + case types.IntType: + argInt, ok := arg.Value().(int64) + if !ok { + return "", fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.IntType) + } + return strconv.FormatInt(argInt, 2), nil + case types.UintType: + argUint, ok := arg.Value().(uint64) + if !ok { + return "", fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.UintType) + } + return strconv.FormatUint(argUint, 2), nil default: return "", binaryFormatError(runtimeID, arg.Type().TypeName()) } } -func (c *stringFormatter) Hex(useUpper bool) func(ref.Val, string) (string, error) { - return func(arg ref.Val, locale string) (string, error) { - fmtStr := "%x" +func (c *stringFormatter) Hex(useUpper bool) func(ref.Val) (string, error) { + return func(arg ref.Val) (string, error) { + var fmtStr string if useUpper { fmtStr = "%X" + } else { + fmtStr = "%x" } switch arg.Type() { - case types.StringType, types.BytesType: - if arg.Type() == types.BytesType { - return fmt.Sprintf(fmtStr, arg.Value().([]byte)), nil - } - return fmt.Sprintf(fmtStr, arg.Value().(string)), nil case types.IntType: argInt, ok := arg.Value().(int64) if !ok { - return "", fmt.Errorf("could not convert \"%s\" to int64", arg.Value()) + return "", fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.IntType) } return fmt.Sprintf(fmtStr, argInt), nil case types.UintType: - argInt, ok := arg.Value().(uint64) + argUint, ok := arg.Value().(uint64) if !ok { - return "", fmt.Errorf("could not convert \"%s\" to uint64", arg.Value()) + return "", fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.UintType) } - return fmt.Sprintf(fmtStr, argInt), nil + return fmt.Sprintf(fmtStr, argUint), nil + case types.StringType: + argStr, ok := arg.Value().(string) + if !ok { + return "", fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.StringType) + } + return fmt.Sprintf(fmtStr, argStr), nil + case types.BytesType: + argBytes, ok := arg.Value().([]byte) + if !ok { + return "", fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.BytesType) + } + return fmt.Sprintf(fmtStr, argBytes), nil default: return "", hexFormatError(runtimeID, arg.Type().TypeName()) } } } -func (c *stringFormatter) Octal(arg ref.Val, locale string) (string, error) { +func (c *stringFormatter) Octal(arg ref.Val) (string, error) { switch arg.Type() { case types.IntType: - argInt := arg.Value().(int64) - return fmt.Sprintf("%o", argInt), nil + argInt, ok := arg.Value().(int64) + if !ok { + return "", fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.IntType) + } + return strconv.FormatInt(argInt, 8), nil case types.UintType: - argInt := arg.Value().(uint64) - return fmt.Sprintf("%o", argInt), nil + argUint, ok := arg.Value().(uint64) + if !ok { + return "", fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.UintType) + } + return strconv.FormatUint(argUint, 8), nil default: return "", octalFormatError(runtimeID, arg.Type().TypeName()) } @@ -432,7 +428,7 @@ func (stringFormatValidator) Validate(env *cel.Env, _ cel.ValidatorConfig, a *as ast: a, } // use a placeholder locale, since locale doesn't affect syntax - _, err := parseFormatString(formatStr, formatCheck, formatCheck, "en_US") + _, err := parseFormatString(formatStr, formatCheck, formatCheck) if err != nil { iss.ReportErrorAtID(getErrorExprID(e.ID(), err), "%v", err) continue @@ -504,7 +500,7 @@ type stringFormatChecker struct { ast *ast.AST } -func (c *stringFormatChecker) String(arg ref.Val, locale string) (string, error) { +func (c *stringFormatChecker) String(arg ref.Val) (string, error) { formatArg := c.args[c.currArgIndex] valid, badID := c.verifyString(formatArg) if !valid { @@ -513,20 +509,19 @@ func (c *stringFormatChecker) String(arg ref.Val, locale string) (string, error) return "", nil } -func (c *stringFormatChecker) Decimal(arg ref.Val, locale string) (string, error) { +func (c *stringFormatChecker) Decimal(arg ref.Val) (string, error) { id := c.args[c.currArgIndex].ID() - valid := c.verifyTypeOneOf(id, types.IntType, types.UintType) + valid := c.verifyTypeOneOf(id, types.IntType, types.UintType, types.DoubleType) if !valid { return "", decimalFormatError(id, c.typeOf(id).TypeName()) } return "", nil } -func (c *stringFormatChecker) Fixed(precision *int) func(ref.Val, string) (string, error) { - return func(arg ref.Val, locale string) (string, error) { +func (c *stringFormatChecker) Fixed(precision int) func(ref.Val) (string, error) { + return func(arg ref.Val) (string, error) { id := c.args[c.currArgIndex].ID() - // we allow StringType since "NaN", "Infinity", and "-Infinity" are also valid values - valid := c.verifyTypeOneOf(id, types.DoubleType, types.StringType) + valid := c.verifyTypeOneOf(id, types.IntType, types.UintType, types.DoubleType) if !valid { return "", fixedPointFormatError(id, c.typeOf(id).TypeName()) } @@ -534,10 +529,10 @@ func (c *stringFormatChecker) Fixed(precision *int) func(ref.Val, string) (strin } } -func (c *stringFormatChecker) Scientific(precision *int) func(ref.Val, string) (string, error) { - return func(arg ref.Val, locale string) (string, error) { +func (c *stringFormatChecker) Scientific(precision int) func(ref.Val) (string, error) { + return func(arg ref.Val) (string, error) { id := c.args[c.currArgIndex].ID() - valid := c.verifyTypeOneOf(id, types.DoubleType, types.StringType) + valid := c.verifyTypeOneOf(id, types.IntType, types.UintType, types.DoubleType) if !valid { return "", scientificFormatError(id, c.typeOf(id).TypeName()) } @@ -545,17 +540,17 @@ func (c *stringFormatChecker) Scientific(precision *int) func(ref.Val, string) ( } } -func (c *stringFormatChecker) Binary(arg ref.Val, locale string) (string, error) { +func (c *stringFormatChecker) Binary(arg ref.Val) (string, error) { id := c.args[c.currArgIndex].ID() - valid := c.verifyTypeOneOf(id, types.IntType, types.UintType, types.BoolType) + valid := c.verifyTypeOneOf(id, types.BoolType, types.IntType, types.UintType) if !valid { return "", binaryFormatError(id, c.typeOf(id).TypeName()) } return "", nil } -func (c *stringFormatChecker) Hex(useUpper bool) func(ref.Val, string) (string, error) { - return func(arg ref.Val, locale string) (string, error) { +func (c *stringFormatChecker) Hex(useUpper bool) func(ref.Val) (string, error) { + return func(arg ref.Val) (string, error) { id := c.args[c.currArgIndex].ID() valid := c.verifyTypeOneOf(id, types.IntType, types.UintType, types.StringType, types.BytesType) if !valid { @@ -565,7 +560,7 @@ func (c *stringFormatChecker) Hex(useUpper bool) func(ref.Val, string) (string, } } -func (c *stringFormatChecker) Octal(arg ref.Val, locale string) (string, error) { +func (c *stringFormatChecker) Octal(arg ref.Val) (string, error) { id := c.args[c.currArgIndex].ID() valid := c.verifyTypeOneOf(id, types.IntType, types.UintType) if !valid { @@ -647,27 +642,27 @@ func (c *stringFormatChecker) verifyString(sub ast.Expr) (bool, int64) { // runtime execution. func binaryFormatError(id int64, badType string) error { - return newFormatError(id, "only integers and bools can be formatted as binary, was given %s", badType) + return newFormatError(id, "only ints, uints, and bools can be formatted as binary, was given %s", badType) } func decimalFormatError(id int64, badType string) error { - return newFormatError(id, "decimal clause can only be used on integers, was given %s", badType) + return newFormatError(id, "decimal clause can only be used on ints, uints, and doubles, was given %s", badType) } func fixedPointFormatError(id int64, badType string) error { - return newFormatError(id, "fixed-point clause can only be used on doubles, was given %s", badType) + return newFormatError(id, "fixed-point clause can only be used on ints, uints, and doubles, was given %s", badType) } func hexFormatError(id int64, badType string) error { - return newFormatError(id, "only integers, byte buffers, and strings can be formatted as hex, was given %s", badType) + return newFormatError(id, "only ints, uints, bytes, and strings can be formatted as hex, was given %s", badType) } func octalFormatError(id int64, badType string) error { - return newFormatError(id, "octal clause can only be used on integers, was given %s", badType) + return newFormatError(id, "octal clause can only be used on ints and uints, was given %s", badType) } func scientificFormatError(id int64, badType string) error { - return newFormatError(id, "scientific clause can only be used on doubles, was given %s", badType) + return newFormatError(id, "scientific clause can only be used on ints, uints, and doubles, was given %s", badType) } func stringFormatError(id int64, badType string) error { @@ -717,33 +712,33 @@ func (c *stringArgList) Size() int64 { type formatStringInterpolator interface { // String takes a ref.Val and a string representing the current locale identifier // and returns the Val formatted as a string, or an error if one occurred. - String(ref.Val, string) (string, error) + String(ref.Val) (string, error) // Decimal takes a ref.Val and a string representing the current locale identifier // and returns the Val formatted as a decimal integer, or an error if one occurred. - Decimal(ref.Val, string) (string, error) + Decimal(ref.Val) (string, error) // Fixed takes an int pointer representing precision (or nil if none was given) and // returns a function operating in a similar manner to String and Decimal, taking a // ref.Val and locale and returning the appropriate string. A closure is returned // so precision can be set without needing an additional function call/configuration. - Fixed(*int) func(ref.Val, string) (string, error) + Fixed(int) func(ref.Val) (string, error) // Scientific functions identically to Fixed, except the string returned from the closure // is expected to be in scientific notation. - Scientific(*int) func(ref.Val, string) (string, error) + Scientific(int) func(ref.Val) (string, error) // Binary takes a ref.Val and a string representing the current locale identifier // and returns the Val formatted as a binary integer, or an error if one occurred. - Binary(ref.Val, string) (string, error) + Binary(ref.Val) (string, error) // Hex takes a boolean that, if true, indicates the hex string output by the returned // closure should use uppercase letters for A-F. - Hex(bool) func(ref.Val, string) (string, error) + Hex(bool) func(ref.Val) (string, error) // Octal takes a ref.Val and a string representing the current locale identifier and // returns the Val formatted in octal, or an error if one occurred. - Octal(ref.Val, string) (string, error) + Octal(ref.Val) (string, error) } // formatListArgs is an interface that allows user-defined list-like datatypes to be used @@ -758,7 +753,7 @@ type formatListArgs interface { // parseFormatString formats a string according to the string.format syntax, taking the clause implementations // from the provided FormatCallback and the args from the given FormatList. -func parseFormatString(formatStr string, callback formatStringInterpolator, list formatListArgs, locale string) (string, error) { +func parseFormatString(formatStr string, callback formatStringInterpolator, list formatListArgs) (string, error) { i := 0 argIndex := 0 var builtStr strings.Builder @@ -782,7 +777,7 @@ func parseFormatString(formatStr string, callback formatStringInterpolator, list if int64(argIndex) >= list.Size() { return "", fmt.Errorf("index %d out of range", argIndex) } - numRead, val, refErr := parseAndFormatClause(formatStr[i:], argAny, callback, list, locale) + numRead, val, refErr := parseAndFormatClause(formatStr[i:], argAny, callback, list) if refErr != nil { return "", refErr } @@ -806,7 +801,7 @@ func parseFormatString(formatStr string, callback formatStringInterpolator, list // parseAndFormatClause parses the format clause at the start of the given string with val, and returns // how many characters were consumed and the substituted string form of val, or an error if one occurred. -func parseAndFormatClause(formatStr string, val ref.Val, callback formatStringInterpolator, list formatListArgs, locale string) (int, string, error) { +func parseAndFormatClause(formatStr string, val ref.Val, callback formatStringInterpolator, list formatListArgs) (int, string, error) { i := 1 read, formatter, err := parseFormattingClause(formatStr[i:], callback) i += read @@ -814,7 +809,7 @@ func parseAndFormatClause(formatStr string, val ref.Val, callback formatStringIn return -1, "", newParseFormatError("could not parse formatting clause", err) } - valStr, err := formatter(val, locale) + valStr, err := formatter(val) if err != nil { return -1, "", newParseFormatError("error during formatting", err) } @@ -850,16 +845,16 @@ func parseFormattingClause(formatStr string, callback formatStringInterpolator) } } -func parsePrecision(formatStr string) (int, *int, error) { +func parsePrecision(formatStr string) (int, int, error) { i := 0 if formatStr[i] != '.' { - return i, nil, nil + return i, defaultPrecision, nil } i++ var buffer strings.Builder for { if i >= len(formatStr) { - return -1, nil, errors.New("could not find end of precision specifier") + return -1, -1, errors.New("could not find end of precision specifier") } if !isASCIIDigit(rune(formatStr[i])) { break @@ -869,9 +864,12 @@ func parsePrecision(formatStr string) (int, *int, error) { } precision, err := strconv.Atoi(buffer.String()) if err != nil { - return -1, nil, fmt.Errorf("error while converting precision to integer: %w", err) + return -1, -1, fmt.Errorf("error while converting precision to integer: %w", err) + } + if precision < 0 { + return -1, -1, fmt.Errorf("negative precision: %d", precision) } - return i, &precision, nil + return i, precision, nil } func isASCIIDigit(r rune) bool { diff --git a/ext/strings.go b/ext/strings.go index 2e590a4c5..28b7a2599 100644 --- a/ext/strings.go +++ b/ext/strings.go @@ -25,8 +25,6 @@ import ( "unicode" "unicode/utf8" - "golang.org/x/text/language" - "github.com/google/cel-go/cel" "github.com/google/cel-go/common/types" "github.com/google/cel-go/common/types/ref" @@ -298,7 +296,6 @@ func Strings(options ...StringsOption) cel.EnvOption { } type stringLib struct { - locale string version uint32 validateFormat bool } @@ -311,16 +308,6 @@ func (*stringLib) LibraryName() string { // StringsOption is a functional interface for configuring the strings library. type StringsOption func(*stringLib) *stringLib -// StringsLocale configures the library with the given locale. The locale tag will -// be checked for validity at the time that EnvOptions are configured. If this option -// is not passed, string.format will behave as if en_US was passed as the locale. -func StringsLocale(locale string) StringsOption { - return func(sl *stringLib) *stringLib { - sl.locale = locale - return sl - } -} - // StringsVersion configures the version of the string library. // // The version limits which functions are available. Only functions introduced @@ -350,20 +337,6 @@ func StringsValidateFormatCalls(value bool) StringsOption { // CompileOptions implements the Library interface method. func (lib *stringLib) CompileOptions() []cel.EnvOption { - formatLocale := "en_US" - if lib.locale != "" { - // ensure locale is properly-formed if set - _, err := language.Parse(lib.locale) - if err != nil { - return []cel.EnvOption{ - func(e *cel.Env) (*cel.Env, error) { - return nil, fmt.Errorf("failed to parse locale: %w", err) - }, - } - } - formatLocale = lib.locale - } - opts := []cel.EnvOption{ cel.Function("charAt", cel.MemberOverload("string_char_at_int", []*cel.Type{cel.StringType, cel.IntType}, cel.StringType, @@ -471,7 +444,7 @@ func (lib *stringLib) CompileOptions() []cel.EnvOption { cel.FunctionBinding(func(args ...ref.Val) ref.Val { s := string(args[0].(types.String)) formatArgs := args[1].(traits.Lister) - return stringOrError(parseFormatString(s, &stringFormatter{}, &stringArgList{formatArgs}, formatLocale)) + return stringOrError(parseFormatString(s, &stringFormatter{}, &stringArgList{formatArgs})) }))), cel.Function("strings.quote", cel.Overload("strings_quote", []*cel.Type{cel.StringType}, cel.StringType, cel.UnaryBinding(func(str ref.Val) ref.Val { diff --git a/ext/strings_test.go b/ext/strings_test.go index 22aab84e6..0d1017027 100644 --- a/ext/strings_test.go +++ b/ext/strings_test.go @@ -450,7 +450,6 @@ func TestStringFormat(t *testing.T) { format string dynArgs map[string]any formatArgs string - locale string err string expectedOutput string expectedRuntimeCost uint64 @@ -527,7 +526,6 @@ func TestStringFormat(t *testing.T) { expectedOutput: "1.234", expectedRuntimeCost: 11, expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, - locale: "en_US", }, { name: "binary formatting clause", @@ -661,17 +659,7 @@ func TestStringFormat(t *testing.T) { name: "scientific notation formatting clause", format: "%.6e", formatArgs: "1052.032911275", - expectedOutput: "1.052033\u202f\u00d7\u202f10\u2070\u00b3", - expectedRuntimeCost: 11, - expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, - locale: "en_US", - }, - { - name: "locale support", - format: "%.3f", - formatArgs: "3.14", - locale: "fr_FR", - expectedOutput: "3,140", + expectedOutput: "1.052033e+03", expectedRuntimeCost: 11, expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, }, @@ -682,16 +670,14 @@ func TestStringFormat(t *testing.T) { expectedOutput: "2.718280", expectedRuntimeCost: 11, expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, - locale: "en_US", }, { name: "default precision for scientific notation", format: "%e", formatArgs: "2.71828", - expectedOutput: "2.718280\u202f\u00d7\u202f10\u2070\u2070", + expectedOutput: "2.718280e+00", expectedRuntimeCost: 11, expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, - locale: "en_US", }, { name: "default precision for string", @@ -700,70 +686,54 @@ func TestStringFormat(t *testing.T) { expectedOutput: "2.71", expectedRuntimeCost: 11, expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, - locale: "en_US", }, { name: "default list precision for string", format: "%s", formatArgs: "[2.71]", - expectedOutput: "[2.710000]", + expectedOutput: "[2.71]", expectedRuntimeCost: 21, expectedEstimatedCost: checker.CostEstimate{Min: 21, Max: 21}, - locale: "en_US", }, { - name: "default scientific notation for string", + name: "default format for string", format: "%s", formatArgs: "0.000000002", - expectedOutput: "2e-09", + expectedOutput: "0.000000002", expectedRuntimeCost: 11, expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, - locale: "en_US", }, { name: "default list scientific notation for string", format: "%s", formatArgs: "[0.000000002]", - expectedOutput: "[0.000000]", + expectedOutput: "[0.000000002]", expectedRuntimeCost: 21, expectedEstimatedCost: checker.CostEstimate{Min: 21, Max: 21}, - locale: "en_US", - }, - { - name: "unicode output for scientific notation", - format: "unescaped unicode: %e, escaped unicode: %e", - formatArgs: "2.71828, 2.71828", - expectedOutput: "unescaped unicode: 2.718280 × 10⁰⁰, escaped unicode: 2.718280\u202f\u00d7\u202f10\u2070\u2070", - expectedRuntimeCost: 15, - expectedEstimatedCost: checker.CostEstimate{Min: 15, Max: 15}, - locale: "en_US", }, { name: "NaN support for fixed-point", format: "%f", - formatArgs: `"NaN"`, + formatArgs: `double("NaN")`, expectedOutput: "NaN", - expectedRuntimeCost: 11, - expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, - locale: "en_US", + expectedRuntimeCost: 12, + expectedEstimatedCost: checker.CostEstimate{Min: 12, Max: 12}, }, { name: "positive infinity support for fixed-point", format: "%f", - formatArgs: `"Infinity"`, - expectedOutput: "∞", - expectedRuntimeCost: 11, - expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, - locale: "en_US", + formatArgs: `double("Infinity")`, + expectedOutput: "Infinity", + expectedRuntimeCost: 12, + expectedEstimatedCost: checker.CostEstimate{Min: 12, Max: 12}, }, { name: "negative infinity support for fixed-point", format: "%f", - formatArgs: `"-Infinity"`, - expectedOutput: "-∞", - expectedRuntimeCost: 11, - expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, - locale: "en_US", + formatArgs: `double("-Infinity")`, + expectedOutput: "-Infinity", + expectedRuntimeCost: 12, + expectedEstimatedCost: checker.CostEstimate{Min: 12, Max: 12}, }, { name: "NaN support for string", @@ -774,20 +744,20 @@ func TestStringFormat(t *testing.T) { { name: "positive infinity support for string", format: "%s", - formatArgs: `double("Inf")`, - expectedOutput: "+Inf", + formatArgs: `double("Infinity")`, + expectedOutput: "Infinity", }, { name: "negative infinity support for string", format: "%s", - formatArgs: `double("-Inf")`, - expectedOutput: "-Inf", + formatArgs: `double("-Infinity")`, + expectedOutput: "-Infinity", }, { name: "infinity list support for string", format: "%s", - formatArgs: `[double("NaN"),double("+Inf"), double("-Inf")]`, - expectedOutput: `["NaN", "+Inf", "-Inf"]`, + formatArgs: `[double("NaN"),double("+Infinity"), double("-Infinity")]`, + expectedOutput: `[NaN, Infinity, -Infinity]`, }, { name: "uint support for decimal clause", @@ -857,7 +827,7 @@ func TestStringFormat(t *testing.T) { name: "list support for string", format: "%s", formatArgs: `["abc", 3.14, null, [9, 8, 7, 6], timestamp("2023-02-03T23:31:20Z")]`, - expectedOutput: `["abc", 3.140000, null, [9, 8, 7, 6], timestamp("2023-02-03T23:31:20Z")]`, + expectedOutput: `[abc, 3.14, null, [9, 8, 7, 6], 2023-02-03T23:31:20Z]`, expectedRuntimeCost: 32, expectedEstimatedCost: checker.CostEstimate{Min: 32, Max: 32}, }, @@ -865,8 +835,7 @@ func TestStringFormat(t *testing.T) { name: "map support for string", format: "%s", formatArgs: `{"key1": b"xyz", "key5": null, "key2": duration("2h"), "key4": true, "key3": 2.71828}`, - locale: "nl_NL", - expectedOutput: `{"key1":b"xyz", "key2":duration("7200s"), "key3":2.718280, "key4":true, "key5":null}`, + expectedOutput: `{key1: xyz, key2: 7200s, key3: 2.71828, key4: true, key5: null}`, expectedRuntimeCost: 42, expectedEstimatedCost: checker.CostEstimate{Min: 42, Max: 42}, }, @@ -874,7 +843,7 @@ func TestStringFormat(t *testing.T) { name: "map support (all key types)", format: "map with multiple key types: %s", formatArgs: `{1: "value1", uint(2): "value2", true: double("NaN")}`, - expectedOutput: `map with multiple key types: {1:"value1", 2:"value2", true:"NaN"}`, + expectedOutput: `map with multiple key types: {1: value1, 2: value2, true: NaN}`, expectedRuntimeCost: 46, expectedEstimatedCost: checker.CostEstimate{Min: 46, Max: 46}, }, @@ -908,7 +877,6 @@ func TestStringFormat(t *testing.T) { expectedOutput: "dynIntStr: 32 dynDoubleStr: 56.8", expectedRuntimeCost: 15, expectedEstimatedCost: checker.CostEstimate{Min: 15, Max: 15}, - locale: "en_US", }, { name: "dyntype support for integer formatting clause", @@ -975,19 +943,6 @@ func TestStringFormat(t *testing.T) { expectedOutput: "dynamic double: 4.500", expectedRuntimeCost: 13, expectedEstimatedCost: checker.CostEstimate{Min: 13, Max: 13}, - locale: "en_US", - }, - { - name: "dyntype support for fixed-point formatting clause (comma separator locale)", - format: "dynamic double: %f", - formatArgs: `dynDouble`, - dynArgs: map[string]any{ - "dynDouble": 4.5, - }, - expectedOutput: "dynamic double: 4,500000", - expectedRuntimeCost: 13, - expectedEstimatedCost: checker.CostEstimate{Min: 13, Max: 13}, - locale: "fr_FR", }, { name: "dyntype support for scientific notation", @@ -996,10 +951,9 @@ func TestStringFormat(t *testing.T) { dynArgs: map[string]any{ "dynE": 2.71828, }, - expectedOutput: "(dyntype) e: 2.718280\u202f\u00d7\u202f10\u2070\u2070", + expectedOutput: "(dyntype) e: 2.718280e+00", expectedRuntimeCost: 13, expectedEstimatedCost: checker.CostEstimate{Min: 13, Max: 13}, - locale: "en_US", }, { name: "dyntype NaN/infinity support for fixed-point", @@ -1009,7 +963,7 @@ func TestStringFormat(t *testing.T) { "dynNaN": math.NaN(), "dynInf": math.Inf(1), }, - expectedOutput: "NaN: NaN, infinity: ∞", + expectedOutput: "NaN: NaN, infinity: Infinity", expectedRuntimeCost: 15, expectedEstimatedCost: checker.CostEstimate{Min: 15, Max: 15}, }, @@ -1042,7 +996,7 @@ func TestStringFormat(t *testing.T) { dynArgs: map[string]any{ "dynList": []any{6, 4.2, "a string"}, }, - expectedOutput: `dyntype list: [6, 4.200000, "a string"]`, + expectedOutput: `dyntype list: [6, 4.2, a string]`, expectedRuntimeCost: 13, expectedEstimatedCost: checker.CostEstimate{Min: 13, Max: 13}, }, @@ -1057,7 +1011,7 @@ func TestStringFormat(t *testing.T) { int64(6): mustParseDuration("7m2s"), }, }, - expectedOutput: `dyntype map: {"strKey":"x", 6:duration("422s"), true:42}`, + expectedOutput: `dyntype map: {6: 422s, strKey: x, true: 42}`, expectedRuntimeCost: 13, expectedEstimatedCost: checker.CostEstimate{Min: 13, Max: 13}, }, @@ -1071,7 +1025,6 @@ func TestStringFormat(t *testing.T) { SingleDouble: 1.0, }, }, - locale: "en_US", expectedOutput: `message field msg.single_int32: 2, msg.single_double: 1.0`, }, { @@ -1093,28 +1046,28 @@ func TestStringFormat(t *testing.T) { format: "string is %b", formatArgs: `"abc"`, skipCompileCheck: true, - err: "error during formatting: only integers and bools can be formatted as binary, was given string", + err: "error during formatting: only ints, uints, and bools can be formatted as binary, was given string", }, { name: "duration substitution not allowed with decimal clause", format: "%d", formatArgs: `duration("30m2s")`, skipCompileCheck: true, - err: "error during formatting: decimal clause can only be used on integers, was given google.protobuf.Duration", + err: "error during formatting: decimal clause can only be used on ints, uints, and doubles, was given google.protobuf.Duration", }, { name: "string substitution not allowed with octal clause", format: "octal: %o", formatArgs: `"a string"`, skipCompileCheck: true, - err: "error during formatting: octal clause can only be used on integers, was given string", + err: "error during formatting: octal clause can only be used on ints and uints, was given string", }, { name: "double substitution not allowed with hex clause", format: "double is %x", formatArgs: "0.5", skipCompileCheck: true, - err: "error during formatting: only integers, byte buffers, and strings can be formatted as hex, was given double", + err: "error during formatting: only ints, uints, bytes, and strings can be formatted as hex, was given double", }, { name: "uppercase not allowed for scientific clause", @@ -1149,49 +1102,49 @@ func TestStringFormat(t *testing.T) { format: "null: %d", formatArgs: "null", skipCompileCheck: true, - err: "error during formatting: decimal clause can only be used on integers, was given null_type", + err: "error during formatting: decimal clause can only be used on ints, uints, and doubles, was given null_type", }, { name: "null not allowed for %e", format: "null: %e", formatArgs: "null", skipCompileCheck: true, - err: "error during formatting: scientific clause can only be used on doubles, was given null_type", + err: "error during formatting: scientific clause can only be used on ints, uints, and doubles, was given null_type", }, { name: "null not allowed for %f", format: "null: %f", formatArgs: "null", skipCompileCheck: true, - err: "error during formatting: fixed-point clause can only be used on doubles, was given null_type", + err: "error during formatting: fixed-point clause can only be used on ints, uints, and doubles, was given null_type", }, { name: "null not allowed for %x", format: "null: %x", formatArgs: "null", skipCompileCheck: true, - err: "error during formatting: only integers, byte buffers, and strings can be formatted as hex, was given null_type", + err: "error during formatting: only ints, uints, bytes, and strings can be formatted as hex, was given null_type", }, { name: "null not allowed for %X", format: "null: %X", formatArgs: "null", skipCompileCheck: true, - err: "error during formatting: only integers, byte buffers, and strings can be formatted as hex, was given null_type", + err: "error during formatting: only ints, uints, bytes, and strings can be formatted as hex, was given null_type", }, { name: "null not allowed for %b", format: "null: %b", formatArgs: "null", skipCompileCheck: true, - err: "error during formatting: only integers and bools can be formatted as binary, was given null_type", + err: "error during formatting: only ints, uints, and bools can be formatted as binary, was given null_type", }, { name: "null not allowed for %o", format: "null: %o", formatArgs: "null", skipCompileCheck: true, - err: "error during formatting: octal clause can only be used on integers, was given null_type", + err: "error during formatting: octal clause can only be used on ints and uints, was given null_type", }, { name: "compile-time cardinality check (too few for string)", @@ -1233,14 +1186,14 @@ func TestStringFormat(t *testing.T) { { name: "compile-time %d check", format: "int is %d", - formatArgs: "5.2", - err: "error during formatting: decimal clause can only be used on integers", + formatArgs: "null", + err: "error during formatting: decimal clause can only be used on ints, uints, and doubles, was given null_type", }, { name: "compile-time %f check", format: "double is %f", formatArgs: "true", - err: "error during formatting: fixed-point clause can only be used on doubles", + err: "error during formatting: fixed-point clause can only be used on ints, uints, and doubles, was given bool", }, { name: "compile-time precision syntax check", @@ -1252,31 +1205,31 @@ func TestStringFormat(t *testing.T) { name: "compile-time %e check", format: "double is %e", formatArgs: "true", - err: "error during formatting: scientific clause can only be used on doubles", + err: "error during formatting: scientific clause can only be used on ints, uints, and doubles, was given bool", }, { name: "compile-time %b check", format: "string is %b", formatArgs: `"a string"`, - err: "error during formatting: only integers and bools can be formatted as binary", + err: "error during formatting: only ints, uints, and bools can be formatted as binary, was given string", }, { name: "compile-time %x check", format: "%x is a double", formatArgs: "2.5", - err: "error during formatting: only integers, byte buffers, and strings can be formatted as hex", + err: "error during formatting: only ints, uints, bytes, and strings can be formatted as hex, was given double", }, { name: "compile-time %X check", format: "%X is a double", formatArgs: "2.5", - err: "error during formatting: only integers, byte buffers, and strings can be formatted as hex", + err: "error during formatting: only ints, uints, bytes, and strings can be formatted as hex, was given double", }, { name: "compile-time %o check", format: "an octal: %o", formatArgs: "3.14", - err: "error during formatting: octal clause can only be used on integers", + err: "octal clause can only be used on ints and uints, was given double", }, } evalExpr := func(env *cel.Env, expr string, evalArgs any, expectedRuntimeCost uint64, expectedEstimatedCost checker.CostEstimate, t *testing.T) (ref.Val, error) { @@ -1364,9 +1317,9 @@ func TestStringFormat(t *testing.T) { } return opts } - buildOpts := func(skipCompileCheck bool, locale string, variables []cel.EnvOption) []cel.EnvOption { + buildOpts := func(skipCompileCheck bool, variables []cel.EnvOption) []cel.EnvOption { opts := []cel.EnvOption{ - Strings(StringsLocale(locale), StringsValidateFormatCalls(!skipCompileCheck)), + Strings(StringsValidateFormatCalls(!skipCompileCheck)), cel.Container("ext"), cel.Abbrevs("google.expr.proto3.test"), cel.Types(&proto3pb.TestAllTypes{}), @@ -1379,8 +1332,8 @@ func TestStringFormat(t *testing.T) { opts = append(opts, variables...) return opts } - runCase := func(format, formatArgs, locale string, dynArgs map[string]any, skipCompileCheck bool, expectedRuntimeCost uint64, expectedEstimatedCost checker.CostEstimate, t *testing.T) (ref.Val, error) { - env, err := cel.NewEnv(buildOpts(skipCompileCheck, locale, buildVariables(dynArgs))...) + runCase := func(format, formatArgs string, dynArgs map[string]any, skipCompileCheck bool, expectedRuntimeCost uint64, expectedEstimatedCost checker.CostEstimate, t *testing.T) (ref.Val, error) { + env, err := cel.NewEnv(buildOpts(skipCompileCheck, buildVariables(dynArgs))...) if err != nil { t.Fatalf("cel.NewEnv() failed: %v", err) } @@ -1412,16 +1365,8 @@ func TestStringFormat(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - out, err := runCase(tt.format, tt.formatArgs, tt.locale, tt.dynArgs, tt.skipCompileCheck, tt.expectedRuntimeCost, tt.expectedEstimatedCost, t) + out, err := runCase(tt.format, tt.formatArgs, tt.dynArgs, tt.skipCompileCheck, tt.expectedRuntimeCost, tt.expectedEstimatedCost, t) checkCase(out, tt.expectedOutput, err, tt.err, t) - if tt.locale == "" { - // if the test has no locale specified, then that means it - // should have the same output regardless of locale - t.Run("no change on locale", func(t *testing.T) { - out, err := runCase(tt.format, tt.formatArgs, "da_DK", tt.dynArgs, tt.skipCompileCheck, tt.expectedRuntimeCost, tt.expectedEstimatedCost, t) - checkCase(out, tt.expectedOutput, err, tt.err, t) - }) - } }) } } @@ -1433,7 +1378,7 @@ func TestStringFormatHeterogeneousLiterals(t *testing.T) { }{ { expr: `"list: %s".format([[[1, 2, [3.0, 4]]]])`, - out: `list: [[1, 2, [3.000000, 4]]]`, + out: `list: [[1, 2, [3, 4]]]`, }, { expr: `"list size: %d".format([[[1, 2, [3.0, 4]]].size()])`, @@ -1441,7 +1386,7 @@ func TestStringFormatHeterogeneousLiterals(t *testing.T) { }, { expr: `"list element: %s".format([[[1, 2, [3.0, 4]]][0]])`, - out: `list element: [1, 2, [3.000000, 4]]`, + out: `list element: [1, 2, [3, 4]]`, }, } env, err := cel.NewEnv(Strings(), cel.ASTValidators(cel.ValidateHomogeneousAggregateLiterals())) @@ -1470,83 +1415,6 @@ func TestStringFormatHeterogeneousLiterals(t *testing.T) { } } -func TestBadLocale(t *testing.T) { - _, err := cel.NewEnv(Strings(StringsLocale("bad-locale"))) - if err != nil { - if err.Error() != "failed to parse locale: language: subtag \"locale\" is well-formed but unknown" { - t.Errorf("expected error messaged to be \"failed to parse locale: language: subtag \"locale\" is well-formed but unknown\", got %q", err) - } - } else { - t.Error("expected NewEnv to fail during locale parsing") - } -} - -func TestLiteralOutput(t *testing.T) { - tests := []struct { - name string - formatLiteral string - expectedType string - }{ - { - name: "map literal support", - formatLiteral: `{"key1": b"xyz", false: [11, 12, 13, timestamp("2019-10-12T07:20:50.52Z")], 42: {uint(64): 2.7}, "key5": type(int), "key2": duration("2h"), "key4": true, "key3": 2.71828, "null": null}`, - expectedType: `map`, - }, - { - name: "list literal support", - formatLiteral: `["abc", 3.14, uint(32), b"def", null, type(string), duration("7m"), [9, 8, 7, 6], timestamp("2023-02-03T23:31:20Z")]`, - expectedType: `list`, - }, - } - for _, tt := range tests { - parseAndEval := func(expr string, t *testing.T) (ref.Val, error) { - env, err := cel.NewEnv(Strings()) - if err != nil { - t.Fatalf("cel.NewEnv(Strings()) failed: %v", err) - } - parsedAst, issues := env.Parse(expr) - if issues.Err() != nil { - t.Fatalf("env.Parse(%v) failed: %v", expr, issues.Err()) - } - checkedAst, issues := env.Check(parsedAst) - if issues.Err() != nil { - t.Fatalf("env.Check(%v) failed: %v", expr, issues.Err()) - } - program, err := env.Program(checkedAst) - if err != nil { - t.Fatal(err) - } - out, _, err := program.Eval(cel.NoVars()) - return out, err - } - t.Run(tt.name, func(t *testing.T) { - expr := fmt.Sprintf(`"%%s".format([%s])`, tt.formatLiteral) - literalVal, err := parseAndEval(expr, t) - if err != nil { - t.Fatalf("program.Eval failed: %v", err) - } - out, err := parseAndEval(literalVal.Value().(string), t) - if err != nil { - t.Fatalf("literal evaluation failed: %v", err) - } - if out.Type().TypeName() != tt.expectedType { - t.Errorf("expected literal to evaluate to type %s, got %s", tt.expectedType, out.Type().TypeName()) - } - equivalentVal, err := parseAndEval(literalVal.Value().(string)+" == "+tt.formatLiteral, t) - if err != nil { - t.Fatalf("equality evaluation failed: %v:", err) - } - if equivalentVal.Type().TypeName() != "bool" { - t.Errorf("expected equality expression to evaluation to type bool, got %s", equivalentVal.Type().TypeName()) - } - equivalent := equivalentVal.Value().(bool) - if !equivalent { - t.Errorf("%q (observed) and %q (expected) not considered equivalent", literalVal.Value().(string), tt.formatLiteral) - } - }) - } -} - func mustParseDuration(s string) time.Duration { d, err := time.ParseDuration(s) if err != nil { diff --git a/go.mod b/go.mod index ae23e9ee6..f7d96d112 100644 --- a/go.mod +++ b/go.mod @@ -5,10 +5,9 @@ go 1.21.1 toolchain go1.23.0 require ( - cel.dev/expr v0.19.1 + cel.dev/expr v0.21.2 github.com/antlr4-go/antlr/v4 v4.13.0 github.com/stoewer/go-strcase v1.2.0 - golang.org/x/text v0.16.0 google.golang.org/genproto/googleapis/api v0.0.0-20240826202546-f6391c0de4c7 google.golang.org/protobuf v1.34.2 gopkg.in/yaml.v3 v3.0.1 diff --git a/go.sum b/go.sum index b518e1a53..3d6fbb7eb 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -cel.dev/expr v0.19.1 h1:NciYrtDRIR0lNCnH1LFJegdjspNx9fI59O7TWcua/W4= -cel.dev/expr v0.19.1/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw= +cel.dev/expr v0.21.2 h1:o+Wj235dy4gFYlYin3JsMpp3EEfMrPm/6tdoyjT98S0= +cel.dev/expr v0.21.2/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw= github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI= github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= @@ -15,8 +15,6 @@ github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc h1:mCRnTeVUjcrhlRmO0VK8a6k6Rrf6TF9htwo2pJVSjIU= golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= google.golang.org/genproto/googleapis/api v0.0.0-20240826202546-f6391c0de4c7 h1:YcyjlL1PRr2Q17/I0dPk2JmYS5CDXfcdb2Z3YRioEbw= google.golang.org/genproto/googleapis/api v0.0.0-20240826202546-f6391c0de4c7/go.mod h1:OCdP9MfskevB/rbYvHTsXTtKC+3bHWajPdoKgjcYkfo= google.golang.org/genproto/googleapis/rpc v0.0.0-20240826202546-f6391c0de4c7 h1:2035KHhUv+EpyB+hWgJnaWKJOdX1E95w2S8Rr4uWKTs= diff --git a/vendor/cel.dev/expr/README.md b/vendor/cel.dev/expr/README.md index 7930c0b75..42d67f87c 100644 --- a/vendor/cel.dev/expr/README.md +++ b/vendor/cel.dev/expr/README.md @@ -69,5 +69,3 @@ For more detail, see: * [Language Definition](doc/langdef.md) Released under the [Apache License](LICENSE). - -Disclaimer: This is not an official Google product. diff --git a/vendor/golang.org/x/text/LICENSE b/vendor/golang.org/x/text/LICENSE deleted file mode 100644 index 6a66aea5e..000000000 --- a/vendor/golang.org/x/text/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2009 The Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/golang.org/x/text/PATENTS b/vendor/golang.org/x/text/PATENTS deleted file mode 100644 index 733099041..000000000 --- a/vendor/golang.org/x/text/PATENTS +++ /dev/null @@ -1,22 +0,0 @@ -Additional IP Rights Grant (Patents) - -"This implementation" means the copyrightable works distributed by -Google as part of the Go project. - -Google hereby grants to You a perpetual, worldwide, non-exclusive, -no-charge, royalty-free, irrevocable (except as stated in this section) -patent license to make, have made, use, offer to sell, sell, import, -transfer and otherwise run, modify and propagate the contents of this -implementation of Go, where such license applies only to those patent -claims, both currently owned or controlled by Google and acquired in -the future, licensable by Google that are necessarily infringed by this -implementation of Go. This grant does not include claims that would be -infringed only as a consequence of further modification of this -implementation. If you or your agent or exclusive licensee institute or -order or agree to the institution of patent litigation against any -entity (including a cross-claim or counterclaim in a lawsuit) alleging -that this implementation of Go or any code incorporated within this -implementation of Go constitutes direct or contributory patent -infringement, or inducement of patent infringement, then any patent -rights granted to you under this License for this implementation of Go -shall terminate as of the date such litigation is filed. diff --git a/vendor/golang.org/x/text/feature/plural/common.go b/vendor/golang.org/x/text/feature/plural/common.go deleted file mode 100644 index fdcb373fd..000000000 --- a/vendor/golang.org/x/text/feature/plural/common.go +++ /dev/null @@ -1,70 +0,0 @@ -// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. - -package plural - -// Form defines a plural form. -// -// Not all languages support all forms. Also, the meaning of each form varies -// per language. It is important to note that the name of a form does not -// necessarily correspond one-to-one with the set of numbers. For instance, -// for Croation, One matches not only 1, but also 11, 21, etc. -// -// Each language must at least support the form "other". -type Form byte - -const ( - Other Form = iota - Zero - One - Two - Few - Many -) - -var countMap = map[string]Form{ - "other": Other, - "zero": Zero, - "one": One, - "two": Two, - "few": Few, - "many": Many, -} - -type pluralCheck struct { - // category: - // 3..7: opID - // 0..2: category - cat byte - setID byte -} - -// opID identifies the type of operand in the plural rule, being i, n or f. -// (v, w, and t are treated as filters in our implementation.) -type opID byte - -const ( - opMod opID = 0x1 // is '%' used? - opNotEqual opID = 0x2 // using "!=" to compare - opI opID = 0 << 2 // integers after taking the absolute value - opN opID = 1 << 2 // full number (must be integer) - opF opID = 2 << 2 // fraction - opV opID = 3 << 2 // number of visible digits - opW opID = 4 << 2 // number of visible digits without trailing zeros - opBretonM opID = 5 << 2 // hard-wired rule for Breton - opItalian800 opID = 6 << 2 // hard-wired rule for Italian - opAzerbaijan00s opID = 7 << 2 // hard-wired rule for Azerbaijan -) -const ( - // Use this plural form to indicate the next rule needs to match as well. - // The last condition in the list will have the correct plural form. - andNext = 0x7 - formMask = 0x7 - - opShift = 3 - - // numN indicates the maximum integer, or maximum mod value, for which we - // have inclusion masks. - numN = 100 - // The common denominator of the modulo that is taken. - maxMod = 100 -) diff --git a/vendor/golang.org/x/text/feature/plural/message.go b/vendor/golang.org/x/text/feature/plural/message.go deleted file mode 100644 index 56d518cc3..000000000 --- a/vendor/golang.org/x/text/feature/plural/message.go +++ /dev/null @@ -1,244 +0,0 @@ -// 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 plural - -import ( - "fmt" - "io" - "reflect" - "strconv" - - "golang.org/x/text/internal/catmsg" - "golang.org/x/text/internal/number" - "golang.org/x/text/language" - "golang.org/x/text/message/catalog" -) - -// TODO: consider deleting this interface. Maybe VisibleDigits is always -// sufficient and practical. - -// Interface is used for types that can determine their own plural form. -type Interface interface { - // PluralForm reports the plural form for the given language of the - // underlying value. It also returns the integer value. If the integer value - // is larger than fits in n, PluralForm may return a value modulo - // 10,000,000. - PluralForm(t language.Tag, scale int) (f Form, n int) -} - -// Selectf returns the first case for which its selector is a match for the -// arg-th substitution argument to a formatting call, formatting it as indicated -// by format. -// -// The cases argument are pairs of selectors and messages. Selectors are of type -// string or Form. Messages are of type string or catalog.Message. A selector -// matches an argument if: -// - it is "other" or Other -// - it matches the plural form of the argument: "zero", "one", "two", "few", -// or "many", or the equivalent Form -// - it is of the form "=x" where x is an integer that matches the value of -// the argument. -// - it is of the form " kindDefault { - e.EncodeUint(uint64(m.scale)) - } - - forms := validForms(cardinal, e.Language()) - - for i := 0; i < len(m.cases); { - if err := compileSelector(e, forms, m.cases[i]); err != nil { - return err - } - if i++; i >= len(m.cases) { - return fmt.Errorf("plural: no message defined for selector %v", m.cases[i-1]) - } - var msg catalog.Message - switch x := m.cases[i].(type) { - case string: - msg = catalog.String(x) - case catalog.Message: - msg = x - default: - return fmt.Errorf("plural: message of type %T; must be string or catalog.Message", x) - } - if err := e.EncodeMessage(msg); err != nil { - return err - } - i++ - } - return nil -} - -func compileSelector(e *catmsg.Encoder, valid []Form, selector interface{}) error { - form := Other - switch x := selector.(type) { - case string: - if x == "" { - return fmt.Errorf("plural: empty selector") - } - if c := x[0]; c == '=' || c == '<' { - val, err := strconv.ParseUint(x[1:], 10, 16) - if err != nil { - return fmt.Errorf("plural: invalid number in selector %q: %v", selector, err) - } - e.EncodeUint(uint64(c)) - e.EncodeUint(val) - return nil - } - var ok bool - form, ok = countMap[x] - if !ok { - return fmt.Errorf("plural: invalid plural form %q", selector) - } - case Form: - form = x - default: - return fmt.Errorf("plural: selector of type %T; want string or Form", selector) - } - - ok := false - for _, f := range valid { - if f == form { - ok = true - break - } - } - if !ok { - return fmt.Errorf("plural: form %q not supported for language %q", selector, e.Language()) - } - e.EncodeUint(uint64(form)) - return nil -} - -func execute(d *catmsg.Decoder) bool { - lang := d.Language() - argN := int(d.DecodeUint()) - kind := int(d.DecodeUint()) - scale := -1 // default - if kind > kindDefault { - scale = int(d.DecodeUint()) - } - form := Other - n := -1 - if arg := d.Arg(argN); arg == nil { - // Default to Other. - } else if x, ok := arg.(number.VisibleDigits); ok { - d := x.Digits(nil, lang, scale) - form, n = cardinal.matchDisplayDigits(lang, &d) - } else if x, ok := arg.(Interface); ok { - // This covers lists and formatters from the number package. - form, n = x.PluralForm(lang, scale) - } else { - var f number.Formatter - switch kind { - case kindScale: - f.InitDecimal(lang) - f.SetScale(scale) - case kindScientific: - f.InitScientific(lang) - f.SetScale(scale) - case kindPrecision: - f.InitDecimal(lang) - f.SetPrecision(scale) - case kindDefault: - // sensible default - f.InitDecimal(lang) - if k := reflect.TypeOf(arg).Kind(); reflect.Int <= k && k <= reflect.Uintptr { - f.SetScale(0) - } else { - f.SetScale(2) - } - } - var dec number.Decimal // TODO: buffer in Printer - dec.Convert(f.RoundingContext, arg) - v := number.FormatDigits(&dec, f.RoundingContext) - if !v.NaN && !v.Inf { - form, n = cardinal.matchDisplayDigits(d.Language(), &v) - } - } - for !d.Done() { - f := d.DecodeUint() - if (f == '=' && n == int(d.DecodeUint())) || - (f == '<' && 0 <= n && n < int(d.DecodeUint())) || - form == Form(f) || - Other == Form(f) { - return d.ExecuteMessage() - } - d.SkipMessage() - } - return false -} diff --git a/vendor/golang.org/x/text/feature/plural/plural.go b/vendor/golang.org/x/text/feature/plural/plural.go deleted file mode 100644 index e9f2d42e0..000000000 --- a/vendor/golang.org/x/text/feature/plural/plural.go +++ /dev/null @@ -1,262 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:generate go run gen.go gen_common.go - -// Package plural provides utilities for handling linguistic plurals in text. -// -// The definitions in this package are based on the plural rule handling defined -// in CLDR. See -// https://unicode.org/reports/tr35/tr35-numbers.html#Language_Plural_Rules for -// details. -package plural - -import ( - "golang.org/x/text/internal/language/compact" - "golang.org/x/text/internal/number" - "golang.org/x/text/language" -) - -// Rules defines the plural rules for all languages for a certain plural type. -// -// This package is UNDER CONSTRUCTION and its API may change. -type Rules struct { - rules []pluralCheck - index []byte - langToIndex []byte - inclusionMasks []uint64 -} - -var ( - // Cardinal defines the plural rules for numbers indicating quantities. - Cardinal *Rules = cardinal - - // Ordinal defines the plural rules for numbers indicating position - // (first, second, etc.). - Ordinal *Rules = ordinal - - ordinal = &Rules{ - ordinalRules, - ordinalIndex, - ordinalLangToIndex, - ordinalInclusionMasks[:], - } - - cardinal = &Rules{ - cardinalRules, - cardinalIndex, - cardinalLangToIndex, - cardinalInclusionMasks[:], - } -) - -// getIntApprox converts the digits in slice digits[start:end] to an integer -// according to the following rules: -// - Let i be asInt(digits[start:end]), where out-of-range digits are assumed -// to be zero. -// - Result n is big if i / 10^nMod > 1. -// - Otherwise the result is i % 10^nMod. -// -// For example, if digits is {1, 2, 3} and start:end is 0:5, then the result -// for various values of nMod is: -// - when nMod == 2, n == big -// - when nMod == 3, n == big -// - when nMod == 4, n == big -// - when nMod == 5, n == 12300 -// - when nMod == 6, n == 12300 -// - when nMod == 7, n == 12300 -func getIntApprox(digits []byte, start, end, nMod, big int) (n int) { - // Leading 0 digits just result in 0. - p := start - if p < 0 { - p = 0 - } - // Range only over the part for which we have digits. - mid := end - if mid >= len(digits) { - mid = len(digits) - } - // Check digits more significant that nMod. - if q := end - nMod; q > 0 { - if q > mid { - q = mid - } - for ; p < q; p++ { - if digits[p] != 0 { - return big - } - } - } - for ; p < mid; p++ { - n = 10*n + int(digits[p]) - } - // Multiply for trailing zeros. - for ; p < end; p++ { - n *= 10 - } - return n -} - -// MatchDigits computes the plural form for the given language and the given -// decimal floating point digits. The digits are stored in big-endian order and -// are of value byte(0) - byte(9). The floating point position is indicated by -// exp and the number of visible decimals is scale. All leading and trailing -// zeros may be omitted from digits. -// -// The following table contains examples of possible arguments to represent -// the given numbers. -// -// decimal digits exp scale -// 123 []byte{1, 2, 3} 3 0 -// 123.4 []byte{1, 2, 3, 4} 3 1 -// 123.40 []byte{1, 2, 3, 4} 3 2 -// 100000 []byte{1} 6 0 -// 100000.00 []byte{1} 6 3 -func (p *Rules) MatchDigits(t language.Tag, digits []byte, exp, scale int) Form { - index := tagToID(t) - - // Differentiate up to including mod 1000000 for the integer part. - n := getIntApprox(digits, 0, exp, 6, 1000000) - - // Differentiate up to including mod 100 for the fractional part. - f := getIntApprox(digits, exp, exp+scale, 2, 100) - - return matchPlural(p, index, n, f, scale) -} - -func (p *Rules) matchDisplayDigits(t language.Tag, d *number.Digits) (Form, int) { - n := getIntApprox(d.Digits, 0, int(d.Exp), 6, 1000000) - return p.MatchDigits(t, d.Digits, int(d.Exp), d.NumFracDigits()), n -} - -func validForms(p *Rules, t language.Tag) (forms []Form) { - offset := p.langToIndex[tagToID(t)] - rules := p.rules[p.index[offset]:p.index[offset+1]] - - forms = append(forms, Other) - last := Other - for _, r := range rules { - if cat := Form(r.cat & formMask); cat != andNext && last != cat { - forms = append(forms, cat) - last = cat - } - } - return forms -} - -func (p *Rules) matchComponents(t language.Tag, n, f, scale int) Form { - return matchPlural(p, tagToID(t), n, f, scale) -} - -// MatchPlural returns the plural form for the given language and plural -// operands (as defined in -// https://unicode.org/reports/tr35/tr35-numbers.html#Language_Plural_Rules): -// -// where -// n absolute value of the source number (integer and decimals) -// input -// i integer digits of n. -// v number of visible fraction digits in n, with trailing zeros. -// w number of visible fraction digits in n, without trailing zeros. -// f visible fractional digits in n, with trailing zeros (f = t * 10^(v-w)) -// t visible fractional digits in n, without trailing zeros. -// -// If any of the operand values is too large to fit in an int, it is okay to -// pass the value modulo 10,000,000. -func (p *Rules) MatchPlural(lang language.Tag, i, v, w, f, t int) Form { - return matchPlural(p, tagToID(lang), i, f, v) -} - -func matchPlural(p *Rules, index compact.ID, n, f, v int) Form { - nMask := p.inclusionMasks[n%maxMod] - // Compute the fMask inline in the rules below, as it is relatively rare. - // fMask := p.inclusionMasks[f%maxMod] - vMask := p.inclusionMasks[v%maxMod] - - // Do the matching - offset := p.langToIndex[index] - rules := p.rules[p.index[offset]:p.index[offset+1]] - for i := 0; i < len(rules); i++ { - rule := rules[i] - setBit := uint64(1 << rule.setID) - var skip bool - switch op := opID(rule.cat >> opShift); op { - case opI: // i = x - skip = n >= numN || nMask&setBit == 0 - - case opI | opNotEqual: // i != x - skip = n < numN && nMask&setBit != 0 - - case opI | opMod: // i % m = x - skip = nMask&setBit == 0 - - case opI | opMod | opNotEqual: // i % m != x - skip = nMask&setBit != 0 - - case opN: // n = x - skip = f != 0 || n >= numN || nMask&setBit == 0 - - case opN | opNotEqual: // n != x - skip = f == 0 && n < numN && nMask&setBit != 0 - - case opN | opMod: // n % m = x - skip = f != 0 || nMask&setBit == 0 - - case opN | opMod | opNotEqual: // n % m != x - skip = f == 0 && nMask&setBit != 0 - - case opF: // f = x - skip = f >= numN || p.inclusionMasks[f%maxMod]&setBit == 0 - - case opF | opNotEqual: // f != x - skip = f < numN && p.inclusionMasks[f%maxMod]&setBit != 0 - - case opF | opMod: // f % m = x - skip = p.inclusionMasks[f%maxMod]&setBit == 0 - - case opF | opMod | opNotEqual: // f % m != x - skip = p.inclusionMasks[f%maxMod]&setBit != 0 - - case opV: // v = x - skip = v < numN && vMask&setBit == 0 - - case opV | opNotEqual: // v != x - skip = v < numN && vMask&setBit != 0 - - case opW: // w == 0 - skip = f != 0 - - case opW | opNotEqual: // w != 0 - skip = f == 0 - - // Hard-wired rules that cannot be handled by our algorithm. - - case opBretonM: - skip = f != 0 || n == 0 || n%1000000 != 0 - - case opAzerbaijan00s: - // 100,200,300,400,500,600,700,800,900 - skip = n == 0 || n >= 1000 || n%100 != 0 - - case opItalian800: - skip = (f != 0 || n >= numN || nMask&setBit == 0) && n != 800 - } - if skip { - // advance over AND entries. - for ; i < len(rules) && rules[i].cat&formMask == andNext; i++ { - } - continue - } - // return if we have a final entry. - if cat := rule.cat & formMask; cat != andNext { - return Form(cat) - } - } - return Other -} - -func tagToID(t language.Tag) compact.ID { - id, _ := compact.RegionalID(compact.Tag(t)) - return id -} diff --git a/vendor/golang.org/x/text/feature/plural/tables.go b/vendor/golang.org/x/text/feature/plural/tables.go deleted file mode 100644 index b06b9cb4e..000000000 --- a/vendor/golang.org/x/text/feature/plural/tables.go +++ /dev/null @@ -1,552 +0,0 @@ -// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. - -package plural - -// CLDRVersion is the CLDR version from which the tables in this package are derived. -const CLDRVersion = "32" - -var ordinalRules = []pluralCheck{ // 64 elements - 0: {cat: 0x2f, setID: 0x4}, - 1: {cat: 0x3a, setID: 0x5}, - 2: {cat: 0x22, setID: 0x1}, - 3: {cat: 0x22, setID: 0x6}, - 4: {cat: 0x22, setID: 0x7}, - 5: {cat: 0x2f, setID: 0x8}, - 6: {cat: 0x3c, setID: 0x9}, - 7: {cat: 0x2f, setID: 0xa}, - 8: {cat: 0x3c, setID: 0xb}, - 9: {cat: 0x2c, setID: 0xc}, - 10: {cat: 0x24, setID: 0xd}, - 11: {cat: 0x2d, setID: 0xe}, - 12: {cat: 0x2d, setID: 0xf}, - 13: {cat: 0x2f, setID: 0x10}, - 14: {cat: 0x35, setID: 0x3}, - 15: {cat: 0xc5, setID: 0x11}, - 16: {cat: 0x2, setID: 0x1}, - 17: {cat: 0x5, setID: 0x3}, - 18: {cat: 0xd, setID: 0x12}, - 19: {cat: 0x22, setID: 0x1}, - 20: {cat: 0x2f, setID: 0x13}, - 21: {cat: 0x3d, setID: 0x14}, - 22: {cat: 0x2f, setID: 0x15}, - 23: {cat: 0x3a, setID: 0x16}, - 24: {cat: 0x2f, setID: 0x17}, - 25: {cat: 0x3b, setID: 0x18}, - 26: {cat: 0x2f, setID: 0xa}, - 27: {cat: 0x3c, setID: 0xb}, - 28: {cat: 0x22, setID: 0x1}, - 29: {cat: 0x23, setID: 0x19}, - 30: {cat: 0x24, setID: 0x1a}, - 31: {cat: 0x22, setID: 0x1b}, - 32: {cat: 0x23, setID: 0x2}, - 33: {cat: 0x24, setID: 0x1a}, - 34: {cat: 0xf, setID: 0x15}, - 35: {cat: 0x1a, setID: 0x16}, - 36: {cat: 0xf, setID: 0x17}, - 37: {cat: 0x1b, setID: 0x18}, - 38: {cat: 0xf, setID: 0x1c}, - 39: {cat: 0x1d, setID: 0x1d}, - 40: {cat: 0xa, setID: 0x1e}, - 41: {cat: 0xa, setID: 0x1f}, - 42: {cat: 0xc, setID: 0x20}, - 43: {cat: 0xe4, setID: 0x0}, - 44: {cat: 0x5, setID: 0x3}, - 45: {cat: 0xd, setID: 0xe}, - 46: {cat: 0xd, setID: 0x21}, - 47: {cat: 0x22, setID: 0x1}, - 48: {cat: 0x23, setID: 0x19}, - 49: {cat: 0x24, setID: 0x1a}, - 50: {cat: 0x25, setID: 0x22}, - 51: {cat: 0x22, setID: 0x23}, - 52: {cat: 0x23, setID: 0x19}, - 53: {cat: 0x24, setID: 0x1a}, - 54: {cat: 0x25, setID: 0x22}, - 55: {cat: 0x22, setID: 0x24}, - 56: {cat: 0x23, setID: 0x19}, - 57: {cat: 0x24, setID: 0x1a}, - 58: {cat: 0x25, setID: 0x22}, - 59: {cat: 0x21, setID: 0x25}, - 60: {cat: 0x22, setID: 0x1}, - 61: {cat: 0x23, setID: 0x2}, - 62: {cat: 0x24, setID: 0x26}, - 63: {cat: 0x25, setID: 0x27}, -} // Size: 152 bytes - -var ordinalIndex = []uint8{ // 22 elements - 0x00, 0x00, 0x02, 0x03, 0x04, 0x05, 0x07, 0x09, - 0x0b, 0x0f, 0x10, 0x13, 0x16, 0x1c, 0x1f, 0x22, - 0x28, 0x2f, 0x33, 0x37, 0x3b, 0x40, -} // Size: 46 bytes - -var ordinalLangToIndex = []uint8{ // 775 elements - // Entry 0 - 3F - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x12, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, - 0x10, 0x10, 0x10, 0x00, 0x00, 0x05, 0x05, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - // Entry 40 - 7F - 0x12, 0x12, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, - 0x0e, 0x0e, 0x0e, 0x0e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x14, 0x14, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - // Entry 80 - BF - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c, - 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, - 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, - 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, - 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, - 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, - 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, - 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, - // Entry C0 - FF - 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, - 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, - 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, - 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, - 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, - 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - // Entry 100 - 13F - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, - 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, - // Entry 140 - 17F - 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, - 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, - 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - // Entry 180 - 1BF - 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x09, 0x09, - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - // Entry 1C0 - 1FF - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, - 0x00, 0x00, 0x02, 0x0d, 0x0d, 0x02, 0x02, 0x02, - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - // Entry 200 - 23F - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x13, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - // Entry 240 - 27F - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, - 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - // Entry 280 - 2BF - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x0b, 0x0b, 0x0b, 0x0b, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x07, 0x07, 0x02, 0x00, 0x00, 0x00, 0x00, - // Entry 2C0 - 2FF - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - // Entry 300 - 33F - 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x0c, -} // Size: 799 bytes - -var ordinalInclusionMasks = []uint64{ // 100 elements - // Entry 0 - 1F - 0x0000002000010009, 0x00000018482000d3, 0x0000000042840195, 0x000000410a040581, - 0x00000041040c0081, 0x0000009840040041, 0x0000008400045001, 0x0000003850040001, - 0x0000003850060001, 0x0000003800049001, 0x0000000800052001, 0x0000000040660031, - 0x0000000041840331, 0x0000000100040f01, 0x00000001001c0001, 0x0000000040040001, - 0x0000000000045001, 0x0000000070040001, 0x0000000070040001, 0x0000000000049001, - 0x0000000080050001, 0x0000000040200011, 0x0000000040800111, 0x0000000100000501, - 0x0000000100080001, 0x0000000040000001, 0x0000000000005001, 0x0000000050000001, - 0x0000000050000001, 0x0000000000009001, 0x0000000000010001, 0x0000000040200011, - // Entry 20 - 3F - 0x0000000040800111, 0x0000000100000501, 0x0000000100080001, 0x0000000040000001, - 0x0000000000005001, 0x0000000050000001, 0x0000000050000001, 0x0000000000009001, - 0x0000000200050001, 0x0000000040200011, 0x0000000040800111, 0x0000000100000501, - 0x0000000100080001, 0x0000000040000001, 0x0000000000005001, 0x0000000050000001, - 0x0000000050000001, 0x0000000000009001, 0x0000000080010001, 0x0000000040200011, - 0x0000000040800111, 0x0000000100000501, 0x0000000100080001, 0x0000000040000001, - 0x0000000000005001, 0x0000000050000001, 0x0000000050000001, 0x0000000000009001, - 0x0000000200050001, 0x0000000040200011, 0x0000000040800111, 0x0000000100000501, - // Entry 40 - 5F - 0x0000000100080001, 0x0000000040000001, 0x0000000000005001, 0x0000000050000001, - 0x0000000050000001, 0x0000000000009001, 0x0000000080010001, 0x0000000040200011, - 0x0000000040800111, 0x0000000100000501, 0x0000000100080001, 0x0000000040000001, - 0x0000000000005001, 0x0000000050000001, 0x0000000050000001, 0x0000000000009001, - 0x0000000080070001, 0x0000000040200011, 0x0000000040800111, 0x0000000100000501, - 0x0000000100080001, 0x0000000040000001, 0x0000000000005001, 0x0000000050000001, - 0x0000000050000001, 0x0000000000009001, 0x0000000200010001, 0x0000000040200011, - 0x0000000040800111, 0x0000000100000501, 0x0000000100080001, 0x0000000040000001, - // Entry 60 - 7F - 0x0000000000005001, 0x0000000050000001, 0x0000000050000001, 0x0000000000009001, -} // Size: 824 bytes - -// Slots used for ordinal: 40 of 0xFF rules; 16 of 0xFF indexes; 40 of 64 sets - -var cardinalRules = []pluralCheck{ // 166 elements - 0: {cat: 0x2, setID: 0x3}, - 1: {cat: 0x22, setID: 0x1}, - 2: {cat: 0x2, setID: 0x4}, - 3: {cat: 0x2, setID: 0x4}, - 4: {cat: 0x7, setID: 0x1}, - 5: {cat: 0x62, setID: 0x3}, - 6: {cat: 0x22, setID: 0x4}, - 7: {cat: 0x7, setID: 0x3}, - 8: {cat: 0x42, setID: 0x1}, - 9: {cat: 0x22, setID: 0x4}, - 10: {cat: 0x22, setID: 0x4}, - 11: {cat: 0x22, setID: 0x5}, - 12: {cat: 0x22, setID: 0x1}, - 13: {cat: 0x22, setID: 0x1}, - 14: {cat: 0x7, setID: 0x4}, - 15: {cat: 0x92, setID: 0x3}, - 16: {cat: 0xf, setID: 0x6}, - 17: {cat: 0x1f, setID: 0x7}, - 18: {cat: 0x82, setID: 0x3}, - 19: {cat: 0x92, setID: 0x3}, - 20: {cat: 0xf, setID: 0x6}, - 21: {cat: 0x62, setID: 0x3}, - 22: {cat: 0x4a, setID: 0x6}, - 23: {cat: 0x7, setID: 0x8}, - 24: {cat: 0x62, setID: 0x3}, - 25: {cat: 0x1f, setID: 0x9}, - 26: {cat: 0x62, setID: 0x3}, - 27: {cat: 0x5f, setID: 0x9}, - 28: {cat: 0x72, setID: 0x3}, - 29: {cat: 0x29, setID: 0xa}, - 30: {cat: 0x29, setID: 0xb}, - 31: {cat: 0x4f, setID: 0xb}, - 32: {cat: 0x61, setID: 0x2}, - 33: {cat: 0x2f, setID: 0x6}, - 34: {cat: 0x3a, setID: 0x7}, - 35: {cat: 0x4f, setID: 0x6}, - 36: {cat: 0x5f, setID: 0x7}, - 37: {cat: 0x62, setID: 0x2}, - 38: {cat: 0x4f, setID: 0x6}, - 39: {cat: 0x72, setID: 0x2}, - 40: {cat: 0x21, setID: 0x3}, - 41: {cat: 0x7, setID: 0x4}, - 42: {cat: 0x32, setID: 0x3}, - 43: {cat: 0x21, setID: 0x3}, - 44: {cat: 0x22, setID: 0x1}, - 45: {cat: 0x22, setID: 0x1}, - 46: {cat: 0x23, setID: 0x2}, - 47: {cat: 0x2, setID: 0x3}, - 48: {cat: 0x22, setID: 0x1}, - 49: {cat: 0x24, setID: 0xc}, - 50: {cat: 0x7, setID: 0x1}, - 51: {cat: 0x62, setID: 0x3}, - 52: {cat: 0x74, setID: 0x3}, - 53: {cat: 0x24, setID: 0x3}, - 54: {cat: 0x2f, setID: 0xd}, - 55: {cat: 0x34, setID: 0x1}, - 56: {cat: 0xf, setID: 0x6}, - 57: {cat: 0x1f, setID: 0x7}, - 58: {cat: 0x62, setID: 0x3}, - 59: {cat: 0x4f, setID: 0x6}, - 60: {cat: 0x5a, setID: 0x7}, - 61: {cat: 0xf, setID: 0xe}, - 62: {cat: 0x1f, setID: 0xf}, - 63: {cat: 0x64, setID: 0x3}, - 64: {cat: 0x4f, setID: 0xe}, - 65: {cat: 0x5c, setID: 0xf}, - 66: {cat: 0x22, setID: 0x10}, - 67: {cat: 0x23, setID: 0x11}, - 68: {cat: 0x24, setID: 0x12}, - 69: {cat: 0xf, setID: 0x1}, - 70: {cat: 0x62, setID: 0x3}, - 71: {cat: 0xf, setID: 0x2}, - 72: {cat: 0x63, setID: 0x3}, - 73: {cat: 0xf, setID: 0x13}, - 74: {cat: 0x64, setID: 0x3}, - 75: {cat: 0x74, setID: 0x3}, - 76: {cat: 0xf, setID: 0x1}, - 77: {cat: 0x62, setID: 0x3}, - 78: {cat: 0x4a, setID: 0x1}, - 79: {cat: 0xf, setID: 0x2}, - 80: {cat: 0x63, setID: 0x3}, - 81: {cat: 0x4b, setID: 0x2}, - 82: {cat: 0xf, setID: 0x13}, - 83: {cat: 0x64, setID: 0x3}, - 84: {cat: 0x4c, setID: 0x13}, - 85: {cat: 0x7, setID: 0x1}, - 86: {cat: 0x62, setID: 0x3}, - 87: {cat: 0x7, setID: 0x2}, - 88: {cat: 0x63, setID: 0x3}, - 89: {cat: 0x2f, setID: 0xa}, - 90: {cat: 0x37, setID: 0x14}, - 91: {cat: 0x65, setID: 0x3}, - 92: {cat: 0x7, setID: 0x1}, - 93: {cat: 0x62, setID: 0x3}, - 94: {cat: 0x7, setID: 0x15}, - 95: {cat: 0x64, setID: 0x3}, - 96: {cat: 0x75, setID: 0x3}, - 97: {cat: 0x7, setID: 0x1}, - 98: {cat: 0x62, setID: 0x3}, - 99: {cat: 0xf, setID: 0xe}, - 100: {cat: 0x1f, setID: 0xf}, - 101: {cat: 0x64, setID: 0x3}, - 102: {cat: 0xf, setID: 0x16}, - 103: {cat: 0x17, setID: 0x1}, - 104: {cat: 0x65, setID: 0x3}, - 105: {cat: 0xf, setID: 0x17}, - 106: {cat: 0x65, setID: 0x3}, - 107: {cat: 0xf, setID: 0xf}, - 108: {cat: 0x65, setID: 0x3}, - 109: {cat: 0x2f, setID: 0x6}, - 110: {cat: 0x3a, setID: 0x7}, - 111: {cat: 0x2f, setID: 0xe}, - 112: {cat: 0x3c, setID: 0xf}, - 113: {cat: 0x2d, setID: 0xa}, - 114: {cat: 0x2d, setID: 0x17}, - 115: {cat: 0x2d, setID: 0x18}, - 116: {cat: 0x2f, setID: 0x6}, - 117: {cat: 0x3a, setID: 0xb}, - 118: {cat: 0x2f, setID: 0x19}, - 119: {cat: 0x3c, setID: 0xb}, - 120: {cat: 0x55, setID: 0x3}, - 121: {cat: 0x22, setID: 0x1}, - 122: {cat: 0x24, setID: 0x3}, - 123: {cat: 0x2c, setID: 0xc}, - 124: {cat: 0x2d, setID: 0xb}, - 125: {cat: 0xf, setID: 0x6}, - 126: {cat: 0x1f, setID: 0x7}, - 127: {cat: 0x62, setID: 0x3}, - 128: {cat: 0xf, setID: 0xe}, - 129: {cat: 0x1f, setID: 0xf}, - 130: {cat: 0x64, setID: 0x3}, - 131: {cat: 0xf, setID: 0xa}, - 132: {cat: 0x65, setID: 0x3}, - 133: {cat: 0xf, setID: 0x17}, - 134: {cat: 0x65, setID: 0x3}, - 135: {cat: 0xf, setID: 0x18}, - 136: {cat: 0x65, setID: 0x3}, - 137: {cat: 0x2f, setID: 0x6}, - 138: {cat: 0x3a, setID: 0x1a}, - 139: {cat: 0x2f, setID: 0x1b}, - 140: {cat: 0x3b, setID: 0x1c}, - 141: {cat: 0x2f, setID: 0x1d}, - 142: {cat: 0x3c, setID: 0x1e}, - 143: {cat: 0x37, setID: 0x3}, - 144: {cat: 0xa5, setID: 0x0}, - 145: {cat: 0x22, setID: 0x1}, - 146: {cat: 0x23, setID: 0x2}, - 147: {cat: 0x24, setID: 0x1f}, - 148: {cat: 0x25, setID: 0x20}, - 149: {cat: 0xf, setID: 0x6}, - 150: {cat: 0x62, setID: 0x3}, - 151: {cat: 0xf, setID: 0x1b}, - 152: {cat: 0x63, setID: 0x3}, - 153: {cat: 0xf, setID: 0x21}, - 154: {cat: 0x64, setID: 0x3}, - 155: {cat: 0x75, setID: 0x3}, - 156: {cat: 0x21, setID: 0x3}, - 157: {cat: 0x22, setID: 0x1}, - 158: {cat: 0x23, setID: 0x2}, - 159: {cat: 0x2c, setID: 0x22}, - 160: {cat: 0x2d, setID: 0x5}, - 161: {cat: 0x21, setID: 0x3}, - 162: {cat: 0x22, setID: 0x1}, - 163: {cat: 0x23, setID: 0x2}, - 164: {cat: 0x24, setID: 0x23}, - 165: {cat: 0x25, setID: 0x24}, -} // Size: 356 bytes - -var cardinalIndex = []uint8{ // 36 elements - 0x00, 0x00, 0x02, 0x03, 0x04, 0x06, 0x09, 0x0a, - 0x0c, 0x0d, 0x10, 0x14, 0x17, 0x1d, 0x28, 0x2b, - 0x2d, 0x2f, 0x32, 0x38, 0x42, 0x45, 0x4c, 0x55, - 0x5c, 0x61, 0x6d, 0x74, 0x79, 0x7d, 0x89, 0x91, - 0x95, 0x9c, 0xa1, 0xa6, -} // Size: 60 bytes - -var cardinalLangToIndex = []uint8{ // 775 elements - // Entry 0 - 3F - 0x00, 0x08, 0x08, 0x08, 0x00, 0x00, 0x06, 0x06, - 0x01, 0x01, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, - 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, - 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, - 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, - 0x01, 0x01, 0x08, 0x08, 0x04, 0x04, 0x08, 0x08, - 0x08, 0x08, 0x08, 0x00, 0x00, 0x1a, 0x1a, 0x08, - 0x08, 0x08, 0x08, 0x08, 0x08, 0x06, 0x00, 0x00, - // Entry 40 - 7F - 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x1e, 0x1e, - 0x08, 0x08, 0x13, 0x13, 0x13, 0x13, 0x13, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x08, - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, - 0x18, 0x18, 0x00, 0x00, 0x22, 0x22, 0x09, 0x09, - 0x09, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x00, 0x00, 0x16, 0x16, 0x00, - 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - // Entry 80 - BF - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 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, - 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, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, - // Entry 100 - 13F - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, - 0x08, 0x08, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, - 0x02, 0x02, 0x02, 0x02, 0x04, 0x04, 0x0c, 0x0c, - 0x08, 0x08, 0x08, 0x02, 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, - // Entry 140 - 17F - 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x08, 0x08, 0x04, 0x04, 0x1f, 0x1f, - 0x14, 0x14, 0x04, 0x04, 0x08, 0x08, 0x08, 0x08, - 0x01, 0x01, 0x06, 0x00, 0x00, 0x20, 0x20, 0x08, - 0x08, 0x08, 0x08, 0x08, 0x08, 0x17, 0x17, 0x01, - 0x01, 0x13, 0x13, 0x13, 0x16, 0x16, 0x08, 0x08, - 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - // Entry 180 - 1BF - 0x00, 0x04, 0x0a, 0x0a, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x10, 0x17, 0x00, 0x00, 0x00, 0x08, 0x08, - 0x04, 0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x02, - 0x02, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, - 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, - 0x08, 0x08, 0x00, 0x00, 0x0f, 0x0f, 0x08, 0x10, - // Entry 1C0 - 1FF - 0x10, 0x08, 0x08, 0x0e, 0x0e, 0x08, 0x08, 0x08, - 0x08, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x1b, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x0d, 0x08, - 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, - 0x00, 0x00, 0x08, 0x08, 0x0b, 0x0b, 0x08, 0x08, - 0x08, 0x08, 0x12, 0x01, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x1c, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, - // Entry 200 - 23F - 0x00, 0x08, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, - 0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, - 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x08, - 0x06, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x08, 0x19, 0x19, 0x0d, 0x0d, - 0x08, 0x08, 0x03, 0x04, 0x03, 0x04, 0x04, 0x04, - // Entry 240 - 27F - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, - 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x12, - 0x12, 0x12, 0x08, 0x08, 0x1d, 0x1d, 0x1d, 0x1d, - 0x1d, 0x1d, 0x1d, 0x00, 0x00, 0x08, 0x08, 0x00, - 0x00, 0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x08, - 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x00, 0x00, - 0x00, 0x00, 0x13, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x05, 0x05, 0x18, 0x18, 0x15, 0x15, 0x10, 0x10, - // Entry 280 - 2BF - 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x13, - 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, - 0x13, 0x13, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, 0x08, - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, - 0x08, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, - 0x08, 0x08, 0x08, 0x0c, 0x08, 0x00, 0x00, 0x08, - // Entry 2C0 - 2FF - 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x07, - 0x07, 0x08, 0x08, 0x1d, 0x1d, 0x04, 0x04, 0x04, - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, - 0x08, 0x08, 0x08, 0x06, 0x08, 0x08, 0x00, 0x00, - 0x08, 0x08, 0x08, 0x00, 0x00, 0x04, 0x04, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - // Entry 300 - 33F - 0x00, 0x00, 0x00, 0x01, 0x01, 0x04, 0x04, -} // Size: 799 bytes - -var cardinalInclusionMasks = []uint64{ // 100 elements - // Entry 0 - 1F - 0x0000000200500419, 0x0000000000512153, 0x000000000a327105, 0x0000000ca23c7101, - 0x00000004a23c7201, 0x0000000482943001, 0x0000001482943201, 0x0000000502943001, - 0x0000000502943001, 0x0000000522943201, 0x0000000540543401, 0x00000000454128e1, - 0x000000005b02e821, 0x000000006304e821, 0x000000006304ea21, 0x0000000042842821, - 0x0000000042842a21, 0x0000000042842821, 0x0000000042842821, 0x0000000062842a21, - 0x0000000200400421, 0x0000000000400061, 0x000000000a004021, 0x0000000022004021, - 0x0000000022004221, 0x0000000002800021, 0x0000000002800221, 0x0000000002800021, - 0x0000000002800021, 0x0000000022800221, 0x0000000000400421, 0x0000000000400061, - // Entry 20 - 3F - 0x000000000a004021, 0x0000000022004021, 0x0000000022004221, 0x0000000002800021, - 0x0000000002800221, 0x0000000002800021, 0x0000000002800021, 0x0000000022800221, - 0x0000000200400421, 0x0000000000400061, 0x000000000a004021, 0x0000000022004021, - 0x0000000022004221, 0x0000000002800021, 0x0000000002800221, 0x0000000002800021, - 0x0000000002800021, 0x0000000022800221, 0x0000000000400421, 0x0000000000400061, - 0x000000000a004021, 0x0000000022004021, 0x0000000022004221, 0x0000000002800021, - 0x0000000002800221, 0x0000000002800021, 0x0000000002800021, 0x0000000022800221, - 0x0000000200400421, 0x0000000000400061, 0x000000000a004021, 0x0000000022004021, - // Entry 40 - 5F - 0x0000000022004221, 0x0000000002800021, 0x0000000002800221, 0x0000000002800021, - 0x0000000002800021, 0x0000000022800221, 0x0000000040400421, 0x0000000044400061, - 0x000000005a004021, 0x0000000062004021, 0x0000000062004221, 0x0000000042800021, - 0x0000000042800221, 0x0000000042800021, 0x0000000042800021, 0x0000000062800221, - 0x0000000200400421, 0x0000000000400061, 0x000000000a004021, 0x0000000022004021, - 0x0000000022004221, 0x0000000002800021, 0x0000000002800221, 0x0000000002800021, - 0x0000000002800021, 0x0000000022800221, 0x0000000040400421, 0x0000000044400061, - 0x000000005a004021, 0x0000000062004021, 0x0000000062004221, 0x0000000042800021, - // Entry 60 - 7F - 0x0000000042800221, 0x0000000042800021, 0x0000000042800021, 0x0000000062800221, -} // Size: 824 bytes - -// Slots used for cardinal: A6 of 0xFF rules; 24 of 0xFF indexes; 37 of 64 sets - -// Total table size 3860 bytes (3KiB); checksum: AAFBF21 diff --git a/vendor/golang.org/x/text/internal/catmsg/catmsg.go b/vendor/golang.org/x/text/internal/catmsg/catmsg.go deleted file mode 100644 index 1b257a7b4..000000000 --- a/vendor/golang.org/x/text/internal/catmsg/catmsg.go +++ /dev/null @@ -1,417 +0,0 @@ -// 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 catmsg contains support types for package x/text/message/catalog. -// -// This package contains the low-level implementations of Message used by the -// catalog package and provides primitives for other packages to implement their -// own. For instance, the plural package provides functionality for selecting -// translation strings based on the plural category of substitution arguments. -// -// # Encoding and Decoding -// -// Catalogs store Messages encoded as a single string. Compiling a message into -// a string both results in compacter representation and speeds up evaluation. -// -// A Message must implement a Compile method to convert its arbitrary -// representation to a string. The Compile method takes an Encoder which -// facilitates serializing the message. Encoders also provide more context of -// the messages's creation (such as for which language the message is intended), -// which may not be known at the time of the creation of the message. -// -// Each message type must also have an accompanying decoder registered to decode -// the message. This decoder takes a Decoder argument which provides the -// counterparts for the decoding. -// -// # Renderers -// -// A Decoder must be initialized with a Renderer implementation. These -// implementations must be provided by packages that use Catalogs, typically -// formatting packages such as x/text/message. A typical user will not need to -// worry about this type; it is only relevant to packages that do string -// formatting and want to use the catalog package to handle localized strings. -// -// A package that uses catalogs for selecting strings receives selection results -// as sequence of substrings passed to the Renderer. The following snippet shows -// how to express the above example using the message package. -// -// message.Set(language.English, "You are %d minute(s) late.", -// catalog.Var("minutes", plural.Select(1, "one", "minute")), -// catalog.String("You are %[1]d ${minutes} late.")) -// -// p := message.NewPrinter(language.English) -// p.Printf("You are %d minute(s) late.", 5) // always 5 minutes late. -// -// To evaluate the Printf, package message wraps the arguments in a Renderer -// that is passed to the catalog for message decoding. The call sequence that -// results from evaluating the above message, assuming the person is rather -// tardy, is: -// -// Render("You are %[1]d ") -// Arg(1) -// Render("minutes") -// Render(" late.") -// -// The calls to Arg is caused by the plural.Select execution, which evaluates -// the argument to determine whether the singular or plural message form should -// be selected. The calls to Render reports the partial results to the message -// package for further evaluation. -package catmsg - -import ( - "errors" - "fmt" - "strconv" - "strings" - "sync" - - "golang.org/x/text/language" -) - -// A Handle refers to a registered message type. -type Handle int - -// A Handler decodes and evaluates data compiled by a Message and sends the -// result to the Decoder. The output may depend on the value of the substitution -// arguments, accessible by the Decoder's Arg method. The Handler returns false -// if there is no translation for the given substitution arguments. -type Handler func(d *Decoder) bool - -// Register records the existence of a message type and returns a Handle that -// can be used in the Encoder's EncodeMessageType method to create such -// messages. The prefix of the name should be the package path followed by -// an optional disambiguating string. -// Register will panic if a handle for the same name was already registered. -func Register(name string, handler Handler) Handle { - mutex.Lock() - defer mutex.Unlock() - - if _, ok := names[name]; ok { - panic(fmt.Errorf("catmsg: handler for %q already exists", name)) - } - h := Handle(len(handlers)) - names[name] = h - handlers = append(handlers, handler) - return h -} - -// These handlers require fixed positions in the handlers slice. -const ( - msgVars Handle = iota - msgFirst - msgRaw - msgString - msgAffix - // Leave some arbitrary room for future expansion: 20 should suffice. - numInternal = 20 -) - -const prefix = "golang.org/x/text/internal/catmsg." - -var ( - // TODO: find a more stable way to link handles to message types. - mutex sync.Mutex - names = map[string]Handle{ - prefix + "Vars": msgVars, - prefix + "First": msgFirst, - prefix + "Raw": msgRaw, - prefix + "String": msgString, - prefix + "Affix": msgAffix, - } - handlers = make([]Handler, numInternal) -) - -func init() { - // This handler is a message type wrapper that initializes a decoder - // with a variable block. This message type, if present, is always at the - // start of an encoded message. - handlers[msgVars] = func(d *Decoder) bool { - blockSize := int(d.DecodeUint()) - d.vars = d.data[:blockSize] - d.data = d.data[blockSize:] - return d.executeMessage() - } - - // First takes the first message in a sequence that results in a match for - // the given substitution arguments. - handlers[msgFirst] = func(d *Decoder) bool { - for !d.Done() { - if d.ExecuteMessage() { - return true - } - } - return false - } - - handlers[msgRaw] = func(d *Decoder) bool { - d.Render(d.data) - return true - } - - // A String message alternates between a string constant and a variable - // substitution. - handlers[msgString] = func(d *Decoder) bool { - for !d.Done() { - if str := d.DecodeString(); str != "" { - d.Render(str) - } - if d.Done() { - break - } - d.ExecuteSubstitution() - } - return true - } - - handlers[msgAffix] = func(d *Decoder) bool { - // TODO: use an alternative method for common cases. - prefix := d.DecodeString() - suffix := d.DecodeString() - if prefix != "" { - d.Render(prefix) - } - ret := d.ExecuteMessage() - if suffix != "" { - d.Render(suffix) - } - return ret - } -} - -var ( - // ErrIncomplete indicates a compiled message does not define translations - // for all possible argument values. If this message is returned, evaluating - // a message may result in the ErrNoMatch error. - ErrIncomplete = errors.New("catmsg: incomplete message; may not give result for all inputs") - - // ErrNoMatch indicates no translation message matched the given input - // parameters when evaluating a message. - ErrNoMatch = errors.New("catmsg: no translation for inputs") -) - -// A Message holds a collection of translations for the same phrase that may -// vary based on the values of substitution arguments. -type Message interface { - // Compile encodes the format string(s) of the message as a string for later - // evaluation. - // - // The first call Compile makes on the encoder must be EncodeMessageType. - // The handle passed to this call may either be a handle returned by - // Register to encode a single custom message, or HandleFirst followed by - // a sequence of calls to EncodeMessage. - // - // Compile must return ErrIncomplete if it is possible for evaluation to - // not match any translation for a given set of formatting parameters. - // For example, selecting a translation based on plural form may not yield - // a match if the form "Other" is not one of the selectors. - // - // Compile may return any other application-specific error. For backwards - // compatibility with package like fmt, which often do not do sanity - // checking of format strings ahead of time, Compile should still make an - // effort to have some sensible fallback in case of an error. - Compile(e *Encoder) error -} - -// Compile converts a Message to a data string that can be stored in a Catalog. -// The resulting string can subsequently be decoded by passing to the Execute -// method of a Decoder. -func Compile(tag language.Tag, macros Dictionary, m Message) (data string, err error) { - // TODO: pass macros so they can be used for validation. - v := &Encoder{inBody: true} // encoder for variables - v.root = v - e := &Encoder{root: v, parent: v, tag: tag} // encoder for messages - err = m.Compile(e) - // This package serves te message package, which in turn is meant to be a - // drop-in replacement for fmt. With the fmt package, format strings are - // evaluated lazily and errors are handled by substituting strings in the - // result, rather then returning an error. Dealing with multiple languages - // makes it more important to check errors ahead of time. We chose to be - // consistent and compatible and allow graceful degradation in case of - // errors. - buf := e.buf[stripPrefix(e.buf):] - if len(v.buf) > 0 { - // Prepend variable block. - b := make([]byte, 1+maxVarintBytes+len(v.buf)+len(buf)) - b[0] = byte(msgVars) - b = b[:1+encodeUint(b[1:], uint64(len(v.buf)))] - b = append(b, v.buf...) - b = append(b, buf...) - buf = b - } - if err == nil { - err = v.err - } - return string(buf), err -} - -// FirstOf is a message type that prints the first message in the sequence that -// resolves to a match for the given substitution arguments. -type FirstOf []Message - -// Compile implements Message. -func (s FirstOf) Compile(e *Encoder) error { - e.EncodeMessageType(msgFirst) - err := ErrIncomplete - for i, m := range s { - if err == nil { - return fmt.Errorf("catalog: message argument %d is complete and blocks subsequent messages", i-1) - } - err = e.EncodeMessage(m) - } - return err -} - -// Var defines a message that can be substituted for a placeholder of the same -// name. If an expression does not result in a string after evaluation, Name is -// used as the substitution. For example: -// -// Var{ -// Name: "minutes", -// Message: plural.Select(1, "one", "minute"), -// } -// -// will resolve to minute for singular and minutes for plural forms. -type Var struct { - Name string - Message Message -} - -var errIsVar = errors.New("catmsg: variable used as message") - -// Compile implements Message. -// -// Note that this method merely registers a variable; it does not create an -// encoded message. -func (v *Var) Compile(e *Encoder) error { - if err := e.addVar(v.Name, v.Message); err != nil { - return err - } - // Using a Var by itself is an error. If it is in a sequence followed by - // other messages referring to it, this error will be ignored. - return errIsVar -} - -// Raw is a message consisting of a single format string that is passed as is -// to the Renderer. -// -// Note that a Renderer may still do its own variable substitution. -type Raw string - -// Compile implements Message. -func (r Raw) Compile(e *Encoder) (err error) { - e.EncodeMessageType(msgRaw) - // Special case: raw strings don't have a size encoding and so don't use - // EncodeString. - e.buf = append(e.buf, r...) - return nil -} - -// String is a message consisting of a single format string which contains -// placeholders that may be substituted with variables. -// -// Variable substitutions are marked with placeholders and a variable name of -// the form ${name}. Any other substitutions such as Go templates or -// printf-style substitutions are left to be done by the Renderer. -// -// When evaluation a string interpolation, a Renderer will receive separate -// calls for each placeholder and interstitial string. For example, for the -// message: "%[1]v ${invites} %[2]v to ${their} party." The sequence of calls -// is: -// -// d.Render("%[1]v ") -// d.Arg(1) -// d.Render(resultOfInvites) -// d.Render(" %[2]v to ") -// d.Arg(2) -// d.Render(resultOfTheir) -// d.Render(" party.") -// -// where the messages for "invites" and "their" both use a plural.Select -// referring to the first argument. -// -// Strings may also invoke macros. Macros are essentially variables that can be -// reused. Macros may, for instance, be used to make selections between -// different conjugations of a verb. See the catalog package description for an -// overview of macros. -type String string - -// Compile implements Message. It parses the placeholder formats and returns -// any error. -func (s String) Compile(e *Encoder) (err error) { - msg := string(s) - const subStart = "${" - hasHeader := false - p := 0 - b := []byte{} - for { - i := strings.Index(msg[p:], subStart) - if i == -1 { - break - } - b = append(b, msg[p:p+i]...) - p += i + len(subStart) - if i = strings.IndexByte(msg[p:], '}'); i == -1 { - b = append(b, "$!(MISSINGBRACE)"...) - err = fmt.Errorf("catmsg: missing '}'") - p = len(msg) - break - } - name := strings.TrimSpace(msg[p : p+i]) - if q := strings.IndexByte(name, '('); q == -1 { - if !hasHeader { - hasHeader = true - e.EncodeMessageType(msgString) - } - e.EncodeString(string(b)) - e.EncodeSubstitution(name) - b = b[:0] - } else if j := strings.IndexByte(name[q:], ')'); j == -1 { - // TODO: what should the error be? - b = append(b, "$!(MISSINGPAREN)"...) - err = fmt.Errorf("catmsg: missing ')'") - } else if x, sErr := strconv.ParseUint(strings.TrimSpace(name[q+1:q+j]), 10, 32); sErr != nil { - // TODO: handle more than one argument - b = append(b, "$!(BADNUM)"...) - err = fmt.Errorf("catmsg: invalid number %q", strings.TrimSpace(name[q+1:q+j])) - } else { - if !hasHeader { - hasHeader = true - e.EncodeMessageType(msgString) - } - e.EncodeString(string(b)) - e.EncodeSubstitution(name[:q], int(x)) - b = b[:0] - } - p += i + 1 - } - b = append(b, msg[p:]...) - if !hasHeader { - // Simplify string to a raw string. - Raw(string(b)).Compile(e) - } else if len(b) > 0 { - e.EncodeString(string(b)) - } - return err -} - -// Affix is a message that adds a prefix and suffix to another message. -// This is mostly used add back whitespace to a translation that was stripped -// before sending it out. -type Affix struct { - Message Message - Prefix string - Suffix string -} - -// Compile implements Message. -func (a Affix) Compile(e *Encoder) (err error) { - // TODO: consider adding a special message type that just adds a single - // return. This is probably common enough to handle the majority of cases. - // Get some stats first, though. - e.EncodeMessageType(msgAffix) - e.EncodeString(a.Prefix) - e.EncodeString(a.Suffix) - e.EncodeMessage(a.Message) - return nil -} diff --git a/vendor/golang.org/x/text/internal/catmsg/codec.go b/vendor/golang.org/x/text/internal/catmsg/codec.go deleted file mode 100644 index 49c9fc978..000000000 --- a/vendor/golang.org/x/text/internal/catmsg/codec.go +++ /dev/null @@ -1,407 +0,0 @@ -// 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 catmsg - -import ( - "errors" - "fmt" - - "golang.org/x/text/language" -) - -// A Renderer renders a Message. -type Renderer interface { - // Render renders the given string. The given string may be interpreted as a - // format string, such as the one used by the fmt package or a template. - Render(s string) - - // Arg returns the i-th argument passed to format a message. This method - // should return nil if there is no such argument. Messages need access to - // arguments to allow selecting a message based on linguistic features of - // those arguments. - Arg(i int) interface{} -} - -// A Dictionary specifies a source of messages, including variables or macros. -type Dictionary interface { - // Lookup returns the message for the given key. It returns false for ok if - // such a message could not be found. - Lookup(key string) (data string, ok bool) - - // TODO: consider returning an interface, instead of a string. This will - // allow implementations to do their own message type decoding. -} - -// An Encoder serializes a Message to a string. -type Encoder struct { - // The root encoder is used for storing encoded variables. - root *Encoder - // The parent encoder provides the surrounding scopes for resolving variable - // names. - parent *Encoder - - tag language.Tag - - // buf holds the encoded message so far. After a message completes encoding, - // the contents of buf, prefixed by the encoded length, are flushed to the - // parent buffer. - buf []byte - - // vars is the lookup table of variables in the current scope. - vars []keyVal - - err error - inBody bool // if false next call must be EncodeMessageType -} - -type keyVal struct { - key string - offset int -} - -// Language reports the language for which the encoded message will be stored -// in the Catalog. -func (e *Encoder) Language() language.Tag { return e.tag } - -func (e *Encoder) setError(err error) { - if e.root.err == nil { - e.root.err = err - } -} - -// EncodeUint encodes x. -func (e *Encoder) EncodeUint(x uint64) { - e.checkInBody() - var buf [maxVarintBytes]byte - n := encodeUint(buf[:], x) - e.buf = append(e.buf, buf[:n]...) -} - -// EncodeString encodes s. -func (e *Encoder) EncodeString(s string) { - e.checkInBody() - e.EncodeUint(uint64(len(s))) - e.buf = append(e.buf, s...) -} - -// EncodeMessageType marks the current message to be of type h. -// -// It must be the first call of a Message's Compile method. -func (e *Encoder) EncodeMessageType(h Handle) { - if e.inBody { - panic("catmsg: EncodeMessageType not the first method called") - } - e.inBody = true - e.EncodeUint(uint64(h)) -} - -// EncodeMessage serializes the given message inline at the current position. -func (e *Encoder) EncodeMessage(m Message) error { - e = &Encoder{root: e.root, parent: e, tag: e.tag} - err := m.Compile(e) - if _, ok := m.(*Var); !ok { - e.flushTo(e.parent) - } - return err -} - -func (e *Encoder) checkInBody() { - if !e.inBody { - panic("catmsg: expected prior call to EncodeMessageType") - } -} - -// stripPrefix indicates the number of prefix bytes that must be stripped to -// turn a single-element sequence into a message that is just this single member -// without its size prefix. If the message can be stripped, b[1:n] contains the -// size prefix. -func stripPrefix(b []byte) (n int) { - if len(b) > 0 && Handle(b[0]) == msgFirst { - x, n, _ := decodeUint(b[1:]) - if 1+n+int(x) == len(b) { - return 1 + n - } - } - return 0 -} - -func (e *Encoder) flushTo(dst *Encoder) { - data := e.buf - p := stripPrefix(data) - if p > 0 { - data = data[1:] - } else { - // Prefix the size. - dst.EncodeUint(uint64(len(data))) - } - dst.buf = append(dst.buf, data...) -} - -func (e *Encoder) addVar(key string, m Message) error { - for _, v := range e.parent.vars { - if v.key == key { - err := fmt.Errorf("catmsg: duplicate variable %q", key) - e.setError(err) - return err - } - } - scope := e.parent - // If a variable message is Incomplete, and does not evaluate to a message - // during execution, we fall back to the variable name. We encode this by - // appending the variable name if the message reports it's incomplete. - - err := m.Compile(e) - if err != ErrIncomplete { - e.setError(err) - } - switch { - case len(e.buf) == 1 && Handle(e.buf[0]) == msgFirst: // empty sequence - e.buf = e.buf[:0] - e.inBody = false - fallthrough - case len(e.buf) == 0: - // Empty message. - if err := String(key).Compile(e); err != nil { - e.setError(err) - } - case err == ErrIncomplete: - if Handle(e.buf[0]) != msgFirst { - seq := &Encoder{root: e.root, parent: e} - seq.EncodeMessageType(msgFirst) - e.flushTo(seq) - e = seq - } - // e contains a sequence; append the fallback string. - e.EncodeMessage(String(key)) - } - - // Flush result to variable heap. - offset := len(e.root.buf) - e.flushTo(e.root) - e.buf = e.buf[:0] - - // Record variable offset in current scope. - scope.vars = append(scope.vars, keyVal{key: key, offset: offset}) - return err -} - -const ( - substituteVar = iota - substituteMacro - substituteError -) - -// EncodeSubstitution inserts a resolved reference to a variable or macro. -// -// This call must be matched with a call to ExecuteSubstitution at decoding -// time. -func (e *Encoder) EncodeSubstitution(name string, arguments ...int) { - if arity := len(arguments); arity > 0 { - // TODO: also resolve macros. - e.EncodeUint(substituteMacro) - e.EncodeString(name) - for _, a := range arguments { - e.EncodeUint(uint64(a)) - } - return - } - for scope := e; scope != nil; scope = scope.parent { - for _, v := range scope.vars { - if v.key != name { - continue - } - e.EncodeUint(substituteVar) // TODO: support arity > 0 - e.EncodeUint(uint64(v.offset)) - return - } - } - // TODO: refer to dictionary-wide scoped variables. - e.EncodeUint(substituteError) - e.EncodeString(name) - e.setError(fmt.Errorf("catmsg: unknown var %q", name)) -} - -// A Decoder deserializes and evaluates messages that are encoded by an encoder. -type Decoder struct { - tag language.Tag - dst Renderer - macros Dictionary - - err error - vars string - data string - - macroArg int // TODO: allow more than one argument -} - -// NewDecoder returns a new Decoder. -// -// Decoders are designed to be reused for multiple invocations of Execute. -// Only one goroutine may call Execute concurrently. -func NewDecoder(tag language.Tag, r Renderer, macros Dictionary) *Decoder { - return &Decoder{ - tag: tag, - dst: r, - macros: macros, - } -} - -func (d *Decoder) setError(err error) { - if d.err == nil { - d.err = err - } -} - -// Language returns the language in which the message is being rendered. -// -// The destination language may be a child language of the language used for -// encoding. For instance, a decoding language of "pt-PT"" is consistent with an -// encoding language of "pt". -func (d *Decoder) Language() language.Tag { return d.tag } - -// Done reports whether there are more bytes to process in this message. -func (d *Decoder) Done() bool { return len(d.data) == 0 } - -// Render implements Renderer. -func (d *Decoder) Render(s string) { d.dst.Render(s) } - -// Arg implements Renderer. -// -// During evaluation of macros, the argument positions may be mapped to -// arguments that differ from the original call. -func (d *Decoder) Arg(i int) interface{} { - if d.macroArg != 0 { - if i != 1 { - panic("catmsg: only macros with single argument supported") - } - i = d.macroArg - } - return d.dst.Arg(i) -} - -// DecodeUint decodes a number that was encoded with EncodeUint and advances the -// position. -func (d *Decoder) DecodeUint() uint64 { - x, n, err := decodeUintString(d.data) - d.data = d.data[n:] - if err != nil { - d.setError(err) - } - return x -} - -// DecodeString decodes a string that was encoded with EncodeString and advances -// the position. -func (d *Decoder) DecodeString() string { - size := d.DecodeUint() - s := d.data[:size] - d.data = d.data[size:] - return s -} - -// SkipMessage skips the message at the current location and advances the -// position. -func (d *Decoder) SkipMessage() { - n := int(d.DecodeUint()) - d.data = d.data[n:] -} - -// Execute decodes and evaluates msg. -// -// Only one goroutine may call execute. -func (d *Decoder) Execute(msg string) error { - d.err = nil - if !d.execute(msg) { - return ErrNoMatch - } - return d.err -} - -func (d *Decoder) execute(msg string) bool { - saved := d.data - d.data = msg - ok := d.executeMessage() - d.data = saved - return ok -} - -// executeMessageFromData is like execute, but also decodes a leading message -// size and clips the given string accordingly. -// -// It reports the number of bytes consumed and whether a message was selected. -func (d *Decoder) executeMessageFromData(s string) (n int, ok bool) { - saved := d.data - d.data = s - size := int(d.DecodeUint()) - n = len(s) - len(d.data) - // Sanitize the setting. This allows skipping a size argument for - // RawString and method Done. - d.data = d.data[:size] - ok = d.executeMessage() - n += size - len(d.data) - d.data = saved - return n, ok -} - -var errUnknownHandler = errors.New("catmsg: string contains unsupported handler") - -// executeMessage reads the handle id, initializes the decoder and executes the -// message. It is assumed that all of d.data[d.p:] is the single message. -func (d *Decoder) executeMessage() bool { - if d.Done() { - // We interpret no data as a valid empty message. - return true - } - handle := d.DecodeUint() - - var fn Handler - mutex.Lock() - if int(handle) < len(handlers) { - fn = handlers[handle] - } - mutex.Unlock() - if fn == nil { - d.setError(errUnknownHandler) - d.execute(fmt.Sprintf("\x02$!(UNKNOWNMSGHANDLER=%#x)", handle)) - return true - } - return fn(d) -} - -// ExecuteMessage decodes and executes the message at the current position. -func (d *Decoder) ExecuteMessage() bool { - n, ok := d.executeMessageFromData(d.data) - d.data = d.data[n:] - return ok -} - -// ExecuteSubstitution executes the message corresponding to the substitution -// as encoded by EncodeSubstitution. -func (d *Decoder) ExecuteSubstitution() { - switch x := d.DecodeUint(); x { - case substituteVar: - offset := d.DecodeUint() - d.executeMessageFromData(d.vars[offset:]) - case substituteMacro: - name := d.DecodeString() - data, ok := d.macros.Lookup(name) - old := d.macroArg - // TODO: support macros of arity other than 1. - d.macroArg = int(d.DecodeUint()) - switch { - case !ok: - // TODO: detect this at creation time. - d.setError(fmt.Errorf("catmsg: undefined macro %q", name)) - fallthrough - case !d.execute(data): - d.dst.Render(name) // fall back to macro name. - } - d.macroArg = old - case substituteError: - d.dst.Render(d.DecodeString()) - default: - panic("catmsg: unreachable") - } -} diff --git a/vendor/golang.org/x/text/internal/catmsg/varint.go b/vendor/golang.org/x/text/internal/catmsg/varint.go deleted file mode 100644 index a2cee2cf5..000000000 --- a/vendor/golang.org/x/text/internal/catmsg/varint.go +++ /dev/null @@ -1,62 +0,0 @@ -// 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 catmsg - -// This file implements varint encoding analogous to the one in encoding/binary. -// We need a string version of this function, so we add that here and then add -// the rest for consistency. - -import "errors" - -var ( - errIllegalVarint = errors.New("catmsg: illegal varint") - errVarintTooLarge = errors.New("catmsg: varint too large for uint64") -) - -const maxVarintBytes = 10 // maximum length of a varint - -// encodeUint encodes x as a variable-sized integer into buf and returns the -// number of bytes written. buf must be at least maxVarintBytes long -func encodeUint(buf []byte, x uint64) (n int) { - for ; x > 127; n++ { - buf[n] = 0x80 | uint8(x&0x7F) - x >>= 7 - } - buf[n] = uint8(x) - n++ - return n -} - -func decodeUintString(s string) (x uint64, size int, err error) { - i := 0 - for shift := uint(0); shift < 64; shift += 7 { - if i >= len(s) { - return 0, i, errIllegalVarint - } - b := uint64(s[i]) - i++ - x |= (b & 0x7F) << shift - if b&0x80 == 0 { - return x, i, nil - } - } - return 0, i, errVarintTooLarge -} - -func decodeUint(b []byte) (x uint64, size int, err error) { - i := 0 - for shift := uint(0); shift < 64; shift += 7 { - if i >= len(b) { - return 0, i, errIllegalVarint - } - c := uint64(b[i]) - i++ - x |= (c & 0x7F) << shift - if c&0x80 == 0 { - return x, i, nil - } - } - return 0, i, errVarintTooLarge -} diff --git a/vendor/golang.org/x/text/internal/format/format.go b/vendor/golang.org/x/text/internal/format/format.go deleted file mode 100644 index ee1c57a3c..000000000 --- a/vendor/golang.org/x/text/internal/format/format.go +++ /dev/null @@ -1,41 +0,0 @@ -// 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 format contains types for defining language-specific formatting of -// values. -// -// This package is internal now, but will eventually be exposed after the API -// settles. -package format // import "golang.org/x/text/internal/format" - -import ( - "fmt" - - "golang.org/x/text/language" -) - -// State represents the printer state passed to custom formatters. It provides -// access to the fmt.State interface and the sentence and language-related -// context. -type State interface { - fmt.State - - // Language reports the requested language in which to render a message. - Language() language.Tag - - // TODO: consider this and removing rune from the Format method in the - // Formatter interface. - // - // Verb returns the format variant to render, analogous to the types used - // in fmt. Use 'v' for the default or only variant. - // Verb() rune - - // TODO: more info: - // - sentence context such as linguistic features passed by the translator. -} - -// Formatter is analogous to fmt.Formatter. -type Formatter interface { - Format(state State, verb rune) -} diff --git a/vendor/golang.org/x/text/internal/format/parser.go b/vendor/golang.org/x/text/internal/format/parser.go deleted file mode 100644 index 855aed71d..000000000 --- a/vendor/golang.org/x/text/internal/format/parser.go +++ /dev/null @@ -1,358 +0,0 @@ -// 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 format - -import ( - "reflect" - "unicode/utf8" -) - -// A Parser parses a format string. The result from the parse are set in the -// struct fields. -type Parser struct { - Verb rune - - WidthPresent bool - PrecPresent bool - Minus bool - Plus bool - Sharp bool - Space bool - Zero bool - - // For the formats %+v %#v, we set the plusV/sharpV flags - // and clear the plus/sharp flags since %+v and %#v are in effect - // different, flagless formats set at the top level. - PlusV bool - SharpV bool - - HasIndex bool - - Width int - Prec int // precision - - // retain arguments across calls. - Args []interface{} - // retain current argument number across calls - ArgNum int - - // reordered records whether the format string used argument reordering. - Reordered bool - // goodArgNum records whether the most recent reordering directive was valid. - goodArgNum bool - - // position info - format string - startPos int - endPos int - Status Status -} - -// Reset initializes a parser to scan format strings for the given args. -func (p *Parser) Reset(args []interface{}) { - p.Args = args - p.ArgNum = 0 - p.startPos = 0 - p.Reordered = false -} - -// Text returns the part of the format string that was parsed by the last call -// to Scan. It returns the original substitution clause if the current scan -// parsed a substitution. -func (p *Parser) Text() string { return p.format[p.startPos:p.endPos] } - -// SetFormat sets a new format string to parse. It does not reset the argument -// count. -func (p *Parser) SetFormat(format string) { - p.format = format - p.startPos = 0 - p.endPos = 0 -} - -// Status indicates the result type of a call to Scan. -type Status int - -const ( - StatusText Status = iota - StatusSubstitution - StatusBadWidthSubstitution - StatusBadPrecSubstitution - StatusNoVerb - StatusBadArgNum - StatusMissingArg -) - -// ClearFlags reset the parser to default behavior. -func (p *Parser) ClearFlags() { - p.WidthPresent = false - p.PrecPresent = false - p.Minus = false - p.Plus = false - p.Sharp = false - p.Space = false - p.Zero = false - - p.PlusV = false - p.SharpV = false - - p.HasIndex = false -} - -// Scan scans the next part of the format string and sets the status to -// indicate whether it scanned a string literal, substitution or error. -func (p *Parser) Scan() bool { - p.Status = StatusText - format := p.format - end := len(format) - if p.endPos >= end { - return false - } - afterIndex := false // previous item in format was an index like [3]. - - p.startPos = p.endPos - p.goodArgNum = true - i := p.startPos - for i < end && format[i] != '%' { - i++ - } - if i > p.startPos { - p.endPos = i - return true - } - // Process one verb - i++ - - p.Status = StatusSubstitution - - // Do we have flags? - p.ClearFlags() - -simpleFormat: - for ; i < end; i++ { - c := p.format[i] - switch c { - case '#': - p.Sharp = true - case '0': - p.Zero = !p.Minus // Only allow zero padding to the left. - case '+': - p.Plus = true - case '-': - p.Minus = true - p.Zero = false // Do not pad with zeros to the right. - case ' ': - p.Space = true - default: - // Fast path for common case of ascii lower case simple verbs - // without precision or width or argument indices. - if 'a' <= c && c <= 'z' && p.ArgNum < len(p.Args) { - if c == 'v' { - // Go syntax - p.SharpV = p.Sharp - p.Sharp = false - // Struct-field syntax - p.PlusV = p.Plus - p.Plus = false - } - p.Verb = rune(c) - p.ArgNum++ - p.endPos = i + 1 - return true - } - // Format is more complex than simple flags and a verb or is malformed. - break simpleFormat - } - } - - // Do we have an explicit argument index? - i, afterIndex = p.updateArgNumber(format, i) - - // Do we have width? - if i < end && format[i] == '*' { - i++ - p.Width, p.WidthPresent = p.intFromArg() - - if !p.WidthPresent { - p.Status = StatusBadWidthSubstitution - } - - // We have a negative width, so take its value and ensure - // that the minus flag is set - if p.Width < 0 { - p.Width = -p.Width - p.Minus = true - p.Zero = false // Do not pad with zeros to the right. - } - afterIndex = false - } else { - p.Width, p.WidthPresent, i = parsenum(format, i, end) - if afterIndex && p.WidthPresent { // "%[3]2d" - p.goodArgNum = false - } - } - - // Do we have precision? - if i+1 < end && format[i] == '.' { - i++ - if afterIndex { // "%[3].2d" - p.goodArgNum = false - } - i, afterIndex = p.updateArgNumber(format, i) - if i < end && format[i] == '*' { - i++ - p.Prec, p.PrecPresent = p.intFromArg() - // Negative precision arguments don't make sense - if p.Prec < 0 { - p.Prec = 0 - p.PrecPresent = false - } - if !p.PrecPresent { - p.Status = StatusBadPrecSubstitution - } - afterIndex = false - } else { - p.Prec, p.PrecPresent, i = parsenum(format, i, end) - if !p.PrecPresent { - p.Prec = 0 - p.PrecPresent = true - } - } - } - - if !afterIndex { - i, afterIndex = p.updateArgNumber(format, i) - } - p.HasIndex = afterIndex - - if i >= end { - p.endPos = i - p.Status = StatusNoVerb - return true - } - - verb, w := utf8.DecodeRuneInString(format[i:]) - p.endPos = i + w - p.Verb = verb - - switch { - case verb == '%': // Percent does not absorb operands and ignores f.wid and f.prec. - p.startPos = p.endPos - 1 - p.Status = StatusText - case !p.goodArgNum: - p.Status = StatusBadArgNum - case p.ArgNum >= len(p.Args): // No argument left over to print for the current verb. - p.Status = StatusMissingArg - p.ArgNum++ - case verb == 'v': - // Go syntax - p.SharpV = p.Sharp - p.Sharp = false - // Struct-field syntax - p.PlusV = p.Plus - p.Plus = false - fallthrough - default: - p.ArgNum++ - } - return true -} - -// intFromArg gets the ArgNumth element of Args. On return, isInt reports -// whether the argument has integer type. -func (p *Parser) intFromArg() (num int, isInt bool) { - if p.ArgNum < len(p.Args) { - arg := p.Args[p.ArgNum] - num, isInt = arg.(int) // Almost always OK. - if !isInt { - // Work harder. - switch v := reflect.ValueOf(arg); v.Kind() { - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - n := v.Int() - if int64(int(n)) == n { - num = int(n) - isInt = true - } - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - n := v.Uint() - if int64(n) >= 0 && uint64(int(n)) == n { - num = int(n) - isInt = true - } - default: - // Already 0, false. - } - } - p.ArgNum++ - if tooLarge(num) { - num = 0 - isInt = false - } - } - return -} - -// parseArgNumber returns the value of the bracketed number, minus 1 -// (explicit argument numbers are one-indexed but we want zero-indexed). -// The opening bracket is known to be present at format[0]. -// The returned values are the index, the number of bytes to consume -// up to the closing paren, if present, and whether the number parsed -// ok. The bytes to consume will be 1 if no closing paren is present. -func parseArgNumber(format string) (index int, wid int, ok bool) { - // There must be at least 3 bytes: [n]. - if len(format) < 3 { - return 0, 1, false - } - - // Find closing bracket. - for i := 1; i < len(format); i++ { - if format[i] == ']' { - width, ok, newi := parsenum(format, 1, i) - if !ok || newi != i { - return 0, i + 1, false - } - return width - 1, i + 1, true // arg numbers are one-indexed and skip paren. - } - } - return 0, 1, false -} - -// updateArgNumber returns the next argument to evaluate, which is either the value of the passed-in -// argNum or the value of the bracketed integer that begins format[i:]. It also returns -// the new value of i, that is, the index of the next byte of the format to process. -func (p *Parser) updateArgNumber(format string, i int) (newi int, found bool) { - if len(format) <= i || format[i] != '[' { - return i, false - } - p.Reordered = true - index, wid, ok := parseArgNumber(format[i:]) - if ok && 0 <= index && index < len(p.Args) { - p.ArgNum = index - return i + wid, true - } - p.goodArgNum = false - return i + wid, ok -} - -// tooLarge reports whether the magnitude of the integer is -// too large to be used as a formatting width or precision. -func tooLarge(x int) bool { - const max int = 1e6 - return x > max || x < -max -} - -// parsenum converts ASCII to integer. num is 0 (and isnum is false) if no number present. -func parsenum(s string, start, end int) (num int, isnum bool, newi int) { - if start >= end { - return 0, false, end - } - for newi = start; newi < end && '0' <= s[newi] && s[newi] <= '9'; newi++ { - if tooLarge(num) { - return 0, false, end // Overflow; crazy long number most likely. - } - num = num*10 + int(s[newi]-'0') - isnum = true - } - return -} diff --git a/vendor/golang.org/x/text/internal/internal.go b/vendor/golang.org/x/text/internal/internal.go deleted file mode 100644 index 3cddbbdda..000000000 --- a/vendor/golang.org/x/text/internal/internal.go +++ /dev/null @@ -1,49 +0,0 @@ -// 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 internal contains non-exported functionality that are used by -// packages in the text repository. -package internal // import "golang.org/x/text/internal" - -import ( - "sort" - - "golang.org/x/text/language" -) - -// SortTags sorts tags in place. -func SortTags(tags []language.Tag) { - sort.Sort(sorter(tags)) -} - -type sorter []language.Tag - -func (s sorter) Len() int { - return len(s) -} - -func (s sorter) Swap(i, j int) { - s[i], s[j] = s[j], s[i] -} - -func (s sorter) Less(i, j int) bool { - return s[i].String() < s[j].String() -} - -// UniqueTags sorts and filters duplicate tags in place and returns a slice with -// only unique tags. -func UniqueTags(tags []language.Tag) []language.Tag { - if len(tags) <= 1 { - return tags - } - SortTags(tags) - k := 0 - for i := 1; i < len(tags); i++ { - if tags[k].String() < tags[i].String() { - k++ - tags[k] = tags[i] - } - } - return tags[:k+1] -} diff --git a/vendor/golang.org/x/text/internal/language/common.go b/vendor/golang.org/x/text/internal/language/common.go deleted file mode 100644 index cdfdb7497..000000000 --- a/vendor/golang.org/x/text/internal/language/common.go +++ /dev/null @@ -1,16 +0,0 @@ -// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. - -package language - -// This file contains code common to the maketables.go and the package code. - -// AliasType is the type of an alias in AliasMap. -type AliasType int8 - -const ( - Deprecated AliasType = iota - Macro - Legacy - - AliasTypeUnknown AliasType = -1 -) diff --git a/vendor/golang.org/x/text/internal/language/compact.go b/vendor/golang.org/x/text/internal/language/compact.go deleted file mode 100644 index 46a001507..000000000 --- a/vendor/golang.org/x/text/internal/language/compact.go +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2018 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 language - -// CompactCoreInfo is a compact integer with the three core tags encoded. -type CompactCoreInfo uint32 - -// GetCompactCore generates a uint32 value that is guaranteed to be unique for -// different language, region, and script values. -func GetCompactCore(t Tag) (cci CompactCoreInfo, ok bool) { - if t.LangID > langNoIndexOffset { - return 0, false - } - cci |= CompactCoreInfo(t.LangID) << (8 + 12) - cci |= CompactCoreInfo(t.ScriptID) << 12 - cci |= CompactCoreInfo(t.RegionID) - return cci, true -} - -// Tag generates a tag from c. -func (c CompactCoreInfo) Tag() Tag { - return Tag{ - LangID: Language(c >> 20), - RegionID: Region(c & 0x3ff), - ScriptID: Script(c>>12) & 0xff, - } -} diff --git a/vendor/golang.org/x/text/internal/language/compact/compact.go b/vendor/golang.org/x/text/internal/language/compact/compact.go deleted file mode 100644 index 1b36935ef..000000000 --- a/vendor/golang.org/x/text/internal/language/compact/compact.go +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2018 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 compact defines a compact representation of language tags. -// -// Common language tags (at least all for which locale information is defined -// in CLDR) are assigned a unique index. Each Tag is associated with such an -// ID for selecting language-related resources (such as translations) as well -// as one for selecting regional defaults (currency, number formatting, etc.) -// -// It may want to export this functionality at some point, but at this point -// this is only available for use within x/text. -package compact // import "golang.org/x/text/internal/language/compact" - -import ( - "sort" - "strings" - - "golang.org/x/text/internal/language" -) - -// ID is an integer identifying a single tag. -type ID uint16 - -func getCoreIndex(t language.Tag) (id ID, ok bool) { - cci, ok := language.GetCompactCore(t) - if !ok { - return 0, false - } - i := sort.Search(len(coreTags), func(i int) bool { - return cci <= coreTags[i] - }) - if i == len(coreTags) || coreTags[i] != cci { - return 0, false - } - return ID(i), true -} - -// Parent returns the ID of the parent or the root ID if id is already the root. -func (id ID) Parent() ID { - return parents[id] -} - -// Tag converts id to an internal language Tag. -func (id ID) Tag() language.Tag { - if int(id) >= len(coreTags) { - return specialTags[int(id)-len(coreTags)] - } - return coreTags[id].Tag() -} - -var specialTags []language.Tag - -func init() { - tags := strings.Split(specialTagsStr, " ") - specialTags = make([]language.Tag, len(tags)) - for i, t := range tags { - specialTags[i] = language.MustParse(t) - } -} diff --git a/vendor/golang.org/x/text/internal/language/compact/language.go b/vendor/golang.org/x/text/internal/language/compact/language.go deleted file mode 100644 index 8c1b6666f..000000000 --- a/vendor/golang.org/x/text/internal/language/compact/language.go +++ /dev/null @@ -1,260 +0,0 @@ -// Copyright 2013 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_index.go -output tables.go -//go:generate go run gen_parents.go - -package compact - -// TODO: Remove above NOTE after: -// - verifying that tables are dropped correctly (most notably matcher tables). - -import ( - "strings" - - "golang.org/x/text/internal/language" -) - -// Tag represents a BCP 47 language tag. It is used to specify an instance of a -// specific language or locale. All language tag values are guaranteed to be -// well-formed. -type Tag struct { - // NOTE: exported tags will become part of the public API. - language ID - locale ID - full fullTag // always a language.Tag for now. -} - -const _und = 0 - -type fullTag interface { - IsRoot() bool - Parent() language.Tag -} - -// Make a compact Tag from a fully specified internal language Tag. -func Make(t language.Tag) (tag Tag) { - if region := t.TypeForKey("rg"); len(region) == 6 && region[2:] == "zzzz" { - if r, err := language.ParseRegion(region[:2]); err == nil { - tFull := t - t, _ = t.SetTypeForKey("rg", "") - // TODO: should we not consider "va" for the language tag? - var exact1, exact2 bool - tag.language, exact1 = FromTag(t) - t.RegionID = r - tag.locale, exact2 = FromTag(t) - if !exact1 || !exact2 { - tag.full = tFull - } - return tag - } - } - lang, ok := FromTag(t) - tag.language = lang - tag.locale = lang - if !ok { - tag.full = t - } - return tag -} - -// Tag returns an internal language Tag version of this tag. -func (t Tag) Tag() language.Tag { - if t.full != nil { - return t.full.(language.Tag) - } - tag := t.language.Tag() - if t.language != t.locale { - loc := t.locale.Tag() - tag, _ = tag.SetTypeForKey("rg", strings.ToLower(loc.RegionID.String())+"zzzz") - } - return tag -} - -// IsCompact reports whether this tag is fully defined in terms of ID. -func (t *Tag) IsCompact() bool { - return t.full == nil -} - -// MayHaveVariants reports whether a tag may have variants. If it returns false -// it is guaranteed the tag does not have variants. -func (t Tag) MayHaveVariants() bool { - return t.full != nil || int(t.language) >= len(coreTags) -} - -// MayHaveExtensions reports whether a tag may have extensions. If it returns -// false it is guaranteed the tag does not have them. -func (t Tag) MayHaveExtensions() bool { - return t.full != nil || - int(t.language) >= len(coreTags) || - t.language != t.locale -} - -// IsRoot returns true if t is equal to language "und". -func (t Tag) IsRoot() bool { - if t.full != nil { - return t.full.IsRoot() - } - return t.language == _und -} - -// Parent returns the CLDR parent of t. In CLDR, missing fields in data for a -// specific language are substituted with fields from the parent language. -// The parent for a language may change for newer versions of CLDR. -func (t Tag) Parent() Tag { - if t.full != nil { - return Make(t.full.Parent()) - } - if t.language != t.locale { - // Simulate stripping -u-rg-xxxxxx - return Tag{language: t.language, locale: t.language} - } - // TODO: use parent lookup table once cycle from internal package is - // removed. Probably by internalizing the table and declaring this fast - // enough. - // lang := compactID(internal.Parent(uint16(t.language))) - lang, _ := FromTag(t.language.Tag().Parent()) - return Tag{language: lang, locale: lang} -} - -// nextToken returns token t and the rest of the string. -func nextToken(s string) (t, tail string) { - p := strings.Index(s[1:], "-") - if p == -1 { - return s[1:], "" - } - p++ - return s[1:p], s[p:] -} - -// LanguageID returns an index, where 0 <= index < NumCompactTags, for tags -// for which data exists in the text repository.The index will change over time -// and should not be stored in persistent storage. If t does not match a compact -// index, exact will be false and the compact index will be returned for the -// first match after repeatedly taking the Parent of t. -func LanguageID(t Tag) (id ID, exact bool) { - return t.language, t.full == nil -} - -// RegionalID returns the ID for the regional variant of this tag. This index is -// used to indicate region-specific overrides, such as default currency, default -// calendar and week data, default time cycle, and default measurement system -// and unit preferences. -// -// For instance, the tag en-GB-u-rg-uszzzz specifies British English with US -// settings for currency, number formatting, etc. The CompactIndex for this tag -// will be that for en-GB, while the RegionalID will be the one corresponding to -// en-US. -func RegionalID(t Tag) (id ID, exact bool) { - return t.locale, t.full == nil -} - -// LanguageTag returns t stripped of regional variant indicators. -// -// At the moment this means it is stripped of a regional and variant subtag "rg" -// and "va" in the "u" extension. -func (t Tag) LanguageTag() Tag { - if t.full == nil { - return Tag{language: t.language, locale: t.language} - } - tt := t.Tag() - tt.SetTypeForKey("rg", "") - tt.SetTypeForKey("va", "") - return Make(tt) -} - -// RegionalTag returns the regional variant of the tag. -// -// At the moment this means that the region is set from the regional subtag -// "rg" in the "u" extension. -func (t Tag) RegionalTag() Tag { - rt := Tag{language: t.locale, locale: t.locale} - if t.full == nil { - return rt - } - b := language.Builder{} - tag := t.Tag() - // tag, _ = tag.SetTypeForKey("rg", "") - b.SetTag(t.locale.Tag()) - if v := tag.Variants(); v != "" { - for _, v := range strings.Split(v, "-") { - b.AddVariant(v) - } - } - for _, e := range tag.Extensions() { - b.AddExt(e) - } - return t -} - -// FromTag reports closest matching ID for an internal language Tag. -func FromTag(t language.Tag) (id ID, exact bool) { - // TODO: perhaps give more frequent tags a lower index. - // TODO: we could make the indexes stable. This will excluded some - // possibilities for optimization, so don't do this quite yet. - exact = true - - b, s, r := t.Raw() - if t.HasString() { - if t.IsPrivateUse() { - // We have no entries for user-defined tags. - return 0, false - } - hasExtra := false - if t.HasVariants() { - if t.HasExtensions() { - build := language.Builder{} - build.SetTag(language.Tag{LangID: b, ScriptID: s, RegionID: r}) - build.AddVariant(t.Variants()) - exact = false - t = build.Make() - } - hasExtra = true - } else if _, ok := t.Extension('u'); ok { - // TODO: va may mean something else. Consider not considering it. - // Strip all but the 'va' entry. - old := t - variant := t.TypeForKey("va") - t = language.Tag{LangID: b, ScriptID: s, RegionID: r} - if variant != "" { - t, _ = t.SetTypeForKey("va", variant) - hasExtra = true - } - exact = old == t - } else { - exact = false - } - if hasExtra { - // We have some variants. - for i, s := range specialTags { - if s == t { - return ID(i + len(coreTags)), exact - } - } - exact = false - } - } - if x, ok := getCoreIndex(t); ok { - return x, exact - } - exact = false - if r != 0 && s == 0 { - // Deal with cases where an extra script is inserted for the region. - t, _ := t.Maximize() - if x, ok := getCoreIndex(t); ok { - return x, exact - } - } - for t = t.Parent(); t != root; t = t.Parent() { - // No variants specified: just compare core components. - // The key has the form lllssrrr, where l, s, and r are nibbles for - // respectively the langID, scriptID, and regionID. - if x, ok := getCoreIndex(t); ok { - return x, exact - } - } - return 0, exact -} - -var root = language.Tag{} diff --git a/vendor/golang.org/x/text/internal/language/compact/parents.go b/vendor/golang.org/x/text/internal/language/compact/parents.go deleted file mode 100644 index 8d810723c..000000000 --- a/vendor/golang.org/x/text/internal/language/compact/parents.go +++ /dev/null @@ -1,120 +0,0 @@ -// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. - -package compact - -// parents maps a compact index of a tag to the compact index of the parent of -// this tag. -var parents = []ID{ // 775 elements - // Entry 0 - 3F - 0x0000, 0x0000, 0x0001, 0x0001, 0x0000, 0x0004, 0x0000, 0x0006, - 0x0000, 0x0008, 0x0000, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, - 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, - 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, - 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x0000, - 0x0000, 0x0028, 0x0000, 0x002a, 0x0000, 0x002c, 0x0000, 0x0000, - 0x002f, 0x002e, 0x002e, 0x0000, 0x0033, 0x0000, 0x0035, 0x0000, - 0x0037, 0x0000, 0x0039, 0x0000, 0x003b, 0x0000, 0x0000, 0x003e, - // Entry 40 - 7F - 0x0000, 0x0040, 0x0040, 0x0000, 0x0043, 0x0043, 0x0000, 0x0046, - 0x0000, 0x0048, 0x0000, 0x0000, 0x004b, 0x004a, 0x004a, 0x0000, - 0x004f, 0x004f, 0x004f, 0x004f, 0x0000, 0x0054, 0x0054, 0x0000, - 0x0057, 0x0000, 0x0059, 0x0000, 0x005b, 0x0000, 0x005d, 0x005d, - 0x0000, 0x0060, 0x0000, 0x0062, 0x0000, 0x0064, 0x0000, 0x0066, - 0x0066, 0x0000, 0x0069, 0x0000, 0x006b, 0x006b, 0x006b, 0x006b, - 0x006b, 0x006b, 0x006b, 0x0000, 0x0073, 0x0000, 0x0075, 0x0000, - 0x0077, 0x0000, 0x0000, 0x007a, 0x0000, 0x007c, 0x0000, 0x007e, - // Entry 80 - BF - 0x0000, 0x0080, 0x0080, 0x0000, 0x0083, 0x0083, 0x0000, 0x0086, - 0x0087, 0x0087, 0x0087, 0x0086, 0x0088, 0x0087, 0x0087, 0x0087, - 0x0086, 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, 0x0088, - 0x0087, 0x0087, 0x0087, 0x0087, 0x0088, 0x0087, 0x0088, 0x0087, - 0x0087, 0x0088, 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, - 0x0087, 0x0087, 0x0087, 0x0086, 0x0087, 0x0087, 0x0087, 0x0087, - 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, - 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, 0x0086, 0x0087, 0x0086, - // Entry C0 - FF - 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, - 0x0088, 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, - 0x0086, 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, 0x0088, 0x0087, - 0x0087, 0x0088, 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, - 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, 0x0086, 0x0086, 0x0087, - 0x0087, 0x0086, 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, 0x0000, - 0x00ef, 0x0000, 0x00f1, 0x00f2, 0x00f2, 0x00f2, 0x00f2, 0x00f2, - 0x00f2, 0x00f2, 0x00f2, 0x00f2, 0x00f1, 0x00f2, 0x00f1, 0x00f1, - // Entry 100 - 13F - 0x00f2, 0x00f2, 0x00f1, 0x00f2, 0x00f2, 0x00f2, 0x00f2, 0x00f1, - 0x00f2, 0x00f2, 0x00f2, 0x00f2, 0x00f2, 0x00f2, 0x0000, 0x010e, - 0x0000, 0x0110, 0x0000, 0x0112, 0x0000, 0x0114, 0x0114, 0x0000, - 0x0117, 0x0117, 0x0117, 0x0117, 0x0000, 0x011c, 0x0000, 0x011e, - 0x0000, 0x0120, 0x0120, 0x0000, 0x0123, 0x0123, 0x0123, 0x0123, - 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, - 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, - 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, - // Entry 140 - 17F - 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, - 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, - 0x0123, 0x0123, 0x0000, 0x0152, 0x0000, 0x0154, 0x0000, 0x0156, - 0x0000, 0x0158, 0x0000, 0x015a, 0x0000, 0x015c, 0x015c, 0x015c, - 0x0000, 0x0160, 0x0000, 0x0000, 0x0163, 0x0000, 0x0165, 0x0000, - 0x0167, 0x0167, 0x0167, 0x0000, 0x016b, 0x0000, 0x016d, 0x0000, - 0x016f, 0x0000, 0x0171, 0x0171, 0x0000, 0x0174, 0x0000, 0x0176, - 0x0000, 0x0178, 0x0000, 0x017a, 0x0000, 0x017c, 0x0000, 0x017e, - // Entry 180 - 1BF - 0x0000, 0x0000, 0x0000, 0x0182, 0x0000, 0x0184, 0x0184, 0x0184, - 0x0184, 0x0000, 0x0000, 0x0000, 0x018b, 0x0000, 0x0000, 0x018e, - 0x0000, 0x0000, 0x0191, 0x0000, 0x0000, 0x0000, 0x0195, 0x0000, - 0x0197, 0x0000, 0x0000, 0x019a, 0x0000, 0x0000, 0x019d, 0x0000, - 0x019f, 0x0000, 0x01a1, 0x0000, 0x01a3, 0x0000, 0x01a5, 0x0000, - 0x01a7, 0x0000, 0x01a9, 0x0000, 0x01ab, 0x0000, 0x01ad, 0x0000, - 0x01af, 0x0000, 0x01b1, 0x01b1, 0x0000, 0x01b4, 0x0000, 0x01b6, - 0x0000, 0x01b8, 0x0000, 0x01ba, 0x0000, 0x01bc, 0x0000, 0x0000, - // Entry 1C0 - 1FF - 0x01bf, 0x0000, 0x01c1, 0x0000, 0x01c3, 0x0000, 0x01c5, 0x0000, - 0x01c7, 0x0000, 0x01c9, 0x0000, 0x01cb, 0x01cb, 0x01cb, 0x01cb, - 0x0000, 0x01d0, 0x0000, 0x01d2, 0x01d2, 0x0000, 0x01d5, 0x0000, - 0x01d7, 0x0000, 0x01d9, 0x0000, 0x01db, 0x0000, 0x01dd, 0x0000, - 0x01df, 0x01df, 0x0000, 0x01e2, 0x0000, 0x01e4, 0x0000, 0x01e6, - 0x0000, 0x01e8, 0x0000, 0x01ea, 0x0000, 0x01ec, 0x0000, 0x01ee, - 0x0000, 0x01f0, 0x0000, 0x0000, 0x01f3, 0x0000, 0x01f5, 0x01f5, - 0x01f5, 0x0000, 0x01f9, 0x0000, 0x01fb, 0x0000, 0x01fd, 0x0000, - // Entry 200 - 23F - 0x01ff, 0x0000, 0x0000, 0x0202, 0x0000, 0x0204, 0x0204, 0x0000, - 0x0207, 0x0000, 0x0209, 0x0209, 0x0000, 0x020c, 0x020c, 0x0000, - 0x020f, 0x020f, 0x020f, 0x020f, 0x020f, 0x020f, 0x020f, 0x0000, - 0x0217, 0x0000, 0x0219, 0x0000, 0x021b, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0221, 0x0000, 0x0000, 0x0224, 0x0000, 0x0226, - 0x0226, 0x0000, 0x0229, 0x0000, 0x022b, 0x022b, 0x0000, 0x0000, - 0x022f, 0x022e, 0x022e, 0x0000, 0x0000, 0x0234, 0x0000, 0x0236, - 0x0000, 0x0238, 0x0000, 0x0244, 0x023a, 0x0244, 0x0244, 0x0244, - // Entry 240 - 27F - 0x0244, 0x0244, 0x0244, 0x0244, 0x023a, 0x0244, 0x0244, 0x0000, - 0x0247, 0x0247, 0x0247, 0x0000, 0x024b, 0x0000, 0x024d, 0x0000, - 0x024f, 0x024f, 0x0000, 0x0252, 0x0000, 0x0254, 0x0254, 0x0254, - 0x0254, 0x0254, 0x0254, 0x0000, 0x025b, 0x0000, 0x025d, 0x0000, - 0x025f, 0x0000, 0x0261, 0x0000, 0x0263, 0x0000, 0x0265, 0x0000, - 0x0000, 0x0268, 0x0268, 0x0268, 0x0000, 0x026c, 0x0000, 0x026e, - 0x0000, 0x0270, 0x0000, 0x0000, 0x0000, 0x0274, 0x0273, 0x0273, - 0x0000, 0x0278, 0x0000, 0x027a, 0x0000, 0x027c, 0x0000, 0x0000, - // Entry 280 - 2BF - 0x0000, 0x0000, 0x0281, 0x0000, 0x0000, 0x0284, 0x0000, 0x0286, - 0x0286, 0x0286, 0x0286, 0x0000, 0x028b, 0x028b, 0x028b, 0x0000, - 0x028f, 0x028f, 0x028f, 0x028f, 0x028f, 0x0000, 0x0295, 0x0295, - 0x0295, 0x0295, 0x0000, 0x0000, 0x0000, 0x0000, 0x029d, 0x029d, - 0x029d, 0x0000, 0x02a1, 0x02a1, 0x02a1, 0x02a1, 0x0000, 0x0000, - 0x02a7, 0x02a7, 0x02a7, 0x02a7, 0x0000, 0x02ac, 0x0000, 0x02ae, - 0x02ae, 0x0000, 0x02b1, 0x0000, 0x02b3, 0x0000, 0x02b5, 0x02b5, - 0x0000, 0x0000, 0x02b9, 0x0000, 0x0000, 0x0000, 0x02bd, 0x0000, - // Entry 2C0 - 2FF - 0x02bf, 0x02bf, 0x0000, 0x0000, 0x02c3, 0x0000, 0x02c5, 0x0000, - 0x02c7, 0x0000, 0x02c9, 0x0000, 0x02cb, 0x0000, 0x02cd, 0x02cd, - 0x0000, 0x0000, 0x02d1, 0x0000, 0x02d3, 0x02d0, 0x02d0, 0x0000, - 0x0000, 0x02d8, 0x02d7, 0x02d7, 0x0000, 0x0000, 0x02dd, 0x0000, - 0x02df, 0x0000, 0x02e1, 0x0000, 0x0000, 0x02e4, 0x0000, 0x02e6, - 0x0000, 0x0000, 0x02e9, 0x0000, 0x02eb, 0x0000, 0x02ed, 0x0000, - 0x02ef, 0x02ef, 0x0000, 0x0000, 0x02f3, 0x02f2, 0x02f2, 0x0000, - 0x02f7, 0x0000, 0x02f9, 0x02f9, 0x02f9, 0x02f9, 0x02f9, 0x0000, - // Entry 300 - 33F - 0x02ff, 0x0300, 0x02ff, 0x0000, 0x0303, 0x0051, 0x00e6, -} // Size: 1574 bytes - -// Total table size 1574 bytes (1KiB); checksum: 895AAF0B diff --git a/vendor/golang.org/x/text/internal/language/compact/tables.go b/vendor/golang.org/x/text/internal/language/compact/tables.go deleted file mode 100644 index a09ed198a..000000000 --- a/vendor/golang.org/x/text/internal/language/compact/tables.go +++ /dev/null @@ -1,1015 +0,0 @@ -// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. - -package compact - -import "golang.org/x/text/internal/language" - -// CLDRVersion is the CLDR version from which the tables in this package are derived. -const CLDRVersion = "32" - -// NumCompactTags is the number of common tags. The maximum tag is -// NumCompactTags-1. -const NumCompactTags = 775 -const ( - undIndex ID = 0 - afIndex ID = 1 - afNAIndex ID = 2 - afZAIndex ID = 3 - agqIndex ID = 4 - agqCMIndex ID = 5 - akIndex ID = 6 - akGHIndex ID = 7 - amIndex ID = 8 - amETIndex ID = 9 - arIndex ID = 10 - ar001Index ID = 11 - arAEIndex ID = 12 - arBHIndex ID = 13 - arDJIndex ID = 14 - arDZIndex ID = 15 - arEGIndex ID = 16 - arEHIndex ID = 17 - arERIndex ID = 18 - arILIndex ID = 19 - arIQIndex ID = 20 - arJOIndex ID = 21 - arKMIndex ID = 22 - arKWIndex ID = 23 - arLBIndex ID = 24 - arLYIndex ID = 25 - arMAIndex ID = 26 - arMRIndex ID = 27 - arOMIndex ID = 28 - arPSIndex ID = 29 - arQAIndex ID = 30 - arSAIndex ID = 31 - arSDIndex ID = 32 - arSOIndex ID = 33 - arSSIndex ID = 34 - arSYIndex ID = 35 - arTDIndex ID = 36 - arTNIndex ID = 37 - arYEIndex ID = 38 - arsIndex ID = 39 - asIndex ID = 40 - asINIndex ID = 41 - asaIndex ID = 42 - asaTZIndex ID = 43 - astIndex ID = 44 - astESIndex ID = 45 - azIndex ID = 46 - azCyrlIndex ID = 47 - azCyrlAZIndex ID = 48 - azLatnIndex ID = 49 - azLatnAZIndex ID = 50 - basIndex ID = 51 - basCMIndex ID = 52 - beIndex ID = 53 - beBYIndex ID = 54 - bemIndex ID = 55 - bemZMIndex ID = 56 - bezIndex ID = 57 - bezTZIndex ID = 58 - bgIndex ID = 59 - bgBGIndex ID = 60 - bhIndex ID = 61 - bmIndex ID = 62 - bmMLIndex ID = 63 - bnIndex ID = 64 - bnBDIndex ID = 65 - bnINIndex ID = 66 - boIndex ID = 67 - boCNIndex ID = 68 - boINIndex ID = 69 - brIndex ID = 70 - brFRIndex ID = 71 - brxIndex ID = 72 - brxINIndex ID = 73 - bsIndex ID = 74 - bsCyrlIndex ID = 75 - bsCyrlBAIndex ID = 76 - bsLatnIndex ID = 77 - bsLatnBAIndex ID = 78 - caIndex ID = 79 - caADIndex ID = 80 - caESIndex ID = 81 - caFRIndex ID = 82 - caITIndex ID = 83 - ccpIndex ID = 84 - ccpBDIndex ID = 85 - ccpINIndex ID = 86 - ceIndex ID = 87 - ceRUIndex ID = 88 - cggIndex ID = 89 - cggUGIndex ID = 90 - chrIndex ID = 91 - chrUSIndex ID = 92 - ckbIndex ID = 93 - ckbIQIndex ID = 94 - ckbIRIndex ID = 95 - csIndex ID = 96 - csCZIndex ID = 97 - cuIndex ID = 98 - cuRUIndex ID = 99 - cyIndex ID = 100 - cyGBIndex ID = 101 - daIndex ID = 102 - daDKIndex ID = 103 - daGLIndex ID = 104 - davIndex ID = 105 - davKEIndex ID = 106 - deIndex ID = 107 - deATIndex ID = 108 - deBEIndex ID = 109 - deCHIndex ID = 110 - deDEIndex ID = 111 - deITIndex ID = 112 - deLIIndex ID = 113 - deLUIndex ID = 114 - djeIndex ID = 115 - djeNEIndex ID = 116 - dsbIndex ID = 117 - dsbDEIndex ID = 118 - duaIndex ID = 119 - duaCMIndex ID = 120 - dvIndex ID = 121 - dyoIndex ID = 122 - dyoSNIndex ID = 123 - dzIndex ID = 124 - dzBTIndex ID = 125 - ebuIndex ID = 126 - ebuKEIndex ID = 127 - eeIndex ID = 128 - eeGHIndex ID = 129 - eeTGIndex ID = 130 - elIndex ID = 131 - elCYIndex ID = 132 - elGRIndex ID = 133 - enIndex ID = 134 - en001Index ID = 135 - en150Index ID = 136 - enAGIndex ID = 137 - enAIIndex ID = 138 - enASIndex ID = 139 - enATIndex ID = 140 - enAUIndex ID = 141 - enBBIndex ID = 142 - enBEIndex ID = 143 - enBIIndex ID = 144 - enBMIndex ID = 145 - enBSIndex ID = 146 - enBWIndex ID = 147 - enBZIndex ID = 148 - enCAIndex ID = 149 - enCCIndex ID = 150 - enCHIndex ID = 151 - enCKIndex ID = 152 - enCMIndex ID = 153 - enCXIndex ID = 154 - enCYIndex ID = 155 - enDEIndex ID = 156 - enDGIndex ID = 157 - enDKIndex ID = 158 - enDMIndex ID = 159 - enERIndex ID = 160 - enFIIndex ID = 161 - enFJIndex ID = 162 - enFKIndex ID = 163 - enFMIndex ID = 164 - enGBIndex ID = 165 - enGDIndex ID = 166 - enGGIndex ID = 167 - enGHIndex ID = 168 - enGIIndex ID = 169 - enGMIndex ID = 170 - enGUIndex ID = 171 - enGYIndex ID = 172 - enHKIndex ID = 173 - enIEIndex ID = 174 - enILIndex ID = 175 - enIMIndex ID = 176 - enINIndex ID = 177 - enIOIndex ID = 178 - enJEIndex ID = 179 - enJMIndex ID = 180 - enKEIndex ID = 181 - enKIIndex ID = 182 - enKNIndex ID = 183 - enKYIndex ID = 184 - enLCIndex ID = 185 - enLRIndex ID = 186 - enLSIndex ID = 187 - enMGIndex ID = 188 - enMHIndex ID = 189 - enMOIndex ID = 190 - enMPIndex ID = 191 - enMSIndex ID = 192 - enMTIndex ID = 193 - enMUIndex ID = 194 - enMWIndex ID = 195 - enMYIndex ID = 196 - enNAIndex ID = 197 - enNFIndex ID = 198 - enNGIndex ID = 199 - enNLIndex ID = 200 - enNRIndex ID = 201 - enNUIndex ID = 202 - enNZIndex ID = 203 - enPGIndex ID = 204 - enPHIndex ID = 205 - enPKIndex ID = 206 - enPNIndex ID = 207 - enPRIndex ID = 208 - enPWIndex ID = 209 - enRWIndex ID = 210 - enSBIndex ID = 211 - enSCIndex ID = 212 - enSDIndex ID = 213 - enSEIndex ID = 214 - enSGIndex ID = 215 - enSHIndex ID = 216 - enSIIndex ID = 217 - enSLIndex ID = 218 - enSSIndex ID = 219 - enSXIndex ID = 220 - enSZIndex ID = 221 - enTCIndex ID = 222 - enTKIndex ID = 223 - enTOIndex ID = 224 - enTTIndex ID = 225 - enTVIndex ID = 226 - enTZIndex ID = 227 - enUGIndex ID = 228 - enUMIndex ID = 229 - enUSIndex ID = 230 - enVCIndex ID = 231 - enVGIndex ID = 232 - enVIIndex ID = 233 - enVUIndex ID = 234 - enWSIndex ID = 235 - enZAIndex ID = 236 - enZMIndex ID = 237 - enZWIndex ID = 238 - eoIndex ID = 239 - eo001Index ID = 240 - esIndex ID = 241 - es419Index ID = 242 - esARIndex ID = 243 - esBOIndex ID = 244 - esBRIndex ID = 245 - esBZIndex ID = 246 - esCLIndex ID = 247 - esCOIndex ID = 248 - esCRIndex ID = 249 - esCUIndex ID = 250 - esDOIndex ID = 251 - esEAIndex ID = 252 - esECIndex ID = 253 - esESIndex ID = 254 - esGQIndex ID = 255 - esGTIndex ID = 256 - esHNIndex ID = 257 - esICIndex ID = 258 - esMXIndex ID = 259 - esNIIndex ID = 260 - esPAIndex ID = 261 - esPEIndex ID = 262 - esPHIndex ID = 263 - esPRIndex ID = 264 - esPYIndex ID = 265 - esSVIndex ID = 266 - esUSIndex ID = 267 - esUYIndex ID = 268 - esVEIndex ID = 269 - etIndex ID = 270 - etEEIndex ID = 271 - euIndex ID = 272 - euESIndex ID = 273 - ewoIndex ID = 274 - ewoCMIndex ID = 275 - faIndex ID = 276 - faAFIndex ID = 277 - faIRIndex ID = 278 - ffIndex ID = 279 - ffCMIndex ID = 280 - ffGNIndex ID = 281 - ffMRIndex ID = 282 - ffSNIndex ID = 283 - fiIndex ID = 284 - fiFIIndex ID = 285 - filIndex ID = 286 - filPHIndex ID = 287 - foIndex ID = 288 - foDKIndex ID = 289 - foFOIndex ID = 290 - frIndex ID = 291 - frBEIndex ID = 292 - frBFIndex ID = 293 - frBIIndex ID = 294 - frBJIndex ID = 295 - frBLIndex ID = 296 - frCAIndex ID = 297 - frCDIndex ID = 298 - frCFIndex ID = 299 - frCGIndex ID = 300 - frCHIndex ID = 301 - frCIIndex ID = 302 - frCMIndex ID = 303 - frDJIndex ID = 304 - frDZIndex ID = 305 - frFRIndex ID = 306 - frGAIndex ID = 307 - frGFIndex ID = 308 - frGNIndex ID = 309 - frGPIndex ID = 310 - frGQIndex ID = 311 - frHTIndex ID = 312 - frKMIndex ID = 313 - frLUIndex ID = 314 - frMAIndex ID = 315 - frMCIndex ID = 316 - frMFIndex ID = 317 - frMGIndex ID = 318 - frMLIndex ID = 319 - frMQIndex ID = 320 - frMRIndex ID = 321 - frMUIndex ID = 322 - frNCIndex ID = 323 - frNEIndex ID = 324 - frPFIndex ID = 325 - frPMIndex ID = 326 - frREIndex ID = 327 - frRWIndex ID = 328 - frSCIndex ID = 329 - frSNIndex ID = 330 - frSYIndex ID = 331 - frTDIndex ID = 332 - frTGIndex ID = 333 - frTNIndex ID = 334 - frVUIndex ID = 335 - frWFIndex ID = 336 - frYTIndex ID = 337 - furIndex ID = 338 - furITIndex ID = 339 - fyIndex ID = 340 - fyNLIndex ID = 341 - gaIndex ID = 342 - gaIEIndex ID = 343 - gdIndex ID = 344 - gdGBIndex ID = 345 - glIndex ID = 346 - glESIndex ID = 347 - gswIndex ID = 348 - gswCHIndex ID = 349 - gswFRIndex ID = 350 - gswLIIndex ID = 351 - guIndex ID = 352 - guINIndex ID = 353 - guwIndex ID = 354 - guzIndex ID = 355 - guzKEIndex ID = 356 - gvIndex ID = 357 - gvIMIndex ID = 358 - haIndex ID = 359 - haGHIndex ID = 360 - haNEIndex ID = 361 - haNGIndex ID = 362 - hawIndex ID = 363 - hawUSIndex ID = 364 - heIndex ID = 365 - heILIndex ID = 366 - hiIndex ID = 367 - hiINIndex ID = 368 - hrIndex ID = 369 - hrBAIndex ID = 370 - hrHRIndex ID = 371 - hsbIndex ID = 372 - hsbDEIndex ID = 373 - huIndex ID = 374 - huHUIndex ID = 375 - hyIndex ID = 376 - hyAMIndex ID = 377 - idIndex ID = 378 - idIDIndex ID = 379 - igIndex ID = 380 - igNGIndex ID = 381 - iiIndex ID = 382 - iiCNIndex ID = 383 - inIndex ID = 384 - ioIndex ID = 385 - isIndex ID = 386 - isISIndex ID = 387 - itIndex ID = 388 - itCHIndex ID = 389 - itITIndex ID = 390 - itSMIndex ID = 391 - itVAIndex ID = 392 - iuIndex ID = 393 - iwIndex ID = 394 - jaIndex ID = 395 - jaJPIndex ID = 396 - jboIndex ID = 397 - jgoIndex ID = 398 - jgoCMIndex ID = 399 - jiIndex ID = 400 - jmcIndex ID = 401 - jmcTZIndex ID = 402 - jvIndex ID = 403 - jwIndex ID = 404 - kaIndex ID = 405 - kaGEIndex ID = 406 - kabIndex ID = 407 - kabDZIndex ID = 408 - kajIndex ID = 409 - kamIndex ID = 410 - kamKEIndex ID = 411 - kcgIndex ID = 412 - kdeIndex ID = 413 - kdeTZIndex ID = 414 - keaIndex ID = 415 - keaCVIndex ID = 416 - khqIndex ID = 417 - khqMLIndex ID = 418 - kiIndex ID = 419 - kiKEIndex ID = 420 - kkIndex ID = 421 - kkKZIndex ID = 422 - kkjIndex ID = 423 - kkjCMIndex ID = 424 - klIndex ID = 425 - klGLIndex ID = 426 - klnIndex ID = 427 - klnKEIndex ID = 428 - kmIndex ID = 429 - kmKHIndex ID = 430 - knIndex ID = 431 - knINIndex ID = 432 - koIndex ID = 433 - koKPIndex ID = 434 - koKRIndex ID = 435 - kokIndex ID = 436 - kokINIndex ID = 437 - ksIndex ID = 438 - ksINIndex ID = 439 - ksbIndex ID = 440 - ksbTZIndex ID = 441 - ksfIndex ID = 442 - ksfCMIndex ID = 443 - kshIndex ID = 444 - kshDEIndex ID = 445 - kuIndex ID = 446 - kwIndex ID = 447 - kwGBIndex ID = 448 - kyIndex ID = 449 - kyKGIndex ID = 450 - lagIndex ID = 451 - lagTZIndex ID = 452 - lbIndex ID = 453 - lbLUIndex ID = 454 - lgIndex ID = 455 - lgUGIndex ID = 456 - lktIndex ID = 457 - lktUSIndex ID = 458 - lnIndex ID = 459 - lnAOIndex ID = 460 - lnCDIndex ID = 461 - lnCFIndex ID = 462 - lnCGIndex ID = 463 - loIndex ID = 464 - loLAIndex ID = 465 - lrcIndex ID = 466 - lrcIQIndex ID = 467 - lrcIRIndex ID = 468 - ltIndex ID = 469 - ltLTIndex ID = 470 - luIndex ID = 471 - luCDIndex ID = 472 - luoIndex ID = 473 - luoKEIndex ID = 474 - luyIndex ID = 475 - luyKEIndex ID = 476 - lvIndex ID = 477 - lvLVIndex ID = 478 - masIndex ID = 479 - masKEIndex ID = 480 - masTZIndex ID = 481 - merIndex ID = 482 - merKEIndex ID = 483 - mfeIndex ID = 484 - mfeMUIndex ID = 485 - mgIndex ID = 486 - mgMGIndex ID = 487 - mghIndex ID = 488 - mghMZIndex ID = 489 - mgoIndex ID = 490 - mgoCMIndex ID = 491 - mkIndex ID = 492 - mkMKIndex ID = 493 - mlIndex ID = 494 - mlINIndex ID = 495 - mnIndex ID = 496 - mnMNIndex ID = 497 - moIndex ID = 498 - mrIndex ID = 499 - mrINIndex ID = 500 - msIndex ID = 501 - msBNIndex ID = 502 - msMYIndex ID = 503 - msSGIndex ID = 504 - mtIndex ID = 505 - mtMTIndex ID = 506 - muaIndex ID = 507 - muaCMIndex ID = 508 - myIndex ID = 509 - myMMIndex ID = 510 - mznIndex ID = 511 - mznIRIndex ID = 512 - nahIndex ID = 513 - naqIndex ID = 514 - naqNAIndex ID = 515 - nbIndex ID = 516 - nbNOIndex ID = 517 - nbSJIndex ID = 518 - ndIndex ID = 519 - ndZWIndex ID = 520 - ndsIndex ID = 521 - ndsDEIndex ID = 522 - ndsNLIndex ID = 523 - neIndex ID = 524 - neINIndex ID = 525 - neNPIndex ID = 526 - nlIndex ID = 527 - nlAWIndex ID = 528 - nlBEIndex ID = 529 - nlBQIndex ID = 530 - nlCWIndex ID = 531 - nlNLIndex ID = 532 - nlSRIndex ID = 533 - nlSXIndex ID = 534 - nmgIndex ID = 535 - nmgCMIndex ID = 536 - nnIndex ID = 537 - nnNOIndex ID = 538 - nnhIndex ID = 539 - nnhCMIndex ID = 540 - noIndex ID = 541 - nqoIndex ID = 542 - nrIndex ID = 543 - nsoIndex ID = 544 - nusIndex ID = 545 - nusSSIndex ID = 546 - nyIndex ID = 547 - nynIndex ID = 548 - nynUGIndex ID = 549 - omIndex ID = 550 - omETIndex ID = 551 - omKEIndex ID = 552 - orIndex ID = 553 - orINIndex ID = 554 - osIndex ID = 555 - osGEIndex ID = 556 - osRUIndex ID = 557 - paIndex ID = 558 - paArabIndex ID = 559 - paArabPKIndex ID = 560 - paGuruIndex ID = 561 - paGuruINIndex ID = 562 - papIndex ID = 563 - plIndex ID = 564 - plPLIndex ID = 565 - prgIndex ID = 566 - prg001Index ID = 567 - psIndex ID = 568 - psAFIndex ID = 569 - ptIndex ID = 570 - ptAOIndex ID = 571 - ptBRIndex ID = 572 - ptCHIndex ID = 573 - ptCVIndex ID = 574 - ptGQIndex ID = 575 - ptGWIndex ID = 576 - ptLUIndex ID = 577 - ptMOIndex ID = 578 - ptMZIndex ID = 579 - ptPTIndex ID = 580 - ptSTIndex ID = 581 - ptTLIndex ID = 582 - quIndex ID = 583 - quBOIndex ID = 584 - quECIndex ID = 585 - quPEIndex ID = 586 - rmIndex ID = 587 - rmCHIndex ID = 588 - rnIndex ID = 589 - rnBIIndex ID = 590 - roIndex ID = 591 - roMDIndex ID = 592 - roROIndex ID = 593 - rofIndex ID = 594 - rofTZIndex ID = 595 - ruIndex ID = 596 - ruBYIndex ID = 597 - ruKGIndex ID = 598 - ruKZIndex ID = 599 - ruMDIndex ID = 600 - ruRUIndex ID = 601 - ruUAIndex ID = 602 - rwIndex ID = 603 - rwRWIndex ID = 604 - rwkIndex ID = 605 - rwkTZIndex ID = 606 - sahIndex ID = 607 - sahRUIndex ID = 608 - saqIndex ID = 609 - saqKEIndex ID = 610 - sbpIndex ID = 611 - sbpTZIndex ID = 612 - sdIndex ID = 613 - sdPKIndex ID = 614 - sdhIndex ID = 615 - seIndex ID = 616 - seFIIndex ID = 617 - seNOIndex ID = 618 - seSEIndex ID = 619 - sehIndex ID = 620 - sehMZIndex ID = 621 - sesIndex ID = 622 - sesMLIndex ID = 623 - sgIndex ID = 624 - sgCFIndex ID = 625 - shIndex ID = 626 - shiIndex ID = 627 - shiLatnIndex ID = 628 - shiLatnMAIndex ID = 629 - shiTfngIndex ID = 630 - shiTfngMAIndex ID = 631 - siIndex ID = 632 - siLKIndex ID = 633 - skIndex ID = 634 - skSKIndex ID = 635 - slIndex ID = 636 - slSIIndex ID = 637 - smaIndex ID = 638 - smiIndex ID = 639 - smjIndex ID = 640 - smnIndex ID = 641 - smnFIIndex ID = 642 - smsIndex ID = 643 - snIndex ID = 644 - snZWIndex ID = 645 - soIndex ID = 646 - soDJIndex ID = 647 - soETIndex ID = 648 - soKEIndex ID = 649 - soSOIndex ID = 650 - sqIndex ID = 651 - sqALIndex ID = 652 - sqMKIndex ID = 653 - sqXKIndex ID = 654 - srIndex ID = 655 - srCyrlIndex ID = 656 - srCyrlBAIndex ID = 657 - srCyrlMEIndex ID = 658 - srCyrlRSIndex ID = 659 - srCyrlXKIndex ID = 660 - srLatnIndex ID = 661 - srLatnBAIndex ID = 662 - srLatnMEIndex ID = 663 - srLatnRSIndex ID = 664 - srLatnXKIndex ID = 665 - ssIndex ID = 666 - ssyIndex ID = 667 - stIndex ID = 668 - svIndex ID = 669 - svAXIndex ID = 670 - svFIIndex ID = 671 - svSEIndex ID = 672 - swIndex ID = 673 - swCDIndex ID = 674 - swKEIndex ID = 675 - swTZIndex ID = 676 - swUGIndex ID = 677 - syrIndex ID = 678 - taIndex ID = 679 - taINIndex ID = 680 - taLKIndex ID = 681 - taMYIndex ID = 682 - taSGIndex ID = 683 - teIndex ID = 684 - teINIndex ID = 685 - teoIndex ID = 686 - teoKEIndex ID = 687 - teoUGIndex ID = 688 - tgIndex ID = 689 - tgTJIndex ID = 690 - thIndex ID = 691 - thTHIndex ID = 692 - tiIndex ID = 693 - tiERIndex ID = 694 - tiETIndex ID = 695 - tigIndex ID = 696 - tkIndex ID = 697 - tkTMIndex ID = 698 - tlIndex ID = 699 - tnIndex ID = 700 - toIndex ID = 701 - toTOIndex ID = 702 - trIndex ID = 703 - trCYIndex ID = 704 - trTRIndex ID = 705 - tsIndex ID = 706 - ttIndex ID = 707 - ttRUIndex ID = 708 - twqIndex ID = 709 - twqNEIndex ID = 710 - tzmIndex ID = 711 - tzmMAIndex ID = 712 - ugIndex ID = 713 - ugCNIndex ID = 714 - ukIndex ID = 715 - ukUAIndex ID = 716 - urIndex ID = 717 - urINIndex ID = 718 - urPKIndex ID = 719 - uzIndex ID = 720 - uzArabIndex ID = 721 - uzArabAFIndex ID = 722 - uzCyrlIndex ID = 723 - uzCyrlUZIndex ID = 724 - uzLatnIndex ID = 725 - uzLatnUZIndex ID = 726 - vaiIndex ID = 727 - vaiLatnIndex ID = 728 - vaiLatnLRIndex ID = 729 - vaiVaiiIndex ID = 730 - vaiVaiiLRIndex ID = 731 - veIndex ID = 732 - viIndex ID = 733 - viVNIndex ID = 734 - voIndex ID = 735 - vo001Index ID = 736 - vunIndex ID = 737 - vunTZIndex ID = 738 - waIndex ID = 739 - waeIndex ID = 740 - waeCHIndex ID = 741 - woIndex ID = 742 - woSNIndex ID = 743 - xhIndex ID = 744 - xogIndex ID = 745 - xogUGIndex ID = 746 - yavIndex ID = 747 - yavCMIndex ID = 748 - yiIndex ID = 749 - yi001Index ID = 750 - yoIndex ID = 751 - yoBJIndex ID = 752 - yoNGIndex ID = 753 - yueIndex ID = 754 - yueHansIndex ID = 755 - yueHansCNIndex ID = 756 - yueHantIndex ID = 757 - yueHantHKIndex ID = 758 - zghIndex ID = 759 - zghMAIndex ID = 760 - zhIndex ID = 761 - zhHansIndex ID = 762 - zhHansCNIndex ID = 763 - zhHansHKIndex ID = 764 - zhHansMOIndex ID = 765 - zhHansSGIndex ID = 766 - zhHantIndex ID = 767 - zhHantHKIndex ID = 768 - zhHantMOIndex ID = 769 - zhHantTWIndex ID = 770 - zuIndex ID = 771 - zuZAIndex ID = 772 - caESvalenciaIndex ID = 773 - enUSuvaposixIndex ID = 774 -) - -var coreTags = []language.CompactCoreInfo{ // 773 elements - // Entry 0 - 1F - 0x00000000, 0x01600000, 0x016000d3, 0x01600162, - 0x01c00000, 0x01c00052, 0x02100000, 0x02100081, - 0x02700000, 0x02700070, 0x03a00000, 0x03a00001, - 0x03a00023, 0x03a00039, 0x03a00063, 0x03a00068, - 0x03a0006c, 0x03a0006d, 0x03a0006e, 0x03a00098, - 0x03a0009c, 0x03a000a2, 0x03a000a9, 0x03a000ad, - 0x03a000b1, 0x03a000ba, 0x03a000bb, 0x03a000ca, - 0x03a000e2, 0x03a000ee, 0x03a000f4, 0x03a00109, - // Entry 20 - 3F - 0x03a0010c, 0x03a00116, 0x03a00118, 0x03a0011d, - 0x03a00121, 0x03a00129, 0x03a0015f, 0x04000000, - 0x04300000, 0x0430009a, 0x04400000, 0x04400130, - 0x04800000, 0x0480006f, 0x05800000, 0x05820000, - 0x05820032, 0x0585b000, 0x0585b032, 0x05e00000, - 0x05e00052, 0x07100000, 0x07100047, 0x07500000, - 0x07500163, 0x07900000, 0x07900130, 0x07e00000, - 0x07e00038, 0x08200000, 0x0a000000, 0x0a0000c4, - // Entry 40 - 5F - 0x0a500000, 0x0a500035, 0x0a50009a, 0x0a900000, - 0x0a900053, 0x0a90009a, 0x0b200000, 0x0b200079, - 0x0b500000, 0x0b50009a, 0x0b700000, 0x0b720000, - 0x0b720033, 0x0b75b000, 0x0b75b033, 0x0d700000, - 0x0d700022, 0x0d70006f, 0x0d700079, 0x0d70009f, - 0x0db00000, 0x0db00035, 0x0db0009a, 0x0dc00000, - 0x0dc00107, 0x0df00000, 0x0df00132, 0x0e500000, - 0x0e500136, 0x0e900000, 0x0e90009c, 0x0e90009d, - // Entry 60 - 7F - 0x0fa00000, 0x0fa0005f, 0x0fe00000, 0x0fe00107, - 0x10000000, 0x1000007c, 0x10100000, 0x10100064, - 0x10100083, 0x10800000, 0x108000a5, 0x10d00000, - 0x10d0002e, 0x10d00036, 0x10d0004e, 0x10d00061, - 0x10d0009f, 0x10d000b3, 0x10d000b8, 0x11700000, - 0x117000d5, 0x11f00000, 0x11f00061, 0x12400000, - 0x12400052, 0x12800000, 0x12b00000, 0x12b00115, - 0x12d00000, 0x12d00043, 0x12f00000, 0x12f000a5, - // Entry 80 - 9F - 0x13000000, 0x13000081, 0x13000123, 0x13600000, - 0x1360005e, 0x13600088, 0x13900000, 0x13900001, - 0x1390001a, 0x13900025, 0x13900026, 0x1390002d, - 0x1390002e, 0x1390002f, 0x13900034, 0x13900036, - 0x1390003a, 0x1390003d, 0x13900042, 0x13900046, - 0x13900048, 0x13900049, 0x1390004a, 0x1390004e, - 0x13900050, 0x13900052, 0x1390005d, 0x1390005e, - 0x13900061, 0x13900062, 0x13900064, 0x13900065, - // Entry A0 - BF - 0x1390006e, 0x13900073, 0x13900074, 0x13900075, - 0x13900076, 0x1390007c, 0x1390007d, 0x13900080, - 0x13900081, 0x13900082, 0x13900084, 0x1390008b, - 0x1390008d, 0x1390008e, 0x13900097, 0x13900098, - 0x13900099, 0x1390009a, 0x1390009b, 0x139000a0, - 0x139000a1, 0x139000a5, 0x139000a8, 0x139000aa, - 0x139000ae, 0x139000b2, 0x139000b5, 0x139000b6, - 0x139000c0, 0x139000c1, 0x139000c7, 0x139000c8, - // Entry C0 - DF - 0x139000cb, 0x139000cc, 0x139000cd, 0x139000cf, - 0x139000d1, 0x139000d3, 0x139000d6, 0x139000d7, - 0x139000da, 0x139000de, 0x139000e0, 0x139000e1, - 0x139000e7, 0x139000e8, 0x139000e9, 0x139000ec, - 0x139000ed, 0x139000f1, 0x13900108, 0x1390010a, - 0x1390010b, 0x1390010c, 0x1390010d, 0x1390010e, - 0x1390010f, 0x13900110, 0x13900113, 0x13900118, - 0x1390011c, 0x1390011e, 0x13900120, 0x13900126, - // Entry E0 - FF - 0x1390012a, 0x1390012d, 0x1390012e, 0x13900130, - 0x13900132, 0x13900134, 0x13900136, 0x1390013a, - 0x1390013d, 0x1390013e, 0x13900140, 0x13900143, - 0x13900162, 0x13900163, 0x13900165, 0x13c00000, - 0x13c00001, 0x13e00000, 0x13e0001f, 0x13e0002c, - 0x13e0003f, 0x13e00041, 0x13e00048, 0x13e00051, - 0x13e00054, 0x13e00057, 0x13e0005a, 0x13e00066, - 0x13e00069, 0x13e0006a, 0x13e0006f, 0x13e00087, - // Entry 100 - 11F - 0x13e0008a, 0x13e00090, 0x13e00095, 0x13e000d0, - 0x13e000d9, 0x13e000e3, 0x13e000e5, 0x13e000e8, - 0x13e000ed, 0x13e000f2, 0x13e0011b, 0x13e00136, - 0x13e00137, 0x13e0013c, 0x14000000, 0x1400006b, - 0x14500000, 0x1450006f, 0x14600000, 0x14600052, - 0x14800000, 0x14800024, 0x1480009d, 0x14e00000, - 0x14e00052, 0x14e00085, 0x14e000ca, 0x14e00115, - 0x15100000, 0x15100073, 0x15300000, 0x153000e8, - // Entry 120 - 13F - 0x15800000, 0x15800064, 0x15800077, 0x15e00000, - 0x15e00036, 0x15e00037, 0x15e0003a, 0x15e0003b, - 0x15e0003c, 0x15e00049, 0x15e0004b, 0x15e0004c, - 0x15e0004d, 0x15e0004e, 0x15e0004f, 0x15e00052, - 0x15e00063, 0x15e00068, 0x15e00079, 0x15e0007b, - 0x15e0007f, 0x15e00085, 0x15e00086, 0x15e00087, - 0x15e00092, 0x15e000a9, 0x15e000b8, 0x15e000bb, - 0x15e000bc, 0x15e000bf, 0x15e000c0, 0x15e000c4, - // Entry 140 - 15F - 0x15e000c9, 0x15e000ca, 0x15e000cd, 0x15e000d4, - 0x15e000d5, 0x15e000e6, 0x15e000eb, 0x15e00103, - 0x15e00108, 0x15e0010b, 0x15e00115, 0x15e0011d, - 0x15e00121, 0x15e00123, 0x15e00129, 0x15e00140, - 0x15e00141, 0x15e00160, 0x16900000, 0x1690009f, - 0x16d00000, 0x16d000da, 0x16e00000, 0x16e00097, - 0x17e00000, 0x17e0007c, 0x19000000, 0x1900006f, - 0x1a300000, 0x1a30004e, 0x1a300079, 0x1a3000b3, - // Entry 160 - 17F - 0x1a400000, 0x1a40009a, 0x1a900000, 0x1ab00000, - 0x1ab000a5, 0x1ac00000, 0x1ac00099, 0x1b400000, - 0x1b400081, 0x1b4000d5, 0x1b4000d7, 0x1b800000, - 0x1b800136, 0x1bc00000, 0x1bc00098, 0x1be00000, - 0x1be0009a, 0x1d100000, 0x1d100033, 0x1d100091, - 0x1d200000, 0x1d200061, 0x1d500000, 0x1d500093, - 0x1d700000, 0x1d700028, 0x1e100000, 0x1e100096, - 0x1e700000, 0x1e7000d7, 0x1ea00000, 0x1ea00053, - // Entry 180 - 19F - 0x1f300000, 0x1f500000, 0x1f800000, 0x1f80009e, - 0x1f900000, 0x1f90004e, 0x1f90009f, 0x1f900114, - 0x1f900139, 0x1fa00000, 0x1fb00000, 0x20000000, - 0x200000a3, 0x20300000, 0x20700000, 0x20700052, - 0x20800000, 0x20a00000, 0x20a00130, 0x20e00000, - 0x20f00000, 0x21000000, 0x2100007e, 0x21200000, - 0x21200068, 0x21600000, 0x21700000, 0x217000a5, - 0x21f00000, 0x22300000, 0x22300130, 0x22700000, - // Entry 1A0 - 1BF - 0x2270005b, 0x23400000, 0x234000c4, 0x23900000, - 0x239000a5, 0x24200000, 0x242000af, 0x24400000, - 0x24400052, 0x24500000, 0x24500083, 0x24600000, - 0x246000a5, 0x24a00000, 0x24a000a7, 0x25100000, - 0x2510009a, 0x25400000, 0x254000ab, 0x254000ac, - 0x25600000, 0x2560009a, 0x26a00000, 0x26a0009a, - 0x26b00000, 0x26b00130, 0x26d00000, 0x26d00052, - 0x26e00000, 0x26e00061, 0x27400000, 0x28100000, - // Entry 1C0 - 1DF - 0x2810007c, 0x28a00000, 0x28a000a6, 0x29100000, - 0x29100130, 0x29500000, 0x295000b8, 0x2a300000, - 0x2a300132, 0x2af00000, 0x2af00136, 0x2b500000, - 0x2b50002a, 0x2b50004b, 0x2b50004c, 0x2b50004d, - 0x2b800000, 0x2b8000b0, 0x2bf00000, 0x2bf0009c, - 0x2bf0009d, 0x2c000000, 0x2c0000b7, 0x2c200000, - 0x2c20004b, 0x2c400000, 0x2c4000a5, 0x2c500000, - 0x2c5000a5, 0x2c700000, 0x2c7000b9, 0x2d100000, - // Entry 1E0 - 1FF - 0x2d1000a5, 0x2d100130, 0x2e900000, 0x2e9000a5, - 0x2ed00000, 0x2ed000cd, 0x2f100000, 0x2f1000c0, - 0x2f200000, 0x2f2000d2, 0x2f400000, 0x2f400052, - 0x2ff00000, 0x2ff000c3, 0x30400000, 0x3040009a, - 0x30b00000, 0x30b000c6, 0x31000000, 0x31b00000, - 0x31b0009a, 0x31f00000, 0x31f0003e, 0x31f000d1, - 0x31f0010e, 0x32000000, 0x320000cc, 0x32500000, - 0x32500052, 0x33100000, 0x331000c5, 0x33a00000, - // Entry 200 - 21F - 0x33a0009d, 0x34100000, 0x34500000, 0x345000d3, - 0x34700000, 0x347000db, 0x34700111, 0x34e00000, - 0x34e00165, 0x35000000, 0x35000061, 0x350000da, - 0x35100000, 0x3510009a, 0x351000dc, 0x36700000, - 0x36700030, 0x36700036, 0x36700040, 0x3670005c, - 0x367000da, 0x36700117, 0x3670011c, 0x36800000, - 0x36800052, 0x36a00000, 0x36a000db, 0x36c00000, - 0x36c00052, 0x36f00000, 0x37500000, 0x37600000, - // Entry 220 - 23F - 0x37a00000, 0x38000000, 0x38000118, 0x38700000, - 0x38900000, 0x38900132, 0x39000000, 0x39000070, - 0x390000a5, 0x39500000, 0x3950009a, 0x39800000, - 0x3980007e, 0x39800107, 0x39d00000, 0x39d05000, - 0x39d050e9, 0x39d36000, 0x39d3609a, 0x3a100000, - 0x3b300000, 0x3b3000ea, 0x3bd00000, 0x3bd00001, - 0x3be00000, 0x3be00024, 0x3c000000, 0x3c00002a, - 0x3c000041, 0x3c00004e, 0x3c00005b, 0x3c000087, - // Entry 240 - 25F - 0x3c00008c, 0x3c0000b8, 0x3c0000c7, 0x3c0000d2, - 0x3c0000ef, 0x3c000119, 0x3c000127, 0x3c400000, - 0x3c40003f, 0x3c40006a, 0x3c4000e5, 0x3d400000, - 0x3d40004e, 0x3d900000, 0x3d90003a, 0x3dc00000, - 0x3dc000bd, 0x3dc00105, 0x3de00000, 0x3de00130, - 0x3e200000, 0x3e200047, 0x3e2000a6, 0x3e2000af, - 0x3e2000bd, 0x3e200107, 0x3e200131, 0x3e500000, - 0x3e500108, 0x3e600000, 0x3e600130, 0x3eb00000, - // Entry 260 - 27F - 0x3eb00107, 0x3ec00000, 0x3ec000a5, 0x3f300000, - 0x3f300130, 0x3fa00000, 0x3fa000e9, 0x3fc00000, - 0x3fd00000, 0x3fd00073, 0x3fd000db, 0x3fd0010d, - 0x3ff00000, 0x3ff000d2, 0x40100000, 0x401000c4, - 0x40200000, 0x4020004c, 0x40700000, 0x40800000, - 0x4085b000, 0x4085b0bb, 0x408eb000, 0x408eb0bb, - 0x40c00000, 0x40c000b4, 0x41200000, 0x41200112, - 0x41600000, 0x41600110, 0x41c00000, 0x41d00000, - // Entry 280 - 29F - 0x41e00000, 0x41f00000, 0x41f00073, 0x42200000, - 0x42300000, 0x42300165, 0x42900000, 0x42900063, - 0x42900070, 0x429000a5, 0x42900116, 0x43100000, - 0x43100027, 0x431000c3, 0x4310014e, 0x43200000, - 0x43220000, 0x43220033, 0x432200be, 0x43220106, - 0x4322014e, 0x4325b000, 0x4325b033, 0x4325b0be, - 0x4325b106, 0x4325b14e, 0x43700000, 0x43a00000, - 0x43b00000, 0x44400000, 0x44400031, 0x44400073, - // Entry 2A0 - 2BF - 0x4440010d, 0x44500000, 0x4450004b, 0x445000a5, - 0x44500130, 0x44500132, 0x44e00000, 0x45000000, - 0x4500009a, 0x450000b4, 0x450000d1, 0x4500010e, - 0x46100000, 0x4610009a, 0x46400000, 0x464000a5, - 0x46400132, 0x46700000, 0x46700125, 0x46b00000, - 0x46b00124, 0x46f00000, 0x46f0006e, 0x46f00070, - 0x47100000, 0x47600000, 0x47600128, 0x47a00000, - 0x48000000, 0x48200000, 0x4820012a, 0x48a00000, - // Entry 2C0 - 2DF - 0x48a0005e, 0x48a0012c, 0x48e00000, 0x49400000, - 0x49400107, 0x4a400000, 0x4a4000d5, 0x4a900000, - 0x4a9000bb, 0x4ac00000, 0x4ac00053, 0x4ae00000, - 0x4ae00131, 0x4b400000, 0x4b40009a, 0x4b4000e9, - 0x4bc00000, 0x4bc05000, 0x4bc05024, 0x4bc20000, - 0x4bc20138, 0x4bc5b000, 0x4bc5b138, 0x4be00000, - 0x4be5b000, 0x4be5b0b5, 0x4bef4000, 0x4bef40b5, - 0x4c000000, 0x4c300000, 0x4c30013f, 0x4c900000, - // Entry 2E0 - 2FF - 0x4c900001, 0x4cc00000, 0x4cc00130, 0x4ce00000, - 0x4cf00000, 0x4cf0004e, 0x4e500000, 0x4e500115, - 0x4f200000, 0x4fb00000, 0x4fb00132, 0x50900000, - 0x50900052, 0x51200000, 0x51200001, 0x51800000, - 0x5180003b, 0x518000d7, 0x51f00000, 0x51f3b000, - 0x51f3b053, 0x51f3c000, 0x51f3c08e, 0x52800000, - 0x528000bb, 0x52900000, 0x5293b000, 0x5293b053, - 0x5293b08e, 0x5293b0c7, 0x5293b10e, 0x5293c000, - // Entry 300 - 31F - 0x5293c08e, 0x5293c0c7, 0x5293c12f, 0x52f00000, - 0x52f00162, -} // Size: 3116 bytes - -const specialTagsStr string = "ca-ES-valencia en-US-u-va-posix" - -// Total table size 3147 bytes (3KiB); checksum: 5A8FFFA5 diff --git a/vendor/golang.org/x/text/internal/language/compact/tags.go b/vendor/golang.org/x/text/internal/language/compact/tags.go deleted file mode 100644 index ca135d295..000000000 --- a/vendor/golang.org/x/text/internal/language/compact/tags.go +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright 2013 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 compact - -var ( - und = Tag{} - - Und Tag = Tag{} - - Afrikaans Tag = Tag{language: afIndex, locale: afIndex} - Amharic Tag = Tag{language: amIndex, locale: amIndex} - Arabic Tag = Tag{language: arIndex, locale: arIndex} - ModernStandardArabic Tag = Tag{language: ar001Index, locale: ar001Index} - Azerbaijani Tag = Tag{language: azIndex, locale: azIndex} - Bulgarian Tag = Tag{language: bgIndex, locale: bgIndex} - Bengali Tag = Tag{language: bnIndex, locale: bnIndex} - Catalan Tag = Tag{language: caIndex, locale: caIndex} - Czech Tag = Tag{language: csIndex, locale: csIndex} - Danish Tag = Tag{language: daIndex, locale: daIndex} - German Tag = Tag{language: deIndex, locale: deIndex} - Greek Tag = Tag{language: elIndex, locale: elIndex} - English Tag = Tag{language: enIndex, locale: enIndex} - AmericanEnglish Tag = Tag{language: enUSIndex, locale: enUSIndex} - BritishEnglish Tag = Tag{language: enGBIndex, locale: enGBIndex} - Spanish Tag = Tag{language: esIndex, locale: esIndex} - EuropeanSpanish Tag = Tag{language: esESIndex, locale: esESIndex} - LatinAmericanSpanish Tag = Tag{language: es419Index, locale: es419Index} - Estonian Tag = Tag{language: etIndex, locale: etIndex} - Persian Tag = Tag{language: faIndex, locale: faIndex} - Finnish Tag = Tag{language: fiIndex, locale: fiIndex} - Filipino Tag = Tag{language: filIndex, locale: filIndex} - French Tag = Tag{language: frIndex, locale: frIndex} - CanadianFrench Tag = Tag{language: frCAIndex, locale: frCAIndex} - Gujarati Tag = Tag{language: guIndex, locale: guIndex} - Hebrew Tag = Tag{language: heIndex, locale: heIndex} - Hindi Tag = Tag{language: hiIndex, locale: hiIndex} - Croatian Tag = Tag{language: hrIndex, locale: hrIndex} - Hungarian Tag = Tag{language: huIndex, locale: huIndex} - Armenian Tag = Tag{language: hyIndex, locale: hyIndex} - Indonesian Tag = Tag{language: idIndex, locale: idIndex} - Icelandic Tag = Tag{language: isIndex, locale: isIndex} - Italian Tag = Tag{language: itIndex, locale: itIndex} - Japanese Tag = Tag{language: jaIndex, locale: jaIndex} - Georgian Tag = Tag{language: kaIndex, locale: kaIndex} - Kazakh Tag = Tag{language: kkIndex, locale: kkIndex} - Khmer Tag = Tag{language: kmIndex, locale: kmIndex} - Kannada Tag = Tag{language: knIndex, locale: knIndex} - Korean Tag = Tag{language: koIndex, locale: koIndex} - Kirghiz Tag = Tag{language: kyIndex, locale: kyIndex} - Lao Tag = Tag{language: loIndex, locale: loIndex} - Lithuanian Tag = Tag{language: ltIndex, locale: ltIndex} - Latvian Tag = Tag{language: lvIndex, locale: lvIndex} - Macedonian Tag = Tag{language: mkIndex, locale: mkIndex} - Malayalam Tag = Tag{language: mlIndex, locale: mlIndex} - Mongolian Tag = Tag{language: mnIndex, locale: mnIndex} - Marathi Tag = Tag{language: mrIndex, locale: mrIndex} - Malay Tag = Tag{language: msIndex, locale: msIndex} - Burmese Tag = Tag{language: myIndex, locale: myIndex} - Nepali Tag = Tag{language: neIndex, locale: neIndex} - Dutch Tag = Tag{language: nlIndex, locale: nlIndex} - Norwegian Tag = Tag{language: noIndex, locale: noIndex} - Punjabi Tag = Tag{language: paIndex, locale: paIndex} - Polish Tag = Tag{language: plIndex, locale: plIndex} - Portuguese Tag = Tag{language: ptIndex, locale: ptIndex} - BrazilianPortuguese Tag = Tag{language: ptBRIndex, locale: ptBRIndex} - EuropeanPortuguese Tag = Tag{language: ptPTIndex, locale: ptPTIndex} - Romanian Tag = Tag{language: roIndex, locale: roIndex} - Russian Tag = Tag{language: ruIndex, locale: ruIndex} - Sinhala Tag = Tag{language: siIndex, locale: siIndex} - Slovak Tag = Tag{language: skIndex, locale: skIndex} - Slovenian Tag = Tag{language: slIndex, locale: slIndex} - Albanian Tag = Tag{language: sqIndex, locale: sqIndex} - Serbian Tag = Tag{language: srIndex, locale: srIndex} - SerbianLatin Tag = Tag{language: srLatnIndex, locale: srLatnIndex} - Swedish Tag = Tag{language: svIndex, locale: svIndex} - Swahili Tag = Tag{language: swIndex, locale: swIndex} - Tamil Tag = Tag{language: taIndex, locale: taIndex} - Telugu Tag = Tag{language: teIndex, locale: teIndex} - Thai Tag = Tag{language: thIndex, locale: thIndex} - Turkish Tag = Tag{language: trIndex, locale: trIndex} - Ukrainian Tag = Tag{language: ukIndex, locale: ukIndex} - Urdu Tag = Tag{language: urIndex, locale: urIndex} - Uzbek Tag = Tag{language: uzIndex, locale: uzIndex} - Vietnamese Tag = Tag{language: viIndex, locale: viIndex} - Chinese Tag = Tag{language: zhIndex, locale: zhIndex} - SimplifiedChinese Tag = Tag{language: zhHansIndex, locale: zhHansIndex} - TraditionalChinese Tag = Tag{language: zhHantIndex, locale: zhHantIndex} - Zulu Tag = Tag{language: zuIndex, locale: zuIndex} -) diff --git a/vendor/golang.org/x/text/internal/language/compose.go b/vendor/golang.org/x/text/internal/language/compose.go deleted file mode 100644 index 4ae78e0fa..000000000 --- a/vendor/golang.org/x/text/internal/language/compose.go +++ /dev/null @@ -1,167 +0,0 @@ -// Copyright 2018 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 language - -import ( - "sort" - "strings" -) - -// A Builder allows constructing a Tag from individual components. -// Its main user is Compose in the top-level language package. -type Builder struct { - Tag Tag - - private string // the x extension - variants []string - extensions []string -} - -// Make returns a new Tag from the current settings. -func (b *Builder) Make() Tag { - t := b.Tag - - if len(b.extensions) > 0 || len(b.variants) > 0 { - sort.Sort(sortVariants(b.variants)) - sort.Strings(b.extensions) - - if b.private != "" { - b.extensions = append(b.extensions, b.private) - } - n := maxCoreSize + tokenLen(b.variants...) + tokenLen(b.extensions...) - buf := make([]byte, n) - p := t.genCoreBytes(buf) - t.pVariant = byte(p) - p += appendTokens(buf[p:], b.variants...) - t.pExt = uint16(p) - p += appendTokens(buf[p:], b.extensions...) - t.str = string(buf[:p]) - // We may not always need to remake the string, but when or when not - // to do so is rather tricky. - scan := makeScanner(buf[:p]) - t, _ = parse(&scan, "") - return t - - } else if b.private != "" { - t.str = b.private - t.RemakeString() - } - return t -} - -// SetTag copies all the settings from a given Tag. Any previously set values -// are discarded. -func (b *Builder) SetTag(t Tag) { - b.Tag.LangID = t.LangID - b.Tag.RegionID = t.RegionID - b.Tag.ScriptID = t.ScriptID - // TODO: optimize - b.variants = b.variants[:0] - if variants := t.Variants(); variants != "" { - for _, vr := range strings.Split(variants[1:], "-") { - b.variants = append(b.variants, vr) - } - } - b.extensions, b.private = b.extensions[:0], "" - for _, e := range t.Extensions() { - b.AddExt(e) - } -} - -// AddExt adds extension e to the tag. e must be a valid extension as returned -// by Tag.Extension. If the extension already exists, it will be discarded, -// except for a -u extension, where non-existing key-type pairs will added. -func (b *Builder) AddExt(e string) { - if e[0] == 'x' { - if b.private == "" { - b.private = e - } - return - } - for i, s := range b.extensions { - if s[0] == e[0] { - if e[0] == 'u' { - b.extensions[i] += e[1:] - } - return - } - } - b.extensions = append(b.extensions, e) -} - -// SetExt sets the extension e to the tag. e must be a valid extension as -// returned by Tag.Extension. If the extension already exists, it will be -// overwritten, except for a -u extension, where the individual key-type pairs -// will be set. -func (b *Builder) SetExt(e string) { - if e[0] == 'x' { - b.private = e - return - } - for i, s := range b.extensions { - if s[0] == e[0] { - if e[0] == 'u' { - b.extensions[i] = e + s[1:] - } else { - b.extensions[i] = e - } - return - } - } - b.extensions = append(b.extensions, e) -} - -// AddVariant adds any number of variants. -func (b *Builder) AddVariant(v ...string) { - for _, v := range v { - if v != "" { - b.variants = append(b.variants, v) - } - } -} - -// ClearVariants removes any variants previously added, including those -// copied from a Tag in SetTag. -func (b *Builder) ClearVariants() { - b.variants = b.variants[:0] -} - -// ClearExtensions removes any extensions previously added, including those -// copied from a Tag in SetTag. -func (b *Builder) ClearExtensions() { - b.private = "" - b.extensions = b.extensions[:0] -} - -func tokenLen(token ...string) (n int) { - for _, t := range token { - n += len(t) + 1 - } - return -} - -func appendTokens(b []byte, token ...string) int { - p := 0 - for _, t := range token { - b[p] = '-' - copy(b[p+1:], t) - p += 1 + len(t) - } - return p -} - -type sortVariants []string - -func (s sortVariants) Len() int { - return len(s) -} - -func (s sortVariants) Swap(i, j int) { - s[j], s[i] = s[i], s[j] -} - -func (s sortVariants) Less(i, j int) bool { - return variantIndex[s[i]] < variantIndex[s[j]] -} diff --git a/vendor/golang.org/x/text/internal/language/coverage.go b/vendor/golang.org/x/text/internal/language/coverage.go deleted file mode 100644 index 9b20b88fe..000000000 --- a/vendor/golang.org/x/text/internal/language/coverage.go +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2014 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 language - -// BaseLanguages returns the list of all supported base languages. It generates -// the list by traversing the internal structures. -func BaseLanguages() []Language { - base := make([]Language, 0, NumLanguages) - for i := 0; i < langNoIndexOffset; i++ { - // We included "und" already for the value 0. - if i != nonCanonicalUnd { - base = append(base, Language(i)) - } - } - i := langNoIndexOffset - for _, v := range langNoIndex { - for k := 0; k < 8; k++ { - if v&1 == 1 { - base = append(base, Language(i)) - } - v >>= 1 - i++ - } - } - return base -} diff --git a/vendor/golang.org/x/text/internal/language/language.go b/vendor/golang.org/x/text/internal/language/language.go deleted file mode 100644 index 09d41c736..000000000 --- a/vendor/golang.org/x/text/internal/language/language.go +++ /dev/null @@ -1,627 +0,0 @@ -// Copyright 2013 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 -output tables.go - -package language // import "golang.org/x/text/internal/language" - -// TODO: Remove above NOTE after: -// - verifying that tables are dropped correctly (most notably matcher tables). - -import ( - "errors" - "fmt" - "strings" -) - -const ( - // maxCoreSize is the maximum size of a BCP 47 tag without variants and - // extensions. Equals max lang (3) + script (4) + max reg (3) + 2 dashes. - maxCoreSize = 12 - - // max99thPercentileSize is a somewhat arbitrary buffer size that presumably - // is large enough to hold at least 99% of the BCP 47 tags. - max99thPercentileSize = 32 - - // maxSimpleUExtensionSize is the maximum size of a -u extension with one - // key-type pair. Equals len("-u-") + key (2) + dash + max value (8). - maxSimpleUExtensionSize = 14 -) - -// Tag represents a BCP 47 language tag. It is used to specify an instance of a -// specific language or locale. All language tag values are guaranteed to be -// well-formed. The zero value of Tag is Und. -type Tag struct { - // TODO: the following fields have the form TagTypeID. This name is chosen - // to allow refactoring the public package without conflicting with its - // Base, Script, and Region methods. Once the transition is fully completed - // the ID can be stripped from the name. - - LangID Language - RegionID Region - // TODO: we will soon run out of positions for ScriptID. Idea: instead of - // storing lang, region, and ScriptID codes, store only the compact index and - // have a lookup table from this code to its expansion. This greatly speeds - // up table lookup, speed up common variant cases. - // This will also immediately free up 3 extra bytes. Also, the pVariant - // field can now be moved to the lookup table, as the compact index uniquely - // determines the offset of a possible variant. - ScriptID Script - pVariant byte // offset in str, includes preceding '-' - pExt uint16 // offset of first extension, includes preceding '-' - - // str is the string representation of the Tag. It will only be used if the - // tag has variants or extensions. - str string -} - -// Make is a convenience wrapper for Parse that omits the error. -// In case of an error, a sensible default is returned. -func Make(s string) Tag { - t, _ := Parse(s) - return t -} - -// Raw returns the raw base language, script and region, without making an -// attempt to infer their values. -// TODO: consider removing -func (t Tag) Raw() (b Language, s Script, r Region) { - return t.LangID, t.ScriptID, t.RegionID -} - -// equalTags compares language, script and region subtags only. -func (t Tag) equalTags(a Tag) bool { - return t.LangID == a.LangID && t.ScriptID == a.ScriptID && t.RegionID == a.RegionID -} - -// IsRoot returns true if t is equal to language "und". -func (t Tag) IsRoot() bool { - if int(t.pVariant) < len(t.str) { - return false - } - return t.equalTags(Und) -} - -// IsPrivateUse reports whether the Tag consists solely of an IsPrivateUse use -// tag. -func (t Tag) IsPrivateUse() bool { - return t.str != "" && t.pVariant == 0 -} - -// RemakeString is used to update t.str in case lang, script or region changed. -// It is assumed that pExt and pVariant still point to the start of the -// respective parts. -func (t *Tag) RemakeString() { - if t.str == "" { - return - } - extra := t.str[t.pVariant:] - if t.pVariant > 0 { - extra = extra[1:] - } - if t.equalTags(Und) && strings.HasPrefix(extra, "x-") { - t.str = extra - t.pVariant = 0 - t.pExt = 0 - return - } - var buf [max99thPercentileSize]byte // avoid extra memory allocation in most cases. - b := buf[:t.genCoreBytes(buf[:])] - if extra != "" { - diff := len(b) - int(t.pVariant) - b = append(b, '-') - b = append(b, extra...) - t.pVariant = uint8(int(t.pVariant) + diff) - t.pExt = uint16(int(t.pExt) + diff) - } else { - t.pVariant = uint8(len(b)) - t.pExt = uint16(len(b)) - } - t.str = string(b) -} - -// genCoreBytes writes a string for the base languages, script and region tags -// to the given buffer and returns the number of bytes written. It will never -// write more than maxCoreSize bytes. -func (t *Tag) genCoreBytes(buf []byte) int { - n := t.LangID.StringToBuf(buf[:]) - if t.ScriptID != 0 { - n += copy(buf[n:], "-") - n += copy(buf[n:], t.ScriptID.String()) - } - if t.RegionID != 0 { - n += copy(buf[n:], "-") - n += copy(buf[n:], t.RegionID.String()) - } - return n -} - -// String returns the canonical string representation of the language tag. -func (t Tag) String() string { - if t.str != "" { - return t.str - } - if t.ScriptID == 0 && t.RegionID == 0 { - return t.LangID.String() - } - buf := [maxCoreSize]byte{} - return string(buf[:t.genCoreBytes(buf[:])]) -} - -// MarshalText implements encoding.TextMarshaler. -func (t Tag) MarshalText() (text []byte, err error) { - if t.str != "" { - text = append(text, t.str...) - } else if t.ScriptID == 0 && t.RegionID == 0 { - text = append(text, t.LangID.String()...) - } else { - buf := [maxCoreSize]byte{} - text = buf[:t.genCoreBytes(buf[:])] - } - return text, nil -} - -// UnmarshalText implements encoding.TextUnmarshaler. -func (t *Tag) UnmarshalText(text []byte) error { - tag, err := Parse(string(text)) - *t = tag - return err -} - -// Variants returns the part of the tag holding all variants or the empty string -// if there are no variants defined. -func (t Tag) Variants() string { - if t.pVariant == 0 { - return "" - } - return t.str[t.pVariant:t.pExt] -} - -// VariantOrPrivateUseTags returns variants or private use tags. -func (t Tag) VariantOrPrivateUseTags() string { - if t.pExt > 0 { - return t.str[t.pVariant:t.pExt] - } - return t.str[t.pVariant:] -} - -// HasString reports whether this tag defines more than just the raw -// components. -func (t Tag) HasString() bool { - return t.str != "" -} - -// Parent returns the CLDR parent of t. In CLDR, missing fields in data for a -// specific language are substituted with fields from the parent language. -// The parent for a language may change for newer versions of CLDR. -func (t Tag) Parent() Tag { - if t.str != "" { - // Strip the variants and extensions. - b, s, r := t.Raw() - t = Tag{LangID: b, ScriptID: s, RegionID: r} - if t.RegionID == 0 && t.ScriptID != 0 && t.LangID != 0 { - base, _ := addTags(Tag{LangID: t.LangID}) - if base.ScriptID == t.ScriptID { - return Tag{LangID: t.LangID} - } - } - return t - } - if t.LangID != 0 { - if t.RegionID != 0 { - maxScript := t.ScriptID - if maxScript == 0 { - max, _ := addTags(t) - maxScript = max.ScriptID - } - - for i := range parents { - if Language(parents[i].lang) == t.LangID && Script(parents[i].maxScript) == maxScript { - for _, r := range parents[i].fromRegion { - if Region(r) == t.RegionID { - return Tag{ - LangID: t.LangID, - ScriptID: Script(parents[i].script), - RegionID: Region(parents[i].toRegion), - } - } - } - } - } - - // Strip the script if it is the default one. - base, _ := addTags(Tag{LangID: t.LangID}) - if base.ScriptID != maxScript { - return Tag{LangID: t.LangID, ScriptID: maxScript} - } - return Tag{LangID: t.LangID} - } else if t.ScriptID != 0 { - // The parent for an base-script pair with a non-default script is - // "und" instead of the base language. - base, _ := addTags(Tag{LangID: t.LangID}) - if base.ScriptID != t.ScriptID { - return Und - } - return Tag{LangID: t.LangID} - } - } - return Und -} - -// ParseExtension parses s as an extension and returns it on success. -func ParseExtension(s string) (ext string, err error) { - defer func() { - if recover() != nil { - ext = "" - err = ErrSyntax - } - }() - - scan := makeScannerString(s) - var end int - if n := len(scan.token); n != 1 { - return "", ErrSyntax - } - scan.toLower(0, len(scan.b)) - end = parseExtension(&scan) - if end != len(s) { - return "", ErrSyntax - } - return string(scan.b), nil -} - -// HasVariants reports whether t has variants. -func (t Tag) HasVariants() bool { - return uint16(t.pVariant) < t.pExt -} - -// HasExtensions reports whether t has extensions. -func (t Tag) HasExtensions() bool { - return int(t.pExt) < len(t.str) -} - -// Extension returns the extension of type x for tag t. It will return -// false for ok if t does not have the requested extension. The returned -// extension will be invalid in this case. -func (t Tag) Extension(x byte) (ext string, ok bool) { - for i := int(t.pExt); i < len(t.str)-1; { - var ext string - i, ext = getExtension(t.str, i) - if ext[0] == x { - return ext, true - } - } - return "", false -} - -// Extensions returns all extensions of t. -func (t Tag) Extensions() []string { - e := []string{} - for i := int(t.pExt); i < len(t.str)-1; { - var ext string - i, ext = getExtension(t.str, i) - e = append(e, ext) - } - return e -} - -// TypeForKey returns the type associated with the given key, where key and type -// are of the allowed values defined for the Unicode locale extension ('u') in -// https://www.unicode.org/reports/tr35/#Unicode_Language_and_Locale_Identifiers. -// TypeForKey will traverse the inheritance chain to get the correct value. -// -// If there are multiple types associated with a key, only the first will be -// returned. If there is no type associated with a key, it returns the empty -// string. -func (t Tag) TypeForKey(key string) string { - if _, start, end, _ := t.findTypeForKey(key); end != start { - s := t.str[start:end] - if p := strings.IndexByte(s, '-'); p >= 0 { - s = s[:p] - } - return s - } - return "" -} - -var ( - errPrivateUse = errors.New("cannot set a key on a private use tag") - errInvalidArguments = errors.New("invalid key or type") -) - -// SetTypeForKey returns a new Tag with the key set to type, where key and type -// are of the allowed values defined for the Unicode locale extension ('u') in -// https://www.unicode.org/reports/tr35/#Unicode_Language_and_Locale_Identifiers. -// An empty value removes an existing pair with the same key. -func (t Tag) SetTypeForKey(key, value string) (Tag, error) { - if t.IsPrivateUse() { - return t, errPrivateUse - } - if len(key) != 2 { - return t, errInvalidArguments - } - - // Remove the setting if value is "". - if value == "" { - start, sep, end, _ := t.findTypeForKey(key) - if start != sep { - // Remove a possible empty extension. - switch { - case t.str[start-2] != '-': // has previous elements. - case end == len(t.str), // end of string - end+2 < len(t.str) && t.str[end+2] == '-': // end of extension - start -= 2 - } - if start == int(t.pVariant) && end == len(t.str) { - t.str = "" - t.pVariant, t.pExt = 0, 0 - } else { - t.str = fmt.Sprintf("%s%s", t.str[:start], t.str[end:]) - } - } - return t, nil - } - - if len(value) < 3 || len(value) > 8 { - return t, errInvalidArguments - } - - var ( - buf [maxCoreSize + maxSimpleUExtensionSize]byte - uStart int // start of the -u extension. - ) - - // Generate the tag string if needed. - if t.str == "" { - uStart = t.genCoreBytes(buf[:]) - buf[uStart] = '-' - uStart++ - } - - // Create new key-type pair and parse it to verify. - b := buf[uStart:] - copy(b, "u-") - copy(b[2:], key) - b[4] = '-' - b = b[:5+copy(b[5:], value)] - scan := makeScanner(b) - if parseExtensions(&scan); scan.err != nil { - return t, scan.err - } - - // Assemble the replacement string. - if t.str == "" { - t.pVariant, t.pExt = byte(uStart-1), uint16(uStart-1) - t.str = string(buf[:uStart+len(b)]) - } else { - s := t.str - start, sep, end, hasExt := t.findTypeForKey(key) - if start == sep { - if hasExt { - b = b[2:] - } - t.str = fmt.Sprintf("%s-%s%s", s[:sep], b, s[end:]) - } else { - t.str = fmt.Sprintf("%s-%s%s", s[:start+3], value, s[end:]) - } - } - return t, nil -} - -// findTypeForKey returns the start and end position for the type corresponding -// to key or the point at which to insert the key-value pair if the type -// wasn't found. The hasExt return value reports whether an -u extension was present. -// Note: the extensions are typically very small and are likely to contain -// only one key-type pair. -func (t Tag) findTypeForKey(key string) (start, sep, end int, hasExt bool) { - p := int(t.pExt) - if len(key) != 2 || p == len(t.str) || p == 0 { - return p, p, p, false - } - s := t.str - - // Find the correct extension. - for p++; s[p] != 'u'; p++ { - if s[p] > 'u' { - p-- - return p, p, p, false - } - if p = nextExtension(s, p); p == len(s) { - return len(s), len(s), len(s), false - } - } - // Proceed to the hyphen following the extension name. - p++ - - // curKey is the key currently being processed. - curKey := "" - - // Iterate over keys until we get the end of a section. - for { - end = p - for p++; p < len(s) && s[p] != '-'; p++ { - } - n := p - end - 1 - if n <= 2 && curKey == key { - if sep < end { - sep++ - } - return start, sep, end, true - } - switch n { - case 0, // invalid string - 1: // next extension - return end, end, end, true - case 2: - // next key - curKey = s[end+1 : p] - if curKey > key { - return end, end, end, true - } - start = end - sep = p - } - } -} - -// ParseBase parses a 2- or 3-letter ISO 639 code. -// It returns a ValueError if s is a well-formed but unknown language identifier -// or another error if another error occurred. -func ParseBase(s string) (l Language, err error) { - defer func() { - if recover() != nil { - l = 0 - err = ErrSyntax - } - }() - - if n := len(s); n < 2 || 3 < n { - return 0, ErrSyntax - } - var buf [3]byte - return getLangID(buf[:copy(buf[:], s)]) -} - -// ParseScript parses a 4-letter ISO 15924 code. -// It returns a ValueError if s is a well-formed but unknown script identifier -// or another error if another error occurred. -func ParseScript(s string) (scr Script, err error) { - defer func() { - if recover() != nil { - scr = 0 - err = ErrSyntax - } - }() - - if len(s) != 4 { - return 0, ErrSyntax - } - var buf [4]byte - return getScriptID(script, buf[:copy(buf[:], s)]) -} - -// EncodeM49 returns the Region for the given UN M.49 code. -// It returns an error if r is not a valid code. -func EncodeM49(r int) (Region, error) { - return getRegionM49(r) -} - -// ParseRegion parses a 2- or 3-letter ISO 3166-1 or a UN M.49 code. -// It returns a ValueError if s is a well-formed but unknown region identifier -// or another error if another error occurred. -func ParseRegion(s string) (r Region, err error) { - defer func() { - if recover() != nil { - r = 0 - err = ErrSyntax - } - }() - - if n := len(s); n < 2 || 3 < n { - return 0, ErrSyntax - } - var buf [3]byte - return getRegionID(buf[:copy(buf[:], s)]) -} - -// IsCountry returns whether this region is a country or autonomous area. This -// includes non-standard definitions from CLDR. -func (r Region) IsCountry() bool { - if r == 0 || r.IsGroup() || r.IsPrivateUse() && r != _XK { - return false - } - return true -} - -// IsGroup returns whether this region defines a collection of regions. This -// includes non-standard definitions from CLDR. -func (r Region) IsGroup() bool { - if r == 0 { - return false - } - return int(regionInclusion[r]) < len(regionContainment) -} - -// Contains returns whether Region c is contained by Region r. It returns true -// if c == r. -func (r Region) Contains(c Region) bool { - if r == c { - return true - } - g := regionInclusion[r] - if g >= nRegionGroups { - return false - } - m := regionContainment[g] - - d := regionInclusion[c] - b := regionInclusionBits[d] - - // A contained country may belong to multiple disjoint groups. Matching any - // of these indicates containment. If the contained region is a group, it - // must strictly be a subset. - if d >= nRegionGroups { - return b&m != 0 - } - return b&^m == 0 -} - -var errNoTLD = errors.New("language: region is not a valid ccTLD") - -// TLD returns the country code top-level domain (ccTLD). UK is returned for GB. -// In all other cases it returns either the region itself or an error. -// -// This method may return an error for a region for which there exists a -// canonical form with a ccTLD. To get that ccTLD canonicalize r first. The -// region will already be canonicalized it was obtained from a Tag that was -// obtained using any of the default methods. -func (r Region) TLD() (Region, error) { - // See http://en.wikipedia.org/wiki/Country_code_top-level_domain for the - // difference between ISO 3166-1 and IANA ccTLD. - if r == _GB { - r = _UK - } - if (r.typ() & ccTLD) == 0 { - return 0, errNoTLD - } - return r, nil -} - -// Canonicalize returns the region or a possible replacement if the region is -// deprecated. It will not return a replacement for deprecated regions that -// are split into multiple regions. -func (r Region) Canonicalize() Region { - if cr := normRegion(r); cr != 0 { - return cr - } - return r -} - -// Variant represents a registered variant of a language as defined by BCP 47. -type Variant struct { - ID uint8 - str string -} - -// ParseVariant parses and returns a Variant. An error is returned if s is not -// a valid variant. -func ParseVariant(s string) (v Variant, err error) { - defer func() { - if recover() != nil { - v = Variant{} - err = ErrSyntax - } - }() - - s = strings.ToLower(s) - if id, ok := variantIndex[s]; ok { - return Variant{id, s}, nil - } - return Variant{}, NewValueError([]byte(s)) -} - -// String returns the string representation of the variant. -func (v Variant) String() string { - return v.str -} diff --git a/vendor/golang.org/x/text/internal/language/lookup.go b/vendor/golang.org/x/text/internal/language/lookup.go deleted file mode 100644 index 231b4fbde..000000000 --- a/vendor/golang.org/x/text/internal/language/lookup.go +++ /dev/null @@ -1,412 +0,0 @@ -// Copyright 2013 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 language - -import ( - "bytes" - "fmt" - "sort" - "strconv" - - "golang.org/x/text/internal/tag" -) - -// findIndex tries to find the given tag in idx and returns a standardized error -// if it could not be found. -func findIndex(idx tag.Index, key []byte, form string) (index int, err error) { - if !tag.FixCase(form, key) { - return 0, ErrSyntax - } - i := idx.Index(key) - if i == -1 { - return 0, NewValueError(key) - } - return i, nil -} - -func searchUint(imap []uint16, key uint16) int { - return sort.Search(len(imap), func(i int) bool { - return imap[i] >= key - }) -} - -type Language uint16 - -// getLangID returns the langID of s if s is a canonical subtag -// or langUnknown if s is not a canonical subtag. -func getLangID(s []byte) (Language, error) { - if len(s) == 2 { - return getLangISO2(s) - } - return getLangISO3(s) -} - -// TODO language normalization as well as the AliasMaps could be moved to the -// higher level package, but it is a bit tricky to separate the generation. - -func (id Language) Canonicalize() (Language, AliasType) { - return normLang(id) -} - -// normLang returns the mapped langID of id according to mapping m. -func normLang(id Language) (Language, AliasType) { - k := sort.Search(len(AliasMap), func(i int) bool { - return AliasMap[i].From >= uint16(id) - }) - if k < len(AliasMap) && AliasMap[k].From == uint16(id) { - return Language(AliasMap[k].To), AliasTypes[k] - } - return id, AliasTypeUnknown -} - -// getLangISO2 returns the langID for the given 2-letter ISO language code -// or unknownLang if this does not exist. -func getLangISO2(s []byte) (Language, error) { - if !tag.FixCase("zz", s) { - return 0, ErrSyntax - } - if i := lang.Index(s); i != -1 && lang.Elem(i)[3] != 0 { - return Language(i), nil - } - return 0, NewValueError(s) -} - -const base = 'z' - 'a' + 1 - -func strToInt(s []byte) uint { - v := uint(0) - for i := 0; i < len(s); i++ { - v *= base - v += uint(s[i] - 'a') - } - return v -} - -// converts the given integer to the original ASCII string passed to strToInt. -// len(s) must match the number of characters obtained. -func intToStr(v uint, s []byte) { - for i := len(s) - 1; i >= 0; i-- { - s[i] = byte(v%base) + 'a' - v /= base - } -} - -// getLangISO3 returns the langID for the given 3-letter ISO language code -// or unknownLang if this does not exist. -func getLangISO3(s []byte) (Language, error) { - if tag.FixCase("und", s) { - // first try to match canonical 3-letter entries - for i := lang.Index(s[:2]); i != -1; i = lang.Next(s[:2], i) { - if e := lang.Elem(i); e[3] == 0 && e[2] == s[2] { - // We treat "und" as special and always translate it to "unspecified". - // Note that ZZ and Zzzz are private use and are not treated as - // unspecified by default. - id := Language(i) - if id == nonCanonicalUnd { - return 0, nil - } - return id, nil - } - } - if i := altLangISO3.Index(s); i != -1 { - return Language(altLangIndex[altLangISO3.Elem(i)[3]]), nil - } - n := strToInt(s) - if langNoIndex[n/8]&(1<<(n%8)) != 0 { - return Language(n) + langNoIndexOffset, nil - } - // Check for non-canonical uses of ISO3. - for i := lang.Index(s[:1]); i != -1; i = lang.Next(s[:1], i) { - if e := lang.Elem(i); e[2] == s[1] && e[3] == s[2] { - return Language(i), nil - } - } - return 0, NewValueError(s) - } - return 0, ErrSyntax -} - -// StringToBuf writes the string to b and returns the number of bytes -// written. cap(b) must be >= 3. -func (id Language) StringToBuf(b []byte) int { - if id >= langNoIndexOffset { - intToStr(uint(id)-langNoIndexOffset, b[:3]) - return 3 - } else if id == 0 { - return copy(b, "und") - } - l := lang[id<<2:] - if l[3] == 0 { - return copy(b, l[:3]) - } - return copy(b, l[:2]) -} - -// String returns the BCP 47 representation of the langID. -// Use b as variable name, instead of id, to ensure the variable -// used is consistent with that of Base in which this type is embedded. -func (b Language) String() string { - if b == 0 { - return "und" - } else if b >= langNoIndexOffset { - b -= langNoIndexOffset - buf := [3]byte{} - intToStr(uint(b), buf[:]) - return string(buf[:]) - } - l := lang.Elem(int(b)) - if l[3] == 0 { - return l[:3] - } - return l[:2] -} - -// ISO3 returns the ISO 639-3 language code. -func (b Language) ISO3() string { - if b == 0 || b >= langNoIndexOffset { - return b.String() - } - l := lang.Elem(int(b)) - if l[3] == 0 { - return l[:3] - } else if l[2] == 0 { - return altLangISO3.Elem(int(l[3]))[:3] - } - // This allocation will only happen for 3-letter ISO codes - // that are non-canonical BCP 47 language identifiers. - return l[0:1] + l[2:4] -} - -// IsPrivateUse reports whether this language code is reserved for private use. -func (b Language) IsPrivateUse() bool { - return langPrivateStart <= b && b <= langPrivateEnd -} - -// SuppressScript returns the script marked as SuppressScript in the IANA -// language tag repository, or 0 if there is no such script. -func (b Language) SuppressScript() Script { - if b < langNoIndexOffset { - return Script(suppressScript[b]) - } - return 0 -} - -type Region uint16 - -// getRegionID returns the region id for s if s is a valid 2-letter region code -// or unknownRegion. -func getRegionID(s []byte) (Region, error) { - if len(s) == 3 { - if isAlpha(s[0]) { - return getRegionISO3(s) - } - if i, err := strconv.ParseUint(string(s), 10, 10); err == nil { - return getRegionM49(int(i)) - } - } - return getRegionISO2(s) -} - -// getRegionISO2 returns the regionID for the given 2-letter ISO country code -// or unknownRegion if this does not exist. -func getRegionISO2(s []byte) (Region, error) { - i, err := findIndex(regionISO, s, "ZZ") - if err != nil { - return 0, err - } - return Region(i) + isoRegionOffset, nil -} - -// getRegionISO3 returns the regionID for the given 3-letter ISO country code -// or unknownRegion if this does not exist. -func getRegionISO3(s []byte) (Region, error) { - if tag.FixCase("ZZZ", s) { - for i := regionISO.Index(s[:1]); i != -1; i = regionISO.Next(s[:1], i) { - if e := regionISO.Elem(i); e[2] == s[1] && e[3] == s[2] { - return Region(i) + isoRegionOffset, nil - } - } - for i := 0; i < len(altRegionISO3); i += 3 { - if tag.Compare(altRegionISO3[i:i+3], s) == 0 { - return Region(altRegionIDs[i/3]), nil - } - } - return 0, NewValueError(s) - } - return 0, ErrSyntax -} - -func getRegionM49(n int) (Region, error) { - if 0 < n && n <= 999 { - const ( - searchBits = 7 - regionBits = 9 - regionMask = 1<> searchBits - buf := fromM49[m49Index[idx]:m49Index[idx+1]] - val := uint16(n) << regionBits // we rely on bits shifting out - i := sort.Search(len(buf), func(i int) bool { - return buf[i] >= val - }) - if r := fromM49[int(m49Index[idx])+i]; r&^regionMask == val { - return Region(r & regionMask), nil - } - } - var e ValueError - fmt.Fprint(bytes.NewBuffer([]byte(e.v[:])), n) - return 0, e -} - -// normRegion returns a region if r is deprecated or 0 otherwise. -// TODO: consider supporting BYS (-> BLR), CSK (-> 200 or CZ), PHI (-> PHL) and AFI (-> DJ). -// TODO: consider mapping split up regions to new most populous one (like CLDR). -func normRegion(r Region) Region { - m := regionOldMap - k := sort.Search(len(m), func(i int) bool { - return m[i].From >= uint16(r) - }) - if k < len(m) && m[k].From == uint16(r) { - return Region(m[k].To) - } - return 0 -} - -const ( - iso3166UserAssigned = 1 << iota - ccTLD - bcp47Region -) - -func (r Region) typ() byte { - return regionTypes[r] -} - -// String returns the BCP 47 representation for the region. -// It returns "ZZ" for an unspecified region. -func (r Region) String() string { - if r < isoRegionOffset { - if r == 0 { - return "ZZ" - } - return fmt.Sprintf("%03d", r.M49()) - } - r -= isoRegionOffset - return regionISO.Elem(int(r))[:2] -} - -// ISO3 returns the 3-letter ISO code of r. -// Note that not all regions have a 3-letter ISO code. -// In such cases this method returns "ZZZ". -func (r Region) ISO3() string { - if r < isoRegionOffset { - return "ZZZ" - } - r -= isoRegionOffset - reg := regionISO.Elem(int(r)) - switch reg[2] { - case 0: - return altRegionISO3[reg[3]:][:3] - case ' ': - return "ZZZ" - } - return reg[0:1] + reg[2:4] -} - -// M49 returns the UN M.49 encoding of r, or 0 if this encoding -// is not defined for r. -func (r Region) M49() int { - return int(m49[r]) -} - -// IsPrivateUse reports whether r has the ISO 3166 User-assigned status. This -// may include private-use tags that are assigned by CLDR and used in this -// implementation. So IsPrivateUse and IsCountry can be simultaneously true. -func (r Region) IsPrivateUse() bool { - return r.typ()&iso3166UserAssigned != 0 -} - -type Script uint16 - -// getScriptID returns the script id for string s. It assumes that s -// is of the format [A-Z][a-z]{3}. -func getScriptID(idx tag.Index, s []byte) (Script, error) { - i, err := findIndex(idx, s, "Zzzz") - return Script(i), err -} - -// String returns the script code in title case. -// It returns "Zzzz" for an unspecified script. -func (s Script) String() string { - if s == 0 { - return "Zzzz" - } - return script.Elem(int(s)) -} - -// IsPrivateUse reports whether this script code is reserved for private use. -func (s Script) IsPrivateUse() bool { - return _Qaaa <= s && s <= _Qabx -} - -const ( - maxAltTaglen = len("en-US-POSIX") - maxLen = maxAltTaglen -) - -var ( - // grandfatheredMap holds a mapping from legacy and grandfathered tags to - // their base language or index to more elaborate tag. - grandfatheredMap = map[[maxLen]byte]int16{ - [maxLen]byte{'a', 'r', 't', '-', 'l', 'o', 'j', 'b', 'a', 'n'}: _jbo, // art-lojban - [maxLen]byte{'i', '-', 'a', 'm', 'i'}: _ami, // i-ami - [maxLen]byte{'i', '-', 'b', 'n', 'n'}: _bnn, // i-bnn - [maxLen]byte{'i', '-', 'h', 'a', 'k'}: _hak, // i-hak - [maxLen]byte{'i', '-', 'k', 'l', 'i', 'n', 'g', 'o', 'n'}: _tlh, // i-klingon - [maxLen]byte{'i', '-', 'l', 'u', 'x'}: _lb, // i-lux - [maxLen]byte{'i', '-', 'n', 'a', 'v', 'a', 'j', 'o'}: _nv, // i-navajo - [maxLen]byte{'i', '-', 'p', 'w', 'n'}: _pwn, // i-pwn - [maxLen]byte{'i', '-', 't', 'a', 'o'}: _tao, // i-tao - [maxLen]byte{'i', '-', 't', 'a', 'y'}: _tay, // i-tay - [maxLen]byte{'i', '-', 't', 's', 'u'}: _tsu, // i-tsu - [maxLen]byte{'n', 'o', '-', 'b', 'o', 'k'}: _nb, // no-bok - [maxLen]byte{'n', 'o', '-', 'n', 'y', 'n'}: _nn, // no-nyn - [maxLen]byte{'s', 'g', 'n', '-', 'b', 'e', '-', 'f', 'r'}: _sfb, // sgn-BE-FR - [maxLen]byte{'s', 'g', 'n', '-', 'b', 'e', '-', 'n', 'l'}: _vgt, // sgn-BE-NL - [maxLen]byte{'s', 'g', 'n', '-', 'c', 'h', '-', 'd', 'e'}: _sgg, // sgn-CH-DE - [maxLen]byte{'z', 'h', '-', 'g', 'u', 'o', 'y', 'u'}: _cmn, // zh-guoyu - [maxLen]byte{'z', 'h', '-', 'h', 'a', 'k', 'k', 'a'}: _hak, // zh-hakka - [maxLen]byte{'z', 'h', '-', 'm', 'i', 'n', '-', 'n', 'a', 'n'}: _nan, // zh-min-nan - [maxLen]byte{'z', 'h', '-', 'x', 'i', 'a', 'n', 'g'}: _hsn, // zh-xiang - - // Grandfathered tags with no modern replacement will be converted as - // follows: - [maxLen]byte{'c', 'e', 'l', '-', 'g', 'a', 'u', 'l', 'i', 's', 'h'}: -1, // cel-gaulish - [maxLen]byte{'e', 'n', '-', 'g', 'b', '-', 'o', 'e', 'd'}: -2, // en-GB-oed - [maxLen]byte{'i', '-', 'd', 'e', 'f', 'a', 'u', 'l', 't'}: -3, // i-default - [maxLen]byte{'i', '-', 'e', 'n', 'o', 'c', 'h', 'i', 'a', 'n'}: -4, // i-enochian - [maxLen]byte{'i', '-', 'm', 'i', 'n', 'g', 'o'}: -5, // i-mingo - [maxLen]byte{'z', 'h', '-', 'm', 'i', 'n'}: -6, // zh-min - - // CLDR-specific tag. - [maxLen]byte{'r', 'o', 'o', 't'}: 0, // root - [maxLen]byte{'e', 'n', '-', 'u', 's', '-', 'p', 'o', 's', 'i', 'x'}: -7, // en_US_POSIX" - } - - altTagIndex = [...]uint8{0, 17, 31, 45, 61, 74, 86, 102} - - altTags = "xtg-x-cel-gaulishen-GB-oxendicten-x-i-defaultund-x-i-enochiansee-x-i-mingonan-x-zh-minen-US-u-va-posix" -) - -func grandfathered(s [maxAltTaglen]byte) (t Tag, ok bool) { - if v, ok := grandfatheredMap[s]; ok { - if v < 0 { - return Make(altTags[altTagIndex[-v-1]:altTagIndex[-v]]), true - } - t.LangID = Language(v) - return t, true - } - return t, false -} diff --git a/vendor/golang.org/x/text/internal/language/match.go b/vendor/golang.org/x/text/internal/language/match.go deleted file mode 100644 index 75a2dbca7..000000000 --- a/vendor/golang.org/x/text/internal/language/match.go +++ /dev/null @@ -1,226 +0,0 @@ -// Copyright 2013 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 language - -import "errors" - -type scriptRegionFlags uint8 - -const ( - isList = 1 << iota - scriptInFrom - regionInFrom -) - -func (t *Tag) setUndefinedLang(id Language) { - if t.LangID == 0 { - t.LangID = id - } -} - -func (t *Tag) setUndefinedScript(id Script) { - if t.ScriptID == 0 { - t.ScriptID = id - } -} - -func (t *Tag) setUndefinedRegion(id Region) { - if t.RegionID == 0 || t.RegionID.Contains(id) { - t.RegionID = id - } -} - -// ErrMissingLikelyTagsData indicates no information was available -// to compute likely values of missing tags. -var ErrMissingLikelyTagsData = errors.New("missing likely tags data") - -// addLikelySubtags sets subtags to their most likely value, given the locale. -// In most cases this means setting fields for unknown values, but in some -// cases it may alter a value. It returns an ErrMissingLikelyTagsData error -// if the given locale cannot be expanded. -func (t Tag) addLikelySubtags() (Tag, error) { - id, err := addTags(t) - if err != nil { - return t, err - } else if id.equalTags(t) { - return t, nil - } - id.RemakeString() - return id, nil -} - -// specializeRegion attempts to specialize a group region. -func specializeRegion(t *Tag) bool { - if i := regionInclusion[t.RegionID]; i < nRegionGroups { - x := likelyRegionGroup[i] - if Language(x.lang) == t.LangID && Script(x.script) == t.ScriptID { - t.RegionID = Region(x.region) - } - return true - } - return false -} - -// Maximize returns a new tag with missing tags filled in. -func (t Tag) Maximize() (Tag, error) { - return addTags(t) -} - -func addTags(t Tag) (Tag, error) { - // We leave private use identifiers alone. - if t.IsPrivateUse() { - return t, nil - } - if t.ScriptID != 0 && t.RegionID != 0 { - if t.LangID != 0 { - // already fully specified - specializeRegion(&t) - return t, nil - } - // Search matches for und-script-region. Note that for these cases - // region will never be a group so there is no need to check for this. - list := likelyRegion[t.RegionID : t.RegionID+1] - if x := list[0]; x.flags&isList != 0 { - list = likelyRegionList[x.lang : x.lang+uint16(x.script)] - } - for _, x := range list { - // Deviating from the spec. See match_test.go for details. - if Script(x.script) == t.ScriptID { - t.setUndefinedLang(Language(x.lang)) - return t, nil - } - } - } - if t.LangID != 0 { - // Search matches for lang-script and lang-region, where lang != und. - if t.LangID < langNoIndexOffset { - x := likelyLang[t.LangID] - if x.flags&isList != 0 { - list := likelyLangList[x.region : x.region+uint16(x.script)] - if t.ScriptID != 0 { - for _, x := range list { - if Script(x.script) == t.ScriptID && x.flags&scriptInFrom != 0 { - t.setUndefinedRegion(Region(x.region)) - return t, nil - } - } - } else if t.RegionID != 0 { - count := 0 - goodScript := true - tt := t - for _, x := range list { - // We visit all entries for which the script was not - // defined, including the ones where the region was not - // defined. This allows for proper disambiguation within - // regions. - if x.flags&scriptInFrom == 0 && t.RegionID.Contains(Region(x.region)) { - tt.RegionID = Region(x.region) - tt.setUndefinedScript(Script(x.script)) - goodScript = goodScript && tt.ScriptID == Script(x.script) - count++ - } - } - if count == 1 { - return tt, nil - } - // Even if we fail to find a unique Region, we might have - // an unambiguous script. - if goodScript { - t.ScriptID = tt.ScriptID - } - } - } - } - } else { - // Search matches for und-script. - if t.ScriptID != 0 { - x := likelyScript[t.ScriptID] - if x.region != 0 { - t.setUndefinedRegion(Region(x.region)) - t.setUndefinedLang(Language(x.lang)) - return t, nil - } - } - // Search matches for und-region. If und-script-region exists, it would - // have been found earlier. - if t.RegionID != 0 { - if i := regionInclusion[t.RegionID]; i < nRegionGroups { - x := likelyRegionGroup[i] - if x.region != 0 { - t.setUndefinedLang(Language(x.lang)) - t.setUndefinedScript(Script(x.script)) - t.RegionID = Region(x.region) - } - } else { - x := likelyRegion[t.RegionID] - if x.flags&isList != 0 { - x = likelyRegionList[x.lang] - } - if x.script != 0 && x.flags != scriptInFrom { - t.setUndefinedLang(Language(x.lang)) - t.setUndefinedScript(Script(x.script)) - return t, nil - } - } - } - } - - // Search matches for lang. - if t.LangID < langNoIndexOffset { - x := likelyLang[t.LangID] - if x.flags&isList != 0 { - x = likelyLangList[x.region] - } - if x.region != 0 { - t.setUndefinedScript(Script(x.script)) - t.setUndefinedRegion(Region(x.region)) - } - specializeRegion(&t) - if t.LangID == 0 { - t.LangID = _en // default language - } - return t, nil - } - return t, ErrMissingLikelyTagsData -} - -func (t *Tag) setTagsFrom(id Tag) { - t.LangID = id.LangID - t.ScriptID = id.ScriptID - t.RegionID = id.RegionID -} - -// minimize removes the region or script subtags from t such that -// t.addLikelySubtags() == t.minimize().addLikelySubtags(). -func (t Tag) minimize() (Tag, error) { - t, err := minimizeTags(t) - if err != nil { - return t, err - } - t.RemakeString() - return t, nil -} - -// minimizeTags mimics the behavior of the ICU 51 C implementation. -func minimizeTags(t Tag) (Tag, error) { - if t.equalTags(Und) { - return t, nil - } - max, err := addTags(t) - if err != nil { - return t, err - } - for _, id := range [...]Tag{ - {LangID: t.LangID}, - {LangID: t.LangID, RegionID: t.RegionID}, - {LangID: t.LangID, ScriptID: t.ScriptID}, - } { - if x, err := addTags(id); err == nil && max.equalTags(x) { - t.setTagsFrom(id) - break - } - } - return t, nil -} diff --git a/vendor/golang.org/x/text/internal/language/parse.go b/vendor/golang.org/x/text/internal/language/parse.go deleted file mode 100644 index aad1e0acf..000000000 --- a/vendor/golang.org/x/text/internal/language/parse.go +++ /dev/null @@ -1,608 +0,0 @@ -// Copyright 2013 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 language - -import ( - "bytes" - "errors" - "fmt" - "sort" - - "golang.org/x/text/internal/tag" -) - -// isAlpha returns true if the byte is not a digit. -// b must be an ASCII letter or digit. -func isAlpha(b byte) bool { - return b > '9' -} - -// isAlphaNum returns true if the string contains only ASCII letters or digits. -func isAlphaNum(s []byte) bool { - for _, c := range s { - if !('a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || '0' <= c && c <= '9') { - return false - } - } - return true -} - -// ErrSyntax is returned by any of the parsing functions when the -// input is not well-formed, according to BCP 47. -// TODO: return the position at which the syntax error occurred? -var ErrSyntax = errors.New("language: tag is not well-formed") - -// ErrDuplicateKey is returned when a tag contains the same key twice with -// different values in the -u section. -var ErrDuplicateKey = errors.New("language: different values for same key in -u extension") - -// ValueError is returned by any of the parsing functions when the -// input is well-formed but the respective subtag is not recognized -// as a valid value. -type ValueError struct { - v [8]byte -} - -// NewValueError creates a new ValueError. -func NewValueError(tag []byte) ValueError { - var e ValueError - copy(e.v[:], tag) - return e -} - -func (e ValueError) tag() []byte { - n := bytes.IndexByte(e.v[:], 0) - if n == -1 { - n = 8 - } - return e.v[:n] -} - -// Error implements the error interface. -func (e ValueError) Error() string { - return fmt.Sprintf("language: subtag %q is well-formed but unknown", e.tag()) -} - -// Subtag returns the subtag for which the error occurred. -func (e ValueError) Subtag() string { - return string(e.tag()) -} - -// scanner is used to scan BCP 47 tokens, which are separated by _ or -. -type scanner struct { - b []byte - bytes [max99thPercentileSize]byte - token []byte - start int // start position of the current token - end int // end position of the current token - next int // next point for scan - err error - done bool -} - -func makeScannerString(s string) scanner { - scan := scanner{} - if len(s) <= len(scan.bytes) { - scan.b = scan.bytes[:copy(scan.bytes[:], s)] - } else { - scan.b = []byte(s) - } - scan.init() - return scan -} - -// makeScanner returns a scanner using b as the input buffer. -// b is not copied and may be modified by the scanner routines. -func makeScanner(b []byte) scanner { - scan := scanner{b: b} - scan.init() - return scan -} - -func (s *scanner) init() { - for i, c := range s.b { - if c == '_' { - s.b[i] = '-' - } - } - s.scan() -} - -// restToLower converts the string between start and end to lower case. -func (s *scanner) toLower(start, end int) { - for i := start; i < end; i++ { - c := s.b[i] - if 'A' <= c && c <= 'Z' { - s.b[i] += 'a' - 'A' - } - } -} - -func (s *scanner) setError(e error) { - if s.err == nil || (e == ErrSyntax && s.err != ErrSyntax) { - s.err = e - } -} - -// resizeRange shrinks or grows the array at position oldStart such that -// a new string of size newSize can fit between oldStart and oldEnd. -// Sets the scan point to after the resized range. -func (s *scanner) resizeRange(oldStart, oldEnd, newSize int) { - s.start = oldStart - if end := oldStart + newSize; end != oldEnd { - diff := end - oldEnd - var b []byte - if n := len(s.b) + diff; n > cap(s.b) { - b = make([]byte, n) - copy(b, s.b[:oldStart]) - } else { - b = s.b[:n] - } - copy(b[end:], s.b[oldEnd:]) - s.b = b - s.next = end + (s.next - s.end) - s.end = end - } -} - -// replace replaces the current token with repl. -func (s *scanner) replace(repl string) { - s.resizeRange(s.start, s.end, len(repl)) - copy(s.b[s.start:], repl) -} - -// gobble removes the current token from the input. -// Caller must call scan after calling gobble. -func (s *scanner) gobble(e error) { - s.setError(e) - if s.start == 0 { - s.b = s.b[:+copy(s.b, s.b[s.next:])] - s.end = 0 - } else { - s.b = s.b[:s.start-1+copy(s.b[s.start-1:], s.b[s.end:])] - s.end = s.start - 1 - } - s.next = s.start -} - -// deleteRange removes the given range from s.b before the current token. -func (s *scanner) deleteRange(start, end int) { - s.b = s.b[:start+copy(s.b[start:], s.b[end:])] - diff := end - start - s.next -= diff - s.start -= diff - s.end -= diff -} - -// scan parses the next token of a BCP 47 string. Tokens that are larger -// than 8 characters or include non-alphanumeric characters result in an error -// and are gobbled and removed from the output. -// It returns the end position of the last token consumed. -func (s *scanner) scan() (end int) { - end = s.end - s.token = nil - for s.start = s.next; s.next < len(s.b); { - i := bytes.IndexByte(s.b[s.next:], '-') - if i == -1 { - s.end = len(s.b) - s.next = len(s.b) - i = s.end - s.start - } else { - s.end = s.next + i - s.next = s.end + 1 - } - token := s.b[s.start:s.end] - if i < 1 || i > 8 || !isAlphaNum(token) { - s.gobble(ErrSyntax) - continue - } - s.token = token - return end - } - if n := len(s.b); n > 0 && s.b[n-1] == '-' { - s.setError(ErrSyntax) - s.b = s.b[:len(s.b)-1] - } - s.done = true - return end -} - -// acceptMinSize parses multiple tokens of the given size or greater. -// It returns the end position of the last token consumed. -func (s *scanner) acceptMinSize(min int) (end int) { - end = s.end - s.scan() - for ; len(s.token) >= min; s.scan() { - end = s.end - } - return end -} - -// Parse parses the given BCP 47 string and returns a valid Tag. If parsing -// failed it returns an error and any part of the tag that could be parsed. -// If parsing succeeded but an unknown value was found, it returns -// ValueError. The Tag returned in this case is just stripped of the unknown -// value. All other values are preserved. It accepts tags in the BCP 47 format -// and extensions to this standard defined in -// https://www.unicode.org/reports/tr35/#Unicode_Language_and_Locale_Identifiers. -func Parse(s string) (t Tag, err error) { - // TODO: consider supporting old-style locale key-value pairs. - if s == "" { - return Und, ErrSyntax - } - defer func() { - if recover() != nil { - t = Und - err = ErrSyntax - return - } - }() - if len(s) <= maxAltTaglen { - b := [maxAltTaglen]byte{} - for i, c := range s { - // Generating invalid UTF-8 is okay as it won't match. - if 'A' <= c && c <= 'Z' { - c += 'a' - 'A' - } else if c == '_' { - c = '-' - } - b[i] = byte(c) - } - if t, ok := grandfathered(b); ok { - return t, nil - } - } - scan := makeScannerString(s) - return parse(&scan, s) -} - -func parse(scan *scanner, s string) (t Tag, err error) { - t = Und - var end int - if n := len(scan.token); n <= 1 { - scan.toLower(0, len(scan.b)) - if n == 0 || scan.token[0] != 'x' { - return t, ErrSyntax - } - end = parseExtensions(scan) - } else if n >= 4 { - return Und, ErrSyntax - } else { // the usual case - t, end = parseTag(scan, true) - if n := len(scan.token); n == 1 { - t.pExt = uint16(end) - end = parseExtensions(scan) - } else if end < len(scan.b) { - scan.setError(ErrSyntax) - scan.b = scan.b[:end] - } - } - if int(t.pVariant) < len(scan.b) { - if end < len(s) { - s = s[:end] - } - if len(s) > 0 && tag.Compare(s, scan.b) == 0 { - t.str = s - } else { - t.str = string(scan.b) - } - } else { - t.pVariant, t.pExt = 0, 0 - } - return t, scan.err -} - -// parseTag parses language, script, region and variants. -// It returns a Tag and the end position in the input that was parsed. -// If doNorm is true, then - will be normalized to . -func parseTag(scan *scanner, doNorm bool) (t Tag, end int) { - var e error - // TODO: set an error if an unknown lang, script or region is encountered. - t.LangID, e = getLangID(scan.token) - scan.setError(e) - scan.replace(t.LangID.String()) - langStart := scan.start - end = scan.scan() - for len(scan.token) == 3 && isAlpha(scan.token[0]) { - // From http://tools.ietf.org/html/bcp47, - tags are equivalent - // to a tag of the form . - if doNorm { - lang, e := getLangID(scan.token) - if lang != 0 { - t.LangID = lang - langStr := lang.String() - copy(scan.b[langStart:], langStr) - scan.b[langStart+len(langStr)] = '-' - scan.start = langStart + len(langStr) + 1 - } - scan.gobble(e) - } - end = scan.scan() - } - if len(scan.token) == 4 && isAlpha(scan.token[0]) { - t.ScriptID, e = getScriptID(script, scan.token) - if t.ScriptID == 0 { - scan.gobble(e) - } - end = scan.scan() - } - if n := len(scan.token); n >= 2 && n <= 3 { - t.RegionID, e = getRegionID(scan.token) - if t.RegionID == 0 { - scan.gobble(e) - } else { - scan.replace(t.RegionID.String()) - } - end = scan.scan() - } - scan.toLower(scan.start, len(scan.b)) - t.pVariant = byte(end) - end = parseVariants(scan, end, t) - t.pExt = uint16(end) - return t, end -} - -var separator = []byte{'-'} - -// parseVariants scans tokens as long as each token is a valid variant string. -// Duplicate variants are removed. -func parseVariants(scan *scanner, end int, t Tag) int { - start := scan.start - varIDBuf := [4]uint8{} - variantBuf := [4][]byte{} - varID := varIDBuf[:0] - variant := variantBuf[:0] - last := -1 - needSort := false - for ; len(scan.token) >= 4; scan.scan() { - // TODO: measure the impact of needing this conversion and redesign - // the data structure if there is an issue. - v, ok := variantIndex[string(scan.token)] - if !ok { - // unknown variant - // TODO: allow user-defined variants? - scan.gobble(NewValueError(scan.token)) - continue - } - varID = append(varID, v) - variant = append(variant, scan.token) - if !needSort { - if last < int(v) { - last = int(v) - } else { - needSort = true - // There is no legal combinations of more than 7 variants - // (and this is by no means a useful sequence). - const maxVariants = 8 - if len(varID) > maxVariants { - break - } - } - } - end = scan.end - } - if needSort { - sort.Sort(variantsSort{varID, variant}) - k, l := 0, -1 - for i, v := range varID { - w := int(v) - if l == w { - // Remove duplicates. - continue - } - varID[k] = varID[i] - variant[k] = variant[i] - k++ - l = w - } - if str := bytes.Join(variant[:k], separator); len(str) == 0 { - end = start - 1 - } else { - scan.resizeRange(start, end, len(str)) - copy(scan.b[scan.start:], str) - end = scan.end - } - } - return end -} - -type variantsSort struct { - i []uint8 - v [][]byte -} - -func (s variantsSort) Len() int { - return len(s.i) -} - -func (s variantsSort) Swap(i, j int) { - s.i[i], s.i[j] = s.i[j], s.i[i] - s.v[i], s.v[j] = s.v[j], s.v[i] -} - -func (s variantsSort) Less(i, j int) bool { - return s.i[i] < s.i[j] -} - -type bytesSort struct { - b [][]byte - n int // first n bytes to compare -} - -func (b bytesSort) Len() int { - return len(b.b) -} - -func (b bytesSort) Swap(i, j int) { - b.b[i], b.b[j] = b.b[j], b.b[i] -} - -func (b bytesSort) Less(i, j int) bool { - for k := 0; k < b.n; k++ { - if b.b[i][k] == b.b[j][k] { - continue - } - return b.b[i][k] < b.b[j][k] - } - return false -} - -// parseExtensions parses and normalizes the extensions in the buffer. -// It returns the last position of scan.b that is part of any extension. -// It also trims scan.b to remove excess parts accordingly. -func parseExtensions(scan *scanner) int { - start := scan.start - exts := [][]byte{} - private := []byte{} - end := scan.end - for len(scan.token) == 1 { - extStart := scan.start - ext := scan.token[0] - end = parseExtension(scan) - extension := scan.b[extStart:end] - if len(extension) < 3 || (ext != 'x' && len(extension) < 4) { - scan.setError(ErrSyntax) - end = extStart - continue - } else if start == extStart && (ext == 'x' || scan.start == len(scan.b)) { - scan.b = scan.b[:end] - return end - } else if ext == 'x' { - private = extension - break - } - exts = append(exts, extension) - } - sort.Sort(bytesSort{exts, 1}) - if len(private) > 0 { - exts = append(exts, private) - } - scan.b = scan.b[:start] - if len(exts) > 0 { - scan.b = append(scan.b, bytes.Join(exts, separator)...) - } else if start > 0 { - // Strip trailing '-'. - scan.b = scan.b[:start-1] - } - return end -} - -// parseExtension parses a single extension and returns the position of -// the extension end. -func parseExtension(scan *scanner) int { - start, end := scan.start, scan.end - switch scan.token[0] { - case 'u': // https://www.ietf.org/rfc/rfc6067.txt - attrStart := end - scan.scan() - for last := []byte{}; len(scan.token) > 2; scan.scan() { - if bytes.Compare(scan.token, last) != -1 { - // Attributes are unsorted. Start over from scratch. - p := attrStart + 1 - scan.next = p - attrs := [][]byte{} - for scan.scan(); len(scan.token) > 2; scan.scan() { - attrs = append(attrs, scan.token) - end = scan.end - } - sort.Sort(bytesSort{attrs, 3}) - copy(scan.b[p:], bytes.Join(attrs, separator)) - break - } - last = scan.token - end = scan.end - } - // Scan key-type sequences. A key is of length 2 and may be followed - // by 0 or more "type" subtags from 3 to the maximum of 8 letters. - var last, key []byte - for attrEnd := end; len(scan.token) == 2; last = key { - key = scan.token - end = scan.end - for scan.scan(); end < scan.end && len(scan.token) > 2; scan.scan() { - end = scan.end - } - // TODO: check key value validity - if bytes.Compare(key, last) != 1 || scan.err != nil { - // We have an invalid key or the keys are not sorted. - // Start scanning keys from scratch and reorder. - p := attrEnd + 1 - scan.next = p - keys := [][]byte{} - for scan.scan(); len(scan.token) == 2; { - keyStart := scan.start - end = scan.end - for scan.scan(); end < scan.end && len(scan.token) > 2; scan.scan() { - end = scan.end - } - keys = append(keys, scan.b[keyStart:end]) - } - sort.Stable(bytesSort{keys, 2}) - if n := len(keys); n > 0 { - k := 0 - for i := 1; i < n; i++ { - if !bytes.Equal(keys[k][:2], keys[i][:2]) { - k++ - keys[k] = keys[i] - } else if !bytes.Equal(keys[k], keys[i]) { - scan.setError(ErrDuplicateKey) - } - } - keys = keys[:k+1] - } - reordered := bytes.Join(keys, separator) - if e := p + len(reordered); e < end { - scan.deleteRange(e, end) - end = e - } - copy(scan.b[p:], reordered) - break - } - } - case 't': // https://www.ietf.org/rfc/rfc6497.txt - scan.scan() - if n := len(scan.token); n >= 2 && n <= 3 && isAlpha(scan.token[1]) { - _, end = parseTag(scan, false) - scan.toLower(start, end) - } - for len(scan.token) == 2 && !isAlpha(scan.token[1]) { - end = scan.acceptMinSize(3) - } - case 'x': - end = scan.acceptMinSize(1) - default: - end = scan.acceptMinSize(2) - } - return end -} - -// getExtension returns the name, body and end position of the extension. -func getExtension(s string, p int) (end int, ext string) { - if s[p] == '-' { - p++ - } - if s[p] == 'x' { - return len(s), s[p:] - } - end = nextExtension(s, p) - return end, s[p:end] -} - -// nextExtension finds the next extension within the string, searching -// for the -- pattern from position p. -// In the fast majority of cases, language tags will have at most -// one extension and extensions tend to be small. -func nextExtension(s string, p int) int { - for n := len(s) - 3; p < n; { - if s[p] == '-' { - if s[p+2] == '-' { - return p - } - p += 3 - } else { - p++ - } - } - return len(s) -} diff --git a/vendor/golang.org/x/text/internal/language/tables.go b/vendor/golang.org/x/text/internal/language/tables.go deleted file mode 100644 index 14167e74e..000000000 --- a/vendor/golang.org/x/text/internal/language/tables.go +++ /dev/null @@ -1,3494 +0,0 @@ -// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. - -package language - -import "golang.org/x/text/internal/tag" - -// CLDRVersion is the CLDR version from which the tables in this package are derived. -const CLDRVersion = "32" - -const NumLanguages = 8798 - -const NumScripts = 261 - -const NumRegions = 358 - -type FromTo struct { - From uint16 - To uint16 -} - -const nonCanonicalUnd = 1201 -const ( - _af = 22 - _am = 39 - _ar = 58 - _az = 88 - _bg = 126 - _bn = 165 - _ca = 215 - _cs = 250 - _da = 257 - _de = 269 - _el = 310 - _en = 313 - _es = 318 - _et = 320 - _fa = 328 - _fi = 337 - _fil = 339 - _fr = 350 - _gu = 420 - _he = 444 - _hi = 446 - _hr = 465 - _hu = 469 - _hy = 471 - _id = 481 - _is = 504 - _it = 505 - _ja = 512 - _ka = 528 - _kk = 578 - _km = 586 - _kn = 593 - _ko = 596 - _ky = 650 - _lo = 696 - _lt = 704 - _lv = 711 - _mk = 767 - _ml = 772 - _mn = 779 - _mo = 784 - _mr = 795 - _ms = 799 - _mul = 806 - _my = 817 - _nb = 839 - _ne = 849 - _nl = 871 - _no = 879 - _pa = 925 - _pl = 947 - _pt = 960 - _ro = 988 - _ru = 994 - _sh = 1031 - _si = 1036 - _sk = 1042 - _sl = 1046 - _sq = 1073 - _sr = 1074 - _sv = 1092 - _sw = 1093 - _ta = 1104 - _te = 1121 - _th = 1131 - _tl = 1146 - _tn = 1152 - _tr = 1162 - _uk = 1198 - _ur = 1204 - _uz = 1212 - _vi = 1219 - _zh = 1321 - _zu = 1327 - _jbo = 515 - _ami = 1650 - _bnn = 2357 - _hak = 438 - _tlh = 14467 - _lb = 661 - _nv = 899 - _pwn = 12055 - _tao = 14188 - _tay = 14198 - _tsu = 14662 - _nn = 874 - _sfb = 13629 - _vgt = 15701 - _sgg = 13660 - _cmn = 3007 - _nan = 835 - _hsn = 467 -) - -const langPrivateStart = 0x2f72 - -const langPrivateEnd = 0x3179 - -// lang holds an alphabetically sorted list of ISO-639 language identifiers. -// All entries are 4 bytes. The index of the identifier (divided by 4) is the language tag. -// For 2-byte language identifiers, the two successive bytes have the following meaning: -// - if the first letter of the 2- and 3-letter ISO codes are the same: -// the second and third letter of the 3-letter ISO code. -// - otherwise: a 0 and a by 2 bits right-shifted index into altLangISO3. -// -// For 3-byte language identifiers the 4th byte is 0. -const lang tag.Index = "" + // Size: 5324 bytes - "---\x00aaaraai\x00aak\x00aau\x00abbkabi\x00abq\x00abr\x00abt\x00aby\x00a" + - "cd\x00ace\x00ach\x00ada\x00ade\x00adj\x00ady\x00adz\x00aeveaeb\x00aey" + - "\x00affragc\x00agd\x00agg\x00agm\x00ago\x00agq\x00aha\x00ahl\x00aho\x00a" + - "jg\x00akkaakk\x00ala\x00ali\x00aln\x00alt\x00ammhamm\x00amn\x00amo\x00am" + - "p\x00anrganc\x00ank\x00ann\x00any\x00aoj\x00aom\x00aoz\x00apc\x00apd\x00" + - "ape\x00apr\x00aps\x00apz\x00arraarc\x00arh\x00arn\x00aro\x00arq\x00ars" + - "\x00ary\x00arz\x00assmasa\x00ase\x00asg\x00aso\x00ast\x00ata\x00atg\x00a" + - "tj\x00auy\x00avvaavl\x00avn\x00avt\x00avu\x00awa\x00awb\x00awo\x00awx" + - "\x00ayymayb\x00azzebaakbal\x00ban\x00bap\x00bar\x00bas\x00bav\x00bax\x00" + - "bba\x00bbb\x00bbc\x00bbd\x00bbj\x00bbp\x00bbr\x00bcf\x00bch\x00bci\x00bc" + - "m\x00bcn\x00bco\x00bcq\x00bcu\x00bdd\x00beelbef\x00beh\x00bej\x00bem\x00" + - "bet\x00bew\x00bex\x00bez\x00bfd\x00bfq\x00bft\x00bfy\x00bgulbgc\x00bgn" + - "\x00bgx\x00bhihbhb\x00bhg\x00bhi\x00bhk\x00bhl\x00bho\x00bhy\x00biisbib" + - "\x00big\x00bik\x00bim\x00bin\x00bio\x00biq\x00bjh\x00bji\x00bjj\x00bjn" + - "\x00bjo\x00bjr\x00bjt\x00bjz\x00bkc\x00bkm\x00bkq\x00bku\x00bkv\x00blt" + - "\x00bmambmh\x00bmk\x00bmq\x00bmu\x00bnenbng\x00bnm\x00bnp\x00boodboj\x00" + - "bom\x00bon\x00bpy\x00bqc\x00bqi\x00bqp\x00bqv\x00brrebra\x00brh\x00brx" + - "\x00brz\x00bsosbsj\x00bsq\x00bss\x00bst\x00bto\x00btt\x00btv\x00bua\x00b" + - "uc\x00bud\x00bug\x00buk\x00bum\x00buo\x00bus\x00buu\x00bvb\x00bwd\x00bwr" + - "\x00bxh\x00bye\x00byn\x00byr\x00bys\x00byv\x00byx\x00bza\x00bze\x00bzf" + - "\x00bzh\x00bzw\x00caatcan\x00cbj\x00cch\x00ccp\x00ceheceb\x00cfa\x00cgg" + - "\x00chhachk\x00chm\x00cho\x00chp\x00chr\x00cja\x00cjm\x00cjv\x00ckb\x00c" + - "kl\x00cko\x00cky\x00cla\x00cme\x00cmg\x00cooscop\x00cps\x00crrecrh\x00cr" + - "j\x00crk\x00crl\x00crm\x00crs\x00csescsb\x00csw\x00ctd\x00cuhucvhvcyymda" + - "andad\x00daf\x00dag\x00dah\x00dak\x00dar\x00dav\x00dbd\x00dbq\x00dcc\x00" + - "ddn\x00deeuded\x00den\x00dga\x00dgh\x00dgi\x00dgl\x00dgr\x00dgz\x00dia" + - "\x00dje\x00dnj\x00dob\x00doi\x00dop\x00dow\x00dri\x00drs\x00dsb\x00dtm" + - "\x00dtp\x00dts\x00dty\x00dua\x00duc\x00dud\x00dug\x00dvivdva\x00dww\x00d" + - "yo\x00dyu\x00dzzodzg\x00ebu\x00eeweefi\x00egl\x00egy\x00eka\x00eky\x00el" + - "llema\x00emi\x00enngenn\x00enq\x00eopoeri\x00es\x00\x05esu\x00etstetr" + - "\x00ett\x00etu\x00etx\x00euusewo\x00ext\x00faasfaa\x00fab\x00fag\x00fai" + - "\x00fan\x00ffulffi\x00ffm\x00fiinfia\x00fil\x00fit\x00fjijflr\x00fmp\x00" + - "foaofod\x00fon\x00for\x00fpe\x00fqs\x00frrafrc\x00frp\x00frr\x00frs\x00f" + - "ub\x00fud\x00fue\x00fuf\x00fuh\x00fuq\x00fur\x00fuv\x00fuy\x00fvr\x00fyr" + - "ygalegaa\x00gaf\x00gag\x00gah\x00gaj\x00gam\x00gan\x00gaw\x00gay\x00gba" + - "\x00gbf\x00gbm\x00gby\x00gbz\x00gcr\x00gdlagde\x00gdn\x00gdr\x00geb\x00g" + - "ej\x00gel\x00gez\x00gfk\x00ggn\x00ghs\x00gil\x00gim\x00gjk\x00gjn\x00gju" + - "\x00gkn\x00gkp\x00gllgglk\x00gmm\x00gmv\x00gnrngnd\x00gng\x00god\x00gof" + - "\x00goi\x00gom\x00gon\x00gor\x00gos\x00got\x00grb\x00grc\x00grt\x00grw" + - "\x00gsw\x00guujgub\x00guc\x00gud\x00gur\x00guw\x00gux\x00guz\x00gvlvgvf" + - "\x00gvr\x00gvs\x00gwc\x00gwi\x00gwt\x00gyi\x00haauhag\x00hak\x00ham\x00h" + - "aw\x00haz\x00hbb\x00hdy\x00heebhhy\x00hiinhia\x00hif\x00hig\x00hih\x00hi" + - "l\x00hla\x00hlu\x00hmd\x00hmt\x00hnd\x00hne\x00hnj\x00hnn\x00hno\x00homo" + - "hoc\x00hoj\x00hot\x00hrrvhsb\x00hsn\x00htathuunhui\x00hyyehzerianaian" + - "\x00iar\x00iba\x00ibb\x00iby\x00ica\x00ich\x00idndidd\x00idi\x00idu\x00i" + - "eleife\x00igboigb\x00ige\x00iiiiijj\x00ikpkikk\x00ikt\x00ikw\x00ikx\x00i" + - "lo\x00imo\x00inndinh\x00iodoiou\x00iri\x00isslittaiukuiw\x00\x03iwm\x00i" + - "ws\x00izh\x00izi\x00japnjab\x00jam\x00jbo\x00jbu\x00jen\x00jgk\x00jgo" + - "\x00ji\x00\x06jib\x00jmc\x00jml\x00jra\x00jut\x00jvavjwavkaatkaa\x00kab" + - "\x00kac\x00kad\x00kai\x00kaj\x00kam\x00kao\x00kbd\x00kbm\x00kbp\x00kbq" + - "\x00kbx\x00kby\x00kcg\x00kck\x00kcl\x00kct\x00kde\x00kdh\x00kdl\x00kdt" + - "\x00kea\x00ken\x00kez\x00kfo\x00kfr\x00kfy\x00kgonkge\x00kgf\x00kgp\x00k" + - "ha\x00khb\x00khn\x00khq\x00khs\x00kht\x00khw\x00khz\x00kiikkij\x00kiu" + - "\x00kiw\x00kjuakjd\x00kjg\x00kjs\x00kjy\x00kkazkkc\x00kkj\x00klalkln\x00" + - "klq\x00klt\x00klx\x00kmhmkmb\x00kmh\x00kmo\x00kms\x00kmu\x00kmw\x00knank" + - "nf\x00knp\x00koorkoi\x00kok\x00kol\x00kos\x00koz\x00kpe\x00kpf\x00kpo" + - "\x00kpr\x00kpx\x00kqb\x00kqf\x00kqs\x00kqy\x00kraukrc\x00kri\x00krj\x00k" + - "rl\x00krs\x00kru\x00ksasksb\x00ksd\x00ksf\x00ksh\x00ksj\x00ksr\x00ktb" + - "\x00ktm\x00kto\x00kuurkub\x00kud\x00kue\x00kuj\x00kum\x00kun\x00kup\x00k" + - "us\x00kvomkvg\x00kvr\x00kvx\x00kw\x00\x01kwj\x00kwo\x00kxa\x00kxc\x00kxm" + - "\x00kxp\x00kxw\x00kxz\x00kyirkye\x00kyx\x00kzr\x00laatlab\x00lad\x00lag" + - "\x00lah\x00laj\x00las\x00lbtzlbe\x00lbu\x00lbw\x00lcm\x00lcp\x00ldb\x00l" + - "ed\x00lee\x00lem\x00lep\x00leq\x00leu\x00lez\x00lguglgg\x00liimlia\x00li" + - "d\x00lif\x00lig\x00lih\x00lij\x00lis\x00ljp\x00lki\x00lkt\x00lle\x00lln" + - "\x00lmn\x00lmo\x00lmp\x00lninlns\x00lnu\x00loaoloj\x00lok\x00lol\x00lor" + - "\x00los\x00loz\x00lrc\x00ltitltg\x00luublua\x00luo\x00luy\x00luz\x00lvav" + - "lwl\x00lzh\x00lzz\x00mad\x00maf\x00mag\x00mai\x00mak\x00man\x00mas\x00ma" + - "w\x00maz\x00mbh\x00mbo\x00mbq\x00mbu\x00mbw\x00mci\x00mcp\x00mcq\x00mcr" + - "\x00mcu\x00mda\x00mde\x00mdf\x00mdh\x00mdj\x00mdr\x00mdx\x00med\x00mee" + - "\x00mek\x00men\x00mer\x00met\x00meu\x00mfa\x00mfe\x00mfn\x00mfo\x00mfq" + - "\x00mglgmgh\x00mgl\x00mgo\x00mgp\x00mgy\x00mhahmhi\x00mhl\x00mirimif\x00" + - "min\x00mis\x00miw\x00mkkdmki\x00mkl\x00mkp\x00mkw\x00mlalmle\x00mlp\x00m" + - "ls\x00mmo\x00mmu\x00mmx\x00mnonmna\x00mnf\x00mni\x00mnw\x00moolmoa\x00mo" + - "e\x00moh\x00mos\x00mox\x00mpp\x00mps\x00mpt\x00mpx\x00mql\x00mrarmrd\x00" + - "mrj\x00mro\x00mssamtltmtc\x00mtf\x00mti\x00mtr\x00mua\x00mul\x00mur\x00m" + - "us\x00mva\x00mvn\x00mvy\x00mwk\x00mwr\x00mwv\x00mxc\x00mxm\x00myyamyk" + - "\x00mym\x00myv\x00myw\x00myx\x00myz\x00mzk\x00mzm\x00mzn\x00mzp\x00mzw" + - "\x00mzz\x00naaunac\x00naf\x00nah\x00nak\x00nan\x00nap\x00naq\x00nas\x00n" + - "bobnca\x00nce\x00ncf\x00nch\x00nco\x00ncu\x00nddendc\x00nds\x00neepneb" + - "\x00new\x00nex\x00nfr\x00ngdonga\x00ngb\x00ngl\x00nhb\x00nhe\x00nhw\x00n" + - "if\x00nii\x00nij\x00nin\x00niu\x00niy\x00niz\x00njo\x00nkg\x00nko\x00nll" + - "dnmg\x00nmz\x00nnnonnf\x00nnh\x00nnk\x00nnm\x00noornod\x00noe\x00non\x00" + - "nop\x00nou\x00nqo\x00nrblnrb\x00nsk\x00nsn\x00nso\x00nss\x00ntm\x00ntr" + - "\x00nui\x00nup\x00nus\x00nuv\x00nux\x00nvavnwb\x00nxq\x00nxr\x00nyyanym" + - "\x00nyn\x00nzi\x00occiogc\x00ojjiokr\x00okv\x00omrmong\x00onn\x00ons\x00" + - "opm\x00orrioro\x00oru\x00osssosa\x00ota\x00otk\x00ozm\x00paanpag\x00pal" + - "\x00pam\x00pap\x00pau\x00pbi\x00pcd\x00pcm\x00pdc\x00pdt\x00ped\x00peo" + - "\x00pex\x00pfl\x00phl\x00phn\x00pilipil\x00pip\x00pka\x00pko\x00plolpla" + - "\x00pms\x00png\x00pnn\x00pnt\x00pon\x00ppo\x00pra\x00prd\x00prg\x00psusp" + - "ss\x00ptorptp\x00puu\x00pwa\x00quuequc\x00qug\x00rai\x00raj\x00rao\x00rc" + - "f\x00rej\x00rel\x00res\x00rgn\x00rhg\x00ria\x00rif\x00rjs\x00rkt\x00rmoh" + - "rmf\x00rmo\x00rmt\x00rmu\x00rnunrna\x00rng\x00roonrob\x00rof\x00roo\x00r" + - "ro\x00rtm\x00ruusrue\x00rug\x00rw\x00\x04rwk\x00rwo\x00ryu\x00saansaf" + - "\x00sah\x00saq\x00sas\x00sat\x00sav\x00saz\x00sba\x00sbe\x00sbp\x00scrds" + - "ck\x00scl\x00scn\x00sco\x00scs\x00sdndsdc\x00sdh\x00semesef\x00seh\x00se" + - "i\x00ses\x00sgagsga\x00sgs\x00sgw\x00sgz\x00sh\x00\x02shi\x00shk\x00shn" + - "\x00shu\x00siinsid\x00sig\x00sil\x00sim\x00sjr\x00sklkskc\x00skr\x00sks" + - "\x00sllvsld\x00sli\x00sll\x00sly\x00smmosma\x00smi\x00smj\x00smn\x00smp" + - "\x00smq\x00sms\x00snnasnc\x00snk\x00snp\x00snx\x00sny\x00soomsok\x00soq" + - "\x00sou\x00soy\x00spd\x00spl\x00sps\x00sqqisrrpsrb\x00srn\x00srr\x00srx" + - "\x00ssswssd\x00ssg\x00ssy\x00stotstk\x00stq\x00suunsua\x00sue\x00suk\x00" + - "sur\x00sus\x00svweswwaswb\x00swc\x00swg\x00swp\x00swv\x00sxn\x00sxw\x00s" + - "yl\x00syr\x00szl\x00taamtaj\x00tal\x00tan\x00taq\x00tbc\x00tbd\x00tbf" + - "\x00tbg\x00tbo\x00tbw\x00tbz\x00tci\x00tcy\x00tdd\x00tdg\x00tdh\x00teelt" + - "ed\x00tem\x00teo\x00tet\x00tfi\x00tggktgc\x00tgo\x00tgu\x00thhathl\x00th" + - "q\x00thr\x00tiirtif\x00tig\x00tik\x00tim\x00tio\x00tiv\x00tkuktkl\x00tkr" + - "\x00tkt\x00tlgltlf\x00tlx\x00tly\x00tmh\x00tmy\x00tnsntnh\x00toontof\x00" + - "tog\x00toq\x00tpi\x00tpm\x00tpz\x00tqo\x00trurtru\x00trv\x00trw\x00tssot" + - "sd\x00tsf\x00tsg\x00tsj\x00tsw\x00ttatttd\x00tte\x00ttj\x00ttr\x00tts" + - "\x00ttt\x00tuh\x00tul\x00tum\x00tuq\x00tvd\x00tvl\x00tvu\x00twwitwh\x00t" + - "wq\x00txg\x00tyahtya\x00tyv\x00tzm\x00ubu\x00udm\x00ugiguga\x00ukkruli" + - "\x00umb\x00und\x00unr\x00unx\x00urrduri\x00urt\x00urw\x00usa\x00utr\x00u" + - "vh\x00uvl\x00uzzbvag\x00vai\x00van\x00veenvec\x00vep\x00viievic\x00viv" + - "\x00vls\x00vmf\x00vmw\x00voolvot\x00vro\x00vun\x00vut\x00walnwae\x00waj" + - "\x00wal\x00wan\x00war\x00wbp\x00wbq\x00wbr\x00wci\x00wer\x00wgi\x00whg" + - "\x00wib\x00wiu\x00wiv\x00wja\x00wji\x00wls\x00wmo\x00wnc\x00wni\x00wnu" + - "\x00woolwob\x00wos\x00wrs\x00wsk\x00wtm\x00wuu\x00wuv\x00wwa\x00xav\x00x" + - "bi\x00xcr\x00xes\x00xhhoxla\x00xlc\x00xld\x00xmf\x00xmn\x00xmr\x00xna" + - "\x00xnr\x00xog\x00xon\x00xpr\x00xrb\x00xsa\x00xsi\x00xsm\x00xsr\x00xwe" + - "\x00yam\x00yao\x00yap\x00yas\x00yat\x00yav\x00yay\x00yaz\x00yba\x00ybb" + - "\x00yby\x00yer\x00ygr\x00ygw\x00yiidyko\x00yle\x00ylg\x00yll\x00yml\x00y" + - "ooryon\x00yrb\x00yre\x00yrl\x00yss\x00yua\x00yue\x00yuj\x00yut\x00yuw" + - "\x00zahazag\x00zbl\x00zdj\x00zea\x00zgh\x00zhhozhx\x00zia\x00zlm\x00zmi" + - "\x00zne\x00zuulzxx\x00zza\x00\xff\xff\xff\xff" - -const langNoIndexOffset = 1330 - -// langNoIndex is a bit vector of all 3-letter language codes that are not used as an index -// in lookup tables. The language ids for these language codes are derived directly -// from the letters and are not consecutive. -// Size: 2197 bytes, 2197 elements -var langNoIndex = [2197]uint8{ - // Entry 0 - 3F - 0xff, 0xf8, 0xed, 0xfe, 0xeb, 0xd3, 0x3b, 0xd2, - 0xfb, 0xbf, 0x7a, 0xfa, 0x37, 0x1d, 0x3c, 0x57, - 0x6e, 0x97, 0x73, 0x38, 0xfb, 0xea, 0xbf, 0x70, - 0xad, 0x03, 0xff, 0xff, 0xcf, 0x05, 0x84, 0x72, - 0xe9, 0xbf, 0xfd, 0xbf, 0xbf, 0xf7, 0xfd, 0x77, - 0x0f, 0xff, 0xef, 0x6f, 0xff, 0xfb, 0xdf, 0xe2, - 0xc9, 0xf8, 0x7f, 0x7e, 0x4d, 0xbc, 0x0a, 0x6a, - 0x7c, 0xea, 0xe3, 0xfa, 0x7a, 0xbf, 0x67, 0xff, - // Entry 40 - 7F - 0xff, 0xff, 0xff, 0xdf, 0x2a, 0x54, 0x91, 0xc0, - 0x5d, 0xe3, 0x97, 0x14, 0x07, 0x20, 0xdd, 0xed, - 0x9f, 0x3f, 0xc9, 0x21, 0xf8, 0x3f, 0x94, 0x35, - 0x7c, 0x5f, 0xff, 0x5f, 0x8e, 0x6e, 0xdf, 0xff, - 0xff, 0xff, 0x55, 0x7c, 0xd3, 0xfd, 0xbf, 0xb5, - 0x7b, 0xdf, 0x7f, 0xf7, 0xca, 0xfe, 0xdb, 0xa3, - 0xa8, 0xff, 0x1f, 0x67, 0x7d, 0xeb, 0xef, 0xce, - 0xff, 0xff, 0x9f, 0xff, 0xb7, 0xef, 0xfe, 0xcf, - // Entry 80 - BF - 0xdb, 0xff, 0xf3, 0xcd, 0xfb, 0x7f, 0xff, 0xff, - 0xbb, 0xee, 0xf7, 0xbd, 0xdb, 0xff, 0x5f, 0xf7, - 0xfd, 0xf2, 0xfd, 0xff, 0x5e, 0x2f, 0x3b, 0xba, - 0x7e, 0xff, 0xff, 0xfe, 0xf7, 0xff, 0xdd, 0xff, - 0xfd, 0xdf, 0xfb, 0xfe, 0x9d, 0xb4, 0xd3, 0xff, - 0xef, 0xff, 0xdf, 0xf7, 0x7f, 0xb7, 0xfd, 0xd5, - 0xa5, 0x77, 0x40, 0xff, 0x9c, 0xc1, 0x41, 0x2c, - 0x08, 0x21, 0x41, 0x00, 0x50, 0x40, 0x00, 0x80, - // Entry C0 - FF - 0xfb, 0x4a, 0xf2, 0x9f, 0xb4, 0x42, 0x41, 0x96, - 0x1b, 0x14, 0x08, 0xf3, 0x2b, 0xe7, 0x17, 0x56, - 0x05, 0x7d, 0x0e, 0x1c, 0x37, 0x7f, 0xf3, 0xef, - 0x97, 0xff, 0x5d, 0x38, 0x64, 0x08, 0x00, 0x10, - 0xbc, 0x85, 0xaf, 0xdf, 0xff, 0xff, 0x7b, 0x35, - 0x3e, 0xc7, 0xc7, 0xdf, 0xff, 0x01, 0x81, 0x00, - 0xb0, 0x05, 0x80, 0x00, 0x20, 0x00, 0x00, 0x03, - 0x40, 0x00, 0x40, 0x92, 0x21, 0x50, 0xb1, 0x5d, - // Entry 100 - 13F - 0xfd, 0xdc, 0xbe, 0x5e, 0x00, 0x00, 0x02, 0x64, - 0x0d, 0x19, 0x41, 0xdf, 0x79, 0x22, 0x00, 0x00, - 0x00, 0x5e, 0x64, 0xdc, 0x24, 0xe5, 0xd9, 0xe3, - 0xfe, 0xff, 0xfd, 0xcb, 0x9f, 0x14, 0x41, 0x0c, - 0x86, 0x00, 0xd1, 0x00, 0xf0, 0xc7, 0x67, 0x5f, - 0x56, 0x99, 0x5e, 0xb5, 0x6c, 0xaf, 0x03, 0x00, - 0x02, 0x00, 0x00, 0x00, 0xc0, 0x37, 0xda, 0x56, - 0x90, 0x6d, 0x01, 0x2e, 0x96, 0x69, 0x20, 0xfb, - // Entry 140 - 17F - 0xff, 0x3f, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x16, - 0x03, 0x00, 0x00, 0xb0, 0x14, 0x23, 0x50, 0x06, - 0x0a, 0x00, 0x01, 0x00, 0x00, 0x10, 0x11, 0x09, - 0x00, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x10, - 0x00, 0x00, 0x44, 0x00, 0x00, 0x10, 0x00, 0x05, - 0x08, 0x00, 0x00, 0x05, 0x00, 0x80, 0x28, 0x04, - 0x00, 0x00, 0x40, 0xd5, 0x2d, 0x00, 0x64, 0x35, - 0x24, 0x52, 0xf4, 0xd5, 0xbf, 0x62, 0xc9, 0x03, - // Entry 180 - 1BF - 0x00, 0x80, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x13, 0x39, 0x01, 0xdd, 0x57, 0x98, - 0x21, 0x18, 0x81, 0x08, 0x00, 0x01, 0x40, 0x82, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x40, 0x00, 0x44, 0x00, 0x00, 0x80, 0xea, - 0xa9, 0x39, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - // Entry 1C0 - 1FF - 0x00, 0x03, 0x28, 0x05, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x20, 0x04, 0xa6, 0x00, 0x04, 0x00, 0x00, - 0x81, 0x50, 0x00, 0x00, 0x00, 0x11, 0x84, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x55, - 0x02, 0x10, 0x08, 0x04, 0x00, 0x00, 0x00, 0x40, - 0x30, 0x83, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x1e, 0xcd, 0xbf, 0x7a, 0xbf, - // Entry 200 - 23F - 0xdf, 0xc3, 0x83, 0x82, 0xc0, 0xfb, 0x57, 0x27, - 0xed, 0x55, 0xe7, 0x01, 0x00, 0x20, 0xb2, 0xc5, - 0xa4, 0x45, 0x25, 0x9b, 0x02, 0xdf, 0xe1, 0xdf, - 0x03, 0x44, 0x08, 0x90, 0x01, 0x04, 0x81, 0xe3, - 0x92, 0x54, 0xdb, 0x28, 0xd3, 0x5f, 0xfe, 0x6d, - 0x79, 0xed, 0x1c, 0x7f, 0x04, 0x08, 0x00, 0x01, - 0x21, 0x12, 0x64, 0x5f, 0xdd, 0x0e, 0x85, 0x4f, - 0x40, 0x40, 0x00, 0x04, 0xf1, 0xfd, 0x3d, 0x54, - // Entry 240 - 27F - 0xe8, 0x03, 0xb4, 0x27, 0x23, 0x0d, 0x00, 0x00, - 0x20, 0x7b, 0x78, 0x02, 0x07, 0x84, 0x00, 0xf0, - 0xbb, 0x7e, 0x5a, 0x00, 0x18, 0x04, 0x81, 0x00, - 0x00, 0x00, 0x80, 0x10, 0x90, 0x1c, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, 0x00, 0x04, - 0x08, 0xa0, 0x70, 0xa5, 0x0c, 0x40, 0x00, 0x00, - 0x91, 0x24, 0x04, 0x68, 0x00, 0x20, 0x70, 0xff, - 0x7b, 0x7f, 0x70, 0x00, 0x05, 0x9b, 0xdd, 0x66, - // Entry 280 - 2BF - 0x03, 0x00, 0x11, 0x00, 0x00, 0x00, 0x40, 0x05, - 0xb5, 0xb6, 0x80, 0x08, 0x04, 0x00, 0x04, 0x51, - 0xe2, 0xef, 0xfd, 0x3f, 0x05, 0x09, 0x08, 0x05, - 0x40, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, - 0x0c, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x60, - 0xe7, 0x48, 0x00, 0x81, 0x20, 0xc0, 0x05, 0x80, - 0x03, 0x00, 0x00, 0x00, 0x8c, 0x50, 0x40, 0x04, - 0x84, 0x47, 0x84, 0x40, 0x20, 0x10, 0x00, 0x20, - // Entry 2C0 - 2FF - 0x02, 0x50, 0x80, 0x11, 0x00, 0x99, 0x6c, 0xe2, - 0x50, 0x27, 0x1d, 0x11, 0x29, 0x0e, 0x59, 0xe9, - 0x33, 0x08, 0x00, 0x20, 0x04, 0x40, 0x10, 0x00, - 0x00, 0x00, 0x50, 0x44, 0x92, 0x49, 0xd6, 0x5d, - 0xa7, 0x81, 0x47, 0x97, 0xfb, 0x00, 0x10, 0x00, - 0x08, 0x00, 0x80, 0x00, 0x40, 0x04, 0x00, 0x01, - 0x02, 0x00, 0x01, 0x40, 0x80, 0x00, 0x40, 0x08, - 0xd8, 0xeb, 0xf6, 0x39, 0xc4, 0x8d, 0x12, 0x00, - // Entry 300 - 33F - 0x00, 0x0c, 0x04, 0x01, 0x20, 0x20, 0xdd, 0xa0, - 0x01, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x04, 0x10, 0xd0, 0x9d, 0x95, 0x13, 0x04, 0x80, - 0x00, 0x01, 0xd0, 0x16, 0x40, 0x00, 0x10, 0xb0, - 0x10, 0x62, 0x4c, 0xd2, 0x02, 0x01, 0x4a, 0x00, - 0x46, 0x04, 0x00, 0x08, 0x02, 0x00, 0x20, 0x80, - 0x00, 0x80, 0x06, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x00, 0xf0, 0xd8, 0x6f, 0x15, 0x02, 0x08, 0x00, - // Entry 340 - 37F - 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, - 0x00, 0x10, 0x00, 0x00, 0x00, 0xf0, 0x84, 0xe3, - 0xdd, 0xbf, 0xf9, 0xf9, 0x3b, 0x7f, 0x7f, 0xdb, - 0xfd, 0xfc, 0xfe, 0xdf, 0xff, 0xfd, 0xff, 0xf6, - 0xfb, 0xfc, 0xf7, 0x1f, 0xff, 0xb3, 0x6c, 0xff, - 0xd9, 0xad, 0xdf, 0xfe, 0xef, 0xba, 0xdf, 0xff, - 0xff, 0xff, 0xb7, 0xdd, 0x7d, 0xbf, 0xab, 0x7f, - 0xfd, 0xfd, 0xdf, 0x2f, 0x9c, 0xdf, 0xf3, 0x6f, - // Entry 380 - 3BF - 0xdf, 0xdd, 0xff, 0xfb, 0xee, 0xd2, 0xab, 0x5f, - 0xd5, 0xdf, 0x7f, 0xff, 0xeb, 0xff, 0xe4, 0x4d, - 0xf9, 0xff, 0xfe, 0xf7, 0xfd, 0xdf, 0xfb, 0xbf, - 0xee, 0xdb, 0x6f, 0xef, 0xff, 0x7f, 0xff, 0xff, - 0xf7, 0x5f, 0xd3, 0x3b, 0xfd, 0xd9, 0xdf, 0xeb, - 0xbc, 0x08, 0x05, 0x24, 0xff, 0x07, 0x70, 0xfe, - 0xe6, 0x5e, 0x00, 0x08, 0x00, 0x83, 0x7d, 0x1f, - 0x06, 0xe6, 0x72, 0x60, 0xd1, 0x3c, 0x7f, 0x44, - // Entry 3C0 - 3FF - 0x02, 0x30, 0x9f, 0x7a, 0x16, 0xbd, 0x7f, 0x57, - 0xf2, 0xff, 0x31, 0xff, 0xf2, 0x1e, 0x90, 0xf7, - 0xf1, 0xf9, 0x45, 0x80, 0x01, 0x02, 0x00, 0x20, - 0x40, 0x54, 0x9f, 0x8a, 0xdf, 0xf9, 0x6e, 0x11, - 0x86, 0x51, 0xc0, 0xf3, 0xfb, 0x47, 0x40, 0x03, - 0x05, 0xd1, 0x50, 0x5c, 0x00, 0x40, 0x00, 0x10, - 0x04, 0x02, 0x00, 0x00, 0x0a, 0x00, 0x17, 0xd2, - 0xb9, 0xfd, 0xfc, 0xba, 0xfe, 0xef, 0xc7, 0xbe, - // Entry 400 - 43F - 0x53, 0x6f, 0xdf, 0xe7, 0xdb, 0x65, 0xbb, 0x7f, - 0xfa, 0xff, 0x77, 0xf3, 0xef, 0xbf, 0xfd, 0xf7, - 0xdf, 0xdf, 0x9b, 0x7f, 0xff, 0xff, 0x7f, 0x6f, - 0xf7, 0xfb, 0xeb, 0xdf, 0xbc, 0xff, 0xbf, 0x6b, - 0x7b, 0xfb, 0xff, 0xce, 0x76, 0xbd, 0xf7, 0xf7, - 0xdf, 0xdc, 0xf7, 0xf7, 0xff, 0xdf, 0xf3, 0xfe, - 0xef, 0xff, 0xff, 0xff, 0xb6, 0x7f, 0x7f, 0xde, - 0xf7, 0xb9, 0xeb, 0x77, 0xff, 0xfb, 0xbf, 0xdf, - // Entry 440 - 47F - 0xfd, 0xfe, 0xfb, 0xff, 0xfe, 0xeb, 0x1f, 0x7d, - 0x2f, 0xfd, 0xb6, 0xb5, 0xa5, 0xfc, 0xff, 0xfd, - 0x7f, 0x4e, 0xbf, 0x8f, 0xae, 0xff, 0xee, 0xdf, - 0x7f, 0xf7, 0x73, 0x02, 0x02, 0x04, 0xfc, 0xf7, - 0xff, 0xb7, 0xd7, 0xef, 0xfe, 0xcd, 0xf5, 0xce, - 0xe2, 0x8e, 0xe7, 0xbf, 0xb7, 0xff, 0x56, 0xfd, - 0xcd, 0xff, 0xfb, 0xff, 0xdf, 0xd7, 0xea, 0xff, - 0xe5, 0x5f, 0x6d, 0x0f, 0xa7, 0x51, 0x06, 0xc4, - // Entry 480 - 4BF - 0x93, 0x50, 0x5d, 0xaf, 0xa6, 0xff, 0x99, 0xfb, - 0x63, 0x1d, 0x53, 0xff, 0xef, 0xb7, 0x35, 0x20, - 0x14, 0x00, 0x55, 0x51, 0xc2, 0x65, 0xf5, 0x41, - 0xe2, 0xff, 0xfc, 0xdf, 0x02, 0x85, 0xc5, 0x05, - 0x00, 0x22, 0x00, 0x74, 0x69, 0x10, 0x08, 0x05, - 0x41, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x51, 0x20, 0x05, 0x04, 0x01, 0x00, 0x00, - 0x06, 0x11, 0x20, 0x00, 0x18, 0x01, 0x92, 0xf1, - // Entry 4C0 - 4FF - 0xfd, 0x47, 0x69, 0x06, 0x95, 0x06, 0x57, 0xed, - 0xfb, 0x4d, 0x1c, 0x6b, 0x83, 0x04, 0x62, 0x40, - 0x00, 0x11, 0x42, 0x00, 0x00, 0x00, 0x54, 0x83, - 0xb8, 0x4f, 0x10, 0x8e, 0x89, 0x46, 0xde, 0xf7, - 0x13, 0x31, 0x00, 0x20, 0x00, 0x00, 0x00, 0x90, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x10, 0x00, - 0x01, 0x00, 0x00, 0xf0, 0x5b, 0xf4, 0xbe, 0x3d, - 0xbe, 0xcf, 0xf7, 0xaf, 0x42, 0x04, 0x84, 0x41, - // Entry 500 - 53F - 0x30, 0xff, 0x79, 0x72, 0x04, 0x00, 0x00, 0x49, - 0x2d, 0x14, 0x27, 0x5f, 0xed, 0xf1, 0x3f, 0xe7, - 0x3f, 0x00, 0x00, 0x02, 0xc6, 0xa0, 0x1e, 0xf8, - 0xbb, 0xff, 0xfd, 0xfb, 0xb7, 0xfd, 0xe7, 0xf7, - 0xfd, 0xfc, 0xd5, 0xed, 0x47, 0xf4, 0x7e, 0x10, - 0x01, 0x01, 0x84, 0x6d, 0xff, 0xf7, 0xdd, 0xf9, - 0x5b, 0x05, 0x86, 0xed, 0xf5, 0x77, 0xbd, 0x3c, - 0x00, 0x00, 0x00, 0x42, 0x71, 0x42, 0x00, 0x40, - // Entry 540 - 57F - 0x00, 0x00, 0x01, 0x43, 0x19, 0x24, 0x08, 0x00, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - // Entry 580 - 5BF - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xab, 0xbd, 0xe7, 0x57, 0xee, 0x13, 0x5d, - 0x09, 0xc1, 0x40, 0x21, 0xfa, 0x17, 0x01, 0x80, - 0x00, 0x00, 0x00, 0x00, 0xf0, 0xce, 0xfb, 0xbf, - 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, - 0x00, 0x30, 0x15, 0xa3, 0x10, 0x00, 0x00, 0x00, - 0x11, 0x04, 0x16, 0x00, 0x00, 0x02, 0x20, 0x81, - 0xa3, 0x01, 0x50, 0x00, 0x00, 0x83, 0x11, 0x40, - // Entry 5C0 - 5FF - 0x00, 0x00, 0x00, 0xf0, 0xdd, 0x7b, 0xbe, 0x02, - 0xaa, 0x10, 0x5d, 0x98, 0x52, 0x00, 0x80, 0x20, - 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x02, 0x02, - 0x3d, 0x40, 0x10, 0x02, 0x10, 0x61, 0x5a, 0x9d, - 0x31, 0x00, 0x00, 0x00, 0x01, 0x18, 0x02, 0x20, - 0x00, 0x00, 0x01, 0x00, 0x42, 0x00, 0x20, 0x00, - 0x00, 0x1f, 0xdf, 0xd2, 0xb9, 0xff, 0xfd, 0x3f, - 0x1f, 0x98, 0xcf, 0x9c, 0xff, 0xaf, 0x5f, 0xfe, - // Entry 600 - 63F - 0x7b, 0x4b, 0x40, 0x10, 0xe1, 0xfd, 0xaf, 0xd9, - 0xb7, 0xf6, 0xfb, 0xb3, 0xc7, 0xff, 0x6f, 0xf1, - 0x73, 0xb1, 0x7f, 0x9f, 0x7f, 0xbd, 0xfc, 0xb7, - 0xee, 0x1c, 0xfa, 0xcb, 0xef, 0xdd, 0xf9, 0xbd, - 0x6e, 0xae, 0x55, 0xfd, 0x6e, 0x81, 0x76, 0x9f, - 0xd4, 0x77, 0xf5, 0x7d, 0xfb, 0xff, 0xeb, 0xfe, - 0xbe, 0x5f, 0x46, 0x5b, 0xe9, 0x5f, 0x50, 0x18, - 0x02, 0xfa, 0xf7, 0x9d, 0x15, 0x97, 0x05, 0x0f, - // Entry 640 - 67F - 0x75, 0xc4, 0x7d, 0x81, 0x92, 0xf5, 0x57, 0x6c, - 0xff, 0xe4, 0xef, 0x6f, 0xff, 0xfc, 0xdd, 0xde, - 0xfc, 0xfd, 0x76, 0x5f, 0x7a, 0x3f, 0x00, 0x98, - 0x02, 0xfb, 0xa3, 0xef, 0xf3, 0xd6, 0xf2, 0xff, - 0xb9, 0xda, 0x7d, 0xd0, 0x3e, 0x15, 0x7b, 0xb4, - 0xf5, 0x3e, 0xff, 0xff, 0xf1, 0xf7, 0xff, 0xe7, - 0x5f, 0xff, 0xff, 0x9e, 0xdf, 0xf6, 0xd7, 0xb9, - 0xef, 0x27, 0x80, 0xbb, 0xc5, 0xff, 0xff, 0xe3, - // Entry 680 - 6BF - 0x97, 0x9d, 0xbf, 0x9f, 0xf7, 0xc7, 0xfd, 0x37, - 0xce, 0x7f, 0x44, 0x1d, 0x73, 0x7f, 0xf8, 0xda, - 0x5d, 0xce, 0x7d, 0x06, 0xb9, 0xea, 0x79, 0xa0, - 0x1a, 0x20, 0x00, 0x30, 0x02, 0x04, 0x24, 0x08, - 0x04, 0x00, 0x00, 0x40, 0xd4, 0x02, 0x04, 0x00, - 0x00, 0x04, 0x00, 0x04, 0x00, 0x20, 0x09, 0x06, - 0x50, 0x00, 0x08, 0x00, 0x00, 0x00, 0x24, 0x00, - 0x04, 0x00, 0x10, 0xdc, 0x58, 0xd7, 0x0d, 0x0f, - // Entry 6C0 - 6FF - 0x54, 0x4d, 0xf1, 0x16, 0x44, 0xd5, 0x42, 0x08, - 0x40, 0x02, 0x00, 0x40, 0x00, 0x08, 0x00, 0x00, - 0x00, 0xdc, 0xfb, 0xcb, 0x0e, 0x58, 0x48, 0x41, - 0x24, 0x20, 0x04, 0x00, 0x30, 0x12, 0x40, 0x00, - 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x80, 0x10, 0x10, 0xab, - 0x6d, 0x93, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x80, 0x80, 0x25, 0x00, 0x00, - // Entry 700 - 73F - 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, - 0x80, 0x86, 0xc2, 0x00, 0x00, 0x01, 0x00, 0x01, - 0xff, 0x18, 0x02, 0x00, 0x02, 0xf0, 0xfd, 0x79, - 0x3b, 0x00, 0x25, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, - 0x03, 0x00, 0x09, 0x20, 0x00, 0x00, 0x01, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - // Entry 740 - 77F - 0x00, 0x00, 0x00, 0xef, 0xd5, 0xfd, 0xcf, 0x7e, - 0xb0, 0x11, 0x00, 0x00, 0x00, 0x92, 0x01, 0x46, - 0xcd, 0xf9, 0x5c, 0x00, 0x01, 0x00, 0x30, 0x04, - 0x04, 0x55, 0x00, 0x01, 0x04, 0xf4, 0x3f, 0x4a, - 0x01, 0x00, 0x00, 0xb0, 0x80, 0x20, 0x55, 0x75, - 0x97, 0x7c, 0xdf, 0x31, 0xcc, 0x68, 0xd1, 0x03, - 0xd5, 0x57, 0x27, 0x14, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x2c, 0xf7, 0xcb, 0x1f, 0x14, 0x60, - // Entry 780 - 7BF - 0x83, 0x68, 0x01, 0x10, 0x8b, 0x38, 0x8a, 0x01, - 0x00, 0x00, 0x20, 0x00, 0x24, 0x44, 0x00, 0x00, - 0x10, 0x03, 0x31, 0x02, 0x01, 0x00, 0x00, 0xf0, - 0xf5, 0xff, 0xd5, 0x97, 0xbc, 0x70, 0xd6, 0x78, - 0x78, 0x15, 0x50, 0x05, 0xa4, 0x84, 0xa9, 0x41, - 0x00, 0x00, 0x00, 0x6b, 0x39, 0x52, 0x74, 0x40, - 0xe8, 0x30, 0x90, 0x6a, 0x92, 0x00, 0x00, 0x02, - 0xff, 0xef, 0xff, 0x4b, 0x85, 0x53, 0xf4, 0xed, - // Entry 7C0 - 7FF - 0xdd, 0xbf, 0xf2, 0x5d, 0xc7, 0x0c, 0xd5, 0x42, - 0xfc, 0xff, 0xf7, 0x1f, 0x00, 0x80, 0x40, 0x56, - 0xcc, 0x16, 0x9e, 0xea, 0x35, 0x7d, 0xef, 0xff, - 0xbd, 0xa4, 0xaf, 0x01, 0x44, 0x18, 0x01, 0x4d, - 0x4e, 0x4a, 0x08, 0x50, 0x28, 0x30, 0xe0, 0x80, - 0x10, 0x20, 0x24, 0x00, 0xff, 0x2f, 0xd3, 0x60, - 0xfe, 0x01, 0x02, 0x88, 0x2a, 0x40, 0x16, 0x01, - 0x01, 0x15, 0x2b, 0x3c, 0x01, 0x00, 0x00, 0x10, - // Entry 800 - 83F - 0x90, 0x49, 0x41, 0x02, 0x02, 0x01, 0xe1, 0xbf, - 0xbf, 0x03, 0x00, 0x00, 0x10, 0xdc, 0xa3, 0xd1, - 0x40, 0x9c, 0x44, 0xdf, 0xf5, 0x8f, 0x66, 0xb3, - 0x55, 0x20, 0xd4, 0xc1, 0xd8, 0x30, 0x3d, 0x80, - 0x00, 0x00, 0x00, 0x04, 0xd4, 0x11, 0xc5, 0x84, - 0x2f, 0x50, 0x00, 0x22, 0x50, 0x6e, 0xbd, 0x93, - 0x07, 0x00, 0x20, 0x10, 0x84, 0xb2, 0x45, 0x10, - 0x06, 0x44, 0x00, 0x00, 0x12, 0x02, 0x11, 0x00, - // Entry 840 - 87F - 0xf0, 0xfb, 0xfd, 0x7f, 0x05, 0x00, 0x16, 0x89, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x03, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x30, 0x02, 0x28, - 0x84, 0x00, 0x21, 0xc0, 0x23, 0x24, 0x00, 0x00, - 0x00, 0xcb, 0xe4, 0x3a, 0x46, 0x88, 0x54, 0xf1, - 0xef, 0xff, 0x7f, 0x12, 0x01, 0x01, 0x84, 0x50, - 0x07, 0xfc, 0xff, 0xff, 0x0f, 0x01, 0x00, 0x40, - 0x10, 0x38, 0x01, 0x01, 0x1c, 0x12, 0x40, 0xe1, - // Entry 880 - 8BF - 0x76, 0x16, 0x08, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x24, - 0x0a, 0x00, 0x80, 0x00, 0x00, -} - -// altLangISO3 holds an alphabetically sorted list of 3-letter language code alternatives -// to 2-letter language codes that cannot be derived using the method described above. -// Each 3-letter code is followed by its 1-byte langID. -const altLangISO3 tag.Index = "---\x00cor\x00hbs\x01heb\x02kin\x03spa\x04yid\x05\xff\xff\xff\xff" - -// altLangIndex is used to convert indexes in altLangISO3 to langIDs. -// Size: 12 bytes, 6 elements -var altLangIndex = [6]uint16{ - 0x0281, 0x0407, 0x01fb, 0x03e5, 0x013e, 0x0208, -} - -// AliasMap maps langIDs to their suggested replacements. -// Size: 772 bytes, 193 elements -var AliasMap = [193]FromTo{ - 0: {From: 0x82, To: 0x88}, - 1: {From: 0x187, To: 0x1ae}, - 2: {From: 0x1f3, To: 0x1e1}, - 3: {From: 0x1fb, To: 0x1bc}, - 4: {From: 0x208, To: 0x512}, - 5: {From: 0x20f, To: 0x20e}, - 6: {From: 0x310, To: 0x3dc}, - 7: {From: 0x347, To: 0x36f}, - 8: {From: 0x407, To: 0x432}, - 9: {From: 0x47a, To: 0x153}, - 10: {From: 0x490, To: 0x451}, - 11: {From: 0x4a2, To: 0x21}, - 12: {From: 0x53e, To: 0x544}, - 13: {From: 0x58f, To: 0x12d}, - 14: {From: 0x62b, To: 0x34}, - 15: {From: 0x62f, To: 0x14}, - 16: {From: 0x630, To: 0x1eb1}, - 17: {From: 0x651, To: 0x431}, - 18: {From: 0x662, To: 0x431}, - 19: {From: 0x6ed, To: 0x3a}, - 20: {From: 0x6f8, To: 0x1d7}, - 21: {From: 0x709, To: 0x3625}, - 22: {From: 0x73e, To: 0x21a1}, - 23: {From: 0x7b3, To: 0x56}, - 24: {From: 0x7b9, To: 0x299b}, - 25: {From: 0x7c5, To: 0x58}, - 26: {From: 0x7e6, To: 0x145}, - 27: {From: 0x80c, To: 0x5a}, - 28: {From: 0x815, To: 0x8d}, - 29: {From: 0x87e, To: 0x810}, - 30: {From: 0x8a8, To: 0x8b7}, - 31: {From: 0x8c3, To: 0xee3}, - 32: {From: 0x8fa, To: 0x1dc}, - 33: {From: 0x9ef, To: 0x331}, - 34: {From: 0xa36, To: 0x2c5}, - 35: {From: 0xa3d, To: 0xbf}, - 36: {From: 0xabe, To: 0x3322}, - 37: {From: 0xb38, To: 0x529}, - 38: {From: 0xb75, To: 0x265a}, - 39: {From: 0xb7e, To: 0xbc3}, - 40: {From: 0xb9b, To: 0x44e}, - 41: {From: 0xbbc, To: 0x4229}, - 42: {From: 0xbbf, To: 0x529}, - 43: {From: 0xbfe, To: 0x2da7}, - 44: {From: 0xc2e, To: 0x3181}, - 45: {From: 0xcb9, To: 0xf3}, - 46: {From: 0xd08, To: 0xfa}, - 47: {From: 0xdc8, To: 0x11a}, - 48: {From: 0xdd7, To: 0x32d}, - 49: {From: 0xdf8, To: 0xdfb}, - 50: {From: 0xdfe, To: 0x531}, - 51: {From: 0xe01, To: 0xdf3}, - 52: {From: 0xedf, To: 0x205a}, - 53: {From: 0xee9, To: 0x222e}, - 54: {From: 0xeee, To: 0x2e9a}, - 55: {From: 0xf39, To: 0x367}, - 56: {From: 0x10d0, To: 0x140}, - 57: {From: 0x1104, To: 0x2d0}, - 58: {From: 0x11a0, To: 0x1ec}, - 59: {From: 0x1279, To: 0x21}, - 60: {From: 0x1424, To: 0x15e}, - 61: {From: 0x1470, To: 0x14e}, - 62: {From: 0x151f, To: 0xd9b}, - 63: {From: 0x1523, To: 0x390}, - 64: {From: 0x1532, To: 0x19f}, - 65: {From: 0x1580, To: 0x210}, - 66: {From: 0x1583, To: 0x10d}, - 67: {From: 0x15a3, To: 0x3caf}, - 68: {From: 0x1630, To: 0x222e}, - 69: {From: 0x166a, To: 0x19b}, - 70: {From: 0x16c8, To: 0x136}, - 71: {From: 0x1700, To: 0x29f8}, - 72: {From: 0x1718, To: 0x194}, - 73: {From: 0x1727, To: 0xf3f}, - 74: {From: 0x177a, To: 0x178}, - 75: {From: 0x1809, To: 0x17b6}, - 76: {From: 0x1816, To: 0x18f3}, - 77: {From: 0x188a, To: 0x436}, - 78: {From: 0x1979, To: 0x1d01}, - 79: {From: 0x1a74, To: 0x2bb0}, - 80: {From: 0x1a8a, To: 0x1f8}, - 81: {From: 0x1b5a, To: 0x1fa}, - 82: {From: 0x1b86, To: 0x1515}, - 83: {From: 0x1d64, To: 0x2c9b}, - 84: {From: 0x2038, To: 0x37b1}, - 85: {From: 0x203d, To: 0x20dd}, - 86: {From: 0x2042, To: 0x2e00}, - 87: {From: 0x205a, To: 0x30b}, - 88: {From: 0x20e3, To: 0x274}, - 89: {From: 0x20ee, To: 0x263}, - 90: {From: 0x20f2, To: 0x22d}, - 91: {From: 0x20f9, To: 0x256}, - 92: {From: 0x210f, To: 0x21eb}, - 93: {From: 0x2135, To: 0x27d}, - 94: {From: 0x2160, To: 0x913}, - 95: {From: 0x2199, To: 0x121}, - 96: {From: 0x21ce, To: 0x1561}, - 97: {From: 0x21e6, To: 0x504}, - 98: {From: 0x21f4, To: 0x49f}, - 99: {From: 0x21fb, To: 0x269}, - 100: {From: 0x222d, To: 0x121}, - 101: {From: 0x2237, To: 0x121}, - 102: {From: 0x2248, To: 0x217d}, - 103: {From: 0x2262, To: 0x92a}, - 104: {From: 0x2316, To: 0x3226}, - 105: {From: 0x236a, To: 0x2835}, - 106: {From: 0x2382, To: 0x3365}, - 107: {From: 0x2472, To: 0x2c7}, - 108: {From: 0x24e4, To: 0x2ff}, - 109: {From: 0x24f0, To: 0x2fa}, - 110: {From: 0x24fa, To: 0x31f}, - 111: {From: 0x2550, To: 0xb5b}, - 112: {From: 0x25a9, To: 0xe2}, - 113: {From: 0x263e, To: 0x2d0}, - 114: {From: 0x26c9, To: 0x26b4}, - 115: {From: 0x26f9, To: 0x3c8}, - 116: {From: 0x2727, To: 0x3caf}, - 117: {From: 0x2755, To: 0x6a4}, - 118: {From: 0x2765, To: 0x26b4}, - 119: {From: 0x2789, To: 0x4358}, - 120: {From: 0x27c9, To: 0x2001}, - 121: {From: 0x28ea, To: 0x27b1}, - 122: {From: 0x28ef, To: 0x2837}, - 123: {From: 0x28fe, To: 0xaa5}, - 124: {From: 0x2914, To: 0x351}, - 125: {From: 0x2986, To: 0x2da7}, - 126: {From: 0x29f0, To: 0x96b}, - 127: {From: 0x2b1a, To: 0x38d}, - 128: {From: 0x2bfc, To: 0x395}, - 129: {From: 0x2c3f, To: 0x3caf}, - 130: {From: 0x2ce1, To: 0x2201}, - 131: {From: 0x2cfc, To: 0x3be}, - 132: {From: 0x2d13, To: 0x597}, - 133: {From: 0x2d47, To: 0x148}, - 134: {From: 0x2d48, To: 0x148}, - 135: {From: 0x2dff, To: 0x2f1}, - 136: {From: 0x2e08, To: 0x19cc}, - 137: {From: 0x2e10, To: 0xc45}, - 138: {From: 0x2e1a, To: 0x2d95}, - 139: {From: 0x2e21, To: 0x292}, - 140: {From: 0x2e54, To: 0x7d}, - 141: {From: 0x2e65, To: 0x2282}, - 142: {From: 0x2e97, To: 0x1a4}, - 143: {From: 0x2ea0, To: 0x2e9b}, - 144: {From: 0x2eef, To: 0x2ed7}, - 145: {From: 0x3193, To: 0x3c4}, - 146: {From: 0x3366, To: 0x338e}, - 147: {From: 0x342a, To: 0x3dc}, - 148: {From: 0x34ee, To: 0x18d0}, - 149: {From: 0x35c8, To: 0x2c9b}, - 150: {From: 0x35e6, To: 0x412}, - 151: {From: 0x35f5, To: 0x24b}, - 152: {From: 0x360d, To: 0x1dc}, - 153: {From: 0x3658, To: 0x246}, - 154: {From: 0x3676, To: 0x3f4}, - 155: {From: 0x36fd, To: 0x445}, - 156: {From: 0x3747, To: 0x3b42}, - 157: {From: 0x37c0, To: 0x121}, - 158: {From: 0x3816, To: 0x38f2}, - 159: {From: 0x382a, To: 0x2b48}, - 160: {From: 0x382b, To: 0x2c9b}, - 161: {From: 0x382f, To: 0xa9}, - 162: {From: 0x3832, To: 0x3228}, - 163: {From: 0x386c, To: 0x39a6}, - 164: {From: 0x3892, To: 0x3fc0}, - 165: {From: 0x38a0, To: 0x45f}, - 166: {From: 0x38a5, To: 0x39d7}, - 167: {From: 0x38b4, To: 0x1fa4}, - 168: {From: 0x38b5, To: 0x2e9a}, - 169: {From: 0x38fa, To: 0x38f1}, - 170: {From: 0x395c, To: 0x47e}, - 171: {From: 0x3b4e, To: 0xd91}, - 172: {From: 0x3b78, To: 0x137}, - 173: {From: 0x3c99, To: 0x4bc}, - 174: {From: 0x3fbd, To: 0x100}, - 175: {From: 0x4208, To: 0xa91}, - 176: {From: 0x42be, To: 0x573}, - 177: {From: 0x42f9, To: 0x3f60}, - 178: {From: 0x4378, To: 0x25a}, - 179: {From: 0x43b8, To: 0xe6c}, - 180: {From: 0x43cd, To: 0x10f}, - 181: {From: 0x43d4, To: 0x4848}, - 182: {From: 0x44af, To: 0x3322}, - 183: {From: 0x44e3, To: 0x512}, - 184: {From: 0x45ca, To: 0x2409}, - 185: {From: 0x45dd, To: 0x26dc}, - 186: {From: 0x4610, To: 0x48ae}, - 187: {From: 0x46ae, To: 0x46a0}, - 188: {From: 0x473e, To: 0x4745}, - 189: {From: 0x4817, To: 0x3503}, - 190: {From: 0x483b, To: 0x208b}, - 191: {From: 0x4916, To: 0x31f}, - 192: {From: 0x49a7, To: 0x523}, -} - -// Size: 193 bytes, 193 elements -var AliasTypes = [193]AliasType{ - // Entry 0 - 3F - 1, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 1, 0, 0, 0, 0, - 1, 2, 1, 1, 2, 0, 0, 1, 0, 1, 2, 1, 1, 0, 0, 0, - 0, 2, 1, 1, 0, 2, 0, 0, 1, 0, 1, 0, 0, 1, 2, 1, - 1, 1, 1, 0, 0, 0, 0, 2, 1, 1, 1, 1, 2, 1, 0, 1, - // Entry 40 - 7F - 1, 2, 2, 0, 0, 1, 2, 0, 1, 0, 1, 1, 1, 1, 0, 0, - 2, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 2, 2, 2, 0, - 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, - // Entry 80 - BF - 1, 0, 0, 1, 0, 2, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, - 0, 1, 1, 2, 0, 0, 2, 0, 0, 1, 1, 1, 0, 0, 0, 0, - 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 2, 0, - 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, - // Entry C0 - FF - 1, -} - -const ( - _Latn = 91 - _Hani = 57 - _Hans = 59 - _Hant = 60 - _Qaaa = 149 - _Qaai = 157 - _Qabx = 198 - _Zinh = 255 - _Zyyy = 260 - _Zzzz = 261 -) - -// script is an alphabetically sorted list of ISO 15924 codes. The index -// of the script in the string, divided by 4, is the internal scriptID. -const script tag.Index = "" + // Size: 1052 bytes - "----AdlmAfakAghbAhomArabAranArmiArmnAvstBaliBamuBassBatkBengBhksBlisBopo" + - "BrahBraiBugiBuhdCakmCansCariChamCherChrsCirtCoptCpmnCprtCyrlCyrsDevaDiak" + - "DogrDsrtDuplEgydEgyhEgypElbaElymEthiGeokGeorGlagGongGonmGothGranGrekGujr" + - "GuruHanbHangHaniHanoHansHantHatrHebrHiraHluwHmngHmnpHrktHungIndsItalJamo" + - "JavaJpanJurcKaliKanaKawiKharKhmrKhojKitlKitsKndaKoreKpelKthiLanaLaooLatf" + - "LatgLatnLekeLepcLimbLinaLinbLisuLomaLyciLydiMahjMakaMandManiMarcMayaMedf" + - "MendMercMeroMlymModiMongMoonMrooMteiMultMymrNagmNandNarbNbatNewaNkdbNkgb" + - "NkooNshuOgamOlckOrkhOryaOsgeOsmaOugrPalmPaucPcunPelmPermPhagPhliPhlpPhlv" + - "PhnxPiqdPlrdPrtiPsinQaaaQaabQaacQaadQaaeQaafQaagQaahQaaiQaajQaakQaalQaam" + - "QaanQaaoQaapQaaqQaarQaasQaatQaauQaavQaawQaaxQaayQaazQabaQabbQabcQabdQabe" + - "QabfQabgQabhQabiQabjQabkQablQabmQabnQaboQabpQabqQabrQabsQabtQabuQabvQabw" + - "QabxRanjRjngRohgRoroRunrSamrSaraSarbSaurSgnwShawShrdShuiSiddSindSinhSogd" + - "SogoSoraSoyoSundSunuSyloSyrcSyreSyrjSyrnTagbTakrTaleTaluTamlTangTavtTelu" + - "TengTfngTglgThaaThaiTibtTirhTnsaTotoUgarVaiiVispVithWaraWchoWoleXpeoXsux" + - "YeziYiiiZanbZinhZmthZsyeZsymZxxxZyyyZzzz\xff\xff\xff\xff" - -// suppressScript is an index from langID to the dominant script for that language, -// if it exists. If a script is given, it should be suppressed from the language tag. -// Size: 1330 bytes, 1330 elements -var suppressScript = [1330]uint8{ - // Entry 0 - 3F - 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, - // Entry 40 - 7F - 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, - // Entry 80 - BF - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - // Entry C0 - FF - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, - // Entry 100 - 13F - 0x5b, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xed, 0x00, 0x00, 0x00, 0x00, 0xef, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, - 0x00, 0x5b, 0x00, 0x00, 0x5b, 0x00, 0x5b, 0x00, - // Entry 140 - 17F - 0x5b, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x5b, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, - 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x00, - 0x00, 0x5b, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x5b, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - // Entry 180 - 1BF - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x5b, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x5b, 0x35, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x22, 0x00, - // Entry 1C0 - 1FF - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x5b, 0x5b, 0x00, 0x5b, 0x5b, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00, - 0x5b, 0x5b, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, - // Entry 200 - 23F - 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - // Entry 240 - 27F - 0x00, 0x00, 0x20, 0x00, 0x00, 0x5b, 0x00, 0x00, - 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x53, 0x00, 0x00, 0x54, 0x00, 0x22, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - // Entry 280 - 2BF - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, - 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - // Entry 2C0 - 2FF - 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, - // Entry 300 - 33F - 0x00, 0x00, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x5b, - 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x00, - // Entry 340 - 37F - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x00, - 0x5b, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, - 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x5b, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x5b, 0x00, - 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, - // Entry 380 - 3BF - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x5b, 0x00, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, - // Entry 3C0 - 3FF - 0x5b, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, - 0x00, 0x5b, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x20, 0x00, 0x00, 0x5b, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - // Entry 400 - 43F - 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xd6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x5b, 0x00, - 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, - 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00, - // Entry 440 - 47F - 0x00, 0x00, 0x00, 0x00, 0x5b, 0x5b, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xe9, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xee, 0x00, 0x00, 0x00, 0x2c, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, - 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x5b, 0x00, - // Entry 480 - 4BF - 0x5b, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x5b, 0x00, - 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x5b, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - // Entry 4C0 - 4FF - 0x5b, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - // Entry 500 - 53F - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, - 0x00, 0x00, -} - -const ( - _001 = 1 - _419 = 31 - _BR = 65 - _CA = 73 - _ES = 111 - _GB = 124 - _MD = 189 - _PT = 239 - _UK = 307 - _US = 310 - _ZZ = 358 - _XA = 324 - _XC = 326 - _XK = 334 -) - -// isoRegionOffset needs to be added to the index of regionISO to obtain the regionID -// for 2-letter ISO codes. (The first isoRegionOffset regionIDs are reserved for -// the UN.M49 codes used for groups.) -const isoRegionOffset = 32 - -// regionTypes defines the status of a region for various standards. -// Size: 359 bytes, 359 elements -var regionTypes = [359]uint8{ - // Entry 0 - 3F - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - // Entry 40 - 7F - 0x06, 0x06, 0x06, 0x06, 0x04, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x06, 0x06, 0x04, 0x04, 0x06, - 0x04, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x04, 0x06, 0x04, 0x06, 0x06, 0x06, 0x06, 0x00, - 0x06, 0x04, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x04, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x00, 0x06, 0x04, 0x06, 0x06, 0x06, 0x06, 0x06, - // Entry 80 - BF - 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x06, 0x00, 0x04, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x06, 0x00, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - // Entry C0 - FF - 0x06, 0x06, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x00, 0x06, 0x06, 0x06, 0x06, 0x00, 0x06, 0x04, - 0x06, 0x06, 0x06, 0x06, 0x00, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x00, 0x06, 0x06, 0x00, 0x06, 0x05, 0x05, 0x05, - 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, - // Entry 100 - 13F - 0x05, 0x05, 0x05, 0x06, 0x00, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x04, - 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x02, 0x06, 0x04, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x00, 0x06, 0x06, 0x06, 0x06, - // Entry 140 - 17F - 0x06, 0x06, 0x00, 0x06, 0x05, 0x05, 0x05, 0x05, - 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, - 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, - 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04, 0x06, - 0x06, 0x04, 0x06, 0x06, 0x04, 0x06, 0x05, -} - -// regionISO holds a list of alphabetically sorted 2-letter ISO region codes. -// Each 2-letter codes is followed by two bytes with the following meaning: -// - [A-Z}{2}: the first letter of the 2-letter code plus these two -// letters form the 3-letter ISO code. -// - 0, n: index into altRegionISO3. -const regionISO tag.Index = "" + // Size: 1312 bytes - "AAAAACSCADNDAEREAFFGAGTGAIIAALLBAMRMANNTAOGOAQTAARRGASSMATUTAUUSAWBWAXLA" + - "AZZEBAIHBBRBBDGDBEELBFFABGGRBHHRBIDIBJENBLLMBMMUBNRNBOOLBQESBRRABSHSBTTN" + - "BUURBVVTBWWABYLRBZLZCAANCCCKCDODCFAFCGOGCHHECIIVCKOKCLHLCMMRCNHNCOOLCPPT" + - "CQ CRRICS\x00\x00CTTECUUBCVPVCWUWCXXRCYYPCZZEDDDRDEEUDGGADJJIDKNKDMMADO" + - "OMDYHYDZZAEA ECCUEESTEGGYEHSHERRIESSPETTHEU\x00\x03EZ FIINFJJIFKLKFMSM" + - "FOROFQ\x00\x18FRRAFXXXGAABGBBRGDRDGEEOGFUFGGGYGHHAGIIBGLRLGMMBGNINGPLPGQ" + - "NQGRRCGS\x00\x06GTTMGUUMGWNBGYUYHKKGHMMDHNNDHRRVHTTIHUUNHVVOIC IDDNIERL" + - "ILSRIMMNINNDIOOTIQRQIRRNISSLITTAJEEYJMAMJOORJPPNJTTNKEENKGGZKHHMKIIRKM" + - "\x00\x09KNNAKP\x00\x0cKRORKWWTKY\x00\x0fKZAZLAAOLBBNLCCALIIELKKALRBRLSSO" + - "LTTULUUXLVVALYBYMAARMCCOMDDAMENEMFAFMGDGMHHLMIIDMKKDMLLIMMMRMNNGMOACMPNP" + - "MQTQMRRTMSSRMTLTMUUSMVDVMWWIMXEXMYYSMZOZNAAMNCCLNEERNFFKNGGANHHBNIICNLLD" + - "NOORNPPLNQ\x00\x1eNRRUNTTZNUIUNZZLOMMNPAANPCCIPEERPFYFPGNGPHHLPKAKPLOLPM" + - "\x00\x12PNCNPRRIPSSEPTRTPUUSPWLWPYRYPZCZQAATQMMMQNNNQOOOQPPPQQQQQRRRQSSS" + - "QTTTQU\x00\x03QVVVQWWWQXXXQYYYQZZZREEURHHOROOURS\x00\x15RUUSRWWASAAUSBLB" + - "SCYCSDDNSEWESGGPSHHNSIVNSJJMSKVKSLLESMMRSNENSOOMSRURSSSDSTTPSUUNSVLVSXXM" + - "SYYRSZWZTAAATCCATDCDTF\x00\x18TGGOTHHATJJKTKKLTLLSTMKMTNUNTOONTPMPTRURTT" + - "TOTVUVTWWNTZZAUAKRUGGAUK UMMIUN USSAUYRYUZZBVAATVCCTVDDRVEENVGGBVIIRVN" + - "NMVUUTWFLFWKAKWSSMXAAAXBBBXCCCXDDDXEEEXFFFXGGGXHHHXIIIXJJJXKKKXLLLXMMMXN" + - "NNXOOOXPPPXQQQXRRRXSSSXTTTXUUUXVVVXWWWXXXXXYYYXZZZYDMDYEEMYT\x00\x1bYUUG" + - "ZAAFZMMBZRARZWWEZZZZ\xff\xff\xff\xff" - -// altRegionISO3 holds a list of 3-letter region codes that cannot be -// mapped to 2-letter codes using the default algorithm. This is a short list. -const altRegionISO3 string = "SCGQUUSGSCOMPRKCYMSPMSRBATFMYTATN" - -// altRegionIDs holds a list of regionIDs the positions of which match those -// of the 3-letter ISO codes in altRegionISO3. -// Size: 22 bytes, 11 elements -var altRegionIDs = [11]uint16{ - 0x0058, 0x0071, 0x0089, 0x00a9, 0x00ab, 0x00ae, 0x00eb, 0x0106, - 0x0122, 0x0160, 0x00dd, -} - -// Size: 80 bytes, 20 elements -var regionOldMap = [20]FromTo{ - 0: {From: 0x44, To: 0xc5}, - 1: {From: 0x59, To: 0xa8}, - 2: {From: 0x60, To: 0x61}, - 3: {From: 0x67, To: 0x3b}, - 4: {From: 0x7a, To: 0x79}, - 5: {From: 0x94, To: 0x37}, - 6: {From: 0xa4, To: 0x134}, - 7: {From: 0xc2, To: 0x134}, - 8: {From: 0xd8, To: 0x140}, - 9: {From: 0xdd, To: 0x2b}, - 10: {From: 0xf0, To: 0x134}, - 11: {From: 0xf3, To: 0xe3}, - 12: {From: 0xfd, To: 0x71}, - 13: {From: 0x104, To: 0x165}, - 14: {From: 0x12b, To: 0x127}, - 15: {From: 0x133, To: 0x7c}, - 16: {From: 0x13b, To: 0x13f}, - 17: {From: 0x142, To: 0x134}, - 18: {From: 0x15e, To: 0x15f}, - 19: {From: 0x164, To: 0x4b}, -} - -// m49 maps regionIDs to UN.M49 codes. The first isoRegionOffset entries are -// codes indicating collections of regions. -// Size: 718 bytes, 359 elements -var m49 = [359]int16{ - // Entry 0 - 3F - 0, 1, 2, 3, 5, 9, 11, 13, - 14, 15, 17, 18, 19, 21, 29, 30, - 34, 35, 39, 53, 54, 57, 61, 142, - 143, 145, 150, 151, 154, 155, 202, 419, - 958, 0, 20, 784, 4, 28, 660, 8, - 51, 530, 24, 10, 32, 16, 40, 36, - 533, 248, 31, 70, 52, 50, 56, 854, - 100, 48, 108, 204, 652, 60, 96, 68, - // Entry 40 - 7F - 535, 76, 44, 64, 104, 74, 72, 112, - 84, 124, 166, 180, 140, 178, 756, 384, - 184, 152, 120, 156, 170, 0, 0, 188, - 891, 296, 192, 132, 531, 162, 196, 203, - 278, 276, 0, 262, 208, 212, 214, 204, - 12, 0, 218, 233, 818, 732, 232, 724, - 231, 967, 0, 246, 242, 238, 583, 234, - 0, 250, 249, 266, 826, 308, 268, 254, - // Entry 80 - BF - 831, 288, 292, 304, 270, 324, 312, 226, - 300, 239, 320, 316, 624, 328, 344, 334, - 340, 191, 332, 348, 854, 0, 360, 372, - 376, 833, 356, 86, 368, 364, 352, 380, - 832, 388, 400, 392, 581, 404, 417, 116, - 296, 174, 659, 408, 410, 414, 136, 398, - 418, 422, 662, 438, 144, 430, 426, 440, - 442, 428, 434, 504, 492, 498, 499, 663, - // Entry C0 - FF - 450, 584, 581, 807, 466, 104, 496, 446, - 580, 474, 478, 500, 470, 480, 462, 454, - 484, 458, 508, 516, 540, 562, 574, 566, - 548, 558, 528, 578, 524, 10, 520, 536, - 570, 554, 512, 591, 0, 604, 258, 598, - 608, 586, 616, 666, 612, 630, 275, 620, - 581, 585, 600, 591, 634, 959, 960, 961, - 962, 963, 964, 965, 966, 967, 968, 969, - // Entry 100 - 13F - 970, 971, 972, 638, 716, 642, 688, 643, - 646, 682, 90, 690, 729, 752, 702, 654, - 705, 744, 703, 694, 674, 686, 706, 740, - 728, 678, 810, 222, 534, 760, 748, 0, - 796, 148, 260, 768, 764, 762, 772, 626, - 795, 788, 776, 626, 792, 780, 798, 158, - 834, 804, 800, 826, 581, 0, 840, 858, - 860, 336, 670, 704, 862, 92, 850, 704, - // Entry 140 - 17F - 548, 876, 581, 882, 973, 974, 975, 976, - 977, 978, 979, 980, 981, 982, 983, 984, - 985, 986, 987, 988, 989, 990, 991, 992, - 993, 994, 995, 996, 997, 998, 720, 887, - 175, 891, 710, 894, 180, 716, 999, -} - -// m49Index gives indexes into fromM49 based on the three most significant bits -// of a 10-bit UN.M49 code. To search an UN.M49 code in fromM49, search in -// -// fromM49[m49Index[msb39(code)]:m49Index[msb3(code)+1]] -// -// for an entry where the first 7 bits match the 7 lsb of the UN.M49 code. -// The region code is stored in the 9 lsb of the indexed value. -// Size: 18 bytes, 9 elements -var m49Index = [9]int16{ - 0, 59, 108, 143, 181, 220, 259, 291, - 333, -} - -// fromM49 contains entries to map UN.M49 codes to regions. See m49Index for details. -// Size: 666 bytes, 333 elements -var fromM49 = [333]uint16{ - // Entry 0 - 3F - 0x0201, 0x0402, 0x0603, 0x0824, 0x0a04, 0x1027, 0x1205, 0x142b, - 0x1606, 0x1868, 0x1a07, 0x1c08, 0x1e09, 0x202d, 0x220a, 0x240b, - 0x260c, 0x2822, 0x2a0d, 0x302a, 0x3825, 0x3a0e, 0x3c0f, 0x3e32, - 0x402c, 0x4410, 0x4611, 0x482f, 0x4e12, 0x502e, 0x5842, 0x6039, - 0x6435, 0x6628, 0x6834, 0x6a13, 0x6c14, 0x7036, 0x7215, 0x783d, - 0x7a16, 0x8043, 0x883f, 0x8c33, 0x9046, 0x9445, 0x9841, 0xa848, - 0xac9b, 0xb50a, 0xb93d, 0xc03e, 0xc838, 0xd0c5, 0xd83a, 0xe047, - 0xe8a7, 0xf052, 0xf849, 0x085b, 0x10ae, 0x184c, 0x1c17, 0x1e18, - // Entry 40 - 7F - 0x20b4, 0x2219, 0x2921, 0x2c1a, 0x2e1b, 0x3051, 0x341c, 0x361d, - 0x3853, 0x3d2f, 0x445d, 0x4c4a, 0x5454, 0x5ca9, 0x5f60, 0x644d, - 0x684b, 0x7050, 0x7857, 0x7e91, 0x805a, 0x885e, 0x941e, 0x965f, - 0x983b, 0xa064, 0xa865, 0xac66, 0xb46a, 0xbd1b, 0xc487, 0xcc70, - 0xce70, 0xd06e, 0xd26b, 0xd477, 0xdc75, 0xde89, 0xe474, 0xec73, - 0xf031, 0xf27a, 0xf479, 0xfc7f, 0x04e6, 0x0922, 0x0c63, 0x147b, - 0x187e, 0x1c84, 0x26ee, 0x2861, 0x2c60, 0x3061, 0x4081, 0x4882, - 0x50a8, 0x5888, 0x6083, 0x687d, 0x7086, 0x788b, 0x808a, 0x8885, - // Entry 80 - BF - 0x908d, 0x9892, 0x9c8f, 0xa139, 0xa890, 0xb08e, 0xb893, 0xc09e, - 0xc89a, 0xd096, 0xd89d, 0xe09c, 0xe897, 0xf098, 0xf89f, 0x004f, - 0x08a1, 0x10a3, 0x1caf, 0x20a2, 0x28a5, 0x30ab, 0x34ac, 0x3cad, - 0x42a6, 0x44b0, 0x461f, 0x4cb1, 0x54b6, 0x58b9, 0x5cb5, 0x64ba, - 0x6cb3, 0x70b7, 0x74b8, 0x7cc7, 0x84c0, 0x8ccf, 0x94d1, 0x9cce, - 0xa4c4, 0xaccc, 0xb4c9, 0xbcca, 0xc0cd, 0xc8d0, 0xd8bc, 0xe0c6, - 0xe4bd, 0xe6be, 0xe8cb, 0xf0bb, 0xf8d2, 0x00e2, 0x08d3, 0x10de, - 0x18dc, 0x20da, 0x2429, 0x265c, 0x2a30, 0x2d1c, 0x2e40, 0x30df, - // Entry C0 - FF - 0x38d4, 0x4940, 0x54e1, 0x5cd9, 0x64d5, 0x6cd7, 0x74e0, 0x7cd6, - 0x84db, 0x88c8, 0x8b34, 0x8e76, 0x90c1, 0x92f1, 0x94e9, 0x9ee3, - 0xace7, 0xb0f2, 0xb8e5, 0xc0e8, 0xc8ec, 0xd0ea, 0xd8ef, 0xe08c, - 0xe527, 0xeced, 0xf4f4, 0xfd03, 0x0505, 0x0707, 0x0d08, 0x183c, - 0x1d0f, 0x26aa, 0x2826, 0x2cb2, 0x2ebf, 0x34eb, 0x3d3a, 0x4514, - 0x4d19, 0x5509, 0x5d15, 0x6106, 0x650b, 0x6d13, 0x7d0e, 0x7f12, - 0x813f, 0x8310, 0x8516, 0x8d62, 0x9965, 0xa15e, 0xa86f, 0xb118, - 0xb30c, 0xb86d, 0xc10c, 0xc917, 0xd111, 0xd91e, 0xe10d, 0xe84e, - // Entry 100 - 13F - 0xf11d, 0xf525, 0xf924, 0x0123, 0x0926, 0x112a, 0x192d, 0x2023, - 0x2929, 0x312c, 0x3728, 0x3920, 0x3d2e, 0x4132, 0x4931, 0x4ec3, - 0x551a, 0x646c, 0x747c, 0x7e80, 0x80a0, 0x8299, 0x8530, 0x9136, - 0xa53e, 0xac37, 0xb537, 0xb938, 0xbd3c, 0xd941, 0xe543, 0xed5f, - 0xef5f, 0xf658, 0xfd63, 0x7c20, 0x7ef5, 0x80f6, 0x82f7, 0x84f8, - 0x86f9, 0x88fa, 0x8afb, 0x8cfc, 0x8e71, 0x90fe, 0x92ff, 0x9500, - 0x9701, 0x9902, 0x9b44, 0x9d45, 0x9f46, 0xa147, 0xa348, 0xa549, - 0xa74a, 0xa94b, 0xab4c, 0xad4d, 0xaf4e, 0xb14f, 0xb350, 0xb551, - // Entry 140 - 17F - 0xb752, 0xb953, 0xbb54, 0xbd55, 0xbf56, 0xc157, 0xc358, 0xc559, - 0xc75a, 0xc95b, 0xcb5c, 0xcd5d, 0xcf66, -} - -// Size: 2128 bytes -var variantIndex = map[string]uint8{ - "1606nict": 0x0, - "1694acad": 0x1, - "1901": 0x2, - "1959acad": 0x3, - "1994": 0x67, - "1996": 0x4, - "abl1943": 0x5, - "akuapem": 0x6, - "alalc97": 0x69, - "aluku": 0x7, - "ao1990": 0x8, - "aranes": 0x9, - "arevela": 0xa, - "arevmda": 0xb, - "arkaika": 0xc, - "asante": 0xd, - "auvern": 0xe, - "baku1926": 0xf, - "balanka": 0x10, - "barla": 0x11, - "basiceng": 0x12, - "bauddha": 0x13, - "bciav": 0x14, - "bcizbl": 0x15, - "biscayan": 0x16, - "biske": 0x62, - "bohoric": 0x17, - "boont": 0x18, - "bornholm": 0x19, - "cisaup": 0x1a, - "colb1945": 0x1b, - "cornu": 0x1c, - "creiss": 0x1d, - "dajnko": 0x1e, - "ekavsk": 0x1f, - "emodeng": 0x20, - "fonipa": 0x6a, - "fonkirsh": 0x6b, - "fonnapa": 0x6c, - "fonupa": 0x6d, - "fonxsamp": 0x6e, - "gallo": 0x21, - "gascon": 0x22, - "grclass": 0x23, - "grital": 0x24, - "grmistr": 0x25, - "hepburn": 0x26, - "heploc": 0x68, - "hognorsk": 0x27, - "hsistemo": 0x28, - "ijekavsk": 0x29, - "itihasa": 0x2a, - "ivanchov": 0x2b, - "jauer": 0x2c, - "jyutping": 0x2d, - "kkcor": 0x2e, - "kociewie": 0x2f, - "kscor": 0x30, - "laukika": 0x31, - "lemosin": 0x32, - "lengadoc": 0x33, - "lipaw": 0x63, - "ltg1929": 0x34, - "ltg2007": 0x35, - "luna1918": 0x36, - "metelko": 0x37, - "monoton": 0x38, - "ndyuka": 0x39, - "nedis": 0x3a, - "newfound": 0x3b, - "nicard": 0x3c, - "njiva": 0x64, - "nulik": 0x3d, - "osojs": 0x65, - "oxendict": 0x3e, - "pahawh2": 0x3f, - "pahawh3": 0x40, - "pahawh4": 0x41, - "pamaka": 0x42, - "peano": 0x43, - "petr1708": 0x44, - "pinyin": 0x45, - "polyton": 0x46, - "provenc": 0x47, - "puter": 0x48, - "rigik": 0x49, - "rozaj": 0x4a, - "rumgr": 0x4b, - "scotland": 0x4c, - "scouse": 0x4d, - "simple": 0x6f, - "solba": 0x66, - "sotav": 0x4e, - "spanglis": 0x4f, - "surmiran": 0x50, - "sursilv": 0x51, - "sutsilv": 0x52, - "synnejyl": 0x53, - "tarask": 0x54, - "tongyong": 0x55, - "tunumiit": 0x56, - "uccor": 0x57, - "ucrcor": 0x58, - "ulster": 0x59, - "unifon": 0x5a, - "vaidika": 0x5b, - "valencia": 0x5c, - "vallader": 0x5d, - "vecdruka": 0x5e, - "vivaraup": 0x5f, - "wadegile": 0x60, - "xsistemo": 0x61, -} - -// variantNumSpecialized is the number of specialized variants in variants. -const variantNumSpecialized = 105 - -// nRegionGroups is the number of region groups. -const nRegionGroups = 33 - -type likelyLangRegion struct { - lang uint16 - region uint16 -} - -// likelyScript is a lookup table, indexed by scriptID, for the most likely -// languages and regions given a script. -// Size: 1052 bytes, 263 elements -var likelyScript = [263]likelyLangRegion{ - 1: {lang: 0x14e, region: 0x85}, - 3: {lang: 0x2a2, region: 0x107}, - 4: {lang: 0x1f, region: 0x9a}, - 5: {lang: 0x3a, region: 0x6c}, - 7: {lang: 0x3b, region: 0x9d}, - 8: {lang: 0x1d7, region: 0x28}, - 9: {lang: 0x13, region: 0x9d}, - 10: {lang: 0x5b, region: 0x96}, - 11: {lang: 0x60, region: 0x52}, - 12: {lang: 0xb9, region: 0xb5}, - 13: {lang: 0x63, region: 0x96}, - 14: {lang: 0xa5, region: 0x35}, - 15: {lang: 0x3e9, region: 0x9a}, - 17: {lang: 0x529, region: 0x12f}, - 18: {lang: 0x3b1, region: 0x9a}, - 19: {lang: 0x15e, region: 0x79}, - 20: {lang: 0xc2, region: 0x96}, - 21: {lang: 0x9d, region: 0xe8}, - 22: {lang: 0xdb, region: 0x35}, - 23: {lang: 0xf3, region: 0x49}, - 24: {lang: 0x4f0, region: 0x12c}, - 25: {lang: 0xe7, region: 0x13f}, - 26: {lang: 0xe5, region: 0x136}, - 29: {lang: 0xf1, region: 0x6c}, - 31: {lang: 0x1a0, region: 0x5e}, - 32: {lang: 0x3e2, region: 0x107}, - 34: {lang: 0x1be, region: 0x9a}, - 38: {lang: 0x15e, region: 0x79}, - 41: {lang: 0x133, region: 0x6c}, - 42: {lang: 0x431, region: 0x27}, - 44: {lang: 0x27, region: 0x70}, - 46: {lang: 0x210, region: 0x7e}, - 47: {lang: 0xfe, region: 0x38}, - 49: {lang: 0x19b, region: 0x9a}, - 50: {lang: 0x19e, region: 0x131}, - 51: {lang: 0x3e9, region: 0x9a}, - 52: {lang: 0x136, region: 0x88}, - 53: {lang: 0x1a4, region: 0x9a}, - 54: {lang: 0x39d, region: 0x9a}, - 55: {lang: 0x529, region: 0x12f}, - 56: {lang: 0x254, region: 0xac}, - 57: {lang: 0x529, region: 0x53}, - 58: {lang: 0x1cb, region: 0xe8}, - 59: {lang: 0x529, region: 0x53}, - 60: {lang: 0x529, region: 0x12f}, - 61: {lang: 0x2fd, region: 0x9c}, - 62: {lang: 0x1bc, region: 0x98}, - 63: {lang: 0x200, region: 0xa3}, - 64: {lang: 0x1c5, region: 0x12c}, - 65: {lang: 0x1ca, region: 0xb0}, - 68: {lang: 0x1d5, region: 0x93}, - 70: {lang: 0x142, region: 0x9f}, - 71: {lang: 0x254, region: 0xac}, - 72: {lang: 0x20e, region: 0x96}, - 73: {lang: 0x200, region: 0xa3}, - 75: {lang: 0x135, region: 0xc5}, - 76: {lang: 0x200, region: 0xa3}, - 78: {lang: 0x3bb, region: 0xe9}, - 79: {lang: 0x24a, region: 0xa7}, - 80: {lang: 0x3fa, region: 0x9a}, - 83: {lang: 0x251, region: 0x9a}, - 84: {lang: 0x254, region: 0xac}, - 86: {lang: 0x88, region: 0x9a}, - 87: {lang: 0x370, region: 0x124}, - 88: {lang: 0x2b8, region: 0xb0}, - 93: {lang: 0x29f, region: 0x9a}, - 94: {lang: 0x2a8, region: 0x9a}, - 95: {lang: 0x28f, region: 0x88}, - 96: {lang: 0x1a0, region: 0x88}, - 97: {lang: 0x2ac, region: 0x53}, - 99: {lang: 0x4f4, region: 0x12c}, - 100: {lang: 0x4f5, region: 0x12c}, - 101: {lang: 0x1be, region: 0x9a}, - 103: {lang: 0x337, region: 0x9d}, - 104: {lang: 0x4f7, region: 0x53}, - 105: {lang: 0xa9, region: 0x53}, - 108: {lang: 0x2e8, region: 0x113}, - 109: {lang: 0x4f8, region: 0x10c}, - 110: {lang: 0x4f8, region: 0x10c}, - 111: {lang: 0x304, region: 0x9a}, - 112: {lang: 0x31b, region: 0x9a}, - 113: {lang: 0x30b, region: 0x53}, - 115: {lang: 0x31e, region: 0x35}, - 116: {lang: 0x30e, region: 0x9a}, - 117: {lang: 0x414, region: 0xe9}, - 118: {lang: 0x331, region: 0xc5}, - 121: {lang: 0x4f9, region: 0x109}, - 122: {lang: 0x3b, region: 0xa2}, - 123: {lang: 0x353, region: 0xdc}, - 126: {lang: 0x2d0, region: 0x85}, - 127: {lang: 0x52a, region: 0x53}, - 128: {lang: 0x403, region: 0x97}, - 129: {lang: 0x3ee, region: 0x9a}, - 130: {lang: 0x39b, region: 0xc6}, - 131: {lang: 0x395, region: 0x9a}, - 132: {lang: 0x399, region: 0x136}, - 133: {lang: 0x429, region: 0x116}, - 135: {lang: 0x3b, region: 0x11d}, - 136: {lang: 0xfd, region: 0xc5}, - 139: {lang: 0x27d, region: 0x107}, - 140: {lang: 0x2c9, region: 0x53}, - 141: {lang: 0x39f, region: 0x9d}, - 142: {lang: 0x39f, region: 0x53}, - 144: {lang: 0x3ad, region: 0xb1}, - 146: {lang: 0x1c6, region: 0x53}, - 147: {lang: 0x4fd, region: 0x9d}, - 200: {lang: 0x3cb, region: 0x96}, - 203: {lang: 0x372, region: 0x10d}, - 204: {lang: 0x420, region: 0x98}, - 206: {lang: 0x4ff, region: 0x15f}, - 207: {lang: 0x3f0, region: 0x9a}, - 208: {lang: 0x45, region: 0x136}, - 209: {lang: 0x139, region: 0x7c}, - 210: {lang: 0x3e9, region: 0x9a}, - 212: {lang: 0x3e9, region: 0x9a}, - 213: {lang: 0x3fa, region: 0x9a}, - 214: {lang: 0x40c, region: 0xb4}, - 217: {lang: 0x433, region: 0x9a}, - 218: {lang: 0xef, region: 0xc6}, - 219: {lang: 0x43e, region: 0x96}, - 221: {lang: 0x44d, region: 0x35}, - 222: {lang: 0x44e, region: 0x9c}, - 226: {lang: 0x45a, region: 0xe8}, - 227: {lang: 0x11a, region: 0x9a}, - 228: {lang: 0x45e, region: 0x53}, - 229: {lang: 0x232, region: 0x53}, - 230: {lang: 0x450, region: 0x9a}, - 231: {lang: 0x4a5, region: 0x53}, - 232: {lang: 0x9f, region: 0x13f}, - 233: {lang: 0x461, region: 0x9a}, - 235: {lang: 0x528, region: 0xbb}, - 236: {lang: 0x153, region: 0xe8}, - 237: {lang: 0x128, region: 0xce}, - 238: {lang: 0x46b, region: 0x124}, - 239: {lang: 0xa9, region: 0x53}, - 240: {lang: 0x2ce, region: 0x9a}, - 243: {lang: 0x4ad, region: 0x11d}, - 244: {lang: 0x4be, region: 0xb5}, - 247: {lang: 0x1ce, region: 0x9a}, - 250: {lang: 0x3a9, region: 0x9d}, - 251: {lang: 0x22, region: 0x9c}, - 253: {lang: 0x1ea, region: 0x53}, - 254: {lang: 0xef, region: 0xc6}, -} - -type likelyScriptRegion struct { - region uint16 - script uint16 - flags uint8 -} - -// likelyLang is a lookup table, indexed by langID, for the most likely -// scripts and regions given incomplete information. If more entries exist for a -// given language, region and script are the index and size respectively -// of the list in likelyLangList. -// Size: 7980 bytes, 1330 elements -var likelyLang = [1330]likelyScriptRegion{ - 0: {region: 0x136, script: 0x5b, flags: 0x0}, - 1: {region: 0x70, script: 0x5b, flags: 0x0}, - 2: {region: 0x166, script: 0x5b, flags: 0x0}, - 3: {region: 0x166, script: 0x5b, flags: 0x0}, - 4: {region: 0x166, script: 0x5b, flags: 0x0}, - 5: {region: 0x7e, script: 0x20, flags: 0x0}, - 6: {region: 0x166, script: 0x5b, flags: 0x0}, - 7: {region: 0x166, script: 0x20, flags: 0x0}, - 8: {region: 0x81, script: 0x5b, flags: 0x0}, - 9: {region: 0x166, script: 0x5b, flags: 0x0}, - 10: {region: 0x166, script: 0x5b, flags: 0x0}, - 11: {region: 0x166, script: 0x5b, flags: 0x0}, - 12: {region: 0x96, script: 0x5b, flags: 0x0}, - 13: {region: 0x132, script: 0x5b, flags: 0x0}, - 14: {region: 0x81, script: 0x5b, flags: 0x0}, - 15: {region: 0x166, script: 0x5b, flags: 0x0}, - 16: {region: 0x166, script: 0x5b, flags: 0x0}, - 17: {region: 0x107, script: 0x20, flags: 0x0}, - 18: {region: 0x166, script: 0x5b, flags: 0x0}, - 19: {region: 0x9d, script: 0x9, flags: 0x0}, - 20: {region: 0x129, script: 0x5, flags: 0x0}, - 21: {region: 0x166, script: 0x5b, flags: 0x0}, - 22: {region: 0x162, script: 0x5b, flags: 0x0}, - 23: {region: 0x166, script: 0x5b, flags: 0x0}, - 24: {region: 0x166, script: 0x5b, flags: 0x0}, - 25: {region: 0x166, script: 0x5b, flags: 0x0}, - 26: {region: 0x166, script: 0x5b, flags: 0x0}, - 27: {region: 0x166, script: 0x5b, flags: 0x0}, - 28: {region: 0x52, script: 0x5b, flags: 0x0}, - 29: {region: 0x166, script: 0x5b, flags: 0x0}, - 30: {region: 0x166, script: 0x5b, flags: 0x0}, - 31: {region: 0x9a, script: 0x4, flags: 0x0}, - 32: {region: 0x166, script: 0x5b, flags: 0x0}, - 33: {region: 0x81, script: 0x5b, flags: 0x0}, - 34: {region: 0x9c, script: 0xfb, flags: 0x0}, - 35: {region: 0x166, script: 0x5b, flags: 0x0}, - 36: {region: 0x166, script: 0x5b, flags: 0x0}, - 37: {region: 0x14e, script: 0x5b, flags: 0x0}, - 38: {region: 0x107, script: 0x20, flags: 0x0}, - 39: {region: 0x70, script: 0x2c, flags: 0x0}, - 40: {region: 0x166, script: 0x5b, flags: 0x0}, - 41: {region: 0x166, script: 0x5b, flags: 0x0}, - 42: {region: 0xd7, script: 0x5b, flags: 0x0}, - 43: {region: 0x166, script: 0x5b, flags: 0x0}, - 45: {region: 0x166, script: 0x5b, flags: 0x0}, - 46: {region: 0x166, script: 0x5b, flags: 0x0}, - 47: {region: 0x166, script: 0x5b, flags: 0x0}, - 48: {region: 0x166, script: 0x5b, flags: 0x0}, - 49: {region: 0x166, script: 0x5b, flags: 0x0}, - 50: {region: 0x166, script: 0x5b, flags: 0x0}, - 51: {region: 0x96, script: 0x5b, flags: 0x0}, - 52: {region: 0x166, script: 0x5, flags: 0x0}, - 53: {region: 0x123, script: 0x5, flags: 0x0}, - 54: {region: 0x166, script: 0x5b, flags: 0x0}, - 55: {region: 0x166, script: 0x5b, flags: 0x0}, - 56: {region: 0x166, script: 0x5b, flags: 0x0}, - 57: {region: 0x166, script: 0x5b, flags: 0x0}, - 58: {region: 0x6c, script: 0x5, flags: 0x0}, - 59: {region: 0x0, script: 0x3, flags: 0x1}, - 60: {region: 0x166, script: 0x5b, flags: 0x0}, - 61: {region: 0x51, script: 0x5b, flags: 0x0}, - 62: {region: 0x3f, script: 0x5b, flags: 0x0}, - 63: {region: 0x68, script: 0x5, flags: 0x0}, - 65: {region: 0xbb, script: 0x5, flags: 0x0}, - 66: {region: 0x6c, script: 0x5, flags: 0x0}, - 67: {region: 0x9a, script: 0xe, flags: 0x0}, - 68: {region: 0x130, script: 0x5b, flags: 0x0}, - 69: {region: 0x136, script: 0xd0, flags: 0x0}, - 70: {region: 0x166, script: 0x5b, flags: 0x0}, - 71: {region: 0x166, script: 0x5b, flags: 0x0}, - 72: {region: 0x6f, script: 0x5b, flags: 0x0}, - 73: {region: 0x166, script: 0x5b, flags: 0x0}, - 74: {region: 0x166, script: 0x5b, flags: 0x0}, - 75: {region: 0x49, script: 0x5b, flags: 0x0}, - 76: {region: 0x166, script: 0x5b, flags: 0x0}, - 77: {region: 0x107, script: 0x20, flags: 0x0}, - 78: {region: 0x166, script: 0x5, flags: 0x0}, - 79: {region: 0x166, script: 0x5b, flags: 0x0}, - 80: {region: 0x166, script: 0x5b, flags: 0x0}, - 81: {region: 0x166, script: 0x5b, flags: 0x0}, - 82: {region: 0x9a, script: 0x22, flags: 0x0}, - 83: {region: 0x166, script: 0x5b, flags: 0x0}, - 84: {region: 0x166, script: 0x5b, flags: 0x0}, - 85: {region: 0x166, script: 0x5b, flags: 0x0}, - 86: {region: 0x3f, script: 0x5b, flags: 0x0}, - 87: {region: 0x166, script: 0x5b, flags: 0x0}, - 88: {region: 0x3, script: 0x5, flags: 0x1}, - 89: {region: 0x107, script: 0x20, flags: 0x0}, - 90: {region: 0xe9, script: 0x5, flags: 0x0}, - 91: {region: 0x96, script: 0x5b, flags: 0x0}, - 92: {region: 0xdc, script: 0x22, flags: 0x0}, - 93: {region: 0x2e, script: 0x5b, flags: 0x0}, - 94: {region: 0x52, script: 0x5b, flags: 0x0}, - 95: {region: 0x166, script: 0x5b, flags: 0x0}, - 96: {region: 0x52, script: 0xb, flags: 0x0}, - 97: {region: 0x166, script: 0x5b, flags: 0x0}, - 98: {region: 0x166, script: 0x5b, flags: 0x0}, - 99: {region: 0x96, script: 0x5b, flags: 0x0}, - 100: {region: 0x166, script: 0x5b, flags: 0x0}, - 101: {region: 0x52, script: 0x5b, flags: 0x0}, - 102: {region: 0x166, script: 0x5b, flags: 0x0}, - 103: {region: 0x166, script: 0x5b, flags: 0x0}, - 104: {region: 0x166, script: 0x5b, flags: 0x0}, - 105: {region: 0x166, script: 0x5b, flags: 0x0}, - 106: {region: 0x4f, script: 0x5b, flags: 0x0}, - 107: {region: 0x166, script: 0x5b, flags: 0x0}, - 108: {region: 0x166, script: 0x5b, flags: 0x0}, - 109: {region: 0x166, script: 0x5b, flags: 0x0}, - 110: {region: 0x166, script: 0x2c, flags: 0x0}, - 111: {region: 0x166, script: 0x5b, flags: 0x0}, - 112: {region: 0x166, script: 0x5b, flags: 0x0}, - 113: {region: 0x47, script: 0x20, flags: 0x0}, - 114: {region: 0x166, script: 0x5b, flags: 0x0}, - 115: {region: 0x166, script: 0x5b, flags: 0x0}, - 116: {region: 0x10c, script: 0x5, flags: 0x0}, - 117: {region: 0x163, script: 0x5b, flags: 0x0}, - 118: {region: 0x166, script: 0x5b, flags: 0x0}, - 119: {region: 0x96, script: 0x5b, flags: 0x0}, - 120: {region: 0x166, script: 0x5b, flags: 0x0}, - 121: {region: 0x130, script: 0x5b, flags: 0x0}, - 122: {region: 0x52, script: 0x5b, flags: 0x0}, - 123: {region: 0x9a, script: 0xe6, flags: 0x0}, - 124: {region: 0xe9, script: 0x5, flags: 0x0}, - 125: {region: 0x9a, script: 0x22, flags: 0x0}, - 126: {region: 0x38, script: 0x20, flags: 0x0}, - 127: {region: 0x9a, script: 0x22, flags: 0x0}, - 128: {region: 0xe9, script: 0x5, flags: 0x0}, - 129: {region: 0x12c, script: 0x34, flags: 0x0}, - 131: {region: 0x9a, script: 0x22, flags: 0x0}, - 132: {region: 0x166, script: 0x5b, flags: 0x0}, - 133: {region: 0x9a, script: 0x22, flags: 0x0}, - 134: {region: 0xe8, script: 0x5b, flags: 0x0}, - 135: {region: 0x166, script: 0x5b, flags: 0x0}, - 136: {region: 0x9a, script: 0x22, flags: 0x0}, - 137: {region: 0x166, script: 0x5b, flags: 0x0}, - 138: {region: 0x140, script: 0x5b, flags: 0x0}, - 139: {region: 0x166, script: 0x5b, flags: 0x0}, - 140: {region: 0x166, script: 0x5b, flags: 0x0}, - 141: {region: 0xe8, script: 0x5b, flags: 0x0}, - 142: {region: 0x166, script: 0x5b, flags: 0x0}, - 143: {region: 0xd7, script: 0x5b, flags: 0x0}, - 144: {region: 0x166, script: 0x5b, flags: 0x0}, - 145: {region: 0x166, script: 0x5b, flags: 0x0}, - 146: {region: 0x166, script: 0x5b, flags: 0x0}, - 147: {region: 0x166, script: 0x2c, flags: 0x0}, - 148: {region: 0x9a, script: 0x22, flags: 0x0}, - 149: {region: 0x96, script: 0x5b, flags: 0x0}, - 150: {region: 0x166, script: 0x5b, flags: 0x0}, - 151: {region: 0x166, script: 0x5b, flags: 0x0}, - 152: {region: 0x115, script: 0x5b, flags: 0x0}, - 153: {region: 0x166, script: 0x5b, flags: 0x0}, - 154: {region: 0x166, script: 0x5b, flags: 0x0}, - 155: {region: 0x52, script: 0x5b, flags: 0x0}, - 156: {region: 0x166, script: 0x5b, flags: 0x0}, - 157: {region: 0xe8, script: 0x5b, flags: 0x0}, - 158: {region: 0x166, script: 0x5b, flags: 0x0}, - 159: {region: 0x13f, script: 0xe8, flags: 0x0}, - 160: {region: 0xc4, script: 0x5b, flags: 0x0}, - 161: {region: 0x166, script: 0x5b, flags: 0x0}, - 162: {region: 0x166, script: 0x5b, flags: 0x0}, - 163: {region: 0xc4, script: 0x5b, flags: 0x0}, - 164: {region: 0x166, script: 0x5b, flags: 0x0}, - 165: {region: 0x35, script: 0xe, flags: 0x0}, - 166: {region: 0x166, script: 0x5b, flags: 0x0}, - 167: {region: 0x166, script: 0x5b, flags: 0x0}, - 168: {region: 0x166, script: 0x5b, flags: 0x0}, - 169: {region: 0x53, script: 0xef, flags: 0x0}, - 170: {region: 0x166, script: 0x5b, flags: 0x0}, - 171: {region: 0x166, script: 0x5b, flags: 0x0}, - 172: {region: 0x166, script: 0x5b, flags: 0x0}, - 173: {region: 0x9a, script: 0xe, flags: 0x0}, - 174: {region: 0x166, script: 0x5b, flags: 0x0}, - 175: {region: 0x9d, script: 0x5, flags: 0x0}, - 176: {region: 0x166, script: 0x5b, flags: 0x0}, - 177: {region: 0x4f, script: 0x5b, flags: 0x0}, - 178: {region: 0x79, script: 0x5b, flags: 0x0}, - 179: {region: 0x9a, script: 0x22, flags: 0x0}, - 180: {region: 0xe9, script: 0x5, flags: 0x0}, - 181: {region: 0x9a, script: 0x22, flags: 0x0}, - 182: {region: 0x166, script: 0x5b, flags: 0x0}, - 183: {region: 0x33, script: 0x5b, flags: 0x0}, - 184: {region: 0x166, script: 0x5b, flags: 0x0}, - 185: {region: 0xb5, script: 0xc, flags: 0x0}, - 186: {region: 0x52, script: 0x5b, flags: 0x0}, - 187: {region: 0x166, script: 0x2c, flags: 0x0}, - 188: {region: 0xe8, script: 0x5b, flags: 0x0}, - 189: {region: 0x166, script: 0x5b, flags: 0x0}, - 190: {region: 0xe9, script: 0x22, flags: 0x0}, - 191: {region: 0x107, script: 0x20, flags: 0x0}, - 192: {region: 0x160, script: 0x5b, flags: 0x0}, - 193: {region: 0x166, script: 0x5b, flags: 0x0}, - 194: {region: 0x96, script: 0x5b, flags: 0x0}, - 195: {region: 0x166, script: 0x5b, flags: 0x0}, - 196: {region: 0x52, script: 0x5b, flags: 0x0}, - 197: {region: 0x166, script: 0x5b, flags: 0x0}, - 198: {region: 0x166, script: 0x5b, flags: 0x0}, - 199: {region: 0x166, script: 0x5b, flags: 0x0}, - 200: {region: 0x87, script: 0x5b, flags: 0x0}, - 201: {region: 0x166, script: 0x5b, flags: 0x0}, - 202: {region: 0x166, script: 0x5b, flags: 0x0}, - 203: {region: 0x166, script: 0x5b, flags: 0x0}, - 204: {region: 0x166, script: 0x5b, flags: 0x0}, - 205: {region: 0x6e, script: 0x2c, flags: 0x0}, - 206: {region: 0x166, script: 0x5b, flags: 0x0}, - 207: {region: 0x166, script: 0x5b, flags: 0x0}, - 208: {region: 0x52, script: 0x5b, flags: 0x0}, - 209: {region: 0x166, script: 0x5b, flags: 0x0}, - 210: {region: 0x166, script: 0x5b, flags: 0x0}, - 211: {region: 0xc4, script: 0x5b, flags: 0x0}, - 212: {region: 0x166, script: 0x5b, flags: 0x0}, - 213: {region: 0x166, script: 0x5b, flags: 0x0}, - 214: {region: 0x166, script: 0x5b, flags: 0x0}, - 215: {region: 0x6f, script: 0x5b, flags: 0x0}, - 216: {region: 0x166, script: 0x5b, flags: 0x0}, - 217: {region: 0x166, script: 0x5b, flags: 0x0}, - 218: {region: 0xd7, script: 0x5b, flags: 0x0}, - 219: {region: 0x35, script: 0x16, flags: 0x0}, - 220: {region: 0x107, script: 0x20, flags: 0x0}, - 221: {region: 0xe8, script: 0x5b, flags: 0x0}, - 222: {region: 0x166, script: 0x5b, flags: 0x0}, - 223: {region: 0x132, script: 0x5b, flags: 0x0}, - 224: {region: 0x8b, script: 0x5b, flags: 0x0}, - 225: {region: 0x76, script: 0x5b, flags: 0x0}, - 226: {region: 0x107, script: 0x20, flags: 0x0}, - 227: {region: 0x136, script: 0x5b, flags: 0x0}, - 228: {region: 0x49, script: 0x5b, flags: 0x0}, - 229: {region: 0x136, script: 0x1a, flags: 0x0}, - 230: {region: 0xa7, script: 0x5, flags: 0x0}, - 231: {region: 0x13f, script: 0x19, flags: 0x0}, - 232: {region: 0x166, script: 0x5b, flags: 0x0}, - 233: {region: 0x9c, script: 0x5, flags: 0x0}, - 234: {region: 0x166, script: 0x5b, flags: 0x0}, - 235: {region: 0x166, script: 0x5b, flags: 0x0}, - 236: {region: 0x166, script: 0x5b, flags: 0x0}, - 237: {region: 0x166, script: 0x5b, flags: 0x0}, - 238: {region: 0x166, script: 0x5b, flags: 0x0}, - 239: {region: 0xc6, script: 0xda, flags: 0x0}, - 240: {region: 0x79, script: 0x5b, flags: 0x0}, - 241: {region: 0x6c, script: 0x1d, flags: 0x0}, - 242: {region: 0xe8, script: 0x5b, flags: 0x0}, - 243: {region: 0x49, script: 0x17, flags: 0x0}, - 244: {region: 0x131, script: 0x20, flags: 0x0}, - 245: {region: 0x49, script: 0x17, flags: 0x0}, - 246: {region: 0x49, script: 0x17, flags: 0x0}, - 247: {region: 0x49, script: 0x17, flags: 0x0}, - 248: {region: 0x49, script: 0x17, flags: 0x0}, - 249: {region: 0x10b, script: 0x5b, flags: 0x0}, - 250: {region: 0x5f, script: 0x5b, flags: 0x0}, - 251: {region: 0xea, script: 0x5b, flags: 0x0}, - 252: {region: 0x49, script: 0x17, flags: 0x0}, - 253: {region: 0xc5, script: 0x88, flags: 0x0}, - 254: {region: 0x8, script: 0x2, flags: 0x1}, - 255: {region: 0x107, script: 0x20, flags: 0x0}, - 256: {region: 0x7c, script: 0x5b, flags: 0x0}, - 257: {region: 0x64, script: 0x5b, flags: 0x0}, - 258: {region: 0x166, script: 0x5b, flags: 0x0}, - 259: {region: 0x166, script: 0x5b, flags: 0x0}, - 260: {region: 0x166, script: 0x5b, flags: 0x0}, - 261: {region: 0x166, script: 0x5b, flags: 0x0}, - 262: {region: 0x136, script: 0x5b, flags: 0x0}, - 263: {region: 0x107, script: 0x20, flags: 0x0}, - 264: {region: 0xa5, script: 0x5b, flags: 0x0}, - 265: {region: 0x166, script: 0x5b, flags: 0x0}, - 266: {region: 0x166, script: 0x5b, flags: 0x0}, - 267: {region: 0x9a, script: 0x5, flags: 0x0}, - 268: {region: 0x166, script: 0x5b, flags: 0x0}, - 269: {region: 0x61, script: 0x5b, flags: 0x0}, - 270: {region: 0x166, script: 0x5b, flags: 0x0}, - 271: {region: 0x49, script: 0x5b, flags: 0x0}, - 272: {region: 0x166, script: 0x5b, flags: 0x0}, - 273: {region: 0x166, script: 0x5b, flags: 0x0}, - 274: {region: 0x166, script: 0x5b, flags: 0x0}, - 275: {region: 0x166, script: 0x5, flags: 0x0}, - 276: {region: 0x49, script: 0x5b, flags: 0x0}, - 277: {region: 0x166, script: 0x5b, flags: 0x0}, - 278: {region: 0x166, script: 0x5b, flags: 0x0}, - 279: {region: 0xd5, script: 0x5b, flags: 0x0}, - 280: {region: 0x4f, script: 0x5b, flags: 0x0}, - 281: {region: 0x166, script: 0x5b, flags: 0x0}, - 282: {region: 0x9a, script: 0x5, flags: 0x0}, - 283: {region: 0x166, script: 0x5b, flags: 0x0}, - 284: {region: 0x166, script: 0x5b, flags: 0x0}, - 285: {region: 0x166, script: 0x5b, flags: 0x0}, - 286: {region: 0x166, script: 0x2c, flags: 0x0}, - 287: {region: 0x61, script: 0x5b, flags: 0x0}, - 288: {region: 0xc4, script: 0x5b, flags: 0x0}, - 289: {region: 0xd1, script: 0x5b, flags: 0x0}, - 290: {region: 0x166, script: 0x5b, flags: 0x0}, - 291: {region: 0xdc, script: 0x22, flags: 0x0}, - 292: {region: 0x52, script: 0x5b, flags: 0x0}, - 293: {region: 0x166, script: 0x5b, flags: 0x0}, - 294: {region: 0x166, script: 0x5b, flags: 0x0}, - 295: {region: 0x166, script: 0x5b, flags: 0x0}, - 296: {region: 0xce, script: 0xed, flags: 0x0}, - 297: {region: 0x166, script: 0x5b, flags: 0x0}, - 298: {region: 0x166, script: 0x5b, flags: 0x0}, - 299: {region: 0x115, script: 0x5b, flags: 0x0}, - 300: {region: 0x37, script: 0x5b, flags: 0x0}, - 301: {region: 0x43, script: 0xef, flags: 0x0}, - 302: {region: 0x166, script: 0x5b, flags: 0x0}, - 303: {region: 0xa5, script: 0x5b, flags: 0x0}, - 304: {region: 0x81, script: 0x5b, flags: 0x0}, - 305: {region: 0xd7, script: 0x5b, flags: 0x0}, - 306: {region: 0x9f, script: 0x5b, flags: 0x0}, - 307: {region: 0x6c, script: 0x29, flags: 0x0}, - 308: {region: 0x166, script: 0x5b, flags: 0x0}, - 309: {region: 0xc5, script: 0x4b, flags: 0x0}, - 310: {region: 0x88, script: 0x34, flags: 0x0}, - 311: {region: 0x166, script: 0x5b, flags: 0x0}, - 312: {region: 0x166, script: 0x5b, flags: 0x0}, - 313: {region: 0xa, script: 0x2, flags: 0x1}, - 314: {region: 0x166, script: 0x5b, flags: 0x0}, - 315: {region: 0x166, script: 0x5b, flags: 0x0}, - 316: {region: 0x1, script: 0x5b, flags: 0x0}, - 317: {region: 0x166, script: 0x5b, flags: 0x0}, - 318: {region: 0x6f, script: 0x5b, flags: 0x0}, - 319: {region: 0x136, script: 0x5b, flags: 0x0}, - 320: {region: 0x6b, script: 0x5b, flags: 0x0}, - 321: {region: 0x166, script: 0x5b, flags: 0x0}, - 322: {region: 0x9f, script: 0x46, flags: 0x0}, - 323: {region: 0x166, script: 0x5b, flags: 0x0}, - 324: {region: 0x166, script: 0x5b, flags: 0x0}, - 325: {region: 0x6f, script: 0x5b, flags: 0x0}, - 326: {region: 0x52, script: 0x5b, flags: 0x0}, - 327: {region: 0x6f, script: 0x5b, flags: 0x0}, - 328: {region: 0x9d, script: 0x5, flags: 0x0}, - 329: {region: 0x166, script: 0x5b, flags: 0x0}, - 330: {region: 0x166, script: 0x5b, flags: 0x0}, - 331: {region: 0x166, script: 0x5b, flags: 0x0}, - 332: {region: 0x166, script: 0x5b, flags: 0x0}, - 333: {region: 0x87, script: 0x5b, flags: 0x0}, - 334: {region: 0xc, script: 0x2, flags: 0x1}, - 335: {region: 0x166, script: 0x5b, flags: 0x0}, - 336: {region: 0xc4, script: 0x5b, flags: 0x0}, - 337: {region: 0x73, script: 0x5b, flags: 0x0}, - 338: {region: 0x10c, script: 0x5, flags: 0x0}, - 339: {region: 0xe8, script: 0x5b, flags: 0x0}, - 340: {region: 0x10d, script: 0x5b, flags: 0x0}, - 341: {region: 0x74, script: 0x5b, flags: 0x0}, - 342: {region: 0x166, script: 0x5b, flags: 0x0}, - 343: {region: 0x166, script: 0x5b, flags: 0x0}, - 344: {region: 0x77, script: 0x5b, flags: 0x0}, - 345: {region: 0x166, script: 0x5b, flags: 0x0}, - 346: {region: 0x3b, script: 0x5b, flags: 0x0}, - 347: {region: 0x166, script: 0x5b, flags: 0x0}, - 348: {region: 0x166, script: 0x5b, flags: 0x0}, - 349: {region: 0x166, script: 0x5b, flags: 0x0}, - 350: {region: 0x79, script: 0x5b, flags: 0x0}, - 351: {region: 0x136, script: 0x5b, flags: 0x0}, - 352: {region: 0x79, script: 0x5b, flags: 0x0}, - 353: {region: 0x61, script: 0x5b, flags: 0x0}, - 354: {region: 0x61, script: 0x5b, flags: 0x0}, - 355: {region: 0x52, script: 0x5, flags: 0x0}, - 356: {region: 0x141, script: 0x5b, flags: 0x0}, - 357: {region: 0x166, script: 0x5b, flags: 0x0}, - 358: {region: 0x85, script: 0x5b, flags: 0x0}, - 359: {region: 0x166, script: 0x5b, flags: 0x0}, - 360: {region: 0xd5, script: 0x5b, flags: 0x0}, - 361: {region: 0x9f, script: 0x5b, flags: 0x0}, - 362: {region: 0xd7, script: 0x5b, flags: 0x0}, - 363: {region: 0x166, script: 0x5b, flags: 0x0}, - 364: {region: 0x10c, script: 0x5b, flags: 0x0}, - 365: {region: 0xda, script: 0x5b, flags: 0x0}, - 366: {region: 0x97, script: 0x5b, flags: 0x0}, - 367: {region: 0x81, script: 0x5b, flags: 0x0}, - 368: {region: 0x166, script: 0x5b, flags: 0x0}, - 369: {region: 0xbd, script: 0x5b, flags: 0x0}, - 370: {region: 0x166, script: 0x5b, flags: 0x0}, - 371: {region: 0x166, script: 0x5b, flags: 0x0}, - 372: {region: 0x166, script: 0x5b, flags: 0x0}, - 373: {region: 0x53, script: 0x3b, flags: 0x0}, - 374: {region: 0x166, script: 0x5b, flags: 0x0}, - 375: {region: 0x96, script: 0x5b, flags: 0x0}, - 376: {region: 0x166, script: 0x5b, flags: 0x0}, - 377: {region: 0x166, script: 0x5b, flags: 0x0}, - 378: {region: 0x9a, script: 0x22, flags: 0x0}, - 379: {region: 0x166, script: 0x5b, flags: 0x0}, - 380: {region: 0x9d, script: 0x5, flags: 0x0}, - 381: {region: 0x7f, script: 0x5b, flags: 0x0}, - 382: {region: 0x7c, script: 0x5b, flags: 0x0}, - 383: {region: 0x166, script: 0x5b, flags: 0x0}, - 384: {region: 0x166, script: 0x5b, flags: 0x0}, - 385: {region: 0x166, script: 0x5b, flags: 0x0}, - 386: {region: 0x166, script: 0x5b, flags: 0x0}, - 387: {region: 0x166, script: 0x5b, flags: 0x0}, - 388: {region: 0x166, script: 0x5b, flags: 0x0}, - 389: {region: 0x70, script: 0x2c, flags: 0x0}, - 390: {region: 0x166, script: 0x5b, flags: 0x0}, - 391: {region: 0xdc, script: 0x22, flags: 0x0}, - 392: {region: 0x166, script: 0x5b, flags: 0x0}, - 393: {region: 0xa8, script: 0x5b, flags: 0x0}, - 394: {region: 0x166, script: 0x5b, flags: 0x0}, - 395: {region: 0xe9, script: 0x5, flags: 0x0}, - 396: {region: 0x166, script: 0x5b, flags: 0x0}, - 397: {region: 0xe9, script: 0x5, flags: 0x0}, - 398: {region: 0x166, script: 0x5b, flags: 0x0}, - 399: {region: 0x166, script: 0x5b, flags: 0x0}, - 400: {region: 0x6f, script: 0x5b, flags: 0x0}, - 401: {region: 0x9d, script: 0x5, flags: 0x0}, - 402: {region: 0x166, script: 0x5b, flags: 0x0}, - 403: {region: 0x166, script: 0x2c, flags: 0x0}, - 404: {region: 0xf2, script: 0x5b, flags: 0x0}, - 405: {region: 0x166, script: 0x5b, flags: 0x0}, - 406: {region: 0x166, script: 0x5b, flags: 0x0}, - 407: {region: 0x166, script: 0x5b, flags: 0x0}, - 408: {region: 0x166, script: 0x2c, flags: 0x0}, - 409: {region: 0x166, script: 0x5b, flags: 0x0}, - 410: {region: 0x9a, script: 0x22, flags: 0x0}, - 411: {region: 0x9a, script: 0xe9, flags: 0x0}, - 412: {region: 0x96, script: 0x5b, flags: 0x0}, - 413: {region: 0xda, script: 0x5b, flags: 0x0}, - 414: {region: 0x131, script: 0x32, flags: 0x0}, - 415: {region: 0x166, script: 0x5b, flags: 0x0}, - 416: {region: 0xe, script: 0x2, flags: 0x1}, - 417: {region: 0x9a, script: 0xe, flags: 0x0}, - 418: {region: 0x166, script: 0x5b, flags: 0x0}, - 419: {region: 0x4e, script: 0x5b, flags: 0x0}, - 420: {region: 0x9a, script: 0x35, flags: 0x0}, - 421: {region: 0x41, script: 0x5b, flags: 0x0}, - 422: {region: 0x54, script: 0x5b, flags: 0x0}, - 423: {region: 0x166, script: 0x5b, flags: 0x0}, - 424: {region: 0x81, script: 0x5b, flags: 0x0}, - 425: {region: 0x166, script: 0x5b, flags: 0x0}, - 426: {region: 0x166, script: 0x5b, flags: 0x0}, - 427: {region: 0xa5, script: 0x5b, flags: 0x0}, - 428: {region: 0x99, script: 0x5b, flags: 0x0}, - 429: {region: 0x166, script: 0x5b, flags: 0x0}, - 430: {region: 0xdc, script: 0x22, flags: 0x0}, - 431: {region: 0x166, script: 0x5b, flags: 0x0}, - 432: {region: 0x166, script: 0x5, flags: 0x0}, - 433: {region: 0x49, script: 0x5b, flags: 0x0}, - 434: {region: 0x166, script: 0x5, flags: 0x0}, - 435: {region: 0x166, script: 0x5b, flags: 0x0}, - 436: {region: 0x10, script: 0x3, flags: 0x1}, - 437: {region: 0x166, script: 0x5b, flags: 0x0}, - 438: {region: 0x53, script: 0x3b, flags: 0x0}, - 439: {region: 0x166, script: 0x5b, flags: 0x0}, - 440: {region: 0x136, script: 0x5b, flags: 0x0}, - 441: {region: 0x24, script: 0x5, flags: 0x0}, - 442: {region: 0x166, script: 0x5b, flags: 0x0}, - 443: {region: 0x166, script: 0x2c, flags: 0x0}, - 444: {region: 0x98, script: 0x3e, flags: 0x0}, - 445: {region: 0x166, script: 0x5b, flags: 0x0}, - 446: {region: 0x9a, script: 0x22, flags: 0x0}, - 447: {region: 0x166, script: 0x5b, flags: 0x0}, - 448: {region: 0x74, script: 0x5b, flags: 0x0}, - 449: {region: 0x166, script: 0x5b, flags: 0x0}, - 450: {region: 0x166, script: 0x5b, flags: 0x0}, - 451: {region: 0xe8, script: 0x5b, flags: 0x0}, - 452: {region: 0x166, script: 0x5b, flags: 0x0}, - 453: {region: 0x12c, script: 0x40, flags: 0x0}, - 454: {region: 0x53, script: 0x92, flags: 0x0}, - 455: {region: 0x166, script: 0x5b, flags: 0x0}, - 456: {region: 0xe9, script: 0x5, flags: 0x0}, - 457: {region: 0x9a, script: 0x22, flags: 0x0}, - 458: {region: 0xb0, script: 0x41, flags: 0x0}, - 459: {region: 0xe8, script: 0x5b, flags: 0x0}, - 460: {region: 0xe9, script: 0x5, flags: 0x0}, - 461: {region: 0xe7, script: 0x5b, flags: 0x0}, - 462: {region: 0x9a, script: 0x22, flags: 0x0}, - 463: {region: 0x9a, script: 0x22, flags: 0x0}, - 464: {region: 0x166, script: 0x5b, flags: 0x0}, - 465: {region: 0x91, script: 0x5b, flags: 0x0}, - 466: {region: 0x61, script: 0x5b, flags: 0x0}, - 467: {region: 0x53, script: 0x3b, flags: 0x0}, - 468: {region: 0x92, script: 0x5b, flags: 0x0}, - 469: {region: 0x93, script: 0x5b, flags: 0x0}, - 470: {region: 0x166, script: 0x5b, flags: 0x0}, - 471: {region: 0x28, script: 0x8, flags: 0x0}, - 472: {region: 0xd3, script: 0x5b, flags: 0x0}, - 473: {region: 0x79, script: 0x5b, flags: 0x0}, - 474: {region: 0x166, script: 0x5b, flags: 0x0}, - 475: {region: 0x166, script: 0x5b, flags: 0x0}, - 476: {region: 0xd1, script: 0x5b, flags: 0x0}, - 477: {region: 0xd7, script: 0x5b, flags: 0x0}, - 478: {region: 0x166, script: 0x5b, flags: 0x0}, - 479: {region: 0x166, script: 0x5b, flags: 0x0}, - 480: {region: 0x166, script: 0x5b, flags: 0x0}, - 481: {region: 0x96, script: 0x5b, flags: 0x0}, - 482: {region: 0x166, script: 0x5b, flags: 0x0}, - 483: {region: 0x166, script: 0x5b, flags: 0x0}, - 484: {region: 0x166, script: 0x5b, flags: 0x0}, - 486: {region: 0x123, script: 0x5b, flags: 0x0}, - 487: {region: 0xd7, script: 0x5b, flags: 0x0}, - 488: {region: 0x166, script: 0x5b, flags: 0x0}, - 489: {region: 0x166, script: 0x5b, flags: 0x0}, - 490: {region: 0x53, script: 0xfd, flags: 0x0}, - 491: {region: 0x166, script: 0x5b, flags: 0x0}, - 492: {region: 0x136, script: 0x5b, flags: 0x0}, - 493: {region: 0x166, script: 0x5b, flags: 0x0}, - 494: {region: 0x49, script: 0x5b, flags: 0x0}, - 495: {region: 0x166, script: 0x5b, flags: 0x0}, - 496: {region: 0x166, script: 0x5b, flags: 0x0}, - 497: {region: 0xe8, script: 0x5b, flags: 0x0}, - 498: {region: 0x166, script: 0x5b, flags: 0x0}, - 499: {region: 0x96, script: 0x5b, flags: 0x0}, - 500: {region: 0x107, script: 0x20, flags: 0x0}, - 501: {region: 0x1, script: 0x5b, flags: 0x0}, - 502: {region: 0x166, script: 0x5b, flags: 0x0}, - 503: {region: 0x166, script: 0x5b, flags: 0x0}, - 504: {region: 0x9e, script: 0x5b, flags: 0x0}, - 505: {region: 0x9f, script: 0x5b, flags: 0x0}, - 506: {region: 0x49, script: 0x17, flags: 0x0}, - 507: {region: 0x98, script: 0x3e, flags: 0x0}, - 508: {region: 0x166, script: 0x5b, flags: 0x0}, - 509: {region: 0x166, script: 0x5b, flags: 0x0}, - 510: {region: 0x107, script: 0x5b, flags: 0x0}, - 511: {region: 0x166, script: 0x5b, flags: 0x0}, - 512: {region: 0xa3, script: 0x49, flags: 0x0}, - 513: {region: 0x166, script: 0x5b, flags: 0x0}, - 514: {region: 0xa1, script: 0x5b, flags: 0x0}, - 515: {region: 0x1, script: 0x5b, flags: 0x0}, - 516: {region: 0x166, script: 0x5b, flags: 0x0}, - 517: {region: 0x166, script: 0x5b, flags: 0x0}, - 518: {region: 0x166, script: 0x5b, flags: 0x0}, - 519: {region: 0x52, script: 0x5b, flags: 0x0}, - 520: {region: 0x131, script: 0x3e, flags: 0x0}, - 521: {region: 0x166, script: 0x5b, flags: 0x0}, - 522: {region: 0x130, script: 0x5b, flags: 0x0}, - 523: {region: 0xdc, script: 0x22, flags: 0x0}, - 524: {region: 0x166, script: 0x5b, flags: 0x0}, - 525: {region: 0x64, script: 0x5b, flags: 0x0}, - 526: {region: 0x96, script: 0x5b, flags: 0x0}, - 527: {region: 0x96, script: 0x5b, flags: 0x0}, - 528: {region: 0x7e, script: 0x2e, flags: 0x0}, - 529: {region: 0x138, script: 0x20, flags: 0x0}, - 530: {region: 0x68, script: 0x5b, flags: 0x0}, - 531: {region: 0xc5, script: 0x5b, flags: 0x0}, - 532: {region: 0x166, script: 0x5b, flags: 0x0}, - 533: {region: 0x166, script: 0x5b, flags: 0x0}, - 534: {region: 0xd7, script: 0x5b, flags: 0x0}, - 535: {region: 0xa5, script: 0x5b, flags: 0x0}, - 536: {region: 0xc4, script: 0x5b, flags: 0x0}, - 537: {region: 0x107, script: 0x20, flags: 0x0}, - 538: {region: 0x166, script: 0x5b, flags: 0x0}, - 539: {region: 0x166, script: 0x5b, flags: 0x0}, - 540: {region: 0x166, script: 0x5b, flags: 0x0}, - 541: {region: 0x166, script: 0x5b, flags: 0x0}, - 542: {region: 0xd5, script: 0x5, flags: 0x0}, - 543: {region: 0xd7, script: 0x5b, flags: 0x0}, - 544: {region: 0x165, script: 0x5b, flags: 0x0}, - 545: {region: 0x166, script: 0x5b, flags: 0x0}, - 546: {region: 0x166, script: 0x5b, flags: 0x0}, - 547: {region: 0x130, script: 0x5b, flags: 0x0}, - 548: {region: 0x123, script: 0x5, flags: 0x0}, - 549: {region: 0x166, script: 0x5b, flags: 0x0}, - 550: {region: 0x124, script: 0xee, flags: 0x0}, - 551: {region: 0x5b, script: 0x5b, flags: 0x0}, - 552: {region: 0x52, script: 0x5b, flags: 0x0}, - 553: {region: 0x166, script: 0x5b, flags: 0x0}, - 554: {region: 0x4f, script: 0x5b, flags: 0x0}, - 555: {region: 0x9a, script: 0x22, flags: 0x0}, - 556: {region: 0x9a, script: 0x22, flags: 0x0}, - 557: {region: 0x4b, script: 0x5b, flags: 0x0}, - 558: {region: 0x96, script: 0x5b, flags: 0x0}, - 559: {region: 0x166, script: 0x5b, flags: 0x0}, - 560: {region: 0x41, script: 0x5b, flags: 0x0}, - 561: {region: 0x9a, script: 0x5b, flags: 0x0}, - 562: {region: 0x53, script: 0xe5, flags: 0x0}, - 563: {region: 0x9a, script: 0x22, flags: 0x0}, - 564: {region: 0xc4, script: 0x5b, flags: 0x0}, - 565: {region: 0x166, script: 0x5b, flags: 0x0}, - 566: {region: 0x9a, script: 0x76, flags: 0x0}, - 567: {region: 0xe9, script: 0x5, flags: 0x0}, - 568: {region: 0x166, script: 0x5b, flags: 0x0}, - 569: {region: 0xa5, script: 0x5b, flags: 0x0}, - 570: {region: 0x166, script: 0x5b, flags: 0x0}, - 571: {region: 0x12c, script: 0x5b, flags: 0x0}, - 572: {region: 0x166, script: 0x5b, flags: 0x0}, - 573: {region: 0xd3, script: 0x5b, flags: 0x0}, - 574: {region: 0x166, script: 0x5b, flags: 0x0}, - 575: {region: 0xb0, script: 0x58, flags: 0x0}, - 576: {region: 0x166, script: 0x5b, flags: 0x0}, - 577: {region: 0x166, script: 0x5b, flags: 0x0}, - 578: {region: 0x13, script: 0x6, flags: 0x1}, - 579: {region: 0x166, script: 0x5b, flags: 0x0}, - 580: {region: 0x52, script: 0x5b, flags: 0x0}, - 581: {region: 0x83, script: 0x5b, flags: 0x0}, - 582: {region: 0xa5, script: 0x5b, flags: 0x0}, - 583: {region: 0x166, script: 0x5b, flags: 0x0}, - 584: {region: 0x166, script: 0x5b, flags: 0x0}, - 585: {region: 0x166, script: 0x5b, flags: 0x0}, - 586: {region: 0xa7, script: 0x4f, flags: 0x0}, - 587: {region: 0x2a, script: 0x5b, flags: 0x0}, - 588: {region: 0x166, script: 0x5b, flags: 0x0}, - 589: {region: 0x166, script: 0x5b, flags: 0x0}, - 590: {region: 0x166, script: 0x5b, flags: 0x0}, - 591: {region: 0x166, script: 0x5b, flags: 0x0}, - 592: {region: 0x166, script: 0x5b, flags: 0x0}, - 593: {region: 0x9a, script: 0x53, flags: 0x0}, - 594: {region: 0x8c, script: 0x5b, flags: 0x0}, - 595: {region: 0x166, script: 0x5b, flags: 0x0}, - 596: {region: 0xac, script: 0x54, flags: 0x0}, - 597: {region: 0x107, script: 0x20, flags: 0x0}, - 598: {region: 0x9a, script: 0x22, flags: 0x0}, - 599: {region: 0x166, script: 0x5b, flags: 0x0}, - 600: {region: 0x76, script: 0x5b, flags: 0x0}, - 601: {region: 0x166, script: 0x5b, flags: 0x0}, - 602: {region: 0xb5, script: 0x5b, flags: 0x0}, - 603: {region: 0x166, script: 0x5b, flags: 0x0}, - 604: {region: 0x166, script: 0x5b, flags: 0x0}, - 605: {region: 0x166, script: 0x5b, flags: 0x0}, - 606: {region: 0x166, script: 0x5b, flags: 0x0}, - 607: {region: 0x166, script: 0x5b, flags: 0x0}, - 608: {region: 0x166, script: 0x5b, flags: 0x0}, - 609: {region: 0x166, script: 0x5b, flags: 0x0}, - 610: {region: 0x166, script: 0x2c, flags: 0x0}, - 611: {region: 0x166, script: 0x5b, flags: 0x0}, - 612: {region: 0x107, script: 0x20, flags: 0x0}, - 613: {region: 0x113, script: 0x5b, flags: 0x0}, - 614: {region: 0xe8, script: 0x5b, flags: 0x0}, - 615: {region: 0x107, script: 0x5b, flags: 0x0}, - 616: {region: 0x166, script: 0x5b, flags: 0x0}, - 617: {region: 0x9a, script: 0x22, flags: 0x0}, - 618: {region: 0x9a, script: 0x5, flags: 0x0}, - 619: {region: 0x130, script: 0x5b, flags: 0x0}, - 620: {region: 0x166, script: 0x5b, flags: 0x0}, - 621: {region: 0x52, script: 0x5b, flags: 0x0}, - 622: {region: 0x61, script: 0x5b, flags: 0x0}, - 623: {region: 0x166, script: 0x5b, flags: 0x0}, - 624: {region: 0x166, script: 0x5b, flags: 0x0}, - 625: {region: 0x166, script: 0x2c, flags: 0x0}, - 626: {region: 0x166, script: 0x5b, flags: 0x0}, - 627: {region: 0x166, script: 0x5b, flags: 0x0}, - 628: {region: 0x19, script: 0x3, flags: 0x1}, - 629: {region: 0x166, script: 0x5b, flags: 0x0}, - 630: {region: 0x166, script: 0x5b, flags: 0x0}, - 631: {region: 0x166, script: 0x5b, flags: 0x0}, - 632: {region: 0x166, script: 0x5b, flags: 0x0}, - 633: {region: 0x107, script: 0x20, flags: 0x0}, - 634: {region: 0x166, script: 0x5b, flags: 0x0}, - 635: {region: 0x166, script: 0x5b, flags: 0x0}, - 636: {region: 0x166, script: 0x5b, flags: 0x0}, - 637: {region: 0x107, script: 0x20, flags: 0x0}, - 638: {region: 0x166, script: 0x5b, flags: 0x0}, - 639: {region: 0x96, script: 0x5b, flags: 0x0}, - 640: {region: 0xe9, script: 0x5, flags: 0x0}, - 641: {region: 0x7c, script: 0x5b, flags: 0x0}, - 642: {region: 0x166, script: 0x5b, flags: 0x0}, - 643: {region: 0x166, script: 0x5b, flags: 0x0}, - 644: {region: 0x166, script: 0x5b, flags: 0x0}, - 645: {region: 0x166, script: 0x2c, flags: 0x0}, - 646: {region: 0x124, script: 0xee, flags: 0x0}, - 647: {region: 0xe9, script: 0x5, flags: 0x0}, - 648: {region: 0x166, script: 0x5b, flags: 0x0}, - 649: {region: 0x166, script: 0x5b, flags: 0x0}, - 650: {region: 0x1c, script: 0x5, flags: 0x1}, - 651: {region: 0x166, script: 0x5b, flags: 0x0}, - 652: {region: 0x166, script: 0x5b, flags: 0x0}, - 653: {region: 0x166, script: 0x5b, flags: 0x0}, - 654: {region: 0x139, script: 0x5b, flags: 0x0}, - 655: {region: 0x88, script: 0x5f, flags: 0x0}, - 656: {region: 0x98, script: 0x3e, flags: 0x0}, - 657: {region: 0x130, script: 0x5b, flags: 0x0}, - 658: {region: 0xe9, script: 0x5, flags: 0x0}, - 659: {region: 0x132, script: 0x5b, flags: 0x0}, - 660: {region: 0x166, script: 0x5b, flags: 0x0}, - 661: {region: 0xb8, script: 0x5b, flags: 0x0}, - 662: {region: 0x107, script: 0x20, flags: 0x0}, - 663: {region: 0x166, script: 0x5b, flags: 0x0}, - 664: {region: 0x96, script: 0x5b, flags: 0x0}, - 665: {region: 0x166, script: 0x5b, flags: 0x0}, - 666: {region: 0x53, script: 0xee, flags: 0x0}, - 667: {region: 0x166, script: 0x5b, flags: 0x0}, - 668: {region: 0x166, script: 0x5b, flags: 0x0}, - 669: {region: 0x166, script: 0x5b, flags: 0x0}, - 670: {region: 0x166, script: 0x5b, flags: 0x0}, - 671: {region: 0x9a, script: 0x5d, flags: 0x0}, - 672: {region: 0x166, script: 0x5b, flags: 0x0}, - 673: {region: 0x166, script: 0x5b, flags: 0x0}, - 674: {region: 0x107, script: 0x20, flags: 0x0}, - 675: {region: 0x132, script: 0x5b, flags: 0x0}, - 676: {region: 0x166, script: 0x5b, flags: 0x0}, - 677: {region: 0xda, script: 0x5b, flags: 0x0}, - 678: {region: 0x166, script: 0x5b, flags: 0x0}, - 679: {region: 0x166, script: 0x5b, flags: 0x0}, - 680: {region: 0x21, script: 0x2, flags: 0x1}, - 681: {region: 0x166, script: 0x5b, flags: 0x0}, - 682: {region: 0x166, script: 0x5b, flags: 0x0}, - 683: {region: 0x9f, script: 0x5b, flags: 0x0}, - 684: {region: 0x53, script: 0x61, flags: 0x0}, - 685: {region: 0x96, script: 0x5b, flags: 0x0}, - 686: {region: 0x9d, script: 0x5, flags: 0x0}, - 687: {region: 0x136, script: 0x5b, flags: 0x0}, - 688: {region: 0x166, script: 0x5b, flags: 0x0}, - 689: {region: 0x166, script: 0x5b, flags: 0x0}, - 690: {region: 0x9a, script: 0xe9, flags: 0x0}, - 691: {region: 0x9f, script: 0x5b, flags: 0x0}, - 692: {region: 0x166, script: 0x5b, flags: 0x0}, - 693: {region: 0x4b, script: 0x5b, flags: 0x0}, - 694: {region: 0x166, script: 0x5b, flags: 0x0}, - 695: {region: 0x166, script: 0x5b, flags: 0x0}, - 696: {region: 0xb0, script: 0x58, flags: 0x0}, - 697: {region: 0x166, script: 0x5b, flags: 0x0}, - 698: {region: 0x166, script: 0x5b, flags: 0x0}, - 699: {region: 0x4b, script: 0x5b, flags: 0x0}, - 700: {region: 0x166, script: 0x5b, flags: 0x0}, - 701: {region: 0x166, script: 0x5b, flags: 0x0}, - 702: {region: 0x163, script: 0x5b, flags: 0x0}, - 703: {region: 0x9d, script: 0x5, flags: 0x0}, - 704: {region: 0xb7, script: 0x5b, flags: 0x0}, - 705: {region: 0xb9, script: 0x5b, flags: 0x0}, - 706: {region: 0x4b, script: 0x5b, flags: 0x0}, - 707: {region: 0x4b, script: 0x5b, flags: 0x0}, - 708: {region: 0xa5, script: 0x5b, flags: 0x0}, - 709: {region: 0xa5, script: 0x5b, flags: 0x0}, - 710: {region: 0x9d, script: 0x5, flags: 0x0}, - 711: {region: 0xb9, script: 0x5b, flags: 0x0}, - 712: {region: 0x124, script: 0xee, flags: 0x0}, - 713: {region: 0x53, script: 0x3b, flags: 0x0}, - 714: {region: 0x12c, script: 0x5b, flags: 0x0}, - 715: {region: 0x96, script: 0x5b, flags: 0x0}, - 716: {region: 0x52, script: 0x5b, flags: 0x0}, - 717: {region: 0x9a, script: 0x22, flags: 0x0}, - 718: {region: 0x9a, script: 0x22, flags: 0x0}, - 719: {region: 0x96, script: 0x5b, flags: 0x0}, - 720: {region: 0x23, script: 0x3, flags: 0x1}, - 721: {region: 0xa5, script: 0x5b, flags: 0x0}, - 722: {region: 0x166, script: 0x5b, flags: 0x0}, - 723: {region: 0xd0, script: 0x5b, flags: 0x0}, - 724: {region: 0x166, script: 0x5b, flags: 0x0}, - 725: {region: 0x166, script: 0x5b, flags: 0x0}, - 726: {region: 0x166, script: 0x5b, flags: 0x0}, - 727: {region: 0x166, script: 0x5b, flags: 0x0}, - 728: {region: 0x166, script: 0x5b, flags: 0x0}, - 729: {region: 0x166, script: 0x5b, flags: 0x0}, - 730: {region: 0x166, script: 0x5b, flags: 0x0}, - 731: {region: 0x166, script: 0x5b, flags: 0x0}, - 732: {region: 0x166, script: 0x5b, flags: 0x0}, - 733: {region: 0x166, script: 0x5b, flags: 0x0}, - 734: {region: 0x166, script: 0x5b, flags: 0x0}, - 735: {region: 0x166, script: 0x5, flags: 0x0}, - 736: {region: 0x107, script: 0x20, flags: 0x0}, - 737: {region: 0xe8, script: 0x5b, flags: 0x0}, - 738: {region: 0x166, script: 0x5b, flags: 0x0}, - 739: {region: 0x96, script: 0x5b, flags: 0x0}, - 740: {region: 0x166, script: 0x2c, flags: 0x0}, - 741: {region: 0x166, script: 0x5b, flags: 0x0}, - 742: {region: 0x166, script: 0x5b, flags: 0x0}, - 743: {region: 0x166, script: 0x5b, flags: 0x0}, - 744: {region: 0x113, script: 0x5b, flags: 0x0}, - 745: {region: 0xa5, script: 0x5b, flags: 0x0}, - 746: {region: 0x166, script: 0x5b, flags: 0x0}, - 747: {region: 0x166, script: 0x5b, flags: 0x0}, - 748: {region: 0x124, script: 0x5, flags: 0x0}, - 749: {region: 0xcd, script: 0x5b, flags: 0x0}, - 750: {region: 0x166, script: 0x5b, flags: 0x0}, - 751: {region: 0x166, script: 0x5b, flags: 0x0}, - 752: {region: 0x166, script: 0x5b, flags: 0x0}, - 753: {region: 0xc0, script: 0x5b, flags: 0x0}, - 754: {region: 0xd2, script: 0x5b, flags: 0x0}, - 755: {region: 0x166, script: 0x5b, flags: 0x0}, - 756: {region: 0x52, script: 0x5b, flags: 0x0}, - 757: {region: 0xdc, script: 0x22, flags: 0x0}, - 758: {region: 0x130, script: 0x5b, flags: 0x0}, - 759: {region: 0xc1, script: 0x5b, flags: 0x0}, - 760: {region: 0x166, script: 0x5b, flags: 0x0}, - 761: {region: 0x166, script: 0x5b, flags: 0x0}, - 762: {region: 0xe1, script: 0x5b, flags: 0x0}, - 763: {region: 0x166, script: 0x5b, flags: 0x0}, - 764: {region: 0x96, script: 0x5b, flags: 0x0}, - 765: {region: 0x9c, script: 0x3d, flags: 0x0}, - 766: {region: 0x166, script: 0x5b, flags: 0x0}, - 767: {region: 0xc3, script: 0x20, flags: 0x0}, - 768: {region: 0x166, script: 0x5, flags: 0x0}, - 769: {region: 0x166, script: 0x5b, flags: 0x0}, - 770: {region: 0x166, script: 0x5b, flags: 0x0}, - 771: {region: 0x166, script: 0x5b, flags: 0x0}, - 772: {region: 0x9a, script: 0x6f, flags: 0x0}, - 773: {region: 0x166, script: 0x5b, flags: 0x0}, - 774: {region: 0x166, script: 0x5b, flags: 0x0}, - 775: {region: 0x10c, script: 0x5b, flags: 0x0}, - 776: {region: 0x166, script: 0x5b, flags: 0x0}, - 777: {region: 0x166, script: 0x5b, flags: 0x0}, - 778: {region: 0x166, script: 0x5b, flags: 0x0}, - 779: {region: 0x26, script: 0x3, flags: 0x1}, - 780: {region: 0x166, script: 0x5b, flags: 0x0}, - 781: {region: 0x166, script: 0x5b, flags: 0x0}, - 782: {region: 0x9a, script: 0xe, flags: 0x0}, - 783: {region: 0xc5, script: 0x76, flags: 0x0}, - 785: {region: 0x166, script: 0x5b, flags: 0x0}, - 786: {region: 0x49, script: 0x5b, flags: 0x0}, - 787: {region: 0x49, script: 0x5b, flags: 0x0}, - 788: {region: 0x37, script: 0x5b, flags: 0x0}, - 789: {region: 0x166, script: 0x5b, flags: 0x0}, - 790: {region: 0x166, script: 0x5b, flags: 0x0}, - 791: {region: 0x166, script: 0x5b, flags: 0x0}, - 792: {region: 0x166, script: 0x5b, flags: 0x0}, - 793: {region: 0x166, script: 0x5b, flags: 0x0}, - 794: {region: 0x166, script: 0x5b, flags: 0x0}, - 795: {region: 0x9a, script: 0x22, flags: 0x0}, - 796: {region: 0xdc, script: 0x22, flags: 0x0}, - 797: {region: 0x107, script: 0x20, flags: 0x0}, - 798: {region: 0x35, script: 0x73, flags: 0x0}, - 799: {region: 0x29, script: 0x3, flags: 0x1}, - 800: {region: 0xcc, script: 0x5b, flags: 0x0}, - 801: {region: 0x166, script: 0x5b, flags: 0x0}, - 802: {region: 0x166, script: 0x5b, flags: 0x0}, - 803: {region: 0x166, script: 0x5b, flags: 0x0}, - 804: {region: 0x9a, script: 0x22, flags: 0x0}, - 805: {region: 0x52, script: 0x5b, flags: 0x0}, - 807: {region: 0x166, script: 0x5b, flags: 0x0}, - 808: {region: 0x136, script: 0x5b, flags: 0x0}, - 809: {region: 0x166, script: 0x5b, flags: 0x0}, - 810: {region: 0x166, script: 0x5b, flags: 0x0}, - 811: {region: 0xe9, script: 0x5, flags: 0x0}, - 812: {region: 0xc4, script: 0x5b, flags: 0x0}, - 813: {region: 0x9a, script: 0x22, flags: 0x0}, - 814: {region: 0x96, script: 0x5b, flags: 0x0}, - 815: {region: 0x165, script: 0x5b, flags: 0x0}, - 816: {region: 0x166, script: 0x5b, flags: 0x0}, - 817: {region: 0xc5, script: 0x76, flags: 0x0}, - 818: {region: 0x166, script: 0x5b, flags: 0x0}, - 819: {region: 0x166, script: 0x2c, flags: 0x0}, - 820: {region: 0x107, script: 0x20, flags: 0x0}, - 821: {region: 0x166, script: 0x5b, flags: 0x0}, - 822: {region: 0x132, script: 0x5b, flags: 0x0}, - 823: {region: 0x9d, script: 0x67, flags: 0x0}, - 824: {region: 0x166, script: 0x5b, flags: 0x0}, - 825: {region: 0x166, script: 0x5b, flags: 0x0}, - 826: {region: 0x9d, script: 0x5, flags: 0x0}, - 827: {region: 0x166, script: 0x5b, flags: 0x0}, - 828: {region: 0x166, script: 0x5b, flags: 0x0}, - 829: {region: 0x166, script: 0x5b, flags: 0x0}, - 830: {region: 0xde, script: 0x5b, flags: 0x0}, - 831: {region: 0x166, script: 0x5b, flags: 0x0}, - 832: {region: 0x166, script: 0x5b, flags: 0x0}, - 834: {region: 0x166, script: 0x5b, flags: 0x0}, - 835: {region: 0x53, script: 0x3b, flags: 0x0}, - 836: {region: 0x9f, script: 0x5b, flags: 0x0}, - 837: {region: 0xd3, script: 0x5b, flags: 0x0}, - 838: {region: 0x166, script: 0x5b, flags: 0x0}, - 839: {region: 0xdb, script: 0x5b, flags: 0x0}, - 840: {region: 0x166, script: 0x5b, flags: 0x0}, - 841: {region: 0x166, script: 0x5b, flags: 0x0}, - 842: {region: 0x166, script: 0x5b, flags: 0x0}, - 843: {region: 0xd0, script: 0x5b, flags: 0x0}, - 844: {region: 0x166, script: 0x5b, flags: 0x0}, - 845: {region: 0x166, script: 0x5b, flags: 0x0}, - 846: {region: 0x165, script: 0x5b, flags: 0x0}, - 847: {region: 0xd2, script: 0x5b, flags: 0x0}, - 848: {region: 0x61, script: 0x5b, flags: 0x0}, - 849: {region: 0xdc, script: 0x22, flags: 0x0}, - 850: {region: 0x166, script: 0x5b, flags: 0x0}, - 851: {region: 0xdc, script: 0x22, flags: 0x0}, - 852: {region: 0x166, script: 0x5b, flags: 0x0}, - 853: {region: 0x166, script: 0x5b, flags: 0x0}, - 854: {region: 0xd3, script: 0x5b, flags: 0x0}, - 855: {region: 0x166, script: 0x5b, flags: 0x0}, - 856: {region: 0x166, script: 0x5b, flags: 0x0}, - 857: {region: 0xd2, script: 0x5b, flags: 0x0}, - 858: {region: 0x166, script: 0x5b, flags: 0x0}, - 859: {region: 0xd0, script: 0x5b, flags: 0x0}, - 860: {region: 0xd0, script: 0x5b, flags: 0x0}, - 861: {region: 0x166, script: 0x5b, flags: 0x0}, - 862: {region: 0x166, script: 0x5b, flags: 0x0}, - 863: {region: 0x96, script: 0x5b, flags: 0x0}, - 864: {region: 0x166, script: 0x5b, flags: 0x0}, - 865: {region: 0xe0, script: 0x5b, flags: 0x0}, - 866: {region: 0x166, script: 0x5b, flags: 0x0}, - 867: {region: 0x166, script: 0x5b, flags: 0x0}, - 868: {region: 0x9a, script: 0x5b, flags: 0x0}, - 869: {region: 0x166, script: 0x5b, flags: 0x0}, - 870: {region: 0x166, script: 0x5b, flags: 0x0}, - 871: {region: 0xda, script: 0x5b, flags: 0x0}, - 872: {region: 0x52, script: 0x5b, flags: 0x0}, - 873: {region: 0x166, script: 0x5b, flags: 0x0}, - 874: {region: 0xdb, script: 0x5b, flags: 0x0}, - 875: {region: 0x166, script: 0x5b, flags: 0x0}, - 876: {region: 0x52, script: 0x5b, flags: 0x0}, - 877: {region: 0x166, script: 0x5b, flags: 0x0}, - 878: {region: 0x166, script: 0x5b, flags: 0x0}, - 879: {region: 0xdb, script: 0x5b, flags: 0x0}, - 880: {region: 0x124, script: 0x57, flags: 0x0}, - 881: {region: 0x9a, script: 0x22, flags: 0x0}, - 882: {region: 0x10d, script: 0xcb, flags: 0x0}, - 883: {region: 0x166, script: 0x5b, flags: 0x0}, - 884: {region: 0x166, script: 0x5b, flags: 0x0}, - 885: {region: 0x85, script: 0x7e, flags: 0x0}, - 886: {region: 0x162, script: 0x5b, flags: 0x0}, - 887: {region: 0x166, script: 0x5b, flags: 0x0}, - 888: {region: 0x49, script: 0x17, flags: 0x0}, - 889: {region: 0x166, script: 0x5b, flags: 0x0}, - 890: {region: 0x162, script: 0x5b, flags: 0x0}, - 891: {region: 0x166, script: 0x5b, flags: 0x0}, - 892: {region: 0x166, script: 0x5b, flags: 0x0}, - 893: {region: 0x166, script: 0x5b, flags: 0x0}, - 894: {region: 0x166, script: 0x5b, flags: 0x0}, - 895: {region: 0x166, script: 0x5b, flags: 0x0}, - 896: {region: 0x118, script: 0x5b, flags: 0x0}, - 897: {region: 0x166, script: 0x5b, flags: 0x0}, - 898: {region: 0x166, script: 0x5b, flags: 0x0}, - 899: {region: 0x136, script: 0x5b, flags: 0x0}, - 900: {region: 0x166, script: 0x5b, flags: 0x0}, - 901: {region: 0x53, script: 0x5b, flags: 0x0}, - 902: {region: 0x166, script: 0x5b, flags: 0x0}, - 903: {region: 0xcf, script: 0x5b, flags: 0x0}, - 904: {region: 0x130, script: 0x5b, flags: 0x0}, - 905: {region: 0x132, script: 0x5b, flags: 0x0}, - 906: {region: 0x81, script: 0x5b, flags: 0x0}, - 907: {region: 0x79, script: 0x5b, flags: 0x0}, - 908: {region: 0x166, script: 0x5b, flags: 0x0}, - 910: {region: 0x166, script: 0x5b, flags: 0x0}, - 911: {region: 0x166, script: 0x5b, flags: 0x0}, - 912: {region: 0x70, script: 0x5b, flags: 0x0}, - 913: {region: 0x166, script: 0x5b, flags: 0x0}, - 914: {region: 0x166, script: 0x5b, flags: 0x0}, - 915: {region: 0x166, script: 0x5b, flags: 0x0}, - 916: {region: 0x166, script: 0x5b, flags: 0x0}, - 917: {region: 0x9a, script: 0x83, flags: 0x0}, - 918: {region: 0x166, script: 0x5b, flags: 0x0}, - 919: {region: 0x166, script: 0x5, flags: 0x0}, - 920: {region: 0x7e, script: 0x20, flags: 0x0}, - 921: {region: 0x136, script: 0x84, flags: 0x0}, - 922: {region: 0x166, script: 0x5, flags: 0x0}, - 923: {region: 0xc6, script: 0x82, flags: 0x0}, - 924: {region: 0x166, script: 0x5b, flags: 0x0}, - 925: {region: 0x2c, script: 0x3, flags: 0x1}, - 926: {region: 0xe8, script: 0x5b, flags: 0x0}, - 927: {region: 0x2f, script: 0x2, flags: 0x1}, - 928: {region: 0xe8, script: 0x5b, flags: 0x0}, - 929: {region: 0x30, script: 0x5b, flags: 0x0}, - 930: {region: 0xf1, script: 0x5b, flags: 0x0}, - 931: {region: 0x166, script: 0x5b, flags: 0x0}, - 932: {region: 0x79, script: 0x5b, flags: 0x0}, - 933: {region: 0xd7, script: 0x5b, flags: 0x0}, - 934: {region: 0x136, script: 0x5b, flags: 0x0}, - 935: {region: 0x49, script: 0x5b, flags: 0x0}, - 936: {region: 0x166, script: 0x5b, flags: 0x0}, - 937: {region: 0x9d, script: 0xfa, flags: 0x0}, - 938: {region: 0x166, script: 0x5b, flags: 0x0}, - 939: {region: 0x61, script: 0x5b, flags: 0x0}, - 940: {region: 0x166, script: 0x5, flags: 0x0}, - 941: {region: 0xb1, script: 0x90, flags: 0x0}, - 943: {region: 0x166, script: 0x5b, flags: 0x0}, - 944: {region: 0x166, script: 0x5b, flags: 0x0}, - 945: {region: 0x9a, script: 0x12, flags: 0x0}, - 946: {region: 0xa5, script: 0x5b, flags: 0x0}, - 947: {region: 0xea, script: 0x5b, flags: 0x0}, - 948: {region: 0x166, script: 0x5b, flags: 0x0}, - 949: {region: 0x9f, script: 0x5b, flags: 0x0}, - 950: {region: 0x166, script: 0x5b, flags: 0x0}, - 951: {region: 0x166, script: 0x5b, flags: 0x0}, - 952: {region: 0x88, script: 0x34, flags: 0x0}, - 953: {region: 0x76, script: 0x5b, flags: 0x0}, - 954: {region: 0x166, script: 0x5b, flags: 0x0}, - 955: {region: 0xe9, script: 0x4e, flags: 0x0}, - 956: {region: 0x9d, script: 0x5, flags: 0x0}, - 957: {region: 0x1, script: 0x5b, flags: 0x0}, - 958: {region: 0x24, script: 0x5, flags: 0x0}, - 959: {region: 0x166, script: 0x5b, flags: 0x0}, - 960: {region: 0x41, script: 0x5b, flags: 0x0}, - 961: {region: 0x166, script: 0x5b, flags: 0x0}, - 962: {region: 0x7b, script: 0x5b, flags: 0x0}, - 963: {region: 0x166, script: 0x5b, flags: 0x0}, - 964: {region: 0xe5, script: 0x5b, flags: 0x0}, - 965: {region: 0x8a, script: 0x5b, flags: 0x0}, - 966: {region: 0x6a, script: 0x5b, flags: 0x0}, - 967: {region: 0x166, script: 0x5b, flags: 0x0}, - 968: {region: 0x9a, script: 0x22, flags: 0x0}, - 969: {region: 0x166, script: 0x5b, flags: 0x0}, - 970: {region: 0x103, script: 0x5b, flags: 0x0}, - 971: {region: 0x96, script: 0x5b, flags: 0x0}, - 972: {region: 0x166, script: 0x5b, flags: 0x0}, - 973: {region: 0x166, script: 0x5b, flags: 0x0}, - 974: {region: 0x9f, script: 0x5b, flags: 0x0}, - 975: {region: 0x166, script: 0x5, flags: 0x0}, - 976: {region: 0x9a, script: 0x5b, flags: 0x0}, - 977: {region: 0x31, script: 0x2, flags: 0x1}, - 978: {region: 0xdc, script: 0x22, flags: 0x0}, - 979: {region: 0x35, script: 0xe, flags: 0x0}, - 980: {region: 0x4e, script: 0x5b, flags: 0x0}, - 981: {region: 0x73, script: 0x5b, flags: 0x0}, - 982: {region: 0x4e, script: 0x5b, flags: 0x0}, - 983: {region: 0x9d, script: 0x5, flags: 0x0}, - 984: {region: 0x10d, script: 0x5b, flags: 0x0}, - 985: {region: 0x3a, script: 0x5b, flags: 0x0}, - 986: {region: 0x166, script: 0x5b, flags: 0x0}, - 987: {region: 0xd2, script: 0x5b, flags: 0x0}, - 988: {region: 0x105, script: 0x5b, flags: 0x0}, - 989: {region: 0x96, script: 0x5b, flags: 0x0}, - 990: {region: 0x130, script: 0x5b, flags: 0x0}, - 991: {region: 0x166, script: 0x5b, flags: 0x0}, - 992: {region: 0x166, script: 0x5b, flags: 0x0}, - 993: {region: 0x74, script: 0x5b, flags: 0x0}, - 994: {region: 0x107, script: 0x20, flags: 0x0}, - 995: {region: 0x131, script: 0x20, flags: 0x0}, - 996: {region: 0x10a, script: 0x5b, flags: 0x0}, - 997: {region: 0x108, script: 0x5b, flags: 0x0}, - 998: {region: 0x130, script: 0x5b, flags: 0x0}, - 999: {region: 0x166, script: 0x5b, flags: 0x0}, - 1000: {region: 0xa3, script: 0x4c, flags: 0x0}, - 1001: {region: 0x9a, script: 0x22, flags: 0x0}, - 1002: {region: 0x81, script: 0x5b, flags: 0x0}, - 1003: {region: 0x107, script: 0x20, flags: 0x0}, - 1004: {region: 0xa5, script: 0x5b, flags: 0x0}, - 1005: {region: 0x96, script: 0x5b, flags: 0x0}, - 1006: {region: 0x9a, script: 0x5b, flags: 0x0}, - 1007: {region: 0x115, script: 0x5b, flags: 0x0}, - 1008: {region: 0x9a, script: 0xcf, flags: 0x0}, - 1009: {region: 0x166, script: 0x5b, flags: 0x0}, - 1010: {region: 0x166, script: 0x5b, flags: 0x0}, - 1011: {region: 0x130, script: 0x5b, flags: 0x0}, - 1012: {region: 0x9f, script: 0x5b, flags: 0x0}, - 1013: {region: 0x9a, script: 0x22, flags: 0x0}, - 1014: {region: 0x166, script: 0x5, flags: 0x0}, - 1015: {region: 0x9f, script: 0x5b, flags: 0x0}, - 1016: {region: 0x7c, script: 0x5b, flags: 0x0}, - 1017: {region: 0x49, script: 0x5b, flags: 0x0}, - 1018: {region: 0x33, script: 0x4, flags: 0x1}, - 1019: {region: 0x9f, script: 0x5b, flags: 0x0}, - 1020: {region: 0x9d, script: 0x5, flags: 0x0}, - 1021: {region: 0xdb, script: 0x5b, flags: 0x0}, - 1022: {region: 0x4f, script: 0x5b, flags: 0x0}, - 1023: {region: 0xd2, script: 0x5b, flags: 0x0}, - 1024: {region: 0xd0, script: 0x5b, flags: 0x0}, - 1025: {region: 0xc4, script: 0x5b, flags: 0x0}, - 1026: {region: 0x4c, script: 0x5b, flags: 0x0}, - 1027: {region: 0x97, script: 0x80, flags: 0x0}, - 1028: {region: 0xb7, script: 0x5b, flags: 0x0}, - 1029: {region: 0x166, script: 0x2c, flags: 0x0}, - 1030: {region: 0x166, script: 0x5b, flags: 0x0}, - 1032: {region: 0xbb, script: 0xeb, flags: 0x0}, - 1033: {region: 0x166, script: 0x5b, flags: 0x0}, - 1034: {region: 0xc5, script: 0x76, flags: 0x0}, - 1035: {region: 0x166, script: 0x5, flags: 0x0}, - 1036: {region: 0xb4, script: 0xd6, flags: 0x0}, - 1037: {region: 0x70, script: 0x5b, flags: 0x0}, - 1038: {region: 0x166, script: 0x5b, flags: 0x0}, - 1039: {region: 0x166, script: 0x5b, flags: 0x0}, - 1040: {region: 0x166, script: 0x5b, flags: 0x0}, - 1041: {region: 0x166, script: 0x5b, flags: 0x0}, - 1042: {region: 0x112, script: 0x5b, flags: 0x0}, - 1043: {region: 0x166, script: 0x5b, flags: 0x0}, - 1044: {region: 0xe9, script: 0x5, flags: 0x0}, - 1045: {region: 0x166, script: 0x5b, flags: 0x0}, - 1046: {region: 0x110, script: 0x5b, flags: 0x0}, - 1047: {region: 0x166, script: 0x5b, flags: 0x0}, - 1048: {region: 0xea, script: 0x5b, flags: 0x0}, - 1049: {region: 0x166, script: 0x5b, flags: 0x0}, - 1050: {region: 0x96, script: 0x5b, flags: 0x0}, - 1051: {region: 0x143, script: 0x5b, flags: 0x0}, - 1052: {region: 0x10d, script: 0x5b, flags: 0x0}, - 1054: {region: 0x10d, script: 0x5b, flags: 0x0}, - 1055: {region: 0x73, script: 0x5b, flags: 0x0}, - 1056: {region: 0x98, script: 0xcc, flags: 0x0}, - 1057: {region: 0x166, script: 0x5b, flags: 0x0}, - 1058: {region: 0x73, script: 0x5b, flags: 0x0}, - 1059: {region: 0x165, script: 0x5b, flags: 0x0}, - 1060: {region: 0x166, script: 0x5b, flags: 0x0}, - 1061: {region: 0xc4, script: 0x5b, flags: 0x0}, - 1062: {region: 0x166, script: 0x5b, flags: 0x0}, - 1063: {region: 0x166, script: 0x5b, flags: 0x0}, - 1064: {region: 0x166, script: 0x5b, flags: 0x0}, - 1065: {region: 0x116, script: 0x5b, flags: 0x0}, - 1066: {region: 0x166, script: 0x5b, flags: 0x0}, - 1067: {region: 0x166, script: 0x5b, flags: 0x0}, - 1068: {region: 0x124, script: 0xee, flags: 0x0}, - 1069: {region: 0x166, script: 0x5b, flags: 0x0}, - 1070: {region: 0x166, script: 0x5b, flags: 0x0}, - 1071: {region: 0x166, script: 0x5b, flags: 0x0}, - 1072: {region: 0x166, script: 0x5b, flags: 0x0}, - 1073: {region: 0x27, script: 0x5b, flags: 0x0}, - 1074: {region: 0x37, script: 0x5, flags: 0x1}, - 1075: {region: 0x9a, script: 0xd9, flags: 0x0}, - 1076: {region: 0x117, script: 0x5b, flags: 0x0}, - 1077: {region: 0x115, script: 0x5b, flags: 0x0}, - 1078: {region: 0x9a, script: 0x22, flags: 0x0}, - 1079: {region: 0x162, script: 0x5b, flags: 0x0}, - 1080: {region: 0x166, script: 0x5b, flags: 0x0}, - 1081: {region: 0x166, script: 0x5b, flags: 0x0}, - 1082: {region: 0x6e, script: 0x5b, flags: 0x0}, - 1083: {region: 0x162, script: 0x5b, flags: 0x0}, - 1084: {region: 0x166, script: 0x5b, flags: 0x0}, - 1085: {region: 0x61, script: 0x5b, flags: 0x0}, - 1086: {region: 0x96, script: 0x5b, flags: 0x0}, - 1087: {region: 0x166, script: 0x5b, flags: 0x0}, - 1088: {region: 0x166, script: 0x5b, flags: 0x0}, - 1089: {region: 0x130, script: 0x5b, flags: 0x0}, - 1090: {region: 0x166, script: 0x5b, flags: 0x0}, - 1091: {region: 0x85, script: 0x5b, flags: 0x0}, - 1092: {region: 0x10d, script: 0x5b, flags: 0x0}, - 1093: {region: 0x130, script: 0x5b, flags: 0x0}, - 1094: {region: 0x160, script: 0x5, flags: 0x0}, - 1095: {region: 0x4b, script: 0x5b, flags: 0x0}, - 1096: {region: 0x61, script: 0x5b, flags: 0x0}, - 1097: {region: 0x166, script: 0x5b, flags: 0x0}, - 1098: {region: 0x9a, script: 0x22, flags: 0x0}, - 1099: {region: 0x96, script: 0x5b, flags: 0x0}, - 1100: {region: 0x166, script: 0x5b, flags: 0x0}, - 1101: {region: 0x35, script: 0xe, flags: 0x0}, - 1102: {region: 0x9c, script: 0xde, flags: 0x0}, - 1103: {region: 0xea, script: 0x5b, flags: 0x0}, - 1104: {region: 0x9a, script: 0xe6, flags: 0x0}, - 1105: {region: 0xdc, script: 0x22, flags: 0x0}, - 1106: {region: 0x166, script: 0x5b, flags: 0x0}, - 1107: {region: 0x166, script: 0x5b, flags: 0x0}, - 1108: {region: 0x166, script: 0x5b, flags: 0x0}, - 1109: {region: 0x166, script: 0x5b, flags: 0x0}, - 1110: {region: 0x166, script: 0x5b, flags: 0x0}, - 1111: {region: 0x166, script: 0x5b, flags: 0x0}, - 1112: {region: 0x166, script: 0x5b, flags: 0x0}, - 1113: {region: 0x166, script: 0x5b, flags: 0x0}, - 1114: {region: 0xe8, script: 0x5b, flags: 0x0}, - 1115: {region: 0x166, script: 0x5b, flags: 0x0}, - 1116: {region: 0x166, script: 0x5b, flags: 0x0}, - 1117: {region: 0x9a, script: 0x53, flags: 0x0}, - 1118: {region: 0x53, script: 0xe4, flags: 0x0}, - 1119: {region: 0xdc, script: 0x22, flags: 0x0}, - 1120: {region: 0xdc, script: 0x22, flags: 0x0}, - 1121: {region: 0x9a, script: 0xe9, flags: 0x0}, - 1122: {region: 0x166, script: 0x5b, flags: 0x0}, - 1123: {region: 0x113, script: 0x5b, flags: 0x0}, - 1124: {region: 0x132, script: 0x5b, flags: 0x0}, - 1125: {region: 0x127, script: 0x5b, flags: 0x0}, - 1126: {region: 0x166, script: 0x5b, flags: 0x0}, - 1127: {region: 0x3c, script: 0x3, flags: 0x1}, - 1128: {region: 0x166, script: 0x5b, flags: 0x0}, - 1129: {region: 0x166, script: 0x5b, flags: 0x0}, - 1130: {region: 0x166, script: 0x5b, flags: 0x0}, - 1131: {region: 0x124, script: 0xee, flags: 0x0}, - 1132: {region: 0xdc, script: 0x22, flags: 0x0}, - 1133: {region: 0xdc, script: 0x22, flags: 0x0}, - 1134: {region: 0xdc, script: 0x22, flags: 0x0}, - 1135: {region: 0x70, script: 0x2c, flags: 0x0}, - 1136: {region: 0x166, script: 0x5b, flags: 0x0}, - 1137: {region: 0x6e, script: 0x2c, flags: 0x0}, - 1138: {region: 0x166, script: 0x5b, flags: 0x0}, - 1139: {region: 0x166, script: 0x5b, flags: 0x0}, - 1140: {region: 0x166, script: 0x5b, flags: 0x0}, - 1141: {region: 0xd7, script: 0x5b, flags: 0x0}, - 1142: {region: 0x128, script: 0x5b, flags: 0x0}, - 1143: {region: 0x126, script: 0x5b, flags: 0x0}, - 1144: {region: 0x32, script: 0x5b, flags: 0x0}, - 1145: {region: 0xdc, script: 0x22, flags: 0x0}, - 1146: {region: 0xe8, script: 0x5b, flags: 0x0}, - 1147: {region: 0x166, script: 0x5b, flags: 0x0}, - 1148: {region: 0x166, script: 0x5b, flags: 0x0}, - 1149: {region: 0x32, script: 0x5b, flags: 0x0}, - 1150: {region: 0xd5, script: 0x5b, flags: 0x0}, - 1151: {region: 0x166, script: 0x5b, flags: 0x0}, - 1152: {region: 0x162, script: 0x5b, flags: 0x0}, - 1153: {region: 0x166, script: 0x5b, flags: 0x0}, - 1154: {region: 0x12a, script: 0x5b, flags: 0x0}, - 1155: {region: 0x166, script: 0x5b, flags: 0x0}, - 1156: {region: 0xcf, script: 0x5b, flags: 0x0}, - 1157: {region: 0x166, script: 0x5b, flags: 0x0}, - 1158: {region: 0xe7, script: 0x5b, flags: 0x0}, - 1159: {region: 0x166, script: 0x5b, flags: 0x0}, - 1160: {region: 0x166, script: 0x5b, flags: 0x0}, - 1161: {region: 0x166, script: 0x5b, flags: 0x0}, - 1162: {region: 0x12c, script: 0x5b, flags: 0x0}, - 1163: {region: 0x12c, script: 0x5b, flags: 0x0}, - 1164: {region: 0x12f, script: 0x5b, flags: 0x0}, - 1165: {region: 0x166, script: 0x5, flags: 0x0}, - 1166: {region: 0x162, script: 0x5b, flags: 0x0}, - 1167: {region: 0x88, script: 0x34, flags: 0x0}, - 1168: {region: 0xdc, script: 0x22, flags: 0x0}, - 1169: {region: 0xe8, script: 0x5b, flags: 0x0}, - 1170: {region: 0x43, script: 0xef, flags: 0x0}, - 1171: {region: 0x166, script: 0x5b, flags: 0x0}, - 1172: {region: 0x107, script: 0x20, flags: 0x0}, - 1173: {region: 0x166, script: 0x5b, flags: 0x0}, - 1174: {region: 0x166, script: 0x5b, flags: 0x0}, - 1175: {region: 0x132, script: 0x5b, flags: 0x0}, - 1176: {region: 0x166, script: 0x5b, flags: 0x0}, - 1177: {region: 0x124, script: 0xee, flags: 0x0}, - 1178: {region: 0x32, script: 0x5b, flags: 0x0}, - 1179: {region: 0x166, script: 0x5b, flags: 0x0}, - 1180: {region: 0x166, script: 0x5b, flags: 0x0}, - 1181: {region: 0xcf, script: 0x5b, flags: 0x0}, - 1182: {region: 0x166, script: 0x5b, flags: 0x0}, - 1183: {region: 0x166, script: 0x5b, flags: 0x0}, - 1184: {region: 0x12e, script: 0x5b, flags: 0x0}, - 1185: {region: 0x166, script: 0x5b, flags: 0x0}, - 1187: {region: 0x166, script: 0x5b, flags: 0x0}, - 1188: {region: 0xd5, script: 0x5b, flags: 0x0}, - 1189: {region: 0x53, script: 0xe7, flags: 0x0}, - 1190: {region: 0xe6, script: 0x5b, flags: 0x0}, - 1191: {region: 0x166, script: 0x5b, flags: 0x0}, - 1192: {region: 0x107, script: 0x20, flags: 0x0}, - 1193: {region: 0xbb, script: 0x5b, flags: 0x0}, - 1194: {region: 0x166, script: 0x5b, flags: 0x0}, - 1195: {region: 0x107, script: 0x20, flags: 0x0}, - 1196: {region: 0x3f, script: 0x4, flags: 0x1}, - 1197: {region: 0x11d, script: 0xf3, flags: 0x0}, - 1198: {region: 0x131, script: 0x20, flags: 0x0}, - 1199: {region: 0x76, script: 0x5b, flags: 0x0}, - 1200: {region: 0x2a, script: 0x5b, flags: 0x0}, - 1202: {region: 0x43, script: 0x3, flags: 0x1}, - 1203: {region: 0x9a, script: 0xe, flags: 0x0}, - 1204: {region: 0xe9, script: 0x5, flags: 0x0}, - 1205: {region: 0x166, script: 0x5b, flags: 0x0}, - 1206: {region: 0x166, script: 0x5b, flags: 0x0}, - 1207: {region: 0x166, script: 0x5b, flags: 0x0}, - 1208: {region: 0x166, script: 0x5b, flags: 0x0}, - 1209: {region: 0x166, script: 0x5b, flags: 0x0}, - 1210: {region: 0x166, script: 0x5b, flags: 0x0}, - 1211: {region: 0x166, script: 0x5b, flags: 0x0}, - 1212: {region: 0x46, script: 0x4, flags: 0x1}, - 1213: {region: 0x166, script: 0x5b, flags: 0x0}, - 1214: {region: 0xb5, script: 0xf4, flags: 0x0}, - 1215: {region: 0x166, script: 0x5b, flags: 0x0}, - 1216: {region: 0x162, script: 0x5b, flags: 0x0}, - 1217: {region: 0x9f, script: 0x5b, flags: 0x0}, - 1218: {region: 0x107, script: 0x5b, flags: 0x0}, - 1219: {region: 0x13f, script: 0x5b, flags: 0x0}, - 1220: {region: 0x11c, script: 0x5b, flags: 0x0}, - 1221: {region: 0x166, script: 0x5b, flags: 0x0}, - 1222: {region: 0x36, script: 0x5b, flags: 0x0}, - 1223: {region: 0x61, script: 0x5b, flags: 0x0}, - 1224: {region: 0xd2, script: 0x5b, flags: 0x0}, - 1225: {region: 0x1, script: 0x5b, flags: 0x0}, - 1226: {region: 0x107, script: 0x5b, flags: 0x0}, - 1227: {region: 0x6b, script: 0x5b, flags: 0x0}, - 1228: {region: 0x130, script: 0x5b, flags: 0x0}, - 1229: {region: 0x166, script: 0x5b, flags: 0x0}, - 1230: {region: 0x36, script: 0x5b, flags: 0x0}, - 1231: {region: 0x4e, script: 0x5b, flags: 0x0}, - 1232: {region: 0x166, script: 0x5b, flags: 0x0}, - 1233: {region: 0x70, script: 0x2c, flags: 0x0}, - 1234: {region: 0x166, script: 0x5b, flags: 0x0}, - 1235: {region: 0xe8, script: 0x5b, flags: 0x0}, - 1236: {region: 0x2f, script: 0x5b, flags: 0x0}, - 1237: {region: 0x9a, script: 0xe9, flags: 0x0}, - 1238: {region: 0x9a, script: 0x22, flags: 0x0}, - 1239: {region: 0x166, script: 0x5b, flags: 0x0}, - 1240: {region: 0x166, script: 0x5b, flags: 0x0}, - 1241: {region: 0x166, script: 0x5b, flags: 0x0}, - 1242: {region: 0x166, script: 0x5b, flags: 0x0}, - 1243: {region: 0x166, script: 0x5b, flags: 0x0}, - 1244: {region: 0x166, script: 0x5b, flags: 0x0}, - 1245: {region: 0x166, script: 0x5b, flags: 0x0}, - 1246: {region: 0x166, script: 0x5b, flags: 0x0}, - 1247: {region: 0x166, script: 0x5b, flags: 0x0}, - 1248: {region: 0x141, script: 0x5b, flags: 0x0}, - 1249: {region: 0x166, script: 0x5b, flags: 0x0}, - 1250: {region: 0x166, script: 0x5b, flags: 0x0}, - 1251: {region: 0xa9, script: 0x5, flags: 0x0}, - 1252: {region: 0x166, script: 0x5b, flags: 0x0}, - 1253: {region: 0x115, script: 0x5b, flags: 0x0}, - 1254: {region: 0x166, script: 0x5b, flags: 0x0}, - 1255: {region: 0x166, script: 0x5b, flags: 0x0}, - 1256: {region: 0x166, script: 0x5b, flags: 0x0}, - 1257: {region: 0x166, script: 0x5b, flags: 0x0}, - 1258: {region: 0x9a, script: 0x22, flags: 0x0}, - 1259: {region: 0x53, script: 0x3b, flags: 0x0}, - 1260: {region: 0x166, script: 0x5b, flags: 0x0}, - 1261: {region: 0x166, script: 0x5b, flags: 0x0}, - 1262: {region: 0x41, script: 0x5b, flags: 0x0}, - 1263: {region: 0x166, script: 0x5b, flags: 0x0}, - 1264: {region: 0x12c, script: 0x18, flags: 0x0}, - 1265: {region: 0x166, script: 0x5b, flags: 0x0}, - 1266: {region: 0x162, script: 0x5b, flags: 0x0}, - 1267: {region: 0x166, script: 0x5b, flags: 0x0}, - 1268: {region: 0x12c, script: 0x63, flags: 0x0}, - 1269: {region: 0x12c, script: 0x64, flags: 0x0}, - 1270: {region: 0x7e, script: 0x2e, flags: 0x0}, - 1271: {region: 0x53, script: 0x68, flags: 0x0}, - 1272: {region: 0x10c, script: 0x6d, flags: 0x0}, - 1273: {region: 0x109, script: 0x79, flags: 0x0}, - 1274: {region: 0x9a, script: 0x22, flags: 0x0}, - 1275: {region: 0x132, script: 0x5b, flags: 0x0}, - 1276: {region: 0x166, script: 0x5b, flags: 0x0}, - 1277: {region: 0x9d, script: 0x93, flags: 0x0}, - 1278: {region: 0x166, script: 0x5b, flags: 0x0}, - 1279: {region: 0x15f, script: 0xce, flags: 0x0}, - 1280: {region: 0x166, script: 0x5b, flags: 0x0}, - 1281: {region: 0x166, script: 0x5b, flags: 0x0}, - 1282: {region: 0xdc, script: 0x22, flags: 0x0}, - 1283: {region: 0x166, script: 0x5b, flags: 0x0}, - 1284: {region: 0x166, script: 0x5b, flags: 0x0}, - 1285: {region: 0xd2, script: 0x5b, flags: 0x0}, - 1286: {region: 0x76, script: 0x5b, flags: 0x0}, - 1287: {region: 0x166, script: 0x5b, flags: 0x0}, - 1288: {region: 0x166, script: 0x5b, flags: 0x0}, - 1289: {region: 0x52, script: 0x5b, flags: 0x0}, - 1290: {region: 0x166, script: 0x5b, flags: 0x0}, - 1291: {region: 0x166, script: 0x5b, flags: 0x0}, - 1292: {region: 0x166, script: 0x5b, flags: 0x0}, - 1293: {region: 0x52, script: 0x5b, flags: 0x0}, - 1294: {region: 0x166, script: 0x5b, flags: 0x0}, - 1295: {region: 0x166, script: 0x5b, flags: 0x0}, - 1296: {region: 0x166, script: 0x5b, flags: 0x0}, - 1297: {region: 0x166, script: 0x5b, flags: 0x0}, - 1298: {region: 0x1, script: 0x3e, flags: 0x0}, - 1299: {region: 0x166, script: 0x5b, flags: 0x0}, - 1300: {region: 0x166, script: 0x5b, flags: 0x0}, - 1301: {region: 0x166, script: 0x5b, flags: 0x0}, - 1302: {region: 0x166, script: 0x5b, flags: 0x0}, - 1303: {region: 0x166, script: 0x5b, flags: 0x0}, - 1304: {region: 0xd7, script: 0x5b, flags: 0x0}, - 1305: {region: 0x166, script: 0x5b, flags: 0x0}, - 1306: {region: 0x166, script: 0x5b, flags: 0x0}, - 1307: {region: 0x166, script: 0x5b, flags: 0x0}, - 1308: {region: 0x41, script: 0x5b, flags: 0x0}, - 1309: {region: 0x166, script: 0x5b, flags: 0x0}, - 1310: {region: 0xd0, script: 0x5b, flags: 0x0}, - 1311: {region: 0x4a, script: 0x3, flags: 0x1}, - 1312: {region: 0x166, script: 0x5b, flags: 0x0}, - 1313: {region: 0x166, script: 0x5b, flags: 0x0}, - 1314: {region: 0x166, script: 0x5b, flags: 0x0}, - 1315: {region: 0x53, script: 0x5b, flags: 0x0}, - 1316: {region: 0x10c, script: 0x5b, flags: 0x0}, - 1318: {region: 0xa9, script: 0x5, flags: 0x0}, - 1319: {region: 0xda, script: 0x5b, flags: 0x0}, - 1320: {region: 0xbb, script: 0xeb, flags: 0x0}, - 1321: {region: 0x4d, script: 0x14, flags: 0x1}, - 1322: {region: 0x53, script: 0x7f, flags: 0x0}, - 1323: {region: 0x166, script: 0x5b, flags: 0x0}, - 1324: {region: 0x123, script: 0x5b, flags: 0x0}, - 1325: {region: 0xd1, script: 0x5b, flags: 0x0}, - 1326: {region: 0x166, script: 0x5b, flags: 0x0}, - 1327: {region: 0x162, script: 0x5b, flags: 0x0}, - 1329: {region: 0x12c, script: 0x5b, flags: 0x0}, -} - -// likelyLangList holds lists info associated with likelyLang. -// Size: 582 bytes, 97 elements -var likelyLangList = [97]likelyScriptRegion{ - 0: {region: 0x9d, script: 0x7, flags: 0x0}, - 1: {region: 0xa2, script: 0x7a, flags: 0x2}, - 2: {region: 0x11d, script: 0x87, flags: 0x2}, - 3: {region: 0x32, script: 0x5b, flags: 0x0}, - 4: {region: 0x9c, script: 0x5, flags: 0x4}, - 5: {region: 0x9d, script: 0x5, flags: 0x4}, - 6: {region: 0x107, script: 0x20, flags: 0x4}, - 7: {region: 0x9d, script: 0x5, flags: 0x2}, - 8: {region: 0x107, script: 0x20, flags: 0x0}, - 9: {region: 0x38, script: 0x2f, flags: 0x2}, - 10: {region: 0x136, script: 0x5b, flags: 0x0}, - 11: {region: 0x7c, script: 0xd1, flags: 0x2}, - 12: {region: 0x115, script: 0x5b, flags: 0x0}, - 13: {region: 0x85, script: 0x1, flags: 0x2}, - 14: {region: 0x5e, script: 0x1f, flags: 0x0}, - 15: {region: 0x88, script: 0x60, flags: 0x2}, - 16: {region: 0xd7, script: 0x5b, flags: 0x0}, - 17: {region: 0x52, script: 0x5, flags: 0x4}, - 18: {region: 0x10c, script: 0x5, flags: 0x4}, - 19: {region: 0xaf, script: 0x20, flags: 0x0}, - 20: {region: 0x24, script: 0x5, flags: 0x4}, - 21: {region: 0x53, script: 0x5, flags: 0x4}, - 22: {region: 0x9d, script: 0x5, flags: 0x4}, - 23: {region: 0xc6, script: 0x5, flags: 0x4}, - 24: {region: 0x53, script: 0x5, flags: 0x2}, - 25: {region: 0x12c, script: 0x5b, flags: 0x0}, - 26: {region: 0xb1, script: 0x5, flags: 0x4}, - 27: {region: 0x9c, script: 0x5, flags: 0x2}, - 28: {region: 0xa6, script: 0x20, flags: 0x0}, - 29: {region: 0x53, script: 0x5, flags: 0x4}, - 30: {region: 0x12c, script: 0x5b, flags: 0x4}, - 31: {region: 0x53, script: 0x5, flags: 0x2}, - 32: {region: 0x12c, script: 0x5b, flags: 0x2}, - 33: {region: 0xdc, script: 0x22, flags: 0x0}, - 34: {region: 0x9a, script: 0x5e, flags: 0x2}, - 35: {region: 0x84, script: 0x5b, flags: 0x0}, - 36: {region: 0x85, script: 0x7e, flags: 0x4}, - 37: {region: 0x85, script: 0x7e, flags: 0x2}, - 38: {region: 0xc6, script: 0x20, flags: 0x0}, - 39: {region: 0x53, script: 0x71, flags: 0x4}, - 40: {region: 0x53, script: 0x71, flags: 0x2}, - 41: {region: 0xd1, script: 0x5b, flags: 0x0}, - 42: {region: 0x4a, script: 0x5, flags: 0x4}, - 43: {region: 0x96, script: 0x5, flags: 0x4}, - 44: {region: 0x9a, script: 0x36, flags: 0x0}, - 45: {region: 0xe9, script: 0x5, flags: 0x4}, - 46: {region: 0xe9, script: 0x5, flags: 0x2}, - 47: {region: 0x9d, script: 0x8d, flags: 0x0}, - 48: {region: 0x53, script: 0x8e, flags: 0x2}, - 49: {region: 0xbb, script: 0xeb, flags: 0x0}, - 50: {region: 0xda, script: 0x5b, flags: 0x4}, - 51: {region: 0xe9, script: 0x5, flags: 0x0}, - 52: {region: 0x9a, script: 0x22, flags: 0x2}, - 53: {region: 0x9a, script: 0x50, flags: 0x2}, - 54: {region: 0x9a, script: 0xd5, flags: 0x2}, - 55: {region: 0x106, script: 0x20, flags: 0x0}, - 56: {region: 0xbe, script: 0x5b, flags: 0x4}, - 57: {region: 0x105, script: 0x5b, flags: 0x4}, - 58: {region: 0x107, script: 0x5b, flags: 0x4}, - 59: {region: 0x12c, script: 0x5b, flags: 0x4}, - 60: {region: 0x125, script: 0x20, flags: 0x0}, - 61: {region: 0xe9, script: 0x5, flags: 0x4}, - 62: {region: 0xe9, script: 0x5, flags: 0x2}, - 63: {region: 0x53, script: 0x5, flags: 0x0}, - 64: {region: 0xaf, script: 0x20, flags: 0x4}, - 65: {region: 0xc6, script: 0x20, flags: 0x4}, - 66: {region: 0xaf, script: 0x20, flags: 0x2}, - 67: {region: 0x9a, script: 0xe, flags: 0x0}, - 68: {region: 0xdc, script: 0x22, flags: 0x4}, - 69: {region: 0xdc, script: 0x22, flags: 0x2}, - 70: {region: 0x138, script: 0x5b, flags: 0x0}, - 71: {region: 0x24, script: 0x5, flags: 0x4}, - 72: {region: 0x53, script: 0x20, flags: 0x4}, - 73: {region: 0x24, script: 0x5, flags: 0x2}, - 74: {region: 0x8e, script: 0x3c, flags: 0x0}, - 75: {region: 0x53, script: 0x3b, flags: 0x4}, - 76: {region: 0x53, script: 0x3b, flags: 0x2}, - 77: {region: 0x53, script: 0x3b, flags: 0x0}, - 78: {region: 0x2f, script: 0x3c, flags: 0x4}, - 79: {region: 0x3e, script: 0x3c, flags: 0x4}, - 80: {region: 0x7c, script: 0x3c, flags: 0x4}, - 81: {region: 0x7f, script: 0x3c, flags: 0x4}, - 82: {region: 0x8e, script: 0x3c, flags: 0x4}, - 83: {region: 0x96, script: 0x3c, flags: 0x4}, - 84: {region: 0xc7, script: 0x3c, flags: 0x4}, - 85: {region: 0xd1, script: 0x3c, flags: 0x4}, - 86: {region: 0xe3, script: 0x3c, flags: 0x4}, - 87: {region: 0xe6, script: 0x3c, flags: 0x4}, - 88: {region: 0xe8, script: 0x3c, flags: 0x4}, - 89: {region: 0x117, script: 0x3c, flags: 0x4}, - 90: {region: 0x124, script: 0x3c, flags: 0x4}, - 91: {region: 0x12f, script: 0x3c, flags: 0x4}, - 92: {region: 0x136, script: 0x3c, flags: 0x4}, - 93: {region: 0x13f, script: 0x3c, flags: 0x4}, - 94: {region: 0x12f, script: 0x11, flags: 0x2}, - 95: {region: 0x12f, script: 0x37, flags: 0x2}, - 96: {region: 0x12f, script: 0x3c, flags: 0x2}, -} - -type likelyLangScript struct { - lang uint16 - script uint16 - flags uint8 -} - -// likelyRegion is a lookup table, indexed by regionID, for the most likely -// languages and scripts given incomplete information. If more entries exist -// for a given regionID, lang and script are the index and size respectively -// of the list in likelyRegionList. -// TODO: exclude containers and user-definable regions from the list. -// Size: 2154 bytes, 359 elements -var likelyRegion = [359]likelyLangScript{ - 34: {lang: 0xd7, script: 0x5b, flags: 0x0}, - 35: {lang: 0x3a, script: 0x5, flags: 0x0}, - 36: {lang: 0x0, script: 0x2, flags: 0x1}, - 39: {lang: 0x2, script: 0x2, flags: 0x1}, - 40: {lang: 0x4, script: 0x2, flags: 0x1}, - 42: {lang: 0x3c0, script: 0x5b, flags: 0x0}, - 43: {lang: 0x0, script: 0x5b, flags: 0x0}, - 44: {lang: 0x13e, script: 0x5b, flags: 0x0}, - 45: {lang: 0x41b, script: 0x5b, flags: 0x0}, - 46: {lang: 0x10d, script: 0x5b, flags: 0x0}, - 48: {lang: 0x367, script: 0x5b, flags: 0x0}, - 49: {lang: 0x444, script: 0x5b, flags: 0x0}, - 50: {lang: 0x58, script: 0x5b, flags: 0x0}, - 51: {lang: 0x6, script: 0x2, flags: 0x1}, - 53: {lang: 0xa5, script: 0xe, flags: 0x0}, - 54: {lang: 0x367, script: 0x5b, flags: 0x0}, - 55: {lang: 0x15e, script: 0x5b, flags: 0x0}, - 56: {lang: 0x7e, script: 0x20, flags: 0x0}, - 57: {lang: 0x3a, script: 0x5, flags: 0x0}, - 58: {lang: 0x3d9, script: 0x5b, flags: 0x0}, - 59: {lang: 0x15e, script: 0x5b, flags: 0x0}, - 60: {lang: 0x15e, script: 0x5b, flags: 0x0}, - 62: {lang: 0x31f, script: 0x5b, flags: 0x0}, - 63: {lang: 0x13e, script: 0x5b, flags: 0x0}, - 64: {lang: 0x3a1, script: 0x5b, flags: 0x0}, - 65: {lang: 0x3c0, script: 0x5b, flags: 0x0}, - 67: {lang: 0x8, script: 0x2, flags: 0x1}, - 69: {lang: 0x0, script: 0x5b, flags: 0x0}, - 71: {lang: 0x71, script: 0x20, flags: 0x0}, - 73: {lang: 0x512, script: 0x3e, flags: 0x2}, - 74: {lang: 0x31f, script: 0x5, flags: 0x2}, - 75: {lang: 0x445, script: 0x5b, flags: 0x0}, - 76: {lang: 0x15e, script: 0x5b, flags: 0x0}, - 77: {lang: 0x15e, script: 0x5b, flags: 0x0}, - 78: {lang: 0x10d, script: 0x5b, flags: 0x0}, - 79: {lang: 0x15e, script: 0x5b, flags: 0x0}, - 81: {lang: 0x13e, script: 0x5b, flags: 0x0}, - 82: {lang: 0x15e, script: 0x5b, flags: 0x0}, - 83: {lang: 0xa, script: 0x4, flags: 0x1}, - 84: {lang: 0x13e, script: 0x5b, flags: 0x0}, - 85: {lang: 0x0, script: 0x5b, flags: 0x0}, - 87: {lang: 0x13e, script: 0x5b, flags: 0x0}, - 90: {lang: 0x13e, script: 0x5b, flags: 0x0}, - 91: {lang: 0x3c0, script: 0x5b, flags: 0x0}, - 92: {lang: 0x3a1, script: 0x5b, flags: 0x0}, - 94: {lang: 0xe, script: 0x2, flags: 0x1}, - 95: {lang: 0xfa, script: 0x5b, flags: 0x0}, - 97: {lang: 0x10d, script: 0x5b, flags: 0x0}, - 99: {lang: 0x1, script: 0x5b, flags: 0x0}, - 100: {lang: 0x101, script: 0x5b, flags: 0x0}, - 102: {lang: 0x13e, script: 0x5b, flags: 0x0}, - 104: {lang: 0x10, script: 0x2, flags: 0x1}, - 105: {lang: 0x13e, script: 0x5b, flags: 0x0}, - 106: {lang: 0x13e, script: 0x5b, flags: 0x0}, - 107: {lang: 0x140, script: 0x5b, flags: 0x0}, - 108: {lang: 0x3a, script: 0x5, flags: 0x0}, - 109: {lang: 0x3a, script: 0x5, flags: 0x0}, - 110: {lang: 0x46f, script: 0x2c, flags: 0x0}, - 111: {lang: 0x13e, script: 0x5b, flags: 0x0}, - 112: {lang: 0x12, script: 0x2, flags: 0x1}, - 114: {lang: 0x10d, script: 0x5b, flags: 0x0}, - 115: {lang: 0x151, script: 0x5b, flags: 0x0}, - 116: {lang: 0x1c0, script: 0x22, flags: 0x2}, - 119: {lang: 0x158, script: 0x5b, flags: 0x0}, - 121: {lang: 0x15e, script: 0x5b, flags: 0x0}, - 123: {lang: 0x15e, script: 0x5b, flags: 0x0}, - 124: {lang: 0x14, script: 0x2, flags: 0x1}, - 126: {lang: 0x16, script: 0x3, flags: 0x1}, - 127: {lang: 0x15e, script: 0x5b, flags: 0x0}, - 129: {lang: 0x21, script: 0x5b, flags: 0x0}, - 131: {lang: 0x245, script: 0x5b, flags: 0x0}, - 133: {lang: 0x15e, script: 0x5b, flags: 0x0}, - 134: {lang: 0x15e, script: 0x5b, flags: 0x0}, - 135: {lang: 0x13e, script: 0x5b, flags: 0x0}, - 136: {lang: 0x19, script: 0x2, flags: 0x1}, - 137: {lang: 0x0, script: 0x5b, flags: 0x0}, - 138: {lang: 0x13e, script: 0x5b, flags: 0x0}, - 140: {lang: 0x3c0, script: 0x5b, flags: 0x0}, - 142: {lang: 0x529, script: 0x3c, flags: 0x0}, - 143: {lang: 0x0, script: 0x5b, flags: 0x0}, - 144: {lang: 0x13e, script: 0x5b, flags: 0x0}, - 145: {lang: 0x1d1, script: 0x5b, flags: 0x0}, - 146: {lang: 0x1d4, script: 0x5b, flags: 0x0}, - 147: {lang: 0x1d5, script: 0x5b, flags: 0x0}, - 149: {lang: 0x13e, script: 0x5b, flags: 0x0}, - 150: {lang: 0x1b, script: 0x2, flags: 0x1}, - 152: {lang: 0x1bc, script: 0x3e, flags: 0x0}, - 154: {lang: 0x1d, script: 0x3, flags: 0x1}, - 156: {lang: 0x3a, script: 0x5, flags: 0x0}, - 157: {lang: 0x20, script: 0x2, flags: 0x1}, - 158: {lang: 0x1f8, script: 0x5b, flags: 0x0}, - 159: {lang: 0x1f9, script: 0x5b, flags: 0x0}, - 162: {lang: 0x3a, script: 0x5, flags: 0x0}, - 163: {lang: 0x200, script: 0x49, flags: 0x0}, - 165: {lang: 0x445, script: 0x5b, flags: 0x0}, - 166: {lang: 0x28a, script: 0x20, flags: 0x0}, - 167: {lang: 0x22, script: 0x3, flags: 0x1}, - 169: {lang: 0x25, script: 0x2, flags: 0x1}, - 171: {lang: 0x254, script: 0x54, flags: 0x0}, - 172: {lang: 0x254, script: 0x54, flags: 0x0}, - 173: {lang: 0x3a, script: 0x5, flags: 0x0}, - 175: {lang: 0x3e2, script: 0x20, flags: 0x0}, - 176: {lang: 0x27, script: 0x2, flags: 0x1}, - 177: {lang: 0x3a, script: 0x5, flags: 0x0}, - 179: {lang: 0x10d, script: 0x5b, flags: 0x0}, - 180: {lang: 0x40c, script: 0xd6, flags: 0x0}, - 182: {lang: 0x43b, script: 0x5b, flags: 0x0}, - 183: {lang: 0x2c0, script: 0x5b, flags: 0x0}, - 184: {lang: 0x15e, script: 0x5b, flags: 0x0}, - 185: {lang: 0x2c7, script: 0x5b, flags: 0x0}, - 186: {lang: 0x3a, script: 0x5, flags: 0x0}, - 187: {lang: 0x29, script: 0x2, flags: 0x1}, - 188: {lang: 0x15e, script: 0x5b, flags: 0x0}, - 189: {lang: 0x2b, script: 0x2, flags: 0x1}, - 190: {lang: 0x432, script: 0x5b, flags: 0x0}, - 191: {lang: 0x15e, script: 0x5b, flags: 0x0}, - 192: {lang: 0x2f1, script: 0x5b, flags: 0x0}, - 195: {lang: 0x2d, script: 0x2, flags: 0x1}, - 196: {lang: 0xa0, script: 0x5b, flags: 0x0}, - 197: {lang: 0x2f, script: 0x2, flags: 0x1}, - 198: {lang: 0x31, script: 0x2, flags: 0x1}, - 199: {lang: 0x33, script: 0x2, flags: 0x1}, - 201: {lang: 0x15e, script: 0x5b, flags: 0x0}, - 202: {lang: 0x35, script: 0x2, flags: 0x1}, - 204: {lang: 0x320, script: 0x5b, flags: 0x0}, - 205: {lang: 0x37, script: 0x3, flags: 0x1}, - 206: {lang: 0x128, script: 0xed, flags: 0x0}, - 208: {lang: 0x13e, script: 0x5b, flags: 0x0}, - 209: {lang: 0x31f, script: 0x5b, flags: 0x0}, - 210: {lang: 0x3c0, script: 0x5b, flags: 0x0}, - 211: {lang: 0x16, script: 0x5b, flags: 0x0}, - 212: {lang: 0x15e, script: 0x5b, flags: 0x0}, - 213: {lang: 0x1b4, script: 0x5b, flags: 0x0}, - 215: {lang: 0x1b4, script: 0x5, flags: 0x2}, - 217: {lang: 0x13e, script: 0x5b, flags: 0x0}, - 218: {lang: 0x367, script: 0x5b, flags: 0x0}, - 219: {lang: 0x347, script: 0x5b, flags: 0x0}, - 220: {lang: 0x351, script: 0x22, flags: 0x0}, - 226: {lang: 0x3a, script: 0x5, flags: 0x0}, - 227: {lang: 0x13e, script: 0x5b, flags: 0x0}, - 229: {lang: 0x13e, script: 0x5b, flags: 0x0}, - 230: {lang: 0x15e, script: 0x5b, flags: 0x0}, - 231: {lang: 0x486, script: 0x5b, flags: 0x0}, - 232: {lang: 0x153, script: 0x5b, flags: 0x0}, - 233: {lang: 0x3a, script: 0x3, flags: 0x1}, - 234: {lang: 0x3b3, script: 0x5b, flags: 0x0}, - 235: {lang: 0x15e, script: 0x5b, flags: 0x0}, - 237: {lang: 0x13e, script: 0x5b, flags: 0x0}, - 238: {lang: 0x3a, script: 0x5, flags: 0x0}, - 239: {lang: 0x3c0, script: 0x5b, flags: 0x0}, - 241: {lang: 0x3a2, script: 0x5b, flags: 0x0}, - 242: {lang: 0x194, script: 0x5b, flags: 0x0}, - 244: {lang: 0x3a, script: 0x5, flags: 0x0}, - 259: {lang: 0x15e, script: 0x5b, flags: 0x0}, - 261: {lang: 0x3d, script: 0x2, flags: 0x1}, - 262: {lang: 0x432, script: 0x20, flags: 0x0}, - 263: {lang: 0x3f, script: 0x2, flags: 0x1}, - 264: {lang: 0x3e5, script: 0x5b, flags: 0x0}, - 265: {lang: 0x3a, script: 0x5, flags: 0x0}, - 267: {lang: 0x15e, script: 0x5b, flags: 0x0}, - 268: {lang: 0x3a, script: 0x5, flags: 0x0}, - 269: {lang: 0x41, script: 0x2, flags: 0x1}, - 272: {lang: 0x416, script: 0x5b, flags: 0x0}, - 273: {lang: 0x347, script: 0x5b, flags: 0x0}, - 274: {lang: 0x43, script: 0x2, flags: 0x1}, - 276: {lang: 0x1f9, script: 0x5b, flags: 0x0}, - 277: {lang: 0x15e, script: 0x5b, flags: 0x0}, - 278: {lang: 0x429, script: 0x5b, flags: 0x0}, - 279: {lang: 0x367, script: 0x5b, flags: 0x0}, - 281: {lang: 0x3c0, script: 0x5b, flags: 0x0}, - 283: {lang: 0x13e, script: 0x5b, flags: 0x0}, - 285: {lang: 0x45, script: 0x2, flags: 0x1}, - 289: {lang: 0x15e, script: 0x5b, flags: 0x0}, - 290: {lang: 0x15e, script: 0x5b, flags: 0x0}, - 291: {lang: 0x47, script: 0x2, flags: 0x1}, - 292: {lang: 0x49, script: 0x3, flags: 0x1}, - 293: {lang: 0x4c, script: 0x2, flags: 0x1}, - 294: {lang: 0x477, script: 0x5b, flags: 0x0}, - 295: {lang: 0x3c0, script: 0x5b, flags: 0x0}, - 296: {lang: 0x476, script: 0x5b, flags: 0x0}, - 297: {lang: 0x4e, script: 0x2, flags: 0x1}, - 298: {lang: 0x482, script: 0x5b, flags: 0x0}, - 300: {lang: 0x50, script: 0x4, flags: 0x1}, - 302: {lang: 0x4a0, script: 0x5b, flags: 0x0}, - 303: {lang: 0x54, script: 0x2, flags: 0x1}, - 304: {lang: 0x445, script: 0x5b, flags: 0x0}, - 305: {lang: 0x56, script: 0x3, flags: 0x1}, - 306: {lang: 0x445, script: 0x5b, flags: 0x0}, - 310: {lang: 0x512, script: 0x3e, flags: 0x2}, - 311: {lang: 0x13e, script: 0x5b, flags: 0x0}, - 312: {lang: 0x4bc, script: 0x5b, flags: 0x0}, - 313: {lang: 0x1f9, script: 0x5b, flags: 0x0}, - 316: {lang: 0x13e, script: 0x5b, flags: 0x0}, - 319: {lang: 0x4c3, script: 0x5b, flags: 0x0}, - 320: {lang: 0x8a, script: 0x5b, flags: 0x0}, - 321: {lang: 0x15e, script: 0x5b, flags: 0x0}, - 323: {lang: 0x41b, script: 0x5b, flags: 0x0}, - 334: {lang: 0x59, script: 0x2, flags: 0x1}, - 351: {lang: 0x3a, script: 0x5, flags: 0x0}, - 352: {lang: 0x5b, script: 0x2, flags: 0x1}, - 357: {lang: 0x423, script: 0x5b, flags: 0x0}, -} - -// likelyRegionList holds lists info associated with likelyRegion. -// Size: 558 bytes, 93 elements -var likelyRegionList = [93]likelyLangScript{ - 0: {lang: 0x148, script: 0x5, flags: 0x0}, - 1: {lang: 0x476, script: 0x5b, flags: 0x0}, - 2: {lang: 0x431, script: 0x5b, flags: 0x0}, - 3: {lang: 0x2ff, script: 0x20, flags: 0x0}, - 4: {lang: 0x1d7, script: 0x8, flags: 0x0}, - 5: {lang: 0x274, script: 0x5b, flags: 0x0}, - 6: {lang: 0xb7, script: 0x5b, flags: 0x0}, - 7: {lang: 0x432, script: 0x20, flags: 0x0}, - 8: {lang: 0x12d, script: 0xef, flags: 0x0}, - 9: {lang: 0x351, script: 0x22, flags: 0x0}, - 10: {lang: 0x529, script: 0x3b, flags: 0x0}, - 11: {lang: 0x4ac, script: 0x5, flags: 0x0}, - 12: {lang: 0x523, script: 0x5b, flags: 0x0}, - 13: {lang: 0x29a, script: 0xee, flags: 0x0}, - 14: {lang: 0x136, script: 0x34, flags: 0x0}, - 15: {lang: 0x48a, script: 0x5b, flags: 0x0}, - 16: {lang: 0x3a, script: 0x5, flags: 0x0}, - 17: {lang: 0x15e, script: 0x5b, flags: 0x0}, - 18: {lang: 0x27, script: 0x2c, flags: 0x0}, - 19: {lang: 0x139, script: 0x5b, flags: 0x0}, - 20: {lang: 0x26a, script: 0x5, flags: 0x2}, - 21: {lang: 0x512, script: 0x3e, flags: 0x2}, - 22: {lang: 0x210, script: 0x2e, flags: 0x0}, - 23: {lang: 0x5, script: 0x20, flags: 0x0}, - 24: {lang: 0x274, script: 0x5b, flags: 0x0}, - 25: {lang: 0x136, script: 0x34, flags: 0x0}, - 26: {lang: 0x2ff, script: 0x20, flags: 0x0}, - 27: {lang: 0x1e1, script: 0x5b, flags: 0x0}, - 28: {lang: 0x31f, script: 0x5, flags: 0x0}, - 29: {lang: 0x1be, script: 0x22, flags: 0x0}, - 30: {lang: 0x4b4, script: 0x5, flags: 0x0}, - 31: {lang: 0x236, script: 0x76, flags: 0x0}, - 32: {lang: 0x148, script: 0x5, flags: 0x0}, - 33: {lang: 0x476, script: 0x5b, flags: 0x0}, - 34: {lang: 0x24a, script: 0x4f, flags: 0x0}, - 35: {lang: 0xe6, script: 0x5, flags: 0x0}, - 36: {lang: 0x226, script: 0xee, flags: 0x0}, - 37: {lang: 0x3a, script: 0x5, flags: 0x0}, - 38: {lang: 0x15e, script: 0x5b, flags: 0x0}, - 39: {lang: 0x2b8, script: 0x58, flags: 0x0}, - 40: {lang: 0x226, script: 0xee, flags: 0x0}, - 41: {lang: 0x3a, script: 0x5, flags: 0x0}, - 42: {lang: 0x15e, script: 0x5b, flags: 0x0}, - 43: {lang: 0x3dc, script: 0x5b, flags: 0x0}, - 44: {lang: 0x4ae, script: 0x20, flags: 0x0}, - 45: {lang: 0x2ff, script: 0x20, flags: 0x0}, - 46: {lang: 0x431, script: 0x5b, flags: 0x0}, - 47: {lang: 0x331, script: 0x76, flags: 0x0}, - 48: {lang: 0x213, script: 0x5b, flags: 0x0}, - 49: {lang: 0x30b, script: 0x20, flags: 0x0}, - 50: {lang: 0x242, script: 0x5, flags: 0x0}, - 51: {lang: 0x529, script: 0x3c, flags: 0x0}, - 52: {lang: 0x3c0, script: 0x5b, flags: 0x0}, - 53: {lang: 0x3a, script: 0x5, flags: 0x0}, - 54: {lang: 0x15e, script: 0x5b, flags: 0x0}, - 55: {lang: 0x2ed, script: 0x5b, flags: 0x0}, - 56: {lang: 0x4b4, script: 0x5, flags: 0x0}, - 57: {lang: 0x88, script: 0x22, flags: 0x0}, - 58: {lang: 0x4b4, script: 0x5, flags: 0x0}, - 59: {lang: 0x4b4, script: 0x5, flags: 0x0}, - 60: {lang: 0xbe, script: 0x22, flags: 0x0}, - 61: {lang: 0x3dc, script: 0x5b, flags: 0x0}, - 62: {lang: 0x7e, script: 0x20, flags: 0x0}, - 63: {lang: 0x3e2, script: 0x20, flags: 0x0}, - 64: {lang: 0x267, script: 0x5b, flags: 0x0}, - 65: {lang: 0x444, script: 0x5b, flags: 0x0}, - 66: {lang: 0x512, script: 0x3e, flags: 0x0}, - 67: {lang: 0x412, script: 0x5b, flags: 0x0}, - 68: {lang: 0x4ae, script: 0x20, flags: 0x0}, - 69: {lang: 0x3a, script: 0x5, flags: 0x0}, - 70: {lang: 0x15e, script: 0x5b, flags: 0x0}, - 71: {lang: 0x15e, script: 0x5b, flags: 0x0}, - 72: {lang: 0x35, script: 0x5, flags: 0x0}, - 73: {lang: 0x46b, script: 0xee, flags: 0x0}, - 74: {lang: 0x2ec, script: 0x5, flags: 0x0}, - 75: {lang: 0x30f, script: 0x76, flags: 0x0}, - 76: {lang: 0x467, script: 0x20, flags: 0x0}, - 77: {lang: 0x148, script: 0x5, flags: 0x0}, - 78: {lang: 0x3a, script: 0x5, flags: 0x0}, - 79: {lang: 0x15e, script: 0x5b, flags: 0x0}, - 80: {lang: 0x48a, script: 0x5b, flags: 0x0}, - 81: {lang: 0x58, script: 0x5, flags: 0x0}, - 82: {lang: 0x219, script: 0x20, flags: 0x0}, - 83: {lang: 0x81, script: 0x34, flags: 0x0}, - 84: {lang: 0x529, script: 0x3c, flags: 0x0}, - 85: {lang: 0x48c, script: 0x5b, flags: 0x0}, - 86: {lang: 0x4ae, script: 0x20, flags: 0x0}, - 87: {lang: 0x512, script: 0x3e, flags: 0x0}, - 88: {lang: 0x3b3, script: 0x5b, flags: 0x0}, - 89: {lang: 0x431, script: 0x5b, flags: 0x0}, - 90: {lang: 0x432, script: 0x20, flags: 0x0}, - 91: {lang: 0x15e, script: 0x5b, flags: 0x0}, - 92: {lang: 0x446, script: 0x5, flags: 0x0}, -} - -type likelyTag struct { - lang uint16 - region uint16 - script uint16 -} - -// Size: 198 bytes, 33 elements -var likelyRegionGroup = [33]likelyTag{ - 1: {lang: 0x139, region: 0xd7, script: 0x5b}, - 2: {lang: 0x139, region: 0x136, script: 0x5b}, - 3: {lang: 0x3c0, region: 0x41, script: 0x5b}, - 4: {lang: 0x139, region: 0x2f, script: 0x5b}, - 5: {lang: 0x139, region: 0xd7, script: 0x5b}, - 6: {lang: 0x13e, region: 0xd0, script: 0x5b}, - 7: {lang: 0x445, region: 0x130, script: 0x5b}, - 8: {lang: 0x3a, region: 0x6c, script: 0x5}, - 9: {lang: 0x445, region: 0x4b, script: 0x5b}, - 10: {lang: 0x139, region: 0x162, script: 0x5b}, - 11: {lang: 0x139, region: 0x136, script: 0x5b}, - 12: {lang: 0x139, region: 0x136, script: 0x5b}, - 13: {lang: 0x13e, region: 0x5a, script: 0x5b}, - 14: {lang: 0x529, region: 0x53, script: 0x3b}, - 15: {lang: 0x1be, region: 0x9a, script: 0x22}, - 16: {lang: 0x1e1, region: 0x96, script: 0x5b}, - 17: {lang: 0x1f9, region: 0x9f, script: 0x5b}, - 18: {lang: 0x139, region: 0x2f, script: 0x5b}, - 19: {lang: 0x139, region: 0xe7, script: 0x5b}, - 20: {lang: 0x139, region: 0x8b, script: 0x5b}, - 21: {lang: 0x41b, region: 0x143, script: 0x5b}, - 22: {lang: 0x529, region: 0x53, script: 0x3b}, - 23: {lang: 0x4bc, region: 0x138, script: 0x5b}, - 24: {lang: 0x3a, region: 0x109, script: 0x5}, - 25: {lang: 0x3e2, region: 0x107, script: 0x20}, - 26: {lang: 0x3e2, region: 0x107, script: 0x20}, - 27: {lang: 0x139, region: 0x7c, script: 0x5b}, - 28: {lang: 0x10d, region: 0x61, script: 0x5b}, - 29: {lang: 0x139, region: 0xd7, script: 0x5b}, - 30: {lang: 0x13e, region: 0x1f, script: 0x5b}, - 31: {lang: 0x139, region: 0x9b, script: 0x5b}, - 32: {lang: 0x139, region: 0x7c, script: 0x5b}, -} - -// Size: 264 bytes, 33 elements -var regionContainment = [33]uint64{ - // Entry 0 - 1F - 0x00000001ffffffff, 0x00000000200007a2, 0x0000000000003044, 0x0000000000000008, - 0x00000000803c0010, 0x0000000000000020, 0x0000000000000040, 0x0000000000000080, - 0x0000000000000100, 0x0000000000000200, 0x0000000000000400, 0x000000004000384c, - 0x0000000000001000, 0x0000000000002000, 0x0000000000004000, 0x0000000000008000, - 0x0000000000010000, 0x0000000000020000, 0x0000000000040000, 0x0000000000080000, - 0x0000000000100000, 0x0000000000200000, 0x0000000001c1c000, 0x0000000000800000, - 0x0000000001000000, 0x000000001e020000, 0x0000000004000000, 0x0000000008000000, - 0x0000000010000000, 0x00000000200006a0, 0x0000000040002048, 0x0000000080000000, - // Entry 20 - 3F - 0x0000000100000000, -} - -// regionInclusion maps region identifiers to sets of regions in regionInclusionBits, -// where each set holds all groupings that are directly connected in a region -// containment graph. -// Size: 359 bytes, 359 elements -var regionInclusion = [359]uint8{ - // Entry 0 - 3F - 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, - 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, - 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, - 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, - 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x26, 0x23, - 0x24, 0x26, 0x27, 0x22, 0x28, 0x29, 0x2a, 0x2b, - 0x26, 0x2c, 0x24, 0x23, 0x26, 0x25, 0x2a, 0x2d, - 0x2e, 0x24, 0x2f, 0x2d, 0x26, 0x30, 0x31, 0x28, - // Entry 40 - 7F - 0x26, 0x28, 0x26, 0x25, 0x31, 0x22, 0x32, 0x33, - 0x34, 0x30, 0x22, 0x27, 0x27, 0x27, 0x35, 0x2d, - 0x29, 0x28, 0x27, 0x36, 0x28, 0x22, 0x21, 0x34, - 0x23, 0x21, 0x26, 0x2d, 0x26, 0x22, 0x37, 0x2e, - 0x35, 0x2a, 0x22, 0x2f, 0x38, 0x26, 0x26, 0x21, - 0x39, 0x39, 0x28, 0x38, 0x39, 0x39, 0x2f, 0x3a, - 0x2f, 0x20, 0x21, 0x38, 0x3b, 0x28, 0x3c, 0x2c, - 0x21, 0x2a, 0x35, 0x27, 0x38, 0x26, 0x24, 0x28, - // Entry 80 - BF - 0x2c, 0x2d, 0x23, 0x30, 0x2d, 0x2d, 0x26, 0x27, - 0x3a, 0x22, 0x34, 0x3c, 0x2d, 0x28, 0x36, 0x22, - 0x34, 0x3a, 0x26, 0x2e, 0x21, 0x39, 0x31, 0x38, - 0x24, 0x2c, 0x25, 0x22, 0x24, 0x25, 0x2c, 0x3a, - 0x2c, 0x26, 0x24, 0x36, 0x21, 0x2f, 0x3d, 0x31, - 0x3c, 0x2f, 0x26, 0x36, 0x36, 0x24, 0x26, 0x3d, - 0x31, 0x24, 0x26, 0x35, 0x25, 0x2d, 0x32, 0x38, - 0x2a, 0x38, 0x39, 0x39, 0x35, 0x33, 0x23, 0x26, - // Entry C0 - FF - 0x2f, 0x3c, 0x21, 0x23, 0x2d, 0x31, 0x36, 0x36, - 0x3c, 0x26, 0x2d, 0x26, 0x3a, 0x2f, 0x25, 0x2f, - 0x34, 0x31, 0x2f, 0x32, 0x3b, 0x2d, 0x2b, 0x2d, - 0x21, 0x34, 0x2a, 0x2c, 0x25, 0x21, 0x3c, 0x24, - 0x29, 0x2b, 0x24, 0x34, 0x21, 0x28, 0x29, 0x3b, - 0x31, 0x25, 0x2e, 0x30, 0x29, 0x26, 0x24, 0x3a, - 0x21, 0x3c, 0x28, 0x21, 0x24, 0x21, 0x21, 0x1f, - 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, - // Entry 100 - 13F - 0x21, 0x21, 0x21, 0x2f, 0x21, 0x2e, 0x23, 0x33, - 0x2f, 0x24, 0x3b, 0x2f, 0x39, 0x38, 0x31, 0x2d, - 0x3a, 0x2c, 0x2e, 0x2d, 0x23, 0x2d, 0x2f, 0x28, - 0x2f, 0x27, 0x33, 0x34, 0x26, 0x24, 0x32, 0x22, - 0x26, 0x27, 0x22, 0x2d, 0x31, 0x3d, 0x29, 0x31, - 0x3d, 0x39, 0x29, 0x31, 0x24, 0x26, 0x29, 0x36, - 0x2f, 0x33, 0x2f, 0x21, 0x22, 0x21, 0x30, 0x28, - 0x3d, 0x23, 0x26, 0x21, 0x28, 0x26, 0x26, 0x31, - // Entry 140 - 17F - 0x3b, 0x29, 0x21, 0x29, 0x21, 0x21, 0x21, 0x21, - 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x23, 0x21, - 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, - 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x24, 0x24, - 0x2f, 0x23, 0x32, 0x2f, 0x27, 0x2f, 0x21, -} - -// regionInclusionBits is an array of bit vectors where every vector represents -// a set of region groupings. These sets are used to compute the distance -// between two regions for the purpose of language matching. -// Size: 584 bytes, 73 elements -var regionInclusionBits = [73]uint64{ - // Entry 0 - 1F - 0x0000000102400813, 0x00000000200007a3, 0x0000000000003844, 0x0000000040000808, - 0x00000000803c0011, 0x0000000020000022, 0x0000000040000844, 0x0000000020000082, - 0x0000000000000102, 0x0000000020000202, 0x0000000020000402, 0x000000004000384d, - 0x0000000000001804, 0x0000000040002804, 0x0000000000404000, 0x0000000000408000, - 0x0000000000410000, 0x0000000002020000, 0x0000000000040010, 0x0000000000080010, - 0x0000000000100010, 0x0000000000200010, 0x0000000001c1c001, 0x0000000000c00000, - 0x0000000001400000, 0x000000001e020001, 0x0000000006000000, 0x000000000a000000, - 0x0000000012000000, 0x00000000200006a2, 0x0000000040002848, 0x0000000080000010, - // Entry 20 - 3F - 0x0000000100000001, 0x0000000000000001, 0x0000000080000000, 0x0000000000020000, - 0x0000000001000000, 0x0000000000008000, 0x0000000000002000, 0x0000000000000200, - 0x0000000000000008, 0x0000000000200000, 0x0000000110000000, 0x0000000000040000, - 0x0000000008000000, 0x0000000000000020, 0x0000000104000000, 0x0000000000000080, - 0x0000000000001000, 0x0000000000010000, 0x0000000000000400, 0x0000000004000000, - 0x0000000000000040, 0x0000000010000000, 0x0000000000004000, 0x0000000101000000, - 0x0000000108000000, 0x0000000000000100, 0x0000000100020000, 0x0000000000080000, - 0x0000000000100000, 0x0000000000800000, 0x00000001ffffffff, 0x0000000122400fb3, - // Entry 40 - 5F - 0x00000001827c0813, 0x000000014240385f, 0x0000000103c1c813, 0x000000011e420813, - 0x0000000112000001, 0x0000000106000001, 0x0000000101400001, 0x000000010a000001, - 0x0000000102020001, -} - -// regionInclusionNext marks, for each entry in regionInclusionBits, the set of -// all groups that are reachable from the groups set in the respective entry. -// Size: 73 bytes, 73 elements -var regionInclusionNext = [73]uint8{ - // Entry 0 - 3F - 0x3e, 0x3f, 0x0b, 0x0b, 0x40, 0x01, 0x0b, 0x01, - 0x01, 0x01, 0x01, 0x41, 0x0b, 0x0b, 0x16, 0x16, - 0x16, 0x19, 0x04, 0x04, 0x04, 0x04, 0x42, 0x16, - 0x16, 0x43, 0x19, 0x19, 0x19, 0x01, 0x0b, 0x04, - 0x00, 0x00, 0x1f, 0x11, 0x18, 0x0f, 0x0d, 0x09, - 0x03, 0x15, 0x44, 0x12, 0x1b, 0x05, 0x45, 0x07, - 0x0c, 0x10, 0x0a, 0x1a, 0x06, 0x1c, 0x0e, 0x46, - 0x47, 0x08, 0x48, 0x13, 0x14, 0x17, 0x3e, 0x3e, - // Entry 40 - 7F - 0x3e, 0x3e, 0x3e, 0x3e, 0x43, 0x43, 0x42, 0x43, - 0x43, -} - -type parentRel struct { - lang uint16 - script uint16 - maxScript uint16 - toRegion uint16 - fromRegion []uint16 -} - -// Size: 414 bytes, 5 elements -var parents = [5]parentRel{ - 0: {lang: 0x139, script: 0x0, maxScript: 0x5b, toRegion: 0x1, fromRegion: []uint16{0x1a, 0x25, 0x26, 0x2f, 0x34, 0x36, 0x3d, 0x42, 0x46, 0x48, 0x49, 0x4a, 0x50, 0x52, 0x5d, 0x5e, 0x62, 0x65, 0x6e, 0x74, 0x75, 0x76, 0x7c, 0x7d, 0x80, 0x81, 0x82, 0x84, 0x8d, 0x8e, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0xa0, 0xa1, 0xa5, 0xa8, 0xaa, 0xae, 0xb2, 0xb5, 0xb6, 0xc0, 0xc7, 0xcb, 0xcc, 0xcd, 0xcf, 0xd1, 0xd3, 0xd6, 0xd7, 0xde, 0xe0, 0xe1, 0xe7, 0xe8, 0xe9, 0xec, 0xf1, 0x108, 0x10a, 0x10b, 0x10c, 0x10e, 0x10f, 0x113, 0x118, 0x11c, 0x11e, 0x120, 0x126, 0x12a, 0x12d, 0x12e, 0x130, 0x132, 0x13a, 0x13d, 0x140, 0x143, 0x162, 0x163, 0x165}}, - 1: {lang: 0x139, script: 0x0, maxScript: 0x5b, toRegion: 0x1a, fromRegion: []uint16{0x2e, 0x4e, 0x61, 0x64, 0x73, 0xda, 0x10d, 0x110}}, - 2: {lang: 0x13e, script: 0x0, maxScript: 0x5b, toRegion: 0x1f, fromRegion: []uint16{0x2c, 0x3f, 0x41, 0x48, 0x51, 0x54, 0x57, 0x5a, 0x66, 0x6a, 0x8a, 0x90, 0xd0, 0xd9, 0xe3, 0xe5, 0xed, 0xf2, 0x11b, 0x136, 0x137, 0x13c}}, - 3: {lang: 0x3c0, script: 0x0, maxScript: 0x5b, toRegion: 0xef, fromRegion: []uint16{0x2a, 0x4e, 0x5b, 0x87, 0x8c, 0xb8, 0xc7, 0xd2, 0x119, 0x127}}, - 4: {lang: 0x529, script: 0x3c, maxScript: 0x3c, toRegion: 0x8e, fromRegion: []uint16{0xc7}}, -} - -// Total table size 30466 bytes (29KiB); checksum: 7544152B diff --git a/vendor/golang.org/x/text/internal/language/tags.go b/vendor/golang.org/x/text/internal/language/tags.go deleted file mode 100644 index e7afd3188..000000000 --- a/vendor/golang.org/x/text/internal/language/tags.go +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2013 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 language - -// MustParse is like Parse, but panics if the given BCP 47 tag cannot be parsed. -// It simplifies safe initialization of Tag values. -func MustParse(s string) Tag { - t, err := Parse(s) - if err != nil { - panic(err) - } - return t -} - -// MustParseBase is like ParseBase, but panics if the given base cannot be parsed. -// It simplifies safe initialization of Base values. -func MustParseBase(s string) Language { - b, err := ParseBase(s) - if err != nil { - panic(err) - } - return b -} - -// MustParseScript is like ParseScript, but panics if the given script cannot be -// parsed. It simplifies safe initialization of Script values. -func MustParseScript(s string) Script { - scr, err := ParseScript(s) - if err != nil { - panic(err) - } - return scr -} - -// MustParseRegion is like ParseRegion, but panics if the given region cannot be -// parsed. It simplifies safe initialization of Region values. -func MustParseRegion(s string) Region { - r, err := ParseRegion(s) - if err != nil { - panic(err) - } - return r -} - -// Und is the root language. -var Und Tag diff --git a/vendor/golang.org/x/text/internal/match.go b/vendor/golang.org/x/text/internal/match.go deleted file mode 100644 index 1cc004a6d..000000000 --- a/vendor/golang.org/x/text/internal/match.go +++ /dev/null @@ -1,67 +0,0 @@ -// 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 internal - -// This file contains matchers that implement CLDR inheritance. -// -// See https://unicode.org/reports/tr35/#Locale_Inheritance. -// -// Some of the inheritance described in this document is already handled by -// the cldr package. - -import ( - "golang.org/x/text/language" -) - -// TODO: consider if (some of the) matching algorithm needs to be public after -// getting some feel about what is generic and what is specific. - -// NewInheritanceMatcher returns a matcher that matches based on the inheritance -// chain. -// -// The matcher uses canonicalization and the parent relationship to find a -// match. The resulting match will always be either Und or a language with the -// same language and script as the requested language. It will not match -// languages for which there is understood to be mutual or one-directional -// intelligibility. -// -// A Match will indicate an Exact match if the language matches after -// canonicalization and High if the matched tag is a parent. -func NewInheritanceMatcher(t []language.Tag) *InheritanceMatcher { - tags := &InheritanceMatcher{make(map[language.Tag]int)} - for i, tag := range t { - ct, err := language.All.Canonicalize(tag) - if err != nil { - ct = tag - } - tags.index[ct] = i - } - return tags -} - -type InheritanceMatcher struct { - index map[language.Tag]int -} - -func (m InheritanceMatcher) Match(want ...language.Tag) (language.Tag, int, language.Confidence) { - for _, t := range want { - ct, err := language.All.Canonicalize(t) - if err != nil { - ct = t - } - conf := language.Exact - for { - if index, ok := m.index[ct]; ok { - return ct, index, conf - } - if ct == language.Und { - break - } - ct = ct.Parent() - conf = language.High - } - } - return language.Und, 0, language.No -} diff --git a/vendor/golang.org/x/text/internal/number/common.go b/vendor/golang.org/x/text/internal/number/common.go deleted file mode 100644 index a6e9c8e0d..000000000 --- a/vendor/golang.org/x/text/internal/number/common.go +++ /dev/null @@ -1,55 +0,0 @@ -// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. - -package number - -import ( - "unicode/utf8" - - "golang.org/x/text/internal/language/compact" -) - -// 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 compact.ID - 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 deleted file mode 100644 index e128cf343..000000000 --- a/vendor/golang.org/x/text/internal/number/decimal.go +++ /dev/null @@ -1,500 +0,0 @@ -// 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 usable 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/format.go b/vendor/golang.org/x/text/internal/number/format.go deleted file mode 100644 index cd94c5dc4..000000000 --- a/vendor/golang.org/x/text/internal/number/format.go +++ /dev/null @@ -1,535 +0,0 @@ -// 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) - f.Pattern = formats[index[tagToID(t)]] -} - -// 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/number.go b/vendor/golang.org/x/text/internal/number/number.go deleted file mode 100644 index e1d933c3f..000000000 --- a/vendor/golang.org/x/text/internal/number/number.go +++ /dev/null @@ -1,152 +0,0 @@ -// 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/language/compact" - "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 compact.ID, 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 = langIndex.Parent() - } else { - // The index points to a list of symbol data indexes. - for _, e := range langToAlt[p&^hasNonLatnMask:] { - if 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 - // https://unicode.org/reports/tr35/#Locale_Inheritance. - ns = numLatn - langIndex = compactIndex - continue outerLoop - } - // Fall back to parent. - langIndex = langIndex.Parent() - } 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 { - return InfoFromLangID(tagToID(t), t.TypeForKey("nu")) -} - -// 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 { - return &formats[index[tagToID(t)]] -} - -func tagToID(t language.Tag) compact.ID { - id, _ := compact.RegionalID(compact.Tag(t)) - return id -} diff --git a/vendor/golang.org/x/text/internal/number/pattern.go b/vendor/golang.org/x/text/internal/number/pattern.go deleted file mode 100644 index 06e59559a..000000000 --- a/vendor/golang.org/x/text/internal/number/pattern.go +++ /dev/null @@ -1,485 +0,0 @@ -// 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 -// https://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 https://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/roundingmode_string.go b/vendor/golang.org/x/text/internal/number/roundingmode_string.go deleted file mode 100644 index bcc22471d..000000000 --- a/vendor/golang.org/x/text/internal/number/roundingmode_string.go +++ /dev/null @@ -1,30 +0,0 @@ -// Code generated by "stringer -type RoundingMode"; DO NOT EDIT. - -package number - -import "strconv" - -func _() { - // An "invalid array index" compiler error signifies that the constant values have changed. - // Re-run the stringer command to generate them again. - var x [1]struct{} - _ = x[ToNearestEven-0] - _ = x[ToNearestZero-1] - _ = x[ToNearestAway-2] - _ = x[ToPositiveInf-3] - _ = x[ToNegativeInf-4] - _ = x[ToZero-5] - _ = x[AwayFromZero-6] - _ = x[numModes-7] -} - -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 "RoundingMode(" + strconv.FormatInt(int64(i), 10) + ")" - } - 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 deleted file mode 100644 index 8efce81b5..000000000 --- a/vendor/golang.org/x/text/internal/number/tables.go +++ /dev/null @@ -1,1219 +0,0 @@ -// 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 = [775]symOffset{ - // Entry 0 - 3F - 0x8000, 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, 0x0000, 0x0000, - // Entry 40 - 7F - 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, 0x0000, 0x0000, - // Entry 80 - BF - 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, 0x0000, 0x0000, - // Entry C0 - FF - 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, 0x0006, 0x0006, - // Entry 100 - 13F - 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, 0x0001, 0x0001, - // Entry 140 - 17F - 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, 0x0000, 0x0000, - // Entry 180 - 1BF - 0x0000, 0x0000, 0x8052, 0x0006, 0x0006, 0x001d, 0x0006, 0x0006, - 0x0006, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0006, 0x0006, - 0x0000, 0x0000, 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, - // Entry 1C0 - 1FF - 0x0000, 0x0023, 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, 0x0000, 0x805a, 0x0000, 0x0000, 0x0006, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0006, 0x0006, 0x805b, 0x0026, 0x805d, - // Entry 200 - 23F - 0x0000, 0x0000, 0x0000, 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, - // Entry 240 - 27F - 0x0001, 0x0001, 0x0001, 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, 0x0000, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, - 0x002c, 0x002c, 0x002d, 0x002d, 0x002e, 0x002e, 0x0000, 0x0000, - // Entry 280 - 2BF - 0x0000, 0x002f, 0x002f, 0x0000, 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, 0x0000, 0x8071, 0x0031, 0x0006, - // Entry 2C0 - 2FF - 0x0006, 0x0006, 0x0000, 0x0001, 0x0001, 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, - // Entry 300 - 33F - 0x0036, 0x0036, 0x0036, 0x0000, 0x0000, 0x0006, 0x0014, -} // Size: 1550 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: 0xa, symIndex: 0x39, system: 0x3}, - 4: {compactTag: 0xa, symIndex: 0x2, system: 0x0}, - 5: {compactTag: 0x28, symIndex: 0x0, system: 0x6}, - 6: {compactTag: 0x2c, symIndex: 0x5, system: 0x0}, - 7: {compactTag: 0x2c, symIndex: 0x3a, system: 0x3}, - 8: {compactTag: 0x2c, symIndex: 0x42, system: 0x4}, - 9: {compactTag: 0x40, symIndex: 0x0, system: 0x6}, - 10: {compactTag: 0x43, symIndex: 0x0, system: 0x0}, - 11: {compactTag: 0x43, symIndex: 0x4f, system: 0x37}, - 12: {compactTag: 0x46, symIndex: 0x1, system: 0x0}, - 13: {compactTag: 0x46, symIndex: 0x38, system: 0x3}, - 14: {compactTag: 0x54, symIndex: 0x0, system: 0x9}, - 15: {compactTag: 0x5d, symIndex: 0x3a, system: 0x3}, - 16: {compactTag: 0x5d, symIndex: 0x8, system: 0x0}, - 17: {compactTag: 0x60, symIndex: 0x1, system: 0x0}, - 18: {compactTag: 0x60, symIndex: 0x38, system: 0x3}, - 19: {compactTag: 0x60, symIndex: 0x42, system: 0x4}, - 20: {compactTag: 0x60, symIndex: 0x0, system: 0x5}, - 21: {compactTag: 0x60, symIndex: 0x0, system: 0x6}, - 22: {compactTag: 0x60, symIndex: 0x0, system: 0x8}, - 23: {compactTag: 0x60, symIndex: 0x0, system: 0x9}, - 24: {compactTag: 0x60, symIndex: 0x0, system: 0xa}, - 25: {compactTag: 0x60, symIndex: 0x0, system: 0xb}, - 26: {compactTag: 0x60, symIndex: 0x0, system: 0xc}, - 27: {compactTag: 0x60, symIndex: 0x0, system: 0xd}, - 28: {compactTag: 0x60, symIndex: 0x0, system: 0xe}, - 29: {compactTag: 0x60, symIndex: 0x0, system: 0xf}, - 30: {compactTag: 0x60, symIndex: 0x0, system: 0x11}, - 31: {compactTag: 0x60, symIndex: 0x0, system: 0x12}, - 32: {compactTag: 0x60, symIndex: 0x0, system: 0x13}, - 33: {compactTag: 0x60, symIndex: 0x0, system: 0x14}, - 34: {compactTag: 0x60, symIndex: 0x0, system: 0x15}, - 35: {compactTag: 0x60, symIndex: 0x0, system: 0x16}, - 36: {compactTag: 0x60, symIndex: 0x0, system: 0x17}, - 37: {compactTag: 0x60, symIndex: 0x0, system: 0x18}, - 38: {compactTag: 0x60, symIndex: 0x0, system: 0x19}, - 39: {compactTag: 0x60, symIndex: 0x0, system: 0x1f}, - 40: {compactTag: 0x60, symIndex: 0x0, system: 0x21}, - 41: {compactTag: 0x60, symIndex: 0x0, system: 0x23}, - 42: {compactTag: 0x60, symIndex: 0x0, system: 0x24}, - 43: {compactTag: 0x60, symIndex: 0x0, system: 0x25}, - 44: {compactTag: 0x60, symIndex: 0x0, system: 0x28}, - 45: {compactTag: 0x60, symIndex: 0x0, system: 0x29}, - 46: {compactTag: 0x60, symIndex: 0x0, system: 0x2a}, - 47: {compactTag: 0x60, symIndex: 0x0, system: 0x2b}, - 48: {compactTag: 0x60, symIndex: 0x0, system: 0x2c}, - 49: {compactTag: 0x60, symIndex: 0x0, system: 0x2d}, - 50: {compactTag: 0x60, symIndex: 0x0, system: 0x30}, - 51: {compactTag: 0x60, symIndex: 0x0, system: 0x31}, - 52: {compactTag: 0x60, symIndex: 0x0, system: 0x32}, - 53: {compactTag: 0x60, symIndex: 0x0, system: 0x33}, - 54: {compactTag: 0x60, symIndex: 0x0, system: 0x34}, - 55: {compactTag: 0x60, symIndex: 0x0, system: 0x35}, - 56: {compactTag: 0x60, symIndex: 0x0, system: 0x36}, - 57: {compactTag: 0x60, symIndex: 0x0, system: 0x37}, - 58: {compactTag: 0x60, symIndex: 0x0, system: 0x39}, - 59: {compactTag: 0x60, symIndex: 0x0, system: 0x43}, - 60: {compactTag: 0x64, symIndex: 0x0, system: 0x0}, - 61: {compactTag: 0x64, symIndex: 0x38, system: 0x3}, - 62: {compactTag: 0x64, symIndex: 0x42, system: 0x4}, - 63: {compactTag: 0x7c, symIndex: 0x50, system: 0x37}, - 64: {compactTag: 0x7c, symIndex: 0x0, system: 0x0}, - 65: {compactTag: 0x114, symIndex: 0x43, system: 0x4}, - 66: {compactTag: 0x114, symIndex: 0x18, system: 0x0}, - 67: {compactTag: 0x114, symIndex: 0x3b, system: 0x3}, - 68: {compactTag: 0x123, symIndex: 0x1, system: 0x0}, - 69: {compactTag: 0x123, symIndex: 0x3c, system: 0x3}, - 70: {compactTag: 0x123, symIndex: 0x44, system: 0x4}, - 71: {compactTag: 0x158, symIndex: 0x0, system: 0x0}, - 72: {compactTag: 0x158, symIndex: 0x3b, system: 0x3}, - 73: {compactTag: 0x158, symIndex: 0x45, system: 0x4}, - 74: {compactTag: 0x160, symIndex: 0x0, system: 0x0}, - 75: {compactTag: 0x160, symIndex: 0x38, system: 0x3}, - 76: {compactTag: 0x16d, symIndex: 0x1b, system: 0x0}, - 77: {compactTag: 0x16d, symIndex: 0x0, system: 0x9}, - 78: {compactTag: 0x16d, symIndex: 0x0, system: 0xa}, - 79: {compactTag: 0x17c, symIndex: 0x0, system: 0x0}, - 80: {compactTag: 0x17c, symIndex: 0x3d, system: 0x3}, - 81: {compactTag: 0x17c, symIndex: 0x42, system: 0x4}, - 82: {compactTag: 0x182, symIndex: 0x6, system: 0x0}, - 83: {compactTag: 0x182, symIndex: 0x38, system: 0x3}, - 84: {compactTag: 0x1b1, symIndex: 0x0, system: 0x0}, - 85: {compactTag: 0x1b1, symIndex: 0x3e, system: 0x3}, - 86: {compactTag: 0x1b6, symIndex: 0x42, system: 0x4}, - 87: {compactTag: 0x1b6, symIndex: 0x1b, system: 0x0}, - 88: {compactTag: 0x1d2, symIndex: 0x42, system: 0x4}, - 89: {compactTag: 0x1d2, symIndex: 0x0, system: 0x0}, - 90: {compactTag: 0x1f3, symIndex: 0x0, system: 0xb}, - 91: {compactTag: 0x1fd, symIndex: 0x4e, system: 0x24}, - 92: {compactTag: 0x1fd, symIndex: 0x26, system: 0x0}, - 93: {compactTag: 0x1ff, symIndex: 0x42, system: 0x4}, - 94: {compactTag: 0x204, symIndex: 0x15, system: 0x0}, - 95: {compactTag: 0x204, symIndex: 0x3f, system: 0x3}, - 96: {compactTag: 0x204, symIndex: 0x46, system: 0x4}, - 97: {compactTag: 0x20c, symIndex: 0x0, system: 0xb}, - 98: {compactTag: 0x20f, symIndex: 0x6, system: 0x0}, - 99: {compactTag: 0x20f, symIndex: 0x38, system: 0x3}, - 100: {compactTag: 0x20f, symIndex: 0x42, system: 0x4}, - 101: {compactTag: 0x22e, symIndex: 0x0, system: 0x0}, - 102: {compactTag: 0x22e, symIndex: 0x47, system: 0x4}, - 103: {compactTag: 0x22f, symIndex: 0x42, system: 0x4}, - 104: {compactTag: 0x22f, symIndex: 0x1b, system: 0x0}, - 105: {compactTag: 0x238, symIndex: 0x42, system: 0x4}, - 106: {compactTag: 0x238, symIndex: 0x28, system: 0x0}, - 107: {compactTag: 0x265, symIndex: 0x38, system: 0x3}, - 108: {compactTag: 0x265, symIndex: 0x0, system: 0x0}, - 109: {compactTag: 0x29d, symIndex: 0x22, system: 0x0}, - 110: {compactTag: 0x29d, symIndex: 0x40, system: 0x3}, - 111: {compactTag: 0x29d, symIndex: 0x48, system: 0x4}, - 112: {compactTag: 0x29d, symIndex: 0x4d, system: 0xc}, - 113: {compactTag: 0x2bd, symIndex: 0x31, system: 0x0}, - 114: {compactTag: 0x2bd, symIndex: 0x3e, system: 0x3}, - 115: {compactTag: 0x2bd, symIndex: 0x42, system: 0x4}, - 116: {compactTag: 0x2cd, symIndex: 0x1b, system: 0x0}, - 117: {compactTag: 0x2cd, symIndex: 0x49, system: 0x4}, - 118: {compactTag: 0x2ce, symIndex: 0x49, system: 0x4}, - 119: {compactTag: 0x2d0, symIndex: 0x33, system: 0x0}, - 120: {compactTag: 0x2d0, symIndex: 0x4a, system: 0x4}, - 121: {compactTag: 0x2d1, symIndex: 0x42, system: 0x4}, - 122: {compactTag: 0x2d1, symIndex: 0x28, system: 0x0}, - 123: {compactTag: 0x2d3, symIndex: 0x34, system: 0x0}, - 124: {compactTag: 0x2d3, symIndex: 0x4b, system: 0x4}, - 125: {compactTag: 0x2f9, symIndex: 0x0, system: 0x0}, - 126: {compactTag: 0x2f9, symIndex: 0x38, system: 0x3}, - 127: {compactTag: 0x2f9, symIndex: 0x42, system: 0x4}, - 128: {compactTag: 0x2ff, symIndex: 0x36, system: 0x0}, - 129: {compactTag: 0x2ff, symIndex: 0x41, system: 0x3}, - 130: {compactTag: 0x2ff, symIndex: 0x4c, system: 0x4}, -} // Size: 810 bytes - -var tagToDecimal = []uint8{ // 775 elements - // Entry 0 - 3F - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 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, 0x01, 0x01, - // Entry 40 - 7F - 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, 0x01, 0x01, - // 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, 0x05, 0x01, 0x01, 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, - 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, 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, 0x01, 0x01, 0x05, 0x05, 0x05, 0x05, - 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, 0x01, 0x01, 0x05, 0x05, - 0x01, 0x01, 0x01, 0x05, 0x05, 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, 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, - // 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, 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, - // 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, - // Entry 300 - 33F - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x08, -} // Size: 799 bytes - -var tagToScientific = []uint8{ // 775 elements - // Entry 0 - 3F - 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, - 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, - 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, 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, 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, 0x02, 0x0c, 0x0c, 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, 0x02, 0x02, 0x02, 0x0c, 0x02, - 0x02, 0x0c, 0x0c, 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, 0x02, 0x02, 0x02, 0x02, - 0x0d, 0x0d, 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, - // Entry 300 - 33F - 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x09, -} // Size: 799 bytes - -var tagToPercent = []uint8{ // 775 elements - // Entry 0 - 3F - 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, - 0x06, 0x06, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - // Entry 40 - 7F - 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, 0x04, 0x04, - // Entry 80 - BF - 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, 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, 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, 0x03, 0x03, - // Entry 100 - 13F - 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, 0x03, 0x03, - // Entry 140 - 17F - 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, 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, 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, - // Entry 1C0 - 1FF - 0x04, 0x04, 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, - // Entry 200 - 23F - 0x04, 0x04, 0x04, 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, - // Entry 240 - 27F - 0x04, 0x04, 0x04, 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, 0x04, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, - // Entry 280 - 2BF - 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, 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, 0x04, 0x0e, - // Entry 2C0 - 2FF - 0x0e, 0x0e, 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, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, - 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - // Entry 300 - 33F - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x0a, -} // Size: 799 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 8634 bytes (8KiB); checksum: 8F23386D diff --git a/vendor/golang.org/x/text/internal/stringset/set.go b/vendor/golang.org/x/text/internal/stringset/set.go deleted file mode 100644 index bb2fffbc7..000000000 --- a/vendor/golang.org/x/text/internal/stringset/set.go +++ /dev/null @@ -1,86 +0,0 @@ -// 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 stringset provides a way to represent a collection of strings -// compactly. -package stringset - -import "sort" - -// A Set holds a collection of strings that can be looked up by an index number. -type Set struct { - // These fields are exported to allow for code generation. - - Data string - Index []uint16 -} - -// Elem returns the string with index i. It panics if i is out of range. -func (s *Set) Elem(i int) string { - return s.Data[s.Index[i]:s.Index[i+1]] -} - -// Len returns the number of strings in the set. -func (s *Set) Len() int { - return len(s.Index) - 1 -} - -// Search returns the index of the given string or -1 if it is not in the set. -// The Set must have been created with strings in sorted order. -func Search(s *Set, str string) int { - // TODO: optimize this if it gets used a lot. - n := len(s.Index) - 1 - p := sort.Search(n, func(i int) bool { - return s.Elem(i) >= str - }) - if p == n || str != s.Elem(p) { - return -1 - } - return p -} - -// A Builder constructs Sets. -type Builder struct { - set Set - index map[string]int -} - -// NewBuilder returns a new and initialized Builder. -func NewBuilder() *Builder { - return &Builder{ - set: Set{ - Index: []uint16{0}, - }, - index: map[string]int{}, - } -} - -// Set creates the set created so far. -func (b *Builder) Set() Set { - return b.set -} - -// Index returns the index for the given string, which must have been added -// before. -func (b *Builder) Index(s string) int { - return b.index[s] -} - -// Add adds a string to the index. Strings that are added by a single Add will -// be stored together, unless they match an existing string. -func (b *Builder) Add(ss ...string) { - // First check if the string already exists. - for _, s := range ss { - if _, ok := b.index[s]; ok { - continue - } - b.index[s] = len(b.set.Index) - 1 - b.set.Data += s - x := len(b.set.Data) - if x > 0xFFFF { - panic("Index too > 0xFFFF") - } - b.set.Index = append(b.set.Index, uint16(x)) - } -} diff --git a/vendor/golang.org/x/text/internal/tag/tag.go b/vendor/golang.org/x/text/internal/tag/tag.go deleted file mode 100644 index b5d348891..000000000 --- a/vendor/golang.org/x/text/internal/tag/tag.go +++ /dev/null @@ -1,100 +0,0 @@ -// 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 tag contains functionality handling tags and related data. -package tag // import "golang.org/x/text/internal/tag" - -import "sort" - -// An Index converts tags to a compact numeric value. -// -// All elements are of size 4. Tags may be up to 4 bytes long. Excess bytes can -// be used to store additional information about the tag. -type Index string - -// Elem returns the element data at the given index. -func (s Index) Elem(x int) string { - return string(s[x*4 : x*4+4]) -} - -// Index reports the index of the given key or -1 if it could not be found. -// Only the first len(key) bytes from the start of the 4-byte entries will be -// considered for the search and the first match in Index will be returned. -func (s Index) Index(key []byte) int { - n := len(key) - // search the index of the first entry with an equal or higher value than - // key in s. - index := sort.Search(len(s)/4, func(i int) bool { - return cmp(s[i*4:i*4+n], key) != -1 - }) - i := index * 4 - if cmp(s[i:i+len(key)], key) != 0 { - return -1 - } - return index -} - -// Next finds the next occurrence of key after index x, which must have been -// obtained from a call to Index using the same key. It returns x+1 or -1. -func (s Index) Next(key []byte, x int) int { - if x++; x*4 < len(s) && cmp(s[x*4:x*4+len(key)], key) == 0 { - return x - } - return -1 -} - -// cmp returns an integer comparing a and b lexicographically. -func cmp(a Index, b []byte) int { - n := len(a) - if len(b) < n { - n = len(b) - } - for i, c := range b[:n] { - switch { - case a[i] > c: - return 1 - case a[i] < c: - return -1 - } - } - switch { - case len(a) < len(b): - return -1 - case len(a) > len(b): - return 1 - } - return 0 -} - -// Compare returns an integer comparing a and b lexicographically. -func Compare(a string, b []byte) int { - return cmp(Index(a), b) -} - -// FixCase reformats b to the same pattern of cases as form. -// If returns false if string b is malformed. -func FixCase(form string, b []byte) bool { - if len(form) != len(b) { - return false - } - for i, c := range b { - if form[i] <= 'Z' { - if c >= 'a' { - c -= 'z' - 'Z' - } - if c < 'A' || 'Z' < c { - return false - } - } else { - if c <= 'Z' { - c += 'z' - 'Z' - } - if c < 'a' || 'z' < c { - return false - } - } - b[i] = c - } - return true -} diff --git a/vendor/golang.org/x/text/language/coverage.go b/vendor/golang.org/x/text/language/coverage.go deleted file mode 100644 index a24fd1a4d..000000000 --- a/vendor/golang.org/x/text/language/coverage.go +++ /dev/null @@ -1,187 +0,0 @@ -// Copyright 2014 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 language - -import ( - "fmt" - "sort" - - "golang.org/x/text/internal/language" -) - -// The Coverage interface is used to define the level of coverage of an -// internationalization service. Note that not all types are supported by all -// services. As lists may be generated on the fly, it is recommended that users -// of a Coverage cache the results. -type Coverage interface { - // Tags returns the list of supported tags. - Tags() []Tag - - // BaseLanguages returns the list of supported base languages. - BaseLanguages() []Base - - // Scripts returns the list of supported scripts. - Scripts() []Script - - // Regions returns the list of supported regions. - Regions() []Region -} - -var ( - // Supported defines a Coverage that lists all supported subtags. Tags - // always returns nil. - Supported Coverage = allSubtags{} -) - -// TODO: -// - Support Variants, numbering systems. -// - CLDR coverage levels. -// - Set of common tags defined in this package. - -type allSubtags struct{} - -// Regions returns the list of supported regions. As all regions are in a -// consecutive range, it simply returns a slice of numbers in increasing order. -// The "undefined" region is not returned. -func (s allSubtags) Regions() []Region { - reg := make([]Region, language.NumRegions) - for i := range reg { - reg[i] = Region{language.Region(i + 1)} - } - return reg -} - -// Scripts returns the list of supported scripts. As all scripts are in a -// consecutive range, it simply returns a slice of numbers in increasing order. -// The "undefined" script is not returned. -func (s allSubtags) Scripts() []Script { - scr := make([]Script, language.NumScripts) - for i := range scr { - scr[i] = Script{language.Script(i + 1)} - } - return scr -} - -// BaseLanguages returns the list of all supported base languages. It generates -// the list by traversing the internal structures. -func (s allSubtags) BaseLanguages() []Base { - bs := language.BaseLanguages() - base := make([]Base, len(bs)) - for i, b := range bs { - base[i] = Base{b} - } - return base -} - -// Tags always returns nil. -func (s allSubtags) Tags() []Tag { - return nil -} - -// coverage is used by NewCoverage which is used as a convenient way for -// creating Coverage implementations for partially defined data. Very often a -// package will only need to define a subset of slices. coverage provides a -// convenient way to do this. Moreover, packages using NewCoverage, instead of -// their own implementation, will not break if later new slice types are added. -type coverage struct { - tags func() []Tag - bases func() []Base - scripts func() []Script - regions func() []Region -} - -func (s *coverage) Tags() []Tag { - if s.tags == nil { - return nil - } - return s.tags() -} - -// bases implements sort.Interface and is used to sort base languages. -type bases []Base - -func (b bases) Len() int { - return len(b) -} - -func (b bases) Swap(i, j int) { - b[i], b[j] = b[j], b[i] -} - -func (b bases) Less(i, j int) bool { - return b[i].langID < b[j].langID -} - -// BaseLanguages returns the result from calling s.bases if it is specified or -// otherwise derives the set of supported base languages from tags. -func (s *coverage) BaseLanguages() []Base { - if s.bases == nil { - tags := s.Tags() - if len(tags) == 0 { - return nil - } - a := make([]Base, len(tags)) - for i, t := range tags { - a[i] = Base{language.Language(t.lang())} - } - sort.Sort(bases(a)) - k := 0 - for i := 1; i < len(a); i++ { - if a[k] != a[i] { - k++ - a[k] = a[i] - } - } - return a[:k+1] - } - return s.bases() -} - -func (s *coverage) Scripts() []Script { - if s.scripts == nil { - return nil - } - return s.scripts() -} - -func (s *coverage) Regions() []Region { - if s.regions == nil { - return nil - } - return s.regions() -} - -// NewCoverage returns a Coverage for the given lists. It is typically used by -// packages providing internationalization services to define their level of -// coverage. A list may be of type []T or func() []T, where T is either Tag, -// Base, Script or Region. The returned Coverage derives the value for Bases -// from Tags if no func or slice for []Base is specified. For other unspecified -// types the returned Coverage will return nil for the respective methods. -func NewCoverage(list ...interface{}) Coverage { - s := &coverage{} - for _, x := range list { - switch v := x.(type) { - case func() []Base: - s.bases = v - case func() []Script: - s.scripts = v - case func() []Region: - s.regions = v - case func() []Tag: - s.tags = v - case []Base: - s.bases = func() []Base { return v } - case []Script: - s.scripts = func() []Script { return v } - case []Region: - s.regions = func() []Region { return v } - case []Tag: - s.tags = func() []Tag { return v } - default: - panic(fmt.Sprintf("language: unsupported set type %T", v)) - } - } - return s -} diff --git a/vendor/golang.org/x/text/language/doc.go b/vendor/golang.org/x/text/language/doc.go deleted file mode 100644 index 212b77c90..000000000 --- a/vendor/golang.org/x/text/language/doc.go +++ /dev/null @@ -1,98 +0,0 @@ -// 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 language implements BCP 47 language tags and related functionality. -// -// The most important function of package language is to match a list of -// user-preferred languages to a list of supported languages. -// It alleviates the developer of dealing with the complexity of this process -// and provides the user with the best experience -// (see https://blog.golang.org/matchlang). -// -// # Matching preferred against supported languages -// -// A Matcher for an application that supports English, Australian English, -// Danish, and standard Mandarin can be created as follows: -// -// var matcher = language.NewMatcher([]language.Tag{ -// language.English, // The first language is used as fallback. -// language.MustParse("en-AU"), -// language.Danish, -// language.Chinese, -// }) -// -// This list of supported languages is typically implied by the languages for -// which there exists translations of the user interface. -// -// User-preferred languages usually come as a comma-separated list of BCP 47 -// language tags. -// The MatchString finds best matches for such strings: -// -// handler(w http.ResponseWriter, r *http.Request) { -// lang, _ := r.Cookie("lang") -// accept := r.Header.Get("Accept-Language") -// tag, _ := language.MatchStrings(matcher, lang.String(), accept) -// -// // tag should now be used for the initialization of any -// // locale-specific service. -// } -// -// The Matcher's Match method can be used to match Tags directly. -// -// Matchers are aware of the intricacies of equivalence between languages, such -// as deprecated subtags, legacy tags, macro languages, mutual -// intelligibility between scripts and languages, and transparently passing -// BCP 47 user configuration. -// For instance, it will know that a reader of Bokmål Danish can read Norwegian -// and will know that Cantonese ("yue") is a good match for "zh-HK". -// -// # Using match results -// -// To guarantee a consistent user experience to the user it is important to -// use the same language tag for the selection of any locale-specific services. -// For example, it is utterly confusing to substitute spelled-out numbers -// or dates in one language in text of another language. -// More subtly confusing is using the wrong sorting order or casing -// algorithm for a certain language. -// -// All the packages in x/text that provide locale-specific services -// (e.g. collate, cases) should be initialized with the tag that was -// obtained at the start of an interaction with the user. -// -// Note that Tag that is returned by Match and MatchString may differ from any -// of the supported languages, as it may contain carried over settings from -// the user tags. -// This may be inconvenient when your application has some additional -// locale-specific data for your supported languages. -// Match and MatchString both return the index of the matched supported tag -// to simplify associating such data with the matched tag. -// -// # Canonicalization -// -// If one uses the Matcher to compare languages one does not need to -// worry about canonicalization. -// -// The meaning of a Tag varies per application. The language package -// therefore delays canonicalization and preserves information as much -// as possible. The Matcher, however, will always take into account that -// two different tags may represent the same language. -// -// By default, only legacy and deprecated tags are converted into their -// canonical equivalent. All other information is preserved. This approach makes -// the confidence scores more accurate and allows matchers to distinguish -// between variants that are otherwise lost. -// -// As a consequence, two tags that should be treated as identical according to -// BCP 47 or CLDR, like "en-Latn" and "en", will be represented differently. The -// Matcher handles such distinctions, though, and is aware of the -// equivalence relations. The CanonType type can be used to alter the -// canonicalization form. -// -// # References -// -// BCP 47 - Tags for Identifying Languages http://tools.ietf.org/html/bcp47 -package language // import "golang.org/x/text/language" - -// TODO: explanation on how to match languages for your own locale-specific -// service. diff --git a/vendor/golang.org/x/text/language/language.go b/vendor/golang.org/x/text/language/language.go deleted file mode 100644 index 4d9c66121..000000000 --- a/vendor/golang.org/x/text/language/language.go +++ /dev/null @@ -1,605 +0,0 @@ -// Copyright 2013 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 -output tables.go - -package language - -// TODO: Remove above NOTE after: -// - verifying that tables are dropped correctly (most notably matcher tables). - -import ( - "strings" - - "golang.org/x/text/internal/language" - "golang.org/x/text/internal/language/compact" -) - -// Tag represents a BCP 47 language tag. It is used to specify an instance of a -// specific language or locale. All language tag values are guaranteed to be -// well-formed. -type Tag compact.Tag - -func makeTag(t language.Tag) (tag Tag) { - return Tag(compact.Make(t)) -} - -func (t *Tag) tag() language.Tag { - return (*compact.Tag)(t).Tag() -} - -func (t *Tag) isCompact() bool { - return (*compact.Tag)(t).IsCompact() -} - -// TODO: improve performance. -func (t *Tag) lang() language.Language { return t.tag().LangID } -func (t *Tag) region() language.Region { return t.tag().RegionID } -func (t *Tag) script() language.Script { return t.tag().ScriptID } - -// Make is a convenience wrapper for Parse that omits the error. -// In case of an error, a sensible default is returned. -func Make(s string) Tag { - return Default.Make(s) -} - -// Make is a convenience wrapper for c.Parse that omits the error. -// In case of an error, a sensible default is returned. -func (c CanonType) Make(s string) Tag { - t, _ := c.Parse(s) - return t -} - -// Raw returns the raw base language, script and region, without making an -// attempt to infer their values. -func (t Tag) Raw() (b Base, s Script, r Region) { - tt := t.tag() - return Base{tt.LangID}, Script{tt.ScriptID}, Region{tt.RegionID} -} - -// IsRoot returns true if t is equal to language "und". -func (t Tag) IsRoot() bool { - return compact.Tag(t).IsRoot() -} - -// CanonType can be used to enable or disable various types of canonicalization. -type CanonType int - -const ( - // Replace deprecated base languages with their preferred replacements. - DeprecatedBase CanonType = 1 << iota - // Replace deprecated scripts with their preferred replacements. - DeprecatedScript - // Replace deprecated regions with their preferred replacements. - DeprecatedRegion - // Remove redundant scripts. - SuppressScript - // Normalize legacy encodings. This includes legacy languages defined in - // CLDR as well as bibliographic codes defined in ISO-639. - Legacy - // Map the dominant language of a macro language group to the macro language - // subtag. For example cmn -> zh. - Macro - // The CLDR flag should be used if full compatibility with CLDR is required. - // There are a few cases where language.Tag may differ from CLDR. To follow all - // of CLDR's suggestions, use All|CLDR. - CLDR - - // Raw can be used to Compose or Parse without Canonicalization. - Raw CanonType = 0 - - // Replace all deprecated tags with their preferred replacements. - Deprecated = DeprecatedBase | DeprecatedScript | DeprecatedRegion - - // All canonicalizations recommended by BCP 47. - BCP47 = Deprecated | SuppressScript - - // All canonicalizations. - All = BCP47 | Legacy | Macro - - // Default is the canonicalization used by Parse, Make and Compose. To - // preserve as much information as possible, canonicalizations that remove - // potentially valuable information are not included. The Matcher is - // designed to recognize similar tags that would be the same if - // they were canonicalized using All. - Default = Deprecated | Legacy - - canonLang = DeprecatedBase | Legacy | Macro - - // TODO: LikelyScript, LikelyRegion: suppress similar to ICU. -) - -// canonicalize returns the canonicalized equivalent of the tag and -// whether there was any change. -func canonicalize(c CanonType, t language.Tag) (language.Tag, bool) { - if c == Raw { - return t, false - } - changed := false - if c&SuppressScript != 0 { - if t.LangID.SuppressScript() == t.ScriptID { - t.ScriptID = 0 - changed = true - } - } - if c&canonLang != 0 { - for { - if l, aliasType := t.LangID.Canonicalize(); l != t.LangID { - switch aliasType { - case language.Legacy: - if c&Legacy != 0 { - if t.LangID == _sh && t.ScriptID == 0 { - t.ScriptID = _Latn - } - t.LangID = l - changed = true - } - case language.Macro: - if c&Macro != 0 { - // We deviate here from CLDR. The mapping "nb" -> "no" - // qualifies as a typical Macro language mapping. However, - // for legacy reasons, CLDR maps "no", the macro language - // code for Norwegian, to the dominant variant "nb". This - // change is currently under consideration for CLDR as well. - // See https://unicode.org/cldr/trac/ticket/2698 and also - // https://unicode.org/cldr/trac/ticket/1790 for some of the - // practical implications. TODO: this check could be removed - // if CLDR adopts this change. - if c&CLDR == 0 || t.LangID != _nb { - changed = true - t.LangID = l - } - } - case language.Deprecated: - if c&DeprecatedBase != 0 { - if t.LangID == _mo && t.RegionID == 0 { - t.RegionID = _MD - } - t.LangID = l - changed = true - // Other canonicalization types may still apply. - continue - } - } - } else if c&Legacy != 0 && t.LangID == _no && c&CLDR != 0 { - t.LangID = _nb - changed = true - } - break - } - } - if c&DeprecatedScript != 0 { - if t.ScriptID == _Qaai { - changed = true - t.ScriptID = _Zinh - } - } - if c&DeprecatedRegion != 0 { - if r := t.RegionID.Canonicalize(); r != t.RegionID { - changed = true - t.RegionID = r - } - } - return t, changed -} - -// Canonicalize returns the canonicalized equivalent of the tag. -func (c CanonType) Canonicalize(t Tag) (Tag, error) { - // First try fast path. - if t.isCompact() { - if _, changed := canonicalize(c, compact.Tag(t).Tag()); !changed { - return t, nil - } - } - // It is unlikely that one will canonicalize a tag after matching. So do - // a slow but simple approach here. - if tag, changed := canonicalize(c, t.tag()); changed { - tag.RemakeString() - return makeTag(tag), nil - } - return t, nil - -} - -// Confidence indicates the level of certainty for a given return value. -// For example, Serbian may be written in Cyrillic or Latin script. -// The confidence level indicates whether a value was explicitly specified, -// whether it is typically the only possible value, or whether there is -// an ambiguity. -type Confidence int - -const ( - No Confidence = iota // full confidence that there was no match - Low // most likely value picked out of a set of alternatives - High // value is generally assumed to be the correct match - Exact // exact match or explicitly specified value -) - -var confName = []string{"No", "Low", "High", "Exact"} - -func (c Confidence) String() string { - return confName[c] -} - -// String returns the canonical string representation of the language tag. -func (t Tag) String() string { - return t.tag().String() -} - -// MarshalText implements encoding.TextMarshaler. -func (t Tag) MarshalText() (text []byte, err error) { - return t.tag().MarshalText() -} - -// UnmarshalText implements encoding.TextUnmarshaler. -func (t *Tag) UnmarshalText(text []byte) error { - var tag language.Tag - err := tag.UnmarshalText(text) - *t = makeTag(tag) - return err -} - -// Base returns the base language of the language tag. If the base language is -// unspecified, an attempt will be made to infer it from the context. -// It uses a variant of CLDR's Add Likely Subtags algorithm. This is subject to change. -func (t Tag) Base() (Base, Confidence) { - if b := t.lang(); b != 0 { - return Base{b}, Exact - } - tt := t.tag() - c := High - if tt.ScriptID == 0 && !tt.RegionID.IsCountry() { - c = Low - } - if tag, err := tt.Maximize(); err == nil && tag.LangID != 0 { - return Base{tag.LangID}, c - } - return Base{0}, No -} - -// Script infers the script for the language tag. If it was not explicitly given, it will infer -// a most likely candidate. -// If more than one script is commonly used for a language, the most likely one -// is returned with a low confidence indication. For example, it returns (Cyrl, Low) -// for Serbian. -// If a script cannot be inferred (Zzzz, No) is returned. We do not use Zyyy (undetermined) -// as one would suspect from the IANA registry for BCP 47. In a Unicode context Zyyy marks -// common characters (like 1, 2, 3, '.', etc.) and is therefore more like multiple scripts. -// See https://www.unicode.org/reports/tr24/#Values for more details. Zzzz is also used for -// unknown value in CLDR. (Zzzz, Exact) is returned if Zzzz was explicitly specified. -// Note that an inferred script is never guaranteed to be the correct one. Latin is -// almost exclusively used for Afrikaans, but Arabic has been used for some texts -// in the past. Also, the script that is commonly used may change over time. -// It uses a variant of CLDR's Add Likely Subtags algorithm. This is subject to change. -func (t Tag) Script() (Script, Confidence) { - if scr := t.script(); scr != 0 { - return Script{scr}, Exact - } - tt := t.tag() - sc, c := language.Script(_Zzzz), No - if scr := tt.LangID.SuppressScript(); scr != 0 { - // Note: it is not always the case that a language with a suppress - // script value is only written in one script (e.g. kk, ms, pa). - if tt.RegionID == 0 { - return Script{scr}, High - } - sc, c = scr, High - } - if tag, err := tt.Maximize(); err == nil { - if tag.ScriptID != sc { - sc, c = tag.ScriptID, Low - } - } else { - tt, _ = canonicalize(Deprecated|Macro, tt) - if tag, err := tt.Maximize(); err == nil && tag.ScriptID != sc { - sc, c = tag.ScriptID, Low - } - } - return Script{sc}, c -} - -// Region returns the region for the language tag. If it was not explicitly given, it will -// infer a most likely candidate from the context. -// It uses a variant of CLDR's Add Likely Subtags algorithm. This is subject to change. -func (t Tag) Region() (Region, Confidence) { - if r := t.region(); r != 0 { - return Region{r}, Exact - } - tt := t.tag() - if tt, err := tt.Maximize(); err == nil { - return Region{tt.RegionID}, Low // TODO: differentiate between high and low. - } - tt, _ = canonicalize(Deprecated|Macro, tt) - if tag, err := tt.Maximize(); err == nil { - return Region{tag.RegionID}, Low - } - return Region{_ZZ}, No // TODO: return world instead of undetermined? -} - -// Variants returns the variants specified explicitly for this language tag. -// or nil if no variant was specified. -func (t Tag) Variants() []Variant { - if !compact.Tag(t).MayHaveVariants() { - return nil - } - v := []Variant{} - x, str := "", t.tag().Variants() - for str != "" { - x, str = nextToken(str) - v = append(v, Variant{x}) - } - return v -} - -// Parent returns the CLDR parent of t. In CLDR, missing fields in data for a -// specific language are substituted with fields from the parent language. -// The parent for a language may change for newer versions of CLDR. -// -// Parent returns a tag for a less specific language that is mutually -// intelligible or Und if there is no such language. This may not be the same as -// simply stripping the last BCP 47 subtag. For instance, the parent of "zh-TW" -// is "zh-Hant", and the parent of "zh-Hant" is "und". -func (t Tag) Parent() Tag { - return Tag(compact.Tag(t).Parent()) -} - -// nextToken returns token t and the rest of the string. -func nextToken(s string) (t, tail string) { - p := strings.Index(s[1:], "-") - if p == -1 { - return s[1:], "" - } - p++ - return s[1:p], s[p:] -} - -// Extension is a single BCP 47 extension. -type Extension struct { - s string -} - -// String returns the string representation of the extension, including the -// type tag. -func (e Extension) String() string { - return e.s -} - -// ParseExtension parses s as an extension and returns it on success. -func ParseExtension(s string) (e Extension, err error) { - ext, err := language.ParseExtension(s) - return Extension{ext}, err -} - -// Type returns the one-byte extension type of e. It returns 0 for the zero -// exception. -func (e Extension) Type() byte { - if e.s == "" { - return 0 - } - return e.s[0] -} - -// Tokens returns the list of tokens of e. -func (e Extension) Tokens() []string { - return strings.Split(e.s, "-") -} - -// Extension returns the extension of type x for tag t. It will return -// false for ok if t does not have the requested extension. The returned -// extension will be invalid in this case. -func (t Tag) Extension(x byte) (ext Extension, ok bool) { - if !compact.Tag(t).MayHaveExtensions() { - return Extension{}, false - } - e, ok := t.tag().Extension(x) - return Extension{e}, ok -} - -// Extensions returns all extensions of t. -func (t Tag) Extensions() []Extension { - if !compact.Tag(t).MayHaveExtensions() { - return nil - } - e := []Extension{} - for _, ext := range t.tag().Extensions() { - e = append(e, Extension{ext}) - } - return e -} - -// TypeForKey returns the type associated with the given key, where key and type -// are of the allowed values defined for the Unicode locale extension ('u') in -// https://www.unicode.org/reports/tr35/#Unicode_Language_and_Locale_Identifiers. -// TypeForKey will traverse the inheritance chain to get the correct value. -// -// If there are multiple types associated with a key, only the first will be -// returned. If there is no type associated with a key, it returns the empty -// string. -func (t Tag) TypeForKey(key string) string { - if !compact.Tag(t).MayHaveExtensions() { - if key != "rg" && key != "va" { - return "" - } - } - return t.tag().TypeForKey(key) -} - -// SetTypeForKey returns a new Tag with the key set to type, where key and type -// are of the allowed values defined for the Unicode locale extension ('u') in -// https://www.unicode.org/reports/tr35/#Unicode_Language_and_Locale_Identifiers. -// An empty value removes an existing pair with the same key. -func (t Tag) SetTypeForKey(key, value string) (Tag, error) { - tt, err := t.tag().SetTypeForKey(key, value) - return makeTag(tt), err -} - -// NumCompactTags is the number of compact tags. The maximum tag is -// NumCompactTags-1. -const NumCompactTags = compact.NumCompactTags - -// CompactIndex returns an index, where 0 <= index < NumCompactTags, for tags -// for which data exists in the text repository.The index will change over time -// and should not be stored in persistent storage. If t does not match a compact -// index, exact will be false and the compact index will be returned for the -// first match after repeatedly taking the Parent of t. -func CompactIndex(t Tag) (index int, exact bool) { - id, exact := compact.LanguageID(compact.Tag(t)) - return int(id), exact -} - -var root = language.Tag{} - -// Base is an ISO 639 language code, used for encoding the base language -// of a language tag. -type Base struct { - langID language.Language -} - -// ParseBase parses a 2- or 3-letter ISO 639 code. -// It returns a ValueError if s is a well-formed but unknown language identifier -// or another error if another error occurred. -func ParseBase(s string) (Base, error) { - l, err := language.ParseBase(s) - return Base{l}, err -} - -// String returns the BCP 47 representation of the base language. -func (b Base) String() string { - return b.langID.String() -} - -// ISO3 returns the ISO 639-3 language code. -func (b Base) ISO3() string { - return b.langID.ISO3() -} - -// IsPrivateUse reports whether this language code is reserved for private use. -func (b Base) IsPrivateUse() bool { - return b.langID.IsPrivateUse() -} - -// Script is a 4-letter ISO 15924 code for representing scripts. -// It is idiomatically represented in title case. -type Script struct { - scriptID language.Script -} - -// ParseScript parses a 4-letter ISO 15924 code. -// It returns a ValueError if s is a well-formed but unknown script identifier -// or another error if another error occurred. -func ParseScript(s string) (Script, error) { - sc, err := language.ParseScript(s) - return Script{sc}, err -} - -// String returns the script code in title case. -// It returns "Zzzz" for an unspecified script. -func (s Script) String() string { - return s.scriptID.String() -} - -// IsPrivateUse reports whether this script code is reserved for private use. -func (s Script) IsPrivateUse() bool { - return s.scriptID.IsPrivateUse() -} - -// Region is an ISO 3166-1 or UN M.49 code for representing countries and regions. -type Region struct { - regionID language.Region -} - -// EncodeM49 returns the Region for the given UN M.49 code. -// It returns an error if r is not a valid code. -func EncodeM49(r int) (Region, error) { - rid, err := language.EncodeM49(r) - return Region{rid}, err -} - -// ParseRegion parses a 2- or 3-letter ISO 3166-1 or a UN M.49 code. -// It returns a ValueError if s is a well-formed but unknown region identifier -// or another error if another error occurred. -func ParseRegion(s string) (Region, error) { - r, err := language.ParseRegion(s) - return Region{r}, err -} - -// String returns the BCP 47 representation for the region. -// It returns "ZZ" for an unspecified region. -func (r Region) String() string { - return r.regionID.String() -} - -// ISO3 returns the 3-letter ISO code of r. -// Note that not all regions have a 3-letter ISO code. -// In such cases this method returns "ZZZ". -func (r Region) ISO3() string { - return r.regionID.ISO3() -} - -// M49 returns the UN M.49 encoding of r, or 0 if this encoding -// is not defined for r. -func (r Region) M49() int { - return r.regionID.M49() -} - -// IsPrivateUse reports whether r has the ISO 3166 User-assigned status. This -// may include private-use tags that are assigned by CLDR and used in this -// implementation. So IsPrivateUse and IsCountry can be simultaneously true. -func (r Region) IsPrivateUse() bool { - return r.regionID.IsPrivateUse() -} - -// IsCountry returns whether this region is a country or autonomous area. This -// includes non-standard definitions from CLDR. -func (r Region) IsCountry() bool { - return r.regionID.IsCountry() -} - -// IsGroup returns whether this region defines a collection of regions. This -// includes non-standard definitions from CLDR. -func (r Region) IsGroup() bool { - return r.regionID.IsGroup() -} - -// Contains returns whether Region c is contained by Region r. It returns true -// if c == r. -func (r Region) Contains(c Region) bool { - return r.regionID.Contains(c.regionID) -} - -// TLD returns the country code top-level domain (ccTLD). UK is returned for GB. -// In all other cases it returns either the region itself or an error. -// -// This method may return an error for a region for which there exists a -// canonical form with a ccTLD. To get that ccTLD canonicalize r first. The -// region will already be canonicalized it was obtained from a Tag that was -// obtained using any of the default methods. -func (r Region) TLD() (Region, error) { - tld, err := r.regionID.TLD() - return Region{tld}, err -} - -// Canonicalize returns the region or a possible replacement if the region is -// deprecated. It will not return a replacement for deprecated regions that -// are split into multiple regions. -func (r Region) Canonicalize() Region { - return Region{r.regionID.Canonicalize()} -} - -// Variant represents a registered variant of a language as defined by BCP 47. -type Variant struct { - variant string -} - -// ParseVariant parses and returns a Variant. An error is returned if s is not -// a valid variant. -func ParseVariant(s string) (Variant, error) { - v, err := language.ParseVariant(s) - return Variant{v.String()}, err -} - -// String returns the string representation of the variant. -func (v Variant) String() string { - return v.variant -} diff --git a/vendor/golang.org/x/text/language/match.go b/vendor/golang.org/x/text/language/match.go deleted file mode 100644 index 1153baf29..000000000 --- a/vendor/golang.org/x/text/language/match.go +++ /dev/null @@ -1,735 +0,0 @@ -// Copyright 2013 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 language - -import ( - "errors" - "strings" - - "golang.org/x/text/internal/language" -) - -// A MatchOption configures a Matcher. -type MatchOption func(*matcher) - -// PreferSameScript will, in the absence of a match, result in the first -// preferred tag with the same script as a supported tag to match this supported -// tag. The default is currently true, but this may change in the future. -func PreferSameScript(preferSame bool) MatchOption { - return func(m *matcher) { m.preferSameScript = preferSame } -} - -// TODO(v1.0.0): consider making Matcher a concrete type, instead of interface. -// There doesn't seem to be too much need for multiple types. -// Making it a concrete type allows MatchStrings to be a method, which will -// improve its discoverability. - -// MatchStrings parses and matches the given strings until one of them matches -// the language in the Matcher. A string may be an Accept-Language header as -// handled by ParseAcceptLanguage. The default language is returned if no -// other language matched. -func MatchStrings(m Matcher, lang ...string) (tag Tag, index int) { - for _, accept := range lang { - desired, _, err := ParseAcceptLanguage(accept) - if err != nil { - continue - } - if tag, index, conf := m.Match(desired...); conf != No { - return tag, index - } - } - tag, index, _ = m.Match() - return -} - -// Matcher is the interface that wraps the Match method. -// -// Match returns the best match for any of the given tags, along with -// a unique index associated with the returned tag and a confidence -// score. -type Matcher interface { - Match(t ...Tag) (tag Tag, index int, c Confidence) -} - -// Comprehends reports the confidence score for a speaker of a given language -// to being able to comprehend the written form of an alternative language. -func Comprehends(speaker, alternative Tag) Confidence { - _, _, c := NewMatcher([]Tag{alternative}).Match(speaker) - return c -} - -// NewMatcher returns a Matcher that matches an ordered list of preferred tags -// against a list of supported tags based on written intelligibility, closeness -// of dialect, equivalence of subtags and various other rules. It is initialized -// with the list of supported tags. The first element is used as the default -// value in case no match is found. -// -// Its Match method matches the first of the given Tags to reach a certain -// confidence threshold. The tags passed to Match should therefore be specified -// in order of preference. Extensions are ignored for matching. -// -// The index returned by the Match method corresponds to the index of the -// matched tag in t, but is augmented with the Unicode extension ('u')of the -// corresponding preferred tag. This allows user locale options to be passed -// transparently. -func NewMatcher(t []Tag, options ...MatchOption) Matcher { - return newMatcher(t, options) -} - -func (m *matcher) Match(want ...Tag) (t Tag, index int, c Confidence) { - var tt language.Tag - match, w, c := m.getBest(want...) - if match != nil { - tt, index = match.tag, match.index - } else { - // TODO: this should be an option - tt = m.default_.tag - if m.preferSameScript { - outer: - for _, w := range want { - script, _ := w.Script() - if script.scriptID == 0 { - // Don't do anything if there is no script, such as with - // private subtags. - continue - } - for i, h := range m.supported { - if script.scriptID == h.maxScript { - tt, index = h.tag, i - break outer - } - } - } - } - // TODO: select first language tag based on script. - } - if w.RegionID != tt.RegionID && w.RegionID != 0 { - if w.RegionID != 0 && tt.RegionID != 0 && tt.RegionID.Contains(w.RegionID) { - tt.RegionID = w.RegionID - tt.RemakeString() - } else if r := w.RegionID.String(); len(r) == 2 { - // TODO: also filter macro and deprecated. - tt, _ = tt.SetTypeForKey("rg", strings.ToLower(r)+"zzzz") - } - } - // Copy options from the user-provided tag into the result tag. This is hard - // to do after the fact, so we do it here. - // TODO: add in alternative variants to -u-va-. - // TODO: add preferred region to -u-rg-. - if e := w.Extensions(); len(e) > 0 { - b := language.Builder{} - b.SetTag(tt) - for _, e := range e { - b.AddExt(e) - } - tt = b.Make() - } - return makeTag(tt), index, c -} - -// ErrMissingLikelyTagsData indicates no information was available -// to compute likely values of missing tags. -var ErrMissingLikelyTagsData = errors.New("missing likely tags data") - -// func (t *Tag) setTagsFrom(id Tag) { -// t.LangID = id.LangID -// t.ScriptID = id.ScriptID -// t.RegionID = id.RegionID -// } - -// Tag Matching -// CLDR defines an algorithm for finding the best match between two sets of language -// tags. The basic algorithm defines how to score a possible match and then find -// the match with the best score -// (see https://www.unicode.org/reports/tr35/#LanguageMatching). -// Using scoring has several disadvantages. The scoring obfuscates the importance of -// the various factors considered, making the algorithm harder to understand. Using -// scoring also requires the full score to be computed for each pair of tags. -// -// We will use a different algorithm which aims to have the following properties: -// - clarity on the precedence of the various selection factors, and -// - improved performance by allowing early termination of a comparison. -// -// Matching algorithm (overview) -// Input: -// - supported: a set of supported tags -// - default: the default tag to return in case there is no match -// - desired: list of desired tags, ordered by preference, starting with -// the most-preferred. -// -// Algorithm: -// 1) Set the best match to the lowest confidence level -// 2) For each tag in "desired": -// a) For each tag in "supported": -// 1) compute the match between the two tags. -// 2) if the match is better than the previous best match, replace it -// with the new match. (see next section) -// b) if the current best match is Exact and pin is true the result will be -// frozen to the language found thusfar, although better matches may -// still be found for the same language. -// 3) If the best match so far is below a certain threshold, return "default". -// -// Ranking: -// We use two phases to determine whether one pair of tags are a better match -// than another pair of tags. First, we determine a rough confidence level. If the -// levels are different, the one with the highest confidence wins. -// Second, if the rough confidence levels are identical, we use a set of tie-breaker -// rules. -// -// The confidence level of matching a pair of tags is determined by finding the -// lowest confidence level of any matches of the corresponding subtags (the -// result is deemed as good as its weakest link). -// We define the following levels: -// Exact - An exact match of a subtag, before adding likely subtags. -// MaxExact - An exact match of a subtag, after adding likely subtags. -// [See Note 2]. -// High - High level of mutual intelligibility between different subtag -// variants. -// Low - Low level of mutual intelligibility between different subtag -// variants. -// No - No mutual intelligibility. -// -// The following levels can occur for each type of subtag: -// Base: Exact, MaxExact, High, Low, No -// Script: Exact, MaxExact [see Note 3], Low, No -// Region: Exact, MaxExact, High -// Variant: Exact, High -// Private: Exact, No -// -// Any result with a confidence level of Low or higher is deemed a possible match. -// Once a desired tag matches any of the supported tags with a level of MaxExact -// or higher, the next desired tag is not considered (see Step 2.b). -// Note that CLDR provides languageMatching data that defines close equivalence -// classes for base languages, scripts and regions. -// -// Tie-breaking -// If we get the same confidence level for two matches, we apply a sequence of -// tie-breaking rules. The first that succeeds defines the result. The rules are -// applied in the following order. -// 1) Original language was defined and was identical. -// 2) Original region was defined and was identical. -// 3) Distance between two maximized regions was the smallest. -// 4) Original script was defined and was identical. -// 5) Distance from want tag to have tag using the parent relation [see Note 5.] -// If there is still no winner after these rules are applied, the first match -// found wins. -// -// Notes: -// [2] In practice, as matching of Exact is done in a separate phase from -// matching the other levels, we reuse the Exact level to mean MaxExact in -// the second phase. As a consequence, we only need the levels defined by -// the Confidence type. The MaxExact confidence level is mapped to High in -// the public API. -// [3] We do not differentiate between maximized script values that were derived -// from suppressScript versus most likely tag data. We determined that in -// ranking the two, one ranks just after the other. Moreover, the two cannot -// occur concurrently. As a consequence, they are identical for practical -// purposes. -// [4] In case of deprecated, macro-equivalents and legacy mappings, we assign -// the MaxExact level to allow iw vs he to still be a closer match than -// en-AU vs en-US, for example. -// [5] In CLDR a locale inherits fields that are unspecified for this locale -// from its parent. Therefore, if a locale is a parent of another locale, -// it is a strong measure for closeness, especially when no other tie -// breaker rule applies. One could also argue it is inconsistent, for -// example, when pt-AO matches pt (which CLDR equates with pt-BR), even -// though its parent is pt-PT according to the inheritance rules. -// -// Implementation Details: -// There are several performance considerations worth pointing out. Most notably, -// we preprocess as much as possible (within reason) at the time of creation of a -// matcher. This includes: -// - creating a per-language map, which includes data for the raw base language -// and its canonicalized variant (if applicable), -// - expanding entries for the equivalence classes defined in CLDR's -// languageMatch data. -// The per-language map ensures that typically only a very small number of tags -// need to be considered. The pre-expansion of canonicalized subtags and -// equivalence classes reduces the amount of map lookups that need to be done at -// runtime. - -// matcher keeps a set of supported language tags, indexed by language. -type matcher struct { - default_ *haveTag - supported []*haveTag - index map[language.Language]*matchHeader - passSettings bool - preferSameScript bool -} - -// matchHeader has the lists of tags for exact matches and matches based on -// maximized and canonicalized tags for a given language. -type matchHeader struct { - haveTags []*haveTag - original bool -} - -// haveTag holds a supported Tag and its maximized script and region. The maximized -// or canonicalized language is not stored as it is not needed during matching. -type haveTag struct { - tag language.Tag - - // index of this tag in the original list of supported tags. - index int - - // conf is the maximum confidence that can result from matching this haveTag. - // When conf < Exact this means it was inserted after applying a CLDR equivalence rule. - conf Confidence - - // Maximized region and script. - maxRegion language.Region - maxScript language.Script - - // altScript may be checked as an alternative match to maxScript. If altScript - // matches, the confidence level for this match is Low. Theoretically there - // could be multiple alternative scripts. This does not occur in practice. - altScript language.Script - - // nextMax is the index of the next haveTag with the same maximized tags. - nextMax uint16 -} - -func makeHaveTag(tag language.Tag, index int) (haveTag, language.Language) { - max := tag - if tag.LangID != 0 || tag.RegionID != 0 || tag.ScriptID != 0 { - max, _ = canonicalize(All, max) - max, _ = max.Maximize() - max.RemakeString() - } - return haveTag{tag, index, Exact, max.RegionID, max.ScriptID, altScript(max.LangID, max.ScriptID), 0}, max.LangID -} - -// altScript returns an alternative script that may match the given script with -// a low confidence. At the moment, the langMatch data allows for at most one -// script to map to another and we rely on this to keep the code simple. -func altScript(l language.Language, s language.Script) language.Script { - for _, alt := range matchScript { - // TODO: also match cases where language is not the same. - if (language.Language(alt.wantLang) == l || language.Language(alt.haveLang) == l) && - language.Script(alt.haveScript) == s { - return language.Script(alt.wantScript) - } - } - return 0 -} - -// addIfNew adds a haveTag to the list of tags only if it is a unique tag. -// Tags that have the same maximized values are linked by index. -func (h *matchHeader) addIfNew(n haveTag, exact bool) { - h.original = h.original || exact - // Don't add new exact matches. - for _, v := range h.haveTags { - if equalsRest(v.tag, n.tag) { - return - } - } - // Allow duplicate maximized tags, but create a linked list to allow quickly - // comparing the equivalents and bail out. - for i, v := range h.haveTags { - if v.maxScript == n.maxScript && - v.maxRegion == n.maxRegion && - v.tag.VariantOrPrivateUseTags() == n.tag.VariantOrPrivateUseTags() { - for h.haveTags[i].nextMax != 0 { - i = int(h.haveTags[i].nextMax) - } - h.haveTags[i].nextMax = uint16(len(h.haveTags)) - break - } - } - h.haveTags = append(h.haveTags, &n) -} - -// header returns the matchHeader for the given language. It creates one if -// it doesn't already exist. -func (m *matcher) header(l language.Language) *matchHeader { - if h := m.index[l]; h != nil { - return h - } - h := &matchHeader{} - m.index[l] = h - return h -} - -func toConf(d uint8) Confidence { - if d <= 10 { - return High - } - if d < 30 { - return Low - } - return No -} - -// newMatcher builds an index for the given supported tags and returns it as -// a matcher. It also expands the index by considering various equivalence classes -// for a given tag. -func newMatcher(supported []Tag, options []MatchOption) *matcher { - m := &matcher{ - index: make(map[language.Language]*matchHeader), - preferSameScript: true, - } - for _, o := range options { - o(m) - } - if len(supported) == 0 { - m.default_ = &haveTag{} - return m - } - // Add supported languages to the index. Add exact matches first to give - // them precedence. - for i, tag := range supported { - tt := tag.tag() - pair, _ := makeHaveTag(tt, i) - m.header(tt.LangID).addIfNew(pair, true) - m.supported = append(m.supported, &pair) - } - m.default_ = m.header(supported[0].lang()).haveTags[0] - // Keep these in two different loops to support the case that two equivalent - // languages are distinguished, such as iw and he. - for i, tag := range supported { - tt := tag.tag() - pair, max := makeHaveTag(tt, i) - if max != tt.LangID { - m.header(max).addIfNew(pair, true) - } - } - - // update is used to add indexes in the map for equivalent languages. - // update will only add entries to original indexes, thus not computing any - // transitive relations. - update := func(want, have uint16, conf Confidence) { - if hh := m.index[language.Language(have)]; hh != nil { - if !hh.original { - return - } - hw := m.header(language.Language(want)) - for _, ht := range hh.haveTags { - v := *ht - if conf < v.conf { - v.conf = conf - } - v.nextMax = 0 // this value needs to be recomputed - if v.altScript != 0 { - v.altScript = altScript(language.Language(want), v.maxScript) - } - hw.addIfNew(v, conf == Exact && hh.original) - } - } - } - - // Add entries for languages with mutual intelligibility as defined by CLDR's - // languageMatch data. - for _, ml := range matchLang { - update(ml.want, ml.have, toConf(ml.distance)) - if !ml.oneway { - update(ml.have, ml.want, toConf(ml.distance)) - } - } - - // Add entries for possible canonicalizations. This is an optimization to - // ensure that only one map lookup needs to be done at runtime per desired tag. - // First we match deprecated equivalents. If they are perfect equivalents - // (their canonicalization simply substitutes a different language code, but - // nothing else), the match confidence is Exact, otherwise it is High. - for i, lm := range language.AliasMap { - // If deprecated codes match and there is no fiddling with the script - // or region, we consider it an exact match. - conf := Exact - if language.AliasTypes[i] != language.Macro { - if !isExactEquivalent(language.Language(lm.From)) { - conf = High - } - update(lm.To, lm.From, conf) - } - update(lm.From, lm.To, conf) - } - return m -} - -// getBest gets the best matching tag in m for any of the given tags, taking into -// account the order of preference of the given tags. -func (m *matcher) getBest(want ...Tag) (got *haveTag, orig language.Tag, c Confidence) { - best := bestMatch{} - for i, ww := range want { - w := ww.tag() - var max language.Tag - // Check for exact match first. - h := m.index[w.LangID] - if w.LangID != 0 { - if h == nil { - continue - } - // Base language is defined. - max, _ = canonicalize(Legacy|Deprecated|Macro, w) - // A region that is added through canonicalization is stronger than - // a maximized region: set it in the original (e.g. mo -> ro-MD). - if w.RegionID != max.RegionID { - w.RegionID = max.RegionID - } - // TODO: should we do the same for scripts? - // See test case: en, sr, nl ; sh ; sr - max, _ = max.Maximize() - } else { - // Base language is not defined. - if h != nil { - for i := range h.haveTags { - have := h.haveTags[i] - if equalsRest(have.tag, w) { - return have, w, Exact - } - } - } - if w.ScriptID == 0 && w.RegionID == 0 { - // We skip all tags matching und for approximate matching, including - // private tags. - continue - } - max, _ = w.Maximize() - if h = m.index[max.LangID]; h == nil { - continue - } - } - pin := true - for _, t := range want[i+1:] { - if w.LangID == t.lang() { - pin = false - break - } - } - // Check for match based on maximized tag. - for i := range h.haveTags { - have := h.haveTags[i] - best.update(have, w, max.ScriptID, max.RegionID, pin) - if best.conf == Exact { - for have.nextMax != 0 { - have = h.haveTags[have.nextMax] - best.update(have, w, max.ScriptID, max.RegionID, pin) - } - return best.have, best.want, best.conf - } - } - } - if best.conf <= No { - if len(want) != 0 { - return nil, want[0].tag(), No - } - return nil, language.Tag{}, No - } - return best.have, best.want, best.conf -} - -// bestMatch accumulates the best match so far. -type bestMatch struct { - have *haveTag - want language.Tag - conf Confidence - pinnedRegion language.Region - pinLanguage bool - sameRegionGroup bool - // Cached results from applying tie-breaking rules. - origLang bool - origReg bool - paradigmReg bool - regGroupDist uint8 - origScript bool -} - -// update updates the existing best match if the new pair is considered to be a -// better match. To determine if the given pair is a better match, it first -// computes the rough confidence level. If this surpasses the current match, it -// will replace it and update the tie-breaker rule cache. If there is a tie, it -// proceeds with applying a series of tie-breaker rules. If there is no -// conclusive winner after applying the tie-breaker rules, it leaves the current -// match as the preferred match. -// -// If pin is true and have and tag are a strong match, it will henceforth only -// consider matches for this language. This corresponds to the idea that most -// users have a strong preference for the first defined language. A user can -// still prefer a second language over a dialect of the preferred language by -// explicitly specifying dialects, e.g. "en, nl, en-GB". In this case pin should -// be false. -func (m *bestMatch) update(have *haveTag, tag language.Tag, maxScript language.Script, maxRegion language.Region, pin bool) { - // Bail if the maximum attainable confidence is below that of the current best match. - c := have.conf - if c < m.conf { - return - } - // Don't change the language once we already have found an exact match. - if m.pinLanguage && tag.LangID != m.want.LangID { - return - } - // Pin the region group if we are comparing tags for the same language. - if tag.LangID == m.want.LangID && m.sameRegionGroup { - _, sameGroup := regionGroupDist(m.pinnedRegion, have.maxRegion, have.maxScript, m.want.LangID) - if !sameGroup { - return - } - } - if c == Exact && have.maxScript == maxScript { - // If there is another language and then another entry of this language, - // don't pin anything, otherwise pin the language. - m.pinLanguage = pin - } - if equalsRest(have.tag, tag) { - } else if have.maxScript != maxScript { - // There is usually very little comprehension between different scripts. - // In a few cases there may still be Low comprehension. This possibility - // is pre-computed and stored in have.altScript. - if Low < m.conf || have.altScript != maxScript { - return - } - c = Low - } else if have.maxRegion != maxRegion { - if High < c { - // There is usually a small difference between languages across regions. - c = High - } - } - - // We store the results of the computations of the tie-breaker rules along - // with the best match. There is no need to do the checks once we determine - // we have a winner, but we do still need to do the tie-breaker computations. - // We use "beaten" to keep track if we still need to do the checks. - beaten := false // true if the new pair defeats the current one. - if c != m.conf { - if c < m.conf { - return - } - beaten = true - } - - // Tie-breaker rules: - // We prefer if the pre-maximized language was specified and identical. - origLang := have.tag.LangID == tag.LangID && tag.LangID != 0 - if !beaten && m.origLang != origLang { - if m.origLang { - return - } - beaten = true - } - - // We prefer if the pre-maximized region was specified and identical. - origReg := have.tag.RegionID == tag.RegionID && tag.RegionID != 0 - if !beaten && m.origReg != origReg { - if m.origReg { - return - } - beaten = true - } - - regGroupDist, sameGroup := regionGroupDist(have.maxRegion, maxRegion, maxScript, tag.LangID) - if !beaten && m.regGroupDist != regGroupDist { - if regGroupDist > m.regGroupDist { - return - } - beaten = true - } - - paradigmReg := isParadigmLocale(tag.LangID, have.maxRegion) - if !beaten && m.paradigmReg != paradigmReg { - if !paradigmReg { - return - } - beaten = true - } - - // Next we prefer if the pre-maximized script was specified and identical. - origScript := have.tag.ScriptID == tag.ScriptID && tag.ScriptID != 0 - if !beaten && m.origScript != origScript { - if m.origScript { - return - } - beaten = true - } - - // Update m to the newly found best match. - if beaten { - m.have = have - m.want = tag - m.conf = c - m.pinnedRegion = maxRegion - m.sameRegionGroup = sameGroup - m.origLang = origLang - m.origReg = origReg - m.paradigmReg = paradigmReg - m.origScript = origScript - m.regGroupDist = regGroupDist - } -} - -func isParadigmLocale(lang language.Language, r language.Region) bool { - for _, e := range paradigmLocales { - if language.Language(e[0]) == lang && (r == language.Region(e[1]) || r == language.Region(e[2])) { - return true - } - } - return false -} - -// regionGroupDist computes the distance between two regions based on their -// CLDR grouping. -func regionGroupDist(a, b language.Region, script language.Script, lang language.Language) (dist uint8, same bool) { - const defaultDistance = 4 - - aGroup := uint(regionToGroups[a]) << 1 - bGroup := uint(regionToGroups[b]) << 1 - for _, ri := range matchRegion { - if language.Language(ri.lang) == lang && (ri.script == 0 || language.Script(ri.script) == script) { - group := uint(1 << (ri.group &^ 0x80)) - if 0x80&ri.group == 0 { - if aGroup&bGroup&group != 0 { // Both regions are in the group. - return ri.distance, ri.distance == defaultDistance - } - } else { - if (aGroup|bGroup)&group == 0 { // Both regions are not in the group. - return ri.distance, ri.distance == defaultDistance - } - } - } - } - return defaultDistance, true -} - -// equalsRest compares everything except the language. -func equalsRest(a, b language.Tag) bool { - // TODO: don't include extensions in this comparison. To do this efficiently, - // though, we should handle private tags separately. - return a.ScriptID == b.ScriptID && a.RegionID == b.RegionID && a.VariantOrPrivateUseTags() == b.VariantOrPrivateUseTags() -} - -// isExactEquivalent returns true if canonicalizing the language will not alter -// the script or region of a tag. -func isExactEquivalent(l language.Language) bool { - for _, o := range notEquivalent { - if o == l { - return false - } - } - return true -} - -var notEquivalent []language.Language - -func init() { - // Create a list of all languages for which canonicalization may alter the - // script or region. - for _, lm := range language.AliasMap { - tag := language.Tag{LangID: language.Language(lm.From)} - if tag, _ = canonicalize(All, tag); tag.ScriptID != 0 || tag.RegionID != 0 { - notEquivalent = append(notEquivalent, language.Language(lm.From)) - } - } - // Maximize undefined regions of paradigm locales. - for i, v := range paradigmLocales { - t := language.Tag{LangID: language.Language(v[0])} - max, _ := t.Maximize() - if v[1] == 0 { - paradigmLocales[i][1] = uint16(max.RegionID) - } - if v[2] == 0 { - paradigmLocales[i][2] = uint16(max.RegionID) - } - } -} diff --git a/vendor/golang.org/x/text/language/parse.go b/vendor/golang.org/x/text/language/parse.go deleted file mode 100644 index 4d57222e7..000000000 --- a/vendor/golang.org/x/text/language/parse.go +++ /dev/null @@ -1,256 +0,0 @@ -// Copyright 2013 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 language - -import ( - "errors" - "sort" - "strconv" - "strings" - - "golang.org/x/text/internal/language" -) - -// ValueError is returned by any of the parsing functions when the -// input is well-formed but the respective subtag is not recognized -// as a valid value. -type ValueError interface { - error - - // Subtag returns the subtag for which the error occurred. - Subtag() string -} - -// Parse parses the given BCP 47 string and returns a valid Tag. If parsing -// failed it returns an error and any part of the tag that could be parsed. -// If parsing succeeded but an unknown value was found, it returns -// ValueError. The Tag returned in this case is just stripped of the unknown -// value. All other values are preserved. It accepts tags in the BCP 47 format -// and extensions to this standard defined in -// https://www.unicode.org/reports/tr35/#Unicode_Language_and_Locale_Identifiers. -// The resulting tag is canonicalized using the default canonicalization type. -func Parse(s string) (t Tag, err error) { - return Default.Parse(s) -} - -// Parse parses the given BCP 47 string and returns a valid Tag. If parsing -// failed it returns an error and any part of the tag that could be parsed. -// If parsing succeeded but an unknown value was found, it returns -// ValueError. The Tag returned in this case is just stripped of the unknown -// value. All other values are preserved. It accepts tags in the BCP 47 format -// and extensions to this standard defined in -// https://www.unicode.org/reports/tr35/#Unicode_Language_and_Locale_Identifiers. -// The resulting tag is canonicalized using the canonicalization type c. -func (c CanonType) Parse(s string) (t Tag, err error) { - defer func() { - if recover() != nil { - t = Tag{} - err = language.ErrSyntax - } - }() - - tt, err := language.Parse(s) - if err != nil { - return makeTag(tt), err - } - tt, changed := canonicalize(c, tt) - if changed { - tt.RemakeString() - } - return makeTag(tt), err -} - -// Compose creates a Tag from individual parts, which may be of type Tag, Base, -// Script, Region, Variant, []Variant, Extension, []Extension or error. If a -// Base, Script or Region or slice of type Variant or Extension is passed more -// than once, the latter will overwrite the former. Variants and Extensions are -// accumulated, but if two extensions of the same type are passed, the latter -// will replace the former. For -u extensions, though, the key-type pairs are -// added, where later values overwrite older ones. A Tag overwrites all former -// values and typically only makes sense as the first argument. The resulting -// tag is returned after canonicalizing using the Default CanonType. If one or -// more errors are encountered, one of the errors is returned. -func Compose(part ...interface{}) (t Tag, err error) { - return Default.Compose(part...) -} - -// Compose creates a Tag from individual parts, which may be of type Tag, Base, -// Script, Region, Variant, []Variant, Extension, []Extension or error. If a -// Base, Script or Region or slice of type Variant or Extension is passed more -// than once, the latter will overwrite the former. Variants and Extensions are -// accumulated, but if two extensions of the same type are passed, the latter -// will replace the former. For -u extensions, though, the key-type pairs are -// added, where later values overwrite older ones. A Tag overwrites all former -// values and typically only makes sense as the first argument. The resulting -// tag is returned after canonicalizing using CanonType c. If one or more errors -// are encountered, one of the errors is returned. -func (c CanonType) Compose(part ...interface{}) (t Tag, err error) { - defer func() { - if recover() != nil { - t = Tag{} - err = language.ErrSyntax - } - }() - - var b language.Builder - if err = update(&b, part...); err != nil { - return und, err - } - b.Tag, _ = canonicalize(c, b.Tag) - return makeTag(b.Make()), err -} - -var errInvalidArgument = errors.New("invalid Extension or Variant") - -func update(b *language.Builder, part ...interface{}) (err error) { - for _, x := range part { - switch v := x.(type) { - case Tag: - b.SetTag(v.tag()) - case Base: - b.Tag.LangID = v.langID - case Script: - b.Tag.ScriptID = v.scriptID - case Region: - b.Tag.RegionID = v.regionID - case Variant: - if v.variant == "" { - err = errInvalidArgument - break - } - b.AddVariant(v.variant) - case Extension: - if v.s == "" { - err = errInvalidArgument - break - } - b.SetExt(v.s) - case []Variant: - b.ClearVariants() - for _, v := range v { - b.AddVariant(v.variant) - } - case []Extension: - b.ClearExtensions() - for _, e := range v { - b.SetExt(e.s) - } - // TODO: support parsing of raw strings based on morphology or just extensions? - case error: - if v != nil { - err = v - } - } - } - return -} - -var errInvalidWeight = errors.New("ParseAcceptLanguage: invalid weight") -var errTagListTooLarge = errors.New("tag list exceeds max length") - -// ParseAcceptLanguage parses the contents of an Accept-Language header as -// defined in http://www.ietf.org/rfc/rfc2616.txt and returns a list of Tags and -// a list of corresponding quality weights. It is more permissive than RFC 2616 -// and may return non-nil slices even if the input is not valid. -// The Tags will be sorted by highest weight first and then by first occurrence. -// Tags with a weight of zero will be dropped. An error will be returned if the -// input could not be parsed. -func ParseAcceptLanguage(s string) (tag []Tag, q []float32, err error) { - defer func() { - if recover() != nil { - tag = nil - q = nil - err = language.ErrSyntax - } - }() - - if strings.Count(s, "-") > 1000 { - return nil, nil, errTagListTooLarge - } - - var entry string - for s != "" { - if entry, s = split(s, ','); entry == "" { - continue - } - - entry, weight := split(entry, ';') - - // Scan the language. - t, err := Parse(entry) - if err != nil { - id, ok := acceptFallback[entry] - if !ok { - return nil, nil, err - } - t = makeTag(language.Tag{LangID: id}) - } - - // Scan the optional weight. - w := 1.0 - if weight != "" { - weight = consume(weight, 'q') - weight = consume(weight, '=') - // consume returns the empty string when a token could not be - // consumed, resulting in an error for ParseFloat. - if w, err = strconv.ParseFloat(weight, 32); err != nil { - return nil, nil, errInvalidWeight - } - // Drop tags with a quality weight of 0. - if w <= 0 { - continue - } - } - - tag = append(tag, t) - q = append(q, float32(w)) - } - sort.Stable(&tagSort{tag, q}) - return tag, q, nil -} - -// consume removes a leading token c from s and returns the result or the empty -// string if there is no such token. -func consume(s string, c byte) string { - if s == "" || s[0] != c { - return "" - } - return strings.TrimSpace(s[1:]) -} - -func split(s string, c byte) (head, tail string) { - if i := strings.IndexByte(s, c); i >= 0 { - return strings.TrimSpace(s[:i]), strings.TrimSpace(s[i+1:]) - } - return strings.TrimSpace(s), "" -} - -// Add hack mapping to deal with a small number of cases that occur -// in Accept-Language (with reasonable frequency). -var acceptFallback = map[string]language.Language{ - "english": _en, - "deutsch": _de, - "italian": _it, - "french": _fr, - "*": _mul, // defined in the spec to match all languages. -} - -type tagSort struct { - tag []Tag - q []float32 -} - -func (s *tagSort) Len() int { - return len(s.q) -} - -func (s *tagSort) Less(i, j int) bool { - return s.q[i] > s.q[j] -} - -func (s *tagSort) Swap(i, j int) { - s.tag[i], s.tag[j] = s.tag[j], s.tag[i] - s.q[i], s.q[j] = s.q[j], s.q[i] -} diff --git a/vendor/golang.org/x/text/language/tables.go b/vendor/golang.org/x/text/language/tables.go deleted file mode 100644 index a6573dcb2..000000000 --- a/vendor/golang.org/x/text/language/tables.go +++ /dev/null @@ -1,298 +0,0 @@ -// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. - -package language - -// CLDRVersion is the CLDR version from which the tables in this package are derived. -const CLDRVersion = "32" - -const ( - _de = 269 - _en = 313 - _fr = 350 - _it = 505 - _mo = 784 - _no = 879 - _nb = 839 - _pt = 960 - _sh = 1031 - _mul = 806 - _und = 0 -) -const ( - _001 = 1 - _419 = 31 - _BR = 65 - _CA = 73 - _ES = 111 - _GB = 124 - _MD = 189 - _PT = 239 - _UK = 307 - _US = 310 - _ZZ = 358 - _XA = 324 - _XC = 326 - _XK = 334 -) -const ( - _Latn = 91 - _Hani = 57 - _Hans = 59 - _Hant = 60 - _Qaaa = 149 - _Qaai = 157 - _Qabx = 198 - _Zinh = 255 - _Zyyy = 260 - _Zzzz = 261 -) - -var regionToGroups = []uint8{ // 359 elements - // Entry 0 - 3F - 0x00, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x00, 0x04, - // Entry 40 - 7F - 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x00, - 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, - // Entry 80 - BF - 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, - 0x00, 0x00, 0x04, 0x01, 0x00, 0x04, 0x02, 0x00, - 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, - 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x04, - // Entry C0 - FF - 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, - 0x01, 0x04, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x04, 0x00, 0x05, 0x00, 0x00, - 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - // Entry 100 - 13F - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x05, 0x04, - 0x00, 0x00, 0x04, 0x00, 0x04, 0x04, 0x05, 0x00, - // Entry 140 - 17F - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -} // Size: 383 bytes - -var paradigmLocales = [][3]uint16{ // 3 elements - 0: [3]uint16{0x139, 0x0, 0x7c}, - 1: [3]uint16{0x13e, 0x0, 0x1f}, - 2: [3]uint16{0x3c0, 0x41, 0xef}, -} // Size: 42 bytes - -type mutualIntelligibility struct { - want uint16 - have uint16 - distance uint8 - oneway bool -} -type scriptIntelligibility struct { - wantLang uint16 - haveLang uint16 - wantScript uint8 - haveScript uint8 - distance uint8 -} -type regionIntelligibility struct { - lang uint16 - script uint8 - group uint8 - distance uint8 -} - -// matchLang holds pairs of langIDs of base languages that are typically -// mutually intelligible. Each pair is associated with a confidence and -// whether the intelligibility goes one or both ways. -var matchLang = []mutualIntelligibility{ // 113 elements - 0: {want: 0x1d1, have: 0xb7, distance: 0x4, oneway: false}, - 1: {want: 0x407, have: 0xb7, distance: 0x4, oneway: false}, - 2: {want: 0x407, have: 0x1d1, distance: 0x4, oneway: false}, - 3: {want: 0x407, have: 0x432, distance: 0x4, oneway: false}, - 4: {want: 0x43a, have: 0x1, distance: 0x4, oneway: false}, - 5: {want: 0x1a3, have: 0x10d, distance: 0x4, oneway: true}, - 6: {want: 0x295, have: 0x10d, distance: 0x4, oneway: true}, - 7: {want: 0x101, have: 0x36f, distance: 0x8, oneway: false}, - 8: {want: 0x101, have: 0x347, distance: 0x8, oneway: false}, - 9: {want: 0x5, have: 0x3e2, distance: 0xa, oneway: true}, - 10: {want: 0xd, have: 0x139, distance: 0xa, oneway: true}, - 11: {want: 0x16, have: 0x367, distance: 0xa, oneway: true}, - 12: {want: 0x21, have: 0x139, distance: 0xa, oneway: true}, - 13: {want: 0x56, have: 0x13e, distance: 0xa, oneway: true}, - 14: {want: 0x58, have: 0x3e2, distance: 0xa, oneway: true}, - 15: {want: 0x71, have: 0x3e2, distance: 0xa, oneway: true}, - 16: {want: 0x75, have: 0x139, distance: 0xa, oneway: true}, - 17: {want: 0x82, have: 0x1be, distance: 0xa, oneway: true}, - 18: {want: 0xa5, have: 0x139, distance: 0xa, oneway: true}, - 19: {want: 0xb2, have: 0x15e, distance: 0xa, oneway: true}, - 20: {want: 0xdd, have: 0x153, distance: 0xa, oneway: true}, - 21: {want: 0xe5, have: 0x139, distance: 0xa, oneway: true}, - 22: {want: 0xe9, have: 0x3a, distance: 0xa, oneway: true}, - 23: {want: 0xf0, have: 0x15e, distance: 0xa, oneway: true}, - 24: {want: 0xf9, have: 0x15e, distance: 0xa, oneway: true}, - 25: {want: 0x100, have: 0x139, distance: 0xa, oneway: true}, - 26: {want: 0x130, have: 0x139, distance: 0xa, oneway: true}, - 27: {want: 0x13c, have: 0x139, distance: 0xa, oneway: true}, - 28: {want: 0x140, have: 0x151, distance: 0xa, oneway: true}, - 29: {want: 0x145, have: 0x13e, distance: 0xa, oneway: true}, - 30: {want: 0x158, have: 0x101, distance: 0xa, oneway: true}, - 31: {want: 0x16d, have: 0x367, distance: 0xa, oneway: true}, - 32: {want: 0x16e, have: 0x139, distance: 0xa, oneway: true}, - 33: {want: 0x16f, have: 0x139, distance: 0xa, oneway: true}, - 34: {want: 0x17e, have: 0x139, distance: 0xa, oneway: true}, - 35: {want: 0x190, have: 0x13e, distance: 0xa, oneway: true}, - 36: {want: 0x194, have: 0x13e, distance: 0xa, oneway: true}, - 37: {want: 0x1a4, have: 0x1be, distance: 0xa, oneway: true}, - 38: {want: 0x1b4, have: 0x139, distance: 0xa, oneway: true}, - 39: {want: 0x1b8, have: 0x139, distance: 0xa, oneway: true}, - 40: {want: 0x1d4, have: 0x15e, distance: 0xa, oneway: true}, - 41: {want: 0x1d7, have: 0x3e2, distance: 0xa, oneway: true}, - 42: {want: 0x1d9, have: 0x139, distance: 0xa, oneway: true}, - 43: {want: 0x1e7, have: 0x139, distance: 0xa, oneway: true}, - 44: {want: 0x1f8, have: 0x139, distance: 0xa, oneway: true}, - 45: {want: 0x20e, have: 0x1e1, distance: 0xa, oneway: true}, - 46: {want: 0x210, have: 0x139, distance: 0xa, oneway: true}, - 47: {want: 0x22d, have: 0x15e, distance: 0xa, oneway: true}, - 48: {want: 0x242, have: 0x3e2, distance: 0xa, oneway: true}, - 49: {want: 0x24a, have: 0x139, distance: 0xa, oneway: true}, - 50: {want: 0x251, have: 0x139, distance: 0xa, oneway: true}, - 51: {want: 0x265, have: 0x139, distance: 0xa, oneway: true}, - 52: {want: 0x274, have: 0x48a, distance: 0xa, oneway: true}, - 53: {want: 0x28a, have: 0x3e2, distance: 0xa, oneway: true}, - 54: {want: 0x28e, have: 0x1f9, distance: 0xa, oneway: true}, - 55: {want: 0x2a3, have: 0x139, distance: 0xa, oneway: true}, - 56: {want: 0x2b5, have: 0x15e, distance: 0xa, oneway: true}, - 57: {want: 0x2b8, have: 0x139, distance: 0xa, oneway: true}, - 58: {want: 0x2be, have: 0x139, distance: 0xa, oneway: true}, - 59: {want: 0x2c3, have: 0x15e, distance: 0xa, oneway: true}, - 60: {want: 0x2ed, have: 0x139, distance: 0xa, oneway: true}, - 61: {want: 0x2f1, have: 0x15e, distance: 0xa, oneway: true}, - 62: {want: 0x2fa, have: 0x139, distance: 0xa, oneway: true}, - 63: {want: 0x2ff, have: 0x7e, distance: 0xa, oneway: true}, - 64: {want: 0x304, have: 0x139, distance: 0xa, oneway: true}, - 65: {want: 0x30b, have: 0x3e2, distance: 0xa, oneway: true}, - 66: {want: 0x31b, have: 0x1be, distance: 0xa, oneway: true}, - 67: {want: 0x31f, have: 0x1e1, distance: 0xa, oneway: true}, - 68: {want: 0x320, have: 0x139, distance: 0xa, oneway: true}, - 69: {want: 0x331, have: 0x139, distance: 0xa, oneway: true}, - 70: {want: 0x351, have: 0x139, distance: 0xa, oneway: true}, - 71: {want: 0x36a, have: 0x347, distance: 0xa, oneway: false}, - 72: {want: 0x36a, have: 0x36f, distance: 0xa, oneway: true}, - 73: {want: 0x37a, have: 0x139, distance: 0xa, oneway: true}, - 74: {want: 0x387, have: 0x139, distance: 0xa, oneway: true}, - 75: {want: 0x389, have: 0x139, distance: 0xa, oneway: true}, - 76: {want: 0x38b, have: 0x15e, distance: 0xa, oneway: true}, - 77: {want: 0x390, have: 0x139, distance: 0xa, oneway: true}, - 78: {want: 0x395, have: 0x139, distance: 0xa, oneway: true}, - 79: {want: 0x39d, have: 0x139, distance: 0xa, oneway: true}, - 80: {want: 0x3a5, have: 0x139, distance: 0xa, oneway: true}, - 81: {want: 0x3be, have: 0x139, distance: 0xa, oneway: true}, - 82: {want: 0x3c4, have: 0x13e, distance: 0xa, oneway: true}, - 83: {want: 0x3d4, have: 0x10d, distance: 0xa, oneway: true}, - 84: {want: 0x3d9, have: 0x139, distance: 0xa, oneway: true}, - 85: {want: 0x3e5, have: 0x15e, distance: 0xa, oneway: true}, - 86: {want: 0x3e9, have: 0x1be, distance: 0xa, oneway: true}, - 87: {want: 0x3fa, have: 0x139, distance: 0xa, oneway: true}, - 88: {want: 0x40c, have: 0x139, distance: 0xa, oneway: true}, - 89: {want: 0x423, have: 0x139, distance: 0xa, oneway: true}, - 90: {want: 0x429, have: 0x139, distance: 0xa, oneway: true}, - 91: {want: 0x431, have: 0x139, distance: 0xa, oneway: true}, - 92: {want: 0x43b, have: 0x139, distance: 0xa, oneway: true}, - 93: {want: 0x43e, have: 0x1e1, distance: 0xa, oneway: true}, - 94: {want: 0x445, have: 0x139, distance: 0xa, oneway: true}, - 95: {want: 0x450, have: 0x139, distance: 0xa, oneway: true}, - 96: {want: 0x461, have: 0x139, distance: 0xa, oneway: true}, - 97: {want: 0x467, have: 0x3e2, distance: 0xa, oneway: true}, - 98: {want: 0x46f, have: 0x139, distance: 0xa, oneway: true}, - 99: {want: 0x476, have: 0x3e2, distance: 0xa, oneway: true}, - 100: {want: 0x3883, have: 0x139, distance: 0xa, oneway: true}, - 101: {want: 0x480, have: 0x139, distance: 0xa, oneway: true}, - 102: {want: 0x482, have: 0x139, distance: 0xa, oneway: true}, - 103: {want: 0x494, have: 0x3e2, distance: 0xa, oneway: true}, - 104: {want: 0x49d, have: 0x139, distance: 0xa, oneway: true}, - 105: {want: 0x4ac, have: 0x529, distance: 0xa, oneway: true}, - 106: {want: 0x4b4, have: 0x139, distance: 0xa, oneway: true}, - 107: {want: 0x4bc, have: 0x3e2, distance: 0xa, oneway: true}, - 108: {want: 0x4e5, have: 0x15e, distance: 0xa, oneway: true}, - 109: {want: 0x4f2, have: 0x139, distance: 0xa, oneway: true}, - 110: {want: 0x512, have: 0x139, distance: 0xa, oneway: true}, - 111: {want: 0x518, have: 0x139, distance: 0xa, oneway: true}, - 112: {want: 0x52f, have: 0x139, distance: 0xa, oneway: true}, -} // Size: 702 bytes - -// matchScript holds pairs of scriptIDs where readers of one script -// can typically also read the other. Each is associated with a confidence. -var matchScript = []scriptIntelligibility{ // 26 elements - 0: {wantLang: 0x432, haveLang: 0x432, wantScript: 0x5b, haveScript: 0x20, distance: 0x5}, - 1: {wantLang: 0x432, haveLang: 0x432, wantScript: 0x20, haveScript: 0x5b, distance: 0x5}, - 2: {wantLang: 0x58, haveLang: 0x3e2, wantScript: 0x5b, haveScript: 0x20, distance: 0xa}, - 3: {wantLang: 0xa5, haveLang: 0x139, wantScript: 0xe, haveScript: 0x5b, distance: 0xa}, - 4: {wantLang: 0x1d7, haveLang: 0x3e2, wantScript: 0x8, haveScript: 0x20, distance: 0xa}, - 5: {wantLang: 0x210, haveLang: 0x139, wantScript: 0x2e, haveScript: 0x5b, distance: 0xa}, - 6: {wantLang: 0x24a, haveLang: 0x139, wantScript: 0x4f, haveScript: 0x5b, distance: 0xa}, - 7: {wantLang: 0x251, haveLang: 0x139, wantScript: 0x53, haveScript: 0x5b, distance: 0xa}, - 8: {wantLang: 0x2b8, haveLang: 0x139, wantScript: 0x58, haveScript: 0x5b, distance: 0xa}, - 9: {wantLang: 0x304, haveLang: 0x139, wantScript: 0x6f, haveScript: 0x5b, distance: 0xa}, - 10: {wantLang: 0x331, haveLang: 0x139, wantScript: 0x76, haveScript: 0x5b, distance: 0xa}, - 11: {wantLang: 0x351, haveLang: 0x139, wantScript: 0x22, haveScript: 0x5b, distance: 0xa}, - 12: {wantLang: 0x395, haveLang: 0x139, wantScript: 0x83, haveScript: 0x5b, distance: 0xa}, - 13: {wantLang: 0x39d, haveLang: 0x139, wantScript: 0x36, haveScript: 0x5b, distance: 0xa}, - 14: {wantLang: 0x3be, haveLang: 0x139, wantScript: 0x5, haveScript: 0x5b, distance: 0xa}, - 15: {wantLang: 0x3fa, haveLang: 0x139, wantScript: 0x5, haveScript: 0x5b, distance: 0xa}, - 16: {wantLang: 0x40c, haveLang: 0x139, wantScript: 0xd6, haveScript: 0x5b, distance: 0xa}, - 17: {wantLang: 0x450, haveLang: 0x139, wantScript: 0xe6, haveScript: 0x5b, distance: 0xa}, - 18: {wantLang: 0x461, haveLang: 0x139, wantScript: 0xe9, haveScript: 0x5b, distance: 0xa}, - 19: {wantLang: 0x46f, haveLang: 0x139, wantScript: 0x2c, haveScript: 0x5b, distance: 0xa}, - 20: {wantLang: 0x476, haveLang: 0x3e2, wantScript: 0x5b, haveScript: 0x20, distance: 0xa}, - 21: {wantLang: 0x4b4, haveLang: 0x139, wantScript: 0x5, haveScript: 0x5b, distance: 0xa}, - 22: {wantLang: 0x4bc, haveLang: 0x3e2, wantScript: 0x5b, haveScript: 0x20, distance: 0xa}, - 23: {wantLang: 0x512, haveLang: 0x139, wantScript: 0x3e, haveScript: 0x5b, distance: 0xa}, - 24: {wantLang: 0x529, haveLang: 0x529, wantScript: 0x3b, haveScript: 0x3c, distance: 0xf}, - 25: {wantLang: 0x529, haveLang: 0x529, wantScript: 0x3c, haveScript: 0x3b, distance: 0x13}, -} // Size: 232 bytes - -var matchRegion = []regionIntelligibility{ // 15 elements - 0: {lang: 0x3a, script: 0x0, group: 0x4, distance: 0x4}, - 1: {lang: 0x3a, script: 0x0, group: 0x84, distance: 0x4}, - 2: {lang: 0x139, script: 0x0, group: 0x1, distance: 0x4}, - 3: {lang: 0x139, script: 0x0, group: 0x81, distance: 0x4}, - 4: {lang: 0x13e, script: 0x0, group: 0x3, distance: 0x4}, - 5: {lang: 0x13e, script: 0x0, group: 0x83, distance: 0x4}, - 6: {lang: 0x3c0, script: 0x0, group: 0x3, distance: 0x4}, - 7: {lang: 0x3c0, script: 0x0, group: 0x83, distance: 0x4}, - 8: {lang: 0x529, script: 0x3c, group: 0x2, distance: 0x4}, - 9: {lang: 0x529, script: 0x3c, group: 0x82, distance: 0x4}, - 10: {lang: 0x3a, script: 0x0, group: 0x80, distance: 0x5}, - 11: {lang: 0x139, script: 0x0, group: 0x80, distance: 0x5}, - 12: {lang: 0x13e, script: 0x0, group: 0x80, distance: 0x5}, - 13: {lang: 0x3c0, script: 0x0, group: 0x80, distance: 0x5}, - 14: {lang: 0x529, script: 0x3c, group: 0x80, distance: 0x5}, -} // Size: 114 bytes - -// Total table size 1473 bytes (1KiB); checksum: 7BB90B5C diff --git a/vendor/golang.org/x/text/language/tags.go b/vendor/golang.org/x/text/language/tags.go deleted file mode 100644 index 42ea79266..000000000 --- a/vendor/golang.org/x/text/language/tags.go +++ /dev/null @@ -1,145 +0,0 @@ -// Copyright 2013 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 language - -import "golang.org/x/text/internal/language/compact" - -// TODO: Various sets of commonly use tags and regions. - -// MustParse is like Parse, but panics if the given BCP 47 tag cannot be parsed. -// It simplifies safe initialization of Tag values. -func MustParse(s string) Tag { - t, err := Parse(s) - if err != nil { - panic(err) - } - return t -} - -// MustParse is like Parse, but panics if the given BCP 47 tag cannot be parsed. -// It simplifies safe initialization of Tag values. -func (c CanonType) MustParse(s string) Tag { - t, err := c.Parse(s) - if err != nil { - panic(err) - } - return t -} - -// MustParseBase is like ParseBase, but panics if the given base cannot be parsed. -// It simplifies safe initialization of Base values. -func MustParseBase(s string) Base { - b, err := ParseBase(s) - if err != nil { - panic(err) - } - return b -} - -// MustParseScript is like ParseScript, but panics if the given script cannot be -// parsed. It simplifies safe initialization of Script values. -func MustParseScript(s string) Script { - scr, err := ParseScript(s) - if err != nil { - panic(err) - } - return scr -} - -// MustParseRegion is like ParseRegion, but panics if the given region cannot be -// parsed. It simplifies safe initialization of Region values. -func MustParseRegion(s string) Region { - r, err := ParseRegion(s) - if err != nil { - panic(err) - } - return r -} - -var ( - und = Tag{} - - Und Tag = Tag{} - - Afrikaans Tag = Tag(compact.Afrikaans) - Amharic Tag = Tag(compact.Amharic) - Arabic Tag = Tag(compact.Arabic) - ModernStandardArabic Tag = Tag(compact.ModernStandardArabic) - Azerbaijani Tag = Tag(compact.Azerbaijani) - Bulgarian Tag = Tag(compact.Bulgarian) - Bengali Tag = Tag(compact.Bengali) - Catalan Tag = Tag(compact.Catalan) - Czech Tag = Tag(compact.Czech) - Danish Tag = Tag(compact.Danish) - German Tag = Tag(compact.German) - Greek Tag = Tag(compact.Greek) - English Tag = Tag(compact.English) - AmericanEnglish Tag = Tag(compact.AmericanEnglish) - BritishEnglish Tag = Tag(compact.BritishEnglish) - Spanish Tag = Tag(compact.Spanish) - EuropeanSpanish Tag = Tag(compact.EuropeanSpanish) - LatinAmericanSpanish Tag = Tag(compact.LatinAmericanSpanish) - Estonian Tag = Tag(compact.Estonian) - Persian Tag = Tag(compact.Persian) - Finnish Tag = Tag(compact.Finnish) - Filipino Tag = Tag(compact.Filipino) - French Tag = Tag(compact.French) - CanadianFrench Tag = Tag(compact.CanadianFrench) - Gujarati Tag = Tag(compact.Gujarati) - Hebrew Tag = Tag(compact.Hebrew) - Hindi Tag = Tag(compact.Hindi) - Croatian Tag = Tag(compact.Croatian) - Hungarian Tag = Tag(compact.Hungarian) - Armenian Tag = Tag(compact.Armenian) - Indonesian Tag = Tag(compact.Indonesian) - Icelandic Tag = Tag(compact.Icelandic) - Italian Tag = Tag(compact.Italian) - Japanese Tag = Tag(compact.Japanese) - Georgian Tag = Tag(compact.Georgian) - Kazakh Tag = Tag(compact.Kazakh) - Khmer Tag = Tag(compact.Khmer) - Kannada Tag = Tag(compact.Kannada) - Korean Tag = Tag(compact.Korean) - Kirghiz Tag = Tag(compact.Kirghiz) - Lao Tag = Tag(compact.Lao) - Lithuanian Tag = Tag(compact.Lithuanian) - Latvian Tag = Tag(compact.Latvian) - Macedonian Tag = Tag(compact.Macedonian) - Malayalam Tag = Tag(compact.Malayalam) - Mongolian Tag = Tag(compact.Mongolian) - Marathi Tag = Tag(compact.Marathi) - Malay Tag = Tag(compact.Malay) - Burmese Tag = Tag(compact.Burmese) - Nepali Tag = Tag(compact.Nepali) - Dutch Tag = Tag(compact.Dutch) - Norwegian Tag = Tag(compact.Norwegian) - Punjabi Tag = Tag(compact.Punjabi) - Polish Tag = Tag(compact.Polish) - Portuguese Tag = Tag(compact.Portuguese) - BrazilianPortuguese Tag = Tag(compact.BrazilianPortuguese) - EuropeanPortuguese Tag = Tag(compact.EuropeanPortuguese) - Romanian Tag = Tag(compact.Romanian) - Russian Tag = Tag(compact.Russian) - Sinhala Tag = Tag(compact.Sinhala) - Slovak Tag = Tag(compact.Slovak) - Slovenian Tag = Tag(compact.Slovenian) - Albanian Tag = Tag(compact.Albanian) - Serbian Tag = Tag(compact.Serbian) - SerbianLatin Tag = Tag(compact.SerbianLatin) - Swedish Tag = Tag(compact.Swedish) - Swahili Tag = Tag(compact.Swahili) - Tamil Tag = Tag(compact.Tamil) - Telugu Tag = Tag(compact.Telugu) - Thai Tag = Tag(compact.Thai) - Turkish Tag = Tag(compact.Turkish) - Ukrainian Tag = Tag(compact.Ukrainian) - Urdu Tag = Tag(compact.Urdu) - Uzbek Tag = Tag(compact.Uzbek) - Vietnamese Tag = Tag(compact.Vietnamese) - Chinese Tag = Tag(compact.Chinese) - SimplifiedChinese Tag = Tag(compact.SimplifiedChinese) - TraditionalChinese Tag = Tag(compact.TraditionalChinese) - Zulu Tag = Tag(compact.Zulu) -) diff --git a/vendor/golang.org/x/text/message/catalog.go b/vendor/golang.org/x/text/message/catalog.go deleted file mode 100644 index 068271def..000000000 --- a/vendor/golang.org/x/text/message/catalog.go +++ /dev/null @@ -1,36 +0,0 @@ -// 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 message - -// TODO: some types in this file will need to be made public at some time. -// Documentation and method names will reflect this by using the exported name. - -import ( - "golang.org/x/text/language" - "golang.org/x/text/message/catalog" -) - -// MatchLanguage reports the matched tag obtained from language.MatchStrings for -// the Matcher of the DefaultCatalog. -func MatchLanguage(preferred ...string) language.Tag { - c := DefaultCatalog - tag, _ := language.MatchStrings(c.Matcher(), preferred...) - return tag -} - -// DefaultCatalog is used by SetString. -var DefaultCatalog catalog.Catalog = defaultCatalog - -var defaultCatalog = catalog.NewBuilder() - -// SetString calls SetString on the initial default Catalog. -func SetString(tag language.Tag, key string, msg string) error { - return defaultCatalog.SetString(tag, key, msg) -} - -// Set calls Set on the initial default Catalog. -func Set(tag language.Tag, key string, msg ...catalog.Message) error { - return defaultCatalog.Set(tag, key, msg...) -} diff --git a/vendor/golang.org/x/text/message/catalog/catalog.go b/vendor/golang.org/x/text/message/catalog/catalog.go deleted file mode 100644 index 96955d075..000000000 --- a/vendor/golang.org/x/text/message/catalog/catalog.go +++ /dev/null @@ -1,365 +0,0 @@ -// 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 catalog defines collections of translated format strings. -// -// This package mostly defines types for populating catalogs with messages. The -// catmsg package contains further definitions for creating custom message and -// dictionary types as well as packages that use Catalogs. -// -// Package catalog defines various interfaces: Dictionary, Loader, and Message. -// A Dictionary maintains a set of translations of format strings for a single -// language. The Loader interface defines a source of dictionaries. A -// translation of a format string is represented by a Message. -// -// # Catalogs -// -// A Catalog defines a programmatic interface for setting message translations. -// It maintains a set of per-language dictionaries with translations for a set -// of keys. For message translation to function properly, a translation should -// be defined for each key for each supported language. A dictionary may be -// underspecified, though, if there is a parent language that already defines -// the key. For example, a Dictionary for "en-GB" could leave out entries that -// are identical to those in a dictionary for "en". -// -// # Messages -// -// A Message is a format string which varies on the value of substitution -// variables. For instance, to indicate the number of results one could want "no -// results" if there are none, "1 result" if there is 1, and "%d results" for -// any other number. Catalog is agnostic to the kind of format strings that are -// used: for instance, messages can follow either the printf-style substitution -// from package fmt or use templates. -// -// A Message does not substitute arguments in the format string. This job is -// reserved for packages that render strings, such as message, that use Catalogs -// to selected string. This separation of concerns allows Catalog to be used to -// store any kind of formatting strings. -// -// # Selecting messages based on linguistic features of substitution arguments -// -// Messages may vary based on any linguistic features of the argument values. -// The most common one is plural form, but others exist. -// -// Selection messages are provided in packages that provide support for a -// specific linguistic feature. The following snippet uses plural.Selectf: -// -// catalog.Set(language.English, "You are %d minute(s) late.", -// plural.Selectf(1, "", -// plural.One, "You are 1 minute late.", -// plural.Other, "You are %d minutes late.")) -// -// In this example, a message is stored in the Catalog where one of two messages -// is selected based on the first argument, a number. The first message is -// selected if the argument is singular (identified by the selector "one") and -// the second message is selected in all other cases. The selectors are defined -// by the plural rules defined in CLDR. The selector "other" is special and will -// always match. Each language always defines one of the linguistic categories -// to be "other." For English, singular is "one" and plural is "other". -// -// Selects can be nested. This allows selecting sentences based on features of -// multiple arguments or multiple linguistic properties of a single argument. -// -// # String interpolation -// -// There is often a lot of commonality between the possible variants of a -// message. For instance, in the example above the word "minute" varies based on -// the plural catogory of the argument, but the rest of the sentence is -// identical. Using interpolation the above message can be rewritten as: -// -// catalog.Set(language.English, "You are %d minute(s) late.", -// catalog.Var("minutes", -// plural.Selectf(1, "", plural.One, "minute", plural.Other, "minutes")), -// catalog.String("You are %[1]d ${minutes} late.")) -// -// Var is defined to return the variable name if the message does not yield a -// match. This allows us to further simplify this snippet to -// -// catalog.Set(language.English, "You are %d minute(s) late.", -// catalog.Var("minutes", plural.Selectf(1, "", plural.One, "minute")), -// catalog.String("You are %d ${minutes} late.")) -// -// Overall this is still only a minor improvement, but things can get a lot more -// unwieldy if more than one linguistic feature is used to determine a message -// variant. Consider the following example: -// -// // argument 1: list of hosts, argument 2: list of guests -// catalog.Set(language.English, "%[1]v invite(s) %[2]v to their party.", -// catalog.Var("their", -// plural.Selectf(1, "" -// plural.One, gender.Select(1, "female", "her", "other", "his"))), -// catalog.Var("invites", plural.Selectf(1, "", plural.One, "invite")) -// catalog.String("%[1]v ${invites} %[2]v to ${their} party.")), -// -// Without variable substitution, this would have to be written as -// -// // argument 1: list of hosts, argument 2: list of guests -// catalog.Set(language.English, "%[1]v invite(s) %[2]v to their party.", -// plural.Selectf(1, "", -// plural.One, gender.Select(1, -// "female", "%[1]v invites %[2]v to her party." -// "other", "%[1]v invites %[2]v to his party."), -// plural.Other, "%[1]v invites %[2]v to their party.")) -// -// Not necessarily shorter, but using variables there is less duplication and -// the messages are more maintenance friendly. Moreover, languages may have up -// to six plural forms. This makes the use of variables more welcome. -// -// Different messages using the same inflections can reuse variables by moving -// them to macros. Using macros we can rewrite the message as: -// -// // argument 1: list of hosts, argument 2: list of guests -// catalog.SetString(language.English, "%[1]v invite(s) %[2]v to their party.", -// "%[1]v ${invites(1)} %[2]v to ${their(1)} party.") -// -// Where the following macros were defined separately. -// -// catalog.SetMacro(language.English, "invites", plural.Selectf(1, "", -// plural.One, "invite")) -// catalog.SetMacro(language.English, "their", plural.Selectf(1, "", -// plural.One, gender.Select(1, "female", "her", "other", "his"))), -// -// Placeholders use parentheses and the arguments to invoke a macro. -// -// # Looking up messages -// -// Message lookup using Catalogs is typically only done by specialized packages -// and is not something the user should be concerned with. For instance, to -// express the tardiness of a user using the related message we defined earlier, -// the user may use the package message like so: -// -// p := message.NewPrinter(language.English) -// p.Printf("You are %d minute(s) late.", 5) -// -// Which would print: -// -// You are 5 minutes late. -// -// This package is UNDER CONSTRUCTION and its API may change. -package catalog // import "golang.org/x/text/message/catalog" - -// TODO: -// Some way to freeze a catalog. -// - Locking on each lockup turns out to be about 50% of the total running time -// for some of the benchmarks in the message package. -// Consider these: -// - Sequence type to support sequences in user-defined messages. -// - Garbage collection: Remove dictionaries that can no longer be reached -// as other dictionaries have been added that cover all possible keys. - -import ( - "errors" - "fmt" - - "golang.org/x/text/internal" - - "golang.org/x/text/internal/catmsg" - "golang.org/x/text/language" -) - -// A Catalog allows lookup of translated messages. -type Catalog interface { - // Languages returns all languages for which the Catalog contains variants. - Languages() []language.Tag - - // Matcher returns a Matcher for languages from this Catalog. - Matcher() language.Matcher - - // A Context is used for evaluating Messages. - Context(tag language.Tag, r catmsg.Renderer) *Context - - // This method also makes Catalog a private interface. - lookup(tag language.Tag, key string) (data string, ok bool) -} - -// NewFromMap creates a Catalog from the given map. If a Dictionary is -// underspecified the entry is retrieved from a parent language. -func NewFromMap(dictionaries map[string]Dictionary, opts ...Option) (Catalog, error) { - options := options{} - for _, o := range opts { - o(&options) - } - c := &catalog{ - dicts: map[language.Tag]Dictionary{}, - } - _, hasFallback := dictionaries[options.fallback.String()] - if hasFallback { - // TODO: Should it be okay to not have a fallback language? - // Catalog generators could enforce there is always a fallback. - c.langs = append(c.langs, options.fallback) - } - for lang, dict := range dictionaries { - tag, err := language.Parse(lang) - if err != nil { - return nil, fmt.Errorf("catalog: invalid language tag %q", lang) - } - if _, ok := c.dicts[tag]; ok { - return nil, fmt.Errorf("catalog: duplicate entry for tag %q after normalization", tag) - } - c.dicts[tag] = dict - if !hasFallback || tag != options.fallback { - c.langs = append(c.langs, tag) - } - } - if hasFallback { - internal.SortTags(c.langs[1:]) - } else { - internal.SortTags(c.langs) - } - c.matcher = language.NewMatcher(c.langs) - return c, nil -} - -// A Dictionary is a source of translations for a single language. -type Dictionary interface { - // Lookup returns a message compiled with catmsg.Compile for the given key. - // It returns false for ok if such a message could not be found. - Lookup(key string) (data string, ok bool) -} - -type catalog struct { - langs []language.Tag - dicts map[language.Tag]Dictionary - macros store - matcher language.Matcher -} - -func (c *catalog) Languages() []language.Tag { return c.langs } -func (c *catalog) Matcher() language.Matcher { return c.matcher } - -func (c *catalog) lookup(tag language.Tag, key string) (data string, ok bool) { - for ; ; tag = tag.Parent() { - if dict, ok := c.dicts[tag]; ok { - if data, ok := dict.Lookup(key); ok { - return data, true - } - } - if tag == language.Und { - break - } - } - return "", false -} - -// Context returns a Context for formatting messages. -// Only one Message may be formatted per context at any given time. -func (c *catalog) Context(tag language.Tag, r catmsg.Renderer) *Context { - return &Context{ - cat: c, - tag: tag, - dec: catmsg.NewDecoder(tag, r, &dict{&c.macros, tag}), - } -} - -// A Builder allows building a Catalog programmatically. -type Builder struct { - options - matcher language.Matcher - - index store - macros store -} - -type options struct { - fallback language.Tag -} - -// An Option configures Catalog behavior. -type Option func(*options) - -// Fallback specifies the default fallback language. The default is Und. -func Fallback(tag language.Tag) Option { - return func(o *options) { o.fallback = tag } -} - -// TODO: -// // Catalogs specifies one or more sources for a Catalog. -// // Lookups are in order. -// // This can be changed inserting a Catalog used for setting, which implements -// // Loader, used for setting in the chain. -// func Catalogs(d ...Loader) Option { -// return nil -// } -// -// func Delims(start, end string) Option {} -// -// func Dict(tag language.Tag, d ...Dictionary) Option - -// NewBuilder returns an empty mutable Catalog. -func NewBuilder(opts ...Option) *Builder { - c := &Builder{} - for _, o := range opts { - o(&c.options) - } - return c -} - -// SetString is shorthand for Set(tag, key, String(msg)). -func (c *Builder) SetString(tag language.Tag, key string, msg string) error { - return c.set(tag, key, &c.index, String(msg)) -} - -// Set sets the translation for the given language and key. -// -// When evaluation this message, the first Message in the sequence to msgs to -// evaluate to a string will be the message returned. -func (c *Builder) Set(tag language.Tag, key string, msg ...Message) error { - return c.set(tag, key, &c.index, msg...) -} - -// SetMacro defines a Message that may be substituted in another message. -// The arguments to a macro Message are passed as arguments in the -// placeholder the form "${foo(arg1, arg2)}". -func (c *Builder) SetMacro(tag language.Tag, name string, msg ...Message) error { - return c.set(tag, name, &c.macros, msg...) -} - -// ErrNotFound indicates there was no message for the given key. -var ErrNotFound = errors.New("catalog: message not found") - -// String specifies a plain message string. It can be used as fallback if no -// other strings match or as a simple standalone message. -// -// It is an error to pass more than one String in a message sequence. -func String(name string) Message { - return catmsg.String(name) -} - -// Var sets a variable that may be substituted in formatting patterns using -// named substitution of the form "${name}". The name argument is used as a -// fallback if the statements do not produce a match. The statement sequence may -// not contain any Var calls. -// -// The name passed to a Var must be unique within message sequence. -func Var(name string, msg ...Message) Message { - return &catmsg.Var{Name: name, Message: firstInSequence(msg)} -} - -// Context returns a Context for formatting messages. -// Only one Message may be formatted per context at any given time. -func (b *Builder) Context(tag language.Tag, r catmsg.Renderer) *Context { - return &Context{ - cat: b, - tag: tag, - dec: catmsg.NewDecoder(tag, r, &dict{&b.macros, tag}), - } -} - -// A Context is used for evaluating Messages. -// Only one Message may be formatted per context at any given time. -type Context struct { - cat Catalog - tag language.Tag // TODO: use compact index. - dec *catmsg.Decoder -} - -// Execute looks up and executes the message with the given key. -// It returns ErrNotFound if no message could be found in the index. -func (c *Context) Execute(key string) error { - data, ok := c.cat.lookup(c.tag, key) - if !ok { - return ErrNotFound - } - return c.dec.Execute(data) -} diff --git a/vendor/golang.org/x/text/message/catalog/dict.go b/vendor/golang.org/x/text/message/catalog/dict.go deleted file mode 100644 index a0eb81810..000000000 --- a/vendor/golang.org/x/text/message/catalog/dict.go +++ /dev/null @@ -1,129 +0,0 @@ -// 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 catalog - -import ( - "sync" - - "golang.org/x/text/internal" - "golang.org/x/text/internal/catmsg" - "golang.org/x/text/language" -) - -// TODO: -// Dictionary returns a Dictionary that returns the first Message, using the -// given language tag, that matches: -// 1. the last one registered by one of the Set methods -// 2. returned by one of the Loaders -// 3. repeat from 1. using the parent language -// This approach allows messages to be underspecified. -// func (c *Catalog) Dictionary(tag language.Tag) (Dictionary, error) { -// // TODO: verify dictionary exists. -// return &dict{&c.index, tag}, nil -// } - -type dict struct { - s *store - tag language.Tag // TODO: make compact tag. -} - -func (d *dict) Lookup(key string) (data string, ok bool) { - return d.s.lookup(d.tag, key) -} - -func (b *Builder) lookup(tag language.Tag, key string) (data string, ok bool) { - return b.index.lookup(tag, key) -} - -func (c *Builder) set(tag language.Tag, key string, s *store, msg ...Message) error { - data, err := catmsg.Compile(tag, &dict{&c.macros, tag}, firstInSequence(msg)) - - s.mutex.Lock() - defer s.mutex.Unlock() - - m := s.index[tag] - if m == nil { - m = msgMap{} - if s.index == nil { - s.index = map[language.Tag]msgMap{} - } - c.matcher = nil - s.index[tag] = m - } - - m[key] = data - return err -} - -func (c *Builder) Matcher() language.Matcher { - c.index.mutex.RLock() - m := c.matcher - c.index.mutex.RUnlock() - if m != nil { - return m - } - - c.index.mutex.Lock() - if c.matcher == nil { - c.matcher = language.NewMatcher(c.unlockedLanguages()) - } - m = c.matcher - c.index.mutex.Unlock() - return m -} - -type store struct { - mutex sync.RWMutex - index map[language.Tag]msgMap -} - -type msgMap map[string]string - -func (s *store) lookup(tag language.Tag, key string) (data string, ok bool) { - s.mutex.RLock() - defer s.mutex.RUnlock() - - for ; ; tag = tag.Parent() { - if msgs, ok := s.index[tag]; ok { - if msg, ok := msgs[key]; ok { - return msg, true - } - } - if tag == language.Und { - break - } - } - return "", false -} - -// Languages returns all languages for which the Catalog contains variants. -func (b *Builder) Languages() []language.Tag { - s := &b.index - s.mutex.RLock() - defer s.mutex.RUnlock() - - return b.unlockedLanguages() -} - -func (b *Builder) unlockedLanguages() []language.Tag { - s := &b.index - if len(s.index) == 0 { - return nil - } - tags := make([]language.Tag, 0, len(s.index)) - _, hasFallback := s.index[b.options.fallback] - offset := 0 - if hasFallback { - tags = append(tags, b.options.fallback) - offset = 1 - } - for t := range s.index { - if t != b.options.fallback { - tags = append(tags, t) - } - } - internal.SortTags(tags[offset:]) - return tags -} diff --git a/vendor/golang.org/x/text/message/catalog/go19.go b/vendor/golang.org/x/text/message/catalog/go19.go deleted file mode 100644 index 291a4df94..000000000 --- a/vendor/golang.org/x/text/message/catalog/go19.go +++ /dev/null @@ -1,15 +0,0 @@ -// 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:build go1.9 - -package catalog - -import "golang.org/x/text/internal/catmsg" - -// A Message holds a collection of translations for the same phrase that may -// vary based on the values of substitution arguments. -type Message = catmsg.Message - -type firstInSequence = catmsg.FirstOf diff --git a/vendor/golang.org/x/text/message/catalog/gopre19.go b/vendor/golang.org/x/text/message/catalog/gopre19.go deleted file mode 100644 index da44ebb8b..000000000 --- a/vendor/golang.org/x/text/message/catalog/gopre19.go +++ /dev/null @@ -1,23 +0,0 @@ -// 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:build !go1.9 - -package catalog - -import "golang.org/x/text/internal/catmsg" - -// A Message holds a collection of translations for the same phrase that may -// vary based on the values of substitution arguments. -type Message interface { - catmsg.Message -} - -func firstInSequence(m []Message) catmsg.Message { - a := []catmsg.Message{} - for _, m := range m { - a = append(a, m) - } - return catmsg.FirstOf(a) -} diff --git a/vendor/golang.org/x/text/message/doc.go b/vendor/golang.org/x/text/message/doc.go deleted file mode 100644 index 4bf7bdcac..000000000 --- a/vendor/golang.org/x/text/message/doc.go +++ /dev/null @@ -1,99 +0,0 @@ -// 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 message implements formatted I/O for localized strings with functions -// analogous to the fmt's print functions. It is a drop-in replacement for fmt. -// -// # Localized Formatting -// -// A format string can be localized by replacing any of the print functions of -// fmt with an equivalent call to a Printer. -// -// p := message.NewPrinter(message.MatchLanguage("en")) -// p.Println(123456.78) // Prints 123,456.78 -// -// p.Printf("%d ducks in a row", 4331) // Prints 4,331 ducks in a row -// -// p := message.NewPrinter(message.MatchLanguage("nl")) -// p.Printf("Hoogte: %.1f meter", 1244.9) // Prints Hoogte: 1,244.9 meter -// -// p := message.NewPrinter(message.MatchLanguage("bn")) -// p.Println(123456.78) // Prints ১,২৩,৪৫৬.৭৮ -// -// Printer currently supports numbers and specialized types for which packages -// exist in x/text. Other builtin types such as time.Time and slices are -// planned. -// -// Format strings largely have the same meaning as with fmt with the following -// notable exceptions: -// - flag # always resorts to fmt for printing -// - verb 'f', 'e', 'g', 'd' use localized formatting unless the '#' flag is -// specified. -// - verb 'm' inserts a translation of a string argument. -// -// See package fmt for more options. -// -// # Translation -// -// The format strings that are passed to Printf, Sprintf, Fprintf, or Errorf -// are used as keys to look up translations for the specified languages. -// More on how these need to be specified below. -// -// One can use arbitrary keys to distinguish between otherwise ambiguous -// strings: -// -// p := message.NewPrinter(language.English) -// p.Printf("archive(noun)") // Prints "archive" -// p.Printf("archive(verb)") // Prints "archive" -// -// p := message.NewPrinter(language.German) -// p.Printf("archive(noun)") // Prints "Archiv" -// p.Printf("archive(verb)") // Prints "archivieren" -// -// To retain the fallback functionality, use Key: -// -// p.Printf(message.Key("archive(noun)", "archive")) -// p.Printf(message.Key("archive(verb)", "archive")) -// -// # Translation Pipeline -// -// Format strings that contain text need to be translated to support different -// locales. The first step is to extract strings that need to be translated. -// -// 1. Install gotext -// -// go get -u golang.org/x/text/cmd/gotext -// gotext -help -// -// 2. Mark strings in your source to be translated by using message.Printer, -// instead of the functions of the fmt package. -// -// 3. Extract the strings from your source -// -// gotext extract -// -// The output will be written to the textdata directory. -// -// 4. Send the files for translation -// -// It is planned to support multiple formats, but for now one will have to -// rewrite the JSON output to the desired format. -// -// 5. Inject translations into program -// -// 6. Repeat from 2 -// -// Right now this has to be done programmatically with calls to Set or -// SetString. These functions as well as the methods defined in -// see also package golang.org/x/text/message/catalog can be used to implement -// either dynamic or static loading of messages. -// -// # Plural and Gender Forms -// -// Translated messages can vary based on the plural and gender forms of -// substitution values. In general, it is up to the translators to provide -// alternative translations for such forms. See the packages in -// golang.org/x/text/feature and golang.org/x/text/message/catalog for more -// information. -package message diff --git a/vendor/golang.org/x/text/message/format.go b/vendor/golang.org/x/text/message/format.go deleted file mode 100644 index a47d17dd4..000000000 --- a/vendor/golang.org/x/text/message/format.go +++ /dev/null @@ -1,510 +0,0 @@ -// 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 message - -import ( - "bytes" - "strconv" - "unicode/utf8" - - "golang.org/x/text/internal/format" -) - -const ( - ldigits = "0123456789abcdefx" - udigits = "0123456789ABCDEFX" -) - -const ( - signed = true - unsigned = false -) - -// A formatInfo is the raw formatter used by Printf etc. -// It prints into a buffer that must be set up separately. -type formatInfo struct { - buf *bytes.Buffer - - format.Parser - - // intbuf is large enough to store %b of an int64 with a sign and - // avoids padding at the end of the struct on 32 bit architectures. - intbuf [68]byte -} - -func (f *formatInfo) init(buf *bytes.Buffer) { - f.ClearFlags() - f.buf = buf -} - -// writePadding generates n bytes of padding. -func (f *formatInfo) writePadding(n int) { - if n <= 0 { // No padding bytes needed. - return - } - f.buf.Grow(n) - // Decide which byte the padding should be filled with. - padByte := byte(' ') - if f.Zero { - padByte = byte('0') - } - // Fill padding with padByte. - for i := 0; i < n; i++ { - f.buf.WriteByte(padByte) // TODO: make more efficient. - } -} - -// pad appends b to f.buf, padded on left (!f.minus) or right (f.minus). -func (f *formatInfo) pad(b []byte) { - if !f.WidthPresent || f.Width == 0 { - f.buf.Write(b) - return - } - width := f.Width - utf8.RuneCount(b) - if !f.Minus { - // left padding - f.writePadding(width) - f.buf.Write(b) - } else { - // right padding - f.buf.Write(b) - f.writePadding(width) - } -} - -// padString appends s to f.buf, padded on left (!f.minus) or right (f.minus). -func (f *formatInfo) padString(s string) { - if !f.WidthPresent || f.Width == 0 { - f.buf.WriteString(s) - return - } - width := f.Width - utf8.RuneCountInString(s) - if !f.Minus { - // left padding - f.writePadding(width) - f.buf.WriteString(s) - } else { - // right padding - f.buf.WriteString(s) - f.writePadding(width) - } -} - -// fmt_boolean formats a boolean. -func (f *formatInfo) fmt_boolean(v bool) { - if v { - f.padString("true") - } else { - f.padString("false") - } -} - -// fmt_unicode formats a uint64 as "U+0078" or with f.sharp set as "U+0078 'x'". -func (f *formatInfo) fmt_unicode(u uint64) { - buf := f.intbuf[0:] - - // With default precision set the maximum needed buf length is 18 - // for formatting -1 with %#U ("U+FFFFFFFFFFFFFFFF") which fits - // into the already allocated intbuf with a capacity of 68 bytes. - prec := 4 - if f.PrecPresent && f.Prec > 4 { - prec = f.Prec - // Compute space needed for "U+" , number, " '", character, "'". - width := 2 + prec + 2 + utf8.UTFMax + 1 - if width > len(buf) { - buf = make([]byte, width) - } - } - - // Format into buf, ending at buf[i]. Formatting numbers is easier right-to-left. - i := len(buf) - - // For %#U we want to add a space and a quoted character at the end of the buffer. - if f.Sharp && u <= utf8.MaxRune && strconv.IsPrint(rune(u)) { - i-- - buf[i] = '\'' - i -= utf8.RuneLen(rune(u)) - utf8.EncodeRune(buf[i:], rune(u)) - i-- - buf[i] = '\'' - i-- - buf[i] = ' ' - } - // Format the Unicode code point u as a hexadecimal number. - for u >= 16 { - i-- - buf[i] = udigits[u&0xF] - prec-- - u >>= 4 - } - i-- - buf[i] = udigits[u] - prec-- - // Add zeros in front of the number until requested precision is reached. - for prec > 0 { - i-- - buf[i] = '0' - prec-- - } - // Add a leading "U+". - i-- - buf[i] = '+' - i-- - buf[i] = 'U' - - oldZero := f.Zero - f.Zero = false - f.pad(buf[i:]) - f.Zero = oldZero -} - -// fmt_integer formats signed and unsigned integers. -func (f *formatInfo) fmt_integer(u uint64, base int, isSigned bool, digits string) { - negative := isSigned && int64(u) < 0 - if negative { - u = -u - } - - buf := f.intbuf[0:] - // The already allocated f.intbuf with a capacity of 68 bytes - // is large enough for integer formatting when no precision or width is set. - if f.WidthPresent || f.PrecPresent { - // Account 3 extra bytes for possible addition of a sign and "0x". - width := 3 + f.Width + f.Prec // wid and prec are always positive. - if width > len(buf) { - // We're going to need a bigger boat. - buf = make([]byte, width) - } - } - - // Two ways to ask for extra leading zero digits: %.3d or %03d. - // If both are specified the f.zero flag is ignored and - // padding with spaces is used instead. - prec := 0 - if f.PrecPresent { - prec = f.Prec - // Precision of 0 and value of 0 means "print nothing" but padding. - if prec == 0 && u == 0 { - oldZero := f.Zero - f.Zero = false - f.writePadding(f.Width) - f.Zero = oldZero - return - } - } else if f.Zero && f.WidthPresent { - prec = f.Width - if negative || f.Plus || f.Space { - prec-- // leave room for sign - } - } - - // Because printing is easier right-to-left: format u into buf, ending at buf[i]. - // We could make things marginally faster by splitting the 32-bit case out - // into a separate block but it's not worth the duplication, so u has 64 bits. - i := len(buf) - // Use constants for the division and modulo for more efficient code. - // Switch cases ordered by popularity. - switch base { - case 10: - for u >= 10 { - i-- - next := u / 10 - buf[i] = byte('0' + u - next*10) - u = next - } - case 16: - for u >= 16 { - i-- - buf[i] = digits[u&0xF] - u >>= 4 - } - case 8: - for u >= 8 { - i-- - buf[i] = byte('0' + u&7) - u >>= 3 - } - case 2: - for u >= 2 { - i-- - buf[i] = byte('0' + u&1) - u >>= 1 - } - default: - panic("fmt: unknown base; can't happen") - } - i-- - buf[i] = digits[u] - for i > 0 && prec > len(buf)-i { - i-- - buf[i] = '0' - } - - // Various prefixes: 0x, -, etc. - if f.Sharp { - switch base { - case 8: - if buf[i] != '0' { - i-- - buf[i] = '0' - } - case 16: - // Add a leading 0x or 0X. - i-- - buf[i] = digits[16] - i-- - buf[i] = '0' - } - } - - if negative { - i-- - buf[i] = '-' - } else if f.Plus { - i-- - buf[i] = '+' - } else if f.Space { - i-- - buf[i] = ' ' - } - - // Left padding with zeros has already been handled like precision earlier - // or the f.zero flag is ignored due to an explicitly set precision. - oldZero := f.Zero - f.Zero = false - f.pad(buf[i:]) - f.Zero = oldZero -} - -// truncate truncates the string to the specified precision, if present. -func (f *formatInfo) truncate(s string) string { - if f.PrecPresent { - n := f.Prec - for i := range s { - n-- - if n < 0 { - return s[:i] - } - } - } - return s -} - -// fmt_s formats a string. -func (f *formatInfo) fmt_s(s string) { - s = f.truncate(s) - f.padString(s) -} - -// fmt_sbx formats a string or byte slice as a hexadecimal encoding of its bytes. -func (f *formatInfo) fmt_sbx(s string, b []byte, digits string) { - length := len(b) - if b == nil { - // No byte slice present. Assume string s should be encoded. - length = len(s) - } - // Set length to not process more bytes than the precision demands. - if f.PrecPresent && f.Prec < length { - length = f.Prec - } - // Compute width of the encoding taking into account the f.sharp and f.space flag. - width := 2 * length - if width > 0 { - if f.Space { - // Each element encoded by two hexadecimals will get a leading 0x or 0X. - if f.Sharp { - width *= 2 - } - // Elements will be separated by a space. - width += length - 1 - } else if f.Sharp { - // Only a leading 0x or 0X will be added for the whole string. - width += 2 - } - } else { // The byte slice or string that should be encoded is empty. - if f.WidthPresent { - f.writePadding(f.Width) - } - return - } - // Handle padding to the left. - if f.WidthPresent && f.Width > width && !f.Minus { - f.writePadding(f.Width - width) - } - // Write the encoding directly into the output buffer. - buf := f.buf - if f.Sharp { - // Add leading 0x or 0X. - buf.WriteByte('0') - buf.WriteByte(digits[16]) - } - var c byte - for i := 0; i < length; i++ { - if f.Space && i > 0 { - // Separate elements with a space. - buf.WriteByte(' ') - if f.Sharp { - // Add leading 0x or 0X for each element. - buf.WriteByte('0') - buf.WriteByte(digits[16]) - } - } - if b != nil { - c = b[i] // Take a byte from the input byte slice. - } else { - c = s[i] // Take a byte from the input string. - } - // Encode each byte as two hexadecimal digits. - buf.WriteByte(digits[c>>4]) - buf.WriteByte(digits[c&0xF]) - } - // Handle padding to the right. - if f.WidthPresent && f.Width > width && f.Minus { - f.writePadding(f.Width - width) - } -} - -// fmt_sx formats a string as a hexadecimal encoding of its bytes. -func (f *formatInfo) fmt_sx(s, digits string) { - f.fmt_sbx(s, nil, digits) -} - -// fmt_bx formats a byte slice as a hexadecimal encoding of its bytes. -func (f *formatInfo) fmt_bx(b []byte, digits string) { - f.fmt_sbx("", b, digits) -} - -// fmt_q formats a string as a double-quoted, escaped Go string constant. -// If f.sharp is set a raw (backquoted) string may be returned instead -// if the string does not contain any control characters other than tab. -func (f *formatInfo) fmt_q(s string) { - s = f.truncate(s) - if f.Sharp && strconv.CanBackquote(s) { - f.padString("`" + s + "`") - return - } - buf := f.intbuf[:0] - if f.Plus { - f.pad(strconv.AppendQuoteToASCII(buf, s)) - } else { - f.pad(strconv.AppendQuote(buf, s)) - } -} - -// fmt_c formats an integer as a Unicode character. -// If the character is not valid Unicode, it will print '\ufffd'. -func (f *formatInfo) fmt_c(c uint64) { - r := rune(c) - if c > utf8.MaxRune { - r = utf8.RuneError - } - buf := f.intbuf[:0] - w := utf8.EncodeRune(buf[:utf8.UTFMax], r) - f.pad(buf[:w]) -} - -// fmt_qc formats an integer as a single-quoted, escaped Go character constant. -// If the character is not valid Unicode, it will print '\ufffd'. -func (f *formatInfo) fmt_qc(c uint64) { - r := rune(c) - if c > utf8.MaxRune { - r = utf8.RuneError - } - buf := f.intbuf[:0] - if f.Plus { - f.pad(strconv.AppendQuoteRuneToASCII(buf, r)) - } else { - f.pad(strconv.AppendQuoteRune(buf, r)) - } -} - -// fmt_float formats a float64. It assumes that verb is a valid format specifier -// for strconv.AppendFloat and therefore fits into a byte. -func (f *formatInfo) fmt_float(v float64, size int, verb rune, prec int) { - // Explicit precision in format specifier overrules default precision. - if f.PrecPresent { - prec = f.Prec - } - // Format number, reserving space for leading + sign if needed. - num := strconv.AppendFloat(f.intbuf[:1], v, byte(verb), prec, size) - if num[1] == '-' || num[1] == '+' { - num = num[1:] - } else { - num[0] = '+' - } - // f.space means to add a leading space instead of a "+" sign unless - // the sign is explicitly asked for by f.plus. - if f.Space && num[0] == '+' && !f.Plus { - num[0] = ' ' - } - // Special handling for infinities and NaN, - // which don't look like a number so shouldn't be padded with zeros. - if num[1] == 'I' || num[1] == 'N' { - oldZero := f.Zero - f.Zero = false - // Remove sign before NaN if not asked for. - if num[1] == 'N' && !f.Space && !f.Plus { - num = num[1:] - } - f.pad(num) - f.Zero = oldZero - return - } - // The sharp flag forces printing a decimal point for non-binary formats - // and retains trailing zeros, which we may need to restore. - if f.Sharp && verb != 'b' { - digits := 0 - switch verb { - case 'v', 'g', 'G': - digits = prec - // If no precision is set explicitly use a precision of 6. - if digits == -1 { - digits = 6 - } - } - - // Buffer pre-allocated with enough room for - // exponent notations of the form "e+123". - var tailBuf [5]byte - tail := tailBuf[:0] - - hasDecimalPoint := false - // Starting from i = 1 to skip sign at num[0]. - for i := 1; i < len(num); i++ { - switch num[i] { - case '.': - hasDecimalPoint = true - case 'e', 'E': - tail = append(tail, num[i:]...) - num = num[:i] - default: - digits-- - } - } - if !hasDecimalPoint { - num = append(num, '.') - } - for digits > 0 { - num = append(num, '0') - digits-- - } - num = append(num, tail...) - } - // We want a sign if asked for and if the sign is not positive. - if f.Plus || num[0] != '+' { - // If we're zero padding to the left we want the sign before the leading zeros. - // Achieve this by writing the sign out and then padding the unsigned number. - if f.Zero && f.WidthPresent && f.Width > len(num) { - f.buf.WriteByte(num[0]) - f.writePadding(f.Width - len(num)) - f.buf.Write(num[1:]) - return - } - f.pad(num) - return - } - // No sign to show and the number is positive; just print the unsigned number. - f.pad(num[1:]) -} diff --git a/vendor/golang.org/x/text/message/message.go b/vendor/golang.org/x/text/message/message.go deleted file mode 100644 index 91a972642..000000000 --- a/vendor/golang.org/x/text/message/message.go +++ /dev/null @@ -1,192 +0,0 @@ -// 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 message // import "golang.org/x/text/message" - -import ( - "io" - "os" - - // Include features to facilitate generated catalogs. - _ "golang.org/x/text/feature/plural" - - "golang.org/x/text/internal/number" - "golang.org/x/text/language" - "golang.org/x/text/message/catalog" -) - -// A Printer implements language-specific formatted I/O analogous to the fmt -// package. -type Printer struct { - // the language - tag language.Tag - - toDecimal number.Formatter - toScientific number.Formatter - - cat catalog.Catalog -} - -type options struct { - cat catalog.Catalog - // TODO: - // - allow %s to print integers in written form (tables are likely too large - // to enable this by default). - // - list behavior - // -} - -// An Option defines an option of a Printer. -type Option func(o *options) - -// Catalog defines the catalog to be used. -func Catalog(c catalog.Catalog) Option { - return func(o *options) { o.cat = c } -} - -// NewPrinter returns a Printer that formats messages tailored to language t. -func NewPrinter(t language.Tag, opts ...Option) *Printer { - options := &options{ - cat: DefaultCatalog, - } - for _, o := range opts { - o(options) - } - p := &Printer{ - tag: t, - cat: options.cat, - } - p.toDecimal.InitDecimal(t) - p.toScientific.InitScientific(t) - return p -} - -// Sprint is like fmt.Sprint, but using language-specific formatting. -func (p *Printer) Sprint(a ...interface{}) string { - pp := newPrinter(p) - pp.doPrint(a) - s := pp.String() - pp.free() - return s -} - -// Fprint is like fmt.Fprint, but using language-specific formatting. -func (p *Printer) Fprint(w io.Writer, a ...interface{}) (n int, err error) { - pp := newPrinter(p) - pp.doPrint(a) - n64, err := io.Copy(w, &pp.Buffer) - pp.free() - return int(n64), err -} - -// Print is like fmt.Print, but using language-specific formatting. -func (p *Printer) Print(a ...interface{}) (n int, err error) { - return p.Fprint(os.Stdout, a...) -} - -// Sprintln is like fmt.Sprintln, but using language-specific formatting. -func (p *Printer) Sprintln(a ...interface{}) string { - pp := newPrinter(p) - pp.doPrintln(a) - s := pp.String() - pp.free() - return s -} - -// Fprintln is like fmt.Fprintln, but using language-specific formatting. -func (p *Printer) Fprintln(w io.Writer, a ...interface{}) (n int, err error) { - pp := newPrinter(p) - pp.doPrintln(a) - n64, err := io.Copy(w, &pp.Buffer) - pp.free() - return int(n64), err -} - -// Println is like fmt.Println, but using language-specific formatting. -func (p *Printer) Println(a ...interface{}) (n int, err error) { - return p.Fprintln(os.Stdout, a...) -} - -// Sprintf is like fmt.Sprintf, but using language-specific formatting. -func (p *Printer) Sprintf(key Reference, a ...interface{}) string { - pp := newPrinter(p) - lookupAndFormat(pp, key, a) - s := pp.String() - pp.free() - return s -} - -// Fprintf is like fmt.Fprintf, but using language-specific formatting. -func (p *Printer) Fprintf(w io.Writer, key Reference, a ...interface{}) (n int, err error) { - pp := newPrinter(p) - lookupAndFormat(pp, key, a) - n, err = w.Write(pp.Bytes()) - pp.free() - return n, err - -} - -// Printf is like fmt.Printf, but using language-specific formatting. -func (p *Printer) Printf(key Reference, a ...interface{}) (n int, err error) { - pp := newPrinter(p) - lookupAndFormat(pp, key, a) - n, err = os.Stdout.Write(pp.Bytes()) - pp.free() - return n, err -} - -func lookupAndFormat(p *printer, r Reference, a []interface{}) { - p.fmt.Reset(a) - switch v := r.(type) { - case string: - if p.catContext.Execute(v) == catalog.ErrNotFound { - p.Render(v) - return - } - case key: - if p.catContext.Execute(v.id) == catalog.ErrNotFound && - p.catContext.Execute(v.fallback) == catalog.ErrNotFound { - p.Render(v.fallback) - return - } - default: - panic("key argument is not a Reference") - } -} - -type rawPrinter struct { - p *printer -} - -func (p rawPrinter) Render(msg string) { p.p.WriteString(msg) } -func (p rawPrinter) Arg(i int) interface{} { return nil } - -// Arg implements catmsg.Renderer. -func (p *printer) Arg(i int) interface{} { // TODO, also return "ok" bool - i-- - if uint(i) < uint(len(p.fmt.Args)) { - return p.fmt.Args[i] - } - return nil -} - -// Render implements catmsg.Renderer. -func (p *printer) Render(msg string) { - p.doPrintf(msg) -} - -// A Reference is a string or a message reference. -type Reference interface { - // TODO: also allow []string -} - -// Key creates a message Reference for a message where the given id is used for -// message lookup and the fallback is returned when no matches are found. -func Key(id string, fallback string) Reference { - return key{id, fallback} -} - -type key struct { - id, fallback string -} diff --git a/vendor/golang.org/x/text/message/print.go b/vendor/golang.org/x/text/message/print.go deleted file mode 100644 index da304cc0e..000000000 --- a/vendor/golang.org/x/text/message/print.go +++ /dev/null @@ -1,984 +0,0 @@ -// 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 message - -import ( - "bytes" - "fmt" // TODO: consider copying interfaces from package fmt to avoid dependency. - "math" - "reflect" - "sync" - "unicode/utf8" - - "golang.org/x/text/internal/format" - "golang.org/x/text/internal/number" - "golang.org/x/text/language" - "golang.org/x/text/message/catalog" -) - -// Strings for use with buffer.WriteString. -// This is less overhead than using buffer.Write with byte arrays. -const ( - commaSpaceString = ", " - nilAngleString = "" - nilParenString = "(nil)" - nilString = "nil" - mapString = "map[" - percentBangString = "%!" - missingString = "(MISSING)" - badIndexString = "(BADINDEX)" - panicString = "(PANIC=" - extraString = "%!(EXTRA " - badWidthString = "%!(BADWIDTH)" - badPrecString = "%!(BADPREC)" - noVerbString = "%!(NOVERB)" - - invReflectString = "" -) - -var printerPool = sync.Pool{ - New: func() interface{} { return new(printer) }, -} - -// newPrinter allocates a new printer struct or grabs a cached one. -func newPrinter(pp *Printer) *printer { - p := printerPool.Get().(*printer) - p.Printer = *pp - // TODO: cache most of the following call. - p.catContext = pp.cat.Context(pp.tag, p) - - p.panicking = false - p.erroring = false - p.fmt.init(&p.Buffer) - return p -} - -// free saves used printer structs in printerFree; avoids an allocation per invocation. -func (p *printer) free() { - p.Buffer.Reset() - p.arg = nil - p.value = reflect.Value{} - printerPool.Put(p) -} - -// printer is used to store a printer's state. -// It implements "golang.org/x/text/internal/format".State. -type printer struct { - Printer - - // the context for looking up message translations - catContext *catalog.Context - - // buffer for accumulating output. - bytes.Buffer - - // arg holds the current item, as an interface{}. - arg interface{} - // value is used instead of arg for reflect values. - value reflect.Value - - // fmt is used to format basic items such as integers or strings. - fmt formatInfo - - // panicking is set by catchPanic to avoid infinite panic, recover, panic, ... recursion. - panicking bool - // erroring is set when printing an error string to guard against calling handleMethods. - erroring bool -} - -// Language implements "golang.org/x/text/internal/format".State. -func (p *printer) Language() language.Tag { return p.tag } - -func (p *printer) Width() (wid int, ok bool) { return p.fmt.Width, p.fmt.WidthPresent } - -func (p *printer) Precision() (prec int, ok bool) { return p.fmt.Prec, p.fmt.PrecPresent } - -func (p *printer) Flag(b int) bool { - switch b { - case '-': - return p.fmt.Minus - case '+': - return p.fmt.Plus || p.fmt.PlusV - case '#': - return p.fmt.Sharp || p.fmt.SharpV - case ' ': - return p.fmt.Space - case '0': - return p.fmt.Zero - } - return false -} - -// getField gets the i'th field of the struct value. -// If the field is itself is an interface, return a value for -// the thing inside the interface, not the interface itself. -func getField(v reflect.Value, i int) reflect.Value { - val := v.Field(i) - if val.Kind() == reflect.Interface && !val.IsNil() { - val = val.Elem() - } - return val -} - -func (p *printer) unknownType(v reflect.Value) { - if !v.IsValid() { - p.WriteString(nilAngleString) - return - } - p.WriteByte('?') - p.WriteString(v.Type().String()) - p.WriteByte('?') -} - -func (p *printer) badVerb(verb rune) { - p.erroring = true - p.WriteString(percentBangString) - p.WriteRune(verb) - p.WriteByte('(') - switch { - case p.arg != nil: - p.WriteString(reflect.TypeOf(p.arg).String()) - p.WriteByte('=') - p.printArg(p.arg, 'v') - case p.value.IsValid(): - p.WriteString(p.value.Type().String()) - p.WriteByte('=') - p.printValue(p.value, 'v', 0) - default: - p.WriteString(nilAngleString) - } - p.WriteByte(')') - p.erroring = false -} - -func (p *printer) fmtBool(v bool, verb rune) { - switch verb { - case 't', 'v': - p.fmt.fmt_boolean(v) - default: - p.badVerb(verb) - } -} - -// fmt0x64 formats a uint64 in hexadecimal and prefixes it with 0x or -// not, as requested, by temporarily setting the sharp flag. -func (p *printer) fmt0x64(v uint64, leading0x bool) { - sharp := p.fmt.Sharp - p.fmt.Sharp = leading0x - p.fmt.fmt_integer(v, 16, unsigned, ldigits) - p.fmt.Sharp = sharp -} - -// fmtInteger formats a signed or unsigned integer. -func (p *printer) fmtInteger(v uint64, isSigned bool, verb rune) { - switch verb { - case 'v': - if p.fmt.SharpV && !isSigned { - p.fmt0x64(v, true) - return - } - fallthrough - case 'd': - if p.fmt.Sharp || p.fmt.SharpV { - p.fmt.fmt_integer(v, 10, isSigned, ldigits) - } else { - p.fmtDecimalInt(v, isSigned) - } - case 'b': - p.fmt.fmt_integer(v, 2, isSigned, ldigits) - case 'o': - p.fmt.fmt_integer(v, 8, isSigned, ldigits) - case 'x': - p.fmt.fmt_integer(v, 16, isSigned, ldigits) - case 'X': - p.fmt.fmt_integer(v, 16, isSigned, udigits) - case 'c': - p.fmt.fmt_c(v) - case 'q': - if v <= utf8.MaxRune { - p.fmt.fmt_qc(v) - } else { - p.badVerb(verb) - } - case 'U': - p.fmt.fmt_unicode(v) - default: - p.badVerb(verb) - } -} - -// fmtFloat formats a float. The default precision for each verb -// is specified as last argument in the call to fmt_float. -func (p *printer) fmtFloat(v float64, size int, verb rune) { - switch verb { - case 'b': - p.fmt.fmt_float(v, size, verb, -1) - case 'v': - verb = 'g' - fallthrough - case 'g', 'G': - if p.fmt.Sharp || p.fmt.SharpV { - p.fmt.fmt_float(v, size, verb, -1) - } else { - p.fmtVariableFloat(v, size) - } - case 'e', 'E': - if p.fmt.Sharp || p.fmt.SharpV { - p.fmt.fmt_float(v, size, verb, 6) - } else { - p.fmtScientific(v, size, 6) - } - case 'f', 'F': - if p.fmt.Sharp || p.fmt.SharpV { - p.fmt.fmt_float(v, size, verb, 6) - } else { - p.fmtDecimalFloat(v, size, 6) - } - default: - p.badVerb(verb) - } -} - -func (p *printer) setFlags(f *number.Formatter) { - f.Flags &^= number.ElideSign - if p.fmt.Plus || p.fmt.Space { - f.Flags |= number.AlwaysSign - if !p.fmt.Plus { - f.Flags |= number.ElideSign - } - } else { - f.Flags &^= number.AlwaysSign - } -} - -func (p *printer) updatePadding(f *number.Formatter) { - f.Flags &^= number.PadMask - if p.fmt.Minus { - f.Flags |= number.PadAfterSuffix - } else { - f.Flags |= number.PadBeforePrefix - } - f.PadRune = ' ' - f.FormatWidth = uint16(p.fmt.Width) -} - -func (p *printer) initDecimal(minFrac, maxFrac int) { - f := &p.toDecimal - f.MinIntegerDigits = 1 - f.MaxIntegerDigits = 0 - f.MinFractionDigits = uint8(minFrac) - f.MaxFractionDigits = int16(maxFrac) - p.setFlags(f) - f.PadRune = 0 - if p.fmt.WidthPresent { - if p.fmt.Zero { - wid := p.fmt.Width - // Use significant integers for this. - // TODO: this is not the same as width, but so be it. - if f.MinFractionDigits > 0 { - wid -= 1 + int(f.MinFractionDigits) - } - if p.fmt.Plus || p.fmt.Space { - wid-- - } - if wid > 0 && wid > int(f.MinIntegerDigits) { - f.MinIntegerDigits = uint8(wid) - } - } - p.updatePadding(f) - } -} - -func (p *printer) initScientific(minFrac, maxFrac int) { - f := &p.toScientific - if maxFrac < 0 { - f.SetPrecision(maxFrac) - } else { - f.SetPrecision(maxFrac + 1) - f.MinFractionDigits = uint8(minFrac) - f.MaxFractionDigits = int16(maxFrac) - } - f.MinExponentDigits = 2 - p.setFlags(f) - f.PadRune = 0 - if p.fmt.WidthPresent { - f.Flags &^= number.PadMask - if p.fmt.Zero { - f.PadRune = f.Digit(0) - f.Flags |= number.PadAfterPrefix - } else { - f.PadRune = ' ' - f.Flags |= number.PadBeforePrefix - } - p.updatePadding(f) - } -} - -func (p *printer) fmtDecimalInt(v uint64, isSigned bool) { - var d number.Decimal - - f := &p.toDecimal - if p.fmt.PrecPresent { - p.setFlags(f) - f.MinIntegerDigits = uint8(p.fmt.Prec) - f.MaxIntegerDigits = 0 - f.MinFractionDigits = 0 - f.MaxFractionDigits = 0 - if p.fmt.WidthPresent { - p.updatePadding(f) - } - } else { - p.initDecimal(0, 0) - } - d.ConvertInt(p.toDecimal.RoundingContext, isSigned, v) - - out := p.toDecimal.Format([]byte(nil), &d) - p.Buffer.Write(out) -} - -func (p *printer) fmtDecimalFloat(v float64, size, prec int) { - var d number.Decimal - if p.fmt.PrecPresent { - prec = p.fmt.Prec - } - p.initDecimal(prec, prec) - d.ConvertFloat(p.toDecimal.RoundingContext, v, size) - - out := p.toDecimal.Format([]byte(nil), &d) - p.Buffer.Write(out) -} - -func (p *printer) fmtVariableFloat(v float64, size int) { - prec := -1 - if p.fmt.PrecPresent { - prec = p.fmt.Prec - } - var d number.Decimal - p.initScientific(0, prec) - d.ConvertFloat(p.toScientific.RoundingContext, v, size) - - // Copy logic of 'g' formatting from strconv. It is simplified a bit as - // we don't have to mind having prec > len(d.Digits). - shortest := prec < 0 - ePrec := prec - if shortest { - prec = len(d.Digits) - ePrec = 6 - } else if prec == 0 { - prec = 1 - ePrec = 1 - } - exp := int(d.Exp) - 1 - if exp < -4 || exp >= ePrec { - p.initScientific(0, prec) - - out := p.toScientific.Format([]byte(nil), &d) - p.Buffer.Write(out) - } else { - if prec > int(d.Exp) { - prec = len(d.Digits) - } - if prec -= int(d.Exp); prec < 0 { - prec = 0 - } - p.initDecimal(0, prec) - - out := p.toDecimal.Format([]byte(nil), &d) - p.Buffer.Write(out) - } -} - -func (p *printer) fmtScientific(v float64, size, prec int) { - var d number.Decimal - if p.fmt.PrecPresent { - prec = p.fmt.Prec - } - p.initScientific(prec, prec) - rc := p.toScientific.RoundingContext - d.ConvertFloat(rc, v, size) - - out := p.toScientific.Format([]byte(nil), &d) - p.Buffer.Write(out) - -} - -// fmtComplex formats a complex number v with -// r = real(v) and j = imag(v) as (r+ji) using -// fmtFloat for r and j formatting. -func (p *printer) fmtComplex(v complex128, size int, verb rune) { - // Make sure any unsupported verbs are found before the - // calls to fmtFloat to not generate an incorrect error string. - switch verb { - case 'v', 'b', 'g', 'G', 'f', 'F', 'e', 'E': - p.WriteByte('(') - p.fmtFloat(real(v), size/2, verb) - // Imaginary part always has a sign. - if math.IsNaN(imag(v)) { - // By CLDR's rules, NaNs do not use patterns or signs. As this code - // relies on AlwaysSign working for imaginary parts, we need to - // manually handle NaNs. - f := &p.toScientific - p.setFlags(f) - p.updatePadding(f) - p.setFlags(f) - nan := f.Symbol(number.SymNan) - extra := 0 - if w, ok := p.Width(); ok { - extra = w - utf8.RuneCountInString(nan) - 1 - } - if f.Flags&number.PadAfterNumber == 0 { - for ; extra > 0; extra-- { - p.WriteRune(f.PadRune) - } - } - p.WriteString(f.Symbol(number.SymPlusSign)) - p.WriteString(nan) - for ; extra > 0; extra-- { - p.WriteRune(f.PadRune) - } - p.WriteString("i)") - return - } - oldPlus := p.fmt.Plus - p.fmt.Plus = true - p.fmtFloat(imag(v), size/2, verb) - p.WriteString("i)") // TODO: use symbol? - p.fmt.Plus = oldPlus - default: - p.badVerb(verb) - } -} - -func (p *printer) fmtString(v string, verb rune) { - switch verb { - case 'v': - if p.fmt.SharpV { - p.fmt.fmt_q(v) - } else { - p.fmt.fmt_s(v) - } - case 's': - p.fmt.fmt_s(v) - case 'x': - p.fmt.fmt_sx(v, ldigits) - case 'X': - p.fmt.fmt_sx(v, udigits) - case 'q': - p.fmt.fmt_q(v) - case 'm': - ctx := p.cat.Context(p.tag, rawPrinter{p}) - if ctx.Execute(v) == catalog.ErrNotFound { - p.WriteString(v) - } - default: - p.badVerb(verb) - } -} - -func (p *printer) fmtBytes(v []byte, verb rune, typeString string) { - switch verb { - case 'v', 'd': - if p.fmt.SharpV { - p.WriteString(typeString) - if v == nil { - p.WriteString(nilParenString) - return - } - p.WriteByte('{') - for i, c := range v { - if i > 0 { - p.WriteString(commaSpaceString) - } - p.fmt0x64(uint64(c), true) - } - p.WriteByte('}') - } else { - p.WriteByte('[') - for i, c := range v { - if i > 0 { - p.WriteByte(' ') - } - p.fmt.fmt_integer(uint64(c), 10, unsigned, ldigits) - } - p.WriteByte(']') - } - case 's': - p.fmt.fmt_s(string(v)) - case 'x': - p.fmt.fmt_bx(v, ldigits) - case 'X': - p.fmt.fmt_bx(v, udigits) - case 'q': - p.fmt.fmt_q(string(v)) - default: - p.printValue(reflect.ValueOf(v), verb, 0) - } -} - -func (p *printer) fmtPointer(value reflect.Value, verb rune) { - var u uintptr - switch value.Kind() { - case reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr, reflect.Slice, reflect.UnsafePointer: - u = value.Pointer() - default: - p.badVerb(verb) - return - } - - switch verb { - case 'v': - if p.fmt.SharpV { - p.WriteByte('(') - p.WriteString(value.Type().String()) - p.WriteString(")(") - if u == 0 { - p.WriteString(nilString) - } else { - p.fmt0x64(uint64(u), true) - } - p.WriteByte(')') - } else { - if u == 0 { - p.fmt.padString(nilAngleString) - } else { - p.fmt0x64(uint64(u), !p.fmt.Sharp) - } - } - case 'p': - p.fmt0x64(uint64(u), !p.fmt.Sharp) - case 'b', 'o', 'd', 'x', 'X': - if verb == 'd' { - p.fmt.Sharp = true // Print as standard go. TODO: does this make sense? - } - p.fmtInteger(uint64(u), unsigned, verb) - default: - p.badVerb(verb) - } -} - -func (p *printer) catchPanic(arg interface{}, verb rune) { - if err := recover(); err != nil { - // If it's a nil pointer, just say "". The likeliest causes are a - // Stringer that fails to guard against nil or a nil pointer for a - // value receiver, and in either case, "" is a nice result. - if v := reflect.ValueOf(arg); v.Kind() == reflect.Ptr && v.IsNil() { - p.WriteString(nilAngleString) - return - } - // Otherwise print a concise panic message. Most of the time the panic - // value will print itself nicely. - if p.panicking { - // Nested panics; the recursion in printArg cannot succeed. - panic(err) - } - - oldFlags := p.fmt.Parser - // For this output we want default behavior. - p.fmt.ClearFlags() - - p.WriteString(percentBangString) - p.WriteRune(verb) - p.WriteString(panicString) - p.panicking = true - p.printArg(err, 'v') - p.panicking = false - p.WriteByte(')') - - p.fmt.Parser = oldFlags - } -} - -func (p *printer) handleMethods(verb rune) (handled bool) { - if p.erroring { - return - } - // Is it a Formatter? - if formatter, ok := p.arg.(format.Formatter); ok { - handled = true - defer p.catchPanic(p.arg, verb) - formatter.Format(p, verb) - return - } - if formatter, ok := p.arg.(fmt.Formatter); ok { - handled = true - defer p.catchPanic(p.arg, verb) - formatter.Format(p, verb) - return - } - - // If we're doing Go syntax and the argument knows how to supply it, take care of it now. - if p.fmt.SharpV { - if stringer, ok := p.arg.(fmt.GoStringer); ok { - handled = true - defer p.catchPanic(p.arg, verb) - // Print the result of GoString unadorned. - p.fmt.fmt_s(stringer.GoString()) - return - } - } else { - // If a string is acceptable according to the format, see if - // the value satisfies one of the string-valued interfaces. - // Println etc. set verb to %v, which is "stringable". - switch verb { - case 'v', 's', 'x', 'X', 'q': - // Is it an error or Stringer? - // The duplication in the bodies is necessary: - // setting handled and deferring catchPanic - // must happen before calling the method. - switch v := p.arg.(type) { - case error: - handled = true - defer p.catchPanic(p.arg, verb) - p.fmtString(v.Error(), verb) - return - - case fmt.Stringer: - handled = true - defer p.catchPanic(p.arg, verb) - p.fmtString(v.String(), verb) - return - } - } - } - return false -} - -func (p *printer) printArg(arg interface{}, verb rune) { - p.arg = arg - p.value = reflect.Value{} - - if arg == nil { - switch verb { - case 'T', 'v': - p.fmt.padString(nilAngleString) - default: - p.badVerb(verb) - } - return - } - - // Special processing considerations. - // %T (the value's type) and %p (its address) are special; we always do them first. - switch verb { - case 'T': - p.fmt.fmt_s(reflect.TypeOf(arg).String()) - return - case 'p': - p.fmtPointer(reflect.ValueOf(arg), 'p') - return - } - - // Some types can be done without reflection. - switch f := arg.(type) { - case bool: - p.fmtBool(f, verb) - case float32: - p.fmtFloat(float64(f), 32, verb) - case float64: - p.fmtFloat(f, 64, verb) - case complex64: - p.fmtComplex(complex128(f), 64, verb) - case complex128: - p.fmtComplex(f, 128, verb) - case int: - p.fmtInteger(uint64(f), signed, verb) - case int8: - p.fmtInteger(uint64(f), signed, verb) - case int16: - p.fmtInteger(uint64(f), signed, verb) - case int32: - p.fmtInteger(uint64(f), signed, verb) - case int64: - p.fmtInteger(uint64(f), signed, verb) - case uint: - p.fmtInteger(uint64(f), unsigned, verb) - case uint8: - p.fmtInteger(uint64(f), unsigned, verb) - case uint16: - p.fmtInteger(uint64(f), unsigned, verb) - case uint32: - p.fmtInteger(uint64(f), unsigned, verb) - case uint64: - p.fmtInteger(f, unsigned, verb) - case uintptr: - p.fmtInteger(uint64(f), unsigned, verb) - case string: - p.fmtString(f, verb) - case []byte: - p.fmtBytes(f, verb, "[]byte") - case reflect.Value: - // Handle extractable values with special methods - // since printValue does not handle them at depth 0. - if f.IsValid() && f.CanInterface() { - p.arg = f.Interface() - if p.handleMethods(verb) { - return - } - } - p.printValue(f, verb, 0) - default: - // If the type is not simple, it might have methods. - if !p.handleMethods(verb) { - // Need to use reflection, since the type had no - // interface methods that could be used for formatting. - p.printValue(reflect.ValueOf(f), verb, 0) - } - } -} - -// printValue is similar to printArg but starts with a reflect value, not an interface{} value. -// It does not handle 'p' and 'T' verbs because these should have been already handled by printArg. -func (p *printer) printValue(value reflect.Value, verb rune, depth int) { - // Handle values with special methods if not already handled by printArg (depth == 0). - if depth > 0 && value.IsValid() && value.CanInterface() { - p.arg = value.Interface() - if p.handleMethods(verb) { - return - } - } - p.arg = nil - p.value = value - - switch f := value; value.Kind() { - case reflect.Invalid: - if depth == 0 { - p.WriteString(invReflectString) - } else { - switch verb { - case 'v': - p.WriteString(nilAngleString) - default: - p.badVerb(verb) - } - } - case reflect.Bool: - p.fmtBool(f.Bool(), verb) - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - p.fmtInteger(uint64(f.Int()), signed, verb) - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - p.fmtInteger(f.Uint(), unsigned, verb) - case reflect.Float32: - p.fmtFloat(f.Float(), 32, verb) - case reflect.Float64: - p.fmtFloat(f.Float(), 64, verb) - case reflect.Complex64: - p.fmtComplex(f.Complex(), 64, verb) - case reflect.Complex128: - p.fmtComplex(f.Complex(), 128, verb) - case reflect.String: - p.fmtString(f.String(), verb) - case reflect.Map: - if p.fmt.SharpV { - p.WriteString(f.Type().String()) - if f.IsNil() { - p.WriteString(nilParenString) - return - } - p.WriteByte('{') - } else { - p.WriteString(mapString) - } - keys := f.MapKeys() - for i, key := range keys { - if i > 0 { - if p.fmt.SharpV { - p.WriteString(commaSpaceString) - } else { - p.WriteByte(' ') - } - } - p.printValue(key, verb, depth+1) - p.WriteByte(':') - p.printValue(f.MapIndex(key), verb, depth+1) - } - if p.fmt.SharpV { - p.WriteByte('}') - } else { - p.WriteByte(']') - } - case reflect.Struct: - if p.fmt.SharpV { - p.WriteString(f.Type().String()) - } - p.WriteByte('{') - for i := 0; i < f.NumField(); i++ { - if i > 0 { - if p.fmt.SharpV { - p.WriteString(commaSpaceString) - } else { - p.WriteByte(' ') - } - } - if p.fmt.PlusV || p.fmt.SharpV { - if name := f.Type().Field(i).Name; name != "" { - p.WriteString(name) - p.WriteByte(':') - } - } - p.printValue(getField(f, i), verb, depth+1) - } - p.WriteByte('}') - case reflect.Interface: - value := f.Elem() - if !value.IsValid() { - if p.fmt.SharpV { - p.WriteString(f.Type().String()) - p.WriteString(nilParenString) - } else { - p.WriteString(nilAngleString) - } - } else { - p.printValue(value, verb, depth+1) - } - case reflect.Array, reflect.Slice: - switch verb { - case 's', 'q', 'x', 'X': - // Handle byte and uint8 slices and arrays special for the above verbs. - t := f.Type() - if t.Elem().Kind() == reflect.Uint8 { - var bytes []byte - if f.Kind() == reflect.Slice { - bytes = f.Bytes() - } else if f.CanAddr() { - bytes = f.Slice(0, f.Len()).Bytes() - } else { - // We have an array, but we cannot Slice() a non-addressable array, - // so we build a slice by hand. This is a rare case but it would be nice - // if reflection could help a little more. - bytes = make([]byte, f.Len()) - for i := range bytes { - bytes[i] = byte(f.Index(i).Uint()) - } - } - p.fmtBytes(bytes, verb, t.String()) - return - } - } - if p.fmt.SharpV { - p.WriteString(f.Type().String()) - if f.Kind() == reflect.Slice && f.IsNil() { - p.WriteString(nilParenString) - return - } - p.WriteByte('{') - for i := 0; i < f.Len(); i++ { - if i > 0 { - p.WriteString(commaSpaceString) - } - p.printValue(f.Index(i), verb, depth+1) - } - p.WriteByte('}') - } else { - p.WriteByte('[') - for i := 0; i < f.Len(); i++ { - if i > 0 { - p.WriteByte(' ') - } - p.printValue(f.Index(i), verb, depth+1) - } - p.WriteByte(']') - } - case reflect.Ptr: - // pointer to array or slice or struct? ok at top level - // but not embedded (avoid loops) - if depth == 0 && f.Pointer() != 0 { - switch a := f.Elem(); a.Kind() { - case reflect.Array, reflect.Slice, reflect.Struct, reflect.Map: - p.WriteByte('&') - p.printValue(a, verb, depth+1) - return - } - } - fallthrough - case reflect.Chan, reflect.Func, reflect.UnsafePointer: - p.fmtPointer(f, verb) - default: - p.unknownType(f) - } -} - -func (p *printer) badArgNum(verb rune) { - p.WriteString(percentBangString) - p.WriteRune(verb) - p.WriteString(badIndexString) -} - -func (p *printer) missingArg(verb rune) { - p.WriteString(percentBangString) - p.WriteRune(verb) - p.WriteString(missingString) -} - -func (p *printer) doPrintf(fmt string) { - for p.fmt.Parser.SetFormat(fmt); p.fmt.Scan(); { - switch p.fmt.Status { - case format.StatusText: - p.WriteString(p.fmt.Text()) - case format.StatusSubstitution: - p.printArg(p.Arg(p.fmt.ArgNum), p.fmt.Verb) - case format.StatusBadWidthSubstitution: - p.WriteString(badWidthString) - p.printArg(p.Arg(p.fmt.ArgNum), p.fmt.Verb) - case format.StatusBadPrecSubstitution: - p.WriteString(badPrecString) - p.printArg(p.Arg(p.fmt.ArgNum), p.fmt.Verb) - case format.StatusNoVerb: - p.WriteString(noVerbString) - case format.StatusBadArgNum: - p.badArgNum(p.fmt.Verb) - case format.StatusMissingArg: - p.missingArg(p.fmt.Verb) - default: - panic("unreachable") - } - } - - // Check for extra arguments, but only if there was at least one ordered - // argument. Note that this behavior is necessarily different from fmt: - // different variants of messages may opt to drop some or all of the - // arguments. - if !p.fmt.Reordered && p.fmt.ArgNum < len(p.fmt.Args) && p.fmt.ArgNum != 0 { - p.fmt.ClearFlags() - p.WriteString(extraString) - for i, arg := range p.fmt.Args[p.fmt.ArgNum:] { - if i > 0 { - p.WriteString(commaSpaceString) - } - if arg == nil { - p.WriteString(nilAngleString) - } else { - p.WriteString(reflect.TypeOf(arg).String()) - p.WriteString("=") - p.printArg(arg, 'v') - } - } - p.WriteByte(')') - } -} - -func (p *printer) doPrint(a []interface{}) { - prevString := false - for argNum, arg := range a { - isString := arg != nil && reflect.TypeOf(arg).Kind() == reflect.String - // Add a space between two non-string arguments. - if argNum > 0 && !isString && !prevString { - p.WriteByte(' ') - } - p.printArg(arg, 'v') - prevString = isString - } -} - -// doPrintln is like doPrint but always adds a space between arguments -// and a newline after the last argument. -func (p *printer) doPrintln(a []interface{}) { - for argNum, arg := range a { - if argNum > 0 { - p.WriteByte(' ') - } - p.printArg(arg, 'v') - } - p.WriteByte('\n') -} diff --git a/vendor/modules.txt b/vendor/modules.txt index b7fb68df9..b5a81eb56 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1,4 +1,4 @@ -# cel.dev/expr v0.19.1 +# cel.dev/expr v0.21.2 ## explicit; go 1.21.1 cel.dev/expr # github.com/antlr4-go/antlr/v4 v4.13.0 @@ -11,20 +11,6 @@ github.com/stoewer/go-strcase ## explicit; go 1.20 golang.org/x/exp/constraints golang.org/x/exp/slices -# golang.org/x/text v0.16.0 -## explicit; go 1.18 -golang.org/x/text/feature/plural -golang.org/x/text/internal -golang.org/x/text/internal/catmsg -golang.org/x/text/internal/format -golang.org/x/text/internal/language -golang.org/x/text/internal/language/compact -golang.org/x/text/internal/number -golang.org/x/text/internal/stringset -golang.org/x/text/internal/tag -golang.org/x/text/language -golang.org/x/text/message -golang.org/x/text/message/catalog # google.golang.org/genproto/googleapis/api v0.0.0-20240826202546-f6391c0de4c7 ## explicit; go 1.21 google.golang.org/genproto/googleapis/api/expr/v1alpha1 From a268e76921c4cff97cb8eb7d9c5e7f6a11119a56 Mon Sep 17 00:00:00 2001 From: Justin King Date: Wed, 19 Feb 2025 15:11:41 -0800 Subject: [PATCH 2/7] Remove usage of ext.Format from repl Signed-off-by: Justin King --- repl/evaluator.go | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/repl/evaluator.go b/repl/evaluator.go index c26b09c62..5563f15e9 100644 --- a/repl/evaluator.go +++ b/repl/evaluator.go @@ -1002,13 +1002,7 @@ func (e *Evaluator) Process(cmd Cmder) (string, bool, error) { if ok { return fmt.Sprintf("Unknown %v", unknown), false, nil } - v, err := ext.FormatString(val, "") - - if err != nil { - // Default format if type is unsupported by ext.Strings formatter. - return fmt.Sprintf("%v : %s", val.Value(), t), false, nil - } - return fmt.Sprintf("%s : %s", v, t), false, nil + return fmt.Sprintf("%s : %s", val, t), false, nil } case *letVarCmd: var err error From e777be945e1bb6281aea2b167f06f07aebc4b9a9 Mon Sep 17 00:00:00 2001 From: Justin King Date: Fri, 21 Feb 2025 09:45:23 -0800 Subject: [PATCH 3/7] Update strings.format changes to be versioned Signed-off-by: Justin King --- ext/formatting.go | 642 +-- ext/formatting_test.go | 1136 ++++++ ext/formatting_v2.go | 772 ++++ ext/formatting_v2_test.go | 1015 +++++ ext/strings.go | 82 +- ext/strings_test.go | 977 ----- go.mod | 1 + go.sum | 2 + vendor/golang.org/x/text/LICENSE | 27 + vendor/golang.org/x/text/PATENTS | 22 + .../x/text/feature/plural/common.go | 70 + .../x/text/feature/plural/message.go | 244 ++ .../x/text/feature/plural/plural.go | 262 ++ .../x/text/feature/plural/tables.go | 552 +++ .../x/text/internal/catmsg/catmsg.go | 417 ++ .../x/text/internal/catmsg/codec.go | 407 ++ .../x/text/internal/catmsg/varint.go | 62 + .../x/text/internal/format/format.go | 41 + .../x/text/internal/format/parser.go | 358 ++ vendor/golang.org/x/text/internal/internal.go | 49 + .../x/text/internal/language/common.go | 16 + .../x/text/internal/language/compact.go | 29 + .../text/internal/language/compact/compact.go | 61 + .../internal/language/compact/language.go | 260 ++ .../text/internal/language/compact/parents.go | 120 + .../text/internal/language/compact/tables.go | 1015 +++++ .../x/text/internal/language/compact/tags.go | 91 + .../x/text/internal/language/compose.go | 167 + .../x/text/internal/language/coverage.go | 28 + .../x/text/internal/language/language.go | 627 +++ .../x/text/internal/language/lookup.go | 412 ++ .../x/text/internal/language/match.go | 226 ++ .../x/text/internal/language/parse.go | 608 +++ .../x/text/internal/language/tables.go | 3494 +++++++++++++++++ .../x/text/internal/language/tags.go | 48 + vendor/golang.org/x/text/internal/match.go | 67 + .../x/text/internal/number/common.go | 55 + .../x/text/internal/number/decimal.go | 500 +++ .../x/text/internal/number/format.go | 535 +++ .../x/text/internal/number/number.go | 152 + .../x/text/internal/number/pattern.go | 485 +++ .../internal/number/roundingmode_string.go | 30 + .../x/text/internal/number/tables.go | 1219 ++++++ .../x/text/internal/stringset/set.go | 86 + vendor/golang.org/x/text/internal/tag/tag.go | 100 + vendor/golang.org/x/text/language/coverage.go | 187 + vendor/golang.org/x/text/language/doc.go | 98 + vendor/golang.org/x/text/language/language.go | 605 +++ vendor/golang.org/x/text/language/match.go | 735 ++++ vendor/golang.org/x/text/language/parse.go | 256 ++ vendor/golang.org/x/text/language/tables.go | 298 ++ vendor/golang.org/x/text/language/tags.go | 145 + vendor/golang.org/x/text/message/catalog.go | 36 + .../x/text/message/catalog/catalog.go | 365 ++ .../golang.org/x/text/message/catalog/dict.go | 129 + .../golang.org/x/text/message/catalog/go19.go | 15 + .../x/text/message/catalog/gopre19.go | 23 + vendor/golang.org/x/text/message/doc.go | 99 + vendor/golang.org/x/text/message/format.go | 510 +++ vendor/golang.org/x/text/message/message.go | 192 + vendor/golang.org/x/text/message/print.go | 984 +++++ vendor/modules.txt | 14 + 62 files changed, 20944 insertions(+), 1316 deletions(-) create mode 100644 ext/formatting_test.go create mode 100644 ext/formatting_v2.go create mode 100644 ext/formatting_v2_test.go create mode 100644 vendor/golang.org/x/text/LICENSE create mode 100644 vendor/golang.org/x/text/PATENTS create mode 100644 vendor/golang.org/x/text/feature/plural/common.go create mode 100644 vendor/golang.org/x/text/feature/plural/message.go create mode 100644 vendor/golang.org/x/text/feature/plural/plural.go create mode 100644 vendor/golang.org/x/text/feature/plural/tables.go create mode 100644 vendor/golang.org/x/text/internal/catmsg/catmsg.go create mode 100644 vendor/golang.org/x/text/internal/catmsg/codec.go create mode 100644 vendor/golang.org/x/text/internal/catmsg/varint.go create mode 100644 vendor/golang.org/x/text/internal/format/format.go create mode 100644 vendor/golang.org/x/text/internal/format/parser.go create mode 100644 vendor/golang.org/x/text/internal/internal.go create mode 100644 vendor/golang.org/x/text/internal/language/common.go create mode 100644 vendor/golang.org/x/text/internal/language/compact.go create mode 100644 vendor/golang.org/x/text/internal/language/compact/compact.go create mode 100644 vendor/golang.org/x/text/internal/language/compact/language.go create mode 100644 vendor/golang.org/x/text/internal/language/compact/parents.go create mode 100644 vendor/golang.org/x/text/internal/language/compact/tables.go create mode 100644 vendor/golang.org/x/text/internal/language/compact/tags.go create mode 100644 vendor/golang.org/x/text/internal/language/compose.go create mode 100644 vendor/golang.org/x/text/internal/language/coverage.go create mode 100644 vendor/golang.org/x/text/internal/language/language.go create mode 100644 vendor/golang.org/x/text/internal/language/lookup.go create mode 100644 vendor/golang.org/x/text/internal/language/match.go create mode 100644 vendor/golang.org/x/text/internal/language/parse.go create mode 100644 vendor/golang.org/x/text/internal/language/tables.go create mode 100644 vendor/golang.org/x/text/internal/language/tags.go create mode 100644 vendor/golang.org/x/text/internal/match.go 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/format.go create mode 100644 vendor/golang.org/x/text/internal/number/number.go create mode 100644 vendor/golang.org/x/text/internal/number/pattern.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/stringset/set.go create mode 100644 vendor/golang.org/x/text/internal/tag/tag.go create mode 100644 vendor/golang.org/x/text/language/coverage.go create mode 100644 vendor/golang.org/x/text/language/doc.go create mode 100644 vendor/golang.org/x/text/language/language.go create mode 100644 vendor/golang.org/x/text/language/match.go create mode 100644 vendor/golang.org/x/text/language/parse.go create mode 100644 vendor/golang.org/x/text/language/tables.go create mode 100644 vendor/golang.org/x/text/language/tags.go create mode 100644 vendor/golang.org/x/text/message/catalog.go create mode 100644 vendor/golang.org/x/text/message/catalog/catalog.go create mode 100644 vendor/golang.org/x/text/message/catalog/dict.go create mode 100644 vendor/golang.org/x/text/message/catalog/go19.go create mode 100644 vendor/golang.org/x/text/message/catalog/gopre19.go create mode 100644 vendor/golang.org/x/text/message/doc.go create mode 100644 vendor/golang.org/x/text/message/format.go create mode 100644 vendor/golang.org/x/text/message/message.go create mode 100644 vendor/golang.org/x/text/message/print.go diff --git a/ext/formatting.go b/ext/formatting.go index 36b765e60..aa334ccd9 100644 --- a/ext/formatting.go +++ b/ext/formatting.go @@ -21,9 +21,11 @@ import ( "sort" "strconv" "strings" - "time" "unicode" + "golang.org/x/text/language" + "golang.org/x/text/message" + "github.com/google/cel-go/cel" "github.com/google/cel-go/common/ast" "github.com/google/cel-go/common/overloads" @@ -32,366 +34,368 @@ import ( "github.com/google/cel-go/common/types/traits" ) -type clauseImpl func(ref.Val) (string, error) - -type appendingFormatter struct { - buf []byte -} - -type formattedMapEntry struct { - key string - val string +type clauseImpl func(ref.Val, string) (string, error) + +func clauseForType(argType ref.Type) (clauseImpl, error) { + switch argType { + case types.IntType, types.UintType: + return formatDecimal, nil + case types.StringType, types.BytesType, types.BoolType, types.NullType, types.TypeType: + return FormatString, nil + case types.TimestampType, types.DurationType: + // special case to ensure timestamps/durations get printed as CEL literals + return func(arg ref.Val, locale string) (string, error) { + argStrVal := arg.ConvertToType(types.StringType) + argStr := argStrVal.Value().(string) + if arg.Type() == types.TimestampType { + return fmt.Sprintf("timestamp(%q)", argStr), nil + } + if arg.Type() == types.DurationType { + return fmt.Sprintf("duration(%q)", argStr), nil + } + return "", fmt.Errorf("cannot convert argument of type %s to timestamp/duration", arg.Type().TypeName()) + }, nil + case types.ListType: + return formatList, nil + case types.MapType: + return formatMap, nil + case types.DoubleType: + // avoid formatFixed so we can output a period as the decimal separator in order + // to always be a valid CEL literal + return func(arg ref.Val, locale string) (string, error) { + argDouble, ok := arg.Value().(float64) + if !ok { + return "", fmt.Errorf("couldn't convert %s to float64", arg.Type().TypeName()) + } + fmtStr := fmt.Sprintf("%%.%df", defaultPrecision) + return fmt.Sprintf(fmtStr, argDouble), nil + }, nil + case types.TypeType: + return func(arg ref.Val, locale string) (string, error) { + return fmt.Sprintf("type(%s)", arg.Value().(string)), nil + }, nil + default: + return nil, fmt.Errorf("no formatting function for %s", argType.TypeName()) + } } -func (af *appendingFormatter) format(arg ref.Val) error { - switch arg.Type() { - case types.BoolType: - argBool, ok := arg.Value().(bool) - if !ok { - return fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.BoolType) - } - af.buf = strconv.AppendBool(af.buf, argBool) - return nil - case types.IntType: - argInt, ok := arg.Value().(int64) - if !ok { - return fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.IntType) - } - af.buf = strconv.AppendInt(af.buf, argInt, 10) - return nil - case types.UintType: - argUint, ok := arg.Value().(uint64) - if !ok { - return fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.UintType) - } - af.buf = strconv.AppendUint(af.buf, argUint, 10) - return nil - case types.DoubleType: - argDbl, ok := arg.Value().(float64) - if !ok { - return fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.DoubleType) - } - if math.IsNaN(argDbl) { - af.buf = append(af.buf, "NaN"...) - return nil - } - if math.IsInf(argDbl, -1) { - af.buf = append(af.buf, "-Infinity"...) - return nil +func formatList(arg ref.Val, locale string) (string, error) { + argList := arg.(traits.Lister) + argIterator := argList.Iterator() + var listStrBuilder strings.Builder + _, err := listStrBuilder.WriteRune('[') + if err != nil { + return "", fmt.Errorf("error writing to list string: %w", err) + } + for argIterator.HasNext() == types.True { + member := argIterator.Next() + memberFormat, err := clauseForType(member.Type()) + if err != nil { + return "", err } - if math.IsInf(argDbl, 1) { - af.buf = append(af.buf, "Infinity"...) - return nil + unquotedStr, err := memberFormat(member, locale) + if err != nil { + return "", err } - af.buf = strconv.AppendFloat(af.buf, argDbl, 'f', -1, 64) - return nil - case types.BytesType: - argBytes, ok := arg.Value().([]byte) - if !ok { - return fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.BytesType) + str := quoteForCEL(member, unquotedStr) + _, err = listStrBuilder.WriteString(str) + if err != nil { + return "", fmt.Errorf("error writing to list string: %w", err) } - af.buf = append(af.buf, argBytes...) - return nil - case types.StringType: - argStr, ok := arg.Value().(string) - if !ok { - return fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.StringType) + if argIterator.HasNext() == types.True { + _, err = listStrBuilder.WriteString(", ") + if err != nil { + return "", fmt.Errorf("error writing to list string: %w", err) + } } - af.buf = append(af.buf, argStr...) - return nil - case types.DurationType: - argDur, ok := arg.Value().(time.Duration) - if !ok { - return fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.DurationType) + } + _, err = listStrBuilder.WriteRune(']') + if err != nil { + return "", fmt.Errorf("error writing to list string: %w", err) + } + return listStrBuilder.String(), nil +} + +func formatMap(arg ref.Val, locale string) (string, error) { + argMap := arg.(traits.Mapper) + argIterator := argMap.Iterator() + type mapPair struct { + key string + value string + } + argPairs := make([]mapPair, argMap.Size().Value().(int64)) + i := 0 + for argIterator.HasNext() == types.True { + key := argIterator.Next() + var keyFormat clauseImpl + switch key.Type() { + case types.StringType, types.BoolType: + keyFormat = FormatString + case types.IntType, types.UintType: + keyFormat = formatDecimal + default: + return "", fmt.Errorf("no formatting function for map key of type %s", key.Type().TypeName()) } - af.buf = strconv.AppendFloat(af.buf, argDur.Seconds(), 'f', -1, 64) - af.buf = append(af.buf, "s"...) - return nil - case types.TimestampType: - argTime, ok := arg.Value().(time.Time) - if !ok { - return fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.TimestampType) + unquotedKeyStr, err := keyFormat(key, locale) + if err != nil { + return "", err } - af.buf = argTime.UTC().AppendFormat(af.buf, time.RFC3339Nano) - return nil - case types.NullType: - af.buf = append(af.buf, "null"...) - return nil - case types.TypeType: - argType, ok := arg.Value().(string) - if !ok { - return fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.TypeType) + keyStr := quoteForCEL(key, unquotedKeyStr) + value, found := argMap.Find(key) + if !found { + return "", fmt.Errorf("could not find key: %q", key) } - af.buf = append(af.buf, argType...) - return nil - case types.ListType: - argList, ok := arg.(traits.Lister) - if !ok { - return fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.ListType) + valueFormat, err := clauseForType(value.Type()) + if err != nil { + return "", err } - argIter := argList.Iterator() - af.buf = append(af.buf, "["...) - if argIter.HasNext() == types.True { - if err := af.format(argIter.Next()); err != nil { - return err - } - for argIter.HasNext() == types.True { - af.buf = append(af.buf, ", "...) - if err := af.format(argIter.Next()); err != nil { - return err - } - } + unquotedValueStr, err := valueFormat(value, locale) + if err != nil { + return "", err } - af.buf = append(af.buf, "]"...) - return nil - case types.MapType: - argMap, ok := arg.(traits.Mapper) - if !ok { - return fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.MapType) + valueStr := quoteForCEL(value, unquotedValueStr) + argPairs[i] = mapPair{keyStr, valueStr} + i++ + } + sort.SliceStable(argPairs, func(x, y int) bool { + return argPairs[x].key < argPairs[y].key + }) + var mapStrBuilder strings.Builder + _, err := mapStrBuilder.WriteRune('{') + if err != nil { + return "", fmt.Errorf("error writing to map string: %w", err) + } + for i, entry := range argPairs { + _, err = mapStrBuilder.WriteString(fmt.Sprintf("%s:%s", entry.key, entry.value)) + if err != nil { + return "", fmt.Errorf("error writing to map string: %w", err) } - argIter := argMap.Iterator() - ents := []formattedMapEntry{} - for argIter.HasNext() == types.True { - key := argIter.Next() - val, ok := argMap.Find(key) - if !ok { - return fmt.Errorf("key missing from map: '%s'", key) - } - keyStr, err := FormatString(key) + if i < len(argPairs)-1 { + _, err = mapStrBuilder.WriteString(", ") if err != nil { - return err - } - valStr, err := FormatString(val) - if err != nil { - return err - } - ents = append(ents, formattedMapEntry{keyStr, valStr}) - } - sort.SliceStable(ents, func(x, y int) bool { - return ents[x].key < ents[y].key - }) - af.buf = append(af.buf, "{"...) - for i, e := range ents { - if i > 0 { - af.buf = append(af.buf, ", "...) + return "", fmt.Errorf("error writing to map string: %w", err) } - af.buf = append(af.buf, e.key...) - af.buf = append(af.buf, ": "...) - af.buf = append(af.buf, e.val...) } - af.buf = append(af.buf, "}"...) - return nil + } + _, err = mapStrBuilder.WriteRune('}') + if err != nil { + return "", fmt.Errorf("error writing to map string: %w", err) + } + return mapStrBuilder.String(), nil +} + +// quoteForCEL takes a formatted, unquoted value and quotes it in a manner suitable +// for embedding directly in CEL. +func quoteForCEL(refVal ref.Val, unquotedValue string) string { + switch refVal.Type() { + case types.StringType: + return fmt.Sprintf("%q", unquotedValue) + case types.BytesType: + return fmt.Sprintf("b%q", unquotedValue) + case types.DoubleType: + // special case to handle infinity/NaN + num := refVal.Value().(float64) + if math.IsInf(num, 1) || math.IsInf(num, -1) || math.IsNaN(num) { + return fmt.Sprintf("%q", unquotedValue) + } + return unquotedValue default: - return stringFormatError(runtimeID, arg.Type().TypeName()) + return unquotedValue } } // FormatString returns the string representation of a CEL value. // // It is used to implement the %s specifier in the (string).format() extension function. -func FormatString(arg ref.Val) (string, error) { - var fmter appendingFormatter - if err := fmter.format(arg); err != nil { - return "", err +func FormatString(arg ref.Val, locale string) (string, error) { + switch arg.Type() { + case types.ListType: + return formatList(arg, locale) + case types.MapType: + return formatMap(arg, locale) + case types.IntType, types.UintType, types.DoubleType, + types.BoolType, types.StringType, types.TimestampType, types.BytesType, types.DurationType, types.TypeType: + argStrVal := arg.ConvertToType(types.StringType) + argStr, ok := argStrVal.Value().(string) + if !ok { + return "", fmt.Errorf("could not convert argument %q to string", argStrVal) + } + return argStr, nil + case types.NullType: + return "null", nil + default: + return "", stringFormatError(runtimeID, arg.Type().TypeName()) } - return string(fmter.buf), nil } -type stringFormatter struct{} - -func (c *stringFormatter) String(arg ref.Val) (string, error) { - return FormatString(arg) -} - -func (c *stringFormatter) Decimal(arg ref.Val) (string, error) { +func formatDecimal(arg ref.Val, locale string) (string, error) { switch arg.Type() { case types.IntType: - argInt, ok := arg.Value().(int64) + argInt, ok := arg.ConvertToType(types.IntType).Value().(int64) if !ok { - return "", fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.IntType) + return "", fmt.Errorf("could not convert \"%s\" to int64", arg.Value()) } - return strconv.FormatInt(argInt, 10), nil + return fmt.Sprintf("%d", argInt), nil case types.UintType: - argUint, ok := arg.Value().(uint64) + argInt, ok := arg.ConvertToType(types.UintType).Value().(uint64) if !ok { - return "", fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.UintType) + return "", fmt.Errorf("could not convert \"%s\" to uint64", arg.Value()) } - return strconv.FormatUint(argUint, 10), nil - case types.DoubleType: - argDbl, ok := arg.Value().(float64) - if !ok { - return "", fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.DoubleType) - } - if math.IsNaN(argDbl) { - return "NaN", nil - } - if math.IsInf(argDbl, -1) { - return "-Infinity", nil - } - if math.IsInf(argDbl, 1) { - return "Infinity", nil - } - return strconv.FormatFloat(argDbl, 'f', -1, 64), nil + return fmt.Sprintf("%d", argInt), nil default: return "", decimalFormatError(runtimeID, arg.Type().TypeName()) } } -func (c *stringFormatter) Fixed(precision int) func(ref.Val) (string, error) { - return func(arg ref.Val) (string, error) { - fmtStr := fmt.Sprintf("%%.%df", precision) - switch arg.Type() { - case types.IntType: - argInt, ok := arg.Value().(int64) - if !ok { - return "", fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.IntType) - } - return fmt.Sprintf(fmtStr, argInt), nil - case types.UintType: - argUint, ok := arg.Value().(uint64) - if !ok { - return "", fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.UintType) - } - return fmt.Sprintf(fmtStr, argUint), nil - case types.DoubleType: - argDbl, ok := arg.Value().(float64) - if !ok { - return "", fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.DoubleType) - } - if math.IsNaN(argDbl) { - return "NaN", nil - } - if math.IsInf(argDbl, -1) { - return "-Infinity", nil - } - if math.IsInf(argDbl, 1) { - return "Infinity", nil +func matchLanguage(locale string) (language.Tag, error) { + matcher, err := makeMatcher(locale) + if err != nil { + return language.Und, err + } + tag, _ := language.MatchStrings(matcher, locale) + return tag, nil +} + +func makeMatcher(locale string) (language.Matcher, error) { + tags := make([]language.Tag, 0) + tag, err := language.Parse(locale) + if err != nil { + return nil, err + } + tags = append(tags, tag) + return language.NewMatcher(tags), nil +} + +type stringFormatter struct{} + +func (c *stringFormatter) String(arg ref.Val, locale string) (string, error) { + return FormatString(arg, locale) +} + +func (c *stringFormatter) Decimal(arg ref.Val, locale string) (string, error) { + return formatDecimal(arg, locale) +} + +func (c *stringFormatter) Fixed(precision *int) func(ref.Val, string) (string, error) { + if precision == nil { + precision = new(int) + *precision = defaultPrecision + } + return func(arg ref.Val, locale string) (string, error) { + strException := false + if arg.Type() == types.StringType { + argStr := arg.Value().(string) + if argStr == "NaN" || argStr == "Infinity" || argStr == "-Infinity" { + strException = true } - return fmt.Sprintf(fmtStr, argDbl), nil - default: + } + if arg.Type() != types.DoubleType && !strException { return "", fixedPointFormatError(runtimeID, arg.Type().TypeName()) } + argFloatVal := arg.ConvertToType(types.DoubleType) + argFloat, ok := argFloatVal.Value().(float64) + if !ok { + return "", fmt.Errorf("could not convert \"%s\" to float64", argFloatVal.Value()) + } + fmtStr := fmt.Sprintf("%%.%df", *precision) + + matchedLocale, err := matchLanguage(locale) + if err != nil { + return "", fmt.Errorf("error matching locale: %w", err) + } + return message.NewPrinter(matchedLocale).Sprintf(fmtStr, argFloat), nil } } -func (c *stringFormatter) Scientific(precision int) func(ref.Val) (string, error) { - return func(arg ref.Val) (string, error) { - fmtStr := fmt.Sprintf("%%1.%de", precision) - switch arg.Type() { - case types.IntType: - argInt, ok := arg.Value().(int64) - if !ok { - return "", fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.IntType) - } - return fmt.Sprintf(fmtStr, argInt), nil - case types.UintType: - argUint, ok := arg.Value().(uint64) - if !ok { - return "", fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.UintType) - } - return fmt.Sprintf(fmtStr, argUint), nil - case types.DoubleType: - argDbl, ok := arg.Value().(float64) - if !ok { - return "", fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.DoubleType) - } - if math.IsNaN(argDbl) { - return "NaN", nil - } - if math.IsInf(argDbl, -1) { - return "-Infinity", nil - } - if math.IsInf(argDbl, 1) { - return "Infinity", nil +func (c *stringFormatter) Scientific(precision *int) func(ref.Val, string) (string, error) { + if precision == nil { + precision = new(int) + *precision = defaultPrecision + } + return func(arg ref.Val, locale string) (string, error) { + strException := false + if arg.Type() == types.StringType { + argStr := arg.Value().(string) + if argStr == "NaN" || argStr == "Infinity" || argStr == "-Infinity" { + strException = true } - return fmt.Sprintf(fmtStr, argDbl), nil - default: + } + if arg.Type() != types.DoubleType && !strException { return "", scientificFormatError(runtimeID, arg.Type().TypeName()) } + argFloatVal := arg.ConvertToType(types.DoubleType) + argFloat, ok := argFloatVal.Value().(float64) + if !ok { + return "", fmt.Errorf("could not convert \"%v\" to float64", argFloatVal.Value()) + } + matchedLocale, err := matchLanguage(locale) + if err != nil { + return "", fmt.Errorf("error matching locale: %w", err) + } + fmtStr := fmt.Sprintf("%%%de", *precision) + return message.NewPrinter(matchedLocale).Sprintf(fmtStr, argFloat), nil } } -func (c *stringFormatter) Binary(arg ref.Val) (string, error) { +func (c *stringFormatter) Binary(arg ref.Val, locale string) (string, error) { switch arg.Type() { + case types.IntType: + argInt := arg.Value().(int64) + // locale is intentionally unused as integers formatted as binary + // strings are locale-independent + return fmt.Sprintf("%b", argInt), nil + case types.UintType: + argInt := arg.Value().(uint64) + return fmt.Sprintf("%b", argInt), nil case types.BoolType: - argBool, ok := arg.Value().(bool) - if !ok { - return "", fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.BoolType) - } + argBool := arg.Value().(bool) if argBool { return "1", nil } return "0", nil - case types.IntType: - argInt, ok := arg.Value().(int64) - if !ok { - return "", fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.IntType) - } - return strconv.FormatInt(argInt, 2), nil - case types.UintType: - argUint, ok := arg.Value().(uint64) - if !ok { - return "", fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.UintType) - } - return strconv.FormatUint(argUint, 2), nil default: return "", binaryFormatError(runtimeID, arg.Type().TypeName()) } } -func (c *stringFormatter) Hex(useUpper bool) func(ref.Val) (string, error) { - return func(arg ref.Val) (string, error) { - var fmtStr string +func (c *stringFormatter) Hex(useUpper bool) func(ref.Val, string) (string, error) { + return func(arg ref.Val, locale string) (string, error) { + fmtStr := "%x" if useUpper { fmtStr = "%X" - } else { - fmtStr = "%x" } switch arg.Type() { + case types.StringType, types.BytesType: + if arg.Type() == types.BytesType { + return fmt.Sprintf(fmtStr, arg.Value().([]byte)), nil + } + return fmt.Sprintf(fmtStr, arg.Value().(string)), nil case types.IntType: argInt, ok := arg.Value().(int64) if !ok { - return "", fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.IntType) + return "", fmt.Errorf("could not convert \"%s\" to int64", arg.Value()) } return fmt.Sprintf(fmtStr, argInt), nil case types.UintType: - argUint, ok := arg.Value().(uint64) + argInt, ok := arg.Value().(uint64) if !ok { - return "", fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.UintType) + return "", fmt.Errorf("could not convert \"%s\" to uint64", arg.Value()) } - return fmt.Sprintf(fmtStr, argUint), nil - case types.StringType: - argStr, ok := arg.Value().(string) - if !ok { - return "", fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.StringType) - } - return fmt.Sprintf(fmtStr, argStr), nil - case types.BytesType: - argBytes, ok := arg.Value().([]byte) - if !ok { - return "", fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.BytesType) - } - return fmt.Sprintf(fmtStr, argBytes), nil + return fmt.Sprintf(fmtStr, argInt), nil default: return "", hexFormatError(runtimeID, arg.Type().TypeName()) } } } -func (c *stringFormatter) Octal(arg ref.Val) (string, error) { +func (c *stringFormatter) Octal(arg ref.Val, locale string) (string, error) { switch arg.Type() { case types.IntType: - argInt, ok := arg.Value().(int64) - if !ok { - return "", fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.IntType) - } - return strconv.FormatInt(argInt, 8), nil + argInt := arg.Value().(int64) + return fmt.Sprintf("%o", argInt), nil case types.UintType: - argUint, ok := arg.Value().(uint64) - if !ok { - return "", fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.UintType) - } - return strconv.FormatUint(argUint, 8), nil + argInt := arg.Value().(uint64) + return fmt.Sprintf("%o", argInt), nil default: return "", octalFormatError(runtimeID, arg.Type().TypeName()) } @@ -428,7 +432,7 @@ func (stringFormatValidator) Validate(env *cel.Env, _ cel.ValidatorConfig, a *as ast: a, } // use a placeholder locale, since locale doesn't affect syntax - _, err := parseFormatString(formatStr, formatCheck, formatCheck) + _, err := parseFormatString(formatStr, formatCheck, formatCheck, "en_US") if err != nil { iss.ReportErrorAtID(getErrorExprID(e.ID(), err), "%v", err) continue @@ -500,7 +504,7 @@ type stringFormatChecker struct { ast *ast.AST } -func (c *stringFormatChecker) String(arg ref.Val) (string, error) { +func (c *stringFormatChecker) String(arg ref.Val, locale string) (string, error) { formatArg := c.args[c.currArgIndex] valid, badID := c.verifyString(formatArg) if !valid { @@ -509,19 +513,20 @@ func (c *stringFormatChecker) String(arg ref.Val) (string, error) { return "", nil } -func (c *stringFormatChecker) Decimal(arg ref.Val) (string, error) { +func (c *stringFormatChecker) Decimal(arg ref.Val, locale string) (string, error) { id := c.args[c.currArgIndex].ID() - valid := c.verifyTypeOneOf(id, types.IntType, types.UintType, types.DoubleType) + valid := c.verifyTypeOneOf(id, types.IntType, types.UintType) if !valid { return "", decimalFormatError(id, c.typeOf(id).TypeName()) } return "", nil } -func (c *stringFormatChecker) Fixed(precision int) func(ref.Val) (string, error) { - return func(arg ref.Val) (string, error) { +func (c *stringFormatChecker) Fixed(precision *int) func(ref.Val, string) (string, error) { + return func(arg ref.Val, locale string) (string, error) { id := c.args[c.currArgIndex].ID() - valid := c.verifyTypeOneOf(id, types.IntType, types.UintType, types.DoubleType) + // we allow StringType since "NaN", "Infinity", and "-Infinity" are also valid values + valid := c.verifyTypeOneOf(id, types.DoubleType, types.StringType) if !valid { return "", fixedPointFormatError(id, c.typeOf(id).TypeName()) } @@ -529,10 +534,10 @@ func (c *stringFormatChecker) Fixed(precision int) func(ref.Val) (string, error) } } -func (c *stringFormatChecker) Scientific(precision int) func(ref.Val) (string, error) { - return func(arg ref.Val) (string, error) { +func (c *stringFormatChecker) Scientific(precision *int) func(ref.Val, string) (string, error) { + return func(arg ref.Val, locale string) (string, error) { id := c.args[c.currArgIndex].ID() - valid := c.verifyTypeOneOf(id, types.IntType, types.UintType, types.DoubleType) + valid := c.verifyTypeOneOf(id, types.DoubleType, types.StringType) if !valid { return "", scientificFormatError(id, c.typeOf(id).TypeName()) } @@ -540,17 +545,17 @@ func (c *stringFormatChecker) Scientific(precision int) func(ref.Val) (string, e } } -func (c *stringFormatChecker) Binary(arg ref.Val) (string, error) { +func (c *stringFormatChecker) Binary(arg ref.Val, locale string) (string, error) { id := c.args[c.currArgIndex].ID() - valid := c.verifyTypeOneOf(id, types.BoolType, types.IntType, types.UintType) + valid := c.verifyTypeOneOf(id, types.IntType, types.UintType, types.BoolType) if !valid { return "", binaryFormatError(id, c.typeOf(id).TypeName()) } return "", nil } -func (c *stringFormatChecker) Hex(useUpper bool) func(ref.Val) (string, error) { - return func(arg ref.Val) (string, error) { +func (c *stringFormatChecker) Hex(useUpper bool) func(ref.Val, string) (string, error) { + return func(arg ref.Val, locale string) (string, error) { id := c.args[c.currArgIndex].ID() valid := c.verifyTypeOneOf(id, types.IntType, types.UintType, types.StringType, types.BytesType) if !valid { @@ -560,7 +565,7 @@ func (c *stringFormatChecker) Hex(useUpper bool) func(ref.Val) (string, error) { } } -func (c *stringFormatChecker) Octal(arg ref.Val) (string, error) { +func (c *stringFormatChecker) Octal(arg ref.Val, locale string) (string, error) { id := c.args[c.currArgIndex].ID() valid := c.verifyTypeOneOf(id, types.IntType, types.UintType) if !valid { @@ -642,27 +647,27 @@ func (c *stringFormatChecker) verifyString(sub ast.Expr) (bool, int64) { // runtime execution. func binaryFormatError(id int64, badType string) error { - return newFormatError(id, "only ints, uints, and bools can be formatted as binary, was given %s", badType) + return newFormatError(id, "only integers and bools can be formatted as binary, was given %s", badType) } func decimalFormatError(id int64, badType string) error { - return newFormatError(id, "decimal clause can only be used on ints, uints, and doubles, was given %s", badType) + return newFormatError(id, "decimal clause can only be used on integers, was given %s", badType) } func fixedPointFormatError(id int64, badType string) error { - return newFormatError(id, "fixed-point clause can only be used on ints, uints, and doubles, was given %s", badType) + return newFormatError(id, "fixed-point clause can only be used on doubles, was given %s", badType) } func hexFormatError(id int64, badType string) error { - return newFormatError(id, "only ints, uints, bytes, and strings can be formatted as hex, was given %s", badType) + return newFormatError(id, "only integers, byte buffers, and strings can be formatted as hex, was given %s", badType) } func octalFormatError(id int64, badType string) error { - return newFormatError(id, "octal clause can only be used on ints and uints, was given %s", badType) + return newFormatError(id, "octal clause can only be used on integers, was given %s", badType) } func scientificFormatError(id int64, badType string) error { - return newFormatError(id, "scientific clause can only be used on ints, uints, and doubles, was given %s", badType) + return newFormatError(id, "scientific clause can only be used on doubles, was given %s", badType) } func stringFormatError(id int64, badType string) error { @@ -712,33 +717,33 @@ func (c *stringArgList) Size() int64 { type formatStringInterpolator interface { // String takes a ref.Val and a string representing the current locale identifier // and returns the Val formatted as a string, or an error if one occurred. - String(ref.Val) (string, error) + String(ref.Val, string) (string, error) // Decimal takes a ref.Val and a string representing the current locale identifier // and returns the Val formatted as a decimal integer, or an error if one occurred. - Decimal(ref.Val) (string, error) + Decimal(ref.Val, string) (string, error) // Fixed takes an int pointer representing precision (or nil if none was given) and // returns a function operating in a similar manner to String and Decimal, taking a // ref.Val and locale and returning the appropriate string. A closure is returned // so precision can be set without needing an additional function call/configuration. - Fixed(int) func(ref.Val) (string, error) + Fixed(*int) func(ref.Val, string) (string, error) // Scientific functions identically to Fixed, except the string returned from the closure // is expected to be in scientific notation. - Scientific(int) func(ref.Val) (string, error) + Scientific(*int) func(ref.Val, string) (string, error) // Binary takes a ref.Val and a string representing the current locale identifier // and returns the Val formatted as a binary integer, or an error if one occurred. - Binary(ref.Val) (string, error) + Binary(ref.Val, string) (string, error) // Hex takes a boolean that, if true, indicates the hex string output by the returned // closure should use uppercase letters for A-F. - Hex(bool) func(ref.Val) (string, error) + Hex(bool) func(ref.Val, string) (string, error) // Octal takes a ref.Val and a string representing the current locale identifier and // returns the Val formatted in octal, or an error if one occurred. - Octal(ref.Val) (string, error) + Octal(ref.Val, string) (string, error) } // formatListArgs is an interface that allows user-defined list-like datatypes to be used @@ -753,7 +758,7 @@ type formatListArgs interface { // parseFormatString formats a string according to the string.format syntax, taking the clause implementations // from the provided FormatCallback and the args from the given FormatList. -func parseFormatString(formatStr string, callback formatStringInterpolator, list formatListArgs) (string, error) { +func parseFormatString(formatStr string, callback formatStringInterpolator, list formatListArgs, locale string) (string, error) { i := 0 argIndex := 0 var builtStr strings.Builder @@ -777,7 +782,7 @@ func parseFormatString(formatStr string, callback formatStringInterpolator, list if int64(argIndex) >= list.Size() { return "", fmt.Errorf("index %d out of range", argIndex) } - numRead, val, refErr := parseAndFormatClause(formatStr[i:], argAny, callback, list) + numRead, val, refErr := parseAndFormatClause(formatStr[i:], argAny, callback, list, locale) if refErr != nil { return "", refErr } @@ -801,7 +806,7 @@ func parseFormatString(formatStr string, callback formatStringInterpolator, list // parseAndFormatClause parses the format clause at the start of the given string with val, and returns // how many characters were consumed and the substituted string form of val, or an error if one occurred. -func parseAndFormatClause(formatStr string, val ref.Val, callback formatStringInterpolator, list formatListArgs) (int, string, error) { +func parseAndFormatClause(formatStr string, val ref.Val, callback formatStringInterpolator, list formatListArgs, locale string) (int, string, error) { i := 1 read, formatter, err := parseFormattingClause(formatStr[i:], callback) i += read @@ -809,7 +814,7 @@ func parseAndFormatClause(formatStr string, val ref.Val, callback formatStringIn return -1, "", newParseFormatError("could not parse formatting clause", err) } - valStr, err := formatter(val) + valStr, err := formatter(val, locale) if err != nil { return -1, "", newParseFormatError("error during formatting", err) } @@ -845,16 +850,16 @@ func parseFormattingClause(formatStr string, callback formatStringInterpolator) } } -func parsePrecision(formatStr string) (int, int, error) { +func parsePrecision(formatStr string) (int, *int, error) { i := 0 if formatStr[i] != '.' { - return i, defaultPrecision, nil + return i, nil, nil } i++ var buffer strings.Builder for { if i >= len(formatStr) { - return -1, -1, errors.New("could not find end of precision specifier") + return -1, nil, errors.New("could not find end of precision specifier") } if !isASCIIDigit(rune(formatStr[i])) { break @@ -864,12 +869,9 @@ func parsePrecision(formatStr string) (int, int, error) { } precision, err := strconv.Atoi(buffer.String()) if err != nil { - return -1, -1, fmt.Errorf("error while converting precision to integer: %w", err) - } - if precision < 0 { - return -1, -1, fmt.Errorf("negative precision: %d", precision) + return -1, nil, fmt.Errorf("error while converting precision to integer: %w", err) } - return i, precision, nil + return i, &precision, nil } func isASCIIDigit(r rune) bool { diff --git a/ext/formatting_test.go b/ext/formatting_test.go new file mode 100644 index 000000000..6b1f25066 --- /dev/null +++ b/ext/formatting_test.go @@ -0,0 +1,1136 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ext + +import ( + "fmt" + "math" + "reflect" + "strings" + "testing" + "time" + + "google.golang.org/protobuf/proto" + + "github.com/google/cel-go/cel" + "github.com/google/cel-go/checker" + "github.com/google/cel-go/common/types" + "github.com/google/cel-go/common/types/ref" + + proto3pb "github.com/google/cel-go/test/proto3pb" +) + +func TestStringFormat(t *testing.T) { + tests := []struct { + name string + format string + dynArgs map[string]any + formatArgs string + locale string + err string + expectedOutput string + expectedRuntimeCost uint64 + expectedEstimatedCost checker.CostEstimate + skipCompileCheck bool + }{ + { + name: "no-op", + format: "no substitution", + expectedOutput: "no substitution", + expectedRuntimeCost: 12, + expectedEstimatedCost: checker.CostEstimate{Min: 12, Max: 12}, + }, + + { + name: "mid-string substitution", + format: "str is %s and some more", + formatArgs: `"filler"`, + expectedOutput: "str is filler and some more", + expectedRuntimeCost: 13, + expectedEstimatedCost: checker.CostEstimate{Min: 13, Max: 13}, + }, + { + name: "percent escaping", + format: "%% and also %%", + expectedOutput: "% and also %", + expectedRuntimeCost: 12, + expectedEstimatedCost: checker.CostEstimate{Min: 12, Max: 12}, + }, + { + name: "substution inside escaped percent signs", + format: "%%%s%%", + formatArgs: `"text"`, + expectedOutput: "%text%", + expectedRuntimeCost: 11, + expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, + }, + { + name: "substitution with one escaped percent sign on the right", + format: "%s%%", + formatArgs: `"percent on the right"`, + expectedOutput: "percent on the right%", + expectedRuntimeCost: 11, + expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, + }, + { + name: "substitution with one escaped percent sign on the left", + format: "%%%s", + formatArgs: `"percent on the left"`, + expectedOutput: "%percent on the left", + expectedRuntimeCost: 11, + expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, + }, + { + name: "multiple substitutions", + format: "%d %d %d, %s %s %s, %d %d %d, %s %s %s", + formatArgs: `1, 2, 3, "A", "B", "C", 4, 5, 6, "D", "E", "F"`, + expectedOutput: "1 2 3, A B C, 4 5 6, D E F", + expectedRuntimeCost: 14, + expectedEstimatedCost: checker.CostEstimate{Min: 14, Max: 14}, + }, + { + name: "percent sign escape sequence support", + format: "\u0025\u0025escaped \u0025s\u0025\u0025", + formatArgs: `"percent"`, + expectedOutput: "%escaped percent%", + expectedRuntimeCost: 12, + expectedEstimatedCost: checker.CostEstimate{Min: 12, Max: 12}, + }, + { + name: "fixed point formatting clause", + format: "%.3f", + formatArgs: "1.2345", + expectedOutput: "1.234", + expectedRuntimeCost: 11, + expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, + locale: "en_US", + }, + { + name: "binary formatting clause", + format: "this is 5 in binary: %b", + formatArgs: "5", + expectedOutput: "this is 5 in binary: 101", + expectedRuntimeCost: 13, + expectedEstimatedCost: checker.CostEstimate{Min: 13, Max: 13}, + }, + { + name: "negative binary formatting clause", + format: "this is -5 in binary: %b", + formatArgs: "-5", + expectedOutput: "this is -5 in binary: -101", + expectedRuntimeCost: 13, + expectedEstimatedCost: checker.CostEstimate{Min: 13, Max: 13}, + }, + { + name: "uint support for binary formatting", + format: "unsigned 64 in binary: %b", + formatArgs: "uint(64)", + expectedOutput: "unsigned 64 in binary: 1000000", + expectedRuntimeCost: 14, + expectedEstimatedCost: checker.CostEstimate{Min: 14, Max: 14}, + }, + { + name: "bool support for binary formatting", + format: "bit set from bool: %b", + formatArgs: "true", + expectedOutput: "bit set from bool: 1", + expectedRuntimeCost: 13, + expectedEstimatedCost: checker.CostEstimate{Min: 13, Max: 13}, + }, + { + name: "octal formatting clause", + format: "%o", + formatArgs: "11", + expectedOutput: "13", + expectedRuntimeCost: 11, + expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, + }, + { + name: "negative octal formatting clause", + format: "%o", + formatArgs: "-11", + expectedOutput: "-13", + expectedRuntimeCost: 11, + expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, + }, + { + name: "uint support for octal formatting clause", + format: "this is an unsigned octal: %o", + formatArgs: "uint(65535)", + expectedOutput: "this is an unsigned octal: 177777", + expectedRuntimeCost: 14, + expectedEstimatedCost: checker.CostEstimate{Min: 14, Max: 14}, + }, + { + name: "lowercase hexadecimal formatting clause", + format: "%x is 30 in hexadecimal", + formatArgs: "30", + expectedOutput: "1e is 30 in hexadecimal", + expectedRuntimeCost: 13, + expectedEstimatedCost: checker.CostEstimate{Min: 13, Max: 13}, + }, + { + name: "uppercase hexadecimal formatting clause", + format: "%X is 20 in hexadecimal", + formatArgs: "30", + expectedOutput: "1E is 20 in hexadecimal", + expectedRuntimeCost: 13, + expectedEstimatedCost: checker.CostEstimate{Min: 13, Max: 13}, + }, + { + name: "negative hexadecimal formatting clause", + format: "%x is -30 in hexadecimal", + formatArgs: "-30", + expectedOutput: "-1e is -30 in hexadecimal", + expectedRuntimeCost: 13, + expectedEstimatedCost: checker.CostEstimate{Min: 13, Max: 13}, + }, + { + name: "unsigned support for hexadecimal formatting clause", + format: "%X is 6000 in hexadecimal", + formatArgs: "uint(6000)", + expectedOutput: "1770 is 6000 in hexadecimal", + expectedRuntimeCost: 14, + expectedEstimatedCost: checker.CostEstimate{Min: 14, Max: 14}, + }, + { + name: "string support with hexadecimal formatting clause", + format: "%x", + formatArgs: `"Hello world!"`, + expectedOutput: "48656c6c6f20776f726c6421", + expectedRuntimeCost: 11, + expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, + }, + { + name: "string support with uppercase hexadecimal formatting clause", + format: "%X", + formatArgs: `"Hello world!"`, + expectedOutput: "48656C6C6F20776F726C6421", + expectedRuntimeCost: 11, + expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, + }, + { + name: "byte support with hexadecimal formatting clause", + format: "%x", + formatArgs: `b"byte string"`, + expectedOutput: "6279746520737472696e67", + expectedRuntimeCost: 11, + expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, + }, + { + name: "byte support with hexadecimal formatting clause leading zero", + format: "%x", + formatArgs: `b"\x00\x00byte string\x00"`, + expectedOutput: "00006279746520737472696e6700", + expectedRuntimeCost: 11, + expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, + }, + { + name: "byte support with uppercase hexadecimal formatting clause", + format: "%X", + formatArgs: `b"byte string"`, + expectedOutput: "6279746520737472696E67", + expectedRuntimeCost: 11, + expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, + }, + { + name: "scientific notation formatting clause", + format: "%.6e", + formatArgs: "1052.032911275", + expectedOutput: "1.052033\u202f\u00d7\u202f10\u2070\u00b3", + expectedRuntimeCost: 11, + expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, + locale: "en_US", + }, + { + name: "locale support", + format: "%.3f", + formatArgs: "3.14", + locale: "fr_FR", + expectedOutput: "3,140", + expectedRuntimeCost: 11, + expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, + }, + { + name: "default precision for fixed-point clause", + format: "%f", + formatArgs: "2.71828", + expectedOutput: "2.718280", + expectedRuntimeCost: 11, + expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, + locale: "en_US", + }, + { + name: "default precision for scientific notation", + format: "%e", + formatArgs: "2.71828", + expectedOutput: "2.718280\u202f\u00d7\u202f10\u2070\u2070", + expectedRuntimeCost: 11, + expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, + locale: "en_US", + }, + { + name: "default precision for string", + format: "%s", + formatArgs: "2.71", + expectedOutput: "2.71", + expectedRuntimeCost: 11, + expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, + locale: "en_US", + }, + { + name: "default list precision for string", + format: "%s", + formatArgs: "[2.71]", + expectedOutput: "[2.710000]", + expectedRuntimeCost: 21, + expectedEstimatedCost: checker.CostEstimate{Min: 21, Max: 21}, + locale: "en_US", + }, + { + name: "default scientific notation for string", + format: "%s", + formatArgs: "0.000000002", + expectedOutput: "2e-09", + expectedRuntimeCost: 11, + expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, + locale: "en_US", + }, + { + name: "default list scientific notation for string", + format: "%s", + formatArgs: "[0.000000002]", + expectedOutput: "[0.000000]", + expectedRuntimeCost: 21, + expectedEstimatedCost: checker.CostEstimate{Min: 21, Max: 21}, + locale: "en_US", + }, + { + name: "unicode output for scientific notation", + format: "unescaped unicode: %e, escaped unicode: %e", + formatArgs: "2.71828, 2.71828", + expectedOutput: "unescaped unicode: 2.718280 × 10⁰⁰, escaped unicode: 2.718280\u202f\u00d7\u202f10\u2070\u2070", + expectedRuntimeCost: 15, + expectedEstimatedCost: checker.CostEstimate{Min: 15, Max: 15}, + locale: "en_US", + }, + { + name: "NaN support for fixed-point", + format: "%f", + formatArgs: `"NaN"`, + expectedOutput: "NaN", + expectedRuntimeCost: 11, + expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, + locale: "en_US", + }, + { + name: "positive infinity support for fixed-point", + format: "%f", + formatArgs: `"Infinity"`, + expectedOutput: "∞", + expectedRuntimeCost: 11, + expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, + locale: "en_US", + }, + { + name: "negative infinity support for fixed-point", + format: "%f", + formatArgs: `"-Infinity"`, + expectedOutput: "-∞", + expectedRuntimeCost: 11, + expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, + locale: "en_US", + }, + { + name: "NaN support for string", + format: "%s", + formatArgs: `double("NaN")`, + expectedOutput: "NaN", + }, + { + name: "positive infinity support for string", + format: "%s", + formatArgs: `double("Inf")`, + expectedOutput: "+Inf", + }, + { + name: "negative infinity support for string", + format: "%s", + formatArgs: `double("-Inf")`, + expectedOutput: "-Inf", + }, + { + name: "infinity list support for string", + format: "%s", + formatArgs: `[double("NaN"),double("+Inf"), double("-Inf")]`, + expectedOutput: `["NaN", "+Inf", "-Inf"]`, + }, + { + name: "uint support for decimal clause", + format: "%d", + formatArgs: "uint(64)", + expectedOutput: "64", + expectedRuntimeCost: 12, + expectedEstimatedCost: checker.CostEstimate{Min: 12, Max: 12}, + }, + { + name: "null support for string", + format: "null: %s", + formatArgs: "null", + expectedOutput: "null: null", + expectedRuntimeCost: 11, + expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, + }, + { + name: "int support for string", + format: "%s", + formatArgs: `999999999999`, + expectedOutput: "999999999999", + expectedRuntimeCost: 11, + expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, + }, + { + name: "bytes support for string", + format: "some bytes: %s", + formatArgs: `b"xyz"`, + expectedOutput: "some bytes: xyz", + expectedRuntimeCost: 12, + expectedEstimatedCost: checker.CostEstimate{Min: 12, Max: 12}, + }, + { + name: "type() support for string", + format: "type is %s", + formatArgs: `type("test string")`, + expectedOutput: "type is string", + expectedRuntimeCost: 12, + expectedEstimatedCost: checker.CostEstimate{Min: 12, Max: 12}, + }, + { + name: "timestamp support for string", + format: "%s", + formatArgs: `timestamp("2023-02-03T23:31:20+00:00")`, + expectedOutput: "2023-02-03T23:31:20Z", + expectedRuntimeCost: 12, + expectedEstimatedCost: checker.CostEstimate{Min: 12, Max: 12}, + }, + { + name: "duration support for string", + format: "%s", + formatArgs: `duration("1h45m47s")`, + expectedOutput: "6347s", + expectedRuntimeCost: 12, + expectedEstimatedCost: checker.CostEstimate{Min: 12, Max: 12}, + }, + { + name: "small duration support for string", + format: "%s", + formatArgs: `duration("2ns")`, + expectedOutput: "0.000000002s", + expectedRuntimeCost: 12, + expectedEstimatedCost: checker.CostEstimate{Min: 12, Max: 12}, + }, + { + name: "list support for string", + format: "%s", + formatArgs: `["abc", 3.14, null, [9, 8, 7, 6], timestamp("2023-02-03T23:31:20Z")]`, + expectedOutput: `["abc", 3.140000, null, [9, 8, 7, 6], timestamp("2023-02-03T23:31:20Z")]`, + expectedRuntimeCost: 32, + expectedEstimatedCost: checker.CostEstimate{Min: 32, Max: 32}, + }, + { + name: "map support for string", + format: "%s", + formatArgs: `{"key1": b"xyz", "key5": null, "key2": duration("2h"), "key4": true, "key3": 2.71828}`, + locale: "nl_NL", + expectedOutput: `{"key1":b"xyz", "key2":duration("7200s"), "key3":2.718280, "key4":true, "key5":null}`, + expectedRuntimeCost: 42, + expectedEstimatedCost: checker.CostEstimate{Min: 42, Max: 42}, + }, + { + name: "map support (all key types)", + format: "map with multiple key types: %s", + formatArgs: `{1: "value1", uint(2): "value2", true: double("NaN")}`, + expectedOutput: `map with multiple key types: {1:"value1", 2:"value2", true:"NaN"}`, + expectedRuntimeCost: 46, + expectedEstimatedCost: checker.CostEstimate{Min: 46, Max: 46}, + }, + { + name: "boolean support for %s", + format: "true bool: %s, false bool: %s", + formatArgs: `true, false`, + expectedOutput: "true bool: true, false bool: false", + expectedRuntimeCost: 13, + expectedEstimatedCost: checker.CostEstimate{Min: 13, Max: 13}, + }, + { + name: "dyntype support for string formatting clause", + format: "dynamic string: %s", + formatArgs: `dynStr`, + dynArgs: map[string]any{ + "dynStr": "a string", + }, + expectedOutput: "dynamic string: a string", + expectedRuntimeCost: 13, + expectedEstimatedCost: checker.CostEstimate{Min: 13, Max: 13}, + }, + { + name: "dyntype support for numbers with string formatting clause", + format: "dynIntStr: %s dynDoubleStr: %s", + formatArgs: `dynIntStr, dynDoubleStr`, + dynArgs: map[string]any{ + "dynIntStr": 32, + "dynDoubleStr": 56.8, + }, + expectedOutput: "dynIntStr: 32 dynDoubleStr: 56.8", + expectedRuntimeCost: 15, + expectedEstimatedCost: checker.CostEstimate{Min: 15, Max: 15}, + locale: "en_US", + }, + { + name: "dyntype support for integer formatting clause", + format: "dynamic int: %d", + formatArgs: `dynInt`, + dynArgs: map[string]any{ + "dynInt": 128, + }, + expectedOutput: "dynamic int: 128", + expectedRuntimeCost: 13, + expectedEstimatedCost: checker.CostEstimate{Min: 13, Max: 13}, + }, + { + name: "dyntype support for integer formatting clause (unsigned)", + format: "dynamic unsigned int: %d", + formatArgs: `dynUnsignedInt`, + dynArgs: map[string]any{ + "dynUnsignedInt": uint64(256), + }, + expectedOutput: "dynamic unsigned int: 256", + expectedRuntimeCost: 14, + expectedEstimatedCost: checker.CostEstimate{Min: 14, Max: 14}, + }, + { + name: "dyntype support for hex formatting clause", + format: "dynamic hex int: %x", + formatArgs: `dynHexInt`, + dynArgs: map[string]any{ + "dynHexInt": 22, + }, + expectedOutput: "dynamic hex int: 16", + expectedRuntimeCost: 13, + expectedEstimatedCost: checker.CostEstimate{Min: 13, Max: 13}, + }, + { + name: "dyntype support for hex formatting clause (uppercase)", + format: "dynamic hex int: %X (uppercase)", + formatArgs: `dynHexInt`, + dynArgs: map[string]any{ + "dynHexInt": 26, + }, + expectedOutput: "dynamic hex int: 1A (uppercase)", + expectedRuntimeCost: 15, + expectedEstimatedCost: checker.CostEstimate{Min: 15, Max: 15}, + }, + { + name: "dyntype support for unsigned hex formatting clause", + format: "dynamic hex int: %x (unsigned)", + formatArgs: `dynUnsignedHexInt`, + dynArgs: map[string]any{ + "dynUnsignedHexInt": uint(500), + }, + expectedOutput: "dynamic hex int: 1f4 (unsigned)", + expectedRuntimeCost: 14, + expectedEstimatedCost: checker.CostEstimate{Min: 14, Max: 14}, + }, + { + name: "dyntype support for fixed-point formatting clause", + format: "dynamic double: %.3f", + formatArgs: `dynDouble`, + dynArgs: map[string]any{ + "dynDouble": 4.5, + }, + expectedOutput: "dynamic double: 4.500", + expectedRuntimeCost: 13, + expectedEstimatedCost: checker.CostEstimate{Min: 13, Max: 13}, + locale: "en_US", + }, + { + name: "dyntype support for fixed-point formatting clause (comma separator locale)", + format: "dynamic double: %f", + formatArgs: `dynDouble`, + dynArgs: map[string]any{ + "dynDouble": 4.5, + }, + expectedOutput: "dynamic double: 4,500000", + expectedRuntimeCost: 13, + expectedEstimatedCost: checker.CostEstimate{Min: 13, Max: 13}, + locale: "fr_FR", + }, + { + name: "dyntype support for scientific notation", + format: "(dyntype) e: %e", + formatArgs: "dynE", + dynArgs: map[string]any{ + "dynE": 2.71828, + }, + expectedOutput: "(dyntype) e: 2.718280\u202f\u00d7\u202f10\u2070\u2070", + expectedRuntimeCost: 13, + expectedEstimatedCost: checker.CostEstimate{Min: 13, Max: 13}, + locale: "en_US", + }, + { + name: "dyntype NaN/infinity support for fixed-point", + format: "NaN: %f, infinity: %f", + formatArgs: `dynNaN, dynInf`, + dynArgs: map[string]any{ + "dynNaN": math.NaN(), + "dynInf": math.Inf(1), + }, + expectedOutput: "NaN: NaN, infinity: ∞", + expectedRuntimeCost: 15, + expectedEstimatedCost: checker.CostEstimate{Min: 15, Max: 15}, + }, + { + name: "dyntype support for timestamp", + format: "dyntype timestamp: %s", + formatArgs: `dynTime`, + dynArgs: map[string]any{ + "dynTime": time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC), + }, + expectedOutput: "dyntype timestamp: 2009-11-10T23:00:00Z", + expectedRuntimeCost: 14, + expectedEstimatedCost: checker.CostEstimate{Min: 14, Max: 14}, + }, + { + name: "dyntype support for duration", + format: "dyntype duration: %s", + formatArgs: `dynDuration`, + dynArgs: map[string]any{ + "dynDuration": mustParseDuration("2h25m47s"), + }, + expectedOutput: "dyntype duration: 8747s", + expectedRuntimeCost: 13, + expectedEstimatedCost: checker.CostEstimate{Min: 13, Max: 13}, + }, + { + name: "dyntype support for lists", + format: "dyntype list: %s", + formatArgs: `dynList`, + dynArgs: map[string]any{ + "dynList": []any{6, 4.2, "a string"}, + }, + expectedOutput: `dyntype list: [6, 4.200000, "a string"]`, + expectedRuntimeCost: 13, + expectedEstimatedCost: checker.CostEstimate{Min: 13, Max: 13}, + }, + { + name: "dyntype support for maps", + format: "dyntype map: %s", + formatArgs: `dynMap`, + dynArgs: map[string]any{ + "dynMap": map[any]any{ + "strKey": "x", + true: 42, + int64(6): mustParseDuration("7m2s"), + }, + }, + expectedOutput: `dyntype map: {"strKey":"x", 6:duration("422s"), true:42}`, + expectedRuntimeCost: 13, + expectedEstimatedCost: checker.CostEstimate{Min: 13, Max: 13}, + }, + { + name: "message field support", + format: "message field msg.single_int32: %d, msg.single_double: %.1f", + formatArgs: `msg.single_int32, msg.single_double`, + dynArgs: map[string]any{ + "msg": &proto3pb.TestAllTypes{ + SingleInt32: 2, + SingleDouble: 1.0, + }, + }, + locale: "en_US", + expectedOutput: `message field msg.single_int32: 2, msg.single_double: 1.0`, + }, + { + name: "unrecognized formatting clause", + format: "%a", + formatArgs: "1", + skipCompileCheck: true, + err: "could not parse formatting clause: unrecognized formatting clause \"a\"", + }, + { + name: "out of bounds arg index", + format: "%d %d %d", + formatArgs: "0, 1", + skipCompileCheck: true, + err: "index 2 out of range", + }, + { + name: "string substitution is not allowed with binary clause", + format: "string is %b", + formatArgs: `"abc"`, + skipCompileCheck: true, + err: "error during formatting: only integers and bools can be formatted as binary, was given string", + }, + { + name: "duration substitution not allowed with decimal clause", + format: "%d", + formatArgs: `duration("30m2s")`, + skipCompileCheck: true, + err: "error during formatting: decimal clause can only be used on integers, was given google.protobuf.Duration", + }, + { + name: "string substitution not allowed with octal clause", + format: "octal: %o", + formatArgs: `"a string"`, + skipCompileCheck: true, + err: "error during formatting: octal clause can only be used on integers, was given string", + }, + { + name: "double substitution not allowed with hex clause", + format: "double is %x", + formatArgs: "0.5", + skipCompileCheck: true, + err: "error during formatting: only integers, byte buffers, and strings can be formatted as hex, was given double", + }, + { + name: "uppercase not allowed for scientific clause", + format: "double is %E", + formatArgs: "0.5", + skipCompileCheck: true, + err: `could not parse formatting clause: unrecognized formatting clause "E"`, + }, + { + name: "object not allowed", + format: "object is %s", + formatArgs: `ext.TestAllTypes{PbVal: test.TestAllTypes{}}`, + skipCompileCheck: true, + err: "error during formatting: string clause can only be used on strings, bools, bytes, ints, doubles, maps, lists, types, durations, and timestamps, was given ext.TestAllTypes", + }, + { + name: "object inside list", + format: "%s", + formatArgs: "[1, 2, ext.TestAllTypes{PbVal: test.TestAllTypes{}}]", + skipCompileCheck: true, + err: "error during formatting: string clause can only be used on strings, bools, bytes, ints, doubles, maps, lists, types, durations, and timestamps, was given ext.TestAllTypes", + }, + { + name: "object inside map", + format: "%s", + formatArgs: `{1: "a", 2: ext.TestAllTypes{}}`, + skipCompileCheck: true, + err: "error during formatting: string clause can only be used on strings, bools, bytes, ints, doubles, maps, lists, types, durations, and timestamps, was given ext.TestAllTypes", + }, + { + name: "null not allowed for %d", + format: "null: %d", + formatArgs: "null", + skipCompileCheck: true, + err: "error during formatting: decimal clause can only be used on integers, was given null_type", + }, + { + name: "null not allowed for %e", + format: "null: %e", + formatArgs: "null", + skipCompileCheck: true, + err: "error during formatting: scientific clause can only be used on doubles, was given null_type", + }, + { + name: "null not allowed for %f", + format: "null: %f", + formatArgs: "null", + skipCompileCheck: true, + err: "error during formatting: fixed-point clause can only be used on doubles, was given null_type", + }, + { + name: "null not allowed for %x", + format: "null: %x", + formatArgs: "null", + skipCompileCheck: true, + err: "error during formatting: only integers, byte buffers, and strings can be formatted as hex, was given null_type", + }, + { + name: "null not allowed for %X", + format: "null: %X", + formatArgs: "null", + skipCompileCheck: true, + err: "error during formatting: only integers, byte buffers, and strings can be formatted as hex, was given null_type", + }, + { + name: "null not allowed for %b", + format: "null: %b", + formatArgs: "null", + skipCompileCheck: true, + err: "error during formatting: only integers and bools can be formatted as binary, was given null_type", + }, + { + name: "null not allowed for %o", + format: "null: %o", + formatArgs: "null", + skipCompileCheck: true, + err: "error during formatting: octal clause can only be used on integers, was given null_type", + }, + { + name: "compile-time cardinality check (too few for string)", + format: "%s %s", + formatArgs: `"abc"`, + err: "index 1 out of range", + }, + { + name: "compile-time cardinality check (too many for string)", + format: "%s %s", + formatArgs: `"abc", "def", "ghi"`, + err: "too many arguments supplied to string.format (expected 2, got 3)", + }, + { + name: "compile-time syntax check (unexpected end of string)", + format: "filler %", + formatArgs: "", + err: "unexpected end of string", + }, + { + name: "compile-time syntax check (unrecognized formatting clause)", + format: "%j", + // pass args here, otherwise the cardinality check will fail first + formatArgs: "123", + err: `could not parse formatting clause: unrecognized formatting clause "j"`, + }, + { + name: "compile-time %s check", + format: "object is %s", + formatArgs: `ext.TestAllTypes{PbVal: test.TestAllTypes{}}`, + err: "error during formatting: string clause can only be used on strings, bools, bytes, ints, doubles, maps, lists, types, durations, and timestamps", + }, + { + name: "compile-time check for objects inside list literal", + format: "list is %s", + formatArgs: `[1, 2, ext.TestAllTypes{PbVal: test.TestAllTypes{}}]`, + err: "error during formatting: string clause can only be used on strings, bools, bytes, ints, doubles, maps, lists, types, durations, and timestamps", + }, + { + name: "compile-time %d check", + format: "int is %d", + formatArgs: "5.2", + err: "error during formatting: decimal clause can only be used on integers", + }, + { + name: "compile-time %f check", + format: "double is %f", + formatArgs: "true", + err: "error during formatting: fixed-point clause can only be used on doubles", + }, + { + name: "compile-time precision syntax check", + format: "double is %.34", + formatArgs: "5.0", + err: "could not parse formatting clause: error while parsing precision: could not find end of precision specifier", + }, + { + name: "compile-time %e check", + format: "double is %e", + formatArgs: "true", + err: "error during formatting: scientific clause can only be used on doubles", + }, + { + name: "compile-time %b check", + format: "string is %b", + formatArgs: `"a string"`, + err: "error during formatting: only integers and bools can be formatted as binary", + }, + { + name: "compile-time %x check", + format: "%x is a double", + formatArgs: "2.5", + err: "error during formatting: only integers, byte buffers, and strings can be formatted as hex", + }, + { + name: "compile-time %X check", + format: "%X is a double", + formatArgs: "2.5", + err: "error during formatting: only integers, byte buffers, and strings can be formatted as hex", + }, + { + name: "compile-time %o check", + format: "an octal: %o", + formatArgs: "3.14", + err: "error during formatting: octal clause can only be used on integers", + }, + } + evalExpr := func(env *cel.Env, expr string, evalArgs any, expectedRuntimeCost uint64, expectedEstimatedCost checker.CostEstimate, t *testing.T) (ref.Val, error) { + t.Logf("evaluating expr: %s", expr) + parsedAst, issues := env.Parse(expr) + if issues.Err() != nil { + t.Fatalf("env.Parse(%v) failed: %v", expr, issues.Err()) + } + checkedAst, issues := env.Check(parsedAst) + if issues.Err() != nil { + return nil, issues.Err() + } + evalOpts := make([]cel.ProgramOption, 0) + costTracker := &noopCostEstimator{} + if expectedRuntimeCost != 0 { + evalOpts = append(evalOpts, cel.CostTracking(costTracker)) + } + program, err := env.Program(checkedAst, evalOpts...) + if err != nil { + return nil, err + } + + actualEstimatedCost, err := env.EstimateCost(checkedAst, costTracker) + if err != nil { + t.Fatal(err) + } + if expectedEstimatedCost.Min != 0 && expectedEstimatedCost.Max != 0 { + if actualEstimatedCost.Min != expectedEstimatedCost.Min && actualEstimatedCost.Max != expectedEstimatedCost.Max { + t.Fatalf("expected estimated cost range to be %v, was %v", expectedEstimatedCost, actualEstimatedCost) + } + } + + var out ref.Val + var details *cel.EvalDetails + if evalArgs != nil { + out, details, err = program.Eval(evalArgs) + } else { + out, details, err = program.Eval(cel.NoVars()) + } + + if expectedRuntimeCost != 0 { + if details == nil { + t.Fatal("no EvalDetails available when runtime cost was expected") + } + if *details.ActualCost() != expectedRuntimeCost { + t.Fatalf("expected runtime cost to be %d, was %d", expectedRuntimeCost, *details.ActualCost()) + } + if expectedEstimatedCost.Min != 0 && expectedEstimatedCost.Max != 0 { + if *details.ActualCost() < expectedEstimatedCost.Min || *details.ActualCost() > expectedEstimatedCost.Max { + t.Fatalf("runtime cost %d outside of expected estimated cost range %v", *details.ActualCost(), expectedEstimatedCost) + } + } + } + return out, err + } + buildVariables := func(vars map[string]any) []cel.EnvOption { + opts := make([]cel.EnvOption, len(vars)) + i := 0 + for name, value := range vars { + t := cel.DynType + switch v := value.(type) { + case proto.Message: + t = cel.ObjectType(string(v.ProtoReflect().Descriptor().FullName())) + case types.Bool: + t = cel.BoolType + case types.Bytes: + t = cel.BytesType + case types.Double: + t = cel.DoubleType + case types.Duration: + t = cel.DurationType + case types.Int: + t = cel.IntType + case types.Null: + t = cel.NullType + case types.String: + t = cel.StringType + case types.Timestamp: + t = cel.TimestampType + case types.Uint: + t = cel.UintType + } + opts[i] = cel.Variable(name, t) + i++ + } + return opts + } + buildOpts := func(skipCompileCheck bool, locale string, variables []cel.EnvOption) []cel.EnvOption { + opts := []cel.EnvOption{ + Strings(StringsLocale(locale), StringsValidateFormatCalls(!skipCompileCheck), StringsVersion(3)), + cel.Container("ext"), + cel.Abbrevs("google.expr.proto3.test"), + cel.Types(&proto3pb.TestAllTypes{}), + NativeTypes( + reflect.TypeOf(&TestNestedType{}), + reflect.ValueOf(&TestAllTypes{}), + ), + } + opts = append(opts, cel.ASTValidators(cel.ValidateHomogeneousAggregateLiterals())) + opts = append(opts, variables...) + return opts + } + runCase := func(format, formatArgs, locale string, dynArgs map[string]any, skipCompileCheck bool, expectedRuntimeCost uint64, expectedEstimatedCost checker.CostEstimate, t *testing.T) (ref.Val, error) { + env, err := cel.NewEnv(buildOpts(skipCompileCheck, locale, buildVariables(dynArgs))...) + if err != nil { + t.Fatalf("cel.NewEnv() failed: %v", err) + } + expr := fmt.Sprintf("%q.format([%s])", format, formatArgs) + if len(dynArgs) == 0 { + return evalExpr(env, expr, cel.NoVars(), expectedRuntimeCost, expectedEstimatedCost, t) + } + return evalExpr(env, expr, dynArgs, expectedRuntimeCost, expectedEstimatedCost, t) + } + checkCase := func(output ref.Val, expectedOutput string, err error, expectedErr string, t *testing.T) { + if err != nil { + if expectedErr != "" { + if !strings.Contains(err.Error(), expectedErr) { + t.Fatalf("expected %q as error message, got %q", expectedErr, err.Error()) + } + } else { + t.Fatalf("unexpected error: %s", err) + } + } else { + if output.Type() != types.StringType { + t.Fatalf("expected test expr to eval to string (got %s instead)", output.Type().TypeName()) + } else { + outputStr := output.Value().(string) + if outputStr != expectedOutput { + t.Errorf("expected %q as output, got %q", expectedOutput, outputStr) + } + } + } + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + out, err := runCase(tt.format, tt.formatArgs, tt.locale, tt.dynArgs, tt.skipCompileCheck, tt.expectedRuntimeCost, tt.expectedEstimatedCost, t) + checkCase(out, tt.expectedOutput, err, tt.err, t) + if tt.locale == "" { + // if the test has no locale specified, then that means it + // should have the same output regardless of locale + t.Run("no change on locale", func(t *testing.T) { + out, err := runCase(tt.format, tt.formatArgs, "da_DK", tt.dynArgs, tt.skipCompileCheck, tt.expectedRuntimeCost, tt.expectedEstimatedCost, t) + checkCase(out, tt.expectedOutput, err, tt.err, t) + }) + } + }) + } +} + +func TestStringFormatHeterogeneousLiterals(t *testing.T) { + tests := []struct { + expr string + out string + }{ + { + expr: `"list: %s".format([[[1, 2, [3.0, 4]]]])`, + out: `list: [[1, 2, [3.000000, 4]]]`, + }, + { + expr: `"list size: %d".format([[[1, 2, [3.0, 4]]].size()])`, + out: `list size: 1`, + }, + { + expr: `"list element: %s".format([[[1, 2, [3.0, 4]]][0]])`, + out: `list element: [1, 2, [3.000000, 4]]`, + }, + } + env, err := cel.NewEnv(Strings(StringsVersion(3)), cel.ASTValidators(cel.ValidateHomogeneousAggregateLiterals())) + if err != nil { + t.Fatalf("cel.NewEnv() failed: %v", err) + } + for _, tst := range tests { + tc := tst + t.Run(tc.expr, func(t *testing.T) { + ast, iss := env.Compile(tc.expr) + if iss.Err() != nil { + t.Fatalf("env.Compile(%q) failed: %v", tc.expr, iss.Err()) + } + prg, err := env.Program(ast) + if err != nil { + t.Fatalf("env.Program() failed: %v", err) + } + out, _, err := prg.Eval(cel.NoVars()) + if err != nil { + t.Fatalf("Eval() failed: %v", err) + } + if out.Value() != tc.out { + t.Errorf("Eval() got %v, wanted %v", out, tc.out) + } + }) + } +} + +func TestBadLocale(t *testing.T) { + _, err := cel.NewEnv(Strings(StringsLocale("bad-locale"), StringsVersion(3))) + if err != nil { + if err.Error() != "failed to parse locale: language: subtag \"locale\" is well-formed but unknown" { + t.Errorf("expected error messaged to be \"failed to parse locale: language: subtag \"locale\" is well-formed but unknown\", got %q", err) + } + } else { + t.Error("expected NewEnv to fail during locale parsing") + } +} + +func TestLiteralOutput(t *testing.T) { + tests := []struct { + name string + formatLiteral string + expectedType string + }{ + { + name: "map literal support", + formatLiteral: `{"key1": b"xyz", false: [11, 12, 13, timestamp("2019-10-12T07:20:50.52Z")], 42: {uint(64): 2.7}, "key5": type(int), "key2": duration("2h"), "key4": true, "key3": 2.71828, "null": null}`, + expectedType: `map`, + }, + { + name: "list literal support", + formatLiteral: `["abc", 3.14, uint(32), b"def", null, type(string), duration("7m"), [9, 8, 7, 6], timestamp("2023-02-03T23:31:20Z")]`, + expectedType: `list`, + }, + } + for _, tt := range tests { + parseAndEval := func(expr string, t *testing.T) (ref.Val, error) { + env, err := cel.NewEnv(Strings(StringsVersion(3))) + if err != nil { + t.Fatalf("cel.NewEnv(Strings(StringsVersion(3))) failed: %v", err) + } + parsedAst, issues := env.Parse(expr) + if issues.Err() != nil { + t.Fatalf("env.Parse(%v) failed: %v", expr, issues.Err()) + } + checkedAst, issues := env.Check(parsedAst) + if issues.Err() != nil { + t.Fatalf("env.Check(%v) failed: %v", expr, issues.Err()) + } + program, err := env.Program(checkedAst) + if err != nil { + t.Fatal(err) + } + out, _, err := program.Eval(cel.NoVars()) + return out, err + } + t.Run(tt.name, func(t *testing.T) { + expr := fmt.Sprintf(`"%%s".format([%s])`, tt.formatLiteral) + literalVal, err := parseAndEval(expr, t) + if err != nil { + t.Fatalf("program.Eval failed: %v", err) + } + out, err := parseAndEval(literalVal.Value().(string), t) + if err != nil { + t.Fatalf("literal evaluation failed: %v", err) + } + if out.Type().TypeName() != tt.expectedType { + t.Errorf("expected literal to evaluate to type %s, got %s", tt.expectedType, out.Type().TypeName()) + } + equivalentVal, err := parseAndEval(literalVal.Value().(string)+" == "+tt.formatLiteral, t) + if err != nil { + t.Fatalf("equality evaluation failed: %v:", err) + } + if equivalentVal.Type().TypeName() != "bool" { + t.Errorf("expected equality expression to evaluation to type bool, got %s", equivalentVal.Type().TypeName()) + } + equivalent := equivalentVal.Value().(bool) + if !equivalent { + t.Errorf("%q (observed) and %q (expected) not considered equivalent", literalVal.Value().(string), tt.formatLiteral) + } + }) + } +} diff --git a/ext/formatting_v2.go b/ext/formatting_v2.go new file mode 100644 index 000000000..3aa3a51eb --- /dev/null +++ b/ext/formatting_v2.go @@ -0,0 +1,772 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ext + +import ( + "errors" + "fmt" + "math" + "sort" + "strconv" + "strings" + "time" + "unicode" + + "github.com/google/cel-go/cel" + "github.com/google/cel-go/common/ast" + "github.com/google/cel-go/common/types" + "github.com/google/cel-go/common/types/ref" + "github.com/google/cel-go/common/types/traits" +) + +type clauseImplV2 func(ref.Val) (string, error) + +type appendingFormatterV2 struct { + buf []byte +} + +type formattedMapEntryV2 struct { + key string + val string +} + +func (af *appendingFormatterV2) format(arg ref.Val) error { + switch arg.Type() { + case types.BoolType: + argBool, ok := arg.Value().(bool) + if !ok { + return fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.BoolType) + } + af.buf = strconv.AppendBool(af.buf, argBool) + return nil + case types.IntType: + argInt, ok := arg.Value().(int64) + if !ok { + return fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.IntType) + } + af.buf = strconv.AppendInt(af.buf, argInt, 10) + return nil + case types.UintType: + argUint, ok := arg.Value().(uint64) + if !ok { + return fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.UintType) + } + af.buf = strconv.AppendUint(af.buf, argUint, 10) + return nil + case types.DoubleType: + argDbl, ok := arg.Value().(float64) + if !ok { + return fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.DoubleType) + } + if math.IsNaN(argDbl) { + af.buf = append(af.buf, "NaN"...) + return nil + } + if math.IsInf(argDbl, -1) { + af.buf = append(af.buf, "-Infinity"...) + return nil + } + if math.IsInf(argDbl, 1) { + af.buf = append(af.buf, "Infinity"...) + return nil + } + af.buf = strconv.AppendFloat(af.buf, argDbl, 'f', -1, 64) + return nil + case types.BytesType: + argBytes, ok := arg.Value().([]byte) + if !ok { + return fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.BytesType) + } + af.buf = append(af.buf, argBytes...) + return nil + case types.StringType: + argStr, ok := arg.Value().(string) + if !ok { + return fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.StringType) + } + af.buf = append(af.buf, argStr...) + return nil + case types.DurationType: + argDur, ok := arg.Value().(time.Duration) + if !ok { + return fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.DurationType) + } + af.buf = strconv.AppendFloat(af.buf, argDur.Seconds(), 'f', -1, 64) + af.buf = append(af.buf, "s"...) + return nil + case types.TimestampType: + argTime, ok := arg.Value().(time.Time) + if !ok { + return fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.TimestampType) + } + af.buf = argTime.UTC().AppendFormat(af.buf, time.RFC3339Nano) + return nil + case types.NullType: + af.buf = append(af.buf, "null"...) + return nil + case types.TypeType: + argType, ok := arg.Value().(string) + if !ok { + return fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.TypeType) + } + af.buf = append(af.buf, argType...) + return nil + case types.ListType: + argList, ok := arg.(traits.Lister) + if !ok { + return fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.ListType) + } + argIter := argList.Iterator() + af.buf = append(af.buf, "["...) + if argIter.HasNext() == types.True { + if err := af.format(argIter.Next()); err != nil { + return err + } + for argIter.HasNext() == types.True { + af.buf = append(af.buf, ", "...) + if err := af.format(argIter.Next()); err != nil { + return err + } + } + } + af.buf = append(af.buf, "]"...) + return nil + case types.MapType: + argMap, ok := arg.(traits.Mapper) + if !ok { + return fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.MapType) + } + argIter := argMap.Iterator() + ents := []formattedMapEntryV2{} + for argIter.HasNext() == types.True { + key := argIter.Next() + val, ok := argMap.Find(key) + if !ok { + return fmt.Errorf("key missing from map: '%s'", key) + } + keyStr, err := formatStringV2(key) + if err != nil { + return err + } + valStr, err := formatStringV2(val) + if err != nil { + return err + } + ents = append(ents, formattedMapEntryV2{keyStr, valStr}) + } + sort.SliceStable(ents, func(x, y int) bool { + return ents[x].key < ents[y].key + }) + af.buf = append(af.buf, "{"...) + for i, e := range ents { + if i > 0 { + af.buf = append(af.buf, ", "...) + } + af.buf = append(af.buf, e.key...) + af.buf = append(af.buf, ": "...) + af.buf = append(af.buf, e.val...) + } + af.buf = append(af.buf, "}"...) + return nil + default: + return stringFormatErrorV2(runtimeID, arg.Type().TypeName()) + } +} + +func formatStringV2(arg ref.Val) (string, error) { + var fmter appendingFormatterV2 + if err := fmter.format(arg); err != nil { + return "", err + } + return string(fmter.buf), nil +} + +type stringFormatterV2 struct{} + +func (c *stringFormatterV2) String(arg ref.Val) (string, error) { + return formatStringV2(arg) +} + +func (c *stringFormatterV2) Decimal(arg ref.Val) (string, error) { + switch arg.Type() { + case types.IntType: + argInt, ok := arg.Value().(int64) + if !ok { + return "", fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.IntType) + } + return strconv.FormatInt(argInt, 10), nil + case types.UintType: + argUint, ok := arg.Value().(uint64) + if !ok { + return "", fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.UintType) + } + return strconv.FormatUint(argUint, 10), nil + case types.DoubleType: + argDbl, ok := arg.Value().(float64) + if !ok { + return "", fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.DoubleType) + } + if math.IsNaN(argDbl) { + return "NaN", nil + } + if math.IsInf(argDbl, -1) { + return "-Infinity", nil + } + if math.IsInf(argDbl, 1) { + return "Infinity", nil + } + return strconv.FormatFloat(argDbl, 'f', -1, 64), nil + default: + return "", decimalFormatErrorV2(runtimeID, arg.Type().TypeName()) + } +} + +func (c *stringFormatterV2) Fixed(precision int) func(ref.Val) (string, error) { + return func(arg ref.Val) (string, error) { + fmtStr := fmt.Sprintf("%%.%df", precision) + switch arg.Type() { + case types.IntType: + argInt, ok := arg.Value().(int64) + if !ok { + return "", fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.IntType) + } + return fmt.Sprintf(fmtStr, argInt), nil + case types.UintType: + argUint, ok := arg.Value().(uint64) + if !ok { + return "", fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.UintType) + } + return fmt.Sprintf(fmtStr, argUint), nil + case types.DoubleType: + argDbl, ok := arg.Value().(float64) + if !ok { + return "", fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.DoubleType) + } + if math.IsNaN(argDbl) { + return "NaN", nil + } + if math.IsInf(argDbl, -1) { + return "-Infinity", nil + } + if math.IsInf(argDbl, 1) { + return "Infinity", nil + } + return fmt.Sprintf(fmtStr, argDbl), nil + default: + return "", fixedPointFormatErrorV2(runtimeID, arg.Type().TypeName()) + } + } +} + +func (c *stringFormatterV2) Scientific(precision int) func(ref.Val) (string, error) { + return func(arg ref.Val) (string, error) { + fmtStr := fmt.Sprintf("%%1.%de", precision) + switch arg.Type() { + case types.IntType: + argInt, ok := arg.Value().(int64) + if !ok { + return "", fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.IntType) + } + return fmt.Sprintf(fmtStr, argInt), nil + case types.UintType: + argUint, ok := arg.Value().(uint64) + if !ok { + return "", fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.UintType) + } + return fmt.Sprintf(fmtStr, argUint), nil + case types.DoubleType: + argDbl, ok := arg.Value().(float64) + if !ok { + return "", fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.DoubleType) + } + if math.IsNaN(argDbl) { + return "NaN", nil + } + if math.IsInf(argDbl, -1) { + return "-Infinity", nil + } + if math.IsInf(argDbl, 1) { + return "Infinity", nil + } + return fmt.Sprintf(fmtStr, argDbl), nil + default: + return "", scientificFormatErrorV2(runtimeID, arg.Type().TypeName()) + } + } +} + +func (c *stringFormatterV2) Binary(arg ref.Val) (string, error) { + switch arg.Type() { + case types.BoolType: + argBool, ok := arg.Value().(bool) + if !ok { + return "", fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.BoolType) + } + if argBool { + return "1", nil + } + return "0", nil + case types.IntType: + argInt, ok := arg.Value().(int64) + if !ok { + return "", fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.IntType) + } + return strconv.FormatInt(argInt, 2), nil + case types.UintType: + argUint, ok := arg.Value().(uint64) + if !ok { + return "", fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.UintType) + } + return strconv.FormatUint(argUint, 2), nil + default: + return "", binaryFormatErrorV2(runtimeID, arg.Type().TypeName()) + } +} + +func (c *stringFormatterV2) Hex(useUpper bool) func(ref.Val) (string, error) { + return func(arg ref.Val) (string, error) { + var fmtStr string + if useUpper { + fmtStr = "%X" + } else { + fmtStr = "%x" + } + switch arg.Type() { + case types.IntType: + argInt, ok := arg.Value().(int64) + if !ok { + return "", fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.IntType) + } + return fmt.Sprintf(fmtStr, argInt), nil + case types.UintType: + argUint, ok := arg.Value().(uint64) + if !ok { + return "", fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.UintType) + } + return fmt.Sprintf(fmtStr, argUint), nil + case types.StringType: + argStr, ok := arg.Value().(string) + if !ok { + return "", fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.StringType) + } + return fmt.Sprintf(fmtStr, argStr), nil + case types.BytesType: + argBytes, ok := arg.Value().([]byte) + if !ok { + return "", fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.BytesType) + } + return fmt.Sprintf(fmtStr, argBytes), nil + default: + return "", hexFormatErrorV2(runtimeID, arg.Type().TypeName()) + } + } +} + +func (c *stringFormatterV2) Octal(arg ref.Val) (string, error) { + switch arg.Type() { + case types.IntType: + argInt, ok := arg.Value().(int64) + if !ok { + return "", fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.IntType) + } + return strconv.FormatInt(argInt, 8), nil + case types.UintType: + argUint, ok := arg.Value().(uint64) + if !ok { + return "", fmt.Errorf("type conversion error from '%s' to '%s'", arg.Type(), types.UintType) + } + return strconv.FormatUint(argUint, 8), nil + default: + return "", octalFormatErrorV2(runtimeID, arg.Type().TypeName()) + } +} + +// stringFormatValidatorV2 implements the cel.ASTValidator interface allowing for static validation +// of string.format calls. +type stringFormatValidatorV2 struct{} + +// Name returns the name of the validator. +func (stringFormatValidatorV2) Name() string { + return "cel.validator.string_format" +} + +// Configure implements the ASTValidatorConfigurer interface and augments the list of functions to skip +// during homogeneous aggregate literal type-checks. +func (stringFormatValidatorV2) Configure(config cel.MutableValidatorConfig) error { + functions := config.GetOrDefault(cel.HomogeneousAggregateLiteralExemptFunctions, []string{}).([]string) + functions = append(functions, "format") + return config.Set(cel.HomogeneousAggregateLiteralExemptFunctions, functions) +} + +// Validate parses all literal format strings and type checks the format clause against the argument +// at the corresponding ordinal within the list literal argument to the function, if one is specified. +func (stringFormatValidatorV2) Validate(env *cel.Env, _ cel.ValidatorConfig, a *ast.AST, iss *cel.Issues) { + root := ast.NavigateAST(a) + formatCallExprs := ast.MatchDescendants(root, matchConstantFormatStringWithListLiteralArgs(a)) + for _, e := range formatCallExprs { + call := e.AsCall() + formatStr := call.Target().AsLiteral().Value().(string) + args := call.Args()[0].AsList().Elements() + formatCheck := &stringFormatCheckerV2{ + args: args, + ast: a, + } + // use a placeholder locale, since locale doesn't affect syntax + _, err := parseFormatStringV2(formatStr, formatCheck, formatCheck) + if err != nil { + iss.ReportErrorAtID(getErrorExprID(e.ID(), err), "%v", err) + continue + } + seenArgs := formatCheck.argsRequested + if len(args) > seenArgs { + iss.ReportErrorAtID(e.ID(), + "too many arguments supplied to string.format (expected %d, got %d)", seenArgs, len(args)) + } + } +} + +// stringFormatCheckerV2 implements the formatStringInterpolater interface +type stringFormatCheckerV2 struct { + args []ast.Expr + argsRequested int + currArgIndex int64 + ast *ast.AST +} + +func (c *stringFormatCheckerV2) String(arg ref.Val) (string, error) { + formatArg := c.args[c.currArgIndex] + valid, badID := c.verifyString(formatArg) + if !valid { + return "", stringFormatErrorV2(badID, c.typeOf(badID).TypeName()) + } + return "", nil +} + +func (c *stringFormatCheckerV2) Decimal(arg ref.Val) (string, error) { + id := c.args[c.currArgIndex].ID() + valid := c.verifyTypeOneOf(id, types.IntType, types.UintType, types.DoubleType) + if !valid { + return "", decimalFormatErrorV2(id, c.typeOf(id).TypeName()) + } + return "", nil +} + +func (c *stringFormatCheckerV2) Fixed(precision int) func(ref.Val) (string, error) { + return func(arg ref.Val) (string, error) { + id := c.args[c.currArgIndex].ID() + valid := c.verifyTypeOneOf(id, types.IntType, types.UintType, types.DoubleType) + if !valid { + return "", fixedPointFormatErrorV2(id, c.typeOf(id).TypeName()) + } + return "", nil + } +} + +func (c *stringFormatCheckerV2) Scientific(precision int) func(ref.Val) (string, error) { + return func(arg ref.Val) (string, error) { + id := c.args[c.currArgIndex].ID() + valid := c.verifyTypeOneOf(id, types.IntType, types.UintType, types.DoubleType) + if !valid { + return "", scientificFormatErrorV2(id, c.typeOf(id).TypeName()) + } + return "", nil + } +} + +func (c *stringFormatCheckerV2) Binary(arg ref.Val) (string, error) { + id := c.args[c.currArgIndex].ID() + valid := c.verifyTypeOneOf(id, types.BoolType, types.IntType, types.UintType) + if !valid { + return "", binaryFormatErrorV2(id, c.typeOf(id).TypeName()) + } + return "", nil +} + +func (c *stringFormatCheckerV2) Hex(useUpper bool) func(ref.Val) (string, error) { + return func(arg ref.Val) (string, error) { + id := c.args[c.currArgIndex].ID() + valid := c.verifyTypeOneOf(id, types.IntType, types.UintType, types.StringType, types.BytesType) + if !valid { + return "", hexFormatErrorV2(id, c.typeOf(id).TypeName()) + } + return "", nil + } +} + +func (c *stringFormatCheckerV2) Octal(arg ref.Val) (string, error) { + id := c.args[c.currArgIndex].ID() + valid := c.verifyTypeOneOf(id, types.IntType, types.UintType) + if !valid { + return "", octalFormatErrorV2(id, c.typeOf(id).TypeName()) + } + return "", nil +} + +func (c *stringFormatCheckerV2) Arg(index int64) (ref.Val, error) { + c.argsRequested++ + c.currArgIndex = index + // return a dummy value - this is immediately passed to back to us + // through one of the FormatCallback functions, so anything will do + return types.Int(0), nil +} + +func (c *stringFormatCheckerV2) Size() int64 { + return int64(len(c.args)) +} + +func (c *stringFormatCheckerV2) typeOf(id int64) *cel.Type { + return c.ast.GetType(id) +} + +func (c *stringFormatCheckerV2) verifyTypeOneOf(id int64, validTypes ...*cel.Type) bool { + t := c.typeOf(id) + if t == cel.DynType { + return true + } + for _, vt := range validTypes { + // Only check runtime type compatibility without delving deeper into parameterized types + if t.Kind() == vt.Kind() { + return true + } + } + return false +} + +func (c *stringFormatCheckerV2) verifyString(sub ast.Expr) (bool, int64) { + paramA := cel.TypeParamType("A") + paramB := cel.TypeParamType("B") + subVerified := c.verifyTypeOneOf(sub.ID(), + cel.ListType(paramA), cel.MapType(paramA, paramB), + cel.IntType, cel.UintType, cel.DoubleType, cel.BoolType, cel.StringType, + cel.TimestampType, cel.BytesType, cel.DurationType, cel.TypeType, cel.NullType) + if !subVerified { + return false, sub.ID() + } + switch sub.Kind() { + case ast.ListKind: + for _, e := range sub.AsList().Elements() { + // recursively verify if we're dealing with a list/map + verified, id := c.verifyString(e) + if !verified { + return false, id + } + } + return true, sub.ID() + case ast.MapKind: + for _, e := range sub.AsMap().Entries() { + // recursively verify if we're dealing with a list/map + entry := e.AsMapEntry() + verified, id := c.verifyString(entry.Key()) + if !verified { + return false, id + } + verified, id = c.verifyString(entry.Value()) + if !verified { + return false, id + } + } + return true, sub.ID() + default: + return true, sub.ID() + } +} + +// helper routines for reporting common errors during string formatting static validation and +// runtime execution. + +func binaryFormatErrorV2(id int64, badType string) error { + return newFormatError(id, "only ints, uints, and bools can be formatted as binary, was given %s", badType) +} + +func decimalFormatErrorV2(id int64, badType string) error { + return newFormatError(id, "decimal clause can only be used on ints, uints, and doubles, was given %s", badType) +} + +func fixedPointFormatErrorV2(id int64, badType string) error { + return newFormatError(id, "fixed-point clause can only be used on ints, uints, and doubles, was given %s", badType) +} + +func hexFormatErrorV2(id int64, badType string) error { + return newFormatError(id, "only ints, uints, bytes, and strings can be formatted as hex, was given %s", badType) +} + +func octalFormatErrorV2(id int64, badType string) error { + return newFormatError(id, "octal clause can only be used on ints and uints, was given %s", badType) +} + +func scientificFormatErrorV2(id int64, badType string) error { + return newFormatError(id, "scientific clause can only be used on ints, uints, and doubles, was given %s", badType) +} + +func stringFormatErrorV2(id int64, badType string) error { + return newFormatError(id, "string clause can only be used on strings, bools, bytes, ints, doubles, maps, lists, types, durations, and timestamps, was given %s", badType) +} + +// formatStringInterpolatorV2 is an interface that allows user-defined behavior +// for formatting clause implementations, as well as argument retrieval. +// Each function is expected to support the appropriate types as laid out in +// the string.format documentation, and to return an error if given an inappropriate type. +type formatStringInterpolatorV2 interface { + // String takes a ref.Val and a string representing the current locale identifier + // and returns the Val formatted as a string, or an error if one occurred. + String(ref.Val) (string, error) + + // Decimal takes a ref.Val and a string representing the current locale identifier + // and returns the Val formatted as a decimal integer, or an error if one occurred. + Decimal(ref.Val) (string, error) + + // Fixed takes an int pointer representing precision (or nil if none was given) and + // returns a function operating in a similar manner to String and Decimal, taking a + // ref.Val and locale and returning the appropriate string. A closure is returned + // so precision can be set without needing an additional function call/configuration. + Fixed(int) func(ref.Val) (string, error) + + // Scientific functions identically to Fixed, except the string returned from the closure + // is expected to be in scientific notation. + Scientific(int) func(ref.Val) (string, error) + + // Binary takes a ref.Val and a string representing the current locale identifier + // and returns the Val formatted as a binary integer, or an error if one occurred. + Binary(ref.Val) (string, error) + + // Hex takes a boolean that, if true, indicates the hex string output by the returned + // closure should use uppercase letters for A-F. + Hex(bool) func(ref.Val) (string, error) + + // Octal takes a ref.Val and a string representing the current locale identifier and + // returns the Val formatted in octal, or an error if one occurred. + Octal(ref.Val) (string, error) +} + +// parseFormatString formats a string according to the string.format syntax, taking the clause implementations +// from the provided FormatCallback and the args from the given FormatList. +func parseFormatStringV2(formatStr string, callback formatStringInterpolatorV2, list formatListArgs) (string, error) { + i := 0 + argIndex := 0 + var builtStr strings.Builder + for i < len(formatStr) { + if formatStr[i] == '%' { + if i+1 < len(formatStr) && formatStr[i+1] == '%' { + err := builtStr.WriteByte('%') + if err != nil { + return "", fmt.Errorf("error writing format string: %w", err) + } + i += 2 + continue + } else { + argAny, err := list.Arg(int64(argIndex)) + if err != nil { + return "", err + } + if i+1 >= len(formatStr) { + return "", errors.New("unexpected end of string") + } + if int64(argIndex) >= list.Size() { + return "", fmt.Errorf("index %d out of range", argIndex) + } + numRead, val, refErr := parseAndFormatClauseV2(formatStr[i:], argAny, callback, list) + if refErr != nil { + return "", refErr + } + _, err = builtStr.WriteString(val) + if err != nil { + return "", fmt.Errorf("error writing format string: %w", err) + } + i += numRead + argIndex++ + } + } else { + err := builtStr.WriteByte(formatStr[i]) + if err != nil { + return "", fmt.Errorf("error writing format string: %w", err) + } + i++ + } + } + return builtStr.String(), nil +} + +// parseAndFormatClause parses the format clause at the start of the given string with val, and returns +// how many characters were consumed and the substituted string form of val, or an error if one occurred. +func parseAndFormatClauseV2(formatStr string, val ref.Val, callback formatStringInterpolatorV2, list formatListArgs) (int, string, error) { + i := 1 + read, formatter, err := parseFormattingClauseV2(formatStr[i:], callback) + i += read + if err != nil { + return -1, "", newParseFormatError("could not parse formatting clause", err) + } + + valStr, err := formatter(val) + if err != nil { + return -1, "", newParseFormatError("error during formatting", err) + } + return i, valStr, nil +} + +func parseFormattingClauseV2(formatStr string, callback formatStringInterpolatorV2) (int, clauseImplV2, error) { + i := 0 + read, precision, err := parsePrecisionV2(formatStr[i:]) + i += read + if err != nil { + return -1, nil, fmt.Errorf("error while parsing precision: %w", err) + } + r := rune(formatStr[i]) + i++ + switch r { + case 's': + return i, callback.String, nil + case 'd': + return i, callback.Decimal, nil + case 'f': + return i, callback.Fixed(precision), nil + case 'e': + return i, callback.Scientific(precision), nil + case 'b': + return i, callback.Binary, nil + case 'x', 'X': + return i, callback.Hex(unicode.IsUpper(r)), nil + case 'o': + return i, callback.Octal, nil + default: + return -1, nil, fmt.Errorf("unrecognized formatting clause \"%c\"", r) + } +} + +func parsePrecisionV2(formatStr string) (int, int, error) { + i := 0 + if formatStr[i] != '.' { + return i, defaultPrecision, nil + } + i++ + var buffer strings.Builder + for { + if i >= len(formatStr) { + return -1, -1, errors.New("could not find end of precision specifier") + } + if !isASCIIDigit(rune(formatStr[i])) { + break + } + buffer.WriteByte(formatStr[i]) + i++ + } + precision, err := strconv.Atoi(buffer.String()) + if err != nil { + return -1, -1, fmt.Errorf("error while converting precision to integer: %w", err) + } + if precision < 0 { + return -1, -1, fmt.Errorf("negative precision: %d", precision) + } + return i, precision, nil +} diff --git a/ext/formatting_v2_test.go b/ext/formatting_v2_test.go new file mode 100644 index 000000000..d574e62de --- /dev/null +++ b/ext/formatting_v2_test.go @@ -0,0 +1,1015 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ext + +import ( + "fmt" + "math" + "reflect" + "strings" + "testing" + "time" + + "google.golang.org/protobuf/proto" + + "github.com/google/cel-go/cel" + "github.com/google/cel-go/checker" + "github.com/google/cel-go/common/types" + "github.com/google/cel-go/common/types/ref" + + proto3pb "github.com/google/cel-go/test/proto3pb" +) + +func TestStringsWithExtensionV2(t *testing.T) { + env, err := cel.NewEnv(Strings()) + if err != nil { + t.Fatalf("cel.NewEnv(Strings()) failed: %v", err) + } + _, err = env.Extend(Strings()) + if err != nil { + t.Fatalf("env.Extend(Strings()) failed: %v", err) + } +} + +func TestStringFormatV2(t *testing.T) { + tests := []struct { + name string + format string + dynArgs map[string]any + formatArgs string + err string + expectedOutput string + expectedRuntimeCost uint64 + expectedEstimatedCost checker.CostEstimate + skipCompileCheck bool + }{ + { + name: "no-op", + format: "no substitution", + expectedOutput: "no substitution", + expectedRuntimeCost: 12, + expectedEstimatedCost: checker.CostEstimate{Min: 12, Max: 12}, + }, + + { + name: "mid-string substitution", + format: "str is %s and some more", + formatArgs: `"filler"`, + expectedOutput: "str is filler and some more", + expectedRuntimeCost: 13, + expectedEstimatedCost: checker.CostEstimate{Min: 13, Max: 13}, + }, + { + name: "percent escaping", + format: "%% and also %%", + expectedOutput: "% and also %", + expectedRuntimeCost: 12, + expectedEstimatedCost: checker.CostEstimate{Min: 12, Max: 12}, + }, + { + name: "substution inside escaped percent signs", + format: "%%%s%%", + formatArgs: `"text"`, + expectedOutput: "%text%", + expectedRuntimeCost: 11, + expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, + }, + { + name: "substitution with one escaped percent sign on the right", + format: "%s%%", + formatArgs: `"percent on the right"`, + expectedOutput: "percent on the right%", + expectedRuntimeCost: 11, + expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, + }, + { + name: "substitution with one escaped percent sign on the left", + format: "%%%s", + formatArgs: `"percent on the left"`, + expectedOutput: "%percent on the left", + expectedRuntimeCost: 11, + expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, + }, + { + name: "multiple substitutions", + format: "%d %d %d, %s %s %s, %d %d %d, %s %s %s", + formatArgs: `1, 2, 3, "A", "B", "C", 4, 5, 6, "D", "E", "F"`, + expectedOutput: "1 2 3, A B C, 4 5 6, D E F", + expectedRuntimeCost: 14, + expectedEstimatedCost: checker.CostEstimate{Min: 14, Max: 14}, + }, + { + name: "percent sign escape sequence support", + format: "\u0025\u0025escaped \u0025s\u0025\u0025", + formatArgs: `"percent"`, + expectedOutput: "%escaped percent%", + expectedRuntimeCost: 12, + expectedEstimatedCost: checker.CostEstimate{Min: 12, Max: 12}, + }, + { + name: "fixed point formatting clause", + format: "%.3f", + formatArgs: "1.2345", + expectedOutput: "1.234", + expectedRuntimeCost: 11, + expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, + }, + { + name: "binary formatting clause", + format: "this is 5 in binary: %b", + formatArgs: "5", + expectedOutput: "this is 5 in binary: 101", + expectedRuntimeCost: 13, + expectedEstimatedCost: checker.CostEstimate{Min: 13, Max: 13}, + }, + { + name: "negative binary formatting clause", + format: "this is -5 in binary: %b", + formatArgs: "-5", + expectedOutput: "this is -5 in binary: -101", + expectedRuntimeCost: 13, + expectedEstimatedCost: checker.CostEstimate{Min: 13, Max: 13}, + }, + { + name: "uint support for binary formatting", + format: "unsigned 64 in binary: %b", + formatArgs: "uint(64)", + expectedOutput: "unsigned 64 in binary: 1000000", + expectedRuntimeCost: 14, + expectedEstimatedCost: checker.CostEstimate{Min: 14, Max: 14}, + }, + { + name: "bool support for binary formatting", + format: "bit set from bool: %b", + formatArgs: "true", + expectedOutput: "bit set from bool: 1", + expectedRuntimeCost: 13, + expectedEstimatedCost: checker.CostEstimate{Min: 13, Max: 13}, + }, + { + name: "octal formatting clause", + format: "%o", + formatArgs: "11", + expectedOutput: "13", + expectedRuntimeCost: 11, + expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, + }, + { + name: "negative octal formatting clause", + format: "%o", + formatArgs: "-11", + expectedOutput: "-13", + expectedRuntimeCost: 11, + expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, + }, + { + name: "uint support for octal formatting clause", + format: "this is an unsigned octal: %o", + formatArgs: "uint(65535)", + expectedOutput: "this is an unsigned octal: 177777", + expectedRuntimeCost: 14, + expectedEstimatedCost: checker.CostEstimate{Min: 14, Max: 14}, + }, + { + name: "lowercase hexadecimal formatting clause", + format: "%x is 30 in hexadecimal", + formatArgs: "30", + expectedOutput: "1e is 30 in hexadecimal", + expectedRuntimeCost: 13, + expectedEstimatedCost: checker.CostEstimate{Min: 13, Max: 13}, + }, + { + name: "uppercase hexadecimal formatting clause", + format: "%X is 20 in hexadecimal", + formatArgs: "30", + expectedOutput: "1E is 20 in hexadecimal", + expectedRuntimeCost: 13, + expectedEstimatedCost: checker.CostEstimate{Min: 13, Max: 13}, + }, + { + name: "negative hexadecimal formatting clause", + format: "%x is -30 in hexadecimal", + formatArgs: "-30", + expectedOutput: "-1e is -30 in hexadecimal", + expectedRuntimeCost: 13, + expectedEstimatedCost: checker.CostEstimate{Min: 13, Max: 13}, + }, + { + name: "unsigned support for hexadecimal formatting clause", + format: "%X is 6000 in hexadecimal", + formatArgs: "uint(6000)", + expectedOutput: "1770 is 6000 in hexadecimal", + expectedRuntimeCost: 14, + expectedEstimatedCost: checker.CostEstimate{Min: 14, Max: 14}, + }, + { + name: "string support with hexadecimal formatting clause", + format: "%x", + formatArgs: `"Hello world!"`, + expectedOutput: "48656c6c6f20776f726c6421", + expectedRuntimeCost: 11, + expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, + }, + { + name: "string support with uppercase hexadecimal formatting clause", + format: "%X", + formatArgs: `"Hello world!"`, + expectedOutput: "48656C6C6F20776F726C6421", + expectedRuntimeCost: 11, + expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, + }, + { + name: "byte support with hexadecimal formatting clause", + format: "%x", + formatArgs: `b"byte string"`, + expectedOutput: "6279746520737472696e67", + expectedRuntimeCost: 11, + expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, + }, + { + name: "byte support with hexadecimal formatting clause leading zero", + format: "%x", + formatArgs: `b"\x00\x00byte string\x00"`, + expectedOutput: "00006279746520737472696e6700", + expectedRuntimeCost: 11, + expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, + }, + { + name: "byte support with uppercase hexadecimal formatting clause", + format: "%X", + formatArgs: `b"byte string"`, + expectedOutput: "6279746520737472696E67", + expectedRuntimeCost: 11, + expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, + }, + { + name: "scientific notation formatting clause", + format: "%.6e", + formatArgs: "1052.032911275", + expectedOutput: "1.052033e+03", + expectedRuntimeCost: 11, + expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, + }, + { + name: "default precision for fixed-point clause", + format: "%f", + formatArgs: "2.71828", + expectedOutput: "2.718280", + expectedRuntimeCost: 11, + expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, + }, + { + name: "default precision for scientific notation", + format: "%e", + formatArgs: "2.71828", + expectedOutput: "2.718280e+00", + expectedRuntimeCost: 11, + expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, + }, + { + name: "default precision for string", + format: "%s", + formatArgs: "2.71", + expectedOutput: "2.71", + expectedRuntimeCost: 11, + expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, + }, + { + name: "default list precision for string", + format: "%s", + formatArgs: "[2.71]", + expectedOutput: "[2.71]", + expectedRuntimeCost: 21, + expectedEstimatedCost: checker.CostEstimate{Min: 21, Max: 21}, + }, + { + name: "default format for string", + format: "%s", + formatArgs: "0.000000002", + expectedOutput: "0.000000002", + expectedRuntimeCost: 11, + expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, + }, + { + name: "default list scientific notation for string", + format: "%s", + formatArgs: "[0.000000002]", + expectedOutput: "[0.000000002]", + expectedRuntimeCost: 21, + expectedEstimatedCost: checker.CostEstimate{Min: 21, Max: 21}, + }, + { + name: "NaN support for fixed-point", + format: "%f", + formatArgs: `double("NaN")`, + expectedOutput: "NaN", + expectedRuntimeCost: 12, + expectedEstimatedCost: checker.CostEstimate{Min: 12, Max: 12}, + }, + { + name: "positive infinity support for fixed-point", + format: "%f", + formatArgs: `double("Infinity")`, + expectedOutput: "Infinity", + expectedRuntimeCost: 12, + expectedEstimatedCost: checker.CostEstimate{Min: 12, Max: 12}, + }, + { + name: "negative infinity support for fixed-point", + format: "%f", + formatArgs: `double("-Infinity")`, + expectedOutput: "-Infinity", + expectedRuntimeCost: 12, + expectedEstimatedCost: checker.CostEstimate{Min: 12, Max: 12}, + }, + { + name: "NaN support for string", + format: "%s", + formatArgs: `double("NaN")`, + expectedOutput: "NaN", + }, + { + name: "positive infinity support for string", + format: "%s", + formatArgs: `double("Infinity")`, + expectedOutput: "Infinity", + }, + { + name: "negative infinity support for string", + format: "%s", + formatArgs: `double("-Infinity")`, + expectedOutput: "-Infinity", + }, + { + name: "infinity list support for string", + format: "%s", + formatArgs: `[double("NaN"),double("+Infinity"), double("-Infinity")]`, + expectedOutput: `[NaN, Infinity, -Infinity]`, + }, + { + name: "uint support for decimal clause", + format: "%d", + formatArgs: "uint(64)", + expectedOutput: "64", + expectedRuntimeCost: 12, + expectedEstimatedCost: checker.CostEstimate{Min: 12, Max: 12}, + }, + { + name: "null support for string", + format: "null: %s", + formatArgs: "null", + expectedOutput: "null: null", + expectedRuntimeCost: 11, + expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, + }, + { + name: "int support for string", + format: "%s", + formatArgs: `999999999999`, + expectedOutput: "999999999999", + expectedRuntimeCost: 11, + expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, + }, + { + name: "bytes support for string", + format: "some bytes: %s", + formatArgs: `b"xyz"`, + expectedOutput: "some bytes: xyz", + expectedRuntimeCost: 12, + expectedEstimatedCost: checker.CostEstimate{Min: 12, Max: 12}, + }, + { + name: "type() support for string", + format: "type is %s", + formatArgs: `type("test string")`, + expectedOutput: "type is string", + expectedRuntimeCost: 12, + expectedEstimatedCost: checker.CostEstimate{Min: 12, Max: 12}, + }, + { + name: "timestamp support for string", + format: "%s", + formatArgs: `timestamp("2023-02-03T23:31:20+00:00")`, + expectedOutput: "2023-02-03T23:31:20Z", + expectedRuntimeCost: 12, + expectedEstimatedCost: checker.CostEstimate{Min: 12, Max: 12}, + }, + { + name: "duration support for string", + format: "%s", + formatArgs: `duration("1h45m47s")`, + expectedOutput: "6347s", + expectedRuntimeCost: 12, + expectedEstimatedCost: checker.CostEstimate{Min: 12, Max: 12}, + }, + { + name: "small duration support for string", + format: "%s", + formatArgs: `duration("2ns")`, + expectedOutput: "0.000000002s", + expectedRuntimeCost: 12, + expectedEstimatedCost: checker.CostEstimate{Min: 12, Max: 12}, + }, + { + name: "list support for string", + format: "%s", + formatArgs: `["abc", 3.14, null, [9, 8, 7, 6], timestamp("2023-02-03T23:31:20Z")]`, + expectedOutput: `[abc, 3.14, null, [9, 8, 7, 6], 2023-02-03T23:31:20Z]`, + expectedRuntimeCost: 32, + expectedEstimatedCost: checker.CostEstimate{Min: 32, Max: 32}, + }, + { + name: "map support for string", + format: "%s", + formatArgs: `{"key1": b"xyz", "key5": null, "key2": duration("2h"), "key4": true, "key3": 2.71828}`, + expectedOutput: `{key1: xyz, key2: 7200s, key3: 2.71828, key4: true, key5: null}`, + expectedRuntimeCost: 42, + expectedEstimatedCost: checker.CostEstimate{Min: 42, Max: 42}, + }, + { + name: "map support (all key types)", + format: "map with multiple key types: %s", + formatArgs: `{1: "value1", uint(2): "value2", true: double("NaN")}`, + expectedOutput: `map with multiple key types: {1: value1, 2: value2, true: NaN}`, + expectedRuntimeCost: 46, + expectedEstimatedCost: checker.CostEstimate{Min: 46, Max: 46}, + }, + { + name: "boolean support for %s", + format: "true bool: %s, false bool: %s", + formatArgs: `true, false`, + expectedOutput: "true bool: true, false bool: false", + expectedRuntimeCost: 13, + expectedEstimatedCost: checker.CostEstimate{Min: 13, Max: 13}, + }, + { + name: "dyntype support for string formatting clause", + format: "dynamic string: %s", + formatArgs: `dynStr`, + dynArgs: map[string]any{ + "dynStr": "a string", + }, + expectedOutput: "dynamic string: a string", + expectedRuntimeCost: 13, + expectedEstimatedCost: checker.CostEstimate{Min: 13, Max: 13}, + }, + { + name: "dyntype support for numbers with string formatting clause", + format: "dynIntStr: %s dynDoubleStr: %s", + formatArgs: `dynIntStr, dynDoubleStr`, + dynArgs: map[string]any{ + "dynIntStr": 32, + "dynDoubleStr": 56.8, + }, + expectedOutput: "dynIntStr: 32 dynDoubleStr: 56.8", + expectedRuntimeCost: 15, + expectedEstimatedCost: checker.CostEstimate{Min: 15, Max: 15}, + }, + { + name: "dyntype support for integer formatting clause", + format: "dynamic int: %d", + formatArgs: `dynInt`, + dynArgs: map[string]any{ + "dynInt": 128, + }, + expectedOutput: "dynamic int: 128", + expectedRuntimeCost: 13, + expectedEstimatedCost: checker.CostEstimate{Min: 13, Max: 13}, + }, + { + name: "dyntype support for integer formatting clause (unsigned)", + format: "dynamic unsigned int: %d", + formatArgs: `dynUnsignedInt`, + dynArgs: map[string]any{ + "dynUnsignedInt": uint64(256), + }, + expectedOutput: "dynamic unsigned int: 256", + expectedRuntimeCost: 14, + expectedEstimatedCost: checker.CostEstimate{Min: 14, Max: 14}, + }, + { + name: "dyntype support for hex formatting clause", + format: "dynamic hex int: %x", + formatArgs: `dynHexInt`, + dynArgs: map[string]any{ + "dynHexInt": 22, + }, + expectedOutput: "dynamic hex int: 16", + expectedRuntimeCost: 13, + expectedEstimatedCost: checker.CostEstimate{Min: 13, Max: 13}, + }, + { + name: "dyntype support for hex formatting clause (uppercase)", + format: "dynamic hex int: %X (uppercase)", + formatArgs: `dynHexInt`, + dynArgs: map[string]any{ + "dynHexInt": 26, + }, + expectedOutput: "dynamic hex int: 1A (uppercase)", + expectedRuntimeCost: 15, + expectedEstimatedCost: checker.CostEstimate{Min: 15, Max: 15}, + }, + { + name: "dyntype support for unsigned hex formatting clause", + format: "dynamic hex int: %x (unsigned)", + formatArgs: `dynUnsignedHexInt`, + dynArgs: map[string]any{ + "dynUnsignedHexInt": uint(500), + }, + expectedOutput: "dynamic hex int: 1f4 (unsigned)", + expectedRuntimeCost: 14, + expectedEstimatedCost: checker.CostEstimate{Min: 14, Max: 14}, + }, + { + name: "dyntype support for fixed-point formatting clause", + format: "dynamic double: %.3f", + formatArgs: `dynDouble`, + dynArgs: map[string]any{ + "dynDouble": 4.5, + }, + expectedOutput: "dynamic double: 4.500", + expectedRuntimeCost: 13, + expectedEstimatedCost: checker.CostEstimate{Min: 13, Max: 13}, + }, + { + name: "dyntype support for scientific notation", + format: "(dyntype) e: %e", + formatArgs: "dynE", + dynArgs: map[string]any{ + "dynE": 2.71828, + }, + expectedOutput: "(dyntype) e: 2.718280e+00", + expectedRuntimeCost: 13, + expectedEstimatedCost: checker.CostEstimate{Min: 13, Max: 13}, + }, + { + name: "dyntype NaN/infinity support for fixed-point", + format: "NaN: %f, infinity: %f", + formatArgs: `dynNaN, dynInf`, + dynArgs: map[string]any{ + "dynNaN": math.NaN(), + "dynInf": math.Inf(1), + }, + expectedOutput: "NaN: NaN, infinity: Infinity", + expectedRuntimeCost: 15, + expectedEstimatedCost: checker.CostEstimate{Min: 15, Max: 15}, + }, + { + name: "dyntype support for timestamp", + format: "dyntype timestamp: %s", + formatArgs: `dynTime`, + dynArgs: map[string]any{ + "dynTime": time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC), + }, + expectedOutput: "dyntype timestamp: 2009-11-10T23:00:00Z", + expectedRuntimeCost: 14, + expectedEstimatedCost: checker.CostEstimate{Min: 14, Max: 14}, + }, + { + name: "dyntype support for duration", + format: "dyntype duration: %s", + formatArgs: `dynDuration`, + dynArgs: map[string]any{ + "dynDuration": mustParseDuration("2h25m47s"), + }, + expectedOutput: "dyntype duration: 8747s", + expectedRuntimeCost: 13, + expectedEstimatedCost: checker.CostEstimate{Min: 13, Max: 13}, + }, + { + name: "dyntype support for lists", + format: "dyntype list: %s", + formatArgs: `dynList`, + dynArgs: map[string]any{ + "dynList": []any{6, 4.2, "a string"}, + }, + expectedOutput: `dyntype list: [6, 4.2, a string]`, + expectedRuntimeCost: 13, + expectedEstimatedCost: checker.CostEstimate{Min: 13, Max: 13}, + }, + { + name: "dyntype support for maps", + format: "dyntype map: %s", + formatArgs: `dynMap`, + dynArgs: map[string]any{ + "dynMap": map[any]any{ + "strKey": "x", + true: 42, + int64(6): mustParseDuration("7m2s"), + }, + }, + expectedOutput: `dyntype map: {6: 422s, strKey: x, true: 42}`, + expectedRuntimeCost: 13, + expectedEstimatedCost: checker.CostEstimate{Min: 13, Max: 13}, + }, + { + name: "message field support", + format: "message field msg.single_int32: %d, msg.single_double: %.1f", + formatArgs: `msg.single_int32, msg.single_double`, + dynArgs: map[string]any{ + "msg": &proto3pb.TestAllTypes{ + SingleInt32: 2, + SingleDouble: 1.0, + }, + }, + expectedOutput: `message field msg.single_int32: 2, msg.single_double: 1.0`, + }, + { + name: "unrecognized formatting clause", + format: "%a", + formatArgs: "1", + skipCompileCheck: true, + err: "could not parse formatting clause: unrecognized formatting clause \"a\"", + }, + { + name: "out of bounds arg index", + format: "%d %d %d", + formatArgs: "0, 1", + skipCompileCheck: true, + err: "index 2 out of range", + }, + { + name: "string substitution is not allowed with binary clause", + format: "string is %b", + formatArgs: `"abc"`, + skipCompileCheck: true, + err: "error during formatting: only ints, uints, and bools can be formatted as binary, was given string", + }, + { + name: "duration substitution not allowed with decimal clause", + format: "%d", + formatArgs: `duration("30m2s")`, + skipCompileCheck: true, + err: "error during formatting: decimal clause can only be used on ints, uints, and doubles, was given google.protobuf.Duration", + }, + { + name: "string substitution not allowed with octal clause", + format: "octal: %o", + formatArgs: `"a string"`, + skipCompileCheck: true, + err: "error during formatting: octal clause can only be used on ints and uints, was given string", + }, + { + name: "double substitution not allowed with hex clause", + format: "double is %x", + formatArgs: "0.5", + skipCompileCheck: true, + err: "error during formatting: only ints, uints, bytes, and strings can be formatted as hex, was given double", + }, + { + name: "uppercase not allowed for scientific clause", + format: "double is %E", + formatArgs: "0.5", + skipCompileCheck: true, + err: `could not parse formatting clause: unrecognized formatting clause "E"`, + }, + { + name: "object not allowed", + format: "object is %s", + formatArgs: `ext.TestAllTypes{PbVal: test.TestAllTypes{}}`, + skipCompileCheck: true, + err: "error during formatting: string clause can only be used on strings, bools, bytes, ints, doubles, maps, lists, types, durations, and timestamps, was given ext.TestAllTypes", + }, + { + name: "object inside list", + format: "%s", + formatArgs: "[1, 2, ext.TestAllTypes{PbVal: test.TestAllTypes{}}]", + skipCompileCheck: true, + err: "error during formatting: string clause can only be used on strings, bools, bytes, ints, doubles, maps, lists, types, durations, and timestamps, was given ext.TestAllTypes", + }, + { + name: "object inside map", + format: "%s", + formatArgs: `{1: "a", 2: ext.TestAllTypes{}}`, + skipCompileCheck: true, + err: "error during formatting: string clause can only be used on strings, bools, bytes, ints, doubles, maps, lists, types, durations, and timestamps, was given ext.TestAllTypes", + }, + { + name: "null not allowed for %d", + format: "null: %d", + formatArgs: "null", + skipCompileCheck: true, + err: "error during formatting: decimal clause can only be used on ints, uints, and doubles, was given null_type", + }, + { + name: "null not allowed for %e", + format: "null: %e", + formatArgs: "null", + skipCompileCheck: true, + err: "error during formatting: scientific clause can only be used on ints, uints, and doubles, was given null_type", + }, + { + name: "null not allowed for %f", + format: "null: %f", + formatArgs: "null", + skipCompileCheck: true, + err: "error during formatting: fixed-point clause can only be used on ints, uints, and doubles, was given null_type", + }, + { + name: "null not allowed for %x", + format: "null: %x", + formatArgs: "null", + skipCompileCheck: true, + err: "error during formatting: only ints, uints, bytes, and strings can be formatted as hex, was given null_type", + }, + { + name: "null not allowed for %X", + format: "null: %X", + formatArgs: "null", + skipCompileCheck: true, + err: "error during formatting: only ints, uints, bytes, and strings can be formatted as hex, was given null_type", + }, + { + name: "null not allowed for %b", + format: "null: %b", + formatArgs: "null", + skipCompileCheck: true, + err: "error during formatting: only ints, uints, and bools can be formatted as binary, was given null_type", + }, + { + name: "null not allowed for %o", + format: "null: %o", + formatArgs: "null", + skipCompileCheck: true, + err: "error during formatting: octal clause can only be used on ints and uints, was given null_type", + }, + { + name: "compile-time cardinality check (too few for string)", + format: "%s %s", + formatArgs: `"abc"`, + err: "index 1 out of range", + }, + { + name: "compile-time cardinality check (too many for string)", + format: "%s %s", + formatArgs: `"abc", "def", "ghi"`, + err: "too many arguments supplied to string.format (expected 2, got 3)", + }, + { + name: "compile-time syntax check (unexpected end of string)", + format: "filler %", + formatArgs: "", + err: "unexpected end of string", + }, + { + name: "compile-time syntax check (unrecognized formatting clause)", + format: "%j", + // pass args here, otherwise the cardinality check will fail first + formatArgs: "123", + err: `could not parse formatting clause: unrecognized formatting clause "j"`, + }, + { + name: "compile-time %s check", + format: "object is %s", + formatArgs: `ext.TestAllTypes{PbVal: test.TestAllTypes{}}`, + err: "error during formatting: string clause can only be used on strings, bools, bytes, ints, doubles, maps, lists, types, durations, and timestamps", + }, + { + name: "compile-time check for objects inside list literal", + format: "list is %s", + formatArgs: `[1, 2, ext.TestAllTypes{PbVal: test.TestAllTypes{}}]`, + err: "error during formatting: string clause can only be used on strings, bools, bytes, ints, doubles, maps, lists, types, durations, and timestamps", + }, + { + name: "compile-time %d check", + format: "int is %d", + formatArgs: "null", + err: "error during formatting: decimal clause can only be used on ints, uints, and doubles, was given null_type", + }, + { + name: "compile-time %f check", + format: "double is %f", + formatArgs: "true", + err: "error during formatting: fixed-point clause can only be used on ints, uints, and doubles, was given bool", + }, + { + name: "compile-time precision syntax check", + format: "double is %.34", + formatArgs: "5.0", + err: "could not parse formatting clause: error while parsing precision: could not find end of precision specifier", + }, + { + name: "compile-time %e check", + format: "double is %e", + formatArgs: "true", + err: "error during formatting: scientific clause can only be used on ints, uints, and doubles, was given bool", + }, + { + name: "compile-time %b check", + format: "string is %b", + formatArgs: `"a string"`, + err: "error during formatting: only ints, uints, and bools can be formatted as binary, was given string", + }, + { + name: "compile-time %x check", + format: "%x is a double", + formatArgs: "2.5", + err: "error during formatting: only ints, uints, bytes, and strings can be formatted as hex, was given double", + }, + { + name: "compile-time %X check", + format: "%X is a double", + formatArgs: "2.5", + err: "error during formatting: only ints, uints, bytes, and strings can be formatted as hex, was given double", + }, + { + name: "compile-time %o check", + format: "an octal: %o", + formatArgs: "3.14", + err: "octal clause can only be used on ints and uints, was given double", + }, + } + evalExpr := func(env *cel.Env, expr string, evalArgs any, expectedRuntimeCost uint64, expectedEstimatedCost checker.CostEstimate, t *testing.T) (ref.Val, error) { + t.Logf("evaluating expr: %s", expr) + parsedAst, issues := env.Parse(expr) + if issues.Err() != nil { + t.Fatalf("env.Parse(%v) failed: %v", expr, issues.Err()) + } + checkedAst, issues := env.Check(parsedAst) + if issues.Err() != nil { + return nil, issues.Err() + } + evalOpts := make([]cel.ProgramOption, 0) + costTracker := &noopCostEstimator{} + if expectedRuntimeCost != 0 { + evalOpts = append(evalOpts, cel.CostTracking(costTracker)) + } + program, err := env.Program(checkedAst, evalOpts...) + if err != nil { + return nil, err + } + + actualEstimatedCost, err := env.EstimateCost(checkedAst, costTracker) + if err != nil { + t.Fatal(err) + } + if expectedEstimatedCost.Min != 0 && expectedEstimatedCost.Max != 0 { + if actualEstimatedCost.Min != expectedEstimatedCost.Min && actualEstimatedCost.Max != expectedEstimatedCost.Max { + t.Fatalf("expected estimated cost range to be %v, was %v", expectedEstimatedCost, actualEstimatedCost) + } + } + + var out ref.Val + var details *cel.EvalDetails + if evalArgs != nil { + out, details, err = program.Eval(evalArgs) + } else { + out, details, err = program.Eval(cel.NoVars()) + } + + if expectedRuntimeCost != 0 { + if details == nil { + t.Fatal("no EvalDetails available when runtime cost was expected") + } + if *details.ActualCost() != expectedRuntimeCost { + t.Fatalf("expected runtime cost to be %d, was %d", expectedRuntimeCost, *details.ActualCost()) + } + if expectedEstimatedCost.Min != 0 && expectedEstimatedCost.Max != 0 { + if *details.ActualCost() < expectedEstimatedCost.Min || *details.ActualCost() > expectedEstimatedCost.Max { + t.Fatalf("runtime cost %d outside of expected estimated cost range %v", *details.ActualCost(), expectedEstimatedCost) + } + } + } + return out, err + } + buildVariables := func(vars map[string]any) []cel.EnvOption { + opts := make([]cel.EnvOption, len(vars)) + i := 0 + for name, value := range vars { + t := cel.DynType + switch v := value.(type) { + case proto.Message: + t = cel.ObjectType(string(v.ProtoReflect().Descriptor().FullName())) + case types.Bool: + t = cel.BoolType + case types.Bytes: + t = cel.BytesType + case types.Double: + t = cel.DoubleType + case types.Duration: + t = cel.DurationType + case types.Int: + t = cel.IntType + case types.Null: + t = cel.NullType + case types.String: + t = cel.StringType + case types.Timestamp: + t = cel.TimestampType + case types.Uint: + t = cel.UintType + } + opts[i] = cel.Variable(name, t) + i++ + } + return opts + } + buildOpts := func(skipCompileCheck bool, variables []cel.EnvOption) []cel.EnvOption { + opts := []cel.EnvOption{ + Strings(StringsValidateFormatCalls(!skipCompileCheck)), + cel.Container("ext"), + cel.Abbrevs("google.expr.proto3.test"), + cel.Types(&proto3pb.TestAllTypes{}), + NativeTypes( + reflect.TypeOf(&TestNestedType{}), + reflect.ValueOf(&TestAllTypes{}), + ), + } + opts = append(opts, cel.ASTValidators(cel.ValidateHomogeneousAggregateLiterals())) + opts = append(opts, variables...) + return opts + } + runCase := func(format, formatArgs string, dynArgs map[string]any, skipCompileCheck bool, expectedRuntimeCost uint64, expectedEstimatedCost checker.CostEstimate, t *testing.T) (ref.Val, error) { + env, err := cel.NewEnv(buildOpts(skipCompileCheck, buildVariables(dynArgs))...) + if err != nil { + t.Fatalf("cel.NewEnv() failed: %v", err) + } + expr := fmt.Sprintf("%q.format([%s])", format, formatArgs) + if len(dynArgs) == 0 { + return evalExpr(env, expr, cel.NoVars(), expectedRuntimeCost, expectedEstimatedCost, t) + } + return evalExpr(env, expr, dynArgs, expectedRuntimeCost, expectedEstimatedCost, t) + } + checkCase := func(output ref.Val, expectedOutput string, err error, expectedErr string, t *testing.T) { + if err != nil { + if expectedErr != "" { + if !strings.Contains(err.Error(), expectedErr) { + t.Fatalf("expected %q as error message, got %q", expectedErr, err.Error()) + } + } else { + t.Fatalf("unexpected error: %s", err) + } + } else { + if output.Type() != types.StringType { + t.Fatalf("expected test expr to eval to string (got %s instead)", output.Type().TypeName()) + } else { + outputStr := output.Value().(string) + if outputStr != expectedOutput { + t.Errorf("expected %q as output, got %q", expectedOutput, outputStr) + } + } + } + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + out, err := runCase(tt.format, tt.formatArgs, tt.dynArgs, tt.skipCompileCheck, tt.expectedRuntimeCost, tt.expectedEstimatedCost, t) + checkCase(out, tt.expectedOutput, err, tt.err, t) + }) + } +} + +func TestStringFormatHeterogeneousLiteralsV2(t *testing.T) { + tests := []struct { + expr string + out string + }{ + { + expr: `"list: %s".format([[[1, 2, [3.0, 4]]]])`, + out: `list: [[1, 2, [3, 4]]]`, + }, + { + expr: `"list size: %d".format([[[1, 2, [3.0, 4]]].size()])`, + out: `list size: 1`, + }, + { + expr: `"list element: %s".format([[[1, 2, [3.0, 4]]][0]])`, + out: `list element: [1, 2, [3, 4]]`, + }, + } + env, err := cel.NewEnv(Strings(), cel.ASTValidators(cel.ValidateHomogeneousAggregateLiterals())) + if err != nil { + t.Fatalf("cel.NewEnv() failed: %v", err) + } + for _, tst := range tests { + tc := tst + t.Run(tc.expr, func(t *testing.T) { + ast, iss := env.Compile(tc.expr) + if iss.Err() != nil { + t.Fatalf("env.Compile(%q) failed: %v", tc.expr, iss.Err()) + } + prg, err := env.Program(ast) + if err != nil { + t.Fatalf("env.Program() failed: %v", err) + } + out, _, err := prg.Eval(cel.NoVars()) + if err != nil { + t.Fatalf("Eval() failed: %v", err) + } + if out.Value() != tc.out { + t.Errorf("Eval() got %v, wanted %v", out, tc.out) + } + }) + } +} diff --git a/ext/strings.go b/ext/strings.go index 28b7a2599..88b4d7f03 100644 --- a/ext/strings.go +++ b/ext/strings.go @@ -25,6 +25,8 @@ import ( "unicode" "unicode/utf8" + "golang.org/x/text/language" + "github.com/google/cel-go/cel" "github.com/google/cel-go/common/types" "github.com/google/cel-go/common/types/ref" @@ -284,10 +286,15 @@ const ( // // 'gums'.reverse() // returns 'smug' // 'John Smith'.reverse() // returns 'htimS nhoJ' +// +// Introduced at version: 4 +// +// Formatting updated to adhere to https://github.com/google/cel-spec/blob/master/doc/extensions/strings.md. +// +// .format() -> func Strings(options ...StringsOption) cel.EnvOption { s := &stringLib{ - version: math.MaxUint32, - validateFormat: true, + version: math.MaxUint32, } for _, o := range options { s = o(s) @@ -296,8 +303,8 @@ func Strings(options ...StringsOption) cel.EnvOption { } type stringLib struct { - version uint32 - validateFormat bool + locale string + version uint32 } // LibraryName implements the SingletonLibrary interface method. @@ -308,6 +315,18 @@ func (*stringLib) LibraryName() string { // StringsOption is a functional interface for configuring the strings library. type StringsOption func(*stringLib) *stringLib +// StringsLocale configures the library with the given locale. The locale tag will +// be checked for validity at the time that EnvOptions are configured. If this option +// is not passed, string.format will behave as if en_US was passed as the locale. +// +// If StringsVersion is greater than or equal to 4, this option is ignored. +func StringsLocale(locale string) StringsOption { + return func(sl *stringLib) *stringLib { + sl.locale = locale + return sl + } +} + // StringsVersion configures the version of the string library. // // The version limits which functions are available. Only functions introduced @@ -327,16 +346,29 @@ func StringsVersion(version uint32) StringsOption { // StringsValidateFormatCalls validates type-checked ASTs to ensure that string.format() calls have // valid formatting clauses and valid argument types for each clause. // -// Enabled by default. +// Deprecated func StringsValidateFormatCalls(value bool) StringsOption { return func(s *stringLib) *stringLib { - s.validateFormat = value return s } } // CompileOptions implements the Library interface method. func (lib *stringLib) CompileOptions() []cel.EnvOption { + formatLocale := "en_US" + if lib.version < 4 && lib.locale != "" { + // ensure locale is properly-formed if set + _, err := language.Parse(lib.locale) + if err != nil { + return []cel.EnvOption{ + func(e *cel.Env) (*cel.Env, error) { + return nil, fmt.Errorf("failed to parse locale: %w", err) + }, + } + } + formatLocale = lib.locale + } + opts := []cel.EnvOption{ cel.Function("charAt", cel.MemberOverload("string_char_at_int", []*cel.Type{cel.StringType, cel.IntType}, cel.StringType, @@ -439,21 +471,29 @@ func (lib *stringLib) CompileOptions() []cel.EnvOption { }))), } if lib.version >= 1 { - opts = append(opts, cel.Function("format", - cel.MemberOverload("string_format", []*cel.Type{cel.StringType, cel.ListType(cel.DynType)}, cel.StringType, - cel.FunctionBinding(func(args ...ref.Val) ref.Val { - s := string(args[0].(types.String)) - formatArgs := args[1].(traits.Lister) - return stringOrError(parseFormatString(s, &stringFormatter{}, &stringArgList{formatArgs})) - }))), + if lib.version >= 4 { + opts = append(opts, cel.Function("format", + cel.MemberOverload("string_format", []*cel.Type{cel.StringType, cel.ListType(cel.DynType)}, cel.StringType, + cel.FunctionBinding(func(args ...ref.Val) ref.Val { + s := string(args[0].(types.String)) + formatArgs := args[1].(traits.Lister) + return stringOrError(parseFormatStringV2(s, &stringFormatterV2{}, &stringArgList{formatArgs})) + })))) + } else { + opts = append(opts, cel.Function("format", + cel.MemberOverload("string_format", []*cel.Type{cel.StringType, cel.ListType(cel.DynType)}, cel.StringType, + cel.FunctionBinding(func(args ...ref.Val) ref.Val { + s := string(args[0].(types.String)) + formatArgs := args[1].(traits.Lister) + return stringOrError(parseFormatString(s, &stringFormatter{}, &stringArgList{formatArgs}, formatLocale)) + })))) + } + opts = append(opts, cel.Function("strings.quote", cel.Overload("strings_quote", []*cel.Type{cel.StringType}, cel.StringType, cel.UnaryBinding(func(str ref.Val) ref.Val { s := str.(types.String) return stringOrError(quote(string(s))) - }))), - - cel.ASTValidators(stringFormatValidator{})) - + })))) } if lib.version >= 2 { opts = append(opts, @@ -502,8 +542,12 @@ func (lib *stringLib) CompileOptions() []cel.EnvOption { }))), ) } - if lib.validateFormat { - opts = append(opts, cel.ASTValidators(stringFormatValidator{})) + if lib.version >= 1 { + if lib.version >= 4 { + opts = append(opts, cel.ASTValidators(stringFormatValidatorV2{})) + } else { + opts = append(opts, cel.ASTValidators(stringFormatValidator{})) + } } return opts } diff --git a/ext/strings_test.go b/ext/strings_test.go index 0d1017027..3a8adeb09 100644 --- a/ext/strings_test.go +++ b/ext/strings_test.go @@ -16,21 +16,15 @@ package ext import ( "fmt" - "math" - "reflect" "strings" "testing" "time" "unicode/utf8" - "google.golang.org/protobuf/proto" - "github.com/google/cel-go/cel" "github.com/google/cel-go/checker" "github.com/google/cel-go/common/types" "github.com/google/cel-go/common/types/ref" - - proto3pb "github.com/google/cel-go/test/proto3pb" ) // TODO: move these tests to a conformance test. @@ -444,977 +438,6 @@ func TestStringsWithExtension(t *testing.T) { } } -func TestStringFormat(t *testing.T) { - tests := []struct { - name string - format string - dynArgs map[string]any - formatArgs string - err string - expectedOutput string - expectedRuntimeCost uint64 - expectedEstimatedCost checker.CostEstimate - skipCompileCheck bool - }{ - { - name: "no-op", - format: "no substitution", - expectedOutput: "no substitution", - expectedRuntimeCost: 12, - expectedEstimatedCost: checker.CostEstimate{Min: 12, Max: 12}, - }, - - { - name: "mid-string substitution", - format: "str is %s and some more", - formatArgs: `"filler"`, - expectedOutput: "str is filler and some more", - expectedRuntimeCost: 13, - expectedEstimatedCost: checker.CostEstimate{Min: 13, Max: 13}, - }, - { - name: "percent escaping", - format: "%% and also %%", - expectedOutput: "% and also %", - expectedRuntimeCost: 12, - expectedEstimatedCost: checker.CostEstimate{Min: 12, Max: 12}, - }, - { - name: "substution inside escaped percent signs", - format: "%%%s%%", - formatArgs: `"text"`, - expectedOutput: "%text%", - expectedRuntimeCost: 11, - expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, - }, - { - name: "substitution with one escaped percent sign on the right", - format: "%s%%", - formatArgs: `"percent on the right"`, - expectedOutput: "percent on the right%", - expectedRuntimeCost: 11, - expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, - }, - { - name: "substitution with one escaped percent sign on the left", - format: "%%%s", - formatArgs: `"percent on the left"`, - expectedOutput: "%percent on the left", - expectedRuntimeCost: 11, - expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, - }, - { - name: "multiple substitutions", - format: "%d %d %d, %s %s %s, %d %d %d, %s %s %s", - formatArgs: `1, 2, 3, "A", "B", "C", 4, 5, 6, "D", "E", "F"`, - expectedOutput: "1 2 3, A B C, 4 5 6, D E F", - expectedRuntimeCost: 14, - expectedEstimatedCost: checker.CostEstimate{Min: 14, Max: 14}, - }, - { - name: "percent sign escape sequence support", - format: "\u0025\u0025escaped \u0025s\u0025\u0025", - formatArgs: `"percent"`, - expectedOutput: "%escaped percent%", - expectedRuntimeCost: 12, - expectedEstimatedCost: checker.CostEstimate{Min: 12, Max: 12}, - }, - { - name: "fixed point formatting clause", - format: "%.3f", - formatArgs: "1.2345", - expectedOutput: "1.234", - expectedRuntimeCost: 11, - expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, - }, - { - name: "binary formatting clause", - format: "this is 5 in binary: %b", - formatArgs: "5", - expectedOutput: "this is 5 in binary: 101", - expectedRuntimeCost: 13, - expectedEstimatedCost: checker.CostEstimate{Min: 13, Max: 13}, - }, - { - name: "negative binary formatting clause", - format: "this is -5 in binary: %b", - formatArgs: "-5", - expectedOutput: "this is -5 in binary: -101", - expectedRuntimeCost: 13, - expectedEstimatedCost: checker.CostEstimate{Min: 13, Max: 13}, - }, - { - name: "uint support for binary formatting", - format: "unsigned 64 in binary: %b", - formatArgs: "uint(64)", - expectedOutput: "unsigned 64 in binary: 1000000", - expectedRuntimeCost: 14, - expectedEstimatedCost: checker.CostEstimate{Min: 14, Max: 14}, - }, - { - name: "bool support for binary formatting", - format: "bit set from bool: %b", - formatArgs: "true", - expectedOutput: "bit set from bool: 1", - expectedRuntimeCost: 13, - expectedEstimatedCost: checker.CostEstimate{Min: 13, Max: 13}, - }, - { - name: "octal formatting clause", - format: "%o", - formatArgs: "11", - expectedOutput: "13", - expectedRuntimeCost: 11, - expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, - }, - { - name: "negative octal formatting clause", - format: "%o", - formatArgs: "-11", - expectedOutput: "-13", - expectedRuntimeCost: 11, - expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, - }, - { - name: "uint support for octal formatting clause", - format: "this is an unsigned octal: %o", - formatArgs: "uint(65535)", - expectedOutput: "this is an unsigned octal: 177777", - expectedRuntimeCost: 14, - expectedEstimatedCost: checker.CostEstimate{Min: 14, Max: 14}, - }, - { - name: "lowercase hexadecimal formatting clause", - format: "%x is 30 in hexadecimal", - formatArgs: "30", - expectedOutput: "1e is 30 in hexadecimal", - expectedRuntimeCost: 13, - expectedEstimatedCost: checker.CostEstimate{Min: 13, Max: 13}, - }, - { - name: "uppercase hexadecimal formatting clause", - format: "%X is 20 in hexadecimal", - formatArgs: "30", - expectedOutput: "1E is 20 in hexadecimal", - expectedRuntimeCost: 13, - expectedEstimatedCost: checker.CostEstimate{Min: 13, Max: 13}, - }, - { - name: "negative hexadecimal formatting clause", - format: "%x is -30 in hexadecimal", - formatArgs: "-30", - expectedOutput: "-1e is -30 in hexadecimal", - expectedRuntimeCost: 13, - expectedEstimatedCost: checker.CostEstimate{Min: 13, Max: 13}, - }, - { - name: "unsigned support for hexadecimal formatting clause", - format: "%X is 6000 in hexadecimal", - formatArgs: "uint(6000)", - expectedOutput: "1770 is 6000 in hexadecimal", - expectedRuntimeCost: 14, - expectedEstimatedCost: checker.CostEstimate{Min: 14, Max: 14}, - }, - { - name: "string support with hexadecimal formatting clause", - format: "%x", - formatArgs: `"Hello world!"`, - expectedOutput: "48656c6c6f20776f726c6421", - expectedRuntimeCost: 11, - expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, - }, - { - name: "string support with uppercase hexadecimal formatting clause", - format: "%X", - formatArgs: `"Hello world!"`, - expectedOutput: "48656C6C6F20776F726C6421", - expectedRuntimeCost: 11, - expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, - }, - { - name: "byte support with hexadecimal formatting clause", - format: "%x", - formatArgs: `b"byte string"`, - expectedOutput: "6279746520737472696e67", - expectedRuntimeCost: 11, - expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, - }, - { - name: "byte support with hexadecimal formatting clause leading zero", - format: "%x", - formatArgs: `b"\x00\x00byte string\x00"`, - expectedOutput: "00006279746520737472696e6700", - expectedRuntimeCost: 11, - expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, - }, - { - name: "byte support with uppercase hexadecimal formatting clause", - format: "%X", - formatArgs: `b"byte string"`, - expectedOutput: "6279746520737472696E67", - expectedRuntimeCost: 11, - expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, - }, - { - name: "scientific notation formatting clause", - format: "%.6e", - formatArgs: "1052.032911275", - expectedOutput: "1.052033e+03", - expectedRuntimeCost: 11, - expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, - }, - { - name: "default precision for fixed-point clause", - format: "%f", - formatArgs: "2.71828", - expectedOutput: "2.718280", - expectedRuntimeCost: 11, - expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, - }, - { - name: "default precision for scientific notation", - format: "%e", - formatArgs: "2.71828", - expectedOutput: "2.718280e+00", - expectedRuntimeCost: 11, - expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, - }, - { - name: "default precision for string", - format: "%s", - formatArgs: "2.71", - expectedOutput: "2.71", - expectedRuntimeCost: 11, - expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, - }, - { - name: "default list precision for string", - format: "%s", - formatArgs: "[2.71]", - expectedOutput: "[2.71]", - expectedRuntimeCost: 21, - expectedEstimatedCost: checker.CostEstimate{Min: 21, Max: 21}, - }, - { - name: "default format for string", - format: "%s", - formatArgs: "0.000000002", - expectedOutput: "0.000000002", - expectedRuntimeCost: 11, - expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, - }, - { - name: "default list scientific notation for string", - format: "%s", - formatArgs: "[0.000000002]", - expectedOutput: "[0.000000002]", - expectedRuntimeCost: 21, - expectedEstimatedCost: checker.CostEstimate{Min: 21, Max: 21}, - }, - { - name: "NaN support for fixed-point", - format: "%f", - formatArgs: `double("NaN")`, - expectedOutput: "NaN", - expectedRuntimeCost: 12, - expectedEstimatedCost: checker.CostEstimate{Min: 12, Max: 12}, - }, - { - name: "positive infinity support for fixed-point", - format: "%f", - formatArgs: `double("Infinity")`, - expectedOutput: "Infinity", - expectedRuntimeCost: 12, - expectedEstimatedCost: checker.CostEstimate{Min: 12, Max: 12}, - }, - { - name: "negative infinity support for fixed-point", - format: "%f", - formatArgs: `double("-Infinity")`, - expectedOutput: "-Infinity", - expectedRuntimeCost: 12, - expectedEstimatedCost: checker.CostEstimate{Min: 12, Max: 12}, - }, - { - name: "NaN support for string", - format: "%s", - formatArgs: `double("NaN")`, - expectedOutput: "NaN", - }, - { - name: "positive infinity support for string", - format: "%s", - formatArgs: `double("Infinity")`, - expectedOutput: "Infinity", - }, - { - name: "negative infinity support for string", - format: "%s", - formatArgs: `double("-Infinity")`, - expectedOutput: "-Infinity", - }, - { - name: "infinity list support for string", - format: "%s", - formatArgs: `[double("NaN"),double("+Infinity"), double("-Infinity")]`, - expectedOutput: `[NaN, Infinity, -Infinity]`, - }, - { - name: "uint support for decimal clause", - format: "%d", - formatArgs: "uint(64)", - expectedOutput: "64", - expectedRuntimeCost: 12, - expectedEstimatedCost: checker.CostEstimate{Min: 12, Max: 12}, - }, - { - name: "null support for string", - format: "null: %s", - formatArgs: "null", - expectedOutput: "null: null", - expectedRuntimeCost: 11, - expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, - }, - { - name: "int support for string", - format: "%s", - formatArgs: `999999999999`, - expectedOutput: "999999999999", - expectedRuntimeCost: 11, - expectedEstimatedCost: checker.CostEstimate{Min: 11, Max: 11}, - }, - { - name: "bytes support for string", - format: "some bytes: %s", - formatArgs: `b"xyz"`, - expectedOutput: "some bytes: xyz", - expectedRuntimeCost: 12, - expectedEstimatedCost: checker.CostEstimate{Min: 12, Max: 12}, - }, - { - name: "type() support for string", - format: "type is %s", - formatArgs: `type("test string")`, - expectedOutput: "type is string", - expectedRuntimeCost: 12, - expectedEstimatedCost: checker.CostEstimate{Min: 12, Max: 12}, - }, - { - name: "timestamp support for string", - format: "%s", - formatArgs: `timestamp("2023-02-03T23:31:20+00:00")`, - expectedOutput: "2023-02-03T23:31:20Z", - expectedRuntimeCost: 12, - expectedEstimatedCost: checker.CostEstimate{Min: 12, Max: 12}, - }, - { - name: "duration support for string", - format: "%s", - formatArgs: `duration("1h45m47s")`, - expectedOutput: "6347s", - expectedRuntimeCost: 12, - expectedEstimatedCost: checker.CostEstimate{Min: 12, Max: 12}, - }, - { - name: "small duration support for string", - format: "%s", - formatArgs: `duration("2ns")`, - expectedOutput: "0.000000002s", - expectedRuntimeCost: 12, - expectedEstimatedCost: checker.CostEstimate{Min: 12, Max: 12}, - }, - { - name: "list support for string", - format: "%s", - formatArgs: `["abc", 3.14, null, [9, 8, 7, 6], timestamp("2023-02-03T23:31:20Z")]`, - expectedOutput: `[abc, 3.14, null, [9, 8, 7, 6], 2023-02-03T23:31:20Z]`, - expectedRuntimeCost: 32, - expectedEstimatedCost: checker.CostEstimate{Min: 32, Max: 32}, - }, - { - name: "map support for string", - format: "%s", - formatArgs: `{"key1": b"xyz", "key5": null, "key2": duration("2h"), "key4": true, "key3": 2.71828}`, - expectedOutput: `{key1: xyz, key2: 7200s, key3: 2.71828, key4: true, key5: null}`, - expectedRuntimeCost: 42, - expectedEstimatedCost: checker.CostEstimate{Min: 42, Max: 42}, - }, - { - name: "map support (all key types)", - format: "map with multiple key types: %s", - formatArgs: `{1: "value1", uint(2): "value2", true: double("NaN")}`, - expectedOutput: `map with multiple key types: {1: value1, 2: value2, true: NaN}`, - expectedRuntimeCost: 46, - expectedEstimatedCost: checker.CostEstimate{Min: 46, Max: 46}, - }, - { - name: "boolean support for %s", - format: "true bool: %s, false bool: %s", - formatArgs: `true, false`, - expectedOutput: "true bool: true, false bool: false", - expectedRuntimeCost: 13, - expectedEstimatedCost: checker.CostEstimate{Min: 13, Max: 13}, - }, - { - name: "dyntype support for string formatting clause", - format: "dynamic string: %s", - formatArgs: `dynStr`, - dynArgs: map[string]any{ - "dynStr": "a string", - }, - expectedOutput: "dynamic string: a string", - expectedRuntimeCost: 13, - expectedEstimatedCost: checker.CostEstimate{Min: 13, Max: 13}, - }, - { - name: "dyntype support for numbers with string formatting clause", - format: "dynIntStr: %s dynDoubleStr: %s", - formatArgs: `dynIntStr, dynDoubleStr`, - dynArgs: map[string]any{ - "dynIntStr": 32, - "dynDoubleStr": 56.8, - }, - expectedOutput: "dynIntStr: 32 dynDoubleStr: 56.8", - expectedRuntimeCost: 15, - expectedEstimatedCost: checker.CostEstimate{Min: 15, Max: 15}, - }, - { - name: "dyntype support for integer formatting clause", - format: "dynamic int: %d", - formatArgs: `dynInt`, - dynArgs: map[string]any{ - "dynInt": 128, - }, - expectedOutput: "dynamic int: 128", - expectedRuntimeCost: 13, - expectedEstimatedCost: checker.CostEstimate{Min: 13, Max: 13}, - }, - { - name: "dyntype support for integer formatting clause (unsigned)", - format: "dynamic unsigned int: %d", - formatArgs: `dynUnsignedInt`, - dynArgs: map[string]any{ - "dynUnsignedInt": uint64(256), - }, - expectedOutput: "dynamic unsigned int: 256", - expectedRuntimeCost: 14, - expectedEstimatedCost: checker.CostEstimate{Min: 14, Max: 14}, - }, - { - name: "dyntype support for hex formatting clause", - format: "dynamic hex int: %x", - formatArgs: `dynHexInt`, - dynArgs: map[string]any{ - "dynHexInt": 22, - }, - expectedOutput: "dynamic hex int: 16", - expectedRuntimeCost: 13, - expectedEstimatedCost: checker.CostEstimate{Min: 13, Max: 13}, - }, - { - name: "dyntype support for hex formatting clause (uppercase)", - format: "dynamic hex int: %X (uppercase)", - formatArgs: `dynHexInt`, - dynArgs: map[string]any{ - "dynHexInt": 26, - }, - expectedOutput: "dynamic hex int: 1A (uppercase)", - expectedRuntimeCost: 15, - expectedEstimatedCost: checker.CostEstimate{Min: 15, Max: 15}, - }, - { - name: "dyntype support for unsigned hex formatting clause", - format: "dynamic hex int: %x (unsigned)", - formatArgs: `dynUnsignedHexInt`, - dynArgs: map[string]any{ - "dynUnsignedHexInt": uint(500), - }, - expectedOutput: "dynamic hex int: 1f4 (unsigned)", - expectedRuntimeCost: 14, - expectedEstimatedCost: checker.CostEstimate{Min: 14, Max: 14}, - }, - { - name: "dyntype support for fixed-point formatting clause", - format: "dynamic double: %.3f", - formatArgs: `dynDouble`, - dynArgs: map[string]any{ - "dynDouble": 4.5, - }, - expectedOutput: "dynamic double: 4.500", - expectedRuntimeCost: 13, - expectedEstimatedCost: checker.CostEstimate{Min: 13, Max: 13}, - }, - { - name: "dyntype support for scientific notation", - format: "(dyntype) e: %e", - formatArgs: "dynE", - dynArgs: map[string]any{ - "dynE": 2.71828, - }, - expectedOutput: "(dyntype) e: 2.718280e+00", - expectedRuntimeCost: 13, - expectedEstimatedCost: checker.CostEstimate{Min: 13, Max: 13}, - }, - { - name: "dyntype NaN/infinity support for fixed-point", - format: "NaN: %f, infinity: %f", - formatArgs: `dynNaN, dynInf`, - dynArgs: map[string]any{ - "dynNaN": math.NaN(), - "dynInf": math.Inf(1), - }, - expectedOutput: "NaN: NaN, infinity: Infinity", - expectedRuntimeCost: 15, - expectedEstimatedCost: checker.CostEstimate{Min: 15, Max: 15}, - }, - { - name: "dyntype support for timestamp", - format: "dyntype timestamp: %s", - formatArgs: `dynTime`, - dynArgs: map[string]any{ - "dynTime": time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC), - }, - expectedOutput: "dyntype timestamp: 2009-11-10T23:00:00Z", - expectedRuntimeCost: 14, - expectedEstimatedCost: checker.CostEstimate{Min: 14, Max: 14}, - }, - { - name: "dyntype support for duration", - format: "dyntype duration: %s", - formatArgs: `dynDuration`, - dynArgs: map[string]any{ - "dynDuration": mustParseDuration("2h25m47s"), - }, - expectedOutput: "dyntype duration: 8747s", - expectedRuntimeCost: 13, - expectedEstimatedCost: checker.CostEstimate{Min: 13, Max: 13}, - }, - { - name: "dyntype support for lists", - format: "dyntype list: %s", - formatArgs: `dynList`, - dynArgs: map[string]any{ - "dynList": []any{6, 4.2, "a string"}, - }, - expectedOutput: `dyntype list: [6, 4.2, a string]`, - expectedRuntimeCost: 13, - expectedEstimatedCost: checker.CostEstimate{Min: 13, Max: 13}, - }, - { - name: "dyntype support for maps", - format: "dyntype map: %s", - formatArgs: `dynMap`, - dynArgs: map[string]any{ - "dynMap": map[any]any{ - "strKey": "x", - true: 42, - int64(6): mustParseDuration("7m2s"), - }, - }, - expectedOutput: `dyntype map: {6: 422s, strKey: x, true: 42}`, - expectedRuntimeCost: 13, - expectedEstimatedCost: checker.CostEstimate{Min: 13, Max: 13}, - }, - { - name: "message field support", - format: "message field msg.single_int32: %d, msg.single_double: %.1f", - formatArgs: `msg.single_int32, msg.single_double`, - dynArgs: map[string]any{ - "msg": &proto3pb.TestAllTypes{ - SingleInt32: 2, - SingleDouble: 1.0, - }, - }, - expectedOutput: `message field msg.single_int32: 2, msg.single_double: 1.0`, - }, - { - name: "unrecognized formatting clause", - format: "%a", - formatArgs: "1", - skipCompileCheck: true, - err: "could not parse formatting clause: unrecognized formatting clause \"a\"", - }, - { - name: "out of bounds arg index", - format: "%d %d %d", - formatArgs: "0, 1", - skipCompileCheck: true, - err: "index 2 out of range", - }, - { - name: "string substitution is not allowed with binary clause", - format: "string is %b", - formatArgs: `"abc"`, - skipCompileCheck: true, - err: "error during formatting: only ints, uints, and bools can be formatted as binary, was given string", - }, - { - name: "duration substitution not allowed with decimal clause", - format: "%d", - formatArgs: `duration("30m2s")`, - skipCompileCheck: true, - err: "error during formatting: decimal clause can only be used on ints, uints, and doubles, was given google.protobuf.Duration", - }, - { - name: "string substitution not allowed with octal clause", - format: "octal: %o", - formatArgs: `"a string"`, - skipCompileCheck: true, - err: "error during formatting: octal clause can only be used on ints and uints, was given string", - }, - { - name: "double substitution not allowed with hex clause", - format: "double is %x", - formatArgs: "0.5", - skipCompileCheck: true, - err: "error during formatting: only ints, uints, bytes, and strings can be formatted as hex, was given double", - }, - { - name: "uppercase not allowed for scientific clause", - format: "double is %E", - formatArgs: "0.5", - skipCompileCheck: true, - err: `could not parse formatting clause: unrecognized formatting clause "E"`, - }, - { - name: "object not allowed", - format: "object is %s", - formatArgs: `ext.TestAllTypes{PbVal: test.TestAllTypes{}}`, - skipCompileCheck: true, - err: "error during formatting: string clause can only be used on strings, bools, bytes, ints, doubles, maps, lists, types, durations, and timestamps, was given ext.TestAllTypes", - }, - { - name: "object inside list", - format: "%s", - formatArgs: "[1, 2, ext.TestAllTypes{PbVal: test.TestAllTypes{}}]", - skipCompileCheck: true, - err: "error during formatting: string clause can only be used on strings, bools, bytes, ints, doubles, maps, lists, types, durations, and timestamps, was given ext.TestAllTypes", - }, - { - name: "object inside map", - format: "%s", - formatArgs: `{1: "a", 2: ext.TestAllTypes{}}`, - skipCompileCheck: true, - err: "error during formatting: string clause can only be used on strings, bools, bytes, ints, doubles, maps, lists, types, durations, and timestamps, was given ext.TestAllTypes", - }, - { - name: "null not allowed for %d", - format: "null: %d", - formatArgs: "null", - skipCompileCheck: true, - err: "error during formatting: decimal clause can only be used on ints, uints, and doubles, was given null_type", - }, - { - name: "null not allowed for %e", - format: "null: %e", - formatArgs: "null", - skipCompileCheck: true, - err: "error during formatting: scientific clause can only be used on ints, uints, and doubles, was given null_type", - }, - { - name: "null not allowed for %f", - format: "null: %f", - formatArgs: "null", - skipCompileCheck: true, - err: "error during formatting: fixed-point clause can only be used on ints, uints, and doubles, was given null_type", - }, - { - name: "null not allowed for %x", - format: "null: %x", - formatArgs: "null", - skipCompileCheck: true, - err: "error during formatting: only ints, uints, bytes, and strings can be formatted as hex, was given null_type", - }, - { - name: "null not allowed for %X", - format: "null: %X", - formatArgs: "null", - skipCompileCheck: true, - err: "error during formatting: only ints, uints, bytes, and strings can be formatted as hex, was given null_type", - }, - { - name: "null not allowed for %b", - format: "null: %b", - formatArgs: "null", - skipCompileCheck: true, - err: "error during formatting: only ints, uints, and bools can be formatted as binary, was given null_type", - }, - { - name: "null not allowed for %o", - format: "null: %o", - formatArgs: "null", - skipCompileCheck: true, - err: "error during formatting: octal clause can only be used on ints and uints, was given null_type", - }, - { - name: "compile-time cardinality check (too few for string)", - format: "%s %s", - formatArgs: `"abc"`, - err: "index 1 out of range", - }, - { - name: "compile-time cardinality check (too many for string)", - format: "%s %s", - formatArgs: `"abc", "def", "ghi"`, - err: "too many arguments supplied to string.format (expected 2, got 3)", - }, - { - name: "compile-time syntax check (unexpected end of string)", - format: "filler %", - formatArgs: "", - err: "unexpected end of string", - }, - { - name: "compile-time syntax check (unrecognized formatting clause)", - format: "%j", - // pass args here, otherwise the cardinality check will fail first - formatArgs: "123", - err: `could not parse formatting clause: unrecognized formatting clause "j"`, - }, - { - name: "compile-time %s check", - format: "object is %s", - formatArgs: `ext.TestAllTypes{PbVal: test.TestAllTypes{}}`, - err: "error during formatting: string clause can only be used on strings, bools, bytes, ints, doubles, maps, lists, types, durations, and timestamps", - }, - { - name: "compile-time check for objects inside list literal", - format: "list is %s", - formatArgs: `[1, 2, ext.TestAllTypes{PbVal: test.TestAllTypes{}}]`, - err: "error during formatting: string clause can only be used on strings, bools, bytes, ints, doubles, maps, lists, types, durations, and timestamps", - }, - { - name: "compile-time %d check", - format: "int is %d", - formatArgs: "null", - err: "error during formatting: decimal clause can only be used on ints, uints, and doubles, was given null_type", - }, - { - name: "compile-time %f check", - format: "double is %f", - formatArgs: "true", - err: "error during formatting: fixed-point clause can only be used on ints, uints, and doubles, was given bool", - }, - { - name: "compile-time precision syntax check", - format: "double is %.34", - formatArgs: "5.0", - err: "could not parse formatting clause: error while parsing precision: could not find end of precision specifier", - }, - { - name: "compile-time %e check", - format: "double is %e", - formatArgs: "true", - err: "error during formatting: scientific clause can only be used on ints, uints, and doubles, was given bool", - }, - { - name: "compile-time %b check", - format: "string is %b", - formatArgs: `"a string"`, - err: "error during formatting: only ints, uints, and bools can be formatted as binary, was given string", - }, - { - name: "compile-time %x check", - format: "%x is a double", - formatArgs: "2.5", - err: "error during formatting: only ints, uints, bytes, and strings can be formatted as hex, was given double", - }, - { - name: "compile-time %X check", - format: "%X is a double", - formatArgs: "2.5", - err: "error during formatting: only ints, uints, bytes, and strings can be formatted as hex, was given double", - }, - { - name: "compile-time %o check", - format: "an octal: %o", - formatArgs: "3.14", - err: "octal clause can only be used on ints and uints, was given double", - }, - } - evalExpr := func(env *cel.Env, expr string, evalArgs any, expectedRuntimeCost uint64, expectedEstimatedCost checker.CostEstimate, t *testing.T) (ref.Val, error) { - t.Logf("evaluating expr: %s", expr) - parsedAst, issues := env.Parse(expr) - if issues.Err() != nil { - t.Fatalf("env.Parse(%v) failed: %v", expr, issues.Err()) - } - checkedAst, issues := env.Check(parsedAst) - if issues.Err() != nil { - return nil, issues.Err() - } - evalOpts := make([]cel.ProgramOption, 0) - costTracker := &noopCostEstimator{} - if expectedRuntimeCost != 0 { - evalOpts = append(evalOpts, cel.CostTracking(costTracker)) - } - program, err := env.Program(checkedAst, evalOpts...) - if err != nil { - return nil, err - } - - actualEstimatedCost, err := env.EstimateCost(checkedAst, costTracker) - if err != nil { - t.Fatal(err) - } - if expectedEstimatedCost.Min != 0 && expectedEstimatedCost.Max != 0 { - if actualEstimatedCost.Min != expectedEstimatedCost.Min && actualEstimatedCost.Max != expectedEstimatedCost.Max { - t.Fatalf("expected estimated cost range to be %v, was %v", expectedEstimatedCost, actualEstimatedCost) - } - } - - var out ref.Val - var details *cel.EvalDetails - if evalArgs != nil { - out, details, err = program.Eval(evalArgs) - } else { - out, details, err = program.Eval(cel.NoVars()) - } - - if expectedRuntimeCost != 0 { - if details == nil { - t.Fatal("no EvalDetails available when runtime cost was expected") - } - if *details.ActualCost() != expectedRuntimeCost { - t.Fatalf("expected runtime cost to be %d, was %d", expectedRuntimeCost, *details.ActualCost()) - } - if expectedEstimatedCost.Min != 0 && expectedEstimatedCost.Max != 0 { - if *details.ActualCost() < expectedEstimatedCost.Min || *details.ActualCost() > expectedEstimatedCost.Max { - t.Fatalf("runtime cost %d outside of expected estimated cost range %v", *details.ActualCost(), expectedEstimatedCost) - } - } - } - return out, err - } - buildVariables := func(vars map[string]any) []cel.EnvOption { - opts := make([]cel.EnvOption, len(vars)) - i := 0 - for name, value := range vars { - t := cel.DynType - switch v := value.(type) { - case proto.Message: - t = cel.ObjectType(string(v.ProtoReflect().Descriptor().FullName())) - case types.Bool: - t = cel.BoolType - case types.Bytes: - t = cel.BytesType - case types.Double: - t = cel.DoubleType - case types.Duration: - t = cel.DurationType - case types.Int: - t = cel.IntType - case types.Null: - t = cel.NullType - case types.String: - t = cel.StringType - case types.Timestamp: - t = cel.TimestampType - case types.Uint: - t = cel.UintType - } - opts[i] = cel.Variable(name, t) - i++ - } - return opts - } - buildOpts := func(skipCompileCheck bool, variables []cel.EnvOption) []cel.EnvOption { - opts := []cel.EnvOption{ - Strings(StringsValidateFormatCalls(!skipCompileCheck)), - cel.Container("ext"), - cel.Abbrevs("google.expr.proto3.test"), - cel.Types(&proto3pb.TestAllTypes{}), - NativeTypes( - reflect.TypeOf(&TestNestedType{}), - reflect.ValueOf(&TestAllTypes{}), - ), - } - opts = append(opts, cel.ASTValidators(cel.ValidateHomogeneousAggregateLiterals())) - opts = append(opts, variables...) - return opts - } - runCase := func(format, formatArgs string, dynArgs map[string]any, skipCompileCheck bool, expectedRuntimeCost uint64, expectedEstimatedCost checker.CostEstimate, t *testing.T) (ref.Val, error) { - env, err := cel.NewEnv(buildOpts(skipCompileCheck, buildVariables(dynArgs))...) - if err != nil { - t.Fatalf("cel.NewEnv() failed: %v", err) - } - expr := fmt.Sprintf("%q.format([%s])", format, formatArgs) - if len(dynArgs) == 0 { - return evalExpr(env, expr, cel.NoVars(), expectedRuntimeCost, expectedEstimatedCost, t) - } - return evalExpr(env, expr, dynArgs, expectedRuntimeCost, expectedEstimatedCost, t) - } - checkCase := func(output ref.Val, expectedOutput string, err error, expectedErr string, t *testing.T) { - if err != nil { - if expectedErr != "" { - if !strings.Contains(err.Error(), expectedErr) { - t.Fatalf("expected %q as error message, got %q", expectedErr, err.Error()) - } - } else { - t.Fatalf("unexpected error: %s", err) - } - } else { - if output.Type() != types.StringType { - t.Fatalf("expected test expr to eval to string (got %s instead)", output.Type().TypeName()) - } else { - outputStr := output.Value().(string) - if outputStr != expectedOutput { - t.Errorf("expected %q as output, got %q", expectedOutput, outputStr) - } - } - } - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - out, err := runCase(tt.format, tt.formatArgs, tt.dynArgs, tt.skipCompileCheck, tt.expectedRuntimeCost, tt.expectedEstimatedCost, t) - checkCase(out, tt.expectedOutput, err, tt.err, t) - }) - } -} - -func TestStringFormatHeterogeneousLiterals(t *testing.T) { - tests := []struct { - expr string - out string - }{ - { - expr: `"list: %s".format([[[1, 2, [3.0, 4]]]])`, - out: `list: [[1, 2, [3, 4]]]`, - }, - { - expr: `"list size: %d".format([[[1, 2, [3.0, 4]]].size()])`, - out: `list size: 1`, - }, - { - expr: `"list element: %s".format([[[1, 2, [3.0, 4]]][0]])`, - out: `list element: [1, 2, [3, 4]]`, - }, - } - env, err := cel.NewEnv(Strings(), cel.ASTValidators(cel.ValidateHomogeneousAggregateLiterals())) - if err != nil { - t.Fatalf("cel.NewEnv() failed: %v", err) - } - for _, tst := range tests { - tc := tst - t.Run(tc.expr, func(t *testing.T) { - ast, iss := env.Compile(tc.expr) - if iss.Err() != nil { - t.Fatalf("env.Compile(%q) failed: %v", tc.expr, iss.Err()) - } - prg, err := env.Program(ast) - if err != nil { - t.Fatalf("env.Program() failed: %v", err) - } - out, _, err := prg.Eval(cel.NoVars()) - if err != nil { - t.Fatalf("Eval() failed: %v", err) - } - if out.Value() != tc.out { - t.Errorf("Eval() got %v, wanted %v", out, tc.out) - } - }) - } -} - func mustParseDuration(s string) time.Duration { d, err := time.ParseDuration(s) if err != nil { diff --git a/go.mod b/go.mod index f7d96d112..8bf321c5a 100644 --- a/go.mod +++ b/go.mod @@ -15,5 +15,6 @@ require ( require ( golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc // indirect + golang.org/x/text v0.22.0 google.golang.org/genproto/googleapis/rpc v0.0.0-20240826202546-f6391c0de4c7 // indirect ) diff --git a/go.sum b/go.sum index 3d6fbb7eb..69a046f2b 100644 --- a/go.sum +++ b/go.sum @@ -15,6 +15,8 @@ github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc h1:mCRnTeVUjcrhlRmO0VK8a6k6Rrf6TF9htwo2pJVSjIU= golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= +golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= +golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= google.golang.org/genproto/googleapis/api v0.0.0-20240826202546-f6391c0de4c7 h1:YcyjlL1PRr2Q17/I0dPk2JmYS5CDXfcdb2Z3YRioEbw= google.golang.org/genproto/googleapis/api v0.0.0-20240826202546-f6391c0de4c7/go.mod h1:OCdP9MfskevB/rbYvHTsXTtKC+3bHWajPdoKgjcYkfo= google.golang.org/genproto/googleapis/rpc v0.0.0-20240826202546-f6391c0de4c7 h1:2035KHhUv+EpyB+hWgJnaWKJOdX1E95w2S8Rr4uWKTs= diff --git a/vendor/golang.org/x/text/LICENSE b/vendor/golang.org/x/text/LICENSE new file mode 100644 index 000000000..2a7cf70da --- /dev/null +++ b/vendor/golang.org/x/text/LICENSE @@ -0,0 +1,27 @@ +Copyright 2009 The Go Authors. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google LLC nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/golang.org/x/text/PATENTS b/vendor/golang.org/x/text/PATENTS new file mode 100644 index 000000000..733099041 --- /dev/null +++ b/vendor/golang.org/x/text/PATENTS @@ -0,0 +1,22 @@ +Additional IP Rights Grant (Patents) + +"This implementation" means the copyrightable works distributed by +Google as part of the Go project. + +Google hereby grants to You a perpetual, worldwide, non-exclusive, +no-charge, royalty-free, irrevocable (except as stated in this section) +patent license to make, have made, use, offer to sell, sell, import, +transfer and otherwise run, modify and propagate the contents of this +implementation of Go, where such license applies only to those patent +claims, both currently owned or controlled by Google and acquired in +the future, licensable by Google that are necessarily infringed by this +implementation of Go. This grant does not include claims that would be +infringed only as a consequence of further modification of this +implementation. If you or your agent or exclusive licensee institute or +order or agree to the institution of patent litigation against any +entity (including a cross-claim or counterclaim in a lawsuit) alleging +that this implementation of Go or any code incorporated within this +implementation of Go constitutes direct or contributory patent +infringement, or inducement of patent infringement, then any patent +rights granted to you under this License for this implementation of Go +shall terminate as of the date such litigation is filed. diff --git a/vendor/golang.org/x/text/feature/plural/common.go b/vendor/golang.org/x/text/feature/plural/common.go new file mode 100644 index 000000000..fdcb373fd --- /dev/null +++ b/vendor/golang.org/x/text/feature/plural/common.go @@ -0,0 +1,70 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +package plural + +// Form defines a plural form. +// +// Not all languages support all forms. Also, the meaning of each form varies +// per language. It is important to note that the name of a form does not +// necessarily correspond one-to-one with the set of numbers. For instance, +// for Croation, One matches not only 1, but also 11, 21, etc. +// +// Each language must at least support the form "other". +type Form byte + +const ( + Other Form = iota + Zero + One + Two + Few + Many +) + +var countMap = map[string]Form{ + "other": Other, + "zero": Zero, + "one": One, + "two": Two, + "few": Few, + "many": Many, +} + +type pluralCheck struct { + // category: + // 3..7: opID + // 0..2: category + cat byte + setID byte +} + +// opID identifies the type of operand in the plural rule, being i, n or f. +// (v, w, and t are treated as filters in our implementation.) +type opID byte + +const ( + opMod opID = 0x1 // is '%' used? + opNotEqual opID = 0x2 // using "!=" to compare + opI opID = 0 << 2 // integers after taking the absolute value + opN opID = 1 << 2 // full number (must be integer) + opF opID = 2 << 2 // fraction + opV opID = 3 << 2 // number of visible digits + opW opID = 4 << 2 // number of visible digits without trailing zeros + opBretonM opID = 5 << 2 // hard-wired rule for Breton + opItalian800 opID = 6 << 2 // hard-wired rule for Italian + opAzerbaijan00s opID = 7 << 2 // hard-wired rule for Azerbaijan +) +const ( + // Use this plural form to indicate the next rule needs to match as well. + // The last condition in the list will have the correct plural form. + andNext = 0x7 + formMask = 0x7 + + opShift = 3 + + // numN indicates the maximum integer, or maximum mod value, for which we + // have inclusion masks. + numN = 100 + // The common denominator of the modulo that is taken. + maxMod = 100 +) diff --git a/vendor/golang.org/x/text/feature/plural/message.go b/vendor/golang.org/x/text/feature/plural/message.go new file mode 100644 index 000000000..56d518cc3 --- /dev/null +++ b/vendor/golang.org/x/text/feature/plural/message.go @@ -0,0 +1,244 @@ +// 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 plural + +import ( + "fmt" + "io" + "reflect" + "strconv" + + "golang.org/x/text/internal/catmsg" + "golang.org/x/text/internal/number" + "golang.org/x/text/language" + "golang.org/x/text/message/catalog" +) + +// TODO: consider deleting this interface. Maybe VisibleDigits is always +// sufficient and practical. + +// Interface is used for types that can determine their own plural form. +type Interface interface { + // PluralForm reports the plural form for the given language of the + // underlying value. It also returns the integer value. If the integer value + // is larger than fits in n, PluralForm may return a value modulo + // 10,000,000. + PluralForm(t language.Tag, scale int) (f Form, n int) +} + +// Selectf returns the first case for which its selector is a match for the +// arg-th substitution argument to a formatting call, formatting it as indicated +// by format. +// +// The cases argument are pairs of selectors and messages. Selectors are of type +// string or Form. Messages are of type string or catalog.Message. A selector +// matches an argument if: +// - it is "other" or Other +// - it matches the plural form of the argument: "zero", "one", "two", "few", +// or "many", or the equivalent Form +// - it is of the form "=x" where x is an integer that matches the value of +// the argument. +// - it is of the form " kindDefault { + e.EncodeUint(uint64(m.scale)) + } + + forms := validForms(cardinal, e.Language()) + + for i := 0; i < len(m.cases); { + if err := compileSelector(e, forms, m.cases[i]); err != nil { + return err + } + if i++; i >= len(m.cases) { + return fmt.Errorf("plural: no message defined for selector %v", m.cases[i-1]) + } + var msg catalog.Message + switch x := m.cases[i].(type) { + case string: + msg = catalog.String(x) + case catalog.Message: + msg = x + default: + return fmt.Errorf("plural: message of type %T; must be string or catalog.Message", x) + } + if err := e.EncodeMessage(msg); err != nil { + return err + } + i++ + } + return nil +} + +func compileSelector(e *catmsg.Encoder, valid []Form, selector interface{}) error { + form := Other + switch x := selector.(type) { + case string: + if x == "" { + return fmt.Errorf("plural: empty selector") + } + if c := x[0]; c == '=' || c == '<' { + val, err := strconv.ParseUint(x[1:], 10, 16) + if err != nil { + return fmt.Errorf("plural: invalid number in selector %q: %v", selector, err) + } + e.EncodeUint(uint64(c)) + e.EncodeUint(val) + return nil + } + var ok bool + form, ok = countMap[x] + if !ok { + return fmt.Errorf("plural: invalid plural form %q", selector) + } + case Form: + form = x + default: + return fmt.Errorf("plural: selector of type %T; want string or Form", selector) + } + + ok := false + for _, f := range valid { + if f == form { + ok = true + break + } + } + if !ok { + return fmt.Errorf("plural: form %q not supported for language %q", selector, e.Language()) + } + e.EncodeUint(uint64(form)) + return nil +} + +func execute(d *catmsg.Decoder) bool { + lang := d.Language() + argN := int(d.DecodeUint()) + kind := int(d.DecodeUint()) + scale := -1 // default + if kind > kindDefault { + scale = int(d.DecodeUint()) + } + form := Other + n := -1 + if arg := d.Arg(argN); arg == nil { + // Default to Other. + } else if x, ok := arg.(number.VisibleDigits); ok { + d := x.Digits(nil, lang, scale) + form, n = cardinal.matchDisplayDigits(lang, &d) + } else if x, ok := arg.(Interface); ok { + // This covers lists and formatters from the number package. + form, n = x.PluralForm(lang, scale) + } else { + var f number.Formatter + switch kind { + case kindScale: + f.InitDecimal(lang) + f.SetScale(scale) + case kindScientific: + f.InitScientific(lang) + f.SetScale(scale) + case kindPrecision: + f.InitDecimal(lang) + f.SetPrecision(scale) + case kindDefault: + // sensible default + f.InitDecimal(lang) + if k := reflect.TypeOf(arg).Kind(); reflect.Int <= k && k <= reflect.Uintptr { + f.SetScale(0) + } else { + f.SetScale(2) + } + } + var dec number.Decimal // TODO: buffer in Printer + dec.Convert(f.RoundingContext, arg) + v := number.FormatDigits(&dec, f.RoundingContext) + if !v.NaN && !v.Inf { + form, n = cardinal.matchDisplayDigits(d.Language(), &v) + } + } + for !d.Done() { + f := d.DecodeUint() + if (f == '=' && n == int(d.DecodeUint())) || + (f == '<' && 0 <= n && n < int(d.DecodeUint())) || + form == Form(f) || + Other == Form(f) { + return d.ExecuteMessage() + } + d.SkipMessage() + } + return false +} diff --git a/vendor/golang.org/x/text/feature/plural/plural.go b/vendor/golang.org/x/text/feature/plural/plural.go new file mode 100644 index 000000000..e9f2d42e0 --- /dev/null +++ b/vendor/golang.org/x/text/feature/plural/plural.go @@ -0,0 +1,262 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:generate go run gen.go gen_common.go + +// Package plural provides utilities for handling linguistic plurals in text. +// +// The definitions in this package are based on the plural rule handling defined +// in CLDR. See +// https://unicode.org/reports/tr35/tr35-numbers.html#Language_Plural_Rules for +// details. +package plural + +import ( + "golang.org/x/text/internal/language/compact" + "golang.org/x/text/internal/number" + "golang.org/x/text/language" +) + +// Rules defines the plural rules for all languages for a certain plural type. +// +// This package is UNDER CONSTRUCTION and its API may change. +type Rules struct { + rules []pluralCheck + index []byte + langToIndex []byte + inclusionMasks []uint64 +} + +var ( + // Cardinal defines the plural rules for numbers indicating quantities. + Cardinal *Rules = cardinal + + // Ordinal defines the plural rules for numbers indicating position + // (first, second, etc.). + Ordinal *Rules = ordinal + + ordinal = &Rules{ + ordinalRules, + ordinalIndex, + ordinalLangToIndex, + ordinalInclusionMasks[:], + } + + cardinal = &Rules{ + cardinalRules, + cardinalIndex, + cardinalLangToIndex, + cardinalInclusionMasks[:], + } +) + +// getIntApprox converts the digits in slice digits[start:end] to an integer +// according to the following rules: +// - Let i be asInt(digits[start:end]), where out-of-range digits are assumed +// to be zero. +// - Result n is big if i / 10^nMod > 1. +// - Otherwise the result is i % 10^nMod. +// +// For example, if digits is {1, 2, 3} and start:end is 0:5, then the result +// for various values of nMod is: +// - when nMod == 2, n == big +// - when nMod == 3, n == big +// - when nMod == 4, n == big +// - when nMod == 5, n == 12300 +// - when nMod == 6, n == 12300 +// - when nMod == 7, n == 12300 +func getIntApprox(digits []byte, start, end, nMod, big int) (n int) { + // Leading 0 digits just result in 0. + p := start + if p < 0 { + p = 0 + } + // Range only over the part for which we have digits. + mid := end + if mid >= len(digits) { + mid = len(digits) + } + // Check digits more significant that nMod. + if q := end - nMod; q > 0 { + if q > mid { + q = mid + } + for ; p < q; p++ { + if digits[p] != 0 { + return big + } + } + } + for ; p < mid; p++ { + n = 10*n + int(digits[p]) + } + // Multiply for trailing zeros. + for ; p < end; p++ { + n *= 10 + } + return n +} + +// MatchDigits computes the plural form for the given language and the given +// decimal floating point digits. The digits are stored in big-endian order and +// are of value byte(0) - byte(9). The floating point position is indicated by +// exp and the number of visible decimals is scale. All leading and trailing +// zeros may be omitted from digits. +// +// The following table contains examples of possible arguments to represent +// the given numbers. +// +// decimal digits exp scale +// 123 []byte{1, 2, 3} 3 0 +// 123.4 []byte{1, 2, 3, 4} 3 1 +// 123.40 []byte{1, 2, 3, 4} 3 2 +// 100000 []byte{1} 6 0 +// 100000.00 []byte{1} 6 3 +func (p *Rules) MatchDigits(t language.Tag, digits []byte, exp, scale int) Form { + index := tagToID(t) + + // Differentiate up to including mod 1000000 for the integer part. + n := getIntApprox(digits, 0, exp, 6, 1000000) + + // Differentiate up to including mod 100 for the fractional part. + f := getIntApprox(digits, exp, exp+scale, 2, 100) + + return matchPlural(p, index, n, f, scale) +} + +func (p *Rules) matchDisplayDigits(t language.Tag, d *number.Digits) (Form, int) { + n := getIntApprox(d.Digits, 0, int(d.Exp), 6, 1000000) + return p.MatchDigits(t, d.Digits, int(d.Exp), d.NumFracDigits()), n +} + +func validForms(p *Rules, t language.Tag) (forms []Form) { + offset := p.langToIndex[tagToID(t)] + rules := p.rules[p.index[offset]:p.index[offset+1]] + + forms = append(forms, Other) + last := Other + for _, r := range rules { + if cat := Form(r.cat & formMask); cat != andNext && last != cat { + forms = append(forms, cat) + last = cat + } + } + return forms +} + +func (p *Rules) matchComponents(t language.Tag, n, f, scale int) Form { + return matchPlural(p, tagToID(t), n, f, scale) +} + +// MatchPlural returns the plural form for the given language and plural +// operands (as defined in +// https://unicode.org/reports/tr35/tr35-numbers.html#Language_Plural_Rules): +// +// where +// n absolute value of the source number (integer and decimals) +// input +// i integer digits of n. +// v number of visible fraction digits in n, with trailing zeros. +// w number of visible fraction digits in n, without trailing zeros. +// f visible fractional digits in n, with trailing zeros (f = t * 10^(v-w)) +// t visible fractional digits in n, without trailing zeros. +// +// If any of the operand values is too large to fit in an int, it is okay to +// pass the value modulo 10,000,000. +func (p *Rules) MatchPlural(lang language.Tag, i, v, w, f, t int) Form { + return matchPlural(p, tagToID(lang), i, f, v) +} + +func matchPlural(p *Rules, index compact.ID, n, f, v int) Form { + nMask := p.inclusionMasks[n%maxMod] + // Compute the fMask inline in the rules below, as it is relatively rare. + // fMask := p.inclusionMasks[f%maxMod] + vMask := p.inclusionMasks[v%maxMod] + + // Do the matching + offset := p.langToIndex[index] + rules := p.rules[p.index[offset]:p.index[offset+1]] + for i := 0; i < len(rules); i++ { + rule := rules[i] + setBit := uint64(1 << rule.setID) + var skip bool + switch op := opID(rule.cat >> opShift); op { + case opI: // i = x + skip = n >= numN || nMask&setBit == 0 + + case opI | opNotEqual: // i != x + skip = n < numN && nMask&setBit != 0 + + case opI | opMod: // i % m = x + skip = nMask&setBit == 0 + + case opI | opMod | opNotEqual: // i % m != x + skip = nMask&setBit != 0 + + case opN: // n = x + skip = f != 0 || n >= numN || nMask&setBit == 0 + + case opN | opNotEqual: // n != x + skip = f == 0 && n < numN && nMask&setBit != 0 + + case opN | opMod: // n % m = x + skip = f != 0 || nMask&setBit == 0 + + case opN | opMod | opNotEqual: // n % m != x + skip = f == 0 && nMask&setBit != 0 + + case opF: // f = x + skip = f >= numN || p.inclusionMasks[f%maxMod]&setBit == 0 + + case opF | opNotEqual: // f != x + skip = f < numN && p.inclusionMasks[f%maxMod]&setBit != 0 + + case opF | opMod: // f % m = x + skip = p.inclusionMasks[f%maxMod]&setBit == 0 + + case opF | opMod | opNotEqual: // f % m != x + skip = p.inclusionMasks[f%maxMod]&setBit != 0 + + case opV: // v = x + skip = v < numN && vMask&setBit == 0 + + case opV | opNotEqual: // v != x + skip = v < numN && vMask&setBit != 0 + + case opW: // w == 0 + skip = f != 0 + + case opW | opNotEqual: // w != 0 + skip = f == 0 + + // Hard-wired rules that cannot be handled by our algorithm. + + case opBretonM: + skip = f != 0 || n == 0 || n%1000000 != 0 + + case opAzerbaijan00s: + // 100,200,300,400,500,600,700,800,900 + skip = n == 0 || n >= 1000 || n%100 != 0 + + case opItalian800: + skip = (f != 0 || n >= numN || nMask&setBit == 0) && n != 800 + } + if skip { + // advance over AND entries. + for ; i < len(rules) && rules[i].cat&formMask == andNext; i++ { + } + continue + } + // return if we have a final entry. + if cat := rule.cat & formMask; cat != andNext { + return Form(cat) + } + } + return Other +} + +func tagToID(t language.Tag) compact.ID { + id, _ := compact.RegionalID(compact.Tag(t)) + return id +} diff --git a/vendor/golang.org/x/text/feature/plural/tables.go b/vendor/golang.org/x/text/feature/plural/tables.go new file mode 100644 index 000000000..b06b9cb4e --- /dev/null +++ b/vendor/golang.org/x/text/feature/plural/tables.go @@ -0,0 +1,552 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +package plural + +// CLDRVersion is the CLDR version from which the tables in this package are derived. +const CLDRVersion = "32" + +var ordinalRules = []pluralCheck{ // 64 elements + 0: {cat: 0x2f, setID: 0x4}, + 1: {cat: 0x3a, setID: 0x5}, + 2: {cat: 0x22, setID: 0x1}, + 3: {cat: 0x22, setID: 0x6}, + 4: {cat: 0x22, setID: 0x7}, + 5: {cat: 0x2f, setID: 0x8}, + 6: {cat: 0x3c, setID: 0x9}, + 7: {cat: 0x2f, setID: 0xa}, + 8: {cat: 0x3c, setID: 0xb}, + 9: {cat: 0x2c, setID: 0xc}, + 10: {cat: 0x24, setID: 0xd}, + 11: {cat: 0x2d, setID: 0xe}, + 12: {cat: 0x2d, setID: 0xf}, + 13: {cat: 0x2f, setID: 0x10}, + 14: {cat: 0x35, setID: 0x3}, + 15: {cat: 0xc5, setID: 0x11}, + 16: {cat: 0x2, setID: 0x1}, + 17: {cat: 0x5, setID: 0x3}, + 18: {cat: 0xd, setID: 0x12}, + 19: {cat: 0x22, setID: 0x1}, + 20: {cat: 0x2f, setID: 0x13}, + 21: {cat: 0x3d, setID: 0x14}, + 22: {cat: 0x2f, setID: 0x15}, + 23: {cat: 0x3a, setID: 0x16}, + 24: {cat: 0x2f, setID: 0x17}, + 25: {cat: 0x3b, setID: 0x18}, + 26: {cat: 0x2f, setID: 0xa}, + 27: {cat: 0x3c, setID: 0xb}, + 28: {cat: 0x22, setID: 0x1}, + 29: {cat: 0x23, setID: 0x19}, + 30: {cat: 0x24, setID: 0x1a}, + 31: {cat: 0x22, setID: 0x1b}, + 32: {cat: 0x23, setID: 0x2}, + 33: {cat: 0x24, setID: 0x1a}, + 34: {cat: 0xf, setID: 0x15}, + 35: {cat: 0x1a, setID: 0x16}, + 36: {cat: 0xf, setID: 0x17}, + 37: {cat: 0x1b, setID: 0x18}, + 38: {cat: 0xf, setID: 0x1c}, + 39: {cat: 0x1d, setID: 0x1d}, + 40: {cat: 0xa, setID: 0x1e}, + 41: {cat: 0xa, setID: 0x1f}, + 42: {cat: 0xc, setID: 0x20}, + 43: {cat: 0xe4, setID: 0x0}, + 44: {cat: 0x5, setID: 0x3}, + 45: {cat: 0xd, setID: 0xe}, + 46: {cat: 0xd, setID: 0x21}, + 47: {cat: 0x22, setID: 0x1}, + 48: {cat: 0x23, setID: 0x19}, + 49: {cat: 0x24, setID: 0x1a}, + 50: {cat: 0x25, setID: 0x22}, + 51: {cat: 0x22, setID: 0x23}, + 52: {cat: 0x23, setID: 0x19}, + 53: {cat: 0x24, setID: 0x1a}, + 54: {cat: 0x25, setID: 0x22}, + 55: {cat: 0x22, setID: 0x24}, + 56: {cat: 0x23, setID: 0x19}, + 57: {cat: 0x24, setID: 0x1a}, + 58: {cat: 0x25, setID: 0x22}, + 59: {cat: 0x21, setID: 0x25}, + 60: {cat: 0x22, setID: 0x1}, + 61: {cat: 0x23, setID: 0x2}, + 62: {cat: 0x24, setID: 0x26}, + 63: {cat: 0x25, setID: 0x27}, +} // Size: 152 bytes + +var ordinalIndex = []uint8{ // 22 elements + 0x00, 0x00, 0x02, 0x03, 0x04, 0x05, 0x07, 0x09, + 0x0b, 0x0f, 0x10, 0x13, 0x16, 0x1c, 0x1f, 0x22, + 0x28, 0x2f, 0x33, 0x37, 0x3b, 0x40, +} // Size: 46 bytes + +var ordinalLangToIndex = []uint8{ // 775 elements + // Entry 0 - 3F + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x12, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x00, 0x00, 0x05, 0x05, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // Entry 40 - 7F + 0x12, 0x12, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, + 0x0e, 0x0e, 0x0e, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x14, 0x14, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // Entry 80 - BF + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + // Entry C0 - FF + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // Entry 100 - 13F + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, + 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + // Entry 140 - 17F + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, + 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, + 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // Entry 180 - 1BF + 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // Entry 1C0 - 1FF + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x0d, 0x0d, 0x02, 0x02, 0x02, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // Entry 200 - 23F + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x13, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // Entry 240 - 27F + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // Entry 280 - 2BF + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0b, 0x0b, 0x0b, 0x0b, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x07, 0x07, 0x02, 0x00, 0x00, 0x00, 0x00, + // Entry 2C0 - 2FF + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // Entry 300 - 33F + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x0c, +} // Size: 799 bytes + +var ordinalInclusionMasks = []uint64{ // 100 elements + // Entry 0 - 1F + 0x0000002000010009, 0x00000018482000d3, 0x0000000042840195, 0x000000410a040581, + 0x00000041040c0081, 0x0000009840040041, 0x0000008400045001, 0x0000003850040001, + 0x0000003850060001, 0x0000003800049001, 0x0000000800052001, 0x0000000040660031, + 0x0000000041840331, 0x0000000100040f01, 0x00000001001c0001, 0x0000000040040001, + 0x0000000000045001, 0x0000000070040001, 0x0000000070040001, 0x0000000000049001, + 0x0000000080050001, 0x0000000040200011, 0x0000000040800111, 0x0000000100000501, + 0x0000000100080001, 0x0000000040000001, 0x0000000000005001, 0x0000000050000001, + 0x0000000050000001, 0x0000000000009001, 0x0000000000010001, 0x0000000040200011, + // Entry 20 - 3F + 0x0000000040800111, 0x0000000100000501, 0x0000000100080001, 0x0000000040000001, + 0x0000000000005001, 0x0000000050000001, 0x0000000050000001, 0x0000000000009001, + 0x0000000200050001, 0x0000000040200011, 0x0000000040800111, 0x0000000100000501, + 0x0000000100080001, 0x0000000040000001, 0x0000000000005001, 0x0000000050000001, + 0x0000000050000001, 0x0000000000009001, 0x0000000080010001, 0x0000000040200011, + 0x0000000040800111, 0x0000000100000501, 0x0000000100080001, 0x0000000040000001, + 0x0000000000005001, 0x0000000050000001, 0x0000000050000001, 0x0000000000009001, + 0x0000000200050001, 0x0000000040200011, 0x0000000040800111, 0x0000000100000501, + // Entry 40 - 5F + 0x0000000100080001, 0x0000000040000001, 0x0000000000005001, 0x0000000050000001, + 0x0000000050000001, 0x0000000000009001, 0x0000000080010001, 0x0000000040200011, + 0x0000000040800111, 0x0000000100000501, 0x0000000100080001, 0x0000000040000001, + 0x0000000000005001, 0x0000000050000001, 0x0000000050000001, 0x0000000000009001, + 0x0000000080070001, 0x0000000040200011, 0x0000000040800111, 0x0000000100000501, + 0x0000000100080001, 0x0000000040000001, 0x0000000000005001, 0x0000000050000001, + 0x0000000050000001, 0x0000000000009001, 0x0000000200010001, 0x0000000040200011, + 0x0000000040800111, 0x0000000100000501, 0x0000000100080001, 0x0000000040000001, + // Entry 60 - 7F + 0x0000000000005001, 0x0000000050000001, 0x0000000050000001, 0x0000000000009001, +} // Size: 824 bytes + +// Slots used for ordinal: 40 of 0xFF rules; 16 of 0xFF indexes; 40 of 64 sets + +var cardinalRules = []pluralCheck{ // 166 elements + 0: {cat: 0x2, setID: 0x3}, + 1: {cat: 0x22, setID: 0x1}, + 2: {cat: 0x2, setID: 0x4}, + 3: {cat: 0x2, setID: 0x4}, + 4: {cat: 0x7, setID: 0x1}, + 5: {cat: 0x62, setID: 0x3}, + 6: {cat: 0x22, setID: 0x4}, + 7: {cat: 0x7, setID: 0x3}, + 8: {cat: 0x42, setID: 0x1}, + 9: {cat: 0x22, setID: 0x4}, + 10: {cat: 0x22, setID: 0x4}, + 11: {cat: 0x22, setID: 0x5}, + 12: {cat: 0x22, setID: 0x1}, + 13: {cat: 0x22, setID: 0x1}, + 14: {cat: 0x7, setID: 0x4}, + 15: {cat: 0x92, setID: 0x3}, + 16: {cat: 0xf, setID: 0x6}, + 17: {cat: 0x1f, setID: 0x7}, + 18: {cat: 0x82, setID: 0x3}, + 19: {cat: 0x92, setID: 0x3}, + 20: {cat: 0xf, setID: 0x6}, + 21: {cat: 0x62, setID: 0x3}, + 22: {cat: 0x4a, setID: 0x6}, + 23: {cat: 0x7, setID: 0x8}, + 24: {cat: 0x62, setID: 0x3}, + 25: {cat: 0x1f, setID: 0x9}, + 26: {cat: 0x62, setID: 0x3}, + 27: {cat: 0x5f, setID: 0x9}, + 28: {cat: 0x72, setID: 0x3}, + 29: {cat: 0x29, setID: 0xa}, + 30: {cat: 0x29, setID: 0xb}, + 31: {cat: 0x4f, setID: 0xb}, + 32: {cat: 0x61, setID: 0x2}, + 33: {cat: 0x2f, setID: 0x6}, + 34: {cat: 0x3a, setID: 0x7}, + 35: {cat: 0x4f, setID: 0x6}, + 36: {cat: 0x5f, setID: 0x7}, + 37: {cat: 0x62, setID: 0x2}, + 38: {cat: 0x4f, setID: 0x6}, + 39: {cat: 0x72, setID: 0x2}, + 40: {cat: 0x21, setID: 0x3}, + 41: {cat: 0x7, setID: 0x4}, + 42: {cat: 0x32, setID: 0x3}, + 43: {cat: 0x21, setID: 0x3}, + 44: {cat: 0x22, setID: 0x1}, + 45: {cat: 0x22, setID: 0x1}, + 46: {cat: 0x23, setID: 0x2}, + 47: {cat: 0x2, setID: 0x3}, + 48: {cat: 0x22, setID: 0x1}, + 49: {cat: 0x24, setID: 0xc}, + 50: {cat: 0x7, setID: 0x1}, + 51: {cat: 0x62, setID: 0x3}, + 52: {cat: 0x74, setID: 0x3}, + 53: {cat: 0x24, setID: 0x3}, + 54: {cat: 0x2f, setID: 0xd}, + 55: {cat: 0x34, setID: 0x1}, + 56: {cat: 0xf, setID: 0x6}, + 57: {cat: 0x1f, setID: 0x7}, + 58: {cat: 0x62, setID: 0x3}, + 59: {cat: 0x4f, setID: 0x6}, + 60: {cat: 0x5a, setID: 0x7}, + 61: {cat: 0xf, setID: 0xe}, + 62: {cat: 0x1f, setID: 0xf}, + 63: {cat: 0x64, setID: 0x3}, + 64: {cat: 0x4f, setID: 0xe}, + 65: {cat: 0x5c, setID: 0xf}, + 66: {cat: 0x22, setID: 0x10}, + 67: {cat: 0x23, setID: 0x11}, + 68: {cat: 0x24, setID: 0x12}, + 69: {cat: 0xf, setID: 0x1}, + 70: {cat: 0x62, setID: 0x3}, + 71: {cat: 0xf, setID: 0x2}, + 72: {cat: 0x63, setID: 0x3}, + 73: {cat: 0xf, setID: 0x13}, + 74: {cat: 0x64, setID: 0x3}, + 75: {cat: 0x74, setID: 0x3}, + 76: {cat: 0xf, setID: 0x1}, + 77: {cat: 0x62, setID: 0x3}, + 78: {cat: 0x4a, setID: 0x1}, + 79: {cat: 0xf, setID: 0x2}, + 80: {cat: 0x63, setID: 0x3}, + 81: {cat: 0x4b, setID: 0x2}, + 82: {cat: 0xf, setID: 0x13}, + 83: {cat: 0x64, setID: 0x3}, + 84: {cat: 0x4c, setID: 0x13}, + 85: {cat: 0x7, setID: 0x1}, + 86: {cat: 0x62, setID: 0x3}, + 87: {cat: 0x7, setID: 0x2}, + 88: {cat: 0x63, setID: 0x3}, + 89: {cat: 0x2f, setID: 0xa}, + 90: {cat: 0x37, setID: 0x14}, + 91: {cat: 0x65, setID: 0x3}, + 92: {cat: 0x7, setID: 0x1}, + 93: {cat: 0x62, setID: 0x3}, + 94: {cat: 0x7, setID: 0x15}, + 95: {cat: 0x64, setID: 0x3}, + 96: {cat: 0x75, setID: 0x3}, + 97: {cat: 0x7, setID: 0x1}, + 98: {cat: 0x62, setID: 0x3}, + 99: {cat: 0xf, setID: 0xe}, + 100: {cat: 0x1f, setID: 0xf}, + 101: {cat: 0x64, setID: 0x3}, + 102: {cat: 0xf, setID: 0x16}, + 103: {cat: 0x17, setID: 0x1}, + 104: {cat: 0x65, setID: 0x3}, + 105: {cat: 0xf, setID: 0x17}, + 106: {cat: 0x65, setID: 0x3}, + 107: {cat: 0xf, setID: 0xf}, + 108: {cat: 0x65, setID: 0x3}, + 109: {cat: 0x2f, setID: 0x6}, + 110: {cat: 0x3a, setID: 0x7}, + 111: {cat: 0x2f, setID: 0xe}, + 112: {cat: 0x3c, setID: 0xf}, + 113: {cat: 0x2d, setID: 0xa}, + 114: {cat: 0x2d, setID: 0x17}, + 115: {cat: 0x2d, setID: 0x18}, + 116: {cat: 0x2f, setID: 0x6}, + 117: {cat: 0x3a, setID: 0xb}, + 118: {cat: 0x2f, setID: 0x19}, + 119: {cat: 0x3c, setID: 0xb}, + 120: {cat: 0x55, setID: 0x3}, + 121: {cat: 0x22, setID: 0x1}, + 122: {cat: 0x24, setID: 0x3}, + 123: {cat: 0x2c, setID: 0xc}, + 124: {cat: 0x2d, setID: 0xb}, + 125: {cat: 0xf, setID: 0x6}, + 126: {cat: 0x1f, setID: 0x7}, + 127: {cat: 0x62, setID: 0x3}, + 128: {cat: 0xf, setID: 0xe}, + 129: {cat: 0x1f, setID: 0xf}, + 130: {cat: 0x64, setID: 0x3}, + 131: {cat: 0xf, setID: 0xa}, + 132: {cat: 0x65, setID: 0x3}, + 133: {cat: 0xf, setID: 0x17}, + 134: {cat: 0x65, setID: 0x3}, + 135: {cat: 0xf, setID: 0x18}, + 136: {cat: 0x65, setID: 0x3}, + 137: {cat: 0x2f, setID: 0x6}, + 138: {cat: 0x3a, setID: 0x1a}, + 139: {cat: 0x2f, setID: 0x1b}, + 140: {cat: 0x3b, setID: 0x1c}, + 141: {cat: 0x2f, setID: 0x1d}, + 142: {cat: 0x3c, setID: 0x1e}, + 143: {cat: 0x37, setID: 0x3}, + 144: {cat: 0xa5, setID: 0x0}, + 145: {cat: 0x22, setID: 0x1}, + 146: {cat: 0x23, setID: 0x2}, + 147: {cat: 0x24, setID: 0x1f}, + 148: {cat: 0x25, setID: 0x20}, + 149: {cat: 0xf, setID: 0x6}, + 150: {cat: 0x62, setID: 0x3}, + 151: {cat: 0xf, setID: 0x1b}, + 152: {cat: 0x63, setID: 0x3}, + 153: {cat: 0xf, setID: 0x21}, + 154: {cat: 0x64, setID: 0x3}, + 155: {cat: 0x75, setID: 0x3}, + 156: {cat: 0x21, setID: 0x3}, + 157: {cat: 0x22, setID: 0x1}, + 158: {cat: 0x23, setID: 0x2}, + 159: {cat: 0x2c, setID: 0x22}, + 160: {cat: 0x2d, setID: 0x5}, + 161: {cat: 0x21, setID: 0x3}, + 162: {cat: 0x22, setID: 0x1}, + 163: {cat: 0x23, setID: 0x2}, + 164: {cat: 0x24, setID: 0x23}, + 165: {cat: 0x25, setID: 0x24}, +} // Size: 356 bytes + +var cardinalIndex = []uint8{ // 36 elements + 0x00, 0x00, 0x02, 0x03, 0x04, 0x06, 0x09, 0x0a, + 0x0c, 0x0d, 0x10, 0x14, 0x17, 0x1d, 0x28, 0x2b, + 0x2d, 0x2f, 0x32, 0x38, 0x42, 0x45, 0x4c, 0x55, + 0x5c, 0x61, 0x6d, 0x74, 0x79, 0x7d, 0x89, 0x91, + 0x95, 0x9c, 0xa1, 0xa6, +} // Size: 60 bytes + +var cardinalLangToIndex = []uint8{ // 775 elements + // Entry 0 - 3F + 0x00, 0x08, 0x08, 0x08, 0x00, 0x00, 0x06, 0x06, + 0x01, 0x01, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, + 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, + 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, + 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, + 0x01, 0x01, 0x08, 0x08, 0x04, 0x04, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x00, 0x00, 0x1a, 0x1a, 0x08, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x06, 0x00, 0x00, + // Entry 40 - 7F + 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x1e, 0x1e, + 0x08, 0x08, 0x13, 0x13, 0x13, 0x13, 0x13, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x08, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x18, 0x18, 0x00, 0x00, 0x22, 0x22, 0x09, 0x09, + 0x09, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x00, 0x00, 0x16, 0x16, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // Entry 80 - BF + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 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, + 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, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, + // Entry 100 - 13F + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, + 0x08, 0x08, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x04, 0x04, 0x0c, 0x0c, + 0x08, 0x08, 0x08, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + // Entry 140 - 17F + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x08, 0x08, 0x04, 0x04, 0x1f, 0x1f, + 0x14, 0x14, 0x04, 0x04, 0x08, 0x08, 0x08, 0x08, + 0x01, 0x01, 0x06, 0x00, 0x00, 0x20, 0x20, 0x08, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x17, 0x17, 0x01, + 0x01, 0x13, 0x13, 0x13, 0x16, 0x16, 0x08, 0x08, + 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // Entry 180 - 1BF + 0x00, 0x04, 0x0a, 0x0a, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x10, 0x17, 0x00, 0x00, 0x00, 0x08, 0x08, + 0x04, 0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x02, + 0x02, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, + 0x08, 0x08, 0x00, 0x00, 0x0f, 0x0f, 0x08, 0x10, + // Entry 1C0 - 1FF + 0x10, 0x08, 0x08, 0x0e, 0x0e, 0x08, 0x08, 0x08, + 0x08, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x1b, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x0d, 0x08, + 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, + 0x00, 0x00, 0x08, 0x08, 0x0b, 0x0b, 0x08, 0x08, + 0x08, 0x08, 0x12, 0x01, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x1c, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, + // Entry 200 - 23F + 0x00, 0x08, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, + 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x08, + 0x06, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x08, 0x19, 0x19, 0x0d, 0x0d, + 0x08, 0x08, 0x03, 0x04, 0x03, 0x04, 0x04, 0x04, + // Entry 240 - 27F + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x12, + 0x12, 0x12, 0x08, 0x08, 0x1d, 0x1d, 0x1d, 0x1d, + 0x1d, 0x1d, 0x1d, 0x00, 0x00, 0x08, 0x08, 0x00, + 0x00, 0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x08, + 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x13, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x05, 0x05, 0x18, 0x18, 0x15, 0x15, 0x10, 0x10, + // Entry 280 - 2BF + 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x13, + 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, + 0x13, 0x13, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, + 0x08, 0x08, 0x08, 0x0c, 0x08, 0x00, 0x00, 0x08, + // Entry 2C0 - 2FF + 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x07, + 0x07, 0x08, 0x08, 0x1d, 0x1d, 0x04, 0x04, 0x04, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, + 0x08, 0x08, 0x08, 0x06, 0x08, 0x08, 0x00, 0x00, + 0x08, 0x08, 0x08, 0x00, 0x00, 0x04, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // Entry 300 - 33F + 0x00, 0x00, 0x00, 0x01, 0x01, 0x04, 0x04, +} // Size: 799 bytes + +var cardinalInclusionMasks = []uint64{ // 100 elements + // Entry 0 - 1F + 0x0000000200500419, 0x0000000000512153, 0x000000000a327105, 0x0000000ca23c7101, + 0x00000004a23c7201, 0x0000000482943001, 0x0000001482943201, 0x0000000502943001, + 0x0000000502943001, 0x0000000522943201, 0x0000000540543401, 0x00000000454128e1, + 0x000000005b02e821, 0x000000006304e821, 0x000000006304ea21, 0x0000000042842821, + 0x0000000042842a21, 0x0000000042842821, 0x0000000042842821, 0x0000000062842a21, + 0x0000000200400421, 0x0000000000400061, 0x000000000a004021, 0x0000000022004021, + 0x0000000022004221, 0x0000000002800021, 0x0000000002800221, 0x0000000002800021, + 0x0000000002800021, 0x0000000022800221, 0x0000000000400421, 0x0000000000400061, + // Entry 20 - 3F + 0x000000000a004021, 0x0000000022004021, 0x0000000022004221, 0x0000000002800021, + 0x0000000002800221, 0x0000000002800021, 0x0000000002800021, 0x0000000022800221, + 0x0000000200400421, 0x0000000000400061, 0x000000000a004021, 0x0000000022004021, + 0x0000000022004221, 0x0000000002800021, 0x0000000002800221, 0x0000000002800021, + 0x0000000002800021, 0x0000000022800221, 0x0000000000400421, 0x0000000000400061, + 0x000000000a004021, 0x0000000022004021, 0x0000000022004221, 0x0000000002800021, + 0x0000000002800221, 0x0000000002800021, 0x0000000002800021, 0x0000000022800221, + 0x0000000200400421, 0x0000000000400061, 0x000000000a004021, 0x0000000022004021, + // Entry 40 - 5F + 0x0000000022004221, 0x0000000002800021, 0x0000000002800221, 0x0000000002800021, + 0x0000000002800021, 0x0000000022800221, 0x0000000040400421, 0x0000000044400061, + 0x000000005a004021, 0x0000000062004021, 0x0000000062004221, 0x0000000042800021, + 0x0000000042800221, 0x0000000042800021, 0x0000000042800021, 0x0000000062800221, + 0x0000000200400421, 0x0000000000400061, 0x000000000a004021, 0x0000000022004021, + 0x0000000022004221, 0x0000000002800021, 0x0000000002800221, 0x0000000002800021, + 0x0000000002800021, 0x0000000022800221, 0x0000000040400421, 0x0000000044400061, + 0x000000005a004021, 0x0000000062004021, 0x0000000062004221, 0x0000000042800021, + // Entry 60 - 7F + 0x0000000042800221, 0x0000000042800021, 0x0000000042800021, 0x0000000062800221, +} // Size: 824 bytes + +// Slots used for cardinal: A6 of 0xFF rules; 24 of 0xFF indexes; 37 of 64 sets + +// Total table size 3860 bytes (3KiB); checksum: AAFBF21 diff --git a/vendor/golang.org/x/text/internal/catmsg/catmsg.go b/vendor/golang.org/x/text/internal/catmsg/catmsg.go new file mode 100644 index 000000000..1b257a7b4 --- /dev/null +++ b/vendor/golang.org/x/text/internal/catmsg/catmsg.go @@ -0,0 +1,417 @@ +// 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 catmsg contains support types for package x/text/message/catalog. +// +// This package contains the low-level implementations of Message used by the +// catalog package and provides primitives for other packages to implement their +// own. For instance, the plural package provides functionality for selecting +// translation strings based on the plural category of substitution arguments. +// +// # Encoding and Decoding +// +// Catalogs store Messages encoded as a single string. Compiling a message into +// a string both results in compacter representation and speeds up evaluation. +// +// A Message must implement a Compile method to convert its arbitrary +// representation to a string. The Compile method takes an Encoder which +// facilitates serializing the message. Encoders also provide more context of +// the messages's creation (such as for which language the message is intended), +// which may not be known at the time of the creation of the message. +// +// Each message type must also have an accompanying decoder registered to decode +// the message. This decoder takes a Decoder argument which provides the +// counterparts for the decoding. +// +// # Renderers +// +// A Decoder must be initialized with a Renderer implementation. These +// implementations must be provided by packages that use Catalogs, typically +// formatting packages such as x/text/message. A typical user will not need to +// worry about this type; it is only relevant to packages that do string +// formatting and want to use the catalog package to handle localized strings. +// +// A package that uses catalogs for selecting strings receives selection results +// as sequence of substrings passed to the Renderer. The following snippet shows +// how to express the above example using the message package. +// +// message.Set(language.English, "You are %d minute(s) late.", +// catalog.Var("minutes", plural.Select(1, "one", "minute")), +// catalog.String("You are %[1]d ${minutes} late.")) +// +// p := message.NewPrinter(language.English) +// p.Printf("You are %d minute(s) late.", 5) // always 5 minutes late. +// +// To evaluate the Printf, package message wraps the arguments in a Renderer +// that is passed to the catalog for message decoding. The call sequence that +// results from evaluating the above message, assuming the person is rather +// tardy, is: +// +// Render("You are %[1]d ") +// Arg(1) +// Render("minutes") +// Render(" late.") +// +// The calls to Arg is caused by the plural.Select execution, which evaluates +// the argument to determine whether the singular or plural message form should +// be selected. The calls to Render reports the partial results to the message +// package for further evaluation. +package catmsg + +import ( + "errors" + "fmt" + "strconv" + "strings" + "sync" + + "golang.org/x/text/language" +) + +// A Handle refers to a registered message type. +type Handle int + +// A Handler decodes and evaluates data compiled by a Message and sends the +// result to the Decoder. The output may depend on the value of the substitution +// arguments, accessible by the Decoder's Arg method. The Handler returns false +// if there is no translation for the given substitution arguments. +type Handler func(d *Decoder) bool + +// Register records the existence of a message type and returns a Handle that +// can be used in the Encoder's EncodeMessageType method to create such +// messages. The prefix of the name should be the package path followed by +// an optional disambiguating string. +// Register will panic if a handle for the same name was already registered. +func Register(name string, handler Handler) Handle { + mutex.Lock() + defer mutex.Unlock() + + if _, ok := names[name]; ok { + panic(fmt.Errorf("catmsg: handler for %q already exists", name)) + } + h := Handle(len(handlers)) + names[name] = h + handlers = append(handlers, handler) + return h +} + +// These handlers require fixed positions in the handlers slice. +const ( + msgVars Handle = iota + msgFirst + msgRaw + msgString + msgAffix + // Leave some arbitrary room for future expansion: 20 should suffice. + numInternal = 20 +) + +const prefix = "golang.org/x/text/internal/catmsg." + +var ( + // TODO: find a more stable way to link handles to message types. + mutex sync.Mutex + names = map[string]Handle{ + prefix + "Vars": msgVars, + prefix + "First": msgFirst, + prefix + "Raw": msgRaw, + prefix + "String": msgString, + prefix + "Affix": msgAffix, + } + handlers = make([]Handler, numInternal) +) + +func init() { + // This handler is a message type wrapper that initializes a decoder + // with a variable block. This message type, if present, is always at the + // start of an encoded message. + handlers[msgVars] = func(d *Decoder) bool { + blockSize := int(d.DecodeUint()) + d.vars = d.data[:blockSize] + d.data = d.data[blockSize:] + return d.executeMessage() + } + + // First takes the first message in a sequence that results in a match for + // the given substitution arguments. + handlers[msgFirst] = func(d *Decoder) bool { + for !d.Done() { + if d.ExecuteMessage() { + return true + } + } + return false + } + + handlers[msgRaw] = func(d *Decoder) bool { + d.Render(d.data) + return true + } + + // A String message alternates between a string constant and a variable + // substitution. + handlers[msgString] = func(d *Decoder) bool { + for !d.Done() { + if str := d.DecodeString(); str != "" { + d.Render(str) + } + if d.Done() { + break + } + d.ExecuteSubstitution() + } + return true + } + + handlers[msgAffix] = func(d *Decoder) bool { + // TODO: use an alternative method for common cases. + prefix := d.DecodeString() + suffix := d.DecodeString() + if prefix != "" { + d.Render(prefix) + } + ret := d.ExecuteMessage() + if suffix != "" { + d.Render(suffix) + } + return ret + } +} + +var ( + // ErrIncomplete indicates a compiled message does not define translations + // for all possible argument values. If this message is returned, evaluating + // a message may result in the ErrNoMatch error. + ErrIncomplete = errors.New("catmsg: incomplete message; may not give result for all inputs") + + // ErrNoMatch indicates no translation message matched the given input + // parameters when evaluating a message. + ErrNoMatch = errors.New("catmsg: no translation for inputs") +) + +// A Message holds a collection of translations for the same phrase that may +// vary based on the values of substitution arguments. +type Message interface { + // Compile encodes the format string(s) of the message as a string for later + // evaluation. + // + // The first call Compile makes on the encoder must be EncodeMessageType. + // The handle passed to this call may either be a handle returned by + // Register to encode a single custom message, or HandleFirst followed by + // a sequence of calls to EncodeMessage. + // + // Compile must return ErrIncomplete if it is possible for evaluation to + // not match any translation for a given set of formatting parameters. + // For example, selecting a translation based on plural form may not yield + // a match if the form "Other" is not one of the selectors. + // + // Compile may return any other application-specific error. For backwards + // compatibility with package like fmt, which often do not do sanity + // checking of format strings ahead of time, Compile should still make an + // effort to have some sensible fallback in case of an error. + Compile(e *Encoder) error +} + +// Compile converts a Message to a data string that can be stored in a Catalog. +// The resulting string can subsequently be decoded by passing to the Execute +// method of a Decoder. +func Compile(tag language.Tag, macros Dictionary, m Message) (data string, err error) { + // TODO: pass macros so they can be used for validation. + v := &Encoder{inBody: true} // encoder for variables + v.root = v + e := &Encoder{root: v, parent: v, tag: tag} // encoder for messages + err = m.Compile(e) + // This package serves te message package, which in turn is meant to be a + // drop-in replacement for fmt. With the fmt package, format strings are + // evaluated lazily and errors are handled by substituting strings in the + // result, rather then returning an error. Dealing with multiple languages + // makes it more important to check errors ahead of time. We chose to be + // consistent and compatible and allow graceful degradation in case of + // errors. + buf := e.buf[stripPrefix(e.buf):] + if len(v.buf) > 0 { + // Prepend variable block. + b := make([]byte, 1+maxVarintBytes+len(v.buf)+len(buf)) + b[0] = byte(msgVars) + b = b[:1+encodeUint(b[1:], uint64(len(v.buf)))] + b = append(b, v.buf...) + b = append(b, buf...) + buf = b + } + if err == nil { + err = v.err + } + return string(buf), err +} + +// FirstOf is a message type that prints the first message in the sequence that +// resolves to a match for the given substitution arguments. +type FirstOf []Message + +// Compile implements Message. +func (s FirstOf) Compile(e *Encoder) error { + e.EncodeMessageType(msgFirst) + err := ErrIncomplete + for i, m := range s { + if err == nil { + return fmt.Errorf("catalog: message argument %d is complete and blocks subsequent messages", i-1) + } + err = e.EncodeMessage(m) + } + return err +} + +// Var defines a message that can be substituted for a placeholder of the same +// name. If an expression does not result in a string after evaluation, Name is +// used as the substitution. For example: +// +// Var{ +// Name: "minutes", +// Message: plural.Select(1, "one", "minute"), +// } +// +// will resolve to minute for singular and minutes for plural forms. +type Var struct { + Name string + Message Message +} + +var errIsVar = errors.New("catmsg: variable used as message") + +// Compile implements Message. +// +// Note that this method merely registers a variable; it does not create an +// encoded message. +func (v *Var) Compile(e *Encoder) error { + if err := e.addVar(v.Name, v.Message); err != nil { + return err + } + // Using a Var by itself is an error. If it is in a sequence followed by + // other messages referring to it, this error will be ignored. + return errIsVar +} + +// Raw is a message consisting of a single format string that is passed as is +// to the Renderer. +// +// Note that a Renderer may still do its own variable substitution. +type Raw string + +// Compile implements Message. +func (r Raw) Compile(e *Encoder) (err error) { + e.EncodeMessageType(msgRaw) + // Special case: raw strings don't have a size encoding and so don't use + // EncodeString. + e.buf = append(e.buf, r...) + return nil +} + +// String is a message consisting of a single format string which contains +// placeholders that may be substituted with variables. +// +// Variable substitutions are marked with placeholders and a variable name of +// the form ${name}. Any other substitutions such as Go templates or +// printf-style substitutions are left to be done by the Renderer. +// +// When evaluation a string interpolation, a Renderer will receive separate +// calls for each placeholder and interstitial string. For example, for the +// message: "%[1]v ${invites} %[2]v to ${their} party." The sequence of calls +// is: +// +// d.Render("%[1]v ") +// d.Arg(1) +// d.Render(resultOfInvites) +// d.Render(" %[2]v to ") +// d.Arg(2) +// d.Render(resultOfTheir) +// d.Render(" party.") +// +// where the messages for "invites" and "their" both use a plural.Select +// referring to the first argument. +// +// Strings may also invoke macros. Macros are essentially variables that can be +// reused. Macros may, for instance, be used to make selections between +// different conjugations of a verb. See the catalog package description for an +// overview of macros. +type String string + +// Compile implements Message. It parses the placeholder formats and returns +// any error. +func (s String) Compile(e *Encoder) (err error) { + msg := string(s) + const subStart = "${" + hasHeader := false + p := 0 + b := []byte{} + for { + i := strings.Index(msg[p:], subStart) + if i == -1 { + break + } + b = append(b, msg[p:p+i]...) + p += i + len(subStart) + if i = strings.IndexByte(msg[p:], '}'); i == -1 { + b = append(b, "$!(MISSINGBRACE)"...) + err = fmt.Errorf("catmsg: missing '}'") + p = len(msg) + break + } + name := strings.TrimSpace(msg[p : p+i]) + if q := strings.IndexByte(name, '('); q == -1 { + if !hasHeader { + hasHeader = true + e.EncodeMessageType(msgString) + } + e.EncodeString(string(b)) + e.EncodeSubstitution(name) + b = b[:0] + } else if j := strings.IndexByte(name[q:], ')'); j == -1 { + // TODO: what should the error be? + b = append(b, "$!(MISSINGPAREN)"...) + err = fmt.Errorf("catmsg: missing ')'") + } else if x, sErr := strconv.ParseUint(strings.TrimSpace(name[q+1:q+j]), 10, 32); sErr != nil { + // TODO: handle more than one argument + b = append(b, "$!(BADNUM)"...) + err = fmt.Errorf("catmsg: invalid number %q", strings.TrimSpace(name[q+1:q+j])) + } else { + if !hasHeader { + hasHeader = true + e.EncodeMessageType(msgString) + } + e.EncodeString(string(b)) + e.EncodeSubstitution(name[:q], int(x)) + b = b[:0] + } + p += i + 1 + } + b = append(b, msg[p:]...) + if !hasHeader { + // Simplify string to a raw string. + Raw(string(b)).Compile(e) + } else if len(b) > 0 { + e.EncodeString(string(b)) + } + return err +} + +// Affix is a message that adds a prefix and suffix to another message. +// This is mostly used add back whitespace to a translation that was stripped +// before sending it out. +type Affix struct { + Message Message + Prefix string + Suffix string +} + +// Compile implements Message. +func (a Affix) Compile(e *Encoder) (err error) { + // TODO: consider adding a special message type that just adds a single + // return. This is probably common enough to handle the majority of cases. + // Get some stats first, though. + e.EncodeMessageType(msgAffix) + e.EncodeString(a.Prefix) + e.EncodeString(a.Suffix) + e.EncodeMessage(a.Message) + return nil +} diff --git a/vendor/golang.org/x/text/internal/catmsg/codec.go b/vendor/golang.org/x/text/internal/catmsg/codec.go new file mode 100644 index 000000000..547802b0f --- /dev/null +++ b/vendor/golang.org/x/text/internal/catmsg/codec.go @@ -0,0 +1,407 @@ +// 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 catmsg + +import ( + "errors" + "fmt" + + "golang.org/x/text/language" +) + +// A Renderer renders a Message. +type Renderer interface { + // Render renders the given string. The given string may be interpreted as a + // format string, such as the one used by the fmt package or a template. + Render(s string) + + // Arg returns the i-th argument passed to format a message. This method + // should return nil if there is no such argument. Messages need access to + // arguments to allow selecting a message based on linguistic features of + // those arguments. + Arg(i int) interface{} +} + +// A Dictionary specifies a source of messages, including variables or macros. +type Dictionary interface { + // Lookup returns the message for the given key. It returns false for ok if + // such a message could not be found. + Lookup(key string) (data string, ok bool) + + // TODO: consider returning an interface, instead of a string. This will + // allow implementations to do their own message type decoding. +} + +// An Encoder serializes a Message to a string. +type Encoder struct { + // The root encoder is used for storing encoded variables. + root *Encoder + // The parent encoder provides the surrounding scopes for resolving variable + // names. + parent *Encoder + + tag language.Tag + + // buf holds the encoded message so far. After a message completes encoding, + // the contents of buf, prefixed by the encoded length, are flushed to the + // parent buffer. + buf []byte + + // vars is the lookup table of variables in the current scope. + vars []keyVal + + err error + inBody bool // if false next call must be EncodeMessageType +} + +type keyVal struct { + key string + offset int +} + +// Language reports the language for which the encoded message will be stored +// in the Catalog. +func (e *Encoder) Language() language.Tag { return e.tag } + +func (e *Encoder) setError(err error) { + if e.root.err == nil { + e.root.err = err + } +} + +// EncodeUint encodes x. +func (e *Encoder) EncodeUint(x uint64) { + e.checkInBody() + var buf [maxVarintBytes]byte + n := encodeUint(buf[:], x) + e.buf = append(e.buf, buf[:n]...) +} + +// EncodeString encodes s. +func (e *Encoder) EncodeString(s string) { + e.checkInBody() + e.EncodeUint(uint64(len(s))) + e.buf = append(e.buf, s...) +} + +// EncodeMessageType marks the current message to be of type h. +// +// It must be the first call of a Message's Compile method. +func (e *Encoder) EncodeMessageType(h Handle) { + if e.inBody { + panic("catmsg: EncodeMessageType not the first method called") + } + e.inBody = true + e.EncodeUint(uint64(h)) +} + +// EncodeMessage serializes the given message inline at the current position. +func (e *Encoder) EncodeMessage(m Message) error { + e = &Encoder{root: e.root, parent: e, tag: e.tag} + err := m.Compile(e) + if _, ok := m.(*Var); !ok { + e.flushTo(e.parent) + } + return err +} + +func (e *Encoder) checkInBody() { + if !e.inBody { + panic("catmsg: expected prior call to EncodeMessageType") + } +} + +// stripPrefix indicates the number of prefix bytes that must be stripped to +// turn a single-element sequence into a message that is just this single member +// without its size prefix. If the message can be stripped, b[1:n] contains the +// size prefix. +func stripPrefix(b []byte) (n int) { + if len(b) > 0 && Handle(b[0]) == msgFirst { + x, n, _ := decodeUint(b[1:]) + if 1+n+int(x) == len(b) { + return 1 + n + } + } + return 0 +} + +func (e *Encoder) flushTo(dst *Encoder) { + data := e.buf + p := stripPrefix(data) + if p > 0 { + data = data[1:] + } else { + // Prefix the size. + dst.EncodeUint(uint64(len(data))) + } + dst.buf = append(dst.buf, data...) +} + +func (e *Encoder) addVar(key string, m Message) error { + for _, v := range e.parent.vars { + if v.key == key { + err := fmt.Errorf("catmsg: duplicate variable %q", key) + e.setError(err) + return err + } + } + scope := e.parent + // If a variable message is Incomplete, and does not evaluate to a message + // during execution, we fall back to the variable name. We encode this by + // appending the variable name if the message reports it's incomplete. + + err := m.Compile(e) + if err != ErrIncomplete { + e.setError(err) + } + switch { + case len(e.buf) == 1 && Handle(e.buf[0]) == msgFirst: // empty sequence + e.buf = e.buf[:0] + e.inBody = false + fallthrough + case len(e.buf) == 0: + // Empty message. + if err := String(key).Compile(e); err != nil { + e.setError(err) + } + case err == ErrIncomplete: + if Handle(e.buf[0]) != msgFirst { + seq := &Encoder{root: e.root, parent: e} + seq.EncodeMessageType(msgFirst) + e.flushTo(seq) + e = seq + } + // e contains a sequence; append the fallback string. + e.EncodeMessage(String(key)) + } + + // Flush result to variable heap. + offset := len(e.root.buf) + e.flushTo(e.root) + e.buf = e.buf[:0] + + // Record variable offset in current scope. + scope.vars = append(scope.vars, keyVal{key: key, offset: offset}) + return err +} + +const ( + substituteVar = iota + substituteMacro + substituteError +) + +// EncodeSubstitution inserts a resolved reference to a variable or macro. +// +// This call must be matched with a call to ExecuteSubstitution at decoding +// time. +func (e *Encoder) EncodeSubstitution(name string, arguments ...int) { + if arity := len(arguments); arity > 0 { + // TODO: also resolve macros. + e.EncodeUint(substituteMacro) + e.EncodeString(name) + for _, a := range arguments { + e.EncodeUint(uint64(a)) + } + return + } + for scope := e; scope != nil; scope = scope.parent { + for _, v := range scope.vars { + if v.key != name { + continue + } + e.EncodeUint(substituteVar) // TODO: support arity > 0 + e.EncodeUint(uint64(v.offset)) + return + } + } + // TODO: refer to dictionary-wide scoped variables. + e.EncodeUint(substituteError) + e.EncodeString(name) + e.setError(fmt.Errorf("catmsg: unknown var %q", name)) +} + +// A Decoder deserializes and evaluates messages that are encoded by an encoder. +type Decoder struct { + tag language.Tag + dst Renderer + macros Dictionary + + err error + vars string + data string + + macroArg int // TODO: allow more than one argument +} + +// NewDecoder returns a new Decoder. +// +// Decoders are designed to be reused for multiple invocations of Execute. +// Only one goroutine may call Execute concurrently. +func NewDecoder(tag language.Tag, r Renderer, macros Dictionary) *Decoder { + return &Decoder{ + tag: tag, + dst: r, + macros: macros, + } +} + +func (d *Decoder) setError(err error) { + if d.err == nil { + d.err = err + } +} + +// Language returns the language in which the message is being rendered. +// +// The destination language may be a child language of the language used for +// encoding. For instance, a decoding language of "pt-PT" is consistent with an +// encoding language of "pt". +func (d *Decoder) Language() language.Tag { return d.tag } + +// Done reports whether there are more bytes to process in this message. +func (d *Decoder) Done() bool { return len(d.data) == 0 } + +// Render implements Renderer. +func (d *Decoder) Render(s string) { d.dst.Render(s) } + +// Arg implements Renderer. +// +// During evaluation of macros, the argument positions may be mapped to +// arguments that differ from the original call. +func (d *Decoder) Arg(i int) interface{} { + if d.macroArg != 0 { + if i != 1 { + panic("catmsg: only macros with single argument supported") + } + i = d.macroArg + } + return d.dst.Arg(i) +} + +// DecodeUint decodes a number that was encoded with EncodeUint and advances the +// position. +func (d *Decoder) DecodeUint() uint64 { + x, n, err := decodeUintString(d.data) + d.data = d.data[n:] + if err != nil { + d.setError(err) + } + return x +} + +// DecodeString decodes a string that was encoded with EncodeString and advances +// the position. +func (d *Decoder) DecodeString() string { + size := d.DecodeUint() + s := d.data[:size] + d.data = d.data[size:] + return s +} + +// SkipMessage skips the message at the current location and advances the +// position. +func (d *Decoder) SkipMessage() { + n := int(d.DecodeUint()) + d.data = d.data[n:] +} + +// Execute decodes and evaluates msg. +// +// Only one goroutine may call execute. +func (d *Decoder) Execute(msg string) error { + d.err = nil + if !d.execute(msg) { + return ErrNoMatch + } + return d.err +} + +func (d *Decoder) execute(msg string) bool { + saved := d.data + d.data = msg + ok := d.executeMessage() + d.data = saved + return ok +} + +// executeMessageFromData is like execute, but also decodes a leading message +// size and clips the given string accordingly. +// +// It reports the number of bytes consumed and whether a message was selected. +func (d *Decoder) executeMessageFromData(s string) (n int, ok bool) { + saved := d.data + d.data = s + size := int(d.DecodeUint()) + n = len(s) - len(d.data) + // Sanitize the setting. This allows skipping a size argument for + // RawString and method Done. + d.data = d.data[:size] + ok = d.executeMessage() + n += size - len(d.data) + d.data = saved + return n, ok +} + +var errUnknownHandler = errors.New("catmsg: string contains unsupported handler") + +// executeMessage reads the handle id, initializes the decoder and executes the +// message. It is assumed that all of d.data[d.p:] is the single message. +func (d *Decoder) executeMessage() bool { + if d.Done() { + // We interpret no data as a valid empty message. + return true + } + handle := d.DecodeUint() + + var fn Handler + mutex.Lock() + if int(handle) < len(handlers) { + fn = handlers[handle] + } + mutex.Unlock() + if fn == nil { + d.setError(errUnknownHandler) + d.execute(fmt.Sprintf("\x02$!(UNKNOWNMSGHANDLER=%#x)", handle)) + return true + } + return fn(d) +} + +// ExecuteMessage decodes and executes the message at the current position. +func (d *Decoder) ExecuteMessage() bool { + n, ok := d.executeMessageFromData(d.data) + d.data = d.data[n:] + return ok +} + +// ExecuteSubstitution executes the message corresponding to the substitution +// as encoded by EncodeSubstitution. +func (d *Decoder) ExecuteSubstitution() { + switch x := d.DecodeUint(); x { + case substituteVar: + offset := d.DecodeUint() + d.executeMessageFromData(d.vars[offset:]) + case substituteMacro: + name := d.DecodeString() + data, ok := d.macros.Lookup(name) + old := d.macroArg + // TODO: support macros of arity other than 1. + d.macroArg = int(d.DecodeUint()) + switch { + case !ok: + // TODO: detect this at creation time. + d.setError(fmt.Errorf("catmsg: undefined macro %q", name)) + fallthrough + case !d.execute(data): + d.dst.Render(name) // fall back to macro name. + } + d.macroArg = old + case substituteError: + d.dst.Render(d.DecodeString()) + default: + panic("catmsg: unreachable") + } +} diff --git a/vendor/golang.org/x/text/internal/catmsg/varint.go b/vendor/golang.org/x/text/internal/catmsg/varint.go new file mode 100644 index 000000000..a2cee2cf5 --- /dev/null +++ b/vendor/golang.org/x/text/internal/catmsg/varint.go @@ -0,0 +1,62 @@ +// 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 catmsg + +// This file implements varint encoding analogous to the one in encoding/binary. +// We need a string version of this function, so we add that here and then add +// the rest for consistency. + +import "errors" + +var ( + errIllegalVarint = errors.New("catmsg: illegal varint") + errVarintTooLarge = errors.New("catmsg: varint too large for uint64") +) + +const maxVarintBytes = 10 // maximum length of a varint + +// encodeUint encodes x as a variable-sized integer into buf and returns the +// number of bytes written. buf must be at least maxVarintBytes long +func encodeUint(buf []byte, x uint64) (n int) { + for ; x > 127; n++ { + buf[n] = 0x80 | uint8(x&0x7F) + x >>= 7 + } + buf[n] = uint8(x) + n++ + return n +} + +func decodeUintString(s string) (x uint64, size int, err error) { + i := 0 + for shift := uint(0); shift < 64; shift += 7 { + if i >= len(s) { + return 0, i, errIllegalVarint + } + b := uint64(s[i]) + i++ + x |= (b & 0x7F) << shift + if b&0x80 == 0 { + return x, i, nil + } + } + return 0, i, errVarintTooLarge +} + +func decodeUint(b []byte) (x uint64, size int, err error) { + i := 0 + for shift := uint(0); shift < 64; shift += 7 { + if i >= len(b) { + return 0, i, errIllegalVarint + } + c := uint64(b[i]) + i++ + x |= (c & 0x7F) << shift + if c&0x80 == 0 { + return x, i, nil + } + } + return 0, i, errVarintTooLarge +} diff --git a/vendor/golang.org/x/text/internal/format/format.go b/vendor/golang.org/x/text/internal/format/format.go new file mode 100644 index 000000000..ee1c57a3c --- /dev/null +++ b/vendor/golang.org/x/text/internal/format/format.go @@ -0,0 +1,41 @@ +// 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 format contains types for defining language-specific formatting of +// values. +// +// This package is internal now, but will eventually be exposed after the API +// settles. +package format // import "golang.org/x/text/internal/format" + +import ( + "fmt" + + "golang.org/x/text/language" +) + +// State represents the printer state passed to custom formatters. It provides +// access to the fmt.State interface and the sentence and language-related +// context. +type State interface { + fmt.State + + // Language reports the requested language in which to render a message. + Language() language.Tag + + // TODO: consider this and removing rune from the Format method in the + // Formatter interface. + // + // Verb returns the format variant to render, analogous to the types used + // in fmt. Use 'v' for the default or only variant. + // Verb() rune + + // TODO: more info: + // - sentence context such as linguistic features passed by the translator. +} + +// Formatter is analogous to fmt.Formatter. +type Formatter interface { + Format(state State, verb rune) +} diff --git a/vendor/golang.org/x/text/internal/format/parser.go b/vendor/golang.org/x/text/internal/format/parser.go new file mode 100644 index 000000000..855aed71d --- /dev/null +++ b/vendor/golang.org/x/text/internal/format/parser.go @@ -0,0 +1,358 @@ +// 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 format + +import ( + "reflect" + "unicode/utf8" +) + +// A Parser parses a format string. The result from the parse are set in the +// struct fields. +type Parser struct { + Verb rune + + WidthPresent bool + PrecPresent bool + Minus bool + Plus bool + Sharp bool + Space bool + Zero bool + + // For the formats %+v %#v, we set the plusV/sharpV flags + // and clear the plus/sharp flags since %+v and %#v are in effect + // different, flagless formats set at the top level. + PlusV bool + SharpV bool + + HasIndex bool + + Width int + Prec int // precision + + // retain arguments across calls. + Args []interface{} + // retain current argument number across calls + ArgNum int + + // reordered records whether the format string used argument reordering. + Reordered bool + // goodArgNum records whether the most recent reordering directive was valid. + goodArgNum bool + + // position info + format string + startPos int + endPos int + Status Status +} + +// Reset initializes a parser to scan format strings for the given args. +func (p *Parser) Reset(args []interface{}) { + p.Args = args + p.ArgNum = 0 + p.startPos = 0 + p.Reordered = false +} + +// Text returns the part of the format string that was parsed by the last call +// to Scan. It returns the original substitution clause if the current scan +// parsed a substitution. +func (p *Parser) Text() string { return p.format[p.startPos:p.endPos] } + +// SetFormat sets a new format string to parse. It does not reset the argument +// count. +func (p *Parser) SetFormat(format string) { + p.format = format + p.startPos = 0 + p.endPos = 0 +} + +// Status indicates the result type of a call to Scan. +type Status int + +const ( + StatusText Status = iota + StatusSubstitution + StatusBadWidthSubstitution + StatusBadPrecSubstitution + StatusNoVerb + StatusBadArgNum + StatusMissingArg +) + +// ClearFlags reset the parser to default behavior. +func (p *Parser) ClearFlags() { + p.WidthPresent = false + p.PrecPresent = false + p.Minus = false + p.Plus = false + p.Sharp = false + p.Space = false + p.Zero = false + + p.PlusV = false + p.SharpV = false + + p.HasIndex = false +} + +// Scan scans the next part of the format string and sets the status to +// indicate whether it scanned a string literal, substitution or error. +func (p *Parser) Scan() bool { + p.Status = StatusText + format := p.format + end := len(format) + if p.endPos >= end { + return false + } + afterIndex := false // previous item in format was an index like [3]. + + p.startPos = p.endPos + p.goodArgNum = true + i := p.startPos + for i < end && format[i] != '%' { + i++ + } + if i > p.startPos { + p.endPos = i + return true + } + // Process one verb + i++ + + p.Status = StatusSubstitution + + // Do we have flags? + p.ClearFlags() + +simpleFormat: + for ; i < end; i++ { + c := p.format[i] + switch c { + case '#': + p.Sharp = true + case '0': + p.Zero = !p.Minus // Only allow zero padding to the left. + case '+': + p.Plus = true + case '-': + p.Minus = true + p.Zero = false // Do not pad with zeros to the right. + case ' ': + p.Space = true + default: + // Fast path for common case of ascii lower case simple verbs + // without precision or width or argument indices. + if 'a' <= c && c <= 'z' && p.ArgNum < len(p.Args) { + if c == 'v' { + // Go syntax + p.SharpV = p.Sharp + p.Sharp = false + // Struct-field syntax + p.PlusV = p.Plus + p.Plus = false + } + p.Verb = rune(c) + p.ArgNum++ + p.endPos = i + 1 + return true + } + // Format is more complex than simple flags and a verb or is malformed. + break simpleFormat + } + } + + // Do we have an explicit argument index? + i, afterIndex = p.updateArgNumber(format, i) + + // Do we have width? + if i < end && format[i] == '*' { + i++ + p.Width, p.WidthPresent = p.intFromArg() + + if !p.WidthPresent { + p.Status = StatusBadWidthSubstitution + } + + // We have a negative width, so take its value and ensure + // that the minus flag is set + if p.Width < 0 { + p.Width = -p.Width + p.Minus = true + p.Zero = false // Do not pad with zeros to the right. + } + afterIndex = false + } else { + p.Width, p.WidthPresent, i = parsenum(format, i, end) + if afterIndex && p.WidthPresent { // "%[3]2d" + p.goodArgNum = false + } + } + + // Do we have precision? + if i+1 < end && format[i] == '.' { + i++ + if afterIndex { // "%[3].2d" + p.goodArgNum = false + } + i, afterIndex = p.updateArgNumber(format, i) + if i < end && format[i] == '*' { + i++ + p.Prec, p.PrecPresent = p.intFromArg() + // Negative precision arguments don't make sense + if p.Prec < 0 { + p.Prec = 0 + p.PrecPresent = false + } + if !p.PrecPresent { + p.Status = StatusBadPrecSubstitution + } + afterIndex = false + } else { + p.Prec, p.PrecPresent, i = parsenum(format, i, end) + if !p.PrecPresent { + p.Prec = 0 + p.PrecPresent = true + } + } + } + + if !afterIndex { + i, afterIndex = p.updateArgNumber(format, i) + } + p.HasIndex = afterIndex + + if i >= end { + p.endPos = i + p.Status = StatusNoVerb + return true + } + + verb, w := utf8.DecodeRuneInString(format[i:]) + p.endPos = i + w + p.Verb = verb + + switch { + case verb == '%': // Percent does not absorb operands and ignores f.wid and f.prec. + p.startPos = p.endPos - 1 + p.Status = StatusText + case !p.goodArgNum: + p.Status = StatusBadArgNum + case p.ArgNum >= len(p.Args): // No argument left over to print for the current verb. + p.Status = StatusMissingArg + p.ArgNum++ + case verb == 'v': + // Go syntax + p.SharpV = p.Sharp + p.Sharp = false + // Struct-field syntax + p.PlusV = p.Plus + p.Plus = false + fallthrough + default: + p.ArgNum++ + } + return true +} + +// intFromArg gets the ArgNumth element of Args. On return, isInt reports +// whether the argument has integer type. +func (p *Parser) intFromArg() (num int, isInt bool) { + if p.ArgNum < len(p.Args) { + arg := p.Args[p.ArgNum] + num, isInt = arg.(int) // Almost always OK. + if !isInt { + // Work harder. + switch v := reflect.ValueOf(arg); v.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + n := v.Int() + if int64(int(n)) == n { + num = int(n) + isInt = true + } + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + n := v.Uint() + if int64(n) >= 0 && uint64(int(n)) == n { + num = int(n) + isInt = true + } + default: + // Already 0, false. + } + } + p.ArgNum++ + if tooLarge(num) { + num = 0 + isInt = false + } + } + return +} + +// parseArgNumber returns the value of the bracketed number, minus 1 +// (explicit argument numbers are one-indexed but we want zero-indexed). +// The opening bracket is known to be present at format[0]. +// The returned values are the index, the number of bytes to consume +// up to the closing paren, if present, and whether the number parsed +// ok. The bytes to consume will be 1 if no closing paren is present. +func parseArgNumber(format string) (index int, wid int, ok bool) { + // There must be at least 3 bytes: [n]. + if len(format) < 3 { + return 0, 1, false + } + + // Find closing bracket. + for i := 1; i < len(format); i++ { + if format[i] == ']' { + width, ok, newi := parsenum(format, 1, i) + if !ok || newi != i { + return 0, i + 1, false + } + return width - 1, i + 1, true // arg numbers are one-indexed and skip paren. + } + } + return 0, 1, false +} + +// updateArgNumber returns the next argument to evaluate, which is either the value of the passed-in +// argNum or the value of the bracketed integer that begins format[i:]. It also returns +// the new value of i, that is, the index of the next byte of the format to process. +func (p *Parser) updateArgNumber(format string, i int) (newi int, found bool) { + if len(format) <= i || format[i] != '[' { + return i, false + } + p.Reordered = true + index, wid, ok := parseArgNumber(format[i:]) + if ok && 0 <= index && index < len(p.Args) { + p.ArgNum = index + return i + wid, true + } + p.goodArgNum = false + return i + wid, ok +} + +// tooLarge reports whether the magnitude of the integer is +// too large to be used as a formatting width or precision. +func tooLarge(x int) bool { + const max int = 1e6 + return x > max || x < -max +} + +// parsenum converts ASCII to integer. num is 0 (and isnum is false) if no number present. +func parsenum(s string, start, end int) (num int, isnum bool, newi int) { + if start >= end { + return 0, false, end + } + for newi = start; newi < end && '0' <= s[newi] && s[newi] <= '9'; newi++ { + if tooLarge(num) { + return 0, false, end // Overflow; crazy long number most likely. + } + num = num*10 + int(s[newi]-'0') + isnum = true + } + return +} diff --git a/vendor/golang.org/x/text/internal/internal.go b/vendor/golang.org/x/text/internal/internal.go new file mode 100644 index 000000000..3cddbbdda --- /dev/null +++ b/vendor/golang.org/x/text/internal/internal.go @@ -0,0 +1,49 @@ +// 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 internal contains non-exported functionality that are used by +// packages in the text repository. +package internal // import "golang.org/x/text/internal" + +import ( + "sort" + + "golang.org/x/text/language" +) + +// SortTags sorts tags in place. +func SortTags(tags []language.Tag) { + sort.Sort(sorter(tags)) +} + +type sorter []language.Tag + +func (s sorter) Len() int { + return len(s) +} + +func (s sorter) Swap(i, j int) { + s[i], s[j] = s[j], s[i] +} + +func (s sorter) Less(i, j int) bool { + return s[i].String() < s[j].String() +} + +// UniqueTags sorts and filters duplicate tags in place and returns a slice with +// only unique tags. +func UniqueTags(tags []language.Tag) []language.Tag { + if len(tags) <= 1 { + return tags + } + SortTags(tags) + k := 0 + for i := 1; i < len(tags); i++ { + if tags[k].String() < tags[i].String() { + k++ + tags[k] = tags[i] + } + } + return tags[:k+1] +} diff --git a/vendor/golang.org/x/text/internal/language/common.go b/vendor/golang.org/x/text/internal/language/common.go new file mode 100644 index 000000000..cdfdb7497 --- /dev/null +++ b/vendor/golang.org/x/text/internal/language/common.go @@ -0,0 +1,16 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +package language + +// This file contains code common to the maketables.go and the package code. + +// AliasType is the type of an alias in AliasMap. +type AliasType int8 + +const ( + Deprecated AliasType = iota + Macro + Legacy + + AliasTypeUnknown AliasType = -1 +) diff --git a/vendor/golang.org/x/text/internal/language/compact.go b/vendor/golang.org/x/text/internal/language/compact.go new file mode 100644 index 000000000..46a001507 --- /dev/null +++ b/vendor/golang.org/x/text/internal/language/compact.go @@ -0,0 +1,29 @@ +// Copyright 2018 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 language + +// CompactCoreInfo is a compact integer with the three core tags encoded. +type CompactCoreInfo uint32 + +// GetCompactCore generates a uint32 value that is guaranteed to be unique for +// different language, region, and script values. +func GetCompactCore(t Tag) (cci CompactCoreInfo, ok bool) { + if t.LangID > langNoIndexOffset { + return 0, false + } + cci |= CompactCoreInfo(t.LangID) << (8 + 12) + cci |= CompactCoreInfo(t.ScriptID) << 12 + cci |= CompactCoreInfo(t.RegionID) + return cci, true +} + +// Tag generates a tag from c. +func (c CompactCoreInfo) Tag() Tag { + return Tag{ + LangID: Language(c >> 20), + RegionID: Region(c & 0x3ff), + ScriptID: Script(c>>12) & 0xff, + } +} diff --git a/vendor/golang.org/x/text/internal/language/compact/compact.go b/vendor/golang.org/x/text/internal/language/compact/compact.go new file mode 100644 index 000000000..1b36935ef --- /dev/null +++ b/vendor/golang.org/x/text/internal/language/compact/compact.go @@ -0,0 +1,61 @@ +// Copyright 2018 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 compact defines a compact representation of language tags. +// +// Common language tags (at least all for which locale information is defined +// in CLDR) are assigned a unique index. Each Tag is associated with such an +// ID for selecting language-related resources (such as translations) as well +// as one for selecting regional defaults (currency, number formatting, etc.) +// +// It may want to export this functionality at some point, but at this point +// this is only available for use within x/text. +package compact // import "golang.org/x/text/internal/language/compact" + +import ( + "sort" + "strings" + + "golang.org/x/text/internal/language" +) + +// ID is an integer identifying a single tag. +type ID uint16 + +func getCoreIndex(t language.Tag) (id ID, ok bool) { + cci, ok := language.GetCompactCore(t) + if !ok { + return 0, false + } + i := sort.Search(len(coreTags), func(i int) bool { + return cci <= coreTags[i] + }) + if i == len(coreTags) || coreTags[i] != cci { + return 0, false + } + return ID(i), true +} + +// Parent returns the ID of the parent or the root ID if id is already the root. +func (id ID) Parent() ID { + return parents[id] +} + +// Tag converts id to an internal language Tag. +func (id ID) Tag() language.Tag { + if int(id) >= len(coreTags) { + return specialTags[int(id)-len(coreTags)] + } + return coreTags[id].Tag() +} + +var specialTags []language.Tag + +func init() { + tags := strings.Split(specialTagsStr, " ") + specialTags = make([]language.Tag, len(tags)) + for i, t := range tags { + specialTags[i] = language.MustParse(t) + } +} diff --git a/vendor/golang.org/x/text/internal/language/compact/language.go b/vendor/golang.org/x/text/internal/language/compact/language.go new file mode 100644 index 000000000..8c1b6666f --- /dev/null +++ b/vendor/golang.org/x/text/internal/language/compact/language.go @@ -0,0 +1,260 @@ +// Copyright 2013 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_index.go -output tables.go +//go:generate go run gen_parents.go + +package compact + +// TODO: Remove above NOTE after: +// - verifying that tables are dropped correctly (most notably matcher tables). + +import ( + "strings" + + "golang.org/x/text/internal/language" +) + +// Tag represents a BCP 47 language tag. It is used to specify an instance of a +// specific language or locale. All language tag values are guaranteed to be +// well-formed. +type Tag struct { + // NOTE: exported tags will become part of the public API. + language ID + locale ID + full fullTag // always a language.Tag for now. +} + +const _und = 0 + +type fullTag interface { + IsRoot() bool + Parent() language.Tag +} + +// Make a compact Tag from a fully specified internal language Tag. +func Make(t language.Tag) (tag Tag) { + if region := t.TypeForKey("rg"); len(region) == 6 && region[2:] == "zzzz" { + if r, err := language.ParseRegion(region[:2]); err == nil { + tFull := t + t, _ = t.SetTypeForKey("rg", "") + // TODO: should we not consider "va" for the language tag? + var exact1, exact2 bool + tag.language, exact1 = FromTag(t) + t.RegionID = r + tag.locale, exact2 = FromTag(t) + if !exact1 || !exact2 { + tag.full = tFull + } + return tag + } + } + lang, ok := FromTag(t) + tag.language = lang + tag.locale = lang + if !ok { + tag.full = t + } + return tag +} + +// Tag returns an internal language Tag version of this tag. +func (t Tag) Tag() language.Tag { + if t.full != nil { + return t.full.(language.Tag) + } + tag := t.language.Tag() + if t.language != t.locale { + loc := t.locale.Tag() + tag, _ = tag.SetTypeForKey("rg", strings.ToLower(loc.RegionID.String())+"zzzz") + } + return tag +} + +// IsCompact reports whether this tag is fully defined in terms of ID. +func (t *Tag) IsCompact() bool { + return t.full == nil +} + +// MayHaveVariants reports whether a tag may have variants. If it returns false +// it is guaranteed the tag does not have variants. +func (t Tag) MayHaveVariants() bool { + return t.full != nil || int(t.language) >= len(coreTags) +} + +// MayHaveExtensions reports whether a tag may have extensions. If it returns +// false it is guaranteed the tag does not have them. +func (t Tag) MayHaveExtensions() bool { + return t.full != nil || + int(t.language) >= len(coreTags) || + t.language != t.locale +} + +// IsRoot returns true if t is equal to language "und". +func (t Tag) IsRoot() bool { + if t.full != nil { + return t.full.IsRoot() + } + return t.language == _und +} + +// Parent returns the CLDR parent of t. In CLDR, missing fields in data for a +// specific language are substituted with fields from the parent language. +// The parent for a language may change for newer versions of CLDR. +func (t Tag) Parent() Tag { + if t.full != nil { + return Make(t.full.Parent()) + } + if t.language != t.locale { + // Simulate stripping -u-rg-xxxxxx + return Tag{language: t.language, locale: t.language} + } + // TODO: use parent lookup table once cycle from internal package is + // removed. Probably by internalizing the table and declaring this fast + // enough. + // lang := compactID(internal.Parent(uint16(t.language))) + lang, _ := FromTag(t.language.Tag().Parent()) + return Tag{language: lang, locale: lang} +} + +// nextToken returns token t and the rest of the string. +func nextToken(s string) (t, tail string) { + p := strings.Index(s[1:], "-") + if p == -1 { + return s[1:], "" + } + p++ + return s[1:p], s[p:] +} + +// LanguageID returns an index, where 0 <= index < NumCompactTags, for tags +// for which data exists in the text repository.The index will change over time +// and should not be stored in persistent storage. If t does not match a compact +// index, exact will be false and the compact index will be returned for the +// first match after repeatedly taking the Parent of t. +func LanguageID(t Tag) (id ID, exact bool) { + return t.language, t.full == nil +} + +// RegionalID returns the ID for the regional variant of this tag. This index is +// used to indicate region-specific overrides, such as default currency, default +// calendar and week data, default time cycle, and default measurement system +// and unit preferences. +// +// For instance, the tag en-GB-u-rg-uszzzz specifies British English with US +// settings for currency, number formatting, etc. The CompactIndex for this tag +// will be that for en-GB, while the RegionalID will be the one corresponding to +// en-US. +func RegionalID(t Tag) (id ID, exact bool) { + return t.locale, t.full == nil +} + +// LanguageTag returns t stripped of regional variant indicators. +// +// At the moment this means it is stripped of a regional and variant subtag "rg" +// and "va" in the "u" extension. +func (t Tag) LanguageTag() Tag { + if t.full == nil { + return Tag{language: t.language, locale: t.language} + } + tt := t.Tag() + tt.SetTypeForKey("rg", "") + tt.SetTypeForKey("va", "") + return Make(tt) +} + +// RegionalTag returns the regional variant of the tag. +// +// At the moment this means that the region is set from the regional subtag +// "rg" in the "u" extension. +func (t Tag) RegionalTag() Tag { + rt := Tag{language: t.locale, locale: t.locale} + if t.full == nil { + return rt + } + b := language.Builder{} + tag := t.Tag() + // tag, _ = tag.SetTypeForKey("rg", "") + b.SetTag(t.locale.Tag()) + if v := tag.Variants(); v != "" { + for _, v := range strings.Split(v, "-") { + b.AddVariant(v) + } + } + for _, e := range tag.Extensions() { + b.AddExt(e) + } + return t +} + +// FromTag reports closest matching ID for an internal language Tag. +func FromTag(t language.Tag) (id ID, exact bool) { + // TODO: perhaps give more frequent tags a lower index. + // TODO: we could make the indexes stable. This will excluded some + // possibilities for optimization, so don't do this quite yet. + exact = true + + b, s, r := t.Raw() + if t.HasString() { + if t.IsPrivateUse() { + // We have no entries for user-defined tags. + return 0, false + } + hasExtra := false + if t.HasVariants() { + if t.HasExtensions() { + build := language.Builder{} + build.SetTag(language.Tag{LangID: b, ScriptID: s, RegionID: r}) + build.AddVariant(t.Variants()) + exact = false + t = build.Make() + } + hasExtra = true + } else if _, ok := t.Extension('u'); ok { + // TODO: va may mean something else. Consider not considering it. + // Strip all but the 'va' entry. + old := t + variant := t.TypeForKey("va") + t = language.Tag{LangID: b, ScriptID: s, RegionID: r} + if variant != "" { + t, _ = t.SetTypeForKey("va", variant) + hasExtra = true + } + exact = old == t + } else { + exact = false + } + if hasExtra { + // We have some variants. + for i, s := range specialTags { + if s == t { + return ID(i + len(coreTags)), exact + } + } + exact = false + } + } + if x, ok := getCoreIndex(t); ok { + return x, exact + } + exact = false + if r != 0 && s == 0 { + // Deal with cases where an extra script is inserted for the region. + t, _ := t.Maximize() + if x, ok := getCoreIndex(t); ok { + return x, exact + } + } + for t = t.Parent(); t != root; t = t.Parent() { + // No variants specified: just compare core components. + // The key has the form lllssrrr, where l, s, and r are nibbles for + // respectively the langID, scriptID, and regionID. + if x, ok := getCoreIndex(t); ok { + return x, exact + } + } + return 0, exact +} + +var root = language.Tag{} diff --git a/vendor/golang.org/x/text/internal/language/compact/parents.go b/vendor/golang.org/x/text/internal/language/compact/parents.go new file mode 100644 index 000000000..8d810723c --- /dev/null +++ b/vendor/golang.org/x/text/internal/language/compact/parents.go @@ -0,0 +1,120 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +package compact + +// parents maps a compact index of a tag to the compact index of the parent of +// this tag. +var parents = []ID{ // 775 elements + // Entry 0 - 3F + 0x0000, 0x0000, 0x0001, 0x0001, 0x0000, 0x0004, 0x0000, 0x0006, + 0x0000, 0x0008, 0x0000, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, + 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, + 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, + 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x0000, + 0x0000, 0x0028, 0x0000, 0x002a, 0x0000, 0x002c, 0x0000, 0x0000, + 0x002f, 0x002e, 0x002e, 0x0000, 0x0033, 0x0000, 0x0035, 0x0000, + 0x0037, 0x0000, 0x0039, 0x0000, 0x003b, 0x0000, 0x0000, 0x003e, + // Entry 40 - 7F + 0x0000, 0x0040, 0x0040, 0x0000, 0x0043, 0x0043, 0x0000, 0x0046, + 0x0000, 0x0048, 0x0000, 0x0000, 0x004b, 0x004a, 0x004a, 0x0000, + 0x004f, 0x004f, 0x004f, 0x004f, 0x0000, 0x0054, 0x0054, 0x0000, + 0x0057, 0x0000, 0x0059, 0x0000, 0x005b, 0x0000, 0x005d, 0x005d, + 0x0000, 0x0060, 0x0000, 0x0062, 0x0000, 0x0064, 0x0000, 0x0066, + 0x0066, 0x0000, 0x0069, 0x0000, 0x006b, 0x006b, 0x006b, 0x006b, + 0x006b, 0x006b, 0x006b, 0x0000, 0x0073, 0x0000, 0x0075, 0x0000, + 0x0077, 0x0000, 0x0000, 0x007a, 0x0000, 0x007c, 0x0000, 0x007e, + // Entry 80 - BF + 0x0000, 0x0080, 0x0080, 0x0000, 0x0083, 0x0083, 0x0000, 0x0086, + 0x0087, 0x0087, 0x0087, 0x0086, 0x0088, 0x0087, 0x0087, 0x0087, + 0x0086, 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, 0x0088, + 0x0087, 0x0087, 0x0087, 0x0087, 0x0088, 0x0087, 0x0088, 0x0087, + 0x0087, 0x0088, 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, + 0x0087, 0x0087, 0x0087, 0x0086, 0x0087, 0x0087, 0x0087, 0x0087, + 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, + 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, 0x0086, 0x0087, 0x0086, + // Entry C0 - FF + 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, + 0x0088, 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, + 0x0086, 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, 0x0088, 0x0087, + 0x0087, 0x0088, 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, + 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, 0x0086, 0x0086, 0x0087, + 0x0087, 0x0086, 0x0087, 0x0087, 0x0087, 0x0087, 0x0087, 0x0000, + 0x00ef, 0x0000, 0x00f1, 0x00f2, 0x00f2, 0x00f2, 0x00f2, 0x00f2, + 0x00f2, 0x00f2, 0x00f2, 0x00f2, 0x00f1, 0x00f2, 0x00f1, 0x00f1, + // Entry 100 - 13F + 0x00f2, 0x00f2, 0x00f1, 0x00f2, 0x00f2, 0x00f2, 0x00f2, 0x00f1, + 0x00f2, 0x00f2, 0x00f2, 0x00f2, 0x00f2, 0x00f2, 0x0000, 0x010e, + 0x0000, 0x0110, 0x0000, 0x0112, 0x0000, 0x0114, 0x0114, 0x0000, + 0x0117, 0x0117, 0x0117, 0x0117, 0x0000, 0x011c, 0x0000, 0x011e, + 0x0000, 0x0120, 0x0120, 0x0000, 0x0123, 0x0123, 0x0123, 0x0123, + 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, + 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, + 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, + // Entry 140 - 17F + 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, + 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, 0x0123, + 0x0123, 0x0123, 0x0000, 0x0152, 0x0000, 0x0154, 0x0000, 0x0156, + 0x0000, 0x0158, 0x0000, 0x015a, 0x0000, 0x015c, 0x015c, 0x015c, + 0x0000, 0x0160, 0x0000, 0x0000, 0x0163, 0x0000, 0x0165, 0x0000, + 0x0167, 0x0167, 0x0167, 0x0000, 0x016b, 0x0000, 0x016d, 0x0000, + 0x016f, 0x0000, 0x0171, 0x0171, 0x0000, 0x0174, 0x0000, 0x0176, + 0x0000, 0x0178, 0x0000, 0x017a, 0x0000, 0x017c, 0x0000, 0x017e, + // Entry 180 - 1BF + 0x0000, 0x0000, 0x0000, 0x0182, 0x0000, 0x0184, 0x0184, 0x0184, + 0x0184, 0x0000, 0x0000, 0x0000, 0x018b, 0x0000, 0x0000, 0x018e, + 0x0000, 0x0000, 0x0191, 0x0000, 0x0000, 0x0000, 0x0195, 0x0000, + 0x0197, 0x0000, 0x0000, 0x019a, 0x0000, 0x0000, 0x019d, 0x0000, + 0x019f, 0x0000, 0x01a1, 0x0000, 0x01a3, 0x0000, 0x01a5, 0x0000, + 0x01a7, 0x0000, 0x01a9, 0x0000, 0x01ab, 0x0000, 0x01ad, 0x0000, + 0x01af, 0x0000, 0x01b1, 0x01b1, 0x0000, 0x01b4, 0x0000, 0x01b6, + 0x0000, 0x01b8, 0x0000, 0x01ba, 0x0000, 0x01bc, 0x0000, 0x0000, + // Entry 1C0 - 1FF + 0x01bf, 0x0000, 0x01c1, 0x0000, 0x01c3, 0x0000, 0x01c5, 0x0000, + 0x01c7, 0x0000, 0x01c9, 0x0000, 0x01cb, 0x01cb, 0x01cb, 0x01cb, + 0x0000, 0x01d0, 0x0000, 0x01d2, 0x01d2, 0x0000, 0x01d5, 0x0000, + 0x01d7, 0x0000, 0x01d9, 0x0000, 0x01db, 0x0000, 0x01dd, 0x0000, + 0x01df, 0x01df, 0x0000, 0x01e2, 0x0000, 0x01e4, 0x0000, 0x01e6, + 0x0000, 0x01e8, 0x0000, 0x01ea, 0x0000, 0x01ec, 0x0000, 0x01ee, + 0x0000, 0x01f0, 0x0000, 0x0000, 0x01f3, 0x0000, 0x01f5, 0x01f5, + 0x01f5, 0x0000, 0x01f9, 0x0000, 0x01fb, 0x0000, 0x01fd, 0x0000, + // Entry 200 - 23F + 0x01ff, 0x0000, 0x0000, 0x0202, 0x0000, 0x0204, 0x0204, 0x0000, + 0x0207, 0x0000, 0x0209, 0x0209, 0x0000, 0x020c, 0x020c, 0x0000, + 0x020f, 0x020f, 0x020f, 0x020f, 0x020f, 0x020f, 0x020f, 0x0000, + 0x0217, 0x0000, 0x0219, 0x0000, 0x021b, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0221, 0x0000, 0x0000, 0x0224, 0x0000, 0x0226, + 0x0226, 0x0000, 0x0229, 0x0000, 0x022b, 0x022b, 0x0000, 0x0000, + 0x022f, 0x022e, 0x022e, 0x0000, 0x0000, 0x0234, 0x0000, 0x0236, + 0x0000, 0x0238, 0x0000, 0x0244, 0x023a, 0x0244, 0x0244, 0x0244, + // Entry 240 - 27F + 0x0244, 0x0244, 0x0244, 0x0244, 0x023a, 0x0244, 0x0244, 0x0000, + 0x0247, 0x0247, 0x0247, 0x0000, 0x024b, 0x0000, 0x024d, 0x0000, + 0x024f, 0x024f, 0x0000, 0x0252, 0x0000, 0x0254, 0x0254, 0x0254, + 0x0254, 0x0254, 0x0254, 0x0000, 0x025b, 0x0000, 0x025d, 0x0000, + 0x025f, 0x0000, 0x0261, 0x0000, 0x0263, 0x0000, 0x0265, 0x0000, + 0x0000, 0x0268, 0x0268, 0x0268, 0x0000, 0x026c, 0x0000, 0x026e, + 0x0000, 0x0270, 0x0000, 0x0000, 0x0000, 0x0274, 0x0273, 0x0273, + 0x0000, 0x0278, 0x0000, 0x027a, 0x0000, 0x027c, 0x0000, 0x0000, + // Entry 280 - 2BF + 0x0000, 0x0000, 0x0281, 0x0000, 0x0000, 0x0284, 0x0000, 0x0286, + 0x0286, 0x0286, 0x0286, 0x0000, 0x028b, 0x028b, 0x028b, 0x0000, + 0x028f, 0x028f, 0x028f, 0x028f, 0x028f, 0x0000, 0x0295, 0x0295, + 0x0295, 0x0295, 0x0000, 0x0000, 0x0000, 0x0000, 0x029d, 0x029d, + 0x029d, 0x0000, 0x02a1, 0x02a1, 0x02a1, 0x02a1, 0x0000, 0x0000, + 0x02a7, 0x02a7, 0x02a7, 0x02a7, 0x0000, 0x02ac, 0x0000, 0x02ae, + 0x02ae, 0x0000, 0x02b1, 0x0000, 0x02b3, 0x0000, 0x02b5, 0x02b5, + 0x0000, 0x0000, 0x02b9, 0x0000, 0x0000, 0x0000, 0x02bd, 0x0000, + // Entry 2C0 - 2FF + 0x02bf, 0x02bf, 0x0000, 0x0000, 0x02c3, 0x0000, 0x02c5, 0x0000, + 0x02c7, 0x0000, 0x02c9, 0x0000, 0x02cb, 0x0000, 0x02cd, 0x02cd, + 0x0000, 0x0000, 0x02d1, 0x0000, 0x02d3, 0x02d0, 0x02d0, 0x0000, + 0x0000, 0x02d8, 0x02d7, 0x02d7, 0x0000, 0x0000, 0x02dd, 0x0000, + 0x02df, 0x0000, 0x02e1, 0x0000, 0x0000, 0x02e4, 0x0000, 0x02e6, + 0x0000, 0x0000, 0x02e9, 0x0000, 0x02eb, 0x0000, 0x02ed, 0x0000, + 0x02ef, 0x02ef, 0x0000, 0x0000, 0x02f3, 0x02f2, 0x02f2, 0x0000, + 0x02f7, 0x0000, 0x02f9, 0x02f9, 0x02f9, 0x02f9, 0x02f9, 0x0000, + // Entry 300 - 33F + 0x02ff, 0x0300, 0x02ff, 0x0000, 0x0303, 0x0051, 0x00e6, +} // Size: 1574 bytes + +// Total table size 1574 bytes (1KiB); checksum: 895AAF0B diff --git a/vendor/golang.org/x/text/internal/language/compact/tables.go b/vendor/golang.org/x/text/internal/language/compact/tables.go new file mode 100644 index 000000000..a09ed198a --- /dev/null +++ b/vendor/golang.org/x/text/internal/language/compact/tables.go @@ -0,0 +1,1015 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +package compact + +import "golang.org/x/text/internal/language" + +// CLDRVersion is the CLDR version from which the tables in this package are derived. +const CLDRVersion = "32" + +// NumCompactTags is the number of common tags. The maximum tag is +// NumCompactTags-1. +const NumCompactTags = 775 +const ( + undIndex ID = 0 + afIndex ID = 1 + afNAIndex ID = 2 + afZAIndex ID = 3 + agqIndex ID = 4 + agqCMIndex ID = 5 + akIndex ID = 6 + akGHIndex ID = 7 + amIndex ID = 8 + amETIndex ID = 9 + arIndex ID = 10 + ar001Index ID = 11 + arAEIndex ID = 12 + arBHIndex ID = 13 + arDJIndex ID = 14 + arDZIndex ID = 15 + arEGIndex ID = 16 + arEHIndex ID = 17 + arERIndex ID = 18 + arILIndex ID = 19 + arIQIndex ID = 20 + arJOIndex ID = 21 + arKMIndex ID = 22 + arKWIndex ID = 23 + arLBIndex ID = 24 + arLYIndex ID = 25 + arMAIndex ID = 26 + arMRIndex ID = 27 + arOMIndex ID = 28 + arPSIndex ID = 29 + arQAIndex ID = 30 + arSAIndex ID = 31 + arSDIndex ID = 32 + arSOIndex ID = 33 + arSSIndex ID = 34 + arSYIndex ID = 35 + arTDIndex ID = 36 + arTNIndex ID = 37 + arYEIndex ID = 38 + arsIndex ID = 39 + asIndex ID = 40 + asINIndex ID = 41 + asaIndex ID = 42 + asaTZIndex ID = 43 + astIndex ID = 44 + astESIndex ID = 45 + azIndex ID = 46 + azCyrlIndex ID = 47 + azCyrlAZIndex ID = 48 + azLatnIndex ID = 49 + azLatnAZIndex ID = 50 + basIndex ID = 51 + basCMIndex ID = 52 + beIndex ID = 53 + beBYIndex ID = 54 + bemIndex ID = 55 + bemZMIndex ID = 56 + bezIndex ID = 57 + bezTZIndex ID = 58 + bgIndex ID = 59 + bgBGIndex ID = 60 + bhIndex ID = 61 + bmIndex ID = 62 + bmMLIndex ID = 63 + bnIndex ID = 64 + bnBDIndex ID = 65 + bnINIndex ID = 66 + boIndex ID = 67 + boCNIndex ID = 68 + boINIndex ID = 69 + brIndex ID = 70 + brFRIndex ID = 71 + brxIndex ID = 72 + brxINIndex ID = 73 + bsIndex ID = 74 + bsCyrlIndex ID = 75 + bsCyrlBAIndex ID = 76 + bsLatnIndex ID = 77 + bsLatnBAIndex ID = 78 + caIndex ID = 79 + caADIndex ID = 80 + caESIndex ID = 81 + caFRIndex ID = 82 + caITIndex ID = 83 + ccpIndex ID = 84 + ccpBDIndex ID = 85 + ccpINIndex ID = 86 + ceIndex ID = 87 + ceRUIndex ID = 88 + cggIndex ID = 89 + cggUGIndex ID = 90 + chrIndex ID = 91 + chrUSIndex ID = 92 + ckbIndex ID = 93 + ckbIQIndex ID = 94 + ckbIRIndex ID = 95 + csIndex ID = 96 + csCZIndex ID = 97 + cuIndex ID = 98 + cuRUIndex ID = 99 + cyIndex ID = 100 + cyGBIndex ID = 101 + daIndex ID = 102 + daDKIndex ID = 103 + daGLIndex ID = 104 + davIndex ID = 105 + davKEIndex ID = 106 + deIndex ID = 107 + deATIndex ID = 108 + deBEIndex ID = 109 + deCHIndex ID = 110 + deDEIndex ID = 111 + deITIndex ID = 112 + deLIIndex ID = 113 + deLUIndex ID = 114 + djeIndex ID = 115 + djeNEIndex ID = 116 + dsbIndex ID = 117 + dsbDEIndex ID = 118 + duaIndex ID = 119 + duaCMIndex ID = 120 + dvIndex ID = 121 + dyoIndex ID = 122 + dyoSNIndex ID = 123 + dzIndex ID = 124 + dzBTIndex ID = 125 + ebuIndex ID = 126 + ebuKEIndex ID = 127 + eeIndex ID = 128 + eeGHIndex ID = 129 + eeTGIndex ID = 130 + elIndex ID = 131 + elCYIndex ID = 132 + elGRIndex ID = 133 + enIndex ID = 134 + en001Index ID = 135 + en150Index ID = 136 + enAGIndex ID = 137 + enAIIndex ID = 138 + enASIndex ID = 139 + enATIndex ID = 140 + enAUIndex ID = 141 + enBBIndex ID = 142 + enBEIndex ID = 143 + enBIIndex ID = 144 + enBMIndex ID = 145 + enBSIndex ID = 146 + enBWIndex ID = 147 + enBZIndex ID = 148 + enCAIndex ID = 149 + enCCIndex ID = 150 + enCHIndex ID = 151 + enCKIndex ID = 152 + enCMIndex ID = 153 + enCXIndex ID = 154 + enCYIndex ID = 155 + enDEIndex ID = 156 + enDGIndex ID = 157 + enDKIndex ID = 158 + enDMIndex ID = 159 + enERIndex ID = 160 + enFIIndex ID = 161 + enFJIndex ID = 162 + enFKIndex ID = 163 + enFMIndex ID = 164 + enGBIndex ID = 165 + enGDIndex ID = 166 + enGGIndex ID = 167 + enGHIndex ID = 168 + enGIIndex ID = 169 + enGMIndex ID = 170 + enGUIndex ID = 171 + enGYIndex ID = 172 + enHKIndex ID = 173 + enIEIndex ID = 174 + enILIndex ID = 175 + enIMIndex ID = 176 + enINIndex ID = 177 + enIOIndex ID = 178 + enJEIndex ID = 179 + enJMIndex ID = 180 + enKEIndex ID = 181 + enKIIndex ID = 182 + enKNIndex ID = 183 + enKYIndex ID = 184 + enLCIndex ID = 185 + enLRIndex ID = 186 + enLSIndex ID = 187 + enMGIndex ID = 188 + enMHIndex ID = 189 + enMOIndex ID = 190 + enMPIndex ID = 191 + enMSIndex ID = 192 + enMTIndex ID = 193 + enMUIndex ID = 194 + enMWIndex ID = 195 + enMYIndex ID = 196 + enNAIndex ID = 197 + enNFIndex ID = 198 + enNGIndex ID = 199 + enNLIndex ID = 200 + enNRIndex ID = 201 + enNUIndex ID = 202 + enNZIndex ID = 203 + enPGIndex ID = 204 + enPHIndex ID = 205 + enPKIndex ID = 206 + enPNIndex ID = 207 + enPRIndex ID = 208 + enPWIndex ID = 209 + enRWIndex ID = 210 + enSBIndex ID = 211 + enSCIndex ID = 212 + enSDIndex ID = 213 + enSEIndex ID = 214 + enSGIndex ID = 215 + enSHIndex ID = 216 + enSIIndex ID = 217 + enSLIndex ID = 218 + enSSIndex ID = 219 + enSXIndex ID = 220 + enSZIndex ID = 221 + enTCIndex ID = 222 + enTKIndex ID = 223 + enTOIndex ID = 224 + enTTIndex ID = 225 + enTVIndex ID = 226 + enTZIndex ID = 227 + enUGIndex ID = 228 + enUMIndex ID = 229 + enUSIndex ID = 230 + enVCIndex ID = 231 + enVGIndex ID = 232 + enVIIndex ID = 233 + enVUIndex ID = 234 + enWSIndex ID = 235 + enZAIndex ID = 236 + enZMIndex ID = 237 + enZWIndex ID = 238 + eoIndex ID = 239 + eo001Index ID = 240 + esIndex ID = 241 + es419Index ID = 242 + esARIndex ID = 243 + esBOIndex ID = 244 + esBRIndex ID = 245 + esBZIndex ID = 246 + esCLIndex ID = 247 + esCOIndex ID = 248 + esCRIndex ID = 249 + esCUIndex ID = 250 + esDOIndex ID = 251 + esEAIndex ID = 252 + esECIndex ID = 253 + esESIndex ID = 254 + esGQIndex ID = 255 + esGTIndex ID = 256 + esHNIndex ID = 257 + esICIndex ID = 258 + esMXIndex ID = 259 + esNIIndex ID = 260 + esPAIndex ID = 261 + esPEIndex ID = 262 + esPHIndex ID = 263 + esPRIndex ID = 264 + esPYIndex ID = 265 + esSVIndex ID = 266 + esUSIndex ID = 267 + esUYIndex ID = 268 + esVEIndex ID = 269 + etIndex ID = 270 + etEEIndex ID = 271 + euIndex ID = 272 + euESIndex ID = 273 + ewoIndex ID = 274 + ewoCMIndex ID = 275 + faIndex ID = 276 + faAFIndex ID = 277 + faIRIndex ID = 278 + ffIndex ID = 279 + ffCMIndex ID = 280 + ffGNIndex ID = 281 + ffMRIndex ID = 282 + ffSNIndex ID = 283 + fiIndex ID = 284 + fiFIIndex ID = 285 + filIndex ID = 286 + filPHIndex ID = 287 + foIndex ID = 288 + foDKIndex ID = 289 + foFOIndex ID = 290 + frIndex ID = 291 + frBEIndex ID = 292 + frBFIndex ID = 293 + frBIIndex ID = 294 + frBJIndex ID = 295 + frBLIndex ID = 296 + frCAIndex ID = 297 + frCDIndex ID = 298 + frCFIndex ID = 299 + frCGIndex ID = 300 + frCHIndex ID = 301 + frCIIndex ID = 302 + frCMIndex ID = 303 + frDJIndex ID = 304 + frDZIndex ID = 305 + frFRIndex ID = 306 + frGAIndex ID = 307 + frGFIndex ID = 308 + frGNIndex ID = 309 + frGPIndex ID = 310 + frGQIndex ID = 311 + frHTIndex ID = 312 + frKMIndex ID = 313 + frLUIndex ID = 314 + frMAIndex ID = 315 + frMCIndex ID = 316 + frMFIndex ID = 317 + frMGIndex ID = 318 + frMLIndex ID = 319 + frMQIndex ID = 320 + frMRIndex ID = 321 + frMUIndex ID = 322 + frNCIndex ID = 323 + frNEIndex ID = 324 + frPFIndex ID = 325 + frPMIndex ID = 326 + frREIndex ID = 327 + frRWIndex ID = 328 + frSCIndex ID = 329 + frSNIndex ID = 330 + frSYIndex ID = 331 + frTDIndex ID = 332 + frTGIndex ID = 333 + frTNIndex ID = 334 + frVUIndex ID = 335 + frWFIndex ID = 336 + frYTIndex ID = 337 + furIndex ID = 338 + furITIndex ID = 339 + fyIndex ID = 340 + fyNLIndex ID = 341 + gaIndex ID = 342 + gaIEIndex ID = 343 + gdIndex ID = 344 + gdGBIndex ID = 345 + glIndex ID = 346 + glESIndex ID = 347 + gswIndex ID = 348 + gswCHIndex ID = 349 + gswFRIndex ID = 350 + gswLIIndex ID = 351 + guIndex ID = 352 + guINIndex ID = 353 + guwIndex ID = 354 + guzIndex ID = 355 + guzKEIndex ID = 356 + gvIndex ID = 357 + gvIMIndex ID = 358 + haIndex ID = 359 + haGHIndex ID = 360 + haNEIndex ID = 361 + haNGIndex ID = 362 + hawIndex ID = 363 + hawUSIndex ID = 364 + heIndex ID = 365 + heILIndex ID = 366 + hiIndex ID = 367 + hiINIndex ID = 368 + hrIndex ID = 369 + hrBAIndex ID = 370 + hrHRIndex ID = 371 + hsbIndex ID = 372 + hsbDEIndex ID = 373 + huIndex ID = 374 + huHUIndex ID = 375 + hyIndex ID = 376 + hyAMIndex ID = 377 + idIndex ID = 378 + idIDIndex ID = 379 + igIndex ID = 380 + igNGIndex ID = 381 + iiIndex ID = 382 + iiCNIndex ID = 383 + inIndex ID = 384 + ioIndex ID = 385 + isIndex ID = 386 + isISIndex ID = 387 + itIndex ID = 388 + itCHIndex ID = 389 + itITIndex ID = 390 + itSMIndex ID = 391 + itVAIndex ID = 392 + iuIndex ID = 393 + iwIndex ID = 394 + jaIndex ID = 395 + jaJPIndex ID = 396 + jboIndex ID = 397 + jgoIndex ID = 398 + jgoCMIndex ID = 399 + jiIndex ID = 400 + jmcIndex ID = 401 + jmcTZIndex ID = 402 + jvIndex ID = 403 + jwIndex ID = 404 + kaIndex ID = 405 + kaGEIndex ID = 406 + kabIndex ID = 407 + kabDZIndex ID = 408 + kajIndex ID = 409 + kamIndex ID = 410 + kamKEIndex ID = 411 + kcgIndex ID = 412 + kdeIndex ID = 413 + kdeTZIndex ID = 414 + keaIndex ID = 415 + keaCVIndex ID = 416 + khqIndex ID = 417 + khqMLIndex ID = 418 + kiIndex ID = 419 + kiKEIndex ID = 420 + kkIndex ID = 421 + kkKZIndex ID = 422 + kkjIndex ID = 423 + kkjCMIndex ID = 424 + klIndex ID = 425 + klGLIndex ID = 426 + klnIndex ID = 427 + klnKEIndex ID = 428 + kmIndex ID = 429 + kmKHIndex ID = 430 + knIndex ID = 431 + knINIndex ID = 432 + koIndex ID = 433 + koKPIndex ID = 434 + koKRIndex ID = 435 + kokIndex ID = 436 + kokINIndex ID = 437 + ksIndex ID = 438 + ksINIndex ID = 439 + ksbIndex ID = 440 + ksbTZIndex ID = 441 + ksfIndex ID = 442 + ksfCMIndex ID = 443 + kshIndex ID = 444 + kshDEIndex ID = 445 + kuIndex ID = 446 + kwIndex ID = 447 + kwGBIndex ID = 448 + kyIndex ID = 449 + kyKGIndex ID = 450 + lagIndex ID = 451 + lagTZIndex ID = 452 + lbIndex ID = 453 + lbLUIndex ID = 454 + lgIndex ID = 455 + lgUGIndex ID = 456 + lktIndex ID = 457 + lktUSIndex ID = 458 + lnIndex ID = 459 + lnAOIndex ID = 460 + lnCDIndex ID = 461 + lnCFIndex ID = 462 + lnCGIndex ID = 463 + loIndex ID = 464 + loLAIndex ID = 465 + lrcIndex ID = 466 + lrcIQIndex ID = 467 + lrcIRIndex ID = 468 + ltIndex ID = 469 + ltLTIndex ID = 470 + luIndex ID = 471 + luCDIndex ID = 472 + luoIndex ID = 473 + luoKEIndex ID = 474 + luyIndex ID = 475 + luyKEIndex ID = 476 + lvIndex ID = 477 + lvLVIndex ID = 478 + masIndex ID = 479 + masKEIndex ID = 480 + masTZIndex ID = 481 + merIndex ID = 482 + merKEIndex ID = 483 + mfeIndex ID = 484 + mfeMUIndex ID = 485 + mgIndex ID = 486 + mgMGIndex ID = 487 + mghIndex ID = 488 + mghMZIndex ID = 489 + mgoIndex ID = 490 + mgoCMIndex ID = 491 + mkIndex ID = 492 + mkMKIndex ID = 493 + mlIndex ID = 494 + mlINIndex ID = 495 + mnIndex ID = 496 + mnMNIndex ID = 497 + moIndex ID = 498 + mrIndex ID = 499 + mrINIndex ID = 500 + msIndex ID = 501 + msBNIndex ID = 502 + msMYIndex ID = 503 + msSGIndex ID = 504 + mtIndex ID = 505 + mtMTIndex ID = 506 + muaIndex ID = 507 + muaCMIndex ID = 508 + myIndex ID = 509 + myMMIndex ID = 510 + mznIndex ID = 511 + mznIRIndex ID = 512 + nahIndex ID = 513 + naqIndex ID = 514 + naqNAIndex ID = 515 + nbIndex ID = 516 + nbNOIndex ID = 517 + nbSJIndex ID = 518 + ndIndex ID = 519 + ndZWIndex ID = 520 + ndsIndex ID = 521 + ndsDEIndex ID = 522 + ndsNLIndex ID = 523 + neIndex ID = 524 + neINIndex ID = 525 + neNPIndex ID = 526 + nlIndex ID = 527 + nlAWIndex ID = 528 + nlBEIndex ID = 529 + nlBQIndex ID = 530 + nlCWIndex ID = 531 + nlNLIndex ID = 532 + nlSRIndex ID = 533 + nlSXIndex ID = 534 + nmgIndex ID = 535 + nmgCMIndex ID = 536 + nnIndex ID = 537 + nnNOIndex ID = 538 + nnhIndex ID = 539 + nnhCMIndex ID = 540 + noIndex ID = 541 + nqoIndex ID = 542 + nrIndex ID = 543 + nsoIndex ID = 544 + nusIndex ID = 545 + nusSSIndex ID = 546 + nyIndex ID = 547 + nynIndex ID = 548 + nynUGIndex ID = 549 + omIndex ID = 550 + omETIndex ID = 551 + omKEIndex ID = 552 + orIndex ID = 553 + orINIndex ID = 554 + osIndex ID = 555 + osGEIndex ID = 556 + osRUIndex ID = 557 + paIndex ID = 558 + paArabIndex ID = 559 + paArabPKIndex ID = 560 + paGuruIndex ID = 561 + paGuruINIndex ID = 562 + papIndex ID = 563 + plIndex ID = 564 + plPLIndex ID = 565 + prgIndex ID = 566 + prg001Index ID = 567 + psIndex ID = 568 + psAFIndex ID = 569 + ptIndex ID = 570 + ptAOIndex ID = 571 + ptBRIndex ID = 572 + ptCHIndex ID = 573 + ptCVIndex ID = 574 + ptGQIndex ID = 575 + ptGWIndex ID = 576 + ptLUIndex ID = 577 + ptMOIndex ID = 578 + ptMZIndex ID = 579 + ptPTIndex ID = 580 + ptSTIndex ID = 581 + ptTLIndex ID = 582 + quIndex ID = 583 + quBOIndex ID = 584 + quECIndex ID = 585 + quPEIndex ID = 586 + rmIndex ID = 587 + rmCHIndex ID = 588 + rnIndex ID = 589 + rnBIIndex ID = 590 + roIndex ID = 591 + roMDIndex ID = 592 + roROIndex ID = 593 + rofIndex ID = 594 + rofTZIndex ID = 595 + ruIndex ID = 596 + ruBYIndex ID = 597 + ruKGIndex ID = 598 + ruKZIndex ID = 599 + ruMDIndex ID = 600 + ruRUIndex ID = 601 + ruUAIndex ID = 602 + rwIndex ID = 603 + rwRWIndex ID = 604 + rwkIndex ID = 605 + rwkTZIndex ID = 606 + sahIndex ID = 607 + sahRUIndex ID = 608 + saqIndex ID = 609 + saqKEIndex ID = 610 + sbpIndex ID = 611 + sbpTZIndex ID = 612 + sdIndex ID = 613 + sdPKIndex ID = 614 + sdhIndex ID = 615 + seIndex ID = 616 + seFIIndex ID = 617 + seNOIndex ID = 618 + seSEIndex ID = 619 + sehIndex ID = 620 + sehMZIndex ID = 621 + sesIndex ID = 622 + sesMLIndex ID = 623 + sgIndex ID = 624 + sgCFIndex ID = 625 + shIndex ID = 626 + shiIndex ID = 627 + shiLatnIndex ID = 628 + shiLatnMAIndex ID = 629 + shiTfngIndex ID = 630 + shiTfngMAIndex ID = 631 + siIndex ID = 632 + siLKIndex ID = 633 + skIndex ID = 634 + skSKIndex ID = 635 + slIndex ID = 636 + slSIIndex ID = 637 + smaIndex ID = 638 + smiIndex ID = 639 + smjIndex ID = 640 + smnIndex ID = 641 + smnFIIndex ID = 642 + smsIndex ID = 643 + snIndex ID = 644 + snZWIndex ID = 645 + soIndex ID = 646 + soDJIndex ID = 647 + soETIndex ID = 648 + soKEIndex ID = 649 + soSOIndex ID = 650 + sqIndex ID = 651 + sqALIndex ID = 652 + sqMKIndex ID = 653 + sqXKIndex ID = 654 + srIndex ID = 655 + srCyrlIndex ID = 656 + srCyrlBAIndex ID = 657 + srCyrlMEIndex ID = 658 + srCyrlRSIndex ID = 659 + srCyrlXKIndex ID = 660 + srLatnIndex ID = 661 + srLatnBAIndex ID = 662 + srLatnMEIndex ID = 663 + srLatnRSIndex ID = 664 + srLatnXKIndex ID = 665 + ssIndex ID = 666 + ssyIndex ID = 667 + stIndex ID = 668 + svIndex ID = 669 + svAXIndex ID = 670 + svFIIndex ID = 671 + svSEIndex ID = 672 + swIndex ID = 673 + swCDIndex ID = 674 + swKEIndex ID = 675 + swTZIndex ID = 676 + swUGIndex ID = 677 + syrIndex ID = 678 + taIndex ID = 679 + taINIndex ID = 680 + taLKIndex ID = 681 + taMYIndex ID = 682 + taSGIndex ID = 683 + teIndex ID = 684 + teINIndex ID = 685 + teoIndex ID = 686 + teoKEIndex ID = 687 + teoUGIndex ID = 688 + tgIndex ID = 689 + tgTJIndex ID = 690 + thIndex ID = 691 + thTHIndex ID = 692 + tiIndex ID = 693 + tiERIndex ID = 694 + tiETIndex ID = 695 + tigIndex ID = 696 + tkIndex ID = 697 + tkTMIndex ID = 698 + tlIndex ID = 699 + tnIndex ID = 700 + toIndex ID = 701 + toTOIndex ID = 702 + trIndex ID = 703 + trCYIndex ID = 704 + trTRIndex ID = 705 + tsIndex ID = 706 + ttIndex ID = 707 + ttRUIndex ID = 708 + twqIndex ID = 709 + twqNEIndex ID = 710 + tzmIndex ID = 711 + tzmMAIndex ID = 712 + ugIndex ID = 713 + ugCNIndex ID = 714 + ukIndex ID = 715 + ukUAIndex ID = 716 + urIndex ID = 717 + urINIndex ID = 718 + urPKIndex ID = 719 + uzIndex ID = 720 + uzArabIndex ID = 721 + uzArabAFIndex ID = 722 + uzCyrlIndex ID = 723 + uzCyrlUZIndex ID = 724 + uzLatnIndex ID = 725 + uzLatnUZIndex ID = 726 + vaiIndex ID = 727 + vaiLatnIndex ID = 728 + vaiLatnLRIndex ID = 729 + vaiVaiiIndex ID = 730 + vaiVaiiLRIndex ID = 731 + veIndex ID = 732 + viIndex ID = 733 + viVNIndex ID = 734 + voIndex ID = 735 + vo001Index ID = 736 + vunIndex ID = 737 + vunTZIndex ID = 738 + waIndex ID = 739 + waeIndex ID = 740 + waeCHIndex ID = 741 + woIndex ID = 742 + woSNIndex ID = 743 + xhIndex ID = 744 + xogIndex ID = 745 + xogUGIndex ID = 746 + yavIndex ID = 747 + yavCMIndex ID = 748 + yiIndex ID = 749 + yi001Index ID = 750 + yoIndex ID = 751 + yoBJIndex ID = 752 + yoNGIndex ID = 753 + yueIndex ID = 754 + yueHansIndex ID = 755 + yueHansCNIndex ID = 756 + yueHantIndex ID = 757 + yueHantHKIndex ID = 758 + zghIndex ID = 759 + zghMAIndex ID = 760 + zhIndex ID = 761 + zhHansIndex ID = 762 + zhHansCNIndex ID = 763 + zhHansHKIndex ID = 764 + zhHansMOIndex ID = 765 + zhHansSGIndex ID = 766 + zhHantIndex ID = 767 + zhHantHKIndex ID = 768 + zhHantMOIndex ID = 769 + zhHantTWIndex ID = 770 + zuIndex ID = 771 + zuZAIndex ID = 772 + caESvalenciaIndex ID = 773 + enUSuvaposixIndex ID = 774 +) + +var coreTags = []language.CompactCoreInfo{ // 773 elements + // Entry 0 - 1F + 0x00000000, 0x01600000, 0x016000d3, 0x01600162, + 0x01c00000, 0x01c00052, 0x02100000, 0x02100081, + 0x02700000, 0x02700070, 0x03a00000, 0x03a00001, + 0x03a00023, 0x03a00039, 0x03a00063, 0x03a00068, + 0x03a0006c, 0x03a0006d, 0x03a0006e, 0x03a00098, + 0x03a0009c, 0x03a000a2, 0x03a000a9, 0x03a000ad, + 0x03a000b1, 0x03a000ba, 0x03a000bb, 0x03a000ca, + 0x03a000e2, 0x03a000ee, 0x03a000f4, 0x03a00109, + // Entry 20 - 3F + 0x03a0010c, 0x03a00116, 0x03a00118, 0x03a0011d, + 0x03a00121, 0x03a00129, 0x03a0015f, 0x04000000, + 0x04300000, 0x0430009a, 0x04400000, 0x04400130, + 0x04800000, 0x0480006f, 0x05800000, 0x05820000, + 0x05820032, 0x0585b000, 0x0585b032, 0x05e00000, + 0x05e00052, 0x07100000, 0x07100047, 0x07500000, + 0x07500163, 0x07900000, 0x07900130, 0x07e00000, + 0x07e00038, 0x08200000, 0x0a000000, 0x0a0000c4, + // Entry 40 - 5F + 0x0a500000, 0x0a500035, 0x0a50009a, 0x0a900000, + 0x0a900053, 0x0a90009a, 0x0b200000, 0x0b200079, + 0x0b500000, 0x0b50009a, 0x0b700000, 0x0b720000, + 0x0b720033, 0x0b75b000, 0x0b75b033, 0x0d700000, + 0x0d700022, 0x0d70006f, 0x0d700079, 0x0d70009f, + 0x0db00000, 0x0db00035, 0x0db0009a, 0x0dc00000, + 0x0dc00107, 0x0df00000, 0x0df00132, 0x0e500000, + 0x0e500136, 0x0e900000, 0x0e90009c, 0x0e90009d, + // Entry 60 - 7F + 0x0fa00000, 0x0fa0005f, 0x0fe00000, 0x0fe00107, + 0x10000000, 0x1000007c, 0x10100000, 0x10100064, + 0x10100083, 0x10800000, 0x108000a5, 0x10d00000, + 0x10d0002e, 0x10d00036, 0x10d0004e, 0x10d00061, + 0x10d0009f, 0x10d000b3, 0x10d000b8, 0x11700000, + 0x117000d5, 0x11f00000, 0x11f00061, 0x12400000, + 0x12400052, 0x12800000, 0x12b00000, 0x12b00115, + 0x12d00000, 0x12d00043, 0x12f00000, 0x12f000a5, + // Entry 80 - 9F + 0x13000000, 0x13000081, 0x13000123, 0x13600000, + 0x1360005e, 0x13600088, 0x13900000, 0x13900001, + 0x1390001a, 0x13900025, 0x13900026, 0x1390002d, + 0x1390002e, 0x1390002f, 0x13900034, 0x13900036, + 0x1390003a, 0x1390003d, 0x13900042, 0x13900046, + 0x13900048, 0x13900049, 0x1390004a, 0x1390004e, + 0x13900050, 0x13900052, 0x1390005d, 0x1390005e, + 0x13900061, 0x13900062, 0x13900064, 0x13900065, + // Entry A0 - BF + 0x1390006e, 0x13900073, 0x13900074, 0x13900075, + 0x13900076, 0x1390007c, 0x1390007d, 0x13900080, + 0x13900081, 0x13900082, 0x13900084, 0x1390008b, + 0x1390008d, 0x1390008e, 0x13900097, 0x13900098, + 0x13900099, 0x1390009a, 0x1390009b, 0x139000a0, + 0x139000a1, 0x139000a5, 0x139000a8, 0x139000aa, + 0x139000ae, 0x139000b2, 0x139000b5, 0x139000b6, + 0x139000c0, 0x139000c1, 0x139000c7, 0x139000c8, + // Entry C0 - DF + 0x139000cb, 0x139000cc, 0x139000cd, 0x139000cf, + 0x139000d1, 0x139000d3, 0x139000d6, 0x139000d7, + 0x139000da, 0x139000de, 0x139000e0, 0x139000e1, + 0x139000e7, 0x139000e8, 0x139000e9, 0x139000ec, + 0x139000ed, 0x139000f1, 0x13900108, 0x1390010a, + 0x1390010b, 0x1390010c, 0x1390010d, 0x1390010e, + 0x1390010f, 0x13900110, 0x13900113, 0x13900118, + 0x1390011c, 0x1390011e, 0x13900120, 0x13900126, + // Entry E0 - FF + 0x1390012a, 0x1390012d, 0x1390012e, 0x13900130, + 0x13900132, 0x13900134, 0x13900136, 0x1390013a, + 0x1390013d, 0x1390013e, 0x13900140, 0x13900143, + 0x13900162, 0x13900163, 0x13900165, 0x13c00000, + 0x13c00001, 0x13e00000, 0x13e0001f, 0x13e0002c, + 0x13e0003f, 0x13e00041, 0x13e00048, 0x13e00051, + 0x13e00054, 0x13e00057, 0x13e0005a, 0x13e00066, + 0x13e00069, 0x13e0006a, 0x13e0006f, 0x13e00087, + // Entry 100 - 11F + 0x13e0008a, 0x13e00090, 0x13e00095, 0x13e000d0, + 0x13e000d9, 0x13e000e3, 0x13e000e5, 0x13e000e8, + 0x13e000ed, 0x13e000f2, 0x13e0011b, 0x13e00136, + 0x13e00137, 0x13e0013c, 0x14000000, 0x1400006b, + 0x14500000, 0x1450006f, 0x14600000, 0x14600052, + 0x14800000, 0x14800024, 0x1480009d, 0x14e00000, + 0x14e00052, 0x14e00085, 0x14e000ca, 0x14e00115, + 0x15100000, 0x15100073, 0x15300000, 0x153000e8, + // Entry 120 - 13F + 0x15800000, 0x15800064, 0x15800077, 0x15e00000, + 0x15e00036, 0x15e00037, 0x15e0003a, 0x15e0003b, + 0x15e0003c, 0x15e00049, 0x15e0004b, 0x15e0004c, + 0x15e0004d, 0x15e0004e, 0x15e0004f, 0x15e00052, + 0x15e00063, 0x15e00068, 0x15e00079, 0x15e0007b, + 0x15e0007f, 0x15e00085, 0x15e00086, 0x15e00087, + 0x15e00092, 0x15e000a9, 0x15e000b8, 0x15e000bb, + 0x15e000bc, 0x15e000bf, 0x15e000c0, 0x15e000c4, + // Entry 140 - 15F + 0x15e000c9, 0x15e000ca, 0x15e000cd, 0x15e000d4, + 0x15e000d5, 0x15e000e6, 0x15e000eb, 0x15e00103, + 0x15e00108, 0x15e0010b, 0x15e00115, 0x15e0011d, + 0x15e00121, 0x15e00123, 0x15e00129, 0x15e00140, + 0x15e00141, 0x15e00160, 0x16900000, 0x1690009f, + 0x16d00000, 0x16d000da, 0x16e00000, 0x16e00097, + 0x17e00000, 0x17e0007c, 0x19000000, 0x1900006f, + 0x1a300000, 0x1a30004e, 0x1a300079, 0x1a3000b3, + // Entry 160 - 17F + 0x1a400000, 0x1a40009a, 0x1a900000, 0x1ab00000, + 0x1ab000a5, 0x1ac00000, 0x1ac00099, 0x1b400000, + 0x1b400081, 0x1b4000d5, 0x1b4000d7, 0x1b800000, + 0x1b800136, 0x1bc00000, 0x1bc00098, 0x1be00000, + 0x1be0009a, 0x1d100000, 0x1d100033, 0x1d100091, + 0x1d200000, 0x1d200061, 0x1d500000, 0x1d500093, + 0x1d700000, 0x1d700028, 0x1e100000, 0x1e100096, + 0x1e700000, 0x1e7000d7, 0x1ea00000, 0x1ea00053, + // Entry 180 - 19F + 0x1f300000, 0x1f500000, 0x1f800000, 0x1f80009e, + 0x1f900000, 0x1f90004e, 0x1f90009f, 0x1f900114, + 0x1f900139, 0x1fa00000, 0x1fb00000, 0x20000000, + 0x200000a3, 0x20300000, 0x20700000, 0x20700052, + 0x20800000, 0x20a00000, 0x20a00130, 0x20e00000, + 0x20f00000, 0x21000000, 0x2100007e, 0x21200000, + 0x21200068, 0x21600000, 0x21700000, 0x217000a5, + 0x21f00000, 0x22300000, 0x22300130, 0x22700000, + // Entry 1A0 - 1BF + 0x2270005b, 0x23400000, 0x234000c4, 0x23900000, + 0x239000a5, 0x24200000, 0x242000af, 0x24400000, + 0x24400052, 0x24500000, 0x24500083, 0x24600000, + 0x246000a5, 0x24a00000, 0x24a000a7, 0x25100000, + 0x2510009a, 0x25400000, 0x254000ab, 0x254000ac, + 0x25600000, 0x2560009a, 0x26a00000, 0x26a0009a, + 0x26b00000, 0x26b00130, 0x26d00000, 0x26d00052, + 0x26e00000, 0x26e00061, 0x27400000, 0x28100000, + // Entry 1C0 - 1DF + 0x2810007c, 0x28a00000, 0x28a000a6, 0x29100000, + 0x29100130, 0x29500000, 0x295000b8, 0x2a300000, + 0x2a300132, 0x2af00000, 0x2af00136, 0x2b500000, + 0x2b50002a, 0x2b50004b, 0x2b50004c, 0x2b50004d, + 0x2b800000, 0x2b8000b0, 0x2bf00000, 0x2bf0009c, + 0x2bf0009d, 0x2c000000, 0x2c0000b7, 0x2c200000, + 0x2c20004b, 0x2c400000, 0x2c4000a5, 0x2c500000, + 0x2c5000a5, 0x2c700000, 0x2c7000b9, 0x2d100000, + // Entry 1E0 - 1FF + 0x2d1000a5, 0x2d100130, 0x2e900000, 0x2e9000a5, + 0x2ed00000, 0x2ed000cd, 0x2f100000, 0x2f1000c0, + 0x2f200000, 0x2f2000d2, 0x2f400000, 0x2f400052, + 0x2ff00000, 0x2ff000c3, 0x30400000, 0x3040009a, + 0x30b00000, 0x30b000c6, 0x31000000, 0x31b00000, + 0x31b0009a, 0x31f00000, 0x31f0003e, 0x31f000d1, + 0x31f0010e, 0x32000000, 0x320000cc, 0x32500000, + 0x32500052, 0x33100000, 0x331000c5, 0x33a00000, + // Entry 200 - 21F + 0x33a0009d, 0x34100000, 0x34500000, 0x345000d3, + 0x34700000, 0x347000db, 0x34700111, 0x34e00000, + 0x34e00165, 0x35000000, 0x35000061, 0x350000da, + 0x35100000, 0x3510009a, 0x351000dc, 0x36700000, + 0x36700030, 0x36700036, 0x36700040, 0x3670005c, + 0x367000da, 0x36700117, 0x3670011c, 0x36800000, + 0x36800052, 0x36a00000, 0x36a000db, 0x36c00000, + 0x36c00052, 0x36f00000, 0x37500000, 0x37600000, + // Entry 220 - 23F + 0x37a00000, 0x38000000, 0x38000118, 0x38700000, + 0x38900000, 0x38900132, 0x39000000, 0x39000070, + 0x390000a5, 0x39500000, 0x3950009a, 0x39800000, + 0x3980007e, 0x39800107, 0x39d00000, 0x39d05000, + 0x39d050e9, 0x39d36000, 0x39d3609a, 0x3a100000, + 0x3b300000, 0x3b3000ea, 0x3bd00000, 0x3bd00001, + 0x3be00000, 0x3be00024, 0x3c000000, 0x3c00002a, + 0x3c000041, 0x3c00004e, 0x3c00005b, 0x3c000087, + // Entry 240 - 25F + 0x3c00008c, 0x3c0000b8, 0x3c0000c7, 0x3c0000d2, + 0x3c0000ef, 0x3c000119, 0x3c000127, 0x3c400000, + 0x3c40003f, 0x3c40006a, 0x3c4000e5, 0x3d400000, + 0x3d40004e, 0x3d900000, 0x3d90003a, 0x3dc00000, + 0x3dc000bd, 0x3dc00105, 0x3de00000, 0x3de00130, + 0x3e200000, 0x3e200047, 0x3e2000a6, 0x3e2000af, + 0x3e2000bd, 0x3e200107, 0x3e200131, 0x3e500000, + 0x3e500108, 0x3e600000, 0x3e600130, 0x3eb00000, + // Entry 260 - 27F + 0x3eb00107, 0x3ec00000, 0x3ec000a5, 0x3f300000, + 0x3f300130, 0x3fa00000, 0x3fa000e9, 0x3fc00000, + 0x3fd00000, 0x3fd00073, 0x3fd000db, 0x3fd0010d, + 0x3ff00000, 0x3ff000d2, 0x40100000, 0x401000c4, + 0x40200000, 0x4020004c, 0x40700000, 0x40800000, + 0x4085b000, 0x4085b0bb, 0x408eb000, 0x408eb0bb, + 0x40c00000, 0x40c000b4, 0x41200000, 0x41200112, + 0x41600000, 0x41600110, 0x41c00000, 0x41d00000, + // Entry 280 - 29F + 0x41e00000, 0x41f00000, 0x41f00073, 0x42200000, + 0x42300000, 0x42300165, 0x42900000, 0x42900063, + 0x42900070, 0x429000a5, 0x42900116, 0x43100000, + 0x43100027, 0x431000c3, 0x4310014e, 0x43200000, + 0x43220000, 0x43220033, 0x432200be, 0x43220106, + 0x4322014e, 0x4325b000, 0x4325b033, 0x4325b0be, + 0x4325b106, 0x4325b14e, 0x43700000, 0x43a00000, + 0x43b00000, 0x44400000, 0x44400031, 0x44400073, + // Entry 2A0 - 2BF + 0x4440010d, 0x44500000, 0x4450004b, 0x445000a5, + 0x44500130, 0x44500132, 0x44e00000, 0x45000000, + 0x4500009a, 0x450000b4, 0x450000d1, 0x4500010e, + 0x46100000, 0x4610009a, 0x46400000, 0x464000a5, + 0x46400132, 0x46700000, 0x46700125, 0x46b00000, + 0x46b00124, 0x46f00000, 0x46f0006e, 0x46f00070, + 0x47100000, 0x47600000, 0x47600128, 0x47a00000, + 0x48000000, 0x48200000, 0x4820012a, 0x48a00000, + // Entry 2C0 - 2DF + 0x48a0005e, 0x48a0012c, 0x48e00000, 0x49400000, + 0x49400107, 0x4a400000, 0x4a4000d5, 0x4a900000, + 0x4a9000bb, 0x4ac00000, 0x4ac00053, 0x4ae00000, + 0x4ae00131, 0x4b400000, 0x4b40009a, 0x4b4000e9, + 0x4bc00000, 0x4bc05000, 0x4bc05024, 0x4bc20000, + 0x4bc20138, 0x4bc5b000, 0x4bc5b138, 0x4be00000, + 0x4be5b000, 0x4be5b0b5, 0x4bef4000, 0x4bef40b5, + 0x4c000000, 0x4c300000, 0x4c30013f, 0x4c900000, + // Entry 2E0 - 2FF + 0x4c900001, 0x4cc00000, 0x4cc00130, 0x4ce00000, + 0x4cf00000, 0x4cf0004e, 0x4e500000, 0x4e500115, + 0x4f200000, 0x4fb00000, 0x4fb00132, 0x50900000, + 0x50900052, 0x51200000, 0x51200001, 0x51800000, + 0x5180003b, 0x518000d7, 0x51f00000, 0x51f3b000, + 0x51f3b053, 0x51f3c000, 0x51f3c08e, 0x52800000, + 0x528000bb, 0x52900000, 0x5293b000, 0x5293b053, + 0x5293b08e, 0x5293b0c7, 0x5293b10e, 0x5293c000, + // Entry 300 - 31F + 0x5293c08e, 0x5293c0c7, 0x5293c12f, 0x52f00000, + 0x52f00162, +} // Size: 3116 bytes + +const specialTagsStr string = "ca-ES-valencia en-US-u-va-posix" + +// Total table size 3147 bytes (3KiB); checksum: 5A8FFFA5 diff --git a/vendor/golang.org/x/text/internal/language/compact/tags.go b/vendor/golang.org/x/text/internal/language/compact/tags.go new file mode 100644 index 000000000..ca135d295 --- /dev/null +++ b/vendor/golang.org/x/text/internal/language/compact/tags.go @@ -0,0 +1,91 @@ +// Copyright 2013 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 compact + +var ( + und = Tag{} + + Und Tag = Tag{} + + Afrikaans Tag = Tag{language: afIndex, locale: afIndex} + Amharic Tag = Tag{language: amIndex, locale: amIndex} + Arabic Tag = Tag{language: arIndex, locale: arIndex} + ModernStandardArabic Tag = Tag{language: ar001Index, locale: ar001Index} + Azerbaijani Tag = Tag{language: azIndex, locale: azIndex} + Bulgarian Tag = Tag{language: bgIndex, locale: bgIndex} + Bengali Tag = Tag{language: bnIndex, locale: bnIndex} + Catalan Tag = Tag{language: caIndex, locale: caIndex} + Czech Tag = Tag{language: csIndex, locale: csIndex} + Danish Tag = Tag{language: daIndex, locale: daIndex} + German Tag = Tag{language: deIndex, locale: deIndex} + Greek Tag = Tag{language: elIndex, locale: elIndex} + English Tag = Tag{language: enIndex, locale: enIndex} + AmericanEnglish Tag = Tag{language: enUSIndex, locale: enUSIndex} + BritishEnglish Tag = Tag{language: enGBIndex, locale: enGBIndex} + Spanish Tag = Tag{language: esIndex, locale: esIndex} + EuropeanSpanish Tag = Tag{language: esESIndex, locale: esESIndex} + LatinAmericanSpanish Tag = Tag{language: es419Index, locale: es419Index} + Estonian Tag = Tag{language: etIndex, locale: etIndex} + Persian Tag = Tag{language: faIndex, locale: faIndex} + Finnish Tag = Tag{language: fiIndex, locale: fiIndex} + Filipino Tag = Tag{language: filIndex, locale: filIndex} + French Tag = Tag{language: frIndex, locale: frIndex} + CanadianFrench Tag = Tag{language: frCAIndex, locale: frCAIndex} + Gujarati Tag = Tag{language: guIndex, locale: guIndex} + Hebrew Tag = Tag{language: heIndex, locale: heIndex} + Hindi Tag = Tag{language: hiIndex, locale: hiIndex} + Croatian Tag = Tag{language: hrIndex, locale: hrIndex} + Hungarian Tag = Tag{language: huIndex, locale: huIndex} + Armenian Tag = Tag{language: hyIndex, locale: hyIndex} + Indonesian Tag = Tag{language: idIndex, locale: idIndex} + Icelandic Tag = Tag{language: isIndex, locale: isIndex} + Italian Tag = Tag{language: itIndex, locale: itIndex} + Japanese Tag = Tag{language: jaIndex, locale: jaIndex} + Georgian Tag = Tag{language: kaIndex, locale: kaIndex} + Kazakh Tag = Tag{language: kkIndex, locale: kkIndex} + Khmer Tag = Tag{language: kmIndex, locale: kmIndex} + Kannada Tag = Tag{language: knIndex, locale: knIndex} + Korean Tag = Tag{language: koIndex, locale: koIndex} + Kirghiz Tag = Tag{language: kyIndex, locale: kyIndex} + Lao Tag = Tag{language: loIndex, locale: loIndex} + Lithuanian Tag = Tag{language: ltIndex, locale: ltIndex} + Latvian Tag = Tag{language: lvIndex, locale: lvIndex} + Macedonian Tag = Tag{language: mkIndex, locale: mkIndex} + Malayalam Tag = Tag{language: mlIndex, locale: mlIndex} + Mongolian Tag = Tag{language: mnIndex, locale: mnIndex} + Marathi Tag = Tag{language: mrIndex, locale: mrIndex} + Malay Tag = Tag{language: msIndex, locale: msIndex} + Burmese Tag = Tag{language: myIndex, locale: myIndex} + Nepali Tag = Tag{language: neIndex, locale: neIndex} + Dutch Tag = Tag{language: nlIndex, locale: nlIndex} + Norwegian Tag = Tag{language: noIndex, locale: noIndex} + Punjabi Tag = Tag{language: paIndex, locale: paIndex} + Polish Tag = Tag{language: plIndex, locale: plIndex} + Portuguese Tag = Tag{language: ptIndex, locale: ptIndex} + BrazilianPortuguese Tag = Tag{language: ptBRIndex, locale: ptBRIndex} + EuropeanPortuguese Tag = Tag{language: ptPTIndex, locale: ptPTIndex} + Romanian Tag = Tag{language: roIndex, locale: roIndex} + Russian Tag = Tag{language: ruIndex, locale: ruIndex} + Sinhala Tag = Tag{language: siIndex, locale: siIndex} + Slovak Tag = Tag{language: skIndex, locale: skIndex} + Slovenian Tag = Tag{language: slIndex, locale: slIndex} + Albanian Tag = Tag{language: sqIndex, locale: sqIndex} + Serbian Tag = Tag{language: srIndex, locale: srIndex} + SerbianLatin Tag = Tag{language: srLatnIndex, locale: srLatnIndex} + Swedish Tag = Tag{language: svIndex, locale: svIndex} + Swahili Tag = Tag{language: swIndex, locale: swIndex} + Tamil Tag = Tag{language: taIndex, locale: taIndex} + Telugu Tag = Tag{language: teIndex, locale: teIndex} + Thai Tag = Tag{language: thIndex, locale: thIndex} + Turkish Tag = Tag{language: trIndex, locale: trIndex} + Ukrainian Tag = Tag{language: ukIndex, locale: ukIndex} + Urdu Tag = Tag{language: urIndex, locale: urIndex} + Uzbek Tag = Tag{language: uzIndex, locale: uzIndex} + Vietnamese Tag = Tag{language: viIndex, locale: viIndex} + Chinese Tag = Tag{language: zhIndex, locale: zhIndex} + SimplifiedChinese Tag = Tag{language: zhHansIndex, locale: zhHansIndex} + TraditionalChinese Tag = Tag{language: zhHantIndex, locale: zhHantIndex} + Zulu Tag = Tag{language: zuIndex, locale: zuIndex} +) diff --git a/vendor/golang.org/x/text/internal/language/compose.go b/vendor/golang.org/x/text/internal/language/compose.go new file mode 100644 index 000000000..4ae78e0fa --- /dev/null +++ b/vendor/golang.org/x/text/internal/language/compose.go @@ -0,0 +1,167 @@ +// Copyright 2018 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 language + +import ( + "sort" + "strings" +) + +// A Builder allows constructing a Tag from individual components. +// Its main user is Compose in the top-level language package. +type Builder struct { + Tag Tag + + private string // the x extension + variants []string + extensions []string +} + +// Make returns a new Tag from the current settings. +func (b *Builder) Make() Tag { + t := b.Tag + + if len(b.extensions) > 0 || len(b.variants) > 0 { + sort.Sort(sortVariants(b.variants)) + sort.Strings(b.extensions) + + if b.private != "" { + b.extensions = append(b.extensions, b.private) + } + n := maxCoreSize + tokenLen(b.variants...) + tokenLen(b.extensions...) + buf := make([]byte, n) + p := t.genCoreBytes(buf) + t.pVariant = byte(p) + p += appendTokens(buf[p:], b.variants...) + t.pExt = uint16(p) + p += appendTokens(buf[p:], b.extensions...) + t.str = string(buf[:p]) + // We may not always need to remake the string, but when or when not + // to do so is rather tricky. + scan := makeScanner(buf[:p]) + t, _ = parse(&scan, "") + return t + + } else if b.private != "" { + t.str = b.private + t.RemakeString() + } + return t +} + +// SetTag copies all the settings from a given Tag. Any previously set values +// are discarded. +func (b *Builder) SetTag(t Tag) { + b.Tag.LangID = t.LangID + b.Tag.RegionID = t.RegionID + b.Tag.ScriptID = t.ScriptID + // TODO: optimize + b.variants = b.variants[:0] + if variants := t.Variants(); variants != "" { + for _, vr := range strings.Split(variants[1:], "-") { + b.variants = append(b.variants, vr) + } + } + b.extensions, b.private = b.extensions[:0], "" + for _, e := range t.Extensions() { + b.AddExt(e) + } +} + +// AddExt adds extension e to the tag. e must be a valid extension as returned +// by Tag.Extension. If the extension already exists, it will be discarded, +// except for a -u extension, where non-existing key-type pairs will added. +func (b *Builder) AddExt(e string) { + if e[0] == 'x' { + if b.private == "" { + b.private = e + } + return + } + for i, s := range b.extensions { + if s[0] == e[0] { + if e[0] == 'u' { + b.extensions[i] += e[1:] + } + return + } + } + b.extensions = append(b.extensions, e) +} + +// SetExt sets the extension e to the tag. e must be a valid extension as +// returned by Tag.Extension. If the extension already exists, it will be +// overwritten, except for a -u extension, where the individual key-type pairs +// will be set. +func (b *Builder) SetExt(e string) { + if e[0] == 'x' { + b.private = e + return + } + for i, s := range b.extensions { + if s[0] == e[0] { + if e[0] == 'u' { + b.extensions[i] = e + s[1:] + } else { + b.extensions[i] = e + } + return + } + } + b.extensions = append(b.extensions, e) +} + +// AddVariant adds any number of variants. +func (b *Builder) AddVariant(v ...string) { + for _, v := range v { + if v != "" { + b.variants = append(b.variants, v) + } + } +} + +// ClearVariants removes any variants previously added, including those +// copied from a Tag in SetTag. +func (b *Builder) ClearVariants() { + b.variants = b.variants[:0] +} + +// ClearExtensions removes any extensions previously added, including those +// copied from a Tag in SetTag. +func (b *Builder) ClearExtensions() { + b.private = "" + b.extensions = b.extensions[:0] +} + +func tokenLen(token ...string) (n int) { + for _, t := range token { + n += len(t) + 1 + } + return +} + +func appendTokens(b []byte, token ...string) int { + p := 0 + for _, t := range token { + b[p] = '-' + copy(b[p+1:], t) + p += 1 + len(t) + } + return p +} + +type sortVariants []string + +func (s sortVariants) Len() int { + return len(s) +} + +func (s sortVariants) Swap(i, j int) { + s[j], s[i] = s[i], s[j] +} + +func (s sortVariants) Less(i, j int) bool { + return variantIndex[s[i]] < variantIndex[s[j]] +} diff --git a/vendor/golang.org/x/text/internal/language/coverage.go b/vendor/golang.org/x/text/internal/language/coverage.go new file mode 100644 index 000000000..9b20b88fe --- /dev/null +++ b/vendor/golang.org/x/text/internal/language/coverage.go @@ -0,0 +1,28 @@ +// Copyright 2014 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 language + +// BaseLanguages returns the list of all supported base languages. It generates +// the list by traversing the internal structures. +func BaseLanguages() []Language { + base := make([]Language, 0, NumLanguages) + for i := 0; i < langNoIndexOffset; i++ { + // We included "und" already for the value 0. + if i != nonCanonicalUnd { + base = append(base, Language(i)) + } + } + i := langNoIndexOffset + for _, v := range langNoIndex { + for k := 0; k < 8; k++ { + if v&1 == 1 { + base = append(base, Language(i)) + } + v >>= 1 + i++ + } + } + return base +} diff --git a/vendor/golang.org/x/text/internal/language/language.go b/vendor/golang.org/x/text/internal/language/language.go new file mode 100644 index 000000000..09d41c736 --- /dev/null +++ b/vendor/golang.org/x/text/internal/language/language.go @@ -0,0 +1,627 @@ +// Copyright 2013 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 -output tables.go + +package language // import "golang.org/x/text/internal/language" + +// TODO: Remove above NOTE after: +// - verifying that tables are dropped correctly (most notably matcher tables). + +import ( + "errors" + "fmt" + "strings" +) + +const ( + // maxCoreSize is the maximum size of a BCP 47 tag without variants and + // extensions. Equals max lang (3) + script (4) + max reg (3) + 2 dashes. + maxCoreSize = 12 + + // max99thPercentileSize is a somewhat arbitrary buffer size that presumably + // is large enough to hold at least 99% of the BCP 47 tags. + max99thPercentileSize = 32 + + // maxSimpleUExtensionSize is the maximum size of a -u extension with one + // key-type pair. Equals len("-u-") + key (2) + dash + max value (8). + maxSimpleUExtensionSize = 14 +) + +// Tag represents a BCP 47 language tag. It is used to specify an instance of a +// specific language or locale. All language tag values are guaranteed to be +// well-formed. The zero value of Tag is Und. +type Tag struct { + // TODO: the following fields have the form TagTypeID. This name is chosen + // to allow refactoring the public package without conflicting with its + // Base, Script, and Region methods. Once the transition is fully completed + // the ID can be stripped from the name. + + LangID Language + RegionID Region + // TODO: we will soon run out of positions for ScriptID. Idea: instead of + // storing lang, region, and ScriptID codes, store only the compact index and + // have a lookup table from this code to its expansion. This greatly speeds + // up table lookup, speed up common variant cases. + // This will also immediately free up 3 extra bytes. Also, the pVariant + // field can now be moved to the lookup table, as the compact index uniquely + // determines the offset of a possible variant. + ScriptID Script + pVariant byte // offset in str, includes preceding '-' + pExt uint16 // offset of first extension, includes preceding '-' + + // str is the string representation of the Tag. It will only be used if the + // tag has variants or extensions. + str string +} + +// Make is a convenience wrapper for Parse that omits the error. +// In case of an error, a sensible default is returned. +func Make(s string) Tag { + t, _ := Parse(s) + return t +} + +// Raw returns the raw base language, script and region, without making an +// attempt to infer their values. +// TODO: consider removing +func (t Tag) Raw() (b Language, s Script, r Region) { + return t.LangID, t.ScriptID, t.RegionID +} + +// equalTags compares language, script and region subtags only. +func (t Tag) equalTags(a Tag) bool { + return t.LangID == a.LangID && t.ScriptID == a.ScriptID && t.RegionID == a.RegionID +} + +// IsRoot returns true if t is equal to language "und". +func (t Tag) IsRoot() bool { + if int(t.pVariant) < len(t.str) { + return false + } + return t.equalTags(Und) +} + +// IsPrivateUse reports whether the Tag consists solely of an IsPrivateUse use +// tag. +func (t Tag) IsPrivateUse() bool { + return t.str != "" && t.pVariant == 0 +} + +// RemakeString is used to update t.str in case lang, script or region changed. +// It is assumed that pExt and pVariant still point to the start of the +// respective parts. +func (t *Tag) RemakeString() { + if t.str == "" { + return + } + extra := t.str[t.pVariant:] + if t.pVariant > 0 { + extra = extra[1:] + } + if t.equalTags(Und) && strings.HasPrefix(extra, "x-") { + t.str = extra + t.pVariant = 0 + t.pExt = 0 + return + } + var buf [max99thPercentileSize]byte // avoid extra memory allocation in most cases. + b := buf[:t.genCoreBytes(buf[:])] + if extra != "" { + diff := len(b) - int(t.pVariant) + b = append(b, '-') + b = append(b, extra...) + t.pVariant = uint8(int(t.pVariant) + diff) + t.pExt = uint16(int(t.pExt) + diff) + } else { + t.pVariant = uint8(len(b)) + t.pExt = uint16(len(b)) + } + t.str = string(b) +} + +// genCoreBytes writes a string for the base languages, script and region tags +// to the given buffer and returns the number of bytes written. It will never +// write more than maxCoreSize bytes. +func (t *Tag) genCoreBytes(buf []byte) int { + n := t.LangID.StringToBuf(buf[:]) + if t.ScriptID != 0 { + n += copy(buf[n:], "-") + n += copy(buf[n:], t.ScriptID.String()) + } + if t.RegionID != 0 { + n += copy(buf[n:], "-") + n += copy(buf[n:], t.RegionID.String()) + } + return n +} + +// String returns the canonical string representation of the language tag. +func (t Tag) String() string { + if t.str != "" { + return t.str + } + if t.ScriptID == 0 && t.RegionID == 0 { + return t.LangID.String() + } + buf := [maxCoreSize]byte{} + return string(buf[:t.genCoreBytes(buf[:])]) +} + +// MarshalText implements encoding.TextMarshaler. +func (t Tag) MarshalText() (text []byte, err error) { + if t.str != "" { + text = append(text, t.str...) + } else if t.ScriptID == 0 && t.RegionID == 0 { + text = append(text, t.LangID.String()...) + } else { + buf := [maxCoreSize]byte{} + text = buf[:t.genCoreBytes(buf[:])] + } + return text, nil +} + +// UnmarshalText implements encoding.TextUnmarshaler. +func (t *Tag) UnmarshalText(text []byte) error { + tag, err := Parse(string(text)) + *t = tag + return err +} + +// Variants returns the part of the tag holding all variants or the empty string +// if there are no variants defined. +func (t Tag) Variants() string { + if t.pVariant == 0 { + return "" + } + return t.str[t.pVariant:t.pExt] +} + +// VariantOrPrivateUseTags returns variants or private use tags. +func (t Tag) VariantOrPrivateUseTags() string { + if t.pExt > 0 { + return t.str[t.pVariant:t.pExt] + } + return t.str[t.pVariant:] +} + +// HasString reports whether this tag defines more than just the raw +// components. +func (t Tag) HasString() bool { + return t.str != "" +} + +// Parent returns the CLDR parent of t. In CLDR, missing fields in data for a +// specific language are substituted with fields from the parent language. +// The parent for a language may change for newer versions of CLDR. +func (t Tag) Parent() Tag { + if t.str != "" { + // Strip the variants and extensions. + b, s, r := t.Raw() + t = Tag{LangID: b, ScriptID: s, RegionID: r} + if t.RegionID == 0 && t.ScriptID != 0 && t.LangID != 0 { + base, _ := addTags(Tag{LangID: t.LangID}) + if base.ScriptID == t.ScriptID { + return Tag{LangID: t.LangID} + } + } + return t + } + if t.LangID != 0 { + if t.RegionID != 0 { + maxScript := t.ScriptID + if maxScript == 0 { + max, _ := addTags(t) + maxScript = max.ScriptID + } + + for i := range parents { + if Language(parents[i].lang) == t.LangID && Script(parents[i].maxScript) == maxScript { + for _, r := range parents[i].fromRegion { + if Region(r) == t.RegionID { + return Tag{ + LangID: t.LangID, + ScriptID: Script(parents[i].script), + RegionID: Region(parents[i].toRegion), + } + } + } + } + } + + // Strip the script if it is the default one. + base, _ := addTags(Tag{LangID: t.LangID}) + if base.ScriptID != maxScript { + return Tag{LangID: t.LangID, ScriptID: maxScript} + } + return Tag{LangID: t.LangID} + } else if t.ScriptID != 0 { + // The parent for an base-script pair with a non-default script is + // "und" instead of the base language. + base, _ := addTags(Tag{LangID: t.LangID}) + if base.ScriptID != t.ScriptID { + return Und + } + return Tag{LangID: t.LangID} + } + } + return Und +} + +// ParseExtension parses s as an extension and returns it on success. +func ParseExtension(s string) (ext string, err error) { + defer func() { + if recover() != nil { + ext = "" + err = ErrSyntax + } + }() + + scan := makeScannerString(s) + var end int + if n := len(scan.token); n != 1 { + return "", ErrSyntax + } + scan.toLower(0, len(scan.b)) + end = parseExtension(&scan) + if end != len(s) { + return "", ErrSyntax + } + return string(scan.b), nil +} + +// HasVariants reports whether t has variants. +func (t Tag) HasVariants() bool { + return uint16(t.pVariant) < t.pExt +} + +// HasExtensions reports whether t has extensions. +func (t Tag) HasExtensions() bool { + return int(t.pExt) < len(t.str) +} + +// Extension returns the extension of type x for tag t. It will return +// false for ok if t does not have the requested extension. The returned +// extension will be invalid in this case. +func (t Tag) Extension(x byte) (ext string, ok bool) { + for i := int(t.pExt); i < len(t.str)-1; { + var ext string + i, ext = getExtension(t.str, i) + if ext[0] == x { + return ext, true + } + } + return "", false +} + +// Extensions returns all extensions of t. +func (t Tag) Extensions() []string { + e := []string{} + for i := int(t.pExt); i < len(t.str)-1; { + var ext string + i, ext = getExtension(t.str, i) + e = append(e, ext) + } + return e +} + +// TypeForKey returns the type associated with the given key, where key and type +// are of the allowed values defined for the Unicode locale extension ('u') in +// https://www.unicode.org/reports/tr35/#Unicode_Language_and_Locale_Identifiers. +// TypeForKey will traverse the inheritance chain to get the correct value. +// +// If there are multiple types associated with a key, only the first will be +// returned. If there is no type associated with a key, it returns the empty +// string. +func (t Tag) TypeForKey(key string) string { + if _, start, end, _ := t.findTypeForKey(key); end != start { + s := t.str[start:end] + if p := strings.IndexByte(s, '-'); p >= 0 { + s = s[:p] + } + return s + } + return "" +} + +var ( + errPrivateUse = errors.New("cannot set a key on a private use tag") + errInvalidArguments = errors.New("invalid key or type") +) + +// SetTypeForKey returns a new Tag with the key set to type, where key and type +// are of the allowed values defined for the Unicode locale extension ('u') in +// https://www.unicode.org/reports/tr35/#Unicode_Language_and_Locale_Identifiers. +// An empty value removes an existing pair with the same key. +func (t Tag) SetTypeForKey(key, value string) (Tag, error) { + if t.IsPrivateUse() { + return t, errPrivateUse + } + if len(key) != 2 { + return t, errInvalidArguments + } + + // Remove the setting if value is "". + if value == "" { + start, sep, end, _ := t.findTypeForKey(key) + if start != sep { + // Remove a possible empty extension. + switch { + case t.str[start-2] != '-': // has previous elements. + case end == len(t.str), // end of string + end+2 < len(t.str) && t.str[end+2] == '-': // end of extension + start -= 2 + } + if start == int(t.pVariant) && end == len(t.str) { + t.str = "" + t.pVariant, t.pExt = 0, 0 + } else { + t.str = fmt.Sprintf("%s%s", t.str[:start], t.str[end:]) + } + } + return t, nil + } + + if len(value) < 3 || len(value) > 8 { + return t, errInvalidArguments + } + + var ( + buf [maxCoreSize + maxSimpleUExtensionSize]byte + uStart int // start of the -u extension. + ) + + // Generate the tag string if needed. + if t.str == "" { + uStart = t.genCoreBytes(buf[:]) + buf[uStart] = '-' + uStart++ + } + + // Create new key-type pair and parse it to verify. + b := buf[uStart:] + copy(b, "u-") + copy(b[2:], key) + b[4] = '-' + b = b[:5+copy(b[5:], value)] + scan := makeScanner(b) + if parseExtensions(&scan); scan.err != nil { + return t, scan.err + } + + // Assemble the replacement string. + if t.str == "" { + t.pVariant, t.pExt = byte(uStart-1), uint16(uStart-1) + t.str = string(buf[:uStart+len(b)]) + } else { + s := t.str + start, sep, end, hasExt := t.findTypeForKey(key) + if start == sep { + if hasExt { + b = b[2:] + } + t.str = fmt.Sprintf("%s-%s%s", s[:sep], b, s[end:]) + } else { + t.str = fmt.Sprintf("%s-%s%s", s[:start+3], value, s[end:]) + } + } + return t, nil +} + +// findTypeForKey returns the start and end position for the type corresponding +// to key or the point at which to insert the key-value pair if the type +// wasn't found. The hasExt return value reports whether an -u extension was present. +// Note: the extensions are typically very small and are likely to contain +// only one key-type pair. +func (t Tag) findTypeForKey(key string) (start, sep, end int, hasExt bool) { + p := int(t.pExt) + if len(key) != 2 || p == len(t.str) || p == 0 { + return p, p, p, false + } + s := t.str + + // Find the correct extension. + for p++; s[p] != 'u'; p++ { + if s[p] > 'u' { + p-- + return p, p, p, false + } + if p = nextExtension(s, p); p == len(s) { + return len(s), len(s), len(s), false + } + } + // Proceed to the hyphen following the extension name. + p++ + + // curKey is the key currently being processed. + curKey := "" + + // Iterate over keys until we get the end of a section. + for { + end = p + for p++; p < len(s) && s[p] != '-'; p++ { + } + n := p - end - 1 + if n <= 2 && curKey == key { + if sep < end { + sep++ + } + return start, sep, end, true + } + switch n { + case 0, // invalid string + 1: // next extension + return end, end, end, true + case 2: + // next key + curKey = s[end+1 : p] + if curKey > key { + return end, end, end, true + } + start = end + sep = p + } + } +} + +// ParseBase parses a 2- or 3-letter ISO 639 code. +// It returns a ValueError if s is a well-formed but unknown language identifier +// or another error if another error occurred. +func ParseBase(s string) (l Language, err error) { + defer func() { + if recover() != nil { + l = 0 + err = ErrSyntax + } + }() + + if n := len(s); n < 2 || 3 < n { + return 0, ErrSyntax + } + var buf [3]byte + return getLangID(buf[:copy(buf[:], s)]) +} + +// ParseScript parses a 4-letter ISO 15924 code. +// It returns a ValueError if s is a well-formed but unknown script identifier +// or another error if another error occurred. +func ParseScript(s string) (scr Script, err error) { + defer func() { + if recover() != nil { + scr = 0 + err = ErrSyntax + } + }() + + if len(s) != 4 { + return 0, ErrSyntax + } + var buf [4]byte + return getScriptID(script, buf[:copy(buf[:], s)]) +} + +// EncodeM49 returns the Region for the given UN M.49 code. +// It returns an error if r is not a valid code. +func EncodeM49(r int) (Region, error) { + return getRegionM49(r) +} + +// ParseRegion parses a 2- or 3-letter ISO 3166-1 or a UN M.49 code. +// It returns a ValueError if s is a well-formed but unknown region identifier +// or another error if another error occurred. +func ParseRegion(s string) (r Region, err error) { + defer func() { + if recover() != nil { + r = 0 + err = ErrSyntax + } + }() + + if n := len(s); n < 2 || 3 < n { + return 0, ErrSyntax + } + var buf [3]byte + return getRegionID(buf[:copy(buf[:], s)]) +} + +// IsCountry returns whether this region is a country or autonomous area. This +// includes non-standard definitions from CLDR. +func (r Region) IsCountry() bool { + if r == 0 || r.IsGroup() || r.IsPrivateUse() && r != _XK { + return false + } + return true +} + +// IsGroup returns whether this region defines a collection of regions. This +// includes non-standard definitions from CLDR. +func (r Region) IsGroup() bool { + if r == 0 { + return false + } + return int(regionInclusion[r]) < len(regionContainment) +} + +// Contains returns whether Region c is contained by Region r. It returns true +// if c == r. +func (r Region) Contains(c Region) bool { + if r == c { + return true + } + g := regionInclusion[r] + if g >= nRegionGroups { + return false + } + m := regionContainment[g] + + d := regionInclusion[c] + b := regionInclusionBits[d] + + // A contained country may belong to multiple disjoint groups. Matching any + // of these indicates containment. If the contained region is a group, it + // must strictly be a subset. + if d >= nRegionGroups { + return b&m != 0 + } + return b&^m == 0 +} + +var errNoTLD = errors.New("language: region is not a valid ccTLD") + +// TLD returns the country code top-level domain (ccTLD). UK is returned for GB. +// In all other cases it returns either the region itself or an error. +// +// This method may return an error for a region for which there exists a +// canonical form with a ccTLD. To get that ccTLD canonicalize r first. The +// region will already be canonicalized it was obtained from a Tag that was +// obtained using any of the default methods. +func (r Region) TLD() (Region, error) { + // See http://en.wikipedia.org/wiki/Country_code_top-level_domain for the + // difference between ISO 3166-1 and IANA ccTLD. + if r == _GB { + r = _UK + } + if (r.typ() & ccTLD) == 0 { + return 0, errNoTLD + } + return r, nil +} + +// Canonicalize returns the region or a possible replacement if the region is +// deprecated. It will not return a replacement for deprecated regions that +// are split into multiple regions. +func (r Region) Canonicalize() Region { + if cr := normRegion(r); cr != 0 { + return cr + } + return r +} + +// Variant represents a registered variant of a language as defined by BCP 47. +type Variant struct { + ID uint8 + str string +} + +// ParseVariant parses and returns a Variant. An error is returned if s is not +// a valid variant. +func ParseVariant(s string) (v Variant, err error) { + defer func() { + if recover() != nil { + v = Variant{} + err = ErrSyntax + } + }() + + s = strings.ToLower(s) + if id, ok := variantIndex[s]; ok { + return Variant{id, s}, nil + } + return Variant{}, NewValueError([]byte(s)) +} + +// String returns the string representation of the variant. +func (v Variant) String() string { + return v.str +} diff --git a/vendor/golang.org/x/text/internal/language/lookup.go b/vendor/golang.org/x/text/internal/language/lookup.go new file mode 100644 index 000000000..231b4fbde --- /dev/null +++ b/vendor/golang.org/x/text/internal/language/lookup.go @@ -0,0 +1,412 @@ +// Copyright 2013 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 language + +import ( + "bytes" + "fmt" + "sort" + "strconv" + + "golang.org/x/text/internal/tag" +) + +// findIndex tries to find the given tag in idx and returns a standardized error +// if it could not be found. +func findIndex(idx tag.Index, key []byte, form string) (index int, err error) { + if !tag.FixCase(form, key) { + return 0, ErrSyntax + } + i := idx.Index(key) + if i == -1 { + return 0, NewValueError(key) + } + return i, nil +} + +func searchUint(imap []uint16, key uint16) int { + return sort.Search(len(imap), func(i int) bool { + return imap[i] >= key + }) +} + +type Language uint16 + +// getLangID returns the langID of s if s is a canonical subtag +// or langUnknown if s is not a canonical subtag. +func getLangID(s []byte) (Language, error) { + if len(s) == 2 { + return getLangISO2(s) + } + return getLangISO3(s) +} + +// TODO language normalization as well as the AliasMaps could be moved to the +// higher level package, but it is a bit tricky to separate the generation. + +func (id Language) Canonicalize() (Language, AliasType) { + return normLang(id) +} + +// normLang returns the mapped langID of id according to mapping m. +func normLang(id Language) (Language, AliasType) { + k := sort.Search(len(AliasMap), func(i int) bool { + return AliasMap[i].From >= uint16(id) + }) + if k < len(AliasMap) && AliasMap[k].From == uint16(id) { + return Language(AliasMap[k].To), AliasTypes[k] + } + return id, AliasTypeUnknown +} + +// getLangISO2 returns the langID for the given 2-letter ISO language code +// or unknownLang if this does not exist. +func getLangISO2(s []byte) (Language, error) { + if !tag.FixCase("zz", s) { + return 0, ErrSyntax + } + if i := lang.Index(s); i != -1 && lang.Elem(i)[3] != 0 { + return Language(i), nil + } + return 0, NewValueError(s) +} + +const base = 'z' - 'a' + 1 + +func strToInt(s []byte) uint { + v := uint(0) + for i := 0; i < len(s); i++ { + v *= base + v += uint(s[i] - 'a') + } + return v +} + +// converts the given integer to the original ASCII string passed to strToInt. +// len(s) must match the number of characters obtained. +func intToStr(v uint, s []byte) { + for i := len(s) - 1; i >= 0; i-- { + s[i] = byte(v%base) + 'a' + v /= base + } +} + +// getLangISO3 returns the langID for the given 3-letter ISO language code +// or unknownLang if this does not exist. +func getLangISO3(s []byte) (Language, error) { + if tag.FixCase("und", s) { + // first try to match canonical 3-letter entries + for i := lang.Index(s[:2]); i != -1; i = lang.Next(s[:2], i) { + if e := lang.Elem(i); e[3] == 0 && e[2] == s[2] { + // We treat "und" as special and always translate it to "unspecified". + // Note that ZZ and Zzzz are private use and are not treated as + // unspecified by default. + id := Language(i) + if id == nonCanonicalUnd { + return 0, nil + } + return id, nil + } + } + if i := altLangISO3.Index(s); i != -1 { + return Language(altLangIndex[altLangISO3.Elem(i)[3]]), nil + } + n := strToInt(s) + if langNoIndex[n/8]&(1<<(n%8)) != 0 { + return Language(n) + langNoIndexOffset, nil + } + // Check for non-canonical uses of ISO3. + for i := lang.Index(s[:1]); i != -1; i = lang.Next(s[:1], i) { + if e := lang.Elem(i); e[2] == s[1] && e[3] == s[2] { + return Language(i), nil + } + } + return 0, NewValueError(s) + } + return 0, ErrSyntax +} + +// StringToBuf writes the string to b and returns the number of bytes +// written. cap(b) must be >= 3. +func (id Language) StringToBuf(b []byte) int { + if id >= langNoIndexOffset { + intToStr(uint(id)-langNoIndexOffset, b[:3]) + return 3 + } else if id == 0 { + return copy(b, "und") + } + l := lang[id<<2:] + if l[3] == 0 { + return copy(b, l[:3]) + } + return copy(b, l[:2]) +} + +// String returns the BCP 47 representation of the langID. +// Use b as variable name, instead of id, to ensure the variable +// used is consistent with that of Base in which this type is embedded. +func (b Language) String() string { + if b == 0 { + return "und" + } else if b >= langNoIndexOffset { + b -= langNoIndexOffset + buf := [3]byte{} + intToStr(uint(b), buf[:]) + return string(buf[:]) + } + l := lang.Elem(int(b)) + if l[3] == 0 { + return l[:3] + } + return l[:2] +} + +// ISO3 returns the ISO 639-3 language code. +func (b Language) ISO3() string { + if b == 0 || b >= langNoIndexOffset { + return b.String() + } + l := lang.Elem(int(b)) + if l[3] == 0 { + return l[:3] + } else if l[2] == 0 { + return altLangISO3.Elem(int(l[3]))[:3] + } + // This allocation will only happen for 3-letter ISO codes + // that are non-canonical BCP 47 language identifiers. + return l[0:1] + l[2:4] +} + +// IsPrivateUse reports whether this language code is reserved for private use. +func (b Language) IsPrivateUse() bool { + return langPrivateStart <= b && b <= langPrivateEnd +} + +// SuppressScript returns the script marked as SuppressScript in the IANA +// language tag repository, or 0 if there is no such script. +func (b Language) SuppressScript() Script { + if b < langNoIndexOffset { + return Script(suppressScript[b]) + } + return 0 +} + +type Region uint16 + +// getRegionID returns the region id for s if s is a valid 2-letter region code +// or unknownRegion. +func getRegionID(s []byte) (Region, error) { + if len(s) == 3 { + if isAlpha(s[0]) { + return getRegionISO3(s) + } + if i, err := strconv.ParseUint(string(s), 10, 10); err == nil { + return getRegionM49(int(i)) + } + } + return getRegionISO2(s) +} + +// getRegionISO2 returns the regionID for the given 2-letter ISO country code +// or unknownRegion if this does not exist. +func getRegionISO2(s []byte) (Region, error) { + i, err := findIndex(regionISO, s, "ZZ") + if err != nil { + return 0, err + } + return Region(i) + isoRegionOffset, nil +} + +// getRegionISO3 returns the regionID for the given 3-letter ISO country code +// or unknownRegion if this does not exist. +func getRegionISO3(s []byte) (Region, error) { + if tag.FixCase("ZZZ", s) { + for i := regionISO.Index(s[:1]); i != -1; i = regionISO.Next(s[:1], i) { + if e := regionISO.Elem(i); e[2] == s[1] && e[3] == s[2] { + return Region(i) + isoRegionOffset, nil + } + } + for i := 0; i < len(altRegionISO3); i += 3 { + if tag.Compare(altRegionISO3[i:i+3], s) == 0 { + return Region(altRegionIDs[i/3]), nil + } + } + return 0, NewValueError(s) + } + return 0, ErrSyntax +} + +func getRegionM49(n int) (Region, error) { + if 0 < n && n <= 999 { + const ( + searchBits = 7 + regionBits = 9 + regionMask = 1<> searchBits + buf := fromM49[m49Index[idx]:m49Index[idx+1]] + val := uint16(n) << regionBits // we rely on bits shifting out + i := sort.Search(len(buf), func(i int) bool { + return buf[i] >= val + }) + if r := fromM49[int(m49Index[idx])+i]; r&^regionMask == val { + return Region(r & regionMask), nil + } + } + var e ValueError + fmt.Fprint(bytes.NewBuffer([]byte(e.v[:])), n) + return 0, e +} + +// normRegion returns a region if r is deprecated or 0 otherwise. +// TODO: consider supporting BYS (-> BLR), CSK (-> 200 or CZ), PHI (-> PHL) and AFI (-> DJ). +// TODO: consider mapping split up regions to new most populous one (like CLDR). +func normRegion(r Region) Region { + m := regionOldMap + k := sort.Search(len(m), func(i int) bool { + return m[i].From >= uint16(r) + }) + if k < len(m) && m[k].From == uint16(r) { + return Region(m[k].To) + } + return 0 +} + +const ( + iso3166UserAssigned = 1 << iota + ccTLD + bcp47Region +) + +func (r Region) typ() byte { + return regionTypes[r] +} + +// String returns the BCP 47 representation for the region. +// It returns "ZZ" for an unspecified region. +func (r Region) String() string { + if r < isoRegionOffset { + if r == 0 { + return "ZZ" + } + return fmt.Sprintf("%03d", r.M49()) + } + r -= isoRegionOffset + return regionISO.Elem(int(r))[:2] +} + +// ISO3 returns the 3-letter ISO code of r. +// Note that not all regions have a 3-letter ISO code. +// In such cases this method returns "ZZZ". +func (r Region) ISO3() string { + if r < isoRegionOffset { + return "ZZZ" + } + r -= isoRegionOffset + reg := regionISO.Elem(int(r)) + switch reg[2] { + case 0: + return altRegionISO3[reg[3]:][:3] + case ' ': + return "ZZZ" + } + return reg[0:1] + reg[2:4] +} + +// M49 returns the UN M.49 encoding of r, or 0 if this encoding +// is not defined for r. +func (r Region) M49() int { + return int(m49[r]) +} + +// IsPrivateUse reports whether r has the ISO 3166 User-assigned status. This +// may include private-use tags that are assigned by CLDR and used in this +// implementation. So IsPrivateUse and IsCountry can be simultaneously true. +func (r Region) IsPrivateUse() bool { + return r.typ()&iso3166UserAssigned != 0 +} + +type Script uint16 + +// getScriptID returns the script id for string s. It assumes that s +// is of the format [A-Z][a-z]{3}. +func getScriptID(idx tag.Index, s []byte) (Script, error) { + i, err := findIndex(idx, s, "Zzzz") + return Script(i), err +} + +// String returns the script code in title case. +// It returns "Zzzz" for an unspecified script. +func (s Script) String() string { + if s == 0 { + return "Zzzz" + } + return script.Elem(int(s)) +} + +// IsPrivateUse reports whether this script code is reserved for private use. +func (s Script) IsPrivateUse() bool { + return _Qaaa <= s && s <= _Qabx +} + +const ( + maxAltTaglen = len("en-US-POSIX") + maxLen = maxAltTaglen +) + +var ( + // grandfatheredMap holds a mapping from legacy and grandfathered tags to + // their base language or index to more elaborate tag. + grandfatheredMap = map[[maxLen]byte]int16{ + [maxLen]byte{'a', 'r', 't', '-', 'l', 'o', 'j', 'b', 'a', 'n'}: _jbo, // art-lojban + [maxLen]byte{'i', '-', 'a', 'm', 'i'}: _ami, // i-ami + [maxLen]byte{'i', '-', 'b', 'n', 'n'}: _bnn, // i-bnn + [maxLen]byte{'i', '-', 'h', 'a', 'k'}: _hak, // i-hak + [maxLen]byte{'i', '-', 'k', 'l', 'i', 'n', 'g', 'o', 'n'}: _tlh, // i-klingon + [maxLen]byte{'i', '-', 'l', 'u', 'x'}: _lb, // i-lux + [maxLen]byte{'i', '-', 'n', 'a', 'v', 'a', 'j', 'o'}: _nv, // i-navajo + [maxLen]byte{'i', '-', 'p', 'w', 'n'}: _pwn, // i-pwn + [maxLen]byte{'i', '-', 't', 'a', 'o'}: _tao, // i-tao + [maxLen]byte{'i', '-', 't', 'a', 'y'}: _tay, // i-tay + [maxLen]byte{'i', '-', 't', 's', 'u'}: _tsu, // i-tsu + [maxLen]byte{'n', 'o', '-', 'b', 'o', 'k'}: _nb, // no-bok + [maxLen]byte{'n', 'o', '-', 'n', 'y', 'n'}: _nn, // no-nyn + [maxLen]byte{'s', 'g', 'n', '-', 'b', 'e', '-', 'f', 'r'}: _sfb, // sgn-BE-FR + [maxLen]byte{'s', 'g', 'n', '-', 'b', 'e', '-', 'n', 'l'}: _vgt, // sgn-BE-NL + [maxLen]byte{'s', 'g', 'n', '-', 'c', 'h', '-', 'd', 'e'}: _sgg, // sgn-CH-DE + [maxLen]byte{'z', 'h', '-', 'g', 'u', 'o', 'y', 'u'}: _cmn, // zh-guoyu + [maxLen]byte{'z', 'h', '-', 'h', 'a', 'k', 'k', 'a'}: _hak, // zh-hakka + [maxLen]byte{'z', 'h', '-', 'm', 'i', 'n', '-', 'n', 'a', 'n'}: _nan, // zh-min-nan + [maxLen]byte{'z', 'h', '-', 'x', 'i', 'a', 'n', 'g'}: _hsn, // zh-xiang + + // Grandfathered tags with no modern replacement will be converted as + // follows: + [maxLen]byte{'c', 'e', 'l', '-', 'g', 'a', 'u', 'l', 'i', 's', 'h'}: -1, // cel-gaulish + [maxLen]byte{'e', 'n', '-', 'g', 'b', '-', 'o', 'e', 'd'}: -2, // en-GB-oed + [maxLen]byte{'i', '-', 'd', 'e', 'f', 'a', 'u', 'l', 't'}: -3, // i-default + [maxLen]byte{'i', '-', 'e', 'n', 'o', 'c', 'h', 'i', 'a', 'n'}: -4, // i-enochian + [maxLen]byte{'i', '-', 'm', 'i', 'n', 'g', 'o'}: -5, // i-mingo + [maxLen]byte{'z', 'h', '-', 'm', 'i', 'n'}: -6, // zh-min + + // CLDR-specific tag. + [maxLen]byte{'r', 'o', 'o', 't'}: 0, // root + [maxLen]byte{'e', 'n', '-', 'u', 's', '-', 'p', 'o', 's', 'i', 'x'}: -7, // en_US_POSIX" + } + + altTagIndex = [...]uint8{0, 17, 31, 45, 61, 74, 86, 102} + + altTags = "xtg-x-cel-gaulishen-GB-oxendicten-x-i-defaultund-x-i-enochiansee-x-i-mingonan-x-zh-minen-US-u-va-posix" +) + +func grandfathered(s [maxAltTaglen]byte) (t Tag, ok bool) { + if v, ok := grandfatheredMap[s]; ok { + if v < 0 { + return Make(altTags[altTagIndex[-v-1]:altTagIndex[-v]]), true + } + t.LangID = Language(v) + return t, true + } + return t, false +} diff --git a/vendor/golang.org/x/text/internal/language/match.go b/vendor/golang.org/x/text/internal/language/match.go new file mode 100644 index 000000000..75a2dbca7 --- /dev/null +++ b/vendor/golang.org/x/text/internal/language/match.go @@ -0,0 +1,226 @@ +// Copyright 2013 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 language + +import "errors" + +type scriptRegionFlags uint8 + +const ( + isList = 1 << iota + scriptInFrom + regionInFrom +) + +func (t *Tag) setUndefinedLang(id Language) { + if t.LangID == 0 { + t.LangID = id + } +} + +func (t *Tag) setUndefinedScript(id Script) { + if t.ScriptID == 0 { + t.ScriptID = id + } +} + +func (t *Tag) setUndefinedRegion(id Region) { + if t.RegionID == 0 || t.RegionID.Contains(id) { + t.RegionID = id + } +} + +// ErrMissingLikelyTagsData indicates no information was available +// to compute likely values of missing tags. +var ErrMissingLikelyTagsData = errors.New("missing likely tags data") + +// addLikelySubtags sets subtags to their most likely value, given the locale. +// In most cases this means setting fields for unknown values, but in some +// cases it may alter a value. It returns an ErrMissingLikelyTagsData error +// if the given locale cannot be expanded. +func (t Tag) addLikelySubtags() (Tag, error) { + id, err := addTags(t) + if err != nil { + return t, err + } else if id.equalTags(t) { + return t, nil + } + id.RemakeString() + return id, nil +} + +// specializeRegion attempts to specialize a group region. +func specializeRegion(t *Tag) bool { + if i := regionInclusion[t.RegionID]; i < nRegionGroups { + x := likelyRegionGroup[i] + if Language(x.lang) == t.LangID && Script(x.script) == t.ScriptID { + t.RegionID = Region(x.region) + } + return true + } + return false +} + +// Maximize returns a new tag with missing tags filled in. +func (t Tag) Maximize() (Tag, error) { + return addTags(t) +} + +func addTags(t Tag) (Tag, error) { + // We leave private use identifiers alone. + if t.IsPrivateUse() { + return t, nil + } + if t.ScriptID != 0 && t.RegionID != 0 { + if t.LangID != 0 { + // already fully specified + specializeRegion(&t) + return t, nil + } + // Search matches for und-script-region. Note that for these cases + // region will never be a group so there is no need to check for this. + list := likelyRegion[t.RegionID : t.RegionID+1] + if x := list[0]; x.flags&isList != 0 { + list = likelyRegionList[x.lang : x.lang+uint16(x.script)] + } + for _, x := range list { + // Deviating from the spec. See match_test.go for details. + if Script(x.script) == t.ScriptID { + t.setUndefinedLang(Language(x.lang)) + return t, nil + } + } + } + if t.LangID != 0 { + // Search matches for lang-script and lang-region, where lang != und. + if t.LangID < langNoIndexOffset { + x := likelyLang[t.LangID] + if x.flags&isList != 0 { + list := likelyLangList[x.region : x.region+uint16(x.script)] + if t.ScriptID != 0 { + for _, x := range list { + if Script(x.script) == t.ScriptID && x.flags&scriptInFrom != 0 { + t.setUndefinedRegion(Region(x.region)) + return t, nil + } + } + } else if t.RegionID != 0 { + count := 0 + goodScript := true + tt := t + for _, x := range list { + // We visit all entries for which the script was not + // defined, including the ones where the region was not + // defined. This allows for proper disambiguation within + // regions. + if x.flags&scriptInFrom == 0 && t.RegionID.Contains(Region(x.region)) { + tt.RegionID = Region(x.region) + tt.setUndefinedScript(Script(x.script)) + goodScript = goodScript && tt.ScriptID == Script(x.script) + count++ + } + } + if count == 1 { + return tt, nil + } + // Even if we fail to find a unique Region, we might have + // an unambiguous script. + if goodScript { + t.ScriptID = tt.ScriptID + } + } + } + } + } else { + // Search matches for und-script. + if t.ScriptID != 0 { + x := likelyScript[t.ScriptID] + if x.region != 0 { + t.setUndefinedRegion(Region(x.region)) + t.setUndefinedLang(Language(x.lang)) + return t, nil + } + } + // Search matches for und-region. If und-script-region exists, it would + // have been found earlier. + if t.RegionID != 0 { + if i := regionInclusion[t.RegionID]; i < nRegionGroups { + x := likelyRegionGroup[i] + if x.region != 0 { + t.setUndefinedLang(Language(x.lang)) + t.setUndefinedScript(Script(x.script)) + t.RegionID = Region(x.region) + } + } else { + x := likelyRegion[t.RegionID] + if x.flags&isList != 0 { + x = likelyRegionList[x.lang] + } + if x.script != 0 && x.flags != scriptInFrom { + t.setUndefinedLang(Language(x.lang)) + t.setUndefinedScript(Script(x.script)) + return t, nil + } + } + } + } + + // Search matches for lang. + if t.LangID < langNoIndexOffset { + x := likelyLang[t.LangID] + if x.flags&isList != 0 { + x = likelyLangList[x.region] + } + if x.region != 0 { + t.setUndefinedScript(Script(x.script)) + t.setUndefinedRegion(Region(x.region)) + } + specializeRegion(&t) + if t.LangID == 0 { + t.LangID = _en // default language + } + return t, nil + } + return t, ErrMissingLikelyTagsData +} + +func (t *Tag) setTagsFrom(id Tag) { + t.LangID = id.LangID + t.ScriptID = id.ScriptID + t.RegionID = id.RegionID +} + +// minimize removes the region or script subtags from t such that +// t.addLikelySubtags() == t.minimize().addLikelySubtags(). +func (t Tag) minimize() (Tag, error) { + t, err := minimizeTags(t) + if err != nil { + return t, err + } + t.RemakeString() + return t, nil +} + +// minimizeTags mimics the behavior of the ICU 51 C implementation. +func minimizeTags(t Tag) (Tag, error) { + if t.equalTags(Und) { + return t, nil + } + max, err := addTags(t) + if err != nil { + return t, err + } + for _, id := range [...]Tag{ + {LangID: t.LangID}, + {LangID: t.LangID, RegionID: t.RegionID}, + {LangID: t.LangID, ScriptID: t.ScriptID}, + } { + if x, err := addTags(id); err == nil && max.equalTags(x) { + t.setTagsFrom(id) + break + } + } + return t, nil +} diff --git a/vendor/golang.org/x/text/internal/language/parse.go b/vendor/golang.org/x/text/internal/language/parse.go new file mode 100644 index 000000000..aad1e0acf --- /dev/null +++ b/vendor/golang.org/x/text/internal/language/parse.go @@ -0,0 +1,608 @@ +// Copyright 2013 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 language + +import ( + "bytes" + "errors" + "fmt" + "sort" + + "golang.org/x/text/internal/tag" +) + +// isAlpha returns true if the byte is not a digit. +// b must be an ASCII letter or digit. +func isAlpha(b byte) bool { + return b > '9' +} + +// isAlphaNum returns true if the string contains only ASCII letters or digits. +func isAlphaNum(s []byte) bool { + for _, c := range s { + if !('a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || '0' <= c && c <= '9') { + return false + } + } + return true +} + +// ErrSyntax is returned by any of the parsing functions when the +// input is not well-formed, according to BCP 47. +// TODO: return the position at which the syntax error occurred? +var ErrSyntax = errors.New("language: tag is not well-formed") + +// ErrDuplicateKey is returned when a tag contains the same key twice with +// different values in the -u section. +var ErrDuplicateKey = errors.New("language: different values for same key in -u extension") + +// ValueError is returned by any of the parsing functions when the +// input is well-formed but the respective subtag is not recognized +// as a valid value. +type ValueError struct { + v [8]byte +} + +// NewValueError creates a new ValueError. +func NewValueError(tag []byte) ValueError { + var e ValueError + copy(e.v[:], tag) + return e +} + +func (e ValueError) tag() []byte { + n := bytes.IndexByte(e.v[:], 0) + if n == -1 { + n = 8 + } + return e.v[:n] +} + +// Error implements the error interface. +func (e ValueError) Error() string { + return fmt.Sprintf("language: subtag %q is well-formed but unknown", e.tag()) +} + +// Subtag returns the subtag for which the error occurred. +func (e ValueError) Subtag() string { + return string(e.tag()) +} + +// scanner is used to scan BCP 47 tokens, which are separated by _ or -. +type scanner struct { + b []byte + bytes [max99thPercentileSize]byte + token []byte + start int // start position of the current token + end int // end position of the current token + next int // next point for scan + err error + done bool +} + +func makeScannerString(s string) scanner { + scan := scanner{} + if len(s) <= len(scan.bytes) { + scan.b = scan.bytes[:copy(scan.bytes[:], s)] + } else { + scan.b = []byte(s) + } + scan.init() + return scan +} + +// makeScanner returns a scanner using b as the input buffer. +// b is not copied and may be modified by the scanner routines. +func makeScanner(b []byte) scanner { + scan := scanner{b: b} + scan.init() + return scan +} + +func (s *scanner) init() { + for i, c := range s.b { + if c == '_' { + s.b[i] = '-' + } + } + s.scan() +} + +// restToLower converts the string between start and end to lower case. +func (s *scanner) toLower(start, end int) { + for i := start; i < end; i++ { + c := s.b[i] + if 'A' <= c && c <= 'Z' { + s.b[i] += 'a' - 'A' + } + } +} + +func (s *scanner) setError(e error) { + if s.err == nil || (e == ErrSyntax && s.err != ErrSyntax) { + s.err = e + } +} + +// resizeRange shrinks or grows the array at position oldStart such that +// a new string of size newSize can fit between oldStart and oldEnd. +// Sets the scan point to after the resized range. +func (s *scanner) resizeRange(oldStart, oldEnd, newSize int) { + s.start = oldStart + if end := oldStart + newSize; end != oldEnd { + diff := end - oldEnd + var b []byte + if n := len(s.b) + diff; n > cap(s.b) { + b = make([]byte, n) + copy(b, s.b[:oldStart]) + } else { + b = s.b[:n] + } + copy(b[end:], s.b[oldEnd:]) + s.b = b + s.next = end + (s.next - s.end) + s.end = end + } +} + +// replace replaces the current token with repl. +func (s *scanner) replace(repl string) { + s.resizeRange(s.start, s.end, len(repl)) + copy(s.b[s.start:], repl) +} + +// gobble removes the current token from the input. +// Caller must call scan after calling gobble. +func (s *scanner) gobble(e error) { + s.setError(e) + if s.start == 0 { + s.b = s.b[:+copy(s.b, s.b[s.next:])] + s.end = 0 + } else { + s.b = s.b[:s.start-1+copy(s.b[s.start-1:], s.b[s.end:])] + s.end = s.start - 1 + } + s.next = s.start +} + +// deleteRange removes the given range from s.b before the current token. +func (s *scanner) deleteRange(start, end int) { + s.b = s.b[:start+copy(s.b[start:], s.b[end:])] + diff := end - start + s.next -= diff + s.start -= diff + s.end -= diff +} + +// scan parses the next token of a BCP 47 string. Tokens that are larger +// than 8 characters or include non-alphanumeric characters result in an error +// and are gobbled and removed from the output. +// It returns the end position of the last token consumed. +func (s *scanner) scan() (end int) { + end = s.end + s.token = nil + for s.start = s.next; s.next < len(s.b); { + i := bytes.IndexByte(s.b[s.next:], '-') + if i == -1 { + s.end = len(s.b) + s.next = len(s.b) + i = s.end - s.start + } else { + s.end = s.next + i + s.next = s.end + 1 + } + token := s.b[s.start:s.end] + if i < 1 || i > 8 || !isAlphaNum(token) { + s.gobble(ErrSyntax) + continue + } + s.token = token + return end + } + if n := len(s.b); n > 0 && s.b[n-1] == '-' { + s.setError(ErrSyntax) + s.b = s.b[:len(s.b)-1] + } + s.done = true + return end +} + +// acceptMinSize parses multiple tokens of the given size or greater. +// It returns the end position of the last token consumed. +func (s *scanner) acceptMinSize(min int) (end int) { + end = s.end + s.scan() + for ; len(s.token) >= min; s.scan() { + end = s.end + } + return end +} + +// Parse parses the given BCP 47 string and returns a valid Tag. If parsing +// failed it returns an error and any part of the tag that could be parsed. +// If parsing succeeded but an unknown value was found, it returns +// ValueError. The Tag returned in this case is just stripped of the unknown +// value. All other values are preserved. It accepts tags in the BCP 47 format +// and extensions to this standard defined in +// https://www.unicode.org/reports/tr35/#Unicode_Language_and_Locale_Identifiers. +func Parse(s string) (t Tag, err error) { + // TODO: consider supporting old-style locale key-value pairs. + if s == "" { + return Und, ErrSyntax + } + defer func() { + if recover() != nil { + t = Und + err = ErrSyntax + return + } + }() + if len(s) <= maxAltTaglen { + b := [maxAltTaglen]byte{} + for i, c := range s { + // Generating invalid UTF-8 is okay as it won't match. + if 'A' <= c && c <= 'Z' { + c += 'a' - 'A' + } else if c == '_' { + c = '-' + } + b[i] = byte(c) + } + if t, ok := grandfathered(b); ok { + return t, nil + } + } + scan := makeScannerString(s) + return parse(&scan, s) +} + +func parse(scan *scanner, s string) (t Tag, err error) { + t = Und + var end int + if n := len(scan.token); n <= 1 { + scan.toLower(0, len(scan.b)) + if n == 0 || scan.token[0] != 'x' { + return t, ErrSyntax + } + end = parseExtensions(scan) + } else if n >= 4 { + return Und, ErrSyntax + } else { // the usual case + t, end = parseTag(scan, true) + if n := len(scan.token); n == 1 { + t.pExt = uint16(end) + end = parseExtensions(scan) + } else if end < len(scan.b) { + scan.setError(ErrSyntax) + scan.b = scan.b[:end] + } + } + if int(t.pVariant) < len(scan.b) { + if end < len(s) { + s = s[:end] + } + if len(s) > 0 && tag.Compare(s, scan.b) == 0 { + t.str = s + } else { + t.str = string(scan.b) + } + } else { + t.pVariant, t.pExt = 0, 0 + } + return t, scan.err +} + +// parseTag parses language, script, region and variants. +// It returns a Tag and the end position in the input that was parsed. +// If doNorm is true, then - will be normalized to . +func parseTag(scan *scanner, doNorm bool) (t Tag, end int) { + var e error + // TODO: set an error if an unknown lang, script or region is encountered. + t.LangID, e = getLangID(scan.token) + scan.setError(e) + scan.replace(t.LangID.String()) + langStart := scan.start + end = scan.scan() + for len(scan.token) == 3 && isAlpha(scan.token[0]) { + // From http://tools.ietf.org/html/bcp47, - tags are equivalent + // to a tag of the form . + if doNorm { + lang, e := getLangID(scan.token) + if lang != 0 { + t.LangID = lang + langStr := lang.String() + copy(scan.b[langStart:], langStr) + scan.b[langStart+len(langStr)] = '-' + scan.start = langStart + len(langStr) + 1 + } + scan.gobble(e) + } + end = scan.scan() + } + if len(scan.token) == 4 && isAlpha(scan.token[0]) { + t.ScriptID, e = getScriptID(script, scan.token) + if t.ScriptID == 0 { + scan.gobble(e) + } + end = scan.scan() + } + if n := len(scan.token); n >= 2 && n <= 3 { + t.RegionID, e = getRegionID(scan.token) + if t.RegionID == 0 { + scan.gobble(e) + } else { + scan.replace(t.RegionID.String()) + } + end = scan.scan() + } + scan.toLower(scan.start, len(scan.b)) + t.pVariant = byte(end) + end = parseVariants(scan, end, t) + t.pExt = uint16(end) + return t, end +} + +var separator = []byte{'-'} + +// parseVariants scans tokens as long as each token is a valid variant string. +// Duplicate variants are removed. +func parseVariants(scan *scanner, end int, t Tag) int { + start := scan.start + varIDBuf := [4]uint8{} + variantBuf := [4][]byte{} + varID := varIDBuf[:0] + variant := variantBuf[:0] + last := -1 + needSort := false + for ; len(scan.token) >= 4; scan.scan() { + // TODO: measure the impact of needing this conversion and redesign + // the data structure if there is an issue. + v, ok := variantIndex[string(scan.token)] + if !ok { + // unknown variant + // TODO: allow user-defined variants? + scan.gobble(NewValueError(scan.token)) + continue + } + varID = append(varID, v) + variant = append(variant, scan.token) + if !needSort { + if last < int(v) { + last = int(v) + } else { + needSort = true + // There is no legal combinations of more than 7 variants + // (and this is by no means a useful sequence). + const maxVariants = 8 + if len(varID) > maxVariants { + break + } + } + } + end = scan.end + } + if needSort { + sort.Sort(variantsSort{varID, variant}) + k, l := 0, -1 + for i, v := range varID { + w := int(v) + if l == w { + // Remove duplicates. + continue + } + varID[k] = varID[i] + variant[k] = variant[i] + k++ + l = w + } + if str := bytes.Join(variant[:k], separator); len(str) == 0 { + end = start - 1 + } else { + scan.resizeRange(start, end, len(str)) + copy(scan.b[scan.start:], str) + end = scan.end + } + } + return end +} + +type variantsSort struct { + i []uint8 + v [][]byte +} + +func (s variantsSort) Len() int { + return len(s.i) +} + +func (s variantsSort) Swap(i, j int) { + s.i[i], s.i[j] = s.i[j], s.i[i] + s.v[i], s.v[j] = s.v[j], s.v[i] +} + +func (s variantsSort) Less(i, j int) bool { + return s.i[i] < s.i[j] +} + +type bytesSort struct { + b [][]byte + n int // first n bytes to compare +} + +func (b bytesSort) Len() int { + return len(b.b) +} + +func (b bytesSort) Swap(i, j int) { + b.b[i], b.b[j] = b.b[j], b.b[i] +} + +func (b bytesSort) Less(i, j int) bool { + for k := 0; k < b.n; k++ { + if b.b[i][k] == b.b[j][k] { + continue + } + return b.b[i][k] < b.b[j][k] + } + return false +} + +// parseExtensions parses and normalizes the extensions in the buffer. +// It returns the last position of scan.b that is part of any extension. +// It also trims scan.b to remove excess parts accordingly. +func parseExtensions(scan *scanner) int { + start := scan.start + exts := [][]byte{} + private := []byte{} + end := scan.end + for len(scan.token) == 1 { + extStart := scan.start + ext := scan.token[0] + end = parseExtension(scan) + extension := scan.b[extStart:end] + if len(extension) < 3 || (ext != 'x' && len(extension) < 4) { + scan.setError(ErrSyntax) + end = extStart + continue + } else if start == extStart && (ext == 'x' || scan.start == len(scan.b)) { + scan.b = scan.b[:end] + return end + } else if ext == 'x' { + private = extension + break + } + exts = append(exts, extension) + } + sort.Sort(bytesSort{exts, 1}) + if len(private) > 0 { + exts = append(exts, private) + } + scan.b = scan.b[:start] + if len(exts) > 0 { + scan.b = append(scan.b, bytes.Join(exts, separator)...) + } else if start > 0 { + // Strip trailing '-'. + scan.b = scan.b[:start-1] + } + return end +} + +// parseExtension parses a single extension and returns the position of +// the extension end. +func parseExtension(scan *scanner) int { + start, end := scan.start, scan.end + switch scan.token[0] { + case 'u': // https://www.ietf.org/rfc/rfc6067.txt + attrStart := end + scan.scan() + for last := []byte{}; len(scan.token) > 2; scan.scan() { + if bytes.Compare(scan.token, last) != -1 { + // Attributes are unsorted. Start over from scratch. + p := attrStart + 1 + scan.next = p + attrs := [][]byte{} + for scan.scan(); len(scan.token) > 2; scan.scan() { + attrs = append(attrs, scan.token) + end = scan.end + } + sort.Sort(bytesSort{attrs, 3}) + copy(scan.b[p:], bytes.Join(attrs, separator)) + break + } + last = scan.token + end = scan.end + } + // Scan key-type sequences. A key is of length 2 and may be followed + // by 0 or more "type" subtags from 3 to the maximum of 8 letters. + var last, key []byte + for attrEnd := end; len(scan.token) == 2; last = key { + key = scan.token + end = scan.end + for scan.scan(); end < scan.end && len(scan.token) > 2; scan.scan() { + end = scan.end + } + // TODO: check key value validity + if bytes.Compare(key, last) != 1 || scan.err != nil { + // We have an invalid key or the keys are not sorted. + // Start scanning keys from scratch and reorder. + p := attrEnd + 1 + scan.next = p + keys := [][]byte{} + for scan.scan(); len(scan.token) == 2; { + keyStart := scan.start + end = scan.end + for scan.scan(); end < scan.end && len(scan.token) > 2; scan.scan() { + end = scan.end + } + keys = append(keys, scan.b[keyStart:end]) + } + sort.Stable(bytesSort{keys, 2}) + if n := len(keys); n > 0 { + k := 0 + for i := 1; i < n; i++ { + if !bytes.Equal(keys[k][:2], keys[i][:2]) { + k++ + keys[k] = keys[i] + } else if !bytes.Equal(keys[k], keys[i]) { + scan.setError(ErrDuplicateKey) + } + } + keys = keys[:k+1] + } + reordered := bytes.Join(keys, separator) + if e := p + len(reordered); e < end { + scan.deleteRange(e, end) + end = e + } + copy(scan.b[p:], reordered) + break + } + } + case 't': // https://www.ietf.org/rfc/rfc6497.txt + scan.scan() + if n := len(scan.token); n >= 2 && n <= 3 && isAlpha(scan.token[1]) { + _, end = parseTag(scan, false) + scan.toLower(start, end) + } + for len(scan.token) == 2 && !isAlpha(scan.token[1]) { + end = scan.acceptMinSize(3) + } + case 'x': + end = scan.acceptMinSize(1) + default: + end = scan.acceptMinSize(2) + } + return end +} + +// getExtension returns the name, body and end position of the extension. +func getExtension(s string, p int) (end int, ext string) { + if s[p] == '-' { + p++ + } + if s[p] == 'x' { + return len(s), s[p:] + } + end = nextExtension(s, p) + return end, s[p:end] +} + +// nextExtension finds the next extension within the string, searching +// for the -- pattern from position p. +// In the fast majority of cases, language tags will have at most +// one extension and extensions tend to be small. +func nextExtension(s string, p int) int { + for n := len(s) - 3; p < n; { + if s[p] == '-' { + if s[p+2] == '-' { + return p + } + p += 3 + } else { + p++ + } + } + return len(s) +} diff --git a/vendor/golang.org/x/text/internal/language/tables.go b/vendor/golang.org/x/text/internal/language/tables.go new file mode 100644 index 000000000..14167e74e --- /dev/null +++ b/vendor/golang.org/x/text/internal/language/tables.go @@ -0,0 +1,3494 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +package language + +import "golang.org/x/text/internal/tag" + +// CLDRVersion is the CLDR version from which the tables in this package are derived. +const CLDRVersion = "32" + +const NumLanguages = 8798 + +const NumScripts = 261 + +const NumRegions = 358 + +type FromTo struct { + From uint16 + To uint16 +} + +const nonCanonicalUnd = 1201 +const ( + _af = 22 + _am = 39 + _ar = 58 + _az = 88 + _bg = 126 + _bn = 165 + _ca = 215 + _cs = 250 + _da = 257 + _de = 269 + _el = 310 + _en = 313 + _es = 318 + _et = 320 + _fa = 328 + _fi = 337 + _fil = 339 + _fr = 350 + _gu = 420 + _he = 444 + _hi = 446 + _hr = 465 + _hu = 469 + _hy = 471 + _id = 481 + _is = 504 + _it = 505 + _ja = 512 + _ka = 528 + _kk = 578 + _km = 586 + _kn = 593 + _ko = 596 + _ky = 650 + _lo = 696 + _lt = 704 + _lv = 711 + _mk = 767 + _ml = 772 + _mn = 779 + _mo = 784 + _mr = 795 + _ms = 799 + _mul = 806 + _my = 817 + _nb = 839 + _ne = 849 + _nl = 871 + _no = 879 + _pa = 925 + _pl = 947 + _pt = 960 + _ro = 988 + _ru = 994 + _sh = 1031 + _si = 1036 + _sk = 1042 + _sl = 1046 + _sq = 1073 + _sr = 1074 + _sv = 1092 + _sw = 1093 + _ta = 1104 + _te = 1121 + _th = 1131 + _tl = 1146 + _tn = 1152 + _tr = 1162 + _uk = 1198 + _ur = 1204 + _uz = 1212 + _vi = 1219 + _zh = 1321 + _zu = 1327 + _jbo = 515 + _ami = 1650 + _bnn = 2357 + _hak = 438 + _tlh = 14467 + _lb = 661 + _nv = 899 + _pwn = 12055 + _tao = 14188 + _tay = 14198 + _tsu = 14662 + _nn = 874 + _sfb = 13629 + _vgt = 15701 + _sgg = 13660 + _cmn = 3007 + _nan = 835 + _hsn = 467 +) + +const langPrivateStart = 0x2f72 + +const langPrivateEnd = 0x3179 + +// lang holds an alphabetically sorted list of ISO-639 language identifiers. +// All entries are 4 bytes. The index of the identifier (divided by 4) is the language tag. +// For 2-byte language identifiers, the two successive bytes have the following meaning: +// - if the first letter of the 2- and 3-letter ISO codes are the same: +// the second and third letter of the 3-letter ISO code. +// - otherwise: a 0 and a by 2 bits right-shifted index into altLangISO3. +// +// For 3-byte language identifiers the 4th byte is 0. +const lang tag.Index = "" + // Size: 5324 bytes + "---\x00aaaraai\x00aak\x00aau\x00abbkabi\x00abq\x00abr\x00abt\x00aby\x00a" + + "cd\x00ace\x00ach\x00ada\x00ade\x00adj\x00ady\x00adz\x00aeveaeb\x00aey" + + "\x00affragc\x00agd\x00agg\x00agm\x00ago\x00agq\x00aha\x00ahl\x00aho\x00a" + + "jg\x00akkaakk\x00ala\x00ali\x00aln\x00alt\x00ammhamm\x00amn\x00amo\x00am" + + "p\x00anrganc\x00ank\x00ann\x00any\x00aoj\x00aom\x00aoz\x00apc\x00apd\x00" + + "ape\x00apr\x00aps\x00apz\x00arraarc\x00arh\x00arn\x00aro\x00arq\x00ars" + + "\x00ary\x00arz\x00assmasa\x00ase\x00asg\x00aso\x00ast\x00ata\x00atg\x00a" + + "tj\x00auy\x00avvaavl\x00avn\x00avt\x00avu\x00awa\x00awb\x00awo\x00awx" + + "\x00ayymayb\x00azzebaakbal\x00ban\x00bap\x00bar\x00bas\x00bav\x00bax\x00" + + "bba\x00bbb\x00bbc\x00bbd\x00bbj\x00bbp\x00bbr\x00bcf\x00bch\x00bci\x00bc" + + "m\x00bcn\x00bco\x00bcq\x00bcu\x00bdd\x00beelbef\x00beh\x00bej\x00bem\x00" + + "bet\x00bew\x00bex\x00bez\x00bfd\x00bfq\x00bft\x00bfy\x00bgulbgc\x00bgn" + + "\x00bgx\x00bhihbhb\x00bhg\x00bhi\x00bhk\x00bhl\x00bho\x00bhy\x00biisbib" + + "\x00big\x00bik\x00bim\x00bin\x00bio\x00biq\x00bjh\x00bji\x00bjj\x00bjn" + + "\x00bjo\x00bjr\x00bjt\x00bjz\x00bkc\x00bkm\x00bkq\x00bku\x00bkv\x00blt" + + "\x00bmambmh\x00bmk\x00bmq\x00bmu\x00bnenbng\x00bnm\x00bnp\x00boodboj\x00" + + "bom\x00bon\x00bpy\x00bqc\x00bqi\x00bqp\x00bqv\x00brrebra\x00brh\x00brx" + + "\x00brz\x00bsosbsj\x00bsq\x00bss\x00bst\x00bto\x00btt\x00btv\x00bua\x00b" + + "uc\x00bud\x00bug\x00buk\x00bum\x00buo\x00bus\x00buu\x00bvb\x00bwd\x00bwr" + + "\x00bxh\x00bye\x00byn\x00byr\x00bys\x00byv\x00byx\x00bza\x00bze\x00bzf" + + "\x00bzh\x00bzw\x00caatcan\x00cbj\x00cch\x00ccp\x00ceheceb\x00cfa\x00cgg" + + "\x00chhachk\x00chm\x00cho\x00chp\x00chr\x00cja\x00cjm\x00cjv\x00ckb\x00c" + + "kl\x00cko\x00cky\x00cla\x00cme\x00cmg\x00cooscop\x00cps\x00crrecrh\x00cr" + + "j\x00crk\x00crl\x00crm\x00crs\x00csescsb\x00csw\x00ctd\x00cuhucvhvcyymda" + + "andad\x00daf\x00dag\x00dah\x00dak\x00dar\x00dav\x00dbd\x00dbq\x00dcc\x00" + + "ddn\x00deeuded\x00den\x00dga\x00dgh\x00dgi\x00dgl\x00dgr\x00dgz\x00dia" + + "\x00dje\x00dnj\x00dob\x00doi\x00dop\x00dow\x00dri\x00drs\x00dsb\x00dtm" + + "\x00dtp\x00dts\x00dty\x00dua\x00duc\x00dud\x00dug\x00dvivdva\x00dww\x00d" + + "yo\x00dyu\x00dzzodzg\x00ebu\x00eeweefi\x00egl\x00egy\x00eka\x00eky\x00el" + + "llema\x00emi\x00enngenn\x00enq\x00eopoeri\x00es\x00\x05esu\x00etstetr" + + "\x00ett\x00etu\x00etx\x00euusewo\x00ext\x00faasfaa\x00fab\x00fag\x00fai" + + "\x00fan\x00ffulffi\x00ffm\x00fiinfia\x00fil\x00fit\x00fjijflr\x00fmp\x00" + + "foaofod\x00fon\x00for\x00fpe\x00fqs\x00frrafrc\x00frp\x00frr\x00frs\x00f" + + "ub\x00fud\x00fue\x00fuf\x00fuh\x00fuq\x00fur\x00fuv\x00fuy\x00fvr\x00fyr" + + "ygalegaa\x00gaf\x00gag\x00gah\x00gaj\x00gam\x00gan\x00gaw\x00gay\x00gba" + + "\x00gbf\x00gbm\x00gby\x00gbz\x00gcr\x00gdlagde\x00gdn\x00gdr\x00geb\x00g" + + "ej\x00gel\x00gez\x00gfk\x00ggn\x00ghs\x00gil\x00gim\x00gjk\x00gjn\x00gju" + + "\x00gkn\x00gkp\x00gllgglk\x00gmm\x00gmv\x00gnrngnd\x00gng\x00god\x00gof" + + "\x00goi\x00gom\x00gon\x00gor\x00gos\x00got\x00grb\x00grc\x00grt\x00grw" + + "\x00gsw\x00guujgub\x00guc\x00gud\x00gur\x00guw\x00gux\x00guz\x00gvlvgvf" + + "\x00gvr\x00gvs\x00gwc\x00gwi\x00gwt\x00gyi\x00haauhag\x00hak\x00ham\x00h" + + "aw\x00haz\x00hbb\x00hdy\x00heebhhy\x00hiinhia\x00hif\x00hig\x00hih\x00hi" + + "l\x00hla\x00hlu\x00hmd\x00hmt\x00hnd\x00hne\x00hnj\x00hnn\x00hno\x00homo" + + "hoc\x00hoj\x00hot\x00hrrvhsb\x00hsn\x00htathuunhui\x00hyyehzerianaian" + + "\x00iar\x00iba\x00ibb\x00iby\x00ica\x00ich\x00idndidd\x00idi\x00idu\x00i" + + "eleife\x00igboigb\x00ige\x00iiiiijj\x00ikpkikk\x00ikt\x00ikw\x00ikx\x00i" + + "lo\x00imo\x00inndinh\x00iodoiou\x00iri\x00isslittaiukuiw\x00\x03iwm\x00i" + + "ws\x00izh\x00izi\x00japnjab\x00jam\x00jbo\x00jbu\x00jen\x00jgk\x00jgo" + + "\x00ji\x00\x06jib\x00jmc\x00jml\x00jra\x00jut\x00jvavjwavkaatkaa\x00kab" + + "\x00kac\x00kad\x00kai\x00kaj\x00kam\x00kao\x00kbd\x00kbm\x00kbp\x00kbq" + + "\x00kbx\x00kby\x00kcg\x00kck\x00kcl\x00kct\x00kde\x00kdh\x00kdl\x00kdt" + + "\x00kea\x00ken\x00kez\x00kfo\x00kfr\x00kfy\x00kgonkge\x00kgf\x00kgp\x00k" + + "ha\x00khb\x00khn\x00khq\x00khs\x00kht\x00khw\x00khz\x00kiikkij\x00kiu" + + "\x00kiw\x00kjuakjd\x00kjg\x00kjs\x00kjy\x00kkazkkc\x00kkj\x00klalkln\x00" + + "klq\x00klt\x00klx\x00kmhmkmb\x00kmh\x00kmo\x00kms\x00kmu\x00kmw\x00knank" + + "nf\x00knp\x00koorkoi\x00kok\x00kol\x00kos\x00koz\x00kpe\x00kpf\x00kpo" + + "\x00kpr\x00kpx\x00kqb\x00kqf\x00kqs\x00kqy\x00kraukrc\x00kri\x00krj\x00k" + + "rl\x00krs\x00kru\x00ksasksb\x00ksd\x00ksf\x00ksh\x00ksj\x00ksr\x00ktb" + + "\x00ktm\x00kto\x00kuurkub\x00kud\x00kue\x00kuj\x00kum\x00kun\x00kup\x00k" + + "us\x00kvomkvg\x00kvr\x00kvx\x00kw\x00\x01kwj\x00kwo\x00kxa\x00kxc\x00kxm" + + "\x00kxp\x00kxw\x00kxz\x00kyirkye\x00kyx\x00kzr\x00laatlab\x00lad\x00lag" + + "\x00lah\x00laj\x00las\x00lbtzlbe\x00lbu\x00lbw\x00lcm\x00lcp\x00ldb\x00l" + + "ed\x00lee\x00lem\x00lep\x00leq\x00leu\x00lez\x00lguglgg\x00liimlia\x00li" + + "d\x00lif\x00lig\x00lih\x00lij\x00lis\x00ljp\x00lki\x00lkt\x00lle\x00lln" + + "\x00lmn\x00lmo\x00lmp\x00lninlns\x00lnu\x00loaoloj\x00lok\x00lol\x00lor" + + "\x00los\x00loz\x00lrc\x00ltitltg\x00luublua\x00luo\x00luy\x00luz\x00lvav" + + "lwl\x00lzh\x00lzz\x00mad\x00maf\x00mag\x00mai\x00mak\x00man\x00mas\x00ma" + + "w\x00maz\x00mbh\x00mbo\x00mbq\x00mbu\x00mbw\x00mci\x00mcp\x00mcq\x00mcr" + + "\x00mcu\x00mda\x00mde\x00mdf\x00mdh\x00mdj\x00mdr\x00mdx\x00med\x00mee" + + "\x00mek\x00men\x00mer\x00met\x00meu\x00mfa\x00mfe\x00mfn\x00mfo\x00mfq" + + "\x00mglgmgh\x00mgl\x00mgo\x00mgp\x00mgy\x00mhahmhi\x00mhl\x00mirimif\x00" + + "min\x00mis\x00miw\x00mkkdmki\x00mkl\x00mkp\x00mkw\x00mlalmle\x00mlp\x00m" + + "ls\x00mmo\x00mmu\x00mmx\x00mnonmna\x00mnf\x00mni\x00mnw\x00moolmoa\x00mo" + + "e\x00moh\x00mos\x00mox\x00mpp\x00mps\x00mpt\x00mpx\x00mql\x00mrarmrd\x00" + + "mrj\x00mro\x00mssamtltmtc\x00mtf\x00mti\x00mtr\x00mua\x00mul\x00mur\x00m" + + "us\x00mva\x00mvn\x00mvy\x00mwk\x00mwr\x00mwv\x00mxc\x00mxm\x00myyamyk" + + "\x00mym\x00myv\x00myw\x00myx\x00myz\x00mzk\x00mzm\x00mzn\x00mzp\x00mzw" + + "\x00mzz\x00naaunac\x00naf\x00nah\x00nak\x00nan\x00nap\x00naq\x00nas\x00n" + + "bobnca\x00nce\x00ncf\x00nch\x00nco\x00ncu\x00nddendc\x00nds\x00neepneb" + + "\x00new\x00nex\x00nfr\x00ngdonga\x00ngb\x00ngl\x00nhb\x00nhe\x00nhw\x00n" + + "if\x00nii\x00nij\x00nin\x00niu\x00niy\x00niz\x00njo\x00nkg\x00nko\x00nll" + + "dnmg\x00nmz\x00nnnonnf\x00nnh\x00nnk\x00nnm\x00noornod\x00noe\x00non\x00" + + "nop\x00nou\x00nqo\x00nrblnrb\x00nsk\x00nsn\x00nso\x00nss\x00ntm\x00ntr" + + "\x00nui\x00nup\x00nus\x00nuv\x00nux\x00nvavnwb\x00nxq\x00nxr\x00nyyanym" + + "\x00nyn\x00nzi\x00occiogc\x00ojjiokr\x00okv\x00omrmong\x00onn\x00ons\x00" + + "opm\x00orrioro\x00oru\x00osssosa\x00ota\x00otk\x00ozm\x00paanpag\x00pal" + + "\x00pam\x00pap\x00pau\x00pbi\x00pcd\x00pcm\x00pdc\x00pdt\x00ped\x00peo" + + "\x00pex\x00pfl\x00phl\x00phn\x00pilipil\x00pip\x00pka\x00pko\x00plolpla" + + "\x00pms\x00png\x00pnn\x00pnt\x00pon\x00ppo\x00pra\x00prd\x00prg\x00psusp" + + "ss\x00ptorptp\x00puu\x00pwa\x00quuequc\x00qug\x00rai\x00raj\x00rao\x00rc" + + "f\x00rej\x00rel\x00res\x00rgn\x00rhg\x00ria\x00rif\x00rjs\x00rkt\x00rmoh" + + "rmf\x00rmo\x00rmt\x00rmu\x00rnunrna\x00rng\x00roonrob\x00rof\x00roo\x00r" + + "ro\x00rtm\x00ruusrue\x00rug\x00rw\x00\x04rwk\x00rwo\x00ryu\x00saansaf" + + "\x00sah\x00saq\x00sas\x00sat\x00sav\x00saz\x00sba\x00sbe\x00sbp\x00scrds" + + "ck\x00scl\x00scn\x00sco\x00scs\x00sdndsdc\x00sdh\x00semesef\x00seh\x00se" + + "i\x00ses\x00sgagsga\x00sgs\x00sgw\x00sgz\x00sh\x00\x02shi\x00shk\x00shn" + + "\x00shu\x00siinsid\x00sig\x00sil\x00sim\x00sjr\x00sklkskc\x00skr\x00sks" + + "\x00sllvsld\x00sli\x00sll\x00sly\x00smmosma\x00smi\x00smj\x00smn\x00smp" + + "\x00smq\x00sms\x00snnasnc\x00snk\x00snp\x00snx\x00sny\x00soomsok\x00soq" + + "\x00sou\x00soy\x00spd\x00spl\x00sps\x00sqqisrrpsrb\x00srn\x00srr\x00srx" + + "\x00ssswssd\x00ssg\x00ssy\x00stotstk\x00stq\x00suunsua\x00sue\x00suk\x00" + + "sur\x00sus\x00svweswwaswb\x00swc\x00swg\x00swp\x00swv\x00sxn\x00sxw\x00s" + + "yl\x00syr\x00szl\x00taamtaj\x00tal\x00tan\x00taq\x00tbc\x00tbd\x00tbf" + + "\x00tbg\x00tbo\x00tbw\x00tbz\x00tci\x00tcy\x00tdd\x00tdg\x00tdh\x00teelt" + + "ed\x00tem\x00teo\x00tet\x00tfi\x00tggktgc\x00tgo\x00tgu\x00thhathl\x00th" + + "q\x00thr\x00tiirtif\x00tig\x00tik\x00tim\x00tio\x00tiv\x00tkuktkl\x00tkr" + + "\x00tkt\x00tlgltlf\x00tlx\x00tly\x00tmh\x00tmy\x00tnsntnh\x00toontof\x00" + + "tog\x00toq\x00tpi\x00tpm\x00tpz\x00tqo\x00trurtru\x00trv\x00trw\x00tssot" + + "sd\x00tsf\x00tsg\x00tsj\x00tsw\x00ttatttd\x00tte\x00ttj\x00ttr\x00tts" + + "\x00ttt\x00tuh\x00tul\x00tum\x00tuq\x00tvd\x00tvl\x00tvu\x00twwitwh\x00t" + + "wq\x00txg\x00tyahtya\x00tyv\x00tzm\x00ubu\x00udm\x00ugiguga\x00ukkruli" + + "\x00umb\x00und\x00unr\x00unx\x00urrduri\x00urt\x00urw\x00usa\x00utr\x00u" + + "vh\x00uvl\x00uzzbvag\x00vai\x00van\x00veenvec\x00vep\x00viievic\x00viv" + + "\x00vls\x00vmf\x00vmw\x00voolvot\x00vro\x00vun\x00vut\x00walnwae\x00waj" + + "\x00wal\x00wan\x00war\x00wbp\x00wbq\x00wbr\x00wci\x00wer\x00wgi\x00whg" + + "\x00wib\x00wiu\x00wiv\x00wja\x00wji\x00wls\x00wmo\x00wnc\x00wni\x00wnu" + + "\x00woolwob\x00wos\x00wrs\x00wsk\x00wtm\x00wuu\x00wuv\x00wwa\x00xav\x00x" + + "bi\x00xcr\x00xes\x00xhhoxla\x00xlc\x00xld\x00xmf\x00xmn\x00xmr\x00xna" + + "\x00xnr\x00xog\x00xon\x00xpr\x00xrb\x00xsa\x00xsi\x00xsm\x00xsr\x00xwe" + + "\x00yam\x00yao\x00yap\x00yas\x00yat\x00yav\x00yay\x00yaz\x00yba\x00ybb" + + "\x00yby\x00yer\x00ygr\x00ygw\x00yiidyko\x00yle\x00ylg\x00yll\x00yml\x00y" + + "ooryon\x00yrb\x00yre\x00yrl\x00yss\x00yua\x00yue\x00yuj\x00yut\x00yuw" + + "\x00zahazag\x00zbl\x00zdj\x00zea\x00zgh\x00zhhozhx\x00zia\x00zlm\x00zmi" + + "\x00zne\x00zuulzxx\x00zza\x00\xff\xff\xff\xff" + +const langNoIndexOffset = 1330 + +// langNoIndex is a bit vector of all 3-letter language codes that are not used as an index +// in lookup tables. The language ids for these language codes are derived directly +// from the letters and are not consecutive. +// Size: 2197 bytes, 2197 elements +var langNoIndex = [2197]uint8{ + // Entry 0 - 3F + 0xff, 0xf8, 0xed, 0xfe, 0xeb, 0xd3, 0x3b, 0xd2, + 0xfb, 0xbf, 0x7a, 0xfa, 0x37, 0x1d, 0x3c, 0x57, + 0x6e, 0x97, 0x73, 0x38, 0xfb, 0xea, 0xbf, 0x70, + 0xad, 0x03, 0xff, 0xff, 0xcf, 0x05, 0x84, 0x72, + 0xe9, 0xbf, 0xfd, 0xbf, 0xbf, 0xf7, 0xfd, 0x77, + 0x0f, 0xff, 0xef, 0x6f, 0xff, 0xfb, 0xdf, 0xe2, + 0xc9, 0xf8, 0x7f, 0x7e, 0x4d, 0xbc, 0x0a, 0x6a, + 0x7c, 0xea, 0xe3, 0xfa, 0x7a, 0xbf, 0x67, 0xff, + // Entry 40 - 7F + 0xff, 0xff, 0xff, 0xdf, 0x2a, 0x54, 0x91, 0xc0, + 0x5d, 0xe3, 0x97, 0x14, 0x07, 0x20, 0xdd, 0xed, + 0x9f, 0x3f, 0xc9, 0x21, 0xf8, 0x3f, 0x94, 0x35, + 0x7c, 0x5f, 0xff, 0x5f, 0x8e, 0x6e, 0xdf, 0xff, + 0xff, 0xff, 0x55, 0x7c, 0xd3, 0xfd, 0xbf, 0xb5, + 0x7b, 0xdf, 0x7f, 0xf7, 0xca, 0xfe, 0xdb, 0xa3, + 0xa8, 0xff, 0x1f, 0x67, 0x7d, 0xeb, 0xef, 0xce, + 0xff, 0xff, 0x9f, 0xff, 0xb7, 0xef, 0xfe, 0xcf, + // Entry 80 - BF + 0xdb, 0xff, 0xf3, 0xcd, 0xfb, 0x7f, 0xff, 0xff, + 0xbb, 0xee, 0xf7, 0xbd, 0xdb, 0xff, 0x5f, 0xf7, + 0xfd, 0xf2, 0xfd, 0xff, 0x5e, 0x2f, 0x3b, 0xba, + 0x7e, 0xff, 0xff, 0xfe, 0xf7, 0xff, 0xdd, 0xff, + 0xfd, 0xdf, 0xfb, 0xfe, 0x9d, 0xb4, 0xd3, 0xff, + 0xef, 0xff, 0xdf, 0xf7, 0x7f, 0xb7, 0xfd, 0xd5, + 0xa5, 0x77, 0x40, 0xff, 0x9c, 0xc1, 0x41, 0x2c, + 0x08, 0x21, 0x41, 0x00, 0x50, 0x40, 0x00, 0x80, + // Entry C0 - FF + 0xfb, 0x4a, 0xf2, 0x9f, 0xb4, 0x42, 0x41, 0x96, + 0x1b, 0x14, 0x08, 0xf3, 0x2b, 0xe7, 0x17, 0x56, + 0x05, 0x7d, 0x0e, 0x1c, 0x37, 0x7f, 0xf3, 0xef, + 0x97, 0xff, 0x5d, 0x38, 0x64, 0x08, 0x00, 0x10, + 0xbc, 0x85, 0xaf, 0xdf, 0xff, 0xff, 0x7b, 0x35, + 0x3e, 0xc7, 0xc7, 0xdf, 0xff, 0x01, 0x81, 0x00, + 0xb0, 0x05, 0x80, 0x00, 0x20, 0x00, 0x00, 0x03, + 0x40, 0x00, 0x40, 0x92, 0x21, 0x50, 0xb1, 0x5d, + // Entry 100 - 13F + 0xfd, 0xdc, 0xbe, 0x5e, 0x00, 0x00, 0x02, 0x64, + 0x0d, 0x19, 0x41, 0xdf, 0x79, 0x22, 0x00, 0x00, + 0x00, 0x5e, 0x64, 0xdc, 0x24, 0xe5, 0xd9, 0xe3, + 0xfe, 0xff, 0xfd, 0xcb, 0x9f, 0x14, 0x41, 0x0c, + 0x86, 0x00, 0xd1, 0x00, 0xf0, 0xc7, 0x67, 0x5f, + 0x56, 0x99, 0x5e, 0xb5, 0x6c, 0xaf, 0x03, 0x00, + 0x02, 0x00, 0x00, 0x00, 0xc0, 0x37, 0xda, 0x56, + 0x90, 0x6d, 0x01, 0x2e, 0x96, 0x69, 0x20, 0xfb, + // Entry 140 - 17F + 0xff, 0x3f, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x16, + 0x03, 0x00, 0x00, 0xb0, 0x14, 0x23, 0x50, 0x06, + 0x0a, 0x00, 0x01, 0x00, 0x00, 0x10, 0x11, 0x09, + 0x00, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x44, 0x00, 0x00, 0x10, 0x00, 0x05, + 0x08, 0x00, 0x00, 0x05, 0x00, 0x80, 0x28, 0x04, + 0x00, 0x00, 0x40, 0xd5, 0x2d, 0x00, 0x64, 0x35, + 0x24, 0x52, 0xf4, 0xd5, 0xbf, 0x62, 0xc9, 0x03, + // Entry 180 - 1BF + 0x00, 0x80, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x04, 0x13, 0x39, 0x01, 0xdd, 0x57, 0x98, + 0x21, 0x18, 0x81, 0x08, 0x00, 0x01, 0x40, 0x82, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x40, 0x00, 0x44, 0x00, 0x00, 0x80, 0xea, + 0xa9, 0x39, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + // Entry 1C0 - 1FF + 0x00, 0x03, 0x28, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x20, 0x04, 0xa6, 0x00, 0x04, 0x00, 0x00, + 0x81, 0x50, 0x00, 0x00, 0x00, 0x11, 0x84, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x55, + 0x02, 0x10, 0x08, 0x04, 0x00, 0x00, 0x00, 0x40, + 0x30, 0x83, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1e, 0xcd, 0xbf, 0x7a, 0xbf, + // Entry 200 - 23F + 0xdf, 0xc3, 0x83, 0x82, 0xc0, 0xfb, 0x57, 0x27, + 0xed, 0x55, 0xe7, 0x01, 0x00, 0x20, 0xb2, 0xc5, + 0xa4, 0x45, 0x25, 0x9b, 0x02, 0xdf, 0xe1, 0xdf, + 0x03, 0x44, 0x08, 0x90, 0x01, 0x04, 0x81, 0xe3, + 0x92, 0x54, 0xdb, 0x28, 0xd3, 0x5f, 0xfe, 0x6d, + 0x79, 0xed, 0x1c, 0x7f, 0x04, 0x08, 0x00, 0x01, + 0x21, 0x12, 0x64, 0x5f, 0xdd, 0x0e, 0x85, 0x4f, + 0x40, 0x40, 0x00, 0x04, 0xf1, 0xfd, 0x3d, 0x54, + // Entry 240 - 27F + 0xe8, 0x03, 0xb4, 0x27, 0x23, 0x0d, 0x00, 0x00, + 0x20, 0x7b, 0x78, 0x02, 0x07, 0x84, 0x00, 0xf0, + 0xbb, 0x7e, 0x5a, 0x00, 0x18, 0x04, 0x81, 0x00, + 0x00, 0x00, 0x80, 0x10, 0x90, 0x1c, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, 0x00, 0x04, + 0x08, 0xa0, 0x70, 0xa5, 0x0c, 0x40, 0x00, 0x00, + 0x91, 0x24, 0x04, 0x68, 0x00, 0x20, 0x70, 0xff, + 0x7b, 0x7f, 0x70, 0x00, 0x05, 0x9b, 0xdd, 0x66, + // Entry 280 - 2BF + 0x03, 0x00, 0x11, 0x00, 0x00, 0x00, 0x40, 0x05, + 0xb5, 0xb6, 0x80, 0x08, 0x04, 0x00, 0x04, 0x51, + 0xe2, 0xef, 0xfd, 0x3f, 0x05, 0x09, 0x08, 0x05, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x60, + 0xe7, 0x48, 0x00, 0x81, 0x20, 0xc0, 0x05, 0x80, + 0x03, 0x00, 0x00, 0x00, 0x8c, 0x50, 0x40, 0x04, + 0x84, 0x47, 0x84, 0x40, 0x20, 0x10, 0x00, 0x20, + // Entry 2C0 - 2FF + 0x02, 0x50, 0x80, 0x11, 0x00, 0x99, 0x6c, 0xe2, + 0x50, 0x27, 0x1d, 0x11, 0x29, 0x0e, 0x59, 0xe9, + 0x33, 0x08, 0x00, 0x20, 0x04, 0x40, 0x10, 0x00, + 0x00, 0x00, 0x50, 0x44, 0x92, 0x49, 0xd6, 0x5d, + 0xa7, 0x81, 0x47, 0x97, 0xfb, 0x00, 0x10, 0x00, + 0x08, 0x00, 0x80, 0x00, 0x40, 0x04, 0x00, 0x01, + 0x02, 0x00, 0x01, 0x40, 0x80, 0x00, 0x40, 0x08, + 0xd8, 0xeb, 0xf6, 0x39, 0xc4, 0x8d, 0x12, 0x00, + // Entry 300 - 33F + 0x00, 0x0c, 0x04, 0x01, 0x20, 0x20, 0xdd, 0xa0, + 0x01, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x04, 0x10, 0xd0, 0x9d, 0x95, 0x13, 0x04, 0x80, + 0x00, 0x01, 0xd0, 0x16, 0x40, 0x00, 0x10, 0xb0, + 0x10, 0x62, 0x4c, 0xd2, 0x02, 0x01, 0x4a, 0x00, + 0x46, 0x04, 0x00, 0x08, 0x02, 0x00, 0x20, 0x80, + 0x00, 0x80, 0x06, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0xf0, 0xd8, 0x6f, 0x15, 0x02, 0x08, 0x00, + // Entry 340 - 37F + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, + 0x00, 0x10, 0x00, 0x00, 0x00, 0xf0, 0x84, 0xe3, + 0xdd, 0xbf, 0xf9, 0xf9, 0x3b, 0x7f, 0x7f, 0xdb, + 0xfd, 0xfc, 0xfe, 0xdf, 0xff, 0xfd, 0xff, 0xf6, + 0xfb, 0xfc, 0xf7, 0x1f, 0xff, 0xb3, 0x6c, 0xff, + 0xd9, 0xad, 0xdf, 0xfe, 0xef, 0xba, 0xdf, 0xff, + 0xff, 0xff, 0xb7, 0xdd, 0x7d, 0xbf, 0xab, 0x7f, + 0xfd, 0xfd, 0xdf, 0x2f, 0x9c, 0xdf, 0xf3, 0x6f, + // Entry 380 - 3BF + 0xdf, 0xdd, 0xff, 0xfb, 0xee, 0xd2, 0xab, 0x5f, + 0xd5, 0xdf, 0x7f, 0xff, 0xeb, 0xff, 0xe4, 0x4d, + 0xf9, 0xff, 0xfe, 0xf7, 0xfd, 0xdf, 0xfb, 0xbf, + 0xee, 0xdb, 0x6f, 0xef, 0xff, 0x7f, 0xff, 0xff, + 0xf7, 0x5f, 0xd3, 0x3b, 0xfd, 0xd9, 0xdf, 0xeb, + 0xbc, 0x08, 0x05, 0x24, 0xff, 0x07, 0x70, 0xfe, + 0xe6, 0x5e, 0x00, 0x08, 0x00, 0x83, 0x7d, 0x1f, + 0x06, 0xe6, 0x72, 0x60, 0xd1, 0x3c, 0x7f, 0x44, + // Entry 3C0 - 3FF + 0x02, 0x30, 0x9f, 0x7a, 0x16, 0xbd, 0x7f, 0x57, + 0xf2, 0xff, 0x31, 0xff, 0xf2, 0x1e, 0x90, 0xf7, + 0xf1, 0xf9, 0x45, 0x80, 0x01, 0x02, 0x00, 0x20, + 0x40, 0x54, 0x9f, 0x8a, 0xdf, 0xf9, 0x6e, 0x11, + 0x86, 0x51, 0xc0, 0xf3, 0xfb, 0x47, 0x40, 0x03, + 0x05, 0xd1, 0x50, 0x5c, 0x00, 0x40, 0x00, 0x10, + 0x04, 0x02, 0x00, 0x00, 0x0a, 0x00, 0x17, 0xd2, + 0xb9, 0xfd, 0xfc, 0xba, 0xfe, 0xef, 0xc7, 0xbe, + // Entry 400 - 43F + 0x53, 0x6f, 0xdf, 0xe7, 0xdb, 0x65, 0xbb, 0x7f, + 0xfa, 0xff, 0x77, 0xf3, 0xef, 0xbf, 0xfd, 0xf7, + 0xdf, 0xdf, 0x9b, 0x7f, 0xff, 0xff, 0x7f, 0x6f, + 0xf7, 0xfb, 0xeb, 0xdf, 0xbc, 0xff, 0xbf, 0x6b, + 0x7b, 0xfb, 0xff, 0xce, 0x76, 0xbd, 0xf7, 0xf7, + 0xdf, 0xdc, 0xf7, 0xf7, 0xff, 0xdf, 0xf3, 0xfe, + 0xef, 0xff, 0xff, 0xff, 0xb6, 0x7f, 0x7f, 0xde, + 0xf7, 0xb9, 0xeb, 0x77, 0xff, 0xfb, 0xbf, 0xdf, + // Entry 440 - 47F + 0xfd, 0xfe, 0xfb, 0xff, 0xfe, 0xeb, 0x1f, 0x7d, + 0x2f, 0xfd, 0xb6, 0xb5, 0xa5, 0xfc, 0xff, 0xfd, + 0x7f, 0x4e, 0xbf, 0x8f, 0xae, 0xff, 0xee, 0xdf, + 0x7f, 0xf7, 0x73, 0x02, 0x02, 0x04, 0xfc, 0xf7, + 0xff, 0xb7, 0xd7, 0xef, 0xfe, 0xcd, 0xf5, 0xce, + 0xe2, 0x8e, 0xe7, 0xbf, 0xb7, 0xff, 0x56, 0xfd, + 0xcd, 0xff, 0xfb, 0xff, 0xdf, 0xd7, 0xea, 0xff, + 0xe5, 0x5f, 0x6d, 0x0f, 0xa7, 0x51, 0x06, 0xc4, + // Entry 480 - 4BF + 0x93, 0x50, 0x5d, 0xaf, 0xa6, 0xff, 0x99, 0xfb, + 0x63, 0x1d, 0x53, 0xff, 0xef, 0xb7, 0x35, 0x20, + 0x14, 0x00, 0x55, 0x51, 0xc2, 0x65, 0xf5, 0x41, + 0xe2, 0xff, 0xfc, 0xdf, 0x02, 0x85, 0xc5, 0x05, + 0x00, 0x22, 0x00, 0x74, 0x69, 0x10, 0x08, 0x05, + 0x41, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x51, 0x20, 0x05, 0x04, 0x01, 0x00, 0x00, + 0x06, 0x11, 0x20, 0x00, 0x18, 0x01, 0x92, 0xf1, + // Entry 4C0 - 4FF + 0xfd, 0x47, 0x69, 0x06, 0x95, 0x06, 0x57, 0xed, + 0xfb, 0x4d, 0x1c, 0x6b, 0x83, 0x04, 0x62, 0x40, + 0x00, 0x11, 0x42, 0x00, 0x00, 0x00, 0x54, 0x83, + 0xb8, 0x4f, 0x10, 0x8e, 0x89, 0x46, 0xde, 0xf7, + 0x13, 0x31, 0x00, 0x20, 0x00, 0x00, 0x00, 0x90, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x10, 0x00, + 0x01, 0x00, 0x00, 0xf0, 0x5b, 0xf4, 0xbe, 0x3d, + 0xbe, 0xcf, 0xf7, 0xaf, 0x42, 0x04, 0x84, 0x41, + // Entry 500 - 53F + 0x30, 0xff, 0x79, 0x72, 0x04, 0x00, 0x00, 0x49, + 0x2d, 0x14, 0x27, 0x5f, 0xed, 0xf1, 0x3f, 0xe7, + 0x3f, 0x00, 0x00, 0x02, 0xc6, 0xa0, 0x1e, 0xf8, + 0xbb, 0xff, 0xfd, 0xfb, 0xb7, 0xfd, 0xe7, 0xf7, + 0xfd, 0xfc, 0xd5, 0xed, 0x47, 0xf4, 0x7e, 0x10, + 0x01, 0x01, 0x84, 0x6d, 0xff, 0xf7, 0xdd, 0xf9, + 0x5b, 0x05, 0x86, 0xed, 0xf5, 0x77, 0xbd, 0x3c, + 0x00, 0x00, 0x00, 0x42, 0x71, 0x42, 0x00, 0x40, + // Entry 540 - 57F + 0x00, 0x00, 0x01, 0x43, 0x19, 0x24, 0x08, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + // Entry 580 - 5BF + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xab, 0xbd, 0xe7, 0x57, 0xee, 0x13, 0x5d, + 0x09, 0xc1, 0x40, 0x21, 0xfa, 0x17, 0x01, 0x80, + 0x00, 0x00, 0x00, 0x00, 0xf0, 0xce, 0xfb, 0xbf, + 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x30, 0x15, 0xa3, 0x10, 0x00, 0x00, 0x00, + 0x11, 0x04, 0x16, 0x00, 0x00, 0x02, 0x20, 0x81, + 0xa3, 0x01, 0x50, 0x00, 0x00, 0x83, 0x11, 0x40, + // Entry 5C0 - 5FF + 0x00, 0x00, 0x00, 0xf0, 0xdd, 0x7b, 0xbe, 0x02, + 0xaa, 0x10, 0x5d, 0x98, 0x52, 0x00, 0x80, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x02, 0x02, + 0x3d, 0x40, 0x10, 0x02, 0x10, 0x61, 0x5a, 0x9d, + 0x31, 0x00, 0x00, 0x00, 0x01, 0x18, 0x02, 0x20, + 0x00, 0x00, 0x01, 0x00, 0x42, 0x00, 0x20, 0x00, + 0x00, 0x1f, 0xdf, 0xd2, 0xb9, 0xff, 0xfd, 0x3f, + 0x1f, 0x98, 0xcf, 0x9c, 0xff, 0xaf, 0x5f, 0xfe, + // Entry 600 - 63F + 0x7b, 0x4b, 0x40, 0x10, 0xe1, 0xfd, 0xaf, 0xd9, + 0xb7, 0xf6, 0xfb, 0xb3, 0xc7, 0xff, 0x6f, 0xf1, + 0x73, 0xb1, 0x7f, 0x9f, 0x7f, 0xbd, 0xfc, 0xb7, + 0xee, 0x1c, 0xfa, 0xcb, 0xef, 0xdd, 0xf9, 0xbd, + 0x6e, 0xae, 0x55, 0xfd, 0x6e, 0x81, 0x76, 0x9f, + 0xd4, 0x77, 0xf5, 0x7d, 0xfb, 0xff, 0xeb, 0xfe, + 0xbe, 0x5f, 0x46, 0x5b, 0xe9, 0x5f, 0x50, 0x18, + 0x02, 0xfa, 0xf7, 0x9d, 0x15, 0x97, 0x05, 0x0f, + // Entry 640 - 67F + 0x75, 0xc4, 0x7d, 0x81, 0x92, 0xf5, 0x57, 0x6c, + 0xff, 0xe4, 0xef, 0x6f, 0xff, 0xfc, 0xdd, 0xde, + 0xfc, 0xfd, 0x76, 0x5f, 0x7a, 0x3f, 0x00, 0x98, + 0x02, 0xfb, 0xa3, 0xef, 0xf3, 0xd6, 0xf2, 0xff, + 0xb9, 0xda, 0x7d, 0xd0, 0x3e, 0x15, 0x7b, 0xb4, + 0xf5, 0x3e, 0xff, 0xff, 0xf1, 0xf7, 0xff, 0xe7, + 0x5f, 0xff, 0xff, 0x9e, 0xdf, 0xf6, 0xd7, 0xb9, + 0xef, 0x27, 0x80, 0xbb, 0xc5, 0xff, 0xff, 0xe3, + // Entry 680 - 6BF + 0x97, 0x9d, 0xbf, 0x9f, 0xf7, 0xc7, 0xfd, 0x37, + 0xce, 0x7f, 0x44, 0x1d, 0x73, 0x7f, 0xf8, 0xda, + 0x5d, 0xce, 0x7d, 0x06, 0xb9, 0xea, 0x79, 0xa0, + 0x1a, 0x20, 0x00, 0x30, 0x02, 0x04, 0x24, 0x08, + 0x04, 0x00, 0x00, 0x40, 0xd4, 0x02, 0x04, 0x00, + 0x00, 0x04, 0x00, 0x04, 0x00, 0x20, 0x09, 0x06, + 0x50, 0x00, 0x08, 0x00, 0x00, 0x00, 0x24, 0x00, + 0x04, 0x00, 0x10, 0xdc, 0x58, 0xd7, 0x0d, 0x0f, + // Entry 6C0 - 6FF + 0x54, 0x4d, 0xf1, 0x16, 0x44, 0xd5, 0x42, 0x08, + 0x40, 0x02, 0x00, 0x40, 0x00, 0x08, 0x00, 0x00, + 0x00, 0xdc, 0xfb, 0xcb, 0x0e, 0x58, 0x48, 0x41, + 0x24, 0x20, 0x04, 0x00, 0x30, 0x12, 0x40, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x80, 0x10, 0x10, 0xab, + 0x6d, 0x93, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x80, 0x25, 0x00, 0x00, + // Entry 700 - 73F + 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x80, 0x86, 0xc2, 0x00, 0x00, 0x01, 0x00, 0x01, + 0xff, 0x18, 0x02, 0x00, 0x02, 0xf0, 0xfd, 0x79, + 0x3b, 0x00, 0x25, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, + 0x03, 0x00, 0x09, 0x20, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // Entry 740 - 77F + 0x00, 0x00, 0x00, 0xef, 0xd5, 0xfd, 0xcf, 0x7e, + 0xb0, 0x11, 0x00, 0x00, 0x00, 0x92, 0x01, 0x46, + 0xcd, 0xf9, 0x5c, 0x00, 0x01, 0x00, 0x30, 0x04, + 0x04, 0x55, 0x00, 0x01, 0x04, 0xf4, 0x3f, 0x4a, + 0x01, 0x00, 0x00, 0xb0, 0x80, 0x20, 0x55, 0x75, + 0x97, 0x7c, 0xdf, 0x31, 0xcc, 0x68, 0xd1, 0x03, + 0xd5, 0x57, 0x27, 0x14, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x2c, 0xf7, 0xcb, 0x1f, 0x14, 0x60, + // Entry 780 - 7BF + 0x83, 0x68, 0x01, 0x10, 0x8b, 0x38, 0x8a, 0x01, + 0x00, 0x00, 0x20, 0x00, 0x24, 0x44, 0x00, 0x00, + 0x10, 0x03, 0x31, 0x02, 0x01, 0x00, 0x00, 0xf0, + 0xf5, 0xff, 0xd5, 0x97, 0xbc, 0x70, 0xd6, 0x78, + 0x78, 0x15, 0x50, 0x05, 0xa4, 0x84, 0xa9, 0x41, + 0x00, 0x00, 0x00, 0x6b, 0x39, 0x52, 0x74, 0x40, + 0xe8, 0x30, 0x90, 0x6a, 0x92, 0x00, 0x00, 0x02, + 0xff, 0xef, 0xff, 0x4b, 0x85, 0x53, 0xf4, 0xed, + // Entry 7C0 - 7FF + 0xdd, 0xbf, 0xf2, 0x5d, 0xc7, 0x0c, 0xd5, 0x42, + 0xfc, 0xff, 0xf7, 0x1f, 0x00, 0x80, 0x40, 0x56, + 0xcc, 0x16, 0x9e, 0xea, 0x35, 0x7d, 0xef, 0xff, + 0xbd, 0xa4, 0xaf, 0x01, 0x44, 0x18, 0x01, 0x4d, + 0x4e, 0x4a, 0x08, 0x50, 0x28, 0x30, 0xe0, 0x80, + 0x10, 0x20, 0x24, 0x00, 0xff, 0x2f, 0xd3, 0x60, + 0xfe, 0x01, 0x02, 0x88, 0x2a, 0x40, 0x16, 0x01, + 0x01, 0x15, 0x2b, 0x3c, 0x01, 0x00, 0x00, 0x10, + // Entry 800 - 83F + 0x90, 0x49, 0x41, 0x02, 0x02, 0x01, 0xe1, 0xbf, + 0xbf, 0x03, 0x00, 0x00, 0x10, 0xdc, 0xa3, 0xd1, + 0x40, 0x9c, 0x44, 0xdf, 0xf5, 0x8f, 0x66, 0xb3, + 0x55, 0x20, 0xd4, 0xc1, 0xd8, 0x30, 0x3d, 0x80, + 0x00, 0x00, 0x00, 0x04, 0xd4, 0x11, 0xc5, 0x84, + 0x2f, 0x50, 0x00, 0x22, 0x50, 0x6e, 0xbd, 0x93, + 0x07, 0x00, 0x20, 0x10, 0x84, 0xb2, 0x45, 0x10, + 0x06, 0x44, 0x00, 0x00, 0x12, 0x02, 0x11, 0x00, + // Entry 840 - 87F + 0xf0, 0xfb, 0xfd, 0x7f, 0x05, 0x00, 0x16, 0x89, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x30, 0x02, 0x28, + 0x84, 0x00, 0x21, 0xc0, 0x23, 0x24, 0x00, 0x00, + 0x00, 0xcb, 0xe4, 0x3a, 0x46, 0x88, 0x54, 0xf1, + 0xef, 0xff, 0x7f, 0x12, 0x01, 0x01, 0x84, 0x50, + 0x07, 0xfc, 0xff, 0xff, 0x0f, 0x01, 0x00, 0x40, + 0x10, 0x38, 0x01, 0x01, 0x1c, 0x12, 0x40, 0xe1, + // Entry 880 - 8BF + 0x76, 0x16, 0x08, 0x03, 0x10, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x24, + 0x0a, 0x00, 0x80, 0x00, 0x00, +} + +// altLangISO3 holds an alphabetically sorted list of 3-letter language code alternatives +// to 2-letter language codes that cannot be derived using the method described above. +// Each 3-letter code is followed by its 1-byte langID. +const altLangISO3 tag.Index = "---\x00cor\x00hbs\x01heb\x02kin\x03spa\x04yid\x05\xff\xff\xff\xff" + +// altLangIndex is used to convert indexes in altLangISO3 to langIDs. +// Size: 12 bytes, 6 elements +var altLangIndex = [6]uint16{ + 0x0281, 0x0407, 0x01fb, 0x03e5, 0x013e, 0x0208, +} + +// AliasMap maps langIDs to their suggested replacements. +// Size: 772 bytes, 193 elements +var AliasMap = [193]FromTo{ + 0: {From: 0x82, To: 0x88}, + 1: {From: 0x187, To: 0x1ae}, + 2: {From: 0x1f3, To: 0x1e1}, + 3: {From: 0x1fb, To: 0x1bc}, + 4: {From: 0x208, To: 0x512}, + 5: {From: 0x20f, To: 0x20e}, + 6: {From: 0x310, To: 0x3dc}, + 7: {From: 0x347, To: 0x36f}, + 8: {From: 0x407, To: 0x432}, + 9: {From: 0x47a, To: 0x153}, + 10: {From: 0x490, To: 0x451}, + 11: {From: 0x4a2, To: 0x21}, + 12: {From: 0x53e, To: 0x544}, + 13: {From: 0x58f, To: 0x12d}, + 14: {From: 0x62b, To: 0x34}, + 15: {From: 0x62f, To: 0x14}, + 16: {From: 0x630, To: 0x1eb1}, + 17: {From: 0x651, To: 0x431}, + 18: {From: 0x662, To: 0x431}, + 19: {From: 0x6ed, To: 0x3a}, + 20: {From: 0x6f8, To: 0x1d7}, + 21: {From: 0x709, To: 0x3625}, + 22: {From: 0x73e, To: 0x21a1}, + 23: {From: 0x7b3, To: 0x56}, + 24: {From: 0x7b9, To: 0x299b}, + 25: {From: 0x7c5, To: 0x58}, + 26: {From: 0x7e6, To: 0x145}, + 27: {From: 0x80c, To: 0x5a}, + 28: {From: 0x815, To: 0x8d}, + 29: {From: 0x87e, To: 0x810}, + 30: {From: 0x8a8, To: 0x8b7}, + 31: {From: 0x8c3, To: 0xee3}, + 32: {From: 0x8fa, To: 0x1dc}, + 33: {From: 0x9ef, To: 0x331}, + 34: {From: 0xa36, To: 0x2c5}, + 35: {From: 0xa3d, To: 0xbf}, + 36: {From: 0xabe, To: 0x3322}, + 37: {From: 0xb38, To: 0x529}, + 38: {From: 0xb75, To: 0x265a}, + 39: {From: 0xb7e, To: 0xbc3}, + 40: {From: 0xb9b, To: 0x44e}, + 41: {From: 0xbbc, To: 0x4229}, + 42: {From: 0xbbf, To: 0x529}, + 43: {From: 0xbfe, To: 0x2da7}, + 44: {From: 0xc2e, To: 0x3181}, + 45: {From: 0xcb9, To: 0xf3}, + 46: {From: 0xd08, To: 0xfa}, + 47: {From: 0xdc8, To: 0x11a}, + 48: {From: 0xdd7, To: 0x32d}, + 49: {From: 0xdf8, To: 0xdfb}, + 50: {From: 0xdfe, To: 0x531}, + 51: {From: 0xe01, To: 0xdf3}, + 52: {From: 0xedf, To: 0x205a}, + 53: {From: 0xee9, To: 0x222e}, + 54: {From: 0xeee, To: 0x2e9a}, + 55: {From: 0xf39, To: 0x367}, + 56: {From: 0x10d0, To: 0x140}, + 57: {From: 0x1104, To: 0x2d0}, + 58: {From: 0x11a0, To: 0x1ec}, + 59: {From: 0x1279, To: 0x21}, + 60: {From: 0x1424, To: 0x15e}, + 61: {From: 0x1470, To: 0x14e}, + 62: {From: 0x151f, To: 0xd9b}, + 63: {From: 0x1523, To: 0x390}, + 64: {From: 0x1532, To: 0x19f}, + 65: {From: 0x1580, To: 0x210}, + 66: {From: 0x1583, To: 0x10d}, + 67: {From: 0x15a3, To: 0x3caf}, + 68: {From: 0x1630, To: 0x222e}, + 69: {From: 0x166a, To: 0x19b}, + 70: {From: 0x16c8, To: 0x136}, + 71: {From: 0x1700, To: 0x29f8}, + 72: {From: 0x1718, To: 0x194}, + 73: {From: 0x1727, To: 0xf3f}, + 74: {From: 0x177a, To: 0x178}, + 75: {From: 0x1809, To: 0x17b6}, + 76: {From: 0x1816, To: 0x18f3}, + 77: {From: 0x188a, To: 0x436}, + 78: {From: 0x1979, To: 0x1d01}, + 79: {From: 0x1a74, To: 0x2bb0}, + 80: {From: 0x1a8a, To: 0x1f8}, + 81: {From: 0x1b5a, To: 0x1fa}, + 82: {From: 0x1b86, To: 0x1515}, + 83: {From: 0x1d64, To: 0x2c9b}, + 84: {From: 0x2038, To: 0x37b1}, + 85: {From: 0x203d, To: 0x20dd}, + 86: {From: 0x2042, To: 0x2e00}, + 87: {From: 0x205a, To: 0x30b}, + 88: {From: 0x20e3, To: 0x274}, + 89: {From: 0x20ee, To: 0x263}, + 90: {From: 0x20f2, To: 0x22d}, + 91: {From: 0x20f9, To: 0x256}, + 92: {From: 0x210f, To: 0x21eb}, + 93: {From: 0x2135, To: 0x27d}, + 94: {From: 0x2160, To: 0x913}, + 95: {From: 0x2199, To: 0x121}, + 96: {From: 0x21ce, To: 0x1561}, + 97: {From: 0x21e6, To: 0x504}, + 98: {From: 0x21f4, To: 0x49f}, + 99: {From: 0x21fb, To: 0x269}, + 100: {From: 0x222d, To: 0x121}, + 101: {From: 0x2237, To: 0x121}, + 102: {From: 0x2248, To: 0x217d}, + 103: {From: 0x2262, To: 0x92a}, + 104: {From: 0x2316, To: 0x3226}, + 105: {From: 0x236a, To: 0x2835}, + 106: {From: 0x2382, To: 0x3365}, + 107: {From: 0x2472, To: 0x2c7}, + 108: {From: 0x24e4, To: 0x2ff}, + 109: {From: 0x24f0, To: 0x2fa}, + 110: {From: 0x24fa, To: 0x31f}, + 111: {From: 0x2550, To: 0xb5b}, + 112: {From: 0x25a9, To: 0xe2}, + 113: {From: 0x263e, To: 0x2d0}, + 114: {From: 0x26c9, To: 0x26b4}, + 115: {From: 0x26f9, To: 0x3c8}, + 116: {From: 0x2727, To: 0x3caf}, + 117: {From: 0x2755, To: 0x6a4}, + 118: {From: 0x2765, To: 0x26b4}, + 119: {From: 0x2789, To: 0x4358}, + 120: {From: 0x27c9, To: 0x2001}, + 121: {From: 0x28ea, To: 0x27b1}, + 122: {From: 0x28ef, To: 0x2837}, + 123: {From: 0x28fe, To: 0xaa5}, + 124: {From: 0x2914, To: 0x351}, + 125: {From: 0x2986, To: 0x2da7}, + 126: {From: 0x29f0, To: 0x96b}, + 127: {From: 0x2b1a, To: 0x38d}, + 128: {From: 0x2bfc, To: 0x395}, + 129: {From: 0x2c3f, To: 0x3caf}, + 130: {From: 0x2ce1, To: 0x2201}, + 131: {From: 0x2cfc, To: 0x3be}, + 132: {From: 0x2d13, To: 0x597}, + 133: {From: 0x2d47, To: 0x148}, + 134: {From: 0x2d48, To: 0x148}, + 135: {From: 0x2dff, To: 0x2f1}, + 136: {From: 0x2e08, To: 0x19cc}, + 137: {From: 0x2e10, To: 0xc45}, + 138: {From: 0x2e1a, To: 0x2d95}, + 139: {From: 0x2e21, To: 0x292}, + 140: {From: 0x2e54, To: 0x7d}, + 141: {From: 0x2e65, To: 0x2282}, + 142: {From: 0x2e97, To: 0x1a4}, + 143: {From: 0x2ea0, To: 0x2e9b}, + 144: {From: 0x2eef, To: 0x2ed7}, + 145: {From: 0x3193, To: 0x3c4}, + 146: {From: 0x3366, To: 0x338e}, + 147: {From: 0x342a, To: 0x3dc}, + 148: {From: 0x34ee, To: 0x18d0}, + 149: {From: 0x35c8, To: 0x2c9b}, + 150: {From: 0x35e6, To: 0x412}, + 151: {From: 0x35f5, To: 0x24b}, + 152: {From: 0x360d, To: 0x1dc}, + 153: {From: 0x3658, To: 0x246}, + 154: {From: 0x3676, To: 0x3f4}, + 155: {From: 0x36fd, To: 0x445}, + 156: {From: 0x3747, To: 0x3b42}, + 157: {From: 0x37c0, To: 0x121}, + 158: {From: 0x3816, To: 0x38f2}, + 159: {From: 0x382a, To: 0x2b48}, + 160: {From: 0x382b, To: 0x2c9b}, + 161: {From: 0x382f, To: 0xa9}, + 162: {From: 0x3832, To: 0x3228}, + 163: {From: 0x386c, To: 0x39a6}, + 164: {From: 0x3892, To: 0x3fc0}, + 165: {From: 0x38a0, To: 0x45f}, + 166: {From: 0x38a5, To: 0x39d7}, + 167: {From: 0x38b4, To: 0x1fa4}, + 168: {From: 0x38b5, To: 0x2e9a}, + 169: {From: 0x38fa, To: 0x38f1}, + 170: {From: 0x395c, To: 0x47e}, + 171: {From: 0x3b4e, To: 0xd91}, + 172: {From: 0x3b78, To: 0x137}, + 173: {From: 0x3c99, To: 0x4bc}, + 174: {From: 0x3fbd, To: 0x100}, + 175: {From: 0x4208, To: 0xa91}, + 176: {From: 0x42be, To: 0x573}, + 177: {From: 0x42f9, To: 0x3f60}, + 178: {From: 0x4378, To: 0x25a}, + 179: {From: 0x43b8, To: 0xe6c}, + 180: {From: 0x43cd, To: 0x10f}, + 181: {From: 0x43d4, To: 0x4848}, + 182: {From: 0x44af, To: 0x3322}, + 183: {From: 0x44e3, To: 0x512}, + 184: {From: 0x45ca, To: 0x2409}, + 185: {From: 0x45dd, To: 0x26dc}, + 186: {From: 0x4610, To: 0x48ae}, + 187: {From: 0x46ae, To: 0x46a0}, + 188: {From: 0x473e, To: 0x4745}, + 189: {From: 0x4817, To: 0x3503}, + 190: {From: 0x483b, To: 0x208b}, + 191: {From: 0x4916, To: 0x31f}, + 192: {From: 0x49a7, To: 0x523}, +} + +// Size: 193 bytes, 193 elements +var AliasTypes = [193]AliasType{ + // Entry 0 - 3F + 1, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 1, 0, 0, 0, 0, + 1, 2, 1, 1, 2, 0, 0, 1, 0, 1, 2, 1, 1, 0, 0, 0, + 0, 2, 1, 1, 0, 2, 0, 0, 1, 0, 1, 0, 0, 1, 2, 1, + 1, 1, 1, 0, 0, 0, 0, 2, 1, 1, 1, 1, 2, 1, 0, 1, + // Entry 40 - 7F + 1, 2, 2, 0, 0, 1, 2, 0, 1, 0, 1, 1, 1, 1, 0, 0, + 2, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 2, 2, 2, 0, + 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, + // Entry 80 - BF + 1, 0, 0, 1, 0, 2, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 1, 1, 2, 0, 0, 2, 0, 0, 1, 1, 1, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 2, 0, + 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, + // Entry C0 - FF + 1, +} + +const ( + _Latn = 91 + _Hani = 57 + _Hans = 59 + _Hant = 60 + _Qaaa = 149 + _Qaai = 157 + _Qabx = 198 + _Zinh = 255 + _Zyyy = 260 + _Zzzz = 261 +) + +// script is an alphabetically sorted list of ISO 15924 codes. The index +// of the script in the string, divided by 4, is the internal scriptID. +const script tag.Index = "" + // Size: 1052 bytes + "----AdlmAfakAghbAhomArabAranArmiArmnAvstBaliBamuBassBatkBengBhksBlisBopo" + + "BrahBraiBugiBuhdCakmCansCariChamCherChrsCirtCoptCpmnCprtCyrlCyrsDevaDiak" + + "DogrDsrtDuplEgydEgyhEgypElbaElymEthiGeokGeorGlagGongGonmGothGranGrekGujr" + + "GuruHanbHangHaniHanoHansHantHatrHebrHiraHluwHmngHmnpHrktHungIndsItalJamo" + + "JavaJpanJurcKaliKanaKawiKharKhmrKhojKitlKitsKndaKoreKpelKthiLanaLaooLatf" + + "LatgLatnLekeLepcLimbLinaLinbLisuLomaLyciLydiMahjMakaMandManiMarcMayaMedf" + + "MendMercMeroMlymModiMongMoonMrooMteiMultMymrNagmNandNarbNbatNewaNkdbNkgb" + + "NkooNshuOgamOlckOrkhOryaOsgeOsmaOugrPalmPaucPcunPelmPermPhagPhliPhlpPhlv" + + "PhnxPiqdPlrdPrtiPsinQaaaQaabQaacQaadQaaeQaafQaagQaahQaaiQaajQaakQaalQaam" + + "QaanQaaoQaapQaaqQaarQaasQaatQaauQaavQaawQaaxQaayQaazQabaQabbQabcQabdQabe" + + "QabfQabgQabhQabiQabjQabkQablQabmQabnQaboQabpQabqQabrQabsQabtQabuQabvQabw" + + "QabxRanjRjngRohgRoroRunrSamrSaraSarbSaurSgnwShawShrdShuiSiddSindSinhSogd" + + "SogoSoraSoyoSundSunuSyloSyrcSyreSyrjSyrnTagbTakrTaleTaluTamlTangTavtTelu" + + "TengTfngTglgThaaThaiTibtTirhTnsaTotoUgarVaiiVispVithWaraWchoWoleXpeoXsux" + + "YeziYiiiZanbZinhZmthZsyeZsymZxxxZyyyZzzz\xff\xff\xff\xff" + +// suppressScript is an index from langID to the dominant script for that language, +// if it exists. If a script is given, it should be suppressed from the language tag. +// Size: 1330 bytes, 1330 elements +var suppressScript = [1330]uint8{ + // Entry 0 - 3F + 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, + // Entry 40 - 7F + 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, + // Entry 80 - BF + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // Entry C0 - FF + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, + // Entry 100 - 13F + 0x5b, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xed, 0x00, 0x00, 0x00, 0x00, 0xef, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, + 0x00, 0x5b, 0x00, 0x00, 0x5b, 0x00, 0x5b, 0x00, + // Entry 140 - 17F + 0x5b, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x5b, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, + 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x00, + 0x00, 0x5b, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x5b, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // Entry 180 - 1BF + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x5b, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x5b, 0x35, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x22, 0x00, + // Entry 1C0 - 1FF + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x5b, 0x5b, 0x00, 0x5b, 0x5b, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00, + 0x5b, 0x5b, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, + // Entry 200 - 23F + 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // Entry 240 - 27F + 0x00, 0x00, 0x20, 0x00, 0x00, 0x5b, 0x00, 0x00, + 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x53, 0x00, 0x00, 0x54, 0x00, 0x22, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // Entry 280 - 2BF + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, + 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // Entry 2C0 - 2FF + 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, + // Entry 300 - 33F + 0x00, 0x00, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x5b, + 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x00, + // Entry 340 - 37F + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x00, + 0x5b, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, + 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x5b, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x5b, 0x00, + 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, + // Entry 380 - 3BF + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x5b, 0x00, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, + // Entry 3C0 - 3FF + 0x5b, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, + 0x00, 0x5b, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x00, 0x00, 0x5b, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // Entry 400 - 43F + 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xd6, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x5b, 0x00, + 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, + 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00, + // Entry 440 - 47F + 0x00, 0x00, 0x00, 0x00, 0x5b, 0x5b, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xe9, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xee, 0x00, 0x00, 0x00, 0x2c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, + 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x5b, 0x00, + // Entry 480 - 4BF + 0x5b, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x5b, 0x00, + 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x5b, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // Entry 4C0 - 4FF + 0x5b, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // Entry 500 - 53F + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, + 0x00, 0x00, +} + +const ( + _001 = 1 + _419 = 31 + _BR = 65 + _CA = 73 + _ES = 111 + _GB = 124 + _MD = 189 + _PT = 239 + _UK = 307 + _US = 310 + _ZZ = 358 + _XA = 324 + _XC = 326 + _XK = 334 +) + +// isoRegionOffset needs to be added to the index of regionISO to obtain the regionID +// for 2-letter ISO codes. (The first isoRegionOffset regionIDs are reserved for +// the UN.M49 codes used for groups.) +const isoRegionOffset = 32 + +// regionTypes defines the status of a region for various standards. +// Size: 359 bytes, 359 elements +var regionTypes = [359]uint8{ + // Entry 0 - 3F + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + // Entry 40 - 7F + 0x06, 0x06, 0x06, 0x06, 0x04, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x04, 0x04, 0x06, + 0x04, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x04, 0x06, 0x04, 0x06, 0x06, 0x06, 0x06, 0x00, + 0x06, 0x04, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x04, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x00, 0x06, 0x04, 0x06, 0x06, 0x06, 0x06, 0x06, + // Entry 80 - BF + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x00, 0x04, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x00, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + // Entry C0 - FF + 0x06, 0x06, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x00, 0x06, 0x06, 0x06, 0x06, 0x00, 0x06, 0x04, + 0x06, 0x06, 0x06, 0x06, 0x00, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x00, 0x06, 0x06, 0x00, 0x06, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + // Entry 100 - 13F + 0x05, 0x05, 0x05, 0x06, 0x00, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x04, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x02, 0x06, 0x04, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x00, 0x06, 0x06, 0x06, 0x06, + // Entry 140 - 17F + 0x06, 0x06, 0x00, 0x06, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04, 0x06, + 0x06, 0x04, 0x06, 0x06, 0x04, 0x06, 0x05, +} + +// regionISO holds a list of alphabetically sorted 2-letter ISO region codes. +// Each 2-letter codes is followed by two bytes with the following meaning: +// - [A-Z}{2}: the first letter of the 2-letter code plus these two +// letters form the 3-letter ISO code. +// - 0, n: index into altRegionISO3. +const regionISO tag.Index = "" + // Size: 1312 bytes + "AAAAACSCADNDAEREAFFGAGTGAIIAALLBAMRMANNTAOGOAQTAARRGASSMATUTAUUSAWBWAXLA" + + "AZZEBAIHBBRBBDGDBEELBFFABGGRBHHRBIDIBJENBLLMBMMUBNRNBOOLBQESBRRABSHSBTTN" + + "BUURBVVTBWWABYLRBZLZCAANCCCKCDODCFAFCGOGCHHECIIVCKOKCLHLCMMRCNHNCOOLCPPT" + + "CQ CRRICS\x00\x00CTTECUUBCVPVCWUWCXXRCYYPCZZEDDDRDEEUDGGADJJIDKNKDMMADO" + + "OMDYHYDZZAEA ECCUEESTEGGYEHSHERRIESSPETTHEU\x00\x03EZ FIINFJJIFKLKFMSM" + + "FOROFQ\x00\x18FRRAFXXXGAABGBBRGDRDGEEOGFUFGGGYGHHAGIIBGLRLGMMBGNINGPLPGQ" + + "NQGRRCGS\x00\x06GTTMGUUMGWNBGYUYHKKGHMMDHNNDHRRVHTTIHUUNHVVOIC IDDNIERL" + + "ILSRIMMNINNDIOOTIQRQIRRNISSLITTAJEEYJMAMJOORJPPNJTTNKEENKGGZKHHMKIIRKM" + + "\x00\x09KNNAKP\x00\x0cKRORKWWTKY\x00\x0fKZAZLAAOLBBNLCCALIIELKKALRBRLSSO" + + "LTTULUUXLVVALYBYMAARMCCOMDDAMENEMFAFMGDGMHHLMIIDMKKDMLLIMMMRMNNGMOACMPNP" + + "MQTQMRRTMSSRMTLTMUUSMVDVMWWIMXEXMYYSMZOZNAAMNCCLNEERNFFKNGGANHHBNIICNLLD" + + "NOORNPPLNQ\x00\x1eNRRUNTTZNUIUNZZLOMMNPAANPCCIPEERPFYFPGNGPHHLPKAKPLOLPM" + + "\x00\x12PNCNPRRIPSSEPTRTPUUSPWLWPYRYPZCZQAATQMMMQNNNQOOOQPPPQQQQQRRRQSSS" + + "QTTTQU\x00\x03QVVVQWWWQXXXQYYYQZZZREEURHHOROOURS\x00\x15RUUSRWWASAAUSBLB" + + "SCYCSDDNSEWESGGPSHHNSIVNSJJMSKVKSLLESMMRSNENSOOMSRURSSSDSTTPSUUNSVLVSXXM" + + "SYYRSZWZTAAATCCATDCDTF\x00\x18TGGOTHHATJJKTKKLTLLSTMKMTNUNTOONTPMPTRURTT" + + "TOTVUVTWWNTZZAUAKRUGGAUK UMMIUN USSAUYRYUZZBVAATVCCTVDDRVEENVGGBVIIRVN" + + "NMVUUTWFLFWKAKWSSMXAAAXBBBXCCCXDDDXEEEXFFFXGGGXHHHXIIIXJJJXKKKXLLLXMMMXN" + + "NNXOOOXPPPXQQQXRRRXSSSXTTTXUUUXVVVXWWWXXXXXYYYXZZZYDMDYEEMYT\x00\x1bYUUG" + + "ZAAFZMMBZRARZWWEZZZZ\xff\xff\xff\xff" + +// altRegionISO3 holds a list of 3-letter region codes that cannot be +// mapped to 2-letter codes using the default algorithm. This is a short list. +const altRegionISO3 string = "SCGQUUSGSCOMPRKCYMSPMSRBATFMYTATN" + +// altRegionIDs holds a list of regionIDs the positions of which match those +// of the 3-letter ISO codes in altRegionISO3. +// Size: 22 bytes, 11 elements +var altRegionIDs = [11]uint16{ + 0x0058, 0x0071, 0x0089, 0x00a9, 0x00ab, 0x00ae, 0x00eb, 0x0106, + 0x0122, 0x0160, 0x00dd, +} + +// Size: 80 bytes, 20 elements +var regionOldMap = [20]FromTo{ + 0: {From: 0x44, To: 0xc5}, + 1: {From: 0x59, To: 0xa8}, + 2: {From: 0x60, To: 0x61}, + 3: {From: 0x67, To: 0x3b}, + 4: {From: 0x7a, To: 0x79}, + 5: {From: 0x94, To: 0x37}, + 6: {From: 0xa4, To: 0x134}, + 7: {From: 0xc2, To: 0x134}, + 8: {From: 0xd8, To: 0x140}, + 9: {From: 0xdd, To: 0x2b}, + 10: {From: 0xf0, To: 0x134}, + 11: {From: 0xf3, To: 0xe3}, + 12: {From: 0xfd, To: 0x71}, + 13: {From: 0x104, To: 0x165}, + 14: {From: 0x12b, To: 0x127}, + 15: {From: 0x133, To: 0x7c}, + 16: {From: 0x13b, To: 0x13f}, + 17: {From: 0x142, To: 0x134}, + 18: {From: 0x15e, To: 0x15f}, + 19: {From: 0x164, To: 0x4b}, +} + +// m49 maps regionIDs to UN.M49 codes. The first isoRegionOffset entries are +// codes indicating collections of regions. +// Size: 718 bytes, 359 elements +var m49 = [359]int16{ + // Entry 0 - 3F + 0, 1, 2, 3, 5, 9, 11, 13, + 14, 15, 17, 18, 19, 21, 29, 30, + 34, 35, 39, 53, 54, 57, 61, 142, + 143, 145, 150, 151, 154, 155, 202, 419, + 958, 0, 20, 784, 4, 28, 660, 8, + 51, 530, 24, 10, 32, 16, 40, 36, + 533, 248, 31, 70, 52, 50, 56, 854, + 100, 48, 108, 204, 652, 60, 96, 68, + // Entry 40 - 7F + 535, 76, 44, 64, 104, 74, 72, 112, + 84, 124, 166, 180, 140, 178, 756, 384, + 184, 152, 120, 156, 170, 0, 0, 188, + 891, 296, 192, 132, 531, 162, 196, 203, + 278, 276, 0, 262, 208, 212, 214, 204, + 12, 0, 218, 233, 818, 732, 232, 724, + 231, 967, 0, 246, 242, 238, 583, 234, + 0, 250, 249, 266, 826, 308, 268, 254, + // Entry 80 - BF + 831, 288, 292, 304, 270, 324, 312, 226, + 300, 239, 320, 316, 624, 328, 344, 334, + 340, 191, 332, 348, 854, 0, 360, 372, + 376, 833, 356, 86, 368, 364, 352, 380, + 832, 388, 400, 392, 581, 404, 417, 116, + 296, 174, 659, 408, 410, 414, 136, 398, + 418, 422, 662, 438, 144, 430, 426, 440, + 442, 428, 434, 504, 492, 498, 499, 663, + // Entry C0 - FF + 450, 584, 581, 807, 466, 104, 496, 446, + 580, 474, 478, 500, 470, 480, 462, 454, + 484, 458, 508, 516, 540, 562, 574, 566, + 548, 558, 528, 578, 524, 10, 520, 536, + 570, 554, 512, 591, 0, 604, 258, 598, + 608, 586, 616, 666, 612, 630, 275, 620, + 581, 585, 600, 591, 634, 959, 960, 961, + 962, 963, 964, 965, 966, 967, 968, 969, + // Entry 100 - 13F + 970, 971, 972, 638, 716, 642, 688, 643, + 646, 682, 90, 690, 729, 752, 702, 654, + 705, 744, 703, 694, 674, 686, 706, 740, + 728, 678, 810, 222, 534, 760, 748, 0, + 796, 148, 260, 768, 764, 762, 772, 626, + 795, 788, 776, 626, 792, 780, 798, 158, + 834, 804, 800, 826, 581, 0, 840, 858, + 860, 336, 670, 704, 862, 92, 850, 704, + // Entry 140 - 17F + 548, 876, 581, 882, 973, 974, 975, 976, + 977, 978, 979, 980, 981, 982, 983, 984, + 985, 986, 987, 988, 989, 990, 991, 992, + 993, 994, 995, 996, 997, 998, 720, 887, + 175, 891, 710, 894, 180, 716, 999, +} + +// m49Index gives indexes into fromM49 based on the three most significant bits +// of a 10-bit UN.M49 code. To search an UN.M49 code in fromM49, search in +// +// fromM49[m49Index[msb39(code)]:m49Index[msb3(code)+1]] +// +// for an entry where the first 7 bits match the 7 lsb of the UN.M49 code. +// The region code is stored in the 9 lsb of the indexed value. +// Size: 18 bytes, 9 elements +var m49Index = [9]int16{ + 0, 59, 108, 143, 181, 220, 259, 291, + 333, +} + +// fromM49 contains entries to map UN.M49 codes to regions. See m49Index for details. +// Size: 666 bytes, 333 elements +var fromM49 = [333]uint16{ + // Entry 0 - 3F + 0x0201, 0x0402, 0x0603, 0x0824, 0x0a04, 0x1027, 0x1205, 0x142b, + 0x1606, 0x1868, 0x1a07, 0x1c08, 0x1e09, 0x202d, 0x220a, 0x240b, + 0x260c, 0x2822, 0x2a0d, 0x302a, 0x3825, 0x3a0e, 0x3c0f, 0x3e32, + 0x402c, 0x4410, 0x4611, 0x482f, 0x4e12, 0x502e, 0x5842, 0x6039, + 0x6435, 0x6628, 0x6834, 0x6a13, 0x6c14, 0x7036, 0x7215, 0x783d, + 0x7a16, 0x8043, 0x883f, 0x8c33, 0x9046, 0x9445, 0x9841, 0xa848, + 0xac9b, 0xb50a, 0xb93d, 0xc03e, 0xc838, 0xd0c5, 0xd83a, 0xe047, + 0xe8a7, 0xf052, 0xf849, 0x085b, 0x10ae, 0x184c, 0x1c17, 0x1e18, + // Entry 40 - 7F + 0x20b4, 0x2219, 0x2921, 0x2c1a, 0x2e1b, 0x3051, 0x341c, 0x361d, + 0x3853, 0x3d2f, 0x445d, 0x4c4a, 0x5454, 0x5ca9, 0x5f60, 0x644d, + 0x684b, 0x7050, 0x7857, 0x7e91, 0x805a, 0x885e, 0x941e, 0x965f, + 0x983b, 0xa064, 0xa865, 0xac66, 0xb46a, 0xbd1b, 0xc487, 0xcc70, + 0xce70, 0xd06e, 0xd26b, 0xd477, 0xdc75, 0xde89, 0xe474, 0xec73, + 0xf031, 0xf27a, 0xf479, 0xfc7f, 0x04e6, 0x0922, 0x0c63, 0x147b, + 0x187e, 0x1c84, 0x26ee, 0x2861, 0x2c60, 0x3061, 0x4081, 0x4882, + 0x50a8, 0x5888, 0x6083, 0x687d, 0x7086, 0x788b, 0x808a, 0x8885, + // Entry 80 - BF + 0x908d, 0x9892, 0x9c8f, 0xa139, 0xa890, 0xb08e, 0xb893, 0xc09e, + 0xc89a, 0xd096, 0xd89d, 0xe09c, 0xe897, 0xf098, 0xf89f, 0x004f, + 0x08a1, 0x10a3, 0x1caf, 0x20a2, 0x28a5, 0x30ab, 0x34ac, 0x3cad, + 0x42a6, 0x44b0, 0x461f, 0x4cb1, 0x54b6, 0x58b9, 0x5cb5, 0x64ba, + 0x6cb3, 0x70b7, 0x74b8, 0x7cc7, 0x84c0, 0x8ccf, 0x94d1, 0x9cce, + 0xa4c4, 0xaccc, 0xb4c9, 0xbcca, 0xc0cd, 0xc8d0, 0xd8bc, 0xe0c6, + 0xe4bd, 0xe6be, 0xe8cb, 0xf0bb, 0xf8d2, 0x00e2, 0x08d3, 0x10de, + 0x18dc, 0x20da, 0x2429, 0x265c, 0x2a30, 0x2d1c, 0x2e40, 0x30df, + // Entry C0 - FF + 0x38d4, 0x4940, 0x54e1, 0x5cd9, 0x64d5, 0x6cd7, 0x74e0, 0x7cd6, + 0x84db, 0x88c8, 0x8b34, 0x8e76, 0x90c1, 0x92f1, 0x94e9, 0x9ee3, + 0xace7, 0xb0f2, 0xb8e5, 0xc0e8, 0xc8ec, 0xd0ea, 0xd8ef, 0xe08c, + 0xe527, 0xeced, 0xf4f4, 0xfd03, 0x0505, 0x0707, 0x0d08, 0x183c, + 0x1d0f, 0x26aa, 0x2826, 0x2cb2, 0x2ebf, 0x34eb, 0x3d3a, 0x4514, + 0x4d19, 0x5509, 0x5d15, 0x6106, 0x650b, 0x6d13, 0x7d0e, 0x7f12, + 0x813f, 0x8310, 0x8516, 0x8d62, 0x9965, 0xa15e, 0xa86f, 0xb118, + 0xb30c, 0xb86d, 0xc10c, 0xc917, 0xd111, 0xd91e, 0xe10d, 0xe84e, + // Entry 100 - 13F + 0xf11d, 0xf525, 0xf924, 0x0123, 0x0926, 0x112a, 0x192d, 0x2023, + 0x2929, 0x312c, 0x3728, 0x3920, 0x3d2e, 0x4132, 0x4931, 0x4ec3, + 0x551a, 0x646c, 0x747c, 0x7e80, 0x80a0, 0x8299, 0x8530, 0x9136, + 0xa53e, 0xac37, 0xb537, 0xb938, 0xbd3c, 0xd941, 0xe543, 0xed5f, + 0xef5f, 0xf658, 0xfd63, 0x7c20, 0x7ef5, 0x80f6, 0x82f7, 0x84f8, + 0x86f9, 0x88fa, 0x8afb, 0x8cfc, 0x8e71, 0x90fe, 0x92ff, 0x9500, + 0x9701, 0x9902, 0x9b44, 0x9d45, 0x9f46, 0xa147, 0xa348, 0xa549, + 0xa74a, 0xa94b, 0xab4c, 0xad4d, 0xaf4e, 0xb14f, 0xb350, 0xb551, + // Entry 140 - 17F + 0xb752, 0xb953, 0xbb54, 0xbd55, 0xbf56, 0xc157, 0xc358, 0xc559, + 0xc75a, 0xc95b, 0xcb5c, 0xcd5d, 0xcf66, +} + +// Size: 2128 bytes +var variantIndex = map[string]uint8{ + "1606nict": 0x0, + "1694acad": 0x1, + "1901": 0x2, + "1959acad": 0x3, + "1994": 0x67, + "1996": 0x4, + "abl1943": 0x5, + "akuapem": 0x6, + "alalc97": 0x69, + "aluku": 0x7, + "ao1990": 0x8, + "aranes": 0x9, + "arevela": 0xa, + "arevmda": 0xb, + "arkaika": 0xc, + "asante": 0xd, + "auvern": 0xe, + "baku1926": 0xf, + "balanka": 0x10, + "barla": 0x11, + "basiceng": 0x12, + "bauddha": 0x13, + "bciav": 0x14, + "bcizbl": 0x15, + "biscayan": 0x16, + "biske": 0x62, + "bohoric": 0x17, + "boont": 0x18, + "bornholm": 0x19, + "cisaup": 0x1a, + "colb1945": 0x1b, + "cornu": 0x1c, + "creiss": 0x1d, + "dajnko": 0x1e, + "ekavsk": 0x1f, + "emodeng": 0x20, + "fonipa": 0x6a, + "fonkirsh": 0x6b, + "fonnapa": 0x6c, + "fonupa": 0x6d, + "fonxsamp": 0x6e, + "gallo": 0x21, + "gascon": 0x22, + "grclass": 0x23, + "grital": 0x24, + "grmistr": 0x25, + "hepburn": 0x26, + "heploc": 0x68, + "hognorsk": 0x27, + "hsistemo": 0x28, + "ijekavsk": 0x29, + "itihasa": 0x2a, + "ivanchov": 0x2b, + "jauer": 0x2c, + "jyutping": 0x2d, + "kkcor": 0x2e, + "kociewie": 0x2f, + "kscor": 0x30, + "laukika": 0x31, + "lemosin": 0x32, + "lengadoc": 0x33, + "lipaw": 0x63, + "ltg1929": 0x34, + "ltg2007": 0x35, + "luna1918": 0x36, + "metelko": 0x37, + "monoton": 0x38, + "ndyuka": 0x39, + "nedis": 0x3a, + "newfound": 0x3b, + "nicard": 0x3c, + "njiva": 0x64, + "nulik": 0x3d, + "osojs": 0x65, + "oxendict": 0x3e, + "pahawh2": 0x3f, + "pahawh3": 0x40, + "pahawh4": 0x41, + "pamaka": 0x42, + "peano": 0x43, + "petr1708": 0x44, + "pinyin": 0x45, + "polyton": 0x46, + "provenc": 0x47, + "puter": 0x48, + "rigik": 0x49, + "rozaj": 0x4a, + "rumgr": 0x4b, + "scotland": 0x4c, + "scouse": 0x4d, + "simple": 0x6f, + "solba": 0x66, + "sotav": 0x4e, + "spanglis": 0x4f, + "surmiran": 0x50, + "sursilv": 0x51, + "sutsilv": 0x52, + "synnejyl": 0x53, + "tarask": 0x54, + "tongyong": 0x55, + "tunumiit": 0x56, + "uccor": 0x57, + "ucrcor": 0x58, + "ulster": 0x59, + "unifon": 0x5a, + "vaidika": 0x5b, + "valencia": 0x5c, + "vallader": 0x5d, + "vecdruka": 0x5e, + "vivaraup": 0x5f, + "wadegile": 0x60, + "xsistemo": 0x61, +} + +// variantNumSpecialized is the number of specialized variants in variants. +const variantNumSpecialized = 105 + +// nRegionGroups is the number of region groups. +const nRegionGroups = 33 + +type likelyLangRegion struct { + lang uint16 + region uint16 +} + +// likelyScript is a lookup table, indexed by scriptID, for the most likely +// languages and regions given a script. +// Size: 1052 bytes, 263 elements +var likelyScript = [263]likelyLangRegion{ + 1: {lang: 0x14e, region: 0x85}, + 3: {lang: 0x2a2, region: 0x107}, + 4: {lang: 0x1f, region: 0x9a}, + 5: {lang: 0x3a, region: 0x6c}, + 7: {lang: 0x3b, region: 0x9d}, + 8: {lang: 0x1d7, region: 0x28}, + 9: {lang: 0x13, region: 0x9d}, + 10: {lang: 0x5b, region: 0x96}, + 11: {lang: 0x60, region: 0x52}, + 12: {lang: 0xb9, region: 0xb5}, + 13: {lang: 0x63, region: 0x96}, + 14: {lang: 0xa5, region: 0x35}, + 15: {lang: 0x3e9, region: 0x9a}, + 17: {lang: 0x529, region: 0x12f}, + 18: {lang: 0x3b1, region: 0x9a}, + 19: {lang: 0x15e, region: 0x79}, + 20: {lang: 0xc2, region: 0x96}, + 21: {lang: 0x9d, region: 0xe8}, + 22: {lang: 0xdb, region: 0x35}, + 23: {lang: 0xf3, region: 0x49}, + 24: {lang: 0x4f0, region: 0x12c}, + 25: {lang: 0xe7, region: 0x13f}, + 26: {lang: 0xe5, region: 0x136}, + 29: {lang: 0xf1, region: 0x6c}, + 31: {lang: 0x1a0, region: 0x5e}, + 32: {lang: 0x3e2, region: 0x107}, + 34: {lang: 0x1be, region: 0x9a}, + 38: {lang: 0x15e, region: 0x79}, + 41: {lang: 0x133, region: 0x6c}, + 42: {lang: 0x431, region: 0x27}, + 44: {lang: 0x27, region: 0x70}, + 46: {lang: 0x210, region: 0x7e}, + 47: {lang: 0xfe, region: 0x38}, + 49: {lang: 0x19b, region: 0x9a}, + 50: {lang: 0x19e, region: 0x131}, + 51: {lang: 0x3e9, region: 0x9a}, + 52: {lang: 0x136, region: 0x88}, + 53: {lang: 0x1a4, region: 0x9a}, + 54: {lang: 0x39d, region: 0x9a}, + 55: {lang: 0x529, region: 0x12f}, + 56: {lang: 0x254, region: 0xac}, + 57: {lang: 0x529, region: 0x53}, + 58: {lang: 0x1cb, region: 0xe8}, + 59: {lang: 0x529, region: 0x53}, + 60: {lang: 0x529, region: 0x12f}, + 61: {lang: 0x2fd, region: 0x9c}, + 62: {lang: 0x1bc, region: 0x98}, + 63: {lang: 0x200, region: 0xa3}, + 64: {lang: 0x1c5, region: 0x12c}, + 65: {lang: 0x1ca, region: 0xb0}, + 68: {lang: 0x1d5, region: 0x93}, + 70: {lang: 0x142, region: 0x9f}, + 71: {lang: 0x254, region: 0xac}, + 72: {lang: 0x20e, region: 0x96}, + 73: {lang: 0x200, region: 0xa3}, + 75: {lang: 0x135, region: 0xc5}, + 76: {lang: 0x200, region: 0xa3}, + 78: {lang: 0x3bb, region: 0xe9}, + 79: {lang: 0x24a, region: 0xa7}, + 80: {lang: 0x3fa, region: 0x9a}, + 83: {lang: 0x251, region: 0x9a}, + 84: {lang: 0x254, region: 0xac}, + 86: {lang: 0x88, region: 0x9a}, + 87: {lang: 0x370, region: 0x124}, + 88: {lang: 0x2b8, region: 0xb0}, + 93: {lang: 0x29f, region: 0x9a}, + 94: {lang: 0x2a8, region: 0x9a}, + 95: {lang: 0x28f, region: 0x88}, + 96: {lang: 0x1a0, region: 0x88}, + 97: {lang: 0x2ac, region: 0x53}, + 99: {lang: 0x4f4, region: 0x12c}, + 100: {lang: 0x4f5, region: 0x12c}, + 101: {lang: 0x1be, region: 0x9a}, + 103: {lang: 0x337, region: 0x9d}, + 104: {lang: 0x4f7, region: 0x53}, + 105: {lang: 0xa9, region: 0x53}, + 108: {lang: 0x2e8, region: 0x113}, + 109: {lang: 0x4f8, region: 0x10c}, + 110: {lang: 0x4f8, region: 0x10c}, + 111: {lang: 0x304, region: 0x9a}, + 112: {lang: 0x31b, region: 0x9a}, + 113: {lang: 0x30b, region: 0x53}, + 115: {lang: 0x31e, region: 0x35}, + 116: {lang: 0x30e, region: 0x9a}, + 117: {lang: 0x414, region: 0xe9}, + 118: {lang: 0x331, region: 0xc5}, + 121: {lang: 0x4f9, region: 0x109}, + 122: {lang: 0x3b, region: 0xa2}, + 123: {lang: 0x353, region: 0xdc}, + 126: {lang: 0x2d0, region: 0x85}, + 127: {lang: 0x52a, region: 0x53}, + 128: {lang: 0x403, region: 0x97}, + 129: {lang: 0x3ee, region: 0x9a}, + 130: {lang: 0x39b, region: 0xc6}, + 131: {lang: 0x395, region: 0x9a}, + 132: {lang: 0x399, region: 0x136}, + 133: {lang: 0x429, region: 0x116}, + 135: {lang: 0x3b, region: 0x11d}, + 136: {lang: 0xfd, region: 0xc5}, + 139: {lang: 0x27d, region: 0x107}, + 140: {lang: 0x2c9, region: 0x53}, + 141: {lang: 0x39f, region: 0x9d}, + 142: {lang: 0x39f, region: 0x53}, + 144: {lang: 0x3ad, region: 0xb1}, + 146: {lang: 0x1c6, region: 0x53}, + 147: {lang: 0x4fd, region: 0x9d}, + 200: {lang: 0x3cb, region: 0x96}, + 203: {lang: 0x372, region: 0x10d}, + 204: {lang: 0x420, region: 0x98}, + 206: {lang: 0x4ff, region: 0x15f}, + 207: {lang: 0x3f0, region: 0x9a}, + 208: {lang: 0x45, region: 0x136}, + 209: {lang: 0x139, region: 0x7c}, + 210: {lang: 0x3e9, region: 0x9a}, + 212: {lang: 0x3e9, region: 0x9a}, + 213: {lang: 0x3fa, region: 0x9a}, + 214: {lang: 0x40c, region: 0xb4}, + 217: {lang: 0x433, region: 0x9a}, + 218: {lang: 0xef, region: 0xc6}, + 219: {lang: 0x43e, region: 0x96}, + 221: {lang: 0x44d, region: 0x35}, + 222: {lang: 0x44e, region: 0x9c}, + 226: {lang: 0x45a, region: 0xe8}, + 227: {lang: 0x11a, region: 0x9a}, + 228: {lang: 0x45e, region: 0x53}, + 229: {lang: 0x232, region: 0x53}, + 230: {lang: 0x450, region: 0x9a}, + 231: {lang: 0x4a5, region: 0x53}, + 232: {lang: 0x9f, region: 0x13f}, + 233: {lang: 0x461, region: 0x9a}, + 235: {lang: 0x528, region: 0xbb}, + 236: {lang: 0x153, region: 0xe8}, + 237: {lang: 0x128, region: 0xce}, + 238: {lang: 0x46b, region: 0x124}, + 239: {lang: 0xa9, region: 0x53}, + 240: {lang: 0x2ce, region: 0x9a}, + 243: {lang: 0x4ad, region: 0x11d}, + 244: {lang: 0x4be, region: 0xb5}, + 247: {lang: 0x1ce, region: 0x9a}, + 250: {lang: 0x3a9, region: 0x9d}, + 251: {lang: 0x22, region: 0x9c}, + 253: {lang: 0x1ea, region: 0x53}, + 254: {lang: 0xef, region: 0xc6}, +} + +type likelyScriptRegion struct { + region uint16 + script uint16 + flags uint8 +} + +// likelyLang is a lookup table, indexed by langID, for the most likely +// scripts and regions given incomplete information. If more entries exist for a +// given language, region and script are the index and size respectively +// of the list in likelyLangList. +// Size: 7980 bytes, 1330 elements +var likelyLang = [1330]likelyScriptRegion{ + 0: {region: 0x136, script: 0x5b, flags: 0x0}, + 1: {region: 0x70, script: 0x5b, flags: 0x0}, + 2: {region: 0x166, script: 0x5b, flags: 0x0}, + 3: {region: 0x166, script: 0x5b, flags: 0x0}, + 4: {region: 0x166, script: 0x5b, flags: 0x0}, + 5: {region: 0x7e, script: 0x20, flags: 0x0}, + 6: {region: 0x166, script: 0x5b, flags: 0x0}, + 7: {region: 0x166, script: 0x20, flags: 0x0}, + 8: {region: 0x81, script: 0x5b, flags: 0x0}, + 9: {region: 0x166, script: 0x5b, flags: 0x0}, + 10: {region: 0x166, script: 0x5b, flags: 0x0}, + 11: {region: 0x166, script: 0x5b, flags: 0x0}, + 12: {region: 0x96, script: 0x5b, flags: 0x0}, + 13: {region: 0x132, script: 0x5b, flags: 0x0}, + 14: {region: 0x81, script: 0x5b, flags: 0x0}, + 15: {region: 0x166, script: 0x5b, flags: 0x0}, + 16: {region: 0x166, script: 0x5b, flags: 0x0}, + 17: {region: 0x107, script: 0x20, flags: 0x0}, + 18: {region: 0x166, script: 0x5b, flags: 0x0}, + 19: {region: 0x9d, script: 0x9, flags: 0x0}, + 20: {region: 0x129, script: 0x5, flags: 0x0}, + 21: {region: 0x166, script: 0x5b, flags: 0x0}, + 22: {region: 0x162, script: 0x5b, flags: 0x0}, + 23: {region: 0x166, script: 0x5b, flags: 0x0}, + 24: {region: 0x166, script: 0x5b, flags: 0x0}, + 25: {region: 0x166, script: 0x5b, flags: 0x0}, + 26: {region: 0x166, script: 0x5b, flags: 0x0}, + 27: {region: 0x166, script: 0x5b, flags: 0x0}, + 28: {region: 0x52, script: 0x5b, flags: 0x0}, + 29: {region: 0x166, script: 0x5b, flags: 0x0}, + 30: {region: 0x166, script: 0x5b, flags: 0x0}, + 31: {region: 0x9a, script: 0x4, flags: 0x0}, + 32: {region: 0x166, script: 0x5b, flags: 0x0}, + 33: {region: 0x81, script: 0x5b, flags: 0x0}, + 34: {region: 0x9c, script: 0xfb, flags: 0x0}, + 35: {region: 0x166, script: 0x5b, flags: 0x0}, + 36: {region: 0x166, script: 0x5b, flags: 0x0}, + 37: {region: 0x14e, script: 0x5b, flags: 0x0}, + 38: {region: 0x107, script: 0x20, flags: 0x0}, + 39: {region: 0x70, script: 0x2c, flags: 0x0}, + 40: {region: 0x166, script: 0x5b, flags: 0x0}, + 41: {region: 0x166, script: 0x5b, flags: 0x0}, + 42: {region: 0xd7, script: 0x5b, flags: 0x0}, + 43: {region: 0x166, script: 0x5b, flags: 0x0}, + 45: {region: 0x166, script: 0x5b, flags: 0x0}, + 46: {region: 0x166, script: 0x5b, flags: 0x0}, + 47: {region: 0x166, script: 0x5b, flags: 0x0}, + 48: {region: 0x166, script: 0x5b, flags: 0x0}, + 49: {region: 0x166, script: 0x5b, flags: 0x0}, + 50: {region: 0x166, script: 0x5b, flags: 0x0}, + 51: {region: 0x96, script: 0x5b, flags: 0x0}, + 52: {region: 0x166, script: 0x5, flags: 0x0}, + 53: {region: 0x123, script: 0x5, flags: 0x0}, + 54: {region: 0x166, script: 0x5b, flags: 0x0}, + 55: {region: 0x166, script: 0x5b, flags: 0x0}, + 56: {region: 0x166, script: 0x5b, flags: 0x0}, + 57: {region: 0x166, script: 0x5b, flags: 0x0}, + 58: {region: 0x6c, script: 0x5, flags: 0x0}, + 59: {region: 0x0, script: 0x3, flags: 0x1}, + 60: {region: 0x166, script: 0x5b, flags: 0x0}, + 61: {region: 0x51, script: 0x5b, flags: 0x0}, + 62: {region: 0x3f, script: 0x5b, flags: 0x0}, + 63: {region: 0x68, script: 0x5, flags: 0x0}, + 65: {region: 0xbb, script: 0x5, flags: 0x0}, + 66: {region: 0x6c, script: 0x5, flags: 0x0}, + 67: {region: 0x9a, script: 0xe, flags: 0x0}, + 68: {region: 0x130, script: 0x5b, flags: 0x0}, + 69: {region: 0x136, script: 0xd0, flags: 0x0}, + 70: {region: 0x166, script: 0x5b, flags: 0x0}, + 71: {region: 0x166, script: 0x5b, flags: 0x0}, + 72: {region: 0x6f, script: 0x5b, flags: 0x0}, + 73: {region: 0x166, script: 0x5b, flags: 0x0}, + 74: {region: 0x166, script: 0x5b, flags: 0x0}, + 75: {region: 0x49, script: 0x5b, flags: 0x0}, + 76: {region: 0x166, script: 0x5b, flags: 0x0}, + 77: {region: 0x107, script: 0x20, flags: 0x0}, + 78: {region: 0x166, script: 0x5, flags: 0x0}, + 79: {region: 0x166, script: 0x5b, flags: 0x0}, + 80: {region: 0x166, script: 0x5b, flags: 0x0}, + 81: {region: 0x166, script: 0x5b, flags: 0x0}, + 82: {region: 0x9a, script: 0x22, flags: 0x0}, + 83: {region: 0x166, script: 0x5b, flags: 0x0}, + 84: {region: 0x166, script: 0x5b, flags: 0x0}, + 85: {region: 0x166, script: 0x5b, flags: 0x0}, + 86: {region: 0x3f, script: 0x5b, flags: 0x0}, + 87: {region: 0x166, script: 0x5b, flags: 0x0}, + 88: {region: 0x3, script: 0x5, flags: 0x1}, + 89: {region: 0x107, script: 0x20, flags: 0x0}, + 90: {region: 0xe9, script: 0x5, flags: 0x0}, + 91: {region: 0x96, script: 0x5b, flags: 0x0}, + 92: {region: 0xdc, script: 0x22, flags: 0x0}, + 93: {region: 0x2e, script: 0x5b, flags: 0x0}, + 94: {region: 0x52, script: 0x5b, flags: 0x0}, + 95: {region: 0x166, script: 0x5b, flags: 0x0}, + 96: {region: 0x52, script: 0xb, flags: 0x0}, + 97: {region: 0x166, script: 0x5b, flags: 0x0}, + 98: {region: 0x166, script: 0x5b, flags: 0x0}, + 99: {region: 0x96, script: 0x5b, flags: 0x0}, + 100: {region: 0x166, script: 0x5b, flags: 0x0}, + 101: {region: 0x52, script: 0x5b, flags: 0x0}, + 102: {region: 0x166, script: 0x5b, flags: 0x0}, + 103: {region: 0x166, script: 0x5b, flags: 0x0}, + 104: {region: 0x166, script: 0x5b, flags: 0x0}, + 105: {region: 0x166, script: 0x5b, flags: 0x0}, + 106: {region: 0x4f, script: 0x5b, flags: 0x0}, + 107: {region: 0x166, script: 0x5b, flags: 0x0}, + 108: {region: 0x166, script: 0x5b, flags: 0x0}, + 109: {region: 0x166, script: 0x5b, flags: 0x0}, + 110: {region: 0x166, script: 0x2c, flags: 0x0}, + 111: {region: 0x166, script: 0x5b, flags: 0x0}, + 112: {region: 0x166, script: 0x5b, flags: 0x0}, + 113: {region: 0x47, script: 0x20, flags: 0x0}, + 114: {region: 0x166, script: 0x5b, flags: 0x0}, + 115: {region: 0x166, script: 0x5b, flags: 0x0}, + 116: {region: 0x10c, script: 0x5, flags: 0x0}, + 117: {region: 0x163, script: 0x5b, flags: 0x0}, + 118: {region: 0x166, script: 0x5b, flags: 0x0}, + 119: {region: 0x96, script: 0x5b, flags: 0x0}, + 120: {region: 0x166, script: 0x5b, flags: 0x0}, + 121: {region: 0x130, script: 0x5b, flags: 0x0}, + 122: {region: 0x52, script: 0x5b, flags: 0x0}, + 123: {region: 0x9a, script: 0xe6, flags: 0x0}, + 124: {region: 0xe9, script: 0x5, flags: 0x0}, + 125: {region: 0x9a, script: 0x22, flags: 0x0}, + 126: {region: 0x38, script: 0x20, flags: 0x0}, + 127: {region: 0x9a, script: 0x22, flags: 0x0}, + 128: {region: 0xe9, script: 0x5, flags: 0x0}, + 129: {region: 0x12c, script: 0x34, flags: 0x0}, + 131: {region: 0x9a, script: 0x22, flags: 0x0}, + 132: {region: 0x166, script: 0x5b, flags: 0x0}, + 133: {region: 0x9a, script: 0x22, flags: 0x0}, + 134: {region: 0xe8, script: 0x5b, flags: 0x0}, + 135: {region: 0x166, script: 0x5b, flags: 0x0}, + 136: {region: 0x9a, script: 0x22, flags: 0x0}, + 137: {region: 0x166, script: 0x5b, flags: 0x0}, + 138: {region: 0x140, script: 0x5b, flags: 0x0}, + 139: {region: 0x166, script: 0x5b, flags: 0x0}, + 140: {region: 0x166, script: 0x5b, flags: 0x0}, + 141: {region: 0xe8, script: 0x5b, flags: 0x0}, + 142: {region: 0x166, script: 0x5b, flags: 0x0}, + 143: {region: 0xd7, script: 0x5b, flags: 0x0}, + 144: {region: 0x166, script: 0x5b, flags: 0x0}, + 145: {region: 0x166, script: 0x5b, flags: 0x0}, + 146: {region: 0x166, script: 0x5b, flags: 0x0}, + 147: {region: 0x166, script: 0x2c, flags: 0x0}, + 148: {region: 0x9a, script: 0x22, flags: 0x0}, + 149: {region: 0x96, script: 0x5b, flags: 0x0}, + 150: {region: 0x166, script: 0x5b, flags: 0x0}, + 151: {region: 0x166, script: 0x5b, flags: 0x0}, + 152: {region: 0x115, script: 0x5b, flags: 0x0}, + 153: {region: 0x166, script: 0x5b, flags: 0x0}, + 154: {region: 0x166, script: 0x5b, flags: 0x0}, + 155: {region: 0x52, script: 0x5b, flags: 0x0}, + 156: {region: 0x166, script: 0x5b, flags: 0x0}, + 157: {region: 0xe8, script: 0x5b, flags: 0x0}, + 158: {region: 0x166, script: 0x5b, flags: 0x0}, + 159: {region: 0x13f, script: 0xe8, flags: 0x0}, + 160: {region: 0xc4, script: 0x5b, flags: 0x0}, + 161: {region: 0x166, script: 0x5b, flags: 0x0}, + 162: {region: 0x166, script: 0x5b, flags: 0x0}, + 163: {region: 0xc4, script: 0x5b, flags: 0x0}, + 164: {region: 0x166, script: 0x5b, flags: 0x0}, + 165: {region: 0x35, script: 0xe, flags: 0x0}, + 166: {region: 0x166, script: 0x5b, flags: 0x0}, + 167: {region: 0x166, script: 0x5b, flags: 0x0}, + 168: {region: 0x166, script: 0x5b, flags: 0x0}, + 169: {region: 0x53, script: 0xef, flags: 0x0}, + 170: {region: 0x166, script: 0x5b, flags: 0x0}, + 171: {region: 0x166, script: 0x5b, flags: 0x0}, + 172: {region: 0x166, script: 0x5b, flags: 0x0}, + 173: {region: 0x9a, script: 0xe, flags: 0x0}, + 174: {region: 0x166, script: 0x5b, flags: 0x0}, + 175: {region: 0x9d, script: 0x5, flags: 0x0}, + 176: {region: 0x166, script: 0x5b, flags: 0x0}, + 177: {region: 0x4f, script: 0x5b, flags: 0x0}, + 178: {region: 0x79, script: 0x5b, flags: 0x0}, + 179: {region: 0x9a, script: 0x22, flags: 0x0}, + 180: {region: 0xe9, script: 0x5, flags: 0x0}, + 181: {region: 0x9a, script: 0x22, flags: 0x0}, + 182: {region: 0x166, script: 0x5b, flags: 0x0}, + 183: {region: 0x33, script: 0x5b, flags: 0x0}, + 184: {region: 0x166, script: 0x5b, flags: 0x0}, + 185: {region: 0xb5, script: 0xc, flags: 0x0}, + 186: {region: 0x52, script: 0x5b, flags: 0x0}, + 187: {region: 0x166, script: 0x2c, flags: 0x0}, + 188: {region: 0xe8, script: 0x5b, flags: 0x0}, + 189: {region: 0x166, script: 0x5b, flags: 0x0}, + 190: {region: 0xe9, script: 0x22, flags: 0x0}, + 191: {region: 0x107, script: 0x20, flags: 0x0}, + 192: {region: 0x160, script: 0x5b, flags: 0x0}, + 193: {region: 0x166, script: 0x5b, flags: 0x0}, + 194: {region: 0x96, script: 0x5b, flags: 0x0}, + 195: {region: 0x166, script: 0x5b, flags: 0x0}, + 196: {region: 0x52, script: 0x5b, flags: 0x0}, + 197: {region: 0x166, script: 0x5b, flags: 0x0}, + 198: {region: 0x166, script: 0x5b, flags: 0x0}, + 199: {region: 0x166, script: 0x5b, flags: 0x0}, + 200: {region: 0x87, script: 0x5b, flags: 0x0}, + 201: {region: 0x166, script: 0x5b, flags: 0x0}, + 202: {region: 0x166, script: 0x5b, flags: 0x0}, + 203: {region: 0x166, script: 0x5b, flags: 0x0}, + 204: {region: 0x166, script: 0x5b, flags: 0x0}, + 205: {region: 0x6e, script: 0x2c, flags: 0x0}, + 206: {region: 0x166, script: 0x5b, flags: 0x0}, + 207: {region: 0x166, script: 0x5b, flags: 0x0}, + 208: {region: 0x52, script: 0x5b, flags: 0x0}, + 209: {region: 0x166, script: 0x5b, flags: 0x0}, + 210: {region: 0x166, script: 0x5b, flags: 0x0}, + 211: {region: 0xc4, script: 0x5b, flags: 0x0}, + 212: {region: 0x166, script: 0x5b, flags: 0x0}, + 213: {region: 0x166, script: 0x5b, flags: 0x0}, + 214: {region: 0x166, script: 0x5b, flags: 0x0}, + 215: {region: 0x6f, script: 0x5b, flags: 0x0}, + 216: {region: 0x166, script: 0x5b, flags: 0x0}, + 217: {region: 0x166, script: 0x5b, flags: 0x0}, + 218: {region: 0xd7, script: 0x5b, flags: 0x0}, + 219: {region: 0x35, script: 0x16, flags: 0x0}, + 220: {region: 0x107, script: 0x20, flags: 0x0}, + 221: {region: 0xe8, script: 0x5b, flags: 0x0}, + 222: {region: 0x166, script: 0x5b, flags: 0x0}, + 223: {region: 0x132, script: 0x5b, flags: 0x0}, + 224: {region: 0x8b, script: 0x5b, flags: 0x0}, + 225: {region: 0x76, script: 0x5b, flags: 0x0}, + 226: {region: 0x107, script: 0x20, flags: 0x0}, + 227: {region: 0x136, script: 0x5b, flags: 0x0}, + 228: {region: 0x49, script: 0x5b, flags: 0x0}, + 229: {region: 0x136, script: 0x1a, flags: 0x0}, + 230: {region: 0xa7, script: 0x5, flags: 0x0}, + 231: {region: 0x13f, script: 0x19, flags: 0x0}, + 232: {region: 0x166, script: 0x5b, flags: 0x0}, + 233: {region: 0x9c, script: 0x5, flags: 0x0}, + 234: {region: 0x166, script: 0x5b, flags: 0x0}, + 235: {region: 0x166, script: 0x5b, flags: 0x0}, + 236: {region: 0x166, script: 0x5b, flags: 0x0}, + 237: {region: 0x166, script: 0x5b, flags: 0x0}, + 238: {region: 0x166, script: 0x5b, flags: 0x0}, + 239: {region: 0xc6, script: 0xda, flags: 0x0}, + 240: {region: 0x79, script: 0x5b, flags: 0x0}, + 241: {region: 0x6c, script: 0x1d, flags: 0x0}, + 242: {region: 0xe8, script: 0x5b, flags: 0x0}, + 243: {region: 0x49, script: 0x17, flags: 0x0}, + 244: {region: 0x131, script: 0x20, flags: 0x0}, + 245: {region: 0x49, script: 0x17, flags: 0x0}, + 246: {region: 0x49, script: 0x17, flags: 0x0}, + 247: {region: 0x49, script: 0x17, flags: 0x0}, + 248: {region: 0x49, script: 0x17, flags: 0x0}, + 249: {region: 0x10b, script: 0x5b, flags: 0x0}, + 250: {region: 0x5f, script: 0x5b, flags: 0x0}, + 251: {region: 0xea, script: 0x5b, flags: 0x0}, + 252: {region: 0x49, script: 0x17, flags: 0x0}, + 253: {region: 0xc5, script: 0x88, flags: 0x0}, + 254: {region: 0x8, script: 0x2, flags: 0x1}, + 255: {region: 0x107, script: 0x20, flags: 0x0}, + 256: {region: 0x7c, script: 0x5b, flags: 0x0}, + 257: {region: 0x64, script: 0x5b, flags: 0x0}, + 258: {region: 0x166, script: 0x5b, flags: 0x0}, + 259: {region: 0x166, script: 0x5b, flags: 0x0}, + 260: {region: 0x166, script: 0x5b, flags: 0x0}, + 261: {region: 0x166, script: 0x5b, flags: 0x0}, + 262: {region: 0x136, script: 0x5b, flags: 0x0}, + 263: {region: 0x107, script: 0x20, flags: 0x0}, + 264: {region: 0xa5, script: 0x5b, flags: 0x0}, + 265: {region: 0x166, script: 0x5b, flags: 0x0}, + 266: {region: 0x166, script: 0x5b, flags: 0x0}, + 267: {region: 0x9a, script: 0x5, flags: 0x0}, + 268: {region: 0x166, script: 0x5b, flags: 0x0}, + 269: {region: 0x61, script: 0x5b, flags: 0x0}, + 270: {region: 0x166, script: 0x5b, flags: 0x0}, + 271: {region: 0x49, script: 0x5b, flags: 0x0}, + 272: {region: 0x166, script: 0x5b, flags: 0x0}, + 273: {region: 0x166, script: 0x5b, flags: 0x0}, + 274: {region: 0x166, script: 0x5b, flags: 0x0}, + 275: {region: 0x166, script: 0x5, flags: 0x0}, + 276: {region: 0x49, script: 0x5b, flags: 0x0}, + 277: {region: 0x166, script: 0x5b, flags: 0x0}, + 278: {region: 0x166, script: 0x5b, flags: 0x0}, + 279: {region: 0xd5, script: 0x5b, flags: 0x0}, + 280: {region: 0x4f, script: 0x5b, flags: 0x0}, + 281: {region: 0x166, script: 0x5b, flags: 0x0}, + 282: {region: 0x9a, script: 0x5, flags: 0x0}, + 283: {region: 0x166, script: 0x5b, flags: 0x0}, + 284: {region: 0x166, script: 0x5b, flags: 0x0}, + 285: {region: 0x166, script: 0x5b, flags: 0x0}, + 286: {region: 0x166, script: 0x2c, flags: 0x0}, + 287: {region: 0x61, script: 0x5b, flags: 0x0}, + 288: {region: 0xc4, script: 0x5b, flags: 0x0}, + 289: {region: 0xd1, script: 0x5b, flags: 0x0}, + 290: {region: 0x166, script: 0x5b, flags: 0x0}, + 291: {region: 0xdc, script: 0x22, flags: 0x0}, + 292: {region: 0x52, script: 0x5b, flags: 0x0}, + 293: {region: 0x166, script: 0x5b, flags: 0x0}, + 294: {region: 0x166, script: 0x5b, flags: 0x0}, + 295: {region: 0x166, script: 0x5b, flags: 0x0}, + 296: {region: 0xce, script: 0xed, flags: 0x0}, + 297: {region: 0x166, script: 0x5b, flags: 0x0}, + 298: {region: 0x166, script: 0x5b, flags: 0x0}, + 299: {region: 0x115, script: 0x5b, flags: 0x0}, + 300: {region: 0x37, script: 0x5b, flags: 0x0}, + 301: {region: 0x43, script: 0xef, flags: 0x0}, + 302: {region: 0x166, script: 0x5b, flags: 0x0}, + 303: {region: 0xa5, script: 0x5b, flags: 0x0}, + 304: {region: 0x81, script: 0x5b, flags: 0x0}, + 305: {region: 0xd7, script: 0x5b, flags: 0x0}, + 306: {region: 0x9f, script: 0x5b, flags: 0x0}, + 307: {region: 0x6c, script: 0x29, flags: 0x0}, + 308: {region: 0x166, script: 0x5b, flags: 0x0}, + 309: {region: 0xc5, script: 0x4b, flags: 0x0}, + 310: {region: 0x88, script: 0x34, flags: 0x0}, + 311: {region: 0x166, script: 0x5b, flags: 0x0}, + 312: {region: 0x166, script: 0x5b, flags: 0x0}, + 313: {region: 0xa, script: 0x2, flags: 0x1}, + 314: {region: 0x166, script: 0x5b, flags: 0x0}, + 315: {region: 0x166, script: 0x5b, flags: 0x0}, + 316: {region: 0x1, script: 0x5b, flags: 0x0}, + 317: {region: 0x166, script: 0x5b, flags: 0x0}, + 318: {region: 0x6f, script: 0x5b, flags: 0x0}, + 319: {region: 0x136, script: 0x5b, flags: 0x0}, + 320: {region: 0x6b, script: 0x5b, flags: 0x0}, + 321: {region: 0x166, script: 0x5b, flags: 0x0}, + 322: {region: 0x9f, script: 0x46, flags: 0x0}, + 323: {region: 0x166, script: 0x5b, flags: 0x0}, + 324: {region: 0x166, script: 0x5b, flags: 0x0}, + 325: {region: 0x6f, script: 0x5b, flags: 0x0}, + 326: {region: 0x52, script: 0x5b, flags: 0x0}, + 327: {region: 0x6f, script: 0x5b, flags: 0x0}, + 328: {region: 0x9d, script: 0x5, flags: 0x0}, + 329: {region: 0x166, script: 0x5b, flags: 0x0}, + 330: {region: 0x166, script: 0x5b, flags: 0x0}, + 331: {region: 0x166, script: 0x5b, flags: 0x0}, + 332: {region: 0x166, script: 0x5b, flags: 0x0}, + 333: {region: 0x87, script: 0x5b, flags: 0x0}, + 334: {region: 0xc, script: 0x2, flags: 0x1}, + 335: {region: 0x166, script: 0x5b, flags: 0x0}, + 336: {region: 0xc4, script: 0x5b, flags: 0x0}, + 337: {region: 0x73, script: 0x5b, flags: 0x0}, + 338: {region: 0x10c, script: 0x5, flags: 0x0}, + 339: {region: 0xe8, script: 0x5b, flags: 0x0}, + 340: {region: 0x10d, script: 0x5b, flags: 0x0}, + 341: {region: 0x74, script: 0x5b, flags: 0x0}, + 342: {region: 0x166, script: 0x5b, flags: 0x0}, + 343: {region: 0x166, script: 0x5b, flags: 0x0}, + 344: {region: 0x77, script: 0x5b, flags: 0x0}, + 345: {region: 0x166, script: 0x5b, flags: 0x0}, + 346: {region: 0x3b, script: 0x5b, flags: 0x0}, + 347: {region: 0x166, script: 0x5b, flags: 0x0}, + 348: {region: 0x166, script: 0x5b, flags: 0x0}, + 349: {region: 0x166, script: 0x5b, flags: 0x0}, + 350: {region: 0x79, script: 0x5b, flags: 0x0}, + 351: {region: 0x136, script: 0x5b, flags: 0x0}, + 352: {region: 0x79, script: 0x5b, flags: 0x0}, + 353: {region: 0x61, script: 0x5b, flags: 0x0}, + 354: {region: 0x61, script: 0x5b, flags: 0x0}, + 355: {region: 0x52, script: 0x5, flags: 0x0}, + 356: {region: 0x141, script: 0x5b, flags: 0x0}, + 357: {region: 0x166, script: 0x5b, flags: 0x0}, + 358: {region: 0x85, script: 0x5b, flags: 0x0}, + 359: {region: 0x166, script: 0x5b, flags: 0x0}, + 360: {region: 0xd5, script: 0x5b, flags: 0x0}, + 361: {region: 0x9f, script: 0x5b, flags: 0x0}, + 362: {region: 0xd7, script: 0x5b, flags: 0x0}, + 363: {region: 0x166, script: 0x5b, flags: 0x0}, + 364: {region: 0x10c, script: 0x5b, flags: 0x0}, + 365: {region: 0xda, script: 0x5b, flags: 0x0}, + 366: {region: 0x97, script: 0x5b, flags: 0x0}, + 367: {region: 0x81, script: 0x5b, flags: 0x0}, + 368: {region: 0x166, script: 0x5b, flags: 0x0}, + 369: {region: 0xbd, script: 0x5b, flags: 0x0}, + 370: {region: 0x166, script: 0x5b, flags: 0x0}, + 371: {region: 0x166, script: 0x5b, flags: 0x0}, + 372: {region: 0x166, script: 0x5b, flags: 0x0}, + 373: {region: 0x53, script: 0x3b, flags: 0x0}, + 374: {region: 0x166, script: 0x5b, flags: 0x0}, + 375: {region: 0x96, script: 0x5b, flags: 0x0}, + 376: {region: 0x166, script: 0x5b, flags: 0x0}, + 377: {region: 0x166, script: 0x5b, flags: 0x0}, + 378: {region: 0x9a, script: 0x22, flags: 0x0}, + 379: {region: 0x166, script: 0x5b, flags: 0x0}, + 380: {region: 0x9d, script: 0x5, flags: 0x0}, + 381: {region: 0x7f, script: 0x5b, flags: 0x0}, + 382: {region: 0x7c, script: 0x5b, flags: 0x0}, + 383: {region: 0x166, script: 0x5b, flags: 0x0}, + 384: {region: 0x166, script: 0x5b, flags: 0x0}, + 385: {region: 0x166, script: 0x5b, flags: 0x0}, + 386: {region: 0x166, script: 0x5b, flags: 0x0}, + 387: {region: 0x166, script: 0x5b, flags: 0x0}, + 388: {region: 0x166, script: 0x5b, flags: 0x0}, + 389: {region: 0x70, script: 0x2c, flags: 0x0}, + 390: {region: 0x166, script: 0x5b, flags: 0x0}, + 391: {region: 0xdc, script: 0x22, flags: 0x0}, + 392: {region: 0x166, script: 0x5b, flags: 0x0}, + 393: {region: 0xa8, script: 0x5b, flags: 0x0}, + 394: {region: 0x166, script: 0x5b, flags: 0x0}, + 395: {region: 0xe9, script: 0x5, flags: 0x0}, + 396: {region: 0x166, script: 0x5b, flags: 0x0}, + 397: {region: 0xe9, script: 0x5, flags: 0x0}, + 398: {region: 0x166, script: 0x5b, flags: 0x0}, + 399: {region: 0x166, script: 0x5b, flags: 0x0}, + 400: {region: 0x6f, script: 0x5b, flags: 0x0}, + 401: {region: 0x9d, script: 0x5, flags: 0x0}, + 402: {region: 0x166, script: 0x5b, flags: 0x0}, + 403: {region: 0x166, script: 0x2c, flags: 0x0}, + 404: {region: 0xf2, script: 0x5b, flags: 0x0}, + 405: {region: 0x166, script: 0x5b, flags: 0x0}, + 406: {region: 0x166, script: 0x5b, flags: 0x0}, + 407: {region: 0x166, script: 0x5b, flags: 0x0}, + 408: {region: 0x166, script: 0x2c, flags: 0x0}, + 409: {region: 0x166, script: 0x5b, flags: 0x0}, + 410: {region: 0x9a, script: 0x22, flags: 0x0}, + 411: {region: 0x9a, script: 0xe9, flags: 0x0}, + 412: {region: 0x96, script: 0x5b, flags: 0x0}, + 413: {region: 0xda, script: 0x5b, flags: 0x0}, + 414: {region: 0x131, script: 0x32, flags: 0x0}, + 415: {region: 0x166, script: 0x5b, flags: 0x0}, + 416: {region: 0xe, script: 0x2, flags: 0x1}, + 417: {region: 0x9a, script: 0xe, flags: 0x0}, + 418: {region: 0x166, script: 0x5b, flags: 0x0}, + 419: {region: 0x4e, script: 0x5b, flags: 0x0}, + 420: {region: 0x9a, script: 0x35, flags: 0x0}, + 421: {region: 0x41, script: 0x5b, flags: 0x0}, + 422: {region: 0x54, script: 0x5b, flags: 0x0}, + 423: {region: 0x166, script: 0x5b, flags: 0x0}, + 424: {region: 0x81, script: 0x5b, flags: 0x0}, + 425: {region: 0x166, script: 0x5b, flags: 0x0}, + 426: {region: 0x166, script: 0x5b, flags: 0x0}, + 427: {region: 0xa5, script: 0x5b, flags: 0x0}, + 428: {region: 0x99, script: 0x5b, flags: 0x0}, + 429: {region: 0x166, script: 0x5b, flags: 0x0}, + 430: {region: 0xdc, script: 0x22, flags: 0x0}, + 431: {region: 0x166, script: 0x5b, flags: 0x0}, + 432: {region: 0x166, script: 0x5, flags: 0x0}, + 433: {region: 0x49, script: 0x5b, flags: 0x0}, + 434: {region: 0x166, script: 0x5, flags: 0x0}, + 435: {region: 0x166, script: 0x5b, flags: 0x0}, + 436: {region: 0x10, script: 0x3, flags: 0x1}, + 437: {region: 0x166, script: 0x5b, flags: 0x0}, + 438: {region: 0x53, script: 0x3b, flags: 0x0}, + 439: {region: 0x166, script: 0x5b, flags: 0x0}, + 440: {region: 0x136, script: 0x5b, flags: 0x0}, + 441: {region: 0x24, script: 0x5, flags: 0x0}, + 442: {region: 0x166, script: 0x5b, flags: 0x0}, + 443: {region: 0x166, script: 0x2c, flags: 0x0}, + 444: {region: 0x98, script: 0x3e, flags: 0x0}, + 445: {region: 0x166, script: 0x5b, flags: 0x0}, + 446: {region: 0x9a, script: 0x22, flags: 0x0}, + 447: {region: 0x166, script: 0x5b, flags: 0x0}, + 448: {region: 0x74, script: 0x5b, flags: 0x0}, + 449: {region: 0x166, script: 0x5b, flags: 0x0}, + 450: {region: 0x166, script: 0x5b, flags: 0x0}, + 451: {region: 0xe8, script: 0x5b, flags: 0x0}, + 452: {region: 0x166, script: 0x5b, flags: 0x0}, + 453: {region: 0x12c, script: 0x40, flags: 0x0}, + 454: {region: 0x53, script: 0x92, flags: 0x0}, + 455: {region: 0x166, script: 0x5b, flags: 0x0}, + 456: {region: 0xe9, script: 0x5, flags: 0x0}, + 457: {region: 0x9a, script: 0x22, flags: 0x0}, + 458: {region: 0xb0, script: 0x41, flags: 0x0}, + 459: {region: 0xe8, script: 0x5b, flags: 0x0}, + 460: {region: 0xe9, script: 0x5, flags: 0x0}, + 461: {region: 0xe7, script: 0x5b, flags: 0x0}, + 462: {region: 0x9a, script: 0x22, flags: 0x0}, + 463: {region: 0x9a, script: 0x22, flags: 0x0}, + 464: {region: 0x166, script: 0x5b, flags: 0x0}, + 465: {region: 0x91, script: 0x5b, flags: 0x0}, + 466: {region: 0x61, script: 0x5b, flags: 0x0}, + 467: {region: 0x53, script: 0x3b, flags: 0x0}, + 468: {region: 0x92, script: 0x5b, flags: 0x0}, + 469: {region: 0x93, script: 0x5b, flags: 0x0}, + 470: {region: 0x166, script: 0x5b, flags: 0x0}, + 471: {region: 0x28, script: 0x8, flags: 0x0}, + 472: {region: 0xd3, script: 0x5b, flags: 0x0}, + 473: {region: 0x79, script: 0x5b, flags: 0x0}, + 474: {region: 0x166, script: 0x5b, flags: 0x0}, + 475: {region: 0x166, script: 0x5b, flags: 0x0}, + 476: {region: 0xd1, script: 0x5b, flags: 0x0}, + 477: {region: 0xd7, script: 0x5b, flags: 0x0}, + 478: {region: 0x166, script: 0x5b, flags: 0x0}, + 479: {region: 0x166, script: 0x5b, flags: 0x0}, + 480: {region: 0x166, script: 0x5b, flags: 0x0}, + 481: {region: 0x96, script: 0x5b, flags: 0x0}, + 482: {region: 0x166, script: 0x5b, flags: 0x0}, + 483: {region: 0x166, script: 0x5b, flags: 0x0}, + 484: {region: 0x166, script: 0x5b, flags: 0x0}, + 486: {region: 0x123, script: 0x5b, flags: 0x0}, + 487: {region: 0xd7, script: 0x5b, flags: 0x0}, + 488: {region: 0x166, script: 0x5b, flags: 0x0}, + 489: {region: 0x166, script: 0x5b, flags: 0x0}, + 490: {region: 0x53, script: 0xfd, flags: 0x0}, + 491: {region: 0x166, script: 0x5b, flags: 0x0}, + 492: {region: 0x136, script: 0x5b, flags: 0x0}, + 493: {region: 0x166, script: 0x5b, flags: 0x0}, + 494: {region: 0x49, script: 0x5b, flags: 0x0}, + 495: {region: 0x166, script: 0x5b, flags: 0x0}, + 496: {region: 0x166, script: 0x5b, flags: 0x0}, + 497: {region: 0xe8, script: 0x5b, flags: 0x0}, + 498: {region: 0x166, script: 0x5b, flags: 0x0}, + 499: {region: 0x96, script: 0x5b, flags: 0x0}, + 500: {region: 0x107, script: 0x20, flags: 0x0}, + 501: {region: 0x1, script: 0x5b, flags: 0x0}, + 502: {region: 0x166, script: 0x5b, flags: 0x0}, + 503: {region: 0x166, script: 0x5b, flags: 0x0}, + 504: {region: 0x9e, script: 0x5b, flags: 0x0}, + 505: {region: 0x9f, script: 0x5b, flags: 0x0}, + 506: {region: 0x49, script: 0x17, flags: 0x0}, + 507: {region: 0x98, script: 0x3e, flags: 0x0}, + 508: {region: 0x166, script: 0x5b, flags: 0x0}, + 509: {region: 0x166, script: 0x5b, flags: 0x0}, + 510: {region: 0x107, script: 0x5b, flags: 0x0}, + 511: {region: 0x166, script: 0x5b, flags: 0x0}, + 512: {region: 0xa3, script: 0x49, flags: 0x0}, + 513: {region: 0x166, script: 0x5b, flags: 0x0}, + 514: {region: 0xa1, script: 0x5b, flags: 0x0}, + 515: {region: 0x1, script: 0x5b, flags: 0x0}, + 516: {region: 0x166, script: 0x5b, flags: 0x0}, + 517: {region: 0x166, script: 0x5b, flags: 0x0}, + 518: {region: 0x166, script: 0x5b, flags: 0x0}, + 519: {region: 0x52, script: 0x5b, flags: 0x0}, + 520: {region: 0x131, script: 0x3e, flags: 0x0}, + 521: {region: 0x166, script: 0x5b, flags: 0x0}, + 522: {region: 0x130, script: 0x5b, flags: 0x0}, + 523: {region: 0xdc, script: 0x22, flags: 0x0}, + 524: {region: 0x166, script: 0x5b, flags: 0x0}, + 525: {region: 0x64, script: 0x5b, flags: 0x0}, + 526: {region: 0x96, script: 0x5b, flags: 0x0}, + 527: {region: 0x96, script: 0x5b, flags: 0x0}, + 528: {region: 0x7e, script: 0x2e, flags: 0x0}, + 529: {region: 0x138, script: 0x20, flags: 0x0}, + 530: {region: 0x68, script: 0x5b, flags: 0x0}, + 531: {region: 0xc5, script: 0x5b, flags: 0x0}, + 532: {region: 0x166, script: 0x5b, flags: 0x0}, + 533: {region: 0x166, script: 0x5b, flags: 0x0}, + 534: {region: 0xd7, script: 0x5b, flags: 0x0}, + 535: {region: 0xa5, script: 0x5b, flags: 0x0}, + 536: {region: 0xc4, script: 0x5b, flags: 0x0}, + 537: {region: 0x107, script: 0x20, flags: 0x0}, + 538: {region: 0x166, script: 0x5b, flags: 0x0}, + 539: {region: 0x166, script: 0x5b, flags: 0x0}, + 540: {region: 0x166, script: 0x5b, flags: 0x0}, + 541: {region: 0x166, script: 0x5b, flags: 0x0}, + 542: {region: 0xd5, script: 0x5, flags: 0x0}, + 543: {region: 0xd7, script: 0x5b, flags: 0x0}, + 544: {region: 0x165, script: 0x5b, flags: 0x0}, + 545: {region: 0x166, script: 0x5b, flags: 0x0}, + 546: {region: 0x166, script: 0x5b, flags: 0x0}, + 547: {region: 0x130, script: 0x5b, flags: 0x0}, + 548: {region: 0x123, script: 0x5, flags: 0x0}, + 549: {region: 0x166, script: 0x5b, flags: 0x0}, + 550: {region: 0x124, script: 0xee, flags: 0x0}, + 551: {region: 0x5b, script: 0x5b, flags: 0x0}, + 552: {region: 0x52, script: 0x5b, flags: 0x0}, + 553: {region: 0x166, script: 0x5b, flags: 0x0}, + 554: {region: 0x4f, script: 0x5b, flags: 0x0}, + 555: {region: 0x9a, script: 0x22, flags: 0x0}, + 556: {region: 0x9a, script: 0x22, flags: 0x0}, + 557: {region: 0x4b, script: 0x5b, flags: 0x0}, + 558: {region: 0x96, script: 0x5b, flags: 0x0}, + 559: {region: 0x166, script: 0x5b, flags: 0x0}, + 560: {region: 0x41, script: 0x5b, flags: 0x0}, + 561: {region: 0x9a, script: 0x5b, flags: 0x0}, + 562: {region: 0x53, script: 0xe5, flags: 0x0}, + 563: {region: 0x9a, script: 0x22, flags: 0x0}, + 564: {region: 0xc4, script: 0x5b, flags: 0x0}, + 565: {region: 0x166, script: 0x5b, flags: 0x0}, + 566: {region: 0x9a, script: 0x76, flags: 0x0}, + 567: {region: 0xe9, script: 0x5, flags: 0x0}, + 568: {region: 0x166, script: 0x5b, flags: 0x0}, + 569: {region: 0xa5, script: 0x5b, flags: 0x0}, + 570: {region: 0x166, script: 0x5b, flags: 0x0}, + 571: {region: 0x12c, script: 0x5b, flags: 0x0}, + 572: {region: 0x166, script: 0x5b, flags: 0x0}, + 573: {region: 0xd3, script: 0x5b, flags: 0x0}, + 574: {region: 0x166, script: 0x5b, flags: 0x0}, + 575: {region: 0xb0, script: 0x58, flags: 0x0}, + 576: {region: 0x166, script: 0x5b, flags: 0x0}, + 577: {region: 0x166, script: 0x5b, flags: 0x0}, + 578: {region: 0x13, script: 0x6, flags: 0x1}, + 579: {region: 0x166, script: 0x5b, flags: 0x0}, + 580: {region: 0x52, script: 0x5b, flags: 0x0}, + 581: {region: 0x83, script: 0x5b, flags: 0x0}, + 582: {region: 0xa5, script: 0x5b, flags: 0x0}, + 583: {region: 0x166, script: 0x5b, flags: 0x0}, + 584: {region: 0x166, script: 0x5b, flags: 0x0}, + 585: {region: 0x166, script: 0x5b, flags: 0x0}, + 586: {region: 0xa7, script: 0x4f, flags: 0x0}, + 587: {region: 0x2a, script: 0x5b, flags: 0x0}, + 588: {region: 0x166, script: 0x5b, flags: 0x0}, + 589: {region: 0x166, script: 0x5b, flags: 0x0}, + 590: {region: 0x166, script: 0x5b, flags: 0x0}, + 591: {region: 0x166, script: 0x5b, flags: 0x0}, + 592: {region: 0x166, script: 0x5b, flags: 0x0}, + 593: {region: 0x9a, script: 0x53, flags: 0x0}, + 594: {region: 0x8c, script: 0x5b, flags: 0x0}, + 595: {region: 0x166, script: 0x5b, flags: 0x0}, + 596: {region: 0xac, script: 0x54, flags: 0x0}, + 597: {region: 0x107, script: 0x20, flags: 0x0}, + 598: {region: 0x9a, script: 0x22, flags: 0x0}, + 599: {region: 0x166, script: 0x5b, flags: 0x0}, + 600: {region: 0x76, script: 0x5b, flags: 0x0}, + 601: {region: 0x166, script: 0x5b, flags: 0x0}, + 602: {region: 0xb5, script: 0x5b, flags: 0x0}, + 603: {region: 0x166, script: 0x5b, flags: 0x0}, + 604: {region: 0x166, script: 0x5b, flags: 0x0}, + 605: {region: 0x166, script: 0x5b, flags: 0x0}, + 606: {region: 0x166, script: 0x5b, flags: 0x0}, + 607: {region: 0x166, script: 0x5b, flags: 0x0}, + 608: {region: 0x166, script: 0x5b, flags: 0x0}, + 609: {region: 0x166, script: 0x5b, flags: 0x0}, + 610: {region: 0x166, script: 0x2c, flags: 0x0}, + 611: {region: 0x166, script: 0x5b, flags: 0x0}, + 612: {region: 0x107, script: 0x20, flags: 0x0}, + 613: {region: 0x113, script: 0x5b, flags: 0x0}, + 614: {region: 0xe8, script: 0x5b, flags: 0x0}, + 615: {region: 0x107, script: 0x5b, flags: 0x0}, + 616: {region: 0x166, script: 0x5b, flags: 0x0}, + 617: {region: 0x9a, script: 0x22, flags: 0x0}, + 618: {region: 0x9a, script: 0x5, flags: 0x0}, + 619: {region: 0x130, script: 0x5b, flags: 0x0}, + 620: {region: 0x166, script: 0x5b, flags: 0x0}, + 621: {region: 0x52, script: 0x5b, flags: 0x0}, + 622: {region: 0x61, script: 0x5b, flags: 0x0}, + 623: {region: 0x166, script: 0x5b, flags: 0x0}, + 624: {region: 0x166, script: 0x5b, flags: 0x0}, + 625: {region: 0x166, script: 0x2c, flags: 0x0}, + 626: {region: 0x166, script: 0x5b, flags: 0x0}, + 627: {region: 0x166, script: 0x5b, flags: 0x0}, + 628: {region: 0x19, script: 0x3, flags: 0x1}, + 629: {region: 0x166, script: 0x5b, flags: 0x0}, + 630: {region: 0x166, script: 0x5b, flags: 0x0}, + 631: {region: 0x166, script: 0x5b, flags: 0x0}, + 632: {region: 0x166, script: 0x5b, flags: 0x0}, + 633: {region: 0x107, script: 0x20, flags: 0x0}, + 634: {region: 0x166, script: 0x5b, flags: 0x0}, + 635: {region: 0x166, script: 0x5b, flags: 0x0}, + 636: {region: 0x166, script: 0x5b, flags: 0x0}, + 637: {region: 0x107, script: 0x20, flags: 0x0}, + 638: {region: 0x166, script: 0x5b, flags: 0x0}, + 639: {region: 0x96, script: 0x5b, flags: 0x0}, + 640: {region: 0xe9, script: 0x5, flags: 0x0}, + 641: {region: 0x7c, script: 0x5b, flags: 0x0}, + 642: {region: 0x166, script: 0x5b, flags: 0x0}, + 643: {region: 0x166, script: 0x5b, flags: 0x0}, + 644: {region: 0x166, script: 0x5b, flags: 0x0}, + 645: {region: 0x166, script: 0x2c, flags: 0x0}, + 646: {region: 0x124, script: 0xee, flags: 0x0}, + 647: {region: 0xe9, script: 0x5, flags: 0x0}, + 648: {region: 0x166, script: 0x5b, flags: 0x0}, + 649: {region: 0x166, script: 0x5b, flags: 0x0}, + 650: {region: 0x1c, script: 0x5, flags: 0x1}, + 651: {region: 0x166, script: 0x5b, flags: 0x0}, + 652: {region: 0x166, script: 0x5b, flags: 0x0}, + 653: {region: 0x166, script: 0x5b, flags: 0x0}, + 654: {region: 0x139, script: 0x5b, flags: 0x0}, + 655: {region: 0x88, script: 0x5f, flags: 0x0}, + 656: {region: 0x98, script: 0x3e, flags: 0x0}, + 657: {region: 0x130, script: 0x5b, flags: 0x0}, + 658: {region: 0xe9, script: 0x5, flags: 0x0}, + 659: {region: 0x132, script: 0x5b, flags: 0x0}, + 660: {region: 0x166, script: 0x5b, flags: 0x0}, + 661: {region: 0xb8, script: 0x5b, flags: 0x0}, + 662: {region: 0x107, script: 0x20, flags: 0x0}, + 663: {region: 0x166, script: 0x5b, flags: 0x0}, + 664: {region: 0x96, script: 0x5b, flags: 0x0}, + 665: {region: 0x166, script: 0x5b, flags: 0x0}, + 666: {region: 0x53, script: 0xee, flags: 0x0}, + 667: {region: 0x166, script: 0x5b, flags: 0x0}, + 668: {region: 0x166, script: 0x5b, flags: 0x0}, + 669: {region: 0x166, script: 0x5b, flags: 0x0}, + 670: {region: 0x166, script: 0x5b, flags: 0x0}, + 671: {region: 0x9a, script: 0x5d, flags: 0x0}, + 672: {region: 0x166, script: 0x5b, flags: 0x0}, + 673: {region: 0x166, script: 0x5b, flags: 0x0}, + 674: {region: 0x107, script: 0x20, flags: 0x0}, + 675: {region: 0x132, script: 0x5b, flags: 0x0}, + 676: {region: 0x166, script: 0x5b, flags: 0x0}, + 677: {region: 0xda, script: 0x5b, flags: 0x0}, + 678: {region: 0x166, script: 0x5b, flags: 0x0}, + 679: {region: 0x166, script: 0x5b, flags: 0x0}, + 680: {region: 0x21, script: 0x2, flags: 0x1}, + 681: {region: 0x166, script: 0x5b, flags: 0x0}, + 682: {region: 0x166, script: 0x5b, flags: 0x0}, + 683: {region: 0x9f, script: 0x5b, flags: 0x0}, + 684: {region: 0x53, script: 0x61, flags: 0x0}, + 685: {region: 0x96, script: 0x5b, flags: 0x0}, + 686: {region: 0x9d, script: 0x5, flags: 0x0}, + 687: {region: 0x136, script: 0x5b, flags: 0x0}, + 688: {region: 0x166, script: 0x5b, flags: 0x0}, + 689: {region: 0x166, script: 0x5b, flags: 0x0}, + 690: {region: 0x9a, script: 0xe9, flags: 0x0}, + 691: {region: 0x9f, script: 0x5b, flags: 0x0}, + 692: {region: 0x166, script: 0x5b, flags: 0x0}, + 693: {region: 0x4b, script: 0x5b, flags: 0x0}, + 694: {region: 0x166, script: 0x5b, flags: 0x0}, + 695: {region: 0x166, script: 0x5b, flags: 0x0}, + 696: {region: 0xb0, script: 0x58, flags: 0x0}, + 697: {region: 0x166, script: 0x5b, flags: 0x0}, + 698: {region: 0x166, script: 0x5b, flags: 0x0}, + 699: {region: 0x4b, script: 0x5b, flags: 0x0}, + 700: {region: 0x166, script: 0x5b, flags: 0x0}, + 701: {region: 0x166, script: 0x5b, flags: 0x0}, + 702: {region: 0x163, script: 0x5b, flags: 0x0}, + 703: {region: 0x9d, script: 0x5, flags: 0x0}, + 704: {region: 0xb7, script: 0x5b, flags: 0x0}, + 705: {region: 0xb9, script: 0x5b, flags: 0x0}, + 706: {region: 0x4b, script: 0x5b, flags: 0x0}, + 707: {region: 0x4b, script: 0x5b, flags: 0x0}, + 708: {region: 0xa5, script: 0x5b, flags: 0x0}, + 709: {region: 0xa5, script: 0x5b, flags: 0x0}, + 710: {region: 0x9d, script: 0x5, flags: 0x0}, + 711: {region: 0xb9, script: 0x5b, flags: 0x0}, + 712: {region: 0x124, script: 0xee, flags: 0x0}, + 713: {region: 0x53, script: 0x3b, flags: 0x0}, + 714: {region: 0x12c, script: 0x5b, flags: 0x0}, + 715: {region: 0x96, script: 0x5b, flags: 0x0}, + 716: {region: 0x52, script: 0x5b, flags: 0x0}, + 717: {region: 0x9a, script: 0x22, flags: 0x0}, + 718: {region: 0x9a, script: 0x22, flags: 0x0}, + 719: {region: 0x96, script: 0x5b, flags: 0x0}, + 720: {region: 0x23, script: 0x3, flags: 0x1}, + 721: {region: 0xa5, script: 0x5b, flags: 0x0}, + 722: {region: 0x166, script: 0x5b, flags: 0x0}, + 723: {region: 0xd0, script: 0x5b, flags: 0x0}, + 724: {region: 0x166, script: 0x5b, flags: 0x0}, + 725: {region: 0x166, script: 0x5b, flags: 0x0}, + 726: {region: 0x166, script: 0x5b, flags: 0x0}, + 727: {region: 0x166, script: 0x5b, flags: 0x0}, + 728: {region: 0x166, script: 0x5b, flags: 0x0}, + 729: {region: 0x166, script: 0x5b, flags: 0x0}, + 730: {region: 0x166, script: 0x5b, flags: 0x0}, + 731: {region: 0x166, script: 0x5b, flags: 0x0}, + 732: {region: 0x166, script: 0x5b, flags: 0x0}, + 733: {region: 0x166, script: 0x5b, flags: 0x0}, + 734: {region: 0x166, script: 0x5b, flags: 0x0}, + 735: {region: 0x166, script: 0x5, flags: 0x0}, + 736: {region: 0x107, script: 0x20, flags: 0x0}, + 737: {region: 0xe8, script: 0x5b, flags: 0x0}, + 738: {region: 0x166, script: 0x5b, flags: 0x0}, + 739: {region: 0x96, script: 0x5b, flags: 0x0}, + 740: {region: 0x166, script: 0x2c, flags: 0x0}, + 741: {region: 0x166, script: 0x5b, flags: 0x0}, + 742: {region: 0x166, script: 0x5b, flags: 0x0}, + 743: {region: 0x166, script: 0x5b, flags: 0x0}, + 744: {region: 0x113, script: 0x5b, flags: 0x0}, + 745: {region: 0xa5, script: 0x5b, flags: 0x0}, + 746: {region: 0x166, script: 0x5b, flags: 0x0}, + 747: {region: 0x166, script: 0x5b, flags: 0x0}, + 748: {region: 0x124, script: 0x5, flags: 0x0}, + 749: {region: 0xcd, script: 0x5b, flags: 0x0}, + 750: {region: 0x166, script: 0x5b, flags: 0x0}, + 751: {region: 0x166, script: 0x5b, flags: 0x0}, + 752: {region: 0x166, script: 0x5b, flags: 0x0}, + 753: {region: 0xc0, script: 0x5b, flags: 0x0}, + 754: {region: 0xd2, script: 0x5b, flags: 0x0}, + 755: {region: 0x166, script: 0x5b, flags: 0x0}, + 756: {region: 0x52, script: 0x5b, flags: 0x0}, + 757: {region: 0xdc, script: 0x22, flags: 0x0}, + 758: {region: 0x130, script: 0x5b, flags: 0x0}, + 759: {region: 0xc1, script: 0x5b, flags: 0x0}, + 760: {region: 0x166, script: 0x5b, flags: 0x0}, + 761: {region: 0x166, script: 0x5b, flags: 0x0}, + 762: {region: 0xe1, script: 0x5b, flags: 0x0}, + 763: {region: 0x166, script: 0x5b, flags: 0x0}, + 764: {region: 0x96, script: 0x5b, flags: 0x0}, + 765: {region: 0x9c, script: 0x3d, flags: 0x0}, + 766: {region: 0x166, script: 0x5b, flags: 0x0}, + 767: {region: 0xc3, script: 0x20, flags: 0x0}, + 768: {region: 0x166, script: 0x5, flags: 0x0}, + 769: {region: 0x166, script: 0x5b, flags: 0x0}, + 770: {region: 0x166, script: 0x5b, flags: 0x0}, + 771: {region: 0x166, script: 0x5b, flags: 0x0}, + 772: {region: 0x9a, script: 0x6f, flags: 0x0}, + 773: {region: 0x166, script: 0x5b, flags: 0x0}, + 774: {region: 0x166, script: 0x5b, flags: 0x0}, + 775: {region: 0x10c, script: 0x5b, flags: 0x0}, + 776: {region: 0x166, script: 0x5b, flags: 0x0}, + 777: {region: 0x166, script: 0x5b, flags: 0x0}, + 778: {region: 0x166, script: 0x5b, flags: 0x0}, + 779: {region: 0x26, script: 0x3, flags: 0x1}, + 780: {region: 0x166, script: 0x5b, flags: 0x0}, + 781: {region: 0x166, script: 0x5b, flags: 0x0}, + 782: {region: 0x9a, script: 0xe, flags: 0x0}, + 783: {region: 0xc5, script: 0x76, flags: 0x0}, + 785: {region: 0x166, script: 0x5b, flags: 0x0}, + 786: {region: 0x49, script: 0x5b, flags: 0x0}, + 787: {region: 0x49, script: 0x5b, flags: 0x0}, + 788: {region: 0x37, script: 0x5b, flags: 0x0}, + 789: {region: 0x166, script: 0x5b, flags: 0x0}, + 790: {region: 0x166, script: 0x5b, flags: 0x0}, + 791: {region: 0x166, script: 0x5b, flags: 0x0}, + 792: {region: 0x166, script: 0x5b, flags: 0x0}, + 793: {region: 0x166, script: 0x5b, flags: 0x0}, + 794: {region: 0x166, script: 0x5b, flags: 0x0}, + 795: {region: 0x9a, script: 0x22, flags: 0x0}, + 796: {region: 0xdc, script: 0x22, flags: 0x0}, + 797: {region: 0x107, script: 0x20, flags: 0x0}, + 798: {region: 0x35, script: 0x73, flags: 0x0}, + 799: {region: 0x29, script: 0x3, flags: 0x1}, + 800: {region: 0xcc, script: 0x5b, flags: 0x0}, + 801: {region: 0x166, script: 0x5b, flags: 0x0}, + 802: {region: 0x166, script: 0x5b, flags: 0x0}, + 803: {region: 0x166, script: 0x5b, flags: 0x0}, + 804: {region: 0x9a, script: 0x22, flags: 0x0}, + 805: {region: 0x52, script: 0x5b, flags: 0x0}, + 807: {region: 0x166, script: 0x5b, flags: 0x0}, + 808: {region: 0x136, script: 0x5b, flags: 0x0}, + 809: {region: 0x166, script: 0x5b, flags: 0x0}, + 810: {region: 0x166, script: 0x5b, flags: 0x0}, + 811: {region: 0xe9, script: 0x5, flags: 0x0}, + 812: {region: 0xc4, script: 0x5b, flags: 0x0}, + 813: {region: 0x9a, script: 0x22, flags: 0x0}, + 814: {region: 0x96, script: 0x5b, flags: 0x0}, + 815: {region: 0x165, script: 0x5b, flags: 0x0}, + 816: {region: 0x166, script: 0x5b, flags: 0x0}, + 817: {region: 0xc5, script: 0x76, flags: 0x0}, + 818: {region: 0x166, script: 0x5b, flags: 0x0}, + 819: {region: 0x166, script: 0x2c, flags: 0x0}, + 820: {region: 0x107, script: 0x20, flags: 0x0}, + 821: {region: 0x166, script: 0x5b, flags: 0x0}, + 822: {region: 0x132, script: 0x5b, flags: 0x0}, + 823: {region: 0x9d, script: 0x67, flags: 0x0}, + 824: {region: 0x166, script: 0x5b, flags: 0x0}, + 825: {region: 0x166, script: 0x5b, flags: 0x0}, + 826: {region: 0x9d, script: 0x5, flags: 0x0}, + 827: {region: 0x166, script: 0x5b, flags: 0x0}, + 828: {region: 0x166, script: 0x5b, flags: 0x0}, + 829: {region: 0x166, script: 0x5b, flags: 0x0}, + 830: {region: 0xde, script: 0x5b, flags: 0x0}, + 831: {region: 0x166, script: 0x5b, flags: 0x0}, + 832: {region: 0x166, script: 0x5b, flags: 0x0}, + 834: {region: 0x166, script: 0x5b, flags: 0x0}, + 835: {region: 0x53, script: 0x3b, flags: 0x0}, + 836: {region: 0x9f, script: 0x5b, flags: 0x0}, + 837: {region: 0xd3, script: 0x5b, flags: 0x0}, + 838: {region: 0x166, script: 0x5b, flags: 0x0}, + 839: {region: 0xdb, script: 0x5b, flags: 0x0}, + 840: {region: 0x166, script: 0x5b, flags: 0x0}, + 841: {region: 0x166, script: 0x5b, flags: 0x0}, + 842: {region: 0x166, script: 0x5b, flags: 0x0}, + 843: {region: 0xd0, script: 0x5b, flags: 0x0}, + 844: {region: 0x166, script: 0x5b, flags: 0x0}, + 845: {region: 0x166, script: 0x5b, flags: 0x0}, + 846: {region: 0x165, script: 0x5b, flags: 0x0}, + 847: {region: 0xd2, script: 0x5b, flags: 0x0}, + 848: {region: 0x61, script: 0x5b, flags: 0x0}, + 849: {region: 0xdc, script: 0x22, flags: 0x0}, + 850: {region: 0x166, script: 0x5b, flags: 0x0}, + 851: {region: 0xdc, script: 0x22, flags: 0x0}, + 852: {region: 0x166, script: 0x5b, flags: 0x0}, + 853: {region: 0x166, script: 0x5b, flags: 0x0}, + 854: {region: 0xd3, script: 0x5b, flags: 0x0}, + 855: {region: 0x166, script: 0x5b, flags: 0x0}, + 856: {region: 0x166, script: 0x5b, flags: 0x0}, + 857: {region: 0xd2, script: 0x5b, flags: 0x0}, + 858: {region: 0x166, script: 0x5b, flags: 0x0}, + 859: {region: 0xd0, script: 0x5b, flags: 0x0}, + 860: {region: 0xd0, script: 0x5b, flags: 0x0}, + 861: {region: 0x166, script: 0x5b, flags: 0x0}, + 862: {region: 0x166, script: 0x5b, flags: 0x0}, + 863: {region: 0x96, script: 0x5b, flags: 0x0}, + 864: {region: 0x166, script: 0x5b, flags: 0x0}, + 865: {region: 0xe0, script: 0x5b, flags: 0x0}, + 866: {region: 0x166, script: 0x5b, flags: 0x0}, + 867: {region: 0x166, script: 0x5b, flags: 0x0}, + 868: {region: 0x9a, script: 0x5b, flags: 0x0}, + 869: {region: 0x166, script: 0x5b, flags: 0x0}, + 870: {region: 0x166, script: 0x5b, flags: 0x0}, + 871: {region: 0xda, script: 0x5b, flags: 0x0}, + 872: {region: 0x52, script: 0x5b, flags: 0x0}, + 873: {region: 0x166, script: 0x5b, flags: 0x0}, + 874: {region: 0xdb, script: 0x5b, flags: 0x0}, + 875: {region: 0x166, script: 0x5b, flags: 0x0}, + 876: {region: 0x52, script: 0x5b, flags: 0x0}, + 877: {region: 0x166, script: 0x5b, flags: 0x0}, + 878: {region: 0x166, script: 0x5b, flags: 0x0}, + 879: {region: 0xdb, script: 0x5b, flags: 0x0}, + 880: {region: 0x124, script: 0x57, flags: 0x0}, + 881: {region: 0x9a, script: 0x22, flags: 0x0}, + 882: {region: 0x10d, script: 0xcb, flags: 0x0}, + 883: {region: 0x166, script: 0x5b, flags: 0x0}, + 884: {region: 0x166, script: 0x5b, flags: 0x0}, + 885: {region: 0x85, script: 0x7e, flags: 0x0}, + 886: {region: 0x162, script: 0x5b, flags: 0x0}, + 887: {region: 0x166, script: 0x5b, flags: 0x0}, + 888: {region: 0x49, script: 0x17, flags: 0x0}, + 889: {region: 0x166, script: 0x5b, flags: 0x0}, + 890: {region: 0x162, script: 0x5b, flags: 0x0}, + 891: {region: 0x166, script: 0x5b, flags: 0x0}, + 892: {region: 0x166, script: 0x5b, flags: 0x0}, + 893: {region: 0x166, script: 0x5b, flags: 0x0}, + 894: {region: 0x166, script: 0x5b, flags: 0x0}, + 895: {region: 0x166, script: 0x5b, flags: 0x0}, + 896: {region: 0x118, script: 0x5b, flags: 0x0}, + 897: {region: 0x166, script: 0x5b, flags: 0x0}, + 898: {region: 0x166, script: 0x5b, flags: 0x0}, + 899: {region: 0x136, script: 0x5b, flags: 0x0}, + 900: {region: 0x166, script: 0x5b, flags: 0x0}, + 901: {region: 0x53, script: 0x5b, flags: 0x0}, + 902: {region: 0x166, script: 0x5b, flags: 0x0}, + 903: {region: 0xcf, script: 0x5b, flags: 0x0}, + 904: {region: 0x130, script: 0x5b, flags: 0x0}, + 905: {region: 0x132, script: 0x5b, flags: 0x0}, + 906: {region: 0x81, script: 0x5b, flags: 0x0}, + 907: {region: 0x79, script: 0x5b, flags: 0x0}, + 908: {region: 0x166, script: 0x5b, flags: 0x0}, + 910: {region: 0x166, script: 0x5b, flags: 0x0}, + 911: {region: 0x166, script: 0x5b, flags: 0x0}, + 912: {region: 0x70, script: 0x5b, flags: 0x0}, + 913: {region: 0x166, script: 0x5b, flags: 0x0}, + 914: {region: 0x166, script: 0x5b, flags: 0x0}, + 915: {region: 0x166, script: 0x5b, flags: 0x0}, + 916: {region: 0x166, script: 0x5b, flags: 0x0}, + 917: {region: 0x9a, script: 0x83, flags: 0x0}, + 918: {region: 0x166, script: 0x5b, flags: 0x0}, + 919: {region: 0x166, script: 0x5, flags: 0x0}, + 920: {region: 0x7e, script: 0x20, flags: 0x0}, + 921: {region: 0x136, script: 0x84, flags: 0x0}, + 922: {region: 0x166, script: 0x5, flags: 0x0}, + 923: {region: 0xc6, script: 0x82, flags: 0x0}, + 924: {region: 0x166, script: 0x5b, flags: 0x0}, + 925: {region: 0x2c, script: 0x3, flags: 0x1}, + 926: {region: 0xe8, script: 0x5b, flags: 0x0}, + 927: {region: 0x2f, script: 0x2, flags: 0x1}, + 928: {region: 0xe8, script: 0x5b, flags: 0x0}, + 929: {region: 0x30, script: 0x5b, flags: 0x0}, + 930: {region: 0xf1, script: 0x5b, flags: 0x0}, + 931: {region: 0x166, script: 0x5b, flags: 0x0}, + 932: {region: 0x79, script: 0x5b, flags: 0x0}, + 933: {region: 0xd7, script: 0x5b, flags: 0x0}, + 934: {region: 0x136, script: 0x5b, flags: 0x0}, + 935: {region: 0x49, script: 0x5b, flags: 0x0}, + 936: {region: 0x166, script: 0x5b, flags: 0x0}, + 937: {region: 0x9d, script: 0xfa, flags: 0x0}, + 938: {region: 0x166, script: 0x5b, flags: 0x0}, + 939: {region: 0x61, script: 0x5b, flags: 0x0}, + 940: {region: 0x166, script: 0x5, flags: 0x0}, + 941: {region: 0xb1, script: 0x90, flags: 0x0}, + 943: {region: 0x166, script: 0x5b, flags: 0x0}, + 944: {region: 0x166, script: 0x5b, flags: 0x0}, + 945: {region: 0x9a, script: 0x12, flags: 0x0}, + 946: {region: 0xa5, script: 0x5b, flags: 0x0}, + 947: {region: 0xea, script: 0x5b, flags: 0x0}, + 948: {region: 0x166, script: 0x5b, flags: 0x0}, + 949: {region: 0x9f, script: 0x5b, flags: 0x0}, + 950: {region: 0x166, script: 0x5b, flags: 0x0}, + 951: {region: 0x166, script: 0x5b, flags: 0x0}, + 952: {region: 0x88, script: 0x34, flags: 0x0}, + 953: {region: 0x76, script: 0x5b, flags: 0x0}, + 954: {region: 0x166, script: 0x5b, flags: 0x0}, + 955: {region: 0xe9, script: 0x4e, flags: 0x0}, + 956: {region: 0x9d, script: 0x5, flags: 0x0}, + 957: {region: 0x1, script: 0x5b, flags: 0x0}, + 958: {region: 0x24, script: 0x5, flags: 0x0}, + 959: {region: 0x166, script: 0x5b, flags: 0x0}, + 960: {region: 0x41, script: 0x5b, flags: 0x0}, + 961: {region: 0x166, script: 0x5b, flags: 0x0}, + 962: {region: 0x7b, script: 0x5b, flags: 0x0}, + 963: {region: 0x166, script: 0x5b, flags: 0x0}, + 964: {region: 0xe5, script: 0x5b, flags: 0x0}, + 965: {region: 0x8a, script: 0x5b, flags: 0x0}, + 966: {region: 0x6a, script: 0x5b, flags: 0x0}, + 967: {region: 0x166, script: 0x5b, flags: 0x0}, + 968: {region: 0x9a, script: 0x22, flags: 0x0}, + 969: {region: 0x166, script: 0x5b, flags: 0x0}, + 970: {region: 0x103, script: 0x5b, flags: 0x0}, + 971: {region: 0x96, script: 0x5b, flags: 0x0}, + 972: {region: 0x166, script: 0x5b, flags: 0x0}, + 973: {region: 0x166, script: 0x5b, flags: 0x0}, + 974: {region: 0x9f, script: 0x5b, flags: 0x0}, + 975: {region: 0x166, script: 0x5, flags: 0x0}, + 976: {region: 0x9a, script: 0x5b, flags: 0x0}, + 977: {region: 0x31, script: 0x2, flags: 0x1}, + 978: {region: 0xdc, script: 0x22, flags: 0x0}, + 979: {region: 0x35, script: 0xe, flags: 0x0}, + 980: {region: 0x4e, script: 0x5b, flags: 0x0}, + 981: {region: 0x73, script: 0x5b, flags: 0x0}, + 982: {region: 0x4e, script: 0x5b, flags: 0x0}, + 983: {region: 0x9d, script: 0x5, flags: 0x0}, + 984: {region: 0x10d, script: 0x5b, flags: 0x0}, + 985: {region: 0x3a, script: 0x5b, flags: 0x0}, + 986: {region: 0x166, script: 0x5b, flags: 0x0}, + 987: {region: 0xd2, script: 0x5b, flags: 0x0}, + 988: {region: 0x105, script: 0x5b, flags: 0x0}, + 989: {region: 0x96, script: 0x5b, flags: 0x0}, + 990: {region: 0x130, script: 0x5b, flags: 0x0}, + 991: {region: 0x166, script: 0x5b, flags: 0x0}, + 992: {region: 0x166, script: 0x5b, flags: 0x0}, + 993: {region: 0x74, script: 0x5b, flags: 0x0}, + 994: {region: 0x107, script: 0x20, flags: 0x0}, + 995: {region: 0x131, script: 0x20, flags: 0x0}, + 996: {region: 0x10a, script: 0x5b, flags: 0x0}, + 997: {region: 0x108, script: 0x5b, flags: 0x0}, + 998: {region: 0x130, script: 0x5b, flags: 0x0}, + 999: {region: 0x166, script: 0x5b, flags: 0x0}, + 1000: {region: 0xa3, script: 0x4c, flags: 0x0}, + 1001: {region: 0x9a, script: 0x22, flags: 0x0}, + 1002: {region: 0x81, script: 0x5b, flags: 0x0}, + 1003: {region: 0x107, script: 0x20, flags: 0x0}, + 1004: {region: 0xa5, script: 0x5b, flags: 0x0}, + 1005: {region: 0x96, script: 0x5b, flags: 0x0}, + 1006: {region: 0x9a, script: 0x5b, flags: 0x0}, + 1007: {region: 0x115, script: 0x5b, flags: 0x0}, + 1008: {region: 0x9a, script: 0xcf, flags: 0x0}, + 1009: {region: 0x166, script: 0x5b, flags: 0x0}, + 1010: {region: 0x166, script: 0x5b, flags: 0x0}, + 1011: {region: 0x130, script: 0x5b, flags: 0x0}, + 1012: {region: 0x9f, script: 0x5b, flags: 0x0}, + 1013: {region: 0x9a, script: 0x22, flags: 0x0}, + 1014: {region: 0x166, script: 0x5, flags: 0x0}, + 1015: {region: 0x9f, script: 0x5b, flags: 0x0}, + 1016: {region: 0x7c, script: 0x5b, flags: 0x0}, + 1017: {region: 0x49, script: 0x5b, flags: 0x0}, + 1018: {region: 0x33, script: 0x4, flags: 0x1}, + 1019: {region: 0x9f, script: 0x5b, flags: 0x0}, + 1020: {region: 0x9d, script: 0x5, flags: 0x0}, + 1021: {region: 0xdb, script: 0x5b, flags: 0x0}, + 1022: {region: 0x4f, script: 0x5b, flags: 0x0}, + 1023: {region: 0xd2, script: 0x5b, flags: 0x0}, + 1024: {region: 0xd0, script: 0x5b, flags: 0x0}, + 1025: {region: 0xc4, script: 0x5b, flags: 0x0}, + 1026: {region: 0x4c, script: 0x5b, flags: 0x0}, + 1027: {region: 0x97, script: 0x80, flags: 0x0}, + 1028: {region: 0xb7, script: 0x5b, flags: 0x0}, + 1029: {region: 0x166, script: 0x2c, flags: 0x0}, + 1030: {region: 0x166, script: 0x5b, flags: 0x0}, + 1032: {region: 0xbb, script: 0xeb, flags: 0x0}, + 1033: {region: 0x166, script: 0x5b, flags: 0x0}, + 1034: {region: 0xc5, script: 0x76, flags: 0x0}, + 1035: {region: 0x166, script: 0x5, flags: 0x0}, + 1036: {region: 0xb4, script: 0xd6, flags: 0x0}, + 1037: {region: 0x70, script: 0x5b, flags: 0x0}, + 1038: {region: 0x166, script: 0x5b, flags: 0x0}, + 1039: {region: 0x166, script: 0x5b, flags: 0x0}, + 1040: {region: 0x166, script: 0x5b, flags: 0x0}, + 1041: {region: 0x166, script: 0x5b, flags: 0x0}, + 1042: {region: 0x112, script: 0x5b, flags: 0x0}, + 1043: {region: 0x166, script: 0x5b, flags: 0x0}, + 1044: {region: 0xe9, script: 0x5, flags: 0x0}, + 1045: {region: 0x166, script: 0x5b, flags: 0x0}, + 1046: {region: 0x110, script: 0x5b, flags: 0x0}, + 1047: {region: 0x166, script: 0x5b, flags: 0x0}, + 1048: {region: 0xea, script: 0x5b, flags: 0x0}, + 1049: {region: 0x166, script: 0x5b, flags: 0x0}, + 1050: {region: 0x96, script: 0x5b, flags: 0x0}, + 1051: {region: 0x143, script: 0x5b, flags: 0x0}, + 1052: {region: 0x10d, script: 0x5b, flags: 0x0}, + 1054: {region: 0x10d, script: 0x5b, flags: 0x0}, + 1055: {region: 0x73, script: 0x5b, flags: 0x0}, + 1056: {region: 0x98, script: 0xcc, flags: 0x0}, + 1057: {region: 0x166, script: 0x5b, flags: 0x0}, + 1058: {region: 0x73, script: 0x5b, flags: 0x0}, + 1059: {region: 0x165, script: 0x5b, flags: 0x0}, + 1060: {region: 0x166, script: 0x5b, flags: 0x0}, + 1061: {region: 0xc4, script: 0x5b, flags: 0x0}, + 1062: {region: 0x166, script: 0x5b, flags: 0x0}, + 1063: {region: 0x166, script: 0x5b, flags: 0x0}, + 1064: {region: 0x166, script: 0x5b, flags: 0x0}, + 1065: {region: 0x116, script: 0x5b, flags: 0x0}, + 1066: {region: 0x166, script: 0x5b, flags: 0x0}, + 1067: {region: 0x166, script: 0x5b, flags: 0x0}, + 1068: {region: 0x124, script: 0xee, flags: 0x0}, + 1069: {region: 0x166, script: 0x5b, flags: 0x0}, + 1070: {region: 0x166, script: 0x5b, flags: 0x0}, + 1071: {region: 0x166, script: 0x5b, flags: 0x0}, + 1072: {region: 0x166, script: 0x5b, flags: 0x0}, + 1073: {region: 0x27, script: 0x5b, flags: 0x0}, + 1074: {region: 0x37, script: 0x5, flags: 0x1}, + 1075: {region: 0x9a, script: 0xd9, flags: 0x0}, + 1076: {region: 0x117, script: 0x5b, flags: 0x0}, + 1077: {region: 0x115, script: 0x5b, flags: 0x0}, + 1078: {region: 0x9a, script: 0x22, flags: 0x0}, + 1079: {region: 0x162, script: 0x5b, flags: 0x0}, + 1080: {region: 0x166, script: 0x5b, flags: 0x0}, + 1081: {region: 0x166, script: 0x5b, flags: 0x0}, + 1082: {region: 0x6e, script: 0x5b, flags: 0x0}, + 1083: {region: 0x162, script: 0x5b, flags: 0x0}, + 1084: {region: 0x166, script: 0x5b, flags: 0x0}, + 1085: {region: 0x61, script: 0x5b, flags: 0x0}, + 1086: {region: 0x96, script: 0x5b, flags: 0x0}, + 1087: {region: 0x166, script: 0x5b, flags: 0x0}, + 1088: {region: 0x166, script: 0x5b, flags: 0x0}, + 1089: {region: 0x130, script: 0x5b, flags: 0x0}, + 1090: {region: 0x166, script: 0x5b, flags: 0x0}, + 1091: {region: 0x85, script: 0x5b, flags: 0x0}, + 1092: {region: 0x10d, script: 0x5b, flags: 0x0}, + 1093: {region: 0x130, script: 0x5b, flags: 0x0}, + 1094: {region: 0x160, script: 0x5, flags: 0x0}, + 1095: {region: 0x4b, script: 0x5b, flags: 0x0}, + 1096: {region: 0x61, script: 0x5b, flags: 0x0}, + 1097: {region: 0x166, script: 0x5b, flags: 0x0}, + 1098: {region: 0x9a, script: 0x22, flags: 0x0}, + 1099: {region: 0x96, script: 0x5b, flags: 0x0}, + 1100: {region: 0x166, script: 0x5b, flags: 0x0}, + 1101: {region: 0x35, script: 0xe, flags: 0x0}, + 1102: {region: 0x9c, script: 0xde, flags: 0x0}, + 1103: {region: 0xea, script: 0x5b, flags: 0x0}, + 1104: {region: 0x9a, script: 0xe6, flags: 0x0}, + 1105: {region: 0xdc, script: 0x22, flags: 0x0}, + 1106: {region: 0x166, script: 0x5b, flags: 0x0}, + 1107: {region: 0x166, script: 0x5b, flags: 0x0}, + 1108: {region: 0x166, script: 0x5b, flags: 0x0}, + 1109: {region: 0x166, script: 0x5b, flags: 0x0}, + 1110: {region: 0x166, script: 0x5b, flags: 0x0}, + 1111: {region: 0x166, script: 0x5b, flags: 0x0}, + 1112: {region: 0x166, script: 0x5b, flags: 0x0}, + 1113: {region: 0x166, script: 0x5b, flags: 0x0}, + 1114: {region: 0xe8, script: 0x5b, flags: 0x0}, + 1115: {region: 0x166, script: 0x5b, flags: 0x0}, + 1116: {region: 0x166, script: 0x5b, flags: 0x0}, + 1117: {region: 0x9a, script: 0x53, flags: 0x0}, + 1118: {region: 0x53, script: 0xe4, flags: 0x0}, + 1119: {region: 0xdc, script: 0x22, flags: 0x0}, + 1120: {region: 0xdc, script: 0x22, flags: 0x0}, + 1121: {region: 0x9a, script: 0xe9, flags: 0x0}, + 1122: {region: 0x166, script: 0x5b, flags: 0x0}, + 1123: {region: 0x113, script: 0x5b, flags: 0x0}, + 1124: {region: 0x132, script: 0x5b, flags: 0x0}, + 1125: {region: 0x127, script: 0x5b, flags: 0x0}, + 1126: {region: 0x166, script: 0x5b, flags: 0x0}, + 1127: {region: 0x3c, script: 0x3, flags: 0x1}, + 1128: {region: 0x166, script: 0x5b, flags: 0x0}, + 1129: {region: 0x166, script: 0x5b, flags: 0x0}, + 1130: {region: 0x166, script: 0x5b, flags: 0x0}, + 1131: {region: 0x124, script: 0xee, flags: 0x0}, + 1132: {region: 0xdc, script: 0x22, flags: 0x0}, + 1133: {region: 0xdc, script: 0x22, flags: 0x0}, + 1134: {region: 0xdc, script: 0x22, flags: 0x0}, + 1135: {region: 0x70, script: 0x2c, flags: 0x0}, + 1136: {region: 0x166, script: 0x5b, flags: 0x0}, + 1137: {region: 0x6e, script: 0x2c, flags: 0x0}, + 1138: {region: 0x166, script: 0x5b, flags: 0x0}, + 1139: {region: 0x166, script: 0x5b, flags: 0x0}, + 1140: {region: 0x166, script: 0x5b, flags: 0x0}, + 1141: {region: 0xd7, script: 0x5b, flags: 0x0}, + 1142: {region: 0x128, script: 0x5b, flags: 0x0}, + 1143: {region: 0x126, script: 0x5b, flags: 0x0}, + 1144: {region: 0x32, script: 0x5b, flags: 0x0}, + 1145: {region: 0xdc, script: 0x22, flags: 0x0}, + 1146: {region: 0xe8, script: 0x5b, flags: 0x0}, + 1147: {region: 0x166, script: 0x5b, flags: 0x0}, + 1148: {region: 0x166, script: 0x5b, flags: 0x0}, + 1149: {region: 0x32, script: 0x5b, flags: 0x0}, + 1150: {region: 0xd5, script: 0x5b, flags: 0x0}, + 1151: {region: 0x166, script: 0x5b, flags: 0x0}, + 1152: {region: 0x162, script: 0x5b, flags: 0x0}, + 1153: {region: 0x166, script: 0x5b, flags: 0x0}, + 1154: {region: 0x12a, script: 0x5b, flags: 0x0}, + 1155: {region: 0x166, script: 0x5b, flags: 0x0}, + 1156: {region: 0xcf, script: 0x5b, flags: 0x0}, + 1157: {region: 0x166, script: 0x5b, flags: 0x0}, + 1158: {region: 0xe7, script: 0x5b, flags: 0x0}, + 1159: {region: 0x166, script: 0x5b, flags: 0x0}, + 1160: {region: 0x166, script: 0x5b, flags: 0x0}, + 1161: {region: 0x166, script: 0x5b, flags: 0x0}, + 1162: {region: 0x12c, script: 0x5b, flags: 0x0}, + 1163: {region: 0x12c, script: 0x5b, flags: 0x0}, + 1164: {region: 0x12f, script: 0x5b, flags: 0x0}, + 1165: {region: 0x166, script: 0x5, flags: 0x0}, + 1166: {region: 0x162, script: 0x5b, flags: 0x0}, + 1167: {region: 0x88, script: 0x34, flags: 0x0}, + 1168: {region: 0xdc, script: 0x22, flags: 0x0}, + 1169: {region: 0xe8, script: 0x5b, flags: 0x0}, + 1170: {region: 0x43, script: 0xef, flags: 0x0}, + 1171: {region: 0x166, script: 0x5b, flags: 0x0}, + 1172: {region: 0x107, script: 0x20, flags: 0x0}, + 1173: {region: 0x166, script: 0x5b, flags: 0x0}, + 1174: {region: 0x166, script: 0x5b, flags: 0x0}, + 1175: {region: 0x132, script: 0x5b, flags: 0x0}, + 1176: {region: 0x166, script: 0x5b, flags: 0x0}, + 1177: {region: 0x124, script: 0xee, flags: 0x0}, + 1178: {region: 0x32, script: 0x5b, flags: 0x0}, + 1179: {region: 0x166, script: 0x5b, flags: 0x0}, + 1180: {region: 0x166, script: 0x5b, flags: 0x0}, + 1181: {region: 0xcf, script: 0x5b, flags: 0x0}, + 1182: {region: 0x166, script: 0x5b, flags: 0x0}, + 1183: {region: 0x166, script: 0x5b, flags: 0x0}, + 1184: {region: 0x12e, script: 0x5b, flags: 0x0}, + 1185: {region: 0x166, script: 0x5b, flags: 0x0}, + 1187: {region: 0x166, script: 0x5b, flags: 0x0}, + 1188: {region: 0xd5, script: 0x5b, flags: 0x0}, + 1189: {region: 0x53, script: 0xe7, flags: 0x0}, + 1190: {region: 0xe6, script: 0x5b, flags: 0x0}, + 1191: {region: 0x166, script: 0x5b, flags: 0x0}, + 1192: {region: 0x107, script: 0x20, flags: 0x0}, + 1193: {region: 0xbb, script: 0x5b, flags: 0x0}, + 1194: {region: 0x166, script: 0x5b, flags: 0x0}, + 1195: {region: 0x107, script: 0x20, flags: 0x0}, + 1196: {region: 0x3f, script: 0x4, flags: 0x1}, + 1197: {region: 0x11d, script: 0xf3, flags: 0x0}, + 1198: {region: 0x131, script: 0x20, flags: 0x0}, + 1199: {region: 0x76, script: 0x5b, flags: 0x0}, + 1200: {region: 0x2a, script: 0x5b, flags: 0x0}, + 1202: {region: 0x43, script: 0x3, flags: 0x1}, + 1203: {region: 0x9a, script: 0xe, flags: 0x0}, + 1204: {region: 0xe9, script: 0x5, flags: 0x0}, + 1205: {region: 0x166, script: 0x5b, flags: 0x0}, + 1206: {region: 0x166, script: 0x5b, flags: 0x0}, + 1207: {region: 0x166, script: 0x5b, flags: 0x0}, + 1208: {region: 0x166, script: 0x5b, flags: 0x0}, + 1209: {region: 0x166, script: 0x5b, flags: 0x0}, + 1210: {region: 0x166, script: 0x5b, flags: 0x0}, + 1211: {region: 0x166, script: 0x5b, flags: 0x0}, + 1212: {region: 0x46, script: 0x4, flags: 0x1}, + 1213: {region: 0x166, script: 0x5b, flags: 0x0}, + 1214: {region: 0xb5, script: 0xf4, flags: 0x0}, + 1215: {region: 0x166, script: 0x5b, flags: 0x0}, + 1216: {region: 0x162, script: 0x5b, flags: 0x0}, + 1217: {region: 0x9f, script: 0x5b, flags: 0x0}, + 1218: {region: 0x107, script: 0x5b, flags: 0x0}, + 1219: {region: 0x13f, script: 0x5b, flags: 0x0}, + 1220: {region: 0x11c, script: 0x5b, flags: 0x0}, + 1221: {region: 0x166, script: 0x5b, flags: 0x0}, + 1222: {region: 0x36, script: 0x5b, flags: 0x0}, + 1223: {region: 0x61, script: 0x5b, flags: 0x0}, + 1224: {region: 0xd2, script: 0x5b, flags: 0x0}, + 1225: {region: 0x1, script: 0x5b, flags: 0x0}, + 1226: {region: 0x107, script: 0x5b, flags: 0x0}, + 1227: {region: 0x6b, script: 0x5b, flags: 0x0}, + 1228: {region: 0x130, script: 0x5b, flags: 0x0}, + 1229: {region: 0x166, script: 0x5b, flags: 0x0}, + 1230: {region: 0x36, script: 0x5b, flags: 0x0}, + 1231: {region: 0x4e, script: 0x5b, flags: 0x0}, + 1232: {region: 0x166, script: 0x5b, flags: 0x0}, + 1233: {region: 0x70, script: 0x2c, flags: 0x0}, + 1234: {region: 0x166, script: 0x5b, flags: 0x0}, + 1235: {region: 0xe8, script: 0x5b, flags: 0x0}, + 1236: {region: 0x2f, script: 0x5b, flags: 0x0}, + 1237: {region: 0x9a, script: 0xe9, flags: 0x0}, + 1238: {region: 0x9a, script: 0x22, flags: 0x0}, + 1239: {region: 0x166, script: 0x5b, flags: 0x0}, + 1240: {region: 0x166, script: 0x5b, flags: 0x0}, + 1241: {region: 0x166, script: 0x5b, flags: 0x0}, + 1242: {region: 0x166, script: 0x5b, flags: 0x0}, + 1243: {region: 0x166, script: 0x5b, flags: 0x0}, + 1244: {region: 0x166, script: 0x5b, flags: 0x0}, + 1245: {region: 0x166, script: 0x5b, flags: 0x0}, + 1246: {region: 0x166, script: 0x5b, flags: 0x0}, + 1247: {region: 0x166, script: 0x5b, flags: 0x0}, + 1248: {region: 0x141, script: 0x5b, flags: 0x0}, + 1249: {region: 0x166, script: 0x5b, flags: 0x0}, + 1250: {region: 0x166, script: 0x5b, flags: 0x0}, + 1251: {region: 0xa9, script: 0x5, flags: 0x0}, + 1252: {region: 0x166, script: 0x5b, flags: 0x0}, + 1253: {region: 0x115, script: 0x5b, flags: 0x0}, + 1254: {region: 0x166, script: 0x5b, flags: 0x0}, + 1255: {region: 0x166, script: 0x5b, flags: 0x0}, + 1256: {region: 0x166, script: 0x5b, flags: 0x0}, + 1257: {region: 0x166, script: 0x5b, flags: 0x0}, + 1258: {region: 0x9a, script: 0x22, flags: 0x0}, + 1259: {region: 0x53, script: 0x3b, flags: 0x0}, + 1260: {region: 0x166, script: 0x5b, flags: 0x0}, + 1261: {region: 0x166, script: 0x5b, flags: 0x0}, + 1262: {region: 0x41, script: 0x5b, flags: 0x0}, + 1263: {region: 0x166, script: 0x5b, flags: 0x0}, + 1264: {region: 0x12c, script: 0x18, flags: 0x0}, + 1265: {region: 0x166, script: 0x5b, flags: 0x0}, + 1266: {region: 0x162, script: 0x5b, flags: 0x0}, + 1267: {region: 0x166, script: 0x5b, flags: 0x0}, + 1268: {region: 0x12c, script: 0x63, flags: 0x0}, + 1269: {region: 0x12c, script: 0x64, flags: 0x0}, + 1270: {region: 0x7e, script: 0x2e, flags: 0x0}, + 1271: {region: 0x53, script: 0x68, flags: 0x0}, + 1272: {region: 0x10c, script: 0x6d, flags: 0x0}, + 1273: {region: 0x109, script: 0x79, flags: 0x0}, + 1274: {region: 0x9a, script: 0x22, flags: 0x0}, + 1275: {region: 0x132, script: 0x5b, flags: 0x0}, + 1276: {region: 0x166, script: 0x5b, flags: 0x0}, + 1277: {region: 0x9d, script: 0x93, flags: 0x0}, + 1278: {region: 0x166, script: 0x5b, flags: 0x0}, + 1279: {region: 0x15f, script: 0xce, flags: 0x0}, + 1280: {region: 0x166, script: 0x5b, flags: 0x0}, + 1281: {region: 0x166, script: 0x5b, flags: 0x0}, + 1282: {region: 0xdc, script: 0x22, flags: 0x0}, + 1283: {region: 0x166, script: 0x5b, flags: 0x0}, + 1284: {region: 0x166, script: 0x5b, flags: 0x0}, + 1285: {region: 0xd2, script: 0x5b, flags: 0x0}, + 1286: {region: 0x76, script: 0x5b, flags: 0x0}, + 1287: {region: 0x166, script: 0x5b, flags: 0x0}, + 1288: {region: 0x166, script: 0x5b, flags: 0x0}, + 1289: {region: 0x52, script: 0x5b, flags: 0x0}, + 1290: {region: 0x166, script: 0x5b, flags: 0x0}, + 1291: {region: 0x166, script: 0x5b, flags: 0x0}, + 1292: {region: 0x166, script: 0x5b, flags: 0x0}, + 1293: {region: 0x52, script: 0x5b, flags: 0x0}, + 1294: {region: 0x166, script: 0x5b, flags: 0x0}, + 1295: {region: 0x166, script: 0x5b, flags: 0x0}, + 1296: {region: 0x166, script: 0x5b, flags: 0x0}, + 1297: {region: 0x166, script: 0x5b, flags: 0x0}, + 1298: {region: 0x1, script: 0x3e, flags: 0x0}, + 1299: {region: 0x166, script: 0x5b, flags: 0x0}, + 1300: {region: 0x166, script: 0x5b, flags: 0x0}, + 1301: {region: 0x166, script: 0x5b, flags: 0x0}, + 1302: {region: 0x166, script: 0x5b, flags: 0x0}, + 1303: {region: 0x166, script: 0x5b, flags: 0x0}, + 1304: {region: 0xd7, script: 0x5b, flags: 0x0}, + 1305: {region: 0x166, script: 0x5b, flags: 0x0}, + 1306: {region: 0x166, script: 0x5b, flags: 0x0}, + 1307: {region: 0x166, script: 0x5b, flags: 0x0}, + 1308: {region: 0x41, script: 0x5b, flags: 0x0}, + 1309: {region: 0x166, script: 0x5b, flags: 0x0}, + 1310: {region: 0xd0, script: 0x5b, flags: 0x0}, + 1311: {region: 0x4a, script: 0x3, flags: 0x1}, + 1312: {region: 0x166, script: 0x5b, flags: 0x0}, + 1313: {region: 0x166, script: 0x5b, flags: 0x0}, + 1314: {region: 0x166, script: 0x5b, flags: 0x0}, + 1315: {region: 0x53, script: 0x5b, flags: 0x0}, + 1316: {region: 0x10c, script: 0x5b, flags: 0x0}, + 1318: {region: 0xa9, script: 0x5, flags: 0x0}, + 1319: {region: 0xda, script: 0x5b, flags: 0x0}, + 1320: {region: 0xbb, script: 0xeb, flags: 0x0}, + 1321: {region: 0x4d, script: 0x14, flags: 0x1}, + 1322: {region: 0x53, script: 0x7f, flags: 0x0}, + 1323: {region: 0x166, script: 0x5b, flags: 0x0}, + 1324: {region: 0x123, script: 0x5b, flags: 0x0}, + 1325: {region: 0xd1, script: 0x5b, flags: 0x0}, + 1326: {region: 0x166, script: 0x5b, flags: 0x0}, + 1327: {region: 0x162, script: 0x5b, flags: 0x0}, + 1329: {region: 0x12c, script: 0x5b, flags: 0x0}, +} + +// likelyLangList holds lists info associated with likelyLang. +// Size: 582 bytes, 97 elements +var likelyLangList = [97]likelyScriptRegion{ + 0: {region: 0x9d, script: 0x7, flags: 0x0}, + 1: {region: 0xa2, script: 0x7a, flags: 0x2}, + 2: {region: 0x11d, script: 0x87, flags: 0x2}, + 3: {region: 0x32, script: 0x5b, flags: 0x0}, + 4: {region: 0x9c, script: 0x5, flags: 0x4}, + 5: {region: 0x9d, script: 0x5, flags: 0x4}, + 6: {region: 0x107, script: 0x20, flags: 0x4}, + 7: {region: 0x9d, script: 0x5, flags: 0x2}, + 8: {region: 0x107, script: 0x20, flags: 0x0}, + 9: {region: 0x38, script: 0x2f, flags: 0x2}, + 10: {region: 0x136, script: 0x5b, flags: 0x0}, + 11: {region: 0x7c, script: 0xd1, flags: 0x2}, + 12: {region: 0x115, script: 0x5b, flags: 0x0}, + 13: {region: 0x85, script: 0x1, flags: 0x2}, + 14: {region: 0x5e, script: 0x1f, flags: 0x0}, + 15: {region: 0x88, script: 0x60, flags: 0x2}, + 16: {region: 0xd7, script: 0x5b, flags: 0x0}, + 17: {region: 0x52, script: 0x5, flags: 0x4}, + 18: {region: 0x10c, script: 0x5, flags: 0x4}, + 19: {region: 0xaf, script: 0x20, flags: 0x0}, + 20: {region: 0x24, script: 0x5, flags: 0x4}, + 21: {region: 0x53, script: 0x5, flags: 0x4}, + 22: {region: 0x9d, script: 0x5, flags: 0x4}, + 23: {region: 0xc6, script: 0x5, flags: 0x4}, + 24: {region: 0x53, script: 0x5, flags: 0x2}, + 25: {region: 0x12c, script: 0x5b, flags: 0x0}, + 26: {region: 0xb1, script: 0x5, flags: 0x4}, + 27: {region: 0x9c, script: 0x5, flags: 0x2}, + 28: {region: 0xa6, script: 0x20, flags: 0x0}, + 29: {region: 0x53, script: 0x5, flags: 0x4}, + 30: {region: 0x12c, script: 0x5b, flags: 0x4}, + 31: {region: 0x53, script: 0x5, flags: 0x2}, + 32: {region: 0x12c, script: 0x5b, flags: 0x2}, + 33: {region: 0xdc, script: 0x22, flags: 0x0}, + 34: {region: 0x9a, script: 0x5e, flags: 0x2}, + 35: {region: 0x84, script: 0x5b, flags: 0x0}, + 36: {region: 0x85, script: 0x7e, flags: 0x4}, + 37: {region: 0x85, script: 0x7e, flags: 0x2}, + 38: {region: 0xc6, script: 0x20, flags: 0x0}, + 39: {region: 0x53, script: 0x71, flags: 0x4}, + 40: {region: 0x53, script: 0x71, flags: 0x2}, + 41: {region: 0xd1, script: 0x5b, flags: 0x0}, + 42: {region: 0x4a, script: 0x5, flags: 0x4}, + 43: {region: 0x96, script: 0x5, flags: 0x4}, + 44: {region: 0x9a, script: 0x36, flags: 0x0}, + 45: {region: 0xe9, script: 0x5, flags: 0x4}, + 46: {region: 0xe9, script: 0x5, flags: 0x2}, + 47: {region: 0x9d, script: 0x8d, flags: 0x0}, + 48: {region: 0x53, script: 0x8e, flags: 0x2}, + 49: {region: 0xbb, script: 0xeb, flags: 0x0}, + 50: {region: 0xda, script: 0x5b, flags: 0x4}, + 51: {region: 0xe9, script: 0x5, flags: 0x0}, + 52: {region: 0x9a, script: 0x22, flags: 0x2}, + 53: {region: 0x9a, script: 0x50, flags: 0x2}, + 54: {region: 0x9a, script: 0xd5, flags: 0x2}, + 55: {region: 0x106, script: 0x20, flags: 0x0}, + 56: {region: 0xbe, script: 0x5b, flags: 0x4}, + 57: {region: 0x105, script: 0x5b, flags: 0x4}, + 58: {region: 0x107, script: 0x5b, flags: 0x4}, + 59: {region: 0x12c, script: 0x5b, flags: 0x4}, + 60: {region: 0x125, script: 0x20, flags: 0x0}, + 61: {region: 0xe9, script: 0x5, flags: 0x4}, + 62: {region: 0xe9, script: 0x5, flags: 0x2}, + 63: {region: 0x53, script: 0x5, flags: 0x0}, + 64: {region: 0xaf, script: 0x20, flags: 0x4}, + 65: {region: 0xc6, script: 0x20, flags: 0x4}, + 66: {region: 0xaf, script: 0x20, flags: 0x2}, + 67: {region: 0x9a, script: 0xe, flags: 0x0}, + 68: {region: 0xdc, script: 0x22, flags: 0x4}, + 69: {region: 0xdc, script: 0x22, flags: 0x2}, + 70: {region: 0x138, script: 0x5b, flags: 0x0}, + 71: {region: 0x24, script: 0x5, flags: 0x4}, + 72: {region: 0x53, script: 0x20, flags: 0x4}, + 73: {region: 0x24, script: 0x5, flags: 0x2}, + 74: {region: 0x8e, script: 0x3c, flags: 0x0}, + 75: {region: 0x53, script: 0x3b, flags: 0x4}, + 76: {region: 0x53, script: 0x3b, flags: 0x2}, + 77: {region: 0x53, script: 0x3b, flags: 0x0}, + 78: {region: 0x2f, script: 0x3c, flags: 0x4}, + 79: {region: 0x3e, script: 0x3c, flags: 0x4}, + 80: {region: 0x7c, script: 0x3c, flags: 0x4}, + 81: {region: 0x7f, script: 0x3c, flags: 0x4}, + 82: {region: 0x8e, script: 0x3c, flags: 0x4}, + 83: {region: 0x96, script: 0x3c, flags: 0x4}, + 84: {region: 0xc7, script: 0x3c, flags: 0x4}, + 85: {region: 0xd1, script: 0x3c, flags: 0x4}, + 86: {region: 0xe3, script: 0x3c, flags: 0x4}, + 87: {region: 0xe6, script: 0x3c, flags: 0x4}, + 88: {region: 0xe8, script: 0x3c, flags: 0x4}, + 89: {region: 0x117, script: 0x3c, flags: 0x4}, + 90: {region: 0x124, script: 0x3c, flags: 0x4}, + 91: {region: 0x12f, script: 0x3c, flags: 0x4}, + 92: {region: 0x136, script: 0x3c, flags: 0x4}, + 93: {region: 0x13f, script: 0x3c, flags: 0x4}, + 94: {region: 0x12f, script: 0x11, flags: 0x2}, + 95: {region: 0x12f, script: 0x37, flags: 0x2}, + 96: {region: 0x12f, script: 0x3c, flags: 0x2}, +} + +type likelyLangScript struct { + lang uint16 + script uint16 + flags uint8 +} + +// likelyRegion is a lookup table, indexed by regionID, for the most likely +// languages and scripts given incomplete information. If more entries exist +// for a given regionID, lang and script are the index and size respectively +// of the list in likelyRegionList. +// TODO: exclude containers and user-definable regions from the list. +// Size: 2154 bytes, 359 elements +var likelyRegion = [359]likelyLangScript{ + 34: {lang: 0xd7, script: 0x5b, flags: 0x0}, + 35: {lang: 0x3a, script: 0x5, flags: 0x0}, + 36: {lang: 0x0, script: 0x2, flags: 0x1}, + 39: {lang: 0x2, script: 0x2, flags: 0x1}, + 40: {lang: 0x4, script: 0x2, flags: 0x1}, + 42: {lang: 0x3c0, script: 0x5b, flags: 0x0}, + 43: {lang: 0x0, script: 0x5b, flags: 0x0}, + 44: {lang: 0x13e, script: 0x5b, flags: 0x0}, + 45: {lang: 0x41b, script: 0x5b, flags: 0x0}, + 46: {lang: 0x10d, script: 0x5b, flags: 0x0}, + 48: {lang: 0x367, script: 0x5b, flags: 0x0}, + 49: {lang: 0x444, script: 0x5b, flags: 0x0}, + 50: {lang: 0x58, script: 0x5b, flags: 0x0}, + 51: {lang: 0x6, script: 0x2, flags: 0x1}, + 53: {lang: 0xa5, script: 0xe, flags: 0x0}, + 54: {lang: 0x367, script: 0x5b, flags: 0x0}, + 55: {lang: 0x15e, script: 0x5b, flags: 0x0}, + 56: {lang: 0x7e, script: 0x20, flags: 0x0}, + 57: {lang: 0x3a, script: 0x5, flags: 0x0}, + 58: {lang: 0x3d9, script: 0x5b, flags: 0x0}, + 59: {lang: 0x15e, script: 0x5b, flags: 0x0}, + 60: {lang: 0x15e, script: 0x5b, flags: 0x0}, + 62: {lang: 0x31f, script: 0x5b, flags: 0x0}, + 63: {lang: 0x13e, script: 0x5b, flags: 0x0}, + 64: {lang: 0x3a1, script: 0x5b, flags: 0x0}, + 65: {lang: 0x3c0, script: 0x5b, flags: 0x0}, + 67: {lang: 0x8, script: 0x2, flags: 0x1}, + 69: {lang: 0x0, script: 0x5b, flags: 0x0}, + 71: {lang: 0x71, script: 0x20, flags: 0x0}, + 73: {lang: 0x512, script: 0x3e, flags: 0x2}, + 74: {lang: 0x31f, script: 0x5, flags: 0x2}, + 75: {lang: 0x445, script: 0x5b, flags: 0x0}, + 76: {lang: 0x15e, script: 0x5b, flags: 0x0}, + 77: {lang: 0x15e, script: 0x5b, flags: 0x0}, + 78: {lang: 0x10d, script: 0x5b, flags: 0x0}, + 79: {lang: 0x15e, script: 0x5b, flags: 0x0}, + 81: {lang: 0x13e, script: 0x5b, flags: 0x0}, + 82: {lang: 0x15e, script: 0x5b, flags: 0x0}, + 83: {lang: 0xa, script: 0x4, flags: 0x1}, + 84: {lang: 0x13e, script: 0x5b, flags: 0x0}, + 85: {lang: 0x0, script: 0x5b, flags: 0x0}, + 87: {lang: 0x13e, script: 0x5b, flags: 0x0}, + 90: {lang: 0x13e, script: 0x5b, flags: 0x0}, + 91: {lang: 0x3c0, script: 0x5b, flags: 0x0}, + 92: {lang: 0x3a1, script: 0x5b, flags: 0x0}, + 94: {lang: 0xe, script: 0x2, flags: 0x1}, + 95: {lang: 0xfa, script: 0x5b, flags: 0x0}, + 97: {lang: 0x10d, script: 0x5b, flags: 0x0}, + 99: {lang: 0x1, script: 0x5b, flags: 0x0}, + 100: {lang: 0x101, script: 0x5b, flags: 0x0}, + 102: {lang: 0x13e, script: 0x5b, flags: 0x0}, + 104: {lang: 0x10, script: 0x2, flags: 0x1}, + 105: {lang: 0x13e, script: 0x5b, flags: 0x0}, + 106: {lang: 0x13e, script: 0x5b, flags: 0x0}, + 107: {lang: 0x140, script: 0x5b, flags: 0x0}, + 108: {lang: 0x3a, script: 0x5, flags: 0x0}, + 109: {lang: 0x3a, script: 0x5, flags: 0x0}, + 110: {lang: 0x46f, script: 0x2c, flags: 0x0}, + 111: {lang: 0x13e, script: 0x5b, flags: 0x0}, + 112: {lang: 0x12, script: 0x2, flags: 0x1}, + 114: {lang: 0x10d, script: 0x5b, flags: 0x0}, + 115: {lang: 0x151, script: 0x5b, flags: 0x0}, + 116: {lang: 0x1c0, script: 0x22, flags: 0x2}, + 119: {lang: 0x158, script: 0x5b, flags: 0x0}, + 121: {lang: 0x15e, script: 0x5b, flags: 0x0}, + 123: {lang: 0x15e, script: 0x5b, flags: 0x0}, + 124: {lang: 0x14, script: 0x2, flags: 0x1}, + 126: {lang: 0x16, script: 0x3, flags: 0x1}, + 127: {lang: 0x15e, script: 0x5b, flags: 0x0}, + 129: {lang: 0x21, script: 0x5b, flags: 0x0}, + 131: {lang: 0x245, script: 0x5b, flags: 0x0}, + 133: {lang: 0x15e, script: 0x5b, flags: 0x0}, + 134: {lang: 0x15e, script: 0x5b, flags: 0x0}, + 135: {lang: 0x13e, script: 0x5b, flags: 0x0}, + 136: {lang: 0x19, script: 0x2, flags: 0x1}, + 137: {lang: 0x0, script: 0x5b, flags: 0x0}, + 138: {lang: 0x13e, script: 0x5b, flags: 0x0}, + 140: {lang: 0x3c0, script: 0x5b, flags: 0x0}, + 142: {lang: 0x529, script: 0x3c, flags: 0x0}, + 143: {lang: 0x0, script: 0x5b, flags: 0x0}, + 144: {lang: 0x13e, script: 0x5b, flags: 0x0}, + 145: {lang: 0x1d1, script: 0x5b, flags: 0x0}, + 146: {lang: 0x1d4, script: 0x5b, flags: 0x0}, + 147: {lang: 0x1d5, script: 0x5b, flags: 0x0}, + 149: {lang: 0x13e, script: 0x5b, flags: 0x0}, + 150: {lang: 0x1b, script: 0x2, flags: 0x1}, + 152: {lang: 0x1bc, script: 0x3e, flags: 0x0}, + 154: {lang: 0x1d, script: 0x3, flags: 0x1}, + 156: {lang: 0x3a, script: 0x5, flags: 0x0}, + 157: {lang: 0x20, script: 0x2, flags: 0x1}, + 158: {lang: 0x1f8, script: 0x5b, flags: 0x0}, + 159: {lang: 0x1f9, script: 0x5b, flags: 0x0}, + 162: {lang: 0x3a, script: 0x5, flags: 0x0}, + 163: {lang: 0x200, script: 0x49, flags: 0x0}, + 165: {lang: 0x445, script: 0x5b, flags: 0x0}, + 166: {lang: 0x28a, script: 0x20, flags: 0x0}, + 167: {lang: 0x22, script: 0x3, flags: 0x1}, + 169: {lang: 0x25, script: 0x2, flags: 0x1}, + 171: {lang: 0x254, script: 0x54, flags: 0x0}, + 172: {lang: 0x254, script: 0x54, flags: 0x0}, + 173: {lang: 0x3a, script: 0x5, flags: 0x0}, + 175: {lang: 0x3e2, script: 0x20, flags: 0x0}, + 176: {lang: 0x27, script: 0x2, flags: 0x1}, + 177: {lang: 0x3a, script: 0x5, flags: 0x0}, + 179: {lang: 0x10d, script: 0x5b, flags: 0x0}, + 180: {lang: 0x40c, script: 0xd6, flags: 0x0}, + 182: {lang: 0x43b, script: 0x5b, flags: 0x0}, + 183: {lang: 0x2c0, script: 0x5b, flags: 0x0}, + 184: {lang: 0x15e, script: 0x5b, flags: 0x0}, + 185: {lang: 0x2c7, script: 0x5b, flags: 0x0}, + 186: {lang: 0x3a, script: 0x5, flags: 0x0}, + 187: {lang: 0x29, script: 0x2, flags: 0x1}, + 188: {lang: 0x15e, script: 0x5b, flags: 0x0}, + 189: {lang: 0x2b, script: 0x2, flags: 0x1}, + 190: {lang: 0x432, script: 0x5b, flags: 0x0}, + 191: {lang: 0x15e, script: 0x5b, flags: 0x0}, + 192: {lang: 0x2f1, script: 0x5b, flags: 0x0}, + 195: {lang: 0x2d, script: 0x2, flags: 0x1}, + 196: {lang: 0xa0, script: 0x5b, flags: 0x0}, + 197: {lang: 0x2f, script: 0x2, flags: 0x1}, + 198: {lang: 0x31, script: 0x2, flags: 0x1}, + 199: {lang: 0x33, script: 0x2, flags: 0x1}, + 201: {lang: 0x15e, script: 0x5b, flags: 0x0}, + 202: {lang: 0x35, script: 0x2, flags: 0x1}, + 204: {lang: 0x320, script: 0x5b, flags: 0x0}, + 205: {lang: 0x37, script: 0x3, flags: 0x1}, + 206: {lang: 0x128, script: 0xed, flags: 0x0}, + 208: {lang: 0x13e, script: 0x5b, flags: 0x0}, + 209: {lang: 0x31f, script: 0x5b, flags: 0x0}, + 210: {lang: 0x3c0, script: 0x5b, flags: 0x0}, + 211: {lang: 0x16, script: 0x5b, flags: 0x0}, + 212: {lang: 0x15e, script: 0x5b, flags: 0x0}, + 213: {lang: 0x1b4, script: 0x5b, flags: 0x0}, + 215: {lang: 0x1b4, script: 0x5, flags: 0x2}, + 217: {lang: 0x13e, script: 0x5b, flags: 0x0}, + 218: {lang: 0x367, script: 0x5b, flags: 0x0}, + 219: {lang: 0x347, script: 0x5b, flags: 0x0}, + 220: {lang: 0x351, script: 0x22, flags: 0x0}, + 226: {lang: 0x3a, script: 0x5, flags: 0x0}, + 227: {lang: 0x13e, script: 0x5b, flags: 0x0}, + 229: {lang: 0x13e, script: 0x5b, flags: 0x0}, + 230: {lang: 0x15e, script: 0x5b, flags: 0x0}, + 231: {lang: 0x486, script: 0x5b, flags: 0x0}, + 232: {lang: 0x153, script: 0x5b, flags: 0x0}, + 233: {lang: 0x3a, script: 0x3, flags: 0x1}, + 234: {lang: 0x3b3, script: 0x5b, flags: 0x0}, + 235: {lang: 0x15e, script: 0x5b, flags: 0x0}, + 237: {lang: 0x13e, script: 0x5b, flags: 0x0}, + 238: {lang: 0x3a, script: 0x5, flags: 0x0}, + 239: {lang: 0x3c0, script: 0x5b, flags: 0x0}, + 241: {lang: 0x3a2, script: 0x5b, flags: 0x0}, + 242: {lang: 0x194, script: 0x5b, flags: 0x0}, + 244: {lang: 0x3a, script: 0x5, flags: 0x0}, + 259: {lang: 0x15e, script: 0x5b, flags: 0x0}, + 261: {lang: 0x3d, script: 0x2, flags: 0x1}, + 262: {lang: 0x432, script: 0x20, flags: 0x0}, + 263: {lang: 0x3f, script: 0x2, flags: 0x1}, + 264: {lang: 0x3e5, script: 0x5b, flags: 0x0}, + 265: {lang: 0x3a, script: 0x5, flags: 0x0}, + 267: {lang: 0x15e, script: 0x5b, flags: 0x0}, + 268: {lang: 0x3a, script: 0x5, flags: 0x0}, + 269: {lang: 0x41, script: 0x2, flags: 0x1}, + 272: {lang: 0x416, script: 0x5b, flags: 0x0}, + 273: {lang: 0x347, script: 0x5b, flags: 0x0}, + 274: {lang: 0x43, script: 0x2, flags: 0x1}, + 276: {lang: 0x1f9, script: 0x5b, flags: 0x0}, + 277: {lang: 0x15e, script: 0x5b, flags: 0x0}, + 278: {lang: 0x429, script: 0x5b, flags: 0x0}, + 279: {lang: 0x367, script: 0x5b, flags: 0x0}, + 281: {lang: 0x3c0, script: 0x5b, flags: 0x0}, + 283: {lang: 0x13e, script: 0x5b, flags: 0x0}, + 285: {lang: 0x45, script: 0x2, flags: 0x1}, + 289: {lang: 0x15e, script: 0x5b, flags: 0x0}, + 290: {lang: 0x15e, script: 0x5b, flags: 0x0}, + 291: {lang: 0x47, script: 0x2, flags: 0x1}, + 292: {lang: 0x49, script: 0x3, flags: 0x1}, + 293: {lang: 0x4c, script: 0x2, flags: 0x1}, + 294: {lang: 0x477, script: 0x5b, flags: 0x0}, + 295: {lang: 0x3c0, script: 0x5b, flags: 0x0}, + 296: {lang: 0x476, script: 0x5b, flags: 0x0}, + 297: {lang: 0x4e, script: 0x2, flags: 0x1}, + 298: {lang: 0x482, script: 0x5b, flags: 0x0}, + 300: {lang: 0x50, script: 0x4, flags: 0x1}, + 302: {lang: 0x4a0, script: 0x5b, flags: 0x0}, + 303: {lang: 0x54, script: 0x2, flags: 0x1}, + 304: {lang: 0x445, script: 0x5b, flags: 0x0}, + 305: {lang: 0x56, script: 0x3, flags: 0x1}, + 306: {lang: 0x445, script: 0x5b, flags: 0x0}, + 310: {lang: 0x512, script: 0x3e, flags: 0x2}, + 311: {lang: 0x13e, script: 0x5b, flags: 0x0}, + 312: {lang: 0x4bc, script: 0x5b, flags: 0x0}, + 313: {lang: 0x1f9, script: 0x5b, flags: 0x0}, + 316: {lang: 0x13e, script: 0x5b, flags: 0x0}, + 319: {lang: 0x4c3, script: 0x5b, flags: 0x0}, + 320: {lang: 0x8a, script: 0x5b, flags: 0x0}, + 321: {lang: 0x15e, script: 0x5b, flags: 0x0}, + 323: {lang: 0x41b, script: 0x5b, flags: 0x0}, + 334: {lang: 0x59, script: 0x2, flags: 0x1}, + 351: {lang: 0x3a, script: 0x5, flags: 0x0}, + 352: {lang: 0x5b, script: 0x2, flags: 0x1}, + 357: {lang: 0x423, script: 0x5b, flags: 0x0}, +} + +// likelyRegionList holds lists info associated with likelyRegion. +// Size: 558 bytes, 93 elements +var likelyRegionList = [93]likelyLangScript{ + 0: {lang: 0x148, script: 0x5, flags: 0x0}, + 1: {lang: 0x476, script: 0x5b, flags: 0x0}, + 2: {lang: 0x431, script: 0x5b, flags: 0x0}, + 3: {lang: 0x2ff, script: 0x20, flags: 0x0}, + 4: {lang: 0x1d7, script: 0x8, flags: 0x0}, + 5: {lang: 0x274, script: 0x5b, flags: 0x0}, + 6: {lang: 0xb7, script: 0x5b, flags: 0x0}, + 7: {lang: 0x432, script: 0x20, flags: 0x0}, + 8: {lang: 0x12d, script: 0xef, flags: 0x0}, + 9: {lang: 0x351, script: 0x22, flags: 0x0}, + 10: {lang: 0x529, script: 0x3b, flags: 0x0}, + 11: {lang: 0x4ac, script: 0x5, flags: 0x0}, + 12: {lang: 0x523, script: 0x5b, flags: 0x0}, + 13: {lang: 0x29a, script: 0xee, flags: 0x0}, + 14: {lang: 0x136, script: 0x34, flags: 0x0}, + 15: {lang: 0x48a, script: 0x5b, flags: 0x0}, + 16: {lang: 0x3a, script: 0x5, flags: 0x0}, + 17: {lang: 0x15e, script: 0x5b, flags: 0x0}, + 18: {lang: 0x27, script: 0x2c, flags: 0x0}, + 19: {lang: 0x139, script: 0x5b, flags: 0x0}, + 20: {lang: 0x26a, script: 0x5, flags: 0x2}, + 21: {lang: 0x512, script: 0x3e, flags: 0x2}, + 22: {lang: 0x210, script: 0x2e, flags: 0x0}, + 23: {lang: 0x5, script: 0x20, flags: 0x0}, + 24: {lang: 0x274, script: 0x5b, flags: 0x0}, + 25: {lang: 0x136, script: 0x34, flags: 0x0}, + 26: {lang: 0x2ff, script: 0x20, flags: 0x0}, + 27: {lang: 0x1e1, script: 0x5b, flags: 0x0}, + 28: {lang: 0x31f, script: 0x5, flags: 0x0}, + 29: {lang: 0x1be, script: 0x22, flags: 0x0}, + 30: {lang: 0x4b4, script: 0x5, flags: 0x0}, + 31: {lang: 0x236, script: 0x76, flags: 0x0}, + 32: {lang: 0x148, script: 0x5, flags: 0x0}, + 33: {lang: 0x476, script: 0x5b, flags: 0x0}, + 34: {lang: 0x24a, script: 0x4f, flags: 0x0}, + 35: {lang: 0xe6, script: 0x5, flags: 0x0}, + 36: {lang: 0x226, script: 0xee, flags: 0x0}, + 37: {lang: 0x3a, script: 0x5, flags: 0x0}, + 38: {lang: 0x15e, script: 0x5b, flags: 0x0}, + 39: {lang: 0x2b8, script: 0x58, flags: 0x0}, + 40: {lang: 0x226, script: 0xee, flags: 0x0}, + 41: {lang: 0x3a, script: 0x5, flags: 0x0}, + 42: {lang: 0x15e, script: 0x5b, flags: 0x0}, + 43: {lang: 0x3dc, script: 0x5b, flags: 0x0}, + 44: {lang: 0x4ae, script: 0x20, flags: 0x0}, + 45: {lang: 0x2ff, script: 0x20, flags: 0x0}, + 46: {lang: 0x431, script: 0x5b, flags: 0x0}, + 47: {lang: 0x331, script: 0x76, flags: 0x0}, + 48: {lang: 0x213, script: 0x5b, flags: 0x0}, + 49: {lang: 0x30b, script: 0x20, flags: 0x0}, + 50: {lang: 0x242, script: 0x5, flags: 0x0}, + 51: {lang: 0x529, script: 0x3c, flags: 0x0}, + 52: {lang: 0x3c0, script: 0x5b, flags: 0x0}, + 53: {lang: 0x3a, script: 0x5, flags: 0x0}, + 54: {lang: 0x15e, script: 0x5b, flags: 0x0}, + 55: {lang: 0x2ed, script: 0x5b, flags: 0x0}, + 56: {lang: 0x4b4, script: 0x5, flags: 0x0}, + 57: {lang: 0x88, script: 0x22, flags: 0x0}, + 58: {lang: 0x4b4, script: 0x5, flags: 0x0}, + 59: {lang: 0x4b4, script: 0x5, flags: 0x0}, + 60: {lang: 0xbe, script: 0x22, flags: 0x0}, + 61: {lang: 0x3dc, script: 0x5b, flags: 0x0}, + 62: {lang: 0x7e, script: 0x20, flags: 0x0}, + 63: {lang: 0x3e2, script: 0x20, flags: 0x0}, + 64: {lang: 0x267, script: 0x5b, flags: 0x0}, + 65: {lang: 0x444, script: 0x5b, flags: 0x0}, + 66: {lang: 0x512, script: 0x3e, flags: 0x0}, + 67: {lang: 0x412, script: 0x5b, flags: 0x0}, + 68: {lang: 0x4ae, script: 0x20, flags: 0x0}, + 69: {lang: 0x3a, script: 0x5, flags: 0x0}, + 70: {lang: 0x15e, script: 0x5b, flags: 0x0}, + 71: {lang: 0x15e, script: 0x5b, flags: 0x0}, + 72: {lang: 0x35, script: 0x5, flags: 0x0}, + 73: {lang: 0x46b, script: 0xee, flags: 0x0}, + 74: {lang: 0x2ec, script: 0x5, flags: 0x0}, + 75: {lang: 0x30f, script: 0x76, flags: 0x0}, + 76: {lang: 0x467, script: 0x20, flags: 0x0}, + 77: {lang: 0x148, script: 0x5, flags: 0x0}, + 78: {lang: 0x3a, script: 0x5, flags: 0x0}, + 79: {lang: 0x15e, script: 0x5b, flags: 0x0}, + 80: {lang: 0x48a, script: 0x5b, flags: 0x0}, + 81: {lang: 0x58, script: 0x5, flags: 0x0}, + 82: {lang: 0x219, script: 0x20, flags: 0x0}, + 83: {lang: 0x81, script: 0x34, flags: 0x0}, + 84: {lang: 0x529, script: 0x3c, flags: 0x0}, + 85: {lang: 0x48c, script: 0x5b, flags: 0x0}, + 86: {lang: 0x4ae, script: 0x20, flags: 0x0}, + 87: {lang: 0x512, script: 0x3e, flags: 0x0}, + 88: {lang: 0x3b3, script: 0x5b, flags: 0x0}, + 89: {lang: 0x431, script: 0x5b, flags: 0x0}, + 90: {lang: 0x432, script: 0x20, flags: 0x0}, + 91: {lang: 0x15e, script: 0x5b, flags: 0x0}, + 92: {lang: 0x446, script: 0x5, flags: 0x0}, +} + +type likelyTag struct { + lang uint16 + region uint16 + script uint16 +} + +// Size: 198 bytes, 33 elements +var likelyRegionGroup = [33]likelyTag{ + 1: {lang: 0x139, region: 0xd7, script: 0x5b}, + 2: {lang: 0x139, region: 0x136, script: 0x5b}, + 3: {lang: 0x3c0, region: 0x41, script: 0x5b}, + 4: {lang: 0x139, region: 0x2f, script: 0x5b}, + 5: {lang: 0x139, region: 0xd7, script: 0x5b}, + 6: {lang: 0x13e, region: 0xd0, script: 0x5b}, + 7: {lang: 0x445, region: 0x130, script: 0x5b}, + 8: {lang: 0x3a, region: 0x6c, script: 0x5}, + 9: {lang: 0x445, region: 0x4b, script: 0x5b}, + 10: {lang: 0x139, region: 0x162, script: 0x5b}, + 11: {lang: 0x139, region: 0x136, script: 0x5b}, + 12: {lang: 0x139, region: 0x136, script: 0x5b}, + 13: {lang: 0x13e, region: 0x5a, script: 0x5b}, + 14: {lang: 0x529, region: 0x53, script: 0x3b}, + 15: {lang: 0x1be, region: 0x9a, script: 0x22}, + 16: {lang: 0x1e1, region: 0x96, script: 0x5b}, + 17: {lang: 0x1f9, region: 0x9f, script: 0x5b}, + 18: {lang: 0x139, region: 0x2f, script: 0x5b}, + 19: {lang: 0x139, region: 0xe7, script: 0x5b}, + 20: {lang: 0x139, region: 0x8b, script: 0x5b}, + 21: {lang: 0x41b, region: 0x143, script: 0x5b}, + 22: {lang: 0x529, region: 0x53, script: 0x3b}, + 23: {lang: 0x4bc, region: 0x138, script: 0x5b}, + 24: {lang: 0x3a, region: 0x109, script: 0x5}, + 25: {lang: 0x3e2, region: 0x107, script: 0x20}, + 26: {lang: 0x3e2, region: 0x107, script: 0x20}, + 27: {lang: 0x139, region: 0x7c, script: 0x5b}, + 28: {lang: 0x10d, region: 0x61, script: 0x5b}, + 29: {lang: 0x139, region: 0xd7, script: 0x5b}, + 30: {lang: 0x13e, region: 0x1f, script: 0x5b}, + 31: {lang: 0x139, region: 0x9b, script: 0x5b}, + 32: {lang: 0x139, region: 0x7c, script: 0x5b}, +} + +// Size: 264 bytes, 33 elements +var regionContainment = [33]uint64{ + // Entry 0 - 1F + 0x00000001ffffffff, 0x00000000200007a2, 0x0000000000003044, 0x0000000000000008, + 0x00000000803c0010, 0x0000000000000020, 0x0000000000000040, 0x0000000000000080, + 0x0000000000000100, 0x0000000000000200, 0x0000000000000400, 0x000000004000384c, + 0x0000000000001000, 0x0000000000002000, 0x0000000000004000, 0x0000000000008000, + 0x0000000000010000, 0x0000000000020000, 0x0000000000040000, 0x0000000000080000, + 0x0000000000100000, 0x0000000000200000, 0x0000000001c1c000, 0x0000000000800000, + 0x0000000001000000, 0x000000001e020000, 0x0000000004000000, 0x0000000008000000, + 0x0000000010000000, 0x00000000200006a0, 0x0000000040002048, 0x0000000080000000, + // Entry 20 - 3F + 0x0000000100000000, +} + +// regionInclusion maps region identifiers to sets of regions in regionInclusionBits, +// where each set holds all groupings that are directly connected in a region +// containment graph. +// Size: 359 bytes, 359 elements +var regionInclusion = [359]uint8{ + // Entry 0 - 3F + 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, + 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, + 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, + 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x26, 0x23, + 0x24, 0x26, 0x27, 0x22, 0x28, 0x29, 0x2a, 0x2b, + 0x26, 0x2c, 0x24, 0x23, 0x26, 0x25, 0x2a, 0x2d, + 0x2e, 0x24, 0x2f, 0x2d, 0x26, 0x30, 0x31, 0x28, + // Entry 40 - 7F + 0x26, 0x28, 0x26, 0x25, 0x31, 0x22, 0x32, 0x33, + 0x34, 0x30, 0x22, 0x27, 0x27, 0x27, 0x35, 0x2d, + 0x29, 0x28, 0x27, 0x36, 0x28, 0x22, 0x21, 0x34, + 0x23, 0x21, 0x26, 0x2d, 0x26, 0x22, 0x37, 0x2e, + 0x35, 0x2a, 0x22, 0x2f, 0x38, 0x26, 0x26, 0x21, + 0x39, 0x39, 0x28, 0x38, 0x39, 0x39, 0x2f, 0x3a, + 0x2f, 0x20, 0x21, 0x38, 0x3b, 0x28, 0x3c, 0x2c, + 0x21, 0x2a, 0x35, 0x27, 0x38, 0x26, 0x24, 0x28, + // Entry 80 - BF + 0x2c, 0x2d, 0x23, 0x30, 0x2d, 0x2d, 0x26, 0x27, + 0x3a, 0x22, 0x34, 0x3c, 0x2d, 0x28, 0x36, 0x22, + 0x34, 0x3a, 0x26, 0x2e, 0x21, 0x39, 0x31, 0x38, + 0x24, 0x2c, 0x25, 0x22, 0x24, 0x25, 0x2c, 0x3a, + 0x2c, 0x26, 0x24, 0x36, 0x21, 0x2f, 0x3d, 0x31, + 0x3c, 0x2f, 0x26, 0x36, 0x36, 0x24, 0x26, 0x3d, + 0x31, 0x24, 0x26, 0x35, 0x25, 0x2d, 0x32, 0x38, + 0x2a, 0x38, 0x39, 0x39, 0x35, 0x33, 0x23, 0x26, + // Entry C0 - FF + 0x2f, 0x3c, 0x21, 0x23, 0x2d, 0x31, 0x36, 0x36, + 0x3c, 0x26, 0x2d, 0x26, 0x3a, 0x2f, 0x25, 0x2f, + 0x34, 0x31, 0x2f, 0x32, 0x3b, 0x2d, 0x2b, 0x2d, + 0x21, 0x34, 0x2a, 0x2c, 0x25, 0x21, 0x3c, 0x24, + 0x29, 0x2b, 0x24, 0x34, 0x21, 0x28, 0x29, 0x3b, + 0x31, 0x25, 0x2e, 0x30, 0x29, 0x26, 0x24, 0x3a, + 0x21, 0x3c, 0x28, 0x21, 0x24, 0x21, 0x21, 0x1f, + 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, + // Entry 100 - 13F + 0x21, 0x21, 0x21, 0x2f, 0x21, 0x2e, 0x23, 0x33, + 0x2f, 0x24, 0x3b, 0x2f, 0x39, 0x38, 0x31, 0x2d, + 0x3a, 0x2c, 0x2e, 0x2d, 0x23, 0x2d, 0x2f, 0x28, + 0x2f, 0x27, 0x33, 0x34, 0x26, 0x24, 0x32, 0x22, + 0x26, 0x27, 0x22, 0x2d, 0x31, 0x3d, 0x29, 0x31, + 0x3d, 0x39, 0x29, 0x31, 0x24, 0x26, 0x29, 0x36, + 0x2f, 0x33, 0x2f, 0x21, 0x22, 0x21, 0x30, 0x28, + 0x3d, 0x23, 0x26, 0x21, 0x28, 0x26, 0x26, 0x31, + // Entry 140 - 17F + 0x3b, 0x29, 0x21, 0x29, 0x21, 0x21, 0x21, 0x21, + 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x23, 0x21, + 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, + 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x24, 0x24, + 0x2f, 0x23, 0x32, 0x2f, 0x27, 0x2f, 0x21, +} + +// regionInclusionBits is an array of bit vectors where every vector represents +// a set of region groupings. These sets are used to compute the distance +// between two regions for the purpose of language matching. +// Size: 584 bytes, 73 elements +var regionInclusionBits = [73]uint64{ + // Entry 0 - 1F + 0x0000000102400813, 0x00000000200007a3, 0x0000000000003844, 0x0000000040000808, + 0x00000000803c0011, 0x0000000020000022, 0x0000000040000844, 0x0000000020000082, + 0x0000000000000102, 0x0000000020000202, 0x0000000020000402, 0x000000004000384d, + 0x0000000000001804, 0x0000000040002804, 0x0000000000404000, 0x0000000000408000, + 0x0000000000410000, 0x0000000002020000, 0x0000000000040010, 0x0000000000080010, + 0x0000000000100010, 0x0000000000200010, 0x0000000001c1c001, 0x0000000000c00000, + 0x0000000001400000, 0x000000001e020001, 0x0000000006000000, 0x000000000a000000, + 0x0000000012000000, 0x00000000200006a2, 0x0000000040002848, 0x0000000080000010, + // Entry 20 - 3F + 0x0000000100000001, 0x0000000000000001, 0x0000000080000000, 0x0000000000020000, + 0x0000000001000000, 0x0000000000008000, 0x0000000000002000, 0x0000000000000200, + 0x0000000000000008, 0x0000000000200000, 0x0000000110000000, 0x0000000000040000, + 0x0000000008000000, 0x0000000000000020, 0x0000000104000000, 0x0000000000000080, + 0x0000000000001000, 0x0000000000010000, 0x0000000000000400, 0x0000000004000000, + 0x0000000000000040, 0x0000000010000000, 0x0000000000004000, 0x0000000101000000, + 0x0000000108000000, 0x0000000000000100, 0x0000000100020000, 0x0000000000080000, + 0x0000000000100000, 0x0000000000800000, 0x00000001ffffffff, 0x0000000122400fb3, + // Entry 40 - 5F + 0x00000001827c0813, 0x000000014240385f, 0x0000000103c1c813, 0x000000011e420813, + 0x0000000112000001, 0x0000000106000001, 0x0000000101400001, 0x000000010a000001, + 0x0000000102020001, +} + +// regionInclusionNext marks, for each entry in regionInclusionBits, the set of +// all groups that are reachable from the groups set in the respective entry. +// Size: 73 bytes, 73 elements +var regionInclusionNext = [73]uint8{ + // Entry 0 - 3F + 0x3e, 0x3f, 0x0b, 0x0b, 0x40, 0x01, 0x0b, 0x01, + 0x01, 0x01, 0x01, 0x41, 0x0b, 0x0b, 0x16, 0x16, + 0x16, 0x19, 0x04, 0x04, 0x04, 0x04, 0x42, 0x16, + 0x16, 0x43, 0x19, 0x19, 0x19, 0x01, 0x0b, 0x04, + 0x00, 0x00, 0x1f, 0x11, 0x18, 0x0f, 0x0d, 0x09, + 0x03, 0x15, 0x44, 0x12, 0x1b, 0x05, 0x45, 0x07, + 0x0c, 0x10, 0x0a, 0x1a, 0x06, 0x1c, 0x0e, 0x46, + 0x47, 0x08, 0x48, 0x13, 0x14, 0x17, 0x3e, 0x3e, + // Entry 40 - 7F + 0x3e, 0x3e, 0x3e, 0x3e, 0x43, 0x43, 0x42, 0x43, + 0x43, +} + +type parentRel struct { + lang uint16 + script uint16 + maxScript uint16 + toRegion uint16 + fromRegion []uint16 +} + +// Size: 414 bytes, 5 elements +var parents = [5]parentRel{ + 0: {lang: 0x139, script: 0x0, maxScript: 0x5b, toRegion: 0x1, fromRegion: []uint16{0x1a, 0x25, 0x26, 0x2f, 0x34, 0x36, 0x3d, 0x42, 0x46, 0x48, 0x49, 0x4a, 0x50, 0x52, 0x5d, 0x5e, 0x62, 0x65, 0x6e, 0x74, 0x75, 0x76, 0x7c, 0x7d, 0x80, 0x81, 0x82, 0x84, 0x8d, 0x8e, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0xa0, 0xa1, 0xa5, 0xa8, 0xaa, 0xae, 0xb2, 0xb5, 0xb6, 0xc0, 0xc7, 0xcb, 0xcc, 0xcd, 0xcf, 0xd1, 0xd3, 0xd6, 0xd7, 0xde, 0xe0, 0xe1, 0xe7, 0xe8, 0xe9, 0xec, 0xf1, 0x108, 0x10a, 0x10b, 0x10c, 0x10e, 0x10f, 0x113, 0x118, 0x11c, 0x11e, 0x120, 0x126, 0x12a, 0x12d, 0x12e, 0x130, 0x132, 0x13a, 0x13d, 0x140, 0x143, 0x162, 0x163, 0x165}}, + 1: {lang: 0x139, script: 0x0, maxScript: 0x5b, toRegion: 0x1a, fromRegion: []uint16{0x2e, 0x4e, 0x61, 0x64, 0x73, 0xda, 0x10d, 0x110}}, + 2: {lang: 0x13e, script: 0x0, maxScript: 0x5b, toRegion: 0x1f, fromRegion: []uint16{0x2c, 0x3f, 0x41, 0x48, 0x51, 0x54, 0x57, 0x5a, 0x66, 0x6a, 0x8a, 0x90, 0xd0, 0xd9, 0xe3, 0xe5, 0xed, 0xf2, 0x11b, 0x136, 0x137, 0x13c}}, + 3: {lang: 0x3c0, script: 0x0, maxScript: 0x5b, toRegion: 0xef, fromRegion: []uint16{0x2a, 0x4e, 0x5b, 0x87, 0x8c, 0xb8, 0xc7, 0xd2, 0x119, 0x127}}, + 4: {lang: 0x529, script: 0x3c, maxScript: 0x3c, toRegion: 0x8e, fromRegion: []uint16{0xc7}}, +} + +// Total table size 30466 bytes (29KiB); checksum: 7544152B diff --git a/vendor/golang.org/x/text/internal/language/tags.go b/vendor/golang.org/x/text/internal/language/tags.go new file mode 100644 index 000000000..e7afd3188 --- /dev/null +++ b/vendor/golang.org/x/text/internal/language/tags.go @@ -0,0 +1,48 @@ +// Copyright 2013 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 language + +// MustParse is like Parse, but panics if the given BCP 47 tag cannot be parsed. +// It simplifies safe initialization of Tag values. +func MustParse(s string) Tag { + t, err := Parse(s) + if err != nil { + panic(err) + } + return t +} + +// MustParseBase is like ParseBase, but panics if the given base cannot be parsed. +// It simplifies safe initialization of Base values. +func MustParseBase(s string) Language { + b, err := ParseBase(s) + if err != nil { + panic(err) + } + return b +} + +// MustParseScript is like ParseScript, but panics if the given script cannot be +// parsed. It simplifies safe initialization of Script values. +func MustParseScript(s string) Script { + scr, err := ParseScript(s) + if err != nil { + panic(err) + } + return scr +} + +// MustParseRegion is like ParseRegion, but panics if the given region cannot be +// parsed. It simplifies safe initialization of Region values. +func MustParseRegion(s string) Region { + r, err := ParseRegion(s) + if err != nil { + panic(err) + } + return r +} + +// Und is the root language. +var Und Tag diff --git a/vendor/golang.org/x/text/internal/match.go b/vendor/golang.org/x/text/internal/match.go new file mode 100644 index 000000000..1cc004a6d --- /dev/null +++ b/vendor/golang.org/x/text/internal/match.go @@ -0,0 +1,67 @@ +// 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 internal + +// This file contains matchers that implement CLDR inheritance. +// +// See https://unicode.org/reports/tr35/#Locale_Inheritance. +// +// Some of the inheritance described in this document is already handled by +// the cldr package. + +import ( + "golang.org/x/text/language" +) + +// TODO: consider if (some of the) matching algorithm needs to be public after +// getting some feel about what is generic and what is specific. + +// NewInheritanceMatcher returns a matcher that matches based on the inheritance +// chain. +// +// The matcher uses canonicalization and the parent relationship to find a +// match. The resulting match will always be either Und or a language with the +// same language and script as the requested language. It will not match +// languages for which there is understood to be mutual or one-directional +// intelligibility. +// +// A Match will indicate an Exact match if the language matches after +// canonicalization and High if the matched tag is a parent. +func NewInheritanceMatcher(t []language.Tag) *InheritanceMatcher { + tags := &InheritanceMatcher{make(map[language.Tag]int)} + for i, tag := range t { + ct, err := language.All.Canonicalize(tag) + if err != nil { + ct = tag + } + tags.index[ct] = i + } + return tags +} + +type InheritanceMatcher struct { + index map[language.Tag]int +} + +func (m InheritanceMatcher) Match(want ...language.Tag) (language.Tag, int, language.Confidence) { + for _, t := range want { + ct, err := language.All.Canonicalize(t) + if err != nil { + ct = t + } + conf := language.Exact + for { + if index, ok := m.index[ct]; ok { + return ct, index, conf + } + if ct == language.Und { + break + } + ct = ct.Parent() + conf = language.High + } + } + return language.Und, 0, language.No +} 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 000000000..a6e9c8e0d --- /dev/null +++ b/vendor/golang.org/x/text/internal/number/common.go @@ -0,0 +1,55 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +package number + +import ( + "unicode/utf8" + + "golang.org/x/text/internal/language/compact" +) + +// 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 compact.ID + 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 000000000..e128cf343 --- /dev/null +++ b/vendor/golang.org/x/text/internal/number/decimal.go @@ -0,0 +1,500 @@ +// 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 usable 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/format.go b/vendor/golang.org/x/text/internal/number/format.go new file mode 100644 index 000000000..cd94c5dc4 --- /dev/null +++ b/vendor/golang.org/x/text/internal/number/format.go @@ -0,0 +1,535 @@ +// 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) + f.Pattern = formats[index[tagToID(t)]] +} + +// 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/number.go b/vendor/golang.org/x/text/internal/number/number.go new file mode 100644 index 000000000..e1d933c3f --- /dev/null +++ b/vendor/golang.org/x/text/internal/number/number.go @@ -0,0 +1,152 @@ +// 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/language/compact" + "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 compact.ID, 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 = langIndex.Parent() + } else { + // The index points to a list of symbol data indexes. + for _, e := range langToAlt[p&^hasNonLatnMask:] { + if 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 + // https://unicode.org/reports/tr35/#Locale_Inheritance. + ns = numLatn + langIndex = compactIndex + continue outerLoop + } + // Fall back to parent. + langIndex = langIndex.Parent() + } 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 { + return InfoFromLangID(tagToID(t), t.TypeForKey("nu")) +} + +// 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 { + return &formats[index[tagToID(t)]] +} + +func tagToID(t language.Tag) compact.ID { + id, _ := compact.RegionalID(compact.Tag(t)) + return id +} 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 000000000..06e59559a --- /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 +// https://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 https://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/roundingmode_string.go b/vendor/golang.org/x/text/internal/number/roundingmode_string.go new file mode 100644 index 000000000..bcc22471d --- /dev/null +++ b/vendor/golang.org/x/text/internal/number/roundingmode_string.go @@ -0,0 +1,30 @@ +// Code generated by "stringer -type RoundingMode"; DO NOT EDIT. + +package number + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[ToNearestEven-0] + _ = x[ToNearestZero-1] + _ = x[ToNearestAway-2] + _ = x[ToPositiveInf-3] + _ = x[ToNegativeInf-4] + _ = x[ToZero-5] + _ = x[AwayFromZero-6] + _ = x[numModes-7] +} + +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 "RoundingMode(" + strconv.FormatInt(int64(i), 10) + ")" + } + 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 000000000..8efce81b5 --- /dev/null +++ b/vendor/golang.org/x/text/internal/number/tables.go @@ -0,0 +1,1219 @@ +// 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 = [775]symOffset{ + // Entry 0 - 3F + 0x8000, 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, 0x0000, 0x0000, + // Entry 40 - 7F + 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, 0x0000, 0x0000, + // Entry 80 - BF + 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, 0x0000, 0x0000, + // Entry C0 - FF + 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, 0x0006, 0x0006, + // Entry 100 - 13F + 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, 0x0001, 0x0001, + // Entry 140 - 17F + 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, 0x0000, 0x0000, + // Entry 180 - 1BF + 0x0000, 0x0000, 0x8052, 0x0006, 0x0006, 0x001d, 0x0006, 0x0006, + 0x0006, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0006, 0x0006, + 0x0000, 0x0000, 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, + // Entry 1C0 - 1FF + 0x0000, 0x0023, 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, 0x0000, 0x805a, 0x0000, 0x0000, 0x0006, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0006, 0x0006, 0x805b, 0x0026, 0x805d, + // Entry 200 - 23F + 0x0000, 0x0000, 0x0000, 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, + // Entry 240 - 27F + 0x0001, 0x0001, 0x0001, 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, 0x0000, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x002c, 0x002c, 0x002d, 0x002d, 0x002e, 0x002e, 0x0000, 0x0000, + // Entry 280 - 2BF + 0x0000, 0x002f, 0x002f, 0x0000, 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, 0x0000, 0x8071, 0x0031, 0x0006, + // Entry 2C0 - 2FF + 0x0006, 0x0006, 0x0000, 0x0001, 0x0001, 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, + // Entry 300 - 33F + 0x0036, 0x0036, 0x0036, 0x0000, 0x0000, 0x0006, 0x0014, +} // Size: 1550 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: 0xa, symIndex: 0x39, system: 0x3}, + 4: {compactTag: 0xa, symIndex: 0x2, system: 0x0}, + 5: {compactTag: 0x28, symIndex: 0x0, system: 0x6}, + 6: {compactTag: 0x2c, symIndex: 0x5, system: 0x0}, + 7: {compactTag: 0x2c, symIndex: 0x3a, system: 0x3}, + 8: {compactTag: 0x2c, symIndex: 0x42, system: 0x4}, + 9: {compactTag: 0x40, symIndex: 0x0, system: 0x6}, + 10: {compactTag: 0x43, symIndex: 0x0, system: 0x0}, + 11: {compactTag: 0x43, symIndex: 0x4f, system: 0x37}, + 12: {compactTag: 0x46, symIndex: 0x1, system: 0x0}, + 13: {compactTag: 0x46, symIndex: 0x38, system: 0x3}, + 14: {compactTag: 0x54, symIndex: 0x0, system: 0x9}, + 15: {compactTag: 0x5d, symIndex: 0x3a, system: 0x3}, + 16: {compactTag: 0x5d, symIndex: 0x8, system: 0x0}, + 17: {compactTag: 0x60, symIndex: 0x1, system: 0x0}, + 18: {compactTag: 0x60, symIndex: 0x38, system: 0x3}, + 19: {compactTag: 0x60, symIndex: 0x42, system: 0x4}, + 20: {compactTag: 0x60, symIndex: 0x0, system: 0x5}, + 21: {compactTag: 0x60, symIndex: 0x0, system: 0x6}, + 22: {compactTag: 0x60, symIndex: 0x0, system: 0x8}, + 23: {compactTag: 0x60, symIndex: 0x0, system: 0x9}, + 24: {compactTag: 0x60, symIndex: 0x0, system: 0xa}, + 25: {compactTag: 0x60, symIndex: 0x0, system: 0xb}, + 26: {compactTag: 0x60, symIndex: 0x0, system: 0xc}, + 27: {compactTag: 0x60, symIndex: 0x0, system: 0xd}, + 28: {compactTag: 0x60, symIndex: 0x0, system: 0xe}, + 29: {compactTag: 0x60, symIndex: 0x0, system: 0xf}, + 30: {compactTag: 0x60, symIndex: 0x0, system: 0x11}, + 31: {compactTag: 0x60, symIndex: 0x0, system: 0x12}, + 32: {compactTag: 0x60, symIndex: 0x0, system: 0x13}, + 33: {compactTag: 0x60, symIndex: 0x0, system: 0x14}, + 34: {compactTag: 0x60, symIndex: 0x0, system: 0x15}, + 35: {compactTag: 0x60, symIndex: 0x0, system: 0x16}, + 36: {compactTag: 0x60, symIndex: 0x0, system: 0x17}, + 37: {compactTag: 0x60, symIndex: 0x0, system: 0x18}, + 38: {compactTag: 0x60, symIndex: 0x0, system: 0x19}, + 39: {compactTag: 0x60, symIndex: 0x0, system: 0x1f}, + 40: {compactTag: 0x60, symIndex: 0x0, system: 0x21}, + 41: {compactTag: 0x60, symIndex: 0x0, system: 0x23}, + 42: {compactTag: 0x60, symIndex: 0x0, system: 0x24}, + 43: {compactTag: 0x60, symIndex: 0x0, system: 0x25}, + 44: {compactTag: 0x60, symIndex: 0x0, system: 0x28}, + 45: {compactTag: 0x60, symIndex: 0x0, system: 0x29}, + 46: {compactTag: 0x60, symIndex: 0x0, system: 0x2a}, + 47: {compactTag: 0x60, symIndex: 0x0, system: 0x2b}, + 48: {compactTag: 0x60, symIndex: 0x0, system: 0x2c}, + 49: {compactTag: 0x60, symIndex: 0x0, system: 0x2d}, + 50: {compactTag: 0x60, symIndex: 0x0, system: 0x30}, + 51: {compactTag: 0x60, symIndex: 0x0, system: 0x31}, + 52: {compactTag: 0x60, symIndex: 0x0, system: 0x32}, + 53: {compactTag: 0x60, symIndex: 0x0, system: 0x33}, + 54: {compactTag: 0x60, symIndex: 0x0, system: 0x34}, + 55: {compactTag: 0x60, symIndex: 0x0, system: 0x35}, + 56: {compactTag: 0x60, symIndex: 0x0, system: 0x36}, + 57: {compactTag: 0x60, symIndex: 0x0, system: 0x37}, + 58: {compactTag: 0x60, symIndex: 0x0, system: 0x39}, + 59: {compactTag: 0x60, symIndex: 0x0, system: 0x43}, + 60: {compactTag: 0x64, symIndex: 0x0, system: 0x0}, + 61: {compactTag: 0x64, symIndex: 0x38, system: 0x3}, + 62: {compactTag: 0x64, symIndex: 0x42, system: 0x4}, + 63: {compactTag: 0x7c, symIndex: 0x50, system: 0x37}, + 64: {compactTag: 0x7c, symIndex: 0x0, system: 0x0}, + 65: {compactTag: 0x114, symIndex: 0x43, system: 0x4}, + 66: {compactTag: 0x114, symIndex: 0x18, system: 0x0}, + 67: {compactTag: 0x114, symIndex: 0x3b, system: 0x3}, + 68: {compactTag: 0x123, symIndex: 0x1, system: 0x0}, + 69: {compactTag: 0x123, symIndex: 0x3c, system: 0x3}, + 70: {compactTag: 0x123, symIndex: 0x44, system: 0x4}, + 71: {compactTag: 0x158, symIndex: 0x0, system: 0x0}, + 72: {compactTag: 0x158, symIndex: 0x3b, system: 0x3}, + 73: {compactTag: 0x158, symIndex: 0x45, system: 0x4}, + 74: {compactTag: 0x160, symIndex: 0x0, system: 0x0}, + 75: {compactTag: 0x160, symIndex: 0x38, system: 0x3}, + 76: {compactTag: 0x16d, symIndex: 0x1b, system: 0x0}, + 77: {compactTag: 0x16d, symIndex: 0x0, system: 0x9}, + 78: {compactTag: 0x16d, symIndex: 0x0, system: 0xa}, + 79: {compactTag: 0x17c, symIndex: 0x0, system: 0x0}, + 80: {compactTag: 0x17c, symIndex: 0x3d, system: 0x3}, + 81: {compactTag: 0x17c, symIndex: 0x42, system: 0x4}, + 82: {compactTag: 0x182, symIndex: 0x6, system: 0x0}, + 83: {compactTag: 0x182, symIndex: 0x38, system: 0x3}, + 84: {compactTag: 0x1b1, symIndex: 0x0, system: 0x0}, + 85: {compactTag: 0x1b1, symIndex: 0x3e, system: 0x3}, + 86: {compactTag: 0x1b6, symIndex: 0x42, system: 0x4}, + 87: {compactTag: 0x1b6, symIndex: 0x1b, system: 0x0}, + 88: {compactTag: 0x1d2, symIndex: 0x42, system: 0x4}, + 89: {compactTag: 0x1d2, symIndex: 0x0, system: 0x0}, + 90: {compactTag: 0x1f3, symIndex: 0x0, system: 0xb}, + 91: {compactTag: 0x1fd, symIndex: 0x4e, system: 0x24}, + 92: {compactTag: 0x1fd, symIndex: 0x26, system: 0x0}, + 93: {compactTag: 0x1ff, symIndex: 0x42, system: 0x4}, + 94: {compactTag: 0x204, symIndex: 0x15, system: 0x0}, + 95: {compactTag: 0x204, symIndex: 0x3f, system: 0x3}, + 96: {compactTag: 0x204, symIndex: 0x46, system: 0x4}, + 97: {compactTag: 0x20c, symIndex: 0x0, system: 0xb}, + 98: {compactTag: 0x20f, symIndex: 0x6, system: 0x0}, + 99: {compactTag: 0x20f, symIndex: 0x38, system: 0x3}, + 100: {compactTag: 0x20f, symIndex: 0x42, system: 0x4}, + 101: {compactTag: 0x22e, symIndex: 0x0, system: 0x0}, + 102: {compactTag: 0x22e, symIndex: 0x47, system: 0x4}, + 103: {compactTag: 0x22f, symIndex: 0x42, system: 0x4}, + 104: {compactTag: 0x22f, symIndex: 0x1b, system: 0x0}, + 105: {compactTag: 0x238, symIndex: 0x42, system: 0x4}, + 106: {compactTag: 0x238, symIndex: 0x28, system: 0x0}, + 107: {compactTag: 0x265, symIndex: 0x38, system: 0x3}, + 108: {compactTag: 0x265, symIndex: 0x0, system: 0x0}, + 109: {compactTag: 0x29d, symIndex: 0x22, system: 0x0}, + 110: {compactTag: 0x29d, symIndex: 0x40, system: 0x3}, + 111: {compactTag: 0x29d, symIndex: 0x48, system: 0x4}, + 112: {compactTag: 0x29d, symIndex: 0x4d, system: 0xc}, + 113: {compactTag: 0x2bd, symIndex: 0x31, system: 0x0}, + 114: {compactTag: 0x2bd, symIndex: 0x3e, system: 0x3}, + 115: {compactTag: 0x2bd, symIndex: 0x42, system: 0x4}, + 116: {compactTag: 0x2cd, symIndex: 0x1b, system: 0x0}, + 117: {compactTag: 0x2cd, symIndex: 0x49, system: 0x4}, + 118: {compactTag: 0x2ce, symIndex: 0x49, system: 0x4}, + 119: {compactTag: 0x2d0, symIndex: 0x33, system: 0x0}, + 120: {compactTag: 0x2d0, symIndex: 0x4a, system: 0x4}, + 121: {compactTag: 0x2d1, symIndex: 0x42, system: 0x4}, + 122: {compactTag: 0x2d1, symIndex: 0x28, system: 0x0}, + 123: {compactTag: 0x2d3, symIndex: 0x34, system: 0x0}, + 124: {compactTag: 0x2d3, symIndex: 0x4b, system: 0x4}, + 125: {compactTag: 0x2f9, symIndex: 0x0, system: 0x0}, + 126: {compactTag: 0x2f9, symIndex: 0x38, system: 0x3}, + 127: {compactTag: 0x2f9, symIndex: 0x42, system: 0x4}, + 128: {compactTag: 0x2ff, symIndex: 0x36, system: 0x0}, + 129: {compactTag: 0x2ff, symIndex: 0x41, system: 0x3}, + 130: {compactTag: 0x2ff, symIndex: 0x4c, system: 0x4}, +} // Size: 810 bytes + +var tagToDecimal = []uint8{ // 775 elements + // Entry 0 - 3F + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 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, 0x01, 0x01, + // Entry 40 - 7F + 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, 0x01, 0x01, + // 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, 0x05, 0x01, 0x01, 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, + 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, 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, 0x01, 0x01, 0x05, 0x05, 0x05, 0x05, + 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, 0x01, 0x01, 0x05, 0x05, + 0x01, 0x01, 0x01, 0x05, 0x05, 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, 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, + // 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, 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, + // 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, + // Entry 300 - 33F + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x08, +} // Size: 799 bytes + +var tagToScientific = []uint8{ // 775 elements + // Entry 0 - 3F + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 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, + 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, 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, 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, 0x02, 0x0c, 0x0c, 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, 0x02, 0x02, 0x02, 0x0c, 0x02, + 0x02, 0x0c, 0x0c, 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, 0x02, 0x02, 0x02, 0x02, + 0x0d, 0x0d, 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, + // Entry 300 - 33F + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x09, +} // Size: 799 bytes + +var tagToPercent = []uint8{ // 775 elements + // Entry 0 - 3F + 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, + 0x06, 0x06, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + // Entry 40 - 7F + 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, 0x04, 0x04, + // Entry 80 - BF + 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, 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, 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, 0x03, 0x03, + // Entry 100 - 13F + 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, 0x03, 0x03, + // Entry 140 - 17F + 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, 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, 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, + // Entry 1C0 - 1FF + 0x04, 0x04, 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, + // Entry 200 - 23F + 0x04, 0x04, 0x04, 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, + // Entry 240 - 27F + 0x04, 0x04, 0x04, 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, 0x04, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, + // Entry 280 - 2BF + 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, 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, 0x04, 0x0e, + // Entry 2C0 - 2FF + 0x0e, 0x0e, 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, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, + 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + // Entry 300 - 33F + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x0a, +} // Size: 799 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 8634 bytes (8KiB); checksum: 8F23386D diff --git a/vendor/golang.org/x/text/internal/stringset/set.go b/vendor/golang.org/x/text/internal/stringset/set.go new file mode 100644 index 000000000..bb2fffbc7 --- /dev/null +++ b/vendor/golang.org/x/text/internal/stringset/set.go @@ -0,0 +1,86 @@ +// 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 stringset provides a way to represent a collection of strings +// compactly. +package stringset + +import "sort" + +// A Set holds a collection of strings that can be looked up by an index number. +type Set struct { + // These fields are exported to allow for code generation. + + Data string + Index []uint16 +} + +// Elem returns the string with index i. It panics if i is out of range. +func (s *Set) Elem(i int) string { + return s.Data[s.Index[i]:s.Index[i+1]] +} + +// Len returns the number of strings in the set. +func (s *Set) Len() int { + return len(s.Index) - 1 +} + +// Search returns the index of the given string or -1 if it is not in the set. +// The Set must have been created with strings in sorted order. +func Search(s *Set, str string) int { + // TODO: optimize this if it gets used a lot. + n := len(s.Index) - 1 + p := sort.Search(n, func(i int) bool { + return s.Elem(i) >= str + }) + if p == n || str != s.Elem(p) { + return -1 + } + return p +} + +// A Builder constructs Sets. +type Builder struct { + set Set + index map[string]int +} + +// NewBuilder returns a new and initialized Builder. +func NewBuilder() *Builder { + return &Builder{ + set: Set{ + Index: []uint16{0}, + }, + index: map[string]int{}, + } +} + +// Set creates the set created so far. +func (b *Builder) Set() Set { + return b.set +} + +// Index returns the index for the given string, which must have been added +// before. +func (b *Builder) Index(s string) int { + return b.index[s] +} + +// Add adds a string to the index. Strings that are added by a single Add will +// be stored together, unless they match an existing string. +func (b *Builder) Add(ss ...string) { + // First check if the string already exists. + for _, s := range ss { + if _, ok := b.index[s]; ok { + continue + } + b.index[s] = len(b.set.Index) - 1 + b.set.Data += s + x := len(b.set.Data) + if x > 0xFFFF { + panic("Index too > 0xFFFF") + } + b.set.Index = append(b.set.Index, uint16(x)) + } +} diff --git a/vendor/golang.org/x/text/internal/tag/tag.go b/vendor/golang.org/x/text/internal/tag/tag.go new file mode 100644 index 000000000..b5d348891 --- /dev/null +++ b/vendor/golang.org/x/text/internal/tag/tag.go @@ -0,0 +1,100 @@ +// 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 tag contains functionality handling tags and related data. +package tag // import "golang.org/x/text/internal/tag" + +import "sort" + +// An Index converts tags to a compact numeric value. +// +// All elements are of size 4. Tags may be up to 4 bytes long. Excess bytes can +// be used to store additional information about the tag. +type Index string + +// Elem returns the element data at the given index. +func (s Index) Elem(x int) string { + return string(s[x*4 : x*4+4]) +} + +// Index reports the index of the given key or -1 if it could not be found. +// Only the first len(key) bytes from the start of the 4-byte entries will be +// considered for the search and the first match in Index will be returned. +func (s Index) Index(key []byte) int { + n := len(key) + // search the index of the first entry with an equal or higher value than + // key in s. + index := sort.Search(len(s)/4, func(i int) bool { + return cmp(s[i*4:i*4+n], key) != -1 + }) + i := index * 4 + if cmp(s[i:i+len(key)], key) != 0 { + return -1 + } + return index +} + +// Next finds the next occurrence of key after index x, which must have been +// obtained from a call to Index using the same key. It returns x+1 or -1. +func (s Index) Next(key []byte, x int) int { + if x++; x*4 < len(s) && cmp(s[x*4:x*4+len(key)], key) == 0 { + return x + } + return -1 +} + +// cmp returns an integer comparing a and b lexicographically. +func cmp(a Index, b []byte) int { + n := len(a) + if len(b) < n { + n = len(b) + } + for i, c := range b[:n] { + switch { + case a[i] > c: + return 1 + case a[i] < c: + return -1 + } + } + switch { + case len(a) < len(b): + return -1 + case len(a) > len(b): + return 1 + } + return 0 +} + +// Compare returns an integer comparing a and b lexicographically. +func Compare(a string, b []byte) int { + return cmp(Index(a), b) +} + +// FixCase reformats b to the same pattern of cases as form. +// If returns false if string b is malformed. +func FixCase(form string, b []byte) bool { + if len(form) != len(b) { + return false + } + for i, c := range b { + if form[i] <= 'Z' { + if c >= 'a' { + c -= 'z' - 'Z' + } + if c < 'A' || 'Z' < c { + return false + } + } else { + if c <= 'Z' { + c += 'z' - 'Z' + } + if c < 'a' || 'z' < c { + return false + } + } + b[i] = c + } + return true +} diff --git a/vendor/golang.org/x/text/language/coverage.go b/vendor/golang.org/x/text/language/coverage.go new file mode 100644 index 000000000..a24fd1a4d --- /dev/null +++ b/vendor/golang.org/x/text/language/coverage.go @@ -0,0 +1,187 @@ +// Copyright 2014 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 language + +import ( + "fmt" + "sort" + + "golang.org/x/text/internal/language" +) + +// The Coverage interface is used to define the level of coverage of an +// internationalization service. Note that not all types are supported by all +// services. As lists may be generated on the fly, it is recommended that users +// of a Coverage cache the results. +type Coverage interface { + // Tags returns the list of supported tags. + Tags() []Tag + + // BaseLanguages returns the list of supported base languages. + BaseLanguages() []Base + + // Scripts returns the list of supported scripts. + Scripts() []Script + + // Regions returns the list of supported regions. + Regions() []Region +} + +var ( + // Supported defines a Coverage that lists all supported subtags. Tags + // always returns nil. + Supported Coverage = allSubtags{} +) + +// TODO: +// - Support Variants, numbering systems. +// - CLDR coverage levels. +// - Set of common tags defined in this package. + +type allSubtags struct{} + +// Regions returns the list of supported regions. As all regions are in a +// consecutive range, it simply returns a slice of numbers in increasing order. +// The "undefined" region is not returned. +func (s allSubtags) Regions() []Region { + reg := make([]Region, language.NumRegions) + for i := range reg { + reg[i] = Region{language.Region(i + 1)} + } + return reg +} + +// Scripts returns the list of supported scripts. As all scripts are in a +// consecutive range, it simply returns a slice of numbers in increasing order. +// The "undefined" script is not returned. +func (s allSubtags) Scripts() []Script { + scr := make([]Script, language.NumScripts) + for i := range scr { + scr[i] = Script{language.Script(i + 1)} + } + return scr +} + +// BaseLanguages returns the list of all supported base languages. It generates +// the list by traversing the internal structures. +func (s allSubtags) BaseLanguages() []Base { + bs := language.BaseLanguages() + base := make([]Base, len(bs)) + for i, b := range bs { + base[i] = Base{b} + } + return base +} + +// Tags always returns nil. +func (s allSubtags) Tags() []Tag { + return nil +} + +// coverage is used by NewCoverage which is used as a convenient way for +// creating Coverage implementations for partially defined data. Very often a +// package will only need to define a subset of slices. coverage provides a +// convenient way to do this. Moreover, packages using NewCoverage, instead of +// their own implementation, will not break if later new slice types are added. +type coverage struct { + tags func() []Tag + bases func() []Base + scripts func() []Script + regions func() []Region +} + +func (s *coverage) Tags() []Tag { + if s.tags == nil { + return nil + } + return s.tags() +} + +// bases implements sort.Interface and is used to sort base languages. +type bases []Base + +func (b bases) Len() int { + return len(b) +} + +func (b bases) Swap(i, j int) { + b[i], b[j] = b[j], b[i] +} + +func (b bases) Less(i, j int) bool { + return b[i].langID < b[j].langID +} + +// BaseLanguages returns the result from calling s.bases if it is specified or +// otherwise derives the set of supported base languages from tags. +func (s *coverage) BaseLanguages() []Base { + if s.bases == nil { + tags := s.Tags() + if len(tags) == 0 { + return nil + } + a := make([]Base, len(tags)) + for i, t := range tags { + a[i] = Base{language.Language(t.lang())} + } + sort.Sort(bases(a)) + k := 0 + for i := 1; i < len(a); i++ { + if a[k] != a[i] { + k++ + a[k] = a[i] + } + } + return a[:k+1] + } + return s.bases() +} + +func (s *coverage) Scripts() []Script { + if s.scripts == nil { + return nil + } + return s.scripts() +} + +func (s *coverage) Regions() []Region { + if s.regions == nil { + return nil + } + return s.regions() +} + +// NewCoverage returns a Coverage for the given lists. It is typically used by +// packages providing internationalization services to define their level of +// coverage. A list may be of type []T or func() []T, where T is either Tag, +// Base, Script or Region. The returned Coverage derives the value for Bases +// from Tags if no func or slice for []Base is specified. For other unspecified +// types the returned Coverage will return nil for the respective methods. +func NewCoverage(list ...interface{}) Coverage { + s := &coverage{} + for _, x := range list { + switch v := x.(type) { + case func() []Base: + s.bases = v + case func() []Script: + s.scripts = v + case func() []Region: + s.regions = v + case func() []Tag: + s.tags = v + case []Base: + s.bases = func() []Base { return v } + case []Script: + s.scripts = func() []Script { return v } + case []Region: + s.regions = func() []Region { return v } + case []Tag: + s.tags = func() []Tag { return v } + default: + panic(fmt.Sprintf("language: unsupported set type %T", v)) + } + } + return s +} diff --git a/vendor/golang.org/x/text/language/doc.go b/vendor/golang.org/x/text/language/doc.go new file mode 100644 index 000000000..212b77c90 --- /dev/null +++ b/vendor/golang.org/x/text/language/doc.go @@ -0,0 +1,98 @@ +// 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 language implements BCP 47 language tags and related functionality. +// +// The most important function of package language is to match a list of +// user-preferred languages to a list of supported languages. +// It alleviates the developer of dealing with the complexity of this process +// and provides the user with the best experience +// (see https://blog.golang.org/matchlang). +// +// # Matching preferred against supported languages +// +// A Matcher for an application that supports English, Australian English, +// Danish, and standard Mandarin can be created as follows: +// +// var matcher = language.NewMatcher([]language.Tag{ +// language.English, // The first language is used as fallback. +// language.MustParse("en-AU"), +// language.Danish, +// language.Chinese, +// }) +// +// This list of supported languages is typically implied by the languages for +// which there exists translations of the user interface. +// +// User-preferred languages usually come as a comma-separated list of BCP 47 +// language tags. +// The MatchString finds best matches for such strings: +// +// handler(w http.ResponseWriter, r *http.Request) { +// lang, _ := r.Cookie("lang") +// accept := r.Header.Get("Accept-Language") +// tag, _ := language.MatchStrings(matcher, lang.String(), accept) +// +// // tag should now be used for the initialization of any +// // locale-specific service. +// } +// +// The Matcher's Match method can be used to match Tags directly. +// +// Matchers are aware of the intricacies of equivalence between languages, such +// as deprecated subtags, legacy tags, macro languages, mutual +// intelligibility between scripts and languages, and transparently passing +// BCP 47 user configuration. +// For instance, it will know that a reader of Bokmål Danish can read Norwegian +// and will know that Cantonese ("yue") is a good match for "zh-HK". +// +// # Using match results +// +// To guarantee a consistent user experience to the user it is important to +// use the same language tag for the selection of any locale-specific services. +// For example, it is utterly confusing to substitute spelled-out numbers +// or dates in one language in text of another language. +// More subtly confusing is using the wrong sorting order or casing +// algorithm for a certain language. +// +// All the packages in x/text that provide locale-specific services +// (e.g. collate, cases) should be initialized with the tag that was +// obtained at the start of an interaction with the user. +// +// Note that Tag that is returned by Match and MatchString may differ from any +// of the supported languages, as it may contain carried over settings from +// the user tags. +// This may be inconvenient when your application has some additional +// locale-specific data for your supported languages. +// Match and MatchString both return the index of the matched supported tag +// to simplify associating such data with the matched tag. +// +// # Canonicalization +// +// If one uses the Matcher to compare languages one does not need to +// worry about canonicalization. +// +// The meaning of a Tag varies per application. The language package +// therefore delays canonicalization and preserves information as much +// as possible. The Matcher, however, will always take into account that +// two different tags may represent the same language. +// +// By default, only legacy and deprecated tags are converted into their +// canonical equivalent. All other information is preserved. This approach makes +// the confidence scores more accurate and allows matchers to distinguish +// between variants that are otherwise lost. +// +// As a consequence, two tags that should be treated as identical according to +// BCP 47 or CLDR, like "en-Latn" and "en", will be represented differently. The +// Matcher handles such distinctions, though, and is aware of the +// equivalence relations. The CanonType type can be used to alter the +// canonicalization form. +// +// # References +// +// BCP 47 - Tags for Identifying Languages http://tools.ietf.org/html/bcp47 +package language // import "golang.org/x/text/language" + +// TODO: explanation on how to match languages for your own locale-specific +// service. diff --git a/vendor/golang.org/x/text/language/language.go b/vendor/golang.org/x/text/language/language.go new file mode 100644 index 000000000..4d9c66121 --- /dev/null +++ b/vendor/golang.org/x/text/language/language.go @@ -0,0 +1,605 @@ +// Copyright 2013 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 -output tables.go + +package language + +// TODO: Remove above NOTE after: +// - verifying that tables are dropped correctly (most notably matcher tables). + +import ( + "strings" + + "golang.org/x/text/internal/language" + "golang.org/x/text/internal/language/compact" +) + +// Tag represents a BCP 47 language tag. It is used to specify an instance of a +// specific language or locale. All language tag values are guaranteed to be +// well-formed. +type Tag compact.Tag + +func makeTag(t language.Tag) (tag Tag) { + return Tag(compact.Make(t)) +} + +func (t *Tag) tag() language.Tag { + return (*compact.Tag)(t).Tag() +} + +func (t *Tag) isCompact() bool { + return (*compact.Tag)(t).IsCompact() +} + +// TODO: improve performance. +func (t *Tag) lang() language.Language { return t.tag().LangID } +func (t *Tag) region() language.Region { return t.tag().RegionID } +func (t *Tag) script() language.Script { return t.tag().ScriptID } + +// Make is a convenience wrapper for Parse that omits the error. +// In case of an error, a sensible default is returned. +func Make(s string) Tag { + return Default.Make(s) +} + +// Make is a convenience wrapper for c.Parse that omits the error. +// In case of an error, a sensible default is returned. +func (c CanonType) Make(s string) Tag { + t, _ := c.Parse(s) + return t +} + +// Raw returns the raw base language, script and region, without making an +// attempt to infer their values. +func (t Tag) Raw() (b Base, s Script, r Region) { + tt := t.tag() + return Base{tt.LangID}, Script{tt.ScriptID}, Region{tt.RegionID} +} + +// IsRoot returns true if t is equal to language "und". +func (t Tag) IsRoot() bool { + return compact.Tag(t).IsRoot() +} + +// CanonType can be used to enable or disable various types of canonicalization. +type CanonType int + +const ( + // Replace deprecated base languages with their preferred replacements. + DeprecatedBase CanonType = 1 << iota + // Replace deprecated scripts with their preferred replacements. + DeprecatedScript + // Replace deprecated regions with their preferred replacements. + DeprecatedRegion + // Remove redundant scripts. + SuppressScript + // Normalize legacy encodings. This includes legacy languages defined in + // CLDR as well as bibliographic codes defined in ISO-639. + Legacy + // Map the dominant language of a macro language group to the macro language + // subtag. For example cmn -> zh. + Macro + // The CLDR flag should be used if full compatibility with CLDR is required. + // There are a few cases where language.Tag may differ from CLDR. To follow all + // of CLDR's suggestions, use All|CLDR. + CLDR + + // Raw can be used to Compose or Parse without Canonicalization. + Raw CanonType = 0 + + // Replace all deprecated tags with their preferred replacements. + Deprecated = DeprecatedBase | DeprecatedScript | DeprecatedRegion + + // All canonicalizations recommended by BCP 47. + BCP47 = Deprecated | SuppressScript + + // All canonicalizations. + All = BCP47 | Legacy | Macro + + // Default is the canonicalization used by Parse, Make and Compose. To + // preserve as much information as possible, canonicalizations that remove + // potentially valuable information are not included. The Matcher is + // designed to recognize similar tags that would be the same if + // they were canonicalized using All. + Default = Deprecated | Legacy + + canonLang = DeprecatedBase | Legacy | Macro + + // TODO: LikelyScript, LikelyRegion: suppress similar to ICU. +) + +// canonicalize returns the canonicalized equivalent of the tag and +// whether there was any change. +func canonicalize(c CanonType, t language.Tag) (language.Tag, bool) { + if c == Raw { + return t, false + } + changed := false + if c&SuppressScript != 0 { + if t.LangID.SuppressScript() == t.ScriptID { + t.ScriptID = 0 + changed = true + } + } + if c&canonLang != 0 { + for { + if l, aliasType := t.LangID.Canonicalize(); l != t.LangID { + switch aliasType { + case language.Legacy: + if c&Legacy != 0 { + if t.LangID == _sh && t.ScriptID == 0 { + t.ScriptID = _Latn + } + t.LangID = l + changed = true + } + case language.Macro: + if c&Macro != 0 { + // We deviate here from CLDR. The mapping "nb" -> "no" + // qualifies as a typical Macro language mapping. However, + // for legacy reasons, CLDR maps "no", the macro language + // code for Norwegian, to the dominant variant "nb". This + // change is currently under consideration for CLDR as well. + // See https://unicode.org/cldr/trac/ticket/2698 and also + // https://unicode.org/cldr/trac/ticket/1790 for some of the + // practical implications. TODO: this check could be removed + // if CLDR adopts this change. + if c&CLDR == 0 || t.LangID != _nb { + changed = true + t.LangID = l + } + } + case language.Deprecated: + if c&DeprecatedBase != 0 { + if t.LangID == _mo && t.RegionID == 0 { + t.RegionID = _MD + } + t.LangID = l + changed = true + // Other canonicalization types may still apply. + continue + } + } + } else if c&Legacy != 0 && t.LangID == _no && c&CLDR != 0 { + t.LangID = _nb + changed = true + } + break + } + } + if c&DeprecatedScript != 0 { + if t.ScriptID == _Qaai { + changed = true + t.ScriptID = _Zinh + } + } + if c&DeprecatedRegion != 0 { + if r := t.RegionID.Canonicalize(); r != t.RegionID { + changed = true + t.RegionID = r + } + } + return t, changed +} + +// Canonicalize returns the canonicalized equivalent of the tag. +func (c CanonType) Canonicalize(t Tag) (Tag, error) { + // First try fast path. + if t.isCompact() { + if _, changed := canonicalize(c, compact.Tag(t).Tag()); !changed { + return t, nil + } + } + // It is unlikely that one will canonicalize a tag after matching. So do + // a slow but simple approach here. + if tag, changed := canonicalize(c, t.tag()); changed { + tag.RemakeString() + return makeTag(tag), nil + } + return t, nil + +} + +// Confidence indicates the level of certainty for a given return value. +// For example, Serbian may be written in Cyrillic or Latin script. +// The confidence level indicates whether a value was explicitly specified, +// whether it is typically the only possible value, or whether there is +// an ambiguity. +type Confidence int + +const ( + No Confidence = iota // full confidence that there was no match + Low // most likely value picked out of a set of alternatives + High // value is generally assumed to be the correct match + Exact // exact match or explicitly specified value +) + +var confName = []string{"No", "Low", "High", "Exact"} + +func (c Confidence) String() string { + return confName[c] +} + +// String returns the canonical string representation of the language tag. +func (t Tag) String() string { + return t.tag().String() +} + +// MarshalText implements encoding.TextMarshaler. +func (t Tag) MarshalText() (text []byte, err error) { + return t.tag().MarshalText() +} + +// UnmarshalText implements encoding.TextUnmarshaler. +func (t *Tag) UnmarshalText(text []byte) error { + var tag language.Tag + err := tag.UnmarshalText(text) + *t = makeTag(tag) + return err +} + +// Base returns the base language of the language tag. If the base language is +// unspecified, an attempt will be made to infer it from the context. +// It uses a variant of CLDR's Add Likely Subtags algorithm. This is subject to change. +func (t Tag) Base() (Base, Confidence) { + if b := t.lang(); b != 0 { + return Base{b}, Exact + } + tt := t.tag() + c := High + if tt.ScriptID == 0 && !tt.RegionID.IsCountry() { + c = Low + } + if tag, err := tt.Maximize(); err == nil && tag.LangID != 0 { + return Base{tag.LangID}, c + } + return Base{0}, No +} + +// Script infers the script for the language tag. If it was not explicitly given, it will infer +// a most likely candidate. +// If more than one script is commonly used for a language, the most likely one +// is returned with a low confidence indication. For example, it returns (Cyrl, Low) +// for Serbian. +// If a script cannot be inferred (Zzzz, No) is returned. We do not use Zyyy (undetermined) +// as one would suspect from the IANA registry for BCP 47. In a Unicode context Zyyy marks +// common characters (like 1, 2, 3, '.', etc.) and is therefore more like multiple scripts. +// See https://www.unicode.org/reports/tr24/#Values for more details. Zzzz is also used for +// unknown value in CLDR. (Zzzz, Exact) is returned if Zzzz was explicitly specified. +// Note that an inferred script is never guaranteed to be the correct one. Latin is +// almost exclusively used for Afrikaans, but Arabic has been used for some texts +// in the past. Also, the script that is commonly used may change over time. +// It uses a variant of CLDR's Add Likely Subtags algorithm. This is subject to change. +func (t Tag) Script() (Script, Confidence) { + if scr := t.script(); scr != 0 { + return Script{scr}, Exact + } + tt := t.tag() + sc, c := language.Script(_Zzzz), No + if scr := tt.LangID.SuppressScript(); scr != 0 { + // Note: it is not always the case that a language with a suppress + // script value is only written in one script (e.g. kk, ms, pa). + if tt.RegionID == 0 { + return Script{scr}, High + } + sc, c = scr, High + } + if tag, err := tt.Maximize(); err == nil { + if tag.ScriptID != sc { + sc, c = tag.ScriptID, Low + } + } else { + tt, _ = canonicalize(Deprecated|Macro, tt) + if tag, err := tt.Maximize(); err == nil && tag.ScriptID != sc { + sc, c = tag.ScriptID, Low + } + } + return Script{sc}, c +} + +// Region returns the region for the language tag. If it was not explicitly given, it will +// infer a most likely candidate from the context. +// It uses a variant of CLDR's Add Likely Subtags algorithm. This is subject to change. +func (t Tag) Region() (Region, Confidence) { + if r := t.region(); r != 0 { + return Region{r}, Exact + } + tt := t.tag() + if tt, err := tt.Maximize(); err == nil { + return Region{tt.RegionID}, Low // TODO: differentiate between high and low. + } + tt, _ = canonicalize(Deprecated|Macro, tt) + if tag, err := tt.Maximize(); err == nil { + return Region{tag.RegionID}, Low + } + return Region{_ZZ}, No // TODO: return world instead of undetermined? +} + +// Variants returns the variants specified explicitly for this language tag. +// or nil if no variant was specified. +func (t Tag) Variants() []Variant { + if !compact.Tag(t).MayHaveVariants() { + return nil + } + v := []Variant{} + x, str := "", t.tag().Variants() + for str != "" { + x, str = nextToken(str) + v = append(v, Variant{x}) + } + return v +} + +// Parent returns the CLDR parent of t. In CLDR, missing fields in data for a +// specific language are substituted with fields from the parent language. +// The parent for a language may change for newer versions of CLDR. +// +// Parent returns a tag for a less specific language that is mutually +// intelligible or Und if there is no such language. This may not be the same as +// simply stripping the last BCP 47 subtag. For instance, the parent of "zh-TW" +// is "zh-Hant", and the parent of "zh-Hant" is "und". +func (t Tag) Parent() Tag { + return Tag(compact.Tag(t).Parent()) +} + +// nextToken returns token t and the rest of the string. +func nextToken(s string) (t, tail string) { + p := strings.Index(s[1:], "-") + if p == -1 { + return s[1:], "" + } + p++ + return s[1:p], s[p:] +} + +// Extension is a single BCP 47 extension. +type Extension struct { + s string +} + +// String returns the string representation of the extension, including the +// type tag. +func (e Extension) String() string { + return e.s +} + +// ParseExtension parses s as an extension and returns it on success. +func ParseExtension(s string) (e Extension, err error) { + ext, err := language.ParseExtension(s) + return Extension{ext}, err +} + +// Type returns the one-byte extension type of e. It returns 0 for the zero +// exception. +func (e Extension) Type() byte { + if e.s == "" { + return 0 + } + return e.s[0] +} + +// Tokens returns the list of tokens of e. +func (e Extension) Tokens() []string { + return strings.Split(e.s, "-") +} + +// Extension returns the extension of type x for tag t. It will return +// false for ok if t does not have the requested extension. The returned +// extension will be invalid in this case. +func (t Tag) Extension(x byte) (ext Extension, ok bool) { + if !compact.Tag(t).MayHaveExtensions() { + return Extension{}, false + } + e, ok := t.tag().Extension(x) + return Extension{e}, ok +} + +// Extensions returns all extensions of t. +func (t Tag) Extensions() []Extension { + if !compact.Tag(t).MayHaveExtensions() { + return nil + } + e := []Extension{} + for _, ext := range t.tag().Extensions() { + e = append(e, Extension{ext}) + } + return e +} + +// TypeForKey returns the type associated with the given key, where key and type +// are of the allowed values defined for the Unicode locale extension ('u') in +// https://www.unicode.org/reports/tr35/#Unicode_Language_and_Locale_Identifiers. +// TypeForKey will traverse the inheritance chain to get the correct value. +// +// If there are multiple types associated with a key, only the first will be +// returned. If there is no type associated with a key, it returns the empty +// string. +func (t Tag) TypeForKey(key string) string { + if !compact.Tag(t).MayHaveExtensions() { + if key != "rg" && key != "va" { + return "" + } + } + return t.tag().TypeForKey(key) +} + +// SetTypeForKey returns a new Tag with the key set to type, where key and type +// are of the allowed values defined for the Unicode locale extension ('u') in +// https://www.unicode.org/reports/tr35/#Unicode_Language_and_Locale_Identifiers. +// An empty value removes an existing pair with the same key. +func (t Tag) SetTypeForKey(key, value string) (Tag, error) { + tt, err := t.tag().SetTypeForKey(key, value) + return makeTag(tt), err +} + +// NumCompactTags is the number of compact tags. The maximum tag is +// NumCompactTags-1. +const NumCompactTags = compact.NumCompactTags + +// CompactIndex returns an index, where 0 <= index < NumCompactTags, for tags +// for which data exists in the text repository.The index will change over time +// and should not be stored in persistent storage. If t does not match a compact +// index, exact will be false and the compact index will be returned for the +// first match after repeatedly taking the Parent of t. +func CompactIndex(t Tag) (index int, exact bool) { + id, exact := compact.LanguageID(compact.Tag(t)) + return int(id), exact +} + +var root = language.Tag{} + +// Base is an ISO 639 language code, used for encoding the base language +// of a language tag. +type Base struct { + langID language.Language +} + +// ParseBase parses a 2- or 3-letter ISO 639 code. +// It returns a ValueError if s is a well-formed but unknown language identifier +// or another error if another error occurred. +func ParseBase(s string) (Base, error) { + l, err := language.ParseBase(s) + return Base{l}, err +} + +// String returns the BCP 47 representation of the base language. +func (b Base) String() string { + return b.langID.String() +} + +// ISO3 returns the ISO 639-3 language code. +func (b Base) ISO3() string { + return b.langID.ISO3() +} + +// IsPrivateUse reports whether this language code is reserved for private use. +func (b Base) IsPrivateUse() bool { + return b.langID.IsPrivateUse() +} + +// Script is a 4-letter ISO 15924 code for representing scripts. +// It is idiomatically represented in title case. +type Script struct { + scriptID language.Script +} + +// ParseScript parses a 4-letter ISO 15924 code. +// It returns a ValueError if s is a well-formed but unknown script identifier +// or another error if another error occurred. +func ParseScript(s string) (Script, error) { + sc, err := language.ParseScript(s) + return Script{sc}, err +} + +// String returns the script code in title case. +// It returns "Zzzz" for an unspecified script. +func (s Script) String() string { + return s.scriptID.String() +} + +// IsPrivateUse reports whether this script code is reserved for private use. +func (s Script) IsPrivateUse() bool { + return s.scriptID.IsPrivateUse() +} + +// Region is an ISO 3166-1 or UN M.49 code for representing countries and regions. +type Region struct { + regionID language.Region +} + +// EncodeM49 returns the Region for the given UN M.49 code. +// It returns an error if r is not a valid code. +func EncodeM49(r int) (Region, error) { + rid, err := language.EncodeM49(r) + return Region{rid}, err +} + +// ParseRegion parses a 2- or 3-letter ISO 3166-1 or a UN M.49 code. +// It returns a ValueError if s is a well-formed but unknown region identifier +// or another error if another error occurred. +func ParseRegion(s string) (Region, error) { + r, err := language.ParseRegion(s) + return Region{r}, err +} + +// String returns the BCP 47 representation for the region. +// It returns "ZZ" for an unspecified region. +func (r Region) String() string { + return r.regionID.String() +} + +// ISO3 returns the 3-letter ISO code of r. +// Note that not all regions have a 3-letter ISO code. +// In such cases this method returns "ZZZ". +func (r Region) ISO3() string { + return r.regionID.ISO3() +} + +// M49 returns the UN M.49 encoding of r, or 0 if this encoding +// is not defined for r. +func (r Region) M49() int { + return r.regionID.M49() +} + +// IsPrivateUse reports whether r has the ISO 3166 User-assigned status. This +// may include private-use tags that are assigned by CLDR and used in this +// implementation. So IsPrivateUse and IsCountry can be simultaneously true. +func (r Region) IsPrivateUse() bool { + return r.regionID.IsPrivateUse() +} + +// IsCountry returns whether this region is a country or autonomous area. This +// includes non-standard definitions from CLDR. +func (r Region) IsCountry() bool { + return r.regionID.IsCountry() +} + +// IsGroup returns whether this region defines a collection of regions. This +// includes non-standard definitions from CLDR. +func (r Region) IsGroup() bool { + return r.regionID.IsGroup() +} + +// Contains returns whether Region c is contained by Region r. It returns true +// if c == r. +func (r Region) Contains(c Region) bool { + return r.regionID.Contains(c.regionID) +} + +// TLD returns the country code top-level domain (ccTLD). UK is returned for GB. +// In all other cases it returns either the region itself or an error. +// +// This method may return an error for a region for which there exists a +// canonical form with a ccTLD. To get that ccTLD canonicalize r first. The +// region will already be canonicalized it was obtained from a Tag that was +// obtained using any of the default methods. +func (r Region) TLD() (Region, error) { + tld, err := r.regionID.TLD() + return Region{tld}, err +} + +// Canonicalize returns the region or a possible replacement if the region is +// deprecated. It will not return a replacement for deprecated regions that +// are split into multiple regions. +func (r Region) Canonicalize() Region { + return Region{r.regionID.Canonicalize()} +} + +// Variant represents a registered variant of a language as defined by BCP 47. +type Variant struct { + variant string +} + +// ParseVariant parses and returns a Variant. An error is returned if s is not +// a valid variant. +func ParseVariant(s string) (Variant, error) { + v, err := language.ParseVariant(s) + return Variant{v.String()}, err +} + +// String returns the string representation of the variant. +func (v Variant) String() string { + return v.variant +} diff --git a/vendor/golang.org/x/text/language/match.go b/vendor/golang.org/x/text/language/match.go new file mode 100644 index 000000000..1153baf29 --- /dev/null +++ b/vendor/golang.org/x/text/language/match.go @@ -0,0 +1,735 @@ +// Copyright 2013 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 language + +import ( + "errors" + "strings" + + "golang.org/x/text/internal/language" +) + +// A MatchOption configures a Matcher. +type MatchOption func(*matcher) + +// PreferSameScript will, in the absence of a match, result in the first +// preferred tag with the same script as a supported tag to match this supported +// tag. The default is currently true, but this may change in the future. +func PreferSameScript(preferSame bool) MatchOption { + return func(m *matcher) { m.preferSameScript = preferSame } +} + +// TODO(v1.0.0): consider making Matcher a concrete type, instead of interface. +// There doesn't seem to be too much need for multiple types. +// Making it a concrete type allows MatchStrings to be a method, which will +// improve its discoverability. + +// MatchStrings parses and matches the given strings until one of them matches +// the language in the Matcher. A string may be an Accept-Language header as +// handled by ParseAcceptLanguage. The default language is returned if no +// other language matched. +func MatchStrings(m Matcher, lang ...string) (tag Tag, index int) { + for _, accept := range lang { + desired, _, err := ParseAcceptLanguage(accept) + if err != nil { + continue + } + if tag, index, conf := m.Match(desired...); conf != No { + return tag, index + } + } + tag, index, _ = m.Match() + return +} + +// Matcher is the interface that wraps the Match method. +// +// Match returns the best match for any of the given tags, along with +// a unique index associated with the returned tag and a confidence +// score. +type Matcher interface { + Match(t ...Tag) (tag Tag, index int, c Confidence) +} + +// Comprehends reports the confidence score for a speaker of a given language +// to being able to comprehend the written form of an alternative language. +func Comprehends(speaker, alternative Tag) Confidence { + _, _, c := NewMatcher([]Tag{alternative}).Match(speaker) + return c +} + +// NewMatcher returns a Matcher that matches an ordered list of preferred tags +// against a list of supported tags based on written intelligibility, closeness +// of dialect, equivalence of subtags and various other rules. It is initialized +// with the list of supported tags. The first element is used as the default +// value in case no match is found. +// +// Its Match method matches the first of the given Tags to reach a certain +// confidence threshold. The tags passed to Match should therefore be specified +// in order of preference. Extensions are ignored for matching. +// +// The index returned by the Match method corresponds to the index of the +// matched tag in t, but is augmented with the Unicode extension ('u')of the +// corresponding preferred tag. This allows user locale options to be passed +// transparently. +func NewMatcher(t []Tag, options ...MatchOption) Matcher { + return newMatcher(t, options) +} + +func (m *matcher) Match(want ...Tag) (t Tag, index int, c Confidence) { + var tt language.Tag + match, w, c := m.getBest(want...) + if match != nil { + tt, index = match.tag, match.index + } else { + // TODO: this should be an option + tt = m.default_.tag + if m.preferSameScript { + outer: + for _, w := range want { + script, _ := w.Script() + if script.scriptID == 0 { + // Don't do anything if there is no script, such as with + // private subtags. + continue + } + for i, h := range m.supported { + if script.scriptID == h.maxScript { + tt, index = h.tag, i + break outer + } + } + } + } + // TODO: select first language tag based on script. + } + if w.RegionID != tt.RegionID && w.RegionID != 0 { + if w.RegionID != 0 && tt.RegionID != 0 && tt.RegionID.Contains(w.RegionID) { + tt.RegionID = w.RegionID + tt.RemakeString() + } else if r := w.RegionID.String(); len(r) == 2 { + // TODO: also filter macro and deprecated. + tt, _ = tt.SetTypeForKey("rg", strings.ToLower(r)+"zzzz") + } + } + // Copy options from the user-provided tag into the result tag. This is hard + // to do after the fact, so we do it here. + // TODO: add in alternative variants to -u-va-. + // TODO: add preferred region to -u-rg-. + if e := w.Extensions(); len(e) > 0 { + b := language.Builder{} + b.SetTag(tt) + for _, e := range e { + b.AddExt(e) + } + tt = b.Make() + } + return makeTag(tt), index, c +} + +// ErrMissingLikelyTagsData indicates no information was available +// to compute likely values of missing tags. +var ErrMissingLikelyTagsData = errors.New("missing likely tags data") + +// func (t *Tag) setTagsFrom(id Tag) { +// t.LangID = id.LangID +// t.ScriptID = id.ScriptID +// t.RegionID = id.RegionID +// } + +// Tag Matching +// CLDR defines an algorithm for finding the best match between two sets of language +// tags. The basic algorithm defines how to score a possible match and then find +// the match with the best score +// (see https://www.unicode.org/reports/tr35/#LanguageMatching). +// Using scoring has several disadvantages. The scoring obfuscates the importance of +// the various factors considered, making the algorithm harder to understand. Using +// scoring also requires the full score to be computed for each pair of tags. +// +// We will use a different algorithm which aims to have the following properties: +// - clarity on the precedence of the various selection factors, and +// - improved performance by allowing early termination of a comparison. +// +// Matching algorithm (overview) +// Input: +// - supported: a set of supported tags +// - default: the default tag to return in case there is no match +// - desired: list of desired tags, ordered by preference, starting with +// the most-preferred. +// +// Algorithm: +// 1) Set the best match to the lowest confidence level +// 2) For each tag in "desired": +// a) For each tag in "supported": +// 1) compute the match between the two tags. +// 2) if the match is better than the previous best match, replace it +// with the new match. (see next section) +// b) if the current best match is Exact and pin is true the result will be +// frozen to the language found thusfar, although better matches may +// still be found for the same language. +// 3) If the best match so far is below a certain threshold, return "default". +// +// Ranking: +// We use two phases to determine whether one pair of tags are a better match +// than another pair of tags. First, we determine a rough confidence level. If the +// levels are different, the one with the highest confidence wins. +// Second, if the rough confidence levels are identical, we use a set of tie-breaker +// rules. +// +// The confidence level of matching a pair of tags is determined by finding the +// lowest confidence level of any matches of the corresponding subtags (the +// result is deemed as good as its weakest link). +// We define the following levels: +// Exact - An exact match of a subtag, before adding likely subtags. +// MaxExact - An exact match of a subtag, after adding likely subtags. +// [See Note 2]. +// High - High level of mutual intelligibility between different subtag +// variants. +// Low - Low level of mutual intelligibility between different subtag +// variants. +// No - No mutual intelligibility. +// +// The following levels can occur for each type of subtag: +// Base: Exact, MaxExact, High, Low, No +// Script: Exact, MaxExact [see Note 3], Low, No +// Region: Exact, MaxExact, High +// Variant: Exact, High +// Private: Exact, No +// +// Any result with a confidence level of Low or higher is deemed a possible match. +// Once a desired tag matches any of the supported tags with a level of MaxExact +// or higher, the next desired tag is not considered (see Step 2.b). +// Note that CLDR provides languageMatching data that defines close equivalence +// classes for base languages, scripts and regions. +// +// Tie-breaking +// If we get the same confidence level for two matches, we apply a sequence of +// tie-breaking rules. The first that succeeds defines the result. The rules are +// applied in the following order. +// 1) Original language was defined and was identical. +// 2) Original region was defined and was identical. +// 3) Distance between two maximized regions was the smallest. +// 4) Original script was defined and was identical. +// 5) Distance from want tag to have tag using the parent relation [see Note 5.] +// If there is still no winner after these rules are applied, the first match +// found wins. +// +// Notes: +// [2] In practice, as matching of Exact is done in a separate phase from +// matching the other levels, we reuse the Exact level to mean MaxExact in +// the second phase. As a consequence, we only need the levels defined by +// the Confidence type. The MaxExact confidence level is mapped to High in +// the public API. +// [3] We do not differentiate between maximized script values that were derived +// from suppressScript versus most likely tag data. We determined that in +// ranking the two, one ranks just after the other. Moreover, the two cannot +// occur concurrently. As a consequence, they are identical for practical +// purposes. +// [4] In case of deprecated, macro-equivalents and legacy mappings, we assign +// the MaxExact level to allow iw vs he to still be a closer match than +// en-AU vs en-US, for example. +// [5] In CLDR a locale inherits fields that are unspecified for this locale +// from its parent. Therefore, if a locale is a parent of another locale, +// it is a strong measure for closeness, especially when no other tie +// breaker rule applies. One could also argue it is inconsistent, for +// example, when pt-AO matches pt (which CLDR equates with pt-BR), even +// though its parent is pt-PT according to the inheritance rules. +// +// Implementation Details: +// There are several performance considerations worth pointing out. Most notably, +// we preprocess as much as possible (within reason) at the time of creation of a +// matcher. This includes: +// - creating a per-language map, which includes data for the raw base language +// and its canonicalized variant (if applicable), +// - expanding entries for the equivalence classes defined in CLDR's +// languageMatch data. +// The per-language map ensures that typically only a very small number of tags +// need to be considered. The pre-expansion of canonicalized subtags and +// equivalence classes reduces the amount of map lookups that need to be done at +// runtime. + +// matcher keeps a set of supported language tags, indexed by language. +type matcher struct { + default_ *haveTag + supported []*haveTag + index map[language.Language]*matchHeader + passSettings bool + preferSameScript bool +} + +// matchHeader has the lists of tags for exact matches and matches based on +// maximized and canonicalized tags for a given language. +type matchHeader struct { + haveTags []*haveTag + original bool +} + +// haveTag holds a supported Tag and its maximized script and region. The maximized +// or canonicalized language is not stored as it is not needed during matching. +type haveTag struct { + tag language.Tag + + // index of this tag in the original list of supported tags. + index int + + // conf is the maximum confidence that can result from matching this haveTag. + // When conf < Exact this means it was inserted after applying a CLDR equivalence rule. + conf Confidence + + // Maximized region and script. + maxRegion language.Region + maxScript language.Script + + // altScript may be checked as an alternative match to maxScript. If altScript + // matches, the confidence level for this match is Low. Theoretically there + // could be multiple alternative scripts. This does not occur in practice. + altScript language.Script + + // nextMax is the index of the next haveTag with the same maximized tags. + nextMax uint16 +} + +func makeHaveTag(tag language.Tag, index int) (haveTag, language.Language) { + max := tag + if tag.LangID != 0 || tag.RegionID != 0 || tag.ScriptID != 0 { + max, _ = canonicalize(All, max) + max, _ = max.Maximize() + max.RemakeString() + } + return haveTag{tag, index, Exact, max.RegionID, max.ScriptID, altScript(max.LangID, max.ScriptID), 0}, max.LangID +} + +// altScript returns an alternative script that may match the given script with +// a low confidence. At the moment, the langMatch data allows for at most one +// script to map to another and we rely on this to keep the code simple. +func altScript(l language.Language, s language.Script) language.Script { + for _, alt := range matchScript { + // TODO: also match cases where language is not the same. + if (language.Language(alt.wantLang) == l || language.Language(alt.haveLang) == l) && + language.Script(alt.haveScript) == s { + return language.Script(alt.wantScript) + } + } + return 0 +} + +// addIfNew adds a haveTag to the list of tags only if it is a unique tag. +// Tags that have the same maximized values are linked by index. +func (h *matchHeader) addIfNew(n haveTag, exact bool) { + h.original = h.original || exact + // Don't add new exact matches. + for _, v := range h.haveTags { + if equalsRest(v.tag, n.tag) { + return + } + } + // Allow duplicate maximized tags, but create a linked list to allow quickly + // comparing the equivalents and bail out. + for i, v := range h.haveTags { + if v.maxScript == n.maxScript && + v.maxRegion == n.maxRegion && + v.tag.VariantOrPrivateUseTags() == n.tag.VariantOrPrivateUseTags() { + for h.haveTags[i].nextMax != 0 { + i = int(h.haveTags[i].nextMax) + } + h.haveTags[i].nextMax = uint16(len(h.haveTags)) + break + } + } + h.haveTags = append(h.haveTags, &n) +} + +// header returns the matchHeader for the given language. It creates one if +// it doesn't already exist. +func (m *matcher) header(l language.Language) *matchHeader { + if h := m.index[l]; h != nil { + return h + } + h := &matchHeader{} + m.index[l] = h + return h +} + +func toConf(d uint8) Confidence { + if d <= 10 { + return High + } + if d < 30 { + return Low + } + return No +} + +// newMatcher builds an index for the given supported tags and returns it as +// a matcher. It also expands the index by considering various equivalence classes +// for a given tag. +func newMatcher(supported []Tag, options []MatchOption) *matcher { + m := &matcher{ + index: make(map[language.Language]*matchHeader), + preferSameScript: true, + } + for _, o := range options { + o(m) + } + if len(supported) == 0 { + m.default_ = &haveTag{} + return m + } + // Add supported languages to the index. Add exact matches first to give + // them precedence. + for i, tag := range supported { + tt := tag.tag() + pair, _ := makeHaveTag(tt, i) + m.header(tt.LangID).addIfNew(pair, true) + m.supported = append(m.supported, &pair) + } + m.default_ = m.header(supported[0].lang()).haveTags[0] + // Keep these in two different loops to support the case that two equivalent + // languages are distinguished, such as iw and he. + for i, tag := range supported { + tt := tag.tag() + pair, max := makeHaveTag(tt, i) + if max != tt.LangID { + m.header(max).addIfNew(pair, true) + } + } + + // update is used to add indexes in the map for equivalent languages. + // update will only add entries to original indexes, thus not computing any + // transitive relations. + update := func(want, have uint16, conf Confidence) { + if hh := m.index[language.Language(have)]; hh != nil { + if !hh.original { + return + } + hw := m.header(language.Language(want)) + for _, ht := range hh.haveTags { + v := *ht + if conf < v.conf { + v.conf = conf + } + v.nextMax = 0 // this value needs to be recomputed + if v.altScript != 0 { + v.altScript = altScript(language.Language(want), v.maxScript) + } + hw.addIfNew(v, conf == Exact && hh.original) + } + } + } + + // Add entries for languages with mutual intelligibility as defined by CLDR's + // languageMatch data. + for _, ml := range matchLang { + update(ml.want, ml.have, toConf(ml.distance)) + if !ml.oneway { + update(ml.have, ml.want, toConf(ml.distance)) + } + } + + // Add entries for possible canonicalizations. This is an optimization to + // ensure that only one map lookup needs to be done at runtime per desired tag. + // First we match deprecated equivalents. If they are perfect equivalents + // (their canonicalization simply substitutes a different language code, but + // nothing else), the match confidence is Exact, otherwise it is High. + for i, lm := range language.AliasMap { + // If deprecated codes match and there is no fiddling with the script + // or region, we consider it an exact match. + conf := Exact + if language.AliasTypes[i] != language.Macro { + if !isExactEquivalent(language.Language(lm.From)) { + conf = High + } + update(lm.To, lm.From, conf) + } + update(lm.From, lm.To, conf) + } + return m +} + +// getBest gets the best matching tag in m for any of the given tags, taking into +// account the order of preference of the given tags. +func (m *matcher) getBest(want ...Tag) (got *haveTag, orig language.Tag, c Confidence) { + best := bestMatch{} + for i, ww := range want { + w := ww.tag() + var max language.Tag + // Check for exact match first. + h := m.index[w.LangID] + if w.LangID != 0 { + if h == nil { + continue + } + // Base language is defined. + max, _ = canonicalize(Legacy|Deprecated|Macro, w) + // A region that is added through canonicalization is stronger than + // a maximized region: set it in the original (e.g. mo -> ro-MD). + if w.RegionID != max.RegionID { + w.RegionID = max.RegionID + } + // TODO: should we do the same for scripts? + // See test case: en, sr, nl ; sh ; sr + max, _ = max.Maximize() + } else { + // Base language is not defined. + if h != nil { + for i := range h.haveTags { + have := h.haveTags[i] + if equalsRest(have.tag, w) { + return have, w, Exact + } + } + } + if w.ScriptID == 0 && w.RegionID == 0 { + // We skip all tags matching und for approximate matching, including + // private tags. + continue + } + max, _ = w.Maximize() + if h = m.index[max.LangID]; h == nil { + continue + } + } + pin := true + for _, t := range want[i+1:] { + if w.LangID == t.lang() { + pin = false + break + } + } + // Check for match based on maximized tag. + for i := range h.haveTags { + have := h.haveTags[i] + best.update(have, w, max.ScriptID, max.RegionID, pin) + if best.conf == Exact { + for have.nextMax != 0 { + have = h.haveTags[have.nextMax] + best.update(have, w, max.ScriptID, max.RegionID, pin) + } + return best.have, best.want, best.conf + } + } + } + if best.conf <= No { + if len(want) != 0 { + return nil, want[0].tag(), No + } + return nil, language.Tag{}, No + } + return best.have, best.want, best.conf +} + +// bestMatch accumulates the best match so far. +type bestMatch struct { + have *haveTag + want language.Tag + conf Confidence + pinnedRegion language.Region + pinLanguage bool + sameRegionGroup bool + // Cached results from applying tie-breaking rules. + origLang bool + origReg bool + paradigmReg bool + regGroupDist uint8 + origScript bool +} + +// update updates the existing best match if the new pair is considered to be a +// better match. To determine if the given pair is a better match, it first +// computes the rough confidence level. If this surpasses the current match, it +// will replace it and update the tie-breaker rule cache. If there is a tie, it +// proceeds with applying a series of tie-breaker rules. If there is no +// conclusive winner after applying the tie-breaker rules, it leaves the current +// match as the preferred match. +// +// If pin is true and have and tag are a strong match, it will henceforth only +// consider matches for this language. This corresponds to the idea that most +// users have a strong preference for the first defined language. A user can +// still prefer a second language over a dialect of the preferred language by +// explicitly specifying dialects, e.g. "en, nl, en-GB". In this case pin should +// be false. +func (m *bestMatch) update(have *haveTag, tag language.Tag, maxScript language.Script, maxRegion language.Region, pin bool) { + // Bail if the maximum attainable confidence is below that of the current best match. + c := have.conf + if c < m.conf { + return + } + // Don't change the language once we already have found an exact match. + if m.pinLanguage && tag.LangID != m.want.LangID { + return + } + // Pin the region group if we are comparing tags for the same language. + if tag.LangID == m.want.LangID && m.sameRegionGroup { + _, sameGroup := regionGroupDist(m.pinnedRegion, have.maxRegion, have.maxScript, m.want.LangID) + if !sameGroup { + return + } + } + if c == Exact && have.maxScript == maxScript { + // If there is another language and then another entry of this language, + // don't pin anything, otherwise pin the language. + m.pinLanguage = pin + } + if equalsRest(have.tag, tag) { + } else if have.maxScript != maxScript { + // There is usually very little comprehension between different scripts. + // In a few cases there may still be Low comprehension. This possibility + // is pre-computed and stored in have.altScript. + if Low < m.conf || have.altScript != maxScript { + return + } + c = Low + } else if have.maxRegion != maxRegion { + if High < c { + // There is usually a small difference between languages across regions. + c = High + } + } + + // We store the results of the computations of the tie-breaker rules along + // with the best match. There is no need to do the checks once we determine + // we have a winner, but we do still need to do the tie-breaker computations. + // We use "beaten" to keep track if we still need to do the checks. + beaten := false // true if the new pair defeats the current one. + if c != m.conf { + if c < m.conf { + return + } + beaten = true + } + + // Tie-breaker rules: + // We prefer if the pre-maximized language was specified and identical. + origLang := have.tag.LangID == tag.LangID && tag.LangID != 0 + if !beaten && m.origLang != origLang { + if m.origLang { + return + } + beaten = true + } + + // We prefer if the pre-maximized region was specified and identical. + origReg := have.tag.RegionID == tag.RegionID && tag.RegionID != 0 + if !beaten && m.origReg != origReg { + if m.origReg { + return + } + beaten = true + } + + regGroupDist, sameGroup := regionGroupDist(have.maxRegion, maxRegion, maxScript, tag.LangID) + if !beaten && m.regGroupDist != regGroupDist { + if regGroupDist > m.regGroupDist { + return + } + beaten = true + } + + paradigmReg := isParadigmLocale(tag.LangID, have.maxRegion) + if !beaten && m.paradigmReg != paradigmReg { + if !paradigmReg { + return + } + beaten = true + } + + // Next we prefer if the pre-maximized script was specified and identical. + origScript := have.tag.ScriptID == tag.ScriptID && tag.ScriptID != 0 + if !beaten && m.origScript != origScript { + if m.origScript { + return + } + beaten = true + } + + // Update m to the newly found best match. + if beaten { + m.have = have + m.want = tag + m.conf = c + m.pinnedRegion = maxRegion + m.sameRegionGroup = sameGroup + m.origLang = origLang + m.origReg = origReg + m.paradigmReg = paradigmReg + m.origScript = origScript + m.regGroupDist = regGroupDist + } +} + +func isParadigmLocale(lang language.Language, r language.Region) bool { + for _, e := range paradigmLocales { + if language.Language(e[0]) == lang && (r == language.Region(e[1]) || r == language.Region(e[2])) { + return true + } + } + return false +} + +// regionGroupDist computes the distance between two regions based on their +// CLDR grouping. +func regionGroupDist(a, b language.Region, script language.Script, lang language.Language) (dist uint8, same bool) { + const defaultDistance = 4 + + aGroup := uint(regionToGroups[a]) << 1 + bGroup := uint(regionToGroups[b]) << 1 + for _, ri := range matchRegion { + if language.Language(ri.lang) == lang && (ri.script == 0 || language.Script(ri.script) == script) { + group := uint(1 << (ri.group &^ 0x80)) + if 0x80&ri.group == 0 { + if aGroup&bGroup&group != 0 { // Both regions are in the group. + return ri.distance, ri.distance == defaultDistance + } + } else { + if (aGroup|bGroup)&group == 0 { // Both regions are not in the group. + return ri.distance, ri.distance == defaultDistance + } + } + } + } + return defaultDistance, true +} + +// equalsRest compares everything except the language. +func equalsRest(a, b language.Tag) bool { + // TODO: don't include extensions in this comparison. To do this efficiently, + // though, we should handle private tags separately. + return a.ScriptID == b.ScriptID && a.RegionID == b.RegionID && a.VariantOrPrivateUseTags() == b.VariantOrPrivateUseTags() +} + +// isExactEquivalent returns true if canonicalizing the language will not alter +// the script or region of a tag. +func isExactEquivalent(l language.Language) bool { + for _, o := range notEquivalent { + if o == l { + return false + } + } + return true +} + +var notEquivalent []language.Language + +func init() { + // Create a list of all languages for which canonicalization may alter the + // script or region. + for _, lm := range language.AliasMap { + tag := language.Tag{LangID: language.Language(lm.From)} + if tag, _ = canonicalize(All, tag); tag.ScriptID != 0 || tag.RegionID != 0 { + notEquivalent = append(notEquivalent, language.Language(lm.From)) + } + } + // Maximize undefined regions of paradigm locales. + for i, v := range paradigmLocales { + t := language.Tag{LangID: language.Language(v[0])} + max, _ := t.Maximize() + if v[1] == 0 { + paradigmLocales[i][1] = uint16(max.RegionID) + } + if v[2] == 0 { + paradigmLocales[i][2] = uint16(max.RegionID) + } + } +} diff --git a/vendor/golang.org/x/text/language/parse.go b/vendor/golang.org/x/text/language/parse.go new file mode 100644 index 000000000..4d57222e7 --- /dev/null +++ b/vendor/golang.org/x/text/language/parse.go @@ -0,0 +1,256 @@ +// Copyright 2013 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 language + +import ( + "errors" + "sort" + "strconv" + "strings" + + "golang.org/x/text/internal/language" +) + +// ValueError is returned by any of the parsing functions when the +// input is well-formed but the respective subtag is not recognized +// as a valid value. +type ValueError interface { + error + + // Subtag returns the subtag for which the error occurred. + Subtag() string +} + +// Parse parses the given BCP 47 string and returns a valid Tag. If parsing +// failed it returns an error and any part of the tag that could be parsed. +// If parsing succeeded but an unknown value was found, it returns +// ValueError. The Tag returned in this case is just stripped of the unknown +// value. All other values are preserved. It accepts tags in the BCP 47 format +// and extensions to this standard defined in +// https://www.unicode.org/reports/tr35/#Unicode_Language_and_Locale_Identifiers. +// The resulting tag is canonicalized using the default canonicalization type. +func Parse(s string) (t Tag, err error) { + return Default.Parse(s) +} + +// Parse parses the given BCP 47 string and returns a valid Tag. If parsing +// failed it returns an error and any part of the tag that could be parsed. +// If parsing succeeded but an unknown value was found, it returns +// ValueError. The Tag returned in this case is just stripped of the unknown +// value. All other values are preserved. It accepts tags in the BCP 47 format +// and extensions to this standard defined in +// https://www.unicode.org/reports/tr35/#Unicode_Language_and_Locale_Identifiers. +// The resulting tag is canonicalized using the canonicalization type c. +func (c CanonType) Parse(s string) (t Tag, err error) { + defer func() { + if recover() != nil { + t = Tag{} + err = language.ErrSyntax + } + }() + + tt, err := language.Parse(s) + if err != nil { + return makeTag(tt), err + } + tt, changed := canonicalize(c, tt) + if changed { + tt.RemakeString() + } + return makeTag(tt), err +} + +// Compose creates a Tag from individual parts, which may be of type Tag, Base, +// Script, Region, Variant, []Variant, Extension, []Extension or error. If a +// Base, Script or Region or slice of type Variant or Extension is passed more +// than once, the latter will overwrite the former. Variants and Extensions are +// accumulated, but if two extensions of the same type are passed, the latter +// will replace the former. For -u extensions, though, the key-type pairs are +// added, where later values overwrite older ones. A Tag overwrites all former +// values and typically only makes sense as the first argument. The resulting +// tag is returned after canonicalizing using the Default CanonType. If one or +// more errors are encountered, one of the errors is returned. +func Compose(part ...interface{}) (t Tag, err error) { + return Default.Compose(part...) +} + +// Compose creates a Tag from individual parts, which may be of type Tag, Base, +// Script, Region, Variant, []Variant, Extension, []Extension or error. If a +// Base, Script or Region or slice of type Variant or Extension is passed more +// than once, the latter will overwrite the former. Variants and Extensions are +// accumulated, but if two extensions of the same type are passed, the latter +// will replace the former. For -u extensions, though, the key-type pairs are +// added, where later values overwrite older ones. A Tag overwrites all former +// values and typically only makes sense as the first argument. The resulting +// tag is returned after canonicalizing using CanonType c. If one or more errors +// are encountered, one of the errors is returned. +func (c CanonType) Compose(part ...interface{}) (t Tag, err error) { + defer func() { + if recover() != nil { + t = Tag{} + err = language.ErrSyntax + } + }() + + var b language.Builder + if err = update(&b, part...); err != nil { + return und, err + } + b.Tag, _ = canonicalize(c, b.Tag) + return makeTag(b.Make()), err +} + +var errInvalidArgument = errors.New("invalid Extension or Variant") + +func update(b *language.Builder, part ...interface{}) (err error) { + for _, x := range part { + switch v := x.(type) { + case Tag: + b.SetTag(v.tag()) + case Base: + b.Tag.LangID = v.langID + case Script: + b.Tag.ScriptID = v.scriptID + case Region: + b.Tag.RegionID = v.regionID + case Variant: + if v.variant == "" { + err = errInvalidArgument + break + } + b.AddVariant(v.variant) + case Extension: + if v.s == "" { + err = errInvalidArgument + break + } + b.SetExt(v.s) + case []Variant: + b.ClearVariants() + for _, v := range v { + b.AddVariant(v.variant) + } + case []Extension: + b.ClearExtensions() + for _, e := range v { + b.SetExt(e.s) + } + // TODO: support parsing of raw strings based on morphology or just extensions? + case error: + if v != nil { + err = v + } + } + } + return +} + +var errInvalidWeight = errors.New("ParseAcceptLanguage: invalid weight") +var errTagListTooLarge = errors.New("tag list exceeds max length") + +// ParseAcceptLanguage parses the contents of an Accept-Language header as +// defined in http://www.ietf.org/rfc/rfc2616.txt and returns a list of Tags and +// a list of corresponding quality weights. It is more permissive than RFC 2616 +// and may return non-nil slices even if the input is not valid. +// The Tags will be sorted by highest weight first and then by first occurrence. +// Tags with a weight of zero will be dropped. An error will be returned if the +// input could not be parsed. +func ParseAcceptLanguage(s string) (tag []Tag, q []float32, err error) { + defer func() { + if recover() != nil { + tag = nil + q = nil + err = language.ErrSyntax + } + }() + + if strings.Count(s, "-") > 1000 { + return nil, nil, errTagListTooLarge + } + + var entry string + for s != "" { + if entry, s = split(s, ','); entry == "" { + continue + } + + entry, weight := split(entry, ';') + + // Scan the language. + t, err := Parse(entry) + if err != nil { + id, ok := acceptFallback[entry] + if !ok { + return nil, nil, err + } + t = makeTag(language.Tag{LangID: id}) + } + + // Scan the optional weight. + w := 1.0 + if weight != "" { + weight = consume(weight, 'q') + weight = consume(weight, '=') + // consume returns the empty string when a token could not be + // consumed, resulting in an error for ParseFloat. + if w, err = strconv.ParseFloat(weight, 32); err != nil { + return nil, nil, errInvalidWeight + } + // Drop tags with a quality weight of 0. + if w <= 0 { + continue + } + } + + tag = append(tag, t) + q = append(q, float32(w)) + } + sort.Stable(&tagSort{tag, q}) + return tag, q, nil +} + +// consume removes a leading token c from s and returns the result or the empty +// string if there is no such token. +func consume(s string, c byte) string { + if s == "" || s[0] != c { + return "" + } + return strings.TrimSpace(s[1:]) +} + +func split(s string, c byte) (head, tail string) { + if i := strings.IndexByte(s, c); i >= 0 { + return strings.TrimSpace(s[:i]), strings.TrimSpace(s[i+1:]) + } + return strings.TrimSpace(s), "" +} + +// Add hack mapping to deal with a small number of cases that occur +// in Accept-Language (with reasonable frequency). +var acceptFallback = map[string]language.Language{ + "english": _en, + "deutsch": _de, + "italian": _it, + "french": _fr, + "*": _mul, // defined in the spec to match all languages. +} + +type tagSort struct { + tag []Tag + q []float32 +} + +func (s *tagSort) Len() int { + return len(s.q) +} + +func (s *tagSort) Less(i, j int) bool { + return s.q[i] > s.q[j] +} + +func (s *tagSort) Swap(i, j int) { + s.tag[i], s.tag[j] = s.tag[j], s.tag[i] + s.q[i], s.q[j] = s.q[j], s.q[i] +} diff --git a/vendor/golang.org/x/text/language/tables.go b/vendor/golang.org/x/text/language/tables.go new file mode 100644 index 000000000..a6573dcb2 --- /dev/null +++ b/vendor/golang.org/x/text/language/tables.go @@ -0,0 +1,298 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +package language + +// CLDRVersion is the CLDR version from which the tables in this package are derived. +const CLDRVersion = "32" + +const ( + _de = 269 + _en = 313 + _fr = 350 + _it = 505 + _mo = 784 + _no = 879 + _nb = 839 + _pt = 960 + _sh = 1031 + _mul = 806 + _und = 0 +) +const ( + _001 = 1 + _419 = 31 + _BR = 65 + _CA = 73 + _ES = 111 + _GB = 124 + _MD = 189 + _PT = 239 + _UK = 307 + _US = 310 + _ZZ = 358 + _XA = 324 + _XC = 326 + _XK = 334 +) +const ( + _Latn = 91 + _Hani = 57 + _Hans = 59 + _Hant = 60 + _Qaaa = 149 + _Qaai = 157 + _Qabx = 198 + _Zinh = 255 + _Zyyy = 260 + _Zzzz = 261 +) + +var regionToGroups = []uint8{ // 359 elements + // Entry 0 - 3F + 0x00, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x00, 0x04, + // Entry 40 - 7F + 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x00, + 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, + // Entry 80 - BF + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x04, 0x01, 0x00, 0x04, 0x02, 0x00, + 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x04, + // Entry C0 - FF + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x01, 0x04, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x05, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // Entry 100 - 13F + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x05, 0x04, + 0x00, 0x00, 0x04, 0x00, 0x04, 0x04, 0x05, 0x00, + // Entry 140 - 17F + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +} // Size: 383 bytes + +var paradigmLocales = [][3]uint16{ // 3 elements + 0: [3]uint16{0x139, 0x0, 0x7c}, + 1: [3]uint16{0x13e, 0x0, 0x1f}, + 2: [3]uint16{0x3c0, 0x41, 0xef}, +} // Size: 42 bytes + +type mutualIntelligibility struct { + want uint16 + have uint16 + distance uint8 + oneway bool +} +type scriptIntelligibility struct { + wantLang uint16 + haveLang uint16 + wantScript uint8 + haveScript uint8 + distance uint8 +} +type regionIntelligibility struct { + lang uint16 + script uint8 + group uint8 + distance uint8 +} + +// matchLang holds pairs of langIDs of base languages that are typically +// mutually intelligible. Each pair is associated with a confidence and +// whether the intelligibility goes one or both ways. +var matchLang = []mutualIntelligibility{ // 113 elements + 0: {want: 0x1d1, have: 0xb7, distance: 0x4, oneway: false}, + 1: {want: 0x407, have: 0xb7, distance: 0x4, oneway: false}, + 2: {want: 0x407, have: 0x1d1, distance: 0x4, oneway: false}, + 3: {want: 0x407, have: 0x432, distance: 0x4, oneway: false}, + 4: {want: 0x43a, have: 0x1, distance: 0x4, oneway: false}, + 5: {want: 0x1a3, have: 0x10d, distance: 0x4, oneway: true}, + 6: {want: 0x295, have: 0x10d, distance: 0x4, oneway: true}, + 7: {want: 0x101, have: 0x36f, distance: 0x8, oneway: false}, + 8: {want: 0x101, have: 0x347, distance: 0x8, oneway: false}, + 9: {want: 0x5, have: 0x3e2, distance: 0xa, oneway: true}, + 10: {want: 0xd, have: 0x139, distance: 0xa, oneway: true}, + 11: {want: 0x16, have: 0x367, distance: 0xa, oneway: true}, + 12: {want: 0x21, have: 0x139, distance: 0xa, oneway: true}, + 13: {want: 0x56, have: 0x13e, distance: 0xa, oneway: true}, + 14: {want: 0x58, have: 0x3e2, distance: 0xa, oneway: true}, + 15: {want: 0x71, have: 0x3e2, distance: 0xa, oneway: true}, + 16: {want: 0x75, have: 0x139, distance: 0xa, oneway: true}, + 17: {want: 0x82, have: 0x1be, distance: 0xa, oneway: true}, + 18: {want: 0xa5, have: 0x139, distance: 0xa, oneway: true}, + 19: {want: 0xb2, have: 0x15e, distance: 0xa, oneway: true}, + 20: {want: 0xdd, have: 0x153, distance: 0xa, oneway: true}, + 21: {want: 0xe5, have: 0x139, distance: 0xa, oneway: true}, + 22: {want: 0xe9, have: 0x3a, distance: 0xa, oneway: true}, + 23: {want: 0xf0, have: 0x15e, distance: 0xa, oneway: true}, + 24: {want: 0xf9, have: 0x15e, distance: 0xa, oneway: true}, + 25: {want: 0x100, have: 0x139, distance: 0xa, oneway: true}, + 26: {want: 0x130, have: 0x139, distance: 0xa, oneway: true}, + 27: {want: 0x13c, have: 0x139, distance: 0xa, oneway: true}, + 28: {want: 0x140, have: 0x151, distance: 0xa, oneway: true}, + 29: {want: 0x145, have: 0x13e, distance: 0xa, oneway: true}, + 30: {want: 0x158, have: 0x101, distance: 0xa, oneway: true}, + 31: {want: 0x16d, have: 0x367, distance: 0xa, oneway: true}, + 32: {want: 0x16e, have: 0x139, distance: 0xa, oneway: true}, + 33: {want: 0x16f, have: 0x139, distance: 0xa, oneway: true}, + 34: {want: 0x17e, have: 0x139, distance: 0xa, oneway: true}, + 35: {want: 0x190, have: 0x13e, distance: 0xa, oneway: true}, + 36: {want: 0x194, have: 0x13e, distance: 0xa, oneway: true}, + 37: {want: 0x1a4, have: 0x1be, distance: 0xa, oneway: true}, + 38: {want: 0x1b4, have: 0x139, distance: 0xa, oneway: true}, + 39: {want: 0x1b8, have: 0x139, distance: 0xa, oneway: true}, + 40: {want: 0x1d4, have: 0x15e, distance: 0xa, oneway: true}, + 41: {want: 0x1d7, have: 0x3e2, distance: 0xa, oneway: true}, + 42: {want: 0x1d9, have: 0x139, distance: 0xa, oneway: true}, + 43: {want: 0x1e7, have: 0x139, distance: 0xa, oneway: true}, + 44: {want: 0x1f8, have: 0x139, distance: 0xa, oneway: true}, + 45: {want: 0x20e, have: 0x1e1, distance: 0xa, oneway: true}, + 46: {want: 0x210, have: 0x139, distance: 0xa, oneway: true}, + 47: {want: 0x22d, have: 0x15e, distance: 0xa, oneway: true}, + 48: {want: 0x242, have: 0x3e2, distance: 0xa, oneway: true}, + 49: {want: 0x24a, have: 0x139, distance: 0xa, oneway: true}, + 50: {want: 0x251, have: 0x139, distance: 0xa, oneway: true}, + 51: {want: 0x265, have: 0x139, distance: 0xa, oneway: true}, + 52: {want: 0x274, have: 0x48a, distance: 0xa, oneway: true}, + 53: {want: 0x28a, have: 0x3e2, distance: 0xa, oneway: true}, + 54: {want: 0x28e, have: 0x1f9, distance: 0xa, oneway: true}, + 55: {want: 0x2a3, have: 0x139, distance: 0xa, oneway: true}, + 56: {want: 0x2b5, have: 0x15e, distance: 0xa, oneway: true}, + 57: {want: 0x2b8, have: 0x139, distance: 0xa, oneway: true}, + 58: {want: 0x2be, have: 0x139, distance: 0xa, oneway: true}, + 59: {want: 0x2c3, have: 0x15e, distance: 0xa, oneway: true}, + 60: {want: 0x2ed, have: 0x139, distance: 0xa, oneway: true}, + 61: {want: 0x2f1, have: 0x15e, distance: 0xa, oneway: true}, + 62: {want: 0x2fa, have: 0x139, distance: 0xa, oneway: true}, + 63: {want: 0x2ff, have: 0x7e, distance: 0xa, oneway: true}, + 64: {want: 0x304, have: 0x139, distance: 0xa, oneway: true}, + 65: {want: 0x30b, have: 0x3e2, distance: 0xa, oneway: true}, + 66: {want: 0x31b, have: 0x1be, distance: 0xa, oneway: true}, + 67: {want: 0x31f, have: 0x1e1, distance: 0xa, oneway: true}, + 68: {want: 0x320, have: 0x139, distance: 0xa, oneway: true}, + 69: {want: 0x331, have: 0x139, distance: 0xa, oneway: true}, + 70: {want: 0x351, have: 0x139, distance: 0xa, oneway: true}, + 71: {want: 0x36a, have: 0x347, distance: 0xa, oneway: false}, + 72: {want: 0x36a, have: 0x36f, distance: 0xa, oneway: true}, + 73: {want: 0x37a, have: 0x139, distance: 0xa, oneway: true}, + 74: {want: 0x387, have: 0x139, distance: 0xa, oneway: true}, + 75: {want: 0x389, have: 0x139, distance: 0xa, oneway: true}, + 76: {want: 0x38b, have: 0x15e, distance: 0xa, oneway: true}, + 77: {want: 0x390, have: 0x139, distance: 0xa, oneway: true}, + 78: {want: 0x395, have: 0x139, distance: 0xa, oneway: true}, + 79: {want: 0x39d, have: 0x139, distance: 0xa, oneway: true}, + 80: {want: 0x3a5, have: 0x139, distance: 0xa, oneway: true}, + 81: {want: 0x3be, have: 0x139, distance: 0xa, oneway: true}, + 82: {want: 0x3c4, have: 0x13e, distance: 0xa, oneway: true}, + 83: {want: 0x3d4, have: 0x10d, distance: 0xa, oneway: true}, + 84: {want: 0x3d9, have: 0x139, distance: 0xa, oneway: true}, + 85: {want: 0x3e5, have: 0x15e, distance: 0xa, oneway: true}, + 86: {want: 0x3e9, have: 0x1be, distance: 0xa, oneway: true}, + 87: {want: 0x3fa, have: 0x139, distance: 0xa, oneway: true}, + 88: {want: 0x40c, have: 0x139, distance: 0xa, oneway: true}, + 89: {want: 0x423, have: 0x139, distance: 0xa, oneway: true}, + 90: {want: 0x429, have: 0x139, distance: 0xa, oneway: true}, + 91: {want: 0x431, have: 0x139, distance: 0xa, oneway: true}, + 92: {want: 0x43b, have: 0x139, distance: 0xa, oneway: true}, + 93: {want: 0x43e, have: 0x1e1, distance: 0xa, oneway: true}, + 94: {want: 0x445, have: 0x139, distance: 0xa, oneway: true}, + 95: {want: 0x450, have: 0x139, distance: 0xa, oneway: true}, + 96: {want: 0x461, have: 0x139, distance: 0xa, oneway: true}, + 97: {want: 0x467, have: 0x3e2, distance: 0xa, oneway: true}, + 98: {want: 0x46f, have: 0x139, distance: 0xa, oneway: true}, + 99: {want: 0x476, have: 0x3e2, distance: 0xa, oneway: true}, + 100: {want: 0x3883, have: 0x139, distance: 0xa, oneway: true}, + 101: {want: 0x480, have: 0x139, distance: 0xa, oneway: true}, + 102: {want: 0x482, have: 0x139, distance: 0xa, oneway: true}, + 103: {want: 0x494, have: 0x3e2, distance: 0xa, oneway: true}, + 104: {want: 0x49d, have: 0x139, distance: 0xa, oneway: true}, + 105: {want: 0x4ac, have: 0x529, distance: 0xa, oneway: true}, + 106: {want: 0x4b4, have: 0x139, distance: 0xa, oneway: true}, + 107: {want: 0x4bc, have: 0x3e2, distance: 0xa, oneway: true}, + 108: {want: 0x4e5, have: 0x15e, distance: 0xa, oneway: true}, + 109: {want: 0x4f2, have: 0x139, distance: 0xa, oneway: true}, + 110: {want: 0x512, have: 0x139, distance: 0xa, oneway: true}, + 111: {want: 0x518, have: 0x139, distance: 0xa, oneway: true}, + 112: {want: 0x52f, have: 0x139, distance: 0xa, oneway: true}, +} // Size: 702 bytes + +// matchScript holds pairs of scriptIDs where readers of one script +// can typically also read the other. Each is associated with a confidence. +var matchScript = []scriptIntelligibility{ // 26 elements + 0: {wantLang: 0x432, haveLang: 0x432, wantScript: 0x5b, haveScript: 0x20, distance: 0x5}, + 1: {wantLang: 0x432, haveLang: 0x432, wantScript: 0x20, haveScript: 0x5b, distance: 0x5}, + 2: {wantLang: 0x58, haveLang: 0x3e2, wantScript: 0x5b, haveScript: 0x20, distance: 0xa}, + 3: {wantLang: 0xa5, haveLang: 0x139, wantScript: 0xe, haveScript: 0x5b, distance: 0xa}, + 4: {wantLang: 0x1d7, haveLang: 0x3e2, wantScript: 0x8, haveScript: 0x20, distance: 0xa}, + 5: {wantLang: 0x210, haveLang: 0x139, wantScript: 0x2e, haveScript: 0x5b, distance: 0xa}, + 6: {wantLang: 0x24a, haveLang: 0x139, wantScript: 0x4f, haveScript: 0x5b, distance: 0xa}, + 7: {wantLang: 0x251, haveLang: 0x139, wantScript: 0x53, haveScript: 0x5b, distance: 0xa}, + 8: {wantLang: 0x2b8, haveLang: 0x139, wantScript: 0x58, haveScript: 0x5b, distance: 0xa}, + 9: {wantLang: 0x304, haveLang: 0x139, wantScript: 0x6f, haveScript: 0x5b, distance: 0xa}, + 10: {wantLang: 0x331, haveLang: 0x139, wantScript: 0x76, haveScript: 0x5b, distance: 0xa}, + 11: {wantLang: 0x351, haveLang: 0x139, wantScript: 0x22, haveScript: 0x5b, distance: 0xa}, + 12: {wantLang: 0x395, haveLang: 0x139, wantScript: 0x83, haveScript: 0x5b, distance: 0xa}, + 13: {wantLang: 0x39d, haveLang: 0x139, wantScript: 0x36, haveScript: 0x5b, distance: 0xa}, + 14: {wantLang: 0x3be, haveLang: 0x139, wantScript: 0x5, haveScript: 0x5b, distance: 0xa}, + 15: {wantLang: 0x3fa, haveLang: 0x139, wantScript: 0x5, haveScript: 0x5b, distance: 0xa}, + 16: {wantLang: 0x40c, haveLang: 0x139, wantScript: 0xd6, haveScript: 0x5b, distance: 0xa}, + 17: {wantLang: 0x450, haveLang: 0x139, wantScript: 0xe6, haveScript: 0x5b, distance: 0xa}, + 18: {wantLang: 0x461, haveLang: 0x139, wantScript: 0xe9, haveScript: 0x5b, distance: 0xa}, + 19: {wantLang: 0x46f, haveLang: 0x139, wantScript: 0x2c, haveScript: 0x5b, distance: 0xa}, + 20: {wantLang: 0x476, haveLang: 0x3e2, wantScript: 0x5b, haveScript: 0x20, distance: 0xa}, + 21: {wantLang: 0x4b4, haveLang: 0x139, wantScript: 0x5, haveScript: 0x5b, distance: 0xa}, + 22: {wantLang: 0x4bc, haveLang: 0x3e2, wantScript: 0x5b, haveScript: 0x20, distance: 0xa}, + 23: {wantLang: 0x512, haveLang: 0x139, wantScript: 0x3e, haveScript: 0x5b, distance: 0xa}, + 24: {wantLang: 0x529, haveLang: 0x529, wantScript: 0x3b, haveScript: 0x3c, distance: 0xf}, + 25: {wantLang: 0x529, haveLang: 0x529, wantScript: 0x3c, haveScript: 0x3b, distance: 0x13}, +} // Size: 232 bytes + +var matchRegion = []regionIntelligibility{ // 15 elements + 0: {lang: 0x3a, script: 0x0, group: 0x4, distance: 0x4}, + 1: {lang: 0x3a, script: 0x0, group: 0x84, distance: 0x4}, + 2: {lang: 0x139, script: 0x0, group: 0x1, distance: 0x4}, + 3: {lang: 0x139, script: 0x0, group: 0x81, distance: 0x4}, + 4: {lang: 0x13e, script: 0x0, group: 0x3, distance: 0x4}, + 5: {lang: 0x13e, script: 0x0, group: 0x83, distance: 0x4}, + 6: {lang: 0x3c0, script: 0x0, group: 0x3, distance: 0x4}, + 7: {lang: 0x3c0, script: 0x0, group: 0x83, distance: 0x4}, + 8: {lang: 0x529, script: 0x3c, group: 0x2, distance: 0x4}, + 9: {lang: 0x529, script: 0x3c, group: 0x82, distance: 0x4}, + 10: {lang: 0x3a, script: 0x0, group: 0x80, distance: 0x5}, + 11: {lang: 0x139, script: 0x0, group: 0x80, distance: 0x5}, + 12: {lang: 0x13e, script: 0x0, group: 0x80, distance: 0x5}, + 13: {lang: 0x3c0, script: 0x0, group: 0x80, distance: 0x5}, + 14: {lang: 0x529, script: 0x3c, group: 0x80, distance: 0x5}, +} // Size: 114 bytes + +// Total table size 1473 bytes (1KiB); checksum: 7BB90B5C diff --git a/vendor/golang.org/x/text/language/tags.go b/vendor/golang.org/x/text/language/tags.go new file mode 100644 index 000000000..42ea79266 --- /dev/null +++ b/vendor/golang.org/x/text/language/tags.go @@ -0,0 +1,145 @@ +// Copyright 2013 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 language + +import "golang.org/x/text/internal/language/compact" + +// TODO: Various sets of commonly use tags and regions. + +// MustParse is like Parse, but panics if the given BCP 47 tag cannot be parsed. +// It simplifies safe initialization of Tag values. +func MustParse(s string) Tag { + t, err := Parse(s) + if err != nil { + panic(err) + } + return t +} + +// MustParse is like Parse, but panics if the given BCP 47 tag cannot be parsed. +// It simplifies safe initialization of Tag values. +func (c CanonType) MustParse(s string) Tag { + t, err := c.Parse(s) + if err != nil { + panic(err) + } + return t +} + +// MustParseBase is like ParseBase, but panics if the given base cannot be parsed. +// It simplifies safe initialization of Base values. +func MustParseBase(s string) Base { + b, err := ParseBase(s) + if err != nil { + panic(err) + } + return b +} + +// MustParseScript is like ParseScript, but panics if the given script cannot be +// parsed. It simplifies safe initialization of Script values. +func MustParseScript(s string) Script { + scr, err := ParseScript(s) + if err != nil { + panic(err) + } + return scr +} + +// MustParseRegion is like ParseRegion, but panics if the given region cannot be +// parsed. It simplifies safe initialization of Region values. +func MustParseRegion(s string) Region { + r, err := ParseRegion(s) + if err != nil { + panic(err) + } + return r +} + +var ( + und = Tag{} + + Und Tag = Tag{} + + Afrikaans Tag = Tag(compact.Afrikaans) + Amharic Tag = Tag(compact.Amharic) + Arabic Tag = Tag(compact.Arabic) + ModernStandardArabic Tag = Tag(compact.ModernStandardArabic) + Azerbaijani Tag = Tag(compact.Azerbaijani) + Bulgarian Tag = Tag(compact.Bulgarian) + Bengali Tag = Tag(compact.Bengali) + Catalan Tag = Tag(compact.Catalan) + Czech Tag = Tag(compact.Czech) + Danish Tag = Tag(compact.Danish) + German Tag = Tag(compact.German) + Greek Tag = Tag(compact.Greek) + English Tag = Tag(compact.English) + AmericanEnglish Tag = Tag(compact.AmericanEnglish) + BritishEnglish Tag = Tag(compact.BritishEnglish) + Spanish Tag = Tag(compact.Spanish) + EuropeanSpanish Tag = Tag(compact.EuropeanSpanish) + LatinAmericanSpanish Tag = Tag(compact.LatinAmericanSpanish) + Estonian Tag = Tag(compact.Estonian) + Persian Tag = Tag(compact.Persian) + Finnish Tag = Tag(compact.Finnish) + Filipino Tag = Tag(compact.Filipino) + French Tag = Tag(compact.French) + CanadianFrench Tag = Tag(compact.CanadianFrench) + Gujarati Tag = Tag(compact.Gujarati) + Hebrew Tag = Tag(compact.Hebrew) + Hindi Tag = Tag(compact.Hindi) + Croatian Tag = Tag(compact.Croatian) + Hungarian Tag = Tag(compact.Hungarian) + Armenian Tag = Tag(compact.Armenian) + Indonesian Tag = Tag(compact.Indonesian) + Icelandic Tag = Tag(compact.Icelandic) + Italian Tag = Tag(compact.Italian) + Japanese Tag = Tag(compact.Japanese) + Georgian Tag = Tag(compact.Georgian) + Kazakh Tag = Tag(compact.Kazakh) + Khmer Tag = Tag(compact.Khmer) + Kannada Tag = Tag(compact.Kannada) + Korean Tag = Tag(compact.Korean) + Kirghiz Tag = Tag(compact.Kirghiz) + Lao Tag = Tag(compact.Lao) + Lithuanian Tag = Tag(compact.Lithuanian) + Latvian Tag = Tag(compact.Latvian) + Macedonian Tag = Tag(compact.Macedonian) + Malayalam Tag = Tag(compact.Malayalam) + Mongolian Tag = Tag(compact.Mongolian) + Marathi Tag = Tag(compact.Marathi) + Malay Tag = Tag(compact.Malay) + Burmese Tag = Tag(compact.Burmese) + Nepali Tag = Tag(compact.Nepali) + Dutch Tag = Tag(compact.Dutch) + Norwegian Tag = Tag(compact.Norwegian) + Punjabi Tag = Tag(compact.Punjabi) + Polish Tag = Tag(compact.Polish) + Portuguese Tag = Tag(compact.Portuguese) + BrazilianPortuguese Tag = Tag(compact.BrazilianPortuguese) + EuropeanPortuguese Tag = Tag(compact.EuropeanPortuguese) + Romanian Tag = Tag(compact.Romanian) + Russian Tag = Tag(compact.Russian) + Sinhala Tag = Tag(compact.Sinhala) + Slovak Tag = Tag(compact.Slovak) + Slovenian Tag = Tag(compact.Slovenian) + Albanian Tag = Tag(compact.Albanian) + Serbian Tag = Tag(compact.Serbian) + SerbianLatin Tag = Tag(compact.SerbianLatin) + Swedish Tag = Tag(compact.Swedish) + Swahili Tag = Tag(compact.Swahili) + Tamil Tag = Tag(compact.Tamil) + Telugu Tag = Tag(compact.Telugu) + Thai Tag = Tag(compact.Thai) + Turkish Tag = Tag(compact.Turkish) + Ukrainian Tag = Tag(compact.Ukrainian) + Urdu Tag = Tag(compact.Urdu) + Uzbek Tag = Tag(compact.Uzbek) + Vietnamese Tag = Tag(compact.Vietnamese) + Chinese Tag = Tag(compact.Chinese) + SimplifiedChinese Tag = Tag(compact.SimplifiedChinese) + TraditionalChinese Tag = Tag(compact.TraditionalChinese) + Zulu Tag = Tag(compact.Zulu) +) diff --git a/vendor/golang.org/x/text/message/catalog.go b/vendor/golang.org/x/text/message/catalog.go new file mode 100644 index 000000000..068271def --- /dev/null +++ b/vendor/golang.org/x/text/message/catalog.go @@ -0,0 +1,36 @@ +// 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 message + +// TODO: some types in this file will need to be made public at some time. +// Documentation and method names will reflect this by using the exported name. + +import ( + "golang.org/x/text/language" + "golang.org/x/text/message/catalog" +) + +// MatchLanguage reports the matched tag obtained from language.MatchStrings for +// the Matcher of the DefaultCatalog. +func MatchLanguage(preferred ...string) language.Tag { + c := DefaultCatalog + tag, _ := language.MatchStrings(c.Matcher(), preferred...) + return tag +} + +// DefaultCatalog is used by SetString. +var DefaultCatalog catalog.Catalog = defaultCatalog + +var defaultCatalog = catalog.NewBuilder() + +// SetString calls SetString on the initial default Catalog. +func SetString(tag language.Tag, key string, msg string) error { + return defaultCatalog.SetString(tag, key, msg) +} + +// Set calls Set on the initial default Catalog. +func Set(tag language.Tag, key string, msg ...catalog.Message) error { + return defaultCatalog.Set(tag, key, msg...) +} diff --git a/vendor/golang.org/x/text/message/catalog/catalog.go b/vendor/golang.org/x/text/message/catalog/catalog.go new file mode 100644 index 000000000..96955d075 --- /dev/null +++ b/vendor/golang.org/x/text/message/catalog/catalog.go @@ -0,0 +1,365 @@ +// 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 catalog defines collections of translated format strings. +// +// This package mostly defines types for populating catalogs with messages. The +// catmsg package contains further definitions for creating custom message and +// dictionary types as well as packages that use Catalogs. +// +// Package catalog defines various interfaces: Dictionary, Loader, and Message. +// A Dictionary maintains a set of translations of format strings for a single +// language. The Loader interface defines a source of dictionaries. A +// translation of a format string is represented by a Message. +// +// # Catalogs +// +// A Catalog defines a programmatic interface for setting message translations. +// It maintains a set of per-language dictionaries with translations for a set +// of keys. For message translation to function properly, a translation should +// be defined for each key for each supported language. A dictionary may be +// underspecified, though, if there is a parent language that already defines +// the key. For example, a Dictionary for "en-GB" could leave out entries that +// are identical to those in a dictionary for "en". +// +// # Messages +// +// A Message is a format string which varies on the value of substitution +// variables. For instance, to indicate the number of results one could want "no +// results" if there are none, "1 result" if there is 1, and "%d results" for +// any other number. Catalog is agnostic to the kind of format strings that are +// used: for instance, messages can follow either the printf-style substitution +// from package fmt or use templates. +// +// A Message does not substitute arguments in the format string. This job is +// reserved for packages that render strings, such as message, that use Catalogs +// to selected string. This separation of concerns allows Catalog to be used to +// store any kind of formatting strings. +// +// # Selecting messages based on linguistic features of substitution arguments +// +// Messages may vary based on any linguistic features of the argument values. +// The most common one is plural form, but others exist. +// +// Selection messages are provided in packages that provide support for a +// specific linguistic feature. The following snippet uses plural.Selectf: +// +// catalog.Set(language.English, "You are %d minute(s) late.", +// plural.Selectf(1, "", +// plural.One, "You are 1 minute late.", +// plural.Other, "You are %d minutes late.")) +// +// In this example, a message is stored in the Catalog where one of two messages +// is selected based on the first argument, a number. The first message is +// selected if the argument is singular (identified by the selector "one") and +// the second message is selected in all other cases. The selectors are defined +// by the plural rules defined in CLDR. The selector "other" is special and will +// always match. Each language always defines one of the linguistic categories +// to be "other." For English, singular is "one" and plural is "other". +// +// Selects can be nested. This allows selecting sentences based on features of +// multiple arguments or multiple linguistic properties of a single argument. +// +// # String interpolation +// +// There is often a lot of commonality between the possible variants of a +// message. For instance, in the example above the word "minute" varies based on +// the plural catogory of the argument, but the rest of the sentence is +// identical. Using interpolation the above message can be rewritten as: +// +// catalog.Set(language.English, "You are %d minute(s) late.", +// catalog.Var("minutes", +// plural.Selectf(1, "", plural.One, "minute", plural.Other, "minutes")), +// catalog.String("You are %[1]d ${minutes} late.")) +// +// Var is defined to return the variable name if the message does not yield a +// match. This allows us to further simplify this snippet to +// +// catalog.Set(language.English, "You are %d minute(s) late.", +// catalog.Var("minutes", plural.Selectf(1, "", plural.One, "minute")), +// catalog.String("You are %d ${minutes} late.")) +// +// Overall this is still only a minor improvement, but things can get a lot more +// unwieldy if more than one linguistic feature is used to determine a message +// variant. Consider the following example: +// +// // argument 1: list of hosts, argument 2: list of guests +// catalog.Set(language.English, "%[1]v invite(s) %[2]v to their party.", +// catalog.Var("their", +// plural.Selectf(1, "" +// plural.One, gender.Select(1, "female", "her", "other", "his"))), +// catalog.Var("invites", plural.Selectf(1, "", plural.One, "invite")) +// catalog.String("%[1]v ${invites} %[2]v to ${their} party.")), +// +// Without variable substitution, this would have to be written as +// +// // argument 1: list of hosts, argument 2: list of guests +// catalog.Set(language.English, "%[1]v invite(s) %[2]v to their party.", +// plural.Selectf(1, "", +// plural.One, gender.Select(1, +// "female", "%[1]v invites %[2]v to her party." +// "other", "%[1]v invites %[2]v to his party."), +// plural.Other, "%[1]v invites %[2]v to their party.")) +// +// Not necessarily shorter, but using variables there is less duplication and +// the messages are more maintenance friendly. Moreover, languages may have up +// to six plural forms. This makes the use of variables more welcome. +// +// Different messages using the same inflections can reuse variables by moving +// them to macros. Using macros we can rewrite the message as: +// +// // argument 1: list of hosts, argument 2: list of guests +// catalog.SetString(language.English, "%[1]v invite(s) %[2]v to their party.", +// "%[1]v ${invites(1)} %[2]v to ${their(1)} party.") +// +// Where the following macros were defined separately. +// +// catalog.SetMacro(language.English, "invites", plural.Selectf(1, "", +// plural.One, "invite")) +// catalog.SetMacro(language.English, "their", plural.Selectf(1, "", +// plural.One, gender.Select(1, "female", "her", "other", "his"))), +// +// Placeholders use parentheses and the arguments to invoke a macro. +// +// # Looking up messages +// +// Message lookup using Catalogs is typically only done by specialized packages +// and is not something the user should be concerned with. For instance, to +// express the tardiness of a user using the related message we defined earlier, +// the user may use the package message like so: +// +// p := message.NewPrinter(language.English) +// p.Printf("You are %d minute(s) late.", 5) +// +// Which would print: +// +// You are 5 minutes late. +// +// This package is UNDER CONSTRUCTION and its API may change. +package catalog // import "golang.org/x/text/message/catalog" + +// TODO: +// Some way to freeze a catalog. +// - Locking on each lockup turns out to be about 50% of the total running time +// for some of the benchmarks in the message package. +// Consider these: +// - Sequence type to support sequences in user-defined messages. +// - Garbage collection: Remove dictionaries that can no longer be reached +// as other dictionaries have been added that cover all possible keys. + +import ( + "errors" + "fmt" + + "golang.org/x/text/internal" + + "golang.org/x/text/internal/catmsg" + "golang.org/x/text/language" +) + +// A Catalog allows lookup of translated messages. +type Catalog interface { + // Languages returns all languages for which the Catalog contains variants. + Languages() []language.Tag + + // Matcher returns a Matcher for languages from this Catalog. + Matcher() language.Matcher + + // A Context is used for evaluating Messages. + Context(tag language.Tag, r catmsg.Renderer) *Context + + // This method also makes Catalog a private interface. + lookup(tag language.Tag, key string) (data string, ok bool) +} + +// NewFromMap creates a Catalog from the given map. If a Dictionary is +// underspecified the entry is retrieved from a parent language. +func NewFromMap(dictionaries map[string]Dictionary, opts ...Option) (Catalog, error) { + options := options{} + for _, o := range opts { + o(&options) + } + c := &catalog{ + dicts: map[language.Tag]Dictionary{}, + } + _, hasFallback := dictionaries[options.fallback.String()] + if hasFallback { + // TODO: Should it be okay to not have a fallback language? + // Catalog generators could enforce there is always a fallback. + c.langs = append(c.langs, options.fallback) + } + for lang, dict := range dictionaries { + tag, err := language.Parse(lang) + if err != nil { + return nil, fmt.Errorf("catalog: invalid language tag %q", lang) + } + if _, ok := c.dicts[tag]; ok { + return nil, fmt.Errorf("catalog: duplicate entry for tag %q after normalization", tag) + } + c.dicts[tag] = dict + if !hasFallback || tag != options.fallback { + c.langs = append(c.langs, tag) + } + } + if hasFallback { + internal.SortTags(c.langs[1:]) + } else { + internal.SortTags(c.langs) + } + c.matcher = language.NewMatcher(c.langs) + return c, nil +} + +// A Dictionary is a source of translations for a single language. +type Dictionary interface { + // Lookup returns a message compiled with catmsg.Compile for the given key. + // It returns false for ok if such a message could not be found. + Lookup(key string) (data string, ok bool) +} + +type catalog struct { + langs []language.Tag + dicts map[language.Tag]Dictionary + macros store + matcher language.Matcher +} + +func (c *catalog) Languages() []language.Tag { return c.langs } +func (c *catalog) Matcher() language.Matcher { return c.matcher } + +func (c *catalog) lookup(tag language.Tag, key string) (data string, ok bool) { + for ; ; tag = tag.Parent() { + if dict, ok := c.dicts[tag]; ok { + if data, ok := dict.Lookup(key); ok { + return data, true + } + } + if tag == language.Und { + break + } + } + return "", false +} + +// Context returns a Context for formatting messages. +// Only one Message may be formatted per context at any given time. +func (c *catalog) Context(tag language.Tag, r catmsg.Renderer) *Context { + return &Context{ + cat: c, + tag: tag, + dec: catmsg.NewDecoder(tag, r, &dict{&c.macros, tag}), + } +} + +// A Builder allows building a Catalog programmatically. +type Builder struct { + options + matcher language.Matcher + + index store + macros store +} + +type options struct { + fallback language.Tag +} + +// An Option configures Catalog behavior. +type Option func(*options) + +// Fallback specifies the default fallback language. The default is Und. +func Fallback(tag language.Tag) Option { + return func(o *options) { o.fallback = tag } +} + +// TODO: +// // Catalogs specifies one or more sources for a Catalog. +// // Lookups are in order. +// // This can be changed inserting a Catalog used for setting, which implements +// // Loader, used for setting in the chain. +// func Catalogs(d ...Loader) Option { +// return nil +// } +// +// func Delims(start, end string) Option {} +// +// func Dict(tag language.Tag, d ...Dictionary) Option + +// NewBuilder returns an empty mutable Catalog. +func NewBuilder(opts ...Option) *Builder { + c := &Builder{} + for _, o := range opts { + o(&c.options) + } + return c +} + +// SetString is shorthand for Set(tag, key, String(msg)). +func (c *Builder) SetString(tag language.Tag, key string, msg string) error { + return c.set(tag, key, &c.index, String(msg)) +} + +// Set sets the translation for the given language and key. +// +// When evaluation this message, the first Message in the sequence to msgs to +// evaluate to a string will be the message returned. +func (c *Builder) Set(tag language.Tag, key string, msg ...Message) error { + return c.set(tag, key, &c.index, msg...) +} + +// SetMacro defines a Message that may be substituted in another message. +// The arguments to a macro Message are passed as arguments in the +// placeholder the form "${foo(arg1, arg2)}". +func (c *Builder) SetMacro(tag language.Tag, name string, msg ...Message) error { + return c.set(tag, name, &c.macros, msg...) +} + +// ErrNotFound indicates there was no message for the given key. +var ErrNotFound = errors.New("catalog: message not found") + +// String specifies a plain message string. It can be used as fallback if no +// other strings match or as a simple standalone message. +// +// It is an error to pass more than one String in a message sequence. +func String(name string) Message { + return catmsg.String(name) +} + +// Var sets a variable that may be substituted in formatting patterns using +// named substitution of the form "${name}". The name argument is used as a +// fallback if the statements do not produce a match. The statement sequence may +// not contain any Var calls. +// +// The name passed to a Var must be unique within message sequence. +func Var(name string, msg ...Message) Message { + return &catmsg.Var{Name: name, Message: firstInSequence(msg)} +} + +// Context returns a Context for formatting messages. +// Only one Message may be formatted per context at any given time. +func (b *Builder) Context(tag language.Tag, r catmsg.Renderer) *Context { + return &Context{ + cat: b, + tag: tag, + dec: catmsg.NewDecoder(tag, r, &dict{&b.macros, tag}), + } +} + +// A Context is used for evaluating Messages. +// Only one Message may be formatted per context at any given time. +type Context struct { + cat Catalog + tag language.Tag // TODO: use compact index. + dec *catmsg.Decoder +} + +// Execute looks up and executes the message with the given key. +// It returns ErrNotFound if no message could be found in the index. +func (c *Context) Execute(key string) error { + data, ok := c.cat.lookup(c.tag, key) + if !ok { + return ErrNotFound + } + return c.dec.Execute(data) +} diff --git a/vendor/golang.org/x/text/message/catalog/dict.go b/vendor/golang.org/x/text/message/catalog/dict.go new file mode 100644 index 000000000..a0eb81810 --- /dev/null +++ b/vendor/golang.org/x/text/message/catalog/dict.go @@ -0,0 +1,129 @@ +// 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 catalog + +import ( + "sync" + + "golang.org/x/text/internal" + "golang.org/x/text/internal/catmsg" + "golang.org/x/text/language" +) + +// TODO: +// Dictionary returns a Dictionary that returns the first Message, using the +// given language tag, that matches: +// 1. the last one registered by one of the Set methods +// 2. returned by one of the Loaders +// 3. repeat from 1. using the parent language +// This approach allows messages to be underspecified. +// func (c *Catalog) Dictionary(tag language.Tag) (Dictionary, error) { +// // TODO: verify dictionary exists. +// return &dict{&c.index, tag}, nil +// } + +type dict struct { + s *store + tag language.Tag // TODO: make compact tag. +} + +func (d *dict) Lookup(key string) (data string, ok bool) { + return d.s.lookup(d.tag, key) +} + +func (b *Builder) lookup(tag language.Tag, key string) (data string, ok bool) { + return b.index.lookup(tag, key) +} + +func (c *Builder) set(tag language.Tag, key string, s *store, msg ...Message) error { + data, err := catmsg.Compile(tag, &dict{&c.macros, tag}, firstInSequence(msg)) + + s.mutex.Lock() + defer s.mutex.Unlock() + + m := s.index[tag] + if m == nil { + m = msgMap{} + if s.index == nil { + s.index = map[language.Tag]msgMap{} + } + c.matcher = nil + s.index[tag] = m + } + + m[key] = data + return err +} + +func (c *Builder) Matcher() language.Matcher { + c.index.mutex.RLock() + m := c.matcher + c.index.mutex.RUnlock() + if m != nil { + return m + } + + c.index.mutex.Lock() + if c.matcher == nil { + c.matcher = language.NewMatcher(c.unlockedLanguages()) + } + m = c.matcher + c.index.mutex.Unlock() + return m +} + +type store struct { + mutex sync.RWMutex + index map[language.Tag]msgMap +} + +type msgMap map[string]string + +func (s *store) lookup(tag language.Tag, key string) (data string, ok bool) { + s.mutex.RLock() + defer s.mutex.RUnlock() + + for ; ; tag = tag.Parent() { + if msgs, ok := s.index[tag]; ok { + if msg, ok := msgs[key]; ok { + return msg, true + } + } + if tag == language.Und { + break + } + } + return "", false +} + +// Languages returns all languages for which the Catalog contains variants. +func (b *Builder) Languages() []language.Tag { + s := &b.index + s.mutex.RLock() + defer s.mutex.RUnlock() + + return b.unlockedLanguages() +} + +func (b *Builder) unlockedLanguages() []language.Tag { + s := &b.index + if len(s.index) == 0 { + return nil + } + tags := make([]language.Tag, 0, len(s.index)) + _, hasFallback := s.index[b.options.fallback] + offset := 0 + if hasFallback { + tags = append(tags, b.options.fallback) + offset = 1 + } + for t := range s.index { + if t != b.options.fallback { + tags = append(tags, t) + } + } + internal.SortTags(tags[offset:]) + return tags +} diff --git a/vendor/golang.org/x/text/message/catalog/go19.go b/vendor/golang.org/x/text/message/catalog/go19.go new file mode 100644 index 000000000..291a4df94 --- /dev/null +++ b/vendor/golang.org/x/text/message/catalog/go19.go @@ -0,0 +1,15 @@ +// 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:build go1.9 + +package catalog + +import "golang.org/x/text/internal/catmsg" + +// A Message holds a collection of translations for the same phrase that may +// vary based on the values of substitution arguments. +type Message = catmsg.Message + +type firstInSequence = catmsg.FirstOf diff --git a/vendor/golang.org/x/text/message/catalog/gopre19.go b/vendor/golang.org/x/text/message/catalog/gopre19.go new file mode 100644 index 000000000..da44ebb8b --- /dev/null +++ b/vendor/golang.org/x/text/message/catalog/gopre19.go @@ -0,0 +1,23 @@ +// 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:build !go1.9 + +package catalog + +import "golang.org/x/text/internal/catmsg" + +// A Message holds a collection of translations for the same phrase that may +// vary based on the values of substitution arguments. +type Message interface { + catmsg.Message +} + +func firstInSequence(m []Message) catmsg.Message { + a := []catmsg.Message{} + for _, m := range m { + a = append(a, m) + } + return catmsg.FirstOf(a) +} diff --git a/vendor/golang.org/x/text/message/doc.go b/vendor/golang.org/x/text/message/doc.go new file mode 100644 index 000000000..4bf7bdcac --- /dev/null +++ b/vendor/golang.org/x/text/message/doc.go @@ -0,0 +1,99 @@ +// 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 message implements formatted I/O for localized strings with functions +// analogous to the fmt's print functions. It is a drop-in replacement for fmt. +// +// # Localized Formatting +// +// A format string can be localized by replacing any of the print functions of +// fmt with an equivalent call to a Printer. +// +// p := message.NewPrinter(message.MatchLanguage("en")) +// p.Println(123456.78) // Prints 123,456.78 +// +// p.Printf("%d ducks in a row", 4331) // Prints 4,331 ducks in a row +// +// p := message.NewPrinter(message.MatchLanguage("nl")) +// p.Printf("Hoogte: %.1f meter", 1244.9) // Prints Hoogte: 1,244.9 meter +// +// p := message.NewPrinter(message.MatchLanguage("bn")) +// p.Println(123456.78) // Prints ১,২৩,৪৫৬.৭৮ +// +// Printer currently supports numbers and specialized types for which packages +// exist in x/text. Other builtin types such as time.Time and slices are +// planned. +// +// Format strings largely have the same meaning as with fmt with the following +// notable exceptions: +// - flag # always resorts to fmt for printing +// - verb 'f', 'e', 'g', 'd' use localized formatting unless the '#' flag is +// specified. +// - verb 'm' inserts a translation of a string argument. +// +// See package fmt for more options. +// +// # Translation +// +// The format strings that are passed to Printf, Sprintf, Fprintf, or Errorf +// are used as keys to look up translations for the specified languages. +// More on how these need to be specified below. +// +// One can use arbitrary keys to distinguish between otherwise ambiguous +// strings: +// +// p := message.NewPrinter(language.English) +// p.Printf("archive(noun)") // Prints "archive" +// p.Printf("archive(verb)") // Prints "archive" +// +// p := message.NewPrinter(language.German) +// p.Printf("archive(noun)") // Prints "Archiv" +// p.Printf("archive(verb)") // Prints "archivieren" +// +// To retain the fallback functionality, use Key: +// +// p.Printf(message.Key("archive(noun)", "archive")) +// p.Printf(message.Key("archive(verb)", "archive")) +// +// # Translation Pipeline +// +// Format strings that contain text need to be translated to support different +// locales. The first step is to extract strings that need to be translated. +// +// 1. Install gotext +// +// go get -u golang.org/x/text/cmd/gotext +// gotext -help +// +// 2. Mark strings in your source to be translated by using message.Printer, +// instead of the functions of the fmt package. +// +// 3. Extract the strings from your source +// +// gotext extract +// +// The output will be written to the textdata directory. +// +// 4. Send the files for translation +// +// It is planned to support multiple formats, but for now one will have to +// rewrite the JSON output to the desired format. +// +// 5. Inject translations into program +// +// 6. Repeat from 2 +// +// Right now this has to be done programmatically with calls to Set or +// SetString. These functions as well as the methods defined in +// see also package golang.org/x/text/message/catalog can be used to implement +// either dynamic or static loading of messages. +// +// # Plural and Gender Forms +// +// Translated messages can vary based on the plural and gender forms of +// substitution values. In general, it is up to the translators to provide +// alternative translations for such forms. See the packages in +// golang.org/x/text/feature and golang.org/x/text/message/catalog for more +// information. +package message diff --git a/vendor/golang.org/x/text/message/format.go b/vendor/golang.org/x/text/message/format.go new file mode 100644 index 000000000..a47d17dd4 --- /dev/null +++ b/vendor/golang.org/x/text/message/format.go @@ -0,0 +1,510 @@ +// 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 message + +import ( + "bytes" + "strconv" + "unicode/utf8" + + "golang.org/x/text/internal/format" +) + +const ( + ldigits = "0123456789abcdefx" + udigits = "0123456789ABCDEFX" +) + +const ( + signed = true + unsigned = false +) + +// A formatInfo is the raw formatter used by Printf etc. +// It prints into a buffer that must be set up separately. +type formatInfo struct { + buf *bytes.Buffer + + format.Parser + + // intbuf is large enough to store %b of an int64 with a sign and + // avoids padding at the end of the struct on 32 bit architectures. + intbuf [68]byte +} + +func (f *formatInfo) init(buf *bytes.Buffer) { + f.ClearFlags() + f.buf = buf +} + +// writePadding generates n bytes of padding. +func (f *formatInfo) writePadding(n int) { + if n <= 0 { // No padding bytes needed. + return + } + f.buf.Grow(n) + // Decide which byte the padding should be filled with. + padByte := byte(' ') + if f.Zero { + padByte = byte('0') + } + // Fill padding with padByte. + for i := 0; i < n; i++ { + f.buf.WriteByte(padByte) // TODO: make more efficient. + } +} + +// pad appends b to f.buf, padded on left (!f.minus) or right (f.minus). +func (f *formatInfo) pad(b []byte) { + if !f.WidthPresent || f.Width == 0 { + f.buf.Write(b) + return + } + width := f.Width - utf8.RuneCount(b) + if !f.Minus { + // left padding + f.writePadding(width) + f.buf.Write(b) + } else { + // right padding + f.buf.Write(b) + f.writePadding(width) + } +} + +// padString appends s to f.buf, padded on left (!f.minus) or right (f.minus). +func (f *formatInfo) padString(s string) { + if !f.WidthPresent || f.Width == 0 { + f.buf.WriteString(s) + return + } + width := f.Width - utf8.RuneCountInString(s) + if !f.Minus { + // left padding + f.writePadding(width) + f.buf.WriteString(s) + } else { + // right padding + f.buf.WriteString(s) + f.writePadding(width) + } +} + +// fmt_boolean formats a boolean. +func (f *formatInfo) fmt_boolean(v bool) { + if v { + f.padString("true") + } else { + f.padString("false") + } +} + +// fmt_unicode formats a uint64 as "U+0078" or with f.sharp set as "U+0078 'x'". +func (f *formatInfo) fmt_unicode(u uint64) { + buf := f.intbuf[0:] + + // With default precision set the maximum needed buf length is 18 + // for formatting -1 with %#U ("U+FFFFFFFFFFFFFFFF") which fits + // into the already allocated intbuf with a capacity of 68 bytes. + prec := 4 + if f.PrecPresent && f.Prec > 4 { + prec = f.Prec + // Compute space needed for "U+" , number, " '", character, "'". + width := 2 + prec + 2 + utf8.UTFMax + 1 + if width > len(buf) { + buf = make([]byte, width) + } + } + + // Format into buf, ending at buf[i]. Formatting numbers is easier right-to-left. + i := len(buf) + + // For %#U we want to add a space and a quoted character at the end of the buffer. + if f.Sharp && u <= utf8.MaxRune && strconv.IsPrint(rune(u)) { + i-- + buf[i] = '\'' + i -= utf8.RuneLen(rune(u)) + utf8.EncodeRune(buf[i:], rune(u)) + i-- + buf[i] = '\'' + i-- + buf[i] = ' ' + } + // Format the Unicode code point u as a hexadecimal number. + for u >= 16 { + i-- + buf[i] = udigits[u&0xF] + prec-- + u >>= 4 + } + i-- + buf[i] = udigits[u] + prec-- + // Add zeros in front of the number until requested precision is reached. + for prec > 0 { + i-- + buf[i] = '0' + prec-- + } + // Add a leading "U+". + i-- + buf[i] = '+' + i-- + buf[i] = 'U' + + oldZero := f.Zero + f.Zero = false + f.pad(buf[i:]) + f.Zero = oldZero +} + +// fmt_integer formats signed and unsigned integers. +func (f *formatInfo) fmt_integer(u uint64, base int, isSigned bool, digits string) { + negative := isSigned && int64(u) < 0 + if negative { + u = -u + } + + buf := f.intbuf[0:] + // The already allocated f.intbuf with a capacity of 68 bytes + // is large enough for integer formatting when no precision or width is set. + if f.WidthPresent || f.PrecPresent { + // Account 3 extra bytes for possible addition of a sign and "0x". + width := 3 + f.Width + f.Prec // wid and prec are always positive. + if width > len(buf) { + // We're going to need a bigger boat. + buf = make([]byte, width) + } + } + + // Two ways to ask for extra leading zero digits: %.3d or %03d. + // If both are specified the f.zero flag is ignored and + // padding with spaces is used instead. + prec := 0 + if f.PrecPresent { + prec = f.Prec + // Precision of 0 and value of 0 means "print nothing" but padding. + if prec == 0 && u == 0 { + oldZero := f.Zero + f.Zero = false + f.writePadding(f.Width) + f.Zero = oldZero + return + } + } else if f.Zero && f.WidthPresent { + prec = f.Width + if negative || f.Plus || f.Space { + prec-- // leave room for sign + } + } + + // Because printing is easier right-to-left: format u into buf, ending at buf[i]. + // We could make things marginally faster by splitting the 32-bit case out + // into a separate block but it's not worth the duplication, so u has 64 bits. + i := len(buf) + // Use constants for the division and modulo for more efficient code. + // Switch cases ordered by popularity. + switch base { + case 10: + for u >= 10 { + i-- + next := u / 10 + buf[i] = byte('0' + u - next*10) + u = next + } + case 16: + for u >= 16 { + i-- + buf[i] = digits[u&0xF] + u >>= 4 + } + case 8: + for u >= 8 { + i-- + buf[i] = byte('0' + u&7) + u >>= 3 + } + case 2: + for u >= 2 { + i-- + buf[i] = byte('0' + u&1) + u >>= 1 + } + default: + panic("fmt: unknown base; can't happen") + } + i-- + buf[i] = digits[u] + for i > 0 && prec > len(buf)-i { + i-- + buf[i] = '0' + } + + // Various prefixes: 0x, -, etc. + if f.Sharp { + switch base { + case 8: + if buf[i] != '0' { + i-- + buf[i] = '0' + } + case 16: + // Add a leading 0x or 0X. + i-- + buf[i] = digits[16] + i-- + buf[i] = '0' + } + } + + if negative { + i-- + buf[i] = '-' + } else if f.Plus { + i-- + buf[i] = '+' + } else if f.Space { + i-- + buf[i] = ' ' + } + + // Left padding with zeros has already been handled like precision earlier + // or the f.zero flag is ignored due to an explicitly set precision. + oldZero := f.Zero + f.Zero = false + f.pad(buf[i:]) + f.Zero = oldZero +} + +// truncate truncates the string to the specified precision, if present. +func (f *formatInfo) truncate(s string) string { + if f.PrecPresent { + n := f.Prec + for i := range s { + n-- + if n < 0 { + return s[:i] + } + } + } + return s +} + +// fmt_s formats a string. +func (f *formatInfo) fmt_s(s string) { + s = f.truncate(s) + f.padString(s) +} + +// fmt_sbx formats a string or byte slice as a hexadecimal encoding of its bytes. +func (f *formatInfo) fmt_sbx(s string, b []byte, digits string) { + length := len(b) + if b == nil { + // No byte slice present. Assume string s should be encoded. + length = len(s) + } + // Set length to not process more bytes than the precision demands. + if f.PrecPresent && f.Prec < length { + length = f.Prec + } + // Compute width of the encoding taking into account the f.sharp and f.space flag. + width := 2 * length + if width > 0 { + if f.Space { + // Each element encoded by two hexadecimals will get a leading 0x or 0X. + if f.Sharp { + width *= 2 + } + // Elements will be separated by a space. + width += length - 1 + } else if f.Sharp { + // Only a leading 0x or 0X will be added for the whole string. + width += 2 + } + } else { // The byte slice or string that should be encoded is empty. + if f.WidthPresent { + f.writePadding(f.Width) + } + return + } + // Handle padding to the left. + if f.WidthPresent && f.Width > width && !f.Minus { + f.writePadding(f.Width - width) + } + // Write the encoding directly into the output buffer. + buf := f.buf + if f.Sharp { + // Add leading 0x or 0X. + buf.WriteByte('0') + buf.WriteByte(digits[16]) + } + var c byte + for i := 0; i < length; i++ { + if f.Space && i > 0 { + // Separate elements with a space. + buf.WriteByte(' ') + if f.Sharp { + // Add leading 0x or 0X for each element. + buf.WriteByte('0') + buf.WriteByte(digits[16]) + } + } + if b != nil { + c = b[i] // Take a byte from the input byte slice. + } else { + c = s[i] // Take a byte from the input string. + } + // Encode each byte as two hexadecimal digits. + buf.WriteByte(digits[c>>4]) + buf.WriteByte(digits[c&0xF]) + } + // Handle padding to the right. + if f.WidthPresent && f.Width > width && f.Minus { + f.writePadding(f.Width - width) + } +} + +// fmt_sx formats a string as a hexadecimal encoding of its bytes. +func (f *formatInfo) fmt_sx(s, digits string) { + f.fmt_sbx(s, nil, digits) +} + +// fmt_bx formats a byte slice as a hexadecimal encoding of its bytes. +func (f *formatInfo) fmt_bx(b []byte, digits string) { + f.fmt_sbx("", b, digits) +} + +// fmt_q formats a string as a double-quoted, escaped Go string constant. +// If f.sharp is set a raw (backquoted) string may be returned instead +// if the string does not contain any control characters other than tab. +func (f *formatInfo) fmt_q(s string) { + s = f.truncate(s) + if f.Sharp && strconv.CanBackquote(s) { + f.padString("`" + s + "`") + return + } + buf := f.intbuf[:0] + if f.Plus { + f.pad(strconv.AppendQuoteToASCII(buf, s)) + } else { + f.pad(strconv.AppendQuote(buf, s)) + } +} + +// fmt_c formats an integer as a Unicode character. +// If the character is not valid Unicode, it will print '\ufffd'. +func (f *formatInfo) fmt_c(c uint64) { + r := rune(c) + if c > utf8.MaxRune { + r = utf8.RuneError + } + buf := f.intbuf[:0] + w := utf8.EncodeRune(buf[:utf8.UTFMax], r) + f.pad(buf[:w]) +} + +// fmt_qc formats an integer as a single-quoted, escaped Go character constant. +// If the character is not valid Unicode, it will print '\ufffd'. +func (f *formatInfo) fmt_qc(c uint64) { + r := rune(c) + if c > utf8.MaxRune { + r = utf8.RuneError + } + buf := f.intbuf[:0] + if f.Plus { + f.pad(strconv.AppendQuoteRuneToASCII(buf, r)) + } else { + f.pad(strconv.AppendQuoteRune(buf, r)) + } +} + +// fmt_float formats a float64. It assumes that verb is a valid format specifier +// for strconv.AppendFloat and therefore fits into a byte. +func (f *formatInfo) fmt_float(v float64, size int, verb rune, prec int) { + // Explicit precision in format specifier overrules default precision. + if f.PrecPresent { + prec = f.Prec + } + // Format number, reserving space for leading + sign if needed. + num := strconv.AppendFloat(f.intbuf[:1], v, byte(verb), prec, size) + if num[1] == '-' || num[1] == '+' { + num = num[1:] + } else { + num[0] = '+' + } + // f.space means to add a leading space instead of a "+" sign unless + // the sign is explicitly asked for by f.plus. + if f.Space && num[0] == '+' && !f.Plus { + num[0] = ' ' + } + // Special handling for infinities and NaN, + // which don't look like a number so shouldn't be padded with zeros. + if num[1] == 'I' || num[1] == 'N' { + oldZero := f.Zero + f.Zero = false + // Remove sign before NaN if not asked for. + if num[1] == 'N' && !f.Space && !f.Plus { + num = num[1:] + } + f.pad(num) + f.Zero = oldZero + return + } + // The sharp flag forces printing a decimal point for non-binary formats + // and retains trailing zeros, which we may need to restore. + if f.Sharp && verb != 'b' { + digits := 0 + switch verb { + case 'v', 'g', 'G': + digits = prec + // If no precision is set explicitly use a precision of 6. + if digits == -1 { + digits = 6 + } + } + + // Buffer pre-allocated with enough room for + // exponent notations of the form "e+123". + var tailBuf [5]byte + tail := tailBuf[:0] + + hasDecimalPoint := false + // Starting from i = 1 to skip sign at num[0]. + for i := 1; i < len(num); i++ { + switch num[i] { + case '.': + hasDecimalPoint = true + case 'e', 'E': + tail = append(tail, num[i:]...) + num = num[:i] + default: + digits-- + } + } + if !hasDecimalPoint { + num = append(num, '.') + } + for digits > 0 { + num = append(num, '0') + digits-- + } + num = append(num, tail...) + } + // We want a sign if asked for and if the sign is not positive. + if f.Plus || num[0] != '+' { + // If we're zero padding to the left we want the sign before the leading zeros. + // Achieve this by writing the sign out and then padding the unsigned number. + if f.Zero && f.WidthPresent && f.Width > len(num) { + f.buf.WriteByte(num[0]) + f.writePadding(f.Width - len(num)) + f.buf.Write(num[1:]) + return + } + f.pad(num) + return + } + // No sign to show and the number is positive; just print the unsigned number. + f.pad(num[1:]) +} diff --git a/vendor/golang.org/x/text/message/message.go b/vendor/golang.org/x/text/message/message.go new file mode 100644 index 000000000..91a972642 --- /dev/null +++ b/vendor/golang.org/x/text/message/message.go @@ -0,0 +1,192 @@ +// 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 message // import "golang.org/x/text/message" + +import ( + "io" + "os" + + // Include features to facilitate generated catalogs. + _ "golang.org/x/text/feature/plural" + + "golang.org/x/text/internal/number" + "golang.org/x/text/language" + "golang.org/x/text/message/catalog" +) + +// A Printer implements language-specific formatted I/O analogous to the fmt +// package. +type Printer struct { + // the language + tag language.Tag + + toDecimal number.Formatter + toScientific number.Formatter + + cat catalog.Catalog +} + +type options struct { + cat catalog.Catalog + // TODO: + // - allow %s to print integers in written form (tables are likely too large + // to enable this by default). + // - list behavior + // +} + +// An Option defines an option of a Printer. +type Option func(o *options) + +// Catalog defines the catalog to be used. +func Catalog(c catalog.Catalog) Option { + return func(o *options) { o.cat = c } +} + +// NewPrinter returns a Printer that formats messages tailored to language t. +func NewPrinter(t language.Tag, opts ...Option) *Printer { + options := &options{ + cat: DefaultCatalog, + } + for _, o := range opts { + o(options) + } + p := &Printer{ + tag: t, + cat: options.cat, + } + p.toDecimal.InitDecimal(t) + p.toScientific.InitScientific(t) + return p +} + +// Sprint is like fmt.Sprint, but using language-specific formatting. +func (p *Printer) Sprint(a ...interface{}) string { + pp := newPrinter(p) + pp.doPrint(a) + s := pp.String() + pp.free() + return s +} + +// Fprint is like fmt.Fprint, but using language-specific formatting. +func (p *Printer) Fprint(w io.Writer, a ...interface{}) (n int, err error) { + pp := newPrinter(p) + pp.doPrint(a) + n64, err := io.Copy(w, &pp.Buffer) + pp.free() + return int(n64), err +} + +// Print is like fmt.Print, but using language-specific formatting. +func (p *Printer) Print(a ...interface{}) (n int, err error) { + return p.Fprint(os.Stdout, a...) +} + +// Sprintln is like fmt.Sprintln, but using language-specific formatting. +func (p *Printer) Sprintln(a ...interface{}) string { + pp := newPrinter(p) + pp.doPrintln(a) + s := pp.String() + pp.free() + return s +} + +// Fprintln is like fmt.Fprintln, but using language-specific formatting. +func (p *Printer) Fprintln(w io.Writer, a ...interface{}) (n int, err error) { + pp := newPrinter(p) + pp.doPrintln(a) + n64, err := io.Copy(w, &pp.Buffer) + pp.free() + return int(n64), err +} + +// Println is like fmt.Println, but using language-specific formatting. +func (p *Printer) Println(a ...interface{}) (n int, err error) { + return p.Fprintln(os.Stdout, a...) +} + +// Sprintf is like fmt.Sprintf, but using language-specific formatting. +func (p *Printer) Sprintf(key Reference, a ...interface{}) string { + pp := newPrinter(p) + lookupAndFormat(pp, key, a) + s := pp.String() + pp.free() + return s +} + +// Fprintf is like fmt.Fprintf, but using language-specific formatting. +func (p *Printer) Fprintf(w io.Writer, key Reference, a ...interface{}) (n int, err error) { + pp := newPrinter(p) + lookupAndFormat(pp, key, a) + n, err = w.Write(pp.Bytes()) + pp.free() + return n, err + +} + +// Printf is like fmt.Printf, but using language-specific formatting. +func (p *Printer) Printf(key Reference, a ...interface{}) (n int, err error) { + pp := newPrinter(p) + lookupAndFormat(pp, key, a) + n, err = os.Stdout.Write(pp.Bytes()) + pp.free() + return n, err +} + +func lookupAndFormat(p *printer, r Reference, a []interface{}) { + p.fmt.Reset(a) + switch v := r.(type) { + case string: + if p.catContext.Execute(v) == catalog.ErrNotFound { + p.Render(v) + return + } + case key: + if p.catContext.Execute(v.id) == catalog.ErrNotFound && + p.catContext.Execute(v.fallback) == catalog.ErrNotFound { + p.Render(v.fallback) + return + } + default: + panic("key argument is not a Reference") + } +} + +type rawPrinter struct { + p *printer +} + +func (p rawPrinter) Render(msg string) { p.p.WriteString(msg) } +func (p rawPrinter) Arg(i int) interface{} { return nil } + +// Arg implements catmsg.Renderer. +func (p *printer) Arg(i int) interface{} { // TODO, also return "ok" bool + i-- + if uint(i) < uint(len(p.fmt.Args)) { + return p.fmt.Args[i] + } + return nil +} + +// Render implements catmsg.Renderer. +func (p *printer) Render(msg string) { + p.doPrintf(msg) +} + +// A Reference is a string or a message reference. +type Reference interface { + // TODO: also allow []string +} + +// Key creates a message Reference for a message where the given id is used for +// message lookup and the fallback is returned when no matches are found. +func Key(id string, fallback string) Reference { + return key{id, fallback} +} + +type key struct { + id, fallback string +} diff --git a/vendor/golang.org/x/text/message/print.go b/vendor/golang.org/x/text/message/print.go new file mode 100644 index 000000000..da304cc0e --- /dev/null +++ b/vendor/golang.org/x/text/message/print.go @@ -0,0 +1,984 @@ +// 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 message + +import ( + "bytes" + "fmt" // TODO: consider copying interfaces from package fmt to avoid dependency. + "math" + "reflect" + "sync" + "unicode/utf8" + + "golang.org/x/text/internal/format" + "golang.org/x/text/internal/number" + "golang.org/x/text/language" + "golang.org/x/text/message/catalog" +) + +// Strings for use with buffer.WriteString. +// This is less overhead than using buffer.Write with byte arrays. +const ( + commaSpaceString = ", " + nilAngleString = "" + nilParenString = "(nil)" + nilString = "nil" + mapString = "map[" + percentBangString = "%!" + missingString = "(MISSING)" + badIndexString = "(BADINDEX)" + panicString = "(PANIC=" + extraString = "%!(EXTRA " + badWidthString = "%!(BADWIDTH)" + badPrecString = "%!(BADPREC)" + noVerbString = "%!(NOVERB)" + + invReflectString = "" +) + +var printerPool = sync.Pool{ + New: func() interface{} { return new(printer) }, +} + +// newPrinter allocates a new printer struct or grabs a cached one. +func newPrinter(pp *Printer) *printer { + p := printerPool.Get().(*printer) + p.Printer = *pp + // TODO: cache most of the following call. + p.catContext = pp.cat.Context(pp.tag, p) + + p.panicking = false + p.erroring = false + p.fmt.init(&p.Buffer) + return p +} + +// free saves used printer structs in printerFree; avoids an allocation per invocation. +func (p *printer) free() { + p.Buffer.Reset() + p.arg = nil + p.value = reflect.Value{} + printerPool.Put(p) +} + +// printer is used to store a printer's state. +// It implements "golang.org/x/text/internal/format".State. +type printer struct { + Printer + + // the context for looking up message translations + catContext *catalog.Context + + // buffer for accumulating output. + bytes.Buffer + + // arg holds the current item, as an interface{}. + arg interface{} + // value is used instead of arg for reflect values. + value reflect.Value + + // fmt is used to format basic items such as integers or strings. + fmt formatInfo + + // panicking is set by catchPanic to avoid infinite panic, recover, panic, ... recursion. + panicking bool + // erroring is set when printing an error string to guard against calling handleMethods. + erroring bool +} + +// Language implements "golang.org/x/text/internal/format".State. +func (p *printer) Language() language.Tag { return p.tag } + +func (p *printer) Width() (wid int, ok bool) { return p.fmt.Width, p.fmt.WidthPresent } + +func (p *printer) Precision() (prec int, ok bool) { return p.fmt.Prec, p.fmt.PrecPresent } + +func (p *printer) Flag(b int) bool { + switch b { + case '-': + return p.fmt.Minus + case '+': + return p.fmt.Plus || p.fmt.PlusV + case '#': + return p.fmt.Sharp || p.fmt.SharpV + case ' ': + return p.fmt.Space + case '0': + return p.fmt.Zero + } + return false +} + +// getField gets the i'th field of the struct value. +// If the field is itself is an interface, return a value for +// the thing inside the interface, not the interface itself. +func getField(v reflect.Value, i int) reflect.Value { + val := v.Field(i) + if val.Kind() == reflect.Interface && !val.IsNil() { + val = val.Elem() + } + return val +} + +func (p *printer) unknownType(v reflect.Value) { + if !v.IsValid() { + p.WriteString(nilAngleString) + return + } + p.WriteByte('?') + p.WriteString(v.Type().String()) + p.WriteByte('?') +} + +func (p *printer) badVerb(verb rune) { + p.erroring = true + p.WriteString(percentBangString) + p.WriteRune(verb) + p.WriteByte('(') + switch { + case p.arg != nil: + p.WriteString(reflect.TypeOf(p.arg).String()) + p.WriteByte('=') + p.printArg(p.arg, 'v') + case p.value.IsValid(): + p.WriteString(p.value.Type().String()) + p.WriteByte('=') + p.printValue(p.value, 'v', 0) + default: + p.WriteString(nilAngleString) + } + p.WriteByte(')') + p.erroring = false +} + +func (p *printer) fmtBool(v bool, verb rune) { + switch verb { + case 't', 'v': + p.fmt.fmt_boolean(v) + default: + p.badVerb(verb) + } +} + +// fmt0x64 formats a uint64 in hexadecimal and prefixes it with 0x or +// not, as requested, by temporarily setting the sharp flag. +func (p *printer) fmt0x64(v uint64, leading0x bool) { + sharp := p.fmt.Sharp + p.fmt.Sharp = leading0x + p.fmt.fmt_integer(v, 16, unsigned, ldigits) + p.fmt.Sharp = sharp +} + +// fmtInteger formats a signed or unsigned integer. +func (p *printer) fmtInteger(v uint64, isSigned bool, verb rune) { + switch verb { + case 'v': + if p.fmt.SharpV && !isSigned { + p.fmt0x64(v, true) + return + } + fallthrough + case 'd': + if p.fmt.Sharp || p.fmt.SharpV { + p.fmt.fmt_integer(v, 10, isSigned, ldigits) + } else { + p.fmtDecimalInt(v, isSigned) + } + case 'b': + p.fmt.fmt_integer(v, 2, isSigned, ldigits) + case 'o': + p.fmt.fmt_integer(v, 8, isSigned, ldigits) + case 'x': + p.fmt.fmt_integer(v, 16, isSigned, ldigits) + case 'X': + p.fmt.fmt_integer(v, 16, isSigned, udigits) + case 'c': + p.fmt.fmt_c(v) + case 'q': + if v <= utf8.MaxRune { + p.fmt.fmt_qc(v) + } else { + p.badVerb(verb) + } + case 'U': + p.fmt.fmt_unicode(v) + default: + p.badVerb(verb) + } +} + +// fmtFloat formats a float. The default precision for each verb +// is specified as last argument in the call to fmt_float. +func (p *printer) fmtFloat(v float64, size int, verb rune) { + switch verb { + case 'b': + p.fmt.fmt_float(v, size, verb, -1) + case 'v': + verb = 'g' + fallthrough + case 'g', 'G': + if p.fmt.Sharp || p.fmt.SharpV { + p.fmt.fmt_float(v, size, verb, -1) + } else { + p.fmtVariableFloat(v, size) + } + case 'e', 'E': + if p.fmt.Sharp || p.fmt.SharpV { + p.fmt.fmt_float(v, size, verb, 6) + } else { + p.fmtScientific(v, size, 6) + } + case 'f', 'F': + if p.fmt.Sharp || p.fmt.SharpV { + p.fmt.fmt_float(v, size, verb, 6) + } else { + p.fmtDecimalFloat(v, size, 6) + } + default: + p.badVerb(verb) + } +} + +func (p *printer) setFlags(f *number.Formatter) { + f.Flags &^= number.ElideSign + if p.fmt.Plus || p.fmt.Space { + f.Flags |= number.AlwaysSign + if !p.fmt.Plus { + f.Flags |= number.ElideSign + } + } else { + f.Flags &^= number.AlwaysSign + } +} + +func (p *printer) updatePadding(f *number.Formatter) { + f.Flags &^= number.PadMask + if p.fmt.Minus { + f.Flags |= number.PadAfterSuffix + } else { + f.Flags |= number.PadBeforePrefix + } + f.PadRune = ' ' + f.FormatWidth = uint16(p.fmt.Width) +} + +func (p *printer) initDecimal(minFrac, maxFrac int) { + f := &p.toDecimal + f.MinIntegerDigits = 1 + f.MaxIntegerDigits = 0 + f.MinFractionDigits = uint8(minFrac) + f.MaxFractionDigits = int16(maxFrac) + p.setFlags(f) + f.PadRune = 0 + if p.fmt.WidthPresent { + if p.fmt.Zero { + wid := p.fmt.Width + // Use significant integers for this. + // TODO: this is not the same as width, but so be it. + if f.MinFractionDigits > 0 { + wid -= 1 + int(f.MinFractionDigits) + } + if p.fmt.Plus || p.fmt.Space { + wid-- + } + if wid > 0 && wid > int(f.MinIntegerDigits) { + f.MinIntegerDigits = uint8(wid) + } + } + p.updatePadding(f) + } +} + +func (p *printer) initScientific(minFrac, maxFrac int) { + f := &p.toScientific + if maxFrac < 0 { + f.SetPrecision(maxFrac) + } else { + f.SetPrecision(maxFrac + 1) + f.MinFractionDigits = uint8(minFrac) + f.MaxFractionDigits = int16(maxFrac) + } + f.MinExponentDigits = 2 + p.setFlags(f) + f.PadRune = 0 + if p.fmt.WidthPresent { + f.Flags &^= number.PadMask + if p.fmt.Zero { + f.PadRune = f.Digit(0) + f.Flags |= number.PadAfterPrefix + } else { + f.PadRune = ' ' + f.Flags |= number.PadBeforePrefix + } + p.updatePadding(f) + } +} + +func (p *printer) fmtDecimalInt(v uint64, isSigned bool) { + var d number.Decimal + + f := &p.toDecimal + if p.fmt.PrecPresent { + p.setFlags(f) + f.MinIntegerDigits = uint8(p.fmt.Prec) + f.MaxIntegerDigits = 0 + f.MinFractionDigits = 0 + f.MaxFractionDigits = 0 + if p.fmt.WidthPresent { + p.updatePadding(f) + } + } else { + p.initDecimal(0, 0) + } + d.ConvertInt(p.toDecimal.RoundingContext, isSigned, v) + + out := p.toDecimal.Format([]byte(nil), &d) + p.Buffer.Write(out) +} + +func (p *printer) fmtDecimalFloat(v float64, size, prec int) { + var d number.Decimal + if p.fmt.PrecPresent { + prec = p.fmt.Prec + } + p.initDecimal(prec, prec) + d.ConvertFloat(p.toDecimal.RoundingContext, v, size) + + out := p.toDecimal.Format([]byte(nil), &d) + p.Buffer.Write(out) +} + +func (p *printer) fmtVariableFloat(v float64, size int) { + prec := -1 + if p.fmt.PrecPresent { + prec = p.fmt.Prec + } + var d number.Decimal + p.initScientific(0, prec) + d.ConvertFloat(p.toScientific.RoundingContext, v, size) + + // Copy logic of 'g' formatting from strconv. It is simplified a bit as + // we don't have to mind having prec > len(d.Digits). + shortest := prec < 0 + ePrec := prec + if shortest { + prec = len(d.Digits) + ePrec = 6 + } else if prec == 0 { + prec = 1 + ePrec = 1 + } + exp := int(d.Exp) - 1 + if exp < -4 || exp >= ePrec { + p.initScientific(0, prec) + + out := p.toScientific.Format([]byte(nil), &d) + p.Buffer.Write(out) + } else { + if prec > int(d.Exp) { + prec = len(d.Digits) + } + if prec -= int(d.Exp); prec < 0 { + prec = 0 + } + p.initDecimal(0, prec) + + out := p.toDecimal.Format([]byte(nil), &d) + p.Buffer.Write(out) + } +} + +func (p *printer) fmtScientific(v float64, size, prec int) { + var d number.Decimal + if p.fmt.PrecPresent { + prec = p.fmt.Prec + } + p.initScientific(prec, prec) + rc := p.toScientific.RoundingContext + d.ConvertFloat(rc, v, size) + + out := p.toScientific.Format([]byte(nil), &d) + p.Buffer.Write(out) + +} + +// fmtComplex formats a complex number v with +// r = real(v) and j = imag(v) as (r+ji) using +// fmtFloat for r and j formatting. +func (p *printer) fmtComplex(v complex128, size int, verb rune) { + // Make sure any unsupported verbs are found before the + // calls to fmtFloat to not generate an incorrect error string. + switch verb { + case 'v', 'b', 'g', 'G', 'f', 'F', 'e', 'E': + p.WriteByte('(') + p.fmtFloat(real(v), size/2, verb) + // Imaginary part always has a sign. + if math.IsNaN(imag(v)) { + // By CLDR's rules, NaNs do not use patterns or signs. As this code + // relies on AlwaysSign working for imaginary parts, we need to + // manually handle NaNs. + f := &p.toScientific + p.setFlags(f) + p.updatePadding(f) + p.setFlags(f) + nan := f.Symbol(number.SymNan) + extra := 0 + if w, ok := p.Width(); ok { + extra = w - utf8.RuneCountInString(nan) - 1 + } + if f.Flags&number.PadAfterNumber == 0 { + for ; extra > 0; extra-- { + p.WriteRune(f.PadRune) + } + } + p.WriteString(f.Symbol(number.SymPlusSign)) + p.WriteString(nan) + for ; extra > 0; extra-- { + p.WriteRune(f.PadRune) + } + p.WriteString("i)") + return + } + oldPlus := p.fmt.Plus + p.fmt.Plus = true + p.fmtFloat(imag(v), size/2, verb) + p.WriteString("i)") // TODO: use symbol? + p.fmt.Plus = oldPlus + default: + p.badVerb(verb) + } +} + +func (p *printer) fmtString(v string, verb rune) { + switch verb { + case 'v': + if p.fmt.SharpV { + p.fmt.fmt_q(v) + } else { + p.fmt.fmt_s(v) + } + case 's': + p.fmt.fmt_s(v) + case 'x': + p.fmt.fmt_sx(v, ldigits) + case 'X': + p.fmt.fmt_sx(v, udigits) + case 'q': + p.fmt.fmt_q(v) + case 'm': + ctx := p.cat.Context(p.tag, rawPrinter{p}) + if ctx.Execute(v) == catalog.ErrNotFound { + p.WriteString(v) + } + default: + p.badVerb(verb) + } +} + +func (p *printer) fmtBytes(v []byte, verb rune, typeString string) { + switch verb { + case 'v', 'd': + if p.fmt.SharpV { + p.WriteString(typeString) + if v == nil { + p.WriteString(nilParenString) + return + } + p.WriteByte('{') + for i, c := range v { + if i > 0 { + p.WriteString(commaSpaceString) + } + p.fmt0x64(uint64(c), true) + } + p.WriteByte('}') + } else { + p.WriteByte('[') + for i, c := range v { + if i > 0 { + p.WriteByte(' ') + } + p.fmt.fmt_integer(uint64(c), 10, unsigned, ldigits) + } + p.WriteByte(']') + } + case 's': + p.fmt.fmt_s(string(v)) + case 'x': + p.fmt.fmt_bx(v, ldigits) + case 'X': + p.fmt.fmt_bx(v, udigits) + case 'q': + p.fmt.fmt_q(string(v)) + default: + p.printValue(reflect.ValueOf(v), verb, 0) + } +} + +func (p *printer) fmtPointer(value reflect.Value, verb rune) { + var u uintptr + switch value.Kind() { + case reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr, reflect.Slice, reflect.UnsafePointer: + u = value.Pointer() + default: + p.badVerb(verb) + return + } + + switch verb { + case 'v': + if p.fmt.SharpV { + p.WriteByte('(') + p.WriteString(value.Type().String()) + p.WriteString(")(") + if u == 0 { + p.WriteString(nilString) + } else { + p.fmt0x64(uint64(u), true) + } + p.WriteByte(')') + } else { + if u == 0 { + p.fmt.padString(nilAngleString) + } else { + p.fmt0x64(uint64(u), !p.fmt.Sharp) + } + } + case 'p': + p.fmt0x64(uint64(u), !p.fmt.Sharp) + case 'b', 'o', 'd', 'x', 'X': + if verb == 'd' { + p.fmt.Sharp = true // Print as standard go. TODO: does this make sense? + } + p.fmtInteger(uint64(u), unsigned, verb) + default: + p.badVerb(verb) + } +} + +func (p *printer) catchPanic(arg interface{}, verb rune) { + if err := recover(); err != nil { + // If it's a nil pointer, just say "". The likeliest causes are a + // Stringer that fails to guard against nil or a nil pointer for a + // value receiver, and in either case, "" is a nice result. + if v := reflect.ValueOf(arg); v.Kind() == reflect.Ptr && v.IsNil() { + p.WriteString(nilAngleString) + return + } + // Otherwise print a concise panic message. Most of the time the panic + // value will print itself nicely. + if p.panicking { + // Nested panics; the recursion in printArg cannot succeed. + panic(err) + } + + oldFlags := p.fmt.Parser + // For this output we want default behavior. + p.fmt.ClearFlags() + + p.WriteString(percentBangString) + p.WriteRune(verb) + p.WriteString(panicString) + p.panicking = true + p.printArg(err, 'v') + p.panicking = false + p.WriteByte(')') + + p.fmt.Parser = oldFlags + } +} + +func (p *printer) handleMethods(verb rune) (handled bool) { + if p.erroring { + return + } + // Is it a Formatter? + if formatter, ok := p.arg.(format.Formatter); ok { + handled = true + defer p.catchPanic(p.arg, verb) + formatter.Format(p, verb) + return + } + if formatter, ok := p.arg.(fmt.Formatter); ok { + handled = true + defer p.catchPanic(p.arg, verb) + formatter.Format(p, verb) + return + } + + // If we're doing Go syntax and the argument knows how to supply it, take care of it now. + if p.fmt.SharpV { + if stringer, ok := p.arg.(fmt.GoStringer); ok { + handled = true + defer p.catchPanic(p.arg, verb) + // Print the result of GoString unadorned. + p.fmt.fmt_s(stringer.GoString()) + return + } + } else { + // If a string is acceptable according to the format, see if + // the value satisfies one of the string-valued interfaces. + // Println etc. set verb to %v, which is "stringable". + switch verb { + case 'v', 's', 'x', 'X', 'q': + // Is it an error or Stringer? + // The duplication in the bodies is necessary: + // setting handled and deferring catchPanic + // must happen before calling the method. + switch v := p.arg.(type) { + case error: + handled = true + defer p.catchPanic(p.arg, verb) + p.fmtString(v.Error(), verb) + return + + case fmt.Stringer: + handled = true + defer p.catchPanic(p.arg, verb) + p.fmtString(v.String(), verb) + return + } + } + } + return false +} + +func (p *printer) printArg(arg interface{}, verb rune) { + p.arg = arg + p.value = reflect.Value{} + + if arg == nil { + switch verb { + case 'T', 'v': + p.fmt.padString(nilAngleString) + default: + p.badVerb(verb) + } + return + } + + // Special processing considerations. + // %T (the value's type) and %p (its address) are special; we always do them first. + switch verb { + case 'T': + p.fmt.fmt_s(reflect.TypeOf(arg).String()) + return + case 'p': + p.fmtPointer(reflect.ValueOf(arg), 'p') + return + } + + // Some types can be done without reflection. + switch f := arg.(type) { + case bool: + p.fmtBool(f, verb) + case float32: + p.fmtFloat(float64(f), 32, verb) + case float64: + p.fmtFloat(f, 64, verb) + case complex64: + p.fmtComplex(complex128(f), 64, verb) + case complex128: + p.fmtComplex(f, 128, verb) + case int: + p.fmtInteger(uint64(f), signed, verb) + case int8: + p.fmtInteger(uint64(f), signed, verb) + case int16: + p.fmtInteger(uint64(f), signed, verb) + case int32: + p.fmtInteger(uint64(f), signed, verb) + case int64: + p.fmtInteger(uint64(f), signed, verb) + case uint: + p.fmtInteger(uint64(f), unsigned, verb) + case uint8: + p.fmtInteger(uint64(f), unsigned, verb) + case uint16: + p.fmtInteger(uint64(f), unsigned, verb) + case uint32: + p.fmtInteger(uint64(f), unsigned, verb) + case uint64: + p.fmtInteger(f, unsigned, verb) + case uintptr: + p.fmtInteger(uint64(f), unsigned, verb) + case string: + p.fmtString(f, verb) + case []byte: + p.fmtBytes(f, verb, "[]byte") + case reflect.Value: + // Handle extractable values with special methods + // since printValue does not handle them at depth 0. + if f.IsValid() && f.CanInterface() { + p.arg = f.Interface() + if p.handleMethods(verb) { + return + } + } + p.printValue(f, verb, 0) + default: + // If the type is not simple, it might have methods. + if !p.handleMethods(verb) { + // Need to use reflection, since the type had no + // interface methods that could be used for formatting. + p.printValue(reflect.ValueOf(f), verb, 0) + } + } +} + +// printValue is similar to printArg but starts with a reflect value, not an interface{} value. +// It does not handle 'p' and 'T' verbs because these should have been already handled by printArg. +func (p *printer) printValue(value reflect.Value, verb rune, depth int) { + // Handle values with special methods if not already handled by printArg (depth == 0). + if depth > 0 && value.IsValid() && value.CanInterface() { + p.arg = value.Interface() + if p.handleMethods(verb) { + return + } + } + p.arg = nil + p.value = value + + switch f := value; value.Kind() { + case reflect.Invalid: + if depth == 0 { + p.WriteString(invReflectString) + } else { + switch verb { + case 'v': + p.WriteString(nilAngleString) + default: + p.badVerb(verb) + } + } + case reflect.Bool: + p.fmtBool(f.Bool(), verb) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + p.fmtInteger(uint64(f.Int()), signed, verb) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + p.fmtInteger(f.Uint(), unsigned, verb) + case reflect.Float32: + p.fmtFloat(f.Float(), 32, verb) + case reflect.Float64: + p.fmtFloat(f.Float(), 64, verb) + case reflect.Complex64: + p.fmtComplex(f.Complex(), 64, verb) + case reflect.Complex128: + p.fmtComplex(f.Complex(), 128, verb) + case reflect.String: + p.fmtString(f.String(), verb) + case reflect.Map: + if p.fmt.SharpV { + p.WriteString(f.Type().String()) + if f.IsNil() { + p.WriteString(nilParenString) + return + } + p.WriteByte('{') + } else { + p.WriteString(mapString) + } + keys := f.MapKeys() + for i, key := range keys { + if i > 0 { + if p.fmt.SharpV { + p.WriteString(commaSpaceString) + } else { + p.WriteByte(' ') + } + } + p.printValue(key, verb, depth+1) + p.WriteByte(':') + p.printValue(f.MapIndex(key), verb, depth+1) + } + if p.fmt.SharpV { + p.WriteByte('}') + } else { + p.WriteByte(']') + } + case reflect.Struct: + if p.fmt.SharpV { + p.WriteString(f.Type().String()) + } + p.WriteByte('{') + for i := 0; i < f.NumField(); i++ { + if i > 0 { + if p.fmt.SharpV { + p.WriteString(commaSpaceString) + } else { + p.WriteByte(' ') + } + } + if p.fmt.PlusV || p.fmt.SharpV { + if name := f.Type().Field(i).Name; name != "" { + p.WriteString(name) + p.WriteByte(':') + } + } + p.printValue(getField(f, i), verb, depth+1) + } + p.WriteByte('}') + case reflect.Interface: + value := f.Elem() + if !value.IsValid() { + if p.fmt.SharpV { + p.WriteString(f.Type().String()) + p.WriteString(nilParenString) + } else { + p.WriteString(nilAngleString) + } + } else { + p.printValue(value, verb, depth+1) + } + case reflect.Array, reflect.Slice: + switch verb { + case 's', 'q', 'x', 'X': + // Handle byte and uint8 slices and arrays special for the above verbs. + t := f.Type() + if t.Elem().Kind() == reflect.Uint8 { + var bytes []byte + if f.Kind() == reflect.Slice { + bytes = f.Bytes() + } else if f.CanAddr() { + bytes = f.Slice(0, f.Len()).Bytes() + } else { + // We have an array, but we cannot Slice() a non-addressable array, + // so we build a slice by hand. This is a rare case but it would be nice + // if reflection could help a little more. + bytes = make([]byte, f.Len()) + for i := range bytes { + bytes[i] = byte(f.Index(i).Uint()) + } + } + p.fmtBytes(bytes, verb, t.String()) + return + } + } + if p.fmt.SharpV { + p.WriteString(f.Type().String()) + if f.Kind() == reflect.Slice && f.IsNil() { + p.WriteString(nilParenString) + return + } + p.WriteByte('{') + for i := 0; i < f.Len(); i++ { + if i > 0 { + p.WriteString(commaSpaceString) + } + p.printValue(f.Index(i), verb, depth+1) + } + p.WriteByte('}') + } else { + p.WriteByte('[') + for i := 0; i < f.Len(); i++ { + if i > 0 { + p.WriteByte(' ') + } + p.printValue(f.Index(i), verb, depth+1) + } + p.WriteByte(']') + } + case reflect.Ptr: + // pointer to array or slice or struct? ok at top level + // but not embedded (avoid loops) + if depth == 0 && f.Pointer() != 0 { + switch a := f.Elem(); a.Kind() { + case reflect.Array, reflect.Slice, reflect.Struct, reflect.Map: + p.WriteByte('&') + p.printValue(a, verb, depth+1) + return + } + } + fallthrough + case reflect.Chan, reflect.Func, reflect.UnsafePointer: + p.fmtPointer(f, verb) + default: + p.unknownType(f) + } +} + +func (p *printer) badArgNum(verb rune) { + p.WriteString(percentBangString) + p.WriteRune(verb) + p.WriteString(badIndexString) +} + +func (p *printer) missingArg(verb rune) { + p.WriteString(percentBangString) + p.WriteRune(verb) + p.WriteString(missingString) +} + +func (p *printer) doPrintf(fmt string) { + for p.fmt.Parser.SetFormat(fmt); p.fmt.Scan(); { + switch p.fmt.Status { + case format.StatusText: + p.WriteString(p.fmt.Text()) + case format.StatusSubstitution: + p.printArg(p.Arg(p.fmt.ArgNum), p.fmt.Verb) + case format.StatusBadWidthSubstitution: + p.WriteString(badWidthString) + p.printArg(p.Arg(p.fmt.ArgNum), p.fmt.Verb) + case format.StatusBadPrecSubstitution: + p.WriteString(badPrecString) + p.printArg(p.Arg(p.fmt.ArgNum), p.fmt.Verb) + case format.StatusNoVerb: + p.WriteString(noVerbString) + case format.StatusBadArgNum: + p.badArgNum(p.fmt.Verb) + case format.StatusMissingArg: + p.missingArg(p.fmt.Verb) + default: + panic("unreachable") + } + } + + // Check for extra arguments, but only if there was at least one ordered + // argument. Note that this behavior is necessarily different from fmt: + // different variants of messages may opt to drop some or all of the + // arguments. + if !p.fmt.Reordered && p.fmt.ArgNum < len(p.fmt.Args) && p.fmt.ArgNum != 0 { + p.fmt.ClearFlags() + p.WriteString(extraString) + for i, arg := range p.fmt.Args[p.fmt.ArgNum:] { + if i > 0 { + p.WriteString(commaSpaceString) + } + if arg == nil { + p.WriteString(nilAngleString) + } else { + p.WriteString(reflect.TypeOf(arg).String()) + p.WriteString("=") + p.printArg(arg, 'v') + } + } + p.WriteByte(')') + } +} + +func (p *printer) doPrint(a []interface{}) { + prevString := false + for argNum, arg := range a { + isString := arg != nil && reflect.TypeOf(arg).Kind() == reflect.String + // Add a space between two non-string arguments. + if argNum > 0 && !isString && !prevString { + p.WriteByte(' ') + } + p.printArg(arg, 'v') + prevString = isString + } +} + +// doPrintln is like doPrint but always adds a space between arguments +// and a newline after the last argument. +func (p *printer) doPrintln(a []interface{}) { + for argNum, arg := range a { + if argNum > 0 { + p.WriteByte(' ') + } + p.printArg(arg, 'v') + } + p.WriteByte('\n') +} diff --git a/vendor/modules.txt b/vendor/modules.txt index b5a81eb56..620a2e524 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -11,6 +11,20 @@ github.com/stoewer/go-strcase ## explicit; go 1.20 golang.org/x/exp/constraints golang.org/x/exp/slices +# golang.org/x/text v0.22.0 +## explicit; go 1.18 +golang.org/x/text/feature/plural +golang.org/x/text/internal +golang.org/x/text/internal/catmsg +golang.org/x/text/internal/format +golang.org/x/text/internal/language +golang.org/x/text/internal/language/compact +golang.org/x/text/internal/number +golang.org/x/text/internal/stringset +golang.org/x/text/internal/tag +golang.org/x/text/language +golang.org/x/text/message +golang.org/x/text/message/catalog # google.golang.org/genproto/googleapis/api v0.0.0-20240826202546-f6391c0de4c7 ## explicit; go 1.21 google.golang.org/genproto/googleapis/api/expr/v1alpha1 From d54e6c0ceb04e39d789c52eac0ebfc8cfae7bbfc Mon Sep 17 00:00:00 2001 From: Justin King Date: Fri, 21 Feb 2025 09:51:09 -0800 Subject: [PATCH 4/7] Update ext/BUILD.bazel Signed-off-by: Justin King --- ext/BUILD.bazel | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/ext/BUILD.bazel b/ext/BUILD.bazel index b764fa1f5..e62fb3a8a 100644 --- a/ext/BUILD.bazel +++ b/ext/BUILD.bazel @@ -11,6 +11,7 @@ go_library( "comprehensions.go", "encoders.go", "formatting.go", + "formatting_v2.go", "guards.go", "lists.go", "math.go", @@ -26,8 +27,8 @@ go_library( "//checker:go_default_library", "//common/ast:go_default_library", "//common/decls:go_default_library", - "//common/overloads:go_default_library", "//common/operators:go_default_library", + "//common/overloads:go_default_library", "//common/types:go_default_library", "//common/types/pb:go_default_library", "//common/types/ref:go_default_library", @@ -48,7 +49,9 @@ go_test( srcs = [ "bindings_test.go", "comprehensions_test.go", - "encoders_test.go", + "encoders_test.go", + "formatting_test.go", + "formatting_v2_test.go", "lists_test.go", "math_test.go", "native_test.go", @@ -68,8 +71,8 @@ go_test( "//test:go_default_library", "//test/proto2pb:go_default_library", "//test/proto3pb:go_default_library", + "@org_golang_google_protobuf//encoding/protojson:go_default_library", "@org_golang_google_protobuf//proto:go_default_library", "@org_golang_google_protobuf//types/known/wrapperspb:go_default_library", - "@org_golang_google_protobuf//encoding/protojson:go_default_library", ], ) From 4d71e511431280f053be50c7a092172fb74d117b Mon Sep 17 00:00:00 2001 From: Justin King Date: Fri, 21 Feb 2025 10:11:41 -0800 Subject: [PATCH 5/7] Fix repl/evaluator.go Signed-off-by: Justin King --- repl/evaluator.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repl/evaluator.go b/repl/evaluator.go index 5563f15e9..852c3493e 100644 --- a/repl/evaluator.go +++ b/repl/evaluator.go @@ -1002,7 +1002,7 @@ func (e *Evaluator) Process(cmd Cmder) (string, bool, error) { if ok { return fmt.Sprintf("Unknown %v", unknown), false, nil } - return fmt.Sprintf("%s : %s", val, t), false, nil + return fmt.Sprintf("%v : %s", val.Value(), t), false, nil } case *letVarCmd: var err error From 974a394e49b14ece33dddf4e0accf74d4d71832d Mon Sep 17 00:00:00 2001 From: Justin King Date: Fri, 21 Feb 2025 10:58:08 -0800 Subject: [PATCH 6/7] Implement fmt.Stringer for various ref.Value to return CEL syntax string Signed-off-by: Justin King --- common/types/bool.go | 10 ++++++++-- common/types/bytes.go | 15 +++++++++++++++ common/types/double.go | 19 +++++++++++++++++++ common/types/duration.go | 4 ++++ common/types/int.go | 4 ++++ common/types/list.go | 2 +- common/types/map.go | 24 ++++++++++++++++++++---- common/types/null.go | 4 ++++ common/types/object.go | 31 +++++++++++++++++++++++++++++++ common/types/string.go | 4 ++++ common/types/timestamp.go | 4 ++++ common/types/uint.go | 4 ++++ repl/evaluator.go | 2 +- repl/evaluator_test.go | 16 ++++++++-------- repl/go.mod | 4 ++-- repl/go.sum | 4 ++-- 16 files changed, 131 insertions(+), 20 deletions(-) diff --git a/common/types/bool.go b/common/types/bool.go index 565734f3f..ea239efd6 100644 --- a/common/types/bool.go +++ b/common/types/bool.go @@ -17,7 +17,6 @@ package types import ( "fmt" "reflect" - "strconv" "github.com/google/cel-go/common/types/ref" @@ -93,7 +92,7 @@ func (b Bool) ConvertToNative(typeDesc reflect.Type) (any, error) { func (b Bool) ConvertToType(typeVal ref.Type) ref.Val { switch typeVal { case StringType: - return String(strconv.FormatBool(bool(b))) + return String(b.String()) case BoolType: return b case TypeType: @@ -128,6 +127,13 @@ func (b Bool) Value() any { return bool(b) } +func (b Bool) String() string { + if b { + return "true" + } + return "false" +} + // IsBool returns whether the input ref.Val or ref.Type is equal to BoolType. func IsBool(elem ref.Val) bool { switch v := elem.(type) { diff --git a/common/types/bytes.go b/common/types/bytes.go index 7e813e291..73175bda4 100644 --- a/common/types/bytes.go +++ b/common/types/bytes.go @@ -19,6 +19,7 @@ import ( "encoding/base64" "fmt" "reflect" + "strings" "unicode/utf8" "github.com/google/cel-go/common/types/ref" @@ -138,3 +139,17 @@ func (b Bytes) Type() ref.Type { func (b Bytes) Value() any { return []byte(b) } + +func (b Bytes) String() string { + return fmt.Sprintf("b\"%s\"", bytesToOctets([]byte(b))) +} + +// bytesToOctets converts byte sequences to a string using a three digit octal encoded value +// per byte. +func bytesToOctets(byteVal []byte) string { + var b strings.Builder + for _, c := range byteVal { + fmt.Fprintf(&b, "\\%03o", c) + } + return b.String() +} diff --git a/common/types/double.go b/common/types/double.go index 027e78978..99b55f9ac 100644 --- a/common/types/double.go +++ b/common/types/double.go @@ -18,6 +18,8 @@ import ( "fmt" "math" "reflect" + "strconv" + "strings" "github.com/google/cel-go/common/types/ref" @@ -209,3 +211,20 @@ func (d Double) Type() ref.Type { func (d Double) Value() any { return float64(d) } + +func (d Double) String() string { + if math.IsNaN(float64(d)) { + return "double(\"NaN\")" + } + if math.IsInf(float64(d), -1) { + return "double(\"-Infinity\")" + } + if math.IsInf(float64(d), 1) { + return "double(\"Infinity\")" + } + s := strconv.FormatFloat(float64(d), 'f', -1, 64) + if !strings.ContainsRune(s, '.') { + s = s + ".0" + } + return s +} diff --git a/common/types/duration.go b/common/types/duration.go index 596e56d6b..dd23e6d82 100644 --- a/common/types/duration.go +++ b/common/types/duration.go @@ -185,6 +185,10 @@ func (d Duration) Value() any { return d.Duration } +func (d Duration) String() string { + return fmt.Sprintf("duration(\"%ss\")", strconv.FormatFloat(d.Seconds(), 'f', -1, 64)) +} + // DurationGetHours returns the duration in hours. func DurationGetHours(val ref.Val) ref.Val { dur, ok := val.(Duration) diff --git a/common/types/int.go b/common/types/int.go index 0ae9507c3..8bb8a0635 100644 --- a/common/types/int.go +++ b/common/types/int.go @@ -290,6 +290,10 @@ func (i Int) Value() any { return int64(i) } +func (i Int) String() string { + return strconv.FormatInt(int64(i), 10) +} + // isJSONSafe indicates whether the int is safely representable as a floating point value in JSON. func (i Int) isJSONSafe() bool { return i >= minIntJSON && i <= maxIntJSON diff --git a/common/types/list.go b/common/types/list.go index 7e68a5daf..a1e7454de 100644 --- a/common/types/list.go +++ b/common/types/list.go @@ -290,7 +290,7 @@ func (l *baseList) String() string { var sb strings.Builder sb.WriteString("[") for i := 0; i < l.size; i++ { - sb.WriteString(fmt.Sprintf("%v", l.get(i))) + sb.WriteString(fmt.Sprintf("%s", l.Get(Int(i)))) if i != l.size-1 { sb.WriteString(", ") } diff --git a/common/types/map.go b/common/types/map.go index cb6cce78b..6e5fedf2a 100644 --- a/common/types/map.go +++ b/common/types/map.go @@ -17,6 +17,7 @@ package types import ( "fmt" "reflect" + "sort" "strings" "github.com/stoewer/go-strcase" @@ -299,20 +300,35 @@ func (m *baseMap) Size() ref.Val { return Int(m.size) } +type baseMapEntry struct { + key string + val string +} + // String converts the map into a human-readable string. func (m *baseMap) String() string { var sb strings.Builder sb.WriteString("{") it := m.Iterator() - i := 0 + var ents []baseMapEntry + if s, ok := m.Size().(Int); ok { + ents = make([]baseMapEntry, 0, int(s)) + } for it.HasNext() == True { k := it.Next() v, _ := m.Find(k) - sb.WriteString(fmt.Sprintf("%v: %v", k, v)) - if i != m.size-1 { + ents = append(ents, baseMapEntry{fmt.Sprintf("%s", k), fmt.Sprintf("%s", v)}) + } + sort.SliceStable(ents, func(i, j int) bool { + return ents[i].key < ents[j].key + }) + for i, ent := range ents { + if i > 0 { sb.WriteString(", ") } - i++ + sb.WriteString(ent.key) + sb.WriteString(": ") + sb.WriteString(ent.val) } sb.WriteString("}") return sb.String() diff --git a/common/types/null.go b/common/types/null.go index 36514ff20..9cd13e399 100644 --- a/common/types/null.go +++ b/common/types/null.go @@ -117,3 +117,7 @@ func (n Null) Type() ref.Type { func (n Null) Value() any { return structpb.NullValue_NULL_VALUE } + +func (n Null) String() string { + return "null" +} diff --git a/common/types/object.go b/common/types/object.go index 5377bff8d..3a9e628bf 100644 --- a/common/types/object.go +++ b/common/types/object.go @@ -17,9 +17,12 @@ package types import ( "fmt" "reflect" + "sort" + "strings" "google.golang.org/protobuf/encoding/protojson" "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/reflect/protoreflect" "github.com/google/cel-go/common/types/pb" "github.com/google/cel-go/common/types/ref" @@ -163,3 +166,31 @@ func (o *protoObj) Type() ref.Type { func (o *protoObj) Value() any { return o.value } + +type protoObjField struct { + fd protoreflect.FieldDescriptor + v protoreflect.Value +} + +func (o *protoObj) String() string { + var fields []protoreflect.FieldDescriptor + o.value.ProtoReflect().Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool { + fields = append(fields, fd) + return true + }) + sort.SliceStable(fields, func(i, j int) bool { + return fields[i].Number() < fields[j].Number() + }) + var sb strings.Builder + sb.WriteString(o.Type().TypeName()) + sb.WriteString("{") + for i, field := range fields { + if i > 0 { + sb.WriteString(", ") + } + sb.WriteString(fmt.Sprintf("%s: ", field.Name())) + sb.WriteString(fmt.Sprintf("%s", o.Get(String(field.Name())))) + } + sb.WriteString("}") + return sb.String() +} diff --git a/common/types/string.go b/common/types/string.go index 3a93743f2..6d028d4e7 100644 --- a/common/types/string.go +++ b/common/types/string.go @@ -186,6 +186,10 @@ func (s String) Value() any { return string(s) } +func (s String) String() string { + return strconv.Quote(string(s)) +} + // StringContains returns whether the string contains a substring. func StringContains(s, sub ref.Val) ref.Val { str, ok := s.(String) diff --git a/common/types/timestamp.go b/common/types/timestamp.go index 33acdea8e..8c55a8e1f 100644 --- a/common/types/timestamp.go +++ b/common/types/timestamp.go @@ -179,6 +179,10 @@ func (t Timestamp) Value() any { return t.Time } +func (t Timestamp) String() string { + return fmt.Sprintf("timestamp(\"%s\")", t.Time.UTC().Format(time.RFC3339Nano)) +} + var ( timestampValueType = reflect.TypeOf(&tpb.Timestamp{}) diff --git a/common/types/uint.go b/common/types/uint.go index 6d74f30d8..9ef815372 100644 --- a/common/types/uint.go +++ b/common/types/uint.go @@ -250,6 +250,10 @@ func (i Uint) Value() any { return uint64(i) } +func (i Uint) String() string { + return strconv.FormatUint(uint64(i), 10) + "u" +} + // isJSONSafe indicates whether the uint is safely representable as a floating point value in JSON. func (i Uint) isJSONSafe() bool { return i <= maxIntJSON diff --git a/repl/evaluator.go b/repl/evaluator.go index 852c3493e..5563f15e9 100644 --- a/repl/evaluator.go +++ b/repl/evaluator.go @@ -1002,7 +1002,7 @@ func (e *Evaluator) Process(cmd Cmder) (string, bool, error) { if ok { return fmt.Sprintf("Unknown %v", unknown), false, nil } - return fmt.Sprintf("%v : %s", val.Value(), t), false, nil + return fmt.Sprintf("%s : %s", val, t), false, nil } case *letVarCmd: var err error diff --git a/repl/evaluator_test.go b/repl/evaluator_test.go index dbe117724..5a82c2fa5 100644 --- a/repl/evaluator_test.go +++ b/repl/evaluator_test.go @@ -535,7 +535,7 @@ func TestProcess(t *testing.T) { expr: "1u + 2u", }, }, - wantText: "3 : uint", + wantText: "3u : uint", wantExit: false, wantError: false, }, @@ -546,7 +546,7 @@ func TestProcess(t *testing.T) { expr: `'a' + r'b\1'`, }, }, - wantText: `ab\1 : string`, + wantText: `"ab\\1" : string`, wantExit: false, wantError: false, }, @@ -557,7 +557,7 @@ func TestProcess(t *testing.T) { expr: `['abc', 123, 3.14, duration('2m')]`, }, }, - wantText: `["abc", 123, 3.140000, duration("120s")] : list(dyn)`, + wantText: `["abc", 123, 3.14, duration("120s")] : list(dyn)`, wantExit: false, wantError: false, }, @@ -568,7 +568,7 @@ func TestProcess(t *testing.T) { expr: `{1: 123, 2: 3.14, 3: duration('2m'), 4: b'123'}`, }, }, - wantText: `{1:123, 2:3.140000, 3:duration("120s"), 4:b"123"} : map(int, dyn)`, + wantText: `{1: 123, 2: 3.14, 3: duration("120s"), 4: b"\061\062\063"} : map(int, dyn)`, wantExit: false, wantError: false, }, @@ -619,7 +619,7 @@ func TestProcess(t *testing.T) { expr: "optional.none().orValue('default')", }, }, - wantText: "default : string", + wantText: "\"default\" : string", wantExit: false, wantError: false, }, @@ -637,7 +637,7 @@ func TestProcess(t *testing.T) { expr: "'test'.substring(2)", }, }, - wantText: "st : string", + wantText: "\"st\" : string", wantExit: false, wantError: false, }, @@ -691,7 +691,7 @@ func TestProcess(t *testing.T) { expr: "base64.encode(b'hello')", }, }, - wantText: "aGVsbG8= : string", + wantText: "\"aGVsbG8=\" : string", wantExit: false, wantError: false, }, @@ -825,7 +825,7 @@ func TestProcess(t *testing.T) { expr: "AttributeContext.Request{host: 'www.example.com'}", }, }, - wantText: `host:"www.example.com" : google.rpc.context.AttributeContext.Request`, + wantText: `google.rpc.context.AttributeContext.Request{host: "www.example.com"} : google.rpc.context.AttributeContext.Request`, wantExit: false, wantError: false, }, diff --git a/repl/go.mod b/repl/go.mod index 01c9db4ec..12e764df3 100644 --- a/repl/go.mod +++ b/repl/go.mod @@ -3,7 +3,7 @@ module github.com/google/cel-go/repl go 1.21.1 require ( - cel.dev/expr v0.18.0 + cel.dev/expr v0.21.2 github.com/antlr4-go/antlr/v4 v4.13.0 github.com/chzyer/readline v1.5.1 github.com/google/cel-go v0.0.0-00010101000000-000000000000 @@ -16,7 +16,7 @@ require ( github.com/stoewer/go-strcase v1.3.0 // indirect golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc // indirect golang.org/x/sys v0.21.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/text v0.22.0 // indirect ) replace github.com/google/cel-go => ../. diff --git a/repl/go.sum b/repl/go.sum index e9660f26b..96c2f193b 100644 --- a/repl/go.sum +++ b/repl/go.sum @@ -27,8 +27,8 @@ golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc/go.mod h1:V1LtkGg67GoY2N1AnL golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= +golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= google.golang.org/genproto/googleapis/api v0.0.0-20240826202546-f6391c0de4c7 h1:YcyjlL1PRr2Q17/I0dPk2JmYS5CDXfcdb2Z3YRioEbw= google.golang.org/genproto/googleapis/api v0.0.0-20240826202546-f6391c0de4c7/go.mod h1:OCdP9MfskevB/rbYvHTsXTtKC+3bHWajPdoKgjcYkfo= google.golang.org/genproto/googleapis/rpc v0.0.0-20240826202546-f6391c0de4c7 h1:2035KHhUv+EpyB+hWgJnaWKJOdX1E95w2S8Rr4uWKTs= From b42d02e1b2efcff43f20ad1bae2cb99eafa0d1a3 Mon Sep 17 00:00:00 2001 From: Justin King Date: Fri, 21 Feb 2025 11:26:17 -0800 Subject: [PATCH 7/7] Fix tests Signed-off-by: Justin King --- cel/cel_example_test.go | 4 +-- cel/cel_test.go | 12 ++++---- common/types/json_struct_test.go | 2 +- common/types/list_test.go | 4 +-- common/types/map_test.go | 48 ++++++++++++++++---------------- common/types/object.go | 4 +-- ext/comprehensions_test.go | 2 +- ext/native_test.go | 6 ++-- interpreter/attributes_test.go | 8 +++--- interpreter/interpretable.go | 6 ++-- interpreter/interpreter_test.go | 10 +++---- 11 files changed, 53 insertions(+), 53 deletions(-) diff --git a/cel/cel_example_test.go b/cel/cel_example_test.go index f4c11b598..d8736f9f9 100644 --- a/cel/cel_example_test.go +++ b/cel/cel_example_test.go @@ -68,7 +68,7 @@ func Example() { } fmt.Println(out) - // Output:Hello world! Nice to meet you, I'm CEL. + // Output:"Hello \"world\"! Nice to meet you, I'm \"CEL\".\n" } func Example_globalOverload() { @@ -116,7 +116,7 @@ func Example_globalOverload() { } fmt.Println(out) - // Output:CEL and world are shaking hands. + // Output:"\"CEL\" and \"world\" are shaking hands.\n" } func Example_statefulOverload() { diff --git a/cel/cel_test.go b/cel/cel_test.go index 3ff459756..877b68580 100644 --- a/cel/cel_test.go +++ b/cel/cel_test.go @@ -2438,7 +2438,7 @@ func TestQuotedFields(t *testing.T) { }, { expr: "{'key-1': 64}.`key-2`", - errorSubstr: "no such key: key-2", + errorSubstr: "no such key: \"key-2\"", }, { expr: "has({'key-1': 64}.`key-1`)", @@ -2951,7 +2951,7 @@ func TestOptionalValuesEval(t *testing.T) { }, }, }, - out: "no such key: a", + out: "no such key: \"a\"", }, { expr: `m.?c.missing.or(m.?c['dashed-index']).orValue('').size()`, @@ -3136,15 +3136,15 @@ func TestEnableErrorOnBadPresenceTest(t *testing.T) { }, { expr: `{'null_field': dyn(null)}.?null_field.?nested`, - out: "no such key: nested", + out: "no such key: \"nested\"", }, { expr: `{'zero_field': dyn(0)}.?zero_field.?invalid`, - out: "no such key: invalid", + out: "no such key: \"invalid\"", }, { expr: `{0: dyn(0)}[?0].?invalid`, - out: "no such key: invalid", + out: "no such key: \"invalid\"", }, { expr: `{true: dyn(0)}[?false].?invalid`, @@ -3152,7 +3152,7 @@ func TestEnableErrorOnBadPresenceTest(t *testing.T) { }, { expr: `{true: dyn(0)}[?true].?invalid`, - out: "no such key: invalid", + out: "no such key: \"invalid\"", }, } diff --git a/common/types/json_struct_test.go b/common/types/json_struct_test.go index 00c9856d8..9c1d5e7ff 100644 --- a/common/types/json_struct_test.go +++ b/common/types/json_struct_test.go @@ -172,7 +172,7 @@ func TestJsonStructGet(t *testing.T) { } e, isError := mapVal.Get(String("third")).(*Err) - if !isError || e.Error() != "no such key: third" { + if !isError || e.Error() != "no such key: \"third\"" { t.Errorf("Got %v, wanted no such key: third", e) } } diff --git a/common/types/list_test.go b/common/types/list_test.go index ba6c498f2..87081d069 100644 --- a/common/types/list_test.go +++ b/common/types/list_test.go @@ -183,7 +183,7 @@ func TestBaseListGet(t *testing.T) { func TestBaseListString(t *testing.T) { l := DefaultTypeAdapter.NativeToValue([]any{1, "hello", 2.1, true, []string{"world"}}) - want := `[1, hello, 2.1, true, [world]]` + want := `[1, "hello", 2.1, true, ["world"]]` if fmt.Sprintf("%v", l) != want { t.Errorf("l.String() got %v, wanted %v", l, want) } @@ -192,7 +192,7 @@ func TestBaseListString(t *testing.T) { func TestConcatListString(t *testing.T) { l := DefaultTypeAdapter.NativeToValue([]any{1, "hello", 2.1, true}).(traits.Lister) c := l.Add(DefaultTypeAdapter.NativeToValue([]string{"world"})) - want := `[1, hello, 2.1, true, world]` + want := `[1, "hello", 2.1, true, "world"]` if fmt.Sprintf("%v", c) != want { t.Errorf("c.String() got %v, wanted %v", c, want) } diff --git a/common/types/map_test.go b/common/types/map_test.go index b16422c75..f46fd6e57 100644 --- a/common/types/map_test.go +++ b/common/types/map_test.go @@ -429,24 +429,24 @@ func TestDynamicMapGet(t *testing.T) { t.Errorf("nestedVal.Get(1) got %v, wanted -1.0", floatVal) } err := mapVal.Get(String("absent")) - if !IsError(err) || err.(*Err).Error() != "no such key: absent" { - t.Errorf("mapVal.Get('absent') got %v, wanted no such key: absent.", err) + if !IsError(err) || err.(*Err).Error() != "no such key: \"absent\"" { + t.Errorf("mapVal.Get('absent') got %v, wanted no such key: \"absent\".", err) } err = nestedVal.Get(String("bad_key")) - if !IsError(err) || err.(*Err).Error() != "no such key: bad_key" { - t.Errorf("nestedVal.Get('bad_key') errored %v, wanted no such key: bad_key.", err) + if !IsError(err) || err.(*Err).Error() != "no such key: \"bad_key\"" { + t.Errorf("nestedVal.Get('bad_key') errored %v, wanted no such key: \"bad_key\".", err) } empty, ok := mapVal.Get(String("empty")).(traits.Mapper) if !ok { t.Fatalf("mapVal.Get('empty') got %v, wanted empty map", mapVal.Get(String("empty"))) } err = empty.Get(String("hello")) - if !IsError(err) || err.(*Err).Error() != "no such key: hello" { - t.Errorf("empty.Get('hello') got %v, wanted no such key: hello", err) + if !IsError(err) || err.(*Err).Error() != "no such key: \"hello\"" { + t.Errorf("empty.Get('hello') got %v, wanted no such key: \"hello\"", err) } err = empty.Get(Double(-1.0)) - if !IsError(err) || err.(*Err).Error() != "no such key: -1" { - t.Errorf("empty.Get(-1.0) got %v, wanted no such key: -1", err) + if !IsError(err) || err.(*Err).Error() != "no such key: -1.0" { + t.Errorf("empty.Get(-1.0) got %v, wanted no such key: -1.0", err) } } @@ -465,24 +465,24 @@ func TestStringIfaceMapGet(t *testing.T) { t.Errorf("nestedVal.Get(1) got %v, wanted -1.0", floatVal) } err := mapVal.Get(String("absent")) - if !IsError(err) || err.(*Err).Error() != "no such key: absent" { - t.Errorf("mapVal.Get('absent') got %v, wanted no such key: absent.", err) + if !IsError(err) || err.(*Err).Error() != "no such key: \"absent\"" { + t.Errorf("mapVal.Get('absent') got %v, wanted no such key: \"absent\".", err) } err = nestedVal.Get(String("bad_key")) - if !IsError(err) || err.(*Err).Error() != "no such key: bad_key" { - t.Errorf("nestedVal.Get('bad_key') got %v, no such key: bad_key", err) + if !IsError(err) || err.(*Err).Error() != "no such key: \"bad_key\"" { + t.Errorf("nestedVal.Get('bad_key') got %v, no such key: \"bad_key\"", err) } empty, ok := mapVal.Get(String("empty")).(traits.Mapper) if !ok { t.Fatalf("mapVal.Get('empty') got %v, wanted empty map", mapVal.Get(String("empty"))) } err = empty.Get(String("hello")) - if !IsError(err) || err.(*Err).Error() != "no such key: hello" { - t.Errorf("empty.Get('hello') got %v, wanted no such key: hello", err) + if !IsError(err) || err.(*Err).Error() != "no such key: \"hello\"" { + t.Errorf("empty.Get('hello') got %v, wanted no such key: \"hello\"", err) } err = empty.Get(Double(-1.0)) - if !IsError(err) || err.(*Err).Error() != "no such key: -1" { - t.Errorf("empty.Get(-1.0) got %v, wanted no such key: -1", err) + if !IsError(err) || err.(*Err).Error() != "no such key: -1.0" { + t.Errorf("empty.Get(-1.0) got %v, wanted no such key: -1.0", err) } } @@ -520,24 +520,24 @@ func TestRefValMapGet(t *testing.T) { t.Errorf("nestedVal.Get(1) got %v, wanted -1.0", floatVal) } err := mapVal.Get(String("absent")) - if !IsError(err) || err.(*Err).Error() != "no such key: absent" { + if !IsError(err) || err.(*Err).Error() != "no such key: \"absent\"" { t.Errorf("mapVal.Get('absent') got %v, wanted no such key: absent.", err) } err = nestedVal.Get(String("bad_key")) - if !IsError(err) || err.(*Err).Error() != "no such key: bad_key" { - t.Errorf("nestedVal.Get('bad_key') got %v, wanted no such key: bad_key.", err) + if !IsError(err) || err.(*Err).Error() != "no such key: \"bad_key\"" { + t.Errorf("nestedVal.Get('bad_key') got %v, wanted no such key: \"bad_key\".", err) } empty, ok := mapVal.Get(String("empty")).(traits.Mapper) if !ok { t.Fatalf("mapVal.Get('empty') got %v, wanted empty map", mapVal.Get(String("empty"))) } err = empty.Get(String("hello")) - if !IsError(err) || err.(*Err).Error() != "no such key: hello" { - t.Errorf("empty.Get('hello') got %v, wanted no such key: hello", err) + if !IsError(err) || err.(*Err).Error() != "no such key: \"hello\"" { + t.Errorf("empty.Get('hello') got %v, wanted no such key: \"hello\"", err) } err = empty.Get(Double(-1.0)) - if !IsError(err) || err.(*Err).Error() != "no such key: -1" { - t.Errorf("empty.Get(-1.0) got %v, wanted no such key: -1", err) + if !IsError(err) || err.(*Err).Error() != "no such key: -1.0" { + t.Errorf("empty.Get(-1.0) got %v, wanted no such key: -1.0", err) } } @@ -842,7 +842,7 @@ func TestProtoMapString(t *testing.T) { } reg := newTestRegistry(t) m := reg.NativeToValue(strMap) - want := `{hello: world}` + want := `{"hello": "world"}` if fmt.Sprintf("%v", m) != want { t.Errorf("map.String() got %v, wanted %v", m, want) } diff --git a/common/types/object.go b/common/types/object.go index 3a9e628bf..c1cb5d059 100644 --- a/common/types/object.go +++ b/common/types/object.go @@ -129,7 +129,7 @@ func (o *protoObj) IsSet(field ref.Val) ref.Val { protoFieldStr := string(protoFieldName) fd, found := o.typeDesc.FieldByName(protoFieldStr) if !found { - return NewErr("no such field '%s'", field) + return NewErr("no such field %s", field) } if fd.IsSet(o.value) { return True @@ -150,7 +150,7 @@ func (o *protoObj) Get(index ref.Val) ref.Val { protoFieldStr := string(protoFieldName) fd, found := o.typeDesc.FieldByName(protoFieldStr) if !found { - return NewErr("no such field '%s'", index) + return NewErr("no such field %s", index) } fv, err := fd.GetFrom(o.value) if err != nil { diff --git a/ext/comprehensions_test.go b/ext/comprehensions_test.go index 89a6052b3..534ff2812 100644 --- a/ext/comprehensions_test.go +++ b/ext/comprehensions_test.go @@ -509,7 +509,7 @@ func TestTwoVarComprehensionsRuntimeErrors(t *testing.T) { }, { expr: `[0, 0u].transformMapEntry(i, v, {v: i})`, - err: "insert failed: key 0 already exists", + err: "insert failed: key 0u already exists", }, } env := testCompreEnv(t) diff --git a/ext/native_test.go b/ext/native_test.go index 2c0ce3d36..51ab605c4 100644 --- a/ext/native_test.go +++ b/ext/native_test.go @@ -559,11 +559,11 @@ func TestNativeTypesRuntimeErrors(t *testing.T) { }, { expr: `ext.TestAllTypes{}.UnsupportedMapVal`, - err: `no such field: UnsupportedMapVal`, + err: `no such field: "UnsupportedMapVal"`, }, { expr: `ext.TestAllTypes{}.privateVal`, - err: `no such field: privateVal`, + err: `no such field: "privateVal"`, }, { expr: `ext.TestAllTypes{BoolVal: 'false'}`, @@ -571,7 +571,7 @@ func TestNativeTypesRuntimeErrors(t *testing.T) { }, { expr: `has(ext.TestAllTypes{}.BadFieldName)`, - err: `no such field: BadFieldName`, + err: `no such field: "BadFieldName"`, }, { expr: `ext.TestAllTypes{}[42]`, diff --git a/interpreter/attributes_test.go b/interpreter/attributes_test.go index 86b6025f1..94acb92b6 100644 --- a/interpreter/attributes_test.go +++ b/interpreter/attributes_test.go @@ -476,7 +476,7 @@ func TestAttributesOptional(t *testing.T) { "b": map[uint]any{}, }, }, - err: errors.New("no such key: 1"), + err: errors.New("no such key: 1u"), }, { // a.b[?1] with no value where 'b' is a []int @@ -645,7 +645,7 @@ func TestAttributesOptional(t *testing.T) { }, "c.d": map[string]any{}, }, - err: errors.New("no such key: e"), + err: errors.New("no such key: \"e\""), }, { // a[?c.d.e] where the c.d.e errors @@ -659,7 +659,7 @@ func TestAttributesOptional(t *testing.T) { }, "c.d": map[string]any{}, }, - err: errors.New("no such key: e"), + err: errors.New("no such key: \"e\""), }, { // a.?single_int32 with a value. @@ -702,7 +702,7 @@ func TestAttributesOptional(t *testing.T) { vars: map[string]any{ "a": map[string]any{}, }, - err: errors.New("no such key: c"), + err: errors.New("no such key: \"c\""), }, { // a, no bindings diff --git a/interpreter/interpretable.go b/interpreter/interpretable.go index 1573523be..d629a1f79 100644 --- a/interpreter/interpretable.go +++ b/interpreter/interpretable.go @@ -708,7 +708,7 @@ func (o *evalObj) Eval(ctx Activation) ref.Val { if o.hasOptionals && o.optionals[i] { optVal, ok := val.(*types.Optional) if !ok { - return types.LabelErrNode(o.id, invalidOptionalEntryInit(field, val)) + return types.LabelErrNode(o.id, invalidOptionalEntryInit(types.String(field), val)) } if !optVal.HasValue() { delete(fieldVals, field) @@ -1233,11 +1233,11 @@ func (c *evalWatchConstructor) Eval(ctx Activation) ref.Val { } func invalidOptionalEntryInit(field any, value ref.Val) ref.Val { - return types.NewErr("cannot initialize optional entry '%v' from non-optional value %v", field, value) + return types.NewErr("cannot initialize optional entry %s from non-optional value %s", field, value) } func invalidOptionalElementInit(value ref.Val) ref.Val { - return types.NewErr("cannot initialize optional list element from non-optional value %v", value) + return types.NewErr("cannot initialize optional list element from non-optional value %s", value) } // newFolder creates or initializes a pooled folder instance. diff --git a/interpreter/interpreter_test.go b/interpreter/interpreter_test.go index 498be1340..9a387f0d4 100644 --- a/interpreter/interpreter_test.go +++ b/interpreter/interpreter_test.go @@ -311,7 +311,7 @@ func testData(t testing.TB) []testCase { "a": int32(1), "b": int32(2), }, - err: "no such key: c", + err: "no such key: \"c\"", }, { name: "in_empty_list", @@ -806,7 +806,7 @@ func testData(t testing.TB) []testCase { types: []proto.Message{&proto2pb.TestAllTypes{}}, unchecked: true, expr: `has(TestAllTypes{}.invalid_field)`, - err: "no such field 'invalid_field'", + err: "no such field \"invalid_field\"", }, { name: "macro_has_pb2_field", @@ -1408,7 +1408,7 @@ func testData(t testing.TB) []testCase { name: "literal_map_optional_field_bad_init", expr: `{?'hi': 'world'}`, unchecked: true, - err: `cannot initialize optional entry 'hi' from non-optional`, + err: `cannot initialize optional entry "hi" from non-optional`, }, { name: "literal_pb_optional_field", @@ -1425,7 +1425,7 @@ func testData(t testing.TB) []testCase { container: "google.expr.proto3.test", types: []proto.Message{&proto3pb.TestAllTypes{}}, unchecked: true, - err: `cannot initialize optional entry 'single_int32' from non-optional`, + err: `cannot initialize optional entry "single_int32" from non-optional`, }, { name: "literal_list_optional_element", @@ -1489,7 +1489,7 @@ func testData(t testing.TB) []testCase { { name: "invalid_presence_test_on_int_literal", expr: `has(dyn(1).invalid)`, - err: "no such key: invalid", + err: "no such key: \"invalid\"", attrs: NewAttributeFactory(testContainer(""), types.DefaultTypeAdapter, types.NewEmptyRegistry(), EnableErrorOnBadPresenceTest(true)), },